diff -Nru a/CREDITS b/CREDITS
--- a/CREDITS	2005-03-01 23:39:08 -08:00
+++ b/CREDITS	2005-03-01 23:39:08 -08:00
@@ -805,6 +805,21 @@
 S: Round Rock, TX  78682
 S: USA
 
+N: Ben Dooks
+E: ben-linux@fluff.org
+E: ben@simtec.co.uk
+W: http://www.fluff.org/ben/
+W: http://www.simtec.co.uk/
+D: Samsung S3C2410/S3C2440 support, general ARM support
+D: Maintaining Simtec Electronics development boards
+S: Simtec Electronics
+S: Avondale Drive
+S: Tarleton
+S: Preston
+S: Lancs
+S: PR4 6AX
+S: United Kingdom
+
 N: John G Dorsey
 E: john+@cs.cmu.edu
 D: ARM Linux ports to Assabet/Neponset, Spot
@@ -1811,7 +1826,8 @@
 
 N: Greg Kroah-Hartman
 E: greg@kroah.com
-W: http://www.kroah.com/linux-usb/
+E: gregkh@suse.de
+W: http://www.kroah.com/linux/
 D: USB Serial Converter driver framework, USB Handspring Visor driver
 D: ConnectTech WHITEHeat USB driver, Generic USB Serial driver
 D: USB I/O Edgeport driver, USB Serial IrDA driver
@@ -1819,6 +1835,7 @@
 D: bits and pieces of USB core code.
 D: PCI Hotplug core, PCI Hotplug Compaq driver modifications
 D: portions of the Linux Security Module (LSM) framework
+D: parts of the driver core, debugfs.
 
 N: Russell Kroll
 E: rkroll@exploits.org
@@ -1893,7 +1910,7 @@
 D: Bug fixes
 
 N: Paul Laufer
-E: pelaufer@csupomona.edu
+E: paul@laufernet.com
 D: Soundblaster driver fixes, ISAPnP quirk
 S: California, USA
 
@@ -2021,6 +2038,17 @@
 E: hjl@gnu.ai.mit.edu
 D: GCC + libraries hacker
 
+N: Michal Ludvig
+E: michal@logix.cz
+E: michal.ludvig@asterisk.co.nz
+W: http://www.logix.cz/michal
+P: 1024D/C45B2218 1162 6471 D391 76E0 9F99  29DA 0C3A 2509 C45B 2218
+D: VIA PadLock driver
+D: Netfilter pkttype module
+S: Asterisk Ltd.
+S: Auckland
+S: New Zealand
+
 N: Tuomas J. Lukka
 E: Tuomas.Lukka@Helsinki.FI
 D: Original dual-monitor patches
@@ -2927,10 +2955,10 @@
 S: Finland
 
 N: Deepak Saxena
-E: deepak@csociety.purdue.edu
+E: dsaxena@plexity.net
 D: I2O kernel layer (config, block, core, pci, net). I2O disk support for LILO
-D: XScale(IOP310) porting
-S: Tempe, Arizona
+D: XScale(IOP, IXP) porting and other random ARM bits
+S: Portland, OR
 
 N: Eric Schenk
 E: Eric.Schenk@dna.lth.se
@@ -3156,6 +3184,14 @@
 S: Seattle, WA  98195-1800
 S: USA
 
+N: Eugene Surovegin
+E: ebs@ebshome.net
+W: http://kernel.ebshome.net/
+P: 1024D/AE5467F1 FF22 39F1 6728 89F6 6E6C  2365 7602 F33D AE54 67F1
+D: Embedded PowerPC 4xx: I2C, PIC and random hacks/fixes
+S: Sunnyvale, California 94085
+S: USA
+
 N: Corey Thomas
 E: corey@world.std.com
 W: http://world.std.com/~corey/index.html
@@ -3335,7 +3371,7 @@
 D: Atari Falcon chipset IDE
 D: Amiga Gayle chipset IDE
 D: mipsel NEC DDB Vrc-5074
-S: Holsbeeksesteenweg 166
+S: Emiel Vlieberghlaan 2A/21
 S: B-3010 Kessel-Lo
 S: Belgium
 
@@ -3569,7 +3605,6 @@
 
 N: David Woodhouse
 E: dwmw2@infradead.org
-E: dwmw2@redhat.com
 D: ARCnet stuff, Applicom board driver, SO_BINDTODEVICE,
 D: some Alpha platform porting from 2.0, Memory Technology Devices,
 D: Acquire watchdog timer, PC speaker driver maintenance,
diff -Nru a/Documentation/00-INDEX b/Documentation/00-INDEX
--- a/Documentation/00-INDEX	2005-03-01 23:38:54 -08:00
+++ b/Documentation/00-INDEX	2005-03-01 23:38:54 -08:00
@@ -40,8 +40,6 @@
 	- directory with info on RCU (read-copy update).
 README.DAC960
 	- info on Mylex DAC960/DAC1100 PCI RAID Controller Driver for Linux.
-README.moxa
-	- release notes for Moxa mutiport serial card.
 SAK.txt
 	- info on Secure Attention Keys.
 SubmittingDrivers
@@ -174,8 +172,6 @@
 	- info on typical Linux memory problems.
 mips/
 	- directory with info about Linux on MIPS architecture.
-mkdev.cciss
-	- script to make /dev entries for SMART controllers (see cciss.txt).
 mono.txt
 	- how to execute Mono-based .NET binaries with the help of BINFMT_MISC.
 moxa-smartio
diff -Nru a/Documentation/Changes b/Documentation/Changes
--- a/Documentation/Changes	2005-03-01 23:39:16 -08:00
+++ b/Documentation/Changes	2005-03-01 23:39:16 -08:00
@@ -223,6 +223,11 @@
 version v0.99.0 or higher. Running old versions may cause problems
 with programs using shared memory.
 
+udev
+----
+udev is a userspace application for populating /dev dynamically with
+only entries for devices actually present. udev replaces devfs.
+
 Networking
 ==========
 
@@ -368,6 +373,10 @@
 ----------
 o  <http://powertweak.sourceforge.net/>
 
+udev
+----
+o <http://www.kernel.org/pub/linux/utils/kernel/hotplug/udev.html>
+
 Networking
 **********
 
@@ -398,5 +407,4 @@
 NFS-Utils
 ---------
 o  <http://nfs.sourceforge.net/>
-
 
diff -Nru a/Documentation/DocBook/kernel-api.tmpl b/Documentation/DocBook/kernel-api.tmpl
--- a/Documentation/DocBook/kernel-api.tmpl	2005-03-01 23:38:44 -08:00
+++ b/Documentation/DocBook/kernel-api.tmpl	2005-03-01 23:38:44 -08:00
@@ -105,6 +105,15 @@
      </sect1>
   </chapter>
 
+  <chapter id="debugfs">
+     <title>The debugfs filesystem</title>
+ 
+     <sect1><title>debugfs interface</title>
+!Efs/debugfs/inode.c
+!Efs/debugfs/file.c
+     </sect1>
+  </chapter>
+
   <chapter id="vfs">
      <title>The Linux VFS</title>
      <sect1><title>The Directory Cache</title>
@@ -143,7 +152,6 @@
   <chapter id="netdev">
      <title>Network device support</title>
      <sect1><title>Driver Support</title>
-!Edrivers/net/net_init.c
 !Enet/core/dev.c
      </sect1>
      <sect1><title>8390 Based Network Cards</title>
diff -Nru a/Documentation/PCIEBUS-HOWTO.txt b/Documentation/PCIEBUS-HOWTO.txt
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/Documentation/PCIEBUS-HOWTO.txt	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,217 @@
+		The PCI Express Port Bus Driver Guide HOWTO
+	Tom L Nguyen tom.l.nguyen@intel.com
+			11/03/2004
+
+1. About this guide
+
+This guide describes the basics of the PCI Express Port Bus driver
+and provides information on how to enable the service drivers to
+register/unregister with the PCI Express Port Bus Driver.
+
+2. Copyright 2004 Intel Corporation
+
+3. What is the PCI Express Port Bus Driver
+
+A PCI Express Port is a logical PCI-PCI Bridge structure. There
+are two types of PCI Express Port: the Root Port and the Switch
+Port. The Root Port originates a PCI Express link from a PCI Express
+Root Complex and the Switch Port connects PCI Express links to
+internal logical PCI buses. The Switch Port, which has its secondary
+bus representing the switch's internal routing logic, is called the
+switch's Upstream Port. The switch's Downstream Port is bridging from
+switch's internal routing bus to a bus representing the downstream
+PCI Express link from the PCI Express Switch.
+
+A PCI Express Port can provide up to four distinct functions,
+referred to in this document as services, depending on its port type.
+PCI Express Port's services include native hotplug support (HP),
+power management event support (PME), advanced error reporting
+support (AER), and virtual channel support (VC). These services may
+be handled by a single complex driver or be individually distributed
+and handled by corresponding service drivers.
+
+4. Why use the PCI Express Port Bus Driver?
+
+In existing Linux kernels, the Linux Device Driver Model allows a
+physical device to be handled by only a single driver. The PCI
+Express Port is a PCI-PCI Bridge device with multiple distinct
+services. To maintain a clean and simple solution each service
+may have its own software service driver. In this case several
+service drivers will compete for a single PCI-PCI Bridge device.
+For example, if the PCI Express Root Port native hotplug service
+driver is loaded first, it claims a PCI-PCI Bridge Root Port. The
+kernel therefore does not load other service drivers for that Root
+Port. In other words, it is impossible to have multiple service
+drivers load and run on a PCI-PCI Bridge device simultaneously
+using the current driver model.
+
+To enable multiple service drivers running simultaneously requires
+having a PCI Express Port Bus driver, which manages all populated
+PCI Express Ports and distributes all provided service requests
+to the corresponding service drivers as required. Some key
+advantages of using the PCI Express Port Bus driver are listed below:
+
+	- Allow multiple service drivers to run simultaneously on
+	  a PCI-PCI Bridge Port device.
+
+	- Allow service drivers implemented in an independent
+	  staged approach.
+	
+	- Allow one service driver to run on multiple PCI-PCI Bridge
+	  Port devices. 
+
+	- Manage and distribute resources of a PCI-PCI Bridge Port
+	  device to requested service drivers.
+
+5. Configuring the PCI Express Port Bus Driver vs. Service Drivers
+
+5.1 Including the PCI Express Port Bus Driver Support into the Kernel
+
+Including the PCI Express Port Bus driver depends on whether the PCI
+Express support is included in the kernel config. The kernel will
+automatically include the PCI Express Port Bus driver as a kernel
+driver when the PCI Express support is enabled in the kernel.
+
+5.2 Enabling Service Driver Support
+
+PCI device drivers are implemented based on Linux Device Driver Model.
+All service drivers are PCI device drivers. As discussed above, it is
+impossible to load any service driver once the kernel has loaded the
+PCI Express Port Bus Driver. To meet the PCI Express Port Bus Driver
+Model requires some minimal changes on existing service drivers that
+imposes no impact on the functionality of existing service drivers.
+
+A service driver is required to use the two APIs shown below to
+register its service with the PCI Express Port Bus driver (see 
+section 5.2.1 & 5.2.2). It is important that a service driver
+initializes the pcie_port_service_driver data structure, included in
+header file /include/linux/pcieport_if.h, before calling these APIs.
+Failure to do so will result an identity mismatch, which prevents
+the PCI Express Port Bus driver from loading a service driver.
+
+5.2.1 pcie_port_service_register
+
+int pcie_port_service_register(struct pcie_port_service_driver *new)
+
+This API replaces the Linux Driver Model's pci_module_init API. A
+service driver should always calls pcie_port_service_register at
+module init. Note that after service driver being loaded, calls
+such as pci_enable_device(dev) and pci_set_master(dev) are no longer
+necessary since these calls are executed by the PCI Port Bus driver.
+
+5.2.2 pcie_port_service_unregister
+
+void pcie_port_service_unregister(struct pcie_port_service_driver *new)
+
+pcie_port_service_unregister replaces the Linux Driver Model's
+pci_unregister_driver. It's always called by service driver when a
+module exits.
+
+5.2.3 Sample Code
+
+Below is sample service driver code to initialize the port service
+driver data structure.
+
+static struct pcie_port_service_id service_id[] = { {
+	.vendor = PCI_ANY_ID,
+	.device = PCI_ANY_ID,
+	.port_type = PCIE_RC_PORT,
+	.service_type = PCIE_PORT_SERVICE_AER,
+	}, { /* end: all zeroes */ }
+};
+
+static struct pcie_port_service_driver root_aerdrv = {
+	.name		= (char *)device_name,
+	.id_table	= &service_id[0],
+
+	.probe		= aerdrv_load,
+	.remove		= aerdrv_unload,
+
+	.suspend	= aerdrv_suspend,
+	.resume		= aerdrv_resume,
+};
+
+Below is a sample code for registering/unregistering a service
+driver.
+
+static int __init aerdrv_service_init(void)
+{
+	int retval = 0;
+	
+	retval = pcie_port_service_register(&root_aerdrv);
+	if (!retval) {
+		/*
+		 * FIX ME
+		 */
+	}
+	return retval;
+}
+
+static void __exit aerdrv_service_exit(void) 
+{
+	pcie_port_service_unregister(&root_aerdrv);
+}
+
+module_init(aerdrv_service_init);
+module_exit(aerdrv_service_exit);
+
+6. Possible Resource Conflicts
+
+Since all service drivers of a PCI-PCI Bridge Port device are
+allowed to run simultaneously, below lists a few of possible resource
+conflicts with proposed solutions.
+
+6.1 MSI Vector Resource
+
+The MSI capability structure enables a device software driver to call
+pci_enable_msi to request MSI based interrupts. Once MSI interrupts
+are enabled on a device, it stays in this mode until a device driver
+calls pci_disable_msi to disable MSI interrupts and revert back to
+INTx emulation mode. Since service drivers of the same PCI-PCI Bridge
+port share the same physical device, if an individual service driver
+calls pci_enable_msi/pci_disable_msi it may result unpredictable
+behavior. For example, two service drivers run simultaneously on the
+same physical Root Port. Both service drivers call pci_enable_msi to
+request MSI based interrupts. A service driver may not know whether
+any other service drivers have run on this Root Port. If either one
+of them calls pci_disable_msi, it puts the other service driver
+in a wrong interrupt mode. 
+
+To avoid this situation all service drivers are not permitted to
+switch interrupt mode on its device. The PCI Express Port Bus driver
+is responsible for determining the interrupt mode and this should be
+transparent to service drivers. Service drivers need to know only
+the vector IRQ assigned to the field irq of struct pcie_device, which
+is passed in when the PCI Express Port Bus driver probes each service
+driver. Service drivers should use (struct pcie_device*)dev->irq to
+call request_irq/free_irq. In addition, the interrupt mode is stored
+in the field interrupt_mode of struct pcie_device.
+
+6.2 MSI-X Vector Resources
+
+Similar to the MSI a device driver for an MSI-X capable device can
+call pci_enable_msix to request MSI-X interrupts. All service drivers
+are not permitted to switch interrupt mode on its device. The PCI
+Express Port Bus driver is responsible for determining the interrupt
+mode and this should be transparent to service drivers. Any attempt
+by service driver to call pci_enable_msix/pci_disable_msix may
+result unpredictable behavior. Service drivers should use
+(struct pcie_device*)dev->irq and call request_irq/free_irq.
+
+6.3 PCI Memory/IO Mapped Regions
+
+Service drivers for PCI Express Power Management (PME), Advanced
+Error Reporting (AER), Hot-Plug (HP) and Virtual Channel (VC) access
+PCI configuration space on the PCI Express port. In all cases the
+registers accessed are independent of each other. This patch assumes
+that all service drivers will be well behaved and not overwrite
+other service driver's configuration settings.
+
+6.4 PCI Config Registers
+
+Each service driver runs its PCI config operations on its own
+capability structure except the PCI Express capability structure, in
+which Root Control register and Device Control register are shared
+between PME and AER. This patch assumes that all service drivers
+will be well behaved and not overwrite other service driver's
+configuration settings.
diff -Nru a/Documentation/README.cycladesZ b/Documentation/README.cycladesZ
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/Documentation/README.cycladesZ	2005-03-01 23:38:58 -08:00
@@ -0,0 +1,8 @@
+
+The Cyclades-Z must have firmware loaded onto the card before it will
+operate.  This operation should be performed during system startup,
+
+The firmware, loader program and the latest device driver code are
+available from Cyclades at
+    ftp://ftp.cyclades.com/pub/cyclades/cyclades-z/linux/
+
diff -Nru a/Documentation/README.moxa b/Documentation/README.moxa
--- a/Documentation/README.moxa	2005-03-01 23:38:52 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,18 +0,0 @@
- ===================================================================	
- Release Note of Linux Driver for Moxa's C104/C168/CI-104J
- ===================================================================	
-
- -------------------------------------------------------------------
- Ver. 1.1  				               Sep.  1, 1999
- -------------------------------------------------------------------
- 1. Improved:
-   a. Static driver (kernel) and dynamic driver (loadable module) 
-      modes are supported.
-   b. Multiple Smartio PCI series boards sharing the same IRQ 
-      supported.
-
- -------------------------------------------------------------------
- Ver. 1.0  				               Feb  17, 1997
- -------------------------------------------------------------------
- 1. Newly release.
-
diff -Nru a/Documentation/SAK.txt b/Documentation/SAK.txt
--- a/Documentation/SAK.txt	2005-03-01 23:38:57 -08:00
+++ b/Documentation/SAK.txt	2005-03-01 23:38:57 -08:00
@@ -1,5 +1,5 @@
 Linux 2.4.2 Secure Attention Key (SAK) handling
-18 March 2001, Andrew Morton <andrewm@uow.edu.au>
+18 March 2001, Andrew Morton <akpm@osdl.org>
 
 An operating system's Secure Attention Key is a security tool which is
 provided as protection against trojan password capturing programs.  It
@@ -44,7 +44,7 @@
    /dev/console opened.
 
    Unfortunately this includes a number of things which you don't
-   actually want killed.  This is because these appliccaitons are
+   actually want killed.  This is because these applications are
    incorrectly holding /dev/console open.  Be sure to complain to your
    Linux distributor about this!
 
diff -Nru a/Documentation/aoe/aoe.txt b/Documentation/aoe/aoe.txt
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/Documentation/aoe/aoe.txt	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,84 @@
+The EtherDrive (R) HOWTO for users of 2.6 kernels is found at ...
+
+  http://www.coraid.com/support/linux/EtherDrive-2.6-HOWTO.html
+
+  It has many tips and hints!
+
+CREATING DEVICE NODES
+
+  Users of udev should find device nodes created automatically.  Two
+  scripts are provided in Documentation/aoe as examples of static
+  device node creation for using the aoe driver.
+
+    rm -rf /dev/etherd
+    sh Documentation/aoe/mkdevs.sh /dev/etherd
+
+  ... or to make just one shelf's worth of block device nodes ...
+
+    sh Documentation/aoe/mkshelf.sh /dev/etherd 0
+
+  There is also an autoload script that shows how to edit
+  /etc/modprobe.conf to ensure that the aoe module is loaded when
+  necessary.
+
+USING DEVICE NODES
+
+  "cat /dev/etherd/err" blocks, waiting for error diagnostic output,
+  like any retransmitted packets.
+
+  "echo eth2 eth4 > /dev/etherd/interfaces" tells the aoe driver to
+  limit ATA over Ethernet traffic to eth2 and eth4.  AoE traffic from
+  untrusted networks should be ignored as a matter of security.
+
+  "echo > /dev/etherd/discover" tells the driver to find out what AoE
+  devices are available.
+
+  These character devices may disappear and be replaced by sysfs
+  counterparts, so distribution maintainers are encouraged to create
+  scripts that use these devices.
+
+  The block devices are named like this:
+
+	e{shelf}.{slot}
+	e{shelf}.{slot}p{part}
+
+  ... so that "e0.2" is the third blade from the left (slot 2) in the
+  first shelf (shelf address zero).  That's the whole disk.  The first
+  partition on that disk would be "e0.2p1".
+
+USING SYSFS
+
+  Each aoe block device in /sys/block has the extra attributes of
+  state, mac, and netif.  The state attribute is "up" when the device
+  is ready for I/O and "down" if detected but unusable.  The
+  "down,closewait" state shows that the device is still open and
+  cannot come up again until it has been closed.
+
+  The mac attribute is the ethernet address of the remote AoE device.
+  The netif attribute is the network interface on the localhost
+  through which we are communicating with the remote AoE device.
+
+  There is a script in this directory that formats this information
+  in a convenient way.
+
+  root@makki root# sh Documentation/aoe/status.sh 
+     e10.0            eth3              up
+     e10.1            eth3              up
+     e10.2            eth3              up
+     e10.3            eth3              up
+     e10.4            eth3              up
+     e10.5            eth3              up
+     e10.6            eth3              up
+     e10.7            eth3              up
+     e10.8            eth3              up
+     e10.9            eth3              up
+      e4.0            eth1              up
+      e4.1            eth1              up
+      e4.2            eth1              up
+      e4.3            eth1              up
+      e4.4            eth1              up
+      e4.5            eth1              up
+      e4.6            eth1              up
+      e4.7            eth1              up
+      e4.8            eth1              up
+      e4.9            eth1              up
diff -Nru a/Documentation/aoe/autoload.sh b/Documentation/aoe/autoload.sh
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/Documentation/aoe/autoload.sh	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,17 @@
+#!/bin/sh
+# set aoe to autoload by installing the
+# aliases in /etc/modprobe.conf
+
+f=/etc/modprobe.conf
+
+if test ! -r $f || test ! -w $f; then
+	echo "cannot configure $f for module autoloading" 1>&2
+	exit 1
+fi
+
+grep major-152 $f >/dev/null
+if [ $? = 1 ]; then
+	echo alias block-major-152 aoe >> $f
+	echo alias char-major-152 aoe >> $f
+fi
+
diff -Nru a/Documentation/aoe/mkdevs.sh b/Documentation/aoe/mkdevs.sh
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/Documentation/aoe/mkdevs.sh	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,36 @@
+#!/bin/sh
+
+n_shelves=${n_shelves:-10}
+n_partitions=${n_partitions:-16}
+
+if test "$#" != "1"; then
+	echo "Usage: sh `basename $0` {dir}" 1>&2
+	exit 1
+fi
+dir=$1
+
+MAJOR=152
+
+echo "Creating AoE devnode files in $dir ..."
+
+set -e
+
+mkdir -p $dir
+
+# (Status info is in sysfs.  See status.sh.)
+# rm -f $dir/stat
+# mknod -m 0400 $dir/stat c $MAJOR 1
+rm -f $dir/err
+mknod -m 0400 $dir/err c $MAJOR 2
+rm -f $dir/discover
+mknod -m 0200 $dir/discover c $MAJOR 3
+rm -f $dir/interfaces
+mknod -m 0200 $dir/interfaces c $MAJOR 4
+
+export n_partitions
+mkshelf=`echo $0 | sed 's!mkdevs!mkshelf!'`
+i=0
+while test $i -lt $n_shelves; do
+	sh -xc "sh $mkshelf $dir $i"
+	i=`expr $i + 1`
+done
diff -Nru a/Documentation/aoe/mkshelf.sh b/Documentation/aoe/mkshelf.sh
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/Documentation/aoe/mkshelf.sh	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,25 @@
+#! /bin/sh
+
+if test "$#" != "2"; then
+	echo "Usage: sh `basename $0` {dir} {shelfaddress}" 1>&2
+	exit 1
+fi
+n_partitions=${n_partitions:-16}
+dir=$1
+shelf=$2
+MAJOR=152
+
+set -e
+
+minor=`echo 10 \* $shelf \* $n_partitions | bc`
+endp=`echo $n_partitions - 1 | bc`
+for slot in `seq 0 9`; do
+	for part in `seq 0 $endp`; do
+		name=e$shelf.$slot
+		test "$part" != "0" && name=${name}p$part
+		rm -f $dir/$name
+		mknod -m 0660 $dir/$name b $MAJOR $minor
+
+		minor=`expr $minor + 1`
+	done
+done
diff -Nru a/Documentation/aoe/status.sh b/Documentation/aoe/status.sh
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/Documentation/aoe/status.sh	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,28 @@
+#! /bin/sh
+# collate and present sysfs information about AoE storage
+
+set -e
+format="%8s\t%8s\t%8s\n"
+me=`basename $0`
+
+# printf "$format" device mac netif state
+
+test -z "`mount | grep sysfs`" && {
+	echo "$me Error: sysfs is not mounted" 1>&2
+	exit 1
+}
+test -z "`lsmod | grep '^aoe'`" && {
+	echo  "$me Error: aoe module is not loaded" 1>&2
+	exit 1
+}
+
+for d in `ls -d /sys/block/etherd* 2>/dev/null | grep -v p` end; do
+	# maybe ls comes up empty, so we use "end"
+	test $d = end && continue
+
+	dev=`echo "$d" | sed 's/.*!//'`
+	printf "$format" \
+		"$dev" \
+		"`cat \"$d/netif\"`" \
+		"`cat \"$d/state\"`"
+done | sort
diff -Nru a/Documentation/arm/IXP4xx b/Documentation/arm/IXP4xx
--- a/Documentation/arm/IXP4xx	2005-03-01 23:38:52 -08:00
+++ b/Documentation/arm/IXP4xx	2005-03-01 23:38:52 -08:00
@@ -12,8 +12,11 @@
 in industrial control and other areas due to low cost and power
 consumption. The IXP4xx family currently consists of several processors
 that support different network offload functions such as encryption,
-routing, firewalling, etc. For more information on the various
-versions of the CPU, see:
+routing, firewalling, etc. The IXP46x family is an updated version which
+supports faster speeds, new memory and flash configurations, and more
+integration such as an on-chip I2C controller.
+
+For more information on the various versions of the CPU, see:
 
    http://developer.intel.com/design/network/products/npfamily/ixp4xx.htm
 
@@ -27,7 +30,7 @@
 - Dual serial ports
 - PCI interface
 - Flash access (MTD/JFFS)
-- I2C through GPIO
+- I2C through GPIO on IXP42x
 - GPIO for input/output/interrupts 
   See include/asm-arm/arch-ixp4xx/platform.h for access functions.
 - Timers (watchdog, OS)
@@ -122,6 +125,12 @@
    also known as the Richfield board. It contains 4 PCI slots, 16MB
    of flash, two 10/100 ports and one ADSL port.
 
+Intel IXDP465 Development Platform
+http://developer.intel.com/design/network/products/npfamily/ixdp465.htm
+
+   This is basically an IXDP425 with an IXP465 and 32M of flash instead
+   of just 16.
+
 Intel IXDPG425 Development Platform
 
    This is basically and ADI Coyote board with a NEC EHCI controller
@@ -154,6 +163,7 @@
 
 The following people have contributed patches/comments/etc:
 
+Lennerty Buytenhek
 Lutz Jaenicke
 Justin Mayfield
 Robert E. Ranslam
@@ -161,4 +171,4 @@
 
 -------------------------------------------------------------------------
 
-Last Update: 11/16/2004
+Last Update: 01/04/2005
diff -Nru a/Documentation/arm/Samsung-S3C24XX/Overview.txt b/Documentation/arm/Samsung-S3C24XX/Overview.txt
--- a/Documentation/arm/Samsung-S3C24XX/Overview.txt	2005-03-01 23:39:17 -08:00
+++ b/Documentation/arm/Samsung-S3C24XX/Overview.txt	2005-03-01 23:39:17 -08:00
@@ -45,6 +45,12 @@
     Handheld (IPAQ), available in several varieties
 
 
+  HP iPAQ rx3715
+
+    S3C2440 based IPAQ, with a number of variations depending on
+    features shipped.
+
+
 NAND
 ----
 
@@ -91,6 +97,8 @@
   Roc Wu
   Klaus Fetscher
   Dimitry Andric
+  Shannon Holland
+
 
 Document Changes
 ----------------
@@ -99,8 +107,9 @@
   05 Sep 2004 - BJD - Added Klaus Fetscher to list of contributors
   25 Oct 2004 - BJD - Added Dimitry Andric to list of contributors
   25 Oct 2004 - BJD - Updated the MTD from the 2.6.9 merge
+  21 Jan 2005 - BJD - Added rx3715, added Shannon to contributors
 
 Document Author
 ---------------
 
-Ben Dooks, (c) 2004 Simtec Electronics
+Ben Dooks, (c) 2004-2005 Simtec Electronics
diff -Nru a/Documentation/atomic_ops.txt b/Documentation/atomic_ops.txt
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/Documentation/atomic_ops.txt	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,456 @@
+		Semantics and Behavior of Atomic and
+		         Bitmask Operations
+
+			  David S. Miller	 
+
+	This document is intended to serve as a guide to Linux port
+maintainers on how to implement atomic counter, bitops, and spinlock
+interfaces properly.
+
+	The atomic_t type should be defined as a signed integer.
+Also, it should be made opaque such that any kind of cast to a normal
+C integer type will fail.  Something like the following should
+suffice:
+
+	typedef struct { volatile int counter; } atomic_t;
+
+	The first operations to implement for atomic_t's are the
+initializers and plain reads.
+
+	#define ATOMIC_INIT(i)		{ (i) }
+	#define atomic_set(v, i)	((v)->counter = (i))
+
+The first macro is used in definitions, such as:
+
+static atomic_t my_counter = ATOMIC_INIT(1);
+
+The second interface can be used at runtime, as in:
+
+	struct foo { atomic_t counter; };
+	...
+
+	struct foo *k;
+
+	k = kmalloc(sizeof(*k), GFP_KERNEL);
+	if (!k)
+		return -ENOMEM;
+	atomic_set(&k->counter, 0);
+
+Next, we have:
+
+	#define atomic_read(v)	((v)->counter)
+
+which simply reads the current value of the counter.
+
+Now, we move onto the actual atomic operation interfaces.
+
+	void atomic_add(int i, atomic_t *v);
+	void atomic_sub(int i, atomic_t *v);
+	void atomic_inc(atomic_t *v);
+	void atomic_dec(atomic_t *v);
+
+These four routines add and subtract integral values to/from the given
+atomic_t value.  The first two routines pass explicit integers by
+which to make the adjustment, whereas the latter two use an implicit
+adjustment value of "1".
+
+One very important aspect of these two routines is that they DO NOT
+require any explicit memory barriers.  They need only perform the
+atomic_t counter update in an SMP safe manner.
+
+Next, we have:
+
+	int atomic_inc_return(atomic_t *v);
+	int atomic_dec_return(atomic_t *v);
+
+These routines add 1 and subtract 1, respectively, from the given
+atomic_t and return the new counter value after the operation is
+performed.
+
+Unlike the above routines, it is required that explicit memory
+barriers are performed before and after the operation.  It must be
+done such that all memory operations before and after the atomic
+operation calls are strongly ordered with respect to the atomic
+operation itself.
+
+For example, it should behave as if a smp_mb() call existed both
+before and after the atomic operation.
+
+If the atomic instructions used in an implementation provide explicit
+memory barrier semantics which satisfy the above requirements, that is
+fine as well.
+
+Let's move on:
+
+	int atomic_add_return(int i, atomic_t *v);
+	int atomic_sub_return(int i, atomic_t *v);
+
+These behave just like atomic_{inc,dec}_return() except that an
+explicit counter adjustment is given instead of the implicit "1".
+This means that like atomic_{inc,dec}_return(), the memory barrier
+semantics are required.
+
+Next:
+
+	int atomic_inc_and_test(atomic_t *v);
+	int atomic_dec_and_test(atomic_t *v);
+
+These two routines increment and decrement by 1, respectively, the
+given atomic counter.  They return a boolean indicating whether the
+resulting counter value was zero or not.
+
+It requires explicit memory barrier semantics around the operation as
+above.
+
+	int atomic_sub_and_test(int i, atomic_t *v);
+
+This is identical to atomic_dec_and_test() except that an explicit
+decrement is given instead of the implicit "1".  It requires explicit
+memory barrier semantics around the operation.
+
+	int atomic_add_negative(int i, atomic_t *v);
+
+The given increment is added to the given atomic counter value.  A
+boolean is return which indicates whether the resulting counter value
+is negative.  It requires explicit memory barrier semantics around the
+operation.
+
+If a caller requires memory barrier semantics around an atomic_t
+operation which does not return a value, a set of interfaces are
+defined which accomplish this:
+
+	void smp_mb__before_atomic_dec(void);
+	void smp_mb__after_atomic_dec(void);
+	void smp_mb__before_atomic_inc(void);
+	void smp_mb__after_atomic_dec(void);
+
+For example, smp_mb__before_atomic_dec() can be used like so:
+
+	obj->dead = 1;
+	smp_mb__before_atomic_dec();
+	atomic_dec(&obj->ref_count);
+
+It makes sure that all memory operations preceeding the atomic_dec()
+call are strongly ordered with respect to the atomic counter
+operation.  In the above example, it guarentees that the assignment of
+"1" to obj->dead will be globally visible to other cpus before the
+atomic counter decrement.
+
+Without the explicitl smp_mb__before_atomic_dec() call, the
+implementation could legally allow the atomic counter update visible
+to other cpus before the "obj->dead = 1;" assignment.
+
+The other three interfaces listed are used to provide explicit
+ordering with respect to memory operations after an atomic_dec() call
+(smp_mb__after_atomic_dec()) and around atomic_inc() calls
+(smp_mb__{before,after}_atomic_inc()).
+
+A missing memory barrier in the cases where they are required by the
+atomic_t implementation above can have disasterous results.  Here is
+an example, which follows a pattern occuring frequently in the Linux
+kernel.  It is the use of atomic counters to implement reference
+counting, and it works such that once the counter falls to zero it can
+be guarenteed that no other entity can be accessing the object:
+
+static void obj_list_add(struct obj *obj)
+{
+	obj->active = 1;
+	list_add(&obj->list);
+}
+
+static void obj_list_del(struct obj *obj)
+{
+	list_del(&obj->list);
+	obj->active = 0;
+}
+
+static void obj_destroy(struct obj *obj)
+{
+	BUG_ON(obj->active);
+	kfree(obj);
+}
+
+struct obj *obj_list_peek(struct list_head *head)
+{
+	if (!list_empty(head)) {
+		struct obj *obj;
+
+		obj = list_entry(head->next, struct obj, list);
+		atomic_inc(&obj->refcnt);
+		return obj;
+	}
+	return NULL;
+}
+
+void obj_poke(void)
+{
+	struct obj *obj;
+
+	spin_lock(&global_list_lock);
+	obj = obj_list_peek(&global_list);
+	spin_unlock(&global_list_lock);
+
+	if (obj) {
+		obj->ops->poke(obj);
+		if (atomic_dec_and_test(&obj->refcnt))
+			obj_destroy(obj);
+	}
+}
+
+void obj_timeout(struct obj *obj)
+{
+	spin_lock(&global_list_lock);
+	obj_list_del(obj);
+	spin_unlock(&global_list_lock);
+
+	if (atomic_dec_and_test(&obj->refcnt))
+		obj_destroy(obj);
+}
+
+(This is a simplification of the ARP queue management in the
+ generic neighbour discover code of the networking.  Olaf Kirch
+ found a bug wrt. memory barriers in kfree_skb() that exposed
+ the atomic_t memory barrier requirements quite clearly.)
+
+Given the above scheme, it must be the case that the obj->active
+update done by the obj list deletion be visible to other processors
+before the atomic counter decrement is performed.
+
+Otherwise, the counter could fall to zero, yet obj->active would still
+be set, thus triggering the assertion in obj_destroy().  The error
+sequence looks like this:
+
+	cpu 0				cpu 1
+	obj_poke()			obj_timeout()
+	obj = obj_list_peek();
+	... gains ref to obj, refcnt=2
+					obj_list_del(obj);
+					obj->active = 0 ...
+					... visibility delayed ...
+					atomic_dec_and_test()
+					... refcnt drops to 1 ...
+	atomic_dec_and_test()
+	... refcount drops to 0 ...
+	obj_destroy()
+	BUG() triggers since obj->active
+	still seen as one
+					obj->active update visibility occurs
+
+With the memory barrier semantics required of the atomic_t operations
+which return values, the above sequence of memory visibility can never
+happen.  Specifically, in the above case the atomic_dec_and_test()
+counter decrement would not become globally visible until the
+obj->active update does.
+
+As a historical note, 32-bit Sparc used to only allow usage of
+24-bits of it's atomic_t type.  This was because it used 8 bits
+as a spinlock for SMP safety.  Sparc32 lacked a "compare and swap"
+type instruction.  However, 32-bit Sparc has since been moved over
+to a "hash table of spinlocks" scheme, that allows the full 32-bit
+counter to be realized.  Essentially, an array of spinlocks are
+indexed into based upon the address of the atomic_t being operated
+on, and that lock protects the atomic operation.  Parisc uses the
+same scheme.
+
+Another note is that the atomic_t operations returning values are
+extremely slow on an old 386.
+
+We will now cover the atomic bitmask operations.  You will find that
+their SMP and memory barrier semantics are similar in shape and scope
+to the atomic_t ops above.
+
+Native atomic bit operations are defined to operate on objects aligned
+to the size of an "unsigned long" C data type, and are least of that
+size.  The endianness of the bits within each "unsigned long" are the
+native endianness of the cpu.
+
+	void set_bit(unsigned long nr, volatils unsigned long *addr);
+	void clear_bit(unsigned long nr, volatils unsigned long *addr);
+	void change_bit(unsigned long nr, volatils unsigned long *addr);
+
+These routines set, clear, and change, respectively, the bit number
+indicated by "nr" on the bit mask pointed to by "ADDR".
+
+They must execute atomically, yet there are no implicit memory barrier
+semantics required of these interfaces.
+
+	int test_and_set_bit(unsigned long nr, volatils unsigned long *addr);
+	int test_and_clear_bit(unsigned long nr, volatils unsigned long *addr);
+	int test_and_change_bit(unsigned long nr, volatils unsigned long *addr);
+
+Like the above, except that these routines return a boolean which
+indicates whether the changed bit was set _BEFORE_ the atomic bit
+operation.
+
+WARNING! It is incredibly important that the value be a boolean,
+ie. "0" or "1".  Do not try to be fancy and save a few instructions by
+declaring the above to return "long" and just returning something like
+"old_val & mask" because that will not work.
+
+For one thing, this return value gets truncated to int in many code
+paths using these interfaces, so on 64-bit if the bit is set in the
+upper 32-bits then testers will never see that.
+
+One great example of where this problem crops up are the thread_info
+flag operations.  Routines such as test_and_set_ti_thread_flag() chop
+the return value into an int.  There are other places where things
+like this occur as well.
+
+These routines, like the atomic_t counter operations returning values,
+require explicit memory barrier semantics around their execution.  All
+memory operations before the atomic bit operation call must be made
+visible globally before the atomic bit operation is made visible.
+Likewise, the atomic bit operation must be visible globally before any
+subsequent memory operation is made visible.  For example:
+
+	obj->dead = 1;
+	if (test_and_set_bit(0, &obj->flags))
+		/* ... */;
+	obj->killed = 1;
+
+The implementation of test_and_set_bit() must guarentee that
+"obj->dead = 1;" is visible to cpus before the atomic memory operation
+done by test_and_set_bit() becomes visible.  Likewise, the atomic
+memory operation done by test_and_set_bit() must become visible before
+"obj->killed = 1;" is visible.
+
+Finally there is the basic operation:
+
+	int test_bit(unsigned long nr, __const__ volatile unsigned long *addr);
+
+Which returns a boolean indicating if bit "nr" is set in the bitmask
+pointed to by "addr".
+
+If explicit memory barriers are required around clear_bit() (which
+does not return a value, and thus does not need to provide memory
+barrier semantics), two interfaces are provided:
+
+	void smp_mb__before_clear_bit(void);
+	void smp_mb__after_clear_bit(void);
+
+They are used as follows, and are akin to their atomic_t operation
+brothers:
+
+	/* All memory operations before this call will
+	 * be globally visible before the clear_bit().
+	 */
+	smp_mb__before_clear_bit();
+	clear_bit( ... );
+
+	/* The clear_bit() will be visible before all
+	 * subsequent memory operations.
+	 */
+	 smp_mb__after_clear_bit();
+
+Finally, there are non-atomic versions of the bitmask operations
+provided.  They are used in contexts where some other higher-level SMP
+locking scheme is being used to protect the bitmask, and thus less
+expensive non-atomic operations may be used in the implementation.
+They have names similar to the above bitmask operation interfaces,
+except that two underscores are prefixed to the interface name.
+
+	void __set_bit(unsigned long nr, volatile unsigned long *addr);
+	void __clear_bit(unsigned long nr, volatile unsigned long *addr);
+	void __change_bit(unsigned long nr, volatile unsigned long *addr);
+	int __test_and_set_bit(unsigned long nr, volatile unsigned long *addr);
+	int __test_and_clear_bit(unsigned long nr, volatile unsigned long *addr);
+	int __test_and_change_bit(unsigned long nr, volatile unsigned long *addr);
+
+These non-atomic variants also do not require any special memory
+barrier semantics.
+
+The routines xchg() and cmpxchg() need the same exact memory barriers
+as the atomic and bit operations returning values.
+
+Spinlocks and rwlocks have memory barrier expectations as well.
+The rule to follow is simple:
+
+1) When acquiring a lock, the implementation must make it globally
+   visible before any subsequent memory operation.
+
+2) When releasing a lock, the implementation must make it such that
+   all previous memory operations are globally visible before the
+   lock release.
+
+Which finally brings us to _atomic_dec_and_lock().  There is an
+architecture-neutral version implemented in lib/dec_and_lock.c,
+but most platforms will wish to optimize this in assembler.
+
+	int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock);
+
+Atomically decrement the given counter, and if will drop to zero
+atomically acquire the given spinlock and perform the decrement
+of the counter to zero.  If it does not drop to zero, do nothing
+with the spinlock.
+
+It is actually pretty simple to get the memory barrier correct.
+Simply satisfy the spinlock grab requirements, which is make
+sure the spinlock operation is globally visible before any
+subsequent memory operation.
+
+We can demonstrate this operation more clearly if we define
+an abstract atomic operation:
+
+	long cas(long *mem, long old, long new);
+
+"cas" stands for "compare and swap".  It atomically:
+
+1) Compares "old" with the value currently at "mem".
+2) If they are equal, "new" is written to "mem".
+3) Regardless, the current value at "mem" is returned.
+
+As an example usage, here is what an atomic counter update
+might look like:
+
+void example_atomic_inc(long *counter)
+{
+	long old, new, ret;
+
+	while (1) {
+		old = *counter;
+		new = old + 1;
+
+		ret = cas(counter, old, new);
+		if (ret == old)
+			break;
+	}
+}
+
+Let's use cas() in order to build a pseudo-C atomic_dec_and_lock():
+
+int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock)
+{
+	long old, new, ret;
+	int went_to_zero;
+
+	went_to_zero = 0;
+	while (1) {
+		old = atomic_read(atomic);
+		new = old - 1;
+		if (new == 0) {
+			went_to_zero = 1;
+			spin_lock(lock);
+		}
+		ret = cas(atomic, old, new);
+		if (ret == old)
+			break;
+		if (went_to_zero) {
+			spin_unlock(lock);
+			went_to_zero = 0;
+		}
+	}
+
+	return went_to_zero;
+}
+
+Now, as far as memory barriers go, as long as spin_lock()
+strictly orders all subsequent memory operations (including
+the cas()) with respect to itself, things will be fine.
+
+Said another way, _atomic_dec_and_lock() must guarentee that
+a counter dropping to zero is never made visible before the
+spinlock being acquired.
+
+Note that this also means that for the case where the counter
+is not dropping to zero, there are no memory ordering
+requirements.
diff -Nru a/Documentation/cciss.txt b/Documentation/cciss.txt
--- a/Documentation/cciss.txt	2005-03-01 23:38:52 -08:00
+++ b/Documentation/cciss.txt	2005-03-01 23:38:52 -08:00
@@ -14,28 +14,29 @@
 	* SA 6400
 	* SA 6400 U320 Expansion Module
 	* SA 6i
-	* SA 6422
-	* SA V100
+	* SA P600
 
-If nodes are not already created in the /dev/cciss directory
+If nodes are not already created in the /dev/cciss directory, run as root:
 
-# mkdev.cciss [ctlrs]
-
-Where ctlrs is the number of controllers you have (defaults to 1 if not
-specified).
+# cd /dev
+# ./MAKEDEV cciss
 
 Device Naming:
 --------------
 
-You need some entries in /dev for the cciss device.  The mkdev.cciss script
+You need some entries in /dev for the cciss device.  The MAKEDEV script
 can make device nodes for you automatically.  Currently the device setup
 is as follows:
 
 Major numbers:
 	104	cciss0	
 	105	cciss1	
-	106	cciss2 
-	etc...
+	106	cciss2
+	105	cciss3
+	108	cciss4
+	109	cciss5
+	110	cciss6
+	111	cciss7
 
 Minor numbers:
         b7 b6 b5 b4 b3 b2 b1 b0
@@ -45,7 +46,7 @@
              |
              +-------------------- Logical Volume number
 
-The suggested device naming scheme is:
+The device naming scheme is:
 /dev/cciss/c0d0			Controller 0, disk 0, whole device
 /dev/cciss/c0d0p1		Controller 0, disk 0, partition 1
 /dev/cciss/c0d0p2		Controller 0, disk 0, partition 2
@@ -117,16 +118,13 @@
 
 Note that the naming convention of the /proc filesystem entries 
 contains a number in addition to the driver name.  (E.g. "cciss0" 
-instead of just "cciss" which you might expect.)   This is because 
-of changes to the 2.4 kernel PCI interface related to PCI hot plug
-that imply the driver must register with the SCSI mid layer once per
-adapter instance rather than once per driver.
+instead of just "cciss" which you might expect.)
 
 Note: ONLY sequential access devices and medium changers are presented 
 as SCSI devices to the SCSI mid layer by the cciss driver.  Specifically, 
 physical SCSI disk drives are NOT presented to the SCSI mid layer.  The 
 physical SCSI disk drives are controlled directly by the array controller 
-hardware and it is important to prevent the OS from attempting to directly 
+hardware and it is important to prevent the kernel from attempting to directly
 access these devices too, as if the array controller were merely a SCSI 
 controller in the same way that we are allowing it to access SCSI tape drives.
 
diff -Nru a/Documentation/cdrom/packet-writing.txt b/Documentation/cdrom/packet-writing.txt
--- a/Documentation/cdrom/packet-writing.txt	2005-03-01 23:38:54 -08:00
+++ b/Documentation/cdrom/packet-writing.txt	2005-03-01 23:38:54 -08:00
@@ -43,6 +43,8 @@
 that it should be possible to put any filesystem with a block size >=
 2KB on such a disc. For example, it should be possible to do:
 
+	# dvd+rw-format /dev/hdc   (only needed if the disc has never
+	                            been formatted)
 	# mkudffs /dev/hdc
 	# mount /dev/hdc /cdrom -t udf -o rw,noatime
 
@@ -54,6 +56,7 @@
 Both problems can be solved by using the pktcdvd driver, which always
 generates aligned writes.
 
+	# dvd+rw-format /dev/hdc
 	# pktsetup dev_name /dev/hdc
 	# mkudffs /dev/pktcdvd/dev_name
 	# mount /dev/pktcdvd/dev_name /cdrom -t udf -o rw,noatime
diff -Nru a/Documentation/cpu-freq/index.txt b/Documentation/cpu-freq/index.txt
--- a/Documentation/cpu-freq/index.txt	2005-03-01 23:38:51 -08:00
+++ b/Documentation/cpu-freq/index.txt	2005-03-01 23:38:51 -08:00
@@ -35,10 +35,10 @@
 ------------
 There is a CPU frequency changing CVS commit and general list where
 you can report bugs, problems or submit patches. To post a message,
-send an email to cpufreq@www.linux.org.uk, to subscribe go to
-http://www.linux.org.uk/mailman/listinfo/cpufreq. Previous post to the
+send an email to cpufreq@lists.linux.org.uk, to subscribe go to
+http://lists.linux.org.uk/mailman/listinfo/cpufreq. Previous post to the
 mailing list are available to subscribers at
-http://www.linux.org.uk/mailman/private/cpufreq/.
+http://lists.linux.org.uk/mailman/private/cpufreq/.
 
 
 Links
@@ -50,7 +50,7 @@
 * http://cvs.arm.linux.org.uk/
 
 the CPUFreq Mailing list:
-* http://www.linux.org.uk/mailman/listinfo/cpufreq
+* http://lists.linux.org.uk/mailman/listinfo/cpufreq
 
 Clock and voltage scaling for the SA-1100:
 * http://www.lart.tudelft.nl/projects/scaling
diff -Nru a/Documentation/devices.txt b/Documentation/devices.txt
--- a/Documentation/devices.txt	2005-03-01 23:38:55 -08:00
+++ b/Documentation/devices.txt	2005-03-01 23:38:55 -08:00
@@ -1,9 +1,9 @@
 
-		       LINUX ALLOCATED DEVICES
+		    LINUX ALLOCATED DEVICES (2.6+ version)
 
 	     Maintained by Torben Mathiasen <device@lanana.org>
 
-		      Last revised: 04 August 2004
+		      Last revised: 25 January 2005
 
 This list is the Linux Device List, the official registry of allocated
 device numbers and /dev directory nodes for the Linux operating
@@ -24,7 +24,8 @@
 the Atari platform only.
 
 The symbol {2.6} means the allocation is obsolete and scheduled for
-removal once kernel version 2.6 (or equivalent) is released.
+removal once kernel version 2.6 (or equivalent) is released. Some of these
+allocations have already been removed.
 
 This document is in the public domain.	The author requests, however,
 that semantically altered versions are not distributed without
@@ -41,13 +42,6 @@
 
 	  **** DEVICE DRIVERS AUTHORS PLEASE READ THIS ****
 
-THE DEVICE REGISTRY IS OFFICIALLY FROZEN FOR LINUS TORVALDS' KERNEL
-TREE.  At Linus' request, no more allocations will be made official
-for Linus' kernel tree; the 3 June 2001 version of this list is the
-official final version of this registry.  At Alan Cox' request,
-however, the registry will continue to be maintained for the -ac
-series of kernels, and registrations will be accepted.
-
 To have a major number allocated, or a minor number in situations
 where that applies (e.g. busmice), please contact me with the
 appropriate device information.	 Also, if you have additional
@@ -436,6 +430,8 @@
 		226 = /dev/systrace	Systrace device
 		227 = /dev/mcelog	X86_64 Machine Check Exception driver
 		228 = /dev/hpet		HPET driver
+		229 = /dev/fuse		Fuse (virtual filesystem in user-space)
+		230 = /dev/midishare	MidiShare driver
 		240-254			Reserved for local use
 		255			Reserved for MISC_DYNAMIC_MINOR
 
@@ -1176,7 +1172,7 @@
 
 		Requested by: andy@scramdisklinux.org
 
- 65 char	Sundance "plink" Transputer boards
+ 65 char	Sundance "plink" Transputer boards (obsolete, unused)
 		  0 = /dev/plink0	First plink device
 		  1 = /dev/plink1	Second plink device
 		  2 = /dev/plink2	Third plink device
@@ -1526,12 +1522,12 @@
 		disks (see major number 3) except that the limit on
 		partitions is 15.
 
- 83 char	Teletext/videotext interfaces {2.6}
-		  0 = /dev/vtx		Teletext decoder
-		 16 = /dev/vttuner	TV tuner on teletext interface
-
-		Devices for the driver contained in the VideoteXt package.
-		More information on http://home.pages.de/~videotext/
+ 83 char	Matrox mga_vid video driver
+ 		 0 = /dev/mga_vid0	1st video card
+		 1 = /dev/mga_vid1	2nd video card
+		 2 = /dev/mga_vid2	3rd video card
+		  ...
+	        15 = /dev/mga_vid15	16th video card
 
  83 block	I2O hard disk
 		  0 = /dev/i2o/hdaw	49th I2O hard disk, whole disk
@@ -1701,11 +1697,6 @@
 		  3 = /dev/ipauth	Authentication control device/log file
 		    ...		
 
- 95 block	IBM S/390 VM/ESA minidisk
-		  0 = /dev/msd0		First VM/ESA minidisk
-		  1 = /dev/msd1		Second VM/ESA minidisk
-		    ...
-
  96 char	Parallel port ATAPI tape devices
 		  0 = /dev/pt0		First parallel port ATAPI tape
 		  1 = /dev/pt1		Second parallel port ATAPI tape
@@ -1742,10 +1733,14 @@
 		See http://stm.lbl.gov/comedi or http://www.llp.fu-berlin.de/.
 
  98 block	User-mode virtual block device
-		  0 = /dev/ubd0		First user-mode block device
-		  1 = /dev/ubd1		Second user-mode block device
+		  0 = /dev/ubda		First user-mode block device
+		 16 = /dev/udbb		Second user-mode block device
 		    ...
 
+		Partitions are handled in the same way as for IDE
+		disks (see major number 3) except that the limit on
+		partitions is 15.
+
 		This device is used by the user-mode virtual kernel port.
 
  99 char	Raw parallel ports
@@ -2109,6 +2104,7 @@
 		disks (see major number 3) except that the limit on
 		partitions is 15.
 
+130 char 	(Misc devices)
 
 130 block       SCSI disk devices (160-175)
                   0 = /dev/sdfe         161st SCSI disk whole disk
@@ -2546,7 +2542,12 @@
 		  0 = /dev/usb/lp0	First USB printer
 		    ...
 		 15 = /dev/usb/lp15	16th USB printer
-		 32 = /dev/usb/mdc800	MDC800 USB camera
+		 16 = /dev/usb/mouse0	First USB mouse
+		    ...
+		 31 = /dev/usb/mouse15	16th USB mouse
+		 32 = /dev/usb/ez0	First USB firmware loader
+		    ...
+		 47 = /dev/usb/ez15	16th USB firmware loader
 		 48 = /dev/usb/scanner0	First USB scanner
 		    ...
 		 63 = /dev/usb/scanner15 16th USB scanner
@@ -2554,22 +2555,11 @@
 		 65 = /dev/usb/usblcd	USBLCD Interface (info@usblcd.de)
 		 66 = /dev/usb/cpad0	Synaptics cPad (mouse/LCD)
 
-		 96 = /dev/usb/hiddev0	1st USB HID device
-		    ...
-		111 = /dev/usb/hiddev15	16th USB HID device
-		112 = /dev/usb/auer0	1st auerswald ISDN device
-		    ...
-		127 = /dev/usb/auer15	16th auerswald ISDN device
-		128 = /dev/usb/brlvgr0	First Braille Voyager device
-		    ...
-		131 = /dev/usb/brlvgr3	Fourth Braille Voyager device
-		144 = /dev/usb/lcd	USB LCD device
-		160 = /dev/usb/legousbtower0	1st USB Legotower device
-		    ...
-		175 = /dev/usb/legousbtower15	16th USB Legotower device
-		240 = /dev/usb/dabusb0	First daubusb device
-		    ...
-		243 = /dev/usb/dabusb3	Fourth dabusb device
+180 block	USB block devices
+		0 = /dev/uba		First USB block device
+		8 = /dev/ubb		Second USB block device
+		16 = /dev/ubc		Thrid USB block device
+		...
 
 181 char	Conrad Electronic parallel port radio clocks
 		  0 = /dev/pcfclock0	First Conrad radio clock
@@ -2760,8 +2750,10 @@
 		 45 = /dev/ttyMM1		Marvell MPSC - port 1
 		 46 = /dev/ttyCPM0		PPC CPM (SCC or SMC) - port 0
 		    ...
-		 49 = /dev/ttyCPM5		PPC CPM (SCC or SMC) - port 5
-
+		 47 = /dev/ttyCPM5		PPC CPM (SCC or SMC) - port 5
+		 50 = /dev/ttyIOC40		Altix serial card
+		    ...
+		 81 = /dev/ttyIOC431		Altix serial card
 
 205 char	Low-density serial ports (alternate device)
 		  0 = /dev/culu0		Callout device for ttyLU0
@@ -2787,12 +2779,16 @@
 		    ...
 		 39 = /dev/cudb7		Callout device for ttyDB7
 		 40 = /dev/cusg0		Callout device for ttySG0
-		 41 = /dev/ttySMX0		Callout device for ttySMX0
-		 42 = /dev/ttySMX1		Callout device for ttySMX1
-		 43 = /dev/ttySMX2		Callout device for ttySMX2
+		 41 = /dev/ttycusmx0		Callout device for ttySMX0
+		 42 = /dev/ttycusmx1		Callout device for ttySMX1
+		 43 = /dev/ttycusmx2		Callout device for ttySMX2
 		 46 = /dev/cucpm0		Callout device for ttyCPM0
 		    ...
 		 49 = /dev/cucpm5		Callout device for ttyCPM5
+		 50 = /dev/cuioc40		Callout device for ttyIOC40
+		    ...
+		 81 = /dev/cuioc431		Callout device for ttyIOC431
+
 
 206 char	OnStream SC-x0 tape devices
 		  0 = /dev/osst0		First OnStream SCSI tape, mode 0
@@ -3006,7 +3002,12 @@
 		ioctl()'s can be used to rewind the tape regardless of
 		the device used to access it.
 
-231-239		UNASSIGNED
+231 char	InfiniBand MAD
+		0 = /dev/infiniband/umad0
+		1 = /dev/infiniband/umad1
+		 ...
+
+232-239		UNASSIGNED
 
 240-254 char	LOCAL/EXPERIMENTAL USE
 240-254 block	LOCAL/EXPERIMENTAL USE
diff -Nru a/Documentation/dvb/README.dibusb b/Documentation/dvb/README.dibusb
--- a/Documentation/dvb/README.dibusb	2005-03-01 23:38:51 -08:00
+++ b/Documentation/dvb/README.dibusb	2005-03-01 23:38:51 -08:00
@@ -26,7 +26,7 @@
 - HAMA DVB-T USB device
 	http://www.hama.de/portal/articleId*110620/action*2598
 
-- CTS Portable (Chinese Television System)
+- CTS Portable (Chinese Television System) (2)
 	http://www.2cts.tv/ctsportable/
 
 - Unknown USB DVB-T device with vendor ID Hyper-Paltek
@@ -46,16 +46,16 @@
 
 Others:
 -------
-- Ultima Electronic/Artec T1 USB TVBOX (AN2135 and AN2235)
+- 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
+- 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
+- Avermedia AverTV DVBT USB (2)
 	http://www.avermedia.com/
 
 - DiBcom USB DVB-T reference device (non-public)
@@ -63,16 +63,33 @@
 
 Supported devices USB2.0
 ========================
-- Twinhan MagicBox II
+- Twinhan MagicBox II (2)
 	http://www.twinhan.com/product_terrestrial_7.asp
 
-- Yakumo DVB-T mobile
+- 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)
+
 - DiBcom USB2.0 DVB-T reference device (non-public)
 
+1) It is working almost.
+2) No test reports received yet. 
+
 
 0. NEWS:
+  2004-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
+  2004-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
@@ -115,13 +132,15 @@
 
 1. How to use?
 NOTE: This driver was developed using Linux 2.6.6.,
-it is working with 2.6.7, 2.6.8.1, 2.6.9 .
+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.
@@ -155,9 +174,13 @@
 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.
@@ -168,13 +191,11 @@
 
 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
-as a slave device in vdr, was not working for me. Some work has to be done
-(patches and comments are very welcome).
+in vdr (at least the USB2.0 one) is working. 
 
 2. Known problems and bugs
 
-TODO:
-- signal-quality and strength calculations
+- none this time
 
 2.1. Adding support for devices 
 
@@ -202,9 +223,10 @@
 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, but watching a channel while
-recording another channel on the same frequency simply does not work.
-This applies to all USB1.1 DVB-T devices.
+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. This applies to all USB1.1 DVB-T 
+devices, not only dibusb)
 
 A special problem of the dibusb for the USB1.1 is, that the USB control
 IC has a problem with write accesses while having MPEG2-streaming
@@ -218,14 +240,20 @@
 these features is maybe a solution. Additionally this behaviour of VDR exceeds
 the USB1.1 bandwidth.
 
+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.
+
 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 and dib3000mb are
-	based.
+    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.
diff -Nru a/Documentation/dvb/get_dvb_firmware b/Documentation/dvb/get_dvb_firmware
--- a/Documentation/dvb/get_dvb_firmware	2005-03-01 23:39:08 -08:00
+++ b/Documentation/dvb/get_dvb_firmware	2005-03-01 23:39:08 -08:00
@@ -21,7 +21,8 @@
 use File::Temp qw/ tempdir /;
 use IO::Handle;
 
-@components = ( "sp8870", "sp887x", "tda10045", "tda10046", "av7110", "dec2000t", "dec2540t", "dec3000s", "vp7041", "dibusb" );
+@components = ( "sp8870", "sp887x", "tda10045", "tda10046", "av7110", "dec2000t",
+		"dec2540t", "dec3000s", "vp7041", "dibusb", "nxt2002" );
 
 # Check args
 syntax() if (scalar(@ARGV) != 1);
@@ -231,6 +232,23 @@
 	verify($outfile,$hash);
 
 	$outfile;
+}
+
+sub nxt2002 {
+    my $sourcefile = "Broadband4PC_4_2_11.zip";
+    my $url = "http://www.bbti.us/download/windows/$sourcefile";
+    my $hash = "c6d2ea47a8f456d887ada0cfb718ff2a";
+    my $outfile = "dvb-fe-nxt2002.fw";
+    my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
+
+    checkstandard();
+    
+    wgetfile($sourcefile, $url);
+    unzip($sourcefile, $tmpdir);
+    verify("$tmpdir/SkyNETU.sys", $hash);
+    extract("$tmpdir/SkyNETU.sys", 375832, 5908, $outfile);
+
+    $outfile;
 }
 
 # ---------------------------------------------------------------
diff -Nru a/Documentation/early-userspace/README b/Documentation/early-userspace/README
--- a/Documentation/early-userspace/README	2005-03-01 23:38:54 -08:00
+++ b/Documentation/early-userspace/README	2005-03-01 23:38:54 -08:00
@@ -1,7 +1,7 @@
 Early userspace support
 =======================
 
-Last update: 2003-08-21
+Last update: 2004-12-20 tlh
 
 
 "Early userspace" is a set of libraries and programs that provide
@@ -17,15 +17,66 @@
 - initramfs, a chunk of code that unpacks the compressed cpio image
   midway through the kernel boot process.
 - klibc, a userspace C library, currently packaged separately, that is
-  optimised for correctness and small size.
+  optimized for correctness and small size.
 
 The cpio file format used by initramfs is the "newc" (aka "cpio -c")
-format, and is documented in the file "buffer-format.txt".  If you
-want to generate your own cpio files directly instead of hacking on
-gen_init_cpio, you will need to short-circuit the build process in
-usr/ so that gen_init_cpio does not get run, then simply pop your own
-initramfs_data.cpio.gz file into place.
+format, and is documented in the file "buffer-format.txt".  There are
+two ways to add an early userspace image: specify an existing cpio
+archive to be used as the image or have the kernel build process build
+the image from specifications.
+
+CPIO ARCHIVE method
+
+You can create a cpio archive that contains the early userspace image.
+Youre cpio archive should be specified in CONFIG_INITRAMFS_SOURCE and it
+will be used directly.  Only a single cpio file may be specified in
+CONFIG_INITRAMFS_SOURCE and directory and file names are not allowed in
+combination with a cpio archive.
+
+IMAGE BUILDING method
+
+The kernel build process can also build an early userspace image from
+source parts rather than supplying a cpio archive.  This method provides
+a way to create images with root-owned files even though the image was
+built by an unprivileged user.
+
+The image is specified as one or more sources in
+CONFIG_INITRAMFS_SOURCE.  Sources can be either directories or files -
+cpio archives are *not* allowed when building from sources.
+
+A source directory will have it and all of it's contents packaged.  The
+specified directory name will be mapped to '/'.  When packaging a
+directory, limited user and group ID translation can be performed.
+INITRAMFS_ROOT_UID can be set to a user ID that needs to be mapped to
+user root (0).  INITRAMFS_ROOT_GID can be set to a group ID that needs
+to be mapped to group root (0).
+
+A source file must be directives in the format required by the
+usr/gen_init_cpio utility (run 'usr/gen_init_cpio --help' to get the
+file format).  The directives in the file will be passed directly to
+usr/gen_init_cpio.
+
+When a combination of directories and files are specified then the
+initramfs image will be an aggregate of all of them.  In this way a user
+can create a 'root-image' directory and install all files into it.
+Because device-special files cannot be created by a unprivileged user,
+special files can be listed in a 'root-files' file.  Both 'root-image'
+and 'root-files' can be listed in CONFIG_INITRAMFS_SOURCE and a complete
+early userspace image can be built by an unprivileged user.
+
+As a technical note, when directories and files are specified, the
+entire CONFIG_INITRAMFS_SOURCE is passed to
+scripts/gen_initramfs_list.sh.  This means that CONFIG_INITRAMFS_SOURCE
+can really be interpreted as any legal argument to
+gen_initramfs_list.sh.  If a directory is specified as an argument then
+the contents are scanned, uid/gid translation is performed, and
+usr/gen_init_cpio file directives are output.  If a directory is
+specified as an arugemnt to scripts/gen_initramfs_list.sh then the
+contents of the file are simply copied to the output.  All of the output
+directives from directory scanning and file contents copying are
+processed by usr/gen_init_cpio.
 
+See also 'scripts/gen_initramfs_list.sh -h'.
 
 Where's this all leading?
 =========================
diff -Nru a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/Documentation/feature-removal-schedule.txt	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,17 @@
+The following is a list of files and features that are going to be
+removed in the kernel source tree.  Every entry should contain what
+exactly is going away, why it is happening, and who is going to be doing
+the work.  When the feature is removed from the kernel, it should also
+be removed from this file.
+
+---------------------------
+
+What:	devfs
+When:	July 2005
+Files:	fs/devfs/*, include/linux/devfs_fs*.h and assorted devfs
+	function calls throughout the kernel tree
+Why:	It has been unmaintained for a number of years, has unfixable
+	races, contains a naming policy within the kernel that is
+	against the LSB, and can be replaced by using udev.
+Who:	Greg Kroah-Hartman <greg@kroah.com>
+
diff -Nru a/Documentation/filesystems/00-INDEX b/Documentation/filesystems/00-INDEX
--- a/Documentation/filesystems/00-INDEX	2005-03-01 23:39:18 -08:00
+++ b/Documentation/filesystems/00-INDEX	2005-03-01 23:39:18 -08:00
@@ -42,8 +42,6 @@
 	- info and mount options for the UDF filesystem.
 ufs.txt
 	- info on the ufs filesystem.
-umsdos.txt
-	- info on the umsdos extensions to the msdos filesystem.
 vfat.txt
 	- info on using the VFAT filesystem used in Windows NT and Windows 95
 vfs.txt
diff -Nru a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking
--- a/Documentation/filesystems/Locking	2005-03-01 23:39:09 -08:00
+++ b/Documentation/filesystems/Locking	2005-03-01 23:39:09 -08:00
@@ -350,6 +350,8 @@
 	unsigned int (*poll) (struct file *, struct poll_table_struct *);
 	int (*ioctl) (struct inode *, struct file *, unsigned int,
 			unsigned long);
+	long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
+	long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
 	int (*mmap) (struct file *, struct vm_area_struct *);
 	int (*open) (struct inode *, struct file *);
 	int (*flush) (struct file *);
@@ -383,6 +385,8 @@
 readdir: 		no
 poll:			no
 ioctl:			yes	(see below)
+unlocked_ioctl:		no	(see below)
+compat_ioctl:		no
 mmap:			no
 open:			maybe	(see below)
 flush:			no
@@ -427,6 +431,9 @@
 ->ioctl() or kill the latter completely. One of the problems is that for
 anything that resembles union-mount we won't have a struct file for all
 components. And there are other reasons why the current interface is a mess...
+
+->ioctl() on regular files is superceded by the ->unlocked_ioctl() that
+doesn't take the BKL.
 
 ->read on directories probably must go away - we should just enforce -EISDIR
 in sys_read() and friends.
diff -Nru a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt
--- a/Documentation/filesystems/proc.txt	2005-03-01 23:38:54 -08:00
+++ b/Documentation/filesystems/proc.txt	2005-03-01 23:38:54 -08:00
@@ -1709,12 +1709,13 @@
 
 Writing to this file results in a flush of the routing cache.
 
-gc_elasticity, gc_interval, gc_min_interval, gc_tresh, gc_timeout,
-gc_thresh, gc_thresh1, gc_thresh2, gc_thresh3
---------------------------------------------------------------
+gc_elasticity, gc_interval, gc_min_interval_ms, gc_timeout, gc_thresh
+---------------------------------------------------------------------
 
 Values to  control  the  frequency  and  behavior  of  the  garbage collection
-algorithm for the routing cache.
+algorithm for the routing cache. gc_min_interval is deprecated and replaced
+by gc_min_interval_ms.
+
 
 max_size
 --------
diff -Nru a/Documentation/filesystems/sysfs-pci.txt b/Documentation/filesystems/sysfs-pci.txt
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/Documentation/filesystems/sysfs-pci.txt	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,88 @@
+Accessing PCI device resources through sysfs
+
+sysfs, usually mounted at /sys, provides access to PCI resources on platforms
+that support it.  For example, a given bus might look like this:
+
+     /sys/devices/pci0000:17
+     |-- 0000:17:00.0
+     |   |-- class
+     |   |-- config
+     |   |-- detach_state
+     |   |-- device
+     |   |-- irq
+     |   |-- local_cpus
+     |   |-- resource
+     |   |-- resource0
+     |   |-- resource1
+     |   |-- resource2
+     |   |-- rom
+     |   |-- subsystem_device
+     |   |-- subsystem_vendor
+     |   `-- vendor
+     `-- detach_state
+
+The topmost element describes the PCI domain and bus number.  In this case,
+the domain number is 0000 and the bus number is 17 (both values are in hex).
+This bus contains a single function device in slot 0.  The domain and bus
+numbers are reproduced for convenience.  Under the device directory are several
+files, each with their own function.
+
+       file		   function
+       ----		   --------
+       class		   PCI class (ascii, ro)
+       config		   PCI config space (binary, rw)
+       detach_state	   connection status (bool, rw)
+       device		   PCI device (ascii, ro)
+       irq		   IRQ number (ascii, ro)
+       local_cpus	   nearby CPU mask (cpumask, ro)
+       resource		   PCI resource host addresses (ascii, ro)
+       resource0..N	   PCI resource N, if present (binary, mmap)
+       rom		   PCI ROM resource, if present (binary, ro)
+       subsystem_device	   PCI subsystem device (ascii, ro)
+       subsystem_vendor	   PCI subsystem vendor (ascii, ro)
+       vendor		   PCI vendor (ascii, ro)
+
+  ro - read only file
+  rw - file is readable and writable
+  mmap - file is mmapable
+  ascii - file contains ascii text
+  binary - file contains binary data
+  cpumask - file contains a cpumask type
+
+The read only files are informational, writes to them will be ignored.
+Writable files can be used to perform actions on the device (e.g. changing
+config space, detaching a device).  mmapable files are available via an
+mmap of the file at offset 0 and can be used to do actual device programming
+from userspace.  Note that some platforms don't support mmapping of certain
+resources, so be sure to check the return value from any attempted mmap.
+
+Accessing legacy resources through sysfs
+
+Legacy I/O port and ISA memory resources are also provided in sysfs if the
+underlying platform supports them.  They're located in the PCI class heirarchy,
+e.g.
+
+	/sys/class/pci_bus/0000:17/
+	|-- bridge -> ../../../devices/pci0000:17
+	|-- cpuaffinity
+	|-- legacy_io
+	`-- legacy_mem
+
+The legacy_io file is a read/write file that can be used by applications to
+do legacy port I/O.  The application should open the file, seek to the desired
+port (e.g. 0x3e8) and do a read or a write of 1, 2 or 4 bytes.  The legacy_mem
+file should be mmapped with an offset corresponding to the memory offset
+desired, e.g. 0xa0000 for the VGA frame buffer.  The application can then
+simply dereference the returned pointer (after checking for errors of course)
+to access legacy memory space.
+
+Supporting PCI access on new platforms
+
+In order to support PCI resource mapping as described above, Linux platform
+code must define HAVE_PCI_MMAP and provide a pci_mmap_page_range function.
+Platforms are free to only support subsets of the mmap functionality, but
+useful return codes should be provided.
+
+Legacy resources are protected by the HAVE_PCI_LEGACY define.  Platforms
+wishing to support legacy functionality should define it and provide
+pci_legacy_read, pci_legacy_write and pci_mmap_legacy_page_range functions.
\ No newline at end of file
diff -Nru a/Documentation/filesystems/umsdos.txt b/Documentation/filesystems/umsdos.txt
--- a/Documentation/filesystems/umsdos.txt	2005-03-01 23:39:18 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,100 +0,0 @@
-Firstly, let me say that UMSDOS is going through some major code changes,
-and has some KNOWN BUGS (and quite a few unknown :-). Please read
-fs/umsdos/README-WIP.txt for more information on current status. Thanks.
-
-----------------------------------------------------------------------------
-Very short explanation for the impatient!
-
-Umsdos is a file system driver that run on top the MSDOS fs driver.
-It is written by Jacques Gelinas (jacques@solucorp.qc.ca)
-and is currently maintained by Matija Nalis (mnalis@jagor.srce.hr)
-
-Umsdos is not a file system per se, but a twist to make a boring
-one into a useful one.
-
-It gives you:
-
-	long file names
-	Permissions and owners
-	Links
-	Special files (devices, pipes...)
-	All that is needed to be a linux root fs.
-
-There is plenty of documentation on it in the source. A formatted document
-made from those comments is available from
-sunsite.unc.edu:/pub/Linux/system/Filesystems/umsdos.
-
-You mount a DOS partition like this:
-
-mount -t umsdos /dev/hda3 /mnt
-         ^
----------|
-
-All options are passed to the msdos drivers. Option like uid,gid etc are
-given to msdos.
-
-The default behavior of Umsdos is to do the same thing as the msdos driver
-mostly passing commands to it without much processing. Again, this is
-the default. After doing the mount on a DOS partition, nothing special
-happens. This is why all mount options are passed to the msdos fs driver.
-
-Umsdos uses a special DOS file --linux-.--- to store the information
-which can't be handled by the normal MS-DOS filesystem. This is the trick.
-
---linux-.--- is optional. There is one per directory.
-
-**** If --linux-.--- is missing, then Umsdos process the directory the
-     same way the msdos driver does. Short file names, no goodies, default
-     owner and permissions. So each directory may have or not this
-     --linux-.---
-
-Now, how to get those --linux-.---.
-
-\begin joke_section
-
-	Well send me a directory content
-	and I will send you one customised for you.
-	$5 per directory. Add any applicable taxes.
-\end joke_section
-
-A utility umssync creates those. The kernel maintains them. It is available
-from the same directory above (sunsite) in the file umsdos_progs-0.7.tar.gz.
-A compiled version is available in umsdos_progs-0.7.bin.tar.gz.
-
-So in our example, after mounting mnt, we do
-
-	umssync .
-
-This will promote this directory (a recursive option is available) to full
-umsdos capabilities (long name, etc.).  However, an "ls -l" before and after
-won't show much difference.  The files which were there are still there, but
-now you can do all this:
-
-	chmod 644 *
-	chown you.your_group *
-	ls >THIS_IS.A.VERY.LONG.NAME
-	ln -s toto tata
-	ls -l
-
-Once a directory is promoted, all subdirectories created will inherit that
-promotion.
-
-What happens if you boot DOS and create files in those promoted directories ?
-Umsdos won't notice new files, but will signal removed files (it won't crash).
-Using umssync in /etc/rc will make sure the DOS directory is in sync with
-the --linux-.---.
-
-It is a good idea to put the following command in your RC file just
-after the "mount -a":
-
-	mount -a
-	/sbin/umssync -i+ -c+ -r99 /umsdos_mount_point
-
-	(You put one for each umsdos mount point in the fstab)
-
-This will ensure nice operation.  A umsdos.fsck is in the making,
-so you will be allowed to manage umsdos partitions in the same way
-other filesystems are, using the generic fsck front end.
-
-Hope this helps!
-
diff -Nru a/Documentation/fujitsu/frv/README.txt b/Documentation/fujitsu/frv/README.txt
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/Documentation/fujitsu/frv/README.txt	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,51 @@
+		       ================================
+		       Fujitsu FR-V LINUX DOCUMENTATION
+		       ================================
+
+This directory contains documentation for the Fujitsu FR-V CPU architecture
+port of Linux.
+
+The following documents are available:
+
+ (*) features.txt
+
+     A description of the basic features inherent in this architecture port.
+
+
+ (*) configuring.txt
+
+     A summary of the configuration options particular to this architecture.
+
+
+ (*) booting.txt
+
+     A description of how to boot the kernel image and a summary of the kernel
+     command line options.
+
+
+ (*) gdbstub.txt
+
+     A description of how to debug the kernel using GDB attached by serial
+     port, and a summary of the services available.
+
+
+ (*) mmu-layout.txt
+
+     A description of the virtual and physical memory layout used in the
+     MMU linux kernel, and the registers used to support it.
+
+
+ (*) gdbinit
+
+     An example .gdbinit file for use with GDB. It includes macros for viewing
+     MMU state on the FR451. See mmu-layout.txt for more information.
+
+
+ (*) clock.txt
+
+     A description of the CPU clock scaling interface.
+
+
+ (*) atomic-ops.txt
+
+     A description of how the FR-V kernel's atomic operations work.
diff -Nru a/Documentation/fujitsu/frv/atomic-ops.txt b/Documentation/fujitsu/frv/atomic-ops.txt
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/Documentation/fujitsu/frv/atomic-ops.txt	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,134 @@
+			       =====================================
+			       FUJITSU FR-V KERNEL ATOMIC OPERATIONS
+			       =====================================
+
+On the FR-V CPUs, there is only one atomic Read-Modify-Write operation: the SWAP/SWAPI
+instruction. Unfortunately, this alone can't be used to implement the following operations:
+
+ (*) Atomic add to memory
+
+ (*) Atomic subtract from memory
+
+ (*) Atomic bit modification (set, clear or invert)
+
+ (*) Atomic compare and exchange
+
+On such CPUs, the standard way of emulating such operations in uniprocessor mode is to disable
+interrupts, but on the FR-V CPUs, modifying the PSR takes a lot of clock cycles, and it has to be
+done twice. This means the CPU runs for a relatively long time with interrupts disabled,
+potentially having a great effect on interrupt latency.
+
+
+=============
+NEW ALGORITHM
+=============
+
+To get around this, the following algorithm has been implemented. It operates in a way similar to
+the LL/SC instruction pairs supported on a number of platforms.
+
+ (*) The CCCR.CC3 register is reserved within the kernel to act as an atomic modify abort flag.
+
+ (*) In the exception prologues run on kernel->kernel entry, CCCR.CC3 is set to 0 (Undefined
+     state).
+
+ (*) All atomic operations can then be broken down into the following algorithm:
+
+     (1) Set ICC3.Z to true and set CC3 to True (ORCC/CKEQ/ORCR).
+
+     (2) Load the value currently in the memory to be modified into a register.
+
+     (3) Make changes to the value.
+
+     (4) If CC3 is still True, simultaneously and atomically (by VLIW packing):
+
+	 (a) Store the modified value back to memory.
+
+	 (b) Set ICC3.Z to false (CORCC on GR29 is sufficient for this - GR29 holds the current
+	     task pointer in the kernel, and so is guaranteed to be non-zero).
+
+     (5) If ICC3.Z is still true, go back to step (1).
+
+This works in a non-SMP environment because any interrupt or other exception that happens between
+steps (1) and (4) will set CC3 to the Undefined, thus aborting the store in (4a), and causing the
+condition in ICC3 to remain with the Z flag set, thus causing step (5) to loop back to step (1).
+
+
+This algorithm suffers from two problems:
+
+ (1) The condition CCCR.CC3 is cleared unconditionally by an exception, irrespective of whether or
+     not any changes were made to the target memory location during that exception.
+
+ (2) The branch from step (5) back to step (1) may have to happen more than once until the store
+     manages to take place. In theory, this loop could cycle forever because there are too many
+     interrupts coming in, but it's unlikely.
+
+
+=======
+EXAMPLE
+=======
+
+Taking an example from include/asm-frv/atomic.h:
+
+	static inline int atomic_add_return(int i, atomic_t *v)
+	{
+		unsigned long val;
+
+		asm("0:						\n"
+
+It starts by setting ICC3.Z to true for later use, and also transforming that into CC3 being in the
+True state.
+
+		    "	orcc		gr0,gr0,gr0,icc3	\n"	<-- (1)
+		    "	ckeq		icc3,cc7		\n"	<-- (1)
+
+Then it does the load. Note that the final phase of step (1) is done at the same time as the
+load. The VLIW packing ensures they are done simultaneously. The ".p" on the load must not be
+removed without swapping the order of these two instructions.
+
+		    "	ld.p		%M0,%1			\n"	<-- (2)
+		    "	orcr		cc7,cc7,cc3		\n"	<-- (1)
+
+Then the proposed modification is generated. Note that the old value can be retained if required
+(such as in test_and_set_bit()).
+
+		    "	add%I2		%1,%2,%1		\n"	<-- (3)
+
+Then it attempts to store the value back, contingent on no exception having cleared CC3 since it
+was set to True.
+
+		    "	cst.p		%1,%M0		,cc3,#1	\n"	<-- (4a)
+
+It simultaneously records the success or failure of the store in ICC3.Z.
+
+		    "	corcc		gr29,gr29,gr0	,cc3,#1	\n"	<-- (4b)
+
+Such that the branch can then be taken if the operation was aborted.
+
+		    "	beq		icc3,#0,0b		\n"	<-- (5)
+		    : "+U"(v->counter), "=&r"(val)
+		    : "NPr"(i)
+		    : "memory", "cc7", "cc3", "icc3"
+		    );
+
+		return val;
+	}
+
+
+=============
+CONFIGURATION
+=============
+
+The atomic ops implementation can be made inline or out-of-line by changing the
+CONFIG_FRV_OUTOFLINE_ATOMIC_OPS configuration variable. Making it out-of-line has a number of
+advantages:
+
+ - The resulting kernel image may be smaller
+ - Debugging is easier as atomic ops can just be stepped over and they can be breakpointed
+
+Keeping it inline also has a number of advantages:
+
+ - The resulting kernel may be Faster
+   - no out-of-line function calls need to be made
+   - the compiler doesn't have half its registers clobbered by making a call
+
+The out-of-line implementations live in arch/frv/lib/atomic-ops.S.
diff -Nru a/Documentation/fujitsu/frv/booting.txt b/Documentation/fujitsu/frv/booting.txt
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/Documentation/fujitsu/frv/booting.txt	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,181 @@
+			  =========================
+			  BOOTING FR-V LINUX KERNEL
+			  =========================
+
+======================
+PROVIDING A FILESYSTEM
+======================
+
+First of all, a root filesystem must be made available. This can be done in
+one of two ways:
+
+  (1) NFS Export
+
+      A filesystem should be constructed in a directory on an NFS server that
+      the target board can reach. This directory should then be NFS exported
+      such that the target board can read and write into it as root.
+
+  (2) Flash Filesystem (JFFS2 Recommended)
+
+      In this case, the image must be stored or built up on flash before it
+      can be used. A complete image can be built using the mkfs.jffs2 or
+      similar program and then downloaded and stored into flash by RedBoot.
+
+
+========================
+LOADING THE KERNEL IMAGE
+========================
+
+The kernel will need to be loaded into RAM by RedBoot (or by some alternative
+boot loader) before it can be run. The kernel image (arch/frv/boot/Image) may
+be loaded in one of three ways:
+
+  (1) Load from Flash
+
+      This is the simplest. RedBoot can store an image in the flash (see the
+      RedBoot documentation) and then load it back into RAM. RedBoot keeps
+      track of the load address, entry point and size, so the command to do
+      this is simply:
+
+	fis load linux
+
+      The image is then ready to be executed.
+
+  (2) Load by TFTP
+
+      The following command will download a raw binary kernel image from the
+      default server (as negotiated by BOOTP) and store it into RAM:
+
+	load -b 0x00100000 -r /tftpboot/image.bin
+
+      The image is then ready to be executed.
+
+  (3) Load by Y-Modem
+
+      The following command will download a raw binary kernel image across the
+      serial port that RedBoot is currently using:
+
+	load -m ymodem -b 0x00100000 -r zImage
+
+      The serial client (such as minicom) must then be told to transmit the
+      program by Y-Modem.
+
+      When finished, the image will then be ready to be executed.
+
+
+==================
+BOOTING THE KERNEL
+==================
+
+Boot the image with the following RedBoot command:
+
+	exec -c "<CMDLINE>" 0x00100000
+
+For example:
+
+	exec -c "console=ttySM0,115200 ip=:::::dhcp root=/dev/mtdblock2 rw"
+
+This will start the kernel running. Note that if the GDB-stub is compiled in,
+then the kernel will immediately wait for GDB to connect over serial before
+doing anything else. See the section on kernel debugging with GDB.
+
+The kernel command line <CMDLINE> tells the kernel where its console is and
+how to find its root filesystem. This is made up of the following components,
+separated by spaces:
+
+  (*) console=ttyS<x>[,<baud>[<parity>[<bits>[<flow>]]]]
+
+      This specifies that the system console should output through on-chip
+      serial port <x> (which can be "0" or "1").
+
+      <baud> is a standard baud rate between 1200 and 115200 (default 9600).
+
+      <parity> is a parity setting of "N", "O", "E", "M" or "S" for None, Odd,
+      Even, Mark or Space. "None" is the default.
+
+      <stop> is "7" or "8" for the number of bits per character. "8" is the
+      default.
+
+      <flow> is "r" to use flow control (XCTS on serial port 2 only). The
+      default is to not use flow control.
+
+      For example:
+
+	console=ttyS0,115200
+
+      To use the first on-chip serial port at baud rate 115200, no parity, 8
+      bits, and no flow control.
+
+  (*) root=/dev/<xxxx>
+
+      This specifies the device upon which the root filesystem resides. For
+      example:
+
+	/dev/nfs	NFS root filesystem
+	/dev/mtdblock3	Fourth RedBoot partition on the System Flash
+
+  (*) rw
+
+      Start with the root filesystem mounted Read/Write.
+
+  The remaining components are all optional:
+
+  (*) ip=<ip>::::<host>:<iface>:<cfg>
+
+      Configure the network interface. If <cfg> is "off" then <ip> should
+      specify the IP address for the network device <iface>. <host> provide
+      the hostname for the device.
+
+      If <cfg> is "bootp" or "dhcp", then all of these parameters will be
+      discovered by consulting a BOOTP or DHCP server.
+
+      For example, the following might be used:
+
+	ip=192.168.73.12::::frv:eth0:off
+
+      This sets the IP address on the VDK motherboard RTL8029 ethernet chipset
+      (eth0) to be 192.168.73.12, and sets the board's hostname to be "frv".
+
+  (*) nfsroot=<server>:<dir>[,v<vers>]
+
+      This is mandatory if "root=/dev/nfs" is given as an option. It tells the
+      kernel the IP address of the NFS server providing its root filesystem,
+      and the pathname on that server of the filesystem.
+
+      The NFS version to use can also be specified. v2 and v3 are supported by
+      Linux.
+
+      For example:
+
+	nfsroot=192.168.73.1:/nfsroot-frv
+
+  (*) profile=1
+
+      Turns on the kernel profiler (accessible through /proc/profile).
+
+  (*) console=gdb0
+
+      This can be used as an alternative to the "console=ttyS..." listed
+      above. I tells the kernel to pass the console output to GDB if the
+      gdbstub is compiled in to the kernel.
+
+      If this is used, then the gdbstub passes the text to GDB, which then
+      simply dumps it to its standard output.
+
+  (*) mem=<xxx>M
+
+      Normally the kernel will work out how much SDRAM it has by reading the
+      SDRAM controller registers. That can be overridden with this
+      option. This allows the kernel to be told that it has <xxx> megabytes of
+      memory available.
+
+  (*) init=<prog> [<arg> [<arg> [<arg> ...]]]
+
+      This tells the kernel what program to run initially. By default this is
+      /sbin/init, but /sbin/sash or /bin/sh are common alternatives.
+
+  (*) vdc=...
+
+      This option configures the MB93493 companion chip visual display
+      driver. Please see Documentation/fujitsu/mb93493/vdc.txt for more
+      information.
diff -Nru a/Documentation/fujitsu/frv/clock.txt b/Documentation/fujitsu/frv/clock.txt
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/Documentation/fujitsu/frv/clock.txt	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,65 @@
+Clock scaling
+-------------
+
+The kernel supports scaling of CLCK.CMODE, CLCK.CM and CLKC.P0 clock
+registers. If built with CONFIG_PM and CONFIG_SYSCTL options enabled, four
+extra files will appear in the directory /proc/sys/pm/. Reading these files
+will show:
+
+      p0		-- current value of the P0 bit in CLKC register.
+      cm		-- current value of the CM bits in CLKC register.
+      cmode		-- current value of the CMODE bits in CLKC register.
+
+On all boards, the 'p0' file should also be writable, and either '1' or '0'
+can be rewritten, to set or clear the CLKC_P0 bit respectively, hence
+controlling whether the resource bus rate clock is halved.
+
+The 'cm' file should also be available on all boards. '0' can be written to it
+to shift the board into High-Speed mode (normal), and '1' can be written to
+shift the board into Medium-Speed mode. Selecting Low-Speed mode is not
+supported by this interface, even though some CPUs do support it.
+
+On the boards with FR405 CPU (i.e. CB60 and CB70), the 'cmode' file is also
+writable, allowing the CPU core speed (and other clock speeds) to be
+controlled from userspace.
+
+
+Determining current and possible settings
+-----------------------------------------
+
+The current state and the available masks can be found in /proc/cpuinfo. For
+example, on the CB70:
+
+	# cat /proc/cpuinfo
+	CPU-Series:     fr400
+	CPU-Core:       fr405, gr0-31, BE, CCCR
+	CPU:            mb93405
+	MMU:            Prot
+	FP-Media:       fr0-31, Media
+	System:         mb93091-cb70, mb93090-mb00
+	PM-Controls:    cmode=0xd31f, cm=0x3, p0=0x3, suspend=0x9
+	PM-Status:      cmode=3, cm=0, p0=0
+	Clock-In:       50.00 MHz
+	Clock-Core:     300.00 MHz
+	Clock-SDRAM:    100.00 MHz
+	Clock-CBus:     100.00 MHz
+	Clock-Res:      50.00 MHz
+	Clock-Ext:      50.00 MHz
+	Clock-DSU:      25.00 MHz
+	BogoMips:       300.00
+
+And on the PDK, the PM lines look like the following:
+
+	PM-Controls:    cm=0x3, p0=0x3, suspend=0x9
+	PM-Status:      cmode=9, cm=0, p0=0
+
+The PM-Controls line, if present, will indicate which /proc/sys/pm files can
+be set to what values. The specification values are bitmasks; so, for example,
+"suspend=0x9" indicates that 0 and 3 can be written validly to
+/proc/sys/pm/suspend.
+
+The PM-Controls line will only be present if CONFIG_PM is configured to Y.
+
+The PM-Status line indicates which clock controls are set to which value. If
+the file can be read, then the suspend value must be 0, and so that's not
+included.
diff -Nru a/Documentation/fujitsu/frv/configuring.txt b/Documentation/fujitsu/frv/configuring.txt
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/Documentation/fujitsu/frv/configuring.txt	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,125 @@
+		   =======================================
+		   FUJITSU FR-V LINUX KERNEL CONFIGURATION
+		   =======================================
+
+=====================
+CONFIGURATION OPTIONS
+=====================
+
+The most important setting is in the "MMU support options" tab (the first
+presented in the configuration tools available):
+
+ (*) "Kernel Type"
+
+     This options allows selection of normal, MMU-requiring linux, and uClinux
+     (which doesn't require an MMU and doesn't have inter-process protection).
+
+There are a number of settings in the "Processor type and features" section of
+the kernel configuration that need to be considered.
+
+ (*) "CPU"
+
+     The register and instruction sets at the core of the processor. This can
+     only be set to "FR40x/45x/55x" at the moment - but this permits usage of
+     the kernel with MB93091 CB10, CB11, CB30, CB41, CB60, CB70 and CB451
+     CPU boards, and with the MB93093 PDK board.
+
+ (*) "System"
+
+     This option allows a choice of basic system. This governs the peripherals
+     that are expected to be available.
+
+ (*) "Motherboard"
+
+     This specifies the type of motherboard being used, and the peripherals
+     upon it. Currently only "MB93090-MB00" can be set here.
+
+ (*) "Default cache-write mode"
+
+     This controls the initial data cache write management mode. By default
+     Write-Through is selected, but Write-Back (Copy-Back) can also be
+     selected. This can be changed dynamically once the kernel is running (see
+     features.txt).
+
+There are some architecture specific configuration options in the "General
+Setup" section of the kernel configuration too:
+
+ (*) "Reserve memory uncached for (PCI) DMA"
+
+     This requests that a uClinux kernel set aside some memory in an uncached
+     window for the use as consistent DMA memory (mainly for PCI). At least a
+     megabyte will be allocated in this way, possibly more. Any memory so
+     reserved will not be available for normal allocations.
+
+ (*) "Kernel support for ELF-FDPIC binaries"
+
+     This enables the binary-format driver for the new FDPIC ELF binaries that
+     this platform normally uses. These binaries are totally relocatable -
+     their separate sections can relocated independently, allowing them to be
+     shared on uClinux where possible. This should normally be enabled.
+
+ (*) "Kernel image protection"
+
+     This makes the protection register governing access to the core kernel
+     image prohibit access by userspace programs. This option is available on
+     uClinux only.
+
+There are also a number of settings in the "Kernel Hacking" section of the
+kernel configuration especially for debugging a kernel on this
+architecture. See the "gdbstub.txt" file for information about those.
+
+
+======================
+DEFAULT CONFIGURATIONS
+======================
+
+The kernel sources include a number of example default configurations:
+
+ (*) defconfig-mb93091
+
+     Default configuration for the MB93091-VDK with both CPU board and
+     MB93090-MB00 motherboard running uClinux.
+
+
+ (*) defconfig-mb93091-fb
+
+     Default configuration for the MB93091-VDK with CPU board,
+     MB93090-MB00 motherboard, and DAV board running uClinux.
+     Includes framebuffer driver.
+
+
+ (*) defconfig-mb93093
+
+     Default configuration for the MB93093-PDK board running uClinux.
+
+
+ (*) defconfig-cb70-standalone
+
+     Default configuration for the MB93091-VDK with only CB70 CPU board
+     running uClinux. This will use the CB70's DM9000 for network access.
+
+
+ (*) defconfig-mmu
+
+     Default configuration for the MB93091-VDK with both CB451 CPU board and
+     MB93090-MB00 motherboard running MMU linux.
+
+ (*) defconfig-mmu-audio
+
+     Default configuration for the MB93091-VDK with CB451 CPU board, DAV
+     board, and MB93090-MB00 motherboard running MMU linux. Includes
+     audio driver.
+
+ (*) defconfig-mmu-fb
+
+     Default configuration for the MB93091-VDK with CB451 CPU board, DAV
+     board, and MB93090-MB00 motherboard running MMU linux. Includes
+     framebuffer driver.
+
+ (*) defconfig-mmu-standalone
+
+     Default configuration for the MB93091-VDK with only CB451 CPU board
+     running MMU linux.
+
+
+
diff -Nru a/Documentation/fujitsu/frv/features.txt b/Documentation/fujitsu/frv/features.txt
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/Documentation/fujitsu/frv/features.txt	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,310 @@
+			 ===========================
+			 FUJITSU FR-V LINUX FEATURES
+			 ===========================
+
+This kernel port has a number of features of which the user should be aware:
+
+ (*) Linux and uClinux
+
+     The FR-V architecture port supports both normal MMU linux and uClinux out
+     of the same sources.
+
+
+ (*) CPU support
+
+     Support for the FR401, FR403, FR405, FR451 and FR555 CPUs should work with
+     the same uClinux kernel configuration.
+
+     In normal (MMU) Linux mode, only the FR451 CPU will work as that is the
+     only one with a suitably featured CPU.
+
+     The kernel is written and compiled with the assumption that only the
+     bottom 32 GR registers and no FR registers will be used by the kernel
+     itself, however all extra userspace registers will be saved on context
+     switch. Note that since most CPUs can't support lazy switching, no attempt
+     is made to do lazy register saving where that would be possible (FR555
+     only currently).
+
+
+ (*) Board support
+
+     The board on which the kernel will run can be configured on the "Processor
+     type and features" configuration tab.
+
+     Set the System to "MB93093-PDK" to boot from the MB93093 (FR403) PDK.
+
+     Set the System to "MB93091-VDK" to boot from the CB11, CB30, CB41, CB60,
+     CB70 or CB451 VDK boards. Set the Motherboard setting to "MB93090-MB00" to
+     boot with the standard ATA90590B VDK motherboard, and set it to "None" to
+     boot without any motherboard.
+
+
+ (*) Binary Formats
+
+     The only userspace binary format supported is FDPIC ELF. Normal ELF, FLAT
+     and AOUT binaries are not supported for this architecture.
+
+     FDPIC ELF supports shared library and program interpreter facilities.
+
+
+ (*) Scheduler Speed
+
+     The kernel scheduler runs at 100Hz irrespective of the clock speed on this
+     architecture. This value is set in asm/param.h (see the HZ macro defined
+     there).
+
+
+ (*) Normal (MMU) Linux Memory Layout.
+
+     See mmu-layout.txt in this directory for a description of the normal linux
+     memory layout
+
+     See include/asm-frv/mem-layout.h for constants pertaining to the memory
+     layout.
+
+     See include/asm-frv/mb-regs.h for the constants pertaining to the I/O bus
+     controller configuration.
+
+
+ (*) uClinux Memory Layout
+
+     The memory layout used by the uClinux kernel is as follows:
+
+	0x00000000 - 0x00000FFF		Null pointer catch page
+	0x20000000 - 0x200FFFFF CS2#    [PDK] FPGA
+	0xC0000000 - 0xCFFFFFFF		SDRAM
+	0xC0000000			Base of Linux kernel image
+	0xE0000000 - 0xEFFFFFFF	CS2#	[VDK] SLBUS/PCI window
+	0xF0000000 - 0xF0FFFFFF	CS5#	MB93493 CSC area (DAV daughter board)
+	0xF1000000 - 0xF1FFFFFF	CS7#	[CB70/CB451] CPU-card PCMCIA port space
+	0xFC000000 - 0xFC0FFFFF	CS1#	[VDK] MB86943 config space
+	0xFC100000 - 0xFC1FFFFF	CS6#	[CB70/CB451] CPU-card DM9000 NIC space
+	0xFC100000 - 0xFC1FFFFF	CS6#	[PDK] AX88796 NIC space
+	0xFC200000 - 0xFC2FFFFF	CS3#	MB93493 CSR area (DAV daughter board)
+	0xFD000000 - 0xFDFFFFFF	CS4#	[CB70/CB451] CPU-card extra flash space
+	0xFE000000 - 0xFEFFFFFF		Internal CPU peripherals
+	0xFF000000 - 0xFF1FFFFF	CS0#	Flash 1
+	0xFF200000 - 0xFF3FFFFF	CS0#	Flash 2
+	0xFFC00000 - 0xFFC0001F	CS0#	[VDK] FPGA
+
+     The kernel reads the size of the SDRAM from the memory bus controller
+     registers by default.
+
+     The kernel initialisation code (1) adjusts the SDRAM base addresses to
+     move the SDRAM to desired address, (2) moves the kernel image down to the
+     bottom of SDRAM, (3) adjusts the bus controller registers to move I/O
+     windows, and (4) rearranges the protection registers to protect all of
+     this.
+
+     The reasons for doing this are: (1) the page at address 0 should be
+     inaccessible so that NULL pointer errors can be caught; and (2) the bottom
+     three quarters are left unoccupied so that an FR-V CPU with an MMU can use
+     it for virtual userspace mappings.
+
+     See include/asm-frv/mem-layout.h for constants pertaining to the memory
+     layout.
+
+     See include/asm-frv/mb-regs.h for the constants pertaining to the I/O bus
+     controller configuration.
+
+
+ (*) uClinux Memory Protection
+
+     A DAMPR register is used to cover the entire region used for I/O
+     (0xE0000000 - 0xFFFFFFFF). This permits the kernel to make uncached
+     accesses to this region. Userspace is not permitted to access it.
+
+     The DAMPR/IAMPR protection registers not in use for any other purpose are
+     tiled over the top of the SDRAM such that:
+
+	(1) The core kernel image is covered by as small a tile as possible
+            granting only the kernel access to the underlying data, whilst
+            making sure no SDRAM is actually made unavailable by this approach.
+
+	(2) All other tiles are arranged to permit userspace access to the rest
+            of the SDRAM.
+
+     Barring point (1), there is nothing to protect kernel data against
+     userspace damage - but this is uClinux.
+
+
+ (*) Exceptions and Fixups
+
+     Since the FR40x and FR55x CPUs that do not have full MMUs generate
+     imprecise data error exceptions, there are currently no automatic fixup
+     services available in uClinux. This includes misaligned memory access
+     fixups.
+
+     Userspace EFAULT errors can be trapped by issuing a MEMBAR instruction and
+     forcing the fault to happen there.
+
+     On the FR451, however, data exceptions are mostly precise, and so
+     exception fixup handling is implemented as normal.
+
+
+ (*) Userspace Breakpoints
+
+     The ptrace() system call supports the following userspace debugging
+     features:
+
+	(1) Hardware assisted single step.
+
+	(2) Breakpoint via the FR-V "BREAK" instruction.
+
+	(3) Breakpoint via the FR-V "TIRA GR0, #1" instruction.
+
+	(4) Syscall entry/exit trap.
+
+     Each of the above generates a SIGTRAP.
+
+
+ (*) On-Chip Serial Ports
+
+     The FR-V on-chip serial ports are made available as ttyS0 and ttyS1. Note
+     that if the GDB stub is compiled in, ttyS1 will not actually be available
+     as it will be being used for the GDB stub.
+
+     These ports can be made by:
+
+	mknod /dev/ttyS0 c 4 64
+	mknod /dev/ttyS1 c 4 65
+
+
+ (*) Maskable Interrupts
+
+     Level 15 (Non-maskable) interrupts are dealt with by the GDB stub if
+     present, and cause a panic if not. If the GDB stub is present, ttyS1's
+     interrupts are rated at level 15.
+
+     All other interrupts are distributed over the set of available priorities
+     so that no IRQs are shared where possible. The arch interrupt handling
+     routines attempt to disentangle the various sources available through the
+     CPU's own multiplexor, and those on off-CPU peripherals.
+
+
+ (*) Accessing PCI Devices
+
+     Where PCI is available, care must be taken when dealing with drivers that
+     access PCI devices. PCI devices present their data in little-endian form,
+     but the CPU sees it in big-endian form. The macros in asm/io.h try to get
+     this right, but may not under all circumstances...
+
+
+ (*) Ax88796 Ethernet Driver
+
+     The MB93093 PDK board has an Ax88796 ethernet chipset (an NE2000 clone). A
+     driver has been written to deal specifically with this. The driver
+     provides MII services for the card.
+
+     The driver can be configured by running make xconfig, and going to:
+
+	(*) Network device support
+	    - turn on "Network device support"
+	    (*) Ethernet (10 or 100Mbit)
+		- turn on "Ethernet (10 or 100Mbit)"
+		- turn on "AX88796 NE2000 compatible chipset"
+
+     The driver can be found in:
+
+	drivers/net/ax88796.c
+	include/asm/ax88796.h
+
+
+ (*) WorkRAM Driver
+
+     This driver provides a character device that permits access to the WorkRAM
+     that can be found on the FR451 CPU. Each page is accessible through a
+     separate minor number, thereby permitting each page to have its own
+     filesystem permissions set on the device file.
+
+     The device files should be:
+
+	mknod /dev/frv/workram0 c 240 0
+	mknod /dev/frv/workram1 c 240 1
+	mknod /dev/frv/workram2 c 240 2
+	...
+
+     The driver will not permit the opening of any device file that does not
+     correspond to at least a partial page of WorkRAM. So the first device file
+     is the only one available on the FR451. If any other CPU is detected, none
+     of the devices will be openable.
+
+     The devices can be accessed with read, write and llseek, and can also be
+     mmapped. If they're mmapped, they will only map at the appropriate
+     0x7e8nnnnn address on linux and at the 0xfe8nnnnn address on uClinux. If
+     MAP_FIXED is not specified, the appropriate address will be chosen anyway.
+
+     The mappings must be MAP_SHARED not MAP_PRIVATE, and must not be
+     PROT_EXEC. They must also start at file offset 0, and must not be longer
+     than one page in size.
+
+     This driver can be configured by running make xconfig, and going to:
+
+	(*) Character devices
+	    - turn on "Fujitsu FR-V CPU WorkRAM support"
+
+
+ (*) Dynamic data cache write mode changing
+
+     It is possible to view and to change the data cache's write mode through
+     the /proc/sys/frv/cache-mode file while the kernel is running. There are
+     two modes available:
+
+	NAME	MEANING
+	=====	==========================================
+	wthru	Data cache is in Write-Through mode
+	wback	Data cache is in Write-Back/Copy-Back mode
+
+     To read the cache mode:
+
+	# cat /proc/sys/frv/cache-mode
+	wthru
+
+     To change the cache mode:
+
+	# echo wback >/proc/sys/frv/cache-mode
+	# cat /proc/sys/frv/cache-mode
+	wback
+
+
+ (*) MMU Context IDs and Pinning
+
+     On MMU Linux the CPU supports the concept of a context ID in its MMU to
+     make it more efficient (TLB entries are labelled with a context ID to link
+     them to specific tasks).
+
+     Normally once a context ID is allocated, it will remain affixed to a task
+     or CLONE_VM'd group of tasks for as long as it exists. However, since the
+     kernel is capable of supporting more tasks than there are possible ID
+     numbers, the kernel will pass context IDs from one task to another if
+     there are insufficient available.
+
+     The context ID currently in use by a task can be viewed in /proc:
+
+	# grep CXNR /proc/1/status
+	CXNR: 1
+
+     Note that kernel threads do not have a userspace context, and so will not
+     show a CXNR entry in that file.
+
+     Under some circumstances, however, it is desirable to pin a context ID on
+     a process such that the kernel won't pass it on. This can be done by
+     writing the process ID of the target process to a special file:
+
+	# echo 17 >/proc/sys/frv/pin-cxnr
+
+     Reading from the file will then show the context ID pinned.
+
+	# cat /proc/sys/frv/pin-cxnr
+	4
+
+     The context ID will remain pinned as long as any process is using that
+     context, i.e.: when the all the subscribing processes have exited or
+     exec'd; or when an unpinning request happens:
+
+	# echo 0 >/proc/sys/frv/pin-cxnr
+
+     When there isn't a pinned context, the file shows -1:
+
+	# cat /proc/sys/frv/pin-cxnr
+	-1
diff -Nru a/Documentation/fujitsu/frv/gdbinit b/Documentation/fujitsu/frv/gdbinit
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/Documentation/fujitsu/frv/gdbinit	2005-03-01 23:39:26 -08:00
@@ -0,0 +1,102 @@
+set remotebreak 1
+
+define _amr
+
+printf "AMRx           DAMR                    IAMR         \n"
+printf "====   =====================   =====================\n"
+printf "amr0 : L:%08lx P:%08lx : L:%08lx P:%08lx\n",__debug_mmu.damr[0x0].L,__debug_mmu.damr[0x0].P,__debug_mmu.iamr[0x0].L,__debug_mmu.iamr[0x0].P
+printf "amr1 : L:%08lx P:%08lx : L:%08lx P:%08lx\n",__debug_mmu.damr[0x1].L,__debug_mmu.damr[0x1].P,__debug_mmu.iamr[0x1].L,__debug_mmu.iamr[0x1].P
+printf "amr2 : L:%08lx P:%08lx : L:%08lx P:%08lx\n",__debug_mmu.damr[0x2].L,__debug_mmu.damr[0x2].P,__debug_mmu.iamr[0x2].L,__debug_mmu.iamr[0x2].P
+printf "amr3 : L:%08lx P:%08lx : L:%08lx P:%08lx\n",__debug_mmu.damr[0x3].L,__debug_mmu.damr[0x3].P,__debug_mmu.iamr[0x3].L,__debug_mmu.iamr[0x3].P
+printf "amr4 : L:%08lx P:%08lx : L:%08lx P:%08lx\n",__debug_mmu.damr[0x4].L,__debug_mmu.damr[0x4].P,__debug_mmu.iamr[0x4].L,__debug_mmu.iamr[0x4].P
+printf "amr5 : L:%08lx P:%08lx : L:%08lx P:%08lx\n",__debug_mmu.damr[0x5].L,__debug_mmu.damr[0x5].P,__debug_mmu.iamr[0x5].L,__debug_mmu.iamr[0x5].P
+printf "amr6 : L:%08lx P:%08lx : L:%08lx P:%08lx\n",__debug_mmu.damr[0x6].L,__debug_mmu.damr[0x6].P,__debug_mmu.iamr[0x6].L,__debug_mmu.iamr[0x6].P
+printf "amr7 : L:%08lx P:%08lx : L:%08lx P:%08lx\n",__debug_mmu.damr[0x7].L,__debug_mmu.damr[0x7].P,__debug_mmu.iamr[0x7].L,__debug_mmu.iamr[0x7].P
+
+printf "amr8 : L:%08lx P:%08lx\n",__debug_mmu.damr[0x8].L,__debug_mmu.damr[0x8].P
+printf "amr9 : L:%08lx P:%08lx\n",__debug_mmu.damr[0x9].L,__debug_mmu.damr[0x9].P
+printf "amr10: L:%08lx P:%08lx\n",__debug_mmu.damr[0xa].L,__debug_mmu.damr[0xa].P
+printf "amr11: L:%08lx P:%08lx\n",__debug_mmu.damr[0xb].L,__debug_mmu.damr[0xb].P
+
+end
+
+
+define _tlb
+printf "tlb[0x00]: %08lx %08lx  %08lx %08lx\n",__debug_mmu.tlb[0x0].L,__debug_mmu.tlb[0x0].P,__debug_mmu.tlb[0x40+0x0].L,__debug_mmu.tlb[0x40+0x0].P
+printf "tlb[0x01]: %08lx %08lx  %08lx %08lx\n",__debug_mmu.tlb[0x1].L,__debug_mmu.tlb[0x1].P,__debug_mmu.tlb[0x40+0x1].L,__debug_mmu.tlb[0x40+0x1].P
+printf "tlb[0x02]: %08lx %08lx  %08lx %08lx\n",__debug_mmu.tlb[0x2].L,__debug_mmu.tlb[0x2].P,__debug_mmu.tlb[0x40+0x2].L,__debug_mmu.tlb[0x40+0x2].P
+printf "tlb[0x03]: %08lx %08lx  %08lx %08lx\n",__debug_mmu.tlb[0x3].L,__debug_mmu.tlb[0x3].P,__debug_mmu.tlb[0x40+0x3].L,__debug_mmu.tlb[0x40+0x3].P
+printf "tlb[0x04]: %08lx %08lx  %08lx %08lx\n",__debug_mmu.tlb[0x4].L,__debug_mmu.tlb[0x4].P,__debug_mmu.tlb[0x40+0x4].L,__debug_mmu.tlb[0x40+0x4].P
+printf "tlb[0x05]: %08lx %08lx  %08lx %08lx\n",__debug_mmu.tlb[0x5].L,__debug_mmu.tlb[0x5].P,__debug_mmu.tlb[0x40+0x5].L,__debug_mmu.tlb[0x40+0x5].P
+printf "tlb[0x06]: %08lx %08lx  %08lx %08lx\n",__debug_mmu.tlb[0x6].L,__debug_mmu.tlb[0x6].P,__debug_mmu.tlb[0x40+0x6].L,__debug_mmu.tlb[0x40+0x6].P
+printf "tlb[0x07]: %08lx %08lx  %08lx %08lx\n",__debug_mmu.tlb[0x7].L,__debug_mmu.tlb[0x7].P,__debug_mmu.tlb[0x40+0x7].L,__debug_mmu.tlb[0x40+0x7].P
+printf "tlb[0x08]: %08lx %08lx  %08lx %08lx\n",__debug_mmu.tlb[0x8].L,__debug_mmu.tlb[0x8].P,__debug_mmu.tlb[0x40+0x8].L,__debug_mmu.tlb[0x40+0x8].P
+printf "tlb[0x09]: %08lx %08lx  %08lx %08lx\n",__debug_mmu.tlb[0x9].L,__debug_mmu.tlb[0x9].P,__debug_mmu.tlb[0x40+0x9].L,__debug_mmu.tlb[0x40+0x9].P
+printf "tlb[0x0a]: %08lx %08lx  %08lx %08lx\n",__debug_mmu.tlb[0xa].L,__debug_mmu.tlb[0xa].P,__debug_mmu.tlb[0x40+0xa].L,__debug_mmu.tlb[0x40+0xa].P
+printf "tlb[0x0b]: %08lx %08lx  %08lx %08lx\n",__debug_mmu.tlb[0xb].L,__debug_mmu.tlb[0xb].P,__debug_mmu.tlb[0x40+0xb].L,__debug_mmu.tlb[0x40+0xb].P
+printf "tlb[0x0c]: %08lx %08lx  %08lx %08lx\n",__debug_mmu.tlb[0xc].L,__debug_mmu.tlb[0xc].P,__debug_mmu.tlb[0x40+0xc].L,__debug_mmu.tlb[0x40+0xc].P
+printf "tlb[0x0d]: %08lx %08lx  %08lx %08lx\n",__debug_mmu.tlb[0xd].L,__debug_mmu.tlb[0xd].P,__debug_mmu.tlb[0x40+0xd].L,__debug_mmu.tlb[0x40+0xd].P
+printf "tlb[0x0e]: %08lx %08lx  %08lx %08lx\n",__debug_mmu.tlb[0xe].L,__debug_mmu.tlb[0xe].P,__debug_mmu.tlb[0x40+0xe].L,__debug_mmu.tlb[0x40+0xe].P
+printf "tlb[0x0f]: %08lx %08lx  %08lx %08lx\n",__debug_mmu.tlb[0xf].L,__debug_mmu.tlb[0xf].P,__debug_mmu.tlb[0x40+0xf].L,__debug_mmu.tlb[0x40+0xf].P
+printf "tlb[0x10]: %08lx %08lx  %08lx %08lx\n",__debug_mmu.tlb[0x10].L,__debug_mmu.tlb[0x10].P,__debug_mmu.tlb[0x40+0x10].L,__debug_mmu.tlb[0x40+0x10].P
+printf "tlb[0x11]: %08lx %08lx  %08lx %08lx\n",__debug_mmu.tlb[0x11].L,__debug_mmu.tlb[0x11].P,__debug_mmu.tlb[0x40+0x11].L,__debug_mmu.tlb[0x40+0x11].P
+printf "tlb[0x12]: %08lx %08lx  %08lx %08lx\n",__debug_mmu.tlb[0x12].L,__debug_mmu.tlb[0x12].P,__debug_mmu.tlb[0x40+0x12].L,__debug_mmu.tlb[0x40+0x12].P
+printf "tlb[0x13]: %08lx %08lx  %08lx %08lx\n",__debug_mmu.tlb[0x13].L,__debug_mmu.tlb[0x13].P,__debug_mmu.tlb[0x40+0x13].L,__debug_mmu.tlb[0x40+0x13].P
+printf "tlb[0x14]: %08lx %08lx  %08lx %08lx\n",__debug_mmu.tlb[0x14].L,__debug_mmu.tlb[0x14].P,__debug_mmu.tlb[0x40+0x14].L,__debug_mmu.tlb[0x40+0x14].P
+printf "tlb[0x15]: %08lx %08lx  %08lx %08lx\n",__debug_mmu.tlb[0x15].L,__debug_mmu.tlb[0x15].P,__debug_mmu.tlb[0x40+0x15].L,__debug_mmu.tlb[0x40+0x15].P
+printf "tlb[0x16]: %08lx %08lx  %08lx %08lx\n",__debug_mmu.tlb[0x16].L,__debug_mmu.tlb[0x16].P,__debug_mmu.tlb[0x40+0x16].L,__debug_mmu.tlb[0x40+0x16].P
+printf "tlb[0x17]: %08lx %08lx  %08lx %08lx\n",__debug_mmu.tlb[0x17].L,__debug_mmu.tlb[0x17].P,__debug_mmu.tlb[0x40+0x17].L,__debug_mmu.tlb[0x40+0x17].P
+printf "tlb[0x18]: %08lx %08lx  %08lx %08lx\n",__debug_mmu.tlb[0x18].L,__debug_mmu.tlb[0x18].P,__debug_mmu.tlb[0x40+0x18].L,__debug_mmu.tlb[0x40+0x18].P
+printf "tlb[0x19]: %08lx %08lx  %08lx %08lx\n",__debug_mmu.tlb[0x19].L,__debug_mmu.tlb[0x19].P,__debug_mmu.tlb[0x40+0x19].L,__debug_mmu.tlb[0x40+0x19].P
+printf "tlb[0x1a]: %08lx %08lx  %08lx %08lx\n",__debug_mmu.tlb[0x1a].L,__debug_mmu.tlb[0x1a].P,__debug_mmu.tlb[0x40+0x1a].L,__debug_mmu.tlb[0x40+0x1a].P
+printf "tlb[0x1b]: %08lx %08lx  %08lx %08lx\n",__debug_mmu.tlb[0x1b].L,__debug_mmu.tlb[0x1b].P,__debug_mmu.tlb[0x40+0x1b].L,__debug_mmu.tlb[0x40+0x1b].P
+printf "tlb[0x1c]: %08lx %08lx  %08lx %08lx\n",__debug_mmu.tlb[0x1c].L,__debug_mmu.tlb[0x1c].P,__debug_mmu.tlb[0x40+0x1c].L,__debug_mmu.tlb[0x40+0x1c].P
+printf "tlb[0x1d]: %08lx %08lx  %08lx %08lx\n",__debug_mmu.tlb[0x1d].L,__debug_mmu.tlb[0x1d].P,__debug_mmu.tlb[0x40+0x1d].L,__debug_mmu.tlb[0x40+0x1d].P
+printf "tlb[0x1e]: %08lx %08lx  %08lx %08lx\n",__debug_mmu.tlb[0x1e].L,__debug_mmu.tlb[0x1e].P,__debug_mmu.tlb[0x40+0x1e].L,__debug_mmu.tlb[0x40+0x1e].P
+printf "tlb[0x1f]: %08lx %08lx  %08lx %08lx\n",__debug_mmu.tlb[0x1f].L,__debug_mmu.tlb[0x1f].P,__debug_mmu.tlb[0x40+0x1f].L,__debug_mmu.tlb[0x40+0x1f].P
+printf "tlb[0x20]: %08lx %08lx  %08lx %08lx\n",__debug_mmu.tlb[0x20].L,__debug_mmu.tlb[0x20].P,__debug_mmu.tlb[0x40+0x20].L,__debug_mmu.tlb[0x40+0x20].P
+printf "tlb[0x21]: %08lx %08lx  %08lx %08lx\n",__debug_mmu.tlb[0x21].L,__debug_mmu.tlb[0x21].P,__debug_mmu.tlb[0x40+0x21].L,__debug_mmu.tlb[0x40+0x21].P
+printf "tlb[0x22]: %08lx %08lx  %08lx %08lx\n",__debug_mmu.tlb[0x22].L,__debug_mmu.tlb[0x22].P,__debug_mmu.tlb[0x40+0x22].L,__debug_mmu.tlb[0x40+0x22].P
+printf "tlb[0x23]: %08lx %08lx  %08lx %08lx\n",__debug_mmu.tlb[0x23].L,__debug_mmu.tlb[0x23].P,__debug_mmu.tlb[0x40+0x23].L,__debug_mmu.tlb[0x40+0x23].P
+printf "tlb[0x24]: %08lx %08lx  %08lx %08lx\n",__debug_mmu.tlb[0x24].L,__debug_mmu.tlb[0x24].P,__debug_mmu.tlb[0x40+0x24].L,__debug_mmu.tlb[0x40+0x24].P
+printf "tlb[0x25]: %08lx %08lx  %08lx %08lx\n",__debug_mmu.tlb[0x25].L,__debug_mmu.tlb[0x25].P,__debug_mmu.tlb[0x40+0x25].L,__debug_mmu.tlb[0x40+0x25].P
+printf "tlb[0x26]: %08lx %08lx  %08lx %08lx\n",__debug_mmu.tlb[0x26].L,__debug_mmu.tlb[0x26].P,__debug_mmu.tlb[0x40+0x26].L,__debug_mmu.tlb[0x40+0x26].P
+printf "tlb[0x27]: %08lx %08lx  %08lx %08lx\n",__debug_mmu.tlb[0x27].L,__debug_mmu.tlb[0x27].P,__debug_mmu.tlb[0x40+0x27].L,__debug_mmu.tlb[0x40+0x27].P
+printf "tlb[0x28]: %08lx %08lx  %08lx %08lx\n",__debug_mmu.tlb[0x28].L,__debug_mmu.tlb[0x28].P,__debug_mmu.tlb[0x40+0x28].L,__debug_mmu.tlb[0x40+0x28].P
+printf "tlb[0x29]: %08lx %08lx  %08lx %08lx\n",__debug_mmu.tlb[0x29].L,__debug_mmu.tlb[0x29].P,__debug_mmu.tlb[0x40+0x29].L,__debug_mmu.tlb[0x40+0x29].P
+printf "tlb[0x2a]: %08lx %08lx  %08lx %08lx\n",__debug_mmu.tlb[0x2a].L,__debug_mmu.tlb[0x2a].P,__debug_mmu.tlb[0x40+0x2a].L,__debug_mmu.tlb[0x40+0x2a].P
+printf "tlb[0x2b]: %08lx %08lx  %08lx %08lx\n",__debug_mmu.tlb[0x2b].L,__debug_mmu.tlb[0x2b].P,__debug_mmu.tlb[0x40+0x2b].L,__debug_mmu.tlb[0x40+0x2b].P
+printf "tlb[0x2c]: %08lx %08lx  %08lx %08lx\n",__debug_mmu.tlb[0x2c].L,__debug_mmu.tlb[0x2c].P,__debug_mmu.tlb[0x40+0x2c].L,__debug_mmu.tlb[0x40+0x2c].P
+printf "tlb[0x2d]: %08lx %08lx  %08lx %08lx\n",__debug_mmu.tlb[0x2d].L,__debug_mmu.tlb[0x2d].P,__debug_mmu.tlb[0x40+0x2d].L,__debug_mmu.tlb[0x40+0x2d].P
+printf "tlb[0x2e]: %08lx %08lx  %08lx %08lx\n",__debug_mmu.tlb[0x2e].L,__debug_mmu.tlb[0x2e].P,__debug_mmu.tlb[0x40+0x2e].L,__debug_mmu.tlb[0x40+0x2e].P
+printf "tlb[0x2f]: %08lx %08lx  %08lx %08lx\n",__debug_mmu.tlb[0x2f].L,__debug_mmu.tlb[0x2f].P,__debug_mmu.tlb[0x40+0x2f].L,__debug_mmu.tlb[0x40+0x2f].P
+printf "tlb[0x30]: %08lx %08lx  %08lx %08lx\n",__debug_mmu.tlb[0x30].L,__debug_mmu.tlb[0x30].P,__debug_mmu.tlb[0x40+0x30].L,__debug_mmu.tlb[0x40+0x30].P
+printf "tlb[0x31]: %08lx %08lx  %08lx %08lx\n",__debug_mmu.tlb[0x31].L,__debug_mmu.tlb[0x31].P,__debug_mmu.tlb[0x40+0x31].L,__debug_mmu.tlb[0x40+0x31].P
+printf "tlb[0x32]: %08lx %08lx  %08lx %08lx\n",__debug_mmu.tlb[0x32].L,__debug_mmu.tlb[0x32].P,__debug_mmu.tlb[0x40+0x32].L,__debug_mmu.tlb[0x40+0x32].P
+printf "tlb[0x33]: %08lx %08lx  %08lx %08lx\n",__debug_mmu.tlb[0x33].L,__debug_mmu.tlb[0x33].P,__debug_mmu.tlb[0x40+0x33].L,__debug_mmu.tlb[0x40+0x33].P
+printf "tlb[0x34]: %08lx %08lx  %08lx %08lx\n",__debug_mmu.tlb[0x34].L,__debug_mmu.tlb[0x34].P,__debug_mmu.tlb[0x40+0x34].L,__debug_mmu.tlb[0x40+0x34].P
+printf "tlb[0x35]: %08lx %08lx  %08lx %08lx\n",__debug_mmu.tlb[0x35].L,__debug_mmu.tlb[0x35].P,__debug_mmu.tlb[0x40+0x35].L,__debug_mmu.tlb[0x40+0x35].P
+printf "tlb[0x36]: %08lx %08lx  %08lx %08lx\n",__debug_mmu.tlb[0x36].L,__debug_mmu.tlb[0x36].P,__debug_mmu.tlb[0x40+0x36].L,__debug_mmu.tlb[0x40+0x36].P
+printf "tlb[0x37]: %08lx %08lx  %08lx %08lx\n",__debug_mmu.tlb[0x37].L,__debug_mmu.tlb[0x37].P,__debug_mmu.tlb[0x40+0x37].L,__debug_mmu.tlb[0x40+0x37].P
+printf "tlb[0x38]: %08lx %08lx  %08lx %08lx\n",__debug_mmu.tlb[0x38].L,__debug_mmu.tlb[0x38].P,__debug_mmu.tlb[0x40+0x38].L,__debug_mmu.tlb[0x40+0x38].P
+printf "tlb[0x39]: %08lx %08lx  %08lx %08lx\n",__debug_mmu.tlb[0x39].L,__debug_mmu.tlb[0x39].P,__debug_mmu.tlb[0x40+0x39].L,__debug_mmu.tlb[0x40+0x39].P
+printf "tlb[0x3a]: %08lx %08lx  %08lx %08lx\n",__debug_mmu.tlb[0x3a].L,__debug_mmu.tlb[0x3a].P,__debug_mmu.tlb[0x40+0x3a].L,__debug_mmu.tlb[0x40+0x3a].P
+printf "tlb[0x3b]: %08lx %08lx  %08lx %08lx\n",__debug_mmu.tlb[0x3b].L,__debug_mmu.tlb[0x3b].P,__debug_mmu.tlb[0x40+0x3b].L,__debug_mmu.tlb[0x40+0x3b].P
+printf "tlb[0x3c]: %08lx %08lx  %08lx %08lx\n",__debug_mmu.tlb[0x3c].L,__debug_mmu.tlb[0x3c].P,__debug_mmu.tlb[0x40+0x3c].L,__debug_mmu.tlb[0x40+0x3c].P
+printf "tlb[0x3d]: %08lx %08lx  %08lx %08lx\n",__debug_mmu.tlb[0x3d].L,__debug_mmu.tlb[0x3d].P,__debug_mmu.tlb[0x40+0x3d].L,__debug_mmu.tlb[0x40+0x3d].P
+printf "tlb[0x3e]: %08lx %08lx  %08lx %08lx\n",__debug_mmu.tlb[0x3e].L,__debug_mmu.tlb[0x3e].P,__debug_mmu.tlb[0x40+0x3e].L,__debug_mmu.tlb[0x40+0x3e].P
+printf "tlb[0x3f]: %08lx %08lx  %08lx %08lx\n",__debug_mmu.tlb[0x3f].L,__debug_mmu.tlb[0x3f].P,__debug_mmu.tlb[0x40+0x3f].L,__debug_mmu.tlb[0x40+0x3f].P
+end
+
+
+define _pgd
+p (pgd_t[0x40])*(pgd_t*)(__debug_mmu.damr[0x3].L)
+end
+
+define _ptd_i
+p (pte_t[0x1000])*(pte_t*)(__debug_mmu.damr[0x4].L)
+end
+
+define _ptd_d
+p (pte_t[0x1000])*(pte_t*)(__debug_mmu.damr[0x5].L)
+end
diff -Nru a/Documentation/fujitsu/frv/gdbstub.txt b/Documentation/fujitsu/frv/gdbstub.txt
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/Documentation/fujitsu/frv/gdbstub.txt	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,130 @@
+			     ====================
+			     DEBUGGING FR-V LINUX
+			     ====================
+
+
+The kernel contains a GDB stub that talks GDB remote protocol across a serial
+port. This permits GDB to single step through the kernel, set breakpoints and
+trap exceptions that happen in kernel space and interrupt execution. It also
+permits the NMI interrupt button or serial port events to jump the kernel into
+the debugger.
+
+On the CPUs that have on-chip UARTs (FR400, FR403, FR405, FR555), the
+GDB stub hijacks a serial port for its own purposes, and makes it
+generate level 15 interrupts (NMI). The kernel proper cannot see the serial
+port in question under these conditions.
+
+On the MB93091-VDK CPU boards, the GDB stub uses UART1, which would otherwise
+be /dev/ttyS1. On the MB93093-PDK, the GDB stub uses UART0. Therefore, on the
+PDK there is no externally accessible serial port and the serial port to
+which the touch screen is attached becomes /dev/ttyS0.
+
+Note that the GDB stub runs entirely within CPU debug mode, and so should not
+incur any exceptions or interrupts whilst it is active. In particular, note
+that the clock will lose time since it is implemented in software.
+
+
+==================
+KERNEL PREPARATION
+==================
+
+Firstly, a debuggable kernel must be built. To do this, unpack the kernel tree
+and copy the configuration that you wish to use to .config. Then reconfigure
+the following things on the "Kernel Hacking" tab:
+
+  (*) "Include debugging information"
+
+      Set this to "Y". This causes all C and Assembly files to be compiled
+      to include debugging information.
+
+  (*) "In-kernel GDB stub"
+
+      Set this to "Y". This causes the GDB stub to be compiled into the
+      kernel.
+
+  (*) "Immediate activation"
+
+      Set this to "Y" if you want the GDB stub to activate as soon as possible
+      and wait for GDB to connect. This allows you to start tracing right from
+      the beginning of start_kernel() in init/main.c.
+
+  (*) "Console through GDB stub"
+
+      Set this to "Y" if you wish to be able to use "console=gdb0" on the
+      command line. That tells the kernel to pass system console messages to
+      GDB (which then prints them on its standard output). This is useful when
+      debugging the serial drivers that'd otherwise be used to pass console
+      messages to the outside world.
+
+Then build as usual, download to the board and execute. Note that if
+"Immediate activation" was selected, then the kernel will wait for GDB to
+attach. If not, then the kernel will boot immediately and GDB will have to
+interupt it or wait for an exception to occur if before doing anything with
+the kernel.
+
+
+=========================
+KERNEL DEBUGGING WITH GDB
+=========================
+
+Set the serial port on the computer that's going to run GDB to the appropriate
+baud rate. Assuming the board's debug port is connected to ttyS0/COM1 on the
+computer doing the debugging:
+
+	stty -F /dev/ttyS0 115200
+
+Then start GDB in the base of the kernel tree:
+
+	frv-uclinux-gdb linux		[uClinux]
+
+Or:
+
+	frv-uclinux-gdb vmlinux		[MMU linux]
+
+When the prompt appears:
+
+	GNU gdb frv-031024
+	Copyright 2003 Free Software Foundation, Inc.
+	GDB is free software, covered by the GNU General Public License, and you are
+	welcome to change it and/or distribute copies of it under certain conditions.
+	Type "show copying" to see the conditions.
+	There is absolutely no warranty for GDB.  Type "show warranty" for details.
+	This GDB was configured as "--host=i686-pc-linux-gnu --target=frv-uclinux"...
+	(gdb)
+
+Attach to the board like this:
+
+        (gdb) target remote /dev/ttyS0
+	Remote debugging using /dev/ttyS0
+	start_kernel () at init/main.c:395
+	(gdb)
+
+This should show the appropriate lines from the source too. The kernel can
+then be debugged almost as if it's any other program.
+
+
+===============================
+INTERRUPTING THE RUNNING KERNEL
+===============================
+
+The kernel can be interrupted whilst it is running, causing a jump back to the
+GDB stub and the debugger:
+
+  (*) Pressing Ctrl-C in GDB. This will cause GDB to try and interrupt the
+      kernel by sending an RS232 BREAK over the serial line to the GDB
+      stub. This will (mostly) immediately interrupt the kernel and return it
+      to the debugger.
+
+  (*) Pressing the NMI button on the board will also cause a jump into the
+      debugger.
+
+  (*) Setting a software breakpoint. This sets a break instruction at the
+      desired location which the GDB stub then traps the exception for.
+
+  (*) Setting a hardware breakpoint. The GDB stub is capable of using the IBAR
+      and DBAR registers to assist debugging.
+
+Furthermore, the GDB stub will intercept a number of exceptions automatically
+if they are caused by kernel execution. It will also intercept BUG() macro
+invokation.
+
diff -Nru a/Documentation/fujitsu/frv/mmu-layout.txt b/Documentation/fujitsu/frv/mmu-layout.txt
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/Documentation/fujitsu/frv/mmu-layout.txt	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,306 @@
+				 =================================
+				 FR451 MMU LINUX MEMORY MANAGEMENT
+				 =================================
+
+============
+MMU HARDWARE
+============
+
+FR451 MMU Linux puts the MMU into EDAT mode whilst running. This means that it uses both the SAT
+registers and the DAT TLB to perform address translation.
+
+There are 8 IAMLR/IAMPR register pairs and 16 DAMLR/DAMPR register pairs for SAT mode.
+
+In DAT mode, there is also a TLB organised in cache format as 64 lines x 2 ways. Each line spans a
+16KB range of addresses, but can match a larger region.
+
+
+===========================
+MEMORY MANAGEMENT REGISTERS
+===========================
+
+Certain control registers are used by the kernel memory management routines:
+
+	REGISTERS		USAGE
+	======================	==================================================
+	IAMR0, DAMR0		Kernel image and data mappings
+	IAMR1, DAMR1		First-chance TLB lookup mapping
+	DAMR2			Page attachment for cache flush by page
+	DAMR3			Current PGD mapping
+	SCR0, DAMR4		Instruction TLB PGE/PTD cache
+	SCR1, DAMR5		Data TLB PGE/PTD cache
+	DAMR6-10		kmap_atomic() mappings
+	DAMR11			I/O mapping
+	CXNR			mm_struct context ID
+	TTBR			Page directory (PGD) pointer (physical address)
+
+
+=====================
+GENERAL MEMORY LAYOUT
+=====================
+
+The physical memory layout is as follows:
+
+  PHYSICAL ADDRESS	CONTROLLER	DEVICE
+  ===================	==============	=======================================
+  00000000 - BFFFFFFF	SDRAM		SDRAM area
+  E0000000 - EFFFFFFF	L-BUS CS2#	VDK SLBUS/PCI window
+  F0000000 - F0FFFFFF	L-BUS CS5#	MB93493 CSC area (DAV daughter board)
+  F1000000 - F1FFFFFF	L-BUS CS7#	(CB70 CPU-card PCMCIA port I/O space)
+  FC000000 - FC0FFFFF	L-BUS CS1#	VDK MB86943 config space
+  FC100000 - FC1FFFFF	L-BUS CS6#	DM9000 NIC I/O space
+  FC200000 - FC2FFFFF	L-BUS CS3#	MB93493 CSR area (DAV daughter board)
+  FD000000 - FDFFFFFF	L-BUS CS4#	(CB70 CPU-card extra flash space)
+  FE000000 - FEFFFFFF			Internal CPU peripherals
+  FF000000 - FF1FFFFF	L-BUS CS0#	Flash 1
+  FF200000 - FF3FFFFF	L-BUS CS0#	Flash 2
+  FFC00000 - FFC0001F	L-BUS CS0#	FPGA
+
+The virtual memory layout is:
+
+  VIRTUAL ADDRESS    PHYSICAL	TRANSLATOR	FLAGS	SIZE	OCCUPATION
+  =================  ========	==============	=======	=======	===================================
+  00004000-BFFFFFFF  various	TLB,xAMR1	D-N-??V	3GB	Userspace
+  C0000000-CFFFFFFF  00000000	xAMPR0		-L-S--V	256MB	Kernel image and data
+  D0000000-D7FFFFFF  various	TLB,xAMR1	D-NS??V	128MB	vmalloc area
+  D8000000-DBFFFFFF  various	TLB,xAMR1	D-NS??V	64MB	kmap() area
+  DC000000-DCFFFFFF  various	TLB			1MB	Secondary kmap_atomic() frame
+  DD000000-DD27FFFF  various	DAMR			160KB	Primary kmap_atomic() frame
+  DD040000			DAMR2/IAMR2	-L-S--V	page	Page cache flush attachment point
+  DD080000			DAMR3		-L-SC-V	page	Page Directory (PGD)
+  DD0C0000			DAMR4		-L-SC-V	page	Cached insn TLB Page Table lookup
+  DD100000			DAMR5		-L-SC-V	page	Cached data TLB Page Table lookup
+  DD140000			DAMR6		-L-S--V	page	kmap_atomic(KM_BOUNCE_READ)
+  DD180000			DAMR7		-L-S--V	page	kmap_atomic(KM_SKB_SUNRPC_DATA)
+  DD1C0000			DAMR8		-L-S--V	page	kmap_atomic(KM_SKB_DATA_SOFTIRQ)
+  DD200000			DAMR9		-L-S--V	page	kmap_atomic(KM_USER0)
+  DD240000			DAMR10		-L-S--V	page	kmap_atomic(KM_USER1)
+  E0000000-FFFFFFFF  E0000000	DAMR11		-L-SC-V	512MB	I/O region
+
+IAMPR1 and DAMPR1 are used as an extension to the TLB.
+
+
+====================
+KMAP AND KMAP_ATOMIC
+====================
+
+To access pages in the page cache (which may not be directly accessible if highmem is available),
+the kernel calls kmap(), does the access and then calls kunmap(); or it calls kmap_atomic(), does
+the access and then calls kunmap_atomic().
+
+kmap() creates an attachment between an arbitrary inaccessible page and a range of virtual
+addresses by installing a PTE in a special page table. The kernel can then access this page as it
+wills. When it's finished, the kernel calls kunmap() to clear the PTE.
+
+kmap_atomic() does something slightly different. In the interests of speed, it chooses one of two
+strategies:
+
+ (1) If possible, kmap_atomic() attaches the requested page to one of DAMPR5 through DAMPR10
+     register pairs; and the matching kunmap_atomic() clears the DAMPR. This makes high memory
+     support really fast as there's no need to flush the TLB or modify the page tables. The DAMLR
+     registers being used for this are preset during boot and don't change over the lifetime of the
+     process. There's a direct mapping between the first few kmap_atomic() types, DAMR number and
+     virtual address slot.
+
+     However, there are more kmap_atomic() types defined than there are DAMR registers available,
+     so we fall back to:
+
+ (2) kmap_atomic() uses a slot in the secondary frame (determined by the type parameter), and then
+     locks an entry in the TLB to translate that slot to the specified page. The number of slots is
+     obviously limited, and their positions are controlled such that each slot is matched by a
+     different line in the TLB. kunmap() ejects the entry from the TLB.
+
+Note that the first three kmap atomic types are really just declared as placeholders. The DAMPR
+registers involved are actually modified directly.
+
+Also note that kmap() itself may sleep, kmap_atomic() may never sleep and both always succeed;
+furthermore, a driver using kmap() may sleep before calling kunmap(), but may not sleep before
+calling kunmap_atomic() if it had previously called kmap_atomic().
+
+
+===============================
+USING MORE THAN 256MB OF MEMORY
+===============================
+
+The kernel cannot access more than 256MB of memory directly. The physical layout, however, permits
+up to 3GB of SDRAM (possibly 3.25GB) to be made available. By using CONFIG_HIGHMEM, the kernel can
+allow userspace (by way of page tables) and itself (by way of kmap) to deal with the memory
+allocation.
+
+External devices can, of course, still DMA to and from all of the SDRAM, even if the kernel can't
+see it directly. The kernel translates page references into real addresses for communicating to the
+devices.
+
+
+===================
+PAGE TABLE TOPOLOGY
+===================
+
+The page tables are arranged in 2-layer format. There is a middle layer (PMD) that would be used in
+3-layer format tables but that is folded into the top layer (PGD) and so consumes no extra memory
+or processing power.
+
+  +------+     PGD    PMD
+  | TTBR |--->+-------------------+
+  +------+    |      |      : STE |
+              | PGE0 | PME0 : STE |
+              |      |      : STE |
+              +-------------------+              Page Table
+              |      |      : STE -------------->+--------+ +0x0000
+              | PGE1 | PME0 : STE -----------+   | PTE0   |
+              |      |      : STE -------+   |   +--------+
+              +-------------------+      |   |   | PTE63  |
+              |      |      : STE |      |   +-->+--------+ +0x0100
+              | PGE2 | PME0 : STE |      |       | PTE64  |
+              |      |      : STE |      |       +--------+
+              +-------------------+      |       | PTE127 |
+              |      |      : STE |      +------>+--------+ +0x0200
+              | PGE3 | PME0 : STE |              | PTE128 |
+              |      |      : STE |              +--------+
+              +-------------------+              | PTE191 |
+                                                 +--------+ +0x0300
+
+Each Page Directory (PGD) is 16KB (page size) in size and is divided into 64 entries (PGEs). Each
+PGE contains one Page Mid Directory (PMD).
+
+Each PMD is 256 bytes in size and contains a single entry (PME). Each PME holds 64 FR451 MMU
+segment table entries of 4 bytes apiece. Each PME "points to" a page table. In practice, each STE
+points to a subset of the page table, the first to PT+0x0000, the second to PT+0x0100, the third to
+PT+0x200, and so on.
+
+Each PGE and PME covers 64MB of the total virtual address space.
+
+Each Page Table (PTD) is 16KB (page size) in size, and is divided into 4096 entries (PTEs). Each
+entry can point to one 16KB page. In practice, each Linux page table is subdivided into 64 FR451
+MMU page tables. But they are all grouped together to make management easier, in particular rmap
+support is then trivial.
+
+Grouping page tables in this fashion makes PGE caching in SCR0/SCR1 more efficient because the
+coverage of the cached item is greater.
+
+Page tables for the vmalloc area are allocated at boot time and shared between all mm_structs.
+
+
+=================
+USER SPACE LAYOUT
+=================
+
+For MMU capable Linux, the regions userspace code are allowed to access are kept entirely separate
+from those dedicated to the kernel:
+
+	VIRTUAL ADDRESS    SIZE   PURPOSE
+	=================  =====  ===================================
+	00000000-00003fff  4KB    NULL pointer access trap
+	00004000-01ffffff  ~32MB  lower mmap space (grows up)
+	02000000-021fffff  2MB    Stack space (grows down from top)
+	02200000-nnnnnnnn         Executable mapping
+        nnnnnnnn-                 brk space (grows up)
+	        -bfffffff         upper mmap space (grows down)
+
+This is so arranged so as to make best use of the 16KB page tables and the way in which PGEs/PMEs
+are cached by the TLB handler. The lower mmap space is filled first, and then the upper mmap space
+is filled.
+
+
+===============================
+GDB-STUB MMU DEBUGGING SERVICES
+===============================
+
+The gdb-stub included in this kernel provides a number of services to aid in the debugging of MMU
+related kernel services:
+
+ (*) Every time the kernel stops, certain state information is dumped into __debug_mmu. This
+     variable is defined in arch/frv/kernel/gdb-stub.c. Note that the gdbinit file in this
+     directory has some useful macros for dealing with this.
+
+     (*) __debug_mmu.tlb[]
+
+	 This receives the current TLB contents. This can be viewed with the _tlb GDB macro:
+
+		(gdb) _tlb
+		tlb[0x00]: 01000005 00718203  01000002 00718203
+		tlb[0x01]: 01004002 006d4201  01004005 006d4203
+		tlb[0x02]: 01008002 006d0201  01008006 00004200
+		tlb[0x03]: 0100c006 007f4202  0100c002 0064c202
+		tlb[0x04]: 01110005 00774201  01110002 00774201
+		tlb[0x05]: 01114005 00770201  01114002 00770201
+		tlb[0x06]: 01118002 0076c201  01118005 0076c201
+		...
+		tlb[0x3d]: 010f4002 00790200  001f4002 0054ca02
+		tlb[0x3e]: 010f8005 0078c201  010f8002 0078c201
+		tlb[0x3f]: 001fc002 0056ca01  001fc005 00538a01
+
+     (*) __debug_mmu.iamr[]
+     (*) __debug_mmu.damr[]
+
+	 These receive the current IAMR and DAMR contents. These can be viewed with with the _amr
+	 GDB macro:
+
+		(gdb) _amr
+		AMRx           DAMR                    IAMR
+		====   =====================   =====================
+		amr0 : L:c0000000 P:00000cb9 : L:c0000000 P:000004b9
+		amr1 : L:01070005 P:006f9203 : L:0102c005 P:006a1201
+		amr2 : L:d8d00000 P:00000000 : L:d8d00000 P:00000000
+		amr3 : L:d8d04000 P:00534c0d : L:00000000 P:00000000
+		amr4 : L:d8d08000 P:00554c0d : L:00000000 P:00000000
+		amr5 : L:d8d0c000 P:00554c0d : L:00000000 P:00000000
+		amr6 : L:d8d10000 P:00000000 : L:00000000 P:00000000
+		amr7 : L:d8d14000 P:00000000 : L:00000000 P:00000000
+		amr8 : L:d8d18000 P:00000000
+		amr9 : L:d8d1c000 P:00000000
+		amr10: L:d8d20000 P:00000000
+		amr11: L:e0000000 P:e0000ccd
+
+ (*) The current task's page directory is bound to DAMR3.
+
+     This can be viewed with the _pgd GDB macro:
+
+	(gdb) _pgd
+	$3 = {{pge = {{ste = {0x554001, 0x554101, 0x554201, 0x554301, 0x554401,
+		  0x554501, 0x554601, 0x554701, 0x554801, 0x554901, 0x554a01,
+		  0x554b01, 0x554c01, 0x554d01, 0x554e01, 0x554f01, 0x555001,
+		  0x555101, 0x555201, 0x555301, 0x555401, 0x555501, 0x555601,
+		  0x555701, 0x555801, 0x555901, 0x555a01, 0x555b01, 0x555c01,
+		  0x555d01, 0x555e01, 0x555f01, 0x556001, 0x556101, 0x556201,
+		  0x556301, 0x556401, 0x556501, 0x556601, 0x556701, 0x556801,
+		  0x556901, 0x556a01, 0x556b01, 0x556c01, 0x556d01, 0x556e01,
+		  0x556f01, 0x557001, 0x557101, 0x557201, 0x557301, 0x557401,
+		  0x557501, 0x557601, 0x557701, 0x557801, 0x557901, 0x557a01,
+		  0x557b01, 0x557c01, 0x557d01, 0x557e01, 0x557f01}}}}, {pge = {{
+		ste = {0x0 <repeats 64 times>}}}} <repeats 51 times>, {pge = {{ste = {
+		  0x248001, 0x248101, 0x248201, 0x248301, 0x248401, 0x248501,
+		  0x248601, 0x248701, 0x248801, 0x248901, 0x248a01, 0x248b01,
+		  0x248c01, 0x248d01, 0x248e01, 0x248f01, 0x249001, 0x249101,
+		  0x249201, 0x249301, 0x249401, 0x249501, 0x249601, 0x249701,
+		  0x249801, 0x249901, 0x249a01, 0x249b01, 0x249c01, 0x249d01,
+		  0x249e01, 0x249f01, 0x24a001, 0x24a101, 0x24a201, 0x24a301,
+		  0x24a401, 0x24a501, 0x24a601, 0x24a701, 0x24a801, 0x24a901,
+		  0x24aa01, 0x24ab01, 0x24ac01, 0x24ad01, 0x24ae01, 0x24af01,
+		  0x24b001, 0x24b101, 0x24b201, 0x24b301, 0x24b401, 0x24b501,
+		  0x24b601, 0x24b701, 0x24b801, 0x24b901, 0x24ba01, 0x24bb01,
+		  0x24bc01, 0x24bd01, 0x24be01, 0x24bf01}}}}, {pge = {{ste = {
+		  0x0 <repeats 64 times>}}}} <repeats 11 times>}
+
+ (*) The PTD last used by the instruction TLB miss handler is attached to DAMR4.
+ (*) The PTD last used by the data TLB miss handler is attached to DAMR5.
+
+     These can be viewed with the _ptd_i and _ptd_d GDB macros:
+
+	(gdb) _ptd_d
+	$5 = {{pte = 0x0} <repeats 127 times>, {pte = 0x539b01}, {
+	    pte = 0x0} <repeats 896 times>, {pte = 0x719303}, {pte = 0x6d5303}, {
+	    pte = 0x0}, {pte = 0x0}, {pte = 0x0}, {pte = 0x0}, {pte = 0x0}, {
+	    pte = 0x0}, {pte = 0x0}, {pte = 0x0}, {pte = 0x0}, {pte = 0x6a1303}, {
+	    pte = 0x0} <repeats 12 times>, {pte = 0x709303}, {pte = 0x0}, {pte = 0x0},
+	  {pte = 0x6fd303}, {pte = 0x6f9303}, {pte = 0x6f5303}, {pte = 0x0}, {
+	    pte = 0x6ed303}, {pte = 0x531b01}, {pte = 0x50db01}, {
+	    pte = 0x0} <repeats 13 times>, {pte = 0x5303}, {pte = 0x7f5303}, {
+	    pte = 0x509b01}, {pte = 0x505b01}, {pte = 0x7c9303}, {pte = 0x7b9303}, {
+	    pte = 0x7b5303}, {pte = 0x7b1303}, {pte = 0x7ad303}, {pte = 0x0}, {
+	    pte = 0x0}, {pte = 0x7a1303}, {pte = 0x0}, {pte = 0x795303}, {pte = 0x0}, {
+	    pte = 0x78d303}, {pte = 0x0}, {pte = 0x0}, {pte = 0x0}, {pte = 0x0}, {
+	    pte = 0x0}, {pte = 0x775303}, {pte = 0x771303}, {pte = 0x76d303}, {
+	    pte = 0x0}, {pte = 0x765303}, {pte = 0x7c5303}, {pte = 0x501b01}, {
+	    pte = 0x4f1b01}, {pte = 0x4edb01}, {pte = 0x0}, {pte = 0x4f9b01}, {
+	    pte = 0x4fdb01}, {pte = 0x0} <repeats 2992 times>}
diff -Nru a/Documentation/i2c/chips/smsc47b397.txt b/Documentation/i2c/chips/smsc47b397.txt
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/Documentation/i2c/chips/smsc47b397.txt	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,146 @@
+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 -Nru a/Documentation/i2c/i2c-old-porting b/Documentation/i2c/i2c-old-porting
--- a/Documentation/i2c/i2c-old-porting	2005-03-01 23:39:16 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,626 +0,0 @@
-I2C Conversion Guide for I2C-old to the current I2C API
-July 2002
-For Linux Kernel v2.5.x
-Frank Davis <fdavis@si.rr.com>
--------------------------------------------------------
-
-There exists several kernel drivers that are using an old version of the I2C
-API. These drivers need to be converted to the current (kernel 2.5.x) version.
-The following document provides a guideline to make the appropriate changes to
-the affected drivers. There maybe slight modifications to this guide that are 
-specific to the driver you are working on. If you see {driver_name}, replace 
-that with the respective name of the driver, such as saa7110.c , {driver_name} 
-= saa7110.
-
--------------------------------------------------------
-
-Step 1: Include the right header file
- 
-Perform the following change within the driver
- 
-#include <linux/i2c-old.h> --> #include <linux/i2c.h>
-
-Step 2: Add and set the i2c modes
-
-Add the following code near the top of the driver
-
-static unsigned short normal_i2c[] = {34>>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 struct i2c_client_address_data addr_data  = {
-	normal_i2c , normal_i2c_range,
-	probe , probe_range,
-	ignore , ignore_range,
-	force
-};
-
-static struct i2c_client client_template;
-
-Step 3: Modify the driver info struct
-
-Within the struct for the driver , such as struct {driver_name}  ,  make the 
-following change ,
-struct i2c_bus *bus --> struct i2c_client *client
-
-Make changes where this change affects references within the file.
-
-Add a semaphore to the driver struct (as above)
-
-struct semaphore lock 
-
-Step 5: Remove specific read and write functions
-
-Remove the driver specific write and read functions, usually in the form:
-{driver_name}_write , {driver_name}_read , {driver_name}_write_block , etc.
-
-Step 6: Update the write and read functions for the current I2C API
-
-Replace all references of {driver_name}_write with i2c_smbus_write_byte_data
-Replace all references of {driver_name}_read with i2c_smbus_read_byte_data or
-i2c_smbus_read_byte , depending on args passed in.
-
-** Ensure that these functions pass in the i2c_client *client , NOT the
-decoder/encoder that was passed in the driver specific write and read
-functions. 
- 
-Step 7: Modify the driver's attach function
-
-Change the driver attach function prototype :
-{driver_name}_attach(struct i2c_device *device) --> {driver_name}_attach(struct 
-i2c_adapter *adap, int addr , unsigned short flags, int kind)
-
-Create a i2c_client client...
-Add the following (where "decoder" is a reference to a struct for the driver
-info:
-
-struct i2c_client *client;
-client = kmalloc(sizeof(*client), GFP_KERNEL);
-if(client == NULL)
-	return -ENOMEM;
-client_template.adapter = adap;
-client_template.addr  = addr;
-memcpy(client, &client_template, sizeof(*client));
-strcpy(client->name , "{driver_name}");
-decoder->client = client;
-client->data = decoder;
-decoder->addr = addr;
-
-Towards the end of the function, add:
-
-init_MUTEX(&decoder->lock);
-i2c_attach_client(client);
-
-
-Step 8: Modify the driver's detach function
-
-Change the driver detach function prototype :
-{driver_name}_detach(struct i2c_device *device) --> {driver_name}_detach(struct 
-i2c_client *client)
-
-In the beginning of the detach function, add:
-i2c_detach_client(client);
-
-Towards the end of the detach function, add:
-kfree(client->data);
-kfree(client);
-
-Step 9: Modify the driver's command function
-
-Change the driver command function prototype :
-
-Step 10: Add the probe function after the driver's attach function.
-
-Add the following code:
-
-static int {driver_name}_probe(struct i2c_adapter *adap)
-{
-	return i2c_probe(adap, &addr_data, {driver_name}_attach);
-
-}
-
-Step 11: Modify the driver's i2c_driver
-
-Find the i2c_driver , such as
-static struct i2c_driver i2c_driver_saa7110
-It is usually located towards the end of the driver 
-Replace the values from I2C_DRIVERID_{something} to {driver_name}_attach, and 
-add the following
-I2C_DRIVERID_{driver_name} , // verify by looking in include/linux/i2c-id.h 
-I2C_DF_NOTIFY,
-{driver_name}_probe, 
-....
-
-Step 12: Adding the i2c_client 
-
-Add the i2c_client to the driver. Add the following code:
-
-static struct i2c_client client_template = {
-	"{driver_name}_client",
-	-1,
-	0,
-	0,
-	NULL,
-	{i2c_driver reference}
-};
-
-Step 13: Registering and Unregistering
-
-Replace i2c_register_driver with i2c_add_driver
-Replace i2c_unregister_driver with i2c_del_driver
-
--------------------------------------------------------
-
-Example:
-
-The following patch provides the i2c coversion patch for the saa7110 driver
-based on the above guide (for clarity).
-
-
---- drivers/media/video/saa7110.c.old	Fri Jun 28 10:22:52 2002
-+++ drivers/media/video/saa7110.c	Thu Jul  4 16:51:08 2002
-@@ -26,7 +26,7 @@
- #include <asm/io.h>
- #include <asm/uaccess.h>
- 
--#include <linux/i2c-old.h>
-+#include <linux/i2c.h>
- #include <linux/videodev.h>
- #include "linux/video_decoder.h"
- 
-@@ -37,13 +37,31 @@
- 
- #define	I2C_SAA7110		0x9C	/* or 0x9E */
- 
-+#define IF_NAME	"saa7110"
- #define	I2C_DELAY		10	/* 10 us or 100khz */
- 
-+static unsigned short normal_i2c[] = {34>>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 struct i2c_client_address_data addr_data = {
-+	normal_i2c, normal_i2c_range,
-+	probe, probe_range,
-+	ignore, ignore_range,
-+	force
-+};
-+
-+static struct i2c_client client_template;
-+
- struct saa7110 {
--	struct	i2c_bus	*bus;
-+	struct i2c_client *client;
- 	int		addr;
- 	unsigned char	reg[36];
--
-+	struct semaphore lock;
- 	int		norm;
- 	int		input;
- 	int		enable;
-@@ -54,67 +72,10 @@
- };
- 
- /* ----------------------------------------------------------------------- */
--/* I2C support functions						   */
--/* ----------------------------------------------------------------------- */
--static
--int saa7110_write(struct saa7110 *decoder, unsigned char subaddr, unsigned char data)
--{
--	int ack;
--
--	LOCK_I2C_BUS(decoder->bus);
--	i2c_start(decoder->bus);
--	i2c_sendbyte(decoder->bus, decoder->addr, I2C_DELAY);
--	i2c_sendbyte(decoder->bus, subaddr, I2C_DELAY);
--	ack = i2c_sendbyte(decoder->bus, data, I2C_DELAY);
--	i2c_stop(decoder->bus);
--	decoder->reg[subaddr] = data;
--	UNLOCK_I2C_BUS(decoder->bus);
--	return ack;
--}
--
--static
--int saa7110_write_block(struct saa7110* decoder, unsigned const char *data, unsigned int len)
--{
--	unsigned subaddr = *data;
--
--	LOCK_I2C_BUS(decoder->bus);
--        i2c_start(decoder->bus);
--        i2c_sendbyte(decoder->bus,decoder->addr,I2C_DELAY);
--	while (len-- > 0) {
--                if (i2c_sendbyte(decoder->bus,*data,0)) {
--                        i2c_stop(decoder->bus);
--                        UNLOCK_I2C_BUS(decoder->bus);
--                        return -EAGAIN;
--                }
--		decoder->reg[subaddr++] = *data++;
--        }
--	i2c_stop(decoder->bus);
--	UNLOCK_I2C_BUS(decoder->bus);
--
--	return 0;
--}
--
--static
--int saa7110_read(struct saa7110* decoder)
--{
--	int data;
--
--	LOCK_I2C_BUS(decoder->bus);
--	i2c_start(decoder->bus);
--	i2c_sendbyte(decoder->bus, decoder->addr, I2C_DELAY);
--	i2c_start(decoder->bus);
--	i2c_sendbyte(decoder->bus, decoder->addr | 1, I2C_DELAY);
--	data = i2c_readbyte(decoder->bus, 1);
--	i2c_stop(decoder->bus);
--	UNLOCK_I2C_BUS(decoder->bus);
--	return data;
--}
--
--/* ----------------------------------------------------------------------- */
- /* SAA7110 functions							   */
- /* ----------------------------------------------------------------------- */
- static
--int saa7110_selmux(struct i2c_device *device, int chan)
-+int saa7110_selmux(struct i2c_client *client, int chan)
- {
- static	const unsigned char modes[9][8] = {
- /* mode 0 */	{ 0x00, 0xD9, 0x17, 0x40, 0x03, 0x44, 0x75, 0x16 },
-@@ -126,61 +87,59 @@
- /* mode 6 */	{ 0x80, 0x59, 0x17, 0x42, 0xA3, 0x44, 0x75, 0x12 },
- /* mode 7 */	{ 0x80, 0x9A, 0x17, 0xB1, 0x13, 0x60, 0xB5, 0x14 },
- /* mode 8 */	{ 0x80, 0x3C, 0x27, 0xC1, 0x23, 0x44, 0x75, 0x21 } };
--	struct saa7110* decoder = device->data;
- 	const unsigned char* ptr = modes[chan];
- 
--	saa7110_write(decoder,0x06,ptr[0]);	/* Luminance control	*/
--	saa7110_write(decoder,0x20,ptr[1]);	/* Analog Control #1	*/
--	saa7110_write(decoder,0x21,ptr[2]);	/* Analog Control #2	*/
--	saa7110_write(decoder,0x22,ptr[3]);	/* Mixer Control #1	*/
--	saa7110_write(decoder,0x2C,ptr[4]);	/* Mixer Control #2	*/
--	saa7110_write(decoder,0x30,ptr[5]);	/* ADCs gain control	*/
--	saa7110_write(decoder,0x31,ptr[6]);	/* Mixer Control #3	*/
--	saa7110_write(decoder,0x21,ptr[7]);	/* Analog Control #2	*/
-+	i2c_smbus_write_byte_data(client,0x06,ptr[0]);	/* Luminance control	*/
-+	i2c_smbus_write_byte_data(client,0x20,ptr[1]);	/* Analog Control #1	*/
-+	i2c_smbus_write_byte_data(client,0x21,ptr[2]);	/* Analog Control #2	*/
-+	i2c_smbus_write_byte_data(client,0x22,ptr[3]);	/* Mixer Control #1	*/
-+	i2c_smbus_write_byte_data(client,0x2C,ptr[4]);	/* Mixer Control #2	*/
-+	i2c_smbus_write_byte_data(client,0x30,ptr[5]);	/* ADCs gain control	*/
-+	i2c_smbus_write_byte_data(client,0x31,ptr[6]);	/* Mixer Control #3	*/
-+	i2c_smbus_write_byte_data(client,0x21,ptr[7]);	/* Analog Control #2	*/
- 
- 	return 0;
- }
- 
- static
--int determine_norm(struct i2c_device* dev)
-+int determine_norm(struct i2c_client* client)
- {
--	struct	saa7110* decoder = dev->data;
- 	int	status;
- 
- 	/* mode changed, start automatic detection */
--	status = saa7110_read(decoder);
-+	status = i2c_smbus_read_byte(client);
- 	if ((status & 3) == 0) {
--		saa7110_write(decoder,0x06,0x80);
-+		i2c_smbus_write_byte_data(client,0x06,0x80);
- 		if (status & 0x20) {
--			DEBUG(printk(KERN_INFO "%s: norm=bw60\n",dev->name));
--			saa7110_write(decoder,0x2E,0x81);
-+			DEBUG(printk(KERN_INFO "%s: norm=bw60\n",adp->name));
-+			i2c_smbus_write_byte_data(client,0x2E,0x81);
- 			return VIDEO_MODE_NTSC;
- 		}
--		DEBUG(printk(KERN_INFO "%s: norm=bw50\n",dev->name));
--		saa7110_write(decoder,0x2E,0x9A);
-+		DEBUG(printk(KERN_INFO "%s: norm=bw50\n",adp->name));
-+		i2c_smbus_write_byte_data(client,0x2E,0x9A);
- 		return VIDEO_MODE_PAL;
- 	}
- 
--	saa7110_write(decoder,0x06,0x00);
-+	i2c_smbus_write_byte_data(client,0x06,0x00);
- 	if (status & 0x20) {	/* 60Hz */
--		DEBUG(printk(KERN_INFO "%s: norm=ntsc\n",dev->name));
--		saa7110_write(decoder,0x0D,0x06);
--		saa7110_write(decoder,0x11,0x2C);
--		saa7110_write(decoder,0x2E,0x81);
-+		DEBUG(printk(KERN_INFO "%s: norm=ntsc\n",adp->name));
-+		i2c_smbus_write_byte_data(client,0x0D,0x06);
-+		i2c_smbus_write_byte_data(client,0x11,0x2C);
-+		i2c_smbus_write_byte_data(client,0x2E,0x81);
- 		return VIDEO_MODE_NTSC;
- 	}
- 
- 	/* 50Hz -> PAL/SECAM */
--	saa7110_write(decoder,0x0D,0x06);
--	saa7110_write(decoder,0x11,0x59);
--	saa7110_write(decoder,0x2E,0x9A);
-+	i2c_smbus_write_byte_data(client,0x0D,0x06);
-+	i2c_smbus_write_byte_data(client,0x11,0x59);
-+	i2c_smbus_write_byte_data(client,0x2E,0x9A);
- 
- 	mdelay(150);	/* pause 150 ms */
- 
--	status = saa7110_read(decoder);
-+	status = i2c_smbus_read_byte(client);
- 	if ((status & 0x03) == 0x01) {
- 		DEBUG(printk(KERN_INFO "%s: norm=secam\n",dev->name));
--		saa7110_write(decoder,0x0D,0x07);
-+		i2c_smbus_write_byte_data(client,0x0D,0x07);
- 		return VIDEO_MODE_SECAM;
- 	}
- 	DEBUG(printk(KERN_INFO "%s: norm=pal\n",dev->name));
-@@ -188,7 +147,7 @@
- }
- 
- static
--int saa7110_attach(struct i2c_device *device)
-+int saa7110_attach(struct i2c_adapter *adap, int  addr, unsigned short flags, int kind)
- {
- static	const unsigned char initseq[] = {
- 	     0, 0x4C, 0x3C, 0x0D, 0xEF, 0xBD, 0xF0, 0x00, 0x00,
-@@ -198,20 +157,28 @@
- 		0xD9, 0x17, 0x40, 0x41, 0x80, 0x41, 0x80, 0x4F,
- 		0xFE, 0x01, 0xCF, 0x0F, 0x03, 0x01, 0x81, 0x03,
- 		0x40, 0x75, 0x01, 0x8C, 0x03};
--	struct	saa7110*	decoder;
-+	struct	saa7110	*decoder;
-+	struct i2c_client *client;
- 	int			rv;
--
--	device->data = decoder = kmalloc(sizeof(struct saa7110), GFP_KERNEL);
--	if (device->data == 0)
-+	client=kmalloc(sizeof(*client), GFP_KERNEL);
-+	if(client == NULL) 
- 		return -ENOMEM;
--
-+	client_template.adapter = adap;
-+	client_template.addr = addr;
-+	memcpy(client, &client_template, sizeof(*client));
-+
-+	decoder = kmalloc(sizeof(*decoder), GFP_KERNEL);
-+	if (decoder == NULL) {
-+		kfree(client);
-+		return -ENOMEM;
-+		}
- 
- 	/* clear our private data */
--	memset(decoder, 0, sizeof(struct saa7110));
--	strcpy(device->name, "saa7110");
--	decoder->bus = device->bus;
--	decoder->addr = device->addr;
-+	memset(decoder, 0, sizeof(*decoder));
-+	strcpy(client->name, IF_NAME);
-+	decoder->client = client;
-+	client->data = decoder;
-+	decoder->addr = addr;
- 	decoder->norm = VIDEO_MODE_PAL;
- 	decoder->input = 0;
- 	decoder->enable = 1;
-@@ -220,40 +187,52 @@
- 	decoder->hue = 32768;
- 	decoder->sat = 32768;
- 
--	rv = saa7110_write_block(decoder, initseq, sizeof(initseq));
-+	rv = i2c_master_send(client, initseq, sizeof(initseq));
- 	if (rv < 0)
--		printk(KERN_ERR "%s_attach: init status %d\n", device->name, rv);
-+		printk(KERN_ERR "%s_attach: init status %d\n", client->name, rv);
- 	else {
--		saa7110_write(decoder,0x21,0x16);
--		saa7110_write(decoder,0x0D,0x04);
--		DEBUG(printk(KERN_INFO "%s_attach: chip version %x\n", device->name, saa7110_read(decoder)));
--		saa7110_write(decoder,0x0D,0x06);
-+		i2c_smbus_write_byte_data(client,0x21,0x16);
-+		i2c_smbus_write_byte_data(client,0x0D,0x04);
-+		DEBUG(printk(KERN_INFO "%s_attach: chip version %x\n", client->name, i2c_smbus_read_byte(client)));
-+		i2c_smbus_write_byte_data(client,0x0D,0x06);
- 	}
- 
-+	init_MUTEX(&decoder->lock);
-+	i2c_attach_client(client);
- 	/* setup and implicit mode 0 select has been performed */
- 	return 0;
- }
- 
-+static 
-+int saa7110_probe(struct i2c_adapter *adap) 
-+{
-+	return i2c_probe(adap, &addr_data, saa7110_attach);
-+}
-+
- static
--int saa7110_detach(struct i2c_device *device)
-+int saa7110_detach(struct i2c_client *client)
- {
--	struct saa7110* decoder = device->data;
-+	struct saa7110* decoder = client->data;
- 
--	DEBUG(printk(KERN_INFO "%s_detach\n",device->name));
-+	i2c_detach_client(client);
-+
-+	DEBUG(printk(KERN_INFO "%s_detach\n",client->name));
- 
- 	/* stop further output */
--	saa7110_write(decoder,0x0E,0x00);
-+	i2c_smbus_write_byte_data(client,0x0E,0x00);
- 
--	kfree(device->data);
-+	kfree(decoder);
-+	kfree(client);
- 
- 	return 0;
- }
- 
- static
--int saa7110_command(struct i2c_device *device, unsigned int cmd, void *arg)
-+int saa7110_command(struct i2c_client *client, unsigned int cmd, void *arg)
- {
--	struct saa7110* decoder = device->data;
-+	struct saa7110* decoder = client->data;
- 	int	v;
- 
- 	switch (cmd) {
-@@ -272,11 +251,11 @@
- 
- 	 case DECODER_GET_STATUS:
- 		{
--			struct saa7110* decoder = device->data;
-+			struct saa7110* decoder = client->data;
- 			int status;
- 			int res = 0;
- 
--			status = i2c_read(device->bus,device->addr|1);
-+			status = i2c_smbus_read_byte(client);
- 			if (status & 0x40)
- 				res |= DECODER_STATUS_GOOD;
- 			if (status & 0x03)
-@@ -301,26 +280,26 @@
- 		v = *(int*)arg;
- 		if (decoder->norm != v) {
- 			decoder->norm = v;
--			saa7110_write(decoder, 0x06, 0x00);
-+			i2c_smbus_write_byte_data(client, 0x06, 0x00);
- 			switch (v) {
- 			 case VIDEO_MODE_NTSC:
--				saa7110_write(decoder, 0x0D, 0x06);
--				saa7110_write(decoder, 0x11, 0x2C);
--				saa7110_write(decoder, 0x30, 0x81);
--				saa7110_write(decoder, 0x2A, 0xDF);
-+				i2c_smbus_write_byte_data(client, 0x0D, 0x06);
-+				i2c_smbus_write_byte_data(client, 0x11, 0x2C);
-+				i2c_smbus_write_byte_data(client, 0x30, 0x81);
-+				i2c_smbus_write_byte_data(client, 0x2A, 0xDF);
- 				break;
- 			 case VIDEO_MODE_PAL:
--				saa7110_write(decoder, 0x0D, 0x06);
--				saa7110_write(decoder, 0x11, 0x59);
--				saa7110_write(decoder, 0x2E, 0x9A);
-+				i2c_smbus_write_byte_data(client, 0x0D, 0x06);
-+				i2c_smbus_write_byte_data(client, 0x11, 0x59);
-+				i2c_smbus_write_byte_data(client, 0x2E, 0x9A);
- 				break;
- 			 case VIDEO_MODE_SECAM:
--				saa7110_write(decoder, 0x0D, 0x07);
--				saa7110_write(decoder, 0x11, 0x59);
--				saa7110_write(decoder, 0x2E, 0x9A);
-+				i2c_smbus_write_byte_data(client, 0x0D, 0x07);
-+				i2c_smbus_write_byte_data(client, 0x11, 0x59);
-+				i2c_smbus_write_byte_data(client, 0x2E, 0x9A);
- 				break;
- 			 case VIDEO_MODE_AUTO:
--				*(int*)arg = determine_norm(device);
-+				*(int*)arg = determine_norm(client);
- 				break;
- 			 default:
- 				return -EPERM;
-@@ -334,7 +313,7 @@
- 			return -EINVAL;
- 		if (decoder->input != v) {
- 			decoder->input = v;
--			saa7110_selmux(device, v);
-+			saa7110_selmux(client, v);
- 		}
- 		break;
- 
-@@ -349,7 +328,7 @@
- 		v = *(int*)arg;
- 		if (decoder->enable != v) {
- 			decoder->enable = v;
--			saa7110_write(decoder,0x0E, v ? 0x18 : 0x00);
-+			i2c_smbus_write_byte_data(client,0x0E, v ? 0x18 : 0x00);
- 		}
- 		break;
- 
-@@ -360,22 +339,22 @@
- 			if (decoder->bright != pic->brightness) {
- 				/* We want 0 to 255 we get 0-65535 */
- 				decoder->bright = pic->brightness;
--				saa7110_write(decoder, 0x19, decoder->bright >> 8);
-+				i2c_smbus_write_byte_data(client, 0x19, decoder->bright >> 8);
- 			}
- 			if (decoder->contrast != pic->contrast) {
- 				/* We want 0 to 127 we get 0-65535 */
- 				decoder->contrast = pic->contrast;
--				saa7110_write(decoder, 0x13, decoder->contrast >> 9);
-+				i2c_smbus_write_byte_data(client, 0x13, decoder->contrast >> 9);
- 			}
- 			if (decoder->sat != pic->colour) {
- 				/* We want 0 to 127 we get 0-65535 */
- 				decoder->sat = pic->colour;
--				saa7110_write(decoder, 0x12, decoder->sat >> 9);
-+				i2c_smbus_write_byte_data(client, 0x12, decoder->sat >> 9);
- 			}
- 			if (decoder->hue != pic->hue) {
- 				/* We want -128 to 127 we get 0-65535 */
- 				decoder->hue = pic->hue;
--				saa7110_write(decoder, 0x07, (decoder->hue>>8)-128);
-+				i2c_smbus_write_byte_data(client, 0x07, (decoder->hue>>8)-128);
- 			}
- 		}
- 		break;
-@@ -383,7 +362,7 @@
- 	 case DECODER_DUMP:
- 		for (v=0; v<34; v+=16) {
- 			int j;
--			DEBUG(printk(KERN_INFO "%s: %03x\n",device->name,v));
-+			DEBUG(printk(KERN_INFO "%s: %03x\n",client->name,v));
- 			for (j=0; j<16; j++) {
- 				DEBUG(printk(KERN_INFO " %02x",decoder->reg[v+j]));
- 			}
-@@ -402,24 +381,30 @@
- 
- static struct i2c_driver i2c_driver_saa7110 =
- {
--	"saa7110",			/* name */
--
--	I2C_DRIVERID_VIDEODECODER,	/* in i2c.h */
--	I2C_SAA7110, I2C_SAA7110+1,	/* Addr range */
--
--	saa7110_attach,
--	saa7110_detach,
--	saa7110_command
-+	.owner		= THIS_MODULE,
-+	.name		= IF_NAME,
-+	.id		= I2C_DRIVERID_SAA7110,
-+	.flags		= I2C_DF_NOTIFY,
-+	.attach_adapter	= saa7110_probe,
-+	.detach_adapter	= saa7110_detach,
-+	.command	= saa7110_command,
- };
-+static struct i2c_client client_template = {
-+	"saa7110_client",
-+	-1,
-+	0,
-+	0,
-+	NULL,
-+	&i2c_driver_saa7110
-+};
- 
- static int saa7110_init(void)
- {
--	return i2c_register_driver(&i2c_driver_saa7110);
-+	return i2c_add_driver(&i2c_driver_saa7110);
- }
- 
- static void saa7110_exit(void)
- {
--	i2c_unregister_driver(&i2c_driver_saa7110);
-+	i2c_del_driver(&i2c_driver_saa7110);
- }
- 
- 
- 
-
diff -Nru a/Documentation/i2c/i2c-stub b/Documentation/i2c/i2c-stub
--- a/Documentation/i2c/i2c-stub	2005-03-01 23:39:18 -08:00
+++ b/Documentation/i2c/i2c-stub	2005-03-01 23:39:18 -08:00
@@ -2,13 +2,18 @@
 
 DESCRIPTION:
 
-This module is a very simple fake I2C/SMBus driver.  It implements three
-types of SMBus commands: write quick, (r/w) byte data, and (r/w) word data.
+This module is a very simple fake I2C/SMBus driver.  It implements four
+types of SMBus commands: write quick, (r/w) byte, (r/w) byte data, and
+(r/w) word data.
 
 No hardware is needed nor associated with this module.  It will accept write
 quick commands to all addresses; it will respond to the other commands (also
 to all addresses) by reading from or writing to an array in memory.  It will
 also spam the kernel logs for every command it handles.
+
+A pointer register with auto-increment is implemented for all byte
+operations.  This allows for continuous byte reads like those supported by
+EEPROMs, among others.
 
 The typical use-case is like this:
 	1. load this module
diff -Nru a/Documentation/i386/boot.txt b/Documentation/i386/boot.txt
--- a/Documentation/i386/boot.txt	2005-03-01 23:39:07 -08:00
+++ b/Documentation/i386/boot.txt	2005-03-01 23:39:07 -08:00
@@ -173,6 +173,9 @@
 	2  bootsect-loader
 	3  SYSLINUX
 	4  EtherBoot
+	5  ELILO
+	7  GRuB
+	8  U-BOOT
 
 	Please contact <hpa@zytor.com> if you need a bootloader ID
 	value assigned.
diff -Nru a/Documentation/i386/zero-page.txt b/Documentation/i386/zero-page.txt
--- a/Documentation/i386/zero-page.txt	2005-03-01 23:38:55 -08:00
+++ b/Documentation/i386/zero-page.txt	2005-03-01 23:38:55 -08:00
@@ -74,6 +74,10 @@
 0x21c	unsigned long	INITRD_SIZE, size in bytes of ramdisk image
 0x220	4 bytes		(setup.S)
 0x224	unsigned short	setup.S heap end pointer
+0x226   unsigned short	zero_pad
+0x228   unsigned long	cmd_line_ptr
+0x22c   unsigned long	ramdisk_max
+0x230   16 bytes 	trampoline
 0x290 - 0x2cf		EDD_MBR_SIG_BUFFER (edd.S)
 0x2d0 - 0x600		E820MAP
 0x600 - 0x7ff		EDDBUF (edd.S) for disk signature read sector
diff -Nru a/Documentation/ide.txt b/Documentation/ide.txt
--- a/Documentation/ide.txt	2005-03-01 23:39:07 -08:00
+++ b/Documentation/ide.txt	2005-03-01 23:39:07 -08:00
@@ -297,6 +297,8 @@
 
  "ide=reverse"		: formerly called to pci sub-system, but now local.
 
+ "ide=nodma"		: disable DMA globally for the IDE subsystem.
+
 The following are valid ONLY on ide0, which usually corresponds
 to the first ATA interface found on the particular host, and the defaults for
 the base,ctl ports must not be altered.
diff -Nru a/Documentation/infiniband/ipoib.txt b/Documentation/infiniband/ipoib.txt
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/Documentation/infiniband/ipoib.txt	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,56 @@
+IP OVER INFINIBAND
+
+  The ib_ipoib driver is an implementation of the IP over InfiniBand
+  protocol as specified by the latest Internet-Drafts issued by the
+  IETF ipoib working group.  It is a "native" implementation in the
+  sense of setting the interface type to ARPHRD_INFINIBAND and the
+  hardware address length to 20 (earlier proprietary implementations
+  masqueraded to the kernel as ethernet interfaces).
+
+Partitions and P_Keys
+
+  When the IPoIB driver is loaded, it creates one interface for each
+  port using the P_Key at index 0.  To create an interface with a
+  different P_Key, write the desired P_Key into the main interface's
+  /sys/class/net/<intf name>/create_child file.  For example:
+
+    echo 0x8001 > /sys/class/net/ib0/create_child
+
+  This will create an interface named ib0.8001 with P_Key 0x8001.  To
+  remove a subinterface, use the "delete_child" file:
+
+    echo 0x8001 > /sys/class/net/ib0/delete_child
+
+  The P_Key for any interface is given by the "pkey" file, and the
+  main interface for a subinterface is in "parent."
+
+Debugging Information
+
+  By compiling the IPoIB driver with CONFIG_INFINIBAND_IPOIB_DEBUG set
+  to 'y', tracing messages are compiled into the driver.  They are
+  turned on by setting the module parameters debug_level and
+  mcast_debug_level to 1.  These parameters can be controlled at
+  runtime through files in /sys/module/ib_ipoib/.
+
+  CONFIG_INFINIBAND_IPOIB_DEBUG also enables the "ipoib_debugfs"
+  virtual filesystem.  By mounting this filesystem, for example with
+
+    mkdir -p /ipoib_debugfs
+    mount -t ipoib_debugfs none /ipoib_debufs
+
+  it is possible to get statistics about multicast groups from the
+  files /ipoib_debugfs/ib0_mcg and so on.
+
+  The performance impact of this option is negligible, so it
+  is safe to enable this option with debug_level set to 0 for normal
+  operation.
+
+  CONFIG_INFINIBAND_IPOIB_DEBUG_DATA enables even more debug output in
+  the data path when data_debug_level is set to 1.  However, even with
+  the output disabled, enabling this configuration option will affect
+  performance, because it adds tests to the fast path.
+
+References
+
+  IETF IP over InfiniBand (ipoib) Working Group
+    http://ietf.org/html.charters/ipoib-charter.html
diff -Nru a/Documentation/infiniband/sysfs.txt b/Documentation/infiniband/sysfs.txt
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/Documentation/infiniband/sysfs.txt	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,66 @@
+SYSFS FILES
+
+  For each InfiniBand device, the InfiniBand drivers create the
+  following files under /sys/class/infiniband/<device name>:
+
+    node_type      - Node type (CA, switch or router)
+    node_guid      - Node GUID
+    sys_image_guid - System image GUID
+
+  In addition, there is a "ports" subdirectory, with one subdirectory
+  for each port.  For example, if mthca0 is a 2-port HCA, there will
+  be two directories:
+
+    /sys/class/infiniband/mthca0/ports/1
+    /sys/class/infiniband/mthca0/ports/2
+
+  (A switch will only have a single "0" subdirectory for switch port
+  0; no subdirectory is created for normal switch ports)
+
+  In each port subdirectory, the following files are created:
+
+    cap_mask       - Port capability mask
+    lid            - Port LID
+    lid_mask_count - Port LID mask count
+    rate           - Port data rate (active width * active speed)
+    sm_lid         - Subnet manager LID for port's subnet
+    sm_sl          - Subnet manager SL for port's subnet
+    state          - Port state (DOWN, INIT, ARMED, ACTIVE or ACTIVE_DEFER)
+    phys_state     - Port physical state (Sleep, Polling, LinkUp, etc)
+
+  There is also a "counters" subdirectory, with files
+
+    VL15_dropped
+    excessive_buffer_overrun_errors
+    link_downed
+    link_error_recovery
+    local_link_integrity_errors
+    port_rcv_constraint_errors
+    port_rcv_data
+    port_rcv_errors
+    port_rcv_packets
+    port_rcv_remote_physical_errors
+    port_rcv_switch_relay_errors
+    port_xmit_constraint_errors
+    port_xmit_data
+    port_xmit_discards
+    port_xmit_packets
+    symbol_error
+
+  Each of these files contains the corresponding value from the port's
+  Performance Management PortCounters attribute, as described in
+  section 16.1.3.5 of the InfiniBand Architecture Specification.
+
+  The "pkeys" and "gids" subdirectories contain one file for each
+  entry in the port's P_Key or GID table respectively.  For example,
+  ports/1/pkeys/10 contains the value at index 10 in port 1's P_Key
+  table.
+
+MTHCA
+
+  The Mellanox HCA driver also creates the files:
+
+    hw_rev   - Hardware revision number
+    fw_ver   - Firmware version
+    hca_type - HCA type: "MT23108", "MT25208 (MT23108 compat mode)",
+               or "MT25208"
diff -Nru a/Documentation/infiniband/user_mad.txt b/Documentation/infiniband/user_mad.txt
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/Documentation/infiniband/user_mad.txt	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,99 @@
+USERSPACE MAD ACCESS
+
+Device files
+
+  Each port of each InfiniBand device has a "umad" device and an
+  "issm" device attached.  For example, a two-port HCA will have two
+  umad devices and two issm devices, while a switch will have one
+  device of each type (for switch port 0).
+
+Creating MAD agents
+
+  A MAD agent can be created by filling in a struct ib_user_mad_reg_req
+  and then calling the IB_USER_MAD_REGISTER_AGENT ioctl on a file
+  descriptor for the appropriate device file.  If the registration
+  request succeeds, a 32-bit id will be returned in the structure.
+  For example:
+
+	struct ib_user_mad_reg_req req = { /* ... */ };
+	ret = ioctl(fd, IB_USER_MAD_REGISTER_AGENT, (char *) &req);
+        if (!ret)
+		my_agent = req.id;
+	else
+		perror("agent register");
+
+  Agents can be unregistered with the IB_USER_MAD_UNREGISTER_AGENT
+  ioctl.  Also, all agents registered through a file descriptor will
+  be unregistered when the descriptor is closed.
+
+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:
+
+	struct ib_user_mad mad;
+	ret = read(fd, &mad, sizeof mad);
+	if (ret != sizeof mad)
+		perror("read");
+
+  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
+  example, the remote LID will be in mad.lid.
+
+  If a send times out, a receive will be generated with mad.status set
+  to ETIMEDOUT.  Otherwise when a MAD has been successfully received,
+  mad.status will be 0.
+
+  poll()/select() may be used to wait until a MAD can be read.
+
+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:
+
+	struct ib_user_mad mad;
+
+	/* fill in mad.data */
+
+	mad.id  = my_agent;	/* req.id from agent registration */
+	mad.lid = my_dest;	/* in network byte order... */
+	/* etc. */
+
+	ret = write(fd, &mad, sizeof mad);
+	if (ret != sizeof mad)
+		perror("write");
+
+Setting IsSM Capability Bit
+
+  To set the IsSM capability bit for a port, simply open the
+  corresponding issm device file.  If the IsSM bit is already set,
+  then the open call will block until the bit is cleared (or return
+  immediately with errno set to EAGAIN if the O_NONBLOCK flag is
+  passed to open()).  The IsSM bit will be cleared when the issm file
+  is closed.  No read, write or other operations can be performed on
+  the issm file.
+
+/dev files
+
+  To create the appropriate character device files automatically with
+  udev, a rule like
+
+    KERNEL="umad*", NAME="infiniband/%k"
+    KERNEL="issm*", NAME="infiniband/%k"
+
+  can be used.  This will create device nodes named
+
+    /dev/infiniband/umad0
+    /dev/infiniband/issm0
+
+  for the first port, and so on.  The InfiniBand device and port
+  associated with these devices can be determined from the files
+
+    /sys/class/infiniband_mad/umad0/ibdev
+    /sys/class/infiniband_mad/umad0/port
+
+  and
+
+    /sys/class/infiniband_mad/issm0/ibdev
+    /sys/class/infiniband_mad/issm0/port
diff -Nru a/Documentation/ioctl-number.txt b/Documentation/ioctl-number.txt
--- a/Documentation/ioctl-number.txt	2005-03-01 23:39:16 -08:00
+++ b/Documentation/ioctl-number.txt	2005-03-01 23:39:16 -08:00
@@ -72,6 +72,7 @@
 0x09	all	linux/md.h
 0x12	all	linux/fs.h
 		linux/blkpg.h
+0x1b	all	InfiniBand Subsystem	<http://www.openib.org/>
 0x20	all	drivers/cdrom/cm206.h
 0x22	all	scsi/sg.h
 '#'	00-3F	IEEE 1394 Subsystem	Block for the entire subsystem
@@ -145,7 +146,7 @@
 'p'	40-7F	linux/nvram.h
 'p'	80-9F				user-space parport
 					<mailto:tim@cyberelk.net>
-'q'	00-1F	linux/videotext.h	conflict!
+'q'	00-1F	linux/serio.h
 'q'	80-FF				Internet PhoneJACK, Internet LineJACK
 					<http://www.quicknet.net>
 'r'	00-1F	linux/msdos_fs.h
@@ -163,6 +164,7 @@
 'z'	40-7F				CAN bus card
 					<mailto:oe@port.de>
 0x80	00-1F	linux/fb.h
+0x81	00-1F	linux/videotext.h
 0x89	00-06	asm-i386/sockios.h
 0x89	0B-DF	linux/sockios.h
 0x89	E0-EF	linux/sockios.h		SIOCPROTOPRIVATE range
diff -Nru a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
--- a/Documentation/kernel-parameters.txt	2005-03-01 23:39:18 -08:00
+++ b/Documentation/kernel-parameters.txt	2005-03-01 23:39:18 -08:00
@@ -29,6 +29,7 @@
 	CD	Appropriate CD support is enabled.
 	DEVFS	devfs support is enabled. 
 	DRM	Direct Rendering Management support is enabled. 
+	EDD	BIOS Enhanced Disk Drive Services (EDD) is enabled
 	EFI	EFI Partitioning (GPT) is enabled
 	EIDE	EIDE/ATAPI support is enabled.
 	FB	The frame buffer device is enabled.
@@ -50,6 +51,7 @@
 	MOUSE	Appropriate mouse support is enabled.
 	MTD	MTD support is enabled.
 	NET	Appropriate network support is enabled.
+	NUMA	NUMA support is enabled.
 	NFS	Appropriate NFS support is enabled.
 	OSS	OSS sound support is enabled.
 	PARIDE	The ParIDE subsystem is enabled.
@@ -150,6 +152,8 @@
 			debugging. After system has booted up, it can be set
 			via /proc/acpi/debug_level.
 
+	acpi_fake_ecdt	[HW,ACPI] Workaround failure due to BIOS lacking ECDT
+
 	ad1816=		[HW,OSS]
 			Format: <io>,<irq>,<dma>,<dma2>
 			See also Documentation/sound/oss/AD1816.
@@ -222,15 +226,19 @@
 
 	atascsi=	[HW,SCSI] Atari SCSI
 
-	atkbd.extra=	[HW] Enable extra LEDs and keys on IBM RapidAccess, EzKey
-			and similar keyboards
+	atkbd.extra=	[HW] Enable extra LEDs and keys on IBM RapidAccess,
+			EzKey and similar keyboards
 
 	atkbd.reset=	[HW] Reset keyboard during initialization
 
 	atkbd.set=	[HW] Select keyboard code set 
 			Format: <int> (2 = AT (default) 3 = PS/2)
 
-	atkbd.scroll=	[HW] Enable scroll wheel on MS Office and similar keyboards
+	atkbd.scroll=	[HW] Enable scroll wheel on MS Office and similar
+			keyboards
+
+	atkbd.softraw=	[HW] Choose between synthetic and real raw mode
+			Format: <bool> (0 = real, 1 = synthetic (default))
 	
 	atkbd.softrepeat=
 			[HW] Use software keyboard repeat
@@ -408,6 +416,10 @@
 
 	edb=		[HW,PS2]
 
+	edd=		[EDD]
+			Format: {"of[f]" | "sk[ipmbr]"}
+			See comment in arch/i386/boot/edd.S
+
 	eicon=		[HW,ISDN] 
 			Format: <id>,<membase>,<irq>
 
@@ -474,6 +486,10 @@
  
 	gvp11=		[HW,SCSI]
 
+	hashdist=	[KNL,NUMA] Large hashes allocated during boot
+			are distributed across NUMA nodes.  Defaults on
+			for IA-64, off otherwise.
+
 	hcl=		[IA-64] SGI's Hardware Graph compatibility layer
 
 	hd=		[EIDE] (E)IDE hard drive subsystem geometry
@@ -498,6 +514,8 @@
 	i8042.dumbkbd	[HW] Pretend that controlled can only read data from
 			     keyboard and can not control its state
 			     (Don't attempt to blink the leds)
+	i8042.noacpi	[HW] Don't use ACPI to discover KBD/AUX controller
+			     settings
 	i8042.noaux	[HW] Don't check for auxiliary (== mouse) port
 	i8042.nomux	[HW] Don't check presence of an active multiplexing
 			     controller
@@ -573,11 +591,13 @@
 			Format: <RDP>, <reset>, <pci_scan>, <verbosity>
 
 	isolcpus=	[KNL,SMP] Isolate CPUs from the general scheduler.
-			Format: <cpu number>, ..., <cpu number>
+			Format: <cpu number>,...,<cpu number>
 			This option can be used to specify one or more CPUs
 			to isolate from the general SMP balancing and scheduling
 			algorithms. The only way to move a process onto or off
 			an "isolated" CPU is via the CPU affinity syscalls.
+			<cpu number> begins at 0 and the maximum value is
+			"number of CPUs in system - 1".
 
 			This option is the preferred way to isolate CPUs. The
 			alternative - manually setting the CPU mask of all tasks
@@ -657,7 +677,11 @@
 
 	mac53c9x=	[HW,SCSI]
 			Format: <num_esps>,<disconnect>,<nosync>,<can_queue>,<cmd_per_lun>,<sg_tablesize>,<hostid>,<use_tags>
-	
+
+	machvec=	[IA64]
+			Force the use of a particular machine-vector (machvec) in a generic
+			kernel.  Example: machvec=hpzx1_swiotlb
+
 	mad16=		[HW,OSS]
 			Format: <io>,<irq>,<dma>,<dma16>,<mpu_io>,<mpu_irq>,<joystick>
 
@@ -872,6 +896,13 @@
 	panic=		[KNL] Kernel behaviour on panic
 			Format: <timeout>
 
+	parkbd.port=	[HW] Parallel port number the keyboard adapter is
+			connected to, default is 0.
+			Format: <parport#>
+	parkbd.mode=	[HW] Parallel port keyboard adapter mode of operation,
+			0 for XT, 1 for AT (default is AT).
+			Format: <mode> 
+
 	parport=0	[HW,PPT]	Specify parallel ports. 0 disables.
 	parport=auto			Use 'auto' to force the driver to use
 	parport=0xBBB[,IRQ[,DMA]]	any IRQ/DMA settings detected (the
@@ -987,6 +1018,9 @@
 			Format: { parport<nr> | timid | 0 }
 			See also Documentation/parport.txt.
 
+	pnpacpi=	[ACPI]
+			{ off }
+
 	pnpbios=	[ISAPNP]
 			{ on | off | curr | res | no-curr | no-res }
 
@@ -1072,6 +1106,9 @@
 
 	root=		[KNL] Root filesystem
 
+	rootdelay=	[KNL] Delay (in seconds) to pause before attempting to
+			mount the root filesystem
+
 	rootflags=	[KNL] Set root filesystem mount option string
 
 	rootfstype=	[KNL] Set root filesystem type
@@ -1319,12 +1356,13 @@
 	thash_entries=	[KNL,NET]
 			Set number of hash buckets for TCP connection
 
-	tipar=		[HW]
-			See header of drivers/char/tipar.c.
+	tipar.timeout=	[HW,PPT]
+			Set communications timeout in tenths of a second
+			(default 15).
+
+	tipar.delay=	[HW,PPT]
+			Set inter-bit delay in microseconds (default 10).
 
-	tiusb=		[HW,USB] Texas Instruments' USB GraphLink (aka SilverLink)
-			Format: <timeout>
- 
 	tmc8xx=		[HW,SCSI]
 			See header of drivers/scsi/seagate.c.
 
diff -Nru a/Documentation/mkdev.cciss b/Documentation/mkdev.cciss
--- a/Documentation/mkdev.cciss	2005-03-01 23:38:52 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,40 +0,0 @@
-#!/bin/sh
-# Script to create device nodes for SMART array controllers
-# Usage:
-#	mkdev.cciss [num controllers] [num log volumes] [num partitions]
-#
-# With no arguments, the script assumes 1 controller, 16 logical volumes,
-# and 16 partitions/volume, which is adequate for most configurations.
-#
-# If you had 5 controllers and were planning on no more than 4 logical volumes
-# each, using a maximum of 8 partitions per volume, you could say:
-#
-# mkdev.cciss 5 4 8
-#
-# Of course, this has no real benefit over "mkdev.cciss 5" except that it
-# doesn't create so many device nodes in /dev/cciss.
-
-NR_CTLR=${1-1}
-NR_VOL=${2-16}
-NR_PART=${3-16}
-
-if [ ! -d /dev/cciss ]; then
-	mkdir -p /dev/cciss
-fi
-
-C=0; while [ $C -lt $NR_CTLR ]; do
-	MAJ=`expr $C + 104`
-	D=0; while [ $D -lt $NR_VOL ]; do
-		P=0; while [ $P -lt $NR_PART ]; do
-			MIN=`expr $D \* 16 + $P`
-			if [ $P -eq 0 ]; then
-				mknod /dev/cciss/c${C}d${D} b $MAJ $MIN
-			else
-				mknod /dev/cciss/c${C}d${D}p${P} b $MAJ $MIN
-			fi
-			P=`expr $P + 1`
-		done
-		D=`expr $D + 1`
-	done
-	C=`expr $C + 1`
-done
diff -Nru a/Documentation/networking/e100.txt b/Documentation/networking/e100.txt
--- a/Documentation/networking/e100.txt	2005-03-01 23:39:09 -08:00
+++ b/Documentation/networking/e100.txt	2005-03-01 23:39:09 -08:00
@@ -1,7 +1,7 @@
 Linux* Base Driver for the Intel(R) PRO/100 Family of Adapters
 ==============================================================
 
-September 13, 2004
+November 17, 2004
 
 
 Contents
@@ -18,9 +18,7 @@
 ===============
 
 This file describes the Linux* Base Driver for the Intel(R) PRO/100 Family of
-Adapters, version 3.2.x.  This driver includes support for Itanium(TM)2 and
-EM64T systems.
-
+Adapters, version 3.3.x.  This driver supports 2.4.x and 2.6.x kernels. 
 
 Identifying Your Adapter
 ========================
@@ -118,12 +116,6 @@
 
   The latest release of ethtool can be found at:
   http://sf.net/projects/gkernel.  
-
-  After ethtool is installed, ethtool-copy.h must be copied and renamed to
-  ethtool.h in your kernel source tree at <linux_kernel_src>/include/linux.  
-  Backup the original ethtool.h as needed before copying.  The driver then 
-  must be recompiled in order to take advantage of the latest ethtool 
-  features.
 
   NOTE: This driver uses mii support from the kernel. As a result, when 
   there is no link, ethtool will report speed/duplex to be 10/half.
diff -Nru a/Documentation/networking/e1000.txt b/Documentation/networking/e1000.txt
--- a/Documentation/networking/e1000.txt	2005-03-01 23:39:09 -08:00
+++ b/Documentation/networking/e1000.txt	2005-03-01 23:39:09 -08:00
@@ -1,7 +1,7 @@
 Linux* Base Driver for the Intel(R) PRO/1000 Family of Adapters
 ===============================================================
 
-September 13, 2004
+November 17, 2004
 
 
 Contents
@@ -20,8 +20,7 @@
 ===============
 
 This file describes the Linux* Base Driver for the Intel(R) PRO/1000 Family
-of Adapters, version 5.x.x.  This driver includes support for Itanium(TM)2 
-and EM64T systems.
+of Adapters, version 5.x.x.  
 
 For questions related to hardware requirements, refer to the documentation 
 supplied with your Intel PRO/1000 adapter. All hardware requirements listed 
@@ -145,9 +144,11 @@
 Default Value: 256
     This value is the number of receive descriptors allocated by the driver. 
     Increasing this value allows the driver to buffer more incoming packets. 
-    Each descriptor is 16 bytes.  A receive buffer is also allocated for each
-    descriptor and can be either 2048, 4096, 8192, or 16384 bytes, depending 
-    on the MTU setting. The maximum MTU size is 16110.
+    Each descriptor is 16 bytes.  A receive buffer is allocated for each
+    descriptor and can either be 2048 or 4096 bytes long, depending on the MTU 
+
+    setting. An incoming packet can span one or more receive descriptors. 
+    The maximum MTU size is 16110.
 
     NOTE: MTU designates the frame size. It only needs to be set for Jumbo 
           Frames.
@@ -251,17 +252,16 @@
   also be forced.
 
 The AutoNeg parameter is used when more control is required over the auto-
-negotiation process.  When this parameter is used, Speed and Duplex must not 
-be specified.  This parameter is a bitmap that specifies which speed and 
-duplex settings are advertised to the link partner.
-
-Bit            7      6      5       4       3      2      1       0
-Speed (Mbps)   N/A    N/A    1000    N/A     100    100    10      10
-Duplex                       Full            Full   Half   Full    Half
-
-For example to limit the negotiated speed/duplex on the interface to 10 Mbps 
-Half or Full duplex, set AutoNeg to 0x02: 
-    insmod e1000 AutoNeg=0x02
+negotiation process. When this parameter is used, Speed and Duplex parameters 
+must not be specified. The following table describes supported values for the 
+AutoNeg parameter:
+
+Speed (Mbps)   		 1000      100    100    10     10
+Duplex                   Full      Full   Half   Full   Half
+Value (in base 16)       0x20      0x08   0x04   0x02   0x01
+
+Example: insmod e1000 AutoNeg=0x03, loads e1000 and specifies (10 full duplex, 
+10 half duplex) for negotiation with the peer.
 
 Note that setting AutoNeg does not guarantee that the board will link at the 
 highest specified speed or duplex mode, but the board will link at the 
@@ -333,11 +333,7 @@
   version 1.6 or later is required for this functionality.
 
   The latest release of ethtool can be found from
-  http://sf.net/projects/gkernel.  After ethtool is installed,
-  ethtool-copy.h must be copied and renamed to ethtool.h in your kernel
-  source tree at <linux_kernel_src>/include/linux.  Backup the original
-  ethtool.h as needed before copying.  The driver then must be recompiled
-  in order to take advantage of the latest ethtool features.
+  http://sf.net/projects/gkernel.  
 
   NOTE: Ethtool 1.6 only supports a limited set of ethtool options. Support 
   for a more complete ethtool feature set can be enabled by upgrading 
diff -Nru a/Documentation/networking/pktgen.txt b/Documentation/networking/pktgen.txt
--- a/Documentation/networking/pktgen.txt	2005-03-01 23:38:57 -08:00
+++ b/Documentation/networking/pktgen.txt	2005-03-01 23:38:57 -08:00
@@ -1,77 +1,214 @@
-How to use the Linux packet generator module.
 
-1. Enable CONFIG_NET_PKTGEN to compile and build pktgen.o, install it
-   in the place where insmod may find it.
-2. Cut script "ipg" (see below).
-3. Edit script to set preferred device and destination IP address.
-3a.  Create more scripts for different interfaces.  Up to thirty-two
-     pktgen processes can be configured and run at once by using the
-     32 /proc/net/pktgen/pg* files.
-4. Run in shell: ". ipg"
-5. After this two commands are defined:
-   A. "pg" to start generator and to get results.
-   B. "pgset" to change generator parameters. F.e.
-      pgset "clone_skb 100"   sets the number of copies of the same packet 
-                              will be sent before a new packet is allocated
-      pgset "clone_skb 0"     use multiple SKBs for packet generation
-      pgset "pkt_size 9014"   sets packet size to 9014
-      pgset "frags 5"         packet will consist of 5 fragments
-      pgset "count 200000"    sets number of packets to send, set to zero
-                              for continuous sends until explicitly
-                              stopped.
-      pgset "ipg 5000"        sets artificial gap inserted between packets
-                              to 5000 nanoseconds
-      pgset "dst 10.0.0.1"    sets IP destination address
-                              (BEWARE! This generator is very aggressive!)
-      pgset "dst_min 10.0.0.1"            Same as dst
-      pgset "dst_max 10.0.0.254"          Set the maximum destination IP.
-      pgset "src_min 10.0.0.1"            Set the minimum (or only) source IP.
-      pgset "src_max 10.0.0.254"          Set the maximum source IP.
-      pgset "dstmac 00:00:00:00:00:00"    sets MAC destination address
-      pgset "srcmac 00:00:00:00:00:00"    sets MAC source address
-      pgset "src_mac_count 1" Sets the number of MACs we'll range through.  The
-                              'minimum' MAC is what you set with srcmac.
-      pgset "dst_mac_count 1" Sets the number of MACs we'll range through.  The
-                              'minimum' MAC is what you set with dstmac.
-      pgset "flag [name]"     Set a flag to determine behaviour.  Current flags
-                              are: IPSRC_RND #IP Source is random (between min/max),
-                                   IPDST_RND, UDPSRC_RND,
-                                   UDPDST_RND, MACSRC_RND, MACDST_RND 
-      pgset "udp_src_min 9"   set UDP source port min, If < udp_src_max, then
-                              cycle through the port range.
-      pgset "udp_src_max 9"   set UDP source port max.
-      pgset "udp_dst_min 9"   set UDP destination port min, If < udp_dst_max, then
-                              cycle through the port range.
-      pgset "udp_dst_max 9"   set UDP destination port max.
-      pgset stop    	      aborts injection
-      
-  Also, ^C aborts generator.
-
----- cut here
-
-#! /bin/sh
-
-modprobe pktgen
-
-PGDEV=/proc/net/pktgen/pg0
-
-function pgset() {
-    local result
-
-    echo $1 > $PGDEV
-
-    result=`cat $PGDEV | fgrep "Result: OK:"`
-    if [ "$result" = "" ]; then
-         cat $PGDEV | fgrep Result:
-    fi
-}
-
-function pg() {
-    echo inject > $PGDEV
-    cat $PGDEV
-}
 
-pgset "odev eth0"
-pgset "dst 0.0.0.0"
+                  HOWTO for the linux packet generator 
+                  ------------------------------------
 
----- cut here
+Date: 041221
+
+Enable CONFIG_NET_PKTGEN to compile and build pktgen.o either in kernel
+or as module. Module is preferred. insmod pktgen if needed. Once running
+pktgen creates a thread on each CPU where each thread has affinty it's CPU.
+Monitoring and controlling is done via /proc. Easiest to select a suitable 
+a sample script and configure.
+
+On a dual CPU:
+
+ps aux | grep pkt
+root       129  0.3  0.0     0    0 ?        SW    2003 523:20 [pktgen/0]
+root       130  0.3  0.0     0    0 ?        SW    2003 509:50 [pktgen/1]
+
+
+For montoring and control pktgen creates:
+	/proc/net/pktgen/pgctrl
+	/proc/net/pktgen/kpktgend_X
+        /proc/net/pktgen/ethX
+
+
+Viewing threads
+===============
+/proc/net/pktgen/kpktgend_0 
+Name: kpktgend_0  max_before_softirq: 10000
+Running: 
+Stopped: eth1 
+Result: OK: max_before_softirq=10000
+
+Most important the devices assigend to thread. Note! A device can only belong 
+to one thread.
+
+
+Viewing devices
+===============
+
+Parm section holds configured info. Current hold running stats. 
+Result is printed after run or after interruption. Example:
+
+/proc/net/pktgen/eth1       
+
+Params: count 10000000  min_pkt_size: 60  max_pkt_size: 60
+     frags: 0  delay: 0  clone_skb: 1000000  ifname: eth1
+     flows: 0 flowlen: 0
+     dst_min: 10.10.11.2  dst_max: 
+     src_min:   src_max: 
+     src_mac: 00:00:00:00:00:00  dst_mac: 00:04:23:AC:FD:82
+     udp_src_min: 9  udp_src_max: 9  udp_dst_min: 9  udp_dst_max: 9
+     src_mac_count: 0  dst_mac_count: 0 
+     Flags: 
+Current:
+     pkts-sofar: 10000000  errors: 39664
+     started: 1103053986245187us  stopped: 1103053999346329us idle: 880401us
+     seq_num: 10000011  cur_dst_mac_offset: 0  cur_src_mac_offset: 0
+     cur_saddr: 0x10a0a0a  cur_daddr: 0x20b0a0a
+     cur_udp_dst: 9  cur_udp_src: 9
+     flows: 0
+Result: OK: 13101142(c12220741+d880401) usec, 10000000 (60byte,0frags)
+  763292pps 390Mb/sec (390805504bps) errors: 39664
+
+Confguring threads and devices
+==============================
+This is done via the /proc interface easiest done via pgset in the scripts
+
+Examples:
+
+ pgset "clone_skb 1"     sets the number of copies of the same packet
+ pgset "clone_skb 0"     use single SKB for all transmits
+ pgset "pkt_size 9014"   sets packet size to 9014
+ pgset "frags 5"         packet will consist of 5 fragments
+ pgset "count 200000"    sets number of packets to send, set to zero
+                         for continious sends untill explicitl stopped.
+
+ pgset "delay 5000"      adds delay to hard_start_xmit(). nanoseconds
+
+ pgset "dst 10.0.0.1"    sets IP destination address
+                         (BEWARE! This generator is very aggressive!)
+
+ pgset "dst_min 10.0.0.1"            Same as dst
+ pgset "dst_max 10.0.0.254"          Set the maximum destination IP.
+ pgset "src_min 10.0.0.1"            Set the minimum (or only) source IP.
+ pgset "src_max 10.0.0.254"          Set the maximum source IP.
+ pgset "dst6 fec0::1"     IPV6 destination address
+ pgset "src6 fec0::2"     IPV6 source address
+ pgset "dstmac 00:00:00:00:00:00"    sets MAC destination address
+ pgset "srcmac 00:00:00:00:00:00"    sets MAC source address
+
+ pgset "src_mac_count 1" Sets the number of MACs we'll range through.  
+                         The 'minimum' MAC is what you set with srcmac.
+
+ pgset "dst_mac_count 1" Sets the number of MACs we'll range through.
+                         The 'minimum' MAC is what you set with dstmac.
+
+ pgset "flag [name]"     Set a flag to determine behaviour.  Current flags
+                         are: IPSRC_RND #IP Source is random (between min/max),
+                              IPDST_RND, UDPSRC_RND,
+                              UDPDST_RND, MACSRC_RND, MACDST_RND 
+
+ pgset "udp_src_min 9"   set UDP source port min, If < udp_src_max, then
+                         cycle through the port range.
+
+ pgset "udp_src_max 9"   set UDP source port max.
+ pgset "udp_dst_min 9"   set UDP destination port min, If < udp_dst_max, then
+                         cycle through the port range.
+ pgset "udp_dst_max 9"   set UDP destination port max.
+
+ pgset stop    	          aborts injection. Also, ^C aborts generator.
+
+
+Example scripts
+===============
+
+A collection of small tutorial scripts for pktgen is in expamples dir.
+
+pktgen.conf-1-1                  # 1 CPU 1 dev 
+pktgen.conf-1-2                  # 1 CPU 2 dev
+pktgen.conf-2-1                  # 2 CPU's 1 dev 
+pktgen.conf-2-2                  # 2 CPU's 2 dev
+pktgen.conf-1-1-rdos             # 1 CPU 1 dev w. route DoS 
+pktgen.conf-1-1-ip6              # 1 CPU 1 dev ipv6
+pktgen.conf-1-1-ip6-rdos         # 1 CPU 1 dev ipv6  w. route DoS
+pktgen.conf-1-1-flows            # 1 CPU 1 dev multiple flows.
+
+Run in shell: ./pktgen.conf-X-Y It does all the setup including sending. 
+
+
+Interrupt affinity
+===================
+Note when adding devices to a specific CPU there good idea to also assign 
+/proc/irq/XX/smp_affinity so the TX-interrupts gets bound to the same CPU.
+as this reduces cache bouncing when freeing skb's.
+
+
+Current commands and configuration options
+==========================================
+
+** Pgcontrol commands:
+
+start
+stop
+
+** Thread commands:
+
+add_device
+rem_device_all
+max_before_softirq
+
+
+** Device commands:
+
+count
+clone_skb
+debug
+
+frags
+delay
+
+src_mac_count
+dst_mac_count
+
+pkt_size 
+min_pkt_size
+max_pkt_size
+
+udp_src_min
+udp_src_max
+
+udp_dst_min
+udp_dst_max
+
+flag
+  IPSRC_RND
+  TXSIZE_RND
+  IPDST_RND
+  UDPSRC_RND
+  UDPDST_RND
+  MACSRC_RND
+  MACDST_RND
+
+dst_min
+dst_max
+
+src_min
+src_max
+
+dst_mac
+src_mac
+
+clear_counters
+
+dst6
+src6
+
+flows
+flowlen
+
+References:
+ftp://robur.slu.se/pub/Linux/net-development/pktgen-testing/
+ftp://robur.slu.se/pub/Linux/net-development/pktgen-testing/examples/
+
+Paper from Linux-Kongress in Erlangen 2004.
+ftp://robur.slu.se/pub/Linux/net-development/pktgen-testing/pktgen_paper.pdf
+
+Thanks to:
+Grant Grundler for testing on IA-64 and parisc, Harald Welte,  Lennert Buytenhek
+Stephen Hemminger, Andi Kleen, Dave Miller and many others.
+
+
+Good luck with the linux net-development.
\ No newline at end of file
diff -Nru a/Documentation/nommu-mmap.txt b/Documentation/nommu-mmap.txt
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/Documentation/nommu-mmap.txt	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,141 @@
+			 =============================
+			 NO-MMU MEMORY MAPPING SUPPORT
+			 =============================
+
+The kernel has limited support for memory mapping under no-MMU conditions, such
+as are used in uClinux environments. From the userspace point of view, memory
+mapping is made use of in conjunction with the mmap() system call, the shmat()
+call and the execve() system call. From the kernel's point of view, execve()
+mapping is actually performed by the binfmt drivers, which call back into the
+mmap() routines to do the actual work.
+
+Memory mapping behaviour also involves the way fork(), vfork(), clone() and
+ptrace() work. Under uClinux there is no fork(), and clone() must be supplied
+the CLONE_VM flag.
+
+The behaviour is similar between the MMU and no-MMU cases, but not identical;
+and it's also much more restricted in the latter case:
+
+ (*) Anonymous mapping, MAP_PRIVATE
+
+	In the MMU case: VM regions backed by arbitrary pages; copy-on-write
+	across fork.
+
+	In the no-MMU case: VM regions backed by arbitrary contiguous runs of
+	pages.
+
+ (*) Anonymous mapping, MAP_SHARED
+
+	These behave very much like private mappings, except that they're
+	shared across fork() or clone() without CLONE_VM in the MMU case. Since
+	the no-MMU case doesn't support these, behaviour is identical to
+	MAP_PRIVATE there.
+
+ (*) File, MAP_PRIVATE, PROT_READ / PROT_EXEC, !PROT_WRITE
+
+	In the MMU case: VM regions backed by pages read from file; changes to
+	the underlying file are reflected in the mapping; copied across fork.
+
+	In the no-MMU case: VM regions backed by arbitrary contiguous runs of
+	pages into which the appropriate bit of the file is read; any remaining
+	bit of the mapping is cleared; such mappings are shared if possible;
+	writes to the file do not affect the mapping; writes to the mapping are
+	visible in other processes (no MMU protection), but should not happen.
+
+ (*) File, MAP_PRIVATE, PROT_READ / PROT_EXEC, PROT_WRITE
+
+	In the MMU case: like the non-PROT_WRITE case, except that the pages in
+	question get copied before the write actually happens. From that point
+	on writes to that page in the file no longer get reflected into the
+	mapping's backing pages.
+
+	In the no-MMU case: works exactly as for the non-PROT_WRITE case.
+
+ (*) Regular file / blockdev, MAP_SHARED, PROT_READ / PROT_EXEC / PROT_WRITE
+
+	In the MMU case: VM regions backed by pages read from file; changes to
+	pages written back to file; writes to file reflected into pages backing
+	mapping; shared across fork.
+
+	In the no-MMU case: not supported.
+
+ (*) Memory backed regular file, MAP_SHARED, PROT_READ / PROT_EXEC / PROT_WRITE
+
+	In the MMU case: As for ordinary regular files.
+
+	In the no-MMU case: The filesystem providing the memory-backed file
+	(such as ramfs or tmpfs) may choose to honour an open, truncate, mmap
+	sequence by providing a contiguous sequence of pages to map. In that
+	case, a shared-writable memory mapping will be possible. It will work
+	as for the MMU case. If the filesystem does not provide any such
+	support, then the mapping request will be denied.
+
+ (*) Memory backed chardev, MAP_SHARED, PROT_READ / PROT_EXEC / PROT_WRITE
+
+	In the MMU case: As for ordinary regular files.
+
+	In the no-MMU case: The character device driver may choose to honour
+	the mmap() by providing direct access to the underlying device if it
+	provides memory or quasi-memory that can be accessed directly. Examples
+	of such are frame buffers and flash devices. If the driver does not
+	provide any such support, then the mapping request will be denied.
+
+
+============================
+FURTHER NOTES ON NO-MMU MMAP
+============================
+
+ (*) A request for a private mapping of less than a page in size may not return
+     a page-aligned buffer. This is because the kernel calls kmalloc() to
+     allocate the buffer, not get_free_page().
+
+ (*) A list of all the mappings on the system is visible through /proc/maps in
+     no-MMU mode.
+
+ (*) Supplying MAP_FIXED or a requesting a particular mapping address will
+     result in an error.
+
+ (*) Files mapped privately must have a read method provided by the driver or
+     filesystem so that the contents can be read into the memory allocated. An
+     error will result if they don't. This is most likely to be encountered
+     with character device files, pipes, fifos and sockets.
+
+
+============================================
+PROVIDING SHAREABLE CHARACTER DEVICE SUPPORT
+============================================
+
+To provide shareable character device support, a driver must provide a
+file->f_op->get_unmapped_area() operation. The mmap() routines will call this
+to get a proposed address for the mapping. This may return an error if it
+doesn't wish to honour the mapping because it's too long, at a weird offset,
+under some unsupported combination of flags or whatever.
+
+The vm_ops->close() routine will be invoked when the last mapping on a chardev
+is removed. An existing mapping will be shared, partially or not, if possible
+without notifying the driver.
+
+It is permitted also for the file->f_op->get_unmapped_area() operation to
+return -ENOSYS. This will be taken to mean that this operation just doesn't
+want to handle it, despite the fact it's got an operation. For instance, it
+might try directing the call to a secondary driver which turns out not to
+implement it. Such is the case for the framebuffer driver which attempts to
+direct the call to the device-specific driver.
+
+
+==============================================
+PROVIDING SHAREABLE MEMORY-BACKED FILE SUPPORT
+==============================================
+
+Provision of shared mappings on memory backed files is similar to the provision
+of support for shared mapped character devices. The main difference is that the
+filesystem providing the service will probably allocate a contiguous collection
+of pages and permit mappings to be made on that.
+
+It is recommended that a truncate operation applied to such a file that
+increases the file size, if that file is empty, be taken as a request to gather
+enough pages to honour a mapping. This is required to support POSIX shared
+memory.
+
+Memory backed devices are indicated by the mapping's backing device info having
+the memory_backed flag set.
diff -Nru a/Documentation/pm.txt b/Documentation/pm.txt
--- a/Documentation/pm.txt	2005-03-01 23:38:54 -08:00
+++ b/Documentation/pm.txt	2005-03-01 23:38:54 -08:00
@@ -91,54 +91,6 @@
 void pm_unregister_all(pm_callback cback);
 
 /*
- * Device idle/use detection
- *
- * In general, drivers for all devices should call "pm_access"
- * before accessing the hardware (ie. before reading or modifying
- * a hardware register).  Request or packet-driven drivers should
- * additionally call "pm_dev_idle" when a device is not being used.
- *
- * Examples:
- * 1) A keyboard driver would call pm_access whenever a key is pressed
- * 2) A network driver would call pm_access before submitting
- *    a packet for transmit or receive and pm_dev_idle when its
- *    transfer and receive queues are empty.
- * 3) A VGA driver would call pm_access before it accesses any
- *    of the video controller registers
- *
- * Ultimately, the PM policy manager uses the access and idle
- * information to decide when to suspend individual devices
- * or when to suspend the entire system
- */
-
-/*
- * Description: Update device access time and wake up device, if necessary
- *
- * Parameters:
- *   dev - PM device previously returned from pm_register
- *
- * Details: If called from an interrupt handler pm_access updates
- *          access time but should never need to wake up the device
- *          (if device is generating interrupts, it should be awake
- *          already)  This is important as we can not wake up
- *          devices from an interrupt handler.
- */
-void pm_access(struct pm_dev *dev);
-
-/*
- * Description: Identify device as currently being idle
- *
- * Parameters:
- *   dev - PM device previously returned from pm_register
- *
- * Details: A call to pm_dev_idle might signal to the policy manager
- *          to put a device to sleep.  If a new device request arrives
- *          between the call to pm_dev_idle and the pm_callback
- *          callback, the driver should fail the pm_callback request.
- */
-void pm_dev_idle(struct pm_dev *dev);
-
-/*
  * Power management request callback
  *
  * Parameters:
diff -Nru a/Documentation/power/devices.txt b/Documentation/power/devices.txt
--- a/Documentation/power/devices.txt	2005-03-01 23:38:51 -08:00
+++ b/Documentation/power/devices.txt	2005-03-01 23:38:51 -08:00
@@ -118,6 +118,94 @@
 There is currently no way to know what states a device or driver
 supports a priori. This will change in the future. 
 
+pm_message_t meaning
+
+pm_message_t has two fields. event ("major"), and flags.  If driver
+does not know event code, it aborts the request, returning error. Some
+drivers may need to deal with special cases based on the actual type
+of suspend operation being done at the system level. This is why
+there are flags.
+
+Event codes are:
+
+ON -- no need to do anything except special cases like broken
+HW.
+
+# NOTIFICATION -- pretty much same as ON?
+
+FREEZE -- stop DMA and interrupts, and be prepared to reinit HW from
+scratch. That probably means stop accepting upstream requests, the
+actual policy of what to do with them beeing specific to a given
+driver. It's acceptable for a network driver to just drop packets
+while a block driver is expected to block the queue so no request is
+lost. (Use IDE as an example on how to do that). FREEZE requires no
+power state change, and it's expected for drivers to be able to
+quickly transition back to operating state.
+
+SUSPEND -- like FREEZE, but also put hardware into low-power state. If
+there's need to distinguish several levels of sleep, additional flag
+is probably best way to do that.
+
+Transitions are only from a resumed state to a suspended state, never
+between 2 suspended states. (ON -> FREEZE or ON -> SUSPEND can happen,
+FREEZE -> SUSPEND or SUSPEND -> FREEZE can not).
+
+All events are:
+
+[NOTE NOTE NOTE: If you are driver author, you should not care; you
+should only look at event, and ignore flags.]
+
+#Prepare for suspend -- userland is still running but we are going to
+#enter suspend state. This gives drivers chance to load firmware from
+#disk and store it in memory, or do other activities taht require
+#operating userland, ability to kmalloc GFP_KERNEL, etc... All of these
+#are forbiden once the suspend dance is started.. event = ON, flags =
+#PREPARE_TO_SUSPEND
+
+Apm standby -- prepare for APM event. Quiesce devices to make life
+easier for APM BIOS. event = FREEZE, flags = APM_STANDBY
+
+Apm suspend -- same as APM_STANDBY, but it we should probably avoid
+spinning down disks. event = FREEZE, flags = APM_SUSPEND
+
+System halt, reboot -- quiesce devices to make life easier for BIOS. event
+= FREEZE, flags = SYSTEM_HALT or SYSTEM_REBOOT
+
+System shutdown -- at least disks need to be spun down, or data may be
+lost. Quiesce devices, just to make life easier for BIOS. event =
+FREEZE, flags = SYSTEM_SHUTDOWN
+
+Kexec    -- turn off DMAs and put hardware into some state where new
+kernel can take over. event = FREEZE, flags = KEXEC
+
+Powerdown at end of swsusp -- very similar to SYSTEM_SHUTDOWN, except wake
+may need to be enabled on some devices. This actually has at least 3
+subtypes, system can reboot, enter S4 and enter S5 at the end of
+swsusp. event = FREEZE, flags = SWSUSP and one of SYSTEM_REBOOT,
+SYSTEM_SHUTDOWN, SYSTEM_S4
+
+Suspend to ram  -- put devices into low power state. event = SUSPEND,
+flags = SUSPEND_TO_RAM
+
+Freeze for swsusp snapshot -- stop DMA and interrupts. No need to put
+devices into low power mode, but you must be able to reinitialize
+device from scratch in resume method. This has two flavors, its done
+once on suspending kernel, once on resuming kernel. event = FREEZE,
+flags = DURING_SUSPEND or DURING_RESUME
+
+Device detach requested from /sys -- deinitialize device; proably same as
+SYSTEM_SHUTDOWN, I do not understand this one too much. probably event
+= FREEZE, flags = DEV_DETACH.
+
+#These are not really events sent:
+#
+#System fully on -- device is working normally; this is probably never
+#passed to suspend() method... event = ON, flags = 0
+#
+#Ready after resume -- userland is now running, again. Time to free any
+#memory you ate during prepare to suspend... event = ON, flags =
+#READY_AFTER_RESUME
+#
 
 Driver Detach Power Management
 
@@ -141,3 +229,91 @@
 The driver core will not call any extra functions when binding the
 device to the driver. 
 
+pm_message_t meaning
+
+pm_message_t has two fields. event ("major"), and flags.  If driver
+does not know event code, it aborts the request, returning error. Some
+drivers may need to deal with special cases based on the actual type
+of suspend operation being done at the system level. This is why
+there are flags.
+
+Event codes are:
+
+ON -- no need to do anything except special cases like broken
+HW.
+
+# NOTIFICATION -- pretty much same as ON?
+
+FREEZE -- stop DMA and interrupts, and be prepared to reinit HW from
+scratch. That probably means stop accepting upstream requests, the
+actual policy of what to do with them being specific to a given
+driver. It's acceptable for a network driver to just drop packets
+while a block driver is expected to block the queue so no request is
+lost. (Use IDE as an example on how to do that). FREEZE requires no
+power state change, and it's expected for drivers to be able to
+quickly transition back to operating state.
+
+SUSPEND -- like FREEZE, but also put hardware into low-power state. If
+there's need to distinguish several levels of sleep, additional flag
+is probably best way to do that.
+
+Transitions are only from a resumed state to a suspended state, never
+between 2 suspended states. (ON -> FREEZE or ON -> SUSPEND can happen,
+FREEZE -> SUSPEND or SUSPEND -> FREEZE can not).
+
+All events are:
+
+[NOTE NOTE NOTE: If you are driver author, you should not care; you
+should only look at event, and ignore flags.]
+
+#Prepare for suspend -- userland is still running but we are going to
+#enter suspend state. This gives drivers chance to load firmware from
+#disk and store it in memory, or do other activities taht require
+#operating userland, ability to kmalloc GFP_KERNEL, etc... All of these
+#are forbiden once the suspend dance is started.. event = ON, flags =
+#PREPARE_TO_SUSPEND
+
+Apm standby -- prepare for APM event. Quiesce devices to make life
+easier for APM BIOS. event = FREEZE, flags = APM_STANDBY
+
+Apm suspend -- same as APM_STANDBY, but it we should probably avoid
+spinning down disks. event = FREEZE, flags = APM_SUSPEND
+
+System halt, reboot -- quiesce devices to make life easier for BIOS. event
+= FREEZE, flags = SYSTEM_HALT or SYSTEM_REBOOT
+
+System shutdown -- at least disks need to be spun down, or data may be
+lost. Quiesce devices, just to make life easier for BIOS. event =
+FREEZE, flags = SYSTEM_SHUTDOWN
+
+Kexec    -- turn off DMAs and put hardware into some state where new
+kernel can take over. event = FREEZE, flags = KEXEC
+
+Powerdown at end of swsusp -- very similar to SYSTEM_SHUTDOWN, except wake
+may need to be enabled on some devices. This actually has at least 3
+subtypes, system can reboot, enter S4 and enter S5 at the end of
+swsusp. event = FREEZE, flags = SWSUSP and one of SYSTEM_REBOOT,
+SYSTEM_SHUTDOWN, SYSTEM_S4
+
+Suspend to ram  -- put devices into low power state. event = SUSPEND,
+flags = SUSPEND_TO_RAM
+
+Freeze for swsusp snapshot -- stop DMA and interrupts. No need to put
+devices into low power mode, but you must be able to reinitialize
+device from scratch in resume method. This has two flavors, its done
+once on suspending kernel, once on resuming kernel. event = FREEZE,
+flags = DURING_SUSPEND or DURING_RESUME
+
+Device detach requested from /sys -- deinitialize device; proably same as
+SYSTEM_SHUTDOWN, I do not understand this one too much. probably event
+= FREEZE, flags = DEV_DETACH.
+
+#These are not really events sent:
+#
+#System fully on -- device is working normally; this is probably never
+#passed to suspend() method... event = ON, flags = 0
+#
+#Ready after resume -- userland is now running, again. Time to free any
+#memory you ate during prepare to suspend... event = ON, flags =
+#READY_AFTER_RESUME
+#
diff -Nru a/Documentation/power/swsusp.txt b/Documentation/power/swsusp.txt
--- a/Documentation/power/swsusp.txt	2005-03-01 23:38:44 -08:00
+++ b/Documentation/power/swsusp.txt	2005-03-01 23:38:44 -08:00
@@ -15,6 +15,9 @@
  * If you change kernel command line between suspend and resume...
  *			        ...prepare for nasty fsck or worse.
  *
+ * If you change your hardware while system is suspended...
+ *			        ...well, it was not good idea.
+ *
  * (*) suspend/resume support is needed to make it safe.
 
 You need to append resume=/dev/your_swap_partition to kernel command
@@ -183,3 +186,50 @@
 
 "platform" is actually right thing to do, but "shutdown" is most
 reliable.
+
+Q: I do not understand why you have such strong objections to idea of
+selective suspend.
+
+A: Do selective suspend during runtime power managment, that's okay. But
+its useless for suspend-to-disk. (And I do not see how you could use
+it for suspend-to-ram, I hope you do not want that).
+
+Lets see, so you suggest to
+
+* SUSPEND all but swap device and parents
+* Snapshot
+* Write image to disk
+* SUSPEND swap device and parents
+* Powerdown
+
+Oh no, that does not work, if swap device or its parents uses DMA,
+you've corrupted data. You'd have to do
+
+* SUSPEND all but swap device and parents
+* FREEZE swap device and parents
+* Snapshot
+* UNFREEZE swap device and parents
+* Write
+* SUSPEND swap device and parents
+
+Which means that you still need that FREEZE state, and you get more
+complicated code. (And I have not yet introduce details like system
+devices).
+
+Q: There don't seem to be any generally useful behavioral
+distinctions between SUSPEND and FREEZE.
+
+A: Doing SUSPEND when you are asked to do FREEZE is always correct,
+but it may be unneccessarily slow. If you want USB to stay simple,
+slowness may not matter to you. It can always be fixed later.
+
+For devices like disk it does matter, you do not want to spindown for
+FREEZE.
+
+Q: After resuming, system is paging heavilly, leading to very bad interactivity.
+
+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.
diff -Nru a/Documentation/powerpc/00-INDEX b/Documentation/powerpc/00-INDEX
--- a/Documentation/powerpc/00-INDEX	2005-03-01 23:39:08 -08:00
+++ b/Documentation/powerpc/00-INDEX	2005-03-01 23:39:08 -08:00
@@ -5,6 +5,9 @@
 
 00-INDEX
 	- this file
+cpu_features.txt
+	- info on how we support a variety of CPUs with minimal compile-time
+	options.
 ppc_htab.txt
 	- info about the Linux/PPC /proc/ppc_htab entry
 smp.txt
diff -Nru a/Documentation/powerpc/cpu_features.txt b/Documentation/powerpc/cpu_features.txt
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/Documentation/powerpc/cpu_features.txt	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,56 @@
+Hollis Blanchard <hollis@austin.ibm.com>
+5 Jun 2002
+
+This document describes the system (including self-modifying code) used in the
+PPC Linux kernel to support a variety of PowerPC CPUs without requiring
+compile-time selection.
+
+Early in the boot process the ppc32 kernel detects the current CPU type and
+chooses a set of features accordingly. Some examples include Altivec support,
+split instruction and data caches, and if the CPU supports the DOZE and NAP
+sleep modes.
+
+Detection of the feature set is simple. A list of processors can be found in
+arch/ppc/kernel/cputable.c. The PVR register is masked and compared with each
+value in the list. If a match is found, the cpu_features of cur_cpu_spec is
+assigned to the feature bitmask for this processor and a __setup_cpu function
+is called.
+
+C code may test 'cur_cpu_spec[smp_processor_id()]->cpu_features' for a
+particular feature bit. This is done in quite a few places, for example
+in ppc_setup_l2cr().
+
+Implementing cpufeatures in assembly is a little more involved. There are
+several paths that are performance-critical and would suffer if an array
+index, structure dereference, and conditional branch were added. To avoid the
+performance penalty but still allow for runtime (rather than compile-time) CPU
+selection, unused code is replaced by 'nop' instructions. This nop'ing is
+based on CPU 0's capabilities, so a multi-processor system with non-identical
+processors will not work (but such a system would likely have other problems
+anyways).
+
+After detecting the processor type, the kernel patches out sections of code
+that shouldn't be used by writing nop's over it. Using cpufeatures requires
+just 2 macros (found in include/asm-ppc/cputable.h), as seen in head.S
+transfer_to_handler:
+
+	#ifdef CONFIG_ALTIVEC
+	BEGIN_FTR_SECTION
+		mfspr	r22,SPRN_VRSAVE		/* if G4, save vrsave register value */
+		stw	r22,THREAD_VRSAVE(r23)
+	END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
+	#endif /* CONFIG_ALTIVEC */
+
+If CPU 0 supports Altivec, the code is left untouched. If it doesn't, both
+instructions are replaced with nop's.
+
+The END_FTR_SECTION macro has two simpler variations: END_FTR_SECTION_IFSET
+and END_FTR_SECTION_IFCLR. These simply test if a flag is set (in
+cur_cpu_spec[0]->cpu_features) or is cleared, respectively. These two macros
+should be used in the majority of cases.
+
+The END_FTR_SECTION macros are implemented by storing information about this
+code in the '__ftr_fixup' ELF section. When do_cpu_ftr_fixups
+(arch/ppc/kernel/misc.S) is invoked, it will iterate over the records in
+__ftr_fixup, and if the required feature is not present it will loop writing
+nop's from each BEGIN_FTR_SECTION to END_FTR_SECTION.
diff -Nru a/Documentation/powerpc/eeh-pci-error-recovery.txt b/Documentation/powerpc/eeh-pci-error-recovery.txt
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/Documentation/powerpc/eeh-pci-error-recovery.txt	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,332 @@
+
+
+                      PCI Bus EEH Error Recovery
+                      --------------------------
+                           Linas Vepstas
+                       <linas@austin.ibm.com>
+                          12 January 2005
+
+
+Overview:
+---------
+The IBM POWER-based pSeries and iSeries computers include PCI bus
+controller chips that have extended capabilities for detecting and
+reporting a large variety of PCI bus error conditions.  These features
+go under the name of "EEH", for "Extended Error Handling".  The EEH
+hardware features allow PCI bus errors to be cleared and a PCI
+card to be "rebooted", without also having to reboot the operating
+system.
+
+This is in contrast to traditional PCI error handling, where the
+PCI chip is wired directly to the CPU, and an error would cause
+a CPU machine-check/check-stop condition, halting the CPU entirely.
+Another "traditional" technique is to ignore such errors, which
+can lead to data corruption, both of user data or of kernel data,
+hung/unresponsive adapters, or system crashes/lockups.  Thus,
+the idea behind EEH is that the operating system can become more
+reliable and robust by protecting it from PCI errors, and giving
+the OS the ability to "reboot"/recover individual PCI devices.
+
+Future systems from other vendors, based on the PCI-E specification,
+may contain similar features.
+
+
+Causes of EEH Errors
+--------------------
+EEH was originally designed to guard against hardware failure, such
+as PCI cards dying from heat, humidity, dust, vibration and bad
+electrical connections. The vast majority of EEH errors seen in
+"real life" are due to eithr poorly seated PCI cards, or,
+unfortunately quite commonly, due device driver bugs, device firmware
+bugs, and sometimes PCI card hardware bugs.
+
+The most common software bug, is one that causes the device to
+attempt to DMA to a location in system memory that has not been
+reserved for DMA access for that card.  This is a powerful feature,
+as it prevents what; otherwise, would have been silent memory
+corruption caused by the bad DMA.  A number of device driver
+bugs have been found and fixed in this way over the past few
+years.  Other possible causes of EEH errors include data or
+address line parity errors (for example, due to poor electrical
+connectivity due to a poorly seated card), and PCI-X split-completion
+errors (due to software, device firmware, or device PCI hardware bugs).
+The vast majority of "true hardware failures" can be cured by
+physically removing and re-seating the PCI card.
+
+
+Detection and Recovery
+----------------------
+In the following discussion, a generic overview of how to detect
+and recover from EEH errors will be presented. This is followed
+by an overview of how the current implementation in the Linux
+kernel does it.  The actual implementation is subject to change,
+and some of the finer points are still being debated.  These
+may in turn be swayed if or when other architectures implement
+similar functionality.
+
+When a PCI Host Bridge (PHB, the bus controller connecting the
+PCI bus to the system CPU electronics complex) detects a PCI error
+condition, it will "isolate" the affected PCI card.  Isolation
+will block all writes (either to the card from the system, or
+from the card to the system), and it will cause all reads to
+return all-ff's (0xff, 0xffff, 0xffffffff for 8/16/32-bit reads).
+This value was chosen because it is the same value you would
+get if the device was physically unplugged from the slot.
+This includes access to PCI memory, I/O space, and PCI config
+space.  Interrupts; however, will continued to be delivered.
+
+Detection and recovery are performed with the aid of ppc64
+firmware.  The programming interfaces in the Linux kernel
+into the firmware are referred to as RTAS (Run-Time Abstraction
+Services).  The Linux kernel does not (should not) access
+the EEH function in the PCI chipsets directly, primarily because
+there are a number of different chipsets out there, each with
+different interfaces and quirks. The firmware provides a
+uniform abstraction layer that will work with all pSeries
+and iSeries hardware (and be forwards-compatible).
+
+If the OS or device driver suspects that a PCI slot has been
+EEH-isolated, there is a firmware call it can make to determine if
+this is the case. If so, then the device driver should put itself
+into a consistent state (given that it won't be able to complete any
+pending work) and start recovery of the card.  Recovery normally
+would consist of reseting the PCI device (holding the PCI #RST
+line high for two seconds), followed by setting up the device
+config space (the base address registers (BAR's), latency timer,
+cache line size, interrupt line, and so on).  This is followed by a
+reinitialization of the device driver.  In a worst-case scenario,
+the power to the card can be toggled, at least on hot-plug-capable
+slots.  In principle, layers far above the device driver probably
+do not need to know that the PCI card has been "rebooted" in this
+way; ideally, there should be at most a pause in Ethernet/disk/USB
+I/O while the card is being reset.
+
+If the card cannot be recovered after three or four resets, the
+kernel/device driver should assume the worst-case scenario, that the
+card has died completely, and report this error to the sysadmin.
+In addition, error messages are reported through RTAS and also through
+syslogd (/var/log/messages) to alert the sysadmin of PCI resets.
+The correct way to deal with failed adapters is to use the standard
+PCI hotplug tools to remove and replace the dead card.
+
+
+Current PPC64 Linux EEH Implementation
+--------------------------------------
+At this time, a generic EEH recovery mechanism has been implemented,
+so that individual device drivers do not need to be modified to support
+EEH recovery.  This generic mechanism piggy-backs on the PCI hotplug
+infrastructure,  and percolates events up through the hotplug/udev
+infrastructure.  Followiing is a detailed description of how this is
+accomplished.
+
+EEH must be enabled in the PHB's very early during the boot process,
+and if a PCI slot is hot-plugged. The former is performed by
+eeh_init() in arch/ppc64/kernel/eeh.c, and the later by
+drivers/pci/hotplug/pSeries_pci.c calling in to the eeh.c code.
+EEH must be enabled before a PCI scan of the device can proceed.
+Current Power5 hardware will not work unless EEH is enabled;
+although older Power4 can run with it disabled.  Effectively,
+EEH can no longer be turned off.  PCI devices *must* be
+registered with the EEH code; the EEH code needs to know about
+the I/O address ranges of the PCI device in order to detect an
+error.  Given an arbitrary address, the routine
+pci_get_device_by_addr() will find the pci device associated
+with that address (if any).
+
+The default include/asm-ppc64/io.h macros readb(), inb(), insb(),
+etc. include a check to see if the the i/o read returned all-0xff's.
+If so, these make a call to eeh_dn_check_failure(), which in turn
+asks the firmware if the all-ff's value is the sign of a true EEH
+error.  If it is not, processing continues as normal.  The grand
+total number of these false alarms or "false positives" can be
+seen in /proc/ppc64/eeh (subject to change).  Normally, almost
+all of these occur during boot, when the PCI bus is scanned, where
+a large number of 0xff reads are part of the bus scan procedure.
+
+If a frozen slot is detected, code in arch/ppc64/kernel/eeh.c will
+print a stack trace to syslog (/var/log/messages).  This stack trace
+has proven to be very useful to device-driver authors for finding
+out at what point the EEH error was detected, as the error itself
+usually occurs slightly beforehand.
+
+Next, it uses the Linux kernel notifier chain/work queue mechanism to
+allow any interested parties to find out about the failure.  Device
+drivers, or other parts of the kernel, can use
+eeh_register_notifier(struct notifier_block *) to find out about EEH
+events.  The event will include a pointer to the pci device, the
+device node and some state info.  Receivers of the event can "do as
+they wish"; the default handler will be described further in this
+section.
+
+To assist in the recovery of the device, eeh.c exports the
+following functions:
+
+rtas_set_slot_reset() -- assert the  PCI #RST line for 1/8th of a second
+rtas_configure_bridge() -- ask firmware to configure any PCI bridges
+   located topologically under the pci slot.
+eeh_save_bars() and eeh_restore_bars(): save and restore the PCI
+   config-space info for a device and any devices under it.
+
+
+A handler for the EEH notifier_block events is implemented in
+drivers/pci/hotplug/pSeries_pci.c, called handle_eeh_events().
+It saves the device BAR's and then calls rpaphp_unconfig_pci_adapter().
+This last call causes the device driver for the card to be stopped,
+which causes hotplug events to go out to user space. This triggers
+user-space scripts that might issue commands such as "ifdown eth0"
+for ethernet cards, and so on.  This handler then sleeps for 5 seconds,
+hoping to give the user-space scripts enough time to complete.
+It then resets the PCI card, reconfigures the device BAR's, and
+any bridges underneath. It then calls rpaphp_enable_pci_slot(),
+which restarts the device driver and triggers more user-space
+events (for example, calling "ifup eth0" for ethernet cards).
+
+
+Device Shutdown and User-Space Events
+-------------------------------------
+This section documents what happens when a pci slot is unconfigured,
+focusing on how the device driver gets shut down, and on how the
+events get delivered to user-space scripts.
+
+Following is an example sequence of events that cause a device driver
+close function to be called during the first phase of an EEH reset.
+The following sequence is an example of the pcnet32 device driver.
+
+    rpa_php_unconfig_pci_adapter (struct slot *)  // in rpaphp_pci.c
+    {
+      calls
+      pci_remove_bus_device (struct pci_dev *) // in /drivers/pci/remove.c
+      {
+        calls
+        pci_destroy_dev (struct pci_dev *)
+        {
+          calls
+          device_unregister (&dev->dev) // in /drivers/base/core.c
+          {
+            calls
+            device_del (struct device *)
+            {
+              calls
+              bus_remove_device() // in /drivers/base/bus.c
+              {
+                calls
+                device_release_driver()
+                {
+                  calls
+                  struct device_driver->remove() which is just
+                  pci_device_remove()  // in /drivers/pci/pci_driver.c
+                  {
+                    calls
+                    struct pci_driver->remove() which is just
+                    pcnet32_remove_one() // in /drivers/net/pcnet32.c
+                    {
+                      calls
+                      unregister_netdev() // in /net/core/dev.c
+                      {
+                        calls
+                        dev_close()  // in /net/core/dev.c
+                        {
+                           calls dev->stop();
+                           which is just pcnet32_close() // in pcnet32.c
+                           {
+                             which does what you wanted
+                             to stop the device
+                           }
+                        }
+                     }
+                   which
+                   frees pcnet32 device driver memory
+                }
+     }}}}}}
+
+
+    in drivers/pci/pci_driver.c,
+    struct device_driver->remove() is just pci_device_remove()
+    which calls struct pci_driver->remove() which is pcnet32_remove_one()
+    which calls unregister_netdev()  (in net/core/dev.c)
+    which calls dev_close()  (in net/core/dev.c)
+    which calls dev->stop() which is pcnet32_close()
+    which then does the appropriate shutdown.
+
+---
+Following is the analogous stack trace for events sent to user-space
+when the pci device is unconfigured.
+
+rpa_php_unconfig_pci_adapter() {             // in rpaphp_pci.c
+  calls
+  pci_remove_bus_device (struct pci_dev *) { // in /drivers/pci/remove.c
+    calls
+    pci_destroy_dev (struct pci_dev *) {
+      calls
+      device_unregister (&dev->dev) {      // in /drivers/base/core.c
+        calls
+        device_del(struct device * dev) {  // in /drivers/base/core.c
+          calls
+          kobject_del() {                  //in /libs/kobject.c
+            calls
+            kobject_hotplug() {            // in /libs/kobject.c
+              calls
+              kset_hotplug() {             // in /lib/kobject.c
+                calls
+                kset->hotplug_ops->hotplug() which is really just
+                a call to
+                dev_hotplug() {           // in /drivers/base/core.c
+                  calls
+                  dev->bus->hotplug() which is really just a call to
+                  pci_hotplug () {      // in drivers/pci/hotplug.c
+                    which prints device name, etc....
+                 }
+               }
+               then kset_hotplug() calls
+                call_usermodehelper () with
+                   argv[0]=hotplug_path[] which is "/sbin/hotplug"
+             --> event to userspace,
+           }
+         }
+         kobject_del() then calls sysfs_remove_dir(), which would
+         trigger any user-space daemon that was watching /sysfs,
+         and notice the delete event.
+
+
+Pro's and Con's of the Current Design
+-------------------------------------
+There are several issues with the current EEH software recovery design,
+which may be addressed in future revisions.  But first, note that the
+big plus of the current design is that no changes need to be made to
+individual device drivers, so that the current design throws a wide net.
+The biggest negative of the design is that it potentially disturbs
+network daemons and file systems that didn't need to be disturbed.
+
+-- A minor complaint is that resetting the network card causes
+   user-space back-to-back ifdown/ifup burps that potentially disturb
+   network daemons, that didn't need to even know that the pci
+   card was being rebooted.
+
+-- A more serious concern is that the same reset, for SCSI devices,
+   causes havoc to mounted file systems.  Scripts cannot post-facto
+   unmount a file system without flushing pending buffers, but this
+   is impossible, because I/O has already been stopped.  Thus,
+   ideally, the reset should happen at or below the block layer,
+   so that the file systems are not disturbed.
+
+   Reiserfs does not tolerate errors returned from the block device.
+   Ext3fs seems to be tolerant, retrying reads/writes until it does
+   succeed. Both have been only lightly tested in this scenario.
+
+   The SCSI-generic subsystem already has built-in code for performing
+   SCSI device resets, SCSI bus resets, and SCSI host-bus-adapter
+   (HBA) resets.  These are cascaded into a chain of attempted
+   resets if a SCSI command fails. These are completely hidden
+   from the block layer.  It would be very natural to add an EEH
+   reset into this chain of events.
+
+-- If a SCSI error occurs for the root device, all is lost unless
+   the sysadmin had the foresight to run /bin, /sbin, /etc, /var
+   and so on, out of ramdisk/tmpfs.
+
+
+Conclusions
+-----------
+There's forward progress ...
+
+
diff -Nru a/Documentation/riscom8.txt b/Documentation/riscom8.txt
--- a/Documentation/riscom8.txt	2005-03-01 23:38:51 -08:00
+++ b/Documentation/riscom8.txt	2005-03-01 23:38:51 -08:00
@@ -1,5 +1,12 @@
+* NOTE - this is an unmaintained driver.  The original author cannot be located.
+
+SDL Communications is now SBS Technologies, and does not have any
+information on these ancient ISA cards on their website.
+
+James Nelson <james4765@gmail.com> - 12-12-2004
+
 	This is the README for RISCom/8 multi-port serial driver
-	(C) 1994-1996 D.Gorodchanin (pgmdsg@ibi.com)
+	(C) 1994-1996 D.Gorodchanin
 	See file LICENSE for terms and conditions.
 
 NOTE: English is not my native language. 
@@ -10,47 +17,20 @@
 1) This driver can support up to 4 boards at time.
    Use string "riscom8=0xXXX,0xXXX,0xXXX,0xXXX" at LILO prompt, for
    setting I/O base addresses for boards. If you compile driver
-   as module use insmod options "iobase=0xXXX iobase1=0xXXX iobase2=..."
+   as module use modprobe options "iobase=0xXXX iobase1=0xXXX iobase2=..."
 
 2) The driver partially supports famous 'setserial' program, you can use almost
    any of its options, excluding port & irq settings.
 
 3) There are some misc. defines at the beginning of riscom8.c, please read the 
    comments and try to change some of them in case of problems.
-	
+
 4) I consider the current state of the driver as BETA.
-   If you REALLY think you found a bug, send me e-mail, I hope I'll
-   fix it. For any other problems please ask support@sdlcomm.com.
 
 5) SDL Communications WWW page is http://www.sdlcomm.com.
 
-6) You can use the script at the end of this file to create RISCom/8 devices.
+6) You can use the MAKEDEV program to create RISCom/8 /dev/ttyL* entries.
 
 7) Minor numbers for first board are 0-7, for second 8-15, etc.
 
 22 Apr 1996.
-
--------------------------------cut here-------------------------------------
-#!/bin/bash
-NORMAL_DEVICE=/dev/ttyL
-CALLOUT_DEVICE=/dev/cuL
-NORMAL_MAJOR=48
-CALLOUT_MAJOR=49
-
-echo "Creating devices... "
-for i in 0 1 2 3; do
-	echo "Board No $[$i+1]"
-	for j in 0 1 2 3 4 5 6 7; do
-		k=$[ 8 * $i + $j]
-		rm -f $NORMAL_DEVICE$k 
-		mknod $NORMAL_DEVICE$k c $NORMAL_MAJOR $k
-		chmod a+rw $NORMAL_DEVICE$k
-		echo -n $NORMAL_DEVICE$k" "
-		rm -f $CALLOUT_DEVICE$k 
-		mknod $CALLOUT_DEVICE$k c $CALLOUT_MAJOR $k
-		chmod a+rw $CALLOUT_DEVICE$k
-		echo $CALLOUT_DEVICE$k
-	done
-done
-echo "done."
--------------------------------cut here-------------------------------------
diff -Nru a/Documentation/scsi/ChangeLog b/Documentation/scsi/ChangeLog
--- a/Documentation/scsi/ChangeLog	2005-03-01 23:38:54 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,2023 +0,0 @@
-Sat Jan 18 15:51:45 1997  Richard Henderson  <rth@tamu.edu>
-
-	* Don't play with usage_count directly, instead hand around
-	the module header and use the module macros.
-
-Fri May 17 00:00:00 1996  Leonard N. Zubkoff <lnz@dandelion.com>
-
-	* BusLogic Driver Version 2.0.3 Released.
-
-Tue Apr 16 21:00:00 1996  Leonard N. Zubkoff <lnz@dandelion.com>
-
-	* BusLogic Driver Version 1.3.2 Released.
-
-Sun Dec 31 23:26:00 1995  Leonard N. Zubkoff <lnz@dandelion.com>
-
-	* BusLogic Driver Version 1.3.1 Released.
-
-Fri Nov 10 15:29:49 1995  Leonard N. Zubkoff <lnz@dandelion.com>
-
-	* Released new BusLogic driver.
-
-Wed Aug  9 22:37:04 1995  Andries Brouwer  <aeb@cwi.nl>
-
-	As a preparation for new device code, separated the various
-	functions the request->dev field had into the device proper,
-	request->rq_dev and a status field request->rq_status.
-
-	The 2nd argument of bios_param is now a kdev_t.
-
-Wed Jul 19 10:43:15 1995  Michael Neuffer  <neuffer@goofy.zdv.uni-mainz.de>
-
-        * scsi.c (scsi_proc_info): /proc/scsi/scsi now also lists all
-	attached devices.
-
-	* scsi_proc.c (proc_print_scsidevice): Added. Used by scsi.c and
-	eata_dma_proc.c to produce some device info for /proc/scsi.
-
-	* eata_dma.c (eata_queue)(eata_int_handler)(eata_scsi_done):
-	Changed handling of internal SCSI commands send to the HBA.
-
-
-Wed Jul 19 10:09:17 1995  Michael Neuffer  <neuffer@goofy.zdv.uni-mainz.de>
-
-	* Linux 1.3.11 released.
-
-	* eata_dma.c (eata_queue)(eata_int_handler): Added code to do
-	command latency measurements if requested by root through
-	/proc/scsi interface.
-	Throughout Use HZ constant for time references.
-
-	* eata_pio.c: Use HZ constant for time references.
-
-	* aic7xxx.c, aic7xxx.h, aic7xxx_asm.c: Changed copyright from BSD
-	to GNU style.
-
-	* scsi.h: Added READ_12 command opcode constant
-
-Wed Jul 19 09:25:30 1995  Michael Neuffer <neuffer@goofy.zdv.uni-mainz.de>
-
-	* Linux 1.3.10 released.
-
-	* scsi_proc.c (dispatch_scsi_info): Removed unused variable.
-
-Wed Jul 19 09:25:30 1995  Michael Neuffer  <neuffer@goofy.zdv.uni-mainz.de>
-
-	* Linux 1.3.9 released.
-
-	* scsi.c Blacklist concept expanded to 'support' more device
-	deficiencies. blacklist[] renamed to device_list[]
-	(scan_scsis): Code cleanup.
-
-	* scsi_debug.c (scsi_debug_proc_info): Added support to control
-	device lockup simulation via /proc/scsi interface.
-
-
-Wed Jul 19 09:22:34 1995  Michael Neuffer  <neuffer@goofy.zdv.uni-mainz.de>
-
-	* Linux 1.3.7 released.
-
-	* scsi_proc.c: Fixed a number of bugs in directory handling
-
-Wed Jul 19 09:18:28 1995  Michael Neuffer  <neuffer@goofy.zdv.uni-mainz.de>
-
-	* Linux 1.3.5 released.
-
-	* Native wide, multichannel and /proc/scsi support now in official
-	kernel distribution.
-
-        * scsi.c/h, hosts.c/h et al reindented to increase readability
-	(especially on 80 column wide terminals).
-
-	* scsi.c, scsi_proc.c, ../../fs/proc/inode.c: Added
-	/proc/scsi/scsi which allows root to scan for hotplugged devices.
-
-	* scsi.c (scsi_proc_info): Added, to support /proc/scsi/scsi.
-	(scan_scsis): Added some 'spaghetti' code to allow scanning for
-	single devices.
-	
-
-Thu Jun 20 15:20:27 1995  Michael Neuffer  <neuffer@goofy.zdv.uni-mainz.de>
-
-        * proc.c: Renamed to scsi_proc.c
-
-Mon Jun 12 20:32:45 1995  Michael Neuffer  <neuffer@goofy.zdv.uni-mainz.de>
-
-	* Linux 1.3.0 released.
-
-Mon May 15 19:33:14 1995  Michael Neuffer  <neuffer@goofy.zdv.uni-mainz.de>
-
-	* scsi.c: Added native multichannel and wide scsi support.
-
-	* proc.c (dispatch_scsi_info) (build_proc_dir_hba_entries):
-	Updated /proc/scsi interface.
-
-Thu May  4 17:58:48 1995  Michael Neuffer  <neuffer@goofy.zdv.uni-mainz.de>
-
-	* sd.c (requeue_sd_request): Zero out the scatterlist only if
-	scsi_malloc returned memory for it.
-
-	* eata_dma.c (register_HBA) (eata_queue): Add support for
-	large scatter/gather tables and set use_clustering accordingly
-
-	* hosts.c: Make use_clustering changeable in the Scsi_Host structure.
-
-Wed Apr 12 15:25:52 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.2.5 released.
-
-	* buslogic.c: Update to version 1.15 (From Leonard N. Zubkoff).
-	Fixed interrupt routine to avoid races when handling multiple
-	complete commands per interrupt.  Seems to come up with faster
-	cards.
-
-	* eata_dma.c: Update to 2.3.5r. Modularize. Improved error handling
-        throughout and fixed bug interrupt routine which resulted in shifted
-        status bytes. Added blink LED state checks for ISA and EISA HBAs.
-        Memory management bug seems to have disappeared ==> increasing
-        C_P_L_CURRENT_MAX to 16 for now. Decreasing C_P_L_DIV to 3 for
-        performance reasons.
-
-	* scsi.c: If we get a FMK, EOM, or ILI when attempting to scan
-	the bus, assume that it was just noise on the bus, and ignore
-	the device.
-
-	* scsi.h: Update and add a bunch of missing commands which we
-	were never using.
-
-	* sd.c: Use restore_flags in do_sd_request - this may result in
-	latency conditions, but it gets rid of races and crashes.
-	Do not save flags again when searching for a second command to
-	queue.
-
-	* st.c: Use bytes, not STP->buffer->buffer_size when reading
-	from tape.
-
-
-Tue Apr  4 09:42:08 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.2.4 released.
-
-	* st.c: Fix typo - restoring wrong flags.
-
-Wed Mar 29 06:55:12 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.2.3 released.
-
-	* st.c: Perform some waiting operations with interrupts off.
-	Is this correct???
-
-Wed Mar 22 10:34:26 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.2.2 released.
-
-	* aha152x.c: Modularize.  Add support for PCMCIA.
-
-	* eata.c: Update to version 2.0.  Fixed bug preventing media
-	detection.  If scsi_register_host returns NULL, fail gracefully.
-
-	* scsi.c: Detect as NEC (for photo-cd purposes) for the 84
-	and 25 models as "NEC_OLDCDR".
-
-	* scsi.h: Add define for NEC_OLDCDR
-
-	* sr.c: Add handling for NEC_OLDCDR.  Treat as unknown.
-
-	* u14-34f.c: Update to version 2.0.  Fixed same bug as in
-	eata.c.
-
-
-Mon Mar  6 11:11:20 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.2.0 released.  Yeah!!!
-
-	* Minor spelling/punctuation changes throughout.  Nothing
-	substantive.
-
-Mon Feb 20 21:33:03 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.95 released.
-
-	* qlogic.c: Update to version 0.41.
-
-	* seagate.c: Change some message to be more descriptive about what
-	we detected.
-
-	* sr.c: spelling/whitespace changes.
-
-Mon Feb 20 21:33:03 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.94 released.
-
-Mon Feb 20 08:57:17 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.93 released.
-
-	* hosts.h: Change io_port to long int from short.
-
- 	* 53c7,8xx.c: crash on AEN fixed, SCSI reset is no longer a NOP,
- 	  NULL pointer panic on odd UDCs fixed, two bugs in diagnostic output
- 	  fixed, should initialize correctly if left running, now loadable,
-  	  new memory allocation, extraneous diagnostic output suppressed,
- 	  splx() replaced with save/restore flags. [ Drew ]
-
-	* hosts.c, hosts.h, scsi_ioctl.c, sd.c, sd_ioctl.c, sg.c, sr.c,
-	sr_ioctl.c: Add special junk at end that Emacs will use for
-	formatting the file.
-
-	* qlogic.c: Update to v0.40a.  Improve parity handling.
-
-	* scsi.c: Add Hitachi DK312C to blacklist.  Change "};" to "}" in
-	many places.  Use scsi_init_malloc to get command block - may
-	need this to be dma compatible for some host adapters.
-	Restore interrupts after unregistering a host.
-
-	* sd.c: Use sti instead of restore flags - causes latency problems.
-
-	* seagate.c: Use controller_type to determine string used when
-	registering irq.
-
-	* sr.c: More photo-cd hacks to make sure we get the xa stuff right.
-	* sr.h, sr.c: Change is_xa to xa_flags field.
-
-	* st.c: Disable retries for write operations.
-
-Wed Feb 15 10:52:56 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.92 released.
-
-	* eata.c: Update to 1.17.
-
-	* eata_dma.c: Update to 2.31a. Add more support for /proc/scsi.
-        Continuing modularization. Less crashes because of the bug in the
-        memory management ==> increase C_P_L_CURRENT_MAX to 10
-        and decrease C_P_L_DIV to 4.
-
-	* hosts.c: If we remove last host registered, reuse host number.
-	When freeing memory from host being deregistered, free extra_bytes
-	too.
-
-	* scsi.c (scan_scsis): memset(SDpnt, 0) and set SCmd.device to SDpnt.
-	Change memory allocation to work around bugs in __get_dma_pages.
-	Do not free host if usage count is not zero (for modules).
-
-	* sr_ioctl.c: Increase IOCTL_TIMEOUT to 3000.
-
-	* st.c: Allow for ST_EXTRA_DEVS in st data structures.
-
-	* u14-34f.c: Update to 1.17.
-
-Thu Feb  9 10:11:16 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.91 released.
-
-	* eata.c: Update to 1.16.  Use wish_block instead of host->block.
-
-	* hosts.c: Initialize wish_block to 0.
-
-	* hosts.h: Add wish_block.
-
-	* scsi.c: Use wish_block as indicator that the host should be added
-	to block list.
-
-	* sg.c: Add SG_EXTRA_DEVS to number of slots.
-
-	* u14-34f.c: Use wish_block.
-
-Tue Feb  7 11:46:04 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.90 released.
-
-	* eata.c: Change naming from eata_* to eata2x_*.  Now at vers 1.15.
-	Update interrupt handler to take pt_regs as arg.  Allow blocking
-	even if loaded as module.  Initialize target_time_out array.
-	Do not put sti(); in timing loop.
-
-	* hosts.c: Do not reuse host numbers.
-	Use scsi_make_blocked_list to generate blocking list.
-
-	* script_asm.pl:  Beats me.  Don't know perl.  Something to do with
-	phase index.
-
-	* scsi.c (scsi_make_blocked_list): New function - code copied from
-	hosts.c.
-
-	* scsi.c: Update code to disable photo CD for Toshiba cdroms.
-	Use just manufacturer name, not model number.
-
-	* sr.c: Fix setting density for Toshiba drives.
-
-	* u14-34f.c: Clear target_time_out array during reset.
-
-Wed Feb  1 09:20:45 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.89 released.
-
-	* Makefile, u14-34f.c: Modularize.
-
-	* Makefile, eata.c: Modularize.  Now version 1.14
-
-	* NCR5380.c: Update interrupt handler with new arglist.  Minor
-	cleanups.
-
-	* eata_dma.c: Begin to modularize.  Add hooks for /proc/scsi.
-	New version 2.3.0a. Add code in interrupt handler to allow
-        certain CDROM drivers to be detected which return a
-        CHECK_CONDITION during SCSI bus scan. Add opcode check to get
-        all DATA IN and DATA OUT phases right. Utilize HBA_interpret flag.
-	Improvements in HBA identification. Various other minor stuff.
-
-	* hosts.c: Initialize ->dma_channel and ->io_port when registering
-	a new host.
-
-	* qlogic.c: Modularize and add PCMCIA support.
-
-	* scsi.c: Add Hitachi to blacklist.
-
-	* scsi.c: Change default to no lun scan (too many problem devices).
-
-	* scsi.h: Define QUEUE_FULL condition.
-
-	* sd.c: Do not check for non-existent partition until after
-	new media check.
-
-	* sg.c: Undo previous change which was wrong.
-
-	* sr_ioctl.c: Increase IOCTL_TIMEOUT to 2000.
-
-	* st.c: Patches from Kai - improve filemark handling.
-
-Tue Jan 31 17:32:12 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.88 released.
-
-	* Throughout - spelling/grammar fixups.
-
-	* scsi.c: Make sure that all buffers are 16 byte aligned - some
-	drivers (buslogic) need this.
-
-	* scsi.c (scan_scsis): Remove message printed.
-
-	* scsi.c (scsi_init): Move message here.
-
-Mon Jan 30 06:40:25 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.87 released.
-
-	* sr.c: Photo-cd related changes. (Gerd Knorr??).
-
-	* st.c: Changes from Kai related to EOM detection.
-
-Mon Jan 23 23:53:10 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.86 released.
-
-	* 53c7,8xx.h: Change SG size to 127.
-
-	* eata_dma: Update to version 2.10i. Remove bug in the registration
-        of multiple HBAs and channels. Minor other improvements and stylistic
-        changes.
-
-	* scsi.c: Test for Toshiba XM-3401TA and exclude from detection
-	as toshiba drive - photo cd does not work with this drive.
-
-	* sr.c:  Update photocd code.
-
-Mon Jan 23 23:53:10 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.85 released.
-
-	* st.c, st_ioctl.c, sg.c, sd_ioctl.c, scsi_ioctl.c, hosts.c:
-	include linux/mm.h
-
-	* qlogic.c, buslogic.c, aha1542.c: Include linux/module.h.
-
-Sun Jan 22 22:08:46 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.84 released.
-
-	* Makefile: Support for loadable QLOGIC boards.
-
-	* aha152x.c: Update to version 1.8 from Juergen.
-
-	* eata_dma.c: Update from Michael Neuffer.
-        Remove hard limit of 2 commands per lun and make it better
-        configurable. Improvements in HBA identification.
-
-	* in2000.c: Fix biosparam to support large disks.
-
-	* qlogic.c: Minor changes (change sti -> restore_flags).
-
-Wed Jan 18 23:33:09 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.83 released.
-
-	* aha1542.c(aha1542_intr_handle): Use arguments handed down to find
-	which irq.
-
-	* buslogic.c: Likewise.
-
-	* eata_dma.c: Use min of 2 cmd_per_lun for OCS_enabled boards.
-
-	* scsi.c: Make RECOVERED_ERROR a SUGGEST_IS_OK.
-
-	* sd.c: Fail if we are opening a non-existent partition.
-
-	* sr.c: Bump SR_TIMEOUT to 15000.
-	Do not probe for media size at boot time(hard on changers).
-	Flag device as needing sector size instead.
-
-	* sr_ioctl.c: Remove CDROMMULTISESSION_SYS ioctl.
-
-	* ultrastor.c: Fix bug in call to ultrastor_interrupt (wrong #args).
-
-Mon Jan 16 07:18:23 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.82 released.
-
-	Throughout.
-	- Change all interrupt handlers to accept new calling convention.
-	In particular, we now receive the irq number as one of the arguments.
-
-	* More minor spelling corrections in some of the new files.
-
-	* aha1542.c, buslogic.c: Clean up interrupt handler a little now
-	that we receive the irq as an arg.
-
-	* aha274x.c: s/snarf_region/request_region/
-
-	* eata.c: Update to version 1.12.   Fix some comments and display a
-	message if we cannot reserve the port addresses.
-
-	* u14-34f.c: Update to version 1.13.   Fix some comments and display a
-	message if we cannot reserve the port addresses.
-
-	* eata_dma.c: Define get_board_data function (send INQUIRY command).
-	Use to improve detection of variants of different DPT boards.  Change
-	version subnumber to "0g".
-
-	* fdomain.c:  Update to version 5.26.  Improve detection of some boards
-	repackaged by IBM.
-
-	* scsi.c (scsi_register_host): Change "name" to const char *.
-
-	* sr.c: Fix problem in set mode command for Toshiba drives.
-
-	* sr.c: Fix typo from patch 81.
-
-Fri Jan 13 12:54:46 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.81 released.  Codefreeze for 1.2 release announced.
-
-	Big changes here.
-
-	* eata_dma.*: New files from Michael Neuffer.
-	(neuffer@goofy.zdv.uni-mainz.de).  Should support
-	all eata/dpt cards.
-
-	* hosts.c, Makefile: Add eata_dma.
-
-	* README.st: Document MTEOM.
-
-	Patches from me (ERY) to finish support for low-level loadable scsi.
-	It now works, and is actually useful.
-
-	* Throughout - add new argument to scsi_init_malloc that takes an
-	additional parameter.  This is used as a priority to kmalloc,
-	and you can specify the GFP_DMA flag if you need DMA-able memory.
-
-	* Makefile: For source files that are loadable, always add name
-	to SCSI_SRCS.  Fill in modules: target.
-
-	* hosts.c:  Change next_host to next_scsi_host, and make global.
-	Print hosts after we have identified all of them.  Use info()
-	function if present, otherwise use name field.
-
-	* hosts.h: Change attach function to return int, not void.
-	Define number of device slots to allow for loadable devices.
-	Define tags to tell scsi module code what type of module we
-	are loading.
-
-	* scsi.c: Fix scan_scsis so that it can be run by a user process.
-	Do not use waiting loops - use up and down mechanism as long
-	as current != task[0].
-
-	* scsi.c(scan_scsis): Do not use stack variables for I/O - this
-	could be > 16Mb if we are loading a module at runtime (i.e. use
-	scsi_init_malloc to get some memory we know will be safe).
-
-	* scsi.c: Change dma freelist to be a set of pages.  This allows
-	us to dynamically adjust the size of the list by adding more pages
-	to the pagelist.  Fix scsi_malloc and scsi_free accordingly.
-
-	* scsi_module.c: Fix include.
-
-	* sd.c: Declare detach function.  Increment/decrement module usage
-	count as required.  Fix init functions to allow loaded devices.
-	Revalidate all new disks so we get the partition tables.  Define
-	detach function.
-
-	* sr.c: Likewise.
-
-	* sg.c: Declare detach function.  Allow attachment of devices on
-	loaded drivers.
-
-	* st.c: Declare detach function.  Increment/decrement module usage
-	count as required.
-
-Tue Jan 10 10:09:58 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.79 released.
-
-	Patch from some undetermined individual who needs to get a life :-).
-
-	* sr.c: Attacked by spelling bee...
-
-	Patches from Gerd Knorr:
-
-	* sr.c: make printk messages for photoCD a little more informative.
-
-	* sr_ioctl.c: Fix CDROMMULTISESSION_SYS ioctl.
-
-Mon Jan  9 10:01:37 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.78 released.
-
-	* Makefile: Add empty modules: target.
-
-	* Wheee.  Now change register_iomem to request_region.
-
-	* in2000.c: Bugfix - apparently this is the fix that we have
-	all been waiting for.  It fixes a problem whereby the driver
-	is not stable under heavy load.  Race condition and all that.
-	Patch from Peter Lu.
-
-Wed Jan  4 21:17:40 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.77 released.
-
-	* 53c7,8xx.c: Fix from Linus - emulate splx.
-
-	Throughout:
-
-		Change "snarf_region" with "register_iomem".
-
-	* scsi_module.c: New file.  Contains support for low-level loadable
-	  scsi drivers. [ERY].
-
-	* sd.c: More s/int/long/ changes.
-
-	* seagate.c: Explicitly include linux/config.h
-
-	* sg.c: Increment/decrement module usage count on open/close.
-
-	* sg.c: Be a bit more careful about the user not supplying enough
-	  information for a valid command.  Pass correct size down to
-	  scsi_do_cmd.
-
-	* sr.c:  More changes for Photo-CD.  This apparently breaks NEC drives.
-
-	* sr_ioctl.c:  Support CDROMMULTISESSION ioctl.
-
-
-Sun Jan  1 19:55:21 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.76 released.
-
-	* constants.c: Add type cast in switch statement.
-
-	* scsi.c (scsi_free): Change datatype of "offset" to long.
-	  (scsi_malloc): Change a few more variables to long.  Who
-	  did this and why was it important?  64 bit machines?
-
-
-	Lots of changes to use save_state/restore_state instead of cli/sti.
-	Files changed include:
-
-	* aha1542.c:
-	* aha1740.c:
-	* buslogic.c:
-	* in2000.c:
-	* scsi.c:
-	* scsi_debug.c:
-	* sd.c:
-	* sr.c:
-	* st.c:
-
-Wed Dec 28 16:38:29 1994  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.75 released.
-
-	* buslogic.c: Spelling fix.
-
-	* scsi.c: Add HP C1790A and C2500A scanjet to blacklist.
-
-	* scsi.c: Spelling fixup.
-
-	* sd.c: Add support for sd_hardsizes (hard sector sizes).
-
-	* ultrastor.c: Use save_flags/restore_flags instead of cli/sti.
-
-Fri Dec 23 13:36:25 1994  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.74 released.
-
-	* README.st: Update from Kai Makisara.
-
-	* eata.c: New version from Dario - version 1.11.
-	  use scsicam bios_param routine.  Add support for 2011
-	  and 2021 boards.
-
-	* hosts.c: Add support for blocking.  Linked list automatically
-	  generated when shpnt->block is set.
-
-	* scsi.c: Add sankyo & HP scanjet to blacklist.  Add support for
-	  kicking things loose when we deadlock.
-
-	* scsi.c: Recognize scanners and processors in scan_scsis.
-
-	* scsi_ioctl.h: Increase timeout to 9 seconds.
-
-	* st.c: New version from Kai - add better support for backspace.
-
-	* u14-34f.c: New version from Dario.  Supports blocking.
-
-Wed Dec 14 14:46:30 1994  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.73 released.
-
-	* buslogic.c: Update from Dave Gentzel.  Version 1.14.
-	  Add module related stuff.   More fault tolerant if out of
-	  DMA memory.
-
-	* fdomain.c: New version from Rik Faith - version 5.22.  Add support
-	  for ISA-200S SCSI adapter.
-
-	* hosts.c: Spelling.
-
-	* qlogic.c: Update to version 0.38a.  Add more support for PCMCIA.
-
-	* scsi.c: Mask device type with 0x1f during scan_scsis.
-	  Add support for deadlocking, err, make that getting out of
-	  deadlock situations that are created when we allow the user
-	  to limit requests to one host adapter at a time.
-
-	* scsi.c: Bugfix - pass pid, not SCpnt as second arg to
-	  scsi_times_out.
-
-	* scsi.c: Restore interrupt state to previous value instead of using
-	  cli/sti pairs.
-
-	* scsi.c: Add a bunch of module stuff (all commented out for now).
-
-	* scsi.c: Clean up scsi_dump_status.
-
-Tue Dec  6 12:34:20 1994  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.72 released.
-
-	* sg.c: Bugfix - always use sg_free, since we might have big buff.
-
-Fri Dec  2 11:24:53 1994  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.71 released.
-
-	* sg.c: Clear buff field when not in use.  Only call scsi_free if
-	non-null.
-
-	* scsi.h: Call wake_up(&wait_for_request) when done with a
-	command.
-
-	* scsi.c (scsi_times_out): Pass pid down so that we can protect
-	against race conditions.
-
-	* scsi.c (scsi_abort): Zero timeout field if we get the
-	NOT_RUNNING message back from low-level driver.
-
-
-	* scsi.c (scsi_done): Restore cmd_len, use_sg here.
-
-	* scsi.c (request_sense): Not here.
-
-	* hosts.h: Add new forbidden_addr, forbidden_size fields.  Who
-	added these and why????
-
-	* hosts.c (scsi_mem_init): Mark pages as reserved if they fall in
-	the forbidden regions.  I am not sure - I think this is so that
-	we can deal with boards that do incomplete decoding of their
-	address lines for the bios chips, but I am not entirely sure.
-
-	* buslogic.c: Set forbidden_addr stuff if using a buggy board.
-
-	* aha1740.c: Test for NULL pointer in SCtmp.  This should not
-	occur, but a nice message is better than a kernel segfault.
-
-	* 53c7,8xx.c: Add new PCI chip ID for 815.
-
-Fri Dec  2 11:24:53 1994  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.70 released.
-
-	* ChangeLog, st.c: Spelling.
-
-Tue Nov 29 18:48:42 1994  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.69 released.
-
-	* u14-34f.h: Non-functional change.  [Dario].
-
-	* u14-34f.c: Use block field in Scsi_Host to prevent commands from
-	being queued to more than one host at the same time (used when
-	motherboard does not deal with multiple bus-masters very well).
-	Only when SINGLE_HOST_OPERATIONS is defined.
-	Use new cmd_per_lun field.  [Dario]
-
-	* eata.c: Likewise.
-
-	* st.c: More changes from Kai.  Add ready flag to indicate drive
-	status.
-
-	* README.st: Document this.
-
-	* sr.c: Bugfix (do not subtract CD_BLOCK_OFFSET) for photo-cd
-	code.
-
-	* sg.c: Bugfix - fix problem where opcode is not correctly set up.
-
-	* seagate.[c,h]: Use #defines to set driver name.
-
-	* scsi_ioctl.c: Zero buffer before executing command.
-
-	* scsi.c: Use new cmd_per_lun field in Scsi_Hosts as appropriate.
-	Add Sony CDU55S to blacklist.
-
-	* hosts.h: Add new cmd_per_lun field to Scsi_Hosts.
-
-	* hosts.c: Initialize cmd_per_lun in Scsi_Hosts from template.
-
-	* buslogic.c: Use cmd_per_lun field - initialize to different
-	values depending upon bus type (i.e. use 1 if ISA, so we do not
-	hog memory).  Use other patches which got lost from 1.1.68.
-
-	* aha1542.c: Spelling.
-
-Tue Nov 29 15:43:50 1994  Eric Youngdale  (eric@andante.aib.com)
-
-	* Linux 1.1.68 released.
-
-	Add support for 12 byte vendor specific commands in scsi-generics,
-	more (i.e. the last mandatory) low-level changes to support
-	loadable modules, plus a few other changes people have requested
-	lately.  Changes by me (ERY) unless otherwise noted.  Spelling
-	changes appear from some unknown corner of the universe.
-
-	* Throughout: Change COMMAND_SIZE() to use SCpnt->cmd_len.
-
-	* Throughout: Change info() low level function to take a Scsi_Host
-	pointer.  This way the info function can return specific
-	information about the host in question, if desired.
-
-	* All low-level drivers: Add NULL in initializer for the
-	usage_count field added to Scsi_Host_Template.
-
-	* aha152x.[c,h]: Remove redundant info() function.
-
-	* aha1542.[c,h]: Likewise.
-
-	* aha1740.[c,h]: Likewise.
-
-	* aha274x.[c,h]: Likewise.
-
-	* eata.[c,h]: Likewise.
-
-	* pas16.[c,h]: Likewise.
-
-	* scsi_debug.[c,h]: Likewise.
-
-	* t128.[c,h]: Likewise.
-
-	* u14-34f.[c,h]: Likewise.
-
-	* ultrastor.[c,h]: Likewise.
-
-	* wd7000.[c,h]: Likewise.
-
-	* aha1542.c: Add support for command line options with lilo to set
-	DMA parameters, I/O port.  From Matt Aarnio.
-
-	* buslogic.[c,h]: New version (1.13) from Dave Gentzel.
-
-	* hosts.h: Add new field to Scsi_Hosts "block" to allow blocking
-	all I/O to certain other cards.  Helps prevent problems with some
-	ISA motherboards.
-
-	* hosts.h: Add usage_count to Scsi_Host_Template.
-
-	* hosts.h: Add n_io_port to Scsi_Host (used when releasing module).
-
-	* hosts.c: Initialize block field.
-
-	* in2000.c: Remove "static" declarations from exported functions.
-
-	* in2000.h: Likewise.
-
-	* scsi.c: Correctly set cmd_len field as required.  Save and
-	change setting when doing a request_sense, restore when done.
-	Move abort timeout message.  Fix panic in request_queueable to
-	print correct function name.
-
-	* scsi.c: When incrementing usage count, walk block linked list
-	for host, and or in SCSI_HOST_BLOCK bit.  When decrementing usage
-	count to 0, clear this bit to allow usage to continue, wake up
-	processes waiting.
-
-
-	* scsi_ioctl.c: If we have an info() function, call it, otherwise
-	if we have a "name" field, use it, else do nothing.
-
-	* sd.c, sr.c: Clear cmd_len field prior to each command we
-	generate.
-
-	* sd.h: Add "has_part_table" bit to rscsi_disks.
-
-	* sg.[c,h]: Add support for vendor specific 12 byte commands (i.e.
-	override command length in COMMAND_SIZE).
-
-	* sr.c: Bugfix from Gerd in photocd code.
-
-	* sr.c: Bugfix in get_sectorsize - always use scsi_malloc buffer -
-	we cannot guarantee that the stack is < 16Mb.
-
-Tue Nov 22 15:40:46 1994  Eric Youngdale  (eric@andante.aib.com)
-
-	* Linux 1.1.67 released.
-
-	* sr.c: Change spelling of manufactor to manufacturer.
-
-	* scsi.h: Likewise.
-
-	* scsi.c: Likewise.
-
-	* qlogic.c: Spelling corrections.
-
-	* in2000.h: Spelling corrections.
-
-	* in2000.c: Update from Bill Earnest, change from
-	jshiffle@netcom.com.  Support new bios versions.
-
-	* README.qlogic: Spelling correction.
-
-Tue Nov 22 15:40:46 1994  Eric Youngdale  (eric@andante.aib.com)
-
-	* Linux 1.1.66 released.
-
-	* u14-34f.c: Spelling corrections.
-
-	* sr.[h,c]: Add support for multi-session CDs from Gerd Knorr.
-
-	* scsi.h: Add manufactor field for keeping track of device
-	manufacturer.
-
-	* scsi.c: More spelling corrections.
-
-	* qlogic.h, qlogic.c, README.qlogic: New driver from Tom Zerucha.
-
-	* in2000.c, in2000.h: New driver from Brad McLean/Bill Earnest.
-
-	* fdomain.c: Spelling correction.
-
-	* eata.c: Spelling correction.
-
-Fri Nov 18 15:22:44 1994  Eric Youngdale  (eric@andante.aib.com)
-
-	* Linux 1.1.65 released.
-
-	* eata.h: Update version string to 1.08.00.
-
-	* eata.c: Set sg_tablesize correctly for DPT PM2012 boards.
-
-	* aha274x.seq: Spell checking.
-
-	* README.st: Likewise.
-
-	* README.aha274x: Likewise.
-
-	* ChangeLog: Likewise.
-
-Tue Nov 15 15:35:08 1994  Eric Youngdale  (eric@andante.aib.com)
-
-	* Linux 1.1.64 released.
-
-	* u14-34f.h: Update version number to 1.10.01.
-
-	* u14-34f.c: Use Scsi_Host can_queue variable instead of one from template.
-
-	* eata.[c,h]: New driver for DPT boards from Dario Ballabio.
-
-	* buslogic.c: Use can_queue field.
-
-Wed Nov 30 12:09:09 1994  Eric Youngdale  (eric@andante.aib.com)
-
-	* Linux 1.1.63 released.
-
-	* sd.c: Give I/O error if we attempt 512 byte I/O to a disk with
-	1024 byte sectors.
-
-	* scsicam.c: Make sure we do read from whole disk (mask off
-	partition).
-
-	* scsi.c: Use can_queue in Scsi_Host structure.
-	Fix panic message about invalid host.
-
-	* hosts.c: Initialize can_queue from template.
-
-	* hosts.h: Add can_queue to Scsi_Host structure.
-
-	* aha1740.c: Print out warning about NULL ecbptr.
-
-Fri Nov  4 12:40:30 1994  Eric Youngdale  (eric@andante.aib.com)
-
-	* Linux 1.1.62 released.
-
-	* fdomain.c: Update to version 5.20. (From Rik Faith).  Support
-	BIOS version 3.5.
-
-	* st.h: Add ST_EOD symbol.
-
-	* st.c: Patches from Kai Makisara - support additional densities,
-	add support for MTFSS, MTBSS, MTWSM commands.
-
-	* README.st: Update to document new commands.
-
-	* scsi.c: Add Mediavision CDR-H93MV to blacklist.
-
-Sat Oct 29 20:57:36 1994  Eric Youngdale  (eric@andante.aib.com)
-
-	* Linux 1.1.60 released.
-
-	* u14-34f.[c,h]: New driver from Dario Ballabio.
-
-	* aic7770.c, aha274x_seq.h, aha274x.seq, aha274x.h, aha274x.c,
-	README.aha274x: New files, new driver from John Aycock.
-
-
-Tue Oct 11 08:47:39 1994  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.54 released.
-
-	* Add third PCI chip id.  [Drew]
-
-	* buslogic.c: Set BUSLOGIC_CMDLUN back to 1 [Eric].
-
-	* ultrastor.c: Fix asm directives for new GCC.
-
-	* sr.c, sd.c: Use new end_scsi_request function.
-
-	* scsi.h(end_scsi_request): Return pointer to block if still
-	active, else return NULL if inactive.  Fixes race condition.
-
-Sun Oct  9 20:23:14 1994  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.53 released.
-
-	* scsi.c: Do not allocate dma bounce buffers if we have exactly
-	16Mb.
-
-Fri Sep  9 05:35:30 1994  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.51 released.
-
-	* aha152x.c: Add support for disabling the parity check.  Update
-	to version 1.4. [Juergen].
-
-	* seagate.c: Tweak debugging message.
-
-Wed Aug 31 10:15:55 1994  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.50 released.
-
-	* aha152x.c: Add eb800 for Vtech Platinum SMP boards. [Juergen].
-
-	* scsi.c: Add Quantum PD1225S to blacklist.
-
-Fri Aug 26 09:38:45 1994  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.49 released.
-
-	* sd.c: Fix bug when we were deleting the wrong entry if we
-	get an unsupported sector size device.
-
-	* sr.c: Another spelling patch.
-
-Thu Aug 25 09:15:27 1994  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.48 released.
-
-	* Throughout: Use new semantics for request_dma, as appropriate.
-
-	* sr.c: Print correct device number.
-
-Sun Aug 21 17:49:23 1994  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.47 released.
-
-	* NCR5380.c: Add support for LIMIT_TRANSFERSIZE.
-
-	* constants.h: Add prototype for print_Scsi_Cmnd.
-
-	* pas16.c: Some more minor tweaks.  Test for Mediavision board.
-	Allow for disks > 1Gb.  [Drew??]
-
-	* sr.c: Set SCpnt->transfersize.
-
-Tue Aug 16 17:29:35 1994  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.46 released.
-
-	* Throughout: More spelling fixups.
-
-	* buslogic.c: Add a few more fixups from Dave.  Disk translation
-	mainly.
-
-	* pas16.c: Add a few patches (Drew?).
-
-
-Thu Aug 11 20:45:15 1994  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.44 released.
-
-	* hosts.c: Add type casts for scsi_init_malloc.
-
-	* scsicam.c: Add type cast.
-
-Wed Aug 10 19:23:01 1994  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.43 released.
-
-	* Throughout: Spelling cleanups. [??]
-
-	* aha152x.c, NCR53*.c, fdomain.c, g_NCR5380.c, pas16.c, seagate.c,
-	 t128.c: Use request_irq, not irqaction. [??]
-
-	* aha1542.c: Move test for shost before we start to use shost.
-
-	* aha1542.c, aha1740.c, ultrastor.c, wd7000.c: Use new
-	calling sequence for request_irq.
-
-	* buslogic.c: Update from Dave Gentzel.
-
-Tue Aug  9 09:32:59 1994  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.42 released.
-
-	* NCR5380.c: Change NCR5380_print_status to static.
-
-	* seagate.c: A few more bugfixes.  Only Drew knows what they are
-	for.
-
-	* ultrastor.c: Tweak some __asm__ directives so that it works
-	with newer compilers. [??]
-
-Sat Aug  6 21:29:36 1994  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.40 released.
-
-	* NCR5380.c: Return SCSI_RESET_WAKEUP from reset function.
-
-	* aha1542.c: Reset mailbox status after a bus device reset.
-
-	* constants.c: Fix typo (;;).
-
-	* g_NCR5380.c:
-	* pas16.c:  Correct usage of NCR5380_init.
-
-	* scsi.c: Remove redundant (and unused variables).
-
-	* sd.c: Use memset to clear all of rscsi_disks before we use it.
-
-	* sg.c: Ditto, except for scsi_generics.
-
-	* sr.c: Ditto, except for scsi_CDs.
-
-	* st.c: Initialize STp->device.
-
-	* seagate.c: Fix bug. [Drew]
-
-Thu Aug  4 08:47:27 1994  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.39 released.
-
-	* Makefile: Fix typo in NCR53C7xx.
-
-	* st.c: Print correct number for device.
-
-Tue Aug  2 11:29:14 1994  Eric Youngdale  (eric@esp22)
-
-	* Linux 1.1.38 released.
-
-	Lots of changes in 1.1.38.  All from Drew unless otherwise noted.
-
-	* 53c7,8xx.c: New file from Drew.  PCI driver.
-
-	* 53c7,8xx.h: Likewise.
-
-	* 53c7,8xx.scr: Likewise.
-
-	* 53c8xx_d.h, 53c8xx_u.h, script_asm.pl: Likewise.
-
-	* scsicam.c: New file from Drew.  Read block 0 on the disk and
-	read the partition table.  Attempt to deduce the geometry from
-	the partition table if possible.  Only used by 53c[7,8]xx right
-	now, but could be used by any device for which we have no way
-	of identifying the geometry.
-
-	* sd.c: Use device letters instead of sd%d in a lot of messages.
-
-	* seagate.c: Fix bug that resulted in lockups with some devices.
-
-	* sr.c (sr_open): Return -EROFS, not -EACCES if we attempt to open
-	device for write.
-
-	* hosts.c, Makefile: Update for new driver.
-
-	* NCR5380.c, NCR5380.h, g_NCR5380.h: Update from Drew to support
-	53C400 chip.
-
-	* constants.c: Define CONST_CMND and CONST_MSG.  Other minor
-	cleanups along the way.  Improve handling of CONST_MSG.
-
-	* fdomain.c, fdomain.h: New version from Rik Faith.  Update to
-	5.18.  Should now support TMC-3260 PCI card with 18C30 chip.
-
-	* pas16.c: Update with new irq initialization.
-
-	* t128.c: Update with minor cleanups.
-
-	* scsi.c (scsi_pid): New variable - gives each command a unique
-	id. Add Quantum LPS5235S to blacklist.  Change in_scan to
-	in_scan_scsis and make global.
-
-	* scsi.h: Add some defines for extended message handling,
-	INITIATE/RELEASE_RECOVERY.  Add a few new fields to support sync
-	transfers.
-
-	* scsi_ioctl.h: Add ioctl to request synchronous transfers.
-
-
-Tue Jul 26 21:36:58 1994  Eric Youngdale  (eric@esp22)
-
-	* Linux 1.1.37 released.
-
-	* aha1542.c: Always call aha1542_mbenable, use new udelay
-	mechanism so we do not wait a long time if the board does not
-	implement this command.
-
-	* g_NCR5380.c: Remove #include <linux/config.h> and #if
-	defined(CONFIG_SCSI_*).
-
-	* seagate.c: Likewise.
-
-	Next round of changes to support loadable modules.  Getting closer
-	now, still not possible to do anything remotely usable.
-
-	hosts.c: Create a linked list of detected high level devices.
-	(scsi_register_device): New function to insert into this list.
-	(scsi_init): Call scsi_register_device for each of the known high
-	level drivers.
-
-	hosts.h: Add prototype for linked list header.  Add structure
-	definition for device template structure which defines the linked
-	list.
-
-	scsi.c: (scan_scsis): Use linked list instead of knowledge about
-	existing high level device drivers.
-	(scsi_dev_init): Use init functions for drivers on linked list
-	instead of explicit list to initialize and attach devices to high
-	level drivers.
-
-	scsi.h: Add new field "attached" to scsi_device - count of number
-	of high level devices attached.
-
-	sd.c, sr.c, sg.c, st.c: Adjust init/attach functions to use new
-	scheme.
-
-Sat Jul 23 13:03:17 1994  Eric Youngdale  (eric@esp22)
-
-	* Linux 1.1.35 released.
-
-	* ultrastor.c: Change constraint on asm() operand so that it works
-	with gcc 2.6.0.
-
-Thu Jul 21 10:37:39 1994  Eric Youngdale  (eric@esp22)
-
-	* Linux 1.1.33 released.
-
-	* sr.c(sr_open): Do not allow opens with write access.
-
-Mon Jul 18 09:51:22 1994 1994  Eric Youngdale  (eric@esp22)
-
-	* Linux 1.1.31 released.
-
-	* sd.c: Increase SD_TIMEOUT from 300 to 600.
-
-	* sr.c: Remove stray task_struct* variable that was no longer
-	used.
-
-	* sr_ioctl.c: Fix typo in up() call.
-
-Sun Jul 17 16:25:29 1994  Eric Youngdale  (eric@esp22)
-
-	* Linux 1.1.30 released.
-
-	* scsi.c (scan_scsis): Fix detection of some Toshiba CDROM drives
-	that report themselves as disk drives.
-
-	* (Throughout): Use request.sem instead of request.waiting.
-	Should fix swap problem with fdomain.
-
-Thu Jul 14 10:51:42 1994  Eric Youngdale  (eric@esp22)
-
-	* Linux 1.1.29 released.
-
-	* scsi.c (scan_scsis): Add new devices to end of linked list, not
-	to the beginning.
-
-	* scsi.h (SCSI_SLEEP): Remove brain dead hack to try to save
-	the task state before sleeping.
-
-Sat Jul  9 15:01:03 1994  Eric Youngdale  (eric@esp22)
-
-	More changes to eventually support loadable modules.  Mainly
-	we want to use linked lists instead of arrays because it is easier
-	to dynamically add and remove things this way.
-
-	Quite a bit more work is needed before loadable modules are
-	possible (and usable) with scsi, but this is most of the grunge
-	work.
-
-	* Linux 1.1.28 released.
-
-	* scsi.c, scsi.h (allocate_device, request_queueable): Change
-	argument from index into scsi_devices to a pointer to the
-	Scsi_Device struct.
-
-	* Throughout: Change all calls to allocate_device,
-	request_queueable to use new calling sequence.
-
-	* Throughout: Use SCpnt->device instead of
-	scsi_devices[SCpnt->index].  Ugh - the pointer was there all along
-	- much cleaner this way.
-
-	* scsi.c (scsi_init_malloc, scsi_free_malloc): New functions -
-	allow us to pretend that we have a working malloc when we
-	initialize.  Use this instead of passing memory_start, memory_end
-	around all over the place.
-
-	* scsi.h, st.c, sr.c, sd.c, sg.c: Change *_init1 functions to use
-	scsi_init_malloc, remove all arguments, no return value.
-
-	* scsi.h: Remove index field from Scsi_Device and Scsi_Cmnd
-	structs.
-
-	* scsi.c (scsi_dev_init): Set up for scsi_init_malloc.
-	(scan_scsis): Get SDpnt from scsi_init_malloc, and refresh
-	when we discover a device.  Free pointer before returning.
-	Change scsi_devices into a linked list.
-
-	* scsi.c (scan_scsis): Change to only scan one host.
-	(scsi_dev_init): Loop over all detected hosts, and scan them.
-
-	* hosts.c  (scsi_init_free): Change so that  number of extra bytes
-	is stored in struct, and we do not have to pass it each time.
-
-	* hosts.h: Change Scsi_Host_Template struct to include "next" and
-	"release" functions.  Initialize to NULL in all low level
-	adapters.
-
-	* hosts.c: Rename scsi_hosts to builtin_scsi_hosts, create linked
-	list scsi_hosts, linked together with the new "next" field.
-
-Wed Jul  6 05:45:02 1994  Eric Youngdale  (eric@esp22)
-
-	* Linux 1.1.25 released.
-
-	* aha152x.c: Changes from Juergen - cleanups and updates.
-
-	* sd.c, sr.c: Use new check_media_change and revalidate
-	file_operations fields.
-
-	* st.c, st.h: Add changes from Kai Makisara, dated Jun 22.
-
-	* hosts.h: Change SG_ALL back to 0xff.  Apparently soft error
-	in /dev/brain resulted in having this bumped up.
-	Change first parameter in bios_param function to be Disk * instead
-	of index into rscsi_disks.
-
-	* sd_ioctl.c: Pass pointer to rscsi_disks element instead of index
-	to array.
-
-	* sd.h: Add struct name "scsi_disk" to typedef for Scsi_Disk.
-
-	* scsi.c: Remove redundant Maxtor XT8760S from blacklist.
-	In scsi_reset, add printk when DEBUG defined.
-
-	* All low level drivers: Modify definitions of bios_param in
-	appropriate way.
-
-Thu Jun 16 10:31:59 1994  Eric Youngdale  (eric@esp22)
-
-	* Linux 1.1.20 released.
-
-	* scsi_ioctl.c: Only pass down the actual number of characters
-	required to scsi_do_cmd, not the one rounded up to a even number
-	of sectors.
-
-	* ultrastor.c: Changes from Caleb Epstein for 24f cards.  Support
-	larger SG lists.
-
-	* ultrastor.c: Changes from me - use scsi_register to register
-	host.  Add some consistency checking,
-
-Wed Jun  1 21:12:13 1994  Eric Youngdale  (eric@esp22)
-
-	* Linux 1.1.19 released.
-
-	* scsi.h: Add new return code for reset() function:
-	SCSI_RESET_PUNT.
-
-	* scsi.c: Make SCSI_RESET_PUNT the same as SCSI_RESET_WAKEUP for
-	now.
-
-	* aha1542.c: If the command responsible for the reset is not
-	pending, return SCSI_RESET_PUNT.
-
-	* aha1740.c, buslogic.c, wd7000.c, ultrastor.c: Return
-	SCSI_RESET_PUNT instead of SCSI_RESET_SNOOZE.
-
-Tue May 31 19:36:01 1994  Eric Youngdale  (eric@esp22)
-
-	* buslogic.c: Do not print out message about "must be Adaptec"
-	if we have detected a buslogic card.  Print out a warning message
-	if we are configuring for >16Mb, since the 445S at board level
-	D or earlier does not work right.  The "D" level board can be made
-	to work by flipping an undocumented switch, but this is too subtle.
-
-    Changes based upon patches in Yggdrasil distribution.
-
-	* sg.c, sg.h: Return sense data to user.
-
-	* aha1542.c, aha1740.c, buslogic.c: Do not panic if
-	sense buffer is wrong size.
-
-	* hosts.c: Test for ultrastor card before any of the others.
-
-	* scsi.c: Allow boot-time option for max_scsi_luns=? so that
-	buggy firmware has an easy work-around.
-
-Sun May 15 20:24:34 1994  Eric Youngdale  (eric@esp22)
-
-	* Linux 1.1.15 released.
-
-	Post-codefreeze thaw...
-
-	* buslogic.[c,h]: New driver from David Gentzel.
-
-	* hosts.h: Add use_clustering field to explicitly say whether
-	clustering should be used for devices attached to this host
-	adapter.  The buslogic board apparently supports large SG lists,
-	but it is apparently faster if sd.c condenses this into a smaller
-	list.
-
-	* sd.c: Use this field instead of heuristic.
-
-	* All host adapter include files: Add appropriate initializer for
-	use_clustering field.
-
-	* scsi.h: Add #defines for return codes for the abort and reset
-	functions.  There are now a specific set of return codes to fully
-	specify all of the possible things that the low-level adapter
-	could do.
-
-	* scsi.c: Act based upon return codes from abort/reset functions.
-
-	* All host adapter abort/reset functions: Return new return code.
-
-	* Add code in scsi.c to help debug timeouts.  Use #define
-	DEBUG_TIMEOUT to enable this.
-
-	* scsi.c: If the host->irq field is set, use
-	disable_irq/enable_irq before calling queuecommand if we
-	are not already in an interrupt.  Reduce races, and we
-	can be sloppier about cli/sti in the interrupt routines now
-	(reduce interrupt latency).
-
-	* constants.c: Fix some things to eliminate warnings.  Add some
-	sense descriptions that were omitted before.
-
-	* aha1542.c: Watch for SCRD from host adapter - if we see it, set
-	a flag.  Currently we only print out the number of pending
-	commands that might need to be restarted.
-
-	* aha1542.c (aha1542_abort): Look for lost interrupts, OGMB still
-	full, and attempt to recover.  Otherwise give up.
-
-	* aha1542.c (aha1542_reset): Try BUS DEVICE RESET, and then pass
-	DID_RESET back up to the upper level code for all commands running
-	on this target (even on different LUNs).
-
-Sat May  7 14:54:01 1994
-
-	* Linux 1.1.12 released.
-
-	* st.c, st.h: New version from Kai.  Supports boot time
-	specification of number of buffers.
-
-	* wd7000.[c,h]: Updated driver from John Boyd.  Now supports
-	more than one wd7000 board in machine at one time, among other things.
-
-Wed Apr 20 22:20:35 1994
-
-	* Linux 1.1.8 released.
-
-	* sd.c: Add a few type casts where scsi_malloc is called.
-
-Wed Apr 13 12:53:29 1994
-
-	* Linux 1.1.4 released.
-
-	* scsi.c: Clean up a few printks (use %p to print pointers).
-
-Wed Apr 13 11:33:02 1994
-
-	* Linux 1.1.3 released.
-
-	* fdomain.c: Update to version 5.16 (Handle different FIFO sizes
-	better).
-
-Fri Apr  8 08:57:19 1994
-
-	* Linux 1.1.2 released.
-
-	* Throughout: SCSI portion of cluster diffs added.
-
-Tue Apr  5 07:41:50 1994
-
-	* Linux 1.1 development tree initiated.
-
-	* The linux 1.0 development tree is now effectively frozen except
-	for obvious bugfixes.
-
-******************************************************************
-******************************************************************
-******************************************************************
-******************************************************************
-
-Sun Apr 17 00:17:39 1994
-
-	* Linux 1.0, patchlevel 9 released.
-
-	* fdomain.c: Update to version 5.16 (Handle different FIFO sizes
-	better).
-
-Thu Apr  7 08:36:20 1994
-
-	* Linux 1.0, patchlevel8 released.
-
-	* fdomain.c: Update to version 5.15 from 5.9.  Handles 3.4 bios.
-
-Sun Apr  3 14:43:03 1994
-
-	* Linux 1.0, patchlevel6 released.
-
-	* wd7000.c: Make stab at fixing race condition.
-
-Sat Mar 26 14:14:50 1994
-
-	* Linux 1.0, patchlevel5 released.
-
-	* aha152x.c, Makefile: Fix a few bugs (too much data message).
-	Add a few more bios signatures. (Patches from Juergen).
-
-	* aha1542.c: Fix race condition in aha1542_out.
-
-Mon Mar 21 16:36:20 1994
-
-	* Linux 1.0, patchlevel3 released.
-
-	* sd.c, st.c, sr.c, sg.c: Return -ENXIO, not -ENODEV if we attempt
-	to open a non-existent device.
-
-	* scsi.c: Add Chinon cdrom to blacklist.
-
-	* sr_ioctl.c: Check return status of verify_area.
-
-Sat Mar  6 16:06:19 1994
-
-	* Linux 1.0 released (technically a pre-release).
-
-	* scsi.c: Add IMS CDD521, Maxtor XT-8760S to blacklist.
-
-Tue Feb 15 10:58:20 1994
-
-        * pl15e released.
-
-        * aha1542.c: For 1542C, allow dynamic device scan with >1Gb turned
-	off.
-
-	* constants.c: Fix typo in definition of CONSTANTS.
-
-        * pl15d released.
-
-Fri Feb 11 10:10:16 1994
-
-        * pl15c released.
-
-	* scsi.c: Add Maxtor XT-3280 and Rodime RO3000S to blacklist.
-
-	* scsi.c: Allow tagged queueing for scsi 3 devices as well.
-	Some really old devices report a version number of 0.  Disallow
-	LUN != 0 for these.
-
-Thu Feb 10 09:48:57 1994
-
-        * pl15b released.
-
-Sun Feb  6 12:19:46 1994
-
-        * pl15a released.
-
-Fri Feb  4 09:02:17 1994
-
-        * scsi.c: Add Teac cdrom to blacklist.
-
-Thu Feb  3 14:16:43 1994
-
-	* pl15 released.
-
-Tue Feb  1 15:47:43 1994
-
-	* pl14w released.
-
-	* wd7000.c (wd_bases): Fix typo in last change.
-
-Mon Jan 24 17:37:23 1994
-
-	* pl14u released.
-
-	* aha1542.c: Support 1542CF/extended bios.  Different from 1542C
-
-	* wd7000.c: Allow bios at 0xd8000 as well.
-
-	* ultrastor.c: Do not truncate cylinders to 1024.
-
-	* fdomain.c: Update to version 5.9 (add new bios signature).
-
-	* NCR5380.c: Update from Drew - should work a lot better now.
-
-Sat Jan  8 15:13:10 1994
-
-	* pl14o released.
-
-	* sr_ioctl.c: Zero reserved field before trying to set audio volume.
-
-Wed Jan  5 13:21:10 1994
-
-	* pl14m released.
-
-	* fdomain.c: Update to version 5.8.  No functional difference???
-
-Tue Jan  4 14:26:13 1994
-
-	* pl14l released.
-
-	* ultrastor.c: Remove outl, inl functions (now provided elsewhere).
-
-Mon Jan  3 12:27:25 1994
-
-	* pl14k released.
-
-	* aha152x.c: Remove insw and outsw functions.
-
-	* fdomain.c: Ditto.
-
-Wed Dec 29 09:47:20 1993
-
-	* pl14i released.
-
-	* scsi.c: Support RECOVERED_ERROR for tape drives.
-
-	* st.c: Update of tape driver from Kai.
-
-Tue Dec 21 09:18:30 1993
-
-	* pl14g released.
-
-	* aha1542.[c,h]: Support extended BIOS stuff.
-
-	* scsi.c: Clean up messages about disks, so they are displayed as
-	sda, sdb, etc instead of sd0, sd1, etc.
-
-	* sr.c:  Force reread of capacity if disk was changed.
-	Clear buffer before asking for capacity/sectorsize (some drives
-	do not report this properly).  Set needs_sector_size flag if
-	drive did not return sensible sector size.
-
-Mon Dec 13 12:13:47 1993
-
-	* aha152x.c: Update to version .101 from Juergen.
-
-Mon Nov 29 03:03:00 1993
-
-        * linux 0.99.14 released.
-
-	* All scsi stuff moved from kernel/blk_drv/scsi to drivers/scsi.
-
-	* Throughout: Grammatical corrections to various comments.
-
-	* Makefile: fix so that we do not need to compile things we are
-	not going to use.
-
-	* NCR5380.c, NCR5380.h, g_NCR5380.c, g_NCR5380.h, pas16.c,
-	pas16.h, t128.c, t128.h:  New files from Drew.
-
-	* aha152x.c, aha152x.h: New files from Juergen Fischer.
-
-	* aha1542.c: Support for more than one 1542 in the machine
-	at the same time.  Make functions static that do not need
-	visibility.
-
-	* aha1740.c: Set NEEDS_JUMPSTART flag in reset function, so we
-	know to restart the command.  Change prototype of aha1740_reset
-	to take a command pointer.
-
-	* constants.c: Clean up a few things.
-
-	* fdomain.c: Update to version 5.6.  Move snarf_region.  Allow
-	board to be set at different SCSI ids.  Remove support for
-	reselection (did not work well).  Set JUMPSTART flag in reset
-	code.
-
-	* hosts.c: Support new low-level adapters.  Allow for more than
-	one adapter of a given type.
-
-	* hosts.h: Allow for more than one adapter of a given type.
-
-	* scsi.c:  Add scsi_device_types array, if NEEDS_JUMPSTART is set
-	after a low-level reset, start the command again.  Sort blacklist,
-	and add Maxtor MXT-1240S, XT-4170S, NEC CDROM 84, Seagate ST157N.
-
-	* scsi.h: Add constants for tagged queueing.
-
-	* Throughout: Use constants from major.h instead of hardcoded
-	numbers for major numbers.
-
-	* scsi_ioctl.c: Fix bug in buffer length in ioctl_command.  Use
-	verify_area in GET_IDLUN ioctl.  Add new ioctls for
-	TAGGED_QUEUE_ENABLE, DISABLE.  Only allow IOCTL_SEND_COMMAND by
-	superuser.
-
-	* sd.c: Only pay attention to UNIT_ATTENTION for removable disks.
-	Fix bug where sometimes portions of blocks would get lost
-	resulting in processes hanging.  Add messages when we spin up a
-	disk, and fix a bug in the timing.  Increase read-ahead for disks
-	that are on a scatter-gather capable host adapter.
-
-	* seagate.c: Fix so that some parameters can be set from the lilo
-	prompt.  Supply jumpstart flag if we are resetting and need the
-	command restarted.   Fix so that we return 1 if we detect a card
-	so that multiple card detection works correctly.  Add yet another
-	signature for FD cards (950).  Add another signature for ST0x.
-
-	* sg.c, sg.h: New files from Lawrence Foard for generic scsi
-	access.
-
-	* sr.c:  Add type casts for (void*) so that we can do pointer
-	arithmetic.  Works with GCC without this, but it is not strictly
-	correct.  Same bugfix as was in sd.c.  Increase read-ahead a la
-	disk driver.
-
-	* sr_ioctl.c: Use scsi_malloc buffer instead of buffer from stack
-	since we cannot guarantee that the stack is < 16Mb.
-
-	ultrastor.c: Update to support 24f properly (JFC's driver).
-
-	wd7000.c: Supply jumpstart flag for reset.  Do not round up
-	number of cylinders in biosparam function.
-
-Sat Sep  4 20:49:56 1993
-
-    * 0.99pl13 released.
-
-    * Throughout:  Use check_region/snarf_region for all low-level
-    drivers.
-
-    * aha1542.c: Do hard reset instead of soft (some ethercard probes
-    screw us up).
-
-    * scsi.c: Add new flag ASKED_FOR_SENSE so that we can tell if we are
-    in a loop whereby the device returns null sense data.
-
-    * sd.c: Add code to spin up a drive if it is not already spinning.
-    Do this one at a time to make it easier on power supplies.
-
-    * sd_ioctl.c: Use sync_dev instead of fsync_dev in BLKFLSBUF ioctl.
-
-    * seagate.c: Switch around DATA/CONTROL lines.
-
-    * st.c: Change sense to unsigned.
-
-Thu Aug  5 11:59:18 1993
-
-    * 0.99pl12 released.
-
-    * constants.c, constants.h: New files with ascii descriptions of
-    various conditions.
-
-    * Makefile: Do not try to count the number of low-level drivers,
-    just generate the list of .o files.
-
-    * aha1542.c: Replace 16 with sizeof(SCpnt->sense_buffer).  Add tests
-    for addresses > 16Mb, panic if we find one.
-
-    * aha1740.c: Ditto with sizeof().
-
-    * fdomain.c: Update to version 3.18.  Add new signature, register IRQ
-    with irqaction.  Use ID 7 for new board.  Be more intelligent about
-    obtaining the h/s/c numbers for biosparam.
-
-    * hosts.c: Do not depend upon Makefile generated count of the number
-    of low-level host adapters.
-
-    * scsi.c: Use array for scsi_command_size instead of a function.  Add
-    Texel cdrom and Maxtor XT-4380S to blacklist.  Allow compile time
-    option for no-multi lun scan.  Add semaphore for possible problems
-    with handshaking, assume device is faulty until we know it not to be
-    the case.  Add DEBUG_INIT symbol to dump info as we scan for devices.
-    Zero sense buffer so we can tell if we need to request it.  When
-    examining sense information, request sense if buffer is all zero.
-    If RESET, request sense information to see what to do next.
-
-    * scsi_debug.c: Change some constants to use symbols like INT_MAX.
-
-    * scsi_ioctl.c (kernel_scsi_ioctl): New function -for making ioctl
-    calls from kernel space.
-
-    * sd.c: Increase timeout to 300.  Use functions in constants.h to
-    display info.  Use scsi_malloc buffer for READ_CAPACITY, since
-    we cannot guarantee that a stack based buffer is < 16Mb.
-
-    * sd_ioctl.c: Add BLKFLSBUF ioctl.
-
-    * seagate.c: Add new compile time options for ARBITRATE,
-    SLOW_HANDSHAKE, and SLOW_RATE.  Update assembly loops for transferring
-    data.  Use kernel_scsi_ioctl to request mode page with geometry.
-
-    * sr.c: Use functions in constants.c to display messages.
-
-    * st.c: Support for variable block size.
-
-    * ultrastor.c: Do not use cache for tape drives.  Set
-    unchecked_isa_dma flag, even though this may not be needed (gets set
-    later).
-
-Sat Jul 17 18:32:44 1993
-
-    * 0.99pl11 released.  C++ compilable.
-
-    * Throughout: Add type casts all over the place, and use "ip" instead
-    of "info" in the various biosparam functions.
-
-    * Makefile: Compile seagate.c with C++ compiler.
-
-    * aha1542.c: Always set ccb pointer as this gets trashed somehow on
-    some systems.  Add a few type casts.  Update biosparam function a little.
-
-    * aha1740.c: Add a few type casts.
-
-    * fdomain.c: Update to version 3.17 from 3.6.  Now works with
-    TMC-18C50.
-
-    * scsi.c: Minor changes here and there with datatypes.  Save use_sg
-    when requesting sense information so that this can properly be
-    restored if we retry the command.  Set aside dma buffers assuming each
-    block is 1 page, not 1Kb minix block.
-
-    * scsi_ioctl.c: Add a few type casts.  Other minor changes.
-
-    * sd.c:  Correctly  free all scsi_malloc'd memory if we run out of
-    dma_pool. Store blocksize information for each partition.
-
-    * seagate.c: Minor cleanups here and there.
-
-    * sr.c: Set up blocksize array for all discs.  Fix bug in freeing
-    buffers if we run out of dma pool.
-
-Thu Jun  2 17:58:11 1993
-
-    * 0.99pl10 released.
-
-    * aha1542.c: Support for BT 445S (VL-bus board with no dma channel).
-
-    * fdomain.c: Upgrade to version 3.6. Preliminary support for TNC-18C50.
-
-    * scsi.c: First attempt to fix problem with old_use_sg.  Change
-    NOT_READY to a SUGGEST_ABORT.  Fix timeout race where time might
-    get decremented past zero.
-
-    * sd.c: Add block_fsync function to dispatch table.
-
-    * sr.c: Increase timeout to 500 from 250.  Add entry for sync in
-    dispatch table (supply NULL).  If we do not have a sectorsize,
-    try to get it in the sd_open function.  Add new function just to
-    obtain sectorsize.
-
-    * sr.h: Add needs_sector_size semaphore.
-
-    * st.c: Add NULL for fsync in dispatch table.
-
-    * wd7000.c: Allow another condition for power on that are normal
-    and do not require a panic.
-
-Thu Apr 22 23:10:11 1993
-
-    * 0.99pl9 released.
-
-    * aha1542.c: Use (void) instead of () in setup_mailboxes.
-
-    * scsi.c: Initialize transfersize and underflow fields in SCmd to 0.
-    Do not panic for unsupported message bytes.
-
-    * scsi.h: Allocate 12 bytes instead of 10 for commands.  Add
-    transfersize and underflow fields.
-
-    * scsi_ioctl.c: Further bugfix to ioctl_probe.
-
-    * sd.c: Use long instead of int for last parameter in sd_ioctl.
-    Initialize transfersize and underflow fields.
-
-    * sd_ioctl.c: Ditto for sd_ioctl(,,,,);
-
-    * seagate.c: New version from Drew.  Includes new signatures for FD
-    cards.  Support for 0ws jumper. Correctly initialize
-    scsi_hosts[hostnum].this_id.  Improved handing of
-    disconnect/reconnect, and support command linking.  Use
-    transfersize and underflow fields.  Support scatter-gather.
-
-    * sr.c, sr_ioctl.c: Use long instead of int for last parameter in sr_ioctl.
-    Use buffer and buflength in do_ioctl.  Patches from Chris Newbold for
-    scsi-2 audio commands.
-
-    * ultrastor.c: Comment out in_byte (compiler warning).
-
-    * wd7000.c: Change () to (void) in wd7000_enable_dma.
-
-Wed Mar 31 16:36:25 1993
-
-    * 0.99pl8 released.
-
-    * aha1542.c: Handle mailboxes better for 1542C.
-        Do not truncate number of cylinders at 1024 for biosparam call.
-
-    * aha1740.c: Fix a few minor bugs for multiple devices.
-        Same as above for biosparam.
-
-    * scsi.c: Add lockable semaphore for removable devices that can have
-    media removal prevented.  Add another signature for flopticals.
-    (allocate_device): Fix race condition.  Allow more space in dma pool
-    for blocksizes of up to 4Kb.
-
-    * scsi.h: Define COMMAND_SIZE.  Define a SCSI specific version of
-    INIT_REQUEST that can run with interrupts off.
-
-    * scsi_ioctl.c: Make ioctl_probe function more idiot-proof.  If
-    a removable device says ILLEGAL REQUEST to a door-locking command,
-    clear lockable flag.  Add SCSI_IOCTL_GET_IDLUN ioctl.  Do not attempt
-    to lock door for devices that do not have lockable semaphore set.
-
-    * sd.c: Fix race condition for multiple disks.  Use INIT_SCSI_REQUEST
-    instead of INIT_REQUEST.  Allow sector sizes of 1024 and 256.  For
-    removable disks that are not ready, mark them as having a media change
-    (some drives do not report this later).
-
-    * seagate.c: Use volatile keyword for memory-mapped register pointers.
-
-    * sr.c: Fix race condition, a la sd.c.  Increase the number of retries
-    to 1.  Use INIT_SCSI_REQUEST.  Allow 512 byte sector sizes.  Do a
-    read_capacity when we init the device so we know the size and
-    sectorsize.
-
-    * st.c: If ioctl not found in st.c, try scsi_ioctl for others.
-
-    * ultrastor.c: Do not truncate number of cylinders at 1024 for
-    biosparam call.
-
-    * wd7000.c: Ditto.
-    Throughout: Use COMMAND_SIZE macro to determine length of scsi
-    command.
-
-
-
-Sat Mar 13 17:31:29 1993
-
-    * 0.99pl7 released.
-
-    Throughout: Improve punctuation in some messages, and use new
-    verify_area syntax.
-
-    * aha1542.c: Handle unexpected interrupts better.
-
-    * scsi.c: Ditto.  Handle reset conditions a bit better, asking for
-    sense information and retrying if required.
-
-    * scsi_ioctl.c: Allow for 12 byte scsi commands.
-
-    * ultrastor.c: Update to use scatter-gather.
-
-Sat Feb 20 17:57:15 1993
-
-    * 0.99pl6 released.
-
-    * fdomain.c: Update to version 3.5.  Handle spurious interrupts
-    better.
-
-    * sd.c: Use register_blkdev function.
-
-    * sr.c: Ditto.
-
-    * st.c: Use register_chrdev function.
-
-    * wd7000.c: Undo previous change.
-
-Sat Feb  6 11:20:43 1993
-
-    * 0.99pl5 released.
-
-    * scsi.c: Fix bug in testing for UNIT_ATTENTION.
-
-    * wd7000.c: Check at more addresses for bios.  Fix bug in biosparam
-    (heads & sectors turned around).
-
-Wed Jan 20 18:13:59 1993
-
-    * 0.99pl4 released.
-
-    * scsi.c: Ignore leading spaces when looking for blacklisted devices.
-
-    * seagate.c: Add a few new signatures for FD cards.  Another patch
-    with SCint to fix race condition.  Use recursion_depth to keep track
-    of how many times we have been recursively called, and do not start
-    another command unless we are on the outer level.  Fixes bug
-    with Syquest cartridge drives (used to crash kernel), because
-    they do not disconnect with large data transfers.
-
-Tue Jan 12 14:33:36 1993
-
-    * 0.99pl3 released.
-
-    * fdomain.c: Update to version 3.3 (a few new signatures).
-
-    * scsi.c: Add CDU-541, Denon DRD-25X to blacklist.
-    (allocate_request, request_queueable): Init request.waiting to NULL if
-    non-buffer type of request.
-
-    * seagate.c:  Allow controller to be overridden with CONTROLLER symbol.
-    Set SCint=NULL when we are done, to remove race condition.
-
-    * st.c: Changes from Kai.
-
-Wed Dec 30 20:03:47 1992
-
-    * 0.99pl2 released.
-
-    * scsi.c: Blacklist back in.  Remove Newbury drive as other bugfix
-    eliminates need for it here.
-
-    * sd.c: Return ENODEV instead of EACCES if no such device available.
-    (sd_init) Init blkdev_fops earlier so that sd_open is available sooner.
-
-    * sr.c: Same as above for sd.c.
-
-    * st.c: Return ENODEV instead of ENXIO if no device.  Init chrdev_fops
-    sooner, so that it is always there even if no tapes.
-
-    * seagate.c (controller_type): New variable to keep track of ST0x or
-    FD.  Modify signatures list to indicate controller type, and init
-    controller_type once we find a match.
-
-    * wd7000.c (wd7000_set_sync): Remove redundant function.
-
-Sun Dec 20 16:26:24 1992
-
-    * 0.99pl1 released.
-
-    * scsi_ioctl.c: Bugfix - check dev->index, not dev->id against
-    NR_SCSI_DEVICES.
-
-    * sr_ioctl.c: Verify that device exists before allowing an ioctl.
-
-    * st.c: Patches from Kai - change timeout values, improve end of tape
-    handling.
-
-Sun Dec 13 18:15:23 1992
-
-    * 0.99 kernel released.  Baseline for this ChangeLog.
diff -Nru a/Documentation/scsi/ChangeLog.1992-1997 b/Documentation/scsi/ChangeLog.1992-1997
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/Documentation/scsi/ChangeLog.1992-1997	2005-03-01 23:38:54 -08:00
@@ -0,0 +1,2023 @@
+Sat Jan 18 15:51:45 1997  Richard Henderson  <rth@tamu.edu>
+
+	* Don't play with usage_count directly, instead hand around
+	the module header and use the module macros.
+
+Fri May 17 00:00:00 1996  Leonard N. Zubkoff <lnz@dandelion.com>
+
+	* BusLogic Driver Version 2.0.3 Released.
+
+Tue Apr 16 21:00:00 1996  Leonard N. Zubkoff <lnz@dandelion.com>
+
+	* BusLogic Driver Version 1.3.2 Released.
+
+Sun Dec 31 23:26:00 1995  Leonard N. Zubkoff <lnz@dandelion.com>
+
+	* BusLogic Driver Version 1.3.1 Released.
+
+Fri Nov 10 15:29:49 1995  Leonard N. Zubkoff <lnz@dandelion.com>
+
+	* Released new BusLogic driver.
+
+Wed Aug  9 22:37:04 1995  Andries Brouwer  <aeb@cwi.nl>
+
+	As a preparation for new device code, separated the various
+	functions the request->dev field had into the device proper,
+	request->rq_dev and a status field request->rq_status.
+
+	The 2nd argument of bios_param is now a kdev_t.
+
+Wed Jul 19 10:43:15 1995  Michael Neuffer  <neuffer@goofy.zdv.uni-mainz.de>
+
+        * scsi.c (scsi_proc_info): /proc/scsi/scsi now also lists all
+	attached devices.
+
+	* scsi_proc.c (proc_print_scsidevice): Added. Used by scsi.c and
+	eata_dma_proc.c to produce some device info for /proc/scsi.
+
+	* eata_dma.c (eata_queue)(eata_int_handler)(eata_scsi_done):
+	Changed handling of internal SCSI commands send to the HBA.
+
+
+Wed Jul 19 10:09:17 1995  Michael Neuffer  <neuffer@goofy.zdv.uni-mainz.de>
+
+	* Linux 1.3.11 released.
+
+	* eata_dma.c (eata_queue)(eata_int_handler): Added code to do
+	command latency measurements if requested by root through
+	/proc/scsi interface.
+	Throughout Use HZ constant for time references.
+
+	* eata_pio.c: Use HZ constant for time references.
+
+	* aic7xxx.c, aic7xxx.h, aic7xxx_asm.c: Changed copyright from BSD
+	to GNU style.
+
+	* scsi.h: Added READ_12 command opcode constant
+
+Wed Jul 19 09:25:30 1995  Michael Neuffer <neuffer@goofy.zdv.uni-mainz.de>
+
+	* Linux 1.3.10 released.
+
+	* scsi_proc.c (dispatch_scsi_info): Removed unused variable.
+
+Wed Jul 19 09:25:30 1995  Michael Neuffer  <neuffer@goofy.zdv.uni-mainz.de>
+
+	* Linux 1.3.9 released.
+
+	* scsi.c Blacklist concept expanded to 'support' more device
+	deficiencies. blacklist[] renamed to device_list[]
+	(scan_scsis): Code cleanup.
+
+	* scsi_debug.c (scsi_debug_proc_info): Added support to control
+	device lockup simulation via /proc/scsi interface.
+
+
+Wed Jul 19 09:22:34 1995  Michael Neuffer  <neuffer@goofy.zdv.uni-mainz.de>
+
+	* Linux 1.3.7 released.
+
+	* scsi_proc.c: Fixed a number of bugs in directory handling
+
+Wed Jul 19 09:18:28 1995  Michael Neuffer  <neuffer@goofy.zdv.uni-mainz.de>
+
+	* Linux 1.3.5 released.
+
+	* Native wide, multichannel and /proc/scsi support now in official
+	kernel distribution.
+
+        * scsi.c/h, hosts.c/h et al reindented to increase readability
+	(especially on 80 column wide terminals).
+
+	* scsi.c, scsi_proc.c, ../../fs/proc/inode.c: Added
+	/proc/scsi/scsi which allows root to scan for hotplugged devices.
+
+	* scsi.c (scsi_proc_info): Added, to support /proc/scsi/scsi.
+	(scan_scsis): Added some 'spaghetti' code to allow scanning for
+	single devices.
+	
+
+Thu Jun 20 15:20:27 1995  Michael Neuffer  <neuffer@goofy.zdv.uni-mainz.de>
+
+        * proc.c: Renamed to scsi_proc.c
+
+Mon Jun 12 20:32:45 1995  Michael Neuffer  <neuffer@goofy.zdv.uni-mainz.de>
+
+	* Linux 1.3.0 released.
+
+Mon May 15 19:33:14 1995  Michael Neuffer  <neuffer@goofy.zdv.uni-mainz.de>
+
+	* scsi.c: Added native multichannel and wide scsi support.
+
+	* proc.c (dispatch_scsi_info) (build_proc_dir_hba_entries):
+	Updated /proc/scsi interface.
+
+Thu May  4 17:58:48 1995  Michael Neuffer  <neuffer@goofy.zdv.uni-mainz.de>
+
+	* sd.c (requeue_sd_request): Zero out the scatterlist only if
+	scsi_malloc returned memory for it.
+
+	* eata_dma.c (register_HBA) (eata_queue): Add support for
+	large scatter/gather tables and set use_clustering accordingly
+
+	* hosts.c: Make use_clustering changeable in the Scsi_Host structure.
+
+Wed Apr 12 15:25:52 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.2.5 released.
+
+	* buslogic.c: Update to version 1.15 (From Leonard N. Zubkoff).
+	Fixed interrupt routine to avoid races when handling multiple
+	complete commands per interrupt.  Seems to come up with faster
+	cards.
+
+	* eata_dma.c: Update to 2.3.5r. Modularize. Improved error handling
+        throughout and fixed bug interrupt routine which resulted in shifted
+        status bytes. Added blink LED state checks for ISA and EISA HBAs.
+        Memory management bug seems to have disappeared ==> increasing
+        C_P_L_CURRENT_MAX to 16 for now. Decreasing C_P_L_DIV to 3 for
+        performance reasons.
+
+	* scsi.c: If we get a FMK, EOM, or ILI when attempting to scan
+	the bus, assume that it was just noise on the bus, and ignore
+	the device.
+
+	* scsi.h: Update and add a bunch of missing commands which we
+	were never using.
+
+	* sd.c: Use restore_flags in do_sd_request - this may result in
+	latency conditions, but it gets rid of races and crashes.
+	Do not save flags again when searching for a second command to
+	queue.
+
+	* st.c: Use bytes, not STP->buffer->buffer_size when reading
+	from tape.
+
+
+Tue Apr  4 09:42:08 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.2.4 released.
+
+	* st.c: Fix typo - restoring wrong flags.
+
+Wed Mar 29 06:55:12 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.2.3 released.
+
+	* st.c: Perform some waiting operations with interrupts off.
+	Is this correct???
+
+Wed Mar 22 10:34:26 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.2.2 released.
+
+	* aha152x.c: Modularize.  Add support for PCMCIA.
+
+	* eata.c: Update to version 2.0.  Fixed bug preventing media
+	detection.  If scsi_register_host returns NULL, fail gracefully.
+
+	* scsi.c: Detect as NEC (for photo-cd purposes) for the 84
+	and 25 models as "NEC_OLDCDR".
+
+	* scsi.h: Add define for NEC_OLDCDR
+
+	* sr.c: Add handling for NEC_OLDCDR.  Treat as unknown.
+
+	* u14-34f.c: Update to version 2.0.  Fixed same bug as in
+	eata.c.
+
+
+Mon Mar  6 11:11:20 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.2.0 released.  Yeah!!!
+
+	* Minor spelling/punctuation changes throughout.  Nothing
+	substantive.
+
+Mon Feb 20 21:33:03 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.95 released.
+
+	* qlogic.c: Update to version 0.41.
+
+	* seagate.c: Change some message to be more descriptive about what
+	we detected.
+
+	* sr.c: spelling/whitespace changes.
+
+Mon Feb 20 21:33:03 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.94 released.
+
+Mon Feb 20 08:57:17 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.93 released.
+
+	* hosts.h: Change io_port to long int from short.
+
+ 	* 53c7,8xx.c: crash on AEN fixed, SCSI reset is no longer a NOP,
+ 	  NULL pointer panic on odd UDCs fixed, two bugs in diagnostic output
+ 	  fixed, should initialize correctly if left running, now loadable,
+  	  new memory allocation, extraneous diagnostic output suppressed,
+ 	  splx() replaced with save/restore flags. [ Drew ]
+
+	* hosts.c, hosts.h, scsi_ioctl.c, sd.c, sd_ioctl.c, sg.c, sr.c,
+	sr_ioctl.c: Add special junk at end that Emacs will use for
+	formatting the file.
+
+	* qlogic.c: Update to v0.40a.  Improve parity handling.
+
+	* scsi.c: Add Hitachi DK312C to blacklist.  Change "};" to "}" in
+	many places.  Use scsi_init_malloc to get command block - may
+	need this to be dma compatible for some host adapters.
+	Restore interrupts after unregistering a host.
+
+	* sd.c: Use sti instead of restore flags - causes latency problems.
+
+	* seagate.c: Use controller_type to determine string used when
+	registering irq.
+
+	* sr.c: More photo-cd hacks to make sure we get the xa stuff right.
+	* sr.h, sr.c: Change is_xa to xa_flags field.
+
+	* st.c: Disable retries for write operations.
+
+Wed Feb 15 10:52:56 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.92 released.
+
+	* eata.c: Update to 1.17.
+
+	* eata_dma.c: Update to 2.31a. Add more support for /proc/scsi.
+        Continuing modularization. Less crashes because of the bug in the
+        memory management ==> increase C_P_L_CURRENT_MAX to 10
+        and decrease C_P_L_DIV to 4.
+
+	* hosts.c: If we remove last host registered, reuse host number.
+	When freeing memory from host being deregistered, free extra_bytes
+	too.
+
+	* scsi.c (scan_scsis): memset(SDpnt, 0) and set SCmd.device to SDpnt.
+	Change memory allocation to work around bugs in __get_dma_pages.
+	Do not free host if usage count is not zero (for modules).
+
+	* sr_ioctl.c: Increase IOCTL_TIMEOUT to 3000.
+
+	* st.c: Allow for ST_EXTRA_DEVS in st data structures.
+
+	* u14-34f.c: Update to 1.17.
+
+Thu Feb  9 10:11:16 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.91 released.
+
+	* eata.c: Update to 1.16.  Use wish_block instead of host->block.
+
+	* hosts.c: Initialize wish_block to 0.
+
+	* hosts.h: Add wish_block.
+
+	* scsi.c: Use wish_block as indicator that the host should be added
+	to block list.
+
+	* sg.c: Add SG_EXTRA_DEVS to number of slots.
+
+	* u14-34f.c: Use wish_block.
+
+Tue Feb  7 11:46:04 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.90 released.
+
+	* eata.c: Change naming from eata_* to eata2x_*.  Now at vers 1.15.
+	Update interrupt handler to take pt_regs as arg.  Allow blocking
+	even if loaded as module.  Initialize target_time_out array.
+	Do not put sti(); in timing loop.
+
+	* hosts.c: Do not reuse host numbers.
+	Use scsi_make_blocked_list to generate blocking list.
+
+	* script_asm.pl:  Beats me.  Don't know perl.  Something to do with
+	phase index.
+
+	* scsi.c (scsi_make_blocked_list): New function - code copied from
+	hosts.c.
+
+	* scsi.c: Update code to disable photo CD for Toshiba cdroms.
+	Use just manufacturer name, not model number.
+
+	* sr.c: Fix setting density for Toshiba drives.
+
+	* u14-34f.c: Clear target_time_out array during reset.
+
+Wed Feb  1 09:20:45 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.89 released.
+
+	* Makefile, u14-34f.c: Modularize.
+
+	* Makefile, eata.c: Modularize.  Now version 1.14
+
+	* NCR5380.c: Update interrupt handler with new arglist.  Minor
+	cleanups.
+
+	* eata_dma.c: Begin to modularize.  Add hooks for /proc/scsi.
+	New version 2.3.0a. Add code in interrupt handler to allow
+        certain CDROM drivers to be detected which return a
+        CHECK_CONDITION during SCSI bus scan. Add opcode check to get
+        all DATA IN and DATA OUT phases right. Utilize HBA_interpret flag.
+	Improvements in HBA identification. Various other minor stuff.
+
+	* hosts.c: Initialize ->dma_channel and ->io_port when registering
+	a new host.
+
+	* qlogic.c: Modularize and add PCMCIA support.
+
+	* scsi.c: Add Hitachi to blacklist.
+
+	* scsi.c: Change default to no lun scan (too many problem devices).
+
+	* scsi.h: Define QUEUE_FULL condition.
+
+	* sd.c: Do not check for non-existent partition until after
+	new media check.
+
+	* sg.c: Undo previous change which was wrong.
+
+	* sr_ioctl.c: Increase IOCTL_TIMEOUT to 2000.
+
+	* st.c: Patches from Kai - improve filemark handling.
+
+Tue Jan 31 17:32:12 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.88 released.
+
+	* Throughout - spelling/grammar fixups.
+
+	* scsi.c: Make sure that all buffers are 16 byte aligned - some
+	drivers (buslogic) need this.
+
+	* scsi.c (scan_scsis): Remove message printed.
+
+	* scsi.c (scsi_init): Move message here.
+
+Mon Jan 30 06:40:25 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.87 released.
+
+	* sr.c: Photo-cd related changes. (Gerd Knorr??).
+
+	* st.c: Changes from Kai related to EOM detection.
+
+Mon Jan 23 23:53:10 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.86 released.
+
+	* 53c7,8xx.h: Change SG size to 127.
+
+	* eata_dma: Update to version 2.10i. Remove bug in the registration
+        of multiple HBAs and channels. Minor other improvements and stylistic
+        changes.
+
+	* scsi.c: Test for Toshiba XM-3401TA and exclude from detection
+	as toshiba drive - photo cd does not work with this drive.
+
+	* sr.c:  Update photocd code.
+
+Mon Jan 23 23:53:10 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.85 released.
+
+	* st.c, st_ioctl.c, sg.c, sd_ioctl.c, scsi_ioctl.c, hosts.c:
+	include linux/mm.h
+
+	* qlogic.c, buslogic.c, aha1542.c: Include linux/module.h.
+
+Sun Jan 22 22:08:46 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.84 released.
+
+	* Makefile: Support for loadable QLOGIC boards.
+
+	* aha152x.c: Update to version 1.8 from Juergen.
+
+	* eata_dma.c: Update from Michael Neuffer.
+        Remove hard limit of 2 commands per lun and make it better
+        configurable. Improvements in HBA identification.
+
+	* in2000.c: Fix biosparam to support large disks.
+
+	* qlogic.c: Minor changes (change sti -> restore_flags).
+
+Wed Jan 18 23:33:09 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.83 released.
+
+	* aha1542.c(aha1542_intr_handle): Use arguments handed down to find
+	which irq.
+
+	* buslogic.c: Likewise.
+
+	* eata_dma.c: Use min of 2 cmd_per_lun for OCS_enabled boards.
+
+	* scsi.c: Make RECOVERED_ERROR a SUGGEST_IS_OK.
+
+	* sd.c: Fail if we are opening a non-existent partition.
+
+	* sr.c: Bump SR_TIMEOUT to 15000.
+	Do not probe for media size at boot time(hard on changers).
+	Flag device as needing sector size instead.
+
+	* sr_ioctl.c: Remove CDROMMULTISESSION_SYS ioctl.
+
+	* ultrastor.c: Fix bug in call to ultrastor_interrupt (wrong #args).
+
+Mon Jan 16 07:18:23 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.82 released.
+
+	Throughout.
+	- Change all interrupt handlers to accept new calling convention.
+	In particular, we now receive the irq number as one of the arguments.
+
+	* More minor spelling corrections in some of the new files.
+
+	* aha1542.c, buslogic.c: Clean up interrupt handler a little now
+	that we receive the irq as an arg.
+
+	* aha274x.c: s/snarf_region/request_region/
+
+	* eata.c: Update to version 1.12.   Fix some comments and display a
+	message if we cannot reserve the port addresses.
+
+	* u14-34f.c: Update to version 1.13.   Fix some comments and display a
+	message if we cannot reserve the port addresses.
+
+	* eata_dma.c: Define get_board_data function (send INQUIRY command).
+	Use to improve detection of variants of different DPT boards.  Change
+	version subnumber to "0g".
+
+	* fdomain.c:  Update to version 5.26.  Improve detection of some boards
+	repackaged by IBM.
+
+	* scsi.c (scsi_register_host): Change "name" to const char *.
+
+	* sr.c: Fix problem in set mode command for Toshiba drives.
+
+	* sr.c: Fix typo from patch 81.
+
+Fri Jan 13 12:54:46 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.81 released.  Codefreeze for 1.2 release announced.
+
+	Big changes here.
+
+	* eata_dma.*: New files from Michael Neuffer.
+	(neuffer@goofy.zdv.uni-mainz.de).  Should support
+	all eata/dpt cards.
+
+	* hosts.c, Makefile: Add eata_dma.
+
+	* README.st: Document MTEOM.
+
+	Patches from me (ERY) to finish support for low-level loadable scsi.
+	It now works, and is actually useful.
+
+	* Throughout - add new argument to scsi_init_malloc that takes an
+	additional parameter.  This is used as a priority to kmalloc,
+	and you can specify the GFP_DMA flag if you need DMA-able memory.
+
+	* Makefile: For source files that are loadable, always add name
+	to SCSI_SRCS.  Fill in modules: target.
+
+	* hosts.c:  Change next_host to next_scsi_host, and make global.
+	Print hosts after we have identified all of them.  Use info()
+	function if present, otherwise use name field.
+
+	* hosts.h: Change attach function to return int, not void.
+	Define number of device slots to allow for loadable devices.
+	Define tags to tell scsi module code what type of module we
+	are loading.
+
+	* scsi.c: Fix scan_scsis so that it can be run by a user process.
+	Do not use waiting loops - use up and down mechanism as long
+	as current != task[0].
+
+	* scsi.c(scan_scsis): Do not use stack variables for I/O - this
+	could be > 16Mb if we are loading a module at runtime (i.e. use
+	scsi_init_malloc to get some memory we know will be safe).
+
+	* scsi.c: Change dma freelist to be a set of pages.  This allows
+	us to dynamically adjust the size of the list by adding more pages
+	to the pagelist.  Fix scsi_malloc and scsi_free accordingly.
+
+	* scsi_module.c: Fix include.
+
+	* sd.c: Declare detach function.  Increment/decrement module usage
+	count as required.  Fix init functions to allow loaded devices.
+	Revalidate all new disks so we get the partition tables.  Define
+	detach function.
+
+	* sr.c: Likewise.
+
+	* sg.c: Declare detach function.  Allow attachment of devices on
+	loaded drivers.
+
+	* st.c: Declare detach function.  Increment/decrement module usage
+	count as required.
+
+Tue Jan 10 10:09:58 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.79 released.
+
+	Patch from some undetermined individual who needs to get a life :-).
+
+	* sr.c: Attacked by spelling bee...
+
+	Patches from Gerd Knorr:
+
+	* sr.c: make printk messages for photoCD a little more informative.
+
+	* sr_ioctl.c: Fix CDROMMULTISESSION_SYS ioctl.
+
+Mon Jan  9 10:01:37 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.78 released.
+
+	* Makefile: Add empty modules: target.
+
+	* Wheee.  Now change register_iomem to request_region.
+
+	* in2000.c: Bugfix - apparently this is the fix that we have
+	all been waiting for.  It fixes a problem whereby the driver
+	is not stable under heavy load.  Race condition and all that.
+	Patch from Peter Lu.
+
+Wed Jan  4 21:17:40 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.77 released.
+
+	* 53c7,8xx.c: Fix from Linus - emulate splx.
+
+	Throughout:
+
+		Change "snarf_region" with "register_iomem".
+
+	* scsi_module.c: New file.  Contains support for low-level loadable
+	  scsi drivers. [ERY].
+
+	* sd.c: More s/int/long/ changes.
+
+	* seagate.c: Explicitly include linux/config.h
+
+	* sg.c: Increment/decrement module usage count on open/close.
+
+	* sg.c: Be a bit more careful about the user not supplying enough
+	  information for a valid command.  Pass correct size down to
+	  scsi_do_cmd.
+
+	* sr.c:  More changes for Photo-CD.  This apparently breaks NEC drives.
+
+	* sr_ioctl.c:  Support CDROMMULTISESSION ioctl.
+
+
+Sun Jan  1 19:55:21 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.76 released.
+
+	* constants.c: Add type cast in switch statement.
+
+	* scsi.c (scsi_free): Change datatype of "offset" to long.
+	  (scsi_malloc): Change a few more variables to long.  Who
+	  did this and why was it important?  64 bit machines?
+
+
+	Lots of changes to use save_state/restore_state instead of cli/sti.
+	Files changed include:
+
+	* aha1542.c:
+	* aha1740.c:
+	* buslogic.c:
+	* in2000.c:
+	* scsi.c:
+	* scsi_debug.c:
+	* sd.c:
+	* sr.c:
+	* st.c:
+
+Wed Dec 28 16:38:29 1994  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.75 released.
+
+	* buslogic.c: Spelling fix.
+
+	* scsi.c: Add HP C1790A and C2500A scanjet to blacklist.
+
+	* scsi.c: Spelling fixup.
+
+	* sd.c: Add support for sd_hardsizes (hard sector sizes).
+
+	* ultrastor.c: Use save_flags/restore_flags instead of cli/sti.
+
+Fri Dec 23 13:36:25 1994  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.74 released.
+
+	* README.st: Update from Kai Makisara.
+
+	* eata.c: New version from Dario - version 1.11.
+	  use scsicam bios_param routine.  Add support for 2011
+	  and 2021 boards.
+
+	* hosts.c: Add support for blocking.  Linked list automatically
+	  generated when shpnt->block is set.
+
+	* scsi.c: Add sankyo & HP scanjet to blacklist.  Add support for
+	  kicking things loose when we deadlock.
+
+	* scsi.c: Recognize scanners and processors in scan_scsis.
+
+	* scsi_ioctl.h: Increase timeout to 9 seconds.
+
+	* st.c: New version from Kai - add better support for backspace.
+
+	* u14-34f.c: New version from Dario.  Supports blocking.
+
+Wed Dec 14 14:46:30 1994  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.73 released.
+
+	* buslogic.c: Update from Dave Gentzel.  Version 1.14.
+	  Add module related stuff.   More fault tolerant if out of
+	  DMA memory.
+
+	* fdomain.c: New version from Rik Faith - version 5.22.  Add support
+	  for ISA-200S SCSI adapter.
+
+	* hosts.c: Spelling.
+
+	* qlogic.c: Update to version 0.38a.  Add more support for PCMCIA.
+
+	* scsi.c: Mask device type with 0x1f during scan_scsis.
+	  Add support for deadlocking, err, make that getting out of
+	  deadlock situations that are created when we allow the user
+	  to limit requests to one host adapter at a time.
+
+	* scsi.c: Bugfix - pass pid, not SCpnt as second arg to
+	  scsi_times_out.
+
+	* scsi.c: Restore interrupt state to previous value instead of using
+	  cli/sti pairs.
+
+	* scsi.c: Add a bunch of module stuff (all commented out for now).
+
+	* scsi.c: Clean up scsi_dump_status.
+
+Tue Dec  6 12:34:20 1994  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.72 released.
+
+	* sg.c: Bugfix - always use sg_free, since we might have big buff.
+
+Fri Dec  2 11:24:53 1994  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.71 released.
+
+	* sg.c: Clear buff field when not in use.  Only call scsi_free if
+	non-null.
+
+	* scsi.h: Call wake_up(&wait_for_request) when done with a
+	command.
+
+	* scsi.c (scsi_times_out): Pass pid down so that we can protect
+	against race conditions.
+
+	* scsi.c (scsi_abort): Zero timeout field if we get the
+	NOT_RUNNING message back from low-level driver.
+
+
+	* scsi.c (scsi_done): Restore cmd_len, use_sg here.
+
+	* scsi.c (request_sense): Not here.
+
+	* hosts.h: Add new forbidden_addr, forbidden_size fields.  Who
+	added these and why????
+
+	* hosts.c (scsi_mem_init): Mark pages as reserved if they fall in
+	the forbidden regions.  I am not sure - I think this is so that
+	we can deal with boards that do incomplete decoding of their
+	address lines for the bios chips, but I am not entirely sure.
+
+	* buslogic.c: Set forbidden_addr stuff if using a buggy board.
+
+	* aha1740.c: Test for NULL pointer in SCtmp.  This should not
+	occur, but a nice message is better than a kernel segfault.
+
+	* 53c7,8xx.c: Add new PCI chip ID for 815.
+
+Fri Dec  2 11:24:53 1994  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.70 released.
+
+	* ChangeLog, st.c: Spelling.
+
+Tue Nov 29 18:48:42 1994  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.69 released.
+
+	* u14-34f.h: Non-functional change.  [Dario].
+
+	* u14-34f.c: Use block field in Scsi_Host to prevent commands from
+	being queued to more than one host at the same time (used when
+	motherboard does not deal with multiple bus-masters very well).
+	Only when SINGLE_HOST_OPERATIONS is defined.
+	Use new cmd_per_lun field.  [Dario]
+
+	* eata.c: Likewise.
+
+	* st.c: More changes from Kai.  Add ready flag to indicate drive
+	status.
+
+	* README.st: Document this.
+
+	* sr.c: Bugfix (do not subtract CD_BLOCK_OFFSET) for photo-cd
+	code.
+
+	* sg.c: Bugfix - fix problem where opcode is not correctly set up.
+
+	* seagate.[c,h]: Use #defines to set driver name.
+
+	* scsi_ioctl.c: Zero buffer before executing command.
+
+	* scsi.c: Use new cmd_per_lun field in Scsi_Hosts as appropriate.
+	Add Sony CDU55S to blacklist.
+
+	* hosts.h: Add new cmd_per_lun field to Scsi_Hosts.
+
+	* hosts.c: Initialize cmd_per_lun in Scsi_Hosts from template.
+
+	* buslogic.c: Use cmd_per_lun field - initialize to different
+	values depending upon bus type (i.e. use 1 if ISA, so we do not
+	hog memory).  Use other patches which got lost from 1.1.68.
+
+	* aha1542.c: Spelling.
+
+Tue Nov 29 15:43:50 1994  Eric Youngdale  (eric@andante.aib.com)
+
+	* Linux 1.1.68 released.
+
+	Add support for 12 byte vendor specific commands in scsi-generics,
+	more (i.e. the last mandatory) low-level changes to support
+	loadable modules, plus a few other changes people have requested
+	lately.  Changes by me (ERY) unless otherwise noted.  Spelling
+	changes appear from some unknown corner of the universe.
+
+	* Throughout: Change COMMAND_SIZE() to use SCpnt->cmd_len.
+
+	* Throughout: Change info() low level function to take a Scsi_Host
+	pointer.  This way the info function can return specific
+	information about the host in question, if desired.
+
+	* All low-level drivers: Add NULL in initializer for the
+	usage_count field added to Scsi_Host_Template.
+
+	* aha152x.[c,h]: Remove redundant info() function.
+
+	* aha1542.[c,h]: Likewise.
+
+	* aha1740.[c,h]: Likewise.
+
+	* aha274x.[c,h]: Likewise.
+
+	* eata.[c,h]: Likewise.
+
+	* pas16.[c,h]: Likewise.
+
+	* scsi_debug.[c,h]: Likewise.
+
+	* t128.[c,h]: Likewise.
+
+	* u14-34f.[c,h]: Likewise.
+
+	* ultrastor.[c,h]: Likewise.
+
+	* wd7000.[c,h]: Likewise.
+
+	* aha1542.c: Add support for command line options with lilo to set
+	DMA parameters, I/O port.  From Matt Aarnio.
+
+	* buslogic.[c,h]: New version (1.13) from Dave Gentzel.
+
+	* hosts.h: Add new field to Scsi_Hosts "block" to allow blocking
+	all I/O to certain other cards.  Helps prevent problems with some
+	ISA motherboards.
+
+	* hosts.h: Add usage_count to Scsi_Host_Template.
+
+	* hosts.h: Add n_io_port to Scsi_Host (used when releasing module).
+
+	* hosts.c: Initialize block field.
+
+	* in2000.c: Remove "static" declarations from exported functions.
+
+	* in2000.h: Likewise.
+
+	* scsi.c: Correctly set cmd_len field as required.  Save and
+	change setting when doing a request_sense, restore when done.
+	Move abort timeout message.  Fix panic in request_queueable to
+	print correct function name.
+
+	* scsi.c: When incrementing usage count, walk block linked list
+	for host, and or in SCSI_HOST_BLOCK bit.  When decrementing usage
+	count to 0, clear this bit to allow usage to continue, wake up
+	processes waiting.
+
+
+	* scsi_ioctl.c: If we have an info() function, call it, otherwise
+	if we have a "name" field, use it, else do nothing.
+
+	* sd.c, sr.c: Clear cmd_len field prior to each command we
+	generate.
+
+	* sd.h: Add "has_part_table" bit to rscsi_disks.
+
+	* sg.[c,h]: Add support for vendor specific 12 byte commands (i.e.
+	override command length in COMMAND_SIZE).
+
+	* sr.c: Bugfix from Gerd in photocd code.
+
+	* sr.c: Bugfix in get_sectorsize - always use scsi_malloc buffer -
+	we cannot guarantee that the stack is < 16Mb.
+
+Tue Nov 22 15:40:46 1994  Eric Youngdale  (eric@andante.aib.com)
+
+	* Linux 1.1.67 released.
+
+	* sr.c: Change spelling of manufactor to manufacturer.
+
+	* scsi.h: Likewise.
+
+	* scsi.c: Likewise.
+
+	* qlogic.c: Spelling corrections.
+
+	* in2000.h: Spelling corrections.
+
+	* in2000.c: Update from Bill Earnest, change from
+	jshiffle@netcom.com.  Support new bios versions.
+
+	* README.qlogic: Spelling correction.
+
+Tue Nov 22 15:40:46 1994  Eric Youngdale  (eric@andante.aib.com)
+
+	* Linux 1.1.66 released.
+
+	* u14-34f.c: Spelling corrections.
+
+	* sr.[h,c]: Add support for multi-session CDs from Gerd Knorr.
+
+	* scsi.h: Add manufactor field for keeping track of device
+	manufacturer.
+
+	* scsi.c: More spelling corrections.
+
+	* qlogic.h, qlogic.c, README.qlogic: New driver from Tom Zerucha.
+
+	* in2000.c, in2000.h: New driver from Brad McLean/Bill Earnest.
+
+	* fdomain.c: Spelling correction.
+
+	* eata.c: Spelling correction.
+
+Fri Nov 18 15:22:44 1994  Eric Youngdale  (eric@andante.aib.com)
+
+	* Linux 1.1.65 released.
+
+	* eata.h: Update version string to 1.08.00.
+
+	* eata.c: Set sg_tablesize correctly for DPT PM2012 boards.
+
+	* aha274x.seq: Spell checking.
+
+	* README.st: Likewise.
+
+	* README.aha274x: Likewise.
+
+	* ChangeLog: Likewise.
+
+Tue Nov 15 15:35:08 1994  Eric Youngdale  (eric@andante.aib.com)
+
+	* Linux 1.1.64 released.
+
+	* u14-34f.h: Update version number to 1.10.01.
+
+	* u14-34f.c: Use Scsi_Host can_queue variable instead of one from template.
+
+	* eata.[c,h]: New driver for DPT boards from Dario Ballabio.
+
+	* buslogic.c: Use can_queue field.
+
+Wed Nov 30 12:09:09 1994  Eric Youngdale  (eric@andante.aib.com)
+
+	* Linux 1.1.63 released.
+
+	* sd.c: Give I/O error if we attempt 512 byte I/O to a disk with
+	1024 byte sectors.
+
+	* scsicam.c: Make sure we do read from whole disk (mask off
+	partition).
+
+	* scsi.c: Use can_queue in Scsi_Host structure.
+	Fix panic message about invalid host.
+
+	* hosts.c: Initialize can_queue from template.
+
+	* hosts.h: Add can_queue to Scsi_Host structure.
+
+	* aha1740.c: Print out warning about NULL ecbptr.
+
+Fri Nov  4 12:40:30 1994  Eric Youngdale  (eric@andante.aib.com)
+
+	* Linux 1.1.62 released.
+
+	* fdomain.c: Update to version 5.20. (From Rik Faith).  Support
+	BIOS version 3.5.
+
+	* st.h: Add ST_EOD symbol.
+
+	* st.c: Patches from Kai Makisara - support additional densities,
+	add support for MTFSS, MTBSS, MTWSM commands.
+
+	* README.st: Update to document new commands.
+
+	* scsi.c: Add Mediavision CDR-H93MV to blacklist.
+
+Sat Oct 29 20:57:36 1994  Eric Youngdale  (eric@andante.aib.com)
+
+	* Linux 1.1.60 released.
+
+	* u14-34f.[c,h]: New driver from Dario Ballabio.
+
+	* aic7770.c, aha274x_seq.h, aha274x.seq, aha274x.h, aha274x.c,
+	README.aha274x: New files, new driver from John Aycock.
+
+
+Tue Oct 11 08:47:39 1994  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.54 released.
+
+	* Add third PCI chip id.  [Drew]
+
+	* buslogic.c: Set BUSLOGIC_CMDLUN back to 1 [Eric].
+
+	* ultrastor.c: Fix asm directives for new GCC.
+
+	* sr.c, sd.c: Use new end_scsi_request function.
+
+	* scsi.h(end_scsi_request): Return pointer to block if still
+	active, else return NULL if inactive.  Fixes race condition.
+
+Sun Oct  9 20:23:14 1994  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.53 released.
+
+	* scsi.c: Do not allocate dma bounce buffers if we have exactly
+	16Mb.
+
+Fri Sep  9 05:35:30 1994  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.51 released.
+
+	* aha152x.c: Add support for disabling the parity check.  Update
+	to version 1.4. [Juergen].
+
+	* seagate.c: Tweak debugging message.
+
+Wed Aug 31 10:15:55 1994  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.50 released.
+
+	* aha152x.c: Add eb800 for Vtech Platinum SMP boards. [Juergen].
+
+	* scsi.c: Add Quantum PD1225S to blacklist.
+
+Fri Aug 26 09:38:45 1994  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.49 released.
+
+	* sd.c: Fix bug when we were deleting the wrong entry if we
+	get an unsupported sector size device.
+
+	* sr.c: Another spelling patch.
+
+Thu Aug 25 09:15:27 1994  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.48 released.
+
+	* Throughout: Use new semantics for request_dma, as appropriate.
+
+	* sr.c: Print correct device number.
+
+Sun Aug 21 17:49:23 1994  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.47 released.
+
+	* NCR5380.c: Add support for LIMIT_TRANSFERSIZE.
+
+	* constants.h: Add prototype for print_Scsi_Cmnd.
+
+	* pas16.c: Some more minor tweaks.  Test for Mediavision board.
+	Allow for disks > 1Gb.  [Drew??]
+
+	* sr.c: Set SCpnt->transfersize.
+
+Tue Aug 16 17:29:35 1994  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.46 released.
+
+	* Throughout: More spelling fixups.
+
+	* buslogic.c: Add a few more fixups from Dave.  Disk translation
+	mainly.
+
+	* pas16.c: Add a few patches (Drew?).
+
+
+Thu Aug 11 20:45:15 1994  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.44 released.
+
+	* hosts.c: Add type casts for scsi_init_malloc.
+
+	* scsicam.c: Add type cast.
+
+Wed Aug 10 19:23:01 1994  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.43 released.
+
+	* Throughout: Spelling cleanups. [??]
+
+	* aha152x.c, NCR53*.c, fdomain.c, g_NCR5380.c, pas16.c, seagate.c,
+	 t128.c: Use request_irq, not irqaction. [??]
+
+	* aha1542.c: Move test for shost before we start to use shost.
+
+	* aha1542.c, aha1740.c, ultrastor.c, wd7000.c: Use new
+	calling sequence for request_irq.
+
+	* buslogic.c: Update from Dave Gentzel.
+
+Tue Aug  9 09:32:59 1994  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.42 released.
+
+	* NCR5380.c: Change NCR5380_print_status to static.
+
+	* seagate.c: A few more bugfixes.  Only Drew knows what they are
+	for.
+
+	* ultrastor.c: Tweak some __asm__ directives so that it works
+	with newer compilers. [??]
+
+Sat Aug  6 21:29:36 1994  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.40 released.
+
+	* NCR5380.c: Return SCSI_RESET_WAKEUP from reset function.
+
+	* aha1542.c: Reset mailbox status after a bus device reset.
+
+	* constants.c: Fix typo (;;).
+
+	* g_NCR5380.c:
+	* pas16.c:  Correct usage of NCR5380_init.
+
+	* scsi.c: Remove redundant (and unused variables).
+
+	* sd.c: Use memset to clear all of rscsi_disks before we use it.
+
+	* sg.c: Ditto, except for scsi_generics.
+
+	* sr.c: Ditto, except for scsi_CDs.
+
+	* st.c: Initialize STp->device.
+
+	* seagate.c: Fix bug. [Drew]
+
+Thu Aug  4 08:47:27 1994  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.39 released.
+
+	* Makefile: Fix typo in NCR53C7xx.
+
+	* st.c: Print correct number for device.
+
+Tue Aug  2 11:29:14 1994  Eric Youngdale  (eric@esp22)
+
+	* Linux 1.1.38 released.
+
+	Lots of changes in 1.1.38.  All from Drew unless otherwise noted.
+
+	* 53c7,8xx.c: New file from Drew.  PCI driver.
+
+	* 53c7,8xx.h: Likewise.
+
+	* 53c7,8xx.scr: Likewise.
+
+	* 53c8xx_d.h, 53c8xx_u.h, script_asm.pl: Likewise.
+
+	* scsicam.c: New file from Drew.  Read block 0 on the disk and
+	read the partition table.  Attempt to deduce the geometry from
+	the partition table if possible.  Only used by 53c[7,8]xx right
+	now, but could be used by any device for which we have no way
+	of identifying the geometry.
+
+	* sd.c: Use device letters instead of sd%d in a lot of messages.
+
+	* seagate.c: Fix bug that resulted in lockups with some devices.
+
+	* sr.c (sr_open): Return -EROFS, not -EACCES if we attempt to open
+	device for write.
+
+	* hosts.c, Makefile: Update for new driver.
+
+	* NCR5380.c, NCR5380.h, g_NCR5380.h: Update from Drew to support
+	53C400 chip.
+
+	* constants.c: Define CONST_CMND and CONST_MSG.  Other minor
+	cleanups along the way.  Improve handling of CONST_MSG.
+
+	* fdomain.c, fdomain.h: New version from Rik Faith.  Update to
+	5.18.  Should now support TMC-3260 PCI card with 18C30 chip.
+
+	* pas16.c: Update with new irq initialization.
+
+	* t128.c: Update with minor cleanups.
+
+	* scsi.c (scsi_pid): New variable - gives each command a unique
+	id. Add Quantum LPS5235S to blacklist.  Change in_scan to
+	in_scan_scsis and make global.
+
+	* scsi.h: Add some defines for extended message handling,
+	INITIATE/RELEASE_RECOVERY.  Add a few new fields to support sync
+	transfers.
+
+	* scsi_ioctl.h: Add ioctl to request synchronous transfers.
+
+
+Tue Jul 26 21:36:58 1994  Eric Youngdale  (eric@esp22)
+
+	* Linux 1.1.37 released.
+
+	* aha1542.c: Always call aha1542_mbenable, use new udelay
+	mechanism so we do not wait a long time if the board does not
+	implement this command.
+
+	* g_NCR5380.c: Remove #include <linux/config.h> and #if
+	defined(CONFIG_SCSI_*).
+
+	* seagate.c: Likewise.
+
+	Next round of changes to support loadable modules.  Getting closer
+	now, still not possible to do anything remotely usable.
+
+	hosts.c: Create a linked list of detected high level devices.
+	(scsi_register_device): New function to insert into this list.
+	(scsi_init): Call scsi_register_device for each of the known high
+	level drivers.
+
+	hosts.h: Add prototype for linked list header.  Add structure
+	definition for device template structure which defines the linked
+	list.
+
+	scsi.c: (scan_scsis): Use linked list instead of knowledge about
+	existing high level device drivers.
+	(scsi_dev_init): Use init functions for drivers on linked list
+	instead of explicit list to initialize and attach devices to high
+	level drivers.
+
+	scsi.h: Add new field "attached" to scsi_device - count of number
+	of high level devices attached.
+
+	sd.c, sr.c, sg.c, st.c: Adjust init/attach functions to use new
+	scheme.
+
+Sat Jul 23 13:03:17 1994  Eric Youngdale  (eric@esp22)
+
+	* Linux 1.1.35 released.
+
+	* ultrastor.c: Change constraint on asm() operand so that it works
+	with gcc 2.6.0.
+
+Thu Jul 21 10:37:39 1994  Eric Youngdale  (eric@esp22)
+
+	* Linux 1.1.33 released.
+
+	* sr.c(sr_open): Do not allow opens with write access.
+
+Mon Jul 18 09:51:22 1994 1994  Eric Youngdale  (eric@esp22)
+
+	* Linux 1.1.31 released.
+
+	* sd.c: Increase SD_TIMEOUT from 300 to 600.
+
+	* sr.c: Remove stray task_struct* variable that was no longer
+	used.
+
+	* sr_ioctl.c: Fix typo in up() call.
+
+Sun Jul 17 16:25:29 1994  Eric Youngdale  (eric@esp22)
+
+	* Linux 1.1.30 released.
+
+	* scsi.c (scan_scsis): Fix detection of some Toshiba CDROM drives
+	that report themselves as disk drives.
+
+	* (Throughout): Use request.sem instead of request.waiting.
+	Should fix swap problem with fdomain.
+
+Thu Jul 14 10:51:42 1994  Eric Youngdale  (eric@esp22)
+
+	* Linux 1.1.29 released.
+
+	* scsi.c (scan_scsis): Add new devices to end of linked list, not
+	to the beginning.
+
+	* scsi.h (SCSI_SLEEP): Remove brain dead hack to try to save
+	the task state before sleeping.
+
+Sat Jul  9 15:01:03 1994  Eric Youngdale  (eric@esp22)
+
+	More changes to eventually support loadable modules.  Mainly
+	we want to use linked lists instead of arrays because it is easier
+	to dynamically add and remove things this way.
+
+	Quite a bit more work is needed before loadable modules are
+	possible (and usable) with scsi, but this is most of the grunge
+	work.
+
+	* Linux 1.1.28 released.
+
+	* scsi.c, scsi.h (allocate_device, request_queueable): Change
+	argument from index into scsi_devices to a pointer to the
+	Scsi_Device struct.
+
+	* Throughout: Change all calls to allocate_device,
+	request_queueable to use new calling sequence.
+
+	* Throughout: Use SCpnt->device instead of
+	scsi_devices[SCpnt->index].  Ugh - the pointer was there all along
+	- much cleaner this way.
+
+	* scsi.c (scsi_init_malloc, scsi_free_malloc): New functions -
+	allow us to pretend that we have a working malloc when we
+	initialize.  Use this instead of passing memory_start, memory_end
+	around all over the place.
+
+	* scsi.h, st.c, sr.c, sd.c, sg.c: Change *_init1 functions to use
+	scsi_init_malloc, remove all arguments, no return value.
+
+	* scsi.h: Remove index field from Scsi_Device and Scsi_Cmnd
+	structs.
+
+	* scsi.c (scsi_dev_init): Set up for scsi_init_malloc.
+	(scan_scsis): Get SDpnt from scsi_init_malloc, and refresh
+	when we discover a device.  Free pointer before returning.
+	Change scsi_devices into a linked list.
+
+	* scsi.c (scan_scsis): Change to only scan one host.
+	(scsi_dev_init): Loop over all detected hosts, and scan them.
+
+	* hosts.c  (scsi_init_free): Change so that  number of extra bytes
+	is stored in struct, and we do not have to pass it each time.
+
+	* hosts.h: Change Scsi_Host_Template struct to include "next" and
+	"release" functions.  Initialize to NULL in all low level
+	adapters.
+
+	* hosts.c: Rename scsi_hosts to builtin_scsi_hosts, create linked
+	list scsi_hosts, linked together with the new "next" field.
+
+Wed Jul  6 05:45:02 1994  Eric Youngdale  (eric@esp22)
+
+	* Linux 1.1.25 released.
+
+	* aha152x.c: Changes from Juergen - cleanups and updates.
+
+	* sd.c, sr.c: Use new check_media_change and revalidate
+	file_operations fields.
+
+	* st.c, st.h: Add changes from Kai Makisara, dated Jun 22.
+
+	* hosts.h: Change SG_ALL back to 0xff.  Apparently soft error
+	in /dev/brain resulted in having this bumped up.
+	Change first parameter in bios_param function to be Disk * instead
+	of index into rscsi_disks.
+
+	* sd_ioctl.c: Pass pointer to rscsi_disks element instead of index
+	to array.
+
+	* sd.h: Add struct name "scsi_disk" to typedef for Scsi_Disk.
+
+	* scsi.c: Remove redundant Maxtor XT8760S from blacklist.
+	In scsi_reset, add printk when DEBUG defined.
+
+	* All low level drivers: Modify definitions of bios_param in
+	appropriate way.
+
+Thu Jun 16 10:31:59 1994  Eric Youngdale  (eric@esp22)
+
+	* Linux 1.1.20 released.
+
+	* scsi_ioctl.c: Only pass down the actual number of characters
+	required to scsi_do_cmd, not the one rounded up to a even number
+	of sectors.
+
+	* ultrastor.c: Changes from Caleb Epstein for 24f cards.  Support
+	larger SG lists.
+
+	* ultrastor.c: Changes from me - use scsi_register to register
+	host.  Add some consistency checking,
+
+Wed Jun  1 21:12:13 1994  Eric Youngdale  (eric@esp22)
+
+	* Linux 1.1.19 released.
+
+	* scsi.h: Add new return code for reset() function:
+	SCSI_RESET_PUNT.
+
+	* scsi.c: Make SCSI_RESET_PUNT the same as SCSI_RESET_WAKEUP for
+	now.
+
+	* aha1542.c: If the command responsible for the reset is not
+	pending, return SCSI_RESET_PUNT.
+
+	* aha1740.c, buslogic.c, wd7000.c, ultrastor.c: Return
+	SCSI_RESET_PUNT instead of SCSI_RESET_SNOOZE.
+
+Tue May 31 19:36:01 1994  Eric Youngdale  (eric@esp22)
+
+	* buslogic.c: Do not print out message about "must be Adaptec"
+	if we have detected a buslogic card.  Print out a warning message
+	if we are configuring for >16Mb, since the 445S at board level
+	D or earlier does not work right.  The "D" level board can be made
+	to work by flipping an undocumented switch, but this is too subtle.
+
+    Changes based upon patches in Yggdrasil distribution.
+
+	* sg.c, sg.h: Return sense data to user.
+
+	* aha1542.c, aha1740.c, buslogic.c: Do not panic if
+	sense buffer is wrong size.
+
+	* hosts.c: Test for ultrastor card before any of the others.
+
+	* scsi.c: Allow boot-time option for max_scsi_luns=? so that
+	buggy firmware has an easy work-around.
+
+Sun May 15 20:24:34 1994  Eric Youngdale  (eric@esp22)
+
+	* Linux 1.1.15 released.
+
+	Post-codefreeze thaw...
+
+	* buslogic.[c,h]: New driver from David Gentzel.
+
+	* hosts.h: Add use_clustering field to explicitly say whether
+	clustering should be used for devices attached to this host
+	adapter.  The buslogic board apparently supports large SG lists,
+	but it is apparently faster if sd.c condenses this into a smaller
+	list.
+
+	* sd.c: Use this field instead of heuristic.
+
+	* All host adapter include files: Add appropriate initializer for
+	use_clustering field.
+
+	* scsi.h: Add #defines for return codes for the abort and reset
+	functions.  There are now a specific set of return codes to fully
+	specify all of the possible things that the low-level adapter
+	could do.
+
+	* scsi.c: Act based upon return codes from abort/reset functions.
+
+	* All host adapter abort/reset functions: Return new return code.
+
+	* Add code in scsi.c to help debug timeouts.  Use #define
+	DEBUG_TIMEOUT to enable this.
+
+	* scsi.c: If the host->irq field is set, use
+	disable_irq/enable_irq before calling queuecommand if we
+	are not already in an interrupt.  Reduce races, and we
+	can be sloppier about cli/sti in the interrupt routines now
+	(reduce interrupt latency).
+
+	* constants.c: Fix some things to eliminate warnings.  Add some
+	sense descriptions that were omitted before.
+
+	* aha1542.c: Watch for SCRD from host adapter - if we see it, set
+	a flag.  Currently we only print out the number of pending
+	commands that might need to be restarted.
+
+	* aha1542.c (aha1542_abort): Look for lost interrupts, OGMB still
+	full, and attempt to recover.  Otherwise give up.
+
+	* aha1542.c (aha1542_reset): Try BUS DEVICE RESET, and then pass
+	DID_RESET back up to the upper level code for all commands running
+	on this target (even on different LUNs).
+
+Sat May  7 14:54:01 1994
+
+	* Linux 1.1.12 released.
+
+	* st.c, st.h: New version from Kai.  Supports boot time
+	specification of number of buffers.
+
+	* wd7000.[c,h]: Updated driver from John Boyd.  Now supports
+	more than one wd7000 board in machine at one time, among other things.
+
+Wed Apr 20 22:20:35 1994
+
+	* Linux 1.1.8 released.
+
+	* sd.c: Add a few type casts where scsi_malloc is called.
+
+Wed Apr 13 12:53:29 1994
+
+	* Linux 1.1.4 released.
+
+	* scsi.c: Clean up a few printks (use %p to print pointers).
+
+Wed Apr 13 11:33:02 1994
+
+	* Linux 1.1.3 released.
+
+	* fdomain.c: Update to version 5.16 (Handle different FIFO sizes
+	better).
+
+Fri Apr  8 08:57:19 1994
+
+	* Linux 1.1.2 released.
+
+	* Throughout: SCSI portion of cluster diffs added.
+
+Tue Apr  5 07:41:50 1994
+
+	* Linux 1.1 development tree initiated.
+
+	* The linux 1.0 development tree is now effectively frozen except
+	for obvious bugfixes.
+
+******************************************************************
+******************************************************************
+******************************************************************
+******************************************************************
+
+Sun Apr 17 00:17:39 1994
+
+	* Linux 1.0, patchlevel 9 released.
+
+	* fdomain.c: Update to version 5.16 (Handle different FIFO sizes
+	better).
+
+Thu Apr  7 08:36:20 1994
+
+	* Linux 1.0, patchlevel8 released.
+
+	* fdomain.c: Update to version 5.15 from 5.9.  Handles 3.4 bios.
+
+Sun Apr  3 14:43:03 1994
+
+	* Linux 1.0, patchlevel6 released.
+
+	* wd7000.c: Make stab at fixing race condition.
+
+Sat Mar 26 14:14:50 1994
+
+	* Linux 1.0, patchlevel5 released.
+
+	* aha152x.c, Makefile: Fix a few bugs (too much data message).
+	Add a few more bios signatures. (Patches from Juergen).
+
+	* aha1542.c: Fix race condition in aha1542_out.
+
+Mon Mar 21 16:36:20 1994
+
+	* Linux 1.0, patchlevel3 released.
+
+	* sd.c, st.c, sr.c, sg.c: Return -ENXIO, not -ENODEV if we attempt
+	to open a non-existent device.
+
+	* scsi.c: Add Chinon cdrom to blacklist.
+
+	* sr_ioctl.c: Check return status of verify_area.
+
+Sat Mar  6 16:06:19 1994
+
+	* Linux 1.0 released (technically a pre-release).
+
+	* scsi.c: Add IMS CDD521, Maxtor XT-8760S to blacklist.
+
+Tue Feb 15 10:58:20 1994
+
+        * pl15e released.
+
+        * aha1542.c: For 1542C, allow dynamic device scan with >1Gb turned
+	off.
+
+	* constants.c: Fix typo in definition of CONSTANTS.
+
+        * pl15d released.
+
+Fri Feb 11 10:10:16 1994
+
+        * pl15c released.
+
+	* scsi.c: Add Maxtor XT-3280 and Rodime RO3000S to blacklist.
+
+	* scsi.c: Allow tagged queueing for scsi 3 devices as well.
+	Some really old devices report a version number of 0.  Disallow
+	LUN != 0 for these.
+
+Thu Feb 10 09:48:57 1994
+
+        * pl15b released.
+
+Sun Feb  6 12:19:46 1994
+
+        * pl15a released.
+
+Fri Feb  4 09:02:17 1994
+
+        * scsi.c: Add Teac cdrom to blacklist.
+
+Thu Feb  3 14:16:43 1994
+
+	* pl15 released.
+
+Tue Feb  1 15:47:43 1994
+
+	* pl14w released.
+
+	* wd7000.c (wd_bases): Fix typo in last change.
+
+Mon Jan 24 17:37:23 1994
+
+	* pl14u released.
+
+	* aha1542.c: Support 1542CF/extended bios.  Different from 1542C
+
+	* wd7000.c: Allow bios at 0xd8000 as well.
+
+	* ultrastor.c: Do not truncate cylinders to 1024.
+
+	* fdomain.c: Update to version 5.9 (add new bios signature).
+
+	* NCR5380.c: Update from Drew - should work a lot better now.
+
+Sat Jan  8 15:13:10 1994
+
+	* pl14o released.
+
+	* sr_ioctl.c: Zero reserved field before trying to set audio volume.
+
+Wed Jan  5 13:21:10 1994
+
+	* pl14m released.
+
+	* fdomain.c: Update to version 5.8.  No functional difference???
+
+Tue Jan  4 14:26:13 1994
+
+	* pl14l released.
+
+	* ultrastor.c: Remove outl, inl functions (now provided elsewhere).
+
+Mon Jan  3 12:27:25 1994
+
+	* pl14k released.
+
+	* aha152x.c: Remove insw and outsw functions.
+
+	* fdomain.c: Ditto.
+
+Wed Dec 29 09:47:20 1993
+
+	* pl14i released.
+
+	* scsi.c: Support RECOVERED_ERROR for tape drives.
+
+	* st.c: Update of tape driver from Kai.
+
+Tue Dec 21 09:18:30 1993
+
+	* pl14g released.
+
+	* aha1542.[c,h]: Support extended BIOS stuff.
+
+	* scsi.c: Clean up messages about disks, so they are displayed as
+	sda, sdb, etc instead of sd0, sd1, etc.
+
+	* sr.c:  Force reread of capacity if disk was changed.
+	Clear buffer before asking for capacity/sectorsize (some drives
+	do not report this properly).  Set needs_sector_size flag if
+	drive did not return sensible sector size.
+
+Mon Dec 13 12:13:47 1993
+
+	* aha152x.c: Update to version .101 from Juergen.
+
+Mon Nov 29 03:03:00 1993
+
+        * linux 0.99.14 released.
+
+	* All scsi stuff moved from kernel/blk_drv/scsi to drivers/scsi.
+
+	* Throughout: Grammatical corrections to various comments.
+
+	* Makefile: fix so that we do not need to compile things we are
+	not going to use.
+
+	* NCR5380.c, NCR5380.h, g_NCR5380.c, g_NCR5380.h, pas16.c,
+	pas16.h, t128.c, t128.h:  New files from Drew.
+
+	* aha152x.c, aha152x.h: New files from Juergen Fischer.
+
+	* aha1542.c: Support for more than one 1542 in the machine
+	at the same time.  Make functions static that do not need
+	visibility.
+
+	* aha1740.c: Set NEEDS_JUMPSTART flag in reset function, so we
+	know to restart the command.  Change prototype of aha1740_reset
+	to take a command pointer.
+
+	* constants.c: Clean up a few things.
+
+	* fdomain.c: Update to version 5.6.  Move snarf_region.  Allow
+	board to be set at different SCSI ids.  Remove support for
+	reselection (did not work well).  Set JUMPSTART flag in reset
+	code.
+
+	* hosts.c: Support new low-level adapters.  Allow for more than
+	one adapter of a given type.
+
+	* hosts.h: Allow for more than one adapter of a given type.
+
+	* scsi.c:  Add scsi_device_types array, if NEEDS_JUMPSTART is set
+	after a low-level reset, start the command again.  Sort blacklist,
+	and add Maxtor MXT-1240S, XT-4170S, NEC CDROM 84, Seagate ST157N.
+
+	* scsi.h: Add constants for tagged queueing.
+
+	* Throughout: Use constants from major.h instead of hardcoded
+	numbers for major numbers.
+
+	* scsi_ioctl.c: Fix bug in buffer length in ioctl_command.  Use
+	verify_area in GET_IDLUN ioctl.  Add new ioctls for
+	TAGGED_QUEUE_ENABLE, DISABLE.  Only allow IOCTL_SEND_COMMAND by
+	superuser.
+
+	* sd.c: Only pay attention to UNIT_ATTENTION for removable disks.
+	Fix bug where sometimes portions of blocks would get lost
+	resulting in processes hanging.  Add messages when we spin up a
+	disk, and fix a bug in the timing.  Increase read-ahead for disks
+	that are on a scatter-gather capable host adapter.
+
+	* seagate.c: Fix so that some parameters can be set from the lilo
+	prompt.  Supply jumpstart flag if we are resetting and need the
+	command restarted.   Fix so that we return 1 if we detect a card
+	so that multiple card detection works correctly.  Add yet another
+	signature for FD cards (950).  Add another signature for ST0x.
+
+	* sg.c, sg.h: New files from Lawrence Foard for generic scsi
+	access.
+
+	* sr.c:  Add type casts for (void*) so that we can do pointer
+	arithmetic.  Works with GCC without this, but it is not strictly
+	correct.  Same bugfix as was in sd.c.  Increase read-ahead a la
+	disk driver.
+
+	* sr_ioctl.c: Use scsi_malloc buffer instead of buffer from stack
+	since we cannot guarantee that the stack is < 16Mb.
+
+	ultrastor.c: Update to support 24f properly (JFC's driver).
+
+	wd7000.c: Supply jumpstart flag for reset.  Do not round up
+	number of cylinders in biosparam function.
+
+Sat Sep  4 20:49:56 1993
+
+    * 0.99pl13 released.
+
+    * Throughout:  Use check_region/snarf_region for all low-level
+    drivers.
+
+    * aha1542.c: Do hard reset instead of soft (some ethercard probes
+    screw us up).
+
+    * scsi.c: Add new flag ASKED_FOR_SENSE so that we can tell if we are
+    in a loop whereby the device returns null sense data.
+
+    * sd.c: Add code to spin up a drive if it is not already spinning.
+    Do this one at a time to make it easier on power supplies.
+
+    * sd_ioctl.c: Use sync_dev instead of fsync_dev in BLKFLSBUF ioctl.
+
+    * seagate.c: Switch around DATA/CONTROL lines.
+
+    * st.c: Change sense to unsigned.
+
+Thu Aug  5 11:59:18 1993
+
+    * 0.99pl12 released.
+
+    * constants.c, constants.h: New files with ascii descriptions of
+    various conditions.
+
+    * Makefile: Do not try to count the number of low-level drivers,
+    just generate the list of .o files.
+
+    * aha1542.c: Replace 16 with sizeof(SCpnt->sense_buffer).  Add tests
+    for addresses > 16Mb, panic if we find one.
+
+    * aha1740.c: Ditto with sizeof().
+
+    * fdomain.c: Update to version 3.18.  Add new signature, register IRQ
+    with irqaction.  Use ID 7 for new board.  Be more intelligent about
+    obtaining the h/s/c numbers for biosparam.
+
+    * hosts.c: Do not depend upon Makefile generated count of the number
+    of low-level host adapters.
+
+    * scsi.c: Use array for scsi_command_size instead of a function.  Add
+    Texel cdrom and Maxtor XT-4380S to blacklist.  Allow compile time
+    option for no-multi lun scan.  Add semaphore for possible problems
+    with handshaking, assume device is faulty until we know it not to be
+    the case.  Add DEBUG_INIT symbol to dump info as we scan for devices.
+    Zero sense buffer so we can tell if we need to request it.  When
+    examining sense information, request sense if buffer is all zero.
+    If RESET, request sense information to see what to do next.
+
+    * scsi_debug.c: Change some constants to use symbols like INT_MAX.
+
+    * scsi_ioctl.c (kernel_scsi_ioctl): New function -for making ioctl
+    calls from kernel space.
+
+    * sd.c: Increase timeout to 300.  Use functions in constants.h to
+    display info.  Use scsi_malloc buffer for READ_CAPACITY, since
+    we cannot guarantee that a stack based buffer is < 16Mb.
+
+    * sd_ioctl.c: Add BLKFLSBUF ioctl.
+
+    * seagate.c: Add new compile time options for ARBITRATE,
+    SLOW_HANDSHAKE, and SLOW_RATE.  Update assembly loops for transferring
+    data.  Use kernel_scsi_ioctl to request mode page with geometry.
+
+    * sr.c: Use functions in constants.c to display messages.
+
+    * st.c: Support for variable block size.
+
+    * ultrastor.c: Do not use cache for tape drives.  Set
+    unchecked_isa_dma flag, even though this may not be needed (gets set
+    later).
+
+Sat Jul 17 18:32:44 1993
+
+    * 0.99pl11 released.  C++ compilable.
+
+    * Throughout: Add type casts all over the place, and use "ip" instead
+    of "info" in the various biosparam functions.
+
+    * Makefile: Compile seagate.c with C++ compiler.
+
+    * aha1542.c: Always set ccb pointer as this gets trashed somehow on
+    some systems.  Add a few type casts.  Update biosparam function a little.
+
+    * aha1740.c: Add a few type casts.
+
+    * fdomain.c: Update to version 3.17 from 3.6.  Now works with
+    TMC-18C50.
+
+    * scsi.c: Minor changes here and there with datatypes.  Save use_sg
+    when requesting sense information so that this can properly be
+    restored if we retry the command.  Set aside dma buffers assuming each
+    block is 1 page, not 1Kb minix block.
+
+    * scsi_ioctl.c: Add a few type casts.  Other minor changes.
+
+    * sd.c:  Correctly  free all scsi_malloc'd memory if we run out of
+    dma_pool. Store blocksize information for each partition.
+
+    * seagate.c: Minor cleanups here and there.
+
+    * sr.c: Set up blocksize array for all discs.  Fix bug in freeing
+    buffers if we run out of dma pool.
+
+Thu Jun  2 17:58:11 1993
+
+    * 0.99pl10 released.
+
+    * aha1542.c: Support for BT 445S (VL-bus board with no dma channel).
+
+    * fdomain.c: Upgrade to version 3.6. Preliminary support for TNC-18C50.
+
+    * scsi.c: First attempt to fix problem with old_use_sg.  Change
+    NOT_READY to a SUGGEST_ABORT.  Fix timeout race where time might
+    get decremented past zero.
+
+    * sd.c: Add block_fsync function to dispatch table.
+
+    * sr.c: Increase timeout to 500 from 250.  Add entry for sync in
+    dispatch table (supply NULL).  If we do not have a sectorsize,
+    try to get it in the sd_open function.  Add new function just to
+    obtain sectorsize.
+
+    * sr.h: Add needs_sector_size semaphore.
+
+    * st.c: Add NULL for fsync in dispatch table.
+
+    * wd7000.c: Allow another condition for power on that are normal
+    and do not require a panic.
+
+Thu Apr 22 23:10:11 1993
+
+    * 0.99pl9 released.
+
+    * aha1542.c: Use (void) instead of () in setup_mailboxes.
+
+    * scsi.c: Initialize transfersize and underflow fields in SCmd to 0.
+    Do not panic for unsupported message bytes.
+
+    * scsi.h: Allocate 12 bytes instead of 10 for commands.  Add
+    transfersize and underflow fields.
+
+    * scsi_ioctl.c: Further bugfix to ioctl_probe.
+
+    * sd.c: Use long instead of int for last parameter in sd_ioctl.
+    Initialize transfersize and underflow fields.
+
+    * sd_ioctl.c: Ditto for sd_ioctl(,,,,);
+
+    * seagate.c: New version from Drew.  Includes new signatures for FD
+    cards.  Support for 0ws jumper. Correctly initialize
+    scsi_hosts[hostnum].this_id.  Improved handing of
+    disconnect/reconnect, and support command linking.  Use
+    transfersize and underflow fields.  Support scatter-gather.
+
+    * sr.c, sr_ioctl.c: Use long instead of int for last parameter in sr_ioctl.
+    Use buffer and buflength in do_ioctl.  Patches from Chris Newbold for
+    scsi-2 audio commands.
+
+    * ultrastor.c: Comment out in_byte (compiler warning).
+
+    * wd7000.c: Change () to (void) in wd7000_enable_dma.
+
+Wed Mar 31 16:36:25 1993
+
+    * 0.99pl8 released.
+
+    * aha1542.c: Handle mailboxes better for 1542C.
+        Do not truncate number of cylinders at 1024 for biosparam call.
+
+    * aha1740.c: Fix a few minor bugs for multiple devices.
+        Same as above for biosparam.
+
+    * scsi.c: Add lockable semaphore for removable devices that can have
+    media removal prevented.  Add another signature for flopticals.
+    (allocate_device): Fix race condition.  Allow more space in dma pool
+    for blocksizes of up to 4Kb.
+
+    * scsi.h: Define COMMAND_SIZE.  Define a SCSI specific version of
+    INIT_REQUEST that can run with interrupts off.
+
+    * scsi_ioctl.c: Make ioctl_probe function more idiot-proof.  If
+    a removable device says ILLEGAL REQUEST to a door-locking command,
+    clear lockable flag.  Add SCSI_IOCTL_GET_IDLUN ioctl.  Do not attempt
+    to lock door for devices that do not have lockable semaphore set.
+
+    * sd.c: Fix race condition for multiple disks.  Use INIT_SCSI_REQUEST
+    instead of INIT_REQUEST.  Allow sector sizes of 1024 and 256.  For
+    removable disks that are not ready, mark them as having a media change
+    (some drives do not report this later).
+
+    * seagate.c: Use volatile keyword for memory-mapped register pointers.
+
+    * sr.c: Fix race condition, a la sd.c.  Increase the number of retries
+    to 1.  Use INIT_SCSI_REQUEST.  Allow 512 byte sector sizes.  Do a
+    read_capacity when we init the device so we know the size and
+    sectorsize.
+
+    * st.c: If ioctl not found in st.c, try scsi_ioctl for others.
+
+    * ultrastor.c: Do not truncate number of cylinders at 1024 for
+    biosparam call.
+
+    * wd7000.c: Ditto.
+    Throughout: Use COMMAND_SIZE macro to determine length of scsi
+    command.
+
+
+
+Sat Mar 13 17:31:29 1993
+
+    * 0.99pl7 released.
+
+    Throughout: Improve punctuation in some messages, and use new
+    verify_area syntax.
+
+    * aha1542.c: Handle unexpected interrupts better.
+
+    * scsi.c: Ditto.  Handle reset conditions a bit better, asking for
+    sense information and retrying if required.
+
+    * scsi_ioctl.c: Allow for 12 byte scsi commands.
+
+    * ultrastor.c: Update to use scatter-gather.
+
+Sat Feb 20 17:57:15 1993
+
+    * 0.99pl6 released.
+
+    * fdomain.c: Update to version 3.5.  Handle spurious interrupts
+    better.
+
+    * sd.c: Use register_blkdev function.
+
+    * sr.c: Ditto.
+
+    * st.c: Use register_chrdev function.
+
+    * wd7000.c: Undo previous change.
+
+Sat Feb  6 11:20:43 1993
+
+    * 0.99pl5 released.
+
+    * scsi.c: Fix bug in testing for UNIT_ATTENTION.
+
+    * wd7000.c: Check at more addresses for bios.  Fix bug in biosparam
+    (heads & sectors turned around).
+
+Wed Jan 20 18:13:59 1993
+
+    * 0.99pl4 released.
+
+    * scsi.c: Ignore leading spaces when looking for blacklisted devices.
+
+    * seagate.c: Add a few new signatures for FD cards.  Another patch
+    with SCint to fix race condition.  Use recursion_depth to keep track
+    of how many times we have been recursively called, and do not start
+    another command unless we are on the outer level.  Fixes bug
+    with Syquest cartridge drives (used to crash kernel), because
+    they do not disconnect with large data transfers.
+
+Tue Jan 12 14:33:36 1993
+
+    * 0.99pl3 released.
+
+    * fdomain.c: Update to version 3.3 (a few new signatures).
+
+    * scsi.c: Add CDU-541, Denon DRD-25X to blacklist.
+    (allocate_request, request_queueable): Init request.waiting to NULL if
+    non-buffer type of request.
+
+    * seagate.c:  Allow controller to be overridden with CONTROLLER symbol.
+    Set SCint=NULL when we are done, to remove race condition.
+
+    * st.c: Changes from Kai.
+
+Wed Dec 30 20:03:47 1992
+
+    * 0.99pl2 released.
+
+    * scsi.c: Blacklist back in.  Remove Newbury drive as other bugfix
+    eliminates need for it here.
+
+    * sd.c: Return ENODEV instead of EACCES if no such device available.
+    (sd_init) Init blkdev_fops earlier so that sd_open is available sooner.
+
+    * sr.c: Same as above for sd.c.
+
+    * st.c: Return ENODEV instead of ENXIO if no device.  Init chrdev_fops
+    sooner, so that it is always there even if no tapes.
+
+    * seagate.c (controller_type): New variable to keep track of ST0x or
+    FD.  Modify signatures list to indicate controller type, and init
+    controller_type once we find a match.
+
+    * wd7000.c (wd7000_set_sync): Remove redundant function.
+
+Sun Dec 20 16:26:24 1992
+
+    * 0.99pl1 released.
+
+    * scsi_ioctl.c: Bugfix - check dev->index, not dev->id against
+    NR_SCSI_DEVICES.
+
+    * sr_ioctl.c: Verify that device exists before allowing an ioctl.
+
+    * st.c: Patches from Kai - change timeout values, improve end of tape
+    handling.
+
+Sun Dec 13 18:15:23 1992
+
+    * 0.99 kernel released.  Baseline for this ChangeLog.
diff -Nru a/Documentation/scsi/ChangeLog.megaraid b/Documentation/scsi/ChangeLog.megaraid
--- a/Documentation/scsi/ChangeLog.megaraid	2005-03-01 23:39:17 -08:00
+++ b/Documentation/scsi/ChangeLog.megaraid	2005-03-01 23:39:17 -08:00
@@ -1,3 +1,105 @@
+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)
+
+1.	Modified name of two attributes in scsi_host_template.
+	On Wed, 2005-02-02 at 10:56 -0500, Ju, Seokmann wrote:
+	> +	.sdev_attrs			= megaraid_device_attrs,
+	> +	.shost_attrs			= megaraid_class_device_attrs,
+
+	These are, perhaps, slightly confusing names.
+	The terms device and class_device have well defined meanings in the
+	generic device model, neither of which is what you mean here.
+	Why not simply megaraid_sdev_attrs and megaraid_shost_attrs?
+
+	Other than this, it looks fine to me too.
+
+Release Date	: Thu Jan 27 00:01:03 EST 2005 - Atul Mukker <atulm@lsil.com>
+Current Version	: 2.20.4.4 (scsi module), 2.20.2.5 (cmm module)
+Older Version	: 2.20.4.3 (scsi module), 2.20.2.4 (cmm module)
+
+1.	Bump up the version of scsi module due to its conflict.
+
+Release Date	: Thu Jan 21 00:01:03 EST 2005 - Atul Mukker <atulm@lsil.com>
+Current Version	: 2.20.4.3 (scsi module), 2.20.2.5 (cmm module)
+Older Version	: 2.20.4.2 (scsi module), 2.20.2.4 (cmm module)
+
+1.	Remove driver ioctl for logical drive to scsi address translation and
+	replace with the sysfs attribute. To remove drives and change
+	capacity, application shall now use the device attribute to get the
+	logical drive number for a scsi device. For adding newly created
+	logical drives, class device attribute would be required to uniquely
+	identify each controller.
+		- Atul Mukker <atulm@lsil.com>
+
+	"James, I've been thinking about this a little more, and you may be on
+	to something here. Let each driver add files as such:"
+
+		- Matt Domsch <Matt_Domsch@dell.com>, 12.15.2004
+		 linux-scsi mailing list
+
+
+	"Then, if you simply publish your LD number as an extra parameter of
+	the device, you can look through /sys to find it."
+
+		- James Bottomley <James.Bottomley@SteelEye.com>, 01.03.2005
+		 linux-scsi mailing list
+
+
+	"I don't see why not ... it's your driver, you can publish whatever
+	extra information you need as scsi_device attributes; that was one of
+	the designs of the extensible attribute system."
+
+		- James Bottomley <James.Bottomley@SteelEye.com>, 01.06.2005
+		 linux-scsi mailing list
+
+2.	Add AMI megaraid support - Brian King <brking@charter.net>
+		PCI_VENDOR_ID_AMI, PCI_DEVICE_ID_AMI_MEGARAID3,
+		PCI_VENDOR_ID_AMI, PCI_SUBSYS_ID_PERC3_DC,
+
+3.	Make some code static - Adrian Bunk <bunk@stusta.de>
+	Date:	Mon, 15 Nov 2004 03:14:57 +0100
+
+	The patch below makes some needlessly global code static.
+	-wait_queue_head_t wait_q;
+	+static wait_queue_head_t wait_q;
+
+	Signed-off-by: Adrian Bunk <bunk@stusta.de>
+
+4.	Added NEC ROMB support - NEC MegaRAID PCI Express ROMB controller
+		PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_MEGARAID_NEC_ROMB_2E,
+		PCI_SUBSYS_ID_NEC, PCI_SUBSYS_ID_MEGARAID_NEC_ROMB_2E,
+
+5.	Fixed Tape drive issue : For any Direct CDB command to physical device
+	including tape, timeout value set by driver was 10 minutes. With this 
+	value, most of command will return within timeout. However, for those
+	command like ERASE or FORMAT, it takes more than an hour depends on
+	capacity of the device and the command could be terminated before it 
+	completes.
+	To address this issue, the 'timeout' field in the DCDB command will 
+	have NO TIMEOUT (i.e., 4) value as its timeout on DCDB command.
+
+
+
+Release Date	: Thu Dec  9 19:10:23 EST 2004
+	- Sreenivas Bagalkote <sreenib@lsil.com>
+
+Current Version	: 2.20.4.2 (scsi module), 2.20.2.4 (cmm module)
+Older Version	: 2.20.4.1 (scsi module), 2.20.2.3 (cmm module)
+
+i.	Introduced driver ioctl that returns scsi address for a given ld.
+	
+	"Why can't the existing sysfs interfaces be used to do this?"
+		- Brian King (brking@us.ibm.com)
+	
+	"I've looked into solving this another way, but I cannot see how
+	to get this driver-private mapping of logical drive number-> HCTL
+	without putting code something like this into the driver."
+
+	"...and by providing a mapping a function to userspace, the driver
+	is free to change its mapping algorithm in the future if necessary .."
+		- Matt Domsch (Matt_Domsch@dell.com)
+
 Release Date	: Thu Dec  9 19:02:14 EST 2004 - Sreenivas Bagalkote <sreenib@lsil.com>
 
 Current Version	: 2.20.4.1 (scsi module), 2.20.2.3 (cmm module)
@@ -13,7 +115,7 @@
 i.	Handle IOCTL cmd timeouts more properly.
 
 ii.	pci_dma_sync_{sg,single}_for_cpu was introduced into megaraid_mbox
-	incorrectly (instead of _for_device). Changed to appropriate
+	incorrectly (instead of _for_device). Changed to appropriate 
 	pci_dma_sync_{sg,single}_for_device.
 
 Release Date	: Wed Oct 06 11:15:29 EDT 2004 - Sreenivas Bagalkote <sreenib@lsil.com>
diff -Nru a/Documentation/scsi/scsi_mid_low_api.txt b/Documentation/scsi/scsi_mid_low_api.txt
--- a/Documentation/scsi/scsi_mid_low_api.txt	2005-03-01 23:39:08 -08:00
+++ b/Documentation/scsi/scsi_mid_low_api.txt	2005-03-01 23:39:08 -08:00
@@ -363,8 +363,8 @@
 Mid level supplied functions
 ============================
 These functions are supplied by the SCSI mid level for use by LLDs.
-The names (i.e. entry points) of these functions are exported (mainly in 
-scsi_syms.c) so an LLD that is a module can access them. The kernel will
+The names (i.e. entry points) of these functions are exported 
+so an LLD that is a module can access them. The kernel will
 arrange for the SCSI mid level to be loaded and initialized before any LLD
 is initialized. The functions below are listed alphabetically and their
 names all start with "scsi_".
diff -Nru a/Documentation/serial/driver b/Documentation/serial/driver
--- a/Documentation/serial/driver	2005-03-01 23:38:53 -08:00
+++ b/Documentation/serial/driver	2005-03-01 23:38:53 -08:00
@@ -211,17 +211,24 @@
 	Yes		1	1	character received, marked as
 					TTY_PARITY
 
+	Other flags may be used (eg, xon/xoff characters) if your
+	hardware supports hardware "soft" flow control.
+
 	Locking: none.
 	Interrupts: caller dependent.
 	This call must not sleep
 
   pm(port,state,oldstate)
-	perform any power management related activities on the specified
-	port.  state indicates the new state (defined by ACPI D0-D3),
+	Perform any power management related activities on the specified
+	port.  State indicates the new state (defined by ACPI D0-D3),
 	oldstate indicates the previous state.  Essentially, D0 means
 	fully on, D3 means powered down.
 
 	This function should not be used to grab any resources.
+
+	This will be called when the port is initially opened and finally
+	closed, except when the port is also the system console.  This
+	will occur even if CONFIG_PM is not set.
 
 	Locking: none.
 	Interrupts: caller dependent.
diff -Nru a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt
--- a/Documentation/sound/alsa/ALSA-Configuration.txt	2005-03-01 23:38:52 -08:00
+++ b/Documentation/sound/alsa/ALSA-Configuration.txt	2005-03-01 23:38:52 -08:00
@@ -184,6 +184,8 @@
     Module for ATI IXP 150/200/250 AC97 controllers.
 
     ac97_clock		- AC'97 clock (defalut = 48000)
+    ac97_quirk		- AC'97 workaround for strange hardware
+			  See the description of intel8x0 module for details.
     spdif_aclink	- S/PDIF transfer over AC-link (default = 1)
 
     This module supports up to 8 cards and autoprobe.
@@ -252,9 +254,18 @@
     Module for video cards based on Bt87x chips.
 
     digital_rate - Override the default digital rate (Hz)
+    load_all	- Load the driver even if the card model isn't known
 
     Module supports up to 8 cards.
 
+  Module snd-ca0106
+  -----------------
+
+    Module for Creative Audigy LS and SB Live 24bit
+
+    Module supports up to 8 cards.
+
+
   Module snd-cmi8330
   ------------------
 
@@ -426,6 +437,13 @@
 	* Creative Card 5.1 (c) 2003			[0x3fc3/0x7cff]
         * Creative Card all ins and outs		[0x3fff/0x7fff]
     
+  Module snd-emu10k1x
+  -------------------
+
+    Module for Creative Emu10k1X (SB Live Dell OEM version)
+
+    Module supports up to 8 cards.
+
   Module snd-ens1370
   ------------------
 
@@ -595,8 +613,11 @@
 
     Module supports up to 8 cards.
 
-    Note: you need to load the firmware via hdsploader utility included
-          in alsa-tools and alsa-firmware packages.
+    Note: The firmware data can be automatically loaded via hotplug
+          when CONFIG_FW_LOADER is set.  Otherwise, you need to load
+          the firmware via hdsploader utility included in alsa-tools
+          package.
+          The firmware data is found in alsa-firmware package.
 
     Note: snd-page-alloc module does the job which snd-hammerfall-mem
           module did formerly.  It will allocate the buffers in advance
@@ -661,16 +682,21 @@
 			* ALi m5455
 
     ac97_clock	  - AC'97 codec clock base (0 = auto-detect)
-    ac97_quirk    - AC'97 workaround for strange hardware (-1 = default)
-                    -1 = default, don't override
-                     0 = disable
-                     1 = use headphone control as master
-                     2 = swap headphone and master controls
-                     3 = for AD1985, turn on OMS bit and use headphone
-                     4 = for ALC65x, turn on the jack sense mode
-                     5 = inverted EAPD implementation
-    buggy_irq      - Enable workaround for buggy interrupts on some
-                     motherboards (default off)
+    ac97_quirk    - AC'97 workaround for strange hardware
+                    The following strings are accepted:
+                      default = don't override the default setting
+                      disable = disable the quirk
+                      hp_only = use headphone control as master
+                      swap_hp = swap headphone and master controls
+                      swap_surround = swap master and surround controls
+                      ad_shring = for AD1985, turn on OMS bit and use headphone
+                      alc_jack = for ALC65x, turn on the jack sense mode
+                      inv_eapd = inverted EAPD implementation
+                      mute_led = bind EAPD bit for turning on/off mute LED
+                    For backward compatibility, the corresponding integer
+                    value -1, 0, ... are accepted, too.
+    buggy_irq     - Enable workaround for buggy interrupts on some
+                    motherboards (default off)
 
     Module supports autoprobe and multiple bus-master chips (max 8).
 
@@ -774,6 +800,12 @@
     Note: One miXart8 board will be represented as 4 alsa cards.
           See MIXART.txt for details.
 
+    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 mixartloader utility in alsa-tools package.
+
   Module snd-mpu401
   -----------------
 
@@ -1182,6 +1214,15 @@
     Note: for the MPU401 on VIA823x, use snd-mpu401 driver
 	  additonally.  The mpu_port option is for VIA686 chips only.
 
+  Module snd-via82xx-modem
+  ------------------------
+
+    Module for VIA82xx AC97 modem
+
+    ac97_clock	- AC'97 codec clock base (default 48000Hz)
+
+    Module supports up to 8 cards.
+
   Module snd-virmidi
   ------------------
 
@@ -1203,9 +1244,12 @@
 
     Module supports up to 8 cards.
 
-    For loading the firmware, use vxloader utility in alsa-tools
-    and alsa-firmware packages.  You can load the firmware automatically
-    by adding the following to /etc/modprobe.conf
+    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.  To invoke
+    vxloader automatically, add the following to /etc/modprobe.conf
 
 	install snd-vx222 /sbin/modprobe --first-time -i snd-vx222 && /usr/bin/vxloader
 
@@ -1234,8 +1278,11 @@
     To activate the driver via the card manager, you'll need to set
     up /etc/pcmcia/vxpocket.conf.  See the sound/pcmcia/vx/vxpocket.c.
 
-    For loading the firmware, use vxloader utility in alsa-tools
-    and alsa-firmware packages.
+    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.
 
     The irq_mask and irq_list are provided to avoid allocation of
     specific IRQs.  Usually you don't need to specify them.
@@ -1260,8 +1307,11 @@
     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.
 
-    For loading the firmware, use vxloader utility in alsa-tools
-    and alsa-firmware packages.
+    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.
 
     The irq_mask and irq_list are provided to avoid allocation of
     specific IRQs.  Usually you don't need to specify them.
@@ -1359,18 +1409,21 @@
 ALSA PCM devices to OSS devices mapping
 =======================================
 
-/dev/snd/pcmC0D0  -> /dev/audio0 (/dev/audio) -> minor 4
-/dev/snd/pcmC0D0  -> /dev/dsp0 (/dev/dsp)     -> minor 3
-/dev/snd/pcmC0D1  -> /dev/adsp0 (/dev/adsp)   -> minor 12
-/dev/snd/pcmC1D0  -> /dev/audio1              -> minor 4+16 = 20
-/dev/snd/pcmC1D0  -> /dev/dsp1                -> minor 3+16 = 19
-/dev/snd/pcmC1D1  -> /dev/adsp1               -> minor 12+16 = 28
-/dev/snd/pcmC2D0  -> /dev/audio2              -> minor 4+32 = 36
-/dev/snd/pcmC2D0  -> /dev/dsp2                -> minor 3+32 = 39
-/dev/snd/pcmC2D1  -> /dev/adsp2               -> minor 12+32 = 44
+/dev/snd/pcmC0D0[c|p]  -> /dev/audio0 (/dev/audio) -> minor 4
+/dev/snd/pcmC0D0[c|p]  -> /dev/dsp0 (/dev/dsp)     -> minor 3
+/dev/snd/pcmC0D1[c|p]  -> /dev/adsp0 (/dev/adsp)   -> minor 12
+/dev/snd/pcmC1D0[c|p]  -> /dev/audio1              -> minor 4+16 = 20
+/dev/snd/pcmC1D0[c|p]  -> /dev/dsp1                -> minor 3+16 = 19
+/dev/snd/pcmC1D1[c|p]  -> /dev/adsp1               -> minor 12+16 = 28
+/dev/snd/pcmC2D0[c|p]  -> /dev/audio2              -> minor 4+32 = 36
+/dev/snd/pcmC2D0[c|p]  -> /dev/dsp2                -> minor 3+32 = 39
+/dev/snd/pcmC2D1[c|p]  -> /dev/adsp2               -> minor 12+32 = 44
+
+The first number from /dev/snd/pcmC{X}D{Y}[c|p] expression means
+soundcard number and second means device number.  The ALSA devices
+have either 'c' or 'p' suffix indicating the direction, capture and
+playback, respectively.
 
-The first number from /dev/snd/pcmC{X}D{Y} expression means soundcard number
-and second means device number.
 Please note that the device mapping above may be varied via the module
 options of snd-pcm-oss module.
 
diff -Nru a/Documentation/sound/alsa/Bt87x.txt b/Documentation/sound/alsa/Bt87x.txt
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/Documentation/sound/alsa/Bt87x.txt	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,78 @@
+Intro
+=====
+
+You might have noticed that the bt878 grabber cards have actually
+_two_ PCI functions:
+
+$ lspci
+[ ... ]
+00:0a.0 Multimedia video controller: Brooktree Corporation Bt878 (rev 02)
+00:0a.1 Multimedia controller: Brooktree Corporation Bt878 (rev 02)
+[ ... ]
+
+The first does video, it is backward compatible to the bt848.  The second
+does audio.  snd-bt87x is a driver for the second function.  It's a sound
+driver which can be used for recording sound (and _only_ recording, no
+playback).  As most TV cards come with a short cable which can be plugged
+into your sound card's line-in you probably don't need this driver if all
+you want to do is just watching TV...
+
+Some cards do not bother to connect anything to the audio input pins of
+the chip, and some other cards use the audio function to transport MPEG
+video data, so it's quite possible that audio recording may not work
+with your card.
+
+
+Driver Status
+=============
+
+The driver is now stable.  However, it doesn't know about many TV cards,
+and it refuses to load for cards it doesn't know.
+
+If the driver complains ("Unknown TV card found, the audio driver will
+not load"), you can specify the load_all=1 option to force the driver to
+try to use the audio capture function of your card.  If the frequency of
+recorded data is not right, try to specify the digital_rate option with
+other values than the default 32000 (often it's 44100 or 64000).
+
+If you have an unknown card, please mail the ID and board name to
+<alsa-devel@lists.sf.net>, regardless of whether audio capture works or
+not, so that future versions of this driver know about your card.
+
+
+Audio modes
+===========
+
+The chip knows two different modes (digital/analog).  snd-bt87x
+registers two PCM devices, one for each mode.  They cannot be used at
+the same time.
+
+
+Digital audio mode
+==================
+
+The first device (hw:X,0) gives you 16 bit stereo sound.  The sample
+rate depends on the external source which feeds the Bt87x with digital
+sound via I2S interface.
+
+
+Analog audio mode (A/D)
+=======================
+
+The second device (hw:X,1) gives you 8 or 16 bit mono sound.  Supported
+sample rates are between 119466 and 448000 Hz (yes, these numbers are
+that high).  If you've set the CONFIG_SND_BT87X_OVERCLOCK option, the
+maximum sample rate is 1792000 Hz, but audio data becomes unusable
+beyond 896000 Hz on my card.
+
+The chip has three analog inputs.  Consequently you'll get a mixer
+device to control these.
+
+
+Have fun,
+
+  Clemens
+
+
+Written by Clemens Ladisch <clemens@ladisch.de>
+big parts copied from btaudio.txt by Gerd Knorr <kraxel@bytesex.org>
diff -Nru 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	2005-03-01 23:38:54 -08:00
+++ b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl	2005-03-01 23:38:54 -08:00
@@ -397,12 +397,12 @@
   #include <sound/core.h>
   #include <sound/initval.h>
 
-  // module parameters (see "Module Parameters")
+  /* module parameters (see "Module Parameters") */
   static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
   static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
   static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
 
-  // definition of the chip-specific record
+  /* definition of the chip-specific record */
   typedef struct snd_mychip mychip_t;
   struct snd_mychip {
           snd_card_t *card;
@@ -410,23 +410,26 @@
           // "PCI Resource Managements"
   };
 
-  // chip-specific destructor
-  // (see "PCI Resource Managements")
+  /* chip-specific destructor
+   * (see "PCI Resource Managements")
+   */
   static int snd_mychip_free(mychip_t *chip)
   {
-          // will be implemented later...
+          .... // will be implemented later...
   }
 
-  // component-destructor
-  // (see "Management of Cards and Components")
+  /* component-destructor
+   * (see "Management of Cards and Components")
+   */
   static int snd_mychip_dev_free(snd_device_t *device)
   {
           mychip_t *chip = device->device_data;
           return snd_mychip_free(chip);
   }
 
-  // chip-specific constructor
-  // (see "Management of Cards and Components")
+  /* chip-specific constructor
+   * (see "Management of Cards and Components")
+   */
   static int __devinit snd_mychip_create(snd_card_t *card,
                                          struct pci_dev *pci,
                                          mychip_t **rchip)
@@ -441,8 +444,9 @@
 
           // check PCI availability here
           // (see "PCI Resource Managements")
+          ....
 
-          // allocate a chip-specific data with zero filled
+          /* allocate a chip-specific data with zero filled */
           chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
           if (chip == NULL)
                   return -ENOMEM;
@@ -451,17 +455,21 @@
 
           // rest of initialization here; will be implemented
           // later, see "PCI Resource Managements"
+          ....
 
           if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL,
                                     chip, &ops)) < 0) {
                   snd_mychip_free(chip);
                   return err;
           }
+
+          snd_card_set_dev(card, &pci->dev);
+
           *rchip = chip;
           return 0;
   }
 
-  // constructor -- see "Constructor" sub-section
+  /* constructor -- see "Constructor" sub-section */
   static int __devinit snd_mychip_probe(struct pci_dev *pci,
                                const struct pci_device_id *pci_id)
   {
@@ -470,7 +478,7 @@
           mychip_t *chip;
           int err;
 
-          // (1)
+          /* (1) */
           if (dev >= SNDRV_CARDS)
                   return -ENODEV;
           if (!enable[dev]) {
@@ -478,39 +486,39 @@
                   return -ENOENT;
           }
 
-          // (2)
+          /* (2) */
           card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
           if (card == NULL)
                   return -ENOMEM;
 
-          // (3)
+          /* (3) */
           if ((err = snd_mychip_create(card, pci, &chip)) < 0) {
                   snd_card_free(card);
                   return err;
           }
 
-          // (4)
+          /* (4) */
           strcpy(card->driver, "My Chip");
           strcpy(card->shortname, "My Own Chip 123");
           sprintf(card->longname, "%s at 0x%lx irq %i",
                   card->shortname, chip->ioport, chip->irq);
 
-          // (5)
-          // implemented later
+          /* (5) */
+          .... // implemented later
 
-          // (6)
+          /* (6) */
           if ((err = snd_card_register(card)) < 0) {
                   snd_card_free(card);
                   return err;
           }
 
-          // (7)
+          /* (7) */
           pci_set_drvdata(pci, card);
           dev++;
           return 0;
   }
 
-  // destructor -- see "Destructor" sub-section
+  /* destructor -- see "Destructor" sub-section */
   static void __devexit snd_mychip_remove(struct pci_dev *pci)
   {
           snd_card_free(pci_get_drvdata(pci));
@@ -743,7 +751,7 @@
           </programlisting>
         </informalexample>
 
-	where the last twos are necessary only when module options are
+	where the last one is necessary only when module options are
       defined in the source file.  If the codes are split to several
       files, the file without module options don't need them.
       </para>
@@ -1089,20 +1097,22 @@
 
   static int snd_mychip_free(mychip_t *chip)
   {
-          // disable hardware here if any
-          // (not implemented in this document)
+          /* disable hardware here if any */
+          .... // (not implemented in this document)
 
-          // release the irq
+          /* release the irq */
           if (chip->irq >= 0)
                   free_irq(chip->irq, (void *)chip);
-          // release the i/o ports
+          /* release the i/o ports */
           pci_release_regions(chip->pci);
-          // release the data
+          /* disable the PCI entry */
+          pci_disable_device(chip->pci);
+          /* release the data */
           kfree(chip);
           return 0;
   }
 
-  // chip-specific constructor
+  /* chip-specific constructor */
   static int __devinit snd_mychip_create(snd_card_t *card,
                                          struct pci_dev *pci,
                                          mychip_t **rchip)
@@ -1115,27 +1125,32 @@
 
           *rchip = NULL;
 
-          // check PCI availability (28bit DMA)
+          /* initialize the PCI entry */
           if ((err = pci_enable_device(pci)) < 0)
                   return err;
+          /* check PCI availability (28bit DMA) */
           if (pci_set_dma_mask(pci, 0x0fffffff) < 0 ||
               pci_set_consistent_dma_mask(pci, 0x0fffffff) < 0) {
                   printk(KERN_ERR "error to set 28bit mask DMA\n");
+                  pci_disable_device(pci);
                   return -ENXIO;
           }
 
           chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
-          if (chip == NULL)
+          if (chip == NULL) {
+                  pci_disable_device(pci);
                   return -ENOMEM;
+          }
 
-          // initialize the stuff
+          /* initialize the stuff */
           chip->card = card;
           chip->pci = pci;
           chip->irq = -1;
 
-          // (1) PCI resource allocation
+          /* (1) PCI resource allocation */
           if ((err = pci_request_regions(pci, "My Chip")) < 0) {
                   kfree(chip);
+                  pci_disable_device(pci);
                   return err;
           }
           chip->port = pci_resource_start(pci, 0);
@@ -1148,19 +1163,22 @@
           }
           chip->irq = pci->irq;
 
-          // (2) initialization of the chip hardware
-          //     (not implemented in this document)
+          /* (2) initialization of the chip hardware */
+          .... //   (not implemented in this document)
 
           if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL,
                                     chip, &ops)) < 0) {
                   snd_mychip_free(chip);
                   return err;
           }
+
+          snd_card_set_dev(card, &pci->dev);
+
           *rchip = chip;
           return 0;
   }        
 
-  // PCI IDs
+  /* PCI IDs */
   static struct pci_device_id snd_mychip_ids[] = {
           { PCI_VENDOR_ID_FOO, PCI_DEVICE_ID_BAR,
             PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
@@ -1169,7 +1187,7 @@
   };
   MODULE_DEVICE_TABLE(pci, snd_mychip_ids);
 
-  // pci_driver definition
+  /* pci_driver definition */
   static struct pci_driver driver = {
           .name = "My Own Chip",
           .id_table = snd_mychip_ids,
@@ -1177,13 +1195,13 @@
           .remove = __devexit_p(snd_mychip_remove),
   };
 
-  // initialization of the module
+  /* initialization of the module */
   static int __init alsa_card_mychip_init(void)
   {
           return pci_module_init(&driver);
   }
 
-  // clean up the module
+  /* clean up the module */
   static void __exit alsa_card_mychip_exit(void)
   {
           pci_unregister_driver(&driver);
@@ -1228,6 +1246,7 @@
   if (pci_set_dma_mask(pci, 0x0fffffff) < 0 ||
       pci_set_consistent_dma_mask(pci, 0x0fffffff) < 0) {
           printk(KERN_ERR "error to set 28bit mask DMA\n");
+          pci_disable_device(pci);
           return -ENXIO;
   }
   
@@ -1285,6 +1304,7 @@
 <![CDATA[
   if ((err = pci_request_regions(pci, "My Chip")) < 0) { 
           kfree(chip);
+          pci_disable_device(pci);
           return err;
   }
   chip->port = pci_resource_start(pci, 0);
@@ -1434,6 +1454,11 @@
       </para>
 
       <para>
+      Don't forget to call <function>pci_disable_device()</function>
+      before all finished.
+      </para>
+
+      <para>
         And finally, release the chip-specific record.
 
         <informalexample>
@@ -1462,7 +1487,7 @@
       When the chip-data is assigned to the card using
       <function>snd_device_new()</function> with
       <constant>SNDRV_DEV_LOWLELVEL</constant> , its destructor is 
-      called at the last.  that is, it is assured that all other
+      called at the last.  That is, it is assured that all other
       components like PCMs and controls have been already released.
       You don't have to call stopping PCMs, etc. explicitly, but just
       stop the hardware in the low-level.
@@ -1485,7 +1510,7 @@
           </programlisting>
         </informalexample>
 
-        and the allocation would be (assuming its size is 512 bytes):
+        and the allocation would be like below:
 
         <informalexample>
           <programlisting>
@@ -1522,6 +1547,30 @@
 
     </section>
 
+    <section id="pci-resource-device-struct">
+      <title>Registration of Device Struct</title>
+      <para>
+	At some point, typically after calling <function>snd_device_new()</function>,
+	you need to register the <structname>struct device</structname> of the chip
+	you're handling for udev and co.  ALSA provides a macro for compatibility with
+	older kernels.  Simply call like the following:
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  snd_card_set_dev(card, &pci->dev);
+]]>
+          </programlisting>
+        </informalexample>
+	so that it stores the PCI's device pointer to the card.  This will be
+	referred by ALSA core functions later when the devices are registered.
+      </para>
+      <para>
+	In the case of non-PCI, pass the proper device struct pointer of the BUS
+	instead.  (In the case of legacy ISA without PnP, you don't have to do
+	anything.)
+      </para>
+    </section>
+
     <section id="pci-resource-entries">
       <title>PCI Entries</title>
       <para>
@@ -1801,8 +1850,9 @@
           mychip_t *chip = snd_pcm_substream_chip(substream);
           snd_pcm_runtime_t *runtime = substream->runtime;
 
-          // set up the hardware with the current configuration
-          // for example...
+          /* set up the hardware with the current configuration
+           * for example...
+           */
           mychip_set_sample_format(chip, runtime->format);
           mychip_set_sample_rate(chip, runtime->rate);
           mychip_set_channels(chip, runtime->channels);
@@ -1835,7 +1885,7 @@
           mychip_t *chip = snd_pcm_substream_chip(substream);
           unsigned int current_ptr;
 
-          // get the current hardware pointer
+          /* get the current hardware pointer */
           current_ptr = mychip_get_hw_pointer(chip);
           return current_ptr;
   }
@@ -2068,18 +2118,19 @@
   static void mychip_pcm_free(snd_pcm_t *pcm)
   {
           mychip_t *chip = snd_pcm_chip(pcm);
-          // free your own data
+          /* free your own data */
           kfree(chip->my_private_pcm_data);
-          // do what you like else...
+          // do what you like else
+          ....
   }
 
   static int __devinit snd_mychip_new_pcm(mychip_t *chip)
   {
           snd_pcm_t *pcm;
           ....
-          // allocate your own data
+          /* allocate your own data */
           chip->my_private_pcm_data = kmalloc(...);
-          // set the destructor
+          /* set the destructor */
           pcm->private_data = chip;
           pcm->private_free = mychip_pcm_free;
           ....
@@ -2231,7 +2282,7 @@
 <![CDATA[
           snd_pcm_runtime_t *runtime = substream->runtime;
           ...
-          runtime->hw = snd_mychip_playback_hw; // common definition
+          runtime->hw = snd_mychip_playback_hw; /* common definition */
           if (chip->model == VERY_OLD_ONE)
                   runtime->hw.channels_max = 1;
 ]]>
@@ -3030,7 +3081,7 @@
           spin_lock(&chip->lock);
           ....
           if (pcm_irq_invoked(chip)) {
-                  // call updater, unlock before it
+                  /* call updater, unlock before it */
                   spin_unlock(&chip->lock);
                   snd_pcm_period_elapsed(chip->substream);
                   spin_lock(&chip->lock);
@@ -3075,24 +3126,25 @@
           ....
           if (pcm_irq_invoked(chip)) {
                   unsigned int last_ptr, size;
-                  // get the current hardware pointer (in frames)
+                  /* get the current hardware pointer (in frames) */
                   last_ptr = get_hw_ptr(chip);
-                  // calculate the processed frames since the
-                  // last update
+                  /* calculate the processed frames since the
+                   * last update
+                   */
                   if (last_ptr < chip->last_ptr)
                           size = runtime->buffer_size + last_ptr 
                                    - chip->last_ptr; 
                   else
                           size = last_ptr - chip->last_ptr;
-                  // remember the last updated point
+                  /* remember the last updated point */
                   chip->last_ptr = last_ptr;
-                  // accumulate the size
+                  /* accumulate the size */
                   chip->size += size;
-                  // over the period boundary?
+                  /* over the period boundary? */
                   if (chip->size >= runtime->period_size) {
-                          // reset the accumulator
+                          /* reset the accumulator */
                           chip->size %= runtime->period_size;
-                          // call updater
+                          /* call updater */
                           spin_unlock(&chip->lock);
                           snd_pcm_period_elapsed(substream);
                           spin_lock(&chip->lock);
@@ -3216,7 +3268,7 @@
           snd_mask_t *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
           snd_mask_t fmt;
 
-          snd_mask_any(&fmt);    // Init the struct
+          snd_mask_any(&fmt);    /* Init the struct */
           if (c->min < 2) {
                   fmt.bits[0] &= SNDRV_PCM_FMTBIT_S16_LE;
                   return snd_mask_refine(f, &fmt);
@@ -5131,7 +5183,7 @@
         <listitem><para>Call <function>snd_pcm_suspend_all()</function> to suspend the running PCM streams.</para></listitem>
         <listitem><para>Save the register values if necessary.</para></listitem>
         <listitem><para>Stop the hardware if necessary.</para></listitem>
-        <listitem><para>Set the power-state as D3hot by calling <function>snd_power_change_state()</function>.</para></listitem>
+        <listitem><para>Disable the PCI device by calling <function>pci_disable_device()</function>.</para></listitem>
       </orderedlist>
     </para>
 
@@ -5143,16 +5195,16 @@
 <![CDATA[
   static int mychip_suspend(snd_card_t *card, unsigned int state)
   {
-          // (1)
+          /* (1) */
           mychip_t *chip = card->pm_private_data;
-          // (2)
+          /* (2) */
           snd_pcm_suspend_all(chip->pcm);
-          // (3)
+          /* (3) */
           snd_mychip_save_registers(chip);
-          // (4)
+          /* (4) */
           snd_mychip_stop_hardware(chip);
-          // (5)
-          snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
+          /* (5) */
+          pci_disable_device(chip->pci);
           return 0;
   }
 ]]>
@@ -5172,8 +5224,6 @@
     <listitem><para>Resume the mixer, e.g. calling
     <function>snd_ac97_resume()</function>.</para></listitem>
     <listitem><para>Restart the hardware (if any).</para></listitem>
-    <listitem><para>Set the power-state as D0 by calling
-    <function>snd_power_change_state()</function>.</para></listitem>
     </orderedlist>
     </para>
 
@@ -5185,20 +5235,18 @@
 <![CDATA[
   static void mychip_resume(mychip_t *chip)
   {
-          // (1)
+          /* (1) */
           mychip_t *chip = card->pm_private_data;
-          // (2)
+          /* (2) */
           pci_enable_device(chip->pci);
-          // (3)
+          /* (3) */
           snd_mychip_reinit_chip(chip);
-          // (4)
+          /* (4) */
           snd_mychip_restore_registers(chip);
-          // (5)
+          /* (5) */
           snd_ac97_resume(chip->ac97);
-          // (6)
+          /* (6) */
           snd_mychip_restart_chip(chip);
-          // (7)
-          snd_power_change_state(card, SNDRV_CTL_POWER_D0);
           return 0;
   }
 ]]>
@@ -5314,19 +5362,15 @@
 <![CDATA[
   #define CARD_NAME "My Chip"
 
-  static int boot_devs;
-  module_param_array(index, int, boot_devs, 0444);
+  module_param_array(index, int, NULL, 0444);
   MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard.");
-  module_param_array(id, charp, boot_devs, 0444);
+  module_param_array(id, charp, NULL, 0444);
   MODULE_PARM_DESC(id, "ID string for " CARD_NAME " soundcard.");
-  module_param_array(enable, bool, boot_devs, 0444);
+  module_param_array(enable, bool, NULL, 0444);
   MODULE_PARM_DESC(enable, "Enable " CARD_NAME " soundcard.");
 ]]>
         </programlisting>
       </informalexample>
-
-    Here boot_devs is passed but simply ignored since we don't care
-    the number of parsed parameters.
     </para>
 
     <para>
@@ -5423,7 +5467,10 @@
           depends on SND
           select SND_PCM
           help
-            Say 'Y' or 'M' to include support for Foobar XYZ soundcard.
+            Say Y here to include support for Foobar XYZ soundcard.
+
+            To compile this driver as a module, choose M here: the module
+            will be called snd-xyz.
 ]]>
         </programlisting>
       </informalexample>
diff -Nru a/Documentation/sound/alsa/MIXART.txt b/Documentation/sound/alsa/MIXART.txt
--- a/Documentation/sound/alsa/MIXART.txt	2005-03-01 23:39:07 -08:00
+++ b/Documentation/sound/alsa/MIXART.txt	2005-03-01 23:39:07 -08:00
@@ -72,6 +72,10 @@
 FIRMWARE
 ========
 
+[As of 2.6.11, the firmware can be loaded automatically with hotplug
+ when CONFIG_FW_LOADER is set.  The mixartloader is necessary only
+ for older versions or when you build the driver into kernel.]
+ 
 For loading the firmware automatically after the module is loaded, use
 the post-install command.  For example, add the following entry to
 /etc/modprobe.conf for miXart driver:
diff -Nru a/Documentation/sound/alsa/OSS-Emulation.txt b/Documentation/sound/alsa/OSS-Emulation.txt
--- a/Documentation/sound/alsa/OSS-Emulation.txt	2005-03-01 23:38:58 -08:00
+++ b/Documentation/sound/alsa/OSS-Emulation.txt	2005-03-01 23:38:58 -08:00
@@ -164,16 +164,15 @@
 
 The block and non-block options are used to change the behavior of
 opening the device file.
-As default, ALSA behaves as defined in POSIX, i.e. blocks the file
-when it's busy until the device becomes free (unless O_NONBLOCK is
-specified).  Some applications assume the non-block open behavior,
-which are actually implemented in some real OSS drivers.
+
+As default, ALSA behaves as original OSS drivers, i.e. does not block
+the file when it's busy. The -EBUSY error is returned in this case.
 
 This blocking behavior can be changed globally via nonblock_open
-module option of snd-pcm-oss.  For using the non-block mode as default
+module option of snd-pcm-oss.  For using the blocking mode as default
 for OSS devices, define like the following:
 
-	options snd-pcm-oss nonblock_open=1
+	options snd-pcm-oss nonblock_open=0
 
 The partial-frag and no-silence commands have been added recently.
 Both commands are for optimization use only.  The former command
diff -Nru a/Documentation/sparse.txt b/Documentation/sparse.txt
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/Documentation/sparse.txt	2005-03-01 23:39:26 -08:00
@@ -0,0 +1,72 @@
+Copyright 2004 Linus Torvalds
+Copyright 2004 Pavel Machek <pavel@suse.cz>
+
+Using sparse for typechecking
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+"__bitwise" is a type attribute, so you have to do something like this:
+
+        typedef int __bitwise pm_request_t;
+
+        enum pm_request {
+                PM_SUSPEND = (__force pm_request_t) 1,
+                PM_RESUME = (__force pm_request_t) 2
+        };
+
+which makes PM_SUSPEND and PM_RESUME "bitwise" integers (the "__force" is
+there because sparse will complain about casting to/from a bitwise type,
+but in this case we really _do_ want to force the conversion). And because
+the enum values are all the same type, now "enum pm_request" will be that
+type too.
+
+And with gcc, all the __bitwise/__force stuff goes away, and it all ends
+up looking just like integers to gcc.
+
+Quite frankly, you don't need the enum there. The above all really just
+boils down to one special "int __bitwise" type.
+
+So the simpler way is to just do
+
+        typedef int __bitwise pm_request_t;
+
+        #define PM_SUSPEND ((__force pm_request_t) 1)
+        #define PM_RESUME ((__force pm_request_t) 2)
+
+and you now have all the infrastructure needed for strict typechecking.
+
+One small note: the constant integer "0" is special. You can use a
+constant zero as a bitwise integer type without sparse ever complaining.
+This is because "bitwise" (as the name implies) was designed for making
+sure that bitwise types don't get mixed up (little-endian vs big-endian
+vs cpu-endian vs whatever), and there the constant "0" really _is_
+special.
+
+Modify top-level Makefile to say
+
+CHECK           = sparse -Wbitwise
+
+or you don't get any checking at all.
+
+
+Where to get sparse
+~~~~~~~~~~~~~~~~~~~
+
+With BK, you can just get it from
+
+        bk://sparse.bkbits.net/sparse
+
+and DaveJ has tar-balls at
+
+	http://www.codemonkey.org.uk/projects/bitkeeper/sparse/
+
+
+Once you have it, just do
+
+        make
+        make install
+
+as your regular user, and it will install sparse in your ~/bin directory.
+After that, doing a kernel make with "make C=1" will run sparse on all the
+C files that get recompiled, or with "make C=2" will run sparse on the
+files whether they need to be recompiled or not (ie the latter is fast way
+to check the whole tree if you have already built it).
diff -Nru a/Documentation/stable_api_nonsense.txt b/Documentation/stable_api_nonsense.txt
--- a/Documentation/stable_api_nonsense.txt	2005-03-01 23:39:09 -08:00
+++ b/Documentation/stable_api_nonsense.txt	2005-03-01 23:39:09 -08:00
@@ -9,7 +9,7 @@
 kernel to userspace interfaces.  The kernel to userspace interface is
 the one that application programs use, the syscall interface.  That
 interface is _very_ stable over time, and will not break.  I have old
-programs that were built on a pre 0.9something kernel that still works
+programs that were built on a pre 0.9something kernel that still work
 just fine on the latest 2.6 kernel release.  This interface is the one
 that users and application programmers can count on being stable.
 
@@ -167,7 +167,7 @@
 ensures that your driver is always buildable, and works over time, with
 very little effort on your part.
 
-The very good side affects of having your driver in the main kernel tree
+The very good side effects of having your driver in the main kernel tree
 are:
   - The quality of the driver will rise as the maintenance costs (to the
     original developer) will decrease.
diff -Nru a/Documentation/stallion.txt b/Documentation/stallion.txt
--- a/Documentation/stallion.txt	2005-03-01 23:39:08 -08:00
+++ b/Documentation/stallion.txt	2005-03-01 23:39:08 -08:00
@@ -1,8 +1,13 @@
+* NOTE - This is an unmaintained driver.  Lantronix, which bought Stallion
+technologies, is not active in driver maintenance, and they have no information
+on when or if they will have a 2.6 driver.
+
+James Nelson <james4765@gmail.com> - 12-12-2004
 
 Stallion Multiport Serial Driver Readme
 ---------------------------------------
 
-Copyright (C) 1994-1999,  Stallion Technologies (support@stallion.com).
+Copyright (C) 1994-1999,  Stallion Technologies.
 
 Version:   5.5.1
 Date:      28MAR99
@@ -19,29 +24,20 @@
 
 If you are using any of the Stallion intelligent multiport boards (Brumby,
 ONboard, EasyConnection 8/64 (ISA, EISA, MCA), EasyConnection/RA-PCI) with
-Linux you will need to get the driver utility package. This package is
-available at most of the Linux archive sites (and on CD-ROMs that contain
-these archives). The file will be called stallion-X.X.X.tar.gz where X.X.X
-will be the version number. In particular this package contains the board
-embedded executable images that are required for these boards. It also
-contains the downloader program. These boards cannot be used without this.
+Linux you will need to get the driver utility package.  This contains a
+firmware loader and the firmware images necessary to make the devices operate.
 
 The Stallion Technologies ftp site, ftp.stallion.com, will always have
-the latest version of the driver utility package. Other sites that usually
-have the latest version are tsx-11.mit.edu, sunsite.unc.edu and their
-mirrors.
-
-ftp.stallion.com:/drivers/ata5/Linux/v550.tar.gz
-tsx-11.mit.edu:/pub/linux/packages/stallion/stallion-5.5.0.tar.gz
-sunsite.unc.edu:/pub/Linux/kernel/patches/serial/stallion-5.5.0.tar.gz
+the latest version of the driver utility package.
+
+ftp://ftp.stallion.com/drivers/ata5/Linux/ata-linux-550.tar.gz
 
 As of the printing of this document the latest version of the driver
 utility package is 5.5.0. If a later version is now available then you
 should use the latest version.
 
 If you are using the EasyIO, EasyConnection 8/32 or EasyConnection 8/64-PCI
-boards then you don't need this package. Although it does have a handy
-script to create the /dev device nodes for these boards, and a serial stats
+boards then you don't need this package, although it does have a serial stats
 display program.
 
 If you require DIP switch settings, EISA or MCA configuration files, or any
@@ -85,7 +81,7 @@
 
 Typically to load up the smart board driver use:
 
-    insmod stallion.o
+    modprobe stallion
 
 This will load the EasyIO and EasyConnection 8/32 driver. It will output a
 message to say that it loaded and print the driver version number. It will
@@ -96,12 +92,12 @@
 
 To load the intelligent board driver use:
 
-    insmod istallion.o
+    modprobe istallion
 
 It will output similar messages to the smart board driver.
 
 If not using an auto-detectable board type (that is a PCI board) then you
-will also need to supply command line arguments to the "insmod" command
+will also need to supply command line arguments to the modprobe command
 when loading the driver. The general form of the configuration argument is
 
     board?=<name>[,<ioaddr>[,<addr>][,<irq>]]
@@ -111,7 +107,7 @@
     board?  -- specifies the arbitrary board number of this board,
                can be in the range 0 to 3.
 
-    name    -- textual name of this board. The board name is the comman
+    name    -- textual name of this board. The board name is the common
                board name, or any "shortened" version of that. The board
                type number may also be used here.
 
@@ -127,24 +123,24 @@
 Up to 4 board configuration arguments can be specified on the load line.
 Here is some examples:
 
-    insmod stallion.o board0=easyio,0x2a0,5
+    modprobe stallion board0=easyio,0x2a0,5
 
 This configures an EasyIO board as board 0 at I/O address 0x2a0 and IRQ 5.
 
-    insmod istallion.o board3=ec8/64,0x2c0,0xcc000
+    modprobe istallion board3=ec8/64,0x2c0,0xcc000
 
 This configures an EasyConnection 8/64 ISA as board 3 at I/O address 0x2c0 at
 memory address 0xcc000.
 
-    insmod stallion.o board1=ec8/32-at,0x2a0,0x280,10
+    modprobe stallion board1=ec8/32-at,0x2a0,0x280,10
 
 This configures an EasyConnection 8/32 ISA board at primary I/O address 0x2a0,
 secondary address 0x280 and IRQ 10.
 
 You will probably want to enter this module load and configuration information
 into your system startup scripts so that the drivers are loaded and configured
-on each system boot. Typically the start up script would be something line
-/etc/rc.d/rc.modules.
+on each system boot. Typically the start up script would be something like
+/etc/modprobe.conf.
 
 
 2.2 STATIC DRIVER CONFIGURATION:
@@ -161,8 +157,8 @@
 To set up the driver(s) for the boards that you want to use you need to
 edit the appropriate driver file and add configuration entries.
 
-If using EasyIO or EasyConnection 8/32 ISA or MCA boards, do:
-   vi /usr/src/linux/drivers/char/stallion.c
+If using EasyIO or EasyConnection 8/32 ISA or MCA boards,
+   In drivers/char/stallion.c:
       - find the definition of the stl_brdconf array (of structures)
         near the top of the file
       - modify this to match the boards you are going to install
@@ -170,8 +166,8 @@
       - save and exit
 
 If using ONboard, Brumby, Stallion or EasyConnection 8/64 (ISA or EISA)
-boards then do:
-   vi /usr/src/linux/drivers/char/istallion.c
+boards,
+   In drivers/char/istallion.c:
       - find the definition of the stli_brdconf array (of structures)
         near the top of the file
       - modify this to match the boards you are going to install
@@ -291,20 +287,20 @@
 of course the ports will not be operational!
 
 If you are using the modularized version of the driver you might want to put
-the insmod calls in the startup script as well (before the download lines
+the modprobe calls in the startup script as well (before the download lines
 obviously).
 
 
 3.2 USING THE SERIAL PORTS
 
 Once the driver is installed you will need to setup some device nodes to
-access the serial ports. The simplest method is to use the stallion utility
-"mkdevnods" script. It will automatically create device entries for Stallion
-boards. This will create the normal serial port devices as /dev/ttyE# where
-# is the port number starting from 0. A bank of 64 minor device numbers is
-allocated to each board, so the first port on the second board is port 64,
-etc. A set of callout type devices is also created. They are created as the
-devices /dev/cue# where # is the same as for the ttyE devices.
+access the serial ports. The simplest method is to use the /dev/MAKEDEV program.
+It will automatically create device entries for Stallion boards. This will
+create the normal serial port devices as /dev/ttyE# where# is the port number
+starting from 0. A bank of 64 minor device numbers is allocated to each board,
+so the first port on the second board is port 64,etc. A set of callout type
+devices may also be created. They are created as the devices /dev/cue# where #
+is the same as for the ttyE devices.
 
 For the most part the Stallion driver tries to emulate the standard PC system
 COM ports and the standard Linux serial driver. The idea is that you should
diff -Nru a/Documentation/unicode.txt b/Documentation/unicode.txt
--- a/Documentation/unicode.txt	2005-03-01 23:38:53 -08:00
+++ b/Documentation/unicode.txt	2005-03-01 23:38:53 -08:00
@@ -1,3 +1,13 @@
+		 Last update: 2005-01-17, version 1.4
+
+This file is maintained by H. Peter Anvin <unicode@lanana.org> as part
+of the Linux Assigned Names And Numbers Authority (LANANA) project.
+The current version can be found at:
+
+	    http://www.lanana.org/docs/unicode/unicode.txt
+
+		       ------------------------
+
 The Linux kernel code has been rewritten to use Unicode to map
 characters to fonts.  By downloading a single Unicode-to-font table,
 both the eight-bit character sets and UTF-8 mode are changed to use
@@ -18,6 +28,10 @@
 permits for example the use of block graphics even with a Latin-1 font
 loaded.
 
+Note that although these codes are similar to ISO 2022, neither the
+codes nor their uses match ISO 2022; Linux has two 8-bit codes (G0 and
+G1), whereas ISO 2022 has four 7-bit codes (G0-G3).
+
 In accordance with the Unicode standard/ISO 10646 the range U+F000 to
 U+F8FF has been reserved for OS-wide allocation (the Unicode Standard
 refers to this as a "Corporate Zone", since this is inaccurate for
@@ -26,18 +40,20 @@
 two (in case 1024- or 2048-character fonts ever become necessary).
 This leaves U+E000 to U+EFFF as End User Zone.
 
-The Unicodes in the range U+F000 to U+F1FF have been hard-coded to map
-directly to the loaded font, bypassing the translation table.  The
-user-defined map now defaults to U+F000 to U+F1FF, emulating the
-previous behaviour.  This range may expand in the future should it be
-warranted.
+[v1.2]: The Unicodes range from U+F000 and up to U+F7FF have been
+hard-coded to map directly to the loaded font, bypassing the
+translation table.  The user-defined map now defaults to U+F000 to
+U+F0FF, emulating the previous behaviour.  In practice, this range
+might be shorter; for example, vgacon can only handle 256-character
+(U+F000..U+F0FF) or 512-character (U+F000..U+F1FF) fonts.
+
 
 Actual characters assigned in the Linux Zone
 --------------------------------------------
 
-In addition, the following characters not present in Unicode 1.1.4 (at
-least, I have not found them!) have been defined; these are used by
-the DEC VT graphics map:
+In addition, the following characters not present in Unicode 1.1.4
+have been defined; these are used by the DEC VT graphics map.  [v1.2]
+THIS USE IS OBSOLETE AND SHOULD NO LONGER BE USED; PLEASE SEE BELOW.
 
 U+F800 DEC VT GRAPHICS HORIZONTAL LINE SCAN 1
 U+F801 DEC VT GRAPHICS HORIZONTAL LINE SCAN 3
@@ -48,31 +64,30 @@
 a smooth progression in the DEC VT graphics character set.  I have
 omitted the scan 5 line, since it is also used as a block-graphics
 character, and hence has been coded as U+2500 FORMS LIGHT HORIZONTAL.
-However, I left U+F802 blank should the need arise.  
+
+[v1.3]: These characters have been officially added to Unicode 3.2.0;
+they are added at U+23BA, U+23BB, U+23BC, U+23BD.  Linux now uses the
+new values.
+
+[v1.2]: The following characters have been added to represent common
+keyboard symbols that are unlikely to ever be added to Unicode proper
+since they are horribly vendor-specific.  This, of course, is an
+excellent example of horrible design.
+
+U+F810 KEYBOARD SYMBOL FLYING FLAG
+U+F811 KEYBOARD SYMBOL PULLDOWN MENU
+U+F812 KEYBOARD SYMBOL OPEN APPLE
+U+F813 KEYBOARD SYMBOL SOLID APPLE
 
 Klingon language support
 ------------------------
 
-Unfortunately, Unicode/ISO 10646 does not allocate code points for the
-language Klingon, probably fearing the potential code point explosion
-if many fictional languages were submitted for inclusion.  There are
-also political reasons (the Japanese, for example, are not too happy
-about the whole 16-bit concept to begin with.)  However, with Linux
-being a hacker-driven OS it seems this is a brilliant linguistic hack
-worth supporting.  Hence I have chosen to add it to the list in the
-Linux Zone.
-
-Several glyph forms for the Klingon alphabet have been proposed.
-However, since the set of symbols appear to be consistent throughout,
-with only the actual shapes being different, in keeping with standard
-Unicode practice these differences are considered font variants.
-
-Klingon has an alphabet of 26 characters, a positional numeric writing
-system with 10 digits, and is written left-to-right, top-to-bottom.
-Punctuation appears to be only used in Latin transliteration; it
-appears customary to write each sentence on its own line, and
-centered.  Space has been reserved for punctuation should it prove
-necessary.
+In 1996, Linux was the first operating system in the world to add
+support for the artificial language Klingon, created by Marc Okrand
+for the "Star Trek" television series.	This encoding was later
+adopted by the ConScript Unicode Registry and proposed (but ultimately
+rejected) for inclusion in Unicode Plane 1.  Thus, it remains as a
+Linux/CSUR private assignment in the Linux Zone.
 
 This encoding has been endorsed by the Klingon Language Institute.
 For more information, contact them at:
@@ -84,6 +99,19 @@
 located it at the end, on a 16-cell boundary in keeping with standard
 Unicode practice.
 
+NOTE: This range is now officially managed by the ConScript Unicode
+Registry.  The normative reference is at:
+
+	http://www.evertype.com/standards/csur/klingon.html
+
+Klingon has an alphabet of 26 characters, a positional numeric writing
+system with 10 digits, and is written left-to-right, top-to-bottom.
+
+Several glyph forms for the Klingon alphabet have been proposed.
+However, since the set of symbols appear to be consistent throughout,
+with only the actual shapes being different, in keeping with standard
+Unicode practice these differences are considered font variants.
+
 U+F8D0	KLINGON LETTER A
 U+F8D1	KLINGON LETTER B
 U+F8D2	KLINGON LETTER CH
@@ -124,16 +152,24 @@
 U+F8F8	KLINGON DIGIT EIGHT
 U+F8F9	KLINGON DIGIT NINE
 
+U+F8FD	KLINGON COMMA
+U+F8FE	KLINGON FULL STOP
+U+F8FF	KLINGON SYMBOL FOR EMPIRE
+
 Other Fictional and Artificial Scripts
 --------------------------------------
 
 Since the assignment of the Klingon Linux Unicode block, a registry of
-fictional and artificial scripts has been established by John Cowan,
-<cowan@ccil.org>.  The ConScript Unicode Registry is accessible at
-http://locke.ccil.org/~cowan/csur/; the ranges used fall at the bottom
-of the End User Zone and can hence not be normatively assigned, but it
-is recommended that people who wish to encode fictional scripts use
-these codes, in the interest of interoperability.  For Klingon, CSUR
-has adopted the Linux encoding.
-
-	H. Peter Anvin <hpa@zytor.com>
+fictional and artificial scripts has been established by John Cowan
+<jcowan@reutershealth.com> and Michael Everson <everson@evertype.com>.
+The ConScript Unicode Registry is accessible at:
+
+	  http://www.evertype.com/standards/csur/
+
+The ranges used fall at the low end of the End User Zone and can hence
+not be normatively assigned, but it is recommended that people who
+wish to encode fictional scripts use these codes, in the interest of
+interoperability.  For Klingon, CSUR has adopted the Linux encoding.
+The CSUR people are driving adding Tengwar and Cirth into Unicode
+Plane 1; the addition of Klingon to Unicode Plane 1 has been rejected
+and so the above encoding remains official.
diff -Nru a/Documentation/usb/error-codes.txt b/Documentation/usb/error-codes.txt
--- a/Documentation/usb/error-codes.txt	2005-03-01 23:38:44 -08:00
+++ b/Documentation/usb/error-codes.txt	2005-03-01 23:38:44 -08:00
@@ -83,7 +83,18 @@
 			   prescribed bus turn-around time
 			c) unknown USB error 
 
--EILSEQ (*, **)		CRC mismatch
+-EILSEQ (*, **)		a) CRC mismatch
+			b) no response packet received within the
+			   prescribed bus turn-around time
+			c) unknown USB error 
+
+			In cases b) and c) either -EPROTO or -EILSEQ
+			may be returned.  Note that often the controller
+			hardware does not distinguish among cases a),
+			b), and c), so a driver cannot tell whether
+			there was a protocol error, a failure to respond
+			(often caused by device disconnect), or some
+			other fault.
 
 -EPIPE (**)		Endpoint stalled.  For non-control endpoints,
 			reset this status with usb_clear_halt().
@@ -104,8 +115,6 @@
 			specified buffer, and URB_SHORT_NOT_OK was set in
 			urb->transfer_flags.
 
--ETIMEDOUT (**)		transfer timed out, NAK
-
 -ENODEV			Device was removed.  Often preceded by a burst of
 			other errors, since the hub driver does't detect
 			device removal events immediately.
@@ -143,4 +152,4 @@
 usb_get_*/usb_set_*():
 usb_control_msg():
 usb_bulk_msg():
-			All USB errors (submit/status) can occur
+-ETIMEDOUT		timeout expired before the transfer completed
diff -Nru a/Documentation/usb/silverlink.txt b/Documentation/usb/silverlink.txt
--- a/Documentation/usb/silverlink.txt	2005-03-01 23:38:55 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,78 +0,0 @@
--------------------------------------------------------------------------
-Readme for Linux device driver for the Texas Instruments SilverLink cable
-and direct USB cable provided by some TI's handhelds.
--------------------------------------------------------------------------
-
-Author: Romain Liévin & Julien Blache
-Homepage: http://lpg.ticalc.org/prj_usb
-
-INTRODUCTION:
-
-This is a driver for the TI-GRAPH LINK USB (aka SilverLink) cable, a cable 
-designed by TI for connecting their TI8x/9x calculators to a computer 
-(PC or Mac usually). It has been extended to support the USB port offered by
-some latest TI handhelds (TI84+ and TI89 Titanium).
-
-If you need more information, please visit the 'SilverLink drivers' homepage 
-at the above URL.
-
-WHAT YOU NEED:
-
-A TI calculator of course and a program capable to communicate with your 
-calculator.
-TiLP will work for sure (since I am his developer !). yal92 may be able to use
-it by changing tidev for tiglusb (may require some hacking...).
-
-HOW TO USE IT:
-
-You must have first compiled USB support, support for your specific USB host
-controller (UHCI or OHCI).
-
-Next, (as root) from your appropriate modules directory (lib/modules/2.5.XX):
-
-       insmod usb/usbcore.o
-       insmod usb/usb-uhci.o  <OR>  insmod usb/ohci-hcd.o
-       insmod tiglusb.o
-
-If it is not already there (it usually is), create the device:
-
-       mknod /dev/tiglusb0 c 115 16
-
-You will have to set permissions on this device to allow you to read/write
-from it:
-
-       chmod 666 /dev/tiglusb0
-       
-Now you are ready to run a linking program such as TiLP. Be sure to configure 
-it properly (RTFM).
-       
-MODULE PARAMETERS:
-
-  You can set these with:  insmod tiglusb NAME=VALUE
-  There is currently no way to set these on a per-cable basis.
-
-  NAME: timeout
-  TYPE: integer
-  DEFAULT: 15
-  DESC: Timeout value in tenth of seconds. If no data is available once this 
-       time has expired then the driver will return with a timeout error.
-
-QUIRKS:
-
-The following problem seems to be specific to the link cable since it appears 
-on all platforms (Linux, Windows, Mac OS-X). 
-
-In some very particular cases, the driver returns with success but
-without any data. The application should retry a read operation at least once.
-
-HOW TO CONTACT US:
-
-You can email me at roms@lpg.ticalc.org. Please prefix the subject line
-with "TIGLUSB: " so that I am certain to notice your message.
-You can also mail JB at jb@jblache.org: he has written the first release of 
-this driver but he better knows the Mac OS-X driver.
-
-CREDITS:
-
-The code is based on dabusb.c, printer.c and scanner.c !
-The driver has been developed independently of Texas Instruments Inc.
diff -Nru a/Documentation/usb/sn9c102.txt b/Documentation/usb/sn9c102.txt
--- a/Documentation/usb/sn9c102.txt	2005-03-01 23:39:09 -08:00
+++ b/Documentation/usb/sn9c102.txt	2005-03-01 23:39:09 -08:00
@@ -11,21 +11,22 @@
 1.  Copyright
 2.  Disclaimer
 3.  License
-4.  Overview
-5.  Driver installation
+4.  Overview and features
+5.  Module dependencies
 6.  Module loading
 7.  Module parameters
 8.  Optional device control through "sysfs"
 9.  Supported devices
-10. How to add support for new image sensors
+10. How to add plug-in's for new image sensors
 11. Notes for V4L2 application developers
-12. Contact information
-13. Credits
+12. Video frame formats
+13. Contact information
+14. Credits
 
 
 1. Copyright
 ============
-Copyright (C) 2004 by Luca Risolia <luca.risolia@studio.unibo.it>
+Copyright (C) 2004-2005 by Luca Risolia <luca.risolia@studio.unibo.it>
 
 
 2. Disclaimer
@@ -51,16 +52,18 @@
 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
 
-4. Overview
-===========
+4. Overview and features
+========================
 This driver attempts to support the video and audio streaming capabilities of
-the devices mounting the SONiX SN9C101, SN9C102 and SN9C103 (or SUI-102) PC
-Camera Controllers.
+the devices mounting the SONiX SN9C101, SN9C102 and SN9C103 PC Camera
+Controllers.
 
 It's worth to note that SONiX has never collaborated with the author during the
 development of this project, despite several requests for enough detailed
 specifications of the register tables, compression engine and video data format
-of the above chips.
+of the above chips. Nevertheless, these informations are no longer necessary,
+becouse all the aspects related to these chips are known and have been
+described in detail in this documentation.
 
 The driver relies on the Video4Linux2 and USB core modules. It has been
 designed to run properly on SMP systems as well.
@@ -79,15 +82,16 @@
   pixel area of image sensor;
 - image downscaling with arbitrary scaling factors from 1, 2 and 4 in both
   directions (see "Notes for V4L2 application developers" paragraph);
-- two different video formats for uncompressed or compressed data (see also
-  "Notes for V4L2 application developers" paragraph);
+- two different video formats for uncompressed or compressed data in low or
+  high compression quality (see also "Notes for V4L2 application developers"
+  and "Video frame formats" paragraphs);
 - full support for the capabilities of many of the possible image sensors that
   can be connected to the SN9C10x bridges, including, for istance, red, green,
   blue and global gain adjustments and exposure (see "Supported devices"
   paragraph for details);
 - use of default color settings for sunlight conditions;
-- dynamic I/O interface for both SN9C10x and image sensor control (see
-  "Optional device control through 'sysfs'" paragraph);
+- dynamic I/O interface for both SN9C10x and image sensor control and
+  monitoring (see "Optional device control through 'sysfs'" paragraph);
 - dynamic driver control thanks to various module parameters (see "Module
   parameters" paragraph);
 - up to 64 cameras can be handled at the same time; they can be connected and
@@ -161,6 +165,17 @@
                 other camera.
 Default:        -1
 -------------------------------------------------------------------------------
+Name:           force_munmap;
+Type:           bool array (min = 0, max = 64)
+Syntax:         <0|1[,...]> 
+Description:    Force the application to unmap previously mapped buffer memory
+                before calling any VIDIOC_S_CROP or VIDIOC_S_FMT ioctl's. Not
+                all the applications support this feature. This parameter is
+                specific for each detected camera.
+                0 = do not force memory unmapping"
+                1 = force memory unmapping (save memory)"
+Default:        0
+-------------------------------------------------------------------------------
 Name:           debug
 Type:           int
 Syntax:         <n> 
@@ -177,7 +192,7 @@
 -------------------------------------------------------------------------------
 
 
-8. Optional device control through "sysfs"
+8. Optional device control through "sysfs" [1]
 ==========================================
 It is possible to read and write both the SN9C10x and the image sensor
 registers by using the "sysfs" filesystem interface.
@@ -195,9 +210,9 @@
 SN9C10x bridge, while the other two control the sensor chip. "reg" and
 "i2c_reg" hold the values of the current register index where the following
 reading/writing operations are addressed at through "val" and "i2c_val". Their
-use is not intended for end-users, unless you know what you are doing. Note
-that "i2c_reg" and "i2c_val" won't be created if the sensor does not actually
-support the standard I2C protocol. Also, remember that you must be logged in as
+use is not intended for end-users. Note that "i2c_reg" and "i2c_val" won't be
+created if the sensor does not actually support the standard I2C protocol or
+its registers are not 8-bit long. Also, remember that you must be logged in as
 root before writing to them.
 
 As an example, suppose we were to want to read the value contained in the
@@ -216,7 +231,48 @@
 	[root@localhost #] echo 2 > val
 
 Note that the SN9C10x always returns 0 when some of its registers are read.
-To avoid race conditions, all the I/O accesses to the files are serialized.
+To avoid race conditions, all the I/O accesses to the above files are
+serialized.
+
+The sysfs interface also provides the "frame_header" entry, which exports the
+frame header of the most recent requested and captured video frame. The header
+is 12-bytes long and is appended to every video frame by the SN9C10x
+controllers. As an example, this additional information can be used by the user
+application for implementing auto-exposure features via software. 
+
+The following table describes the frame header:
+
+Byte #  Value         Description
+------  -----         -----------
+0x00    0xFF          Frame synchronisation pattern.
+0x01    0xFF          Frame synchronisation pattern.
+0x02    0x00          Frame synchronisation pattern.
+0x03    0xC4          Frame synchronisation pattern.
+0x04    0xC4          Frame synchronisation pattern.
+0x05    0x96          Frame synchronisation pattern.
+0x06    0x00 or 0x01  Unknown meaning. The exact value depends on the chip.
+0x07    0xXX          Variable value, whose bits are ff00uzzc, where ff is a
+                      frame counter, u is unknown, zz is a size indicator
+                      (00 = VGA, 01 = SIF, 10 = QSIF) and c stands for
+                      "compression enabled" (1 = yes, 0 = no).
+0x08    0xXX          Brightness sum inside Auto-Exposure area (low-byte).
+0x09    0xXX          Brightness sum inside Auto-Exposure area (high-byte).
+                      For a pure white image, this number will be equal to 500
+                      times the area of the specified AE area. For images
+                      that are not pure white, the value scales down according
+                      to relative whiteness.
+0x0A    0xXX          Brightness sum outside Auto-Exposure area (low-byte).
+0x0B    0xXX          Brightness sum outside Auto-Exposure area (high-byte).
+                      For a pure white image, this number will be equal to 125
+                      times the area outside of the specified AE area. For
+                      images that are not pure white, the value scales down
+                      according to relative whiteness.
+
+The AE area (sx, sy, ex, ey) in the active window can be set by programming the
+registers 0x1c, 0x1d, 0x1e and 0x1f of the SN9C10x controllers, where one unit
+corresponds to 32 pixels.
+
+[1] The frame header has been documented by Bertrik Sikken.
 
 
 9. Supported devices
@@ -275,8 +331,10 @@
 
 Model       Manufacturer
 -----       ------------
-PAS106B     PixArt Imaging Inc.
-PAS202BCB   PixArt Imaging Inc.
+HV7131D     Hynix Semiconductor, Inc.
+MI-0343     Micron Technology, Inc.
+PAS106B     PixArt Imaging, Inc.
+PAS202BCB   PixArt Imaging, Inc.
 TAS5110C1B  Taiwan Advanced Sensor Corporation
 TAS5130D1B  Taiwan Advanced Sensor Corporation
 
@@ -295,15 +353,15 @@
 driver.
 
 
-10. How to add support for new image sensors
-============================================
-It should be easy to write code for new sensors by using the small API that I
-have created for this purpose, which is present in "sn9c102_sensor.h"
+10. How to add plug-in's for new image sensors
+==============================================
+It should be easy to write plug-in's for new sensors by using the small API
+that has been created for this purpose, which is present in "sn9c102_sensor.h"
 (documentation is included there). As an example, have a look at the code in
 "sn9c102_pas106b.c", which uses the mentioned interface.
 
-At the moment, possible unsupported image sensors are: HV7131x series (VGA),
-MI03x series (VGA), OV7620 (VGA), OV7630 (VGA), CIS-VF10 (VGA).
+At the moment, possible unsupported image sensors are: CIS-VF10 (VGA),
+OV7620 (VGA), OV7630 (VGA).
 
 
 11. Notes for V4L2 application developers
@@ -315,11 +373,11 @@
 file descriptor. Once it is selected, the application must close and reopen the
 device to switch to the other I/O method;
 
-- previously mapped buffer memory must always be unmapped before calling any
-of the "VIDIOC_S_CROP", "VIDIOC_TRY_FMT" and "VIDIOC_S_FMT" ioctl's. The same
-number of buffers as before will be allocated again to match the size of the
-new video frames, so you have to map the buffers again before any I/O attempts
-on them.
+- although it is not mandatory, previously mapped buffer memory should always
+be unmapped before calling any "VIDIOC_S_CROP" or "VIDIOC_S_FMT" ioctl's.
+The same number of buffers as before will be allocated again to match the size
+of the new video frames, so you have to map the buffers again before any I/O
+attempts on them.
 
 Consistently with the hardware limits, this driver also supports image
 downscaling with arbitrary scaling factors from 1, 2 and 4 in both directions.
@@ -332,29 +390,98 @@
 This driver supports two different video formats: the first one is the "8-bit
 Sequential Bayer" format and can be used to obtain uncompressed video data
 from the device through the current I/O method, while the second one provides
-"raw" compressed video data (without the initial and final frame headers). The
-compression quality may vary from 0 to 1 and can be selected or queried thanks
-to the VIDIOC_S_JPEGCOMP and VIDIOC_G_JPEGCOMP V4L2 ioctl's. For maximum
-flexibility, the default active video format depends on how the image sensor
-being used is initialized (as described in the documentation of the API for the
-image sensors supplied by this driver).
+"raw" compressed video data (without frame headers not related to the
+compressed data). The compression quality may vary from 0 to 1 and can be
+selected or queried thanks to the VIDIOC_S_JPEGCOMP and VIDIOC_G_JPEGCOMP V4L2
+ioctl's. For maximum flexibility, both the default active video format and the
+default compression quality depend on how the image sensor being used is
+initialized (as described in the documentation of the API for the image sensors
+supplied by this driver).
+
+
+12. Video frame formats [1]
+=======================
+The SN9C10x PC Camera Controllers can send images in two possible video
+formats over the USB: either native "Sequential RGB Bayer" or Huffman
+compressed. The latter is used to achieve high frame rates. The current video
+format may be selected or queried from the user application by calling the
+VIDIOC_S_FMT or VIDIOC_G_FMT ioctl's, as described in the V4L2 API
+specifications.
+
+The name "Sequential Bayer" indicates the organization of the red, green and
+blue pixels in one video frame. Each pixel is associated with a 8-bit long
+value and is disposed in memory according to the pattern shown below:
+
+B[0]   G[1]    B[2]    G[3]    ...   B[m-2]         G[m-1]
+G[m]   R[m+1]  G[m+2]  R[m+2]  ...   G[2m-2]        R[2m-1] 
+...
+...                                  B[(n-1)(m-2)]  G[(n-1)(m-1)]
+...                                  G[n(m-2)]      R[n(m-1)]
+
+The above matrix also represents the sequential or progressive read-out mode of
+the (n, m) Bayer color filter array used in many CCD/CMOS image sensors.
+
+One compressed video frame consists of a bitstream that encodes for every R, G,
+or B pixel the difference between the value of the pixel itself and some
+reference pixel value. Pixels are organised in the Bayer pattern and the Bayer
+sub-pixels are tracked individually and alternatingly. For example, in the
+first line values for the B and G1 pixels are alternatingly encoded, while in
+the second line values for the G2 and R pixels are alternatingly encoded.
+
+The pixel reference value is calculated as follows:
+- the 4 top left pixels are encoded in raw uncompressed 8-bit format;
+- the value in the top two rows is the value of the pixel left of the current
+  pixel;
+- the value in the left column is the value of the pixel above the current
+  pixel;
+- for all other pixels, the reference value is the average of the value of the
+  pixel on the left and the value of the pixel above the current pixel;
+- there is one code in the bitstream that specifies the value of a pixel
+  directly (in 4-bit resolution);
+- pixel values need to be clamped inside the range [0..255] for proper
+  decoding.
+
+The algorithm purely describes the conversion from compressed Bayer code used
+in the SN9C10x chips to uncompressed Bayer. Additional steps are required to
+convert this to a color image (i.e. a color interpolation algorithm).
+ 
+The following Huffman codes have been found:
+0: +0 (relative to reference pixel value) 
+100: +4
+101: -4?
+1110xxxx: set absolute value to xxxx.0000 
+1101: +11
+1111: -11
+11001: +20
+110000: -20
+110001: ??? - these codes are apparently not used
+
+[1] The Huffman compression algorithm has been reverse-engineered and
+    documented by Bertrik Sikken.
 
 
-12. Contact information
+13. Contact information
 =======================
-I may be contacted by e-mail at <luca.risolia@studio.unibo.it>.
+The author may be contacted by e-mail at <luca.risolia@studio.unibo.it>.
 
-I can accept GPG/PGP encrypted e-mail. My GPG key ID is 'FCE635A4'.
-My public 1024-bit key should be available at any keyserver; the fingerprint
-is: '88E8 F32F 7244 68BA 3958  5D40 99DA 5D2A FCE6 35A4'.
+GPG/PGP encrypted e-mail's are accepted. The GPG key ID of the author is
+'FCE635A4'; the public 1024-bit key should be available at any keyserver;
+the fingerprint is: '88E8 F32F 7244 68BA 3958  5D40 99DA 5D2A FCE6 35A4'.
 
 
-13. Credits
+14. Credits
 ===========
-I would thank the following persons:
+Many thanks to following persons for their contribute (listed in alphabetical
+order):
 
-- Stefano Mozzi, who donated 45 EU;
 - Luca Capello for the donation of a webcam;
-- Mizuno Takafumi for the donation of a webcam;
+- Joao Rodrigo Fuzaro, Joao Limirio, Claudio Filho and Caio Begotti for the
+  donation of a webcam;
 - Carlos Eduardo Medaglia Dyonisio, who added the support for the PAS202BCB
-  image sensor.
+  image sensor;
+- Stefano Mozzi, who donated 45 EU;
+- 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;
+- An "anonymous" donator (who didn't want his name to be revealed) for the
+  donation of a webcam.
diff -Nru a/Documentation/vm/hugetlbpage.txt b/Documentation/vm/hugetlbpage.txt
--- a/Documentation/vm/hugetlbpage.txt	2005-03-01 23:38:52 -08:00
+++ b/Documentation/vm/hugetlbpage.txt	2005-03-01 23:38:52 -08:00
@@ -1,14 +1,14 @@
 
 The intent of this file is to give a brief summary of hugetlbpage support in
 the Linux kernel.  This support is built on top of multiple page size support
-that is provided by most of modern architectures.  For example, IA-32
-architecture supports 4K and 4M (2M in PAE mode) page sizes, IA-64
+that is provided by most modern architectures.  For example, i386
+architecture supports 4K and 4M (2M in PAE mode) page sizes, ia64
 architecture supports multiple page sizes 4K, 8K, 64K, 256K, 1M, 4M, 16M,
-256M.  A TLB is a cache of virtual-to-physical translations.  Typically this
-is a very scarce resource on processor.  Operating systems try to make best
-use of limited number of TLB resources.  This optimization is more critical
-now as bigger and bigger physical memories (several GBs) are more readily
-available.
+256M and ppc64 supports 4K and 16M.  A TLB is a cache of virtual-to-physical
+translations.  Typically this is a very scarce resource on processor.
+Operating systems try to make best use of limited number of TLB resources.
+This optimization is more critical now as bigger and bigger physical memories
+(several GBs) are more readily available.
 
 Users can use the huge page support in Linux kernel by either using the mmap
 system call or standard SYSv shared memory system calls (shmget, shmat).
@@ -98,125 +98,187 @@
 applications to use any combination of mmaps and shm* calls.  Though the
 mount of filesystem will be required for using mmaps.
 
-/* Example of using hugepage in user application using Sys V shared memory
- * system calls.  In this example, app is requesting memory of size 256MB that
- * is backed by huge pages.  Application uses the flag SHM_HUGETLB in shmget
- * system call to informt the kernel that it is requesting hugepages.  For
- * IA-64 architecture, Linux kernel reserves Region number 4 for hugepages.
- * That means the addresses starting with 0x800000....will need to be
- * specified.
+*******************************************************************
+
+/*
+ * Example of using hugepage memory in a user application using Sys V shared
+ * memory system calls.  In this example the app is requesting 256MB of
+ * memory that is backed by huge pages.  The application uses the flag
+ * SHM_HUGETLB in the shmget system call to inform the kernel that it is
+ * requesting hugepages.
+ *
+ * For the ia64 architecture, the Linux kernel reserves Region number 4 for
+ * hugepages.  That means the addresses starting with 0x800000... will need
+ * to be specified.  Specifying a fixed address is not required on ppc64,
+ * i386 or x86_64.
+ *
+ * Note: The default shared memory limit is quite low on many kernels,
+ * you may need to increase it via:
+ *
+ * echo 268435456 > /proc/sys/kernel/shmmax
+ *
+ * This will increase the maximum size per shared memory segment to 256MB.
+ * The other limit that you will hit eventually is shmall which is the
+ * total amount of shared memory in pages. To set it to 16GB on a system
+ * with a 4kB pagesize do:
+ *
+ * echo 4194304 > /proc/sys/kernel/shmall
  */
+#include <stdlib.h>
+#include <stdio.h>
 #include <sys/types.h>
+#include <sys/ipc.h>
 #include <sys/shm.h>
-#include <sys/types.h>
 #include <sys/mman.h>
-#include <errno.h>
 
-extern int errno;
+#ifndef SHM_HUGETLB
 #define SHM_HUGETLB 04000
-#define LPAGE_SIZE      (256UL*1024UL*1024UL)
-#define         dprintf(x)  printf(x)
-#define ADDR (0x8000000000000000UL)
-main()
+#endif
+
+#define LENGTH (256UL*1024*1024)
+
+#define dprintf(x)  printf(x)
+
+/* Only ia64 requires this */
+#ifdef __ia64__
+#define ADDR (void *)(0x8000000000000000UL)
+#define SHMAT_FLAGS (SHM_RND)
+#else
+#define ADDR (void *)(0x0UL)
+#define SHMAT_FLAGS (0)
+#endif
+
+int main(void)
 {
-        int shmid;
-        int     i, j, k;
-        volatile        char    *shmaddr;
-
-        if ((shmid =shmget(2, LPAGE_SIZE, SHM_HUGETLB|IPC_CREAT|SHM_R|SHM_W ))
-< 0) {
-                perror("Failure:");
-                exit(1);
-        }
-        printf("shmid: 0x%x\n", shmid);
-        shmaddr = shmat(shmid, (void *)ADDR, SHM_RND) ;
-        if (errno != 0) {
-                perror("Shared Memory Attach Failure:");
-                exit(2);
-        }
-        printf("shmaddr: %p\n", shmaddr);
-
-        dprintf("Starting the writes:\n");
-        for (i=0;i<LPAGE_SIZE;i++) {
-                shmaddr[i] = (char) (i);
-                if (!(i%(1024*1024))) dprintf(".");
-        }
-        dprintf("\n");
-        dprintf("Starting the Check...");
-        for (i=0; i<LPAGE_SIZE;i++)
-                if (shmaddr[i] != (char)i)
-                        printf("\nIndex %d mismatched.");
-        dprintf("Done.\n");
-        if (shmdt((const void *)shmaddr) != 0) {
-                perror("Detached Failure:");
-                exit (3);
-        }
+	int shmid;
+	unsigned long i;
+	char *shmaddr;
+
+	if ((shmid = shmget(2, LENGTH,
+			    SHM_HUGETLB | IPC_CREAT | SHM_R | SHM_W)) < 0) {
+		perror("shmget");
+		exit(1);
+	}
+	printf("shmid: 0x%x\n", shmid);
+
+	shmaddr = shmat(shmid, ADDR, SHMAT_FLAGS);
+	if (shmaddr == (char *)-1) {
+		perror("Shared memory attach failure");
+		shmctl(shmid, IPC_RMID, NULL);
+		exit(2);
+	}
+	printf("shmaddr: %p\n", shmaddr);
+
+	dprintf("Starting the writes:\n");
+	for (i = 0; i < LENGTH; i++) {
+		shmaddr[i] = (char)(i);
+		if (!(i % (1024 * 1024)))
+			dprintf(".");
+	}
+	dprintf("\n");
+
+	dprintf("Starting the Check...");
+	for (i = 0; i < LENGTH; i++)
+		if (shmaddr[i] != (char)i)
+			printf("\nIndex %lu mismatched\n", i);
+	dprintf("Done.\n");
+
+	if (shmdt((const void *)shmaddr) != 0) {
+		perror("Detach failure");
+		shmctl(shmid, IPC_RMID, NULL);
+		exit(3);
+	}
+
+	shmctl(shmid, IPC_RMID, NULL);
+
+	return 0;
 }
-*******************************************************************
-*******************************************************************
 
+*******************************************************************
 
-/* Example of using hugepage in user application using mmap 
- * system call.  Before running this application, make sure that
- * administrator has mounted the hugetlbfs (on some directory like /mnt) using
- * the command mount -t hugetlbfs nodev /mnt
- * In this example, app is requesting memory of size 256MB that
- * is backed by huge pages.  Application uses the flag SHM_HUGETLB in shmget
- * system call to informt the kernel that it is requesting hugepages.  For
- * IA-64 architecture, Linux kernel reserves Region number 4 for hugepages.
- * That means the addresses starting with 0x800000....will need to be
- * specified.
+/*
+ * Example of using hugepage memory in a user application using the mmap
+ * system call.  Before running this application, make sure that the
+ * administrator has mounted the hugetlbfs filesystem (on some directory
+ * like /mnt) using the command mount -t hugetlbfs nodev /mnt. In this
+ * example, the app is requesting memory of size 256MB that is backed by
+ * huge pages.
+ *
+ * For ia64 architecture, Linux kernel reserves Region number 4 for hugepages.
+ * That means the addresses starting with 0x800000... will need to be
+ * specified.  Specifying a fixed address is not required on ppc64, i386
+ * or x86_64.
  */
-#include <unistd.h>
+#include <stdlib.h>
 #include <stdio.h>
+#include <unistd.h>
 #include <sys/mman.h>
 #include <fcntl.h>
-#include <errno.h>
 
 #define FILE_NAME "/mnt/hugepagefile"
-#define LENGTH (256*1024*1024)
+#define LENGTH (256UL*1024*1024)
 #define PROTECTION (PROT_READ | PROT_WRITE)
-#define FLAGS   MAP_SHARED |MAP_FIXED
-#define ADDRESS (char *)(0x60000000UL + 0x8000000000000000UL)
 
-extern errno;
+/* Only ia64 requires this */
+#ifdef __ia64__
+#define ADDR (void *)(0x8000000000000000UL)
+#define FLAGS (MAP_SHARED | MAP_FIXED)
+#else
+#define ADDR (void *)(0x0UL)
+#define FLAGS (MAP_SHARED)
+#endif
 
-check_bytes(char *addr)
+void check_bytes(char *addr)
 {
-        printf("First hex is %x\n", *((unsigned int *)addr));
+	printf("First hex is %x\n", *((unsigned int *)addr));
 }
 
-write_bytes(char *addr)
+void write_bytes(char *addr)
 {
-        int i;
-        for (i=0;i<LENGTH;i++)
-                *(addr+i)=(char)i;
+	unsigned long i;
+
+	for (i = 0; i < LENGTH; i++)
+		*(addr + i) = (char)i;
 }
-read_bytes(char *addr)
+
+void read_bytes(char *addr)
 {
-        int i;
-        check_bytes(addr);
-        for (i=0;i<LENGTH;i++)
-                if (*(addr+i)!=(char)i) {
-                        printf("Mismatch at %d\n", i);
-                        break;
-                }
+	unsigned long i;
+
+	check_bytes(addr);
+	for (i = 0; i < LENGTH; i++)
+		if (*(addr + i) != (char)i) {
+			printf("Mismatch at %lu\n", i);
+			break;
+		}
 }
-main()
+
+int main(void)
 {
-        unsigned long addr = 0;
-        int fd ;
+	void *addr;
+	int fd;
+
+	fd = open(FILE_NAME, O_CREAT | O_RDWR, 0755);
+	if (fd < 0) {
+		perror("Open failed");
+		exit(1);
+	}
+
+	addr = mmap(ADDR, LENGTH, PROTECTION, FLAGS, fd, 0);
+	if (addr == MAP_FAILED) {
+		perror("mmap");
+		unlink(FILE_NAME);
+		exit(1);
+	}
+
+	printf("Returned address is %p\n", addr);
+	check_bytes(addr);
+	write_bytes(addr);
+	read_bytes(addr);
+
+	munmap(addr, LENGTH);
+	close(fd);
+	unlink(FILE_NAME);
 
-        fd = open(FILE_NAME, O_CREAT|O_RDWR, 0755);
-        if (fd < 0) {
-                perror("Open failed");
-                exit(errno);
-        }
-        addr = (unsigned long)mmap(ADDRESS, LENGTH, PROTECTION, FLAGS, fd, 0);
-        if (errno != 0)
-                perror("mmap failed");
-        printf("Returned address is %p\n", addr);
-        check_bytes((char*)addr);
-        write_bytes((char*)addr);
-        read_bytes((char *)addr);
+	return 0;
 }
diff -Nru a/Documentation/vm/numa b/Documentation/vm/numa
--- a/Documentation/vm/numa	2005-03-01 23:39:07 -08:00
+++ b/Documentation/vm/numa	2005-03-01 23:39:07 -08:00
@@ -29,7 +29,7 @@
 into a pg_data_t. The bootmem_data_t is just one part of this. To 
 make the code look uniform between NUMA and regular UMA platforms, 
 UMA platforms have a statically allocated pg_data_t too (contig_page_data).
-For the sake of uniformity, the variable "numnodes" is also defined
+For the sake of uniformity, the function num_online_nodes() is also defined
 for all platforms. As we run benchmarks, we might decide to NUMAize 
 more variables like low_on_memory, nr_free_pages etc into the pg_data_t.
 
diff -Nru a/Documentation/w1/w1.generic b/Documentation/w1/w1.generic
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/Documentation/w1/w1.generic	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,19 @@
+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.
+
+You can call above methods by reading appropriate sysfs files.
diff -Nru a/Documentation/x86_64/boot-options.txt b/Documentation/x86_64/boot-options.txt
--- a/Documentation/x86_64/boot-options.txt	2005-03-01 23:39:17 -08:00
+++ b/Documentation/x86_64/boot-options.txt	2005-03-01 23:39:17 -08:00
@@ -14,8 +14,6 @@
 APICs
 
    apic		 Use IO-APIC. Default
-		 Unless you have an NVidia or VIA/Uniprocessor board.
-		Then it defaults to off.
 
    noapic	 Don't use the IO-APIC.
 
@@ -25,6 +23,8 @@
 
    pirq=...	 See Documentation/i386/IO-APIC.txt
 
+   noapictimer	 Don't set up the APIC timer
+
 Early Console
 
    syntax: earlyprintk=vga
@@ -61,6 +61,9 @@
   This is useful when you use a panic=... timeout and need the box
   quickly up again.
 
+  nohpet
+  Don't use the HPET timer.
+
 Idle loop
 
   idle=poll
@@ -74,7 +77,7 @@
    reboot=b[ios] | t[riple] | k[bd] [, [w]arm | [c]old]
    bios	  Use the CPU reboto vector for warm reset
    warm   Don't set the cold reboot flag
-   cold   Set the cold reboto flag
+   cold   Set the cold reboot flag
    triple Force a triple fault (init)
    kbd    Use the keyboard controller. cold reset (default)
 
@@ -83,6 +86,11 @@
    Disadvantage is that not all hardware will be completely reinitialized
    on reboot so there may be boot problems on some systems.
 
+   reboot=force
+
+   Don't stop other CPUs on reboot. This can make reboot more reliable
+   in some cases.
+
 Non Executable Mappings
 
   noexec=on|off
@@ -102,6 +110,9 @@
 
   numa=off	Only set up a single NUMA node spanning all memory.
 
+  numa=noacpi   Don't parse the SRAT table for NUMA setup
+
+  numa=fake=X   Fake X nodes and ignore NUMA setup of the actual machine.
 
 ACPI
 
@@ -110,6 +121,12 @@
 		interpreter
   acpi=force	Force ACPI on (currently not needed)
 
+  acpi=strict   Disable out of spec ACPI workarounds.
+
+  acpi_sci={edge,level,high,low}  Set up ACPI SCI interrupt.
+
+  acpi=noirq	Don't route interrupts
+
 PCI
 
   pci=off	Don't use PCI
@@ -119,6 +136,7 @@
   pci=assign-busses    Assign busses
   pci=irqmask=MASK	       Set PCI interrupt mask to MASK
   pci=lastbus=NUMBER	       Scan upto NUMBER busses, no matter what the mptable says.
+  pci=noacpi		Don't use ACPI to set up PCI interrupt routing.
 
 IOMMU
 
@@ -144,3 +162,19 @@
 
   pages  Prereserve that many 128K pages for the software IO bounce buffering.
   force  Force all IO through the software TLB.
+
+Debugging
+
+  oops=panic Always panic on oopses. Default is to just kill the process,
+	     but there is a small probability of deadlocking the machine.
+	     This will also cause panics on machine check exceptions.
+	     Useful together with panic=30 to trigger a reboot.
+
+  kstack=N   Print that many words from the kernel stack in oops dumps.
+
+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.
+
diff -Nru a/Documentation/x86_64/mm.txt b/Documentation/x86_64/mm.txt
--- a/Documentation/x86_64/mm.txt	2005-03-01 23:39:16 -08:00
+++ b/Documentation/x86_64/mm.txt	2005-03-01 23:39:16 -08:00
@@ -1,148 +1,24 @@
-The paging design used on the x86-64 linux kernel port in 2.4.x provides:
 
-o	per process virtual address space limit of 512 Gigabytes
-o	top of userspace stack located at address 0x0000007fffffffff
-o	PAGE_OFFSET = 0xffff800000000000
-o	start of the kernel = 0xffffffff800000000
-o	global RAM per system 2^64-PAGE_OFFSET-sizeof(kernel) = 128 Terabytes - 2 Gigabytes
-o	no need of any common code change
-o	no need to use highmem to handle the 128 Terabytes of RAM
-
-Description:
-
-	Userspace is able to modify and it sees only the 3rd/2nd/1st level
-	pagetables (pgd_offset() implicitly walks the 1st slot of the 4th
-	level pagetable and it returns an entry into the 3rd level pagetable).
-	This is where the per-process 512 Gigabytes limit cames from.
-
-	The common code pgd is the PDPE, the pmd is the PDE, the
-	pte is the PTE. The PML4E remains invisible to the common
-	code.
-
-	The kernel uses all the first 47 bits of the negative half
-	of the virtual address space to build the direct mapping using
-	2 Mbytes page size. The kernel virtual	addresses have bit number
-	47 always set to 1 (and in turn also bits 48-63 are set to 1 too,
-	due the sign extension). This is where the 128 Terabytes - 2 Gigabytes global
-	limit of RAM cames from.
-
-	Since the per-process limit is 512 Gigabytes (due to kernel common
-	code 3 level pagetable limitation), the higher virtual address mapped
-	into userspace is 0x7fffffffff and it makes sense to use it
-	as the top of the userspace stack to allow the stack to grow as
-	much as possible.
-
-	Setting the PAGE_OFFSET to 2^39 (after the last userspace
-	virtual address) wouldn't make much difference compared to
-	setting PAGE_OFFSET to 0xffff800000000000 because we have an
-	hole into the virtual address space. The last byte mapped by the
-	255th slot in the 4th level pagetable is at virtual address
-	0x00007fffffffffff and the first byte mapped by the 256th slot in the
-	4th level pagetable is at address 0xffff800000000000. Due to this
-	hole we can't trivially build a direct mapping across all the
-	512 slots of the 4th level pagetable, so we simply use only the
-	second (negative) half of the 4th level pagetable for that purpose
-	(that provides us 128 Terabytes of contigous virtual addresses).
-	Strictly speaking we could build a direct mapping also across the hole
-	using some DISCONTIGMEM trick, but we don't need such a large
-	direct mapping right now.
-
-Future:
-
-	During 2.5.x we can break the 512 Gigabytes per-process limit
-	possibly by removing from the common code any knowledge about the
-	architectural dependent physical layout of the virtual to physical
-	mapping.
-
-	Once the 512 Gigabytes limit will be removed the kernel stack will
-	be moved (most probably to virtual address 0x00007fffffffffff).
-	Nothing	will break in userspace due that move, as nothing breaks
-	in IA32 compiling the kernel with CONFIG_2G.
-
-Linus agreed on not breaking common code and to live with the 512 Gigabytes
-per-process limitation for the 2.4.x timeframe and he has given me and Andi
-some very useful hints... (thanks! :)
-
-Thanks also to H. Peter Anvin for his interesting and useful suggestions on
-the x86-64-discuss lists!
-
-Other memory management related issues follows:
-
-PAGE_SIZE:
-
-	If somebody is wondering why these days we still have a so small
-	4k pagesize (16 or 32 kbytes would be much better for performance
-	of course), the PAGE_SIZE have to remain 4k for 32bit apps to
-	provide 100% backwards compatible IA32 API (we can't allow silent
-	fs corruption or as best a loss of coherency with the page cache
-	by allocating MAP_SHARED areas in MAP_ANONYMOUS memory with a
-	do_mmap_fake). I think it could be possible to have a dynamic page
-	size between 32bit and 64bit apps but it would need extremely
-	intrusive changes in the common code as first for page cache and
-	we sure don't want to depend on them right now even if the
-	hardware would support that.
-
-PAGETABLE SIZE:
-
-	In turn we can't afford to have pagetables larger than 4k because
-	we could not be able to allocate them due physical memory
-	fragmentation, and failing to allocate the kernel stack is a minor
-	issue compared to failing the allocation of a pagetable. If we
-	fail the allocation of a pagetable the only thing we can do is to
-	sched_yield polling the freelist (deadlock prone) or to segfault
-	the task (not even the sighandler would be sure to run).
-
-KERNEL STACK:
-
-	1st stage:
-
-	The kernel stack will be at first allocated with an order 2 allocation
-	(16k) (the utilization of the stack for a 64bit platform really
-	isn't exactly the double of a 32bit platform because the local
-	variables may not be all 64bit wide, but not much less). This will
-	make things even worse than they are right now on IA32 with
-	respect of failing fork/clone due memory fragmentation.
-
-	2nd stage:
-
-	We'll benchmark if reserving one register as task_struct
-	pointer will improve performance of the kernel (instead of
-	recalculating the task_struct pointer starting from the stack
-	pointer each time). My guess is that recalculating will be faster
-	but it worth a try.
-
-		If reserving one register for the task_struct pointer
-		will be faster we can as well split task_struct and kernel
-		stack. task_struct can be a slab allocation or a
-		PAGE_SIZEd allocation, and the kernel stack can then be
-		allocated in a order 1 allocation. Really this is risky,
-		since 8k on a 64bit platform is going to be less than 7k
-		on a 32bit platform but we could try it out. This would
-		reduce the fragmentation problem of an order of magnitude
-		making it equal to the current IA32.
-
-		We must also consider the x86-64 seems to provide in hardware a
-		per-irq stack that could allow us to remove the irq handler
-		footprint from the regular per-process-stack, so it could allow
-		us to live with a smaller kernel stack compared to the other
-		linux architectures.
-
-	3rd stage:
-
-	Before going into production if we still have the order 2
-	allocation we can add a sysctl that allows the kernel stack to be
-	allocated with vmalloc during memory fragmentation. This have to
-	remain turned off during benchmarks :) but it should be ok in real
-	life.
-
-Order of PAGE_CACHE_SIZE and other allocations:
-
-	On the long run we can increase the PAGE_CACHE_SIZE to be
-	an order 2 allocations and also the slab/buffercache etc.ec..
-	could be all done with order 2 allocations. To make the above
-	to work we should change lots of common code thus it can be done
-	only once the basic port will be in a production state. Having
-	a working PAGE_CACHE_SIZE would be a benefit also for
-	IA32 and other architectures of course.
+<previous description obsolete, deleted>
 
-Andrea <andrea@suse.de> SuSE
+Virtual memory map with 4 level page tables:
+
+0000000000000000 - 00007fffffffffff (=47bits) user space, different per mm
+hole caused by [48:63] sign extension
+ffff800000000000 - ffff80ffffffffff (=40bits) guard hole
+ffff810000000000 - ffffc0ffffffffff (=46bits) direct mapping of phys. memory
+ffffc10000000000 - ffffc1ffffffffff (=40bits) hole
+ffffc20000000000 - ffffe1ffffffffff (=45bits) vmalloc/ioremap space
+... unused hole ...
+ffffffff80000000 - ffffffff82800000 (=40MB)   kernel text mapping, from phys 0
+... unused hole ...
+ffffffff88000000 - fffffffffff00000 (=1919MB) module mapping space
+
+vmalloc space is lazily synchronized into the different PML4 pages of
+the processes using the page fault handler, with init_level4_pgt as
+reference.
+
+Current X86-64 implementations only support 40 bit of address space,
+but we support upto 46bits. This expands into MBZ space in the page tables.
+
+-Andi Kleen, Jul 2004
diff -Nru a/MAINTAINERS b/MAINTAINERS
--- a/MAINTAINERS	2005-03-01 23:38:58 -08:00
+++ b/MAINTAINERS	2005-03-01 23:38:58 -08:00
@@ -283,8 +283,13 @@
 S:	Maintained
 
 ARM MFM AND FLOPPY DRIVERS
-P:	Dave Gilbert
-M:	linux@treblig.org
+P:	Ian Molton
+M:	spyro@f2s.com
+S:	Maintained
+
+ARM/CORGI MACHINE SUPPORT
+P:	Richard Purdie
+M:	rpurdie@rpsys.net
 S:	Maintained
 
 ARM/PLEB SUPPORT
@@ -313,6 +318,20 @@
 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
+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
+W:	http://www.fluff.org/ben/linux/
+S:	Maintained
+
 ARPD SUPPORT
 P:	Jonathan Layes
 L:	linux-net@vger.kernel.org
@@ -328,6 +347,12 @@
 W:	http://julien.lerouge.free.fr
 S:	Maintained
 
+ATA OVER ETHERNET DRIVER
+P:	Ed L. Cashin
+M:	ecashin@coraid.com
+W:	http://www.coraid.com/support/linux
+S:	Supported
+
 ATM
 P:	Chas Williams
 M:	chas@cmf.nrl.navy.mil
@@ -550,7 +575,7 @@
 CPU FREQUENCY DRIVERS
 P:	Dave Jones
 M:	davej@codemonkey.org.uk
-L:	cpufreq@www.linux.org.uk
+L:	cpufreq@lists.linux.org.uk
 W:	http://www.codemonkey.org.uk/projects/cpufreq/
 S:	Maintained
 
@@ -705,8 +730,8 @@
 S:	Maintained
 
 DISKQUOTA:
-P:	Marco van Wieringen
-M:	mvw@planets.elm.net
+P:	Jan Kara
+M:	jack@suse.cz
 L:	linux-kernel@vger.kernel.org
 S:	Maintained
 
@@ -724,7 +749,7 @@
 
 DRIVER CORE, KOBJECTS, AND SYSFS
 P:	Greg Kroah-Hartman
-M:	greg@kroah.com
+M:	gregkh@suse.de
 L:	linux-kernel@vger.kernel.org
 S:	Supported
 
@@ -862,6 +887,11 @@
 W:	ftp://ftp.openlinux.org/pub/people/hch/vxfs
 S:	Maintained
 
+FUJITSU FR-V PORT
+P:	David Howells
+M:	dhowells@redhat.com
+S:	Maintained
+
 FTAPE/QIC-117
 L:	linux-tape@vger.kernel.org
 W:	http://sourceforge.net/projects/ftape
@@ -953,6 +983,11 @@
 M:	oliver@neukum.name
 S:	Maintained
 
+HUGETLB FILESYSTEM
+P:	William Irwin
+M:	wli@holomorphy.com
+S:	Maintained
+
 I2C AND SENSORS DRIVERS
 P:	Greg Kroah-Hartman
 M:	greg@kroah.com
@@ -988,8 +1023,8 @@
 S:	Maintained
 
 IA64 (Itanium) PLATFORM
-P:	David Mosberger-Tang
-M:	davidm@hpl.hp.com
+P:	Tony Luck
+M:	tony.luck@intel.com
 L:	linux-ia64@vger.kernel.org
 W:	http://www.ia64-linux.org/
 S:	Maintained
@@ -1081,6 +1116,17 @@
 L:	linux-fbdev-devel@lists.sourceforge.net
 S:	Maintained
 
+INFINIBAND SUBSYSTEM
+P:	Roland Dreier
+M:	roland@topspin.com
+P:	Sean Hefty
+M:	mshefty@ichips.intel.com
+P:	Hal Rosenstock
+M:	halr@voltaire.com
+L:	openib-general@openib.org
+W:	http://www.openib.org/
+S:	Supported
+
 INPUT (KEYBOARD, MOUSE, JOYSTICK) DRIVERS
 P:	Vojtech Pavlik
 M:	vojtech@suse.cz
@@ -1140,13 +1186,6 @@
 W:	http://sourceforge.net/projects/e1000/
 S:	Supported
 
-INTERMEZZO FILE SYSTEM
-P:	Cluster File Systems	
-M:	intermezzo-devel@lists.sf.net
-W:	http://www.inter-mezzo.org/
-L:	intermezzo-discuss@lists.sourceforge.net
-S:	Maintained
-
 IOC3 DRIVER
 P:	Ralf Baechle
 M:	ralf@linux-mips.org
@@ -1439,7 +1478,7 @@
 
 MEMORY TECHNOLOGY DEVICES
 P:	David Woodhouse
-M:	dwmw2@redhat.com
+M:	dwmw2@infradead.org
 W:	http://www.linux-mtd.infradead.org/
 L:	linux-mtd@lists.infradead.org
 S:	Maintained
@@ -1568,7 +1607,6 @@
 M:	wensong@linux-vs.org
 P:	Julian Anastasov
 M:	ja@ssi.bg
-L:	lvs-users@linuxvirtualserver.org
 S:	Maintained
 
 NFS CLIENT
@@ -1706,14 +1744,14 @@
 
 PCI SUBSYSTEM
 P:	Greg Kroah-Hartman
-M:	greg@kroah.com
+M:	gregkh@suse.de
 L:	linux-kernel@vger.kernel.org
+L:	linux-pci@atrey.karlin.mff.cuni.cz
 S:	Supported
 
 PCI HOTPLUG CORE
 P:	Greg Kroah-Hartman
-M:	greg@kroah.com
-M:	gregkh@us.ibm.com
+M:	gregkh@suse.de
 S:	Supported
 
 PCI HOTPLUG COMPAQ DRIVER
@@ -1761,7 +1799,7 @@
 
 PPP OVER ETHERNET
 P:	Michal Ostrowski
-M:	mostrows@styx.uwaterloo.ca
+M:	mostrows@speakeasy.net
 S:	Maintained
 
 PREEMPTIBLE KERNEL
@@ -1791,6 +1829,12 @@
 L:	linux-arm-kernel@lists.arm.linux.org.uk
 S:	Maintained
 
+QLOGIC QLA2XXX FC-SCSI DRIVER
+P:	Andrew Vasquez
+M:	andrew.vasquez@qlogic.com
+L:	linux-scsi@vger.kernel.org
+S:	Supported
+
 QNX4 FILESYSTEM
 P:	Anders Larsen
 M:	al@alarsen.net
@@ -1842,9 +1886,7 @@
 S:	Maintained
 
 RISCOM8 DRIVER
-P:	Dmitry Gorodchanin
-L:	linux-kernel@vger.kernel.org
-S:	Maintained
+S:	Orphan
 
 RTLINUX  REALTIME  LINUX
 P:	Victor Yodaiken
@@ -1953,6 +1995,20 @@
 W:	http://linux-visws.sf.net
 S:	Maintained for 2.6.
 
+SIMTEC EB110ATX (Chalice CATS)
+P:	Ben Dooks
+P:	Vincent Sanders
+M:	support@simtec.co.uk
+W:	http://www.simtec.co.uk/products/EB110ATX/
+S:	Supported
+
+SIMTEC EB2410ITX (BAST)
+P:	Ben Dooks
+P:	Vincent Sanders
+M:	support@simtec.co.uk
+W:	http://www.simtec.co.uk/products/EB2410ITX/
+S:	Supported
+
 SIS 5513 IDE CONTROLLER DRIVER
 P:	Lionel Bouton
 M:	Lionel.Bouton@inet6.fr
@@ -2044,6 +2100,13 @@
 L:	ultralinux@vger.kernel.org
 S:	Maintained
 
+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
+S:	Maintained
+
 SPARC (sparc32):
 P:	William L. Irwin
 M:	wli@holomorphy.com
@@ -2053,7 +2116,6 @@
 SPECIALIX IO8+ MULTIPORT SERIAL CARD DRIVER
 P:	Roger Wolff
 M:	R.E.Wolff@BitWizard.nl
-M:	io8-linux@specialix.co.uk
 L:	linux-kernel@vger.kernel.org ?
 S:	Supported
 
@@ -2123,13 +2185,6 @@
 M:	hch@infradead.org
 S:	Maintained
 
-TI GRAPH LINK USB (SilverLink) CABLE DRIVER
-P:	Romain Lievin
-M:	roms@lpg.ticalc.org
-P:	Julien Blache
-M:	jb@technologeek.org
-S:	Maintained
-
 TI PARALLEL LINK CABLE DRIVER
 P:     Romain Lievin
 M:     roms@lpg.ticalc.org
@@ -2210,13 +2265,6 @@
 W:	http://linux-udf.sourceforge.net
 S:	Maintained
 
-UMSDOS FILESYSTEM
-P:	Matija Nalis
-M:	Matija Nalis <mnalis-umsdos@voyager.hr>
-L:	linux-kernel@vger.kernel.org
-W:	http://linux.voyager.hr/umsdos/
-S:	Maintained
-
 UNIFORM CDROM DRIVER
 P:	Jens Axboe
 M:	axboe@suse.de
@@ -2338,11 +2386,10 @@
 
 USB SERIAL DRIVER
 P:	Greg Kroah-Hartman
-M:	greg@kroah.com
+M:	gregkh@suse.de
 L:	linux-usb-users@lists.sourceforge.net
 L:	linux-usb-devel@lists.sourceforge.net
-S:	Maintained
-W:	http://www.kroah.com/linux-usb/
+S:	Supported
 
 USB SERIAL BELKIN F5U103 DRIVER
 P:	William Greathouse
@@ -2404,7 +2451,7 @@
 
 USB SUBSYSTEM
 P:	Greg Kroah-Hartman
-M:	greg@kroah.com
+M:	gregkh@suse.de
 L:	linux-usb-users@lists.sourceforge.net
 L:	linux-usb-devel@lists.sourceforge.net
 W:	http://www.linux-usb.org
diff -Nru a/Makefile b/Makefile
--- a/Makefile	2005-03-01 23:39:07 -08:00
+++ b/Makefile	2005-03-01 23:39:07 -08:00
@@ -1,6 +1,6 @@
 VERSION = 2
 PATCHLEVEL = 6
-SUBLEVEL = 10
+SUBLEVEL = 11
 EXTRAVERSION =
 NAME=Woozy Numbat
 
@@ -149,14 +149,13 @@
 # careful not to include files twice if building in the source
 # directory. LOCALVERSION from the command line override all of this
 
-ifeq ($(objtree),$(srctree))
-localversion-files := $(wildcard $(srctree)/localversion*)
-else
-localversion-files := $(wildcard $(objtree)/localversion* $(srctree)/localversion*)
-endif
+localver := $(objtree)/localversion* $(srctree)/localversion*
+localver := $(sort $(wildcard $(localver)))
+# skip backup files (containing '~')
+localver := $(foreach f, $(localver), $(if $(findstring ~, $(f)),,$(f)))
 
 LOCALVERSION = $(subst $(space),, \
-	       $(shell cat /dev/null $(localversion-files:%~=)) \
+	       $(shell cat /dev/null $(localver)) \
 	       $(patsubst "%",%,$(CONFIG_LOCALVERSION)))
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)$(LOCALVERSION)
@@ -291,7 +290,7 @@
             $(call cc-option, $(1),$(2))
 
 # cc-option-yn
-# Usage: flag := $(call gcc-option-yn, -march=winchip-c6)
+# Usage: flag := $(call cc-option-yn, -march=winchip-c6)
 cc-option-yn = $(shell if $(CC) $(CFLAGS) $(1) -S -o /dev/null -xc /dev/null \
                 > /dev/null 2>&1; then echo "y"; else echo "n"; fi;)
 
@@ -331,7 +330,10 @@
 KALLSYMS	= scripts/kallsyms
 PERL		= perl
 CHECK		= sparse
+
+NOSTDINC_FLAGS  = -nostdinc -isystem $(shell $(CC) -print-file-name=include)
 CHECKFLAGS     := -D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__
+CHECKFLAGS     += $(NOSTDINC_FLAGS)
 MODFLAGS	= -DMODULE
 CFLAGS_MODULE   = $(MODFLAGS)
 AFLAGS_MODULE   = $(MODFLAGS)
@@ -339,7 +341,6 @@
 CFLAGS_KERNEL	=
 AFLAGS_KERNEL	=
 
-NOSTDINC_FLAGS  = -nostdinc -iwithprefix include
 
 # Use LINUXINCLUDE when you must reference the include/ directory.
 # Needed to be compatible with the O= option
@@ -349,7 +350,8 @@
 CPPFLAGS        := -D__KERNEL__ $(LINUXINCLUDE)
 
 CFLAGS 		:= -Wall -Wstrict-prototypes -Wno-trigraphs \
-	  	   -fno-strict-aliasing -fno-common
+	  	   -fno-strict-aliasing -fno-common \
+		   -ffreestanding
 AFLAGS		:= -D__ASSEMBLY__
 
 export	VERSION PATCHLEVEL SUBLEVEL EXTRAVERSION LOCALVERSION KERNELRELEASE \
@@ -389,7 +391,7 @@
 # using a seperate output directory. This allows convinient use
 # of make in output directory
 outputmakefile:
-	$(Q)if /usr/bin/env test ! $(srctree) -ef $(objtree); then \
+	$(Q)if test ! $(srctree) -ef $(objtree); then \
 	$(CONFIG_SHELL) $(srctree)/scripts/mkmakefile              \
 	    $(srctree) $(objtree) $(VERSION) $(PATCHLEVEL)         \
 	    > $(objtree)/Makefile;                                 \
@@ -531,6 +533,9 @@
 # warn about C99 declaration after statement
 CFLAGS += $(call cc-option,-Wdeclaration-after-statement,)
 
+# disable pointer signedness warnings in gcc 4.0
+CFLAGS += $(call cc-option,-Wno-pointer-sign,)
+
 # Default kernel image to build when no specific target is given.
 # KBUILD_IMAGE may be overruled on the commandline or
 # set in the environment
@@ -1166,7 +1171,7 @@
 quiet_cmd_tags = MAKE   $@
 define cmd_tags
 	rm -f $@; \
-	CTAGSF=`ctags --version | grep -i exuberant >/dev/null && echo "-I __initdata,__exitdata,EXPORT_SYMBOL,EXPORT_SYMBOL_NOVERS"`; \
+	CTAGSF=`ctags --version | grep -i exuberant >/dev/null && echo "-I __initdata,__exitdata,EXPORT_SYMBOL,EXPORT_SYMBOL_GPL"`; \
 	$(all-sources) | xargs ctags $$CTAGSF -a
 endef
 
@@ -1209,6 +1214,9 @@
 checkstack:
 	$(OBJDUMP) -d vmlinux $$(find . -name '*.ko') | \
 	$(PERL) $(src)/scripts/checkstack.pl $(ARCH)
+
+kernelrelease:
+	@echo $(KERNELRELEASE)
 
 # FIXME Should go into a make.lib or something 
 # ===========================================================================
diff -Nru a/arch/alpha/Kconfig b/arch/alpha/Kconfig
--- a/arch/alpha/Kconfig	2005-03-01 23:39:18 -08:00
+++ b/arch/alpha/Kconfig	2005-03-01 23:39:18 -08:00
@@ -28,6 +28,10 @@
 	bool
 	default y
 
+config GENERIC_CALIBRATE_DELAY
+	bool
+	default y
+
 config GENERIC_ISA_DMA
 	bool
 	default y
@@ -485,7 +489,7 @@
 	  singleprocessor machines. On a singleprocessor machine, the kernel
 	  will run faster if you say N here.
 
-	  See also the <file:Documentation/smp.tex>, and the SMP-HOWTO
+	  See also the <file:Documentation/smp.txt>, and the SMP-HOWTO
 	  available at <http://www.tldp.org/docs.html#howto>.
 
 	  If you don't know what to do here, say N.
diff -Nru a/arch/alpha/defconfig b/arch/alpha/defconfig
--- a/arch/alpha/defconfig	2005-03-01 23:38:57 -08:00
+++ b/arch/alpha/defconfig	2005-03-01 23:38:57 -08:00
@@ -411,7 +411,6 @@
 # CONFIG_IP_NF_TARGET_REDIRECT is not set
 # CONFIG_IP_NF_TARGET_NETMAP is not set
 # CONFIG_IP_NF_TARGET_SAME is not set
-# CONFIG_IP_NF_NAT_LOCAL is not set
 # CONFIG_IP_NF_NAT_SNMP_BASIC is not set
 CONFIG_IP_NF_NAT_IRC=m
 CONFIG_IP_NF_NAT_FTP=m
diff -Nru a/arch/alpha/kernel/core_marvel.c b/arch/alpha/kernel/core_marvel.c
--- a/arch/alpha/kernel/core_marvel.c	2005-03-01 23:38:52 -08:00
+++ b/arch/alpha/kernel/core_marvel.c	2005-03-01 23:38:52 -08:00
@@ -118,7 +118,7 @@
 
 	io7 = alloc_bootmem(sizeof(*io7));
 	io7->pe = pe;
-	io7->irq_lock = SPIN_LOCK_UNLOCKED;
+	spin_lock_init(&io7->irq_lock);
 
 	for (h = 0; h < 4; h++) {
 		io7->ports[h].io7 = io7;
diff -Nru a/arch/alpha/kernel/irq_i8259.c b/arch/alpha/kernel/irq_i8259.c
--- a/arch/alpha/kernel/irq_i8259.c	2005-03-01 23:39:09 -08:00
+++ b/arch/alpha/kernel/irq_i8259.c	2005-03-01 23:39:09 -08:00
@@ -22,7 +22,7 @@
 
 /* Note mask bit is true for DISABLED irqs.  */
 static unsigned int cached_irq_mask = 0xffff;
-static spinlock_t i8259_irq_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(i8259_irq_lock);
 
 static inline void
 i8259_update_irq_hw(unsigned int irq, unsigned long mask)
diff -Nru a/arch/alpha/kernel/irq_srm.c b/arch/alpha/kernel/irq_srm.c
--- a/arch/alpha/kernel/irq_srm.c	2005-03-01 23:39:09 -08:00
+++ b/arch/alpha/kernel/irq_srm.c	2005-03-01 23:39:09 -08:00
@@ -15,7 +15,7 @@
  * at the same time in multiple CPUs? To be safe I added a spinlock
  * but it can be removed trivially if the palcode is robust against smp.
  */
-spinlock_t srm_irq_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(srm_irq_lock);
 
 static inline void
 srm_enable_irq(unsigned int irq)
diff -Nru a/arch/alpha/kernel/proto.h b/arch/alpha/kernel/proto.h
--- a/arch/alpha/kernel/proto.h	2005-03-01 23:38:53 -08:00
+++ b/arch/alpha/kernel/proto.h	2005-03-01 23:38:53 -08:00
@@ -167,9 +167,6 @@
 extern void entUna(void);
 extern void entDbg(void);
 
-/* process.c */
-extern void cpu_idle(void) __attribute__((noreturn));
-
 /* ptrace.c */
 extern int ptrace_set_bpt (struct task_struct *child);
 extern int ptrace_cancel_bpt (struct task_struct *child);
diff -Nru a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c
--- a/arch/alpha/kernel/setup.c	2005-03-01 23:38:53 -08:00
+++ b/arch/alpha/kernel/setup.c	2005-03-01 23:38:53 -08:00
@@ -213,14 +213,14 @@
 reserve_std_resources(void)
 {
 	static struct resource standard_io_resources[] = {
-		{ "rtc", -1, -1 },
-        	{ "dma1", 0x00, 0x1f },
-        	{ "pic1", 0x20, 0x3f },
-        	{ "timer", 0x40, 0x5f },
-        	{ "keyboard", 0x60, 0x6f },
-        	{ "dma page reg", 0x80, 0x8f },
-        	{ "pic2", 0xa0, 0xbf },
-        	{ "dma2", 0xc0, 0xdf },
+		{ .name = "rtc", .start = -1, .end = -1 },
+        	{ .name = "dma1", .start = 0x00, .end = 0x1f },
+        	{ .name = "pic1", .start = 0x20, .end = 0x3f },
+        	{ .name = "timer", .start = 0x40, .end = 0x5f },
+        	{ .name = "keyboard", .start = 0x60, .end = 0x6f },
+        	{ .name = "dma page reg", .start = 0x80, .end = 0x8f },
+        	{ .name = "pic2", .start = 0xa0, .end = 0xbf },
+        	{ .name = "dma2", .start = 0xc0, .end = 0xdf },
 	};
 
 	struct resource *io = &ioport_resource;
diff -Nru a/arch/alpha/kernel/smc37c669.c b/arch/alpha/kernel/smc37c669.c
--- a/arch/alpha/kernel/smc37c669.c	2005-03-01 23:39:07 -08:00
+++ b/arch/alpha/kernel/smc37c669.c	2005-03-01 23:39:07 -08:00
@@ -1104,7 +1104,7 @@
     int drq 
 );
 
-static spinlock_t smc_lock __cacheline_aligned = SPIN_LOCK_UNLOCKED;
+static  __cacheline_aligned DEFINE_SPINLOCK(smc_lock);
 
 /*
 **++
diff -Nru a/arch/alpha/kernel/srmcons.c b/arch/alpha/kernel/srmcons.c
--- a/arch/alpha/kernel/srmcons.c	2005-03-01 23:39:16 -08:00
+++ b/arch/alpha/kernel/srmcons.c	2005-03-01 23:39:16 -08:00
@@ -22,7 +22,7 @@
 #include <asm/uaccess.h>
 
 
-static spinlock_t srmcons_callback_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(srmcons_callback_lock);
 static int srm_is_registered_console = 0;
 
 /* 
@@ -160,7 +160,7 @@
 srmcons_get_private_struct(struct srmcons_private **ps)
 {
 	static struct srmcons_private *srmconsp = NULL;
-	static spinlock_t srmconsp_lock = SPIN_LOCK_UNLOCKED;
+	static DEFINE_SPINLOCK(srmconsp_lock);
 	unsigned long flags;
 	int retval = 0;
 
@@ -179,7 +179,7 @@
 		}
 
 		srmconsp->tty = NULL;
-		srmconsp->lock = SPIN_LOCK_UNLOCKED;
+		spin_lock_init(&srmconsp->lock);
 		init_timer(&srmconsp->timer);
 
 		*ps = srmconsp;
diff -Nru a/arch/alpha/kernel/sys_dp264.c b/arch/alpha/kernel/sys_dp264.c
--- a/arch/alpha/kernel/sys_dp264.c	2005-03-01 23:38:53 -08:00
+++ b/arch/alpha/kernel/sys_dp264.c	2005-03-01 23:38:53 -08:00
@@ -43,7 +43,7 @@
 /* dp264 boards handle at max four CPUs */
 static unsigned long cpu_irq_affinity[4] = { 0UL, 0UL, 0UL, 0UL };
 
-spinlock_t dp264_irq_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(dp264_irq_lock);
 
 static void
 tsunami_update_irq_hw(unsigned long mask)
diff -Nru a/arch/alpha/kernel/sys_rawhide.c b/arch/alpha/kernel/sys_rawhide.c
--- a/arch/alpha/kernel/sys_rawhide.c	2005-03-01 23:39:16 -08:00
+++ b/arch/alpha/kernel/sys_rawhide.c	2005-03-01 23:39:16 -08:00
@@ -42,7 +42,7 @@
 	0xff0000, 0xfe0000, 0xff0000, 0xff0000
 };
 static unsigned int cached_irq_masks[4];
-spinlock_t rawhide_irq_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(rawhide_irq_lock);
 
 static inline void
 rawhide_update_irq_hw(int hose, int mask)
diff -Nru a/arch/alpha/kernel/sys_sable.c b/arch/alpha/kernel/sys_sable.c
--- a/arch/alpha/kernel/sys_sable.c	2005-03-01 23:38:52 -08:00
+++ b/arch/alpha/kernel/sys_sable.c	2005-03-01 23:38:52 -08:00
@@ -31,7 +31,7 @@
 #include "pci_impl.h"
 #include "machvec_impl.h"
 
-spinlock_t sable_lynx_irq_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(sable_lynx_irq_lock);
 
 typedef struct irq_swizzle_struct
 {
diff -Nru a/arch/alpha/kernel/sys_titan.c b/arch/alpha/kernel/sys_titan.c
--- a/arch/alpha/kernel/sys_titan.c	2005-03-01 23:39:16 -08:00
+++ b/arch/alpha/kernel/sys_titan.c	2005-03-01 23:39:16 -08:00
@@ -56,7 +56,7 @@
 /*
  * Need SMP-safe access to interrupt CSRs
  */
-spinlock_t titan_irq_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(titan_irq_lock);
 
 static void
 titan_update_irq_hw(unsigned long mask)
diff -Nru a/arch/alpha/kernel/sys_wildfire.c b/arch/alpha/kernel/sys_wildfire.c
--- a/arch/alpha/kernel/sys_wildfire.c	2005-03-01 23:38:56 -08:00
+++ b/arch/alpha/kernel/sys_wildfire.c	2005-03-01 23:38:56 -08:00
@@ -32,7 +32,7 @@
 
 static unsigned long cached_irq_mask[WILDFIRE_NR_IRQS/(sizeof(long)*8)];
 
-spinlock_t wildfire_irq_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(wildfire_irq_lock);
 
 static int doing_init_irq_hw = 0;
 
diff -Nru a/arch/alpha/kernel/time.c b/arch/alpha/kernel/time.c
--- a/arch/alpha/kernel/time.c	2005-03-01 23:38:57 -08:00
+++ b/arch/alpha/kernel/time.c	2005-03-01 23:38:57 -08:00
@@ -63,7 +63,7 @@
 
 static int set_rtc_mmss(unsigned long);
 
-spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(rtc_lock);
 
 #define TICK_SIZE (tick_nsec / 1000)
 
diff -Nru a/arch/alpha/lib/memmove.S b/arch/alpha/lib/memmove.S
--- a/arch/alpha/lib/memmove.S	2005-03-01 23:38:57 -08:00
+++ b/arch/alpha/lib/memmove.S	2005-03-01 23:38:57 -08:00
@@ -12,18 +12,6 @@
 	.text
 
 	.align 4
-	.globl bcopy
-	.ent bcopy
-bcopy:
-	ldgp $29, 0($27)
-	.prologue 1
-	mov $16,$0
-	mov $17,$16
-	mov $0,$17
-	br  $31, memmove	!samegp
-	.end bcopy
-
-	.align 4
 	.globl memmove
 	.ent memmove
 memmove:
diff -Nru a/arch/alpha/mm/init.c b/arch/alpha/mm/init.c
--- a/arch/alpha/mm/init.c	2005-03-01 23:39:16 -08:00
+++ b/arch/alpha/mm/init.c	2005-03-01 23:39:16 -08:00
@@ -42,10 +42,9 @@
 {
 	pgd_t *ret, *init;
 
-	ret = (pgd_t *)__get_free_page(GFP_KERNEL);
+	ret = (pgd_t *)__get_free_page(GFP_KERNEL | __GFP_ZERO);
 	init = pgd_offset(&init_mm, 0UL);
 	if (ret) {
-		clear_page(ret);
 #ifdef CONFIG_ALPHA_LARGE_VMALLOC
 		memcpy (ret + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD,
 			(PTRS_PER_PGD - USER_PTRS_PER_PGD - 1)*sizeof(pgd_t));
@@ -63,9 +62,7 @@
 pte_t *
 pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
 {
-	pte_t *pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT);
-	if (pte)
-		clear_page(pte);
+	pte_t *pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO);
 	return pte;
 }
 
diff -Nru a/arch/alpha/mm/numa.c b/arch/alpha/mm/numa.c
--- a/arch/alpha/mm/numa.c	2005-03-01 23:38:51 -08:00
+++ b/arch/alpha/mm/numa.c	2005-03-01 23:38:51 -08:00
@@ -246,7 +246,7 @@
 	reserve_bootmem_node(NODE_DATA(nid), PFN_PHYS(bootmap_start), bootmap_size);
 	printk(" reserving pages %ld:%ld\n", bootmap_start, bootmap_start+PFN_UP(bootmap_size));
 
-	numnodes++;
+	node_set_online(nid);
 }
 
 void __init
@@ -256,7 +256,7 @@
 
 	show_mem_layout();
 
-	numnodes = 0;
+	nodes_clear(node_online_map);
 
 	min_low_pfn = ~0UL;
 	max_low_pfn = 0UL;
@@ -303,7 +303,7 @@
 	 */
 	dma_local_pfn = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
 
-	for (nid = 0; nid < numnodes; nid++) {
+	for_each_online_node(nid) {
 		unsigned long start_pfn = node_bdata[nid].node_boot_start >> PAGE_SHIFT;
 		unsigned long end_pfn = node_bdata[nid].node_low_pfn;
 
@@ -332,7 +332,7 @@
 	high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT);
 
 	reservedpages = 0;
-	for (nid = 0; nid < numnodes; nid++) {
+	for_each_online_node(nid) {
 		/*
 		 * This will free up the bootmem, ie, slot 0 memory
 		 */
@@ -372,7 +372,7 @@
 	printk("\nMem-info:\n");
 	show_free_areas();
 	printk("Free swap:       %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
-	for (nid = 0; nid < numnodes; nid++) {
+	for_each_online_node(nid) {
 		struct page * lmem_map = node_mem_map(nid);
 		i = node_spanned_pages(nid);
 		while (i-- > 0) {
diff -Nru a/arch/alpha/oprofile/common.c b/arch/alpha/oprofile/common.c
--- a/arch/alpha/oprofile/common.c	2005-03-01 23:38:52 -08:00
+++ b/arch/alpha/oprofile/common.c	2005-03-01 23:38:52 -08:00
@@ -138,17 +138,8 @@
 	return 0;
 }
 
-static struct oprofile_operations oprof_axp_ops = {
-	.create_files	= op_axp_create_files,
-	.setup		= op_axp_setup,
-	.shutdown	= op_axp_shutdown,
-	.start		= op_axp_start,
-	.stop		= op_axp_stop,
-	.cpu_type	= NULL		/* To be filled in below.  */
-};
-
 int __init
-oprofile_arch_init(struct oprofile_operations **ops)
+oprofile_arch_init(struct oprofile_operations *ops)
 {
 	struct op_axp_model *lmodel = NULL;
 
@@ -178,8 +169,12 @@
 		return -ENODEV;
 	model = lmodel;
 
-	oprof_axp_ops.cpu_type = lmodel->cpu_type;
-	*ops = &oprof_axp_ops;
+	ops->create_files = op_axp_create_files;
+	ops->setup = op_axp_setup;
+	ops->shutdown = op_axp_shutdown;
+	ops->start = op_axp_start;
+	ops->stop = op_axp_stop;
+	ops->cpu_type = lmodel->cpu_type;
 
 	printk(KERN_INFO "oprofile: using %s performance monitoring.\n",
 	       lmodel->cpu_type);
diff -Nru a/arch/alpha/oprofile/op_model_ev4.c b/arch/alpha/oprofile/op_model_ev4.c
--- a/arch/alpha/oprofile/op_model_ev4.c	2005-03-01 23:38:56 -08:00
+++ b/arch/alpha/oprofile/op_model_ev4.c	2005-03-01 23:38:56 -08:00
@@ -101,8 +101,7 @@
 		return;
 
 	/* Record the sample.  */
-	oprofile_add_sample(regs->pc, !user_mode(regs),
-			    which, smp_processor_id());
+	oprofile_add_sample(regs, which);
 }
 
 
diff -Nru a/arch/alpha/oprofile/op_model_ev5.c b/arch/alpha/oprofile/op_model_ev5.c
--- a/arch/alpha/oprofile/op_model_ev5.c	2005-03-01 23:38:56 -08:00
+++ b/arch/alpha/oprofile/op_model_ev5.c	2005-03-01 23:38:56 -08:00
@@ -186,8 +186,7 @@
 		     struct op_counter_config *ctr)
 {
 	/* Record the sample.  */
-	oprofile_add_sample(regs->pc, !user_mode(regs),
-			    which, smp_processor_id());
+	oprofile_add_sample(regs, which);
 }
 
 
diff -Nru a/arch/alpha/oprofile/op_model_ev6.c b/arch/alpha/oprofile/op_model_ev6.c
--- a/arch/alpha/oprofile/op_model_ev6.c	2005-03-01 23:38:58 -08:00
+++ b/arch/alpha/oprofile/op_model_ev6.c	2005-03-01 23:38:58 -08:00
@@ -88,8 +88,7 @@
 		     struct op_counter_config *ctr)
 {
 	/* Record the sample.  */
-	oprofile_add_sample(regs->pc, !user_mode(regs),
-			    which, smp_processor_id());
+	oprofile_add_sample(regs, which);
 }
 
 
diff -Nru a/arch/alpha/oprofile/op_model_ev67.c b/arch/alpha/oprofile/op_model_ev67.c
--- a/arch/alpha/oprofile/op_model_ev67.c	2005-03-01 23:39:17 -08:00
+++ b/arch/alpha/oprofile/op_model_ev67.c	2005-03-01 23:39:17 -08:00
@@ -138,8 +138,7 @@
 	if (counter == 1)
 		fake_counter += PM_NUM_COUNTERS;
 	if (ctr[fake_counter].enabled)
-		oprofile_add_sample(pc, kern, fake_counter,
-				    smp_processor_id());
+		oprofile_add_pc(pc, kern, fake_counter);
 }
 
 static void
@@ -197,8 +196,7 @@
 			   to PALcode. Recognize ITB miss by PALcode
 			   offset address, and get actual PC from
 			   EXC_ADDR.  */
-			oprofile_add_sample(regs->pc, kern, which,
-					    smp_processor_id());
+			oprofile_add_pc(regs->pc, kern, which);
 			if ((pmpc & ((1 << 15) - 1)) ==  581)
 				op_add_pm(regs->pc, kern, which,
 					  ctr, PM_ITB_MISS);
@@ -241,7 +239,7 @@
 		}
 	}
 
-	oprofile_add_sample(pmpc, kern, which, smp_processor_id());
+	oprofile_add_pc(pmpc, kern, which);
 
 	pctr_ctl = wrperfmon(5, 0);
 	if (pctr_ctl & (1UL << 27))
diff -Nru a/arch/arm/Kconfig b/arch/arm/Kconfig
--- a/arch/arm/Kconfig	2005-03-01 23:38:58 -08:00
+++ b/arch/arm/Kconfig	2005-03-01 23:38:58 -08:00
@@ -57,6 +57,10 @@
 config RWSEM_XCHGADD_ALGORITHM
 	bool
 
+config GENERIC_CALIBRATE_DELAY
+	bool
+	default y
+
 config GENERIC_BUST_SPINLOCK
 	bool
 
@@ -127,7 +131,7 @@
 	  <http://www.linkupsys.com/>
 
 	  If you have any questions or comments about the Linux kernel port
-	  to this board, send e-mail to sjhill@cotw.com.
+	  to this board, send e-mail to <sjhill@cotw.com>.
 
 config ARCH_PXA
 	bool "PXA2xx-based"
@@ -145,7 +149,7 @@
 	bool "Samsung S3C2410"
 	help
 	  Samsung S3C2410X CPU based systems, such as the Simtec Electronics
-	  BAST (http://www.simtec.co.uk/products/EB110ITX/), the IPAQ 1940 or
+	  BAST (<http://www.simtec.co.uk/products/EB110ITX/>), the IPAQ 1940 or
 	  the Samsung SMDK2410 development board (and derviatives).
 
 config ARCH_SHARK
@@ -230,6 +234,11 @@
 	depends on SA1100_COLLIE
 	default y
 
+config SHARP_SCOOP
+	bool
+	depends on PXA_SHARPSL || SA1100_COLLIE
+	default y
+
 config FORCE_MAX_ZONEORDER
 	int
 	depends on SA1111
@@ -253,6 +262,33 @@
 menu "General setup"
 
 # Select various configuration options depending on the machine type
+
+config SMP
+	bool "Symmetric Multi-Processing (EXPERIMENTAL)"
+	depends on EXPERIMENTAL && 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
+	  you have a system with more than one CPU, say Y.
+
+	  If you say N here, the kernel will run on single and multiprocessor
+	  machines, but will use only one CPU of a multiprocessor machine. If
+	  you say Y here, the kernel will run on many, but not all, single
+	  processor machines. On a single processor machine, the kernel will
+	  run faster if you say N here.
+
+	  See also the <file:Documentation/smp.tex>,
+	  <file:Documentation/smp.txt>, <file:Documentation/i386/IO-APIC.txt>,
+	  <file:Documentation/nmi_watchdog.txt> and the SMP-HOWTO available at
+	  <http://www.linuxdoc.org/docs.html#howto>.
+
+	  If you don't know what to do here, say N.
+
+config NR_CPUS
+	int "Maximum number of CPUs (2-32)"
+	depends on SMP
+	default "4"
+
 config DISCONTIGMEM
 	bool
 	depends on ARCH_EDB7211 || ARCH_SA1100 || (ARCH_LH7A40X && !LH7A40X_CONTIGMEM)
@@ -382,20 +418,6 @@
 	  be linked for and stored to.  This address is dependent on your
 	  own flash usage.
 
-	  Please note that, if you're using MTD, you must use a flash chip
-	  that is NOT handled by MTD or the flash will be turned into non
-	  data mode for status and query purposes which will instantaneously
-	  crash the kernel.
-
-	  MTD can however be used with a XIP kernel on the same flash chip
-	  but only if the flash memory supports multiple partitions in
-	  hardware, like with the Intel K3 flash parts, and only if the
-	  kernel is not stored within the firrst hardware partition of the
-	  chip.
-
-	  In any case, make sure that MTD support is configured out for
-	  the first attempt.
-
 if (ARCH_SA1100 || ARCH_INTEGRATOR)
 
 source "drivers/cpufreq/Kconfig"
@@ -609,7 +631,7 @@
 	  system, but the driver will do nothing.
 
 config LEDS_TIMER
-	bool "Timer LED" if LEDS && (ARCH_NETWINDER || ARCH_EBSA285 || ARCH_SHARK || MACH_MAINSTONE || ARCH_CO285 || ARCH_SA1100 || ARCH_LUBBOCK || ARCH_PXA_IDP || ARCH_INTEGRATOR || ARCH_P720T || ARCH_VERSATILE || ARCH_IMX)
+	bool "Timer LED" if LEDS && (ARCH_NETWINDER || ARCH_EBSA285 || ARCH_SHARK || MACH_MAINSTONE || ARCH_CO285 || ARCH_SA1100 || ARCH_LUBBOCK || ARCH_PXA_IDP || ARCH_INTEGRATOR || ARCH_P720T || ARCH_VERSATILE || ARCH_IMX || MACH_OMAP_H2 || MACH_OMAP_PERSEUS2)
 	depends on ARCH_NETWINDER || ARCH_EBSA110 || ARCH_EBSA285 || ARCH_SHARK || ARCH_CO285 || ARCH_SA1100 || ARCH_LUBBOCK || MACH_MAINSTONE || ARCH_PXA_IDP || ARCH_INTEGRATOR || ARCH_CDB89712 || ARCH_P720T || ARCH_OMAP || ARCH_VERSATILE || ARCH_IMX
 	default y if ARCH_EBSA110
 	help
@@ -625,7 +647,7 @@
 
 config LEDS_CPU
 	bool "CPU usage LED"
-	depends on LEDS && (ARCH_NETWINDER || ARCH_EBSA285 || ARCH_SHARK || ARCH_CO285 || ARCH_SA1100 || ARCH_LUBBOCK || MACH_MAINSTONE || ARCH_PXA_IDP || ARCH_INTEGRATOR || ARCH_P720T || ARCH_VERSATILE || ARCH_IMX)
+	depends on LEDS && (ARCH_NETWINDER || ARCH_EBSA285 || ARCH_SHARK || ARCH_CO285 || ARCH_SA1100 || ARCH_LUBBOCK || MACH_MAINSTONE || ARCH_PXA_IDP || ARCH_INTEGRATOR || ARCH_P720T || ARCH_VERSATILE || ARCH_IMX || MACH_OMAP_H2 || MACH_OMAP_PERSEUS2)
 	help
 	  If you say Y here, the red LED will be used to give a good real
 	  time indication of CPU usage, by lighting whenever the idle task
diff -Nru a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
--- a/arch/arm/boot/compressed/Makefile	2005-03-01 23:38:52 -08:00
+++ b/arch/arm/boot/compressed/Makefile	2005-03-01 23:38:52 -08:00
@@ -46,6 +46,10 @@
 OBJS		+= head-xscale.o
 endif
 
+ifeq ($(CONFIG_PXA_SHARPSL),y)
+OBJS		+= head-sharpsl.o
+endif
+
 ifeq ($(CONFIG_DEBUG_ICEDCC),y)
 OBJS            += ice-dcc.o
 endif
diff -Nru a/arch/arm/boot/compressed/head-sharpsl.S b/arch/arm/boot/compressed/head-sharpsl.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/arm/boot/compressed/head-sharpsl.S	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,92 @@
+/*
+ * linux/arch/arm/boot/compressed/head-sharpsl.S
+ *
+ * Copyright (C) 2004-2005 Richard Purdie <rpurdie@rpsys.net>
+ *
+ * Sharp's bootloader doesn't pass any kind of machine ID
+ * so we have to figure out the machine for ourselves...
+ *
+ * Support for Poodle, Corgi (SL-C700), Shepherd (SL-C750)
+ * and Husky (SL-C760).
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/linkage.h>
+#include <asm/mach-types.h>
+
+#ifndef CONFIG_PXA_SHARPSL
+#error What am I doing here...
+#endif
+
+		.section        ".start", "ax"
+
+__SharpSL_start:
+
+	ldr	r1, .W100ADDR		@ Base address of w100 chip + regs offset
+
+	mov r6, #0x31			@ Load Magic Init value
+	str	r6, [r1, #0x280]	@ to SCRATCH_UMSK
+	mov r5, #0x3000
+.W100LOOP:
+	subs r5, r5, #1
+    bne .W100LOOP
+	mov r6, #0x30			@ Load 2nd Magic Init value
+	str	r6, [r1, #0x280]	@ to SCRATCH_UMSK
+
+	ldr	r6, [r1, #0]		@ Load Chip ID
+	ldr	r3, .W100ID
+	ldr	r7, .POODLEID
+	cmp	r6, r3
+	bne	.SHARPEND			@ We have no w100 - Poodle
+
+	mrc p15, 0, r6, c0, c0	@ Get Processor ID
+	and	r6, r6, #0xffffff00
+	ldr	r7, .CORGIID
+	ldr	r3, .PXA255ID
+	cmp	r6, r3
+	blo	.SHARPEND			@ We have a PXA250 - Corgi
+
+	mov	r1, #0x0c000000		@ Base address of NAND chip
+	ldrb	r3, [r1, #24]	@ Load FLASHCTL
+	bic	r3, r3, #0x11		@ SET NCE
+	orr	r3, r3, #0x0a		@ SET CLR + FLWP
+	strb	r3, [r1, #24]	@ Save to FLASHCTL
+	mov 	r2, #0x90		@ Command "readid"
+	strb	r2, [r1, #20]	@ Save to FLASHIO
+	bic	r3, r3, #2			@ CLR CLE
+	orr	r3, r3, #4			@ SET ALE
+	strb	r3, [r1, #24]	@ Save to FLASHCTL
+	mov		r2, #0			@ Address 0x00
+	strb	r2, [r1, #20]	@ Save to FLASHIO
+	bic	r3, r3, #4			@ CLR ALE
+	strb	r3, [r1, #24]	@ Save to FLASHCTL
+.SHARP1:
+	ldrb	r3, [r1, #24]	@ Load FLASHCTL
+	tst	r3, #32				@ Is chip ready?
+	beq	.SHARP1
+	ldrb	r2, [r1, #20]	@ NAND Manufacturer ID
+	ldrb	r3, [r1, #20]	@ NAND Chip ID
+	ldr	r7, .SHEPHERDID
+	cmp	r3, #0x76			@ 64MiB flash
+	beq	.SHARPEND			@ We have Shepherd
+	ldr	r7, .HUSKYID		@ Must be Husky
+	b .SHARPEND
+
+.PXA255ID:
+	.word	0x69052d00		@ PXA255 Processor ID
+.W100ID:
+	.word	0x57411002		@ w100 Chip ID
+.W100ADDR:
+	.word 	0x08010000		@ w100 Chip ID Reg Address
+.POODLEID:
+	.word	MACH_TYPE_POODLE
+.CORGIID:
+	.word	MACH_TYPE_CORGI
+.SHEPHERDID:
+	.word	MACH_TYPE_SHEPHERD
+.HUSKYID:
+	.word	MACH_TYPE_HUSKY
+.SHARPEND:
+
+
diff -Nru a/arch/arm/boot/compressed/head-xscale.S b/arch/arm/boot/compressed/head-xscale.S
--- a/arch/arm/boot/compressed/head-xscale.S	2005-03-01 23:38:54 -08:00
+++ b/arch/arm/boot/compressed/head-xscale.S	2005-03-01 23:38:54 -08:00
@@ -34,25 +34,16 @@
 		bic	r0, r0, #0x1000		@ clear Icache
 		mcr	p15, 0, r0, c1, c0, 0
 
-#ifdef	CONFIG_ARCH_IQ80321
-		mov	r7, #MACH_TYPE_IQ80321
-#endif
-
-#ifdef  CONFIG_ARCH_IQ31244
-		mov	r7, #(MACH_TYPE_IQ31244 & 0xff)
-		orr	r7, r7, #(MACH_TYPE_IQ31244 & 0xff00)
-#endif
-
-#ifdef  CONFIG_ARCH_IQ80331
-		mov	r7, #(MACH_TYPE_IQ80331 & 0xff)
-		orr	r7, r7, #(MACH_TYPE_IQ80331 & 0xff00)
-#endif
-
 #ifdef CONFIG_ARCH_LUBBOCK
 		mov	r7, #MACH_TYPE_LUBBOCK
 #endif
 
 #ifdef CONFIG_ARCH_COTULLA_IDP
 		mov	r7, #MACH_TYPE_COTULLA_IDP
+#endif
+
+#ifdef  CONFIG_MACH_GTWX5715
+               mov     r7, #(MACH_TYPE_GTWX5715 & 0xff)
+               orr     r7, r7, #(MACH_TYPE_GTWX5715 & 0xff00)
 #endif
 
diff -Nru a/arch/arm/boot/compressed/ofw-shark.c b/arch/arm/boot/compressed/ofw-shark.c
--- a/arch/arm/boot/compressed/ofw-shark.c	2005-03-01 23:38:57 -08:00
+++ b/arch/arm/boot/compressed/ofw-shark.c	2005-03-01 23:38:57 -08:00
@@ -24,6 +24,8 @@
 	int j,i,m,k,nr_banks,size;
 	unsigned char *c;
 
+	k = 0;
+
 	/* Head of the taglist */
 	tag->hdr.tag  = ATAG_CORE;
 	tag->hdr.size = tag_size(tag_core);
diff -Nru a/arch/arm/common/Makefile b/arch/arm/common/Makefile
--- a/arch/arm/common/Makefile	2005-03-01 23:38:56 -08:00
+++ b/arch/arm/common/Makefile	2005-03-01 23:38:56 -08:00
@@ -11,3 +11,4 @@
 obj-$(CONFIG_DMABOUNCE)		+= dmabounce.o
 obj-$(CONFIG_TIMER_ACORN)	+= time-acorn.o
 obj-$(CONFIG_SHARP_LOCOMO)	+= locomo.o
+obj-$(CONFIG_SHARP_SCOOP)	+= scoop.o
diff -Nru a/arch/arm/common/amba.c b/arch/arm/common/amba.c
--- a/arch/arm/common/amba.c	2005-03-01 23:38:56 -08:00
+++ b/arch/arm/common/amba.c	2005-03-01 23:38:56 -08:00
@@ -59,7 +59,7 @@
 #define amba_hotplug NULL
 #endif
 
-static int amba_suspend(struct device *dev, u32 state)
+static int amba_suspend(struct device *dev, pm_message_t state)
 {
 	struct amba_driver *drv = to_amba_driver(dev->driver);
 	int ret = 0;
diff -Nru a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c
--- a/arch/arm/common/locomo.c	2005-03-01 23:38:43 -08:00
+++ b/arch/arm/common/locomo.c	2005-03-01 23:38:43 -08:00
@@ -668,7 +668,7 @@
 	return dev->devid == drv->devid;
 }
 
-static int locomo_bus_suspend(struct device *dev, u32 state)
+static int locomo_bus_suspend(struct device *dev, pm_message_t state)
 {
 	struct locomo_dev *ldev = LOCOMO_DEV(dev);
 	struct locomo_driver *drv = LOCOMO_DRV(dev->driver);
diff -Nru a/arch/arm/common/rtctime.c b/arch/arm/common/rtctime.c
--- a/arch/arm/common/rtctime.c	2005-03-01 23:38:53 -08:00
+++ b/arch/arm/common/rtctime.c	2005-03-01 23:38:53 -08:00
@@ -28,7 +28,7 @@
 /*
  * rtc_lock protects rtc_irq_data
  */
-static spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(rtc_lock);
 static unsigned long rtc_irq_data;
 
 /*
diff -Nru a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c
--- a/arch/arm/common/sa1111.c	2005-03-01 23:39:16 -08:00
+++ b/arch/arm/common/sa1111.c	2005-03-01 23:39:16 -08:00
@@ -53,7 +53,7 @@
 	unsigned long	phys;
 	int		irq;
 	spinlock_t	lock;
-	void		*base;
+	void __iomem	*base;
 };
 
 /*
@@ -141,15 +141,16 @@
 sa1111_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
 {
 	unsigned int stat0, stat1, i;
+	void __iomem *base = desc->data;
 
-	stat0 = sa1111_readl(desc->data + SA1111_INTSTATCLR0);
-	stat1 = sa1111_readl(desc->data + SA1111_INTSTATCLR1);
+	stat0 = sa1111_readl(base + SA1111_INTSTATCLR0);
+	stat1 = sa1111_readl(base + SA1111_INTSTATCLR1);
 
-	sa1111_writel(stat0, desc->data + SA1111_INTSTATCLR0);
+	sa1111_writel(stat0, base + SA1111_INTSTATCLR0);
 
 	desc->chip->ack(irq);
 
-	sa1111_writel(stat1, desc->data + SA1111_INTSTATCLR1);
+	sa1111_writel(stat1, base + SA1111_INTSTATCLR1);
 
 	if (stat0 == 0 && stat1 == 0) {
 		do_bad_IRQ(irq, desc, regs);
@@ -177,7 +178,7 @@
 
 static void sa1111_mask_lowirq(unsigned int irq)
 {
-	void *mapbase = get_irq_chipdata(irq);
+	void __iomem *mapbase = get_irq_chipdata(irq);
 	unsigned long ie0;
 
 	ie0 = sa1111_readl(mapbase + SA1111_INTEN0);
@@ -187,7 +188,7 @@
 
 static void sa1111_unmask_lowirq(unsigned int irq)
 {
-	void *mapbase = get_irq_chipdata(irq);
+	void __iomem *mapbase = get_irq_chipdata(irq);
 	unsigned long ie0;
 
 	ie0 = sa1111_readl(mapbase + SA1111_INTEN0);
@@ -205,7 +206,7 @@
 static int sa1111_retrigger_lowirq(unsigned int irq)
 {
 	unsigned int mask = SA1111_IRQMASK_LO(irq);
-	void *mapbase = get_irq_chipdata(irq);
+	void __iomem *mapbase = get_irq_chipdata(irq);
 	unsigned long ip0;
 	int i;
 
@@ -226,7 +227,7 @@
 static int sa1111_type_lowirq(unsigned int irq, unsigned int flags)
 {
 	unsigned int mask = SA1111_IRQMASK_LO(irq);
-	void *mapbase = get_irq_chipdata(irq);
+	void __iomem *mapbase = get_irq_chipdata(irq);
 	unsigned long ip0;
 
 	if (flags == IRQT_PROBE)
@@ -249,7 +250,7 @@
 static int sa1111_wake_lowirq(unsigned int irq, unsigned int on)
 {
 	unsigned int mask = SA1111_IRQMASK_LO(irq);
-	void *mapbase = get_irq_chipdata(irq);
+	void __iomem *mapbase = get_irq_chipdata(irq);
 	unsigned long we0;
 
 	we0 = sa1111_readl(mapbase + SA1111_WAKEEN0);
@@ -273,7 +274,7 @@
 
 static void sa1111_mask_highirq(unsigned int irq)
 {
-	void *mapbase = get_irq_chipdata(irq);
+	void __iomem *mapbase = get_irq_chipdata(irq);
 	unsigned long ie1;
 
 	ie1 = sa1111_readl(mapbase + SA1111_INTEN1);
@@ -283,7 +284,7 @@
 
 static void sa1111_unmask_highirq(unsigned int irq)
 {
-	void *mapbase = get_irq_chipdata(irq);
+	void __iomem *mapbase = get_irq_chipdata(irq);
 	unsigned long ie1;
 
 	ie1 = sa1111_readl(mapbase + SA1111_INTEN1);
@@ -301,7 +302,7 @@
 static int sa1111_retrigger_highirq(unsigned int irq)
 {
 	unsigned int mask = SA1111_IRQMASK_HI(irq);
-	void *mapbase = get_irq_chipdata(irq);
+	void __iomem *mapbase = get_irq_chipdata(irq);
 	unsigned long ip1;
 	int i;
 
@@ -322,7 +323,7 @@
 static int sa1111_type_highirq(unsigned int irq, unsigned int flags)
 {
 	unsigned int mask = SA1111_IRQMASK_HI(irq);
-	void *mapbase = get_irq_chipdata(irq);
+	void __iomem *mapbase = get_irq_chipdata(irq);
 	unsigned long ip1;
 
 	if (flags == IRQT_PROBE)
@@ -345,7 +346,7 @@
 static int sa1111_wake_highirq(unsigned int irq, unsigned int on)
 {
 	unsigned int mask = SA1111_IRQMASK_HI(irq);
-	void *mapbase = get_irq_chipdata(irq);
+	void __iomem *mapbase = get_irq_chipdata(irq);
 	unsigned long we1;
 
 	we1 = sa1111_readl(mapbase + SA1111_WAKEEN1);
@@ -369,7 +370,7 @@
 
 static void sa1111_setup_irq(struct sa1111 *sachip)
 {
-	void *irqbase = sachip->base + SA1111_INTC;
+	void __iomem *irqbase = sachip->base + SA1111_INTC;
 	unsigned int irq;
 
 	/*
@@ -723,7 +724,7 @@
 static void __sa1111_remove(struct sa1111 *sachip)
 {
 	struct list_head *l, *n;
-	void *irqbase = sachip->base + SA1111_INTC;
+	void __iomem *irqbase = sachip->base + SA1111_INTC;
 
 	list_for_each_safe(l, n, &sachip->dev->children) {
 		struct device *d = list_to_dev(l);
@@ -797,7 +798,7 @@
 	unsigned int	wakeen1;
 };
 
-#ifdef	CONFIG_PM
+#ifdef CONFIG_PM
 
 static int sa1111_suspend(struct device *dev, u32 state, u32 level)
 {
@@ -805,7 +806,7 @@
 	struct sa1111_save_data *save;
 	unsigned long flags;
 	unsigned int val;
-	char *base;
+	void __iomem *base;
 
 	if (level != SUSPEND_DISABLE)
 		return 0;
@@ -866,7 +867,7 @@
 	struct sa1111 *sachip = dev_get_drvdata(dev);
 	struct sa1111_save_data *save;
 	unsigned long flags, id;
-	char *base;
+	void __iomem *base;
 
 	if (level != RESUME_ENABLE)
 		return 0;
@@ -922,11 +923,10 @@
 	return 0;
 }
 
-#else	/* !CONFIG_PM */
-#define sa1111_resume	NULL
-#define sa1111_suspend	NULL
-#endif	/* !CONFIG_PM */
-
+#else
+#define sa1111_suspend NULL
+#define sa1111_resume  NULL
+#endif
 
 static int sa1111_probe(struct device *dev)
 {
@@ -1095,7 +1095,7 @@
 	struct sa1111 *sachip = sa1111_chip_driver(sadev);
 	unsigned long flags;
 	unsigned int val;
-	void *gpio = sachip->base + SA1111_GPIO;
+	void __iomem *gpio = sachip->base + SA1111_GPIO;
 
 #define MODIFY_BITS(port, mask, dir)		\
 	if (mask) {				\
@@ -1121,7 +1121,7 @@
 	struct sa1111 *sachip = sa1111_chip_driver(sadev);
 	unsigned long flags;
 	unsigned int val;
-	void *gpio = sachip->base + SA1111_GPIO;
+	void __iomem *gpio = sachip->base + SA1111_GPIO;
 
 	spin_lock_irqsave(&sachip->lock, flags);
 	MODIFY_BITS(gpio + SA1111_GPIO_PADWR, bits & 15, v);
@@ -1135,7 +1135,7 @@
 	struct sa1111 *sachip = sa1111_chip_driver(sadev);
 	unsigned long flags;
 	unsigned int val;
-	void *gpio = sachip->base + SA1111_GPIO;
+	void __iomem *gpio = sachip->base + SA1111_GPIO;
 
 	spin_lock_irqsave(&sachip->lock, flags);
 	MODIFY_BITS(gpio + SA1111_GPIO_PASSR, bits & 15, v);
@@ -1194,7 +1194,7 @@
 	return dev->devid == drv->devid;
 }
 
-static int sa1111_bus_suspend(struct device *dev, u32 state)
+static int sa1111_bus_suspend(struct device *dev, pm_message_t state)
 {
 	struct sa1111_dev *sadev = SA1111_DEV(dev);
 	struct sa1111_driver *drv = SA1111_DRV(dev->driver);
diff -Nru a/arch/arm/common/scoop.c b/arch/arm/common/scoop.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/arm/common/scoop.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,134 @@
+/*
+ * Support code for the SCOOP interface found on various Sharp PDAs
+ *
+ * Copyright (c) 2004 Richard Purdie
+ *
+ *	Based on code written by Sharp/Lineo for 2.4 kernels
+ *
+ * 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/device.h>
+#include <asm/io.h>
+#include <asm/hardware/scoop.h>
+
+static void __iomem *scoop_io_base;
+
+#define SCOOP_REG(adr) (*(volatile unsigned short*)(scoop_io_base+(adr)))
+
+void reset_scoop(void)
+{
+	SCOOP_REG(SCOOP_MCR) = 0x0100;	// 00
+	SCOOP_REG(SCOOP_CDR) = 0x0000;  // 04
+	SCOOP_REG(SCOOP_CPR) = 0x0000;  // 0C
+	SCOOP_REG(SCOOP_CCR) = 0x0000;  // 10
+	SCOOP_REG(SCOOP_IMR) = 0x0000;  // 18
+	SCOOP_REG(SCOOP_IRM) = 0x00FF;  // 14
+	SCOOP_REG(SCOOP_ISR) = 0x0000;  // 1C
+	SCOOP_REG(SCOOP_IRM) = 0x0000;
+}
+
+static DEFINE_SPINLOCK(scoop_lock);
+static u32 scoop_gpwr;
+
+unsigned short set_scoop_gpio(unsigned short bit)
+{
+	unsigned short gpio_bit;
+	unsigned long flag;
+
+	spin_lock_irqsave(&scoop_lock, flag);
+	gpio_bit = SCOOP_REG(SCOOP_GPWR) | bit;
+	SCOOP_REG(SCOOP_GPWR) = gpio_bit;
+	spin_unlock_irqrestore(&scoop_lock, flag);
+
+	return gpio_bit;
+}
+
+unsigned short reset_scoop_gpio(unsigned short bit)
+{
+	unsigned short gpio_bit;
+	unsigned long flag;
+
+	spin_lock_irqsave(&scoop_lock, flag);
+	gpio_bit = SCOOP_REG(SCOOP_GPWR) & ~bit;
+	SCOOP_REG(SCOOP_GPWR) = gpio_bit;
+	spin_unlock_irqrestore(&scoop_lock, flag);
+
+	return gpio_bit;
+}
+
+EXPORT_SYMBOL(set_scoop_gpio);
+EXPORT_SYMBOL(reset_scoop_gpio);
+
+unsigned short read_scoop_reg(unsigned short reg)
+{
+	return SCOOP_REG(reg);
+}
+
+void write_scoop_reg(unsigned short reg, unsigned short data)
+{
+	SCOOP_REG(reg)=data;
+}
+
+EXPORT_SYMBOL(reset_scoop);
+EXPORT_SYMBOL(read_scoop_reg);
+EXPORT_SYMBOL(write_scoop_reg);
+
+static int scoop_suspend(struct device *dev, uint32_t state, uint32_t level)
+{
+	if (level == SUSPEND_POWER_DOWN) {
+		scoop_gpwr = SCOOP_REG(SCOOP_GPWR);
+		SCOOP_REG(SCOOP_GPWR) = 0;
+	}
+	return 0;
+}
+
+static int scoop_resume(struct device *dev, uint32_t level)
+{
+	if (level == RESUME_POWER_ON) {
+		SCOOP_REG(SCOOP_GPWR) = scoop_gpwr;
+	}
+	return 0;
+}
+
+int __init scoop_probe(struct device *dev)
+{
+	struct scoop_config *inf;
+	struct platform_device *pdev = to_platform_device(dev);
+	struct resource *mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+	if (!mem)
+		return -EINVAL;
+
+	inf = dev->platform_data;
+	scoop_io_base = ioremap(mem->start, 0x1000);
+	if (!scoop_io_base)
+		return -ENOMEM;
+
+	SCOOP_REG(SCOOP_MCR) = 0x0140;
+
+	reset_scoop();
+
+	SCOOP_REG(SCOOP_GPCR) = inf->io_dir & 0xffff;
+	SCOOP_REG(SCOOP_GPWR) = inf->io_out & 0xffff;
+
+	return 0;
+}
+
+static struct device_driver scoop_driver = {
+	.name		= "sharp-scoop",
+	.bus		= &platform_bus_type,
+	.probe		= scoop_probe,
+	.suspend	= scoop_suspend,
+	.resume		= scoop_resume,
+};
+
+int __init scoop_init(void)
+{
+	return driver_register(&scoop_driver);
+}
+
+subsys_initcall(scoop_init);
diff -Nru a/arch/arm/common/via82c505.c b/arch/arm/common/via82c505.c
--- a/arch/arm/common/via82c505.c	2005-03-01 23:38:44 -08:00
+++ b/arch/arm/common/via82c505.c	2005-03-01 23:38:44 -08:00
@@ -59,7 +59,7 @@
 	.write	= via82c505_write_config,
 };
 
-void __init via82c505_preinit(void *sysdata)
+void __init via82c505_preinit(void)
 {
 	printk(KERN_DEBUG "PCI: VIA 82c505\n");
 	if (!request_region(0xA8,2,"via config")) {
diff -Nru a/arch/arm/configs/ebsa110_defconfig b/arch/arm/configs/ebsa110_defconfig
--- a/arch/arm/configs/ebsa110_defconfig	2005-03-01 23:38:51 -08:00
+++ b/arch/arm/configs/ebsa110_defconfig	2005-03-01 23:38:51 -08:00
@@ -239,7 +239,6 @@
 CONFIG_IP_NF_TARGET_REDIRECT=y
 CONFIG_IP_NF_TARGET_NETMAP=y
 CONFIG_IP_NF_TARGET_SAME=y
-# CONFIG_IP_NF_NAT_LOCAL is not set
 # CONFIG_IP_NF_NAT_SNMP_BASIC is not set
 CONFIG_IP_NF_NAT_IRC=y
 CONFIG_IP_NF_NAT_FTP=y
diff -Nru a/arch/arm/configs/ep80219_defconfig b/arch/arm/configs/ep80219_defconfig
--- a/arch/arm/configs/ep80219_defconfig	2005-03-01 23:38:55 -08:00
+++ b/arch/arm/configs/ep80219_defconfig	2005-03-01 23:38:55 -08:00
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc3
-# Wed Dec 15 17:03:41 2004
+# Linux kernel version: 2.6.10
+# Thu Jan  6 10:54:33 2005
 #
 CONFIG_ARM=y
 CONFIG_MMU=y
@@ -90,6 +90,7 @@
 # CONFIG_ARCH_IQ80321 is not set
 CONFIG_ARCH_IQ31244=y
 # CONFIG_ARCH_IQ80331 is not set
+# CONFIG_MACH_IQ80332 is not set
 CONFIG_ARCH_EP80219=y
 CONFIG_ARCH_IOP321=y
 # CONFIG_ARCH_IOP331 is not set
@@ -119,7 +120,6 @@
 # General setup
 #
 CONFIG_PCI=y
-# CONFIG_ZBOOT_ROM is not set
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
 # CONFIG_XIP_KERNEL is not set
@@ -144,7 +144,7 @@
 # CONFIG_PM is not set
 # CONFIG_PREEMPT is not set
 # CONFIG_ARTHUR is not set
-CONFIG_CMDLINE="ip=boot root=nfs console=ttyS0,115200 mem=128M@0xa0000000"
+CONFIG_CMDLINE="ip=boot root=nfs console=ttyS0,115200"
 CONFIG_ALIGNMENT_TRAP=y
 
 #
@@ -398,7 +398,8 @@
 #
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
-# CONFIG_E1000 is not set
+CONFIG_E1000=y
+CONFIG_E1000_NAPI=y
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
@@ -537,7 +538,7 @@
 # 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
diff -Nru a/arch/arm/configs/iq31244_defconfig b/arch/arm/configs/iq31244_defconfig
--- a/arch/arm/configs/iq31244_defconfig	2005-03-01 23:39:17 -08:00
+++ b/arch/arm/configs/iq31244_defconfig	2005-03-01 23:39:18 -08:00
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc3
-# Wed Dec 15 16:58:36 2004
+# Linux kernel version: 2.6.10
+# Thu Jan  6 10:53:05 2005
 #
 CONFIG_ARM=y
 CONFIG_MMU=y
@@ -30,7 +30,8 @@
 CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_HOTPLUG is not set
 CONFIG_KOBJECT_UEVENT=y
-# CONFIG_IKCONFIG is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -90,6 +91,7 @@
 # CONFIG_ARCH_IQ80321 is not set
 CONFIG_ARCH_IQ31244=y
 # CONFIG_ARCH_IQ80331 is not set
+# CONFIG_MACH_IQ80332 is not set
 # CONFIG_ARCH_EP80219 is not set
 CONFIG_ARCH_IOP321=y
 # CONFIG_ARCH_IOP331 is not set
@@ -119,7 +121,6 @@
 # General setup
 #
 CONFIG_PCI=y
-# CONFIG_ZBOOT_ROM is not set
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
 # CONFIG_XIP_KERNEL is not set
@@ -144,7 +145,7 @@
 # CONFIG_PM is not set
 # CONFIG_PREEMPT is not set
 # CONFIG_ARTHUR is not set
-CONFIG_CMDLINE="ip=boot root=nfs console=ttyS0,115200 mem=256M@0xa0000000"
+CONFIG_CMDLINE="ip=boot root=nfs console=ttyS0,115200"
 CONFIG_ALIGNMENT_TRAP=y
 
 #
@@ -506,7 +507,7 @@
 # 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
diff -Nru a/arch/arm/configs/iq80321_defconfig b/arch/arm/configs/iq80321_defconfig
--- a/arch/arm/configs/iq80321_defconfig	2005-03-01 23:38:54 -08:00
+++ b/arch/arm/configs/iq80321_defconfig	2005-03-01 23:38:54 -08:00
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc3
-# Wed Dec 15 16:48:43 2004
+# Linux kernel version: 2.6.10
+# Thu Jan  6 10:52:05 2005
 #
 CONFIG_ARM=y
 CONFIG_MMU=y
@@ -90,6 +90,7 @@
 CONFIG_ARCH_IQ80321=y
 # CONFIG_ARCH_IQ31244 is not set
 # CONFIG_ARCH_IQ80331 is not set
+# CONFIG_MACH_IQ80332 is not set
 # CONFIG_ARCH_EP80219 is not set
 CONFIG_ARCH_IOP321=y
 # CONFIG_ARCH_IOP331 is not set
@@ -119,7 +120,6 @@
 # General setup
 #
 CONFIG_PCI=y
-# CONFIG_ZBOOT_ROM is not set
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
 # CONFIG_XIP_KERNEL is not set
@@ -144,7 +144,7 @@
 # CONFIG_PM is not set
 # CONFIG_PREEMPT is not set
 # CONFIG_ARTHUR is not set
-CONFIG_CMDLINE="ip=boot root=nfs console=ttyS0,115200 mem=128M@0xa0000000"
+CONFIG_CMDLINE="ip=boot root=nfs console=ttyS0,115200"
 CONFIG_ALIGNMENT_TRAP=y
 
 #
@@ -427,7 +427,7 @@
 # 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
@@ -500,7 +500,84 @@
 #
 # I2C support
 #
-# CONFIG_I2C is not set
+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_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_IOP3XX=y
+# CONFIG_I2C_ISA 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
+# 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
+#
+# 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_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
 
 #
 # Multimedia devices
@@ -689,7 +766,7 @@
 # CONFIG_DEBUG_KERNEL is not set
 # CONFIG_DEBUG_INFO is not set
 CONFIG_FRAME_POINTER=y
-# CONFIG_DEBUG_USER is not set
+CONFIG_DEBUG_USER=y
 
 #
 # Security options
diff -Nru a/arch/arm/configs/iq80331_defconfig b/arch/arm/configs/iq80331_defconfig
--- a/arch/arm/configs/iq80331_defconfig	2005-03-01 23:38:44 -08:00
+++ b/arch/arm/configs/iq80331_defconfig	2005-03-01 23:38:44 -08:00
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc3
-# Wed Dec 15 16:43:39 2004
+# Linux kernel version: 2.6.10
+# Thu Jan  6 10:44:16 2005
 #
 CONFIG_ARM=y
 CONFIG_MMU=y
@@ -33,7 +33,6 @@
 # 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
@@ -91,12 +90,14 @@
 # CONFIG_ARCH_IQ80321 is not set
 # CONFIG_ARCH_IQ31244 is not set
 CONFIG_ARCH_IQ80331=y
+# CONFIG_MACH_IQ80332 is not set
 # CONFIG_ARCH_EP80219 is not set
 CONFIG_ARCH_IOP331=y
 
 #
 # IOP3xx Chipset Features
 #
+CONFIG_IOP331_STEPD=y
 
 #
 # Processor Type
@@ -119,7 +120,6 @@
 # General setup
 #
 CONFIG_PCI=y
-# CONFIG_ZBOOT_ROM is not set
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
 # CONFIG_XIP_KERNEL is not set
@@ -141,11 +141,10 @@
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_DEBUG_DRIVER is not set
 # CONFIG_PM is not set
 # CONFIG_PREEMPT is not set
 # CONFIG_ARTHUR is not set
-CONFIG_CMDLINE="ip=boot root=nfs console=ttyS0,115200 mem=128M@0x00000000"
+CONFIG_CMDLINE="ip=boot root=nfs console=ttyS0,115200"
 CONFIG_ALIGNMENT_TRAP=y
 
 #
@@ -511,7 +510,7 @@
 # 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
@@ -584,7 +583,84 @@
 #
 # I2C support
 #
-# CONFIG_I2C is not set
+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_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_IOP3XX=y
+# CONFIG_I2C_ISA 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
+# 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
+#
+# 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_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
 
 #
 # Multimedia devices
@@ -764,19 +840,10 @@
 #
 # Kernel hacking
 #
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_MAGIC_SYSRQ is not set
-# CONFIG_SCHEDSTATS is not set
-# CONFIG_DEBUG_SLAB is not set
-# CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_DEBUG_KOBJECT is not set
-CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_KERNEL is not set
 # CONFIG_DEBUG_INFO is not set
 CONFIG_FRAME_POINTER=y
 CONFIG_DEBUG_USER=y
-# CONFIG_DEBUG_WAITQ is not set
-CONFIG_DEBUG_ERRORS=y
-# CONFIG_DEBUG_LL is not set
 
 #
 # Security options
@@ -793,5 +860,5 @@
 # Library routines
 #
 # CONFIG_CRC_CCITT is not set
-CONFIG_CRC32=y
+# CONFIG_CRC32 is not set
 # CONFIG_LIBCRC32C is not set
diff -Nru a/arch/arm/configs/iq80332_defconfig b/arch/arm/configs/iq80332_defconfig
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/arm/configs/iq80332_defconfig	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,864 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.10
+# Thu Jan  6 10:51:02 2005
+#
+CONFIG_ARM=y
+CONFIG_MMU=y
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=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=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_EXTRA_PASS is not set
+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
+
+#
+# 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
+
+#
+# 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=y
+# 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 is not set
+# 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
+
+#
+# IOP3xx Implementation Options
+#
+
+#
+# IOP3xx Platform Types
+#
+# CONFIG_ARCH_IQ80321 is not set
+# CONFIG_ARCH_IQ31244 is not set
+# CONFIG_ARCH_IQ80331 is not set
+CONFIG_MACH_IQ80332=y
+# CONFIG_ARCH_EP80219 is not set
+CONFIG_ARCH_IOP331=y
+
+#
+# IOP3xx Chipset Features
+#
+# CONFIG_IOP331_STEPD is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_XSCALE=y
+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
+#
+# CONFIG_ARM_THUMB is not set
+CONFIG_XSCALE_PMU=y
+
+#
+# General setup
+#
+CONFIG_PCI=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_PCI_LEGACY_PROC is not set
+CONFIG_PCI_NAMES=y
+
+#
+# At least one math emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_AOUT=y
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_PM is not set
+# CONFIG_PREEMPT is not set
+# CONFIG_ARTHUR is not set
+CONFIG_CMDLINE="ip=boot root=nfs console=ttyS0,115200"
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_REDBOOT_PARTS=y
+CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y
+CONFIG_MTD_REDBOOT_PARTS_READONLY=y
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_NOSWAP=y
+# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
+# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
+# CONFIG_MTD_CFI_GEOMETRY 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=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# 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
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_START=0xc0000000
+CONFIG_MTD_PHYSMAP_LEN=0x00800000
+CONFIG_MTD_PHYSMAP_BANKWIDTH=1
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_EDB7312 is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# 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
+
+#
+# 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_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=8192
+# 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=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_LINEAR=y
+CONFIG_MD_RAID0=y
+CONFIG_MD_RAID1=y
+# CONFIG_MD_RAID10 is not set
+CONFIG_MD_RAID5=y
+# CONFIG_MD_RAID6 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_MD_FAULTY 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
+
+#
+# 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=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_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
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+# CONFIG_NET_ETHERNET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+CONFIG_E1000=y
+CONFIG_E1000_NAPI=y
+# 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 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
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE 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=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+CONFIG_CHR_DEV_SG=y
+
+#
+# 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 is not set
+# CONFIG_SCSI_FC_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_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 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_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG 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
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN 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 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_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# 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_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_IOP3XX=y
+# CONFIG_I2C_ISA 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
+# 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
+#
+# 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_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
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB 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
+CONFIG_XFS_FS=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_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_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_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_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+CONFIG_NFSD=y
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V4 is not set
+# CONFIG_NFSD_TCP is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=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
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING 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
+
+#
+# Misc devices
+#
+
+#
+# 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
+
+#
+# Kernel hacking
+#
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_DEBUG_INFO is not set
+CONFIG_FRAME_POINTER=y
+CONFIG_DEBUG_USER=y
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC32 is not set
+# CONFIG_LIBCRC32C is not set
diff -Nru a/arch/arm/configs/ixp4xx_defconfig b/arch/arm/configs/ixp4xx_defconfig
--- a/arch/arm/configs/ixp4xx_defconfig	2005-03-01 23:38:54 -08:00
+++ b/arch/arm/configs/ixp4xx_defconfig	2005-03-01 23:38:54 -08:00
@@ -399,7 +399,6 @@
 CONFIG_IP_NF_TARGET_REDIRECT=m
 # CONFIG_IP_NF_TARGET_NETMAP is not set
 # CONFIG_IP_NF_TARGET_SAME is not set
-CONFIG_IP_NF_NAT_LOCAL=y
 CONFIG_IP_NF_NAT_SNMP_BASIC=m
 CONFIG_IP_NF_NAT_IRC=m
 CONFIG_IP_NF_NAT_FTP=m
diff -Nru a/arch/arm/configs/omap_h2_1610_defconfig b/arch/arm/configs/omap_h2_1610_defconfig
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/arm/configs/omap_h2_1610_defconfig	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,935 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.11-rc2
+# Tue Feb  1 14:01:46 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
+CONFIG_LOCK_KERNEL=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=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=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
+
+#
+# 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
+
+#
+# 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 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+CONFIG_ARCH_OMAP=y
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_H720X is not set
+
+#
+# TI OMAP Implementations
+#
+
+#
+# OMAP Core Type
+#
+# CONFIG_ARCH_OMAP730 is not set
+# CONFIG_ARCH_OMAP1510 is not set
+CONFIG_ARCH_OMAP16XX=y
+CONFIG_ARCH_OMAP_OTG=y
+
+#
+# OMAP Board Type
+#
+# 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
+#
+CONFIG_OMAP_MUX=y
+# CONFIG_OMAP_MUX_DEBUG is not set
+CONFIG_OMAP_MUX_WARNINGS=y
+CONFIG_OMAP_LL_DEBUG_UART1=y
+# CONFIG_OMAP_LL_DEBUG_UART2 is not set
+# CONFIG_OMAP_LL_DEBUG_UART3 is not set
+CONFIG_OMAP_ARM_192MHZ=y
+# CONFIG_OMAP_ARM_168MHZ is not set
+# CONFIG_OMAP_ARM_120MHZ is not set
+# CONFIG_OMAP_ARM_60MHZ is not set
+# CONFIG_OMAP_ARM_30MHZ is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM926T=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5TJ=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
+
+#
+# General setup
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+# CONFIG_XIP_KERNEL is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# At least one math emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+# CONFIG_VFP is not set
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_AOUT=y
+# 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=y
+CONFIG_PM=y
+CONFIG_PREEMPT=y
+# CONFIG_APM is not set
+# CONFIG_ARTHUR is not set
+CONFIG_CMDLINE="mem=32M console=ttyS0,115200n8 root=0801 ro init=/bin/sh"
+# CONFIG_LEDS is not set
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+CONFIG_MTD_DEBUG=y
+CONFIG_MTD_DEBUG_VERBOSE=3
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_CONCAT is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_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=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_STAA is not set
+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_ARM_INTEGRATOR is not set
+# CONFIG_MTD_EDB7312 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
+
+#
+# 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=8192
+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=m
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD 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 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_SMC91X=y
+
+#
+# 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 is not set
+# CONFIG_PPP_SYNC_TTY is not set
+# CONFIG_PPP_DEFLATE is not set
+# CONFIG_PPP_BSDCOMP is not set
+# CONFIG_PPPOE is not set
+CONFIG_SLIP=y
+CONFIG_SLIP_COMPRESSED=y
+# CONFIG_SLIP_SMART is not set
+# CONFIG_SLIP_MODE_SLIP6 is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE 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 is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG 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 is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# Fusion MPT device support
+#
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# 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=y
+CONFIG_INPUT_EVBUG=y
+
+#
+# Input I/O drivers
+#
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_CT82C710 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=y
+CONFIG_INPUT_UINPUT=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=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 is not set
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_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
+# CONFIG_RAW_DRIVER is not set
+
+#
+# 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_PARPORT_LIGHT is not set
+# CONFIG_I2C_STUB 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_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_ISP1301_OMAP=y
+# 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
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB 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
+# 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_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_JFFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=2
+# 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
+# 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_EXPORTFS is not set
+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=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
+
+#
+# Graphics support
+#
+CONFIG_FB=y
+CONFIG_FB_MODE_HELPERS=y
+# CONFIG_FB_TILEBLITTING is not set
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+# 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=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
+#
+CONFIG_SOUND=y
+
+#
+# Advanced Linux Sound Architecture
+#
+# CONFIG_SND is not set
+
+#
+# Open Sound System
+#
+CONFIG_SOUND_PRIME=y
+# CONFIG_SOUND_BT878 is not set
+# CONFIG_SOUND_FUSION is not set
+# CONFIG_SOUND_CS4281 is not set
+# CONFIG_SOUND_SONICVIBES is not set
+# CONFIG_SOUND_TRIDENT is not set
+# CONFIG_SOUND_MSNDCLAS is not set
+# CONFIG_SOUND_MSNDPIN is not set
+# CONFIG_SOUND_OSS is not set
+# CONFIG_SOUND_TVMIXER is not set
+# CONFIG_SOUND_AD1980 is not set
+
+#
+# Misc devices
+#
+
+#
+# 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=y
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+# 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_DUALSPEED is not set
+# CONFIG_USB_ZERO is not set
+CONFIG_USB_ETH=y
+CONFIG_USB_ETH_RNDIS=y
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FILE_STORAGE is not set
+# CONFIG_USB_G_SERIAL is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# Kernel hacking
+#
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
+CONFIG_DEBUG_PREEMPT=y
+# CONFIG_DEBUG_SPINLOCK 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
+
+#
+# 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_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
+#
+
+#
+# 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 -Nru a/arch/arm/configs/s3c2410_defconfig b/arch/arm/configs/s3c2410_defconfig
--- a/arch/arm/configs/s3c2410_defconfig	2005-03-01 23:38:55 -08:00
+++ b/arch/arm/configs/s3c2410_defconfig	2005-03-01 23:38:55 -08:00
@@ -1,12 +1,13 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc2
-# Mon Nov 15 15:29:42 2004
+# Linux kernel version: 2.6.11-rc1-bk5
+# Tue Jan 18 11:36:49 2005
 #
 CONFIG_ARM=y
 CONFIG_MMU=y
 CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_IOMAP=y
 
 #
@@ -123,12 +124,20 @@
 #
 # General setup
 #
-# CONFIG_ZBOOT_ROM is not set
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
 # CONFIG_XIP_KERNEL is not set
 
 #
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
 # At least one math emulation must be selected
 #
 CONFIG_FPE_NWFPE=y
@@ -143,6 +152,7 @@
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
 # CONFIG_DEBUG_DRIVER is not set
 CONFIG_PM=y
 # CONFIG_PREEMPT is not set
@@ -168,6 +178,7 @@
 CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_REDBOOT_PARTS=y
+CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
 CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y
 # CONFIG_MTD_REDBOOT_PARTS_READONLY is not set
 CONFIG_MTD_CMDLINE_PARTS=y
@@ -200,13 +211,15 @@
 # CONFIG_MTD_CFI_I4 is not set
 # CONFIG_MTD_CFI_I8 is not set
 CONFIG_MTD_CFI_INTELEXT=y
-# CONFIG_MTD_CFI_AMDSTD is not set
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_CFI_AMDSTD_RETRY=0
 # CONFIG_MTD_CFI_STAA is not set
 CONFIG_MTD_CFI_UTIL=y
 # CONFIG_MTD_RAM is not set
-# CONFIG_MTD_ROM is not set
+CONFIG_MTD_ROM=y
 # CONFIG_MTD_ABSENT is not set
 # CONFIG_MTD_OBSOLETE_CHIPS is not set
+# CONFIG_MTD_XIP is not set
 
 #
 # Mapping drivers for chip access
@@ -226,6 +239,7 @@
 # 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
@@ -244,6 +258,7 @@
 # CONFIG_MTD_NAND_S3C2410_DEBUG is not set
 # CONFIG_MTD_NAND_S3C2410_HWECC is not set
 # CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
 
 #
 # Plug and Play support
@@ -254,10 +269,12 @@
 #
 # 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
 # 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=""
@@ -270,6 +287,7 @@
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
 
 #
 # Multi-device support (RAID and LVM)
@@ -456,6 +474,7 @@
 CONFIG_SERIO_SERPORT=y
 # CONFIG_SERIO_CT82C710 is not set
 # CONFIG_SERIO_PARKBD is not set
+CONFIG_SERIO_LIBPS2=y
 # CONFIG_SERIO_RAW is not set
 
 #
@@ -489,6 +508,7 @@
 # CONFIG_DIGI is not set
 # CONFIG_MOXA_INTELLIO is not set
 # CONFIG_MOXA_SMARTIO is not set
+# CONFIG_ISI is not set
 # CONFIG_SYNCLINKMP is not set
 # CONFIG_N_HDLC is not set
 # CONFIG_RISCOM8 is not set
@@ -583,6 +603,7 @@
 CONFIG_I2C_SENSOR=m
 # 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
@@ -600,6 +621,7 @@
 # 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_W83781D is not set
 # CONFIG_SENSORS_W83L785TS is not set
@@ -693,6 +715,7 @@
 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
@@ -812,6 +835,7 @@
 # Logo configuration
 #
 # CONFIG_LOGO is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -830,6 +854,10 @@
 # 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
@@ -848,8 +876,9 @@
 # CONFIG_DEBUG_SLAB is not set
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_KOBJECT is not set
-# CONFIG_DEBUG_BUGVERBOSE 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
@@ -869,6 +898,10 @@
 # Cryptographic options
 #
 # CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
 
 #
 # Library routines
diff -Nru a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
--- a/arch/arm/kernel/Makefile	2005-03-01 23:39:16 -08:00
+++ b/arch/arm/kernel/Makefile	2005-03-01 23:39:16 -08:00
@@ -18,6 +18,7 @@
 obj-$(CONFIG_ARTHUR)		+= arthur.o
 obj-$(CONFIG_ISA_DMA)		+= dma-isa.o
 obj-$(CONFIG_PCI)		+= bios32.o
+obj-$(CONFIG_SMP)		+= smp.o
 
 obj-$(CONFIG_IWMMXT)		+= iwmmxt.o
 AFLAGS_iwmmxt.o			:= -Wa,-mcpu=iwmmxt
diff -Nru a/arch/arm/kernel/apm.c b/arch/arm/kernel/apm.c
--- a/arch/arm/kernel/apm.c	2005-03-01 23:39:16 -08:00
+++ b/arch/arm/kernel/apm.c	2005-03-01 23:39:16 -08:00
@@ -97,7 +97,7 @@
  */
 static DECLARE_WAIT_QUEUE_HEAD(kapmd_wait);
 static DECLARE_COMPLETION(kapmd_exit);
-static spinlock_t kapmd_queue_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(kapmd_queue_lock);
 static struct apm_queue kapmd_queue;
 
 
diff -Nru a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c
--- a/arch/arm/kernel/asm-offsets.c	2005-03-01 23:38:52 -08:00
+++ b/arch/arm/kernel/asm-offsets.c	2005-03-01 23:38:52 -08:00
@@ -59,6 +59,7 @@
   DEFINE(TI_CPU_DOMAIN,		offsetof(struct thread_info, cpu_domain));
   DEFINE(TI_CPU_SAVE,		offsetof(struct thread_info, cpu_context));
   DEFINE(TI_USED_CP,		offsetof(struct thread_info, used_cp));
+  DEFINE(TI_TP_VALUE,		offsetof(struct thread_info, tp_value));
   DEFINE(TI_FPSTATE,		offsetof(struct thread_info, fpstate));
   DEFINE(TI_VFPSTATE,		offsetof(struct thread_info, vfpstate));
   DEFINE(TI_IWMMXT_STATE,	(offsetof(struct thread_info, fpstate)+4)&~7);
@@ -73,7 +74,7 @@
   DEFINE(VM_EXEC,	       	VM_EXEC);
   BLANK();
   DEFINE(PAGE_SZ,	       	PAGE_SIZE);
-  DEFINE(VIRT_OFFSET,	       	PAGE_OFFSET);
+  DEFINE(VIRT_OFFSET,		PAGE_OFFSET);
   BLANK();
   DEFINE(SYS_ERROR0,		0x9f0000);
   BLANK();
diff -Nru a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S
--- a/arch/arm/kernel/calls.S	2005-03-01 23:39:18 -08:00
+++ b/arch/arm/kernel/calls.S	2005-03-01 23:39:18 -08:00
@@ -134,7 +134,7 @@
 		.long	sys_ipc
 		.long	sys_fsync
 		.long	sys_sigreturn_wrapper
-/* 120 */	.long	sys_clone_wapper
+/* 120 */	.long	sys_clone_wrapper
 		.long	sys_setdomainname
 		.long	sys_newuname
 		.long	sys_ni_syscall
@@ -254,7 +254,7 @@
 		.long	sys_fremovexattr
 		.long	sys_tkill
 		.long	sys_sendfile64
-/* 240 */	.long	sys_futex
+/* 240 */	.long	sys_futex_wrapper
 		.long	sys_sched_setaffinity
 		.long	sys_sched_getaffinity
 		.long	sys_io_setup
@@ -270,7 +270,7 @@
 	 	.long	sys_remap_file_pages
 		.long	sys_ni_syscall	/* sys_set_thread_area */
 /* 255 */	.long	sys_ni_syscall	/* sys_get_thread_area */
- 		.long	sys_ni_syscall	/* sys_set_tid_address */
+ 		.long	sys_set_tid_address
 		.long	sys_timer_create
 		.long	sys_timer_settime
 		.long	sys_timer_gettime
diff -Nru a/arch/arm/kernel/debug.S b/arch/arm/kernel/debug.S
--- a/arch/arm/kernel/debug.S	2005-03-01 23:38:55 -08:00
+++ b/arch/arm/kernel/debug.S	2005-03-01 23:38:55 -08:00
@@ -1,5 +1,5 @@
 /*
- *  linux/arch/arm/kernel/debug-armv.S
+ *  linux/arch/arm/kernel/debug.S
  *
  *  Copyright (C) 1994-1999 Russell King
  *
@@ -20,31 +20,8 @@
  * printk isn't working).  For DEBUGGING ONLY!!!  Do not leave
  * references to these in a production kernel!
  */
-#if defined(CONFIG_ARCH_RPC)
-		.macro	addruart,rx
-		mov	\rx, #0xe0000000
-		orr	\rx, \rx, #0x00010000
-		orr	\rx, \rx, #0x00000fe0
-		.endm
-
-		.macro	senduart,rd,rx
-		strb	\rd, [\rx]
-		.endm
-
-		.macro	busyuart,rd,rx
-1001:		ldrb	\rd, [\rx, #0x14]
-		and	\rd, \rd, #0x60
-		teq	\rd, #0x60
-		bne	1001b
-		.endm
 
-		.macro	waituart,rd,rx
-1001:		ldrb	\rd, [\rx, #0x18]
-		tst	\rd, #0x10
-		beq	1001b
-		.endm
-
-#elif defined(CONFIG_DEBUG_ICEDCC)
+#if defined(CONFIG_DEBUG_ICEDCC)
 		@@ debug using ARM EmbeddedICE DCC channel
 		.macro	addruart, rx
 		.endm
@@ -71,666 +48,8 @@
 		bne	1001b
 1002:
 		.endm
-
-#elif defined(CONFIG_ARCH_EBSA110)
-		.macro	addruart,rx
-		mov	\rx, #0xf0000000
-		orr	\rx, \rx, #0x00000be0
-		.endm
-
-		.macro	senduart,rd,rx
-		strb	\rd, [\rx]
-		.endm
-
-		.macro	busyuart,rd,rx
-1002:		ldrb	\rd, [\rx, #0x14]
-		and	\rd, \rd, #0x60
-		teq	\rd, #0x60
-		bne	1002b
-		.endm
-
-		.macro	waituart,rd,rx
-1001:		ldrb	\rd, [\rx, #0x18]
-		tst	\rd, #0x10
-		beq	1001b
-		.endm
- 	
-#elif defined(CONFIG_ARCH_SHARK)
-		.macro	addruart,rx
-		mov	\rx, #0xe0000000
-		orr	\rx, \rx, #0x000003f8
-		.endm
-
-		.macro	senduart,rd,rx
-		strb	\rd, [\rx]
-		.endm
-
-		.macro	busyuart,rd,rx
-		mov	\rd, #0
-1001:		add	\rd, \rd, #1
-		teq	\rd, #0x10000
-		bne	1001b
-		.endm
-
-		.macro	waituart,rd,rx
-		.endm
-
-#elif defined(CONFIG_FOOTBRIDGE)
-
-#include <asm/hardware/dec21285.h>
-
-#ifndef CONFIG_DEBUG_DC21285_PORT
-	/* For NetWinder debugging */
-		.macro	addruart,rx
-		mrc	p15, 0, \rx, c1, c0
-		tst	\rx, #1			@ MMU enabled?
-		moveq	\rx, #0x7c000000	@ physical
-		movne	\rx, #0xff000000	@ virtual
-		orr	\rx, \rx, #0x000003f8
-		.endm
-
-		.macro	senduart,rd,rx
-		strb	\rd, [\rx]
-		.endm
-
-		.macro	busyuart,rd,rx
-1002:		ldrb	\rd, [\rx, #0x5]
-		and	\rd, \rd, #0x60
-		teq	\rd, #0x60
-		bne	1002b
-		.endm
-
-		.macro	waituart,rd,rx
-1001:		ldrb	\rd, [\rx, #0x6]
-		tst	\rd, #0x10
-		beq	1001b
-		.endm
-#else
-	/* For EBSA285 debugging */
-		.equ	dc21285_high, ARMCSR_BASE & 0xff000000
-		.equ	dc21285_low,  ARMCSR_BASE & 0x00ffffff
-
-		.macro	addruart,rx
-		mov	\rx, #dc21285_high
-		.if	dc21285_low
-		orr	\rx, \rx, #dc21285_low
-		.endif
-		.endm
-
-		.macro	senduart,rd,rx
-		str	\rd, [\rx, #0x160]	@ UARTDR
-		.endm
-
-		.macro	busyuart,rd,rx
-1001:		ldr	\rd, [\rx, #0x178]	@ UARTFLG
-		tst	\rd, #1 << 3
-		bne	1001b
-		.endm
-
-		.macro	waituart,rd,rx
-		.endm
-#endif
-#elif defined(CONFIG_ARCH_FTVPCI)
-		.macro	addruart,rx
-		mrc	p15, 0, \rx, c1, c0
-		tst	\rx, #1			@ MMU enabled?
-		movne	\rx, #0xe0000000
-		moveq	\rx, #0x10000000
-		.endm
-
-		.macro	senduart,rd,rx
-		str	\rd, [\rx, #0xc]
-		.endm
-
-		.macro	busyuart,rd,rx
-1001:		ldr	\rd, [\rx, #0x4]
-		tst	\rd, #1 << 2
-		beq	1001b
-		.endm
-
-		.macro	waituart,rd,rx
-		.endm
-
-#elif defined(CONFIG_ARCH_SA1100)
-
-		.macro	addruart,rx
-		mrc	p15, 0, \rx, c1, c0
-		tst	\rx, #1			@ MMU enabled?
-		moveq	\rx, #0x80000000	@ physical base address
-		movne	\rx, #0xf8000000	@ virtual address
-
-		@ We probe for the active serial port here, coherently with
-		@ the comment in include/asm-arm/arch-sa1100/uncompress.h.
-		@ We assume r1 can be clobbered.
-
-		@ see if Ser3 is active
-		add	\rx, \rx, #0x00050000
-		ldr	r1, [\rx, #UTCR3]
-		tst	r1, #UTCR3_TXE
-
-		@ if Ser3 is inactive, then try Ser1
-		addeq	\rx, \rx, #(0x00010000 - 0x00050000)
-		ldreq	r1, [\rx, #UTCR3]
-		tsteq	r1, #UTCR3_TXE
-
-		@ if Ser1 is inactive, then try Ser2
-		addeq	\rx, \rx, #(0x00030000 - 0x00010000)
-		ldreq	r1, [\rx, #UTCR3]
-		tsteq	r1, #UTCR3_TXE
-
-		@ if all ports are inactive, then there is nothing we can do
-		moveq	pc, lr
-		.endm
-
-		.macro	senduart,rd,rx
-		str	\rd, [\rx, #UTDR]
-		.endm
-
-		.macro	waituart,rd,rx
-1001:		ldr	\rd, [\rx, #UTSR1]
-		tst	\rd, #UTSR1_TNF
-		beq	1001b
-		.endm
-
-		.macro	busyuart,rd,rx
-1001:		ldr	\rd, [\rx, #UTSR1]
-		tst	\rd, #UTSR1_TBY
-		bne	1001b
-		.endm
-
-#elif defined(CONFIG_ARCH_PXA)
-
-		.macro	addruart,rx
-		mrc	p15, 0, \rx, c1, c0
-		tst	\rx, #1			@ MMU enabled?
-		moveq	\rx, #0x40000000		@ physical
-		movne	\rx, #io_p2v(0x40000000)	@ virtual
-		orr	\rx, \rx, #0x00100000
-		.endm
-
-		.macro	senduart,rd,rx
-		str	\rd, [\rx, #0]
-		.endm
-
-		.macro	busyuart,rd,rx
-1002:		ldr	\rd, [\rx, #0x14]
-		tst	\rd, #(1 << 6)
-		beq	1002b
-		.endm
-
-		.macro	waituart,rd,rx
-1001:		ldr	\rd, [\rx, #0x14]
-		tst	\rd, #(1 << 5)
-		beq	1001b
-		.endm
-#elif defined(CONFIG_ARCH_CLPS7500)
-		.macro	addruart,rx
-		mov	\rx, #0xe0000000
-		orr	\rx, \rx, #0x00010000
-		orr	\rx, \rx, #0x00000be0
-		.endm
-
-		.macro	senduart,rd,rx
-		strb	\rd, [\rx]
-		.endm
-
-		.macro	busyuart,rd,rx
-		.endm
-
-		.macro	waituart,rd,rx
-1001:		ldrb	\rd, [\rx, #0x14]
-		tst	\rd, #0x20
-		beq	1001b
-		.endm
-
-#elif defined(CONFIG_ARCH_L7200)
-
-		.equ	io_virt, IO_BASE
-		.equ	io_phys, IO_START
-
-		.macro	addruart,rx
-		mrc	p15, 0, \rx, c1, c0
-		tst	\rx, #1			@ MMU enabled?
-		moveq	\rx, #io_phys		@ physical base address
-		movne	\rx, #io_virt		@ virtual address
-		add	\rx, \rx, #0x00044000	@ UART1
-@		add	\rx, \rx, #0x00045000	@ UART2
-		.endm
-
-		.macro	senduart,rd,rx
-		str	\rd, [\rx, #0x0]	@ UARTDR
-		.endm
-
-		.macro	waituart,rd,rx
-1001:		ldr	\rd, [\rx, #0x18]	@ UARTFLG
-		tst	\rd, #1 << 5		@ UARTFLGUTXFF - 1 when full
-		bne	1001b
-		.endm
-
-		.macro	busyuart,rd,rx
-1001:		ldr	\rd, [\rx, #0x18]	@ UARTFLG
-		tst	\rd, #1 << 3		@ UARTFLGUBUSY - 1 when busy
-		bne	1001b
-		.endm
-
-#elif defined(CONFIG_ARCH_INTEGRATOR)
-
-#include <asm/hardware/amba_serial.h>
-
-		.macro	addruart,rx
-		mrc	p15, 0, \rx, c1, c0
-		tst	\rx, #1			@ MMU enabled?
-		moveq	\rx, #0x16000000	@ physical base address
-		movne	\rx, #0xf0000000	@ virtual base
-		addne	\rx, \rx, #0x16000000 >> 4
-		.endm
-
-		.macro	senduart,rd,rx
-		strb	\rd, [\rx, #UART01x_DR]
-		.endm
-
-		.macro	waituart,rd,rx
-1001:		ldr	\rd, [\rx, #0x18]	@ UARTFLG
-		tst	\rd, #1 << 5		@ UARTFLGUTXFF - 1 when full
-		bne	1001b
-		.endm
-
-		.macro	busyuart,rd,rx
-1001:		ldr	\rd, [\rx, #0x18]	@ UARTFLG
-		tst	\rd, #1 << 3		@ UARTFLGUBUSY - 1 when busy
-		bne	1001b
-		.endm
-
-#elif defined(CONFIG_ARCH_CLPS711X)
-
-#include <asm/hardware/clps7111.h>
-
-		.macro	addruart,rx
-		mrc	p15, 0, \rx, c1, c0
-		tst	\rx, #1			@ MMU enabled?
-		moveq	\rx, #CLPS7111_PHYS_BASE
-		movne	\rx, #CLPS7111_VIRT_BASE
-#ifndef CONFIG_DEBUG_CLPS711X_UART2
-		add	\rx, \rx, #0x0000	@ UART1
-#else
-		add	\rx, \rx, #0x1000	@ UART2
-#endif
-		.endm
-
-		.macro	senduart,rd,rx
-		str	\rd, [\rx, #0x0480]	@ UARTDR
-		.endm
-
-		.macro	waituart,rd,rx
-1001:		ldr	\rd, [\rx, #0x0140]	@ SYSFLGx
-		tst	\rd, #1 << 11		@ UBUSYx
-		bne	1001b
-		.endm
-
-		.macro	busyuart,rd,rx
-		tst	\rx, #0x1000		@ UART2 does not have CTS here
-		bne	1002f
-1001:		ldr	\rd, [\rx, #0x0140]	@ SYSFLGx
-		tst	\rd, #1 << 8		@ CTS
-		bne	1001b
-1002:
-		.endm
-
-#elif defined(CONFIG_ARCH_CAMELOT)
-
-#include <asm/arch/excalibur.h>
-#define UART00_TYPE
-#include <asm/arch/uart00.h>
-
-		.macro	addruart,rx
-		mrc	p15, 0, \rx, c1, c0
-		tst	\rx, #1			@ MMU enabled?
-		ldr	\rx, =EXC_UART00_BASE	@ physical base address
-		orrne	\rx, \rx, #0xff000000	@ virtual base
-		orrne	\rx, \rx, #0x00f00000	
-		.endm
-
-		.macro	senduart,rd,rx
-		str	\rd, [\rx, #UART_TD(0)]
-		.endm
-
-		.macro	waituart,rd,rx
-1001:		ldr	\rd, [\rx, #UART_TSR(0)]
-		and 	\rd, \rd,  #UART_TSR_TX_LEVEL_MSK
-		cmp	\rd, #15
-		beq	1001b
-		.endm
-
-		.macro	busyuart,rd,rx
-1001:		ldr	\rd, [\rx, #UART_TSR(0)]
-		ands 	\rd, \rd,  #UART_TSR_TX_LEVEL_MSK
-		bne	1001b
-		.endm
-
-#elif defined(CONFIG_ARCH_IOP3XX)
-
-		.macro	addruart,rx
-		mov	\rx, #0xfe000000	@ physical
-#if defined(CONFIG_ARCH_IQ80321) || defined(CONFIG_ARCH_IQ31244)
-		orr	\rx, \rx, #0x00800000	@ location of the UART
-#elif defined(CONFIG_ARCH_IOP331)
-		mrc	p15, 0, \rx, c1, c0
-		tst	\rx, #1			@ MMU enabled?
-		moveq	\rx, #0x000fe000	@ Physical Base
-		movne	\rx, #0
-		orr	\rx, \rx, #0xfe000000
-		orr	\rx, \rx, #0x00f00000	@ Virtual Base
-		orr	\rx, \rx, #0x00001700   @ location of the UART
-#else
-#error Unknown IOP3XX implementation
-#endif
-		.endm
-
-		.macro	senduart,rd,rx
-		strb	\rd, [\rx]
-		.endm
-
-		.macro	busyuart,rd,rx
-1002:		ldrb	\rd, [\rx, #0x5]
-		and	\rd, \rd, #0x60
-		teq	\rd, #0x60
-		bne	1002b
-		.endm
-
-		.macro	waituart,rd,rx
-#if !defined(CONFIG_ARCH_IQ80321) || !defined(CONFIG_ARCH_IQ31244) || !defined(CONFIG_ARCH_IQ80331)
-1001:		ldrb	\rd, [\rx, #0x6]
-		tst	\rd, #0x10
-		beq	1001b
-#endif
-		.endm
-
-#elif defined(CONFIG_ARCH_IXP4XX)
-
-                .macro  addruart,rx
-                mrc     p15, 0, \rx, c1, c0
-                tst     \rx, #1                 @ MMU enabled?
-                moveq   \rx, #0xc8000000
-                movne   \rx, #0xff000000
-                add     \rx,\rx,#3              @ Uart regs are at off set of 3 if
-						@ byte writes used - Big Endian.
-                .endm
-
-               .macro  senduart,rd,rx
-                strb    \rd, [\rx]
-                .endm
-
-                .macro  waituart,rd,rx
-1002:           ldrb    \rd, [\rx, #0x14]
-                and     \rd, \rd, #0x60		@ check THRE and TEMT bits
-                teq     \rd, #0x60
-                bne     1002b
-                .endm
-
-                .macro  busyuart,rd,rx
-                .endm
-
-#elif defined(CONFIG_ARCH_IXP2000)
-
-		.macro  addruart,rx
-		mrc	p15, 0, \rx, c1, c0
-		tst	\rx, #1			@ MMU enabled?
-		moveq	\rx, #0xc0000000	@ Physical base
-		movne	\rx, #0xfe000000	@ virtual base
-		orrne	\rx, \rx, #0x00f00000
-		orr	\rx, \rx, #0x00030000
-#ifdef	__ARMEB__
-		orr	\rx, \rx, #0x00000003
-#endif
-		.endm 
-		
-		.macro	senduart,rd,rx
-		strb	\rd, [\rx]
-		.endm
-
-		.macro	busyuart,rd,rx
-1002:		ldrb	\rd, [\rx, #0x14]
-		tst	\rd, #0x20       
-		beq	1002b
-		.endm
-
-		.macro	waituart,rd,rx
-		nop
-		nop
-		nop
-		.endm
-
-#elif defined(CONFIG_ARCH_OMAP)
-
-		.macro	addruart,rx
-		mrc	p15, 0, \rx, c1, c0
-		tst	\rx, #1			@ MMU enabled?
-		moveq	\rx, #0xff000000	@ physical base address
-		movne	\rx, #0xfe000000	@ virtual base
-		orr	\rx, \rx, #0x00fb0000
-#ifdef CONFIG_OMAP_LL_DEBUG_UART3
-		orr	\rx, \rx, #0x00009000	@ UART 3
-#endif
-#if defined(CONFIG_OMAP_LL_DEBUG_UART2) || defined(CONFIG_OMAP_LL_DEBUG_UART3)
-		orr	\rx, \rx, #0x00000800	@ UART 2 & 3
-#endif
-		.endm
-
-		.macro	senduart,rd,rx
-		strb	\rd, [\rx]
-		.endm
-
-		.macro	busyuart,rd,rx
-1001:		ldrb	\rd, [\rx, #(0x5 << 2)]	@ OMAP-1510 and friends
-		and	\rd, \rd, #0x60
-		teq	\rd, #0x60
-		beq	1002f
-		ldrb	\rd, [\rx, #(0x5 << 0)]	@ OMAP-730 only
-		and	\rd, \rd, #0x60
-		teq	\rd, #0x60
-		bne	1001b
-1002:
-		.endm
-
-		.macro	waituart,rd,rx
-		.endm
-
-#elif defined(CONFIG_ARCH_S3C2410)
-#include <asm/arch/map.h>
-#include <asm/arch/regs-serial.h>
-#include <asm/arch/regs-gpio.h>
-#define S3C2410_UART1_OFF (0x4000)
-#define SHIFT_2440TXF (14-9)
-
-		.macro addruart, rx
-		mrc	p15, 0, \rx, c1, c0
-		tst	\rx, #1
-		ldreq	\rx, = S3C2410_PA_UART
-		ldrne	\rx, = S3C2410_VA_UART
-#if CONFIG_DEBUG_S3C2410_UART != 0
-		add	\rx, \rx, #(S3C2410_UART1_OFF * CONFIG_DEBUG_S3C2410_UART)
-#endif
-		.endm
-
-		.macro	senduart,rd,rx
-		str	\rd, [\rx, # S3C2410_UTXH ]
-		.endm
-
-		.macro	busyuart, rd, rx
-		ldr	\rd, [ \rx, # S3C2410_UFCON ]
-		tst	\rd, #S3C2410_UFCON_FIFOMODE	@ fifo enabled?
-		beq	1001f				@
-		@ FIFO enabled...
-1003:
-		mrc	p15, 0, \rd, c1, c0
-		tst	\rd, #1
-		addeq	\rd, \rx, #(S3C2410_PA_GPIO - S3C2410_PA_UART)
-		addne	\rd, \rx, #(S3C2410_VA_GPIO - S3C2410_VA_UART)
-		bic	\rd, \rd, #0xff000
-		ldr	\rd, [ \rd, # S3C2410_GSTATUS1 - S3C2410_GPIOREG(0) ]
-		and	\rd, \rd, #0x00ff0000
-		teq	\rd, #0x00440000		@ is it 2440?
-
-		ldr	\rd, [ \rx, # S3C2410_UFSTAT ]
-		moveq	\rd, \rd, lsr #SHIFT_2440TXF
-		tst	\rd, #S3C2410_UFSTAT_TXFULL
-		bne	1003b
-		b	1002f
-
-1001:
-		@ busy waiting for non fifo
-		ldr	\rd, [ \rx, # S3C2410_UTRSTAT ]
-		tst	\rd, #S3C2410_UTRSTAT_TXFE
-		beq	1001b
-
-1002:		@ exit busyuart
-		.endm
-
-		.macro	waituart,rd,rx
-
-		ldr	\rd, [ \rx, # S3C2410_UFCON ]
-		tst	\rd, #S3C2410_UFCON_FIFOMODE	@ fifo enabled?
-		beq	1001f				@
-		@ FIFO enabled...
-1003:
-		mrc	p15, 0, \rd, c1, c0
-		tst	\rd, #1
-		addeq	\rd, \rx, #(S3C2410_PA_GPIO - S3C2410_PA_UART)
-		addne	\rd, \rx, #(S3C2410_VA_GPIO - S3C2410_VA_UART)
-		bic	\rd, \rd, #0xff000
-		ldr	\rd, [ \rd, # S3C2410_GSTATUS1 - S3C2410_GPIOREG(0) ]
-		and	\rd, \rd, #0x00ff0000
-		teq	\rd, #0x00440000		@ is it 2440?
-
-		ldr	\rd, [ \rx, # S3C2410_UFSTAT ]
-		andne	\rd, \rd, #S3C2410_UFSTAT_TXMASK
-		andeq	\rd, \rd, #S3C2440_UFSTAT_TXMASK
-		teq	\rd, #0
-		bne	1003b
-		b	1002f
-
-1001:
-		@ idle waiting for non fifo
-		ldr	\rd, [ \rx, # S3C2410_UTRSTAT ]
-		tst	\rd, #S3C2410_UTRSTAT_TXFE
-		beq	1001b
-
-1002:		@ exit busyuart
-		.endm
-
-#elif defined(CONFIG_ARCH_LH7A40X)
-	@ It is not known if this will be appropriate for every 40x
-	@ board.
-
-		.macro  addruart,rx
-		mrc     p15, 0, \rx, c1, c0
-		tst     \rx, #1                 @ MMU enabled?
-		mov     \rx, #0x00000700        @ offset from base
-		orreq   \rx, \rx, #0x80000000   @ physical base
-		orrne   \rx, \rx, #0xf8000000   @ virtual base
-		.endm
-
-		.macro  senduart,rd,rx
-		strb    \rd, [\rx]              @ DATA
-		.endm
-
-		.macro  busyuart,rd,rx          @ spin while busy
-1001:		ldr     \rd, [\rx, #0x10]       @ STATUS
-		tst     \rd, #1 << 3            @ BUSY (TX FIFO not empty)
-		bne     1001b                   @ yes, spin
-		.endm
-
-		.macro  waituart,rd,rx          @ wait for Tx FIFO room
-1001:		ldrb    \rd, [\rx, #0x10]       @ STATUS
-		tst     \rd, #1 << 5            @ TXFF (TX FIFO full)
-		bne     1001b                   @ yes, spin
-		.endm
-
-
-#elif defined(CONFIG_ARCH_VERSATILE)
-
-#include <asm/hardware/amba_serial.h>
-
-		.macro	addruart,rx
-		mrc	p15, 0, \rx, c1, c0
-		tst	\rx, #1			@ MMU enabled?
-		moveq	\rx,      #0x10000000
-		movne	\rx,      #0xf1000000	@ virtual base
-		orr	\rx, \rx, #0x001F0000
-		orr	\rx, \rx, #0x00001000
-		.endm
-
-		.macro	senduart,rd,rx
-		strb	\rd, [\rx, #UART01x_DR]
-		.endm
-
-		.macro	waituart,rd,rx
-1001:		ldr	\rd, [\rx, #0x18]	@ UARTFLG
-		tst	\rd, #1 << 5		@ UARTFLGUTXFF - 1 when full
-		bne	1001b
-		.endm
-
-		.macro	busyuart,rd,rx
-1001:		ldr	\rd, [\rx, #0x18]	@ UARTFLG
-		tst	\rd, #1 << 3		@ UARTFLGUBUSY - 1 when busy
-		bne	1001b
-		.endm
-
-#elif defined(CONFIG_ARCH_IMX)
-
-		.macro	addruart,rx
-		mrc	p15, 0, \rx, c1, c0
-		tst	\rx, #1			@ MMU enabled?
-		moveq	\rx, #0x00000000	@ physical
-		movne	\rx, #0xe0000000	@ virtual
-		orr	\rx, \rx, #0x00200000
-		orr	\rx, \rx, #0x00006000	@ UART1 offset
-		.endm
-
-		.macro	senduart,rd,rx
-		str	\rd, [\rx, #0x40]	@ TXDATA
-		.endm
-
-		.macro	waituart,rd,rx
-		.endm
-
-		.macro	busyuart,rd,rx
-1002:		ldr	\rd, [\rx, #0x98]	@ SR2
-		tst	\rd, #1 << 3		@ TXDC
-		beq	1002b			@ wait until transmit done
-		.endm
-
-#elif defined(CONFIG_ARCH_H720X)
-
-		.equ    io_virt, IO_BASE
-		.equ    io_phys, IO_START
-
-		.macro  addruart,rx
-		mrc     p15, 0, \rx, c1, c0
-		tst     \rx, #1  	       @ MMU enabled?
-		moveq   \rx, #io_phys	       @ physical base address
-		movne   \rx, #io_virt	       @ virtual address
-		add     \rx, \rx, #0x00020000   @ UART1
-		.endm
-
-		.macro  senduart,rd,rx
-		str     \rd, [\rx, #0x0]        @ UARTDR
-
-		.endm
-
-		.macro  waituart,rd,rx
-1001:		ldr     \rd, [\rx, #0x18]       @ UARTFLG
-		tst     \rd, #1 << 5	       @ UARTFLGUTXFF - 1 when full
-		bne     1001b
-		.endm
-
-		.macro  busyuart,rd,rx
-1001:		ldr     \rd, [\rx, #0x18]       @ UARTFLG
-		tst     \rd, #1 << 3	       @ UARTFLGUBUSY - 1 when busy
-		bne     1001b
-		.endm
 #else
-#error Unknown architecture
+#include <asm/arch/debug-macro.S>
 #endif
 
 /*
diff -Nru a/arch/arm/kernel/dma.c b/arch/arm/kernel/dma.c
--- a/arch/arm/kernel/dma.c	2005-03-01 23:39:08 -08:00
+++ b/arch/arm/kernel/dma.c	2005-03-01 23:39:08 -08:00
@@ -22,7 +22,7 @@
 
 #include <asm/mach/dma.h>
 
-spinlock_t dma_spin_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(dma_spin_lock);
 
 #if MAX_DMA_CHANNELS > 0
 
diff -Nru a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
--- a/arch/arm/kernel/entry-armv.S	2005-03-01 23:38:54 -08:00
+++ b/arch/arm/kernel/entry-armv.S	2005-03-01 23:38:54 -08:00
@@ -23,1273 +23,362 @@
 
 #include "entry-header.S"
 
-#ifdef IOC_BASE
-/* IOC / IOMD based hardware */
-#include <asm/hardware/iomd.h>
-
-		.equ	ioc_base_high, IOC_BASE & 0xff000000
-		.equ	ioc_base_low, IOC_BASE & 0x00ff0000
-		.macro	disable_fiq
-		mov	r12, #ioc_base_high
-		.if	ioc_base_low
-		orr	r12, r12, #ioc_base_low
-		.endif
-		strb	r12, [r12, #0x38]	@ Disable FIQ register
-		.endm
-
-		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
-		mov	r4, #ioc_base_high		@ point at IOC
-		.if	ioc_base_low
-		orr	r4, r4, #ioc_base_low
-		.endif
-		ldrb	\irqstat, [r4, #IOMD_IRQREQB]	@ get high priority first
-		ldr	\base, =irq_prio_h
-		teq	\irqstat, #0
-#ifdef IOMD_BASE
-		ldreqb	\irqstat, [r4, #IOMD_DMAREQ]	@ get dma
-		addeq	\base, \base, #256		@ irq_prio_h table size
-		teqeq	\irqstat, #0
-		bne	2406f
-#endif
-		ldreqb	\irqstat, [r4, #IOMD_IRQREQA]	@ get low priority
-		addeq	\base, \base, #256		@ irq_prio_d table size
-		teqeq	\irqstat, #0
-#ifdef IOMD_IRQREQC
-		ldreqb	\irqstat, [r4, #IOMD_IRQREQC]
-		addeq	\base, \base, #256		@ irq_prio_l table size
-		teqeq	\irqstat, #0
-#endif
-#ifdef IOMD_IRQREQD
-		ldreqb	\irqstat, [r4, #IOMD_IRQREQD]
-		addeq	\base, \base, #256		@ irq_prio_lc table size
-		teqeq	\irqstat, #0
-#endif
-2406:		ldrneb	\irqnr, [\base, \irqstat]	@ get IRQ number
-		.endm
-
-/*
- * Interrupt table (incorporates priority).  Please note that we
- * rely on the order of these tables (see above code).
- */
-		.macro	irq_prio_table
-irq_prio_h:	.byte	 0, 8, 9, 8,10,10,10,10,11,11,11,11,10,10,10,10
-		.byte	12, 8, 9, 8,10,10,10,10,11,11,11,11,10,10,10,10
-		.byte	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
-		.byte	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
-		.byte	14,14,14,14,10,10,10,10,11,11,11,11,10,10,10,10
-		.byte	14,14,14,14,10,10,10,10,11,11,11,11,10,10,10,10
-		.byte	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
-		.byte	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
-		.byte	15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
-		.byte	15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
-		.byte	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
-		.byte	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
-		.byte	15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
-		.byte	15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
-		.byte	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
-		.byte	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
-#ifdef IOMD_BASE
-irq_prio_d:	.byte	 0,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
-		.byte	20,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
-		.byte	21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
-		.byte	21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
-		.byte	22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
-		.byte	22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
-		.byte	21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
-		.byte	21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
-		.byte	23,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
-		.byte	23,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
-		.byte	21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
-		.byte	21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
-		.byte	22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
-		.byte	22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
-		.byte	21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
-		.byte	21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
-#endif
-irq_prio_l:	.byte	 0, 0, 1, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3
-		.byte	 4, 0, 1, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3
-		.byte	 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
-		.byte	 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
-		.byte	 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3
-		.byte	 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3
-		.byte	 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
-		.byte	 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
-		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
-		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
-		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
-		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
-		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
-		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
-		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
-		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
-#ifdef IOMD_IRQREQC
-irq_prio_lc:	.byte	24,24,25,24,26,26,26,26,27,27,27,27,27,27,27,27
-		.byte	28,24,25,24,26,26,26,26,27,27,27,27,27,27,27,27
-		.byte	29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29
-		.byte	29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29
-		.byte	30,30,30,30,30,30,30,30,27,27,27,27,27,27,27,27
-		.byte	30,30,30,30,30,30,30,30,27,27,27,27,27,27,27,27
-		.byte	29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29
-		.byte	29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29
-		.byte	31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
-		.byte	31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
-		.byte	31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
-		.byte	31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
-		.byte	31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
-		.byte	31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
-		.byte	31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
-		.byte	31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
-#endif
-#ifdef IOMD_IRQREQD
-irq_prio_ld:	.byte	40,40,41,40,42,42,42,42,43,43,43,43,43,43,43,43
-		.byte	44,40,41,40,42,42,42,42,43,43,43,43,43,43,43,43
-		.byte	45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45
-		.byte	45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45
-		.byte	46,46,46,46,46,46,46,46,43,43,43,43,43,43,43,43
-		.byte	46,46,46,46,46,46,46,46,43,43,43,43,43,43,43,43
-		.byte	45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45
-		.byte	45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45
-		.byte	47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
-		.byte	47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
-		.byte	47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
-		.byte	47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
-		.byte	47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
-		.byte	47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
-		.byte	47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
-		.byte	47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
-#endif
-		.endm
-
-#elif defined(CONFIG_ARCH_EBSA110)
-
-#define IRQ_STAT		0xff000000	/* read */
-
-		.macro	disable_fiq
-		.endm
-
-		.macro	get_irqnr_and_base, irqnr, stat, base, tmp
-		mov	\base, #IRQ_STAT
-		ldrb	\stat, [\base]			@ get interrupts
-		mov	\irqnr, #0
-		tst	\stat, #15
-		addeq	\irqnr, \irqnr, #4
-		moveq	\stat, \stat, lsr #4
-		tst	\stat, #3
-		addeq	\irqnr, \irqnr, #2
-		moveq	\stat, \stat, lsr #2
-		tst	\stat, #1
-		addeq	\irqnr, \irqnr, #1
-		moveq	\stat, \stat, lsr #1
-		tst	\stat, #1			@ bit 0 should be set
-		.endm
-
-		.macro	irq_prio_table
-		.endm
-
-#elif defined(CONFIG_ARCH_SHARK)
-
-		.macro	disable_fiq
-		.endm
-
-		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
-		mov	r4, #0xe0000000
-
-		mov	\irqstat, #0x0C
-		strb	\irqstat, [r4, #0x20]		@outb(0x0C, 0x20) /* Poll command */
-		ldrb	\irqnr, [r4, #0x20]		@irq = inb(0x20) & 7
-		and	\irqstat, \irqnr, #0x80
-		teq	\irqstat, #0
-		beq	43f
-		and	\irqnr, \irqnr, #7
-		teq	\irqnr, #2
-		bne	44f
-43:		mov	\irqstat, #0x0C
-		strb	\irqstat, [r4, #0xa0]		@outb(0x0C, 0xA0) /* Poll command */
-		ldrb	\irqnr, [r4, #0xa0]		@irq = (inb(0xA0) & 7) + 8
-		and	\irqstat, \irqnr, #0x80
-		teq	\irqstat, #0
-		beq	44f
-		and	\irqnr, \irqnr, #7
-		add	\irqnr, \irqnr, #8
-44:		teq	\irqstat, #0
-		.endm
-
-		.macro	irq_prio_table
-		.endm
-
-#elif defined(CONFIG_FOOTBRIDGE)
-#include <asm/hardware/dec21285.h>
-
-		.macro	disable_fiq
-		.endm
-
-		.equ	dc21285_high, ARMCSR_BASE & 0xff000000
-		.equ	dc21285_low, ARMCSR_BASE & 0x00ffffff
-
-		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
-		mov	r4, #dc21285_high
-		.if	dc21285_low
-		orr	r4, r4, #dc21285_low
-		.endif
-		ldr	\irqstat, [r4, #0x180]		@ get interrupts
-
-		mov	\irqnr, #IRQ_SDRAMPARITY
-		tst	\irqstat, #IRQ_MASK_SDRAMPARITY
-		bne	1001f
-
-		tst	\irqstat, #IRQ_MASK_UART_RX
-		movne	\irqnr, #IRQ_CONRX
-		bne	1001f
-
-		tst	\irqstat, #IRQ_MASK_DMA1
-		movne	\irqnr, #IRQ_DMA1
-		bne	1001f
-
-		tst	\irqstat, #IRQ_MASK_DMA2
-		movne	\irqnr, #IRQ_DMA2
-		bne	1001f
-
-		tst	\irqstat, #IRQ_MASK_IN0
-		movne	\irqnr, #IRQ_IN0
-		bne	1001f
-
-		tst	\irqstat, #IRQ_MASK_IN1
-		movne	\irqnr, #IRQ_IN1
-		bne	1001f
-
-		tst	\irqstat, #IRQ_MASK_IN2
-		movne	\irqnr, #IRQ_IN2
-		bne	1001f
-
-		tst	\irqstat, #IRQ_MASK_IN3
-		movne	\irqnr, #IRQ_IN3
-		bne	1001f
-
-		tst	\irqstat, #IRQ_MASK_PCI
-		movne	\irqnr, #IRQ_PCI
-		bne	1001f
-
-		tst	\irqstat, #IRQ_MASK_DOORBELLHOST
-		movne	\irqnr, #IRQ_DOORBELLHOST
-		bne     1001f
-	
-		tst	\irqstat, #IRQ_MASK_I2OINPOST
-		movne	\irqnr, #IRQ_I2OINPOST
-		bne	1001f
-
-		tst	\irqstat, #IRQ_MASK_TIMER1
-		movne	\irqnr, #IRQ_TIMER1
-		bne	1001f
-
-		tst	\irqstat, #IRQ_MASK_TIMER2
-		movne	\irqnr, #IRQ_TIMER2
-		bne	1001f
-
-		tst	\irqstat, #IRQ_MASK_TIMER3
-		movne	\irqnr, #IRQ_TIMER3
-		bne	1001f
-
-		tst	\irqstat, #IRQ_MASK_UART_TX
-		movne	\irqnr, #IRQ_CONTX
-		bne	1001f
-
-		tst	\irqstat, #IRQ_MASK_PCI_ABORT
-		movne	\irqnr, #IRQ_PCI_ABORT
-		bne	1001f
-
-		tst	\irqstat, #IRQ_MASK_PCI_SERR
-		movne	\irqnr, #IRQ_PCI_SERR
-		bne	1001f
-
-		tst	\irqstat, #IRQ_MASK_DISCARD_TIMER
-		movne	\irqnr, #IRQ_DISCARD_TIMER
-		bne	1001f
-
-		tst	\irqstat, #IRQ_MASK_PCI_DPERR
-		movne	\irqnr, #IRQ_PCI_DPERR
-		bne	1001f
-
-		tst	\irqstat, #IRQ_MASK_PCI_PERR
-		movne	\irqnr, #IRQ_PCI_PERR
-1001:
-		.endm
-
-		.macro	irq_prio_table
-		.endm
-
-#elif defined(CONFIG_ARCH_NEXUSPCI)
-
-		.macro	disable_fiq
-		.endm
-
-		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
-		ldr	\irqstat, =INTCONT_BASE
-		ldr	\base, =soft_irq_mask
-		ldr	\irqstat, [\irqstat]		@ get interrupts
-		ldr	\base, [\base]
-		mov	\irqnr, #0
-		and	\irqstat, \irqstat, \base	@ mask out disabled ones
-1001:		tst	\irqstat, #1
-		addeq	\irqnr, \irqnr, #1
-		moveq	\irqstat, \irqstat, lsr #1
-		tsteq	\irqnr, #32
-		beq	1001b
-		teq	\irqnr, #32
-		.endm
-
-		.macro	irq_prio_table
-		.ltorg
-		.bss
-ENTRY(soft_irq_mask)
-		.word	0
-		.text
-		.endm
-
-#elif defined(CONFIG_ARCH_TBOX)
-
-		.macro	disable_fiq
-		.endm
-
-		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
-		ldr	\irqstat, =0xffff7000
-		ldr	\irqstat, [\irqstat]		@ get interrupts
-		ldr	\base, =soft_irq_mask
-		ldr	\base, [\base]
-		mov	\irqnr, #0
-		and	\irqstat, \irqstat, \base	@ mask out disabled ones
-1001:		tst	\irqstat, #1
-		addeq	\irqnr, \irqnr, #1
-		moveq	\irqstat, \irqstat, lsr #1
-		tsteq	\irqnr, #32
-		beq	1001b
-		teq	\irqnr, #32
-		.endm
-
-		.macro	irq_prio_table
-		.ltorg
-		.bss
-ENTRY(soft_irq_mask)
-		.word	0
-		.text
-		.endm
-
-#elif defined(CONFIG_ARCH_SA1100)
-
-		.macro	disable_fiq
-		.endm
-
-		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
-		mov	r4, #0xfa000000			@ ICIP = 0xfa050000
-		add	r4, r4, #0x00050000
-		ldr	\irqstat, [r4]			@ get irqs
-		ldr	\irqnr, [r4, #4]		@ ICMR = 0xfa050004
-		ands	\irqstat, \irqstat, \irqnr
-		mov	\irqnr, #0
-		beq	1001f
-		tst	\irqstat, #0xff
-		moveq	\irqstat, \irqstat, lsr #8
-		addeq	\irqnr, \irqnr, #8
-		tsteq	\irqstat, #0xff
-		moveq	\irqstat, \irqstat, lsr #8
-		addeq	\irqnr, \irqnr, #8
-		tsteq	\irqstat, #0xff
-		moveq	\irqstat, \irqstat, lsr #8
-		addeq	\irqnr, \irqnr, #8
-		tst	\irqstat, #0x0f
-		moveq	\irqstat, \irqstat, lsr #4
-		addeq	\irqnr, \irqnr, #4
-		tst	\irqstat, #0x03
-		moveq	\irqstat, \irqstat, lsr #2
-		addeq	\irqnr, \irqnr, #2
-		tst	\irqstat, #0x01
-		addeqs	\irqnr, \irqnr, #1
-1001:
-		.endm
-
-		.macro	irq_prio_table
-		.endm
-
-#elif defined(CONFIG_ARCH_L7200)
-#include <asm/hardware.h>
-	
-		.equ	irq_base_addr,	IO_BASE_2
-
-		.macro  disable_fiq
-		.endm
- 
-		.macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
-		mov     \irqstat, #irq_base_addr		@ Virt addr IRQ regs
-		add	\irqstat, \irqstat, #0x00001000		@ Status reg
-		ldr     \irqstat, [\irqstat, #0]		@ get interrupts
-		mov     \irqnr, #0
-1001:		tst     \irqstat, #1
-		addeq   \irqnr, \irqnr, #1
-		moveq   \irqstat, \irqstat, lsr #1
-		tsteq   \irqnr, #32
-		beq     1001b
-		teq     \irqnr, #32
-		.endm
-
-		.macro  irq_prio_table
-		.endm
-
-#elif defined(CONFIG_ARCH_INTEGRATOR)
-
-		.macro	disable_fiq
-		.endm
-
-		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
-/* FIXME: should not be using soo many LDRs here */
-		ldr	\base, =IO_ADDRESS(INTEGRATOR_IC_BASE)
-		mov	\irqnr, #IRQ_PIC_START
-		ldr	\irqstat, [\base, #IRQ_STATUS]		@ get masked status
-		ldr	\base, =IO_ADDRESS(INTEGRATOR_HDR_BASE)
-		teq	\irqstat, #0
-		ldreq	\irqstat, [\base, #(INTEGRATOR_HDR_IC_OFFSET+IRQ_STATUS)]
-		moveq	\irqnr, #IRQ_CIC_START
-
-1001:		tst	\irqstat, #15
-		bne	1002f
-		add	\irqnr, \irqnr, #4
-		movs	\irqstat, \irqstat, lsr #4
-		bne	1001b
-1002:		tst	\irqstat, #1
-		bne	1003f
-		add	\irqnr, \irqnr, #1
-		movs	\irqstat, \irqstat, lsr #1
-		bne	1002b
-1003:		/* EQ will be set if no irqs pending */
-		.endm
-
-		.macro	irq_prio_table
-		.endm
-
-#elif defined(CONFIG_ARCH_VERSATILE)
-
-		.macro	disable_fiq
-		.endm
-
-		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
-		ldr	\base, =IO_ADDRESS(VERSATILE_VIC_BASE)
-		ldr	\irqstat, [\base, #VIC_IRQ_STATUS]	@ get masked status
-		mov	\irqnr, #0
-		teq	\irqstat, #0
-		beq	1003f
-
-1001:		tst	\irqstat, #15
-		bne	1002f
-		add	\irqnr, \irqnr, #4
-		movs	\irqstat, \irqstat, lsr #4
-		bne	1001b
-1002:		tst	\irqstat, #1
-		bne	1003f
-		add	\irqnr, \irqnr, #1
-		movs	\irqstat, \irqstat, lsr #1
-		bne	1002b
-1003:		/* EQ will be set if no irqs pending */
-
-@		clz	\irqnr, \irqstat
-@1003:		/* EQ will be set if we reach MAXIRQNUM */
-		.endm
-
-		.macro	irq_prio_table
-		.endm
-
-#elif defined(CONFIG_ARCH_CLPS711X)
-
-#include <asm/hardware/clps7111.h>
-
-		.macro	disable_fiq
-		.endm
-
-#if (INTSR2 - INTSR1) != (INTMR2 - INTMR1)
-#error INTSR stride != INTMR stride
-#endif
-
-		.macro	get_irqnr_and_base, irqnr, stat, base, mask
-		mov	\base, #CLPS7111_BASE
-		ldr	\stat, [\base, #INTSR1]
-		ldr	\mask, [\base, #INTMR1]
-		mov	\irqnr, #4
-		mov	\mask, \mask, lsl #16
-		and	\stat, \stat, \mask, lsr #16
-		movs	\stat, \stat, lsr #4
-		bne	1001f
-
-		add	\base, \base, #INTSR2 - INTSR1
-		ldr	\stat, [\base, #INTSR1]
-		ldr	\mask, [\base, #INTMR1]
-		mov	\irqnr, #16
-		mov	\mask, \mask, lsl #16
-		and	\stat, \stat, \mask, lsr #16
-
-1001:		tst	\stat, #255
-		addeq	\irqnr, \irqnr, #8
-		moveq	\stat, \stat, lsr #8
-		tst	\stat, #15
-		addeq	\irqnr, \irqnr, #4
-		moveq	\stat, \stat, lsr #4
-		tst	\stat, #3
-		addeq	\irqnr, \irqnr, #2
-		moveq	\stat, \stat, lsr #2
-		tst	\stat, #1
-		addeq	\irqnr, \irqnr, #1
-		moveq	\stat, \stat, lsr #1
-		tst	\stat, #1			@ bit 0 should be set
-		.endm
-
-		.macro	irq_prio_table
-		.endm
-	
-#elif defined (CONFIG_ARCH_CAMELOT)
-#include <asm/arch/platform.h>
-#undef IRQ_MODE /* same name defined in asm/proc/ptrace.h */
-#include <asm/arch/int_ctrl00.h>
-	
-		.macro	disable_fiq
-		.endm
-
-		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
-	
-		ldr	\irqstat, =INT_ID(IO_ADDRESS(EXC_INT_CTRL00_BASE))
-		ldr	\irqnr,[\irqstat]		
-		cmp	\irqnr,#0
-		subne	\irqnr,\irqnr,#1
-
-	
-		.endm
-
-		.macro	irq_prio_table
-		.endm
-
-#elif defined(CONFIG_ARCH_IOP321)
-		.macro  disable_fiq
-		.endm
-
-		/*
-		 * Note: only deal with normal interrupts, not FIQ
-		 */
-		.macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
-		mov     \irqnr, #0
-		mrc     p6, 0, \irqstat, c8, c0, 0      @ Read IINTSRC
-		cmp     \irqstat, #0
-		beq     1001f
-		clz     \irqnr, \irqstat
-		mov     \base, #31
-		subs    \irqnr,\base,\irqnr
-		add     \irqnr,\irqnr,#IRQ_IOP321_DMA0_EOT
-1001:
-		.endm
-
-		.macro  irq_prio_table
-		.endm
-
-#elif defined(CONFIG_ARCH_IOP331)
-		.macro  disable_fiq
-		.endm
-
-		/*
-		 * Note: only deal with normal interrupts, not FIQ
-		 */
-		.macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
-		mov     \irqnr, #0
-		mrc     p6, 0, \irqstat, c4, c0, 0      @ Read IINTSRC0
-		cmp     \irqstat, #0
-		bne     1002f
-		mrc     p6, 0, \irqstat, c5, c0, 0      @ Read IINTSRC1
-		cmp	\irqstat, #0
-		beq	1001f
-		clz	\irqnr, \irqstat
-/*
- *		mov	\base, #31
- *		subs	\irqnr,\base,\irqnr
- */
-        rsbs    \irqnr,\irqnr,#31   @ recommend by RMK
-		add	\irqnr,\irqnr,#IRQ_IOP331_XINT8
-		b	1001f
-1002:		clz     \irqnr, \irqstat
-		mov     \base, #31
-		subs    \irqnr,\base,\irqnr
-		add     \irqnr,\irqnr,#IRQ_IOP331_DMA0_EOT
-1001:
-		.endm
-
-		.macro  irq_prio_table
-		.endm
-
-#elif defined(CONFIG_ARCH_PXA)
-
-		.macro	disable_fiq
-		.endm
-
-		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
-#ifdef CONFIG_PXA27x
-		mrc	p6, 0, \irqstat, c0, c0, 0		@ ICIP
-		mrc	p6, 0, \irqnr, c1, c0, 0		@ ICMR
-#else
-		mov	\base, #io_p2v(0x40000000)	@ IIR Ctl = 0x40d00000
-		add	\base, \base, #0x00d00000
-		ldr	\irqstat, [\base, #0]		@ ICIP
-		ldr	\irqnr, [\base, #4]		@ ICMR
-#endif
-		ands	\irqnr, \irqstat, \irqnr
-		beq	1001f
-		rsb	\irqstat, \irqnr, #0
-		and	\irqstat, \irqstat, \irqnr
-		clz	\irqnr, \irqstat
-		rsb	\irqnr, \irqnr, #(31 - PXA_IRQ_SKIP)
-1001:
-		.endm
-
-		.macro	irq_prio_table
-		.endm
-
-#elif defined(CONFIG_ARCH_IXP2000)
-
-		.macro  disable_fiq
-		.endm
-
-		.macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
-		
-		mov	\irqnr, #0x0              @clear out irqnr as default
-                mov	\base, #0xfe000000        
-		orr	\base, \base, #0x00ff0000
-		orr	\base, \base, #0x0000a000
-		orr	\base, \base, #0x08
-		ldr	\irqstat, [\base]         @ get interrupts 
-		mov	\tmp, #IXP2000_VALID_IRQ_MASK & 0xff000000
-		orr	\tmp, \tmp, #IXP2000_VALID_IRQ_MASK & 0x00ff0000
-		orr	\tmp, \tmp, #IXP2000_VALID_IRQ_MASK & 0x0000ff00
-		orr	\tmp, \tmp, #IXP2000_VALID_IRQ_MASK & 0x000000ff
-		and	\irqstat, \irqstat, \tmp
-
-		cmp	\irqstat, #0
-		beq	1001f	
-
-		clz     \irqnr, \irqstat
-		mov     \base, #31
-		subs    \irqnr, \base, \irqnr
-		
-		/*
-		 * We handle PCIA and PCIB here so we don't have an
-		 * extra layer of code just to check these two bits.
-		 */
-		cmp	\irqnr, #IRQ_IXP2000_PCI
-		bne	1001f
-
-		mov	\base, #0xfe000000
-		orr	\base, \base, #0x00fd0000
-		orr	\base, \base, #0x0000e100
-		orr	\base, \base, #0x00000058
-		ldr	\irqstat, [\base]
-
-		mov	\tmp, #(1<<26)
-		tst	\irqstat, \tmp
-		movne	\irqnr, #IRQ_IXP2000_PCIA
-		bne	1001f
-
-		mov	\tmp, #(1<<27)
-		tst	\irqstat, \tmp
-		movne	\irqnr, #IRQ_IXP2000_PCIB
-
-1001:
-		.endm 
-		
-		.macro  irq_prio_table
-		.endm
-
-#elif defined (CONFIG_ARCH_IXP4XX)
-
-		.macro	disable_fiq
-		.endm
-		
-		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
-		ldr	\irqstat, =(IXP4XX_INTC_BASE_VIRT+IXP4XX_ICIP_OFFSET)
-		ldr	\irqstat, [\irqstat]		@ get interrupts
-		cmp	\irqstat, #0
-		beq	1002f
-		clz     \irqnr, \irqstat
-		mov     \base, #31
-		subs    \irqnr, \base, \irqnr
-		
-/*
-1001:		tst	\irqstat, #1
-		addeq	\irqnr, \irqnr, #1
-		moveq	\irqstat, \irqstat, lsr #1
-		tsteq	\irqnr, #32
-		beq	1001b
-		teq	\irqnr, #32
-*/
-1002:
-		.endm
-
-                .macro  irq_prio_table
-                .endm
-
-#elif defined(CONFIG_ARCH_OMAP)
-
-		.macro	disable_fiq
-		.endm
-
-		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
-		ldr	\base, =IO_ADDRESS(OMAP_IH1_BASE)
-		ldr	\irqnr, [\base, #IRQ_ITR_REG_OFFSET]
-		ldr	\tmp, [\base, #IRQ_MIR_REG_OFFSET]
-		mov	\irqstat, #0xffffffff
-		bic	\tmp, \irqstat, \tmp
-		tst	\irqnr, \tmp
-		beq	1510f
-
-		ldr	\irqnr, [\base, #IRQ_SIR_FIQ_REG_OFFSET]
-		cmp	\irqnr, #0
-		ldreq	\irqnr, [\base, #IRQ_SIR_IRQ_REG_OFFSET]
-		cmpeq	\irqnr, #INT_IH2_IRQ
-		ldreq	\base, =IO_ADDRESS(OMAP_IH2_BASE)
-		ldreq	\irqnr, [\base, #IRQ_SIR_IRQ_REG_OFFSET]
-		addeqs	\irqnr, \irqnr, #32
-1510:
-		.endm
-
-		.macro	irq_prio_table
-		.endm
-
-#elif defined(CONFIG_ARCH_S3C2410)
-		/* S3C2410X IRQ Handler, <ben@simtec.co.uk> */
-
-		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
-
-30000:
-		mov	\tmp, #S3C2410_VA_IRQ
-		ldr	\irqnr, [ \tmp, #0x14 ]		@ get irq no
-		teq	\irqnr, #4
-		teqne	\irqnr, #5
-		beq	1002f				@ external irq reg
-		teq	\irqnr, #16
-		beq	1003f				@ lcd controller
-
-		@ debug check to see if interrupt reported is the same
-		@ as the offset....
-
-		teq	\irqnr, #0
-		beq	20002f
-		ldr	\irqstat, [ \tmp, #0x10 ]	@ INTPND
-		mov	\irqstat, \irqstat, lsr \irqnr
-		tst	\irqstat, #1
-		bne	20002f
-
-#if 1
-		stmfd	r13!, { r0 - r4 , r14 }
-		ldr	r1,	[ \tmp, #0x14 ]		@ intoffset
-		ldr	r2,	[ \tmp, #0x10 ]		@ INTPND
-		ldr	r3,	[ \tmp, #0x00 ]		@ SRCPND
-		adr	r0, 20003f
-		bl	printk
-		b	20004f
-#endif
-20003:
-		.ascii	"<7>irq: err - bad offset %d, intpnd=%08x, srcpnd=%08x\n"
-		.byte	0
-		.align	4
-20004:
-		mov	r1, #1
-		mov	\tmp, #S3C2410_VA_IRQ
-		ldmfd	r13!, { r0 - r4 , r14 }
-
-		@ try working out interript number for ourselves
-		mov	\irqnr, #0
-		ldr	\irqstat, [ \tmp, #0x10 ]	@ INTPND
-10021:
-		movs	\irqstat, \irqstat, lsr#1
-		bcs	30000b		@ try and re-start the proccess
-		add	\irqnr, \irqnr, #1
-		cmp	\irqnr, #32
-		ble	10021b
-
-		@ found no interrupt, set Z flag and leave
-		movs	\irqnr, #0
-		b	1001f
-
-20005:
-20002:		@ exit
-		@ we base the s3c2410x interrupts at 16 and above to allow
-		@ isa peripherals to have their standard interrupts, also
-		@ ensure that Z flag is un-set on exit
-
-		@ note, we cannot be sure if we get IRQ_EINT0 (0) that
-		@ there is simply no interrupt pending, so in all other
-		@ cases we jump to say we have found something, otherwise
-		@ we check to see if the interrupt really is assrted
-		adds	\irqnr, \irqnr, #IRQ_EINT0
-		teq	\irqnr, #IRQ_EINT0
-		bne	1001f				@ exit
-		ldr	\irqstat, [ \tmp, #0x10 ]	@ INTPND
-		teq	\irqstat, #0
-		moveq	\irqnr, #0
-		b	1001f
-
-		@ we get here from no main or external interrupts pending
-1002:
-		add	\tmp, \tmp, #S3C2410_VA_GPIO - S3C2410_VA_IRQ
-		ldr	\irqstat, [ \tmp, # 0xa8 ]	@ EXTINTPEND
-		ldr	\irqnr, [ \tmp, # 0xa4 ]	@ EXTINTMASK
-
-		bic	\irqstat, \irqstat, \irqnr	@ clear masked irqs
-
-		mov	\irqnr, #IRQ_EINT4		@ start extint nos
-		mov	\irqstat, \irqstat, lsr#4	@ ignore bottom 4 bits
-10021:
-		movs	\irqstat, \irqstat, lsr#1
-		bcs	1004f
-		add	\irqnr, \irqnr, #1
-		cmp	\irqnr, #IRQ_EINT23
-		ble	10021b
-
-		@ found no interrupt, set Z flag and leave
-		movs	\irqnr, #0
-		b	1001f
-
-1003:
-		@ lcd interrupt has been asserted...
-		add	\tmp, \tmp, #S3C2410_VA_LCD - S3C2410_VA_IRQ
-		ldr	\irqstat, [ \tmp, # 0x54 ]	@ lcd int pending
-
-		tst	\irqstat, #2
-		movne	\irqnr, #IRQ_LCD_FRAME
-		tst	\irqstat, #1
-		movne	\irqnr, #IRQ_LCD_FIFO
-
-		@ fall through to exit with flags updated
-
-1004:		@ ensure Z flag clear in case our MOVS shifted out the last bit
-		teq	\irqnr, #0
-1001:
-		@ exit irq routine
-		.endm
-
-
-		/* currently don't need an disable_fiq macro */
-
-		.macro	disable_fiq
-		.endm
-
-		/* we don't have an irq priority table */
-		.macro irq_prio_table
-		.endm
-
-#elif defined(CONFIG_ARCH_LH7A400)
-
-# if defined (CONFIG_ARCH_LH7A404)
-#  error "LH7A400 and LH7A404 are mutually exclusive"
-# endif
-		.macro	disable_fiq
-		.endm
-
-		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
-		mov	\irqnr, #0
-		mov	\base, #io_p2v(0x80000000)	@ APB registers
-		ldr	\irqstat, [\base, #0x500]	@ PIC INTSR
-
-1001:		movs	\irqstat, \irqstat, lsr #1	@ Shift into carry
-		bcs	1008f				@ Bit set; irq found
-		add	\irqnr, \irqnr, #1
-		bne	1001b				@ Until no bits
-		b	1009f				@ Nothing?  Hmm.
-1008:		movs	\irqstat, #1			@ Force !Z
-1009:
-               .endm
-
-               .macro  irq_prio_table
-               .endm
-
-#elif defined(CONFIG_ARCH_LH7A404)
-
-		.macro	disable_fiq
-		.endm
-
-		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
-		mov	\irqnr, #0			@ VIC1 irq base
-		mov	\base, #io_p2v(0x80000000)	@ APB registers
-		add	\base, \base, #0x8000
-		ldr	\tmp, [\base, #0x0030]		@ VIC1_VECTADDR
-		tst	\tmp, #VA_VECTORED		@ Direct vectored
-		bne	1002f
-		tst	\tmp, #VA_VIC1DEFAULT		@ Default vectored VIC1
-		ldrne	\irqstat, [\base, #0]		@ VIC1_IRQSTATUS
-		bne	1001f
-		add	\base, \base, #(0xa000 - 0x8000)
-		ldr	\tmp, [\base, #0x0030]		@ VIC2_VECTADDR
-		tst	\tmp, #VA_VECTORED		@ Direct vectored
-		bne	1002f
-		ldr	\irqstat, [\base, #0]		@ VIC2_IRQSTATUS
-		mov	\irqnr, #32			@ VIC2 irq base
-
-1001:		movs	\irqstat, \irqstat, lsr #1	@ Shift into carry
-		bcs	1008f				@ Bit set; irq found
-		add	\irqnr, \irqnr, #1
-		bne	1001b				@ Until no bits
-		b	1009f				@ Nothing?  Hmm.
-1002:		and	\irqnr, \tmp, #0x3f		@ Mask for valid bits
-1008:		movs	\irqstat, #1			@ Force !Z
-		str	\tmp, [\base, #0x0030]		@ Clear vector
-1009:
-               .endm
-
-               .macro  irq_prio_table
-               .endm
-
-#elif defined(CONFIG_ARCH_IMX)
-
-		.macro	disable_fiq
-		.endm
-#define AITC_NIVECSR   0x40
-		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
-		ldr	\irqstat, =IO_ADDRESS(IMX_AITC_BASE)
-		@ Load offset & priority of the highest priority
-		@ interrupt pending.
-		ldr	\irqnr, [\irqstat, #AITC_NIVECSR]
-		@ Shift off the priority leaving the offset or
-		@ "interrupt number"
-		mov	\irqnr, \irqnr, lsr #16
- 		ldr	\irqstat, =1	@ dummy compare
-		ldr	\base, =0xFFFF		// invalid interrupt
-		cmp	\irqnr, \base
-		bne	1001f
-		ldr	\irqstat, =0
-1001:
-		tst	\irqstat, #1	@ to make the condition code = TRUE
-		.endm
-
-		.macro	irq_prio_table
-		.endm
-
-#elif defined(CONFIG_ARCH_H720X)
-
-		.macro  disable_fiq
-		.endm
-
-		.macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
-#if defined (CONFIG_CPU_H7201) || defined (CONFIG_CPU_H7202)
-		@ we could use the id register on H7202, but this is not
-		@ properly updated when we come back from asm_do_irq
-		@ without a previous return from interrupt
-		@ (see loops below in irq_svc, irq_usr)
-		@ We see unmasked pending ints only, as the masked pending ints
-		@ are not visible here
-
-		mov     \base, #0xf0000000	       @ base register
-		orr     \base, \base, #0x24000	       @ irqbase
-		ldr     \irqstat, [\base, #0x04]        @ get interrupt status
-#if defined (CONFIG_CPU_H7201)
-		ldr	\tmp, =0x001fffff
-#else
-		mvn     \tmp, #0xc0000000
-#endif
-		and     \irqstat, \irqstat, \tmp        @ mask out unused ints
-		mov     \irqnr, #0
-
-		mov     \tmp, #0xff00
-		orr     \tmp, \tmp, #0xff
-		tst     \irqstat, \tmp
-		addeq   \irqnr, \irqnr, #16
-		moveq   \irqstat, \irqstat, lsr #16
-		tst     \irqstat, #255
-		addeq   \irqnr, \irqnr, #8
-		moveq   \irqstat, \irqstat, lsr #8
-		tst     \irqstat, #15
-		addeq   \irqnr, \irqnr, #4
-		moveq   \irqstat, \irqstat, lsr #4
-		tst     \irqstat, #3
-		addeq   \irqnr, \irqnr, #2
-		moveq   \irqstat, \irqstat, lsr #2
-		tst     \irqstat, #1
-		addeq   \irqnr, \irqnr, #1
-		moveq   \irqstat, \irqstat, lsr #1
-		tst     \irqstat, #1		       @ bit 0 should be set
-		.endm
-
-		.macro  irq_prio_table
-		.endm
-
-#else
-#error hynix processor selection missmatch
-#endif
-#else
-#error Unknown architecture
-#endif
-
 /*
  * Invalid mode handlers
  */
-__pabt_invalid:	sub	sp, sp, #S_FRAME_SIZE		@ Allocate frame size in one go
-		stmia	sp, {r0 - lr}			@ Save XXX r0 - lr
-		ldr	r4, .LCabt
-		mov	r1, #BAD_PREFETCH
-		b	1f
-
-__dabt_invalid:	sub	sp, sp, #S_FRAME_SIZE
-		stmia	sp, {r0 - lr}			@ Save SVC r0 - lr [lr *should* be intact]
-		ldr	r4, .LCabt
-		mov	r1, #BAD_DATA
-		b	1f
-
-__irq_invalid:	sub	sp, sp, #S_FRAME_SIZE		@ Allocate space on stack for frame
-		stmfd	sp, {r0 - lr}			@ Save r0 - lr
-		ldr	r4, .LCirq
-		mov	r1, #BAD_IRQ
-		b	1f
-
-__und_invalid:	sub	sp, sp, #S_FRAME_SIZE
-		stmia	sp, {r0 - lr}
-		ldr	r4, .LCund
-		mov	r1, #BAD_UNDEFINSTR		@ int reason
-
-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
-		b	bad_mode
+	.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
+	mov	r1, #\reason
+	.endm
+
+__pabt_invalid:
+	inv_entry abt, BAD_PREFETCH
+	b	1f
+
+__dabt_invalid:
+	inv_entry abt, BAD_DATA
+	b	1f
+
+__irq_invalid:
+	inv_entry irq, BAD_IRQ
+	b	1f
+
+__und_invalid:
+	inv_entry und, BAD_UNDEFINSTR
+
+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
+	b	bad_mode
 
 /*
  * SVC mode handlers
  */
-		.align	5
-__dabt_svc:	sub	sp, sp, #S_FRAME_SIZE
-		stmia	sp, {r0 - r12}			@ save r0 - r12
-		ldr	r2, .LCabt
-		add	r0, sp, #S_FRAME_SIZE
-		ldmia	r2, {r2 - r4}			@ get pc, cpsr
-		add	r5, sp, #S_SP
-		mov	r1, lr
-		stmia	r5, {r0 - r4}			@ save sp_SVC, lr_SVC, pc, cpsr, old_ro
-		mrs	r9, cpsr			@ Enable interrupts if they were
-		tst	r3, #PSR_I_BIT
-		biceq	r9, r9, #PSR_I_BIT		@ previously
-/*
- * This routine must not corrupt r9
- */
+	.macro	svc_entry, sym
+	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
+	mov	r1, lr
+
+	@
+	@ We are now ready to fill in the remaining blanks on the stack:
+	@
+	@  r0 - sp_svc
+	@  r1 - lr_svc
+	@  r2 - lr_<exception>, already fixed up for correct return/restart
+	@  r3 - spsr_<exception>
+	@  r4 - orig_r0 (see pt_regs definition in ptrace.h)
+	@
+	stmia	r5, {r0 - r4}
+	.endm
+
+	.align	5
+__dabt_svc:
+	svc_entry abt
+
+	@
+	@ get ready to re-enable interrupts if appropriate
+	@
+	mrs	r9, cpsr
+	tst	r3, #PSR_I_BIT
+	biceq	r9, r9, #PSR_I_BIT
+
+	@
+	@ Call the processor-specific abort handler:
+	@
+	@  r2 - aborted context pc
+	@  r3 - aborted context cpsr
+	@
+	@ The abort handler must return the aborted address in r0, and
+	@ the fault status register in r1.  r9 must be preserved.
+	@
 #ifdef MULTI_ABORT
-		ldr	r4, .LCprocfns			@ pass r2, r3 to
-		mov	lr, pc				@ processor code
-		ldr	pc, [r4]			@ call processor specific code
+	ldr	r4, .LCprocfns
+	mov	lr, pc
+	ldr	pc, [r4]
 #else
-		bl	CPU_ABORT_HANDLER
+	bl	CPU_ABORT_HANDLER
 #endif
-		msr	cpsr_c, r9
-		mov	r2, sp
-		bl	do_DataAbort
-		disable_irq r0
-		ldr	r0, [sp, #S_PSR]
-		msr	spsr_cxsf, r0
-		ldmia	sp, {r0 - pc}^			@ load r0 - pc, cpsr
-
-		.align	5
-__irq_svc:	sub	sp, sp, #S_FRAME_SIZE
-		stmia	sp, {r0 - r12}			@ save r0 - r12
-		ldr	r7, .LCirq
-		add	r5, sp, #S_FRAME_SIZE
-		ldmia	r7, {r7 - r9}
-		add	r4, sp, #S_SP
-		mov	r6, lr
-		stmia	r4, {r5, r6, r7, r8, r9}	@ save sp_SVC, lr_SVC, pc, cpsr, old_ro
+
+	@
+	@ set desired IRQ state, then call main handler
+	@
+	msr	cpsr_c, r9
+	mov	r2, sp
+	bl	do_DataAbort
+
+	@
+	@ IRQs off again before pulling preserved data off the stack
+	@
+	disable_irq r0
+
+	@
+	@ restore SPSR and restart the instruction
+	@
+	ldr	r0, [sp, #S_PSR]
+	msr	spsr_cxsf, r0
+	ldmia	sp, {r0 - pc}^			@ load r0 - pc, cpsr
+
+	.align	5
+__irq_svc:
+	svc_entry irq
 #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]
-#endif
-1:		get_irqnr_and_base r0, r6, r5, lr
-		movne	r1, sp
-		@
-		@ routine called with r0 = irq number, r1 = struct pt_regs *
-		@
-		adrsvc	ne, lr, 1b
-		bne	asm_do_IRQ
+	get_thread_info r8
+	ldr	r9, [r8, #TI_PREEMPT]		@ get preempt count
+	add	r7, r9, #1			@ increment it
+	str	r7, [r8, #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
 #ifdef CONFIG_PREEMPT
-		ldr	r0, [r8, #TI_FLAGS]		@ get flags
-		tst	r0, #_TIF_NEED_RESCHED
-		blne	svc_preempt
+	ldr	r0, [r8, #TI_FLAGS]		@ get flags
+	tst	r0, #_TIF_NEED_RESCHED
+	blne	svc_preempt
 preempt_return:
-		ldr	r0, [r8, #TI_PREEMPT]		@ read preempt value
-		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
-		msr	spsr_cxsf, r0
-		ldmia	sp, {r0 - pc}^			@ load r0 - pc, cpsr
+	ldr	r0, [r8, #TI_PREEMPT]		@ read preempt value
+	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
+	msr	spsr_cxsf, r0
+	ldmia	sp, {r0 - pc}^			@ load r0 - pc, cpsr
 
-		.ltorg
+	.ltorg
 
 #ifdef CONFIG_PREEMPT
-svc_preempt:	teq	r9, #0				@ was preempt count = 0
-		ldreq	r6, .LCirq_stat
-		movne	pc, lr				@ no
-		ldr	r0, [r6, #4]			@ local_irq_count
-		ldr	r1, [r6, #8]			@ local_bh_count
-		adds	r0, r0, r1
-		movne	pc, lr
-		mov	r7, #PREEMPT_ACTIVE
-		str	r7, [r8, #TI_PREEMPT]		@ set PREEMPT_ACTIVE
-1:		enable_irq r2				@ enable IRQs
-		bl	schedule
-		disable_irq r0				@ disable IRQs
-		ldr	r0, [r8, #TI_FLAGS]		@ get new tasks TI_FLAGS
-		tst	r0, #_TIF_NEED_RESCHED
-		beq	preempt_return			@ go again
-		b	1b
-#endif
-
-		.align	5
-__und_svc:	sub	sp, sp, #S_FRAME_SIZE
-		stmia	sp, {r0 - r12}			@ save r0 - r12
-		ldr	r3, .LCund
-		mov	r4, lr
-		ldmia	r3, {r5 - r7}
-		add	r3, sp, #S_FRAME_SIZE
-		add	r2, sp, #S_SP
-		stmia	r2, {r3 - r7}			@ save sp_SVC, lr_SVC, pc, cpsr, old_ro
-
-		ldr	r0, [r5, #-4]			@ r0 = instruction
-		adrsvc	al, r9, 1f			@ r9 = normal FP return
-		bl	call_fpe			@ lr = undefined instr return
-
-		mov	r0, sp				@ struct pt_regs *regs
-		bl	do_undefinstr
-
-1:		disable_irq r0
-		ldr	lr, [sp, #S_PSR]		@ Get SVC cpsr
-		msr	spsr_cxsf, lr
-		ldmia	sp, {r0 - pc}^			@ Restore SVC registers
-
-		.align	5
-__pabt_svc:	sub	sp, sp, #S_FRAME_SIZE
-		stmia	sp, {r0 - r12}			@ save r0 - r12
-		ldr	r2, .LCabt
-		add	r0, sp, #S_FRAME_SIZE
-		ldmia	r2, {r2 - r4}			@ get pc, cpsr
-		add	r5, sp, #S_SP
-		mov	r1, lr
-		stmia	r5, {r0 - r4}			@ save sp_SVC, lr_SVC, pc, cpsr, old_ro
-		mrs	r9, cpsr			@ Enable interrupts if they were
-		tst	r3, #PSR_I_BIT
-		biceq	r9, r9, #PSR_I_BIT		@ previously
-		msr	cpsr_c, r9
-		mov	r0, r2				@ address (pc)
-		mov	r1, sp				@ regs
-		bl	do_PrefetchAbort		@ call abort handler
-		disable_irq r0
-		ldr	r0, [sp, #S_PSR]
-		msr	spsr_cxsf, r0
-		ldmia	sp, {r0 - pc}^			@ load r0 - pc, cpsr
-
-		.align	5
-.LCirq:		.word	__temp_irq
-.LCund:		.word	__temp_und
-.LCabt:		.word	__temp_abt
+svc_preempt:
+	teq	r9, #0				@ was preempt count = 0
+	ldreq	r6, .LCirq_stat
+	movne	pc, lr				@ no
+	ldr	r0, [r6, #4]			@ local_irq_count
+	ldr	r1, [r6, #8]			@ local_bh_count
+	adds	r0, r0, r1
+	movne	pc, lr
+	mov	r7, #0				@ preempt_schedule_irq
+	str	r7, [r8, #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
+	tst	r0, #_TIF_NEED_RESCHED
+	beq	preempt_return			@ go again
+	b	1b
+#endif
+
+	.align	5
+__und_svc:
+	svc_entry und
+
+	@
+	@ call emulation code, which returns using r9 if it has emulated
+	@ the instruction, or the more conventional lr if we are to treat
+	@ this as a real undefined instruction
+	@
+	@  r0 - instruction
+	@
+	ldr	r0, [r2, #-4]
+	adr	r9, 1f
+	bl	call_fpe
+
+	mov	r0, sp				@ struct pt_regs *regs
+	bl	do_undefinstr
+
+	@
+	@ IRQs off again before pulling preserved data off the stack
+	@
+1:	disable_irq r0
+
+	@
+	@ restore SPSR and restart the instruction
+	@
+	ldr	lr, [sp, #S_PSR]		@ Get SVC cpsr
+	msr	spsr_cxsf, lr
+	ldmia	sp, {r0 - pc}^			@ Restore SVC registers
+
+	.align	5
+__pabt_svc:
+	svc_entry abt
+
+	@
+	@ re-enable interrupts if appropriate
+	@
+	mrs	r9, cpsr
+	tst	r3, #PSR_I_BIT
+	biceq	r9, r9, #PSR_I_BIT
+	msr	cpsr_c, r9
+
+	@
+	@ set args, then call main handler
+	@
+	@  r0 - address of faulting instruction
+	@  r1 - pointer to registers on stack
+	@
+	mov	r0, r2				@ address (pc)
+	mov	r1, sp				@ regs
+	bl	do_PrefetchAbort		@ call abort handler
+
+	@
+	@ IRQs off again before pulling preserved data off the stack
+	@
+	disable_irq r0
+
+	@
+	@ restore SPSR and restart the instruction
+	@
+	ldr	r0, [sp, #S_PSR]
+	msr	spsr_cxsf, r0
+	ldmia	sp, {r0 - pc}^			@ load r0 - pc, cpsr
+
+	.align	5
+.LCirq:
+	.word	__temp_irq
+.LCund:
+	.word	__temp_und
+.LCabt:
+	.word	__temp_abt
 #ifdef MULTI_ABORT
-.LCprocfns:	.word	processor
+.LCprocfns:
+	.word	processor
 #endif
-.LCfp:		.word	fp_enter
+.LCfp:
+	.word	fp_enter
 #ifdef CONFIG_PREEMPT
-.LCirq_stat:	.word	irq_stat
+.LCirq_stat:
+	.word	irq_stat
 #endif
 
-		irq_prio_table
-
 /*
  * User mode handlers
  */
-		.align	5
-__dabt_usr:	sub	sp, sp, #S_FRAME_SIZE		@ Allocate frame size in one go
-		stmia	sp, {r0 - r12}			@ save r0 - r12
-		ldr	r7, .LCabt
-		add	r5, sp, #S_PC
-		ldmia	r7, {r2 - r4}			@ Get USR pc, cpsr
-		stmia	r5, {r2 - r4}			@ Save USR pc, cpsr, old_r0
-		stmdb	r5, {sp, lr}^
-		alignment_trap r7, r7, __temp_abt
-		zero_fp
+	.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
+
+	@
+	@ We are now ready to fill in the remaining blanks on the stack:
+	@
+	@  r2 - lr_<exception>, already fixed up for correct return/restart
+	@  r3 - spsr_<exception>
+	@  r4 - orig_r0 (see pt_regs definition in ptrace.h)
+	@
+	@ Also, separately save sp_usr and lr_usr
+	@
+	stmia	r5, {r2 - r4}
+	stmdb	r5, {sp, lr}^
+	.endm
+
+	.align	5
+__dabt_usr:
+	usr_entry abt
+	alignment_trap r7, r0, __temp_abt
+	zero_fp
+
+	@
+	@ Call the processor-specific abort handler:
+	@
+	@  r2 - aborted context pc
+	@  r3 - aborted context cpsr
+	@
+	@ The abort handler must return the aborted address in r0, and
+	@ the fault status register in r1.
+	@
 #ifdef MULTI_ABORT
-		ldr	r4, .LCprocfns			@ pass r2, r3 to
-		mov	lr, pc				@ processor code
-		ldr	pc, [r4]			@ call processor specific code
+	ldr	r4, .LCprocfns
+	mov	lr, pc
+	ldr	pc, [r4]
 #else
-		bl	CPU_ABORT_HANDLER
+	bl	CPU_ABORT_HANDLER
 #endif
-		enable_irq r2				@ Enable interrupts
-		mov	r2, sp
-		adrsvc	al, lr, ret_from_exception
-		b	do_DataAbort
-
-		.align	5
-__irq_usr:	sub	sp, sp, #S_FRAME_SIZE
-		stmia	sp, {r0 - r12}			@ save r0 - r12
-		ldr	r4, .LCirq
-		add	r8, sp, #S_PC
-		ldmia	r4, {r5 - r7}			@ get saved PC, SPSR
-		stmia	r8, {r5 - r7}			@ save pc, psr, old_r0
-		stmdb	r8, {sp, lr}^
-		alignment_trap r4, r7, __temp_irq
-		zero_fp
+
+	@
+	@ IRQs on, then call the main handler
+	@
+	enable_irq r2
+	mov	r2, sp
+	adr	lr, ret_from_exception
+	b	do_DataAbort
+
+	.align	5
+__irq_usr:
+	usr_entry irq
+	alignment_trap r7, r0, __temp_irq
+	zero_fp
 #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]
-#endif
-1:		get_irqnr_and_base r0, r6, r5, lr
-		movne	r1, sp
-		adrsvc	ne, lr, 1b
-		@
-		@ routine called with r0 = irq number, r1 = struct pt_regs *
-		@
-		bne	asm_do_IRQ
+	get_thread_info r8
+	ldr	r9, [r8, #TI_PREEMPT]		@ get preempt count
+	add	r7, r9, #1			@ increment it
+	str	r7, [r8, #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
 #ifdef CONFIG_PREEMPT
-		ldr	r0, [r8, #TI_PREEMPT]
-		teq	r0, r7
-		str	r9, [r8, #TI_PREEMPT]
-		strne	r0, [r0, -r0]
-		mov	tsk, r8
+	ldr	r0, [r8, #TI_PREEMPT]
+	teq	r0, r7
+	str	r9, [r8, #TI_PREEMPT]
+	strne	r0, [r0, -r0]
+	mov	tsk, r8
 #else
-		get_thread_info tsk
+	get_thread_info tsk
 #endif
-		mov	why, #0
-		b	ret_to_user
+	mov	why, #0
+	b	ret_to_user
 
-		.ltorg
+	.ltorg
 
-		.align	5
-__und_usr:	sub	sp, sp, #S_FRAME_SIZE		@ Allocate frame size in one go
-		stmia	sp, {r0 - r12}			@ Save r0 - r12
-		ldr	r4, .LCund
-		add	r8, sp, #S_PC
-		ldmia	r4, {r5 - r7}
-		stmia	r8, {r5 - r7}			@ Save USR pc, cpsr, old_r0
-		stmdb	r8, {sp, lr}^			@ Save user sp, lr
-		alignment_trap r4, r7, __temp_und
-		zero_fp
-		tst	r6, #PSR_T_BIT			@ Thumb mode?
-		bne	fpundefinstr			@ ignore FP
-		sub	r4, r5, #4
-1:		ldrt	r0, [r4]			@ r0  = instruction
-		adrsvc	al, r9, ret_from_exception	@ r9  = normal FP return
-		adrsvc	al, lr, fpundefinstr		@ lr  = undefined instr return
+	.align	5
+__und_usr:
+	usr_entry und
+	alignment_trap r7, r0, __temp_und
+	zero_fp
+	tst	r3, #PSR_T_BIT			@ Thumb mode?
+	bne	fpundefinstr			@ ignore FP
+	sub	r4, r2, #4
+
+	@
+	@ fall through to the emulation code, which returns using r9 if
+	@ it has emulated the instruction, or the more conventional lr
+	@ if we are to treat this as a real undefined instruction
+	@
+	@  r0 - instruction
+	@
+1:	ldrt	r0, [r4]
+	adr	r9, ret_from_exception
+	adr	lr, fpundefinstr
+	@
+	@ fallthrough to call_fpe
+	@
 
 /*
  * The out of line fixup for the ldrt above.
  */
-		.section .fixup, "ax"
-2:		mov	pc, r9
-		.previous
-		.section __ex_table,"a"
-		.long	1b, 2b
-		.previous
+	.section .fixup, "ax"
+2:	mov	pc, r9
+	.previous
+	.section __ex_table,"a"
+	.long	1b, 2b
+	.previous
 
 /*
- * r0 = instruction.
- *
  * Check whether the instruction is a co-processor instruction.
  * If yes, we need to call the relevant co-processor handler.
  *
@@ -1300,98 +389,96 @@
  * for the ARM6/ARM7 SWI bug.
  *
  * Emulators may wish to make use of the following registers:
- *  r0  - instruction opcode.
- *  r10 - this threads thread_info structure.
+ *  r0  = instruction opcode.
+ *  r2  = PC+4
+ *  r10 = this threads thread_info structure.
  */
 call_fpe:
-		tst	r0, #0x08000000			@ only CDP/CPRT/LDC/STC have bit 27
+	tst	r0, #0x08000000			@ only CDP/CPRT/LDC/STC have bit 27
 #if defined(CONFIG_CPU_ARM610) || defined(CONFIG_CPU_ARM710)
-		and	r8, r0, #0x0f000000		@ mask out op-code bits
-		teqne	r8, #0x0f000000			@ SWI (ARM6/7 bug)?
+	and	r8, r0, #0x0f000000		@ mask out op-code bits
+	teqne	r8, #0x0f000000			@ SWI (ARM6/7 bug)?
 #endif
-		moveq	pc, lr
-		get_thread_info r10			@ get current thread
-		and	r8, r0, #0x00000f00		@ mask out CP number
-		mov	r7, #1
-		add	r6, r10, #TI_USED_CP
-		strb	r7, [r6, r8, lsr #8]		@ set appropriate used_cp[]
+	moveq	pc, lr
+	get_thread_info r10			@ get current thread
+	and	r8, r0, #0x00000f00		@ mask out CP number
+	mov	r7, #1
+	add	r6, r10, #TI_USED_CP
+	strb	r7, [r6, r8, lsr #8]		@ set appropriate used_cp[]
 #ifdef CONFIG_IWMMXT
-		@ Test if we need to give access to iWMMXt coprocessors
-		ldr	r5, [r10, #TI_FLAGS]
-		rsbs	r7, r8, #(1 << 8)		@ CP 0 or 1 only
-		movcss	r7, r5, lsr #(TIF_USING_IWMMXT + 1)
-		bcs	iwmmxt_task_enable
-#endif
-		enable_irq r7
-		add	pc, pc, r8, lsr #6
-		mov	r0, r0
-
-		mov	pc, lr				@ CP#0
-		b	do_fpe				@ CP#1 (FPE)
-		b	do_fpe				@ CP#2 (FPE)
-		mov	pc, lr				@ CP#3
-		mov	pc, lr				@ CP#4
-		mov	pc, lr				@ CP#5
-		mov	pc, lr				@ CP#6
-		mov	pc, lr				@ CP#7
-		mov	pc, lr				@ CP#8
-		mov	pc, lr				@ CP#9
+	@ Test if we need to give access to iWMMXt coprocessors
+	ldr	r5, [r10, #TI_FLAGS]
+	rsbs	r7, r8, #(1 << 8)		@ CP 0 or 1 only
+	movcss	r7, r5, lsr #(TIF_USING_IWMMXT + 1)
+	bcs	iwmmxt_task_enable
+#endif
+	enable_irq r7
+	add	pc, pc, r8, lsr #6
+	mov	r0, r0
+
+	mov	pc, lr				@ CP#0
+	b	do_fpe				@ CP#1 (FPE)
+	b	do_fpe				@ CP#2 (FPE)
+	mov	pc, lr				@ CP#3
+	mov	pc, lr				@ CP#4
+	mov	pc, lr				@ CP#5
+	mov	pc, lr				@ CP#6
+	mov	pc, lr				@ CP#7
+	mov	pc, lr				@ CP#8
+	mov	pc, lr				@ CP#9
 #ifdef CONFIG_VFP
-		b	do_vfp				@ CP#10 (VFP)
-		b	do_vfp				@ CP#11 (VFP)
+	b	do_vfp				@ CP#10 (VFP)
+	b	do_vfp				@ CP#11 (VFP)
 #else
-		mov	pc, lr				@ CP#10 (VFP)
-		mov	pc, lr				@ CP#11 (VFP)
+	mov	pc, lr				@ CP#10 (VFP)
+	mov	pc, lr				@ CP#11 (VFP)
 #endif
-		mov	pc, lr				@ CP#12
-		mov	pc, lr				@ CP#13
-		mov	pc, lr				@ CP#14 (Debug)
-		mov	pc, lr				@ CP#15 (Control)
-
-do_fpe:		ldr	r4, .LCfp
-		add	r10, r10, #TI_FPSTATE		@ r10 = workspace
-		ldr	pc, [r4]			@ Call FP module USR entry point
+	mov	pc, lr				@ CP#12
+	mov	pc, lr				@ CP#13
+	mov	pc, lr				@ CP#14 (Debug)
+	mov	pc, lr				@ CP#15 (Control)
+
+do_fpe:
+	ldr	r4, .LCfp
+	add	r10, r10, #TI_FPSTATE		@ r10 = workspace
+	ldr	pc, [r4]			@ Call FP module USR entry point
 
 /*
  * The FP module is called with these registers set:
  *  r0  = instruction
- *  r5  = PC
+ *  r2  = PC+4
  *  r9  = normal "successful" return address
  *  r10 = FP workspace
  *  lr  = unrecognised FP instruction return address
  */
 
-		.data
+	.data
 ENTRY(fp_enter)
-		.word	fpundefinstr
-		.text
+	.word	fpundefinstr
+	.text
 
-fpundefinstr:	mov	r0, sp
-		adrsvc	al, lr, ret_from_exception
-		b	do_undefinstr
-
-		.align	5
-__pabt_usr:	sub	sp, sp, #S_FRAME_SIZE		@ Allocate frame size in one go
-		stmia	sp, {r0 - r12}			@ Save r0 - r12
-		ldr	r4, .LCabt
-		add	r8, sp, #S_PC
-		ldmia	r4, {r5 - r7}			@ Get USR pc, cpsr
-		stmia	r8, {r5 - r7}			@ Save USR pc, cpsr, old_r0
-		stmdb	r8, {sp, lr}^			@ Save sp_usr lr_usr
-		alignment_trap r4, r7, __temp_abt
-		zero_fp
-		enable_irq r0				@ Enable interrupts
-		mov	r0, r5				@ address (pc)
-		mov	r1, sp				@ regs
-		bl	do_PrefetchAbort		@ call abort handler
-		/* fall through */
+fpundefinstr:
+	mov	r0, sp
+	adr	lr, ret_from_exception
+	b	do_undefinstr
+
+	.align	5
+__pabt_usr:
+	usr_entry abt
+	alignment_trap r7, r0, __temp_abt
+	zero_fp
+	enable_irq r0				@ Enable interrupts
+	mov	r0, r2				@ address (pc)
+	mov	r1, sp				@ regs
+	bl	do_PrefetchAbort		@ call abort handler
+	/* fall through */
 /*
  * This is the return code to user mode for abort handlers
  */
 ENTRY(ret_from_exception)
-		get_thread_info tsk
-		mov	why, #0
-		b	ret_to_user
+	get_thread_info tsk
+	mov	why, #0
+	b	ret_to_user
 
 /*
  * Register switch for ARMv3 and ARMv4 processors
@@ -1399,212 +486,160 @@
  * previous and next are guaranteed not to be the same.
  */
 ENTRY(__switch_to)
-		add	ip, r1, #TI_CPU_SAVE
-		ldr	r3, [r2, #TI_CPU_DOMAIN]!
-		stmia	ip!, {r4 - sl, fp, sp, lr}	@ Store most regs on stack
+	add	ip, r1, #TI_CPU_SAVE
+	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 defined(CONFIG_CPU_XSCALE) && !defined(CONFIG_IWMMXT)
-		mra	r4, r5, acc0
-		stmia   ip, {r4, r5}
+	mra	r4, r5, acc0
+	stmia   ip, {r4, r5}
 #endif
-		mcr	p15, 0, r3, c3, c0, 0		@ Set domain register
+	mov	r4, #0xffff0fff
+	str	r3, [r4, #-3]			@ Set TLS ptr
+	mcr	p15, 0, r6, c3, c0, 0		@ Set domain register
 #ifdef CONFIG_VFP
-		@ Always disable VFP so we can lazily save/restore the old
-		@ state. This occurs in the context of the previous thread.
-		VFPFMRX	r4, FPEXC
-		bic	r4, r4, #FPEXC_ENABLE
-		VFPFMXR	FPEXC, r4
+	@ Always disable VFP so we can lazily save/restore the old
+	@ state. This occurs in the context of the previous thread.
+	VFPFMRX	r4, FPEXC
+	bic	r4, r4, #FPEXC_ENABLE
+	VFPFMXR	FPEXC, r4
 #endif
 #if defined(CONFIG_IWMMXT)
-		bl	iwmmxt_task_switch
+	bl	iwmmxt_task_switch
 #elif defined(CONFIG_CPU_XSCALE)
-		add	r4, r2, #40			@ cpu_context_save->extra
-		ldmib	r4, {r4, r5}
-		mar	acc0, r4, r5
+	add	r4, r2, #40			@ cpu_context_save->extra
+	ldmib	r4, {r4, r5}
+	mar	acc0, r4, r5
 #endif
-		ldmib	r2, {r4 - sl, fp, sp, pc}	@ Load all regs saved previously
+	ldmib	r2, {r4 - sl, fp, sp, pc}	@ Load all regs saved previously
 
-		__INIT
+	__INIT
 /*
- * Vector stubs.  NOTE that we only align 'vector_IRQ' to a cache line boundary,
- * and we rely on each stub being exactly 48 (1.5 cache lines) in size.  This
- * means that we only ever load two cache lines for this code, or one if we're
- * lucky.  We also copy this code to 0x200 so that we can use branches in the
+ * Vector stubs.
+ *
+ * This code is copied to 0x200 or 0xffff0200 so we can use branches in the
  * vectors, rather than ldr's.
+ *
+ * Common stub entry macro:
+ *   Enter in IRQ mode, spsr = SVC/USR CPSR, lr = SVC/USR PC
  */
-		.align	5
+	.macro	vector_stub, name, sym, correction=0
+	.align	5
+
+vector_\name:
+	ldr	r13, .LCs\sym
+	.if \correction
+	sub	lr, lr, #\correction
+	.endif
+	str	lr, [r13]			@ save lr_IRQ
+	mrs	lr, spsr
+	str	lr, [r13, #4]			@ save spsr_IRQ
+	@
+	@ now branch to the relevant MODE handling routine
+	@
+	mrs	r13, cpsr
+	bic	r13, r13, #MODE_MASK
+	orr	r13, r13, #MODE_SVC
+	msr	spsr_cxsf, r13			@ switch to SVC_32 mode
+
+	and	lr, lr, #15
+	ldr	lr, [pc, lr, lsl #2]
+	movs	pc, lr				@ Changes mode and branches
+	.endm
+
 __stubs_start:
 /*
  * Interrupt dispatcher
- * Enter in IRQ mode, spsr = SVC/USR CPSR, lr = SVC/USR PC
  */
-vector_IRQ:	@
-		@ save mode specific registers
-		@
-		ldr	r13, .LCsirq
-		sub	lr, lr, #4
-		str	lr, [r13]			@ save lr_IRQ
-		mrs	lr, spsr
-		str	lr, [r13, #4]			@ save spsr_IRQ
-		@
-		@ now branch to the relevant MODE handling routine
-		@
-		mrs	r13, cpsr
-		bic	r13, r13, #MODE_MASK
-		orr	r13, r13, #MODE_SVC
-		msr	spsr_cxsf, r13			@ switch to SVC_32 mode
-
-		and	lr, lr, #15
-		ldr	lr, [pc, lr, lsl #2]
-		movs	pc, lr				@ Changes mode and branches
-
-.LCtab_irq:	.word	__irq_usr			@  0  (USR_26 / USR_32)
-		.word	__irq_invalid			@  1  (FIQ_26 / FIQ_32)
-		.word	__irq_invalid			@  2  (IRQ_26 / IRQ_32)
-		.word	__irq_svc			@  3  (SVC_26 / SVC_32)
-		.word	__irq_invalid			@  4
-		.word	__irq_invalid			@  5
-		.word	__irq_invalid			@  6
-		.word	__irq_invalid			@  7
-		.word	__irq_invalid			@  8
-		.word	__irq_invalid			@  9
-		.word	__irq_invalid			@  a
-		.word	__irq_invalid			@  b
-		.word	__irq_invalid			@  c
-		.word	__irq_invalid			@  d
-		.word	__irq_invalid			@  e
-		.word	__irq_invalid			@  f
+	vector_stub	irq, irq, 4
 
-		.align	5
+	.long	__irq_usr			@  0  (USR_26 / USR_32)
+	.long	__irq_invalid			@  1  (FIQ_26 / FIQ_32)
+	.long	__irq_invalid			@  2  (IRQ_26 / IRQ_32)
+	.long	__irq_svc			@  3  (SVC_26 / SVC_32)
+	.long	__irq_invalid			@  4
+	.long	__irq_invalid			@  5
+	.long	__irq_invalid			@  6
+	.long	__irq_invalid			@  7
+	.long	__irq_invalid			@  8
+	.long	__irq_invalid			@  9
+	.long	__irq_invalid			@  a
+	.long	__irq_invalid			@  b
+	.long	__irq_invalid			@  c
+	.long	__irq_invalid			@  d
+	.long	__irq_invalid			@  e
+	.long	__irq_invalid			@  f
 
 /*
- * Data abort dispatcher - dispatches it to the correct handler for the processor mode
+ * Data abort dispatcher
  * Enter in ABT mode, spsr = USR CPSR, lr = USR PC
  */
-vector_data:	@
-		@ save mode specific registers
-		@
-		ldr	r13, .LCsabt
-		sub	lr, lr, #8
-		str	lr, [r13]
-		mrs	lr, spsr
-		str	lr, [r13, #4]
-		@
-		@ now branch to the relevant MODE handling routine
-		@
-		mrs	r13, cpsr
-		bic	r13, r13, #MODE_MASK
-		orr	r13, r13, #MODE_SVC
-		msr	spsr_cxsf, r13			@ switch to SVC_32 mode
-
-		and	lr, lr, #15
-		ldr	lr, [pc, lr, lsl #2]
-		movs	pc, lr				@ Changes mode and branches
-
-.LCtab_dabt:	.word	__dabt_usr			@  0  (USR_26 / USR_32)
-		.word	__dabt_invalid			@  1  (FIQ_26 / FIQ_32)
-		.word	__dabt_invalid			@  2  (IRQ_26 / IRQ_32)
-		.word	__dabt_svc			@  3  (SVC_26 / SVC_32)
-		.word	__dabt_invalid			@  4
-		.word	__dabt_invalid			@  5
-		.word	__dabt_invalid			@  6
-		.word	__dabt_invalid			@  7
-		.word	__dabt_invalid			@  8
-		.word	__dabt_invalid			@  9
-		.word	__dabt_invalid			@  a
-		.word	__dabt_invalid			@  b
-		.word	__dabt_invalid			@  c
-		.word	__dabt_invalid			@  d
-		.word	__dabt_invalid			@  e
-		.word	__dabt_invalid			@  f
+	vector_stub	dabt, abt, 8
 
-		.align	5
+	.long	__dabt_usr			@  0  (USR_26 / USR_32)
+	.long	__dabt_invalid			@  1  (FIQ_26 / FIQ_32)
+	.long	__dabt_invalid			@  2  (IRQ_26 / IRQ_32)
+	.long	__dabt_svc			@  3  (SVC_26 / SVC_32)
+	.long	__dabt_invalid			@  4
+	.long	__dabt_invalid			@  5
+	.long	__dabt_invalid			@  6
+	.long	__dabt_invalid			@  7
+	.long	__dabt_invalid			@  8
+	.long	__dabt_invalid			@  9
+	.long	__dabt_invalid			@  a
+	.long	__dabt_invalid			@  b
+	.long	__dabt_invalid			@  c
+	.long	__dabt_invalid			@  d
+	.long	__dabt_invalid			@  e
+	.long	__dabt_invalid			@  f
 
 /*
- * Prefetch abort dispatcher - dispatches it to the correct handler for the processor mode
+ * Prefetch abort dispatcher
  * Enter in ABT mode, spsr = USR CPSR, lr = USR PC
  */
-vector_prefetch:
-		@
-		@ save mode specific registers
-		@
-		ldr	r13, .LCsabt
-		sub	lr, lr, #4
-		str	lr, [r13]			@ save lr_ABT
-		mrs	lr, spsr
-		str	lr, [r13, #4]			@ save spsr_ABT
-		@
-		@ now branch to the relevant MODE handling routine
-		@
-		mrs	r13, cpsr
-		bic	r13, r13, #MODE_MASK
-		orr	r13, r13, #MODE_SVC
-		msr	spsr_cxsf, r13			@ switch to SVC_32 mode
-
-		ands	lr, lr, #15
-		ldr	lr, [pc, lr, lsl #2]
-		movs	pc, lr
-
-.LCtab_pabt:	.word	__pabt_usr			@  0 (USR_26 / USR_32)
-		.word	__pabt_invalid			@  1 (FIQ_26 / FIQ_32)
-		.word	__pabt_invalid			@  2 (IRQ_26 / IRQ_32)
-		.word	__pabt_svc			@  3 (SVC_26 / SVC_32)
-		.word	__pabt_invalid			@  4
-		.word	__pabt_invalid			@  5
-		.word	__pabt_invalid			@  6
-		.word	__pabt_invalid			@  7
-		.word	__pabt_invalid			@  8
-		.word	__pabt_invalid			@  9
-		.word	__pabt_invalid			@  a
-		.word	__pabt_invalid			@  b
-		.word	__pabt_invalid			@  c
-		.word	__pabt_invalid			@  d
-		.word	__pabt_invalid			@  e
-		.word	__pabt_invalid			@  f
+	vector_stub	pabt, abt, 4
 
-		.align	5
+	.long	__pabt_usr			@  0 (USR_26 / USR_32)
+	.long	__pabt_invalid			@  1 (FIQ_26 / FIQ_32)
+	.long	__pabt_invalid			@  2 (IRQ_26 / IRQ_32)
+	.long	__pabt_svc			@  3 (SVC_26 / SVC_32)
+	.long	__pabt_invalid			@  4
+	.long	__pabt_invalid			@  5
+	.long	__pabt_invalid			@  6
+	.long	__pabt_invalid			@  7
+	.long	__pabt_invalid			@  8
+	.long	__pabt_invalid			@  9
+	.long	__pabt_invalid			@  a
+	.long	__pabt_invalid			@  b
+	.long	__pabt_invalid			@  c
+	.long	__pabt_invalid			@  d
+	.long	__pabt_invalid			@  e
+	.long	__pabt_invalid			@  f
 
 /*
- * Undef instr entry dispatcher - dispatches it to the correct handler for the processor mode
+ * Undef instr entry dispatcher
  * Enter in UND mode, spsr = SVC/USR CPSR, lr = SVC/USR PC
  */
-vector_undefinstr:
-		@
-		@ save mode specific registers
-		@
-		ldr	r13, .LCsund
-		str	lr, [r13]			@ save lr_UND
-		mrs	lr, spsr
-		str	lr, [r13, #4]			@ save spsr_UND
-		@
-		@ now branch to the relevant MODE handling routine
-		@
-		mrs	r13, cpsr
-		bic	r13, r13, #MODE_MASK
-		orr	r13, r13, #MODE_SVC
-		msr	spsr_cxsf, r13			@ switch to SVC_32 mode
-
-		and	lr, lr, #15
-		ldr	lr, [pc, lr, lsl #2]
-		movs	pc, lr				@ Changes mode and branches
-
-.LCtab_und:	.word	__und_usr			@  0 (USR_26 / USR_32)
-		.word	__und_invalid			@  1 (FIQ_26 / FIQ_32)
-		.word	__und_invalid			@  2 (IRQ_26 / IRQ_32)
-		.word	__und_svc			@  3 (SVC_26 / SVC_32)
-		.word	__und_invalid			@  4
-		.word	__und_invalid			@  5
-		.word	__und_invalid			@  6
-		.word	__und_invalid			@  7
-		.word	__und_invalid			@  8
-		.word	__und_invalid			@  9
-		.word	__und_invalid			@  a
-		.word	__und_invalid			@  b
-		.word	__und_invalid			@  c
-		.word	__und_invalid			@  d
-		.word	__und_invalid			@  e
-		.word	__und_invalid			@  f
+	vector_stub	und, und
+
+	.long	__und_usr			@  0 (USR_26 / USR_32)
+	.long	__und_invalid			@  1 (FIQ_26 / FIQ_32)
+	.long	__und_invalid			@  2 (IRQ_26 / IRQ_32)
+	.long	__und_svc			@  3 (SVC_26 / SVC_32)
+	.long	__und_invalid			@  4
+	.long	__und_invalid			@  5
+	.long	__und_invalid			@  6
+	.long	__und_invalid			@  7
+	.long	__und_invalid			@  8
+	.long	__und_invalid			@  9
+	.long	__und_invalid			@  a
+	.long	__und_invalid			@  b
+	.long	__und_invalid			@  c
+	.long	__und_invalid			@  d
+	.long	__und_invalid			@  e
+	.long	__und_invalid			@  f
 
-		.align	5
+	.align	5
 
 /*=============================================================================
  * Undefined FIQs
@@ -1616,8 +651,9 @@
  * other mode than FIQ...  Ok you can switch to another mode, but you can't
  * get out of that mode without clobbering one register.
  */
-vector_FIQ:	disable_fiq
-		subs	pc, lr, #4
+vector_fiq:
+	disable_fiq
+	subs	pc, lr, #4
 
 /*=============================================================================
  * Address exception handler
@@ -1627,70 +663,78 @@
  */
 
 vector_addrexcptn:
-		b	vector_addrexcptn
+	b	vector_addrexcptn
 
 /*
  * We group all the following data together to optimise
  * for CPUs with separate I & D caches.
  */
-		.align	5
+	.align	5
 
-.LCvswi:	.word	vector_swi
+.LCvswi:
+	.word	vector_swi
 
-.LCsirq:	.word	__temp_irq
-.LCsund:	.word	__temp_und
-.LCsabt:	.word	__temp_abt
+.LCsirq:
+	.word	__temp_irq
+.LCsund:
+	.word	__temp_und
+.LCsabt:
+	.word	__temp_abt
 
 __stubs_end:
 
-		.equ	__real_stubs_start, .LCvectors + 0x200
+	.equ	__real_stubs_start, .LCvectors + 0x200
 
-.LCvectors:	swi	SYS_ERROR0
-		b	__real_stubs_start + (vector_undefinstr - __stubs_start)
-		ldr	pc, __real_stubs_start + (.LCvswi - __stubs_start)
-		b	__real_stubs_start + (vector_prefetch - __stubs_start)
-		b	__real_stubs_start + (vector_data - __stubs_start)
-		b	__real_stubs_start + (vector_addrexcptn - __stubs_start)
-		b	__real_stubs_start + (vector_IRQ - __stubs_start)
-		b	__real_stubs_start + (vector_FIQ - __stubs_start)
+.LCvectors:
+	swi	SYS_ERROR0
+	b	__real_stubs_start + (vector_und - __stubs_start)
+	ldr	pc, __real_stubs_start + (.LCvswi - __stubs_start)
+	b	__real_stubs_start + (vector_pabt - __stubs_start)
+	b	__real_stubs_start + (vector_dabt - __stubs_start)
+	b	__real_stubs_start + (vector_addrexcptn - __stubs_start)
+	b	__real_stubs_start + (vector_irq - __stubs_start)
+	b	__real_stubs_start + (vector_fiq - __stubs_start)
 
 ENTRY(__trap_init)
-		stmfd	sp!, {r4 - r6, lr}
+	stmfd	sp!, {r4 - r6, lr}
 
-		mov	r0, #0xff000000
-		orr	r0, r0, #0x00ff0000		@ high vectors position
-		adr	r1, .LCvectors			@ set up the vectors
-		ldmia	r1, {r1, r2, r3, r4, r5, r6, ip, lr}
-		stmia	r0, {r1, r2, r3, r4, r5, r6, ip, lr}
-
-		add	r2, r0, #0x200
-		adr	r0, __stubs_start		@ copy stubs to 0x200
-		adr	r1, __stubs_end
-1:		ldr	r3, [r0], #4
-		str	r3, [r2], #4
-		cmp	r0, r1
-		blt	1b
-		LOADREGS(fd, sp!, {r4 - r6, pc})
+	mov	r0, #0xff000000
+	orr	r0, r0, #0x00ff0000		@ high vectors position
+	adr	r1, .LCvectors			@ set up the vectors
+	ldmia	r1, {r1, r2, r3, r4, r5, r6, ip, lr}
+	stmia	r0, {r1, r2, r3, r4, r5, r6, ip, lr}
+
+	add	r2, r0, #0x200
+	adr	r0, __stubs_start		@ copy stubs to 0x200
+	adr	r1, __stubs_end
+1:	ldr	r3, [r0], #4
+	str	r3, [r2], #4
+	cmp	r0, r1
+	blt	1b
+	LOADREGS(fd, sp!, {r4 - r6, pc})
 
-		.data
+	.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
+__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
+	.globl	cr_alignment
+	.globl	cr_no_alignment
 cr_alignment:
-		.space	4
+	.space	4
 cr_no_alignment:
-		.space	4
+	.space	4
diff -Nru a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
--- a/arch/arm/kernel/entry-common.S	2005-03-01 23:38:51 -08:00
+++ b/arch/arm/kernel/entry-common.S	2005-03-01 23:38:51 -08:00
@@ -11,6 +11,7 @@
 
 #include <asm/thread_info.h>
 #include <asm/ptrace.h>
+#include <asm/unistd.h>
 
 #include "entry-header.S"
 
@@ -137,7 +138,7 @@
 	tst	ip, #_TIF_SYSCALL_TRACE		@ are we tracing syscalls?
 	bne	__sys_trace
 
-	adrsvc	al, lr, ret_fast_syscall	@ return address
+	adr	lr, ret_fast_syscall		@ return address
 	cmp	scno, #NR_syscalls		@ check upper syscall limit
 	ldrcc	pc, [tbl, scno, lsl #2]		@ call sys_* routine
 
@@ -157,7 +158,7 @@
 	mov	r0, #0				@ trace entry [IP = 0]
 	bl	syscall_trace
 
-	adrsvc	al, lr, __sys_trace_return	@ return address
+	adr	lr, __sys_trace_return		@ return address
 	add	r1, sp, #S_R0 + S_OFF		@ pointer to regs
 	cmp	scno, #NR_syscalls		@ check upper syscall limit
 	ldmccia	r1, {r0 - r3}			@ have to reload r0 - r3
@@ -190,13 +191,14 @@
 		.type	sys_syscall, #function
 sys_syscall:
 		eor	scno, r0, #OS_NUMBER << 20
-		cmp	scno, #NR_syscalls	@ check range
-		stmleia	sp, {r5, r6}		@ shuffle args
-		movle	r0, r1
-		movle	r1, r2
-		movle	r2, r3
-		movle	r3, r4
-		ldrle	pc, [tbl, scno, lsl #2]
+		cmp	scno, #__NR_syscall - __NR_SYSCALL_BASE
+		cmpne	scno, #NR_syscalls	@ check range
+		stmloia	sp, {r5, r6}		@ shuffle args
+		movlo	r0, r1
+		movlo	r1, r2
+		movlo	r2, r3
+		movlo	r3, r4
+		ldrlo	pc, [tbl, scno, lsl #2]
 		b	sys_ni_syscall
 
 sys_fork_wrapper:
@@ -211,8 +213,9 @@
 		add	r3, sp, #S_OFF
 		b	sys_execve
 
-sys_clone_wapper:
-		add	r2, sp, #S_OFF
+sys_clone_wrapper:
+		add	ip, sp, #S_OFF
+		str	ip, [sp, #4]
 		b	sys_clone
 
 sys_sigsuspend_wrapper:
@@ -234,6 +237,10 @@
 sys_sigaltstack_wrapper:
 		ldr	r2, [sp, #S_OFF + S_SP]
 		b	do_sigaltstack
+
+sys_futex_wrapper:
+		str	r5, [sp, #4]		@ push sixth arg
+		b	sys_futex
 
 /*
  * Note: off_4k (r5) is always units of 4K.  If we can't do the requested
diff -Nru a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S
--- a/arch/arm/kernel/entry-header.S	2005-03-01 23:38:56 -08:00
+++ b/arch/arm/kernel/entry-header.S	2005-03-01 23:38:56 -08:00
@@ -6,6 +6,7 @@
 #include <asm/errno.h>
 #include <asm/hardware.h>
 #include <asm/arch/irqs.h>
+#include <asm/arch/entry-macro.S>
 
 #ifndef MODE_SVC
 #define MODE_SVC 0x13
@@ -138,13 +139,6 @@
 	.macro	get_thread_info, rd
 	mov	\rd, sp, lsr #13
 	mov	\rd, \rd, lsl #13
-	.endm
-
-/*
- * Like adr, but force SVC mode (if required)
- */
-	.macro	adrsvc, cond, reg, label
-	adr\cond	\reg, \label
 	.endm
 
 	.macro	alignment_trap, rbase, rtemp, sym
diff -Nru a/arch/arm/kernel/fiq.c b/arch/arm/kernel/fiq.c
--- a/arch/arm/kernel/fiq.c	2005-03-01 23:39:09 -08:00
+++ b/arch/arm/kernel/fiq.c	2005-03-01 23:39:09 -08:00
@@ -46,6 +46,12 @@
 #include <asm/system.h>
 #include <asm/uaccess.h>
 
+#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
+#warning This file requires GCC 3.3.x or older to build.  Alternatively,
+#warning please talk to GCC people to resolve the issues with the
+#warning assembly clobber list.
+#endif
+
 static unsigned long no_fiq_insn;
 
 /* Default reacquire function
@@ -89,16 +95,15 @@
  */
 void set_fiq_regs(struct pt_regs *regs)
 {
-	register unsigned long tmp, tmp2;
+	register unsigned long tmp;
 	__asm__ volatile (
 	"mrs	%0, cpsr\n\
-	mov	%1, %3\n\
-	msr	cpsr_c, %1	@ select FIQ mode\n\
+	msr	cpsr_c, %2	@ select FIQ mode\n\
 	mov	r0, r0\n\
-	ldmia	%2, {r8 - r14}\n\
+	ldmia	%1, {r8 - r14}\n\
 	msr	cpsr_c, %0	@ return to SVC mode\n\
 	mov	r0, r0"
-	: "=&r" (tmp), "=&r" (tmp2)
+	: "=&r" (tmp)
 	: "r" (&regs->ARM_r8), "I" (PSR_I_BIT | PSR_F_BIT | FIQ_MODE)
 	/* These registers aren't modified by the above code in a way
 	   visible to the compiler, but we mark them as clobbers anyway
@@ -109,16 +114,15 @@
 
 void get_fiq_regs(struct pt_regs *regs)
 {
-	register unsigned long tmp, tmp2;
+	register unsigned long tmp;
 	__asm__ volatile (
 	"mrs	%0, cpsr\n\
-	mov	%1, %3\n\
-	msr	cpsr_c, %1	@ select FIQ mode\n\
+	msr	cpsr_c, %2	@ select FIQ mode\n\
 	mov	r0, r0\n\
-	stmia	%2, {r8 - r14}\n\
+	stmia	%1, {r8 - r14}\n\
 	msr	cpsr_c, %0	@ return to SVC mode\n\
 	mov	r0, r0"
-	: "=&r" (tmp), "=&r" (tmp2)
+	: "=&r" (tmp)
 	: "r" (&regs->ARM_r8), "I" (PSR_I_BIT | PSR_F_BIT | FIQ_MODE)
 	/* These registers aren't modified by the above code in a way
 	   visible to the compiler, but we mark them as clobbers anyway
diff -Nru a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
--- a/arch/arm/kernel/head.S	2005-03-01 23:38:44 -08:00
+++ b/arch/arm/kernel/head.S	2005-03-01 23:38:44 -08:00
@@ -14,10 +14,19 @@
 #include <linux/init.h>
 
 #include <asm/assembler.h>
+#include <asm/domain.h>
 #include <asm/mach-types.h>
 #include <asm/procinfo.h>
 #include <asm/ptrace.h>
 #include <asm/constants.h>
+#include <asm/system.h>
+
+#define PROCINFO_MMUFLAGS	8
+#define PROCINFO_INITFUNC	12
+
+#define MACHINFO_PHYSRAM	4
+#define MACHINFO_PHYSIO		8
+#define MACHINFO_PGOFFIO	12
 
 #ifndef CONFIG_XIP_KERNEL
 /*
@@ -86,17 +95,16 @@
  * circumstances, zImage) is for.
  */
 	__INIT
-	.type	stext, #function
+	.type	stext, %function
 ENTRY(stext)
-	mov	r12, r0
-	mov	r0, #PSR_F_BIT | PSR_I_BIT | MODE_SVC	@ make sure svc mode
-	msr	cpsr_c, r0			@ and all irqs disabled
-	bl	__lookup_processor_type
-	teq	r10, #0				@ invalid processor?
+	msr	cpsr_c, #PSR_F_BIT | PSR_I_BIT | MODE_SVC @ ensure svc mode
+						@ and irqs disabled
+	bl	__lookup_processor_type		@ r5=procinfo r9=cpuid
+	movs	r10, r5				@ invalid processor (r5=0)?
 	moveq	r0, #'p'			@ yes, error 'p'
 	beq	__error
-	bl	__lookup_architecture_type
-	teq	r7, #0				@ invalid architecture?
+	bl	__lookup_machine_type		@ r5=machinfo
+	movs	r8, r5				@ invalid machine (r5=0)?
 	moveq	r0, #'a'			@ yes, error 'a'
 	beq	__error
 	bl	__create_page_tables
@@ -104,89 +112,128 @@
 	/*
 	 * The following calls CPU specific code in a position independent
 	 * manner.  See arch/arm/mm/proc-*.S for details.  r10 = base of
-	 * xxx_proc_info structure selected by __lookup_architecture_type
+	 * xxx_proc_info structure selected by __lookup_machine_type
 	 * above.  On return, the CPU will be ready for the MMU to be
 	 * turned on, and r0 will hold the CPU control register value.
 	 */
-	adr	lr, __turn_mmu_on		@ return (PIC) address
-	add	pc, r10, #12
+	ldr	r13, __switch_data		@ address to jump to after
+						@ mmu has been enabled
+	adr	lr, __enable_mmu		@ return (PIC) address
+	add	pc, r10, #PROCINFO_INITFUNC
 
 	.type	__switch_data, %object
 __switch_data:
 	.long	__mmap_switched
-	.long	__data_loc			@ r2
-	.long	__data_start			@ r3
-	.long	__bss_start			@ r4
-	.long	_end				@ r5
-	.long	processor_id			@ r6
-	.long	__machine_arch_type		@ r7
-	.long	cr_alignment			@ r8
+	.long	__data_loc			@ r4
+	.long	__data_start			@ r5
+	.long	__bss_start			@ r6
+	.long	_end				@ r7
+	.long	processor_id			@ r4
+	.long	__machine_arch_type		@ r5
+	.long	cr_alignment			@ r6
 	.long	init_thread_union+8192		@ sp
 
 /*
- * Enable the MMU.  This completely changes the structure of the visible
- * memory space.  You will not be able to trace execution through this.
- * If you have an enquiry about this, *please* check the linux-arm-kernel
- * mailing list archives BEFORE sending another post to the list.
- */
-	.align	5
-	.type	__turn_mmu_on, %function
-__turn_mmu_on:
-	ldr	lr, __switch_data
-#ifdef CONFIG_ALIGNMENT_TRAP
-	orr	r0, r0, #2			@ ...........A.
-#endif
-	mcr	p15, 0, r0, c1, c0, 0		@ write control reg
-	mrc	p15, 0, r3, c0, c0, 0		@ read id reg
-	mov	r3, r3
-	mov	r3, r3
-	mov	pc, lr
-
-/*
  * The following fragment of code is executed with the MMU on, and uses
  * absolute addresses; this is not position independent.
  *
- *  r0  = processor control register
+ *  r0  = cp#15 control register
  *  r1  = machine ID
  *  r9  = processor ID
- *  r12 = value of r0 when kernel was called (currently always zero)
  */
-	.align	5
+	.type	__mmap_switched, %function
 __mmap_switched:
-	adr	r2, __switch_data + 4
-	ldmia	r2, {r2, r3, r4, r5, r6, r7, r8, sp}
+	adr	r3, __switch_data + 4
 
-	cmp	r2, r3				@ Copy data segment if needed
-1:	cmpne	r3, r4
-	ldrne	fp, [r2], #4
-	strne	fp, [r3], #4
+	ldmia	r3!, {r4, r5, r6, r7}
+	cmp	r4, r5				@ Copy data segment if needed
+1:	cmpne	r5, r6
+	ldrne	fp, [r4], #4
+	strne	fp, [r5], #4
 	bne	1b
 
 	mov	fp, #0				@ Clear BSS (and zero fp)
-1:	cmp	r4, r5
-	strcc	fp, [r4],#4
+1:	cmp	r6, r7
+	strcc	fp, [r6],#4
 	bcc	1b
 
-	str	r9, [r6]			@ Save processor ID
-	str	r1, [r7]			@ Save machine type
-	bic	r2, r0, #2			@ Clear 'A' bit
-	stmia	r8, {r0, r2}			@ Save control register values
+	ldmia	r3, {r4, r5, r6, sp}
+	str	r9, [r4]			@ Save processor ID
+	str	r1, [r5]			@ Save machine type
+	bic	r4, r0, #CR_A			@ Clear 'A' bit
+	stmia	r6, {r0, r4}			@ Save control register values
 	b	start_kernel
 
 
 
+/*
+ * Setup common bits before finally enabling the MMU.  Essentially
+ * this is just loading the page table pointer and domain access
+ * registers.
+ */
+	.type	__enable_mmu, %function
+__enable_mmu:
+#ifdef CONFIG_ALIGNMENT_TRAP
+	orr	r0, r0, #CR_A
+#else
+	bic	r0, r0, #CR_A
+#endif
+#ifdef CONFIG_CPU_DCACHE_DISABLE
+	bic	r0, r0, #CR_C
+#endif
+#ifdef CONFIG_CPU_BPREDICT_DISABLE
+	bic	r0, r0, #CR_Z
+#endif
+#ifdef CONFIG_CPU_ICACHE_DISABLE
+	bic	r0, r0, #CR_I
+#endif
+	mov	r5, #(domain_val(DOMAIN_USER, DOMAIN_MANAGER) | \
+		      domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \
+		      domain_val(DOMAIN_TABLE, DOMAIN_MANAGER) | \
+		      domain_val(DOMAIN_IO, DOMAIN_CLIENT))
+	mcr	p15, 0, r5, c3, c0, 0		@ load domain access register
+	mcr	p15, 0, r4, c2, c0, 0		@ load page table pointer
+	b	__turn_mmu_on
+
+/*
+ * Enable the MMU.  This completely changes the structure of the visible
+ * memory space.  You will not be able to trace execution through this.
+ * If you have an enquiry about this, *please* check the linux-arm-kernel
+ * mailing list archives BEFORE sending another post to the list.
+ *
+ *  r0  = cp#15 control register
+ *  r13 = *virtual* address to jump to upon completion
+ *
+ * other registers depend on the function called upon completion
+ */
+	.align	5
+	.type	__turn_mmu_on, %function
+__turn_mmu_on:
+	mov	r0, r0
+	mcr	p15, 0, r0, c1, c0, 0		@ write control reg
+	mrc	p15, 0, r3, c0, c0, 0		@ read id reg
+	mov	r3, r3
+	mov	r3, r3
+	mov	pc, r13
+
+
 
 /*
  * Setup the initial page tables.  We only setup the barest
  * amount which are required to get the kernel running, which
  * generally means mapping in the kernel code.
  *
- * r5 = physical address of start of RAM
- * r6 = physical IO address
- * r7 = byte offset into page tables for IO
- * r8 = page table flags
+ * r8  = machinfo
+ * r9  = cpuid
+ * r10 = procinfo
+ *
+ * Returns:
+ *  r0, r3, r5, r6, r7 corrupted
+ *  r4 = physical page table address
  */
+	.type	__create_page_tables, %function
 __create_page_tables:
+	ldr	r5, [r8, #MACHINFO_PHYSRAM]	@ physram
 	pgtbl	r4, r5				@ page table address
 
 	/*
@@ -194,23 +241,25 @@
 	 */
 	mov	r0, r4
 	mov	r3, #0
-	add	r2, r0, #0x4000
+	add	r6, r0, #0x4000
 1:	str	r3, [r0], #4
 	str	r3, [r0], #4
 	str	r3, [r0], #4
 	str	r3, [r0], #4
-	teq	r0, r2
+	teq	r0, r6
 	bne	1b
 
+	ldr	r7, [r10, #PROCINFO_MMUFLAGS]	@ mmuflags
+
 	/*
 	 * Create identity mapping for first MB of kernel to
 	 * cater for the MMU enable.  This identity mapping
 	 * will be removed by paging_init().  We use our current program
 	 * counter to determine corresponding section base address.
 	 */
-	mov	r2, pc, lsr #20			@ start of kernel section
-	add	r3, r8, r2, lsl #20		@ flags + kernel base
-	str	r3, [r4, r2, lsl #2]		@ identity mapping
+	mov	r6, pc, lsr #20			@ start of kernel section
+	orr	r3, r7, r6, lsl #20		@ flags + kernel base
+	str	r3, [r4, r6, lsl #2]		@ identity mapping
 
 	/*
 	 * Now setup the pagetables for our kernel direct
@@ -231,8 +280,8 @@
 	 * Then map first 1MB of ram in case it contains our boot params.
 	 */
 	add	r0, r4, #VIRT_OFFSET >> 18
-	add	r2, r5, r8
-	str	r2, [r0]
+	orr	r6, r5, r7
+	str	r6, [r0]
 
 #ifdef CONFIG_XIP_KERNEL
 	/*
@@ -242,15 +291,15 @@
 	sub	r3, r4, r5
 	mov	r3, r3, lsr #20
 	add	r0, r0, r3, lsl #2
-	add	r2, r2, r3, lsl #20
-	str	r2, [r0], #4
-	add	r2, r2, #(1 << 20)
-	str	r2, [r0], #4
-	add	r2, r2, #(1 << 20)
-	str	r2, [r0]
+	add	r6, r6, r3, lsl #20
+	str	r6, [r0], #4
+	add	r6, r6, #(1 << 20)
+	str	r6, [r0], #4
+	add	r6, r6, #(1 << 20)
+	str	r6, [r0]
 #endif
 
-	bic	r8, r8, #0x0c			@ turn off cacheable
+	bic	r7, r7, #0x0c			@ turn off cacheable
 						@ and bufferable bits
 #ifdef CONFIG_DEBUG_LL
 	/*
@@ -258,15 +307,17 @@
 	 * This allows debug messages to be output
 	 * via a serial console before paging_init.
 	 */
-	add	r0, r4, r7
-	rsb	r3, r7, #0x4000			@ PTRS_PER_PGD*sizeof(long)
-	cmp	r3, #0x0800
-	addge	r2, r0, #0x0800
-	addlt	r2, r0, r3
-	orr	r3, r6, r8
+	ldr	r3, [r8, #MACHINFO_PGOFFIO]
+	add	r0, r4, r3
+	rsb	r3, r3, #0x4000			@ PTRS_PER_PGD*sizeof(long)
+	cmp	r3, #0x0800			@ limit to 512MB
+	movhi	r3, #0x0800
+	add	r6, r0, r3
+	ldr	r3, [r8, #MACHINFO_PHYSIO]
+	orr	r3, r3, r7
 1:	str	r3, [r0], #4
 	add	r3, r3, #1 << 20
-	teq	r0, r2
+	teq	r0, r6
 	bne	1b
 #if defined(CONFIG_ARCH_NETWINDER) || defined(CONFIG_ARCH_CATS)
 	/*
@@ -278,7 +329,7 @@
 	bne	1f
 	add	r0, r4, #0x3fc0			@ ff000000
 	mov	r3, #0x7c000000
-	orr	r3, r3, r8
+	orr	r3, r3, r7
 	str	r3, [r0], #4
 	add	r3, r3, #1 << 20
 	str	r3, [r0], #4
@@ -293,7 +344,7 @@
 	 */
 	add	r0, r4, #0x80			@ 02000000
 	mov	r3, #0x02000000
-	orr	r3, r3, r8
+	orr	r3, r3, r7
 	str	r3, [r0]
 	add	r0, r4, #0x3600			@ d8000000
 	str	r3, [r0]
@@ -315,6 +366,7 @@
  *
  * Generally, only serious errors cause this.
  */
+	.type	__error, %function
 __error:
 #ifdef CONFIG_DEBUG_LL
 	mov	r8, r0				@ preserve r0
@@ -340,6 +392,7 @@
 	b	1b
 
 #ifdef CONFIG_DEBUG_LL
+	.type	err_str, %object
 err_str:
 	.asciz	"\nError: "
 	.align
@@ -353,35 +406,44 @@
  * calculate the offset.
  *
  * Returns:
- *	r5, r6, r7 corrupted
- *	r8  = page table flags
- *	r9  = processor ID
- *	r10 = pointer to processor structure
+ *	r3, r4, r6 corrupted
+ *	r5 = proc_info pointer in physical address space
+ *	r9 = cpuid
  */
+	.type	__lookup_processor_type, %function
 __lookup_processor_type:
-	adr	r5, 2f
-	ldmia	r5, {r7, r9, r10}
-	sub	r5, r5, r10			@ convert addresses
-	add	r7, r7, r5			@ to our address space
-	add	r10, r9, r5
+	adr	r3, 3f
+	ldmda	r3, {r5, r6, r9}
+	sub	r3, r3, r9			@ get offset between virt&phys
+	add	r5, r5, r3			@ convert virt addresses to
+	add	r6, r6, r3			@ physical address space
 	mrc	p15, 0, r9, c0, c0		@ get processor id
-1:	ldmia	r10, {r5, r6, r8}		@ value, mask, mmuflags
-	and	r6, r6, r9			@ mask wanted bits
-	teq	r5, r6
-	moveq	pc, lr
-	add	r10, r10, #PROC_INFO_SZ		@ sizeof(proc_info_list)
-	cmp	r10, r7
+1:	ldmia	r5, {r3, r4}			@ value, mask
+	and	r4, r4, r9			@ mask wanted bits
+	teq	r3, r4
+	beq	2f
+	add	r5, r5, #PROC_INFO_SZ		@ sizeof(proc_info_list)
+	cmp	r5, r6
 	blt	1b
-	mov	r10, #0				@ unknown processor
-	mov	pc, lr
+	mov	r5, #0				@ unknown processor
+2:	mov	pc, lr
+
+/*
+ * This provides a C-API version of the above function.
+ */
+ENTRY(lookup_processor_type)
+	stmfd	sp!, {r4 - r6, r9, lr}
+	bl	__lookup_processor_type
+	mov	r0, r5
+	ldmfd	sp!, {r4 - r6, r9, pc}
 
 /*
  * Look in include/asm-arm/procinfo.h and arch/arm/kernel/arch.[ch] for
  * more information about the __proc_info and __arch_info structures.
  */
-2:	.long	__proc_info_end
 	.long	__proc_info_begin
-	.long	2b
+	.long	__proc_info_end
+3:	.long	.
 	.long	__arch_info_begin
 	.long	__arch_info_end
 
@@ -393,24 +455,31 @@
  *
  *  r1 = machine architecture number
  * Returns:
- *  r2, r3, r4 corrupted
- *  r5 = physical start address of RAM
- *  r6 = physical address of IO
- *  r7 = byte offset into page tables for IO
- */
-__lookup_architecture_type:
-	adr	r4, 2b
-	ldmia	r4, {r2, r3, r5, r6, r7}	@ throw away r2, r3
-	sub	r5, r4, r5			@ convert addresses
-	add	r4, r6, r5			@ to our address space
-	add	r7, r7, r5
-1:	ldr	r5, [r4]			@ get machine type
-	teq	r5, r1				@ matches loader number?
+ *  r3, r4, r6 corrupted
+ *  r5 = mach_info pointer in physical address space
+ */
+	.type	__lookup_machine_type, %function
+__lookup_machine_type:
+	adr	r3, 3b
+	ldmia	r3, {r4, r5, r6}
+	sub	r3, r3, r4			@ get offset between virt&phys
+	add	r5, r5, r3			@ convert virt addresses to
+	add	r6, r6, r3			@ physical address space
+1:	ldr	r3, [r5]			@ get machine type
+	teq	r3, r1				@ matches loader number?
 	beq	2f				@ found
-	add	r4, r4, #SIZEOF_MACHINE_DESC	@ next machine_desc
-	cmp	r4, r7
+	add	r5, r5, #SIZEOF_MACHINE_DESC	@ next machine_desc
+	cmp	r5, r6
 	blt	1b
-	mov	r7, #0				@ unknown architecture
-	mov	pc, lr
-2:	ldmib	r4, {r5, r6, r7}		@ found, get results
-	mov	pc, lr
+	mov	r5, #0				@ unknown machine
+2:	mov	pc, lr
+
+/*
+ * This provides a C-API version of the above function.
+ */
+ENTRY(lookup_machine_type)
+	stmfd	sp!, {r4 - r6, lr}
+	mov	r1, r0
+	bl	__lookup_machine_type
+	mov	r0, r5
+	ldmfd	sp!, {r4 - r6, pc}
diff -Nru a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
--- a/arch/arm/kernel/irq.c	2005-03-01 23:38:44 -08:00
+++ b/arch/arm/kernel/irq.c	2005-03-01 23:38:44 -08:00
@@ -32,6 +32,7 @@
 #include <linux/errno.h>
 #include <linux/list.h>
 #include <linux/kallsyms.h>
+#include <linux/proc_fs.h>
 
 #include <asm/irq.h>
 #include <asm/system.h>
@@ -48,7 +49,7 @@
 
 static int noirqdebug;
 static volatile unsigned long irq_err_count;
-static spinlock_t irq_controller_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(irq_controller_lock);
 static LIST_HEAD(irq_pending);
 
 struct irqdesc irq_desc[NR_IRQS];
@@ -85,6 +86,23 @@
 	.disable_depth	= 1,
 };
 
+#ifdef CONFIG_SMP
+void synchronize_irq(unsigned int irq)
+{
+	struct irqdesc *desc = irq_desc + irq;
+
+	while (desc->running)
+		barrier();
+}
+EXPORT_SYMBOL(synchronize_irq);
+
+#define smp_set_running(desc)	do { desc->running = 1; } while (0)
+#define smp_clear_running(desc)	do { desc->running = 0; } while (0)
+#else
+#define smp_set_running(desc)	do { } while (0)
+#define smp_clear_running(desc)	do { } while (0)
+#endif
+
 /**
  *	disable_irq_nosync - disable an irq without waiting
  *	@irq: Interrupt to disable
@@ -232,6 +250,9 @@
 #ifdef CONFIG_ARCH_ACORN
 		show_fiq_list(p, v);
 #endif
+#ifdef CONFIG_SMP
+		show_ipi_list(p);
+#endif
 		seq_printf(p, "Err: %10lu\n", irq_err_count);
 	}
 	return 0;
@@ -329,18 +350,22 @@
 do_simple_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
 {
 	struct irqaction *action;
-	const int cpu = smp_processor_id();
+	const unsigned int cpu = smp_processor_id();
 
 	desc->triggered = 1;
 
 	kstat_cpu(cpu).irqs[irq]++;
 
+	smp_set_running(desc);
+
 	action = desc->action;
 	if (action) {
 		int ret = __do_irq(irq, action, regs);
 		if (ret != IRQ_HANDLED)
 			report_bad_irq(irq, regs, desc, ret);
 	}
+
+	smp_clear_running(desc);
 }
 
 /*
@@ -350,7 +375,7 @@
 void
 do_edge_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
 {
-	const int cpu = smp_processor_id();
+	const unsigned int cpu = smp_processor_id();
 
 	desc->triggered = 1;
 
@@ -414,7 +439,7 @@
 do_level_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
 {
 	struct irqaction *action;
-	const int cpu = smp_processor_id();
+	const unsigned int cpu = smp_processor_id();
 
 	desc->triggered = 1;
 
@@ -426,6 +451,8 @@
 	if (likely(!desc->disable_depth)) {
 		kstat_cpu(cpu).irqs[irq]++;
 
+		smp_set_running(desc);
+
 		/*
 		 * Return with this interrupt masked if no action
 		 */
@@ -440,6 +467,8 @@
 				   !check_irq_lock(desc, irq, regs)))
 				desc->chip->unmask(irq);
 		}
+
+		smp_clear_running(desc);
 	}
 }
 
@@ -878,8 +907,97 @@
 
 EXPORT_SYMBOL(probe_irq_off);
 
+#ifdef CONFIG_SMP
+static void route_irq(struct irqdesc *desc, unsigned int irq, unsigned int cpu)
+{
+	pr_debug("IRQ%u: moving from cpu%u to cpu%u\n", irq, desc->cpu, cpu);
+
+	spin_lock_irq(&irq_controller_lock);
+	desc->cpu = cpu;
+	desc->chip->set_cpu(desc, irq, cpu);
+	spin_unlock_irq(&irq_controller_lock);
+}
+
+#ifdef CONFIG_PROC_FS
+static int
+irq_affinity_read_proc(char *page, char **start, off_t off, int count,
+		       int *eof, void *data)
+{
+	struct irqdesc *desc = irq_desc + ((int)data);
+	int len = cpumask_scnprintf(page, count, desc->affinity);
+
+	if (count - len < 2)
+		return -EINVAL;
+	page[len++] = '\n';
+	page[len] = '\0';
+
+	return len;
+}
+
+static int
+irq_affinity_write_proc(struct file *file, const char __user *buffer,
+			unsigned long count, void *data)
+{
+	unsigned int irq = (unsigned int)data;
+	struct irqdesc *desc = irq_desc + irq;
+	cpumask_t affinity, tmp;
+	int ret = -EIO;
+
+	if (!desc->chip->set_cpu)
+		goto out;
+
+	ret = cpumask_parse(buffer, count, affinity);
+	if (ret)
+		goto out;
+
+	cpus_and(tmp, affinity, cpu_online_map);
+	if (cpus_empty(tmp)) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	desc->affinity = affinity;
+	route_irq(desc, irq, first_cpu(tmp));
+	ret = count;
+
+ out:
+	return ret;
+}
+#endif
+#endif
+
 void __init init_irq_proc(void)
 {
+#if defined(CONFIG_SMP) && defined(CONFIG_PROC_FS)
+	struct proc_dir_entry *dir;
+	int irq;
+
+	dir = proc_mkdir("irq", 0);
+	if (!dir)
+		return;
+
+	for (irq = 0; irq < NR_IRQS; irq++) {
+		struct proc_dir_entry *entry;
+		struct irqdesc *desc;
+		char name[16];
+
+		desc = irq_desc + irq;
+		memset(name, 0, sizeof(name));
+		snprintf(name, sizeof(name) - 1, "%u", irq);
+
+		desc->procdir = proc_mkdir(name, dir);
+		if (!desc->procdir)
+			continue;
+
+		entry = create_proc_entry("smp_affinity", 0600, desc->procdir);
+		if (entry) {
+			entry->nlink = 1;
+			entry->data = (void *)irq;
+			entry->read_proc = irq_affinity_read_proc;
+			entry->write_proc = irq_affinity_write_proc;
+		}
+	}
+#endif
 }
 
 void __init init_IRQ(void)
@@ -887,6 +1005,11 @@
 	struct irqdesc *desc;
 	extern void init_dma(void);
 	int irq;
+
+#ifdef CONFIG_SMP
+	bad_irq_desc.affinity = CPU_MASK_ALL;
+	bad_irq_desc.cpu = smp_processor_id();
+#endif
 
 	for (irq = 0, desc = irq_desc; irq < NR_IRQS; irq++, desc++) {
 		*desc = bad_irq_desc;
diff -Nru a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
--- a/arch/arm/kernel/process.c	2005-03-01 23:39:16 -08:00
+++ b/arch/arm/kernel/process.c	2005-03-01 23:39:16 -08:00
@@ -352,6 +352,9 @@
 	thread->cpu_context.sp = (unsigned long)childregs;
 	thread->cpu_context.pc = (unsigned long)ret_from_fork;
 
+	if (clone_flags & CLONE_SETTLS)
+		thread->tp_value = regs->ARM_r3;
+
 	return 0;
 }
 
diff -Nru a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
--- a/arch/arm/kernel/ptrace.c	2005-03-01 23:38:52 -08:00
+++ b/arch/arm/kernel/ptrace.c	2005-03-01 23:38:52 -08:00
@@ -719,6 +719,11 @@
 			ret = ptrace_setfpregs(child, (void __user *)data);
 			break;
 
+		case PTRACE_GET_THREAD_AREA:
+			ret = put_user(child->thread_info->tp_value,
+				       (unsigned long __user *) data);
+			break;
+
 		default:
 			ret = ptrace_request(child, request, addr, data);
 			break;
diff -Nru a/arch/arm/kernel/semaphore.c b/arch/arm/kernel/semaphore.c
--- a/arch/arm/kernel/semaphore.c	2005-03-01 23:38:56 -08:00
+++ b/arch/arm/kernel/semaphore.c	2005-03-01 23:38:56 -08:00
@@ -54,7 +54,7 @@
 	wake_up(&sem->wait);
 }
 
-static spinlock_t semaphore_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(semaphore_lock);
 
 void __sched __down(struct semaphore * sem)
 {
@@ -178,7 +178,7 @@
  * registers (r0 to r3 and lr), but not ip, as we use it as a return
  * value in some cases..
  */
-asm("	.section .sched.text			\n\
+asm("	.section .sched.text,\"ax\"		\n\
 	.align	5				\n\
 	.globl	__down_failed			\n\
 __down_failed:					\n\
diff -Nru a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
--- a/arch/arm/kernel/setup.c	2005-03-01 23:38:58 -08:00
+++ b/arch/arm/kernel/setup.c	2005-03-01 23:38:58 -08:00
@@ -24,6 +24,7 @@
 #include <linux/cpu.h>
 #include <linux/interrupt.h>
 
+#include <asm/cpu.h>
 #include <asm/elf.h>
 #include <asm/hardware.h>
 #include <asm/io.h>
@@ -108,6 +109,8 @@
 static union { char c[4]; unsigned long l; } endian_test __initdata = { { 'l', '?', '?', 'b' } };
 #define ENDIANNESS ((char)endian_test.l)
 
+DEFINE_PER_CPU(struct cpuinfo_arm, cpu_data);
+
 /*
  * Standard memory resources
  */
@@ -218,12 +221,12 @@
 #define CACHE_M(y)	((y) & (1 << 2))
 #define CACHE_LINE(y)	((y) & 3)
 
-static inline void dump_cache(const char *prefix, unsigned int cache)
+static inline void dump_cache(const char *prefix, int cpu, unsigned int cache)
 {
 	unsigned int mult = 2 + (CACHE_M(cache) ? 1 : 0);
 
-	printk("%s: %d bytes, associativity %d, %d byte lines, %d sets\n",
-		prefix,
+	printk("CPU%u: %s: %d bytes, associativity %d, %d byte lines, %d sets\n",
+		cpu, prefix,
 		mult << (8 + CACHE_SIZE(cache)),
 		(mult << CACHE_ASSOC(cache)) >> 1,
 		8 << CACHE_LINE(cache),
@@ -231,18 +234,18 @@
 			CACHE_LINE(cache)));
 }
 
-static void __init dump_cpu_info(void)
+static void __init dump_cpu_info(int cpu)
 {
 	unsigned int info = read_cpuid(CPUID_CACHETYPE);
 
 	if (info != processor_id) {
-		printk("CPU: D %s %s cache\n", cache_is_vivt() ? "VIVT" : "VIPT",
+		printk("CPU%u: D %s %s cache\n", cpu, cache_is_vivt() ? "VIVT" : "VIPT",
 		       cache_types[CACHE_TYPE(info)]);
 		if (CACHE_S(info)) {
-			dump_cache("CPU: I cache", CACHE_ISIZE(info));
-			dump_cache("CPU: D cache", CACHE_DSIZE(info));
+			dump_cache("I cache", cpu, CACHE_ISIZE(info));
+			dump_cache("D cache", cpu, CACHE_DSIZE(info));
 		} else {
-			dump_cache("CPU: cache", CACHE_ISIZE(info));
+			dump_cache("cache", cpu, CACHE_ISIZE(info));
 		}
 	}
 }
@@ -264,9 +267,15 @@
 	return cpu_arch;
 }
 
+/*
+ * These functions re-use the assembly code in head.S, which
+ * already provide the required functionality.
+ */
+extern struct proc_info_list *lookup_processor_type(void);
+extern struct machine_desc *lookup_machine_type(unsigned int);
+
 static void __init setup_processor(void)
 {
-	extern struct proc_info_list __proc_info_begin, __proc_info_end;
 	struct proc_info_list *list;
 
 	/*
@@ -274,15 +283,8 @@
 	 * types.  The linker builds this table for us from the
 	 * entries in arch/arm/mm/proc-*.S
 	 */
-	for (list = &__proc_info_begin; list < &__proc_info_end ; list++)
-		if ((processor_id & list->cpu_mask) == list->cpu_val)
-			break;
-
-	/*
-	 * If processor type is unrecognised, then we
-	 * can do nothing...
-	 */
-	if (list >= &__proc_info_end) {
+	list = lookup_processor_type();
+	if (!list) {
 		printk("CPU configuration botched (ID %08x), unable "
 		       "to continue.\n", processor_id);
 		while (1);
@@ -307,7 +309,7 @@
 	       cpu_name, processor_id, (int)processor_id & 15,
 	       proc_arch[cpu_architecture()]);
 
-	dump_cpu_info();
+	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);
@@ -318,22 +320,14 @@
 
 static struct machine_desc * __init setup_machine(unsigned int nr)
 {
-	extern struct machine_desc __arch_info_begin, __arch_info_end;
 	struct machine_desc *list;
 
 	/*
-	 * locate architecture in the list of supported architectures.
+	 * locate machine in the list of supported machines.
 	 */
-	for (list = &__arch_info_begin; list < &__arch_info_end; list++)
-		if (list->nr == nr)
-			break;
-
-	/*
-	 * If the architecture type is not recognised, then we
-	 * can co nothing...
-	 */
-	if (list >= &__arch_info_end) {
-		printk("Architecture configuration botched (nr %d), unable "
+	list = lookup_machine_type(nr);
+	if (!list) {
+		printk("Machine configuration botched (nr %d), unable "
 		       "to continue.\n", nr);
 		while (1);
 	}
@@ -739,11 +733,15 @@
 #endif
 }
 
-static struct cpu cpu[1];
 
 static int __init topology_init(void)
 {
-	return register_cpu(cpu, 0, NULL);
+	int cpu;
+
+	for_each_cpu(cpu)
+		register_cpu(&per_cpu(cpu_data, cpu).cpu, cpu, NULL);
+
+	return 0;
 }
 
 subsys_initcall(topology_init);
@@ -784,9 +782,18 @@
 	seq_printf(m, "Processor\t: %s rev %d (%s)\n",
 		   cpu_name, (int)processor_id & 15, elf_platform);
 
+#if defined(CONFIG_SMP)
+	for_each_online_cpu(i) {
+		seq_printf(m, "Processor\t: %d\n", i);
+		seq_printf(m, "BogoMIPS\t: %lu.%02lu\n\n",
+			   per_cpu(cpu_data, i).loops_per_jiffy / (500000UL/HZ),
+			   (per_cpu(cpu_data, i).loops_per_jiffy / (5000UL/HZ)) % 100);
+	}
+#else /* CONFIG_SMP */
 	seq_printf(m, "BogoMIPS\t: %lu.%02lu\n",
 		   loops_per_jiffy / (500000/HZ),
 		   (loops_per_jiffy / (5000/HZ)) % 100);
+#endif
 
 	/* dump out the processor features */
 	seq_puts(m, "Features\t: ");
diff -Nru a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
--- a/arch/arm/kernel/signal.c	2005-03-01 23:38:51 -08:00
+++ b/arch/arm/kernel/signal.c	2005-03-01 23:38:51 -08:00
@@ -12,7 +12,6 @@
 #include <linux/signal.h>
 #include <linux/ptrace.h>
 #include <linux/personality.h>
-#include <linux/suspend.h>
 
 #include <asm/cacheflush.h>
 #include <asm/ucontext.h>
@@ -689,10 +688,8 @@
 	if (!user_mode(regs))
 		return 0;
 
-	if (current->flags & PF_FREEZE) {
-		refrigerator(0);
+	if (try_to_freeze(0))
 		goto no_signal;
-	}
 
 	if (current->ptrace & PT_SINGLESTEP)
 		ptrace_cancel_bpt(current);
diff -Nru a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/arm/kernel/smp.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,396 @@
+/*
+ *  linux/arch/arm/kernel/smp.c
+ *
+ *  Copyright (C) 2002 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/config.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/cache.h>
+#include <linux/profile.h>
+#include <linux/errno.h>
+#include <linux/mm.h>
+#include <linux/cpu.h>
+#include <linux/smp.h>
+#include <linux/seq_file.h>
+
+#include <asm/atomic.h>
+#include <asm/cacheflush.h>
+#include <asm/cpu.h>
+#include <asm/processor.h>
+#include <asm/tlbflush.h>
+#include <asm/ptrace.h>
+
+/*
+ * bitmask of present and online CPUs.
+ * 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_online_map;
+
+/*
+ * structures for inter-processor calls
+ * - A collection of single bit ipi messages.
+ */
+struct ipi_data {
+	spinlock_t lock;
+	unsigned long ipi_count;
+	unsigned long bits;
+};
+
+static DEFINE_PER_CPU(struct ipi_data, ipi_data) = {
+	.lock	= SPIN_LOCK_UNLOCKED,
+};
+
+enum ipi_msg_type {
+	IPI_TIMER,
+	IPI_RESCHEDULE,
+	IPI_CALL_FUNC,
+	IPI_CPU_STOP,
+};
+
+struct smp_call_struct {
+	void (*func)(void *info);
+	void *info;
+	int wait;
+	cpumask_t pending;
+	cpumask_t unfinished;
+};
+
+static struct smp_call_struct * volatile smp_call_function_data;
+static DEFINE_SPINLOCK(smp_call_function_lock);
+
+int __init __cpu_up(unsigned int cpu)
+{
+	struct task_struct *idle;
+	int ret;
+
+	/*
+	 * Spawn a new process manually.  Grab a pointer to
+	 * its task struct so we can mess with it
+	 */
+	idle = fork_idle(cpu);
+	if (IS_ERR(idle)) {
+		printk(KERN_ERR "CPU%u: fork() failed\n", cpu);
+		return PTR_ERR(idle);
+	}
+
+	/*
+	 * Now bring the CPU into our world.
+	 */
+	ret = boot_secondary(cpu, idle);
+	if (ret) {
+		printk(KERN_CRIT "cpu_up: processor %d failed to boot\n", cpu);
+		/*
+		 * FIXME: We need to clean up the new idle thread. --rmk
+		 */
+	}
+
+	return ret;
+}
+
+/*
+ * Called by both boot and secondaries to move global data into
+ * per-processor storage.
+ */
+void __init smp_store_cpu_info(unsigned int cpuid)
+{
+	struct cpuinfo_arm *cpu_info = &per_cpu(cpu_data, cpuid);
+
+	cpu_info->loops_per_jiffy = loops_per_jiffy;
+}
+
+void __init smp_cpus_done(unsigned int max_cpus)
+{
+	int cpu;
+	unsigned long bogosum = 0;
+
+	for_each_online_cpu(cpu)
+		bogosum += per_cpu(cpu_data, cpu).loops_per_jiffy;
+
+	printk(KERN_INFO "SMP: Total of %d processors activated "
+	       "(%lu.%02lu BogoMIPS).\n",
+	       num_online_cpus(),
+	       bogosum / (500000/HZ),
+	       (bogosum / (5000/HZ)) % 100);
+}
+
+void __init smp_prepare_boot_cpu(void)
+{
+	unsigned int cpu = smp_processor_id();
+
+	cpu_set(cpu, cpu_present_mask);
+	cpu_set(cpu, cpu_online_map);
+}
+
+static void send_ipi_message(cpumask_t callmap, enum ipi_msg_type msg)
+{
+	unsigned long flags;
+	unsigned int cpu;
+
+	local_irq_save(flags);
+
+	for_each_cpu_mask(cpu, callmap) {
+		struct ipi_data *ipi = &per_cpu(ipi_data, cpu);
+
+		spin_lock(&ipi->lock);
+		ipi->bits |= 1 << msg;
+		spin_unlock(&ipi->lock);
+	}
+
+	/*
+	 * Call the platform specific cross-CPU call function.
+	 */
+	smp_cross_call(callmap);
+
+	local_irq_restore(flags);
+}
+
+/*
+ * You must not call this function with disabled interrupts, from a
+ * hardware interrupt handler, nor from a bottom half handler.
+ */
+int smp_call_function_on_cpu(void (*func)(void *info), void *info, int retry,
+                             int wait, cpumask_t callmap)
+{
+	struct smp_call_struct data;
+	unsigned long timeout;
+	int ret = 0;
+
+	data.func = func;
+	data.info = info;
+	data.wait = wait;
+
+	cpu_clear(smp_processor_id(), callmap);
+	if (cpus_empty(callmap))
+		goto out;
+
+	data.pending = callmap;
+	if (wait)
+		data.unfinished = callmap;
+
+	/*
+	 * try to get the mutex on smp_call_function_data
+	 */
+	spin_lock(&smp_call_function_lock);
+	smp_call_function_data = &data;
+
+	send_ipi_message(callmap, IPI_CALL_FUNC);
+
+	timeout = jiffies + HZ;
+	while (!cpus_empty(data.pending) && time_before(jiffies, timeout))
+		barrier();
+
+	/*
+	 * did we time out?
+	 */
+	if (!cpus_empty(data.pending)) {
+		/*
+		 * this may be causing our panic - report it
+		 */
+		printk(KERN_CRIT
+		       "CPU%u: smp_call_function timeout for %p(%p)\n"
+		       "      callmap %lx pending %lx, %swait\n",
+		       smp_processor_id(), func, info, callmap, data.pending,
+		       wait ? "" : "no ");
+
+		/*
+		 * TRACE
+		 */
+		timeout = jiffies + (5 * HZ);
+		while (!cpus_empty(data.pending) && time_before(jiffies, timeout))
+			barrier();
+
+		if (cpus_empty(data.pending))
+			printk(KERN_CRIT "     RESOLVED\n");
+		else
+			printk(KERN_CRIT "     STILL STUCK\n");
+	}
+
+	/*
+	 * whatever happened, we're done with the data, so release it
+	 */
+	smp_call_function_data = NULL;
+	spin_unlock(&smp_call_function_lock);
+
+	if (!cpus_empty(data.pending)) {
+		ret = -ETIMEDOUT;
+		goto out;
+	}
+
+	if (wait)
+		while (!cpus_empty(data.unfinished))
+			barrier();
+ out:
+
+	return 0;
+}
+
+int smp_call_function(void (*func)(void *info), void *info, int retry,
+                      int wait)
+{
+	return smp_call_function_on_cpu(func, info, retry, wait,
+					cpu_online_map);
+}
+
+void show_ipi_list(struct seq_file *p)
+{
+	unsigned int cpu;
+
+	seq_puts(p, "IPI:");
+
+	for_each_online_cpu(cpu)
+		seq_printf(p, " %10lu", per_cpu(ipi_data, cpu).ipi_count);
+
+	seq_putc(p, '\n');
+}
+
+static void ipi_timer(struct pt_regs *regs)
+{
+	int user = user_mode(regs);
+
+	irq_enter();
+	profile_tick(CPU_PROFILING, regs);
+	update_process_times(user);
+	irq_exit();
+}
+
+/*
+ * ipi_call_function - handle IPI from smp_call_function()
+ *
+ * Note that we copy data out of the cross-call structure and then
+ * let the caller know that we're here and have done with their data
+ */
+static void ipi_call_function(unsigned int cpu)
+{
+	struct smp_call_struct *data = smp_call_function_data;
+	void (*func)(void *info) = data->func;
+	void *info = data->info;
+	int wait = data->wait;
+
+	cpu_clear(cpu, data->pending);
+
+	func(info);
+
+	if (wait)
+		cpu_clear(cpu, data->unfinished);
+}
+
+static DEFINE_SPINLOCK(stop_lock);
+
+/*
+ * ipi_cpu_stop - handle IPI from smp_send_stop()
+ */
+static void ipi_cpu_stop(unsigned int cpu)
+{
+	spin_lock(&stop_lock);
+	printk(KERN_CRIT "CPU%u: stopping\n", cpu);
+	dump_stack();
+	spin_unlock(&stop_lock);
+
+	cpu_clear(cpu, cpu_online_map);
+
+	local_fiq_disable();
+	local_irq_disable();
+
+	while (1)
+		cpu_relax();
+}
+
+/*
+ * Main handler for inter-processor interrupts
+ *
+ * For ARM, the ipimask now only identifies a single
+ * category of IPI (Bit 1 IPIs have been replaced by a
+ * different mechanism):
+ *
+ *  Bit 0 - Inter-processor function call
+ */
+void do_IPI(struct pt_regs *regs)
+{
+	unsigned int cpu = smp_processor_id();
+	struct ipi_data *ipi = &per_cpu(ipi_data, cpu);
+
+	ipi->ipi_count++;
+
+	for (;;) {
+		unsigned long msgs;
+
+		spin_lock(&ipi->lock);
+		msgs = ipi->bits;
+		ipi->bits = 0;
+		spin_unlock(&ipi->lock);
+
+		if (!msgs)
+			break;
+
+		do {
+			unsigned nextmsg;
+
+			nextmsg = msgs & -msgs;
+			msgs &= ~nextmsg;
+			nextmsg = ffz(~nextmsg);
+
+			switch (nextmsg) {
+			case IPI_TIMER:
+				ipi_timer(regs);
+				break;
+
+			case IPI_RESCHEDULE:
+				/*
+				 * nothing more to do - eveything is
+				 * done on the interrupt return path
+				 */
+				break;
+
+			case IPI_CALL_FUNC:
+				ipi_call_function(cpu);
+				break;
+
+			case IPI_CPU_STOP:
+				ipi_cpu_stop(cpu);
+				break;
+
+			default:
+				printk(KERN_CRIT "CPU%u: Unknown IPI message 0x%x\n",
+				       cpu, nextmsg);
+				break;
+			}
+		} while (msgs);
+	}
+}
+
+void smp_send_reschedule(int cpu)
+{
+	send_ipi_message(cpumask_of_cpu(cpu), IPI_RESCHEDULE);
+}
+
+void smp_send_timer(void)
+{
+	cpumask_t mask = cpu_online_map;
+	cpu_clear(smp_processor_id(), mask);
+	send_ipi_message(mask, IPI_TIMER);
+}
+
+void smp_send_stop(void)
+{
+	cpumask_t mask = cpu_online_map;
+	cpu_clear(smp_processor_id(), mask);
+	send_ipi_message(mask, IPI_CPU_STOP);
+}
+
+/*
+ * not supported here
+ */
+int __init setup_profiling_timer(unsigned int multiplier)
+{
+	return -EINVAL;
+}
diff -Nru a/arch/arm/kernel/sys_arm.c b/arch/arm/kernel/sys_arm.c
--- a/arch/arm/kernel/sys_arm.c	2005-03-01 23:38:53 -08:00
+++ b/arch/arm/kernel/sys_arm.c	2005-03-01 23:38:53 -08:00
@@ -241,18 +241,14 @@
 /* Clone a task - this clones the calling program thread.
  * This is called indirectly via a small wrapper
  */
-asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp, struct pt_regs *regs)
+asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
+			 int __user *parent_tidptr, int tls_val,
+			 int __user *child_tidptr, struct pt_regs *regs)
 {
-	/*
-	 * We don't support SETTID / CLEARTID
-	 */
-	if (clone_flags & (CLONE_PARENT_SETTID | CLONE_CHILD_CLEARTID))
-		return -EINVAL;
-
 	if (!newsp)
 		newsp = regs->ARM_sp;
 
-	return do_fork(clone_flags, newsp, regs, 0, NULL, NULL);
+	return do_fork(clone_flags, newsp, regs, 0, parent_tidptr, child_tidptr);
 }
 
 asmlinkage int sys_vfork(struct pt_regs *regs)
diff -Nru a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
--- a/arch/arm/kernel/time.c	2005-03-01 23:39:08 -08:00
+++ b/arch/arm/kernel/time.c	2005-03-01 23:39:08 -08:00
@@ -48,7 +48,7 @@
 extern unsigned long wall_jiffies;
 
 /* this needs a better home */
-spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(rtc_lock);
 
 #ifdef CONFIG_SA1100_RTC_MODULE
 EXPORT_SYMBOL(rtc_lock);
@@ -63,7 +63,7 @@
 	unsigned long fp, pc = instruction_pointer(regs);
 
 	if (in_lock_functions(pc)) {
-		fp = thread_saved_fp(current);
+		fp = regs->ARM_fp;
 		pc = pc_pointer(((unsigned long *)fp)[-1]);
 	}
 
diff -Nru a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
--- a/arch/arm/kernel/traps.c	2005-03-01 23:38:56 -08:00
+++ b/arch/arm/kernel/traps.c	2005-03-01 23:38:56 -08:00
@@ -200,7 +200,7 @@
 	barrier();
 }
 
-spinlock_t die_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(die_lock);
 
 /*
  * This function is protected against re-entrancy.
@@ -241,7 +241,7 @@
 }
 
 static LIST_HEAD(undef_hook);
-static spinlock_t undef_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(undef_lock);
 
 void register_undef_hook(struct undef_hook *hook)
 {
@@ -393,6 +393,7 @@
 #define NR(x) ((__ARM_NR_##x) - __ARM_NR_BASE)
 asmlinkage int arm_syscall(int no, struct pt_regs *regs)
 {
+	struct thread_info *thread = current_thread_info();
 	siginfo_t info;
 
 	if ((no >> 16) != 0x9f)
@@ -444,6 +445,17 @@
 			break;
 		regs->ARM_cpsr |= MODE32_BIT;
 		return regs->ARM_r0;
+
+	case NR(set_tls):
+		thread->tp_value = regs->ARM_r0;
+		/*
+		 * Our user accessible TLS ptr is located at 0xffff0ffc.
+		 * On SMP read access to this address must raise a fault
+		 * and be emulated from the data abort handler.
+		 * m
+		 */
+		*((unsigned long *)0xffff0ffc) = thread->tp_value;
+		return 0;
 
 	default:
 		/* Calls 9f00xx..9f07ff are defined to return -ENOSYS
diff -Nru a/arch/arm/lib/io-readsw-armv4.S b/arch/arm/lib/io-readsw-armv4.S
--- a/arch/arm/lib/io-readsw-armv4.S	2005-03-01 23:38:58 -08:00
+++ b/arch/arm/lib/io-readsw-armv4.S	2005-03-01 23:38:58 -08:00
@@ -18,25 +18,14 @@
 #endif
 		.endm
 
-.insw_bad_alignment:
-		adr	r0, .insw_bad_align_msg
-		mov	r2, lr
-		b	panic
-.insw_bad_align_msg:
-		.asciz	"insw: bad buffer alignment (0x%p, lr=0x%08lX)\n"
-		.align
-
-.insw_align:	tst	r1, #1
-		bne	.insw_bad_alignment
-
-		ldrh	r3, [r0]
-		strh	r3, [r1], #2
-
-		subs	r2, r2, #1
-		RETINSTR(moveq, pc, lr)
+.insw_align:	movs	ip, r1, lsl #31
+		bne	.insw_noalign
+		ldrh	ip, [r0]
+		sub	r2, r2, #1
+		strh	ip, [r1], #2
 
 ENTRY(__raw_readsw)
-		teq	r2, #0		@ do we have to check for the zero len?
+		teq	r2, #0
 		moveq	pc, lr
 		tst	r1, #3
 		bne	.insw_align
@@ -62,14 +51,10 @@
 		ldrh	lr, [r0]
 		pack	ip, ip, lr
 
-		stmia	r1!, {r3 - r5, ip}
-
 		subs	r2, r2, #8
+		stmia	r1!, {r3 - r5, ip}
 		bpl	.insw_8_lp
 
-		tst	r2, #7
-		LOADREGS(eqfd, sp!, {r4, r5, pc})
-
 .no_insw_8:	tst	r2, #4
 		beq	.no_insw_4
 
@@ -83,17 +68,63 @@
 
 		stmia	r1!, {r3, r4}
 
-.no_insw_4:	tst	r2, #2
-		beq	.no_insw_2
+.no_insw_4:	movs	r2, r2, lsl #31
+		bcc	.no_insw_2
 
 		ldrh	r3, [r0]
 		ldrh	ip, [r0]
 		pack	r3, r3, ip
-
 		str	r3, [r1], #4
 
-.no_insw_2:	tst	r2, #1
-		ldrneh	r3, [r0]
+.no_insw_2:	ldrneh	r3, [r0]
 		strneh	r3, [r1]
 
-		LOADREGS(fd, sp!, {r4, r5, pc})
+		ldmfd	sp!, {r4, r5, pc}
+
+#ifdef __ARMEB__
+#define _BE_ONLY_(code...)	code
+#define _LE_ONLY_(code...)
+#define push_hbyte0		lsr #8
+#define pull_hbyte1		lsl #24
+#else
+#define _BE_ONLY_(code...)
+#define _LE_ONLY_(code...) code
+#define push_hbyte0		lsl #24
+#define pull_hbyte1		lsr #8
+#endif
+
+.insw_noalign:	stmfd	sp!, {r4, lr}
+		ldrccb	ip, [r1, #-1]!
+		bcc	1f
+
+		ldrh	ip, [r0]
+		sub	r2, r2, #1
+   _BE_ONLY_(	mov	ip, ip, ror #8		)
+		strb	ip, [r1], #1
+   _LE_ONLY_(	mov	ip, ip, lsr #8		)
+   _BE_ONLY_(	mov	ip, ip, lsr #24		)
+
+1:		subs	r2, r2, #2
+		bmi	3f
+   _BE_ONLY_(	mov	ip, ip, lsl #24		)
+
+2:		ldrh	r3, [r0]
+		ldrh	r4, [r0]
+		subs	r2, r2, #2
+		orr	ip, ip, r3, lsl #8
+		orr	ip, ip, r4, push_hbyte0
+		str	ip, [r1], #4
+		mov	ip, r4, pull_hbyte1
+		bpl	2b
+
+   _BE_ONLY_(	mov	ip, ip, lsr #24		)
+
+3:		tst	r2, #1
+		strb	ip, [r1], #1
+		ldrneh	ip, [r0]
+   _BE_ONLY_(	movne	ip, ip, ror #8		)
+		strneb	ip, [r1], #1
+   _LE_ONLY_(	movne	ip, ip, lsr #8		)
+   _BE_ONLY_(	movne	ip, ip, lsr #24		)
+		strneb	ip, [r1]
+		ldmfd	sp!, {r4, pc}
diff -Nru a/arch/arm/lib/io-writesw-armv4.S b/arch/arm/lib/io-writesw-armv4.S
--- a/arch/arm/lib/io-writesw-armv4.S	2005-03-01 23:39:16 -08:00
+++ b/arch/arm/lib/io-writesw-armv4.S	2005-03-01 23:39:16 -08:00
@@ -22,27 +22,17 @@
 #endif
 		.endm
 
-.outsw_bad_alignment:
-		adr	r0, .outsw_bad_align_msg
-		mov	r2, lr
-		b	panic
-.outsw_bad_align_msg:
-		.asciz	"outsw: bad buffer alignment (0x%p, lr=0x%08lX)\n"
-		.align
-
-.outsw_align:	tst	r1, #1
-		bne	.outsw_bad_alignment
+.outsw_align:	movs	ip, r1, lsl #31
+		bne	.outsw_noalign
 
 		ldrh	r3, [r1], #2
+		sub	r2, r2, #1
 		strh	r3, [r0]
 
-		subs	r2, r2, #1
-		RETINSTR(moveq, pc, lr)
-
 ENTRY(__raw_writesw)
-		teq	r2, #0		@ do we have to check for the zero len?
+		teq	r2, #0
 		moveq	pc, lr
-		tst	r1, #3
+		ands	r3, r1, #3
 		bne	.outsw_align
 
 		stmfd	sp!, {r4, r5, lr}
@@ -51,16 +41,13 @@
 		bmi	.no_outsw_8
 
 .outsw_8_lp:	ldmia	r1!, {r3, r4, r5, ip}
+		subs	r2, r2, #8
 		outword	r3
 		outword	r4
 		outword	r5
 		outword	ip
-		subs	r2, r2, #8
 		bpl	.outsw_8_lp
 
-		tst	r2, #7
-		LOADREGS(eqfd, sp!, {r4, r5, pc})
-
 .no_outsw_8:	tst	r2, #4
 		beq	.no_outsw_4
 
@@ -68,14 +55,41 @@
 		outword	r3
 		outword	ip
 
-.no_outsw_4:	tst	r2, #2
-		beq	.no_outsw_2
+.no_outsw_4:	movs	r2, r2, lsl #31
+		bcc	.no_outsw_2
 
 		ldr	r3, [r1], #4
 		outword	r3
 
-.no_outsw_2:	tst	r2, #1
-		ldrneh	r3, [r1]
+.no_outsw_2:	ldrneh	r3, [r1]
 		strneh	r3, [r0]
 
-		LOADREGS(fd, sp!, {r4, r5, pc})
+		ldmfd	sp!, {r4, r5, pc}
+
+#ifdef __ARMEB__
+#define pull_hbyte0	lsl #8
+#define push_hbyte1	lsr #24
+#else
+#define pull_hbyte0	lsr #24
+#define push_hbyte1	lsl #8
+#endif
+
+.outsw_noalign:	ldr	r3, [r1, -r3]!
+		subcs	r2, r2, #1
+		bcs	2f
+		subs	r2, r2, #2
+		bmi	3f
+
+1:		mov	ip, r3, lsr #8
+		strh	ip, [r0]
+2:		mov	ip, r3, pull_hbyte0
+		ldr	r3, [r1, #4]!
+		subs	r2, r2, #2
+		orr	ip, ip, r3, push_hbyte1
+		strh	ip, [r0]
+		bpl	2b
+
+3:		tst	r2, #1
+2:		movne	ip, r3, lsr #8
+		strneh	ip, [r0]
+		mov	pc, lr
diff -Nru a/arch/arm/mach-footbridge/Kconfig b/arch/arm/mach-footbridge/Kconfig
--- a/arch/arm/mach-footbridge/Kconfig	2005-03-01 23:39:16 -08:00
+++ b/arch/arm/mach-footbridge/Kconfig	2005-03-01 23:39:16 -08:00
@@ -26,7 +26,7 @@
 	  <http://www.crl.hpl.hp.com/projects/personalserver/>
 
 	  If you have any questions or comments about the  Compaq Personal
-	  Server, send e-mail to skiff@crl.dec.com.
+	  Server, send e-mail to <skiff@crl.dec.com>.
 
 config ARCH_EBSA285_ADDIN
 	bool "EBSA285 (addin mode)"
diff -Nru a/arch/arm/mach-footbridge/ebsa285-leds.c b/arch/arm/mach-footbridge/ebsa285-leds.c
--- a/arch/arm/mach-footbridge/ebsa285-leds.c	2005-03-01 23:38:53 -08:00
+++ b/arch/arm/mach-footbridge/ebsa285-leds.c	2005-03-01 23:38:53 -08:00
@@ -32,7 +32,7 @@
 static char led_state;
 static char hw_led_state;
 
-static spinlock_t leds_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(leds_lock);
 
 static void ebsa285_leds_event(led_event_t evt)
 {
diff -Nru a/arch/arm/mach-footbridge/netwinder-hw.c b/arch/arm/mach-footbridge/netwinder-hw.c
--- a/arch/arm/mach-footbridge/netwinder-hw.c	2005-03-01 23:38:52 -08:00
+++ b/arch/arm/mach-footbridge/netwinder-hw.c	2005-03-01 23:38:52 -08:00
@@ -68,7 +68,7 @@
 /*
  * This is a lock for accessing ports GP1_IO_BASE and GP2_IO_BASE
  */
-spinlock_t gpio_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(gpio_lock);
 
 static unsigned int current_gpio_op;
 static unsigned int current_gpio_io;
diff -Nru a/arch/arm/mach-footbridge/netwinder-leds.c b/arch/arm/mach-footbridge/netwinder-leds.c
--- a/arch/arm/mach-footbridge/netwinder-leds.c	2005-03-01 23:39:09 -08:00
+++ b/arch/arm/mach-footbridge/netwinder-leds.c	2005-03-01 23:39:09 -08:00
@@ -32,7 +32,7 @@
 static char led_state;
 static char hw_led_state;
 
-static spinlock_t leds_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(leds_lock);
 extern spinlock_t gpio_lock;
 
 static void netwinder_leds_event(led_event_t evt)
diff -Nru a/arch/arm/mach-h720x/Kconfig b/arch/arm/mach-h720x/Kconfig
--- a/arch/arm/mach-h720x/Kconfig	2005-03-01 23:38:43 -08:00
+++ b/arch/arm/mach-h720x/Kconfig	2005-03-01 23:38:43 -08:00
@@ -27,5 +27,12 @@
 	bool
 	help
 	  Select code specific to h7202 variants
+config H7202_SERIAL23
+	depends on CPU_H7202
+	bool "Use serial ports 2+3"
+	help
+	  Say Y here if you wish to use serial ports 2+3. They share their
+	  pins with the keyboard matrix controller, so you have to decide.
+
 
 endif
diff -Nru a/arch/arm/mach-h720x/cpu-h7202.c b/arch/arm/mach-h720x/cpu-h7202.c
--- a/arch/arm/mach-h720x/cpu-h7202.c	2005-03-01 23:38:58 -08:00
+++ b/arch/arm/mach-h720x/cpu-h7202.c	2005-03-01 23:38:58 -08:00
@@ -5,7 +5,7 @@
  *               2003 Robert Schwebel <r.schwebel@pengutronix.de>
  *               2004 Sascha Hauer    <s.hauer@pengutronix.de>
  *
- * processor specific stuff for the Hynix h7201
+ * processor specific stuff for the Hynix h7202
  *
  * 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,7 +48,8 @@
 
 static struct plat_serial8250_port serial_platform_data[] = {
 	{
-		.membase	= SERIAL0_BASE,
+		.membase	= (void*)SERIAL0_VIRT,
+		.mapbase	= SERIAL0_BASE,
 		.irq		= IRQ_UART0,
 		.uartclk	= 2*1843200,
 		.regshift	= 2,
@@ -56,15 +57,18 @@
 		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
 	},
 	{
-		.membase	= SERIAL1_BASE,
+		.membase	= (void*)SERIAL1_VIRT,
+		.mapbase	= SERIAL1_BASE,
 		.irq		= IRQ_UART1,
 		.uartclk	= 2*1843200,
 		.regshift	= 2,
 		.iotype		= UPIO_MEM,
 		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
 	},
+#ifdef CONFIG_H7202_SERIAL23
 	{
-		.membase	= SERIAL2_BASE,
+		.membase	= (void*)SERIAL2_VIRT,
+		.mapbase	= SERIAL2_BASE,
 		.irq		= IRQ_UART2,
 		.uartclk	= 2*1843200,
 		.regshift	= 2,
@@ -72,13 +76,15 @@
 		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
 	},
 	{
-		.membase	= SERIAL3_BASE,
+		.membase	= (void*)SERIAL3_VIRT,
+		.mapbase	= SERIAL3_BASE,
 		.irq		= IRQ_UART3,
 		.uartclk	= 2*1843200,
 		.regshift	= 2,
 		.iotype		= UPIO_MEM,
 		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
 	},
+#endif
 	{ },
 };
 
@@ -210,5 +216,13 @@
 	/* Enable clocks */
 	CPU_REG (PMU_BASE, PMU_PLL_CTRL) |= PLL_2_EN | PLL_1_EN | PLL_3_MUTE;
 
+	CPU_REG (SERIAL0_VIRT, SERIAL_ENABLE) = SERIAL_ENABLE_EN;
+	CPU_REG (SERIAL1_VIRT, SERIAL_ENABLE) = SERIAL_ENABLE_EN;
+#ifdef CONFIG_H7202_SERIAL23
+	CPU_REG (SERIAL2_VIRT, SERIAL_ENABLE) = SERIAL_ENABLE_EN;
+	CPU_REG (SERIAL3_VIRT, SERIAL_ENABLE) = SERIAL_ENABLE_EN;
+	CPU_IO (GPIO_AMULSEL) = AMULSEL_USIN2 | AMULSEL_USOUT2 |
+	                        AMULSEL_USIN3 | AMULSEL_USOUT3;
+#endif
 	(void) platform_add_devices(devices, ARRAY_SIZE(devices));
 }
diff -Nru a/arch/arm/mach-imx/dma.c b/arch/arm/mach-imx/dma.c
--- a/arch/arm/mach-imx/dma.c	2005-03-01 23:39:18 -08:00
+++ b/arch/arm/mach-imx/dma.c	2005-03-01 23:39:18 -08:00
@@ -136,7 +136,7 @@
 			       i, channel->name);
 			DBOSR |= (1 << i);
 		}
-		DISR |= (1 << i);
+		DISR = (1 << i);
 	}
 	return IRQ_HANDLED;
 }
@@ -158,10 +158,10 @@
 				 */
 				printk(KERN_WARNING
 				       "spurious IRQ for DMA channel %d\n", i);
-				DISR |= (1 << i);
 			}
 		}
 	}
+	DISR = disr;
 	return IRQ_HANDLED;
 }
 
diff -Nru a/arch/arm/mach-imx/generic.c b/arch/arm/mach-imx/generic.c
--- a/arch/arm/mach-imx/generic.c	2005-03-01 23:39:18 -08:00
+++ b/arch/arm/mach-imx/generic.c	2005-03-01 23:39:18 -08:00
@@ -100,8 +100,8 @@
 static unsigned int imx_decode_pll(unsigned int pll)
 {
 	u32 mfi = (pll >> 10) & 0xf;
-	u32 mfn = pll & 0x3f;
-	u32 mfd = (pll >> 16) & 0x3f;
+	u32 mfn = pll & 0x3ff;
+	u32 mfd = (pll >> 16) & 0x3ff;
 	u32 pd =  (pll >> 26) & 0xf;
 	u32 f_ref = (CSCR & CSCR_SYSTEM_SEL) ? 16000000 : (CLK32 * 512);
 
diff -Nru a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c
--- a/arch/arm/mach-integrator/core.c	2005-03-01 23:39:08 -08:00
+++ b/arch/arm/mach-integrator/core.c	2005-03-01 23:39:08 -08:00
@@ -115,7 +115,7 @@
 
 #define CM_CTRL	IO_ADDRESS(INTEGRATOR_HDR_BASE) + INTEGRATOR_HDR_CTRL_OFFSET
 
-static spinlock_t cm_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(cm_lock);
 
 /**
  * cm_control - update the CM_CTRL register.
diff -Nru a/arch/arm/mach-integrator/impd1.c b/arch/arm/mach-integrator/impd1.c
--- a/arch/arm/mach-integrator/impd1.c	2005-03-01 23:38:55 -08:00
+++ b/arch/arm/mach-integrator/impd1.c	2005-03-01 23:38:55 -08:00
@@ -17,6 +17,7 @@
 #include <linux/init.h>
 #include <linux/device.h>
 #include <linux/errno.h>
+#include <linux/mm.h>
 
 #include <asm/io.h>
 #include <asm/hardware/icst525.h>
@@ -34,7 +35,7 @@
 MODULE_PARM_DESC(lmid, "logic module stack position");
 
 struct impd1_module {
-	void		*base;
+	void __iomem	*base;
 	struct clk	vcos[2];
 };
 
@@ -259,6 +260,17 @@
 	return ret;
 }
 
+static int impd1fb_clcd_mmap(struct clcd_fb *fb, struct vm_area_struct *vma)
+{
+	unsigned long start, size;
+
+	start = vma->vm_pgoff + (fb->fb.fix.smem_start >> PAGE_SHIFT);
+	size = vma->vm_end - vma->vm_start;
+
+	return remap_pfn_range(vma, vma->vm_start, start, size,
+			       vma->vm_page_prot);
+}
+
 static void impd1fb_clcd_remove(struct clcd_fb *fb)
 {
 	iounmap(fb->fb.screen_base);
@@ -272,6 +284,7 @@
 	.disable	= impd1fb_clcd_disable,
 	.enable		= impd1fb_clcd_enable,
 	.setup		= impd1fb_clcd_setup,
+	.mmap		= impd1fb_clcd_mmap,
 	.remove		= impd1fb_clcd_remove,
 };
 
diff -Nru a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c
--- a/arch/arm/mach-integrator/integrator_ap.c	2005-03-01 23:39:09 -08:00
+++ b/arch/arm/mach-integrator/integrator_ap.c	2005-03-01 23:39:09 -08:00
@@ -68,7 +68,6 @@
  * f1200000	12000000	EBI registers
  * f1300000	13000000	Counter/Timer
  * f1400000	14000000	Interrupt controller
- * f1500000	15000000	RTC
  * f1600000	16000000	UART 0
  * f1700000	17000000	UART 1
  * f1a00000	1a000000	Debug LEDs
@@ -81,7 +80,6 @@
  { IO_ADDRESS(INTEGRATOR_EBI_BASE),   INTEGRATOR_EBI_BASE,   SZ_4K,  MT_DEVICE },
  { IO_ADDRESS(INTEGRATOR_CT_BASE),    INTEGRATOR_CT_BASE,    SZ_4K,  MT_DEVICE },
  { IO_ADDRESS(INTEGRATOR_IC_BASE),    INTEGRATOR_IC_BASE,    SZ_4K,  MT_DEVICE },
- { IO_ADDRESS(INTEGRATOR_RTC_BASE),   INTEGRATOR_RTC_BASE,   SZ_4K,  MT_DEVICE },
  { IO_ADDRESS(INTEGRATOR_UART0_BASE), INTEGRATOR_UART0_BASE, SZ_4K,  MT_DEVICE },
  { IO_ADDRESS(INTEGRATOR_UART1_BASE), INTEGRATOR_UART1_BASE, SZ_4K,  MT_DEVICE },
  { IO_ADDRESS(INTEGRATOR_DBG_BASE),   INTEGRATOR_DBG_BASE,   SZ_4K,  MT_DEVICE },
diff -Nru a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
--- a/arch/arm/mach-integrator/integrator_cp.c	2005-03-01 23:39:16 -08:00
+++ b/arch/arm/mach-integrator/integrator_cp.c	2005-03-01 23:39:16 -08:00
@@ -444,6 +444,14 @@
 	return 0;
 }
 
+static int cp_clcd_mmap(struct clcd_fb *fb, struct vm_area_struct *vma)
+{
+	return dma_mmap_writecombine(&fb->dev->dev, vma,
+				     fb->fb.screen_base,
+				     fb->fb.fix.smem_start,
+				     fb->fb.fix.smem_len);
+}
+
 static void cp_clcd_remove(struct clcd_fb *fb)
 {
 	dma_free_writecombine(&fb->dev->dev, fb->fb.fix.smem_len,
@@ -456,6 +464,7 @@
 	.decode		= clcdfb_decode,
 	.enable		= cp_clcd_enable,
 	.setup		= cp_clcd_setup,
+	.mmap		= cp_clcd_mmap,
 	.remove		= cp_clcd_remove,
 };
 
diff -Nru a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c
--- a/arch/arm/mach-integrator/pci_v3.c	2005-03-01 23:39:08 -08:00
+++ b/arch/arm/mach-integrator/pci_v3.c	2005-03-01 23:39:08 -08:00
@@ -163,7 +163,7 @@
  *	 7:2	register number
  *  
  */
-static spinlock_t v3_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(v3_lock);
 
 #define PCI_BUS_NONMEM_START	0x00000000
 #define PCI_BUS_NONMEM_SIZE	SZ_256M
diff -Nru a/arch/arm/mach-integrator/time.c b/arch/arm/mach-integrator/time.c
--- a/arch/arm/mach-integrator/time.c	2005-03-01 23:38:56 -08:00
+++ b/arch/arm/mach-integrator/time.c	2005-03-01 23:38:56 -08:00
@@ -1,46 +1,213 @@
 /*
  *  linux/arch/arm/mach-integrator/time.c
  *
- *  Copyright (C) 2000-2001 Deep Blue Solutions
+ *  Copyright (C) 2000-2001 Deep Blue Solutions Ltd.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/time.h>
+#include <linux/mc146818rtc.h>
+#include <linux/interrupt.h>
 #include <linux/init.h>
+#include <linux/device.h>
 
+#include <asm/hardware/amba.h>
 #include <asm/hardware.h>
 #include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/rtc.h>
 
-#define RTC_DR		(IO_ADDRESS(INTEGRATOR_RTC_BASE) + 0)
-#define RTC_MR		(IO_ADDRESS(INTEGRATOR_RTC_BASE) + 4)
-#define RTC_STAT	(IO_ADDRESS(INTEGRATOR_RTC_BASE) + 8)
-#define RTC_EOI		(IO_ADDRESS(INTEGRATOR_RTC_BASE) + 8)
-#define RTC_LR		(IO_ADDRESS(INTEGRATOR_RTC_BASE) + 12)
-#define RTC_CR		(IO_ADDRESS(INTEGRATOR_RTC_BASE) + 16)
+#include <asm/mach/time.h>
 
-#define RTC_CR_MIE	0x00000001
+#define RTC_DR		(0)
+#define RTC_MR		(4)
+#define RTC_STAT	(8)
+#define RTC_EOI		(8)
+#define RTC_LR		(12)
+#define RTC_CR		(16)
+#define RTC_CR_MIE	(1 << 0)
 
 extern int (*set_rtc)(void);
+static void __iomem *rtc_base;
 
 static int integrator_set_rtc(void)
 {
-	__raw_writel(xtime.tv_sec, RTC_LR);
+	__raw_writel(xtime.tv_sec, rtc_base + RTC_LR);
 	return 1;
 }
 
-static int integrator_rtc_init(void)
+static void rtc_read_alarm(struct rtc_wkalrm *alrm)
 {
-	__raw_writel(0, RTC_CR);
-	__raw_writel(0, RTC_EOI);
+	rtc_time_to_tm(readl(rtc_base + RTC_MR), &alrm->time);
+}
+
+static int rtc_set_alarm(struct rtc_wkalrm *alrm)
+{
+	unsigned long time;
+	int ret;
 
-	xtime.tv_sec = __raw_readl(RTC_DR);
+	ret = rtc_tm_to_time(&alrm->time, &time);
+	if (ret == 0)
+		writel(time, rtc_base + RTC_MR);
+	return ret;
+}
+
+static void rtc_read_time(struct rtc_time *tm)
+{
+	rtc_time_to_tm(readl(rtc_base + RTC_DR), tm);
+}
+
+/*
+ * Set the RTC time.  Unfortunately, we can't accurately set
+ * the point at which the counter updates.
+ *
+ * Also, since RTC_LR is transferred to RTC_CR on next rising
+ * edge of the 1Hz clock, we must write the time one second
+ * in advance.
+ */
+static int rtc_set_time(struct rtc_time *tm)
+{
+	unsigned long time;
+	int ret;
+
+	ret = rtc_tm_to_time(tm, &time);
+	if (ret == 0)
+		writel(time + 1, rtc_base + RTC_LR);
+
+	return ret;
+}
+
+static struct rtc_ops rtc_ops = {
+	.owner		= THIS_MODULE,
+	.read_time	= rtc_read_time,
+	.set_time	= rtc_set_time,
+	.read_alarm	= rtc_read_alarm,
+	.set_alarm	= rtc_set_alarm,
+};
+
+static irqreturn_t rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	writel(0, rtc_base + RTC_EOI);
+	return IRQ_HANDLED;
+}
+
+static int rtc_probe(struct amba_device *dev, void *id)
+{
+	int ret;
+
+	if (rtc_base)
+		return -EBUSY;
+
+	ret = amba_request_regions(dev, NULL);
+	if (ret)
+		goto out;
+
+	rtc_base = ioremap(dev->res.start, SZ_4K);
+	if (!rtc_base) {
+		ret = -ENOMEM;
+		goto res_out;
+	}
+
+	__raw_writel(0, rtc_base + RTC_CR);
+	__raw_writel(0, rtc_base + RTC_EOI);
+
+	xtime.tv_sec = __raw_readl(rtc_base + RTC_DR);
+
+	ret = request_irq(dev->irq[0], rtc_interrupt, SA_INTERRUPT,
+			  "rtc-pl030", dev);
+	if (ret)
+		goto map_out;
+
+	ret = register_rtc(&rtc_ops);
+	if (ret)
+		goto irq_out;
 
 	set_rtc = integrator_set_rtc;
+	return 0;
+
+ irq_out:
+	free_irq(dev->irq[0], dev);
+ map_out:
+	iounmap(rtc_base);
+	rtc_base = NULL;
+ res_out:
+	amba_release_regions(dev);
+ out:
+	return ret;
+}
+
+static int rtc_remove(struct amba_device *dev)
+{
+	set_rtc = NULL;
+
+	writel(0, rtc_base + RTC_CR);
+
+	free_irq(dev->irq[0], dev);
+	unregister_rtc(&rtc_ops);
+
+	iounmap(rtc_base);
+	rtc_base = NULL;
+	amba_release_regions(dev);
 
 	return 0;
 }
 
-__initcall(integrator_rtc_init);
+static struct timespec rtc_delta;
+
+static int rtc_suspend(struct amba_device *dev, u32 state)
+{
+	struct timespec rtc;
+
+	rtc.tv_sec = readl(rtc_base + RTC_DR);
+	rtc.tv_nsec = 0;
+	save_time_delta(&rtc_delta, &rtc);
+
+	return 0;
+}
+
+static int rtc_resume(struct amba_device *dev)
+{
+	struct timespec rtc;
+
+	rtc.tv_sec = readl(rtc_base + RTC_DR);
+	rtc.tv_nsec = 0;
+	restore_time_delta(&rtc_delta, &rtc);
+
+	return 0;
+}
+
+static struct amba_id rtc_ids[] = {
+	{
+		.id	= 0x00041030,
+		.mask	= 0x000fffff,
+	},
+	{ 0, 0 },
+};
+
+static struct amba_driver rtc_driver = {
+	.drv		= {
+		.name	= "rtc-pl030",
+	},
+	.probe		= rtc_probe,
+	.remove		= rtc_remove,
+	.suspend	= rtc_suspend,
+	.resume		= rtc_resume,
+	.id_table	= rtc_ids,
+};
+
+static int __init integrator_rtc_init(void)
+{
+	return amba_driver_register(&rtc_driver);
+}
+
+static void __exit integrator_rtc_exit(void)
+{
+	amba_driver_unregister(&rtc_driver);
+}
+
+module_init(integrator_rtc_init);
+module_exit(integrator_rtc_exit);
diff -Nru a/arch/arm/mach-iop3xx/Kconfig b/arch/arm/mach-iop3xx/Kconfig
--- a/arch/arm/mach-iop3xx/Kconfig	2005-03-01 23:39:17 -08:00
+++ b/arch/arm/mach-iop3xx/Kconfig	2005-03-01 23:39:17 -08:00
@@ -25,6 +25,13 @@
 	  Say Y here if you want to run your kernel on the Intel IQ80331
 	  evaluation kit for the IOP331 chipset.
 
+config MACH_IQ80332
+	bool "Enable support for IQ80332"
+	select ARCH_IOP331
+	help
+	  Say Y here if you want to run your kernel on the Intel IQ80332
+	  evaluation kit for the IOP332 chipset
+
 config ARCH_EP80219
     bool "Enable support for EP80219"
     select ARCH_IOP321
@@ -41,10 +48,16 @@
 	bool
 	default ARCH_IQ80331
 	help
-	  The IQ80331 uses the IOP331 variant.
+	  The IQ80331, IQ80332, and IQ80333 uses the IOP331 variant.
 
 comment "IOP3xx Chipset Features"
 
-endmenu
+config IOP331_STEPD
+	bool "Chip stepping D of the IOP80331 processor or IOP80333"
+	depends on (ARCH_IOP331)
+	help
+		  Say Y here if you have StepD of the IOP80331 or IOP8033
+		  based platforms.
 
+endmenu
 endif
diff -Nru a/arch/arm/mach-iop3xx/Makefile b/arch/arm/mach-iop3xx/Makefile
--- a/arch/arm/mach-iop3xx/Makefile	2005-03-01 23:39:16 -08:00
+++ b/arch/arm/mach-iop3xx/Makefile	2005-03-01 23:39:16 -08:00
@@ -19,3 +19,5 @@
 obj-$(CONFIG_ARCH_IQ31244) += iq31244-mm.o iq31244-pci.o
 
 obj-$(CONFIG_ARCH_IQ80331) += iq80331-mm.o iq80331-pci.o
+
+obj-$(CONFIG_MACH_IQ80332) += iq80332-mm.o iq80332-pci.o
diff -Nru a/arch/arm/mach-iop3xx/iop321-pci.c b/arch/arm/mach-iop3xx/iop321-pci.c
--- a/arch/arm/mach-iop3xx/iop321-pci.c	2005-03-01 23:39:09 -08:00
+++ b/arch/arm/mach-iop3xx/iop321-pci.c	2005-03-01 23:39:09 -08:00
@@ -197,31 +197,24 @@
 
 void iop321_init(void)
 {
-#if CONFIG_ARCH_EP80219
-    *IOP321_ATUCR = 0x2;
-    *IOP321_OIOWTVR = 0x90000000;
-    *IOP321_IABAR0  = 0x00000004;
-    *IOP321_IABAR2  = 0xa000000c;
-    *IOP321_IALR2   = 0xe0000000;
-#endif
-
 	DBG("PCI:  Intel 80321 PCI init code.\n");
-	DBG("\tATU: IOP321_ATUCMD=0x%04x\n", *IOP321_ATUCMD);
-	DBG("\tATU: IOP321_OMWTVR0=0x%04x, IOP321_OIOWTVR=0x%04x\n",
+	DBG("ATU: IOP321_ATUCMD=0x%04x\n", *IOP321_ATUCMD);
+	DBG("ATU: IOP321_OMWTVR0=0x%04x, IOP321_OIOWTVR=0x%04x\n",
 			*IOP321_OMWTVR0,
 			*IOP321_OIOWTVR);
-	DBG("\tATU: IOP321_ATUCR=0x%08x\n", *IOP321_ATUCR);
-	DBG("\tATU: IOP321_IABAR0=0x%08x IOP321_IALR0=0x%08x IOP321_IATVR0=%08x\n", *IOP321_IABAR0, *IOP321_IALR0, *IOP321_IATVR0);
-	DBG("\tATU: IOP321_ERBAR=0x%08x IOP321_ERLR=0x%08x IOP321_ERTVR=%08x\n", *IOP321_ERBAR, *IOP321_ERLR, *IOP321_ERTVR);
-	DBG("\tATU: IOP321_IABAR2=0x%08x IOP321_IALR2=0x%08x IOP321_IATVR2=%08x\n", *IOP321_IABAR2, *IOP321_IALR2, *IOP321_IATVR2);
-	DBG("\tATU: IOP321_IABAR3=0x%08x IOP321_IALR3=0x%08x IOP321_IATVR3=%08x\n", *IOP321_IABAR3, *IOP321_IALR3, *IOP321_IATVR3);
+	DBG("ATU: IOP321_ATUCR=0x%08x\n", *IOP321_ATUCR);
+	DBG("ATU: IOP321_IABAR0=0x%08x IOP321_IALR0=0x%08x IOP321_IATVR0=%08x\n",
+			*IOP321_IABAR0, *IOP321_IALR0, *IOP321_IATVR0);
+	DBG("ATU: IOP321_OMWTVR0=0x%08x\n", *IOP321_OMWTVR0);
+	DBG("ATU: IOP321_IABAR1=0x%08x IOP321_IALR1=0x%08x\n",
+			*IOP321_IABAR1, *IOP321_IALR1);
+	DBG("ATU: IOP321_ERBAR=0x%08x IOP321_ERLR=0x%08x IOP321_ERTVR=%08x\n",
+			*IOP321_ERBAR, *IOP321_ERLR, *IOP321_ERTVR);
+	DBG("ATU: IOP321_IABAR2=0x%08x IOP321_IALR2=0x%08x IOP321_IATVR2=%08x\n",
+			*IOP321_IABAR2, *IOP321_IALR2, *IOP321_IATVR2);
+	DBG("ATU: IOP321_IABAR3=0x%08x IOP321_IALR3=0x%08x IOP321_IATVR3=%08x\n",
+			*IOP321_IABAR3, *IOP321_IALR3, *IOP321_IATVR3);
 
-#if 0
-	hook_fault_code(4, iop321_pci_abort, SIGBUS, "external abort on linefetch");
-	hook_fault_code(6, iop321_pci_abort, SIGBUS, "external abort on linefetch");
-	hook_fault_code(8, iop321_pci_abort, SIGBUS, "external abort on non-linefetch");
-	hook_fault_code(10, iop321_pci_abort, SIGBUS, "external abort on non-linefetch");
-#endif
 	hook_fault_code(16+6, iop321_pci_abort, SIGBUS, "imprecise external abort");
 }
 
diff -Nru a/arch/arm/mach-iop3xx/iop321-setup.c b/arch/arm/mach-iop3xx/iop321-setup.c
--- a/arch/arm/mach-iop3xx/iop321-setup.c	2005-03-01 23:38:57 -08:00
+++ b/arch/arm/mach-iop3xx/iop321-setup.c	2005-03-01 23:38:57 -08:00
@@ -3,6 +3,7 @@
  *
  * Author: Nicolas Pitre <nico@cam.org>
  * Copyright (C) 2001 MontaVista Software, Inc.
+ * 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
@@ -40,10 +41,10 @@
  /* virtual     physical      length      type */
 
  /* mem mapped registers */
- { IOP321_VIRT_MEM_BASE,  IOP321_PHY_MEM_BASE,   0x00002000,  MT_DEVICE },
+ { IOP321_VIRT_MEM_BASE,  IOP321_PHYS_MEM_BASE,   0x00002000,  MT_DEVICE },
 
  /* PCI IO space */
- { 0xfe000000,  0x90000000,   0x00020000,  MT_DEVICE }
+ { IOP321_PCI_LOWER_IO_VA,  IOP321_PCI_LOWER_IO_PA,   IOP321_PCI_IO_WINDOW_SIZE,  MT_DEVICE }
 };
 
 #ifdef CONFIG_ARCH_IQ80321
@@ -71,6 +72,60 @@
 	}
 };
 
+static struct resource iop32x_i2c_0_resources[] = {
+	[0] = {
+		.start = 0xfffff680,
+		.end = 0xfffff698,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_IOP321_I2C_0,
+		.end = IRQ_IOP321_I2C_0,
+		.flags = IORESOURCE_IRQ
+	}
+};
+
+static struct resource iop32x_i2c_1_resources[] = {
+	[0] = {
+		.start = 0xfffff6a0,
+		.end = 0xfffff6b8,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_IOP321_I2C_1,
+		.end = IRQ_IOP321_I2C_1,
+		.flags = IORESOURCE_IRQ
+	}
+};
+
+static struct platform_device iop32x_i2c_0_controller = {
+	.name = "IOP3xx-I2C",
+	.id = 0,
+	.num_resources = 2,
+	.resource = iop32x_i2c_0_resources
+};
+
+static struct platform_device iop32x_i2c_1_controller = {
+	.name = "IOP3xx-I2C",
+	.id = 1,
+	.num_resources = 2,
+	.resource = iop32x_i2c_1_resources
+};
+
+static struct platform_device *iop32x_devices[] __initdata = {
+	&iop32x_i2c_0_controller,
+	&iop32x_i2c_1_controller
+};
+
+void __init iop32x_init(void)
+{
+	if(iop_is_321())
+	{
+		platform_add_devices(iop32x_devices,
+				ARRAY_SIZE(iop32x_devices));
+	}
+}
+
 void __init iop321_map_io(void)
 {
 	iotable_init(iop321_std_desc, ARRAY_SIZE(iop321_std_desc));
@@ -97,6 +152,7 @@
 	INITIRQ(iop321_init_irq)
 	.timer		= &iop321_timer,
     BOOT_PARAMS(0xa0000100)
+	INIT_MACHINE(iop32x_init)
 MACHINE_END
 #elif defined(CONFIG_ARCH_IQ31244)
 MACHINE_START(IQ31244, "Intel IQ31244")
@@ -106,6 +162,7 @@
     INITIRQ(iop321_init_irq)
 	.timer		= &iop321_timer,
     BOOT_PARAMS(0xa0000100)
+	INIT_MACHINE(iop32x_init)
 MACHINE_END
 #else
 #error No machine descriptor defined for this IOP3XX implementation
diff -Nru a/arch/arm/mach-iop3xx/iop331-pci.c b/arch/arm/mach-iop3xx/iop331-pci.c
--- a/arch/arm/mach-iop3xx/iop331-pci.c	2005-03-01 23:39:08 -08:00
+++ b/arch/arm/mach-iop3xx/iop331-pci.c	2005-03-01 23:39:08 -08:00
@@ -4,7 +4,7 @@
  * PCI support for the Intel IOP331 chipset
  *
  * Author: Dave Jiang (dave.jiang@intel.com)
- * Copyright (C) 2003 Intel Corp.
+ * Copyright (C) 2003, 2004 Intel Corp.
  *
  * 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
@@ -26,7 +26,8 @@
 
 #include <asm/arch/iop331.h>
 
-//#define DEBUG
+#undef DEBUG
+#undef DEBUG1
 
 #ifdef DEBUG
 #define  DBG(x...) printk(x)
@@ -34,6 +35,12 @@
 #define  DBG(x...) do { } while (0)
 #endif
 
+#ifdef DEBUG1
+#define  DBG1(x...) printk(x)
+#else
+#define  DBG1(x...) do { } while (0)
+#endif
+
 /*
  * This routine builds either a type0 or type1 configuration command.  If the
  * bus is on the 80331 then a type0 made, else a type1 is created.
@@ -197,21 +204,19 @@
 
 void iop331_init(void)
 {
-	DBG("PCI:  Intel 80331 PCI init code.\n");
-	DBG("\tATU: IOP331_ATUCMD=0x%04x\n", *IOP331_ATUCMD);
-	DBG("\tATU: IOP331_OMWTVR0=0x%04x, IOP331_OIOWTVR=0x%04x\n",
+	DBG1("PCI:  Intel 80331 PCI init code.\n");
+	DBG1("\tATU: IOP331_ATUCMD=0x%04x\n", *IOP331_ATUCMD);
+	DBG1("\tATU: IOP331_OMWTVR0=0x%04x, IOP331_OIOWTVR=0x%04x\n",
 			*IOP331_OMWTVR0,
 			*IOP331_OIOWTVR);
-	DBG("\tATU: IOP331_ATUCR=0x%08x\n", *IOP331_ATUCR);
-	DBG("\tATU: IOP331_IABAR0=0x%08x IOP331_IALR0=0x%08x IOP331_IATVR0=%08x\n", *IOP331_IABAR0, *IOP331_IALR0, *IOP331_IATVR0);
-	DBG("\tATU: IOP331_ERBAR=0x%08x IOP331_ERLR=0x%08x IOP331_ERTVR=%08x\n", *IOP331_ERBAR, *IOP331_ERLR, *IOP331_ERTVR);
-	DBG("\tATU: IOP331_IABAR2=0x%08x IOP331_IALR2=0x%08x IOP331_IATVR2=%08x\n", *IOP331_IABAR2, *IOP331_IALR2, *IOP331_IATVR2);
-	DBG("\tATU: IOP331_IABAR3=0x%08x IOP331_IALR3=0x%08x IOP331_IATVR3=%08x\n", *IOP331_IABAR3, *IOP331_IALR3, *IOP331_IATVR3);
-
-	/* redboot changed, reset IABAR0 to something sane */
-	/* fixes master aborts in plugged in cards */
-	/* will clean up later and work nicely with redboot */
-	*IOP331_IABAR0 = 0x00000004;
+	DBG1("\tATU: IOP331_OMWTVR1=0x%04x\n", *IOP331_OMWTVR1);
+	DBG1("\tATU: IOP331_ATUCR=0x%08x\n", *IOP331_ATUCR);
+	DBG1("\tATU: IOP331_IABAR0=0x%08x IOP331_IALR0=0x%08x IOP331_IATVR0=%08x\n", *IOP331_IABAR0, *IOP331_IALR0, *IOP331_IATVR0);
+	DBG1("\tATU: IOP31_IABAR1=0x%08x IOP331_IALR1=0x%08x\n", *IOP331_IABAR1, *IOP331_IALR1);
+	DBG1("\tATU: IOP331_ERBAR=0x%08x IOP331_ERLR=0x%08x IOP331_ERTVR=%08x\n", *IOP331_ERBAR, *IOP331_ERLR, *IOP331_ERTVR);
+	DBG1("\tATU: IOP331_IABAR2=0x%08x IOP331_IALR2=0x%08x IOP331_IATVR2=%08x\n", *IOP331_IABAR2, *IOP331_IALR2, *IOP331_IATVR2);
+	DBG1("\tATU: IOP331_IABAR3=0x%08x IOP331_IALR3=0x%08x IOP331_IATVR3=%08x\n", *IOP331_IABAR3, *IOP331_IALR3, *IOP331_IATVR3);
+
 	hook_fault_code(16+6, iop331_pci_abort, SIGBUS, "imprecise external abort");
 }
 
diff -Nru a/arch/arm/mach-iop3xx/iop331-setup.c b/arch/arm/mach-iop3xx/iop331-setup.c
--- a/arch/arm/mach-iop3xx/iop331-setup.c	2005-03-01 23:39:16 -08:00
+++ b/arch/arm/mach-iop3xx/iop331-setup.c	2005-03-01 23:39:16 -08:00
@@ -12,6 +12,7 @@
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/config.h>
+#include <linux/init.h>
 #include <linux/major.h>
 #include <linux/fs.h>
 #include <linux/device.h>
@@ -42,13 +43,13 @@
  { IOP331_VIRT_MEM_BASE,  IOP331_PHYS_MEM_BASE,   0x00002000,  MT_DEVICE },
 
  /* PCI IO space */
- { 0xfe000000,  0x90000000,   0x00020000,  MT_DEVICE }
+ { IOP331_PCI_LOWER_IO_VA,  IOP331_PCI_LOWER_IO_PA,   IOP331_PCI_IO_WINDOW_SIZE,  MT_DEVICE }
 };
 
 static struct uart_port iop331_serial_ports[] = {
 	{
-		.membase	= (char*)(IQ80331_UART0_VIRT),
-		.mapbase	= (IQ80331_UART0_PHYS),
+		.membase	= (char*)(IOP331_UART0_VIRT),
+		.mapbase	= (IOP331_UART0_PHYS),
 		.irq		= IRQ_IOP331_UART0,
 		.flags		= UPF_SKIP_TEST,
 		.iotype		= UPIO_MEM,
@@ -58,8 +59,8 @@
 		.type		= PORT_XSCALE,
 		.fifosize	= 32
 	} , {
-		.membase	= (char*)(IQ80331_UART1_VIRT),
-		.mapbase	= (IQ80331_UART1_PHYS),
+		.membase	= (char*)(IOP331_UART1_VIRT),
+		.mapbase	= (IOP331_UART1_PHYS),
 		.irq		= IRQ_IOP331_UART1,
 		.flags		= UPF_SKIP_TEST,
 		.iotype		= UPIO_MEM,
@@ -71,6 +72,60 @@
 	}
 };
 
+static struct resource iop33x_i2c_0_resources[] = {
+	[0] = {
+		.start = 0xfffff680,
+		.end = 0xfffff698,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_IOP331_I2C_0,
+		.end = IRQ_IOP331_I2C_0,
+		.flags = IORESOURCE_IRQ
+	}
+};
+
+static struct resource iop33x_i2c_1_resources[] = {
+	[0] = {
+		.start = 0xfffff6a0,
+		.end = 0xfffff6b8,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_IOP331_I2C_1,
+		.end = IRQ_IOP331_I2C_1,
+		.flags = IORESOURCE_IRQ
+	}
+};
+
+static struct platform_device iop33x_i2c_0_controller = {
+	.name = "IOP3xx-I2C",
+	.id = 0,
+	.num_resources = 2,
+	.resource = iop33x_i2c_0_resources
+};
+
+static struct platform_device iop33x_i2c_1_controller = {
+	.name = "IOP3xx-I2C",
+	.id = 1,
+	.num_resources = 2,
+	.resource = iop33x_i2c_1_resources
+};
+
+static struct platform_device *iop33x_devices[] __initdata = {
+	&iop33x_i2c_0_controller,
+	&iop33x_i2c_1_controller
+};
+
+void __init iop33x_init(void)
+{
+	if(iop_is_331())
+	{
+		platform_add_devices(iop33x_devices,
+				ARRAY_SIZE(iop33x_devices));
+	}
+}
+
 void __init iop331_map_io(void)
 {
 	iotable_init(iop331_std_desc, ARRAY_SIZE(iop331_std_desc));
@@ -78,22 +133,43 @@
 	early_serial_setup(&iop331_serial_ports[1]);
 }
 
-#ifdef CONFIG_ARCH_IQ80331
+#ifdef CONFIG_ARCH_IOP331
 extern void iop331_init_irq(void);
 extern struct sys_timer iop331_timer;
+#endif
+
+#ifdef CONFIG_ARCH_IQ80331
 extern void iq80331_map_io(void);
 #endif
 
+#ifdef CONFIG_MACH_IQ80332
+extern void iq80332_map_io(void);
+#endif
+
 #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, IQ80331_UART0_VIRT, IQ80331_UART0_PHYS)
+    //BOOT_MEM(PHYS_OFFSET, IOP331_UART0_VIRT, IOP331_UART0_PHYS)
     MAPIO(iq80331_map_io)
     INITIRQ(iop331_init_irq)
-    .timer		= &iop331_timer,
+	.timer		= &iop331_timer,
     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)
+	.timer		= &iop331_timer,
+    BOOT_PARAMS(0x0100)
+	INIT_MACHINE(iop33x_init)
+MACHINE_END
+
 #else
 #error No machine descriptor defined for this IOP3XX implementation
 #endif
diff -Nru a/arch/arm/mach-iop3xx/iq31244-pci.c b/arch/arm/mach-iop3xx/iq31244-pci.c
--- a/arch/arm/mach-iop3xx/iq31244-pci.c	2005-03-01 23:39:16 -08:00
+++ b/arch/arm/mach-iop3xx/iq31244-pci.c	2005-03-01 23:39:16 -08:00
@@ -5,6 +5,7 @@
  *
  * Author: Rory Bolt <rorybolt@pacbell.net>
  * Copyright (C) 2002 Rory Bolt
+ * Copyright (C) 2004 Intel Corp.
  *
  * 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,28 +78,25 @@
 
 	memset(res, 0, sizeof(struct resource) * 2);
 
-	res[0].start = IQ31244_PCI_IO_BASE + 0x6e000000;
-	res[0].end   = IQ31244_PCI_IO_BASE + IQ31244_PCI_IO_SIZE - 1 + IQ31244_PCI_IO_OFFSET;
+	res[0].start = IOP321_PCI_LOWER_IO_VA;
+	res[0].end   = IOP321_PCI_UPPER_IO_VA;
 	res[0].name  = "IQ31244 PCI I/O Space";
 	res[0].flags = IORESOURCE_IO;
 
-	res[1].start = IQ31244_PCI_MEM_BASE;
-	res[1].end   = IQ31244_PCI_MEM_BASE + IQ31244_PCI_MEM_SIZE;
+	res[1].start = IOP321_PCI_LOWER_MEM_PA;
+	res[1].end   = IOP321_PCI_UPPER_MEM_PA;
 	res[1].name  = "IQ31244 PCI Memory Space";
 	res[1].flags = IORESOURCE_MEM;
 
 	request_resource(&ioport_resource, &res[0]);
 	request_resource(&iomem_resource, &res[1]);
 
+	sys->mem_offset = IOP321_PCI_MEM_OFFSET;
+	sys->io_offset  = IOP321_PCI_IO_OFFSET;
+
 	sys->resource[0] = &res[0];
 	sys->resource[1] = &res[1];
 	sys->resource[2] = NULL;
-	sys->io_offset   = IQ31244_PCI_IO_OFFSET;
-	sys->mem_offset = IQ80321_PCI_MEM_BASE -
-		(*IOP321_IABAR1 & PCI_BASE_ADDRESS_MEM_MASK);
-
-	iop3xx_pcibios_min_io = IQ31244_PCI_IO_BASE;
-	iop3xx_pcibios_min_mem = IQ31244_PCI_MEM_BASE;
 
 	return 1;
 }
@@ -106,9 +104,6 @@
 static void iq31244_preinit(void)
 {
 	iop321_init();
-	/* setting up the second translation window */
-	*IOP321_OMWTVR1 = IQ31244_PCI_MEM_BASE + 0x04000000;
-	*IOP321_OUMWTVR1 = 0x0;
 }
 
 static struct hw_pci iq31244_pci __initdata = {
diff -Nru a/arch/arm/mach-iop3xx/iq80321-pci.c b/arch/arm/mach-iop3xx/iq80321-pci.c
--- a/arch/arm/mach-iop3xx/iq80321-pci.c	2005-03-01 23:39:16 -08:00
+++ b/arch/arm/mach-iop3xx/iq80321-pci.c	2005-03-01 23:39:16 -08:00
@@ -5,6 +5,7 @@
  *
  * Author: Rory Bolt <rorybolt@pacbell.net>
  * Copyright (C) 2002 Rory Bolt
+ * Copyright (C) 2004 Intel Corp.
  *
  * 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
@@ -71,44 +72,25 @@
 
 	memset(res, 0, sizeof(struct resource) * 2);
 
-	res[0].start = IQ80321_PCI_IO_BASE + IQ80321_PCI_IO_OFFSET;
-	res[0].end   = IQ80321_PCI_IO_BASE + IQ80321_PCI_IO_SIZE - 1 + IQ80321_PCI_IO_OFFSET;
+	res[0].start = IOP321_PCI_LOWER_IO_VA;
+	res[0].end   = IOP321_PCI_UPPER_IO_VA;
 	res[0].name  = "IQ80321 PCI I/O Space";
 	res[0].flags = IORESOURCE_IO;
 
-	res[1].start = IQ80321_PCI_MEM_BASE;
-	res[1].end   = IQ80321_PCI_MEM_BASE + IQ80321_PCI_MEM_SIZE;
+	res[1].start = IOP321_PCI_LOWER_MEM_PA;
+	res[1].end   = IOP321_PCI_UPPER_MEM_PA;
 	res[1].name  = "IQ80321 PCI Memory Space";
 	res[1].flags = IORESOURCE_MEM;
 
 	request_resource(&ioport_resource, &res[0]);
 	request_resource(&iomem_resource, &res[1]);
 
-	/*
-	 * Since the IQ80321 is a slave card on a PCI backplane,
-	 * it uses BAR1 to reserve a portion of PCI memory space for
-	 * use with the private devices on the secondary bus
-	 * (GigE and PCI-X slot). We read BAR1 and configure
-	 * our outbound translation windows to target that
-	 * address range and assign all devices in that
-	 * address range. W/O this, certain BIOSes will fail
-	 * to boot as the IQ80321 claims addresses that are
-	 * in use by other devices.
-	 *
-	 * Note that the same cannot be done  with I/O space,
-	 * so hopefully the host will stick to the lower 64K for
-	 * PCI I/O and leave us alone.
-	 */
-	sys->mem_offset = IQ80321_PCI_MEM_BASE -
-		(*IOP321_IABAR1 & PCI_BASE_ADDRESS_MEM_MASK);
+	sys->mem_offset = IOP321_PCI_MEM_OFFSET;
+	sys->io_offset  = IOP321_PCI_IO_OFFSET;
 
 	sys->resource[0] = &res[0];
 	sys->resource[1] = &res[1];
 	sys->resource[2] = NULL;
-	sys->io_offset   = IQ80321_PCI_IO_OFFSET;
-
-	iop3xx_pcibios_min_io = IQ80321_PCI_IO_BASE;
-	iop3xx_pcibios_min_mem = IQ80321_PCI_MEM_BASE;
 
 	return 1;
 }
diff -Nru a/arch/arm/mach-iop3xx/iq80331-pci.c b/arch/arm/mach-iop3xx/iq80331-pci.c
--- a/arch/arm/mach-iop3xx/iq80331-pci.c	2005-03-01 23:39:17 -08:00
+++ b/arch/arm/mach-iop3xx/iq80331-pci.c	2005-03-01 23:39:17 -08:00
@@ -4,7 +4,7 @@
  * PCI support for the Intel IQ80331 reference board
  *
  * Author: Dave Jiang <dave.jiang@intel.com>
- * Copyright (C) 2003 Intel Corp.
+ * Copyright (C) 2003, 2004 Intel Corp.
  *
  * 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
@@ -68,44 +68,25 @@
 
 	memset(res, 0, sizeof(struct resource) * 2);
 
-	res[0].start = IQ80331_PCI_IO_BASE + 0x6e000000;
-	res[0].end   = IQ80331_PCI_IO_BASE + IQ80331_PCI_IO_SIZE - 1 + IQ80331_PCI_IO_OFFSET;
+	res[0].start = IOP331_PCI_LOWER_IO_VA;
+	res[0].end   = IOP331_PCI_UPPER_IO_VA;
 	res[0].name  = "IQ80331 PCI I/O Space";
 	res[0].flags = IORESOURCE_IO;
 
-	res[1].start = IQ80331_PCI_MEM_BASE;
-	res[1].end   = IQ80331_PCI_MEM_BASE + IQ80331_PCI_MEM_SIZE;
+	res[1].start = IOP331_PCI_LOWER_MEM_PA;
+	res[1].end   = IOP331_PCI_UPPER_MEM_PA;
 	res[1].name  = "IQ80331 PCI Memory Space";
 	res[1].flags = IORESOURCE_MEM;
 
 	request_resource(&ioport_resource, &res[0]);
 	request_resource(&iomem_resource, &res[1]);
 
-	/*
-	 * Since the IQ80331 is a slave card on a PCI backplane,
-	 * it uses BAR1 to reserve a portion of PCI memory space for
-	 * use with the private devices on the secondary bus
-	 * (GigE and PCI-X slot). We read BAR1 and configure
-	 * our outbound translation windows to target that
-	 * address range and assign all devices in that
-	 * address range. W/O this, certain BIOSes will fail
-	 * to boot as the IQ80331 claims addresses that are
-	 * in use by other devices.
-	 *
-	 * Note that the same cannot be done  with I/O space,
-	 * so hopefully the host will stick to the lower 64K for
-	 * PCI I/O and leave us alone.
-	 */
-	sys->mem_offset = IQ80331_PCI_MEM_BASE -
-		(*IOP331_IABAR1 & PCI_BASE_ADDRESS_MEM_MASK);
+	sys->mem_offset = IOP331_PCI_MEM_OFFSET;
+	sys->io_offset  = IOP331_PCI_IO_OFFSET;
 
 	sys->resource[0] = &res[0];
 	sys->resource[1] = &res[1];
 	sys->resource[2] = NULL;
-	sys->io_offset   = IQ80331_PCI_IO_OFFSET;
-
-	iop3xx_pcibios_min_io = IQ80331_PCI_IO_BASE;
-	iop3xx_pcibios_min_mem = IQ80331_PCI_MEM_BASE;
 
 	return 1;
 }
diff -Nru a/arch/arm/mach-iop3xx/iq80332-mm.c b/arch/arm/mach-iop3xx/iq80332-mm.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/arm/mach-iop3xx/iq80332-mm.c	2005-03-01 23:39:26 -08:00
@@ -0,0 +1,36 @@
+/*
+ * linux/arch/arm/mach-iop3xx/mm.c
+ *
+ * Low level memory initialization for iq80332 platform
+ *
+ * Author: Dave Jiang <dave.jiang@intel.com>
+ * Copyright (C) 2004 Intel 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 <linux/mm.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+
+#include <asm/mach/map.h>
+#include <asm/mach-types.h>
+
+
+/*
+ * IQ80332 specific IO mappings
+ *
+ * We use RedBoot's setup for the onboard devices.
+ */
+
+void __init iq80332_map_io(void)
+{
+	iop331_map_io();
+}
diff -Nru a/arch/arm/mach-iop3xx/iq80332-pci.c b/arch/arm/mach-iop3xx/iq80332-pci.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/arm/mach-iop3xx/iq80332-pci.c	2005-03-01 23:39:26 -08:00
@@ -0,0 +1,125 @@
+/*
+ * arch/arm/mach-iop3xx/iq80332-pci.c
+ *
+ * PCI support for the Intel IQ80332 reference board
+ *
+ * Author: Dave Jiang <dave.jiang@intel.com>
+ * Copyright (C) 2004 Intel Corp.
+ *
+ * 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/pci.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach/pci.h>
+#include <asm/mach-types.h>
+
+/*
+ * The following macro is used to lookup irqs in a standard table
+ * format for those systems that do not already have PCI
+ * interrupts properly routed.  We assume 1 <= pin <= 4
+ */
+#define PCI_IRQ_TABLE_LOOKUP(minid,maxid)	\
+({ int _ctl_ = -1;				\
+   unsigned int _idsel = idsel - minid;		\
+   if (_idsel <= maxid)				\
+      _ctl_ = pci_irq_table[_idsel][pin-1];	\
+   _ctl_; })
+
+#define INTA	IRQ_IQ80332_INTA
+#define INTB	IRQ_IQ80332_INTB
+#define INTC	IRQ_IQ80332_INTC
+#define INTD	IRQ_IQ80332_INTD
+
+//#define INTE	IRQ_IQ80332_I82544
+
+static inline int __init
+iq80332_map_irq(struct pci_dev *dev, u8 idsel, u8 pin)
+{
+	static int pci_irq_table[][8] = {
+		/*
+		 * PCI IDSEL/INTPIN->INTLINE
+		 * A       B       C       D
+		 */
+		{-1,   -1,   -1,   -1},
+		{-1,   -1,   -1,   -1},
+		{-1,   -1,   -1,   -1},
+		{INTA, INTB, INTC, INTD}, /* PCI-X Slot */
+		{-1,   -1,   -1,   -1},
+		{INTC, INTC, INTC, INTC}, /* GigE  */
+		{-1,   -1,   -1,   -1},
+		{-1,   -1,   -1,   -1},
+	};
+
+	BUG_ON(pin < 1 || pin > 4);
+
+	return PCI_IRQ_TABLE_LOOKUP(1, 7);
+}
+
+static int iq80332_setup(int nr, struct pci_sys_data *sys)
+{
+	struct resource *res;
+
+	if(nr != 0)
+		return 0;
+
+	res = kmalloc(sizeof(struct resource) * 2, GFP_KERNEL);
+	if (!res)
+		panic("PCI: unable to alloc resources");
+
+	memset(res, 0, sizeof(struct resource) * 2);
+
+	res[0].start = IOP331_PCI_LOWER_IO_VA;
+	res[0].end   = IOP331_PCI_UPPER_IO_VA;
+	res[0].name  = "IQ80332 PCI I/O Space";
+	res[0].flags = IORESOURCE_IO;
+
+	res[1].start = IOP331_PCI_LOWER_MEM_PA;
+	res[1].end   = IOP331_PCI_UPPER_MEM_PA;
+	res[1].name  = "IQ80332 PCI Memory Space";
+	res[1].flags = IORESOURCE_MEM;
+
+	request_resource(&ioport_resource, &res[0]);
+	request_resource(&iomem_resource, &res[1]);
+
+	sys->mem_offset = IOP331_PCI_MEM_OFFSET;
+	sys->io_offset  = IOP331_PCI_IO_OFFSET;
+
+	sys->resource[0] = &res[0];
+	sys->resource[1] = &res[1];
+	sys->resource[2] = NULL;
+
+	return 1;
+}
+
+static void iq80332_preinit(void)
+{
+	iop331_init();
+}
+
+static struct hw_pci iq80332_pci __initdata = {
+	.swizzle	= pci_std_swizzle,
+	.nr_controllers = 1,
+	.setup		= iq80332_setup,
+	.scan		= iop331_scan_bus,
+	.preinit	= iq80332_preinit,
+	.map_irq	= iq80332_map_irq
+};
+
+static int __init iq80332_pci_init(void)
+{
+	if (machine_is_iq80332())
+		pci_common_init(&iq80332_pci);
+	return 0;
+}
+
+subsys_initcall(iq80332_pci_init);
+
+
+
+
diff -Nru a/arch/arm/mach-ixp2000/Kconfig b/arch/arm/mach-ixp2000/Kconfig
--- a/arch/arm/mach-ixp2000/Kconfig	2005-03-01 23:39:07 -08:00
+++ b/arch/arm/mach-ixp2000/Kconfig	2005-03-01 23:39:07 -08:00
@@ -14,21 +14,21 @@
 	help
 	  Say 'Y' here if you want your kernel to support the Radisys
 	  ENP2611 PCI network processing card. For more information on
-	  this card, see Documentation/arm/ENP2611.
+	  this card, see <file:Documentation/arm/ENP2611>.
 
 config ARCH_IXDP2400
 	bool "Support Intel IXDP2400"
 	help
 	  Say 'Y' here if you want your kernel to support the Intel
 	  IXDP2400 reference platform. For more information on
-	  this platform, see Documentation/arm/IXP2000.
+	  this platform, see <file:Documentation/arm/IXP2000>.
 
 config ARCH_IXDP2800
 	bool "Support Intel IXDP2800"
 	help
 	  Say 'Y' here if you want your kernel to support the Intel
 	  IXDP2800 reference platform. For more information on
-	  this platform, see Documentation/arm/IXP2000.
+	  this platform, see <file:Documentation/arm/IXP2000>.
 
 config ARCH_IXDP2X00
 	bool
@@ -40,14 +40,14 @@
 	help
 	  Say 'Y' here if you want your kernel to support the Intel
 	  IXDP2401 reference platform. For more information on
-	  this platform, see Documentation/arm/IXP2000.
+	  this platform, see <file:Documentation/arm/IXP2000>.
 
 config ARCH_IXDP2801
 	bool "Support Intel IXDP2801"
 	help
 	  Say 'Y' here if you want your kernel to support the Intel
 	  IXDP2801 reference platform. For more information on
-	  this platform, see Documentation/arm/IXP2000.
+	  this platform, see <file:Documentation/arm/IXP2000>.
 
 config ARCH_IXDP2X01
 	bool
diff -Nru a/arch/arm/mach-ixp2000/core.c b/arch/arm/mach-ixp2000/core.c
--- a/arch/arm/mach-ixp2000/core.c	2005-03-01 23:39:17 -08:00
+++ b/arch/arm/mach-ixp2000/core.c	2005-03-01 23:39:17 -08:00
@@ -40,7 +40,7 @@
 #include <asm/mach/time.h>
 #include <asm/mach/irq.h>
 
-static spinlock_t ixp2000_slowport_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(ixp2000_slowport_lock);
 static unsigned long ixp2000_slowport_irq_flags;
 
 /*************************************************************************
@@ -160,6 +160,9 @@
 	iotable_init(ixp2000_small_io_desc, ARRAY_SIZE(ixp2000_small_io_desc));
 	iotable_init(ixp2000_large_io_desc, ARRAY_SIZE(ixp2000_large_io_desc));
 	early_serial_setup(&ixp2000_serial_port);
+
+	/* Set slowport to 8-bit mode.  */
+	ixp2000_reg_write(IXP2000_SLOWPORT_FRM, 1);
 }
 
 /*************************************************************************
@@ -167,15 +170,15 @@
  *************************************************************************/
 static unsigned ticks_per_jiffy;
 static unsigned ticks_per_usec;
+static unsigned next_jiffy_time;
 
 unsigned long ixp2000_gettimeoffset (void)
 {
-	unsigned long elapsed;
+ 	unsigned long offset;
 
-	/* Get ticks since last perfect jiffy */
-	elapsed = ticks_per_jiffy - *IXP2000_T1_CSR;
+	offset = next_jiffy_time - *IXP2000_T4_CSR;
 
-	return elapsed / ticks_per_usec;
+	return offset / ticks_per_usec;
 }
 
 static int ixp2000_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
@@ -185,7 +188,10 @@
 	/* clear timer 1 */
 	ixp2000_reg_write(IXP2000_T1_CLR, 1);
 	
-	timer_tick(regs);
+	while ((next_jiffy_time - *IXP2000_T4_CSR) > ticks_per_jiffy) {
+		timer_tick(regs);
+		next_jiffy_time -= ticks_per_jiffy;
+	}
 
 	write_sequnlock(&xtime_lock);
 
@@ -201,13 +207,20 @@
 void __init ixp2000_init_time(unsigned long tick_rate)
 {
 	ixp2000_reg_write(IXP2000_T1_CLR, 0);
-	ixp2000_reg_write(IXP2000_T2_CLR, 0);
+	ixp2000_reg_write(IXP2000_T4_CLR, 0);
 
 	ticks_per_jiffy = (tick_rate + HZ/2) / HZ;
 	ticks_per_usec = tick_rate / 1000000;
 
 	ixp2000_reg_write(IXP2000_T1_CLD, ticks_per_jiffy);
 	ixp2000_reg_write(IXP2000_T1_CTL, (1 << 7));
+
+	/*
+	 * We use T4 as a monotonic counter to track missed jiffies
+	 */
+	ixp2000_reg_write(IXP2000_T4_CLD, -1);
+	ixp2000_reg_write(IXP2000_T4_CTL, (1 << 7));
+ 	next_jiffy_time = 0xffffffff - ticks_per_jiffy;
 
 	/* register for interrupt */
 	setup_irq(IRQ_IXP2000_TIMER1, &ixp2000_timer_irq);
diff -Nru a/arch/arm/mach-ixp2000/enp2611.c b/arch/arm/mach-ixp2000/enp2611.c
--- a/arch/arm/mach-ixp2000/enp2611.c	2005-03-01 23:38:55 -08:00
+++ b/arch/arm/mach-ixp2000/enp2611.c	2005-03-01 23:38:55 -08:00
@@ -57,7 +57,7 @@
 	ixp2000_init_time(50 * 1000 * 1000);
 }
 
-static struct enp2611_timer = {
+static struct sys_timer enp2611_timer = {
 	.init		= enp2611_timer_init,
 	.offset		= ixp2000_gettimeoffset,
 };
@@ -124,20 +124,28 @@
 {
 	int irq;
 
-	if (dev->bus->number == 0x00 && PCI_SLOT(dev->devfn) == 0x01) {
+	if (dev->bus->number == 0 && PCI_SLOT(dev->devfn) == 0) {
+		/* IXP2400. */
+		irq = IRQ_IXP2000_PCIA;
+	} else if (dev->bus->number == 0 && PCI_SLOT(dev->devfn) == 1) {
 		/* 21555 non-transparent bridge.  */
 		irq = IRQ_IXP2000_PCIB;
-	} else if (dev->bus->number == 0x01 && PCI_SLOT(dev->devfn) == 0x00) {
+	} else if (dev->bus->number == 0 && PCI_SLOT(dev->devfn) == 4) {
+		/* PCI2050B transparent bridge.  */
+		irq = -1;
+	} else if (dev->bus->number == 1 && PCI_SLOT(dev->devfn) == 0) {
 		/* 82559 ethernet.  */
 		irq = IRQ_IXP2000_PCIA;
+	} else if (dev->bus->number == 1 && PCI_SLOT(dev->devfn) == 1) {
+		/* SPI-3 option board.  */
+		irq = IRQ_IXP2000_PCIB;
 	} else {
-		printk(KERN_INFO "enp2611_pci_map_irq for unknown device\n");
-		irq = IRQ_IXP2000_PCI;
+		printk(KERN_ERR "enp2611_pci_map_irq() called for unknown "
+				"device PCI:%d:%d:%d\n", dev->bus->number,
+				PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
+		irq = -1;
 	}
 
-	printk(KERN_INFO "Assigned IRQ %d to PCI:%d:%d:%d\n", irq,
-		dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
-
 	return irq;
 }
 
@@ -151,7 +159,9 @@
 
 int __init enp2611_pci_init(void)
 {
-	pci_common_init(&enp2611_pci);
+	if (machine_is_enp2611())
+		pci_common_init(&enp2611_pci);
+
 	return 0;
 }
 
diff -Nru a/arch/arm/mach-ixp2000/ixdp2400.c b/arch/arm/mach-ixp2000/ixdp2400.c
--- a/arch/arm/mach-ixp2000/ixdp2400.c	2005-03-01 23:38:56 -08:00
+++ b/arch/arm/mach-ixp2000/ixdp2400.c	2005-03-01 23:38:56 -08:00
@@ -56,7 +56,7 @@
 	ixp2000_init_time(((3125000 * numerator) / (denominator)) / 2);
 }
 
-static struct timer ixdp2400_timer = {
+static struct sys_timer ixdp2400_timer = {
 	.init		= ixdp2400_timer_init,
 	.offset		= ixp2000_gettimeoffset,
 };
diff -Nru a/arch/arm/mach-ixp2000/ixdp2800.c b/arch/arm/mach-ixp2000/ixdp2800.c
--- a/arch/arm/mach-ixp2000/ixdp2800.c	2005-03-01 23:39:07 -08:00
+++ b/arch/arm/mach-ixp2000/ixdp2800.c	2005-03-01 23:39:07 -08:00
@@ -113,7 +113,7 @@
 		 * Device behind the first bridge
 		 */
 		if(dev->bus->self->devfn == IXDP2X00_P2P_DEVFN) {
-			switch(PCI_SLOT(dev->devfn)) {
+			switch(dev->devfn) {
 				case IXDP2X00_PMC_DEVFN:
 					return IRQ_IXDP2800_PMC;	
 			
diff -Nru a/arch/arm/mach-ixp2000/ixdp2x00.c b/arch/arm/mach-ixp2000/ixdp2x00.c
--- a/arch/arm/mach-ixp2000/ixdp2x00.c	2005-03-01 23:38:51 -08:00
+++ b/arch/arm/mach-ixp2000/ixdp2x00.c	2005-03-01 23:38:51 -08:00
@@ -91,7 +91,7 @@
 	unsigned long dummy;
 	static struct slowport_cfg old_cfg;
 
-#ifdef CONFGI_ARCH_IXDP2400
+#ifdef CONFIG_ARCH_IXDP2400
 	if (machine_is_ixdp2400())
 		ixp2000_acquire_slowport(&slowport_cpld_cfg, &old_cfg);
 #endif
diff -Nru a/arch/arm/mach-ixp2000/pci.c b/arch/arm/mach-ixp2000/pci.c
--- a/arch/arm/mach-ixp2000/pci.c	2005-03-01 23:38:58 -08:00
+++ b/arch/arm/mach-ixp2000/pci.c	2005-03-01 23:38:58 -08:00
@@ -142,10 +142,11 @@
 {
 
 	volatile u32 temp;
+	unsigned long flags;
 
 	pci_master_aborts = 1;
 
-	cli();
+	local_irq_save(flags);
 	temp = *(IXP2000_PCI_CONTROL);
 	if (temp & ((1 << 8) | (1 << 5))) {
 		ixp2000_reg_write(IXP2000_PCI_CONTROL, temp);
@@ -158,7 +159,7 @@
 			temp = *(IXP2000_PCI_CMDSTAT);
 		}
 	}
-	sti();
+	local_irq_restore(flags);
 
 	/*
 	 * If it was an imprecise abort, then we need to correct the
@@ -174,8 +175,9 @@
 clear_master_aborts(void)
 {
 	volatile u32 temp;
+	unsigned long flags;
 
-	cli();
+	local_irq_save(flags);
 	temp = *(IXP2000_PCI_CONTROL);
 	if (temp & ((1 << 8) | (1 << 5))) {	
 		ixp2000_reg_write(IXP2000_PCI_CONTROL, temp);
@@ -188,7 +190,7 @@
 			temp = *(IXP2000_PCI_CMDSTAT);
 		}
 	}
-	sti();
+	local_irq_restore(flags);
 
 	return 0;
 }
diff -Nru a/arch/arm/mach-ixp4xx/Kconfig b/arch/arm/mach-ixp4xx/Kconfig
--- a/arch/arm/mach-ixp4xx/Kconfig	2005-03-01 23:38:53 -08:00
+++ b/arch/arm/mach-ixp4xx/Kconfig	2005-03-01 23:38:53 -08:00
@@ -13,29 +13,37 @@
 	help
 	  Say 'Y' here if you want your kernel to support the Gateworks
 	  Avila Network Platform. For more information on this platform,
-	  see Documentation/arm/IXP4xx.
+	  see <file:Documentation/arm/IXP4xx>.
 
 config ARCH_ADI_COYOTE
 	bool "Coyote"
 	help
 	  Say 'Y' here if you want your kernel to support the ADI 
 	  Engineering Coyote Gateway Reference Platform. For more
-	  information on this platform, see Documentation/arm/IXP4xx.
+	  information on this platform, see <file:Documentation/arm/IXP4xx>.
 
 config ARCH_IXDP425
 	bool "IXDP425"
 	help
 	  Say 'Y' here if you want your kernel to support Intel's 
 	  IXDP425 Development Platform (Also known as Richfield).  
-	  For more information on this platform, see Documentation/arm/IXP4xx.
+	  For more information on this platform, see <file:Documentation/arm/IXP4xx>.
 
 config MACH_IXDPG425
 	bool "IXDPG425"
 	help
 	  Say 'Y' here if you want your kernel to support Intel's
 	  IXDPG425 Development Platform (Also known as Montajade).
+	  For more information on this platform, see <file:Documentation/arm/IXP4xx>.
+
+config MACH_IXDP465
+	bool "IXDP465"
+	help
+	  Say 'Y' here if you want your kernel to support Intel's
+	  IXDP465 Development Platform (Also known as BMP).
 	  For more information on this platform, see Documentation/arm/IXP4xx.
 
+
 #
 # IXCDP1100 is the exact same HW as IXDP425, but with a different machine 
 # number from the bootloader due to marketing monkeys, so we just enable it 
@@ -51,16 +59,42 @@
 	help
 	  Say 'Y' here if you want your kernel to support the Motorola
 	  PrPCM1100 Processor Mezanine Module. For more information on
-	  this platform, see Documentation/arm/IXP4xx.
+	  this platform, see <file:Documentation/arm/IXP4xx>.
 
 #
 # Avila and IXDP share the same source for now. Will change in future
 #
 config	ARCH_IXDP4XX
 	bool
-	depends on ARCH_IXDP425 || ARCH_AVILA
+	depends on ARCH_IXDP425 || ARCH_AVILA || MACH_IXDP465
+	default y
+
+#
+# Certain registers and IRQs are only enabled if supporting IXP465 CPUs
+#
+config CPU_IXP46X
+	bool
+	depends on MACH_IXDP465
 	default y
 
+config MACH_GTWX5715
+	bool "Gemtek WX5715 (Linksys WRV54G)"
+	depends on ARCH_IXP4XX
+	help
+		This board is currently inside the Linksys WRV54G Gateways.
+
+		IXP425 - 266mhz
+		32mb SDRAM
+		8mb Flash
+		miniPCI slot 0 does not have a card connector soldered to the board
+		miniPCI slot 1 has an ISL3880 802.11g card (Prism54)
+		npe0 is connected to a Kendin KS8995M Switch (4 ports)
+		npe1 is the "wan" port
+		"Console" UART is available on J11 as console
+		"High Speed" UART is n/c (as far as I can tell)
+		20 Pin ARM/Xscale JTAG interface on J2
+
+
 comment "IXP4xx Options"
 
 config IXP4XX_INDIRECT_PCI
@@ -71,7 +105,7 @@
           1) A direct mapped window from 0x48000000 to 0x4bffffff (64MB).
              To access PCI via this space, we simply ioremap() the BAR
              into the kernel and we can use the standard read[bwl]/write[bwl]
-             macros. This is the preffered method due to speed but it
+             macros. This is the preferred method due to speed but it
              limits the system to just 64MB of PCI memory. This can be 
              problamatic if using video cards and other memory-heavy devices.
           
diff -Nru a/arch/arm/mach-ixp4xx/Makefile b/arch/arm/mach-ixp4xx/Makefile
--- a/arch/arm/mach-ixp4xx/Makefile	2005-03-01 23:38:53 -08:00
+++ b/arch/arm/mach-ixp4xx/Makefile	2005-03-01 23:38:53 -08:00
@@ -8,4 +8,5 @@
 obj-$(CONFIG_MACH_IXDPG425)	+= ixdpg425-pci.o coyote-setup.o
 obj-$(CONFIG_ARCH_ADI_COYOTE)	+= coyote-pci.o coyote-setup.o
 obj-$(CONFIG_ARCH_PRPMC1100)	+= prpmc1100-pci.o prpmc1100-setup.o
+obj-$(CONFIG_MACH_GTWX5715)	+= gtwx5715-pci.o gtwx5715-setup.o
 
diff -Nru a/arch/arm/mach-ixp4xx/common-pci.c b/arch/arm/mach-ixp4xx/common-pci.c
--- a/arch/arm/mach-ixp4xx/common-pci.c	2005-03-01 23:39:09 -08:00
+++ b/arch/arm/mach-ixp4xx/common-pci.c	2005-03-01 23:39:09 -08:00
@@ -53,7 +53,7 @@
  * these transactions are atomic or we will end up
  * with corrupt data on the bus or in a driver.
  */
-static spinlock_t ixp4xx_pci_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(ixp4xx_pci_lock);
 
 /*
  * Read from PCI config space
@@ -348,10 +348,11 @@
 	asm("mrc p15, 0, %0, cr0, cr0, 0;" : "=r"(processor_id) :);
 
 	/*
-	 * Determine which PCI read method to use
+	 * Determine which PCI read method to use.
+	 * Rev 0 IXP425 requires workaround.
 	 */
-	if (!(processor_id & 0xf)) {
-		printk("PCI: IXP4xx A0 silicon detected - "
+	if (!(processor_id & 0xf) && !cpu_is_ixp46x()) {
+		printk("PCI: IXP42x A0 silicon detected - "
 			"PCI Non-Prefetch Workaround Enabled\n");
 		ixp4xx_pci_read = ixp4xx_pci_read_errata;
 	} else
diff -Nru a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
--- a/arch/arm/mach-ixp4xx/common.c	2005-03-01 23:38:57 -08:00
+++ b/arch/arm/mach-ixp4xx/common.c	2005-03-01 23:38:57 -08:00
@@ -145,7 +145,10 @@
  **************************************************************************/
 static void ixp4xx_irq_mask(unsigned int irq)
 {
-	*IXP4XX_ICMR &= ~(1 << irq);
+	if (cpu_is_ixp46x() && irq >= 32)
+		*IXP4XX_ICMR2 &= ~(1 << (irq - 32));
+	else
+		*IXP4XX_ICMR &= ~(1 << irq);
 }
 
 static void ixp4xx_irq_mask_ack(unsigned int irq)
@@ -155,13 +158,13 @@
 
 static void ixp4xx_irq_unmask(unsigned int irq)
 {
-	static int irq2gpio[NR_IRQS] = {
+	static int irq2gpio[32] = {
 		-1, -1, -1, -1, -1, -1,  0,  1,
 		-1, -1, -1, -1, -1, -1, -1, -1,
 		-1, -1, -1,  2,  3,  4,  5,  6,
 		 7,  8,  9, 10, 11, 12, -1, -1,
 	};
-	int line = irq2gpio[irq];
+	int line = (irq < 32) ? irq2gpio[irq] : -1;
 
 	/*
 	 * This only works for LEVEL gpio IRQs as per the IXP4xx developer's
@@ -171,7 +174,10 @@
 	if (line >= 0)
 		gpio_line_isr_clear(line);
 
-	*IXP4XX_ICMR |= (1 << irq);
+	if (cpu_is_ixp46x() && irq >= 32)
+		*IXP4XX_ICMR2 |= (1 << (irq - 32));
+	else
+		*IXP4XX_ICMR |= (1 << irq);
 }
 
 static struct irqchip ixp4xx_irq_chip = {
@@ -190,6 +196,14 @@
 	/* Disable all interrupt */
 	*IXP4XX_ICMR = 0x0; 
 
+	if (cpu_is_ixp46x()) {
+		/* Route upper 32 sources to IRQ instead of FIQ */
+		*IXP4XX_ICLR2 = 0x00;
+
+		/* Disable upper 32 interrupts */
+		*IXP4XX_ICMR2 = 0x00;
+	}
+
 	for(i = 0; i < NR_IRQS; i++)
 	{
 		set_irq_chip(i, &ixp4xx_irq_chip);
@@ -265,3 +279,40 @@
 	.init		= ixp4xx_timer_init,
 	.offset		= ixp4xx_gettimeoffset,
 };
+
+static struct resource ixp46x_i2c_resources[] = {
+	[0] = {
+		.start 	= 0xc8011000,
+		.end	= 0xc801101c,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start 	= IRQ_IXP4XX_I2C,
+		.end	= IRQ_IXP4XX_I2C,
+		.flags	= IORESOURCE_IRQ
+	}
+};
+
+/*
+ * I2C controller. The IXP46x uses the same block as the IOP3xx, so
+ * we just use the same device name.
+ */
+static struct platform_device ixp46x_i2c_controller = {
+	.name		= "IOP3xx-I2C",
+	.id		= 0,
+	.num_resources	= 2,
+	.resource	= ixp46x_i2c_resources
+};
+
+static struct platform_device *ixp46x_devices[] __initdata = {
+	&ixp46x_i2c_controller
+};
+
+void __init ixp4xx_sys_init(void)
+{
+	if (cpu_is_ixp46x()) {
+		platform_add_devices(ixp46x_devices,
+				ARRAY_SIZE(ixp46x_devices));
+	}
+}
+
diff -Nru a/arch/arm/mach-ixp4xx/coyote-pci.c b/arch/arm/mach-ixp4xx/coyote-pci.c
--- a/arch/arm/mach-ixp4xx/coyote-pci.c	2005-03-01 23:38:58 -08:00
+++ b/arch/arm/mach-ixp4xx/coyote-pci.c	2005-03-01 23:38:58 -08:00
@@ -14,6 +14,7 @@
  *
  */
 
+#include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/init.h>
 
diff -Nru a/arch/arm/mach-ixp4xx/coyote-setup.c b/arch/arm/mach-ixp4xx/coyote-setup.c
--- a/arch/arm/mach-ixp4xx/coyote-setup.c	2005-03-01 23:38:53 -08:00
+++ b/arch/arm/mach-ixp4xx/coyote-setup.c	2005-03-01 23:38:53 -08:00
@@ -8,6 +8,7 @@
  * Author: Deepak Saxena <dsaxena@plexity.net>
  */
 
+#include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/device.h>
 #include <linux/serial.h>
@@ -89,7 +90,8 @@
 	*IXP4XX_EXP_CS0 |= IXP4XX_FLASH_WRITABLE;
 	*IXP4XX_EXP_CS1 = *IXP4XX_EXP_CS0;
 
-	platform_add_devices(&coyote_devices, ARRAY_SIZE(coyote_devices));
+	ixp4xx_sys_init();
+	platform_add_devices(coyote_devices, ARRAY_SIZE(coyote_devices));
 }
 
 #ifdef CONFIG_ARCH_ADI_COYOTE
diff -Nru a/arch/arm/mach-ixp4xx/gtwx5715-pci.c b/arch/arm/mach-ixp4xx/gtwx5715-pci.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/arm/mach-ixp4xx/gtwx5715-pci.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,101 @@
+/*
+ * arch/arm/mach-ixp4xx/gtwx5715-pci.c
+ *
+ * Gemtek GTWX5715 (Linksys WRV54G) board setup
+ *
+ * Copyright (C) 2004 George T. Joseph
+ * Derived from Coyote
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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/pci.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <asm/mach-types.h>
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/arch/gtwx5715.h>
+#include <asm/mach/pci.h>
+
+extern void ixp4xx_pci_preinit(void);
+extern int ixp4xx_setup(int nr, struct pci_sys_data *sys);
+extern struct pci_bus *ixp4xx_scan_bus(int nr, struct pci_sys_data *sys);
+
+        /*
+        * The exact GPIO pins and IRQs are defined in arch-ixp4xx/gtwx5715.h
+        * Slot 0 isn't actually populated with a card connector but
+        * we initialize it anyway in case a future version has the
+        * slot populated or someone with good soldering skills has
+        * some free time.
+        */
+
+
+static void gtwx5715_init_gpio(u8 pin, u32 style)
+{
+	gpio_line_config(pin, style | IXP4XX_GPIO_ACTIVE_LOW);
+
+	if (style & IXP4XX_GPIO_IN) gpio_line_isr_clear(pin);
+}
+
+void __init gtwx5715_pci_preinit(void)
+{
+	gtwx5715_init_gpio(GTWX5715_PCI_SLOT0_INTA_GPIO,	IXP4XX_GPIO_IN);
+	gtwx5715_init_gpio(GTWX5715_PCI_SLOT1_INTA_GPIO,	IXP4XX_GPIO_IN);
+
+	ixp4xx_pci_preinit();
+}
+
+
+static int __init gtwx5715_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	int rc;
+	static int gtwx5715_irqmap
+			[GTWX5715_PCI_SLOT_COUNT]
+			[GTWX5715_PCI_INT_PIN_COUNT] = {
+	{GTWX5715_PCI_SLOT0_INTA_IRQ, GTWX5715_PCI_SLOT0_INTB_IRQ},
+	{GTWX5715_PCI_SLOT1_INTA_IRQ, GTWX5715_PCI_SLOT1_INTB_IRQ},
+};
+
+	if (slot >= GTWX5715_PCI_SLOT_COUNT ||
+			pin >= GTWX5715_PCI_INT_PIN_COUNT) rc = -1;
+	else
+		rc = gtwx5715_irqmap[slot][pin-1];
+
+	printk("%s: Mapped slot %d pin %d to IRQ %d\n", __FUNCTION__,slot, pin, rc);
+	return(rc);
+}
+
+struct hw_pci gtwx5715_pci __initdata = {
+	.nr_controllers = 1,
+	.preinit =        gtwx5715_pci_preinit,
+	.swizzle =        pci_std_swizzle,
+	.setup =          ixp4xx_setup,
+	.scan =           ixp4xx_scan_bus,
+	.map_irq =        gtwx5715_map_irq,
+};
+
+int __init gtwx5715_pci_init(void)
+{
+	if (machine_is_gtwx5715())
+	{
+		pci_common_init(&gtwx5715_pci);
+	}
+
+	return 0;
+}
+
+subsys_initcall(gtwx5715_pci_init);
diff -Nru a/arch/arm/mach-ixp4xx/gtwx5715-setup.c b/arch/arm/mach-ixp4xx/gtwx5715-setup.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/arm/mach-ixp4xx/gtwx5715-setup.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,153 @@
+/*
+ * arch/arm/mach-ixp4xx/gtwx5715-setup.c
+ *
+ * Gemtek GTWX5715 (Linksys WRV54G) board settup
+ *
+ * Copyright (C) 2004 George T. Joseph
+ * Derived from Coyote
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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/device.h>
+#include <linux/serial.h>
+#include <linux/tty.h>
+#include <linux/serial_8250.h>
+
+#include <asm/types.h>
+#include <asm/setup.h>
+#include <asm/memory.h>
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+#include <asm/arch/gtwx5715.h>
+
+/*
+ * Xscale UART registers are 32 bits wide with only the least
+ * significant 8 bits having any meaning.  From a configuration
+ * perspective, this means 2 things...
+ *
+ *   Setting .regshift = 2 so that the standard 16550 registers
+ *   line up on every 4th byte.
+ *
+ *   Shifting the register start virtual address +3 bytes when
+ *   compiled big-endian.  Since register writes are done on a
+ *   single byte basis, if the shift isn't done the driver will
+ *   write the value into the most significant byte of the register,
+ *   which is ignored, instead of the least significant.
+ */
+
+#ifdef	__ARMEB__
+#define	REG_OFFSET	3
+#else
+#define	REG_OFFSET	0
+#endif
+
+/*
+ * Only the second or "console" uart is connected on the gtwx5715.
+ */
+
+static struct resource gtwx5715_uart_resources[] = {
+	{
+		.start	= IXP4XX_UART2_BASE_PHYS,
+		.end	= IXP4XX_UART2_BASE_PHYS + 0x0fff,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= IRQ_IXP4XX_UART2,
+		.end	= IRQ_IXP4XX_UART2,
+		.flags	= IORESOURCE_IRQ,
+	},
+	{ },
+};
+
+
+static struct plat_serial8250_port gtwx5715_uart_platform_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 platform_device gtwx5715_uart_device = {
+	.name		= "serial8250",
+	.id		= 0,
+	.dev			= {
+		.platform_data	= gtwx5715_uart_platform_data,
+	},
+	.num_resources	= 2,
+	.resource	= gtwx5715_uart_resources,
+};
+
+
+void __init gtwx5715_map_io(void)
+{
+	ixp4xx_map_io();
+}
+
+static struct flash_platform_data gtwx5715_flash_data = {
+	.map_name	= "cfi_probe",
+	.width		= 2,
+};
+
+static struct resource gtwx5715_flash_resource = {
+	.start		= GTWX5715_FLASH_BASE,
+	.end		= GTWX5715_FLASH_BASE + GTWX5715_FLASH_SIZE,
+	.flags		= IORESOURCE_MEM,
+};
+
+static struct platform_device gtwx5715_flash = {
+	.name		= "IXP4XX-Flash",
+	.id		= 0,
+	.dev		= {
+		.platform_data = &gtwx5715_flash_data,
+	},
+	.num_resources	= 1,
+	.resource	= &gtwx5715_flash_resource,
+};
+
+static struct platform_device *gtwx5715_devices[] __initdata = {
+	&gtwx5715_uart_device,
+	&gtwx5715_flash,
+};
+
+static void __init gtwx5715_init(void)
+{
+	platform_add_devices(gtwx5715_devices, ARRAY_SIZE(gtwx5715_devices));
+}
+
+
+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)
+MACHINE_END
+
+
diff -Nru a/arch/arm/mach-ixp4xx/ixdp425-pci.c b/arch/arm/mach-ixp4xx/ixdp425-pci.c
--- a/arch/arm/mach-ixp4xx/ixdp425-pci.c	2005-03-01 23:38:57 -08:00
+++ b/arch/arm/mach-ixp4xx/ixdp425-pci.c	2005-03-01 23:38:57 -08:00
@@ -14,6 +14,7 @@
  *
  */
 
+#include <linux/kernel.h>
 #include <linux/config.h>
 #include <linux/pci.h>
 #include <linux/init.h>
@@ -73,9 +74,8 @@
 
 int __init ixdp425_pci_init(void)
 {
-	if (machine_is_ixdp425() || 
-		machine_is_ixcdp1100() || 
-		machine_is_avila())
+	if (machine_is_ixdp425() || machine_is_ixcdp1100() ||
+			machine_is_avila() || machine_is_ixdp465())
 		pci_common_init(&ixdp425_pci);
 	return 0;
 }
diff -Nru a/arch/arm/mach-ixp4xx/ixdp425-setup.c b/arch/arm/mach-ixp4xx/ixdp425-setup.c
--- a/arch/arm/mach-ixp4xx/ixdp425-setup.c	2005-03-01 23:38:57 -08:00
+++ b/arch/arm/mach-ixp4xx/ixdp425-setup.c	2005-03-01 23:38:57 -08:00
@@ -8,6 +8,7 @@
  * Author: Deepak Saxena <dsaxena@plexity.net>
  */
 
+#include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/device.h>
 #include <linux/serial.h>
@@ -108,10 +109,30 @@
 
 static void __init ixdp425_init(void)
 {
-	platform_add_devices(&ixdp425_devices, ARRAY_SIZE(ixdp425_devices));
+	ixp4xx_sys_init();
+
+	/*
+	 * IXP465 has 32MB window
+	 */
+	if (machine_is_ixdp465()) {
+		ixdp425_flash_resource.end += IXDP425_FLASH_SIZE;
+	}
+
+	platform_add_devices(ixdp425_devices, ARRAY_SIZE(ixdp425_devices));
 }
 
 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)
+	.timer		= &ixp4xx_timer,
+	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)
diff -Nru a/arch/arm/mach-ixp4xx/ixdpg425-pci.c b/arch/arm/mach-ixp4xx/ixdpg425-pci.c
--- a/arch/arm/mach-ixp4xx/ixdpg425-pci.c	2005-03-01 23:38:54 -08:00
+++ b/arch/arm/mach-ixp4xx/ixdpg425-pci.c	2005-03-01 23:38:54 -08:00
@@ -13,6 +13,7 @@
  *
  */
 
+#include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/init.h>
 
diff -Nru a/arch/arm/mach-ixp4xx/prpmc1100-pci.c b/arch/arm/mach-ixp4xx/prpmc1100-pci.c
--- a/arch/arm/mach-ixp4xx/prpmc1100-pci.c	2005-03-01 23:38:44 -08:00
+++ b/arch/arm/mach-ixp4xx/prpmc1100-pci.c	2005-03-01 23:38:44 -08:00
@@ -19,6 +19,7 @@
  *
  */
 
+#include <linux/kernel.h>
 #include <linux/config.h>
 #include <linux/pci.h>
 #include <linux/init.h>
diff -Nru a/arch/arm/mach-ixp4xx/prpmc1100-setup.c b/arch/arm/mach-ixp4xx/prpmc1100-setup.c
--- a/arch/arm/mach-ixp4xx/prpmc1100-setup.c	2005-03-01 23:38:53 -08:00
+++ b/arch/arm/mach-ixp4xx/prpmc1100-setup.c	2005-03-01 23:38:53 -08:00
@@ -8,6 +8,7 @@
  * Author: Deepak Saxena <dsaxena@plexity.net>
  */
 
+#include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/device.h>
 #include <linux/serial.h>
@@ -79,7 +80,9 @@
 
 static void __init prpmc1100_init(void)
 {
-	platform_add_devices(&prpmc1100_devices, ARRAY_SIZE(prpmc1100_devices));
+	ixp4xx_sys_init();
+
+	platform_add_devices(prpmc1100_devices, ARRAY_SIZE(prpmc1100_devices));
 }
 
 MACHINE_START(PRPMC1100, "Motorola PrPMC1100")
diff -Nru a/arch/arm/mach-omap/board-h2.c b/arch/arm/mach-omap/board-h2.c
--- a/arch/arm/mach-omap/board-h2.c	2005-03-01 23:39:18 -08:00
+++ b/arch/arm/mach-omap/board-h2.c	2005-03-01 23:39:18 -08:00
@@ -32,10 +32,11 @@
 #include <asm/arch/clocks.h>
 #include <asm/arch/gpio.h>
 #include <asm/arch/usb.h>
-#include <asm/arch/serial.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 resource h2_smc91x_resources[] = {
@@ -45,8 +46,8 @@
 		.flags	= IORESOURCE_MEM,
 	},
 	[1] = {
-		.start	= 0,				/* Really GPIO 0 */
-		.end	= 0,
+		.start	= OMAP_GPIO_IRQ(0),
+		.end	= OMAP_GPIO_IRQ(0),
 		.flags	= IORESOURCE_IRQ,
 	},
 };
@@ -62,9 +63,20 @@
 	&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 = {
diff -Nru a/arch/arm/mach-omap/board-h3.c b/arch/arm/mach-omap/board-h3.c
--- a/arch/arm/mach-omap/board-h3.c	2005-03-01 23:38:51 -08:00
+++ b/arch/arm/mach-omap/board-h3.c	2005-03-01 23:38:51 -08:00
@@ -28,16 +28,13 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/arch/irqs.h>
+#include <asm/arch/mux.h>
 #include <asm/arch/gpio.h>
 #include <asm/mach-types.h>
-#include <asm/arch/serial.h>
 
 #include "common.h"
 
-void h3_init_irq(void)
-{
-	omap_init_irq();
-}
+extern int omap_gpio_init(void);
 
 static int __initdata h3_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 1};
 
@@ -48,8 +45,8 @@
 		.flags	= IORESOURCE_MEM,
 	},
 	[1] = {
-		.start	= 0,
-		.end	= 0,
+		.start	= OMAP_GPIO_IRQ(40),
+		.end	= OMAP_GPIO_IRQ(40),
 		.flags	= IORESOURCE_IRQ,
 	},
 };
@@ -68,6 +65,23 @@
 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)
diff -Nru a/arch/arm/mach-omap/board-innovator.c b/arch/arm/mach-omap/board-innovator.c
--- a/arch/arm/mach-omap/board-innovator.c	2005-03-01 23:38:51 -08:00
+++ b/arch/arm/mach-omap/board-innovator.c	2005-03-01 23:38:51 -08:00
@@ -30,13 +30,12 @@
 #include <asm/arch/gpio.h>
 #include <asm/arch/fpga.h>
 #include <asm/arch/usb.h>
-#include <asm/arch/serial.h>
 
 #include "common.h"
 
-#ifdef CONFIG_ARCH_OMAP1510
+static int __initdata innovator_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 1};
 
-extern int omap_gpio_init(void);
+#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 = {
@@ -44,8 +43,6 @@
 	MT_DEVICE },
 };
 
-static int __initdata innovator_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 1};
-
 static struct resource innovator1510_smc91x_resources[] = {
 	[0] = {
 		.start	= OMAP1510_FPGA_ETHR_START,	/* Physical */
@@ -81,8 +78,8 @@
 		.flags	= IORESOURCE_MEM,
 	},
 	[1] = {
-		.start	= 0,				/* Really GPIO 0 */
-		.end	= 0,
+		.start	= OMAP_GPIO_IRQ(0),
+		.end	= OMAP_GPIO_IRQ(0),
 		.flags	= IORESOURCE_IRQ,
 	},
 };
@@ -100,15 +97,31 @@
 
 #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()) {
-		omap_gpio_init();
 		omap1510_fpga_init_irq();
 	}
 #endif
+	innovator_init_smc91x();
 }
 
 #ifdef CONFIG_ARCH_OMAP1510
diff -Nru a/arch/arm/mach-omap/board-osk.c b/arch/arm/mach-omap/board-osk.c
--- a/arch/arm/mach-omap/board-osk.c	2005-03-01 23:39:09 -08:00
+++ b/arch/arm/mach-omap/board-osk.c	2005-03-01 23:39:09 -08:00
@@ -39,7 +39,6 @@
 #include <asm/arch/gpio.h>
 #include <asm/arch/fpga.h>
 #include <asm/arch/usb.h>
-#include <asm/arch/serial.h>
 
 #include "common.h"
 
@@ -57,8 +56,8 @@
 		.flags	= IORESOURCE_MEM,
 	},
 	[1] = {
-		.start	= 0,				/* Really GPIO 0 */
-		.end	= 0,
+		.start	= OMAP_GPIO_IRQ(0),
+		.end	= OMAP_GPIO_IRQ(0),
 		.flags	= IORESOURCE_IRQ,
 	},
 };
@@ -74,9 +73,20 @@
 	&osk5912_smc91x_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);
+}
+
 void osk_init_irq(void)
 {
 	omap_init_irq();
+	omap_gpio_init();
+	osk_init_smc91x();
 }
 
 static struct omap_usb_config osk_usb_config __initdata = {
diff -Nru a/arch/arm/mach-omap/board-perseus2.c b/arch/arm/mach-omap/board-perseus2.c
--- a/arch/arm/mach-omap/board-perseus2.c	2005-03-01 23:39:08 -08:00
+++ b/arch/arm/mach-omap/board-perseus2.c	2005-03-01 23:39:08 -08:00
@@ -14,6 +14,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/device.h>
+#include <linux/delay.h>
 
 #include <asm/hardware.h>
 #include <asm/mach-types.h>
@@ -28,11 +29,6 @@
 
 #include "common.h"
 
-void omap_perseus2_init_irq(void)
-{
-	omap_init_irq();
-}
-
 static struct resource smc91x_resources[] = {
 	[0] = {
 		.start	= H2P2_DBG_FPGA_ETHR_START,	/* Physical */
@@ -62,6 +58,22 @@
 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 */
diff -Nru a/arch/arm/mach-omap/clock.c b/arch/arm/mach-omap/clock.c
--- a/arch/arm/mach-omap/clock.c	2005-03-01 23:38:58 -08:00
+++ b/arch/arm/mach-omap/clock.c	2005-03-01 23:38:58 -08:00
@@ -22,7 +22,7 @@
 
 static LIST_HEAD(clocks);
 static DECLARE_MUTEX(clocks_sem);
-static spinlock_t clockfw_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(clockfw_lock);
 static void propagate_rate(struct clk *  clk);
 /* MPU virtual clock functions */
 static int select_table_rate(unsigned long rate);
diff -Nru a/arch/arm/mach-omap/common.c b/arch/arm/mach-omap/common.c
--- a/arch/arm/mach-omap/common.c	2005-03-01 23:39:17 -08:00
+++ b/arch/arm/mach-omap/common.c	2005-03-01 23:39:17 -08:00
@@ -30,8 +30,6 @@
 #include <asm/arch/board.h>
 #include <asm/arch/mux.h>
 #include <asm/arch/fpga.h>
-#include <asm/arch/serial.h>
-
 
 #include "clock.h"
 
@@ -307,14 +305,14 @@
 		_omap_map_io();
 }
 
-static inline unsigned int omap_serial_in(struct plat_serial8250_port *up, 
+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, 
+static inline void omap_serial_outp(struct plat_serial8250_port *p, int offset,
 				    int value)
 {
 	offset <<= p->regshift;
@@ -323,12 +321,14 @@
 
 /*
  * Internal UARTs need to be initialized for the 8250 autoconfig to work
- * properly.
+ * 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_MDR1, 0x00); /* enable UART */
+	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);
diff -Nru a/arch/arm/mach-omap/dma.c b/arch/arm/mach-omap/dma.c
--- a/arch/arm/mach-omap/dma.c	2005-03-01 23:39:16 -08:00
+++ b/arch/arm/mach-omap/dma.c	2005-03-01 23:39:16 -08:00
@@ -6,6 +6,7 @@
  * 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.
  *
@@ -477,10 +478,6 @@
 			if (dev_id == 0)
 				break;
 		}
-		if (dev_id != 0 && dma_chan[ch].dev_id == dev_id) {
-			spin_unlock_irqrestore(&dma_chan_lock, flags);
-			return -EAGAIN;
-		}
 	}
 	if (free_ch == -1) {
 		spin_unlock_irqrestore(&dma_chan_lock, flags);
@@ -931,6 +928,50 @@
 			    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;
@@ -999,9 +1040,13 @@
 	}
 	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);
diff -Nru a/arch/arm/mach-omap/mux.c b/arch/arm/mach-omap/mux.c
--- a/arch/arm/mach-omap/mux.c	2005-03-01 23:39:09 -08:00
+++ b/arch/arm/mach-omap/mux.c	2005-03-01 23:39:09 -08:00
@@ -40,7 +40,7 @@
 int __init_or_module
 omap_cfg_reg(const reg_cfg_t reg_cfg)
 {
-	static spinlock_t mux_spin_lock = SPIN_LOCK_UNLOCKED;
+	static DEFINE_SPINLOCK(mux_spin_lock);
 
 	unsigned long flags;
 	reg_cfg_set *cfg;
diff -Nru a/arch/arm/mach-omap/pm.c b/arch/arm/mach-omap/pm.c
--- a/arch/arm/mach-omap/pm.c	2005-03-01 23:38:54 -08:00
+++ b/arch/arm/mach-omap/pm.c	2005-03-01 23:38:54 -08:00
@@ -81,6 +81,12 @@
 	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 {
@@ -508,7 +514,7 @@
  */
 //#include <asm/arch/hardware.h>
 
-static int omap_pm_prepare(u32 state)
+static int omap_pm_prepare(suspend_state_t state)
 {
 	int error = 0;
 
@@ -535,7 +541,7 @@
  *
  */
 
-static int omap_pm_enter(u32 state)
+static int omap_pm_enter(suspend_state_t state)
 {
 	switch (state)
 	{
@@ -563,7 +569,7 @@
  *	failed).
  */
 
-static int omap_pm_finish(u32 state)
+static int omap_pm_finish(suspend_state_t state)
 {
 	return 0;
 }
diff -Nru a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
--- a/arch/arm/mach-pxa/Kconfig	2005-03-01 23:38:54 -08:00
+++ b/arch/arm/mach-pxa/Kconfig	2005-03-01 23:38:54 -08:00
@@ -18,9 +18,29 @@
 	bool "Accelent Xscale IDP"
 	select PXA25x
 
+config PXA_SHARPSL
+	bool "SHARP SL-C7xx Models (Corgi, Shepherd and Husky)"
+	select PXA25x
+	help
+	  Say Y here if you intend to run this kernel on a
+	  Sharp SL-C700 (Corgi), SL-C750 (Shepherd) or a
+	  Sharp SL-C760 (Husky) handheld computer.
+
 endchoice
 
 endmenu
+
+config MACH_CORGI
+	bool "Enable Sharp SL-C700 (Corgi) Support"
+	depends PXA_SHARPSL
+
+config MACH_SHEPHERD
+	bool "Enable Sharp SL-C750 (Shepherd) Support"
+	depends PXA_SHARPSL
+
+config MACH_HUSKY
+	bool "Enable Sharp SL-C760 (Husky) Support"
+	depends PXA_SHARPSL
 
 config PXA25x
 	bool
diff -Nru a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile
--- a/arch/arm/mach-pxa/Makefile	2005-03-01 23:38:57 -08:00
+++ b/arch/arm/mach-pxa/Makefile	2005-03-01 23:38:57 -08:00
@@ -11,6 +11,7 @@
 obj-$(CONFIG_ARCH_LUBBOCK) += lubbock.o
 obj-$(CONFIG_MACH_MAINSTONE) += mainstone.o
 obj-$(CONFIG_ARCH_PXA_IDP) += idp.o
+obj-$(CONFIG_PXA_SHARPSL)	+= corgi.o corgi_ssp.o ssp.o
 
 # Support for blinky lights
 led-y := leds.o
diff -Nru a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/arm/mach-pxa/corgi.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,337 @@
+/*
+ * Support for Sharp SL-C7xx PDAs
+ * Models: SL-C700 (Corgi), SL-C750 (Shepherd), SL-C760 (Husky)
+ *
+ * Copyright (c) 2004-2005 Richard Purdie
+ *
+ * Based on Sharp's 2.4 kernel patches/lubbock.c
+ *
+ * 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/major.h>
+#include <linux/fs.h>
+#include <linux/interrupt.h>
+#include <linux/mmc/host.h>
+
+#include <asm/setup.h>
+#include <asm/memory.h>
+#include <asm/mach-types.h>
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/arch/pxa-regs.h>
+#include <asm/arch/irq.h>
+#include <asm/arch/mmc.h>
+#include <asm/arch/udc.h>
+#include <asm/arch/corgi.h>
+
+#include <asm/hardware/scoop.h>
+#include <video/w100fb.h>
+
+#include "generic.h"
+
+
+/*
+ * Corgi SCOOP Device
+ */
+static struct resource corgi_scoop_resources[] = {
+	[0] = {
+		.start		= 0x10800000,
+		.end		= 0x10800fff,
+		.flags		= IORESOURCE_MEM,
+	},
+};
+
+static struct scoop_config corgi_scoop_setup = {
+	.io_dir 	= CORGI_SCOOP_IO_DIR,
+	.io_out		= CORGI_SCOOP_IO_OUT,
+};
+
+static struct platform_device corgiscoop_device = {
+	.name		= "sharp-scoop",
+	.id		= -1,
+	.dev		= {
+ 		.platform_data	= &corgi_scoop_setup,
+	},
+	.num_resources	= ARRAY_SIZE(corgi_scoop_resources),
+	.resource	= corgi_scoop_resources,
+};
+
+
+/*
+ * Corgi SSP Device
+ *
+ * Set the parent as the scoop device because a lot of SSP devices
+ * also use scoop functions and this makes the power up/down order
+ * work correctly.
+ */
+static struct platform_device corgissp_device = {
+	.name		= "corgi-ssp",
+	.dev		= {
+ 		.parent = &corgiscoop_device.dev,
+	},
+	.id		= -1,
+};
+
+
+/*
+ * Corgi w100 Frame Buffer Device
+ */
+static struct w100fb_mach_info corgi_fb_info = {
+	.w100fb_ssp_send 	= corgi_ssp_lcdtg_send,
+	.comadj 			= -1,
+	.phadadj 			= -1,
+};
+
+static struct resource corgi_fb_resources[] = {
+	[0] = {
+		.start		= 0x08000000,
+		.end		= 0x08ffffff,
+		.flags		= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device corgifb_device = {
+	.name		= "w100fb",
+	.id		= -1,
+	.dev		= {
+ 		.platform_data	= &corgi_fb_info,
+ 		.parent = &corgissp_device.dev,
+	},
+	.num_resources	= ARRAY_SIZE(corgi_fb_resources),
+	.resource	= corgi_fb_resources,
+};
+
+
+/*
+ * Corgi Backlight Device
+ */
+static struct platform_device corgibl_device = {
+	.name		= "corgi-bl",
+	.dev		= {
+ 		.parent = &corgifb_device.dev,
+	},
+	.id		= -1,
+};
+
+
+/*
+ * MMC/SD Device
+ *
+ * The card detect interrupt isn't debounced so we delay it by HZ/4
+ * to give the card a chance to fully insert/eject.
+ */
+static struct mmc_detect {
+	struct timer_list detect_timer;
+	void *devid;
+} mmc_detect;
+
+static void mmc_detect_callback(unsigned long data)
+{
+	mmc_detect_change(mmc_detect.devid);
+}
+
+static irqreturn_t corgi_mmc_detect_int(int irq, void *devid, struct pt_regs *regs)
+{
+	mmc_detect.devid=devid;
+	mod_timer(&mmc_detect.detect_timer, jiffies + HZ/4);
+	return IRQ_HANDLED;
+}
+
+static int corgi_mci_init(struct device *dev, irqreturn_t (*unused_detect_int)(int, void *, struct pt_regs *), void *data)
+{
+	int err;
+
+	/* setup GPIO for PXA25x MMC controller	*/
+	pxa_gpio_mode(GPIO6_MMCCLK_MD);
+	pxa_gpio_mode(GPIO8_MMCCS0_MD);
+	pxa_gpio_mode(CORGI_GPIO_nSD_DETECT | GPIO_IN);
+	pxa_gpio_mode(CORGI_GPIO_SD_PWR | GPIO_OUT);
+
+	init_timer(&mmc_detect.detect_timer);
+	mmc_detect.detect_timer.function = mmc_detect_callback;
+	mmc_detect.detect_timer.data = (unsigned long) &mmc_detect;
+
+	err = request_irq(CORGI_IRQ_GPIO_nSD_DETECT, corgi_mmc_detect_int, SA_INTERRUPT,
+			     "MMC card detect", data);
+	if (err) {
+		printk(KERN_ERR "corgi_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
+		return -1;
+	}
+
+	set_irq_type(CORGI_IRQ_GPIO_nSD_DETECT, IRQT_BOTHEDGE);
+
+	return 0;
+}
+
+static void corgi_mci_setpower(struct device *dev, unsigned int vdd)
+{
+	struct pxamci_platform_data* p_d = dev->platform_data;
+
+	if (( 1 << vdd) & p_d->ocr_mask) {
+		printk(KERN_DEBUG "%s: on\n", __FUNCTION__);
+		GPSR1 = GPIO_bit(CORGI_GPIO_SD_PWR);
+	} else {
+		printk(KERN_DEBUG "%s: off\n", __FUNCTION__);
+		GPCR1 = GPIO_bit(CORGI_GPIO_SD_PWR);
+	}
+}
+
+static void corgi_mci_exit(struct device *dev, void *data)
+{
+	free_irq(CORGI_IRQ_GPIO_nSD_DETECT, data);
+	del_timer(&mmc_detect.detect_timer);
+}
+
+static struct pxamci_platform_data corgi_mci_platform_data = {
+	.ocr_mask	= MMC_VDD_32_33|MMC_VDD_33_34,
+	.init 		= corgi_mci_init,
+	.setpower 	= corgi_mci_setpower,
+	.exit		= corgi_mci_exit,
+};
+
+
+/*
+ * USB Device Controller
+ */
+static void corgi_udc_command(int cmd)
+{
+	switch(cmd)	{
+	case PXA2XX_UDC_CMD_CONNECT:
+		GPSR(CORGI_GPIO_USB_PULLUP) = GPIO_bit(CORGI_GPIO_USB_PULLUP);
+		break;
+	case PXA2XX_UDC_CMD_DISCONNECT:
+		GPCR(CORGI_GPIO_USB_PULLUP) = GPIO_bit(CORGI_GPIO_USB_PULLUP);
+		break;
+	}
+}
+
+static struct pxa2xx_udc_mach_info udc_info __initdata = {
+	/* no connect GPIO; corgi can't tell connection status */
+	.udc_command		= corgi_udc_command,
+};
+
+
+static struct platform_device *devices[] __initdata = {
+	&corgiscoop_device,
+	&corgissp_device,
+	&corgifb_device,
+	&corgibl_device,
+};
+
+static struct sharpsl_flash_param_info sharpsl_flash_param;
+
+static void corgi_get_param(void)
+{
+	sharpsl_flash_param.comadj_keyword = readl(FLASH_MEM_BASE + FLASH_COMADJ_MAGIC_ADR);
+	sharpsl_flash_param.comadj = readl(FLASH_MEM_BASE + FLASH_COMADJ_DATA_ADR);
+
+	sharpsl_flash_param.phad_keyword = readl(FLASH_MEM_BASE + FLASH_PHAD_MAGIC_ADR);
+	sharpsl_flash_param.phadadj = readl(FLASH_MEM_BASE + FLASH_PHAD_DATA_ADR);
+}
+
+static void __init corgi_init(void)
+{
+	if (sharpsl_flash_param.comadj_keyword == FLASH_COMADJ_MAJIC)
+		corgi_fb_info.comadj=sharpsl_flash_param.comadj;
+	else
+		corgi_fb_info.comadj=-1;
+
+	if (sharpsl_flash_param.phad_keyword == FLASH_PHAD_MAJIC)
+		corgi_fb_info.phadadj=sharpsl_flash_param.phadadj;
+	else
+		corgi_fb_info.phadadj=-1;
+
+	pxa_gpio_mode(CORGI_GPIO_USB_PULLUP | GPIO_OUT);
+ 	pxa_set_udc_info(&udc_info);
+	pxa_set_mci_info(&corgi_mci_platform_data);
+
+	platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+static void __init fixup_corgi(struct machine_desc *desc,
+		struct tag *tags, char **cmdline, struct meminfo *mi)
+{
+	corgi_get_param();
+	mi->nr_banks=1;
+	mi->bank[0].start = 0xa0000000;
+	mi->bank[0].node = 0;
+	if (machine_is_corgi())
+		mi->bank[0].size = (32*1024*1024);
+	else
+		mi->bank[0].size = (64*1024*1024);
+}
+
+static void __init corgi_init_irq(void)
+{
+	pxa_init_irq();
+}
+
+static struct map_desc corgi_io_desc[] __initdata = {
+/*    virtual     physical    length      */
+/*	{ 0xf1000000, 0x08000000, 0x01000000, MT_DEVICE },*/ /* LCDC (readable for Qt driver) */
+/*	{ 0xef700000, 0x10800000, 0x00001000, MT_DEVICE },*/  /* SCOOP */
+	{ 0xef800000, 0x00000000, 0x00800000, MT_DEVICE }, /* Boot Flash */
+};
+
+static void __init corgi_map_io(void)
+{
+	pxa_map_io();
+	iotable_init(corgi_io_desc,ARRAY_SIZE(corgi_io_desc));
+
+	/* setup sleep mode values */
+	PWER  = 0x00000002;
+	PFER  = 0x00000000;
+	PRER  = 0x00000002;
+	PGSR0 = 0x0158C000;
+	PGSR1 = 0x00FF0080;
+	PGSR2 = 0x0001C004;
+	/* Stop 3.6MHz and drive HIGH to PCMCIA and CS */
+	PCFR |= PCFR_OPDE;
+}
+
+#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,
+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,
+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,
+MACHINE_END
+#endif
+
diff -Nru a/arch/arm/mach-pxa/corgi_ssp.c b/arch/arm/mach-pxa/corgi_ssp.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/arm/mach-pxa/corgi_ssp.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,248 @@
+/*
+ *  SSP control code for Sharp Corgi devices
+ *
+ *  Copyright (c) 2004 Richard Purdie
+ *
+ *  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/kernel.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <asm/hardware.h>
+
+#include <asm/arch/ssp.h>
+#include <asm/arch/corgi.h>
+#include <asm/arch/pxa-regs.h>
+
+static spinlock_t corgi_ssp_lock = SPIN_LOCK_UNLOCKED;
+static struct ssp_dev corgi_ssp_dev;
+static struct ssp_state corgi_ssp_state;
+
+/*
+ * There are three devices connected to the SSP interface:
+ *   1. A touchscreen controller (TI ADS7846 compatible)
+ *   2. An LCD contoller (with some Backlight functionality)
+ *   3. A battery moinitoring IC (Maxim MAX1111)
+ *
+ * Each device uses a different speed/mode of communication.
+ *
+ * The touchscreen is very sensitive and the most frequently used
+ * so the port is left configured for this.
+ *
+ * Devices are selected using Chip Selects on GPIOs.
+ */
+
+/*
+ *  ADS7846 Routines
+ */
+unsigned long corgi_ssp_ads7846_putget(ulong data)
+{
+	unsigned long ret,flag;
+
+	spin_lock_irqsave(&corgi_ssp_lock, flag);
+	GPCR0 = GPIO_bit(CORGI_GPIO_ADS7846_CS);
+
+	ssp_write_word(&corgi_ssp_dev,data);
+	ret = ssp_read_word(&corgi_ssp_dev);
+
+	GPSR0 = GPIO_bit(CORGI_GPIO_ADS7846_CS);
+	spin_unlock_irqrestore(&corgi_ssp_lock, flag);
+
+	return ret;
+}
+
+/*
+ * NOTE: These functions should always be called in interrupt context
+ * and use the _lock and _unlock functions. They are very time sensitive.
+ */
+void corgi_ssp_ads7846_lock(void)
+{
+	spin_lock(&corgi_ssp_lock);
+	GPCR0 = GPIO_bit(CORGI_GPIO_ADS7846_CS);
+}
+
+void corgi_ssp_ads7846_unlock(void)
+{
+	GPSR0 = GPIO_bit(CORGI_GPIO_ADS7846_CS);
+	spin_unlock(&corgi_ssp_lock);
+}
+
+void corgi_ssp_ads7846_put(ulong data)
+{
+	ssp_write_word(&corgi_ssp_dev,data);
+}
+
+unsigned long corgi_ssp_ads7846_get(void)
+{
+	return ssp_read_word(&corgi_ssp_dev);
+}
+
+EXPORT_SYMBOL(corgi_ssp_ads7846_putget);
+EXPORT_SYMBOL(corgi_ssp_ads7846_lock);
+EXPORT_SYMBOL(corgi_ssp_ads7846_unlock);
+EXPORT_SYMBOL(corgi_ssp_ads7846_put);
+EXPORT_SYMBOL(corgi_ssp_ads7846_get);
+
+
+/*
+ *  LCD/Backlight Routines
+ */
+unsigned long corgi_ssp_dac_put(ulong data)
+{
+	unsigned long flag;
+
+	spin_lock_irqsave(&corgi_ssp_lock, flag);
+	GPCR0 = GPIO_bit(CORGI_GPIO_LCDCON_CS);
+
+	ssp_disable(&corgi_ssp_dev);
+	ssp_config(&corgi_ssp_dev, (SSCR0_Motorola | (SSCR0_DSS & 0x07 )), SSCR1_SPH, 0, SSCR0_SerClkDiv(76));
+	ssp_enable(&corgi_ssp_dev);
+
+	ssp_write_word(&corgi_ssp_dev,data);
+	/* Read null data back from device to prevent SSP overflow */
+	ssp_read_word(&corgi_ssp_dev);
+
+	ssp_disable(&corgi_ssp_dev);
+	ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(2));
+	ssp_enable(&corgi_ssp_dev);
+	GPSR0 = GPIO_bit(CORGI_GPIO_LCDCON_CS);
+	spin_unlock_irqrestore(&corgi_ssp_lock, flag);
+
+	return 0;
+}
+
+void corgi_ssp_lcdtg_send(u8 adrs, u8 data)
+{
+	corgi_ssp_dac_put(((adrs & 0x07) << 5) | (data & 0x1f));
+}
+
+void corgi_ssp_blduty_set(int duty)
+{
+	corgi_ssp_lcdtg_send(0x02,duty);
+}
+
+EXPORT_SYMBOL(corgi_ssp_lcdtg_send);
+EXPORT_SYMBOL(corgi_ssp_blduty_set);
+
+/*
+ *  Max1111 Routines
+ */
+int corgi_ssp_max1111_get(ulong data)
+{
+	unsigned long flag;
+	int voltage,voltage1,voltage2;
+
+	spin_lock_irqsave(&corgi_ssp_lock, flag);
+	GPCR0 = GPIO_bit(CORGI_GPIO_MAX1111_CS);
+	ssp_disable(&corgi_ssp_dev);
+	ssp_config(&corgi_ssp_dev, (SSCR0_Motorola | (SSCR0_DSS & 0x07 )), 0, 0, SSCR0_SerClkDiv(8));
+	ssp_enable(&corgi_ssp_dev);
+
+	udelay(1);
+
+	/* TB1/RB1 */
+	ssp_write_word(&corgi_ssp_dev,data);
+	ssp_read_word(&corgi_ssp_dev); /* null read */
+
+	/* TB12/RB2 */
+	ssp_write_word(&corgi_ssp_dev,0);
+	voltage1=ssp_read_word(&corgi_ssp_dev);
+
+	/* TB13/RB3*/
+	ssp_write_word(&corgi_ssp_dev,0);
+	voltage2=ssp_read_word(&corgi_ssp_dev);
+
+	ssp_disable(&corgi_ssp_dev);
+	ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(2));
+	ssp_enable(&corgi_ssp_dev);
+	GPSR0 = GPIO_bit(CORGI_GPIO_MAX1111_CS);
+	spin_unlock_irqrestore(&corgi_ssp_lock, flag);
+
+	if (voltage1 & 0xc0 || voltage2 & 0x3f)
+		voltage = -1;
+	else
+		voltage = ((voltage1 << 2) & 0xfc) | ((voltage2 >> 6) & 0x03);
+
+	return voltage;
+}
+
+EXPORT_SYMBOL(corgi_ssp_max1111_get);
+
+/*
+ *  Support Routines
+ */
+int __init corgi_ssp_probe(struct device *dev)
+{
+	int ret;
+
+	/* Chip Select - Disable All */
+	GPDR0 |= GPIO_bit(CORGI_GPIO_LCDCON_CS); /* output */
+	GPSR0 = GPIO_bit(CORGI_GPIO_LCDCON_CS);  /* High - Disable LCD Control/Timing Gen */
+	GPDR0 |= GPIO_bit(CORGI_GPIO_MAX1111_CS); /* output */
+	GPSR0 = GPIO_bit(CORGI_GPIO_MAX1111_CS);  /* High - Disable MAX1111*/
+	GPDR0 |= GPIO_bit(CORGI_GPIO_ADS7846_CS);  /* output */
+	GPSR0 = GPIO_bit(CORGI_GPIO_ADS7846_CS);   /* High - Disable ADS7846*/
+
+	ret=ssp_init(&corgi_ssp_dev,1);
+
+	if (ret)
+		printk(KERN_ERR "Unable to register SSP handler!\n");
+	else {
+		ssp_disable(&corgi_ssp_dev);
+		ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(2));
+		ssp_enable(&corgi_ssp_dev);
+	}
+
+	return ret;
+}
+
+static int corgi_ssp_remove(struct device *dev)
+{
+	ssp_exit(&corgi_ssp_dev);
+	return 0;
+}
+
+static int corgi_ssp_suspend(struct device *dev, u32 state, u32 level)
+{
+	if (level == SUSPEND_POWER_DOWN) {
+		ssp_flush(&corgi_ssp_dev);
+		ssp_save_state(&corgi_ssp_dev,&corgi_ssp_state);
+	}
+	return 0;
+}
+
+static int corgi_ssp_resume(struct device *dev, u32 level)
+{
+	if (level == RESUME_POWER_ON) {
+		GPSR0 = GPIO_bit(CORGI_GPIO_LCDCON_CS);  /* High - Disable LCD Control/Timing Gen */
+		GPSR0 = GPIO_bit(CORGI_GPIO_MAX1111_CS); /* High - Disable MAX1111*/
+		GPSR0 = GPIO_bit(CORGI_GPIO_ADS7846_CS); /* High - Disable ADS7846*/
+		ssp_restore_state(&corgi_ssp_dev,&corgi_ssp_state);
+		ssp_enable(&corgi_ssp_dev);
+	}
+	return 0;
+}
+
+static struct device_driver corgissp_driver = {
+	.name		= "corgi-ssp",
+	.bus		= &platform_bus_type,
+	.probe		= corgi_ssp_probe,
+	.remove		= corgi_ssp_remove,
+	.suspend	= corgi_ssp_suspend,
+	.resume		= corgi_ssp_resume,
+};
+
+int __init corgi_ssp_init(void)
+{
+	return driver_register(&corgissp_driver);
+}
+
+arch_initcall(corgi_ssp_init);
diff -Nru a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c
--- a/arch/arm/mach-pxa/generic.c	2005-03-01 23:38:54 -08:00
+++ b/arch/arm/mach-pxa/generic.c	2005-03-01 23:38:54 -08:00
@@ -92,7 +92,7 @@
  */
 static struct map_desc standard_io_desc[] __initdata = {
  /* virtual     physical    length      type */
-  { 0xf2000000, 0x40000000, 0x01800000, MT_DEVICE }, /* Devs */
+  { 0xf2000000, 0x40000000, 0x02000000, MT_DEVICE }, /* Devs */
   { 0xf4000000, 0x44000000, 0x00100000, MT_DEVICE }, /* LCD */
   { 0xf6000000, 0x48000000, 0x00100000, MT_DEVICE }, /* Mem Ctl */
   { 0xf8000000, 0x4c000000, 0x00100000, MT_DEVICE }, /* USB host */
diff -Nru a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
--- a/arch/arm/mach-pxa/lubbock.c	2005-03-01 23:39:18 -08:00
+++ b/arch/arm/mach-pxa/lubbock.c	2005-03-01 23:39:18 -08:00
@@ -29,12 +29,13 @@
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 
+#include <asm/hardware/sa1111.h>
+
 #include <asm/arch/pxa-regs.h>
 #include <asm/arch/lubbock.h>
 #include <asm/arch/udc.h>
 #include <asm/arch/pxafb.h>
 #include <asm/arch/mmc.h>
-#include <asm/hardware/sa1111.h>
 
 #include "generic.h"
 
diff -Nru a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c
--- a/arch/arm/mach-pxa/mainstone.c	2005-03-01 23:39:17 -08:00
+++ b/arch/arm/mach-pxa/mainstone.c	2005-03-01 23:39:17 -08:00
@@ -33,6 +33,7 @@
 
 #include <asm/arch/pxa-regs.h>
 #include <asm/arch/mainstone.h>
+#include <asm/arch/audio.h>
 #include <asm/arch/pxafb.h>
 #include <asm/arch/mmc.h>
 
@@ -120,6 +121,44 @@
 	.resource	= smc91x_resources,
 };
 
+static int mst_audio_startup(snd_pcm_substream_t *substream, void *priv)
+{
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+		MST_MSCWR2 &= ~MST_MSCWR2_AC97_SPKROFF;
+	return 0;
+}
+
+static void mst_audio_shutdown(snd_pcm_substream_t *substream, void *priv)
+{
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+		MST_MSCWR2 |= MST_MSCWR2_AC97_SPKROFF;
+}
+
+static long mst_audio_suspend_mask;
+
+static void mst_audio_suspend(void *priv)
+{
+	mst_audio_suspend_mask = MST_MSCWR2;
+	MST_MSCWR2 |= MST_MSCWR2_AC97_SPKROFF;
+}
+
+static void mst_audio_resume(void *priv)
+{
+	MST_MSCWR2 &= mst_audio_suspend_mask | ~MST_MSCWR2_AC97_SPKROFF;
+}
+
+static pxa2xx_audio_ops_t mst_audio_ops = {
+	.startup	= mst_audio_startup,
+	.shutdown	= mst_audio_shutdown,
+	.suspend	= mst_audio_suspend,
+	.resume		= mst_audio_resume,
+};
+
+static struct platform_device mst_audio_device = {
+	.name		= "pxa2xx-ac97",
+	.id		= -1,
+	.dev		= { .platform_data = &mst_audio_ops },
+};
 
 static void mainstone_backlight_power(int on)
 {
@@ -228,7 +267,14 @@
 
 static void __init mainstone_init(void)
 {
+	/*
+	 * On Mainstone, we route AC97_SYSCLK via GPIO45 to
+	 * the audio daughter card
+	 */
+	pxa_gpio_mode(GPIO45_SYSCLK_AC97_MD);
+
 	platform_device_register(&smc91x_device);
+	platform_device_register(&mst_audio_device);
 
 	/* reading Mainstone's "Virtual Configuration Register"
 	   might be handy to select LCD type here */
diff -Nru a/arch/arm/mach-pxa/ssp.c b/arch/arm/mach-pxa/ssp.c
--- a/arch/arm/mach-pxa/ssp.c	2005-03-01 23:39:16 -08:00
+++ b/arch/arm/mach-pxa/ssp.c	2005-03-01 23:39:16 -08:00
@@ -17,7 +17,8 @@
  *
  *  Revision history:
  *   22nd Aug 2003 Initial version.
- *
+ *   20th Dec 2004 Added ssp_config for changing port config without
+ *                 closing the port.
  */
 
 #include <linux/module.h>
@@ -34,6 +35,11 @@
 #include <asm/arch/ssp.h>
 #include <asm/arch/pxa-regs.h>
 
+#define PXA_SSP_PORTS 	3
+
+static DECLARE_MUTEX(sem);
+static int use_count[PXA_SSP_PORTS] = {0, 0, 0};
+
 static irqreturn_t ssp_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	struct ssp_dev *dev = (struct ssp_dev*) dev_id;
@@ -171,6 +177,30 @@
 }
 
 /**
+ * ssp_config - configure SSP port settings
+ * @mode: port operating mode
+ * @flags: port config flags
+ * @psp_flags: port PSP config flags
+ * @speed: port speed
+ *
+ * Port MUST be disabled by ssp_disable before making any config changes.
+ */
+int ssp_config(struct ssp_dev *dev, u32 mode, u32 flags, u32 psp_flags, u32 speed)
+{
+	dev->mode = mode;
+	dev->flags = flags;
+	dev->psp_flags = psp_flags;
+	dev->speed = speed;
+
+	/* set up port type, speed, port settings */
+	SSCR0_P(dev->port) = (dev->speed | dev->mode);
+	SSCR1_P(dev->port) = dev->flags;
+	SSPSP_P(dev->port) = dev->psp_flags;
+
+	return 0;
+}
+
+/**
  * ssp_init - setup the SSP port
  *
  * initialise and claim resources for the SSP port.
@@ -180,12 +210,23 @@
  *   %-EBUSY	if the resources are already in use
  *   %0		on success
  */
-int ssp_init(struct ssp_dev *dev, u32 port, u32 mode, u32 flags, u32 psp_flags,
-						u32 speed)
+int ssp_init(struct ssp_dev *dev, u32 port)
 {
 	int ret, irq;
 
+	if (port > PXA_SSP_PORTS || port == 0)
+		return -ENODEV;
+
+	down(&sem);
+	if (use_count[port - 1]) {
+		up(&sem);
+		return -EBUSY;
+	}
+	use_count[port - 1]++;
+
 	if (!request_mem_region(__PREG(SSCR0_P(port)), 0x2c, "SSP")) {
+		use_count[port - 1]--;
+		up(&sem);
 		return -EBUSY;
 	}
 
@@ -213,15 +254,6 @@
 	}
 
 	dev->port = port;
-	dev->mode = mode;
-	dev->flags = flags;
-	dev->psp_flags = psp_flags;
-	dev->speed = speed;
-
-	/* set up port type, speed, port settings */
-	SSCR0_P(dev->port) = (dev->speed | dev->mode);
-	SSCR1_P(dev->port) = dev->flags;
-	SSPSP_P(dev->port) = dev->psp_flags;
 
 	ret = request_irq(irq, ssp_interrupt, 0, "SSP", dev);
 	if (ret)
@@ -252,10 +284,13 @@
 #endif
 	}
 
+	up(&sem);
 	return 0;
 
 out_region:
-	release_mem_region(__PREG(SSCR0_P(dev->port)), 0x2c);
+	release_mem_region(__PREG(SSCR0_P(port)), 0x2c);
+	use_count[port - 1]--;
+	up(&sem);
 	return ret;
 }
 
@@ -268,6 +303,7 @@
 {
 	int irq;
 
+	down(&sem);
 	SSCR0_P(dev->port) &= ~SSCR0_SSE;
 
 	/* find irq, save power and turn off SSP port clock */
@@ -306,6 +342,8 @@
 
 	free_irq(irq, dev);
 	release_mem_region(__PREG(SSCR0_P(dev->port)), 0x2c);
+	use_count[dev->port - 1]--;
+	up(&sem);
 }
 
 EXPORT_SYMBOL(ssp_write_word);
@@ -317,3 +355,9 @@
 EXPORT_SYMBOL(ssp_restore_state);
 EXPORT_SYMBOL(ssp_init);
 EXPORT_SYMBOL(ssp_exit);
+EXPORT_SYMBOL(ssp_config);
+
+MODULE_DESCRIPTION("PXA SSP driver");
+MODULE_AUTHOR("Liam Girdwood");
+MODULE_LICENSE("GPL");
+
diff -Nru a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig
--- a/arch/arm/mach-s3c2410/Kconfig	2005-03-01 23:38:56 -08:00
+++ b/arch/arm/mach-s3c2410/Kconfig	2005-03-01 23:38:56 -08:00
@@ -41,7 +41,7 @@
 	help
 	  Say Y here if you are using the HP iPAQ rx3715.
 
-	  See http://www.handhelds.org/projects/rx3715.html for more
+	  See <http://www.handhelds.org/projects/rx3715.html> for more
 	  information on this project
 
 endmenu
@@ -77,7 +77,7 @@
 	  to the kernel log, at priority KERN_DEBUG.
 
 	  Note, it is easy to create and fill the log buffer in a small
-	  amount of time, as well as using an significant percantage of
+	  amount of time, as well as using an significant percentage of
 	  the CPU time doing so.
 
 
@@ -115,9 +115,9 @@
 	  Choice of which UART port to use for the low-level messages,
 	  such as the `Uncompressing...` at start time. The value of
 	  this configuration should be between zero and two. The port
-	  must have been initalised by the boot-loader before use.
+	  must have been initialised by the boot-loader before use.
 
 	  Note, this does not affect the port used by the debug messages,
-	  which is a seperate configuration.
+	  which is a separate configuration.
 
 endif
diff -Nru a/arch/arm/mach-s3c2410/clock.c b/arch/arm/mach-s3c2410/clock.c
--- a/arch/arm/mach-s3c2410/clock.c	2005-03-01 23:38:52 -08:00
+++ b/arch/arm/mach-s3c2410/clock.c	2005-03-01 23:38:52 -08:00
@@ -60,7 +60,7 @@
 
 /* old functions */
 
-void inline s3c2410_clk_enable(unsigned int clocks, unsigned int enable)
+void inline s3c24xx_clk_enable(unsigned int clocks, unsigned int enable)
 {
 	unsigned long clkcon;
 	unsigned long flags;
@@ -88,9 +88,9 @@
 	return 0;
 }
 
-int s3c2410_clkcon_enable(struct clk *clk, int enable)
+int s3c24xx_clkcon_enable(struct clk *clk, int enable)
 {
-	s3c2410_clk_enable(clk->ctrlbit, enable);
+	s3c24xx_clk_enable(clk->ctrlbit, enable);
 	return 0;
 }
 
@@ -264,90 +264,90 @@
 	{ .name    = "nand",
 	  .id	   = -1,
 	  .parent  = &clk_h,
-	  .enable  = s3c2410_clkcon_enable,
+	  .enable  = s3c24xx_clkcon_enable,
 	  .ctrlbit = S3C2410_CLKCON_NAND
 	},
 	{ .name    = "lcd",
 	  .id	   = -1,
 	  .parent  = &clk_h,
-	  .enable  = s3c2410_clkcon_enable,
+	  .enable  = s3c24xx_clkcon_enable,
 	  .ctrlbit = S3C2410_CLKCON_LCDC
 	},
 	{ .name    = "usb-host",
 	  .id	   = -1,
 	  .parent  = &clk_h,
-	  .enable  = s3c2410_clkcon_enable,
+	  .enable  = s3c24xx_clkcon_enable,
 	  .ctrlbit = S3C2410_CLKCON_USBH
 	},
 	{ .name    = "usb-device",
 	  .id	   = -1,
 	  .parent  = &clk_h,
-	  .enable  = s3c2410_clkcon_enable,
+	  .enable  = s3c24xx_clkcon_enable,
 	  .ctrlbit = S3C2410_CLKCON_USBD
 	},
 	{ .name    = "timers",
 	  .parent  = &clk_p,
-	  .enable  = s3c2410_clkcon_enable,
+	  .enable  = s3c24xx_clkcon_enable,
 	  .ctrlbit = S3C2410_CLKCON_PWMT
 	},
 	{ .name    = "sdi",
 	  .id	   = -1,
 	  .parent  = &clk_p,
-	  .enable  = s3c2410_clkcon_enable,
+	  .enable  = s3c24xx_clkcon_enable,
 	  .ctrlbit = S3C2410_CLKCON_SDI
 	},
 	{ .name    = "uart",
 	  .id	   = 0,
 	  .parent  = &clk_p,
-	  .enable  = s3c2410_clkcon_enable,
+	  .enable  = s3c24xx_clkcon_enable,
 	  .ctrlbit = S3C2410_CLKCON_UART0
 	},
 	{ .name    = "uart",
 	  .id	   = 1,
 	  .parent  = &clk_p,
-	  .enable  = s3c2410_clkcon_enable,
+	  .enable  = s3c24xx_clkcon_enable,
 	  .ctrlbit = S3C2410_CLKCON_UART1
 	},
 	{ .name    = "uart",
 	  .id	   = 2,
 	  .parent  = &clk_p,
-	  .enable  = s3c2410_clkcon_enable,
+	  .enable  = s3c24xx_clkcon_enable,
 	  .ctrlbit = S3C2410_CLKCON_UART2
 	},
 	{ .name    = "gpio",
 	  .id	   = -1,
 	  .parent  = &clk_p,
-	  .enable  = s3c2410_clkcon_enable,
+	  .enable  = s3c24xx_clkcon_enable,
 	  .ctrlbit = S3C2410_CLKCON_GPIO
 	},
 	{ .name    = "rtc",
 	  .id	   = -1,
 	  .parent  = &clk_p,
-	  .enable  = s3c2410_clkcon_enable,
+	  .enable  = s3c24xx_clkcon_enable,
 	  .ctrlbit = S3C2410_CLKCON_RTC
 	},
 	{ .name    = "adc",
 	  .id	   = -1,
 	  .parent  = &clk_p,
-	  .enable  = s3c2410_clkcon_enable,
+	  .enable  = s3c24xx_clkcon_enable,
 	  .ctrlbit = S3C2410_CLKCON_ADC
 	},
 	{ .name    = "i2c",
 	  .id	   = -1,
 	  .parent  = &clk_p,
-	  .enable  = s3c2410_clkcon_enable,
+	  .enable  = s3c24xx_clkcon_enable,
 	  .ctrlbit = S3C2410_CLKCON_IIC
 	},
 	{ .name    = "iis",
 	  .id	   = -1,
 	  .parent  = &clk_p,
-	  .enable  = s3c2410_clkcon_enable,
+	  .enable  = s3c24xx_clkcon_enable,
 	  .ctrlbit = S3C2410_CLKCON_IIS
 	},
 	{ .name    = "spi",
 	  .id	   = -1,
 	  .parent  = &clk_p,
-	  .enable  = s3c2410_clkcon_enable,
+	  .enable  = s3c24xx_clkcon_enable,
 	  .ctrlbit = S3C2410_CLKCON_SPI
 	},
 	{ .name    = "watchdog",
@@ -359,7 +359,7 @@
 
 /* initialise the clock system */
 
-int s3c2410_register_clock(struct clk *clk)
+int s3c24xx_register_clock(struct clk *clk)
 {
 	clk->owner = THIS_MODULE;
 	atomic_set(&clk->used, 0);
@@ -378,7 +378,7 @@
 
 /* initalise all the clocks */
 
-int __init s3c2410_init_clocks(void)
+int __init s3c24xx_setup_clocks(void)
 {
 	struct clk *clkp = init_clocks;
 	int ptr;
@@ -403,28 +403,28 @@
 	 * and of course, this looks neater
 	 */
 
-	s3c2410_clk_enable(S3C2410_CLKCON_NAND, 0);
-	s3c2410_clk_enable(S3C2410_CLKCON_USBH, 0);
-	s3c2410_clk_enable(S3C2410_CLKCON_USBD, 0);
-	s3c2410_clk_enable(S3C2410_CLKCON_ADC, 0);
-	s3c2410_clk_enable(S3C2410_CLKCON_IIC, 0);
-	s3c2410_clk_enable(S3C2410_CLKCON_SPI, 0);
+	s3c24xx_clk_enable(S3C2410_CLKCON_NAND, 0);
+	s3c24xx_clk_enable(S3C2410_CLKCON_USBH, 0);
+	s3c24xx_clk_enable(S3C2410_CLKCON_USBD, 0);
+	s3c24xx_clk_enable(S3C2410_CLKCON_ADC, 0);
+	s3c24xx_clk_enable(S3C2410_CLKCON_IIC, 0);
+	s3c24xx_clk_enable(S3C2410_CLKCON_SPI, 0);
 
 	/* assume uart clocks are correctly setup */
 
 	/* register our clocks */
 
-	if (s3c2410_register_clock(&clk_f) < 0)
+	if (s3c24xx_register_clock(&clk_f) < 0)
 		printk(KERN_ERR "failed to register cpu fclk\n");
 
-	if (s3c2410_register_clock(&clk_h) < 0)
+	if (s3c24xx_register_clock(&clk_h) < 0)
 		printk(KERN_ERR "failed to register cpu hclk\n");
 
-	if (s3c2410_register_clock(&clk_p) < 0)
+	if (s3c24xx_register_clock(&clk_p) < 0)
 		printk(KERN_ERR "failed to register cpu pclk\n");
 
 	for (ptr = 0; ptr < ARRAY_SIZE(init_clocks); ptr++, clkp++) {
-		ret = s3c2410_register_clock(clkp);
+		ret = s3c24xx_register_clock(clkp);
 		if (ret < 0) {
 			printk(KERN_ERR "Failed to register clock %s (%d)\n",
 			       clkp->name, ret);
diff -Nru a/arch/arm/mach-s3c2410/clock.h b/arch/arm/mach-s3c2410/clock.h
--- a/arch/arm/mach-s3c2410/clock.h	2005-03-01 23:38:57 -08:00
+++ b/arch/arm/mach-s3c2410/clock.h	2005-03-01 23:38:57 -08:00
@@ -41,7 +41,7 @@
  * Please DO NOT use these outside of arch/arm/mach-s3c2410
 */
 
-extern int s3c2410_clkcon_enable(struct clk *clk, int enable);
-extern int s3c2410_register_clock(struct clk *clk);
-extern int s3c2410_init_clocks(void);
+extern int s3c24xx_clkcon_enable(struct clk *clk, int enable);
+extern int s3c24xx_register_clock(struct clk *clk);
 
+extern int s3c24xx_setup_clocks(void);
diff -Nru a/arch/arm/mach-s3c2410/cpu.c b/arch/arm/mach-s3c2410/cpu.c
--- a/arch/arm/mach-s3c2410/cpu.c	2005-03-01 23:38:57 -08:00
+++ b/arch/arm/mach-s3c2410/cpu.c	2005-03-01 23:38:57 -08:00
@@ -46,6 +46,8 @@
 	unsigned long	idcode;
 	unsigned long	idmask;
 	void		(*map_io)(struct map_desc *mach_desc, int size);
+	void		(*init_uarts)(struct s3c2410_uartcfg *cfg, int no);
+	void		(*init_clocks)(int xtal);
 	int		(*init)(void);
 	const char	*name;
 };
@@ -59,32 +61,40 @@
 
 static struct cpu_table cpu_ids[] __initdata = {
 	{
-		.idcode	= 0x32410000,
-		.idmask = 0xffffffff,
-		.map_io = s3c2410_map_io,
-		.init   = s3c2410_init,
-		.name   = name_s3c2410
+		.idcode		= 0x32410000,
+		.idmask		= 0xffffffff,
+		.map_io		= s3c2410_map_io,
+		.init_clocks	= s3c2410_init_clocks,
+		.init_uarts	= s3c2410_init_uarts,
+		.init		= s3c2410_init,
+		.name		= name_s3c2410
 	},
 	{
-		.idcode	= 0x32410002,
-		.idmask = 0xffffffff,
-		.map_io = s3c2410_map_io,
-		.init   = s3c2410_init,
-		.name   = name_s3c2410a
+		.idcode		= 0x32410002,
+		.idmask		= 0xffffffff,
+		.map_io		= s3c2410_map_io,
+		.init_clocks	= s3c2410_init_clocks,
+		.init_uarts	= s3c2410_init_uarts,
+		.init		= s3c2410_init,
+		.name		= name_s3c2410a
 	},
 	{
-		.idcode	= 0x32440000,
-		.idmask = 0xffffffff,
-		.map_io = s3c2440_map_io,
-		.init   = s3c2440_init,
-		.name   = name_s3c2440
+		.idcode		= 0x32440000,
+		.idmask		= 0xffffffff,
+		.map_io		= s3c2440_map_io,
+		.init_clocks	= s3c2440_init_clocks,
+		.init_uarts	= s3c2440_init_uarts,
+		.init		= s3c2440_init,
+		.name		= name_s3c2440
 	},
 	{
-		.idcode	= 0x32440001,
-		.idmask = 0xffffffff,
-		.map_io = s3c2440_map_io,
-		.init   = s3c2440_init,
-		.name   = name_s3c2440a
+		.idcode		= 0x32440001,
+		.idmask		= 0xffffffff,
+		.map_io		= s3c2440_map_io,
+		.init_clocks	= s3c2440_init_clocks,
+		.init_uarts	= s3c2440_init_uarts,
+		.init		= s3c2440_init,
+		.name		= name_s3c2440a
 	}
 };
 
@@ -127,7 +137,7 @@
 		struct clk **ptr = b->clocks;;
 
 		for (i = b->clocks_count; i > 0; i--, ptr++)
-			s3c2410_register_clock(*ptr);
+			s3c24xx_register_clock(*ptr);
 	}
 }
 
@@ -158,6 +168,40 @@
 	printk("CPU %s (id 0x%08lx)\n", cpu->name, idcode);
 
 	(cpu->map_io)(mach_desc, size);
+}
+
+/* s3c24xx_init_clocks
+ *
+ * Initialise the clock subsystem and associated information from the
+ * given master crystal value.
+ *
+ * xtal  = 0 -> use default PLL crystal value (normally 12MHz)
+ *      != 0 -> PLL crystal value in Hz
+*/
+
+void __init s3c24xx_init_clocks(int xtal)
+{
+	if (xtal != 0)
+		s3c24xx_xtal = xtal;
+
+	if (cpu == NULL)
+		panic("s3c24xx_init_clocks: no cpu setup?\n");
+
+	if (cpu->init_clocks == NULL)
+		panic("s3c24xx_init_clocks: cpu has no clock init\n");
+	else
+		(cpu->init_clocks)(xtal);
+}
+
+void __init s3c24xx_init_uarts(struct s3c2410_uartcfg *cfg, int no)
+{
+	if (cpu == NULL)
+		return;
+
+	if (cpu->init_uarts == NULL) {
+		printk(KERN_ERR "s3c24xx_init_uarts: cpu has no uart init\n");
+	} else
+		(cpu->init_uarts)(cfg, no);
 }
 
 static int __init s3c_arch_init(void)
diff -Nru a/arch/arm/mach-s3c2410/cpu.h b/arch/arm/mach-s3c2410/cpu.h
--- a/arch/arm/mach-s3c2410/cpu.h	2005-03-01 23:38:53 -08:00
+++ b/arch/arm/mach-s3c2410/cpu.h	2005-03-01 23:38:53 -08:00
@@ -1,7 +1,7 @@
 /* arch/arm/mach-s3c2410/cpu.h
  *
- * Copyright (c) 2004 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
+ * Copyright (c) 2004-2005 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
  *
  * Header file for S3C24XX CPU support
  *
@@ -12,6 +12,9 @@
  * Modifications:
  *     24-Aug-2004 BJD  Start of generic S3C24XX support
  *     18-Oct-2004 BJD  Moved board struct into this file
+ *     04-Jan-2005 BJD  New uart initialisation
+ *     10-Jan-2005 BJD  Moved generic init here, specific to cpu headers
+ *     14-Jan-2005 BJD  Added s3c24xx_init_clocks() call
 */
 
 #define IODESC_ENT(x) { S3C2410_VA_##x, S3C2410_PA_##x, S3C2410_SZ_##x, MT_DEVICE }
@@ -22,24 +25,19 @@
 
 #define print_mhz(m) ((m) / MHZ), ((m / 1000) % 1000)
 
-#ifdef CONFIG_CPU_S3C2410
-extern  int s3c2410_init(void);
-extern void s3c2410_map_io(struct map_desc *mach_desc, int size);
-#else
-#define s3c2410_map_io NULL
-#define s3c2410_init NULL
-#endif
+/* forward declaration */
+struct s3c2410_uartcfg;
 
-#ifdef CONFIG_CPU_S3C2440
-extern  int s3c2440_init(void);
-extern void s3c2440_map_io(struct map_desc *mach_desc, int size);
-#else
-#define s3c2440_map_io NULL
-#define s3c2440_init NULL
-#endif
+/* core initialisation functions */
+
+extern void s3c24xx_init_irq(void);
 
 extern void s3c24xx_init_io(struct map_desc *mach_desc, int size);
 
+extern void s3c24xx_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+
+extern void s3c24xx_init_clocks(int xtal);
+
 /* the board structure is used at first initialsation time
  * to get info such as the devices to register for this
  * board. This is done because platfrom_add_devices() cannot
@@ -56,4 +54,7 @@
 
 extern void s3c24xx_set_board(struct s3c24xx_board *board);
 
+/* timer for 2410/2440 */
 
+struct sys_timer;
+extern struct sys_timer s3c24xx_timer;
diff -Nru a/arch/arm/mach-s3c2410/dma.c b/arch/arm/mach-s3c2410/dma.c
--- a/arch/arm/mach-s3c2410/dma.c	2005-03-01 23:38:53 -08:00
+++ b/arch/arm/mach-s3c2410/dma.c	2005-03-01 23:38:53 -08:00
@@ -1063,6 +1063,29 @@
 
 EXPORT_SYMBOL(s3c2410_dma_devconfig);
 
+/* s3c2410_dma_getposition
+ *
+ * returns the current transfer points for the dma source and destination
+*/
+
+int s3c2410_dma_getposition(dmach_t channel, dma_addr_t *src, dma_addr_t *dst)
+{
+ 	s3c2410_dma_chan_t *chan = &s3c2410_chans[channel];
+
+ 	check_channel(channel);
+
+	if (src != NULL)
+ 		*src = dma_rdreg(chan, S3C2410_DMA_DCSRC);
+
+ 	if (dst != NULL)
+ 		*dst = dma_rdreg(chan, S3C2410_DMA_DCDST);
+
+ 	return 0;
+}
+
+EXPORT_SYMBOL(s3c2410_dma_getposition);
+
+
 /* system device class */
 
 #ifdef CONFIG_PM
diff -Nru a/arch/arm/mach-s3c2410/irq.c b/arch/arm/mach-s3c2410/irq.c
--- a/arch/arm/mach-s3c2410/irq.c	2005-03-01 23:38:55 -08:00
+++ b/arch/arm/mach-s3c2410/irq.c	2005-03-01 23:38:55 -08:00
@@ -628,12 +628,12 @@
 	s3c_irq_demux_uart(IRQ_S3CUART_RX2, regs);
 }
 
-/* s3c2410_init_irq
+/* s3c24xx_init_irq
  *
  * Initialise S3C2410 IRQ system
 */
 
-void __init s3c2410_init_irq(void)
+void __init s3c24xx_init_irq(void)
 {
 	unsigned long pend;
 	unsigned long last;
diff -Nru a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c
--- a/arch/arm/mach-s3c2410/mach-bast.c	2005-03-01 23:38:58 -08:00
+++ b/arch/arm/mach-s3c2410/mach-bast.c	2005-03-01 23:38:58 -08:00
@@ -1,6 +1,6 @@
 /* linux/arch/arm/mach-s3c2410/mach-bast.c
  *
- * Copyright (c) 2003,2004 Simtec Electronics
+ * Copyright (c) 2003-2005 Simtec Electronics
  *   Ben Dooks <ben@simtec.co.uk>
  *
  * http://www.simtec.co.uk/products/EB2410ITX/
@@ -20,6 +20,9 @@
  *     18-Jan-2003 BJD  Added serial port configuration
  *     05-Oct-2004 BJD  Power management code
  *     04-Nov-2004 BJD  Updated serial port clocks
+ *     04-Jan-2005 BJD  New uart init call
+ *     10-Jan-2005 BJD  Removed include of s3c2410.h
+ *     14-Jan-2005 BJD  Add support for muitlple NAND devices
 */
 
 #include <linux/kernel.h>
@@ -46,15 +49,20 @@
 #include <asm/arch/regs-serial.h>
 #include <asm/arch/regs-gpio.h>
 #include <asm/arch/regs-mem.h>
+#include <asm/arch/nand.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
 
-#include "s3c2410.h"
 #include "clock.h"
 #include "devs.h"
 #include "cpu.h"
 #include "usb-simtec.h"
 #include "pm.h"
 
-#define COPYRIGHT ", (c) 2004 Simtec Electronics"
+#define COPYRIGHT ", (c) 2004-2005 Simtec Electronics"
 
 /* macros for virtual address mods for the io space entries */
 #define VA_C5(item) ((item) + BAST_VAM_CS5)
@@ -219,6 +227,100 @@
 	.resource	= bast_nor_resource,
 };
 
+/* NAND Flash on BAST board */
+
+
+static int smartmedia_map[] = { 0 };
+static int chip0_map[] = { 1 };
+static int chip1_map[] = { 2 };
+static int chip2_map[] = { 3 };
+
+struct mtd_partition bast_default_nand_part[] = {
+	[0] = {
+		.name	= "Boot Agent",
+		.size	= SZ_16K,
+		.offset	= 0
+	},
+	[1] = {
+		.name	= "/boot",
+		.size	= SZ_4M - SZ_16K,
+		.offset	= SZ_16K,
+	},
+	[2] = {
+		.name	= "user",
+		.offset	= SZ_4M,
+		.size	= MTDPART_SIZ_FULL,
+	}
+};
+
+/* the bast has 4 selectable slots for nand-flash, the three
+ * on-board chip areas, as well as the external SmartMedia
+ * slot.
+ *
+ * Note, there is no current hot-plug support for the SmartMedia
+ * socket.
+*/
+
+static struct s3c2410_nand_set bast_nand_sets[] = {
+	[0] = {
+		.name		= "SmartMedia",
+		.nr_chips	= 1,
+		.nr_map		= smartmedia_map,
+		.nr_partitions	= ARRAY_SIZE(bast_default_nand_part),
+		.partitions	= bast_default_nand_part
+	},
+	[1] = {
+		.name		= "chip0",
+		.nr_chips	= 1,
+		.nr_map		= chip0_map,
+		.nr_partitions	= ARRAY_SIZE(bast_default_nand_part),
+		.partitions	= bast_default_nand_part
+	},
+	[2] = {
+		.name		= "chip1",
+		.nr_chips	= 1,
+		.nr_map		= chip1_map,
+		.nr_partitions	= ARRAY_SIZE(bast_default_nand_part),
+		.partitions	= bast_default_nand_part
+	},
+	[3] = {
+		.name		= "chip2",
+		.nr_chips	= 1,
+		.nr_map		= chip2_map,
+		.nr_partitions	= ARRAY_SIZE(bast_default_nand_part),
+		.partitions	= bast_default_nand_part
+	}
+};
+
+static void bast_nand_select(struct s3c2410_nand_set *set, int slot)
+{
+	unsigned int tmp;
+
+	slot = set->nr_map[slot] & 3;
+
+	pr_debug("bast_nand: selecting slot %d (set %p,%p)\n",
+		 slot, set, set->nr_map);
+
+	tmp = __raw_readb(BAST_VA_CTRL2);
+	tmp &= BAST_CPLD_CTLR2_IDERST;
+	tmp |= slot;
+	tmp |= BAST_CPLD_CTRL2_WNAND;
+
+	pr_debug("bast_nand: ctrl2 now %02x\n", tmp);
+
+	__raw_writeb(tmp, BAST_VA_CTRL2);
+}
+
+static struct s3c2410_platform_nand bast_nand_info = {
+	.tacls		= 80,
+	.twrph0		= 80,
+	.twrph1		= 80,
+	.nr_sets	= ARRAY_SIZE(bast_nand_sets),
+	.sets		= bast_nand_sets,
+	.select_chip	= bast_nand_select,
+};
+
+
 /* Standard BAST devices */
 
 static struct platform_device *bast_devices[] __initdata = {
@@ -228,6 +330,7 @@
 	&s3c_device_i2c,
 	&s3c_device_iis,
  	&s3c_device_rtc,
+	&s3c_device_nand,
 	&bast_device_nor
 };
 
@@ -261,15 +364,18 @@
 
 	s3c24xx_uclk.parent  = &s3c24xx_clkout1;
 
+	s3c_device_nand.dev.platform_data = &bast_nand_info;
+
 	s3c24xx_init_io(bast_iodesc, ARRAY_SIZE(bast_iodesc));
-	s3c2410_init_uarts(bast_uartcfgs, ARRAY_SIZE(bast_uartcfgs));
+	s3c24xx_init_clocks(0);
+	s3c24xx_init_uarts(bast_uartcfgs, ARRAY_SIZE(bast_uartcfgs));
 	s3c24xx_set_board(&bast_board);
 	usb_simtec_init();
 }
 
 void __init bast_init_irq(void)
 {
-	s3c2410_init_irq();
+	s3c24xx_init_irq();
 }
 
 #ifdef CONFIG_PM
@@ -306,5 +412,5 @@
      MAPIO(bast_map_io)
      INITIRQ(bast_init_irq)
 	.init_machine	= bast_init_machine,
-     .timer		= &s3c2410_timer,
+	.timer		= &s3c24xx_timer,
 MACHINE_END
diff -Nru a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c
--- a/arch/arm/mach-s3c2410/mach-h1940.c	2005-03-01 23:39:08 -08:00
+++ b/arch/arm/mach-s3c2410/mach-h1940.c	2005-03-01 23:39:08 -08:00
@@ -1,6 +1,6 @@
 /* linux/arch/arm/mach-s3c2410/mach-h1940.c
  *
- * Copyright (c) 2003,2004 Simtec Electronics
+ * Copyright (c) 2003-2005 Simtec Electronics
  *   Ben Dooks <ben@simtec.co.uk>
  *
  * http://www.handhelds.org/projects/h1940.html
@@ -20,6 +20,9 @@
  *     04-Sep-2004 BJD  Changed uart init, renamed ipaq_ -> h1940_
  *     18-Oct-2004 BJD  Updated new board structure name
  *     04-Nov-2004 BJD  Change for new serial clock
+ *     04-Jan-2005 BJD  Updated uart init call
+ *     10-Jan-2005 BJD  Removed include of s3c2410.h
+ *     14-Jan-2005 BJD  Added clock init
 */
 
 #include <linux/kernel.h>
@@ -44,7 +47,6 @@
 
 #include <linux/serial_core.h>
 
-#include "s3c2410.h"
 #include "clock.h"
 #include "devs.h"
 #include "cpu.h"
@@ -102,13 +104,14 @@
 void __init h1940_map_io(void)
 {
 	s3c24xx_init_io(h1940_iodesc, ARRAY_SIZE(h1940_iodesc));
-	s3c2410_init_uarts(h1940_uartcfgs, ARRAY_SIZE(h1940_uartcfgs));
+	s3c24xx_init_clocks(0);
+	s3c24xx_init_uarts(h1940_uartcfgs, ARRAY_SIZE(h1940_uartcfgs));
 	s3c24xx_set_board(&h1940_board);
 }
 
 void __init h1940_init_irq(void)
 {
-	s3c2410_init_irq();
+	s3c24xx_init_irq();
 
 }
 
@@ -118,5 +121,5 @@
      BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100)
      MAPIO(h1940_map_io)
      INITIRQ(h1940_init_irq)
-     .timer		= &s3c2410_timer,
+	.timer		= &s3c24xx_timer,
 MACHINE_END
diff -Nru a/arch/arm/mach-s3c2410/mach-rx3715.c b/arch/arm/mach-s3c2410/mach-rx3715.c
--- a/arch/arm/mach-s3c2410/mach-rx3715.c	2005-03-01 23:39:08 -08:00
+++ b/arch/arm/mach-s3c2410/mach-rx3715.c	2005-03-01 23:39:08 -08:00
@@ -12,6 +12,8 @@
  * Modifications:
  *	16-Sep-2004 BJD Copied from mach-h1940.c
  *	25-Oct-2004 BJD Updates for 2.6.10-rc1
+ *	10-Jan-2005 BJD Removed include of s3c2410.h s3c2440.h
+ *	14-Jan-2005 BJD Added new clock init
 */
 
 #include <linux/kernel.h>
@@ -38,8 +40,6 @@
 #include <asm/arch/regs-serial.h>
 #include <asm/arch/regs-gpio.h>
 
-#include "s3c2410.h"
-#include "s3c2440.h"
 #include "clock.h"
 #include "devs.h"
 #include "cpu.h"
@@ -92,16 +92,15 @@
 
 void __init rx3715_map_io(void)
 {
-	s3c24xx_xtal = 16934000;
-
 	s3c24xx_init_io(rx3715_iodesc, ARRAY_SIZE(rx3715_iodesc));
-	s3c2440_init_uarts(rx3715_uartcfgs, ARRAY_SIZE(rx3715_uartcfgs));
+	s3c24xx_init_clocks(16934000);
+	s3c24xx_init_uarts(rx3715_uartcfgs, ARRAY_SIZE(rx3715_uartcfgs));
 	s3c24xx_set_board(&rx3715_board);
 }
 
 void __init rx3715_init_irq(void)
 {
-	s3c2410_init_irq();
+	s3c24xx_init_irq();
 }
 
 #ifdef CONFIG_PM
@@ -120,5 +119,5 @@
      MAPIO(rx3715_map_io)
      INITIRQ(rx3715_init_irq)
      INIT_MACHINE(rx3715_init_machine)
-     .timer		= &s3c2410_timer,
+	.timer		= &s3c24xx_timer,
 MACHINE_END
diff -Nru a/arch/arm/mach-s3c2410/mach-smdk2410.c b/arch/arm/mach-s3c2410/mach-smdk2410.c
--- a/arch/arm/mach-s3c2410/mach-smdk2410.c	2005-03-01 23:39:18 -08:00
+++ b/arch/arm/mach-s3c2410/mach-smdk2410.c	2005-03-01 23:39:18 -08:00
@@ -46,7 +46,6 @@
 
 #include <asm/arch/regs-serial.h>
 
-#include "s3c2410.h"
 #include "devs.h"
 #include "cpu.h"
 
@@ -98,13 +97,14 @@
 void __init smdk2410_map_io(void)
 {
 	s3c24xx_init_io(smdk2410_iodesc, ARRAY_SIZE(smdk2410_iodesc));
-	s3c2410_init_uarts(smdk2410_uartcfgs, ARRAY_SIZE(smdk2410_uartcfgs));
+	s3c24xx_init_clocks(0);
+	s3c24xx_init_uarts(smdk2410_uartcfgs, ARRAY_SIZE(smdk2410_uartcfgs));
 	s3c24xx_set_board(&smdk2410_board);
 }
 
 void __init smdk2410_init_irq(void)
 {
-	s3c2410_init_irq();
+	s3c24xx_init_irq();
 }
 
 MACHINE_START(SMDK2410, "SMDK2410") /* @TODO: request a new identifier and switch
@@ -114,7 +114,7 @@
      BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100)
      MAPIO(smdk2410_map_io)
      INITIRQ(smdk2410_init_irq)
-     .timer		= &s3c2410_timer,
+	.timer		= &s3c24xx_timer,
 MACHINE_END
 
 
diff -Nru a/arch/arm/mach-s3c2410/mach-vr1000.c b/arch/arm/mach-s3c2410/mach-vr1000.c
--- a/arch/arm/mach-s3c2410/mach-vr1000.c	2005-03-01 23:39:09 -08:00
+++ b/arch/arm/mach-s3c2410/mach-vr1000.c	2005-03-01 23:39:09 -08:00
@@ -1,6 +1,6 @@
 /* linux/arch/arm/mach-s3c2410/mach-vr1000.c
  *
- * Copyright (c) 2003,2004 Simtec Electronics
+ * Copyright (c) 2003-2005 Simtec Electronics
  *   Ben Dooks <ben@simtec.co.uk>
  *
  * Machine support for Thorcom VR1000 board. Designed for Thorcom by
@@ -18,6 +18,12 @@
  *     05-Apr-2004 BJD  Copied to make mach-vr1000.c
  *     18-Oct-2004 BJD  Updated board struct
  *     04-Nov-2004 BJD  Clock and serial configuration update
+ *
+ *     04-Jan-2005 BJD  Updated uart init call
+ *     10-Jan-2005 BJD  Removed include of s3c2410.h
+ *     14-Jan-2005 BJD  Added clock init
+ *     15-Jan-2005 BJD  Add serial port device definition
+ *     20-Jan-2005 BJD  Use UPF_IOREMAP for ports
 */
 
 #include <linux/kernel.h>
@@ -27,12 +33,19 @@
 #include <linux/timer.h>
 #include <linux/init.h>
 
+#include <linux/serial.h>
+#include <linux/tty.h>
+#include <linux/serial_8250.h>
+#include <linux/serial_reg.h>
+
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 
 #include <asm/arch/bast-map.h>
 #include <asm/arch/vr1000-map.h>
+#include <asm/arch/vr1000-irq.h>
+#include <asm/arch/vr1000-cpld.h>
 
 #include <asm/hardware.h>
 #include <asm/io.h>
@@ -42,7 +55,6 @@
 //#include <asm/debug-ll.h>
 #include <asm/arch/regs-serial.h>
 
-#include "s3c2410.h"
 #include "clock.h"
 #include "devs.h"
 #include "cpu.h"
@@ -164,12 +176,82 @@
 	}
 };
 
+/* definitions for the vr1000 extra 16550 serial ports */
+
+#define VR1000_BAUDBASE (3692307)
+
+#define VR1000_SERIAL_MAPBASE(x) (VR1000_PA_SERIAL + 0x80 + ((x) << 5))
+
+static struct plat_serial8250_port serial_platform_data[] = {
+	[0] = {
+		.mapbase	= VR1000_SERIAL_MAPBASE(0),
+		.irq		= IRQ_VR1000_SERIAL + 0,
+		.flags		= UPF_BOOT_AUTOCONF | UPF_IOREMAP,
+		.iotype		= UPIO_MEM,
+		.regshift	= 0,
+		.uartclk	= VR1000_BAUDBASE,
+	},
+	[1] = {
+		.mapbase	= VR1000_SERIAL_MAPBASE(1),
+		.irq		= IRQ_VR1000_SERIAL + 1,
+		.flags		= UPF_BOOT_AUTOCONF | UPF_IOREMAP,
+		.iotype		= UPIO_MEM,
+		.regshift	= 0,
+		.uartclk	= VR1000_BAUDBASE,
+	},
+	[2] = {
+		.mapbase	= VR1000_SERIAL_MAPBASE(2),
+		.irq		= IRQ_VR1000_SERIAL + 2,
+		.flags		= UPF_BOOT_AUTOCONF | UPF_IOREMAP,
+		.iotype		= UPIO_MEM,
+		.regshift	= 0,
+		.uartclk	= VR1000_BAUDBASE,
+	},
+	[3] = {
+		.mapbase	= VR1000_SERIAL_MAPBASE(3),
+		.irq		= IRQ_VR1000_SERIAL + 3,
+		.flags		= UPF_BOOT_AUTOCONF | UPF_IOREMAP,
+		.iotype		= UPIO_MEM,
+		.regshift	= 0,
+		.uartclk	= VR1000_BAUDBASE,
+	},
+	{ },
+};
+
+static struct platform_device serial_device = {
+	.name			= "serial8250",
+	.id			= 0,
+	.dev			= {
+		.platform_data	= serial_platform_data,
+	},
+};
+
+/* MTD NOR Flash */
+
+static struct resource vr1000_nor_resource[] = {
+	[0] = {
+		.start	= S3C2410_CS1 + 0x4000000,
+		.end	= S3C2410_CS1 + 0x4000000 + SZ_16M - 1,
+		.flags	= IORESOURCE_MEM,
+	}
+};
+
+static struct platform_device vr1000_nor = {
+	.name		= "bast-nor",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(vr1000_nor_resource),
+	.resource	= vr1000_nor_resource,
+};
+
+
 static struct platform_device *vr1000_devices[] __initdata = {
 	&s3c_device_usb,
 	&s3c_device_lcd,
 	&s3c_device_wdt,
 	&s3c_device_i2c,
 	&s3c_device_iis,
+	&serial_device,
+	&vr1000_nor,
 };
 
 static struct clk *vr1000_clocks[] = {
@@ -204,14 +286,15 @@
 	s3c24xx_uclk.parent  = &s3c24xx_clkout1;
 
 	s3c24xx_init_io(vr1000_iodesc, ARRAY_SIZE(vr1000_iodesc));
-	s3c2410_init_uarts(vr1000_uartcfgs, ARRAY_SIZE(vr1000_uartcfgs));
+	s3c24xx_init_clocks(0);
+	s3c24xx_init_uarts(vr1000_uartcfgs, ARRAY_SIZE(vr1000_uartcfgs));
 	s3c24xx_set_board(&vr1000_board);
 	usb_simtec_init();
 }
 
 void __init vr1000_init_irq(void)
 {
-	s3c2410_init_irq();
+	s3c24xx_init_irq();
 }
 
 MACHINE_START(VR1000, "Thorcom-VR1000")
@@ -220,5 +303,5 @@
      BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100)
      MAPIO(vr1000_map_io)
      INITIRQ(vr1000_init_irq)
-     .timer		= &s3c2410_timer,
+	.timer		= &s3c24xx_timer,
 MACHINE_END
diff -Nru a/arch/arm/mach-s3c2410/s3c2410.c b/arch/arm/mach-s3c2410/s3c2410.c
--- a/arch/arm/mach-s3c2410/s3c2410.c	2005-03-01 23:38:57 -08:00
+++ b/arch/arm/mach-s3c2410/s3c2410.c	2005-03-01 23:38:57 -08:00
@@ -1,6 +1,6 @@
 /* linux/arch/arm/mach-s3c2410/s3c2410.c
  *
- * Copyright (c) 2003,2004 Simtec Electronics
+ * Copyright (c) 2003-2005 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
  *
  * http://www.simtec.co.uk/products/EB2410ITX/
@@ -17,6 +17,7 @@
  *     21-Aug-2004 BJD  Added new struct s3c2410_board handler
  *     28-Sep-2004 BJD  Updates for new serial port bits
  *     04-Nov-2004 BJD  Updated UART configuration process
+ *     10-Jan-2004 BJD  Removed s3c2410_clock_tick_rate
 */
 
 #include <linux/kernel.h>
@@ -42,8 +43,6 @@
 #include "cpu.h"
 #include "clock.h"
 
-int s3c2410_clock_tick_rate = 12*1000*1000;  /* current timers at 12MHz */
-
 /* Initial IO mappings */
 
 static struct map_desc s3c2410_iodesc[] __initdata = {
@@ -152,19 +151,19 @@
  *
  * register the standard cpu IO areas, and any passed in from the
  * machine specific initialisation.
- *
- * this function also sets the initial clock frequencies from the
- * settings passed in
 */
 
 void __init s3c2410_map_io(struct map_desc *mach_desc, int mach_size)
 {
-	unsigned long tmp;
-
 	/* register our io-tables */
 
 	iotable_init(s3c2410_iodesc, ARRAY_SIZE(s3c2410_iodesc));
 	iotable_init(mach_desc, mach_size);
+}
+
+void __init s3c2410_init_clocks(int xtal)
+{
+	unsigned long tmp;
 
 	/* now we've got our machine bits initialised, work out what
 	 * clocks we've got */
@@ -189,7 +188,7 @@
 	 * console to use them
 	 */
 
-	s3c2410_init_clocks();
+	s3c24xx_setup_clocks();
 }
 
 int __init s3c2410_init(void)
diff -Nru a/arch/arm/mach-s3c2410/s3c2410.h b/arch/arm/mach-s3c2410/s3c2410.h
--- a/arch/arm/mach-s3c2410/s3c2410.h	2005-03-01 23:38:56 -08:00
+++ b/arch/arm/mach-s3c2410/s3c2410.h	2005-03-01 23:38:56 -08:00
@@ -1,7 +1,7 @@
 /* arch/arm/mach-s3c2410/s3c2410.h
  *
  * Copyright (c) 2004 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
+ *	Ben Dooks <ben@simtec.co.uk>
  *
  * Header file for s3c2410 machine directory
  *
@@ -14,17 +14,24 @@
  *     20-Aug-2004 BJD  Added s3c2410_board struct
  *     04-Sep-2004 BJD  Added s3c2410_init_uarts() call
  *     17-Oct-2004 BJD  Moved board out to cpu
+ *     04-Jan-2005 BJD  Changed uart init
+ *     10-Jan-2005 BJD  Removed timer to cpu.h, moved 2410 specific bits here
+ *     14-Jan-2005 BJD  Added s3c2410_init_clocks call
 */
 
-struct s3c2410_uartcfg;
+#ifdef CONFIG_CPU_S3C2410
 
-extern void s3c2410_map_io(struct map_desc *, int count);
+extern  int s3c2410_init(void);
 
-extern void s3c2410_init_uarts(struct s3c2410_uartcfg *, int no);
+extern void s3c2410_map_io(struct map_desc *mach_desc, int size);
 
-extern void s3c2410_init_irq(void);
+extern void s3c2410_init_uarts(struct s3c2410_uartcfg *cfg, int no);
 
-struct sys_timer;
-extern struct sys_timer s3c2410_timer;
+extern void s3c2410_init_clocks(int xtal);
 
-extern void s3c2410_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+#else
+#define s3c2410_init_clocks NULL
+#define s3c2410_init_uarts NULL
+#define s3c2410_map_io NULL
+#define s3c2410_init NULL
+#endif
diff -Nru a/arch/arm/mach-s3c2410/s3c2440-dsc.c b/arch/arm/mach-s3c2410/s3c2440-dsc.c
--- a/arch/arm/mach-s3c2410/s3c2440-dsc.c	2005-03-01 23:39:09 -08:00
+++ b/arch/arm/mach-s3c2410/s3c2440-dsc.c	2005-03-01 23:39:09 -08:00
@@ -1,6 +1,6 @@
 /* linux/arch/arm/mach-s3c2410/s3c2440-dsc.c
  *
- * Copyright (c) 2004 Simtec Electronics
+ * Copyright (c) 2004-2005 Simtec Electronics
  *   Ben Dooks <ben@simtec.co.uk>
  *
  * Samsung S3C2440 Drive Strength Control support
@@ -12,6 +12,7 @@
  * Modifications:
  *     29-Aug-2004 BJD  Start of drive-strength control
  *     09-Nov-2004 BJD  Added symbol export
+ *     11-Jan-2005 BJD  Include fix
 */
 
 #include <linux/kernel.h>
@@ -31,8 +32,8 @@
 #include <asm/arch/regs-gpio.h>
 #include <asm/arch/regs-dsc.h>
 
-#include "s3c2440.h"
 #include "cpu.h"
+#include "s3c2440.h"
 
 int s3c2440_set_dsc(unsigned int pin, unsigned int value)
 {
diff -Nru a/arch/arm/mach-s3c2410/s3c2440.c b/arch/arm/mach-s3c2410/s3c2440.c
--- a/arch/arm/mach-s3c2410/s3c2440.c	2005-03-01 23:38:44 -08:00
+++ b/arch/arm/mach-s3c2410/s3c2440.c	2005-03-01 23:38:44 -08:00
@@ -1,6 +1,6 @@
 /* linux/arch/arm/mach-s3c2410/s3c2440.c
  *
- * Copyright (c) 2004 Simtec Electronics
+ * Copyright (c) 2004-2005 Simtec Electronics
  *   Ben Dooks <ben@simtec.co.uk>
  *
  * Samsung S3C2440 Mobile CPU support
@@ -16,6 +16,8 @@
  *	09-Nov-2004 BJD  Added sysdev for power management
  *	04-Nov-2004 BJD  New serial registration
  *	15-Nov-2004 BJD  Rename the i2c device for the s3c2440
+ *	14-Jan-2005 BJD  Moved clock init code into seperate function
+ *	14-Jan-2005 BJD  Removed un-used clock bits
 */
 
 #include <linux/kernel.h>
@@ -48,10 +50,6 @@
 #include "cpu.h"
 #include "pm.h"
 
-int s3c2440_clock_tick_rate = 12*1000*1000;  /* current timers at 12MHz */
-
-/* clock info */
-unsigned long s3c2440_hdiv;
 
 static struct map_desc s3c2440_iodesc[] __initdata = {
 	IODESC_ENT(USBHOST),
@@ -59,6 +57,7 @@
 	IODESC_ENT(LCD),
 	IODESC_ENT(TIMER),
 	IODESC_ENT(ADC),
+	IODESC_ENT(WATCHDOG),
 };
 
 static struct resource s3c_uart0_resource[] = {
@@ -154,13 +153,13 @@
 
 static struct clk s3c2440_clk_cam = {
 	.name		= "camera",
-	.enable		= s3c2410_clkcon_enable,
+	.enable		= s3c24xx_clkcon_enable,
 	.ctrlbit	= S3C2440_CLKCON_CAMERA
 };
 
 static struct clk s3c2440_clk_ac97 = {
 	.name		= "ac97",
-	.enable		= s3c2410_clkcon_enable,
+	.enable		= s3c24xx_clkcon_enable,
 	.ctrlbit	= S3C2440_CLKCON_CAMERA
 };
 
@@ -203,13 +202,20 @@
 
 void __init s3c2440_map_io(struct map_desc *mach_desc, int size)
 {
-	unsigned long clkdiv;
-	unsigned long camdiv;
-
 	/* register our io-tables */
 
 	iotable_init(s3c2440_iodesc, ARRAY_SIZE(s3c2440_iodesc));
 	iotable_init(mach_desc, size);
+	/* rename any peripherals used differing from the s3c2410 */
+
+	s3c_device_i2c.name = "s3c2440-i2c";
+}
+
+void __init s3c2440_init_clocks(int xtal)
+{
+	unsigned long clkdiv;
+	unsigned long camdiv;
+	int s3c2440_hdiv = 1;
 
 	/* now we've got our machine bits initialised, work out what
 	 * clocks we've got */
@@ -243,7 +249,7 @@
 	s3c24xx_hclk = s3c24xx_fclk / s3c2440_hdiv;
 	s3c24xx_pclk = s3c24xx_hclk / ((clkdiv & S3C2440_CLKDIVN_PDIVN)? 2:1);
 
-	/* print brieft summary of clocks, etc */
+	/* print brief summary of clocks, etc */
 
 	printk("S3C2440: core %ld.%03ld MHz, memory %ld.%03ld MHz, peripheral %ld.%03ld MHz\n",
 	       print_mhz(s3c24xx_fclk), print_mhz(s3c24xx_hclk),
@@ -253,22 +259,18 @@
 	 * console to use them, and to add new ones after the initialisation
 	 */
 
-	s3c2410_init_clocks();
+	s3c24xx_setup_clocks();
 
 	/* add s3c2440 specific clocks */
 
 	s3c2440_clk_cam.parent = clk_get(NULL, "hclk");
 	s3c2440_clk_ac97.parent = clk_get(NULL, "pclk");
 
-	s3c2410_register_clock(&s3c2440_clk_ac97);
-	s3c2410_register_clock(&s3c2440_clk_cam);
+	s3c24xx_register_clock(&s3c2440_clk_ac97);
+	s3c24xx_register_clock(&s3c2440_clk_cam);
 
 	clk_disable(&s3c2440_clk_ac97);
 	clk_disable(&s3c2440_clk_cam);
-
-	/* rename any peripherals used differing from the s3c2410 */
-
-	s3c_device_i2c.name = "s3c2440-i2c";
 }
 
 int __init s3c2440_init(void)
diff -Nru a/arch/arm/mach-s3c2410/s3c2440.h b/arch/arm/mach-s3c2410/s3c2440.h
--- a/arch/arm/mach-s3c2410/s3c2440.h	2005-03-01 23:39:07 -08:00
+++ b/arch/arm/mach-s3c2410/s3c2440.h	2005-03-01 23:39:07 -08:00
@@ -1,7 +1,7 @@
 /* arch/arm/mach-s3c2410/s3c2440.h
  *
- * Copyright (c) 2004 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
+ * Copyright (c) 2004-2005 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
  *
  * Header file for s3c2440 cpu support
  *
@@ -12,12 +12,24 @@
  * Modifications:
  *	24-Aug-2004 BJD  Start of S3C2440 CPU support
  *	04-Nov-2004 BJD  Added s3c2440_init_uarts()
+ *	04-Jan-2005 BJD  Moved uart init to cpu code
+ *	10-Jan-2005 BJD  Moved 2440 specific init here
+ *	14-Jan-2005 BJD  Split the clock initialisation code
 */
 
-struct s3c2410_uartcfg;
+#ifdef CONFIG_CPU_S3C2440
 
-extern void s3c2440_init_irq(void);
+extern  int s3c2440_init(void);
 
-extern void s3c2440_init_time(void);
+extern void s3c2440_map_io(struct map_desc *mach_desc, int size);
 
 extern void s3c2440_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+
+extern void s3c2440_init_clocks(int xtal);
+
+#else
+#define s3c2440_init_clocks NULL
+#define s3c2440_init_uarts NULL
+#define s3c2440_map_io NULL
+#define s3c2440_init NULL
+#endif
diff -Nru a/arch/arm/mach-s3c2410/time.c b/arch/arm/mach-s3c2410/time.c
--- a/arch/arm/mach-s3c2410/time.c	2005-03-01 23:38:55 -08:00
+++ b/arch/arm/mach-s3c2410/time.c	2005-03-01 23:38:55 -08:00
@@ -232,7 +232,7 @@
 	setup_irq(IRQ_TIMER4, &s3c2410_timer_irq);
 }
 
-struct sys_timer s3c2410_timer = {
+struct sys_timer s3c24xx_timer = {
 	.init		= s3c2410_timer_init,
 	.offset		= s3c2410_gettimeoffset,
 	.resume		= s3c2410_timer_setup
diff -Nru a/arch/arm/mach-sa1100/badge4.c b/arch/arm/mach-sa1100/badge4.c
--- a/arch/arm/mach-sa1100/badge4.c	2005-03-01 23:38:52 -08:00
+++ b/arch/arm/mach-sa1100/badge4.c	2005-03-01 23:38:52 -08:00
@@ -57,7 +57,7 @@
 	.name		= "sa1111",
 	.id		= 0,
 	.dev		= {
-		.dma_mask = &sa1111_dmamask;
+		.dma_mask = &sa1111_dmamask,
 		.coherent_dma_mask = 0xffffffff,
 	},
 	.num_resources	= ARRAY_SIZE(sa1111_resources),
@@ -212,8 +212,7 @@
 	/* maybe turn on 5v0 from the start */
 	badge4_set_5V(BADGE4_5V_INITIALLY, five_v_on);
 
-	sa11x0_set_flash_data(badge4_flash_data, badge4_flash_resources,
-			      ARRAY_SIZE(badge4_flash_resources);
+	sa11x0_set_flash_data(&badge4_flash_data, &badge4_flash_resource, 1);
 
 	return 0;
 }
diff -Nru a/arch/arm/mach-sa1100/collie.c b/arch/arm/mach-sa1100/collie.c
--- a/arch/arm/mach-sa1100/collie.c	2005-03-01 23:38:56 -08:00
+++ b/arch/arm/mach-sa1100/collie.c	2005-03-01 23:38:56 -08:00
@@ -37,36 +37,34 @@
 #include <asm/mach/map.h>
 #include <asm/mach/serial_sa1100.h>
 
+#include <asm/hardware/scoop.h>
 #include <asm/hardware/locomo.h>
 
 #include "generic.h"
 
-static void __init scoop_init(void)
-{
+static struct resource collie_scoop_resources[] = {
+	[0] = {
+		.start		= 0x40800000,
+		.end		= 0x40800fff,
+		.flags		= IORESOURCE_MEM,
+	},
+};
 
-#define	COLLIE_SCP_INIT_DATA(adr,dat)	(((adr)<<16)|(dat))
-#define	COLLIE_SCP_INIT_DATA_END	((unsigned long)-1)
-	static const unsigned long scp_init[] = {
-		COLLIE_SCP_INIT_DATA(COLLIE_SCP_MCR, 0x0140),	// 00
-		COLLIE_SCP_INIT_DATA(COLLIE_SCP_MCR, 0x0100),
-		COLLIE_SCP_INIT_DATA(COLLIE_SCP_CDR, 0x0000),	// 04
-		COLLIE_SCP_INIT_DATA(COLLIE_SCP_CPR, 0x0000),	// 0C
-		COLLIE_SCP_INIT_DATA(COLLIE_SCP_CCR, 0x0000),	// 10
-		COLLIE_SCP_INIT_DATA(COLLIE_SCP_IMR, 0x0000),	// 18
-		COLLIE_SCP_INIT_DATA(COLLIE_SCP_IRM, 0x00FF),	// 14
-		COLLIE_SCP_INIT_DATA(COLLIE_SCP_ISR, 0x0000),	// 1C
-		COLLIE_SCP_INIT_DATA(COLLIE_SCP_IRM, 0x0000),
-		COLLIE_SCP_INIT_DATA(COLLIE_SCP_GPCR, COLLIE_SCP_IO_DIR),	// 20
-		COLLIE_SCP_INIT_DATA(COLLIE_SCP_GPWR, COLLIE_SCP_IO_OUT),	// 24
-		COLLIE_SCP_INIT_DATA_END
-	};
-	int i;
-	for (i = 0; scp_init[i] != COLLIE_SCP_INIT_DATA_END; i++) {
-		int adr = scp_init[i] >> 16;
-		COLLIE_SCP_REG(adr) = scp_init[i] & 0xFFFF;
-	}
+static struct scoop_config collie_scoop_setup = {
+	.io_dir 	= COLLIE_SCOOP_IO_DIR,
+	.io_out		= COLLIE_SCOOP_IO_OUT,
+};
+
+static struct platform_device colliescoop_device = {
+	.name		= "sharp-scoop",
+	.id		= -1,
+	.dev		= {
+ 		.platform_data	= &collie_scoop_setup,
+	},
+	.num_resources	= ARRAY_SIZE(collie_scoop_resources),
+	.resource	= collie_scoop_resources,
+};
 
-}
 
 static struct resource locomo_resources[] = {
 	[0] = {
@@ -90,6 +88,7 @@
 
 static struct platform_device *devices[] __initdata = {
 	&locomo_device,
+	&colliescoop_device,
 };
 
 static struct mtd_partition collie_partitions[] = {
@@ -111,11 +110,11 @@
 
 static void collie_set_vpp(int vpp)
 {
-	COLLIE_SCP_REG_GPCR |= COLLIE_SCP_VPEN;
+	write_scoop_reg(SCOOP_GPCR, read_scoop_reg(SCOOP_GPCR) | COLLIE_SCP_VPEN);
 	if (vpp) {
-		COLLIE_SCP_REG_GPWR |= COLLIE_SCP_VPEN;
+		write_scoop_reg(SCOOP_GPWR, read_scoop_reg(SCOOP_GPWR) | COLLIE_SCP_VPEN);
 	} else {
-		COLLIE_SCP_REG_GPWR &= ~COLLIE_SCP_VPEN;
+		write_scoop_reg(SCOOP_GPWR, read_scoop_reg(SCOOP_GPWR) & ~COLLIE_SCP_VPEN);
 	}
 }
 
@@ -160,8 +159,6 @@
 	GPDR |= GPIO_32_768kHz;
 	TUCR  = TUCR_32_768kHz;
 
-	scoop_init();
-
 	ret = platform_add_devices(devices, ARRAY_SIZE(devices));
 	if (ret) {
 		printk(KERN_WARNING "collie: Unable to register LoCoMo device\n");
@@ -175,7 +172,6 @@
 	/* virtual     physical    length      type */
 	{0xe8000000, 0x00000000, 0x02000000, MT_DEVICE},	/* 32M main flash (cs0) */
 	{0xea000000, 0x08000000, 0x02000000, MT_DEVICE},	/* 32M boot flash (cs1) */
-	{0xf0000000, 0x40000000, 0x01000000, MT_DEVICE},	/* 16M LOCOMO  & SCOOP (cs4) */
 };
 
 static void __init collie_map_io(void)
diff -Nru a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c
--- a/arch/arm/mach-sa1100/neponset.c	2005-03-01 23:38:57 -08:00
+++ b/arch/arm/mach-sa1100/neponset.c	2005-03-01 23:38:57 -08:00
@@ -211,8 +211,8 @@
 }
 
 #else
-#define	neponset_suspend	NULL
-#define	neponset_resume	NULL
+#define neponset_suspend NULL
+#define neponset_resume  NULL
 #endif
 
 static struct device_driver neponset_device_driver = {
diff -Nru a/arch/arm/mach-sa1100/shannon.c b/arch/arm/mach-sa1100/shannon.c
--- a/arch/arm/mach-sa1100/shannon.c	2005-03-01 23:39:18 -08:00
+++ b/arch/arm/mach-sa1100/shannon.c	2005-03-01 23:39:18 -08:00
@@ -2,15 +2,17 @@
  * linux/arch/arm/mach-sa1100/shannon.c
  */
 
+#include <linux/config.h>
 #include <linux/init.h>
+#include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/tty.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 
 #include <asm/hardware.h>
+#include <asm/mach-types.h>
 #include <asm/setup.h>
-#include <asm/irq.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/flash.h>
@@ -52,7 +54,7 @@
 
 static void __init shannon_init(void)
 {
-	sa11x0_set_flash_data(&shannon_flash_data, shannon_flash_resource, 1);
+	sa11x0_set_flash_data(&shannon_flash_data, &shannon_flash_resource, 1);
 }
 
 static void __init shannon_map_io(void)
diff -Nru a/arch/arm/mach-shark/core.c b/arch/arm/mach-shark/core.c
--- a/arch/arm/mach-shark/core.c	2005-03-01 23:39:07 -08:00
+++ b/arch/arm/mach-shark/core.c	2005-03-01 23:39:07 -08:00
@@ -93,8 +93,6 @@
  */
 static void __init shark_timer_init(void)
 {
-        unsigned long flags;
-
 	outb(0x34, 0x43);               /* binary, mode 0, LSB/MSB, Ch 0 */
 	outb(HZ_TIME & 0xff, 0x40);     /* LSB of count */
 	outb(HZ_TIME >> 8, 0x40);
diff -Nru a/arch/arm/mach-shark/irq.c b/arch/arm/mach-shark/irq.c
--- a/arch/arm/mach-shark/irq.c	2005-03-01 23:39:08 -08:00
+++ b/arch/arm/mach-shark/irq.c	2005-03-01 23:39:08 -08:00
@@ -61,9 +61,10 @@
 
 static void shark_ack_8259A_irq(unsigned int irq){}
 
-static void bogus_int(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t bogus_int(int irq, void *dev_id, struct pt_regs *regs)
 {
 	printk("Got interrupt %i!\n",irq);
+	return IRQ_NONE;
 }
 
 static struct irqaction cascade;
@@ -102,11 +103,7 @@
 	//request_region(0xA0,0x2,"pic2");
 
 	cascade.handler = bogus_int;
-	cascade.flags = 0;
-	cascade.mask = 0;
 	cascade.name = "cascade";
-	cascade.next = NULL;
-	cascade.dev_id = NULL;
 	setup_irq(2,&cascade);
 }
 
diff -Nru a/arch/arm/mach-shark/leds.c b/arch/arm/mach-shark/leds.c
--- a/arch/arm/mach-shark/leds.c	2005-03-01 23:38:56 -08:00
+++ b/arch/arm/mach-shark/leds.c	2005-03-01 23:38:56 -08:00
@@ -33,7 +33,7 @@
 static short hw_led_state;
 static short saved_state;
 
-static spinlock_t leds_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(leds_lock);
 
 short sequoia_read(int addr) {
   outw(addr,0x24);
diff -Nru a/arch/arm/mach-shark/pci.c b/arch/arm/mach-shark/pci.c
--- a/arch/arm/mach-shark/pci.c	2005-03-01 23:38:55 -08:00
+++ b/arch/arm/mach-shark/pci.c	2005-03-01 23:38:55 -08:00
@@ -21,7 +21,7 @@
 	else return 255;
 }
 
-extern void __init via82c505_preinit(void *sysdata);
+extern void __init via82c505_preinit(void);
 
 static struct hw_pci shark_pci __initdata = {
 	.setup		= via82c505_setup,
@@ -29,7 +29,7 @@
 	.map_irq	= shark_map_irq,
 	.nr_controllers = 1,
 	.scan		= via82c505_scan_bus,
-	.preinit	= via82c505_preinit
+	.preinit	= via82c505_preinit,
 };
 
 static int __init shark_pci_init(void)
diff -Nru a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
--- a/arch/arm/mach-versatile/core.c	2005-03-01 23:38:56 -08:00
+++ b/arch/arm/mach-versatile/core.c	2005-03-01 23:38:56 -08:00
@@ -597,6 +597,14 @@
 	return 0;
 }
 
+static int versatile_clcd_mmap(struct clcd_fb *fb, struct vm_area_struct *vma)
+{
+	return dma_mmap_writecombine(&fb->dev->dev, vma,
+				     fb->fb.screen_base,
+				     fb->fb.fix.smem_start,
+				     fb->fb.fix.smem_len);
+}
+
 static void versatile_clcd_remove(struct clcd_fb *fb)
 {
 	dma_free_writecombine(&fb->dev->dev, fb->fb.fix.smem_len,
@@ -610,6 +618,7 @@
 	.disable	= versatile_clcd_disable,
 	.enable		= versatile_clcd_enable,
 	.setup		= versatile_clcd_setup,
+	.mmap		= versatile_clcd_mmap,
 	.remove		= versatile_clcd_remove,
 };
 
diff -Nru a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
--- a/arch/arm/mm/Kconfig	2005-03-01 23:39:18 -08:00
+++ b/arch/arm/mm/Kconfig	2005-03-01 23:39:18 -08:00
@@ -82,9 +82,9 @@
 
 # ARM922T
 config CPU_ARM922T
-	bool
-	depends on ARCH_CAMELOT || ARCH_LH7A40X
-	default y
+	bool "Support ARM922T processor" if ARCH_INTEGRATOR
+	depends on ARCH_CAMELOT || ARCH_LH7A40X || ARCH_INTEGRATOR
+	default y if ARCH_CAMELOT || ARCH_LH7A40X
 	select CPU_32v4
 	select CPU_ABRT_EV4T
 	select CPU_CACHE_V4WT
@@ -101,9 +101,9 @@
 
 # ARM925T
 config CPU_ARM925T
- 	bool
+ 	bool "Support ARM925T processor" if ARCH_OMAP
  	depends on ARCH_OMAP1510
- 	default y
+ 	default y if ARCH_OMAP1510
 	select CPU_32v4
 	select CPU_ABRT_EV4T
 	select CPU_CACHE_V4WT
@@ -121,8 +121,8 @@
 # ARM926T
 config CPU_ARM926T
 	bool "Support ARM926T processor" if ARCH_INTEGRATOR
-	depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP1610 || ARCH_OMAP5912
-	default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB
+	depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX
+	default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX
 	select CPU_32v5
 	select CPU_ABRT_EV5TJ
 	select CPU_CACHE_VIVT
@@ -392,8 +392,9 @@
 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
+	default y if CPU_ARM925T
 	help
-	  Say Y here to use the data cache in writethough mode. Unless you
+	  Say Y here to use the data cache in writethrough mode. Unless you
 	  specifically require this or are unsure, say N.
 
 config CPU_CACHE_ROUND_ROBIN
diff -Nru a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c
--- a/arch/arm/mm/alignment.c	2005-03-01 23:38:53 -08:00
+++ b/arch/arm/mm/alignment.c	2005-03-01 23:38:53 -08:00
@@ -3,6 +3,9 @@
  *
  *  Copyright (C) 1995  Linus Torvalds
  *  Modifications for ARM processor (c) 1995-2001 Russell King
+ *  Thumb aligment fault fixups (c) 2004 MontaVista Software, Inc.
+ *  - Adapted from gdb/sim/arm/thumbemu.c -- Thumb instruction emulation.
+ *    Copyright (C) 1996, Cygnus Software Technologies Ltd.
  *
  * 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
@@ -130,6 +133,18 @@
 #define TYPE_LDST	2
 #define TYPE_DONE	3
 
+#ifdef __ARMEB__
+#define BE		1
+#define FIRST_BYTE_16	"mov	%1, %1, ror #8\n"
+#define FIRST_BYTE_32	"mov	%1, %1, ror #24\n"
+#define NEXT_BYTE	"ror #24"
+#else
+#define BE		0
+#define FIRST_BYTE_16
+#define FIRST_BYTE_32
+#define NEXT_BYTE	"lsr #8"
+#endif
+
 #define __get8_unaligned_check(ins,val,addr,err)	\
 	__asm__(					\
 	"1:	"ins"	%1, [%2], #1\n"			\
@@ -149,9 +164,10 @@
 #define __get16_unaligned_check(ins,val,addr)			\
 	do {							\
 		unsigned int err = 0, v, a = addr;		\
-		__get8_unaligned_check(ins,val,a,err);		\
 		__get8_unaligned_check(ins,v,a,err);		\
-		val |= v << 8;					\
+		val =  v << ((BE) ? 8 : 0);			\
+		__get8_unaligned_check(ins,v,a,err);		\
+		val |= v << ((BE) ? 0 : 8);			\
 		if (err)					\
 			goto fault;				\
 	} while (0)
@@ -165,13 +181,14 @@
 #define __get32_unaligned_check(ins,val,addr)			\
 	do {							\
 		unsigned int err = 0, v, a = addr;		\
-		__get8_unaligned_check(ins,val,a,err);		\
 		__get8_unaligned_check(ins,v,a,err);		\
-		val |= v << 8;					\
+		val =  v << ((BE) ? 24 :  0);			\
+		__get8_unaligned_check(ins,v,a,err);		\
+		val |= v << ((BE) ? 16 :  8);			\
 		__get8_unaligned_check(ins,v,a,err);		\
-		val |= v << 16;					\
+		val |= v << ((BE) ?  8 : 16);			\
 		__get8_unaligned_check(ins,v,a,err);		\
-		val |= v << 24;					\
+		val |= v << ((BE) ?  0 : 24);			\
 		if (err)					\
 			goto fault;				\
 	} while (0)
@@ -185,9 +202,9 @@
 #define __put16_unaligned_check(ins,val,addr)			\
 	do {							\
 		unsigned int err = 0, v = val, a = addr;	\
-		__asm__(					\
+		__asm__( FIRST_BYTE_16				\
 		"1:	"ins"	%1, [%2], #1\n"			\
-		"	mov	%1, %1, lsr #8\n"		\
+		"	mov	%1, %1, "NEXT_BYTE"\n"		\
 		"2:	"ins"	%1, [%2]\n"			\
 		"3:\n"						\
 		"	.section .fixup,\"ax\"\n"		\
@@ -215,13 +232,13 @@
 #define __put32_unaligned_check(ins,val,addr)			\
 	do {							\
 		unsigned int err = 0, v = val, a = addr;	\
-		__asm__(					\
+		__asm__( FIRST_BYTE_32				\
 		"1:	"ins"	%1, [%2], #1\n"			\
-		"	mov	%1, %1, lsr #8\n"		\
+		"	mov	%1, %1, "NEXT_BYTE"\n"		\
 		"2:	"ins"	%1, [%2], #1\n"			\
-		"	mov	%1, %1, lsr #8\n"		\
+		"	mov	%1, %1, "NEXT_BYTE"\n"		\
 		"3:	"ins"	%1, [%2], #1\n"			\
-		"	mov	%1, %1, lsr #8\n"		\
+		"	mov	%1, %1, "NEXT_BYTE"\n"		\
 		"4:	"ins"	%1, [%2]\n"			\
 		"5:\n"						\
 		"	.section .fixup,\"ax\"\n"		\
@@ -449,16 +466,146 @@
 	return TYPE_ERROR;
 }
 
+/*
+ * Convert Thumb ld/st instruction forms to equivalent ARM instructions so
+ * we can reuse ARM userland alignment fault fixups for Thumb.
+ *
+ * This implementation was initially based on the algorithm found in
+ * gdb/sim/arm/thumbemu.c. It is basically just a code reduction of same
+ * to convert only Thumb ld/st instruction forms to equivalent ARM forms.
+ *
+ * NOTES:
+ * 1. Comments below refer to ARM ARM DDI0100E Thumb Instruction sections.
+ * 2. If for some reason we're passed an non-ld/st Thumb instruction to
+ *    decode, we return 0xdeadc0de. This should never happen under normal
+ *    circumstances but if it does, we've got other problems to deal with
+ *    elsewhere and we obviously can't fix those problems here.
+ */
+
+static unsigned long
+thumb2arm(u16 tinstr)
+{
+	u32 L = (tinstr & (1<<11)) >> 11;
+
+	switch ((tinstr & 0xf800) >> 11) {
+	/* 6.5.1 Format 1: */
+	case 0x6000 >> 11:				/* 7.1.52 STR(1) */
+	case 0x6800 >> 11:				/* 7.1.26 LDR(1) */
+	case 0x7000 >> 11:				/* 7.1.55 STRB(1) */
+	case 0x7800 >> 11:				/* 7.1.30 LDRB(1) */
+		return 0xe5800000 |
+			((tinstr & (1<<12)) << (22-12)) |	/* fixup */
+			(L<<20) |				/* L==1? */
+			((tinstr & (7<<0)) << (12-0)) |		/* Rd */
+			((tinstr & (7<<3)) << (16-3)) |		/* Rn */
+			((tinstr & (31<<6)) >>			/* immed_5 */
+				(6 - ((tinstr & (1<<12)) ? 0 : 2)));
+	case 0x8000 >> 11:				/* 7.1.57 STRH(1) */
+	case 0x8800 >> 11:				/* 7.1.32 LDRH(1) */
+		return 0xe1c000b0 |
+			(L<<20) |				/* L==1? */
+			((tinstr & (7<<0)) << (12-0)) |		/* Rd */
+			((tinstr & (7<<3)) << (16-3)) |		/* Rn */
+			((tinstr & (7<<6)) >> (6-1)) |	 /* immed_5[2:0] */
+			((tinstr & (3<<9)) >> (9-8));	 /* immed_5[4:3] */
+
+	/* 6.5.1 Format 2: */
+	case 0x5000 >> 11:
+	case 0x5800 >> 11:
+		{
+			static const u32 subset[8] = {
+				0xe7800000,		/* 7.1.53 STR(2) */
+				0xe18000b0,		/* 7.1.58 STRH(2) */
+				0xe7c00000,		/* 7.1.56 STRB(2) */
+				0xe19000d0,		/* 7.1.34 LDRSB */
+				0xe7900000,		/* 7.1.27 LDR(2) */
+				0xe19000b0,		/* 7.1.33 LDRH(2) */
+				0xe7d00000,		/* 7.1.31 LDRB(2) */
+				0xe19000f0		/* 7.1.35 LDRSH */
+			};
+			return subset[(tinstr & (7<<9)) >> 9] |
+			    ((tinstr & (7<<0)) << (12-0)) |	/* Rd */
+			    ((tinstr & (7<<3)) << (16-3)) |	/* Rn */
+			    ((tinstr & (7<<6)) >> (6-0));	/* Rm */
+		}
+
+	/* 6.5.1 Format 3: */
+	case 0x4800 >> 11:				/* 7.1.28 LDR(3) */
+		/* NOTE: This case is not technically possible. We're
+		 * 	 loading 32-bit memory data via PC relative
+		 *	 addressing mode. So we can and should eliminate
+		 *	 this case. But I'll leave it here for now.
+		 */
+		return 0xe59f0000 |
+		    ((tinstr & (7<<8)) << (12-8)) |		/* Rd */
+		    ((tinstr & 255) << (2-0));			/* immed_8 */
+
+	/* 6.5.1 Format 4: */
+	case 0x9000 >> 11:				/* 7.1.54 STR(3) */
+	case 0x9800 >> 11:				/* 7.1.29 LDR(4) */
+		return 0xe58d0000 |
+			(L<<20) |				/* L==1? */
+			((tinstr & (7<<8)) << (12-8)) |		/* Rd */
+			((tinstr & 255) << 2);			/* immed_8 */
+
+	/* 6.6.1 Format 1: */
+	case 0xc000 >> 11:				/* 7.1.51 STMIA */
+	case 0xc800 >> 11:				/* 7.1.25 LDMIA */
+		{
+			u32 Rn = (tinstr & (7<<8)) >> 8;
+			u32 W = ((L<<Rn) & (tinstr&255)) ? 0 : 1<<21;
+
+			return 0xe8800000 | W | (L<<20) | (Rn<<16) |
+				(tinstr&255);
+		}
+
+	/* 6.6.1 Format 2: */
+	case 0xb000 >> 11:				/* 7.1.48 PUSH */
+	case 0xb800 >> 11:				/* 7.1.47 POP */
+		if ((tinstr & (3 << 9)) == 0x0400) {
+			static const u32 subset[4] = {
+				0xe92d0000,	/* STMDB sp!,{registers} */
+				0xe92d4000,	/* STMDB sp!,{registers,lr} */
+				0xe8bd0000,	/* LDMIA sp!,{registers} */
+				0xe8bd8000	/* LDMIA sp!,{registers,pc} */
+			};
+			return subset[(L<<1) | ((tinstr & (1<<8)) >> 8)] |
+			    (tinstr & 255);		/* register_list */
+		}
+		/* Else fall through for illegal instruction case */
+
+	default:
+		return 0xdeadc0de;
+	}
+}
+
 static int
 do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
 {
 	union offset_union offset;
-	unsigned long instr, instrptr;
+	unsigned long instr = 0, instrptr;
 	int (*handler)(unsigned long addr, unsigned long instr, struct pt_regs *regs);
 	unsigned int type;
+	mm_segment_t fs;
+	unsigned int fault;
+	u16 tinstr = 0;
 
 	instrptr = instruction_pointer(regs);
-	instr = *(unsigned long *)instrptr;
+
+	fs = get_fs();
+	set_fs(KERNEL_DS);
+	if thumb_mode(regs) {
+		fault = __get_user(tinstr, (u16 *)(instrptr & ~1));
+		if (!(fault))
+			instr = thumb2arm(tinstr);
+	} else
+		fault = __get_user(instr, (u32 *)instrptr);
+	set_fs(fs);
+
+	if (fault) {
+		type = TYPE_FAULT;
+ 		goto bad_or_fault;
+	}
 
 	if (user_mode(regs))
 		goto user;
@@ -467,7 +614,7 @@
 
  fixup:
 
-	regs->ARM_pc += 4;
+	regs->ARM_pc += thumb_mode(regs) ? 2 : 4;
 
 	switch (CODING_BITS(instr)) {
 	case 0x00000000:	/* ldrh or strh */
@@ -537,7 +684,7 @@
  bad_or_fault:
 	if (type == TYPE_ERROR)
 		goto bad;
-	regs->ARM_pc -= 4;
+	regs->ARM_pc -= thumb_mode(regs) ? 2 : 4;
 	/*
 	 * We got a fault - fix it up, or die.
 	 */
@@ -549,7 +696,9 @@
 	 * Oops, we didn't handle the instruction.
 	 */
 	printk(KERN_ERR "Alignment trap: not handling instruction "
-		"%08lx at [<%08lx>]\n", instr, instrptr);
+		"%0*lx at [<%08lx>]\n",
+		thumb_mode(regs) ? 4 : 8,
+		thumb_mode(regs) ? tinstr : instr, instrptr);
 	ai_skipped += 1;
 	return 1;
 
@@ -557,9 +706,12 @@
 	ai_user += 1;
 
 	if (ai_usermode & 1)
-		printk("Alignment trap: %s (%d) PC=0x%08lx Instr=0x%08lx "
+		printk("Alignment trap: %s (%d) PC=0x%08lx Instr=0x%0*lx "
 		       "Address=0x%08lx FSR 0x%03x\n", current->comm,
-			current->pid, instrptr, instr, addr, fsr);
+			current->pid, instrptr,
+		        thumb_mode(regs) ? 4 : 8,
+		        thumb_mode(regs) ? tinstr : instr,
+		        addr, fsr);
 
 	if (ai_usermode & 2)
 		goto fixup;
diff -Nru a/arch/arm/mm/consistent.c b/arch/arm/mm/consistent.c
--- a/arch/arm/mm/consistent.c	2005-03-01 23:39:09 -08:00
+++ b/arch/arm/mm/consistent.c	2005-03-01 23:39:09 -08:00
@@ -1,7 +1,7 @@
 /*
  *  linux/arch/arm/mm/consistent.c
  *
- *  Copyright (C) 2000-2002 Russell King
+ *  Copyright (C) 2000-2004 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
@@ -30,7 +30,7 @@
  * This is the page table (2MB) covering uncached, DMA consistent allocations
  */
 static pte_t *consistent_pte;
-static spinlock_t consistent_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(consistent_lock);
 
 /*
  * VM region handling support.
@@ -65,6 +65,7 @@
 	struct list_head	vm_list;
 	unsigned long		vm_start;
 	unsigned long		vm_end;
+	struct page		*vm_pages;
 };
 
 static struct vm_region consistent_head = {
@@ -206,6 +207,8 @@
 		pte_t *pte = consistent_pte + CONSISTENT_OFFSET(c->vm_start);
 		struct page *end = page + (1 << order);
 
+		c->vm_pages = page;
+
 		/*
 		 * Set the "dma handle"
 		 */
@@ -215,6 +218,9 @@
 			BUG_ON(!pte_none(*pte));
 
 			set_page_count(page, 1);
+			/*
+			 * x86 does not mark the pages reserved...
+			 */
 			SetPageReserved(page);
 			set_pte(pte, mk_pte(page, prot));
 			page++;
@@ -264,6 +270,53 @@
 }
 EXPORT_SYMBOL(dma_alloc_writecombine);
 
+static int dma_mmap(struct device *dev, struct vm_area_struct *vma,
+		    void *cpu_addr, dma_addr_t dma_addr, size_t size)
+{
+	unsigned long flags, user_size, kern_size;
+	struct vm_region *c;
+	int ret = -ENXIO;
+
+	user_size = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
+
+	spin_lock_irqsave(&consistent_lock, flags);
+	c = vm_region_find(&consistent_head, (unsigned long)cpu_addr);
+	spin_unlock_irqrestore(&consistent_lock, flags);
+
+	if (c) {
+		unsigned long off = vma->vm_pgoff;
+
+		kern_size = (c->vm_end - c->vm_start) >> PAGE_SHIFT;
+
+		if (off < kern_size &&
+		    user_size <= (kern_size - off)) {
+			vma->vm_flags |= VM_RESERVED;
+			ret = remap_pfn_range(vma, vma->vm_start,
+					      page_to_pfn(c->vm_pages) + off,
+					      user_size << PAGE_SHIFT,
+					      vma->vm_page_prot);
+		}
+	}
+
+	return ret;
+}
+
+int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+		      void *cpu_addr, dma_addr_t dma_addr, size_t size)
+{
+	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+	return dma_mmap(dev, vma, cpu_addr, dma_addr, size);
+}
+EXPORT_SYMBOL(dma_mmap_coherent);
+
+int dma_mmap_writecombine(struct device *dev, struct vm_area_struct *vma,
+			  void *cpu_addr, dma_addr_t dma_addr, size_t size)
+{
+	vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
+	return dma_mmap(dev, vma, cpu_addr, dma_addr, size);
+}
+EXPORT_SYMBOL(dma_mmap_writecombine);
+
 /*
  * free a page as defined by the above mapping.
  */
@@ -300,6 +353,10 @@
 
 			if (pfn_valid(pfn)) {
 				struct page *page = pfn_to_page(pfn);
+
+				/*
+				 * x86 does not mark the pages reserved...
+				 */
 				ClearPageReserved(page);
 
 				__free_page(page);
diff -Nru a/arch/arm/mm/copypage-v6.c b/arch/arm/mm/copypage-v6.c
--- a/arch/arm/mm/copypage-v6.c	2005-03-01 23:38:55 -08:00
+++ b/arch/arm/mm/copypage-v6.c	2005-03-01 23:38:55 -08:00
@@ -28,7 +28,7 @@
 
 static pte_t *from_pte;
 static pte_t *to_pte;
-static spinlock_t v6_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(v6_lock);
 
 #define DCACHE_COLOUR(vaddr) ((vaddr & (SHMLBA - 1)) >> PAGE_SHIFT)
 
diff -Nru a/arch/arm/mm/init.c b/arch/arm/mm/init.c
--- a/arch/arm/mm/init.c	2005-03-01 23:38:52 -08:00
+++ b/arch/arm/mm/init.c	2005-03-01 23:38:52 -08:00
@@ -15,6 +15,7 @@
 #include <linux/init.h>
 #include <linux/bootmem.h>
 #include <linux/mman.h>
+#include <linux/nodemask.h>
 #include <linux/initrd.h>
 
 #include <asm/mach-types.h>
@@ -55,7 +56,7 @@
 	show_free_areas();
 	printk("Free swap:       %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
 
-	for (node = 0; node < numnodes; node++) {
+	for_each_online_node(node) {
 		struct page *page, *end;
 
 		page = NODE_MEM_MAP(node);
@@ -178,18 +179,14 @@
 
 		node = mi->bank[i].node;
 
-		if (node >= numnodes) {
-			numnodes = node + 1;
-
-			/*
-			 * Make sure we haven't exceeded the maximum number
-			 * of nodes that we have in this configuration.  If
-			 * we have, we're in trouble.  (maybe we ought to
-			 * limit, instead of bugging?)
-			 */
-			if (numnodes > MAX_NUMNODES)
-				BUG();
-		}
+		/*
+		 * Make sure we haven't exceeded the maximum number of nodes
+		 * that we have in this configuration.  If we have, we're in
+		 * trouble.  (maybe we ought to limit, instead of bugging?)
+		 */
+		if (node >= MAX_NUMNODES)
+			BUG();
+		node_set_online(node);
 
 		/*
 		 * Get the start and end pfns for this bank
@@ -211,7 +208,7 @@
 	 * Calculate the number of pages we require to
 	 * store the bootmem bitmaps.
 	 */
-	for (i = 0; i < numnodes; i++) {
+	for_each_online_node(i) {
 		if (np[i].end == 0)
 			continue;
 
@@ -380,13 +377,13 @@
 	 * (we could also do with rolling bootmem_init and paging_init
 	 * into one generic "memory_init" type function).
 	 */
-	np += numnodes - 1;
-	for (node = numnodes - 1; node >= 0; node--, np--) {
+	np += num_online_nodes() - 1;
+	for (node = num_online_nodes() - 1; node >= 0; node--, np--) {
 		/*
 		 * If there are no pages in this node, ignore it.
 		 * Note that node 0 must always have some pages.
 		 */
-		if (np->end == 0) {
+		if (np->end == 0 || !node_online(node)) {
 			if (node == 0)
 				BUG();
 			continue;
@@ -449,7 +446,7 @@
 	/*
 	 * initialise the zones within each node
 	 */
-	for (node = 0; node < numnodes; node++) {
+	for_each_online_node(node) {
 		unsigned long zone_size[MAX_NR_ZONES];
 		unsigned long zhole_size[MAX_NR_ZONES];
 		struct bootmem_data *bdata;
@@ -558,7 +555,7 @@
 		create_memmap_holes(&meminfo);
 
 	/* this will put all unused low memory onto the freelists */
-	for (node = 0; node < numnodes; node++) {
+	for_each_online_node(node) {
 		pg_data_t *pgdat = NODE_DATA(node);
 
 		if (pgdat->node_spanned_pages != 0)
diff -Nru a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
--- a/arch/arm/mm/ioremap.c	2005-03-01 23:39:07 -08:00
+++ b/arch/arm/mm/ioremap.c	2005-03-01 23:39:07 -08:00
@@ -148,7 +148,7 @@
 	 */
 	offset = phys_addr & ~PAGE_MASK;
 	phys_addr &= PAGE_MASK;
-	size = PAGE_ALIGN(last_addr) - phys_addr;
+	size = PAGE_ALIGN(last_addr + 1) - phys_addr;
 
 	/*
 	 * Ok, go for it..
diff -Nru a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c
--- a/arch/arm/mm/mm-armv.c	2005-03-01 23:39:07 -08:00
+++ b/arch/arm/mm/mm-armv.c	2005-03-01 23:39:07 -08:00
@@ -15,6 +15,7 @@
 #include <linux/init.h>
 #include <linux/bootmem.h>
 #include <linux/highmem.h>
+#include <linux/nodemask.h>
 
 #include <asm/pgalloc.h>
 #include <asm/page.h>
@@ -239,7 +240,8 @@
 
 /*
  * Create a SECTION PGD between VIRT and PHYS in domain
- * DOMAIN with protection PROT
+ * DOMAIN with protection PROT.  This operates on half-
+ * pgdir entry increments.
  */
 static inline void
 alloc_init_section(unsigned long virt, unsigned long phys, int prot)
@@ -481,6 +483,9 @@
 		length -= PAGE_SIZE;
 	}
 
+	/*
+	 * A section mapping covers half a "pgdir" entry.
+	 */
 	while (length >= (PGDIR_SIZE / 2)) {
 		alloc_init_section(virt, virt + off, prot_sect);
 
@@ -522,6 +527,7 @@
 			pmdval |= PMD_BIT4;
 		pmd = pmd_offset(pgd + i, i << PGDIR_SHIFT);
 		set_pmd(pmd, __pmd(pmdval));
+		set_pmd(pmd + 1, __pmd(pmdval + (1 << (PGDIR_SHIFT - 1))));
 	}
 }
 
@@ -696,6 +702,6 @@
 {
 	int node;
 
-	for (node = 0; node < numnodes; node++)
+	for_each_online_node(node)
 		free_unused_memmap_node(node, mi);
 }
diff -Nru a/arch/arm/mm/proc-arm1020.S b/arch/arm/mm/proc-arm1020.S
--- a/arch/arm/mm/proc-arm1020.S	2005-03-01 23:38:52 -08:00
+++ b/arch/arm/mm/proc-arm1020.S	2005-03-01 23:38:52 -08:00
@@ -431,36 +431,29 @@
 	mcr	p15, 0, r0, c7, c7		@ invalidate I,D caches on v4
 	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer on v4
 	mcr	p15, 0, r0, c8, c7		@ invalidate I,D TLBs on v4
-	mcr	p15, 0, r4, c2, c0		@ load page table pointer
-	mov	r0, #0x1f			@ Domains 0, 1 = client
-	mcr	p15, 0, r0, c3, c0		@ load domain access register
 	mrc	p15, 0, r0, c1, c0		@ get control register v4
-/*
- * Clear out 'unwanted' bits (then put them in if we need them)
- */
-	bic	r0, r0, #0x1e00 		@ i...??r.........
-	bic	r0, r0, #0x000e 		@ ............wca.
-/*
- * Turn on what we want
- */
-	orr	r0, r0, #0x0031 		@ ..........DP...M
-	orr	r0, r0, #0x0100 		@ .......S........
-
+	ldr	r5, arm1020_cr1_clear
+	bic	r0, r0, r5
+	ldr	r5, arm1020_cr1_set
+	orr	r0, r0, r5
 #ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
-	orr	r0, r0, #0x4000 		@ .R..............
-#endif
-#ifndef CONFIG_CPU_BPREDICT_DISABLE
-	orr	r0, r0, #0x0800 		@ ....Z...........
-#endif
-#ifndef CONFIG_CPU_DCACHE_DISABLE
-	orr	r0, r0, #0x0004 		@ Enable D cache
-#endif
-#ifndef CONFIG_CPU_ICACHE_DISABLE
-	orr	r0, r0, #0x1000 		@ I Cache on
+	orr	r0, r0, #0x4000 		@ .R.. .... .... ....
 #endif
 	mov	pc, lr
 	.size	__arm1020_setup, . - __arm1020_setup
 
+	/*
+	 *  R
+	 * .RVI ZFRS BLDP WCAM
+	 * .0.1 1001 ..11 0101	/* FIXME: why no V bit? */
+	 */
+	.type	arm1020_cr1_clear, #object
+	.type	arm1020_cr1_set, #object
+arm1020_cr1_clear:
+	.word	0x593f
+arm1020_cr1_set:
+	.word	0x1935
+
 	__INITDATA
 
 /*
@@ -522,7 +515,9 @@
 __arm1020_proc_info:
 	.long	0x4104a200			@ ARM 1020T (Architecture v5T)
 	.long	0xff0ffff0
-	.long	0x00000c02			@ mmuflags
+	.long   PMD_TYPE_SECT | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ
 	b	__arm1020_setup
 	.long	cpu_arch_name
 	.long	cpu_elf_name
diff -Nru a/arch/arm/mm/proc-arm1020e.S b/arch/arm/mm/proc-arm1020e.S
--- a/arch/arm/mm/proc-arm1020e.S	2005-03-01 23:38:58 -08:00
+++ b/arch/arm/mm/proc-arm1020e.S	2005-03-01 23:38:58 -08:00
@@ -413,36 +413,29 @@
 	mcr	p15, 0, r0, c7, c7		@ invalidate I,D caches on v4
 	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer on v4
 	mcr	p15, 0, r0, c8, c7		@ invalidate I,D TLBs on v4
-	mcr	p15, 0, r4, c2, c0		@ load page table pointer
-	mov	r0, #0x1f			@ Domains 0, 1 = client
-	mcr	p15, 0, r0, c3, c0		@ load domain access register
 	mrc	p15, 0, r0, c1, c0		@ get control register v4
-/*
- * Clear out 'unwanted' bits (then put them in if we need them)
- */
-	bic	r0, r0, #0x1e00 		@ i...??r.........
-	bic	r0, r0, #0x000e 		@ ............wca.
-/*
- * Turn on what we want
- */
-	orr	r0, r0, #0x0031 		@ ..........DP...M
-	orr	r0, r0, #0x0100 		@ .......S........
-
+	ldr	r5, arm1020e_cr1_clear
+	bic	r0, r0, r5
+	ldr	r5, arm1020e_cr1_set
+	orr	r0, r0, r5
 #ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
-	orr	r0, r0, #0x4000 		@ .R..............
-#endif
-#ifndef CONFIG_CPU_BPREDICT_DISABLE
-	orr	r0, r0, #0x0800 		@ ....Z...........
-#endif
-#ifndef CONFIG_CPU_DCACHE_DISABLE
-	orr	r0, r0, #0x0004 		@ Enable D cache
-#endif
-#ifndef CONFIG_CPU_ICACHE_DISABLE
-	orr	r0, r0, #0x1000 		@ I Cache on
+	orr	r0, r0, #0x4000 		@ .R.. .... .... ....
 #endif
 	mov	pc, lr
 	.size	__arm1020e_setup, . - __arm1020e_setup
 
+	/*
+	 *  R
+	 * .RVI ZFRS BLDP WCAM
+	 * .0.1 1001 ..11 0101	/* FIXME: why no V bit? */
+	 */
+	.type	arm1020e_cr1_clear, #object
+	.type	arm1020e_cr1_set, #object
+arm1020e_cr1_clear:
+	.word	0x5f3f
+arm1020e_cr1_set:
+	.word	0x1935
+
 	__INITDATA
 
 /*
@@ -504,7 +497,10 @@
 __arm1020e_proc_info:
 	.long	0x4105a200			@ ARM 1020TE (Architecture v5TE)
 	.long	0xff0ffff0
-	.long	0x00000c12			@ mmuflags
+	.long   PMD_TYPE_SECT | \
+		PMD_BIT4 | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ
 	b	__arm1020e_setup
 	.long	cpu_arch_name
 	.long	cpu_elf_name
diff -Nru a/arch/arm/mm/proc-arm1022.S b/arch/arm/mm/proc-arm1022.S
--- a/arch/arm/mm/proc-arm1022.S	2005-03-01 23:39:16 -08:00
+++ b/arch/arm/mm/proc-arm1022.S	2005-03-01 23:39:16 -08:00
@@ -394,36 +394,30 @@
 	mcr	p15, 0, r0, c7, c7		@ invalidate I,D caches on v4
 	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer on v4
 	mcr	p15, 0, r0, c8, c7		@ invalidate I,D TLBs on v4
-	mcr	p15, 0, r4, c2, c0		@ load page table pointer
-	mov	r0, #0x1f			@ Domains 0, 1 = client
-	mcr	p15, 0, r0, c3, c0		@ load domain access register
 	mrc	p15, 0, r0, c1, c0		@ get control register v4
-/*
- * Clear out 'unwanted' bits (then put them in if we need them)
- */
-	bic	r0, r0, #0x1e00 		@ ...i??r.........
-	bic	r0, r0, #0x000e 		@ ............wca.
-/*
- * Turn on what we want
- */
-	orr	r0, r0, #0x0031 		@ ..........DP...M
-	orr	r0, r0, #0x2100 		@ ..V....S........
-
+	ldr	r5, arm1022_cr1_clear
+	bic	r0, r0, r5
+	ldr	r5, arm1022_cr1_set
+	orr	r0, r0, r5
 #ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
 	orr	r0, r0, #0x4000 		@ .R..............
 #endif
-#ifndef CONFIG_CPU_BPREDICT_DISABLE
-	orr	r0, r0, #0x0800 		@ ....Z...........
-#endif
-#ifndef CONFIG_CPU_DCACHE_DISABLE
-	orr	r0, r0, #0x0004 		@ .............C..
-#endif
-#ifndef CONFIG_CPU_ICACHE_DISABLE
-	orr	r0, r0, #0x1000 		@ ...I............
-#endif
 	mov	pc, lr
 	.size	__arm1022_setup, . - __arm1022_setup
 
+	/*
+	 *  R
+	 * .RVI ZFRS BLDP WCAM
+	 * .011 1001 ..11 0101
+	 * 
+	 */
+	.type	arm1022_cr1_clear, #object
+	.type	arm1022_cr1_set, #object
+arm1022_cr1_clear:
+	.word	0x7f3f
+arm1022_cr1_set:
+	.word	0x3935
+
 	__INITDATA
 
 /*
@@ -485,7 +479,10 @@
 __arm1022_proc_info:
 	.long	0x4105a220			@ ARM 1022E (v5TE)
 	.long	0xff0ffff0
-	.long	0x00000c12			@ mmuflags
+	.long   PMD_TYPE_SECT | \
+		PMD_BIT4 | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ
 	b	__arm1022_setup
 	.long	cpu_arch_name
 	.long	cpu_elf_name
diff -Nru a/arch/arm/mm/proc-arm1026.S b/arch/arm/mm/proc-arm1026.S
--- a/arch/arm/mm/proc-arm1026.S	2005-03-01 23:38:57 -08:00
+++ b/arch/arm/mm/proc-arm1026.S	2005-03-01 23:38:57 -08:00
@@ -389,35 +389,30 @@
 	mov	r0, #4				@ explicitly disable writeback
 	mcr	p15, 7, r0, c15, c0, 0
 #endif
-	mov	r0, #0x1f			@ Domains 0, 1 = client
-	mcr	p15, 0, r0, c3, c0		@ load domain access register
 	mrc	p15, 0, r0, c1, c0		@ get control register v4
-/*
- * Clear out 'unwanted' bits (then put them in if we need them)
- */
-	bic	r0, r0, #0x1e00 		@ ...i??r.........
-	bic	r0, r0, #0x000e 		@ ............wca.
-/*
- * Turn on what we want
- */
-	orr	r0, r0, #0x0031 		@ ..........DP...M
-	orr	r0, r0, #0x2100 		@ ..V....S........
-
+	ldr	r5, arm1026_cr1_clear
+	bic	r0, r0, r5
+	ldr	r5, arm1026_cr1_set
+	orr	r0, r0, r5
 #ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
-	orr	r0, r0, #0x4000 		@ .R..............
-#endif
-#ifndef CONFIG_CPU_BPREDICT_DISABLE
-	orr	r0, r0, #0x0800 		@ ....Z...........
-#endif
-#ifndef CONFIG_CPU_DCACHE_DISABLE
-	orr	r0, r0, #0x0004 		@ .............C..
-#endif
-#ifndef CONFIG_CPU_ICACHE_DISABLE
-	orr	r0, r0, #0x1000 		@ ...I............
+	orr	r0, r0, #0x4000 		@ .R.. .... .... ....
 #endif
 	mov	pc, lr
 	.size	__arm1026_setup, . - __arm1026_setup
 
+	/*
+	 *  R
+	 * .RVI ZFRS BLDP WCAM
+	 * .011 1001 ..11 0101
+	 * 
+	 */
+	.type	arm1026_cr1_clear, #object
+	.type	arm1026_cr1_set, #object
+arm1026_cr1_clear:
+	.word	0x7f3f
+arm1026_cr1_set:
+	.word	0x3935
+
 	__INITDATA
 
 /*
@@ -480,7 +475,10 @@
 __arm1026_proc_info:
 	.long	0x4106a260			@ ARM 1026EJ-S (v5TEJ)
 	.long	0xff0ffff0
-	.long	0x00000c12			@ mmuflags
+	.long   PMD_TYPE_SECT | \
+		PMD_BIT4 | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ
 	b	__arm1026_setup
 	.long	cpu_arch_name
 	.long	cpu_elf_name
diff -Nru a/arch/arm/mm/proc-arm6_7.S b/arch/arm/mm/proc-arm6_7.S
--- a/arch/arm/mm/proc-arm6_7.S	2005-03-01 23:39:18 -08:00
+++ b/arch/arm/mm/proc-arm6_7.S	2005-03-01 23:39:18 -08:00
@@ -253,9 +253,6 @@
 __arm6_setup:	mov	r0, #0
 		mcr	p15, 0, r0, c7, c0		@ flush caches on v3
 		mcr	p15, 0, r0, c5, c0		@ flush TLBs on v3
-		mcr	p15, 0, r4, c2, c0		@ load page table pointer
-		mov	r0, #0x1f			@ Domains 0, 1 = client
-		mcr	p15, 0, r0, c3, c0		@ load domain access register
 		mov	r0, #0x3d			@ . ..RS BLDP WCAM
 		orr	r0, r0, #0x100			@ . ..01 0011 1101
 		mov	pc, lr
@@ -265,8 +262,6 @@
 __arm7_setup:	mov	r0, #0
 		mcr	p15, 0, r0, c7, c0		@ flush caches on v3
 		mcr	p15, 0, r0, c5, c0		@ flush TLBs on v3
-		mcr	p15, 0, r4, c2, c0		@ load page table pointer
-		mov	r0, #0x1f			@ Domains 0, 1 = client
 		mcr	p15, 0, r0, c3, c0		@ load domain access register
 		mov	r0, #0x7d			@ . ..RS BLDP WCAM
 		orr	r0, r0, #0x100			@ . ..01 0111 1101
@@ -391,7 +386,12 @@
 __arm710_proc_info:
 		.long	0x41007100
 		.long	0xfff8ff00
-		.long	0x00000c1e
+		.long   PMD_TYPE_SECT | \
+			PMD_SECT_BUFFERABLE | \
+			PMD_SECT_CACHEABLE | \
+			PMD_BIT4 | \
+			PMD_SECT_AP_WRITE | \
+			PMD_SECT_AP_READ
 		b	__arm7_setup
 		.long	cpu_arch_name
 		.long	cpu_elf_name
diff -Nru a/arch/arm/mm/proc-arm720.S b/arch/arm/mm/proc-arm720.S
--- a/arch/arm/mm/proc-arm720.S	2005-03-01 23:39:07 -08:00
+++ b/arch/arm/mm/proc-arm720.S	2005-03-01 23:39:07 -08:00
@@ -124,37 +124,59 @@
 		mcr	p15, 0, ip, c1, c0, 0		@ ctrl register
 		mov	pc, r0
 
-		__INIT
+	__INIT
 
-		.type	__arm710_setup, #function
-__arm710_setup:	mov	r0, #0
-		mcr	p15, 0, r0, c7, c7, 0		@ invalidate caches
-		mcr	p15, 0, r0, c8, c7, 0		@ flush TLB (v4)
-		mcr	p15, 0, r4, c2, c0		@ load page table pointer
-		mov	r0, #0x1f			@ Domains 0, 1 = client
-		mcr	p15, 0, r0, c3, c0		@ load domain access register
-
-		mrc	p15, 0, r0, c1, c0		@ get control register
-		bic	r0, r0, #0x0e00			@ ..V. ..RS BLDP WCAM
-		orr	r0, r0, #0x0100			@ .... .... .111 .... (old)
-		orr	r0, r0, #0x003d			@ .... ..01 ..11 1101 (new)
-		mov	pc, lr				@ __ret (head.S)
-		.size	__arm710_setup, . - __arm710_setup
-
-		.type	__arm720_setup, #function
-__arm720_setup:	mov	r0, #0
-		mcr	p15, 0, r0, c7, c7, 0		@ invalidate caches
-		mcr	p15, 0, r0, c8, c7, 0		@ flush TLB (v4)
-		mcr	p15, 0, r4, c2, c0		@ load page table pointer
-		mov	r0, #0x1f			@ Domains 0, 1 = client
-		mcr	p15, 0, r0, c3, c0		@ load domain access register
-
-		mrc	p15, 0, r0, c1, c0		@ get control register
-		bic	r0, r0, #0x0e00			@ ..V. ..RS BLDP WCAM
-		orr	r0, r0, #0x2100			@ .... .... .111 .... (old)
-		orr	r0, r0, #0x003d			@ ..1. ..01 ..11 1101 (new)
-		mov	pc, lr				@ __ret (head.S)
-		.size	__arm720_setup, . - __arm720_setup
+	.type	__arm710_setup, #function
+__arm710_setup:
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c7, 0		@ invalidate caches
+	mcr	p15, 0, r0, c8, c7, 0		@ flush TLB (v4)
+	mrc	p15, 0, r0, c1, c0		@ get control register
+	ldr	r5, arm710_cr1_clear
+	bic	r0, r0, r5
+	ldr	r5, arm710_cr1_set
+	orr	r0, r0, r5
+	mov	pc, lr				@ __ret (head.S)
+	.size	__arm710_setup, . - __arm710_setup
+
+	/*
+	 *  R
+	 * .RVI ZFRS BLDP WCAM
+	 * .... 0001 ..11 1101
+	 * 
+	 */
+	.type	arm710_cr1_clear, #object
+	.type	arm710_cr1_set, #object
+arm710_cr1_clear:
+	.word	0x0f3f
+arm710_cr1_set:
+	.word	0x013d
+
+	.type	__arm720_setup, #function
+__arm720_setup:
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c7, 0		@ invalidate caches
+	mcr	p15, 0, r0, c8, c7, 0		@ flush TLB (v4)
+	mrc	p15, 0, r0, c1, c0		@ get control register
+	ldr	r5, arm720_cr1_clear
+	bic	r0, r0, r5
+	ldr	r5, arm720_cr1_set
+	orr	r0, r0, r5
+	mov	pc, lr				@ __ret (head.S)
+	.size	__arm720_setup, . - __arm720_setup
+
+	/*
+	 *  R
+	 * .RVI ZFRS BLDP WCAM
+	 * ..1. 1001 ..11 1101
+	 * 
+	 */
+	.type	arm720_cr1_clear, #object
+	.type	arm720_cr1_set, #object
+arm720_cr1_clear:
+	.word	0x2f3f
+arm720_cr1_set:
+	.word	0x213d
 
 		__INITDATA
 
@@ -206,7 +228,12 @@
 __arm710_proc_info:
 		.long	0x41807100				@ cpu_val
 		.long	0xffffff00				@ cpu_mask
-		.long	0x00000c1e				@ section_mmu_flags
+		.long   PMD_TYPE_SECT | \
+			PMD_SECT_BUFFERABLE | \
+			PMD_SECT_CACHEABLE | \
+			PMD_BIT4 | \
+			PMD_SECT_AP_WRITE | \
+			PMD_SECT_AP_READ
 		b	__arm710_setup				@ cpu_flush
 		.long	cpu_arch_name				@ arch_name
 		.long	cpu_elf_name				@ elf_name
@@ -222,7 +249,12 @@
 __arm720_proc_info:
 		.long	0x41807200				@ cpu_val
 		.long	0xffffff00				@ cpu_mask
-		.long	0x00000c1e				@ section_mmu_flags
+		.long   PMD_TYPE_SECT | \
+			PMD_SECT_BUFFERABLE | \
+			PMD_SECT_CACHEABLE | \
+			PMD_BIT4 | \
+			PMD_SECT_AP_WRITE | \
+			PMD_SECT_AP_READ
 		b	__arm720_setup				@ cpu_flush
 		.long	cpu_arch_name				@ arch_name
 		.long	cpu_elf_name				@ elf_name
diff -Nru a/arch/arm/mm/proc-arm920.S b/arch/arm/mm/proc-arm920.S
--- a/arch/arm/mm/proc-arm920.S	2005-03-01 23:38:51 -08:00
+++ b/arch/arm/mm/proc-arm920.S	2005-03-01 23:38:51 -08:00
@@ -382,33 +382,27 @@
 	mcr	p15, 0, r0, c7, c7		@ invalidate I,D caches on v4
 	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer on v4
 	mcr	p15, 0, r0, c8, c7		@ invalidate I,D TLBs on v4
-	mcr	p15, 0, r4, c2, c0		@ load page table pointer
-	mov	r0, #0x1f			@ Domains 0, 1 = client
-	mcr	p15, 0, r0, c3, c0		@ load domain access register
 	mrc	p15, 0, r0, c1, c0		@ get control register v4
-/*
- * Clear out 'unwanted' bits (then put them in if we need them)
- */
-						@   VI ZFRS BLDP WCAM
-	bic	r0, r0, #0x0e00
-	bic	r0, r0, #0x0002
-	bic	r0, r0, #0x000c
-	bic	r0, r0, #0x1000			@ ...0 000. .... 000.
-/*
- * Turn on what we want
- */
-	orr	r0, r0, #0x0031
-	orr	r0, r0, #0x2100			@ ..1. ...1 ..11 ...1
-
-#ifndef CONFIG_CPU_DCACHE_DISABLE
-	orr	r0, r0, #0x0004			@ .... .... .... .1..
-#endif
-#ifndef CONFIG_CPU_ICACHE_DISABLE
-	orr	r0, r0, #0x1000			@ ...1 .... .... ....
-#endif
+	ldr	r5, arm920_cr1_clear
+	bic	r0, r0, r5
+	ldr	r5, arm920_cr1_set
+	orr	r0, r0, r5
 	mov	pc, lr
 	.size	__arm920_setup, . - __arm920_setup
 
+	/*
+	 *  R
+	 * .RVI ZFRS BLDP WCAM
+	 * ..11 0001 ..11 0101
+	 * 
+	 */
+	.type	arm920_cr1_clear, #object
+	.type	arm920_cr1_set, #object
+arm920_cr1_clear:
+	.word	0x3f3f
+arm920_cr1_set:
+	.word	0x3135
+
 	__INITDATA
 
 /*
@@ -464,7 +458,12 @@
 __arm920_proc_info:
 	.long	0x41009200
 	.long	0xff00fff0
-	.long	0x00000c1e			@ mmuflags
+	.long   PMD_TYPE_SECT | \
+		PMD_SECT_BUFFERABLE | \
+		PMD_SECT_CACHEABLE | \
+		PMD_BIT4 | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ
 	b	__arm920_setup
 	.long	cpu_arch_name
 	.long	cpu_elf_name
diff -Nru a/arch/arm/mm/proc-arm922.S b/arch/arm/mm/proc-arm922.S
--- a/arch/arm/mm/proc-arm922.S	2005-03-01 23:39:09 -08:00
+++ b/arch/arm/mm/proc-arm922.S	2005-03-01 23:39:09 -08:00
@@ -386,33 +386,27 @@
 	mcr	p15, 0, r0, c7, c7		@ invalidate I,D caches on v4
 	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer on v4
 	mcr	p15, 0, r0, c8, c7		@ invalidate I,D TLBs on v4
-	mcr	p15, 0, r4, c2, c0		@ load page table pointer
-	mov	r0, #0x1f			@ Domains 0, 1 = client
-	mcr	p15, 0, r0, c3, c0		@ load domain access register
 	mrc	p15, 0, r0, c1, c0		@ get control register v4
-/*
- * Clear out 'unwanted' bits (then put them in if we need them)
- */
-						@   VI ZFRS BLDP WCAM
-	bic	r0, r0, #0x0e00
-	bic	r0, r0, #0x0002
-	bic	r0, r0, #0x000c
-	bic	r0, r0, #0x1000			@ ...0 000. .... 000.
-/*
- * Turn on what we want
- */
-	orr	r0, r0, #0x0031
-	orr	r0, r0, #0x2100			@ ..1. ...1 ..11 ...1
-
-#ifndef CONFIG_CPU_DCACHE_DISABLE
-	orr	r0, r0, #0x0004			@ .... .... .... .1..
-#endif
-#ifndef CONFIG_CPU_ICACHE_DISABLE
-	orr	r0, r0, #0x1000			@ ...1 .... .... ....
-#endif
+	ldr	r5, arm922_cr1_clear
+	bic	r0, r0, r5
+	ldr	r5, arm922_cr1_set
+	orr	r0, r0, r5
 	mov	pc, lr
 	.size	__arm922_setup, . - __arm922_setup
 
+	/*
+	 *  R
+	 * .RVI ZFRS BLDP WCAM
+	 * ..11 0001 ..11 0101
+	 * 
+	 */
+	.type	arm922_cr1_clear, #object
+	.type	arm922_cr1_set, #object
+arm922_cr1_clear:
+	.word	0x3f3f
+arm922_cr1_set:
+	.word	0x3135
+
 	__INITDATA
 
 /*
@@ -468,7 +462,12 @@
 __arm922_proc_info:
 	.long	0x41009220
 	.long	0xff00fff0
-	.long	0x00000c1e			@ mmuflags
+	.long   PMD_TYPE_SECT | \
+		PMD_SECT_BUFFERABLE | \
+		PMD_SECT_CACHEABLE | \
+		PMD_BIT4 | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ
 	b	__arm922_setup
 	.long	cpu_arch_name
 	.long	cpu_elf_name
diff -Nru a/arch/arm/mm/proc-arm925.S b/arch/arm/mm/proc-arm925.S
--- a/arch/arm/mm/proc-arm925.S	2005-03-01 23:38:56 -08:00
+++ b/arch/arm/mm/proc-arm925.S	2005-03-01 23:38:56 -08:00
@@ -439,45 +439,36 @@
 	mcr	p15, 0, r0, c7, c7		@ invalidate I,D caches on v4
 	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer on v4
 	mcr	p15, 0, r0, c8, c7		@ invalidate I,D TLBs on v4
-	mcr	p15, 0, r4, c2, c0		@ load page table pointer
 
 #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
 	mov	r0, #4				@ disable write-back on caches explicitly
 	mcr	p15, 7, r0, c15, c0, 0
 #endif
 
-	mov	r0, #0x1f			@ Domains 0, 1 = client
-	mcr	p15, 0, r0, c3, c0		@ load domain access register
 	mrc	p15, 0, r0, c1, c0		@ get control register v4
-/*
- * Clear out 'unwanted' bits (then put them in if we need them)
- */
-						@   VI ZFRS BLDP WCAM
-	bic	r0, r0, #0x0e00
-	bic	r0, r0, #0x0002
-	bic	r0, r0, #0x000c
-	bic	r0, r0, #0x1000			@ ...0 000. .... 000.
-/*
- * Turn on what we want
- */
-	orr	r0, r0, #0x0031
-	orr	r0, r0, #0x2100			@ ..1. ...1 ..11 ...1
-
-	/* Writebuffer on */
-	orr	r0, r0, #0x0008			@ .... .... .... 1...
-
+	ldr	r5, arm925_cr1_clear
+	bic	r0, r0, r5
+	ldr	r5, arm925_cr1_set
+	orr	r0, r0, r5
 #ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
 	orr	r0, r0, #0x4000			@ .1.. .... .... ....
 #endif
-#ifndef CONFIG_CPU_DCACHE_DISABLE
-	orr	r0, r0, #0x0004			@ .... .... .... .1..
-#endif
-#ifndef CONFIG_CPU_ICACHE_DISABLE
-	orr	r0, r0, #0x1000			@ ...1 .... .... ....
-#endif
 	mov	pc, lr
 	.size	__arm925_setup, . - __arm925_setup
 
+	/*
+	 *  R
+	 * .RVI ZFRS BLDP WCAM
+	 * .011 0001 ..11 1101
+	 * 
+	 */
+	.type	arm925_cr1_clear, #object
+	.type	arm925_cr1_set, #object
+arm925_cr1_clear:
+	.word	0x7f3f
+arm925_cr1_set:
+	.word	0x313d
+
 	__INITDATA
 
 /*
@@ -536,7 +527,10 @@
 __arm925_proc_info:
 	.long	0x54029250
 	.long	0xfffffff0
-	.long	0x00000c12			@ mmuflags
+	.long   PMD_TYPE_SECT | \
+		PMD_BIT4 | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ
 	b	__arm925_setup
 	.long	cpu_arch_name
 	.long	cpu_elf_name
@@ -552,7 +546,10 @@
 __arm915_proc_info:
 	.long	0x54029150
 	.long	0xfffffff0
-	.long	0x00000c12			@ mmuflags
+	.long   PMD_TYPE_SECT | \
+		PMD_BIT4 | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ
 	b	__arm925_setup
 	.long	cpu_arch_name
 	.long	cpu_elf_name
diff -Nru a/arch/arm/mm/proc-arm926.S b/arch/arm/mm/proc-arm926.S
--- a/arch/arm/mm/proc-arm926.S	2005-03-01 23:38:58 -08:00
+++ b/arch/arm/mm/proc-arm926.S	2005-03-01 23:38:58 -08:00
@@ -388,7 +388,6 @@
 	mcr	p15, 0, r0, c7, c7		@ invalidate I,D caches on v4
 	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer on v4
 	mcr	p15, 0, r0, c8, c7		@ invalidate I,D TLBs on v4
-	mcr	p15, 0, r4, c2, c0		@ load page table pointer
 
 
 #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
@@ -396,35 +395,30 @@
 	mcr	p15, 7, r0, c15, c0, 0
 #endif 
 
-	mov	r0, #0x1f			@ Domains 0, 1 = client
-	mcr	p15, 0, r0, c3, c0		@ load domain access register
 	mrc	p15, 0, r0, c1, c0		@ get control register v4
-/*
- * Clear out 'unwanted' bits (then put them in if we need them)
- */
-						@   VI ZFRS BLDP WCAM
-	bic	r0, r0, #0x0e00
-	bic	r0, r0, #0x0002
-	bic	r0, r0, #0x000c
-	bic	r0, r0, #0x1000			@ ...0 000. .... 000.
-/*
- * Turn on what we want
- */
-	orr	r0, r0, #0x0031
-	orr	r0, r0, #0x2100			@ ..1. ...1 ..11 ...1
-
+	ldr	r5, arm926_cr1_clear
+	bic	r0, r0, r5
+	ldr	r5, arm926_cr1_set
+	orr	r0, r0, r5
 #ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
 	orr	r0, r0, #0x4000			@ .1.. .... .... ....
 #endif
-#ifndef CONFIG_CPU_DCACHE_DISABLE
-	orr	r0, r0, #0x0004			@ .... .... .... .1..
-#endif
-#ifndef CONFIG_CPU_ICACHE_DISABLE
-	orr	r0, r0, #0x1000			@ ...1 .... .... ....
-#endif
 	mov	pc, lr
 	.size	__arm926_setup, . - __arm926_setup
 
+	/*
+	 *  R
+	 * .RVI ZFRS BLDP WCAM
+	 * .011 0001 ..11 0101
+	 * 
+	 */
+	.type	arm926_cr1_clear, #object
+	.type	arm926_cr1_set, #object
+arm926_cr1_clear:
+	.word	0x7f3f
+arm926_cr1_set:
+	.word	0x3135
+
 	__INITDATA
 
 /*
@@ -483,7 +477,12 @@
 __arm926_proc_info:
 	.long	0x41069260			@ ARM926EJ-S (v5TEJ)
 	.long	0xff0ffff0
-	.long	0x00000c1e			@ mmuflags
+	.long   PMD_TYPE_SECT | \
+		PMD_SECT_BUFFERABLE | \
+		PMD_SECT_CACHEABLE | \
+		PMD_BIT4 | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ
 	b	__arm926_setup
 	.long	cpu_arch_name
 	.long	cpu_elf_name
diff -Nru a/arch/arm/mm/proc-sa110.S b/arch/arm/mm/proc-sa110.S
--- a/arch/arm/mm/proc-sa110.S	2005-03-01 23:38:57 -08:00
+++ b/arch/arm/mm/proc-sa110.S	2005-03-01 23:38:57 -08:00
@@ -186,21 +186,31 @@
 
 	.type	__sa110_setup, #function
 __sa110_setup:
-	mrc	p15, 0, r0, c1, c0		@ get control register v4
-	bic	r0, r0, #0x2e00			@ ..VI ZFRS BLDP WCAM
-	bic	r0, r0, #0x0002			@ ..0. 000. .... ..0.
-	orr	r0, r0, #0x003d
-	orr	r0, r0, #0x1100			@ ...1 ...1 ..11 11.1
 	mov	r10, #0
 	mcr	p15, 0, r10, c7, c7		@ invalidate I,D caches on v4
 	mcr	p15, 0, r10, c7, c10, 4		@ drain write buffer on v4
 	mcr	p15, 0, r10, c8, c7		@ invalidate I,D TLBs on v4
-	mcr	p15, 0, r4, c2, c0		@ load page table pointer
-	mov	r10, #0x1f			@ Domains 0, 1 = client
-	mcr	p15, 0, r10, c3, c0		@ load domain access register
+	mrc	p15, 0, r0, c1, c0		@ get control register v4
+	ldr	r5, sa110_cr1_clear
+	bic	r0, r0, r5
+	ldr	r5, sa110_cr1_set
+	orr	r0, r0, r5
 	mov	pc, lr
 	.size	__sa110_setup, . - __sa110_setup
 
+	/*
+	 *  R
+	 * .RVI ZFRS BLDP WCAM
+	 * ..01 0001 ..11 1101
+	 * 
+	 */
+	.type	sa110_cr1_clear, #object
+	.type	sa110_cr1_set, #object
+sa110_cr1_clear:
+	.word	0x3f3f
+sa110_cr1_set:
+	.word	0x113d
+
 	__INITDATA
 
 /*
@@ -245,7 +255,11 @@
 __sa110_proc_info:
 	.long	0x4401a100
 	.long	0xfffffff0
-	.long	0x00000c0e
+	.long   PMD_TYPE_SECT | \
+		PMD_SECT_BUFFERABLE | \
+		PMD_SECT_CACHEABLE | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ
 	b	__sa110_setup
 	.long	cpu_arch_name
 	.long	cpu_elf_name
diff -Nru a/arch/arm/mm/proc-sa1100.S b/arch/arm/mm/proc-sa1100.S
--- a/arch/arm/mm/proc-sa1100.S	2005-03-01 23:39:08 -08:00
+++ b/arch/arm/mm/proc-sa1100.S	2005-03-01 23:39:08 -08:00
@@ -209,21 +209,31 @@
 
 	.type	__sa1100_setup, #function
 __sa1100_setup:
-	mov	r10, #0
-	mcr	p15, 0, r10, c7, c7		@ invalidate I,D caches on v4
-	mcr	p15, 0, r10, c7, c10, 4		@ drain write buffer on v4
-	mcr	p15, 0, r10, c8, c7		@ invalidate I,D TLBs on v4
-	mov	r0, #0x1f			@ Domains 0, 1 = client
-	mcr	p15, 0, r0, c3, c0		@ load domain access register
-	mcr	p15, 0, r4, c2, c0		@ load page table pointer
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c7		@ invalidate I,D caches on v4
+	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer on v4
+	mcr	p15, 0, r0, c8, c7		@ invalidate I,D TLBs on v4
 	mrc	p15, 0, r0, c1, c0		@ get control register v4
-	bic	r0, r0, #0x0e00			@ ..VI ZFRS BLDP WCAM
-	bic	r0, r0, #0x0002			@ .... 000. .... ..0.
-	orr	r0, r0, #0x003d
-	orr	r0, r0, #0x3100			@ ..11 ...1 ..11 11.1
+	ldr	r5, sa1100_cr1_clear
+	bic	r0, r0, r5
+	ldr	r5, sa1100_cr1_set
+	orr	r0, r0, r5
 	mov	pc, lr
 	.size	__sa1100_setup, . - __sa1100_setup
 
+	/*
+	 *  R
+	 * .RVI ZFRS BLDP WCAM
+	 * ..11 0001 ..11 1101
+	 * 
+	 */
+	.type	sa1100_cr1_clear, #object
+	.type	sa1100_cr1_set, #object
+sa1100_cr1_clear:
+	.word	0x3f3f
+sa1100_cr1_set:
+	.word	0x313d
+
 	__INITDATA
 
 /*
@@ -276,7 +286,11 @@
 __sa1100_proc_info:
 	.long	0x4401a110
 	.long	0xfffffff0
-	.long	0x00000c0e
+	.long   PMD_TYPE_SECT | \
+		PMD_SECT_BUFFERABLE | \
+		PMD_SECT_CACHEABLE | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ
 	b	__sa1100_setup
 	.long	cpu_arch_name
 	.long	cpu_elf_name
@@ -292,7 +306,11 @@
 __sa1110_proc_info:
 	.long	0x6901b110
 	.long	0xfffffff0
-	.long	0x00000c0e
+	.long   PMD_TYPE_SECT | \
+		PMD_SECT_BUFFERABLE | \
+		PMD_SECT_CACHEABLE | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ
 	b	__sa1100_setup
 	.long	cpu_arch_name
 	.long	cpu_elf_name
diff -Nru a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S
--- a/arch/arm/mm/proc-v6.S	2005-03-01 23:38:44 -08:00
+++ b/arch/arm/mm/proc-v6.S	2005-03-01 23:38:44 -08:00
@@ -105,6 +105,7 @@
 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, 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
@@ -189,27 +190,24 @@
  *	- cache type register is implemented
  */
 __v6_setup:
-	mov	r10, #0
-	mcr	p15, 0, r10, c7, c14, 0		@ clean+invalidate D cache
-	mcr	p15, 0, r10, c7, c5, 0		@ invalidate I cache
-	mcr	p15, 0, r10, c7, c15, 0		@ clean+invalidate cache
-	mcr	p15, 0, r10, c7, c10, 4		@ drain write buffer
-	mcr	p15, 0, r10, c8, c7, 0		@ invalidate I + D TLBs
-	mcr	p15, 0, r10, c2, c0, 2		@ TTB control register
-	mcr	p15, 0, r4, c2, c0, 0		@ load TTB0
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c14, 0		@ clean+invalidate D cache
+	mcr	p15, 0, r0, c7, c5, 0		@ invalidate I cache
+	mcr	p15, 0, r0, c7, c15, 0		@ clean+invalidate cache
+	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer
+	mcr	p15, 0, r0, c8, c7, 0		@ invalidate I + D TLBs
+	mcr	p15, 0, r0, c2, c0, 2		@ TTB control register
 	mcr	p15, 0, r4, c2, c0, 1		@ load TTB1
-	mov	r10, #0x1f			@ domains 0, 1 = manager
-	mcr	p15, 0, r10, c3, c0, 0		@ load domain access register
-	mrc	p15, 0, r0, c1, c0, 0		@ read control register
 #ifdef CONFIG_VFP
-	mrc	p15, 0, r10, c1, c0, 2
-	orr	r10, r10, #(3 << 20)
-	mcr	p15, 0, r10, c1, c0, 2		@ Enable full access to VFP
+	mrc	p15, 0, r0, c1, c0, 2
+	orr	r0, r0, #(3 << 20)
+	mcr	p15, 0, r0, c1, c0, 2		@ Enable full access to VFP
 #endif
-	ldr	r10, cr1_clear			@ get mask for bits to clear
-	bic	r0, r0, r10			@ clear bits them
-	ldr	r10, cr1_set			@ get mask for bits to set
-	orr	r0, r0, r10			@ set them
+	mrc	p15, 0, r0, c1, c0, 0		@ read control register
+	ldr	r5, v6_cr1_clear		@ get mask for bits to clear
+	bic	r0, r0, r5			@ clear bits them
+	ldr	r5, v6_cr1_set			@ get mask for bits to set
+	orr	r0, r0, r5			@ set them
 	mov	pc, lr				@ return to head.S:__ret
 
 	/*
@@ -218,11 +216,11 @@
 	 * rrrr rrrx xxx0 0101 xxxx xxxx x111 xxxx < forced
 	 *         0 110       0011 1.00 .111 1101 < we want
 	 */
-	.type	cr1_clear, #object
-	.type	cr1_set, #object
-cr1_clear:
-	.word	0x0120c302
-cr1_set:
+	.type	v6_cr1_clear, #object
+	.type	v6_cr1_set, #object
+v6_cr1_clear:
+	.word	0x01e0fb7f
+v6_cr1_set:
 	.word	0x00c0387d
 
 	.type	v6_processor_functions, #object
@@ -257,7 +255,11 @@
 __v6_proc_info:
 	.long	0x0007b000
 	.long	0x0007f000
-	.long	0x00000c0e
+	.long   PMD_TYPE_SECT | \
+		PMD_SECT_BUFFERABLE | \
+		PMD_SECT_CACHEABLE | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ
 	b	__v6_setup
 	.long	cpu_arch_name
 	.long	cpu_elf_name
diff -Nru a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S
--- a/arch/arm/mm/proc-xscale.S	2005-03-01 23:39:09 -08:00
+++ b/arch/arm/mm/proc-xscale.S	2005-03-01 23:39:09 -08:00
@@ -594,14 +594,9 @@
 
 	.type	__xscale_setup, #function
 __xscale_setup:
-	mov	r0, #PSR_F_BIT|PSR_I_BIT|SVC_MODE
-	msr	cpsr_c, r0
 	mcr	p15, 0, ip, c7, c7, 0		@ invalidate I, D caches & BTB
 	mcr	p15, 0, ip, c7, c10, 4		@ Drain Write (& Fill) Buffer
 	mcr	p15, 0, ip, c8, c7, 0		@ invalidate I, D TLBs
-	mcr	p15, 0, r4, c2, c0, 0		@ load page table pointer
-	mov	r0, #0x1f			@ Domains 0, 1 = client
-	mcr	p15, 0, r0, c3, c0, 0		@ load domain access register
 #ifdef CONFIG_IWMMXT
 	mov	r0, #0				@ initially disallow access to CP0/CP1
 #else
@@ -611,13 +606,26 @@
 	orr	r0, r0, #1 << 13		@ Its undefined whether this
 	mcr	p15, 0, r0, c15, c1, 0		@ affects USR or SVC modes
 	mrc	p15, 0, r0, c1, c0, 0		@ get control register
-	bic	r0, r0, #0x0200			@ .... ..R. .... ....
-	bic	r0, r0, #0x0002			@ .... .... .... ..A.
-	orr	r0, r0, #0x0005			@ .... .... .... .C.M
-	orr	r0, r0, #0x3900			@ ..VI Z..S .... ....
+	ldr	r5, xscale_cr1_clear
+	bic	r0, r0, r5
+	ldr	r5, xscale_cr1_set
+	orr	r0, r0, r5
 	mov	pc, lr
 	.size	__xscale_setup, . - __xscale_setup
 
+	/*
+	 *  R
+	 * .RVI ZFRS BLDP WCAM
+	 * ..11 1.01 .... .101
+	 * 
+	 */
+	.type	xscale_cr1_clear, #object
+	.type	xscale_cr1_set, #object
+xscale_cr1_clear:
+	.word	0x3b07
+xscale_cr1_set:
+	.word	0x3905
+
 	__INITDATA
 
 /*
@@ -712,7 +720,11 @@
 __80200_proc_info:
 	.long	0x69052000
 	.long	0xfffffff0
-	.long	0x00000c0e
+	.long   PMD_TYPE_SECT | \
+		PMD_SECT_BUFFERABLE | \
+		PMD_SECT_CACHEABLE | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ
 	b	__xscale_setup
 	.long	cpu_arch_name
 	.long	cpu_elf_name
@@ -728,7 +740,11 @@
 __8032x_proc_info:
 	.long	0x69052420
 	.long	0xfffff5e0      @ mask should accomodate IOP80219 also
-	.long	0x00000c0e
+	.long   PMD_TYPE_SECT | \
+		PMD_SECT_BUFFERABLE | \
+		PMD_SECT_CACHEABLE | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ
 	b	__xscale_setup
 	.long	cpu_arch_name
 	.long	cpu_elf_name
@@ -742,9 +758,13 @@
 
 	.type	__8033x_proc_info,#object
 __8033x_proc_info:
-	.long	0x69054090
-	.long	0xffffffb0
-	.long	0x00000c0e
+	.long	0x69054010
+	.long	0xffffff30
+	.long   PMD_TYPE_SECT | \
+		PMD_SECT_BUFFERABLE | \
+		PMD_SECT_CACHEABLE | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ
 	b	__xscale_setup
 	.long	cpu_arch_name
 	.long	cpu_elf_name
@@ -760,7 +780,11 @@
 __pxa250_proc_info:
 	.long	0x69052100
 	.long	0xfffff7f0
-	.long	0x00000c0e
+	.long   PMD_TYPE_SECT | \
+		PMD_SECT_BUFFERABLE | \
+		PMD_SECT_CACHEABLE | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ
 	b	__xscale_setup
 	.long	cpu_arch_name
 	.long	cpu_elf_name
@@ -776,7 +800,11 @@
 __pxa210_proc_info:
 	.long	0x69052120
 	.long	0xfffff3f0
-	.long	0x00000c0e
+	.long   PMD_TYPE_SECT | \
+		PMD_SECT_BUFFERABLE | \
+		PMD_SECT_CACHEABLE | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ
 	b	__xscale_setup
 	.long	cpu_arch_name
 	.long	cpu_elf_name
@@ -792,7 +820,11 @@
 __ixp2400_proc_info:
 	.long   0x69054190
 	.long   0xfffffff0
-	.long   0x00000c0e
+	.long   PMD_TYPE_SECT | \
+		PMD_SECT_BUFFERABLE | \
+		PMD_SECT_CACHEABLE | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ
 	b       __xscale_setup
 	.long   cpu_arch_name
 	.long   cpu_elf_name
@@ -808,7 +840,11 @@
 __ixp2800_proc_info:
 	.long   0x690541a0
 	.long   0xfffffff0
-	.long   0x00000c0e
+	.long   PMD_TYPE_SECT | \
+		PMD_SECT_BUFFERABLE | \
+		PMD_SECT_CACHEABLE | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ
 	b       __xscale_setup
 	.long   cpu_arch_name
 	.long   cpu_elf_name
@@ -824,7 +860,11 @@
 __ixp42x_proc_info:
 	.long   0x690541c0
 	.long   0xffffffc0
-	.long   0x00000c0e
+	.long   PMD_TYPE_SECT | \
+		PMD_SECT_BUFFERABLE | \
+		PMD_SECT_CACHEABLE | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ
 	b       __xscale_setup
 	.long   cpu_arch_name
 	.long   cpu_elf_name
@@ -856,7 +896,11 @@
 __pxa255_proc_info:
 	.long	0x69052d00
 	.long	0xfffffff0
-	.long	0x00000c0e
+	.long   PMD_TYPE_SECT | \
+		PMD_SECT_BUFFERABLE | \
+		PMD_SECT_CACHEABLE | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ
 	b	__xscale_setup
 	.long	cpu_arch_name
 	.long	cpu_elf_name
@@ -872,7 +916,11 @@
 __pxa270_proc_info:
 	.long	0x69054110
 	.long	0xfffffff0
-	.long	0x00000c0e
+	.long   PMD_TYPE_SECT | \
+		PMD_SECT_BUFFERABLE | \
+		PMD_SECT_CACHEABLE | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ
 	b	__xscale_setup
 	.long	cpu_arch_name
 	.long	cpu_elf_name
diff -Nru a/arch/arm/mm/tlb-v4.S b/arch/arm/mm/tlb-v4.S
--- a/arch/arm/mm/tlb-v4.S	2005-03-01 23:38:55 -08:00
+++ b/arch/arm/mm/tlb-v4.S	2005-03-01 23:38:55 -08:00
@@ -44,7 +44,7 @@
 	mov	pc, lr
 
 /*
- *	v4_flush_kerm_tlb_range(start, end)
+ *	v4_flush_kern_tlb_range(start, end)
  *
  *	Invalidate a range of TLB entries in the specified kernel
  *	address range.
diff -Nru a/arch/arm/mm/tlb-v4wb.S b/arch/arm/mm/tlb-v4wb.S
--- a/arch/arm/mm/tlb-v4wb.S	2005-03-01 23:38:54 -08:00
+++ b/arch/arm/mm/tlb-v4wb.S	2005-03-01 23:38:54 -08:00
@@ -47,7 +47,7 @@
 	mov	pc, lr
 
 /*
- *	v4_flush_kerm_tlb_range(start, end)
+ *	v4_flush_kern_tlb_range(start, end)
  *
  *	Invalidate a range of TLB entries in the specified kernel
  *	address range.
diff -Nru a/arch/arm/oprofile/common.c b/arch/arm/oprofile/common.c
--- a/arch/arm/oprofile/common.c	2005-03-01 23:39:10 -08:00
+++ b/arch/arm/oprofile/common.c	2005-03-01 23:39:10 -08:00
@@ -11,6 +11,7 @@
 #include <linux/oprofile.h>
 #include <linux/errno.h>
 #include <asm/semaphore.h>
+#include <linux/sysdev.h>
 
 #include "op_counter.h"
 #include "op_arm_model.h"
@@ -24,15 +25,27 @@
 static void pmu_stop(void);
 static int pmu_create_files(struct super_block *, struct dentry *);
 
-static struct oprofile_operations pmu_ops = {
-	.create_files	= pmu_create_files,
-	.setup		= pmu_setup,
-	.shutdown	= pmu_stop,
-	.start		= pmu_start,
-	.stop		= pmu_stop,
+#ifdef CONFIG_PM
+static int pmu_suspend(struct sys_device *dev, u32 state)
+{
+	if (pmu_enabled)
+		pmu_stop();
+	return 0;
+}
+
+static int pmu_resume(struct sys_device *dev)
+{
+	if (pmu_enabled)
+		pmu_start();
+	return 0;
+}
+
+static struct sysdev_class oprofile_sysclass = {
+	set_kset_name("oprofile"),
+	.resume		= pmu_resume,
+	.suspend	= pmu_suspend,
 };
 
-#ifdef CONFIG_PM
 static struct sys_device device_oprofile = {
 	.id		= 0,
 	.cls		= &oprofile_sysclass,
@@ -43,14 +56,14 @@
 	int ret;
 
 	if (!(ret = sysdev_class_register(&oprofile_sysclass)))
-		ret = sys_device_register(&device_oprofile);
+		ret = sysdev_register(&device_oprofile);
 
 	return ret;
 }
 
-static void __exit exit_driverfs(void)
+static void  exit_driverfs(void)
 {
-	sys_device_unregister(&device_oprofile);
+	sysdev_unregister(&device_oprofile);
 	sysdev_class_unregister(&oprofile_sysclass);
 }
 #else
@@ -113,7 +126,7 @@
 	up(&pmu_sem);
 }
 
-int __init pmu_init(struct oprofile_operations **ops, struct op_arm_model_spec *spec)
+int __init pmu_init(struct oprofile_operations *ops, struct op_arm_model_spec *spec)
 {
 	init_MUTEX(&pmu_sem);
 
@@ -122,9 +135,14 @@
 
 	pmu_model = spec;
 	init_driverfs();
-	*ops = &pmu_ops;
-	pmu_ops.cpu_type = pmu_model->name;
+	ops->create_files = pmu_create_files;
+	ops->setup = pmu_setup;
+	ops->shutdown = pmu_stop;
+	ops->start = pmu_start;
+	ops->stop = pmu_stop;
+	ops->cpu_type = pmu_model->name;
 	printk(KERN_INFO "oprofile: using %s PMU\n", spec->name);
+
 	return 0;
 }
 
diff -Nru a/arch/arm/oprofile/init.c b/arch/arm/oprofile/init.c
--- a/arch/arm/oprofile/init.c	2005-03-01 23:38:54 -08:00
+++ b/arch/arm/oprofile/init.c	2005-03-01 23:38:54 -08:00
@@ -12,13 +12,14 @@
 #include <linux/errno.h>
 #include "op_arm_model.h"
 
-int __init oprofile_arch_init(struct oprofile_operations **ops)
+int __init oprofile_arch_init(struct oprofile_operations *ops)
 {
 	int ret = -ENODEV;
 
 #ifdef CONFIG_CPU_XSCALE
 	ret = pmu_init(ops, &op_xscale_spec);
 #endif
+
 	return ret;
 }
 
diff -Nru a/arch/arm/oprofile/op_arm_model.h b/arch/arm/oprofile/op_arm_model.h
--- a/arch/arm/oprofile/op_arm_model.h	2005-03-01 23:39:07 -08:00
+++ b/arch/arm/oprofile/op_arm_model.h	2005-03-01 23:39:07 -08:00
@@ -24,6 +24,6 @@
 extern struct op_arm_model_spec op_xscale_spec;
 #endif
 
-extern int pmu_init(struct oprofile_operations **ops, struct op_arm_model_spec *spec);
+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 -Nru a/arch/arm/oprofile/op_model_xscale.c b/arch/arm/oprofile/op_model_xscale.c
--- a/arch/arm/oprofile/op_model_xscale.c	2005-03-01 23:38:58 -08:00
+++ b/arch/arm/oprofile/op_model_xscale.c	2005-03-01 23:38:58 -08:00
@@ -42,6 +42,9 @@
 #ifdef CONFIG_ARCH_IOP331
 #define XSCALE_PMU_IRQ  IRQ_IOP331_CORE_PMU
 #endif
+#ifdef CONFIG_ARCH_PXA
+#define XSCALE_PMU_IRQ  IRQ_PMU
+#endif
 
 /*
  * Different types of events that can be counted by the XScale PMU
@@ -305,9 +308,9 @@
 	/*       Overflow bit gets cleared. There's no workaround.	 */
 	/*	 Fixed in B stepping or later			 	 */
 
-	pmnc &= ~(PMU_ENABLE | pmu->cnt_ovf[PMN0] | pmu->cnt_ovf[PMN1] |
-		pmu->cnt_ovf[CCNT]);
-	write_pmnc(pmnc);
+	/* Write the value back to clear the overflow flags. Overflow */
+	/* flags remain in pmnc for use below */
+	write_pmnc(pmnc & ~PMU_ENABLE);
 
 	for (i = CCNT; i <= PMN1; i++) {
 		if (!(pmu->int_mask[i] & pmu->int_enable))
@@ -343,8 +346,7 @@
 
 static irqreturn_t xscale_pmu_interrupt(int irq, void *arg, struct pt_regs *regs)
 {
-	unsigned long pc = profile_pc(regs);
-	int i, is_kernel = !user_mode(regs);
+	int i;
 	u32 pmnc;
 
 	if (pmu->id == PMU_XSC1)
@@ -357,7 +359,7 @@
 			continue;
 
 		write_counter(i, -(u32)results[i].reset_counter);
-		oprofile_add_sample(pc, is_kernel, i, smp_processor_id());
+		oprofile_add_sample(regs, i);
 		results[i].ovf--;
 	}
 
diff -Nru a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types
--- a/arch/arm/tools/mach-types	2005-03-01 23:38:57 -08:00
+++ b/arch/arm/tools/mach-types	2005-03-01 23:38:57 -08:00
@@ -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: Sun Nov 7 13:20:41 2004
+# Last update: Thu Jan 6 00:10:23 2005
 #
 # machine_is_xxx	CONFIG_xxxx		MACH_TYPE_xxx		number
 #
@@ -226,7 +226,7 @@
 pnp1110			SA1100_PNP1110		PNP1110			215
 csb226			ARCH_CSB226		CSB226			216
 arnold			SA1100_ARNOLD		ARNOLD			217
-psiboard		SA1100_PSIBOARD		PSIBOARD		218
+voiceblue		SA1100_PSIBOARD		PSIBOARD		218
 jz8028			ARCH_JZ8028		JZ8028			219
 h5400			ARCH_H5400		H5400			220
 forte			SA1100_FORTE		FORTE			221
@@ -250,8 +250,8 @@
 pdb			ARCH_PDB		PDB			239
 blue_2g			SA1100_BLUE_2G		BLUE_2G			240
 bluearch		SA1100_BLUEARCH		BLUEARCH		241
-ixdp2400		ARCH_IXDB2400		IXDB2400		242
-ixdp2800		ARCH_IXDB2800		IXDB2800		243
+ixdp2400		ARCH_IXDP2400		IXDP2400		242
+ixdp2800		ARCH_IXDP2800		IXDP2800		243
 explorer		SA1100_EXPLORER		EXPLORER		244
 ixdp425			ARCH_IXDP425		IXDP425			245
 chimp			ARCH_CHIMP		CHIMP			246
@@ -634,3 +634,36 @@
 cm4008			MACH_CM4008		CM4008			624
 p2001			MACH_P2001		P2001			625
 twister			MACH_TWISTER		TWISTER			626
+mudshark		MACH_MUDSHARK		MUDSHARK		627
+hb2			MACH_HB2		HB2			628
+iq80332			MACH_IQ80332		IQ80332			629
+sendt			MACH_SENDT		SENDT			630
+mx2jazz			MACH_MX2JAZZ		MX2JAZZ			631
+multiio			MACH_MULTIIO		MULTIIO			632
+hrdisplay		MACH_HRDISPLAY		HRDISPLAY		633
+scma11bb		MACH_SCMA11BB		SCMA11BB		634
+trizeps3		MACH_TRIZEPS3		TRIZEPS3		635
+zefeerdza		MACH_ZEFEERDZA		ZEFEERDZA		636
+zefeerdzb		MACH_ZEFEERDZB		ZEFEERDZB		637
+zefeerdzg		MACH_ZEFEERDZG		ZEFEERDZG		638
+zefeerdzn		MACH_ZEFEERDZN		ZEFEERDZN		639
+zefeerdzq		MACH_ZEFEERDZQ		ZEFEERDZQ		640
+gtwx5715		MACH_GTWX5715		GTWX5715		641
+unknown			MACH_VL420		VL420			642
+astro_jack		MACH_ASTRO_JACK		ASTRO_JACK		643
+tip03			MACH_TIP03		TIP03			644
+a9200ec			MACH_A9200EC		A9200EC			645
+pnx0105			MACH_PNX0105		PNX0105			646
+adcpoecpu		MACH_ADCPOECPU		ADCPOECPU		647
+csb637			MACH_CSB637		CSB637			648
+ml69q6203		MACH_ML69Q6203		ML69Q6203		649
+mb9200			MACH_MB9200		MB9200			650
+kulun			MACH_KULUN		KULUN			651
+snapper			MACH_SNAPPER		SNAPPER			652
+optima			MACH_OPTIMA		OPTIMA			653
+dlhsbc			MACH_DLHSBC		DLHSBC			654
+x30			MACH_X30		X30			655
+n30			MACH_N30		N30			656
+manga_ks8695		MACH_MANGA_KS8695	MANGA_KS8695		657
+ajax			MACH_AJAX		AJAX			658
+nec_mp900		MACH_NEC_MP900		NEC_MP900		659
diff -Nru a/arch/arm/vfp/entry.S b/arch/arm/vfp/entry.S
--- a/arch/arm/vfp/entry.S	2005-03-01 23:39:09 -08:00
+++ b/arch/arm/vfp/entry.S	2005-03-01 23:39:09 -08:00
@@ -17,7 +17,7 @@
  */
 #include <linux/linkage.h>
 #include <linux/init.h>
-#include <asm/thread_info.h>
+#include <asm/constants.h>
 #include <asm/vfpmacros.h>
 
 	.globl	do_vfp
diff -Nru a/arch/arm/vfp/vfphw.S b/arch/arm/vfp/vfphw.S
--- a/arch/arm/vfp/vfphw.S	2005-03-01 23:38:53 -08:00
+++ b/arch/arm/vfp/vfphw.S	2005-03-01 23:38:53 -08:00
@@ -62,14 +62,14 @@
 @ VFP hardware support entry point.
 @
 @  r0  = faulted instruction
-@  r5  = faulted PC+4
+@  r2  = faulted PC+4
 @  r9  = successful return
 @  r10 = vfp_state union
 @  lr  = failure return
 
 	.globl	vfp_support_entry
 vfp_support_entry:
-	DBGSTR3	"instr %08x pc %08x state %p", r0, r5, r10
+	DBGSTR3	"instr %08x pc %08x state %p", r0, r2, r10
 
 	VFPFMRX	r1, FPEXC		@ Is the VFP enabled?
 	DBGSTR1	"fpexc %08x", r1
@@ -80,14 +80,14 @@
 	ldr	r3, last_VFP_context_address
 	orr	r1, r1, #FPEXC_ENABLE	@ user FPEXC has the enable bit set
 	ldr	r4, [r3]		@ last_VFP_context pointer
-	bic	r2, r1, #FPEXC_EXCEPTION @ make sure exceptions are disabled
+	bic	r5, r1, #FPEXC_EXCEPTION @ make sure exceptions are disabled
 	cmp	r4, r10
 	beq	check_for_exception	@ we are returning to the same
 					@ process, so the registers are
 					@ still there.  In this case, we do
 					@ not want to drop a pending exception.
 
-	VFPFMXR	FPEXC, r2		@ enable VFP, disable any pending
+	VFPFMXR	FPEXC, r5		@ enable VFP, disable any pending
 					@ exceptions, so we can get at the
 					@ rest of it
 
@@ -96,14 +96,14 @@
 	DBGSTR1	"save old state %p", r4
 	cmp	r4, #0
 	beq	no_old_VFP_process
-	VFPFMRX	r2, FPSCR		@ current status
+	VFPFMRX	r5, FPSCR		@ current status
 	VFPFMRX	r6, FPINST		@ FPINST (always there, rev0 onwards)
 	tst	r1, #FPEXC_FPV2		@ is there an FPINST2 to read?
 	VFPFMRX	r8, FPINST2, NE		@ FPINST2 if needed - avoids reading
 					@ nonexistant reg on rev0
 	VFPFSTMIA r4 			@ save the working registers
 	add	r4, r4, #8*16+4
-	stmia	r4, {r1, r2, r6, r8}	@ save FPEXC, FPSCR, FPINST, FPINST2
+	stmia	r4, {r1, r5, r6, r8}	@ save FPEXC, FPSCR, FPINST, FPINST2
 					@ and point r4 at the word at the
 					@ start of the register dump
 
@@ -112,14 +112,14 @@
 	str	r10, [r3]		@ update the last_VFP_context pointer
 					@ Load the saved state back into the VFP
 	add	r4, r10, #8*16+4
-	ldmia	r4, {r1, r2, r6, r8}	@ load FPEXC, FPSCR, FPINST, FPINST2
+	ldmia	r4, {r1, r5, r6, r8}	@ load FPEXC, FPSCR, FPINST, FPINST2
 	VFPFLDMIA r10	 		@ reload the working registers while
 					@ FPEXC is in a safe state
 	tst	r1, #FPEXC_FPV2		@ is there an FPINST2 to write?
 	VFPFMXR	FPINST2, r8, NE		@ FPINST2 if needed - avoids writing
 					@ nonexistant reg on rev0
 	VFPFMXR	FPINST, r6
-	VFPFMXR	FPSCR, r2		@ restore status
+	VFPFMXR	FPSCR, r5		@ restore status
 
 check_for_exception:
 	tst	r1, #FPEXC_EXCEPTION
@@ -128,16 +128,16 @@
 					@ out before setting an FPEXC that
 					@ stops us reading stuff
 	VFPFMXR	FPEXC, r1		@ restore FPEXC last
-	sub	r5, r5, #4
-	str	r5, [sp, #S_PC]		@ retry the instruction
+	sub	r2, r2, #4
+	str	r2, [sp, #S_PC]		@ retry the instruction
 	mov	pc, r9			@ we think we have handled things
 
 
 look_for_VFP_exceptions:
 	tst	r1, #FPEXC_EXCEPTION
 	bne	process_exception
-	VFPFMRX	r2, FPSCR
-	tst	r2, #FPSCR_IXE		@ IXE doesn't set FPEXC_EXCEPTION !
+	VFPFMRX	r5, FPSCR
+	tst	r5, #FPSCR_IXE		@ IXE doesn't set FPEXC_EXCEPTION !
 	bne	process_exception
 
 	@ Fall into hand on to next handler - appropriate coproc instr
@@ -148,8 +148,8 @@
 
 process_exception:
 	DBGSTR	"bounce"
-	sub	r5, r5, #4
-	str	r5, [sp, #S_PC]		@ retry the instruction on exit from
+	sub	r2, r2, #4
+	str	r2, [sp, #S_PC]		@ retry the instruction on exit from
 					@ the imprecise exception handling in
 					@ the support code
 	mov	r2, sp			@ nothing stacked - regdump is at TOS
diff -Nru a/arch/arm26/ACKNOWLEDGEMENTS b/arch/arm26/ACKNOWLEDGEMENTS
--- a/arch/arm26/ACKNOWLEDGEMENTS	2005-03-01 23:39:17 -08:00
+++ b/arch/arm26/ACKNOWLEDGEMENTS	2005-03-01 23:39:17 -08:00
@@ -15,6 +15,8 @@
 Russell King
 Keith Owens
 
+also thanks to Nicholas Pitre for hints, and for the basis or our XIP support.
+
 Currently maintaing the code are
 
 Ian Molton (Maintainer / Archimedes)
diff -Nru a/arch/arm26/Kconfig b/arch/arm26/Kconfig
--- a/arch/arm26/Kconfig	2005-03-01 23:38:58 -08:00
+++ b/arch/arm26/Kconfig	2005-03-01 23:38:58 -08:00
@@ -45,6 +45,10 @@
 config RWSEM_XCHGADD_ALGORITHM
 	bool
 
+config GENERIC_CALIBRATE_DELAY
+	bool
+	default y
+
 config GENERIC_BUST_SPINLOCK
 	bool
 
@@ -221,4 +225,3 @@
 source "crypto/Kconfig"
 
 source "lib/Kconfig"
-
diff -Nru a/arch/arm26/Makefile b/arch/arm26/Makefile
--- a/arch/arm26/Makefile	2005-03-01 23:38:56 -08:00
+++ b/arch/arm26/Makefile	2005-03-01 23:38:56 -08:00
@@ -6,6 +6,7 @@
 # for more details.
 #
 # Copyright (C) 1995-2001 by Russell King
+# Copyright (c) 2004 Ian Molton
 
 LDFLAGS_vmlinux	:=-p -X
 CPPFLAGS_vmlinux.lds = -DTEXTADDR=$(TEXTADDR) -DDATAADDR=$(DATAADDR)
@@ -20,13 +21,9 @@
 CFLAGS		+=-g
 endif
 
-# Force -mno-fpu to be passed to the assembler.  Some versions of gcc don't
-# do this with -msoft-float
-CFLAGS_BOOT	:=-mapcs-26 -mcpu=arm3 -mshort-load-bytes -msoft-float -Wa,-mno-fpu -Uarm
-CFLAGS		+=-mapcs-26 -mcpu=arm3 -mshort-load-bytes -msoft-float -Wa,-mno-fpu -Uarm
-AFLAGS		+=-mapcs-26 -mcpu=arm3 -mno-fpu -msoft-float -Wa,-mno-fpu
-
-head-y		:= arch/arm26/machine/head.o arch/arm26/kernel/init_task.o
+CFLAGS_BOOT	:=-mapcs-26 -mcpu=arm3 -msoft-float -Uarm
+CFLAGS		+=-mapcs-26 -mcpu=arm3 -msoft-float -Uarm
+AFLAGS		+=-mapcs-26 -mcpu=arm3 -msoft-float
 
 ifeq ($(CONFIG_XIP_KERNEL),y)
   TEXTADDR	 := 0x03880000
@@ -36,6 +33,8 @@
   DATAADDR       := .
 endif
 
+head-y          := arch/arm26/kernel/head.o arch/arm26/kernel/init_task.o
+
 ifeq ($(incdir-y),)
 incdir-y :=
 endif
@@ -109,6 +108,7 @@
   echo  '* zImage        - Compressed kernel image (arch/$(ARCH)/boot/zImage)'
   echo  '  Image         - Uncompressed kernel image (arch/$(ARCH)/boot/Image)'
   echo  '  bootpImage    - Combined zImage and initial RAM disk' 
+  echo  '  xipImage      - eXecute In Place capable image for ROM use (arch/$(ARCH)/boot/xipImage)'
   echo  '  initrd        - Create an initial image'
   echo  '  install       - Install uncompressed kernel'
   echo  '  zinstall      - Install compressed kernel'
diff -Nru a/arch/arm26/boot/Makefile b/arch/arm26/boot/Makefile
--- a/arch/arm26/boot/Makefile	2005-03-01 23:39:18 -08:00
+++ b/arch/arm26/boot/Makefile	2005-03-01 23:39:18 -08:00
@@ -1,5 +1,5 @@
 #
-# arch/arm/boot/Makefile
+# arch/arm26/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
@@ -51,8 +51,10 @@
 
 ifeq ($(CONFIG_XIP_KERNEL),y)
 $(obj)/xipImage: vmlinux FORCE
-	$(OBJCOPY) -S -O binary -R .data -R .comment vmlinux vmlinux-text.bin
-	$(OBJCOPY) -S -O binary -R .init -R .text -R .comment -R __ex_table -R __ksymtab vmlinux vmlinux-data.bin
+#	$(OBJCOPY) -S -O binary -R .data -R .comment vmlinux vmlinux-text.bin
+# FIXME - where has .pci_fixup crept in from?
+	$(OBJCOPY) -S -O binary -R .data -R .pci_fixup -R .comment vmlinux vmlinux-text.bin
+	$(OBJCOPY) -S -O binary -R .init -R .text -R __ex_table -R .pci_fixup -R __ksymtab -R __ksymtab_gpl -R __kcrctab -R __kcrctab_gpl -R __param -R .comment vmlinux vmlinux-data.bin
 	cat vmlinux-text.bin vmlinux-data.bin > $@
 	$(RM) -f vmlinux-text.bin vmlinux-data.bin
 	@echo '  Kernel: $@ is ready'
diff -Nru a/arch/arm26/boot/compressed/head.S b/arch/arm26/boot/compressed/head.S
--- a/arch/arm26/boot/compressed/head.S	2005-03-01 23:39:09 -08:00
+++ b/arch/arm26/boot/compressed/head.S	2005-03-01 23:39:09 -08:00
@@ -1,5 +1,5 @@
 /*
- *  linux/arch/arm/boot/compressed/head.S
+ *  linux/arch/arm26/boot/compressed/head.S
  *
  *  Copyright (C) 1996-2002 Russell King
  *
diff -Nru a/arch/arm26/boot/compressed/ll_char_wr.S b/arch/arm26/boot/compressed/ll_char_wr.S
--- a/arch/arm26/boot/compressed/ll_char_wr.S	2005-03-01 23:38:51 -08:00
+++ b/arch/arm26/boot/compressed/ll_char_wr.S	2005-03-01 23:38:51 -08:00
@@ -1,5 +1,5 @@
 /*
- *  linux/arch/arm/lib/ll_char_wr.S
+ *  linux/arch/arm26/lib/ll_char_wr.S
  *
  *  Copyright (C) 1995, 1996 Russell King.
  *
diff -Nru a/arch/arm26/boot/compressed/ofw-shark.c b/arch/arm26/boot/compressed/ofw-shark.c
--- a/arch/arm26/boot/compressed/ofw-shark.c	2005-03-01 23:39:18 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,258 +0,0 @@
-/*
- * linux/arch/arm/boot/compressed/ofw-shark.c
- *
- * by Alexander Schulz
- *
- * This file is used to get some basic information
- * about the memory layout of the shark we are running
- * on. Memory is usually divided in blocks a 8 MB.
- * And bootargs are copied from OpenFirmware.
- */
-
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <asm/setup.h>
-#include <asm/page.h>
-
-
-asmlinkage void
-create_params (unsigned long *buffer)
-{
-	/* Is there a better address? Also change in mach-shark/core.c */
-	struct tag *tag = (struct tag *) 0x08003000;
-	int j,i,m,k,nr_banks,size;
-	unsigned char *c;
-
-	/* Head of the taglist */
-	tag->hdr.tag  = ATAG_CORE;
-	tag->hdr.size = tag_size(tag_core);
-	tag->u.core.flags = FLAG_READONLY;
-	tag->u.core.pagesize = PAGE_SIZE;
-	tag->u.core.rootdev = 0;
-
-	/* Build up one tagged block for each memory region */
-	size=0;
-	nr_banks=(unsigned int) buffer[0];
-	for (j=0;j<nr_banks;j++){
-		/* search the lowest address and put it into the next entry   */
-		/* not a fast sort algorithm, but there are at most 8 entries */
-		/* and this is used only once anyway                          */
-		m=0xffffffff;
-		for (i=0;i<(unsigned int) buffer[0];i++){
-			if (buffer[2*i+1]<m) {
-				m=buffer[2*i+1];
-				k=i;
-			}
-		}
-	  
-		tag = tag_next(tag);
-		tag->hdr.tag = ATAG_MEM;
-		tag->hdr.size = tag_size(tag_mem32);
-		tag->u.mem.size = buffer[2*k+2];
-		tag->u.mem.start = buffer[2*k+1];
-
-		size += buffer[2*k+2];
-
-		buffer[2*k+1]=0xffffffff;                    /* mark as copied */
-	}
-	
-	/* The command line */
-	tag = tag_next(tag);
-	tag->hdr.tag = ATAG_CMDLINE;
-	
-	c=(unsigned char *)(&buffer[34]);
-	j=0;
-	while (*c) tag->u.cmdline.cmdline[j++]=*c++;
-
-	tag->u.cmdline.cmdline[j]=0;
-	tag->hdr.size = (j + 7 + sizeof(struct tag_header)) >> 2;
-
-	/* Hardware revision */
-	tag = tag_next(tag);
-	tag->hdr.tag = ATAG_REVISION;
-	tag->hdr.size = tag_size(tag_revision);
-	tag->u.revision.rev = ((unsigned char) buffer[33])-'0';
-
-	/* End of the taglist */
-	tag = tag_next(tag);
-	tag->hdr.tag = 0;
-	tag->hdr.size = 0;
-}
-
-
-typedef int (*ofw_handle_t)(void *);
-
-/* Everything below is called with a wrong MMU setting.
- * This means: no string constants, no initialization of
- * arrays, no global variables! This is ugly but I didn't
- * want to write this in assembler :-)
- */
-
-int
-of_decode_int(const unsigned char *p)
-{
-	unsigned int i = *p++ << 8;
-	i = (i + *p++) << 8;
-	i = (i + *p++) << 8;
-	return (i + *p);
-}
-  
-int
-OF_finddevice(ofw_handle_t openfirmware, char *name)
-{
-	unsigned int args[8];
-	char service[12];
-
-	service[0]='f';
-	service[1]='i';
-	service[2]='n';
-	service[3]='d';
-	service[4]='d';
-	service[5]='e';
-	service[6]='v';
-	service[7]='i';
-	service[8]='c';
-	service[9]='e';
-	service[10]='\0';
-
-	args[0]=(unsigned int)service;
-	args[1]=1;
-	args[2]=1;
-	args[3]=(unsigned int)name;
-
-	if (openfirmware(args) == -1)
-		return -1;
-	return args[4];
-}
-
-int
-OF_getproplen(ofw_handle_t openfirmware, int handle, char *prop)
-{
-	unsigned int args[8];
-	char service[12];
-
-	service[0]='g';
-	service[1]='e';
-	service[2]='t';
-	service[3]='p';
-	service[4]='r';
-	service[5]='o';
-	service[6]='p';
-	service[7]='l';
-	service[8]='e';
-	service[9]='n';
-	service[10]='\0';
-
-	args[0] = (unsigned int)service;
-	args[1] = 2;
-	args[2] = 1;
-	args[3] = (unsigned int)handle;
-	args[4] = (unsigned int)prop;
-
-	if (openfirmware(args) == -1)
-		return -1;
-	return args[5];
-}
-  
-int
-OF_getprop(ofw_handle_t openfirmware, int handle, char *prop, void *buf, unsigned int buflen)
-{
-	unsigned int args[8];
-	char service[8];
-
-	service[0]='g';
-	service[1]='e';
-	service[2]='t';
-	service[3]='p';
-	service[4]='r';
-	service[5]='o';
-	service[6]='p';
-	service[7]='\0';
-
-	args[0] = (unsigned int)service;
-	args[1] = 4;
-	args[2] = 1;
-	args[3] = (unsigned int)handle;
-	args[4] = (unsigned int)prop;
-	args[5] = (unsigned int)buf;
-	args[6] = buflen;
-
-	if (openfirmware(args) == -1)
-		return -1;
-	return args[7];
-}
-  
-asmlinkage void ofw_init(ofw_handle_t o, int *nomr, int *pointer)
-{
-	int phandle,i,mem_len,buffer[32];
-	char temp[15];
-  
-	temp[0]='/';
-	temp[1]='m';
-	temp[2]='e';
-	temp[3]='m';
-	temp[4]='o';
-	temp[5]='r';
-	temp[6]='y';
-	temp[7]='\0';
-
-	phandle=OF_finddevice(o,temp);
-
-	temp[0]='r';
-	temp[1]='e';
-	temp[2]='g';
-	temp[3]='\0';
-
-	mem_len = OF_getproplen(o,phandle, temp);
-	OF_getprop(o,phandle, temp, buffer, mem_len);
-	*nomr=mem_len >> 3;
-
-	for (i=0; i<=mem_len/4; i++) pointer[i]=of_decode_int((const unsigned char *)&buffer[i]);
-
-	temp[0]='/';
-	temp[1]='c';
-	temp[2]='h';
-	temp[3]='o';
-	temp[4]='s';
-	temp[5]='e';
-	temp[6]='n';
-	temp[7]='\0';
-
-	phandle=OF_finddevice(o,temp);
-
-	temp[0]='b';
-	temp[1]='o';
-	temp[2]='o';
-	temp[3]='t';
-	temp[4]='a';
-	temp[5]='r';
-	temp[6]='g';
-	temp[7]='s';
-	temp[8]='\0';
-
-	mem_len = OF_getproplen(o,phandle, temp);
-	OF_getprop(o,phandle, temp, buffer, mem_len);
-	if (mem_len > 128) mem_len=128;
-	for (i=0; i<=mem_len/4; i++) pointer[i+33]=buffer[i];
-	pointer[i+33]=0;
-
-	temp[0]='/';
-	temp[1]='\0';
-	phandle=OF_finddevice(o,temp);
-	temp[0]='b';
-	temp[1]='a';
-	temp[2]='n';
-	temp[3]='n';
-	temp[4]='e';
-	temp[5]='r';
-	temp[6]='-';
-	temp[7]='n';
-	temp[8]='a';
-	temp[9]='m';
-	temp[10]='e';
-	temp[11]='\0';
-	mem_len = OF_getproplen(o,phandle, temp);
-	OF_getprop(o,phandle, temp, buffer, mem_len);
-	(unsigned char) pointer[32] = ((unsigned char *) buffer)[mem_len-2];
-}
diff -Nru a/arch/arm26/boot/compressed/uncompress.h b/arch/arm26/boot/compressed/uncompress.h
--- a/arch/arm26/boot/compressed/uncompress.h	2005-03-01 23:38:57 -08:00
+++ b/arch/arm26/boot/compressed/uncompress.h	2005-03-01 23:38:57 -08:00
@@ -1,5 +1,4 @@
 /*
- *  linux/include/asm-arm/arch-arc/uncompress.h
  *
  *  Copyright (C) 1996 Russell King
  *
diff -Nru a/arch/arm26/boot/compressed/vmlinux.lds.in b/arch/arm26/boot/compressed/vmlinux.lds.in
--- a/arch/arm26/boot/compressed/vmlinux.lds.in	2005-03-01 23:38:52 -08:00
+++ b/arch/arm26/boot/compressed/vmlinux.lds.in	2005-03-01 23:38:52 -08:00
@@ -1,5 +1,5 @@
 /*
- *  linux/arch/arm/boot/compressed/vmlinux.lds.in
+ *  linux/arch/arm26/boot/compressed/vmlinux.lds.in
  *
  *  Copyright (C) 2000 Russell King
  *
diff -Nru a/arch/arm26/boot/install.sh b/arch/arm26/boot/install.sh
--- a/arch/arm26/boot/install.sh	2005-03-01 23:39:09 -08:00
+++ b/arch/arm26/boot/install.sh	2005-03-01 23:39:09 -08:00
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# arch/arm/boot/install.sh
+# arch/arm26/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
@@ -10,7 +10,7 @@
 #
 # Adapted from code in arch/i386/boot/Makefile by H. Peter Anvin
 # Adapted from code in arch/i386/boot/install.sh by Russell King
-# Stolen from arch/arm/boot/install.sh by Ian Molton
+# Stolen from arm32 by Ian Molton
 #
 # "make install" script for arm architecture
 #
diff -Nru a/arch/arm26/kernel/Makefile b/arch/arm26/kernel/Makefile
--- a/arch/arm26/kernel/Makefile	2005-03-01 23:38:57 -08:00
+++ b/arch/arm26/kernel/Makefile	2005-03-01 23:38:57 -08:00
@@ -2,17 +2,16 @@
 # Makefile for the linux kernel.
 #
 
-ENTRY_OBJ = entry.o
-
 # Object file lists.
 
-obj-y		:= compat.o dma.o entry.o irq.o   \
-		   process.o ptrace.o semaphore.o setup.o signal.o sys_arm.o \
-		   time.o traps.o ecard.o time-acorn.o dma.o \
-		   ecard.o fiq.o time.o
+AFLAGS_head.o           := -DTEXTADDR=$(TEXTADDR)
+
+obj-y		:= compat.o dma.o entry.o irq.o process.o ptrace.o       \
+		   semaphore.o setup.o signal.o sys_arm.o time.o traps.o \
+		   ecard.o dma.o ecard.o fiq.o time.o
+
+extra-y		:= head.o init_task.o vmlinux.lds
 
 obj-$(CONFIG_FIQ)		+= fiq.o
 obj-$(CONFIG_MODULES)		+= armksyms.o
-
-extra-y := init_task.o vmlinux.lds
 
diff -Nru a/arch/arm26/kernel/armksyms.c b/arch/arm26/kernel/armksyms.c
--- a/arch/arm26/kernel/armksyms.c	2005-03-01 23:38:55 -08:00
+++ b/arch/arm26/kernel/armksyms.c	2005-03-01 23:38:55 -08:00
@@ -7,6 +7,7 @@
  * 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/config.h>
 #include <linux/module.h>
 #include <linux/user.h>
@@ -27,8 +28,6 @@
 #include <asm/elf.h>
 #include <asm/io.h>
 #include <asm/irq.h>
-#include <asm/pgalloc.h>
-//#include <asm/proc-fns.h>
 #include <asm/processor.h>
 #include <asm/semaphore.h>
 #include <asm/system.h>
@@ -69,8 +68,9 @@
 /*
  * This has a special calling convention; it doesn't
  * modify any of the usual registers, except for LR.
+ * FIXME - we used to use our own local version - looks to be in kernel/softirq now
  */
-extern void __do_softirq(void);
+//extern void __do_softirq(void);
 
 #define EXPORT_SYMBOL_ALIAS(sym,orig)		\
  const char __kstrtab_##sym[]			\
@@ -95,7 +95,7 @@
 EXPORT_SYMBOL(kd_mksound);
 #endif
 
-EXPORT_SYMBOL(__do_softirq);
+//EXPORT_SYMBOL(__do_softirq);
 
 	/* platform dependent support */
 EXPORT_SYMBOL(dump_thread);
@@ -212,12 +212,6 @@
 EXPORT_SYMBOL(sys_open);
 EXPORT_SYMBOL(sys_exit);
 EXPORT_SYMBOL(sys_wait4);
-
-	/* semaphores */
-EXPORT_SYMBOL(__down_failed);
-EXPORT_SYMBOL(__down_interruptible_failed);
-EXPORT_SYMBOL(__down_trylock_failed);
-EXPORT_SYMBOL(__up_wakeup);
 
 EXPORT_SYMBOL(get_wchan);
 
diff -Nru a/arch/arm26/kernel/asm-offsets.c b/arch/arm26/kernel/asm-offsets.c
--- a/arch/arm26/kernel/asm-offsets.c	2005-03-01 23:38:53 -08:00
+++ b/arch/arm26/kernel/asm-offsets.c	2005-03-01 23:38:53 -08:00
@@ -42,7 +42,6 @@
 
 int main(void)
 {
-  DEFINE(TSK_USED_MATH,		offsetof(struct task_struct, used_math));
   DEFINE(TSK_ACTIVE_MM,		offsetof(struct task_struct, active_mm));
   BLANK();
   DEFINE(VMA_VM_MM,		offsetof(struct vm_area_struct, vm_mm));
diff -Nru a/arch/arm26/kernel/calls.S b/arch/arm26/kernel/calls.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/arm26/kernel/calls.S	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,265 @@
+/*
+ *  linux/arch/arm26/kernel/calls.S
+ *
+ *  Copyright (C) 2003 Ian Molton
+ *
+ * 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.
+ *
+ *  FIXME
+ *  This file is included twice in entry.S which may not be necessary
+ */
+
+//FIXME - clearly NR_syscalls is never defined here
+
+#ifndef NR_syscalls
+#define NR_syscalls 256
+#else
+
+__syscall_start:
+/* 0 */		.long	sys_ni_syscall
+		.long	sys_exit
+		.long	sys_fork_wrapper
+		.long	sys_read
+		.long	sys_write
+/* 5 */		.long	sys_open
+		.long	sys_close
+		.long	sys_ni_syscall		/* was sys_waitpid */
+		.long	sys_creat
+		.long	sys_link
+/* 10 */	.long	sys_unlink
+		.long	sys_execve_wrapper
+		.long	sys_chdir
+		.long	sys_time		/* used by libc4 */
+		.long	sys_mknod
+/* 15 */	.long	sys_chmod
+		.long	sys_lchown16
+		.long	sys_ni_syscall		/* was sys_break */
+		.long	sys_ni_syscall		/* was sys_stat */
+		.long	sys_lseek
+/* 20 */	.long	sys_getpid
+		.long	sys_mount
+		.long	sys_oldumount		/* used by libc4 */
+		.long	sys_setuid16
+		.long	sys_getuid16
+/* 25 */	.long	sys_stime
+		.long	sys_ptrace
+		.long	sys_alarm		/* used by libc4 */
+		.long	sys_ni_syscall		/* was sys_fstat */
+		.long	sys_pause
+/* 30 */	.long	sys_utime		/* used by libc4 */
+		.long	sys_ni_syscall		/* was sys_stty */
+		.long	sys_ni_syscall		/* was sys_getty */
+		.long	sys_access
+		.long	sys_nice
+/* 35 */	.long	sys_ni_syscall		/* was sys_ftime */
+		.long	sys_sync
+		.long	sys_kill
+		.long	sys_rename
+		.long	sys_mkdir
+/* 40 */	.long	sys_rmdir
+		.long	sys_dup
+		.long	sys_pipe
+		.long	sys_times
+		.long	sys_ni_syscall		/* was sys_prof */
+/* 45 */	.long	sys_brk
+		.long	sys_setgid16
+		.long	sys_getgid16
+		.long	sys_ni_syscall		/* was sys_signal */
+		.long	sys_geteuid16
+/* 50 */	.long	sys_getegid16
+		.long	sys_acct
+		.long	sys_umount
+		.long	sys_ni_syscall		/* was sys_lock */
+		.long	sys_ioctl
+/* 55 */	.long	sys_fcntl
+		.long	sys_ni_syscall		/* was sys_mpx */
+		.long	sys_setpgid
+		.long	sys_ni_syscall		/* was sys_ulimit */
+		.long	sys_ni_syscall		/* was sys_olduname */
+/* 60 */	.long	sys_umask
+		.long	sys_chroot
+		.long	sys_ustat
+		.long	sys_dup2
+		.long	sys_getppid
+/* 65 */	.long	sys_getpgrp
+		.long	sys_setsid
+		.long	sys_sigaction
+		.long	sys_ni_syscall		/* was sys_sgetmask */
+		.long	sys_ni_syscall		/* was sys_ssetmask */
+/* 70 */	.long	sys_setreuid16
+		.long	sys_setregid16
+		.long	sys_sigsuspend_wrapper
+		.long	sys_sigpending
+		.long	sys_sethostname
+/* 75 */	.long	sys_setrlimit
+		.long	sys_old_getrlimit	/* used by libc4 */
+		.long	sys_getrusage
+		.long	sys_gettimeofday
+		.long	sys_settimeofday
+/* 80 */	.long	sys_getgroups16
+		.long	sys_setgroups16
+		.long	old_select		/* used by libc4 */
+		.long	sys_symlink
+		.long	sys_ni_syscall		/* was sys_lstat */
+/* 85 */	.long	sys_readlink
+		.long	sys_uselib
+		.long	sys_swapon
+		.long	sys_reboot
+		.long	old_readdir		/* used by libc4 */
+/* 90 */	.long	old_mmap		/* used by libc4 */
+		.long	sys_munmap
+		.long	sys_truncate
+		.long	sys_ftruncate
+		.long	sys_fchmod
+/* 95 */	.long	sys_fchown16
+		.long	sys_getpriority
+		.long	sys_setpriority
+		.long	sys_ni_syscall		/* was sys_profil */
+		.long	sys_statfs
+/* 100 */	.long	sys_fstatfs
+		.long	sys_ni_syscall
+		.long	sys_socketcall
+		.long	sys_syslog
+		.long	sys_setitimer
+/* 105 */	.long	sys_getitimer
+		.long	sys_newstat
+		.long	sys_newlstat
+		.long	sys_newfstat
+		.long	sys_ni_syscall		/* was sys_uname */
+/* 110 */	.long	sys_ni_syscall		/* was sys_iopl */
+		.long	sys_vhangup
+		.long	sys_ni_syscall
+		.long	sys_syscall		/* call a syscall */
+		.long	sys_wait4
+/* 115 */	.long	sys_swapoff
+		.long	sys_sysinfo
+		.long	sys_ipc
+		.long	sys_fsync
+		.long	sys_sigreturn_wrapper
+/* 120 */	.long	sys_clone_wapper
+		.long	sys_setdomainname
+		.long	sys_newuname
+		.long	sys_ni_syscall
+		.long	sys_adjtimex
+/* 125 */	.long	sys_mprotect
+		.long	sys_sigprocmask
+		.long	sys_ni_syscall  /* WAS: sys_create_module */
+		.long	sys_init_module
+		.long	sys_delete_module
+/* 130 */	.long	sys_ni_syscall  /* WAS: sys_get_kernel_syms */
+		.long	sys_quotactl
+		.long	sys_getpgid
+		.long	sys_fchdir
+		.long	sys_bdflush
+/* 135 */	.long	sys_sysfs
+		.long	sys_personality
+		.long	sys_ni_syscall		/* .long	_sys_afs_syscall */
+		.long	sys_setfsuid16
+		.long	sys_setfsgid16
+/* 140 */	.long	sys_llseek
+		.long	sys_getdents
+		.long	sys_select
+		.long	sys_flock
+		.long	sys_msync
+/* 145 */	.long	sys_readv
+		.long	sys_writev
+		.long	sys_getsid
+		.long	sys_fdatasync
+		.long	sys_sysctl
+/* 150 */	.long	sys_mlock
+		.long	sys_munlock
+		.long	sys_mlockall
+		.long	sys_munlockall
+		.long	sys_sched_setparam
+/* 155 */	.long	sys_sched_getparam
+		.long	sys_sched_setscheduler
+		.long	sys_sched_getscheduler
+		.long	sys_sched_yield
+		.long	sys_sched_get_priority_max
+/* 160 */	.long	sys_sched_get_priority_min
+		.long	sys_sched_rr_get_interval
+		.long	sys_nanosleep
+		.long	sys_arm_mremap
+		.long	sys_setresuid16
+/* 165 */	.long	sys_getresuid16
+		.long	sys_ni_syscall
+		.long	sys_ni_syscall /* WAS: sys_query_module */
+		.long	sys_poll
+		.long	sys_nfsservctl
+/* 170 */	.long	sys_setresgid16
+		.long	sys_getresgid16
+		.long	sys_prctl
+		.long	sys_rt_sigreturn_wrapper
+		.long	sys_rt_sigaction
+/* 175 */	.long	sys_rt_sigprocmask
+		.long	sys_rt_sigpending
+		.long	sys_rt_sigtimedwait
+		.long	sys_rt_sigqueueinfo
+		.long	sys_rt_sigsuspend_wrapper
+/* 180 */	.long	sys_pread64
+		.long	sys_pwrite64
+		.long	sys_chown16
+		.long	sys_getcwd
+		.long	sys_capget
+/* 185 */	.long	sys_capset
+		.long	sys_sigaltstack_wrapper
+		.long	sys_sendfile
+		.long	sys_ni_syscall
+		.long	sys_ni_syscall
+/* 190 */	.long	sys_vfork_wrapper
+		.long	sys_getrlimit
+		.long	sys_mmap2
+		.long	sys_truncate64
+		.long	sys_ftruncate64
+/* 195 */	.long	sys_stat64
+		.long	sys_lstat64
+		.long	sys_fstat64
+		.long	sys_lchown
+		.long	sys_getuid
+/* 200 */	.long	sys_getgid
+		.long	sys_geteuid
+		.long	sys_getegid
+		.long	sys_setreuid
+		.long	sys_setregid
+/* 205 */	.long	sys_getgroups
+		.long	sys_setgroups
+		.long	sys_fchown
+		.long	sys_setresuid
+		.long	sys_getresuid
+/* 210 */	.long	sys_setresgid
+		.long	sys_getresgid
+		.long	sys_chown
+		.long	sys_setuid
+		.long	sys_setgid
+/* 215 */	.long	sys_setfsuid
+		.long	sys_setfsgid
+		.long	sys_getdents64
+		.long	sys_pivot_root
+		.long	sys_mincore
+/* 220 */	.long	sys_madvise
+		.long	sys_fcntl64
+		.long	sys_ni_syscall /* TUX */
+		.long	sys_ni_syscall /* WAS: sys_security */
+		.long	sys_gettid
+/* 225 */	.long	sys_readahead
+		.long	sys_setxattr
+		.long	sys_lsetxattr
+		.long	sys_fsetxattr
+		.long	sys_getxattr
+/* 230 */	.long	sys_lgetxattr
+		.long	sys_fgetxattr
+		.long	sys_listxattr
+		.long	sys_llistxattr
+		.long	sys_flistxattr
+/* 235 */	.long	sys_removexattr
+		.long	sys_lremovexattr
+		.long	sys_fremovexattr
+		.long	sys_tkill
+__syscall_end:
+
+		.rept	NR_syscalls - (__syscall_end - __syscall_start) / 4
+			.long	sys_ni_syscall
+		.endr
+#endif
diff -Nru a/arch/arm26/kernel/compat.c b/arch/arm26/kernel/compat.c
--- a/arch/arm26/kernel/compat.c	2005-03-01 23:39:09 -08:00
+++ b/arch/arm26/kernel/compat.c	2005-03-01 23:39:09 -08:00
@@ -1,5 +1,5 @@
 /*
- *  linux/arch/arm/kernel/compat.c
+ *  linux/arch/arm26/kernel/compat.c
  *
  *  Copyright (C) 2001 Russell King
  *                2003 Ian Molton
diff -Nru a/arch/arm26/kernel/dma.c b/arch/arm26/kernel/dma.c
--- a/arch/arm26/kernel/dma.c	2005-03-01 23:39:18 -08:00
+++ b/arch/arm26/kernel/dma.c	2005-03-01 23:39:18 -08:00
@@ -1,5 +1,5 @@
 /*
- *  linux/arch/arm/kernel/dma.c
+ *  linux/arch/arm26/kernel/dma.c
  *
  *  Copyright (C) 1995-2000 Russell King
  *                2003      Ian Molton
@@ -22,9 +22,7 @@
 
 #include <asm/dma.h>
 
-spinlock_t dma_spin_lock = SPIN_LOCK_UNLOCKED;
-
-#if MAX_DMA_CHANNELS > 0
+DEFINE_SPINLOCK(dma_spin_lock);
 
 static dma_t dma_chan[MAX_DMA_CHANNELS];
 
@@ -259,33 +257,6 @@
 {
 	arch_dma_init(dma_chan);
 }
-
-#else
-
-int request_dma(dmach_t channel, const char *device_id)
-{
-	return -EINVAL;
-}
-
-int get_dma_residue(dmach_t channel)
-{
-	return 0;
-}
-
-#define GLOBAL_ALIAS(_a,_b) asm (".set " #_a "," #_b "; .globl " #_a)
-GLOBAL_ALIAS(disable_dma, get_dma_residue);
-GLOBAL_ALIAS(enable_dma, get_dma_residue);
-GLOBAL_ALIAS(free_dma, get_dma_residue);
-GLOBAL_ALIAS(get_dma_list, get_dma_residue);
-GLOBAL_ALIAS(set_dma_mode, get_dma_residue);
-GLOBAL_ALIAS(set_dma_page, get_dma_residue);
-GLOBAL_ALIAS(set_dma_count, get_dma_residue);
-GLOBAL_ALIAS(set_dma_addr, get_dma_residue);
-GLOBAL_ALIAS(set_dma_sg, get_dma_residue);
-GLOBAL_ALIAS(set_dma_speed, get_dma_residue);
-GLOBAL_ALIAS(init_dma, get_dma_residue);
-
-#endif
 
 EXPORT_SYMBOL(request_dma);
 EXPORT_SYMBOL(free_dma);
diff -Nru a/arch/arm26/kernel/ecard.c b/arch/arm26/kernel/ecard.c
--- a/arch/arm26/kernel/ecard.c	2005-03-01 23:39:18 -08:00
+++ b/arch/arm26/kernel/ecard.c	2005-03-01 23:39:18 -08:00
@@ -42,9 +42,7 @@
 #include <asm/hardware.h>
 #include <asm/io.h>
 #include <asm/irq.h>
-#include <asm/pgalloc.h>
 #include <asm/mmu_context.h>
-#include <asm/irq.h>
 #include <asm/irqchip.h>
 #include <asm/tlbflush.h>
 
@@ -137,65 +135,23 @@
 	unsigned int len = req->length;
 	unsigned int off = req->address;
 
-	if (req->ec->slot_no == 8) {
-		/*
-		 * The card maintains an index which increments the address
-		 * into a 4096-byte page on each access.  We need to keep
-		 * track of the counter.
-		 */
-		static unsigned int index;
-		unsigned int page;
-
-		page = (off >> 12) * 4;
-		if (page > 256 * 4)
-			return;
-
-		off &= 4095;
-
-		/*
-		 * If we are reading offset 0, or our current index is
-		 * greater than the offset, reset the hardware index counter.
-		 */
-		if (off == 0 || index > off) {
-			*base_addr = 0;
-			index = 0;
-		}
-
-		/*
-		 * Increment the hardware index counter until we get to the
-		 * required offset.  The read bytes are discarded.
-		 */
-		while (index < off) {
-			unsigned char byte;
-			byte = base_addr[page];
-			index += 1;
-		}
-
+	if (!req->use_loader || !req->ec->loader) {
+		off *= 4;
 		while (len--) {
-			*buf++ = base_addr[page];
-			index += 1;
+			*buf++ = base_addr[off];
+			off += 4;
 		}
 	} else {
-
-		if (!req->use_loader || !req->ec->loader) {
-			off *= 4;
-			while (len--) {
-				*buf++ = base_addr[off];
-				off += 4;
-			}
-		} else {
-			while(len--) {
-				/*
-				 * The following is required by some
-				 * expansion card loader programs.
-				 */
-				*(unsigned long *)0x108 = 0;
-				*buf++ = ecard_loader_read(off++, base_addr,
-							   req->ec->loader);
-			}
+		while(len--) {
+			/*
+			 * The following is required by some
+			 * expansion card loader programs.
+			 */
+			*(unsigned long *)0x108 = 0;
+			*buf++ = ecard_loader_read(off++, base_addr,
+						   req->ec->loader);
 		}
 	}
-
 }
 
 static void ecard_do_request(struct ecard_request *req)
@@ -466,7 +422,7 @@
 	for (ec = cards; ec; ec = ec->next) {
 		int pending;
 
-		if (!ec->claimed || ec->irq == NO_IRQ || ec->slot_no == 8)
+		if (!ec->claimed || ec->irq == NO_IRQ)
 			continue;
 
 		if (ec->ops && ec->ops->irqpending)
@@ -494,22 +450,15 @@
 	unsigned long address = 0;
 	int slot = ec->slot_no;
 
-	if (ec->slot_no == 8)
-		return 0;
-
 	ectcr &= ~(1 << slot);
 
 	switch (type) {
 	case ECARD_MEMC:
-		if (slot < 4)
-			address = IO_EC_MEMC_BASE + (slot << 12);
+		address = IO_EC_MEMC_BASE + (slot << 12);
 		break;
 
 	case ECARD_IOC:
-		if (slot < 4)
-			address = IO_EC_IOC_BASE + (slot << 12);
-		if (address)
-			address +=  speed << 17;
+		address = IO_EC_IOC_BASE + (slot << 12) + (speed << 17);
 		break;
 
 	default:
@@ -592,11 +541,9 @@
 	unsigned int slot = ec->slot_no;
 	int i;
 
-	if (slot < 4) {
-		ec_set_resource(ec, ECARD_RES_MEMC,
-				PODSLOT_MEMC_BASE + (slot << 14),
-				PODSLOT_MEMC_SIZE, IORESOURCE_MEM);
-	}
+	ec_set_resource(ec, ECARD_RES_MEMC,
+			PODSLOT_MEMC_BASE + (slot << 14),
+			PODSLOT_MEMC_SIZE, IORESOURCE_MEM);
 
 	for (i = 0; i < ECARD_RES_IOCSYNC - ECARD_RES_IOCSLOW; i++) {
 		ec_set_resource(ec, i + ECARD_RES_IOCSLOW,
@@ -739,12 +686,10 @@
 	/*
 	 * hook the interrupt handlers
 	 */
-	if (slot < 8) {
-		ec->irq = 32 + slot;
-		set_irq_chip(ec->irq, &ecard_chip);
-		set_irq_handler(ec->irq, do_level_IRQ);
-		set_irq_flags(ec->irq, IRQF_VALID);
-	}
+	ec->irq = 32 + slot;
+	set_irq_chip(ec->irq, &ecard_chip);
+	set_irq_handler(ec->irq, do_level_IRQ);
+	set_irq_flags(ec->irq, IRQF_VALID);
 
 	for (ecp = &cards; *ecp; ecp = &(*ecp)->next);
 
@@ -777,7 +722,7 @@
 
 	printk("Probing expansion cards\n");
 
-	for (slot = 0; slot < 4; slot ++) {
+	for (slot = 0; slot < MAX_ECARDS; slot ++) {
 		ecard_probe(slot, ECARD_IOC);
 	}
 
diff -Nru a/arch/arm26/kernel/entry.S b/arch/arm26/kernel/entry.S
--- a/arch/arm26/kernel/entry.S	2005-03-01 23:38:52 -08:00
+++ b/arch/arm26/kernel/entry.S	2005-03-01 23:38:52 -08:00
@@ -3,10 +3,10 @@
  * Assembled from chunks of code in arch/arm
  *
  * Copyright (C) 2003 Ian Molton
+ * Based on the work of RMK.
  *
  */
 
-#include <linux/config.h> /* for CONFIG_ARCH_xxxx */
 #include <linux/linkage.h>
 
 #include <asm/assembler.h>
@@ -35,8 +35,6 @@
 #define BAD_IRQ		3
 #define BAD_UNDEFINSTR	4
 
-#define PT_TRACESYS	0x00000002
-
 @ OS version number used in SWIs
 @  RISC OS is 0
 @  RISC iX is 8
@@ -46,10 +44,12 @@
 
 @
 @ Stack format (ensured by USER_* and SVC_*)
+@ PSR and PC are comined on arm26
 @
-#define S_FRAME_SIZE	72   @ FIXME: Really?
+
+#define S_OFF		8
+
 #define S_OLD_R0	64
-#define S_PSR		60
 #define S_PC		60
 #define S_LR		56
 #define S_SP		52
@@ -66,19 +66,18 @@
 #define S_R2		8
 #define S_R1		4
 #define S_R0		0
-#define S_OFF		8
 
 	.macro	save_user_regs
-	str	r0, [sp, #-4]!
-	str	lr, [sp, #-4]!
+	str	r0, [sp, #-4]!   @ Store SVC r0
+	str	lr, [sp, #-4]!   @ Store user mode PC
 	sub	sp, sp, #15*4
-	stmia	sp, {r0 - lr}^
+	stmia	sp, {r0 - lr}^   @ Store the other user-mode regs
 	mov	r0, r0
 	.endm
 
 	.macro	slow_restore_user_regs
-	ldmia	sp, {r0 - lr}^   @ restore the user regs
-	mov	r0, r0           @ no-op
+	ldmia	sp, {r0 - lr}^   @ restore the user regs not including PC
+	mov	r0, r0
 	ldr	lr, [sp, #15*4]  @ get user PC
 	add	sp, sp, #15*4+8  @ free stack
 	movs	pc, lr           @ return
@@ -93,6 +92,32 @@
 	movs	pc, lr
 	.endm
 
+	.macro	save_svc_regs
+	str     sp, [sp, #-16]!
+	str     lr, [sp, #8]
+	str     lr, [sp, #4]
+	stmfd   sp!, {r0 - r12}
+	mov     r0, #-1
+	str     r0, [sp, #S_OLD_R0]
+	zero_fp
+	.endm
+
+	.macro	save_svc_regs_irq
+	str     sp, [sp, #-16]!
+	str     lr, [sp, #4]
+	ldr     lr, .LCirq
+	ldr     lr, [lr]
+	str     lr, [sp, #8]
+	stmfd   sp!, {r0 - r12}
+	mov     r0, #-1
+	str     r0, [sp, #S_OLD_R0]
+	zero_fp
+	.endm
+
+	.macro	restore_svc_regs
+                ldmfd   sp, {r0 - pc}^
+	.endm
+
 	.macro	mask_pc, rd, rm
 	bic	\rd, \rm, #PCMASK
 	.endm
@@ -117,21 +142,10 @@
 	mov	\rd, \rd, lsl #13
 	.endm
 
-	/*
-	 * Like adr, but force SVC mode (if required)
-	 */
-	.macro	adrsvc, cond, reg, label
-	adr\cond	\reg, \label
-	orr\cond	\reg, \reg, #PSR_I_BIT | MODE_SVC26
-	.endm
-
-
 /*
  * These are the registers used in the syscall handler, and allow us to
  * have in theory up to 7 arguments to a function - r0 to r6.
  *
- * r7 is reserved for the system call number for thumb mode.
- *
  * Note that tbl == why is intentional.
  *
  * We must set at least "tsk" and "why" when calling ret_with_reschedule.
@@ -161,17 +175,6 @@
 #endif
 
 /*
- * Our do_softirq out of line code.  See include/asm-arm26/hardirq.h for
- * the calling assembly.
- */
-ENTRY(__do_softirq)
-	stmfd	sp!, {r0 - r3, ip, lr}
-	bl	do_softirq
-	ldmfd	sp!, {r0 - r3, ip, pc}
-
-	.align	5
-
-/*
  * This is the fast syscall return path.  We do as little as
  * possible here, and this includes saving r0 back into the SVC
  * stack.
@@ -228,7 +231,8 @@
 	bl	syscall_trace
 	b	ret_slow_syscall
 	
-#include <asm/calls.h>
+// FIXME - is this strictly necessary?
+#include "calls.S"
 
 /*=============================================================================
  * SWI handler
@@ -258,7 +262,8 @@
 	tst	ip, #_TIF_SYSCALL_TRACE		@ are we tracing syscalls?
 	bne	__sys_trace
 
-	adrsvc	al, lr, ret_fast_syscall	@ return address
+	adral	lr, ret_fast_syscall            @ set return address
+        orral	lr, lr, #PSR_I_BIT | MODE_SVC26 @ Force SVC mode on return
 	cmp	scno, #NR_syscalls		@ check upper syscall limit
 	ldrcc	pc, [tbl, scno, lsl #2]		@ call sys_* routine
 
@@ -278,7 +283,8 @@
 	mov	r0, #0				@ trace entry [IP = 0]
 	bl	syscall_trace
 
-	adrsvc	al, lr, __sys_trace_return	@ return address
+	adral   lr, __sys_trace_return          @ set return address
+        orral   lr, lr, #PSR_I_BIT | MODE_SVC26 @ Force SVC mode on return
 	add	r1, sp, #S_R0 + S_OFF		@ pointer to regs
 	cmp	scno, #NR_syscalls		@ check upper syscall limit
 	ldmccia	r1, {r0 - r3}			@ have to reload r0 - r3
@@ -301,7 +307,7 @@
 
 	.type	sys_call_table, #object
 ENTRY(sys_call_table)
-#include <asm/calls.h>
+#include "calls.S"
 
 /*============================================================================
  * Special system call wrappers
@@ -387,27 +393,22 @@
 
 		.text
 
-		.equ	ioc_base_high, IOC_BASE & 0xff000000
-		.equ	ioc_base_low, IOC_BASE & 0x00ff0000
-		.macro	disable_fiq
-		mov	r12, #ioc_base_high
-		.if	ioc_base_low
-		orr	r12, r12, #ioc_base_low
-		.endif
-		strb	r12, [r12, #0x38]	@ Disable FIQ register
+		.macro handle_irq
+1:		mov     r4, #IOC_BASE
+		ldrb    r6, [r4, #0x24]            @ get high priority first
+		adr     r5, irq_prio_h
+		teq     r6, #0
+		ldreqb  r6, [r4, #0x14]            @ get low priority
+		adreq   r5, irq_prio_l
+
+                teq     r6, #0                     @ If an IRQ happened...
+                ldrneb  r0, [r5, r6]               @ get IRQ number
+                movne   r1, sp                     @ get struct pt_regs
+                adrne   lr, 1b                     @ Set return address to 1b
+                orrne   lr, lr, #PSR_I_BIT | MODE_SVC26  @ (and force SVC mode)
+                bne     asm_do_IRQ                 @ process IRQ (if asserted)
 		.endm
 
-		.macro	get_irqnr_and_base, irqnr, base
-		mov	r4, #ioc_base_high		@ point at IOC
-		.if	ioc_base_low
-		orr	r4, r4, #ioc_base_low
-		.endif
-		ldrb	\irqnr, [r4, #0x24]		@ get high priority first
-		adr	\base, irq_prio_h
-		teq	\irqnr, #0
-		ldreqb	\irqnr, [r4, #0x14]		@ get low priority
-		adreq	\base, irq_prio_l
-		.endm
 
 /*
  * Interrupt table (incorporates priority)
@@ -448,9 +449,9 @@
 		.endm
 
 #if 1
-/* FIXME (well, ok, dont - but its easy to grep for :) */
 /*
  * Uncomment these if you wish to get more debugging into about data aborts.
+ * FIXME - I bet we can find a way to encode these and keep performance.
  */
 #define FAULT_CODE_LDRSTRPOST	0x80
 #define FAULT_CODE_LDRSTRPRE	0x40
@@ -462,29 +463,6 @@
 #define FAULT_CODE_WRITE	0x02
 #define FAULT_CODE_FORCECOW	0x01
 
-#define SVC_SAVE_ALL				\
-		str	sp, [sp, #-16]!		;\
-		str	lr, [sp, #8]		;\
-		str	lr, [sp, #4]		;\
-		stmfd	sp!, {r0 - r12}		;\
-		mov	r0, #-1			;\
-		str	r0, [sp, #S_OLD_R0]	;\
-		zero_fp
-
-#define SVC_IRQ_SAVE_ALL			\
-		str	sp, [sp, #-16]!		;\
-		str	lr, [sp, #4]		;\
-		ldr	lr, .LCirq		;\
-		ldr	lr, [lr]		;\
-		str	lr, [sp, #8]		;\
-		stmfd	sp!, {r0 - r12}		;\
-		mov	r0, #-1			;\
-		str	r0, [sp, #S_OLD_R0]	;\
-		zero_fp
-
-#define SVC_RESTORE_ALL				\
-		ldmfd	sp, {r0 - pc}^
-		
 /*=============================================================================
  * Undefined FIQs
  *-----------------------------------------------------------------------------
@@ -526,13 +504,13 @@
 /* FIXME - should we trap for a null pointer here? */
 
 /* The SVC mode case */
-__und_svc:      SVC_SAVE_ALL                            @ Non-user mode
+__und_svc:	save_svc_regs                           @ Non-user mode
                 mask_pc r0, lr
                 and     r2, lr, #3
                 sub     r0, r0, #4
                 mov     r1, sp
                 bl      do_undefinstr
-                SVC_RESTORE_ALL
+                restore_svc_regs
 
 /* We get here if the FP emulator doesnt handle the undef instr.
  * If the insn WAS handled, the emulator jumps to ret_from_exception by itself/
@@ -614,7 +592,7 @@
 		ldr	lr, [sp,#S_PC]		@ FIXME program to test this on.  I think its
 		b	.Lbug_undef		@ broken at the moment though!)
 
-__pabt_invalid:	SVC_SAVE_ALL
+__pabt_invalid:	save_svc_regs
 		mov	r0, sp			@ Prefetch aborts are definitely *not*
 		mov	r1, #BAD_PREFETCH	@ allowed in non-user modes.  We cant
 		and	r2, lr, #3		@ recover from this problem.
@@ -648,7 +626,7 @@
 		b	ret_from_exception
 
 Laddrexcptn_not_user:
-		SVC_SAVE_ALL
+		save_svc_regs
 		and	r2, lr, #3
 		teq	r2, #3
 		bne	Laddrexcptn_illegal_mode
@@ -686,56 +664,50 @@
 /*=============================================================================
  * Interrupt (IRQ) handler
  *-----------------------------------------------------------------------------
- * Note: if in user mode, then *no* kernel routine is running, so do not have
- *       to save svc lr
- * (r13 points to irq temp save area)
+ * Note: if the IRQ was taken whilst in user mode, then *no* kernel routine
+ * is running, so do not have to save svc lr.
+ *
+ * Entered in IRQ mode.
  */
 
-vector_IRQ:	ldr	r13, .LCirq			@ I will leave this one in just in case...
-		sub	lr, lr, #4
-		str	lr, [r13]
-		tst	lr, #3
-		bne	__irq_svc
-		teqp	pc, #PSR_I_BIT | MODE_SVC26
+vector_IRQ:	ldr     sp, .LCirq         @ Setup some temporary stack
+                sub     lr, lr, #4
+                str     lr, [sp]           @ push return address
+
+		tst     lr, #3
+		bne	__irq_non_usr
+
+__irq_usr:	teqp	pc, #PSR_I_BIT | MODE_SVC26     @ Enter SVC mode
 		mov	r0, r0
+
 		ldr	lr, .LCirq
-		ldr	lr, [lr]
+		ldr	lr, [lr]           @ Restore lr for jump back to USR
+
 		save_user_regs
 
-1:		get_irqnr_and_base r6, r5
-		teq	r6, #0
-		ldrneb	r0, [r5, r6]			@ get IRQ number
-		movne	r1, sp
-		@
-		@ routine called with r0 = irq number, r1 = struct pt_regs *
-		@
-		adr	lr, 1b
-		orr	lr, lr, #PSR_I_BIT | MODE_SVC26		@ Force SVC
-		bne	asm_do_IRQ
+		handle_irq
 
 		mov	why, #0
-		get_thread_info tsk        @ FIXME - was r5, but seemed wrong.
+		get_thread_info tsk
 		b	ret_to_user
 
+@ Place the IRQ priority table here so that the handle_irq macros above
+@ and below here can access it.
+
 		irq_prio_table
 
-__irq_svc:	teqp	pc, #PSR_I_BIT | MODE_SVC26
+__irq_non_usr:	teqp	pc, #PSR_I_BIT | MODE_SVC26     @ Enter SVC mode
 		mov	r0, r0
-		SVC_IRQ_SAVE_ALL
+
+		save_svc_regs_irq
+
                 and	r2, lr, #3
 		teq	r2, #3
-		bne	__irq_invalid
-1:		get_irqnr_and_base r6, r5
-		teq	r6, #0
-		ldrneb	r0, [r5, r6]			@ get IRQ number
-		movne	r1, sp
-		@
-		@ routine called with r0 = irq number, r1 = struct pt_regs *
-		@
-		adr	lr, 1b
-		orr	lr, lr, #PSR_I_BIT | MODE_SVC26		@ Force SVC
-		bne	asm_do_IRQ			@ Returns to 1b
-		SVC_RESTORE_ALL
+		bne	__irq_invalid                @ IRQ not from SVC mode
+
+		handle_irq
+
+		restore_svc_regs
 
 __irq_invalid:	mov	r0, sp
 		mov	r1, #BAD_IRQ
@@ -762,7 +734,7 @@
 		b	ret_from_exception
 
 Ldata_not_user:
-		SVC_SAVE_ALL
+		save_svc_regs
 		and	r2, lr, #3
 		teq	r2, #3
 		bne	Ldata_illegal_mode
@@ -770,7 +742,7 @@
 		teqeqp	pc, #MODE_SVC26
 		mask_pc	r0, lr
 		bl	Ldata_do
-		SVC_RESTORE_ALL
+		restore_svc_regs
 
 Ldata_illegal_mode:
 		mov	r0, sp
diff -Nru a/arch/arm26/kernel/head.S b/arch/arm26/kernel/head.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/arm26/kernel/head.S	2005-03-01 23:39:18 -08:00
@@ -0,0 +1,113 @@
+/*
+ *  linux/arch/arm26/kernel/head.S
+ *
+ *  Copyright (C) 1994-2000 Russell King
+ *  Copyright (C) 2003 Ian Molton
+ *
+ * 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.
+ *
+ *  26-bit kernel startup code
+ */
+#include <linux/config.h>
+#include <linux/linkage.h>
+#include <asm/mach-types.h>
+
+		.globl	swapper_pg_dir
+		.equ	swapper_pg_dir,	0x0207d000
+
+/*
+ * Entry point.
+ */
+		.section ".init.text",#alloc,#execinstr
+ENTRY(stext)
+
+__entry:
+		cmp	pc, #0x02000000
+		ldrlt	pc, LC0			@ if 0x01800000, call at 0x02080000
+		teq	r0, #0                  @ Check for old calling method
+		blne	oldparams		@ Move page if old
+
+		adr	r0, LC0
+		ldmib	r0, {r2-r5, sp}		@ Setup stack (and fetch other values)
+
+		mov	r0, #0			@ Clear BSS
+1:		cmp	r2, r3
+		strcc	r0, [r2], #4
+		bcc	1b
+
+		bl	detect_proc_type
+		str	r0, [r4]
+		bl	detect_arch_type
+		str	r0, [r5]
+
+#ifdef CONFIG_XIP_KERNEL
+               ldr     r3, ETEXT                       @ data section copy
+               ldr     r4, SDATA
+               ldr     r5, EDATA
+1:
+               ldr     r6, [r3], #4
+               str     r6, [r4], #4
+               cmp     r4, r5
+               blt     1b
+#endif
+		mov	fp, #0
+		b	start_kernel
+
+LC0:		.word	_stext
+		.word	__bss_start		@ r2
+		.word	_end			@ r3
+		.word	processor_id		@ r4
+		.word	__machine_arch_type	@ r5
+		.word	init_thread_union+8192	@ sp
+#ifdef CONFIG_XIP_KERNEL
+ETEXT:		.word   _endtext
+SDATA:		.word   _sdata
+EDATA:		.word   __bss_start
+#endif
+
+arm2_id:	.long	0x41560200  @ ARM2 and 250 dont have a CPUID
+arm250_id:	.long	0x41560250  @ So we create some after probing for them
+		.align
+
+oldparams:	mov     r4, #0x02000000
+		add	r3, r4, #0x00080000
+		add	r4, r4, #0x0007c000
+1:		ldmia	r0!, {r5 - r12}
+		stmia	r4!, {r5 - r12}
+		cmp	r4, r3
+		blt	1b
+		mov	pc, lr
+
+/*
+ * We need some way to automatically detect the difference between
+ * these two machines.  Unfortunately, it is not possible to detect
+ * the presence of the SuperIO chip, because that will hang the old
+ * Archimedes machines solid.
+ */
+/* DAG: Outdated, these have been combined !!!!!!! */
+detect_arch_type:
+#if defined(CONFIG_ARCH_ARC)
+		mov	r0, #MACH_TYPE_ARCHIMEDES
+#elif defined(CONFIG_ARCH_A5K)
+		mov	r0, #MACH_TYPE_A5K
+#endif
+		mov	pc, lr
+
+detect_proc_type:
+		mov	ip, lr
+		mov	r2, #0xea000000		@ Point undef instr to continuation
+		adr	r0, continue - 12
+		orr	r0, r2, r0, lsr #2
+		mov	r1, #0
+		str	r0, [r1, #4]
+		ldr	r0, arm2_id
+		swp	r2, r2, [r1]		@ check for swp (ARM2 cant)
+		ldr	r0, arm250_id
+		mrc	15, 0, r3, c0, c0	@ check for CP#15 (ARM250 cant)
+		mov	r0, r3
+continue:	mov	r2, #0xeb000000		@ Make undef vector loop
+		sub	r2, r2, #2
+		str	r2, [r1, #4]
+		mov	pc, ip
diff -Nru a/arch/arm26/kernel/init_task.c b/arch/arm26/kernel/init_task.c
--- a/arch/arm26/kernel/init_task.c	2005-03-01 23:38:54 -08:00
+++ b/arch/arm26/kernel/init_task.c	2005-03-01 23:38:54 -08:00
@@ -1,5 +1,5 @@
 /*
- *  linux/arch/arm/kernel/init_task.c
+ *  linux/arch/arm26/kernel/init_task.c
  *
  * Copyright (C) 2003 Ian Molton
  *
@@ -29,7 +29,9 @@
  * We need to make sure that this is 8192-byte aligned due to the
  * way process stacks are handled. This is done by making sure
  * the linker maps this in the .text segment right after head.S,
- * and making head.S ensure the proper alignment.
+ * and making the linker scripts ensure the proper alignment.
+ *
+ * FIXME - should this be 32K alignment on arm26?
  *
  * The things we do for performance...
  */
diff -Nru a/arch/arm26/kernel/irq.c b/arch/arm26/kernel/irq.c
--- a/arch/arm26/kernel/irq.c	2005-03-01 23:39:16 -08:00
+++ b/arch/arm26/kernel/irq.c	2005-03-01 23:39:16 -08:00
@@ -50,7 +50,7 @@
 #define MAX_IRQ_CNT	100000
 
 static volatile unsigned long irq_err_count;
-static spinlock_t irq_controller_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(irq_controller_lock);
 
 struct irqdesc irq_desc[NR_IRQS];
 
diff -Nru a/arch/arm26/kernel/process.c b/arch/arm26/kernel/process.c
--- a/arch/arm26/kernel/process.c	2005-03-01 23:39:10 -08:00
+++ b/arch/arm26/kernel/process.c	2005-03-01 23:39:10 -08:00
@@ -68,41 +68,21 @@
 __setup("hlt", hlt_setup);
 
 /*
- * The following aren't currently used.
- */
-void (*pm_idle)(void);
-void (*pm_power_off)(void);
-
-/*
  * This is our default idle handler.  We need to disable
  * interrupts here to ensure we don't miss a wakeup call.
  */
-void default_idle(void)
-{
-	local_irq_disable();
-	if (!need_resched() && !hlt_counter)
-	local_irq_enable();
-}
-
-/*
- * The idle thread.  We try to conserve power, while trying to keep
- * overall latency low.  The architecture specific idle is passed
- * a value to indicate the level of "idleness" of the system.
- */
 void cpu_idle(void)
 {
 	/* endless idle loop with no priority at all */
 	preempt_disable();
 	while (1) {
-		void (*idle)(void) = pm_idle;
-		if (!idle)
-			idle = default_idle;
-		leds_event(led_idle_start);
-		while (!need_resched())
-			idle();
-		leds_event(led_idle_end);
-		schedule();
+		while (!need_resched()) {
+			local_irq_disable();
+			if (!need_resched() && !hlt_counter)
+				local_irq_enable();
+		}
 	}
+	schedule();
 }
 
 static char reboot_mode = 'h';
@@ -115,20 +95,15 @@
 
 __setup("reboot=", reboot_setup);
 
+/* ARM26 cant do these but we still need to define them. */
 void machine_halt(void)
 {
-	leds_event(led_halted);
 }
-
-EXPORT_SYMBOL(machine_halt);
-
 void machine_power_off(void)
 {
-	leds_event(led_halted);
-	if (pm_power_off)
-		pm_power_off();
 }
 
+EXPORT_SYMBOL(machine_halt);
 EXPORT_SYMBOL(machine_power_off);
 
 void machine_restart(char * __unused)
@@ -296,7 +271,7 @@
 	memset(&tsk->thread.debug, 0, sizeof(struct debug_info));
 	memset(&thread->fpstate, 0, sizeof(union fp_state));
 
-	current->used_math = 0;
+	clear_used_math();
 }
 
 void release_thread(struct task_struct *dead_task)
@@ -306,7 +281,7 @@
 asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
 
 int
-copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
+copy_thread(int nr, unsigned long clone_flags, unsigned long stack_start,
 	    unsigned long unused, struct task_struct *p, struct pt_regs *regs)
 {
 	struct thread_info *thread = p->thread_info;
@@ -315,7 +290,7 @@
 	childregs = __get_user_regs(thread);
 	*childregs = *regs;
 	childregs->ARM_r0 = 0;
-	childregs->ARM_sp = esp;
+	childregs->ARM_sp = stack_start;
 
 	memset(&thread->cpu_context, 0, sizeof(struct cpu_context_save));
 	thread->cpu_context.sp = (unsigned long)childregs;
@@ -330,7 +305,7 @@
 int dump_fpu (struct pt_regs *regs, struct user_fp *fp)
 {
 	struct thread_info *thread = current_thread_info();
-	int used_math = current->used_math;
+	int used_math = !!used_math();
 
 	if (used_math)
 		memcpy(fp, &thread->fpstate.soft, sizeof (*fp));
@@ -367,35 +342,42 @@
 }
 
 /*
- * This is the mechanism for creating a new kernel thread.
- *
- * NOTE! Only a kernel-only process(ie the swapper or direct descendants
- * who haven't done an "execve()") should use this: it will work within
- * a system call from a "real" process, but the process memory space will
- * not be free'd until both the parent and the child have exited.
- * FIXME - taken from arm32
+ * Shuffle the argument into the correct register before calling the
+ * thread function.  r1 is the thread argument, r2 is the pointer to
+ * the thread function, and r3 points to the exit function.
+ * FIXME - make sure this is right - the older code used to zero fp
+ * and cause the parent to call sys_exit (do_exit in this version)
+ */
+extern void kernel_thread_helper(void);
+
+asm(    ".section .text\n"
+"       .align\n"
+"       .type   kernel_thread_helper, #function\n"
+"kernel_thread_helper:\n"
+"       mov     r0, r1\n"
+"       mov     lr, r3\n"
+"       mov     pc, r2\n"
+"       .size   kernel_thread_helper, . - kernel_thread_helper\n"
+"       .previous");
+
+/*
+ * Create a kernel thread.
  */
 pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
 {
-        register unsigned int r0 asm("r0") = flags | CLONE_VM | CLONE_UNTRACED;
-        register unsigned int r1 asm("r1") = 0;
-        register pid_t __ret asm("r0");
-
-        __asm__ __volatile__(
-        __syscall(clone)"       @ kernel_thread sys_clone       \n\
-        movs    %0, r0          @ if we are the child           \n\
-        bne     1f                                              \n\
-        mov     fp, #0          @ ensure that fp is zero        \n\
-        mov     r0, %4                                          \n\
-        mov     lr, pc                                          \n\
-        mov     pc, %3                                          \n\
-        b       sys_exit                                        \n\
-1:      "
-        : "=r" (__ret)
-        : "0" (r0), "r" (r1), "r" (fn), "r" (arg)
-        : "lr");
-        return __ret;
+        struct pt_regs regs;
+
+        memset(&regs, 0, sizeof(regs));
+
+        regs.ARM_r1 = (unsigned long)arg;
+        regs.ARM_r2 = (unsigned long)fn;
+        regs.ARM_r3 = (unsigned long)do_exit;
+        regs.ARM_pc = (unsigned long)kernel_thread_helper | MODE_SVC26;
+
+        return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
 }
+EXPORT_SYMBOL(kernel_thread);
+
 
 unsigned long get_wchan(struct task_struct *p)
 {
diff -Nru a/arch/arm26/kernel/ptrace.c b/arch/arm26/kernel/ptrace.c
--- a/arch/arm26/kernel/ptrace.c	2005-03-01 23:38:57 -08:00
+++ b/arch/arm26/kernel/ptrace.c	2005-03-01 23:38:57 -08:00
@@ -540,7 +540,7 @@
  */
 static int ptrace_setfpregs(struct task_struct *tsk, void *ufp)
 {
-	tsk->used_math = 1;
+	set_stopped_child_used_math(tsk);
 	return copy_from_user(&tsk->thread_info->fpstate, ufp,
 			      sizeof(struct user_fp)) ? -EFAULT : 0;
 }
diff -Nru a/arch/arm26/kernel/semaphore.c b/arch/arm26/kernel/semaphore.c
--- a/arch/arm26/kernel/semaphore.c	2005-03-01 23:38:54 -08:00
+++ b/arch/arm26/kernel/semaphore.c	2005-03-01 23:38:54 -08:00
@@ -12,6 +12,7 @@
  * 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/config.h>
 #include <linux/sched.h>
 #include <linux/errno.h>
@@ -55,7 +56,7 @@
 	wake_up(&sem->wait);
 }
 
-static spinlock_t semaphore_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(semaphore_lock);
 
 void __sched __down(struct semaphore * sem)
 {
@@ -179,7 +180,7 @@
  * registers (r0 to r3 and lr), but not ip, as we use it as a return
  * value in some cases..
  */
-asm("	.section .sched.text			\n\
+asm("	.section .sched.text , #alloc, #execinstr	\n\
 	.align	5				\n\
 	.globl	__down_failed			\n\
 __down_failed:					\n\
@@ -214,4 +215,9 @@
 	bl	__up				\n\
 	ldmfd	sp!, {r0 - r3, pc}^		\n\
 	");
+
+EXPORT_SYMBOL(__down_failed);
+EXPORT_SYMBOL(__down_interruptible_failed);
+EXPORT_SYMBOL(__down_trylock_failed);
+EXPORT_SYMBOL(__up_wakeup);
 
diff -Nru a/arch/arm26/kernel/setup.c b/arch/arm26/kernel/setup.c
--- a/arch/arm26/kernel/setup.c	2005-03-01 23:38:53 -08:00
+++ b/arch/arm26/kernel/setup.c	2005-03-01 23:38:53 -08:00
@@ -1,5 +1,5 @@
 /*
- *  linux/arch/arm/kernel/setup.c
+ *  linux/arch/arm26/kernel/setup.c
  *
  *  Copyright (C) 1995-2001 Russell King
  *  Copyright (C) 2003 Ian Molton
@@ -37,7 +37,7 @@
 #endif
 
 #ifdef CONFIG_PREEMPT
-spinlock_t kernel_flag = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(kernel_flag);
 #endif
 
 #if defined(CONFIG_FPE_NWFPE)
@@ -119,7 +119,7 @@
 	/*
 	 * locate processor in the list of supported processor
 	 * types.  The linker builds this table for us from the
-	 * entries in arch/arm/mm/proc-*.S
+	 * entries in arch/arm26/mm/proc-*.S
 	 */
 	for (list = &__proc_info_begin; list < &__proc_info_end ; list++)
 		if ((processor_id & list->cpu_mask) == list->cpu_val)
diff -Nru a/arch/arm26/kernel/sys_arm.c b/arch/arm26/kernel/sys_arm.c
--- a/arch/arm26/kernel/sys_arm.c	2005-03-01 23:38:58 -08:00
+++ b/arch/arm26/kernel/sys_arm.c	2005-03-01 23:38:58 -08:00
@@ -13,6 +13,7 @@
  *  have a non-standard calling sequence on the Linux/arm
  *  platform.
  */
+#include <linux/module.h>
 #include <linux/errno.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
@@ -281,3 +282,43 @@
 out:
 	return error;
 }
+
+/* FIXME - see if this is correct for arm26 */
+long execve(const char *filename, char **argv, char **envp)
+{
+	struct pt_regs regs;
+        int ret;
+         memset(&regs, 0, sizeof(struct pt_regs));
+        ret = do_execve((char *)filename, (char __user * __user *)argv,                         (char __user * __user *)envp, &regs);
+        if (ret < 0)
+                goto out;
+
+        /*
+         * Save argc to the register structure for userspace.
+         */
+        regs.ARM_r0 = ret;
+
+        /*
+         * We were successful.  We won't be returning to our caller, but
+         * instead to user space by manipulating the kernel stack.
+         */
+        asm(    "add    r0, %0, %1\n\t"
+                "mov    r1, %2\n\t"
+                "mov    r2, %3\n\t"
+                "bl     memmove\n\t"    /* copy regs to top of stack */
+                "mov    r8, #0\n\t"     /* not a syscall */
+                "mov    r9, %0\n\t"     /* thread structure */
+                "mov    sp, r0\n\t"     /* reposition stack pointer */
+                "b      ret_to_user"
+                :
+                : "r" (current_thread_info()),
+                  "Ir" (THREAD_SIZE - 8 - sizeof(regs)),
+                  "r" (&regs),
+                  "Ir" (sizeof(regs))
+                : "r0", "r1", "r2", "r3", "ip", "memory");
+
+ out:
+        return ret;
+}
+
+EXPORT_SYMBOL(execve);
diff -Nru a/arch/arm26/kernel/time-acorn.c b/arch/arm26/kernel/time-acorn.c
--- a/arch/arm26/kernel/time-acorn.c	2005-03-01 23:38:53 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,69 +0,0 @@
-/*
- *  linux/arch/arm/kernel/time-acorn.c
- *
- *  Copyright (c) 1996-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.
- *
- *  Changelog:
- *   24-Sep-1996	RMK	Created
- *   10-Oct-1996	RMK	Brought up to date with arch-sa110eval
- *   04-Dec-1997	RMK	Updated for new arch/arm/time.c
- *   13-May-2003        IM      Brought over to ARM26
- */
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-
-#include <asm/hardware.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/ioc.h>
-
-extern unsigned long (*gettimeoffset)(void);
-
-static unsigned long ioctime_gettimeoffset(void)
-{
-	unsigned int count1, count2, status;
-        long offset;
-
-        ioc_writeb (0, IOC_T0LATCH);
-        barrier ();
-        count1 = ioc_readb(IOC_T0CNTL) | (ioc_readb(IOC_T0CNTH) << 8);
-        barrier ();
-        status = ioc_readb(IOC_IRQREQA);
-        barrier ();
-        ioc_writeb (0, IOC_T0LATCH);
-        barrier ();
-        count2 = ioc_readb(IOC_T0CNTL) | (ioc_readb(IOC_T0CNTH) << 8);
-
-        offset = count2;
-        if (count2 < count1) {
-                /*
-                 * We have not had an interrupt between reading count1
-                 * and count2.
-                 */
-                if (status & (1 << 5))
-                        offset -= LATCH;
-        } else if (count2 > count1) {
-                /*
-                 * We have just had another interrupt between reading
-                 * count1 and count2.
-                 */
-                offset -= LATCH;
-        }
-
-        offset = (LATCH - offset) * (tick_nsec / 1000);
-        return (offset + LATCH/2) / LATCH;
-}
-
-void __init ioctime_init(void)
-{
-	ioc_writeb(LATCH & 255, IOC_T0LTCHL);
-	ioc_writeb(LATCH >> 8, IOC_T0LTCHH);
-	ioc_writeb(0, IOC_T0GO);
-
-	gettimeoffset = ioctime_gettimeoffset;
-}
diff -Nru a/arch/arm26/kernel/time.c b/arch/arm26/kernel/time.c
--- a/arch/arm26/kernel/time.c	2005-03-01 23:39:07 -08:00
+++ b/arch/arm26/kernel/time.c	2005-03-01 23:39:07 -08:00
@@ -32,7 +32,7 @@
 #include <asm/hardware.h>
 #include <asm/io.h>
 #include <asm/irq.h>
-#include <asm/leds.h>
+#include <asm/ioc.h>
 
 u64 jiffies_64 = INITIAL_JIFFIES;
 
@@ -41,7 +41,7 @@
 extern unsigned long wall_jiffies;
 
 /* this needs a better home */
-spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(rtc_lock);
 
 /* change this if you have some constant time drift */
 #define USECS_PER_JIFFY	(1000000/HZ)
@@ -56,16 +56,53 @@
  */
 int (*set_rtc)(void) = dummy_set_rtc;
 
-static unsigned long dummy_gettimeoffset(void)
+/*
+ * Get time offset based on IOCs timer.
+ * FIXME - if this is called with interrutps off, why the shennanigans
+ * below ?
+ */
+static unsigned long gettimeoffset(void)
 {
-	return 0;
+        unsigned int count1, count2, status;
+        long offset;
+
+        ioc_writeb (0, IOC_T0LATCH);
+        barrier ();
+        count1 = ioc_readb(IOC_T0CNTL) | (ioc_readb(IOC_T0CNTH) << 8);
+        barrier ();
+        status = ioc_readb(IOC_IRQREQA);
+        barrier ();
+        ioc_writeb (0, IOC_T0LATCH);
+        barrier ();
+        count2 = ioc_readb(IOC_T0CNTL) | (ioc_readb(IOC_T0CNTH) << 8);
+
+        offset = count2;
+        if (count2 < count1) {
+                /*
+                 * We have not had an interrupt between reading count1
+                 * and count2.
+                 */
+                if (status & (1 << 5))
+                        offset -= LATCH;
+        } else if (count2 > count1) {
+                /*
+                 * We have just had another interrupt between reading
+                 * count1 and count2.
+                 */
+                offset -= LATCH;
+        }
+
+        offset = (LATCH - offset) * (tick_nsec / 1000);
+        return (offset + LATCH/2) / LATCH;
 }
 
 /*
- * hook for getting the time offset.  Note that it is
- * always called with interrupts disabled.
+ * Scheduler clock - returns current time in nanosec units.
  */
-unsigned long (*gettimeoffset)(void) = dummy_gettimeoffset;
+unsigned long long sched_clock(void)
+{
+	return (unsigned long long)jiffies * (1000000000 / HZ);
+}
 
 static unsigned long next_rtc_update;
 
@@ -187,7 +224,10 @@
  */
 void __init time_init(void)
 {
-        ioctime_init();
+	ioc_writeb(LATCH & 255, IOC_T0LTCHL);
+        ioc_writeb(LATCH >> 8, IOC_T0LTCHH);
+        ioc_writeb(0, IOC_T0GO);
+
 
         setup_irq(IRQ_TIMER, &timer_irq);
 }
diff -Nru a/arch/arm26/kernel/traps.c b/arch/arm26/kernel/traps.c
--- a/arch/arm26/kernel/traps.c	2005-03-01 23:39:07 -08:00
+++ b/arch/arm26/kernel/traps.c	2005-03-01 23:39:07 -08:00
@@ -1,5 +1,5 @@
 /*
- *  linux/arch/arm/kernel/traps.c
+ *  linux/arch/arm26/kernel/traps.c
  *
  *  Copyright (C) 1995-2002 Russell King
  *  Fragments that appear the same as linux/arch/i386/kernel/traps.c (C) Linus Torvalds
@@ -10,9 +10,11 @@
  * published by the Free Software Foundation.
  *
  *  'traps.c' handles hardware exceptions after we have saved some state in
- *  'linux/arch/arm/lib/traps.S'.  Mostly a debugging aid, but will probably
+ *  'linux/arch/arm26/lib/traps.S'.  Mostly a debugging aid, but will probably
  *  kill the offending process.
  */
+
+#include <linux/module.h>
 #include <linux/config.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
@@ -28,7 +30,6 @@
 
 #include <asm/atomic.h>
 #include <asm/io.h>
-#include <asm/pgalloc.h>
 #include <asm/pgtable.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -134,8 +135,6 @@
 	dump_mem("Stack: ", sp, 8192+(unsigned long)tsk->thread_info);
 }
 
-EXPORT_SYMBOL(dump_stack);
-
 void dump_stack(void)
 {
 #ifdef CONFIG_DEBUG_ERRORS
@@ -143,6 +142,8 @@
 #endif
 }
 
+EXPORT_SYMBOL(dump_stack);
+
 //FIXME - was a static fn
 void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
 {
@@ -170,7 +171,7 @@
 	dump_mem("Stack: ", (unsigned long)sp, 8192+(unsigned long)task->thread_info);
 }
 
-spinlock_t die_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(die_lock);
 
 /*
  * This function is protected against re-entrancy.
@@ -425,7 +426,6 @@
 		return 0;
 
 	case NR(usr26):
-	case NR(usr32):
 		break;
 
 	default:
diff -Nru a/arch/arm26/kernel/vmlinux-arm26-xip.lds.in b/arch/arm26/kernel/vmlinux-arm26-xip.lds.in
--- a/arch/arm26/kernel/vmlinux-arm26-xip.lds.in	2005-03-01 23:39:09 -08:00
+++ b/arch/arm26/kernel/vmlinux-arm26-xip.lds.in	2005-03-01 23:39:09 -08:00
@@ -64,6 +64,7 @@
 		_text = .;		/* Text and read-only data	*/
 			*(.text)
 			SCHED_TEXT
+			LOCK_TEXT       /* FIXME - borrowed from arm32 - check*/
 			*(.fixup)
 			*(.gnu.warning)
 			*(.rodata)
@@ -91,9 +92,11 @@
 	_sdata = .;
 
 	.data : {
+		. = ALIGN(8192);
 		/*
 		 * first, the init thread union, aligned
-		 * to an 8192 byte boundary.
+		 * to an 8192 byte boundary. (see arm26/kernel/init_task.c)
+		 * FIXME - sould this be 32K aligned on arm26?
 		 */
 		*(.init.task)
 
diff -Nru a/arch/arm26/kernel/vmlinux-arm26.lds.in b/arch/arm26/kernel/vmlinux-arm26.lds.in
--- a/arch/arm26/kernel/vmlinux-arm26.lds.in	2005-03-01 23:38:52 -08:00
+++ b/arch/arm26/kernel/vmlinux-arm26.lds.in	2005-03-01 23:38:52 -08:00
@@ -65,6 +65,7 @@
 		_text = .;		/* Text and read-only data	*/
 			*(.text)
 			SCHED_TEXT
+			LOCK_TEXT
 			*(.fixup)
 			*(.gnu.warning)
 			*(.rodata)
@@ -90,7 +91,7 @@
 	.data : {
 		/*
 		 * first, the init task union, aligned
-		 * to an 8192 byte boundary.
+		 * to an 8192 byte boundary. (see arm26/kernel/init_task.c)
 		 */
 		*(.init.task)
 
diff -Nru a/arch/arm26/lib/Makefile b/arch/arm26/lib/Makefile
--- a/arch/arm26/lib/Makefile	2005-03-01 23:39:07 -08:00
+++ b/arch/arm26/lib/Makefile	2005-03-01 23:39:07 -08:00
@@ -1,5 +1,5 @@
 #
-# linux/arch/arm/lib/Makefile
+# linux/arch/arm26/lib/Makefile
 #
 # Copyright (C) 1995-2000 Russell King
 #
@@ -7,15 +7,15 @@
 lib-y		:= backtrace.o changebit.o csumipv6.o csumpartial.o   \
 		   csumpartialcopy.o csumpartialcopyuser.o clearbit.o \
 		   copy_page.o delay.o findbit.o memchr.o memcpy.o    \
-		   memset.o memzero.o setbit.o    \
-		   strchr.o strrchr.o testchangebit.o  \
+		   memset.o memzero.o setbit.o                        \
+		   strchr.o strrchr.o testchangebit.o                 \
 		   testclearbit.o testsetbit.o getuser.o              \
 		   putuser.o ashldi3.o ashrdi3.o lshrdi3.o muldi3.o   \
 		   ucmpdi2.o udivdi3.o lib1funcs.o ecard.o io-acorn.o \
 		   floppydma.o io-readsb.o io-writesb.o io-writesl.o  \
-		   uaccess-kernel.o uaccess-user.o io-readsw-armv3.o  \
-		   io-writesw-armv3.o io-readsl-armv3.o ecard.o       \
-		   io-acorn.o floppydma.o
+		   uaccess-kernel.o uaccess-user.o io-readsw.o        \
+		   io-writesw.o io-readsl.o ecard.o io-acorn.o        \
+		   floppydma.o
 
 lib-n		:=
 
diff -Nru a/arch/arm26/lib/backtrace.S b/arch/arm26/lib/backtrace.S
--- a/arch/arm26/lib/backtrace.S	2005-03-01 23:39:08 -08:00
+++ b/arch/arm26/lib/backtrace.S	2005-03-01 23:39:08 -08:00
@@ -1,5 +1,5 @@
 /*
- *  linux/arch/arm/lib/backtrace.S
+ *  linux/arch/arm26/lib/backtrace.S
  *
  *  Copyright (C) 1995, 1996 Russell King
  *
diff -Nru a/arch/arm26/lib/changebit.S b/arch/arm26/lib/changebit.S
--- a/arch/arm26/lib/changebit.S	2005-03-01 23:39:08 -08:00
+++ b/arch/arm26/lib/changebit.S	2005-03-01 23:39:08 -08:00
@@ -1,5 +1,5 @@
 /*
- *  linux/arch/arm/lib/changebit.S
+ *  linux/arch/arm26/lib/changebit.S
  *
  *  Copyright (C) 1995-1996 Russell King
  *
diff -Nru a/arch/arm26/lib/clearbit.S b/arch/arm26/lib/clearbit.S
--- a/arch/arm26/lib/clearbit.S	2005-03-01 23:38:52 -08:00
+++ b/arch/arm26/lib/clearbit.S	2005-03-01 23:38:52 -08:00
@@ -1,5 +1,5 @@
 /*
- *  linux/arch/arm/lib/clearbit.S
+ *  linux/arch/arm26/lib/clearbit.S
  *
  *  Copyright (C) 1995-1996 Russell King
  *
diff -Nru a/arch/arm26/lib/copy_page.S b/arch/arm26/lib/copy_page.S
--- a/arch/arm26/lib/copy_page.S	2005-03-01 23:38:52 -08:00
+++ b/arch/arm26/lib/copy_page.S	2005-03-01 23:38:52 -08:00
@@ -1,5 +1,5 @@
 /*
- *  linux/arch/arm/lib/copypage.S
+ *  linux/arch/arm26/lib/copypage.S
  *
  *  Copyright (C) 1995-1999 Russell King
  *
diff -Nru a/arch/arm26/lib/csumipv6.S b/arch/arm26/lib/csumipv6.S
--- a/arch/arm26/lib/csumipv6.S	2005-03-01 23:39:09 -08:00
+++ b/arch/arm26/lib/csumipv6.S	2005-03-01 23:39:09 -08:00
@@ -1,5 +1,5 @@
 /*
- *  linux/arch/arm/lib/csumipv6.S
+ *  linux/arch/arm26/lib/csumipv6.S
  *
  *  Copyright (C) 1995-1998 Russell King
  *
diff -Nru a/arch/arm26/lib/csumpartial.S b/arch/arm26/lib/csumpartial.S
--- a/arch/arm26/lib/csumpartial.S	2005-03-01 23:38:53 -08:00
+++ b/arch/arm26/lib/csumpartial.S	2005-03-01 23:38:53 -08:00
@@ -1,5 +1,5 @@
 /*
- *  linux/arch/arm/lib/csumpartial.S
+ *  linux/arch/arm26/lib/csumpartial.S
  *
  *  Copyright (C) 1995-1998 Russell King
  *
diff -Nru a/arch/arm26/lib/csumpartialcopy.S b/arch/arm26/lib/csumpartialcopy.S
--- a/arch/arm26/lib/csumpartialcopy.S	2005-03-01 23:38:57 -08:00
+++ b/arch/arm26/lib/csumpartialcopy.S	2005-03-01 23:38:57 -08:00
@@ -1,5 +1,5 @@
 /*
- *  linux/arch/arm/lib/csumpartialcopy.S
+ *  linux/arch/arm26/lib/csumpartialcopy.S
  *
  *  Copyright (C) 1995-1998 Russell King
  *
diff -Nru a/arch/arm26/lib/csumpartialcopygeneric.S b/arch/arm26/lib/csumpartialcopygeneric.S
--- a/arch/arm26/lib/csumpartialcopygeneric.S	2005-03-01 23:38:58 -08:00
+++ b/arch/arm26/lib/csumpartialcopygeneric.S	2005-03-01 23:38:58 -08:00
@@ -1,5 +1,5 @@
 /*
- *  linux/arch/arm/lib/csumpartialcopygeneric.S
+ *  linux/arch/arm26/lib/csumpartialcopygeneric.S
  *
  *  Copyright (C) 1995-2001 Russell King
  *
diff -Nru a/arch/arm26/lib/delay.S b/arch/arm26/lib/delay.S
--- a/arch/arm26/lib/delay.S	2005-03-01 23:39:17 -08:00
+++ b/arch/arm26/lib/delay.S	2005-03-01 23:39:17 -08:00
@@ -1,5 +1,5 @@
 /*
- *  linux/arch/arm/lib/delay.S
+ *  linux/arch/arm26/lib/delay.S
  *
  *  Copyright (C) 1995, 1996 Russell King
  *
diff -Nru a/arch/arm26/lib/ecard.S b/arch/arm26/lib/ecard.S
--- a/arch/arm26/lib/ecard.S	2005-03-01 23:39:07 -08:00
+++ b/arch/arm26/lib/ecard.S	2005-03-01 23:39:07 -08:00
@@ -1,5 +1,5 @@
 /*
- *  linux/arch/arm/lib/ecard.S
+ *  linux/arch/arm26/lib/ecard.S
  *
  *  Copyright (C) 1995, 1996 Russell King
  *
diff -Nru a/arch/arm26/lib/floppydma.S b/arch/arm26/lib/floppydma.S
--- a/arch/arm26/lib/floppydma.S	2005-03-01 23:38:52 -08:00
+++ b/arch/arm26/lib/floppydma.S	2005-03-01 23:38:52 -08:00
@@ -1,5 +1,5 @@
 /*
- *  linux/arch/arm/lib/floppydma.S
+ *  linux/arch/arm26/lib/floppydma.S
  *
  *  Copyright (C) 1995, 1996 Russell King
  *
diff -Nru a/arch/arm26/lib/getuser.S b/arch/arm26/lib/getuser.S
--- a/arch/arm26/lib/getuser.S	2005-03-01 23:39:17 -08:00
+++ b/arch/arm26/lib/getuser.S	2005-03-01 23:39:17 -08:00
@@ -1,5 +1,5 @@
 /*
- *  linux/arch/arm/lib/getuser.S
+ *  linux/arch/arm26/lib/getuser.S
  *
  *  Copyright (C) 2001 Russell King
  *
@@ -28,6 +28,7 @@
  */
 #include <asm/asm_offsets.h>
 #include <asm/thread_info.h>
+#include <asm/errno.h>
 
         .global __get_user_1
 __get_user_1:
@@ -98,7 +99,7 @@
         mov     r2, #0
 __get_user_bad:
         mov     r1, #0
-        mov     r0, #-14
+        mov     r0, #-EFAULT
         ldmfd   sp!, {pc}^
 
 .section __ex_table, "a"
diff -Nru a/arch/arm26/lib/io-acorn.S b/arch/arm26/lib/io-acorn.S
--- a/arch/arm26/lib/io-acorn.S	2005-03-01 23:39:16 -08:00
+++ b/arch/arm26/lib/io-acorn.S	2005-03-01 23:39:16 -08:00
@@ -1,5 +1,5 @@
 /*
- *  linux/arch/arm/lib/io-acorn.S
+ *  linux/arch/arm26/lib/io-acorn.S
  *
  *  Copyright (C) 1995, 1996 Russell King
  *
diff -Nru a/arch/arm26/lib/io-readsb.S b/arch/arm26/lib/io-readsb.S
--- a/arch/arm26/lib/io-readsb.S	2005-03-01 23:39:08 -08:00
+++ b/arch/arm26/lib/io-readsb.S	2005-03-01 23:39:08 -08:00
@@ -1,5 +1,5 @@
 /*
- *  linux/arch/arm/lib/io-readsb.S
+ *  linux/arch/arm26/lib/io-readsb.S
  *
  *  Copyright (C) 1995-2000 Russell King
  *
diff -Nru a/arch/arm26/lib/io-readsl-armv3.S b/arch/arm26/lib/io-readsl-armv3.S
--- a/arch/arm26/lib/io-readsl-armv3.S	2005-03-01 23:39:07 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,78 +0,0 @@
-/*
- *  linux/arch/arm/lib/io-readsl-armv3.S
- *
- *  Copyright (C) 1995-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.
- */
-#include <linux/linkage.h>
-#include <asm/assembler.h>
-#include <asm/hardware.h>
-
-/*
- * Note that some reads can be aligned on half-word boundaries.
- */
-ENTRY(__raw_readsl)
-		teq	r2, #0		@ do we have to check for the zero len?
-		moveq	pc, lr
-		ands	ip, r1, #3
-		bne	2f
-
-1:		ldr	r3, [r0]
-		str	r3, [r1], #4
-		subs	r2, r2, #1
-		bne	1b
-		mov	pc, lr
-
-2:		cmp	ip, #2
-		ldr	ip, [r0]
-		blt	4f
-		bgt	6f
-
-		strb	ip, [r1], #1
-		mov	ip, ip, lsr #8
-		strb	ip, [r1], #1
-		mov	ip, ip, lsr #8
-3:		subs	r2, r2, #1
-		ldrne	r3, [r0]
-		orrne	ip, ip, r3, lsl #16
-		strne	ip, [r1], #4
-		movne	ip, r3, lsr #16
-		bne	3b
-		strb	ip, [r1], #1
-		mov	ip, ip, lsr #8
-		strb	ip, [r1], #1
-		mov	pc, lr
-
-4:		strb	ip, [r1], #1
-		mov	ip, ip, lsr #8
-		strb	ip, [r1], #1
-		mov	ip, ip, lsr #8
-		strb	ip, [r1], #1
-		mov	ip, ip, lsr #8
-5:		subs	r2, r2, #1
-		ldrne	r3, [r0]
-		orrne	ip, ip, r3, lsl #8
-		strne	ip, [r1], #4
-		movne	ip, r3, lsr #24
-		bne	5b
-		strb	ip, [r1], #1
-		mov	pc, lr
-
-6:		strb	ip, [r1], #1
-		mov	ip, ip, lsr #8
-7:		subs	r2, r2, #1
-		ldrne	r3, [r0]
-		orrne	ip, ip, r3, lsl #24
-		strne	ip, [r1], #4
-		movne	ip, r3, lsr #8
-		bne	7b
-		strb	ip, [r1], #1
-		mov	ip, ip, lsr #8
-		strb	ip, [r1], #1
-		mov	ip, ip, lsr #8
-		strb	ip, [r1], #1
-		mov	pc, lr
-
diff -Nru a/arch/arm26/lib/io-readsl.S b/arch/arm26/lib/io-readsl.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/arm26/lib/io-readsl.S	2005-03-01 23:39:07 -08:00
@@ -0,0 +1,78 @@
+/*
+ *  linux/arch/arm26/lib/io-readsl.S
+ *
+ *  Copyright (C) 1995-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.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/hardware.h>
+
+/*
+ * Note that some reads can be aligned on half-word boundaries.
+ */
+ENTRY(__raw_readsl)
+		teq	r2, #0		@ do we have to check for the zero len?
+		moveq	pc, lr
+		ands	ip, r1, #3
+		bne	2f
+
+1:		ldr	r3, [r0]
+		str	r3, [r1], #4
+		subs	r2, r2, #1
+		bne	1b
+		mov	pc, lr
+
+2:		cmp	ip, #2
+		ldr	ip, [r0]
+		blt	4f
+		bgt	6f
+
+		strb	ip, [r1], #1
+		mov	ip, ip, lsr #8
+		strb	ip, [r1], #1
+		mov	ip, ip, lsr #8
+3:		subs	r2, r2, #1
+		ldrne	r3, [r0]
+		orrne	ip, ip, r3, lsl #16
+		strne	ip, [r1], #4
+		movne	ip, r3, lsr #16
+		bne	3b
+		strb	ip, [r1], #1
+		mov	ip, ip, lsr #8
+		strb	ip, [r1], #1
+		mov	pc, lr
+
+4:		strb	ip, [r1], #1
+		mov	ip, ip, lsr #8
+		strb	ip, [r1], #1
+		mov	ip, ip, lsr #8
+		strb	ip, [r1], #1
+		mov	ip, ip, lsr #8
+5:		subs	r2, r2, #1
+		ldrne	r3, [r0]
+		orrne	ip, ip, r3, lsl #8
+		strne	ip, [r1], #4
+		movne	ip, r3, lsr #24
+		bne	5b
+		strb	ip, [r1], #1
+		mov	pc, lr
+
+6:		strb	ip, [r1], #1
+		mov	ip, ip, lsr #8
+7:		subs	r2, r2, #1
+		ldrne	r3, [r0]
+		orrne	ip, ip, r3, lsl #24
+		strne	ip, [r1], #4
+		movne	ip, r3, lsr #8
+		bne	7b
+		strb	ip, [r1], #1
+		mov	ip, ip, lsr #8
+		strb	ip, [r1], #1
+		mov	ip, ip, lsr #8
+		strb	ip, [r1], #1
+		mov	pc, lr
+
diff -Nru a/arch/arm26/lib/io-readsw-armv3.S b/arch/arm26/lib/io-readsw-armv3.S
--- a/arch/arm26/lib/io-readsw-armv3.S	2005-03-01 23:38:51 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,107 +0,0 @@
-/*
- *  linux/arch/arm/lib/io-readsw-armv3.S
- *
- *  Copyright (C) 1995-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.
- */
-#include <linux/linkage.h>
-#include <asm/assembler.h>
-#include <asm/hardware.h>
-
-.insw_bad_alignment:
-		adr	r0, .insw_bad_align_msg
-		mov	r2, lr
-		b	panic
-.insw_bad_align_msg:
-		.asciz	"insw: bad buffer alignment (0x%p, lr=0x%08lX)\n"
-		.align
-
-.insw_align:	tst	r1, #1
-		bne	.insw_bad_alignment
-
-		ldr	r3, [r0]
-		strb	r3, [r1], #1
-		mov	r3, r3, lsr #8
-		strb	r3, [r1], #1
-
-		subs	r2, r2, #1
-		RETINSTR(moveq, pc, lr)
-
-ENTRY(__raw_readsw)
-		teq	r2, #0		@ do we have to check for the zero len?
-		moveq	pc, lr
-		tst	r1, #3
-		bne	.insw_align
-
-.insw_aligned:	mov	ip, #0xff
-		orr	ip, ip, ip, lsl #8
-		stmfd	sp!, {r4, r5, r6, lr}
-
-		subs	r2, r2, #8
-		bmi	.no_insw_8
-
-.insw_8_lp:	ldr	r3, [r0]
-		and	r3, r3, ip
-		ldr	r4, [r0]
-		orr	r3, r3, r4, lsl #16
-
-		ldr	r4, [r0]
-		and	r4, r4, ip
-		ldr	r5, [r0]
-		orr	r4, r4, r5, lsl #16
-
-		ldr	r5, [r0]
-		and	r5, r5, ip
-		ldr	r6, [r0]
-		orr	r5, r5, r6, lsl #16
-
-		ldr	r6, [r0]
-		and	r6, r6, ip
-		ldr	lr, [r0]
-		orr	r6, r6, lr, lsl #16
-
-		stmia	r1!, {r3 - r6}
-
-		subs	r2, r2, #8
-		bpl	.insw_8_lp
-
-		tst	r2, #7
-		LOADREGS(eqfd, sp!, {r4, r5, r6, pc})
-
-.no_insw_8:	tst	r2, #4
-		beq	.no_insw_4
-
-		ldr	r3, [r0]
-		and	r3, r3, ip
-		ldr	r4, [r0]
-		orr	r3, r3, r4, lsl #16
-
-		ldr	r4, [r0]
-		and	r4, r4, ip
-		ldr	r5, [r0]
-		orr	r4, r4, r5, lsl #16
-
-		stmia	r1!, {r3, r4}
-
-.no_insw_4:	tst	r2, #2
-		beq	.no_insw_2
-
-		ldr	r3, [r0]
-		and	r3, r3, ip
-		ldr	r4, [r0]
-		orr	r3, r3, r4, lsl #16
-
-		str	r3, [r1], #4
-
-.no_insw_2:	tst	r2, #1
-		ldrne	r3, [r0]
-		strneb	r3, [r1], #1
-		movne	r3, r3, lsr #8
-		strneb	r3, [r1]
-
-		LOADREGS(fd, sp!, {r4, r5, r6, pc})
-
-
diff -Nru a/arch/arm26/lib/io-readsw.S b/arch/arm26/lib/io-readsw.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/arm26/lib/io-readsw.S	2005-03-01 23:38:51 -08:00
@@ -0,0 +1,107 @@
+/*
+ *  linux/arch/arm26/lib/io-readsw.S
+ *
+ *  Copyright (C) 1995-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.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/hardware.h>
+
+.insw_bad_alignment:
+		adr	r0, .insw_bad_align_msg
+		mov	r2, lr
+		b	panic
+.insw_bad_align_msg:
+		.asciz	"insw: bad buffer alignment (0x%p, lr=0x%08lX)\n"
+		.align
+
+.insw_align:	tst	r1, #1
+		bne	.insw_bad_alignment
+
+		ldr	r3, [r0]
+		strb	r3, [r1], #1
+		mov	r3, r3, lsr #8
+		strb	r3, [r1], #1
+
+		subs	r2, r2, #1
+		RETINSTR(moveq, pc, lr)
+
+ENTRY(__raw_readsw)
+		teq	r2, #0		@ do we have to check for the zero len?
+		moveq	pc, lr
+		tst	r1, #3
+		bne	.insw_align
+
+.insw_aligned:	mov	ip, #0xff
+		orr	ip, ip, ip, lsl #8
+		stmfd	sp!, {r4, r5, r6, lr}
+
+		subs	r2, r2, #8
+		bmi	.no_insw_8
+
+.insw_8_lp:	ldr	r3, [r0]
+		and	r3, r3, ip
+		ldr	r4, [r0]
+		orr	r3, r3, r4, lsl #16
+
+		ldr	r4, [r0]
+		and	r4, r4, ip
+		ldr	r5, [r0]
+		orr	r4, r4, r5, lsl #16
+
+		ldr	r5, [r0]
+		and	r5, r5, ip
+		ldr	r6, [r0]
+		orr	r5, r5, r6, lsl #16
+
+		ldr	r6, [r0]
+		and	r6, r6, ip
+		ldr	lr, [r0]
+		orr	r6, r6, lr, lsl #16
+
+		stmia	r1!, {r3 - r6}
+
+		subs	r2, r2, #8
+		bpl	.insw_8_lp
+
+		tst	r2, #7
+		LOADREGS(eqfd, sp!, {r4, r5, r6, pc})
+
+.no_insw_8:	tst	r2, #4
+		beq	.no_insw_4
+
+		ldr	r3, [r0]
+		and	r3, r3, ip
+		ldr	r4, [r0]
+		orr	r3, r3, r4, lsl #16
+
+		ldr	r4, [r0]
+		and	r4, r4, ip
+		ldr	r5, [r0]
+		orr	r4, r4, r5, lsl #16
+
+		stmia	r1!, {r3, r4}
+
+.no_insw_4:	tst	r2, #2
+		beq	.no_insw_2
+
+		ldr	r3, [r0]
+		and	r3, r3, ip
+		ldr	r4, [r0]
+		orr	r3, r3, r4, lsl #16
+
+		str	r3, [r1], #4
+
+.no_insw_2:	tst	r2, #1
+		ldrne	r3, [r0]
+		strneb	r3, [r1], #1
+		movne	r3, r3, lsr #8
+		strneb	r3, [r1]
+
+		LOADREGS(fd, sp!, {r4, r5, r6, pc})
+
+
diff -Nru a/arch/arm26/lib/io-writesb.S b/arch/arm26/lib/io-writesb.S
--- a/arch/arm26/lib/io-writesb.S	2005-03-01 23:38:54 -08:00
+++ b/arch/arm26/lib/io-writesb.S	2005-03-01 23:38:54 -08:00
@@ -1,5 +1,5 @@
 /*
- *  linux/arch/arm/lib/io-writesb.S
+ *  linux/arch/arm26/lib/io-writesb.S
  *
  *  Copyright (C) 1995-2000 Russell King
  *
diff -Nru a/arch/arm26/lib/io-writesl.S b/arch/arm26/lib/io-writesl.S
--- a/arch/arm26/lib/io-writesl.S	2005-03-01 23:39:10 -08:00
+++ b/arch/arm26/lib/io-writesl.S	2005-03-01 23:39:10 -08:00
@@ -1,5 +1,5 @@
 /*
- *  linux/arch/arm/lib/io-writesl.S
+ *  linux/arch/arm26/lib/io-writesl.S
  *
  *  Copyright (C) 1995-2000 Russell King
  *
diff -Nru a/arch/arm26/lib/io-writesw-armv3.S b/arch/arm26/lib/io-writesw-armv3.S
--- a/arch/arm26/lib/io-writesw-armv3.S	2005-03-01 23:38:52 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,127 +0,0 @@
-/*
- *  linux/arch/arm/lib/io-writesw-armv3.S
- *
- *  Copyright (C) 1995-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.
- */
-#include <linux/linkage.h>
-#include <asm/assembler.h>
-#include <asm/hardware.h>
-
-.outsw_bad_alignment:
-		adr	r0, .outsw_bad_align_msg
-		mov	r2, lr
-		b	panic
-.outsw_bad_align_msg:
-		.asciz	"outsw: bad buffer alignment (0x%p, lr=0x%08lX)\n"
-		.align
-
-.outsw_align:	tst	r1, #1
-		bne	.outsw_bad_alignment
-
-		add	r1, r1, #2
-
-		ldr	r3, [r1, #-4]
-		mov	r3, r3, lsr #16
-		orr	r3, r3, r3, lsl #16
-		str	r3, [r0]
-		subs	r2, r2, #1
-		RETINSTR(moveq, pc, lr)
-
-ENTRY(__raw_writesw)
-		teq	r2, #0		@ do we have to check for the zero len?
-		moveq	pc, lr
-		tst	r1, #3
-		bne	.outsw_align
-
-.outsw_aligned:	stmfd	sp!, {r4, r5, r6, lr}
-
-		subs	r2, r2, #8
-		bmi	.no_outsw_8
-
-.outsw_8_lp:	ldmia	r1!, {r3, r4, r5, r6}
-
-		mov	ip, r3, lsl #16
-		orr	ip, ip, ip, lsr #16
-		str	ip, [r0]
-
-		mov	ip, r3, lsr #16
-		orr	ip, ip, ip, lsl #16
-		str	ip, [r0]
-
-		mov	ip, r4, lsl #16
-		orr	ip, ip, ip, lsr #16
-		str	ip, [r0]
-
-		mov	ip, r4, lsr #16
-		orr	ip, ip, ip, lsl #16
-		str	ip, [r0]
-
-		mov	ip, r5, lsl #16
-		orr	ip, ip, ip, lsr #16
-		str	ip, [r0]
-
-		mov	ip, r5, lsr #16
-		orr	ip, ip, ip, lsl #16
-		str	ip, [r0]
-
-		mov	ip, r6, lsl #16
-		orr	ip, ip, ip, lsr #16
-		str	ip, [r0]
-
-		mov	ip, r6, lsr #16
-		orr	ip, ip, ip, lsl #16
-		str	ip, [r0]
-
-		subs	r2, r2, #8
-		bpl	.outsw_8_lp
-
-		tst	r2, #7
-		LOADREGS(eqfd, sp!, {r4, r5, r6, pc})
-
-.no_outsw_8:	tst	r2, #4
-		beq	.no_outsw_4
-
-		ldmia	r1!, {r3, r4}
-
-		mov	ip, r3, lsl #16
-		orr	ip, ip, ip, lsr #16
-		str	ip, [r0]
-
-		mov	ip, r3, lsr #16
-		orr	ip, ip, ip, lsl #16
-		str	ip, [r0]
-
-		mov	ip, r4, lsl #16
-		orr	ip, ip, ip, lsr #16
-		str	ip, [r0]
-
-		mov	ip, r4, lsr #16
-		orr	ip, ip, ip, lsl #16
-		str	ip, [r0]
-
-.no_outsw_4:	tst	r2, #2
-		beq	.no_outsw_2
-
-		ldr	r3, [r1], #4
-
-		mov	ip, r3, lsl #16
-		orr	ip, ip, ip, lsr #16
-		str	ip, [r0]
-
-		mov	ip, r3, lsr #16
-		orr	ip, ip, ip, lsl #16
-		str	ip, [r0]
-
-.no_outsw_2:	tst	r2, #1
-
-		ldrne	r3, [r1]
-
-		movne	ip, r3, lsl #16
-		orrne	ip, ip, ip, lsr #16
-		strne	ip, [r0]
-
-		LOADREGS(fd, sp!, {r4, r5, r6, pc})
diff -Nru a/arch/arm26/lib/io-writesw.S b/arch/arm26/lib/io-writesw.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/arm26/lib/io-writesw.S	2005-03-01 23:38:52 -08:00
@@ -0,0 +1,127 @@
+/*
+ *  linux/arch/arm26/lib/io-writesw.S
+ *
+ *  Copyright (C) 1995-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.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/hardware.h>
+
+.outsw_bad_alignment:
+		adr	r0, .outsw_bad_align_msg
+		mov	r2, lr
+		b	panic
+.outsw_bad_align_msg:
+		.asciz	"outsw: bad buffer alignment (0x%p, lr=0x%08lX)\n"
+		.align
+
+.outsw_align:	tst	r1, #1
+		bne	.outsw_bad_alignment
+
+		add	r1, r1, #2
+
+		ldr	r3, [r1, #-4]
+		mov	r3, r3, lsr #16
+		orr	r3, r3, r3, lsl #16
+		str	r3, [r0]
+		subs	r2, r2, #1
+		RETINSTR(moveq, pc, lr)
+
+ENTRY(__raw_writesw)
+		teq	r2, #0		@ do we have to check for the zero len?
+		moveq	pc, lr
+		tst	r1, #3
+		bne	.outsw_align
+
+.outsw_aligned:	stmfd	sp!, {r4, r5, r6, lr}
+
+		subs	r2, r2, #8
+		bmi	.no_outsw_8
+
+.outsw_8_lp:	ldmia	r1!, {r3, r4, r5, r6}
+
+		mov	ip, r3, lsl #16
+		orr	ip, ip, ip, lsr #16
+		str	ip, [r0]
+
+		mov	ip, r3, lsr #16
+		orr	ip, ip, ip, lsl #16
+		str	ip, [r0]
+
+		mov	ip, r4, lsl #16
+		orr	ip, ip, ip, lsr #16
+		str	ip, [r0]
+
+		mov	ip, r4, lsr #16
+		orr	ip, ip, ip, lsl #16
+		str	ip, [r0]
+
+		mov	ip, r5, lsl #16
+		orr	ip, ip, ip, lsr #16
+		str	ip, [r0]
+
+		mov	ip, r5, lsr #16
+		orr	ip, ip, ip, lsl #16
+		str	ip, [r0]
+
+		mov	ip, r6, lsl #16
+		orr	ip, ip, ip, lsr #16
+		str	ip, [r0]
+
+		mov	ip, r6, lsr #16
+		orr	ip, ip, ip, lsl #16
+		str	ip, [r0]
+
+		subs	r2, r2, #8
+		bpl	.outsw_8_lp
+
+		tst	r2, #7
+		LOADREGS(eqfd, sp!, {r4, r5, r6, pc})
+
+.no_outsw_8:	tst	r2, #4
+		beq	.no_outsw_4
+
+		ldmia	r1!, {r3, r4}
+
+		mov	ip, r3, lsl #16
+		orr	ip, ip, ip, lsr #16
+		str	ip, [r0]
+
+		mov	ip, r3, lsr #16
+		orr	ip, ip, ip, lsl #16
+		str	ip, [r0]
+
+		mov	ip, r4, lsl #16
+		orr	ip, ip, ip, lsr #16
+		str	ip, [r0]
+
+		mov	ip, r4, lsr #16
+		orr	ip, ip, ip, lsl #16
+		str	ip, [r0]
+
+.no_outsw_4:	tst	r2, #2
+		beq	.no_outsw_2
+
+		ldr	r3, [r1], #4
+
+		mov	ip, r3, lsl #16
+		orr	ip, ip, ip, lsr #16
+		str	ip, [r0]
+
+		mov	ip, r3, lsr #16
+		orr	ip, ip, ip, lsl #16
+		str	ip, [r0]
+
+.no_outsw_2:	tst	r2, #1
+
+		ldrne	r3, [r1]
+
+		movne	ip, r3, lsl #16
+		orrne	ip, ip, ip, lsr #16
+		strne	ip, [r0]
+
+		LOADREGS(fd, sp!, {r4, r5, r6, pc})
diff -Nru a/arch/arm26/lib/memchr.S b/arch/arm26/lib/memchr.S
--- a/arch/arm26/lib/memchr.S	2005-03-01 23:39:16 -08:00
+++ b/arch/arm26/lib/memchr.S	2005-03-01 23:39:16 -08:00
@@ -1,5 +1,5 @@
 /*
- *  linux/arch/arm/lib/memchr.S
+ *  linux/arch/arm26/lib/memchr.S
  *
  *  Copyright (C) 1995-2000 Russell King
  *
diff -Nru a/arch/arm26/lib/memcpy.S b/arch/arm26/lib/memcpy.S
--- a/arch/arm26/lib/memcpy.S	2005-03-01 23:39:09 -08:00
+++ b/arch/arm26/lib/memcpy.S	2005-03-01 23:39:09 -08:00
@@ -1,5 +1,5 @@
 /*
- *  linux/arch/arm/lib/memcpy.S
+ *  linux/arch/arm26/lib/memcpy.S
  *
  *  Copyright (C) 1995-1999 Russell King
  *
diff -Nru a/arch/arm26/lib/memset.S b/arch/arm26/lib/memset.S
--- a/arch/arm26/lib/memset.S	2005-03-01 23:39:07 -08:00
+++ b/arch/arm26/lib/memset.S	2005-03-01 23:39:07 -08:00
@@ -1,5 +1,5 @@
 /*
- *  linux/arch/arm/lib/memset.S
+ *  linux/arch/arm26/lib/memset.S
  *
  *  Copyright (C) 1995-2000 Russell King
  *
diff -Nru a/arch/arm26/lib/memzero.S b/arch/arm26/lib/memzero.S
--- a/arch/arm26/lib/memzero.S	2005-03-01 23:38:56 -08:00
+++ b/arch/arm26/lib/memzero.S	2005-03-01 23:38:56 -08:00
@@ -1,5 +1,5 @@
 /*
- *  linux/arch/arm/lib/memzero.S
+ *  linux/arch/arm26/lib/memzero.S
  *
  *  Copyright (C) 1995-2000 Russell King
  *
diff -Nru a/arch/arm26/lib/putuser.S b/arch/arm26/lib/putuser.S
--- a/arch/arm26/lib/putuser.S	2005-03-01 23:38:58 -08:00
+++ b/arch/arm26/lib/putuser.S	2005-03-01 23:38:58 -08:00
@@ -1,5 +1,5 @@
 /*
- *  linux/arch/arm/lib/putuser.S
+ *  linux/arch/arm26/lib/putuser.S
  *
  *  Copyright (C) 2001 Russell King
  *
@@ -28,6 +28,7 @@
  */
 #include <asm/asm_offsets.h>
 #include <asm/thread_info.h>
+#include <asm/errno.h>
 
         .global __put_user_1
 __put_user_1:
@@ -95,7 +96,7 @@
         ldmfd   sp!, {pc}^
 
 __put_user_bad:
-	mov	r0, #-14
+	mov	r0, #-EFAULT
 	mov	pc, lr
 
 .section __ex_table, "a"
diff -Nru a/arch/arm26/lib/setbit.S b/arch/arm26/lib/setbit.S
--- a/arch/arm26/lib/setbit.S	2005-03-01 23:38:51 -08:00
+++ b/arch/arm26/lib/setbit.S	2005-03-01 23:38:51 -08:00
@@ -1,5 +1,5 @@
 /*
- *  linux/arch/arm/lib/setbit.S
+ *  linux/arch/arm26/lib/setbit.S
  *
  *  Copyright (C) 1995-1996 Russell King
  *
diff -Nru a/arch/arm26/lib/strchr.S b/arch/arm26/lib/strchr.S
--- a/arch/arm26/lib/strchr.S	2005-03-01 23:38:44 -08:00
+++ b/arch/arm26/lib/strchr.S	2005-03-01 23:38:44 -08:00
@@ -1,5 +1,5 @@
 /*
- *  linux/arch/arm/lib/strchr.S
+ *  linux/arch/arm26/lib/strchr.S
  *
  *  Copyright (C) 1995-2000 Russell King
  *
diff -Nru a/arch/arm26/lib/strrchr.S b/arch/arm26/lib/strrchr.S
--- a/arch/arm26/lib/strrchr.S	2005-03-01 23:39:09 -08:00
+++ b/arch/arm26/lib/strrchr.S	2005-03-01 23:39:09 -08:00
@@ -1,5 +1,5 @@
 /*
- *  linux/arch/arm/lib/strrchr.S
+ *  linux/arch/arm26/lib/strrchr.S
  *
  *  Copyright (C) 1995-2000 Russell King
  *
diff -Nru a/arch/arm26/lib/testchangebit.S b/arch/arm26/lib/testchangebit.S
--- a/arch/arm26/lib/testchangebit.S	2005-03-01 23:38:54 -08:00
+++ b/arch/arm26/lib/testchangebit.S	2005-03-01 23:38:54 -08:00
@@ -1,5 +1,5 @@
 /*
- *  linux/arch/arm/lib/testchangebit.S
+ *  linux/arch/arm26/lib/testchangebit.S
  *
  *  Copyright (C) 1995-1996 Russell King
  *
diff -Nru a/arch/arm26/lib/testclearbit.S b/arch/arm26/lib/testclearbit.S
--- a/arch/arm26/lib/testclearbit.S	2005-03-01 23:39:10 -08:00
+++ b/arch/arm26/lib/testclearbit.S	2005-03-01 23:39:10 -08:00
@@ -1,5 +1,5 @@
 /*
- *  linux/arch/arm/lib/testclearbit.S
+ *  linux/arch/arm26/lib/testclearbit.S
  *
  *  Copyright (C) 1995-1996 Russell King
  *
diff -Nru a/arch/arm26/lib/testsetbit.S b/arch/arm26/lib/testsetbit.S
--- a/arch/arm26/lib/testsetbit.S	2005-03-01 23:38:58 -08:00
+++ b/arch/arm26/lib/testsetbit.S	2005-03-01 23:38:58 -08:00
@@ -1,5 +1,5 @@
 /*
- *  linux/arch/arm/lib/testsetbit.S
+ *  linux/arch/arm26/lib/testsetbit.S
  *
  *  Copyright (C) 1995-1996 Russell King
  *
diff -Nru a/arch/arm26/machine/Makefile b/arch/arm26/machine/Makefile
--- a/arch/arm26/machine/Makefile	2005-03-01 23:38:56 -08:00
+++ b/arch/arm26/machine/Makefile	2005-03-01 23:38:56 -08:00
@@ -4,9 +4,5 @@
 
 # Object file lists.
 
-obj-y			:= dma.o irq.o oldlatches.o \
-			   small_page.o
+obj-y			:= dma.o irq.o latches.o
 
-extra-y 		:= head.o
-
-AFLAGS_head.o		:= -DTEXTADDR=$(TEXTADDR)
diff -Nru a/arch/arm26/machine/dma.c b/arch/arm26/machine/dma.c
--- a/arch/arm26/machine/dma.c	2005-03-01 23:39:08 -08:00
+++ b/arch/arm26/machine/dma.c	2005-03-01 23:39:08 -08:00
@@ -1,5 +1,5 @@
 /*
- *  linux/arch/arm/kernel/dma-arc.c
+ *  linux/arch/arm26/kernel/dma.c
  *
  *  Copyright (C) 1998-1999 Dave Gilbert / Russell King
  *  Copyright (C) 2003 Ian Molton
diff -Nru a/arch/arm26/machine/head.S b/arch/arm26/machine/head.S
--- a/arch/arm26/machine/head.S	2005-03-01 23:39:18 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,111 +0,0 @@
-/*
- *  linux/arch/arm/kernel/head-armo.S
- *
- *  Copyright (C) 1994-2000 Russell King
- *  Copyright (C) 2003 Ian Molton
- *
- * 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.
- *
- *  26-bit kernel startup code
- */
-#include <linux/config.h>
-#include <linux/linkage.h>
-#include <asm/mach-types.h>
-
-		.globl	swapper_pg_dir
-		.equ	swapper_pg_dir,	0x0207d000
-
-/*
- * Entry point.
- */
-		.section ".init.text",#alloc,#execinstr
-ENTRY(stext)
-__entry:	cmp	pc, #0x02000000
-		ldrlt	pc, LC0			@ if 0x01800000, call at 0x02080000
-		teq	r0, #0                  @ Check for old calling method
-		blne	oldparams		@ Move page if old
-		adr	r0, LC0
-		ldmib	r0, {r2-r5, sp}		@ Setup stack (and fetch other values)
-
-		mov	r0, #0			@ Clear BSS
-1:		cmp	r2, r3
-		strcc	r0, [r2], #4
-		bcc	1b
-
-		bl	detect_proc_type
-		str	r0, [r4]
-		bl	detect_arch_type
-		str	r0, [r5]
-
-#ifdef CONFIG_XIP_KERNEL
-               ldr     r3, ETEXT                       @ data section copy
-               ldr     r4, SDATA
-               ldr     r5, EDATA
-1:
-               ldr     r6, [r3], #4
-               str     r6, [r4], #4
-               cmp     r4, r5
-               blt     1b
-#endif
-
-		mov	fp, #0
-		b	start_kernel
-
-LC0:		.word	_stext
-		.word	__bss_start		@ r2
-		.word	_end			@ r3
-		.word	processor_id		@ r4
-		.word	__machine_arch_type	@ r5
-		.word	init_thread_union+8192	@ sp
-#ifdef CONFIG_XIP_KERNEL
-ETEXT:		.word   _endtext
-SDATA:		.word   _sdata
-EDATA:		.word   __bss_start
-#endif
-
-arm2_id:	.long	0x41560200  @ ARM2 and 250 dont have a CPUID
-arm250_id:	.long	0x41560250  @ So we create some after probing for them
-		.align
-
-oldparams:	mov	r4, #0x02000000
-		add	r3, r4, #0x00080000
-		add	r4, r4, #0x0007c000
-1:		ldmia	r0!, {r5 - r12}
-		stmia	r4!, {r5 - r12}
-		cmp	r4, r3
-		blt	1b
-		mov	pc, lr
-
-/*
- * We need some way to automatically detect the difference between
- * these two machines.  Unfortunately, it is not possible to detect
- * the presence of the SuperIO chip, because that will hang the old
- * Archimedes machines solid.
- */
-/* DAG: Outdated, these have been combined !!!!!!! */
-detect_arch_type:
-#if defined(CONFIG_ARCH_ARC)
-		mov	r0, #MACH_TYPE_ARCHIMEDES
-#elif defined(CONFIG_ARCH_A5K)
-		mov	r0, #MACH_TYPE_A5K
-#endif
-		mov	pc, lr
-
-detect_proc_type:
-		mov	ip, lr
-		mov	r2, #0xea000000		@ Point undef instr to continuation
-		adr	r0, continue - 12
-		orr	r0, r2, r0, lsr #2
-		mov	r1, #0
-		str	r0, [r1, #4]
-		ldr	r0, arm2_id
-		swp	r2, r2, [r1]		@ check for swp (ARM2 cant)
-		ldr	r0, arm250_id
-		mrc	15, 0, r3, c0, c0	@ check for CP#15 (ARM250 cant)
-		mov	r0, r3
-continue:	mov	r2, #0xeb000000		@ Make undef vector loop
-		sub	r2, r2, #2
-		str	r2, [r1, #4]
-		mov	pc, ip
diff -Nru a/arch/arm26/machine/irq.c b/arch/arm26/machine/irq.c
--- a/arch/arm26/machine/irq.c	2005-03-01 23:38:53 -08:00
+++ b/arch/arm26/machine/irq.c	2005-03-01 23:38:53 -08:00
@@ -1,5 +1,5 @@
 /*
- *  linux/arch/arm/mach-arc/irq.c
+ *  linux/arch/arm26/mach-arc/irq.c
  *
  *  Copyright (C) 1996 Russell King
  *
diff -Nru a/arch/arm26/machine/latches.c b/arch/arm26/machine/latches.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/arm26/machine/latches.c	2005-03-01 23:38:54 -08:00
@@ -0,0 +1,72 @@
+/*
+ *  linux/arch/arm26/kernel/latches.c
+ *
+ *  Copyright (C) David Alan Gilbert 1995/1996,2000
+ *  Copyright (C) Ian Molton 2003
+ *
+ * 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.
+ *
+ *  Support for the latches on the old Archimedes which control the floppy,
+ *  hard disc and printer
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+
+#include <asm/io.h>
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/oldlatches.h>
+
+static unsigned char latch_a_copy;
+static unsigned char latch_b_copy;
+
+/* newval=(oldval & ~mask)|newdata */
+void oldlatch_aupdate(unsigned char mask,unsigned char newdata)
+{
+	unsigned long flags;
+
+	BUG_ON(!machine_is_archimedes());
+
+	local_irq_save(flags); //FIXME: was local_save_flags
+	latch_a_copy = (latch_a_copy & ~mask) | newdata;
+	__raw_writeb(latch_a_copy, LATCHA_BASE);
+	local_irq_restore(flags);
+
+	printk("Latch: A = 0x%02x\n", latch_a_copy);
+}
+
+
+/* newval=(oldval & ~mask)|newdata */
+void oldlatch_bupdate(unsigned char mask,unsigned char newdata)
+{
+	unsigned long flags;
+
+	BUG_ON(!machine_is_archimedes());
+
+
+	local_irq_save(flags);//FIXME: was local_save_flags
+	latch_b_copy = (latch_b_copy & ~mask) | newdata;
+	__raw_writeb(latch_b_copy, LATCHB_BASE);
+	local_irq_restore(flags);
+
+	printk("Latch: B = 0x%02x\n", latch_b_copy);
+}
+
+static int __init oldlatch_init(void)
+{
+	if (machine_is_archimedes()) {
+		oldlatch_aupdate(0xff, 0xff);
+		/* Thats no FDC reset...*/
+		oldlatch_bupdate(0xff, LATCHB_FDCRESET);
+	}
+	return 0;
+}
+
+arch_initcall(oldlatch_init);
+
+EXPORT_SYMBOL(oldlatch_aupdate);
+EXPORT_SYMBOL(oldlatch_bupdate);
diff -Nru a/arch/arm26/machine/oldlatches.c b/arch/arm26/machine/oldlatches.c
--- a/arch/arm26/machine/oldlatches.c	2005-03-01 23:38:54 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,72 +0,0 @@
-/*
- *  linux/arch/arm/kernel/oldlatches.c
- *
- *  Copyright (C) David Alan Gilbert 1995/1996,2000
- *  Copyright (C) Ian Molton 2003
- *
- * 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.
- *
- *  Support for the latches on the old Archimedes which control the floppy,
- *  hard disc and printer
- */
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/sched.h>
-
-#include <asm/io.h>
-#include <asm/hardware.h>
-#include <asm/mach-types.h>
-#include <asm/oldlatches.h>
-
-static unsigned char latch_a_copy;
-static unsigned char latch_b_copy;
-
-/* newval=(oldval & ~mask)|newdata */
-void oldlatch_aupdate(unsigned char mask,unsigned char newdata)
-{
-	unsigned long flags;
-
-	BUG_ON(!machine_is_archimedes());
-
-	local_irq_save(flags); //FIXME: was local_save_flags
-	latch_a_copy = (latch_a_copy & ~mask) | newdata;
-	__raw_writeb(latch_a_copy, LATCHA_BASE);
-	local_irq_restore(flags);
-
-	printk("Latch: A = 0x%02x\n", latch_a_copy);
-}
-
-
-/* newval=(oldval & ~mask)|newdata */
-void oldlatch_bupdate(unsigned char mask,unsigned char newdata)
-{
-	unsigned long flags;
-
-	BUG_ON(!machine_is_archimedes());
-	
-
-	local_irq_save(flags);//FIXME: was local_save_flags
-	latch_b_copy = (latch_b_copy & ~mask) | newdata;
-	__raw_writeb(latch_b_copy, LATCHB_BASE);
-	local_irq_restore(flags);
-
-	printk("Latch: B = 0x%02x\n", latch_b_copy);
-}
-
-static int __init oldlatch_init(void)
-{
-	if (machine_is_archimedes()) {
-		oldlatch_aupdate(0xff, 0xff);
-		/* Thats no FDC reset...*/
-		oldlatch_bupdate(0xff, LATCHB_FDCRESET);
-	}
-	return 0;
-}
-
-arch_initcall(oldlatch_init);
-
-EXPORT_SYMBOL(oldlatch_aupdate);
-EXPORT_SYMBOL(oldlatch_bupdate);
diff -Nru a/arch/arm26/machine/small_page.c b/arch/arm26/machine/small_page.c
--- a/arch/arm26/machine/small_page.c	2005-03-01 23:39:18 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,191 +0,0 @@
-/*
- *  linux/arch/arm/mm/small_page.c
- *
- *  Copyright (C) 1996  Russell King
- *  Copyright (C) 2003  Ian Molton
- *
- * 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:
- *   26/01/1996	RMK	Cleaned up various areas to make little more generic
- *   07/02/1999	RMK	Support added for 16K and 32K page sizes
- *			containing 8K blocks
- */
-#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/mman.h>
-#include <linux/mm.h>
-#include <linux/swap.h>
-#include <linux/smp.h>
-#include <linux/bitops.h>
-
-#include <asm/pgtable.h>
-
-#define PEDANTIC
-
-/*
- * Requirement:
- *  We need to be able to allocate naturally aligned memory of finer
- *  granularity than the page size.  This is typically used for the
- *  second level page tables on 32-bit ARMs.
- *
- * Theory:
- *  We "misuse" the Linux memory management system.  We use alloc_page
- *  to allocate a page and then mark it as reserved.  The Linux memory
- *  management system will then ignore the "offset", "next_hash" and
- *  "pprev_hash" entries in the mem_map for this page.
- *
- *  We then use a bitstring in the "offset" field to mark which segments
- *  of the page are in use, and manipulate this as required during the
- *  allocation and freeing of these small pages.
- *
- *  We also maintain a queue of pages being used for this purpose using
- *  the "next_hash" and "pprev_hash" entries of mem_map;
- */
-
-struct order {
-	struct list_head queue;
-	unsigned int mask;		/* (1 << shift) - 1		*/
-	unsigned int shift;		/* (1 << shift) size of page	*/
-	unsigned int block_mask;	/* nr_blocks - 1		*/
-	unsigned int all_used;		/* (1 << nr_blocks) - 1		*/
-};
-
-
-static struct order orders[] = {
-#if PAGE_SIZE == 32768
-	{ LIST_HEAD_INIT(orders[0].queue), 2047, 11, 15, 0x0000ffff },
-	{ LIST_HEAD_INIT(orders[1].queue), 8191, 13,  3, 0x0000000f }
-#else
-#error unsupported page size (ARGH!)
-#endif
-};
-
-#define USED_MAP(pg)			((pg)->index)
-#define TEST_AND_CLEAR_USED(pg,off)	(test_and_clear_bit(off, &USED_MAP(pg)))
-#define SET_USED(pg,off)		(set_bit(off, &USED_MAP(pg)))
-
-static spinlock_t small_page_lock = SPIN_LOCK_UNLOCKED;
-
-static unsigned long __get_small_page(int priority, struct order *order)
-{
-	unsigned long flags;
-	struct page *page;
-	int offset;
-
-	do {
-		spin_lock_irqsave(&small_page_lock, flags);
-
-		if (list_empty(&order->queue))
-			goto need_new_page;
-
-		page = list_entry(order->queue.next, struct page, list);
-again:
-#ifdef PEDANTIC
-		if (USED_MAP(page) & ~order->all_used)
-			PAGE_BUG(page);
-#endif
-		offset = ffz(USED_MAP(page));
-		SET_USED(page, offset);
-		if (USED_MAP(page) == order->all_used)
-			list_del_init(&page->lru);
-		spin_unlock_irqrestore(&small_page_lock, flags);
-
-		return (unsigned long) page_address(page) + (offset << order->shift);
-
-need_new_page:
-		spin_unlock_irqrestore(&small_page_lock, flags);
-		page = alloc_page(priority);
-		spin_lock_irqsave(&small_page_lock, flags);
-
-		if (list_empty(&order->queue)) {
-			if (!page)
-				goto no_page;
-			SetPageReserved(page);
-			USED_MAP(page) = 0;
-			list_add(&page->lru, &order->queue);
-			goto again;
-		}
-
-		spin_unlock_irqrestore(&small_page_lock, flags);
-		__free_page(page);
-	} while (1);
-
-no_page:
-	spin_unlock_irqrestore(&small_page_lock, flags);
-	return 0;
-}
-
-static void __free_small_page(unsigned long spage, struct order *order)
-{
-	unsigned long flags;
-	struct page *page;
-
-	if (virt_addr_valid(spage)) {
-		page = virt_to_page(spage);
-
-		/*
-		 * The container-page must be marked Reserved
-		 */
-		if (!PageReserved(page) || spage & order->mask)
-			goto non_small;
-
-#ifdef PEDANTIC
-		if (USED_MAP(page) & ~order->all_used)
-			PAGE_BUG(page);
-#endif
-
-		spage = spage >> order->shift;
-		spage &= order->block_mask;
-
-		/*
-		 * the following must be atomic wrt get_page
-		 */
-		spin_lock_irqsave(&small_page_lock, flags);
-
-		if (USED_MAP(page) == order->all_used)
-			list_add(&page->lru, &order->queue);
-
-		if (!TEST_AND_CLEAR_USED(page, spage))
-			goto already_free;
-
-		if (USED_MAP(page) == 0)
-			goto free_page;
-
-		spin_unlock_irqrestore(&small_page_lock, flags);
-	}
-	return;
-
-free_page:
-	/*
-	 * unlink the page from the small page queue and free it
-	 */
-	list_del_init(&page->lru);
-	spin_unlock_irqrestore(&small_page_lock, flags);
-	ClearPageReserved(page);
-	__free_page(page);
-	return;
-
-non_small:
-	printk("Trying to free non-small page from %p\n", __builtin_return_address(0));
-	return;
-already_free:
-	printk("Trying to free free small page from %p\n", __builtin_return_address(0));
-}
-
-unsigned long get_page_8k(int priority)
-{
-	return __get_small_page(priority, orders+1);
-}
-
-void free_page_8k(unsigned long spage)
-{
-	__free_small_page(spage, orders+1);
-}
diff -Nru a/arch/arm26/mm/Makefile b/arch/arm26/mm/Makefile
--- a/arch/arm26/mm/Makefile	2005-03-01 23:38:53 -08:00
+++ b/arch/arm26/mm/Makefile	2005-03-01 23:38:53 -08:00
@@ -2,4 +2,5 @@
 # Makefile for the linux arm26-specific parts of the memory manager.
 #
 
-obj-y		:= init.o extable.o proc-funcs.o mm-memc.o fault.o
+obj-y		:= init.o extable.o proc-funcs.o memc.o fault.o \
+		   small_page.o
diff -Nru a/arch/arm26/mm/extable.c b/arch/arm26/mm/extable.c
--- a/arch/arm26/mm/extable.c	2005-03-01 23:38:56 -08:00
+++ b/arch/arm26/mm/extable.c	2005-03-01 23:38:56 -08:00
@@ -1,5 +1,5 @@
 /*
- *  linux/arch/arm/mm/extable.c
+ *  linux/arch/arm26/mm/extable.c
  */
 
 #include <linux/config.h>
@@ -11,6 +11,12 @@
         const struct exception_table_entry *fixup;
 
         fixup = search_exception_tables(instruction_pointer(regs));
+
+	/*
+	 * The kernel runs in SVC mode - make sure we keep running in SVC mode
+	 * by frobbing the PSR appropriately (PSR and PC are in the same reg.
+	 * on ARM26)
+	 */
         if (fixup)
                 regs->ARM_pc = fixup->fixup | PSR_I_BIT | MODE_SVC26;
 
diff -Nru a/arch/arm26/mm/fault.c b/arch/arm26/mm/fault.c
--- a/arch/arm26/mm/fault.c	2005-03-01 23:38:54 -08:00
+++ b/arch/arm26/mm/fault.c	2005-03-01 23:38:54 -08:00
@@ -1,5 +1,5 @@
 /*
- *  linux/arch/arm/mm/fault-common.c
+ *  linux/arch/arm26/mm/fault.c
  *
  *  Copyright (C) 1995  Linus Torvalds
  *  Modifications for ARM processor (c) 1995-2001 Russell King
@@ -212,7 +212,6 @@
 	tsk = current;
 	mm  = tsk->mm;
 
-	printk("do_page_fault: pid: %d      %08x\n", tsk->pid, addr);
 	/*
 	 * If we're in an interrupt or have no user
 	 * context, we must not take the fault..
diff -Nru a/arch/arm26/mm/init.c b/arch/arm26/mm/init.c
--- a/arch/arm26/mm/init.c	2005-03-01 23:39:16 -08:00
+++ b/arch/arm26/mm/init.c	2005-03-01 23:39:16 -08:00
@@ -1,5 +1,5 @@
 /*
- *  linux/arch/arm/mm/init.c
+ *  linux/arch/arm26/mm/init.c
  *
  *  Copyright (C) 1995-2002 Russell King
  *
@@ -26,7 +26,6 @@
 
 #include <asm/segment.h>
 #include <asm/mach-types.h>
-#include <asm/pgalloc.h>
 #include <asm/dma.h>
 #include <asm/hardware.h>
 #include <asm/setup.h>
@@ -84,7 +83,7 @@
 		else if (!page_count(page))
 			free++;
 		else
-			shared += atomic_read(&page->count) - 1;
+			shared += page_count(page) - 1;
 		page++;
 	} while (page < end);
 
@@ -156,7 +155,8 @@
 {
 	unsigned int memend_pfn = 0;
 
-	numnodes = 1;
+	nodes_clear(node_online_map);
+	node_set_online(0);
 
 	np->bootmap_pages = 0;
 
diff -Nru a/arch/arm26/mm/memc.c b/arch/arm26/mm/memc.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/arm26/mm/memc.c	2005-03-01 23:39:17 -08:00
@@ -0,0 +1,202 @@
+/*
+ *  linux/arch/arm26/mm/memc.c
+ *
+ *  Copyright (C) 1998-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.
+ *
+ *  Page table sludge for older ARM processor architectures.
+ */
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+#include <asm/page.h>
+#include <asm/memory.h>
+#include <asm/hardware.h>
+
+#include <asm/map.h>
+
+#define MEMC_TABLE_SIZE (256*sizeof(unsigned long))
+
+kmem_cache_t *pte_cache, *pgd_cache;
+int page_nr;
+
+/*
+ * Allocate space for a page table and a MEMC table.
+ * Note that we place the MEMC
+ * table before the page directory.  This means we can
+ * easily get to both tightly-associated data structures
+ * with a single pointer.
+ */
+static inline pgd_t *alloc_pgd_table(void)
+{
+	void *pg2k = kmem_cache_alloc(pgd_cache, GFP_KERNEL);
+
+	if (pg2k)
+		pg2k += MEMC_TABLE_SIZE;
+
+	return (pgd_t *)pg2k;
+}
+
+/*
+ * Free a page table. this function is the counterpart to get_pgd_slow
+ * below, not alloc_pgd_table above.
+ */
+void free_pgd_slow(pgd_t *pgd)
+{
+	unsigned long tbl = (unsigned long)pgd;
+
+	tbl -= MEMC_TABLE_SIZE;
+
+	kmem_cache_free(pgd_cache, (void *)tbl);
+}
+
+/*
+ * Allocate a new pgd and fill it in ready for use
+ *
+ * A new tasks pgd is completely empty (all pages !present) except for:
+ *
+ * o The machine vectors at virtual address 0x0
+ * o The vmalloc region at the top of address space
+ *
+ */
+#define FIRST_KERNEL_PGD_NR     (FIRST_USER_PGD_NR + USER_PTRS_PER_PGD)
+
+pgd_t *get_pgd_slow(struct mm_struct *mm)
+{
+	pgd_t *new_pgd, *init_pgd;
+	pmd_t *new_pmd, *init_pmd;
+	pte_t *new_pte, *init_pte;
+
+	new_pgd = alloc_pgd_table();
+	if (!new_pgd)
+		goto no_pgd;
+
+	/*
+	 * This lock is here just to satisfy pmd_alloc and pte_lock
+         * FIXME: I bet we could avoid taking it pretty much altogether
+	 */
+	spin_lock(&mm->page_table_lock);
+
+	/*
+	 * On ARM, first page must always be allocated since it contains
+	 * the machine vectors.
+	 */
+	new_pmd = pmd_alloc(mm, new_pgd, 0);
+	if (!new_pmd)
+		goto no_pmd;
+
+	new_pte = pte_alloc_kernel(mm, new_pmd, 0);
+	if (!new_pte)
+		goto no_pte;
+
+	init_pgd = pgd_offset(&init_mm, 0);
+	init_pmd = pmd_offset(init_pgd, 0);
+	init_pte = pte_offset(init_pmd, 0);
+
+	set_pte(new_pte, *init_pte);
+
+	/*
+	 * the page table entries are zeroed
+	 * when the table is created. (see the cache_ctor functions below)
+	 * Now we need to plonk the kernel (vmalloc) area at the end of
+	 * the address space. We copy this from the init thread, just like
+	 * the init_pte we copied above...
+	 */
+	memcpy(new_pgd + FIRST_KERNEL_PGD_NR, init_pgd + FIRST_KERNEL_PGD_NR,
+		(PTRS_PER_PGD - FIRST_KERNEL_PGD_NR) * sizeof(pgd_t));
+
+	spin_unlock(&mm->page_table_lock);
+
+	/* update MEMC tables */
+	cpu_memc_update_all(new_pgd);
+	return new_pgd;
+
+no_pte:
+	spin_unlock(&mm->page_table_lock);
+	pmd_free(new_pmd);
+	free_pgd_slow(new_pgd);
+	return NULL;
+
+no_pmd:
+	spin_unlock(&mm->page_table_lock);
+	free_pgd_slow(new_pgd);
+	return NULL;
+
+no_pgd:
+	return NULL;
+}
+
+/*
+ * No special code is required here.
+ */
+void setup_mm_for_reboot(char mode)
+{
+}
+
+/*
+ * This contains the code to setup the memory map on an ARM2/ARM250/ARM3
+ *  o swapper_pg_dir = 0x0207d000
+ *  o kernel proper starts at 0x0208000
+ *  o create (allocate) a pte to contain the machine vectors
+ *  o populate the pte (points to 0x02078000) (FIXME - is it zeroed?)
+ *  o populate the init tasks page directory (pgd) with the new pte
+ *  o zero the rest of the init tasks pgdir (FIXME - what about vmalloc?!)
+ */
+void __init memtable_init(struct meminfo *mi)
+{
+	pte_t *pte;
+	int i;
+
+	page_nr = max_low_pfn;
+
+	pte = alloc_bootmem_low_pages(PTRS_PER_PTE * sizeof(pte_t));
+	pte[0] = mk_pte_phys(PAGE_OFFSET + SCREEN_SIZE, PAGE_READONLY);
+	pmd_populate(&init_mm, pmd_offset(swapper_pg_dir, 0), pte);
+
+	for (i = 1; i < PTRS_PER_PGD; i++)
+		pgd_val(swapper_pg_dir[i]) = 0;
+}
+
+void __init iotable_init(struct map_desc *io_desc)
+{
+	/* nothing to do */
+}
+
+/*
+ * We never have holes in the memmap
+ */
+void __init create_memmap_holes(struct meminfo *mi)
+{
+}
+
+static void pte_cache_ctor(void *pte, kmem_cache_t *cache, unsigned long flags)
+{
+	memzero(pte, sizeof(pte_t) * PTRS_PER_PTE);
+}
+
+static void pgd_cache_ctor(void *pgd, kmem_cache_t *cache, unsigned long flags)
+{
+	memzero(pgd + MEMC_TABLE_SIZE, USER_PTRS_PER_PGD * sizeof(pgd_t));
+}
+
+void __init pgtable_cache_init(void)
+{
+	pte_cache = kmem_cache_create("pte-cache",
+				sizeof(pte_t) * PTRS_PER_PTE,
+				0, 0, pte_cache_ctor, NULL);
+	if (!pte_cache)
+		BUG();
+
+	pgd_cache = kmem_cache_create("pgd-cache", MEMC_TABLE_SIZE +
+				sizeof(pgd_t) * PTRS_PER_PGD,
+				0, 0, pgd_cache_ctor, NULL);
+	if (!pgd_cache)
+		BUG();
+}
diff -Nru a/arch/arm26/mm/mm-memc.c b/arch/arm26/mm/mm-memc.c
--- a/arch/arm26/mm/mm-memc.c	2005-03-01 23:39:17 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,202 +0,0 @@
-/*
- *  linux/arch/arm/mm/mm-armo.c
- *
- *  Copyright (C) 1998-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.
- *
- *  Page table sludge for older ARM processor architectures.
- */
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/init.h>
-#include <linux/bootmem.h>
-
-#include <asm/pgtable.h>
-#include <asm/pgalloc.h>
-#include <asm/page.h>
-#include <asm/memory.h>
-#include <asm/hardware.h>
-
-#include <asm/map.h>
-
-#define MEMC_TABLE_SIZE (256*sizeof(unsigned long))
-
-kmem_cache_t *pte_cache, *pgd_cache;
-int page_nr;
-
-/*
- * Allocate space for a page table and a MEMC table.
- * Note that we place the MEMC
- * table before the page directory.  This means we can
- * easily get to both tightly-associated data structures
- * with a single pointer.
- */
-static inline pgd_t *alloc_pgd_table(void)
-{
-	void *pg2k = kmem_cache_alloc(pgd_cache, GFP_KERNEL);
-
-	if (pg2k)
-		pg2k += MEMC_TABLE_SIZE;
-
-	return (pgd_t *)pg2k;
-}
-
-/*
- * Free a page table. this function is the counterpart to get_pgd_slow
- * below, not alloc_pgd_table above.
- */
-void free_pgd_slow(pgd_t *pgd)
-{
-	unsigned long tbl = (unsigned long)pgd;
-
-	tbl -= MEMC_TABLE_SIZE;
-
-	kmem_cache_free(pgd_cache, (void *)tbl);
-}
-
-/*
- * Allocate a new pgd and fill it in ready for use
- *
- * A new tasks pgd is completely empty (all pages !present) except for:
- *
- * o The machine vectors at virtual address 0x0
- * o The vmalloc region at the top of address space
- *
- */
-#define FIRST_KERNEL_PGD_NR     (FIRST_USER_PGD_NR + USER_PTRS_PER_PGD)
-
-pgd_t *get_pgd_slow(struct mm_struct *mm)
-{
-	pgd_t *new_pgd, *init_pgd;
-	pmd_t *new_pmd, *init_pmd;
-	pte_t *new_pte, *init_pte;
-
-	new_pgd = alloc_pgd_table();
-	if (!new_pgd)
-		goto no_pgd;
-
-	/*
-	 * This lock is here just to satisfy pmd_alloc and pte_lock
-         * FIXME: I bet we could avoid taking it pretty much altogether
-	 */
-	spin_lock(&mm->page_table_lock);
-
-	/*
-	 * On ARM, first page must always be allocated since it contains
-	 * the machine vectors.
-	 */
-	new_pmd = pmd_alloc(mm, new_pgd, 0);
-	if (!new_pmd)
-		goto no_pmd;
-
-	new_pte = pte_alloc_kernel(mm, new_pmd, 0);
-	if (!new_pte)
-		goto no_pte;
-
-	init_pgd = pgd_offset(&init_mm, 0);
-	init_pmd = pmd_offset(init_pgd, 0);
-	init_pte = pte_offset(init_pmd, 0);
-
-	set_pte(new_pte, *init_pte);
-
-	/*
-	 * the page table entries are zeroed
-	 * when the table is created. (see the cache_ctor functions below)
-	 * Now we need to plonk the kernel (vmalloc) area at the end of
-	 * the address space. We copy this from the init thread, just like
-	 * the init_pte we copied above...
-	 */
-	memcpy(new_pgd + FIRST_KERNEL_PGD_NR, init_pgd + FIRST_KERNEL_PGD_NR,
-		(PTRS_PER_PGD - FIRST_KERNEL_PGD_NR) * sizeof(pgd_t));
-
-	spin_unlock(&mm->page_table_lock);
-
-	/* update MEMC tables */
-	cpu_memc_update_all(new_pgd);
-	return new_pgd;
-
-no_pte:
-	spin_unlock(&mm->page_table_lock);
-	pmd_free(new_pmd);
-	free_pgd_slow(new_pgd);
-	return NULL;
-
-no_pmd:
-	spin_unlock(&mm->page_table_lock);
-	free_pgd_slow(new_pgd);
-	return NULL;
-
-no_pgd:
-	return NULL;
-}
-
-/*
- * No special code is required here.
- */
-void setup_mm_for_reboot(char mode)
-{
-}
-
-/*
- * This contains the code to setup the memory map on an ARM2/ARM250/ARM3
- *  o swapper_pg_dir = 0x0207d000
- *  o kernel proper starts at 0x0208000
- *  o create (allocate) a pte to contain the machine vectors
- *  o populate the pte (points to 0x02078000) (FIXME - is it zeroed?)
- *  o populate the init tasks page directory (pgd) with the new pte
- *  o zero the rest of the init tasks pgdir (FIXME - what about vmalloc?!)
- */
-void __init memtable_init(struct meminfo *mi)
-{
-	pte_t *pte;
-	int i;
-
-	page_nr = max_low_pfn;
-
-	pte = alloc_bootmem_low_pages(PTRS_PER_PTE * sizeof(pte_t));
-	pte[0] = mk_pte_phys(PAGE_OFFSET + SCREEN_SIZE, PAGE_READONLY);
-	pmd_populate(&init_mm, pmd_offset(swapper_pg_dir, 0), pte);
-
-	for (i = 1; i < PTRS_PER_PGD; i++)
-		pgd_val(swapper_pg_dir[i]) = 0;
-}
-
-void __init iotable_init(struct map_desc *io_desc)
-{
-	/* nothing to do */
-}
-
-/*
- * We never have holes in the memmap
- */
-void __init create_memmap_holes(struct meminfo *mi)
-{
-}
-
-static void pte_cache_ctor(void *pte, kmem_cache_t *cache, unsigned long flags)
-{
-	memzero(pte, sizeof(pte_t) * PTRS_PER_PTE);
-}
-
-static void pgd_cache_ctor(void *pgd, kmem_cache_t *cache, unsigned long flags)
-{
-	memzero(pgd + MEMC_TABLE_SIZE, USER_PTRS_PER_PGD * sizeof(pgd_t));
-}
-
-void __init pgtable_cache_init(void)
-{
-	pte_cache = kmem_cache_create("pte-cache",
-				sizeof(pte_t) * PTRS_PER_PTE,
-				0, 0, pte_cache_ctor, NULL);
-	if (!pte_cache)
-		BUG();
-
-	pgd_cache = kmem_cache_create("pgd-cache", MEMC_TABLE_SIZE +
-				sizeof(pgd_t) * PTRS_PER_PGD,
-				0, 0, pgd_cache_ctor, NULL);
-	if (!pgd_cache)
-		BUG();
-}
diff -Nru a/arch/arm26/mm/proc-funcs.S b/arch/arm26/mm/proc-funcs.S
--- a/arch/arm26/mm/proc-funcs.S	2005-03-01 23:39:10 -08:00
+++ b/arch/arm26/mm/proc-funcs.S	2005-03-01 23:39:10 -08:00
@@ -1,5 +1,5 @@
 /*
- *  linux/arch/arm/mm/proc-arm2,3.S
+ *  linux/arch/arm26/mm/proc-arm2,3.S
  *
  *  Copyright (C) 1997-1999 Russell King
  *
diff -Nru a/arch/arm26/mm/small_page.c b/arch/arm26/mm/small_page.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/arm26/mm/small_page.c	2005-03-01 23:39:18 -08:00
@@ -0,0 +1,194 @@
+/*
+ *  linux/arch/arm26/mm/small_page.c
+ *
+ *  Copyright (C) 1996  Russell King
+ *  Copyright (C) 2003  Ian Molton
+ *
+ * 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:
+ *   26/01/1996	RMK	Cleaned up various areas to make little more generic
+ *   07/02/1999	RMK	Support added for 16K and 32K page sizes
+ *			containing 8K blocks
+ *   23/05/2004 IM	Fixed to use struct page->lru (thanks wli)
+ *
+ */
+#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/mman.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/smp.h>
+#include <linux/bitops.h>
+
+#include <asm/pgtable.h>
+
+#define PEDANTIC
+
+/*
+ * Requirement:
+ *  We need to be able to allocate naturally aligned memory of finer
+ *  granularity than the page size.  This is typically used for the
+ *  second level page tables on 32-bit ARMs.
+ *
+ * FIXME - this comment is *out of date*
+ * Theory:
+ *  We "misuse" the Linux memory management system.  We use alloc_page
+ *  to allocate a page and then mark it as reserved.  The Linux memory
+ *  management system will then ignore the "offset", "next_hash" and
+ *  "pprev_hash" entries in the mem_map for this page.
+ *
+ *  We then use a bitstring in the "offset" field to mark which segments
+ *  of the page are in use, and manipulate this as required during the
+ *  allocation and freeing of these small pages.
+ *
+ *  We also maintain a queue of pages being used for this purpose using
+ *  the "next_hash" and "pprev_hash" entries of mem_map;
+ */
+
+struct order {
+	struct list_head queue;
+	unsigned int mask;		/* (1 << shift) - 1		*/
+	unsigned int shift;		/* (1 << shift) size of page	*/
+	unsigned int block_mask;	/* nr_blocks - 1		*/
+	unsigned int all_used;		/* (1 << nr_blocks) - 1		*/
+};
+
+
+static struct order orders[] = {
+#if PAGE_SIZE == 32768
+	{ LIST_HEAD_INIT(orders[0].queue), 2047, 11, 15, 0x0000ffff },
+	{ LIST_HEAD_INIT(orders[1].queue), 8191, 13,  3, 0x0000000f }
+#else
+#error unsupported page size (ARGH!)
+#endif
+};
+
+#define USED_MAP(pg)			((pg)->index)
+#define TEST_AND_CLEAR_USED(pg,off)	(test_and_clear_bit(off, &USED_MAP(pg)))
+#define SET_USED(pg,off)		(set_bit(off, &USED_MAP(pg)))
+
+static DEFINE_SPINLOCK(small_page_lock);
+
+static unsigned long __get_small_page(int priority, struct order *order)
+{
+	unsigned long flags;
+	struct page *page;
+	int offset;
+
+	do {
+		spin_lock_irqsave(&small_page_lock, flags);
+
+		if (list_empty(&order->queue))
+			goto need_new_page;
+
+		page = list_entry(order->queue.next, struct page, lru);
+again:
+#ifdef PEDANTIC
+		if (USED_MAP(page) & ~order->all_used)
+			PAGE_BUG(page);
+#endif
+		offset = ffz(USED_MAP(page));
+		SET_USED(page, offset);
+		if (USED_MAP(page) == order->all_used)
+			list_del_init(&page->lru);
+		spin_unlock_irqrestore(&small_page_lock, flags);
+
+		return (unsigned long) page_address(page) + (offset << order->shift);
+
+need_new_page:
+		spin_unlock_irqrestore(&small_page_lock, flags);
+		page = alloc_page(priority);
+		spin_lock_irqsave(&small_page_lock, flags);
+
+		if (list_empty(&order->queue)) {
+			if (!page)
+				goto no_page;
+			SetPageReserved(page);
+			USED_MAP(page) = 0;
+			list_add(&page->lru, &order->queue);
+			goto again;
+		}
+
+		spin_unlock_irqrestore(&small_page_lock, flags);
+		__free_page(page);
+	} while (1);
+
+no_page:
+	spin_unlock_irqrestore(&small_page_lock, flags);
+	return 0;
+}
+
+static void __free_small_page(unsigned long spage, struct order *order)
+{
+	unsigned long flags;
+	struct page *page;
+
+	if (virt_addr_valid(spage)) {
+		page = virt_to_page(spage);
+
+		/*
+		 * The container-page must be marked Reserved
+		 */
+		if (!PageReserved(page) || spage & order->mask)
+			goto non_small;
+
+#ifdef PEDANTIC
+		if (USED_MAP(page) & ~order->all_used)
+			PAGE_BUG(page);
+#endif
+
+		spage = spage >> order->shift;
+		spage &= order->block_mask;
+
+		/*
+		 * the following must be atomic wrt get_page
+		 */
+		spin_lock_irqsave(&small_page_lock, flags);
+
+		if (USED_MAP(page) == order->all_used)
+			list_add(&page->lru, &order->queue);
+
+		if (!TEST_AND_CLEAR_USED(page, spage))
+			goto already_free;
+
+		if (USED_MAP(page) == 0)
+			goto free_page;
+
+		spin_unlock_irqrestore(&small_page_lock, flags);
+	}
+	return;
+
+free_page:
+	/*
+	 * unlink the page from the small page queue and free it
+	 */
+	list_del_init(&page->lru);
+	spin_unlock_irqrestore(&small_page_lock, flags);
+	ClearPageReserved(page);
+	__free_page(page);
+	return;
+
+non_small:
+	printk("Trying to free non-small page from %p\n", __builtin_return_address(0));
+	return;
+already_free:
+	printk("Trying to free free small page from %p\n", __builtin_return_address(0));
+}
+
+unsigned long get_page_8k(int priority)
+{
+	return __get_small_page(priority, orders+1);
+}
+
+void free_page_8k(unsigned long spage)
+{
+	__free_small_page(spage, orders+1);
+}
diff -Nru a/arch/cris/Kconfig b/arch/cris/Kconfig
--- a/arch/cris/Kconfig	2005-03-01 23:39:16 -08:00
+++ b/arch/cris/Kconfig	2005-03-01 23:39:16 -08:00
@@ -20,6 +20,10 @@
 config RWSEM_XCHGADD_ALGORITHM
 	bool
 
+config GENERIC_CALIBRATE_DELAY
+	bool
+	default y
+
 config CRIS
 	bool
 	default y
diff -Nru a/arch/cris/arch-v10/drivers/Kconfig b/arch/cris/arch-v10/drivers/Kconfig
--- a/arch/cris/arch-v10/drivers/Kconfig	2005-03-01 23:38:53 -08:00
+++ b/arch/cris/arch-v10/drivers/Kconfig	2005-03-01 23:38:53 -08:00
@@ -557,7 +557,7 @@
 	select DMA_NONPCI
 	help
 	  Enable this to get support for ATA/IDE.
-	  You can't use parallell ports or SCSI ports
+	  You can't use paralell ports or SCSI ports
 	  at the same time.
 
 
diff -Nru a/arch/cris/arch-v10/kernel/fasttimer.c b/arch/cris/arch-v10/kernel/fasttimer.c
--- a/arch/cris/arch-v10/kernel/fasttimer.c	2005-03-01 23:39:18 -08:00
+++ b/arch/cris/arch-v10/kernel/fasttimer.c	2005-03-01 23:39:18 -08:00
@@ -599,23 +599,8 @@
 
 #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)
+                       ,int *eof, void *data_unused);
 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
@@ -624,12 +609,7 @@
 #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
-                               )
+                       ,int *eof, void *data_unused)
 {
   unsigned long flags;
   int i = 0;
@@ -805,9 +785,7 @@
 
   memcpy(buf, bigbuf + offset, len);
   *start = buf;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
   *eof = 1;
-#endif
 
   return len;
 }
@@ -982,12 +960,8 @@
     }
 #endif
 #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(TIMER1_IRQ_NBR, timer1_handler, SA_SHIRQ,
                    "fast timer int", NULL))
diff -Nru a/arch/cris/kernel/irq.c b/arch/cris/kernel/irq.c
--- a/arch/cris/kernel/irq.c	2005-03-01 23:39:17 -08:00
+++ b/arch/cris/kernel/irq.c	2005-03-01 23:39:17 -08:00
@@ -158,11 +158,6 @@
 		local_irq_disable();
         }
         irq_exit();
-
-	if (softirq_pending(cpu))
-                do_softirq();
-
-        /* unmasking and bottom half handling is done magically for us. */
 }
 
 /* this function links in a handler into the chain of handlers for the
diff -Nru a/arch/frv/Kconfig b/arch/frv/Kconfig
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/Kconfig	2005-03-01 23:39:26 -08:00
@@ -0,0 +1,501 @@
+#
+# For a description of the syntax of this configuration file,
+# see Documentation/kbuild/kconfig-language.txt.
+#
+config FRV
+	bool
+	default y
+
+config UID16
+	bool
+	default y
+
+config RWSEM_GENERIC_SPINLOCK
+	bool
+	default y
+
+config RWSEM_XCHGADD_ALGORITHM
+	bool
+
+config GENERIC_FIND_NEXT_BIT
+	bool
+	default y
+
+config GENERIC_CALIBRATE_DELAY
+	bool
+	default n
+
+config GENERIC_HARDIRQS
+	bool
+	default n
+
+mainmenu "Fujitsu FR-V Kernel Configuration"
+
+source "init/Kconfig"
+
+
+menu "Fujitsu FR-V system setup"
+
+config MMU
+	bool "MMU support"
+	help
+	  This options switches on and off support for the FR-V MMU
+	  (effectively switching between vmlinux and uClinux). Not all FR-V
+	  CPUs support this. Currently only the FR451 has a sufficiently
+	  featured MMU.
+
+config FRV_OUTOFLINE_ATOMIC_OPS
+	bool "Out-of-line the FRV atomic operations"
+	default n
+	help
+	  Setting this option causes the FR-V atomic operations to be mostly
+	  implemented out-of-line.
+
+	  See Documentation/fujitsu/frv/atomic-ops.txt for more information.
+
+config HIGHMEM
+	bool "High memory support"
+	depends on MMU
+	default y
+	help
+	  If you wish to use more than 256MB of memory with your MMU based
+	  system, you will need to select this option. The kernel can only see
+	  the memory between 0xC0000000 and 0xD0000000 directly... everything
+	  else must be kmapped.
+
+	  The arch is, however, capable of supporting up to 3GB of SDRAM.
+
+config HIGHPTE
+	bool "Allocate page tables in highmem"
+	depends on HIGHMEM
+	default y
+	help
+	  The VM uses one page of memory for each page table.  For systems
+	  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.
+
+choice
+	prompt "uClinux kernel load address"
+	depends on !MMU
+	default UCPAGE_OFFSET_C0000000
+	help
+	  This option sets the base address for the uClinux kernel. The kernel
+	  will rearrange the SDRAM layout to start at this address, and move
+	  itself to start there. It must be greater than 0, and it must be
+	  sufficiently less than 0xE0000000 that the SDRAM does not intersect
+	  the I/O region.
+
+	  The base address must also be aligned such that the SDRAM controller
+	  can decode it. For instance, a 512MB SDRAM bank must be 512MB aligned.
+
+config UCPAGE_OFFSET_20000000
+       bool "0x20000000"
+
+config UCPAGE_OFFSET_40000000
+       bool "0x40000000"
+
+config UCPAGE_OFFSET_60000000
+       bool "0x60000000"
+
+config UCPAGE_OFFSET_80000000
+       bool "0x80000000"
+
+config UCPAGE_OFFSET_A0000000
+       bool "0xA0000000"
+
+config UCPAGE_OFFSET_C0000000
+       bool "0xC0000000 (Recommended)"
+
+endchoice
+
+config PROTECT_KERNEL
+	bool "Protect core kernel against userspace"
+	depends on !MMU
+	default y
+	help
+	  Selecting this option causes the uClinux kernel to change the
+	  permittivity of DAMPR register covering the core kernel image to
+	  prevent userspace accessing the underlying memory directly.
+
+choice
+	prompt "CPU Caching mode"
+	default FRV_DEFL_CACHE_WBACK
+	help
+	  This option determines the default caching mode for the kernel.
+
+	  Write-Back caching mode involves the all reads and writes causing
+	  the affected cacheline to be read into the cache first before being
+	  operated upon. Memory is not then updated by a write until the cache
+	  is filled and a cacheline needs to be displaced from the cache to
+	  make room. Only at that point is it written back.
+
+	  Write-Behind caching is similar to Write-Back caching, except that a
+	  write won't fetch a cacheline into the cache if there isn't already
+	  one there; it will write directly to memory instead.
+
+	  Write-Through caching only fetches cachelines from memory on a
+	  read. Writes always get written directly to memory. If the affected
+	  cacheline is also in cache, it will be updated too.
+
+	  The final option is to turn of caching entirely.
+
+	  Note that not all CPUs support Write-Behind caching. If the CPU on
+	  which the kernel is running doesn't, it'll fall back to Write-Back
+	  caching.
+
+config FRV_DEFL_CACHE_WBACK
+	bool "Write-Back"
+
+config FRV_DEFL_CACHE_WBEHIND
+	bool "Write-Behind"
+
+config FRV_DEFL_CACHE_WTHRU
+	bool "Write-Through"
+
+config FRV_DEFL_CACHE_DISABLED
+	bool "Disabled"
+
+endchoice
+
+menu "CPU core support"
+
+config CPU_FR401
+	bool "Include FR401 core support"
+	depends on !MMU
+	default y
+	help
+	  This enables support for the FR401, FR401A and FR403 CPUs
+
+config CPU_FR405
+	bool "Include FR405 core support"
+	depends on !MMU
+	default y
+	help
+	  This enables support for the FR405 CPU
+
+config CPU_FR451
+	bool "Include FR451 core support"
+	default y
+	help
+	  This enables support for the FR451 CPU
+
+config CPU_FR451_COMPILE
+	bool "Specifically compile for FR451 core"
+	depends on CPU_FR451 && !CPU_FR401 && !CPU_FR405 && !CPU_FR551
+	default y
+	help
+	  This causes appropriate flags to be passed to the compiler to
+	  optimise for the FR451 CPU
+
+config CPU_FR551
+	bool "Include FR551 core support"
+	depends on !MMU
+	default y
+	help
+	  This enables support for the FR555 CPU
+
+config CPU_FR551_COMPILE
+	bool "Specifically compile for FR551 core"
+	depends on CPU_FR551 && !CPU_FR401 && !CPU_FR405 && !CPU_FR451
+	default y
+	help
+	  This causes appropriate flags to be passed to the compiler to
+	  optimise for the FR555 CPU
+
+config FRV_L1_CACHE_SHIFT
+	int
+	default "5" if CPU_FR401 || CPU_FR405 || CPU_FR451
+	default "6" if CPU_FR551
+
+endmenu
+
+choice
+	prompt "System support"
+	default MB93091_VDK
+
+config MB93091_VDK
+	bool "MB93091 CPU board with or without motherboard"
+
+config MB93093_PDK
+	bool "MB93093 PDK unit"
+
+endchoice
+
+if MB93091_VDK
+choice
+	prompt "Motherboard support"
+	default MB93090_MB00
+
+config MB93090_MB00
+	bool "Use the MB93090-MB00 motherboard"
+	help
+	  Select this option if the MB93091 CPU board is going to be used with
+	  a MB93090-MB00 VDK motherboard
+
+config MB93091_NO_MB
+	bool "Use standalone"
+	help
+	  Select this option if the MB93091 CPU board is going to be used
+	  without a motherboard
+
+endchoice
+endif
+
+choice
+	prompt "GP-Relative data support"
+	default GPREL_DATA_8
+	help
+	  This option controls what data, if any, should be placed in the GP
+	  relative data sections. Using this means that the compiler can
+	  generate accesses to the data using GR16-relative addressing which
+	  is faster than absolute instructions and saves space (2 instructions
+	  per access).
+
+	  However, the GPREL region is limited in size because the immediate
+	  value used in the load and store instructions is limited to a 12-bit
+	  signed number.
+
+	  So if the linker starts complaining that accesses to GPREL data are
+	  out of range, try changing this option from the default.
+
+	  Note that modules will always be compiled with this feature disabled
+	  as the module data will not be in range of the GP base address.
+
+config GPREL_DATA_8
+	bool "Put data objects of up to 8 bytes into GP-REL"
+
+config GPREL_DATA_4
+	bool "Put data objects of up to 4 bytes into GP-REL"
+
+config GPREL_DATA_NONE
+	bool "Don't use GP-REL"
+
+endchoice
+
+config PCI
+	bool "Use PCI"
+	depends on MB93090_MB00
+	default y
+	help
+	  Some FR-V systems (such as the MB93090-MB00 VDK) have PCI
+	  onboard. If you have one of these boards and you wish to use the PCI
+	  facilities, say Y here.
+
+	  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.
+
+config RESERVE_DMA_COHERENT
+	bool "Reserve DMA coherent memory"
+	depends on PCI && !MMU
+	default y
+	help
+	  Many PCI drivers require access to uncached memory for DMA device
+	  communications (such as is done with some Ethernet buffer rings). If
+	  a fully featured MMU is available, this can be done through page
+	  table settings, but if not, a region has to be set aside and marked
+	  with a special DAMPR register.
+
+	  Setting this option causes uClinux to set aside a portion of the
+	  available memory for use in this manner. The memory will then be
+	  unavailable for normal kernel use.
+
+source "drivers/pci/Kconfig"
+
+config PCMCIA
+	tristate "Use PCMCIA"
+	help
+	  Say Y here if you want to attach PCMCIA- or PC-cards to your FR-V
+	  board.  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.  If you want to use CardBus
+	  cards, you need to say Y here and also to "CardBus support" below.
+
+	  To use your PC-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 compile this driver as modules, choose M here: the
+	  modules will be called pcmcia_core and ds.
+
+#config MATH_EMULATION
+#	bool "Math emulation support (EXPERIMENTAL)"
+#	depends on EXPERIMENTAL
+#	help
+#	  At some point in the future, this will cause floating-point math
+#	  instructions to be emulated by the kernel on machines that lack a
+#	  floating-point math coprocessor.  Thrill-seekers and chronically
+#	  sleep-deprived psychotic hacker types can say Y now, everyone else
+#	  should probably wait a while.
+
+menu "Power management options"
+source kernel/power/Kconfig
+endmenu
+
+endmenu
+
+
+menu "Executable formats"
+
+source "fs/Kconfig.binfmt"
+
+endmenu
+
+source "drivers/Kconfig"
+
+source "fs/Kconfig"
+
+menu "Kernel hacking"
+
+config DEBUG_KERNEL
+	bool "Kernel debugging"
+	help
+	  Say Y here if you are developing drivers or trying to debug and
+	  identify kernel problems.
+
+config EARLY_PRINTK
+	bool "Early printk"
+	depends on EMBEDDED && DEBUG_KERNEL
+	default n
+	help
+	  Write kernel log output directly into the VGA buffer or to a serial
+	  port.
+
+	  This is useful for kernel debugging when your machine crashes very
+	  early before the console code is initialized. For normal operation
+	  it is not recommended because it looks ugly and doesn't cooperate
+	  with klogd/syslogd or the X server. You should normally N here,
+	  unless you want to debug such a crash.
+
+config DEBUG_STACKOVERFLOW
+	bool "Check for stack overflows"
+	depends on DEBUG_KERNEL
+
+config DEBUG_SLAB
+	bool "Debug memory allocations"
+	depends on DEBUG_KERNEL
+	help
+	  Say Y here to have the kernel do limited verification on memory
+	  allocation as well as poisoning memory on free to catch use of freed
+	  memory.
+
+config MAGIC_SYSRQ
+	bool "Magic SysRq key"
+	depends on DEBUG_KERNEL
+	help
+	  If you say Y here, you will have some control over the system even
+	  if the system crashes for example during kernel debugging (e.g., you
+	  will be able to flush the buffer cache to disk, reboot the system
+	  immediately or dump some status information). This is accomplished
+	  by pressing various keys while holding SysRq (Alt+PrintScreen). It
+	  also works on a serial console (on PC hardware at least), if you
+	  send a BREAK and then within 5 seconds a command keypress. The
+	  keys are documented in <file:Documentation/sysrq.txt>. Don't say Y
+	  unless you really know what this hack does.
+
+config DEBUG_SPINLOCK
+	bool "Spinlock debugging"
+	depends on DEBUG_KERNEL
+	help
+	  Say Y here and build SMP to catch missing spinlock initialization
+	  and certain other kinds of spinlock errors commonly made.  This is
+	  best used in conjunction with the NMI watchdog so that spinlock
+	  deadlocks are also debuggable.
+
+config DEBUG_SPINLOCK_SLEEP
+	bool "Sleep-inside-spinlock checking"
+	depends on DEBUG_KERNEL
+	help
+	  If you say Y here, various routines which may sleep will become very
+	  noisy if they are called with a spinlock held.
+
+config DEBUG_PAGEALLOC
+	bool "Page alloc debugging"
+	depends on DEBUG_KERNEL
+	help
+	  Unmap pages from the kernel linear mapping after free_pages().
+	  This results in a large slowdown, but helps to find certain types
+	  of memory corruptions.
+
+config DEBUG_HIGHMEM
+	bool "Highmem debugging"
+	depends on DEBUG_KERNEL && HIGHMEM
+	help
+	  This options enables addition error checking for high memory systems.
+	  Disable for production systems.
+
+config DEBUG_INFO
+	bool "Compile the kernel with debug info"
+	depends on DEBUG_KERNEL
+	help
+          If you say Y here the resulting kernel image will include
+	  debugging info resulting in a larger kernel image.
+	  Say Y here only if you plan to use gdb to debug the kernel.
+	  If you don't debug the kernel, you can say N.
+
+config DEBUG_BUGVERBOSE
+	bool "Verbose BUG() reporting"
+	depends on DEBUG_KERNEL
+
+config FRAME_POINTER
+	bool "Compile the kernel with frame pointers"
+	depends on DEBUG_KERNEL
+	help
+	  If you say Y here the resulting kernel image will be slightly larger
+	  and slower, but it will give very useful debugging information.
+	  If you don't debug the kernel, you can say N, but we may not be able
+	  to solve problems without frame pointers.
+
+config GDBSTUB
+	bool "Remote GDB kernel debugging"
+	depends on DEBUG_KERNEL
+	select DEBUG_INFO
+	select FRAME_POINTER
+	help
+	  If you say Y here, it will be possible to remotely debug the kernel
+	  using gdb. This enlarges your kernel ELF image disk size by several
+	  megabytes and requires a machine with more than 16 MB, better 32 MB
+	  RAM to avoid excessive linking time. This is only useful for kernel
+	  hackers. If unsure, say N.
+
+choice
+	prompt "GDB stub port"
+	default GDBSTUB_UART1
+	depends on GDBSTUB
+	help
+	  Select the on-CPU port used for GDB-stub
+
+config GDBSTUB_UART0
+	bool "/dev/ttyS0"
+
+config GDBSTUB_UART1
+	bool "/dev/ttyS1"
+
+endchoice
+
+config GDBSTUB_IMMEDIATE
+	bool "Break into GDB stub immediately"
+	depends on GDBSTUB
+	help
+	  If you say Y here, GDB stub will break into the program as soon as
+	  possible, leaving the program counter at the beginning of
+	  start_kernel() in init/main.c.
+
+config GDB_CONSOLE
+	bool "Console output to GDB"
+	depends on KGDB
+	help
+	  If you are using GDB for remote debugging over a serial port and
+	  would like kernel messages to be formatted into GDB $O packets so
+	  that GDB prints them as program output, say 'Y'.
+
+endmenu
+
+source "security/Kconfig"
+
+source "crypto/Kconfig"
+
+source "lib/Kconfig"
diff -Nru a/arch/frv/Makefile b/arch/frv/Makefile
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/Makefile	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,118 @@
+#
+# frv/Makefile
+#
+# 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
+#
+# This file 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 Red Hat Inc.
+# - Written by David Howells <dhowells@redhat.com>
+# - Derived from arch/m68knommu/Makefile,
+#	Copyright (c) 1999,2001  D. Jeff Dionne <jeff@lineo.ca>,
+#	Rt-Control Inc. / Lineo, Inc.
+#
+# Copyright (C) 1998,1999  D. Jeff Dionne <jeff@uclinux.org>,
+#                          Kenneth Albanowski <kjahds@kjahds.com>,
+#
+# Based on arch/m68k/Makefile:
+# Copyright (C) 1994 by Hamish Macdonald
+#
+
+CCSPECS	:= $(shell $(CC) -v 2>&1 | grep "^Reading specs from " | head -1 | cut -c20-)
+CCDIR	:= $(strip $(patsubst %/specs,%,$(CCSPECS)))
+CPUCLASS := fr400
+
+# test for cross compiling
+COMPILE_ARCH = $(shell uname -m)
+
+ifdef CONFIG_MMU
+UTS_SYSNAME = -DUTS_SYSNAME=\"Linux\"
+else
+UTS_SYSNAME = -DUTS_SYSNAME=\"uClinux\"
+endif
+
+ARCHMODFLAGS	+= -G0 -mlong-calls
+
+ifdef CONFIG_GPREL_DATA_8
+CFLAGS		+= -G8
+else
+ifdef CONFIG_GPREL_DATA_4
+CFLAGS		+= -G4
+else
+ifdef CONFIG_GPREL_DATA_NONE
+CFLAGS		+= -G0
+endif
+endif
+endif
+
+#LDFLAGS_vmlinux	:= -Map linkmap.txt
+
+ifdef CONFIG_GC_SECTIONS
+CFLAGS		+= -ffunction-sections -fdata-sections
+LINKFLAGS	+= --gc-sections
+endif
+
+ifndef CONFIG_FRAME_POINTER
+CFLAGS		+= -mno-linked-fp
+endif
+
+ifdef CONFIG_CPU_FR451_COMPILE
+CFLAGS		+= -mcpu=fr450
+AFLAGS		+= -mcpu=fr450
+ASFLAGS		+= -mcpu=fr450
+else
+ifdef CONFIG_CPU_FR551_COMPILE
+CFLAGS		+= -mcpu=fr550
+AFLAGS		+= -mcpu=fr550
+ASFLAGS		+= -mcpu=fr550
+else
+CFLAGS		+= -mcpu=fr400
+AFLAGS		+= -mcpu=fr400
+ASFLAGS		+= -mcpu=fr400
+endif
+endif
+
+# pretend the kernel is going to run on an FR400 with no media-fp unit
+# - reserve CC3 for use with atomic ops
+# - all the extra registers are dealt with only at context switch time
+CFLAGS		+= -mno-fdpic -mgpr-32 -msoft-float -mno-media
+CFLAGS		+= -ffixed-fcc3 -ffixed-cc3 -ffixed-gr15
+AFLAGS		+= -mno-fdpic
+ASFLAGS		+= -mno-fdpic
+
+# make sure the .S files get compiled with debug info
+# and disable optimisations that are unhelpful whilst debugging
+ifdef CONFIG_DEBUG_INFO
+CFLAGS		+= -O1
+AFLAGS		+= -Wa,--gdwarf2
+ASFLAGS		+= -Wa,--gdwarf2
+endif
+
+head-y		:= arch/frv/kernel/head.o arch/frv/kernel/init_task.o
+
+core-y		+= arch/frv/kernel/ arch/frv/mm/
+libs-y		+= arch/frv/lib/
+
+core-$(CONFIG_MB93090_MB00)	+= arch/frv/mb93090-mb00/
+
+all: Image
+
+Image: vmlinux
+	$(Q)$(MAKE) $(build)=arch/frv/boot $@
+
+bootstrap:
+	$(Q)$(MAKEBOOT) bootstrap
+
+archmrproper:
+	$(Q)$(MAKE) -C arch/frv/boot mrproper
+
+archclean:
+	$(Q)$(MAKE) -C arch/frv/boot clean
+
+archdep: scripts/mkdep symlinks
+	$(Q)$(MAKE) -C arch/frv/boot dep
diff -Nru a/arch/frv/boot/Makefile b/arch/frv/boot/Makefile
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/boot/Makefile	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,73 @@
+#
+# arch/arm/boot/Makefile
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 1995-2000 Russell King
+#
+
+SYSTEM	=$(TOPDIR)/$(LINUX)
+
+ZTEXTADDR	 = 0x02080000
+PARAMS_PHYS	 = 0x0207c000
+INITRD_PHYS	 = 0x02180000
+INITRD_VIRT	 = 0x02180000
+
+#
+# If you don't define ZRELADDR above,
+# then it defaults to ZTEXTADDR
+#
+ifeq ($(ZRELADDR),)
+ZRELADDR	= $(ZTEXTADDR)
+endif
+
+export	SYSTEM ZTEXTADDR ZBSSADDR ZRELADDR INITRD_PHYS INITRD_VIRT PARAMS_PHYS
+
+Image: $(obj)/Image
+
+targets: $(obj)/Image
+
+$(obj)/Image: vmlinux FORCE
+	$(OBJCOPY) -O binary -R .note -R .comment -S vmlinux $@
+
+#$(obj)/Image:	$(CONFIGURE) $(SYSTEM)
+#	$(OBJCOPY) -O binary -R .note -R .comment -g -S $(SYSTEM) $@
+
+bzImage: zImage
+
+zImage:	$(CONFIGURE) compressed/$(LINUX)
+	$(OBJCOPY) -O binary -R .note -R .comment -S compressed/$(LINUX) $@
+
+bootpImage: bootp/bootp
+	$(OBJCOPY) -O binary -R .note -R .comment -S bootp/bootp $@
+
+compressed/$(LINUX): $(TOPDIR)/$(LINUX) dep
+	@$(MAKE) -C compressed $(LINUX)
+
+bootp/bootp: zImage initrd
+	@$(MAKE) -C bootp bootp
+
+initrd:
+	@test "$(INITRD_VIRT)" != "" || (echo This architecture does not support INITRD; exit -1)
+	@test "$(INITRD)" != "" || (echo You must specify INITRD; exit -1)
+
+#
+# installation
+#
+install: $(CONFIGURE) Image
+	sh ./install.sh $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) Image $(TOPDIR)/System.map "$(INSTALL_PATH)"
+
+zinstall: $(CONFIGURE) zImage
+	sh ./install.sh $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) zImage $(TOPDIR)/System.map "$(INSTALL_PATH)"
+
+#
+# miscellany
+#
+mrproper clean:
+	$(RM) Image zImage bootpImage
+#	@$(MAKE) -C compressed clean
+#	@$(MAKE) -C bootp clean
+
+dep:
diff -Nru a/arch/frv/kernel/Makefile b/arch/frv/kernel/Makefile
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/kernel/Makefile	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,22 @@
+#
+# Makefile for the linux kernel.
+#
+
+heads-y				:= head-uc-fr401.o head-uc-fr451.o head-uc-fr555.o
+heads-$(CONFIG_MMU)		:= head-mmu-fr451.o
+
+extra-y:= head.o init_task.o vmlinux.lds
+
+obj-y := $(heads-y) entry.o entry-table.o break.o switch_to.o kernel_thread.o \
+	 process.o traps.o ptrace.o signal.o dma.o \
+	 sys_frv.o time.o semaphore.o setup.o frv_ksyms.o \
+	 debug-stub.o irq.o irq-routing.o sleep.o uaccess.o
+
+obj-$(CONFIG_GDBSTUB)		+= gdb-stub.o gdb-io.o
+
+obj-$(CONFIG_MB93091_VDK)	+= irq-mb93091.o
+obj-$(CONFIG_MB93093_PDK)	+= irq-mb93093.o
+obj-$(CONFIG_FUJITSU_MB93493)	+= irq-mb93493.o
+obj-$(CONFIG_PM)		+= pm.o cmode.o
+obj-$(CONFIG_MB93093_PDK)	+= pm-mb93093.o
+obj-$(CONFIG_SYSCTL)		+= sysctl.o
diff -Nru a/arch/frv/kernel/break.S b/arch/frv/kernel/break.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/kernel/break.S	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,720 @@
+/* break.S: Break interrupt handling (kept separate from entry.S)
+ *
+ * Copyright (C) 2003 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/sys.h>
+#include <linux/config.h>
+#include <linux/linkage.h>
+#include <asm/setup.h>
+#include <asm/segment.h>
+#include <asm/ptrace.h>
+#include <asm/spr-regs.h>
+
+#include <asm/errno.h>
+
+#
+# the break handler has its own stack
+#
+	.section	.bss.stack
+	.globl		__break_user_context
+	.balign		8192
+__break_stack:
+	.space		(8192 - (USER_CONTEXT_SIZE + REG__DEBUG_XTRA)) & ~7
+__break_stack_tos:
+	.space		REG__DEBUG_XTRA
+__break_user_context:
+	.space		USER_CONTEXT_SIZE
+
+#
+# miscellaneous variables
+#
+	.section	.bss
+#ifdef CONFIG_MMU
+	.globl		__break_tlb_miss_real_return_info
+__break_tlb_miss_real_return_info:
+	.balign		8
+	.space		2*4			/* saved PCSR, PSR for TLB-miss handler fixup */
+#endif
+
+__break_trace_through_exceptions:
+	.space		4
+
+#define CS2_ECS1	0xe1200000
+#define CS2_USERLED	0x4
+
+.macro LEDS val,reg
+#	sethi.p		%hi(CS2_ECS1+CS2_USERLED),gr30
+#	setlo		%lo(CS2_ECS1+CS2_USERLED),gr30
+#	setlos		#~\val,\reg
+#	st		\reg,@(gr30,gr0)
+#	setlos		#0x5555,\reg
+#	sethi.p		%hi(0xffc00100),gr30
+#	setlo		%lo(0xffc00100),gr30
+#	sth		\reg,@(gr30,gr0)
+#	membar
+.endm
+
+###############################################################################
+#
+# entry point for Break Exceptions/Interrupts
+#
+###############################################################################
+	.text
+	.balign		4
+	.globl		__entry_break
+__entry_break:
+#ifdef CONFIG_MMU
+	movgs		gr31,scr3
+#endif
+	LEDS		0x1001,gr31
+
+	sethi.p		%hi(__break_user_context),gr31
+	setlo		%lo(__break_user_context),gr31
+
+	stdi		gr2,@(gr31,#REG_GR(2))
+	movsg		ccr,gr3
+	sti		gr3,@(gr31,#REG_CCR)
+
+	# catch the return from a TLB-miss handler that had single-step disabled
+	# traps will be enabled, so we have to do this now
+#ifdef CONFIG_MMU
+	movsg		bpcsr,gr3
+	sethi.p		%hi(__break_tlb_miss_return_breaks_here),gr2
+	setlo		%lo(__break_tlb_miss_return_breaks_here),gr2
+	subcc		gr2,gr3,gr0,icc0
+	beq		icc0,#2,__break_return_singlestep_tlbmiss
+#endif
+
+	# determine whether we have stepped through into an exception
+	# - we need to take special action to suspend h/w single stepping if we've done
+	#   that, so that the gdbstub doesn't get bogged down endlessly stepping through
+	#   external interrupt handling
+	movsg		bpsr,gr3
+	andicc		gr3,#BPSR_BET,gr0,icc0
+	bne		icc0,#2,__break_maybe_userspace	/* jump if PSR.ET was 1 */
+
+	LEDS		0x1003,gr2
+
+	movsg		brr,gr3
+	andicc		gr3,#BRR_ST,gr0,icc0
+	andicc.p	gr3,#BRR_SB,gr0,icc1
+	bne		icc0,#2,__break_step		/* jump if single-step caused break */
+	beq		icc1,#2,__break_continue	/* jump if BREAK didn't cause break */
+
+	LEDS		0x1007,gr2
+
+	# handle special breaks
+	movsg		bpcsr,gr3
+
+	sethi.p		%hi(__entry_return_singlestep_breaks_here),gr2
+	setlo		%lo(__entry_return_singlestep_breaks_here),gr2
+	subcc		gr2,gr3,gr0,icc0
+	beq		icc0,#2,__break_return_singlestep
+
+	bra		__break_continue
+
+
+###############################################################################
+#
+# handle BREAK instruction in kernel-mode exception epilogue
+#
+###############################################################################
+__break_return_singlestep:
+	LEDS		0x100f,gr2
+
+	# special break insn requests single-stepping to be turned back on
+	#		HERE		RETT
+	# PSR.ET	0		0
+	# PSR.PS	old PSR.S	?
+	# PSR.S		1		1
+	# BPSR.ET	0		1 (can't have caused orig excep otherwise)
+	# BPSR.BS	1		old PSR.S
+	movsg		dcr,gr2
+	sethi.p		%hi(DCR_SE),gr3
+	setlo		%lo(DCR_SE),gr3
+	or		gr2,gr3,gr2
+	movgs		gr2,dcr
+
+	movsg		psr,gr2
+	andi		gr2,#PSR_PS,gr2
+	slli		gr2,#11,gr2			/* PSR.PS -> BPSR.BS */
+	ori		gr2,#BPSR_BET,gr2		/* 1 -> BPSR.BET */
+	movgs		gr2,bpsr
+
+	# return to the invoker of the original kernel exception
+	movsg		pcsr,gr2
+	movgs		gr2,bpcsr
+
+	LEDS		0x101f,gr2
+
+	ldi		@(gr31,#REG_CCR),gr3
+	movgs		gr3,ccr
+	lddi.p		@(gr31,#REG_GR(2)),gr2
+	xor		gr31,gr31,gr31
+	movgs		gr0,brr
+#ifdef CONFIG_MMU
+	movsg		scr3,gr31
+#endif
+	rett		#1
+
+###############################################################################
+#
+# handle BREAK instruction in TLB-miss handler return path
+#
+###############################################################################
+#ifdef CONFIG_MMU
+__break_return_singlestep_tlbmiss:
+	LEDS		0x1100,gr2
+
+	sethi.p		%hi(__break_tlb_miss_real_return_info),gr3
+	setlo		%lo(__break_tlb_miss_real_return_info),gr3
+	lddi		@(gr3,#0),gr2
+	movgs		gr2,pcsr
+	movgs		gr3,psr
+
+	bra		__break_return_singlestep
+#endif
+
+
+###############################################################################
+#
+# handle single stepping into an exception prologue from kernel mode
+# - we try and catch it whilst it is still in the main vector table
+# - if we catch it there, we have to jump to the fixup handler
+#   - there is a fixup table that has a pointer for every 16b slot in the trap
+#     table
+#
+###############################################################################
+__break_step:
+	LEDS		0x2003,gr2
+
+	# external interrupts seem to escape from the trap table before single
+	# step catches up with them
+	movsg		bpcsr,gr2
+	sethi.p		%hi(__entry_kernel_external_interrupt),gr3
+	setlo		%lo(__entry_kernel_external_interrupt),gr3
+	subcc		gr2,gr3,gr0,icc0
+	beq		icc0,#2,__break_step_kernel_external_interrupt
+	sethi.p		%hi(__entry_uspace_external_interrupt),gr3
+	setlo		%lo(__entry_uspace_external_interrupt),gr3
+	subcc		gr2,gr3,gr0,icc0
+	beq		icc0,#2,__break_step_uspace_external_interrupt
+
+	LEDS		0x2007,gr2
+
+	# the two main vector tables are adjacent on one 8Kb slab
+	movsg		bpcsr,gr2
+	setlos		#0xffffe000,gr3
+	and		gr2,gr3,gr2
+	sethi.p		%hi(__trap_tables),gr3
+	setlo		%lo(__trap_tables),gr3
+	subcc		gr2,gr3,gr0,icc0
+	bne		icc0,#2,__break_continue
+
+	LEDS		0x200f,gr2
+
+	# skip workaround if so requested by GDB
+	sethi.p		%hi(__break_trace_through_exceptions),gr3
+	setlo		%lo(__break_trace_through_exceptions),gr3
+	ld		@(gr3,gr0),gr3
+	subcc		gr3,gr0,gr0,icc0
+	bne		icc0,#0,__break_continue
+
+	LEDS		0x201f,gr2
+
+	# access the fixup table - there's a 1:1 mapping between the slots in the trap tables and
+	# the slots in the trap fixup tables allowing us to simply divide the offset into the
+	# former by 4 to access the latter
+	sethi.p		%hi(__trap_tables),gr3
+	setlo		%lo(__trap_tables),gr3
+	movsg		bpcsr,gr2
+	sub		gr2,gr3,gr2
+	srli.p		gr2,#2,gr2
+
+	sethi		%hi(__trap_fixup_tables),gr3
+	setlo.p		%lo(__trap_fixup_tables),gr3
+	andi		gr2,#~3,gr2
+	ld		@(gr2,gr3),gr2
+	jmpil		@(gr2,#0)
+
+# step through an internal exception from kernel mode
+	.globl		__break_step_kernel_softprog_interrupt
+__break_step_kernel_softprog_interrupt:
+	sethi.p		%hi(__entry_kernel_softprog_interrupt_reentry),gr3
+	setlo		%lo(__entry_kernel_softprog_interrupt_reentry),gr3
+	bra		__break_return_as_kernel_prologue
+
+# step through an external interrupt from kernel mode
+	.globl		__break_step_kernel_external_interrupt
+__break_step_kernel_external_interrupt:
+	sethi.p		%hi(__entry_kernel_external_interrupt_reentry),gr3
+	setlo		%lo(__entry_kernel_external_interrupt_reentry),gr3
+
+__break_return_as_kernel_prologue:
+	LEDS		0x203f,gr2
+
+	movgs		gr3,bpcsr
+
+	# do the bit we had to skip
+#ifdef CONFIG_MMU
+	movsg		ear0,gr2		/* EAR0 can get clobbered by gdb-stub (ICI/ICEI) */
+	movgs		gr2,scr2
+#endif
+
+	or.p		sp,gr0,gr2		/* set up the stack pointer */
+	subi		sp,#REG__END,sp
+	sti.p		gr2,@(sp,#REG_SP)
+
+	setlos		#REG__STATUS_STEP,gr2
+	sti		gr2,@(sp,#REG__STATUS)		/* record single step status */
+
+	# cancel single-stepping mode
+	movsg		dcr,gr2
+	sethi.p		%hi(~DCR_SE),gr3
+	setlo		%lo(~DCR_SE),gr3
+	and		gr2,gr3,gr2
+	movgs		gr2,dcr
+
+	LEDS		0x207f,gr2
+
+	ldi		@(gr31,#REG_CCR),gr3
+	movgs		gr3,ccr
+	lddi.p		@(gr31,#REG_GR(2)),gr2
+	xor		gr31,gr31,gr31
+	movgs		gr0,brr
+#ifdef CONFIG_MMU
+	movsg		scr3,gr31
+#endif
+	rett		#1
+
+# step through an internal exception from uspace mode
+	.globl		__break_step_uspace_softprog_interrupt
+__break_step_uspace_softprog_interrupt:
+	sethi.p		%hi(__entry_uspace_softprog_interrupt_reentry),gr3
+	setlo		%lo(__entry_uspace_softprog_interrupt_reentry),gr3
+	bra		__break_return_as_uspace_prologue
+
+# step through an external interrupt from kernel mode
+	.globl		__break_step_uspace_external_interrupt
+__break_step_uspace_external_interrupt:
+	sethi.p		%hi(__entry_uspace_external_interrupt_reentry),gr3
+	setlo		%lo(__entry_uspace_external_interrupt_reentry),gr3
+
+__break_return_as_uspace_prologue:
+	LEDS		0x20ff,gr2
+
+	movgs		gr3,bpcsr
+
+	# do the bit we had to skip
+	sethi.p		%hi(__kernel_frame0_ptr),gr28
+	setlo		%lo(__kernel_frame0_ptr),gr28
+	ldi.p		@(gr28,#0),gr28
+
+	setlos		#REG__STATUS_STEP,gr2
+	sti		gr2,@(gr28,#REG__STATUS)	/* record single step status */
+
+	# cancel single-stepping mode
+	movsg		dcr,gr2
+	sethi.p		%hi(~DCR_SE),gr3
+	setlo		%lo(~DCR_SE),gr3
+	and		gr2,gr3,gr2
+	movgs		gr2,dcr
+
+	LEDS		0x20fe,gr2
+
+	ldi		@(gr31,#REG_CCR),gr3
+	movgs		gr3,ccr
+	lddi.p		@(gr31,#REG_GR(2)),gr2
+	xor		gr31,gr31,gr31
+	movgs		gr0,brr
+#ifdef CONFIG_MMU
+	movsg		scr3,gr31
+#endif
+	rett		#1
+
+#ifdef CONFIG_MMU
+# step through an ITLB-miss handler from user mode
+	.globl		__break_user_insn_tlb_miss
+__break_user_insn_tlb_miss:
+	# we'll want to try the trap stub again
+	sethi.p		%hi(__trap_user_insn_tlb_miss),gr2
+	setlo		%lo(__trap_user_insn_tlb_miss),gr2
+	movgs		gr2,bpcsr
+
+__break_tlb_miss_common:
+	LEDS		0x2101,gr2
+
+	# cancel single-stepping mode
+	movsg		dcr,gr2
+	sethi.p		%hi(~DCR_SE),gr3
+	setlo		%lo(~DCR_SE),gr3
+	and		gr2,gr3,gr2
+	movgs		gr2,dcr
+
+	# we'll swap the real return address for one with a BREAK insn so that we can re-enable
+	# single stepping on return
+	movsg		pcsr,gr2
+	sethi.p		%hi(__break_tlb_miss_real_return_info),gr3
+	setlo		%lo(__break_tlb_miss_real_return_info),gr3
+	sti		gr2,@(gr3,#0)
+
+	sethi.p		%hi(__break_tlb_miss_return_break),gr2
+	setlo		%lo(__break_tlb_miss_return_break),gr2
+	movgs		gr2,pcsr
+
+	# we also have to fudge PSR because the return BREAK is in kernel space and we want
+	# to get a BREAK fault not an access violation should the return be to userspace
+	movsg		psr,gr2
+	sti.p		gr2,@(gr3,#4)
+	ori		gr2,#PSR_PS,gr2
+	movgs		gr2,psr
+
+	LEDS		0x2102,gr2
+
+	ldi		@(gr31,#REG_CCR),gr3
+	movgs		gr3,ccr
+	lddi		@(gr31,#REG_GR(2)),gr2
+	movsg		scr3,gr31
+	movgs		gr0,brr
+	rett		#1
+
+# step through a DTLB-miss handler from user mode
+	.globl		__break_user_data_tlb_miss
+__break_user_data_tlb_miss:
+	# we'll want to try the trap stub again
+	sethi.p		%hi(__trap_user_data_tlb_miss),gr2
+	setlo		%lo(__trap_user_data_tlb_miss),gr2
+	movgs		gr2,bpcsr
+	bra		__break_tlb_miss_common
+
+# step through an ITLB-miss handler from kernel mode
+	.globl		__break_kernel_insn_tlb_miss
+__break_kernel_insn_tlb_miss:
+	# we'll want to try the trap stub again
+	sethi.p		%hi(__trap_kernel_insn_tlb_miss),gr2
+	setlo		%lo(__trap_kernel_insn_tlb_miss),gr2
+	movgs		gr2,bpcsr
+	bra		__break_tlb_miss_common
+
+# step through a DTLB-miss handler from kernel mode
+	.globl		__break_kernel_data_tlb_miss
+__break_kernel_data_tlb_miss:
+	# we'll want to try the trap stub again
+	sethi.p		%hi(__trap_kernel_data_tlb_miss),gr2
+	setlo		%lo(__trap_kernel_data_tlb_miss),gr2
+	movgs		gr2,bpcsr
+	bra		__break_tlb_miss_common
+#endif
+
+###############################################################################
+#
+# handle debug events originating with userspace
+#
+###############################################################################
+__break_maybe_userspace:
+	LEDS		0x3003,gr2
+
+	setlos		#BPSR_BS,gr2
+	andcc		gr3,gr2,gr0,icc0
+	bne		icc0,#0,__break_continue	/* skip if PSR.S was 1 */
+
+	movsg		brr,gr2
+	andicc		gr2,#BRR_ST|BRR_SB,gr0,icc0
+	beq		icc0,#0,__break_continue	/* jump if not BREAK or single-step */
+
+	LEDS		0x3007,gr2
+
+	# do the first part of the exception prologue here
+	sethi.p		%hi(__kernel_frame0_ptr),gr28
+	setlo		%lo(__kernel_frame0_ptr),gr28
+	ldi		@(gr28,#0),gr28
+	andi		gr28,#~7,gr28
+
+	# set up the kernel stack pointer
+	sti		sp  ,@(gr28,#REG_SP)
+	ori		gr28,0,sp
+	sti		gr0 ,@(gr28,#REG_GR(28))
+
+	stdi		gr20,@(gr28,#REG_GR(20))
+	stdi		gr22,@(gr28,#REG_GR(22))
+
+	movsg		tbr,gr20
+	movsg		bpcsr,gr21
+	movsg		psr,gr22
+
+	# determine the exception type and cancel single-stepping mode
+	or		gr0,gr0,gr23
+
+	movsg		dcr,gr2
+	sethi.p		%hi(DCR_SE),gr3
+	setlo		%lo(DCR_SE),gr3
+	andcc		gr2,gr3,gr0,icc0
+	beq		icc0,#0,__break_no_user_sstep	/* must have been a BREAK insn */
+
+	not		gr3,gr3
+	and		gr2,gr3,gr2
+	movgs		gr2,dcr
+	ori		gr23,#REG__STATUS_STEP,gr23
+
+__break_no_user_sstep:
+	LEDS		0x300f,gr2
+
+	movsg		brr,gr2
+	andi		gr2,#BRR_ST|BRR_SB,gr2
+	slli		gr2,#1,gr2
+	or		gr23,gr2,gr23
+	sti.p		gr23,@(gr28,#REG__STATUS)	/* record single step status */
+
+	# adjust the value acquired from TBR - this indicates the exception
+	setlos		#~TBR_TT,gr2
+	and.p		gr20,gr2,gr20
+	setlos		#TBR_TT_BREAK,gr2
+	or.p		gr20,gr2,gr20
+
+	# fudge PSR.PS and BPSR.BS to return to kernel mode through the trap
+	# table as trap 126
+	andi		gr22,#~PSR_PS,gr22		/* PSR.PS should be 0 */
+	movgs		gr22,psr
+
+	setlos		#BPSR_BS,gr2			/* BPSR.BS should be 1 and BPSR.BET 0 */
+	movgs		gr2,bpsr
+
+	# return through remainder of the exception prologue
+	# - need to load gr23 with return handler address
+	sethi.p		%hi(__entry_return_from_user_exception),gr23
+	setlo		%lo(__entry_return_from_user_exception),gr23
+	sethi.p		%hi(__entry_common),gr3
+	setlo		%lo(__entry_common),gr3
+	movgs		gr3,bpcsr
+
+	LEDS		0x301f,gr2
+
+	ldi		@(gr31,#REG_CCR),gr3
+	movgs		gr3,ccr
+	lddi.p		@(gr31,#REG_GR(2)),gr2
+	xor		gr31,gr31,gr31
+	movgs		gr0,brr
+#ifdef CONFIG_MMU
+	movsg		scr3,gr31
+#endif
+	rett		#1
+
+###############################################################################
+#
+# resume normal debug-mode entry
+#
+###############################################################################
+__break_continue:
+	LEDS		0x4003,gr2
+
+	# set up the kernel stack pointer
+	sti		sp,@(gr31,#REG_SP)
+
+	sethi.p		%hi(__break_stack_tos),sp
+	setlo		%lo(__break_stack_tos),sp
+
+	# finish building the exception frame
+	stdi		gr4 ,@(gr31,#REG_GR(4))
+	stdi		gr6 ,@(gr31,#REG_GR(6))
+	stdi		gr8 ,@(gr31,#REG_GR(8))
+	stdi		gr10,@(gr31,#REG_GR(10))
+	stdi		gr12,@(gr31,#REG_GR(12))
+	stdi		gr14,@(gr31,#REG_GR(14))
+	stdi		gr16,@(gr31,#REG_GR(16))
+	stdi		gr18,@(gr31,#REG_GR(18))
+	stdi		gr20,@(gr31,#REG_GR(20))
+	stdi		gr22,@(gr31,#REG_GR(22))
+	stdi		gr24,@(gr31,#REG_GR(24))
+	stdi		gr26,@(gr31,#REG_GR(26))
+	sti		gr0 ,@(gr31,#REG_GR(28))	/* NULL frame pointer */
+	sti		gr29,@(gr31,#REG_GR(29))
+	sti		gr30,@(gr31,#REG_GR(30))
+	sti		gr8 ,@(gr31,#REG_ORIG_GR8)
+
+#ifdef CONFIG_MMU
+	movsg		scr3,gr19
+	sti		gr19,@(gr31,#REG_GR(31))
+#endif
+
+	movsg		bpsr ,gr19
+	movsg		tbr  ,gr20
+	movsg		bpcsr,gr21
+	movsg		psr  ,gr22
+	movsg		isr  ,gr23
+	movsg		cccr ,gr25
+	movsg		lr   ,gr26
+	movsg		lcr  ,gr27
+
+	andi.p		gr22,#~(PSR_S|PSR_ET),gr5	/* rebuild PSR */
+	andi		gr19,#PSR_ET,gr4
+	or.p		gr4,gr5,gr5
+	srli		gr19,#10,gr4
+	andi		gr4,#PSR_S,gr4
+	or.p		gr4,gr5,gr5
+
+	setlos		#-1,gr6
+	sti		gr20,@(gr31,#REG_TBR)
+	sti		gr21,@(gr31,#REG_PC)
+	sti		gr5 ,@(gr31,#REG_PSR)
+	sti		gr23,@(gr31,#REG_ISR)
+	sti		gr25,@(gr31,#REG_CCCR)
+	stdi		gr26,@(gr31,#REG_LR)
+	sti		gr6 ,@(gr31,#REG_SYSCALLNO)
+
+	# store CPU-specific regs
+	movsg		iacc0h,gr4
+	movsg		iacc0l,gr5
+	stdi		gr4,@(gr31,#REG_IACC0)
+
+	movsg		gner0,gr4
+	movsg		gner1,gr5
+	stdi		gr4,@(gr31,#REG_GNER0)
+
+	# build the debug register frame
+	movsg		brr,gr4
+	movgs		gr0,brr
+	movsg		nmar,gr5
+	movsg		dcr,gr6
+
+	stdi		gr4 ,@(gr31,#REG_BRR)
+	sti		gr19,@(gr31,#REG_BPSR)
+	sti.p		gr6 ,@(gr31,#REG_DCR)
+
+	# trap exceptions during break handling and disable h/w breakpoints/watchpoints
+	sethi		%hi(DCR_EBE),gr5
+	setlo.p		%lo(DCR_EBE),gr5
+	sethi		%hi(__entry_breaktrap_table),gr4
+	setlo		%lo(__entry_breaktrap_table),gr4
+	movgs		gr5,dcr
+	movgs		gr4,tbr
+
+	# set up kernel global registers
+	sethi.p		%hi(__kernel_current_task),gr5
+	setlo		%lo(__kernel_current_task),gr5
+	ld		@(gr5,gr0),gr29
+	ldi.p		@(gr29,#4),gr15		; __current_thread_info = current->thread_info
+
+	sethi		%hi(_gp),gr16
+	setlo.p		%lo(_gp),gr16
+
+	# make sure we (the kernel) get div-zero and misalignment exceptions
+	setlos		#ISR_EDE|ISR_DTT_DIVBYZERO|ISR_EMAM_EXCEPTION,gr5
+	movgs		gr5,isr
+
+	# enter the GDB stub
+	LEDS		0x4007,gr2
+
+	or.p		gr0,gr0,fp
+	call		debug_stub
+
+	LEDS		0x403f,gr2
+
+	# return from break
+	lddi		@(gr31,#REG_IACC0),gr4
+	movgs		gr4,iacc0h
+	movgs		gr5,iacc0l
+
+	lddi		@(gr31,#REG_GNER0),gr4
+	movgs		gr4,gner0
+	movgs		gr5,gner1
+
+	lddi		@(gr31,#REG_LR)  ,gr26
+	lddi		@(gr31,#REG_CCR) ,gr24
+	lddi		@(gr31,#REG_PSR) ,gr22
+	ldi		@(gr31,#REG_PC)  ,gr21
+	ldi		@(gr31,#REG_TBR) ,gr20
+	ldi.p		@(gr31,#REG_DCR) ,gr6
+
+	andi		gr22,#PSR_S,gr19		/* rebuild BPSR */
+	andi.p		gr22,#PSR_ET,gr5
+	slli		gr19,#10,gr19
+	or		gr5,gr19,gr19
+
+	movgs		gr6 ,dcr
+	movgs		gr19,bpsr
+	movgs		gr20,tbr
+	movgs		gr21,bpcsr
+	movgs		gr23,isr
+	movgs		gr24,ccr
+	movgs		gr25,cccr
+	movgs		gr26,lr
+	movgs		gr27,lcr
+
+	LEDS		0x407f,gr2
+
+#ifdef CONFIG_MMU
+	ldi		@(gr31,#REG_GR(31)),gr2
+	movgs		gr2,scr3
+#endif
+
+	ldi		@(gr31,#REG_GR(30)),gr30
+	ldi		@(gr31,#REG_GR(29)),gr29
+	lddi		@(gr31,#REG_GR(26)),gr26
+	lddi		@(gr31,#REG_GR(24)),gr24
+	lddi		@(gr31,#REG_GR(22)),gr22
+	lddi		@(gr31,#REG_GR(20)),gr20
+	lddi		@(gr31,#REG_GR(18)),gr18
+	lddi		@(gr31,#REG_GR(16)),gr16
+	lddi		@(gr31,#REG_GR(14)),gr14
+	lddi		@(gr31,#REG_GR(12)),gr12
+	lddi		@(gr31,#REG_GR(10)),gr10
+	lddi		@(gr31,#REG_GR(8)) ,gr8
+	lddi		@(gr31,#REG_GR(6)) ,gr6
+	lddi		@(gr31,#REG_GR(4)) ,gr4
+	lddi		@(gr31,#REG_GR(2)) ,gr2
+	ldi.p		@(gr31,#REG_SP)    ,sp
+
+	xor		gr31,gr31,gr31
+	movgs		gr0,brr
+#ifdef CONFIG_MMU
+	movsg		scr3,gr31
+#endif
+	rett		#1
+
+###################################################################################################
+#
+# GDB stub "system calls"
+#
+###################################################################################################
+
+#ifdef CONFIG_GDBSTUB
+	# void gdbstub_console_write(struct console *con, const char *p, unsigned n)
+	.globl		gdbstub_console_write
+gdbstub_console_write:
+	break
+	bralr
+#endif
+
+	# GDB stub BUG() trap
+	# GR8 is the proposed signal number
+	.globl		__debug_bug_trap
+__debug_bug_trap:
+	break
+	bralr
+
+	# transfer kernel exeception to GDB for handling
+	.globl		__break_hijack_kernel_event
+__break_hijack_kernel_event:
+	break
+	.globl		__break_hijack_kernel_event_breaks_here
+__break_hijack_kernel_event_breaks_here:
+	nop
+
+#ifdef CONFIG_MMU
+	# handle a return from TLB-miss that requires single-step reactivation
+	.globl		__break_tlb_miss_return_break
+__break_tlb_miss_return_break:
+	break
+__break_tlb_miss_return_breaks_here:
+	nop
+#endif
+
+	# guard the first .text label in the next file from confusion
+	nop
diff -Nru a/arch/frv/kernel/cmode.S b/arch/frv/kernel/cmode.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/kernel/cmode.S	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,190 @@
+/* cmode.S: clock mode management
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Woodhouse (dwmw2@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ */
+
+#include <linux/sys.h>
+#include <linux/config.h>
+#include <linux/linkage.h>
+#include <asm/setup.h>
+#include <asm/segment.h>
+#include <asm/ptrace.h>
+#include <asm/errno.h>
+#include <asm/cache.h>
+#include <asm/spr-regs.h>
+
+#define __addr_MASK	0xfeff9820	/* interrupt controller mask */
+
+#define __addr_SDRAMC	0xfe000400	/* SDRAM controller regs */
+#define SDRAMC_DSTS	0x28		/* SDRAM status */
+#define SDRAMC_DSTS_SSI	0x00000001	/* indicates that the SDRAM is in self-refresh mode */
+#define SDRAMC_DRCN	0x30		/* SDRAM refresh control */
+#define SDRAMC_DRCN_SR	0x00000001	/* transition SDRAM into self-refresh mode */
+#define __addr_CLKC	0xfeff9a00
+#define CLKC_SWCMODE	0x00000008
+#define __addr_LEDS	0xe1200004
+
+.macro li v r
+	sethi.p		%hi(\v),\r
+	setlo		%lo(\v),\r
+.endm
+
+	.text
+	.balign		4
+
+
+###############################################################################
+#
+# Change CMODE
+# - void frv_change_cmode(int cmode)
+#
+###############################################################################
+	.globl		frv_change_cmode
+        .type		frv_change_cmode,@function
+
+.macro	LEDS v
+#ifdef DEBUG_CMODE
+	setlos	#~\v,gr10
+	sti	gr10,@(gr11,#0)
+	membar
+#endif
+.endm
+
+frv_change_cmode:
+	movsg		lr,gr9
+#ifdef DEBUG_CMODE
+	li		__addr_LEDS,gr11
+#endif
+	dcef		@(gr0,gr0),#1
+
+	# Shift argument left by 24 bits to fit in SWCMODE register later.
+	slli		gr8,#24,gr8
+
+	# (1) Set '0' in the PSR.ET bit, and prohibit interrupts.
+	movsg		psr,gr14
+	andi		gr14,#~PSR_ET,gr3
+	movgs		gr3,psr
+
+#if 0 // Fujitsu recommend to skip this and will update docs.
+	# (2) Set '0' to all bits of the MASK register of the interrupt
+	#     controller, and mask interrupts.
+	li		__addr_MASK,gr12
+	ldi		@(gr12,#0),gr13
+	li		0xffff0000,gr4
+	sti		gr4,@(gr12,#0)
+#endif
+
+	# (3) Stop the transfer function of DMAC. Stop all the bus masters
+	#     to access SDRAM and the internal resources.
+
+	# (already done by caller)
+
+	# (4) Preload a series of following instructions to the instruction
+	#     cache.
+	li		#__cmode_icache_lock_start,gr3
+	li		#__cmode_icache_lock_end,gr4
+
+1:	icpl		gr3,gr0,#1
+	addi		gr3,#L1_CACHE_BYTES,gr3
+	cmp		gr4,gr3,icc0
+	bhi		icc0,#0,1b
+
+	# Set up addresses in regs for later steps.
+	setlos		SDRAMC_DRCN_SR,gr3
+	li		__addr_SDRAMC,gr4
+	li		__addr_CLKC,gr5
+	ldi		@(gr5,#0),gr6
+	li		#0x80000000,gr7
+	or		gr6,gr7,gr6
+
+	bra		__cmode_icache_lock_start
+
+	.balign	L1_CACHE_BYTES
+__cmode_icache_lock_start:
+
+	# (5) Flush the content of all caches by the DCEF instruction.
+	dcef		@(gr0,gr0),#1
+
+	# (6) Execute loading the dummy for SDRAM.
+	ldi		@(gr9,#0),gr0
+
+	# (7) Set '1' to the DRCN.SR bit, and change SDRAM to the
+	#     self-refresh mode. Execute the dummy load to all memory
+	#     devices set to cacheable on the external bus side in parallel
+	#     with this.
+	sti		gr3,@(gr4,#SDRAMC_DRCN)
+
+	# (8) Execute memory barrier instruction (MEMBAR).
+	membar
+
+	# (9) Read the DSTS register repeatedly until '1' stands in the
+	#     DSTS.SSI field.
+1:	ldi		@(gr4,#SDRAMC_DSTS),gr3
+	andicc		gr3,#SDRAMC_DSTS_SSI,gr3,icc0
+	beq		icc0,#0,1b
+
+	# (10) Execute memory barrier instruction (MEMBAR).
+	membar
+
+#if 1
+	# (11) Set the value of CMODE that you want to change to
+	#      SWCMODE.SWCM[3:0].
+	sti		gr8,@(gr5,#CLKC_SWCMODE)
+
+	# (12) Set '1' to the CLKC.SWEN bit. In that case, do not change
+	#      fields other than SWEN of the CLKC register.
+	sti		gr6,@(gr5,#0)
+#endif
+	# (13) Execute the instruction just after the memory barrier
+	# instruction that executes the self-loop 256 times. (Meanwhile,
+	# the CMODE switch is done.)
+	membar
+	setlos		#256,gr7
+2:	subicc		gr7,#1,gr7,icc0
+	bne		icc0,#2,2b
+
+	LEDS	0x36
+
+	# (14) Release the self-refresh of SDRAM.
+	sti		gr0,@(gr4,#SDRAMC_DRCN)
+
+	# Wait for it...
+3:	ldi		@(gr4,#SDRAMC_DSTS),gr3
+	andicc		gr3,#SDRAMC_DSTS_SSI,gr3,icc0
+	bne		icc0,#2,3b
+
+#if 0
+	li		0x0100000,gr10
+4:	subicc		gr10,#1,gr10,icc0
+
+	bne		icc0,#0,4b
+#endif
+
+__cmode_icache_lock_end:
+
+	li		#__cmode_icache_lock_start,gr3
+	li		#__cmode_icache_lock_end,gr4
+
+4:	icul		gr3
+	addi		gr3,#L1_CACHE_BYTES,gr3
+	cmp		gr4,gr3,icc0
+	bhi		icc0,#0,4b
+
+#if 0 // Fujitsu recommend to skip this and will update docs.
+	# (15) Release the interrupt mask setting of the MASK register of
+	# the interrupt controller if necessary.
+	sti		gr13,@(gr12,#0)
+#endif
+	# (16) Set  1' in the PSR.ET bit, and permit interrupt.
+	movgs		gr14,psr
+
+	bralr
+
+	.size		frv_change_cmode, .-frv_change_cmode
diff -Nru a/arch/frv/kernel/debug-stub.c b/arch/frv/kernel/debug-stub.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/kernel/debug-stub.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,259 @@
+/* debug-stub.c: debug-mode stub
+ *
+ * Copyright (C) 2004 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/string.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/serial_reg.h>
+
+#include <asm/system.h>
+#include <asm/serial-regs.h>
+#include <asm/timer-regs.h>
+#include <asm/irc-regs.h>
+#include <asm/gdb-stub.h>
+#include "gdb-io.h"
+
+/* CPU board CON5 */
+#define __UART0(X) (*(volatile uint8_t *)(UART0_BASE + (UART_##X)))
+
+#define LSR_WAIT_FOR0(STATE)			\
+do {						\
+} while (!(__UART0(LSR) & UART_LSR_##STATE))
+
+#define FLOWCTL_QUERY0(LINE)	({ __UART0(MSR) & UART_MSR_##LINE; })
+#define FLOWCTL_CLEAR0(LINE)	do { __UART0(MCR) &= ~UART_MCR_##LINE; } while (0)
+#define FLOWCTL_SET0(LINE)	do { __UART0(MCR) |= UART_MCR_##LINE; } while (0)
+
+#define FLOWCTL_WAIT_FOR0(LINE)			\
+do {						\
+	gdbstub_do_rx();			\
+} while(!FLOWCTL_QUERY(LINE))
+
+static void __init debug_stub_init(void);
+
+extern asmlinkage void __break_hijack_kernel_event(void);
+extern asmlinkage void __break_hijack_kernel_event_breaks_here(void);
+
+/*****************************************************************************/
+/*
+ * debug mode handler stub
+ * - we come here with the CPU in debug mode and with exceptions disabled
+ * - handle debugging services for userspace
+ */
+asmlinkage void debug_stub(void)
+{
+	unsigned long hsr0;
+	int type = 0;
+
+	static u8 inited = 0;
+	if (!inited) {
+		debug_stub_init();
+		type = -1;
+		inited = 1;
+	}
+
+	hsr0 = __get_HSR(0);
+	if (hsr0 & HSR0_ETMD)
+		__set_HSR(0, hsr0 & ~HSR0_ETMD);
+
+	/* disable single stepping */
+	__debug_regs->dcr &= ~DCR_SE;
+
+	/* kernel mode can propose an exception be handled in debug mode by jumping to a special
+	 * location */
+	if (__debug_frame->pc == (unsigned long) __break_hijack_kernel_event_breaks_here) {
+		/* replace the debug frame with the kernel frame and discard
+		 * the top kernel context */
+		*__debug_frame = *__frame;
+		__frame = __debug_frame->next_frame;
+		__debug_regs->brr = (__debug_frame->tbr & TBR_TT) << 12;
+		__debug_regs->brr |= BRR_EB;
+	}
+
+	if (__debug_frame->pc == (unsigned long) __debug_bug_trap + 4) {
+		__debug_frame->pc = __debug_frame->lr;
+		type = __debug_frame->gr8;
+	}
+
+#ifdef CONFIG_GDBSTUB
+	gdbstub(type);
+#endif
+
+	if (hsr0 & HSR0_ETMD)
+		__set_HSR(0, __get_HSR(0) | HSR0_ETMD);
+
+} /* end debug_stub() */
+
+/*****************************************************************************/
+/*
+ * debug stub initialisation
+ */
+static void __init debug_stub_init(void)
+{
+	__set_IRR(6, 0xff000000);	/* map ERRs to NMI */
+	__set_IITMR(1, 0x20000000);	/* ERR0/1, UART0/1 IRQ detect levels */
+
+	asm volatile("	movgs	gr0,ibar0	\n"
+		     "	movgs	gr0,ibar1	\n"
+		     "	movgs	gr0,ibar2	\n"
+		     "	movgs	gr0,ibar3	\n"
+		     "	movgs	gr0,dbar0	\n"
+		     "	movgs	gr0,dbmr00	\n"
+		     "	movgs	gr0,dbmr01	\n"
+		     "	movgs	gr0,dbdr00	\n"
+		     "	movgs	gr0,dbdr01	\n"
+		     "	movgs	gr0,dbar1	\n"
+		     "	movgs	gr0,dbmr10	\n"
+		     "	movgs	gr0,dbmr11	\n"
+		     "	movgs	gr0,dbdr10	\n"
+		     "	movgs	gr0,dbdr11	\n"
+		     );
+
+	/* deal with debugging stub initialisation and initial pause */
+	if (__debug_frame->pc == (unsigned long) __debug_stub_init_break)
+		__debug_frame->pc = (unsigned long) start_kernel;
+
+	/* enable the debug events we want to trap */
+	__debug_regs->dcr = DCR_EBE;
+
+#ifdef CONFIG_GDBSTUB
+	gdbstub_init();
+#endif
+
+	__clr_MASK_all();
+	__clr_MASK(15);
+	__clr_RC(15);
+
+} /* end debug_stub_init() */
+
+/*****************************************************************************/
+/*
+ * kernel "exit" trap for gdb stub
+ */
+void debug_stub_exit(int status)
+{
+
+#ifdef CONFIG_GDBSTUB
+	gdbstub_exit(status);
+#endif
+
+} /* end debug_stub_exit() */
+
+/*****************************************************************************/
+/*
+ * send string to serial port
+ */
+void debug_to_serial(const char *p, int n)
+{
+	char ch;
+
+	for (; n > 0; n--) {
+		ch = *p++;
+		FLOWCTL_SET0(DTR);
+		LSR_WAIT_FOR0(THRE);
+		// FLOWCTL_WAIT_FOR(CTS);
+
+		if (ch == 0x0a) {
+			__UART0(TX) = 0x0d;
+			mb();
+			LSR_WAIT_FOR0(THRE);
+			// FLOWCTL_WAIT_FOR(CTS);
+		}
+		__UART0(TX) = ch;
+		mb();
+
+		FLOWCTL_CLEAR0(DTR);
+	}
+
+} /* end debug_to_serial() */
+
+/*****************************************************************************/
+/*
+ * send string to serial port
+ */
+void debug_to_serial2(const char *fmt, ...)
+{
+	va_list va;
+	char buf[64];
+	int n;
+
+	va_start(va, fmt);
+	n = vsprintf(buf, fmt, va);
+	va_end(va);
+
+	debug_to_serial(buf, n);
+
+} /* end debug_to_serial2() */
+
+/*****************************************************************************/
+/*
+ * set up the ttyS0 serial port baud rate timers
+ */
+void __init console_set_baud(unsigned baud)
+{
+	unsigned value, high, low;
+	u8 lcr;
+
+	/* work out the divisor to give us the nearest higher baud rate */
+	value = __serial_clock_speed_HZ / 16 / baud;
+
+	/* determine the baud rate range */
+	high = __serial_clock_speed_HZ / 16 / value;
+	low = __serial_clock_speed_HZ / 16 / (value + 1);
+
+	/* pick the nearest bound */
+	if (low + (high - low) / 2 > baud)
+		value++;
+
+	lcr = __UART0(LCR);
+	__UART0(LCR) |= UART_LCR_DLAB;
+	mb();
+	__UART0(DLL) = value & 0xff;
+	__UART0(DLM) = (value >> 8) & 0xff;
+	mb();
+	__UART0(LCR) = lcr;
+	mb();
+
+} /* end console_set_baud() */
+
+/*****************************************************************************/
+/*
+ *
+ */
+int __init console_get_baud(void)
+{
+	unsigned value;
+	u8 lcr;
+
+	lcr = __UART0(LCR);
+	__UART0(LCR) |= UART_LCR_DLAB;
+	mb();
+	value =  __UART0(DLM) << 8;
+	value |= __UART0(DLL);
+	__UART0(LCR) = lcr;
+	mb();
+
+	return value;
+} /* end console_get_baud() */
+
+/*****************************************************************************/
+/*
+ * display BUG() info
+ */
+#ifndef CONFIG_NO_KERNEL_MSG
+void __debug_bug_printk(const char *file, unsigned line)
+{
+	printk("kernel BUG at %s:%d!\n", file, line);
+
+} /* end __debug_bug_printk() */
+#endif
diff -Nru a/arch/frv/kernel/dma.c b/arch/frv/kernel/dma.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/kernel/dma.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,464 @@
+/* dma.c: DMA controller management on FR401 and the like
+ *
+ * Copyright (C) 2004 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/spinlock.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <asm/dma.h>
+#include <asm/gpio-regs.h>
+#include <asm/irc-regs.h>
+#include <asm/cpu-irqs.h>
+
+struct frv_dma_channel {
+	uint8_t			flags;
+#define FRV_DMA_FLAGS_RESERVED	0x01
+#define FRV_DMA_FLAGS_INUSE	0x02
+#define FRV_DMA_FLAGS_PAUSED	0x04
+	uint8_t			cap;		/* capabilities available */
+	int			irq;		/* completion IRQ */
+	uint32_t		dreqbit;
+	uint32_t		dackbit;
+	uint32_t		donebit;
+	const unsigned long	ioaddr;		/* DMA controller regs addr */
+	const char		*devname;
+	dma_irq_handler_t	handler;
+	void			*data;
+};
+
+
+#define __get_DMAC(IO,X)	({ *(volatile unsigned long *)((IO) + DMAC_##X##x); })
+
+#define __set_DMAC(IO,X,V)					\
+do {								\
+	*(volatile unsigned long *)((IO) + DMAC_##X##x) = (V);	\
+	mb();							\
+} while(0)
+
+#define ___set_DMAC(IO,X,V)					\
+do {								\
+	*(volatile unsigned long *)((IO) + DMAC_##X##x) = (V);	\
+} while(0)
+
+
+static struct frv_dma_channel frv_dma_channels[FRV_DMA_NCHANS] = {
+	[0] = {
+		.cap		= FRV_DMA_CAP_DREQ | FRV_DMA_CAP_DACK | FRV_DMA_CAP_DONE,
+		.irq		= IRQ_CPU_DMA0,
+		.dreqbit	= SIR_DREQ0_INPUT,
+		.dackbit	= SOR_DACK0_OUTPUT,
+		.donebit	= SOR_DONE0_OUTPUT,
+		.ioaddr		= 0xfe000900,
+	},
+	[1] = {
+		.cap		= FRV_DMA_CAP_DREQ | FRV_DMA_CAP_DACK | FRV_DMA_CAP_DONE,
+		.irq		= IRQ_CPU_DMA1,
+		.dreqbit	= SIR_DREQ1_INPUT,
+		.dackbit	= SOR_DACK1_OUTPUT,
+		.donebit	= SOR_DONE1_OUTPUT,
+		.ioaddr		= 0xfe000980,
+	},
+	[2] = {
+		.cap		= FRV_DMA_CAP_DREQ | FRV_DMA_CAP_DACK,
+		.irq		= IRQ_CPU_DMA2,
+		.dreqbit	= SIR_DREQ2_INPUT,
+		.dackbit	= SOR_DACK2_OUTPUT,
+		.ioaddr		= 0xfe000a00,
+	},
+	[3] = {
+		.cap		= FRV_DMA_CAP_DREQ | FRV_DMA_CAP_DACK,
+		.irq		= IRQ_CPU_DMA3,
+		.dreqbit	= SIR_DREQ3_INPUT,
+		.dackbit	= SOR_DACK3_OUTPUT,
+		.ioaddr		= 0xfe000a80,
+	},
+	[4] = {
+		.cap		= FRV_DMA_CAP_DREQ,
+		.irq		= IRQ_CPU_DMA4,
+		.dreqbit	= SIR_DREQ4_INPUT,
+		.ioaddr		= 0xfe001000,
+	},
+	[5] = {
+		.cap		= FRV_DMA_CAP_DREQ,
+		.irq		= IRQ_CPU_DMA5,
+		.dreqbit	= SIR_DREQ5_INPUT,
+		.ioaddr		= 0xfe001080,
+	},
+	[6] = {
+		.cap		= FRV_DMA_CAP_DREQ,
+		.irq		= IRQ_CPU_DMA6,
+		.dreqbit	= SIR_DREQ6_INPUT,
+		.ioaddr		= 0xfe001100,
+	},
+	[7] = {
+		.cap		= FRV_DMA_CAP_DREQ,
+		.irq		= IRQ_CPU_DMA7,
+		.dreqbit	= SIR_DREQ7_INPUT,
+		.ioaddr		= 0xfe001180,
+	},
+};
+
+static DEFINE_RWLOCK(frv_dma_channels_lock);
+
+unsigned long frv_dma_inprogress;
+
+#define frv_clear_dma_inprogress(channel) \
+	atomic_clear_mask(1 << (channel), &frv_dma_inprogress);
+
+#define frv_set_dma_inprogress(channel) \
+	atomic_set_mask(1 << (channel), &frv_dma_inprogress);
+
+/*****************************************************************************/
+/*
+ * DMA irq handler - determine channel involved, grab status and call real handler
+ */
+static irqreturn_t dma_irq_handler(int irq, void *_channel, struct pt_regs *regs)
+{
+	struct frv_dma_channel *channel = _channel;
+
+	frv_clear_dma_inprogress(channel - frv_dma_channels);
+	return channel->handler(channel - frv_dma_channels,
+				__get_DMAC(channel->ioaddr, CSTR),
+				channel->data,
+				regs);
+
+} /* end dma_irq_handler() */
+
+/*****************************************************************************/
+/*
+ * Determine which DMA controllers are present on this CPU
+ */
+void __init frv_dma_init(void)
+{
+	unsigned long psr = __get_PSR();
+	int num_dma, i;
+
+	/* First, determine how many DMA channels are available */
+	switch (PSR_IMPLE(psr)) {
+	case PSR_IMPLE_FR405:
+	case PSR_IMPLE_FR451:
+	case PSR_IMPLE_FR501:
+	case PSR_IMPLE_FR551:
+		num_dma = FRV_DMA_8CHANS;
+		break;
+
+	case PSR_IMPLE_FR401:
+	default:
+		num_dma = FRV_DMA_4CHANS;
+		break;
+	}
+
+	/* Now mark all of the non-existent channels as reserved */
+	for(i = num_dma; i < FRV_DMA_NCHANS; i++)
+		frv_dma_channels[i].flags = FRV_DMA_FLAGS_RESERVED;
+
+} /* end frv_dma_init() */
+
+/*****************************************************************************/
+/*
+ * allocate a DMA controller channel and the IRQ associated with it
+ */
+int frv_dma_open(const char *devname,
+		 unsigned long dmamask,
+		 int dmacap,
+		 dma_irq_handler_t handler,
+		 unsigned long irq_flags,
+		 void *data)
+{
+	struct frv_dma_channel *channel;
+	int dma, ret;
+	uint32_t val;
+
+	write_lock(&frv_dma_channels_lock);
+
+	ret = -ENOSPC;
+
+	for (dma = FRV_DMA_NCHANS - 1; dma >= 0; dma--) {
+		channel = &frv_dma_channels[dma];
+
+		if (!test_bit(dma, &dmamask))
+			continue;
+
+		if ((channel->cap & dmacap) != dmacap)
+			continue;
+
+		if (!frv_dma_channels[dma].flags)
+			goto found;
+	}
+
+	goto out;
+
+ found:
+	ret = request_irq(channel->irq, dma_irq_handler, irq_flags, devname, channel);
+	if (ret < 0)
+		goto out;
+
+	/* okay, we've allocated all the resources */
+	channel = &frv_dma_channels[dma];
+
+	channel->flags		|= FRV_DMA_FLAGS_INUSE;
+	channel->devname	= devname;
+	channel->handler	= handler;
+	channel->data		= data;
+
+	/* Now make sure we are set up for DMA and not GPIO */
+	/* SIR bit must be set for DMA to work */
+	__set_SIR(channel->dreqbit | __get_SIR());
+	/* SOR bits depend on what the caller requests */
+	val = __get_SOR();
+	if(dmacap & FRV_DMA_CAP_DACK)
+		val |= channel->dackbit;
+	else
+		val &= ~channel->dackbit;
+	if(dmacap & FRV_DMA_CAP_DONE)
+		val |= channel->donebit;
+	else
+		val &= ~channel->donebit;
+	__set_SOR(val);
+
+	ret = dma;
+ out:
+	write_unlock(&frv_dma_channels_lock);
+	return ret;
+} /* end frv_dma_open() */
+
+EXPORT_SYMBOL(frv_dma_open);
+
+/*****************************************************************************/
+/*
+ * close a DMA channel and its associated interrupt
+ */
+void frv_dma_close(int dma)
+{
+	struct frv_dma_channel *channel = &frv_dma_channels[dma];
+	unsigned long flags;
+
+	write_lock_irqsave(&frv_dma_channels_lock, flags);
+
+	free_irq(channel->irq, channel);
+	frv_dma_stop(dma);
+
+	channel->flags &= ~FRV_DMA_FLAGS_INUSE;
+
+	write_unlock_irqrestore(&frv_dma_channels_lock, flags);
+} /* end frv_dma_close() */
+
+EXPORT_SYMBOL(frv_dma_close);
+
+/*****************************************************************************/
+/*
+ * set static configuration on a DMA channel
+ */
+void frv_dma_config(int dma, unsigned long ccfr, unsigned long cctr, unsigned long apr)
+{
+	unsigned long ioaddr = frv_dma_channels[dma].ioaddr;
+
+	___set_DMAC(ioaddr, CCFR, ccfr);
+	___set_DMAC(ioaddr, CCTR, cctr);
+	___set_DMAC(ioaddr, APR,  apr);
+	mb();
+
+} /* end frv_dma_config() */
+
+EXPORT_SYMBOL(frv_dma_config);
+
+/*****************************************************************************/
+/*
+ * start a DMA channel
+ */
+void frv_dma_start(int dma,
+		   unsigned long sba, unsigned long dba,
+		   unsigned long pix, unsigned long six, unsigned long bcl)
+{
+	unsigned long ioaddr = frv_dma_channels[dma].ioaddr;
+
+	___set_DMAC(ioaddr, SBA,  sba);
+	___set_DMAC(ioaddr, DBA,  dba);
+	___set_DMAC(ioaddr, PIX,  pix);
+	___set_DMAC(ioaddr, SIX,  six);
+	___set_DMAC(ioaddr, BCL,  bcl);
+	___set_DMAC(ioaddr, CSTR, 0);
+	mb();
+
+	__set_DMAC(ioaddr, CCTR, __get_DMAC(ioaddr, CCTR) | DMAC_CCTRx_ACT);
+	frv_set_dma_inprogress(dma);
+
+} /* end frv_dma_start() */
+
+EXPORT_SYMBOL(frv_dma_start);
+
+/*****************************************************************************/
+/*
+ * restart a DMA channel that's been stopped in circular addressing mode by comparison-end
+ */
+void frv_dma_restart_circular(int dma, unsigned long six)
+{
+	unsigned long ioaddr = frv_dma_channels[dma].ioaddr;
+
+	___set_DMAC(ioaddr, SIX,  six);
+	___set_DMAC(ioaddr, CSTR, __get_DMAC(ioaddr, CSTR) & ~DMAC_CSTRx_CE);
+	mb();
+
+	__set_DMAC(ioaddr, CCTR, __get_DMAC(ioaddr, CCTR) | DMAC_CCTRx_ACT);
+	frv_set_dma_inprogress(dma);
+
+} /* end frv_dma_restart_circular() */
+
+EXPORT_SYMBOL(frv_dma_restart_circular);
+
+/*****************************************************************************/
+/*
+ * stop a DMA channel
+ */
+void frv_dma_stop(int dma)
+{
+	unsigned long ioaddr = frv_dma_channels[dma].ioaddr;
+	uint32_t cctr;
+
+	___set_DMAC(ioaddr, CSTR, 0);
+	cctr = __get_DMAC(ioaddr, CCTR);
+	cctr &= ~(DMAC_CCTRx_IE | DMAC_CCTRx_ACT);
+	cctr |= DMAC_CCTRx_FC; 	/* fifo clear */
+	__set_DMAC(ioaddr, CCTR, cctr);
+	__set_DMAC(ioaddr, BCL,  0);
+	frv_clear_dma_inprogress(dma);
+} /* end frv_dma_stop() */
+
+EXPORT_SYMBOL(frv_dma_stop);
+
+/*****************************************************************************/
+/*
+ * test interrupt status of DMA channel
+ */
+int is_frv_dma_interrupting(int dma)
+{
+	unsigned long ioaddr = frv_dma_channels[dma].ioaddr;
+
+	return __get_DMAC(ioaddr, CSTR) & (1 << 23);
+
+} /* end is_frv_dma_interrupting() */
+
+EXPORT_SYMBOL(is_frv_dma_interrupting);
+
+/*****************************************************************************/
+/*
+ * dump data about a DMA channel
+ */
+void frv_dma_dump(int dma)
+{
+	unsigned long ioaddr = frv_dma_channels[dma].ioaddr;
+	unsigned long cstr, pix, six, bcl;
+
+	cstr = __get_DMAC(ioaddr, CSTR);
+	pix  = __get_DMAC(ioaddr, PIX);
+	six  = __get_DMAC(ioaddr, SIX);
+	bcl  = __get_DMAC(ioaddr, BCL);
+
+	printk("DMA[%d] cstr=%lx pix=%lx six=%lx bcl=%lx\n", dma, cstr, pix, six, bcl);
+
+} /* end frv_dma_dump() */
+
+EXPORT_SYMBOL(frv_dma_dump);
+
+/*****************************************************************************/
+/*
+ * pause all DMA controllers
+ * - called by clock mangling routines
+ * - caller must be holding interrupts disabled
+ */
+void frv_dma_pause_all(void)
+{
+	struct frv_dma_channel *channel;
+	unsigned long ioaddr;
+	unsigned long cstr, cctr;
+	int dma;
+
+	write_lock(&frv_dma_channels_lock);
+
+	for (dma = FRV_DMA_NCHANS - 1; dma >= 0; dma--) {
+		channel = &frv_dma_channels[dma];
+
+		if (!(channel->flags & FRV_DMA_FLAGS_INUSE))
+			continue;
+
+		ioaddr = channel->ioaddr;
+		cctr = __get_DMAC(ioaddr, CCTR);
+		if (cctr & DMAC_CCTRx_ACT) {
+			cctr &= ~DMAC_CCTRx_ACT;
+			__set_DMAC(ioaddr, CCTR, cctr);
+
+			do {
+				cstr = __get_DMAC(ioaddr, CSTR);
+			} while (cstr & DMAC_CSTRx_BUSY);
+
+			if (cstr & DMAC_CSTRx_FED)
+				channel->flags |= FRV_DMA_FLAGS_PAUSED;
+			frv_clear_dma_inprogress(dma);
+		}
+	}
+
+} /* end frv_dma_pause_all() */
+
+EXPORT_SYMBOL(frv_dma_pause_all);
+
+/*****************************************************************************/
+/*
+ * resume paused DMA controllers
+ * - called by clock mangling routines
+ * - caller must be holding interrupts disabled
+ */
+void frv_dma_resume_all(void)
+{
+	struct frv_dma_channel *channel;
+	unsigned long ioaddr;
+	unsigned long cstr, cctr;
+	int dma;
+
+	for (dma = FRV_DMA_NCHANS - 1; dma >= 0; dma--) {
+		channel = &frv_dma_channels[dma];
+
+		if (!(channel->flags & FRV_DMA_FLAGS_PAUSED))
+			continue;
+
+		ioaddr = channel->ioaddr;
+		cstr = __get_DMAC(ioaddr, CSTR);
+		cstr &= ~(DMAC_CSTRx_FED | DMAC_CSTRx_INT);
+		__set_DMAC(ioaddr, CSTR, cstr);
+
+		cctr = __get_DMAC(ioaddr, CCTR);
+		cctr |= DMAC_CCTRx_ACT;
+		__set_DMAC(ioaddr, CCTR, cctr);
+
+		channel->flags &= ~FRV_DMA_FLAGS_PAUSED;
+		frv_set_dma_inprogress(dma);
+	}
+
+	write_unlock(&frv_dma_channels_lock);
+
+} /* end frv_dma_resume_all() */
+
+EXPORT_SYMBOL(frv_dma_resume_all);
+
+/*****************************************************************************/
+/*
+ * dma status clear
+ */
+void frv_dma_status_clear(int dma)
+{
+	unsigned long ioaddr = frv_dma_channels[dma].ioaddr;
+	uint32_t cctr;
+	___set_DMAC(ioaddr, CSTR, 0);
+
+	cctr = __get_DMAC(ioaddr, CCTR);
+} /* end frv_dma_status_clear() */
+
+EXPORT_SYMBOL(frv_dma_status_clear);
diff -Nru a/arch/frv/kernel/entry-table.S b/arch/frv/kernel/entry-table.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/kernel/entry-table.S	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,295 @@
+/* entry-table.S: main trap vector tables and exception jump table
+ *
+ * Copyright (C) 2003 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/sys.h>
+#include <linux/config.h>
+#include <linux/linkage.h>
+#include <asm/spr-regs.h>
+
+###############################################################################
+#
+# Declare the main trap and vector tables
+#
+# There are six tables:
+#
+# (1) The trap table for debug mode
+# (2) The trap table for kernel mode
+# (3) The trap table for user mode
+#
+#     The CPU jumps to an appropriate slot in the appropriate table to perform
+#     exception processing. We have three different tables for the three
+#     different CPU modes because there is no hardware differentiation between
+#     stack pointers for these three modes, and so we have to invent one when
+#     crossing mode boundaries.
+#
+# (4) The exception handler vector table
+#
+#     The user and kernel trap tables use the same prologue for normal
+#     exception processing. The prologue then jumps to the handler in this
+#     table, as indexed by the exception ID from the TBR.
+#
+# (5) The fixup table for kernel-trap single-step
+# (6) The fixup table for user-trap single-step
+#
+#     Due to the way single-stepping works on this CPU (single-step is not
+#     disabled when crossing exception boundaries, only when in debug mode),
+#     we have to catch the single-step event in break.S and jump to the fixup
+#     routine pointed to by this table.
+#
+# The linker script places the user mode and kernel mode trap tables on to
+# the same 8Kb page, so that break.S can be more efficient when performing
+# single-step bypass management
+#
+###############################################################################
+
+	# trap table for entry from debug mode
+	.section	.trap.break,"ax"
+	.balign		256*16
+	.globl		__entry_breaktrap_table
+__entry_breaktrap_table:
+
+	# trap table for entry from user mode
+	.section	.trap.user,"ax"
+	.balign		256*16
+	.globl		__entry_usertrap_table
+__entry_usertrap_table:
+
+	# trap table for entry from kernel mode
+	.section	.trap.kernel,"ax"
+	.balign		256*16
+	.globl		__entry_kerneltrap_table
+__entry_kerneltrap_table:
+
+	# exception handler jump table
+	.section	.trap.vector,"ax"
+	.balign		256*4
+	.globl		__entry_vector_table
+__entry_vector_table:
+
+	# trap fixup table for single-stepping in user mode
+	.section	.trap.fixup.user,"a"
+	.balign		256*4
+	.globl		__break_usertrap_fixup_table
+__break_usertrap_fixup_table:
+
+	# trap fixup table for single-stepping in user mode
+	.section	.trap.fixup.kernel,"a"
+	.balign		256*4
+	.globl		__break_kerneltrap_fixup_table
+__break_kerneltrap_fixup_table:
+
+	# handler declaration for a sofware or program interrupt
+.macro VECTOR_SOFTPROG tbr_tt, vec
+	.section .trap.user
+	.org		\tbr_tt
+	bra		__entry_uspace_softprog_interrupt
+	.section .trap.fixup.user
+	.org		\tbr_tt >> 2
+	.long		__break_step_uspace_softprog_interrupt
+	.section .trap.kernel
+	.org		\tbr_tt
+	bra		__entry_kernel_softprog_interrupt
+	.section .trap.fixup.kernel
+	.org		\tbr_tt >> 2
+	.long		__break_step_kernel_softprog_interrupt
+	.section .trap.vector
+	.org		\tbr_tt >> 2
+	.long		\vec
+.endm
+
+	# handler declaration for a maskable external interrupt
+.macro VECTOR_IRQ tbr_tt, vec
+	.section .trap.user
+	.org		\tbr_tt
+	bra		__entry_uspace_external_interrupt
+	.section .trap.fixup.user
+	.org		\tbr_tt >> 2
+	.long		__break_step_uspace_external_interrupt
+	.section .trap.kernel
+	.org		\tbr_tt
+	bra		__entry_kernel_external_interrupt
+	.section .trap.fixup.kernel
+	.org		\tbr_tt >> 2
+	.long		__break_step_kernel_external_interrupt
+	.section .trap.vector
+	.org		\tbr_tt >> 2
+	.long		\vec
+.endm
+
+	# handler declaration for an NMI external interrupt
+.macro VECTOR_NMI tbr_tt, vec
+	.section .trap.user
+	.org		\tbr_tt
+	break
+	break
+	break
+	break
+	.section .trap.kernel
+	.org		\tbr_tt
+	break
+	break
+	break
+	break
+	.section .trap.vector
+	.org		\tbr_tt >> 2
+	.long		\vec
+.endm
+
+	# handler declaration for an MMU only sofware or program interrupt
+.macro VECTOR_SP_MMU tbr_tt, vec
+#ifdef CONFIG_MMU
+ 	VECTOR_SOFTPROG	\tbr_tt, \vec
+#else
+	VECTOR_NMI	\tbr_tt, 0
+#endif
+.endm
+
+
+###############################################################################
+#
+# specification of the vectors
+# - note: each macro inserts code into multiple sections
+#
+###############################################################################
+	VECTOR_SP_MMU	TBR_TT_INSTR_MMU_MISS,	__entry_insn_mmu_miss
+	VECTOR_SOFTPROG	TBR_TT_INSTR_ACC_ERROR,	__entry_insn_access_error
+	VECTOR_SOFTPROG	TBR_TT_INSTR_ACC_EXCEP,	__entry_insn_access_exception
+	VECTOR_SOFTPROG	TBR_TT_PRIV_INSTR,	__entry_privileged_instruction
+	VECTOR_SOFTPROG	TBR_TT_ILLEGAL_INSTR,	__entry_illegal_instruction
+	VECTOR_SOFTPROG	TBR_TT_FP_EXCEPTION,	__entry_media_exception
+	VECTOR_SOFTPROG	TBR_TT_MP_EXCEPTION,	__entry_media_exception
+	VECTOR_SOFTPROG	TBR_TT_DATA_ACC_ERROR,	__entry_data_access_error
+	VECTOR_SP_MMU	TBR_TT_DATA_MMU_MISS,	__entry_data_mmu_miss
+	VECTOR_SOFTPROG	TBR_TT_DATA_ACC_EXCEP,	__entry_data_access_exception
+	VECTOR_SOFTPROG	TBR_TT_DATA_STR_ERROR,	__entry_data_store_error
+	VECTOR_SOFTPROG	TBR_TT_DIVISION_EXCEP,	__entry_division_exception
+
+#ifdef CONFIG_MMU
+	.section .trap.user
+	.org		TBR_TT_INSTR_TLB_MISS
+	.globl		__trap_user_insn_tlb_miss
+__trap_user_insn_tlb_miss:
+	movsg		ear0,gr28			/* faulting address */
+	movsg		scr0,gr31			/* get mapped PTD coverage start address */
+	xor.p		gr28,gr31,gr31			/* compare addresses */
+	bra		__entry_user_insn_tlb_miss
+
+	.org		TBR_TT_DATA_TLB_MISS
+	.globl		__trap_user_data_tlb_miss
+__trap_user_data_tlb_miss:
+	movsg		ear0,gr28			/* faulting address */
+	movsg		scr1,gr31			/* get mapped PTD coverage start address */
+	xor.p		gr28,gr31,gr31			/* compare addresses */
+	bra		__entry_user_data_tlb_miss
+
+	.section .trap.kernel
+	.org		TBR_TT_INSTR_TLB_MISS
+	.globl		__trap_kernel_insn_tlb_miss
+__trap_kernel_insn_tlb_miss:
+	movsg		ear0,gr29			/* faulting address */
+	movsg		scr0,gr31			/* get mapped PTD coverage start address */
+	xor.p		gr29,gr31,gr31			/* compare addresses */
+	bra		__entry_kernel_insn_tlb_miss
+
+	.org		TBR_TT_DATA_TLB_MISS
+	.globl		__trap_kernel_data_tlb_miss
+__trap_kernel_data_tlb_miss:
+	movsg		ear0,gr29			/* faulting address */
+	movsg		scr1,gr31			/* get mapped PTD coverage start address */
+	xor.p		gr29,gr31,gr31			/* compare addresses */
+	bra		__entry_kernel_data_tlb_miss
+
+	.section .trap.fixup.user
+	.org		TBR_TT_INSTR_TLB_MISS >> 2
+	.globl		__trap_fixup_user_insn_tlb_miss
+__trap_fixup_user_insn_tlb_miss:
+	.long		__break_user_insn_tlb_miss
+	.org		TBR_TT_DATA_TLB_MISS >> 2
+	.globl		__trap_fixup_user_data_tlb_miss
+__trap_fixup_user_data_tlb_miss:
+	.long		__break_user_data_tlb_miss
+
+	.section .trap.fixup.kernel
+	.org		TBR_TT_INSTR_TLB_MISS >> 2
+	.globl		__trap_fixup_kernel_insn_tlb_miss
+__trap_fixup_kernel_insn_tlb_miss:
+	.long		__break_kernel_insn_tlb_miss
+	.org		TBR_TT_DATA_TLB_MISS >> 2
+	.globl		__trap_fixup_kernel_data_tlb_miss
+__trap_fixup_kernel_data_tlb_miss:
+	.long		__break_kernel_data_tlb_miss
+
+	.section .trap.vector
+	.org		TBR_TT_INSTR_TLB_MISS >> 2
+	.long		__entry_insn_mmu_fault
+	.org		TBR_TT_DATA_TLB_MISS >> 2
+	.long		__entry_data_mmu_fault
+#endif
+
+	VECTOR_SP_MMU	TBR_TT_DATA_DAT_EXCEP,	__entry_data_dat_fault
+	VECTOR_NMI	TBR_TT_DECREMENT_TIMER,	__entry_do_NMI
+	VECTOR_SOFTPROG	TBR_TT_COMPOUND_EXCEP,	__entry_compound_exception
+	VECTOR_IRQ	TBR_TT_INTERRUPT_1,	__entry_do_IRQ
+	VECTOR_IRQ	TBR_TT_INTERRUPT_2,	__entry_do_IRQ
+	VECTOR_IRQ	TBR_TT_INTERRUPT_3,	__entry_do_IRQ
+	VECTOR_IRQ	TBR_TT_INTERRUPT_4,	__entry_do_IRQ
+	VECTOR_IRQ	TBR_TT_INTERRUPT_5,	__entry_do_IRQ
+	VECTOR_IRQ	TBR_TT_INTERRUPT_6,	__entry_do_IRQ
+	VECTOR_IRQ	TBR_TT_INTERRUPT_7,	__entry_do_IRQ
+	VECTOR_IRQ	TBR_TT_INTERRUPT_8,	__entry_do_IRQ
+	VECTOR_IRQ	TBR_TT_INTERRUPT_9,	__entry_do_IRQ
+	VECTOR_IRQ	TBR_TT_INTERRUPT_10,	__entry_do_IRQ
+	VECTOR_IRQ	TBR_TT_INTERRUPT_11,	__entry_do_IRQ
+	VECTOR_IRQ	TBR_TT_INTERRUPT_12,	__entry_do_IRQ
+	VECTOR_IRQ	TBR_TT_INTERRUPT_13,	__entry_do_IRQ
+	VECTOR_IRQ	TBR_TT_INTERRUPT_14,	__entry_do_IRQ
+	VECTOR_NMI	TBR_TT_INTERRUPT_15,	__entry_do_NMI
+
+	# miscellaneous user mode entry points
+	.section	.trap.user
+	.org		TBR_TT_TRAP0
+	.rept		127
+	bra		__entry_uspace_softprog_interrupt
+	bra		__break_step_uspace_softprog_interrupt
+	.long		0,0
+	.endr
+	.org		TBR_TT_BREAK
+	bra		__entry_break
+	.long		0,0,0
+
+	# miscellaneous kernel mode entry points
+	.section	.trap.kernel
+	.org		TBR_TT_TRAP0
+	.rept		127
+	bra		__entry_kernel_softprog_interrupt
+	bra		__break_step_kernel_softprog_interrupt
+	.long		0,0
+	.endr
+	.org		TBR_TT_BREAK
+	bra		__entry_break
+	.long		0,0,0
+
+	# miscellaneous debug mode entry points
+	.section	.trap.break
+	.org		TBR_TT_BREAK
+	movsg		bpcsr,gr30
+	jmpl		@(gr30,gr0)
+
+	# miscellaneous vectors
+	.section	.trap.vector
+	.org		TBR_TT_TRAP0 >> 2
+	.long		system_call
+	.rept		126
+	.long		__entry_unsupported_trap
+	.endr
+	.org		TBR_TT_BREAK >> 2
+	.long		__entry_debug_exception
diff -Nru a/arch/frv/kernel/entry.S b/arch/frv/kernel/entry.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/kernel/entry.S	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,1428 @@
+/* entry.S: FR-V entry
+ *
+ * Copyright (C) 2003 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.
+ *
+ *
+ * Entry to the kernel is "interesting":
+ *  (1) There are no stack pointers, not even for the kernel
+ *  (2) General Registers should not be clobbered
+ *  (3) There are no kernel-only data registers
+ *  (4) Since all addressing modes are wrt to a General Register, no global
+ *      variables can be reached
+ *
+ * We deal with this by declaring that we shall kill GR28 on entering the
+ * kernel from userspace
+ *
+ * However, since break interrupts can interrupt the CPU even when PSR.ET==0,
+ * they can't rely on GR28 to be anything useful, and so need to clobber a
+ * separate register (GR31). Break interrupts are managed in break.S
+ *
+ * GR29 _is_ saved, and holds the current task pointer globally
+ *
+ */
+
+#include <linux/sys.h>
+#include <linux/config.h>
+#include <linux/linkage.h>
+#include <asm/thread_info.h>
+#include <asm/setup.h>
+#include <asm/segment.h>
+#include <asm/ptrace.h>
+#include <asm/errno.h>
+#include <asm/cache.h>
+#include <asm/spr-regs.h>
+
+#define nr_syscalls ((syscall_table_size)/4)
+
+	.text
+	.balign		4
+
+.macro LEDS val
+#	sethi.p		%hi(0xe1200004),gr30
+#	setlo		%lo(0xe1200004),gr30
+#	setlos		#~\val,gr31
+#	st		gr31,@(gr30,gr0)
+#	sethi.p		%hi(0xffc00100),gr30
+#	setlo		%lo(0xffc00100),gr30
+#	sth		gr0,@(gr30,gr0)
+#	membar
+.endm
+
+.macro LEDS32
+#	not		gr31,gr31
+#	sethi.p		%hi(0xe1200004),gr30
+#	setlo		%lo(0xe1200004),gr30
+#	st.p		gr31,@(gr30,gr0)
+#	srli		gr31,#16,gr31
+#	sethi.p		%hi(0xffc00100),gr30
+#	setlo		%lo(0xffc00100),gr30
+#	sth		gr31,@(gr30,gr0)
+#	membar
+.endm
+
+###############################################################################
+#
+# entry point for External interrupts received whilst executing userspace code
+#
+###############################################################################
+	.globl		__entry_uspace_external_interrupt
+        .type		__entry_uspace_external_interrupt,@function
+__entry_uspace_external_interrupt:
+	LEDS		0x6200
+	sethi.p		%hi(__kernel_frame0_ptr),gr28
+	setlo		%lo(__kernel_frame0_ptr),gr28
+	ldi		@(gr28,#0),gr28
+
+	# handle h/w single-step through exceptions
+	sti		gr0,@(gr28,#REG__STATUS)
+
+	.globl		__entry_uspace_external_interrupt_reentry
+__entry_uspace_external_interrupt_reentry:
+	LEDS		0x6201
+
+	setlos		#REG__END,gr30
+	dcpl		gr28,gr30,#0
+
+	# finish building the exception frame
+	sti		sp,  @(gr28,#REG_SP)
+	stdi		gr2, @(gr28,#REG_GR(2))
+	stdi		gr4, @(gr28,#REG_GR(4))
+	stdi		gr6, @(gr28,#REG_GR(6))
+	stdi		gr8, @(gr28,#REG_GR(8))
+	stdi		gr10,@(gr28,#REG_GR(10))
+	stdi		gr12,@(gr28,#REG_GR(12))
+	stdi		gr14,@(gr28,#REG_GR(14))
+	stdi		gr16,@(gr28,#REG_GR(16))
+	stdi		gr18,@(gr28,#REG_GR(18))
+	stdi		gr20,@(gr28,#REG_GR(20))
+	stdi		gr22,@(gr28,#REG_GR(22))
+	stdi		gr24,@(gr28,#REG_GR(24))
+	stdi		gr26,@(gr28,#REG_GR(26))
+	sti		gr0, @(gr28,#REG_GR(28))
+	sti		gr29,@(gr28,#REG_GR(29))
+	stdi.p		gr30,@(gr28,#REG_GR(30))
+
+	# set up the kernel stack pointer
+	ori		gr28,0,sp
+
+	movsg		tbr ,gr20
+	movsg		psr ,gr22
+	movsg		pcsr,gr21
+	movsg		isr ,gr23
+	movsg		ccr ,gr24
+	movsg		cccr,gr25
+	movsg		lr  ,gr26
+	movsg		lcr ,gr27
+
+	setlos.p	#-1,gr4
+	andi		gr22,#PSR_PS,gr5		/* try to rebuild original PSR value */
+	andi.p		gr22,#~(PSR_PS|PSR_S),gr6
+	slli		gr5,#1,gr5
+	or		gr6,gr5,gr5
+	andi		gr5,#~PSR_ET,gr5
+
+	sti		gr20,@(gr28,#REG_TBR)
+	sti		gr21,@(gr28,#REG_PC)
+	sti		gr5 ,@(gr28,#REG_PSR)
+	sti		gr23,@(gr28,#REG_ISR)
+	stdi		gr24,@(gr28,#REG_CCR)
+	stdi		gr26,@(gr28,#REG_LR)
+	sti		gr4 ,@(gr28,#REG_SYSCALLNO)
+
+	movsg		iacc0h,gr4
+	movsg		iacc0l,gr5
+	stdi		gr4,@(gr28,#REG_IACC0)
+
+	movsg		gner0,gr4
+	movsg		gner1,gr5
+	stdi		gr4,@(gr28,#REG_GNER0)
+
+	# set up kernel global registers
+	sethi.p		%hi(__kernel_current_task),gr5
+	setlo		%lo(__kernel_current_task),gr5
+	sethi.p		%hi(_gp),gr16
+	setlo		%lo(_gp),gr16
+	ldi		@(gr5,#0),gr29
+	ldi.p		@(gr29,#4),gr15		; __current_thread_info = current->thread_info
+
+	# make sure we (the kernel) get div-zero and misalignment exceptions
+	setlos		#ISR_EDE|ISR_DTT_DIVBYZERO|ISR_EMAM_EXCEPTION,gr5
+	movgs		gr5,isr
+
+	# switch to the kernel trap table
+	sethi.p		%hi(__entry_kerneltrap_table),gr6
+	setlo		%lo(__entry_kerneltrap_table),gr6
+	movgs		gr6,tbr
+
+	# set the return address
+	sethi.p		%hi(__entry_return_from_user_interrupt),gr4
+	setlo		%lo(__entry_return_from_user_interrupt),gr4
+	movgs		gr4,lr
+
+	# raise the minimum interrupt priority to 15 (NMI only) and enable exceptions
+	movsg		psr,gr4
+
+	ori		gr4,#PSR_PIL_14,gr4
+	movgs		gr4,psr
+	ori		gr4,#PSR_PIL_14|PSR_ET,gr4
+	movgs		gr4,psr
+
+	LEDS		0x6202
+	bra		do_IRQ
+
+	.size		__entry_uspace_external_interrupt,.-__entry_uspace_external_interrupt
+
+###############################################################################
+#
+# entry point for External interrupts received whilst executing kernel code
+# - on arriving here, the following registers should already be set up:
+#	GR15	- current thread_info struct pointer
+#	GR16	- kernel GP-REL pointer
+#	GR29	- current task struct pointer
+#	TBR	- kernel trap vector table
+#	ISR	- kernel's preferred integer controls
+#
+###############################################################################
+	.globl		__entry_kernel_external_interrupt
+        .type		__entry_kernel_external_interrupt,@function
+__entry_kernel_external_interrupt:
+	LEDS		0x6210
+
+	sub		sp,gr15,gr31
+	LEDS32
+
+	# set up the stack pointer
+	or.p		sp,gr0,gr30
+	subi		sp,#REG__END,sp
+	sti		gr30,@(sp,#REG_SP)
+
+	# handle h/w single-step through exceptions
+	sti		gr0,@(sp,#REG__STATUS)
+
+	.globl		__entry_kernel_external_interrupt_reentry
+__entry_kernel_external_interrupt_reentry:
+	LEDS		0x6211
+
+	# set up the exception frame
+	setlos		#REG__END,gr30
+	dcpl		sp,gr30,#0
+
+	sti.p		gr28,@(sp,#REG_GR(28))
+	ori		sp,0,gr28
+
+	# finish building the exception frame
+	stdi		gr2,@(gr28,#REG_GR(2))
+	stdi		gr4,@(gr28,#REG_GR(4))
+	stdi		gr6,@(gr28,#REG_GR(6))
+	stdi		gr8,@(gr28,#REG_GR(8))
+	stdi		gr10,@(gr28,#REG_GR(10))
+	stdi		gr12,@(gr28,#REG_GR(12))
+	stdi		gr14,@(gr28,#REG_GR(14))
+	stdi		gr16,@(gr28,#REG_GR(16))
+	stdi		gr18,@(gr28,#REG_GR(18))
+	stdi		gr20,@(gr28,#REG_GR(20))
+	stdi		gr22,@(gr28,#REG_GR(22))
+	stdi		gr24,@(gr28,#REG_GR(24))
+	stdi		gr26,@(gr28,#REG_GR(26))
+	sti		gr29,@(gr28,#REG_GR(29))
+	stdi		gr30,@(gr28,#REG_GR(30))
+
+	movsg		tbr ,gr20
+	movsg		psr ,gr22
+	movsg		pcsr,gr21
+	movsg		isr ,gr23
+	movsg		ccr ,gr24
+	movsg		cccr,gr25
+	movsg		lr  ,gr26
+	movsg		lcr ,gr27
+
+	setlos.p	#-1,gr4
+	andi		gr22,#PSR_PS,gr5		/* try to rebuild original PSR value */
+	andi.p		gr22,#~(PSR_PS|PSR_S),gr6
+	slli		gr5,#1,gr5
+	or		gr6,gr5,gr5
+	andi.p		gr5,#~PSR_ET,gr5
+
+	# set CCCR.CC3 to Undefined to abort atomic-modify completion inside the kernel
+	# - for an explanation of how it works, see: Documentation/fujitsu/frv/atomic-ops.txt
+	andi		gr25,#~0xc0,gr25
+
+	sti		gr20,@(gr28,#REG_TBR)
+	sti		gr21,@(gr28,#REG_PC)
+	sti		gr5 ,@(gr28,#REG_PSR)
+	sti		gr23,@(gr28,#REG_ISR)
+	stdi		gr24,@(gr28,#REG_CCR)
+	stdi		gr26,@(gr28,#REG_LR)
+	sti		gr4 ,@(gr28,#REG_SYSCALLNO)
+
+	movsg		iacc0h,gr4
+	movsg		iacc0l,gr5
+	stdi		gr4,@(gr28,#REG_IACC0)
+
+	movsg		gner0,gr4
+	movsg		gner1,gr5
+	stdi		gr4,@(gr28,#REG_GNER0)
+
+	# set the return address
+	sethi.p		%hi(__entry_return_from_kernel_interrupt),gr4
+	setlo		%lo(__entry_return_from_kernel_interrupt),gr4
+	movgs		gr4,lr
+
+	# clear power-saving mode flags
+	movsg		hsr0,gr4
+	andi		gr4,#~HSR0_PDM,gr4
+	movgs		gr4,hsr0
+
+	# raise the minimum interrupt priority to 15 (NMI only) and enable exceptions
+	movsg		psr,gr4
+	ori		gr4,#PSR_PIL_14,gr4
+	movgs		gr4,psr
+	ori		gr4,#PSR_ET,gr4
+	movgs		gr4,psr
+
+	LEDS		0x6212
+	bra		do_IRQ
+
+	.size		__entry_kernel_external_interrupt,.-__entry_kernel_external_interrupt
+
+
+###############################################################################
+#
+# entry point for Software and Progam interrupts generated whilst executing userspace code
+#
+###############################################################################
+	.globl		__entry_uspace_softprog_interrupt
+        .type		__entry_uspace_softprog_interrupt,@function
+	.globl		__entry_uspace_handle_mmu_fault
+__entry_uspace_softprog_interrupt:
+	LEDS		0x6000
+#ifdef CONFIG_MMU
+	movsg		ear0,gr28
+__entry_uspace_handle_mmu_fault:
+	movgs		gr28,scr2
+#endif
+	sethi.p		%hi(__kernel_frame0_ptr),gr28
+	setlo		%lo(__kernel_frame0_ptr),gr28
+	ldi		@(gr28,#0),gr28
+
+	# handle h/w single-step through exceptions
+	sti		gr0,@(gr28,#REG__STATUS)
+
+	.globl		__entry_uspace_softprog_interrupt_reentry
+__entry_uspace_softprog_interrupt_reentry:
+	LEDS		0x6001
+
+	setlos		#REG__END,gr30
+	dcpl		gr28,gr30,#0
+
+	# set up the kernel stack pointer
+	sti.p		sp,@(gr28,#REG_SP)
+	ori		gr28,0,sp
+	sti		gr0,@(gr28,#REG_GR(28))
+
+	stdi		gr20,@(gr28,#REG_GR(20))
+	stdi		gr22,@(gr28,#REG_GR(22))
+
+	movsg		tbr,gr20
+	movsg		pcsr,gr21
+	movsg		psr,gr22
+
+	sethi.p		%hi(__entry_return_from_user_exception),gr23
+	setlo		%lo(__entry_return_from_user_exception),gr23
+	bra		__entry_common
+
+	.size		__entry_uspace_softprog_interrupt,.-__entry_uspace_softprog_interrupt
+
+	# single-stepping was disabled on entry to a TLB handler that then faulted
+#ifdef CONFIG_MMU
+	.globl		__entry_uspace_handle_mmu_fault_sstep
+__entry_uspace_handle_mmu_fault_sstep:
+	movgs		gr28,scr2
+	sethi.p		%hi(__kernel_frame0_ptr),gr28
+	setlo		%lo(__kernel_frame0_ptr),gr28
+	ldi		@(gr28,#0),gr28
+
+	# flag single-step re-enablement
+	sti		gr0,@(gr28,#REG__STATUS)
+	bra		__entry_uspace_softprog_interrupt_reentry
+#endif
+
+
+###############################################################################
+#
+# entry point for Software and Progam interrupts generated whilst executing kernel code
+#
+###############################################################################
+	.globl		__entry_kernel_softprog_interrupt
+        .type		__entry_kernel_softprog_interrupt,@function
+__entry_kernel_softprog_interrupt:
+	LEDS		0x6004
+
+#ifdef CONFIG_MMU
+	movsg		ear0,gr30
+	movgs		gr30,scr2
+#endif
+
+	.globl		__entry_kernel_handle_mmu_fault
+__entry_kernel_handle_mmu_fault:
+	# set up the stack pointer
+	subi		sp,#REG__END,sp
+	sti		sp,@(sp,#REG_SP)
+	sti		sp,@(sp,#REG_SP-4)
+	andi		sp,#~7,sp
+
+	# handle h/w single-step through exceptions
+	sti		gr0,@(sp,#REG__STATUS)
+
+	.globl		__entry_kernel_softprog_interrupt_reentry
+__entry_kernel_softprog_interrupt_reentry:
+	LEDS		0x6005
+
+	setlos		#REG__END,gr30
+	dcpl		sp,gr30,#0
+
+	# set up the exception frame
+	sti.p		gr28,@(sp,#REG_GR(28))
+	ori		sp,0,gr28
+
+	stdi		gr20,@(gr28,#REG_GR(20))
+	stdi		gr22,@(gr28,#REG_GR(22))
+
+	ldi		@(sp,#REG_SP),gr22		/* reconstruct the old SP */
+	addi		gr22,#REG__END,gr22
+	sti		gr22,@(sp,#REG_SP)
+
+	# set CCCR.CC3 to Undefined to abort atomic-modify completion inside the kernel
+	# - for an explanation of how it works, see: Documentation/fujitsu/frv/atomic-ops.txt
+	movsg		cccr,gr20
+	andi		gr20,#~0xc0,gr20
+	movgs		gr20,cccr
+
+	movsg		tbr,gr20
+	movsg		pcsr,gr21
+	movsg		psr,gr22
+
+	sethi.p		%hi(__entry_return_from_kernel_exception),gr23
+	setlo		%lo(__entry_return_from_kernel_exception),gr23
+	bra		__entry_common
+
+	.size		__entry_kernel_softprog_interrupt,.-__entry_kernel_softprog_interrupt
+
+	# single-stepping was disabled on entry to a TLB handler that then faulted
+#ifdef CONFIG_MMU
+	.globl		__entry_kernel_handle_mmu_fault_sstep
+__entry_kernel_handle_mmu_fault_sstep:
+	# set up the stack pointer
+	subi		sp,#REG__END,sp
+	sti		sp,@(sp,#REG_SP)
+	sti		sp,@(sp,#REG_SP-4)
+	andi		sp,#~7,sp
+
+	# flag single-step re-enablement
+	sethi		#REG__STATUS_STEP,gr30
+	sti		gr30,@(sp,#REG__STATUS)
+	bra		__entry_kernel_softprog_interrupt_reentry
+#endif
+
+
+###############################################################################
+#
+# the rest of the kernel entry point code
+# - on arriving here, the following registers should be set up:
+#	GR1	- kernel stack pointer
+#	GR7	- syscall number (trap 0 only)
+#	GR8-13	- syscall args (trap 0 only)
+#	GR20	- saved TBR
+#	GR21	- saved PC
+#	GR22	- saved PSR
+#	GR23	- return handler address
+#	GR28	- exception frame on stack
+#	SCR2	- saved EAR0 where applicable (clobbered by ICI & ICEF insns on FR451)
+#	PSR	- PSR.S 1, PSR.ET 0
+#
+###############################################################################
+	.globl		__entry_common
+        .type		__entry_common,@function
+__entry_common:
+	LEDS		0x6008
+
+	# finish building the exception frame
+	stdi		gr2,@(gr28,#REG_GR(2))
+	stdi		gr4,@(gr28,#REG_GR(4))
+	stdi		gr6,@(gr28,#REG_GR(6))
+	stdi		gr8,@(gr28,#REG_GR(8))
+	stdi		gr10,@(gr28,#REG_GR(10))
+	stdi		gr12,@(gr28,#REG_GR(12))
+	stdi		gr14,@(gr28,#REG_GR(14))
+	stdi		gr16,@(gr28,#REG_GR(16))
+	stdi		gr18,@(gr28,#REG_GR(18))
+	stdi		gr24,@(gr28,#REG_GR(24))
+	stdi		gr26,@(gr28,#REG_GR(26))
+	sti		gr29,@(gr28,#REG_GR(29))
+	stdi		gr30,@(gr28,#REG_GR(30))
+
+	movsg		lcr ,gr27
+	movsg		lr  ,gr26
+	movgs		gr23,lr
+	movsg		cccr,gr25
+	movsg		ccr ,gr24
+	movsg		isr ,gr23
+
+	setlos.p	#-1,gr4
+	andi		gr22,#PSR_PS,gr5		/* try to rebuild original PSR value */
+	andi.p		gr22,#~(PSR_PS|PSR_S),gr6
+	slli		gr5,#1,gr5
+	or		gr6,gr5,gr5
+	andi		gr5,#~PSR_ET,gr5
+
+	sti		gr20,@(gr28,#REG_TBR)
+	sti		gr21,@(gr28,#REG_PC)
+	sti		gr5 ,@(gr28,#REG_PSR)
+	sti		gr23,@(gr28,#REG_ISR)
+	stdi		gr24,@(gr28,#REG_CCR)
+	stdi		gr26,@(gr28,#REG_LR)
+	sti		gr4 ,@(gr28,#REG_SYSCALLNO)
+
+	movsg		iacc0h,gr4
+	movsg		iacc0l,gr5
+	stdi		gr4,@(gr28,#REG_IACC0)
+
+	movsg		gner0,gr4
+	movsg		gner1,gr5
+	stdi		gr4,@(gr28,#REG_GNER0)
+
+	# set up kernel global registers
+	sethi.p		%hi(__kernel_current_task),gr5
+	setlo		%lo(__kernel_current_task),gr5
+	sethi.p		%hi(_gp),gr16
+	setlo		%lo(_gp),gr16
+	ldi		@(gr5,#0),gr29
+	ldi		@(gr29,#4),gr15		; __current_thread_info = current->thread_info
+
+	# switch to the kernel trap table
+	sethi.p		%hi(__entry_kerneltrap_table),gr6
+	setlo		%lo(__entry_kerneltrap_table),gr6
+	movgs		gr6,tbr
+
+	# make sure we (the kernel) get div-zero and misalignment exceptions
+	setlos		#ISR_EDE|ISR_DTT_DIVBYZERO|ISR_EMAM_EXCEPTION,gr5
+	movgs		gr5,isr
+
+	# clear power-saving mode flags
+	movsg		hsr0,gr4
+	andi		gr4,#~HSR0_PDM,gr4
+	movgs		gr4,hsr0
+
+	# multiplex again using old TBR as a guide
+	setlos.p	#TBR_TT,gr3
+	sethi		%hi(__entry_vector_table),gr6
+	and.p		gr20,gr3,gr5
+	setlo		%lo(__entry_vector_table),gr6
+	srli		gr5,#2,gr5
+	ld		@(gr5,gr6),gr5
+
+	LEDS		0x6009
+	jmpl		@(gr5,gr0)
+
+
+	.size		__entry_common,.-__entry_common
+
+###############################################################################
+#
+# handle instruction MMU fault
+#
+###############################################################################
+#ifdef CONFIG_MMU
+	.globl		__entry_insn_mmu_fault
+__entry_insn_mmu_fault:
+	LEDS		0x6010
+	setlos		#0,gr8
+	movsg		esr0,gr9
+	movsg		scr2,gr10
+
+	# now that we've accessed the exception regs, we can enable exceptions
+	movsg		psr,gr4
+	ori		gr4,#PSR_ET,gr4
+	movgs		gr4,psr
+
+	sethi.p		%hi(do_page_fault),gr5
+	setlo		%lo(do_page_fault),gr5
+	jmpl		@(gr5,gr0)	; call do_page_fault(0,esr0,ear0)
+#endif
+
+
+###############################################################################
+#
+# handle instruction access error
+#
+###############################################################################
+	.globl		__entry_insn_access_error
+__entry_insn_access_error:
+	LEDS		0x6011
+	sethi.p		%hi(insn_access_error),gr5
+	setlo		%lo(insn_access_error),gr5
+	movsg		esfr1,gr8
+	movsg		epcr0,gr9
+	movsg		esr0,gr10
+
+	# now that we've accessed the exception regs, we can enable exceptions
+	movsg		psr,gr4
+	ori		gr4,#PSR_ET,gr4
+	movgs		gr4,psr
+	jmpl		@(gr5,gr0)	; call insn_access_error(esfr1,epcr0,esr0)
+
+###############################################################################
+#
+# handle various instructions of dubious legality
+#
+###############################################################################
+	.globl		__entry_unsupported_trap
+	.globl		__entry_illegal_instruction
+	.globl		__entry_privileged_instruction
+	.globl		__entry_debug_exception
+__entry_unsupported_trap:
+	subi		gr21,#4,gr21
+	sti		gr21,@(gr28,#REG_PC)
+__entry_illegal_instruction:
+__entry_privileged_instruction:
+__entry_debug_exception:
+	LEDS		0x6012
+	sethi.p		%hi(illegal_instruction),gr5
+	setlo		%lo(illegal_instruction),gr5
+	movsg		esfr1,gr8
+	movsg		epcr0,gr9
+	movsg		esr0,gr10
+
+	# now that we've accessed the exception regs, we can enable exceptions
+	movsg		psr,gr4
+	ori		gr4,#PSR_ET,gr4
+	movgs		gr4,psr
+	jmpl		@(gr5,gr0)	; call ill_insn(esfr1,epcr0,esr0)
+
+###############################################################################
+#
+# handle media exception
+#
+###############################################################################
+	.globl		__entry_media_exception
+__entry_media_exception:
+	LEDS		0x6013
+	sethi.p		%hi(media_exception),gr5
+	setlo		%lo(media_exception),gr5
+	movsg		msr0,gr8
+	movsg		msr1,gr9
+
+	# now that we've accessed the exception regs, we can enable exceptions
+	movsg		psr,gr4
+	ori		gr4,#PSR_ET,gr4
+	movgs		gr4,psr
+	jmpl		@(gr5,gr0)	; call media_excep(msr0,msr1)
+
+###############################################################################
+#
+# handle data MMU fault
+# handle data DAT fault (write-protect exception)
+#
+###############################################################################
+#ifdef CONFIG_MMU
+	.globl		__entry_data_mmu_fault
+__entry_data_mmu_fault:
+	.globl		__entry_data_dat_fault
+__entry_data_dat_fault:
+	LEDS		0x6014
+	setlos		#1,gr8
+	movsg		esr0,gr9
+	movsg		scr2,gr10	; saved EAR0
+
+	# now that we've accessed the exception regs, we can enable exceptions
+	movsg		psr,gr4
+	ori		gr4,#PSR_ET,gr4
+	movgs		gr4,psr
+
+	sethi.p		%hi(do_page_fault),gr5
+	setlo		%lo(do_page_fault),gr5
+	jmpl		@(gr5,gr0)	; call do_page_fault(1,esr0,ear0)
+#endif
+
+###############################################################################
+#
+# handle data and instruction access exceptions
+#
+###############################################################################
+	.globl		__entry_insn_access_exception
+	.globl		__entry_data_access_exception
+__entry_insn_access_exception:
+__entry_data_access_exception:
+	LEDS		0x6016
+	sethi.p		%hi(memory_access_exception),gr5
+	setlo		%lo(memory_access_exception),gr5
+	movsg		esr0,gr8
+	movsg		scr2,gr9	; saved EAR0
+	movsg		epcr0,gr10
+
+	# now that we've accessed the exception regs, we can enable exceptions
+	movsg		psr,gr4
+	ori		gr4,#PSR_ET,gr4
+	movgs		gr4,psr
+	jmpl		@(gr5,gr0)	; call memory_access_error(esr0,ear0,epcr0)
+
+###############################################################################
+#
+# handle data access error
+#
+###############################################################################
+	.globl		__entry_data_access_error
+__entry_data_access_error:
+	LEDS		0x6016
+	sethi.p		%hi(data_access_error),gr5
+	setlo		%lo(data_access_error),gr5
+	movsg		esfr1,gr8
+	movsg		esr15,gr9
+	movsg		ear15,gr10
+
+	# now that we've accessed the exception regs, we can enable exceptions
+	movsg		psr,gr4
+	ori		gr4,#PSR_ET,gr4
+	movgs		gr4,psr
+	jmpl		@(gr5,gr0)	; call data_access_error(esfr1,esr15,ear15)
+
+###############################################################################
+#
+# handle data store error
+#
+###############################################################################
+	.globl		__entry_data_store_error
+__entry_data_store_error:
+	LEDS		0x6017
+	sethi.p		%hi(data_store_error),gr5
+	setlo		%lo(data_store_error),gr5
+	movsg		esfr1,gr8
+	movsg		esr14,gr9
+
+	# now that we've accessed the exception regs, we can enable exceptions
+	movsg		psr,gr4
+	ori		gr4,#PSR_ET,gr4
+	movgs		gr4,psr
+	jmpl		@(gr5,gr0)	; call data_store_error(esfr1,esr14)
+
+###############################################################################
+#
+# handle division exception
+#
+###############################################################################
+	.globl		__entry_division_exception
+__entry_division_exception:
+	LEDS		0x6018
+	sethi.p		%hi(division_exception),gr5
+	setlo		%lo(division_exception),gr5
+	movsg		esfr1,gr8
+	movsg		esr0,gr9
+	movsg		isr,gr10
+
+	# now that we've accessed the exception regs, we can enable exceptions
+	movsg		psr,gr4
+	ori		gr4,#PSR_ET,gr4
+	movgs		gr4,psr
+	jmpl		@(gr5,gr0)	; call div_excep(esfr1,esr0,isr)
+
+###############################################################################
+#
+# handle compound exception
+#
+###############################################################################
+	.globl		__entry_compound_exception
+__entry_compound_exception:
+	LEDS		0x6019
+	sethi.p		%hi(compound_exception),gr5
+	setlo		%lo(compound_exception),gr5
+	movsg		esfr1,gr8
+	movsg		esr0,gr9
+	movsg		esr14,gr10
+	movsg		esr15,gr11
+	movsg		msr0,gr12
+	movsg		msr1,gr13
+
+	# now that we've accessed the exception regs, we can enable exceptions
+	movsg		psr,gr4
+	ori		gr4,#PSR_ET,gr4
+	movgs		gr4,psr
+	jmpl		@(gr5,gr0)	; call comp_excep(esfr1,esr0,esr14,esr15,msr0,msr1)
+
+###############################################################################
+#
+# handle interrupts and NMIs
+#
+###############################################################################
+	.globl		__entry_do_IRQ
+__entry_do_IRQ:
+	LEDS		0x6020
+
+	# we can enable exceptions
+	movsg		psr,gr4
+	ori		gr4,#PSR_ET,gr4
+	movgs		gr4,psr
+	bra		do_IRQ
+
+	.globl		__entry_do_NMI
+__entry_do_NMI:
+	LEDS		0x6021
+
+	# we can enable exceptions
+	movsg		psr,gr4
+	ori		gr4,#PSR_ET,gr4
+	movgs		gr4,psr
+	bra		do_NMI
+
+###############################################################################
+#
+# the return path for a newly forked child process
+# - __switch_to() saved the old current pointer in GR8 for us
+#
+###############################################################################
+	.globl		ret_from_fork
+ret_from_fork:
+	LEDS		0x6100
+	call		schedule_tail
+
+	# fork & co. return 0 to child
+	setlos.p	#0,gr8
+	bra		__syscall_exit
+
+###################################################################################################
+#
+# Return to user mode is not as complex as all this looks,
+# but we want the default path for a system call return to
+# go as quickly as possible which is why some of this is
+# less clear than it otherwise should be.
+#
+###################################################################################################
+	.balign		L1_CACHE_BYTES
+	.globl		system_call
+system_call:
+	LEDS		0x6101
+	movsg		psr,gr4			; enable exceptions
+	ori		gr4,#PSR_ET,gr4
+	movgs		gr4,psr
+
+	sti		gr7,@(gr28,#REG_SYSCALLNO)
+	sti.p		gr8,@(gr28,#REG_ORIG_GR8)
+
+	subicc		gr7,#nr_syscalls,gr0,icc0
+	bnc		icc0,#0,__syscall_badsys
+
+	ldi		@(gr15,#TI_FLAGS),gr4
+	ori		gr4,#_TIF_SYSCALL_TRACE,gr4
+	andicc		gr4,#_TIF_SYSCALL_TRACE,gr0,icc0
+	bne		icc0,#0,__syscall_trace_entry
+
+__syscall_call:
+	slli.p		gr7,#2,gr7
+	sethi		%hi(sys_call_table),gr5
+	setlo		%lo(sys_call_table),gr5
+	ld		@(gr5,gr7),gr4
+	calll		@(gr4,gr0)
+
+
+###############################################################################
+#
+# return to interrupted process
+#
+###############################################################################
+__syscall_exit:
+	LEDS		0x6300
+
+	sti		gr8,@(gr28,#REG_GR(8))	; save return value
+
+	# rebuild saved psr - execve will change it for init/main.c
+	ldi		@(gr28,#REG_PSR),gr22
+	srli		gr22,#1,gr5
+	andi.p		gr22,#~PSR_PS,gr22
+	andi		gr5,#PSR_PS,gr5
+	or		gr5,gr22,gr22
+	ori		gr22,#PSR_S,gr22
+
+	# keep current PSR in GR23
+	movsg		psr,gr23
+
+	# make sure we don't miss an interrupt setting need_resched or sigpending between
+	# sampling and the RETT
+	ori		gr23,#PSR_PIL_14,gr23
+	movgs		gr23,psr
+
+	ldi		@(gr15,#TI_FLAGS),gr4
+	sethi.p		%hi(_TIF_ALLWORK_MASK),gr5
+	setlo		%lo(_TIF_ALLWORK_MASK),gr5
+	andcc		gr4,gr5,gr0,icc0
+	bne		icc0,#0,__syscall_exit_work
+
+	# restore all registers and return
+__entry_return_direct:
+	LEDS		0x6301
+
+	andi		gr22,#~PSR_ET,gr22
+	movgs		gr22,psr
+
+	ldi		@(gr28,#REG_ISR),gr23
+	lddi		@(gr28,#REG_CCR),gr24
+	lddi		@(gr28,#REG_LR) ,gr26
+	ldi		@(gr28,#REG_PC) ,gr21
+	ldi		@(gr28,#REG_TBR),gr20
+
+	movgs		gr20,tbr
+	movgs		gr21,pcsr
+	movgs		gr23,isr
+	movgs		gr24,ccr
+	movgs		gr25,cccr
+	movgs		gr26,lr
+	movgs		gr27,lcr
+
+	lddi		@(gr28,#REG_GNER0),gr4
+	movgs		gr4,gner0
+	movgs		gr5,gner1
+
+	lddi		@(gr28,#REG_IACC0),gr4
+	movgs		gr4,iacc0h
+	movgs		gr5,iacc0l
+
+	lddi		@(gr28,#REG_GR(4)) ,gr4
+	lddi		@(gr28,#REG_GR(6)) ,gr6
+	lddi		@(gr28,#REG_GR(8)) ,gr8
+	lddi		@(gr28,#REG_GR(10)),gr10
+	lddi		@(gr28,#REG_GR(12)),gr12
+	lddi		@(gr28,#REG_GR(14)),gr14
+	lddi		@(gr28,#REG_GR(16)),gr16
+	lddi		@(gr28,#REG_GR(18)),gr18
+	lddi		@(gr28,#REG_GR(20)),gr20
+	lddi		@(gr28,#REG_GR(22)),gr22
+	lddi		@(gr28,#REG_GR(24)),gr24
+	lddi		@(gr28,#REG_GR(26)),gr26
+	ldi		@(gr28,#REG_GR(29)),gr29
+	lddi		@(gr28,#REG_GR(30)),gr30
+
+	# check to see if a debugging return is required
+	LEDS		0x67f0
+	movsg		ccr,gr2
+	ldi		@(gr28,#REG__STATUS),gr3
+	andicc		gr3,#REG__STATUS_STEP,gr0,icc0
+	bne		icc0,#0,__entry_return_singlestep
+	movgs		gr2,ccr
+
+	ldi		@(gr28,#REG_SP)    ,sp
+	lddi		@(gr28,#REG_GR(2)) ,gr2
+	ldi		@(gr28,#REG_GR(28)),gr28
+
+	LEDS		0x67fe
+//	movsg		pcsr,gr31
+//	LEDS32
+
+#if 0
+	# store the current frame in the workram on the FR451
+	movgs		gr28,scr2
+	sethi.p		%hi(0xfe800000),gr28
+	setlo		%lo(0xfe800000),gr28
+
+	stdi		gr2,@(gr28,#REG_GR(2))
+	stdi		gr4,@(gr28,#REG_GR(4))
+	stdi		gr6,@(gr28,#REG_GR(6))
+	stdi		gr8,@(gr28,#REG_GR(8))
+	stdi		gr10,@(gr28,#REG_GR(10))
+	stdi		gr12,@(gr28,#REG_GR(12))
+	stdi		gr14,@(gr28,#REG_GR(14))
+	stdi		gr16,@(gr28,#REG_GR(16))
+	stdi		gr18,@(gr28,#REG_GR(18))
+	stdi		gr24,@(gr28,#REG_GR(24))
+	stdi		gr26,@(gr28,#REG_GR(26))
+	sti		gr29,@(gr28,#REG_GR(29))
+	stdi		gr30,@(gr28,#REG_GR(30))
+
+	movsg		tbr ,gr30
+	sti		gr30,@(gr28,#REG_TBR)
+	movsg		pcsr,gr30
+	sti		gr30,@(gr28,#REG_PC)
+	movsg		psr ,gr30
+	sti		gr30,@(gr28,#REG_PSR)
+	movsg		isr ,gr30
+	sti		gr30,@(gr28,#REG_ISR)
+	movsg		ccr ,gr30
+	movsg		cccr,gr31
+	stdi		gr30,@(gr28,#REG_CCR)
+	movsg		lr  ,gr30
+	movsg		lcr ,gr31
+	stdi		gr30,@(gr28,#REG_LR)
+	sti		gr0 ,@(gr28,#REG_SYSCALLNO)
+	movsg		scr2,gr28
+#endif
+
+	rett		#0
+
+	# return via break.S
+__entry_return_singlestep:
+	movgs		gr2,ccr
+	lddi		@(gr28,#REG_GR(2)) ,gr2
+	ldi		@(gr28,#REG_SP)    ,sp
+	ldi		@(gr28,#REG_GR(28)),gr28
+	LEDS		0x67ff
+	break
+	.globl		__entry_return_singlestep_breaks_here
+__entry_return_singlestep_breaks_here:
+	nop
+
+
+###############################################################################
+#
+# return to a process interrupted in kernel space
+# - we need to consider preemption if that is enabled
+#
+###############################################################################
+	.balign		L1_CACHE_BYTES
+__entry_return_from_kernel_exception:
+	LEDS		0x6302
+	movsg		psr,gr23
+	ori		gr23,#PSR_PIL_14,gr23
+	movgs		gr23,psr
+	bra		__entry_return_direct
+
+	.balign		L1_CACHE_BYTES
+__entry_return_from_kernel_interrupt:
+	LEDS		0x6303
+	movsg		psr,gr23
+	ori		gr23,#PSR_PIL_14,gr23
+	movgs		gr23,psr
+
+#ifdef CONFIG_PREEMPT
+	ldi		@(gr15,#TI_PRE_COUNT),gr5
+	subicc		gr5,#0,gr0,icc0
+	beq		icc0,#0,__entry_return_direct
+
+__entry_preempt_need_resched:
+	ldi		@(gr15,#TI_FLAGS),gr4
+	andicc		gr4,#_TIF_NEED_RESCHED,gr0,icc0
+	beq		icc0,#1,__entry_return_direct
+
+	setlos		#PREEMPT_ACTIVE,gr5
+	sti		gr5,@(gr15,#TI_FLAGS)
+
+	andi		gr23,#~PSR_PIL,gr23
+	movgs		gr23,psr
+
+	call		schedule
+	sti		gr0,@(gr15,#TI_PRE_COUNT)
+
+	movsg		psr,gr23
+	ori		gr23,#PSR_PIL_14,gr23
+	movgs		gr23,psr
+	bra		__entry_preempt_need_resched
+#else
+	bra		__entry_return_direct
+#endif
+
+
+###############################################################################
+#
+# perform work that needs to be done immediately before resumption
+#
+###############################################################################
+	.globl		__entry_return_from_user_exception
+	.balign		L1_CACHE_BYTES
+__entry_return_from_user_exception:
+	LEDS		0x6501
+
+__entry_resume_userspace:
+	# make sure we don't miss an interrupt setting need_resched or sigpending between
+	# sampling and the RETT
+	movsg		psr,gr23
+	ori		gr23,#PSR_PIL_14,gr23
+	movgs		gr23,psr
+
+__entry_return_from_user_interrupt:
+	LEDS		0x6402
+	ldi		@(gr15,#TI_FLAGS),gr4
+	sethi.p		%hi(_TIF_WORK_MASK),gr5
+	setlo		%lo(_TIF_WORK_MASK),gr5
+	andcc		gr4,gr5,gr0,icc0
+	beq		icc0,#1,__entry_return_direct
+
+__entry_work_pending:
+	LEDS		0x6404
+	andicc		gr4,#_TIF_NEED_RESCHED,gr0,icc0
+	beq		icc0,#1,__entry_work_notifysig
+
+__entry_work_resched:
+	LEDS		0x6408
+	movsg		psr,gr23
+	andi		gr23,#~PSR_PIL,gr23
+	movgs		gr23,psr
+	call		schedule
+	movsg		psr,gr23
+	ori		gr23,#PSR_PIL_14,gr23
+	movgs		gr23,psr
+
+	LEDS		0x6401
+	ldi		@(gr15,#TI_FLAGS),gr4
+	sethi.p		%hi(_TIF_WORK_MASK),gr5
+	setlo		%lo(_TIF_WORK_MASK),gr5
+	andcc		gr4,gr5,gr0,icc0
+	beq		icc0,#1,__entry_return_direct
+	andicc		gr4,#_TIF_NEED_RESCHED,gr0,icc0
+	bne		icc0,#1,__entry_work_resched
+
+__entry_work_notifysig:
+	LEDS		0x6410
+	ori.p		gr4,#0,gr8
+	call		do_notify_resume
+	bra		__entry_return_direct
+
+	# perform syscall entry tracing
+__syscall_trace_entry:
+	LEDS		0x6320
+	setlos.p	#0,gr8
+	call		do_syscall_trace
+
+	ldi		@(gr28,#REG_SYSCALLNO),gr7
+	lddi		@(gr28,#REG_GR(8)) ,gr8
+	lddi		@(gr28,#REG_GR(10)),gr10
+	lddi.p		@(gr28,#REG_GR(12)),gr12
+
+	subicc		gr7,#nr_syscalls,gr0,icc0
+	bnc		icc0,#0,__syscall_badsys
+	bra		__syscall_call
+
+	# perform syscall exit tracing
+__syscall_exit_work:
+	LEDS		0x6340
+	andicc		gr4,#_TIF_SYSCALL_TRACE,gr0,icc0
+	beq		icc0,#1,__entry_work_pending
+
+	movsg		psr,gr23
+	andi		gr23,#~PSR_PIL,gr23	; could let do_syscall_trace() call schedule()
+	movgs		gr23,psr
+
+	setlos.p	#1,gr8
+	call		do_syscall_trace
+	bra		__entry_resume_userspace
+
+__syscall_badsys:
+	LEDS		0x6380
+	setlos		#-ENOSYS,gr8
+	sti		gr8,@(gr28,#REG_GR(8))	; save return value
+	bra		__entry_resume_userspace
+
+
+###############################################################################
+#
+# syscall vector table
+#
+###############################################################################
+#ifdef CONFIG_MMU
+#define __MMU(X) X
+#else
+#define __MMU(X) sys_ni_syscall
+#endif
+
+	.section .rodata
+ALIGN
+	.globl		sys_call_table
+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_ni_syscall // 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_ni_syscall // 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 old uname syscall */
+	.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_ni_syscall // sys_sgetmask
+	.long sys_ni_syscall // sys_ssetmask
+	.long sys_setreuid16	/* 70 */
+	.long sys_setregid16
+	.long sys_sigsuspend
+	.long sys_ni_syscall // sys_sigpending
+	.long sys_sethostname
+	.long sys_setrlimit	/* 75 */
+	.long sys_ni_syscall // sys_old_getrlimit
+	.long sys_getrusage
+	.long sys_gettimeofday
+	.long sys_settimeofday
+	.long sys_getgroups16	/* 80 */
+	.long sys_setgroups16
+	.long sys_ni_syscall			/* old_select slot */
+	.long sys_symlink
+	.long sys_lstat
+	.long sys_readlink		/* 85 */
+	.long sys_uselib
+	.long sys_swapon
+	.long sys_reboot
+	.long sys_ni_syscall // old_readdir
+	.long sys_ni_syscall	/* 90 */	/* old_mmap slot */
+	.long sys_munmap
+	.long sys_truncate
+	.long sys_ftruncate
+	.long sys_fchmod
+	.long sys_fchown16		/* 95 */
+	.long sys_getpriority
+	.long sys_setpriority
+	.long sys_ni_syscall			/* old profil syscall holder */
+	.long sys_statfs
+	.long sys_fstatfs		/* 100 */
+	.long sys_ni_syscall			/* ioperm for 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	/* obsolete olduname( syscall */
+	.long sys_ni_syscall	/* iopl for i386 */ /* 110 */
+	.long sys_vhangup
+	.long sys_ni_syscall	/* obsolete idle( syscall */
+	.long sys_ni_syscall	/* vm86old for 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	/* old "cacheflush" */
+	.long sys_adjtimex
+	.long __MMU(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	/* 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 __MMU(sys_msync)
+	.long sys_readv		/* 145 */
+	.long sys_writev
+	.long sys_getsid
+	.long sys_fdatasync
+	.long sys_sysctl
+	.long __MMU(sys_mlock)		/* 150 */
+	.long __MMU(sys_munlock)
+	.long __MMU(sys_mlockall)
+	.long __MMU(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 __MMU(sys_mremap)
+	.long sys_setresuid16
+	.long sys_getresuid16	/* 165 */
+	.long sys_ni_syscall	/* for 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 __MMU(sys_mincore)
+	.long __MMU(sys_madvise)
+	.long sys_getdents64	/* 220 */
+	.long sys_fcntl64
+	.long sys_ni_syscall	/* reserved for TUX */
+	.long sys_ni_syscall	/* Reserved for Security */
+	.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 __MMU(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_mbind
+	.long sys_get_mempolicy
+	.long 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
+	.long sys_ni_syscall		/* 285 */ /* available */
+	.long sys_add_key
+	.long sys_request_key
+	.long sys_keyctl
+	.long sys_ni_syscall // sys_vperfctr_open
+	.long sys_ni_syscall // sys_vperfctr_control	/* 290 */
+	.long sys_ni_syscall // sys_vperfctr_unlink
+	.long sys_ni_syscall // sys_vperfctr_iresume
+	.long sys_ni_syscall // sys_vperfctr_read
+
+
+syscall_table_size = (. - sys_call_table)
diff -Nru a/arch/frv/kernel/frv_ksyms.c b/arch/frv/kernel/frv_ksyms.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/kernel/frv_ksyms.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,124 @@
+#include <linux/module.h>
+#include <linux/linkage.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/user.h>
+#include <linux/elfcore.h>
+#include <linux/in6.h>
+#include <linux/interrupt.h>
+#include <linux/config.h>
+
+#include <asm/setup.h>
+#include <asm/pgalloc.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/semaphore.h>
+#include <asm/checksum.h>
+#include <asm/hardirq.h>
+#include <asm/current.h>
+
+extern void dump_thread(struct pt_regs *, struct user *);
+extern long __memcpy_user(void *dst, const void *src, size_t count);
+
+/* platform dependent support */
+
+EXPORT_SYMBOL(__ioremap);
+EXPORT_SYMBOL(iounmap);
+
+EXPORT_SYMBOL(dump_thread);
+EXPORT_SYMBOL(strnlen);
+EXPORT_SYMBOL(strrchr);
+EXPORT_SYMBOL(strstr);
+EXPORT_SYMBOL(strchr);
+EXPORT_SYMBOL(strcat);
+EXPORT_SYMBOL(strlen);
+EXPORT_SYMBOL(strcmp);
+EXPORT_SYMBOL(strncmp);
+EXPORT_SYMBOL(strncpy);
+
+EXPORT_SYMBOL(ip_fast_csum);
+
+#if 0
+EXPORT_SYMBOL(local_irq_count);
+EXPORT_SYMBOL(local_bh_count);
+#endif
+EXPORT_SYMBOL(kernel_thread);
+
+EXPORT_SYMBOL(enable_irq);
+EXPORT_SYMBOL(disable_irq);
+EXPORT_SYMBOL(__res_bus_clock_speed_HZ);
+EXPORT_SYMBOL(__page_offset);
+EXPORT_SYMBOL(__memcpy_user);
+EXPORT_SYMBOL(flush_dcache_page);
+
+#ifndef CONFIG_MMU
+EXPORT_SYMBOL(memory_start);
+EXPORT_SYMBOL(memory_end);
+#endif
+
+EXPORT_SYMBOL(__debug_bug_trap);
+
+/* Networking helper routines. */
+EXPORT_SYMBOL(csum_partial_copy);
+
+/* The following are special because they're not called
+   explicitly (the C compiler generates them).  Fortunately,
+   their interface isn't gonna change any time soon now, so
+   it's OK to leave it out of version control.  */
+EXPORT_SYMBOL(memcpy);
+EXPORT_SYMBOL(memset);
+EXPORT_SYMBOL(memcmp);
+EXPORT_SYMBOL(memscan);
+EXPORT_SYMBOL(memmove);
+EXPORT_SYMBOL(strtok);
+
+EXPORT_SYMBOL(get_wchan);
+
+#ifdef CONFIG_FRV_OUTOFLINE_ATOMIC_OPS
+EXPORT_SYMBOL(atomic_test_and_ANDNOT_mask);
+EXPORT_SYMBOL(atomic_test_and_OR_mask);
+EXPORT_SYMBOL(atomic_test_and_XOR_mask);
+EXPORT_SYMBOL(atomic_add_return);
+EXPORT_SYMBOL(atomic_sub_return);
+EXPORT_SYMBOL(__xchg_8);
+EXPORT_SYMBOL(__xchg_16);
+EXPORT_SYMBOL(__xchg_32);
+EXPORT_SYMBOL(__cmpxchg_8);
+EXPORT_SYMBOL(__cmpxchg_16);
+EXPORT_SYMBOL(__cmpxchg_32);
+#endif
+
+/*
+ * libgcc functions - functions that are used internally by the
+ * compiler...  (prototypes are not correct though, but that
+ * doesn't really matter since they're not versioned).
+ */
+extern void __gcc_bcmp(void);
+extern void __ashldi3(void);
+extern void __ashrdi3(void);
+extern void __cmpdi2(void);
+extern void __divdi3(void);
+extern void __lshrdi3(void);
+extern void __moddi3(void);
+extern void __muldi3(void);
+extern void __negdi2(void);
+extern void __ucmpdi2(void);
+extern void __udivdi3(void);
+extern void __udivmoddi4(void);
+extern void __umoddi3(void);
+
+        /* gcc lib functions */
+//EXPORT_SYMBOL(__gcc_bcmp);
+EXPORT_SYMBOL(__ashldi3);
+EXPORT_SYMBOL(__ashrdi3);
+//EXPORT_SYMBOL(__cmpdi2);
+//EXPORT_SYMBOL(__divdi3);
+EXPORT_SYMBOL(__lshrdi3);
+//EXPORT_SYMBOL(__moddi3);
+EXPORT_SYMBOL(__muldi3);
+EXPORT_SYMBOL(__negdi2);
+//EXPORT_SYMBOL(__ucmpdi2);
+//EXPORT_SYMBOL(__udivdi3);
+//EXPORT_SYMBOL(__udivmoddi4);
+//EXPORT_SYMBOL(__umoddi3);
diff -Nru a/arch/frv/kernel/gdb-io.c b/arch/frv/kernel/gdb-io.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/kernel/gdb-io.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,216 @@
+/* gdb-io.c: FR403 GDB stub I/O
+ *
+ * Copyright (C) 2003 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/string.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/console.h>
+#include <linux/init.h>
+#include <linux/serial_reg.h>
+
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/irc-regs.h>
+#include <asm/timer-regs.h>
+#include <asm/gdb-stub.h>
+#include "gdb-io.h"
+
+#ifdef CONFIG_GDBSTUB_UART0
+#define __UART(X) (*(volatile uint8_t *)(UART0_BASE + (UART_##X)))
+#define __UART_IRR_NMI 0xff0f0000
+#else /* CONFIG_GDBSTUB_UART1 */
+#define __UART(X) (*(volatile uint8_t *)(UART1_BASE + (UART_##X)))
+#define __UART_IRR_NMI 0xfff00000
+#endif
+
+#define LSR_WAIT_FOR(STATE)			\
+do {						\
+	gdbstub_do_rx();			\
+} while (!(__UART(LSR) & UART_LSR_##STATE))
+
+#define FLOWCTL_QUERY(LINE)	({ __UART(MSR) & UART_MSR_##LINE; })
+#define FLOWCTL_CLEAR(LINE)	do { __UART(MCR) &= ~UART_MCR_##LINE; mb(); } while (0)
+#define FLOWCTL_SET(LINE)	do { __UART(MCR) |= UART_MCR_##LINE;  mb(); } while (0)
+
+#define FLOWCTL_WAIT_FOR(LINE)			\
+do {						\
+	gdbstub_do_rx();			\
+} while(!FLOWCTL_QUERY(LINE))
+
+/*****************************************************************************/
+/*
+ * initialise the GDB stub
+ * - called with PSR.ET==0, so can't incur external interrupts
+ */
+void gdbstub_io_init(void)
+{
+	/* set up the serial port */
+	__UART(LCR) = UART_LCR_WLEN8; /* 1N8 */
+	__UART(FCR) =
+		UART_FCR_ENABLE_FIFO |
+		UART_FCR_CLEAR_RCVR |
+		UART_FCR_CLEAR_XMIT |
+		UART_FCR_TRIGGER_1;
+
+	FLOWCTL_CLEAR(DTR);
+	FLOWCTL_SET(RTS);
+
+//	gdbstub_set_baud(115200);
+
+	/* we want to get serial receive interrupts */
+	__UART(IER) = UART_IER_RDI | UART_IER_RLSI;
+	mb();
+
+	__set_IRR(6, __UART_IRR_NMI);	/* map ERRs and UARTx to NMI */
+
+} /* end gdbstub_io_init() */
+
+/*****************************************************************************/
+/*
+ * set up the GDB stub serial port baud rate timers
+ */
+void gdbstub_set_baud(unsigned baud)
+{
+	unsigned value, high, low;
+	u8 lcr;
+
+	/* work out the divisor to give us the nearest higher baud rate */
+	value = __serial_clock_speed_HZ / 16 / baud;
+
+	/* determine the baud rate range */
+	high = __serial_clock_speed_HZ / 16 / value;
+	low = __serial_clock_speed_HZ / 16 / (value + 1);
+
+	/* pick the nearest bound */
+	if (low + (high - low) / 2 > baud)
+		value++;
+
+	lcr = __UART(LCR);
+	__UART(LCR) |= UART_LCR_DLAB;
+	mb();
+	__UART(DLL) = value & 0xff;
+	__UART(DLM) = (value >> 8) & 0xff;
+	mb();
+	__UART(LCR) = lcr;
+	mb();
+
+} /* end gdbstub_set_baud() */
+
+/*****************************************************************************/
+/*
+ * receive characters into the receive FIFO
+ */
+void gdbstub_do_rx(void)
+{
+	unsigned ix, nix;
+
+	ix = gdbstub_rx_inp;
+
+	while (__UART(LSR) & UART_LSR_DR) {
+		nix = (ix + 2) & 0xfff;
+		if (nix == gdbstub_rx_outp)
+			break;
+
+		gdbstub_rx_buffer[ix++] = __UART(LSR);
+		gdbstub_rx_buffer[ix++] = __UART(RX);
+		ix = nix;
+	}
+
+	gdbstub_rx_inp = ix;
+
+	__clr_RC(15);
+	__clr_IRL();
+
+} /* end gdbstub_do_rx() */
+
+/*****************************************************************************/
+/*
+ * wait for a character to come from the debugger
+ */
+int gdbstub_rx_char(unsigned char *_ch, int nonblock)
+{
+	unsigned ix;
+	u8 ch, st;
+
+	*_ch = 0xff;
+
+	if (gdbstub_rx_unget) {
+		*_ch = gdbstub_rx_unget;
+		gdbstub_rx_unget = 0;
+		return 0;
+	}
+
+ try_again:
+	gdbstub_do_rx();
+
+	/* pull chars out of the buffer */
+	ix = gdbstub_rx_outp;
+	if (ix == gdbstub_rx_inp) {
+		if (nonblock)
+			return -EAGAIN;
+		//watchdog_alert_counter = 0;
+		goto try_again;
+	}
+
+	st = gdbstub_rx_buffer[ix++];
+	ch = gdbstub_rx_buffer[ix++];
+	gdbstub_rx_outp = ix & 0x00000fff;
+
+	if (st & UART_LSR_BI) {
+		gdbstub_proto("### GDB Rx Break Detected ###\n");
+		return -EINTR;
+	}
+	else if (st & (UART_LSR_FE|UART_LSR_OE|UART_LSR_PE)) {
+		gdbstub_proto("### GDB Rx Error (st=%02x) ###\n",st);
+		return -EIO;
+	}
+	else {
+		gdbstub_proto("### GDB Rx %02x (st=%02x) ###\n",ch,st);
+		*_ch = ch & 0x7f;
+		return 0;
+	}
+
+} /* end gdbstub_rx_char() */
+
+/*****************************************************************************/
+/*
+ * send a character to the debugger
+ */
+void gdbstub_tx_char(unsigned char ch)
+{
+	FLOWCTL_SET(DTR);
+	LSR_WAIT_FOR(THRE);
+//	FLOWCTL_WAIT_FOR(CTS);
+
+	if (ch == 0x0a) {
+		__UART(TX) = 0x0d;
+		mb();
+		LSR_WAIT_FOR(THRE);
+//		FLOWCTL_WAIT_FOR(CTS);
+	}
+	__UART(TX) = ch;
+	mb();
+
+	FLOWCTL_CLEAR(DTR);
+} /* end gdbstub_tx_char() */
+
+/*****************************************************************************/
+/*
+ * send a character to the debugger
+ */
+void gdbstub_tx_flush(void)
+{
+	LSR_WAIT_FOR(TEMT);
+	LSR_WAIT_FOR(THRE);
+	FLOWCTL_CLEAR(DTR);
+} /* end gdbstub_tx_flush() */
diff -Nru a/arch/frv/kernel/gdb-io.h b/arch/frv/kernel/gdb-io.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/kernel/gdb-io.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,55 @@
+/* gdb-io.h: FR403 GDB I/O port defs
+ *
+ * Copyright (C) 2003 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.
+ */
+
+#ifndef _GDB_IO_H
+#define _GDB_IO_H
+
+#include <asm/serial-regs.h>
+
+#undef UART_RX
+#undef UART_TX
+#undef UART_DLL
+#undef UART_DLM
+#undef UART_IER
+#undef UART_IIR
+#undef UART_FCR
+#undef UART_LCR
+#undef UART_MCR
+#undef UART_LSR
+#undef UART_MSR
+#undef UART_SCR
+
+#define UART_RX		0*8	/* In:  Receive buffer (DLAB=0) */
+#define UART_TX		0*8	/* Out: Transmit buffer (DLAB=0) */
+#define UART_DLL	0*8	/* Out: Divisor Latch Low (DLAB=1) */
+#define UART_DLM	1*8	/* Out: Divisor Latch High (DLAB=1) */
+#define UART_IER	1*8	/* Out: Interrupt Enable Register */
+#define UART_IIR	2*8	/* In:  Interrupt ID Register */
+#define UART_FCR	2*8	/* Out: FIFO Control Register */
+#define UART_LCR	3*8	/* Out: Line Control Register */
+#define UART_MCR	4*8	/* Out: Modem Control Register */
+#define UART_LSR	5*8	/* In:  Line Status Register */
+#define UART_MSR	6*8	/* In:  Modem Status Register */
+#define UART_SCR	7*8	/* I/O: Scratch Register */
+
+#define UART_LCR_DLAB	0x80	/* Divisor latch access bit */
+#define UART_LCR_SBC	0x40	/* Set break control */
+#define UART_LCR_SPAR	0x20	/* Stick parity (?) */
+#define UART_LCR_EPAR	0x10	/* Even parity select */
+#define UART_LCR_PARITY	0x08	/* Parity Enable */
+#define UART_LCR_STOP	0x04	/* Stop bits: 0=1 stop bit, 1= 2 stop bits */
+#define UART_LCR_WLEN5  0x00	/* Wordlength: 5 bits */
+#define UART_LCR_WLEN6  0x01	/* Wordlength: 6 bits */
+#define UART_LCR_WLEN7  0x02	/* Wordlength: 7 bits */
+#define UART_LCR_WLEN8  0x03	/* Wordlength: 8 bits */
+
+
+#endif /* _GDB_IO_H */
diff -Nru a/arch/frv/kernel/gdb-stub.c b/arch/frv/kernel/gdb-stub.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/kernel/gdb-stub.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,2084 @@
+/* gdb-stub.c: FRV GDB stub
+ *
+ * Copyright (C) 2003,4 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ * - Derived from Linux/MIPS version, Copyright (C) 1995 Andreas Busse
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+/*
+ *  To enable debugger support, two things need to happen.  One, a
+ *  call to set_debug_traps() is necessary in order to allow any breakpoints
+ *  or error conditions to be properly intercepted and reported to gdb.
+ *  Two, a breakpoint needs to be generated to begin communication.  This
+ *  is most easily accomplished by a call to breakpoint().  Breakpoint()
+ *  simulates a breakpoint by executing a BREAK instruction.
+ *
+ *
+ *    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
+ *
+ *
+ *  ==============
+ *  MORE EXAMPLES:
+ *  ==============
+ *
+ *  For reference -- the following are the steps that one
+ *  company took (RidgeRun Inc) to get remote gdb debugging
+ *  going. In this scenario the host machine was a PC and the
+ *  target platform was a Galileo EVB64120A MIPS evaluation
+ *  board.
+ *
+ *  Step 1:
+ *  First download gdb-5.0.tar.gz from the internet.
+ *  and then build/install the package.
+ *
+ *  Example:
+ *    $ tar zxf gdb-5.0.tar.gz
+ *    $ cd gdb-5.0
+ *    $ ./configure --target=frv-elf-gdb
+ *    $ make
+ *    $ frv-elf-gdb
+ *
+ *  Step 2:
+ *  Configure linux for remote debugging and build it.
+ *
+ *  Example:
+ *    $ cd ~/linux
+ *    $ make menuconfig <go to "Kernel Hacking" and turn on remote debugging>
+ *    $ make dep; make vmlinux
+ *
+ *  Step 3:
+ *  Download the kernel to the remote target and start
+ *  the kernel running. It will promptly halt and wait
+ *  for the host gdb session to connect. It does this
+ *  since the "Kernel Hacking" option has defined
+ *  CONFIG_REMOTE_DEBUG which in turn enables your calls
+ *  to:
+ *     set_debug_traps();
+ *     breakpoint();
+ *
+ *  Step 4:
+ *  Start the gdb session on the host.
+ *
+ *  Example:
+ *    $ frv-elf-gdb vmlinux
+ *    (gdb) set remotebaud 115200
+ *    (gdb) target remote /dev/ttyS1
+ *    ...at this point you are connected to
+ *       the remote target and can use gdb
+ *       in the normal fasion. Setting
+ *       breakpoints, single stepping,
+ *       printing variables, etc.
+ *
+ */
+
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/console.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/nmi.h>
+
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/gdb-stub.h>
+
+#define LEDS(x) do { /* *(u32*)0xe1200004 = ~(x); mb(); */ } while(0)
+
+#undef GDBSTUB_DEBUG_PROTOCOL
+
+extern void debug_to_serial(const char *p, int n);
+extern void gdbstub_console_write(struct console *co, const char *p, unsigned n);
+
+extern volatile uint32_t __break_error_detect[3]; /* ESFR1, ESR15, EAR15 */
+extern struct user_context __break_user_context;
+
+struct __debug_amr {
+	unsigned long L, P;
+} __attribute__((aligned(8)));
+
+struct __debug_mmu {
+	struct {
+		unsigned long	hsr0, pcsr, esr0, ear0, epcr0;
+#ifdef CONFIG_MMU
+		unsigned long	tplr, tppr, tpxr, cxnr;
+#endif
+	} regs;
+
+	struct __debug_amr	iamr[16];
+	struct __debug_amr	damr[16];
+
+#ifdef CONFIG_MMU
+	struct __debug_amr	tlb[64*2];
+#endif
+};
+
+static struct __debug_mmu __debug_mmu;
+
+/*
+ * BUFMAX defines the maximum number of characters in inbound/outbound buffers
+ * at least NUMREGBYTES*2 are needed for register packets
+ */
+#define BUFMAX 2048
+
+#define BREAK_INSN	0x801000c0	/* use "break" as bkpt */
+
+static const char gdbstub_banner[] = "Linux/FR-V GDB Stub (c) RedHat 2003\n";
+
+volatile u8	gdbstub_rx_buffer[PAGE_SIZE] __attribute__((aligned(PAGE_SIZE)));
+volatile u32	gdbstub_rx_inp = 0;
+volatile u32	gdbstub_rx_outp = 0;
+volatile u8	gdbstub_rx_overflow = 0;
+u8		gdbstub_rx_unget = 0;
+
+/* set with GDB whilst running to permit step through exceptions */
+extern volatile u32 __attribute__((section(".bss"))) gdbstub_trace_through_exceptions;
+
+static char	input_buffer[BUFMAX];
+static char	output_buffer[BUFMAX];
+
+static const char hexchars[] = "0123456789abcdef";
+
+static const char *regnames[] = {
+	"PSR ", "ISR ", "CCR ", "CCCR",
+	"LR  ", "LCR ", "PC  ", "_stt",
+	"sys ", "GR8*", "GNE0", "GNE1",
+	"IACH", "IACL",
+	"TBR ", "SP  ", "FP  ", "GR3 ",
+	"GR4 ", "GR5 ", "GR6 ", "GR7 ",
+	"GR8 ", "GR9 ", "GR10", "GR11",
+	"GR12", "GR13", "GR14", "GR15",
+	"GR16", "GR17", "GR18", "GR19",
+	"GR20", "GR21", "GR22", "GR23",
+	"GR24", "GR25", "GR26", "GR27",
+	"EFRM", "CURR", "GR30", "BFRM"
+};
+
+struct gdbstub_bkpt {
+	unsigned long	addr;		/* address of breakpoint */
+	unsigned	len;		/* size of breakpoint */
+	uint32_t	originsns[7];	/* original instructions */
+};
+
+static struct gdbstub_bkpt gdbstub_bkpts[256];
+
+/*
+ * local prototypes
+ */
+
+static void gdbstub_recv_packet(char *buffer);
+static int gdbstub_send_packet(char *buffer);
+static int gdbstub_compute_signal(unsigned long tbr);
+static int hex(unsigned char ch);
+static int hexToInt(char **ptr, unsigned long *intValue);
+static unsigned char *mem2hex(const void *mem, char *buf, int count, int may_fault);
+static char *hex2mem(const char *buf, void *_mem, int count);
+
+/*
+ * Convert ch from a hex digit to an int
+ */
+static int hex(unsigned 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;
+}
+
+void gdbstub_printk(const char *fmt, ...)
+{
+	static char buf[1024];
+	va_list args;
+	int len;
+
+	/* Emit the output into the temporary buffer */
+	va_start(args, fmt);
+	len = vsnprintf(buf, sizeof(buf), fmt, args);
+	va_end(args);
+	debug_to_serial(buf, len);
+}
+
+static inline char *gdbstub_strcpy(char *dst, const char *src)
+{
+	int loop = 0;
+	while ((dst[loop] = src[loop]))
+	       loop++;
+	return dst;
+}
+
+static void gdbstub_purge_cache(void)
+{
+	asm volatile("	dcef	@(gr0,gr0),#1	\n"
+		     "	icei	@(gr0,gr0),#1	\n"
+		     "	membar			\n"
+		     "	bar			\n"
+		     );
+}
+
+/*****************************************************************************/
+/*
+ * scan for the sequence $<data>#<checksum>
+ */
+static void gdbstub_recv_packet(char *buffer)
+{
+	unsigned char checksum;
+	unsigned char xmitcsum;
+	unsigned char ch;
+	int count, i, ret, error;
+
+	for (;;) {
+		/* wait around for the start character, ignore all other characters */
+		do {
+			gdbstub_rx_char(&ch, 0);
+		} while (ch != '$');
+
+		checksum = 0;
+		xmitcsum = -1;
+		count = 0;
+		error = 0;
+
+		/* now, read until a # or end of buffer is found */
+		while (count < BUFMAX) {
+			ret = gdbstub_rx_char(&ch, 0);
+			if (ret < 0)
+				error = ret;
+
+			if (ch == '#')
+				break;
+			checksum += ch;
+			buffer[count] = ch;
+			count++;
+		}
+
+		if (error == -EIO) {
+			gdbstub_proto("### GDB Rx Error - Skipping packet ###\n");
+			gdbstub_proto("### GDB Tx NAK\n");
+			gdbstub_tx_char('-');
+			continue;
+		}
+
+		if (count >= BUFMAX || error)
+			continue;
+
+		buffer[count] = 0;
+
+		/* read the checksum */
+		ret = gdbstub_rx_char(&ch, 0);
+		if (ret < 0)
+			error = ret;
+		xmitcsum = hex(ch) << 4;
+
+		ret = gdbstub_rx_char(&ch, 0);
+		if (ret < 0)
+			error = ret;
+		xmitcsum |= hex(ch);
+
+		if (error) {
+			if (error == -EIO)
+				gdbstub_proto("### GDB Rx Error - Skipping packet\n");
+			gdbstub_proto("### GDB Tx NAK\n");
+			gdbstub_tx_char('-');
+			continue;
+		}
+
+		/* check the checksum */
+		if (checksum != xmitcsum) {
+			gdbstub_proto("### GDB Tx NAK\n");
+			gdbstub_tx_char('-');	/* failed checksum */
+			continue;
+		}
+
+		gdbstub_proto("### GDB Rx '$%s#%02x' ###\n", buffer, checksum);
+		gdbstub_proto("### GDB Tx ACK\n");
+		gdbstub_tx_char('+'); /* successful transfer */
+
+		/* if a sequence char is present, reply the sequence ID */
+		if (buffer[2] == ':') {
+			gdbstub_tx_char(buffer[0]);
+			gdbstub_tx_char(buffer[1]);
+
+			/* remove sequence chars from buffer */
+			count = 0;
+			while (buffer[count]) count++;
+			for (i=3; i <= count; i++)
+				buffer[i - 3] = buffer[i];
+		}
+
+		break;
+	}
+} /* end gdbstub_recv_packet() */
+
+/*****************************************************************************/
+/*
+ * send the packet in buffer.
+ * - return 0 if successfully ACK'd
+ * - return 1 if abandoned due to new incoming packet
+ */
+static int gdbstub_send_packet(char *buffer)
+{
+	unsigned char checksum;
+	int count;
+	unsigned char ch;
+
+	/* $<packet info>#<checksum> */
+	gdbstub_proto("### GDB Tx '%s' ###\n", buffer);
+
+	do {
+		gdbstub_tx_char('$');
+		checksum = 0;
+		count = 0;
+
+		while ((ch = buffer[count]) != 0) {
+			gdbstub_tx_char(ch);
+			checksum += ch;
+			count += 1;
+		}
+
+		gdbstub_tx_char('#');
+		gdbstub_tx_char(hexchars[checksum >> 4]);
+		gdbstub_tx_char(hexchars[checksum & 0xf]);
+
+	} while (gdbstub_rx_char(&ch,0),
+#ifdef GDBSTUB_DEBUG_PROTOCOL
+		 ch=='-' && (gdbstub_proto("### GDB Rx NAK\n"),0),
+		 ch!='-' && ch!='+' && (gdbstub_proto("### GDB Rx ??? %02x\n",ch),0),
+#endif
+		 ch!='+' && ch!='$');
+
+	if (ch=='+') {
+		gdbstub_proto("### GDB Rx ACK\n");
+		return 0;
+	}
+
+	gdbstub_proto("### GDB Tx Abandoned\n");
+	gdbstub_rx_unget = ch;
+	return 1;
+} /* end gdbstub_send_packet() */
+
+/*
+ * While we find nice hex chars, build an int.
+ * Return number of chars processed.
+ */
+static int hexToInt(char **ptr, unsigned long *_value)
+{
+	int count = 0, ch;
+
+	*_value = 0;
+	while (**ptr) {
+		ch = hex(**ptr);
+		if (ch < 0)
+			break;
+
+		*_value = (*_value << 4) | ((uint8_t) ch & 0xf);
+		count++;
+
+		(*ptr)++;
+	}
+
+	return count;
+}
+
+/*****************************************************************************/
+/*
+ * probe an address to see whether it maps to anything
+ */
+static inline int gdbstub_addr_probe(const void *vaddr)
+{
+#ifdef CONFIG_MMU
+	unsigned long paddr;
+
+	asm("lrad %1,%0,#1,#0,#0" : "=r"(paddr) : "r"(vaddr));
+	if (!(paddr & xAMPRx_V))
+		return 0;
+#endif
+
+	return 1;
+} /* end gdbstub_addr_probe() */
+
+#ifdef CONFIG_MMU
+static unsigned long __saved_dampr, __saved_damlr;
+
+static inline unsigned long gdbstub_virt_to_pte(unsigned long vaddr)
+{
+	pgd_t *pgd;
+	pud_t *pud;
+	pmd_t *pmd;
+	pte_t *pte;
+	unsigned long val, dampr5;
+
+	pgd = (pgd_t *) __get_DAMLR(3) + pgd_index(vaddr);
+	pud = pud_offset(pgd, vaddr);
+	pmd = pmd_offset(pud, vaddr);
+
+	if (pmd_bad(*pmd) || !pmd_present(*pmd))
+		return 0;
+
+	/* make sure dampr5 maps to the correct pmd */
+	dampr5 = __get_DAMPR(5);
+	val = pmd_val(*pmd);
+	__set_DAMPR(5, val | xAMPRx_L | xAMPRx_SS_16Kb | xAMPRx_S | xAMPRx_C | xAMPRx_V);
+
+	/* now its safe to access pmd */
+	pte = (pte_t *)__get_DAMLR(5) + __pte_index(vaddr);
+	if (pte_present(*pte))
+		val = pte_val(*pte);
+	else
+		val = 0;
+
+	/* restore original dampr5 */
+	__set_DAMPR(5, dampr5);
+
+	return val;
+}
+#endif
+
+static inline int gdbstub_addr_map(const void *vaddr)
+{
+#ifdef CONFIG_MMU
+	unsigned long pte;
+
+	__saved_dampr = __get_DAMPR(2);
+	__saved_damlr = __get_DAMLR(2);
+#endif
+	if (gdbstub_addr_probe(vaddr))
+		return 1;
+#ifdef CONFIG_MMU
+	pte = gdbstub_virt_to_pte((unsigned long) vaddr);
+	if (pte) {
+		__set_DAMPR(2, pte);
+		__set_DAMLR(2, (unsigned long) vaddr & PAGE_MASK);
+		return 1;
+	}
+#endif
+	return 0;
+}
+
+static inline void gdbstub_addr_unmap(void)
+{
+#ifdef CONFIG_MMU
+	__set_DAMPR(2, __saved_dampr);
+	__set_DAMLR(2, __saved_damlr);
+#endif
+}
+
+/*
+ * access potentially dodgy memory through a potentially dodgy pointer
+ */
+static inline int gdbstub_read_dword(const void *addr, uint32_t *_res)
+{
+	unsigned long brr;
+	uint32_t res;
+
+	if (!gdbstub_addr_map(addr))
+		return 0;
+
+	asm volatile("	movgs	gr0,brr	\n"
+		     "	ld%I2	%M2,%0	\n"
+		     "	movsg	brr,%1	\n"
+		     : "=r"(res), "=r"(brr)
+		     : "m"(*(uint32_t *) addr));
+	*_res = res;
+	gdbstub_addr_unmap();
+	return likely(!brr);
+}
+
+static inline int gdbstub_write_dword(void *addr, uint32_t val)
+{
+	unsigned long brr;
+
+	if (!gdbstub_addr_map(addr))
+		return 0;
+
+	asm volatile("	movgs	gr0,brr	\n"
+		     "	st%I2	%1,%M2	\n"
+		     "	movsg	brr,%0	\n"
+		     : "=r"(brr)
+		     : "r"(val), "m"(*(uint32_t *) addr));
+	gdbstub_addr_unmap();
+	return likely(!brr);
+}
+
+static inline int gdbstub_read_word(const void *addr, uint16_t *_res)
+{
+	unsigned long brr;
+	uint16_t res;
+
+	if (!gdbstub_addr_map(addr))
+		return 0;
+
+	asm volatile("	movgs	gr0,brr	\n"
+		     "	lduh%I2	%M2,%0	\n"
+		     "	movsg	brr,%1	\n"
+		     : "=r"(res), "=r"(brr)
+		     : "m"(*(uint16_t *) addr));
+	*_res = res;
+	gdbstub_addr_unmap();
+	return likely(!brr);
+}
+
+static inline int gdbstub_write_word(void *addr, uint16_t val)
+{
+	unsigned long brr;
+
+	if (!gdbstub_addr_map(addr))
+		return 0;
+
+	asm volatile("	movgs	gr0,brr	\n"
+		     "	sth%I2	%1,%M2	\n"
+		     "	movsg	brr,%0	\n"
+		     : "=r"(brr)
+		     : "r"(val), "m"(*(uint16_t *) addr));
+	gdbstub_addr_unmap();
+	return likely(!brr);
+}
+
+static inline int gdbstub_read_byte(const void *addr, uint8_t *_res)
+{
+	unsigned long brr;
+	uint8_t res;
+
+	if (!gdbstub_addr_map(addr))
+		return 0;
+
+	asm volatile("	movgs	gr0,brr	\n"
+		     "	ldub%I2	%M2,%0	\n"
+		     "	movsg	brr,%1	\n"
+		     : "=r"(res), "=r"(brr)
+		     : "m"(*(uint8_t *) addr));
+	*_res = res;
+	gdbstub_addr_unmap();
+	return likely(!brr);
+}
+
+static inline int gdbstub_write_byte(void *addr, uint8_t val)
+{
+	unsigned long brr;
+
+	if (!gdbstub_addr_map(addr))
+		return 0;
+
+	asm volatile("	movgs	gr0,brr	\n"
+		     "	stb%I2	%1,%M2	\n"
+		     "	movsg	brr,%0	\n"
+		     : "=r"(brr)
+		     : "r"(val), "m"(*(uint8_t *) addr));
+	gdbstub_addr_unmap();
+	return likely(!brr);
+}
+
+static void __gdbstub_console_write(struct console *co, const char *p, unsigned n)
+{
+	char outbuf[26];
+	int qty;
+
+	outbuf[0] = 'O';
+
+	while (n > 0) {
+		qty = 1;
+
+		while (n > 0 && qty < 20) {
+			mem2hex(p, outbuf + qty, 2, 0);
+			qty += 2;
+			if (*p == 0x0a) {
+				outbuf[qty++] = '0';
+				outbuf[qty++] = 'd';
+			}
+			p++;
+			n--;
+		}
+
+		outbuf[qty] = 0;
+		gdbstub_send_packet(outbuf);
+	}
+}
+
+#if 0
+void debug_to_serial(const char *p, int n)
+{
+	gdbstub_console_write(NULL,p,n);
+}
+#endif
+
+#ifdef CONFIG_GDBSTUB_CONSOLE
+
+static kdev_t gdbstub_console_dev(struct console *con)
+{
+	return MKDEV(1,3); /* /dev/null */
+}
+
+static struct console gdbstub_console = {
+	.name	= "gdb",
+	.write	= gdbstub_console_write,	/* in break.S */
+	.device	= gdbstub_console_dev,
+	.flags	= CON_PRINTBUFFER,
+	.index	= -1,
+};
+
+#endif
+
+/*****************************************************************************/
+/*
+ * Convert the memory pointed to by mem into hex, placing result in buf.
+ * - if successful, return a pointer to the last char put in buf (NUL)
+ * - in case of mem fault, return NULL
+ * may_fault is non-zero if we are reading from arbitrary memory, but is currently
+ * not used.
+ */
+static unsigned char *mem2hex(const void *_mem, char *buf, int count, int may_fault)
+{
+	const uint8_t *mem = _mem;
+	uint8_t ch[4] __attribute__((aligned(4)));
+
+	if ((uint32_t)mem&1 && count>=1) {
+		if (!gdbstub_read_byte(mem,ch))
+			return NULL;
+		*buf++ = hexchars[ch[0] >> 4];
+		*buf++ = hexchars[ch[0] & 0xf];
+		mem++;
+		count--;
+	}
+
+	if ((uint32_t)mem&3 && count>=2) {
+		if (!gdbstub_read_word(mem,(uint16_t *)ch))
+			return NULL;
+		*buf++ = hexchars[ch[0] >> 4];
+		*buf++ = hexchars[ch[0] & 0xf];
+		*buf++ = hexchars[ch[1] >> 4];
+		*buf++ = hexchars[ch[1] & 0xf];
+		mem += 2;
+		count -= 2;
+	}
+
+	while (count>=4) {
+		if (!gdbstub_read_dword(mem,(uint32_t *)ch))
+			return NULL;
+		*buf++ = hexchars[ch[0] >> 4];
+		*buf++ = hexchars[ch[0] & 0xf];
+		*buf++ = hexchars[ch[1] >> 4];
+		*buf++ = hexchars[ch[1] & 0xf];
+		*buf++ = hexchars[ch[2] >> 4];
+		*buf++ = hexchars[ch[2] & 0xf];
+		*buf++ = hexchars[ch[3] >> 4];
+		*buf++ = hexchars[ch[3] & 0xf];
+		mem += 4;
+		count -= 4;
+	}
+
+	if (count>=2) {
+		if (!gdbstub_read_word(mem,(uint16_t *)ch))
+			return NULL;
+		*buf++ = hexchars[ch[0] >> 4];
+		*buf++ = hexchars[ch[0] & 0xf];
+		*buf++ = hexchars[ch[1] >> 4];
+		*buf++ = hexchars[ch[1] & 0xf];
+		mem += 2;
+		count -= 2;
+	}
+
+	if (count>=1) {
+		if (!gdbstub_read_byte(mem,ch))
+			return NULL;
+		*buf++ = hexchars[ch[0] >> 4];
+		*buf++ = hexchars[ch[0] & 0xf];
+	}
+
+	*buf = 0;
+
+	return buf;
+} /* end mem2hex() */
+
+/*****************************************************************************/
+/*
+ * convert the hex array pointed to by buf into binary to be placed in mem
+ * return a pointer to the character AFTER the last byte of buffer consumed
+ */
+static char *hex2mem(const char *buf, void *_mem, int count)
+{
+	uint8_t *mem = _mem;
+	union {
+		uint32_t l;
+		uint16_t w;
+		uint8_t  b[4];
+	} ch;
+
+	if ((u32)mem&1 && count>=1) {
+		ch.b[0]  = hex(*buf++) << 4;
+		ch.b[0] |= hex(*buf++);
+		if (!gdbstub_write_byte(mem,ch.b[0]))
+			return NULL;
+		mem++;
+		count--;
+	}
+
+	if ((u32)mem&3 && count>=2) {
+		ch.b[0]  = hex(*buf++) << 4;
+		ch.b[0] |= hex(*buf++);
+		ch.b[1]  = hex(*buf++) << 4;
+		ch.b[1] |= hex(*buf++);
+		if (!gdbstub_write_word(mem,ch.w))
+			return NULL;
+		mem += 2;
+		count -= 2;
+	}
+
+	while (count>=4) {
+		ch.b[0]  = hex(*buf++) << 4;
+		ch.b[0] |= hex(*buf++);
+		ch.b[1]  = hex(*buf++) << 4;
+		ch.b[1] |= hex(*buf++);
+		ch.b[2]  = hex(*buf++) << 4;
+		ch.b[2] |= hex(*buf++);
+		ch.b[3]  = hex(*buf++) << 4;
+		ch.b[3] |= hex(*buf++);
+		if (!gdbstub_write_dword(mem,ch.l))
+			return NULL;
+		mem += 4;
+		count -= 4;
+	}
+
+	if (count>=2) {
+		ch.b[0]  = hex(*buf++) << 4;
+		ch.b[0] |= hex(*buf++);
+		ch.b[1]  = hex(*buf++) << 4;
+		ch.b[1] |= hex(*buf++);
+		if (!gdbstub_write_word(mem,ch.w))
+			return NULL;
+		mem += 2;
+		count -= 2;
+	}
+
+	if (count>=1) {
+		ch.b[0]  = hex(*buf++) << 4;
+		ch.b[0] |= hex(*buf++);
+		if (!gdbstub_write_byte(mem,ch.b[0]))
+			return NULL;
+	}
+
+	return (char *) buf;
+} /* end hex2mem() */
+
+/*****************************************************************************/
+/*
+ * This table contains the mapping between FRV TBR.TT exception codes,
+ * and signals, which are primarily what GDB understands.  It also
+ * indicates which hardware traps we need to commandeer when
+ * initializing the stub.
+ */
+static const struct brr_to_sig_map {
+	unsigned long	brr_mask;	/* BRR bitmask */
+	unsigned long	tbr_tt;		/* TBR.TT code (in BRR.EBTT) */
+	unsigned int	signo;		/* Signal that we map this into */
+} brr_to_sig_map[] = {
+	{ BRR_EB,	TBR_TT_INSTR_ACC_ERROR,	SIGSEGV		},
+	{ BRR_EB,	TBR_TT_ILLEGAL_INSTR,	SIGILL		},
+	{ BRR_EB,	TBR_TT_PRIV_INSTR,	SIGILL		},
+	{ BRR_EB,	TBR_TT_MP_EXCEPTION,	SIGFPE		},
+	{ BRR_EB,	TBR_TT_DATA_ACC_ERROR,	SIGSEGV		},
+	{ BRR_EB,	TBR_TT_DATA_STR_ERROR,	SIGSEGV		},
+	{ BRR_EB,	TBR_TT_DIVISION_EXCEP,	SIGFPE		},
+	{ BRR_EB,	TBR_TT_COMPOUND_EXCEP,	SIGSEGV		},
+	{ BRR_EB,	TBR_TT_INTERRUPT_13,	SIGALRM		},	/* watchdog */
+	{ BRR_EB,	TBR_TT_INTERRUPT_14,	SIGINT		},	/* GDB serial */
+	{ BRR_EB,	TBR_TT_INTERRUPT_15,	SIGQUIT		},	/* NMI */
+	{ BRR_CB,	0,			SIGUSR1		},
+	{ BRR_TB,	0,			SIGUSR2		},
+	{ BRR_DBNEx,	0,			SIGTRAP		},
+	{ BRR_DBx,	0,			SIGTRAP		},	/* h/w watchpoint */
+	{ BRR_IBx,	0,			SIGTRAP		},	/* h/w breakpoint */
+	{ BRR_CBB,	0,			SIGTRAP		},
+	{ BRR_SB,	0,			SIGTRAP		},
+	{ BRR_ST,	0,			SIGTRAP		},	/* single step */
+	{ 0,		0,			SIGHUP		}	/* default */
+};
+
+/*****************************************************************************/
+/*
+ * convert the FRV BRR register contents into a UNIX signal number
+ */
+static inline int gdbstub_compute_signal(unsigned long brr)
+{
+	const struct brr_to_sig_map *map;
+	unsigned long tbr = (brr & BRR_EBTT) >> 12;
+
+	for (map = brr_to_sig_map; map->brr_mask; map++)
+		if (map->brr_mask & brr)
+			if (!map->tbr_tt || map->tbr_tt == tbr)
+				break;
+
+	return map->signo;
+} /* end gdbstub_compute_signal() */
+
+/*****************************************************************************/
+/*
+ * set a software breakpoint or a hardware breakpoint or watchpoint
+ */
+static int gdbstub_set_breakpoint(unsigned long type, unsigned long addr, unsigned long len)
+{
+	unsigned long tmp;
+	int bkpt, loop, xloop;
+
+	union {
+		struct {
+			unsigned long mask0, mask1;
+		};
+		uint8_t bytes[8];
+	} dbmr;
+
+	//gdbstub_printk("setbkpt(%ld,%08lx,%ld)\n", type, addr, len);
+
+	switch (type) {
+		/* set software breakpoint */
+	case 0:
+		if (addr & 3 || len > 7*4)
+			return -EINVAL;
+
+		for (bkpt = 255; bkpt >= 0; bkpt--)
+			if (!gdbstub_bkpts[bkpt].addr)
+				break;
+		if (bkpt < 0)
+			return -ENOSPC;
+
+		for (loop = 0; loop < len/4; loop++)
+			if (!gdbstub_read_dword(&((uint32_t *) addr)[loop],
+						&gdbstub_bkpts[bkpt].originsns[loop]))
+				return -EFAULT;
+
+		for (loop = 0; loop < len/4; loop++)
+			if (!gdbstub_write_dword(&((uint32_t *) addr)[loop],
+						 BREAK_INSN)
+			    ) {
+				/* need to undo the changes if possible */
+				for (xloop = 0; xloop < loop; xloop++)
+					gdbstub_write_dword(&((uint32_t *) addr)[xloop],
+							    gdbstub_bkpts[bkpt].originsns[xloop]);
+				return -EFAULT;
+			}
+
+		gdbstub_bkpts[bkpt].addr = addr;
+		gdbstub_bkpts[bkpt].len = len;
+
+#if 0
+		gdbstub_printk("Set BKPT[%02x]: %08lx #%d {%04x, %04x} -> { %04x, %04x }\n",
+			       bkpt,
+			       gdbstub_bkpts[bkpt].addr,
+			       gdbstub_bkpts[bkpt].len,
+			       gdbstub_bkpts[bkpt].originsns[0],
+			       gdbstub_bkpts[bkpt].originsns[1],
+			       ((uint32_t *) addr)[0],
+			       ((uint32_t *) addr)[1]
+			       );
+#endif
+		return 0;
+
+		/* set hardware breakpoint */
+	case 1:
+		if (addr & 3 || len != 4)
+			return -EINVAL;
+
+		if (!(__debug_regs->dcr & DCR_IBE0)) {
+			//gdbstub_printk("set h/w break 0: %08lx\n", addr);
+			__debug_regs->dcr |= DCR_IBE0;
+			asm volatile("movgs %0,ibar0" : : "r"(addr));
+			return 0;
+		}
+
+		if (!(__debug_regs->dcr & DCR_IBE1)) {
+			//gdbstub_printk("set h/w break 1: %08lx\n", addr);
+			__debug_regs->dcr |= DCR_IBE1;
+			asm volatile("movgs %0,ibar1" : : "r"(addr));
+			return 0;
+		}
+
+		if (!(__debug_regs->dcr & DCR_IBE2)) {
+			//gdbstub_printk("set h/w break 2: %08lx\n", addr);
+			__debug_regs->dcr |= DCR_IBE2;
+			asm volatile("movgs %0,ibar2" : : "r"(addr));
+			return 0;
+		}
+
+		if (!(__debug_regs->dcr & DCR_IBE3)) {
+			//gdbstub_printk("set h/w break 3: %08lx\n", addr);
+			__debug_regs->dcr |= DCR_IBE3;
+			asm volatile("movgs %0,ibar3" : : "r"(addr));
+			return 0;
+		}
+
+		return -ENOSPC;
+
+		/* set data read/write/access watchpoint */
+	case 2:
+	case 3:
+	case 4:
+		if ((addr & ~7) != ((addr + len - 1) & ~7))
+			return -EINVAL;
+
+		tmp = addr & 7;
+
+		memset(dbmr.bytes, 0xff, sizeof(dbmr.bytes));
+		for (loop = 0; loop < len; loop++)
+			dbmr.bytes[tmp + loop] = 0;
+
+		addr &= ~7;
+
+		if (!(__debug_regs->dcr & (DCR_DRBE0|DCR_DWBE0))) {
+			//gdbstub_printk("set h/w watchpoint 0 type %ld: %08lx\n", type, addr);
+			tmp = type==2 ? DCR_DWBE0 : type==3 ? DCR_DRBE0 : DCR_DRBE0|DCR_DWBE0;
+			__debug_regs->dcr |= tmp;
+			asm volatile("	movgs	%0,dbar0	\n"
+				     "	movgs	%1,dbmr00	\n"
+				     "	movgs	%2,dbmr01	\n"
+				     "	movgs	gr0,dbdr00	\n"
+				     "	movgs	gr0,dbdr01	\n"
+				     : : "r"(addr), "r"(dbmr.mask0), "r"(dbmr.mask1));
+			return 0;
+		}
+
+		if (!(__debug_regs->dcr & (DCR_DRBE1|DCR_DWBE1))) {
+			//gdbstub_printk("set h/w watchpoint 1 type %ld: %08lx\n", type, addr);
+			tmp = type==2 ? DCR_DWBE1 : type==3 ? DCR_DRBE1 : DCR_DRBE1|DCR_DWBE1;
+			__debug_regs->dcr |= tmp;
+			asm volatile("	movgs	%0,dbar1	\n"
+				     "	movgs	%1,dbmr10	\n"
+				     "	movgs	%2,dbmr11	\n"
+				     "	movgs	gr0,dbdr10	\n"
+				     "	movgs	gr0,dbdr11	\n"
+				     : : "r"(addr), "r"(dbmr.mask0), "r"(dbmr.mask1));
+			return 0;
+		}
+
+		return -ENOSPC;
+
+	default:
+		return -EINVAL;
+	}
+
+} /* end gdbstub_set_breakpoint() */
+
+/*****************************************************************************/
+/*
+ * clear a breakpoint or watchpoint
+ */
+int gdbstub_clear_breakpoint(unsigned long type, unsigned long addr, unsigned long len)
+{
+	unsigned long tmp;
+	int bkpt, loop;
+
+	union {
+		struct {
+			unsigned long mask0, mask1;
+		};
+		uint8_t bytes[8];
+	} dbmr;
+
+	//gdbstub_printk("clearbkpt(%ld,%08lx,%ld)\n", type, addr, len);
+
+	switch (type) {
+		/* clear software breakpoint */
+	case 0:
+		for (bkpt = 255; bkpt >= 0; bkpt--)
+			if (gdbstub_bkpts[bkpt].addr == addr && gdbstub_bkpts[bkpt].len == len)
+				break;
+		if (bkpt < 0)
+			return -ENOENT;
+
+		gdbstub_bkpts[bkpt].addr = 0;
+
+		for (loop = 0; loop < len/4; loop++)
+			if (!gdbstub_write_dword(&((uint32_t *) addr)[loop],
+						 gdbstub_bkpts[bkpt].originsns[loop]))
+				return -EFAULT;
+		return 0;
+
+		/* clear hardware breakpoint */
+	case 1:
+		if (addr & 3 || len != 4)
+			return -EINVAL;
+
+#define __get_ibar(X) ({ unsigned long x; asm volatile("movsg ibar"#X",%0" : "=r"(x)); x; })
+
+		if (__debug_regs->dcr & DCR_IBE0 && __get_ibar(0) == addr) {
+			//gdbstub_printk("clear h/w break 0: %08lx\n", addr);
+			__debug_regs->dcr &= ~DCR_IBE0;
+			asm volatile("movgs gr0,ibar0");
+			return 0;
+		}
+
+		if (__debug_regs->dcr & DCR_IBE1 && __get_ibar(1) == addr) {
+			//gdbstub_printk("clear h/w break 1: %08lx\n", addr);
+			__debug_regs->dcr &= ~DCR_IBE1;
+			asm volatile("movgs gr0,ibar1");
+			return 0;
+		}
+
+		if (__debug_regs->dcr & DCR_IBE2 && __get_ibar(2) == addr) {
+			//gdbstub_printk("clear h/w break 2: %08lx\n", addr);
+			__debug_regs->dcr &= ~DCR_IBE2;
+			asm volatile("movgs gr0,ibar2");
+			return 0;
+		}
+
+		if (__debug_regs->dcr & DCR_IBE3 && __get_ibar(3) == addr) {
+			//gdbstub_printk("clear h/w break 3: %08lx\n", addr);
+			__debug_regs->dcr &= ~DCR_IBE3;
+			asm volatile("movgs gr0,ibar3");
+			return 0;
+		}
+
+		return -EINVAL;
+
+		/* clear data read/write/access watchpoint */
+	case 2:
+	case 3:
+	case 4:
+		if ((addr & ~7) != ((addr + len - 1) & ~7))
+			return -EINVAL;
+
+		tmp = addr & 7;
+
+		memset(dbmr.bytes, 0xff, sizeof(dbmr.bytes));
+		for (loop = 0; loop < len; loop++)
+			dbmr.bytes[tmp + loop] = 0;
+
+		addr &= ~7;
+
+#define __get_dbar(X) ({ unsigned long x; asm volatile("movsg dbar"#X",%0" : "=r"(x)); x; })
+#define __get_dbmr0(X) ({ unsigned long x; asm volatile("movsg dbmr"#X"0,%0" : "=r"(x)); x; })
+#define __get_dbmr1(X) ({ unsigned long x; asm volatile("movsg dbmr"#X"1,%0" : "=r"(x)); x; })
+
+		/* consider DBAR 0 */
+		tmp = type==2 ? DCR_DWBE0 : type==3 ? DCR_DRBE0 : DCR_DRBE0|DCR_DWBE0;
+
+		if ((__debug_regs->dcr & (DCR_DRBE0|DCR_DWBE0)) != tmp ||
+		    __get_dbar(0) != addr ||
+		    __get_dbmr0(0) != dbmr.mask0 ||
+		    __get_dbmr1(0) != dbmr.mask1)
+			goto skip_dbar0;
+
+		//gdbstub_printk("clear h/w watchpoint 0 type %ld: %08lx\n", type, addr);
+		__debug_regs->dcr &= ~(DCR_DRBE0|DCR_DWBE0);
+		asm volatile("	movgs	gr0,dbar0	\n"
+			     "	movgs	gr0,dbmr00	\n"
+			     "	movgs	gr0,dbmr01	\n"
+			     "	movgs	gr0,dbdr00	\n"
+			     "	movgs	gr0,dbdr01	\n");
+		return 0;
+
+	skip_dbar0:
+		/* consider DBAR 0 */
+		tmp = type==2 ? DCR_DWBE1 : type==3 ? DCR_DRBE1 : DCR_DRBE1|DCR_DWBE1;
+
+		if ((__debug_regs->dcr & (DCR_DRBE1|DCR_DWBE1)) != tmp ||
+		    __get_dbar(1) != addr ||
+		    __get_dbmr0(1) != dbmr.mask0 ||
+		    __get_dbmr1(1) != dbmr.mask1)
+			goto skip_dbar1;
+
+		//gdbstub_printk("clear h/w watchpoint 1 type %ld: %08lx\n", type, addr);
+		__debug_regs->dcr &= ~(DCR_DRBE1|DCR_DWBE1);
+		asm volatile("	movgs	gr0,dbar1	\n"
+			     "	movgs	gr0,dbmr10	\n"
+			     "	movgs	gr0,dbmr11	\n"
+			     "	movgs	gr0,dbdr10	\n"
+			     "	movgs	gr0,dbdr11	\n");
+		return 0;
+
+	skip_dbar1:
+		return -ENOSPC;
+
+	default:
+		return -EINVAL;
+	}
+} /* end gdbstub_clear_breakpoint() */
+
+/*****************************************************************************/
+/*
+ * check a for an internal software breakpoint, and wind the PC back if necessary
+ */
+static void gdbstub_check_breakpoint(void)
+{
+	unsigned long addr = __debug_frame->pc - 4;
+	int bkpt;
+
+	for (bkpt = 255; bkpt >= 0; bkpt--)
+		if (gdbstub_bkpts[bkpt].addr == addr)
+			break;
+	if (bkpt >= 0)
+		__debug_frame->pc = addr;
+
+	//gdbstub_printk("alter pc [%d] %08lx\n", bkpt, __debug_frame->pc);
+
+} /* end gdbstub_check_breakpoint() */
+
+/*****************************************************************************/
+/*
+ *
+ */
+static void __attribute__((unused)) gdbstub_show_regs(void)
+{
+	uint32_t *reg;
+	int loop;
+
+	gdbstub_printk("\n");
+
+	gdbstub_printk("Frame: @%p [%s]\n",
+		       __debug_frame,
+		       __debug_frame->psr & PSR_S ? "kernel" : "user");
+
+	reg = (uint32_t *) __debug_frame;
+	for (loop = 0; loop < REG__END; loop++) {
+		printk("%s %08x", regnames[loop + 0], reg[loop + 0]);
+
+		if (loop == REG__END - 1 || loop % 5 == 4)
+			printk("\n");
+		else
+			printk(" | ");
+	}
+
+	gdbstub_printk("Process %s (pid: %d)\n", current->comm, current->pid);
+} /* end gdbstub_show_regs() */
+
+/*****************************************************************************/
+/*
+ * dump debugging regs
+ */
+static void __attribute__((unused)) gdbstub_dump_debugregs(void)
+{
+	unsigned long x;
+
+	x = __debug_regs->dcr;
+	gdbstub_printk("DCR    %08lx  ", x);
+
+	x = __debug_regs->brr;
+	gdbstub_printk("BRR %08lx\n", x);
+
+	gdbstub_printk("IBAR0  %08lx  ", __get_ibar(0));
+	gdbstub_printk("IBAR1  %08lx  ", __get_ibar(1));
+	gdbstub_printk("IBAR2  %08lx  ", __get_ibar(2));
+	gdbstub_printk("IBAR3  %08lx\n", __get_ibar(3));
+
+	gdbstub_printk("DBAR0  %08lx  ", __get_dbar(0));
+	gdbstub_printk("DBMR00 %08lx  ", __get_dbmr0(0));
+	gdbstub_printk("DBMR01 %08lx\n", __get_dbmr1(0));
+
+	gdbstub_printk("DBAR1  %08lx  ", __get_dbar(1));
+	gdbstub_printk("DBMR10 %08lx  ", __get_dbmr0(1));
+	gdbstub_printk("DBMR11 %08lx\n", __get_dbmr1(1));
+
+	gdbstub_printk("\n");
+} /* end gdbstub_dump_debugregs() */
+
+/*****************************************************************************/
+/*
+ * dump the MMU state into a structure so that it can be accessed with GDB
+ */
+void gdbstub_get_mmu_state(void)
+{
+	asm volatile("movsg hsr0,%0" : "=r"(__debug_mmu.regs.hsr0));
+	asm volatile("movsg pcsr,%0" : "=r"(__debug_mmu.regs.pcsr));
+	asm volatile("movsg esr0,%0" : "=r"(__debug_mmu.regs.esr0));
+	asm volatile("movsg ear0,%0" : "=r"(__debug_mmu.regs.ear0));
+	asm volatile("movsg epcr0,%0" : "=r"(__debug_mmu.regs.epcr0));
+
+	/* read the protection / SAT registers */
+	__debug_mmu.iamr[0].L  = __get_IAMLR(0);
+	__debug_mmu.iamr[0].P  = __get_IAMPR(0);
+	__debug_mmu.iamr[1].L  = __get_IAMLR(1);
+	__debug_mmu.iamr[1].P  = __get_IAMPR(1);
+	__debug_mmu.iamr[2].L  = __get_IAMLR(2);
+	__debug_mmu.iamr[2].P  = __get_IAMPR(2);
+	__debug_mmu.iamr[3].L  = __get_IAMLR(3);
+	__debug_mmu.iamr[3].P  = __get_IAMPR(3);
+	__debug_mmu.iamr[4].L  = __get_IAMLR(4);
+	__debug_mmu.iamr[4].P  = __get_IAMPR(4);
+	__debug_mmu.iamr[5].L  = __get_IAMLR(5);
+	__debug_mmu.iamr[5].P  = __get_IAMPR(5);
+	__debug_mmu.iamr[6].L  = __get_IAMLR(6);
+	__debug_mmu.iamr[6].P  = __get_IAMPR(6);
+	__debug_mmu.iamr[7].L  = __get_IAMLR(7);
+	__debug_mmu.iamr[7].P  = __get_IAMPR(7);
+	__debug_mmu.iamr[8].L  = __get_IAMLR(8);
+	__debug_mmu.iamr[8].P  = __get_IAMPR(8);
+	__debug_mmu.iamr[9].L  = __get_IAMLR(9);
+	__debug_mmu.iamr[9].P  = __get_IAMPR(9);
+	__debug_mmu.iamr[10].L = __get_IAMLR(10);
+	__debug_mmu.iamr[10].P = __get_IAMPR(10);
+	__debug_mmu.iamr[11].L = __get_IAMLR(11);
+	__debug_mmu.iamr[11].P = __get_IAMPR(11);
+	__debug_mmu.iamr[12].L = __get_IAMLR(12);
+	__debug_mmu.iamr[12].P = __get_IAMPR(12);
+	__debug_mmu.iamr[13].L = __get_IAMLR(13);
+	__debug_mmu.iamr[13].P = __get_IAMPR(13);
+	__debug_mmu.iamr[14].L = __get_IAMLR(14);
+	__debug_mmu.iamr[14].P = __get_IAMPR(14);
+	__debug_mmu.iamr[15].L = __get_IAMLR(15);
+	__debug_mmu.iamr[15].P = __get_IAMPR(15);
+
+	__debug_mmu.damr[0].L  = __get_DAMLR(0);
+	__debug_mmu.damr[0].P  = __get_DAMPR(0);
+	__debug_mmu.damr[1].L  = __get_DAMLR(1);
+	__debug_mmu.damr[1].P  = __get_DAMPR(1);
+	__debug_mmu.damr[2].L  = __get_DAMLR(2);
+	__debug_mmu.damr[2].P  = __get_DAMPR(2);
+	__debug_mmu.damr[3].L  = __get_DAMLR(3);
+	__debug_mmu.damr[3].P  = __get_DAMPR(3);
+	__debug_mmu.damr[4].L  = __get_DAMLR(4);
+	__debug_mmu.damr[4].P  = __get_DAMPR(4);
+	__debug_mmu.damr[5].L  = __get_DAMLR(5);
+	__debug_mmu.damr[5].P  = __get_DAMPR(5);
+	__debug_mmu.damr[6].L  = __get_DAMLR(6);
+	__debug_mmu.damr[6].P  = __get_DAMPR(6);
+	__debug_mmu.damr[7].L  = __get_DAMLR(7);
+	__debug_mmu.damr[7].P  = __get_DAMPR(7);
+	__debug_mmu.damr[8].L  = __get_DAMLR(8);
+	__debug_mmu.damr[8].P  = __get_DAMPR(8);
+	__debug_mmu.damr[9].L  = __get_DAMLR(9);
+	__debug_mmu.damr[9].P  = __get_DAMPR(9);
+	__debug_mmu.damr[10].L = __get_DAMLR(10);
+	__debug_mmu.damr[10].P = __get_DAMPR(10);
+	__debug_mmu.damr[11].L = __get_DAMLR(11);
+	__debug_mmu.damr[11].P = __get_DAMPR(11);
+	__debug_mmu.damr[12].L = __get_DAMLR(12);
+	__debug_mmu.damr[12].P = __get_DAMPR(12);
+	__debug_mmu.damr[13].L = __get_DAMLR(13);
+	__debug_mmu.damr[13].P = __get_DAMPR(13);
+	__debug_mmu.damr[14].L = __get_DAMLR(14);
+	__debug_mmu.damr[14].P = __get_DAMPR(14);
+	__debug_mmu.damr[15].L = __get_DAMLR(15);
+	__debug_mmu.damr[15].P = __get_DAMPR(15);
+
+#ifdef CONFIG_MMU
+	do {
+		/* read the DAT entries from the TLB */
+		struct __debug_amr *p;
+		int loop;
+
+		asm volatile("movsg tplr,%0" : "=r"(__debug_mmu.regs.tplr));
+		asm volatile("movsg tppr,%0" : "=r"(__debug_mmu.regs.tppr));
+		asm volatile("movsg tpxr,%0" : "=r"(__debug_mmu.regs.tpxr));
+		asm volatile("movsg cxnr,%0" : "=r"(__debug_mmu.regs.cxnr));
+
+		p = __debug_mmu.tlb;
+
+		/* way 0 */
+		asm volatile("movgs %0,tpxr" :: "r"(0 << TPXR_WAY_SHIFT));
+		for (loop = 0; loop < 64; loop++) {
+			asm volatile("tlbpr %0,gr0,#1,#0" :: "r"(loop << PAGE_SHIFT));
+			asm volatile("movsg tplr,%0" : "=r"(p->L));
+			asm volatile("movsg tppr,%0" : "=r"(p->P));
+			p++;
+		}
+
+		/* way 1 */
+		asm volatile("movgs %0,tpxr" :: "r"(1 << TPXR_WAY_SHIFT));
+		for (loop = 0; loop < 64; loop++) {
+			asm volatile("tlbpr %0,gr0,#1,#0" :: "r"(loop << PAGE_SHIFT));
+			asm volatile("movsg tplr,%0" : "=r"(p->L));
+			asm volatile("movsg tppr,%0" : "=r"(p->P));
+			p++;
+		}
+
+		asm volatile("movgs %0,tplr" :: "r"(__debug_mmu.regs.tplr));
+		asm volatile("movgs %0,tppr" :: "r"(__debug_mmu.regs.tppr));
+		asm volatile("movgs %0,tpxr" :: "r"(__debug_mmu.regs.tpxr));
+	} while(0);
+#endif
+
+} /* end gdbstub_get_mmu_state() */
+
+/*****************************************************************************/
+/*
+ * handle event interception and GDB remote protocol processing
+ * - on entry:
+ *	PSR.ET==0, PSR.S==1 and the CPU is in debug mode
+ *	__debug_frame points to the saved registers
+ *	__frame points to the kernel mode exception frame, if it was in kernel
+ *      mode when the break happened
+ */
+void gdbstub(int sigval)
+{
+	unsigned long addr, length, loop, dbar, temp, temp2, temp3;
+	uint32_t zero;
+	char *ptr;
+	int flush_cache = 0;
+
+	LEDS(0x5000);
+
+	if (sigval < 0) {
+#ifndef CONFIG_GDBSTUB_IMMEDIATE
+		/* return immediately if GDB immediate activation option not set */
+		return;
+#else
+		sigval = SIGINT;
+#endif
+	}
+
+	save_user_regs(&__break_user_context);
+
+#if 0
+	gdbstub_printk("--> gdbstub() %08x %p %08x %08x\n",
+		       __debug_frame->pc,
+		       __debug_frame,
+		       __debug_regs->brr,
+		       __debug_regs->bpsr);
+//	gdbstub_show_regs();
+#endif
+
+	LEDS(0x5001);
+
+	/* if we were interrupted by input on the serial gdbstub serial port,
+	 * restore the context prior to the interrupt so that we return to that
+	 * directly
+	 */
+	temp = (unsigned long) __entry_kerneltrap_table;
+	temp2 = (unsigned long) __entry_usertrap_table;
+	temp3 = __debug_frame->pc & ~15;
+
+	if (temp3 == temp + TBR_TT_INTERRUPT_15 ||
+	    temp3 == temp2 + TBR_TT_INTERRUPT_15
+	    ) {
+		asm volatile("movsg pcsr,%0" : "=r"(__debug_frame->pc));
+		__debug_frame->psr |= PSR_ET;
+		__debug_frame->psr &= ~PSR_S;
+		if (__debug_frame->psr & PSR_PS)
+			__debug_frame->psr |= PSR_S;
+		__debug_regs->brr = (__debug_frame->tbr & TBR_TT) << 12;
+		__debug_regs->brr |= BRR_EB;
+		sigval = SIGINT;
+	}
+
+	/* handle the decrement timer going off (FR451 only) */
+	if (temp3 == temp + TBR_TT_DECREMENT_TIMER ||
+	    temp3 == temp2 + TBR_TT_DECREMENT_TIMER
+	    ) {
+		asm volatile("movgs %0,timerd" :: "r"(10000000));
+		asm volatile("movsg pcsr,%0" : "=r"(__debug_frame->pc));
+		__debug_frame->psr |= PSR_ET;
+		__debug_frame->psr &= ~PSR_S;
+		if (__debug_frame->psr & PSR_PS)
+			__debug_frame->psr |= PSR_S;
+		__debug_regs->brr = (__debug_frame->tbr & TBR_TT) << 12;
+		__debug_regs->brr |= BRR_EB;
+		sigval = SIGXCPU;;
+	}
+
+	LEDS(0x5002);
+
+	/* after a BREAK insn, the PC lands on the far side of it */
+	if (__debug_regs->brr & BRR_SB)
+		gdbstub_check_breakpoint();
+
+	LEDS(0x5003);
+
+	/* handle attempts to write console data via GDB "O" commands */
+	if (__debug_frame->pc == (unsigned long) gdbstub_console_write + 4) {
+		__gdbstub_console_write((struct console *) __debug_frame->gr8,
+					(const char *) __debug_frame->gr9,
+					(unsigned) __debug_frame->gr10);
+		goto done;
+	}
+
+	if (gdbstub_rx_unget) {
+		sigval = SIGINT;
+		goto packet_waiting;
+	}
+
+	if (!sigval)
+		sigval = gdbstub_compute_signal(__debug_regs->brr);
+
+	LEDS(0x5004);
+
+	/* send a message to the debugger's user saying what happened if it may
+	 * not be clear cut (we can't map exceptions onto signals properly)
+	 */
+	if (sigval != SIGINT && sigval != SIGTRAP && sigval != SIGILL) {
+		static const char title[] = "Break ";
+		static const char crlf[] = "\r\n";
+		unsigned long brr = __debug_regs->brr;
+		char hx;
+
+		ptr = output_buffer;
+		*ptr++ = 'O';
+		ptr = mem2hex(title, ptr, sizeof(title) - 1,0);
+
+		hx = hexchars[(brr & 0xf0000000) >> 28];
+		*ptr++ = hexchars[hx >> 4];	*ptr++ = hexchars[hx & 0xf];
+		hx = hexchars[(brr & 0x0f000000) >> 24];
+		*ptr++ = hexchars[hx >> 4];	*ptr++ = hexchars[hx & 0xf];
+		hx = hexchars[(brr & 0x00f00000) >> 20];
+		*ptr++ = hexchars[hx >> 4];	*ptr++ = hexchars[hx & 0xf];
+		hx = hexchars[(brr & 0x000f0000) >> 16];
+		*ptr++ = hexchars[hx >> 4];	*ptr++ = hexchars[hx & 0xf];
+		hx = hexchars[(brr & 0x0000f000) >> 12];
+		*ptr++ = hexchars[hx >> 4];	*ptr++ = hexchars[hx & 0xf];
+		hx = hexchars[(brr & 0x00000f00) >> 8];
+		*ptr++ = hexchars[hx >> 4];	*ptr++ = hexchars[hx & 0xf];
+		hx = hexchars[(brr & 0x000000f0) >> 4];
+		*ptr++ = hexchars[hx >> 4];	*ptr++ = hexchars[hx & 0xf];
+		hx = hexchars[(brr & 0x0000000f)];
+		*ptr++ = hexchars[hx >> 4];	*ptr++ = hexchars[hx & 0xf];
+
+		ptr = mem2hex(crlf, ptr, sizeof(crlf) - 1, 0);
+		*ptr = 0;
+		gdbstub_send_packet(output_buffer);	/* send it off... */
+	}
+
+	LEDS(0x5005);
+
+	/* tell the debugger that an exception has occurred */
+	ptr = output_buffer;
+
+	/* Send trap type (converted to signal) */
+	*ptr++ = 'T';
+	*ptr++ = hexchars[sigval >> 4];
+	*ptr++ = hexchars[sigval & 0xf];
+
+	/* Send Error PC */
+	*ptr++ = hexchars[GDB_REG_PC >> 4];
+	*ptr++ = hexchars[GDB_REG_PC & 0xf];
+	*ptr++ = ':';
+	ptr = mem2hex(&__debug_frame->pc, ptr, 4, 0);
+	*ptr++ = ';';
+
+	/*
+	 * Send frame pointer
+	 */
+	*ptr++ = hexchars[GDB_REG_FP >> 4];
+	*ptr++ = hexchars[GDB_REG_FP & 0xf];
+	*ptr++ = ':';
+	ptr = mem2hex(&__debug_frame->fp, ptr, 4, 0);
+	*ptr++ = ';';
+
+	/*
+	 * Send stack pointer
+	 */
+	*ptr++ = hexchars[GDB_REG_SP >> 4];
+	*ptr++ = hexchars[GDB_REG_SP & 0xf];
+	*ptr++ = ':';
+	ptr = mem2hex(&__debug_frame->sp, ptr, 4, 0);
+	*ptr++ = ';';
+
+	*ptr++ = 0;
+	gdbstub_send_packet(output_buffer);	/* send it off... */
+
+	LEDS(0x5006);
+
+ packet_waiting:
+	gdbstub_get_mmu_state();
+
+	/* wait for input from remote GDB */
+	while (1) {
+		output_buffer[0] = 0;
+
+		LEDS(0x5007);
+		gdbstub_recv_packet(input_buffer);
+		LEDS(0x5600 | input_buffer[0]);
+
+		switch (input_buffer[0]) {
+			/* request repeat of last signal number */
+		case '?':
+			output_buffer[0] = 'S';
+			output_buffer[1] = hexchars[sigval >> 4];
+			output_buffer[2] = hexchars[sigval & 0xf];
+			output_buffer[3] = 0;
+			break;
+
+		case 'd':
+			/* toggle debug flag */
+			break;
+
+			/* return the value of the CPU registers
+			 * - GR0,  GR1,  GR2,  GR3,  GR4,  GR5,  GR6,  GR7,
+			 * - GR8,  GR9,  GR10, GR11, GR12, GR13, GR14, GR15,
+			 * - GR16, GR17, GR18, GR19, GR20, GR21, GR22, GR23,
+			 * - GR24, GR25, GR26, GR27, GR28, GR29, GR30, GR31,
+			 * - GR32, GR33, GR34, GR35, GR36, GR37, GR38, GR39,
+			 * - GR40, GR41, GR42, GR43, GR44, GR45, GR46, GR47,
+			 * - GR48, GR49, GR50, GR51, GR52, GR53, GR54, GR55,
+			 * - GR56, GR57, GR58, GR59, GR60, GR61, GR62, GR63,
+			 * - FP0,  FP1,  FP2,  FP3,  FP4,  FP5,  FP6,  FP7,
+			 * - FP8,  FP9,  FP10, FP11, FP12, FP13, FP14, FP15,
+			 * - FP16, FP17, FP18, FP19, FP20, FP21, FP22, FP23,
+			 * - FP24, FP25, FP26, FP27, FP28, FP29, FP30, FP31,
+			 * - FP32, FP33, FP34, FP35, FP36, FP37, FP38, FP39,
+			 * - FP40, FP41, FP42, FP43, FP44, FP45, FP46, FP47,
+			 * - FP48, FP49, FP50, FP51, FP52, FP53, FP54, FP55,
+			 * - FP56, FP57, FP58, FP59, FP60, FP61, FP62, FP63,
+			 * - PC, PSR, CCR, CCCR,
+			 * - _X132, _X133, _X134
+			 * - TBR, BRR, DBAR0, DBAR1, DBAR2, DBAR3,
+			 * - _X141, _X142, _X143, _X144,
+			 * - LR, LCR
+			 */
+		case 'g':
+			zero = 0;
+			ptr = output_buffer;
+
+			/* deal with GR0, GR1-GR27, GR28-GR31, GR32-GR63 */
+			ptr = mem2hex(&zero, ptr, 4, 0);
+
+			for (loop = 1; loop <= 27; loop++)
+				ptr = mem2hex((unsigned long *)__debug_frame + REG_GR(loop),
+					      ptr, 4, 0);
+			temp = (unsigned long) __frame;
+			ptr = mem2hex(&temp, ptr, 4, 0);
+			ptr = mem2hex((unsigned long *)__debug_frame + REG_GR(29), ptr, 4, 0);
+			ptr = mem2hex((unsigned long *)__debug_frame + REG_GR(30), ptr, 4, 0);
+#ifdef CONFIG_MMU
+			ptr = mem2hex((unsigned long *)__debug_frame + REG_GR(31), ptr, 4, 0);
+#else
+			temp = (unsigned long) __debug_frame;
+			ptr = mem2hex(&temp, ptr, 4, 0);
+#endif
+
+			for (loop = 32; loop <= 63; loop++)
+				ptr = mem2hex((unsigned long *)__debug_frame + REG_GR(loop),
+					      ptr, 4, 0);
+
+			/* deal with FR0-FR63 */
+			for (loop = 0; loop <= 63; loop++)
+				ptr = mem2hex((unsigned long *)&__break_user_context +
+					      __FPMEDIA_FR(loop),
+					      ptr, 4, 0);
+
+			/* deal with special registers */
+			ptr = mem2hex(&__debug_frame->pc,    ptr, 4, 0);
+			ptr = mem2hex(&__debug_frame->psr,   ptr, 4, 0);
+			ptr = mem2hex(&__debug_frame->ccr,   ptr, 4, 0);
+			ptr = mem2hex(&__debug_frame->cccr,  ptr, 4, 0);
+			ptr = mem2hex(&zero, ptr, 4, 0);
+			ptr = mem2hex(&zero, ptr, 4, 0);
+			ptr = mem2hex(&zero, ptr, 4, 0);
+			ptr = mem2hex(&__debug_frame->tbr,   ptr, 4, 0);
+			ptr = mem2hex(&__debug_regs->brr ,   ptr, 4, 0);
+
+			asm volatile("movsg dbar0,%0" : "=r"(dbar));
+			ptr = mem2hex(&dbar, ptr, 4, 0);
+			asm volatile("movsg dbar1,%0" : "=r"(dbar));
+			ptr = mem2hex(&dbar, ptr, 4, 0);
+			asm volatile("movsg dbar2,%0" : "=r"(dbar));
+			ptr = mem2hex(&dbar, ptr, 4, 0);
+			asm volatile("movsg dbar3,%0" : "=r"(dbar));
+			ptr = mem2hex(&dbar, ptr, 4, 0);
+
+			asm volatile("movsg scr0,%0" : "=r"(dbar));
+			ptr = mem2hex(&dbar, ptr, 4, 0);
+			asm volatile("movsg scr1,%0" : "=r"(dbar));
+			ptr = mem2hex(&dbar, ptr, 4, 0);
+			asm volatile("movsg scr2,%0" : "=r"(dbar));
+			ptr = mem2hex(&dbar, ptr, 4, 0);
+			asm volatile("movsg scr3,%0" : "=r"(dbar));
+			ptr = mem2hex(&dbar, ptr, 4, 0);
+
+			ptr = mem2hex(&__debug_frame->lr, ptr, 4, 0);
+			ptr = mem2hex(&__debug_frame->lcr, ptr, 4, 0);
+
+			ptr = mem2hex(&__debug_frame->iacc0, ptr, 8, 0);
+
+			ptr = mem2hex(&__break_user_context.f.fsr[0], ptr, 4, 0);
+
+			for (loop = 0; loop <= 7; loop++)
+				ptr = mem2hex(&__break_user_context.f.acc[loop], ptr, 4, 0);
+
+			ptr = mem2hex(&__break_user_context.f.accg, ptr, 8, 0);
+
+			for (loop = 0; loop <= 1; loop++)
+				ptr = mem2hex(&__break_user_context.f.msr[loop], ptr, 4, 0);
+
+			ptr = mem2hex(&__debug_frame->gner0, ptr, 4, 0);
+			ptr = mem2hex(&__debug_frame->gner1, ptr, 4, 0);
+
+			ptr = mem2hex(&__break_user_context.f.fner[0], ptr, 4, 0);
+			ptr = mem2hex(&__break_user_context.f.fner[1], ptr, 4, 0);
+
+			break;
+
+			/* set the values of the CPU registers */
+		case 'G':
+			ptr = &input_buffer[1];
+
+			/* deal with GR0, GR1-GR27, GR28-GR31, GR32-GR63 */
+			ptr = hex2mem(ptr, &temp, 4);
+
+			for (loop = 1; loop <= 27; loop++)
+				ptr = hex2mem(ptr, (unsigned long *)__debug_frame + REG_GR(loop),
+					      4);
+
+			ptr = hex2mem(ptr, &temp, 4);
+			__frame = (struct pt_regs *) temp;
+			ptr = hex2mem(ptr, &__debug_frame->gr29, 4);
+			ptr = hex2mem(ptr, &__debug_frame->gr30, 4);
+#ifdef CONFIG_MMU
+			ptr = hex2mem(ptr, &__debug_frame->gr31, 4);
+#else
+			ptr = hex2mem(ptr, &temp, 4);
+#endif
+
+			for (loop = 32; loop <= 63; loop++)
+				ptr = hex2mem(ptr, (unsigned long *)__debug_frame + REG_GR(loop),
+					      4);
+
+			/* deal with FR0-FR63 */
+			for (loop = 0; loop <= 63; loop++)
+				ptr = mem2hex((unsigned long *)&__break_user_context +
+					      __FPMEDIA_FR(loop),
+					      ptr, 4, 0);
+
+			/* deal with special registers */
+			ptr = hex2mem(ptr, &__debug_frame->pc,  4);
+			ptr = hex2mem(ptr, &__debug_frame->psr, 4);
+			ptr = hex2mem(ptr, &__debug_frame->ccr, 4);
+			ptr = hex2mem(ptr, &__debug_frame->cccr,4);
+
+			for (loop = 132; loop <= 140; loop++)
+				ptr = hex2mem(ptr, &temp, 4);
+
+			ptr = hex2mem(ptr, &temp, 4);
+			asm volatile("movgs %0,scr0" :: "r"(temp));
+			ptr = hex2mem(ptr, &temp, 4);
+			asm volatile("movgs %0,scr1" :: "r"(temp));
+			ptr = hex2mem(ptr, &temp, 4);
+			asm volatile("movgs %0,scr2" :: "r"(temp));
+			ptr = hex2mem(ptr, &temp, 4);
+			asm volatile("movgs %0,scr3" :: "r"(temp));
+
+			ptr = hex2mem(ptr, &__debug_frame->lr,  4);
+			ptr = hex2mem(ptr, &__debug_frame->lcr, 4);
+
+			ptr = hex2mem(ptr, &__debug_frame->iacc0, 8);
+
+			ptr = hex2mem(ptr, &__break_user_context.f.fsr[0], 4);
+
+			for (loop = 0; loop <= 7; loop++)
+				ptr = hex2mem(ptr, &__break_user_context.f.acc[loop], 4);
+
+			ptr = hex2mem(ptr, &__break_user_context.f.accg, 8);
+
+			for (loop = 0; loop <= 1; loop++)
+				ptr = hex2mem(ptr, &__break_user_context.f.msr[loop], 4);
+
+			ptr = hex2mem(ptr, &__debug_frame->gner0, 4);
+			ptr = hex2mem(ptr, &__debug_frame->gner1, 4);
+
+			ptr = hex2mem(ptr, &__break_user_context.f.fner[0], 4);
+			ptr = hex2mem(ptr, &__break_user_context.f.fner[1], 4);
+
+			gdbstub_strcpy(output_buffer,"OK");
+			break;
+
+			/* mAA..AA,LLLL  Read LLLL bytes at address AA..AA */
+		case 'm':
+			ptr = &input_buffer[1];
+
+			if (hexToInt(&ptr, &addr) &&
+			    *ptr++ == ',' &&
+			    hexToInt(&ptr, &length)
+			    ) {
+				if (mem2hex((char *)addr, output_buffer, length, 1))
+					break;
+				gdbstub_strcpy (output_buffer, "E03");
+			}
+			else {
+				gdbstub_strcpy(output_buffer,"E01");
+			}
+			break;
+
+			/* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
+		case 'M':
+			ptr = &input_buffer[1];
+
+			if (hexToInt(&ptr, &addr) &&
+			    *ptr++ == ',' &&
+			    hexToInt(&ptr, &length) &&
+			    *ptr++ == ':'
+			    ) {
+				if (hex2mem(ptr, (char *)addr, length)) {
+					gdbstub_strcpy(output_buffer, "OK");
+				}
+				else {
+					gdbstub_strcpy(output_buffer, "E03");
+				}
+			}
+			else
+				gdbstub_strcpy(output_buffer, "E02");
+
+			flush_cache = 1;
+			break;
+
+			/* PNN,=RRRRRRRR: Write value R to reg N return OK */
+		case 'P':
+			ptr = &input_buffer[1];
+
+			if (!hexToInt(&ptr, &addr) ||
+			    *ptr++ != '=' ||
+			    !hexToInt(&ptr, &temp)
+			    ) {
+				gdbstub_strcpy(output_buffer, "E01");
+				break;
+			}
+
+			temp2 = 1;
+			switch (addr) {
+			case GDB_REG_GR(0):
+				break;
+			case GDB_REG_GR(1) ... GDB_REG_GR(63):
+				__break_user_context.i.gr[addr - GDB_REG_GR(0)] = temp;
+				break;
+			case GDB_REG_FR(0) ... GDB_REG_FR(63):
+				__break_user_context.f.fr[addr - GDB_REG_FR(0)] = temp;
+				break;
+			case GDB_REG_PC:
+				__break_user_context.i.pc = temp;
+				break;
+			case GDB_REG_PSR:
+				__break_user_context.i.psr = temp;
+				break;
+			case GDB_REG_CCR:
+				__break_user_context.i.ccr = temp;
+				break;
+			case GDB_REG_CCCR:
+				__break_user_context.i.cccr = temp;
+				break;
+			case GDB_REG_BRR:
+				__debug_regs->brr = temp;
+				break;
+			case GDB_REG_LR:
+				__break_user_context.i.lr = temp;
+				break;
+			case GDB_REG_LCR:
+				__break_user_context.i.lcr = temp;
+				break;
+			case GDB_REG_FSR0:
+				__break_user_context.f.fsr[0] = temp;
+				break;
+			case GDB_REG_ACC(0) ... GDB_REG_ACC(7):
+				__break_user_context.f.acc[addr - GDB_REG_ACC(0)] = temp;
+				break;
+			case GDB_REG_ACCG(0):
+				*(uint32_t *) &__break_user_context.f.accg[0] = temp;
+				break;
+			case GDB_REG_ACCG(4):
+				*(uint32_t *) &__break_user_context.f.accg[4] = temp;
+				break;
+			case GDB_REG_MSR(0) ... GDB_REG_MSR(1):
+				__break_user_context.f.msr[addr - GDB_REG_MSR(0)] = temp;
+				break;
+			case GDB_REG_GNER(0) ... GDB_REG_GNER(1):
+				__break_user_context.i.gner[addr - GDB_REG_GNER(0)] = temp;
+				break;
+			case GDB_REG_FNER(0) ... GDB_REG_FNER(1):
+				__break_user_context.f.fner[addr - GDB_REG_FNER(0)] = temp;
+				break;
+			default:
+				temp2 = 0;
+				break;
+			}
+
+			if (temp2) {
+				gdbstub_strcpy(output_buffer, "OK");
+			}
+			else {
+				gdbstub_strcpy(output_buffer, "E02");
+			}
+			break;
+
+			/* cAA..AA    Continue at address AA..AA(optional) */
+		case 'c':
+			/* try to read optional parameter, pc unchanged if no parm */
+			ptr = &input_buffer[1];
+			if (hexToInt(&ptr, &addr))
+				__debug_frame->pc = addr;
+			goto done;
+
+			/* kill the program */
+		case 'k' :
+			goto done;	/* just continue */
+
+
+			/* reset the whole machine (FIXME: system dependent) */
+		case 'r':
+			break;
+
+
+			/* step to next instruction */
+		case 's':
+			__debug_regs->dcr |= DCR_SE;
+			goto done;
+
+			/* set baud rate (bBB) */
+		case 'b':
+			ptr = &input_buffer[1];
+			if (!hexToInt(&ptr, &temp)) {
+				gdbstub_strcpy(output_buffer,"B01");
+				break;
+			}
+
+			if (temp) {
+				/* ack before changing speed */
+				gdbstub_send_packet("OK");
+				gdbstub_set_baud(temp);
+			}
+			break;
+
+			/* set breakpoint */
+		case 'Z':
+			ptr = &input_buffer[1];
+
+			if (!hexToInt(&ptr,&temp) || *ptr++ != ',' ||
+			    !hexToInt(&ptr,&addr) || *ptr++ != ',' ||
+			    !hexToInt(&ptr,&length)
+			    ) {
+				gdbstub_strcpy(output_buffer,"E01");
+				break;
+			}
+
+			if (temp >= 5) {
+				gdbstub_strcpy(output_buffer,"E03");
+				break;
+			}
+
+			if (gdbstub_set_breakpoint(temp, addr, length) < 0) {
+				gdbstub_strcpy(output_buffer,"E03");
+				break;
+			}
+
+			if (temp == 0)
+				flush_cache = 1; /* soft bkpt by modified memory */
+
+			gdbstub_strcpy(output_buffer,"OK");
+			break;
+
+			/* clear breakpoint */
+		case 'z':
+			ptr = &input_buffer[1];
+
+			if (!hexToInt(&ptr,&temp) || *ptr++ != ',' ||
+			    !hexToInt(&ptr,&addr) || *ptr++ != ',' ||
+			    !hexToInt(&ptr,&length)
+			    ) {
+				gdbstub_strcpy(output_buffer,"E01");
+				break;
+			}
+
+			if (temp >= 5) {
+				gdbstub_strcpy(output_buffer,"E03");
+				break;
+			}
+
+			if (gdbstub_clear_breakpoint(temp, addr, length) < 0) {
+				gdbstub_strcpy(output_buffer,"E03");
+				break;
+			}
+
+			if (temp == 0)
+				flush_cache = 1; /* soft bkpt by modified memory */
+
+			gdbstub_strcpy(output_buffer,"OK");
+			break;
+
+		default:
+			gdbstub_proto("### GDB Unsupported Cmd '%s'\n",input_buffer);
+			break;
+		}
+
+		/* reply to the request */
+		LEDS(0x5009);
+		gdbstub_send_packet(output_buffer);
+	}
+
+ done:
+	restore_user_regs(&__break_user_context);
+
+	//gdbstub_dump_debugregs();
+	//gdbstub_printk("<-- gdbstub() %08x\n", __debug_frame->pc);
+
+	/* need to flush the instruction cache before resuming, as we may have
+	 * deposited a breakpoint, and the icache probably has no way of
+	 * knowing that a data ref to some location may have changed something
+	 * that is in the instruction cache.  NB: We flush both caches, just to
+	 * be sure...
+	 */
+
+	/* note: flushing the icache will clobber EAR0 on the FR451 */
+	if (flush_cache)
+		gdbstub_purge_cache();
+
+	LEDS(0x5666);
+
+} /* end gdbstub() */
+
+/*****************************************************************************/
+/*
+ * initialise the GDB stub
+ */
+void __init gdbstub_init(void)
+{
+#ifdef CONFIG_GDBSTUB_IMMEDIATE
+	unsigned char ch;
+	int ret;
+#endif
+
+	gdbstub_printk("%s", gdbstub_banner);
+	gdbstub_printk("DCR: %x\n", __debug_regs->dcr);
+
+	gdbstub_io_init();
+
+	/* try to talk to GDB (or anyone insane enough to want to type GDB protocol by hand) */
+	gdbstub_proto("### GDB Tx ACK\n");
+	gdbstub_tx_char('+'); /* 'hello world' */
+
+#ifdef CONFIG_GDBSTUB_IMMEDIATE
+	gdbstub_printk("GDB Stub waiting for packet\n");
+
+	/*
+	 * In case GDB is started before us, ack any packets
+	 * (presumably "$?#xx") sitting there.
+	 */
+	do { gdbstub_rx_char(&ch, 0); } while (ch != '$');
+	do { gdbstub_rx_char(&ch, 0); } while (ch != '#');
+	do { ret = gdbstub_rx_char(&ch, 0); } while (ret != 0); /* eat first csum byte */
+	do { ret = gdbstub_rx_char(&ch, 0); } while (ret != 0); /* eat second csum byte */
+
+	gdbstub_proto("### GDB Tx NAK\n");
+	gdbstub_tx_char('-'); /* nak it */
+
+#else
+	gdbstub_printk("GDB Stub set\n");
+#endif
+
+#if 0
+	/* send banner */
+	ptr = output_buffer;
+	*ptr++ = 'O';
+	ptr = mem2hex(gdbstub_banner, ptr, sizeof(gdbstub_banner) - 1, 0);
+	gdbstub_send_packet(output_buffer);
+#endif
+#if defined(CONFIG_GDBSTUB_CONSOLE) && defined(CONFIG_GDBSTUB_IMMEDIATE)
+	register_console(&gdbstub_console);
+#endif
+
+} /* end gdbstub_init() */
+
+/*****************************************************************************/
+/*
+ * register the console at a more appropriate time
+ */
+#if defined (CONFIG_GDBSTUB_CONSOLE) && !defined(CONFIG_GDBSTUB_IMMEDIATE)
+static int __init gdbstub_postinit(void)
+{
+	printk("registering console\n");
+	register_console(&gdbstub_console);
+	return 0;
+} /* end gdbstub_postinit() */
+
+__initcall(gdbstub_postinit);
+#endif
+
+/*****************************************************************************/
+/*
+ * send an exit message to GDB
+ */
+void gdbstub_exit(int status)
+{
+	unsigned char checksum;
+	int count;
+	unsigned char ch;
+
+	sprintf(output_buffer,"W%02x",status&0xff);
+
+	gdbstub_tx_char('$');
+	checksum = 0;
+	count = 0;
+
+	while ((ch = output_buffer[count]) != 0) {
+		gdbstub_tx_char(ch);
+		checksum += ch;
+		count += 1;
+	}
+
+	gdbstub_tx_char('#');
+	gdbstub_tx_char(hexchars[checksum >> 4]);
+	gdbstub_tx_char(hexchars[checksum & 0xf]);
+
+	/* make sure the output is flushed, or else RedBoot might clobber it */
+	gdbstub_tx_char('-');
+	gdbstub_tx_flush();
+
+} /* end gdbstub_exit() */
+
+/*****************************************************************************/
+/*
+ * GDB wants to call malloc() and free() to allocate memory for calling kernel
+ * functions directly from its command line
+ */
+static void *malloc(size_t size) __attribute__((unused));
+static void *malloc(size_t size)
+{
+	return kmalloc(size, GFP_ATOMIC);
+}
+
+static void free(void *p) __attribute__((unused));
+static void free(void *p)
+{
+	kfree(p);
+}
+
+static uint32_t ___get_HSR0(void) __attribute__((unused));
+static uint32_t ___get_HSR0(void)
+{
+	return __get_HSR(0);
+}
+
+static uint32_t ___set_HSR0(uint32_t x) __attribute__((unused));
+static uint32_t ___set_HSR0(uint32_t x)
+{
+	__set_HSR(0, x);
+	return __get_HSR(0);
+}
diff -Nru a/arch/frv/kernel/head-mmu-fr451.S b/arch/frv/kernel/head-mmu-fr451.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/kernel/head-mmu-fr451.S	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,374 @@
+/* head-mmu-fr451.S: FR451 mmu-linux specific bits of initialisation
+ *
+ * Copyright (C) 2004 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/config.h>
+#include <linux/threads.h>
+#include <linux/linkage.h>
+#include <asm/ptrace.h>
+#include <asm/page.h>
+#include <asm/mem-layout.h>
+#include <asm/spr-regs.h>
+#include <asm/mb86943a.h>
+#include "head.inc"
+
+
+#define __400_DBR0	0xfe000e00
+#define __400_DBR1	0xfe000e08
+#define __400_DBR2	0xfe000e10
+#define __400_DBR3	0xfe000e18
+#define __400_DAM0	0xfe000f00
+#define __400_DAM1	0xfe000f08
+#define __400_DAM2	0xfe000f10
+#define __400_DAM3	0xfe000f18
+#define __400_LGCR	0xfe000010
+#define __400_LCR	0xfe000100
+#define __400_LSBR	0xfe000c00
+
+	.section	.text.init,"ax"
+	.balign		4
+
+###############################################################################
+#
+# describe the position and layout of the SDRAM controller registers
+#
+#	ENTRY:			EXIT:
+# GR5	-			cacheline size
+# GR11	-			displacement of 2nd SDRAM addr reg from GR14
+# GR12	-			displacement of 3rd SDRAM addr reg from GR14
+# GR13	-			displacement of 4th SDRAM addr reg from GR14
+# GR14	-			address of 1st SDRAM addr reg
+# GR15	-			amount to shift address by to match SDRAM addr reg
+# GR26	&__head_reference	[saved]
+# GR30	LED address		[saved]
+# CC0	-			T if DBR0 is present
+# CC1	-			T if DBR1 is present
+# CC2	-			T if DBR2 is present
+# CC3	-			T if DBR3 is present
+#
+###############################################################################
+	.globl		__head_fr451_describe_sdram
+__head_fr451_describe_sdram:
+	sethi.p		%hi(__400_DBR0),gr14
+	setlo		%lo(__400_DBR0),gr14
+	setlos.p	#__400_DBR1-__400_DBR0,gr11
+	setlos		#__400_DBR2-__400_DBR0,gr12
+	setlos.p	#__400_DBR3-__400_DBR0,gr13
+	setlos		#32,gr5			; cacheline size
+	setlos.p	#0,gr15			; amount to shift addr reg by
+	setlos		#0x00ff,gr4
+	movgs		gr4,cccr		; extant DARS/DAMK regs
+	bralr
+
+###############################################################################
+#
+# rearrange the bus controller registers
+#
+#	ENTRY:			EXIT:
+# GR26	&__head_reference	[saved]
+# GR30	LED address		revised LED address
+#
+###############################################################################
+	.globl		__head_fr451_set_busctl
+__head_fr451_set_busctl:
+	sethi.p		%hi(__400_LGCR),gr4
+	setlo		%lo(__400_LGCR),gr4
+	sethi.p		%hi(__400_LSBR),gr10
+	setlo		%lo(__400_LSBR),gr10
+	sethi.p		%hi(__400_LCR),gr11
+	setlo		%lo(__400_LCR),gr11
+
+	# set the bus controller
+	ldi		@(gr4,#0),gr5
+	ori		gr5,#0xff,gr5		; make sure all chip-selects are enabled
+	sti		gr5,@(gr4,#0)
+
+	sethi.p		%hi(__region_CS1),gr4
+	setlo		%lo(__region_CS1),gr4
+	sethi.p		%hi(__region_CS1_M),gr5
+	setlo		%lo(__region_CS1_M),gr5
+	sethi.p		%hi(__region_CS1_C),gr6
+	setlo		%lo(__region_CS1_C),gr6
+	sti		gr4,@(gr10,#1*0x08)
+	sti		gr5,@(gr10,#1*0x08+0x100)
+	sti		gr6,@(gr11,#1*0x08)
+	sethi.p		%hi(__region_CS2),gr4
+	setlo		%lo(__region_CS2),gr4
+	sethi.p		%hi(__region_CS2_M),gr5
+	setlo		%lo(__region_CS2_M),gr5
+	sethi.p		%hi(__region_CS2_C),gr6
+	setlo		%lo(__region_CS2_C),gr6
+	sti		gr4,@(gr10,#2*0x08)
+	sti		gr5,@(gr10,#2*0x08+0x100)
+	sti		gr6,@(gr11,#2*0x08)
+	sethi.p		%hi(__region_CS3),gr4
+	setlo		%lo(__region_CS3),gr4
+	sethi.p		%hi(__region_CS3_M),gr5
+	setlo		%lo(__region_CS3_M),gr5
+	sethi.p		%hi(__region_CS3_C),gr6
+	setlo		%lo(__region_CS3_C),gr6
+	sti		gr4,@(gr10,#3*0x08)
+	sti		gr5,@(gr10,#3*0x08+0x100)
+	sti		gr6,@(gr11,#3*0x08)
+	sethi.p		%hi(__region_CS4),gr4
+	setlo		%lo(__region_CS4),gr4
+	sethi.p		%hi(__region_CS4_M),gr5
+	setlo		%lo(__region_CS4_M),gr5
+	sethi.p		%hi(__region_CS4_C),gr6
+	setlo		%lo(__region_CS4_C),gr6
+	sti		gr4,@(gr10,#4*0x08)
+	sti		gr5,@(gr10,#4*0x08+0x100)
+	sti		gr6,@(gr11,#4*0x08)
+	sethi.p		%hi(__region_CS5),gr4
+	setlo		%lo(__region_CS5),gr4
+	sethi.p		%hi(__region_CS5_M),gr5
+	setlo		%lo(__region_CS5_M),gr5
+	sethi.p		%hi(__region_CS5_C),gr6
+	setlo		%lo(__region_CS5_C),gr6
+	sti		gr4,@(gr10,#5*0x08)
+	sti		gr5,@(gr10,#5*0x08+0x100)
+	sti		gr6,@(gr11,#5*0x08)
+	sethi.p		%hi(__region_CS6),gr4
+	setlo		%lo(__region_CS6),gr4
+	sethi.p		%hi(__region_CS6_M),gr5
+	setlo		%lo(__region_CS6_M),gr5
+	sethi.p		%hi(__region_CS6_C),gr6
+	setlo		%lo(__region_CS6_C),gr6
+	sti		gr4,@(gr10,#6*0x08)
+	sti		gr5,@(gr10,#6*0x08+0x100)
+	sti		gr6,@(gr11,#6*0x08)
+	sethi.p		%hi(__region_CS7),gr4
+	setlo		%lo(__region_CS7),gr4
+	sethi.p		%hi(__region_CS7_M),gr5
+	setlo		%lo(__region_CS7_M),gr5
+	sethi.p		%hi(__region_CS7_C),gr6
+	setlo		%lo(__region_CS7_C),gr6
+	sti		gr4,@(gr10,#7*0x08)
+	sti		gr5,@(gr10,#7*0x08+0x100)
+	sti		gr6,@(gr11,#7*0x08)
+	membar
+	bar
+
+	# adjust LED bank address
+#ifdef CONFIG_MB93091_VDK
+	sethi.p		%hi(__region_CS2 + 0x01200004),gr30
+	setlo		%lo(__region_CS2 + 0x01200004),gr30
+#endif
+	bralr
+
+###############################################################################
+#
+# determine the total SDRAM size
+#
+#	ENTRY:			EXIT:
+# GR25	-			SDRAM size
+# GR26	&__head_reference	[saved]
+# GR30	LED address		[saved]
+#
+###############################################################################
+	.globl		__head_fr451_survey_sdram
+__head_fr451_survey_sdram:
+	sethi.p		%hi(__400_DAM0),gr11
+	setlo		%lo(__400_DAM0),gr11
+	sethi.p		%hi(__400_DBR0),gr12
+	setlo		%lo(__400_DBR0),gr12
+
+	sethi.p		%hi(0xfe000000),gr17		; unused SDRAM DBR value
+	setlo		%lo(0xfe000000),gr17
+	setlos		#0,gr25
+
+	ldi		@(gr12,#0x00),gr4		; DAR0
+	subcc		gr4,gr17,gr0,icc0
+	beq		icc0,#0,__head_no_DCS0
+	ldi		@(gr11,#0x00),gr6		; DAM0: bits 31:20 match addr 31:20
+	add		gr25,gr6,gr25
+	addi		gr25,#1,gr25
+__head_no_DCS0:
+
+	ldi		@(gr12,#0x08),gr4		; DAR1
+	subcc		gr4,gr17,gr0,icc0
+	beq		icc0,#0,__head_no_DCS1
+	ldi		@(gr11,#0x08),gr6		; DAM1: bits 31:20 match addr 31:20
+	add		gr25,gr6,gr25
+	addi		gr25,#1,gr25
+__head_no_DCS1:
+
+	ldi		@(gr12,#0x10),gr4		; DAR2
+	subcc		gr4,gr17,gr0,icc0
+	beq		icc0,#0,__head_no_DCS2
+	ldi		@(gr11,#0x10),gr6		; DAM2: bits 31:20 match addr 31:20
+	add		gr25,gr6,gr25
+	addi		gr25,#1,gr25
+__head_no_DCS2:
+
+	ldi		@(gr12,#0x18),gr4		; DAR3
+	subcc		gr4,gr17,gr0,icc0
+	beq		icc0,#0,__head_no_DCS3
+	ldi		@(gr11,#0x18),gr6		; DAM3: bits 31:20 match addr 31:20
+	add		gr25,gr6,gr25
+	addi		gr25,#1,gr25
+__head_no_DCS3:
+	bralr
+
+###############################################################################
+#
+# set the protection map with the I/DAMPR registers
+#
+#	ENTRY:			EXIT:
+# GR25	SDRAM size		[saved]
+# GR26	&__head_reference	[saved]
+# GR30	LED address		[saved]
+#
+#
+# Using this map:
+#	REGISTERS	ADDRESS RANGE		VIEW
+#	===============	======================	===============================
+#	IAMPR0/DAMPR0	0xC0000000-0xCFFFFFFF	Cached kernel RAM Window
+#	DAMPR11		0xE0000000-0xFFFFFFFF	Uncached I/O
+#
+###############################################################################
+	.globl		__head_fr451_set_protection
+__head_fr451_set_protection:
+	movsg		lr,gr27
+
+	# set the I/O region protection registers for FR451 in MMU mode
+#define PGPROT_IO	xAMPRx_L|xAMPRx_M|xAMPRx_S_KERNEL|xAMPRx_C|xAMPRx_V
+
+	sethi.p		%hi(__region_IO),gr5
+	setlo		%lo(__region_IO),gr5
+	setlos		#PGPROT_IO|xAMPRx_SS_512Mb,gr4
+	or		gr4,gr5,gr4
+	movgs		gr5,damlr11			; General I/O tile
+	movgs		gr4,dampr11
+
+	# need to open a window onto at least part of the RAM for the kernel's use
+	sethi.p		%hi(__sdram_base),gr8
+	setlo		%lo(__sdram_base),gr8		; physical address
+	sethi.p		%hi(__page_offset),gr9
+	setlo		%lo(__page_offset),gr9		; virtual address
+
+	setlos		#xAMPRx_L|xAMPRx_M|xAMPRx_SS_256Mb|xAMPRx_S_KERNEL|xAMPRx_V,gr11
+	or		gr8,gr11,gr8
+
+	movgs		gr9,iamlr0			; mapped from real address 0
+	movgs		gr8,iampr0			; cached kernel memory at 0xC0000000
+	movgs		gr9,damlr0
+	movgs		gr8,dampr0
+
+	# set a temporary mapping for the kernel running at address 0 until we've turned on the MMU
+	sethi.p		%hi(__sdram_base),gr9
+	setlo		%lo(__sdram_base),gr9		; virtual address
+
+	and.p		gr4,gr11,gr4
+	and		gr5,gr11,gr5
+	or.p		gr4,gr11,gr4
+	or		gr5,gr11,gr5
+
+	movgs		gr9,iamlr1			; mapped from real address 0
+	movgs		gr8,iampr1			; cached kernel memory at 0x00000000
+	movgs		gr9,damlr1
+	movgs		gr8,dampr1
+
+	# we use DAMR2-10 for kmap_atomic(), cache flush and TLB management
+	# since the DAMLR regs are not going to change, we can set them now
+	# also set up IAMLR2 to the same as DAMLR5
+	sethi.p		%hi(KMAP_ATOMIC_PRIMARY_FRAME),gr4
+	setlo		%lo(KMAP_ATOMIC_PRIMARY_FRAME),gr4
+	sethi.p		%hi(PAGE_SIZE),gr5
+	setlo		%lo(PAGE_SIZE),gr5
+
+	movgs		gr4,damlr2
+	movgs		gr4,iamlr2
+	add		gr4,gr5,gr4
+	movgs		gr4,damlr3
+	add		gr4,gr5,gr4
+	movgs		gr4,damlr4
+	add		gr4,gr5,gr4
+	movgs		gr4,damlr5
+	add		gr4,gr5,gr4
+	movgs		gr4,damlr6
+	add		gr4,gr5,gr4
+	movgs		gr4,damlr7
+	add		gr4,gr5,gr4
+	movgs		gr4,damlr8
+	add		gr4,gr5,gr4
+	movgs		gr4,damlr9
+	add		gr4,gr5,gr4
+	movgs		gr4,damlr10
+
+	movgs		gr0,dampr2
+	movgs		gr0,dampr4
+	movgs		gr0,dampr5
+	movgs		gr0,dampr6
+	movgs		gr0,dampr7
+	movgs		gr0,dampr8
+	movgs		gr0,dampr9
+	movgs		gr0,dampr10
+
+	movgs		gr0,iamlr3
+	movgs		gr0,iamlr4
+	movgs		gr0,iamlr5
+	movgs		gr0,iamlr6
+	movgs		gr0,iamlr7
+
+	movgs		gr0,iampr2
+	movgs		gr0,iampr3
+	movgs		gr0,iampr4
+	movgs		gr0,iampr5
+	movgs		gr0,iampr6
+	movgs		gr0,iampr7
+
+	# start in TLB context 0 with the swapper's page tables
+	movgs		gr0,cxnr
+
+	sethi.p		%hi(swapper_pg_dir),gr4
+	setlo		%lo(swapper_pg_dir),gr4
+	sethi.p		%hi(__page_offset),gr5
+	setlo		%lo(__page_offset),gr5
+	sub		gr4,gr5,gr4
+	movgs		gr4,ttbr
+	setlos		#xAMPRx_L|xAMPRx_M|xAMPRx_SS_16Kb|xAMPRx_S|xAMPRx_C|xAMPRx_V,gr5
+	or		gr4,gr5,gr4
+	movgs		gr4,dampr3
+
+	# the FR451 also has an extra trap base register
+	movsg		tbr,gr4
+	movgs		gr4,btbr
+
+	LEDS		0x3300
+	jmpl		@(gr27,gr0)
+
+###############################################################################
+#
+# finish setting up the protection registers
+#
+###############################################################################
+	.globl		__head_fr451_finalise_protection
+__head_fr451_finalise_protection:
+	# turn on the timers as appropriate
+	movgs		gr0,timerh
+	movgs		gr0,timerl
+	movgs		gr0,timerd
+	movsg		hsr0,gr4
+	sethi.p		%hi(HSR0_ETMI),gr5
+	setlo		%lo(HSR0_ETMI),gr5
+	or		gr4,gr5,gr4
+	movgs		gr4,hsr0
+
+	# clear the TLB entry cache
+	movgs		gr0,iamlr1
+	movgs		gr0,iampr1
+	movgs		gr0,damlr1
+	movgs		gr0,dampr1
+
+	# clear the PGE cache
+	sethi.p		%hi(__flush_tlb_all),gr4
+	setlo		%lo(__flush_tlb_all),gr4
+	jmpl		@(gr4,gr0)
diff -Nru a/arch/frv/kernel/head-uc-fr401.S b/arch/frv/kernel/head-uc-fr401.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/kernel/head-uc-fr401.S	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,311 @@
+/* head-uc-fr401.S: FR401/3/5 uc-linux specific bits of initialisation
+ *
+ * Copyright (C) 2004 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/config.h>
+#include <linux/threads.h>
+#include <linux/linkage.h>
+#include <asm/ptrace.h>
+#include <asm/page.h>
+#include <asm/spr-regs.h>
+#include <asm/mb86943a.h>
+#include "head.inc"
+
+
+#define __400_DBR0	0xfe000e00
+#define __400_DBR1	0xfe000e08
+#define __400_DBR2	0xfe000e10	/* not on FR401 */
+#define __400_DBR3	0xfe000e18	/* not on FR401 */
+#define __400_DAM0	0xfe000f00
+#define __400_DAM1	0xfe000f08
+#define __400_DAM2	0xfe000f10	/* not on FR401 */
+#define __400_DAM3	0xfe000f18	/* not on FR401 */
+#define __400_LGCR	0xfe000010
+#define __400_LCR	0xfe000100
+#define __400_LSBR	0xfe000c00
+
+	.section	.text.init,"ax"
+	.balign		4
+
+###############################################################################
+#
+# describe the position and layout of the SDRAM controller registers
+#
+#	ENTRY:			EXIT:
+# GR5	-			cacheline size
+# GR11	-			displacement of 2nd SDRAM addr reg from GR14
+# GR12	-			displacement of 3rd SDRAM addr reg from GR14
+# GR13	-			displacement of 4th SDRAM addr reg from GR14
+# GR14	-			address of 1st SDRAM addr reg
+# GR15	-			amount to shift address by to match SDRAM addr reg
+# GR26	&__head_reference	[saved]
+# GR30	LED address		[saved]
+# CC0	-			T if DBR0 is present
+# CC1	-			T if DBR1 is present
+# CC2	-			T if DBR2 is present (not FR401/FR401A)
+# CC3	-			T if DBR3 is present (not FR401/FR401A)
+#
+###############################################################################
+	.globl		__head_fr401_describe_sdram
+__head_fr401_describe_sdram:
+	sethi.p		%hi(__400_DBR0),gr14
+	setlo		%lo(__400_DBR0),gr14
+	setlos.p	#__400_DBR1-__400_DBR0,gr11
+	setlos		#__400_DBR2-__400_DBR0,gr12
+	setlos.p	#__400_DBR3-__400_DBR0,gr13
+	setlos		#32,gr5			; cacheline size
+	setlos.p	#0,gr15			; amount to shift addr reg by
+
+	# specify which DBR regs are present
+	setlos		#0x00ff,gr4
+	movgs		gr4,cccr
+	movsg		psr,gr3			; check for FR401/FR401A
+	srli		gr3,#25,gr3
+	subicc		gr3,#0x20>>1,gr0,icc0
+	bnelr		icc0,#1
+	setlos		#0x000f,gr4
+	movgs		gr4,cccr
+	bralr
+
+###############################################################################
+#
+# rearrange the bus controller registers
+#
+#	ENTRY:			EXIT:
+# GR26	&__head_reference	[saved]
+# GR30	LED address		revised LED address
+#
+###############################################################################
+	.globl		__head_fr401_set_busctl
+__head_fr401_set_busctl:
+	sethi.p		%hi(__400_LGCR),gr4
+	setlo		%lo(__400_LGCR),gr4
+	sethi.p		%hi(__400_LSBR),gr10
+	setlo		%lo(__400_LSBR),gr10
+	sethi.p		%hi(__400_LCR),gr11
+	setlo		%lo(__400_LCR),gr11
+
+	# set the bus controller
+	ldi		@(gr4,#0),gr5
+	ori		gr5,#0xff,gr5		; make sure all chip-selects are enabled
+	sti		gr5,@(gr4,#0)
+
+	sethi.p		%hi(__region_CS1),gr4
+	setlo		%lo(__region_CS1),gr4
+	sethi.p		%hi(__region_CS1_M),gr5
+	setlo		%lo(__region_CS1_M),gr5
+	sethi.p		%hi(__region_CS1_C),gr6
+	setlo		%lo(__region_CS1_C),gr6
+	sti		gr4,@(gr10,#1*0x08)
+	sti		gr5,@(gr10,#1*0x08+0x100)
+	sti		gr6,@(gr11,#1*0x08)
+	sethi.p		%hi(__region_CS2),gr4
+	setlo		%lo(__region_CS2),gr4
+	sethi.p		%hi(__region_CS2_M),gr5
+	setlo		%lo(__region_CS2_M),gr5
+	sethi.p		%hi(__region_CS2_C),gr6
+	setlo		%lo(__region_CS2_C),gr6
+	sti		gr4,@(gr10,#2*0x08)
+	sti		gr5,@(gr10,#2*0x08+0x100)
+	sti		gr6,@(gr11,#2*0x08)
+	sethi.p		%hi(__region_CS3),gr4
+	setlo		%lo(__region_CS3),gr4
+	sethi.p		%hi(__region_CS3_M),gr5
+	setlo		%lo(__region_CS3_M),gr5
+	sethi.p		%hi(__region_CS3_C),gr6
+	setlo		%lo(__region_CS3_C),gr6
+	sti		gr4,@(gr10,#3*0x08)
+	sti		gr5,@(gr10,#3*0x08+0x100)
+	sti		gr6,@(gr11,#3*0x08)
+	sethi.p		%hi(__region_CS4),gr4
+	setlo		%lo(__region_CS4),gr4
+	sethi.p		%hi(__region_CS4_M),gr5
+	setlo		%lo(__region_CS4_M),gr5
+	sethi.p		%hi(__region_CS4_C),gr6
+	setlo		%lo(__region_CS4_C),gr6
+	sti		gr4,@(gr10,#4*0x08)
+	sti		gr5,@(gr10,#4*0x08+0x100)
+	sti		gr6,@(gr11,#4*0x08)
+	sethi.p		%hi(__region_CS5),gr4
+	setlo		%lo(__region_CS5),gr4
+	sethi.p		%hi(__region_CS5_M),gr5
+	setlo		%lo(__region_CS5_M),gr5
+	sethi.p		%hi(__region_CS5_C),gr6
+	setlo		%lo(__region_CS5_C),gr6
+	sti		gr4,@(gr10,#5*0x08)
+	sti		gr5,@(gr10,#5*0x08+0x100)
+	sti		gr6,@(gr11,#5*0x08)
+	sethi.p		%hi(__region_CS6),gr4
+	setlo		%lo(__region_CS6),gr4
+	sethi.p		%hi(__region_CS6_M),gr5
+	setlo		%lo(__region_CS6_M),gr5
+	sethi.p		%hi(__region_CS6_C),gr6
+	setlo		%lo(__region_CS6_C),gr6
+	sti		gr4,@(gr10,#6*0x08)
+	sti		gr5,@(gr10,#6*0x08+0x100)
+	sti		gr6,@(gr11,#6*0x08)
+	sethi.p		%hi(__region_CS7),gr4
+	setlo		%lo(__region_CS7),gr4
+	sethi.p		%hi(__region_CS7_M),gr5
+	setlo		%lo(__region_CS7_M),gr5
+	sethi.p		%hi(__region_CS7_C),gr6
+	setlo		%lo(__region_CS7_C),gr6
+	sti		gr4,@(gr10,#7*0x08)
+	sti		gr5,@(gr10,#7*0x08+0x100)
+	sti		gr6,@(gr11,#7*0x08)
+	membar
+	bar
+
+	# adjust LED bank address
+	sethi.p		%hi(LED_ADDR - 0x20000000 +__region_CS2),gr30
+	setlo		%lo(LED_ADDR - 0x20000000 +__region_CS2),gr30
+	bralr
+
+###############################################################################
+#
+# determine the total SDRAM size
+#
+#	ENTRY:			EXIT:
+# GR25	-			SDRAM size
+# GR26	&__head_reference	[saved]
+# GR30	LED address		[saved]
+#
+###############################################################################
+	.globl		__head_fr401_survey_sdram
+__head_fr401_survey_sdram:
+	sethi.p		%hi(__400_DAM0),gr11
+	setlo		%lo(__400_DAM0),gr11
+	sethi.p		%hi(__400_DBR0),gr12
+	setlo		%lo(__400_DBR0),gr12
+
+	sethi.p		%hi(0xfe000000),gr17		; unused SDRAM DBR value
+	setlo		%lo(0xfe000000),gr17
+	setlos		#0,gr25
+
+	ldi		@(gr12,#0x00),gr4		; DAR0
+	subcc		gr4,gr17,gr0,icc0
+	beq		icc0,#0,__head_no_DCS0
+	ldi		@(gr11,#0x00),gr6		; DAM0: bits 31:20 match addr 31:20
+	add		gr25,gr6,gr25
+	addi		gr25,#1,gr25
+__head_no_DCS0:
+
+	ldi		@(gr12,#0x08),gr4		; DAR1
+	subcc		gr4,gr17,gr0,icc0
+	beq		icc0,#0,__head_no_DCS1
+	ldi		@(gr11,#0x08),gr6		; DAM1: bits 31:20 match addr 31:20
+	add		gr25,gr6,gr25
+	addi		gr25,#1,gr25
+__head_no_DCS1:
+
+	# FR401/FR401A does not have DCS2/3
+	movsg		psr,gr3
+	srli		gr3,#25,gr3
+	subicc		gr3,#0x20>>1,gr0,icc0
+	beq		icc0,#0,__head_no_DCS3
+
+	ldi		@(gr12,#0x10),gr4		; DAR2
+	subcc		gr4,gr17,gr0,icc0
+	beq		icc0,#0,__head_no_DCS2
+	ldi		@(gr11,#0x10),gr6		; DAM2: bits 31:20 match addr 31:20
+	add		gr25,gr6,gr25
+	addi		gr25,#1,gr25
+__head_no_DCS2:
+
+	ldi		@(gr12,#0x18),gr4		; DAR3
+	subcc		gr4,gr17,gr0,icc0
+	beq		icc0,#0,__head_no_DCS3
+	ldi		@(gr11,#0x18),gr6		; DAM3: bits 31:20 match addr 31:20
+	add		gr25,gr6,gr25
+	addi		gr25,#1,gr25
+__head_no_DCS3:
+	bralr
+
+###############################################################################
+#
+# set the protection map with the I/DAMPR registers
+#
+#	ENTRY:			EXIT:
+# GR25	SDRAM size		[saved]
+# GR26	&__head_reference	[saved]
+# GR30	LED address		[saved]
+#
+###############################################################################
+	.globl		__head_fr401_set_protection
+__head_fr401_set_protection:
+	movsg		lr,gr27
+
+	# set the I/O region protection registers for FR401/3/5
+	sethi.p		%hi(__region_IO),gr5
+	setlo		%lo(__region_IO),gr5
+	ori		gr5,#xAMPRx_SS_512Mb|xAMPRx_S_KERNEL|xAMPRx_C|xAMPRx_V,gr5
+	movgs		gr0,iampr7
+	movgs		gr5,dampr7			; General I/O tile
+
+	# need to tile the remaining IAMPR/DAMPR registers to cover as much of the RAM as possible
+	# - start with the highest numbered registers
+	sethi.p		%hi(__kernel_image_end),gr8
+	setlo		%lo(__kernel_image_end),gr8
+	sethi.p		%hi(32768),gr4			; allow for a maximal allocator bitmap
+	setlo		%lo(32768),gr4
+	add		gr8,gr4,gr8
+	sethi.p		%hi(1024*2048-1),gr4		; round up to nearest 2MiB
+	setlo		%lo(1024*2048-1),gr4
+	add.p		gr8,gr4,gr8
+	not		gr4,gr4
+	and		gr8,gr4,gr8
+
+	sethi.p		%hi(__page_offset),gr9
+	setlo		%lo(__page_offset),gr9
+	add		gr9,gr25,gr9
+
+	# GR8 = base of uncovered RAM
+	# GR9 = top of uncovered RAM
+
+#ifdef CONFIG_MB93093_PDK
+	sethi.p		%hi(__region_CS2),gr4
+	setlo		%lo(__region_CS2),gr4
+	ori		gr4,#xAMPRx_SS_1Mb|xAMPRx_S_KERNEL|xAMPRx_C|xAMPRx_V,gr4
+	movgs		gr4,dampr6
+	movgs		gr0,iampr6
+#else
+	call		__head_split_region
+	movgs		gr4,iampr6
+	movgs		gr5,dampr6
+#endif
+	call		__head_split_region
+	movgs		gr4,iampr5
+	movgs		gr5,dampr5
+	call		__head_split_region
+	movgs		gr4,iampr4
+	movgs		gr5,dampr4
+	call		__head_split_region
+	movgs		gr4,iampr3
+	movgs		gr5,dampr3
+	call		__head_split_region
+	movgs		gr4,iampr2
+	movgs		gr5,dampr2
+	call		__head_split_region
+	movgs		gr4,iampr1
+	movgs		gr5,dampr1
+
+	# cover kernel core image with kernel-only segment
+	sethi.p		%hi(__page_offset),gr8
+	setlo		%lo(__page_offset),gr8
+	call		__head_split_region
+
+#ifdef CONFIG_PROTECT_KERNEL
+	ori.p		gr4,#xAMPRx_S_KERNEL,gr4
+	ori		gr5,#xAMPRx_S_KERNEL,gr5
+#endif
+
+	movgs		gr4,iampr0
+	movgs		gr5,dampr0
+	jmpl		@(gr27,gr0)
diff -Nru a/arch/frv/kernel/head-uc-fr451.S b/arch/frv/kernel/head-uc-fr451.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/kernel/head-uc-fr451.S	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,174 @@
+/* head-uc-fr451.S: FR451 uc-linux specific bits of initialisation
+ *
+ * Copyright (C) 2004 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/config.h>
+#include <linux/threads.h>
+#include <linux/linkage.h>
+#include <asm/ptrace.h>
+#include <asm/page.h>
+#include <asm/spr-regs.h>
+#include <asm/mb86943a.h>
+#include "head.inc"
+
+
+#define __400_DBR0	0xfe000e00
+#define __400_DBR1	0xfe000e08
+#define __400_DBR2	0xfe000e10
+#define __400_DBR3	0xfe000e18
+#define __400_DAM0	0xfe000f00
+#define __400_DAM1	0xfe000f08
+#define __400_DAM2	0xfe000f10
+#define __400_DAM3	0xfe000f18
+#define __400_LGCR	0xfe000010
+#define __400_LCR	0xfe000100
+#define __400_LSBR	0xfe000c00
+
+	.section	.text.init,"ax"
+	.balign		4
+
+###############################################################################
+#
+# set the protection map with the I/DAMPR registers
+#
+#	ENTRY:			EXIT:
+# GR25	SDRAM size		[saved]
+# GR26	&__head_reference	[saved]
+# GR30	LED address		[saved]
+#
+###############################################################################
+	.globl		__head_fr451_set_protection
+__head_fr451_set_protection:
+	movsg		lr,gr27
+
+	movgs		gr0,dampr10
+	movgs		gr0,damlr10
+	movgs		gr0,dampr9
+	movgs		gr0,damlr9
+	movgs		gr0,dampr8
+	movgs		gr0,damlr8
+
+	# set the I/O region protection registers for FR401/3/5
+	sethi.p		%hi(__region_IO),gr5
+	setlo		%lo(__region_IO),gr5
+	sethi.p		%hi(0x1fffffff),gr7
+	setlo		%lo(0x1fffffff),gr7
+	ori		gr5,#xAMPRx_SS_512Mb|xAMPRx_S_KERNEL|xAMPRx_C|xAMPRx_V,gr5
+	movgs		gr5,dampr11			; General I/O tile
+	movgs		gr7,damlr11
+
+	# need to tile the remaining IAMPR/DAMPR registers to cover as much of the RAM as possible
+	# - start with the highest numbered registers
+	sethi.p		%hi(__kernel_image_end),gr8
+	setlo		%lo(__kernel_image_end),gr8
+	sethi.p		%hi(32768),gr4			; allow for a maximal allocator bitmap
+	setlo		%lo(32768),gr4
+	add		gr8,gr4,gr8
+	sethi.p		%hi(1024*2048-1),gr4		; round up to nearest 2MiB
+	setlo		%lo(1024*2048-1),gr4
+	add.p		gr8,gr4,gr8
+	not		gr4,gr4
+	and		gr8,gr4,gr8
+
+	sethi.p		%hi(__page_offset),gr9
+	setlo		%lo(__page_offset),gr9
+	add		gr9,gr25,gr9
+
+	sethi.p		%hi(0xffffc000),gr11
+	setlo		%lo(0xffffc000),gr11
+
+	# GR8 = base of uncovered RAM
+	# GR9 = top of uncovered RAM
+	# GR11 = xAMLR mask
+	LEDS		0x3317
+	call		__head_split_region
+	movgs		gr4,iampr7
+	movgs		gr6,iamlr7
+	movgs		gr5,dampr7
+	movgs		gr7,damlr7
+
+	LEDS		0x3316
+	call		__head_split_region
+	movgs		gr4,iampr6
+	movgs		gr6,iamlr6
+	movgs		gr5,dampr6
+	movgs		gr7,damlr6
+
+	LEDS		0x3315
+	call		__head_split_region
+	movgs		gr4,iampr5
+	movgs		gr6,iamlr5
+	movgs		gr5,dampr5
+	movgs		gr7,damlr5
+
+	LEDS		0x3314
+	call		__head_split_region
+	movgs		gr4,iampr4
+	movgs		gr6,iamlr4
+	movgs		gr5,dampr4
+	movgs		gr7,damlr4
+
+	LEDS		0x3313
+	call		__head_split_region
+	movgs		gr4,iampr3
+	movgs		gr6,iamlr3
+	movgs		gr5,dampr3
+	movgs		gr7,damlr3
+
+	LEDS		0x3312
+	call		__head_split_region
+	movgs		gr4,iampr2
+	movgs		gr6,iamlr2
+	movgs		gr5,dampr2
+	movgs		gr7,damlr2
+
+	LEDS		0x3311
+	call		__head_split_region
+	movgs		gr4,iampr1
+	movgs		gr6,iamlr1
+	movgs		gr5,dampr1
+	movgs		gr7,damlr1
+
+	# cover kernel core image with kernel-only segment
+	LEDS		0x3310
+	sethi.p		%hi(__page_offset),gr8
+	setlo		%lo(__page_offset),gr8
+	call		__head_split_region
+
+#ifdef CONFIG_PROTECT_KERNEL
+	ori.p		gr4,#xAMPRx_S_KERNEL,gr4
+	ori		gr5,#xAMPRx_S_KERNEL,gr5
+#endif
+
+	movgs		gr4,iampr0
+	movgs		gr6,iamlr0
+	movgs		gr5,dampr0
+	movgs		gr7,damlr0
+
+	# start in TLB context 0 with no page tables
+	movgs		gr0,cxnr
+	movgs		gr0,ttbr
+
+	# the FR451 also has an extra trap base register
+	movsg		tbr,gr4
+	movgs		gr4,btbr
+
+	# turn on the timers as appropriate
+	movgs		gr0,timerh
+	movgs		gr0,timerl
+	movgs		gr0,timerd
+	movsg		hsr0,gr4
+	sethi.p		%hi(HSR0_ETMI),gr5
+	setlo		%lo(HSR0_ETMI),gr5
+	or		gr4,gr5,gr4
+	movgs		gr4,hsr0
+
+	LEDS		0x3300
+	jmpl		@(gr27,gr0)
diff -Nru a/arch/frv/kernel/head-uc-fr555.S b/arch/frv/kernel/head-uc-fr555.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/kernel/head-uc-fr555.S	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,347 @@
+/* head-uc-fr555.S: FR555 uc-linux specific bits of initialisation
+ *
+ * Copyright (C) 2004 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/config.h>
+#include <linux/threads.h>
+#include <linux/linkage.h>
+#include <asm/ptrace.h>
+#include <asm/page.h>
+#include <asm/spr-regs.h>
+#include <asm/mb86943a.h>
+#include "head.inc"
+
+
+#define __551_DARS0	0xfeff0100
+#define __551_DARS1	0xfeff0104
+#define __551_DARS2	0xfeff0108
+#define __551_DARS3	0xfeff010c
+#define __551_DAMK0	0xfeff0110
+#define __551_DAMK1	0xfeff0114
+#define __551_DAMK2	0xfeff0118
+#define __551_DAMK3	0xfeff011c
+#define __551_LCR	0xfeff1100
+#define __551_LSBR	0xfeff1c00
+
+	.section	.text.init,"ax"
+	.balign		4
+
+###############################################################################
+#
+# describe the position and layout of the SDRAM controller registers
+#
+#	ENTRY:			EXIT:
+# GR5	-			cacheline size
+# GR11	-			displacement of 2nd SDRAM addr reg from GR14
+# GR12	-			displacement of 3rd SDRAM addr reg from GR14
+# GR13	-			displacement of 4th SDRAM addr reg from GR14
+# GR14	-			address of 1st SDRAM addr reg
+# GR15	-			amount to shift address by to match SDRAM addr reg
+# GR26	&__head_reference	[saved]
+# GR30	LED address		[saved]
+# CC0	-			T if DARS0 is present
+# CC1	-			T if DARS1 is present
+# CC2	-			T if DARS2 is present
+# CC3	-			T if DARS3 is present
+#
+###############################################################################
+	.globl		__head_fr555_describe_sdram
+__head_fr555_describe_sdram:
+	sethi.p		%hi(__551_DARS0),gr14
+	setlo		%lo(__551_DARS0),gr14
+	setlos.p	#__551_DARS1-__551_DARS0,gr11
+	setlos		#__551_DARS2-__551_DARS0,gr12
+	setlos.p	#__551_DARS3-__551_DARS0,gr13
+	setlos		#64,gr5			; cacheline size
+	setlos		#20,gr15		; amount to shift addr by
+	setlos		#0x00ff,gr4
+	movgs		gr4,cccr		; extant DARS/DAMK regs
+	bralr
+
+###############################################################################
+#
+# rearrange the bus controller registers
+#
+#	ENTRY:			EXIT:
+# GR26	&__head_reference	[saved]
+# GR30	LED address		revised LED address
+#
+###############################################################################
+	.globl		__head_fr555_set_busctl
+__head_fr555_set_busctl:
+	LEDS		0x100f
+	sethi.p		%hi(__551_LSBR),gr10
+	setlo		%lo(__551_LSBR),gr10
+	sethi.p		%hi(__551_LCR),gr11
+	setlo		%lo(__551_LCR),gr11
+
+	# set the bus controller
+	sethi.p		%hi(__region_CS1),gr4
+	setlo		%lo(__region_CS1),gr4
+	sethi.p		%hi(__region_CS1_M),gr5
+	setlo		%lo(__region_CS1_M),gr5
+	sethi.p		%hi(__region_CS1_C),gr6
+	setlo		%lo(__region_CS1_C),gr6
+	sti		gr4,@(gr10,#1*0x08)
+	sti		gr5,@(gr10,#1*0x08+0x100)
+	sti		gr6,@(gr11,#1*0x08)
+	sethi.p		%hi(__region_CS2),gr4
+	setlo		%lo(__region_CS2),gr4
+	sethi.p		%hi(__region_CS2_M),gr5
+	setlo		%lo(__region_CS2_M),gr5
+	sethi.p		%hi(__region_CS2_C),gr6
+	setlo		%lo(__region_CS2_C),gr6
+	sti		gr4,@(gr10,#2*0x08)
+	sti		gr5,@(gr10,#2*0x08+0x100)
+	sti		gr6,@(gr11,#2*0x08)
+	sethi.p		%hi(__region_CS3),gr4
+	setlo		%lo(__region_CS3),gr4
+	sethi.p		%hi(__region_CS3_M),gr5
+	setlo		%lo(__region_CS3_M),gr5
+	sethi.p		%hi(__region_CS3_C),gr6
+	setlo		%lo(__region_CS3_C),gr6
+	sti		gr4,@(gr10,#3*0x08)
+	sti		gr5,@(gr10,#3*0x08+0x100)
+	sti		gr6,@(gr11,#3*0x08)
+	sethi.p		%hi(__region_CS4),gr4
+	setlo		%lo(__region_CS4),gr4
+	sethi.p		%hi(__region_CS4_M),gr5
+	setlo		%lo(__region_CS4_M),gr5
+	sethi.p		%hi(__region_CS4_C),gr6
+	setlo		%lo(__region_CS4_C),gr6
+	sti		gr4,@(gr10,#4*0x08)
+	sti		gr5,@(gr10,#4*0x08+0x100)
+	sti		gr6,@(gr11,#4*0x08)
+	sethi.p		%hi(__region_CS5),gr4
+	setlo		%lo(__region_CS5),gr4
+	sethi.p		%hi(__region_CS5_M),gr5
+	setlo		%lo(__region_CS5_M),gr5
+	sethi.p		%hi(__region_CS5_C),gr6
+	setlo		%lo(__region_CS5_C),gr6
+	sti		gr4,@(gr10,#5*0x08)
+	sti		gr5,@(gr10,#5*0x08+0x100)
+	sti		gr6,@(gr11,#5*0x08)
+	sethi.p		%hi(__region_CS6),gr4
+	setlo		%lo(__region_CS6),gr4
+	sethi.p		%hi(__region_CS6_M),gr5
+	setlo		%lo(__region_CS6_M),gr5
+	sethi.p		%hi(__region_CS6_C),gr6
+	setlo		%lo(__region_CS6_C),gr6
+	sti		gr4,@(gr10,#6*0x08)
+	sti		gr5,@(gr10,#6*0x08+0x100)
+	sti		gr6,@(gr11,#6*0x08)
+	sethi.p		%hi(__region_CS7),gr4
+	setlo		%lo(__region_CS7),gr4
+	sethi.p		%hi(__region_CS7_M),gr5
+	setlo		%lo(__region_CS7_M),gr5
+	sethi.p		%hi(__region_CS7_C),gr6
+	setlo		%lo(__region_CS7_C),gr6
+	sti		gr4,@(gr10,#7*0x08)
+	sti		gr5,@(gr10,#7*0x08+0x100)
+	sti		gr6,@(gr11,#7*0x08)
+	membar
+	bar
+
+	# adjust LED bank address
+#ifdef CONFIG_MB93091_VDK
+	sethi.p		%hi(LED_ADDR - 0x20000000 +__region_CS2),gr30
+	setlo		%lo(LED_ADDR - 0x20000000 +__region_CS2),gr30
+#endif
+	bralr
+
+###############################################################################
+#
+# determine the total SDRAM size
+#
+#	ENTRY:			EXIT:
+# GR25	-			SDRAM size
+# GR26	&__head_reference	[saved]
+# GR30	LED address		[saved]
+#
+###############################################################################
+	.globl		__head_fr555_survey_sdram
+__head_fr555_survey_sdram:
+	sethi.p		%hi(__551_DAMK0),gr11
+	setlo		%lo(__551_DAMK0),gr11
+	sethi.p		%hi(__551_DARS0),gr12
+	setlo		%lo(__551_DARS0),gr12
+
+	sethi.p		%hi(0xfff),gr17			; unused SDRAM AMK value
+	setlo		%lo(0xfff),gr17
+	setlos		#0,gr25
+
+	ldi		@(gr11,#0x00),gr6		; DAMK0: bits 11:0 match addr 11:0
+	subcc		gr6,gr17,gr0,icc0
+	beq		icc0,#0,__head_no_DCS0
+	ldi		@(gr12,#0x00),gr4		; DARS0
+	add		gr25,gr6,gr25
+	addi		gr25,#1,gr25
+__head_no_DCS0:
+
+	ldi		@(gr11,#0x04),gr6		; DAMK1: bits 11:0 match addr 11:0
+	subcc		gr6,gr17,gr0,icc0
+	beq		icc0,#0,__head_no_DCS1
+	ldi		@(gr12,#0x04),gr4		; DARS1
+	add		gr25,gr6,gr25
+	addi		gr25,#1,gr25
+__head_no_DCS1:
+
+	ldi		@(gr11,#0x8),gr6		; DAMK2: bits 11:0 match addr 11:0
+	subcc		gr6,gr17,gr0,icc0
+	beq		icc0,#0,__head_no_DCS2
+	ldi		@(gr12,#0x8),gr4		; DARS2
+	add		gr25,gr6,gr25
+	addi		gr25,#1,gr25
+__head_no_DCS2:
+
+	ldi		@(gr11,#0xc),gr6		; DAMK3: bits 11:0 match addr 11:0
+	subcc		gr6,gr17,gr0,icc0
+	beq		icc0,#0,__head_no_DCS3
+	ldi		@(gr12,#0xc),gr4		; DARS3
+	add		gr25,gr6,gr25
+	addi		gr25,#1,gr25
+__head_no_DCS3:
+
+	slli		gr25,#20,gr25			; shift [11:0] -> [31:20]
+	bralr
+
+###############################################################################
+#
+# set the protection map with the I/DAMPR registers
+#
+#	ENTRY:			EXIT:
+# GR25	SDRAM size		saved
+# GR30	LED address		saved
+#
+###############################################################################
+	.globl		__head_fr555_set_protection
+__head_fr555_set_protection:
+	movsg		lr,gr27
+
+	sethi.p		%hi(0xfff00000),gr11
+	setlo		%lo(0xfff00000),gr11
+
+	# set the I/O region protection registers for FR555
+	sethi.p		%hi(__region_IO),gr7
+	setlo		%lo(__region_IO),gr7
+	ori		gr7,#xAMPRx_SS_512Mb|xAMPRx_S_KERNEL|xAMPRx_C|xAMPRx_V,gr5
+	movgs		gr0,iampr15
+	movgs		gr0,iamlr15
+	movgs		gr5,dampr15
+	movgs		gr7,damlr15
+
+	# need to tile the remaining IAMPR/DAMPR registers to cover as much of the RAM as possible
+	# - start with the highest numbered registers
+	sethi.p		%hi(__kernel_image_end),gr8
+	setlo		%lo(__kernel_image_end),gr8
+	sethi.p		%hi(32768),gr4			; allow for a maximal allocator bitmap
+	setlo		%lo(32768),gr4
+	add		gr8,gr4,gr8
+	sethi.p		%hi(1024*2048-1),gr4		; round up to nearest 2MiB
+	setlo		%lo(1024*2048-1),gr4
+	add.p		gr8,gr4,gr8
+	not		gr4,gr4
+	and		gr8,gr4,gr8
+
+	sethi.p		%hi(__page_offset),gr9
+	setlo		%lo(__page_offset),gr9
+	add		gr9,gr25,gr9
+
+	# GR8 = base of uncovered RAM
+	# GR9 = top of uncovered RAM
+	# GR11 - mask for DAMLR/IAMLR regs
+	#
+	call		__head_split_region
+	movgs		gr4,iampr14
+	movgs		gr6,iamlr14
+	movgs		gr5,dampr14
+	movgs		gr7,damlr14
+	call		__head_split_region
+	movgs		gr4,iampr13
+	movgs		gr6,iamlr13
+	movgs		gr5,dampr13
+	movgs		gr7,damlr13
+	call		__head_split_region
+	movgs		gr4,iampr12
+	movgs		gr6,iamlr12
+	movgs		gr5,dampr12
+	movgs		gr7,damlr12
+	call		__head_split_region
+	movgs		gr4,iampr11
+	movgs		gr6,iamlr11
+	movgs		gr5,dampr11
+	movgs		gr7,damlr11
+	call		__head_split_region
+	movgs		gr4,iampr10
+	movgs		gr6,iamlr10
+	movgs		gr5,dampr10
+	movgs		gr7,damlr10
+	call		__head_split_region
+	movgs		gr4,iampr9
+	movgs		gr6,iamlr9
+	movgs		gr5,dampr9
+	movgs		gr7,damlr9
+	call		__head_split_region
+	movgs		gr4,iampr8
+	movgs		gr6,iamlr8
+	movgs		gr5,dampr8
+	movgs		gr7,damlr8
+
+	call		__head_split_region
+	movgs		gr4,iampr7
+	movgs		gr6,iamlr7
+	movgs		gr5,dampr7
+	movgs		gr7,damlr7
+	call		__head_split_region
+	movgs		gr4,iampr6
+	movgs		gr6,iamlr6
+	movgs		gr5,dampr6
+	movgs		gr7,damlr6
+	call		__head_split_region
+	movgs		gr4,iampr5
+	movgs		gr6,iamlr5
+	movgs		gr5,dampr5
+	movgs		gr7,damlr5
+	call		__head_split_region
+	movgs		gr4,iampr4
+	movgs		gr6,iamlr4
+	movgs		gr5,dampr4
+	movgs		gr7,damlr4
+	call		__head_split_region
+	movgs		gr4,iampr3
+	movgs		gr6,iamlr3
+	movgs		gr5,dampr3
+	movgs		gr7,damlr3
+	call		__head_split_region
+	movgs		gr4,iampr2
+	movgs		gr6,iamlr2
+	movgs		gr5,dampr2
+	movgs		gr7,damlr2
+	call		__head_split_region
+	movgs		gr4,iampr1
+	movgs		gr6,iamlr1
+	movgs		gr5,dampr1
+	movgs		gr7,damlr1
+
+	# cover kernel core image with kernel-only segment
+	sethi.p		%hi(__page_offset),gr8
+	setlo		%lo(__page_offset),gr8
+	call		__head_split_region
+
+#ifdef CONFIG_PROTECT_KERNEL
+	ori.p		gr4,#xAMPRx_S_KERNEL,gr4
+	ori		gr5,#xAMPRx_S_KERNEL,gr5
+#endif
+
+	movgs		gr4,iampr0
+	movgs		gr6,iamlr0
+	movgs		gr5,dampr0
+	movgs		gr7,damlr0
+	jmpl		@(gr27,gr0)
diff -Nru a/arch/frv/kernel/head.S b/arch/frv/kernel/head.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/kernel/head.S	2005-03-01 23:39:26 -08:00
@@ -0,0 +1,639 @@
+/* head.S: kernel entry point for FR-V kernel
+ *
+ * Copyright (C) 2003, 2004 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/config.h>
+#include <linux/threads.h>
+#include <linux/linkage.h>
+#include <asm/ptrace.h>
+#include <asm/page.h>
+#include <asm/spr-regs.h>
+#include <asm/mb86943a.h>
+#include <asm/cache.h>
+#include "head.inc"
+
+###############################################################################
+#
+# void _boot(unsigned long magic, char *command_line) __attribute__((noreturn))
+#
+# - if magic is 0xdead1eaf, then command_line is assumed to point to the kernel
+#   command line string
+#
+###############################################################################
+	.section	.text.head,"ax"
+	.balign		4
+
+	.globl		_boot, __head_reference
+        .type		_boot,@function
+_boot:
+__head_reference:
+	sethi.p		%hi(LED_ADDR),gr30
+	setlo		%lo(LED_ADDR),gr30
+
+	LEDS		0x0000
+
+	# calculate reference address for PC-relative stuff
+	call		0f
+0:	movsg		lr,gr26
+	addi		gr26,#__head_reference-0b,gr26
+
+	# invalidate and disable both of the caches and turn off the memory access checking
+	dcef		@(gr0,gr0),1
+	bar
+
+	sethi.p		%hi(~(HSR0_ICE|HSR0_DCE|HSR0_CBM|HSR0_EIMMU|HSR0_EDMMU)),gr4
+	setlo		%lo(~(HSR0_ICE|HSR0_DCE|HSR0_CBM|HSR0_EIMMU|HSR0_EDMMU)),gr4
+	movsg		hsr0,gr5
+	and		gr4,gr5,gr5
+	movgs		gr5,hsr0
+	movsg		hsr0,gr5
+
+	LEDS		0x0001
+
+	icei		@(gr0,gr0),1
+	dcei		@(gr0,gr0),1
+	bar
+
+	# turn the instruction cache back on
+	sethi.p		%hi(HSR0_ICE),gr4
+	setlo		%lo(HSR0_ICE),gr4
+	movsg		hsr0,gr5
+	or		gr4,gr5,gr5
+	movgs		gr5,hsr0
+	movsg		hsr0,gr5
+
+	bar
+
+	LEDS		0x0002
+
+	# retrieve the parameters (including command line) before we overwrite them
+	sethi.p		%hi(0xdead1eaf),gr7
+	setlo		%lo(0xdead1eaf),gr7
+	subcc		gr7,gr8,gr0,icc0
+	bne		icc0,#0,__head_no_parameters
+
+	sethi.p		%hi(redboot_command_line-1),gr6
+	setlo		%lo(redboot_command_line-1),gr6
+	sethi.p		%hi(__head_reference),gr4
+	setlo		%lo(__head_reference),gr4
+	sub		gr6,gr4,gr6
+	add.p		gr6,gr26,gr6
+	subi		gr9,#1,gr9
+	setlos.p	#511,gr4
+	setlos		#1,gr5
+
+__head_copy_cmdline:
+	ldubu.p		@(gr9,gr5),gr16
+	subicc		gr4,#1,gr4,icc0
+	stbu.p		gr16,@(gr6,gr5)
+	subicc		gr16,#0,gr0,icc1
+	bls		icc0,#0,__head_end_cmdline
+	bne		icc1,#1,__head_copy_cmdline
+__head_end_cmdline:
+	stbu		gr0,@(gr6,gr5)
+__head_no_parameters:
+
+###############################################################################
+#
+# we need to relocate the SDRAM to 0x00000000 (linux) or 0xC0000000 (uClinux)
+# - note that we're going to have to run entirely out of the icache whilst
+#   fiddling with the SDRAM controller registers
+#
+###############################################################################
+#ifdef CONFIG_MMU
+	call		__head_fr451_describe_sdram
+
+#else
+	movsg		psr,gr5
+	srli		gr5,#28,gr5
+	subicc		gr5,#3,gr0,icc0
+	beq		icc0,#0,__head_fr551_sdram
+
+	call		__head_fr401_describe_sdram
+	bra		__head_do_sdram
+
+__head_fr551_sdram:
+	call		__head_fr555_describe_sdram
+	LEDS		0x000d
+
+__head_do_sdram:
+#endif
+
+	# preload the registers with invalid values in case any DBR/DARS are marked not present
+	sethi.p		%hi(0xfe000000),gr17		; unused SDRAM DBR value
+	setlo		%lo(0xfe000000),gr17
+	or.p		gr17,gr0,gr20
+	or		gr17,gr0,gr21
+	or.p		gr17,gr0,gr22
+	or		gr17,gr0,gr23
+
+	# consult the SDRAM controller CS address registers
+	cld		@(gr14,gr0 ),gr20,	cc0,#1	; DBR0 / DARS0
+	cld		@(gr14,gr11),gr21,	cc1,#1	; DBR1 / DARS1
+	cld		@(gr14,gr12),gr22,	cc2,#1	; DBR2 / DARS2
+	cld.p		@(gr14,gr13),gr23,	cc3,#1	; DBR3 / DARS3
+
+	sll		gr20,gr15,gr20			; shift values up for FR551
+	sll		gr21,gr15,gr21
+	sll		gr22,gr15,gr22
+	sll		gr23,gr15,gr23
+
+	LEDS		0x0003
+
+	# assume the lowest valid CS line to be the SDRAM base and get its address
+	subcc		gr20,gr17,gr0,icc0
+	subcc.p		gr21,gr17,gr0,icc1
+	subcc		gr22,gr17,gr0,icc2
+	subcc.p		gr23,gr17,gr0,icc3
+	ckne		icc0,cc4			; T if DBR0 != 0xfe000000
+	ckne		icc1,cc5
+	ckne		icc2,cc6
+	ckne		icc3,cc7
+	cor		gr23,gr0,gr24,		cc7,#1	; GR24 = SDRAM base
+	cor		gr22,gr0,gr24,		cc6,#1
+	cor		gr21,gr0,gr24,		cc5,#1
+	cor		gr20,gr0,gr24,		cc4,#1
+
+	# calculate the displacement required to get the SDRAM into the right place in memory
+	sethi.p		%hi(__sdram_base),gr16
+	setlo		%lo(__sdram_base),gr16
+	sub		gr16,gr24,gr16			; delta = __sdram_base - DBRx
+
+	# calculate the new values to go in the controller regs
+	cadd.p		gr20,gr16,gr20,		cc4,#1	; DCS#0 (new) = DCS#0 (old) + delta
+	cadd		gr21,gr16,gr21,		cc5,#1
+	cadd.p		gr22,gr16,gr22,		cc6,#1
+	cadd		gr23,gr16,gr23,		cc7,#1
+
+	srl		gr20,gr15,gr20			; shift values down for FR551
+	srl		gr21,gr15,gr21
+	srl		gr22,gr15,gr22
+	srl		gr23,gr15,gr23
+
+	# work out the address at which the reg updater resides and lock it into icache
+	# also work out the address the updater will jump to when finished
+	sethi.p		%hi(__head_move_sdram-__head_reference),gr18
+	setlo		%lo(__head_move_sdram-__head_reference),gr18
+	sethi.p		%hi(__head_sdram_moved-__head_reference),gr19
+	setlo		%lo(__head_sdram_moved-__head_reference),gr19
+	add.p		gr18,gr26,gr18
+	add		gr19,gr26,gr19
+	add.p		gr19,gr16,gr19			; moved = addr + (__sdram_base - DBRx)
+	add		gr18,gr5,gr4			; two cachelines probably required
+
+	icpl		gr18,gr0,#1			; load and lock the cachelines
+	icpl		gr4,gr0,#1
+	LEDS		0x0004
+	membar
+	bar
+	jmpl		@(gr18,gr0)
+
+	.balign		L1_CACHE_BYTES
+__head_move_sdram:
+	cst		gr20,@(gr14,gr0 ),	cc4,#1
+	cst		gr21,@(gr14,gr11),	cc5,#1
+	cst		gr22,@(gr14,gr12),	cc6,#1
+	cst		gr23,@(gr14,gr13),	cc7,#1
+	cld		@(gr14,gr0 ),gr20,	cc4,#1
+	cld		@(gr14,gr11),gr21,	cc5,#1
+	cld		@(gr14,gr12),gr22,	cc4,#1
+	cld		@(gr14,gr13),gr23,	cc7,#1
+	bar
+	membar
+	jmpl		@(gr19,gr0)
+
+	.balign		L1_CACHE_BYTES
+__head_sdram_moved:
+	icul		gr18
+	add		gr18,gr5,gr4
+	icul		gr4
+	icei		@(gr0,gr0),1
+	dcei		@(gr0,gr0),1
+
+	LEDS		0x0005
+
+	# recalculate reference address
+	call		0f
+0:	movsg		lr,gr26
+	addi		gr26,#__head_reference-0b,gr26
+
+
+###############################################################################
+#
+# move the kernel image down to the bottom of the SDRAM
+#
+###############################################################################
+	sethi.p		%hi(__kernel_image_size_no_bss+15),gr4
+	setlo		%lo(__kernel_image_size_no_bss+15),gr4
+	srli.p		gr4,#4,gr4			; count
+	or		gr26,gr26,gr16			; source
+
+	sethi.p		%hi(__sdram_base),gr17		; destination
+	setlo		%lo(__sdram_base),gr17
+
+	setlos		#8,gr5
+	sub.p		gr16,gr5,gr16			; adjust src for LDDU
+	sub		gr17,gr5,gr17			; adjust dst for LDDU
+
+	sethi.p		%hi(__head_move_kernel-__head_reference),gr18
+	setlo		%lo(__head_move_kernel-__head_reference),gr18
+	sethi.p		%hi(__head_kernel_moved-__head_reference+__sdram_base),gr19
+	setlo		%lo(__head_kernel_moved-__head_reference+__sdram_base),gr19
+	add		gr18,gr26,gr18
+	icpl		gr18,gr0,#1
+	jmpl		@(gr18,gr0)
+
+	.balign		32
+__head_move_kernel:
+	lddu		@(gr16,gr5),gr10
+	lddu		@(gr16,gr5),gr12
+	stdu.p		gr10,@(gr17,gr5)
+	subicc		gr4,#1,gr4,icc0
+	stdu.p		gr12,@(gr17,gr5)
+	bhi		icc0,#0,__head_move_kernel
+	jmpl		@(gr19,gr0)
+
+	.balign		32
+__head_kernel_moved:
+	icul		gr18
+	icei		@(gr0,gr0),1
+	dcei		@(gr0,gr0),1
+
+	LEDS		0x0006
+
+	# recalculate reference address
+	call		0f
+0:	movsg		lr,gr26
+	addi		gr26,#__head_reference-0b,gr26
+
+
+###############################################################################
+#
+# rearrange the iomem map and set the protection registers
+#
+###############################################################################
+
+#ifdef CONFIG_MMU
+	LEDS		0x3301
+	call		__head_fr451_set_busctl
+	LEDS		0x3303
+	call		__head_fr451_survey_sdram
+	LEDS		0x3305
+	call		__head_fr451_set_protection
+
+#else
+	movsg		psr,gr5
+	srli		gr5,#PSR_IMPLE_SHIFT,gr5
+	subicc		gr5,#PSR_IMPLE_FR551,gr0,icc0
+	beq		icc0,#0,__head_fr555_memmap
+	subicc		gr5,#PSR_IMPLE_FR451,gr0,icc0
+	beq		icc0,#0,__head_fr451_memmap
+
+	LEDS		0x3101
+	call		__head_fr401_set_busctl
+	LEDS		0x3103
+	call		__head_fr401_survey_sdram
+	LEDS		0x3105
+	call		__head_fr401_set_protection
+	bra		__head_done_memmap
+
+__head_fr451_memmap:
+	LEDS		0x3301
+	call		__head_fr401_set_busctl
+	LEDS		0x3303
+	call		__head_fr401_survey_sdram
+	LEDS		0x3305
+	call		__head_fr451_set_protection
+	bra		__head_done_memmap
+
+__head_fr555_memmap:
+	LEDS		0x3501
+	call		__head_fr555_set_busctl
+	LEDS		0x3503
+	call		__head_fr555_survey_sdram
+	LEDS		0x3505
+	call		__head_fr555_set_protection
+
+__head_done_memmap:
+#endif
+	LEDS		0x0007
+
+###############################################################################
+#
+# turn the data cache and MMU on
+# - for the FR451 this'll mean that the window through which the kernel is
+#   viewed will change
+#
+###############################################################################
+
+#ifdef CONFIG_MMU
+#define MMUMODE		HSR0_EIMMU|HSR0_EDMMU|HSR0_EXMMU|HSR0_EDAT|HSR0_XEDAT
+#else
+#define MMUMODE		HSR0_EIMMU|HSR0_EDMMU
+#endif
+
+	movsg		hsr0,gr5
+
+	sethi.p		%hi(MMUMODE),gr4
+	setlo		%lo(MMUMODE),gr4
+	or		gr4,gr5,gr5
+
+#if defined(CONFIG_FRV_DEFL_CACHE_WTHRU)
+	sethi.p		%hi(HSR0_DCE|HSR0_CBM_WRITE_THRU),gr4
+	setlo		%lo(HSR0_DCE|HSR0_CBM_WRITE_THRU),gr4
+#elif defined(CONFIG_FRV_DEFL_CACHE_WBACK)
+	sethi.p		%hi(HSR0_DCE|HSR0_CBM_COPY_BACK),gr4
+	setlo		%lo(HSR0_DCE|HSR0_CBM_COPY_BACK),gr4
+#elif defined(CONFIG_FRV_DEFL_CACHE_WBEHIND)
+	sethi.p		%hi(HSR0_DCE|HSR0_CBM_COPY_BACK),gr4
+	setlo		%lo(HSR0_DCE|HSR0_CBM_COPY_BACK),gr4
+
+	movsg		psr,gr6
+	srli		gr6,#24,gr6
+	cmpi		gr6,#0x50,icc0		// FR451
+	beq		icc0,#0,0f
+	cmpi		gr6,#0x40,icc0		// FR405
+	bne		icc0,#0,1f
+0:
+	# turn off write-allocate
+	sethi.p		%hi(HSR0_NWA),gr6
+	setlo		%lo(HSR0_NWA),gr6
+	or		gr4,gr6,gr4
+1:
+
+#else
+#error No default cache configuration set
+#endif
+
+	or		gr4,gr5,gr5
+	movgs		gr5,hsr0
+	bar
+
+	LEDS		0x0008
+
+	sethi.p		%hi(__head_mmu_enabled),gr19
+	setlo		%lo(__head_mmu_enabled),gr19
+	jmpl		@(gr19,gr0)
+
+__head_mmu_enabled:
+	icei		@(gr0,gr0),#1
+	dcei		@(gr0,gr0),#1
+
+	LEDS		0x0009
+
+#ifdef CONFIG_MMU
+	call		__head_fr451_finalise_protection
+#endif
+
+	LEDS		0x000a
+
+###############################################################################
+#
+# set up the runtime environment
+#
+###############################################################################
+
+	# clear the BSS area
+	sethi.p		%hi(__bss_start),gr4
+	setlo		%lo(__bss_start),gr4
+	sethi.p		%hi(_end),gr5
+	setlo		%lo(_end),gr5
+	or.p		gr0,gr0,gr18
+	or		gr0,gr0,gr19
+
+0:
+	stdi		gr18,@(gr4,#0)
+	stdi		gr18,@(gr4,#8)
+	stdi		gr18,@(gr4,#16)
+	stdi.p		gr18,@(gr4,#24)
+	addi		gr4,#24,gr4
+	subcc		gr5,gr4,gr0,icc0
+	bhi		icc0,#2,0b
+
+	LEDS		0x000b
+
+	# save the SDRAM details
+	sethi.p		%hi(__sdram_old_base),gr4
+	setlo		%lo(__sdram_old_base),gr4
+	st		gr24,@(gr4,gr0)
+
+	sethi.p		%hi(__sdram_base),gr5
+	setlo		%lo(__sdram_base),gr5
+	sethi.p		%hi(memory_start),gr4
+	setlo		%lo(memory_start),gr4
+	st		gr5,@(gr4,gr0)
+
+	add		gr25,gr5,gr25
+	sethi.p		%hi(memory_end),gr4
+	setlo		%lo(memory_end),gr4
+	st		gr25,@(gr4,gr0)
+
+	# point the TBR at the kernel trap table
+	sethi.p		%hi(__entry_kerneltrap_table),gr4
+	setlo		%lo(__entry_kerneltrap_table),gr4
+	movgs		gr4,tbr
+
+	# set up the exception frame for init
+	sethi.p		%hi(__kernel_frame0_ptr),gr28
+	setlo		%lo(__kernel_frame0_ptr),gr28
+	sethi.p		%hi(_gp),gr16
+	setlo		%lo(_gp),gr16
+	sethi.p		%hi(__entry_usertrap_table),gr4
+	setlo		%lo(__entry_usertrap_table),gr4
+
+	lddi		@(gr28,#0),gr28		; load __frame & current
+	ldi.p		@(gr29,#4),gr15		; set current_thread
+
+	or		gr0,gr0,fp
+	or		gr28,gr0,sp
+
+	sti.p		gr4,@(gr28,REG_TBR)
+	setlos		#ISR_EDE|ISR_DTT_DIVBYZERO|ISR_EMAM_EXCEPTION,gr5
+	movgs		gr5,isr
+
+	# turn on and off various CPU services
+	movsg		psr,gr22
+	sethi.p		%hi(#PSR_EM|PSR_EF|PSR_CM|PSR_NEM),gr4
+	setlo		%lo(#PSR_EM|PSR_EF|PSR_CM|PSR_NEM),gr4
+	or		gr22,gr4,gr22
+	movgs		gr22,psr
+
+	andi		gr22,#~(PSR_PIL|PSR_PS|PSR_S),gr22
+	ori		gr22,#PSR_ET,gr22
+	sti		gr22,@(gr28,REG_PSR)
+
+
+###############################################################################
+#
+# set up the registers and jump into the kernel
+#
+###############################################################################
+
+	LEDS		0x000c
+
+	# initialise the processor and the peripherals
+	#call		SYMBOL_NAME(processor_init)
+	#call		SYMBOL_NAME(unit_init)
+	#LEDS		0x0aff
+
+	sethi.p		#0xe5e5,gr3
+	setlo		#0xe5e5,gr3
+	or.p		gr3,gr0,gr4
+	or		gr3,gr0,gr5
+	or.p		gr3,gr0,gr6
+	or		gr3,gr0,gr7
+	or.p		gr3,gr0,gr8
+	or		gr3,gr0,gr9
+	or.p		gr3,gr0,gr10
+	or		gr3,gr0,gr11
+	or.p		gr3,gr0,gr12
+	or		gr3,gr0,gr13
+	or.p		gr3,gr0,gr14
+	or		gr3,gr0,gr17
+	or.p		gr3,gr0,gr18
+	or		gr3,gr0,gr19
+	or.p		gr3,gr0,gr20
+	or		gr3,gr0,gr21
+	or.p		gr3,gr0,gr23
+	or		gr3,gr0,gr24
+	or.p		gr3,gr0,gr25
+	or		gr3,gr0,gr26
+	or.p		gr3,gr0,gr27
+#	or		gr3,gr0,gr30
+	or		gr3,gr0,gr31
+	movgs		gr0,lr
+	movgs		gr0,lcr
+	movgs		gr0,ccr
+	movgs		gr0,cccr
+
+#ifdef CONFIG_MMU
+	movgs		gr3,scr2
+	movgs		gr3,scr3
+#endif
+
+	LEDS		0x0fff
+
+	# invoke the debugging stub if present
+	# - arch/frv/kernel/debug-stub.c will shift control directly to init/main.c
+	#   (it will not return here)
+	break
+	.globl		__debug_stub_init_break
+__debug_stub_init_break:
+
+	# however, if you need to use an ICE, and don't care about using any userspace
+	# debugging tools (such as the ptrace syscall), you can just step over the break
+	# above and get to the kernel this way
+	# look at arch/frv/kernel/debug-stub.c: debug_stub_init() to see what you've missed
+	call		start_kernel
+
+	.globl		__head_end
+__head_end:
+	.size		_boot, .-_boot
+
+	# provide a point for GDB to place a break
+	.section	.text.start,"ax"
+	.globl		_start
+	.balign		4
+_start:
+	call		_boot
+
+	.previous
+###############################################################################
+#
+# split a tile off of the region defined by GR8-GR9
+#
+#	ENTRY:			EXIT:
+# GR4	-			IAMPR value representing tile
+# GR5	-			DAMPR value representing tile
+# GR6	-			IAMLR value representing tile
+# GR7	-			DAMLR value representing tile
+# GR8	region base pointer	[saved]
+# GR9	region top pointer	updated to exclude new tile
+# GR11	xAMLR mask		[saved]
+# GR25	SDRAM size		[saved]
+# GR30	LED address		[saved]
+#
+# - GR8 and GR9 should be rounded up/down to the nearest megabyte before calling
+#
+###############################################################################
+	.globl		__head_split_region
+	.type		__head_split_region,@function
+__head_split_region:
+	subcc.p		gr9,gr8,gr4,icc0
+	setlos		#31,gr5
+	scan.p		gr4,gr0,gr6
+	beq		icc0,#0,__head_region_empty
+	sub.p		gr5,gr6,gr6			; bit number of highest set bit (1MB=>20)
+	setlos		#1,gr4
+	sll.p		gr4,gr6,gr4			; size of region (1 << bitno)
+	subi		gr6,#17,gr6			; 1MB => 0x03
+	slli.p		gr6,#4,gr6			; 1MB => 0x30
+	sub		gr9,gr4,gr9			; move uncovered top down
+
+	or		gr9,gr6,gr4
+	ori		gr4,#xAMPRx_S_USER|xAMPRx_C_CACHED|xAMPRx_V,gr4
+	or.p		gr4,gr0,gr5
+
+	and		gr4,gr11,gr6
+	and.p		gr5,gr11,gr7
+	bralr
+
+__head_region_empty:
+	or.p		gr0,gr0,gr4
+	or		gr0,gr0,gr5
+	or.p		gr0,gr0,gr6
+	or		gr0,gr0,gr7
+	bralr
+	.size		__head_split_region, .-__head_split_region
+
+###############################################################################
+#
+# write the 32-bit hex number in GR8 to ttyS0
+#
+###############################################################################
+#if 0
+	.globl		__head_write_to_ttyS0
+	.type		__head_write_to_ttyS0,@function
+__head_write_to_ttyS0:
+	sethi.p		%hi(0xfeff9c00),gr31
+	setlo		%lo(0xfeff9c00),gr31
+	setlos		#8,gr20
+
+0:	ldubi		@(gr31,#5*8),gr21
+	andi		gr21,#0x60,gr21
+	subicc		gr21,#0x60,gr21,icc0
+	bne		icc0,#0,0b
+
+1:	srli		gr8,#28,gr21
+	slli		gr8,#4,gr8
+
+	addi		gr21,#'0',gr21
+	subicc		gr21,#'9',gr0,icc0
+	bls		icc0,#2,2f
+	addi		gr21,#'A'-'0'-10,gr21
+2:
+	stbi		gr21,@(gr31,#0*8)
+	subicc		gr20,#1,gr20,icc0
+	bhi		icc0,#2,1b
+
+	setlos		#'\r',gr21
+	stbi		gr21,@(gr31,#0*8)
+
+	setlos		#'\n',gr21
+	stbi		gr21,@(gr31,#0*8)
+
+3:	ldubi		@(gr31,#5*8),gr21
+	andi		gr21,#0x60,gr21
+	subicc		gr21,#0x60,gr21,icc0
+	bne		icc0,#0,3b
+	bralr
+
+	.size		__head_write_to_ttyS0, .-__head_write_to_ttyS0
+#endif
diff -Nru a/arch/frv/kernel/head.inc b/arch/frv/kernel/head.inc
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/kernel/head.inc	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,50 @@
+/* head.inc: head common definitions -*- asm -*-
+ *
+ * Copyright (C) 2004 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.
+ */
+
+
+#if defined(CONFIG_MB93090_MB00)
+#define LED_ADDR (0x21200000+4)
+
+.macro LEDS val
+	sethi.p		%hi(0xFFC00030),gr3
+	setlo		%lo(0xFFC00030),gr3
+	lduh		@(gr3,gr0),gr3
+	andicc		gr3,#0x100,gr0,icc0
+	bne		icc0,0,999f
+
+	setlos		#~\val,gr3
+	st		gr3,@(gr30,gr0)
+	membar
+	dcf		@(gr30,gr0)
+    999:
+.endm
+
+#elif defined(CONFIG_MB93093_PDK)
+#define LED_ADDR (0x20000023)
+
+.macro LEDS val
+	setlos		#\val,gr3
+	stb		gr3,@(gr30,gr0)
+	membar
+.endm
+
+#else
+#define LED_ADDR 0
+
+.macro LEDS val
+.endm
+#endif
+
+#ifdef CONFIG_MMU
+__sdram_base = 0x00000000		/* base address to which SDRAM relocated */
+#else
+__sdram_base = 0xc0000000		/* base address to which SDRAM relocated */
+#endif
diff -Nru a/arch/frv/kernel/init_task.c b/arch/frv/kernel/init_task.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/kernel/init_task.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,39 @@
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/init_task.h>
+#include <linux/fs.h>
+#include <linux/mqueue.h>
+
+#include <asm/uaccess.h>
+#include <asm/pgtable.h>
+
+
+static struct fs_struct init_fs = INIT_FS;
+static struct files_struct init_files = INIT_FILES;
+static struct signal_struct init_signals = INIT_SIGNALS(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);
+
+/*
+ * Initial thread structure.
+ *
+ * We need to make sure that this is THREAD_SIZE aligned due to the
+ * way process stacks are handled. This is done by having a special
+ * "init_task" linker map entry..
+ */
+union thread_union init_thread_union
+	__attribute__((__section__(".data.init_task"))) =
+		{ INIT_THREAD_INFO(init_task) };
+
+/*
+ * Initial task structure.
+ *
+ * All other task structs will be allocated on slabs in fork.c
+ */
+struct task_struct init_task = INIT_TASK(init_task);
+
+EXPORT_SYMBOL(init_task);
diff -Nru a/arch/frv/kernel/irq-mb93091.c b/arch/frv/kernel/irq-mb93091.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/kernel/irq-mb93091.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,116 @@
+/* irq-mb93091.c: MB93091 FPGA interrupt handling
+ *
+ * Copyright (C) 2003 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/config.h>
+#include <linux/ptrace.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/bitops.h>
+#include <asm/delay.h>
+#include <asm/irq.h>
+#include <asm/irc-regs.h>
+#include <asm/irq-routing.h>
+
+#define __reg16(ADDR) (*(volatile unsigned short *)(ADDR))
+
+#define __get_IMR()	({ __reg16(0xffc00004); })
+#define __set_IMR(M)	do { __reg16(0xffc00004) = (M); wmb(); } while(0)
+#define __get_IFR()	({ __reg16(0xffc0000c); })
+#define __clr_IFR(M)	do { __reg16(0xffc0000c) = ~(M); wmb(); } while(0)
+
+static void frv_fpga_doirq(struct irq_source *source);
+static void frv_fpga_control(struct irq_group *group, int irq, int on);
+
+/*****************************************************************************/
+/*
+ * FPGA IRQ multiplexor
+ */
+static struct irq_source frv_fpga[4] = {
+#define __FPGA(X, M)					\
+	[X] = {						\
+		.muxname	= "fpga."#X,		\
+		.irqmask	= M,			\
+		.doirq		= frv_fpga_doirq,	\
+	}
+
+	__FPGA(0, 0x0028),
+	__FPGA(1, 0x0050),
+	__FPGA(2, 0x1c00),
+	__FPGA(3, 0x6386),
+};
+
+static struct irq_group frv_fpga_irqs = {
+	.first_irq	= IRQ_BASE_FPGA,
+	.control	= frv_fpga_control,
+	.sources = {
+		[ 1] = &frv_fpga[3],
+		[ 2] = &frv_fpga[3],
+		[ 3] = &frv_fpga[0],
+		[ 4] = &frv_fpga[1],
+		[ 5] = &frv_fpga[0],
+		[ 6] = &frv_fpga[1],
+		[ 7] = &frv_fpga[3],
+		[ 8] = &frv_fpga[3],
+		[ 9] = &frv_fpga[3],
+		[10] = &frv_fpga[2],
+		[11] = &frv_fpga[2],
+		[12] = &frv_fpga[2],
+		[13] = &frv_fpga[3],
+		[14] = &frv_fpga[3],
+	},
+};
+
+
+static void frv_fpga_control(struct irq_group *group, int index, int on)
+{
+	uint16_t imr = __get_IMR();
+
+	if (on)
+		imr &= ~(1 << index);
+	else
+		imr |= 1 << index;
+
+	__set_IMR(imr);
+}
+
+static void frv_fpga_doirq(struct irq_source *source)
+{
+	uint16_t mask, imr;
+
+	imr = __get_IMR();
+	mask = source->irqmask & ~imr & __get_IFR();
+	if (mask) {
+		__set_IMR(imr | mask);
+		__clr_IFR(mask);
+		distribute_irqs(&frv_fpga_irqs, mask);
+		__set_IMR(imr);
+	}
+}
+
+void __init fpga_init(void)
+{
+	__set_IMR(0x7ffe);
+	__clr_IFR(0x0000);
+
+	frv_irq_route_external(&frv_fpga[0], IRQ_CPU_EXTERNAL0);
+	frv_irq_route_external(&frv_fpga[1], IRQ_CPU_EXTERNAL1);
+	frv_irq_route_external(&frv_fpga[2], IRQ_CPU_EXTERNAL2);
+	frv_irq_route_external(&frv_fpga[3], IRQ_CPU_EXTERNAL3);
+	frv_irq_set_group(&frv_fpga_irqs);
+}
diff -Nru a/arch/frv/kernel/irq-mb93093.c b/arch/frv/kernel/irq-mb93093.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/kernel/irq-mb93093.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,99 @@
+/* irq-mb93093.c: MB93093 FPGA interrupt handling
+ *
+ * Copyright (C) 2004 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/config.h>
+#include <linux/ptrace.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/bitops.h>
+#include <asm/delay.h>
+#include <asm/irq.h>
+#include <asm/irc-regs.h>
+#include <asm/irq-routing.h>
+
+#define __reg16(ADDR) (*(volatile unsigned short *)(__region_CS2 + (ADDR)))
+
+#define __get_IMR()	({ __reg16(0x0a); })
+#define __set_IMR(M)	do { __reg16(0x0a) = (M);  wmb(); } while(0)
+#define __get_IFR()	({ __reg16(0x02); })
+#define __clr_IFR(M)	do { __reg16(0x02) = ~(M); wmb(); } while(0)
+
+static void frv_fpga_doirq(struct irq_source *source);
+static void frv_fpga_control(struct irq_group *group, int irq, int on);
+
+/*****************************************************************************/
+/*
+ * FPGA IRQ multiplexor
+ */
+static struct irq_source frv_fpga[4] = {
+#define __FPGA(X, M)					\
+	[X] = {						\
+		.muxname	= "fpga."#X,		\
+		.irqmask	= M,			\
+		.doirq		= frv_fpga_doirq,	\
+	}
+
+	__FPGA(0, 0x0700),
+};
+
+static struct irq_group frv_fpga_irqs = {
+	.first_irq	= IRQ_BASE_FPGA,
+	.control	= frv_fpga_control,
+	.sources = {
+		[ 8] = &frv_fpga[0],
+		[ 9] = &frv_fpga[0],
+		[10] = &frv_fpga[0],
+	},
+};
+
+
+static void frv_fpga_control(struct irq_group *group, int index, int on)
+{
+	uint16_t imr = __get_IMR();
+
+	if (on)
+		imr &= ~(1 << index);
+	else
+		imr |= 1 << index;
+
+	__set_IMR(imr);
+}
+
+static void frv_fpga_doirq(struct irq_source *source)
+{
+	uint16_t mask, imr;
+
+	imr = __get_IMR();
+	mask = source->irqmask & ~imr & __get_IFR();
+	if (mask) {
+		__set_IMR(imr | mask);
+		__clr_IFR(mask);
+		distribute_irqs(&frv_fpga_irqs, mask);
+		__set_IMR(imr);
+	}
+}
+
+void __init fpga_init(void)
+{
+	__set_IMR(0x0700);
+	__clr_IFR(0x0000);
+
+	frv_irq_route_external(&frv_fpga[0], IRQ_CPU_EXTERNAL2);
+	frv_irq_set_group(&frv_fpga_irqs);
+}
diff -Nru a/arch/frv/kernel/irq-mb93493.c b/arch/frv/kernel/irq-mb93493.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/kernel/irq-mb93493.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,108 @@
+/* irq-mb93493.c: MB93493 companion chip interrupt handler
+ *
+ * Copyright (C) 2004 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/config.h>
+#include <linux/ptrace.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/bitops.h>
+#include <asm/delay.h>
+#include <asm/irq.h>
+#include <asm/irc-regs.h>
+#include <asm/irq-routing.h>
+#include <asm/mb93493-irqs.h>
+
+static void frv_mb93493_doirq(struct irq_source *source);
+
+/*****************************************************************************/
+/*
+ * MB93493 companion chip IRQ multiplexor
+ */
+static struct irq_source frv_mb93493[2] = {
+	[0] = {
+		.muxname		= "mb93493.0",
+		.muxdata		= __region_CS3 + 0x3d0,
+		.doirq			= frv_mb93493_doirq,
+		.irqmask		= 0x0000,
+	},
+	[1] = {
+		.muxname		= "mb93493.1",
+		.muxdata		= __region_CS3 + 0x3d4,
+		.doirq			= frv_mb93493_doirq,
+		.irqmask		= 0x0000,
+	},
+};
+
+static void frv_mb93493_control(struct irq_group *group, int index, int on)
+{
+	struct irq_source *source;
+	uint32_t iqsr;
+
+	if ((frv_mb93493[0].irqmask & (1 << index)))
+		source = &frv_mb93493[0];
+	else
+		source = &frv_mb93493[1];
+
+	iqsr = readl(source->muxdata);
+	if (on)
+		iqsr |= 1 << (index + 16);
+	else
+		iqsr &= ~(1 << (index + 16));
+
+	writel(iqsr, source->muxdata);
+}
+
+static struct irq_group frv_mb93493_irqs = {
+	.first_irq	= IRQ_BASE_MB93493,
+	.control	= frv_mb93493_control,
+};
+
+static void frv_mb93493_doirq(struct irq_source *source)
+{
+	uint32_t mask = readl(source->muxdata);
+	mask = mask & (mask >> 16) & 0xffff;
+
+	if (mask)
+		distribute_irqs(&frv_mb93493_irqs, mask);
+}
+
+static void __init mb93493_irq_route(int irq, int source)
+{
+	frv_mb93493[source].irqmask |= 1 << (irq - IRQ_BASE_MB93493);
+	frv_mb93493_irqs.sources[irq - IRQ_BASE_MB93493] = &frv_mb93493[source];
+}
+
+void __init route_mb93493_irqs(void)
+{
+	frv_irq_route_external(&frv_mb93493[0], IRQ_CPU_MB93493_0);
+	frv_irq_route_external(&frv_mb93493[1], IRQ_CPU_MB93493_1);
+
+	frv_irq_set_group(&frv_mb93493_irqs);
+
+	mb93493_irq_route(IRQ_MB93493_VDC,		IRQ_MB93493_VDC_ROUTE);
+	mb93493_irq_route(IRQ_MB93493_VCC,		IRQ_MB93493_VCC_ROUTE);
+	mb93493_irq_route(IRQ_MB93493_AUDIO_IN,		IRQ_MB93493_AUDIO_IN_ROUTE);
+	mb93493_irq_route(IRQ_MB93493_I2C_0,		IRQ_MB93493_I2C_0_ROUTE);
+	mb93493_irq_route(IRQ_MB93493_I2C_1,		IRQ_MB93493_I2C_1_ROUTE);
+	mb93493_irq_route(IRQ_MB93493_USB,		IRQ_MB93493_USB_ROUTE);
+	mb93493_irq_route(IRQ_MB93493_LOCAL_BUS,	IRQ_MB93493_LOCAL_BUS_ROUTE);
+	mb93493_irq_route(IRQ_MB93493_PCMCIA,		IRQ_MB93493_PCMCIA_ROUTE);
+	mb93493_irq_route(IRQ_MB93493_GPIO,		IRQ_MB93493_GPIO_ROUTE);
+	mb93493_irq_route(IRQ_MB93493_AUDIO_OUT,	IRQ_MB93493_AUDIO_OUT_ROUTE);
+}
diff -Nru a/arch/frv/kernel/irq-routing.c b/arch/frv/kernel/irq-routing.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/kernel/irq-routing.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,291 @@
+/* irq-routing.c: IRQ routing
+ *
+ * Copyright (C) 2004 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/sched.h>
+#include <linux/random.h>
+#include <linux/init.h>
+#include <linux/serial_reg.h>
+#include <asm/io.h>
+#include <asm/irq-routing.h>
+#include <asm/irc-regs.h>
+#include <asm/serial-regs.h>
+#include <asm/dma.h>
+
+struct irq_level frv_irq_levels[16] = {
+	[0 ... 15] = {
+		.lock	= SPIN_LOCK_UNLOCKED,
+	}
+};
+
+struct irq_group *irq_groups[NR_IRQ_GROUPS];
+
+extern struct irq_group frv_cpu_irqs;
+
+void __init frv_irq_route(struct irq_source *source, int irqlevel)
+{
+	source->level = &frv_irq_levels[irqlevel];
+	source->next = frv_irq_levels[irqlevel].sources;
+	frv_irq_levels[irqlevel].sources = source;
+}
+
+void __init frv_irq_route_external(struct irq_source *source, int irq)
+{
+	int irqlevel = 0;
+
+	switch (irq) {
+	case IRQ_CPU_EXTERNAL0:	irqlevel = IRQ_XIRQ0_LEVEL; break;
+	case IRQ_CPU_EXTERNAL1:	irqlevel = IRQ_XIRQ1_LEVEL; break;
+	case IRQ_CPU_EXTERNAL2:	irqlevel = IRQ_XIRQ2_LEVEL; break;
+	case IRQ_CPU_EXTERNAL3:	irqlevel = IRQ_XIRQ3_LEVEL; break;
+	case IRQ_CPU_EXTERNAL4:	irqlevel = IRQ_XIRQ4_LEVEL; break;
+	case IRQ_CPU_EXTERNAL5:	irqlevel = IRQ_XIRQ5_LEVEL; break;
+	case IRQ_CPU_EXTERNAL6:	irqlevel = IRQ_XIRQ6_LEVEL; break;
+	case IRQ_CPU_EXTERNAL7:	irqlevel = IRQ_XIRQ7_LEVEL; break;
+	default: BUG();
+	}
+
+	source->level = &frv_irq_levels[irqlevel];
+	source->next = frv_irq_levels[irqlevel].sources;
+	frv_irq_levels[irqlevel].sources = source;
+}
+
+void __init frv_irq_set_group(struct irq_group *group)
+{
+	irq_groups[group->first_irq >> NR_IRQ_LOG2_ACTIONS_PER_GROUP] = group;
+}
+
+void distribute_irqs(struct irq_group *group, unsigned long irqmask)
+{
+	struct irqaction *action;
+	int irq;
+
+	while (irqmask) {
+		asm("scan %1,gr0,%0" : "=r"(irq) : "r"(irqmask));
+		if (irq < 0 || irq > 31)
+			asm volatile("break");
+		irq = 31 - irq;
+
+		irqmask &= ~(1 << irq);
+		action = group->actions[irq];
+
+		irq += group->first_irq;
+
+		if (action) {
+			int status = 0;
+
+//			if (!(action->flags & SA_INTERRUPT))
+//				local_irq_enable();
+
+			do {
+				status |= action->flags;
+				action->handler(irq, action->dev_id, __frame);
+				action = action->next;
+			} while (action);
+
+			if (status & SA_SAMPLE_RANDOM)
+				add_interrupt_randomness(irq);
+			local_irq_disable();
+		}
+	}
+}
+
+/*****************************************************************************/
+/*
+ * CPU UART interrupts
+ */
+static void frv_cpuuart_doirq(struct irq_source *source)
+{
+//	uint8_t iir = readb(source->muxdata + UART_IIR * 8);
+//	if ((iir & 0x0f) != UART_IIR_NO_INT)
+		distribute_irqs(&frv_cpu_irqs, source->irqmask);
+}
+
+struct irq_source frv_cpuuart[2] = {
+#define __CPUUART(X, A)						\
+	[X] = {							\
+		.muxname	= "uart",			\
+		.muxdata	= (volatile void __iomem *) A,	\
+		.irqmask	= 1 << IRQ_CPU_UART##X,		\
+		.doirq		= frv_cpuuart_doirq,		\
+	}
+
+	__CPUUART(0, UART0_BASE),
+	__CPUUART(1, UART1_BASE),
+};
+
+/*****************************************************************************/
+/*
+ * CPU DMA interrupts
+ */
+static void frv_cpudma_doirq(struct irq_source *source)
+{
+	uint32_t cstr = readl(source->muxdata + DMAC_CSTRx);
+	if (cstr & DMAC_CSTRx_INT)
+		distribute_irqs(&frv_cpu_irqs, source->irqmask);
+}
+
+struct irq_source frv_cpudma[8] = {
+#define __CPUDMA(X, A)						\
+	[X] = {							\
+		.muxname	= "dma",			\
+		.muxdata	= (volatile void __iomem *) A,	\
+		.irqmask	= 1 << IRQ_CPU_DMA##X,		\
+		.doirq		= frv_cpudma_doirq,		\
+	}
+
+	__CPUDMA(0, 0xfe000900),
+	__CPUDMA(1, 0xfe000980),
+	__CPUDMA(2, 0xfe000a00),
+	__CPUDMA(3, 0xfe000a80),
+	__CPUDMA(4, 0xfe001000),
+	__CPUDMA(5, 0xfe001080),
+	__CPUDMA(6, 0xfe001100),
+	__CPUDMA(7, 0xfe001180),
+};
+
+/*****************************************************************************/
+/*
+ * CPU timer interrupts - can't tell whether they've generated an interrupt or not
+ */
+static void frv_cputimer_doirq(struct irq_source *source)
+{
+	distribute_irqs(&frv_cpu_irqs, source->irqmask);
+}
+
+struct irq_source frv_cputimer[3] = {
+#define __CPUTIMER(X)						\
+	[X] = {							\
+		.muxname	= "timer",			\
+		.muxdata	= 0,				\
+		.irqmask	= 1 << IRQ_CPU_TIMER##X,	\
+		.doirq		= frv_cputimer_doirq,		\
+	}
+
+	__CPUTIMER(0),
+	__CPUTIMER(1),
+	__CPUTIMER(2),
+};
+
+/*****************************************************************************/
+/*
+ * external CPU interrupts - can't tell directly whether they've generated an interrupt or not
+ */
+static void frv_cpuexternal_doirq(struct irq_source *source)
+{
+	distribute_irqs(&frv_cpu_irqs, source->irqmask);
+}
+
+struct irq_source frv_cpuexternal[8] = {
+#define __CPUEXTERNAL(X)					\
+	[X] = {							\
+		.muxname	= "ext",			\
+		.muxdata	= 0,				\
+		.irqmask	= 1 << IRQ_CPU_EXTERNAL##X,	\
+		.doirq		= frv_cpuexternal_doirq,	\
+	}
+
+	__CPUEXTERNAL(0),
+	__CPUEXTERNAL(1),
+	__CPUEXTERNAL(2),
+	__CPUEXTERNAL(3),
+	__CPUEXTERNAL(4),
+	__CPUEXTERNAL(5),
+	__CPUEXTERNAL(6),
+	__CPUEXTERNAL(7),
+};
+
+#define set_IRR(N,A,B,C,D) __set_IRR(N, (A << 28) | (B << 24) | (C << 20) | (D << 16))
+
+struct irq_group frv_cpu_irqs = {
+	.sources = {
+		[IRQ_CPU_UART0]		= &frv_cpuuart[0],
+		[IRQ_CPU_UART1]		= &frv_cpuuart[1],
+		[IRQ_CPU_TIMER0]	= &frv_cputimer[0],
+		[IRQ_CPU_TIMER1]	= &frv_cputimer[1],
+		[IRQ_CPU_TIMER2]	= &frv_cputimer[2],
+		[IRQ_CPU_DMA0]		= &frv_cpudma[0],
+		[IRQ_CPU_DMA1]		= &frv_cpudma[1],
+		[IRQ_CPU_DMA2]		= &frv_cpudma[2],
+		[IRQ_CPU_DMA3]		= &frv_cpudma[3],
+		[IRQ_CPU_DMA4]		= &frv_cpudma[4],
+		[IRQ_CPU_DMA5]		= &frv_cpudma[5],
+		[IRQ_CPU_DMA6]		= &frv_cpudma[6],
+		[IRQ_CPU_DMA7]		= &frv_cpudma[7],
+		[IRQ_CPU_EXTERNAL0]	= &frv_cpuexternal[0],
+		[IRQ_CPU_EXTERNAL1]	= &frv_cpuexternal[1],
+		[IRQ_CPU_EXTERNAL2]	= &frv_cpuexternal[2],
+		[IRQ_CPU_EXTERNAL3]	= &frv_cpuexternal[3],
+		[IRQ_CPU_EXTERNAL4]	= &frv_cpuexternal[4],
+		[IRQ_CPU_EXTERNAL5]	= &frv_cpuexternal[5],
+		[IRQ_CPU_EXTERNAL6]	= &frv_cpuexternal[6],
+		[IRQ_CPU_EXTERNAL7]	= &frv_cpuexternal[7],
+	},
+};
+
+/*****************************************************************************/
+/*
+ * route the CPU's interrupt sources
+ */
+void __init route_cpu_irqs(void)
+{
+	frv_irq_set_group(&frv_cpu_irqs);
+
+	__set_IITMR(0, 0x003f0000);	/* DMA0-3, TIMER0-2 IRQ detect levels */
+	__set_IITMR(1, 0x20000000);	/* ERR0-1, UART0-1, DMA4-7 IRQ detect levels */
+
+	/* route UART and error interrupts */
+	frv_irq_route(&frv_cpuuart[0],	IRQ_UART0_LEVEL);
+	frv_irq_route(&frv_cpuuart[1],	IRQ_UART1_LEVEL);
+
+	set_IRR(6, IRQ_GDBSTUB_LEVEL, IRQ_GDBSTUB_LEVEL, IRQ_UART1_LEVEL, IRQ_UART0_LEVEL);
+
+	/* route DMA channel interrupts */
+	frv_irq_route(&frv_cpudma[0],	IRQ_DMA0_LEVEL);
+	frv_irq_route(&frv_cpudma[1],	IRQ_DMA1_LEVEL);
+	frv_irq_route(&frv_cpudma[2],	IRQ_DMA2_LEVEL);
+	frv_irq_route(&frv_cpudma[3],	IRQ_DMA3_LEVEL);
+	frv_irq_route(&frv_cpudma[4],	IRQ_DMA4_LEVEL);
+	frv_irq_route(&frv_cpudma[5],	IRQ_DMA5_LEVEL);
+	frv_irq_route(&frv_cpudma[6],	IRQ_DMA6_LEVEL);
+	frv_irq_route(&frv_cpudma[7],	IRQ_DMA7_LEVEL);
+
+	set_IRR(4, IRQ_DMA3_LEVEL, IRQ_DMA2_LEVEL, IRQ_DMA1_LEVEL, IRQ_DMA0_LEVEL);
+	set_IRR(7, IRQ_DMA7_LEVEL, IRQ_DMA6_LEVEL, IRQ_DMA5_LEVEL, IRQ_DMA4_LEVEL);
+
+	/* route timer interrupts */
+	frv_irq_route(&frv_cputimer[0],	IRQ_TIMER0_LEVEL);
+	frv_irq_route(&frv_cputimer[1],	IRQ_TIMER1_LEVEL);
+	frv_irq_route(&frv_cputimer[2],	IRQ_TIMER2_LEVEL);
+
+	set_IRR(5, 0, IRQ_TIMER2_LEVEL, IRQ_TIMER1_LEVEL, IRQ_TIMER0_LEVEL);
+
+	/* route external interrupts */
+	frv_irq_route(&frv_cpuexternal[0], IRQ_XIRQ0_LEVEL);
+	frv_irq_route(&frv_cpuexternal[1], IRQ_XIRQ1_LEVEL);
+	frv_irq_route(&frv_cpuexternal[2], IRQ_XIRQ2_LEVEL);
+	frv_irq_route(&frv_cpuexternal[3], IRQ_XIRQ3_LEVEL);
+	frv_irq_route(&frv_cpuexternal[4], IRQ_XIRQ4_LEVEL);
+	frv_irq_route(&frv_cpuexternal[5], IRQ_XIRQ5_LEVEL);
+	frv_irq_route(&frv_cpuexternal[6], IRQ_XIRQ6_LEVEL);
+	frv_irq_route(&frv_cpuexternal[7], IRQ_XIRQ7_LEVEL);
+
+	set_IRR(2, IRQ_XIRQ7_LEVEL, IRQ_XIRQ6_LEVEL, IRQ_XIRQ5_LEVEL, IRQ_XIRQ4_LEVEL);
+	set_IRR(3, IRQ_XIRQ3_LEVEL, IRQ_XIRQ2_LEVEL, IRQ_XIRQ1_LEVEL, IRQ_XIRQ0_LEVEL);
+
+#if defined(CONFIG_MB93091_VDK)
+	__set_TM1(0x55550000);		/* XIRQ7-0 all active low */
+#elif defined(CONFIG_MB93093_PDK)
+	__set_TM1(0x15550000);		/* XIRQ7 active high, 6-0 all active low */
+#else
+#error dont know external IRQ trigger levels for this setup
+#endif
+
+} /* end route_cpu_irqs() */
diff -Nru a/arch/frv/kernel/irq.c b/arch/frv/kernel/irq.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/kernel/irq.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,764 @@
+/* irq.c: FRV IRQ handling
+ *
+ * Copyright (C) 2003, 2004 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.
+ */
+
+/*
+ * (mostly architecture independent, will move to kernel/irq.c in 2.5.)
+ *
+ * IRQs are in fact implemented a bit like signal handlers for the kernel.
+ * Naturally it's not a 1:1 relation, but there are similarities.
+ */
+
+#include <linux/config.h>
+#include <linux/ptrace.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/timex.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <linux/smp_lock.h>
+#include <linux/init.h>
+#include <linux/kernel_stat.h>
+#include <linux/irq.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+
+#include <asm/atomic.h>
+#include <asm/io.h>
+#include <asm/smp.h>
+#include <asm/system.h>
+#include <asm/bitops.h>
+#include <asm/uaccess.h>
+#include <asm/pgalloc.h>
+#include <asm/delay.h>
+#include <asm/irq.h>
+#include <asm/irc-regs.h>
+#include <asm/irq-routing.h>
+#include <asm/gdb-stub.h>
+
+extern void __init fpga_init(void);
+extern void __init route_mb93493_irqs(void);
+
+static void register_irq_proc (unsigned int irq);
+
+/*
+ * Special irq handlers.
+ */
+
+irqreturn_t no_action(int cpl, void *dev_id, struct pt_regs *regs) { return IRQ_HANDLED; }
+
+atomic_t irq_err_count;
+
+/*
+ * Generic, controller-independent functions:
+ */
+int show_interrupts(struct seq_file *p, void *v)
+{
+	struct irqaction *action;
+	struct irq_group *group;
+	unsigned long flags;
+	int level, grp, ix, i, j;
+
+	i = *(loff_t *) v;
+
+	switch (i) {
+	case 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');
+		break;
+
+	case 1 ... NR_IRQ_GROUPS * NR_IRQ_ACTIONS_PER_GROUP:
+		local_irq_save(flags);
+
+		grp = (i - 1) / NR_IRQ_ACTIONS_PER_GROUP;
+		group = irq_groups[grp];
+		if (!group)
+			goto skip;
+
+		ix = (i - 1) % NR_IRQ_ACTIONS_PER_GROUP;
+		action = group->actions[ix];
+		if (!action)
+			goto skip;
+
+		seq_printf(p, "%3d: ", i - 1);
+
+#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 - 1]);
+#endif
+
+		level = group->sources[ix]->level - frv_irq_levels;
+
+		seq_printf(p, " %12s@%x", group->sources[ix]->muxname, level);
+		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);
+		break;
+
+	case NR_IRQ_GROUPS * NR_IRQ_ACTIONS_PER_GROUP + 1:
+		seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
+		break;
+
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+
+/*
+ * Generic enable/disable code: this just calls
+ * down into the PIC-specific version for the actual
+ * hardware disable after having gotten the irq
+ * controller lock.
+ */
+
+/**
+ *	disable_irq_nosync - disable an irq without waiting
+ *	@irq: Interrupt to disable
+ *
+ *	Disable the selected interrupt line.  Disables and Enables are
+ *	nested.
+ *	Unlike disable_irq(), this function does not ensure existing
+ *	instances of the IRQ handler have completed before returning.
+ *
+ *	This function may be called from IRQ context.
+ */
+
+void disable_irq_nosync(unsigned int irq)
+{
+	struct irq_source *source;
+	struct irq_group *group;
+	struct irq_level *level;
+	unsigned long flags;
+	int idx = irq & (NR_IRQ_ACTIONS_PER_GROUP - 1);
+
+	group = irq_groups[irq >> NR_IRQ_LOG2_ACTIONS_PER_GROUP];
+	if (!group)
+		BUG();
+
+	source = group->sources[idx];
+	if (!source)
+		BUG();
+
+	level = source->level;
+
+	spin_lock_irqsave(&level->lock, flags);
+
+	if (group->control) {
+		if (!group->disable_cnt[idx]++)
+			group->control(group, idx, 0);
+	} else if (!level->disable_count++) {
+		__set_MASK(level - frv_irq_levels);
+	}
+
+	spin_unlock_irqrestore(&level->lock, flags);
+}
+
+/**
+ *	disable_irq - disable an irq and wait for completion
+ *	@irq: Interrupt to disable
+ *
+ *	Disable the selected interrupt line.  Enables and Disables are
+ *	nested.
+ *	This function waits for any pending IRQ handlers for this interrupt
+ *	to complete before returning. If you use this function while
+ *	holding a resource the IRQ handler may need you will deadlock.
+ *
+ *	This function may be called - with care - from IRQ context.
+ */
+
+void disable_irq(unsigned int irq)
+{
+	disable_irq_nosync(irq);
+
+#ifdef CONFIG_SMP
+	if (!local_irq_count(smp_processor_id())) {
+		do {
+			barrier();
+		} while (irq_desc[irq].status & IRQ_INPROGRESS);
+	}
+#endif
+}
+
+/**
+ *	enable_irq - enable handling of an irq
+ *	@irq: Interrupt to enable
+ *
+ *	Undoes the effect of one call to disable_irq().  If this
+ *	matches the last disable, processing of interrupts on this
+ *	IRQ line is re-enabled.
+ *
+ *	This function may be called from IRQ context.
+ */
+
+void enable_irq(unsigned int irq)
+{
+	struct irq_source *source;
+	struct irq_group *group;
+	struct irq_level *level;
+	unsigned long flags;
+	int idx = irq & (NR_IRQ_ACTIONS_PER_GROUP - 1);
+	int count;
+
+	group = irq_groups[irq >> NR_IRQ_LOG2_ACTIONS_PER_GROUP];
+	if (!group)
+		BUG();
+
+	source = group->sources[idx];
+	if (!source)
+		BUG();
+
+	level = source->level;
+
+	spin_lock_irqsave(&level->lock, flags);
+
+	if (group->control)
+		count = group->disable_cnt[idx];
+	else
+		count = level->disable_count;
+
+	switch (count) {
+	case 1:
+		if (group->control) {
+			if (group->actions[idx])
+				group->control(group, idx, 1);
+		} else {
+			if (level->usage)
+				__clr_MASK(level - frv_irq_levels);
+		}
+		/* fall-through */
+
+	default:
+		count--;
+		break;
+
+	case 0:
+		printk("enable_irq(%u) unbalanced from %p\n", irq, __builtin_return_address(0));
+	}
+
+	if (group->control)
+		group->disable_cnt[idx] = count;
+	else
+		level->disable_count = count;
+
+	spin_unlock_irqrestore(&level->lock, flags);
+}
+
+/*****************************************************************************/
+/*
+ * handles all normal device IRQ's
+ * - registers are referred to by the __frame variable (GR28)
+ * - IRQ distribution is complicated in this arch because of the many PICs, the
+ *   way they work and the way they cascade
+ */
+asmlinkage void do_IRQ(void)
+{
+	struct irq_source *source;
+	int level, cpu;
+
+	level = (__frame->tbr >> 4) & 0xf;
+	cpu = smp_processor_id();
+
+#if 0
+	{
+		static u32 irqcount;
+		*(volatile u32 *) 0xe1200004 = ~((irqcount++ << 8) | level);
+		*(volatile u16 *) 0xffc00100 = (u16) ~0x9999;
+		mb();
+	}
+#endif
+
+	if ((unsigned long) __frame - (unsigned long) (current + 1) < 512)
+		BUG();
+
+	__set_MASK(level);
+	__clr_RC(level);
+	__clr_IRL();
+
+	kstat_this_cpu.irqs[level]++;
+
+	irq_enter();
+
+	for (source = frv_irq_levels[level].sources; source; source = source->next)
+		source->doirq(source);
+
+	irq_exit();
+
+	__clr_MASK(level);
+
+	/* only process softirqs if we didn't interrupt another interrupt handler */
+	if ((__frame->psr & PSR_PIL) == PSR_PIL_0)
+		if (local_softirq_pending())
+			do_softirq();
+
+#ifdef CONFIG_PREEMPT
+	local_irq_disable();
+	while (--current->preempt_count == 0) {
+		if (!(__frame->psr & PSR_S) ||
+		    current->need_resched == 0 ||
+		    in_interrupt())
+			break;
+		current->preempt_count++;
+		local_irq_enable();
+		preempt_schedule();
+		local_irq_disable();
+	}
+#endif
+
+#if 0
+	{
+		*(volatile u16 *) 0xffc00100 = (u16) ~0x6666;
+		mb();
+	}
+#endif
+
+} /* end do_IRQ() */
+
+/*****************************************************************************/
+/*
+ * handles all NMIs when not co-opted by the debugger
+ * - registers are referred to by the __frame variable (GR28)
+ */
+asmlinkage void do_NMI(void)
+{
+} /* end do_NMI() */
+
+/*****************************************************************************/
+/**
+ *	request_irq - allocate an interrupt line
+ *	@irq: Interrupt line to allocate
+ *	@handler: Function to be called when the IRQ occurs
+ *	@irqflags: Interrupt type flags
+ *	@devname: An ascii name for the claiming device
+ *	@dev_id: A cookie passed back to the handler function
+ *
+ *	This call allocates interrupt resources and enables the
+ *	interrupt line and IRQ handling. From the point this
+ *	call is made your handler function may be invoked. Since
+ *	your handler function must clear any interrupt the board
+ *	raises, you must take care both to initialise your hardware
+ *	and to set up the interrupt handler in the right order.
+ *
+ *	Dev_id must be globally unique. Normally the address of the
+ *	device data structure is used as the cookie. Since the handler
+ *	receives this value it makes sense to use it.
+ *
+ *	If your interrupt is shared you must pass a non NULL dev_id
+ *	as this is required when freeing the interrupt.
+ *
+ *	Flags:
+ *
+ *	SA_SHIRQ		Interrupt is shared
+ *
+ *	SA_INTERRUPT		Disable local interrupts while processing
+ *
+ *	SA_SAMPLE_RANDOM	The interrupt can be used for entropy
+ *
+ */
+
+int request_irq(unsigned int irq,
+		irqreturn_t (*handler)(int, void *, struct pt_regs *),
+		unsigned long irqflags,
+		const char * devname,
+		void *dev_id)
+{
+	int retval;
+	struct irqaction *action;
+
+#if 1
+	/*
+	 * Sanity-check: shared interrupts should REALLY pass in
+	 * a real dev-ID, otherwise we'll have trouble later trying
+	 * to figure out which interrupt is which (messes up the
+	 * interrupt freeing logic etc).
+	 */
+	if (irqflags & SA_SHIRQ) {
+		if (!dev_id)
+			printk("Bad boy: %s (at 0x%x) called us without a dev_id!\n",
+			       devname, (&irq)[-1]);
+	}
+#endif
+
+	if ((irq >> NR_IRQ_LOG2_ACTIONS_PER_GROUP) >= NR_IRQ_GROUPS)
+		return -EINVAL;
+	if (!handler)
+		return -EINVAL;
+
+	action = (struct irqaction *) kmalloc(sizeof(struct irqaction), GFP_KERNEL);
+	if (!action)
+		return -ENOMEM;
+
+	action->handler = handler;
+	action->flags = irqflags;
+	action->mask = CPU_MASK_NONE;
+	action->name = devname;
+	action->next = NULL;
+	action->dev_id = dev_id;
+
+	retval = setup_irq(irq, action);
+	if (retval)
+		kfree(action);
+	return retval;
+}
+
+/**
+ *	free_irq - free an interrupt
+ *	@irq: Interrupt line to free
+ *	@dev_id: Device identity to free
+ *
+ *	Remove an interrupt handler. The handler is removed and if the
+ *	interrupt line is no longer in use by any driver it is disabled.
+ *	On a shared IRQ the caller must ensure the interrupt is disabled
+ *	on the card it drives before calling this function. The function
+ *	does not return until any executing interrupts for this IRQ
+ *	have completed.
+ *
+ *	This function may be called from interrupt context.
+ *
+ *	Bugs: Attempting to free an irq in a handler for the same irq hangs
+ *	      the machine.
+ */
+
+void free_irq(unsigned int irq, void *dev_id)
+{
+	struct irq_source *source;
+	struct irq_group *group;
+	struct irq_level *level;
+	struct irqaction **p, **pp;
+	unsigned long flags;
+
+	if ((irq >> NR_IRQ_LOG2_ACTIONS_PER_GROUP) >= NR_IRQ_GROUPS)
+		return;
+
+	group = irq_groups[irq >> NR_IRQ_LOG2_ACTIONS_PER_GROUP];
+	if (!group)
+		BUG();
+
+	source = group->sources[irq & (NR_IRQ_ACTIONS_PER_GROUP - 1)];
+	if (!source)
+		BUG();
+
+	level = source->level;
+	p = &group->actions[irq & (NR_IRQ_ACTIONS_PER_GROUP - 1)];
+
+	spin_lock_irqsave(&level->lock, flags);
+
+	for (pp = p; *pp; pp = &(*pp)->next) {
+		struct irqaction *action = *pp;
+
+		if (action->dev_id != dev_id)
+			continue;
+
+		/* found it - remove from the list of entries */
+		*pp = action->next;
+
+		level->usage--;
+
+		if (p == pp && group->control)
+			group->control(group, irq & (NR_IRQ_ACTIONS_PER_GROUP - 1), 0);
+
+		if (level->usage == 0)
+			__set_MASK(level - frv_irq_levels);
+
+		spin_unlock_irqrestore(&level->lock,flags);
+
+#ifdef CONFIG_SMP
+		/* Wait to make sure it's not being used on another CPU */
+		while (desc->status & IRQ_INPROGRESS)
+			barrier();
+#endif
+		kfree(action);
+		return;
+	}
+}
+
+/*
+ * IRQ autodetection code..
+ *
+ * This depends on the fact that any interrupt that comes in on to an
+ * unassigned IRQ will cause GxICR_DETECT to be set
+ */
+
+static DECLARE_MUTEX(probe_sem);
+
+/**
+ *	probe_irq_on	- begin an interrupt autodetect
+ *
+ *	Commence probing for an interrupt. The interrupts are scanned
+ *	and a mask of potential interrupt lines is returned.
+ *
+ */
+
+unsigned long probe_irq_on(void)
+{
+	down(&probe_sem);
+	return 0;
+}
+
+/*
+ * Return a mask of triggered interrupts (this
+ * can handle only legacy ISA interrupts).
+ */
+
+/**
+ *	probe_irq_mask - scan a bitmap of interrupt lines
+ *	@val:	mask of interrupts to consider
+ *
+ *	Scan the ISA bus interrupt lines and return a bitmap of
+ *	active interrupts. The interrupt probe logic state is then
+ *	returned to its previous value.
+ *
+ *	Note: we need to scan all the irq's even though we will
+ *	only return ISA irq numbers - just so that we reset them
+ *	all to a known state.
+ */
+unsigned int probe_irq_mask(unsigned long xmask)
+{
+	up(&probe_sem);
+	return 0;
+}
+
+/*
+ * Return the one interrupt that triggered (this can
+ * handle any interrupt source).
+ */
+
+/**
+ *	probe_irq_off	- end an interrupt autodetect
+ *	@xmask: mask of potential interrupts (unused)
+ *
+ *	Scans the unused interrupt lines and returns the line which
+ *	appears to have triggered the interrupt. If no interrupt was
+ *	found then zero is returned. If more than one interrupt is
+ *	found then minus the first candidate is returned to indicate
+ *	their is doubt.
+ *
+ *	The interrupt probe logic state is returned to its previous
+ *	value.
+ *
+ *	BUGS: When used in a module (which arguably shouldnt happen)
+ *	nothing prevents two IRQ probe callers from overlapping. The
+ *	results of this are non-optimal.
+ */
+
+int probe_irq_off(unsigned long xmask)
+{
+	up(&probe_sem);
+	return -1;
+}
+
+/* this was setup_x86_irq but it seems pretty generic */
+int setup_irq(unsigned int irq, struct irqaction *new)
+{
+	struct irq_source *source;
+	struct irq_group *group;
+	struct irq_level *level;
+	struct irqaction **p, **pp;
+	unsigned long flags;
+
+	group = irq_groups[irq >> NR_IRQ_LOG2_ACTIONS_PER_GROUP];
+	if (!group)
+		BUG();
+
+	source = group->sources[irq & (NR_IRQ_ACTIONS_PER_GROUP - 1)];
+	if (!source)
+		BUG();
+
+	level = source->level;
+
+	p = &group->actions[irq & (NR_IRQ_ACTIONS_PER_GROUP - 1)];
+
+	/*
+	 * Some drivers like serial.c use request_irq() heavily,
+	 * so we have to be careful not to interfere with a
+	 * running system.
+	 */
+	if (new->flags & SA_SAMPLE_RANDOM) {
+		/*
+		 * This function might sleep, we want to call it first,
+		 * outside of the atomic block.
+		 * Yes, this might clear the entropy pool if the wrong
+		 * driver is attempted to be loaded, without actually
+		 * installing a new handler, but is this really a problem,
+		 * only the sysadmin is able to do this.
+		 */
+		rand_initialize_irq(irq);
+	}
+
+	/* must juggle the interrupt processing stuff with interrupts disabled */
+	spin_lock_irqsave(&level->lock, flags);
+
+	/* can't share interrupts unless all parties agree to */
+	if (level->usage != 0 && !(level->flags & new->flags & SA_SHIRQ)) {
+		spin_unlock_irqrestore(&level->lock,flags);
+		return -EBUSY;
+	}
+
+	/* add new interrupt at end of irq queue */
+	pp = p;
+	while (*pp)
+		pp = &(*pp)->next;
+
+	*pp = new;
+
+	level->usage++;
+	level->flags = new->flags;
+
+	/* turn the interrupts on */
+	if (level->usage == 1)
+		__clr_MASK(level - frv_irq_levels);
+
+	if (p == pp && group->control)
+		group->control(group, irq & (NR_IRQ_ACTIONS_PER_GROUP - 1), 1);
+
+	spin_unlock_irqrestore(&level->lock, flags);
+	register_irq_proc(irq);
+	return 0;
+}
+
+static struct proc_dir_entry * root_irq_dir;
+static struct proc_dir_entry * irq_dir [NR_IRQS];
+
+#define HEX_DIGITS 8
+
+static unsigned int parse_hex_value (const char *buffer,
+				     unsigned long count, unsigned long *ret)
+{
+	unsigned char hexnum [HEX_DIGITS];
+	unsigned long value;
+	int i;
+
+	if (!count)
+		return -EINVAL;
+	if (count > HEX_DIGITS)
+		count = HEX_DIGITS;
+	if (copy_from_user(hexnum, buffer, count))
+		return -EFAULT;
+
+	/*
+	 * Parse the first 8 characters as a hex string, any non-hex char
+	 * is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same.
+	 */
+	value = 0;
+
+	for (i = 0; i < count; i++) {
+		unsigned int c = hexnum[i];
+
+		switch (c) {
+			case '0' ... '9': c -= '0'; break;
+			case 'a' ... 'f': c -= 'a'-10; break;
+			case 'A' ... 'F': c -= 'A'-10; break;
+		default:
+			goto out;
+		}
+		value = (value << 4) | c;
+	}
+out:
+	*ret = value;
+	return 0;
+}
+
+
+static int prof_cpu_mask_read_proc (char *page, char **start, off_t off,
+			int count, int *eof, void *data)
+{
+	unsigned long *mask = (unsigned long *) data;
+	if (count < HEX_DIGITS+1)
+		return -EINVAL;
+	return sprintf (page, "%08lx\n", *mask);
+}
+
+static int prof_cpu_mask_write_proc (struct file *file, const char *buffer,
+					unsigned long count, void *data)
+{
+	unsigned long *mask = (unsigned long *) data, full_count = count, err;
+	unsigned long new_value;
+
+	show_state();
+	err = parse_hex_value(buffer, count, &new_value);
+	if (err)
+		return err;
+
+	*mask = new_value;
+	return full_count;
+}
+
+#define MAX_NAMELEN 10
+
+static void register_irq_proc (unsigned int irq)
+{
+	char name [MAX_NAMELEN];
+
+	if (!root_irq_dir || irq_dir[irq])
+		return;
+
+	memset(name, 0, MAX_NAMELEN);
+	sprintf(name, "%d", irq);
+
+	/* create /proc/irq/1234 */
+	irq_dir[irq] = proc_mkdir(name, root_irq_dir);
+}
+
+unsigned long prof_cpu_mask = -1;
+
+void init_irq_proc (void)
+{
+	struct proc_dir_entry *entry;
+	int i;
+
+	/* create /proc/irq */
+	root_irq_dir = proc_mkdir("irq", 0);
+
+	/* create /proc/irq/prof_cpu_mask */
+	entry = create_proc_entry("prof_cpu_mask", 0600, root_irq_dir);
+	if (!entry)
+	    return;
+
+	entry->nlink = 1;
+	entry->data = (void *)&prof_cpu_mask;
+	entry->read_proc = prof_cpu_mask_read_proc;
+	entry->write_proc = prof_cpu_mask_write_proc;
+
+	/*
+	 * Create entries for all existing IRQs.
+	 */
+	for (i = 0; i < NR_IRQS; i++)
+		register_irq_proc(i);
+}
+
+/*****************************************************************************/
+/*
+ * initialise the interrupt system
+ */
+void __init init_IRQ(void)
+{
+	route_cpu_irqs();
+	fpga_init();
+#ifdef CONFIG_FUJITSU_MB93493
+	route_mb93493_irqs();
+#endif
+} /* end init_IRQ() */
diff -Nru a/arch/frv/kernel/kernel_thread.S b/arch/frv/kernel/kernel_thread.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/kernel/kernel_thread.S	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,77 @@
+/* kernel_thread.S: kernel thread creation
+ *
+ * Copyright (C) 2003 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/linkage.h>
+#include <asm/unistd.h>
+
+#define CLONE_VM	0x00000100	/* set if VM shared between processes */
+#define	KERN_ERR	"<3>"
+
+	.section .rodata
+kernel_thread_emsg:
+	.asciz	KERN_ERR "failed to create kernel thread: error=%d\n"
+
+	.text
+	.balign		4
+
+###############################################################################
+#
+# Create a kernel thread
+#
+# int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
+#
+###############################################################################
+	.globl		kernel_thread
+	.type		kernel_thread,@function
+kernel_thread:
+	or.p		gr8,gr0,gr4
+	or		gr9,gr0,gr5
+
+	# start by forking the current process, but with shared VM
+	setlos.p	#__NR_clone,gr7		; syscall number
+	ori		gr10,#CLONE_VM,gr8	; first syscall arg	[clone_flags]
+	sethi.p		#0xe4e4,gr9		; second syscall arg	[newsp]
+	setlo		#0xe4e4,gr9
+	setlos.p	#0,gr10			; third syscall arg	[parent_tidptr]
+	setlos		#0,gr11			; fourth syscall arg	[child_tidptr]
+	tira		gr0,#0
+	setlos.p	#4095,gr7
+	andcc		gr8,gr8,gr0,icc0
+	addcc.p		gr8,gr7,gr0,icc1
+	bnelr		icc0,#2
+	bc		icc1,#0,kernel_thread_error
+
+	# now invoke the work function
+	or		gr5,gr0,gr8
+	calll		@(gr4,gr0)
+
+	# and finally exit the thread
+	setlos		#__NR_exit,gr7		; syscall number
+	tira		gr0,#0
+
+kernel_thread_error:
+	subi		sp,#8,sp
+	movsg		lr,gr4
+	sti		gr8,@(sp,#0)
+	sti.p		gr4,@(sp,#4)
+
+	or		gr8,gr0,gr9
+	sethi.p		%hi(kernel_thread_emsg),gr8
+	setlo		%lo(kernel_thread_emsg),gr8
+
+	call		printk
+
+	ldi		@(sp,#4),gr4
+	ldi		@(sp,#0),gr8
+	subi		sp,#8,sp
+	jmpl		@(gr4,gr0)
+
+	.size		kernel_thread,.-kernel_thread
diff -Nru a/arch/frv/kernel/local.h b/arch/frv/kernel/local.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/kernel/local.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,56 @@
+/* local.h: local definitions
+ *
+ * Copyright (C) 2004 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.
+ */
+
+#ifndef _FRV_LOCAL_H
+#define _FRV_LOCAL_H
+
+#include <asm/sections.h>
+
+#ifndef __ASSEMBLY__
+
+/* dma.c */
+extern unsigned long frv_dma_inprogress;
+
+extern void frv_dma_pause_all(void);
+extern void frv_dma_resume_all(void);
+
+/* sleep.S */
+extern asmlinkage void frv_cpu_suspend(unsigned long);
+extern asmlinkage void frv_cpu_core_sleep(void);
+
+/* setup.c */
+extern unsigned long __nongprelbss pdm_suspend_mode;
+extern void determine_clocks(int verbose);
+extern int __nongprelbss clock_p0_current;
+extern int __nongprelbss clock_cm_current;
+extern int __nongprelbss clock_cmode_current;
+
+#ifdef CONFIG_PM
+extern int __nongprelbss clock_cmodes_permitted;
+extern unsigned long __nongprelbss clock_bits_settable;
+#define CLOCK_BIT_CM		0x0000000f
+#define CLOCK_BIT_CM_H		0x00000001	/* CLKC.CM can be set to 0 */
+#define CLOCK_BIT_CM_M		0x00000002	/* CLKC.CM can be set to 1 */
+#define CLOCK_BIT_CM_L		0x00000004	/* CLKC.CM can be set to 2 */
+#define CLOCK_BIT_P0		0x00000010	/* CLKC.P0 can be changed */
+#define CLOCK_BIT_CMODE		0x00000020	/* CLKC.CMODE can be changed */
+
+extern void (*__power_switch_wake_setup)(void);
+extern int  (*__power_switch_wake_check)(void);
+extern void (*__power_switch_wake_cleanup)(void);
+#endif
+
+/* time.c */
+extern void time_divisor_init(void);
+
+
+#endif /* __ASSEMBLY__ */
+#endif /* _FRV_LOCAL_H */
diff -Nru a/arch/frv/kernel/pm-mb93093.c b/arch/frv/kernel/pm-mb93093.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/kernel/pm-mb93093.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,66 @@
+/*
+ * FR-V MB93093 Power Management Routines
+ *
+ * Copyright (c) 2004 Red Hat, Inc.
+ *
+ * Written by: msalter@redhat.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/pm.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/sysctl.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <asm/uaccess.h>
+
+#include <asm/mb86943a.h>
+
+#include "local.h"
+
+static unsigned long imask;
+/*
+ * Setup interrupt masks, etc to enable wakeup by power switch
+ */
+static void mb93093_power_switch_setup(void)
+{
+	/* mask all but FPGA interrupt sources. */
+	imask = *(volatile unsigned long *)0xfeff9820;
+	*(volatile unsigned long *)0xfeff9820 = ~(1 << (IRQ_XIRQ2_LEVEL + 16)) & 0xfffe0000;
+}
+
+/*
+ * Cleanup interrupt masks, etc after wakeup by power switch
+ */
+static void mb93093_power_switch_cleanup(void)
+{
+	*(volatile unsigned long *)0xfeff9820 = imask;
+}
+
+/*
+ * Return non-zero if wakeup irq was caused by power switch
+ */
+static int mb93093_power_switch_check(void)
+{
+	return 1;
+}
+
+/*
+ * Initialize power interface
+ */
+static int __init mb93093_pm_init(void)
+{
+	__power_switch_wake_setup = mb93093_power_switch_setup;
+	__power_switch_wake_check = mb93093_power_switch_check;
+	__power_switch_wake_cleanup = mb93093_power_switch_cleanup;
+	return 0;
+}
+
+__initcall(mb93093_pm_init);
+
diff -Nru a/arch/frv/kernel/pm.c b/arch/frv/kernel/pm.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/kernel/pm.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,432 @@
+/*
+ * FR-V Power Management Routines
+ *
+ * Copyright (c) 2004 Red Hat, Inc.
+ *
+ * Based on SA1100 version:
+ * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/pm.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/sysctl.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <asm/uaccess.h>
+
+#include <asm/mb86943a.h>
+
+#include "local.h"
+
+void (*pm_power_off)(void);
+
+extern void frv_change_cmode(int);
+
+/*
+ * Debug macros
+ */
+#define DEBUG
+
+int pm_do_suspend(void)
+{
+	local_irq_disable();
+
+	__set_LEDS(0xb1);
+
+	/* go zzz */
+	frv_cpu_suspend(pdm_suspend_mode);
+
+	__set_LEDS(0xb2);
+
+	local_irq_enable();
+
+	return 0;
+}
+
+static unsigned long __irq_mask;
+
+/*
+ * Setup interrupt masks, etc to enable wakeup by power switch
+ */
+static void __default_power_switch_setup(void)
+{
+	/* default is to mask all interrupt sources. */
+	__irq_mask = *(unsigned long *)0xfeff9820;
+	*(unsigned long *)0xfeff9820 = 0xfffe0000;
+}
+
+/*
+ * Cleanup interrupt masks, etc after wakeup by power switch
+ */
+static void __default_power_switch_cleanup(void)
+{
+	*(unsigned long *)0xfeff9820 = __irq_mask;
+}
+
+/*
+ * Return non-zero if wakeup irq was caused by power switch
+ */
+static int __default_power_switch_check(void)
+{
+	return 1;
+}
+
+void (*__power_switch_wake_setup)(void) = __default_power_switch_setup;
+int  (*__power_switch_wake_check)(void) = __default_power_switch_check;
+void (*__power_switch_wake_cleanup)(void) = __default_power_switch_cleanup;
+
+int pm_do_bus_sleep(void)
+{
+	local_irq_disable();
+
+	/*
+         * Here is where we need some platform-dependent setup
+	 * of the interrupt state so that appropriate wakeup
+	 * sources are allowed and all others are masked.
+	 */
+	__power_switch_wake_setup();
+
+	__set_LEDS(0xa1);
+
+	/* go zzz
+	 *
+	 * This is in a loop in case power switch shares an irq with other
+	 * devices. The wake_check() tells us if we need to finish waking
+	 * or go back to sleep.
+	 */
+	do {
+		frv_cpu_suspend(HSR0_PDM_BUS_SLEEP);
+	} while (__power_switch_wake_check && !__power_switch_wake_check());
+
+	__set_LEDS(0xa2);
+
+	/*
+         * Here is where we need some platform-dependent restore
+	 * of the interrupt state prior to being called.
+	 */
+	__power_switch_wake_cleanup();
+
+	local_irq_enable();
+
+	return 0;
+}
+
+unsigned long sleep_phys_sp(void *sp)
+{
+	return virt_to_phys(sp);
+}
+
+#ifdef CONFIG_SYSCTL
+/*
+ * Use a temporary sysctl number. Horrid, but will be cleaned up in 2.6
+ * when all the PM interfaces exist nicely.
+ */
+#define CTL_PM 9899
+#define CTL_PM_SUSPEND 1
+#define CTL_PM_CMODE 2
+#define CTL_PM_P0 4
+#define CTL_PM_CM 5
+
+static int user_atoi(char *ubuf, size_t len)
+{
+	char buf[16];
+	unsigned long ret;
+
+	if (len > 15)
+		return -EINVAL;
+
+	if (copy_from_user(buf, ubuf, len))
+		return -EFAULT;
+
+	buf[len] = 0;
+	ret = simple_strtoul(buf, NULL, 0);
+	if (ret > INT_MAX)
+		return -ERANGE;
+	return ret;
+}
+
+/*
+ * Send us to sleep.
+ */
+static int sysctl_pm_do_suspend(ctl_table *ctl, int write, struct file *filp,
+				void *buffer, size_t *lenp, loff_t *fpos)
+{
+	int retval, mode;
+
+	if (*lenp <= 0)
+		return -EIO;
+
+	mode = user_atoi(buffer, *lenp);
+	if ((mode != 1) && (mode != 5))
+		return -EINVAL;
+
+	retval = pm_send_all(PM_SUSPEND, (void *)3);
+
+	if (retval == 0) {
+		if (mode == 5)
+		    retval = pm_do_bus_sleep();
+		else
+		    retval = pm_do_suspend();
+		pm_send_all(PM_RESUME, (void *)0);
+	}
+
+	return retval;
+}
+
+static int try_set_cmode(int new_cmode)
+{
+	if (new_cmode > 15)
+		return -EINVAL;
+	if (!(clock_cmodes_permitted & (1<<new_cmode)))
+		return -EINVAL;
+
+	/* tell all the drivers we're suspending */
+	pm_send_all(PM_SUSPEND, (void *)3);
+
+	/* now change cmode */
+	local_irq_disable();
+	frv_dma_pause_all();
+
+	frv_change_cmode(new_cmode);
+
+	determine_clocks(0);
+	time_divisor_init();
+
+#ifdef DEBUG
+	determine_clocks(1);
+#endif
+	frv_dma_resume_all();
+	local_irq_enable();
+
+	/* tell all the drivers we're resuming */
+	pm_send_all(PM_RESUME, (void *)0);
+	return 0;
+}
+
+
+static int cmode_procctl(ctl_table *ctl, int write, struct file *filp,
+			 void *buffer, size_t *lenp, loff_t *fpos)
+{
+	int new_cmode;
+
+	if (!write)
+		return proc_dointvec(ctl, write, filp, buffer, lenp, fpos);
+
+	new_cmode = user_atoi(buffer, *lenp);
+
+	return try_set_cmode(new_cmode)?:*lenp;
+}
+
+static int cmode_sysctl(ctl_table *table, int *name, int nlen,
+			void *oldval, size_t *oldlenp,
+			void *newval, size_t newlen, void **context)
+{
+	if (oldval && oldlenp) {
+		size_t oldlen;
+
+		if (get_user(oldlen, oldlenp))
+			return -EFAULT;
+
+		if (oldlen != sizeof(int))
+			return -EINVAL;
+
+		if (put_user(clock_cmode_current, (unsigned int *)oldval) ||
+		    put_user(sizeof(int), oldlenp))
+			return -EFAULT;
+	}
+	if (newval && newlen) {
+		int new_cmode;
+
+		if (newlen != sizeof(int))
+			return -EINVAL;
+
+		if (get_user(new_cmode, (int *)newval))
+			return -EFAULT;
+
+		return try_set_cmode(new_cmode)?:1;
+	}
+	return 1;
+}
+
+static int try_set_p0(int new_p0)
+{
+	unsigned long flags, clkc;
+
+	if (new_p0 < 0 || new_p0 > 1)
+		return -EINVAL;
+
+	local_irq_save(flags);
+	__set_PSR(flags & ~PSR_ET);
+
+	frv_dma_pause_all();
+
+	clkc = __get_CLKC();
+	if (new_p0)
+		clkc |= CLKC_P0;
+	else
+		clkc &= ~CLKC_P0;
+	__set_CLKC(clkc);
+
+	determine_clocks(0);
+	time_divisor_init();
+
+#ifdef DEBUG
+	determine_clocks(1);
+#endif
+	frv_dma_resume_all();
+	local_irq_restore(flags);
+	return 0;
+}
+
+static int try_set_cm(int new_cm)
+{
+	unsigned long flags, clkc;
+
+	if (new_cm < 0 || new_cm > 1)
+		return -EINVAL;
+
+	local_irq_save(flags);
+	__set_PSR(flags & ~PSR_ET);
+
+	frv_dma_pause_all();
+
+	clkc = __get_CLKC();
+	clkc &= ~CLKC_CM;
+	clkc |= new_cm;
+	__set_CLKC(clkc);
+
+	determine_clocks(0);
+	time_divisor_init();
+
+#if 1 //def DEBUG
+	determine_clocks(1);
+#endif
+
+	frv_dma_resume_all();
+	local_irq_restore(flags);
+	return 0;
+}
+
+static int p0_procctl(ctl_table *ctl, int write, struct file *filp,
+		      void *buffer, size_t *lenp, loff_t *fpos)
+{
+	int new_p0;
+
+	if (!write)
+		return proc_dointvec(ctl, write, filp, buffer, lenp, fpos);
+
+	new_p0 = user_atoi(buffer, *lenp);
+
+	return try_set_p0(new_p0)?:*lenp;
+}
+
+static int p0_sysctl(ctl_table *table, int *name, int nlen,
+		     void *oldval, size_t *oldlenp,
+		     void *newval, size_t newlen, void **context)
+{
+	if (oldval && oldlenp) {
+		size_t oldlen;
+
+		if (get_user(oldlen, oldlenp))
+			return -EFAULT;
+
+		if (oldlen != sizeof(int))
+			return -EINVAL;
+
+		if (put_user(clock_p0_current, (unsigned int *)oldval) ||
+		    put_user(sizeof(int), oldlenp))
+			return -EFAULT;
+	}
+	if (newval && newlen) {
+		int new_p0;
+
+		if (newlen != sizeof(int))
+			return -EINVAL;
+
+		if (get_user(new_p0, (int *)newval))
+			return -EFAULT;
+
+		return try_set_p0(new_p0)?:1;
+	}
+	return 1;
+}
+
+static int cm_procctl(ctl_table *ctl, int write, struct file *filp,
+		      void *buffer, size_t *lenp, loff_t *fpos)
+{
+	int new_cm;
+
+	if (!write)
+		return proc_dointvec(ctl, write, filp, buffer, lenp, fpos);
+
+	new_cm = user_atoi(buffer, *lenp);
+
+	return try_set_cm(new_cm)?:*lenp;
+}
+
+static int cm_sysctl(ctl_table *table, int *name, int nlen,
+		     void *oldval, size_t *oldlenp,
+		     void *newval, size_t newlen, void **context)
+{
+	if (oldval && oldlenp) {
+		size_t oldlen;
+
+		if (get_user(oldlen, oldlenp))
+			return -EFAULT;
+
+		if (oldlen != sizeof(int))
+			return -EINVAL;
+
+		if (put_user(clock_cm_current, (unsigned int *)oldval) ||
+		    put_user(sizeof(int), oldlenp))
+			return -EFAULT;
+	}
+	if (newval && newlen) {
+		int new_cm;
+
+		if (newlen != sizeof(int))
+			return -EINVAL;
+
+		if (get_user(new_cm, (int *)newval))
+			return -EFAULT;
+
+		return try_set_cm(new_cm)?:1;
+	}
+	return 1;
+}
+
+
+static struct ctl_table pm_table[] =
+{
+	{CTL_PM_SUSPEND, "suspend", NULL, 0, 0200, NULL, &sysctl_pm_do_suspend},
+	{CTL_PM_CMODE, "cmode", &clock_cmode_current, sizeof(int), 0644, NULL, &cmode_procctl, &cmode_sysctl, NULL},
+	{CTL_PM_P0, "p0", &clock_p0_current, sizeof(int), 0644, NULL, &p0_procctl, &p0_sysctl, NULL},
+	{CTL_PM_CM, "cm", &clock_cm_current, sizeof(int), 0644, NULL, &cm_procctl, &cm_sysctl, NULL},
+	{0}
+};
+
+static struct ctl_table pm_dir_table[] =
+{
+	{CTL_PM, "pm", NULL, 0, 0555, pm_table},
+	{0}
+};
+
+/*
+ * Initialize power interface
+ */
+static int __init pm_init(void)
+{
+	register_sysctl_table(pm_dir_table, 1);
+	return 0;
+}
+
+__initcall(pm_init);
+
+#endif
diff -Nru a/arch/frv/kernel/process.c b/arch/frv/kernel/process.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/kernel/process.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,388 @@
+/* process.c: FRV specific parts of process handling
+ *
+ * Copyright (C) 2003-5 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ * - Derived from arch/m68k/kernel/process.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.
+ */
+
+#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/user.h>
+#include <linux/elf.h>
+#include <linux/reboot.h>
+#include <linux/interrupt.h>
+
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/setup.h>
+#include <asm/pgtable.h>
+#include <asm/gdb-stub.h>
+#include <asm/mb-regs.h>
+
+#include "local.h"
+
+asmlinkage void ret_from_fork(void);
+
+#include <asm/pgalloc.h>
+
+struct task_struct *alloc_task_struct(void)
+{
+	struct task_struct *p = kmalloc(THREAD_SIZE, GFP_KERNEL);
+	if (p)
+		atomic_set((atomic_t *)(p+1), 1);
+	return p;
+}
+
+void free_task_struct(struct task_struct *p)
+{
+	if (atomic_dec_and_test((atomic_t *)(p+1)))
+		kfree(p);
+}
+
+static void core_sleep_idle(void)
+{
+#ifdef LED_DEBUG_SLEEP
+	/* Show that we're sleeping... */
+	__set_LEDS(0x55aa);
+#endif
+	frv_cpu_core_sleep();
+#ifdef LED_DEBUG_SLEEP
+	/* ... and that we woke up */
+	__set_LEDS(0);
+#endif
+	mb();
+}
+
+void (*idle)(void) = core_sleep_idle;
+
+/*
+ * The idle thread. There's no useful work to be
+ * done, so just try to conserve power and have a
+ * low exit latency (ie sit in a loop waiting for
+ * somebody to say that they'd like to reschedule)
+ */
+void cpu_idle(void)
+{
+	/* endless idle loop with no priority at all */
+	while (1) {
+		while (!need_resched()) {
+			irq_stat[smp_processor_id()].idle_timestamp = jiffies;
+
+			if (!frv_dma_inprogress && idle)
+				idle();
+		}
+
+		schedule();
+	}
+}
+
+void machine_restart(char * __unused)
+{
+	unsigned long reset_addr;
+#ifdef CONFIG_GDBSTUB
+	gdbstub_exit(0);
+#endif
+
+	if (PSR_IMPLE(__get_PSR()) == PSR_IMPLE_FR551)
+		reset_addr = 0xfefff500;
+	else
+		reset_addr = 0xfeff0500;
+
+	/* Software reset. */
+	asm volatile("      dcef @(gr0,gr0),1 ! membar !"
+		     "      sti     %1,@(%0,0) !"
+		     "      nop ! nop ! nop ! nop ! nop ! "
+		     "      nop ! nop ! nop ! nop ! nop ! "
+		     "      nop ! nop ! nop ! nop ! nop ! "
+		     "      nop ! nop ! nop ! nop ! nop ! "
+		     : : "r" (reset_addr), "r" (1) );
+
+	for (;;)
+		;
+}
+
+void machine_halt(void)
+{
+#ifdef CONFIG_GDBSTUB
+	gdbstub_exit(0);
+#endif
+
+	for (;;);
+}
+
+void machine_power_off(void)
+{
+#ifdef CONFIG_GDBSTUB
+	gdbstub_exit(0);
+#endif
+
+	for (;;);
+}
+
+void flush_thread(void)
+{
+#if 0 //ndef NO_FPU
+	unsigned long zero = 0;
+#endif
+	set_fs(USER_DS);
+}
+
+inline unsigned long user_stack(const struct pt_regs *regs)
+{
+	while (regs->next_frame)
+		regs = regs->next_frame;
+	return user_mode(regs) ? regs->sp : 0;
+}
+
+asmlinkage int sys_fork(void)
+{
+#ifndef CONFIG_MMU
+	/* fork almost works, enough to trick you into looking elsewhere:-( */
+	return -EINVAL;
+#else
+	return do_fork(SIGCHLD, user_stack(__frame), __frame, 0, NULL, NULL);
+#endif
+}
+
+asmlinkage int sys_vfork(void)
+{
+	return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, user_stack(__frame), __frame, 0,
+		       NULL, NULL);
+}
+
+/*****************************************************************************/
+/*
+ * clone a process
+ * - tlsptr is retrieved by copy_thread()
+ */
+asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
+			 int __user *parent_tidptr, int __user *child_tidptr,
+			 int __user *tlsptr)
+{
+	if (!newsp)
+		newsp = user_stack(__frame);
+	return do_fork(clone_flags, newsp, __frame, 0, parent_tidptr, child_tidptr);
+} /* end sys_clone() */
+
+/*****************************************************************************/
+/*
+ * This gets called before we allocate a new thread and copy
+ * the current task into it.
+ */
+void prepare_to_copy(struct task_struct *tsk)
+{
+	//unlazy_fpu(tsk);
+} /* end prepare_to_copy() */
+
+/*****************************************************************************/
+/*
+ * set up the kernel stack and exception frames for a new process
+ */
+int copy_thread(int nr, unsigned long clone_flags,
+		unsigned long usp, unsigned long topstk,
+		struct task_struct *p, struct pt_regs *regs)
+{
+	struct pt_regs *childregs0, *childregs, *regs0;
+
+	regs0 = __kernel_frame0_ptr;
+	childregs0 = (struct pt_regs *)
+		((unsigned long) p->thread_info + THREAD_SIZE - USER_CONTEXT_SIZE);
+	childregs = childregs0;
+
+	/* set up the userspace frame (the only place that the USP is stored) */
+	*childregs0 = *regs0;
+
+	childregs0->gr8		= 0;
+	childregs0->sp		= usp;
+	childregs0->next_frame	= NULL;
+
+	/* set up the return kernel frame if called from kernel_thread() */
+	if (regs != regs0) {
+		childregs--;
+		*childregs = *regs;
+		childregs->sp = (unsigned long) childregs0;
+		childregs->next_frame = childregs0;
+		childregs->gr15 = (unsigned long) p->thread_info;
+		childregs->gr29 = (unsigned long) p;
+	}
+
+	p->set_child_tid = p->clear_child_tid = NULL;
+
+	p->thread.frame	 = childregs;
+	p->thread.curr	 = p;
+	p->thread.sp	 = (unsigned long) childregs;
+	p->thread.fp	 = 0;
+	p->thread.lr	 = 0;
+	p->thread.pc	 = (unsigned long) ret_from_fork;
+	p->thread.frame0 = childregs0;
+
+	/* the new TLS pointer is passed in as arg #5 to sys_clone() */
+	if (clone_flags & CLONE_SETTLS)
+		childregs->gr29 = childregs->gr12;
+
+	save_user_regs(p->thread.user);
+
+	return 0;
+} /* end copy_thread() */
+
+/*
+ * fill in the user structure for a core dump..
+ */
+void dump_thread(struct pt_regs *regs, struct user *dump)
+{
+#if 0
+	/* changed the size calculations - should hopefully work better. lbt */
+	dump->magic = CMAGIC;
+	dump->start_code = 0;
+	dump->start_stack = user_stack(regs) & ~(PAGE_SIZE - 1);
+	dump->u_tsize = ((unsigned long) current->mm->end_code) >> PAGE_SHIFT;
+	dump->u_dsize = ((unsigned long) (current->mm->brk + (PAGE_SIZE-1))) >> PAGE_SHIFT;
+	dump->u_dsize -= dump->u_tsize;
+	dump->u_ssize = 0;
+
+	if (dump->start_stack < TASK_SIZE)
+		dump->u_ssize = ((unsigned long) (TASK_SIZE - dump->start_stack)) >> PAGE_SHIFT;
+
+	dump->regs = *(struct user_context *) regs;
+#endif
+}
+
+/*
+ * sys_execve() executes a new program.
+ */
+asmlinkage int sys_execve(char *name, char **argv, char **envp)
+{
+	int error;
+	char * filename;
+
+	lock_kernel();
+	filename = getname(name);
+	error = PTR_ERR(filename);
+	if (IS_ERR(filename))
+		goto out;
+	error = do_execve(filename, argv, envp, __frame);
+	putname(filename);
+ out:
+	unlock_kernel();
+	return error;
+}
+
+unsigned long get_wchan(struct task_struct *p)
+{
+	struct pt_regs *regs0;
+	unsigned long fp, pc;
+	unsigned long stack_limit;
+	int count = 0;
+	if (!p || p == current || p->state == TASK_RUNNING)
+		return 0;
+
+	stack_limit = (unsigned long) (p + 1);
+	fp = p->thread.fp;
+	regs0 = p->thread.frame0;
+
+	do {
+		if (fp < stack_limit || fp >= (unsigned long) regs0 || fp & 3)
+			return 0;
+
+		pc = ((unsigned long *) fp)[2];
+
+		/* FIXME: This depends on the order of these functions. */
+		if (!in_sched_functions(pc))
+			return pc;
+
+		fp = *(unsigned long *) fp;
+	} while (count++ < 16);
+
+	return 0;
+}
+
+unsigned long thread_saved_pc(struct task_struct *tsk)
+{
+	/* Check whether the thread is blocked in resume() */
+	if (in_sched_functions(tsk->thread.pc))
+		return ((unsigned long *)tsk->thread.fp)[2];
+	else
+		return tsk->thread.pc;
+}
+
+int elf_check_arch(const struct elf32_hdr *hdr)
+{
+	unsigned long hsr0 = __get_HSR(0);
+	unsigned long psr = __get_PSR();
+
+	if (hdr->e_machine != EM_FRV)
+		return 0;
+
+	switch (hdr->e_flags & EF_FRV_GPR_MASK) {
+	case EF_FRV_GPR64:
+		if ((hsr0 & HSR0_GRN) == HSR0_GRN_32)
+			return 0;
+	case EF_FRV_GPR32:
+	case 0:
+		break;
+	default:
+		return 0;
+	}
+
+	switch (hdr->e_flags & EF_FRV_FPR_MASK) {
+	case EF_FRV_FPR64:
+		if ((hsr0 & HSR0_FRN) == HSR0_FRN_32)
+			return 0;
+	case EF_FRV_FPR32:
+	case EF_FRV_FPR_NONE:
+	case 0:
+		break;
+	default:
+		return 0;
+	}
+
+	if ((hdr->e_flags & EF_FRV_MULADD) == EF_FRV_MULADD)
+		if (PSR_IMPLE(psr) != PSR_IMPLE_FR405 &&
+		    PSR_IMPLE(psr) != PSR_IMPLE_FR451)
+			return 0;
+
+	switch (hdr->e_flags & EF_FRV_CPU_MASK) {
+	case EF_FRV_CPU_GENERIC:
+		break;
+	case EF_FRV_CPU_FR300:
+	case EF_FRV_CPU_SIMPLE:
+	case EF_FRV_CPU_TOMCAT:
+	default:
+		return 0;
+	case EF_FRV_CPU_FR400:
+		if (PSR_IMPLE(psr) != PSR_IMPLE_FR401 &&
+		    PSR_IMPLE(psr) != PSR_IMPLE_FR405 &&
+		    PSR_IMPLE(psr) != PSR_IMPLE_FR451 &&
+		    PSR_IMPLE(psr) != PSR_IMPLE_FR551)
+			return 0;
+		break;
+	case EF_FRV_CPU_FR450:
+		if (PSR_IMPLE(psr) != PSR_IMPLE_FR451)
+			return 0;
+		break;
+	case EF_FRV_CPU_FR500:
+		if (PSR_IMPLE(psr) != PSR_IMPLE_FR501)
+			return 0;
+		break;
+	case EF_FRV_CPU_FR550:
+		if (PSR_IMPLE(psr) != PSR_IMPLE_FR551)
+			return 0;
+		break;
+	}
+
+	return 1;
+}
diff -Nru a/arch/frv/kernel/ptrace.c b/arch/frv/kernel/ptrace.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/kernel/ptrace.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,764 @@
+/* ptrace.c: FRV specific parts of process tracing
+ *
+ * Copyright (C) 2003-5 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ * - Derived from arch/m68k/kernel/ptrace.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.
+ */
+
+#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/config.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/unistd.h>
+
+/*
+ * does not yet catch signals sent when the child dies.
+ * in exit.c or in signal.c.
+ */
+
+/*
+ * Get contents of register REGNO in task TASK.
+ */
+static inline long get_reg(struct task_struct *task, int regno)
+{
+	struct user_context *user = task->thread.user;
+
+	if (regno < 0 || regno >= PT__END)
+		return 0;
+
+	return ((unsigned long *) user)[regno];
+}
+
+/*
+ * Write contents of register REGNO in task TASK.
+ */
+static inline int put_reg(struct task_struct *task, int regno,
+			  unsigned long data)
+{
+	struct user_context *user = task->thread.user;
+
+	if (regno < 0 || regno >= PT__END)
+		return -EIO;
+
+	switch (regno) {
+	case PT_GR(0):
+		return 0;
+	case PT_PSR:
+	case PT__STATUS:
+		return -EIO;
+	default:
+		((unsigned long *) user)[regno] = data;
+		return 0;
+	}
+}
+
+/*
+ * check that an address falls within the bounds of the target process's memory mappings
+ */
+static inline int is_user_addr_valid(struct task_struct *child,
+				     unsigned long start, unsigned long len)
+{
+#ifdef CONFIG_MMU
+	if (start >= PAGE_OFFSET || len > PAGE_OFFSET - start)
+		return -EIO;
+	return 0;
+#else
+	struct vm_list_struct *vml;
+
+	for (vml = child->mm->context.vmlist; vml; vml = vml->next)
+		if (start >= vml->vma->vm_start && start + len <= vml->vma->vm_end)
+			return 0;
+
+	return -EIO;
+#endif
+}
+
+/*
+ * Called by kernel/ptrace.c when detaching..
+ *
+ * Control h/w single stepping
+ */
+void ptrace_disable(struct task_struct *child)
+{
+	child->thread.frame0->__status &= ~REG__STATUS_STEP;
+}
+
+void ptrace_enable(struct task_struct *child)
+{
+	child->thread.frame0->__status |= REG__STATUS_STEP;
+}
+
+asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
+{
+	struct task_struct *child;
+	unsigned long tmp;
+	int ret;
+
+	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)		/* you may not mess with init */
+		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) {
+		/* when I and D space are separate, these will need to be fixed. */
+	case PTRACE_PEEKTEXT: /* read word at location addr. */
+	case PTRACE_PEEKDATA: {
+		int copied;
+
+		ret = -EIO;
+		if (is_user_addr_valid(child, addr, sizeof(tmp)) < 0)
+			break;
+
+		copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
+		if (copied != sizeof(tmp))
+			break;
+
+		ret = put_user(tmp,(unsigned long *) data);
+		break;
+	}
+
+		/* read the word at location addr in the USER area. */
+	case PTRACE_PEEKUSR: {
+		tmp = 0;
+		ret = -EIO;
+		if ((addr & 3) || addr < 0)
+			break;
+
+		ret = 0;
+		switch (addr >> 2) {
+		case 0 ... PT__END - 1:
+			tmp = get_reg(child, addr >> 2);
+			break;
+
+		case PT__END + 0:
+			tmp = child->mm->end_code - child->mm->start_code;
+			break;
+
+		case PT__END + 1:
+			tmp = child->mm->end_data - child->mm->start_data;
+			break;
+
+		case PT__END + 2:
+			tmp = child->mm->start_stack - child->mm->start_brk;
+			break;
+
+		case PT__END + 3:
+			tmp = child->mm->start_code;
+			break;
+
+		case PT__END + 4:
+			tmp = child->mm->start_stack;
+			break;
+
+		default:
+			ret = -EIO;
+			break;
+		}
+
+		if (ret == 0)
+			ret = put_user(tmp, (unsigned long *) data);
+		break;
+	}
+
+		/* when I and D space are separate, this will have to be fixed. */
+	case PTRACE_POKETEXT: /* write the word at location addr. */
+	case PTRACE_POKEDATA:
+		ret = -EIO;
+		if (is_user_addr_valid(child, addr, sizeof(tmp)) < 0)
+			break;
+		if (access_process_vm(child, addr, &data, sizeof(data), 1) != sizeof(data))
+			break;
+		ret = 0;
+		break;
+
+	case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
+		ret = -EIO;
+		if ((addr & 3) || addr < 0)
+			break;
+
+		ret = 0;
+		switch (addr >> 2) {
+		case 0 ... PT__END-1:
+			ret = put_reg(child, addr >> 2, data);
+			break;
+
+		default:
+			ret = -EIO;
+			break;
+		}
+		break;
+
+	case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
+	case PTRACE_CONT: /* restart after signal. */
+		ret = -EIO;
+		if ((unsigned long) data > _NSIG)
+			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;
+		ptrace_disable(child);
+		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->exit_state == EXIT_ZOMBIE)	/* already dead */
+			break;
+		child->exit_code = SIGKILL;
+		clear_tsk_thread_flag(child, TIF_SINGLESTEP);
+		ptrace_disable(child);
+		wake_up_process(child);
+		break;
+
+	case PTRACE_SINGLESTEP:  /* set the trap flag. */
+		ret = -EIO;
+		if ((unsigned long) data > _NSIG)
+			break;
+		clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+		ptrace_enable(child);
+		child->exit_code = data;
+		wake_up_process(child);
+		ret = 0;
+		break;
+
+	case PTRACE_DETACH:	/* detach a process that was attached. */
+		ret = ptrace_detach(child, data);
+		break;
+
+	case PTRACE_GETREGS: { /* Get all integer regs from the child. */
+		int i;
+		for (i = 0; i < PT__GPEND; i++) {
+			tmp = get_reg(child, i);
+			if (put_user(tmp, (unsigned long *) data)) {
+				ret = -EFAULT;
+				break;
+			}
+			data += sizeof(long);
+		}
+		ret = 0;
+		break;
+	}
+
+	case PTRACE_SETREGS: { /* Set all integer regs in the child. */
+		int i;
+		for (i = 0; i < PT__GPEND; i++) {
+			if (get_user(tmp, (unsigned long *) data)) {
+				ret = -EFAULT;
+				break;
+			}
+			put_reg(child, i, tmp);
+			data += sizeof(long);
+		}
+		ret = 0;
+		break;
+	}
+
+	case PTRACE_GETFPREGS: { /* Get the child FP/Media state. */
+		ret = 0;
+		if (copy_to_user((void *) data,
+				 &child->thread.user->f,
+				 sizeof(child->thread.user->f)))
+			ret = -EFAULT;
+		break;
+	}
+
+	case PTRACE_SETFPREGS: { /* Set the child FP/Media state. */
+		ret = 0;
+		if (copy_from_user(&child->thread.user->f,
+				   (void *) data,
+				   sizeof(child->thread.user->f)))
+			ret = -EFAULT;
+		break;
+	}
+
+	case PTRACE_GETFDPIC:
+		tmp = 0;
+		switch (addr) {
+		case PTRACE_GETFDPIC_EXEC:
+			tmp = child->mm->context.exec_fdpic_loadmap;
+			break;
+		case PTRACE_GETFDPIC_INTERP:
+			tmp = child->mm->context.interp_fdpic_loadmap;
+			break;
+		default:
+			break;
+		}
+
+		ret = 0;
+		if (put_user(tmp, (unsigned long *) data)) {
+			ret = -EFAULT;
+			break;
+		}
+		break;
+
+	default:
+		ret = -EIO;
+		break;
+	}
+out_tsk:
+	put_task_struct(child);
+out:
+	unlock_kernel();
+	return ret;
+}
+
+int __nongprelbss kstrace;
+
+static const struct {
+	const char	*name;
+	unsigned	argmask;
+} __syscall_name_table[NR_syscalls] = {
+	[0]	= { "restart_syscall"			},
+	[1]	= { "exit",		0x000001	},
+	[2]	= { "fork",		0xffffff	},
+	[3]	= { "read",		0x000141	},
+	[4]	= { "write",		0x000141	},
+	[5]	= { "open",		0x000235	},
+	[6]	= { "close",		0x000001	},
+	[7]	= { "waitpid",		0x000141	},
+	[8]	= { "creat",		0x000025	},
+	[9]	= { "link",		0x000055	},
+	[10]	= { "unlink",		0x000005	},
+	[11]	= { "execve",		0x000445	},
+	[12]	= { "chdir",		0x000005	},
+	[13]	= { "time",		0x000004	},
+	[14]	= { "mknod",		0x000325	},
+	[15]	= { "chmod",		0x000025	},
+	[16]	= { "lchown",		0x000025	},
+	[17]	= { "break" },
+	[18]	= { "oldstat",		0x000045	},
+	[19]	= { "lseek",		0x000131	},
+	[20]	= { "getpid",		0xffffff	},
+	[21]	= { "mount",		0x043555	},
+	[22]	= { "umount",		0x000005	},
+	[23]	= { "setuid",		0x000001	},
+	[24]	= { "getuid",		0xffffff	},
+	[25]	= { "stime",		0x000004	},
+	[26]	= { "ptrace",		0x004413	},
+	[27]	= { "alarm",		0x000001	},
+	[28]	= { "oldfstat",		0x000041	},
+	[29]	= { "pause",		0xffffff	},
+	[30]	= { "utime",		0x000045	},
+	[31]	= { "stty" },
+	[32]	= { "gtty" },
+	[33]	= { "access",		0x000025	},
+	[34]	= { "nice",		0x000001	},
+	[35]	= { "ftime" },
+	[36]	= { "sync",		0xffffff	},
+	[37]	= { "kill",		0x000011	},
+	[38]	= { "rename",		0x000055	},
+	[39]	= { "mkdir",		0x000025	},
+	[40]	= { "rmdir",		0x000005	},
+	[41]	= { "dup",		0x000001	},
+	[42]	= { "pipe",		0x000004	},
+	[43]	= { "times",		0x000004	},
+	[44]	= { "prof" },
+	[45]	= { "brk",		0x000004	},
+	[46]	= { "setgid",		0x000001	},
+	[47]	= { "getgid",		0xffffff	},
+	[48]	= { "signal",		0x000041	},
+	[49]	= { "geteuid",		0xffffff	},
+	[50]	= { "getegid",		0xffffff	},
+	[51]	= { "acct",		0x000005	},
+	[52]	= { "umount2",		0x000035	},
+	[53]	= { "lock" },
+	[54]	= { "ioctl",		0x000331	},
+	[55]	= { "fcntl",		0x000331	},
+	[56]	= { "mpx" },
+	[57]	= { "setpgid",		0x000011	},
+	[58]	= { "ulimit" },
+	[60]	= { "umask",		0x000002	},
+	[61]	= { "chroot",		0x000005	},
+	[62]	= { "ustat",		0x000043	},
+	[63]	= { "dup2",		0x000011	},
+	[64]	= { "getppid",		0xffffff	},
+	[65]	= { "getpgrp",		0xffffff	},
+	[66]	= { "setsid",		0xffffff	},
+	[67]	= { "sigaction" },
+	[68]	= { "sgetmask" },
+	[69]	= { "ssetmask" },
+	[70]	= { "setreuid" },
+	[71]	= { "setregid" },
+	[72]	= { "sigsuspend" },
+	[73]	= { "sigpending" },
+	[74]	= { "sethostname" },
+	[75]	= { "setrlimit" },
+	[76]	= { "getrlimit" },
+	[77]	= { "getrusage" },
+	[78]	= { "gettimeofday" },
+	[79]	= { "settimeofday" },
+	[80]	= { "getgroups" },
+	[81]	= { "setgroups" },
+	[82]	= { "select" },
+	[83]	= { "symlink" },
+	[84]	= { "oldlstat" },
+	[85]	= { "readlink" },
+	[86]	= { "uselib" },
+	[87]	= { "swapon" },
+	[88]	= { "reboot" },
+	[89]	= { "readdir" },
+	[91]	= { "munmap",		0x000034	},
+	[92]	= { "truncate" },
+	[93]	= { "ftruncate" },
+	[94]	= { "fchmod" },
+	[95]	= { "fchown" },
+	[96]	= { "getpriority" },
+	[97]	= { "setpriority" },
+	[99]	= { "statfs" },
+	[100]	= { "fstatfs" },
+	[102]	= { "socketcall" },
+	[103]	= { "syslog" },
+	[104]	= { "setitimer" },
+	[105]	= { "getitimer" },
+	[106]	= { "stat" },
+	[107]	= { "lstat" },
+	[108]	= { "fstat" },
+	[111]	= { "vhangup" },
+	[114]	= { "wait4" },
+	[115]	= { "swapoff" },
+	[116]	= { "sysinfo" },
+	[117]	= { "ipc" },
+	[118]	= { "fsync" },
+	[119]	= { "sigreturn" },
+	[120]	= { "clone" },
+	[121]	= { "setdomainname" },
+	[122]	= { "uname" },
+	[123]	= { "modify_ldt" },
+	[123]	= { "cacheflush" },
+	[124]	= { "adjtimex" },
+	[125]	= { "mprotect" },
+	[126]	= { "sigprocmask" },
+	[127]	= { "create_module" },
+	[128]	= { "init_module" },
+	[129]	= { "delete_module" },
+	[130]	= { "get_kernel_syms" },
+	[131]	= { "quotactl" },
+	[132]	= { "getpgid" },
+	[133]	= { "fchdir" },
+	[134]	= { "bdflush" },
+	[135]	= { "sysfs" },
+	[136]	= { "personality" },
+	[137]	= { "afs_syscall" },
+	[138]	= { "setfsuid" },
+	[139]	= { "setfsgid" },
+	[140]	= { "_llseek",			0x014331	},
+	[141]	= { "getdents" },
+	[142]	= { "_newselect",		0x000141	},
+	[143]	= { "flock" },
+	[144]	= { "msync" },
+	[145]	= { "readv" },
+	[146]	= { "writev" },
+	[147]	= { "getsid",			0x000001	},
+	[148]	= { "fdatasync",		0x000001	},
+	[149]	= { "_sysctl",			0x000004	},
+	[150]	= { "mlock" },
+	[151]	= { "munlock" },
+	[152]	= { "mlockall" },
+	[153]	= { "munlockall" },
+	[154]	= { "sched_setparam" },
+	[155]	= { "sched_getparam" },
+	[156]	= { "sched_setscheduler" },
+	[157]	= { "sched_getscheduler" },
+	[158]	= { "sched_yield" },
+	[159]	= { "sched_get_priority_max" },
+	[160]	= { "sched_get_priority_min" },
+	[161]	= { "sched_rr_get_interval" },
+	[162]	= { "nanosleep",		0x000044	},
+	[163]	= { "mremap" },
+	[164]	= { "setresuid" },
+	[165]	= { "getresuid" },
+	[166]	= { "vm86" },
+	[167]	= { "query_module" },
+	[168]	= { "poll" },
+	[169]	= { "nfsservctl" },
+	[170]	= { "setresgid" },
+	[171]	= { "getresgid" },
+	[172]	= { "prctl",			0x333331	},
+	[173]	= { "rt_sigreturn",		0xffffff	},
+	[174]	= { "rt_sigaction",		0x001441	},
+	[175]	= { "rt_sigprocmask",		0x001441	},
+	[176]	= { "rt_sigpending",		0x000014	},
+	[177]	= { "rt_sigtimedwait",		0x001444	},
+	[178]	= { "rt_sigqueueinfo",		0x000411	},
+	[179]	= { "rt_sigsuspend",		0x000014	},
+	[180]	= { "pread",			0x003341	},
+	[181]	= { "pwrite",			0x003341	},
+	[182]	= { "chown",			0x000115	},
+	[183]	= { "getcwd" },
+	[184]	= { "capget" },
+	[185]	= { "capset" },
+	[186]	= { "sigaltstack" },
+	[187]	= { "sendfile" },
+	[188]	= { "getpmsg" },
+	[189]	= { "putpmsg" },
+	[190]	= { "vfork",			0xffffff	},
+	[191]	= { "ugetrlimit" },
+	[192]	= { "mmap2",			0x313314	},
+	[193]	= { "truncate64" },
+	[194]	= { "ftruncate64" },
+	[195]	= { "stat64",			0x000045	},
+	[196]	= { "lstat64",			0x000045	},
+	[197]	= { "fstat64",			0x000041	},
+	[198]	= { "lchown32" },
+	[199]	= { "getuid32",			0xffffff	},
+	[200]	= { "getgid32",			0xffffff	},
+	[201]	= { "geteuid32",		0xffffff	},
+	[202]	= { "getegid32",		0xffffff	},
+	[203]	= { "setreuid32" },
+	[204]	= { "setregid32" },
+	[205]	= { "getgroups32" },
+	[206]	= { "setgroups32" },
+	[207]	= { "fchown32" },
+	[208]	= { "setresuid32" },
+	[209]	= { "getresuid32" },
+	[210]	= { "setresgid32" },
+	[211]	= { "getresgid32" },
+	[212]	= { "chown32" },
+	[213]	= { "setuid32" },
+	[214]	= { "setgid32" },
+	[215]	= { "setfsuid32" },
+	[216]	= { "setfsgid32" },
+	[217]	= { "pivot_root" },
+	[218]	= { "mincore" },
+	[219]	= { "madvise" },
+	[220]	= { "getdents64" },
+	[221]	= { "fcntl64" },
+	[223]	= { "security" },
+	[224]	= { "gettid" },
+	[225]	= { "readahead" },
+	[226]	= { "setxattr" },
+	[227]	= { "lsetxattr" },
+	[228]	= { "fsetxattr" },
+	[229]	= { "getxattr" },
+	[230]	= { "lgetxattr" },
+	[231]	= { "fgetxattr" },
+	[232]	= { "listxattr" },
+	[233]	= { "llistxattr" },
+	[234]	= { "flistxattr" },
+	[235]	= { "removexattr" },
+	[236]	= { "lremovexattr" },
+	[237]	= { "fremovexattr" },
+	[238]	= { "tkill" },
+	[239]	= { "sendfile64" },
+	[240]	= { "futex" },
+	[241]	= { "sched_setaffinity" },
+	[242]	= { "sched_getaffinity" },
+	[243]	= { "set_thread_area" },
+	[244]	= { "get_thread_area" },
+	[245]	= { "io_setup" },
+	[246]	= { "io_destroy" },
+	[247]	= { "io_getevents" },
+	[248]	= { "io_submit" },
+	[249]	= { "io_cancel" },
+	[250]	= { "fadvise64" },
+	[252]	= { "exit_group",		0x000001	},
+	[253]	= { "lookup_dcookie" },
+	[254]	= { "epoll_create" },
+	[255]	= { "epoll_ctl" },
+	[256]	= { "epoll_wait" },
+	[257]	= { "remap_file_pages" },
+	[258]	= { "set_tid_address" },
+	[259]	= { "timer_create" },
+	[260]	= { "timer_settime" },
+	[261]	= { "timer_gettime" },
+	[262]	= { "timer_getoverrun" },
+	[263]	= { "timer_delete" },
+	[264]	= { "clock_settime" },
+	[265]	= { "clock_gettime" },
+	[266]	= { "clock_getres" },
+	[267]	= { "clock_nanosleep" },
+	[268]	= { "statfs64" },
+	[269]	= { "fstatfs64" },
+	[270]	= { "tgkill" },
+	[271]	= { "utimes" },
+	[272]	= { "fadvise64_64" },
+	[273]	= { "vserver" },
+	[274]	= { "mbind" },
+	[275]	= { "get_mempolicy" },
+	[276]	= { "set_mempolicy" },
+	[277]	= { "mq_open" },
+	[278]	= { "mq_unlink" },
+	[279]	= { "mq_timedsend" },
+	[280]	= { "mq_timedreceive" },
+	[281]	= { "mq_notify" },
+	[282]	= { "mq_getsetattr" },
+	[283]	= { "sys_kexec_load" },
+};
+
+asmlinkage void do_syscall_trace(int leaving)
+{
+#if 0
+	unsigned long *argp;
+	const char *name;
+	unsigned argmask;
+	char buffer[16];
+
+	if (!kstrace)
+		return;
+
+	if (!current->mm)
+		return;
+
+	if (__frame->gr7 == __NR_close)
+		return;
+
+#if 0
+	if (__frame->gr7 != __NR_mmap2 &&
+	    __frame->gr7 != __NR_vfork &&
+	    __frame->gr7 != __NR_execve &&
+	    __frame->gr7 != __NR_exit)
+		return;
+#endif
+
+	argmask = 0;
+	name = NULL;
+	if (__frame->gr7 < NR_syscalls) {
+		name = __syscall_name_table[__frame->gr7].name;
+		argmask = __syscall_name_table[__frame->gr7].argmask;
+	}
+	if (!name) {
+		sprintf(buffer, "sys_%lx", __frame->gr7);
+		name = buffer;
+	}
+
+	if (!leaving) {
+		if (!argmask) {
+			printk(KERN_CRIT "[%d] %s(%lx,%lx,%lx,%lx,%lx,%lx)\n",
+			       current->pid,
+			       name,
+			       __frame->gr8,
+			       __frame->gr9,
+			       __frame->gr10,
+			       __frame->gr11,
+			       __frame->gr12,
+			       __frame->gr13);
+		}
+		else if (argmask == 0xffffff) {
+			printk(KERN_CRIT "[%d] %s()\n",
+			       current->pid,
+			       name);
+		}
+		else {
+			printk(KERN_CRIT "[%d] %s(",
+			       current->pid,
+			       name);
+
+			argp = &__frame->gr8;
+
+			do {
+				switch (argmask & 0xf) {
+				case 1:
+					printk("%ld", (long) *argp);
+					break;
+				case 2:
+					printk("%lo", *argp);
+					break;
+				case 3:
+					printk("%lx", *argp);
+					break;
+				case 4:
+					printk("%p", (void *) *argp);
+					break;
+				case 5:
+					printk("\"%s\"", (char *) *argp);
+					break;
+				}
+
+				argp++;
+				argmask >>= 4;
+				if (argmask)
+					printk(",");
+
+			} while (argmask);
+
+			printk(")\n");
+		}
+	}
+	else {
+		if ((int)__frame->gr8 > -4096 && (int)__frame->gr8 < 4096)
+			printk(KERN_CRIT "[%d] %s() = %ld\n", current->pid, name, __frame->gr8);
+		else
+			printk(KERN_CRIT "[%d] %s() = %lx\n", current->pid, name, __frame->gr8);
+	}
+	return;
+#endif
+
+	if (!test_thread_flag(TIF_SYSCALL_TRACE))
+		return;
+
+	if (!(current->ptrace & PT_PTRACED))
+		return;
+
+	/* we need to indicate entry or exit to strace */
+	if (leaving)
+		__frame->__status |= REG__STATUS_SYSC_EXIT;
+	else
+		__frame->__status |= REG__STATUS_SYSC_ENTRY;
+
+	ptrace_notify(SIGTRAP);
+
+	/*
+	 * 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 -Nru a/arch/frv/kernel/semaphore.c b/arch/frv/kernel/semaphore.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/kernel/semaphore.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,156 @@
+/* semaphore.c: FR-V semaphores
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ * - Derived from lib/rwsem-spinlock.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.
+ */
+
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/module.h>
+#include <asm/semaphore.h>
+
+struct sem_waiter {
+	struct list_head	list;
+	struct task_struct	*task;
+};
+
+#if SEM_DEBUG
+void semtrace(struct semaphore *sem, const char *str)
+{
+	if (sem->debug)
+		printk("[%d] %s({%d,%d})\n",
+		       current->pid,
+		       str,
+		       sem->counter,
+		       list_empty(&sem->wait_list) ? 0 : 1);
+}
+#else
+#define semtrace(SEM,STR) do { } while(0)
+#endif
+
+/*
+ * wait for a token to be granted from a semaphore
+ * - entered with lock held and interrupts disabled
+ */
+void __down(struct semaphore *sem, unsigned long flags)
+{
+	struct task_struct *tsk = current;
+	struct sem_waiter waiter;
+
+	semtrace(sem, "Entering __down");
+
+	/* set up my own style of waitqueue */
+	waiter.task = tsk;
+	get_task_struct(tsk);
+
+	list_add_tail(&waiter.list, &sem->wait_list);
+
+	/* we don't need to touch the semaphore struct anymore */
+	spin_unlock_irqrestore(&sem->wait_lock, flags);
+
+	/* wait to be given the semaphore */
+	set_task_state(tsk, TASK_UNINTERRUPTIBLE);
+
+	for (;;) {
+		if (list_empty(&waiter.list))
+			break;
+		schedule();
+		set_task_state(tsk, TASK_UNINTERRUPTIBLE);
+	}
+
+	tsk->state = TASK_RUNNING;
+	semtrace(sem, "Leaving __down");
+}
+
+EXPORT_SYMBOL(__down);
+
+/*
+ * interruptibly wait for a token to be granted from a semaphore
+ * - entered with lock held and interrupts disabled
+ */
+int __down_interruptible(struct semaphore *sem, unsigned long flags)
+{
+	struct task_struct *tsk = current;
+	struct sem_waiter waiter;
+	int ret;
+
+	semtrace(sem,"Entering __down_interruptible");
+
+	/* set up my own style of waitqueue */
+	waiter.task = tsk;
+	get_task_struct(tsk);
+
+	list_add_tail(&waiter.list, &sem->wait_list);
+
+	/* we don't need to touch the semaphore struct anymore */
+	set_task_state(tsk, TASK_INTERRUPTIBLE);
+
+	spin_unlock_irqrestore(&sem->wait_lock, flags);
+
+	/* wait to be given the semaphore */
+	ret = 0;
+	for (;;) {
+		if (list_empty(&waiter.list))
+			break;
+		if (unlikely(signal_pending(current)))
+			goto interrupted;
+		schedule();
+		set_task_state(tsk, TASK_INTERRUPTIBLE);
+	}
+
+ out:
+	tsk->state = TASK_RUNNING;
+	semtrace(sem, "Leaving __down_interruptible");
+	return ret;
+
+ interrupted:
+	spin_lock_irqsave(&sem->wait_lock, flags);
+
+	if (!list_empty(&waiter.list)) {
+		list_del(&waiter.list);
+		ret = -EINTR;
+	}
+
+	spin_unlock_irqrestore(&sem->wait_lock, flags);
+	if (ret == -EINTR)
+		put_task_struct(current);
+	goto out;
+}
+
+EXPORT_SYMBOL(__down_interruptible);
+
+/*
+ * release a single token back to a semaphore
+ * - entered with lock held and interrupts disabled
+ */
+void __up(struct semaphore *sem)
+{
+	struct task_struct *tsk;
+	struct sem_waiter *waiter;
+
+	semtrace(sem,"Entering __up");
+
+	/* grant the token to the process at the front of the queue */
+	waiter = list_entry(sem->wait_list.next, struct sem_waiter, list);
+
+	/* We must be careful not to touch 'waiter' after we set ->task = NULL.
+	 * It is an allocated on the waiter's stack and may become invalid at
+	 * any time after that point (due to a wakeup from another source).
+	 */
+	list_del_init(&waiter->list);
+	tsk = waiter->task;
+	mb();
+	waiter->task = NULL;
+	wake_up_process(tsk);
+	put_task_struct(tsk);
+
+	semtrace(sem,"Leaving __up");
+}
+
+EXPORT_SYMBOL(__up);
diff -Nru a/arch/frv/kernel/setup.c b/arch/frv/kernel/setup.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/kernel/setup.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,1197 @@
+/* setup.c: FRV specific setup
+ *
+ * Copyright (C) 2003-5 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ * - Derived from arch/m68k/kernel/setup.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.
+ */
+
+#include <linux/config.h>
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/fb.h>
+#include <linux/console.h>
+#include <linux/genhd.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/major.h>
+#include <linux/bootmem.h>
+#include <linux/highmem.h>
+#include <linux/seq_file.h>
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+#include <linux/serial_reg.h>
+
+#include <asm/setup.h>
+#include <asm/serial.h>
+#include <asm/irq.h>
+#include <asm/sections.h>
+#include <asm/pgalloc.h>
+#include <asm/busctl-regs.h>
+#include <asm/serial-regs.h>
+#include <asm/timer-regs.h>
+#include <asm/irc-regs.h>
+#include <asm/spr-regs.h>
+#include <asm/mb-regs.h>
+#include <asm/mb93493-regs.h>
+#include <asm/gdb-stub.h>
+#include <asm/irq-routing.h>
+#include <asm/io.h>
+
+#ifdef CONFIG_BLK_DEV_INITRD
+#include <linux/blk.h>
+#include <asm/pgtable.h>
+#endif
+
+#include "local.h"
+
+#ifdef CONFIG_MB93090_MB00
+static void __init mb93090_display(void);
+#endif
+#ifdef CONFIG_MMU
+static void __init setup_linux_memory(void);
+#else
+static void __init setup_uclinux_memory(void);
+#endif
+
+#ifdef CONFIG_CONSOLE
+extern struct consw *conswitchp;
+#ifdef CONFIG_FRAMEBUFFER
+extern struct consw fb_con;
+#endif
+#endif
+
+#ifdef CONFIG_MB93090_MB00
+static char __initdata mb93090_banner[] = "FJ/RH FR-V Linux";
+static char __initdata mb93090_version[] = UTS_RELEASE;
+
+int __nongprelbss mb93090_mb00_detected;
+#endif
+
+const char __frv_unknown_system[] = "unknown";
+const char __frv_mb93091_cb10[] = "mb93091-cb10";
+const char __frv_mb93091_cb11[] = "mb93091-cb11";
+const char __frv_mb93091_cb30[] = "mb93091-cb30";
+const char __frv_mb93091_cb41[] = "mb93091-cb41";
+const char __frv_mb93091_cb60[] = "mb93091-cb60";
+const char __frv_mb93091_cb70[] = "mb93091-cb70";
+const char __frv_mb93091_cb451[] = "mb93091-cb451";
+const char __frv_mb93090_mb00[] = "mb93090-mb00";
+
+const char __frv_mb93493[] = "mb93493";
+
+const char __frv_mb93093[] = "mb93093";
+
+static const char *__nongprelbss cpu_series;
+static const char *__nongprelbss cpu_core;
+static const char *__nongprelbss cpu_silicon;
+static const char *__nongprelbss cpu_mmu;
+static const char *__nongprelbss cpu_system;
+static const char *__nongprelbss cpu_board1;
+static const char *__nongprelbss cpu_board2;
+
+static unsigned long __nongprelbss cpu_psr_all;
+static unsigned long __nongprelbss cpu_hsr0_all;
+
+unsigned long __nongprelbss pdm_suspend_mode;
+
+unsigned long __nongprelbss rom_length;
+unsigned long __nongprelbss memory_start;
+unsigned long __nongprelbss memory_end;
+
+unsigned long __nongprelbss dma_coherent_mem_start;
+unsigned long __nongprelbss dma_coherent_mem_end;
+
+unsigned long __initdata __sdram_old_base;
+unsigned long __initdata num_mappedpages;
+
+struct cpuinfo_frv __nongprelbss boot_cpu_data;
+
+char command_line[COMMAND_LINE_SIZE];
+char __initdata redboot_command_line[COMMAND_LINE_SIZE];
+
+#ifdef CONFIG_PM
+#define __pminit
+#define __pminitdata
+#else
+#define __pminit __init
+#define __pminitdata __initdata
+#endif
+
+struct clock_cmode {
+	uint8_t	xbus, sdram, corebus, core, dsu;
+};
+
+#define _frac(N,D) ((N)<<4 | (D))
+#define _x0_16	_frac(1,6)
+#define _x0_25	_frac(1,4)
+#define _x0_33	_frac(1,3)
+#define _x0_375	_frac(3,8)
+#define _x0_5	_frac(1,2)
+#define _x0_66	_frac(2,3)
+#define _x0_75	_frac(3,4)
+#define _x1	_frac(1,1)
+#define _x1_5	_frac(3,2)
+#define _x2	_frac(2,1)
+#define _x3	_frac(3,1)
+#define _x4	_frac(4,1)
+#define _x4_5	_frac(9,2)
+#define _x6	_frac(6,1)
+#define _x8	_frac(8,1)
+#define _x9	_frac(9,1)
+
+int __nongprelbss clock_p0_current;
+int __nongprelbss clock_cm_current;
+int __nongprelbss clock_cmode_current;
+#ifdef CONFIG_PM
+int __nongprelbss clock_cmodes_permitted;
+unsigned long __nongprelbss clock_bits_settable;
+#endif
+
+static struct clock_cmode __pminitdata undef_clock_cmode = { _x1, _x1, _x1, _x1, _x1 };
+
+static struct clock_cmode __pminitdata clock_cmodes_fr401_fr403[16] = {
+	[4]	= {	_x1,	_x1,	_x2,	_x2,	_x0_25	},
+	[5]	= { 	_x1,	_x2,	_x4,	_x4,	_x0_5	},
+	[8]	= { 	_x1,	_x1,	_x1,	_x2,	_x0_25	},
+	[9]	= { 	_x1,	_x2,	_x2,	_x4,	_x0_5	},
+	[11]	= { 	_x1,	_x4,	_x4,	_x8,	_x1	},
+	[12]	= { 	_x1,	_x1,	_x2,	_x4,	_x0_5	},
+	[13]	= { 	_x1,	_x2,	_x4,	_x8,	_x1	},
+};
+
+static struct clock_cmode __pminitdata clock_cmodes_fr405[16] = {
+	[0]	= {	_x1,	_x1,	_x1,	_x1,	_x0_5	},
+	[1]	= {	_x1,	_x1,	_x1,	_x3,	_x0_25	},
+	[2]	= {	_x1,	_x1,	_x2,	_x6,	_x0_5	},
+	[3]	= {	_x1,	_x2,	_x2,	_x6,	_x0_5	},
+	[4]	= {	_x1,	_x1,	_x2,	_x2,	_x0_16	},
+	[8]	= { 	_x1,	_x1,	_x1,	_x2,	_x0_16	},
+	[9]	= { 	_x1,	_x2,	_x2,	_x4,	_x0_33	},
+	[12]	= { 	_x1,	_x1,	_x2,	_x4,	_x0_33	},
+	[14]	= { 	_x1,	_x3,	_x3,	_x9,	_x0_75	},
+	[15]	= { 	_x1,	_x1_5,	_x1_5,	_x4_5,	_x0_375	},
+
+#define CLOCK_CMODES_PERMITTED_FR405 0xd31f
+};
+
+static struct clock_cmode __pminitdata clock_cmodes_fr555[16] = {
+	[0]	= {	_x1,	_x2,	_x2,	_x4,	_x0_33	},
+	[1]	= {	_x1,	_x3,	_x3,	_x6,	_x0_5	},
+	[2]	= {	_x1,	_x2,	_x4,	_x8,	_x0_66	},
+	[3]	= {	_x1,	_x1_5,	_x3,	_x6,	_x0_5	},
+	[4]	= {	_x1,	_x3,	_x3,	_x9,	_x0_75	},
+	[5]	= {	_x1,	_x2,	_x2,	_x6,	_x0_5	},
+	[6]	= {	_x1,	_x1_5,	_x1_5,	_x4_5,	_x0_375	},
+};
+
+static const struct clock_cmode __pminitdata *clock_cmodes;
+static int __pminitdata clock_doubled;
+
+static struct uart_port __initdata __frv_uart0 = {
+	.uartclk		= 0,
+	.membase		= (char *) UART0_BASE,
+	.irq			= IRQ_CPU_UART0,
+	.regshift		= 3,
+	.iotype			= UPIO_MEM,
+	.flags			= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+};
+
+static struct uart_port __initdata __frv_uart1 = {
+	.uartclk		= 0,
+	.membase		= (char *) UART1_BASE,
+	.irq			= IRQ_CPU_UART1,
+	.regshift		= 3,
+	.iotype			= UPIO_MEM,
+	.flags			= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+};
+
+#if 0
+static void __init printk_xampr(unsigned long ampr, unsigned long amlr, char i_d, int n)
+{
+	unsigned long phys, virt, cxn, size;
+
+#ifdef CONFIG_MMU
+	virt = amlr & 0xffffc000;
+	cxn = amlr & 0x3fff;
+#else
+	virt = ampr & 0xffffc000;
+	cxn = 0;
+#endif
+	phys = ampr & xAMPRx_PPFN;
+	size = 1 << (((ampr & xAMPRx_SS) >> 4) + 17);
+
+	printk("%cAMPR%d: va %08lx-%08lx [pa %08lx] %c%c%c%c [cxn:%04lx]\n",
+	       i_d, n,
+	       virt, virt + size - 1,
+	       phys,
+	       ampr & xAMPRx_S  ? 'S' : '-',
+	       ampr & xAMPRx_C  ? 'C' : '-',
+	       ampr & DAMPRx_WP ? 'W' : '-',
+	       ampr & xAMPRx_V  ? 'V' : '-',
+	       cxn
+	       );
+}
+#endif
+
+/*****************************************************************************/
+/*
+ * dump the memory map
+ */
+static void __init dump_memory_map(void)
+{
+
+#if 0
+	/* dump the protection map */
+	printk_xampr(__get_IAMPR(0),  __get_IAMLR(0),  'I', 0);
+	printk_xampr(__get_IAMPR(1),  __get_IAMLR(1),  'I', 1);
+	printk_xampr(__get_IAMPR(2),  __get_IAMLR(2),  'I', 2);
+	printk_xampr(__get_IAMPR(3),  __get_IAMLR(3),  'I', 3);
+	printk_xampr(__get_IAMPR(4),  __get_IAMLR(4),  'I', 4);
+	printk_xampr(__get_IAMPR(5),  __get_IAMLR(5),  'I', 5);
+	printk_xampr(__get_IAMPR(6),  __get_IAMLR(6),  'I', 6);
+	printk_xampr(__get_IAMPR(7),  __get_IAMLR(7),  'I', 7);
+	printk_xampr(__get_IAMPR(8),  __get_IAMLR(8),  'I', 8);
+	printk_xampr(__get_IAMPR(9),  __get_IAMLR(9),  'i', 9);
+	printk_xampr(__get_IAMPR(10), __get_IAMLR(10), 'I', 10);
+	printk_xampr(__get_IAMPR(11), __get_IAMLR(11), 'I', 11);
+	printk_xampr(__get_IAMPR(12), __get_IAMLR(12), 'I', 12);
+	printk_xampr(__get_IAMPR(13), __get_IAMLR(13), 'I', 13);
+	printk_xampr(__get_IAMPR(14), __get_IAMLR(14), 'I', 14);
+	printk_xampr(__get_IAMPR(15), __get_IAMLR(15), 'I', 15);
+
+	printk_xampr(__get_DAMPR(0),  __get_DAMLR(0),  'D', 0);
+	printk_xampr(__get_DAMPR(1),  __get_DAMLR(1),  'D', 1);
+	printk_xampr(__get_DAMPR(2),  __get_DAMLR(2),  'D', 2);
+	printk_xampr(__get_DAMPR(3),  __get_DAMLR(3),  'D', 3);
+	printk_xampr(__get_DAMPR(4),  __get_DAMLR(4),  'D', 4);
+	printk_xampr(__get_DAMPR(5),  __get_DAMLR(5),  'D', 5);
+	printk_xampr(__get_DAMPR(6),  __get_DAMLR(6),  'D', 6);
+	printk_xampr(__get_DAMPR(7),  __get_DAMLR(7),  'D', 7);
+	printk_xampr(__get_DAMPR(8),  __get_DAMLR(8),  'D', 8);
+	printk_xampr(__get_DAMPR(9),  __get_DAMLR(9),  'D', 9);
+	printk_xampr(__get_DAMPR(10), __get_DAMLR(10), 'D', 10);
+	printk_xampr(__get_DAMPR(11), __get_DAMLR(11), 'D', 11);
+	printk_xampr(__get_DAMPR(12), __get_DAMLR(12), 'D', 12);
+	printk_xampr(__get_DAMPR(13), __get_DAMLR(13), 'D', 13);
+	printk_xampr(__get_DAMPR(14), __get_DAMLR(14), 'D', 14);
+	printk_xampr(__get_DAMPR(15), __get_DAMLR(15), 'D', 15);
+#endif
+
+#if 0
+	/* dump the bus controller registers */
+	printk("LGCR: %08lx\n", __get_LGCR());
+	printk("Master: %08lx-%08lx CR=%08lx\n",
+	       __get_LEMBR(), __get_LEMBR() + __get_LEMAM(),
+	       __get_LMAICR());
+
+	int loop;
+	for (loop = 1; loop <= 7; loop++) {
+		unsigned long lcr = __get_LCR(loop), lsbr = __get_LSBR(loop);
+		printk("CS#%d: %08lx-%08lx %c%c%c%c%c%c%c%c%c\n",
+		       loop,
+		       lsbr, lsbr + __get_LSAM(loop),
+		       lcr & 0x80000000 ? 'r' : '-',
+		       lcr & 0x40000000 ? 'w' : '-',
+		       lcr & 0x08000000 ? 'b' : '-',
+		       lcr & 0x04000000 ? 'B' : '-',
+		       lcr & 0x02000000 ? 'C' : '-',
+		       lcr & 0x01000000 ? 'D' : '-',
+		       lcr & 0x00800000 ? 'W' : '-',
+		       lcr & 0x00400000 ? 'R' : '-',
+		       (lcr & 0x00030000) == 0x00000000 ? '4' :
+		       (lcr & 0x00030000) == 0x00010000 ? '2' :
+		       (lcr & 0x00030000) == 0x00020000 ? '1' :
+		       '-'
+		       );
+	}
+#endif
+
+#if 0
+	printk("\n");
+#endif
+} /* end dump_memory_map() */
+
+/*****************************************************************************/
+/*
+ * attempt to detect a VDK motherboard and DAV daughter board on an MB93091 system
+ */
+#ifdef CONFIG_MB93091_VDK
+static void __init detect_mb93091(void)
+{
+#ifdef CONFIG_MB93090_MB00
+	/* Detect CB70 without motherboard */
+	if (!(cpu_system == __frv_mb93091_cb70 && ((*(unsigned short *)0xffc00030) & 0x100))) {
+		cpu_board1 = __frv_mb93090_mb00;
+		mb93090_mb00_detected = 1;
+	}
+#endif
+
+#ifdef CONFIG_FUJITSU_MB93493
+	cpu_board2 = __frv_mb93493;
+#endif
+
+} /* end detect_mb93091() */
+#endif
+
+/*****************************************************************************/
+/*
+ * determine the CPU type and set appropriate parameters
+ *
+ * Family     Series      CPU Core    Silicon    Imple  Vers
+ * ----------------------------------------------------------
+ * FR-V --+-> FR400 --+-> FR401 --+-> MB93401     02     00 [1]
+ *        |           |           |
+ *        |           |           +-> MB93401/A   02     01
+ *        |           |           |
+ *        |           |           +-> MB93403     02     02
+ *        |           |
+ *        |           +-> FR405 ----> MB93405     04     00
+ *        |
+ *        +-> FR450 ----> FR451 ----> MB93451     05     00
+ *        |
+ *        +-> FR500 ----> FR501 --+-> MB93501     01     01 [2]
+ *        |                       |
+ *        |                       +-> MB93501/A   01     02
+ *        |
+ *        +-> FR550 --+-> FR551 ----> MB93555     03     01
+ *
+ *  [1] The MB93401 is an obsolete CPU replaced by the MB93401A
+ *  [2] The MB93501 is an obsolete CPU replaced by the MB93501A
+ *
+ * Imple is PSR(Processor Status Register)[31:28].
+ * Vers is PSR(Processor Status Register)[27:24].
+ *
+ * A "Silicon" consists of CPU core and some on-chip peripherals.
+ */
+static void __init determine_cpu(void)
+{
+	unsigned long hsr0 = __get_HSR(0);
+	unsigned long psr = __get_PSR();
+
+	/* work out what selectable services the CPU supports */
+	__set_PSR(psr | PSR_EM | PSR_EF | PSR_CM | PSR_NEM);
+	cpu_psr_all = __get_PSR();
+	__set_PSR(psr);
+
+	__set_HSR(0, hsr0 | HSR0_GRLE | HSR0_GRHE | HSR0_FRLE | HSR0_FRHE);
+	cpu_hsr0_all = __get_HSR(0);
+	__set_HSR(0, hsr0);
+
+	/* derive other service specs from the CPU type */
+	cpu_series		= "unknown";
+	cpu_core		= "unknown";
+	cpu_silicon		= "unknown";
+	cpu_mmu			= "Prot";
+	cpu_system		= __frv_unknown_system;
+	clock_cmodes		= NULL;
+	clock_doubled		= 0;
+#ifdef CONFIG_PM
+	clock_bits_settable	= CLOCK_BIT_CM_H | CLOCK_BIT_CM_M | CLOCK_BIT_P0;
+#endif
+
+	switch (PSR_IMPLE(psr)) {
+	case PSR_IMPLE_FR401:
+		cpu_series	= "fr400";
+		cpu_core	= "fr401";
+		pdm_suspend_mode = HSR0_PDM_PLL_RUN;
+
+		switch (PSR_VERSION(psr)) {
+		case PSR_VERSION_FR401_MB93401:
+			cpu_silicon	= "mb93401";
+			cpu_system	= __frv_mb93091_cb10;
+			clock_cmodes	= clock_cmodes_fr401_fr403;
+			clock_doubled	= 1;
+			break;
+		case PSR_VERSION_FR401_MB93401A:
+			cpu_silicon	= "mb93401/A";
+			cpu_system	= __frv_mb93091_cb11;
+			clock_cmodes	= clock_cmodes_fr401_fr403;
+			break;
+		case PSR_VERSION_FR401_MB93403:
+			cpu_silicon	= "mb93403";
+#ifndef CONFIG_MB93093_PDK
+			cpu_system	= __frv_mb93091_cb30;
+#else
+			cpu_system	= __frv_mb93093;
+#endif
+			clock_cmodes	= clock_cmodes_fr401_fr403;
+			break;
+		default:
+			break;
+		}
+		break;
+
+	case PSR_IMPLE_FR405:
+		cpu_series	= "fr400";
+		cpu_core	= "fr405";
+		pdm_suspend_mode = HSR0_PDM_PLL_STOP;
+
+		switch (PSR_VERSION(psr)) {
+		case PSR_VERSION_FR405_MB93405:
+			cpu_silicon	= "mb93405";
+			cpu_system	= __frv_mb93091_cb60;
+			clock_cmodes	= clock_cmodes_fr405;
+#ifdef CONFIG_PM
+			clock_bits_settable |= CLOCK_BIT_CMODE;
+			clock_cmodes_permitted = CLOCK_CMODES_PERMITTED_FR405;
+#endif
+
+			/* the FPGA on the CB70 has extra registers
+			 * - it has 0x0046 in the VDK_ID FPGA register at 0x1a0, which is
+			 *   how we tell the difference between it and a CB60
+			 */
+			if (*(volatile unsigned short *) 0xffc001a0 == 0x0046)
+				cpu_system = __frv_mb93091_cb70;
+			break;
+		default:
+			break;
+		}
+		break;
+
+	case PSR_IMPLE_FR451:
+		cpu_series	= "fr450";
+		cpu_core	= "fr451";
+		pdm_suspend_mode = HSR0_PDM_PLL_STOP;
+#ifdef CONFIG_PM
+		clock_bits_settable |= CLOCK_BIT_CMODE;
+		clock_cmodes_permitted = CLOCK_CMODES_PERMITTED_FR405;
+#endif
+		switch (PSR_VERSION(psr)) {
+		case PSR_VERSION_FR451_MB93451:
+			cpu_silicon	= "mb93451";
+			cpu_mmu		= "Prot, SAT, xSAT, DAT";
+			cpu_system	= __frv_mb93091_cb451;
+			clock_cmodes	= clock_cmodes_fr405;
+			break;
+		default:
+			break;
+		}
+		break;
+
+	case PSR_IMPLE_FR501:
+		cpu_series	= "fr500";
+		cpu_core	= "fr501";
+		pdm_suspend_mode = HSR0_PDM_PLL_STOP;
+
+		switch (PSR_VERSION(psr)) {
+		case PSR_VERSION_FR501_MB93501:  cpu_silicon = "mb93501";   break;
+		case PSR_VERSION_FR501_MB93501A: cpu_silicon = "mb93501/A"; break;
+		default:
+			break;
+		}
+		break;
+
+	case PSR_IMPLE_FR551:
+		cpu_series	= "fr550";
+		cpu_core	= "fr551";
+		pdm_suspend_mode = HSR0_PDM_PLL_RUN;
+
+		switch (PSR_VERSION(psr)) {
+		case PSR_VERSION_FR551_MB93555:
+			cpu_silicon	= "mb93555";
+			cpu_mmu		= "Prot, SAT";
+			cpu_system	= __frv_mb93091_cb41;
+			clock_cmodes	= clock_cmodes_fr555;
+			clock_doubled	= 1;
+			break;
+		default:
+			break;
+		}
+		break;
+
+	default:
+		break;
+	}
+
+	printk("- Series:%s CPU:%s Silicon:%s\n",
+	       cpu_series, cpu_core, cpu_silicon);
+
+#ifdef CONFIG_MB93091_VDK
+	detect_mb93091();
+#endif
+
+#if defined(CONFIG_MB93093_PDK) && defined(CONFIG_FUJITSU_MB93493)
+	cpu_board2 = __frv_mb93493;
+#endif
+
+} /* end determine_cpu() */
+
+/*****************************************************************************/
+/*
+ * calculate the bus clock speed
+ */
+void __pminit determine_clocks(int verbose)
+{
+	const struct clock_cmode *mode, *tmode;
+	unsigned long clkc, psr, quot;
+
+	clkc = __get_CLKC();
+	psr = __get_PSR();
+
+	clock_p0_current = !!(clkc & CLKC_P0);
+	clock_cm_current = clkc & CLKC_CM;
+	clock_cmode_current = (clkc & CLKC_CMODE) >> CLKC_CMODE_s;
+
+	if (verbose)
+		printk("psr=%08lx hsr0=%08lx clkc=%08lx\n", psr, __get_HSR(0), clkc);
+
+	/* the CB70 has some alternative ways of setting the clock speed through switches accessed
+	 * through the FPGA.  */
+	if (cpu_system == __frv_mb93091_cb70) {
+		unsigned short clkswr = *(volatile unsigned short *) 0xffc00104UL & 0x1fffUL;
+
+		if (clkswr & 0x1000)
+			__clkin_clock_speed_HZ = 60000000UL;
+		else
+			__clkin_clock_speed_HZ =
+				((clkswr >> 8) & 0xf) * 10000000 +
+				((clkswr >> 4) & 0xf) * 1000000 +
+				((clkswr     ) & 0xf) * 100000;
+	}
+	/* the FR451 is currently fixed at 24MHz */
+	else if (cpu_system == __frv_mb93091_cb451) {
+		//__clkin_clock_speed_HZ = 24000000UL; // CB451-FPGA
+		unsigned short clkswr = *(volatile unsigned short *) 0xffc00104UL & 0x1fffUL;
+
+		if (clkswr & 0x1000)
+			__clkin_clock_speed_HZ = 60000000UL;
+		else
+			__clkin_clock_speed_HZ =
+				((clkswr >> 8) & 0xf) * 10000000 +
+				((clkswr >> 4) & 0xf) * 1000000 +
+				((clkswr     ) & 0xf) * 100000;
+	}
+	/* otherwise determine the clockspeed from VDK or other registers */
+	else {
+		__clkin_clock_speed_HZ = __get_CLKIN();
+	}
+
+	/* look up the appropriate clock relationships table entry */
+	mode = &undef_clock_cmode;
+	if (clock_cmodes) {
+		tmode = &clock_cmodes[(clkc & CLKC_CMODE) >> CLKC_CMODE_s];
+		if (tmode->xbus)
+			mode = tmode;
+	}
+
+#define CLOCK(SRC,RATIO) ((SRC) * (((RATIO) >> 4) & 0x0f) / ((RATIO) & 0x0f))
+
+	if (clock_doubled)
+		__clkin_clock_speed_HZ <<= 1;
+
+	__ext_bus_clock_speed_HZ	= CLOCK(__clkin_clock_speed_HZ, mode->xbus);
+	__sdram_clock_speed_HZ		= CLOCK(__clkin_clock_speed_HZ, mode->sdram);
+	__dsu_clock_speed_HZ		= CLOCK(__clkin_clock_speed_HZ, mode->dsu);
+
+	switch (clkc & CLKC_CM) {
+	case 0: /* High */
+		__core_bus_clock_speed_HZ	= CLOCK(__clkin_clock_speed_HZ, mode->corebus);
+		__core_clock_speed_HZ		= CLOCK(__clkin_clock_speed_HZ, mode->core);
+		break;
+	case 1: /* Medium */
+		__core_bus_clock_speed_HZ	= CLOCK(__clkin_clock_speed_HZ, mode->sdram);
+		__core_clock_speed_HZ		= CLOCK(__clkin_clock_speed_HZ, mode->sdram);
+		break;
+	case 2: /* Low; not supported */
+	case 3: /* UNDEF */
+		printk("Unsupported CLKC CM %ld\n", clkc & CLKC_CM);
+		panic("Bye");
+	}
+
+	__res_bus_clock_speed_HZ = __ext_bus_clock_speed_HZ;
+	if (clkc & CLKC_P0)
+		__res_bus_clock_speed_HZ >>= 1;
+
+	if (verbose) {
+		printk("CLKIN: %lu.%3.3luMHz\n",
+		       __clkin_clock_speed_HZ / 1000000,
+		       (__clkin_clock_speed_HZ / 1000) % 1000);
+
+		printk("CLKS:"
+		       " ext=%luMHz res=%luMHz sdram=%luMHz cbus=%luMHz core=%luMHz dsu=%luMHz\n",
+		       __ext_bus_clock_speed_HZ / 1000000,
+		       __res_bus_clock_speed_HZ / 1000000,
+		       __sdram_clock_speed_HZ / 1000000,
+		       __core_bus_clock_speed_HZ / 1000000,
+		       __core_clock_speed_HZ / 1000000,
+		       __dsu_clock_speed_HZ / 1000000
+		       );
+	}
+
+	/* calculate the number of __delay() loop iterations per sec (2 insn loop) */
+	__delay_loops_MHz = __core_clock_speed_HZ / (1000000 * 2);
+
+	/* set the serial prescaler */
+	__serial_clock_speed_HZ = __res_bus_clock_speed_HZ;
+	quot = 1;
+	while (__serial_clock_speed_HZ / quot / 16 / 65536 > 3000)
+		quot += 1;
+
+	/* double the divisor if P0 is clear, so that if/when P0 is set, it's still achievable
+	 * - we have to be careful - dividing too much can mean we can't get 115200 baud
+	 */
+	if (__serial_clock_speed_HZ > 32000000 && !(clkc & CLKC_P0))
+		quot <<= 1;
+
+	__serial_clock_speed_HZ /= quot;
+	__frv_uart0.uartclk = __serial_clock_speed_HZ;
+	__frv_uart1.uartclk = __serial_clock_speed_HZ;
+
+	if (verbose)
+		printk("      uart=%luMHz\n", __serial_clock_speed_HZ / 1000000 * quot);
+
+	while (!(__get_UART0_LSR() & UART_LSR_TEMT))
+		continue;
+
+	while (!(__get_UART1_LSR() & UART_LSR_TEMT))
+		continue;
+
+	__set_UCPVR(quot);
+	__set_UCPSR(0);
+} /* end determine_clocks() */
+
+/*****************************************************************************/
+/*
+ * reserve some DMA consistent memory
+ */
+#ifdef CONFIG_RESERVE_DMA_COHERENT
+static void __init reserve_dma_coherent(void)
+{
+	unsigned long ampr;
+
+	/* find the first non-kernel memory tile and steal it */
+#define __steal_AMPR(r)						\
+	if (__get_DAMPR(r) & xAMPRx_V) {			\
+		ampr = __get_DAMPR(r);				\
+		__set_DAMPR(r, ampr | xAMPRx_S | xAMPRx_C);	\
+		__set_IAMPR(r, 0);				\
+		goto found;					\
+	}
+
+	__steal_AMPR(1);
+	__steal_AMPR(2);
+	__steal_AMPR(3);
+	__steal_AMPR(4);
+	__steal_AMPR(5);
+	__steal_AMPR(6);
+
+	if (PSR_IMPLE(__get_PSR()) == PSR_IMPLE_FR551) {
+		__steal_AMPR(7);
+		__steal_AMPR(8);
+		__steal_AMPR(9);
+		__steal_AMPR(10);
+		__steal_AMPR(11);
+		__steal_AMPR(12);
+		__steal_AMPR(13);
+		__steal_AMPR(14);
+	}
+
+	/* unable to grant any DMA consistent memory */
+	printk("No DMA consistent memory reserved\n");
+	return;
+
+ found:
+	dma_coherent_mem_start = ampr & xAMPRx_PPFN;
+	ampr &= xAMPRx_SS;
+	ampr >>= 4;
+	ampr = 1 << (ampr - 3 + 20);
+	dma_coherent_mem_end = dma_coherent_mem_start + ampr;
+
+	printk("DMA consistent memory reserved %lx-%lx\n",
+	       dma_coherent_mem_start, dma_coherent_mem_end);
+
+} /* end reserve_dma_coherent() */
+#endif
+
+/*****************************************************************************/
+/*
+ * calibrate the delay loop
+ */
+void __init calibrate_delay(void)
+{
+	loops_per_jiffy = __delay_loops_MHz * (1000000 / HZ);
+
+	printk("Calibrating delay loop... %lu.%02lu BogoMIPS\n",
+	       loops_per_jiffy / (500000 / HZ),
+	       (loops_per_jiffy / (5000 / HZ)) % 100);
+
+} /* end calibrate_delay() */
+
+/*****************************************************************************/
+/*
+ * look through the command line for some things we need to know immediately
+ */
+static void __init parse_cmdline_early(char *cmdline)
+{
+	if (!cmdline)
+		return;
+
+	while (*cmdline) {
+		if (*cmdline == ' ')
+			cmdline++;
+
+		/* "mem=XXX[kKmM]" sets SDRAM size to <mem>, overriding the value we worked
+		 * out from the SDRAM controller mask register
+		 */
+		if (!memcmp(cmdline, "mem=", 4)) {
+			unsigned long long mem_size;
+
+			mem_size = memparse(cmdline + 4, &cmdline);
+			memory_end = memory_start + mem_size;
+		}
+
+		while (*cmdline && *cmdline != ' ')
+			cmdline++;
+	}
+
+} /* end parse_cmdline_early() */
+
+/*****************************************************************************/
+/*
+ *
+ */
+void __init setup_arch(char **cmdline_p)
+{
+#ifdef CONFIG_MMU
+	printk("Linux FR-V port done by Red Hat Inc <dhowells@redhat.com>\n");
+#else
+	printk("uClinux FR-V port done by Red Hat Inc <dhowells@redhat.com>\n");
+#endif
+
+	memcpy(saved_command_line, redboot_command_line, COMMAND_LINE_SIZE);
+
+	determine_cpu();
+	determine_clocks(1);
+
+	/* For printk-directly-beats-on-serial-hardware hack */
+	console_set_baud(115200);
+#ifdef CONFIG_GDBSTUB
+	gdbstub_set_baud(115200);
+#endif
+
+#ifdef CONFIG_RESERVE_DMA_COHERENT
+	reserve_dma_coherent();
+#endif
+	dump_memory_map();
+
+#ifdef CONFIG_MB93090_MB00
+	if (mb93090_mb00_detected)
+		mb93090_display();
+#endif
+
+	/* register those serial ports that are available */
+#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)
+	/* we need to initialize the Flashrom device here since we might
+	 * do things with flash early on in the boot
+	 */
+	flash_probe();
+#endif
+
+	/* deal with the command line - RedBoot may have passed one to the kernel */
+	memcpy(command_line, saved_command_line, sizeof(command_line));
+	*cmdline_p = &command_line[0];
+	parse_cmdline_early(command_line);
+
+	/* set up the memory description
+	 * - by now the stack is part of the init task */
+	printk("Memory %08lx-%08lx\n", memory_start, memory_end);
+
+	if (memory_start == memory_end) BUG();
+
+	init_mm.start_code = (unsigned long) &_stext;
+	init_mm.end_code = (unsigned long) &_etext;
+	init_mm.end_data = (unsigned long) &_edata;
+#if 0 /* DAVIDM - don't set brk just incase someone decides to use it */
+	init_mm.brk = (unsigned long) &_end;
+#else
+	init_mm.brk = (unsigned long) 0;
+#endif
+
+#ifdef DEBUG
+	printk("KERNEL -> TEXT=0x%06x-0x%06x DATA=0x%06x-0x%06x BSS=0x%06x-0x%06x\n",
+	       (int) &_stext, (int) &_etext,
+	       (int) &_sdata, (int) &_edata,
+	       (int) &_sbss, (int) &_ebss);
+#endif
+
+#ifdef CONFIG_VT
+#if defined(CONFIG_VGA_CONSOLE)
+        conswitchp = &vga_con;
+#elif defined(CONFIG_DUMMY_CONSOLE)
+        conswitchp = &dummy_con;
+#endif
+#endif
+
+#ifdef CONFIG_BLK_DEV_BLKMEM
+	ROOT_DEV = MKDEV(BLKMEM_MAJOR,0);
+#endif
+	/*rom_length = (unsigned long)&_flashend - (unsigned long)&_romvec;*/
+
+#ifdef CONFIG_MMU
+	setup_linux_memory();
+#else
+	setup_uclinux_memory();
+#endif
+
+	/* get kmalloc into gear */
+	paging_init();
+
+	/* init DMA */
+	frv_dma_init();
+#ifdef DEBUG
+	printk("Done setup_arch\n");
+#endif
+
+	/* start the decrement timer running */
+//	asm volatile("movgs %0,timerd" :: "r"(10000000));
+//	__set_HSR(0, __get_HSR(0) | HSR0_ETMD);
+
+} /* end setup_arch() */
+
+#if 0
+/*****************************************************************************/
+/*
+ *
+ */
+static int __devinit setup_arch_serial(void)
+{
+	/* register those serial ports that are available */
+#ifndef CONFIG_GDBSTUB_UART0
+	early_serial_setup(&__frv_uart0);
+#endif
+#ifndef CONFIG_GDBSTUB_UART1
+	early_serial_setup(&__frv_uart1);
+#endif
+
+	return 0;
+} /* end setup_arch_serial() */
+
+late_initcall(setup_arch_serial);
+#endif
+
+/*****************************************************************************/
+/*
+ * set up the memory map for normal MMU linux
+ */
+#ifdef CONFIG_MMU
+static void __init setup_linux_memory(void)
+{
+	unsigned long bootmap_size, low_top_pfn, kstart, kend, high_mem;
+
+	kstart	= (unsigned long) &__kernel_image_start - PAGE_OFFSET;
+	kend	= (unsigned long) &__kernel_image_end - PAGE_OFFSET;
+
+	kstart = kstart & PAGE_MASK;
+	kend = (kend + PAGE_SIZE - 1) & PAGE_MASK;
+
+	/* give all the memory to the bootmap allocator,  tell it to put the
+	 * boot mem_map immediately following the kernel image
+	 */
+	bootmap_size = init_bootmem_node(NODE_DATA(0),
+					 kend >> PAGE_SHIFT,		/* map addr */
+					 memory_start >> PAGE_SHIFT,	/* start of RAM */
+					 memory_end >> PAGE_SHIFT	/* end of RAM */
+					 );
+
+	/* pass the memory that the kernel can immediately use over to the bootmem allocator */
+	max_mapnr = num_physpages = (memory_end - memory_start) >> PAGE_SHIFT;
+	low_top_pfn = (KERNEL_LOWMEM_END - KERNEL_LOWMEM_START) >> PAGE_SHIFT;
+	high_mem = 0;
+
+	if (num_physpages > low_top_pfn) {
+#ifdef CONFIG_HIGHMEM
+		high_mem = num_physpages - low_top_pfn;
+#else
+		max_mapnr = num_physpages = low_top_pfn;
+#endif
+	}
+	else {
+		low_top_pfn = num_physpages;
+	}
+
+	min_low_pfn = memory_start >> PAGE_SHIFT;
+	max_low_pfn = low_top_pfn;
+	max_pfn = memory_end >> PAGE_SHIFT;
+
+	num_mappedpages = low_top_pfn;
+
+	printk(KERN_NOTICE "%ldMB LOWMEM available.\n", low_top_pfn >> (20 - PAGE_SHIFT));
+
+	free_bootmem(memory_start, low_top_pfn << PAGE_SHIFT);
+
+#ifdef CONFIG_HIGHMEM
+	if (high_mem)
+		printk(KERN_NOTICE "%ldMB HIGHMEM available.\n", high_mem >> (20 - PAGE_SHIFT));
+#endif
+
+	/* take back the memory occupied by the kernel image and the bootmem alloc map */
+	reserve_bootmem(kstart, kend - kstart + bootmap_size);
+
+	/* reserve the memory occupied by the initial ramdisk */
+#ifdef CONFIG_BLK_DEV_INITRD
+	if (LOADER_TYPE && INITRD_START) {
+		if (INITRD_START + INITRD_SIZE <= (low_top_pfn << PAGE_SHIFT)) {
+			reserve_bootmem(INITRD_START, INITRD_SIZE);
+			initrd_start = INITRD_START ? INITRD_START + PAGE_OFFSET : 0;
+			initrd_end = initrd_start + INITRD_SIZE;
+		}
+		else {
+			printk(KERN_ERR
+			       "initrd extends beyond end of memory (0x%08lx > 0x%08lx)\n"
+			       "disabling initrd\n",
+			       INITRD_START + INITRD_SIZE,
+			       low_top_pfn << PAGE_SHIFT);
+			initrd_start = 0;
+		}
+	}
+#endif
+
+} /* end setup_linux_memory() */
+#endif
+
+/*****************************************************************************/
+/*
+ * set up the memory map for uClinux
+ */
+#ifndef CONFIG_MMU
+static void __init setup_uclinux_memory(void)
+{
+#ifdef CONFIG_PROTECT_KERNEL
+	unsigned long dampr;
+#endif
+	unsigned long kend;
+	int bootmap_size;
+
+	kend = (unsigned long) &__kernel_image_end;
+	kend = (kend + PAGE_SIZE - 1) & PAGE_MASK;
+
+	/* give all the memory to the bootmap allocator,  tell it to put the
+	 * boot mem_map immediately following the kernel image
+	 */
+	bootmap_size = init_bootmem_node(NODE_DATA(0),
+					 kend >> PAGE_SHIFT,		/* map addr */
+					 memory_start >> PAGE_SHIFT,	/* start of RAM */
+					 memory_end >> PAGE_SHIFT	/* end of RAM */
+					 );
+
+	/* free all the usable memory */
+	free_bootmem(memory_start, memory_end - memory_start);
+
+	high_memory = (void *) (memory_end & PAGE_MASK);
+	max_mapnr = num_physpages = ((unsigned long) high_memory - PAGE_OFFSET) >> PAGE_SHIFT;
+
+	min_low_pfn = memory_start >> PAGE_SHIFT;
+	max_low_pfn = memory_end >> PAGE_SHIFT;
+	max_pfn = max_low_pfn;
+
+	/* now take back the bits the core kernel is occupying */
+#ifndef CONFIG_PROTECT_KERNEL
+	reserve_bootmem(kend, bootmap_size);
+	reserve_bootmem((unsigned long) &__kernel_image_start,
+			kend - (unsigned long) &__kernel_image_start);
+
+#else
+	dampr = __get_DAMPR(0);
+	dampr &= xAMPRx_SS;
+	dampr = (dampr >> 4) + 17;
+	dampr = 1 << dampr;
+
+	reserve_bootmem(__get_DAMPR(0) & xAMPRx_PPFN, dampr);
+#endif
+
+	/* reserve some memory to do uncached DMA through if requested */
+#ifdef CONFIG_RESERVE_DMA_COHERENT
+	if (dma_coherent_mem_start)
+		reserve_bootmem(dma_coherent_mem_start,
+				dma_coherent_mem_end - dma_coherent_mem_start);
+#endif
+
+} /* end setup_uclinux_memory() */
+#endif
+
+/*****************************************************************************/
+/*
+ * get CPU information for use by procfs
+ */
+static int show_cpuinfo(struct seq_file *m, void *v)
+{
+	const char *gr, *fr, *fm, *fp, *cm, *nem, *ble;
+#ifdef CONFIG_PM
+	const char *sep;
+#endif
+
+	gr  = cpu_hsr0_all & HSR0_GRHE	? "gr0-63"	: "gr0-31";
+	fr  = cpu_hsr0_all & HSR0_FRHE	? "fr0-63"	: "fr0-31";
+	fm  = cpu_psr_all  & PSR_EM	? ", Media"	: "";
+	fp  = cpu_psr_all  & PSR_EF	? ", FPU"	: "";
+	cm  = cpu_psr_all  & PSR_CM	? ", CCCR"	: "";
+	nem = cpu_psr_all  & PSR_NEM	? ", NE"	: "";
+	ble = cpu_psr_all  & PSR_BE	? "BE"		: "LE";
+
+	seq_printf(m,
+		   "CPU-Series:\t%s\n"
+		   "CPU-Core:\t%s, %s, %s%s%s\n"
+		   "CPU:\t\t%s\n"
+		   "MMU:\t\t%s\n"
+		   "FP-Media:\t%s%s%s\n"
+		   "System:\t\t%s",
+		   cpu_series,
+		   cpu_core, gr, ble, cm, nem,
+		   cpu_silicon,
+		   cpu_mmu,
+		   fr, fm, fp,
+		   cpu_system);
+
+	if (cpu_board1)
+		seq_printf(m, ", %s", cpu_board1);
+
+	if (cpu_board2)
+		seq_printf(m, ", %s", cpu_board2);
+
+	seq_printf(m, "\n");
+
+#ifdef CONFIG_PM
+	seq_printf(m, "PM-Controls:");
+	sep = "\t";
+
+	if (clock_bits_settable & CLOCK_BIT_CMODE) {
+		seq_printf(m, "%scmode=0x%04hx", sep, clock_cmodes_permitted);
+		sep = ", ";
+	}
+
+	if (clock_bits_settable & CLOCK_BIT_CM) {
+		seq_printf(m, "%scm=0x%lx", sep, clock_bits_settable & CLOCK_BIT_CM);
+		sep = ", ";
+	}
+
+	if (clock_bits_settable & CLOCK_BIT_P0) {
+		seq_printf(m, "%sp0=0x3", sep);
+		sep = ", ";
+	}
+
+	seq_printf(m, "%ssuspend=0x22\n", sep);
+#endif
+
+	seq_printf(m,
+		   "PM-Status:\tcmode=%d, cm=%d, p0=%d\n",
+		   clock_cmode_current, clock_cm_current, clock_p0_current);
+
+#define print_clk(TAG, VAR) \
+	seq_printf(m, "Clock-" TAG ":\t%lu.%2.2lu MHz\n", VAR / 1000000, (VAR / 10000) % 100)
+
+	print_clk("In",    __clkin_clock_speed_HZ);
+	print_clk("Core",  __core_clock_speed_HZ);
+	print_clk("SDRAM", __sdram_clock_speed_HZ);
+	print_clk("CBus",  __core_bus_clock_speed_HZ);
+	print_clk("Res",   __res_bus_clock_speed_HZ);
+	print_clk("Ext",   __ext_bus_clock_speed_HZ);
+	print_clk("DSU",   __dsu_clock_speed_HZ);
+
+	seq_printf(m,
+		   "BogoMips:\t%lu.%02lu\n",
+		   (loops_per_jiffy * HZ) / 500000, ((loops_per_jiffy * HZ) / 5000) % 100);
+
+	return 0;
+} /* end show_cpuinfo() */
+
+static void *c_start(struct seq_file *m, loff_t *pos)
+{
+	return *pos < NR_CPUS ? (void *) 0x12345678 : NULL;
+}
+
+static void *c_next(struct seq_file *m, void *v, loff_t *pos)
+{
+	++*pos;
+	return c_start(m, pos);
+}
+
+static void c_stop(struct seq_file *m, void *v)
+{
+}
+
+struct seq_operations cpuinfo_op = {
+	.start	= c_start,
+	.next	= c_next,
+	.stop	= c_stop,
+	.show	= show_cpuinfo,
+};
+
+void arch_gettod(int *year, int *mon, int *day, int *hour,
+		 int *min, int *sec)
+{
+	*year = *mon = *day = *hour = *min = *sec = 0;
+}
+
+/*****************************************************************************/
+/*
+ *
+ */
+#ifdef CONFIG_MB93090_MB00
+static void __init mb93090_sendlcdcmd(uint32_t cmd)
+{
+	unsigned long base = __addr_LCD();
+	int loop;
+
+	/* request reading of the busy flag */
+	__set_LCD(base, LCD_CMD_READ_BUSY);
+	__set_LCD(base, LCD_CMD_READ_BUSY & ~LCD_E);
+
+	/* wait for the busy flag to become clear */
+	for (loop = 10000; loop > 0; loop--)
+		if (!(__get_LCD(base) & 0x80))
+			break;
+
+	/* send the command */
+	__set_LCD(base, cmd);
+	__set_LCD(base, cmd & ~LCD_E);
+
+} /* end mb93090_sendlcdcmd() */
+
+/*****************************************************************************/
+/*
+ * write to the MB93090 LEDs and LCD
+ */
+static void __init mb93090_display(void)
+{
+	const char *p;
+
+	__set_LEDS(0);
+
+	/* set up the LCD */
+	mb93090_sendlcdcmd(LCD_CMD_CLEAR);
+	mb93090_sendlcdcmd(LCD_CMD_FUNCSET(1,1,0));
+	mb93090_sendlcdcmd(LCD_CMD_ON(0,0));
+	mb93090_sendlcdcmd(LCD_CMD_HOME);
+
+	mb93090_sendlcdcmd(LCD_CMD_SET_DD_ADDR(0));
+	for (p = mb93090_banner; *p; p++)
+		mb93090_sendlcdcmd(LCD_DATA_WRITE(*p));
+
+	mb93090_sendlcdcmd(LCD_CMD_SET_DD_ADDR(64));
+	for (p = mb93090_version; *p; p++)
+		mb93090_sendlcdcmd(LCD_DATA_WRITE(*p));
+
+} /* end mb93090_display() */
+
+#endif // CONFIG_MB93090_MB00
diff -Nru a/arch/frv/kernel/signal.c b/arch/frv/kernel/signal.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/kernel/signal.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,589 @@
+/* signal.c: FRV specific bits of signal handling
+ *
+ * Copyright (C) 2003-5 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ * - Derived from arch/m68k/kernel/signal.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.
+ */
+
+#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/personality.h>
+#include <linux/suspend.h>
+#include <asm/ucontext.h>
+#include <asm/uaccess.h>
+#include <asm/cacheflush.h>
+
+#define DEBUG_SIG 0
+
+#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
+
+struct fdpic_func_descriptor {
+	unsigned long	text;
+	unsigned long	GOT;
+};
+
+asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset);
+
+/*
+ * Atomically swap in the new signal mask, and wait for a signal.
+ */
+asmlinkage int sys_sigsuspend(int history0, int history1, old_sigset_t mask)
+{
+	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);
+
+	__frame->gr8 = -EINTR;
+	while (1) {
+		current->state = TASK_INTERRUPTIBLE;
+		schedule();
+		if (do_signal(__frame, &saveset))
+			/* return the signal number as the return value of this function
+			 * - this is an utterly evil hack. syscalls should not invoke do_signal()
+			 *   as entry.S sets regs->gr8 to the return value of the system call
+			 * - we can't just use sigpending() as we'd have to discard SIG_IGN signals
+			 *   and call waitpid() if SIGCHLD needed discarding
+			 * - this only works on the i386 because it passes arguments to the signal
+			 *   handler on the stack, and the return value in EAX is effectively
+			 *   discarded
+			 */
+			return __frame->gr8;
+	}
+}
+
+asmlinkage int sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize)
+{
+	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);
+
+	__frame->gr8 = -EINTR;
+	while (1) {
+		current->state = TASK_INTERRUPTIBLE;
+		schedule();
+		if (do_signal(__frame, &saveset))
+			/* return the signal number as the return value of this function
+			 * - this is an utterly evil hack. syscalls should not invoke do_signal()
+			 *   as entry.S sets regs->gr8 to the return value of the system call
+			 * - we can't just use sigpending() as we'd have to discard SIG_IGN signals
+			 *   and call waitpid() if SIGCHLD needed discarding
+			 * - this only works on the i386 because it passes arguments to the signal
+			 *   handler on the stack, and the return value in EAX is effectively
+			 *   discarded
+			 */
+			return __frame->gr8;
+	}
+}
+
+asmlinkage int sys_sigaction(int sig,
+			     const struct old_sigaction __user *act,
+			     struct old_sigaction __user *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(const stack_t __user *uss, stack_t __user *uoss)
+{
+	return do_sigaltstack(uss, uoss, __frame->sp);
+}
+
+
+/*
+ * Do a signal return; undo the signal stack.
+ */
+
+struct sigframe
+{
+	void (*pretcode)(void);
+	int sig;
+	struct sigcontext sc;
+	unsigned long extramask[_NSIG_WORDS-1];
+	uint32_t retcode[2];
+};
+
+struct rt_sigframe
+{
+	void (*pretcode)(void);
+	int sig;
+	struct siginfo *pinfo;
+	void *puc;
+	struct siginfo info;
+	struct ucontext uc;
+	uint32_t retcode[2];
+};
+
+static int restore_sigcontext(struct sigcontext __user *sc, int *_gr8)
+{
+	struct user_context *user = current->thread.user;
+	unsigned long tbr, psr;
+
+	tbr = user->i.tbr;
+	psr = user->i.psr;
+	if (copy_from_user(user, &sc->sc_context, sizeof(sc->sc_context)))
+		goto badframe;
+	user->i.tbr = tbr;
+	user->i.psr = psr;
+
+	restore_user_regs(user);
+
+	user->i.syscallno = -1;		/* disable syscall checks */
+
+	*_gr8 = user->i.gr[8];
+	return 0;
+
+ badframe:
+	return 1;
+}
+
+asmlinkage int sys_sigreturn(void)
+{
+	struct sigframe __user *frame = (struct sigframe __user *) __frame->sp;
+	sigset_t set;
+	int gr8;
+
+	if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
+		goto badframe;
+	if (__get_user(set.sig[0], &frame->sc.sc_oldmask))
+		goto badframe;
+
+	if (_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(&frame->sc, &gr8))
+		goto badframe;
+	return gr8;
+
+ badframe:
+	force_sig(SIGSEGV, current);
+	return 0;
+}
+
+asmlinkage int sys_rt_sigreturn(void)
+{
+	struct rt_sigframe __user *frame = (struct rt_sigframe __user *) __frame->sp;
+	sigset_t set;
+	stack_t st;
+	int gr8;
+
+	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(&frame->uc.uc_mcontext, &gr8))
+		goto badframe;
+
+	if (do_sigaltstack(&frame->uc.uc_stack, NULL, __frame->sp) == -EFAULT)
+		goto badframe;
+
+	return gr8;
+
+badframe:
+	force_sig(SIGSEGV, current);
+	return 0;
+}
+
+/*
+ * Set up a signal frame
+ */
+static int setup_sigcontext(struct sigcontext __user *sc, unsigned long mask)
+{
+	save_user_regs(current->thread.user);
+
+	if (copy_to_user(&sc->sc_context, current->thread.user, sizeof(sc->sc_context)) != 0)
+		goto badframe;
+
+	/* non-iBCS2 extensions.. */
+	if (__put_user(mask, &sc->sc_oldmask) < 0)
+		goto badframe;
+
+	return 0;
+
+ badframe:
+	return 1;
+}
+
+/*****************************************************************************/
+/*
+ * Determine which stack to use..
+ */
+static inline void __user *get_sigframe(struct k_sigaction *ka,
+					struct pt_regs *regs,
+					size_t frame_size)
+{
+	unsigned long sp;
+
+	/* Default to using normal stack */
+	sp = regs->sp;
+
+	/* 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;
+	}
+
+	return (void __user *) ((sp - frame_size) & ~7UL);
+} /* end get_sigframe() */
+
+/*****************************************************************************/
+/*
+ *
+ */
+static void setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, struct pt_regs * regs)
+{
+	struct sigframe __user *frame;
+	int rsig;
+
+	frame = get_sigframe(ka, regs, sizeof(*frame));
+
+	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
+		goto give_sigsegv;
+
+	rsig = sig;
+	if (sig < 32 &&
+	    __current_thread_info->exec_domain &&
+	    __current_thread_info->exec_domain->signal_invmap)
+		rsig = __current_thread_info->exec_domain->signal_invmap[sig];
+
+	if (__put_user(rsig, &frame->sig) < 0)
+		goto give_sigsegv;
+
+	if (setup_sigcontext(&frame->sc, set->sig[0]))
+		goto give_sigsegv;
+
+	if (_NSIG_WORDS > 1) {
+		if (__copy_to_user(frame->extramask, &set->sig[1],
+				   sizeof(frame->extramask)))
+			goto give_sigsegv;
+	}
+
+	/* Set up to return from userspace.  If provided, use a stub
+	 * already in userspace.  */
+	if (ka->sa.sa_flags & SA_RESTORER) {
+		if (__put_user(ka->sa.sa_restorer, &frame->pretcode) < 0)
+			goto give_sigsegv;
+	}
+	else {
+		/* Set up the following code on the stack:
+		 *	setlos	#__NR_sigreturn,gr7
+		 *	tira	gr0,0
+		 */
+		if (__put_user((void (*)(void))frame->retcode, &frame->pretcode) ||
+		    __put_user(0x8efc0000|__NR_sigreturn, &frame->retcode[0]) ||
+		    __put_user(0xc0700000, &frame->retcode[1]))
+			goto give_sigsegv;
+
+		flush_icache_range((unsigned long) frame->retcode,
+				   (unsigned long) (frame->retcode + 2));
+	}
+
+	/* set up registers for signal handler */
+	regs->sp   = (unsigned long) frame;
+	regs->lr   = (unsigned long) &frame->retcode;
+	regs->gr8  = sig;
+
+	if (get_personality & FDPIC_FUNCPTRS) {
+		struct fdpic_func_descriptor __user *funcptr =
+			(struct fdpic_func_descriptor *) ka->sa.sa_handler;
+		__get_user(regs->pc, &funcptr->text);
+		__get_user(regs->gr15, &funcptr->GOT);
+	} else {
+		regs->pc   = (unsigned long) ka->sa.sa_handler;
+		regs->gr15 = 0;
+	}
+
+	set_fs(USER_DS);
+
+#if DEBUG_SIG
+	printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n",
+		sig, current->comm, current->pid, frame, regs->pc, frame->pretcode);
+#endif
+
+	return;
+
+give_sigsegv:
+	if (sig == SIGSEGV)
+		ka->sa.sa_handler = SIG_DFL;
+
+	force_sig(SIGSEGV, current);
+} /* end setup_frame() */
+
+/*****************************************************************************/
+/*
+ *
+ */
+static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
+			   sigset_t *set, struct pt_regs * regs)
+{
+	struct rt_sigframe __user *frame;
+	int rsig;
+
+	frame = get_sigframe(ka, regs, sizeof(*frame));
+
+	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
+		goto give_sigsegv;
+
+	rsig = sig;
+	if (sig < 32 &&
+	    __current_thread_info->exec_domain &&
+	    __current_thread_info->exec_domain->signal_invmap)
+		rsig = __current_thread_info->exec_domain->signal_invmap[sig];
+
+	if (__put_user(rsig,		&frame->sig) ||
+	    __put_user(&frame->info,	&frame->pinfo) ||
+	    __put_user(&frame->uc,	&frame->puc))
+		goto give_sigsegv;
+
+	if (copy_siginfo_to_user(&frame->info, info))
+		goto give_sigsegv;
+
+	/* Create the ucontext.  */
+	if (__put_user(0, &frame->uc.uc_flags) ||
+	    __put_user(0, &frame->uc.uc_link) ||
+	    __put_user((void*)current->sas_ss_sp, &frame->uc.uc_stack.ss_sp) ||
+	    __put_user(sas_ss_flags(regs->sp), &frame->uc.uc_stack.ss_flags) ||
+	    __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size))
+		goto give_sigsegv;
+
+	if (setup_sigcontext(&frame->uc.uc_mcontext, set->sig[0]))
+		goto give_sigsegv;
+
+	if (__copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)))
+		goto give_sigsegv;
+
+	/* Set up to return from userspace.  If provided, use a stub
+	 * already in userspace.  */
+	if (ka->sa.sa_flags & SA_RESTORER) {
+		if (__put_user(ka->sa.sa_restorer, &frame->pretcode))
+			goto give_sigsegv;
+	}
+	else {
+		/* Set up the following code on the stack:
+		 *	setlos	#__NR_sigreturn,gr7
+		 *	tira	gr0,0
+		 */
+		if (__put_user((void (*)(void))frame->retcode, &frame->pretcode) ||
+		    __put_user(0x8efc0000|__NR_rt_sigreturn, &frame->retcode[0]) ||
+		    __put_user(0xc0700000, &frame->retcode[1]))
+			goto give_sigsegv;
+
+		flush_icache_range((unsigned long) frame->retcode,
+				   (unsigned long) (frame->retcode + 2));
+	}
+
+	/* Set up registers for signal handler */
+	regs->sp  = (unsigned long) frame;
+	regs->lr   = (unsigned long) &frame->retcode;
+	regs->gr8 = sig;
+	regs->gr9 = (unsigned long) &frame->info;
+
+	if (get_personality & FDPIC_FUNCPTRS) {
+		struct fdpic_func_descriptor *funcptr =
+			(struct fdpic_func_descriptor __user *) ka->sa.sa_handler;
+		__get_user(regs->pc, &funcptr->text);
+		__get_user(regs->gr15, &funcptr->GOT);
+	} else {
+		regs->pc   = (unsigned long) ka->sa.sa_handler;
+		regs->gr15 = 0;
+	}
+
+	set_fs(USER_DS);
+
+#if DEBUG_SIG
+	printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n",
+		sig, current->comm, current->pid, frame, regs->pc, frame->pretcode);
+#endif
+
+	return;
+
+give_sigsegv:
+	if (sig == SIGSEGV)
+		ka->sa.sa_handler = SIG_DFL;
+	force_sig(SIGSEGV, current);
+
+} /* end setup_rt_frame() */
+
+/*****************************************************************************/
+/*
+ * OK, we're invoking a handler
+ */
+static void handle_signal(unsigned long sig, siginfo_t *info,
+			  struct k_sigaction *ka, sigset_t *oldset,
+			  struct pt_regs *regs)
+{
+	/* Are we from a system call? */
+	if (in_syscall(regs)) {
+		/* If so, check system call restarting.. */
+		switch (regs->gr8) {
+		case -ERESTART_RESTARTBLOCK:
+		case -ERESTARTNOHAND:
+			regs->gr8 = -EINTR;
+			break;
+
+		case -ERESTARTSYS:
+			if (!(ka->sa.sa_flags & SA_RESTART)) {
+				regs->gr8 = -EINTR;
+				break;
+			}
+			/* fallthrough */
+		case -ERESTARTNOINTR:
+			regs->gr8 = regs->orig_gr8;
+			regs->pc -= 4;
+		}
+	}
+
+	/* 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_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);
+	}
+} /* end handle_signal() */
+
+/*****************************************************************************/
+/*
+ * 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.
+ */
+int do_signal(struct pt_regs *regs, sigset_t *oldset)
+{
+	struct k_sigaction ka;
+	siginfo_t info;
+	int signr;
+
+	/*
+	 * We want the common case to go fast, which
+	 * is why we may in certain cases get here from
+	 * kernel mode. Just return without doing anything
+	 * if so.
+	 */
+	if (!user_mode(regs))
+		return 1;
+
+	if (current->flags & PF_FREEZE) {
+		refrigerator(0);
+		goto no_signal;
+	}
+
+	if (!oldset)
+		oldset = &current->blocked;
+
+	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
+	if (signr > 0) {
+		handle_signal(signr, &info, &ka, oldset, regs);
+		return 1;
+	}
+
+ no_signal:
+	/* Did we come from a system call? */
+	if (regs->syscallno >= 0) {
+		/* Restart the system call - no handlers present */
+		if (regs->gr8 == -ERESTARTNOHAND ||
+		    regs->gr8 == -ERESTARTSYS ||
+		    regs->gr8 == -ERESTARTNOINTR) {
+			regs->gr8 = regs->orig_gr8;
+			regs->pc -= 4;
+		}
+
+		if (regs->gr8 == -ERESTART_RESTARTBLOCK){
+			regs->gr8 = __NR_restart_syscall;
+			regs->pc -= 4;
+		}
+	}
+
+	return 0;
+} /* end do_signal() */
+
+/*****************************************************************************/
+/*
+ * notification of userspace execution resumption
+ * - triggered by current->work.notify_resume
+ */
+asmlinkage void do_notify_resume(__u32 thread_info_flags)
+{
+	/* pending single-step? */
+	if (thread_info_flags & _TIF_SINGLESTEP)
+		clear_thread_flag(TIF_SINGLESTEP);
+
+	/* deal with pending signal delivery */
+	if (thread_info_flags & _TIF_SIGPENDING)
+		do_signal(__frame, NULL);
+
+} /* end do_notify_resume() */
diff -Nru a/arch/frv/kernel/sleep.S b/arch/frv/kernel/sleep.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/kernel/sleep.S	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,374 @@
+/* sleep.S: power saving mode entry
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Woodhouse (dwmw2@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ */
+
+#include <linux/sys.h>
+#include <linux/config.h>
+#include <linux/linkage.h>
+#include <asm/setup.h>
+#include <asm/segment.h>
+#include <asm/page.h>
+#include <asm/ptrace.h>
+#include <asm/errno.h>
+#include <asm/cache.h>
+#include <asm/spr-regs.h>
+
+#define __addr_MASK	0xfeff9820	/* interrupt controller mask */
+
+#define __addr_FR55X_DRCN	0xfeff0218      /* Address of DRCN register */
+#define FR55X_DSTS_OFFSET	-4		/* Offset from DRCN to DSTS */
+#define FR55X_SDRAMC_DSTS_SSI	0x00000002	/* indicates that the SDRAM is in self-refresh mode */
+
+#define __addr_FR4XX_DRCN	0xfe000430      /* Address of DRCN register */
+#define FR4XX_DSTS_OFFSET	-8		/* Offset from DRCN to DSTS */
+#define FR4XX_SDRAMC_DSTS_SSI	0x00000001	/* indicates that the SDRAM is in self-refresh mode */
+
+#define SDRAMC_DRCN_SR	0x00000001	/* transition SDRAM into self-refresh mode */
+
+	.section	.bss
+	.balign		8
+	.globl		__sleep_save_area
+__sleep_save_area:
+	.space		16
+
+
+	.text
+	.balign		4
+
+.macro li v r
+	sethi.p		%hi(\v),\r
+	setlo		%lo(\v),\r
+.endm
+
+#ifdef CONFIG_PM
+###############################################################################
+#
+# CPU suspension routine
+# - void frv_cpu_suspend(unsigned long pdm_mode)
+#
+###############################################################################
+	.globl		frv_cpu_suspend
+        .type		frv_cpu_suspend,@function
+frv_cpu_suspend:
+
+	#----------------------------------------------------
+	# save hsr0, psr, isr, and lr for resume code
+	#----------------------------------------------------
+	li		__sleep_save_area,gr11
+
+	movsg		hsr0,gr4
+	movsg		psr,gr5
+	movsg		isr,gr6
+	movsg		lr,gr7
+	stdi		gr4,@(gr11,#0)
+	stdi		gr6,@(gr11,#8)
+
+	# store the return address from sleep in GR14, and its complement in GR13 as a check
+	li		__ramboot_resume,gr14
+#ifdef CONFIG_MMU
+	# Resume via RAMBOOT# will turn MMU off, so bootloader needs a physical address.
+	sethi.p		%hi(__page_offset),gr13
+	setlo		%lo(__page_offset),gr13
+	sub		gr14,gr13,gr14
+#endif
+	not		gr14,gr13
+
+	#----------------------------------------------------
+	# preload and lock into icache that code which may have to run
+	# when dram is in self-refresh state.
+	#----------------------------------------------------
+	movsg		hsr0, gr3
+	li		HSR0_ICE,gr4
+	or		gr3,gr4,gr3
+	movgs		gr3,hsr0
+	or		gr3,gr8,gr7	// add the sleep bits for later
+
+	li		#__icache_lock_start,gr3
+	li		#__icache_lock_end,gr4
+1:	icpl		gr3,gr0,#1
+	addi		gr3,#L1_CACHE_BYTES,gr3
+	cmp		gr4,gr3,icc0
+	bhi		icc0,#0,1b
+
+	# disable exceptions
+	movsg		psr,gr8
+	andi.p		gr8,#~PSR_PIL,gr8
+	andi		gr8,~PSR_ET,gr8
+	movgs		gr8,psr
+	ori		gr8,#PSR_ET,gr8
+
+	srli		gr8,#28,gr4
+	subicc		gr4,#3,gr0,icc0
+	beq		icc0,#0,1f
+	# FR4xx
+	li		__addr_FR4XX_DRCN,gr4
+	li		FR4XX_SDRAMC_DSTS_SSI,gr5
+	li		FR4XX_DSTS_OFFSET,gr6
+	bra		__icache_lock_start
+1:
+	# FR5xx
+	li		__addr_FR55X_DRCN,gr4
+	li		FR55X_SDRAMC_DSTS_SSI,gr5
+	li		FR55X_DSTS_OFFSET,gr6
+	bra		__icache_lock_start
+
+	.size		frv_cpu_suspend, .-frv_cpu_suspend
+
+#
+# the final part of the sleep sequence...
+# - we want it to be be cacheline aligned so we can lock it into the icache easily
+#  On entry:	gr7 holds desired hsr0 sleep value
+#               gr8 holds desired psr sleep value
+#
+	.balign		L1_CACHE_BYTES
+        .type		__icache_lock_start,@function
+__icache_lock_start:
+
+	#----------------------------------------------------
+	# put SDRAM in self-refresh mode
+	#----------------------------------------------------
+
+	# Flush all data in the cache using the DCEF instruction.
+	dcef		@(gr0,gr0),#1
+
+	# Stop DMAC transfer
+
+	# Execute dummy load from SDRAM
+	ldi		@(gr11,#0),gr11
+
+	# put the SDRAM into self-refresh mode
+	ld              @(gr4,gr0),gr11
+	ori		gr11,#SDRAMC_DRCN_SR,gr11
+	st		gr11,@(gr4,gr0)
+	membar
+
+	# wait for SDRAM to reach self-refresh mode
+1:	ld		@(gr4,gr6),gr11
+	andcc		gr11,gr5,gr11,icc0
+	beq		icc0,#0,1b
+
+	#  Set the GPIO register so that the IRQ[3:0] pins become valid, as required.
+	#  Set the clock mode (CLKC register) as required.
+	#     - At this time, also set the CLKC register P0 bit.
+
+	# Set the HSR0 register PDM field.
+	movgs		gr7,hsr0
+
+	# Execute NOP 32 times.
+	.rept		32
+	nop
+	.endr
+
+#if 0 // Fujitsu recommend to skip this and will update docs.
+	#      Release the interrupt mask setting of the MASK register of the
+	#      interrupt controller if necessary.
+	sti		gr10,@(gr9,#0)
+	membar
+#endif
+
+	# Set the PSR register ET bit to 1 to enable interrupts.
+	movgs		gr8,psr
+
+	###################################################
+	# this is only reached if waking up via interrupt
+	###################################################
+
+	# Execute NOP 32 times.
+	.rept		32
+	nop
+	.endr
+
+	#----------------------------------------------------
+	# wake SDRAM from self-refresh mode
+	#----------------------------------------------------
+	ld              @(gr4,gr0),gr11
+	andi		gr11,#~SDRAMC_DRCN_SR,gr11
+	st		gr11,@(gr4,gr0)
+	membar
+2:
+	ld		@(gr4,gr6),gr11	// Wait for it to come back...
+	andcc		gr11,gr5,gr0,icc0
+	bne		icc0,0,2b
+
+	# wait for the SDRAM to stabilise
+	li		0x0100000,gr3
+3:	subicc		gr3,#1,gr3,icc0
+	bne		icc0,#0,3b
+
+	# now that DRAM is back, this is the end of the code which gets
+	# locked in icache.
+__icache_lock_end:
+	.size		__icache_lock_start, .-__icache_lock_start
+
+	# Fall-through to the RAMBOOT# wakeup path
+
+###############################################################################
+#
+#  resume from suspend re-entry point reached via RAMBOOT# and bootloader
+#
+###############################################################################
+__ramboot_resume:
+
+	#----------------------------------------------------
+	# restore hsr0, psr, isr, and leave saved lr in gr7
+	#----------------------------------------------------
+	li		__sleep_save_area,gr11
+#ifdef CONFIG_MMU
+	movsg		hsr0,gr4
+	sethi.p		%hi(HSR0_EXMMU),gr3
+	setlo		%lo(HSR0_EXMMU),gr3
+	andcc		gr3,gr4,gr0,icc0
+	bne		icc0,#0,2f
+
+	# need to use physical address
+	sethi.p		%hi(__page_offset),gr3
+	setlo		%lo(__page_offset),gr3
+	sub		gr11,gr3,gr11
+
+	# flush all tlb entries
+	setlos		#64,gr4
+	setlos.p	#PAGE_SIZE,gr5
+	setlos		#0,gr6
+1:
+	tlbpr		gr6,gr0,#6,#0
+	subicc.p	gr4,#1,gr4,icc0
+	add		gr6,gr5,gr6
+	bne		icc0,#2,1b
+
+	# need a temporary mapping for the current physical address we are
+	# using between time MMU is enabled and jump to virtual address is
+	# made.
+	sethi.p		%hi(0x00000000),gr4
+	setlo		%lo(0x00000000),gr4		; physical address
+	setlos		#xAMPRx_L|xAMPRx_M|xAMPRx_SS_256Mb|xAMPRx_S_KERNEL|xAMPRx_V,gr5
+	or		gr4,gr5,gr5
+
+	movsg		cxnr,gr13
+	or		gr4,gr13,gr4
+
+	movgs		gr4,iamlr1			; mapped from real address 0
+	movgs		gr5,iampr1			; cached kernel memory at 0x00000000
+2:
+#endif
+
+	lddi		@(gr11,#0),gr4 ; hsr0, psr
+	lddi		@(gr11,#8),gr6 ; isr, lr
+	movgs		gr4,hsr0
+	bar
+
+#ifdef CONFIG_MMU
+	sethi.p		%hi(1f),gr11
+	setlo		%lo(1f),gr11
+	jmpl		@(gr11,gr0)
+1:
+	movgs		gr0,iampr1 	; get rid of temporary mapping
+#endif
+	movgs		gr5,psr
+	movgs		gr6,isr
+
+	#----------------------------------------------------
+	# unlock the icache which was locked before going to sleep
+	#----------------------------------------------------
+	li		__icache_lock_start,gr3
+	li		__icache_lock_end,gr4
+1:	icul		gr3
+	addi		gr3,#L1_CACHE_BYTES,gr3
+	cmp		gr4,gr3,icc0
+	bhi		icc0,#0,1b
+
+	#----------------------------------------------------
+	# back to business as usual
+	#----------------------------------------------------
+	jmpl		@(gr7,gr0)		;
+
+#endif /* CONFIG_PM */
+
+###############################################################################
+#
+# CPU core sleep mode routine
+#
+###############################################################################
+	.globl		frv_cpu_core_sleep
+        .type		frv_cpu_core_sleep,@function
+frv_cpu_core_sleep:
+
+	# Preload into icache.
+	li		#__core_sleep_icache_lock_start,gr3
+	li		#__core_sleep_icache_lock_end,gr4
+
+1:	icpl		gr3,gr0,#1
+	addi		gr3,#L1_CACHE_BYTES,gr3
+	cmp		gr4,gr3,icc0
+	bhi		icc0,#0,1b
+
+	bra	__core_sleep_icache_lock_start
+
+	.balign L1_CACHE_BYTES
+__core_sleep_icache_lock_start:
+
+	# (1) Set the PSR register ET bit to 0 to disable interrupts.
+	movsg		psr,gr8
+	andi.p		gr8,#~(PSR_PIL),gr8
+	andi		gr8,#~(PSR_ET),gr4
+	movgs		gr4,psr
+
+#if 0 // Fujitsu recommend to skip this and will update docs.
+	# (2) Set '1' to all bits in the MASK register of the interrupt
+	#     controller and mask interrupts.
+	sethi.p		%hi(__addr_MASK),gr9
+	setlo		%lo(__addr_MASK),gr9
+	sethi.p		%hi(0xffff0000),gr4
+	setlo		%lo(0xffff0000),gr4
+	ldi		@(gr9,#0),gr10
+	sti		gr4,@(gr9,#0)
+#endif
+	# (3) Flush all data in the cache using the DCEF instruction.
+	dcef		@(gr0,gr0),#1
+
+	# (4) Execute the memory barrier instruction
+	membar
+
+	# (5) Set the GPIO register so that the IRQ[3:0] pins become valid, as required.
+	# (6) Set the clock mode (CLKC register) as required.
+	#     - At this time, also set the CLKC register P0 bit.
+	# (7) Set the HSR0 register PDM field to  001 .
+	movsg		hsr0,gr4
+	ori		gr4,HSR0_PDM_CORE_SLEEP,gr4
+	movgs		gr4,hsr0
+
+	# (8) Execute NOP 32 times.
+	.rept		32
+	nop
+	.endr
+
+#if 0 // Fujitsu recommend to skip this and will update docs.
+	# (9) Release the interrupt mask setting of the MASK register of the
+	#     interrupt controller if necessary.
+	sti		gr10,@(gr9,#0)
+	membar
+#endif
+
+	# (10) Set the PSR register ET bit to 1 to enable interrupts.
+	movgs		gr8,psr
+
+__core_sleep_icache_lock_end:
+
+	# Unlock from icache
+	li	__core_sleep_icache_lock_start,gr3
+	li	__core_sleep_icache_lock_end,gr4
+1:	icul		gr3
+	addi		gr3,#L1_CACHE_BYTES,gr3
+	cmp		gr4,gr3,icc0
+	bhi		icc0,#0,1b
+
+	bralr
+
+	.size		frv_cpu_core_sleep, .-frv_cpu_core_sleep
diff -Nru a/arch/frv/kernel/switch_to.S b/arch/frv/kernel/switch_to.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/kernel/switch_to.S	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,496 @@
+###############################################################################
+#
+# switch_to.S: context switch operation
+#
+# Copyright (C) 2003 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/config.h>
+#include <linux/linkage.h>
+#include <asm/thread_info.h>
+#include <asm/processor.h>
+#include <asm/registers.h>
+#include <asm/spr-regs.h>
+
+.macro LEDS val
+	setlos		#~\val,gr27
+	st		gr27,@(gr30,gr0)
+	membar
+	dcf		@(gr30,gr0)
+.endm
+
+	.section	.sdata
+	.balign		8
+
+	# address of frame 0 (userspace) on current kernel stack
+	.globl		__kernel_frame0_ptr
+__kernel_frame0_ptr:
+	.long		init_thread_union + THREAD_SIZE - USER_CONTEXT_SIZE
+
+	# address of current task
+	.globl		__kernel_current_task
+__kernel_current_task:
+	.long		init_task
+
+	.section	.text
+	.balign		4
+
+###############################################################################
+#
+# struct task_struct *__switch_to(struct thread_struct *prev_thread,
+#				  struct thread_struct *next_thread,
+#				  struct task_struct *prev)
+#
+###############################################################################
+	.globl		__switch_to
+__switch_to:
+	# save outgoing process's context
+	sethi.p		%hi(__switch_back),gr13
+	setlo		%lo(__switch_back),gr13
+	movsg		lr,gr12
+
+	stdi		gr28,@(gr8,#__THREAD_FRAME)
+	sti		sp  ,@(gr8,#__THREAD_SP)
+	sti		fp  ,@(gr8,#__THREAD_FP)
+	stdi		gr12,@(gr8,#__THREAD_LR)
+	stdi		gr16,@(gr8,#__THREAD_GR(16))
+	stdi		gr18,@(gr8,#__THREAD_GR(18))
+	stdi		gr20,@(gr8,#__THREAD_GR(20))
+	stdi		gr22,@(gr8,#__THREAD_GR(22))
+	stdi		gr24,@(gr8,#__THREAD_GR(24))
+	stdi.p		gr26,@(gr8,#__THREAD_GR(26))
+
+	or		gr8,gr8,gr22
+	ldi.p		@(gr8,#__THREAD_USER),gr8
+	call		save_user_regs
+	or		gr22,gr22,gr8
+	
+	# retrieve the new context
+	sethi.p		%hi(__kernel_frame0_ptr),gr6
+	setlo		%lo(__kernel_frame0_ptr),gr6
+	movsg		psr,gr4
+
+	lddi.p		@(gr9,#__THREAD_FRAME),gr10
+	or		gr10,gr10,gr27		; save prev for the return value
+
+	ldi		@(gr11,#4),gr19		; get new_current->thread_info
+
+	lddi		@(gr9,#__THREAD_SP),gr12
+	ldi		@(gr9,#__THREAD_LR),gr14
+	ldi		@(gr9,#__THREAD_PC),gr18
+	ldi.p		@(gr9,#__THREAD_FRAME0),gr7
+
+	# actually switch kernel contexts with ordinary exceptions disabled
+	andi		gr4,#~PSR_ET,gr5
+	movgs		gr5,psr
+
+	or.p		gr10,gr0,gr28		; set __frame
+	or		gr11,gr0,gr29		; set __current
+	or.p		gr12,gr0,sp
+	or		gr13,gr0,fp
+	or		gr19,gr0,gr15		; set __current_thread_info
+
+	sti		gr7,@(gr6,#0)		; set __kernel_frame0_ptr
+	sti		gr29,@(gr6,#4)		; set __kernel_current_task
+
+	movgs		gr14,lr
+	bar
+
+	srli		gr15,#28,gr5
+	subicc		gr5,#0xc,gr0,icc0
+	beq		icc0,#0,111f
+	break
+	nop
+111:
+
+	# jump to __switch_back or ret_from_fork as appropriate
+	# - move prev to GR8
+	movgs		gr4,psr
+	jmpl.p		@(gr18,gr0)
+	or		gr27,gr27,gr8
+
+###############################################################################
+#
+# restore incoming process's context
+# - on entry:
+#   - SP, FP, LR, GR15, GR28 and GR29 will have been set up appropriately
+#   - GR8 will point to the outgoing task_struct
+#   - GR9 will point to the incoming thread_struct
+#
+###############################################################################
+__switch_back:
+	lddi		@(gr9,#__THREAD_GR(16)),gr16
+	lddi		@(gr9,#__THREAD_GR(18)),gr18
+	lddi		@(gr9,#__THREAD_GR(20)),gr20
+	lddi		@(gr9,#__THREAD_GR(22)),gr22
+	lddi		@(gr9,#__THREAD_GR(24)),gr24
+	lddi		@(gr9,#__THREAD_GR(26)),gr26
+
+	# fall through into restore_user_regs()
+	ldi.p		@(gr9,#__THREAD_USER),gr8
+	or		gr8,gr8,gr9
+
+###############################################################################
+#
+# restore extra general regs and FP/Media regs
+# - void *restore_user_regs(const struct user_context *target, void *retval)
+# - on entry:
+#   - GR8 will point to the user context to swap in
+#   - GR9 will contain the value to be returned in GR8 (prev task on context switch)
+#
+###############################################################################
+	.globl		restore_user_regs
+restore_user_regs:
+	movsg		hsr0,gr6
+	ori		gr6,#HSR0_GRHE|HSR0_FRLE|HSR0_FRHE,gr6
+	movgs		gr6,hsr0
+	movsg		hsr0,gr6
+
+	movsg		psr,gr7
+	ori		gr7,#PSR_EF|PSR_EM,gr7
+	movgs		gr7,psr
+	movsg		psr,gr7
+	srli		gr7,#24,gr7
+	bar
+
+	lddi		@(gr8,#__FPMEDIA_MSR(0)),gr4
+
+	movgs		gr4,msr0
+	movgs		gr5,msr1
+
+	lddfi		@(gr8,#__FPMEDIA_ACC(0)),fr16
+	lddfi		@(gr8,#__FPMEDIA_ACC(2)),fr18
+	ldbfi		@(gr8,#__FPMEDIA_ACCG(0)),fr20
+	ldbfi		@(gr8,#__FPMEDIA_ACCG(1)),fr21
+	ldbfi		@(gr8,#__FPMEDIA_ACCG(2)),fr22
+	ldbfi		@(gr8,#__FPMEDIA_ACCG(3)),fr23
+
+	mwtacc		fr16,acc0
+	mwtacc		fr17,acc1
+	mwtacc		fr18,acc2
+	mwtacc		fr19,acc3
+	mwtaccg		fr20,accg0
+	mwtaccg		fr21,accg1
+	mwtaccg		fr22,accg2
+	mwtaccg		fr23,accg3
+
+	# some CPUs have extra ACCx and ACCGx regs and maybe FSRx regs
+	subicc.p	gr7,#0x50,gr0,icc0
+	subicc		gr7,#0x31,gr0,icc1
+	beq		icc0,#0,__restore_acc_fr451
+	beq		icc1,#0,__restore_acc_fr555
+__restore_acc_cont:
+
+	# some CPU's have GR32-GR63
+	setlos		#HSR0_FRHE,gr4
+	andcc		gr6,gr4,gr0,icc0
+	beq		icc0,#1,__restore_skip_gr32_gr63
+
+	lddi		@(gr8,#__INT_GR(32)),gr32
+	lddi		@(gr8,#__INT_GR(34)),gr34
+	lddi		@(gr8,#__INT_GR(36)),gr36
+	lddi		@(gr8,#__INT_GR(38)),gr38
+	lddi		@(gr8,#__INT_GR(40)),gr40
+	lddi		@(gr8,#__INT_GR(42)),gr42
+	lddi		@(gr8,#__INT_GR(44)),gr44
+	lddi		@(gr8,#__INT_GR(46)),gr46
+	lddi		@(gr8,#__INT_GR(48)),gr48
+	lddi		@(gr8,#__INT_GR(50)),gr50
+	lddi		@(gr8,#__INT_GR(52)),gr52
+	lddi		@(gr8,#__INT_GR(54)),gr54
+	lddi		@(gr8,#__INT_GR(56)),gr56
+	lddi		@(gr8,#__INT_GR(58)),gr58
+	lddi		@(gr8,#__INT_GR(60)),gr60
+	lddi		@(gr8,#__INT_GR(62)),gr62
+__restore_skip_gr32_gr63:
+
+	# all CPU's have FR0-FR31
+	lddfi		@(gr8,#__FPMEDIA_FR( 0)),fr0
+	lddfi		@(gr8,#__FPMEDIA_FR( 2)),fr2
+	lddfi		@(gr8,#__FPMEDIA_FR( 4)),fr4
+	lddfi		@(gr8,#__FPMEDIA_FR( 6)),fr6
+	lddfi		@(gr8,#__FPMEDIA_FR( 8)),fr8
+	lddfi		@(gr8,#__FPMEDIA_FR(10)),fr10
+	lddfi		@(gr8,#__FPMEDIA_FR(12)),fr12
+	lddfi		@(gr8,#__FPMEDIA_FR(14)),fr14
+	lddfi		@(gr8,#__FPMEDIA_FR(16)),fr16
+	lddfi		@(gr8,#__FPMEDIA_FR(18)),fr18
+	lddfi		@(gr8,#__FPMEDIA_FR(20)),fr20
+	lddfi		@(gr8,#__FPMEDIA_FR(22)),fr22
+	lddfi		@(gr8,#__FPMEDIA_FR(24)),fr24
+	lddfi		@(gr8,#__FPMEDIA_FR(26)),fr26
+	lddfi		@(gr8,#__FPMEDIA_FR(28)),fr28
+	lddfi.p		@(gr8,#__FPMEDIA_FR(30)),fr30
+
+	# some CPU's have FR32-FR63
+	setlos		#HSR0_FRHE,gr4
+	andcc		gr6,gr4,gr0,icc0
+	beq		icc0,#1,__restore_skip_fr32_fr63
+
+	lddfi		@(gr8,#__FPMEDIA_FR(32)),fr32
+	lddfi		@(gr8,#__FPMEDIA_FR(34)),fr34
+	lddfi		@(gr8,#__FPMEDIA_FR(36)),fr36
+	lddfi		@(gr8,#__FPMEDIA_FR(38)),fr38
+	lddfi		@(gr8,#__FPMEDIA_FR(40)),fr40
+	lddfi		@(gr8,#__FPMEDIA_FR(42)),fr42
+	lddfi		@(gr8,#__FPMEDIA_FR(44)),fr44
+	lddfi		@(gr8,#__FPMEDIA_FR(46)),fr46
+	lddfi		@(gr8,#__FPMEDIA_FR(48)),fr48
+	lddfi		@(gr8,#__FPMEDIA_FR(50)),fr50
+	lddfi		@(gr8,#__FPMEDIA_FR(52)),fr52
+	lddfi		@(gr8,#__FPMEDIA_FR(54)),fr54
+	lddfi		@(gr8,#__FPMEDIA_FR(56)),fr56
+	lddfi		@(gr8,#__FPMEDIA_FR(58)),fr58
+	lddfi		@(gr8,#__FPMEDIA_FR(60)),fr60
+	lddfi		@(gr8,#__FPMEDIA_FR(62)),fr62
+__restore_skip_fr32_fr63:
+
+	lddi		@(gr8,#__FPMEDIA_FNER(0)),gr4
+	movsg		fner0,gr4
+	movsg		fner1,gr5
+	or.p		gr9,gr9,gr8
+	bralr
+
+	# the FR451 also has ACC8-11/ACCG8-11 regs (but not 4-7...)
+__restore_acc_fr451:
+	lddfi		@(gr8,#__FPMEDIA_ACC(4)),fr16
+	lddfi		@(gr8,#__FPMEDIA_ACC(6)),fr18
+	ldbfi		@(gr8,#__FPMEDIA_ACCG(4)),fr20
+	ldbfi		@(gr8,#__FPMEDIA_ACCG(5)),fr21
+	ldbfi		@(gr8,#__FPMEDIA_ACCG(6)),fr22
+	ldbfi		@(gr8,#__FPMEDIA_ACCG(7)),fr23
+
+	mwtacc		fr16,acc8
+	mwtacc		fr17,acc9
+	mwtacc		fr18,acc10
+	mwtacc		fr19,acc11
+	mwtaccg		fr20,accg8
+	mwtaccg		fr21,accg9
+	mwtaccg		fr22,accg10
+	mwtaccg		fr23,accg11
+	bra		__restore_acc_cont
+
+	# the FR555 also has ACC4-7/ACCG4-7 regs and an FSR0 reg
+__restore_acc_fr555:
+	lddfi		@(gr8,#__FPMEDIA_ACC(4)),fr16
+	lddfi		@(gr8,#__FPMEDIA_ACC(6)),fr18
+	ldbfi		@(gr8,#__FPMEDIA_ACCG(4)),fr20
+	ldbfi		@(gr8,#__FPMEDIA_ACCG(5)),fr21
+	ldbfi		@(gr8,#__FPMEDIA_ACCG(6)),fr22
+	ldbfi		@(gr8,#__FPMEDIA_ACCG(7)),fr23
+
+	mnop.p
+	mwtacc		fr16,acc4
+	mnop.p
+	mwtacc		fr17,acc5
+	mnop.p
+	mwtacc		fr18,acc6
+	mnop.p
+	mwtacc		fr19,acc7
+	mnop.p
+	mwtaccg		fr20,accg4
+	mnop.p
+	mwtaccg		fr21,accg5
+	mnop.p
+	mwtaccg		fr22,accg6
+	mnop.p
+	mwtaccg		fr23,accg7
+
+	ldi		@(gr8,#__FPMEDIA_FSR(0)),gr4
+	movgs		gr4,fsr0
+
+	bra		__restore_acc_cont
+
+
+###############################################################################
+#
+# save extra general regs and FP/Media regs
+# - void save_user_regs(struct user_context *target)
+#
+###############################################################################
+	.globl		save_user_regs
+save_user_regs:
+	movsg		hsr0,gr6
+	ori		gr6,#HSR0_GRHE|HSR0_FRLE|HSR0_FRHE,gr6
+	movgs		gr6,hsr0
+	movsg		hsr0,gr6
+
+	movsg		psr,gr7
+	ori		gr7,#PSR_EF|PSR_EM,gr7
+	movgs		gr7,psr
+	movsg		psr,gr7
+	srli		gr7,#24,gr7
+	bar
+
+	movsg		fner0,gr4
+	movsg		fner1,gr5
+	stdi.p		gr4,@(gr8,#__FPMEDIA_FNER(0))
+
+	# some CPU's have GR32-GR63
+	setlos		#HSR0_GRHE,gr4
+	andcc		gr6,gr4,gr0,icc0
+	beq		icc0,#1,__save_skip_gr32_gr63
+
+	stdi		gr32,@(gr8,#__INT_GR(32))
+	stdi		gr34,@(gr8,#__INT_GR(34))
+	stdi		gr36,@(gr8,#__INT_GR(36))
+	stdi		gr38,@(gr8,#__INT_GR(38))
+	stdi		gr40,@(gr8,#__INT_GR(40))
+	stdi		gr42,@(gr8,#__INT_GR(42))
+	stdi		gr44,@(gr8,#__INT_GR(44))
+	stdi		gr46,@(gr8,#__INT_GR(46))
+	stdi		gr48,@(gr8,#__INT_GR(48))
+	stdi		gr50,@(gr8,#__INT_GR(50))
+	stdi		gr52,@(gr8,#__INT_GR(52))
+	stdi		gr54,@(gr8,#__INT_GR(54))
+	stdi		gr56,@(gr8,#__INT_GR(56))
+	stdi		gr58,@(gr8,#__INT_GR(58))
+	stdi		gr60,@(gr8,#__INT_GR(60))
+	stdi		gr62,@(gr8,#__INT_GR(62))
+__save_skip_gr32_gr63:
+
+	# all CPU's have FR0-FR31
+	stdfi		fr0 ,@(gr8,#__FPMEDIA_FR( 0))
+	stdfi		fr2 ,@(gr8,#__FPMEDIA_FR( 2))
+	stdfi		fr4 ,@(gr8,#__FPMEDIA_FR( 4))
+	stdfi		fr6 ,@(gr8,#__FPMEDIA_FR( 6))
+	stdfi		fr8 ,@(gr8,#__FPMEDIA_FR( 8))
+	stdfi		fr10,@(gr8,#__FPMEDIA_FR(10))
+	stdfi		fr12,@(gr8,#__FPMEDIA_FR(12))
+	stdfi		fr14,@(gr8,#__FPMEDIA_FR(14))
+	stdfi		fr16,@(gr8,#__FPMEDIA_FR(16))
+	stdfi		fr18,@(gr8,#__FPMEDIA_FR(18))
+	stdfi		fr20,@(gr8,#__FPMEDIA_FR(20))
+	stdfi		fr22,@(gr8,#__FPMEDIA_FR(22))
+	stdfi		fr24,@(gr8,#__FPMEDIA_FR(24))
+	stdfi		fr26,@(gr8,#__FPMEDIA_FR(26))
+	stdfi		fr28,@(gr8,#__FPMEDIA_FR(28))
+	stdfi.p		fr30,@(gr8,#__FPMEDIA_FR(30))
+
+	# some CPU's have FR32-FR63
+	setlos		#HSR0_FRHE,gr4
+	andcc		gr6,gr4,gr0,icc0
+	beq		icc0,#1,__save_skip_fr32_fr63
+
+	stdfi		fr32,@(gr8,#__FPMEDIA_FR(32))
+	stdfi		fr34,@(gr8,#__FPMEDIA_FR(34))
+	stdfi		fr36,@(gr8,#__FPMEDIA_FR(36))
+	stdfi		fr38,@(gr8,#__FPMEDIA_FR(38))
+	stdfi		fr40,@(gr8,#__FPMEDIA_FR(40))
+	stdfi		fr42,@(gr8,#__FPMEDIA_FR(42))
+	stdfi		fr44,@(gr8,#__FPMEDIA_FR(44))
+	stdfi		fr46,@(gr8,#__FPMEDIA_FR(46))
+	stdfi		fr48,@(gr8,#__FPMEDIA_FR(48))
+	stdfi		fr50,@(gr8,#__FPMEDIA_FR(50))
+	stdfi		fr52,@(gr8,#__FPMEDIA_FR(52))
+	stdfi		fr54,@(gr8,#__FPMEDIA_FR(54))
+	stdfi		fr56,@(gr8,#__FPMEDIA_FR(56))
+	stdfi		fr58,@(gr8,#__FPMEDIA_FR(58))
+	stdfi		fr60,@(gr8,#__FPMEDIA_FR(60))
+	stdfi		fr62,@(gr8,#__FPMEDIA_FR(62))
+__save_skip_fr32_fr63:
+
+	mrdacc		acc0 ,fr4
+	mrdacc		acc1 ,fr5
+
+	stdfi.p		fr4 ,@(gr8,#__FPMEDIA_ACC(0))
+
+	mrdacc		acc2 ,fr6
+	mrdacc		acc3 ,fr7
+
+	stdfi.p		fr6 ,@(gr8,#__FPMEDIA_ACC(2))
+
+	mrdaccg		accg0,fr4
+	stbfi.p		fr4 ,@(gr8,#__FPMEDIA_ACCG(0))
+
+	mrdaccg		accg1,fr5
+	stbfi.p		fr5 ,@(gr8,#__FPMEDIA_ACCG(1))
+
+	mrdaccg		accg2,fr6
+	stbfi.p		fr6 ,@(gr8,#__FPMEDIA_ACCG(2))
+
+	mrdaccg		accg3,fr7
+	stbfi		fr7 ,@(gr8,#__FPMEDIA_ACCG(3))
+
+	movsg		msr0 ,gr4
+	movsg		msr1 ,gr5
+
+	stdi		gr4 ,@(gr8,#__FPMEDIA_MSR(0))
+
+	# some CPUs have extra ACCx and ACCGx regs and maybe FSRx regs
+	subicc.p	gr7,#0x50,gr0,icc0
+	subicc		gr7,#0x31,gr0,icc1
+	beq		icc0,#0,__save_acc_fr451
+	beq		icc1,#0,__save_acc_fr555
+__save_acc_cont:
+
+	lddfi		@(gr8,#__FPMEDIA_FR(4)),fr4
+	lddfi.p		@(gr8,#__FPMEDIA_FR(6)),fr6
+	bralr
+
+	# the FR451 also has ACC8-11/ACCG8-11 regs (but not 4-7...)
+__save_acc_fr451:
+	mrdacc		acc8 ,fr4
+	mrdacc		acc9 ,fr5
+
+	stdfi.p		fr4 ,@(gr8,#__FPMEDIA_ACC(4))
+
+	mrdacc		acc10,fr6
+	mrdacc		acc11,fr7
+
+	stdfi.p		fr6 ,@(gr8,#__FPMEDIA_ACC(6))
+
+	mrdaccg		accg8,fr4
+	stbfi.p		fr4 ,@(gr8,#__FPMEDIA_ACCG(4))
+
+	mrdaccg		accg9,fr5
+	stbfi.p		fr5 ,@(gr8,#__FPMEDIA_ACCG(5))
+
+	mrdaccg		accg10,fr6
+	stbfi.p		fr6 ,@(gr8,#__FPMEDIA_ACCG(6))
+
+	mrdaccg		accg11,fr7
+	stbfi		fr7 ,@(gr8,#__FPMEDIA_ACCG(7))
+	bra		__save_acc_cont
+
+	# the FR555 also has ACC4-7/ACCG4-7 regs and an FSR0 reg
+__save_acc_fr555:
+	mnop.p
+	mrdacc		acc4 ,fr4
+	mnop.p
+	mrdacc		acc5 ,fr5
+
+	stdfi		fr4 ,@(gr8,#__FPMEDIA_ACC(4))
+
+	mnop.p
+	mrdacc		acc6 ,fr6
+	mnop.p
+	mrdacc		acc7 ,fr7
+
+	stdfi		fr6 ,@(gr8,#__FPMEDIA_ACC(6))
+
+	mnop.p
+	mrdaccg		accg4,fr4
+	stbfi		fr4 ,@(gr8,#__FPMEDIA_ACCG(4))
+
+	mnop.p
+	mrdaccg		accg5,fr5
+	stbfi		fr5 ,@(gr8,#__FPMEDIA_ACCG(5))
+
+	mnop.p
+	mrdaccg		accg6,fr6
+	stbfi		fr6 ,@(gr8,#__FPMEDIA_ACCG(6))
+
+	mnop.p
+	mrdaccg		accg7,fr7
+	stbfi		fr7 ,@(gr8,#__FPMEDIA_ACCG(7))
+
+	movsg		fsr0 ,gr4
+	sti		gr4 ,@(gr8,#__FPMEDIA_FSR(0))
+	bra		__save_acc_cont
diff -Nru a/arch/frv/kernel/sys_frv.c b/arch/frv/kernel/sys_frv.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/kernel/sys_frv.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,214 @@
+/* sys_frv.c: FRV arch-specific syscall wrappers
+ *
+ * Copyright (C) 2003-5 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ * - Derived from arch/m68k/kernel/sys_m68k.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.
+ */
+
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/sem.h>
+#include <linux/msg.h>
+#include <linux/shm.h>
+#include <linux/stat.h>
+#include <linux/mman.h>
+#include <linux/file.h>
+#include <linux/utsname.h>
+#include <linux/syscalls.h>
+
+#include <asm/setup.h>
+#include <asm/uaccess.h>
+#include <asm/ipc.h>
+
+/*
+ * sys_pipe() is the normal C calling standard for creating
+ * a pipe. It's not the way unix traditionally does this, though.
+ */
+asmlinkage long sys_pipe(unsigned long * fildes)
+{
+	int fd[2];
+	int error;
+
+	error = do_pipe(fd);
+	if (!error) {
+		if (copy_to_user(fildes, fd, 2*sizeof(int)))
+			error = -EFAULT;
+	}
+	return error;
+}
+
+asmlinkage long sys_mmap2(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;
+	}
+
+	/* As with sparc32, make sure the shift for mmap2 is constant
+	   (12), no matter what PAGE_SIZE we have.... */
+
+	/* But unlike sparc32, don't just silently break if we're
+	   trying to map something we can't */
+	if (pgoff & ((1<<(PAGE_SHIFT-12))-1))
+		return -EINVAL;
+
+	pgoff >>= (PAGE_SHIFT - 12);
+
+	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;
+}
+
+#if 0 /* DAVIDM - do we want this */
+struct mmap_arg_struct64 {
+	__u32 addr;
+	__u32 len;
+	__u32 prot;
+	__u32 flags;
+	__u64 offset; /* 64 bits */
+	__u32 fd;
+};
+
+asmlinkage long sys_mmap64(struct mmap_arg_struct64 *arg)
+{
+	int error = -EFAULT;
+	struct file * file = NULL;
+	struct mmap_arg_struct64 a;
+	unsigned long pgoff;
+
+	if (copy_from_user(&a, arg, sizeof(a)))
+		return -EFAULT;
+
+	if ((long)a.offset & ~PAGE_MASK)
+		return -EINVAL;
+
+	pgoff = a.offset >> PAGE_SHIFT;
+	if ((a.offset >> PAGE_SHIFT) != pgoff)
+		return -EINVAL;
+
+	if (!(a.flags & MAP_ANONYMOUS)) {
+		error = -EBADF;
+		file = fget(a.fd);
+		if (!file)
+			goto out;
+	}
+	a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+
+	down_write(&current->mm->mmap_sem);
+	error = do_mmap_pgoff(file, a.addr, a.len, a.prot, a.flags, pgoff);
+	up_write(&current->mm->mmap_sem);
+	if (file)
+		fput(file);
+out:
+	return error;
+}
+#endif
+
+/*
+ * sys_ipc() is the de-multiplexer for the SysV IPC calls..
+ *
+ * This is really horribly ugly.
+ */
+asmlinkage long sys_ipc(unsigned long call,
+			unsigned long first,
+			unsigned long second,
+			unsigned long third,
+			void __user *ptr,
+			unsigned long fifth)
+{
+	int version, ret;
+
+	version = call >> 16; /* hack for backward compatibility */
+	call &= 0xffff;
+
+	switch (call) {
+	case SEMOP:
+		return sys_semtimedop(first, (struct sembuf __user *)ptr, second, NULL);
+	case SEMTIMEDOP:
+		return sys_semtimedop(first, (struct sembuf __user *)ptr, second,
+				      (const struct timespec __user *)fifth);
+
+	case SEMGET:
+		return sys_semget (first, second, third);
+	case SEMCTL: {
+		union semun fourth;
+		if (!ptr)
+			return -EINVAL;
+		if (get_user(fourth.__pad, (void * __user *) ptr))
+			return -EFAULT;
+		return sys_semctl (first, second, third, fourth);
+	}
+
+	case MSGSND:
+		return sys_msgsnd (first, (struct msgbuf __user *) ptr,
+				   second, third);
+	case MSGRCV:
+		switch (version) {
+		case 0: {
+			struct ipc_kludge tmp;
+			if (!ptr)
+				return -EINVAL;
+
+			if (copy_from_user(&tmp,
+					   (struct ipc_kludge __user *) ptr,
+					   sizeof (tmp)))
+				return -EFAULT;
+			return sys_msgrcv (first, tmp.msgp, second,
+					   tmp.msgtyp, third);
+		}
+		default:
+			return sys_msgrcv (first,
+					   (struct msgbuf __user *) ptr,
+					   second, fifth, third);
+		}
+	case MSGGET:
+		return sys_msgget ((key_t) first, second);
+	case MSGCTL:
+		return sys_msgctl (first, second, (struct msqid_ds __user *) ptr);
+
+	case SHMAT:
+		switch (version) {
+		default: {
+			ulong raddr;
+			ret = do_shmat (first, (char __user *) ptr, second, &raddr);
+			if (ret)
+				return ret;
+			return put_user (raddr, (ulong __user *) third);
+		}
+		case 1:	/* iBCS2 emulator entry point */
+			if (!segment_eq(get_fs(), get_ds()))
+				return -EINVAL;
+			/* The "(ulong *) third" is valid _only_ because of the kernel segment thing */
+			return do_shmat (first, (char __user *) ptr, second, (ulong *) third);
+		}
+	case SHMDT:
+		return sys_shmdt ((char __user *)ptr);
+	case SHMGET:
+		return sys_shmget (first, second, third);
+	case SHMCTL:
+		return sys_shmctl (first, second,
+				   (struct shmid_ds __user *) ptr);
+	default:
+		return -ENOSYS;
+	}
+}
diff -Nru a/arch/frv/kernel/sysctl.c b/arch/frv/kernel/sysctl.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/kernel/sysctl.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,206 @@
+/* sysctl.c: implementation of /proc/sys files relating to FRV specifically
+ *
+ * Copyright (C) 2004 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/config.h>
+#include <linux/slab.h>
+#include <linux/sysctl.h>
+#include <linux/proc_fs.h>
+#include <linux/init.h>
+#include <asm/uaccess.h>
+
+static const char frv_cache_wback[] = "wback";
+static const char frv_cache_wthru[] = "wthru";
+
+static void frv_change_dcache_mode(unsigned long newmode)
+{
+	unsigned long flags, hsr0;
+
+	local_irq_save(flags);
+
+	hsr0 = __get_HSR(0);
+	hsr0 &= ~HSR0_DCE;
+	__set_HSR(0, hsr0);
+
+	asm volatile("	dcef	@(gr0,gr0),#1	\n"
+		     "	membar			\n"
+		     : : : "memory"
+		     );
+
+	hsr0 = (hsr0 & ~HSR0_CBM) | newmode;
+	__set_HSR(0, hsr0);
+	hsr0 |= HSR0_DCE;
+	__set_HSR(0, hsr0);
+
+	local_irq_restore(flags);
+
+	//printk("HSR0 now %08lx\n", hsr0);
+}
+
+/*****************************************************************************/
+/*
+ * handle requests to dynamically switch the write caching mode delivered by /proc
+ */
+static int procctl_frv_cachemode(ctl_table *table, int write, struct file *filp,
+				 void *buffer, size_t *lenp, loff_t *ppos)
+{
+	unsigned long hsr0;
+	char buff[8];
+	int len;
+
+	len = *lenp;
+
+	if (write) {
+		/* potential state change */
+		if (len <= 1 || len > sizeof(buff) - 1)
+			return -EINVAL;
+
+		if (copy_from_user(buff, buffer, len) != 0)
+			return -EFAULT;
+
+		if (buff[len - 1] == '\n')
+			buff[len - 1] = '\0';
+		else
+			buff[len] = '\0';
+
+		if (strcmp(buff, frv_cache_wback) == 0) {
+			/* switch dcache into write-back mode */
+			frv_change_dcache_mode(HSR0_CBM_COPY_BACK);
+			return 0;
+		}
+
+		if (strcmp(buff, frv_cache_wthru) == 0) {
+			/* switch dcache into write-through mode */
+			frv_change_dcache_mode(HSR0_CBM_WRITE_THRU);
+			return 0;
+		}
+
+		return -EINVAL;
+	}
+
+	/* read the state */
+	if (filp->f_pos > 0) {
+		*lenp = 0;
+		return 0;
+	}
+
+	hsr0 = __get_HSR(0);
+	switch (hsr0 & HSR0_CBM) {
+	case HSR0_CBM_WRITE_THRU:
+		memcpy(buff, frv_cache_wthru, sizeof(frv_cache_wthru) - 1);
+		buff[sizeof(frv_cache_wthru) - 1] = '\n';
+		len = sizeof(frv_cache_wthru);
+		break;
+	default:
+		memcpy(buff, frv_cache_wback, sizeof(frv_cache_wback) - 1);
+		buff[sizeof(frv_cache_wback) - 1] = '\n';
+		len = sizeof(frv_cache_wback);
+		break;
+	}
+
+	if (len > *lenp)
+		len = *lenp;
+
+	if (copy_to_user(buffer, buff, len) != 0)
+		return -EFAULT;
+
+	*lenp = len;
+	filp->f_pos = len;
+	return 0;
+
+} /* end procctl_frv_cachemode() */
+
+/*****************************************************************************/
+/*
+ * permit the mm_struct the nominated process is using have its MMU context ID pinned
+ */
+#ifdef CONFIG_MMU
+static int procctl_frv_pin_cxnr(ctl_table *table, int write, struct file *filp,
+				void *buffer, size_t *lenp, loff_t *ppos)
+{
+	pid_t pid;
+	char buff[16], *p;
+	int len;
+
+	len = *lenp;
+
+	if (write) {
+		/* potential state change */
+		if (len <= 1 || len > sizeof(buff) - 1)
+			return -EINVAL;
+
+		if (copy_from_user(buff, buffer, len) != 0)
+			return -EFAULT;
+
+		if (buff[len - 1] == '\n')
+			buff[len - 1] = '\0';
+		else
+			buff[len] = '\0';
+
+		pid = simple_strtoul(buff, &p, 10);
+		if (*p)
+			return -EINVAL;
+
+		return cxn_pin_by_pid(pid);
+	}
+
+	/* read the currently pinned CXN */
+	if (filp->f_pos > 0) {
+		*lenp = 0;
+		return 0;
+	}
+
+	len = snprintf(buff, sizeof(buff), "%d\n", cxn_pinned);
+	if (len > *lenp)
+		len = *lenp;
+
+	if (copy_to_user(buffer, buff, len) != 0)
+		return -EFAULT;
+
+	*lenp = len;
+	filp->f_pos = len;
+	return 0;
+
+} /* end procctl_frv_pin_cxnr() */
+#endif
+
+/*
+ * FR-V specific sysctls
+ */
+static struct ctl_table frv_table[] =
+{
+	{ 1, "cache-mode",	NULL, 0, 0644, NULL, &procctl_frv_cachemode },
+#ifdef CONFIG_MMU
+	{ 2, "pin-cxnr",	NULL, 0, 0644, NULL, &procctl_frv_pin_cxnr },
+#endif
+	{ 0 }
+};
+
+/*
+ * Use a temporary sysctl number. Horrid, but will be cleaned up in 2.6
+ * when all the PM interfaces exist nicely.
+ */
+#define CTL_FRV 9898
+static struct ctl_table frv_dir_table[] =
+{
+	{CTL_FRV, "frv", NULL, 0, 0555, frv_table},
+	{0}
+};
+
+/*
+ * Initialize power interface
+ */
+static int __init frv_sysctl_init(void)
+{
+	register_sysctl_table(frv_dir_table, 1);
+	return 0;
+}
+
+__initcall(frv_sysctl_init);
diff -Nru a/arch/frv/kernel/time.c b/arch/frv/kernel/time.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/kernel/time.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,234 @@
+/* time.c: FRV arch-specific time handling
+ *
+ * Copyright (C) 2003-5 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ * - Derived from arch/m68k/kernel/time.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.
+ */
+
+#include <linux/config.h> /* CONFIG_HEARTBEAT */
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/interrupt.h>
+#include <linux/profile.h>
+#include <linux/irq.h>
+#include <linux/mm.h>
+
+#include <asm/io.h>
+#include <asm/timer-regs.h>
+#include <asm/mb-regs.h>
+#include <asm/mb86943a.h>
+#include <asm/irq-routing.h>
+
+#include <linux/timex.h>
+
+#define TICK_SIZE (tick_nsec / 1000)
+
+extern unsigned long wall_jiffies;
+
+u64 jiffies_64 = INITIAL_JIFFIES;
+EXPORT_SYMBOL(jiffies_64);
+
+unsigned long __nongprelbss __clkin_clock_speed_HZ;
+unsigned long __nongprelbss __ext_bus_clock_speed_HZ;
+unsigned long __nongprelbss __res_bus_clock_speed_HZ;
+unsigned long __nongprelbss __sdram_clock_speed_HZ;
+unsigned long __nongprelbss __core_bus_clock_speed_HZ;
+unsigned long __nongprelbss __core_clock_speed_HZ;
+unsigned long __nongprelbss __dsu_clock_speed_HZ;
+unsigned long __nongprelbss __serial_clock_speed_HZ;
+unsigned long __delay_loops_MHz;
+
+static irqreturn_t timer_interrupt(int irq, void *dummy, struct pt_regs *regs);
+
+static struct irqaction timer_irq  = {
+	timer_interrupt, SA_INTERRUPT, CPU_MASK_NONE, "timer", NULL, NULL
+};
+
+static inline int set_rtc_mmss(unsigned long nowtime)
+{
+	return -1;
+}
+
+/*
+ * timer_interrupt() needs to keep up the real-time clock,
+ * as well as call the "do_timer()" routine every clocktick
+ */
+static irqreturn_t timer_interrupt(int irq, void *dummy, struct pt_regs * regs)
+{
+	/* last time the cmos clock got updated */
+	static long last_rtc_update = 0;
+
+	/*
+	 * Here we are in the timer irq handler. We just have irqs locally
+	 * disabled but we don't know if the timer_bh is running on the other
+	 * CPU. We need to avoid to SMP race with it. NOTE: we don' t need
+	 * the irq version of write_lock because as just said we have irq
+	 * locally disabled. -arca
+	 */
+	write_seqlock(&xtime_lock);
+
+	do_timer(regs);
+	update_process_times(user_mode(regs));
+	profile_tick(CPU_PROFILING, 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.
+	 */
+	if ((time_status & STA_UNSYNC) == 0 &&
+	    xtime.tv_sec > last_rtc_update + 660 &&
+	    (xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 &&
+	    (xtime.tv_nsec / 1000) <= 500000 + ((unsigned) TICK_SIZE) / 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 */
+	}
+
+#ifdef CONFIG_HEARTBEAT
+	static unsigned short n;
+	n++;
+	__set_LEDS(n);
+#endif /* CONFIG_HEARTBEAT */
+
+	write_sequnlock(&xtime_lock);
+	return IRQ_HANDLED;
+}
+
+void time_divisor_init(void)
+{
+	unsigned short base, pre, prediv;
+
+	/* set the scheduling timer going */
+	pre = 1;
+	prediv = 4;
+	base = __res_bus_clock_speed_HZ / pre / HZ / (1 << prediv);
+
+	__set_TPRV(pre);
+	__set_TxCKSL_DATA(0, prediv);
+	__set_TCTR(TCTR_SC_CTR0 | TCTR_RL_RW_LH8 | TCTR_MODE_2);
+	__set_TCSR_DATA(0, base & 0xff);
+	__set_TCSR_DATA(0, base >> 8);
+}
+
+void time_init(void)
+{
+	unsigned int year, mon, day, hour, min, sec;
+
+	extern void arch_gettod(int *year, int *mon, int *day, int *hour, int *min, int *sec);
+
+	/* FIX by dqg : Set to zero for platforms that don't have tod */
+	/* without this time is undefined and can overflow time_t, causing  */
+	/* very stange errors */
+	year = 1980;
+	mon = day = 1;
+	hour = min = sec = 0;
+	arch_gettod (&year, &mon, &day, &hour, &min, &sec);
+
+	if ((year += 1900) < 1970)
+		year += 100;
+	xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
+	xtime.tv_nsec = 0;
+
+	/* install scheduling interrupt handler */
+	setup_irq(IRQ_CPU_TIMER0, &timer_irq);
+
+	time_divisor_init();
+}
+
+/*
+ * This version of gettimeofday has near microsecond resolution.
+ */
+void do_gettimeofday(struct timeval *tv)
+{
+	unsigned long seq;
+	unsigned long usec, sec;
+	unsigned long max_ntp_tick;
+
+	do {
+		unsigned long lost;
+
+		seq = read_seqbegin(&xtime_lock);
+
+		usec = 0;
+		lost = jiffies - wall_jiffies;
+
+		/*
+		 * If time_adjust is negative then NTP is slowing the clock
+		 * so make sure not to go into next possible interval.
+		 * Better to lose some accuracy than have time go backwards..
+		 */
+		if (unlikely(time_adjust < 0)) {
+			max_ntp_tick = (USEC_PER_SEC / HZ) - tickadj;
+			usec = min(usec, max_ntp_tick);
+
+			if (lost)
+				usec += lost * max_ntp_tick;
+		}
+		else if (unlikely(lost))
+			usec += lost * (USEC_PER_SEC / HZ);
+
+		sec = xtime.tv_sec;
+		usec += (xtime.tv_nsec / 1000);
+	} while (read_seqretry(&xtime_lock, seq));
+
+	while (usec >= 1000000) {
+		usec -= 1000000;
+		sec++;
+	}
+
+	tv->tv_sec = sec;
+	tv->tv_usec = usec;
+}
+
+int do_settimeofday(struct timespec *tv)
+{
+	time_t wtm_sec, sec = tv->tv_sec;
+	long wtm_nsec, nsec = tv->tv_nsec;
+
+	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!
+	 */
+	nsec -= 0 * NSEC_PER_USEC;
+	nsec -= (jiffies - wall_jiffies) * TICK_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);
+	clock_was_set();
+	return 0;
+}
+
+/*
+ * Scheduler clock - returns current time in nanosec units.
+ */
+unsigned long long sched_clock(void)
+{
+	return jiffies_64 * (1000000000 / HZ);
+}
diff -Nru a/arch/frv/kernel/traps.c b/arch/frv/kernel/traps.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/kernel/traps.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,431 @@
+/* traps.c: high-level exception handler for FR-V
+ *
+ * Copyright (C) 2003 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/config.h>
+#include <linux/sched.h>
+#include <linux/signal.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/types.h>
+#include <linux/user.h>
+#include <linux/string.h>
+#include <linux/linkage.h>
+#include <linux/init.h>
+
+#include <asm/setup.h>
+#include <asm/fpu.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#include <asm/pgtable.h>
+#include <asm/siginfo.h>
+#include <asm/unaligned.h>
+
+void show_backtrace(struct pt_regs *, unsigned long);
+
+extern asmlinkage void __break_hijack_kernel_event(void);
+
+/*****************************************************************************/
+/*
+ * instruction access error
+ */
+asmlinkage void insn_access_error(unsigned long esfr1, unsigned long epcr0, unsigned long esr0)
+{
+	siginfo_t info;
+
+	die_if_kernel("-- Insn Access Error --\n"
+		      "EPCR0 : %08lx\n"
+		      "ESR0  : %08lx\n",
+		      epcr0, esr0);
+
+	info.si_signo	= SIGSEGV;
+	info.si_code	= SEGV_ACCERR;
+	info.si_errno	= 0;
+	info.si_addr	= (void *) ((epcr0 & EPCR0_V) ? (epcr0 & EPCR0_PC) : __frame->pc);
+
+	force_sig_info(info.si_signo, &info, current);
+} /* end insn_access_error() */
+
+/*****************************************************************************/
+/*
+ * handler for:
+ * - illegal instruction
+ * - privileged instruction
+ * - unsupported trap
+ * - debug exceptions
+ */
+asmlinkage void illegal_instruction(unsigned long esfr1, unsigned long epcr0, unsigned long esr0)
+{
+	siginfo_t info;
+
+	die_if_kernel("-- Illegal Instruction --\n"
+		      "EPCR0 : %08lx\n"
+		      "ESR0  : %08lx\n"
+		      "ESFR1 : %08lx\n",
+		      epcr0, esr0, esfr1);
+
+	info.si_errno	= 0;
+	info.si_addr	= (void *) ((epcr0 & EPCR0_PC) ? (epcr0 & EPCR0_PC) : __frame->pc);
+
+	switch (__frame->tbr & TBR_TT) {
+	case TBR_TT_ILLEGAL_INSTR:
+		info.si_signo	= SIGILL;
+		info.si_code	= ILL_ILLOPC;
+		break;
+	case TBR_TT_PRIV_INSTR:
+		info.si_signo	= SIGILL;
+		info.si_code	= ILL_PRVOPC;
+		break;
+	case TBR_TT_TRAP2 ... TBR_TT_TRAP126:
+		info.si_signo	= SIGILL;
+		info.si_code	= ILL_ILLTRP;
+		break;
+	/* GDB uses "tira gr0, #1" as a breakpoint instruction.  */
+	case TBR_TT_TRAP1:
+	case TBR_TT_BREAK:
+		info.si_signo	= SIGTRAP;
+		info.si_code	=
+			(__frame->__status & REG__STATUS_STEPPED) ? TRAP_TRACE : TRAP_BRKPT;
+		break;
+	}
+
+	force_sig_info(info.si_signo, &info, current);
+} /* end illegal_instruction() */
+
+/*****************************************************************************/
+/*
+ *
+ */
+asmlinkage void media_exception(unsigned long msr0, unsigned long msr1)
+{
+	siginfo_t info;
+
+	die_if_kernel("-- Media Exception --\n"
+		      "MSR0 : %08lx\n"
+		      "MSR1 : %08lx\n",
+		      msr0, msr1);
+
+	info.si_signo	= SIGFPE;
+	info.si_code	= FPE_MDAOVF;
+	info.si_errno	= 0;
+	info.si_addr	= (void *) __frame->pc;
+
+	force_sig_info(info.si_signo, &info, current);
+} /* end media_exception() */
+
+/*****************************************************************************/
+/*
+ * instruction or data access exception
+ */
+asmlinkage void memory_access_exception(unsigned long esr0,
+					unsigned long ear0,
+					unsigned long epcr0)
+{
+	siginfo_t info;
+
+#ifdef CONFIG_MMU
+	unsigned long fixup;
+
+	if ((esr0 & ESRx_EC) == ESRx_EC_DATA_ACCESS)
+		if (handle_misalignment(esr0, ear0, epcr0) == 0)
+			return;
+
+	if ((fixup = search_exception_table(__frame->pc)) != 0) {
+		__frame->pc = fixup;
+		return;
+	}
+#endif
+
+	die_if_kernel("-- Memory Access Exception --\n"
+		      "ESR0  : %08lx\n"
+		      "EAR0  : %08lx\n"
+		      "EPCR0 : %08lx\n",
+		      esr0, ear0, epcr0);
+
+	info.si_signo	= SIGSEGV;
+	info.si_code	= SEGV_ACCERR;
+	info.si_errno	= 0;
+	info.si_addr	= NULL;
+
+	if ((esr0 & (ESRx_VALID | ESR0_EAV)) == (ESRx_VALID | ESR0_EAV))
+		info.si_addr = (void *) ear0;
+
+	force_sig_info(info.si_signo, &info, current);
+
+} /* end memory_access_exception() */
+
+/*****************************************************************************/
+/*
+ * data access error
+ * - double-word data load from CPU control area (0xFExxxxxx)
+ * - read performed on inactive or self-refreshing SDRAM
+ * - error notification from slave device
+ * - misaligned address
+ * - access to out of bounds memory region
+ * - user mode accessing privileged memory region
+ * - write to R/O memory region
+ */
+asmlinkage void data_access_error(unsigned long esfr1, unsigned long esr15, unsigned long ear15)
+{
+	siginfo_t info;
+
+	die_if_kernel("-- Data Access Error --\n"
+		      "ESR15 : %08lx\n"
+		      "EAR15 : %08lx\n",
+		      esr15, ear15);
+
+	info.si_signo	= SIGSEGV;
+	info.si_code	= SEGV_ACCERR;
+	info.si_errno	= 0;
+	info.si_addr	= (void *)
+		(((esr15 & (ESRx_VALID|ESR15_EAV)) == (ESRx_VALID|ESR15_EAV)) ? ear15 : 0);
+
+	force_sig_info(info.si_signo, &info, current);
+} /* end data_access_error() */
+
+/*****************************************************************************/
+/*
+ * data store error - should only happen if accessing inactive or self-refreshing SDRAM
+ */
+asmlinkage void data_store_error(unsigned long esfr1, unsigned long esr15)
+{
+	die_if_kernel("-- Data Store Error --\n"
+		      "ESR15 : %08lx\n",
+		      esr15);
+	BUG();
+} /* end data_store_error() */
+
+/*****************************************************************************/
+/*
+ *
+ */
+asmlinkage void division_exception(unsigned long esfr1, unsigned long esr0, unsigned long isr)
+{
+	siginfo_t info;
+
+	die_if_kernel("-- Division Exception --\n"
+		      "ESR0 : %08lx\n"
+		      "ISR  : %08lx\n",
+		      esr0, isr);
+
+	info.si_signo	= SIGFPE;
+	info.si_code	= FPE_INTDIV;
+	info.si_errno	= 0;
+	info.si_addr	= (void *) __frame->pc;
+
+	force_sig_info(info.si_signo, &info, current);
+} /* end division_exception() */
+
+/*****************************************************************************/
+/*
+ *
+ */
+asmlinkage void compound_exception(unsigned long esfr1,
+				   unsigned long esr0, unsigned long esr14, unsigned long esr15,
+				   unsigned long msr0, unsigned long msr1)
+{
+	die_if_kernel("-- Compound Exception --\n"
+		      "ESR0  : %08lx\n"
+		      "ESR15 : %08lx\n"
+		      "ESR15 : %08lx\n"
+		      "MSR0  : %08lx\n"
+		      "MSR1  : %08lx\n",
+		      esr0, esr14, esr15, msr0, msr1);
+	BUG();
+} /* end compound_exception() */
+
+/*****************************************************************************/
+/*
+ * The architecture-independent backtrace generator
+ */
+void dump_stack(void)
+{
+	show_stack(NULL, NULL);
+}
+
+void show_stack(struct task_struct *task, unsigned long *sp)
+{
+}
+
+void show_trace_task(struct task_struct *tsk)
+{
+	printk("CONTEXT: stack=0x%lx frame=0x%p LR=0x%lx RET=0x%lx\n",
+	       tsk->thread.sp, tsk->thread.frame, tsk->thread.lr, tsk->thread.sched_lr);
+}
+
+static const char *regnames[] = {
+	"PSR ", "ISR ", "CCR ", "CCCR",
+	"LR  ", "LCR ", "PC  ", "_stt",
+	"sys ", "GR8*", "GNE0", "GNE1",
+	"IACH", "IACL",
+	"TBR ", "SP  ", "FP  ", "GR3 ",
+	"GR4 ", "GR5 ", "GR6 ", "GR7 ",
+	"GR8 ", "GR9 ", "GR10", "GR11",
+	"GR12", "GR13", "GR14", "GR15",
+	"GR16", "GR17", "GR18", "GR19",
+	"GR20", "GR21", "GR22", "GR23",
+	"GR24", "GR25", "GR26", "GR27",
+	"EFRM", "CURR", "GR30", "BFRM"
+};
+
+void show_regs(struct pt_regs *regs)
+{
+	uint32_t *reg;
+	int loop;
+
+	printk("\n");
+
+	printk("Frame: @%08x [%s]\n",
+	       (uint32_t) regs,
+	       regs->psr & PSR_S ? "kernel" : "user");
+
+	reg = (uint32_t *) regs;
+	for (loop = 0; loop < REG__END; loop++) {
+		printk("%s %08x", regnames[loop + 0], reg[loop + 0]);
+
+		if (loop == REG__END - 1 || loop % 5 == 4)
+			printk("\n");
+		else
+			printk(" | ");
+	}
+
+	printk("Process %s (pid: %d)\n", current->comm, current->pid);
+}
+
+void die_if_kernel(const char *str, ...)
+{
+	char buffer[256];
+	va_list va;
+
+	if (user_mode(__frame))
+		return;
+
+	va_start(va, str);
+	vsprintf(buffer, str, va);
+	va_end(va);
+
+	console_verbose();
+	printk("\n===================================\n");
+	printk("%s\n", buffer);
+	show_backtrace(__frame, 0);
+
+	__break_hijack_kernel_event();
+	do_exit(SIGSEGV);
+}
+
+/*****************************************************************************/
+/*
+ * dump the contents of an exception frame
+ */
+static void show_backtrace_regs(struct pt_regs *frame)
+{
+	uint32_t *reg;
+	int loop;
+
+	/* print the registers for this frame */
+	printk("<-- %s Frame: @%p -->\n",
+	       frame->psr & PSR_S ? "Kernel Mode" : "User Mode",
+	       frame);
+
+	reg = (uint32_t *) frame;
+	for (loop = 0; loop < REG__END; loop++) {
+		printk("%s %08x", regnames[loop + 0], reg[loop + 0]);
+
+		if (loop == REG__END - 1 || loop % 5 == 4)
+			printk("\n");
+		else
+			printk(" | ");
+	}
+
+	printk("--------\n");
+} /* end show_backtrace_regs() */
+
+/*****************************************************************************/
+/*
+ * generate a backtrace of the kernel stack
+ */
+void show_backtrace(struct pt_regs *frame, unsigned long sp)
+{
+	struct pt_regs *frame0;
+	unsigned long tos = 0, stop = 0, base;
+	int format;
+
+	base = ((((unsigned long) frame) + 8191) & ~8191) - sizeof(struct user_context);
+	frame0 = (struct pt_regs *) base;
+
+	if (sp) {
+		tos = sp;
+		stop = (unsigned long) frame;
+	}
+
+	printk("\nProcess %s (pid: %d)\n\n", current->comm, current->pid);
+
+	for (;;) {
+		/* dump stack segment between frames */
+		//printk("%08lx -> %08lx\n", tos, stop);
+		format = 0;
+		while (tos < stop) {
+			if (format == 0)
+				printk(" %04lx :", tos & 0xffff);
+
+			printk(" %08lx", *(unsigned long *) tos);
+
+			tos += 4;
+			format++;
+			if (format == 8) {
+				printk("\n");
+				format = 0;
+			}
+		}
+
+		if (format > 0)
+			printk("\n");
+
+		/* dump frame 0 outside of the loop */
+		if (frame == frame0)
+			break;
+
+		tos = frame->sp;
+		if (((unsigned long) frame) + sizeof(*frame) != tos) {
+			printk("-- TOS %08lx does not follow frame %p --\n",
+			       tos, frame);
+			break;
+		}
+
+		show_backtrace_regs(frame);
+
+		/* dump the stack between this frame and the next */
+		stop = (unsigned long) frame->next_frame;
+		if (stop != base &&
+		    (stop < tos ||
+		     stop > base ||
+		     (stop < base && stop + sizeof(*frame) > base) ||
+		     stop & 3)) {
+			printk("-- next_frame %08lx is invalid (range %08lx-%08lx) --\n",
+			       stop, tos, base);
+			break;
+		}
+
+		/* move to next frame */
+		frame = frame->next_frame;
+	}
+
+	/* we can always dump frame 0, even if the rest of the stack is corrupt */
+	show_backtrace_regs(frame0);
+
+} /* end show_backtrace() */
+
+/*****************************************************************************/
+/*
+ * initialise traps
+ */
+void __init trap_init (void)
+{
+} /* end trap_init() */
diff -Nru a/arch/frv/kernel/uaccess.c b/arch/frv/kernel/uaccess.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/kernel/uaccess.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,95 @@
+/* uaccess.c: userspace access functions
+ *
+ * Copyright (C) 2004 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/mm.h>
+#include <asm/uaccess.h>
+
+/*****************************************************************************/
+/*
+ * copy a null terminated string from userspace
+ */
+long strncpy_from_user(char *dst, const char *src, long count)
+{
+	unsigned long max;
+	char *p, ch;
+	long err = -EFAULT;
+
+	if (count < 0)
+		BUG();
+
+	p = dst;
+
+#ifndef CONFIG_MMU
+	if ((unsigned long) src < memory_start)
+		goto error;
+#endif
+
+	if ((unsigned long) src >= get_addr_limit())
+		goto error;
+
+	max = get_addr_limit() - (unsigned long) src;
+	if ((unsigned long) count > max) {
+		memset(dst + max, 0, count - max);
+		count = max;
+	}
+
+	err = 0;
+	for (; count > 0; count--, p++, src++) {
+		__get_user_asm(err, ch, src, "ub", "=r");
+		if (err < 0)
+			goto error;
+		if (!ch)
+			break;
+		*p = ch;
+	}
+
+	err = p - dst; /* return length excluding NUL */
+
+ error:
+	if (count > 0)
+		memset(p, 0, count); /* clear remainder of buffer [security] */
+
+	return err;
+} /* end strncpy_from_user() */
+
+/*****************************************************************************/
+/*
+ * Return the size of a string (including the ending 0)
+ *
+ * Return 0 on exception, a value greater than N if too long
+ */
+long strnlen_user(const char *src, long count)
+{
+	const char *p;
+	long err = 0;
+	char ch;
+
+	if (count < 0)
+		BUG();
+
+#ifndef CONFIG_MMU
+	if ((unsigned long) src < memory_start)
+		return 0;
+#endif
+
+	if ((unsigned long) src >= get_addr_limit())
+		return 0;
+
+	for (p = src; count > 0; count--, p++) {
+		__get_user_asm(err, ch, p, "ub", "=r");
+		if (err < 0)
+			return 0;
+		if (!ch)
+			break;
+	}
+
+	return p - src + 1; /* return length including NUL */
+} /* end strnlen_user() */
diff -Nru a/arch/frv/kernel/vmlinux.lds.S b/arch/frv/kernel/vmlinux.lds.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/kernel/vmlinux.lds.S	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,187 @@
+/* ld script to make FRV Linux kernel
+ * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>;
+ */
+OUTPUT_FORMAT("elf32-frv", "elf32-frv", "elf32-frv")
+OUTPUT_ARCH(frv)
+ENTRY(_start)
+
+#include <asm-generic/vmlinux.lds.h>
+#include <asm/processor.h>
+#include <asm/page.h>
+#include <asm/cache.h>
+#include <asm/thread_info.h>
+
+jiffies = jiffies_64 + 4;
+
+__page_offset = 0xc0000000;		/* start of area covered by struct pages */
+__kernel_image_start = __page_offset;	/* address at which kernel image resides */
+
+SECTIONS
+{
+  . = __kernel_image_start;
+
+  /* discardable initialisation code and data */
+  . = ALIGN(PAGE_SIZE);			/* Init code and data */
+  __init_begin = .;
+
+  _sinittext = .;
+  .init.text : {
+	*(.text.head)
+#ifndef CONFIG_DEBUG_INFO
+	*(.init.text)
+	*(.exit.text)
+	*(.exit.data)
+	*(.exitcall.exit)
+#endif
+  }
+  _einittext = .;
+  .init.data : { *(.init.data) }
+
+  . = ALIGN(8);
+  __setup_start = .;
+  .setup.init : { KEEP(*(.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);
+  __alt_instructions = .;
+  .altinstructions : { *(.altinstructions) }
+  __alt_instructions_end = .;
+ .altinstr_replacement : { *(.altinstr_replacement) }
+
+  __per_cpu_start = .;
+  .data.percpu  : { *(.data.percpu) }
+  __per_cpu_end = .;
+
+  . = ALIGN(4096);
+  __initramfs_start = .;
+  .init.ramfs : { *(.init.ramfs) }
+  __initramfs_end = .;
+
+  . = ALIGN(THREAD_SIZE);
+  __init_end = .;
+
+  /* put sections together that have massive alignment issues */
+  . = ALIGN(THREAD_SIZE);
+  .data.init_task : {
+	  /* init task record & stack */
+	  *(.data.init_task)
+  }
+
+  .trap : {
+	/* trap table management - read entry-table.S before modifying */
+	. = ALIGN(8192);
+	__trap_tables = .;
+	*(.trap.user)
+	*(.trap.kernel)
+	. = ALIGN(4096);
+	*(.trap.break)
+  }
+
+  . = ALIGN(4096);
+  .data.page_aligned : { *(.data.idt) }
+
+  . = ALIGN(L1_CACHE_BYTES);
+  .data.cacheline_aligned : { *(.data.cacheline_aligned) }
+
+  /* Text and read-only data */
+  . = ALIGN(4);
+  _text = .;
+  _stext = .;
+  .text : {
+	*(
+		.text.start .text .text.*
+#ifdef CONFIG_DEBUG_INFO
+	.init.text
+	.exit.text
+	.exitcall.exit
+#endif
+	)
+	SCHED_TEXT
+	*(.fixup)
+	*(.gnu.warning)
+	*(.exitcall.exit)
+	} = 0x9090
+
+  _etext = .;			/* End of text section */
+
+  RODATA
+
+  .rodata : {
+	*(.trap.vector)
+
+	/* this clause must not be modified - the ordering and adjacency are imperative */
+	__trap_fixup_tables = .;
+	*(.trap.fixup.user .trap.fixup.kernel)
+
+	}
+
+  . = ALIGN(8);		/* Exception table */
+  __start___ex_table = .;
+  __ex_table : { KEEP(*(__ex_table)) }
+  __stop___ex_table = .;
+
+  _sdata = .;
+  .data : {			/* Data */
+	*(.data .data.*)
+	*(.exit.data)
+	CONSTRUCTORS
+	}
+
+  _edata = .;			/* End of data section */
+
+  /* GP section */
+  . = ALIGN(L1_CACHE_BYTES);
+  _gp = . + 2048;
+  PROVIDE (gp = _gp);
+
+  .sdata : { *(.sdata .sdata.*) }
+
+  /* BSS */
+  . = ALIGN(L1_CACHE_BYTES);
+  __bss_start = .;
+
+  .sbss		: { *(.sbss .sbss.*) }
+  .bss		: { *(.bss .bss.*) }
+  .bss.stack	: { *(.bss) }
+
+  __bss_stop = .;
+  _end = . ;
+  . = ALIGN(PAGE_SIZE);
+  __kernel_image_end = .;
+
+  /* Stabs debugging sections.  */
+  .stab 0 : { *(.stab) }
+  .stabstr 0 : { *(.stabstr) }
+  .stab.excl 0 : { *(.stab.excl) }
+  .stab.exclstr 0 : { *(.stab.exclstr) }
+  .stab.index 0 : { *(.stab.index) }
+  .stab.indexstr 0 : { *(.stab.indexstr) }
+
+  .debug_line		0 : { *(.debug_line) }
+  .debug_info		0 : { *(.debug_info) }
+  .debug_abbrev		0 : { *(.debug_abbrev) }
+  .debug_aranges	0 : { *(.debug_aranges) }
+  .debug_frame		0 : { *(.debug_frame) }
+  .debug_pubnames	0 : { *(.debug_pubnames) }
+  .debug_str		0 : { *(.debug_str) }
+  .debug_ranges		0 : { *(.debug_ranges) }
+
+  .comment 0 : { *(.comment) }
+}
+
+__kernel_image_size_no_bss = __bss_start - __kernel_image_start;
diff -Nru a/arch/frv/lib/Makefile b/arch/frv/lib/Makefile
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/lib/Makefile	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,8 @@
+#
+# Makefile for FRV-specific library files..
+#
+
+lib-y := \
+	__ashldi3.o __lshrdi3.o __muldi3.o __ashrdi3.o __negdi2.o \
+	checksum.o memcpy.o memset.o atomic-ops.o \
+	outsl_ns.o outsl_sw.o insl_ns.o insl_sw.o cache.o
diff -Nru a/arch/frv/lib/__ashldi3.S b/arch/frv/lib/__ashldi3.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/lib/__ashldi3.S	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,40 @@
+/* __ashldi3.S:	64-bit arithmetic shift left
+ *
+ * Copyright (C) 2003 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.
+ */
+
+        .text
+        .p2align	4
+
+###############################################################################
+#
+# unsigned long long __ashldi3(unsigned long long value [GR8:GR9], unsigned by [GR10])
+#
+###############################################################################
+        .globl		__ashldi3
+        .type		__ashldi3,@function
+__ashldi3:
+	andicc.p	gr10,#63,gr10,icc0
+	setlos		#32,gr5
+	andicc.p	gr10,#32,gr0,icc1
+	beqlr		icc0,#0
+	ckeq		icc1,cc4			; cc4 is true if 0<N<32
+
+	# deal with a shift in the range 1<=N<=31
+	csll.p		gr8,gr10,gr8	,cc4,#1		; MSW <<= N
+	csub		gr5,gr10,gr5	,cc4,#1		; M = 32 - N
+	csrl.p		gr9,gr5,gr4	,cc4,#1
+	csll		gr9,gr10,gr9	,cc4,#1		; LSW <<= N
+	cor.p		gr4,gr8,gr8	,cc4,#1		; MSW |= LSW >> M
+
+	# deal with a shift in the range 32<=N<=63
+	csll		gr9,gr10,gr8	,cc4,#0		; MSW = LSW << (N & 31 [implicit AND])
+	cor.p		gr0,gr0,gr9	,cc4,#0		; LSW = 0
+	bralr
+	.size		__ashldi3, .-__ashldi3
diff -Nru a/arch/frv/lib/__ashrdi3.S b/arch/frv/lib/__ashrdi3.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/lib/__ashrdi3.S	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,41 @@
+/* __ashrdi3.S:	64-bit arithmetic shift right
+ *
+ * Copyright (C) 2003 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.
+ */
+
+        .text
+        .p2align	4
+
+###############################################################################
+#
+# signed long long __ashrdi3(signed long long value [GR8:GR9], unsigned by [GR10])
+#
+###############################################################################
+        .globl		__ashrdi3
+        .type		__ashrdi3,@function
+__ashrdi3:
+	andicc.p	gr10,#63,gr10,icc0
+	setlos		#32,gr5
+	andicc.p	gr10,#32,gr0,icc1
+	beqlr		icc0,#0
+	setlos.p	#31,gr6
+	ckeq		icc1,cc4			; cc4 is true if 0<N<32
+
+	# deal with a shift in the range 1<=N<=31
+	csrl.p		gr9,gr10,gr9	,cc4,#1		; LSW >>= N
+	csub		gr5,gr10,gr5	,cc4,#1		; M = 32 - N
+	csll.p		gr8,gr5,gr4	,cc4,#1
+	csra		gr8,gr10,gr8	,cc4,#1		; MSW >>= N
+	cor.p		gr4,gr9,gr9	,cc4,#1		; LSW |= MSW << M
+
+	# deal with a shift in the range 32<=N<=63
+	csra		gr8,gr10,gr9	,cc4,#0		; LSW = MSW >> (N & 31 [implicit AND])
+	csra.p		gr8,gr6,gr8	,cc4,#0		; MSW >>= 31
+	bralr
+	.size		__ashrdi3, .-__ashrdi3
diff -Nru a/arch/frv/lib/__lshrdi3.S b/arch/frv/lib/__lshrdi3.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/lib/__lshrdi3.S	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,40 @@
+/* __lshrdi3.S:	64-bit logical shift right
+ *
+ * Copyright (C) 2003 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.
+ */
+
+        .text
+        .p2align	4
+
+###############################################################################
+#
+# unsigned long long __lshrdi3(unsigned long long value [GR8:GR9], unsigned by [GR10])
+#
+###############################################################################
+        .globl		__lshrdi3
+        .type		__lshrdi3,@function
+__lshrdi3:
+	andicc.p	gr10,#63,gr10,icc0
+	setlos		#32,gr5
+	andicc.p	gr10,#32,gr0,icc1
+	beqlr		icc0,#0
+	ckeq		icc1,cc4			; cc4 is true if 0<N<32
+
+	# deal with a shift in the range 1<=N<=31
+	csrl.p		gr9,gr10,gr9	,cc4,#1		; LSW >>= N
+	csub		gr5,gr10,gr5	,cc4,#1		; M = 32 - N
+	csll.p		gr8,gr5,gr4	,cc4,#1
+	csrl		gr8,gr10,gr8	,cc4,#1		; MSW >>= N
+	cor.p		gr4,gr9,gr9	,cc4,#1		; LSW |= MSW << M
+
+	# deal with a shift in the range 32<=N<=63
+	csrl		gr8,gr10,gr9	,cc4,#0		; LSW = MSW >> (N & 31 [implicit AND])
+	cor.p		gr0,gr0,gr8	,cc4,#0		; MSW = 0
+	bralr
+	.size		__lshrdi3, .-__lshrdi3
diff -Nru a/arch/frv/lib/__muldi3.S b/arch/frv/lib/__muldi3.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/lib/__muldi3.S	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,32 @@
+/* __muldi3.S:	64-bit multiply
+ *
+ * Copyright (C) 2003 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.
+ */
+
+        .text
+        .p2align	4
+
+###############################################################################
+#
+# unsigned long long __muldi3(unsigned long long x [GR8:GR9],
+#                             unsigned long long y [GR10:GR11])
+#
+###############################################################################
+        .globl		__muldi3, __mulll, __umulll
+        .type		__muldi3,@function
+__muldi3:
+__mulll:
+__umulll:
+	umul		gr8,gr11,gr4		; GR4:GR5 = x.MSW * y.LSW
+	umul		gr9,gr10,gr6		; GR6:GR7 = x.LSW * y.MSW
+	umul.p		gr9,gr11,gr8		; GR8:GR9 = x.LSW * y.LSW
+	add		gr5,gr7,gr5
+	add.p		gr8,gr5,gr8		; GR8 += GR5 + GR7
+	bralr
+	.size		__muldi3, .-__muldi3
diff -Nru a/arch/frv/lib/__negdi2.S b/arch/frv/lib/__negdi2.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/lib/__negdi2.S	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,28 @@
+/* __negdi2.S: 64-bit negate
+ *
+ * Copyright (C) 2003 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.
+ */
+
+
+        .text
+        .p2align	4
+
+###############################################################################
+#
+# unsigned long long __negdi2(unsigned long long value [GR8:GR9])
+#
+###############################################################################
+        .globl		__negdi2
+        .type		__negdi2,@function
+__negdi2:
+	subcc		gr0,gr9,gr9,icc0
+	subx		gr0,gr8,gr8,icc0
+	bralr
+	.size		__negdi2, .-__negdi2
+
diff -Nru a/arch/frv/lib/atomic-ops.S b/arch/frv/lib/atomic-ops.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/lib/atomic-ops.S	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,265 @@
+/* atomic-ops.S: kernel atomic operations
+ *
+ * For an explanation of how atomic ops work in this arch, see:
+ *   Documentation/fujitsu/frv/atomic-ops.txt
+ *
+ * Copyright (C) 2004 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 <asm/spr-regs.h>
+
+	.text
+	.balign 4
+
+###############################################################################
+#
+# unsigned long atomic_test_and_ANDNOT_mask(unsigned long mask, volatile unsigned long *v);
+#
+###############################################################################
+	.globl		atomic_test_and_ANDNOT_mask
+        .type		atomic_test_and_ANDNOT_mask,@function
+atomic_test_and_ANDNOT_mask:
+	not.p		gr8,gr10
+0:
+	orcc		gr0,gr0,gr0,icc3		/* set ICC3.Z */
+	ckeq		icc3,cc7
+	ld.p		@(gr9,gr0),gr8			/* LD.P/ORCR must be atomic */
+	orcr		cc7,cc7,cc3			/* set CC3 to true */
+	and		gr8,gr10,gr11
+	cst.p		gr11,@(gr9,gr0)		,cc3,#1
+	corcc		gr29,gr29,gr0		,cc3,#1	/* clear ICC3.Z if store happens */
+	beq		icc3,#0,0b
+	bralr
+
+	.size		atomic_test_and_ANDNOT_mask, .-atomic_test_and_ANDNOT_mask
+
+###############################################################################
+#
+# unsigned long atomic_test_and_OR_mask(unsigned long mask, volatile unsigned long *v);
+#
+###############################################################################
+	.globl		atomic_test_and_OR_mask
+        .type		atomic_test_and_OR_mask,@function
+atomic_test_and_OR_mask:
+	or.p		gr8,gr8,gr10
+0:
+	orcc		gr0,gr0,gr0,icc3		/* set ICC3.Z */
+	ckeq		icc3,cc7
+	ld.p		@(gr9,gr0),gr8			/* LD.P/ORCR must be atomic */
+	orcr		cc7,cc7,cc3			/* set CC3 to true */
+	or		gr8,gr10,gr11
+	cst.p		gr11,@(gr9,gr0)		,cc3,#1
+	corcc		gr29,gr29,gr0		,cc3,#1	/* clear ICC3.Z if store happens */
+	beq		icc3,#0,0b
+	bralr
+
+	.size		atomic_test_and_OR_mask, .-atomic_test_and_OR_mask
+
+###############################################################################
+#
+# unsigned long atomic_test_and_XOR_mask(unsigned long mask, volatile unsigned long *v);
+#
+###############################################################################
+	.globl		atomic_test_and_XOR_mask
+        .type		atomic_test_and_XOR_mask,@function
+atomic_test_and_XOR_mask:
+	or.p		gr8,gr8,gr10
+0:
+	orcc		gr0,gr0,gr0,icc3		/* set ICC3.Z */
+	ckeq		icc3,cc7
+	ld.p		@(gr9,gr0),gr8			/* LD.P/ORCR must be atomic */
+	orcr		cc7,cc7,cc3			/* set CC3 to true */
+	xor		gr8,gr10,gr11
+	cst.p		gr11,@(gr9,gr0)		,cc3,#1
+	corcc		gr29,gr29,gr0		,cc3,#1	/* clear ICC3.Z if store happens */
+	beq		icc3,#0,0b
+	bralr
+
+	.size		atomic_test_and_XOR_mask, .-atomic_test_and_XOR_mask
+
+###############################################################################
+#
+# int atomic_add_return(int i, atomic_t *v)
+#
+###############################################################################
+	.globl		atomic_add_return
+        .type		atomic_add_return,@function
+atomic_add_return:
+	or.p		gr8,gr8,gr10
+0:
+	orcc		gr0,gr0,gr0,icc3		/* set ICC3.Z */
+	ckeq		icc3,cc7
+	ld.p		@(gr9,gr0),gr8			/* LD.P/ORCR must be atomic */
+	orcr		cc7,cc7,cc3			/* set CC3 to true */
+	add		gr8,gr10,gr8
+	cst.p		gr8,@(gr9,gr0)		,cc3,#1
+	corcc		gr29,gr29,gr0		,cc3,#1	/* clear ICC3.Z if store happens */
+	beq		icc3,#0,0b
+	bralr
+
+	.size		atomic_add_return, .-atomic_add_return
+
+###############################################################################
+#
+# int atomic_sub_return(int i, atomic_t *v)
+#
+###############################################################################
+	.globl		atomic_sub_return
+        .type		atomic_sub_return,@function
+atomic_sub_return:
+	or.p		gr8,gr8,gr10
+0:
+	orcc		gr0,gr0,gr0,icc3		/* set ICC3.Z */
+	ckeq		icc3,cc7
+	ld.p		@(gr9,gr0),gr8			/* LD.P/ORCR must be atomic */
+	orcr		cc7,cc7,cc3			/* set CC3 to true */
+	sub		gr8,gr10,gr8
+	cst.p		gr8,@(gr9,gr0)		,cc3,#1
+	corcc		gr29,gr29,gr0		,cc3,#1	/* clear ICC3.Z if store happens */
+	beq		icc3,#0,0b
+	bralr
+
+	.size		atomic_sub_return, .-atomic_sub_return
+
+###############################################################################
+#
+# uint8_t __xchg_8(uint8_t i, uint8_t *v)
+#
+###############################################################################
+	.globl		__xchg_8
+        .type		__xchg_8,@function
+__xchg_8:
+	or.p		gr8,gr8,gr10
+0:
+	orcc		gr0,gr0,gr0,icc3		/* set ICC3.Z */
+	ckeq		icc3,cc7
+	ldub.p		@(gr9,gr0),gr8			/* LD.P/ORCR must be atomic */
+	orcr		cc7,cc7,cc3			/* set CC3 to true */
+	cstb.p		gr10,@(gr9,gr0)		,cc3,#1
+	corcc		gr29,gr29,gr0		,cc3,#1	/* clear ICC3.Z if store happens */
+	beq		icc3,#0,0b
+	bralr
+
+	.size		__xchg_8, .-__xchg_8
+
+###############################################################################
+#
+# uint16_t __xchg_16(uint16_t i, uint16_t *v)
+#
+###############################################################################
+	.globl		__xchg_16
+        .type		__xchg_16,@function
+__xchg_16:
+	or.p		gr8,gr8,gr10
+0:
+	orcc		gr0,gr0,gr0,icc3		/* set ICC3.Z */
+	ckeq		icc3,cc7
+	lduh.p		@(gr9,gr0),gr8			/* LD.P/ORCR must be atomic */
+	orcr		cc7,cc7,cc3			/* set CC3 to true */
+	csth.p		gr10,@(gr9,gr0)		,cc3,#1
+	corcc		gr29,gr29,gr0		,cc3,#1	/* clear ICC3.Z if store happens */
+	beq		icc3,#0,0b
+	bralr
+
+	.size		__xchg_16, .-__xchg_16
+
+###############################################################################
+#
+# uint32_t __xchg_32(uint32_t i, uint32_t *v)
+#
+###############################################################################
+	.globl		__xchg_32
+        .type		__xchg_32,@function
+__xchg_32:
+	or.p		gr8,gr8,gr10
+0:
+	orcc		gr0,gr0,gr0,icc3		/* set ICC3.Z */
+	ckeq		icc3,cc7
+	ld.p		@(gr9,gr0),gr8			/* LD.P/ORCR must be atomic */
+	orcr		cc7,cc7,cc3			/* set CC3 to true */
+	cst.p		gr10,@(gr9,gr0)		,cc3,#1
+	corcc		gr29,gr29,gr0		,cc3,#1	/* clear ICC3.Z if store happens */
+	beq		icc3,#0,0b
+	bralr
+
+	.size		__xchg_32, .-__xchg_32
+
+###############################################################################
+#
+# uint8_t __cmpxchg_8(uint8_t *v, uint8_t test, uint8_t new)
+#
+###############################################################################
+	.globl		__cmpxchg_8
+        .type		__cmpxchg_8,@function
+__cmpxchg_8:
+	or.p		gr8,gr8,gr11
+0:
+	orcc		gr0,gr0,gr0,icc3
+	ckeq		icc3,cc7
+	ldub.p		@(gr11,gr0),gr8
+	orcr		cc7,cc7,cc3
+	sub		gr8,gr9,gr7
+	sllicc		gr7,#24,gr0,icc0
+	bne		icc0,#0,1f
+	cstb.p		gr10,@(gr11,gr0)	,cc3,#1
+	corcc		gr29,gr29,gr0		,cc3,#1
+	beq		icc3,#0,0b
+1:
+	bralr
+
+	.size		__cmpxchg_8, .-__cmpxchg_8
+
+###############################################################################
+#
+# uint16_t __cmpxchg_16(uint16_t *v, uint16_t test, uint16_t new)
+#
+###############################################################################
+	.globl		__cmpxchg_16
+        .type		__cmpxchg_16,@function
+__cmpxchg_16:
+	or.p		gr8,gr8,gr11
+0:
+	orcc		gr0,gr0,gr0,icc3
+	ckeq		icc3,cc7
+	lduh.p		@(gr11,gr0),gr8
+	orcr		cc7,cc7,cc3
+	sub		gr8,gr9,gr7
+	sllicc		gr7,#16,gr0,icc0
+	bne		icc0,#0,1f
+	csth.p		gr10,@(gr11,gr0)	,cc3,#1
+	corcc		gr29,gr29,gr0		,cc3,#1
+	beq		icc3,#0,0b
+1:
+	bralr
+
+	.size		__cmpxchg_16, .-__cmpxchg_16
+
+###############################################################################
+#
+# uint32_t __cmpxchg_32(uint32_t *v, uint32_t test, uint32_t new)
+#
+###############################################################################
+	.globl		__cmpxchg_32
+        .type		__cmpxchg_32,@function
+__cmpxchg_32:
+	or.p		gr8,gr8,gr11
+0:
+	orcc		gr0,gr0,gr0,icc3
+	ckeq		icc3,cc7
+	ld.p		@(gr11,gr0),gr8
+	orcr		cc7,cc7,cc3
+	subcc		gr8,gr9,gr7,icc0
+	bne		icc0,#0,1f
+	cst.p		gr10,@(gr11,gr0)	,cc3,#1
+	corcc		gr29,gr29,gr0		,cc3,#1
+	beq		icc3,#0,0b
+1:
+	bralr
+
+	.size		__cmpxchg_32, .-__cmpxchg_32
diff -Nru a/arch/frv/lib/cache.S b/arch/frv/lib/cache.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/lib/cache.S	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,98 @@
+/* cache.S: cache managment routines
+ *
+ * Copyright (C) 2004 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 <asm/spr-regs.h>
+#include <asm/cache.h>
+
+        .text
+        .p2align	4
+
+###############################################################################
+#
+# Write back a range of dcache
+# - void frv_dcache_writeback(unsigned long start [GR8], unsigned long size [GR9])
+#
+###############################################################################
+        .globl		frv_dcache_writeback
+        .type		frv_dcache_writeback,@function
+frv_dcache_writeback:
+	andi		gr8,~(L1_CACHE_BYTES-1),gr8
+
+2:	dcf		@(gr8,gr0)
+	addi		gr8,#L1_CACHE_BYTES,gr8
+	cmp		gr9,gr8,icc0
+	bhi		icc0,#2,2b
+
+	membar
+	bralr
+	.size		frv_dcache_writeback, .-frv_dcache_writeback
+
+##############################################################################
+#
+# Invalidate a range of dcache and icache
+# - void frv_cache_invalidate(unsigned long start [GR8], unsigned long end [GR9]);
+#
+###############################################################################
+        .globl		frv_cache_invalidate
+        .type		frv_cache_invalidate,@function
+frv_cache_invalidate:
+	andi		gr8,~(L1_CACHE_BYTES-1),gr8
+
+2:	dci		@(gr8,gr0)
+	ici		@(gr8,gr0)
+	addi		gr8,#L1_CACHE_BYTES,gr8
+	cmp		gr9,gr8,icc0
+	bhi		icc0,#2,2b
+
+	membar
+	bralr
+	.size		frv_cache_invalidate, .-frv_cache_invalidate
+
+##############################################################################
+#
+# Invalidate a range of icache
+# - void frv_icache_invalidate(unsigned long start [GR8], unsigned long end [GR9]);
+#
+###############################################################################
+        .globl		frv_icache_invalidate
+        .type		frv_icache_invalidate,@function
+frv_icache_invalidate:
+	andi		gr8,~(L1_CACHE_BYTES-1),gr8
+
+2:	ici		@(gr8,gr0)
+	addi		gr8,#L1_CACHE_BYTES,gr8
+	cmp		gr9,gr8,icc0
+	bhi		icc0,#2,2b
+
+	membar
+	bralr
+	.size		frv_icache_invalidate, .-frv_icache_invalidate
+
+###############################################################################
+#
+# Write back and invalidate a range of dcache and icache
+# - void frv_cache_wback_inv(unsigned long start [GR8], unsigned long end [GR9])
+#
+###############################################################################
+        .globl		frv_cache_wback_inv
+        .type		frv_cache_wback_inv,@function
+frv_cache_wback_inv:
+	andi		gr8,~(L1_CACHE_BYTES-1),gr8
+
+2:	dcf		@(gr8,gr0)
+	ici		@(gr8,gr0)
+	addi		gr8,#L1_CACHE_BYTES,gr8
+	cmp		gr9,gr8,icc0
+	bhi		icc0,#2,2b
+
+	membar
+	bralr
+	.size		frv_cache_wback_inv, .-frv_cache_wback_inv
diff -Nru a/arch/frv/lib/checksum.c b/arch/frv/lib/checksum.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/lib/checksum.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,148 @@
+/*
+ * 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
+ *
+ * Authors:	Jorge Cwik, <jorge@laser.satlink.net>
+ *		Arnt Gulbrandsen, <agulbra@nvg.unit.no>
+ *		Tom May, <ftom@netcom.com>
+ *		Andreas Schwab, <schwab@issan.informatik.uni-dortmund.de>
+ *		Lots of code moved from tcp.c and ip.c; see those files
+ *		for more names.
+ *
+ * 03/02/96	Jes Sorensen, Andreas Schwab, Roman Hodek:
+ *		Fixed some nasty bugs, causing some horrible crashes.
+ *		A: At some points, the sum (%0) was used as
+ *		length-counter instead of the length counter
+ *		(%1). Thanks to Roman Hodek for pointing this out.
+ *		B: GCC seems to mess up if one uses too many
+ *		data-registers to hold input values and one tries to
+ *		specify d0 and d1 as scratch registers. Letting gcc choose these
+ *      registers itself solves the problem.
+ *
+ *		This program is free software; you can redistribute it and/or
+ *		modify it under the terms of the GNU General Public License
+ *		as published by the Free Software Foundation; either version
+ *		2 of the License, or (at your option) any later version.
+ */
+
+/* Revised by Kenneth Albanowski for m68knommu. Basic problem: unaligned access kills, so most
+   of the assembly has to go. */
+
+#include <net/checksum.h>
+#include <asm/checksum.h>
+
+static inline unsigned short from32to16(unsigned long x)
+{
+	/* add up 16-bit and 16-bit for 16+c bit */
+	x = (x & 0xffff) + (x >> 16);
+	/* add up carry.. */
+	x = (x & 0xffff) + (x >> 16);
+	return x;
+}
+
+static unsigned long do_csum(const unsigned char * buff, int len)
+{
+	int odd, count;
+	unsigned long result = 0;
+
+	if (len <= 0)
+		goto out;
+	odd = 1 & (unsigned long) buff;
+	if (odd) {
+		result = *buff;
+		len--;
+		buff++;
+	}
+	count = len >> 1;		/* nr of 16-bit words.. */
+	if (count) {
+		if (2 & (unsigned long) buff) {
+			result += *(unsigned short *) buff;
+			count--;
+			len -= 2;
+			buff += 2;
+		}
+		count >>= 1;		/* nr of 32-bit words.. */
+		if (count) {
+		        unsigned long carry = 0;
+			do {
+				unsigned long w = *(unsigned long *) buff;
+				count--;
+				buff += 4;
+				result += carry;
+				result += w;
+				carry = (w > result);
+			} while (count);
+			result += carry;
+			result = (result & 0xffff) + (result >> 16);
+		}
+		if (len & 2) {
+			result += *(unsigned short *) buff;
+			buff += 2;
+		}
+	}
+	if (len & 1)
+		result += (*buff << 8);
+	result = from32to16(result);
+	if (odd)
+		result = ((result >> 8) & 0xff) | ((result & 0xff) << 8);
+out:
+	return result;
+}
+
+/*
+ * 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
+ */
+unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum)
+{
+	unsigned int result = do_csum(buff, len);
+
+	/* add in old sum, and carry.. */
+	result += sum;
+	if (sum > result)
+		result += 1;
+	return result;
+}
+
+/*
+ * this routine is used for miscellaneous IP-like checksums, mainly
+ * in icmp.c
+ */
+unsigned short ip_compute_csum(const unsigned char * buff, int len)
+{
+	return ~do_csum(buff,len);
+}
+
+/*
+ * copy from fs while checksumming, otherwise like csum_partial
+ */
+
+unsigned int
+csum_partial_copy_from_user(const char *src, char *dst, int len, int sum, int *csum_err)
+{
+	if (csum_err) *csum_err = 0;
+	memcpy(dst, src, len);
+	return csum_partial(dst, len, sum);
+}
+
+/*
+ * copy from ds while checksumming, otherwise like csum_partial
+ */
+
+unsigned int
+csum_partial_copy(const char *src, char *dst, int len, int sum)
+{
+	memcpy(dst, src, len);
+	return csum_partial(dst, len, sum);
+}
diff -Nru a/arch/frv/lib/insl_ns.S b/arch/frv/lib/insl_ns.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/lib/insl_ns.S	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,52 @@
+/* insl_ns.S: input array of 4b words from device port without byte swapping
+ *
+ * Copyright (C) 2003 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.
+ */
+
+
+        .text
+        .p2align	4
+
+###############################################################################
+#
+# void __insl_ns(unsigned int port, void *buf, int n)
+#
+###############################################################################
+        .globl		__insl_ns
+        .type		__insl_ns,@function
+__insl_ns:
+	andicc.p	gr9,#3,gr0,icc0
+	setlos		#4,gr4
+	bne		icc0,#0,__insl_ns_misaligned
+	subi		gr9,#4,gr9
+0:
+	ldi.p		@(gr8,#0),gr5
+	subicc		gr10,#1,gr10,icc0
+	stu.p		gr5,@(gr9,gr4)
+	bhi		icc0,#2,0b
+	bralr
+
+__insl_ns_misaligned:
+	subi.p		gr9,#1,gr9
+	setlos		#1,gr4
+0:
+	ldi		@(gr8,#0),gr5
+
+	srli		gr5,#24,gr6
+	stbu.p		gr6,@(gr9,gr4)
+	srli		gr5,#16,gr6
+	stbu.p		gr6,@(gr9,gr4)
+	srli		gr5,#8,gr6
+	stbu.p		gr6,@(gr9,gr4)
+	subicc		gr10,#1,gr10,icc0
+	stbu.p		gr5,@(gr9,gr4)
+	bhi		icc0,#2,0b
+	bralr
+
+	.size		__insl_ns, .-__insl_ns
diff -Nru a/arch/frv/lib/insl_sw.S b/arch/frv/lib/insl_sw.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/lib/insl_sw.S	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,40 @@
+/* insl_sw.S: input array of 4b words from device port with byte swapping
+ *
+ * Copyright (C) 2003 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.
+ */
+
+
+        .text
+        .p2align	4
+
+###############################################################################
+#
+# void __insl_sw(unsigned int port, void *buf, int n)
+#
+###############################################################################
+        .globl		__insl_sw
+        .type		__insl_sw,@function
+__insl_sw:
+	subi.p		gr9,#1,gr9
+	setlos		#1,gr4
+0:
+	ldi.p		@(gr8,#0),gr5		; get 0xAABBCCDD
+	subicc		gr10,#1,gr10,icc0
+
+	stbu.p		gr5,@(gr9,gr4)		; write 0xDD
+	srli		gr5,#8,gr5
+	stbu.p		gr5,@(gr9,gr4)		; write 0xCC
+	srli		gr5,#8,gr5
+	stbu.p		gr5,@(gr9,gr4)		; write 0xBB
+	srli		gr5,#8,gr5
+	stbu.p		gr5,@(gr9,gr4)		; write 0xAA
+	bhi		icc0,#2,0b
+	bralr
+
+	.size		__insl_sw, .-__insl_sw
diff -Nru a/arch/frv/lib/memcpy.S b/arch/frv/lib/memcpy.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/lib/memcpy.S	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,135 @@
+/* memcpy.S: optimised assembly memcpy
+ *
+ * Copyright (C) 2003 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.
+ */
+
+
+        .text
+        .p2align	4
+
+###############################################################################
+#
+# void *memcpy(void *to, const char *from, size_t count)
+#
+# - NOTE: must not use any stack. exception detection performs function return
+#         to caller's fixup routine, aborting the remainder of the copy
+#
+###############################################################################
+        .globl		memcpy,__memcpy_end
+        .type		memcpy,@function
+memcpy:
+	or.p		gr8,gr9,gr4
+	orcc		gr10,gr0,gr0,icc3
+	or.p		gr10,gr4,gr4
+	beqlr		icc3,#0
+
+	# optimise based on best common alignment for to, from & count
+	andicc.p	gr4,#0x0f,gr0,icc0
+	setlos		#8,gr11
+	andicc.p	gr4,#0x07,gr0,icc1
+	beq		icc0,#0,memcpy_16
+	andicc.p	gr4,#0x03,gr0,icc0
+	beq		icc1,#0,memcpy_8
+	andicc.p	gr4,#0x01,gr0,icc1
+	beq		icc0,#0,memcpy_4
+	setlos.p	#1,gr11
+	beq		icc1,#0,memcpy_2
+
+	# do byte by byte copy
+	sub.p		gr8,gr11,gr3
+	sub		gr9,gr11,gr9
+0:	ldubu.p		@(gr9,gr11),gr4
+	subicc		gr10,#1,gr10,icc0
+	stbu.p		gr4,@(gr3,gr11)
+	bne		icc0,#2,0b
+	bralr
+
+	# do halfword by halfword copy
+memcpy_2:
+	setlos		#2,gr11
+	sub.p		gr8,gr11,gr3
+	sub		gr9,gr11,gr9
+0:	lduhu.p		@(gr9,gr11),gr4
+	subicc		gr10,#2,gr10,icc0
+	sthu.p		gr4,@(gr3,gr11)
+	bne		icc0,#2,0b
+	bralr
+
+	# do word by word copy
+memcpy_4:
+	setlos		#4,gr11
+	sub.p		gr8,gr11,gr3
+	sub		gr9,gr11,gr9
+0:	ldu.p		@(gr9,gr11),gr4
+	subicc		gr10,#4,gr10,icc0
+	stu.p		gr4,@(gr3,gr11)
+	bne		icc0,#2,0b
+	bralr
+
+	# do double-word by double-word copy
+memcpy_8:
+	sub.p		gr8,gr11,gr3
+	sub		gr9,gr11,gr9
+0:	lddu.p		@(gr9,gr11),gr4
+	subicc		gr10,#8,gr10,icc0
+	stdu.p		gr4,@(gr3,gr11)
+	bne		icc0,#2,0b
+	bralr
+
+	# do quad-word by quad-word copy
+memcpy_16:
+	sub.p		gr8,gr11,gr3
+	sub		gr9,gr11,gr9
+0:	lddu		@(gr9,gr11),gr4
+	lddu.p		@(gr9,gr11),gr6
+	subicc		gr10,#16,gr10,icc0
+	stdu		gr4,@(gr3,gr11)
+	stdu.p		gr6,@(gr3,gr11)
+	bne		icc0,#2,0b
+	bralr
+__memcpy_end:
+
+	.size		memcpy, __memcpy_end-memcpy
+
+###############################################################################
+#
+# copy to/from userspace
+# - return the number of bytes that could not be copied (0 on complete success)
+#
+# long __memcpy_user(void *dst, const void *src, size_t count)
+#
+###############################################################################
+        .globl		__memcpy_user, __memcpy_user_error_lr, __memcpy_user_error_handler
+        .type		__memcpy_user,@function
+__memcpy_user:
+	movsg		lr,gr7
+	subi.p		sp,#8,sp
+	add		gr8,gr10,gr6		; calculate expected end address
+	stdi		gr6,@(sp,#0)
+
+	# abuse memcpy to do the dirty work
+	call		memcpy
+__memcpy_user_error_lr:
+	ldi.p		@(sp,#4),gr7
+	setlos		#0,gr8
+	jmpl.p		@(gr7,gr0)
+	addi		sp,#8,sp
+
+	# deal any exception generated by memcpy
+	# GR8 - memcpy's current dest address
+	# GR11 - memset's step value (index register for store insns)
+__memcpy_user_error_handler:
+	lddi.p		@(sp,#0),gr4		; load GR4 with dst+count, GR5 with ret addr
+	add		gr11,gr3,gr7
+	sub.p		gr4,gr7,gr8
+
+	addi		sp,#8,sp
+	jmpl		@(gr5,gr0)
+
+	.size		__memcpy_user, .-__memcpy_user
diff -Nru a/arch/frv/lib/memset.S b/arch/frv/lib/memset.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/lib/memset.S	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,182 @@
+/* memset.S: optimised assembly memset
+ *
+ * Copyright (C) 2003 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.
+ */
+
+
+        .text
+        .p2align	4
+
+###############################################################################
+#
+# void *memset(void *p, char ch, size_t count)
+#
+# - NOTE: must not use any stack. exception detection performs function return
+#         to caller's fixup routine, aborting the remainder of the set
+#         GR4, GR7, GR8, and GR11 must be managed
+#
+###############################################################################
+        .globl		memset,__memset_end
+        .type		memset,@function
+memset:
+	orcc.p		gr10,gr0,gr5,icc3		; GR5 = count
+	andi		gr9,#0xff,gr9
+	or.p		gr8,gr0,gr4			; GR4 = address
+	beqlr		icc3,#0
+
+	# conditionally write a byte to 2b-align the address
+	setlos.p	#1,gr6
+	andicc		gr4,#1,gr0,icc0
+	ckne		icc0,cc7
+	cstb.p		gr9,@(gr4,gr0)		,cc7,#1
+	csubcc		gr5,gr6,gr5		,cc7,#1	; also set ICC3
+	cadd.p		gr4,gr6,gr4		,cc7,#1
+	beqlr		icc3,#0
+
+	# conditionally write a word to 4b-align the address
+	andicc.p	gr4,#2,gr0,icc0
+	subicc		gr5,#2,gr0,icc1
+	setlos.p	#2,gr6
+	ckne		icc0,cc7
+	slli.p		gr9,#8,gr12			; need to double up the pattern
+	cknc		icc1,cc5
+	or.p		gr9,gr12,gr12
+	andcr		cc7,cc5,cc7
+
+	csth.p		gr12,@(gr4,gr0)		,cc7,#1
+	csubcc		gr5,gr6,gr5		,cc7,#1	; also set ICC3
+	cadd.p		gr4,gr6,gr4		,cc7,#1
+	beqlr		icc3,#0
+
+	# conditionally write a dword to 8b-align the address
+	andicc.p	gr4,#4,gr0,icc0
+	subicc		gr5,#4,gr0,icc1
+	setlos.p	#4,gr6
+	ckne		icc0,cc7
+	slli.p		gr12,#16,gr13			; need to quadruple-up the pattern
+	cknc		icc1,cc5
+	or.p		gr13,gr12,gr12
+	andcr		cc7,cc5,cc7
+
+	cst.p		gr12,@(gr4,gr0)		,cc7,#1
+	csubcc		gr5,gr6,gr5		,cc7,#1	; also set ICC3
+	cadd.p		gr4,gr6,gr4		,cc7,#1
+	beqlr		icc3,#0
+
+	or.p		gr12,gr12,gr13			; need to octuple-up the pattern
+
+	# the address is now 8b-aligned - loop around writing 64b chunks
+	setlos		#8,gr7
+	subi.p		gr4,#8,gr4			; store with update index does weird stuff
+	setlos		#64,gr6
+
+	subicc		gr5,#64,gr0,icc0
+0:	cknc		icc0,cc7
+	cstdu		gr12,@(gr4,gr7)		,cc7,#1
+	cstdu		gr12,@(gr4,gr7)		,cc7,#1
+	cstdu		gr12,@(gr4,gr7)		,cc7,#1
+	cstdu		gr12,@(gr4,gr7)		,cc7,#1
+	cstdu		gr12,@(gr4,gr7)		,cc7,#1
+	cstdu.p		gr12,@(gr4,gr7)		,cc7,#1
+	csubcc		gr5,gr6,gr5		,cc7,#1	; also set ICC3
+	cstdu.p		gr12,@(gr4,gr7)		,cc7,#1
+	subicc		gr5,#64,gr0,icc0
+	cstdu.p		gr12,@(gr4,gr7)		,cc7,#1
+	beqlr		icc3,#0
+	bnc		icc0,#2,0b
+
+	# now do 32-byte remnant
+	subicc.p	gr5,#32,gr0,icc0
+	setlos		#32,gr6
+	cknc		icc0,cc7
+	cstdu.p		gr12,@(gr4,gr7)		,cc7,#1
+	csubcc		gr5,gr6,gr5		,cc7,#1	; also set ICC3
+	cstdu.p		gr12,@(gr4,gr7)		,cc7,#1
+	setlos		#16,gr6
+	cstdu.p		gr12,@(gr4,gr7)		,cc7,#1
+	subicc		gr5,#16,gr0,icc0
+	cstdu.p		gr12,@(gr4,gr7)		,cc7,#1
+	beqlr		icc3,#0
+
+	# now do 16-byte remnant
+	cknc		icc0,cc7
+	cstdu.p		gr12,@(gr4,gr7)		,cc7,#1
+	csubcc		gr5,gr6,gr5		,cc7,#1	; also set ICC3
+	cstdu.p		gr12,@(gr4,gr7)		,cc7,#1
+	beqlr		icc3,#0
+
+	# now do 8-byte remnant
+	subicc		gr5,#8,gr0,icc1
+	cknc		icc1,cc7
+	cstdu.p		gr12,@(gr4,gr7)		,cc7,#1
+	csubcc		gr5,gr7,gr5		,cc7,#1	; also set ICC3
+	setlos.p	#4,gr7
+	beqlr		icc3,#0
+
+	# now do 4-byte remnant
+	subicc		gr5,#4,gr0,icc0
+	addi.p		gr4,#4,gr4
+	cknc		icc0,cc7
+	cstu.p		gr12,@(gr4,gr7)		,cc7,#1
+	csubcc		gr5,gr7,gr5		,cc7,#1	; also set ICC3
+	subicc.p	gr5,#2,gr0,icc1
+	beqlr		icc3,#0
+
+	# now do 2-byte remnant
+	setlos		#2,gr7
+	addi.p		gr4,#2,gr4
+	cknc		icc1,cc7
+	csthu.p		gr12,@(gr4,gr7)		,cc7,#1
+	csubcc		gr5,gr7,gr5		,cc7,#1	; also set ICC3
+	subicc.p	gr5,#1,gr0,icc0
+	beqlr		icc3,#0
+
+	# now do 1-byte remnant
+	setlos		#0,gr7
+	addi.p		gr4,#2,gr4
+	cknc		icc0,cc7
+	cstb.p		gr12,@(gr4,gr0)		,cc7,#1
+	bralr
+__memset_end:
+
+	.size		memset, __memset_end-memset
+
+###############################################################################
+#
+# clear memory in userspace
+# - return the number of bytes that could not be cleared (0 on complete success)
+#
+# long __memset_user(void *p, size_t count)
+#
+###############################################################################
+        .globl		__memset_user, __memset_user_error_lr, __memset_user_error_handler
+        .type		__memset_user,@function
+__memset_user:
+	movsg		lr,gr11
+
+	# abuse memset to do the dirty work
+	or.p		gr9,gr9,gr10
+	setlos		#0,gr9
+	call		memset
+__memset_user_error_lr:
+	jmpl.p		@(gr11,gr0)
+	setlos		#0,gr8
+
+	# deal any exception generated by memset
+	# GR4  - memset's address tracking pointer
+	# GR7  - memset's step value (index register for store insns)
+	# GR8  - memset's original start address
+	# GR10 - memset's original count
+__memset_user_error_handler:
+	add.p		gr4,gr7,gr4
+	add		gr8,gr10,gr8
+	jmpl.p		@(gr11,gr0)
+	sub		gr8,gr4,gr8		; we return the amount left uncleared
+
+	.size		__memset_user, .-__memset_user
diff -Nru a/arch/frv/lib/outsl_ns.S b/arch/frv/lib/outsl_ns.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/lib/outsl_ns.S	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,59 @@
+/* outsl_ns.S: output array of 4b words to device without byte swapping
+ *
+ * Copyright (C) 2003 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.
+ */
+
+
+        .text
+        .p2align	4
+
+###############################################################################
+#
+# void __outsl_ns(unsigned int port, const void *buf, int n)
+#
+###############################################################################
+        .globl		__outsl_ns
+        .type		__outsl_ns,@function
+__outsl_ns:
+	andicc.p	gr9,#3,gr0,icc0
+	setlos		#4,gr4
+	bne		icc0,#0,__outsl_ns_misaligned
+	subi		gr9,#4,gr9
+0:
+	ldu.p		@(gr9,gr4),gr5
+	subicc		gr10,#1,gr10,icc0
+	sti.p		gr5,@(gr8,#0)
+	bhi		icc0,#2,0b
+
+	membar
+	bralr
+
+__outsl_ns_misaligned:
+	subi.p		gr9,#1,gr9
+	setlos		#1,gr4
+0:
+	ldubu		@(gr9,gr4),gr5
+	ldubu.p		@(gr9,gr4),gr6
+	slli		gr5,#8,gr5
+	ldubu.p		@(gr9,gr4),gr7
+	or		gr5,gr6,gr5
+	ldubu.p		@(gr9,gr4),gr6
+	slli		gr5,#16,gr5
+	slli.p		gr7,#8,gr7
+	or		gr5,gr6,gr5
+	subicc.p	gr10,#1,gr10,icc0
+	or		gr5,gr7,gr5
+
+	sti.p		gr5,@(gr8,#0)
+	bhi		icc0,#2,0b
+
+	membar
+	bralr
+
+	.size		__outsl_ns, .-__outsl_ns
diff -Nru a/arch/frv/lib/outsl_sw.S b/arch/frv/lib/outsl_sw.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/lib/outsl_sw.S	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,45 @@
+/* outsl_ns.S: output array of 4b words to device with byte swapping
+ *
+ * Copyright (C) 2003 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.
+ */
+
+
+        .text
+        .p2align	4
+
+###############################################################################
+#
+# void __outsl_sw(unsigned int port, const void *buf, int n)
+#
+###############################################################################
+        .globl		__outsl_sw
+        .type		__outsl_sw,@function
+__outsl_sw:
+	subi.p		gr9,#1,gr9
+	setlos		#1,gr4
+0:
+	ldubu		@(gr9,gr4),gr5
+	ldubu		@(gr9,gr4),gr6
+	slli		gr6,#8,gr6
+	ldubu.p		@(gr9,gr4),gr7
+	or		gr5,gr6,gr5
+	ldubu.p		@(gr9,gr4),gr6
+	slli		gr7,#16,gr7
+	slli.p		gr6,#24,gr6
+	or		gr5,gr7,gr5
+	subicc.p	gr10,#1,gr10,icc0
+	or		gr5,gr6,gr5
+
+	sti.p		gr5,@(gr8,#0)
+	bhi		icc0,#2,0b
+
+	membar
+	bralr
+
+	.size		__outsl_sw, .-__outsl_sw
diff -Nru a/arch/frv/mb93090-mb00/Makefile b/arch/frv/mb93090-mb00/Makefile
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/mb93090-mb00/Makefile	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,13 @@
+#
+# Makefile for the MB93090-MB00 motherboard stuff
+#
+
+ifeq "$(CONFIG_PCI)" "y"
+obj-y := pci-frv.o pci-irq.o pci-vdk.o
+
+ifeq "$(CONFIG_MMU)" "y"
+obj-y += pci-dma.o
+else
+obj-y += pci-dma-nommu.o
+endif
+endif
diff -Nru a/arch/frv/mb93090-mb00/pci-dma-nommu.c b/arch/frv/mb93090-mb00/pci-dma-nommu.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/mb93090-mb00/pci-dma-nommu.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,152 @@
+/* pci-dma-nommu.c: Dynamic DMA mapping support for the FRV
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Woodhouse (dwmw2@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/dma-mapping.h>
+#include <linux/list.h>
+#include <linux/pci.h>
+#include <asm/io.h>
+
+#if 1
+#define DMA_SRAM_START	dma_coherent_mem_start
+#define DMA_SRAM_END	dma_coherent_mem_end
+#else // Use video RAM on Matrox
+#define DMA_SRAM_START	0xe8900000
+#define DMA_SRAM_END	0xe8a00000
+#endif
+
+struct dma_alloc_record {
+	struct list_head	list;
+	unsigned long		ofs;
+	unsigned long		len;
+};
+
+static DEFINE_SPINLOCK(dma_alloc_lock);
+static LIST_HEAD(dma_alloc_list);
+
+void *dma_alloc_coherent(struct device *hwdev, size_t size, dma_addr_t *dma_handle, int gfp)
+{
+	struct dma_alloc_record *new;
+	struct list_head *this = &dma_alloc_list;
+	unsigned long flags;
+	unsigned long start = DMA_SRAM_START;
+	unsigned long end;
+
+	if (!DMA_SRAM_START) {
+		printk("%s called without any DMA area reserved!\n", __func__);
+		return NULL;
+	}
+
+	new = kmalloc(sizeof (*new), GFP_ATOMIC);
+	if (!new)
+		return NULL;
+
+	/* Round up to a reasonable alignment */
+	new->len = (size + 31) & ~31;
+
+	spin_lock_irqsave(&dma_alloc_lock, flags);
+
+	list_for_each (this, &dma_alloc_list) {
+		struct dma_alloc_record *this_r = list_entry(this, struct dma_alloc_record, list);
+		end = this_r->ofs;
+
+		if (end - start >= size)
+			goto gotone;
+
+		start = this_r->ofs + this_r->len;
+	}
+	/* Reached end of list. */
+	end = DMA_SRAM_END;
+	this = &dma_alloc_list;
+
+	if (end - start >= size) {
+	gotone:
+		new->ofs = start;
+		list_add_tail(&new->list, this);
+		spin_unlock_irqrestore(&dma_alloc_lock, flags);
+
+		*dma_handle = start;
+		return (void *)start;
+	}
+
+	kfree(new);
+	spin_unlock_irqrestore(&dma_alloc_lock, flags);
+	return NULL;
+}
+
+void dma_free_coherent(struct device *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle)
+{
+	struct dma_alloc_record *rec;
+	unsigned long flags;
+
+	spin_lock_irqsave(&dma_alloc_lock, flags);
+
+	list_for_each_entry(rec, &dma_alloc_list, list) {
+		if (rec->ofs == dma_handle) {
+			list_del(&rec->list);
+			kfree(rec);
+			spin_unlock_irqrestore(&dma_alloc_lock, flags);
+			return;
+		}
+	}
+	spin_unlock_irqrestore(&dma_alloc_lock, flags);
+	BUG();
+}
+
+/*
+ * Map a single buffer of the indicated size for DMA in streaming mode.
+ * The 32-bit bus address to use is returned.
+ *
+ * Once the device is given the dma address, the device owns this memory
+ * until either pci_unmap_single or pci_dma_sync_single is performed.
+ */
+dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
+			  enum dma_data_direction direction)
+{
+	if (direction == DMA_NONE)
+                BUG();
+
+	frv_cache_wback_inv((unsigned long) ptr, (unsigned long) ptr + size);
+
+	return virt_to_bus(ptr);
+}
+
+/*
+ * Map a set of buffers described by scatterlist in streaming
+ * mode for DMA.  This is the scather-gather version of the
+ * above pci_map_single interface.  Here the scatter gather list
+ * elements are each tagged with the appropriate dma address
+ * and length.  They are obtained via sg_dma_{address,length}(SG).
+ *
+ * NOTE: An implementation may be able to use a smaller number of
+ *       DMA address/length pairs than there are SG table elements.
+ *       (for example via virtual mapping capabilities)
+ *       The routine returns the number of addr/length pairs actually
+ *       used, at most nents.
+ *
+ * Device ownership issues as mentioned above for pci_map_single are
+ * the same here.
+ */
+int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+	       enum dma_data_direction direction)
+{
+	int i;
+
+	for (i=0; i<nents; i++)
+		frv_cache_wback_inv(sg_dma_address(&sg[i]),
+				    sg_dma_address(&sg[i]) + sg_dma_len(&sg[i]));
+
+	if (direction == DMA_NONE)
+                BUG();
+
+	return nents;
+}
diff -Nru a/arch/frv/mb93090-mb00/pci-dma.c b/arch/frv/mb93090-mb00/pci-dma.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/mb93090-mb00/pci-dma.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,105 @@
+/* pci-dma.c: Dynamic DMA mapping support for the FRV CPUs that have MMUs
+ *
+ * Copyright (C) 2004 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/types.h>
+#include <linux/slab.h>
+#include <linux/dma-mapping.h>
+#include <linux/list.h>
+#include <linux/pci.h>
+#include <linux/highmem.h>
+#include <asm/io.h>
+
+void *dma_alloc_coherent(struct device *hwdev, size_t size, dma_addr_t *dma_handle, int gfp)
+{
+	void *ret;
+
+	ret = consistent_alloc(gfp, size, dma_handle);
+	if (ret)
+		memset(ret, 0, size);
+
+	return ret;
+}
+
+void dma_free_coherent(struct device *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle)
+{
+	consistent_free(vaddr);
+}
+
+/*
+ * Map a single buffer of the indicated size for DMA in streaming mode.
+ * The 32-bit bus address to use is returned.
+ *
+ * Once the device is given the dma address, the device owns this memory
+ * until either pci_unmap_single or pci_dma_sync_single is performed.
+ */
+dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
+			  enum dma_data_direction direction)
+{
+	if (direction == DMA_NONE)
+                BUG();
+
+	frv_cache_wback_inv((unsigned long) ptr, (unsigned long) ptr + size);
+
+	return virt_to_bus(ptr);
+}
+
+/*
+ * Map a set of buffers described by scatterlist in streaming
+ * mode for DMA.  This is the scather-gather version of the
+ * above pci_map_single interface.  Here the scatter gather list
+ * elements are each tagged with the appropriate dma address
+ * and length.  They are obtained via sg_dma_{address,length}(SG).
+ *
+ * NOTE: An implementation may be able to use a smaller number of
+ *       DMA address/length pairs than there are SG table elements.
+ *       (for example via virtual mapping capabilities)
+ *       The routine returns the number of addr/length pairs actually
+ *       used, at most nents.
+ *
+ * Device ownership issues as mentioned above for pci_map_single are
+ * the same here.
+ */
+int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+	       enum dma_data_direction direction)
+{
+	unsigned long dampr2;
+	void *vaddr;
+	int i;
+
+	if (direction == DMA_NONE)
+                BUG();
+
+	dampr2 = __get_DAMPR(2);
+
+	for (i = 0; i < nents; i++) {
+		vaddr = kmap_atomic(sg[i].page, __KM_CACHE);
+
+		frv_dcache_writeback((unsigned long) vaddr,
+				     (unsigned long) vaddr + PAGE_SIZE);
+
+	}
+
+	kunmap_atomic(vaddr, __KM_CACHE);
+	if (dampr2) {
+		__set_DAMPR(2, dampr2);
+		__set_IAMPR(2, dampr2);
+	}
+
+	return nents;
+}
+
+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);
+	flush_dcache_page(page);
+	return (dma_addr_t) page_to_phys(page) + offset;
+}
diff -Nru a/arch/frv/mb93090-mb00/pci-frv.c b/arch/frv/mb93090-mb00/pci-frv.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/mb93090-mb00/pci-frv.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,288 @@
+/* pci-frv.c: low-level PCI access routines
+ *
+ * Copyright (C) 2003-5 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ * - Derived from the i386 equivalent stuff
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/errno.h>
+
+#include "pci-frv.h"
+
+#if 0
+void
+pcibios_update_resource(struct pci_dev *dev, struct resource *root,
+			struct resource *res, int resource)
+{
+	u32 new, check;
+	int reg;
+
+	new = res->start | (res->flags & PCI_REGION_FLAG_MASK);
+	if (resource < 6) {
+		reg = PCI_BASE_ADDRESS_0 + 4*resource;
+	} else if (resource == PCI_ROM_RESOURCE) {
+		res->flags |= PCI_ROM_ADDRESS_ENABLE;
+		new |= PCI_ROM_ADDRESS_ENABLE;
+		reg = dev->rom_base_reg;
+	} else {
+		/* Somebody might have asked allocation of a non-standard resource */
+		return;
+	}
+
+	pci_write_config_dword(dev, reg, new);
+	pci_read_config_dword(dev, reg, &check);
+	if ((new ^ check) & ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK)) {
+		printk(KERN_ERR "PCI: Error while updating region "
+		       "%s/%d (%08x != %08x)\n", dev->slot_name, resource,
+		       new, check);
+	}
+}
+#endif
+
+/*
+ * 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)
+{
+	if (res->flags & IORESOURCE_IO) {
+		unsigned long start = res->start;
+
+		if (start & 0x300) {
+			start = (start + 0x3ff) & ~0x3ff;
+			res->start = start;
+		}
+	}
+}
+
+
+/*
+ *  Handle resources of PCI devices.  If the world were perfect, we could
+ *  just allocate all the resource regions and do nothing more.  It isn't.
+ *  On the other hand, we cannot just re-allocate all devices, as it would
+ *  require us to know lots of host bridge internals.  So we attempt to
+ *  keep as much of the original configuration as possible, but tweak it
+ *  when it's found to be wrong.
+ *
+ *  Known BIOS problems we have to work around:
+ *	- I/O or memory regions not configured
+ *	- regions configured, but not enabled in the command register
+ *	- bogus I/O addresses above 64K used
+ *	- expansion ROMs left enabled (this may sound harmless, but given
+ *	  the fact the PCI specs explicitly allow address decoders to be
+ *	  shared between expansion ROMs and other resource regions, it's
+ *	  at least dangerous)
+ *
+ *  Our solution:
+ *	(1) Allocate resources for all buses behind PCI-to-PCI bridges.
+ *	    This gives us fixed barriers on where we can allocate.
+ *	(2) Allocate resources for all enabled devices.  If there is
+ *	    a collision, just mark the resource as unallocated. Also
+ *	    disable expansion ROMs during this step.
+ *	(3) Try to allocate resources for disabled devices.  If the
+ *	    resources were assigned correctly, everything goes well,
+ *	    if they weren't, they won't disturb allocation of other
+ *	    resources.
+ *	(4) Assign new addresses to resources which were either
+ *	    not configured at all or misconfigured.  If explicitly
+ *	    requested by the user, configure expansion ROM address
+ *	    as well.
+ */
+
+static void __init pcibios_allocate_bus_resources(struct list_head *bus_list)
+{
+	struct list_head *ln;
+	struct pci_bus *bus;
+	struct pci_dev *dev;
+	int idx;
+	struct resource *r, *pr;
+
+	/* Depth-First Search on bus tree */
+	for (ln=bus_list->next; ln != bus_list; ln=ln->next) {
+		bus = pci_bus_b(ln);
+		if ((dev = bus->self)) {
+			for (idx = PCI_BRIDGE_RESOURCES; idx < PCI_NUM_RESOURCES; idx++) {
+				r = &dev->resource[idx];
+				if (!r->start)
+					continue;
+				pr = pci_find_parent_resource(dev, r);
+				if (!pr || request_resource(pr, r) < 0)
+					printk(KERN_ERR "PCI: Cannot allocate resource region %d of bridge %s\n", idx, dev->slot_name);
+			}
+		}
+		pcibios_allocate_bus_resources(&bus->children);
+	}
+}
+
+static void __init pcibios_allocate_resources(int pass)
+{
+	struct pci_dev *dev = NULL;
+	int idx, disabled;
+	u16 command;
+	struct resource *r, *pr;
+
+	while (dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev),
+	       dev != NULL
+	       ) {
+		pci_read_config_word(dev, PCI_COMMAND, &command);
+		for(idx = 0; idx < 6; idx++) {
+			r = &dev->resource[idx];
+			if (r->parent)		/* Already allocated */
+				continue;
+			if (!r->start)		/* Address not assigned at all */
+				continue;
+			if (r->flags & IORESOURCE_IO)
+				disabled = !(command & PCI_COMMAND_IO);
+			else
+				disabled = !(command & PCI_COMMAND_MEMORY);
+			if (pass == disabled) {
+				DBG("PCI: Resource %08lx-%08lx (f=%lx, d=%d, p=%d)\n",
+				    r->start, r->end, r->flags, disabled, pass);
+				pr = pci_find_parent_resource(dev, r);
+				if (!pr || request_resource(pr, r) < 0) {
+					printk(KERN_ERR "PCI: Cannot allocate resource region %d of device %s\n", idx, pci_name(dev));
+					/* We'll assign a new address later */
+					r->end -= r->start;
+					r->start = 0;
+				}
+			}
+		}
+		if (!pass) {
+			r = &dev->resource[PCI_ROM_RESOURCE];
+			if (r->flags & PCI_ROM_ADDRESS_ENABLE) {
+				/* Turn the ROM off, leave the resource region, but keep it unregistered. */
+				u32 reg;
+				DBG("PCI: Switching off ROM of %s\n", pci_name(dev));
+				r->flags &= ~PCI_ROM_ADDRESS_ENABLE;
+				pci_read_config_dword(dev, dev->rom_base_reg, &reg);
+				pci_write_config_dword(dev, dev->rom_base_reg, reg & ~PCI_ROM_ADDRESS_ENABLE);
+			}
+		}
+	}
+}
+
+static void __init pcibios_assign_resources(void)
+{
+	struct pci_dev *dev = NULL;
+	int idx;
+	struct resource *r;
+
+	while (dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev),
+	       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];
+
+			/*
+			 *  Don't touch IDE controllers and I/O ports of video cards!
+			 */
+			if ((class == PCI_CLASS_STORAGE_IDE && idx < 4) ||
+			    (class == PCI_CLASS_DISPLAY_VGA && (r->flags & IORESOURCE_IO)))
+				continue;
+
+			/*
+			 *  We shall assign a new address to this resource, either because
+			 *  the BIOS forgot to do so or because we have decided the old
+			 *  address was unusable for some reason.
+			 */
+			if (!r->start && r->end)
+				pci_assign_resource(dev, idx);
+		}
+
+		if (pci_probe & PCI_ASSIGN_ROMS) {
+			r = &dev->resource[PCI_ROM_RESOURCE];
+			r->end -= r->start;
+			r->start = 0;
+			if (r->end)
+				pci_assign_resource(dev, PCI_ROM_RESOURCE);
+		}
+	}
+}
+
+void __init pcibios_resource_survey(void)
+{
+	DBG("PCI: Allocating resources\n");
+	pcibios_allocate_bus_resources(&pci_root_buses);
+	pcibios_allocate_resources(0);
+	pcibios_allocate_resources(1);
+	pcibios_assign_resources();
+}
+
+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;
+}
+
+/*
+ *  If we set up a device for bus mastering, we need to check the latency
+ *  timer as certain crappy BIOSes forget to set it properly.
+ */
+unsigned int pcibios_max_latency = 255;
+
+void pcibios_set_master(struct pci_dev *dev)
+{
+	u8 lat;
+	pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
+	if (lat < 16)
+		lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
+	else if (lat > pcibios_max_latency)
+		lat = pcibios_max_latency;
+	else
+		return;
+	printk(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);
+}
diff -Nru a/arch/frv/mb93090-mb00/pci-frv.h b/arch/frv/mb93090-mb00/pci-frv.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/mb93090-mb00/pci-frv.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,47 @@
+/*
+ *	Low-Level PCI Access for FRV machines.
+ *
+ *	(c) 1999 Martin Mares <mj@ucw.cz>
+ */
+
+#include <asm/sections.h>
+
+#undef DEBUG
+
+#ifdef DEBUG
+#define DBG(x...) printk(x)
+#else
+#define DBG(x...)
+#endif
+
+#define PCI_PROBE_BIOS		0x0001
+#define PCI_PROBE_CONF1		0x0002
+#define PCI_PROBE_CONF2		0x0004
+#define PCI_NO_SORT		0x0100
+#define PCI_BIOS_SORT		0x0200
+#define PCI_NO_CHECKS		0x0400
+#define PCI_ASSIGN_ROMS		0x1000
+#define PCI_BIOS_IRQ_SCAN	0x2000
+#define PCI_ASSIGN_ALL_BUSSES	0x4000
+
+extern unsigned int __nongpreldata pci_probe;
+
+/* pci-frv.c */
+
+extern unsigned int pcibios_max_latency;
+
+void pcibios_resource_survey(void);
+int pcibios_enable_resources(struct pci_dev *, int);
+
+/* pci-vdk.c */
+
+extern int __nongpreldata pcibios_last_bus;
+extern struct pci_bus *__nongpreldata pci_root_bus;
+extern struct pci_ops *__nongpreldata pci_root_ops;
+
+/* pci-irq.c */
+extern unsigned int pcibios_irq_mask;
+
+void pcibios_irq_init(void);
+void pcibios_fixup_irqs(void);
+void pcibios_enable_irq(struct pci_dev *dev);
diff -Nru a/arch/frv/mb93090-mb00/pci-irq.c b/arch/frv/mb93090-mb00/pci-irq.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/mb93090-mb00/pci-irq.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,70 @@
+/* pci-irq.c: PCI IRQ routing on the FRV motherboard
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ * derived from: arch/i386/kernel/pci-irq.c: (c) 1999--2000 Martin Mares <mj@suse.cz>
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+
+#include <asm/io.h>
+#include <asm/smp.h>
+#include <asm/irq-routing.h>
+
+#include "pci-frv.h"
+
+/*
+ *	DEVICE	DEVNO	INT#A	INT#B	INT#C	INT#D
+ *	=======	=======	=======	=======	=======	=======
+ *	MB86943	0	fpga.10	-	-	-
+ *	RTL8029	16	fpga.12	-	-	-
+ *	SLOT 1	19	fpga.6	fpga.5	fpga.4	fpga.3
+ *	SLOT 2	18	fpga.5	fpga.4	fpga.3	fpga.6
+ *	SLOT 3	17	fpga.4	fpga.3	fpga.6	fpga.5
+ *
+ */
+
+static const uint8_t __initdata pci_bus0_irq_routing[32][4] = {
+	[0 ] {	IRQ_FPGA_MB86943_PCI_INTA },
+	[16] {	IRQ_FPGA_RTL8029_INTA },
+	[17] {	IRQ_FPGA_PCI_INTC, IRQ_FPGA_PCI_INTD, IRQ_FPGA_PCI_INTA, IRQ_FPGA_PCI_INTB },
+	[18] {	IRQ_FPGA_PCI_INTB, IRQ_FPGA_PCI_INTC, IRQ_FPGA_PCI_INTD, IRQ_FPGA_PCI_INTA },
+	[19] {	IRQ_FPGA_PCI_INTA, IRQ_FPGA_PCI_INTB, IRQ_FPGA_PCI_INTC, IRQ_FPGA_PCI_INTD },
+};
+
+void __init pcibios_irq_init(void)
+{
+}
+
+void __init pcibios_fixup_irqs(void)
+{
+	struct pci_dev *dev = NULL;
+	uint8_t line, pin;
+
+	while (dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev),
+	       dev != NULL
+	       ) {
+		pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
+		if (pin) {
+			dev->irq = pci_bus0_irq_routing[PCI_SLOT(dev->devfn)][pin - 1];
+			pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
+		}
+		pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &line);
+	}
+}
+
+void __init pcibios_penalize_isa_irq(int irq)
+{
+}
+
+void pcibios_enable_irq(struct pci_dev *dev)
+{
+	pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
+}
diff -Nru a/arch/frv/mb93090-mb00/pci-vdk.c b/arch/frv/mb93090-mb00/pci-vdk.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/mb93090-mb00/pci-vdk.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,467 @@
+/* pci-vdk.c: MB93090-MB00 (VDK) PCI support
+ *
+ * Copyright (C) 2003, 2004 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/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+
+#include <asm/segment.h>
+#include <asm/io.h>
+#include <asm/mb-regs.h>
+#include <asm/mb86943a.h>
+#include "pci-frv.h"
+
+unsigned int __nongpreldata pci_probe = 1;
+
+int  __nongpreldata pcibios_last_bus = -1;
+struct pci_bus *__nongpreldata pci_root_bus;
+struct pci_ops *__nongpreldata pci_root_ops;
+
+/*
+ * Functions for accessing PCI configuration space
+ */
+
+#define CONFIG_CMD(bus, dev, where) \
+	(0x80000000 | (bus->number << 16) | (devfn << 8) | (where & ~3))
+
+#define __set_PciCfgAddr(A) writel((A), (volatile void __iomem *) __region_CS1 + 0x80)
+
+#define __get_PciCfgDataB(A) readb((volatile void __iomem *) __region_CS1 + 0x88 + ((A) & 3))
+#define __get_PciCfgDataW(A) readw((volatile void __iomem *) __region_CS1 + 0x88 + ((A) & 2))
+#define __get_PciCfgDataL(A) readl((volatile void __iomem *) __region_CS1 + 0x88)
+
+#define __set_PciCfgDataB(A,V) \
+	writeb((V), (volatile void __iomem *) __region_CS1 + 0x88 + (3 - ((A) & 3)))
+
+#define __set_PciCfgDataW(A,V) \
+	writew((V), (volatile void __iomem *) __region_CS1 + 0x88 + (2 - ((A) & 2)))
+
+#define __set_PciCfgDataL(A,V) \
+	writel((V), (volatile void __iomem *) __region_CS1 + 0x88)
+
+#define __get_PciBridgeDataB(A) readb((volatile void __iomem *) __region_CS1 + 0x800 + (A))
+#define __get_PciBridgeDataW(A) readw((volatile void __iomem *) __region_CS1 + 0x800 + (A))
+#define __get_PciBridgeDataL(A) readl((volatile void __iomem *) __region_CS1 + 0x800 + (A))
+
+#define __set_PciBridgeDataB(A,V) writeb((V), (volatile void __iomem *) __region_CS1 + 0x800 + (A))
+#define __set_PciBridgeDataW(A,V) writew((V), (volatile void __iomem *) __region_CS1 + 0x800 + (A))
+#define __set_PciBridgeDataL(A,V) writel((V), (volatile void __iomem *) __region_CS1 + 0x800 + (A))
+
+static inline int __query(const struct pci_dev *dev)
+{
+//	return dev->bus->number==0 && (dev->devfn==PCI_DEVFN(0,0));
+//	return dev->bus->number==1;
+//	return dev->bus->number==0 &&
+//		(dev->devfn==PCI_DEVFN(2,0) || dev->devfn==PCI_DEVFN(3,0));
+	return 0;
+}
+
+/*****************************************************************************/
+/*
+ *
+ */
+static int pci_frv_read_config(struct pci_bus *bus, unsigned int devfn, int where, int size,
+			       u32 *val)
+{
+	u32 _value;
+
+	if (bus->number == 0 && devfn == PCI_DEVFN(0, 0)) {
+		_value = __get_PciBridgeDataL(where & ~3);
+	}
+	else {
+		__set_PciCfgAddr(CONFIG_CMD(bus, devfn, where));
+		_value = __get_PciCfgDataL(where & ~3);
+	}
+
+	switch (size) {
+	case 1:
+		_value = _value >> ((where & 3) * 8);
+		break;
+
+	case 2:
+		_value = _value >> ((where & 2) * 8);
+		break;
+
+	case 4:
+		break;
+
+	default:
+		BUG();
+	}
+
+	*val = _value;
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int pci_frv_write_config(struct pci_bus *bus, unsigned int devfn, int where, int size,
+				u32 value)
+{
+	switch (size) {
+	case 1:
+		if (bus->number == 0 && devfn == PCI_DEVFN(0, 0)) {
+			__set_PciBridgeDataB(where, value);
+		}
+		else {
+			__set_PciCfgAddr(CONFIG_CMD(bus, devfn, where));
+			__set_PciCfgDataB(where, value);
+		}
+		break;
+
+	case 2:
+		if (bus->number == 0 && devfn == PCI_DEVFN(0, 0)) {
+			__set_PciBridgeDataW(where, value);
+		}
+		else {
+			__set_PciCfgAddr(CONFIG_CMD(bus, devfn, where));
+			__set_PciCfgDataW(where, value);
+		}
+		break;
+
+	case 4:
+		if (bus->number == 0 && devfn == PCI_DEVFN(0, 0)) {
+			__set_PciBridgeDataL(where, value);
+		}
+		else {
+			__set_PciCfgAddr(CONFIG_CMD(bus, devfn, where));
+			__set_PciCfgDataL(where, value);
+		}
+		break;
+
+	default:
+		BUG();
+	}
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops pci_direct_frv = {
+	pci_frv_read_config,
+	pci_frv_write_config,
+};
+
+/*
+ * Before we decide to use direct hardware access mechanisms, we try to do some
+ * trivial checks to ensure it at least _seems_ to be working -- we just test
+ * whether bus 00 contains a host bridge (this is similar to checking
+ * techniques used in XFree86, but ours should be more reliable since we
+ * attempt to make use of direct access hints provided by the PCI BIOS).
+ *
+ * This should be close to trivial, but it isn't, because there are buggy
+ * chipsets (yes, you guessed it, by Intel and Compaq) that have no class ID.
+ */
+static int __init pci_sanity_check(struct pci_ops *o)
+{
+	struct pci_bus bus;		/* Fake bus and device */
+	u32 id;
+
+	bus.number	= 0;
+
+	if (o->read(&bus, 0, PCI_VENDOR_ID, 4, &id) == PCIBIOS_SUCCESSFUL) {
+		printk("PCI: VDK Bridge device:vendor: %08x\n", id);
+		if (id == 0x200e10cf)
+			return 1;
+	}
+
+	printk("PCI: VDK Bridge: Sanity check failed\n");
+	return 0;
+}
+
+static struct pci_ops * __init pci_check_direct(void)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+
+	/* check if access works */
+	if (pci_sanity_check(&pci_direct_frv)) {
+		local_irq_restore(flags);
+		printk("PCI: Using configuration frv\n");
+//		request_mem_region(0xBE040000, 256, "FRV bridge");
+//		request_mem_region(0xBFFFFFF4, 12, "PCI frv");
+		return &pci_direct_frv;
+	}
+
+	local_irq_restore(flags);
+	return NULL;
+}
+
+/*
+ * Several buggy motherboards address only 16 devices and mirror
+ * them to next 16 IDs. We try to detect this `feature' on all
+ * primary buses (those containing host bridges as they are
+ * expected to be unique) and remove the ghost devices.
+ */
+
+static void __init pcibios_fixup_ghosts(struct pci_bus *b)
+{
+	struct list_head *ln, *mn;
+	struct pci_dev *d, *e;
+	int mirror = PCI_DEVFN(16,0);
+	int seen_host_bridge = 0;
+	int i;
+
+	for (ln=b->devices.next; ln != &b->devices; ln=ln->next) {
+		d = pci_dev_b(ln);
+		if ((d->class >> 8) == PCI_CLASS_BRIDGE_HOST)
+			seen_host_bridge++;
+		for (mn=ln->next; mn != &b->devices; mn=mn->next) {
+			e = pci_dev_b(mn);
+			if (e->devfn != d->devfn + mirror ||
+			    e->vendor != d->vendor ||
+			    e->device != d->device ||
+			    e->class != d->class)
+				continue;
+			for(i=0; i<PCI_NUM_RESOURCES; i++)
+				if (e->resource[i].start != d->resource[i].start ||
+				    e->resource[i].end != d->resource[i].end ||
+				    e->resource[i].flags != d->resource[i].flags)
+					continue;
+			break;
+		}
+		if (mn == &b->devices)
+			return;
+	}
+	if (!seen_host_bridge)
+		return;
+	printk("PCI: Ignoring ghost devices on bus %02x\n", b->number);
+
+	ln = &b->devices;
+	while (ln->next != &b->devices) {
+		d = pci_dev_b(ln->next);
+		if (d->devfn >= mirror) {
+			list_del(&d->global_list);
+			list_del(&d->bus_list);
+			kfree(d);
+		} else
+			ln = ln->next;
+	}
+}
+
+/*
+ * Discover remaining PCI buses in case there are peer host bridges.
+ * We use the number of last PCI bus provided by the PCI BIOS.
+ */
+static void __init pcibios_fixup_peer_bridges(void)
+{
+	struct pci_bus bus;
+	struct pci_dev dev;
+	int n;
+	u16 l;
+
+	if (pcibios_last_bus <= 0 || pcibios_last_bus >= 0xff)
+		return;
+	printk("PCI: Peer bridge fixup\n");
+	for (n=0; n <= pcibios_last_bus; n++) {
+		if (pci_find_bus(0, n))
+			continue;
+		bus.number = n;
+		bus.ops = pci_root_ops;
+		dev.bus = &bus;
+		for(dev.devfn=0; dev.devfn<256; dev.devfn += 8)
+			if (!pci_read_config_word(&dev, PCI_VENDOR_ID, &l) &&
+			    l != 0x0000 && l != 0xffff) {
+				printk("Found device at %02x:%02x [%04x]\n", n, dev.devfn, l);
+				printk("PCI: Discovered peer bus %02x\n", n);
+				pci_scan_bus(n, pci_root_ops, NULL);
+				break;
+			}
+	}
+}
+
+/*
+ * Exceptions for specific devices. Usually work-arounds for fatal design flaws.
+ */
+
+static void __init pci_fixup_umc_ide(struct pci_dev *d)
+{
+	/*
+	 * UM8886BF IDE controller sets region type bits incorrectly,
+	 * therefore they look like memory despite of them being I/O.
+	 */
+	int i;
+
+	printk("PCI: Fixing base address flags for device %s\n", d->slot_name);
+	for(i=0; i<4; i++)
+		d->resource[i].flags |= PCI_BASE_ADDRESS_SPACE_IO;
+}
+
+static void __init pci_fixup_ide_bases(struct pci_dev *d)
+{
+	int i;
+
+	/*
+	 * PCI IDE controllers use non-standard I/O port decoding, respect it.
+	 */
+	if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE)
+		return;
+	printk("PCI: IDE base address fixup for %s\n", d->slot_name);
+	for(i=0; i<4; i++) {
+		struct resource *r = &d->resource[i];
+		if ((r->start & ~0x80) == 0x374) {
+			r->start |= 2;
+			r->end = r->start;
+		}
+	}
+}
+
+static void __init pci_fixup_ide_trash(struct pci_dev *d)
+{
+	int i;
+
+	/*
+	 * There exist PCI IDE controllers which have utter garbage
+	 * in first four base registers. Ignore that.
+	 */
+	printk("PCI: IDE base address trash cleared for %s\n", d->slot_name);
+	for(i=0; i<4; i++)
+		d->resource[i].start = d->resource[i].end = d->resource[i].flags = 0;
+}
+
+static void __devinit  pci_fixup_latency(struct pci_dev *d)
+{
+	/*
+	 *  SiS 5597 and 5598 chipsets require latency timer set to
+	 *  at most 32 to avoid lockups.
+	 */
+	DBG("PCI: Setting max latency to 32\n");
+	pcibios_max_latency = 32;
+}
+
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_UMC, PCI_DEVICE_ID_UMC_UM8886BF, pci_fixup_umc_ide);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5513, pci_fixup_ide_trash);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5597, pci_fixup_latency);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5598, pci_fixup_latency);
+DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases);
+
+/*
+ *  Called after each bus is probed, but before its children
+ *  are examined.
+ */
+
+void __init pcibios_fixup_bus(struct pci_bus *bus)
+{
+#if 0
+	printk("### PCIBIOS_FIXUP_BUS(%d)\n",bus->number);
+#endif
+	pcibios_fixup_ghosts(bus);
+	pci_read_bridge_bases(bus);
+
+	if (bus->number == 0) {
+		struct list_head *ln;
+		struct pci_dev *dev;
+		for (ln=bus->devices.next; ln != &bus->devices; ln=ln->next) {
+			dev = pci_dev_b(ln);
+			if (dev->devfn == 0) {
+				dev->resource[0].start = 0;
+				dev->resource[0].end = 0;
+			}
+		}
+	}
+}
+
+/*
+ * Initialization. Try all known PCI access methods. Note that we support
+ * using both PCI BIOS and direct access: in such cases, we use I/O ports
+ * to access config space, but we still keep BIOS order of cards to be
+ * compatible with 2.0.X. This should go away some day.
+ */
+
+int __init pcibios_init(void)
+{
+	struct pci_ops *dir = NULL;
+
+	if (!mb93090_mb00_detected)
+		return -ENXIO;
+
+	__reg_MB86943_sl_ctl |= MB86943_SL_CTL_DRCT_MASTER_SWAP | MB86943_SL_CTL_DRCT_SLAVE_SWAP;
+
+	__reg_MB86943_ecs_base(1)	= ((__region_CS2 + 0x01000000) >> 9) | 0x08000000;
+	__reg_MB86943_ecs_base(2)	= ((__region_CS2 + 0x00000000) >> 9) | 0x08000000;
+
+	*(volatile uint32_t *) (__region_CS1 + 0x848) = 0xe0000000;
+	*(volatile uint32_t *) (__region_CS1 + 0x8b8) = 0x00000000;
+
+	__reg_MB86943_sl_pci_io_base	= (__region_CS2 + 0x04000000) >> 9;
+	__reg_MB86943_sl_pci_mem_base	= (__region_CS2 + 0x08000000) >> 9;
+	__reg_MB86943_pci_sl_io_base	= __region_CS2 + 0x04000000;
+	__reg_MB86943_pci_sl_mem_base	= __region_CS2 + 0x08000000;
+	mb();
+
+	*(volatile unsigned long *)(__region_CS2+0x01300014) == 1;
+
+	ioport_resource.start	= (__reg_MB86943_sl_pci_io_base << 9) & 0xfffffc00;
+	ioport_resource.end	= (__reg_MB86943_sl_pci_io_range << 9) | 0x3ff;
+	ioport_resource.end	+= ioport_resource.start;
+
+	printk("PCI IO window:  %08lx-%08lx\n", ioport_resource.start, ioport_resource.end);
+
+	iomem_resource.start	= (__reg_MB86943_sl_pci_mem_base << 9) & 0xfffffc00;
+
+	/* Reserve somewhere to write to flush posted writes. */
+	iomem_resource.start += 0x400;
+
+	iomem_resource.end	= (__reg_MB86943_sl_pci_mem_range << 9) | 0x3ff;
+	iomem_resource.end	+= iomem_resource.start;
+
+	printk("PCI MEM window: %08lx-%08lx\n", iomem_resource.start, iomem_resource.end);
+	printk("PCI DMA memory: %08lx-%08lx\n", dma_coherent_mem_start, dma_coherent_mem_end);
+
+	if (!pci_probe)
+		return -ENXIO;
+
+	dir = pci_check_direct();
+	if (dir)
+		pci_root_ops = dir;
+	else {
+		printk("PCI: No PCI bus detected\n");
+		return -ENXIO;
+	}
+
+	printk("PCI: Probing PCI hardware\n");
+	pci_root_bus = pci_scan_bus(0, pci_root_ops, NULL);
+
+	pcibios_irq_init();
+	pcibios_fixup_peer_bridges();
+	pcibios_fixup_irqs();
+	pcibios_resource_survey();
+
+	return 0;
+}
+
+arch_initcall(pcibios_init);
+
+char * __init pcibios_setup(char *str)
+{
+	if (!strcmp(str, "off")) {
+		pci_probe = 0;
+		return NULL;
+	} else if (!strncmp(str, "lastbus=", 8)) {
+		pcibios_last_bus = simple_strtol(str+8, NULL, 0);
+		return NULL;
+	}
+	return str;
+}
+
+int pcibios_enable_device(struct pci_dev *dev, int mask)
+{
+	int err;
+
+	if ((err = pcibios_enable_resources(dev, mask)) < 0)
+		return err;
+	pcibios_enable_irq(dev);
+	return 0;
+}
diff -Nru a/arch/frv/mm/Makefile b/arch/frv/mm/Makefile
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/mm/Makefile	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,9 @@
+#
+# Makefile for the arch-specific parts of the memory manager.
+#
+
+obj-y := init.o kmap.o
+
+obj-$(CONFIG_MMU) += \
+	pgalloc.o highmem.o fault.o extable.o cache-page.o tlb-flush.o tlb-miss.o \
+	mmu-context.o dma-alloc.o unaligned.o elf-fdpic.o
diff -Nru a/arch/frv/mm/cache-page.c b/arch/frv/mm/cache-page.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/mm/cache-page.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,66 @@
+/* cache-page.c: whole-page cache wrangling functions for MMU linux
+ *
+ * Copyright (C) 2004 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/sched.h>
+#include <linux/mm.h>
+#include <linux/highmem.h>
+#include <asm/pgalloc.h>
+
+/*****************************************************************************/
+/*
+ * DCF takes a virtual address and the page may not currently have one
+ * - temporarily hijack a kmap_atomic() slot and attach the page to it
+ */
+void flush_dcache_page(struct page *page)
+{
+	unsigned long dampr2;
+	void *vaddr;
+
+	dampr2 = __get_DAMPR(2);
+
+	vaddr = kmap_atomic(page, __KM_CACHE);
+
+	frv_dcache_writeback((unsigned long) vaddr, (unsigned long) vaddr + PAGE_SIZE);
+
+	kunmap_atomic(vaddr, __KM_CACHE);
+
+	if (dampr2) {
+		__set_DAMPR(2, dampr2);
+		__set_IAMPR(2, dampr2);
+	}
+
+} /* end flush_dcache_page() */
+
+/*****************************************************************************/
+/*
+ * ICI takes a virtual address and the page may not currently have one
+ * - so we temporarily attach the page to a bit of virtual space so that is can be flushed
+ */
+void flush_icache_user_range(struct vm_area_struct *vma, struct page *page,
+			     unsigned long start, unsigned long len)
+{
+	unsigned long dampr2;
+	void *vaddr;
+
+	dampr2 = __get_DAMPR(2);
+
+	vaddr = kmap_atomic(page, __KM_CACHE);
+
+	start = (start & ~PAGE_MASK) | (unsigned long) vaddr;
+	frv_cache_wback_inv(start, start + len);
+
+	kunmap_atomic(vaddr, __KM_CACHE);
+
+	if (dampr2) {
+		__set_DAMPR(2, dampr2);
+		__set_IAMPR(2, dampr2);
+	}
+
+} /* end flush_icache_user_range() */
diff -Nru a/arch/frv/mm/dma-alloc.c b/arch/frv/mm/dma-alloc.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/mm/dma-alloc.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,188 @@
+/* dma-alloc.c: consistent DMA memory allocation
+ *
+ * Derived from arch/ppc/mm/cachemap.c
+ *
+ *  PowerPC version derived from arch/arm/mm/consistent.c
+ *    Copyright (C) 2001 Dan Malek (dmalek@jlc.net)
+ *
+ *  linux/arch/arm/mm/consistent.c
+ *
+ *  Copyright (C) 2000 Russell King
+ *
+ * Consistent memory allocators.  Used for DMA devices that want to
+ * share uncached memory with the processor core.  The function return
+ * is the virtual address and 'dma_handle' is the physical address.
+ * Mostly stolen from the ARM port, with some changes for PowerPC.
+ *						-- Dan
+ * Modified for 36-bit support.  -Matt
+ *
+ * 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/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/mman.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/stddef.h>
+#include <linux/vmalloc.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+
+#include <asm/pgalloc.h>
+#include <asm/io.h>
+#include <asm/hardirq.h>
+#include <asm/mmu_context.h>
+#include <asm/pgtable.h>
+#include <asm/mmu.h>
+#include <asm/uaccess.h>
+#include <asm/smp.h>
+
+static int map_page(unsigned long va, unsigned long pa, pgprot_t prot)
+{
+	pgd_t *pge;
+	pud_t *pue;
+	pmd_t *pme;
+	pte_t *pte;
+	int err = -ENOMEM;
+
+	spin_lock(&init_mm.page_table_lock);
+
+	/* Use upper 10 bits of VA to index the first level map */
+	pge = pgd_offset_k(va);
+	pue = pud_offset(pge, va);
+	pme = pmd_offset(pue, va);
+
+	/* Use middle 10 bits of VA to index the second-level map */
+	pte = pte_alloc_kernel(&init_mm, pme, va);
+	if (pte != 0) {
+		err = 0;
+		set_pte(pte, mk_pte_phys(pa & PAGE_MASK, prot));
+	}
+
+	spin_unlock(&init_mm.page_table_lock);
+	return err;
+}
+
+/*
+ * This function will allocate the requested contiguous pages and
+ * map them into the kernel's vmalloc() space.  This is done so we
+ * get unique mapping for these pages, outside of the kernel's 1:1
+ * virtual:physical mapping.  This is necessary so we can cover large
+ * portions of the kernel with single large page TLB entries, and
+ * still get unique uncached pages for consistent DMA.
+ */
+void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle)
+{
+	struct vm_struct *area;
+	unsigned long page, va, pa;
+	void *ret;
+	int order, err, i;
+
+	if (in_interrupt())
+		BUG();
+
+	/* only allocate page size areas */
+	size = PAGE_ALIGN(size);
+	order = get_order(size);
+
+	page = __get_free_pages(gfp, order);
+	if (!page) {
+		BUG();
+		return NULL;
+	}
+
+	/* allocate some common virtual space to map the new pages */
+	area = get_vm_area(size, VM_ALLOC);
+	if (area == 0) {
+		free_pages(page, order);
+		return NULL;
+	}
+	va = VMALLOC_VMADDR(area->addr);
+	ret = (void *) va;
+
+	/* this gives us the real physical address of the first page */
+	*dma_handle = pa = virt_to_bus((void *) page);
+
+	/* set refcount=1 on all pages in an order>0 allocation so that vfree() will actually free
+	 * all pages that were allocated.
+	 */
+	if (order > 0) {
+		struct page *rpage = virt_to_page(page);
+
+		for (i = 1; i < (1 << order); i++)
+			set_page_count(rpage + i, 1);
+	}
+
+	err = 0;
+	for (i = 0; i < size && err == 0; i += PAGE_SIZE)
+		err = map_page(va + i, pa + i, PAGE_KERNEL_NOCACHE);
+
+	if (err) {
+		vfree((void *) va);
+		return NULL;
+	}
+
+	/* we need to ensure that there are no cachelines in use, or worse dirty in this area
+	 * - can't do until after virtual address mappings are created
+	 */
+	frv_cache_invalidate(va, va + size);
+
+	return ret;
+}
+
+/*
+ * free page(s) as defined by the above mapping.
+ */
+void consistent_free(void *vaddr)
+{
+	if (in_interrupt())
+		BUG();
+	vfree(vaddr);
+}
+
+/*
+ * make an area consistent.
+ */
+void consistent_sync(void *vaddr, size_t size, int direction)
+{
+	unsigned long start = (unsigned long) vaddr;
+	unsigned long end   = start + size;
+
+	switch (direction) {
+	case PCI_DMA_NONE:
+		BUG();
+	case PCI_DMA_FROMDEVICE:	/* invalidate only */
+		frv_cache_invalidate(start, end);
+		break;
+	case PCI_DMA_TODEVICE:		/* writeback only */
+		frv_dcache_writeback(start, end);
+		break;
+	case PCI_DMA_BIDIRECTIONAL:	/* writeback and invalidate */
+		frv_dcache_writeback(start, end);
+		break;
+	}
+}
+
+/*
+ * consistent_sync_page make a page are consistent. identical
+ * to consistent_sync, but takes a struct page instead of a virtual address
+ */
+
+void consistent_sync_page(struct page *page, unsigned long offset,
+			  size_t size, int direction)
+{
+	void *start;
+
+	start = page_address(page) + offset;
+	consistent_sync(start, size, direction);
+}
diff -Nru a/arch/frv/mm/elf-fdpic.c b/arch/frv/mm/elf-fdpic.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/mm/elf-fdpic.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,123 @@
+/* elf-fdpic.c: ELF FDPIC memory layout management
+ *
+ * Copyright (C) 2004 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/sched.h>
+#include <linux/mm.h>
+#include <linux/fs.h>
+#include <linux/elf-fdpic.h>
+
+/*****************************************************************************/
+/*
+ * lay out the userspace VM according to our grand design
+ */
+#ifdef CONFIG_MMU
+void elf_fdpic_arch_lay_out_mm(struct elf_fdpic_params *exec_params,
+			       struct elf_fdpic_params *interp_params,
+			       unsigned long *start_stack,
+			       unsigned long *start_brk)
+{
+	*start_stack = 0x02200000UL;
+
+	/* if the only executable is a shared object, assume that it is an interpreter rather than
+	 * a true executable, and map it such that "ld.so --list" comes out right
+	 */
+	if (!(interp_params->flags & ELF_FDPIC_FLAG_PRESENT) &&
+	    exec_params->hdr.e_type != ET_EXEC
+	    ) {
+		exec_params->load_addr = PAGE_SIZE;
+
+		*start_brk = 0x80000000UL;
+	}
+	else {
+		exec_params->load_addr = 0x02200000UL;
+
+		if ((exec_params->flags & ELF_FDPIC_FLAG_ARRANGEMENT) ==
+		    ELF_FDPIC_FLAG_INDEPENDENT
+		    ) {
+			exec_params->flags &= ~ELF_FDPIC_FLAG_ARRANGEMENT;
+			exec_params->flags |= ELF_FDPIC_FLAG_CONSTDISP;
+		}
+	}
+
+} /* end elf_fdpic_arch_lay_out_mm() */
+#endif
+
+/*****************************************************************************/
+/*
+ * place non-fixed mmaps firstly in the bottom part of memory, working up, and then in the top part
+ * of memory, working down
+ */
+unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len,
+				     unsigned long pgoff, unsigned long flags)
+{
+	struct vm_area_struct *vma;
+	unsigned long limit;
+
+	if (len > TASK_SIZE)
+		return -ENOMEM;
+
+	/* only honour a hint if we're not going to clobber something doing so */
+	if (addr) {
+		addr = PAGE_ALIGN(addr);
+		vma = find_vma(current->mm, addr);
+		if (TASK_SIZE - len >= addr &&
+		    (!vma || addr + len <= vma->vm_start))
+			goto success;
+	}
+
+	/* search between the bottom of user VM and the stack grow area */
+	addr = PAGE_SIZE;
+	limit = (current->mm->start_stack - 0x00200000);
+	if (addr + len <= limit) {
+		limit -= len;
+
+		if (addr <= limit) {
+			vma = find_vma(current->mm, PAGE_SIZE);
+			for (; vma; vma = vma->vm_next) {
+				if (addr > limit)
+					break;
+				if (addr + len <= vma->vm_start)
+					goto success;
+				addr = vma->vm_end;
+			}
+		}
+	}
+
+	/* search from just above the WorkRAM area to the top of memory */
+	addr = PAGE_ALIGN(0x80000000);
+	limit = TASK_SIZE - len;
+	if (addr <= limit) {
+		vma = find_vma(current->mm, addr);
+		for (; vma; vma = vma->vm_next) {
+			if (addr > limit)
+				break;
+			if (addr + len <= vma->vm_start)
+				goto success;
+			addr = vma->vm_end;
+		}
+
+		if (!vma && addr <= limit)
+			goto success;
+	}
+
+#if 0
+	printk("[area] l=%lx (ENOMEM) f='%s'\n",
+	       len, filp ? filp->f_dentry->d_name.name : "");
+#endif
+	return -ENOMEM;
+
+ success:
+#if 0
+	printk("[area] l=%lx ad=%lx f='%s'\n",
+	       len, addr, filp ? filp->f_dentry->d_name.name : "");
+#endif
+	return addr;
+} /* end arch_get_unmapped_area() */
diff -Nru a/arch/frv/mm/extable.c b/arch/frv/mm/extable.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/mm/extable.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,91 @@
+/*
+ * linux/arch/frv/mm/extable.c
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <asm/uaccess.h>
+
+extern const struct exception_table_entry __attribute__((aligned(8))) __start___ex_table[];
+extern const struct exception_table_entry __attribute__((aligned(8))) __stop___ex_table[];
+extern const void __memset_end, __memset_user_error_lr, __memset_user_error_handler;
+extern const void __memcpy_end, __memcpy_user_error_lr, __memcpy_user_error_handler;
+extern spinlock_t modlist_lock;
+
+/*****************************************************************************/
+/*
+ *
+ */
+static inline unsigned long search_one_table(const struct exception_table_entry *first,
+					     const struct exception_table_entry *last,
+					     unsigned long value)
+{
+        while (first <= last) {
+		const struct exception_table_entry __attribute__((aligned(8))) *mid;
+		long diff;
+
+		mid = (last - first) / 2 + first;
+		diff = mid->insn - value;
+                if (diff == 0)
+                        return mid->fixup;
+                else if (diff < 0)
+                        first = mid + 1;
+                else
+                        last = mid - 1;
+        }
+        return 0;
+} /* end search_one_table() */
+
+/*****************************************************************************/
+/*
+ * see if there's a fixup handler available to deal with a kernel fault
+ */
+unsigned long search_exception_table(unsigned long pc)
+{
+	unsigned long ret = 0;
+
+	/* determine if the fault lay during a memcpy_user or a memset_user */
+	if (__frame->lr == (unsigned long) &__memset_user_error_lr &&
+	    (unsigned long) &memset <= pc && pc < (unsigned long) &__memset_end
+	    ) {
+		/* the fault occurred in a protected memset
+		 * - we search for the return address (in LR) instead of the program counter
+		 * - it was probably during a clear_user()
+		 */
+		return (unsigned long) &__memset_user_error_handler;
+	}
+	else if (__frame->lr == (unsigned long) &__memcpy_user_error_lr &&
+		 (unsigned long) &memcpy <= pc && pc < (unsigned long) &__memcpy_end
+		 ) {
+		/* the fault occurred in a protected memset
+		 * - we search for the return address (in LR) instead of the program counter
+		 * - it was probably during a copy_to/from_user()
+		 */
+		return (unsigned long) &__memcpy_user_error_handler;
+	}
+
+#ifndef CONFIG_MODULES
+	/* there is only the kernel to search.  */
+	ret = search_one_table(__start___ex_table, __stop___ex_table - 1, pc);
+	return ret;
+
+#else
+	/* the kernel is the last "module" -- no need to treat it special */
+	unsigned long flags;
+	struct module *mp;
+
+	spin_lock_irqsave(&modlist_lock, flags);
+
+	for (mp = module_list; mp != NULL; mp = mp->next) {
+		if (mp->ex_table_start == NULL || !(mp->flags & (MOD_RUNNING | MOD_INITIALIZING)))
+			continue;
+		ret = search_one_table(mp->ex_table_start, mp->ex_table_end - 1, pc);
+		if (ret)
+			break;
+	}
+
+	spin_unlock_irqrestore(&modlist_lock, flags);
+	return ret;
+#endif
+} /* end search_exception_table() */
diff -Nru a/arch/frv/mm/fault.c b/arch/frv/mm/fault.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/mm/fault.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,325 @@
+/*
+ *  linux/arch/frv/mm/fault.c
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * - Written by David Howells (dhowells@redhat.com)
+ * - Derived from arch/m68knommu/mm/fault.c
+ *   - Copyright (C) 1998  D. Jeff Dionne <jeff@lineo.ca>,
+ *   - Copyright (C) 2000  Lineo, Inc.  (www.lineo.com)
+ *
+ *  Based on:
+ *
+ *  linux/arch/m68k/mm/fault.c
+ *
+ *  Copyright (C) 1995  Hamish Macdonald
+ */
+
+#include <linux/mman.h>
+#include <linux/mm.h>
+#include <linux/kernel.h>
+#include <linux/ptrace.h>
+#include <linux/hardirq.h>
+
+#include <asm/system.h>
+#include <asm/pgtable.h>
+#include <asm/uaccess.h>
+#include <asm/gdb-stub.h>
+
+/*****************************************************************************/
+/*
+ * This routine handles page faults.  It determines the problem, and
+ * then passes it off to one of the appropriate routines.
+ */
+asmlinkage void do_page_fault(int datammu, unsigned long esr0, unsigned long ear0)
+{
+	struct vm_area_struct *vma;
+	struct mm_struct *mm;
+	unsigned long _pme, lrai, lrad, fixup;
+	siginfo_t info;
+	pgd_t *pge;
+	pud_t *pue;
+	pte_t *pte;
+	int write;
+
+#if 0
+	const char *atxc[16] = {
+		[0x0] = "mmu-miss", [0x8] = "multi-dat", [0x9] = "multi-sat",
+		[0xa] = "tlb-miss", [0xc] = "privilege", [0xd] = "write-prot",
+	};
+
+	printk("do_page_fault(%d,%lx [%s],%lx)\n",
+	       datammu, esr0, atxc[esr0 >> 20 & 0xf], ear0);
+#endif
+
+	mm = current->mm;
+
+	/*
+	 * We fault-in kernel-space virtual memory on-demand. The
+	 * 'reference' page table is init_mm.pgd.
+	 *
+	 * NOTE! We MUST NOT take any locks for this case. We may
+	 * be in an interrupt or a critical region, and should
+	 * only copy the information from the master page table,
+	 * nothing more.
+	 *
+	 * This verifies that the fault happens in kernel space
+	 * and that the fault was a page not present (invalid) error
+	 */
+	if (!user_mode(__frame) && (esr0 & ESR0_ATXC) == ESR0_ATXC_AMRTLB_MISS) {
+		if (ear0 >= VMALLOC_START && ear0 < VMALLOC_END)
+			goto kernel_pte_fault;
+		if (ear0 >= PKMAP_BASE && ear0 < PKMAP_END)
+			goto kernel_pte_fault;
+	}
+
+	info.si_code = SEGV_MAPERR;
+
+	/*
+	 * If we're in an interrupt or have no user
+	 * context, we must not take the fault..
+	 */
+	if (in_interrupt() || !mm)
+		goto no_context;
+
+	down_read(&mm->mmap_sem);
+
+	vma = find_vma(mm, ear0);
+	if (!vma)
+		goto bad_area;
+	if (vma->vm_start <= ear0)
+		goto good_area;
+	if (!(vma->vm_flags & VM_GROWSDOWN))
+		goto bad_area;
+
+	if (user_mode(__frame)) {
+		/*
+		 * accessing the stack below %esp is always a bug.
+		 * The "+ 32" is there due to some instructions (like
+		 * pusha) doing post-decrement on the stack and that
+		 * doesn't show up until later..
+		 */
+		if ((ear0 & PAGE_MASK) + 2 * PAGE_SIZE < __frame->sp) {
+#if 0
+			printk("[%d] ### Access below stack @%lx (sp=%lx)\n",
+			       current->pid, ear0, __frame->sp);
+			show_registers(__frame);
+			printk("[%d] ### Code: [%08lx] %02x %02x %02x %02x %02x %02x %02x %02x\n",
+			       current->pid,
+			       __frame->pc,
+			       ((u8*)__frame->pc)[0],
+			       ((u8*)__frame->pc)[1],
+			       ((u8*)__frame->pc)[2],
+			       ((u8*)__frame->pc)[3],
+			       ((u8*)__frame->pc)[4],
+			       ((u8*)__frame->pc)[5],
+			       ((u8*)__frame->pc)[6],
+			       ((u8*)__frame->pc)[7]
+			       );
+#endif
+			goto bad_area;
+		}
+	}
+
+	if (expand_stack(vma, ear0))
+		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;
+	write = 0;
+	switch (esr0 & ESR0_ATXC) {
+	default:
+		/* handle write to write protected page */
+	case ESR0_ATXC_WP_EXCEP:
+#ifdef TEST_VERIFY_AREA
+		if (!(user_mode(__frame)))
+			printk("WP fault at %08lx\n", __frame->pc);
+#endif
+		if (!(vma->vm_flags & VM_WRITE))
+			goto bad_area;
+		write = 1;
+		break;
+
+		 /* handle read from protected page */
+	case ESR0_ATXC_PRIV_EXCEP:
+		goto bad_area;
+
+		 /* handle read, write or exec on absent page
+		  * - can't support write without permitting read
+		  * - don't support execute without permitting read and vice-versa
+		  */
+	case ESR0_ATXC_AMRTLB_MISS:
+		if (!(vma->vm_flags & (VM_READ | VM_WRITE | VM_EXEC)))
+			goto bad_area;
+		break;
+	}
+
+	/*
+	 * If for any reason at all we couldn't handle the fault,
+	 * make sure we exit gracefully rather than endlessly redo
+	 * the fault.
+	 */
+	switch (handle_mm_fault(mm, vma, ear0, write)) {
+	case 1:
+		current->min_flt++;
+		break;
+	case 2:
+		current->maj_flt++;
+		break;
+	case 0:
+		goto do_sigbus;
+	default:
+		goto out_of_memory;
+	}
+
+	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);
+
+	/* User mode accesses just cause a SIGSEGV */
+	if (user_mode(__frame)) {
+		info.si_signo = SIGSEGV;
+		info.si_errno = 0;
+		/* info.si_code has been set above */
+		info.si_addr = (void *) ear0;
+		force_sig_info(SIGSEGV, &info, current);
+		return;
+	}
+
+ no_context:
+	/* are we prepared to handle this kernel fault? */
+	if ((fixup = search_exception_table(__frame->pc)) != 0) {
+		__frame->pc = fixup;
+		return;
+	}
+
+/*
+ * Oops. The kernel tried to access some bad page. We'll have to
+ * terminate things with extreme prejudice.
+ */
+
+	bust_spinlocks(1);
+
+	if (ear0 < PAGE_SIZE)
+		printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
+	else
+		printk(KERN_ALERT "Unable to handle kernel paging request");
+	printk(" at virtual addr %08lx\n", ear0);
+	printk("  PC  : %08lx\n", __frame->pc);
+	printk("  EXC : esr0=%08lx ear0=%08lx\n", esr0, ear0);
+
+	asm("lrai %1,%0,#1,#0,#0" : "=&r"(lrai) : "r"(ear0));
+	asm("lrad %1,%0,#1,#0,#0" : "=&r"(lrad) : "r"(ear0));
+
+	printk(KERN_ALERT "  LRAI: %08lx\n", lrai);
+	printk(KERN_ALERT "  LRAD: %08lx\n", lrad);
+
+	__break_hijack_kernel_event();
+
+	pge = pgd_offset(current->mm, ear0);
+	pue = pud_offset(pge, ear0);
+	_pme = pue->pue[0].ste[0];
+
+	printk(KERN_ALERT "  PGE : %8p { PME %08lx }\n", pge, _pme);
+
+	if (_pme & xAMPRx_V) {
+		unsigned long dampr, damlr, val;
+
+		asm volatile("movsg dampr2,%0 ! movgs %2,dampr2 ! movsg damlr2,%1"
+			     : "=&r"(dampr), "=r"(damlr)
+			     : "r" (_pme | xAMPRx_L|xAMPRx_SS_16Kb|xAMPRx_S|xAMPRx_C|xAMPRx_V)
+			     );
+
+		pte = (pte_t *) damlr + __pte_index(ear0);
+		val = pte_val(*pte);
+
+		asm volatile("movgs %0,dampr2" :: "r" (dampr));
+
+		printk(KERN_ALERT "  PTE : %8p { %08lx }\n", pte, val);
+	}
+
+	die_if_kernel("Oops\n");
+	do_exit(SIGKILL);
+
+/*
+ * 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);
+	printk("VM: killing process %s\n", current->comm);
+	if (user_mode(__frame))
+		do_exit(SIGKILL);
+	goto no_context;
+
+ do_sigbus:
+	up_read(&mm->mmap_sem);
+
+	/*
+	 * Send a sigbus, regardless of whether we were in kernel
+	 * or user mode.
+	 */
+	info.si_signo = SIGBUS;
+	info.si_errno = 0;
+	info.si_code = BUS_ADRERR;
+	info.si_addr = (void *) ear0;
+	force_sig_info(SIGBUS, &info, current);
+
+	/* Kernel mode? Handle exceptions or die */
+	if (!user_mode(__frame))
+		goto no_context;
+	return;
+
+/*
+ * The fault was caused by a kernel PTE (such as installed by vmalloc or kmap)
+ */
+ kernel_pte_fault:
+	{
+		/*
+		 * Synchronize this task's top level page-table
+		 * with the 'reference' page table.
+		 *
+		 * Do _not_ use "tsk" here. We might be inside
+		 * an interrupt in the middle of a task switch..
+		 */
+		int index = pgd_index(ear0);
+		pgd_t *pgd, *pgd_k;
+		pud_t *pud, *pud_k;
+		pmd_t *pmd, *pmd_k;
+		pte_t *pte_k;
+
+		pgd = (pgd_t *) __get_TTBR();
+		pgd = (pgd_t *)__va(pgd) + index;
+		pgd_k = ((pgd_t *)(init_mm.pgd)) + index;
+
+		if (!pgd_present(*pgd_k))
+			goto no_context;
+		//set_pgd(pgd, *pgd_k); /////// gcc ICE's on this line
+
+		pud_k = pud_offset(pgd_k, ear0);
+		if (!pud_present(*pud_k))
+			goto no_context;
+
+		pmd_k = pmd_offset(pud_k, ear0);
+		if (!pmd_present(*pmd_k))
+			goto no_context;
+
+		pud = pud_offset(pgd, ear0);
+		pmd = pmd_offset(pud, ear0);
+		set_pmd(pmd, *pmd_k);
+
+		pte_k = pte_offset_kernel(pmd_k, ear0);
+		if (!pte_present(*pte_k))
+			goto no_context;
+		return;
+	}
+} /* end do_page_fault() */
diff -Nru a/arch/frv/mm/highmem.c b/arch/frv/mm/highmem.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/mm/highmem.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,33 @@
+/* highmem.c: arch-specific highmem stuff
+ *
+ * Copyright (C) 2004 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/highmem.h>
+
+void *kmap(struct page *page)
+{
+	might_sleep();
+	if (!PageHighMem(page))
+		return page_address(page);
+	return kmap_high(page);
+}
+
+void kunmap(struct page *page)
+{
+	if (in_interrupt())
+		BUG();
+	if (!PageHighMem(page))
+		return;
+	kunmap_high(page);
+}
+
+struct page *kmap_atomic_to_page(void *ptr)
+{
+	return virt_to_page(ptr);
+}
diff -Nru a/arch/frv/mm/init.c b/arch/frv/mm/init.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/mm/init.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,241 @@
+/* init.c: memory initialisation for FRV
+ *
+ * Copyright (C) 2004 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.
+ *
+ * Derived from:
+ *  - linux/arch/m68knommu/mm/init.c
+ *    - Copyright (C) 1998  D. Jeff Dionne <jeff@lineo.ca>, Kenneth Albanowski <kjahds@kjahds.com>,
+ *    - Copyright (C) 2000  Lineo, Inc.  (www.lineo.com)
+ *  - linux/arch/m68k/mm/init.c
+ *    - Copyright (C) 1995  Hamish Macdonald
+ */
+
+#include <linux/config.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/pagemap.h>
+#include <linux/swap.h>
+#include <linux/mm.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/bootmem.h>
+#include <linux/highmem.h>
+
+#include <asm/setup.h>
+#include <asm/segment.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/mmu_context.h>
+#include <asm/virtconvert.h>
+#include <asm/sections.h>
+#include <asm/tlb.h>
+
+#undef DEBUG
+
+DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
+
+/*
+ * BAD_PAGE is the page that is used for page faults when linux
+ * is out-of-memory. Older versions of linux just did a
+ * do_exit(), but using this instead means there is less risk
+ * for a process dying in kernel mode, possibly leaving a inode
+ * unused etc..
+ *
+ * BAD_PAGETABLE is the accompanying page-table: it is initialized
+ * to point to BAD_PAGE entries.
+ *
+ * ZERO_PAGE is a special page that is used for zero-initialized
+ * data and COW.
+ */
+static unsigned long empty_bad_page_table;
+static unsigned long empty_bad_page;
+unsigned long empty_zero_page;
+
+/*****************************************************************************/
+/*
+ *
+ */
+void show_mem(void)
+{
+	unsigned long i;
+	int free = 0, total = 0, reserved = 0, shared = 0;
+
+	printk("\nMem-info:\n");
+	show_free_areas();
+	i = max_mapnr;
+	while (i-- > 0) {
+		struct page *page = &mem_map[i];
+
+		total++;
+		if (PageReserved(page))
+			reserved++;
+		else if (!page_count(page))
+			free++;
+		else
+			shared += page_count(page) - 1;
+	}
+
+	printk("%d pages of RAM\n",total);
+	printk("%d free pages\n",free);
+	printk("%d reserved pages\n",reserved);
+	printk("%d pages shared\n",shared);
+
+} /* end show_mem() */
+
+/*****************************************************************************/
+/*
+ * paging_init() continues the virtual memory environment setup which
+ * was begun by the code in arch/head.S.
+ * The parameters are pointers to where to stick the starting and ending
+ * addresses  of available kernel virtual memory.
+ */
+void __init paging_init(void)
+{
+	unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0};
+
+	/* allocate some pages for kernel housekeeping tasks */
+	empty_bad_page_table	= (unsigned long) alloc_bootmem_pages(PAGE_SIZE);
+	empty_bad_page		= (unsigned long) alloc_bootmem_pages(PAGE_SIZE);
+	empty_zero_page		= (unsigned long) alloc_bootmem_pages(PAGE_SIZE);
+
+	memset((void *) empty_zero_page, 0, PAGE_SIZE);
+
+#if CONFIG_HIGHMEM
+	if (num_physpages - num_mappedpages) {
+		pgd_t *pge;
+		pud_t *pue;
+		pmd_t *pme;
+
+		pkmap_page_table = alloc_bootmem_pages(PAGE_SIZE);
+
+		memset(pkmap_page_table, 0, PAGE_SIZE);
+
+		pge = swapper_pg_dir + pgd_index_k(PKMAP_BASE);
+		pue = pud_offset(pge, PKMAP_BASE);
+		pme = pmd_offset(pue, PKMAP_BASE);
+		__set_pmd(pme, virt_to_phys(pkmap_page_table) | _PAGE_TABLE);
+	}
+#endif
+
+	/* distribute the allocatable pages across the various zones and pass them to the allocator
+	 */
+	zones_size[ZONE_DMA]     = max_low_pfn - min_low_pfn;
+	zones_size[ZONE_NORMAL]  = 0;
+#ifdef CONFIG_HIGHMEM
+	zones_size[ZONE_HIGHMEM] = num_physpages - num_mappedpages;
+#endif
+
+	free_area_init(zones_size);
+
+#ifdef CONFIG_MMU
+	/* initialise init's MMU context */
+	init_new_context(&init_task, &init_mm);
+#endif
+
+} /* end paging_init() */
+
+/*****************************************************************************/
+/*
+ *
+ */
+void __init mem_init(void)
+{
+	unsigned long npages = (memory_end - memory_start) >> PAGE_SHIFT;
+	unsigned long tmp;
+#ifdef CONFIG_MMU
+	unsigned long loop, pfn;
+	int datapages = 0;
+#endif
+	int codek = 0, datak = 0;
+
+	/* this will put all memory onto the freelists */
+	totalram_pages = free_all_bootmem();
+
+#ifdef CONFIG_MMU
+	for (loop = 0 ; loop < npages ; loop++)
+		if (PageReserved(&mem_map[loop]))
+			datapages++;
+
+#ifdef CONFIG_HIGHMEM
+	for (pfn = num_physpages - 1; pfn >= num_mappedpages; pfn--) {
+		struct page *page = &mem_map[pfn];
+
+		ClearPageReserved(page);
+		set_bit(PG_highmem, &page->flags);
+		set_page_count(page, 1);
+		__free_page(page);
+		totalram_pages++;
+	}
+#endif
+
+	codek = ((unsigned long) &_etext - (unsigned long) &_stext) >> 10;
+	datak = datapages << (PAGE_SHIFT - 10);
+
+#else
+	codek = (_etext - _stext) >> 10;
+	datak = 0; //(_ebss - _sdata) >> 10;
+#endif
+
+	tmp = nr_free_pages() << PAGE_SHIFT;
+	printk("Memory available: %luKiB/%luKiB RAM, %luKiB/%luKiB ROM (%dKiB kernel code, %dKiB data)\n",
+	       tmp >> 10,
+	       npages << (PAGE_SHIFT - 10),
+	       (rom_length > 0) ? ((rom_length >> 10) - codek) : 0,
+	       rom_length >> 10,
+	       codek,
+	       datak
+	       );
+
+} /* end mem_init() */
+
+/*****************************************************************************/
+/*
+ * free the memory that was only required for initialisation
+ */
+void __init free_initmem(void)
+{
+#if defined(CONFIG_RAMKERNEL) && !defined(CONFIG_PROTECT_KERNEL)
+	unsigned long start, end, addr;
+
+	start = PAGE_ALIGN((unsigned long) &__init_begin);	/* round up */
+	end   = ((unsigned long) &__init_end) & PAGE_MASK;	/* round down */
+
+	/* next to check that the page we free is not a partial page */
+	for (addr = start; addr < end; addr += PAGE_SIZE) {
+		ClearPageReserved(virt_to_page(addr));
+		set_page_count(virt_to_page(addr), 1);
+		free_page(addr);
+		totalram_pages++;
+	}
+
+	printk("Freeing unused kernel memory: %ldKiB freed (0x%lx - 0x%lx)\n",
+	       (end - start) >> 10, start, end);
+#endif
+} /* end free_initmem() */
+
+/*****************************************************************************/
+/*
+ * free the initial ramdisk memory
+ */
+#ifdef CONFIG_BLK_DEV_INITRD
+void __init free_initrd_mem(unsigned long start, unsigned long end)
+{
+	int pages = 0;
+	for (; start < end; start += PAGE_SIZE) {
+		ClearPageReserved(virt_to_page(start));
+		set_page_count(virt_to_page(start), 1);
+		free_page(start);
+		totalram_pages++;
+		pages++;
+	}
+	printk("Freeing initrd memory: %dKiB freed\n", (pages * PAGE_SIZE) >> 10);
+} /* end free_initrd_mem() */
+#endif
diff -Nru a/arch/frv/mm/kmap.c b/arch/frv/mm/kmap.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/mm/kmap.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,62 @@
+/* kmap.c: ioremapping handlers
+ *
+ * Copyright (C) 2003-5 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ * - Derived from arch/m68k/mm/kmap.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.
+ */
+
+#include <linux/config.h>
+#include <linux/mm.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/vmalloc.h>
+
+#include <asm/setup.h>
+#include <asm/segment.h>
+#include <asm/page.h>
+#include <asm/pgalloc.h>
+#include <asm/io.h>
+#include <asm/system.h>
+
+#undef DEBUG
+
+/*****************************************************************************/
+/*
+ * Map some physical address range into the kernel address space.
+ */
+
+void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag)
+{
+	return (void *)physaddr;
+}
+
+/*
+ * Unmap a ioremap()ed region again
+ */
+void iounmap(void *addr)
+{
+}
+
+/*
+ * __iounmap unmaps nearly everything, so be careful
+ * it doesn't free currently pointer/page tables anymore but it
+ * wans't used anyway and might be added later.
+ */
+void __iounmap(void *addr, unsigned long size)
+{
+}
+
+/*
+ * Set new cache mode for some kernel address space.
+ * The caller must push data for that range itself, if such data may already
+ * be in the cache.
+ */
+void kernel_set_cachemode(void *addr, unsigned long size, int cmode)
+{
+}
diff -Nru a/arch/frv/mm/mmu-context.c b/arch/frv/mm/mmu-context.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/mm/mmu-context.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,208 @@
+/* mmu-context.c: MMU context allocation and management
+ *
+ * Copyright (C) 2004 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/sched.h>
+#include <linux/mm.h>
+#include <asm/tlbflush.h>
+
+#define NR_CXN	4096
+
+static unsigned long cxn_bitmap[NR_CXN / (sizeof(unsigned long) * 8)];
+static LIST_HEAD(cxn_owners_lru);
+static DEFINE_SPINLOCK(cxn_owners_lock);
+
+int __nongpreldata cxn_pinned = -1;
+
+
+/*****************************************************************************/
+/*
+ * initialise a new context
+ */
+int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
+{
+	memset(&mm->context, 0, sizeof(mm->context));
+	INIT_LIST_HEAD(&mm->context.id_link);
+	mm->context.itlb_cached_pge = 0xffffffffUL;
+	mm->context.dtlb_cached_pge = 0xffffffffUL;
+
+	return 0;
+} /* end init_new_context() */
+
+/*****************************************************************************/
+/*
+ * make sure a kernel MMU context has a CPU context number
+ * - call with cxn_owners_lock held
+ */
+static unsigned get_cxn(mm_context_t *ctx)
+{
+	struct list_head *_p;
+	mm_context_t *p;
+	unsigned cxn;
+
+	if (!list_empty(&ctx->id_link)) {
+		list_move_tail(&ctx->id_link, &cxn_owners_lru);
+	}
+	else {
+		/* find the first unallocated context number
+		 * - 0 is reserved for the kernel
+		 */
+		cxn = find_next_zero_bit(&cxn_bitmap, NR_CXN, 1);
+		if (cxn < NR_CXN) {
+			set_bit(cxn, &cxn_bitmap);
+		}
+		else {
+			/* none remaining - need to steal someone else's cxn */
+			p = NULL;
+			list_for_each(_p, &cxn_owners_lru) {
+				p = list_entry(_p, mm_context_t, id_link);
+				if (!p->id_busy && p->id != cxn_pinned)
+					break;
+			}
+
+			BUG_ON(_p == &cxn_owners_lru);
+
+			cxn = p->id;
+			p->id = 0;
+			list_del_init(&p->id_link);
+			__flush_tlb_mm(cxn);
+		}
+
+		ctx->id = cxn;
+		list_add_tail(&ctx->id_link, &cxn_owners_lru);
+	}
+
+	return ctx->id;
+} /* end get_cxn() */
+
+/*****************************************************************************/
+/*
+ * restore the current TLB miss handler mapped page tables into the MMU context and set up a
+ * mapping for the page directory
+ */
+void change_mm_context(mm_context_t *old, mm_context_t *ctx, pgd_t *pgd)
+{
+	unsigned long _pgd;
+
+	_pgd = virt_to_phys(pgd);
+
+	/* save the state of the outgoing MMU context */
+	old->id_busy = 0;
+
+	asm volatile("movsg scr0,%0"   : "=r"(old->itlb_cached_pge));
+	asm volatile("movsg dampr4,%0" : "=r"(old->itlb_ptd_mapping));
+	asm volatile("movsg scr1,%0"   : "=r"(old->dtlb_cached_pge));
+	asm volatile("movsg dampr5,%0" : "=r"(old->dtlb_ptd_mapping));
+
+	/* select an MMU context number */
+	spin_lock(&cxn_owners_lock);
+	get_cxn(ctx);
+	ctx->id_busy = 1;
+	spin_unlock(&cxn_owners_lock);
+
+	asm volatile("movgs %0,cxnr"   : : "r"(ctx->id));
+
+	/* restore the state of the incoming MMU context */
+	asm volatile("movgs %0,scr0"   : : "r"(ctx->itlb_cached_pge));
+	asm volatile("movgs %0,dampr4" : : "r"(ctx->itlb_ptd_mapping));
+	asm volatile("movgs %0,scr1"   : : "r"(ctx->dtlb_cached_pge));
+	asm volatile("movgs %0,dampr5" : : "r"(ctx->dtlb_ptd_mapping));
+
+	/* map the PGD into uncached virtual memory */
+	asm volatile("movgs %0,ttbr"   : : "r"(_pgd));
+	asm volatile("movgs %0,dampr3"
+		     :: "r"(_pgd | xAMPRx_L | xAMPRx_M | xAMPRx_SS_16Kb |
+			    xAMPRx_S | xAMPRx_C | xAMPRx_V));
+
+} /* end change_mm_context() */
+
+/*****************************************************************************/
+/*
+ * finished with an MMU context number
+ */
+void destroy_context(struct mm_struct *mm)
+{
+	mm_context_t *ctx = &mm->context;
+
+	spin_lock(&cxn_owners_lock);
+
+	if (!list_empty(&ctx->id_link)) {
+		if (ctx->id == cxn_pinned)
+			cxn_pinned = -1;
+
+		list_del_init(&ctx->id_link);
+		clear_bit(ctx->id, &cxn_bitmap);
+		__flush_tlb_mm(ctx->id);
+		ctx->id = 0;
+	}
+
+	spin_unlock(&cxn_owners_lock);
+} /* end destroy_context() */
+
+/*****************************************************************************/
+/*
+ * display the MMU context currently a process is currently using
+ */
+#ifdef CONFIG_PROC_FS
+char *proc_pid_status_frv_cxnr(struct mm_struct *mm, char *buffer)
+{
+	spin_lock(&cxn_owners_lock);
+	buffer += sprintf(buffer, "CXNR: %u\n", mm->context.id);
+	spin_unlock(&cxn_owners_lock);
+
+	return buffer;
+} /* end proc_pid_status_frv_cxnr() */
+#endif
+
+/*****************************************************************************/
+/*
+ * (un)pin a process's mm_struct's MMU context ID
+ */
+int cxn_pin_by_pid(pid_t pid)
+{
+	struct task_struct *tsk;
+	struct mm_struct *mm = NULL;
+	int ret;
+
+	/* unpin if pid is zero */
+	if (pid == 0) {
+		cxn_pinned = -1;
+		return 0;
+	}
+
+	ret = -ESRCH;
+
+	/* get a handle on the mm_struct */
+	read_lock(&tasklist_lock);
+	tsk = find_task_by_pid(pid);
+	if (tsk) {
+		ret = -EINVAL;
+
+		task_lock(tsk);
+		if (tsk->mm) {
+			mm = tsk->mm;
+			atomic_inc(&mm->mm_users);
+			ret = 0;
+		}
+		task_unlock(tsk);
+	}
+	read_unlock(&tasklist_lock);
+
+	if (ret < 0)
+		return ret;
+
+	/* make sure it has a CXN and pin it */
+	spin_lock(&cxn_owners_lock);
+	cxn_pinned = get_cxn(&mm->context);
+	spin_unlock(&cxn_owners_lock);
+
+	mmput(mm);
+	return 0;
+} /* end cxn_pin_by_pid() */
diff -Nru a/arch/frv/mm/pgalloc.c b/arch/frv/mm/pgalloc.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/mm/pgalloc.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,159 @@
+/* pgalloc.c: page directory & page table allocation
+ *
+ * Copyright (C) 2004 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/sched.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <linux/highmem.h>
+#include <asm/pgalloc.h>
+#include <asm/page.h>
+#include <asm/cacheflush.h>
+
+pgd_t swapper_pg_dir[PTRS_PER_PGD] __attribute__((aligned(PAGE_SIZE)));
+kmem_cache_t *pgd_cache;
+
+pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
+{
+	pte_t *pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT);
+	if (pte)
+		clear_page(pte);
+	return pte;
+}
+
+struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address)
+{
+	struct page *page;
+
+#ifdef CONFIG_HIGHPTE
+	page = alloc_pages(GFP_KERNEL|__GFP_HIGHMEM|__GFP_REPEAT, 0);
+#else
+	page = alloc_pages(GFP_KERNEL|__GFP_REPEAT, 0);
+#endif
+	if (page)
+		clear_highpage(page);
+	flush_dcache_page(page);
+	return page;
+}
+
+void __set_pmd(pmd_t *pmdptr, unsigned long pmd)
+{
+	unsigned long *__ste_p = pmdptr->ste;
+	int loop;
+
+	if (!pmd) {
+		memset(__ste_p, 0, PME_SIZE);
+	}
+	else {
+		BUG_ON(pmd & (0x3f00 | xAMPRx_SS | 0xe));
+
+		for (loop = PME_SIZE; loop > 0; loop -= 4) {
+			*__ste_p++ = pmd;
+			pmd += __frv_PT_SIZE;
+		}
+	}
+
+	frv_dcache_writeback((unsigned long) pmdptr, (unsigned long) (pmdptr + 1));
+}
+
+/*
+ * List of all pgd's needed for non-PAE so it can invalidate entries
+ * in both cached and uncached pgd's; not needed for PAE since the
+ * kernel pmd is shared. If PAE were not to share the pmd a similar
+ * tactic would be needed. This is essentially codepath-based locking
+ * against pageattr.c; it is the unique case in which a valid change
+ * of kernel pagetables can't be lazily synchronized by vmalloc faults.
+ * vmalloc faults work because attached pagetables are never freed.
+ * If the locking proves to be non-performant, a ticketing scheme with
+ * checks at dup_mmap(), exec(), and other mmlist addition points
+ * could be used. The locking scheme was chosen on the basis of
+ * manfred's recommendations and having no core impact whatsoever.
+ * -- wli
+ */
+DEFINE_SPINLOCK(pgd_lock);
+struct page *pgd_list;
+
+static inline void pgd_list_add(pgd_t *pgd)
+{
+	struct page *page = virt_to_page(pgd);
+	page->index = (unsigned long) pgd_list;
+	if (pgd_list)
+		pgd_list->private = (unsigned long) &page->index;
+	pgd_list = page;
+	page->private = (unsigned long) &pgd_list;
+}
+
+static inline void pgd_list_del(pgd_t *pgd)
+{
+	struct page *next, **pprev, *page = virt_to_page(pgd);
+	next = (struct page *) page->index;
+	pprev = (struct page **) page->private;
+	*pprev = next;
+	if (next)
+		next->private = (unsigned long) pprev;
+}
+
+void pgd_ctor(void *pgd, kmem_cache_t *cache, unsigned long unused)
+{
+	unsigned long flags;
+
+	if (PTRS_PER_PMD == 1)
+		spin_lock_irqsave(&pgd_lock, flags);
+
+	memcpy((pgd_t *) pgd + USER_PGDS_IN_LAST_PML4,
+	       swapper_pg_dir + USER_PGDS_IN_LAST_PML4,
+	       (PTRS_PER_PGD - USER_PGDS_IN_LAST_PML4) * sizeof(pgd_t));
+
+	if (PTRS_PER_PMD > 1)
+		return;
+
+	pgd_list_add(pgd);
+	spin_unlock_irqrestore(&pgd_lock, flags);
+	memset(pgd, 0, USER_PGDS_IN_LAST_PML4 * sizeof(pgd_t));
+}
+
+/* never called when PTRS_PER_PMD > 1 */
+void pgd_dtor(void *pgd, kmem_cache_t *cache, unsigned long unused)
+{
+	unsigned long flags; /* can be called from interrupt context */
+
+	spin_lock_irqsave(&pgd_lock, flags);
+	pgd_list_del(pgd);
+	spin_unlock_irqrestore(&pgd_lock, flags);
+}
+
+pgd_t *pgd_alloc(struct mm_struct *mm)
+{
+	pgd_t *pgd;
+
+	pgd = kmem_cache_alloc(pgd_cache, GFP_KERNEL);
+	if (!pgd)
+		return pgd;
+
+	return pgd;
+}
+
+void pgd_free(pgd_t *pgd)
+{
+	/* in the non-PAE case, clear_page_tables() clears user pgd entries */
+	kmem_cache_free(pgd_cache, pgd);
+}
+
+void __init pgtable_cache_init(void)
+{
+	pgd_cache = kmem_cache_create("pgd",
+				      PTRS_PER_PGD * sizeof(pgd_t),
+				      PTRS_PER_PGD * sizeof(pgd_t),
+				      0,
+				      pgd_ctor,
+				      pgd_dtor);
+	if (!pgd_cache)
+		panic("pgtable_cache_init(): Cannot create pgd cache");
+}
diff -Nru a/arch/frv/mm/tlb-flush.S b/arch/frv/mm/tlb-flush.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/mm/tlb-flush.S	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,185 @@
+/* tlb-flush.S: TLB flushing routines
+ *
+ * Copyright (C) 2004 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/sys.h>
+#include <linux/config.h>
+#include <linux/linkage.h>
+#include <asm/page.h>
+#include <asm/ptrace.h>
+#include <asm/spr-regs.h>
+
+.macro DEBUG ch
+#	sethi.p		%hi(0xfeff9c00),gr4
+#	setlo		%lo(0xfeff9c00),gr4
+#	setlos		#\ch,gr5
+#	stbi		gr5,@(gr4,#0)
+#	membar
+.endm
+
+	.section	.rodata
+
+	# sizes corresponding to TPXR.LMAX
+	.balign		1
+__tlb_lmax_sizes:
+	.byte		0, 64, 0, 0
+	.byte		0, 0, 0, 0
+	.byte		0, 0, 0, 0
+	.byte		0, 0, 0, 0
+
+	.section	.text
+	.balign		4
+
+###############################################################################
+#
+# flush everything
+# - void __flush_tlb_all(void)
+#
+###############################################################################
+	.globl		__flush_tlb_all
+	.type		__flush_tlb_all,@function
+__flush_tlb_all:
+	DEBUG		'A'
+
+	# kill cached PGE value
+	setlos		#0xffffffff,gr4
+	movgs		gr4,scr0
+	movgs		gr4,scr1
+
+	# kill AMPR-cached TLB values
+	movgs		gr0,iamlr1
+	movgs		gr0,iampr1
+	movgs		gr0,damlr1
+	movgs		gr0,dampr1
+
+	# find out how many lines there are
+	movsg		tpxr,gr5
+	sethi.p		%hi(__tlb_lmax_sizes),gr4
+	srli		gr5,#TPXR_LMAX_SHIFT,gr5
+	setlo.p		%lo(__tlb_lmax_sizes),gr4
+	andi		gr5,#TPXR_LMAX_SMASK,gr5
+	ldub		@(gr4,gr5),gr4
+
+	# now, we assume that the TLB line step is page size in size
+	setlos.p	#PAGE_SIZE,gr5
+	setlos		#0,gr6
+1:
+	tlbpr		gr6,gr0,#6,#0
+	subicc.p	gr4,#1,gr4,icc0
+	add		gr6,gr5,gr6
+	bne		icc0,#2,1b
+
+	DEBUG		'B'
+	bralr
+
+	.size		__flush_tlb_all, .-__flush_tlb_all
+
+###############################################################################
+#
+# flush everything to do with one context
+# - void __flush_tlb_mm(unsigned long contextid [GR8])
+#
+###############################################################################
+	.globl		__flush_tlb_mm
+	.type		__flush_tlb_mm,@function
+__flush_tlb_mm:
+	DEBUG		'M'
+
+	# kill cached PGE value
+	setlos		#0xffffffff,gr4
+	movgs		gr4,scr0
+	movgs		gr4,scr1
+
+	# specify the context we want to flush
+	movgs		gr8,tplr
+
+	# find out how many lines there are
+	movsg		tpxr,gr5
+	sethi.p		%hi(__tlb_lmax_sizes),gr4
+	srli		gr5,#TPXR_LMAX_SHIFT,gr5
+	setlo.p		%lo(__tlb_lmax_sizes),gr4
+	andi		gr5,#TPXR_LMAX_SMASK,gr5
+	ldub		@(gr4,gr5),gr4
+
+	# now, we assume that the TLB line step is page size in size
+	setlos.p	#PAGE_SIZE,gr5
+	setlos		#0,gr6
+0:
+	tlbpr		gr6,gr0,#5,#0
+	subicc.p	gr4,#1,gr4,icc0
+	add		gr6,gr5,gr6
+	bne		icc0,#2,0b
+
+	DEBUG		'N'
+	bralr
+
+	.size		__flush_tlb_mm, .-__flush_tlb_mm
+
+###############################################################################
+#
+# flush a range of addresses from the TLB
+# - void __flush_tlb_page(unsigned long contextid [GR8],
+#			  unsigned long start [GR9])
+#
+###############################################################################
+	.globl		__flush_tlb_page
+	.type		__flush_tlb_page,@function
+__flush_tlb_page:
+	# kill cached PGE value
+	setlos		#0xffffffff,gr4
+	movgs		gr4,scr0
+	movgs		gr4,scr1
+
+	# specify the context we want to flush
+	movgs		gr8,tplr
+
+	# zap the matching TLB line and AMR values
+	setlos		#~(PAGE_SIZE-1),gr5
+	and		gr9,gr5,gr9
+	tlbpr		gr9,gr0,#5,#0
+
+	bralr
+
+	.size		__flush_tlb_page, .-__flush_tlb_page
+
+###############################################################################
+#
+# flush a range of addresses from the TLB
+# - void __flush_tlb_range(unsigned long contextid [GR8],
+#			   unsigned long start [GR9],
+#			   unsigned long end [GR10])
+#
+###############################################################################
+	.globl		__flush_tlb_range
+	.type		__flush_tlb_range,@function
+__flush_tlb_range:
+	# kill cached PGE value
+	setlos		#0xffffffff,gr4
+	movgs		gr4,scr0
+	movgs		gr4,scr1
+
+	# specify the context we want to flush
+	movgs		gr8,tplr
+
+	# round the start down to beginning of TLB line and end up to beginning of next TLB line
+	setlos.p	#~(PAGE_SIZE-1),gr5
+	setlos		#PAGE_SIZE,gr6
+	subi.p		gr10,#1,gr10
+	and		gr9,gr5,gr9
+	and		gr10,gr5,gr10
+2:
+	tlbpr		gr9,gr0,#5,#0
+	subcc.p		gr9,gr10,gr0,icc0
+	add		gr9,gr6,gr9
+	bne		icc0,#0,2b		; most likely a 1-page flush
+
+	bralr
+
+	.size		__flush_tlb_range, .-__flush_tlb_range
diff -Nru a/arch/frv/mm/tlb-miss.S b/arch/frv/mm/tlb-miss.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/mm/tlb-miss.S	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,631 @@
+/* tlb-miss.S: TLB miss handlers
+ *
+ * Copyright (C) 2004 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/sys.h>
+#include <linux/config.h>
+#include <linux/linkage.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/highmem.h>
+#include <asm/spr-regs.h>
+
+	.section	.text
+	.balign		4
+
+	.globl		__entry_insn_mmu_miss
+__entry_insn_mmu_miss:
+	break
+	nop
+
+	.globl		__entry_insn_mmu_exception
+__entry_insn_mmu_exception:
+	break
+	nop
+
+	.globl		__entry_data_mmu_miss
+__entry_data_mmu_miss:
+	break
+	nop
+
+	.globl		__entry_data_mmu_exception
+__entry_data_mmu_exception:
+	break
+	nop
+
+###############################################################################
+#
+# handle a lookup failure of one sort or another in a kernel TLB handler
+# On entry:
+#   GR29 - faulting address
+#   SCR2 - saved CCR
+#
+###############################################################################
+	.type		__tlb_kernel_fault,@function
+__tlb_kernel_fault:
+	# see if we're supposed to re-enable single-step mode upon return
+	sethi.p		%hi(__break_tlb_miss_return_break),gr30
+	setlo		%lo(__break_tlb_miss_return_break),gr30
+	movsg		pcsr,gr31
+
+	subcc		gr31,gr30,gr0,icc0
+	beq		icc0,#0,__tlb_kernel_fault_sstep
+
+	movsg		scr2,gr30
+	movgs		gr30,ccr
+	movgs		gr29,scr2			/* save EAR0 value */
+	sethi.p		%hi(__kernel_current_task),gr29
+	setlo		%lo(__kernel_current_task),gr29
+	ldi.p		@(gr29,#0),gr29			/* restore GR29 */
+
+	bra		__entry_kernel_handle_mmu_fault
+
+	# we've got to re-enable single-stepping
+__tlb_kernel_fault_sstep:
+	sethi.p		%hi(__break_tlb_miss_real_return_info),gr30
+	setlo		%lo(__break_tlb_miss_real_return_info),gr30
+	lddi		@(gr30,0),gr30
+	movgs		gr30,pcsr
+	movgs		gr31,psr
+
+	movsg		scr2,gr30
+	movgs		gr30,ccr
+	movgs		gr29,scr2			/* save EAR0 value */
+	sethi.p		%hi(__kernel_current_task),gr29
+	setlo		%lo(__kernel_current_task),gr29
+	ldi.p		@(gr29,#0),gr29			/* restore GR29 */
+	bra		__entry_kernel_handle_mmu_fault_sstep
+
+	.size		__tlb_kernel_fault, .-__tlb_kernel_fault
+
+###############################################################################
+#
+# handle a lookup failure of one sort or another in a user TLB handler
+# On entry:
+#   GR28 - faulting address
+#   SCR2 - saved CCR
+#
+###############################################################################
+	.type		__tlb_user_fault,@function
+__tlb_user_fault:
+	# see if we're supposed to re-enable single-step mode upon return
+	sethi.p		%hi(__break_tlb_miss_return_break),gr30
+	setlo		%lo(__break_tlb_miss_return_break),gr30
+	movsg		pcsr,gr31
+	subcc		gr31,gr30,gr0,icc0
+	beq		icc0,#0,__tlb_user_fault_sstep
+
+	movsg		scr2,gr30
+	movgs		gr30,ccr
+	bra		__entry_uspace_handle_mmu_fault
+
+	# we've got to re-enable single-stepping
+__tlb_user_fault_sstep:
+	sethi.p		%hi(__break_tlb_miss_real_return_info),gr30
+	setlo		%lo(__break_tlb_miss_real_return_info),gr30
+	lddi		@(gr30,0),gr30
+	movgs		gr30,pcsr
+	movgs		gr31,psr
+	movsg		scr2,gr30
+	movgs		gr30,ccr
+	bra		__entry_uspace_handle_mmu_fault_sstep
+
+	.size		__tlb_user_fault, .-__tlb_user_fault
+
+###############################################################################
+#
+# Kernel instruction TLB miss handler
+# On entry:
+#   GR1   - kernel stack pointer
+#   GR28  - saved exception frame pointer
+#   GR29  - faulting address
+#   GR31  - EAR0 ^ SCR0
+#   SCR0  - base of virtual range covered by cached PGE from last ITLB miss (or 0xffffffff)
+#   DAMR3 - mapped page directory
+#   DAMR4 - mapped page table as matched by SCR0
+#
+###############################################################################
+	.globl		__entry_kernel_insn_tlb_miss
+	.type		__entry_kernel_insn_tlb_miss,@function
+__entry_kernel_insn_tlb_miss:
+#if 0
+	sethi.p		%hi(0xe1200004),gr30
+	setlo		%lo(0xe1200004),gr30
+	st		gr0,@(gr30,gr0)
+	sethi.p		%hi(0xffc00100),gr30
+	setlo		%lo(0xffc00100),gr30
+	sth		gr30,@(gr30,gr0)
+	membar
+#endif
+
+	movsg		ccr,gr30			/* save CCR */
+	movgs		gr30,scr2
+
+	# see if the cached page table mapping is appropriate
+	srlicc.p	gr31,#26,gr0,icc0
+	setlos		0x3ffc,gr30
+	srli.p		gr29,#12,gr31			/* use EAR0[25:14] as PTE index */
+	bne		icc0,#0,__itlb_k_PTD_miss
+
+__itlb_k_PTD_mapped:
+	# access the PTD with EAR0[25:14]
+	# - DAMLR4 points to the virtual address of the appropriate page table
+	# - the PTD holds 4096 PTEs
+	# - the PTD must be accessed uncached
+	# - the PTE must be marked accessed if it was valid
+	#
+	and		gr31,gr30,gr31
+	movsg		damlr4,gr30
+	add		gr30,gr31,gr31
+	ldi		@(gr31,#0),gr30			/* fetch the PTE */
+	andicc		gr30,#_PAGE_PRESENT,gr0,icc0
+	ori.p		gr30,#_PAGE_ACCESSED,gr30
+	beq		icc0,#0,__tlb_kernel_fault	/* jump if PTE invalid */
+	sti.p		gr30,@(gr31,#0)			/* update the PTE */
+	andi		gr30,#~_PAGE_ACCESSED,gr30
+
+	# we're using IAMR1 as an extra TLB entry
+	# - punt the entry here (if valid) to the real TLB and then replace with the new PTE
+	# - need to check DAMR1 lest we cause an multiple-DAT-hit exception
+	# - IAMPR1 has no WP bit, and we mustn't lose WP information
+	movsg		iampr1,gr31
+	andicc		gr31,#xAMPRx_V,gr0,icc0
+	setlos.p	0xfffff000,gr31
+	beq		icc0,#0,__itlb_k_nopunt		/* punt not required */
+
+	movsg		iamlr1,gr31
+	movgs		gr31,tplr			/* set TPLR.CXN */
+	tlbpr		gr31,gr0,#4,#0			/* delete matches from TLB, IAMR1, DAMR1 */
+
+	movsg		dampr1,gr31
+	ori		gr31,#xAMPRx_V,gr31		/* entry was invalidated by tlbpr #4 */
+	movgs		gr31,tppr
+	movsg		iamlr1,gr31			/* set TPLR.CXN */
+	movgs		gr31,tplr
+	tlbpr		gr31,gr0,#2,#0			/* save to the TLB */
+	movsg		tpxr,gr31			/* check the TLB write error flag */
+	andicc.p	gr31,#TPXR_E,gr0,icc0
+	setlos		#0xfffff000,gr31
+	bne		icc0,#0,__tlb_kernel_fault
+
+__itlb_k_nopunt:
+
+	# assemble the new TLB entry
+	and		gr29,gr31,gr29
+	movsg		cxnr,gr31
+	or		gr29,gr31,gr29
+	movgs		gr29,iamlr1			/* xAMLR = address | context number */
+	movgs		gr30,iampr1
+	movgs		gr29,damlr1
+	movgs		gr30,dampr1
+
+	# return, restoring registers
+	movsg		scr2,gr30
+	movgs		gr30,ccr
+	sethi.p		%hi(__kernel_current_task),gr29
+	setlo		%lo(__kernel_current_task),gr29
+	ldi		@(gr29,#0),gr29
+	rett		#0
+	beq		icc0,#3,0			/* prevent icache prefetch */
+
+	# the PTE we want wasn't in the PTD we have mapped, so we need to go looking for a more
+	# appropriate page table and map that instead
+	#   - access the PGD with EAR0[31:26]
+	#   - DAMLR3 points to the virtual address of the page directory
+	#   - the PGD holds 64 PGEs and each PGE/PME points to a set of page tables
+__itlb_k_PTD_miss:
+	srli		gr29,#26,gr31			/* calculate PGE offset */
+	slli		gr31,#8,gr31			/* and clear bottom bits */
+
+	movsg		damlr3,gr30
+	ld		@(gr31,gr30),gr30		/* access the PGE */
+
+	andicc.p	gr30,#_PAGE_PRESENT,gr0,icc0
+	andicc		gr30,#xAMPRx_SS,gr0,icc1
+
+	# map this PTD instead and record coverage address
+	ori.p		gr30,#xAMPRx_L|xAMPRx_SS_16Kb|xAMPRx_S|xAMPRx_C|xAMPRx_V,gr30
+	beq		icc0,#0,__tlb_kernel_fault	/* jump if PGE not present */
+	slli.p		gr31,#18,gr31
+	bne		icc1,#0,__itlb_k_bigpage
+	movgs		gr30,dampr4
+	movgs		gr31,scr0
+
+	# we can now resume normal service
+	setlos		0x3ffc,gr30
+	srli.p		gr29,#12,gr31			/* use EAR0[25:14] as PTE index */
+	bra		__itlb_k_PTD_mapped
+
+__itlb_k_bigpage:
+	break
+	nop
+
+	.size		__entry_kernel_insn_tlb_miss, .-__entry_kernel_insn_tlb_miss
+
+###############################################################################
+#
+# Kernel data TLB miss handler
+# On entry:
+#   GR1   - kernel stack pointer
+#   GR28  - saved exception frame pointer
+#   GR29  - faulting address
+#   GR31  - EAR0 ^ SCR1
+#   SCR1  - base of virtual range covered by cached PGE from last DTLB miss (or 0xffffffff)
+#   DAMR3 - mapped page directory
+#   DAMR5 - mapped page table as matched by SCR1
+#
+###############################################################################
+	.globl		__entry_kernel_data_tlb_miss
+	.type		__entry_kernel_data_tlb_miss,@function
+__entry_kernel_data_tlb_miss:
+#if 0
+	sethi.p		%hi(0xe1200004),gr30
+	setlo		%lo(0xe1200004),gr30
+	st		gr0,@(gr30,gr0)
+	sethi.p		%hi(0xffc00100),gr30
+	setlo		%lo(0xffc00100),gr30
+	sth		gr30,@(gr30,gr0)
+	membar
+#endif
+
+	movsg		ccr,gr30			/* save CCR */
+	movgs		gr30,scr2
+
+	# see if the cached page table mapping is appropriate
+	srlicc.p	gr31,#26,gr0,icc0
+	setlos		0x3ffc,gr30
+	srli.p		gr29,#12,gr31			/* use EAR0[25:14] as PTE index */
+	bne		icc0,#0,__dtlb_k_PTD_miss
+
+__dtlb_k_PTD_mapped:
+	# access the PTD with EAR0[25:14]
+	# - DAMLR5 points to the virtual address of the appropriate page table
+	# - the PTD holds 4096 PTEs
+	# - the PTD must be accessed uncached
+	# - the PTE must be marked accessed if it was valid
+	#
+	and		gr31,gr30,gr31
+	movsg		damlr5,gr30
+	add		gr30,gr31,gr31
+	ldi		@(gr31,#0),gr30			/* fetch the PTE */
+	andicc		gr30,#_PAGE_PRESENT,gr0,icc0
+	ori.p		gr30,#_PAGE_ACCESSED,gr30
+	beq		icc0,#0,__tlb_kernel_fault	/* jump if PTE invalid */
+	sti.p		gr30,@(gr31,#0)			/* update the PTE */
+	andi		gr30,#~_PAGE_ACCESSED,gr30
+
+	# we're using DAMR1 as an extra TLB entry
+	# - punt the entry here (if valid) to the real TLB and then replace with the new PTE
+	# - need to check IAMR1 lest we cause an multiple-DAT-hit exception
+	movsg		dampr1,gr31
+	andicc		gr31,#xAMPRx_V,gr0,icc0
+	setlos.p	0xfffff000,gr31
+	beq		icc0,#0,__dtlb_k_nopunt		/* punt not required */
+
+	movsg		damlr1,gr31
+	movgs		gr31,tplr			/* set TPLR.CXN */
+	tlbpr		gr31,gr0,#4,#0			/* delete matches from TLB, IAMR1, DAMR1 */
+
+	movsg		dampr1,gr31
+	ori		gr31,#xAMPRx_V,gr31		/* entry was invalidated by tlbpr #4 */
+	movgs		gr31,tppr
+	movsg		damlr1,gr31			/* set TPLR.CXN */
+	movgs		gr31,tplr
+	tlbpr		gr31,gr0,#2,#0			/* save to the TLB */
+	movsg		tpxr,gr31			/* check the TLB write error flag */
+	andicc.p	gr31,#TPXR_E,gr0,icc0
+	setlos		#0xfffff000,gr31
+	bne		icc0,#0,__tlb_kernel_fault
+
+__dtlb_k_nopunt:
+
+	# assemble the new TLB entry
+	and		gr29,gr31,gr29
+	movsg		cxnr,gr31
+	or		gr29,gr31,gr29
+	movgs		gr29,iamlr1			/* xAMLR = address | context number */
+	movgs		gr30,iampr1
+	movgs		gr29,damlr1
+	movgs		gr30,dampr1
+
+	# return, restoring registers
+	movsg		scr2,gr30
+	movgs		gr30,ccr
+	sethi.p		%hi(__kernel_current_task),gr29
+	setlo		%lo(__kernel_current_task),gr29
+	ldi		@(gr29,#0),gr29
+	rett		#0
+	beq		icc0,#3,0			/* prevent icache prefetch */
+
+	# the PTE we want wasn't in the PTD we have mapped, so we need to go looking for a more
+	# appropriate page table and map that instead
+	#   - access the PGD with EAR0[31:26]
+	#   - DAMLR3 points to the virtual address of the page directory
+	#   - the PGD holds 64 PGEs and each PGE/PME points to a set of page tables
+__dtlb_k_PTD_miss:
+	srli		gr29,#26,gr31			/* calculate PGE offset */
+	slli		gr31,#8,gr31			/* and clear bottom bits */
+
+	movsg		damlr3,gr30
+	ld		@(gr31,gr30),gr30		/* access the PGE */
+
+	andicc.p	gr30,#_PAGE_PRESENT,gr0,icc0
+	andicc		gr30,#xAMPRx_SS,gr0,icc1
+
+	# map this PTD instead and record coverage address
+	ori.p		gr30,#xAMPRx_L|xAMPRx_SS_16Kb|xAMPRx_S|xAMPRx_C|xAMPRx_V,gr30
+	beq		icc0,#0,__tlb_kernel_fault	/* jump if PGE not present */
+	slli.p		gr31,#18,gr31
+	bne		icc1,#0,__dtlb_k_bigpage
+	movgs		gr30,dampr5
+	movgs		gr31,scr1
+
+	# we can now resume normal service
+	setlos		0x3ffc,gr30
+	srli.p		gr29,#12,gr31			/* use EAR0[25:14] as PTE index */
+	bra		__dtlb_k_PTD_mapped
+
+__dtlb_k_bigpage:
+	break
+	nop
+
+	.size		__entry_kernel_data_tlb_miss, .-__entry_kernel_data_tlb_miss
+
+###############################################################################
+#
+# Userspace instruction TLB miss handler (with PGE prediction)
+# On entry:
+#   GR28  - faulting address
+#   GR31  - EAR0 ^ SCR0
+#   SCR0  - base of virtual range covered by cached PGE from last ITLB miss (or 0xffffffff)
+#   DAMR3 - mapped page directory
+#   DAMR4 - mapped page table as matched by SCR0
+#
+###############################################################################
+	.globl		__entry_user_insn_tlb_miss
+	.type		__entry_user_insn_tlb_miss,@function
+__entry_user_insn_tlb_miss:
+#if 0
+	sethi.p		%hi(0xe1200004),gr30
+	setlo		%lo(0xe1200004),gr30
+	st		gr0,@(gr30,gr0)
+	sethi.p		%hi(0xffc00100),gr30
+	setlo		%lo(0xffc00100),gr30
+	sth		gr30,@(gr30,gr0)
+	membar
+#endif
+
+	movsg		ccr,gr30			/* save CCR */
+	movgs		gr30,scr2
+
+	# see if the cached page table mapping is appropriate
+	srlicc.p	gr31,#26,gr0,icc0
+	setlos		0x3ffc,gr30
+	srli.p		gr28,#12,gr31			/* use EAR0[25:14] as PTE index */
+	bne		icc0,#0,__itlb_u_PTD_miss
+
+__itlb_u_PTD_mapped:
+	# access the PTD with EAR0[25:14]
+	# - DAMLR4 points to the virtual address of the appropriate page table
+	# - the PTD holds 4096 PTEs
+	# - the PTD must be accessed uncached
+	# - the PTE must be marked accessed if it was valid
+	#
+	and		gr31,gr30,gr31
+	movsg		damlr4,gr30
+	add		gr30,gr31,gr31
+	ldi		@(gr31,#0),gr30			/* fetch the PTE */
+	andicc		gr30,#_PAGE_PRESENT,gr0,icc0
+	ori.p		gr30,#_PAGE_ACCESSED,gr30
+	beq		icc0,#0,__tlb_user_fault	/* jump if PTE invalid */
+	sti.p		gr30,@(gr31,#0)			/* update the PTE */
+	andi		gr30,#~_PAGE_ACCESSED,gr30
+
+	# we're using IAMR1/DAMR1 as an extra TLB entry
+	# - punt the entry here (if valid) to the real TLB and then replace with the new PTE
+	movsg		dampr1,gr31
+	andicc		gr31,#xAMPRx_V,gr0,icc0
+	setlos.p	0xfffff000,gr31
+	beq		icc0,#0,__itlb_u_nopunt		/* punt not required */
+
+	movsg		dampr1,gr31
+	movgs		gr31,tppr
+	movsg		damlr1,gr31			/* set TPLR.CXN */
+	movgs		gr31,tplr
+	tlbpr		gr31,gr0,#2,#0			/* save to the TLB */
+	movsg		tpxr,gr31			/* check the TLB write error flag */
+	andicc.p	gr31,#TPXR_E,gr0,icc0
+	setlos		#0xfffff000,gr31
+	bne		icc0,#0,__tlb_user_fault
+
+__itlb_u_nopunt:
+
+	# assemble the new TLB entry
+	and		gr28,gr31,gr28
+	movsg		cxnr,gr31
+	or		gr28,gr31,gr28
+	movgs		gr28,iamlr1			/* xAMLR = address | context number */
+	movgs		gr30,iampr1
+	movgs		gr28,damlr1
+	movgs		gr30,dampr1
+
+	# return, restoring registers
+	movsg		scr2,gr30
+	movgs		gr30,ccr
+	rett		#0
+	beq		icc0,#3,0			/* prevent icache prefetch */
+
+	# the PTE we want wasn't in the PTD we have mapped, so we need to go looking for a more
+	# appropriate page table and map that instead
+	#   - access the PGD with EAR0[31:26]
+	#   - DAMLR3 points to the virtual address of the page directory
+	#   - the PGD holds 64 PGEs and each PGE/PME points to a set of page tables
+__itlb_u_PTD_miss:
+	srli		gr28,#26,gr31			/* calculate PGE offset */
+	slli		gr31,#8,gr31			/* and clear bottom bits */
+
+	movsg		damlr3,gr30
+	ld		@(gr31,gr30),gr30		/* access the PGE */
+
+	andicc.p	gr30,#_PAGE_PRESENT,gr0,icc0
+	andicc		gr30,#xAMPRx_SS,gr0,icc1
+
+	# map this PTD instead and record coverage address
+	ori.p		gr30,#xAMPRx_L|xAMPRx_SS_16Kb|xAMPRx_S|xAMPRx_C|xAMPRx_V,gr30
+	beq		icc0,#0,__tlb_user_fault	/* jump if PGE not present */
+	slli.p		gr31,#18,gr31
+	bne		icc1,#0,__itlb_u_bigpage
+	movgs		gr30,dampr4
+	movgs		gr31,scr0
+
+	# we can now resume normal service
+	setlos		0x3ffc,gr30
+	srli.p		gr28,#12,gr31			/* use EAR0[25:14] as PTE index */
+	bra		__itlb_u_PTD_mapped
+
+__itlb_u_bigpage:
+	break
+	nop
+
+	.size		__entry_user_insn_tlb_miss, .-__entry_user_insn_tlb_miss
+
+###############################################################################
+#
+# Userspace data TLB miss handler
+# On entry:
+#   GR28  - faulting address
+#   GR31  - EAR0 ^ SCR1
+#   SCR1  - base of virtual range covered by cached PGE from last DTLB miss (or 0xffffffff)
+#   DAMR3 - mapped page directory
+#   DAMR5 - mapped page table as matched by SCR1
+#
+###############################################################################
+	.globl		__entry_user_data_tlb_miss
+	.type		__entry_user_data_tlb_miss,@function
+__entry_user_data_tlb_miss:
+#if 0
+	sethi.p		%hi(0xe1200004),gr30
+	setlo		%lo(0xe1200004),gr30
+	st		gr0,@(gr30,gr0)
+	sethi.p		%hi(0xffc00100),gr30
+	setlo		%lo(0xffc00100),gr30
+	sth		gr30,@(gr30,gr0)
+	membar
+#endif
+
+	movsg		ccr,gr30			/* save CCR */
+	movgs		gr30,scr2
+
+	# see if the cached page table mapping is appropriate
+	srlicc.p	gr31,#26,gr0,icc0
+	setlos		0x3ffc,gr30
+	srli.p		gr28,#12,gr31			/* use EAR0[25:14] as PTE index */
+	bne		icc0,#0,__dtlb_u_PTD_miss
+
+__dtlb_u_PTD_mapped:
+	# access the PTD with EAR0[25:14]
+	# - DAMLR5 points to the virtual address of the appropriate page table
+	# - the PTD holds 4096 PTEs
+	# - the PTD must be accessed uncached
+	# - the PTE must be marked accessed if it was valid
+	#
+	and		gr31,gr30,gr31
+	movsg		damlr5,gr30
+
+__dtlb_u_using_iPTD:
+	add		gr30,gr31,gr31
+	ldi		@(gr31,#0),gr30			/* fetch the PTE */
+	andicc		gr30,#_PAGE_PRESENT,gr0,icc0
+	ori.p		gr30,#_PAGE_ACCESSED,gr30
+	beq		icc0,#0,__tlb_user_fault	/* jump if PTE invalid */
+	sti.p		gr30,@(gr31,#0)			/* update the PTE */
+	andi		gr30,#~_PAGE_ACCESSED,gr30
+
+	# we're using DAMR1 as an extra TLB entry
+	# - punt the entry here (if valid) to the real TLB and then replace with the new PTE
+	movsg		dampr1,gr31
+	andicc		gr31,#xAMPRx_V,gr0,icc0
+	setlos.p	0xfffff000,gr31
+	beq		icc0,#0,__dtlb_u_nopunt		/* punt not required */
+
+	movsg		dampr1,gr31
+	movgs		gr31,tppr
+	movsg		damlr1,gr31			/* set TPLR.CXN */
+	movgs		gr31,tplr
+	tlbpr		gr31,gr0,#2,#0			/* save to the TLB */
+	movsg		tpxr,gr31			/* check the TLB write error flag */
+	andicc.p	gr31,#TPXR_E,gr0,icc0
+	setlos		#0xfffff000,gr31
+	bne		icc0,#0,__tlb_user_fault
+
+__dtlb_u_nopunt:
+
+	# assemble the new TLB entry
+	and		gr28,gr31,gr28
+	movsg		cxnr,gr31
+	or		gr28,gr31,gr28
+	movgs		gr28,iamlr1			/* xAMLR = address | context number */
+	movgs		gr30,iampr1
+	movgs		gr28,damlr1
+	movgs		gr30,dampr1
+
+	# return, restoring registers
+	movsg		scr2,gr30
+	movgs		gr30,ccr
+	rett		#0
+	beq		icc0,#3,0			/* prevent icache prefetch */
+
+	# the PTE we want wasn't in the PTD we have mapped, so we need to go looking for a more
+	# appropriate page table and map that instead
+	#   - first of all, check the insn PGE cache - we may well get a hit there
+	#   - access the PGD with EAR0[31:26]
+	#   - DAMLR3 points to the virtual address of the page directory
+	#   - the PGD holds 64 PGEs and each PGE/PME points to a set of page tables
+__dtlb_u_PTD_miss:
+	movsg		scr0,gr31			/* consult the insn-PGE-cache key */
+	xor		gr28,gr31,gr31
+	srlicc		gr31,#26,gr0,icc0
+	srli		gr28,#12,gr31			/* use EAR0[25:14] as PTE index */
+	bne		icc0,#0,__dtlb_u_iPGE_miss
+
+	# what we're looking for is covered by the insn-PGE-cache
+	setlos		0x3ffc,gr30
+	and		gr31,gr30,gr31
+	movsg		damlr4,gr30
+	bra		__dtlb_u_using_iPTD
+
+__dtlb_u_iPGE_miss:
+	srli		gr28,#26,gr31			/* calculate PGE offset */
+	slli		gr31,#8,gr31			/* and clear bottom bits */
+
+	movsg		damlr3,gr30
+	ld		@(gr31,gr30),gr30		/* access the PGE */
+
+	andicc.p	gr30,#_PAGE_PRESENT,gr0,icc0
+	andicc		gr30,#xAMPRx_SS,gr0,icc1
+
+	# map this PTD instead and record coverage address
+	ori.p		gr30,#xAMPRx_L|xAMPRx_SS_16Kb|xAMPRx_S|xAMPRx_C|xAMPRx_V,gr30
+	beq		icc0,#0,__tlb_user_fault	/* jump if PGE not present */
+	slli.p		gr31,#18,gr31
+	bne		icc1,#0,__dtlb_u_bigpage
+	movgs		gr30,dampr5
+	movgs		gr31,scr1
+
+	# we can now resume normal service
+	setlos		0x3ffc,gr30
+	srli.p		gr28,#12,gr31			/* use EAR0[25:14] as PTE index */
+	bra		__dtlb_u_PTD_mapped
+
+__dtlb_u_bigpage:
+	break
+	nop
+
+	.size		__entry_user_data_tlb_miss, .-__entry_user_data_tlb_miss
diff -Nru a/arch/frv/mm/unaligned.c b/arch/frv/mm/unaligned.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/frv/mm/unaligned.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,218 @@
+/* unaligned.c: unalignment fixup handler for CPUs on which it is supported (FR451 only)
+ *
+ * Copyright (C) 2004 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/config.h>
+#include <linux/sched.h>
+#include <linux/signal.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/types.h>
+#include <linux/user.h>
+#include <linux/string.h>
+#include <linux/linkage.h>
+#include <linux/init.h>
+
+#include <asm/setup.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+
+#if 0
+#define kdebug(fmt, ...) printk("FDPIC "fmt"\n" ,##__VA_ARGS__ )
+#else
+#define kdebug(fmt, ...) do {} while(0)
+#endif
+
+#define _MA_SIGNED	0x01
+#define _MA_HALF	0x02
+#define _MA_WORD	0x04
+#define _MA_DWORD	0x08
+#define _MA_SZ_MASK	0x0e
+#define _MA_LOAD	0x10
+#define _MA_STORE	0x20
+#define _MA_UPDATE	0x40
+#define _MA_IMM		0x80
+
+#define _MA_LDxU	_MA_LOAD | _MA_UPDATE
+#define _MA_LDxI	_MA_LOAD | _MA_IMM
+#define _MA_STxU	_MA_STORE | _MA_UPDATE
+#define _MA_STxI	_MA_STORE | _MA_IMM
+
+static const uint8_t tbl_LDGRk_reg[0x40] = {
+	[0x02] = _MA_LOAD | _MA_HALF | _MA_SIGNED,	/* LDSH  @(GRi,GRj),GRk */
+	[0x03] = _MA_LOAD | _MA_HALF,			/* LDUH  @(GRi,GRj),GRk */
+	[0x04] = _MA_LOAD | _MA_WORD,			/* LD	 @(GRi,GRj),GRk */
+	[0x05] = _MA_LOAD | _MA_DWORD,			/* LDD	 @(GRi,GRj),GRk */
+	[0x12] = _MA_LDxU | _MA_HALF | _MA_SIGNED,	/* LDSHU @(GRi,GRj),GRk */
+	[0x13] = _MA_LDxU | _MA_HALF,			/* LDUHU @(GRi,GRj),GRk */
+	[0x14] = _MA_LDxU | _MA_WORD,			/* LDU	 @(GRi,GRj),GRk */
+	[0x15] = _MA_LDxU | _MA_DWORD,			/* LDDU	 @(GRi,GRj),GRk */
+};
+
+static const uint8_t tbl_STGRk_reg[0x40] = {
+	[0x01] = _MA_STORE | _MA_HALF,			/* STH   @(GRi,GRj),GRk */
+	[0x02] = _MA_STORE | _MA_WORD,			/* ST	 @(GRi,GRj),GRk */
+	[0x03] = _MA_STORE | _MA_DWORD,			/* STD	 @(GRi,GRj),GRk */
+	[0x11] = _MA_STxU  | _MA_HALF,			/* STHU  @(GRi,GRj),GRk */
+	[0x12] = _MA_STxU  | _MA_WORD,			/* STU	 @(GRi,GRj),GRk */
+	[0x13] = _MA_STxU  | _MA_DWORD,			/* STDU	 @(GRi,GRj),GRk */
+};
+
+static const uint8_t tbl_LDSTGRk_imm[0x80] = {
+	[0x31] = _MA_LDxI | _MA_HALF | _MA_SIGNED,	/* LDSHI @(GRi,d12),GRk */
+	[0x32] = _MA_LDxI | _MA_WORD,			/* LDI   @(GRi,d12),GRk */
+	[0x33] = _MA_LDxI | _MA_DWORD,			/* LDDI  @(GRi,d12),GRk */
+	[0x36] = _MA_LDxI | _MA_HALF,			/* LDUHI @(GRi,d12),GRk */
+	[0x51] = _MA_STxI | _MA_HALF,			/* STHI  @(GRi,d12),GRk */
+	[0x52] = _MA_STxI | _MA_WORD,			/* STI   @(GRi,d12),GRk */
+	[0x53] = _MA_STxI | _MA_DWORD,			/* STDI  @(GRi,d12),GRk */
+};
+
+
+/*****************************************************************************/
+/*
+ * see if we can handle the exception by fixing up a misaligned memory access
+ */
+int handle_misalignment(unsigned long esr0, unsigned long ear0, unsigned long epcr0)
+{
+	unsigned long insn, addr, *greg;
+	int GRi, GRj, GRk, D12, op;
+
+	union {
+		uint64_t _64;
+		uint32_t _32[2];
+		uint16_t _16;
+		uint8_t _8[8];
+	} x;
+
+	if (!(esr0 & ESR0_EAV) || !(epcr0 & EPCR0_V) || !(ear0 & 7))
+		return -EAGAIN;
+
+	epcr0 &= EPCR0_PC;
+
+	if (__frame->pc != epcr0) {
+		kdebug("MISALIGN: Execution not halted on excepting instruction\n");
+		BUG();
+	}
+
+	if (__get_user(insn, (unsigned long *) epcr0) < 0)
+		return -EFAULT;
+
+	/* determine the instruction type first */
+	switch ((insn >> 18) & 0x7f) {
+	case 0x2:
+		/* LDx @(GRi,GRj),GRk */
+		op = tbl_LDGRk_reg[(insn >> 6) & 0x3f];
+		break;
+
+	case 0x3:
+		/* STx GRk,@(GRi,GRj) */
+		op = tbl_STGRk_reg[(insn >> 6) & 0x3f];
+		break;
+
+	default:
+		op = tbl_LDSTGRk_imm[(insn >> 18) & 0x7f];
+		break;
+	}
+
+	if (!op)
+		return -EAGAIN;
+
+	kdebug("MISALIGN: pc=%08lx insn=%08lx ad=%08lx op=%02x\n", epcr0, insn, ear0, op);
+
+	memset(&x, 0xba, 8);
+
+	/* validate the instruction parameters */
+	greg = (unsigned long *) &__frame->tbr;
+
+	GRi = (insn >> 12) & 0x3f;
+	GRk = (insn >> 25) & 0x3f;
+
+	if (GRi > 31 || GRk > 31)
+		return -ENOENT;
+
+	if (op & _MA_DWORD && GRk & 1)
+		return -EINVAL;
+
+	if (op & _MA_IMM) {
+		D12 = insn & 0xfff;
+		asm ("slli %0,#20,%0 ! srai %0,#20,%0" : "=r"(D12) : "0"(D12)); /* sign extend */
+		addr = (GRi ? greg[GRi] : 0) + D12;
+	}
+	else {
+		GRj = (insn >>  0) & 0x3f;
+		if (GRj > 31)
+			return -ENOENT;
+		addr = (GRi ? greg[GRi] : 0) + (GRj ? greg[GRj] : 0);
+	}
+
+	if (addr != ear0) {
+		kdebug("MISALIGN: Calculated addr (%08lx) does not match EAR0 (%08lx)\n",
+		       addr, ear0);
+		return -EFAULT;
+	}
+
+	/* check the address is okay */
+	if (user_mode(__frame) && ___range_ok(ear0, 8) < 0)
+		return -EFAULT;
+
+	/* perform the memory op */
+	if (op & _MA_STORE) {
+		/* perform a store */
+		x._32[0] = 0;
+		if (GRk != 0) {
+			if (op & _MA_HALF) {
+				x._16 = greg[GRk];
+			}
+			else {
+				x._32[0] = greg[GRk];
+			}
+		}
+		if (op & _MA_DWORD)
+			x._32[1] = greg[GRk + 1];
+
+		kdebug("MISALIGN: Store GR%d { %08x:%08x } -> %08lx (%dB)\n",
+		       GRk, x._32[1], x._32[0], addr, op & _MA_SZ_MASK);
+
+		if (__memcpy_user((void *) addr, &x, op & _MA_SZ_MASK) != 0)
+			return -EFAULT;
+	}
+	else {
+		/* perform a load */
+		if (__memcpy_user(&x, (void *) addr, op & _MA_SZ_MASK) != 0)
+			return -EFAULT;
+
+		if (op & _MA_HALF) {
+			if (op & _MA_SIGNED)
+				asm ("slli %0,#16,%0 ! srai %0,#16,%0"
+				     : "=r"(x._32[0]) : "0"(x._16));
+			else
+				asm ("sethi #0,%0"
+				     : "=r"(x._32[0]) : "0"(x._16));
+		}
+
+		kdebug("MISALIGN: Load %08lx (%dB) -> GR%d, { %08x:%08x }\n",
+		       addr, op & _MA_SZ_MASK, GRk, x._32[1], x._32[0]);
+
+		if (GRk != 0)
+			greg[GRk] = x._32[0];
+		if (op & _MA_DWORD)
+			greg[GRk + 1] = x._32[1];
+	}
+
+	/* update the base pointer if required */
+	if (op & _MA_UPDATE)
+		greg[GRi] = addr;
+
+	/* well... we've done that insn */
+	__frame->pc = __frame->pc + 4;
+
+	return 0;
+} /* end handle_misalignment() */
diff -Nru a/arch/h8300/Kconfig b/arch/h8300/Kconfig
--- a/arch/h8300/Kconfig	2005-03-01 23:39:09 -08:00
+++ b/arch/h8300/Kconfig	2005-03-01 23:39:09 -08:00
@@ -33,6 +33,10 @@
 	bool
 	default n
 
+config GENERIC_CALIBRATE_DELAY
+	bool
+	default y
+
 config ISA
 	bool
 	default y
diff -Nru a/arch/h8300/Makefile b/arch/h8300/Makefile
--- a/arch/h8300/Makefile	2005-03-01 23:38:53 -08:00
+++ b/arch/h8300/Makefile	2005-03-01 23:38:53 -08:00
@@ -7,9 +7,6 @@
 #
 # (C) Copyright 2002,2003 Yoshinori Sato <ysato@users.sourceforge.jp>
 #
-ifndef include-config
--include $(TOPDIR)/.config
-endif
 
 platform-$(CONFIG_CPU_H8300H)	:= h8300h
 platform-$(CONFIG_CPU_H8S)	:= h8s
@@ -47,9 +44,11 @@
 head-y := arch/$(ARCH)/platform/$(platform-y)/$(board-y)/crt0_$(model-y).o
 
 core-y	+= arch/$(ARCH)/kernel/ \
-	   arch/$(ARCH)/mm/ \
-	   arch/$(ARCH)/platform/$(PLATFORM)/ \
+	   arch/$(ARCH)/mm/
+ifdef PLATFORM
+core-y	+= arch/$(ARCH)/platform/$(PLATFORM)/ \
 	   arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/
+endif
 
 libs-y	+= arch/$(ARCH)/lib/ $(LIBGCC)
 
diff -Nru a/arch/h8300/defconfig b/arch/h8300/defconfig
--- a/arch/h8300/defconfig	2005-03-01 23:38:53 -08:00
+++ b/arch/h8300/defconfig	2005-03-01 23:38:53 -08:00
@@ -1,5 +1,7 @@
 #
 # Automatically generated make config: don't edit
+# Linux kernel version: 2.6.11-rc1
+# Sun Jan 16 17:24:38 2005
 #
 CONFIG_H8300=y
 # CONFIG_MMU is not set
@@ -8,32 +10,37 @@
 CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_ISA=y
+# CONFIG_PCI is not set
 
 #
 # Code maturity level options
 #
 CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
-CONFIG_STANDALONE=y
 CONFIG_BROKEN_ON_SMP=y
 
 #
 # General setup
 #
-# CONFIG_SYSVIPC is not set
+CONFIG_LOCALVERSION=""
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_SYSCTL is not set
+# CONFIG_AUDIT is not set
 CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_HOTPLUG is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_EMBEDDED=y
-CONFIG_KALLSYMS=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
+# CONFIG_KALLSYMS 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_TINY_SHMEM=y
 
 #
 # Loadable module support
@@ -43,32 +50,42 @@
 #
 # Processor type and features
 #
-# CONFIG_H8300H_GENERIC is not set
+CONFIG_H8300H_GENERIC=y
 # CONFIG_H8300H_AKI3068NET is not set
 # CONFIG_H8300H_H8MAX is not set
-CONFIG_H8300H_SIM=y
+# CONFIG_H8300H_SIM is not set
+# CONFIG_H8S_GENERIC is not set
 # CONFIG_H8S_EDOSK2674 is not set
 # CONFIG_H8S_SIM is not set
+
+#
+# Detail Selection
+#
 # CONFIG_H83002 is not set
-CONFIG_H83007=y
+# CONFIG_H83007 is not set
 # CONFIG_H83048 is not set
-# CONFIG_H83068 is not set
-# CONFIG_H8S2678 is not set
-CONFIG_CPU_H8300H=y
-CONFIG_CPU_CLOCK=16000
+CONFIG_H83068=y
+CONFIG_CPU_CLOCK=20000
 # CONFIG_RAMKERNEL is not set
 CONFIG_ROMKERNEL=y
+CONFIG_CPU_H8300H=y
+# CONFIG_PREEMPT is not set
 
 #
 # Executable file formats
 #
 CONFIG_BINFMT_FLAT=y
-# CONFIG_BINFMT_ZFLAT is not set
+CONFIG_BINFMT_ZFLAT=y
+# CONFIG_BINFMT_SHARED_FLAT is not set
 # CONFIG_BINFMT_MISC is not set
 
 #
 # 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
 
 #
 # Memory Technology Devices (MTD)
@@ -76,7 +93,7 @@
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
 CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_CONCAT=y
 # CONFIG_MTD_REDBOOT_PARTS is not set
 # CONFIG_MTD_CMDLINE_PARTS is not set
 
@@ -94,10 +111,19 @@
 #
 # 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=y
-# CONFIG_MTD_ROM is not set
+CONFIG_MTD_ROM=y
 # CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_OBSOLETE_CHIPS is not set
 
 #
 # Mapping drivers for chip access
@@ -109,8 +135,10 @@
 # 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
@@ -130,114 +158,30 @@
 # CONFIG_BLK_DEV_FD is not set
 # CONFIG_BLK_DEV_XD is not set
 # CONFIG_BLK_DEV_LOOP is not set
-# CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
-# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CDROM_PKTCDVD is not set
 
 #
-# ATA/ATAPI/MFM/RLL support
+# IO Schedulers
 #
-# CONFIG_IDE is not set
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
 
 #
-# IDE Extra configuration
+# ATA/ATAPI/MFM/RLL support
 #
+# CONFIG_IDE is not set
 
 #
 # Networking support
 #
-CONFIG_NET=y
-
-#
-# Networking options
-#
-# CONFIG_PACKET is not set
-# CONFIG_NETLINK_DEV is not set
-# CONFIG_UNIX is not set
-# CONFIG_NET_KEY is not set
-# CONFIG_INET is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_DECNET is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_NETFILTER is not set
-# CONFIG_ATM is not set
-# CONFIG_VLAN_8021Q 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_WAN_ROUTER is not set
-# CONFIG_NET_HW_FLOWCONTROL is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-CONFIG_NETDEVICES=y
-
-#
-# ARCnet devices
-#
-# CONFIG_ARCNET is not set
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
-# CONFIG_NET_ETHERNET is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-
-#
-# Ethernet (10000 Mbit)
-#
-# CONFIG_PPP is not set
-# CONFIG_SLIP is not set
-
-#
-# Wireless LAN (non-hamradio)
-#
-# CONFIG_NET_RADIO is not set
-
-#
-# Token Ring devices
-#
-# CONFIG_TR is not set
-# CONFIG_SHAPER is not set
-
-#
-# Wan interfaces
-#
-# CONFIG_WAN is not set
-
-#
-# Amateur Radio support
-#
-# CONFIG_HAMRADIO is not set
-
-#
-# IrDA (infrared) support
-#
-# CONFIG_IRDA is not set
-
-#
-# Bluetooth support
-#
-# CONFIG_BT is not set
+# CONFIG_NET is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
 
 #
 # Input device support
@@ -264,9 +208,6 @@
 # Character devices
 #
 # CONFIG_VT is not set
-# CONFIG_SERIAL is not set
-CONFIG_SH_SCI=y
-CONFIG_SERIAL_CONSOLE=y
 
 #
 # Unix98 PTY support
@@ -281,6 +222,10 @@
 #
 # Non-8250 serial port support
 #
+CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
 
 #
 # I2C support
@@ -290,6 +235,12 @@
 #
 # 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
@@ -308,6 +259,7 @@
 # CONFIG_MINIX_FS is not set
 CONFIG_ROMFS_FS=y
 # CONFIG_QUOTA is not set
+# CONFIG_DNOTIFY is not set
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
 
@@ -320,14 +272,15 @@
 #
 # 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
 
 #
 # Pseudo filesystems
 #
 CONFIG_PROC_FS=y
-CONFIG_PROC_KCORE=y
+# CONFIG_SYSFS is not set
 # CONFIG_DEVFS_FS is not set
 # CONFIG_TMPFS is not set
 # CONFIG_HUGETLB_PAGE is not set
@@ -339,6 +292,7 @@
 # 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
@@ -352,11 +306,6 @@
 # CONFIG_UFS_FS is not set
 
 #
-# Network File Systems
-#
-# CONFIG_EXPORTFS is not set
-
-#
 # Partition Types
 #
 # CONFIG_PARTITION_ADVANCED is not set
@@ -370,18 +319,23 @@
 #
 # Kernel hacking
 #
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_FS is not set
 CONFIG_FULLDEBUG=y
-# CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_HIGHPROFILE is not set
 CONFIG_NO_KERNEL_MSG=y
-CONFIG_GDB_MAGICPRINT=y
 # CONFIG_SYSCALL_PRINT is not set
+# CONFIG_GDB_DEBUG is not set
+# CONFIG_CONFIG_SH_STANDARD_BIOS is not set
 # CONFIG_DEFAULT_CMDLINE is not set
 # CONFIG_BLKDEV_RESERVE is not set
 
 #
 # Security options
 #
+# CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 
 #
@@ -390,6 +344,13 @@
 # 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
diff -Nru a/arch/h8300/kernel/syscalls.S b/arch/h8300/kernel/syscalls.S
--- a/arch/h8300/kernel/syscalls.S	2005-03-01 23:38:54 -08:00
+++ b/arch/h8300/kernel/syscalls.S	2005-03-01 23:38:54 -08:00
@@ -289,6 +289,21 @@
 	.long SYMBOL_NAME(sys_utimes)
  	.long SYMBOL_NAME(sys_fadvise64_64)
 	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_vserver */
+	.long SYMBOL_NAME(sys_mbind)
+	.long SYMBOL_NAME(sys_get_mempolicy)
+	.long SYMBOL_NAME(sys_set_mempolicy)
+	.long SYMBOL_NAME(sys_mq_open)
+	.long SYMBOL_NAME(sys_mq_unlink)
+	.long SYMBOL_NAME(sys_mq_timedsend)
+	.long SYMBOL_NAME(sys_mq_timedreceive)	/* 280 */
+	.long SYMBOL_NAME(sys_mq_notify)
+	.long SYMBOL_NAME(sys_mq_getsetattr)
+	.long SYMBOL_NAME(sys_ni_syscall)	/* reserved for kexec */
+	.long SYMBOL_NAME(sys_waitid)
+	.long SYMBOL_NAME(sys_ni_syscall)	/* 285 */ /* available */
+	.long SYMBOL_NAME(sys_add_key)
+	.long SYMBOL_NAME(sys_request_key)
+	.long SYMBOL_NAME(sys_keyctl)
 
 	.rept NR_syscalls-(.-SYMBOL_NAME(sys_call_table))/4
 		.long SYMBOL_NAME(sys_ni_syscall)
diff -Nru a/arch/i386/Kconfig b/arch/i386/Kconfig
--- a/arch/i386/Kconfig	2005-03-01 23:38:53 -08:00
+++ b/arch/i386/Kconfig	2005-03-01 23:38:53 -08:00
@@ -373,6 +373,10 @@
 	depends on !M386
 	default y
 
+config GENERIC_CALIBRATE_DELAY
+	bool
+	default y
+
 config X86_PPRO_FENCE
 	bool
 	depends on M686 || M586MMX || M586TSC || M586 || M486 || M386
@@ -513,6 +517,17 @@
 	  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.
+
 config X86_UP_APIC
 	bool "Local APIC support on uniprocessors" if !SMP
 	depends on !(X86_VISWS || X86_VOYAGER)
@@ -827,7 +842,6 @@
 	depends on ACPI
 	default n
 	---help---
-
 	This enables the the kernel to boot on EFI platforms using
 	system configuration information passed to it from the firmware.
 	This also enables the kernel to use any EFI runtime services that are
@@ -866,7 +880,7 @@
 	depends on EXPERIMENTAL
 	default n
 	help
-	Compile the kernel with -mregparm=3. This uses an different ABI
+	Compile the kernel with -mregparm=3. This uses a different ABI
 	and passes the first three arguments of a function call in registers.
 	This will probably break binary only modules.
 
@@ -1116,6 +1130,8 @@
 	depends on PCI && (PCI_GOMMCONFIG || (PCI_GOANY && ACPI))
 	select ACPI_BOOT
 	default y
+
+source "drivers/pci/pcie/Kconfig"
 
 source "drivers/pci/Kconfig"
 
diff -Nru a/arch/i386/boot/edd.S b/arch/i386/boot/edd.S
--- a/arch/i386/boot/edd.S	2005-03-01 23:38:52 -08:00
+++ b/arch/i386/boot/edd.S	2005-03-01 23:38:52 -08:00
@@ -1,5 +1,6 @@
 /*
  * BIOS Enhanced Disk Drive support
+ * Copyright (C) 2002, 2003, 2004 Dell, Inc.
  * by Matt Domsch <Matt_Domsch@dell.com> October 2002
  * conformant to T13 Committee www.t13.org
  *   projects 1572D, 1484D, 1386D, 1226DT
@@ -7,14 +8,52 @@
  *	and Andrew Wilks <Andrew_Wilks@dell.com> September 2003, June 2004
  * legacy CHS retreival by Patrick J. LoPresti <patl@users.sourceforge.net>
  *      March 2004
+ * Command line option parsing, Matt Domsch, November 2004
  */
 
 #include <linux/edd.h>
+#include <asm/setup.h>
 
 #if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
+	movb	$0, (EDD_MBR_SIG_NR_BUF)
+	movb	$0, (EDDNR)
+
+# Check the command line for two options:
+# edd=of  disables EDD completely  (edd=off)
+# edd=sk  skips the MBR test    (edd=skipmbr)
+	pushl	%esi
+    	cmpl	$0, %cs:cmd_line_ptr
+	jz	done_cl
+	movl	%cs:(cmd_line_ptr), %esi
+# ds:esi has the pointer to the command line now
+	movl	$(COMMAND_LINE_SIZE-7), %ecx
+# loop through kernel command line one byte at a time
+cl_loop:
+	cmpl	$EDD_CL_EQUALS, (%si)
+	jz	found_edd_equals
+	incl	%esi
+	loop	cl_loop
+	jmp	done_cl
+found_edd_equals:
+# only looking at first two characters after equals
+    	addl	$4, %esi
+	cmpw	$EDD_CL_OFF, (%si)	# edd=of
+	jz	do_edd_off
+	cmpw	$EDD_CL_SKIP, (%si)	# edd=sk
+	jz	do_edd_skipmbr
+	jmp	done_cl
+do_edd_skipmbr:
+    	popl	%esi
+	jmp	edd_start
+do_edd_off:
+	popl	%esi
+	jmp	edd_done
+done_cl:
+	popl	%esi
+
+
 # Read the first sector of each BIOS disk device and store the 4-byte signature
 edd_mbr_sig_start:
-	movb	$0, (EDD_MBR_SIG_NR_BUF)	# zero value at EDD_MBR_SIG_NR_BUF
 	movb	$0x80, %dl			# from device 80
 	movw	$EDD_MBR_SIG_BUF, %bx		# store buffer ptr in bx
 edd_mbr_sig_read:
@@ -76,7 +115,6 @@
        						# result buffer for fn48
 	movw	$EDDBUF+EDDEXTSIZE, %si		# in ds:si, fn41 results
 						# kept just before that
-	movb	$0, (EDDNR)			# zero value at EDDNR
 	movb	$0x80, %dl			# BIOS device 0x80
 
 edd_check_ext:
diff -Nru a/arch/i386/boot/setup.S b/arch/i386/boot/setup.S
--- a/arch/i386/boot/setup.S	2005-03-01 23:38:58 -08:00
+++ b/arch/i386/boot/setup.S	2005-03-01 23:38:58 -08:00
@@ -162,7 +162,9 @@
 					# the contents of an initrd
 
 trampoline:	call	start_of_setup
-		.space	1024
+		.align 16
+					# The offset at this point is 0x240
+		.space	(0x7ff-0x240+1) # E820 & EDD space (ending at 0x7ff)
 # End of setup header #####################################################
 
 start_of_setup:
diff -Nru a/arch/i386/crypto/aes.c b/arch/i386/crypto/aes.c
--- a/arch/i386/crypto/aes.c	2005-03-01 23:38:58 -08:00
+++ b/arch/i386/crypto/aes.c	2005-03-01 23:38:58 -08:00
@@ -93,12 +93,12 @@
 
 u32 ft_tab[4][256];
 u32 fl_tab[4][256];
-u32 ls_tab[4][256];
-u32 im_tab[4][256];
+static u32 ls_tab[4][256];
+static u32 im_tab[4][256];
 u32 il_tab[4][256];
 u32 it_tab[4][256];
 
-void gen_tabs(void)
+static void gen_tabs(void)
 {
 	u32 i, w;
 	u8 pow[512], log[256];
diff -Nru a/arch/i386/defconfig b/arch/i386/defconfig
--- a/arch/i386/defconfig	2005-03-01 23:39:07 -08:00
+++ b/arch/i386/defconfig	2005-03-01 23:39:07 -08:00
@@ -534,7 +534,6 @@
 CONFIG_IP_NF_TARGET_REDIRECT=y
 CONFIG_IP_NF_TARGET_NETMAP=y
 CONFIG_IP_NF_TARGET_SAME=y
-# CONFIG_IP_NF_NAT_LOCAL is not set
 # CONFIG_IP_NF_NAT_SNMP_BASIC is not set
 CONFIG_IP_NF_MANGLE=y
 CONFIG_IP_NF_TARGET_TOS=y
diff -Nru a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c
--- a/arch/i386/kernel/acpi/boot.c	2005-03-01 23:39:09 -08:00
+++ b/arch/i386/kernel/acpi/boot.c	2005-03-01 23:39:09 -08:00
@@ -484,6 +484,28 @@
 }
 EXPORT_SYMBOL(acpi_register_gsi);
 
+/*
+ *  ACPI based hotplug support for CPU
+ */
+#ifdef CONFIG_ACPI_HOTPLUG_CPU
+int
+acpi_map_lsapic(acpi_handle handle, int *pcpu)
+{
+	/* TBD */
+	return -EINVAL;
+}
+EXPORT_SYMBOL(acpi_map_lsapic);
+
+
+int
+acpi_unmap_lsapic(int cpu)
+{
+	/* TBD */
+	return -EINVAL;
+}
+EXPORT_SYMBOL(acpi_unmap_lsapic);
+#endif /* CONFIG_ACPI_HOTPLUG_CPU */
+
 static unsigned long __init
 acpi_scan_rsdp (
 	unsigned long		start,
@@ -788,13 +810,16 @@
 }
 
 /*
- * acpi_boot_init()
+ * acpi_boot_table_init() and acpi_boot_init()
  *  called from setup_arch(), always.
  *	1. checksums all tables
  *	2. enumerates lapics
  *	3. enumerates io-apics
  *
- * side effects:
+ * acpi_table_init() is separate to allow reading SRAT without
+ * other side effects.
+ *
+ * side effects of acpi_boot_init:
  *	acpi_lapic = 1 if LAPIC found
  *	acpi_ioapic = 1 if IOAPIC found
  *	if (acpi_lapic && acpi_ioapic) smp_found_config = 1;
@@ -808,7 +833,7 @@
  */
 
 int __init
-acpi_boot_init (void)
+acpi_boot_table_init(void)
 {
 	int error;
 
@@ -849,6 +874,21 @@
 			return error;
 		}
 	}
+
+	return 0;
+}
+
+
+int __init acpi_boot_init(void)
+{
+	/*
+	 * If acpi_disabled, bail out
+	 * One exception: acpi=ht continues far enough to enumerate LAPICs
+	 */
+	if (acpi_disabled && !acpi_ht)
+		 return 1;
+
+	acpi_table_parse(ACPI_BOOT, acpi_parse_sbf);
 
 	/*
 	 * set sci_int and PM timer address
diff -Nru a/arch/i386/kernel/acpi/wakeup.S b/arch/i386/kernel/acpi/wakeup.S
--- a/arch/i386/kernel/acpi/wakeup.S	2005-03-01 23:38:53 -08:00
+++ b/arch/i386/kernel/acpi/wakeup.S	2005-03-01 23:38:53 -08:00
@@ -278,7 +278,7 @@
 	movl %edi, saved_context_edi
 	pushfl ; popl saved_context_eflags
 
-	movl $ret_point,saved_eip
+	movl $ret_point, saved_eip
 	ret
 
 
@@ -295,7 +295,7 @@
 	call	save_registers
 	pushl	$3
 	call	acpi_enter_sleep_state
-	addl	$4,%esp
+	addl	$4, %esp
 	ret
 	.p2align 4,,7
 ret_point:
diff -Nru a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c
--- a/arch/i386/kernel/apic.c	2005-03-01 23:39:17 -08:00
+++ b/arch/i386/kernel/apic.c	2005-03-01 23:39:17 -08:00
@@ -518,8 +518,7 @@
  * disable it down before re-entering the BIOS on shutdown.
  * Otherwise the BIOS may get confused and not power-off.
  */
-void
-lapic_shutdown()
+void lapic_shutdown(void)
 {
 	if (!cpu_has_apic || !enabled_via_apicbase)
 		return;
@@ -877,30 +876,25 @@
 /* next tick in 8254 can be caught by catching timer wraparound */
 static void __init wait_8254_wraparound(void)
 {
-	unsigned int curr_count, prev_count=~0;
-	int delta;
+	unsigned int curr_count, prev_count;
 
 	curr_count = get_8254_timer_count();
-
 	do {
 		prev_count = curr_count;
 		curr_count = get_8254_timer_count();
-		delta = curr_count-prev_count;
 
-	/*
-	 * This limit for delta seems arbitrary, but it isn't, it's
-	 * slightly above the level of error a buggy Mercury/Neptune
-	 * chipset timer can cause.
-	 */
+		/* workaround for broken Mercury/Neptune */
+		if (prev_count >= curr_count + 0x100)
+			curr_count = get_8254_timer_count();
 
-	} while (delta < 300);
+	} while (prev_count >= curr_count);
 }
 
 /*
  * Default initialization for 8254 timers. If we use other timers like HPET,
  * we override this later
  */
-void (*wait_timer_tick)(void) = wait_8254_wraparound;
+void (*wait_timer_tick)(void) __initdata = wait_8254_wraparound;
 
 /*
  * This function sets up the local APIC timer, with a timeout of
@@ -936,7 +930,7 @@
 	apic_write_around(APIC_TMICT, clocks/APIC_DIVISOR);
 }
 
-static void setup_APIC_timer(unsigned int clocks)
+static void __init setup_APIC_timer(unsigned int clocks)
 {
 	unsigned long flags;
 
@@ -1051,9 +1045,7 @@
 
 void __init 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)
diff -Nru a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c
--- a/arch/i386/kernel/apm.c	2005-03-01 23:38:51 -08:00
+++ b/arch/i386/kernel/apm.c	2005-03-01 23:38:51 -08:00
@@ -424,7 +424,7 @@
 static DECLARE_WAIT_QUEUE_HEAD(apm_waitqueue);
 static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue);
 static struct apm_user *	user_list;
-static spinlock_t		user_list_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(user_list_lock);
 static struct desc_struct	bad_bios_desc = { 0, 0x00409200 };
 
 static char			driver_version[] = "1.16ac";	/* no spaces */
@@ -1201,8 +1201,8 @@
 		printk(KERN_CRIT "apm: suspend was vetoed, but suspending anyway.\n");
 	}
 
-	device_suspend(3);
-	device_power_down(3);
+	device_suspend(PMSG_SUSPEND);
+	device_power_down(PMSG_SUSPEND);
 
 	/* serialize with the timer interrupt */
 	write_seqlock_irq(&xtime_lock);
@@ -1255,7 +1255,7 @@
 {
 	int	err;
 
-	device_power_down(3);
+	device_power_down(PMSG_SUSPEND);
 	/* serialize with the timer interrupt */
 	write_seqlock_irq(&xtime_lock);
 	/* If needed, notify drivers here */
@@ -2369,7 +2369,7 @@
 		 * (pm_idle), Wait for all processors to update cached/local
 		 * copies of pm_idle before proceeding.
 		 */
-		synchronize_kernel();
+		cpu_idle_wait();
 	}
 	if (((apm_info.bios.flags & APM_BIOS_DISENGAGED) == 0)
 	    && (apm_info.connection_version > 0x0100)) {
diff -Nru a/arch/i386/kernel/cpu/amd.c b/arch/i386/kernel/cpu/amd.c
--- a/arch/i386/kernel/cpu/amd.c	2005-03-01 23:39:17 -08:00
+++ b/arch/i386/kernel/cpu/amd.c	2005-03-01 23:39:17 -08:00
@@ -188,6 +188,23 @@
 	}
 
 	display_cacheinfo(c);
+	detect_ht(c);
+
+#ifdef CONFIG_X86_HT
+	/* AMD dual core looks like HT but isn't really. Hide it from the
+	   scheduler. This works around problems with the domain scheduler.
+	   Also probably gives slightly better scheduling and disables
+	   SMT nice which is harmful on dual core.
+	   TBD tune the domain scheduler for dual core. */
+	if (cpu_has(c, X86_FEATURE_CMP_LEGACY))
+		smp_num_siblings = 1;
+#endif
+
+	if (cpuid_eax(0x80000000) >= 0x80000008) {
+		c->x86_num_cores = (cpuid_ecx(0x80000008) & 0xff) + 1;
+		if (c->x86_num_cores & (c->x86_num_cores - 1))
+			c->x86_num_cores = 1;
+	}
 }
 
 static unsigned int amd_size_cache(struct cpuinfo_x86 * c, unsigned int size)
diff -Nru a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c
--- a/arch/i386/kernel/cpu/common.c	2005-03-01 23:38:51 -08:00
+++ b/arch/i386/kernel/cpu/common.c	2005-03-01 23:38:51 -08:00
@@ -10,6 +10,11 @@
 #include <asm/msr.h>
 #include <asm/io.h>
 #include <asm/mmu_context.h>
+#ifdef CONFIG_X86_LOCAL_APIC
+#include <asm/mpspec.h>
+#include <asm/apic.h>
+#include <mach_apic.h>
+#endif
 
 #include "cpu.h"
 
@@ -274,8 +279,10 @@
 		/* AMD-defined flags: level 0x80000001 */
 		xlvl = cpuid_eax(0x80000000);
 		if ( (xlvl & 0xffff0000) == 0x80000000 ) {
-			if ( xlvl >= 0x80000001 )
+			if ( xlvl >= 0x80000001 ) {
 				c->x86_capability[1] = cpuid_edx(0x80000001);
+				c->x86_capability[6] = cpuid_ecx(0x80000001);
+			}
 			if ( xlvl >= 0x80000004 )
 				get_model_name(c); /* Default name */
 		}
@@ -321,6 +328,7 @@
 	c->x86_model = c->x86_mask = 0;	/* So far unknown... */
 	c->x86_vendor_id[0] = '\0'; /* Unset */
 	c->x86_model_id[0] = '\0';  /* Unset */
+	c->x86_num_cores = 1;
 	memset(&c->x86_capability, 0, sizeof c->x86_capability);
 
 	if (!have_cpuid_p()) {
@@ -334,21 +342,19 @@
 
 	generic_identify(c);
 
-	printk(KERN_DEBUG "CPU: After generic identify, caps: %08lx %08lx %08lx %08lx\n",
-		c->x86_capability[0],
-		c->x86_capability[1],
-		c->x86_capability[2],
-		c->x86_capability[3]);
+	printk(KERN_DEBUG "CPU: After generic identify, caps:");
+	for (i = 0; i < NCAPINTS; i++)
+		printk(" %08lx", c->x86_capability[i]);
+	printk("\n");
 
 	if (this_cpu->c_identify) {
 		this_cpu->c_identify(c);
 
-	printk(KERN_DEBUG "CPU: After vendor identify, caps:  %08lx %08lx %08lx %08lx\n",
-		c->x86_capability[0],
-		c->x86_capability[1],
-		c->x86_capability[2],
-		c->x86_capability[3]);
-}
+		printk(KERN_DEBUG "CPU: After vendor identify, caps:");
+		for (i = 0; i < NCAPINTS; i++)
+			printk(" %08lx", c->x86_capability[i]);
+		printk("\n");
+	}
 
 	/*
 	 * Vendor-specific initialization.  In this section we
@@ -398,11 +404,10 @@
 
 	/* Now the feature flags better reflect actual CPU features! */
 
-	printk(KERN_DEBUG "CPU: After all inits, caps:        %08lx %08lx %08lx %08lx\n",
-	       c->x86_capability[0],
-	       c->x86_capability[1],
-	       c->x86_capability[2],
-	       c->x86_capability[3]);
+	printk(KERN_DEBUG "CPU: After all inits, caps:");
+	for (i = 0; i < NCAPINTS; i++)
+		printk(" %08lx", c->x86_capability[i]);
+	printk("\n");
 
 	/*
 	 * On SMP, boot_cpu_data holds the common feature set between
@@ -432,6 +437,50 @@
 		cpu_devs[X86_VENDOR_CYRIX]->c_init(&boot_cpu_data);
 }
 
+#ifdef CONFIG_X86_HT
+void __init detect_ht(struct cpuinfo_x86 *c)
+{
+	u32 	eax, ebx, ecx, edx;
+	int 	index_lsb, index_msb, tmp;
+	int 	cpu = smp_processor_id();
+
+	if (!cpu_has(c, X86_FEATURE_HT))
+		return;
+
+	cpuid(1, &eax, &ebx, &ecx, &edx);
+	smp_num_siblings = (ebx & 0xff0000) >> 16;
+
+	if (smp_num_siblings == 1) {
+		printk(KERN_INFO  "CPU: Hyper-Threading is disabled\n");
+	} else if (smp_num_siblings > 1 ) {
+		index_lsb = 0;
+		index_msb = 31;
+
+		if (smp_num_siblings > NR_CPUS) {
+			printk(KERN_WARNING "CPU: Unsupported number of the siblings %d", smp_num_siblings);
+			smp_num_siblings = 1;
+			return;
+		}
+		tmp = smp_num_siblings;
+		while ((tmp & 1) == 0) {
+			tmp >>=1 ;
+			index_lsb++;
+		}
+		tmp = smp_num_siblings;
+		while ((tmp & 0x80000000 ) == 0) {
+			tmp <<=1 ;
+			index_msb--;
+		}
+		if (index_lsb != index_msb )
+			index_msb++;
+		phys_proc_id[cpu] = phys_pkg_id((ebx >> 24) & 0xFF, index_msb);
+
+		printk(KERN_INFO  "CPU: Physical Processor ID: %d\n",
+		       phys_proc_id[cpu]);
+	}
+}
+#endif
+
 void __init print_cpu_info(struct cpuinfo_x86 *c)
 {
 	char *vendor = NULL;
@@ -455,7 +504,7 @@
 		printk("\n");
 }
 
-unsigned long cpu_initialized __initdata = 0;
+cpumask_t cpu_initialized __initdata = CPU_MASK_NONE;
 
 /* This is hacky. :)
  * We're emulating future behavior.
@@ -509,7 +558,7 @@
 	struct tss_struct * t = &per_cpu(init_tss, cpu);
 	struct thread_struct *thread = &current->thread;
 
-	if (test_and_set_bit(cpu, &cpu_initialized)) {
+	if (cpu_test_and_set(cpu, cpu_initialized)) {
 		printk(KERN_WARNING "CPU#%d already initialized!\n", cpu);
 		for (;;) local_irq_enable();
 	}
@@ -580,6 +629,6 @@
 	 * Force FPU initialization:
 	 */
 	current_thread_info()->status = 0;
-	current->used_math = 0;
+	clear_used_math();
 	mxcsr_feature_mask_init();
 }
diff -Nru a/arch/i386/kernel/cpu/cpufreq/Kconfig b/arch/i386/kernel/cpu/cpufreq/Kconfig
--- a/arch/i386/kernel/cpu/cpufreq/Kconfig	2005-03-01 23:38:53 -08:00
+++ b/arch/i386/kernel/cpu/cpufreq/Kconfig	2005-03-01 23:38:53 -08:00
@@ -175,7 +175,7 @@
 	depends on CPU_FREQ && EXPERIMENTAL
 	help
 	  This adds the CPUFreq driver for FSB changing on nVidia nForce2
-	  plattforms.
+	  platforms.
 
 	  For details, take a look at <file:Documentation/cpu-freq/>.
 
diff -Nru 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	2005-03-01 23:38:52 -08:00
+++ b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c	2005-03-01 23:38:52 -08:00
@@ -38,6 +38,8 @@
 #include <linux/acpi.h>
 #include <acpi/processor.h>
 
+#include "speedstep-est-common.h"
+
 #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "acpi-cpufreq", msg)
 
 MODULE_AUTHOR("Paul Diefenbaugh, Dominik Brodowski");
@@ -48,10 +50,12 @@
 struct cpufreq_acpi_io {
 	struct acpi_processor_performance	acpi_data;
 	struct cpufreq_frequency_table		*freq_table;
+	unsigned int				resume;
 };
 
 static struct cpufreq_acpi_io	*acpi_io_data[NR_CPUS];
 
+static struct cpufreq_driver acpi_cpufreq_driver;
 
 static int
 acpi_processor_write_port(
@@ -119,9 +123,14 @@
 	}
 	
 	if (state == data->acpi_data.state) {
-		dprintk("Already at target state (P%d)\n", state);
-		retval = 0;
-		goto migrate_end;
+		if (unlikely(data->resume)) {
+			dprintk("Called after resume, resetting to P%d\n", state);
+			data->resume = 0;
+		} else {
+			dprintk("Already at target state (P%d)\n", state);
+			retval = 0;
+			goto migrate_end;
+		}
 	}
 
 	dprintk("Transitioning from P%d to P%d\n",
@@ -368,6 +377,10 @@
 	if (result)
 		goto err_free;
 
+	if (is_const_loops_cpu(cpu)) {
+		acpi_cpufreq_driver.flags |= CPUFREQ_CONST_LOOPS;
+	}
+
 	/* capability check */
 	if (data->acpi_data.state_count <= 1) {
 		dprintk("No P-States\n");
@@ -462,6 +475,20 @@
 	return (0);
 }
 
+static int
+acpi_cpufreq_resume (
+	struct cpufreq_policy   *policy)
+{
+	struct cpufreq_acpi_io *data = acpi_io_data[policy->cpu];
+
+
+	dprintk("acpi_cpufreq_resume\n");
+
+	data->resume = 1;
+
+	return (0);
+}
+
 
 static struct freq_attr* acpi_cpufreq_attr[] = {
 	&cpufreq_freq_attr_scaling_available_freqs,
@@ -473,6 +500,7 @@
 	.target 	= acpi_cpufreq_target,
 	.init		= acpi_cpufreq_cpu_init,
 	.exit		= acpi_cpufreq_cpu_exit,
+	.resume		= acpi_cpufreq_resume,
 	.name		= "acpi-cpufreq",
 	.owner		= THIS_MODULE,
 	.attr           = acpi_cpufreq_attr,
diff -Nru a/arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c b/arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c
--- a/arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c	2005-03-01 23:38:52 -08:00
+++ b/arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c	2005-03-01 23:38:52 -08:00
@@ -55,16 +55,7 @@
 MODULE_PARM_DESC(min_fsb,
                  "Minimum FSB to use, if not defined: current FSB - 50");
 
-/* DEBUG
- *   Define it if you want verbose debug output, e.g. for bug reporting
- */
-//#define NFORCE2_DEBUG
-
-#ifdef NFORCE2_DEBUG
-#define dprintk(msg...) printk(msg)
-#else
-#define dprintk(msg...) do { } while(0)
-#endif
+#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "cpufreq-nforce2", msg)
 
 /*
  * nforce2_calc_fsb - calculate FSB
diff -Nru 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	2005-03-01 23:39:18 -08:00
+++ b/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c	2005-03-01 23:39:18 -08:00
@@ -209,7 +209,7 @@
 	if ((gx_params->pci_suscfg & SUSMOD) == 0) 
 		return stock_freq;
 
-	return (stock_freq * gx_params->on_duration) 
+	return (stock_freq * gx_params->off_duration) 
 		/ (gx_params->on_duration + gx_params->off_duration);
 }
 
diff -Nru a/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c b/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c
--- a/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c	2005-03-01 23:39:16 -08:00
+++ b/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c	2005-03-01 23:39:16 -08:00
@@ -171,7 +171,7 @@
 		return speedstep_get_processor_frequency(SPEEDSTEP_PROCESSOR_PM);
 	}
 
-	if ((c->x86 == 0x06) && (c->x86_model == 0x13)) {
+	if ((c->x86 == 0x06) && (c->x86_model == 0x0D)) {
 		/* Pentium M (Dothan) */
 		printk(KERN_WARNING PFX "Warning: Pentium M detected. "
 		       "The speedstep_centrino module offers voltage scaling"
diff -Nru 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	2005-03-01 23:38:51 -08:00
+++ b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c	2005-03-01 23:38:51 -08:00
@@ -67,12 +67,12 @@
 #endif
 
 #ifdef CONFIG_CPU_FREQ_DEBUG
-/* divide by 1000 to get VID. */
+/* divide by 1000 to get VCore voltage in V. */
 static int mobile_vid_table[32] = {
     2000, 1950, 1900, 1850, 1800, 1750, 1700, 1650,
     1600, 1550, 1500, 1450, 1400, 1350, 1300, 0,
     1275, 1250, 1225, 1200, 1175, 1150, 1125, 1100,
-    1075, 1050, 1024, 1000, 975, 950, 925, 0,
+    1075, 1050, 1025, 1000, 975, 950, 925, 0,
 };
 #endif
 
@@ -635,6 +635,17 @@
 
 static int powernow_cpu_exit (struct cpufreq_policy *policy) {
 	cpufreq_frequency_table_put_attr(policy->cpu);
+
+#ifdef CONFIG_X86_POWERNOW_K7_ACPI
+	if (acpi_processor_perf) {
+		acpi_processor_unregister_performance(acpi_processor_perf, 0);
+		kfree(acpi_processor_perf);
+	}
+#endif
+
+	if (powernow_table)
+		kfree(powernow_table);
+
 	return 0;
 }
 
@@ -664,15 +675,7 @@
 
 static void __exit powernow_exit (void)
 {
-#ifdef CONFIG_X86_POWERNOW_K7_ACPI
-	if (acpi_processor_perf) {
-		acpi_processor_unregister_performance(acpi_processor_perf, 0);
-		kfree(acpi_processor_perf);
-	}
-#endif
 	cpufreq_unregister_driver(&powernow_driver);
-	if (powernow_table)
-		kfree(powernow_table);
 }
 
 module_param(acpi_force,  int, 0444);
diff -Nru 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	2005-03-01 23:38:58 -08:00
+++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c	2005-03-01 23:38:58 -08:00
@@ -18,6 +18,9 @@
  *  Processor information obtained from Chapter 9 (Power and Thermal Management)
  *  of the "BIOS and Kernel Developer's Guide for the AMD Athlon 64 and AMD
  *  Opteron Processors" available for download from www.amd.com
+ *
+ *  Tables for specific CPUs can be infrerred from
+ *	http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/30430.pdf
  */
 
 #include <linux/kernel.h>
@@ -65,7 +68,12 @@
 	return 1550-vid*25;
 }
 
-/* Return the vco fid for an input fid */
+/* Return the vco fid for an input fid
+ *
+ * Each "low" fid has corresponding "high" fid, and you can get to "low" fids
+ * only from corresponding high fids. This returns "high" fid corresponding to
+ * "low" one.
+ */
 static u32 convert_fid_to_vco_fid(u32 fid)
 {
 	if (fid < HI_FID_TABLE_BOTTOM) {
@@ -278,7 +286,7 @@
 			return 1;
 	}
 
-	while (rvosteps > 0) {
+	while ((rvosteps > 0)  && ((data->rvo + data->currvid) > reqvid)) {
 		if (data->currvid == 0) {
 			rvosteps = 0;
 		} else {
@@ -307,10 +315,7 @@
 /* Phase 2 - core frequency transition */
 static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid)
 {
-	u32 vcoreqfid;
-	u32 vcocurrfid;
-	u32 vcofiddiff;
-	u32 savevid = data->currvid;
+	u32 vcoreqfid, vcocurrfid, vcofiddiff, savevid = data->currvid;
 
 	if ((reqfid < HI_FID_TABLE_BOTTOM) && (data->currfid < HI_FID_TABLE_BOTTOM)) {
 		printk(KERN_ERR PFX "ph2: illegal lo-lo transition 0x%x 0x%x\n",
@@ -498,7 +503,7 @@
 		    || (pst[j].fid & 1)
 		    || (j && (pst[j].fid < HI_FID_TABLE_BOTTOM))) {
 			/* Only first fid is allowed to be in "low" range */
-			printk(KERN_ERR PFX "fid %d invalid : 0x%x\n", j, pst[j].fid);
+			printk(KERN_ERR PFX "two low fids - %d : 0x%x\n", j, pst[j].fid);
 			return -EINVAL;
 		}
 		if (pst[j].fid < lastfid)
@@ -618,7 +623,7 @@
 			return -ENODEV;
 		}
 
-		data->vstable = psb->voltagestabilizationtime;
+		data->vstable = psb->vstable;
 		dprintk("voltage stabilization time: %d(*20us)\n", data->vstable);
 
 		dprintk("flags2: 0x%x\n", psb->flags2);
@@ -632,8 +637,8 @@
 		dprintk("isochronous relief time: %d\n", data->irt);
 		dprintk("maximum voltage step: %d - 0x%x\n", mvs, data->vidmvs);
 
-		dprintk("numpst: 0x%x\n", psb->numpst);
-		cpst = psb->numpst;
+		dprintk("numpst: 0x%x\n", psb->num_tables);
+		cpst = psb->num_tables;
 		if ((psb->cpuid == 0x00000fc0) || (psb->cpuid == 0x00000fe0) ){
 			thiscpuid = cpuid_eax(CPUID_PROCESSOR_SIGNATURE);
 			if ((thiscpuid == 0x00000fc0) || (thiscpuid == 0x00000fe0) ) {
@@ -651,7 +656,7 @@
 		dprintk("maxvid: 0x%x\n", psb->maxvid);
 		maxvid = psb->maxvid;
 
-		data->numps = psb->numpstates;
+		data->numps = psb->numps;
 		dprintk("numpstates: 0x%x\n", data->numps);
 		return fill_powernow_table(data, (struct pst_s *)(psb+1), maxvid);
 	}
@@ -1010,6 +1015,7 @@
 	/* min/max the cpu is capable of */
 	if (cpufreq_frequency_table_cpuinfo(pol, data->powernow_table)) {
 		printk(KERN_ERR PFX "invalid powernow_table\n");
+		powernow_k8_cpu_exit_acpi(data);
 		kfree(data->powernow_table);
 		kfree(data);
 		return -EINVAL;
@@ -1027,6 +1033,7 @@
 err_out:
 	set_cpus_allowed(current, oldmask);
 	schedule();
+	powernow_k8_cpu_exit_acpi(data);
 
 	kfree(data);
 	return -ENODEV;
diff -Nru 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	2005-03-01 23:38:58 -08:00
+++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.h	2005-03-01 23:38:58 -08:00
@@ -21,8 +21,7 @@
 	u32 plllock; /* pll lock time, units 1 us */
 
 	/* keep track of the current fid / vid */
-	u32 currvid;
-	u32 currfid;
+	u32 currvid, currfid;
 
 	/* the powernow_table includes all frequency and vid/fid pairings:
 	 * fid are the lower 8 bits of the index, vid are the upper 8 bits.
@@ -152,14 +151,14 @@
 	u8 signature[10];
 	u8 tableversion;
 	u8 flags1;
-	u16 voltagestabilizationtime;
+	u16 vstable;
 	u8 flags2;
-	u8 numpst;
+	u8 num_tables;
 	u32 cpuid;
 	u8 plllocktime;
 	u8 maxfid;
 	u8 maxvid;
-	u8 numpstates;
+	u8 numps;
 };
 
 /* Pairs of fid/vid values are appended to the version 1.4 PSB table. */
diff -Nru 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	2005-03-01 23:38:55 -08:00
+++ b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c	2005-03-01 23:38:55 -08:00
@@ -22,6 +22,8 @@
 #include <linux/init.h>
 #include <linux/cpufreq.h>
 #include <linux/config.h>
+#include <linux/delay.h>
+#include <linux/compiler.h>
 
 #ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI
 #include <linux/acpi.h>
@@ -32,6 +34,8 @@
 #include <asm/processor.h>
 #include <asm/cpufeature.h>
 
+#include "speedstep-est-common.h"
+
 #define PFX		"speedstep-centrino: "
 #define MAINTAINER	"Jeremy Fitzhardinge <jeremy@goop.org>"
 
@@ -71,8 +75,10 @@
 static int centrino_verify_cpu_id(const struct cpuinfo_x86 *c, const struct cpu_id *x);
 
 /* Operating points for current CPU */
-static struct cpu_model *centrino_model;
-static const struct cpu_id *centrino_cpu;
+static struct cpu_model *centrino_model[NR_CPUS];
+static const struct cpu_id *centrino_cpu[NR_CPUS];
+
+static struct cpufreq_driver centrino_driver;
 
 #ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE
 
@@ -239,7 +245,7 @@
 
 	if (model->cpu_id == NULL) {
 		/* No match at all */
-		printk(KERN_INFO PFX "no support for CPU model \"%s\": "
+		dprintk(KERN_INFO PFX "no support for CPU model \"%s\": "
 		       "send /proc/cpuinfo to " MAINTAINER "\n",
 		       cpu->x86_model_id);
 		return -ENOENT;
@@ -247,15 +253,15 @@
 
 	if (model->op_points == NULL) {
 		/* Matched a non-match */
-		printk(KERN_INFO PFX "no table support for CPU model \"%s\": \n",
+		dprintk(KERN_INFO PFX "no table support for CPU model \"%s\": \n",
 		       cpu->x86_model_id);
-#ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI
-		printk(KERN_INFO PFX "try compiling with CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI enabled\n");
+#ifndef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI
+		dprintk(KERN_INFO PFX "try compiling with CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI enabled\n");
 #endif
 		return -ENOENT;
 	}
 
-	centrino_model = model;
+	centrino_model[policy->cpu] = model;
 
 	dprintk("found \"%s\": max frequency: %dkHz\n",
 	       model->model_name, model->max_freq);
@@ -277,7 +283,7 @@
 }
 
 /* To be called only after centrino_model is initialized */
-static unsigned extract_clock(unsigned msr)
+static unsigned extract_clock(unsigned msr, unsigned int cpu, int failsafe)
 {
 	int i;
 
@@ -286,28 +292,32 @@
 	 * for centrino, as some DSDTs are buggy.
 	 * Ideally, this can be done using the acpi_data structure.
 	 */
-	if ((centrino_cpu == &cpu_ids[CPU_BANIAS]) ||
-	    (centrino_cpu == &cpu_ids[CPU_DOTHAN_A1]) ||
-	    (centrino_cpu == &cpu_ids[CPU_DOTHAN_B0])) {
+	if ((centrino_cpu[cpu] == &cpu_ids[CPU_BANIAS]) ||
+	    (centrino_cpu[cpu] == &cpu_ids[CPU_DOTHAN_A1]) ||
+	    (centrino_cpu[cpu] == &cpu_ids[CPU_DOTHAN_B0])) {
 		msr = (msr >> 8) & 0xff;
 		return msr * 100000;
 	}
 
-	if ((!centrino_model) || (!centrino_model->op_points))
+	if ((!centrino_model[cpu]) || (!centrino_model[cpu]->op_points))
 		return 0;
 
 	msr &= 0xffff;
-	for (i=0;centrino_model->op_points[i].frequency != CPUFREQ_TABLE_END; i++) {
-		if (msr == centrino_model->op_points[i].index)
-		return centrino_model->op_points[i].frequency;
-	}
-	return 0;
+	for (i=0;centrino_model[cpu]->op_points[i].frequency != CPUFREQ_TABLE_END; i++) {
+		if (msr == centrino_model[cpu]->op_points[i].index)
+			return centrino_model[cpu]->op_points[i].frequency;
+	}
+	if (failsafe)
+		return centrino_model[cpu]->op_points[i-1].frequency;
+	else
+		return 0;
 }
 
 /* Return the current CPU frequency in kHz */
 static unsigned int get_cur_freq(unsigned int cpu)
 {
 	unsigned l, h;
+	unsigned clock_freq;
 	cpumask_t saved_mask;
 
 	saved_mask = current->cpus_allowed;
@@ -316,8 +326,21 @@
 		return 0;
 
 	rdmsr(MSR_IA32_PERF_STATUS, l, h);
+	clock_freq = extract_clock(l, cpu, 0);
+
+	if (unlikely(clock_freq == 0)) {
+		/*
+		 * On some CPUs, we can see transient MSR values (which are
+		 * not present in _PSS), while CPU is doing some automatic
+		 * P-state transition (like TM2). Get the last freq set 
+		 * in PERF_CTL.
+		 */
+		rdmsr(MSR_IA32_PERF_CTL, l, h);
+		clock_freq = extract_clock(l, cpu, 1);
+	}
+
 	set_cpus_allowed(current, saved_mask);
-	return extract_clock(l);
+	return clock_freq;
 }
 
 
@@ -339,6 +362,7 @@
 	struct acpi_object_list		arg_list = {1, &arg0};
 	unsigned long			cur_freq;
 	int				result = 0, i;
+	unsigned int			cpu = policy->cpu;
 
 	/* _PDC settings */
 	arg0.buffer.length = 12;
@@ -350,8 +374,8 @@
 	p.pdc = &arg_list;
 
 	/* register with ACPI core */
-	if (acpi_processor_register_performance(&p, policy->cpu)) {
-		printk(KERN_INFO PFX "obtaining ACPI data failed\n");
+	if (acpi_processor_register_performance(&p, cpu)) {
+		dprintk(KERN_INFO PFX "obtaining ACPI data failed\n");
 		return -EIO;
 	}
 
@@ -392,49 +416,49 @@
 		}
 	}
 
-	centrino_model = kmalloc(sizeof(struct cpu_model), GFP_KERNEL);
-	if (!centrino_model) {
+	centrino_model[cpu] = kmalloc(sizeof(struct cpu_model), GFP_KERNEL);
+	if (!centrino_model[cpu]) {
 		result = -ENOMEM;
 		goto err_unreg;
 	}
-	memset(centrino_model, 0, sizeof(struct cpu_model));
+	memset(centrino_model[cpu], 0, sizeof(struct cpu_model));
 
-	centrino_model->model_name=NULL;
-	centrino_model->max_freq = p.states[0].core_frequency * 1000;
-	centrino_model->op_points =  kmalloc(sizeof(struct cpufreq_frequency_table) *
+	centrino_model[cpu]->model_name=NULL;
+	centrino_model[cpu]->max_freq = p.states[0].core_frequency * 1000;
+	centrino_model[cpu]->op_points =  kmalloc(sizeof(struct cpufreq_frequency_table) *
 					     (p.state_count + 1), GFP_KERNEL);
-        if (!centrino_model->op_points) {
+        if (!centrino_model[cpu]->op_points) {
                 result = -ENOMEM;
                 goto err_kfree;
         }
 
         for (i=0; i<p.state_count; i++) {
-		centrino_model->op_points[i].index = p.states[i].control;
-		centrino_model->op_points[i].frequency = p.states[i].core_frequency * 1000;
+		centrino_model[cpu]->op_points[i].index = p.states[i].control;
+		centrino_model[cpu]->op_points[i].frequency = p.states[i].core_frequency * 1000;
 		dprintk("adding state %i with frequency %u and control value %04x\n", 
-			i, centrino_model->op_points[i].frequency, centrino_model->op_points[i].index);
+			i, centrino_model[cpu]->op_points[i].frequency, centrino_model[cpu]->op_points[i].index);
 	}
-	centrino_model->op_points[p.state_count].frequency = CPUFREQ_TABLE_END;
+	centrino_model[cpu]->op_points[p.state_count].frequency = CPUFREQ_TABLE_END;
 
-	cur_freq = get_cur_freq(policy->cpu);
+	cur_freq = get_cur_freq(cpu);
 
 	for (i=0; i<p.state_count; i++) {
 		if (!p.states[i].core_frequency) {
 			dprintk("skipping state %u\n", i);
-			centrino_model->op_points[i].frequency = CPUFREQ_ENTRY_INVALID;
+			centrino_model[cpu]->op_points[i].frequency = CPUFREQ_ENTRY_INVALID;
 			continue;
 		}
 		
-		if (extract_clock(centrino_model->op_points[i].index) !=
-		    (centrino_model->op_points[i].frequency)) {
+		if (extract_clock(centrino_model[cpu]->op_points[i].index, cpu, 0) !=
+		    (centrino_model[cpu]->op_points[i].frequency)) {
 			dprintk("Invalid encoded frequency (%u vs. %u)\n",
-				extract_clock(centrino_model->op_points[i].index),
-				centrino_model->op_points[i].frequency);
+				extract_clock(centrino_model[cpu]->op_points[i].index, cpu, 0),
+				centrino_model[cpu]->op_points[i].frequency);
 			result = -EINVAL;
 			goto err_kfree_all;
 		}
 
-		if (cur_freq == centrino_model->op_points[i].frequency)
+		if (cur_freq == centrino_model[cpu]->op_points[i].frequency)
 			p.state = i;
 	}
 
@@ -444,12 +468,12 @@
 	return 0;
 
  err_kfree_all:
-	kfree(centrino_model->op_points);
+	kfree(centrino_model[cpu]->op_points);
  err_kfree:
-	kfree(centrino_model);
+	kfree(centrino_model[cpu]);
  err_unreg:
-	acpi_processor_unregister_performance(&p, policy->cpu);
-	printk(KERN_INFO PFX "invalid ACPI data\n");
+	acpi_processor_unregister_performance(&p, cpu);
+	dprintk(KERN_INFO PFX "invalid ACPI data\n");
 	return (result);
 }
 #else
@@ -473,14 +497,18 @@
 			break;
 
 	if (i != N_IDS)
-		centrino_cpu = &cpu_ids[i];
+		centrino_cpu[policy->cpu] = &cpu_ids[i];
+
+	if (is_const_loops_cpu(policy->cpu)) {
+		centrino_driver.flags |= CPUFREQ_CONST_LOOPS;
+	}
 
 	if (centrino_cpu_init_acpi(policy)) {
 		if (policy->cpu != 0)
 			return -ENODEV;
 
-		if (!centrino_cpu) {
-			printk(KERN_INFO PFX "found unsupported CPU with "
+		if (!centrino_cpu[policy->cpu]) {
+			dprintk(KERN_INFO PFX "found unsupported CPU with "
 			"Enhanced SpeedStep: send /proc/cpuinfo to "
 			MAINTAINER "\n");
 			return -ENODEV;
@@ -516,32 +544,34 @@
 
 	dprintk("centrino_cpu_init: cur=%dkHz\n", policy->cur);
 
-	ret = cpufreq_frequency_table_cpuinfo(policy, centrino_model->op_points);
+	ret = cpufreq_frequency_table_cpuinfo(policy, centrino_model[policy->cpu]->op_points);
 	if (ret)
 		return (ret);
 
-	cpufreq_frequency_table_get_attr(centrino_model->op_points, policy->cpu);
+	cpufreq_frequency_table_get_attr(centrino_model[policy->cpu]->op_points, policy->cpu);
 
 	return 0;
 }
 
 static int centrino_cpu_exit(struct cpufreq_policy *policy)
 {
-	if (!centrino_model)
+	unsigned int cpu = policy->cpu;
+
+	if (!centrino_model[cpu])
 		return -ENODEV;
 
-	cpufreq_frequency_table_put_attr(policy->cpu);
+	cpufreq_frequency_table_put_attr(cpu);
 
 #ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI
-	if (!centrino_model->model_name) {
+	if (!centrino_model[cpu]->model_name) {
 		dprintk("unregistering and freeing ACPI data\n");
-		acpi_processor_unregister_performance(&p, policy->cpu);
-		kfree(centrino_model->op_points);
-		kfree(centrino_model);
+		acpi_processor_unregister_performance(&p, cpu);
+		kfree(centrino_model[cpu]->op_points);
+		kfree(centrino_model[cpu]);
 	}
 #endif
 
-	centrino_model = NULL;
+	centrino_model[cpu] = NULL;
 
 	return 0;
 }
@@ -555,7 +585,7 @@
  */
 static int centrino_verify (struct cpufreq_policy *policy)
 {
-	return cpufreq_frequency_table_verify(policy, centrino_model->op_points);
+	return cpufreq_frequency_table_verify(policy, centrino_model[policy->cpu]->op_points);
 }
 
 /**
@@ -571,12 +601,12 @@
 			    unsigned int relation)
 {
 	unsigned int    newstate = 0;
-	unsigned int	msr, oldmsr, h;
+	unsigned int	msr, oldmsr, h, cpu = policy->cpu;
 	struct cpufreq_freqs	freqs;
 	cpumask_t		saved_mask;
 	int			retval;
 
-	if (centrino_model == NULL)
+	if (centrino_model[cpu] == NULL)
 		return -ENODEV;
 
 	/*
@@ -585,18 +615,18 @@
 	 */
 	saved_mask = current->cpus_allowed;
 	set_cpus_allowed(current, policy->cpus);
-	if (smp_processor_id() != policy->cpu) {
+	if (!cpu_isset(smp_processor_id(), policy->cpus)) {
 		dprintk("couldn't limit to CPUs in this domain\n");
 		return(-EAGAIN);
 	}
 
-	if (cpufreq_frequency_table_target(policy, centrino_model->op_points, target_freq,
+	if (cpufreq_frequency_table_target(policy, centrino_model[cpu]->op_points, target_freq,
 					   relation, &newstate)) {
 		retval = -EINVAL;
 		goto migrate_end;
 	}
 
-	msr = centrino_model->op_points[newstate].index;
+	msr = centrino_model[cpu]->op_points[newstate].index;
 	rdmsr(MSR_IA32_PERF_CTL, oldmsr, h);
 
 	if (msr == (oldmsr & 0xffff)) {
@@ -605,9 +635,9 @@
 		goto migrate_end;
 	}
 
-	freqs.cpu = policy->cpu;
-	freqs.old = extract_clock(oldmsr);
-	freqs.new = extract_clock(msr);
+	freqs.cpu = cpu;
+	freqs.old = extract_clock(oldmsr, cpu, 0);
+	freqs.new = extract_clock(msr, cpu, 0);
 
 	dprintk("target=%dkHz old=%d new=%d msr=%04x\n",
 		target_freq, freqs.old, freqs.new, msr);
diff -Nru a/arch/i386/kernel/cpu/cpufreq/speedstep-est-common.h b/arch/i386/kernel/cpu/cpufreq/speedstep-est-common.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/i386/kernel/cpu/cpufreq/speedstep-est-common.h	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,25 @@
+/*
+ * Routines common for drivers handling Enhanced Speedstep Technology
+ *  Copyright (C) 2004 Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
+ *
+ *  Licensed under the terms of the GNU GPL License version 2 -- see
+ *  COPYING for details.
+ */
+
+static inline int is_const_loops_cpu(unsigned int cpu)
+{
+	struct cpuinfo_x86 	*c = cpu_data + cpu;
+
+	if (c->x86_vendor != X86_VENDOR_INTEL || !cpu_has(c, X86_FEATURE_EST))
+		return 0;
+
+	/*
+	 * on P-4s, the TSC runs with constant frequency independent of cpu freq
+	 * when we use EST
+	 */
+	if (c->x86 == 0xf)
+		return 1;
+
+	return 0;
+}
+
diff -Nru a/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c b/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c
--- a/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c	2005-03-01 23:39:09 -08:00
+++ b/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c	2005-03-01 23:39:09 -08:00
@@ -160,7 +160,10 @@
 		printk(KERN_DEBUG "speedstep-lib: couldn't detect FSB speed. Please send an e-mail to <linux@brodo.de>\n");
 
 	/* Multiplier. */
-	mult = msr_lo >> 24;
+	if (c->x86_model < 2)
+		mult = msr_lo >> 27;
+	else
+		mult = msr_lo >> 24;
 
 	dprintk("P4 - FSB %u kHz; Multiplier %u; Speed %u kHz\n", fsb, mult, (fsb * mult));
 
diff -Nru a/arch/i386/kernel/cpu/intel.c b/arch/i386/kernel/cpu/intel.c
--- a/arch/i386/kernel/cpu/intel.c	2005-03-01 23:38:54 -08:00
+++ b/arch/i386/kernel/cpu/intel.c	2005-03-01 23:38:54 -08:00
@@ -139,50 +139,7 @@
 	if ( p )
 		strcpy(c->x86_model_id, p);
 	
-#ifdef CONFIG_X86_HT
-	if (cpu_has(c, X86_FEATURE_HT)) {
-		extern	int phys_proc_id[NR_CPUS];
-		
-		u32 	eax, ebx, ecx, edx;
-		int 	index_lsb, index_msb, tmp;
-		int 	cpu = smp_processor_id();
-
-		cpuid(1, &eax, &ebx, &ecx, &edx);
-		smp_num_siblings = (ebx & 0xff0000) >> 16;
-
-		if (smp_num_siblings == 1) {
-			printk(KERN_INFO  "CPU: Hyper-Threading is disabled\n");
-		} else if (smp_num_siblings > 1 ) {
-			index_lsb = 0;
-			index_msb = 31;
-
-			if (smp_num_siblings > NR_CPUS) {
-				printk(KERN_WARNING "CPU: Unsupported number of the siblings %d", smp_num_siblings);
-				smp_num_siblings = 1;
-				goto too_many_siblings;
-			}
-			tmp = smp_num_siblings;
-			while ((tmp & 1) == 0) {
-				tmp >>=1 ;
-				index_lsb++;
-			}
-			tmp = smp_num_siblings;
-			while ((tmp & 0x80000000 ) == 0) {
-				tmp <<=1 ;
-				index_msb--;
-			}
-			if (index_lsb != index_msb )
-				index_msb++;
-			phys_proc_id[cpu] = phys_pkg_id((ebx >> 24) & 0xFF, index_msb);
-
-			printk(KERN_INFO  "CPU: Physical Processor ID: %d\n",
-                               phys_proc_id[cpu]);
-		}
-
-	}
-too_many_siblings:
-
-#endif
+	detect_ht(c);
 
 	/* Work around errata */
 	Intel_errata_workarounds(c);
diff -Nru a/arch/i386/kernel/cpu/intel_cacheinfo.c b/arch/i386/kernel/cpu/intel_cacheinfo.c
--- a/arch/i386/kernel/cpu/intel_cacheinfo.c	2005-03-01 23:39:08 -08:00
+++ b/arch/i386/kernel/cpu/intel_cacheinfo.c	2005-03-01 23:39:08 -08:00
@@ -58,7 +58,7 @@
 	{ 0x00, 0, 0}
 };
 
-unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c)
+unsigned int __init init_intel_cacheinfo(struct cpuinfo_x86 *c)
 {
 	unsigned int trace = 0, l1i = 0, l1d = 0, l2 = 0, l3 = 0; /* Cache sizes */
 
diff -Nru a/arch/i386/kernel/cpu/mtrr/generic.c b/arch/i386/kernel/cpu/mtrr/generic.c
--- a/arch/i386/kernel/cpu/mtrr/generic.c	2005-03-01 23:38:58 -08:00
+++ b/arch/i386/kernel/cpu/mtrr/generic.c	2005-03-01 23:38:58 -08:00
@@ -231,7 +231,14 @@
 
 static unsigned long cr4 = 0;
 static u32 deftype_lo, deftype_hi;
-static spinlock_t set_atomicity_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(set_atomicity_lock);
+
+/*
+ * Since we are disabling the cache don't allow any interrupts - they
+ * would run extremely slow and would only increase the pain.  The caller must
+ * ensure that local interrupts are disabled and are reenabled after post_set()
+ * has been called.
+ */
 
 static void prepare_set(void)
 {
@@ -240,18 +247,18 @@
 	/*  Note that this is not ideal, since the cache is only flushed/disabled
 	   for this CPU while the MTRRs are changed, but changing this requires
 	   more invasive changes to the way the kernel boots  */
+
 	spin_lock(&set_atomicity_lock);
 
 	/*  Enter the no-fill (CD=1, NW=0) cache mode and flush caches. */
 	cr0 = read_cr0() | 0x40000000;	/* set CD flag */
-	wbinvd();
 	write_cr0(cr0);
 	wbinvd();
 
 	/*  Save value of CR4 and clear Page Global Enable (bit 7)  */
 	if ( cpu_has_pge ) {
 		cr4 = read_cr4();
-		write_cr4(cr4 & (unsigned char) ~(1 << 7));
+		write_cr4(cr4 & ~X86_CR4_PGE);
 	}
 
 	/* Flush all TLBs via a mov %cr3, %reg; mov %reg, %cr3 */
@@ -266,8 +273,7 @@
 
 static void post_set(void)
 {
-	/*  Flush caches and TLBs  */
-	wbinvd();
+	/*  Flush TLBs (no need to flush caches - they are disabled)  */
 	__flush_tlb();
 
 	/* Intel (P6) standard MTRRs */
@@ -285,13 +291,16 @@
 static void generic_set_all(void)
 {
 	unsigned long mask, count;
+	unsigned long flags;
 
+	local_irq_save(flags);
 	prepare_set();
 
 	/* Actually set the state */
 	mask = set_mtrr_state(deftype_lo,deftype_hi);
 
 	post_set();
+	local_irq_restore(flags);
 
 	/*  Use the atomic bitops to update the global mask  */
 	for (count = 0; count < sizeof mask * 8; ++count) {
@@ -314,6 +323,9 @@
     [RETURNS] Nothing.
 */
 {
+	unsigned long flags;
+
+	local_irq_save(flags);
 	prepare_set();
 
 	if (size == 0) {
@@ -328,6 +340,7 @@
 	}
 
 	post_set();
+	local_irq_restore(flags);
 }
 
 int generic_validate_add_page(unsigned long base, unsigned long size, unsigned int type)
diff -Nru a/arch/i386/kernel/cpu/proc.c b/arch/i386/kernel/cpu/proc.c
--- a/arch/i386/kernel/cpu/proc.c	2005-03-01 23:39:10 -08:00
+++ b/arch/i386/kernel/cpu/proc.c	2005-03-01 23:39:10 -08:00
@@ -28,7 +28,7 @@
 		"pni", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 		NULL, NULL, NULL, "syscall", NULL, NULL, NULL, NULL,
 		NULL, NULL, NULL, "mp", "nx", NULL, "mmxext", NULL,
-		NULL, NULL, NULL, NULL, NULL, "lm", "3dnowext", "3dnow",
+		NULL, "fxsr_opt", NULL, NULL, NULL, "lm", "3dnowext", "3dnow",
 
 		/* Transmeta-defined */
 		"recovery", "longrun", NULL, "lrti", NULL, NULL, NULL, NULL,
@@ -45,7 +45,7 @@
 
 		/* Intel-defined (#2) */
 		"pni", NULL, NULL, "monitor", "ds_cpl", NULL, NULL, "est",
-		"tm2", NULL, "cid", NULL, NULL, NULL, "xtpr", NULL,
+		"tm2", NULL, "cid", NULL, NULL, "cx16", "xtpr", NULL,
 		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 
@@ -54,6 +54,12 @@
 		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+
+		/* AMD-defined (#2) */
+		"lahf_lm", "cmp_legacy", NULL, NULL, NULL, NULL, NULL, NULL,
+		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 	};
 	struct cpuinfo_x86 *c = v;
 	int i, n = c - cpu_data;
@@ -88,11 +94,8 @@
 	if (c->x86_cache_size >= 0)
 		seq_printf(m, "cache size\t: %d KB\n", c->x86_cache_size);
 #ifdef CONFIG_X86_HT
-	if (smp_num_siblings > 1) {
-		extern int phys_proc_id[NR_CPUS];
-		seq_printf(m, "physical id\t: %d\n", phys_proc_id[n]);
-		seq_printf(m, "siblings\t: %d\n", smp_num_siblings);
-	}
+	seq_printf(m, "physical id\t: %d\n", phys_proc_id[n]);
+	seq_printf(m, "siblings\t: %d\n", c->x86_num_cores * smp_num_siblings);
 #endif
 	
 	/* We use exception 16 if we have hardware math and we've either seen it or the CPU claims it is internal */
diff -Nru a/arch/i386/kernel/dmi_scan.c b/arch/i386/kernel/dmi_scan.c
--- a/arch/i386/kernel/dmi_scan.c	2005-03-01 23:39:18 -08:00
+++ b/arch/i386/kernel/dmi_scan.c	2005-03-01 23:39:18 -08:00
@@ -102,11 +102,18 @@
 static int __init dmi_iterate(void (*decode)(struct dmi_header *))
 {
 	u8 buf[15];
-	u32 fp=0xF0000;
+	char __iomem *p, *q;
 
-	while (fp < 0xFFFFF)
-	{
-		isa_memcpy_fromio(buf, fp, 15);
+	/*
+	 * no iounmap() for that ioremap(); it would be a no-op, but it's
+	 * so early in setup that sucker gets confused into doing what
+	 * it shouldn't if we actually call it.
+	 */
+	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];
@@ -129,7 +136,6 @@
 			if(dmi_table(base,len, num, decode)==0)
 				return 0;
 		}
-		fp+=16;
 	}
 	return -1;
 }
diff -Nru a/arch/i386/kernel/efi.c b/arch/i386/kernel/efi.c
--- a/arch/i386/kernel/efi.c	2005-03-01 23:39:08 -08:00
+++ b/arch/i386/kernel/efi.c	2005-03-01 23:39:08 -08:00
@@ -62,7 +62,7 @@
  */
 
 static unsigned long efi_rt_eflags;
-static spinlock_t efi_rt_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(efi_rt_lock);
 static pgd_t efi_bak_pg_dir_pointer[2];
 
 static void efi_call_phys_prelog(void)
diff -Nru a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S
--- a/arch/i386/kernel/entry.S	2005-03-01 23:38:54 -08:00
+++ b/arch/i386/kernel/entry.S	2005-03-01 23:38:54 -08:00
@@ -176,6 +176,7 @@
 
 #ifdef CONFIG_PREEMPT
 ENTRY(resume_kernel)
+	cli
 	cmpl $0,TI_preempt_count(%ebp)	# non-zero preempt_count ?
 	jnz restore_all
 need_resched:
@@ -184,11 +185,7 @@
 	jz restore_all
 	testl $IF_MASK,EFLAGS(%esp)     # interrupts off (exception path) ?
 	jz restore_all
-	movl $PREEMPT_ACTIVE,TI_preempt_count(%ebp)
-	sti
-	call schedule
-	cli
-	movl $0,TI_preempt_count(%ebp)
+	call preempt_schedule_irq
 	jmp need_resched
 #endif
 
diff -Nru a/arch/i386/kernel/head.S b/arch/i386/kernel/head.S
--- a/arch/i386/kernel/head.S	2005-03-01 23:38:52 -08:00
+++ b/arch/i386/kernel/head.S	2005-03-01 23:38:52 -08:00
@@ -128,9 +128,6 @@
 	movl %eax,%fs
 	movl %eax,%gs
 
-	xorl %ebx,%ebx
-	incl %ebx				/* This is a secondary processor (AP) */
-
 /*
  *	New page tables may be in 4Mbyte page mode and may
  *	be using the global pages. 
@@ -148,7 +145,7 @@
 #define cr4_bits mmu_cr4_features-__PAGE_OFFSET
 	movl cr4_bits,%edx
 	andl %edx,%edx
-	jz 3f
+	jz 6f
 	movl %cr4,%eax		# Turn on paging options (PSE,PAE,..)
 	orl %edx,%eax
 	movl %eax,%cr4
@@ -176,9 +173,10 @@
 	wrmsr
 
 6:
-	/* cpuid clobbered ebx, set it up again: */
+	/* This is a secondary processor (AP) */
 	xorl %ebx,%ebx
 	incl %ebx
+
 3:
 #endif /* CONFIG_SMP */
 
diff -Nru a/arch/i386/kernel/i386_ksyms.c b/arch/i386/kernel/i386_ksyms.c
--- a/arch/i386/kernel/i386_ksyms.c	2005-03-01 23:39:17 -08:00
+++ b/arch/i386/kernel/i386_ksyms.c	2005-03-01 23:39:17 -08:00
@@ -61,7 +61,6 @@
 
 /* platform dependent support */
 EXPORT_SYMBOL(boot_cpu_data);
-EXPORT_SYMBOL(MCA_bus);
 #ifdef CONFIG_DISCONTIGMEM
 EXPORT_SYMBOL(node_data);
 EXPORT_SYMBOL(physnode_map);
@@ -75,7 +74,6 @@
 EXPORT_SYMBOL(__ioremap);
 EXPORT_SYMBOL(ioremap_nocache);
 EXPORT_SYMBOL(iounmap);
-EXPORT_SYMBOL(probe_irq_mask);
 EXPORT_SYMBOL(kernel_thread);
 EXPORT_SYMBOL(pm_idle);
 EXPORT_SYMBOL(pm_power_off);
diff -Nru a/arch/i386/kernel/i387.c b/arch/i386/kernel/i387.c
--- a/arch/i386/kernel/i387.c	2005-03-01 23:39:18 -08:00
+++ b/arch/i386/kernel/i387.c	2005-03-01 23:39:18 -08:00
@@ -60,7 +60,8 @@
 		tsk->thread.i387.fsave.twd = 0xffffffffu;
 		tsk->thread.i387.fsave.fos = 0xffff0000u;
 	}
-	tsk->used_math = 1;
+	/* only the device not available exception or ptrace can call init_fpu */
+	set_stopped_child_used_math(tsk);
 }
 
 /*
@@ -111,16 +112,17 @@
 static inline unsigned long twd_fxsr_to_i387( struct i387_fxsave_struct *fxsave )
 {
 	struct _fpxreg *st = NULL;
+	unsigned long tos = (fxsave->swd >> 11) & 7;
 	unsigned long twd = (unsigned long) fxsave->twd;
 	unsigned long tag;
 	unsigned long ret = 0xffff0000u;
 	int i;
 
-#define FPREG_ADDR(f, n)	((char *)&(f)->st_space + (n) * 16);
+#define FPREG_ADDR(f, n)	((void *)&(f)->st_space + (n) * 16);
 
 	for ( i = 0 ; i < 8 ; i++ ) {
 		if ( twd & 0x1 ) {
-			st = (struct _fpxreg *) FPREG_ADDR( fxsave, i );
+			st = FPREG_ADDR( fxsave, (i - tos) & 7 );
 
 			switch ( st->exponent & 0x7fff ) {
 			case 0x7fff:
@@ -330,13 +332,13 @@
 
 int save_i387( struct _fpstate __user *buf )
 {
-	if ( !current->used_math )
+	if ( !used_math() )
 		return 0;
 
 	/* This will cause a "finit" to be triggered by the next
 	 * attempted FPU operation by the 'current' process.
 	 */
-	current->used_math = 0;
+	clear_used_math();
 
 	if ( HAVE_HWFP ) {
 		if ( cpu_has_fxsr ) {
@@ -382,7 +384,7 @@
 	} else {
 		err = restore_i387_soft( &current->thread.i387.soft, buf );
 	}
-	current->used_math = 1;
+	set_used_math();
 	return err;
 }
 
@@ -506,7 +508,7 @@
 	int fpvalid;
 	struct task_struct *tsk = current;
 
-	fpvalid = tsk->used_math;
+	fpvalid = !!used_math();
 	if ( fpvalid ) {
 		unlazy_fpu( tsk );
 		if ( cpu_has_fxsr ) {
@@ -521,7 +523,7 @@
 
 int dump_task_fpu(struct task_struct *tsk, struct user_i387_struct *fpu)
 {
-	int fpvalid = tsk->used_math;
+	int fpvalid = !!tsk_used_math(tsk);
 
 	if (fpvalid) {
 		if (tsk == current)
@@ -536,7 +538,7 @@
 
 int dump_task_extended_fpu(struct task_struct *tsk, struct user_fxsr_struct *fpu)
 {
-	int fpvalid = tsk->used_math && cpu_has_fxsr;
+	int fpvalid = tsk_used_math(tsk) && cpu_has_fxsr;
 
 	if (fpvalid) {
 		if (tsk == current)
diff -Nru a/arch/i386/kernel/i8259.c b/arch/i386/kernel/i8259.c
--- a/arch/i386/kernel/i8259.c	2005-03-01 23:39:16 -08:00
+++ b/arch/i386/kernel/i8259.c	2005-03-01 23:39:16 -08:00
@@ -38,7 +38,7 @@
  * moves to arch independent land
  */
 
-spinlock_t i8259A_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(i8259A_lock);
 
 static void end_8259A_irq (unsigned int irq)
 {
diff -Nru a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c
--- a/arch/i386/kernel/io_apic.c	2005-03-01 23:38:55 -08:00
+++ b/arch/i386/kernel/io_apic.c	2005-03-01 23:38:55 -08:00
@@ -45,7 +45,7 @@
 int (*ioapic_renumber_irq)(int ioapic, int irq);
 atomic_t irq_mis_count;
 
-static spinlock_t ioapic_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(ioapic_lock);
 
 /*
  *	Is the SiS APIC rmw bug present ?
@@ -573,6 +573,7 @@
 	for ( ; ; ) {
 		set_current_state(TASK_INTERRUPTIBLE);
 		time_remaining = schedule_timeout(time_remaining);
+		try_to_freeze(PF_FREEZE);
 		if (time_after(jiffies,
 				prev_balance_time+balanced_irq_interval)) {
 			do_irq_balance();
diff -Nru a/arch/i386/kernel/kprobes.c b/arch/i386/kernel/kprobes.c
--- a/arch/i386/kernel/kprobes.c	2005-03-01 23:38:56 -08:00
+++ b/arch/i386/kernel/kprobes.c	2005-03-01 23:38:56 -08:00
@@ -31,6 +31,7 @@
 #include <linux/spinlock.h>
 #include <linux/preempt.h>
 #include <asm/kdebug.h>
+#include <asm/desc.h>
 
 /* kprobe_status settings */
 #define KPROBE_HIT_ACTIVE	0x00000001
@@ -61,10 +62,14 @@
 
 int arch_prepare_kprobe(struct kprobe *p)
 {
-	memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
 	return 0;
 }
 
+void arch_copy_kprobe(struct kprobe *p)
+{
+	memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
+}
+
 void arch_remove_kprobe(struct kprobe *p)
 {
 }
@@ -86,15 +91,26 @@
  * Interrupts are disabled on entry as trap3 is an interrupt gate and they
  * remain disabled thorough out this function.
  */
-static inline int kprobe_handler(struct pt_regs *regs)
+static int kprobe_handler(struct pt_regs *regs)
 {
 	struct kprobe *p;
 	int ret = 0;
-	u8 *addr = (u8 *) (regs->eip - 1);
+	kprobe_opcode_t *addr = NULL;
+	unsigned long *lp;
 
 	/* We're in an interrupt, but this is clear and BUG()-safe. */
 	preempt_disable();
-
+	/* Check if the application is using LDT entry for its code segment and
+	 * calculate the address by reading the base address from the LDT entry.
+	 */
+	if ((regs->xcs & 4) && (current->mm)) {
+		lp = (unsigned long *) ((unsigned long)((regs->xcs >> 3) * 8)
+					+ (char *) current->mm->context.ldt);
+		addr = (kprobe_opcode_t *) (get_desc_base(lp) + regs->eip -
+						sizeof(kprobe_opcode_t));
+	} else {
+		addr = (kprobe_opcode_t *)(regs->eip - sizeof(kprobe_opcode_t));
+	}
 	/* Check we're not actually recursing */
 	if (kprobe_running()) {
 		/* We *are* holding lock here, so this is safe.
diff -Nru a/arch/i386/kernel/mca.c b/arch/i386/kernel/mca.c
--- a/arch/i386/kernel/mca.c	2005-03-01 23:39:08 -08:00
+++ b/arch/i386/kernel/mca.c	2005-03-01 23:39:08 -08:00
@@ -56,13 +56,16 @@
 
 static unsigned char which_scsi = 0;
 
+int MCA_bus = 0;
+EXPORT_SYMBOL(MCA_bus);
+
 /*
  * Motherboard register spinlock. Untested on SMP at the moment, but
  * are there any MCA SMP boxes?
  *
  * Yes - Alan
  */
-spinlock_t mca_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(mca_lock);
 
 /* Build the status info for the adapter */
 
@@ -119,14 +122,14 @@
 
 /*--------------------------------------------------------------------*/
 
-struct resource mca_standard_resources[] = {
-	{ "system control port B (MCA)", 0x60, 0x60 },
-	{ "arbitration (MCA)", 0x90, 0x90 },
-	{ "card Select Feedback (MCA)", 0x91, 0x91 },
-	{ "system Control port A (MCA)", 0x92, 0x92 },
-	{ "system board setup (MCA)", 0x94, 0x94 },
-	{ "POS (MCA)", 0x96, 0x97 },
-	{ "POS (MCA)", 0x100, 0x107 }
+static struct resource mca_standard_resources[] = {
+	{ .start = 0x60, .end = 0x60, .name = "system control port B (MCA)" },
+	{ .start = 0x90, .end = 0x90, .name = "arbitration (MCA)" },
+	{ .start = 0x91, .end = 0x91, .name = "card Select Feedback (MCA)" },
+	{ .start = 0x92, .end = 0x92, .name = "system Control port A (MCA)" },
+	{ .start = 0x94, .end = 0x94, .name = "system board setup (MCA)" },
+	{ .start = 0x96, .end = 0x97, .name = "POS (MCA)" },
+	{ .start = 0x100, .end = 0x107, .name = "POS (MCA)" }
 };
 
 #define MCA_STANDARD_RESOURCES	(sizeof(mca_standard_resources)/sizeof(struct resource))
diff -Nru a/arch/i386/kernel/microcode.c b/arch/i386/kernel/microcode.c
--- a/arch/i386/kernel/microcode.c	2005-03-01 23:38:53 -08:00
+++ b/arch/i386/kernel/microcode.c	2005-03-01 23:38:53 -08:00
@@ -109,7 +109,7 @@
 #define exttable_size(et) ((et)->count * EXT_SIGNATURE_SIZE + EXT_HEADER_SIZE)
 
 /* serialize access to the physical write to MSR 0x79 */
-static spinlock_t microcode_update_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(microcode_update_lock);
 
 /* no concurrent ->write()s are allowed on /dev/cpu/microcode */
 static DECLARE_MUTEX(microcode_sem);
@@ -364,7 +364,7 @@
 	struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num;
 
 	if (uci->mc == NULL) {
-		printk(KERN_INFO "microcode: No suitable data for CPU%d\n", cpu_num);
+		printk(KERN_INFO "microcode: No new microcode data for CPU%d\n", cpu_num);
 		return;
 	}
 
diff -Nru a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c
--- a/arch/i386/kernel/mpparse.c	2005-03-01 23:38:54 -08:00
+++ b/arch/i386/kernel/mpparse.c	2005-03-01 23:38:54 -08:00
@@ -309,8 +309,8 @@
 		printk(KERN_ERR "MAX_MPC_ENTRY exceeded!\n");
 	else
 		translation_table[mpc_record] = m; /* stash this for later */
-	if (m->trans_quad+1 > numnodes)
-		numnodes = m->trans_quad+1;
+	if (m->trans_quad < MAX_NUMNODES && !node_online(m->trans_quad))
+		node_set_online(m->trans_quad);
 }
 
 /*
diff -Nru a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c
--- a/arch/i386/kernel/nmi.c	2005-03-01 23:38:58 -08:00
+++ b/arch/i386/kernel/nmi.c	2005-03-01 23:38:58 -08:00
@@ -50,7 +50,7 @@
  * This is maintained separately from nmi_active because the NMI
  * watchdog may also be driven from the I/O APIC timer.
  */
-static spinlock_t lapic_nmi_owner_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(lapic_nmi_owner_lock);
 static unsigned int lapic_nmi_owner;
 #define LAPIC_NMI_WATCHDOG	(1<<0)
 #define LAPIC_NMI_RESERVED	(1<<1)
@@ -117,8 +117,12 @@
 	/* FIXME: Only boot CPU is online at this stage.  Check CPUs
            as they come up. */
 	for (cpu = 0; cpu < NR_CPUS; cpu++) {
-		if (!cpu_online(cpu))
+#ifdef CONFIG_SMP
+		/* Check cpu_callin_map here because that is set
+		   after the timer is started. */
+		if (!cpu_isset(cpu, cpu_callin_map))
 			continue;
+#endif
 		if (nmi_count(cpu) - prev_nmi_count[cpu] <= 5) {
 			printk("CPU#%d: NMI appears to be stuck!\n", cpu);
 			nmi_active = 0;
diff -Nru a/arch/i386/kernel/numaq.c b/arch/i386/kernel/numaq.c
--- a/arch/i386/kernel/numaq.c	2005-03-01 23:39:08 -08:00
+++ b/arch/i386/kernel/numaq.c	2005-03-01 23:39:08 -08:00
@@ -40,8 +40,7 @@
  * Function: smp_dump_qct()
  *
  * Description: gets memory layout from the quad config table.  This
- * function also increments numnodes with the number of nodes (quads)
- * present.
+ * function also updates node_online_map with the nodes (quads) present.
  */
 static void __init smp_dump_qct(void)
 {
@@ -50,11 +49,10 @@
 	struct sys_cfg_data *scd =
 		(struct sys_cfg_data *)__va(SYS_CFG_DATA_PRIV_ADDR);
 
-	numnodes = 0;
-	for(node = 0; node < MAX_NUMNODES; node++) {
-		if(scd->quads_present31_0 & (1 << node)) {
+	nodes_clear(node_online_map);
+	for_each_node(node) {
+		if (scd->quads_present31_0 & (1 << node)) {
 			node_set_online(node);
-			numnodes++;
 			eq = &scd->eq[node];
 			/* Convert to pages */
 			node_start_pfn[node] = MB_TO_PAGES(
diff -Nru a/arch/i386/kernel/pci-dma.c b/arch/i386/kernel/pci-dma.c
--- a/arch/i386/kernel/pci-dma.c	2005-03-01 23:38:53 -08:00
+++ b/arch/i386/kernel/pci-dma.c	2005-03-01 23:38:53 -08:00
@@ -89,11 +89,11 @@
 	if (!mem_base)
 		goto out;
 
-	dev->dma_mem = kmalloc(GFP_KERNEL, sizeof(struct dma_coherent_mem));
+	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(GFP_KERNEL, bitmap_size);
+	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);
@@ -122,6 +122,7 @@
 	if(!mem)
 		return;
 	dev->dma_mem = NULL;
+	iounmap(mem->virt_base);
 	kfree(mem->bitmap);
 	kfree(mem);
 }
diff -Nru a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
--- a/arch/i386/kernel/process.c	2005-03-01 23:38:43 -08:00
+++ b/arch/i386/kernel/process.c	2005-03-01 23:38:43 -08:00
@@ -72,6 +72,7 @@
  * Powermanagement idle function, if any..
  */
 void (*pm_idle)(void);
+static cpumask_t cpu_idle_map;
 
 void disable_hlt(void)
 {
@@ -93,7 +94,7 @@
  */
 void default_idle(void)
 {
-	if (!hlt_counter && current_cpu_data.hlt_works_ok) {
+	if (!hlt_counter && boot_cpu_data.hlt_works_ok) {
 		local_irq_disable();
 		if (!need_resched())
 			safe_halt();
@@ -144,29 +145,44 @@
  */
 void cpu_idle (void)
 {
+	int cpu = _smp_processor_id();
+
 	/* endless idle loop with no priority at all */
 	while (1) {
 		while (!need_resched()) {
 			void (*idle)(void);
-			/*
-			 * Mark this as an RCU critical section so that
-			 * synchronize_kernel() in the unload path waits
-			 * for our completion.
-			 */
-			rcu_read_lock();
+
+			if (cpu_isset(cpu, cpu_idle_map))
+				cpu_clear(cpu, cpu_idle_map);
+			rmb();
 			idle = pm_idle;
 
 			if (!idle)
 				idle = default_idle;
 
-			irq_stat[smp_processor_id()].idle_timestamp = jiffies;
+			irq_stat[cpu].idle_timestamp = jiffies;
 			idle();
-			rcu_read_unlock();
 		}
 		schedule();
 	}
 }
 
+void cpu_idle_wait(void)
+{
+	int cpu;
+	cpumask_t map;
+
+	for_each_online_cpu(cpu)
+		cpu_set(cpu, cpu_idle_map);
+
+	wmb();
+	do {
+		ssleep(1);
+		cpus_and(map, cpu_idle_map, cpu_online_map);
+	} while (!cpus_empty(map));
+}
+EXPORT_SYMBOL_GPL(cpu_idle_wait);
+
 /*
  * This uses new MONITOR/MWAIT instructions on P4 processors with PNI,
  * which can obviate IPI to trigger checking of need_resched.
@@ -335,7 +351,7 @@
 	 * Forget coprocessor state..
 	 */
 	clear_fpu(tsk);
-	tsk->used_math = 0;
+	clear_used_math();
 }
 
 void release_thread(struct task_struct *dead_task)
diff -Nru a/arch/i386/kernel/ptrace.c b/arch/i386/kernel/ptrace.c
--- a/arch/i386/kernel/ptrace.c	2005-03-01 23:38:54 -08:00
+++ b/arch/i386/kernel/ptrace.c	2005-03-01 23:38:54 -08:00
@@ -42,6 +42,12 @@
  */
 #define EFL_OFFSET ((EFL-2)*4-sizeof(struct pt_regs))
 
+static inline struct pt_regs *get_child_regs(struct task_struct *task)
+{
+	void *stack_top = (void *)task->thread.esp0;
+	return stack_top - sizeof(struct pt_regs);
+}
+
 /*
  * this routine will get a word off of the processes privileged stack. 
  * the offset is how far from the base addr as stored in the TSS.  
@@ -138,24 +144,119 @@
 	return retval;
 }
 
+#define LDT_SEGMENT 4
+
+static unsigned long convert_eip_to_linear(struct task_struct *child, struct pt_regs *regs)
+{
+	unsigned long addr, seg;
+
+	addr = regs->eip;
+	seg = regs->xcs & 0xffff;
+	if (regs->eflags & VM_MASK) {
+		addr = (addr & 0xffff) + (seg << 4);
+		return addr;
+	}
+
+	/*
+	 * We'll assume that the code segments in the GDT
+	 * are all zero-based. That is largely true: the
+	 * TLS segments are used for data, and the PNPBIOS
+	 * and APM bios ones we just ignore here.
+	 */
+	if (seg & LDT_SEGMENT) {
+		u32 *desc;
+		unsigned long base;
+
+		down(&child->mm->context.sem);
+		desc = child->mm->context.ldt + (seg & ~7);
+		base = (desc[0] >> 16) | ((desc[1] & 0xff) << 16) | (desc[1] & 0xff000000);
+
+		/* 16-bit code segment? */
+		if (!((desc[1] >> 22) & 1))
+			addr &= 0xffff;
+		addr += base;
+		up(&child->mm->context.sem);
+	}
+	return addr;
+}
+
+static inline int is_at_popf(struct task_struct *child, struct pt_regs *regs)
+{
+	int i, copied;
+	unsigned char opcode[16];
+	unsigned long addr = convert_eip_to_linear(child, regs);
+
+	copied = access_process_vm(child, addr, opcode, sizeof(opcode), 0);
+	for (i = 0; i < copied; i++) {
+		switch (opcode[i]) {
+		/* popf */
+		case 0x9d:
+			return 1;
+		/* opcode and address size prefixes */
+		case 0x66: case 0x67:
+			continue;
+		/* irrelevant prefixes (segment overrides and repeats) */
+		case 0x26: case 0x2e:
+		case 0x36: case 0x3e:
+		case 0x64: case 0x65:
+		case 0xf0: case 0xf2: case 0xf3:
+			continue;
+
+		/*
+		 * pushf: NOTE! We should probably not let
+		 * the user see the TF bit being set. But
+		 * it's more pain than it's worth to avoid
+		 * it, and a debugger could emulate this
+		 * all in user space if it _really_ cares.
+		 */
+		case 0x9c:
+		default:
+			return 0;
+		}
+	}
+	return 0;
+}
+
 static void set_singlestep(struct task_struct *child)
 {
-	long eflags;
+	struct pt_regs *regs = get_child_regs(child);
 
+	/*
+	 * Always set TIF_SINGLESTEP - this guarantees that 
+	 * we single-step system calls etc..  This will also
+	 * cause us to set TF when returning to user mode.
+	 */
 	set_tsk_thread_flag(child, TIF_SINGLESTEP);
-	eflags = get_stack_long(child, EFL_OFFSET);
-	put_stack_long(child, EFL_OFFSET, eflags | TRAP_FLAG);
+
+	/*
+	 * If TF was already set, don't do anything else
+	 */
+	if (regs->eflags & TRAP_FLAG)
+		return;
+
+	/* Set TF on the kernel stack.. */
+	regs->eflags |= TRAP_FLAG;
+
+	/*
+	 * ..but if TF is changed by the instruction we will trace,
+	 * don't mark it as being "us" that set it, so that we
+	 * won't clear it by hand later.
+	 */
+	if (is_at_popf(child, regs))
+		return;
+	
 	child->ptrace |= PT_DTRACE;
 }
 
 static void clear_singlestep(struct task_struct *child)
 {
-	if (child->ptrace & PT_DTRACE) {
-		long eflags;
+	/* Always clear TIF_SINGLESTEP... */
+	clear_tsk_thread_flag(child, TIF_SINGLESTEP);
 
-		clear_tsk_thread_flag(child, TIF_SINGLESTEP);
-		eflags = get_stack_long(child, EFL_OFFSET);
-		put_stack_long(child, EFL_OFFSET, eflags & ~TRAP_FLAG);
+	/* But touch TF only if it was set by us.. */
+	if (child->ptrace & PT_DTRACE) {
+		struct pt_regs *regs = get_child_regs(child);
+		regs->eflags &= ~TRAP_FLAG;
 		child->ptrace &= ~PT_DTRACE;
 	}
 }
@@ -491,7 +592,7 @@
 			break;
 		}
 		ret = 0;
-		if (!child->used_math)
+		if (!tsk_used_math(child))
 			init_fpu(child);
 		get_fpregs((struct user_i387_struct __user *)data, child);
 		break;
@@ -503,7 +604,7 @@
 			ret = -EIO;
 			break;
 		}
-		child->used_math = 1;
+		set_stopped_child_used_math(child);
 		set_fpregs(child, (struct user_i387_struct __user *)data);
 		ret = 0;
 		break;
@@ -515,7 +616,7 @@
 			ret = -EIO;
 			break;
 		}
-		if (!child->used_math)
+		if (!tsk_used_math(child))
 			init_fpu(child);
 		ret = get_fpxregs((struct user_fxsr_struct __user *)data, child);
 		break;
@@ -527,7 +628,7 @@
 			ret = -EIO;
 			break;
 		}
-		child->used_math = 1;
+		set_stopped_child_used_math(child);
 		ret = set_fpxregs(child, (struct user_fxsr_struct __user *)data);
 		break;
 	}
@@ -553,6 +654,24 @@
 	return ret;
 }
 
+void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code)
+{
+	struct siginfo info;
+
+	tsk->thread.trap_no = 1;
+	tsk->thread.error_code = error_code;
+
+	memset(&info, 0, sizeof(info));
+	info.si_signo = SIGTRAP;
+	info.si_code = TRAP_BRKPT;
+
+	/* User-mode eip? */
+	info.si_addr = user_mode(regs) ? (void __user *) regs->eip : NULL;
+
+	/* Send us the fakey SIGTRAP */
+	force_sig_info(SIGTRAP, &info, tsk);
+}
+
 /* notification of system call entry/exit
  * - triggered by current->work.syscall_trace
  */
@@ -568,15 +687,19 @@
 			audit_syscall_exit(current, regs->eax);
 	}
 
-	if (!test_thread_flag(TIF_SYSCALL_TRACE) &&
-	    !test_thread_flag(TIF_SINGLESTEP))
-		return;
 	if (!(current->ptrace & PT_PTRACED))
 		return;
+
+	/* Fake a debug trap */
+	if (test_thread_flag(TIF_SINGLESTEP))
+		send_sigtrap(current, regs, 0);
+
+	if (!test_thread_flag(TIF_SYSCALL_TRACE))
+		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) &&
-				 !test_thread_flag(TIF_SINGLESTEP) ? 0x80 : 0));
+	ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) ? 0x80 : 0));
 
 	/*
 	 * this isn't the same as continuing with a signal, but it will do
diff -Nru a/arch/i386/kernel/reboot.c b/arch/i386/kernel/reboot.c
--- a/arch/i386/kernel/reboot.c	2005-03-01 23:38:54 -08:00
+++ b/arch/i386/kernel/reboot.c	2005-03-01 23:38:54 -08:00
@@ -20,7 +20,7 @@
 void (*pm_power_off)(void);
 
 static int reboot_mode;
-int reboot_thru_bios;
+static int reboot_thru_bios;
 
 #ifdef CONFIG_SMP
 int reboot_smp = 0;
diff -Nru a/arch/i386/kernel/scx200.c b/arch/i386/kernel/scx200.c
--- a/arch/i386/kernel/scx200.c	2005-03-01 23:39:09 -08:00
+++ b/arch/i386/kernel/scx200.c	2005-03-01 23:39:09 -08:00
@@ -37,8 +37,8 @@
 	.probe = scx200_probe,
 };
 
-spinlock_t scx200_gpio_lock = SPIN_LOCK_UNLOCKED;
-static spinlock_t scx200_gpio_config_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(scx200_gpio_lock);
+static DEFINE_SPINLOCK(scx200_gpio_config_lock);
 
 static int __devinit scx200_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
diff -Nru a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
--- a/arch/i386/kernel/setup.c	2005-03-01 23:38:57 -08:00
+++ b/arch/i386/kernel/setup.c	2005-03-01 23:38:57 -08:00
@@ -33,6 +33,7 @@
 #include <linux/bootmem.h>
 #include <linux/seq_file.h>
 #include <linux/console.h>
+#include <linux/mca.h>
 #include <linux/root_dev.h>
 #include <linux/highmem.h>
 #include <linux/module.h>
@@ -87,7 +88,6 @@
 extern acpi_interrupt_flags	acpi_sci_flags;
 #endif
 
-int MCA_bus;
 /* for MCA, but anyone else can use it if they want */
 unsigned int machine_id;
 unsigned int machine_submodel_id;
@@ -97,6 +97,9 @@
 /* For PCI or other memory-mapped resources */
 unsigned long pci_mem_start = 0x10000000;
 
+/* Boot loader ID as an integer, for the benefit of proc_dointvec */
+int bootloader_type;
+
 /* user-defined highmem size */
 static unsigned int highmem_pages = -1;
 
@@ -672,6 +675,8 @@
 	saved_command_line[COMMAND_LINE_SIZE-1] = '\0';
 
 	for (;;) {
+		if (c != ' ')
+			goto next_char;
 		/*
 		 * "mem=nopentium" disables the 4MB page tables.
 		 * "mem=XXX[kKmM]" defines a memory region from HIGH_MEM
@@ -682,7 +687,7 @@
 		 * HPA tells me bootloaders need to parse mem=, so no new
 		 * option should be mem=  [also see Documentation/i386/boot.txt]
 		 */
-		if (c == ' ' && !memcmp(from, "mem=", 4)) {
+		if (!memcmp(from, "mem=", 4)) {
 			if (to != command_line)
 				to--;
 			if (!memcmp(from+4, "nopentium", 9)) {
@@ -704,7 +709,7 @@
 			}
 		}
 
-		if (c == ' ' && !memcmp(from, "memmap=", 7)) {
+		else if (!memcmp(from, "memmap=", 7)) {
 			if (to != command_line)
 				to--;
 			if (!memcmp(from+7, "exactmap", 8)) {
@@ -737,6 +742,10 @@
 			}
 		}
 
+		else if (!memcmp(from, "noexec=", 7))
+			noexec_setup(from + 7);
+
+
 #ifdef  CONFIG_X86_SMP
 		/*
 		 * If the BIOS enumerates physical processors before logical,
@@ -812,7 +821,7 @@
 		 * This works even on boxes that have no highmem otherwise.
 		 * This also works to reduce highmem size on bigger boxes.
 		 */
-		if (c == ' ' && !memcmp(from, "highmem=", 8))
+		else if (!memcmp(from, "highmem=", 8))
 			highmem_pages = memparse(from+8, &from) >> PAGE_SHIFT;
 	
 		/*
@@ -820,9 +829,10 @@
 		 * bytes. This can be used to increase (or decrease) the
 		 * vmalloc area - the default is 128m.
 		 */
-		if (c == ' ' && !memcmp(from, "vmalloc=", 8))
+		else if (!memcmp(from, "vmalloc=", 8))
 			__VMALLOC_RESERVE = memparse(from+8, &from);
 
+	next_char:
 		c = *(from++);
 		if (!c)
 			break;
@@ -1156,9 +1166,10 @@
 /*
  * Request address space for all standard resources
  */
-static void __init register_memory(unsigned long max_low_pfn)
+static void __init register_memory(void)
 {
-	unsigned long low_mem_size;
+	unsigned long gapstart, gapsize;
+	unsigned long long last;
 	int	      i;
 
 	if (efi_enabled)
@@ -1173,10 +1184,46 @@
 	for (i = 0; i < STANDARD_IO_RESOURCES; i++)
 		request_resource(&ioport_resource, &standard_io_resources[i]);
 
-	/* Tell the PCI layer not to allocate too close to the RAM area.. */
-	low_mem_size = ((max_low_pfn << PAGE_SHIFT) + 0xfffff) & ~0xfffff;
-	if (low_mem_size > pci_mem_start)
-		pci_mem_start = low_mem_size;
+	/*
+	 * Search for the bigest gap in the low 32 bits of the e820
+	 * memory space.
+	 */
+	last = 0x100000000ull;
+	gapstart = 0x10000000;
+	gapsize = 0x400000;
+	i = e820.nr_map;
+	while (--i >= 0) {
+		unsigned long long start = e820.map[i].addr;
+		unsigned long long end = start + e820.map[i].size;
+
+		/*
+		 * Since "last" is at most 4GB, we know we'll
+		 * fit in 32 bits if this condition is true
+		 */
+		if (last > end) {
+			unsigned long gap = last - end;
+
+			if (gap > gapsize) {
+				gapsize = gap;
+				gapstart = end;
+			}
+		}
+		if (start < last)
+			last = start;
+	}
+
+	/*
+	 * Start allocating dynamic PCI memory a bit into the gap,
+	 * aligned up to the nearest megabyte.
+	 *
+	 * Question: should we try to pad it up a bit (do something
+	 * like " + (gapsize >> 3)" in there too?). We now have the
+	 * technology.
+	 */
+	pci_mem_start = (gapstart + 0xfffff) & ~0xfffff;
+
+	printk("Allocating PCI resources starting at %08lx (gap: %08lx:%08lx)\n",
+		pci_mem_start, gapstart, gapsize);
 }
 
 /* Use inline assembly to define this because the nops are defined 
@@ -1288,6 +1335,15 @@
 
 static char * __init machine_specific_memory_setup(void);
 
+#ifdef CONFIG_MCA
+static void set_mca_bus(int x)
+{
+	MCA_bus = x;
+}
+#else
+static void set_mca_bus(int x) { }
+#endif
+
 /*
  * Determine if we were loaded by an EFI loader.  If so, then we have also been
  * passed the efi memmap, systab, etc., so we should use these data structures
@@ -1323,12 +1379,13 @@
 	ist_info = IST_INFO;
 	saved_videomode = VIDEO_MODE;
 	if( SYS_DESC_TABLE.length != 0 ) {
-		MCA_bus = SYS_DESC_TABLE.table[3] &0x2;
+		set_mca_bus(SYS_DESC_TABLE.table[3] & 0x2);
 		machine_id = SYS_DESC_TABLE.table[0];
 		machine_submodel_id = SYS_DESC_TABLE.table[1];
 		BIOS_revision = SYS_DESC_TABLE.table[2];
 	}
 	aux_device_present = AUX_DEVICE_INFO;
+	bootloader_type = LOADER_TYPE;
 
 #ifdef CONFIG_BLK_DEV_RAM
 	rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK;
@@ -1404,6 +1461,7 @@
 	/*
 	 * Parse the ACPI tables for possible boot-time SMP configuration.
 	 */
+	acpi_boot_table_init();
 	acpi_boot_init();
 
 #ifdef CONFIG_X86_LOCAL_APIC
@@ -1411,7 +1469,7 @@
 		get_smp_config();
 #endif
 
-	register_memory(max_low_pfn);
+	register_memory();
 
 #ifdef CONFIG_VT
 #if defined(CONFIG_VGA_CONSOLE)
diff -Nru a/arch/i386/kernel/signal.c b/arch/i386/kernel/signal.c
--- a/arch/i386/kernel/signal.c	2005-03-01 23:38:56 -08:00
+++ b/arch/i386/kernel/signal.c	2005-03-01 23:38:56 -08:00
@@ -190,6 +190,12 @@
 			if (verify_area(VERIFY_READ, buf, sizeof(*buf)))
 				goto badframe;
 			err |= restore_i387(buf);
+		} else {
+			struct task_struct *me = current;
+			if (used_math()) {
+				clear_fpu(me);
+				clear_used_math();
+			}
 		}
 	}
 
@@ -270,7 +276,6 @@
 		 struct pt_regs *regs, unsigned long mask)
 {
 	int tmp, err = 0;
-	unsigned long eflags;
 
 	tmp = 0;
 	__asm__("movl %%gs,%0" : "=r"(tmp): "0"(tmp));
@@ -292,16 +297,7 @@
 	err |= __put_user(current->thread.error_code, &sc->err);
 	err |= __put_user(regs->eip, &sc->eip);
 	err |= __put_user(regs->xcs, (unsigned int __user *)&sc->cs);
-
-	/*
-	 * Iff TF was set because the program is being single-stepped by a
-	 * debugger, don't save that information on the signal stack.. We
-	 * don't want debugging to change state.
-	 */
-	eflags = regs->eflags;
-	if (current->ptrace & PT_DTRACE)
-		eflags &= ~TF_MASK;
-	err |= __put_user(eflags, &sc->eflags);
+	err |= __put_user(regs->eflags, &sc->eflags);
 	err |= __put_user(regs->esp, &sc->esp_at_signal);
 	err |= __put_user(regs->xss, (unsigned int __user *)&sc->ss);
 
@@ -369,20 +365,20 @@
 		? current_thread_info()->exec_domain->signal_invmap[sig]
 		: sig;
 
-	err |= __put_user(usig, &frame->sig);
+	err = __put_user(usig, &frame->sig);
 	if (err)
 		goto give_sigsegv;
 
-	err |= setup_sigcontext(&frame->sc, &frame->fpstate, regs, set->sig[0]);
+	err = setup_sigcontext(&frame->sc, &frame->fpstate, regs, set->sig[0]);
 	if (err)
 		goto give_sigsegv;
 
 	if (_NSIG_WORDS > 1) {
-		err |= __copy_to_user(&frame->extramask, &set->sig[1],
+		err = __copy_to_user(&frame->extramask, &set->sig[1],
 				      sizeof(frame->extramask));
+		if (err)
+			goto give_sigsegv;
 	}
-	if (err)
-		goto give_sigsegv;
 
 	restorer = &__kernel_sigreturn;
 	if (ka->sa.sa_flags & SA_RESTORER)
@@ -424,11 +420,9 @@
 	 * The tracer may want to single-step inside the
 	 * handler too.
 	 */
-	if (regs->eflags & TF_MASK) {
-		regs->eflags &= ~TF_MASK;
-		if (current->ptrace & PT_DTRACE)
-			ptrace_notify(SIGTRAP);
-	}
+	regs->eflags &= ~TF_MASK;
+	if (test_thread_flag(TIF_SINGLESTEP))
+		ptrace_notify(SIGTRAP);
 
 #if DEBUG_SIG
 	printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
@@ -519,11 +513,9 @@
 	 * The tracer may want to single-step inside the
 	 * handler too.
 	 */
-	if (regs->eflags & TF_MASK) {
-		regs->eflags &= ~TF_MASK;
-		if (current->ptrace & PT_DTRACE)
-			ptrace_notify(SIGTRAP);
-	}
+	regs->eflags &= ~TF_MASK;
+	if (test_thread_flag(TIF_SINGLESTEP))
+		ptrace_notify(SIGTRAP);
 
 #if DEBUG_SIG
 	printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
diff -Nru a/arch/i386/kernel/smp.c b/arch/i386/kernel/smp.c
--- a/arch/i386/kernel/smp.c	2005-03-01 23:38:52 -08:00
+++ b/arch/i386/kernel/smp.c	2005-03-01 23:38:52 -08:00
@@ -244,7 +244,7 @@
 static cpumask_t flush_cpumask;
 static struct mm_struct * flush_mm;
 static unsigned long flush_va;
-static spinlock_t tlbstate_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(tlbstate_lock);
 #define FLUSH_ALL	0xffffffff
 
 /*
@@ -481,7 +481,7 @@
  * Structure and data for smp_call_function(). This is designed to minimise
  * static memory requirements. It also looks cleaner.
  */
-static spinlock_t call_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(call_lock);
 
 struct call_data_struct {
 	void (*func) (void *info);
diff -Nru a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
--- a/arch/i386/kernel/smpboot.c	2005-03-01 23:38:57 -08:00
+++ b/arch/i386/kernel/smpboot.c	2005-03-01 23:38:57 -08:00
@@ -61,11 +61,12 @@
 /* Number of siblings per CPU package */
 int smp_num_siblings = 1;
 int phys_proc_id[NR_CPUS]; /* Package ID of each logical CPU */
+EXPORT_SYMBOL(phys_proc_id);
 
 /* bitmap of online cpus */
 cpumask_t cpu_online_map;
 
-static cpumask_t cpu_callin_map;
+cpumask_t cpu_callin_map;
 cpumask_t cpu_callout_map;
 static cpumask_t smp_commenced_mask;
 
@@ -382,8 +383,6 @@
 	setup_local_APIC();
 	map_cpu_to_logical_apicid();
 
-	local_irq_enable();
-
 	/*
 	 * Get our bogomips.
 	 */
@@ -396,7 +395,7 @@
  	smp_store_cpu_info(cpuid);
 
 	disable_APIC_timer();
-	local_irq_disable();
+
 	/*
 	 * Allow the master to continue.
 	 */
@@ -411,12 +410,10 @@
 
 int cpucount;
 
-extern int cpu_idle(void);
-
 /*
  * Activate a secondary processor.
  */
-int __init start_secondary(void *unused)
+static void __init start_secondary(void *unused)
 {
 	/*
 	 * Dont put anything before smp_callin(), SMP
@@ -440,8 +437,12 @@
 	 */
 	local_flush_tlb();
 	cpu_set(smp_processor_id(), cpu_online_map);
+
+	/* We can take interrupts now: we're officially "up". */
+	local_irq_enable();
+
 	wmb();
-	return cpu_idle();
+	cpu_idle();
 }
 
 /*
diff -Nru a/arch/i386/kernel/srat.c b/arch/i386/kernel/srat.c
--- a/arch/i386/kernel/srat.c	2005-03-01 23:38:53 -08:00
+++ b/arch/i386/kernel/srat.c	2005-03-01 23:38:53 -08:00
@@ -232,18 +232,22 @@
 	 * a set of sequential node IDs starting at zero.  (ACPI doesn't seem
 	 * to specify the range of _PXM values.)
 	 */
-	numnodes = 0;		/* init total nodes in system */
+	/*
+	 * MCD - we no longer HAVE to number nodes sequentially.  PXM domain
+	 * numbers could go as high as 256, and MAX_NUMNODES for i386 is typically
+	 * 32, so we will continue numbering them in this manner until MAX_NUMNODES
+	 * approaches MAX_PXM_DOMAINS for i386.
+	 */
+	nodes_clear(node_online_map);
 	for (i = 0; i < MAX_PXM_DOMAINS; i++) {
 		if (BMAP_TEST(pxm_bitmap, i)) {
-			pxm_to_nid_map[i] = numnodes;
-			nid_to_pxm_map[numnodes] = i;
-			node_set_online(numnodes);
-			++numnodes;
+			nid = num_online_nodes();
+			pxm_to_nid_map[i] = nid;
+			nid_to_pxm_map[nid] = i;
+			node_set_online(nid);
 		}
 	}
-
-	if (numnodes == 0)
-		BUG();
+	BUG_ON(num_online_nodes() == 0);
 
 	/* set cnode id in memory chunk structure */
 	for (i = 0; i < num_memory_chunks; i++)
@@ -254,7 +258,7 @@
 		printk("%02X ", pxm_bitmap[i]);
 	}
 	printk("\n");
-	printk("Number of logical nodes in system = %d\n", numnodes);
+	printk("Number of logical nodes in system = %d\n", num_online_nodes());
 	printk("Number of memory chunks in system = %d\n", num_memory_chunks);
 
 	for (j = 0; j < num_memory_chunks; j++){
@@ -265,7 +269,7 @@
 	}
  
 	/*calculate node_start_pfn/node_end_pfn arrays*/
-	for (nid = 0; nid < numnodes; nid++) {
+	for_each_online_node(nid) {
 		int been_here_before = 0;
 
 		for (j = 0; j < num_memory_chunks; j++){
@@ -397,7 +401,7 @@
 	int first;
 	unsigned long end = 0;
 
-	for (nid = 0; nid < numnodes; nid++) {
+	for_each_online_node(nid) {
 		first = 1;
 		for (c = 0; c < num_memory_chunks; c++){
 			if (node_memory_chunk[c].nid == nid) {
@@ -425,8 +429,8 @@
 		zholes_size_init++;
 		get_zholes_init();
 	}
-	if((nid >= numnodes) | (nid >= MAX_NUMNODES))
-		printk("%s: nid = %d is invalid. numnodes = %d",
-		       __FUNCTION__, nid, numnodes);
+	if (nid >= MAX_NUMNODES || !node_online(nid))
+		printk("%s: nid = %d is invalid/offline. num_online_nodes = %d",
+		       __FUNCTION__, nid, num_online_nodes());
 	return &zholes_size[nid * MAX_NR_ZONES];
 }
diff -Nru a/arch/i386/kernel/time.c b/arch/i386/kernel/time.c
--- a/arch/i386/kernel/time.c	2005-03-01 23:38:57 -08:00
+++ b/arch/i386/kernel/time.c	2005-03-01 23:38:57 -08:00
@@ -45,6 +45,7 @@
 #include <linux/sysdev.h>
 #include <linux/bcd.h>
 #include <linux/efi.h>
+#include <linux/mca.h>
 
 #include <asm/io.h>
 #include <asm/smp.h>
@@ -80,9 +81,9 @@
 
 extern unsigned long wall_jiffies;
 
-spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(rtc_lock);
 
-spinlock_t i8253_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(i8253_lock);
 EXPORT_SYMBOL(i8253_lock);
 
 struct timer_opts *cur_timer = &timer_none;
@@ -261,8 +262,7 @@
 			last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
 	}
 
-#ifdef CONFIG_MCA
-	if( MCA_bus ) {
+	if (MCA_bus) {
 		/* The PS/2 uses level-triggered interrupts.  You can't
 		turn them off, nor would you want to (any attempt to
 		enable edge-triggered interrupts usually gets intercepted by a
@@ -275,7 +275,6 @@
 		irq = inb_p( 0x61 );	/* read the current state */
 		outb_p( irq|0x80, 0x61 );	/* reset the IRQ */
 	}
-#endif
 }
 
 /*
@@ -343,12 +342,13 @@
 		hpet_reenable();
 #endif
 	sec = get_cmos_time() + clock_cmos_diff;
-	sleep_length = get_cmos_time() - sleep_start;
+	sleep_length = (get_cmos_time() - sleep_start) * HZ;
 	write_seqlock_irqsave(&xtime_lock, flags);
 	xtime.tv_sec = sec;
 	xtime.tv_nsec = 0;
 	write_sequnlock_irqrestore(&xtime_lock, flags);
-	jiffies += sleep_length * HZ;
+	jiffies += sleep_length;
+	wall_jiffies += sleep_length;
 	return 0;
 }
 
diff -Nru a/arch/i386/kernel/time_hpet.c b/arch/i386/kernel/time_hpet.c
--- a/arch/i386/kernel/time_hpet.c	2005-03-01 23:38:53 -08:00
+++ b/arch/i386/kernel/time_hpet.c	2005-03-01 23:38:53 -08:00
@@ -81,6 +81,11 @@
 	cfg |= HPET_TN_ENABLE | HPET_TN_PERIODIC |
 	       HPET_TN_SETVAL | HPET_TN_32BIT;
 	hpet_writel(cfg, HPET_T0_CFG);
+	/*
+	 * Some systems seems to need two writes to HPET_T0_CMP,
+	 * to get interrupts working
+	 */
+	hpet_writel(tick, HPET_T0_CMP);
 	hpet_writel(tick, HPET_T0_CMP);
 
 	/*
diff -Nru a/arch/i386/kernel/trampoline.S b/arch/i386/kernel/trampoline.S
--- a/arch/i386/kernel/trampoline.S	2005-03-01 23:38:55 -08:00
+++ b/arch/i386/kernel/trampoline.S	2005-03-01 23:38:55 -08:00
@@ -51,8 +51,14 @@
 	movl	$0xA5A5A5A5, trampoline_data - r_base
 				# write marker for master knows we're running
 
-	lidt	boot_idt - r_base	# load idt with 0, 0
-	lgdt	boot_gdt - r_base	# load gdt with whatever is appropriate
+	/* GDT tables in non default location kernel can be beyond 16MB and
+	 * lgdt will not be able to load the address as in real mode default
+	 * operand size is 16bit. Use lgdtl instead to force operand size
+	 * to 32 bit.
+	 */
+
+	lidtl	boot_idt - r_base	# load idt with 0, 0
+	lgdtl	boot_gdt - r_base	# load gdt with whatever is appropriate
 
 	xor	%ax, %ax
 	inc	%ax		# protected mode (PE) bit
diff -Nru a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
--- a/arch/i386/kernel/traps.c	2005-03-01 23:38:53 -08:00
+++ b/arch/i386/kernel/traps.c	2005-03-01 23:38:53 -08:00
@@ -93,7 +93,7 @@
 
 static int kstack_depth_to_print = 24;
 struct notifier_block *i386die_chain;
-static spinlock_t die_notifier_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(die_notifier_lock);
 
 int register_die_notifier(struct notifier_block *nb)
 {
@@ -306,7 +306,7 @@
 	};
 	static int die_counter;
 
-	if (die.lock_owner != smp_processor_id()) {
+	if (die.lock_owner != _smp_processor_id()) {
 		console_verbose();
 		spin_lock_irq(&die.lock);
 		die.lock_owner = smp_processor_id();
@@ -551,7 +551,7 @@
 	printk("Do you have a strange power saving mode enabled?\n");
 }
 
-static spinlock_t nmi_print_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(nmi_print_lock);
 
 void die_nmi (struct pt_regs *regs, const char *msg)
 {
@@ -682,7 +682,6 @@
 {
 	unsigned int condition;
 	struct task_struct *tsk = current;
-	siginfo_t info;
 
 	__asm__ __volatile__("movl %%db6,%0" : "=r" (condition));
 
@@ -705,36 +704,29 @@
 	/* Save debug status register where ptrace can see it */
 	tsk->thread.debugreg[6] = condition;
 
-	/* Mask out spurious TF errors due to lazy TF clearing */
+	/*
+	 * Single-stepping through TF: make sure we ignore any events in
+	 * kernel space (but re-enable TF when returning to user mode).
+	 * And if the event was due to a debugger (PT_DTRACE), clear the
+	 * TF flag so that register information is correct.
+	 */
 	if (condition & DR_STEP) {
 		/*
-		 * The TF error should be masked out only if the current
-		 * process is not traced and if the TRAP flag has been set
-		 * previously by a tracing process (condition detected by
-		 * the PT_DTRACE flag); remember that the i386 TRAP flag
-		 * can be modified by the process itself in user mode,
-		 * allowing programs to debug themselves without the ptrace()
-		 * interface.
+		 * We already checked v86 mode above, so we can
+		 * check for kernel mode by just checking the CPL
+		 * of CS.
 		 */
 		if ((regs->xcs & 3) == 0)
 			goto clear_TF_reenable;
-		if ((tsk->ptrace & (PT_DTRACE|PT_PTRACED)) == PT_DTRACE)
-			goto clear_TF;
+
+		if (likely(tsk->ptrace & PT_DTRACE)) {
+			tsk->ptrace &= ~PT_DTRACE;
+			regs->eflags &= ~TF_MASK;
+		}
 	}
 
 	/* Ok, finally something we can handle */
-	tsk->thread.trap_no = 1;
-	tsk->thread.error_code = error_code;
-	info.si_signo = SIGTRAP;
-	info.si_errno = 0;
-	info.si_code = TRAP_BRKPT;
-	
-	/* If this is a kernel mode trap, save the user PC on entry to 
-	 * the kernel, that's what the debugger can make sense of.
-	 */
-	info.si_addr = ((regs->xcs & 3) == 0) ? (void __user *)tsk->thread.eip
-	                                      : (void __user *)regs->eip;
-	force_sig_info(SIGTRAP, &info, tsk);
+	send_sigtrap(tsk, regs, error_code);
 
 	/* Disable additional traps. They'll be re-enabled when
 	 * the signal is delivered.
@@ -751,7 +743,6 @@
 
 clear_TF_reenable:
 	set_tsk_thread_flag(tsk, TIF_SINGLESTEP);
-clear_TF:
 	regs->eflags &= ~TF_MASK;
 	return;
 }
@@ -920,7 +911,7 @@
 	struct task_struct *tsk = thread->task;
 
 	clts();		/* Allow maths ops (or we recurse) */
-	if (!tsk->used_math)
+	if (!tsk_used_math(tsk))
 		init_fpu(tsk);
 	restore_fpu(tsk);
 	thread->status |= TS_USEDFPU;	/* So we fnsave on switch_to() */
@@ -1004,9 +995,11 @@
 void __init trap_init(void)
 {
 #ifdef CONFIG_EISA
-	if (isa_readl(0x0FFFD9) == 'E'+('I'<<8)+('S'<<16)+('A'<<24)) {
+	void __iomem *p = ioremap(0x0FFFD9, 4);
+	if (readl(p) == 'E'+('I'<<8)+('S'<<16)+('A'<<24)) {
 		EISA_bus = 1;
 	}
+	iounmap(p);
 #endif
 
 #ifdef CONFIG_X86_LOCAL_APIC
diff -Nru a/arch/i386/kernel/vm86.c b/arch/i386/kernel/vm86.c
--- a/arch/i386/kernel/vm86.c	2005-03-01 23:38:52 -08:00
+++ b/arch/i386/kernel/vm86.c	2005-03-01 23:38:52 -08:00
@@ -137,6 +137,7 @@
 static void mark_screen_rdonly(struct task_struct * tsk)
 {
 	pgd_t *pgd;
+	pud_t *pud;
 	pmd_t *pmd;
 	pte_t *pte, *mapped;
 	int i;
@@ -151,7 +152,15 @@
 		pgd_clear(pgd);
 		goto out;
 	}
-	pmd = pmd_offset(pgd, 0xA0000);
+	pud = pud_offset(pgd, 0xA0000);
+	if (pud_none(*pud))
+		goto out;
+	if (pud_bad(*pud)) {
+		pud_ERROR(*pud);
+		pud_clear(pud);
+		goto out;
+	}
+	pmd = pmd_offset(pud, 0xA0000);
 	if (pmd_none(*pmd))
 		goto out;
 	if (pmd_bad(*pmd)) {
@@ -704,7 +713,7 @@
 	int sig;
 } vm86_irqs[16];
 
-static spinlock_t irqbits_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(irqbits_lock);
 static int irqbits;
 
 #define ALLOWED_SIGS ( 1 /* 0 = don't send a signal */ \
diff -Nru a/arch/i386/lib/delay.c b/arch/i386/lib/delay.c
--- a/arch/i386/lib/delay.c	2005-03-01 23:39:10 -08:00
+++ b/arch/i386/lib/delay.c	2005-03-01 23:39:10 -08:00
@@ -34,7 +34,7 @@
 	xloops *= 4;
 	__asm__("mull %0"
 		:"=d" (xloops), "=&a" (d0)
-		:"1" (xloops),"0" (current_cpu_data.loops_per_jiffy * (HZ/4)));
+		:"1" (xloops),"0" (cpu_data[_smp_processor_id()].loops_per_jiffy * (HZ/4)));
         __delay(++xloops);
 }
 
diff -Nru a/arch/i386/lib/usercopy.c b/arch/i386/lib/usercopy.c
--- a/arch/i386/lib/usercopy.c	2005-03-01 23:38:44 -08:00
+++ b/arch/i386/lib/usercopy.c	2005-03-01 23:38:44 -08:00
@@ -514,6 +514,7 @@
 
 unsigned long __copy_to_user_ll(void __user *to, const void *from, unsigned long n)
 {
+	BUG_ON((long) n < 0);
 #ifndef CONFIG_X86_WP_WORKS_OK
 	if (unlikely(boot_cpu_data.wp_works_ok == 0) &&
 			((unsigned long )to) < TASK_SIZE) {
@@ -573,6 +574,7 @@
 unsigned long
 __copy_from_user_ll(void *to, const void __user *from, unsigned long n)
 {
+	BUG_ON((long)n < 0);
 	if (movsl_is_ok(to, from, n))
 		__copy_user_zeroing(to, from, n);
 	else
@@ -597,6 +599,7 @@
 copy_to_user(void __user *to, const void *from, unsigned long n)
 {
 	might_sleep();
+	BUG_ON((long) n < 0);
 	if (access_ok(VERIFY_WRITE, to, n))
 		n = __copy_to_user(to, from, n);
 	return n;
@@ -623,6 +626,7 @@
 copy_from_user(void *to, const void __user *from, unsigned long n)
 {
 	might_sleep();
+	BUG_ON((long) n < 0);
 	if (access_ok(VERIFY_READ, from, n))
 		n = __copy_from_user(to, from, n);
 	else
diff -Nru a/arch/i386/mach-default/topology.c b/arch/i386/mach-default/topology.c
--- a/arch/i386/mach-default/topology.c	2005-03-01 23:39:09 -08:00
+++ b/arch/i386/mach-default/topology.c	2005-03-01 23:39:09 -08:00
@@ -32,6 +32,37 @@
 
 struct i386_cpu cpu_devices[NR_CPUS];
 
+int arch_register_cpu(int num){
+	struct node *parent = NULL;
+	
+#ifdef CONFIG_NUMA
+	int node = cpu_to_node(num);
+	if (node_online(node))
+		parent = &node_devices[node].node;
+#endif /* CONFIG_NUMA */
+
+	return register_cpu(&cpu_devices[num].cpu, num, parent);
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+
+void arch_unregister_cpu(int num) {
+	struct node *parent = NULL;
+
+#ifdef CONFIG_NUMA
+	int node = cpu_to_node(num);
+	if (node_online(node))
+		parent = &node_devices[node].node;
+#endif /* CONFIG_NUMA */
+
+	return unregister_cpu(&cpu_devices[num].cpu, parent);
+}
+EXPORT_SYMBOL(arch_register_cpu);
+EXPORT_SYMBOL(arch_unregister_cpu);
+#endif /*CONFIG_HOTPLUG_CPU*/
+
+
+
 #ifdef CONFIG_NUMA
 #include <linux/mmzone.h>
 #include <asm/node.h>
diff -Nru a/arch/i386/mach-visws/reboot.c b/arch/i386/mach-visws/reboot.c
--- a/arch/i386/mach-visws/reboot.c	2005-03-01 23:39:09 -08:00
+++ b/arch/i386/mach-visws/reboot.c	2005-03-01 23:39:09 -08:00
@@ -8,9 +8,6 @@
 
 void (*pm_power_off)(void);
 
-int reboot_thru_bios;
-int reboot_smp;
-
 void machine_restart(char * __unused)
 {
 #ifdef CONFIG_SMP
diff -Nru a/arch/i386/mach-visws/visws_apic.c b/arch/i386/mach-visws/visws_apic.c
--- a/arch/i386/mach-visws/visws_apic.c	2005-03-01 23:38:52 -08:00
+++ b/arch/i386/mach-visws/visws_apic.c	2005-03-01 23:38:52 -08:00
@@ -31,7 +31,7 @@
 #include "irq_vectors.h"
 
 
-static spinlock_t cobalt_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(cobalt_lock);
 
 /*
  * Set the given Cobalt APIC Redirection Table entry to point
diff -Nru a/arch/i386/mach-voyager/voyager_basic.c b/arch/i386/mach-voyager/voyager_basic.c
--- a/arch/i386/mach-voyager/voyager_basic.c	2005-03-01 23:38:54 -08:00
+++ b/arch/i386/mach-voyager/voyager_basic.c	2005-03-01 23:38:54 -08:00
@@ -36,8 +36,6 @@
  */
 void (*pm_power_off)(void);
 
-int reboot_thru_bios;
-
 int voyager_level = 0;
 
 struct voyager_SUS *voyager_SUS = NULL;
diff -Nru a/arch/i386/mach-voyager/voyager_smp.c b/arch/i386/mach-voyager/voyager_smp.c
--- a/arch/i386/mach-voyager/voyager_smp.c	2005-03-01 23:38:55 -08:00
+++ b/arch/i386/mach-voyager/voyager_smp.c	2005-03-01 23:38:55 -08:00
@@ -27,13 +27,10 @@
 #include <asm/mtrr.h>
 #include <asm/pgalloc.h>
 #include <asm/tlbflush.h>
-#include <asm/desc.h>
 #include <asm/arch_hooks.h>
 
 #include <linux/irq.h>
 
-int reboot_smp = 0;
-
 /* TLB state -- visible externally, indexed physically */
 DEFINE_PER_CPU(struct tlb_state, cpu_tlbstate) ____cacheline_aligned = { &init_mm, 0 };
 
@@ -254,7 +251,7 @@
 static __u16 vic_irq_enable_mask[NR_CPUS] __cacheline_aligned = { 0 };
 
 /* Lock for enable/disable of VIC interrupts */
-static spinlock_t vic_irq_lock __cacheline_aligned = SPIN_LOCK_UNLOCKED;
+static  __cacheline_aligned DEFINE_SPINLOCK(vic_irq_lock);
 
 /* The boot processor is correctly set up in PC mode when it 
  * comes up, but the secondaries need their master/slave 8259
@@ -457,13 +454,12 @@
 }
 
 /* Routine initially called when a non-boot CPU is brought online */
-int __init
+static void __init
 start_secondary(void *unused)
 {
 	__u8 cpuid = hard_smp_processor_id();
 	/* external functions not defined in the headers */
 	extern void calibrate_delay(void);
-	extern int cpu_idle(void);
 
 	cpu_init();
 
@@ -520,7 +516,7 @@
 
 	cpu_set(cpuid, cpu_online_map);
 	wmb();
-	return cpu_idle();
+	cpu_idle();
 }
 
 
@@ -799,7 +795,7 @@
 smp_vic_cmn_interrupt(struct pt_regs *regs)
 {
 	static __u8 in_cmn_int = 0;
-	static spinlock_t cmn_int_lock = SPIN_LOCK_UNLOCKED;
+	static DEFINE_SPINLOCK(cmn_int_lock);
 
 	/* common ints are broadcast, so make sure we only do this once */
 	_raw_spin_lock(&cmn_int_lock);
@@ -832,7 +828,7 @@
 
 static struct mm_struct * flush_mm;
 static unsigned long flush_va;
-static spinlock_t tlbstate_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(tlbstate_lock);
 #define FLUSH_ALL	0xffffffff
 
 /*
@@ -1022,7 +1018,7 @@
 	       __asm__("hlt");
 }
 
-static spinlock_t call_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(call_lock);
 
 struct call_data_struct {
 	void (*func) (void *info);
diff -Nru a/arch/i386/math-emu/fpu_entry.c b/arch/i386/math-emu/fpu_entry.c
--- a/arch/i386/math-emu/fpu_entry.c	2005-03-01 23:39:09 -08:00
+++ b/arch/i386/math-emu/fpu_entry.c	2005-03-01 23:39:09 -08:00
@@ -155,10 +155,10 @@
   RE_ENTRANT_CHECK_ON;
 #endif /* RE_ENTRANT_CHECKING */
 
-  if (!current->used_math)
+  if (!used_math())
     {
       finit();
-      current->used_math = 1;
+      set_used_math();
     }
 
   SETUP_DATA_AREA(arg);
diff -Nru a/arch/i386/mm/discontig.c b/arch/i386/mm/discontig.c
--- a/arch/i386/mm/discontig.c	2005-03-01 23:38:58 -08:00
+++ b/arch/i386/mm/discontig.c	2005-03-01 23:38:58 -08:00
@@ -41,7 +41,7 @@
  * numa interface - we expect the numa architecture specfic code to have
  *                  populated the following initialisation.
  *
- * 1) numnodes         - the total number of nodes configured in the system
+ * 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
  * 3) node_end_pfn     - the ending page fram number for a node
@@ -93,12 +93,12 @@
 
 	/* Run the memory configuration and find the top of memory. */
 	find_max_pfn();
-	node_start_pfn[0]  = 0;
-	node_end_pfn[0]	  = max_pfn;
+	node_start_pfn[0] = 0;
+	node_end_pfn[0] = max_pfn;
 
         /* Indicate there is one node available. */
+	nodes_clear(node_online_map);
 	node_set_online(0);
-	numnodes = 1;
 	return 1;
 }
 
@@ -183,7 +183,9 @@
 	unsigned long pfn;
 	int node;
 
-	for (node = 1; node < numnodes; ++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, 
@@ -198,7 +200,9 @@
 	int nid;
 	unsigned long size, reserve_pages = 0;
 
-	for (nid = 1; nid < numnodes; nid++) {
+	for_each_online_node(nid) {
+		if (nid == 0)
+			continue;
 		/* calculate the size of the mem_map needed in bytes */
 		size = (node_end_pfn[nid] - node_start_pfn[nid] + 1) 
 			* sizeof(struct page) + sizeof(pg_data_t);
@@ -248,7 +252,7 @@
 	get_memcfg_numa();
 
 	/* Fill in the physnode_map */
-	for (nid = 0; nid < numnodes; nid++) {
+	for_each_online_node(nid) {
 		printk("Node: %d, start_pfn: %ld, end_pfn: %ld\n",
 				nid, node_start_pfn[nid], node_end_pfn[nid]);
 		printk("  Setting physnode_map array to node %d for pfns:\n  ",
@@ -285,7 +289,7 @@
 
 	printk("Low memory ends at vaddr %08lx\n",
 			(ulong) pfn_to_kaddr(max_low_pfn));
-	for (nid = 0; nid < numnodes; nid++) {
+	for_each_online_node(nid) {
 		node_remap_start_vaddr[nid] = pfn_to_kaddr(
 			(highstart_pfn + reserve_pages) - node_remap_offset[nid]);
 		allocate_pgdat(nid);
@@ -297,7 +301,7 @@
 	printk("High memory starts at vaddr %08lx\n",
 			(ulong) pfn_to_kaddr(highstart_pfn));
 	vmalloc_earlyreserve = reserve_pages * PAGE_SIZE;
-	for (nid = 0; nid < numnodes; nid++)
+	for_each_online_node(nid)
 		find_max_pfn_node(nid);
 
 	NODE_DATA(0)->bdata = &node0_bdata;
@@ -375,14 +379,16 @@
 	 * Clobber node 0's links and NULL out pgdat_list before starting.
 	 */
 	pgdat_list = NULL;
-	for (nid = numnodes - 1; nid >= 0; nid--) {       
+	for (nid = MAX_NUMNODES - 1; nid >= 0; nid--) {
+		if (!node_online(nid))
+			continue;
 		if (nid)
 			memset(NODE_DATA(nid), 0, sizeof(pg_data_t));
 		NODE_DATA(nid)->pgdat_next = pgdat_list;
 		pgdat_list = NODE_DATA(nid);
 	}
 
-	for (nid = 0; nid < numnodes; nid++) {
+	for_each_online_node(nid) {
 		unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0};
 		unsigned long *zholes_size;
 		unsigned int max_dma;
@@ -464,11 +470,6 @@
 void __init set_max_mapnr_init(void)
 {
 #ifdef CONFIG_HIGHMEM
-	struct zone *high0 = &NODE_DATA(0)->node_zones[ZONE_HIGHMEM];
-	if (high0->spanned_pages > 0)
-	      	highmem_start_page = high0->zone_mem_map;
-	else
-		highmem_start_page = pfn_to_page(max_low_pfn - 1) + 1;
 	num_physpages = highend_pfn;
 #else
 	num_physpages = max_low_pfn;
diff -Nru a/arch/i386/mm/fault.c b/arch/i386/mm/fault.c
--- a/arch/i386/mm/fault.c	2005-03-01 23:38:44 -08:00
+++ b/arch/i386/mm/fault.c	2005-03-01 23:38:44 -08:00
@@ -112,9 +112,7 @@
 	}
 
 	/* Decode the code segment base from the descriptor */
-	base =   (desc[0] >> 16) |
-		((desc[1] & 0xff) << 16) |
-		 (desc[1] & 0xff000000);
+	base = get_desc_base((unsigned long *)desc);
 
 	if (seg & (1<<2)) { 
 		up(&current->mm->context.sem);
@@ -518,6 +516,7 @@
 		int index = pgd_index(address);
 		unsigned long pgd_paddr;
 		pgd_t *pgd, *pgd_k;
+		pud_t *pud, *pud_k;
 		pmd_t *pmd, *pmd_k;
 		pte_t *pte_k;
 
@@ -530,11 +529,17 @@
 
 		/*
 		 * set_pgd(pgd, *pgd_k); here would be useless on PAE
-		 * and redundant with the set_pmd() on non-PAE.
+		 * and redundant with the set_pmd() on non-PAE. As would
+		 * set_pud.
 		 */
 
-		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 no_context;
 		set_pmd(pmd, *pmd_k);
diff -Nru a/arch/i386/mm/highmem.c b/arch/i386/mm/highmem.c
--- a/arch/i386/mm/highmem.c	2005-03-01 23:38:58 -08:00
+++ b/arch/i386/mm/highmem.c	2005-03-01 23:38:58 -08:00
@@ -3,7 +3,7 @@
 void *kmap(struct page *page)
 {
 	might_sleep();
-	if (page < highmem_start_page)
+	if (!PageHighMem(page))
 		return page_address(page);
 	return kmap_high(page);
 }
@@ -12,7 +12,7 @@
 {
 	if (in_interrupt())
 		BUG();
-	if (page < highmem_start_page)
+	if (!PageHighMem(page))
 		return;
 	kunmap_high(page);
 }
@@ -32,7 +32,7 @@
 
 	/* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */
 	inc_preempt_count();
-	if (page < highmem_start_page)
+	if (!PageHighMem(page))
 		return page_address(page);
 
 	idx = type + KM_TYPE_NR*smp_processor_id();
diff -Nru a/arch/i386/mm/hugetlbpage.c b/arch/i386/mm/hugetlbpage.c
--- a/arch/i386/mm/hugetlbpage.c	2005-03-01 23:39:16 -08:00
+++ b/arch/i386/mm/hugetlbpage.c	2005-03-01 23:39:16 -08:00
@@ -21,20 +21,24 @@
 static pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr)
 {
 	pgd_t *pgd;
+	pud_t *pud;
 	pmd_t *pmd = NULL;
 
 	pgd = pgd_offset(mm, addr);
-	pmd = pmd_alloc(mm, pgd, addr);
+	pud = pud_alloc(mm, pgd, addr);
+	pmd = pmd_alloc(mm, pud, addr);
 	return (pte_t *) pmd;
 }
 
 static pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
 {
 	pgd_t *pgd;
+	pud_t *pud;
 	pmd_t *pmd = NULL;
 
 	pgd = pgd_offset(mm, addr);
-	pmd = pmd_offset(pgd, addr);
+	pud = pud_offset(pgd, addr);
+	pmd = pmd_offset(pud, addr);
 	return (pte_t *) pmd;
 }
 
diff -Nru a/arch/i386/mm/init.c b/arch/i386/mm/init.c
--- a/arch/i386/mm/init.c	2005-03-01 23:39:08 -08:00
+++ b/arch/i386/mm/init.c	2005-03-01 23:39:08 -08:00
@@ -54,15 +54,18 @@
  */
 static pmd_t * __init one_md_table_init(pgd_t *pgd)
 {
+	pud_t *pud;
 	pmd_t *pmd_table;
 		
 #ifdef CONFIG_X86_PAE
 	pmd_table = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
 	set_pgd(pgd, __pgd(__pa(pmd_table) | _PAGE_PRESENT));
-	if (pmd_table != pmd_offset(pgd, 0)) 
+	pud = pud_offset(pgd, 0);
+	if (pmd_table != pmd_offset(pud, 0)) 
 		BUG();
 #else
-	pmd_table = pmd_offset(pgd, 0);
+	pud = pud_offset(pgd, 0);
+	pmd_table = pmd_offset(pud, 0);
 #endif
 
 	return pmd_table;
@@ -100,6 +103,7 @@
 static void __init page_table_range_init (unsigned long start, unsigned long end, pgd_t *pgd_base)
 {
 	pgd_t *pgd;
+	pud_t *pud;
 	pmd_t *pmd;
 	int pgd_idx, pmd_idx;
 	unsigned long vaddr;
@@ -112,8 +116,8 @@
 	for ( ; (pgd_idx < PTRS_PER_PGD) && (vaddr != end); pgd++, pgd_idx++) {
 		if (pgd_none(*pgd)) 
 			one_md_table_init(pgd);
-
-		pmd = pmd_offset(pgd, vaddr);
+		pud = pud_offset(pgd, vaddr);
+		pmd = pmd_offset(pud, vaddr);
 		for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end); pmd++, pmd_idx++) {
 			if (pmd_none(*pmd)) 
 				one_page_table_init(pmd);
@@ -126,7 +130,7 @@
 
 static inline int is_kernel_text(unsigned long addr)
 {
-	if (addr >= (unsigned long)_stext && addr <= (unsigned long)__init_end)
+	if (addr >= PAGE_OFFSET && addr <= (unsigned long)__init_end)
 		return 1;
 	return 0;
 }
@@ -233,7 +237,7 @@
 EXPORT_SYMBOL(kmap_pte);
 
 #define kmap_get_fixmap_pte(vaddr)					\
-	pte_offset_kernel(pmd_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr))
+	pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), vaddr), (vaddr)), (vaddr))
 
 void __init kmap_init(void)
 {
@@ -249,6 +253,7 @@
 void __init permanent_kmaps_init(pgd_t *pgd_base)
 {
 	pgd_t *pgd;
+	pud_t *pud;
 	pmd_t *pmd;
 	pte_t *pte;
 	unsigned long vaddr;
@@ -257,7 +262,8 @@
 	page_table_range_init(vaddr, vaddr + PAGE_SIZE*LAST_PKMAP, pgd_base);
 
 	pgd = swapper_pg_dir + pgd_index(vaddr);
-	pmd = pmd_offset(pgd, vaddr);
+	pud = pud_offset(pgd, vaddr);
+	pmd = pmd_offset(pud, vaddr);
 	pte = pte_offset_kernel(pmd, vaddr);
 	pkmap_page_table = pte;	
 }
@@ -424,7 +430,7 @@
  * on      Enable
  * off     Disable
  */
-static int __init noexec_setup(char *str)
+void __init noexec_setup(const char *str)
 {
 	if (!strncmp(str, "on",2) && cpu_has_nx) {
 		__supported_pte_mask |= _PAGE_NX;
@@ -433,11 +439,8 @@
 		disable_nx = 1;
 		__supported_pte_mask &= ~_PAGE_NX;
 	}
-	return 1;
 }
 
-__setup("noexec=", noexec_setup);
-
 int nx_enabled = 0;
 #ifdef CONFIG_X86_PAE
 
@@ -549,7 +552,6 @@
 static void __init set_max_mapnr_init(void)
 {
 #ifdef CONFIG_HIGHMEM
-	highmem_start_page = pfn_to_page(highstart_pfn);
 	max_mapnr = num_physpages = highend_pfn;
 #else
 	max_mapnr = num_physpages = max_low_pfn;
diff -Nru a/arch/i386/mm/ioremap.c b/arch/i386/mm/ioremap.c
--- a/arch/i386/mm/ioremap.c	2005-03-01 23:38:54 -08:00
+++ b/arch/i386/mm/ioremap.c	2005-03-01 23:38:54 -08:00
@@ -80,9 +80,14 @@
 		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,
@@ -130,7 +135,7 @@
 	/*
 	 * Don't allow anybody to remap normal RAM that we're using..
 	 */
-	if (phys_addr < virt_to_phys(high_memory)) {
+	if (phys_addr <= virt_to_phys(high_memory - 1)) {
 		char *t_addr, *t_end;
 		struct page *page;
 
@@ -152,7 +157,7 @@
 	/*
 	 * Ok, go for it..
 	 */
-	area = get_vm_area(size, VM_IOREMAP);
+	area = get_vm_area(size, VM_IOREMAP | (flags << 20));
 	if (!area)
 		return NULL;
 	area->phys_addr = phys_addr;
@@ -197,7 +202,7 @@
 	/* Guaranteed to be > phys_addr, as per __ioremap() */
 	last_addr = phys_addr + size - 1;
 
-	if (last_addr < virt_to_phys(high_memory)) { 
+	if (last_addr < virt_to_phys(high_memory) - 1) {
 		struct page *ppage = virt_to_page(__va(phys_addr));		
 		unsigned long npages;
 
@@ -230,11 +235,12 @@
 	if (!p) { 
 		printk("__iounmap: bad address %p\n", addr);
 		return;
-	} 
+	}
 
-	if (p->flags && p->phys_addr < virt_to_phys(high_memory)) { 
+	if ((p->flags >> 20) && p->phys_addr < virt_to_phys(high_memory) - 1) {
+		/* p->size includes the guard page, but cpa doesn't like that */
 		change_page_attr(virt_to_page(__va(p->phys_addr)),
-				 p->size >> PAGE_SHIFT,
+				 (p->size - PAGE_SIZE) >> PAGE_SHIFT,
 				 PAGE_KERNEL); 				 
 		global_flush_tlb();
 	} 
diff -Nru a/arch/i386/mm/pageattr.c b/arch/i386/mm/pageattr.c
--- a/arch/i386/mm/pageattr.c	2005-03-01 23:38:56 -08:00
+++ b/arch/i386/mm/pageattr.c	2005-03-01 23:38:56 -08:00
@@ -13,17 +13,21 @@
 #include <asm/processor.h>
 #include <asm/tlbflush.h>
 
-static spinlock_t cpa_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(cpa_lock);
 static struct list_head df_list = LIST_HEAD_INIT(df_list);
 
 
 pte_t *lookup_address(unsigned long address) 
 { 
-	pgd_t *pgd = pgd_offset_k(address); 
+	pgd_t *pgd = pgd_offset_k(address);
+	pud_t *pud;
 	pmd_t *pmd;
 	if (pgd_none(*pgd))
 		return NULL;
-	pmd = pmd_offset(pgd, address); 	       
+	pud = pud_offset(pgd, address);
+	if (pud_none(*pud))
+		return NULL;
+	pmd = pmd_offset(pud, address);
 	if (pmd_none(*pmd))
 		return NULL;
 	if (pmd_large(*pmd))
@@ -77,9 +81,11 @@
 	spin_lock_irqsave(&pgd_lock, flags);
 	for (page = pgd_list; page; page = (struct page *)page->index) {
 		pgd_t *pgd;
+		pud_t *pud;
 		pmd_t *pmd;
 		pgd = (pgd_t *)page_address(page) + pgd_index(address);
-		pmd = pmd_offset(pgd, address);
+		pud = pud_offset(pgd, address);
+		pmd = pmd_offset(pud, address);
 		set_pte_atomic((pte_t *)pmd, pte);
 	}
 	spin_unlock_irqrestore(&pgd_lock, flags);
@@ -92,7 +98,7 @@
 static inline void revert_page(struct page *kpte_page, unsigned long address)
 {
 	pte_t *linear = (pte_t *) 
-		pmd_offset(pgd_offset(&init_mm, address), address);
+		pmd_offset(pud_offset(pgd_offset_k(address), address), address);
 	set_pmd_pte(linear,  address,
 		    pfn_pte((__pa(address) & LARGE_PAGE_MASK) >> PAGE_SHIFT,
 			    PAGE_KERNEL_LARGE));
@@ -105,10 +111,7 @@
 	unsigned long address;
 	struct page *kpte_page;
 
-#ifdef CONFIG_HIGHMEM
-	if (page >= highmem_start_page) 
-		BUG(); 
-#endif
+	BUG_ON(PageHighMem(page));
 	address = (unsigned long)page_address(page);
 
 	kpte = lookup_address(address);
@@ -117,27 +120,35 @@
 	kpte_page = virt_to_page(kpte);
 	if (pgprot_val(prot) != pgprot_val(PAGE_KERNEL)) { 
 		if ((pte_val(*kpte) & _PAGE_PSE) == 0) { 
-			pte_t old = *kpte;
-			pte_t standard = mk_pte(page, PAGE_KERNEL); 
 			set_pte_atomic(kpte, mk_pte(page, prot)); 
-			if (pte_same(old,standard))
-				get_page(kpte_page);
 		} else {
 			struct page *split = split_large_page(address, prot); 
 			if (!split)
 				return -ENOMEM;
-			get_page(kpte_page);
 			set_pmd_pte(kpte,address,mk_pte(split, PAGE_KERNEL));
+			kpte_page = split;
 		}	
+		get_page(kpte_page);
 	} else if ((pte_val(*kpte) & _PAGE_PSE) == 0) { 
 		set_pte_atomic(kpte, mk_pte(page, PAGE_KERNEL));
 		__put_page(kpte_page);
-	}
+	} else
+		BUG();
 
-	if (cpu_has_pse && (page_count(kpte_page) == 1)) {
-		list_add(&kpte_page->lru, &df_list);
-		revert_page(kpte_page, address);
-	} 
+	/*
+	 * If the pte was reserved, it means it was created at boot
+	 * time (not via split_large_page) and in turn we must not
+	 * replace it with a largepage.
+	 */
+	if (!PageReserved(kpte_page)) {
+		/* memleak and potential failed 2M page regeneration */
+		BUG_ON(!page_count(kpte_page));
+
+		if (cpu_has_pse && (page_count(kpte_page) == 1)) {
+			list_add(&kpte_page->lru, &df_list);
+			revert_page(kpte_page, address);
+		}
+	}
 	return 0;
 } 
 
diff -Nru a/arch/i386/mm/pgtable.c b/arch/i386/mm/pgtable.c
--- a/arch/i386/mm/pgtable.c	2005-03-01 23:39:18 -08:00
+++ b/arch/i386/mm/pgtable.c	2005-03-01 23:39:18 -08:00
@@ -62,6 +62,7 @@
 static void set_pte_pfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags)
 {
 	pgd_t *pgd;
+	pud_t *pud;
 	pmd_t *pmd;
 	pte_t *pte;
 
@@ -70,7 +71,12 @@
 		BUG();
 		return;
 	}
-	pmd = pmd_offset(pgd, vaddr);
+	pud = pud_offset(pgd, vaddr);
+	if (pud_none(*pud)) {
+		BUG();
+		return;
+	}
+	pmd = pmd_offset(pud, vaddr);
 	if (pmd_none(*pmd)) {
 		BUG();
 		return;
@@ -95,6 +101,7 @@
 void set_pmd_pfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags)
 {
 	pgd_t *pgd;
+	pud_t *pud;
 	pmd_t *pmd;
 
 	if (vaddr & (PMD_SIZE-1)) {		/* vaddr is misaligned */
@@ -110,7 +117,8 @@
 		printk ("set_pmd_pfn: pgd_none\n");
 		return; /* BUG(); */
 	}
-	pmd = pmd_offset(pgd, vaddr);
+	pud = pud_offset(pgd, vaddr);
+	pmd = pmd_offset(pud, vaddr);
 	set_pmd(pmd, pfn_pmd(pfn, flags));
 	/*
 	 * It's enough to flush this one mapping.
@@ -132,10 +140,7 @@
 
 pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
 {
-	pte_t *pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT);
-	if (pte)
-		clear_page(pte);
-	return pte;
+	return (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO);
 }
 
 struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address)
@@ -143,12 +148,10 @@
 	struct page *pte;
 
 #ifdef CONFIG_HIGHPTE
-	pte = alloc_pages(GFP_KERNEL|__GFP_HIGHMEM|__GFP_REPEAT, 0);
+	pte = alloc_pages(GFP_KERNEL|__GFP_HIGHMEM|__GFP_REPEAT|__GFP_ZERO, 0);
 #else
-	pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT, 0);
+	pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0);
 #endif
-	if (pte)
-		clear_highpage(pte);
 	return pte;
 }
 
@@ -169,7 +172,7 @@
  * recommendations and having no core impact whatsoever.
  * -- wli
  */
-spinlock_t pgd_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(pgd_lock);
 struct page *pgd_list;
 
 static inline void pgd_list_add(pgd_t *pgd)
@@ -252,6 +255,6 @@
 	if (PTRS_PER_PMD > 1)
 		for (i = 0; i < USER_PTRS_PER_PGD; ++i)
 			kmem_cache_free(pmd_cache, (void *)__va(pgd_val(pgd[i])-1));
-	/* in the non-PAE case, clear_page_tables() clears user pgd entries */
+	/* in the non-PAE case, clear_page_range() clears user pgd entries */
 	kmem_cache_free(pgd_cache, pgd);
 }
diff -Nru a/arch/i386/oprofile/Makefile b/arch/i386/oprofile/Makefile
--- a/arch/i386/oprofile/Makefile	2005-03-01 23:39:09 -08:00
+++ b/arch/i386/oprofile/Makefile	2005-03-01 23:39:09 -08:00
@@ -6,7 +6,7 @@
 		oprofilefs.o oprofile_stats.o  \
 		timer_int.o )
 
-oprofile-y				:= $(DRIVER_OBJS) init.o
+oprofile-y				:= $(DRIVER_OBJS) init.o backtrace.o
 oprofile-$(CONFIG_X86_LOCAL_APIC) 	+= nmi_int.o op_model_athlon.o \
 					   op_model_ppro.o op_model_p4.o
 oprofile-$(CONFIG_X86_IO_APIC)		+= nmi_timer_int.o
diff -Nru a/arch/i386/oprofile/backtrace.c b/arch/i386/oprofile/backtrace.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/i386/oprofile/backtrace.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,124 @@
+/**
+ * @file backtrace.c
+ *
+ * @remark Copyright 2002 OProfile authors
+ * @remark Read the file COPYING
+ *
+ * @author John Levon
+ * @author David Smith
+ */
+
+#include <linux/oprofile.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <asm/ptrace.h>
+
+struct frame_head {
+	struct frame_head * ebp;
+	unsigned long ret;
+} __attribute__((packed));
+
+
+static struct frame_head *
+dump_backtrace(struct frame_head * head)
+{
+	oprofile_add_trace(head->ret);
+
+	/* frame pointers should strictly progress back up the stack
+	 * (towards higher addresses) */
+	if (head >= head->ebp)
+		return 0;
+
+	return head->ebp;
+}
+
+
+#ifdef CONFIG_X86_4G
+/* With a 4G kernel/user split, user pages are not directly
+ * accessible from the kernel, so don't try
+ */
+static int pages_present(struct frame_head * head)
+{
+	return 0;
+}
+#else
+/* check that the page(s) containing the frame head are present */
+static int pages_present(struct frame_head * head)
+{
+	struct mm_struct * mm = current->mm;
+
+	/* FIXME: only necessary once per page */
+	if (!check_user_page_readable(mm, (unsigned long)head))
+		return 0;
+
+	return check_user_page_readable(mm, (unsigned long)(head + 1));
+}
+#endif /* CONFIG_X86_4G */
+
+
+/*
+ * |             | /\ Higher addresses
+ * |             |
+ * --------------- stack base (address of current_thread_info)
+ * | thread info |
+ * .             .
+ * |    stack    |
+ * --------------- saved regs->ebp value if valid (frame_head address)
+ * .             .
+ * --------------- struct pt_regs stored on stack (struct pt_regs *)
+ * |             |
+ * .             .
+ * |             |
+ * --------------- %esp
+ * |             |
+ * |             | \/ Lower addresses
+ *
+ * Thus, &pt_regs <-> stack base restricts the valid(ish) ebp values
+ */
+#ifdef CONFIG_FRAME_POINTER
+static int valid_kernel_stack(struct frame_head * head, struct pt_regs * regs)
+{
+	unsigned long headaddr = (unsigned long)head;
+	unsigned long stack = (unsigned long)regs;
+	unsigned long stack_base = (stack & ~(THREAD_SIZE - 1)) + THREAD_SIZE;
+
+	return headaddr > stack && headaddr < stack_base;
+}
+#else
+/* without fp, it's just junk */
+static int valid_kernel_stack(struct frame_head * head, struct pt_regs * regs)
+{
+	return 0;
+}
+#endif
+
+
+void
+x86_backtrace(struct pt_regs * const regs, unsigned int depth)
+{
+	struct frame_head *head;
+
+#ifdef CONFIG_X86_64
+	head = (struct frame_head *)regs->rbp;
+#else
+	head = (struct frame_head *)regs->ebp;
+#endif
+
+	if (!user_mode(regs)) {
+		while (depth-- && valid_kernel_stack(head, regs))
+			head = dump_backtrace(head);
+		return;
+	}
+
+#ifdef CONFIG_SMP
+	if (!spin_trylock(&current->mm->page_table_lock))
+		return;
+#endif
+
+	while (depth-- && head && pages_present(head))
+		head = dump_backtrace(head);
+
+#ifdef CONFIG_SMP
+	spin_unlock(&current->mm->page_table_lock);
+#endif
+}
diff -Nru a/arch/i386/oprofile/init.c b/arch/i386/oprofile/init.c
--- a/arch/i386/oprofile/init.c	2005-03-01 23:38:58 -08:00
+++ b/arch/i386/oprofile/init.c	2005-03-01 23:38:58 -08:00
@@ -15,21 +15,27 @@
  * with the NMI mode driver.
  */
  
-extern int nmi_init(struct oprofile_operations ** ops);
-extern int nmi_timer_init(struct oprofile_operations **ops);
+extern int nmi_init(struct oprofile_operations * ops);
+extern int nmi_timer_init(struct oprofile_operations * ops);
 extern void nmi_exit(void);
+extern void x86_backtrace(struct pt_regs * const regs, unsigned int depth);
 
-int __init oprofile_arch_init(struct oprofile_operations ** ops)
+
+int __init oprofile_arch_init(struct oprofile_operations * ops)
 {
-	int ret = -ENODEV;
+	int ret;
+
+	ret = -ENODEV;
+
 #ifdef CONFIG_X86_LOCAL_APIC
 	ret = nmi_init(ops);
 #endif
-
 #ifdef CONFIG_X86_IO_APIC
 	if (ret < 0)
 		ret = nmi_timer_init(ops);
 #endif
+	ops->backtrace = x86_backtrace;
+
 	return ret;
 }
 
diff -Nru a/arch/i386/oprofile/nmi_int.c b/arch/i386/oprofile/nmi_int.c
--- a/arch/i386/oprofile/nmi_int.c	2005-03-01 23:39:16 -08:00
+++ b/arch/i386/oprofile/nmi_int.c	2005-03-01 23:39:16 -08:00
@@ -70,7 +70,7 @@
 }
 
 
-static void __exit exit_driverfs(void)
+static void exit_driverfs(void)
 {
 	sysdev_unregister(&device_oprofile);
 	sysdev_class_unregister(&oprofile_sysclass);
@@ -84,7 +84,7 @@
 
 static int nmi_callback(struct pt_regs * regs, int cpu)
 {
-	return model->check_ctrs(cpu, &cpu_msrs[cpu], regs);
+	return model->check_ctrs(regs, &cpu_msrs[cpu]);
 }
  
  
@@ -300,35 +300,26 @@
 }
  
  
-struct oprofile_operations nmi_ops = {
-	.create_files 	= nmi_create_files,
-	.setup 		= nmi_setup,
-	.shutdown	= nmi_shutdown,
-	.start		= nmi_start,
-	.stop		= nmi_stop
-};
- 
-
-static int __init p4_init(void)
+static int __init p4_init(char ** cpu_type)
 {
-	__u8 cpu_model = current_cpu_data.x86_model;
+	__u8 cpu_model = boot_cpu_data.x86_model;
 
-	if (cpu_model > 3)
+	if (cpu_model > 4)
 		return 0;
 
 #ifndef CONFIG_SMP
-	nmi_ops.cpu_type = "i386/p4";
+	*cpu_type = "i386/p4";
 	model = &op_p4_spec;
 	return 1;
 #else
 	switch (smp_num_siblings) {
 		case 1:
-			nmi_ops.cpu_type = "i386/p4";
+			*cpu_type = "i386/p4";
 			model = &op_p4_spec;
 			return 1;
 
 		case 2:
-			nmi_ops.cpu_type = "i386/p4-ht";
+			*cpu_type = "i386/p4-ht";
 			model = &op_p4_ht2_spec;
 			return 1;
 	}
@@ -340,21 +331,21 @@
 }
 
 
-static int __init ppro_init(void)
+static int __init ppro_init(char ** cpu_type)
 {
-	__u8 cpu_model = current_cpu_data.x86_model;
+	__u8 cpu_model = boot_cpu_data.x86_model;
 
 	if (cpu_model > 0xd)
 		return 0;
 
 	if (cpu_model == 9) {
-		nmi_ops.cpu_type = "i386/p6_mobile";
+		*cpu_type = "i386/p6_mobile";
 	} else if (cpu_model > 5) {
-		nmi_ops.cpu_type = "i386/piii";
+		*cpu_type = "i386/piii";
 	} else if (cpu_model > 2) {
-		nmi_ops.cpu_type = "i386/pii";
+		*cpu_type = "i386/pii";
 	} else {
-		nmi_ops.cpu_type = "i386/ppro";
+		*cpu_type = "i386/ppro";
 	}
 
 	model = &op_ppro_spec;
@@ -364,11 +355,12 @@
 /* in order to get driverfs right */
 static int using_nmi;
 
-int __init nmi_init(struct oprofile_operations ** ops)
+int __init nmi_init(struct oprofile_operations *ops)
 {
-	__u8 vendor = current_cpu_data.x86_vendor;
-	__u8 family = current_cpu_data.x86;
- 
+	__u8 vendor = boot_cpu_data.x86_vendor;
+	__u8 family = boot_cpu_data.x86;
+	char *cpu_type;
+
 	if (!cpu_has_apic)
 		return -ENODEV;
  
@@ -381,13 +373,13 @@
 				return -ENODEV;
 			case 6:
 				model = &op_athlon_spec;
-				nmi_ops.cpu_type = "i386/athlon";
+				cpu_type = "i386/athlon";
 				break;
 			case 0xf:
 				model = &op_athlon_spec;
 				/* Actually it could be i386/hammer too, but give
 				   user space an consistent name. */
-				nmi_ops.cpu_type = "x86-64/hammer";
+				cpu_type = "x86-64/hammer";
 				break;
 			}
 			break;
@@ -396,13 +388,13 @@
 			switch (family) {
 				/* Pentium IV */
 				case 0xf:
-					if (!p4_init())
+					if (!p4_init(&cpu_type))
 						return -ENODEV;
 					break;
 
 				/* A P6-class processor */
 				case 6:
-					if (!ppro_init())
+					if (!ppro_init(&cpu_type))
 						return -ENODEV;
 					break;
 
@@ -417,13 +409,18 @@
 
 	init_driverfs();
 	using_nmi = 1;
-	*ops = &nmi_ops;
+	ops->create_files = nmi_create_files;
+	ops->setup = nmi_setup;
+	ops->shutdown = nmi_shutdown;
+	ops->start = nmi_start;
+	ops->stop = nmi_stop;
+	ops->cpu_type = cpu_type;
 	printk(KERN_INFO "oprofile: using NMI interrupt.\n");
 	return 0;
 }
 
 
-void __exit nmi_exit(void)
+void nmi_exit(void)
 {
 	if (using_nmi)
 		exit_driverfs();
diff -Nru a/arch/i386/oprofile/nmi_timer_int.c b/arch/i386/oprofile/nmi_timer_int.c
--- a/arch/i386/oprofile/nmi_timer_int.c	2005-03-01 23:38:54 -08:00
+++ b/arch/i386/oprofile/nmi_timer_int.c	2005-03-01 23:38:54 -08:00
@@ -20,9 +20,7 @@
  
 static int nmi_timer_callback(struct pt_regs * regs, int cpu)
 {
-	unsigned long eip = instruction_pointer(regs);
- 
-	oprofile_add_sample(eip, !user_mode(regs), 0, cpu);
+	oprofile_add_sample(regs, 0);
 	return 1;
 }
 
@@ -42,20 +40,16 @@
 }
 
 
-static struct oprofile_operations nmi_timer_ops = {
-	.start	= timer_start,
-	.stop	= timer_stop,
-	.cpu_type = "timer"
-};
-
-int __init nmi_timer_init(struct oprofile_operations ** ops)
+int __init nmi_timer_init(struct oprofile_operations * ops)
 {
 	extern int nmi_active;
 
 	if (nmi_active <= 0)
 		return -ENODEV;
 
-	*ops = &nmi_timer_ops;
+	ops->start = timer_start;
+	ops->stop = timer_stop;
+	ops->cpu_type = "timer";
 	printk(KERN_INFO "oprofile: using NMI timer interrupt.\n");
 	return 0;
 }
diff -Nru a/arch/i386/oprofile/op_model_athlon.c b/arch/i386/oprofile/op_model_athlon.c
--- a/arch/i386/oprofile/op_model_athlon.c	2005-03-01 23:39:18 -08:00
+++ b/arch/i386/oprofile/op_model_athlon.c	2005-03-01 23:39:18 -08:00
@@ -90,19 +90,16 @@
 }
 
  
-static int athlon_check_ctrs(unsigned int const cpu, 
-			      struct op_msrs const * const msrs, 
-			      struct pt_regs * const regs)
+static int athlon_check_ctrs(struct pt_regs * const regs,
+			     struct op_msrs const * const msrs)
 {
 	unsigned int low, high;
 	int i;
-	unsigned long eip = profile_pc(regs);
-	int is_kernel = !user_mode(regs);
 
 	for (i = 0 ; i < NUM_COUNTERS; ++i) {
 		CTR_READ(low, high, msrs, i);
 		if (CTR_OVERFLOWED(low)) {
-			oprofile_add_sample(eip, is_kernel, i, cpu);
+			oprofile_add_sample(regs, i);
 			CTR_WRITE(reset_value[i], msrs, i);
 		}
 	}
diff -Nru a/arch/i386/oprofile/op_model_p4.c b/arch/i386/oprofile/op_model_p4.c
--- a/arch/i386/oprofile/op_model_p4.c	2005-03-01 23:38:52 -08:00
+++ b/arch/i386/oprofile/op_model_p4.c	2005-03-01 23:38:52 -08:00
@@ -619,14 +619,11 @@
 }
 
 
-static int p4_check_ctrs(unsigned int const cpu, 
-			  struct op_msrs const * const msrs,
-			  struct pt_regs * const regs)
+static int p4_check_ctrs(struct pt_regs * const regs,
+			 struct op_msrs const * const msrs)
 {
 	unsigned long ctr, low, high, stag, real;
 	int i;
-	unsigned long eip = profile_pc(regs);
-	int is_kernel = !user_mode(regs);
 
 	stag = get_stagger();
 
@@ -657,7 +654,7 @@
 		CCCR_READ(low, high, real);
  		CTR_READ(ctr, high, real);
 		if (CCCR_OVF_P(low) || CTR_OVERFLOW_P(ctr)) {
-			oprofile_add_sample(eip, is_kernel, i, cpu);
+			oprofile_add_sample(regs, i);
  			CTR_WRITE(reset_value[i], real);
 			CCCR_CLEAR_OVF(low);
 			CCCR_WRITE(low, high, real);
diff -Nru a/arch/i386/oprofile/op_model_ppro.c b/arch/i386/oprofile/op_model_ppro.c
--- a/arch/i386/oprofile/op_model_ppro.c	2005-03-01 23:39:07 -08:00
+++ b/arch/i386/oprofile/op_model_ppro.c	2005-03-01 23:39:07 -08:00
@@ -85,19 +85,16 @@
 }
 
  
-static int ppro_check_ctrs(unsigned int const cpu, 
-			    struct op_msrs const * const msrs,
-			    struct pt_regs * const regs)
+static int ppro_check_ctrs(struct pt_regs * const regs,
+			   struct op_msrs const * const msrs)
 {
 	unsigned int low, high;
 	int i;
-	unsigned long eip = profile_pc(regs);
-	int is_kernel = !user_mode(regs);
  
 	for (i = 0 ; i < NUM_COUNTERS; ++i) {
 		CTR_READ(low, high, msrs, i);
 		if (CTR_OVERFLOWED(low)) {
-			oprofile_add_sample(eip, is_kernel, i, cpu);
+			oprofile_add_sample(regs, i);
 			CTR_WRITE(reset_value[i], msrs, i);
 		}
 	}
diff -Nru a/arch/i386/oprofile/op_x86_model.h b/arch/i386/oprofile/op_x86_model.h
--- a/arch/i386/oprofile/op_x86_model.h	2005-03-01 23:38:53 -08:00
+++ b/arch/i386/oprofile/op_x86_model.h	2005-03-01 23:38:53 -08:00
@@ -36,9 +36,8 @@
 	unsigned int const num_controls;
 	void (*fill_in_addresses)(struct op_msrs * const msrs);
 	void (*setup_ctrs)(struct op_msrs const * const msrs);
-	int (*check_ctrs)(unsigned int const cpu, 
-		struct op_msrs const * const msrs,
-		struct pt_regs * const regs);
+	int (*check_ctrs)(struct pt_regs * const regs,
+		struct op_msrs const * const msrs);
 	void (*start)(struct op_msrs const * const msrs);
 	void (*stop)(struct op_msrs const * const msrs);
 };
diff -Nru a/arch/i386/pci/common.c b/arch/i386/pci/common.c
--- a/arch/i386/pci/common.c	2005-03-01 23:38:56 -08:00
+++ b/arch/i386/pci/common.c	2005-03-01 23:38:56 -08:00
@@ -53,7 +53,7 @@
  * This interrupt-safe spinlock protects all accesses to PCI
  * configuration space.
  */
-spinlock_t pci_config_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(pci_config_lock);
 
 /*
  * Several buggy motherboards address only 16 devices and mirror
diff -Nru a/arch/i386/pci/fixup.c b/arch/i386/pci/fixup.c
--- a/arch/i386/pci/fixup.c	2005-03-01 23:39:07 -08:00
+++ b/arch/i386/pci/fixup.c	2005-03-01 23:39:07 -08:00
@@ -227,10 +227,7 @@
  */
 static void __init pci_fixup_nforce2(struct pci_dev *dev)
 {
-	u32 val, fixed_val;
-	u8 rev;
-
-	pci_read_config_byte(dev, PCI_REVISION_ID, &rev);
+	u32 val;
 
 	/*
 	 * Chip  Old value   New value
@@ -240,17 +237,14 @@
 	 * Northbridge chip version may be determined by
 	 * reading the PCI revision ID (0xC1 or greater is C18D).
 	 */
-	fixed_val = rev < 0xC1 ? 0x1F01FF01 : 0x9F01FF01;
-
 	pci_read_config_dword(dev, 0x6c, &val);
 
 	/*
-	 * Apply fixup only if C1 Halt Disconnect is enabled
-	 * (bit28) because it is not supported on some boards.
+	 * Apply fixup if needed, but don't touch disconnect state
 	 */
-	if ((val & (1 << 28)) && val != fixed_val) {
+	if ((val & 0x00FF0000) != 0x00010000) {
 		printk(KERN_WARNING "PCI: nForce2 C1 Halt Disconnect fixup\n");
-		pci_write_config_dword(dev, 0x6c, fixed_val);
+		pci_write_config_dword(dev, 0x6c, (val & 0xFF00FFFF) | 0x00010000);
 	}
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2, pci_fixup_nforce2);
@@ -282,7 +276,7 @@
 	return raw_pci_ops->write(0, bus->number, devfn, where, size, value);
 }
 
-struct pci_ops quirk_pcie_aspm_ops = {
+static struct pci_ops quirk_pcie_aspm_ops = {
 	.read = quirk_pcie_aspm_read,
 	.write = quirk_pcie_aspm_write,
 };
@@ -295,7 +289,7 @@
  * the root port in an array for fast indexing. Replace the bus ops
  * with the modified one.
  */
-void pcie_rootport_aspm_quirk(struct pci_dev *pdev)
+static void pcie_rootport_aspm_quirk(struct pci_dev *pdev)
 {
 	int cap_base, i;
 	struct pci_bus  *pbus;
diff -Nru a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c
--- a/arch/i386/pci/irq.c	2005-03-01 23:39:17 -08:00
+++ b/arch/i386/pci/irq.c	2005-03-01 23:39:17 -08:00
@@ -29,6 +29,8 @@
 
 static struct irq_routing_table *pirq_table;
 
+static int pirq_enable_irq(struct pci_dev *dev);
+
 /*
  * Never use: 0, 1, 2 (timer, keyboard, and cascade)
  * Avoid using: 13, 14 and 15 (FP error and IDE).
@@ -491,6 +493,8 @@
 		case PCI_DEVICE_ID_INTEL_ESB_1:
 		case PCI_DEVICE_ID_INTEL_ICH6_0:
 		case PCI_DEVICE_ID_INTEL_ICH6_1:
+		case PCI_DEVICE_ID_INTEL_ICH7_0:
+		case PCI_DEVICE_ID_INTEL_ICH7_1:
 			r->name = "PIIX/ICH";
 			r->get = pirq_piix_get;
 			r->set = pirq_piix_set;
@@ -733,7 +737,7 @@
 	if (!pirq_table)
 		return 0;
 	
-	DBG("IRQ for %s:%d", pci_name(dev), pin);
+	DBG("IRQ for %s[%c]", pci_name(dev), 'A' + pin);
 	info = pirq_get_info(dev);
 	if (!info) {
 		DBG(" -> not found in routing table\n");
@@ -890,16 +894,16 @@
 					irq = IO_APIC_get_PCI_irq_vector(bridge->bus->number, 
 							PCI_SLOT(bridge->devfn), pin);
 					if (irq >= 0)
-						printk(KERN_WARNING "PCI: using PPB(B%d,I%d,P%d) to get irq %d\n", 
-							bridge->bus->number, PCI_SLOT(bridge->devfn), pin, irq);
+						printk(KERN_WARNING "PCI: using PPB %s[%c] to get irq %d\n",
+							pci_name(bridge), 'A' + pin, irq);
 				}
 				if (irq >= 0) {
 					if (use_pci_vector() &&
 						!platform_legacy_irq(irq))
 						irq = IO_APIC_VECTOR(irq);
 
-					printk(KERN_INFO "PCI->APIC IRQ transform: (B%d,I%d,P%d) -> %d\n",
-						dev->bus->number, PCI_SLOT(dev->devfn), pin, irq);
+					printk(KERN_INFO "PCI->APIC IRQ transform: %s[%c] -> IRQ %d\n",
+						pci_name(dev), 'A' + pin, irq);
 					dev->irq = irq;
 				}
 			}
@@ -1019,10 +1023,10 @@
 		pirq_penalize_isa_irq(irq);
 }
 
-int pirq_enable_irq(struct pci_dev *dev)
+static int pirq_enable_irq(struct pci_dev *dev)
 {
 	u8 pin;
-	extern int interrupt_line_quirk;
+	extern int via_interrupt_line_quirk;
 	struct pci_dev *temp_dev;
 
 	pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
@@ -1049,8 +1053,8 @@
 					irq = IO_APIC_get_PCI_irq_vector(bridge->bus->number, 
 							PCI_SLOT(bridge->devfn), pin);
 					if (irq >= 0)
-						printk(KERN_WARNING "PCI: using PPB(B%d,I%d,P%d) to get irq %d\n", 
-							bridge->bus->number, PCI_SLOT(bridge->devfn), pin, irq);
+						printk(KERN_WARNING "PCI: using PPB %s[%c] to get irq %d\n",
+							pci_name(bridge), 'A' + pin, irq);
 					dev = bridge;
 				}
 				dev = temp_dev;
@@ -1059,8 +1063,8 @@
 					if (!platform_legacy_irq(irq))
 						irq = IO_APIC_VECTOR(irq);
 #endif
-					printk(KERN_INFO "PCI->APIC IRQ transform: (B%d,I%d,P%d) -> %d\n",
-						dev->bus->number, PCI_SLOT(dev->devfn), pin, irq);
+					printk(KERN_INFO "PCI->APIC IRQ transform: %s[%c] -> IRQ %d\n",
+						pci_name(dev), 'A' + pin, irq);
 					dev->irq = irq;
 					return 0;
 				} else
@@ -1080,7 +1084,7 @@
 	}
 	/* VIA bridges use interrupt line for apic/pci steering across
 	   the V-Link */
-	else if (interrupt_line_quirk)
+	else if (via_interrupt_line_quirk)
 		pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq & 15);
 	return 0;
 }
diff -Nru a/arch/i386/pci/numa.c b/arch/i386/pci/numa.c
--- a/arch/i386/pci/numa.c	2005-03-01 23:38:53 -08:00
+++ b/arch/i386/pci/numa.c	2005-03-01 23:38:53 -08:00
@@ -4,6 +4,7 @@
 
 #include <linux/pci.h>
 #include <linux/init.h>
+#include <linux/nodemask.h>
 #include "pci.h"
 
 #define BUS2QUAD(global) (mp_bus_id_to_node[global])
@@ -112,14 +113,15 @@
 		return 0;
 
 	pci_root_bus = pcibios_scan_root(0);
-	if (numnodes > 1) {
-		for (quad = 1; quad < numnodes; ++quad) {
+	if (num_online_nodes() > 1)
+		for_each_online_node(quad) {
+			if (quad == 0)
+				continue;
 			printk("Scanning PCI bus %d for quad %d\n", 
 				QUADLOCAL2BUS(quad,0), quad);
 			pci_scan_bus(QUADLOCAL2BUS(quad,0), 
 				&pci_root_ops, NULL);
 		}
-	}
 	return 0;
 }
 
diff -Nru a/arch/i386/pci/pcbios.c b/arch/i386/pci/pcbios.c
--- a/arch/i386/pci/pcbios.c	2005-03-01 23:38:52 -08:00
+++ b/arch/i386/pci/pcbios.c	2005-03-01 23:38:52 -08:00
@@ -385,8 +385,8 @@
 			}
 		}
 		if (!found) {
-			printk(KERN_WARNING "PCI: Device %02x:%02x not found by BIOS\n",
-				dev->bus->number, dev->devfn);
+			printk(KERN_WARNING "PCI: Device %s not found by BIOS\n",
+				pci_name(dev));
 			list_del(&dev->global_list);
 			list_add_tail(&dev->global_list, &sorted_devices);
 		}
diff -Nru a/arch/i386/pci/pci.h b/arch/i386/pci/pci.h
--- a/arch/i386/pci/pci.h	2005-03-01 23:38:58 -08:00
+++ b/arch/i386/pci/pci.h	2005-03-01 23:38:58 -08:00
@@ -71,6 +71,4 @@
 extern int pcibios_scanned;
 extern spinlock_t pci_config_lock;
 
-int pirq_enable_irq(struct pci_dev *dev);
-
 extern int (*pcibios_enable_irq)(struct pci_dev *dev);
diff -Nru a/arch/ia64/Kconfig b/arch/ia64/Kconfig
--- a/arch/ia64/Kconfig	2005-03-01 23:39:16 -08:00
+++ b/arch/ia64/Kconfig	2005-03-01 23:39:16 -08:00
@@ -30,6 +30,10 @@
 	bool
 	default y
 
+config GENERIC_CALIBRATE_DELAY
+	bool
+	default y
+
 config TIME_INTERPOLATION
 	bool
 	default y
@@ -57,11 +61,12 @@
 	  will run on any supported IA-64 system.  However, if you configure
 	  a kernel for your specific system, it will be faster and smaller.
 
-	  generic	 For any supported IA-64 system
-	  DIG-compliant	 For DIG ("Developer's Interface Guide") compliant systems
-	  HP-zx1/sx1000	 For HP systems
-	  SGI-SN2	 For SGI Altix systems
-	  Ski-simulator  For the HP simulator <http://www.hpl.hp.com/research/linux/ski/>
+	  generic		For any supported IA-64 system
+	  DIG-compliant		For DIG ("Developer's Interface Guide") compliant systems
+	  HP-zx1/sx1000		For HP systems
+	  HP-zx1/sx1000+swiotlb	For HP systems with (broken) DMA-constrained devices.
+	  SGI-SN2		For SGI Altix systems
+	  Ski-simulator		For the HP simulator <http://www.hpl.hp.com/research/linux/ski/>
 
 	  If you don't know what to do, choose "generic".
 
@@ -74,6 +79,15 @@
 	  Build a kernel that runs on HP zx1 and sx1000 systems.  This adds
 	  support for the HP I/O MMU.
 
+config IA64_HP_ZX1_SWIOTLB
+	bool "HP-zx1/sx1000 with software I/O TLB"
+	help
+	  Build a kernel that runs on HP zx1 and sx1000 systems even when they
+	  have broken PCI devices which cannot DMA to full 32 bits.  Apart
+	  from support for the HP I/O MMU, this includes support for the software
+	  I/O TLB, which allows supporting the broken devices at the expense of
+	  wasting some kernel memory (about 2MB by default).
+
 config IA64_SGI_SN2
 	bool "SGI-SN2"
 	help
@@ -144,14 +158,6 @@
 	depends on ITANIUM
 	default y
 
-config ITANIUM_BSTEP_SPECIFIC
-	bool "Itanium B-step specific code"
-	depends on ITANIUM
-	help
-	  Select this option to build a kernel for an Itanium prototype system
-	  with a B-step CPU.  You have a B-step CPU if the "revision" field in
-	  /proc/cpuinfo has a value in the range from 1 to 4.
-
 # align cache-sensitive data to 128 bytes
 config IA64_L1_CACHE_SHIFT
 	int
@@ -178,9 +184,13 @@
 	  require the DISCONTIGMEM option for your machine. If you are
 	  unsure, say Y.
 
+config HOLES_IN_ZONE
+	bool
+	default y if VIRTUAL_MEM_MAP
+
 config DISCONTIGMEM
 	bool "Discontiguous memory support"
-	depends on (IA64_DIG || IA64_SGI_SN2 || IA64_GENERIC || IA64_HP_ZX1) && NUMA && VIRTUAL_MEM_MAP
+	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
 	help
 	  Say Y to support efficient handling of discontiguous physical memory,
@@ -241,13 +251,14 @@
 	  performance hit.
 
 config HOTPLUG_CPU
-    bool "Support for hot-pluggable CPUs (EXPERIMENTAL)"
-    depends on SMP && HOTPLUG && EXPERIMENTAL
+	bool "Support for hot-pluggable CPUs (EXPERIMENTAL)"
+	depends on SMP && EXPERIMENTAL
+	select HOTPLUG
 	default n
-    ---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.
+	---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 PREEMPT
 	bool "Preemptible Kernel"
@@ -302,6 +313,11 @@
 	  To use this option, you have to ensure that the "/proc file system
 	  support" (CONFIG_PROC_FS) is enabled, too.
 
+config ACPI_DEALLOCATE_IRQ
+	bool
+	depends on IOSAPIC && EXPERIMENTAL
+	default y
+
 source "drivers/firmware/Kconfig"
 
 source "fs/Kconfig.binfmt"
@@ -312,7 +328,7 @@
 
 config PM
 	bool "Power Management support"
-	depends on IA64_GENERIC || IA64_DIG || IA64_HP_ZX1
+	depends on IA64_GENERIC || IA64_DIG || IA64_HP_ZX1 || IA64_HP_ZX1_SWIOTLB
 	default y
 	help
 	  "Power Management" means that parts of your computer are shut
@@ -380,6 +396,17 @@
 source "fs/Kconfig"
 
 source "lib/Kconfig"
+
+#
+# Use the generic interrupt handling code in kernel/irq/:
+#
+config GENERIC_HARDIRQS
+	bool
+	default y
+
+config GENERIC_IRQ_PROBE
+	bool
+	default y
 
 source "arch/ia64/hp/sim/Kconfig"
 
diff -Nru a/arch/ia64/Kconfig.debug b/arch/ia64/Kconfig.debug
--- a/arch/ia64/Kconfig.debug	2005-03-01 23:38:56 -08:00
+++ b/arch/ia64/Kconfig.debug	2005-03-01 23:38:56 -08:00
@@ -16,7 +16,7 @@
 
 config IA64_GRANULE_64MB
 	bool "64MB"
-	depends on !(IA64_GENERIC || IA64_HP_ZX1 || IA64_SGI_SN2)
+	depends on !(IA64_GENERIC || IA64_HP_ZX1 || IA64_HP_ZX1_SWIOTLB || IA64_SGI_SN2)
 
 endchoice
 
diff -Nru a/arch/ia64/Makefile b/arch/ia64/Makefile
--- a/arch/ia64/Makefile	2005-03-01 23:38:51 -08:00
+++ b/arch/ia64/Makefile	2005-03-01 23:38:51 -08:00
@@ -46,8 +46,6 @@
 	cflags-$(CONFIG_MCKINLEY)	+= -mtune=mckinley
 endif
 
-cflags-$(CONFIG_ITANIUM_BSTEP_SPECIFIC)	+= -mb-step
-
 CFLAGS += $(cflags-y)
 head-y := arch/ia64/kernel/head.o arch/ia64/kernel/init_task.o
 
@@ -57,11 +55,13 @@
 core-$(CONFIG_IA64_DIG) 	+= arch/ia64/dig/
 core-$(CONFIG_IA64_GENERIC) 	+= arch/ia64/dig/
 core-$(CONFIG_IA64_HP_ZX1)	+= arch/ia64/dig/
+core-$(CONFIG_IA64_HP_ZX1_SWIOTLB) += arch/ia64/dig/
 core-$(CONFIG_IA64_SGI_SN2)	+= arch/ia64/sn/
 
 drivers-$(CONFIG_PCI)		+= arch/ia64/pci/
 drivers-$(CONFIG_IA64_HP_SIM)	+= arch/ia64/hp/sim/
 drivers-$(CONFIG_IA64_HP_ZX1)	+= arch/ia64/hp/common/ arch/ia64/hp/zx1/
+drivers-$(CONFIG_IA64_HP_ZX1_SWIOTLB) += arch/ia64/hp/common/ arch/ia64/hp/zx1/
 drivers-$(CONFIG_IA64_GENERIC)	+= arch/ia64/hp/common/ arch/ia64/hp/zx1/ arch/ia64/hp/sim/ arch/ia64/sn/
 drivers-$(CONFIG_OPROFILE)	+= arch/ia64/oprofile/
 
diff -Nru a/arch/ia64/configs/bigsur_defconfig b/arch/ia64/configs/bigsur_defconfig
--- a/arch/ia64/configs/bigsur_defconfig	2005-03-01 23:38:52 -08:00
+++ b/arch/ia64/configs/bigsur_defconfig	2005-03-01 23:38:52 -08:00
@@ -73,7 +73,6 @@
 CONFIG_IA64_PAGE_SIZE_16KB=y
 # CONFIG_IA64_PAGE_SIZE_64KB is not set
 CONFIG_IA64_BRL_EMU=y
-# CONFIG_ITANIUM_BSTEP_SPECIFIC is not set
 CONFIG_IA64_L1_CACHE_SHIFT=6
 # CONFIG_NUMA is not set
 # CONFIG_VIRTUAL_MEM_MAP is not set
diff -Nru a/arch/ia64/configs/sn2_defconfig b/arch/ia64/configs/sn2_defconfig
--- a/arch/ia64/configs/sn2_defconfig	2005-03-01 23:38:44 -08:00
+++ b/arch/ia64/configs/sn2_defconfig	2005-03-01 23:38:44 -08:00
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc1
-# Mon Nov  1 14:35:44 2004
+# Linux kernel version: 2.6.10
+# Mon Jan 10 13:57:35 2005
 #
 
 #
@@ -58,6 +58,7 @@
 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
@@ -75,6 +76,7 @@
 CONFIG_IA64_L1_CACHE_SHIFT=7
 CONFIG_NUMA=y
 CONFIG_VIRTUAL_MEM_MAP=y
+CONFIG_HOLES_IN_ZONE=y
 CONFIG_DISCONTIGMEM=y
 # CONFIG_IA64_CYCLONE is not set
 CONFIG_IOSAPIC=y
@@ -90,6 +92,7 @@
 CONFIG_IA64_MCA_RECOVERY=y
 CONFIG_PERFMON=y
 CONFIG_IA64_PALINFO=y
+CONFIG_ACPI_DEALLOCATE_IRQ=y
 
 #
 # Firmware Drivers
@@ -110,6 +113,7 @@
 CONFIG_ACPI_BOOT=y
 CONFIG_ACPI_INTERPRETER=y
 # CONFIG_ACPI_BUTTON is not set
+CONFIG_ACPI_VIDEO=m
 # CONFIG_ACPI_FAN is not set
 # CONFIG_ACPI_PROCESSOR is not set
 CONFIG_ACPI_NUMA=y
@@ -119,6 +123,7 @@
 CONFIG_ACPI_POWER=y
 CONFIG_ACPI_PCI=y
 CONFIG_ACPI_SYSTEM=y
+# CONFIG_ACPI_CONTAINER is not set
 
 #
 # Bus options (PCI, PCMCIA)
@@ -174,6 +179,7 @@
 #
 # Plug and Play support
 #
+# CONFIG_PNP is not set
 
 #
 # Block devices
@@ -188,6 +194,7 @@
 # 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=""
@@ -200,6 +207,7 @@
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -287,6 +295,7 @@
 #
 CONFIG_SCSI_SPI_ATTRS=y
 CONFIG_SCSI_FC_ATTRS=y
+# CONFIG_SCSI_ISCSI_ATTRS is not set
 
 #
 # SCSI low-level drivers
@@ -333,7 +342,6 @@
 CONFIG_SCSI_QLA2300=y
 CONFIG_SCSI_QLA2322=y
 # CONFIG_SCSI_QLA6312 is not set
-# CONFIG_SCSI_QLA6322 is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_DEBUG is not set
@@ -350,6 +358,7 @@
 CONFIG_MD_RAID5=y
 # CONFIG_MD_RAID6 is not set
 CONFIG_MD_MULTIPATH=y
+# CONFIG_MD_FAULTY is not set
 CONFIG_BLK_DEV_DM=y
 CONFIG_DM_CRYPT=m
 CONFIG_DM_SNAPSHOT=m
@@ -399,6 +408,8 @@
 # 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
@@ -478,6 +489,7 @@
 # CONFIG_IXGB is not set
 CONFIG_S2IO=m
 # CONFIG_S2IO_NAPI is not set
+# CONFIG_2BUFF_MODE is not set
 
 #
 # Token Ring devices
@@ -554,6 +566,8 @@
 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
@@ -664,6 +678,7 @@
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
 CONFIG_USB_OHCI_HCD=m
 CONFIG_USB_UHCI_HCD=m
+# CONFIG_USB_SL811_HCD is not set
 
 #
 # USB Device Class drivers
@@ -671,6 +686,10 @@
 # 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
 
 #
@@ -700,7 +719,6 @@
 #
 # CONFIG_USB_MDC800 is not set
 # CONFIG_USB_MICROTEK is not set
-# CONFIG_USB_HPUSBSCSI is not set
 
 #
 # USB Multimedia devices
@@ -712,7 +730,7 @@
 #
 
 #
-# USB Network adaptors
+# USB Network Adapters
 #
 # CONFIG_USB_CATC is not set
 # CONFIG_USB_KAWETH is not set
@@ -734,7 +752,6 @@
 #
 # 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
@@ -754,6 +771,20 @@
 # CONFIG_USB_GADGET is not set
 
 #
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+CONFIG_INFINIBAND=m
+CONFIG_INFINIBAND_MTHCA=m
+# CONFIG_INFINIBAND_MTHCA_DEBUG is not set
+CONFIG_INFINIBAND_IPOIB=m
+# CONFIG_INFINIBAND_IPOIB_DEBUG is not set
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
@@ -864,7 +895,7 @@
 CONFIG_CIFS=m
 # CONFIG_CIFS_STATS is not set
 # CONFIG_CIFS_XATTR is not set
-# CONFIG_CIFS_POSIX is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
@@ -958,6 +989,7 @@
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_KOBJECT is not set
 CONFIG_DEBUG_INFO=y
+# 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
@@ -994,7 +1026,12 @@
 # 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
+#
diff -Nru a/arch/ia64/configs/tiger_defconfig b/arch/ia64/configs/tiger_defconfig
--- a/arch/ia64/configs/tiger_defconfig	2005-03-01 23:38:52 -08:00
+++ b/arch/ia64/configs/tiger_defconfig	2005-03-01 23:38:52 -08:00
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc1
-# Tue Nov  2 11:35:10 2004
+# Linux kernel version: 2.6.11-rc2
+# Sat Jan 22 11:17:02 2005
 #
 
 #
@@ -59,12 +59,14 @@
 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_IA64_GENERIC is not set
 CONFIG_IA64_DIG=y
 # 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
@@ -76,6 +78,7 @@
 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_FORCE_MAX_ZONEORDER=18
@@ -89,6 +92,7 @@
 CONFIG_IA64_MCA_RECOVERY=y
 CONFIG_PERFMON=y
 CONFIG_IA64_PALINFO=y
+CONFIG_ACPI_DEALLOCATE_IRQ=y
 
 #
 # Firmware Drivers
@@ -110,8 +114,10 @@
 CONFIG_ACPI_BOOT=y
 CONFIG_ACPI_INTERPRETER=y
 CONFIG_ACPI_BUTTON=m
+# CONFIG_ACPI_VIDEO is not set
 CONFIG_ACPI_FAN=m
 CONFIG_ACPI_PROCESSOR=m
+# CONFIG_ACPI_HOTPLUG_CPU is not set
 CONFIG_ACPI_THERMAL=m
 CONFIG_ACPI_BLACKLIST_YEAR=0
 # CONFIG_ACPI_DEBUG is not set
@@ -119,6 +125,7 @@
 CONFIG_ACPI_POWER=y
 CONFIG_ACPI_PCI=y
 CONFIG_ACPI_SYSTEM=y
+# CONFIG_ACPI_CONTAINER is not set
 
 #
 # Bus options (PCI, PCMCIA)
@@ -137,7 +144,6 @@
 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
 
 #
@@ -174,6 +180,7 @@
 #
 # Plug and Play support
 #
+# CONFIG_PNP is not set
 
 #
 # Block devices
@@ -182,12 +189,14 @@
 # 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
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_UB is not set
 CONFIG_BLK_DEV_RAM=m
+CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
 CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CDROM_PKTCDVD is not set
@@ -199,6 +208,7 @@
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
+# CONFIG_ATA_OVER_ETH is not set
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -285,6 +295,7 @@
 #
 CONFIG_SCSI_SPI_ATTRS=y
 CONFIG_SCSI_FC_ATTRS=y
+# CONFIG_SCSI_ISCSI_ATTRS is not set
 
 #
 # SCSI low-level drivers
@@ -325,7 +336,6 @@
 CONFIG_SCSI_QLA2300=m
 CONFIG_SCSI_QLA2322=m
 # CONFIG_SCSI_QLA6312 is not set
-# CONFIG_SCSI_QLA6322 is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_DEBUG is not set
@@ -342,6 +352,7 @@
 CONFIG_MD_RAID5=m
 CONFIG_MD_RAID6=m
 CONFIG_MD_MULTIPATH=m
+# CONFIG_MD_FAULTY is not set
 CONFIG_BLK_DEV_DM=m
 CONFIG_DM_CRYPT=m
 CONFIG_DM_SNAPSHOT=m
@@ -392,6 +403,7 @@
 # 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
 
@@ -471,7 +483,6 @@
 # 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
@@ -564,12 +575,13 @@
 # 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_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
 
 #
@@ -598,6 +610,8 @@
 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
@@ -645,7 +659,7 @@
 #
 CONFIG_AGP=m
 CONFIG_AGP_I460=m
-CONFIG_DRM=y
+CONFIG_DRM=m
 CONFIG_DRM_TDFX=m
 CONFIG_DRM_R128=m
 CONFIG_DRM_RADEON=m
@@ -691,6 +705,7 @@
 #
 CONFIG_VGA_CONSOLE=y
 CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -722,6 +737,7 @@
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
 CONFIG_USB_OHCI_HCD=m
 CONFIG_USB_UHCI_HCD=y
+# CONFIG_USB_SL811_HCD is not set
 
 #
 # USB Device Class drivers
@@ -729,6 +745,10 @@
 # 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=m
 # CONFIG_USB_STORAGE_DEBUG is not set
 # CONFIG_USB_STORAGE_RW_DETECT is not set
@@ -762,7 +782,6 @@
 #
 # CONFIG_USB_MDC800 is not set
 # CONFIG_USB_MICROTEK is not set
-# CONFIG_USB_HPUSBSCSI is not set
 
 #
 # USB Multimedia devices
@@ -774,7 +793,7 @@
 #
 
 #
-# USB Network adaptors
+# USB Network Adapters
 #
 # CONFIG_USB_CATC is not set
 # CONFIG_USB_KAWETH is not set
@@ -796,7 +815,6 @@
 #
 # 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
@@ -805,6 +823,7 @@
 # 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
 
 #
@@ -817,6 +836,16 @@
 # 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
@@ -927,7 +956,7 @@
 CONFIG_CIFS=m
 # CONFIG_CIFS_STATS is not set
 # CONFIG_CIFS_XATTR is not set
-# CONFIG_CIFS_POSIX is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
@@ -1002,6 +1031,8 @@
 # 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
@@ -1019,6 +1050,7 @@
 # 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
@@ -1055,7 +1087,12 @@
 # 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 -Nru a/arch/ia64/configs/zx1_defconfig b/arch/ia64/configs/zx1_defconfig
--- a/arch/ia64/configs/zx1_defconfig	2005-03-01 23:39:07 -08:00
+++ b/arch/ia64/configs/zx1_defconfig	2005-03-01 23:39:07 -08:00
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.9-rc2-aegl
-# Mon Sep 27 19:03:13 2004
+# Linux kernel version: 2.6.10
+# Wed Dec 29 09:05:48 2004
 #
 
 #
@@ -11,6 +11,7 @@
 # CONFIG_CLEAN_COMPILE is not set
 CONFIG_BROKEN=y
 CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
 
 #
 # General setup
@@ -25,6 +26,7 @@
 # CONFIG_AUDIT is not set
 CONFIG_LOG_BUF_SHIFT=17
 CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
@@ -32,12 +34,12 @@
 # CONFIG_KALLSYMS_EXTRA_PASS 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
 
 #
@@ -47,6 +49,7 @@
 # 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
 
 #
@@ -83,6 +86,7 @@
 CONFIG_HAVE_DEC_LOCK=y
 CONFIG_IA32_SUPPORT=y
 CONFIG_COMPAT=y
+CONFIG_IA64_MCA_RECOVERY=y
 CONFIG_PERFMON=y
 CONFIG_IA64_PALINFO=y
 
@@ -106,9 +110,11 @@
 CONFIG_ACPI_BOOT=y
 CONFIG_ACPI_INTERPRETER=y
 CONFIG_ACPI_BUTTON=y
+CONFIG_ACPI_VIDEO=m
 CONFIG_ACPI_FAN=y
 CONFIG_ACPI_PROCESSOR=y
 CONFIG_ACPI_THERMAL=y
+CONFIG_ACPI_BLACKLIST_YEAR=0
 # CONFIG_ACPI_DEBUG is not set
 CONFIG_ACPI_BUS=y
 CONFIG_ACPI_POWER=y
@@ -136,9 +142,13 @@
 # CONFIG_HOTPLUG_PCI_SHPC is not set
 
 #
-# PCMCIA/CardBus support
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
 #
-# CONFIG_PCMCIA is not set
 
 #
 # Device Drivers
@@ -165,6 +175,7 @@
 #
 # Plug and Play support
 #
+# CONFIG_PNP is not set
 
 #
 # Block devices
@@ -179,8 +190,19 @@
 # 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=""
+# CONFIG_CDROM_PKTCDVD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -199,7 +221,6 @@
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
 # CONFIG_BLK_DEV_IDESCSI is not set
 # CONFIG_IDE_TASK_IOCTL is not set
-# CONFIG_IDE_TASKFILE_IO is not set
 
 #
 # IDE chipset support/bugfixes
@@ -303,6 +324,7 @@
 # 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
 CONFIG_SCSI_QLA2XXX=y
 # CONFIG_SCSI_QLA21XX is not set
 # CONFIG_SCSI_QLA22XX is not set
@@ -362,6 +384,8 @@
 # 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
@@ -375,6 +399,7 @@
 # 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
@@ -399,7 +424,6 @@
 # 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
@@ -469,7 +493,6 @@
 # CONFIG_EPIC100 is not set
 # CONFIG_SUNDANCE is not set
 # CONFIG_VIA_RHINE is not set
-# CONFIG_VIA_VELOCITY is not set
 
 #
 # Ethernet (1000 Mbit)
@@ -483,6 +506,7 @@
 # CONFIG_YELLOWFIN is not set
 # CONFIG_R8169 is not set
 # CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
 CONFIG_TIGON3=y
 
 #
@@ -653,6 +677,7 @@
 # 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
@@ -664,20 +689,24 @@
 # 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
@@ -708,7 +737,37 @@
 #
 # Multimedia devices
 #
-# CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_DEV=y
+
+#
+# Video For Linux
+#
+
+#
+# Video Adapters
+#
+# CONFIG_VIDEO_BT848 is not set
+# CONFIG_VIDEO_CPIA is not set
+# CONFIG_VIDEO_SAA5246A is not set
+# CONFIG_VIDEO_SAA5249 is not set
+# CONFIG_TUNER_3036 is not set
+# CONFIG_VIDEO_STRADIS is not set
+# CONFIG_VIDEO_ZORAN is not set
+# CONFIG_VIDEO_ZR36120 is not set
+# CONFIG_VIDEO_SAA7134 is not set
+# CONFIG_VIDEO_MXB is not set
+# CONFIG_VIDEO_DPC is not set
+# CONFIG_VIDEO_HEXIUM_ORION is not set
+# CONFIG_VIDEO_HEXIUM_GEMINI is not set
+# CONFIG_VIDEO_CX88 is not set
+# CONFIG_VIDEO_OVCAMCHIP is not set
+
+#
+# Radio Adapters
+#
+# CONFIG_RADIO_GEMTEK_PCI is not set
+# CONFIG_RADIO_MAXIRADIO is not set
+# CONFIG_RADIO_MAESTRO is not set
 
 #
 # Digital Video Broadcasting Devices
@@ -720,6 +779,7 @@
 #
 CONFIG_FB=y
 CONFIG_FB_MODE_HELPERS=y
+# CONFIG_FB_TILEBLITTING is not set
 # CONFIG_FB_CIRRUS is not set
 # CONFIG_FB_PM2 is not set
 # CONFIG_FB_CYBER2000 is not set
@@ -733,6 +793,7 @@
 CONFIG_FB_RADEON_DEBUG=y
 # CONFIG_FB_ATY128 is not set
 # CONFIG_FB_ATY is not set
+# CONFIG_FB_SAVAGE is not set
 # CONFIG_FB_SIS is not set
 # CONFIG_FB_NEOMAGIC is not set
 # CONFIG_FB_KYRO is not set
@@ -763,7 +824,87 @@
 #
 # Sound
 #
-# CONFIG_SOUND is not set
+CONFIG_SOUND=y
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+CONFIG_SND_HWDEP=y
+CONFIG_SND_RAWMIDI=y
+CONFIG_SND_SEQUENCER=y
+# CONFIG_SND_SEQ_DUMMY is not set
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+CONFIG_SND_SEQUENCER_OSS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+CONFIG_SND_MPU401_UART=y
+CONFIG_SND_OPL3_LIB=y
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_VIRMIDI is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+
+#
+# PCI devices
+#
+CONFIG_SND_AC97_CODEC=y
+# CONFIG_SND_ALI5451 is not set
+# CONFIG_SND_ATIIXP is not set
+# CONFIG_SND_ATIIXP_MODEM is not set
+# CONFIG_SND_AU8810 is not set
+# CONFIG_SND_AU8820 is not set
+# CONFIG_SND_AU8830 is not set
+# CONFIG_SND_AZT3328 is not set
+# CONFIG_SND_BT87X is not set
+# CONFIG_SND_CS46XX is not set
+# CONFIG_SND_CS4281 is not set
+# CONFIG_SND_EMU10K1 is not set
+# CONFIG_SND_KORG1212 is not set
+# CONFIG_SND_MIXART is not set
+# CONFIG_SND_NM256 is not set
+# CONFIG_SND_RME32 is not set
+# CONFIG_SND_RME96 is not set
+# CONFIG_SND_RME9652 is not set
+# CONFIG_SND_HDSP is not set
+# CONFIG_SND_TRIDENT is not set
+# CONFIG_SND_YMFPCI is not set
+# CONFIG_SND_ALS4000 is not set
+# CONFIG_SND_CMIPCI is not set
+# CONFIG_SND_ENS1370 is not set
+# CONFIG_SND_ENS1371 is not set
+# CONFIG_SND_ES1938 is not set
+# CONFIG_SND_ES1968 is not set
+# CONFIG_SND_MAESTRO3 is not set
+CONFIG_SND_FM801=y
+CONFIG_SND_FM801_TEA575X=y
+# CONFIG_SND_ICE1712 is not set
+# CONFIG_SND_ICE1724 is not set
+# CONFIG_SND_INTEL8X0 is not set
+# CONFIG_SND_INTEL8X0M is not set
+# CONFIG_SND_SONICVIBES is not set
+# CONFIG_SND_VIA82XX is not set
+# CONFIG_SND_VX222 is not set
+
+#
+# USB devices
+#
+# CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_USX2Y is not set
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
 
 #
 # USB support
@@ -779,6 +920,8 @@
 # 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
@@ -788,13 +931,20 @@
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
 CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_UHCI_HCD=y
+# CONFIG_USB_SL811_HCD is not set
 
 #
 # USB Device Class drivers
 #
+# CONFIG_USB_AUDIO is not set
 # CONFIG_USB_BLUETOOTH_TTY is not set
+# CONFIG_USB_MIDI 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=y
 # CONFIG_USB_STORAGE_DEBUG is not set
 # CONFIG_USB_STORAGE_RW_DETECT is not set
@@ -808,7 +958,7 @@
 # CONFIG_USB_STORAGE_JUMPSHOT is not set
 
 #
-# USB Human Interface Devices (HID)
+# USB Input Devices
 #
 CONFIG_USB_HID=y
 CONFIG_USB_HIDINPUT=y
@@ -834,13 +984,17 @@
 # USB Multimedia devices
 #
 # CONFIG_USB_DABUSB is not set
+# CONFIG_USB_VICAM is not set
+# CONFIG_USB_DSBR is not set
+# CONFIG_USB_IBMCAM is not set
+# CONFIG_USB_KONICAWC is not set
+# CONFIG_USB_OV511 is not set
+# CONFIG_USB_SE401 is not set
+# CONFIG_USB_SN9C102 is not set
+# CONFIG_USB_STV680 is not set
 
 #
-# Video4Linux support is needed for USB Multimedia device support
-#
-
-#
-# USB Network adaptors
+# USB Network Adapters
 #
 # CONFIG_USB_CATC is not set
 # CONFIG_USB_KAWETH is not set
@@ -869,14 +1023,24 @@
 # 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
 
 #
+# USB ATM/DSL drivers
+#
+
+#
 # USB Gadget Support
 #
 # CONFIG_USB_GADGET is not set
 
 #
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
@@ -896,6 +1060,7 @@
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 # CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
 CONFIG_AUTOFS_FS=y
 # CONFIG_AUTOFS4_FS is not set
 
@@ -927,6 +1092,8 @@
 # CONFIG_DEVFS_FS is not set
 # CONFIG_DEVPTS_FS_XATTR is not set
 CONFIG_TMPFS=y
+CONFIG_TMPFS_XATTR=y
+CONFIG_TMPFS_SECURITY=y
 CONFIG_HUGETLBFS=y
 CONFIG_HUGETLB_PAGE=y
 CONFIG_RAMFS=y
@@ -1053,9 +1220,11 @@
 #
 CONFIG_DEBUG_KERNEL=y
 CONFIG_MAGIC_SYSRQ=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_INFO is not set
 CONFIG_IA64_GRANULE_16MB=y
 # CONFIG_IA64_GRANULE_64MB is not set
@@ -1068,6 +1237,7 @@
 #
 # Security options
 #
+# CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 
 #
@@ -1081,7 +1251,7 @@
 # CONFIG_CRYPTO_SHA1 is not set
 # CONFIG_CRYPTO_SHA256 is not set
 # CONFIG_CRYPTO_SHA512 is not set
-# CONFIG_CRYPTO_WHIRLPOOL is not set
+# CONFIG_CRYPTO_WP512 is not set
 CONFIG_CRYPTO_DES=y
 # CONFIG_CRYPTO_BLOWFISH is not set
 # CONFIG_CRYPTO_TWOFISH is not set
@@ -1092,7 +1262,12 @@
 # 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 -Nru a/arch/ia64/defconfig b/arch/ia64/defconfig
--- a/arch/ia64/defconfig	2005-03-01 23:38:52 -08:00
+++ b/arch/ia64/defconfig	2005-03-01 23:38:52 -08:00
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc1
-# Tue Nov  2 11:47:56 2004
+# Linux kernel version: 2.6.10
+# Thu Jan  6 11:13:13 2005
 #
 
 #
@@ -59,6 +59,7 @@
 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
@@ -90,6 +91,7 @@
 CONFIG_IA64_MCA_RECOVERY=y
 CONFIG_PERFMON=y
 CONFIG_IA64_PALINFO=y
+CONFIG_ACPI_DEALLOCATE_IRQ=y
 
 #
 # Firmware Drivers
@@ -111,8 +113,10 @@
 CONFIG_ACPI_BOOT=y
 CONFIG_ACPI_INTERPRETER=y
 CONFIG_ACPI_BUTTON=m
+CONFIG_ACPI_VIDEO=m
 CONFIG_ACPI_FAN=m
 CONFIG_ACPI_PROCESSOR=m
+CONFIG_ACPI_HOTPLUG_CPU=y
 CONFIG_ACPI_THERMAL=m
 CONFIG_ACPI_NUMA=y
 CONFIG_ACPI_BLACKLIST_YEAR=0
@@ -121,6 +125,7 @@
 CONFIG_ACPI_POWER=y
 CONFIG_ACPI_PCI=y
 CONFIG_ACPI_SYSTEM=y
+CONFIG_ACPI_CONTAINER=m
 
 #
 # Bus options (PCI, PCMCIA)
@@ -176,6 +181,7 @@
 #
 # Plug and Play support
 #
+# CONFIG_PNP is not set
 
 #
 # Block devices
@@ -189,8 +195,10 @@
 CONFIG_BLK_DEV_NBD=m
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_UB is not set
-CONFIG_BLK_DEV_RAM=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
 
@@ -288,6 +296,7 @@
 #
 CONFIG_SCSI_SPI_ATTRS=y
 CONFIG_SCSI_FC_ATTRS=y
+# CONFIG_SCSI_ISCSI_ATTRS is not set
 
 #
 # SCSI low-level drivers
@@ -328,7 +337,6 @@
 CONFIG_SCSI_QLA2300=m
 CONFIG_SCSI_QLA2322=m
 # CONFIG_SCSI_QLA6312 is not set
-# CONFIG_SCSI_QLA6322 is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_DEBUG is not set
@@ -345,6 +353,7 @@
 CONFIG_MD_RAID5=m
 CONFIG_MD_RAID6=m
 CONFIG_MD_MULTIPATH=m
+# CONFIG_MD_FAULTY is not set
 CONFIG_BLK_DEV_DM=m
 CONFIG_DM_CRYPT=m
 CONFIG_DM_SNAPSHOT=m
@@ -395,6 +404,7 @@
 # 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
 
@@ -573,6 +583,7 @@
 # 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
 
 #
@@ -601,6 +612,7 @@
 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_SYNCLINKMP is not set
 # CONFIG_N_HDLC is not set
@@ -651,7 +663,7 @@
 CONFIG_AGP=m
 CONFIG_AGP_I460=m
 CONFIG_AGP_HP_ZX1=m
-CONFIG_DRM=y
+CONFIG_DRM=m
 CONFIG_DRM_TDFX=m
 CONFIG_DRM_R128=m
 CONFIG_DRM_RADEON=m
@@ -810,6 +822,7 @@
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
 CONFIG_USB_OHCI_HCD=m
 CONFIG_USB_UHCI_HCD=m
+# CONFIG_USB_SL811_HCD is not set
 
 #
 # USB Device Class drivers
@@ -819,6 +832,10 @@
 # CONFIG_USB_MIDI 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=m
 # CONFIG_USB_STORAGE_DEBUG is not set
 # CONFIG_USB_STORAGE_RW_DETECT is not set
@@ -858,7 +875,6 @@
 #
 # CONFIG_USB_MDC800 is not set
 # CONFIG_USB_MICROTEK is not set
-# CONFIG_USB_HPUSBSCSI is not set
 
 #
 # USB Multimedia devices
@@ -870,7 +886,7 @@
 #
 
 #
-# USB Network adaptors
+# USB Network Adapters
 #
 # CONFIG_USB_CATC is not set
 # CONFIG_USB_KAWETH is not set
@@ -913,6 +929,20 @@
 # CONFIG_USB_GADGET is not set
 
 #
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+CONFIG_INFINIBAND=m
+CONFIG_INFINIBAND_MTHCA=m
+# CONFIG_INFINIBAND_MTHCA_DEBUG is not set
+CONFIG_INFINIBAND_IPOIB=m
+# CONFIG_INFINIBAND_IPOIB_DEBUG is not set
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
@@ -1023,7 +1053,7 @@
 CONFIG_CIFS=m
 # CONFIG_CIFS_STATS is not set
 # CONFIG_CIFS_XATTR is not set
-# CONFIG_CIFS_POSIX is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
@@ -1158,7 +1188,12 @@
 # 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 -Nru a/arch/ia64/dig/Makefile b/arch/ia64/dig/Makefile
--- a/arch/ia64/dig/Makefile	2005-03-01 23:39:08 -08:00
+++ b/arch/ia64/dig/Makefile	2005-03-01 23:39:08 -08:00
@@ -6,9 +6,4 @@
 #
 
 obj-y := setup.o
-
-ifndef CONFIG_NUMA
-obj-$(CONFIG_IA64_DIG) += topology.o
-endif
-
 obj-$(CONFIG_IA64_GENERIC) += machvec.o
diff -Nru a/arch/ia64/dig/topology.c b/arch/ia64/dig/topology.c
--- a/arch/ia64/dig/topology.c	2005-03-01 23:39:18 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,43 +0,0 @@
-/*
- * arch/ia64/dig/topology.c
- *	Popuate driverfs with topology information.
- *	Derived entirely from i386/mach-default.c
- *  Intel Corporation - Ashok Raj
- */
-#include <linux/init.h>
-#include <linux/smp.h>
-#include <linux/cpumask.h>
-#include <linux/percpu.h>
-#include <linux/notifier.h>
-#include <linux/cpu.h>
-#include <asm/cpu.h>
-
-static DEFINE_PER_CPU(struct ia64_cpu, cpu_devices);
-
-/*
- * First Pass: simply borrowed code for now. Later should hook into
- * hotplug notification for node/cpu/memory as applicable
- */
-
-static int arch_register_cpu(int num)
-{
-	struct node *parent = NULL;
-
-#ifdef CONFIG_NUMA
-	//parent = &node_devices[cpu_to_node(num)].node;
-#endif
-
-	return register_cpu(&per_cpu(cpu_devices,num).cpu, num, parent);
-}
-
-static int __init topology_init(void)
-{
-    int i;
-
-    for_each_cpu(i) {
-        arch_register_cpu(i);
-	}
-    return 0;
-}
-
-subsys_initcall(topology_init);
diff -Nru a/arch/ia64/hp/common/Makefile b/arch/ia64/hp/common/Makefile
--- a/arch/ia64/hp/common/Makefile	2005-03-01 23:39:09 -08:00
+++ b/arch/ia64/hp/common/Makefile	2005-03-01 23:39:09 -08:00
@@ -6,3 +6,5 @@
 #
 
 obj-y := sba_iommu.o
+obj-$(CONFIG_IA64_HP_ZX1_SWIOTLB) += hwsw_iommu.o
+obj-$(CONFIG_IA64_GENERIC) += hwsw_iommu.o
diff -Nru a/arch/ia64/hp/common/hwsw_iommu.c b/arch/ia64/hp/common/hwsw_iommu.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/ia64/hp/common/hwsw_iommu.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,185 @@
+/*
+ * Copyright (c) 2004 Hewlett-Packard Development Company, L.P.
+ *   Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+ *
+ * This is a pseudo I/O MMU which dispatches to the hardware I/O MMU
+ * whenever possible.  We assume that the hardware I/O MMU requires
+ * full 32-bit addressability, as is the case, e.g., for HP zx1-based
+ * systems (there, the I/O MMU window is mapped at 3-4GB).  If a
+ * device doesn't provide full 32-bit addressability, we fall back on
+ * the sw I/O TLB.  This is good enough to let us support broken
+ * hardware such as soundcards which have a DMA engine that can
+ * address only 28 bits.
+ */
+
+#include <linux/device.h>
+
+#include <asm/machvec.h>
+
+/* swiotlb declarations & definitions: */
+extern void swiotlb_init_with_default_size (size_t size);
+extern ia64_mv_dma_alloc_coherent	swiotlb_alloc_coherent;
+extern ia64_mv_dma_free_coherent	swiotlb_free_coherent;
+extern ia64_mv_dma_map_single		swiotlb_map_single;
+extern ia64_mv_dma_unmap_single		swiotlb_unmap_single;
+extern ia64_mv_dma_map_sg		swiotlb_map_sg;
+extern ia64_mv_dma_unmap_sg		swiotlb_unmap_sg;
+extern ia64_mv_dma_supported		swiotlb_dma_supported;
+extern ia64_mv_dma_mapping_error	swiotlb_dma_mapping_error;
+
+/* hwiommu declarations & definitions: */
+
+extern ia64_mv_dma_alloc_coherent	sba_alloc_coherent;
+extern ia64_mv_dma_free_coherent	sba_free_coherent;
+extern ia64_mv_dma_map_single		sba_map_single;
+extern ia64_mv_dma_unmap_single		sba_unmap_single;
+extern ia64_mv_dma_map_sg		sba_map_sg;
+extern ia64_mv_dma_unmap_sg		sba_unmap_sg;
+extern ia64_mv_dma_supported		sba_dma_supported;
+extern ia64_mv_dma_mapping_error	sba_dma_mapping_error;
+
+#define hwiommu_alloc_coherent		sba_alloc_coherent
+#define hwiommu_free_coherent		sba_free_coherent
+#define hwiommu_map_single		sba_map_single
+#define hwiommu_unmap_single		sba_unmap_single
+#define hwiommu_map_sg			sba_map_sg
+#define hwiommu_unmap_sg		sba_unmap_sg
+#define hwiommu_dma_supported		sba_dma_supported
+#define hwiommu_dma_mapping_error	sba_dma_mapping_error
+#define hwiommu_sync_single_for_cpu	machvec_dma_sync_single
+#define hwiommu_sync_sg_for_cpu		machvec_dma_sync_sg
+#define hwiommu_sync_single_for_device	machvec_dma_sync_single
+#define hwiommu_sync_sg_for_device	machvec_dma_sync_sg
+
+
+/*
+ * Note: we need to make the determination of whether or not to use
+ * the sw I/O TLB based purely on the device structure.  Anything else
+ * would be unreliable or would be too intrusive.
+ */
+static inline int
+use_swiotlb (struct device *dev)
+{
+	return dev && dev->dma_mask && !hwiommu_dma_supported(dev, *dev->dma_mask);
+}
+
+void
+hwsw_init (void)
+{
+	/* default to a smallish 2MB sw I/O TLB */
+	swiotlb_init_with_default_size (2 * (1<<20));
+}
+
+void *
+hwsw_alloc_coherent (struct device *dev, size_t size, dma_addr_t *dma_handle, int flags)
+{
+	if (use_swiotlb(dev))
+		return swiotlb_alloc_coherent(dev, size, dma_handle, flags);
+	else
+		return hwiommu_alloc_coherent(dev, size, dma_handle, flags);
+}
+
+void
+hwsw_free_coherent (struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle)
+{
+	if (use_swiotlb(dev))
+		swiotlb_free_coherent(dev, size, vaddr, dma_handle);
+	else
+		hwiommu_free_coherent(dev, size, vaddr, dma_handle);
+}
+
+dma_addr_t
+hwsw_map_single (struct device *dev, void *addr, size_t size, int dir)
+{
+	if (use_swiotlb(dev))
+		return swiotlb_map_single(dev, addr, size, dir);
+	else
+		return hwiommu_map_single(dev, addr, size, dir);
+}
+
+void
+hwsw_unmap_single (struct device *dev, dma_addr_t iova, size_t size, int dir)
+{
+	if (use_swiotlb(dev))
+		return swiotlb_unmap_single(dev, iova, size, dir);
+	else
+		return hwiommu_unmap_single(dev, iova, size, dir);
+}
+
+
+int
+hwsw_map_sg (struct device *dev, struct scatterlist *sglist, int nents, int dir)
+{
+	if (use_swiotlb(dev))
+		return swiotlb_map_sg(dev, sglist, nents, dir);
+	else
+		return hwiommu_map_sg(dev, sglist, nents, dir);
+}
+
+void
+hwsw_unmap_sg (struct device *dev, struct scatterlist *sglist, int nents, int dir)
+{
+	if (use_swiotlb(dev))
+		return swiotlb_unmap_sg(dev, sglist, nents, dir);
+	else
+		return hwiommu_unmap_sg(dev, sglist, nents, dir);
+}
+
+void
+hwsw_sync_single_for_cpu (struct device *dev, dma_addr_t addr, size_t size, int dir)
+{
+	if (use_swiotlb(dev))
+		swiotlb_sync_single_for_cpu(dev, addr, size, dir);
+	else
+		hwiommu_sync_single_for_cpu(dev, addr, size, dir);
+}
+
+void
+hwsw_sync_sg_for_cpu (struct device *dev, struct scatterlist *sg, int nelems, int dir)
+{
+	if (use_swiotlb(dev))
+		swiotlb_sync_sg_for_cpu(dev, sg, nelems, dir);
+	else
+		hwiommu_sync_sg_for_cpu(dev, sg, nelems, dir);
+}
+
+void
+hwsw_sync_single_for_device (struct device *dev, dma_addr_t addr, size_t size, int dir)
+{
+	if (use_swiotlb(dev))
+		swiotlb_sync_single_for_device(dev, addr, size, dir);
+	else
+		hwiommu_sync_single_for_device(dev, addr, size, dir);
+}
+
+void
+hwsw_sync_sg_for_device (struct device *dev, struct scatterlist *sg, int nelems, int dir)
+{
+	if (use_swiotlb(dev))
+		swiotlb_sync_sg_for_device(dev, sg, nelems, dir);
+	else
+		hwiommu_sync_sg_for_device(dev, sg, nelems, dir);
+}
+
+int
+hwsw_dma_supported (struct device *dev, u64 mask)
+{
+	if (hwiommu_dma_supported(dev, mask))
+		return 1;
+	return swiotlb_dma_supported(dev, mask);
+}
+
+int
+hwsw_dma_mapping_error (dma_addr_t dma_addr)
+{
+	return hwiommu_dma_mapping_error (dma_addr) || swiotlb_dma_mapping_error(dma_addr);
+}
+
+EXPORT_SYMBOL(hwsw_dma_mapping_error);
+EXPORT_SYMBOL(hwsw_map_single);
+EXPORT_SYMBOL(hwsw_unmap_single);
+EXPORT_SYMBOL(hwsw_map_sg);
+EXPORT_SYMBOL(hwsw_unmap_sg);
+EXPORT_SYMBOL(hwsw_dma_supported);
+EXPORT_SYMBOL(hwsw_alloc_coherent);
+EXPORT_SYMBOL(hwsw_free_coherent);
diff -Nru a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c
--- a/arch/ia64/hp/common/sba_iommu.c	2005-03-01 23:38:53 -08:00
+++ b/arch/ia64/hp/common/sba_iommu.c	2005-03-01 23:38:53 -08:00
@@ -1557,7 +1557,7 @@
 	** We program the next pdir index after we stop w/ a key for
 	** the GART code to handshake on.
 	*/
-	while ((device = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, device)) != NULL)
+	for_each_pci_dev(device)	
 		agp_found |= pci_find_capability(device, PCI_CAP_ID_AGP);
 
 	if (agp_found && reserve_sba_gart) {
diff -Nru a/arch/ia64/hp/sim/simeth.c b/arch/ia64/hp/sim/simeth.c
--- a/arch/ia64/hp/sim/simeth.c	2005-03-01 23:39:07 -08:00
+++ b/arch/ia64/hp/sim/simeth.c	2005-03-01 23:39:07 -08:00
@@ -286,7 +286,7 @@
 static int
 simeth_device_event(struct notifier_block *this,unsigned long event, void *ptr)
 {
-	struct net_device *dev = (struct net_device *)ptr;
+	struct net_device *dev = ptr;
 	struct simeth_local *local;
 	struct in_device *in_dev;
 	struct in_ifaddr **ifap = NULL;
@@ -382,7 +382,7 @@
 static int
 simeth_tx(struct sk_buff *skb, struct net_device *dev)
 {
-	struct simeth_local *local = (struct simeth_local *)dev->priv;
+	struct simeth_local *local = dev->priv;
 
 #if 0
 	/* ensure we have at least ETH_ZLEN bytes (min frame size) */
@@ -446,7 +446,7 @@
 	int			len;
 	int			rcv_count = SIMETH_RECV_MAX;
 
-	local = (struct simeth_local *)dev->priv;
+	local = dev->priv;
 	/*
 	 * the loop concept has been borrowed from other drivers
 	 * looks to me like it's a throttling thing to avoid pushing to many
@@ -515,7 +515,7 @@
 static struct net_device_stats *
 simeth_get_stats(struct net_device *dev)
 {
-	struct simeth_local  *local = (struct simeth_local *) dev->priv;
+	struct simeth_local *local = dev->priv;
 
 	return &local->stats;
 }
diff -Nru a/arch/ia64/hp/zx1/Makefile b/arch/ia64/hp/zx1/Makefile
--- a/arch/ia64/hp/zx1/Makefile	2005-03-01 23:39:17 -08:00
+++ b/arch/ia64/hp/zx1/Makefile	2005-03-01 23:39:17 -08:00
@@ -5,4 +5,4 @@
 # Copyright (C) Alex Williamson (alex_williamson@hp.com)
 #
 
-obj-$(CONFIG_IA64_GENERIC) += hpzx1_machvec.o
+obj-$(CONFIG_IA64_GENERIC) += hpzx1_machvec.o hpzx1_swiotlb_machvec.o
diff -Nru a/arch/ia64/hp/zx1/hpzx1_swiotlb_machvec.c b/arch/ia64/hp/zx1/hpzx1_swiotlb_machvec.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/ia64/hp/zx1/hpzx1_swiotlb_machvec.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,3 @@
+#define MACHVEC_PLATFORM_NAME		hpzx1_swiotlb
+#define MACHVEC_PLATFORM_HEADER		<asm/machvec_hpzx1_swiotlb.h>
+#include <asm/machvec_init.h>
diff -Nru a/arch/ia64/ia32/binfmt_elf32.c b/arch/ia64/ia32/binfmt_elf32.c
--- a/arch/ia64/ia32/binfmt_elf32.c	2005-03-01 23:39:16 -08:00
+++ b/arch/ia64/ia32/binfmt_elf32.c	2005-03-01 23:39:16 -08:00
@@ -35,7 +35,7 @@
 
 static void elf32_set_personality (void);
 
-#define setup_arg_pages(bprm,exec)		ia32_setup_arg_pages(bprm,exec)
+#define setup_arg_pages(bprm,tos,exec)		ia32_setup_arg_pages(bprm,exec)
 #define elf_map				elf32_map
 
 #undef SET_PERSONALITY
@@ -103,7 +103,7 @@
 			if (insert_vm_struct(current->mm, vma)) {
 				kmem_cache_free(vm_area_cachep, vma);
 				up_write(&current->mm->mmap_sem);
-				return;
+				BUG();
 			}
 		}
 		up_write(&current->mm->mmap_sem);
@@ -130,7 +130,7 @@
 			if (insert_vm_struct(current->mm, vma)) {
 				kmem_cache_free(vm_area_cachep, vma);
 				up_write(&current->mm->mmap_sem);
-				return;
+				BUG();
 			}
 		}
 		up_write(&current->mm->mmap_sem);
@@ -153,7 +153,7 @@
 			if (insert_vm_struct(current->mm, vma)) {
 				kmem_cache_free(vm_area_cachep, vma);
 				up_write(&current->mm->mmap_sem);
-				return;
+				BUG();
 			}
 		}
 		up_write(&current->mm->mmap_sem);
diff -Nru a/arch/ia64/ia32/elfcore32.h b/arch/ia64/ia32/elfcore32.h
--- a/arch/ia64/ia32/elfcore32.h	2005-03-01 23:38:57 -08:00
+++ b/arch/ia64/ia32/elfcore32.h	2005-03-01 23:38:57 -08:00
@@ -106,7 +106,7 @@
 	struct ia32_user_i387_struct *fpstate = (void*)fpu;
 	mm_segment_t old_fs;
 
-	if (!tsk->used_math)
+	if (!tsk_used_math(tsk))
 		return 0;
 	
 	old_fs = get_fs();
@@ -124,7 +124,7 @@
 	struct ia32_user_fxsr_struct *fpxstate = (void*) xfpu;
 	mm_segment_t old_fs;
 
-	if (!tsk->used_math)
+	if (!tsk_used_math(tsk))
 		return 0;
 
 	old_fs = get_fs();
diff -Nru a/arch/ia64/ia32/ia32_entry.S b/arch/ia64/ia32/ia32_entry.S
--- a/arch/ia64/ia32/ia32_entry.S	2005-03-01 23:38:58 -08:00
+++ b/arch/ia64/ia32/ia32_entry.S	2005-03-01 23:38:58 -08:00
@@ -223,7 +223,7 @@
 	data8 sys_unlink	  /* 10 */
 	data8 ia32_execve
 	data8 sys_chdir
-	data8 sys32_time
+	data8 compat_sys_time
 	data8 sys_mknod
 	data8 sys_chmod		  /* 15 */
 	data8 sys_lchown	/* 16-bit version */
@@ -235,7 +235,7 @@
 	data8 sys_oldumount
 	data8 sys_setuid	/* 16-bit version */
 	data8 sys_getuid	/* 16-bit version */
-	data8 sys_ni_syscall	/* sys_stime is not supported on IA64 */  /* 25 */
+	data8 compat_sys_stime    /* 25 */
 	data8 sys32_ptrace
 	data8 sys32_alarm
 	data8 sys_ni_syscall
@@ -387,7 +387,7 @@
 	data8 sys32_rt_sigaction
 	data8 sys32_rt_sigprocmask /* 175 */
 	data8 sys_rt_sigpending
-	data8 sys32_rt_sigtimedwait
+	data8 compat_sys_rt_sigtimedwait
 	data8 sys32_rt_sigqueueinfo
 	data8 sys32_rt_sigsuspend
 	data8 sys32_pread	  /* 180 */
diff -Nru a/arch/ia64/ia32/ia32_signal.c b/arch/ia64/ia32/ia32_signal.c
--- a/arch/ia64/ia32/ia32_signal.c	2005-03-01 23:38:51 -08:00
+++ b/arch/ia64/ia32/ia32_signal.c	2005-03-01 23:38:51 -08:00
@@ -1,7 +1,7 @@
 /*
  * IA32 Architecture-specific signal handling support.
  *
- * Copyright (C) 1999, 2001-2002 Hewlett-Packard Co
+ * Copyright (C) 1999, 2001-2002, 2005 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  * Copyright (C) 1999 Arun Sharma <arun.sharma@intel.com>
  * Copyright (C) 2000 VA Linux Co
@@ -59,19 +59,19 @@
        int sig;
        int pinfo;
        int puc;
-       siginfo_t32 info;
+       compat_siginfo_t info;
        struct ucontext_ia32 uc;
        struct _fpstate_ia32 fpstate;
        char retcode[8];
 };
 
 int
-copy_siginfo_from_user32 (siginfo_t *to, siginfo_t32 __user *from)
+copy_siginfo_from_user32 (siginfo_t *to, compat_siginfo_t __user *from)
 {
 	unsigned long tmp;
 	int err;
 
-	if (!access_ok(VERIFY_READ, from, sizeof(siginfo_t32)))
+	if (!access_ok(VERIFY_READ, from, sizeof(compat_siginfo_t)))
 		return -EFAULT;
 
 	err = __get_user(to->si_signo, &from->si_signo);
@@ -110,12 +110,12 @@
 }
 
 int
-copy_siginfo_to_user32 (siginfo_t32 __user *to, siginfo_t *from)
+copy_siginfo_to_user32 (compat_siginfo_t __user *to, siginfo_t *from)
 {
 	unsigned int addr;
 	int err;
 
-	if (!access_ok(VERIFY_WRITE, to, sizeof(siginfo_t32)))
+	if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
 		return -EFAULT;
 
 	/* If you change siginfo_t structure, please be sure
@@ -589,34 +589,7 @@
 }
 
 asmlinkage long
-sys32_rt_sigtimedwait (compat_sigset_t __user *uthese, siginfo_t32 __user *uinfo,
-		       struct compat_timespec __user *uts, unsigned int sigsetsize)
-{
-	mm_segment_t old_fs = get_fs();
-	struct timespec t;
-	siginfo_t info;
-	sigset_t s;
-	int ret;
-
-	if (copy_from_user(&s.sig, uthese, sizeof(compat_sigset_t)))
-		return -EFAULT;
-	if (uts && get_compat_timespec(&t, uts))
-		return -EFAULT;
-	set_fs(KERNEL_DS);
-	ret = sys_rt_sigtimedwait((sigset_t __user *) &s,
-				  uinfo ? (siginfo_t __user *) &info : NULL,
-				  uts ? (struct timespec __user *) &t : NULL,
-				  sigsetsize);
-	set_fs(old_fs);
-	if (ret >= 0 && uinfo) {
-		if (copy_siginfo_to_user32(uinfo, &info))
-			return -EFAULT;
-	}
-	return ret;
-}
-
-asmlinkage long
-sys32_rt_sigqueueinfo (int pid, int sig, siginfo_t32 __user *uinfo)
+sys32_rt_sigqueueinfo (int pid, int sig, compat_siginfo_t __user *uinfo)
 {
 	mm_segment_t old_fs = get_fs();
 	siginfo_t info;
@@ -997,11 +970,10 @@
 }
 
 asmlinkage long
-sys32_sigreturn (int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7,
-		 unsigned long stack)
+sys32_sigreturn (int arg0, int arg1, int arg2, int arg3, int arg4, int arg5,
+		 int arg6, int arg7, struct pt_regs regs)
 {
-	struct pt_regs *regs = (struct pt_regs *) &stack;
-	unsigned long esp = (unsigned int) regs->r12;
+	unsigned long esp = (unsigned int) regs.r12;
 	struct sigframe_ia32 __user *frame = (struct sigframe_ia32 __user *)(esp - 8);
 	sigset_t set;
 	int eax;
@@ -1020,7 +992,7 @@
 	recalc_sigpending();
 	spin_unlock_irq(&current->sighand->siglock);
 
-	if (restore_sigcontext_ia32(regs, &frame->sc, &eax))
+	if (restore_sigcontext_ia32(&regs, &frame->sc, &eax))
 		goto badframe;
 	return eax;
 
@@ -1030,11 +1002,10 @@
 }
 
 asmlinkage long
-sys32_rt_sigreturn (int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7,
-		    unsigned long stack)
+sys32_rt_sigreturn (int arg0, int arg1, int arg2, int arg3, int arg4,
+		    int arg5, int arg6, int arg7, struct pt_regs regs)
 {
-	struct pt_regs *regs = (struct pt_regs *) &stack;
-	unsigned long esp = (unsigned int) regs->r12;
+	unsigned long esp = (unsigned int) regs.r12;
 	struct rt_sigframe_ia32 __user *frame = (struct rt_sigframe_ia32 __user *)(esp - 4);
 	sigset_t set;
 	int eax;
@@ -1050,7 +1021,7 @@
 	recalc_sigpending();
 	spin_unlock_irq(&current->sighand->siglock);
 
-	if (restore_sigcontext_ia32(regs, &frame->uc.uc_mcontext, &eax))
+	if (restore_sigcontext_ia32(&regs, &frame->uc.uc_mcontext, &eax))
 		goto badframe;
 
 	/* It is more difficult to avoid calling this function than to
diff -Nru a/arch/ia64/ia32/ia32priv.h b/arch/ia64/ia32/ia32priv.h
--- a/arch/ia64/ia32/ia32priv.h	2005-03-01 23:39:17 -08:00
+++ b/arch/ia64/ia32/ia32priv.h	2005-03-01 23:39:17 -08:00
@@ -232,7 +232,7 @@
 
 #define SIGEV_PAD_SIZE32 ((SIGEV_MAX_SIZE/sizeof(int)) - 3)
 
-typedef struct siginfo32 {
+typedef struct compat_siginfo {
 	int si_signo;
 	int si_errno;
 	int si_code;
@@ -282,7 +282,7 @@
 			int _fd;
 		} _sigpoll;
 	} _sifields;
-} siginfo_t32;
+} compat_siginfo_t;
 
 typedef struct sigevent32 {
 	sigval_t32 sigev_value;
@@ -558,10 +558,6 @@
 /* Prototypes for use in elfcore32.h */
 extern int save_ia32_fpstate (struct task_struct *, struct ia32_user_i387_struct __user *);
 extern int save_ia32_fpxstate (struct task_struct *, struct ia32_user_fxsr_struct __user *);
-
-/* Prototypes for use in sys_ia32.c */
-int copy_siginfo_to_user32 (siginfo_t32 __user *to, siginfo_t *from);
-int copy_siginfo_from_user32 (siginfo_t *to, siginfo_t32 __user *from);
 
 #endif /* !CONFIG_IA32_SUPPORT */
 
diff -Nru a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c
--- a/arch/ia64/ia32/sys_ia32.c	2005-03-01 23:39:06 -08:00
+++ b/arch/ia64/ia32/sys_ia32.c	2005-03-01 23:39:06 -08:00
@@ -6,7 +6,7 @@
  * Copyright (C) 1999		Arun Sharma <arun.sharma@intel.com>
  * Copyright (C) 1997,1998	Jakub Jelinek (jj@sunsite.mff.cuni.cz)
  * Copyright (C) 1997		David S. Miller (davem@caip.rutgers.edu)
- * Copyright (C) 2000-2003 Hewlett-Packard Co
+ * Copyright (C) 2000-2003, 2005 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  * Copyright (C) 2004		Gordon Jin <gordon.jin@intel.com>
  *
@@ -1415,7 +1415,7 @@
 	      case SHMDT:
 		return sys_shmdt(compat_ptr(ptr));
 	      case SHMGET:
-		return sys_shmget(first, second, third);
+		return sys_shmget(first, (unsigned)second, third);
 	      case SHMCTL:
 		return compat_sys_shmctl(first, second, compat_ptr(ptr));
 
@@ -1425,27 +1425,6 @@
 	return -EINVAL;
 }
 
-/*
- * sys_time() can be implemented in user-level using
- * sys_gettimeofday().  IA64 did this but i386 Linux did not
- * so we have to implement this system call here.
- */
-asmlinkage long
-sys32_time (int __user *tloc)
-{
-	int i;
-	struct timeval tv;
-
-	do_gettimeofday(&tv);
-	i = tv.tv_sec;
-
-	if (tloc) {
-		if (put_user(i, tloc))
-			i = -EFAULT;
-	}
-	return i;
-}
-
 asmlinkage long
 compat_sys_wait4 (compat_pid_t pid, compat_uint_t * stat_addr, int options,
 		 struct compat_rusage *ru);
@@ -1457,7 +1436,7 @@
 }
 
 static unsigned int
-ia32_peek (struct pt_regs *regs, struct task_struct *child, unsigned long addr, unsigned int *val)
+ia32_peek (struct task_struct *child, unsigned long addr, unsigned int *val)
 {
 	size_t copied;
 	unsigned int ret;
@@ -1467,7 +1446,7 @@
 }
 
 static unsigned int
-ia32_poke (struct pt_regs *regs, struct task_struct *child, unsigned long addr, unsigned int val)
+ia32_poke (struct task_struct *child, unsigned long addr, unsigned int val)
 {
 
 	if (access_process_vm(child, addr, &val, sizeof(val), 1) != sizeof(val))
@@ -1772,25 +1751,16 @@
 	return 0;
 }
 
-/*
- *  Note that the IA32 version of `ptrace' calls the IA64 routine for
- *    many of the requests.  This will only work for requests that do
- *    not need access to the calling processes `pt_regs' which is located
- *    at the address of `stack'.  Once we call the IA64 `sys_ptrace' then
- *    the address of `stack' will not be the address of the `pt_regs'.
- */
 asmlinkage long
-sys32_ptrace (int request, pid_t pid, unsigned int addr, unsigned int data,
-	      long arg4, long arg5, long arg6, long arg7, long stack)
+sys32_ptrace (int request, pid_t pid, unsigned int addr, unsigned int data)
 {
-	struct pt_regs *regs = (struct pt_regs *) &stack;
 	struct task_struct *child;
 	unsigned int value, tmp;
 	long i, ret;
 
 	lock_kernel();
 	if (request == PTRACE_TRACEME) {
-		ret = sys_ptrace(request, pid, addr, data, arg4, arg5, arg6, arg7, stack);
+		ret = sys_ptrace(request, pid, addr, data);
 		goto out;
 	}
 
@@ -1807,7 +1777,7 @@
 		goto out_tsk;
 
 	if (request == PTRACE_ATTACH) {
-		ret = sys_ptrace(request, pid, addr, data, arg4, arg5, arg6, arg7, stack);
+		ret = sys_ptrace(request, pid, addr, data);
 		goto out_tsk;
 	}
 
@@ -1818,7 +1788,7 @@
 	switch (request) {
 	      case PTRACE_PEEKTEXT:
 	      case PTRACE_PEEKDATA:	/* read word at location addr */
-		ret = ia32_peek(regs, child, addr, &value);
+		ret = ia32_peek(child, addr, &value);
 		if (ret == 0)
 			ret = put_user(value, (unsigned int __user *) compat_ptr(data));
 		else
@@ -1827,7 +1797,7 @@
 
 	      case PTRACE_POKETEXT:
 	      case PTRACE_POKEDATA:	/* write the word at location addr */
-		ret = ia32_poke(regs, child, addr, data);
+		ret = ia32_poke(child, addr, data);
 		goto out_tsk;
 
 	      case PTRACE_PEEKUSR:	/* read word at addr in USER area */
@@ -1894,12 +1864,16 @@
 					    compat_ptr(data));
 		break;
 
+	      case PTRACE_GETEVENTMSG:   
+		ret = put_user(child->ptrace_message, (unsigned int __user *) compat_ptr(data));
+		break;
+
 	      case PTRACE_SYSCALL:	/* continue, stop after next syscall */
 	      case PTRACE_CONT:		/* restart after signal. */
 	      case PTRACE_KILL:
 	      case PTRACE_SINGLESTEP:	/* execute chile for one instruction */
 	      case PTRACE_DETACH:	/* detach a process */
-		ret = sys_ptrace(request, pid, addr, data, arg4, arg5, arg6, arg7, stack);
+		ret = sys_ptrace(request, pid, addr, data);
 		break;
 
 	      default:
@@ -1922,9 +1896,9 @@
 
 asmlinkage long
 sys32_sigaltstack (ia32_stack_t __user *uss32, ia32_stack_t __user *uoss32,
-		   long arg2, long arg3, long arg4, long arg5, long arg6, long arg7, long stack)
+		   long arg2, long arg3, long arg4, long arg5, long arg6,
+		   long arg7, struct pt_regs pt)
 {
-	struct pt_regs *pt = (struct pt_regs *) &stack;
 	stack_t uss, uoss;
 	ia32_stack_t buf32;
 	int ret;
@@ -1945,7 +1919,7 @@
 	}
 	set_fs(KERNEL_DS);
 	ret = do_sigaltstack(uss32 ? (stack_t __user *) &uss : NULL,
-			     (stack_t __user *) &uoss, pt->r12);
+			     (stack_t __user *) &uoss, pt.r12);
  	current->sas_ss_size = buf32.ss_size;
 	set_fs(old_fs);
 out:
@@ -1990,10 +1964,10 @@
 	unsigned int	__unused[4];
 };
 
+#ifdef CONFIG_SYSCTL
 asmlinkage long
 sys32_sysctl (struct sysctl32 __user *args)
 {
-#ifdef CONFIG_SYSCTL
 	struct sysctl32 a32;
 	mm_segment_t old_fs = get_fs ();
 	void __user *oldvalp, *newvalp;
@@ -2032,10 +2006,8 @@
 		return -EFAULT;
 
 	return ret;
-#else
-	return -ENOSYS;
-#endif
 }
+#endif
 
 asmlinkage long
 sys32_newuname (struct new_utsname __user *name)
@@ -2662,7 +2634,7 @@
 } 
 
 asmlinkage long sys32_waitid(int which, compat_pid_t pid,
-			     siginfo_t32 __user *uinfo, int options,
+			     compat_siginfo_t __user *uinfo, int options,
 			     struct compat_rusage __user *uru)
 {
 	siginfo_t info;
@@ -2673,7 +2645,7 @@
 	info.si_signo = 0;
 	set_fs (KERNEL_DS);
 	ret = sys_waitid(which, pid, (siginfo_t __user *) &info, options,
-			 uru ? &ru : NULL);
+			 uru ? (struct rusage __user *) &ru : NULL);
 	set_fs (old_fs);
 
 	if (ret < 0 || info.si_signo == 0)
diff -Nru a/arch/ia64/kernel/Makefile b/arch/ia64/kernel/Makefile
--- a/arch/ia64/kernel/Makefile	2005-03-01 23:39:17 -08:00
+++ b/arch/ia64/kernel/Makefile	2005-03-01 23:39:17 -08:00
@@ -6,11 +6,13 @@
 
 obj-y := acpi.o entry.o efi.o efi_stub.o gate-data.o fsys.o ia64_ksyms.o irq.o irq_ia64.o	\
 	 irq_lsapic.o ivt.o machvec.o pal.o patch.o process.o perfmon.o ptrace.o sal.o		\
-	 salinfo.o semaphore.o setup.o signal.o sys_ia64.o time.o traps.o unaligned.o unwind.o mca.o mca_asm.o
+	 salinfo.o semaphore.o setup.o signal.o sys_ia64.o time.o traps.o unaligned.o \
+	 unwind.o mca.o mca_asm.o topology.o
 
 obj-$(CONFIG_IA64_BRL_EMU)	+= brl_emu.o
 obj-$(CONFIG_IA64_GENERIC)	+= acpi-ext.o
 obj-$(CONFIG_IA64_HP_ZX1)	+= acpi-ext.o
+obj-$(CONFIG_IA64_HP_ZX1_SWIOTLB) += acpi-ext.o
 obj-$(CONFIG_IA64_PALINFO)	+= palinfo.o
 obj-$(CONFIG_IOSAPIC)		+= iosapic.o
 obj-$(CONFIG_MODULES)		+= module.o
diff -Nru a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c
--- a/arch/ia64/kernel/acpi.c	2005-03-01 23:38:57 -08:00
+++ b/arch/ia64/kernel/acpi.c	2005-03-01 23:38:57 -08:00
@@ -113,6 +113,8 @@
 	return "hpsim";
 # elif defined (CONFIG_IA64_HP_ZX1)
 	return "hpzx1";
+# elif defined (CONFIG_IA64_HP_ZX1_SWIOTLB)
+	return "hpzx1_swiotlb";
 # elif defined (CONFIG_IA64_SGI_SN2)
 	return "sn2";
 # elif defined (CONFIG_IA64_DIG)
@@ -355,11 +357,11 @@
 #define PXM_FLAG_LEN ((MAX_PXM_DOMAINS + 1)/32)
 
 static int __initdata srat_num_cpus;			/* number of cpus */
-static u32 __initdata pxm_flag[PXM_FLAG_LEN];
+static u32 __devinitdata pxm_flag[PXM_FLAG_LEN];
 #define pxm_bit_set(bit)	(set_bit(bit,(void *)pxm_flag))
 #define pxm_bit_test(bit)	(test_bit(bit,(void *)pxm_flag))
 /* maps to convert between proximity domain and logical node ID */
-int __initdata pxm_to_nid_map[MAX_PXM_DOMAINS];
+int __devinitdata pxm_to_nid_map[MAX_PXM_DOMAINS];
 int __initdata nid_to_pxm_map[MAX_NUMNODES];
 static struct acpi_table_slit __initdata *slit_table;
 
@@ -445,16 +447,20 @@
 		return;
 	}
 
+	/*
+	 * MCD - This can probably be dropped now.  No need for pxm ID to node ID
+	 * mapping with sparse node numbering iff MAX_PXM_DOMAINS <= MAX_NUMNODES.
+	 */
 	/* calculate total number of nodes in system from PXM bitmap */
-	numnodes = 0;		/* init total nodes in system */
-
 	memset(pxm_to_nid_map, -1, sizeof(pxm_to_nid_map));
 	memset(nid_to_pxm_map, -1, sizeof(nid_to_pxm_map));
+	nodes_clear(node_online_map);
 	for (i = 0; i < MAX_PXM_DOMAINS; i++) {
 		if (pxm_bit_test(i)) {
-			pxm_to_nid_map[i] = numnodes;
-			node_set_online(numnodes);
-			nid_to_pxm_map[numnodes++] = i;
+			int nid = num_online_nodes();
+			pxm_to_nid_map[i] = nid;
+			nid_to_pxm_map[nid] = i;
+			node_set_online(nid);
 		}
 	}
 
@@ -463,7 +469,7 @@
 		node_memblk[i].nid = pxm_to_nid_map[node_memblk[i].nid];
 
 	/* assign memory bank numbers for each chunk on each node */
-	for (i = 0; i < numnodes; i++) {
+	for_each_online_node(i) {
 		int bank;
 
 		bank = 0;
@@ -476,7 +482,7 @@
 	for (i = 0; i < srat_num_cpus; i++)
 		node_cpuid[i].nid = pxm_to_nid_map[node_cpuid[i].nid];
 
-	printk(KERN_INFO "Number of logical nodes in system = %d\n", numnodes);
+	printk(KERN_INFO "Number of logical nodes in system = %d\n", num_online_nodes());
 	printk(KERN_INFO "Number of memory chunks in system = %d\n", num_node_memblks);
 
 	if (!slit_table) return;
@@ -496,8 +502,8 @@
 
 #ifdef SLIT_DEBUG
 	printk("ACPI 2.0 SLIT locality table:\n");
-	for (i = 0; i < numnodes; i++) {
-		for (j = 0; j < numnodes; j++)
+	for_each_online_node(i) {
+		for_each_online_node(j)
 			printk("%03d ", node_distance(i,j));
 		printk("\n");
 	}
@@ -517,6 +523,15 @@
 }
 EXPORT_SYMBOL(acpi_register_gsi);
 
+#ifdef CONFIG_ACPI_DEALLOCATE_IRQ
+void
+acpi_unregister_gsi (u32 gsi)
+{
+	iosapic_unregister_intr(gsi);
+}
+EXPORT_SYMBOL(acpi_unregister_gsi);
+#endif /* CONFIG_ACPI_DEALLOCATE_IRQ */
+
 static int __init
 acpi_parse_fadt (unsigned long phys_addr, unsigned long size)
 {
@@ -651,6 +666,110 @@
 	}
 	return 0;
 }
+
+/*
+ *  ACPI based hotplug CPU support
+ */
+#ifdef CONFIG_ACPI_HOTPLUG_CPU
+static
+int
+acpi_map_cpu2node(acpi_handle handle, int cpu, long physid)
+{
+#ifdef CONFIG_ACPI_NUMA
+	int 			pxm_id;
+
+	pxm_id = acpi_get_pxm(handle);
+
+	/*
+	 * Assuming that the container driver would have set the proximity
+	 * domain and would have initialized pxm_to_nid_map[pxm_id] && pxm_flag
+	 */
+	node_cpuid[cpu].nid = (pxm_id < 0) ? 0:
+			pxm_to_nid_map[pxm_id];
+
+	node_cpuid[cpu].phys_id =  physid;
+#endif
+	return(0);
+}
+
+
+int
+acpi_map_lsapic(acpi_handle handle, int *pcpu)
+{
+	struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+	union acpi_object *obj;
+	struct acpi_table_lsapic *lsapic;
+	cpumask_t tmp_map;
+	long physid;
+	int cpu;
+ 
+	if (ACPI_FAILURE(acpi_evaluate_object(handle, "_MAT", NULL, &buffer)))
+		return -EINVAL;
+
+	if (!buffer.length ||  !buffer.pointer)
+		return -EINVAL;
+ 
+	obj = buffer.pointer;
+	if (obj->type != ACPI_TYPE_BUFFER ||
+	    obj->buffer.length < sizeof(*lsapic)) {
+		acpi_os_free(buffer.pointer);
+		return -EINVAL;
+	}
+
+	lsapic = (struct acpi_table_lsapic *)obj->buffer.pointer;
+
+	if ((lsapic->header.type != ACPI_MADT_LSAPIC) ||
+	    (!lsapic->flags.enabled)) {
+		acpi_os_free(buffer.pointer);
+		return -EINVAL;
+	}
+
+	physid = ((lsapic->id <<8) | (lsapic->eid));
+
+	acpi_os_free(buffer.pointer);
+	buffer.length = ACPI_ALLOCATE_BUFFER;
+	buffer.pointer = NULL;
+
+	cpus_complement(tmp_map, cpu_present_map);
+	cpu = first_cpu(tmp_map);
+	if(cpu >= NR_CPUS)
+		return -EINVAL;
+
+	acpi_map_cpu2node(handle, cpu, physid);
+
+ 	cpu_set(cpu, cpu_present_map);
+	ia64_cpu_to_sapicid[cpu] = physid;
+	ia64_acpiid_to_sapicid[lsapic->acpi_id] = ia64_cpu_to_sapicid[cpu];
+
+	*pcpu = cpu;
+	return(0);
+}
+EXPORT_SYMBOL(acpi_map_lsapic);
+
+
+int
+acpi_unmap_lsapic(int cpu)
+{
+	int i;
+
+	for (i=0; i<MAX_SAPICS; i++) {
+ 		if (ia64_acpiid_to_sapicid[i] == ia64_cpu_to_sapicid[cpu]) {
+ 			ia64_acpiid_to_sapicid[i] = -1;
+ 			break;
+ 		}
+ 	}
+	ia64_cpu_to_sapicid[cpu] = -1;
+	cpu_clear(cpu,cpu_present_map);
+
+#ifdef CONFIG_ACPI_NUMA
+	/* NUMA specific cleanup's */
+#endif
+
+	return(0);
+}
+EXPORT_SYMBOL(acpi_unmap_lsapic);
+#endif /* CONFIG_ACPI_HOTPLUG_CPU */
+ 
 
 #ifdef CONFIG_NUMA
 acpi_status __init
diff -Nru a/arch/ia64/kernel/asm-offsets.c b/arch/ia64/kernel/asm-offsets.c
--- a/arch/ia64/kernel/asm-offsets.c	2005-03-01 23:39:16 -08:00
+++ b/arch/ia64/kernel/asm-offsets.c	2005-03-01 23:39:16 -08:00
@@ -193,9 +193,17 @@
 	DEFINE(IA64_CLONE_VM, CLONE_VM);
 
 	BLANK();
-	DEFINE(IA64_CPUINFO_NSEC_PER_CYC_OFFSET, offsetof (struct cpuinfo_ia64, nsec_per_cyc));
-	DEFINE(IA64_TIMESPEC_TV_NSEC_OFFSET, offsetof (struct timespec, tv_nsec));
-
+	DEFINE(IA64_CPUINFO_NSEC_PER_CYC_OFFSET,
+	       offsetof (struct cpuinfo_ia64, nsec_per_cyc));
+	DEFINE(IA64_CPUINFO_PTCE_BASE_OFFSET,
+	       offsetof (struct cpuinfo_ia64, ptce_base));
+	DEFINE(IA64_CPUINFO_PTCE_COUNT_OFFSET,
+	       offsetof (struct cpuinfo_ia64, ptce_count));
+	DEFINE(IA64_CPUINFO_PTCE_STRIDE_OFFSET,
+	       offsetof (struct cpuinfo_ia64, ptce_stride));
+	BLANK();
+	DEFINE(IA64_TIMESPEC_TV_NSEC_OFFSET,
+	       offsetof (struct timespec, tv_nsec));
 
 	DEFINE(CLONE_SETTLS_BIT, 19);
 #if CLONE_SETTLS != (1<<19)
@@ -203,10 +211,16 @@
 #endif
 
 	BLANK();
-	DEFINE(IA64_MCA_TLB_INFO_SIZE, sizeof (struct ia64_mca_tlb_info));
-	/* used by head.S */
-	DEFINE(IA64_CPUINFO_NSEC_PER_CYC_OFFSET, offsetof (struct cpuinfo_ia64, nsec_per_cyc));
-
+	DEFINE(IA64_MCA_CPU_PROC_STATE_DUMP_OFFSET,
+	       offsetof (struct ia64_mca_cpu, proc_state_dump));
+	DEFINE(IA64_MCA_CPU_STACK_OFFSET,
+	       offsetof (struct ia64_mca_cpu, stack));
+	DEFINE(IA64_MCA_CPU_STACKFRAME_OFFSET,
+	       offsetof (struct ia64_mca_cpu, stackframe));
+	DEFINE(IA64_MCA_CPU_RBSTORE_OFFSET,
+	       offsetof (struct ia64_mca_cpu, rbstore));
+	DEFINE(IA64_MCA_CPU_INIT_STACK_OFFSET,
+	       offsetof (struct ia64_mca_cpu, init_stack));
 	BLANK();
 	/* used by fsys_gettimeofday in arch/ia64/kernel/fsys.S */
 	DEFINE(IA64_TIME_INTERPOLATOR_ADDRESS_OFFSET, offsetof (struct time_interpolator, addr));
diff -Nru a/arch/ia64/kernel/domain.c b/arch/ia64/kernel/domain.c
--- a/arch/ia64/kernel/domain.c	2005-03-01 23:39:17 -08:00
+++ b/arch/ia64/kernel/domain.c	2005-03-01 23:39:17 -08:00
@@ -12,6 +12,7 @@
 #include <linux/cpumask.h>
 #include <linux/init.h>
 #include <linux/topology.h>
+#include <linux/nodemask.h>
 
 #define SD_NODES_PER_DOMAIN 6
 
@@ -150,10 +151,9 @@
 	 * Set up domains. Isolated domains just stay on the dummy domain.
 	 */
 	for_each_cpu_mask(i, cpu_default_map) {
-		int node = cpu_to_node(i);
 		int group;
 		struct sched_domain *sd = NULL, *p;
-		cpumask_t nodemask = node_to_cpumask(node);
+		cpumask_t nodemask = node_to_cpumask(cpu_to_node(i));
 
 		cpus_and(nodemask, nodemask, cpu_default_map);
 
@@ -171,7 +171,7 @@
 
 		sd = &per_cpu(node_domains, i);
 		*sd = SD_NODE_INIT;
-		sd->span = sched_domain_node_span(node);
+		sd->span = sched_domain_node_span(cpu_to_node(i));
 		sd->parent = p;
 		cpus_and(sd->span, sd->span, cpu_default_map);
 #endif
diff -Nru a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c
--- a/arch/ia64/kernel/efi.c	2005-03-01 23:38:51 -08:00
+++ b/arch/ia64/kernel/efi.c	2005-03-01 23:38:51 -08:00
@@ -414,16 +414,15 @@
  * ITR to enable safe PAL calls in virtual mode.  See IA-64 Processor
  * Abstraction Layer chapter 11 in ADAG
  */
-void
-efi_map_pal_code (void)
+
+void *
+efi_get_pal_addr (void)
 {
 	void *efi_map_start, *efi_map_end, *p;
 	efi_memory_desc_t *md;
 	u64 efi_desc_size;
 	int pal_code_count = 0;
-	u64 mask, psr;
-	u64 vaddr;
-	int cpu;
+	u64 vaddr, mask;
 
 	efi_map_start = __va(ia64_boot_param->efi_memmap);
 	efi_map_end   = efi_map_start + ia64_boot_param->efi_memmap_size;
@@ -467,30 +466,39 @@
 		if (md->num_pages << EFI_PAGE_SHIFT > IA64_GRANULE_SIZE)
 			panic("Woah!  PAL code size bigger than a granule!");
 
-		mask  = ~((1 << IA64_GRANULE_SHIFT) - 1);
 #if EFI_DEBUG
+		mask  = ~((1 << IA64_GRANULE_SHIFT) - 1);
+
 		printk(KERN_INFO "CPU %d: mapping PAL code [0x%lx-0x%lx) into [0x%lx-0x%lx)\n",
-		       smp_processor_id(), md->phys_addr,
-		       md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT),
-		       vaddr & mask, (vaddr & mask) + IA64_GRANULE_SIZE);
+			smp_processor_id(), md->phys_addr,
+			md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT),
+			vaddr & mask, (vaddr & mask) + IA64_GRANULE_SIZE);
 #endif
-
-		/*
-		 * Cannot write to CRx with PSR.ic=1
-		 */
-		psr = ia64_clear_ic();
-		ia64_itr(0x1, IA64_TR_PALCODE, vaddr & mask,
-			 pte_val(pfn_pte(md->phys_addr >> PAGE_SHIFT, PAGE_KERNEL)),
-			 IA64_GRANULE_SHIFT);
-		ia64_set_psr(psr);		/* restore psr */
-		ia64_srlz_i();
-
-		cpu = smp_processor_id();
-
-		/* insert this TR into our list for MCA recovery purposes */
-		ia64_mca_tlb_list[cpu].pal_base = vaddr & mask;
-		ia64_mca_tlb_list[cpu].pal_paddr = pte_val(mk_pte_phys(md->phys_addr, PAGE_KERNEL));
+		return __va(md->phys_addr);
 	}
+	printk(KERN_WARNING "%s: no PAL-code memory-descriptor found",
+	       __FUNCTION__);
+	return NULL;
+}
+
+void
+efi_map_pal_code (void)
+{
+	void *pal_vaddr = efi_get_pal_addr ();
+	u64 psr;
+
+	if (!pal_vaddr)
+		return;
+
+	/*
+	 * Cannot write to CRx with PSR.ic=1
+	 */
+	psr = ia64_clear_ic();
+	ia64_itr(0x1, IA64_TR_PALCODE, GRANULEROUNDDOWN((unsigned long) pal_vaddr),
+		 pte_val(pfn_pte(__pa(pal_vaddr) >> PAGE_SHIFT, PAGE_KERNEL)),
+		 IA64_GRANULE_SHIFT);
+	ia64_set_psr(psr);		/* restore psr */
+	ia64_srlz_i();
 }
 
 void __init
@@ -750,6 +758,7 @@
 	}
 	return 0;
 }
+EXPORT_SYMBOL(efi_mem_attributes);
 
 int
 valid_phys_addr_range (unsigned long phys_addr, unsigned long *size)
diff -Nru a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S
--- a/arch/ia64/kernel/entry.S	2005-03-01 23:38:54 -08:00
+++ b/arch/ia64/kernel/entry.S	2005-03-01 23:38:54 -08:00
@@ -3,7 +3,7 @@
  *
  * Kernel entry points.
  *
- * Copyright (C) 1998-2003 Hewlett-Packard Co
+ * Copyright (C) 1998-2003, 2005 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  * Copyright (C) 1999, 2002-2003
  *	Asit Mallick <Asit.K.Mallick@intel.com>
@@ -51,8 +51,11 @@
 	 * setup a null register window frame.
 	 */
 ENTRY(ia64_execve)
-	.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(3)
-	alloc loc1=ar.pfs,3,2,4,0
+	/*
+	 * Allocate 8 input registers since ptrace() may clobber them
+	 */
+	.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8)
+	alloc loc1=ar.pfs,8,2,4,0
 	mov loc0=rp
 	.body
 	mov out0=in0			// filename
@@ -113,8 +116,11 @@
  *	      u64 tls)
  */
 GLOBAL_ENTRY(sys_clone2)
-	.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(6)
-	alloc r16=ar.pfs,6,2,6,0
+	/*
+	 * Allocate 8 input registers since ptrace() may clobber them
+	 */
+	.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8)
+	alloc r16=ar.pfs,8,2,6,0
 	DO_SAVE_SWITCH_STACK
 	adds r2=PT(R16)+IA64_SWITCH_STACK_SIZE+16,sp
 	mov loc0=rp
@@ -142,8 +148,11 @@
  *	Deprecated.  Use sys_clone2() instead.
  */
 GLOBAL_ENTRY(sys_clone)
-	.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(5)
-	alloc r16=ar.pfs,5,2,6,0
+	/*
+	 * Allocate 8 input registers since ptrace() may clobber them
+	 */
+	.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8)
+	alloc r16=ar.pfs,8,2,6,0
 	DO_SAVE_SWITCH_STACK
 	adds r2=PT(R16)+IA64_SWITCH_STACK_SIZE+16,sp
 	mov loc0=rp
@@ -549,7 +558,7 @@
 .mem.offset 0,0; st8.spill [r2]=r8		// store return value in slot for r8
 .mem.offset 8,0; st8.spill [r3]=r10		// clear error indication in slot for r10
 	br.call.sptk.many rp=syscall_trace_leave // give parent a chance to catch return value
-.ret3:	br.cond.sptk ia64_leave_syscall
+.ret3:	br.cond.sptk .work_pending_syscall_end
 
 strace_error:
 	ld8 r3=[r2]				// load pt_regs.r8
@@ -612,10 +621,7 @@
 	PT_REGS_UNWIND_INFO(0)
 	cmp.ge p6,p7=r8,r0			// syscall executed successfully?
 	adds r2=PT(R8)+16,sp			// r2 = &pt_regs.r8
-	adds r3=PT(R10)+16,sp			// r3 = &pt_regs.r10
-	;;
-.mem.offset 0,0; (p6) st8.spill [r2]=r8	// store return value in slot for r8 and set unat bit
-.mem.offset 8,0; (p6) st8.spill [r3]=r0	// clear error indication in slot for r10 and set unat bit
+	mov r10=r0				// clear error indication in r10
 (p7)	br.cond.spnt handle_syscall_error	// handle potential syscall failure
 END(ia64_ret_from_syscall)
 	// fall through
@@ -633,10 +639,12 @@
  *		 r13: restored (user-level thread pointer)
  *		 r14: cleared
  *		 r15: restored (syscall #)
- *	     r16-r19: cleared
+ *	     r16-r17: cleared
+ *		 r18: user-level b6
+ *		 r19: cleared
  *		 r20: user-level ar.fpsr
  *		 r21: user-level b0
- *		 r22: user-level b6
+ *		 r22: cleared
  *		 r23: user-level ar.bspstore
  *		 r24: user-level ar.rnat
  *		 r25: user-level ar.unat
@@ -661,7 +669,7 @@
  *	      ar.csd: cleared
  *	      ar.ssd: cleared
  */
-GLOBAL_ENTRY(ia64_leave_syscall)
+ENTRY(ia64_leave_syscall)
 	PT_REGS_UNWIND_INFO(0)
 	/*
 	 * work.need_resched etc. mustn't get changed by this CPU before it returns to
@@ -690,79 +698,76 @@
 (pUStk)	cmp.eq.unc p6,p0=r0,r0		// p6 <- pUStk
 #endif
 .work_processed_syscall:
-	adds r16=PT(LOADRS)+16,r12
-	adds r17=PT(AR_BSPSTORE)+16,r12
+	adds r2=PT(LOADRS)+16,r12
+	adds r3=PT(AR_BSPSTORE)+16,r12
 	adds r18=TI_FLAGS+IA64_TASK_SIZE,r13
 	;;
 (p6)	ld4 r31=[r18]				// load current_thread_info()->flags
-	ld8 r19=[r16],PT(B6)-PT(LOADRS)		// load ar.rsc value for "loadrs"
-	nop.i 0
+	ld8 r19=[r2],PT(B6)-PT(LOADRS)		// load ar.rsc value for "loadrs"
+	mov b7=r0		// clear b7
 	;;
-	ld8 r23=[r17],PT(R9)-PT(AR_BSPSTORE)	// load ar.bspstore (may be garbage)
-	ld8 r22=[r16],PT(R8)-PT(B6)		// load b6
+	ld8 r23=[r3],PT(R11)-PT(AR_BSPSTORE)	// load ar.bspstore (may be garbage)
+	ld8 r18=[r2],PT(R9)-PT(B6)		// load b6
 (p6)	and r15=TIF_WORK_MASK,r31		// any work other than TIF_SYSCALL_TRACE?
 	;;
-
-	mov.m ar.ccv=r0		// clear ar.ccv
+	mov r16=ar.bsp				// M2  get existing backing store pointer
 (p6)	cmp4.ne.unc p6,p0=r15, r0		// any special work pending?
-(p6)	br.cond.spnt .work_pending
+(p6)	br.cond.spnt .work_pending_syscall
 	;;
 	// start restoring the state saved on the kernel stack (struct pt_regs):
-	ld8.fill r8=[r16],16
-	ld8.fill r9=[r17],16
+	ld8 r9=[r2],PT(CR_IPSR)-PT(R9)
+	ld8 r11=[r3],PT(CR_IIP)-PT(R11)
 	mov f6=f0		// clear f6
 	;;
-	ld8.fill r10=[r16],16
-	ld8.fill r11=[r17],16
-	mov f7=f0		// clear f7
-	;;
-	ld8 r29=[r16],16	// load cr.ipsr
-	ld8 r28=[r17],16	// load cr.iip
+	invala			// M0|1 invalidate ALAT
+	rsm psr.i | psr.ic	// M2 initiate turning off of interrupt and interruption collection
+	mov f9=f0		// clear f9
+
+	ld8 r29=[r2],16		// load cr.ipsr
+	ld8 r28=[r3],16			// load cr.iip
 	mov f8=f0		// clear f8
 	;;
-	ld8 r30=[r16],16	// load cr.ifs
-	ld8 r25=[r17],16	// load ar.unat
+	ld8 r30=[r2],16		// M0|1 load cr.ifs
+	mov.m ar.ssd=r0		// M2 clear ar.ssd
 	cmp.eq p9,p0=r0,r0	// set p9 to indicate that we should restore cr.ifs
 	;;
-	rsm psr.i | psr.ic	// initiate turning off of interrupt and interruption collection
-	invala			// invalidate ALAT
-	mov f9=f0		// clear f9
-
-	mov.m ar.ssd=r0		// clear ar.ssd
-	mov.m ar.csd=r0		// clear ar.csd
+	ld8 r25=[r3],16		// M0|1 load ar.unat
+	mov.m ar.csd=r0		// M2 clear ar.csd
+	mov r22=r0		// clear r22
+	;;
+	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 r26=[r16],16	// load ar.pfs
-	ld8 r27=[r17],PT(PR)-PT(AR_RSC)	// load ar.rsc
+	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
 	;;
-	ld8 r24=[r16],PT(B0)-PT(AR_RNAT)	// load ar.rnat (may be garbage)
-	ld8 r31=[r17],PT(R1)-PT(PR)		// load predicates
+	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=[r16],PT(R12)-PT(B0) // load b0
-	ld8.fill r1=[r17],16	// load r1
-(pUStk) mov r3=1
-	;;
-	ld8.fill r12=[r16],16
-	ld8.fill r13=[r17],16
-	mov r2=r0		// clear r2
+	ld8 r20=[r2],PT(R12)-PT(AR_FPSR)	// load ar.fpsr
+	ld8.fill r1=[r3],16	// load r1
+(pUStk) mov r17=1
 	;;
-	ld8 r20=[r16]		// load ar.fpsr
-	ld8.fill r15=[r17]	// load r15
-	mov b7=r0		// clear b7
+	srlz.d			// M0  ensure interruption collection is off
+	ld8.fill r13=[r3],16
+	mov f7=f0		// clear f7
 	;;
-(pUStk) st1 [r14]=r3
-	addl r17=THIS_CPU(ia64_phys_stacked_size_p8),r0
+	ld8.fill r12=[r2]	// restore r12 (sp)
+	ld8.fill r15=[r3]	// restore r15
+	addl r3=THIS_CPU(ia64_phys_stacked_size_p8),r0
+	;;
+(pUStk)	ld4 r3=[r3]		// r3 = cpu_data->phys_stacked_size_p8
+(pUStk) st1 [r14]=r17
+	mov b6=r18		// I0  restore b6
 	;;
-	mov r16=ar.bsp		// get existing backing store pointer
-	srlz.i			// ensure interruption collection is off
 	mov r14=r0		// clear r14
-	;;
-	ld4 r17=[r17]		// r17 = cpu_data->phys_stacked_size_p8
-	mov b6=r22				// restore b6
-	shr.u r18=r19,16	// get byte size of existing "dirty" partition
+	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
 END(ia64_leave_syscall)
@@ -883,12 +888,16 @@
 	srlz.i			// ensure interruption collection is off
 	mov ar.ccv=r15
 	;;
+	ldf.fill f11=[r2]
 	bsw.0			// switch back to bank 0 (no stop bit required beforehand...)
 	;;
-	ldf.fill f11=[r2]
-(pUStk)	mov r18=IA64_KR(CURRENT)	// Itanium 2: 12 cycle read latency
+(pUStk)	mov r18=IA64_KR(CURRENT)// M2 (12 cycle read latency)
 	adds r16=PT(CR_IPSR)+16,r12
 	adds r17=PT(CR_IIP)+16,r12
+
+(pKStk)	mov r22=psr		// M2 read PSR now that interrupts are disabled
+	nop.i 0
+	nop.i 0
 	;;
 	ld8 r29=[r16],16	// load cr.ipsr
 	ld8 r28=[r17],16	// load cr.iip
@@ -901,7 +910,7 @@
 	cmp.eq p9,p0=r0,r0	// set p9 to indicate that we should restore cr.ifs
 	;;
 	ld8 r24=[r16],16	// load ar.rnat (may be garbage)
-	ld8 r23=[r17],16// load ar.bspstore (may be garbage)
+	ld8 r23=[r17],16	// load ar.bspstore (may be garbage)
 	;;
 	ld8 r31=[r16],16	// load predicates
 	ld8 r21=[r17],16	// load b0
@@ -971,6 +980,7 @@
 	shladd in0=loc1,3,r17
 	mov in1=0
 	;;
+	TEXT_ALIGN(32)
 rse_clear_invalid:
 #ifdef CONFIG_ITANIUM
 	// cycle 0
@@ -1031,23 +1041,33 @@
 	loadrs
 	;;
 skip_rbs_switch:
-(pLvSys)	mov r19=r0		// clear r19 for leave_syscall, no-op otherwise
-	mov b0=r21
-	mov ar.pfs=r26
-(pUStk)	mov ar.bspstore=r23
-(p9)	mov cr.ifs=r30
-(pLvSys)mov r16=r0		// clear r16 for leave_syscall, no-op otherwise
-	mov cr.ipsr=r29
-	mov ar.fpsr=r20
-(pLvSys)mov r17=r0		// clear r17 for leave_syscall, no-op otherwise
-	mov cr.iip=r28
-	;;
-(pUStk)	mov ar.rnat=r24		// must happen with RSE in lazy mode
-(pLvSys)mov r18=r0		// clear r18 for leave_syscall, no-op otherwise
-	mov ar.rsc=r27
-	mov ar.unat=r25
-	mov pr=r31,-1
-	rfi
+	mov ar.unat=r25		// M2
+(pKStk)	extr.u r22=r22,21,1	// I0 extract current value of psr.pp from r22
+(pLvSys)mov r19=r0		// A  clear r19 for leave_syscall, no-op otherwise
+	;;
+(pUStk)	mov ar.bspstore=r23	// M2
+(pKStk)	dep r29=r22,r29,21,1	// I0 update ipsr.pp with psr.pp
+(pLvSys)mov r16=r0		// A  clear r16 for leave_syscall, no-op otherwise
+	;;
+	mov cr.ipsr=r29		// M2
+	mov ar.pfs=r26		// I0
+(pLvSys)mov r17=r0		// A  clear r17 for leave_syscall, no-op otherwise
+
+(p9)	mov cr.ifs=r30		// M2
+	mov b0=r21		// I0
+(pLvSys)mov r18=r0		// A  clear r18 for leave_syscall, no-op otherwise
+
+	mov ar.fpsr=r20		// M2
+	mov cr.iip=r28		// M2
+	nop 0
+	;;
+(pUStk)	mov ar.rnat=r24		// M2 must happen with RSE in lazy mode
+	nop 0
+(pLvSys)mov r2=r0
+
+	mov ar.rsc=r27		// M2
+	mov pr=r31,-1		// I0
+	rfi			// B
 
 	/*
 	 * On entry:
@@ -1056,7 +1076,16 @@
 	 * On exit:
 	 *	p6 = TRUE if work-pending-check needs to be redone
 	 */
+.work_pending_syscall:
+	add r2=-8,r2
+	add r3=-8,r3
+	;;
+	st8 [r2]=r8
+	st8 [r3]=r10
 .work_pending:
+	tbit.nz p6,p0=r31,TIF_SIGDELAYED		// signal delayed from  MCA/INIT/NMI/PMI context?
+(p6)	br.cond.sptk.few .sigdelayed
+	;;
 	tbit.z p6,p0=r31,TIF_NEED_RESCHED		// current_thread_info()->need_resched==0?
 (p6)	br.cond.sptk.few .notify
 #ifdef CONFIG_PREEMPT
@@ -1074,14 +1103,34 @@
 	;;
 (pKStk)	st4 [r20]=r0		// preempt_count() <- 0
 #endif
-(pLvSys)br.cond.sptk.many .work_processed_syscall	// re-check
+(pLvSys)br.cond.sptk.few  .work_pending_syscall_end
 	br.cond.sptk.many .work_processed_kernel	// re-check
 
 .notify:
 (pUStk)	br.call.spnt.many rp=notify_resume_user
 .ret10:	cmp.ne p6,p0=r0,r0				// p6 <- 0
-(pLvSys)br.cond.sptk.many .work_processed_syscall	// don't re-check
+(pLvSys)br.cond.sptk.few  .work_pending_syscall_end
 	br.cond.sptk.many .work_processed_kernel	// don't re-check
+
+// There is a delayed signal that was detected in MCA/INIT/NMI/PMI context where
+// it could not be delivered.  Deliver it now.  The signal might be for us and
+// may set TIF_SIGPENDING, so redrive ia64_leave_* after processing the delayed
+// signal.
+
+.sigdelayed:
+	br.call.sptk.many rp=do_sigdelayed
+	cmp.eq p6,p0=r0,r0				// p6 <- 1, always re-check
+(pLvSys)br.cond.sptk.few  .work_pending_syscall_end
+	br.cond.sptk.many .work_processed_kernel	// re-check
+
+.work_pending_syscall_end:
+	adds r2=PT(R8)+16,r12
+	adds r3=PT(R10)+16,r12
+	;;
+	ld8 r8=[r2]
+	ld8 r10=[r3]
+	br.cond.sptk.many .work_processed_syscall	// re-check
+
 END(ia64_leave_kernel)
 
 ENTRY(handle_syscall_error)
@@ -1093,17 +1142,11 @@
 	 */
 	PT_REGS_UNWIND_INFO(0)
 	ld8 r3=[r2]		// load pt_regs.r8
-	sub r9=0,r8		// negate return value to get errno
 	;;
-	mov r10=-1		// return -1 in pt_regs.r10 to indicate error
 	cmp.eq p6,p7=r3,r0	// is pt_regs.r8==0?
-	adds r3=16,r2		// r3=&pt_regs.r10
 	;;
-(p6)	mov r9=r8
-(p6)	mov r10=0
-	;;
-.mem.offset 0,0; st8.spill [r2]=r9	// store errno in pt_regs.r8 and set unat bit
-.mem.offset 8,0; st8.spill [r3]=r10	// store error indication in pt_regs.r10 and set unat bit
+(p7)	mov r10=-1
+(p7)	sub r8=0,r8		// negate return value to get errno
 	br.cond.sptk ia64_leave_syscall
 END(handle_syscall_error)
 
@@ -1183,7 +1226,10 @@
 
 ENTRY(sys_rt_sigreturn)
 	PT_REGS_UNWIND_INFO(0)
-	alloc r2=ar.pfs,0,0,1,0
+	/*
+	 * Allocate 8 input registers since ptrace() may clobber them
+	 */
+	alloc r2=ar.pfs,8,0,1,0
 	.prologue
 	PT_REGS_SAVES(16)
 	adds sp=-16,sp
diff -Nru a/arch/ia64/kernel/entry.h b/arch/ia64/kernel/entry.h
--- a/arch/ia64/kernel/entry.h	2005-03-01 23:38:55 -08:00
+++ b/arch/ia64/kernel/entry.h	2005-03-01 23:38:55 -08:00
@@ -1,14 +1,25 @@
 #include <linux/config.h>
 
 /*
- * Preserved registers that are shared between code in ivt.S and entry.S.  Be
- * careful not to step on these!
+ * Preserved registers that are shared between code in ivt.S and
+ * entry.S.  Be careful not to step on these!
  */
-#define pLvSys		p1	/* set 1 if leave from syscall; otherwise, set 0 */
-#define pKStk		p2	/* will leave_{kernel,syscall} return to kernel-stacks? */
-#define pUStk		p3	/* will leave_{kernel,syscall} return to user-stacks? */
-#define pSys		p4	/* are we processing a (synchronous) system call? */
-#define pNonSys		p5	/* complement of pSys */
+#define PRED_LEAVE_SYSCALL	1 /* TRUE iff leave from syscall */
+#define PRED_KERNEL_STACK	2 /* returning to kernel-stacks? */
+#define PRED_USER_STACK		3 /* returning to user-stacks? */
+#define PRED_SYSCALL		4 /* inside a system call? */
+#define PRED_NON_SYSCALL	5 /* complement of PRED_SYSCALL */
+
+#ifdef __ASSEMBLY__
+# define PASTE2(x,y)	x##y
+# define PASTE(x,y)	PASTE2(x,y)
+
+# define pLvSys		PASTE(p,PRED_LEAVE_SYSCALL)
+# define pKStk		PASTE(p,PRED_KERNEL_STACK)
+# define pUStk		PASTE(p,PRED_USER_STACK)
+# define pSys		PASTE(p,PRED_SYSCALL)
+# define pNonSys	PASTE(p,PRED_NON_SYSCALL)
+#endif
 
 #define PT(f)		(IA64_PT_REGS_##f##_OFFSET)
 #define SW(f)		(IA64_SWITCH_STACK_##f##_OFFSET)
diff -Nru a/arch/ia64/kernel/fsys.S b/arch/ia64/kernel/fsys.S
--- a/arch/ia64/kernel/fsys.S	2005-03-01 23:39:18 -08:00
+++ b/arch/ia64/kernel/fsys.S	2005-03-01 23:39:18 -08:00
@@ -612,8 +612,9 @@
 	;;
 	mov rp=r2				// set the real return addr
 	tbit.z p8,p0=r3,TIF_SYSCALL_TRACE
-
-(p8)	br.call.sptk.many b6=b6			// ignore this return addr
+	;;
+(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
 END(fsys_bubble_down)
 
diff -Nru a/arch/ia64/kernel/gate.S b/arch/ia64/kernel/gate.S
--- a/arch/ia64/kernel/gate.S	2005-03-01 23:39:09 -08:00
+++ b/arch/ia64/kernel/gate.S	2005-03-01 23:39:09 -08:00
@@ -81,6 +81,7 @@
 	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
@@ -119,7 +120,8 @@
 #endif
 
 	mov r10=-1
-	mov r8=ENOSYS
+(p10)	mov r8=EINVAL
+(p9)	mov r8=ENOSYS
 	FSYS_RETURN
 END(__kernel_syscall_via_epc)
 
diff -Nru a/arch/ia64/kernel/head.S b/arch/ia64/kernel/head.S
--- a/arch/ia64/kernel/head.S	2005-03-01 23:39:07 -08:00
+++ b/arch/ia64/kernel/head.S	2005-03-01 23:39:07 -08:00
@@ -5,7 +5,7 @@
  * to set up the kernel's global pointer and jump to the kernel
  * entry point.
  *
- * Copyright (C) 1998-2001, 2003 Hewlett-Packard Co
+ * Copyright (C) 1998-2001, 2003, 2005 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  *	Stephane Eranian <eranian@hpl.hp.com>
  * Copyright (C) 1999 VA Linux Systems
@@ -65,10 +65,27 @@
 	;;
 	/*
 	 * Initialize kernel region registers:
+	 *	rr[0]: VHPT enabled, page size = PAGE_SHIFT
+	 *	rr[1]: VHPT enabled, page size = PAGE_SHIFT
+	 *	rr[2]: VHPT enabled, page size = PAGE_SHIFT
+	 *	rr[3]: VHPT enabled, page size = PAGE_SHIFT
+	 *	rr[4]: VHPT enabled, page size = PAGE_SHIFT
 	 *	rr[5]: VHPT enabled, page size = PAGE_SHIFT
 	 *	rr[6]: VHPT disabled, page size = IA64_GRANULE_SHIFT
 	 *	rr[7]: VHPT disabled, page size = IA64_GRANULE_SHIFT
+	 * We initialize all of them to prevent inadvertently assuming
+	 * something about the state of address translation early in boot.
 	 */
+	mov r6=((ia64_rid(IA64_REGION_ID_KERNEL, (0<<61)) << 8) | (PAGE_SHIFT << 2) | 1)
+	movl r7=(0<<61)
+	mov r8=((ia64_rid(IA64_REGION_ID_KERNEL, (1<<61)) << 8) | (PAGE_SHIFT << 2) | 1)
+	movl r9=(1<<61)
+	mov r10=((ia64_rid(IA64_REGION_ID_KERNEL, (2<<61)) << 8) | (PAGE_SHIFT << 2) | 1)
+	movl r11=(2<<61)
+	mov r12=((ia64_rid(IA64_REGION_ID_KERNEL, (3<<61)) << 8) | (PAGE_SHIFT << 2) | 1)
+	movl r13=(3<<61)
+	mov r14=((ia64_rid(IA64_REGION_ID_KERNEL, (4<<61)) << 8) | (PAGE_SHIFT << 2) | 1)
+	movl r15=(4<<61)
 	mov r16=((ia64_rid(IA64_REGION_ID_KERNEL, (5<<61)) << 8) | (PAGE_SHIFT << 2) | 1)
 	movl r17=(5<<61)
 	mov r18=((ia64_rid(IA64_REGION_ID_KERNEL, (6<<61)) << 8) | (IA64_GRANULE_SHIFT << 2))
@@ -76,6 +93,11 @@
 	mov r20=((ia64_rid(IA64_REGION_ID_KERNEL, (7<<61)) << 8) | (IA64_GRANULE_SHIFT << 2))
 	movl r21=(7<<61)
 	;;
+	mov rr[r7]=r6
+	mov rr[r9]=r8
+	mov rr[r11]=r10
+	mov rr[r13]=r12
+	mov rr[r15]=r14
 	mov rr[r17]=r16
 	mov rr[r19]=r18
 	mov rr[r21]=r20
@@ -210,21 +232,6 @@
 	;;
 (isBP)	st8 [r2]=r28		// save the address of the boot param area passed by the bootloader
 
-#ifdef CONFIG_IA64_EARLY_PRINTK
-	.rodata
-alive_msg:
-	stringz "I'm alive and well\n"
-alive_msg_end:
-	.previous
-
-	alloc r2=ar.pfs,0,0,2,0
-	movl out0=alive_msg
-	movl out1=alive_msg_end-alive_msg-1
-	;;
-	br.call.sptk.many rp=early_printk
-1:	// force new bundle
-#endif /* CONFIG_IA64_EARLY_PRINTK */
-
 #ifdef CONFIG_SMP
 (isAP)	br.call.sptk.many rp=start_secondary
 .ret0:
@@ -245,7 +252,9 @@
 	;;
 	ld8 out0=[r3]
 	br.call.sptk.many b0=console_print
-self:	br.sptk.many self		// endless loop
+
+self:	hint @pause
+	br.sptk.many self		// endless loop
 END(_start)
 
 GLOBAL_ENTRY(ia64_save_debug_regs)
@@ -949,6 +958,8 @@
 (p14)	br.cond.sptk.few .wait
 (p15)	rsm psr.i		// disable interrupts if we reenabled them
 	br.cond.sptk.few b6	// lock is now free, try to acquire
+	.global ia64_spinlock_contention_pre3_4_end	// for kernprof
+ia64_spinlock_contention_pre3_4_end:
 END(ia64_spinlock_contention_pre3_4)
 
 #else
diff -Nru a/arch/ia64/kernel/ia64_ksyms.c b/arch/ia64/kernel/ia64_ksyms.c
--- a/arch/ia64/kernel/ia64_ksyms.c	2005-03-01 23:38:56 -08:00
+++ b/arch/ia64/kernel/ia64_ksyms.c	2005-03-01 23:38:56 -08:00
@@ -122,3 +122,6 @@
 #  endif
 # endif
 #endif
+
+extern char ia64_ivt[];
+EXPORT_SYMBOL(ia64_ivt);
diff -Nru a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c
--- a/arch/ia64/kernel/iosapic.c	2005-03-01 23:38:57 -08:00
+++ b/arch/ia64/kernel/iosapic.c	2005-03-01 23:38:57 -08:00
@@ -99,7 +99,7 @@
 #define DBG(fmt...)
 #endif
 
-static spinlock_t iosapic_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(iosapic_lock);
 
 /* These tables map IA-64 vectors to the IOSAPIC pin that generates this vector. */
 
@@ -111,6 +111,7 @@
 	unsigned char	dmode	: 3;	/* delivery mode (see iosapic.h) */
 	unsigned char 	polarity: 1;	/* interrupt polarity (see iosapic.h) */
 	unsigned char	trigger	: 1;	/* trigger mode (see iosapic.h) */
+	int		refcnt;		/* reference counter */
 } iosapic_intr_info[IA64_NUM_VECTORS];
 
 static struct iosapic {
@@ -177,7 +178,7 @@
 static void
 set_rte (unsigned int vector, unsigned int dest, int mask)
 {
-	unsigned long pol, trigger, dmode, flags;
+	unsigned long pol, trigger, dmode;
 	u32 low32, high32;
 	char __iomem *addr;
 	int rte_index;
@@ -218,13 +219,9 @@
 	/* dest contains both id and eid */
 	high32 = (dest << IOSAPIC_DEST_SHIFT);
 
-	spin_lock_irqsave(&iosapic_lock, flags);
-	{
-		iosapic_write(addr, IOSAPIC_RTE_HIGH(rte_index), high32);
-		iosapic_write(addr, IOSAPIC_RTE_LOW(rte_index), low32);
-		iosapic_intr_info[vector].low32 = low32;
-	}
-	spin_unlock_irqrestore(&iosapic_lock, flags);
+	iosapic_write(addr, IOSAPIC_RTE_HIGH(rte_index), high32);
+	iosapic_write(addr, IOSAPIC_RTE_LOW(rte_index), low32);
+	iosapic_intr_info[vector].low32 = low32;
 }
 
 static void
@@ -475,6 +472,7 @@
 	iosapic_intr_info[vector].addr     = iosapic_address;
 	iosapic_intr_info[vector].gsi_base = gsi_base;
 	iosapic_intr_info[vector].trigger  = trigger;
+	iosapic_intr_info[vector].refcnt++;
 
 	if (trigger == IOSAPIC_EDGE)
 		irq_type = &irq_type_iosapic_edge;
@@ -581,6 +579,7 @@
 	{
 		vector = gsi_to_vector(gsi);
 		if (vector > 0) {
+			iosapic_intr_info[vector].refcnt++;
 			spin_unlock_irqrestore(&iosapic_lock, flags);
 			return vector;
 		}
@@ -589,6 +588,8 @@
 		dest = get_target_cpu(gsi, vector);
 		register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY,
 			polarity, trigger);
+
+		set_rte(vector, dest, 1);
 	}
 	spin_unlock_irqrestore(&iosapic_lock, flags);
 
@@ -597,9 +598,86 @@
 	       (polarity == IOSAPIC_POL_HIGH ? "high" : "low"),
 	       cpu_logical_id(dest), dest, vector);
 
-	set_rte(vector, dest, 1);
 	return vector;
 }
+
+#ifdef CONFIG_ACPI_DEALLOCATE_IRQ
+void
+iosapic_unregister_intr (unsigned int gsi)
+{
+	unsigned long flags;
+	int irq, vector;
+	irq_desc_t *idesc;
+	int rte_index;
+	unsigned long trigger, polarity;
+
+	/*
+	 * If the irq associated with the gsi is not found,
+	 * iosapic_unregister_intr() is unbalanced. We need to check
+	 * this again after getting locks.
+	 */
+	irq = gsi_to_irq(gsi);
+	if (irq < 0) {
+		printk(KERN_ERR "iosapic_unregister_intr(%u) unbalanced\n", gsi);
+		WARN_ON(1);
+		return;
+	}
+	vector = irq_to_vector(irq);
+
+	idesc = irq_descp(irq);
+	spin_lock_irqsave(&idesc->lock, flags);
+	spin_lock(&iosapic_lock);
+	{
+		rte_index = iosapic_intr_info[vector].rte_index;
+		if (rte_index < 0) {
+			spin_unlock(&iosapic_lock);
+			spin_unlock_irqrestore(&idesc->lock, flags);
+			printk(KERN_ERR "iosapic_unregister_intr(%u) unbalanced\n", gsi);
+			WARN_ON(1);
+			return;
+		}
+
+		if (--iosapic_intr_info[vector].refcnt > 0) {
+			spin_unlock(&iosapic_lock);
+			spin_unlock_irqrestore(&idesc->lock, flags);
+			return;
+		}
+
+		/*
+		 * If interrupt handlers still exist on the irq
+		 * associated with the gsi, don't unregister the
+		 * interrupt.
+		 */
+		if (idesc->action) {
+			iosapic_intr_info[vector].refcnt++;
+			spin_unlock(&iosapic_lock);
+			spin_unlock_irqrestore(&idesc->lock, flags);
+			printk(KERN_WARNING "Cannot unregister GSI. IRQ %u is still in use.\n", irq);
+			return;
+		}
+
+		/* Clear the interrupt controller descriptor. */
+		idesc->handler = &no_irq_type;
+
+		trigger  = iosapic_intr_info[vector].trigger;
+		polarity = iosapic_intr_info[vector].polarity;
+
+		/* Clear the interrupt information. */
+		memset(&iosapic_intr_info[vector], 0, sizeof(struct iosapic_intr_info));
+		iosapic_intr_info[vector].rte_index = -1;	/* mark as unused */
+	}
+	spin_unlock(&iosapic_lock);
+	spin_unlock_irqrestore(&idesc->lock, flags);
+
+	/* Free the interrupt vector */
+	free_irq_vector(vector);
+
+	printk(KERN_INFO "GSI %u (%s, %s) -> vector %d unregisterd.\n",
+	       gsi, (trigger == IOSAPIC_EDGE ? "edge" : "level"),
+	       (polarity == IOSAPIC_POL_HIGH ? "high" : "low"),
+	       vector);
+}
+#endif /* CONFIG_ACPI_DEALLOCATE_IRQ */
 
 /*
  * ACPI calls this when it finds an entry for a platform interrupt.
diff -Nru a/arch/ia64/kernel/irq.c b/arch/ia64/kernel/irq.c
--- a/arch/ia64/kernel/irq.c	2005-03-01 23:39:09 -08:00
+++ b/arch/ia64/kernel/irq.c	2005-03-01 23:39:09 -08:00
@@ -16,175 +16,47 @@
  *			architecture.
  */
 
-/*
- * (mostly architecture independent, will move to kernel/irq.c in 2.5.)
- *
- * IRQs are in fact implemented a bit like signal handlers for the kernel.
- * Naturally it's not a 1:1 relation, but there are similarities.
- */
-
-#include <linux/config.h>
-#include <linux/errno.h>
+#include <asm/delay.h>
+#include <asm/uaccess.h>
 #include <linux/module.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/ioport.h>
+#include <linux/seq_file.h>
 #include <linux/interrupt.h>
-#include <linux/timex.h>
-#include <linux/slab.h>
-#include <linux/random.h>
-#include <linux/cpu.h>
-#include <linux/ctype.h>
-#include <linux/smp_lock.h>
-#include <linux/init.h>
 #include <linux/kernel_stat.h>
-#include <linux/irq.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#include <linux/kallsyms.h>
-#include <linux/notifier.h>
-#include <linux/bitops.h>
-
-#include <asm/atomic.h>
-#include <asm/cpu.h>
-#include <asm/io.h>
-#include <asm/smp.h>
-#include <asm/system.h>
-#include <asm/uaccess.h>
-#include <asm/pgalloc.h>
-#include <asm/tlbflush.h>
-#include <asm/delay.h>
-#include <asm/irq.h>
-
 
 /*
- * Linux has a controller-independent x86 interrupt architecture.
- * every controller has a 'controller-template', that is used
- * by the main code to do the right thing. Each driver-visible
- * interrupt source is transparently wired to the appropriate
- * controller. Thus drivers need not be aware of the
- * interrupt-controller.
- *
- * Various interrupt controllers we handle: 8259 PIC, SMP IO-APIC,
- * PIIX4's internal 8259 PIC and SGI's Visual Workstation Cobalt (IO-)APIC.
- * (IO-APICs assumed to be messaging to Pentium local-APICs)
- *
- * the code is designed to be easily extended with new/different
- * interrupt controllers, without having to do assembly magic.
- */
-
-/*
- * Controller mappings for all interrupt sources:
- */
-irq_desc_t _irq_desc[NR_IRQS] __cacheline_aligned = {
-	[0 ... NR_IRQS-1] = {
-		.status = IRQ_DISABLED,
-		.handler = &no_irq_type,
-		.lock = SPIN_LOCK_UNLOCKED
-	}
-};
-
-#ifdef CONFIG_SMP
-/*
- * This is updated when the user sets irq affinity via /proc
+ * 'what should we do if we get a hw irq event on an illegal vector'.
+ * each architecture has to answer this themselves.
  */
-cpumask_t __cacheline_aligned pending_irq_cpumask[NR_IRQS];
-static unsigned long pending_irq_redir[BITS_TO_LONGS(NR_IRQS)];
-#endif
-
-#ifdef CONFIG_IA64_GENERIC
-irq_desc_t * __ia64_irq_desc (unsigned int irq)
+void ack_bad_irq(unsigned int irq)
 {
-	return _irq_desc + irq;
-}
-
-ia64_vector __ia64_irq_to_vector (unsigned int irq)
-{
-	return (ia64_vector) irq;
+	printk(KERN_ERR "Unexpected irq vector 0x%x on CPU %u!\n", irq, smp_processor_id());
 }
 
+#ifdef CONFIG_IA64_GENERIC
 unsigned int __ia64_local_vector_to_irq (ia64_vector vec)
 {
 	return (unsigned int) vec;
 }
 #endif
 
-static void register_irq_proc (unsigned int irq);
-
-/*
- * Special irq handlers.
- */
-
-irqreturn_t no_action(int cpl, void *dev_id, struct pt_regs *regs)
-{ return IRQ_NONE; }
-
-/*
- * Generic no controller code
- */
-
-static void enable_none(unsigned int irq) { }
-static unsigned int startup_none(unsigned int irq) { return 0; }
-static void disable_none(unsigned int irq) { }
-static void ack_none(unsigned int irq)
-{
 /*
- * 'what should we do if we get a hw irq event on an illegal vector'.
- * each architecture has to answer this themselves, it doesn't deserve
- * a generic callback i think.
+ * Interrupt statistics:
  */
-#ifdef CONFIG_X86
-	printk(KERN_ERR "unexpected IRQ trap at vector %02x\n", irq);
-#ifdef CONFIG_X86_LOCAL_APIC
-	/*
-	 * Currently unexpected vectors happen only on SMP and APIC.
-	 * We _must_ ack these because every local APIC has only N
-	 * irq slots per priority level, and a 'hanging, unacked' IRQ
-	 * holds up an irq slot - in excessive cases (when multiple
-	 * unexpected vectors occur) that might lock up the APIC
-	 * completely.
-	 */
-	ack_APIC_irq();
-#endif
-#endif
-#ifdef CONFIG_IA64
-	printk(KERN_ERR "Unexpected irq vector 0x%x on CPU %u!\n", irq, smp_processor_id());
-#endif
-}
-
-/* startup is the same as "enable", shutdown is same as "disable" */
-#define shutdown_none	disable_none
-#define end_none	enable_none
-
-struct hw_interrupt_type no_irq_type = {
-	"none",
-	startup_none,
-	shutdown_none,
-	enable_none,
-	disable_none,
-	ack_none,
-	end_none
-};
 
 atomic_t irq_err_count;
-#ifdef CONFIG_X86_IO_APIC
-#ifdef APIC_MISMATCH_DEBUG
-atomic_t irq_mis_count;
-#endif
-#endif
 
 /*
- * Generic, controller-independent functions:
+ * /proc/interrupts printing:
  */
 
 int show_interrupts(struct seq_file *p, void *v)
 {
-	int j, i = *(loff_t *) v;
+	int i = *(loff_t *) v, j;
 	struct irqaction * action;
-	irq_desc_t *idesc;
 	unsigned long flags;
 
 	if (i == 0) {
-		seq_puts(p, "           ");
+		seq_printf(p, "           ");
 		for (j=0; j<NR_CPUS; j++)
 			if (cpu_online(j))
 				seq_printf(p, "CPU%d       ",j);
@@ -192,9 +64,8 @@
 	}
 
 	if (i < NR_IRQS) {
-		idesc = irq_descp(i);
-		spin_lock_irqsave(&idesc->lock, flags);
-		action = idesc->action;
+		spin_lock_irqsave(&irq_desc[i].lock, flags);
+		action = irq_desc[i].action;
 		if (!action)
 			goto skip;
 		seq_printf(p, "%3d: ",i);
@@ -205,7 +76,7 @@
 			if (cpu_online(j))
 				seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
 #endif
-		seq_printf(p, " %14s", idesc->handler->typename);
+		seq_printf(p, " %14s", irq_desc[i].handler->typename);
 		seq_printf(p, "  %s", action->name);
 
 		for (action=action->next; action; action = action->next)
@@ -213,728 +84,20 @@
 
 		seq_putc(p, '\n');
 skip:
-		spin_unlock_irqrestore(&idesc->lock, flags);
-	} else if (i == NR_IRQS) {
-#ifdef CONFIG_X86_LOCAL_APIC
-		seq_puts(p, "LOC: ");
-		for (j = 0; j < NR_CPUS; j++)
-			if (cpu_online(j))
-				seq_printf(p, "%10u ", irq_stat[j].apic_timer_irqs);
-		seq_putc(p, '\n');
-#endif
+		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
+	} else if (i == NR_IRQS)
 		seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
-#ifdef CONFIG_X86_IO_APIC
-#ifdef APIC_MISMATCH_DEBUG
-		seq_printf(p, "MIS: %10u\n", atomic_read(&irq_mis_count));
-#endif
-#endif
-	}
 	return 0;
 }
 
 #ifdef CONFIG_SMP
-inline void synchronize_irq(unsigned int irq)
-{
-	while (irq_descp(irq)->status & IRQ_INPROGRESS)
-		cpu_relax();
-}
-EXPORT_SYMBOL(synchronize_irq);
-#endif
-
-/*
- * This should really return information about whether
- * we should do bottom half handling etc. Right now we
- * end up _always_ checking the bottom half, which is a
- * waste of time and is not what some drivers would
- * prefer.
- */
-int handle_IRQ_event(unsigned int irq,
-		struct pt_regs *regs, struct irqaction *action)
-{
-	int status = 1;	/* Force the "do bottom halves" bit */
-	int ret, retval = 0;
-
-	if (!(action->flags & SA_INTERRUPT))
-		local_irq_enable();
-
-	do {
-		ret = action->handler(irq, action->dev_id, regs);
-		if (ret == IRQ_HANDLED)
-			status |= action->flags;
-		retval |= ret;
-		action = action->next;
-	} while (action);
-	if (status & SA_SAMPLE_RANDOM)
-		add_interrupt_randomness(irq);
-	local_irq_disable();
-	return retval;
-}
-
-static void __report_bad_irq(int irq, irq_desc_t *desc, irqreturn_t action_ret)
-{
-	struct irqaction *action;
-
-	if (action_ret != IRQ_HANDLED && action_ret != IRQ_NONE) {
-		printk(KERN_ERR "irq event %d: bogus return value %x\n",
-				irq, action_ret);
-	} else {
-		printk(KERN_ERR "irq %d: nobody cared!\n", irq);
-	}
-	dump_stack();
-	printk(KERN_ERR "handlers:\n");
-	action = desc->action;
-	do {
-		printk(KERN_ERR "[<%p>]", action->handler);
-		print_symbol(" (%s)",
-			(unsigned long)action->handler);
-		printk("\n");
-		action = action->next;
-	} while (action);
-}
-
-static void report_bad_irq(int irq, irq_desc_t *desc, irqreturn_t action_ret)
-{
-	static int count = 100;
-
-	if (count) {
-		count--;
-		__report_bad_irq(irq, desc, action_ret);
-	}
-}
-
-static int noirqdebug;
-
-static int __init noirqdebug_setup(char *str)
-{
-	noirqdebug = 1;
-	printk("IRQ lockup detection disabled\n");
-	return 1;
-}
-
-__setup("noirqdebug", noirqdebug_setup);
-
-/*
- * 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 and try to
- * turn the IRQ off.
- *
- * (The other 100-of-100,000 interrupts may have been a correctly-functioning
- *  device sharing an IRQ with the failing one)
- *
- * Called under desc->lock
- */
-static void note_interrupt(int irq, irq_desc_t *desc, irqreturn_t action_ret)
-{
-	if (action_ret != IRQ_HANDLED) {
-		desc->irqs_unhandled++;
-		if (action_ret != IRQ_NONE)
-			report_bad_irq(irq, desc, action_ret);
-	}
-
-	desc->irq_count++;
-	if (desc->irq_count < 100000)
-		return;
-
-	desc->irq_count = 0;
-	if (desc->irqs_unhandled > 99900) {
-		/*
-		 * The interrupt is stuck
-		 */
-		__report_bad_irq(irq, desc, action_ret);
-		/*
-		 * Now kill the IRQ
-		 */
-		printk(KERN_EMERG "Disabling IRQ #%d\n", irq);
-		desc->status |= IRQ_DISABLED;
-		desc->handler->disable(irq);
-	}
-	desc->irqs_unhandled = 0;
-}
-
-/*
- * Generic enable/disable code: this just calls
- * down into the PIC-specific version for the actual
- * hardware disable after having gotten the irq
- * controller lock.
- */
-
-/**
- *	disable_irq_nosync - disable an irq without waiting
- *	@irq: Interrupt to disable
- *
- *	Disable the selected interrupt line.  Disables and Enables are
- *	nested.
- *	Unlike disable_irq(), this function does not ensure existing
- *	instances of the IRQ handler have completed before returning.
- *
- *	This function may be called from IRQ context.
- */
-
-inline void disable_irq_nosync(unsigned int irq)
-{
-	irq_desc_t *desc = irq_descp(irq);
-	unsigned long flags;
-
-	spin_lock_irqsave(&desc->lock, flags);
-	if (!desc->depth++) {
-		desc->status |= IRQ_DISABLED;
-		desc->handler->disable(irq);
-	}
-	spin_unlock_irqrestore(&desc->lock, flags);
-}
-EXPORT_SYMBOL(disable_irq_nosync);
-
-/**
- *	disable_irq - disable an irq and wait for completion
- *	@irq: Interrupt to disable
- *
- *	Disable the selected interrupt line.  Enables and Disables are
- *	nested.
- *	This function waits for any pending IRQ handlers for this interrupt
- *	to complete before returning. If you use this function while
- *	holding a resource the IRQ handler may need you will deadlock.
- *
- *	This function may be called - with care - from IRQ context.
- */
-
-void disable_irq(unsigned int irq)
-{
-	irq_desc_t *desc = irq_descp(irq);
-
-	disable_irq_nosync(irq);
-	if (desc->action)
-		synchronize_irq(irq);
-}
-EXPORT_SYMBOL(disable_irq);
-
-/**
- *	enable_irq - enable handling of an irq
- *	@irq: Interrupt to enable
- *
- *	Undoes the effect of one call to disable_irq().  If this
- *	matches the last disable, processing of interrupts on this
- *	IRQ line is re-enabled.
- *
- *	This function may be called from IRQ context.
- */
-
-void enable_irq(unsigned int irq)
-{
-	irq_desc_t *desc = irq_descp(irq);
-	unsigned long flags;
-
-	spin_lock_irqsave(&desc->lock, flags);
-	switch (desc->depth) {
-	case 1: {
-		unsigned int status = desc->status & ~IRQ_DISABLED;
-		desc->status = status;
-		if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) {
-			desc->status = status | IRQ_REPLAY;
-			hw_resend_irq(desc->handler,irq);
-		}
-		desc->handler->enable(irq);
-		/* fall-through */
-	}
-	default:
-		desc->depth--;
-		break;
-	case 0:
-		printk(KERN_ERR "enable_irq(%u) unbalanced from %p\n",
-		       irq, (void *) __builtin_return_address(0));
-	}
-	spin_unlock_irqrestore(&desc->lock, flags);
-}
-EXPORT_SYMBOL(enable_irq);
-
-/*
- * do_IRQ handles all normal device IRQ's (the special
- * SMP cross-CPU interrupts have their own specific
- * handlers).
- */
-unsigned int do_IRQ(unsigned long irq, struct pt_regs *regs)
-{
-	/*
-	 * We ack quickly, we don't want the irq controller
-	 * thinking we're snobs just because some other CPU has
-	 * disabled global interrupts (we have already done the
-	 * INT_ACK cycles, it's too late to try to pretend to the
-	 * controller that we aren't taking the interrupt).
-	 *
-	 * 0 return value means that this irq is already being
-	 * handled by some other CPU. (or is disabled)
-	 */
-	irq_desc_t *desc = irq_descp(irq);
-	struct irqaction * action;
-	irqreturn_t action_ret;
-	unsigned int status;
-	int cpu;
-
-	cpu = smp_processor_id(); /* for CONFIG_PREEMPT, this must come after irq_enter()! */
-
-	kstat_cpu(cpu).irqs[irq]++;
-
-	if (desc->status & IRQ_PER_CPU) {
-		/* no locking required for CPU-local interrupts: */
-		desc->handler->ack(irq);
-		action_ret = handle_IRQ_event(irq, regs, desc->action);
-		desc->handler->end(irq);
-	} else {
-		spin_lock(&desc->lock);
-		desc->handler->ack(irq);
-		/*
-		 * REPLAY is when Linux resends an IRQ that was dropped earlier
-		 * WAITING is used by probe to mark irqs that are being tested
-		 */
-		status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING);
-		status |= IRQ_PENDING; /* we _want_ to handle it */
-
-		/*
-		 * If the IRQ is disabled for whatever reason, we cannot
-		 * use the action we have.
-		 */
-		action = NULL;
-		if (likely(!(status & (IRQ_DISABLED | IRQ_INPROGRESS)))) {
-			action = desc->action;
-			status &= ~IRQ_PENDING; /* we commit to handling */
-			status |= IRQ_INPROGRESS; /* we are handling it */
-		}
-		desc->status = status;
-
-		/*
-		 * If there is no IRQ handler or it was disabled, exit early.
-		 * Since we set PENDING, if another processor is handling
-		 * a different instance of this same irq, the other processor
-		 * will take care of it.
-		 */
-		if (unlikely(!action))
-			goto out;
-
-		/*
-		 * Edge triggered interrupts need to remember
-		 * pending events.
-		 * This applies to any hw interrupts that allow a second
-		 * instance of the same irq to arrive while we are in do_IRQ
-		 * or in the handler. But the code here only handles the _second_
-		 * instance of the irq, not the third or fourth. So it is mostly
-		 * useful for irq hardware that does not mask cleanly in an
-		 * SMP environment.
-		 */
-		for (;;) {
-			spin_unlock(&desc->lock);
-			action_ret = handle_IRQ_event(irq, regs, action);
-			spin_lock(&desc->lock);
-			if (!noirqdebug)
-				note_interrupt(irq, desc, action_ret);
-			if (!(desc->status & IRQ_PENDING))
-				break;
-			desc->status &= ~IRQ_PENDING;
-		}
-		desc->status &= ~IRQ_INPROGRESS;
-	  out:
-		/*
-		 * The ->end() handler has to deal with interrupts which got
-		 * disabled while the handler was running.
-		 */
-		desc->handler->end(irq);
-		spin_unlock(&desc->lock);
-	}
-	return 1;
-}
-
-/**
- *	request_irq - allocate an interrupt line
- *	@irq: Interrupt line to allocate
- *	@handler: Function to be called when the IRQ occurs
- *	@irqflags: Interrupt type flags
- *	@devname: An ascii name for the claiming device
- *	@dev_id: A cookie passed back to the handler function
- *
- *	This call allocates interrupt resources and enables the
- *	interrupt line and IRQ handling. From the point this
- *	call is made your handler function may be invoked. Since
- *	your handler function must clear any interrupt the board 
- *	raises, you must take care both to initialise your hardware
- *	and to set up the interrupt handler in the right order.
- *
- *	Dev_id must be globally unique. Normally the address of the
- *	device data structure is used as the cookie. Since the handler
- *	receives this value it makes sense to use it.
- *
- *	If your interrupt is shared you must pass a non NULL dev_id
- *	as this is required when freeing the interrupt.
- *
- *	Flags:
- *
- *	SA_SHIRQ		Interrupt is shared
- *
- *	SA_INTERRUPT		Disable local interrupts while processing
- *
- *	SA_SAMPLE_RANDOM	The interrupt can be used for entropy
- *
- */
-
-int request_irq(unsigned int irq,
-		irqreturn_t (*handler)(int, void *, struct pt_regs *),
-		unsigned long irqflags,
-		const char * devname,
-		void *dev_id)
-{
-	int retval;
-	struct irqaction * action;
-
-#if 1
-	/*
-	 * Sanity-check: shared interrupts should REALLY pass in
-	 * a real dev-ID, otherwise we'll have trouble later trying
-	 * to figure out which interrupt is which (messes up the
-	 * interrupt freeing logic etc).
-	 */
-	if (irqflags & SA_SHIRQ) {
-		if (!dev_id)
-			printk(KERN_ERR "Bad boy: %s called us without a dev_id!\n", devname);
-	}
-#endif
-
-	if (irq >= NR_IRQS)
-		return -EINVAL;
-	if (!handler)
-		return -EINVAL;
-
-	action = (struct irqaction *)
-			kmalloc(sizeof(struct irqaction), GFP_ATOMIC);
-	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);
-
-/**
- *	free_irq - free an interrupt
- *	@irq: Interrupt line to free
- *	@dev_id: Device identity to free
- *
- *	Remove an interrupt handler. The handler is removed and if the
- *	interrupt line is no longer in use by any driver it is disabled.
- *	On a shared IRQ the caller must ensure the interrupt is disabled
- *	on the card it drives before calling this function. The function
- *	does not return until any executing interrupts for this IRQ
- *	have completed.
- *
- *	This function must not be called from interrupt context.
- */
-
-void free_irq(unsigned int irq, void *dev_id)
-{
-	irq_desc_t *desc;
-	struct irqaction **p;
-	unsigned long flags;
-
-	if (irq >= NR_IRQS)
-		return;
-
-	desc = irq_descp(irq);
-	spin_lock_irqsave(&desc->lock,flags);
-	p = &desc->action;
-	for (;;) {
-		struct irqaction * action = *p;
-		if (action) {
-			struct irqaction **pp = p;
-			p = &action->next;
-			if (action->dev_id != dev_id)
-				continue;
-
-			/* Found it - now remove it from the list of entries */
-			*pp = action->next;
-			if (!desc->action) {
-				desc->status |= IRQ_DISABLED;
-				desc->handler->shutdown(irq);
-			}
-			spin_unlock_irqrestore(&desc->lock,flags);
-
-			/* Wait to make sure it's not being used on another CPU */
-			synchronize_irq(irq);
-			kfree(action);
-			return;
-		}
-		printk(KERN_ERR "Trying to free free IRQ%d\n",irq);
-		spin_unlock_irqrestore(&desc->lock,flags);
-		return;
-	}
-}
-
-EXPORT_SYMBOL(free_irq);
-
 /*
- * IRQ autodetection code..
- *
- * This depends on the fact that any interrupt that
- * comes in on to an unassigned handler will get stuck
- * with "IRQ_WAITING" cleared and the interrupt
- * disabled.
- */
-
-static DECLARE_MUTEX(probe_sem);
-
-/**
- *	probe_irq_on	- begin an interrupt autodetect
- *
- *	Commence probing for an interrupt. The interrupts are scanned
- *	and a mask of potential interrupt lines is returned.
- *
- */
-
-unsigned long probe_irq_on(void)
-{
-	unsigned int i;
-	irq_desc_t *desc;
-	unsigned long val;
-	unsigned long delay;
-
-	down(&probe_sem);
-	/*
-	 * something may have generated an irq long ago and we want to
-	 * flush such a longstanding irq before considering it as spurious.
-	 */
-	for (i = NR_IRQS-1; i > 0; i--)  {
-		desc = irq_descp(i);
-
-		spin_lock_irq(&desc->lock);
-		if (!desc->action)
-			desc->handler->startup(i);
-		spin_unlock_irq(&desc->lock);
-	}
-
-	/* Wait for longstanding interrupts to trigger. */
-	for (delay = jiffies + HZ/50; time_after(delay, jiffies); )
-		/* about 20ms delay */ barrier();
-
-	/*
-	 * enable any unassigned irqs
-	 * (we must startup again here because if a longstanding irq
-	 * happened in the previous stage, it may have masked itself)
-	 */
-	for (i = NR_IRQS-1; i > 0; i--) {
-		desc = irq_descp(i);
-
-		spin_lock_irq(&desc->lock);
-		if (!desc->action) {
-			desc->status |= IRQ_AUTODETECT | IRQ_WAITING;
-			if (desc->handler->startup(i))
-				desc->status |= IRQ_PENDING;
-		}
-		spin_unlock_irq(&desc->lock);
-	}
-
-	/*
-	 * Wait for spurious interrupts to trigger
-	 */
-	for (delay = jiffies + HZ/10; time_after(delay, jiffies); )
-		/* about 100ms delay */ barrier();
-
-	/*
-	 * Now filter out any obviously spurious interrupts
-	 */
-	val = 0;
-	for (i = 0; i < NR_IRQS; i++) {
-		irq_desc_t *desc = irq_descp(i);
-		unsigned int status;
-
-		spin_lock_irq(&desc->lock);
-		status = desc->status;
-
-		if (status & IRQ_AUTODETECT) {
-			/* It triggered already - consider it spurious. */
-			if (!(status & IRQ_WAITING)) {
-				desc->status = status & ~IRQ_AUTODETECT;
-				desc->handler->shutdown(i);
-			} else
-				if (i < 32)
-					val |= 1 << i;
-		}
-		spin_unlock_irq(&desc->lock);
-	}
-
-	return val;
-}
-
-EXPORT_SYMBOL(probe_irq_on);
-
-/**
- *	probe_irq_mask - scan a bitmap of interrupt lines
- *	@val:	mask of interrupts to consider
- *
- *	Scan the ISA bus interrupt lines and return a bitmap of
- *	active interrupts. The interrupt probe logic state is then
- *	returned to its previous value.
- *
- *	Note: we need to scan all the irq's even though we will
- *	only return ISA irq numbers - just so that we reset them
- *	all to a known state.
- */
-unsigned int probe_irq_mask(unsigned long val)
-{
-	int i;
-	unsigned int mask;
-
-	mask = 0;
-	for (i = 0; i < 16; i++) {
-		irq_desc_t *desc = irq_descp(i);
-		unsigned int status;
-
-		spin_lock_irq(&desc->lock);
-		status = desc->status;
-
-		if (status & IRQ_AUTODETECT) {
-			if (!(status & IRQ_WAITING))
-				mask |= 1 << i;
-
-			desc->status = status & ~IRQ_AUTODETECT;
-			desc->handler->shutdown(i);
-		}
-		spin_unlock_irq(&desc->lock);
-	}
-	up(&probe_sem);
-
-	return mask & val;
-}
-EXPORT_SYMBOL(probe_irq_mask);
-
-/**
- *	probe_irq_off	- end an interrupt autodetect
- *	@val: mask of potential interrupts (unused)
- *
- *	Scans the unused interrupt lines and returns the line which
- *	appears to have triggered the interrupt. If no interrupt was
- *	found then zero is returned. If more than one interrupt is
- *	found then minus the first candidate is returned to indicate
- *	their is doubt.
- *
- *	The interrupt probe logic state is returned to its previous
- *	value.
- *
- *	BUGS: When used in a module (which arguably shouldn't happen)
- *	nothing prevents two IRQ probe callers from overlapping. The
- *	results of this are non-optimal.
+ * This is updated when the user sets irq affinity via /proc
  */
-
-int probe_irq_off(unsigned long val)
-{
-	int i, irq_found, nr_irqs;
-
-	nr_irqs = 0;
-	irq_found = 0;
-	for (i = 0; i < NR_IRQS; i++) {
-		irq_desc_t *desc = irq_descp(i);
-		unsigned int status;
-
-		spin_lock_irq(&desc->lock);
-		status = desc->status;
-
-		if (status & IRQ_AUTODETECT) {
-			if (!(status & IRQ_WAITING)) {
-				if (!nr_irqs)
-					irq_found = i;
-				nr_irqs++;
-			}
-			desc->status = status & ~IRQ_AUTODETECT;
-			desc->handler->shutdown(i);
-		}
-		spin_unlock_irq(&desc->lock);
-	}
-	up(&probe_sem);
-
-	if (nr_irqs > 1)
-		irq_found = -irq_found;
-	return irq_found;
-}
-
-EXPORT_SYMBOL(probe_irq_off);
-
-int setup_irq(unsigned int irq, struct irqaction * new)
-{
-	int shared = 0;
-	unsigned long flags;
-	struct irqaction *old, **p;
-	irq_desc_t *desc = irq_descp(irq);
-
-	if (desc->handler == &no_irq_type)
-		return -ENOSYS;
-	/*
-	 * Some drivers like serial.c use request_irq() heavily,
-	 * so we have to be careful not to interfere with a
-	 * running system.
-	 */
-	if (new->flags & SA_SAMPLE_RANDOM) {
-		/*
-		 * This function might sleep, we want to call it first,
-		 * outside of the atomic block.
-		 * Yes, this might clear the entropy pool if the wrong
-		 * driver is attempted to be loaded, without actually
-		 * installing a new handler, but is this really a problem,
-		 * only the sysadmin is able to do this.
-		 */
-		rand_initialize_irq(irq);
-	}
-
-	if (new->flags & SA_PERCPU_IRQ) {
-		desc->status |= IRQ_PER_CPU;
-		desc->handler = &irq_type_ia64_lsapic;
-	}
-
-	/*
-	 * The following block of code has to be executed atomically
-	 */
-	spin_lock_irqsave(&desc->lock,flags);
-	p = &desc->action;
-	if ((old = *p) != NULL) {
-		/* Can't share interrupts unless both agree to */
-		if (!(old->flags & new->flags & SA_SHIRQ)) {
-			spin_unlock_irqrestore(&desc->lock,flags);
-			return -EBUSY;
-		}
-
-		/* add new interrupt at end of irq queue */
-		do {
-			p = &old->next;
-			old = *p;
-		} while (old);
-		shared = 1;
-	}
-
-	*p = new;
-
-	if (!shared) {
-		desc->depth = 0;
-		desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT | IRQ_WAITING | IRQ_INPROGRESS);
-		desc->handler->startup(irq);
-	}
-	spin_unlock_irqrestore(&desc->lock,flags);
-
-	register_irq_proc(irq);
-	return 0;
-}
-
-static struct proc_dir_entry * root_irq_dir;
-static struct proc_dir_entry * irq_dir [NR_IRQS];
-
-#ifdef CONFIG_SMP
-
-static struct proc_dir_entry * smp_affinity_entry [NR_IRQS];
+cpumask_t __cacheline_aligned pending_irq_cpumask[NR_IRQS];
+static unsigned long pending_irq_redir[BITS_TO_LONGS(NR_IRQS)];
 
 static cpumask_t irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = CPU_MASK_ALL };
-
 static char irq_redir [NR_IRQS]; // = { [0 ... NR_IRQS-1] = 1 };
 
 void set_irq_affinity_info (unsigned int irq, int hwid, int redir)
@@ -949,79 +112,6 @@
 	}
 }
 
-static int irq_affinity_read_proc (char *page, char **start, off_t off,
-			int count, int *eof, void *data)
-{
-	int len = sprintf(page, "%s", irq_redir[(long)data] ? "r " : "");
-
-	len += cpumask_scnprintf(page+len, count, irq_affinity[(long)data]);
-	if (count - len < 2)
-		return -EINVAL;
-	len += sprintf(page + len, "\n");
-	return len;
-}
-
-static int irq_affinity_write_proc (struct file *file, const char __user *buffer,
-				    unsigned long count, void *data)
-{
-	unsigned int irq = (unsigned long) data;
-	int full_count = count, err;
-	cpumask_t new_value, tmp;
-#	define R_PREFIX_LEN 16
-	char rbuf[R_PREFIX_LEN];
-	int rlen;
-	int prelen;
-	irq_desc_t *desc = irq_descp(irq);
-	unsigned long flags;
-	int redir = 0;
-
-	if (!desc->handler->set_affinity)
-		return -EIO;
-
-	/*
-	 * If string being written starts with a prefix of 'r' or 'R'
-	 * and some limited number of spaces, set IA64_IRQ_REDIRECTED.
-	 * If more than (R_PREFIX_LEN - 2) spaces are passed, they won't
-	 * all be trimmed as part of prelen, the untrimmed spaces will
-	 * cause the hex parsing to fail, and this write() syscall will
-	 * fail with EINVAL.
-	 */
-
-	if (!count)
-		return -EINVAL;
-	rlen = min(sizeof(rbuf)-1, count);
-	if (copy_from_user(rbuf, buffer, rlen))
-		return -EFAULT;
-	rbuf[rlen] = 0;
-	prelen = 0;
-	if (tolower(*rbuf) == 'r') {
-		prelen = strspn(rbuf, "Rr ");
-		redir++;
-	}
-
-	err = cpumask_parse(buffer+prelen, count-prelen, new_value);
-	if (err)
-		return err;
-
-	/*
-	 * Do not allow disabling IRQs completely - it's a too easy
-	 * way to make the system unusable accidentally :-) At least
-	 * one online CPU still has to be targeted.
-	 */
-	cpus_and(tmp, new_value, cpu_online_map);
-	if (cpus_empty(tmp))
-		return -EINVAL;
-
-	spin_lock_irqsave(&desc->lock, flags);
-	pending_irq_cpumask[irq] = new_value;
-	if (redir)
-		set_bit(irq, pending_irq_redir);
-	else
-		clear_bit(irq, pending_irq_redir);
-	spin_unlock_irqrestore(&desc->lock, flags);
-
-	return full_count;
-}
 
 void move_irq(int irq)
 {
@@ -1030,6 +120,9 @@
 	irq_desc_t *desc = irq_descp(irq);
 	int redir = test_bit(irq, pending_irq_redir);
 
+	if (unlikely(!desc->handler->set_affinity))
+		return;
+
 	if (!cpus_empty(pending_irq_cpumask[irq])) {
 		cpus_and(tmp, pending_irq_cpumask[irq], cpu_online_map);
 		if (unlikely(!cpus_empty(tmp))) {
@@ -1121,7 +214,7 @@
 	for (irq=0; irq < NR_IRQS; irq++) {
 		if (vectors_in_migration[irq]) {
 			vectors_in_migration[irq]=0;
-			do_IRQ(irq, NULL);
+			__do_IRQ(irq, NULL);
 		}
 	}
 
@@ -1135,57 +228,3 @@
 	local_irq_disable();
 }
 #endif
-
-#define MAX_NAMELEN 10
-
-static void register_irq_proc (unsigned int irq)
-{
-	char name [MAX_NAMELEN];
-
-	if (!root_irq_dir || (irq_descp(irq)->handler == &no_irq_type) || irq_dir[irq])
-		return;
-
-	memset(name, 0, MAX_NAMELEN);
-	sprintf(name, "%d", irq);
-
-	/* create /proc/irq/1234 */
-	irq_dir[irq] = proc_mkdir(name, root_irq_dir);
-
-#ifdef CONFIG_SMP
-	{
-		struct proc_dir_entry *entry;
-
-		/* create /proc/irq/1234/smp_affinity */
-		entry = create_proc_entry("smp_affinity", 0600, irq_dir[irq]);
-
-		if (entry) {
-			entry->nlink = 1;
-			entry->data = (void *)(long)irq;
-			entry->read_proc = irq_affinity_read_proc;
-			entry->write_proc = irq_affinity_write_proc;
-		}
-
-		smp_affinity_entry[irq] = entry;
-	}
-#endif
-}
-
-void init_irq_proc (void)
-{
-	int i;
-
-	/* create /proc/irq */
-	root_irq_dir = proc_mkdir("irq", NULL);
-
-	/* create /proc/irq/prof_cpu_mask */
-	create_prof_cpu_mask(root_irq_dir);
-
-	/*
-	 * Create entries for all existing IRQs.
-	 */
-	for (i = 0; i < NR_IRQS; i++) {
-		if (irq_descp(i)->handler == &no_irq_type)
-			continue;
-		register_irq_proc(i);
-	}
-}
diff -Nru a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c
--- a/arch/ia64/kernel/irq_ia64.c	2005-03-01 23:38:55 -08:00
+++ b/arch/ia64/kernel/irq_ia64.c	2005-03-01 23:38:55 -08:00
@@ -60,33 +60,35 @@
 };
 EXPORT_SYMBOL(isa_irq_to_vector_map);
 
-static inline void
-irq_enter (void)
-{
-	preempt_count() += HARDIRQ_OFFSET;
-}
-
-static inline void
-irq_exit (void)
-{
-	preempt_count() -= IRQ_EXIT_OFFSET;
-	if (!in_interrupt() && local_softirq_pending())
-		do_softirq();
-	preempt_enable_no_resched();
-}
+static unsigned long ia64_vector_mask[BITS_TO_LONGS(IA64_NUM_DEVICE_VECTORS)];
 
 int
 assign_irq_vector (int irq)
 {
-	static int next_vector = IA64_FIRST_DEVICE_VECTOR;
-
-	if (next_vector > IA64_LAST_DEVICE_VECTOR)
+	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)
 		/* XXX could look for sharable vectors instead of panic'ing... */
 		panic("assign_irq_vector: out of interrupt vectors!");
-	return next_vector++;
+	if (test_and_set_bit(pos, ia64_vector_mask))
+		goto again;
+	return vector;
 }
 
-extern unsigned int do_IRQ(unsigned long irq, struct pt_regs *regs);
+void
+free_irq_vector (int vector)
+{
+	int pos;
+
+	if (vector < IA64_FIRST_DEVICE_VECTOR || vector > IA64_LAST_DEVICE_VECTOR)
+		return;
+
+	pos = vector - IA64_FIRST_DEVICE_VECTOR;
+	if (!test_and_clear_bit(pos, ia64_vector_mask))
+		printk(KERN_WARNING "%s: double free!\n", __FUNCTION__);
+}
 
 #ifdef CONFIG_SMP
 #	define IS_RESCHEDULE(vec)	(vec == IA64_IPI_RESCHEDULE)
@@ -115,7 +117,7 @@
 		 * switched atomically.
 		 */
 		bsp = ia64_getreg(_IA64_REG_AR_BSP);
-		sp = ia64_getreg(_IA64_REG_AR_SP);
+		sp = ia64_getreg(_IA64_REG_SP);
 
 		if ((sp - bsp) < 1024) {
 			static unsigned char count;
@@ -146,7 +148,7 @@
 			ia64_setreg(_IA64_REG_CR_TPR, vector);
 			ia64_srlz_d();
 
-			do_IRQ(local_vector_to_irq(vector), regs);
+			__do_IRQ(local_vector_to_irq(vector), regs);
 
 			/*
 			 * Disable interrupts and send EOI:
@@ -197,7 +199,7 @@
 			 * Probably could shared code.
 			 */
 			vectors_in_migration[local_vector_to_irq(vector)]=0;
-			do_IRQ(local_vector_to_irq(vector), NULL);
+			__do_IRQ(local_vector_to_irq(vector), NULL);
 
 			/*
 			 * Disable interrupts and send EOI
diff -Nru a/arch/ia64/kernel/ivt.S b/arch/ia64/kernel/ivt.S
--- a/arch/ia64/kernel/ivt.S	2005-03-01 23:38:53 -08:00
+++ b/arch/ia64/kernel/ivt.S	2005-03-01 23:38:53 -08:00
@@ -51,6 +51,7 @@
 #include <asm/system.h>
 #include <asm/thread_info.h>
 #include <asm/unistd.h>
+#include <asm/errno.h>
 
 #if 1
 # define PSR_DEFAULT_BITS	psr.ac
@@ -547,7 +548,7 @@
 #endif
 	mov pr=r31,-1				// restore pr
 	rfi
-END(idirty_bit)
+END(dirty_bit)
 
 	.org ia64_ivt+0x2400
 /////////////////////////////////////////////////////////////////////////////////////////
@@ -732,10 +733,12 @@
 	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
 	;;
-	mov r3=NR_syscalls - 1
 	movl r16=sys_call_table
 
 	adds r15=-1024,r15			// r15 contains the syscall number---subtract 1024
@@ -836,8 +839,11 @@
 	 * 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
 	 *	-  r3: preserved (same as on entry)
+	 *	-  r8: -EINVAL if p10 is true
 	 *	- r12: points to kernel stack
 	 *	- r13: points to current task
 	 *	- p15: TRUE if interrupts need to be re-enabled
@@ -871,12 +877,17 @@
 	;;
 
 	st8 [r16]=r19,PT(AR_RNAT)-PT(CR_IFS)	// store ar.pfs.pfm in cr.ifs
+	extr.u r11=r19,7,7	// I0		// get sol of ar.pfs
+	and r8=0x7f,r19		// A		// get sof of ar.pfs
+
 	st8 [r17]=r27,PT(AR_BSPSTORE)-PT(AR_RSC)// save ar.rsc
+	tbit.nz p15,p0=r29,IA64_PSR_I_BIT // I0
 (p9)	mov in1=-1
+	;;
 
 (pUStk) sub r18=r18,r22				// r18=RSE.ndirty*8
-	tbit.nz p15,p0=r29,IA64_PSR_I_BIT
 	tnat.nz p10,p0=in2
+	add r11=8,r11
 	;;
 (pKStk) adds r16=PT(PR)-PT(AR_RNAT),r16		// skip over ar_rnat field
 (pKStk) adds r17=PT(B0)-PT(AR_BSPSTORE),r17	// skip over ar_bspstore field
@@ -904,25 +915,29 @@
 (p13)	mov in5=-1
 	;;
 	st8 [r16]=r21,PT(R8)-PT(AR_FPSR)	// save ar.fpsr
-	st8.spill [r17]=r15			// save r15
 	tnat.nz p14,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)
+(p9)	tnat.nz p10,p0=r15
 	adds r12=-16,r1		// switch to kernel memory stack (with 16 bytes of scratch)
+
+	st8.spill [r17]=r15			// save r15
 	tnat.nz p8,p0=in7
+	nop.i 0
 
 	mov r13=r2				// establish `current'
 	movl r1=__gp				// establish kernel global pointer
 	;;
 (p14)	mov in6=-1
 (p8)	mov in7=-1
-	tnat.nz p9,p0=r15
+	nop.i 0
 
 	cmp.eq pSys,pNonSys=r0,r0		// set pSys=1, pNonSys=0
 	movl r17=FPSR_DEFAULT
 	;;
 	mov.m ar.fpsr=r17			// set ar.fpsr to kernel default value
-(p9)	mov r15=-1
+(p10)	mov r8=-EINVAL
 	br.ret.sptk.many b7
 END(ia64_syscall_setup)
 
diff -Nru a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c
--- a/arch/ia64/kernel/mca.c	2005-03-01 23:38:57 -08:00
+++ b/arch/ia64/kernel/mca.c	2005-03-01 23:38:57 -08:00
@@ -67,6 +67,7 @@
 
 #include <asm/delay.h>
 #include <asm/machvec.h>
+#include <asm/meminit.h>
 #include <asm/page.h>
 #include <asm/ptrace.h>
 #include <asm/system.h>
@@ -85,12 +86,13 @@
 /* Used by mca_asm.S */
 ia64_mca_sal_to_os_state_t	ia64_sal_to_os_handoff_state;
 ia64_mca_os_to_sal_state_t	ia64_os_to_sal_handoff_state;
-u64				ia64_mca_proc_state_dump[512];
-u64				ia64_mca_stack[1024] __attribute__((aligned(16)));
-u64				ia64_mca_stackframe[32];
-u64				ia64_mca_bspstore[1024];
-u64				ia64_init_stack[KERNEL_STACK_SIZE/8] __attribute__((aligned(16)));
 u64				ia64_mca_serialize;
+DEFINE_PER_CPU(u64, ia64_mca_data); /* == __per_cpu_mca[smp_processor_id()] */
+DEFINE_PER_CPU(u64, ia64_mca_per_cpu_pte); /* PTE to map per-CPU area */
+DEFINE_PER_CPU(u64, ia64_mca_pal_pte);	    /* PTE to map PAL code */
+DEFINE_PER_CPU(u64, ia64_mca_pal_base);    /* vaddr PAL code granule */
+
+unsigned long __per_cpu_mca[NR_CPUS];
 
 /* In mca_asm.S */
 extern void			ia64_monarch_init_handler (void);
@@ -98,8 +100,6 @@
 
 static ia64_mc_info_t		ia64_mc_info;
 
-struct ia64_mca_tlb_info ia64_mca_tlb_list[NR_CPUS];
-
 #define MAX_CPE_POLL_INTERVAL (15*60*HZ) /* 15 minutes */
 #define MIN_CPE_POLL_INTERVAL (2*60*HZ)  /* 2 minutes */
 #define CMC_POLL_INTERVAL     (1*60*HZ)  /* 1 minute */
@@ -240,6 +240,7 @@
 ia64_mca_log_sal_error_record(int sal_info_type)
 {
 	u8 *buffer;
+	sal_log_record_header_t *rh;
 	u64 size;
 	int irq_safe = sal_info_type != SAL_INFO_TYPE_MCA && sal_info_type != SAL_INFO_TYPE_INIT;
 #ifdef IA64_MCA_DEBUG_INFO
@@ -258,7 +259,8 @@
 			sal_info_type < ARRAY_SIZE(rec_name) ? rec_name[sal_info_type] : "UNKNOWN");
 
 	/* Clear logs from corrected errors in case there's no user-level logger */
-	if (sal_info_type == SAL_INFO_TYPE_CPE || sal_info_type == SAL_INFO_TYPE_CMC)
+	rh = (sal_log_record_header_t *)buffer;
+	if (rh->severity == sal_log_severity_corrected)
 		ia64_sal_clear_state_info(sal_info_type);
 }
 
@@ -276,7 +278,7 @@
 {
 	static unsigned long	cpe_history[CPE_HISTORY_LENGTH];
 	static int		index;
-	static spinlock_t	cpe_history_lock = SPIN_LOCK_UNLOCKED;
+	static DEFINE_SPINLOCK(cpe_history_lock);
 
 	IA64_MCA_DEBUG("%s: received interrupt vector = %#x on CPU %d\n",
 		       __FUNCTION__, cpe_irq, smp_processor_id());
@@ -887,6 +889,11 @@
 			&ia64_sal_to_os_handoff_state,
 			&ia64_os_to_sal_handoff_state)); 
 
+	if (recover) {
+		sal_log_record_header_t *rh = IA64_LOG_CURR_BUFFER(SAL_INFO_TYPE_MCA);
+		rh->severity = sal_log_severity_corrected;
+		ia64_sal_clear_state_info(SAL_INFO_TYPE_MCA);
+	}
 	/*
 	 *  Wakeup all the processors which are spinning in the rendezvous
 	 *  loop.
@@ -920,7 +927,7 @@
 {
 	static unsigned long	cmc_history[CMC_HISTORY_LENGTH];
 	static int		index;
-	static spinlock_t	cmc_history_lock = SPIN_LOCK_UNLOCKED;
+	static DEFINE_SPINLOCK(cmc_history_lock);
 
 	IA64_MCA_DEBUG("%s: received interrupt vector = %#x on CPU %d\n",
 		       __FUNCTION__, cmc_irq, smp_processor_id());
@@ -1133,6 +1140,7 @@
 	pal_min_state_area_t *ms;
 
 	oops_in_progress = 1;	/* avoid deadlock in printk, but it makes recovery dodgy */
+	console_loglevel = 15;	/* make sure printks make it to console */
 
 	printk(KERN_INFO "Entered OS INIT handler. PSP=%lx\n",
 		ia64_sal_to_os_handoff_state.proc_state_param);
@@ -1193,6 +1201,53 @@
 	.name =		"cpe_poll"
 };
 #endif /* CONFIG_ACPI */
+
+/* Do per-CPU MCA-related initialization.  */
+
+void __devinit
+ia64_mca_cpu_init(void *cpu_data)
+{
+	void *pal_vaddr;
+
+	if (smp_processor_id() == 0) {
+		void *mca_data;
+		int cpu;
+
+		mca_data = alloc_bootmem(sizeof(struct ia64_mca_cpu)
+					 * NR_CPUS);
+		for (cpu = 0; cpu < NR_CPUS; cpu++) {
+			__per_cpu_mca[cpu] = __pa(mca_data);
+			mca_data += sizeof(struct ia64_mca_cpu);
+		}
+	}
+
+        /*
+         * The MCA info structure was allocated earlier and its
+         * physical address saved in __per_cpu_mca[cpu].  Copy that
+         * address * to ia64_mca_data so we can access it as a per-CPU
+         * variable.
+         */
+	__get_cpu_var(ia64_mca_data) = __per_cpu_mca[smp_processor_id()];
+
+	/*
+	 * Stash away a copy of the PTE needed to map the per-CPU page.
+	 * We may need it during MCA recovery.
+	 */
+	__get_cpu_var(ia64_mca_per_cpu_pte) =
+		pte_val(mk_pte_phys(__pa(cpu_data), PAGE_KERNEL));
+
+        /*
+         * Also, stash away a copy of the PAL address and the PTE
+         * needed to map it.
+         */
+        pal_vaddr = efi_get_pal_addr();
+	if (!pal_vaddr)
+		return;
+	__get_cpu_var(ia64_mca_pal_base) =
+		GRANULEROUNDDOWN((unsigned long) pal_vaddr);
+	__get_cpu_var(ia64_mca_pal_pte) = pte_val(mk_pte_phys(__pa(pal_vaddr),
+							      PAGE_KERNEL));
+}
 
 /*
  * ia64_mca_init
diff -Nru a/arch/ia64/kernel/mca_asm.S b/arch/ia64/kernel/mca_asm.S
--- a/arch/ia64/kernel/mca_asm.S	2005-03-01 23:39:09 -08:00
+++ b/arch/ia64/kernel/mca_asm.S	2005-03-01 23:39:09 -08:00
@@ -13,6 +13,9 @@
 //		   2. Restore current thread pointer to kr6
 //		   3. Move stack ptr 16 bytes to conform to C calling convention
 //
+// 04/11/12 Russ Anderson <rja@sgi.com>
+//		   Added per cpu MCA/INIT stack save areas.
+//
 #include <linux/config.h>
 #include <linux/threads.h>
 
@@ -98,15 +101,15 @@
 	ld8	tmp=[sal_to_os_handoff];;				\
 	st8     [os_to_sal_handoff]=tmp;;
 
+#define GET_IA64_MCA_DATA(reg)						\
+	GET_THIS_PADDR(reg, ia64_mca_data)				\
+	;;								\
+	ld8 reg=[reg]
+
 	.global ia64_os_mca_dispatch
 	.global ia64_os_mca_dispatch_end
 	.global ia64_sal_to_os_handoff_state
 	.global	ia64_os_to_sal_handoff_state
-	.global	ia64_mca_proc_state_dump
-	.global	ia64_mca_stack
-	.global	ia64_mca_stackframe
-	.global	ia64_mca_bspstore
-	.global ia64_init_stack
 
 	.text
 	.align 16
@@ -146,36 +149,26 @@
 	// The following code purges TC and TR entries. Then reload all TC entries.
 	// Purge percpu data TC entries.
 begin_tlb_purge_and_reload:
-	mov r16=cr.lid
-	LOAD_PHYSICAL(p0,r17,ia64_mca_tlb_list) // Physical address of ia64_mca_tlb_list
-	mov r19=0
-	mov r20=NR_CPUS
-	;;
-1:	cmp.eq p6,p7=r19,r20
-(p6)	br.spnt.few err
-	ld8 r18=[r17],IA64_MCA_TLB_INFO_SIZE
-	;;
-	add r19=1,r19
-	cmp.eq p6,p7=r18,r16
-(p7)	br.sptk.few 1b
-	;;
-	adds r17=-IA64_MCA_TLB_INFO_SIZE,r17
-	;;
-	mov r23=r17		// save current ia64_mca_percpu_info addr pointer.
-	adds r17=16,r17
+
+#define O(member)	IA64_CPUINFO_##member##_OFFSET
+
+	GET_THIS_PADDR(r2, cpu_info)	// load phys addr of cpu_info into r2
 	;;
-	ld8 r18=[r17],8		// r18=ptce_base
-  	;;
-	ld4 r19=[r17],4		// r19=ptce_count[0]
+	addl r17=O(PTCE_STRIDE),r2
+	addl r2=O(PTCE_BASE),r2
 	;;
-	ld4 r20=[r17],4		// r20=ptce_count[1]
+	ld8 r18=[r2],(O(PTCE_COUNT)-O(PTCE_BASE));;	// r18=ptce_base
+	ld4 r19=[r2],4					// r19=ptce_count[0]
+	ld4 r21=[r17],4					// r21=ptce_stride[0]
 	;;
-	ld4 r21=[r17],4		// r21=ptce_stride[0]
+	ld4 r20=[r2]					// r20=ptce_count[1]
+	ld4 r22=[r17]					// r22=ptce_stride[1]
 	mov r24=0
 	;;
-	ld4 r22=[r17],4		// r22=ptce_stride[1]
 	adds r20=-1,r20
 	;;
+#undef O
+
 2:
 	cmp.ltu p6,p7=r24,r19
 (p7)	br.cond.dpnt.few 4f
@@ -215,9 +208,9 @@
 	srlz.d
 	;;
 	// 3. Purge ITR for PAL code.
-	adds r17=48,r23
+	GET_THIS_PADDR(r2, ia64_mca_pal_base)
 	;;
-	ld8 r16=[r17]
+	ld8 r16=[r2]
 	mov r18=IA64_GRANULE_SHIFT<<2
 	;;
 	ptr.i r16,r18
@@ -260,14 +253,15 @@
 	srlz.d
 	;;
 	// 2. Reload DTR register for PERCPU data.
-	adds r17=8,r23
+	GET_THIS_PADDR(r2, ia64_mca_per_cpu_pte)
+	;;
 	movl r16=PERCPU_ADDR		// vaddr
 	movl r18=PERCPU_PAGE_SHIFT<<2
 	;;
 	mov cr.itir=r18
 	mov cr.ifa=r16
 	;;
-	ld8 r18=[r17]			// pte
+	ld8 r18=[r2]			// load per-CPU PTE
 	mov r16=IA64_TR_PERCPU_DATA;
 	;;
 	itr.d dtr[r16]=r18
@@ -275,11 +269,13 @@
 	srlz.d
 	;;
 	// 3. Reload ITR for PAL code.
-	adds r17=40,r23
+	GET_THIS_PADDR(r2, ia64_mca_pal_pte)
+	;;
+	ld8 r18=[r2]			// load PAL PTE
 	;;
-	ld8 r18=[r17],8			// pte
+	GET_THIS_PADDR(r2, ia64_mca_pal_base)
 	;;
-	ld8 r16=[r17]			// vaddr
+	ld8 r16=[r2]			// load PAL vaddr
 	mov r19=IA64_GRANULE_SHIFT<<2
 	;;
 	mov cr.itir=r19
@@ -318,17 +314,18 @@
 done_tlb_purge_and_reload:
 
 	// Setup new stack frame for OS_MCA handling
-	movl	r2=ia64_mca_bspstore;;	// local bspstore area location in r2
-	DATA_VA_TO_PA(r2);;
-	movl	r3=ia64_mca_stackframe;; // save stack frame to memory in r3
-	DATA_VA_TO_PA(r3);;
+	GET_IA64_MCA_DATA(r2)
+	;;
+	add r3 = IA64_MCA_CPU_STACKFRAME_OFFSET, r2
+	add r2 = IA64_MCA_CPU_RBSTORE_OFFSET, r2
+	;;
 	rse_switch_context(r6,r3,r2);;	// RSC management in this new context
-	movl	r12=ia64_mca_stack
-	mov	r2=8*1024;;		// stack size must be same as C array
-	add	r12=r2,r12;;		// stack base @ bottom of array
-	adds	r12=-16,r12;;		// allow 16 bytes of scratch
-					// (C calling convention)
-	DATA_VA_TO_PA(r12);;
+
+	GET_IA64_MCA_DATA(r2)
+	;;
+	add r2 = IA64_MCA_CPU_STACK_OFFSET+IA64_MCA_STACK_SIZE-16, r2
+	;;
+	mov r12=r2		// establish new stack-pointer
 
         // Enter virtual mode from physical mode
 	VIRTUAL_MODE_ENTER(r2, r3, ia64_os_mca_virtual_begin, r4)
@@ -344,9 +341,10 @@
 ia64_os_mca_virtual_end:
 
 	// restore the original stack frame here
-	movl    r2=ia64_mca_stackframe	// restore stack frame from memory at r2
+	GET_IA64_MCA_DATA(r2)
+	;;
+	add r2 = IA64_MCA_CPU_STACKFRAME_OFFSET, r2
 	;;
-	DATA_VA_TO_PA(r2)
 	movl    r4=IA64_PSR_MC
 	;;
 	rse_return_context(r4,r3,r2)	// switch from interrupt context for RSE
@@ -387,8 +385,10 @@
 ia64_os_mca_proc_state_dump:
 // Save bank 1 GRs 16-31 which will be used by c-language code when we switch
 //  to virtual addressing mode.
-	LOAD_PHYSICAL(p0,r2,ia64_mca_proc_state_dump)// convert OS state dump area to physical address
-
+	GET_IA64_MCA_DATA(r2)
+	;;
+	add r2 = IA64_MCA_CPU_PROC_STATE_DUMP_OFFSET, r2
+	;;
 // save ar.NaT
 	mov		r5=ar.unat                  // ar.unat
 
@@ -618,9 +618,9 @@
 ia64_os_mca_proc_state_restore:
 
 // Restore bank1 GR16-31
-	movl		r2=ia64_mca_proc_state_dump	// Convert virtual address
-	;;						// of OS state dump area
-	DATA_VA_TO_PA(r2)				// to physical address
+	GET_IA64_MCA_DATA(r2)
+	;;
+	add r2 = IA64_MCA_CPU_PROC_STATE_DUMP_OFFSET, r2
 
 restore_GRs:                                    // restore bank-1 GRs 16-31
 	bsw.1;;
diff -Nru a/arch/ia64/kernel/mca_drv.c b/arch/ia64/kernel/mca_drv.c
--- a/arch/ia64/kernel/mca_drv.c	2005-03-01 23:39:08 -08:00
+++ b/arch/ia64/kernel/mca_drv.c	2005-03-01 23:39:08 -08:00
@@ -45,14 +45,14 @@
 /* from mca_drv_asm.S */
 extern void *mca_handler_bhhook(void);
 
-static spinlock_t mca_bh_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(mca_bh_lock);
 
 typedef enum {
 	MCA_IS_LOCAL  = 0,
 	MCA_IS_GLOBAL = 1
 } mca_type_t;
 
-#define MAX_PAGE_ISOLATE 32
+#define MAX_PAGE_ISOLATE 1024
 
 static struct page *page_isolate[MAX_PAGE_ISOLATE];
 static int num_page_isolate = 0;
diff -Nru a/arch/ia64/kernel/minstate.h b/arch/ia64/kernel/minstate.h
--- a/arch/ia64/kernel/minstate.h	2005-03-01 23:39:09 -08:00
+++ b/arch/ia64/kernel/minstate.h	2005-03-01 23:39:09 -08:00
@@ -37,12 +37,15 @@
  * go virtual and don't want to destroy the iip or ipsr.
  */
 #define MINSTATE_START_SAVE_MIN_PHYS								\
-(pKStk) movl sp=ia64_init_stack+IA64_STK_OFFSET-IA64_PT_REGS_SIZE;				\
+(pKStk) mov r3=IA64_KR(PER_CPU_DATA);;								\
+(pKStk) addl r3=THIS_CPU(ia64_mca_data),r3;;							\
+(pKStk) ld8 r3 = [r3];;										\
+(pKStk) addl r3=IA64_MCA_CPU_INIT_STACK_OFFSET,r3;;						\
+(pKStk) addl sp=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r3;						\
 (pUStk)	mov ar.rsc=0;		/* set enforced lazy mode, pl 0, little-endian, loadrs=0 */	\
 (pUStk)	addl r22=IA64_RBS_OFFSET,r1;		/* compute base of register backing store */	\
 	;;											\
 (pUStk)	mov r24=ar.rnat;									\
-(pKStk) tpa r1=sp;				/* compute physical addr of sp	*/		\
 (pUStk)	addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r1;	/* compute base of memory stack */	\
 (pUStk)	mov r23=ar.bspstore;				/* save ar.bspstore */			\
 (pUStk)	dep r22=-1,r22,61,3;			/* compute kernel virtual addr of RBS */	\
diff -Nru a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c
--- a/arch/ia64/kernel/perfmon.c	2005-03-01 23:39:16 -08:00
+++ b/arch/ia64/kernel/perfmon.c	2005-03-01 23:39:16 -08:00
@@ -5,13 +5,13 @@
  * The initial version of perfmon.c was written by
  * Ganesh Venkitachalam, IBM Corp.
  *
- * Then it was modified for perfmon-1.x by Stephane Eranian and 
+ * Then it was modified for perfmon-1.x by Stephane Eranian and
  * David Mosberger, Hewlett Packard Co.
- * 
+ *
  * Version Perfmon-2.x is a rewrite of perfmon-1.x
- * by Stephane Eranian, Hewlett Packard Co. 
+ * by Stephane Eranian, Hewlett Packard Co.
  *
- * Copyright (C) 1999-2003  Hewlett Packard Co
+ * Copyright (C) 1999-2003, 2005  Hewlett Packard Co
  *               Stephane Eranian <eranian@hpl.hp.com>
  *               David Mosberger-Tang <davidm@hpl.hp.com>
  *
@@ -2160,9 +2160,7 @@
 
 	DPRINT(("new inode ino=%ld @%p\n", inode->i_ino, inode));
 
-	inode->i_sb   = pfmfs_mnt->mnt_sb;
 	inode->i_mode = S_IFCHR|S_IRUGO;
-	inode->i_sock = 0;
 	inode->i_uid  = current->fsuid;
 	inode->i_gid  = current->fsgid;
 
@@ -4780,10 +4778,8 @@
  * system-call entry point (must return long)
  */
 asmlinkage long
-sys_perfmonctl (int fd, int cmd, void __user *arg, int count, long arg5, long arg6, long arg7,
-		long arg8, long stack)
+sys_perfmonctl (int fd, int cmd, void __user *arg, int count)
 {
-	struct pt_regs *regs = (struct pt_regs *)&stack;
 	struct file *file = NULL;
 	pfm_context_t *ctx = NULL;
 	unsigned long flags = 0UL;
@@ -4907,7 +4903,7 @@
 	if (unlikely(ret)) goto abort_locked;
 
 skip_fd:
-	ret = (*func)(ctx, args_k, count, regs);
+	ret = (*func)(ctx, args_k, count, ia64_task_regs(current));
 
 	call_made = 1;
 
@@ -6673,8 +6669,7 @@
 }
 #else  /* !CONFIG_PERFMON */
 asmlinkage long
-sys_perfmonctl (int fd, int cmd, void *arg, int count, long arg5, long arg6, long arg7,
-		long arg8, long stack)
+sys_perfmonctl (int fd, int cmd, void *arg, int count)
 {
 	return -ENOSYS;
 }
diff -Nru a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c
--- a/arch/ia64/kernel/process.c	2005-03-01 23:38:57 -08:00
+++ b/arch/ia64/kernel/process.c	2005-03-01 23:38:57 -08:00
@@ -25,6 +25,7 @@
 #include <linux/unistd.h>
 #include <linux/efi.h>
 #include <linux/interrupt.h>
+#include <linux/delay.h>
 
 #include <asm/cpu.h>
 #include <asm/delay.h>
@@ -39,6 +40,8 @@
 #include <asm/unwind.h>
 #include <asm/user.h>
 
+#include "entry.h"
+
 #ifdef CONFIG_PERFMON
 # include <asm/perfmon.h>
 #endif
@@ -46,6 +49,7 @@
 #include "sigframe.h"
 
 void (*ia64_mark_idle)(int);
+static cpumask_t cpu_idle_map;
 
 unsigned long boot_option_idle_override = 0;
 EXPORT_SYMBOL(boot_option_idle_override);
@@ -225,10 +229,28 @@
 }
 #endif /* CONFIG_HOTPLUG_CPU */
 
+
+void cpu_idle_wait(void)
+{
+        int cpu;
+        cpumask_t map;
+
+        for_each_online_cpu(cpu)
+                cpu_set(cpu, cpu_idle_map);
+
+        wmb();
+        do {
+                ssleep(1);
+                cpus_and(map, cpu_idle_map, cpu_online_map);
+        } while (!cpus_empty(map));
+}
+EXPORT_SYMBOL_GPL(cpu_idle_wait);
+
 void __attribute__((noreturn))
-cpu_idle (void *unused)
+cpu_idle (void)
 {
 	void (*mark_idle)(int) = ia64_mark_idle;
+	int cpu = smp_processor_id();
 
 	/* endless idle loop with no priority at all */
 	while (1) {
@@ -241,17 +263,14 @@
 
 			if (mark_idle)
 				(*mark_idle)(1);
-			/*
-			 * Mark this as an RCU critical section so that
-			 * synchronize_kernel() in the unload path waits
-			 * for our completion.
-			 */
-			rcu_read_lock();
+
+			if (cpu_isset(cpu, cpu_idle_map))
+				cpu_clear(cpu, cpu_idle_map);
+			rmb();
 			idle = pm_idle;
 			if (!idle)
 				idle = default_idle;
 			(*idle)();
-			rcu_read_unlock();
 		}
 
 		if (mark_idle)
@@ -613,7 +632,7 @@
 	return 1;	/* f0-f31 are always valid so we always return 1 */
 }
 
-asmlinkage long
+long
 sys_execve (char __user *filename, char __user * __user *argv, char __user * __user *envp,
 	    struct pt_regs *regs)
 {
@@ -650,7 +669,7 @@
 	regs.pt.cr_ifs = 1UL << 63;		/* mark as valid, empty frame */
 	regs.sw.ar_fpsr = regs.pt.ar_fpsr = ia64_getreg(_IA64_REG_AR_FPSR);
 	regs.sw.ar_bspstore = (unsigned long) current + IA64_RBS_OFFSET;
-
+	regs.sw.pr = (1 << PRED_KERNEL_STACK);
 	return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs.pt, 0, NULL, NULL);
 }
 EXPORT_SYMBOL(kernel_thread);
diff -Nru a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c
--- a/arch/ia64/kernel/ptrace.c	2005-03-01 23:39:17 -08:00
+++ b/arch/ia64/kernel/ptrace.c	2005-03-01 23:39:17 -08:00
@@ -1,11 +1,10 @@
 /*
  * Kernel support for the ptrace() and syscall tracing interfaces.
  *
- * Copyright (C) 1999-2004 Hewlett-Packard Co
+ * Copyright (C) 1999-2005 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  *
- * Derived from the x86 and Alpha versions.  Most of the code in here
- * could actually be factored into a common set of routines.
+ * Derived from the x86 and Alpha versions.
  */
 #include <linux/config.h>
 #include <linux/kernel.h>
@@ -17,6 +16,7 @@
 #include <linux/smp_lock.h>
 #include <linux/user.h>
 #include <linux/security.h>
+#include <linux/audit.h>
 
 #include <asm/pgtable.h>
 #include <asm/processor.h>
@@ -31,9 +31,6 @@
 
 #include "entry.h"
 
-#define p4	(1UL << 4)	/* for pSys (see entry.h) */
-#define p5	(1UL << 5)	/* for pNonSys (see entry.h) */
-
 /*
  * Bits in the PSR that we allow ptrace() to change:
  *	be, up, ac, mfl, mfh (the user mask; five bits total)
@@ -43,9 +40,11 @@
  *	ri (restart instruction; two bits)
  *	is (instruction set; one bit)
  */
-#define IPSR_WRITE_MASK \
-	(IA64_PSR_UM | IA64_PSR_DB | IA64_PSR_IS | IA64_PSR_ID | IA64_PSR_DD | IA64_PSR_RI)
-#define IPSR_READ_MASK	IPSR_WRITE_MASK
+#define IPSR_MASK (IA64_PSR_UM | IA64_PSR_DB | IA64_PSR_IS	\
+		   | IA64_PSR_ID | IA64_PSR_DD | IA64_PSR_RI)
+
+#define MASK(nbits)	((1UL << (nbits)) - 1)	/* mask with NBITS bits set */
+#define PFM_MASK	MASK(38)
 
 #define PTRACE_DEBUG	0
 
@@ -71,23 +70,24 @@
 unsigned long
 ia64_get_scratch_nat_bits (struct pt_regs *pt, unsigned long scratch_unat)
 {
-#	define GET_BITS(first, last, unat)						\
-	({										\
-		unsigned long bit = ia64_unat_pos(&pt->r##first);			\
-		unsigned long mask = ((1UL << (last - first + 1)) - 1) << first;	\
-		unsigned long dist;							\
-		if (bit < first)							\
-			dist = 64 + bit - first;					\
-		else									\
-			dist = bit - first;						\
-		ia64_rotr(unat, dist) & mask;						\
+#	define GET_BITS(first, last, unat)				\
+	({								\
+		unsigned long bit = ia64_unat_pos(&pt->r##first);	\
+		unsigned long nbits = (last - first + 1);		\
+		unsigned long mask = MASK(nbits) << first;		\
+		unsigned long dist;					\
+		if (bit < first)					\
+			dist = 64 + bit - first;			\
+		else							\
+			dist = bit - first;				\
+		ia64_rotr(unat, dist) & mask;				\
 	})
 	unsigned long val;
 
 	/*
-	 * Registers that are stored consecutively in struct pt_regs can be handled in
-	 * parallel.  If the register order in struct_pt_regs changes, this code MUST be
-	 * updated.
+	 * Registers that are stored consecutively in struct pt_regs
+	 * can be handled in parallel.  If the register order in
+	 * struct_pt_regs changes, this code MUST be updated.
 	 */
 	val  = GET_BITS( 1,  1, scratch_unat);
 	val |= GET_BITS( 2,  3, scratch_unat);
@@ -109,23 +109,24 @@
 unsigned long
 ia64_put_scratch_nat_bits (struct pt_regs *pt, unsigned long nat)
 {
-#	define PUT_BITS(first, last, nat)						\
-	({										\
-		unsigned long bit = ia64_unat_pos(&pt->r##first);			\
-		unsigned long mask = ((1UL << (last - first + 1)) - 1) << first;	\
-		long dist;								\
-		if (bit < first)							\
-			dist = 64 + bit - first;					\
-		else									\
-			dist = bit - first;						\
-		ia64_rotl(nat & mask, dist);						\
+#	define PUT_BITS(first, last, nat)				\
+	({								\
+		unsigned long bit = ia64_unat_pos(&pt->r##first);	\
+		unsigned long nbits = (last - first + 1);		\
+		unsigned long mask = MASK(nbits) << first;		\
+		long dist;						\
+		if (bit < first)					\
+			dist = 64 + bit - first;			\
+		else							\
+			dist = bit - first;				\
+		ia64_rotl(nat & mask, dist);				\
 	})
 	unsigned long scratch_unat;
 
 	/*
-	 * Registers that are stored consecutively in struct pt_regs can be handled in
-	 * parallel.  If the register order in struct_pt_regs changes, this code MUST be
-	 * updated.
+	 * Registers that are stored consecutively in struct pt_regs
+	 * can be handled in parallel.  If the register order in
+	 * struct_pt_regs changes, this code MUST be updated.
 	 */
 	scratch_unat  = PUT_BITS( 1,  1, nat);
 	scratch_unat |= PUT_BITS( 2,  3, nat);
@@ -188,10 +189,12 @@
 }
 
 /*
- * This routine is used to read an rnat bits that are stored on the kernel backing store.
- * Since, in general, the alignment of the user and kernel are different, this is not
- * completely trivial.  In essence, we need to construct the user RNAT based on up to two
- * kernel RNAT values and/or the RNAT value saved in the child's pt_regs.
+ * This routine is used to read an rnat bits that are stored on the
+ * kernel backing store.  Since, in general, the alignment of the user
+ * and kernel are different, this is not completely trivial.  In
+ * essence, we need to construct the user RNAT based on up to two
+ * kernel RNAT values and/or the RNAT value saved in the child's
+ * pt_regs.
  *
  * user rbs
  *
@@ -224,24 +227,28 @@
  *					+--------+
  *						  <--- child_stack->ar_bspstore
  *
- * The way to think of this code is as follows: bit 0 in the user rnat corresponds to some
- * bit N (0 <= N <= 62) in one of the kernel rnat value.  The kernel rnat value holding
- * this bit is stored in variable rnat0.  rnat1 is loaded with the kernel rnat value that
+ * The way to think of this code is as follows: bit 0 in the user rnat
+ * corresponds to some bit N (0 <= N <= 62) in one of the kernel rnat
+ * value.  The kernel rnat value holding this bit is stored in
+ * variable rnat0.  rnat1 is loaded with the kernel rnat value that
  * form the upper bits of the user rnat value.
  *
  * Boundary cases:
  *
- * o when reading the rnat "below" the first rnat slot on the kernel backing store,
- *   rnat0/rnat1 are set to 0 and the low order bits are merged in from pt->ar_rnat.
+ * o when reading the rnat "below" the first rnat slot on the kernel
+ *   backing store, rnat0/rnat1 are set to 0 and the low order bits are
+ *   merged in from pt->ar_rnat.
  *
- * o when reading the rnat "above" the last rnat slot on the kernel backing store,
- *   rnat0/rnat1 gets its value from sw->ar_rnat.
+ * o when reading the rnat "above" the last rnat slot on the kernel
+ *   backing store, rnat0/rnat1 gets its value from sw->ar_rnat.
  */
 static unsigned long
 get_rnat (struct task_struct *task, struct switch_stack *sw,
-	  unsigned long *krbs, unsigned long *urnat_addr, unsigned long *urbs_end)
+	  unsigned long *krbs, unsigned long *urnat_addr,
+	  unsigned long *urbs_end)
 {
-	unsigned long rnat0 = 0, rnat1 = 0, urnat = 0, *slot0_kaddr, umask = 0, mask, m;
+	unsigned long rnat0 = 0, rnat1 = 0, urnat = 0, *slot0_kaddr;
+	unsigned long umask = 0, mask, m;
 	unsigned long *kbsp, *ubspstore, *rnat0_kaddr, *rnat1_kaddr, shift;
 	long num_regs, nbits;
 	struct pt_regs *pt;
@@ -254,11 +261,12 @@
 		nbits = ia64_rse_num_regs(urnat_addr - 63, urbs_end);
 	else
 		nbits = 63;
-	mask = (1UL << nbits) - 1;
+	mask = MASK(nbits);
 	/*
-	 * First, figure out which bit number slot 0 in user-land maps to in the kernel
-	 * rnat.  Do this by figuring out how many register slots we're beyond the user's
-	 * backingstore and then computing the equivalent address in kernel space.
+	 * First, figure out which bit number slot 0 in user-land maps
+	 * to in the kernel rnat.  Do this by figuring out how many
+	 * register slots we're beyond the user's backingstore and
+	 * then computing the equivalent address in kernel space.
 	 */
 	num_regs = ia64_rse_num_regs(ubspstore, urnat_addr + 1);
 	slot0_kaddr = ia64_rse_skip_regs(krbs, num_regs);
@@ -268,7 +276,7 @@
 
 	if (ubspstore + 63 > urnat_addr) {
 		/* some bits need to be merged in from pt->ar_rnat */
-		umask = ((1UL << ia64_rse_slot_num(ubspstore)) - 1) & mask;
+		umask = MASK(ia64_rse_slot_num(ubspstore)) & mask;
 		urnat = (pt->ar_rnat & umask);
 		mask &= ~umask;
 		if (!mask)
@@ -326,12 +334,13 @@
 			return;
 		nbits = ia64_rse_num_regs(urnat_addr - 63, urbs_kargs);
 	}
-	mask = (1UL << nbits) - 1;
+	mask = MASK(nbits);
 
 	/*
-	 * First, figure out which bit number slot 0 in user-land maps to in the kernel
-	 * rnat.  Do this by figuring out how many register slots we're beyond the user's
-	 * backingstore and then computing the equivalent address in kernel space.
+	 * First, figure out which bit number slot 0 in user-land maps
+	 * to in the kernel rnat.  Do this by figuring out how many
+	 * register slots we're beyond the user's backingstore and
+	 * then computing the equivalent address in kernel space.
 	 */
 	num_regs = ia64_rse_num_regs(ubspstore, urnat_addr + 1);
 	slot0_kaddr = ia64_rse_skip_regs(krbs, num_regs);
@@ -341,7 +350,7 @@
 
 	if (ubspstore + 63 > urnat_addr) {
 		/* some bits need to be place in pt->ar_rnat: */
-		umask = ((1UL << ia64_rse_slot_num(ubspstore)) - 1) & mask;
+		umask = MASK(ia64_rse_slot_num(ubspstore)) & mask;
 		pt->ar_rnat = (pt->ar_rnat & ~umask) | (urnat & umask);
 		mask &= ~umask;
 		if (!mask)
@@ -367,25 +376,28 @@
 }
 
 static inline int
-on_kernel_rbs (unsigned long addr, unsigned long bspstore, unsigned long urbs_end)
+on_kernel_rbs (unsigned long addr, unsigned long bspstore,
+	       unsigned long urbs_end)
 {
-	return (addr >= bspstore
-		&& addr <= (unsigned long) ia64_rse_rnat_addr((unsigned long *) urbs_end));
+	unsigned long *rnat_addr = ia64_rse_rnat_addr((unsigned long *)
+						      urbs_end);
+	return (addr >= bspstore && addr <= (unsigned long) rnat_addr);
 }
 
 /*
- * Read a word from the user-level backing store of task CHILD.  ADDR is the user-level
- * address to read the word from, VAL a pointer to the return value, and USER_BSP gives
- * the end of the user-level backing store (i.e., it's the address that would be in ar.bsp
- * after the user executed a "cover" instruction).
+ * Read a word from the user-level backing store of task CHILD.  ADDR
+ * is the user-level address to read the word from, VAL a pointer to
+ * the return value, and USER_BSP gives the end of the user-level
+ * backing store (i.e., it's the address that would be in ar.bsp after
+ * the user executed a "cover" instruction).
  *
- * This routine takes care of accessing the kernel register backing store for those
- * registers that got spilled there.  It also takes care of calculating the appropriate
- * RNaT collection words.
+ * This routine takes care of accessing the kernel register backing
+ * store for those registers that got spilled there.  It also takes
+ * care of calculating the appropriate RNaT collection words.
  */
 long
-ia64_peek (struct task_struct *child, struct switch_stack *child_stack, unsigned long user_rbs_end,
-	   unsigned long addr, long *val)
+ia64_peek (struct task_struct *child, struct switch_stack *child_stack,
+	   unsigned long user_rbs_end, unsigned long addr, long *val)
 {
 	unsigned long *bspstore, *krbs, regnum, *laddr, *urbs_end, *rnat_addr;
 	struct pt_regs *child_regs;
@@ -397,10 +409,13 @@
 	child_regs = ia64_task_regs(child);
 	bspstore = (unsigned long *) child_regs->ar_bspstore;
 	krbs = (unsigned long *) child + IA64_RBS_OFFSET/8;
-	if (on_kernel_rbs(addr, (unsigned long) bspstore, (unsigned long) urbs_end)) {
+	if (on_kernel_rbs(addr, (unsigned long) bspstore,
+			  (unsigned long) urbs_end))
+	{
 		/*
-		 * Attempt to read the RBS in an area that's actually on the kernel RBS =>
-		 * read the corresponding bits in the kernel RBS.
+		 * Attempt to read the RBS in an area that's actually
+		 * on the kernel RBS => read the corresponding bits in
+		 * the kernel RBS.
 		 */
 		rnat_addr = ia64_rse_rnat_addr(laddr);
 		ret = get_rnat(child, child_stack, krbs, rnat_addr, urbs_end);
@@ -413,18 +428,23 @@
 
 		if (((1UL << ia64_rse_slot_num(laddr)) & ret) != 0) {
 			/*
-			 * It is implementation dependent whether the data portion of a
-			 * NaT value gets saved on a st8.spill or RSE spill (e.g., see
-			 * EAS 2.6, 4.4.4.6 Register Spill and Fill).  To get consistent
-			 * behavior across all possible IA-64 implementations, we return
-			 * zero in this case.
+			 * It is implementation dependent whether the
+			 * data portion of a NaT value gets saved on a
+			 * st8.spill or RSE spill (e.g., see EAS 2.6,
+			 * 4.4.4.6 Register Spill and Fill).  To get
+			 * consistent behavior across all possible
+			 * IA-64 implementations, we return zero in
+			 * this case.
 			 */
 			*val = 0;
 			return 0;
 		}
 
 		if (laddr < urbs_end) {
-			/* the desired word is on the kernel RBS and is not a NaT */
+			/*
+			 * The desired word is on the kernel RBS and
+			 * is not a NaT.
+			 */
 			regnum = ia64_rse_num_regs(bspstore, laddr);
 			*val = *ia64_rse_skip_regs(krbs, regnum);
 			return 0;
@@ -438,43 +458,51 @@
 }
 
 long
-ia64_poke (struct task_struct *child, struct switch_stack *child_stack, unsigned long user_rbs_end,
-	   unsigned long addr, long val)
+ia64_poke (struct task_struct *child, struct switch_stack *child_stack,
+	   unsigned long user_rbs_end, unsigned long addr, long val)
 {
-	unsigned long *bspstore, *krbs, regnum, *laddr, *urbs_end = (long *) user_rbs_end;
+	unsigned long *bspstore, *krbs, regnum, *laddr;
+	unsigned long *urbs_end = (long *) user_rbs_end;
 	struct pt_regs *child_regs;
 
 	laddr = (unsigned long *) addr;
 	child_regs = ia64_task_regs(child);
 	bspstore = (unsigned long *) child_regs->ar_bspstore;
 	krbs = (unsigned long *) child + IA64_RBS_OFFSET/8;
-	if (on_kernel_rbs(addr, (unsigned long) bspstore, (unsigned long) urbs_end)) {
+	if (on_kernel_rbs(addr, (unsigned long) bspstore,
+			  (unsigned long) urbs_end))
+	{
 		/*
-		 * Attempt to write the RBS in an area that's actually on the kernel RBS
-		 * => write the corresponding bits in the kernel RBS.
+		 * Attempt to write the RBS in an area that's actually
+		 * on the kernel RBS => write the corresponding bits
+		 * in the kernel RBS.
 		 */
 		if (ia64_rse_is_rnat_slot(laddr))
-			put_rnat(child, child_stack, krbs, laddr, val, urbs_end);
+			put_rnat(child, child_stack, krbs, laddr, val,
+				 urbs_end);
 		else {
 			if (laddr < urbs_end) {
 				regnum = ia64_rse_num_regs(bspstore, laddr);
 				*ia64_rse_skip_regs(krbs, regnum) = val;
 			}
 		}
-	} else if (access_process_vm(child, addr, &val, sizeof(val), 1) != sizeof(val)) {
+	} else if (access_process_vm(child, addr, &val, sizeof(val), 1)
+		   != sizeof(val))
 		return -EIO;
-	}
 	return 0;
 }
 
 /*
- * Calculate the address of the end of the user-level register backing store.  This is the
- * address that would have been stored in ar.bsp if the user had executed a "cover"
- * instruction right before entering the kernel.  If CFMP is not NULL, it is used to
- * return the "current frame mask" that was active at the time the kernel was entered.
+ * Calculate the address of the end of the user-level register backing
+ * store.  This is the address that would have been stored in ar.bsp
+ * if the user had executed a "cover" instruction right before
+ * entering the kernel.  If CFMP is not NULL, it is used to return the
+ * "current frame mask" that was active at the time the kernel was
+ * entered.
  */
 unsigned long
-ia64_get_user_rbs_end (struct task_struct *child, struct pt_regs *pt, unsigned long *cfmp)
+ia64_get_user_rbs_end (struct task_struct *child, struct pt_regs *pt,
+		       unsigned long *cfmp)
 {
 	unsigned long *krbs, *bspstore, cfm = pt->cr_ifs;
 	long ndirty;
@@ -494,9 +522,11 @@
 }
 
 /*
- * Synchronize (i.e, write) the RSE backing store living in kernel space to the VM of the
- * CHILD task.  SW and PT are the pointers to the switch_stack and pt_regs structures,
- * respectively.  USER_RBS_END is the user-level address at which the backing store ends.
+ * Synchronize (i.e, write) the RSE backing store living in kernel
+ * space to the VM of the CHILD task.  SW and PT are the pointers to
+ * the switch_stack and pt_regs structures, respectively.
+ * USER_RBS_END is the user-level address at which the backing store
+ * ends.
  */
 long
 ia64_sync_user_rbs (struct task_struct *child, struct switch_stack *sw,
@@ -510,7 +540,8 @@
 		ret = ia64_peek(child, sw, user_rbs_end, addr, &val);
 		if (ret < 0)
 			return ret;
-		if (access_process_vm(child, addr, &val, sizeof(val), 1) != sizeof(val))
+		if (access_process_vm(child, addr, &val, sizeof(val), 1)
+		    != sizeof(val))
 			return -EIO;
 	}
 	return 0;
@@ -524,13 +555,14 @@
 
 	if (ptrace_check_attach(thread, 0) < 0)
 		/*
-		 * If the thread is not in an attachable state, we'll ignore it.
-		 * The net effect is that if ADDR happens to overlap with the
-		 * portion of the thread's register backing store that is
-		 * currently residing on the thread's kernel stack, then ptrace()
-		 * may end up accessing a stale value.  But if the thread isn't
-		 * stopped, that's a problem anyhow, so we're doing as well as we
-		 * can...
+		 * If the thread is not in an attachable state, we'll
+		 * ignore it.  The net effect is that if ADDR happens
+		 * to overlap with the portion of the thread's
+		 * register backing store that is currently residing
+		 * on the thread's kernel stack, then ptrace() may end
+		 * up accessing a stale value.  But if the thread
+		 * isn't stopped, that's a problem anyhow, so we're
+		 * doing as well as we can...
 		 */
 		return 0;
 
@@ -543,10 +575,11 @@
 }
 
 /*
- * GDB apparently wants to be able to read the register-backing store of any thread when
- * attached to a given process.  If we are peeking or poking an address that happens to
- * reside in the kernel-backing store of another thread, we need to attach to that thread,
- * because otherwise we end up accessing stale data.
+ * GDB apparently wants to be able to read the register-backing store
+ * of any thread when attached to a given process.  If we are peeking
+ * or poking an address that happens to reside in the kernel-backing
+ * store of another thread, we need to attach to that thread, because
+ * otherwise we end up accessing stale data.
  *
  * task_list_lock must be read-locked before calling this routine!
  */
@@ -560,7 +593,8 @@
 	if (!(mm = get_task_mm(child)))
 		return child;
 
-	mm_users = atomic_read(&mm->mm_users) - 1;	/* -1 because of our get_task_mm()... */
+	/* -1 because of our get_task_mm(): */
+	mm_users = atomic_read(&mm->mm_users) - 1;
 	if (mm_users <= 1)
 		goto out;		/* not multi-threaded */
 
@@ -630,7 +664,8 @@
 }
 
 static int
-access_fr (struct unw_frame_info *info, int regnum, int hi, unsigned long *data, int write_access)
+access_fr (struct unw_frame_info *info, int regnum, int hi,
+	   unsigned long *data, int write_access)
 {
 	struct ia64_fpreg fpval;
 	int ret;
@@ -652,7 +687,8 @@
  * kernel exit-path, rather than the syscall-exit path.
  */
 static void
-convert_to_non_syscall (struct task_struct *child, struct pt_regs  *pt, unsigned long cfm)
+convert_to_non_syscall (struct task_struct *child, struct pt_regs  *pt,
+			unsigned long cfm)
 {
 	struct unw_frame_info info, prev_info;
 	unsigned long ip, pr;
@@ -669,19 +705,59 @@
 	}
 
 	unw_get_pr(&prev_info, &pr);
-	pr &= ~pSys;
-	pr |= pNonSys;
+	pr &= ~(1UL << PRED_SYSCALL);
+	pr |=  (1UL << PRED_NON_SYSCALL);
 	unw_set_pr(&prev_info, pr);
 
 	pt->cr_ifs = (1UL << 63) | cfm;
 }
 
 static int
-access_uarea (struct task_struct *child, unsigned long addr, unsigned long *data, int write_access)
+access_nat_bits (struct task_struct *child, struct pt_regs *pt,
+		 struct unw_frame_info *info,
+		 unsigned long *data, int write_access)
+{
+	unsigned long regnum, nat_bits, scratch_unat, dummy = 0;
+	char nat = 0;
+
+	if (write_access) {
+		nat_bits = *data;
+		scratch_unat = ia64_put_scratch_nat_bits(pt, nat_bits);
+		if (unw_set_ar(info, UNW_AR_UNAT, scratch_unat) < 0) {
+			dprintk("ptrace: failed to set ar.unat\n");
+			return -1;
+		}
+		for (regnum = 4; regnum <= 7; ++regnum) {
+			unw_get_gr(info, regnum, &dummy, &nat);
+			unw_set_gr(info, regnum, dummy,
+				   (nat_bits >> regnum) & 1);
+		}
+	} else {
+		if (unw_get_ar(info, UNW_AR_UNAT, &scratch_unat) < 0) {
+			dprintk("ptrace: failed to read ar.unat\n");
+			return -1;
+		}
+		nat_bits = ia64_get_scratch_nat_bits(pt, scratch_unat);
+		for (regnum = 4; regnum <= 7; ++regnum) {
+			unw_get_gr(info, regnum, &dummy, &nat);
+			nat_bits |= (nat != 0) << regnum;
+		}
+		*data = nat_bits;
+	}
+	return 0;
+}
+
+static int
+access_uarea (struct task_struct *child, unsigned long addr,
+	      unsigned long *data, int write_access)
 {
 	unsigned long *ptr, regnum, urbs_end, rnat_addr, cfm;
 	struct switch_stack *sw;
 	struct pt_regs *pt;
+#	define pt_reg_addr(pt, reg)	((void *)			    \
+					 ((unsigned long) (pt)		    \
+					  + offsetof(struct pt_regs, reg)))
+
 
 	pt = ia64_task_regs(child);
 	sw = (struct switch_stack *) (child->thread.ksp + 16);
@@ -697,17 +773,20 @@
 			ia64_sync_fph(child);
 		else
 			ia64_flush_fph(child);
-		ptr = (unsigned long *) ((unsigned long) &child->thread.fph + addr);
+		ptr = (unsigned long *)
+			((unsigned long) &child->thread.fph + addr);
 	} else if ((addr >= PT_F10) && (addr < PT_F11 + 16)) {
 		/* scratch registers untouched by kernel (saved in pt_regs) */
-		ptr = (unsigned long *)
-			((long) pt + offsetof(struct pt_regs, f10) + addr - PT_F10);
+		ptr = pt_reg_addr(pt, f10) + (addr - PT_F10);
 	} else if (addr >= PT_F12 && addr < PT_F15 + 16) {
-		/* scratch registers untouched by kernel (saved in switch_stack) */
-		ptr = (unsigned long *) ((long) sw + (addr - PT_NAT_BITS - 32));
+		/*
+		 * Scratch registers untouched by kernel (saved in
+		 * switch_stack).
+		 */
+		ptr = (unsigned long *) ((long) sw
+					 + (addr - PT_NAT_BITS - 32));
 	} else if (addr < PT_AR_LC + 8) {
 		/* preserved state: */
-		unsigned long nat_bits, scratch_unat, dummy = 0;
 		struct unw_frame_info info;
 		char nat = 0;
 		int ret;
@@ -718,62 +797,48 @@
 
 		switch (addr) {
 		      case PT_NAT_BITS:
-			if (write_access) {
-				nat_bits = *data;
-				scratch_unat = ia64_put_scratch_nat_bits(pt, nat_bits);
-				if (unw_set_ar(&info, UNW_AR_UNAT, scratch_unat) < 0) {
-					dprintk("ptrace: failed to set ar.unat\n");
-					return -1;
-				}
-				for (regnum = 4; regnum <= 7; ++regnum) {
-					unw_get_gr(&info, regnum, &dummy, &nat);
-					unw_set_gr(&info, regnum, dummy, (nat_bits >> regnum) & 1);
-				}
-			} else {
-				if (unw_get_ar(&info, UNW_AR_UNAT, &scratch_unat) < 0) {
-					dprintk("ptrace: failed to read ar.unat\n");
-					return -1;
-				}
-				nat_bits = ia64_get_scratch_nat_bits(pt, scratch_unat);
-				for (regnum = 4; regnum <= 7; ++regnum) {
-					unw_get_gr(&info, regnum, &dummy, &nat);
-					nat_bits |= (nat != 0) << regnum;
-				}
-				*data = nat_bits;
-			}
-			return 0;
+			return access_nat_bits(child, pt, &info,
+					       data, write_access);
 
 		      case PT_R4: case PT_R5: case PT_R6: case PT_R7:
 			if (write_access) {
 				/* read NaT bit first: */
 				unsigned long dummy;
 
-				ret = unw_get_gr(&info, (addr - PT_R4)/8 + 4, &dummy, &nat);
+				ret = unw_get_gr(&info, (addr - PT_R4)/8 + 4,
+						 &dummy, &nat);
 				if (ret < 0)
 					return ret;
 			}
-			return unw_access_gr(&info, (addr - PT_R4)/8 + 4, data, &nat,
-					     write_access);
+			return unw_access_gr(&info, (addr - PT_R4)/8 + 4, data,
+					     &nat, write_access);
 
-		      case PT_B1: case PT_B2: case PT_B3: case PT_B4: case PT_B5:
-			return unw_access_br(&info, (addr - PT_B1)/8 + 1, data, write_access);
+		      case PT_B1: case PT_B2: case PT_B3:
+		      case PT_B4: case PT_B5:
+			return unw_access_br(&info, (addr - PT_B1)/8 + 1, data,
+					     write_access);
 
 		      case PT_AR_EC:
-			return unw_access_ar(&info, UNW_AR_EC, data, write_access);
+			return unw_access_ar(&info, UNW_AR_EC, data,
+					     write_access);
 
 		      case PT_AR_LC:
-			return unw_access_ar(&info, UNW_AR_LC, data, write_access);
+			return unw_access_ar(&info, UNW_AR_LC, data,
+					     write_access);
 
 		      default:
 			if (addr >= PT_F2 && addr < PT_F5 + 16)
-				return access_fr(&info, (addr - PT_F2)/16 + 2, (addr & 8) != 0,
-						 data, write_access);
+				return access_fr(&info, (addr - PT_F2)/16 + 2,
+						 (addr & 8) != 0, data,
+						 write_access);
 			else if (addr >= PT_F16 && addr < PT_F31 + 16)
-				return access_fr(&info, (addr - PT_F16)/16 + 16, (addr & 8) != 0,
+				return access_fr(&info,
+						 (addr - PT_F16)/16 + 16,
+						 (addr & 8) != 0,
 						 data, write_access);
 			else {
-				dprintk("ptrace: rejecting access to register address 0x%lx\n",
-					addr);
+				dprintk("ptrace: rejecting access to register "
+					"address 0x%lx\n", addr);
 				return -1;
 			}
 		}
@@ -782,34 +847,49 @@
 		switch (addr) {
 		      case PT_AR_BSP:
 			/*
-			 * By convention, we use PT_AR_BSP to refer to the end of the user-level
-			 * backing store.  Use ia64_rse_skip_regs(PT_AR_BSP, -CFM.sof) to get
-			 * the real value of ar.bsp at the time the kernel was entered.
+			 * By convention, we use PT_AR_BSP to refer to
+			 * the end of the user-level backing store.
+			 * Use ia64_rse_skip_regs(PT_AR_BSP, -CFM.sof)
+			 * to get the real value of ar.bsp at the time
+			 * the kernel was entered.
 			 *
-			 * Furthermore, when changing the contents of PT_AR_BSP (or
-			 * PT_CFM) we MUST copy any users-level stacked registers that are
-			 * stored on the kernel stack back to user-space because
-			 * otherwise, we might end up clobbering kernel stacked registers.
-			 * Also, if this happens while the task is blocked in a system
-			 * call, which convert the state such that the non-system-call
-			 * exit path is used.  This ensures that the proper state will be
-			 * picked up when resuming execution.  However, it *also* means
-			 * that once we write PT_AR_BSP/PT_CFM, it won't be possible to
-			 * modify the syscall arguments of the pending system call any
-			 * longer.  This shouldn't be an issue because modifying
-			 * PT_AR_BSP/PT_CFM generally implies that we're either abandoning
-			 * the pending system call or that we defer it's re-execution
-			 * (e.g., due to GDB doing an inferior function call).
+			 * Furthermore, when changing the contents of
+			 * PT_AR_BSP (or PT_CFM) we MUST copy any
+			 * users-level stacked registers that are
+			 * stored on the kernel stack back to
+			 * user-space because otherwise, we might end
+			 * up clobbering kernel stacked registers.
+			 * Also, if this happens while the task is
+			 * blocked in a system call, which convert the
+			 * state such that the non-system-call exit
+			 * path is used.  This ensures that the proper
+			 * state will be picked up when resuming
+			 * execution.  However, it *also* means that
+			 * once we write PT_AR_BSP/PT_CFM, it won't be
+			 * possible to modify the syscall arguments of
+			 * the pending system call any longer.  This
+			 * shouldn't be an issue because modifying
+			 * PT_AR_BSP/PT_CFM generally implies that
+			 * we're either abandoning the pending system
+			 * call or that we defer it's re-execution
+			 * (e.g., due to GDB doing an inferior
+			 * function call).
 			 */
 			urbs_end = ia64_get_user_rbs_end(child, pt, &cfm);
 			if (write_access) {
 				if (*data != urbs_end) {
 					if (ia64_sync_user_rbs(child, sw,
-							       pt->ar_bspstore, urbs_end) < 0)
+							       pt->ar_bspstore,
+							       urbs_end) < 0)
 						return -1;
 					if (in_syscall(pt))
-						convert_to_non_syscall(child, pt, cfm);
-					/* simulate user-level write of ar.bsp: */
+						convert_to_non_syscall(child,
+								       pt,
+								       cfm);
+					/*
+					 * Simulate user-level write
+					 * of ar.bsp:
+					 */
 					pt->loadrs = 0;
 					pt->ar_bspstore = *data;
 				}
@@ -820,14 +900,17 @@
 		      case PT_CFM:
 			urbs_end = ia64_get_user_rbs_end(child, pt, &cfm);
 			if (write_access) {
-				if (((cfm ^ *data) & 0x3fffffffffUL) != 0) {
+				if (((cfm ^ *data) & PFM_MASK) != 0) {
 					if (ia64_sync_user_rbs(child, sw,
-							       pt->ar_bspstore, urbs_end) < 0)
+							       pt->ar_bspstore,
+							       urbs_end) < 0)
 						return -1;
 					if (in_syscall(pt))
-						convert_to_non_syscall(child, pt, cfm);
-					pt->cr_ifs = ((pt->cr_ifs & ~0x3fffffffffUL)
-						      | (*data & 0x3fffffffffUL));
+						convert_to_non_syscall(child,
+								       pt,
+								       cfm);
+					pt->cr_ifs = ((pt->cr_ifs & ~PFM_MASK)
+						      | (*data & PFM_MASK));
 				}
 			} else
 				*data = cfm;
@@ -835,99 +918,94 @@
 
 		      case PT_CR_IPSR:
 			if (write_access)
-				pt->cr_ipsr = ((*data & IPSR_WRITE_MASK)
-					       | (pt->cr_ipsr & ~IPSR_WRITE_MASK));
+				pt->cr_ipsr = ((*data & IPSR_MASK)
+					       | (pt->cr_ipsr & ~IPSR_MASK));
 			else
-				*data = (pt->cr_ipsr & IPSR_READ_MASK);
+				*data = (pt->cr_ipsr & IPSR_MASK);
 			return 0;
 
 		      case PT_AR_RNAT:
 			urbs_end = ia64_get_user_rbs_end(child, pt, NULL);
-			rnat_addr = (long) ia64_rse_rnat_addr((long *) urbs_end);
+			rnat_addr = (long) ia64_rse_rnat_addr((long *)
+							      urbs_end);
 			if (write_access)
-				return ia64_poke(child, sw, urbs_end, rnat_addr, *data);
+				return ia64_poke(child, sw, urbs_end,
+						 rnat_addr, *data);
 			else
-				return ia64_peek(child, sw, urbs_end, rnat_addr, data);
+				return ia64_peek(child, sw, urbs_end,
+						 rnat_addr, data);
 
 		      case PT_R1:
-			ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, r1));
+			ptr = pt_reg_addr(pt, r1);
 			break;
-
 		      case PT_R2:  case PT_R3:
-			ptr = (unsigned long *)
-				((long) pt + offsetof(struct pt_regs, r2) + addr - PT_R2);
+			ptr = pt_reg_addr(pt, r2) + (addr - PT_R2);
 			break;
 		      case PT_R8:  case PT_R9:  case PT_R10: case PT_R11:
-			ptr = (unsigned long *)
-				((long) pt + offsetof(struct pt_regs, r8)+  addr - PT_R8);
+			ptr = pt_reg_addr(pt, r8) + (addr - PT_R8);
 			break;
 		      case PT_R12: case PT_R13:
-			ptr = (unsigned long *)
-				((long) pt + offsetof(struct pt_regs, r12)+  addr - PT_R12);
+			ptr = pt_reg_addr(pt, r12) + (addr - PT_R12);
 			break;
 		      case PT_R14:
-			ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, r14));
+			ptr = pt_reg_addr(pt, r14);
 			break;
 		      case PT_R15:
-			ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, r15));
+			ptr = pt_reg_addr(pt, r15);
 			break;
 		      case PT_R16: case PT_R17: case PT_R18: case PT_R19:
 		      case PT_R20: case PT_R21: case PT_R22: case PT_R23:
 		      case PT_R24: case PT_R25: case PT_R26: case PT_R27:
 		      case PT_R28: case PT_R29: case PT_R30: case PT_R31:
-			ptr = (unsigned long *)
-				((long) pt + offsetof(struct pt_regs, r16) + addr - PT_R16);
+			ptr = pt_reg_addr(pt, r16) + (addr - PT_R16);
 			break;
 		      case PT_B0:
-			ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, b0));
+			ptr = pt_reg_addr(pt, b0);
 			break;
 		      case PT_B6:
-			ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, b6));
+			ptr = pt_reg_addr(pt, b6);
 			break;
 		      case PT_B7:
-			ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, b7));
+			ptr = pt_reg_addr(pt, b7);
 			break;
 		      case PT_F6:  case PT_F6+8: case PT_F7: case PT_F7+8:
 		      case PT_F8:  case PT_F8+8: case PT_F9: case PT_F9+8:
-			ptr = (unsigned long *)
-				((long) pt + offsetof(struct pt_regs, f6) + addr - PT_F6);
+			ptr = pt_reg_addr(pt, f6) + (addr - PT_F6);
 			break;
 		      case PT_AR_BSPSTORE:
-			ptr = (unsigned long *)
-				((long) pt + offsetof(struct pt_regs, ar_bspstore));
+			ptr = pt_reg_addr(pt, ar_bspstore);
 			break;
 		      case PT_AR_RSC:
-			ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, ar_rsc));
+			ptr = pt_reg_addr(pt, ar_rsc);
 			break;
 		      case PT_AR_UNAT:
-			ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, ar_unat));
+			ptr = pt_reg_addr(pt, ar_unat);
 			break;
 		      case PT_AR_PFS:
-			ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, ar_pfs));
+			ptr = pt_reg_addr(pt, ar_pfs);
 			break;
 		      case PT_AR_CCV:
-			ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, ar_ccv));
+			ptr = pt_reg_addr(pt, ar_ccv);
 			break;
 		      case PT_AR_FPSR:
-			ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, ar_fpsr));
+			ptr = pt_reg_addr(pt, ar_fpsr);
 			break;
 		      case PT_CR_IIP:
-			ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, cr_iip));
+			ptr = pt_reg_addr(pt, cr_iip);
 			break;
 		      case PT_PR:
-			ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, pr));
+			ptr = pt_reg_addr(pt, pr);
 			break;
 			/* scratch register */
 
 		      default:
 			/* disallow accessing anything else... */
-			dprintk("ptrace: rejecting access to register address 0x%lx\n",
-				addr);
+			dprintk("ptrace: rejecting access to register "
+				"address 0x%lx\n", addr);
 			return -1;
 		}
 	} else if (addr <= PT_AR_SSD) {
-		ptr = (unsigned long *)
-			((long) pt + offsetof(struct pt_regs, ar_csd) + addr - PT_AR_CSD);
+		ptr = pt_reg_addr(pt, ar_csd) + (addr - PT_AR_CSD);
 	} else {
 		/* access debug registers */
 
@@ -940,41 +1018,46 @@
 		}
 
 		if (regnum >= 8) {
-			dprintk("ptrace: rejecting access to register address 0x%lx\n", addr);
+			dprintk("ptrace: rejecting access to register "
+				"address 0x%lx\n", addr);
 			return -1;
 		}
 #ifdef CONFIG_PERFMON
 		/*
-		 * Check if debug registers are used by perfmon. This test must be done
-		 * once we know that we can do the operation, i.e. the arguments are all
-		 * valid, but before we start modifying the state.
+		 * Check if debug registers are used by perfmon. This
+		 * test must be done once we know that we can do the
+		 * operation, i.e. the arguments are all valid, but
+		 * before we start modifying the state.
 		 *
-		 * Perfmon needs to keep a count of how many processes are trying to
-		 * modify the debug registers for system wide monitoring sessions.
+		 * Perfmon needs to keep a count of how many processes
+		 * are trying to modify the debug registers for system
+		 * wide monitoring sessions.
 		 *
-		 * We also include read access here, because they may cause the
-		 * PMU-installed debug register state (dbr[], ibr[]) to be reset. The two
-		 * arrays are also used by perfmon, but we do not use
-		 * IA64_THREAD_DBG_VALID. The registers are restored by the PMU context
-		 * switch code.
+		 * We also include read access here, because they may
+		 * cause the PMU-installed debug register state
+		 * (dbr[], ibr[]) to be reset. The two arrays are also
+		 * used by perfmon, but we do not use
+		 * IA64_THREAD_DBG_VALID. The registers are restored
+		 * by the PMU context switch code.
 		 */
 		if (pfm_use_debug_registers(child)) return -1;
 #endif
 
 		if (!(child->thread.flags & IA64_THREAD_DBG_VALID)) {
 			child->thread.flags |= IA64_THREAD_DBG_VALID;
-			memset(child->thread.dbr, 0, sizeof(child->thread.dbr));
-			memset(child->thread.ibr, 0, sizeof(child->thread.ibr));
+			memset(child->thread.dbr, 0,
+			       sizeof(child->thread.dbr));
+			memset(child->thread.ibr, 0,
+			       sizeof(child->thread.ibr));
 		}
 
 		ptr += regnum;
 
-		if (write_access)
-			/* don't let the user set kernel-level breakpoints... */
+		if ((regnum & 1) && write_access) {
+			/* don't let the user set kernel-level breakpoints: */
 			*ptr = *data & ~(7UL << 56);
-		else
-			*data = *ptr;
-		return 0;
+			return 0;
+		}
 	}
 	if (write_access)
 		*ptr = *data;
@@ -995,7 +1078,8 @@
 	char nat = 0;
 	int i;
 
-	retval = verify_area(VERIFY_WRITE, ppr, sizeof(struct pt_all_user_regs));
+	retval = verify_area(VERIFY_WRITE, ppr,
+			     sizeof(struct pt_all_user_regs));
 	if (retval != 0) {
 		return -EIO;
 	}
@@ -1097,11 +1181,13 @@
 
 	/* fr6-fr11 */
 
-	retval |= __copy_to_user(&ppr->fr[6], &pt->f6, sizeof(struct ia64_fpreg) * 6);
+	retval |= __copy_to_user(&ppr->fr[6], &pt->f6,
+				 sizeof(struct ia64_fpreg) * 6);
 
 	/* fp scratch regs(12-15) */
 
-	retval |= __copy_to_user(&ppr->fr[12], &sw->f12, sizeof(struct ia64_fpreg) * 4);
+	retval |= __copy_to_user(&ppr->fr[12], &sw->f12,
+				 sizeof(struct ia64_fpreg) * 4);
 
 	/* fr16-fr31 */
 
@@ -1114,7 +1200,8 @@
 	/* fph */
 
 	ia64_flush_fph(child);
-	retval |= __copy_to_user(&ppr->fr[32], &child->thread.fph, sizeof(ppr->fr[32]) * 96);
+	retval |= __copy_to_user(&ppr->fr[32], &child->thread.fph,
+				 sizeof(ppr->fr[32]) * 96);
 
 	/*  preds */
 
@@ -1141,7 +1228,8 @@
 
 	memset(&fpval, 0, sizeof(fpval));
 
-	retval = verify_area(VERIFY_READ, ppr, sizeof(struct pt_all_user_regs));
+	retval = verify_area(VERIFY_READ, ppr,
+			     sizeof(struct pt_all_user_regs));
 	if (retval != 0) {
 		return -EIO;
 	}
@@ -1189,7 +1277,8 @@
 
 	for (i = 4; i < 8; i++) {
 		retval |= __get_user(val, &ppr->gr[i]);
-		if (unw_set_gr(&info, i, val, 0) < 0)	 /* NaT bit will be set via PT_NAT_BITS */
+		/* NaT bit will be set via PT_NAT_BITS: */
+		if (unw_set_gr(&info, i, val, 0) < 0)
 			return -EIO;
 	}
 
@@ -1233,16 +1322,19 @@
 
 	/* fr6-fr11 */
 
-	retval |= __copy_from_user(&pt->f6, &ppr->fr[6], sizeof(ppr->fr[6]) * 6);
+	retval |= __copy_from_user(&pt->f6, &ppr->fr[6],
+				   sizeof(ppr->fr[6]) * 6);
 
 	/* fp scratch regs(12-15) */
 
-	retval |= __copy_from_user(&sw->f12, &ppr->fr[12], sizeof(ppr->fr[12]) * 4);
+	retval |= __copy_from_user(&sw->f12, &ppr->fr[12],
+				   sizeof(ppr->fr[12]) * 4);
 
 	/* fr16-fr31 */
 
 	for (i = 16; i < 32; i++) {
-		retval |= __copy_from_user(&fpval, &ppr->fr[i], sizeof(fpval));
+		retval |= __copy_from_user(&fpval, &ppr->fr[i],
+					   sizeof(fpval));
 		if (unw_set_fr(&info, i, fpval) < 0)
 			return -EIO;
 	}
@@ -1250,7 +1342,8 @@
 	/* fph */
 
 	ia64_sync_fph(child);
-	retval |= __copy_from_user(&child->thread.fph, &ppr->fr[32], sizeof(ppr->fr[32]) * 96);
+	retval |= __copy_from_user(&child->thread.fph, &ppr->fr[32],
+				   sizeof(ppr->fr[32]) * 96);
 
 	/* preds */
 
@@ -1282,16 +1375,15 @@
 {
 	struct ia64_psr *child_psr = ia64_psr(ia64_task_regs(child));
 
-	/* make sure the single step/take-branch tra bits are not set: */
+	/* make sure the single step/taken-branch trap bits are not set: */
 	child_psr->ss = 0;
 	child_psr->tb = 0;
 }
 
 asmlinkage long
-sys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data,
-	    long arg4, long arg5, long arg6, long arg7, long stack)
+sys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data)
 {
-	struct pt_regs *pt, *regs = (struct pt_regs *) &stack;
+	struct pt_regs *pt;
 	unsigned long urbs_end, peek_or_poke;
 	struct task_struct *child;
 	struct switch_stack *sw;
@@ -1311,8 +1403,10 @@
 		goto out;
 	}
 
-	peek_or_poke = (request == PTRACE_PEEKTEXT || request == PTRACE_PEEKDATA
-			|| request == PTRACE_POKETEXT || request == PTRACE_POKEDATA);
+	peek_or_poke = (request == PTRACE_PEEKTEXT
+			|| request == PTRACE_PEEKDATA
+			|| request == PTRACE_POKETEXT
+			|| request == PTRACE_POKEDATA);
 	ret = -ESRCH;
 	read_lock(&tasklist_lock);
 	{
@@ -1344,31 +1438,37 @@
 
 	switch (request) {
 	      case PTRACE_PEEKTEXT:
-	      case PTRACE_PEEKDATA:		/* read word at location addr */
+	      case PTRACE_PEEKDATA:
+		/* read word at location addr */
 		urbs_end = ia64_get_user_rbs_end(child, pt, NULL);
 		ret = ia64_peek(child, sw, urbs_end, addr, &data);
 		if (ret == 0) {
 			ret = data;
-			regs->r8 = 0;	/* ensure "ret" is not mistaken as an error code */
+			/* ensure "ret" is not mistaken as an error code: */
+			force_successful_syscall_return();
 		}
 		goto out_tsk;
 
 	      case PTRACE_POKETEXT:
-	      case PTRACE_POKEDATA:		/* write the word at location addr */
+	      case PTRACE_POKEDATA:
+		/* write the word at location addr */
 		urbs_end = ia64_get_user_rbs_end(child, pt, NULL);
 		ret = ia64_poke(child, sw, urbs_end, addr, data);
 		goto out_tsk;
 
-	      case PTRACE_PEEKUSR:		/* read the word at addr in the USER area */
+	      case PTRACE_PEEKUSR:
+		/* read the word at addr in the USER area */
 		if (access_uarea(child, addr, &data, 0) < 0) {
 			ret = -EIO;
 			goto out_tsk;
 		}
 		ret = data;
-		regs->r8 = 0;	/* ensure "ret" is not mistaken as an error code */
+		/* ensure "ret" is not mistaken as an error code */
+		force_successful_syscall_return();
 		goto out_tsk;
 
-	      case PTRACE_POKEUSR:	      /* write the word at addr in the USER area */
+	      case PTRACE_POKEUSR:
+		/* write the word at addr in the USER area */
 		if (access_uarea(child, addr, &data, 1) < 0) {
 			ret = -EIO;
 			goto out_tsk;
@@ -1376,16 +1476,20 @@
 		ret = 0;
 		goto out_tsk;
 
-	      case PTRACE_OLD_GETSIGINFO:		/* for backwards-compatibility */
+	      case PTRACE_OLD_GETSIGINFO:
+		/* for backwards-compatibility */
 		ret = ptrace_request(child, PTRACE_GETSIGINFO, addr, data);
 		goto out_tsk;
 
-	      case PTRACE_OLD_SETSIGINFO:		/* for backwards-compatibility */
+	      case PTRACE_OLD_SETSIGINFO:
+		/* for backwards-compatibility */
 		ret = ptrace_request(child, PTRACE_SETSIGINFO, addr, data);
 		goto out_tsk;
 
-	      case PTRACE_SYSCALL:	/* continue and stop at next (return from) syscall */
-	      case PTRACE_CONT:		/* restart after signal. */
+	      case PTRACE_SYSCALL:
+		/* continue and stop at next (return from) syscall */
+	      case PTRACE_CONT:
+		/* restart after signal. */
 		ret = -EIO;
 		if (data > _NSIG)
 			goto out_tsk;
@@ -1395,7 +1499,10 @@
 			clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
 		child->exit_code = data;
 
-		/* make sure the single step/taken-branch trap bits are not set: */
+		/*
+		 * Make sure the single step/taken-branch trap bits
+		 * are not set:
+		 */
 		ia64_psr(pt)->ss = 0;
 		ia64_psr(pt)->tb = 0;
 
@@ -1409,19 +1516,18 @@
 		 * sigkill.  Perhaps it should be put in the status
 		 * that it wants to exit.
 		 */
-		if (child->exit_state == EXIT_ZOMBIE)		/* already dead */
+		if (child->exit_state == EXIT_ZOMBIE)
+			/* already dead */
 			goto out_tsk;
 		child->exit_code = SIGKILL;
 
-		/* make sure the single step/take-branch tra bits are not set: */
-		ia64_psr(pt)->ss = 0;
-		ia64_psr(pt)->tb = 0;
-
+		ptrace_disable(child);
 		wake_up_process(child);
 		ret = 0;
 		goto out_tsk;
 
-	      case PTRACE_SINGLESTEP:		/* let child execute for one instruction */
+	      case PTRACE_SINGLESTEP:
+		/* let child execute for one instruction */
 	      case PTRACE_SINGLEBLOCK:
 		ret = -EIO;
 		if (data > _NSIG)
@@ -1440,16 +1546,19 @@
 		ret = 0;
 		goto out_tsk;
 
-	      case PTRACE_DETACH:		/* detach a process that was attached. */
+	      case PTRACE_DETACH:
+		/* detach a process that was attached. */
 		ret = ptrace_detach(child, data);
 		goto out_tsk;
 
 	      case PTRACE_GETREGS:
-		ret = ptrace_getregs(child, (struct pt_all_user_regs __user *) data);
+		ret = ptrace_getregs(child,
+				     (struct pt_all_user_regs __user *) data);
 		goto out_tsk;
 
 	      case PTRACE_SETREGS:
-		ret = ptrace_setregs(child, (struct pt_all_user_regs __user *) data);
+		ret = ptrace_setregs(child,
+				     (struct pt_all_user_regs __user *) data);
 		goto out_tsk;
 
 	      default:
@@ -1472,15 +1581,16 @@
 	if (!(current->ptrace & PT_PTRACED))
 		return;
 	/*
-	 * The 0x80 provides a way for the tracing parent to distinguish between a syscall
-	 * stop and SIGTRAP delivery.
+	 * 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));
+	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
+	 * 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);
@@ -1492,21 +1602,22 @@
 
 asmlinkage void
 syscall_trace_enter (long arg0, long arg1, long arg2, long arg3,
-		     long arg4, long arg5, long arg6, long arg7, long stack)
+		     long arg4, long arg5, long arg6, long arg7,
+		     struct pt_regs regs)
 {
-	struct pt_regs *regs = (struct pt_regs *) &stack;
 	long syscall;
 
 	if (unlikely(current->audit_context)) {
-		if (IS_IA32_PROCESS(regs))
-			syscall = regs->r1;
+		if (IS_IA32_PROCESS(&regs))
+			syscall = regs.r1;
 		else
-			syscall = regs->r15;
+			syscall = regs.r15;
 
 		audit_syscall_entry(current, syscall, arg0, arg1, arg2, arg3);
 	}
 
-	if (test_thread_flag(TIF_SYSCALL_TRACE) && (current->ptrace & PT_PTRACED))
+	if (test_thread_flag(TIF_SYSCALL_TRACE)
+	    && (current->ptrace & PT_PTRACED))
 		syscall_trace();
 }
 
@@ -1514,11 +1625,13 @@
 
 asmlinkage void
 syscall_trace_leave (long arg0, long arg1, long arg2, long arg3,
-		     long arg4, long arg5, long arg6, long arg7, long stack)
+		     long arg4, long arg5, long arg6, long arg7,
+		     struct pt_regs regs)
 {
 	if (unlikely(current->audit_context))
-		audit_syscall_exit(current, ((struct pt_regs *) &stack)->r8);
+		audit_syscall_exit(current, regs.r8);
 
-	if (test_thread_flag(TIF_SYSCALL_TRACE) && (current->ptrace & PT_PTRACED))
+	if (test_thread_flag(TIF_SYSCALL_TRACE)
+	    && (current->ptrace & PT_PTRACED))
 		syscall_trace();
 }
diff -Nru a/arch/ia64/kernel/sal.c b/arch/ia64/kernel/sal.c
--- a/arch/ia64/kernel/sal.c	2005-03-01 23:39:16 -08:00
+++ b/arch/ia64/kernel/sal.c	2005-03-01 23:39:16 -08:00
@@ -18,7 +18,7 @@
 #include <asm/sal.h>
 #include <asm/pal.h>
 
-spinlock_t sal_lock __cacheline_aligned = SPIN_LOCK_UNLOCKED;
+ __cacheline_aligned DEFINE_SPINLOCK(sal_lock);
 unsigned long sal_platform_features;
 
 unsigned short sal_revision;
diff -Nru a/arch/ia64/kernel/salinfo.c b/arch/ia64/kernel/salinfo.c
--- a/arch/ia64/kernel/salinfo.c	2005-03-01 23:39:08 -08:00
+++ b/arch/ia64/kernel/salinfo.c	2005-03-01 23:39:08 -08:00
@@ -19,6 +19,9 @@
  *
  * Jan 28 2004	kaos@sgi.com
  *   Periodically check for outstanding MCA or INIT records.
+ *
+ * Dec  5 2004	kaos@sgi.com
+ *   Standardize which records are cleared automatically.
  */
 
 #include <linux/types.h>
@@ -230,8 +233,8 @@
 	}
 }
 
-/* Check for outstanding MCA/INIT records every 5 minutes (arbitrary) */
-#define SALINFO_TIMER_DELAY (5*60*HZ)
+/* Check for outstanding MCA/INIT records every minute (arbitrary) */
+#define SALINFO_TIMER_DELAY (60*HZ)
 static struct timer_list salinfo_timer;
 
 static void
@@ -382,8 +385,11 @@
 salinfo_log_read_cpu(void *context)
 {
 	struct salinfo_data *data = context;
+	sal_log_record_header_t *rh;
 	data->log_size = ia64_sal_get_state_info(data->type, (u64 *) data->log_buffer);
-	if (data->type == SAL_INFO_TYPE_CPE || data->type == SAL_INFO_TYPE_CMC)
+	rh = (sal_log_record_header_t *)(data->log_buffer);
+	/* Clear corrected errors as they are read from SAL */
+	if (rh->severity == sal_log_severity_corrected)
 		ia64_sal_clear_state_info(data->type);
 }
 
@@ -457,6 +463,7 @@
 static int
 salinfo_log_clear(struct salinfo_data *data, int cpu)
 {
+	sal_log_record_header_t *rh;
 	data->state = STATE_NO_DATA;
 	if (!test_bit(cpu, &data->cpu_event))
 		return 0;
@@ -469,10 +476,9 @@
 		data->saved_num = 0;
 		spin_unlock_irqrestore(&data_saved_lock, flags);
 	}
-	/* ia64_mca_log_sal_error_record or salinfo_log_read_cpu already cleared
-	 * CPE and CMC errors
-	 */
-	if (data->type != SAL_INFO_TYPE_CPE && data->type != SAL_INFO_TYPE_CMC)
+	rh = (sal_log_record_header_t *)(data->log_buffer);
+	/* Corrected errors have already been cleared from SAL */
+	if (rh->severity != sal_log_severity_corrected)
 		call_on_cpu(cpu, salinfo_log_clear_cpu, data);
 	/* clearing a record may make a new record visible */
 	salinfo_log_new_read(cpu, data);
diff -Nru a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
--- a/arch/ia64/kernel/setup.c	2005-03-01 23:38:52 -08:00
+++ b/arch/ia64/kernel/setup.c	2005-03-01 23:38:52 -08:00
@@ -1,7 +1,7 @@
 /*
  * Architecture-specific setup.
  *
- * Copyright (C) 1998-2001, 2003 Hewlett-Packard Co
+ * Copyright (C) 1998-2001, 2003-2004 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  *	Stephane Eranian <eranian@hpl.hp.com>
  * Copyright (C) 2000, Rohit Seth <rohit.seth@intel.com>
@@ -312,7 +312,28 @@
 	io_port_init();
 
 #ifdef CONFIG_IA64_GENERIC
-	machvec_init(acpi_get_sysname());
+	{
+		const char *mvec_name = strstr (*cmdline_p, "machvec=");
+		char str[64];
+
+		if (mvec_name) {
+			const char *end;
+			size_t len;
+
+			mvec_name += 8;
+			end = strchr (mvec_name, ' ');
+			if (end)
+				len = end - mvec_name;
+			else
+				len = strlen (mvec_name);
+			len = min(len, sizeof (str) - 1);
+			strncpy (str, mvec_name, len);
+			str[len] = '\0';
+			mvec_name = str;
+		} else
+			mvec_name = acpi_get_sysname();
+		machvec_init(mvec_name);
+	}
 #endif
 
 	if (early_console_setup(*cmdline_p) == 0)
@@ -366,7 +387,7 @@
 	/* enable IA-64 Machine Check Abort Handling unless disabled */
 	if (!strstr(saved_command_line, "nomca"))
 		ia64_mca_init();
-	
+
 	platform_setup(cmdline_p);
 	paging_init();
 }
@@ -588,6 +609,14 @@
 
 	cpu_data = per_cpu_init();
 
+	/*
+	 * We set ar.k3 so that assembly code in MCA handler can compute
+	 * physical addresses of per cpu variables with a simple:
+	 *   phys = ar.k3 + &per_cpu_var
+	 */
+	ia64_set_kr(IA64_KR_PER_CPU_DATA,
+		    ia64_tpa(cpu_data) - (long) __per_cpu_start);
+
 	get_max_cacheline_size();
 
 	/*
@@ -634,6 +663,7 @@
 		BUG();
 
 	ia64_mmu_init(ia64_imva(cpu_data));
+	ia64_mca_cpu_init(ia64_imva(cpu_data));
 
 #ifdef CONFIG_IA32_SUPPORT
 	ia32_cpu_init();
diff -Nru a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c
--- a/arch/ia64/kernel/signal.c	2005-03-01 23:38:58 -08:00
+++ b/arch/ia64/kernel/signal.c	2005-03-01 23:38:58 -08:00
@@ -84,12 +84,11 @@
 }
 
 asmlinkage long
-sys_sigaltstack (const stack_t __user *uss, stack_t __user *uoss, long arg2, long arg3, long arg4,
-		 long arg5, long arg6, long arg7, long stack)
+sys_sigaltstack (const stack_t __user *uss, stack_t __user *uoss, long arg2,
+		 long arg3, long arg4, long arg5, long arg6, long arg7,
+		 struct pt_regs regs)
 {
-	struct pt_regs *pt = (struct pt_regs *) &stack;
-
-	return do_sigaltstack(uss, uoss, pt->r12);
+	return do_sigaltstack(uss, uoss, regs.r12);
 }
 
 static long
@@ -588,4 +587,105 @@
 		}
 	}
 	return 0;
+}
+
+/* Set a delayed signal that was detected in MCA/INIT/NMI/PMI context where it
+ * could not be delivered.  It is important that the target process is not
+ * allowed to do any more work in user space.  Possible cases for the target
+ * process:
+ *
+ * - It is sleeping and will wake up soon.  Store the data in the current task,
+ *   the signal will be sent when the current task returns from the next
+ *   interrupt.
+ *
+ * - It is running in user context.  Store the data in the current task, the
+ *   signal will be sent when the current task returns from the next interrupt.
+ *
+ * - It is running in kernel context on this or another cpu and will return to
+ *   user context.  Store the data in the target task, the signal will be sent
+ *   to itself when the target task returns to user space.
+ *
+ * - It is running in kernel context on this cpu and will sleep before
+ *   returning to user context.  Because this is also the current task, the
+ *   signal will not get delivered and the task could sleep indefinitely.
+ *   Store the data in the idle task for this cpu, the signal will be sent
+ *   after the idle task processes its next interrupt.
+ *
+ * To cover all cases, store the data in the target task, the current task and
+ * the idle task on this cpu.  Whatever happens, the signal will be delivered
+ * to the target task before it can do any useful user space work.  Multiple
+ * deliveries have no unwanted side effects.
+ *
+ * Note: This code is executed in MCA/INIT/NMI/PMI context, with interrupts
+ * disabled.  It must not take any locks nor use kernel structures or services
+ * that require locks.
+ */
+
+/* To ensure that we get the right pid, check its start time.  To avoid extra
+ * include files in thread_info.h, convert the task start_time to unsigned long,
+ * giving us a cycle time of > 580 years.
+ */
+static inline unsigned long
+start_time_ul(const struct task_struct *t)
+{
+	return t->start_time.tv_sec * NSEC_PER_SEC + t->start_time.tv_nsec;
+}
+
+void
+set_sigdelayed(pid_t pid, int signo, int code, void __user *addr)
+{
+	struct task_struct *t;
+	unsigned long start_time =  0;
+	int i;
+
+	for (i = 1; i <= 3; ++i) {
+		switch (i) {
+		case 1:
+			t = find_task_by_pid(pid);
+			if (t)
+				start_time = start_time_ul(t);
+			break;
+		case 2:
+			t = current;
+			break;
+		default:
+			t = idle_task(smp_processor_id());
+			break;
+		}
+
+		if (!t)
+			return;
+		t->thread_info->sigdelayed.signo = signo;
+		t->thread_info->sigdelayed.code = code;
+		t->thread_info->sigdelayed.addr = addr;
+		t->thread_info->sigdelayed.start_time = start_time;
+		t->thread_info->sigdelayed.pid = pid;
+		wmb();
+		set_tsk_thread_flag(t, TIF_SIGDELAYED);
+	}
+}
+
+/* Called from entry.S when it detects TIF_SIGDELAYED, a delayed signal that
+ * was detected in MCA/INIT/NMI/PMI context where it could not be delivered.
+ */
+
+void
+do_sigdelayed(void)
+{
+	struct siginfo siginfo;
+	pid_t pid;
+	struct task_struct *t;
+
+	clear_thread_flag(TIF_SIGDELAYED);
+	memset(&siginfo, 0, sizeof(siginfo));
+	siginfo.si_signo = current_thread_info()->sigdelayed.signo;
+	siginfo.si_code = current_thread_info()->sigdelayed.code;
+	siginfo.si_addr = current_thread_info()->sigdelayed.addr;
+	pid = current_thread_info()->sigdelayed.pid;
+	t = find_task_by_pid(pid);
+	if (!t)
+		return;
+	if (current_thread_info()->sigdelayed.start_time != start_time_ul(t))
+		return;
+	force_sig_info(siginfo.si_signo, &siginfo, t);
 }
diff -Nru a/arch/ia64/kernel/smp.c b/arch/ia64/kernel/smp.c
--- a/arch/ia64/kernel/smp.c	2005-03-01 23:39:17 -08:00
+++ b/arch/ia64/kernel/smp.c	2005-03-01 23:39:17 -08:00
@@ -52,7 +52,7 @@
  * Structure and data for smp_call_function(). This is designed to minimise static memory
  * requirements. It also looks cleaner.
  */
-static spinlock_t call_lock __cacheline_aligned = SPIN_LOCK_UNLOCKED;
+static  __cacheline_aligned DEFINE_SPINLOCK(call_lock);
 
 struct call_data_struct {
 	void (*func) (void *info);
diff -Nru a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c
--- a/arch/ia64/kernel/smpboot.c	2005-03-01 23:38:54 -08:00
+++ b/arch/ia64/kernel/smpboot.c	2005-03-01 23:38:54 -08:00
@@ -68,7 +68,7 @@
 #define NUM_ROUNDS	64	/* magic value */
 #define NUM_ITERS	5	/* likewise */
 
-static spinlock_t itc_sync_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(itc_sync_lock);
 static volatile unsigned long go[SLAVE + 1];
 
 #define DEBUG_ITC_SYNC	0
@@ -343,8 +343,6 @@
 int __devinit
 start_secondary (void *unused)
 {
-	extern int cpu_idle (void);
-
 	/* Early console may use I/O ports */
 	ia64_set_kr(IA64_KR_IO_BASE, __pa(ia64_iobase));
 
@@ -353,7 +351,8 @@
 	cpu_init();
 	smp_callin();
 
-	return cpu_idle();
+	cpu_idle();
+	return 0;
 }
 
 struct pt_regs * __devinit idle_regs(struct pt_regs *regs)
@@ -613,8 +612,7 @@
 			 */
 			return;
 		}
-		current->state = TASK_UNINTERRUPTIBLE;
-		schedule_timeout(HZ/10);
+		msleep(100);
 	}
  	printk(KERN_ERR "CPU %u didn't die...\n", cpu);
 }
diff -Nru a/arch/ia64/kernel/sys_ia64.c b/arch/ia64/kernel/sys_ia64.c
--- a/arch/ia64/kernel/sys_ia64.c	2005-03-01 23:38:58 -08:00
+++ b/arch/ia64/kernel/sys_ia64.c	2005-03-01 23:38:58 -08:00
@@ -2,7 +2,7 @@
  * This file contains various system calls that have different calling
  * conventions on different platforms.
  *
- * Copyright (C) 1999-2000, 2002-2003 Hewlett-Packard Co
+ * Copyright (C) 1999-2000, 2002-2003, 2005 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  */
 #include <linux/config.h>
@@ -163,10 +163,9 @@
  * and r9) as this is faster than doing a copy_to_user().
  */
 asmlinkage long
-sys_pipe (long arg0, long arg1, long arg2, long arg3,
-	  long arg4, long arg5, long arg6, long arg7, long stack)
+sys_pipe (void)
 {
-	struct pt_regs *regs = (struct pt_regs *) &stack;
+	struct pt_regs *regs = ia64_task_regs(current);
 	int fd[2];
 	int retval;
 
diff -Nru a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c
--- a/arch/ia64/kernel/time.c	2005-03-01 23:38:53 -08:00
+++ b/arch/ia64/kernel/time.c	2005-03-01 23:38:53 -08:00
@@ -32,7 +32,7 @@
 
 extern unsigned long wall_jiffies;
 
-u64 jiffies_64 = INITIAL_JIFFIES;
+u64 jiffies_64 __cacheline_aligned_in_smp = INITIAL_JIFFIES;
 
 EXPORT_SYMBOL(jiffies_64);
 
diff -Nru a/arch/ia64/kernel/topology.c b/arch/ia64/kernel/topology.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/ia64/kernel/topology.c	2005-03-01 23:39:18 -08:00
@@ -0,0 +1,92 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * This file contains NUMA specific variables and functions which can
+ * be split away from DISCONTIGMEM and are used on NUMA machines with
+ * contiguous memory.
+ * 		2002/08/07 Erich Focht <efocht@ess.nec.de>
+ * Populate cpu entries in sysfs for non-numa systems as well
+ *  	Intel Corporation - Ashok Raj
+ */
+
+#include <linux/config.h>
+#include <linux/cpu.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/node.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+#include <linux/nodemask.h>
+#include <asm/mmzone.h>
+#include <asm/numa.h>
+#include <asm/cpu.h>
+
+#ifdef CONFIG_NUMA
+static struct node *sysfs_nodes;
+#endif
+static struct ia64_cpu *sysfs_cpus;
+
+int arch_register_cpu(int num)
+{
+	struct node *parent = NULL;
+	
+#ifdef CONFIG_NUMA
+	parent = &sysfs_nodes[cpu_to_node(num)];
+#endif /* CONFIG_NUMA */
+
+	return register_cpu(&sysfs_cpus[num].cpu, num, parent);
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+
+void arch_unregister_cpu(int num)
+{
+	struct node *parent = NULL;
+
+#ifdef CONFIG_NUMA
+	int node = cpu_to_node(num);
+	parent = &sysfs_nodes[node];
+#endif /* CONFIG_NUMA */
+
+	return unregister_cpu(&sysfs_cpus[num].cpu, parent);
+}
+EXPORT_SYMBOL(arch_register_cpu);
+EXPORT_SYMBOL(arch_unregister_cpu);
+#endif /*CONFIG_HOTPLUG_CPU*/
+
+
+static int __init topology_init(void)
+{
+	int i, err = 0;
+
+#ifdef CONFIG_NUMA
+	sysfs_nodes = kmalloc(sizeof(struct node) * MAX_NUMNODES, GFP_KERNEL);
+	if (!sysfs_nodes) {
+		err = -ENOMEM;
+		goto out;
+	}
+	memset(sysfs_nodes, 0, sizeof(struct node) * MAX_NUMNODES);
+
+	/* MCD - Do we want to register all ONLINE nodes, or all POSSIBLE nodes? */
+	for_each_online_node(i)
+		if ((err = register_node(&sysfs_nodes[i], i, 0)))
+			goto out;
+#endif
+
+	sysfs_cpus = kmalloc(sizeof(struct ia64_cpu) * NR_CPUS, GFP_KERNEL);
+	if (!sysfs_cpus) {
+		err = -ENOMEM;
+		goto out;
+	}
+	memset(sysfs_cpus, 0, sizeof(struct ia64_cpu) * NR_CPUS);
+
+	for_each_present_cpu(i)
+		if((err = arch_register_cpu(i)))
+			goto out;
+out:
+	return err;
+}
+
+__initcall(topology_init);
diff -Nru a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c
--- a/arch/ia64/kernel/traps.c	2005-03-01 23:39:16 -08:00
+++ b/arch/ia64/kernel/traps.c	2005-03-01 23:39:16 -08:00
@@ -358,11 +358,10 @@
 };
 
 struct illegal_op_return
-ia64_illegal_op_fault (unsigned long ec, unsigned long arg1, unsigned long arg2,
-		       unsigned long arg3, unsigned long arg4, unsigned long arg5,
-		       unsigned long arg6, unsigned long arg7, unsigned long stack)
+ia64_illegal_op_fault (unsigned long ec, long arg1, long arg2, long arg3,
+		       long arg4, long arg5, long arg6, long arg7,
+		       struct pt_regs regs)
 {
-	struct pt_regs *regs = (struct pt_regs *) &stack;
 	struct illegal_op_return rv;
 	struct siginfo si;
 	char buf[128];
@@ -371,19 +370,19 @@
 	{
 		extern struct illegal_op_return ia64_emulate_brl (struct pt_regs *, unsigned long);
 
-		rv = ia64_emulate_brl(regs, ec);
+		rv = ia64_emulate_brl(&regs, ec);
 		if (rv.fkt != (unsigned long) -1)
 			return rv;
 	}
 #endif
 
 	sprintf(buf, "IA-64 Illegal operation fault");
-	die_if_kernel(buf, regs, 0);
+	die_if_kernel(buf, &regs, 0);
 
 	memset(&si, 0, sizeof(si));
 	si.si_signo = SIGILL;
 	si.si_code = ILL_ILLOPC;
-	si.si_addr = (void __user *) (regs->cr_iip + ia64_psr(regs)->ri);
+	si.si_addr = (void __user *) (regs.cr_iip + ia64_psr(&regs)->ri);
 	force_sig_info(SIGILL, &si, current);
 	rv.fkt = 0;
 	return rv;
@@ -391,11 +390,10 @@
 
 void
 ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa,
-	    unsigned long iim, unsigned long itir, unsigned long arg5,
-	    unsigned long arg6, unsigned long arg7, unsigned long stack)
+	    unsigned long iim, unsigned long itir, long arg5, long arg6,
+	    long arg7, struct pt_regs regs)
 {
-	struct pt_regs *regs = (struct pt_regs *) &stack;
-	unsigned long code, error = isr;
+	unsigned long code, error = isr, iip;
 	struct siginfo siginfo;
 	char buf[128];
 	int result, sig;
@@ -415,10 +413,12 @@
 		 * This fault was due to lfetch.fault, set "ed" bit in the psr to cancel
 		 * the lfetch.
 		 */
-		ia64_psr(regs)->ed = 1;
+		ia64_psr(&regs)->ed = 1;
 		return;
 	}
 
+	iip = regs.cr_iip + ia64_psr(&regs)->ri;
+
 	switch (vector) {
 	      case 24: /* General Exception */
 		code = (isr >> 4) & 0xf;
@@ -428,8 +428,8 @@
 		if (code == 8) {
 # ifdef CONFIG_IA64_PRINT_HAZARDS
 			printk("%s[%d]: possible hazard @ ip=%016lx (pr = %016lx)\n",
-			       current->comm, current->pid, regs->cr_iip + ia64_psr(regs)->ri,
-			       regs->pr);
+			       current->comm, current->pid,
+			       regs.cr_iip + ia64_psr(&regs)->ri, regs.pr);
 # endif
 			return;
 		}
@@ -437,14 +437,14 @@
 
 	      case 25: /* Disabled FP-Register */
 		if (isr & 2) {
-			disabled_fph_fault(regs);
+			disabled_fph_fault(&regs);
 			return;
 		}
 		sprintf(buf, "Disabled FPL fault---not supposed to happen!");
 		break;
 
 	      case 26: /* NaT Consumption */
-		if (user_mode(regs)) {
+		if (user_mode(&regs)) {
 			void __user *addr;
 
 			if (((isr >> 4) & 0xf) == 2) {
@@ -456,7 +456,8 @@
 				/* register NaT consumption */
 				sig = SIGILL;
 				code = ILL_ILLOPN;
-				addr = (void __user *) (regs->cr_iip + ia64_psr(regs)->ri);
+				addr = (void __user *) (regs.cr_iip
+							+ ia64_psr(&regs)->ri);
 			}
 			siginfo.si_signo = sig;
 			siginfo.si_code = code;
@@ -467,17 +468,17 @@
 			siginfo.si_isr = isr;
 			force_sig_info(sig, &siginfo, current);
 			return;
-		} else if (ia64_done_with_exception(regs))
+		} else if (ia64_done_with_exception(&regs))
 			return;
 		sprintf(buf, "NaT consumption");
 		break;
 
 	      case 31: /* Unsupported Data Reference */
-		if (user_mode(regs)) {
+		if (user_mode(&regs)) {
 			siginfo.si_signo = SIGILL;
 			siginfo.si_code = ILL_ILLOPN;
 			siginfo.si_errno = 0;
-			siginfo.si_addr = (void __user *) (regs->cr_iip + ia64_psr(regs)->ri);
+			siginfo.si_addr = (void __user *) iip;
 			siginfo.si_imm = vector;
 			siginfo.si_flags = __ISR_VALID;
 			siginfo.si_isr = isr;
@@ -490,7 +491,7 @@
 	      case 29: /* Debug */
 	      case 35: /* Taken Branch Trap */
 	      case 36: /* Single Step Trap */
-		if (fsys_mode(current, regs)) {
+		if (fsys_mode(current, &regs)) {
 			extern char __kernel_syscall_via_break[];
 			/*
 			 * Got a trap in fsys-mode: Taken Branch Trap and Single Step trap
@@ -498,13 +499,13 @@
 			 */
 			if (unlikely(vector == 29)) {
 				die("Got debug trap in fsys-mode---not supposed to happen!",
-				    regs, 0);
+				    &regs, 0);
 				return;
 			}
 			/* re-do the system call via break 0x100000: */
-			regs->cr_iip = (unsigned long) __kernel_syscall_via_break;
-			ia64_psr(regs)->ri = 0;
-			ia64_psr(regs)->cpl = 3;
+			regs.cr_iip = (unsigned long) __kernel_syscall_via_break;
+			ia64_psr(&regs)->ri = 0;
+			ia64_psr(&regs)->cpl = 3;
 			return;
 		}
 		switch (vector) {
@@ -515,8 +516,8 @@
 			 * Erratum 10 (IFA may contain incorrect address) now has
 			 * "NoFix" status.  There are no plans for fixing this.
 			 */
-			if (ia64_psr(regs)->is == 0)
-			  ifa = regs->cr_iip;
+			if (ia64_psr(&regs)->is == 0)
+			  ifa = regs.cr_iip;
 #endif
 			break;
 		      case 35: siginfo.si_code = TRAP_BRANCH; ifa = 0; break;
@@ -533,12 +534,12 @@
 
 	      case 32: /* fp fault */
 	      case 33: /* fp trap */
-		result = handle_fpu_swa((vector == 32) ? 1 : 0, regs, isr);
+		result = handle_fpu_swa((vector == 32) ? 1 : 0, &regs, isr);
 		if ((result < 0) || (current->thread.flags & IA64_THREAD_FPEMU_SIGFPE)) {
 			siginfo.si_signo = SIGFPE;
 			siginfo.si_errno = 0;
 			siginfo.si_code = FPE_FLTINV;
-			siginfo.si_addr = (void __user *) (regs->cr_iip + ia64_psr(regs)->ri);
+			siginfo.si_addr = (void __user *) iip;
 			siginfo.si_flags = __ISR_VALID;
 			siginfo.si_isr = isr;
 			siginfo.si_imm = 0;
@@ -554,19 +555,18 @@
 			 * interesting work (e.g., signal delivery is done in the kernel
 			 * exit path).
 			 */
-			ia64_psr(regs)->lp = 0;
+			ia64_psr(&regs)->lp = 0;
 			return;
 		} else {
 			/* Unimplemented Instr. Address Trap */
-			if (user_mode(regs)) {
+			if (user_mode(&regs)) {
 				siginfo.si_signo = SIGILL;
 				siginfo.si_code = ILL_BADIADDR;
 				siginfo.si_errno = 0;
 				siginfo.si_flags = 0;
 				siginfo.si_isr = 0;
 				siginfo.si_imm = 0;
-				siginfo.si_addr = (void __user *)
-					(regs->cr_iip + ia64_psr(regs)->ri);
+				siginfo.si_addr = (void __user *) iip;
 				force_sig_info(SIGILL, &siginfo, current);
 				return;
 			}
@@ -576,23 +576,23 @@
 
 	      case 45:
 #ifdef CONFIG_IA32_SUPPORT
-		if (ia32_exception(regs, isr) == 0)
+		if (ia32_exception(&regs, isr) == 0)
 			return;
 #endif
 		printk(KERN_ERR "Unexpected IA-32 exception (Trap 45)\n");
 		printk(KERN_ERR "  iip - 0x%lx, ifa - 0x%lx, isr - 0x%lx\n",
-		       regs->cr_iip, ifa, isr);
+		       iip, ifa, isr);
 		force_sig(SIGSEGV, current);
 		break;
 
 	      case 46:
 #ifdef CONFIG_IA32_SUPPORT
-		if (ia32_intercept(regs, isr) == 0)
+		if (ia32_intercept(&regs, isr) == 0)
 			return;
 #endif
 		printk(KERN_ERR "Unexpected IA-32 intercept trap (Trap 46)\n");
 		printk(KERN_ERR "  iip - 0x%lx, ifa - 0x%lx, isr - 0x%lx, iim - 0x%lx\n",
-		       regs->cr_iip, ifa, isr, iim);
+		       iip, ifa, isr, iim);
 		force_sig(SIGSEGV, current);
 		return;
 
@@ -604,6 +604,6 @@
 		sprintf(buf, "Fault %lu", vector);
 		break;
 	}
-	die_if_kernel(buf, regs, error);
+	die_if_kernel(buf, &regs, error);
 	force_sig(SIGILL, current);
 }
diff -Nru a/arch/ia64/kernel/unwind.c b/arch/ia64/kernel/unwind.c
--- a/arch/ia64/kernel/unwind.c	2005-03-01 23:39:18 -08:00
+++ b/arch/ia64/kernel/unwind.c	2005-03-01 23:39:18 -08:00
@@ -47,8 +47,6 @@
 #include "entry.h"
 #include "unwind_i.h"
 
-#define p5		5
-
 #define UNW_LOG_CACHE_SIZE	7	/* each unw_script is ~256 bytes in size */
 #define UNW_CACHE_SIZE		(1 << UNW_LOG_CACHE_SIZE)
 
@@ -1899,7 +1897,7 @@
 	num_regs = 0;
 	if ((info->flags & UNW_FLAG_INTERRUPT_FRAME)) {
 		info->pt = info->sp + 16;
-		if ((pr & (1UL << pNonSys)) != 0)
+		if ((pr & (1UL << PRED_NON_SYSCALL)) != 0)
 			num_regs = *info->cfm_loc & 0x7f;		/* size of frame */
 		info->pfs_loc =
 			(unsigned long *) (info->pt + offsetof(struct pt_regs, ar_pfs));
@@ -1945,7 +1943,7 @@
 int
 unw_unwind_to_user (struct unw_frame_info *info)
 {
-	unsigned long ip;
+	unsigned long ip, sp;
 
 	while (unw_unwind(info) >= 0) {
 		if (unw_get_rp(info, &ip) < 0) {
@@ -1954,6 +1952,9 @@
 				   __FUNCTION__, ip);
 			return -1;
 		}
+		unw_get_sp(info, &sp);
+		if (sp >= (unsigned long)info->task + IA64_STK_OFFSET)
+			break;
 		if (ip < FIXADDR_USER_END)
 			return 0;
 	}
@@ -2051,6 +2052,8 @@
 	find_save_locs(info);
 }
 
+EXPORT_SYMBOL(unw_init_frame_info);
+
 void
 unw_init_from_blocked_task (struct unw_frame_info *info, struct task_struct *t)
 {
@@ -2254,7 +2257,7 @@
 		if (i > 0)
 			unw.cache[i].lru_chain = (i - 1);
 		unw.cache[i].coll_chain = -1;
-		unw.cache[i].lock = RW_LOCK_UNLOCKED;
+		rwlock_init(&unw.cache[i].lock);
 	}
 	unw.lru_head = UNW_CACHE_SIZE - 1;
 	unw.lru_tail = 0;
diff -Nru a/arch/ia64/lib/bitop.c b/arch/ia64/lib/bitop.c
--- a/arch/ia64/lib/bitop.c	2005-03-01 23:39:09 -08:00
+++ b/arch/ia64/lib/bitop.c	2005-03-01 23:39:09 -08:00
@@ -8,7 +8,7 @@
  * Find next zero bit in a bitmap reasonably efficiently..
  */
 
-int __find_next_zero_bit (void *addr, unsigned long size, unsigned long offset)
+int __find_next_zero_bit (const void *addr, unsigned long size, unsigned long offset)
 {
 	unsigned long *p = ((unsigned long *) addr) + (offset >> 6);
 	unsigned long result = offset & ~63UL;
diff -Nru a/arch/ia64/lib/csum_partial_copy.c b/arch/ia64/lib/csum_partial_copy.c
--- a/arch/ia64/lib/csum_partial_copy.c	2005-03-01 23:38:59 -08:00
+++ b/arch/ia64/lib/csum_partial_copy.c	2005-03-01 23:38:59 -08:00
@@ -105,8 +105,8 @@
 extern unsigned long do_csum(const unsigned char *, long);
 
 static unsigned int
-do_csum_partial_copy_from_user (const char __user *src, char *dst, int len,
-				unsigned int psum, int *errp)
+do_csum_partial_copy_from_user (const unsigned char __user *src, unsigned char *dst,
+				int len, unsigned int psum, int *errp)
 {
 	unsigned long result;
 
@@ -129,8 +129,8 @@
 }
 
 unsigned int
-csum_partial_copy_from_user (const char __user *src, char *dst, int len,
-			     unsigned int sum, int *errp)
+csum_partial_copy_from_user (const unsigned char __user *src, unsigned char *dst,
+			     int len, unsigned int sum, int *errp)
 {
 	if (!access_ok(VERIFY_READ, src, len)) {
 		*errp = -EFAULT;
@@ -142,7 +142,8 @@
 }
 
 unsigned int
-csum_partial_copy_nocheck(const char __user *src, char *dst, int len, unsigned int sum)
+csum_partial_copy_nocheck(const unsigned char __user *src, unsigned char *dst,
+			  int len, unsigned int sum)
 {
 	return do_csum_partial_copy_from_user(src, dst, len, sum, NULL);
 }
diff -Nru a/arch/ia64/lib/io.c b/arch/ia64/lib/io.c
--- a/arch/ia64/lib/io.c	2005-03-01 23:38:44 -08:00
+++ b/arch/ia64/lib/io.c	2005-03-01 23:38:44 -08:00
@@ -8,8 +8,7 @@
  * Copy data from IO memory space to "real" memory space.
  * This needs to be optimized.
  */
-void
-__ia64_memcpy_fromio (void *to, volatile void __iomem *from, long count)
+void memcpy_fromio(void *to, const volatile void __iomem *from, long count)
 {
 	char *dst = to;
 
@@ -18,30 +17,28 @@
 		*dst++ = readb(from++);
 	}
 }
-EXPORT_SYMBOL(__ia64_memcpy_fromio);
+EXPORT_SYMBOL(memcpy_fromio);
 
 /*
  * Copy data from "real" memory space to IO memory space.
  * This needs to be optimized.
  */
-void
-__ia64_memcpy_toio (volatile void __iomem *to, void *from, long count)
+void memcpy_toio(volatile void __iomem *to, const void *from, long count)
 {
-	char *src = from;
+	const char *src = from;
 
 	while (count) {
 		count--;
 		writeb(*src++, to++);
 	}
 }
-EXPORT_SYMBOL(__ia64_memcpy_toio);
+EXPORT_SYMBOL(memcpy_toio);
 
 /*
  * "memset" on IO memory space.
  * This needs to be optimized.
  */
-void
-__ia64_memset_c_io (volatile void __iomem *dst, unsigned long c, long count)
+void memset_io(volatile void __iomem *dst, int c, long count)
 {
 	unsigned char ch = (char)(c & 0xff);
 
@@ -51,7 +48,7 @@
 		dst++;
 	}
 }
-EXPORT_SYMBOL(__ia64_memset_c_io);
+EXPORT_SYMBOL(memset_io);
 
 #ifdef CONFIG_IA64_GENERIC
 
diff -Nru a/arch/ia64/lib/memcpy.S b/arch/ia64/lib/memcpy.S
--- a/arch/ia64/lib/memcpy.S	2005-03-01 23:38:44 -08:00
+++ b/arch/ia64/lib/memcpy.S	2005-03-01 23:38:44 -08:00
@@ -15,22 +15,6 @@
  */
 #include <asm/asmmacro.h>
 
-GLOBAL_ENTRY(bcopy)
-	.regstk 3,0,0,0
-	mov r8=in0
-	mov in0=in1
-	;;
-	mov in1=r8
-	// gas doesn't handle control flow across procedures, so it doesn't
-	// realize that a stop bit is needed before the "alloc" instruction
-	// below
-{
-	nop.m 0
-	nop.f 0
-	nop.i 0
-}	;;
-END(bcopy)
-	// FALL THROUGH
 GLOBAL_ENTRY(memcpy)
 
 #	define MEM_LAT	21		/* latency to memory */
diff -Nru a/arch/ia64/lib/memcpy_mck.S b/arch/ia64/lib/memcpy_mck.S
--- a/arch/ia64/lib/memcpy_mck.S	2005-03-01 23:39:18 -08:00
+++ b/arch/ia64/lib/memcpy_mck.S	2005-03-01 23:39:18 -08:00
@@ -17,15 +17,6 @@
 
 #define EK(y...) EX(y)
 
-GLOBAL_ENTRY(bcopy)
-	.regstk 3,0,0,0
-	mov r8=in0
-	mov in0=in1
-	;;
-	mov in1=r8
-	;;
-END(bcopy)
-
 /* McKinley specific optimization */
 
 #define retval		r8
diff -Nru a/arch/ia64/lib/swiotlb.c b/arch/ia64/lib/swiotlb.c
--- a/arch/ia64/lib/swiotlb.c	2005-03-01 23:39:08 -08:00
+++ b/arch/ia64/lib/swiotlb.c	2005-03-01 23:39:08 -08:00
@@ -44,54 +44,57 @@
 #define IO_TLB_SEGSIZE	128
 
 /*
- * log of the size of each IO TLB slab.  The number of slabs is command line controllable.
+ * log of the size of each IO TLB slab.  The number of slabs is command line
+ * controllable.
  */
 #define IO_TLB_SHIFT 11
 
 int swiotlb_force;
 
 /*
- * Used to do a quick range check in swiotlb_unmap_single and swiotlb_sync_single_*, to see
- * if the memory was in fact allocated by this API.
+ * Used to do a quick range check in swiotlb_unmap_single and
+ * swiotlb_sync_single_*, to see if the memory was in fact allocated by this
+ * API.
  */
 static char *io_tlb_start, *io_tlb_end;
 
 /*
- * The number of IO TLB blocks (in groups of 64) betweeen io_tlb_start and io_tlb_end.
- * This is command line adjustable via setup_io_tlb_npages.
- * Default to 64MB.
+ * The number of IO TLB blocks (in groups of 64) betweeen io_tlb_start and
+ * io_tlb_end.  This is command line adjustable via setup_io_tlb_npages.
  */
-static unsigned long io_tlb_nslabs = 32768;
+static unsigned long io_tlb_nslabs;
 
-/* 
+/*
  * When the IOMMU overflows we return a fallback buffer. This sets the size.
  */
 static unsigned long io_tlb_overflow = 32*1024;
 
-void *io_tlb_overflow_buffer; 
+void *io_tlb_overflow_buffer;
 
 /*
- * This is a free list describing the number of free entries available from each index
+ * This is a free list describing the number of free entries available from
+ * each index
  */
 static unsigned int *io_tlb_list;
 static unsigned int io_tlb_index;
 
 /*
- * We need to save away the original address corresponding to a mapped entry for the sync
- * operations.
+ * We need to save away the original address corresponding to a mapped entry
+ * for the sync operations.
  */
 static unsigned char **io_tlb_orig_addr;
 
 /*
  * Protect the above data structures in the map and unmap calls
  */
-static spinlock_t io_tlb_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(io_tlb_lock);
 
 static int __init
-setup_io_tlb_npages (char *str)
+setup_io_tlb_npages(char *str)
 {
-	if (isdigit(*str)) { 
-		io_tlb_nslabs = simple_strtoul(str, &str, 0) << (PAGE_SHIFT - IO_TLB_SHIFT);
+	if (isdigit(*str)) {
+		io_tlb_nslabs = simple_strtoul(str, &str, 0) <<
+			(PAGE_SHIFT - IO_TLB_SHIFT);
 		/* avoid tail segment of size < IO_TLB_SEGSIZE */
 		io_tlb_nslabs = ALIGN(io_tlb_nslabs, IO_TLB_SEGSIZE);
 	}
@@ -105,18 +108,24 @@
 /* make io_tlb_overflow tunable too? */
 
 /*
- * Statically reserve bounce buffer space and initialize bounce buffer data structures for
- * the software IO TLB used to implement the PCI DMA API.
+ * Statically reserve bounce buffer space and initialize bounce buffer data
+ * structures for the software IO TLB used to implement the PCI DMA API.
  */
 void
-swiotlb_init (void)
+swiotlb_init_with_default_size (size_t default_size)
 {
 	unsigned long i;
 
+	if (!io_tlb_nslabs) {
+		io_tlb_nslabs = (default_size >> PAGE_SHIFT);
+		io_tlb_nslabs = ALIGN(io_tlb_nslabs, IO_TLB_SEGSIZE);
+	}
+
 	/*
 	 * Get IO TLB memory from the low pages
 	 */
-	io_tlb_start = alloc_bootmem_low_pages(io_tlb_nslabs * (1 << IO_TLB_SHIFT));
+	io_tlb_start = alloc_bootmem_low_pages(io_tlb_nslabs *
+					       (1 << IO_TLB_SHIFT));
 	if (!io_tlb_start)
 		panic("Cannot allocate SWIOTLB buffer");
 	io_tlb_end = io_tlb_start + io_tlb_nslabs * (1 << IO_TLB_SHIFT);
@@ -131,28 +140,36 @@
  		io_tlb_list[i] = IO_TLB_SEGSIZE - OFFSET(i, IO_TLB_SEGSIZE);
 	io_tlb_index = 0;
 	io_tlb_orig_addr = alloc_bootmem(io_tlb_nslabs * sizeof(char *));
-	
-	/* 
-	 * Get the overflow emergency buffer 
+
+	/*
+	 * Get the overflow emergency buffer
 	 */
-	io_tlb_overflow_buffer = alloc_bootmem_low(io_tlb_overflow); 
+	io_tlb_overflow_buffer = alloc_bootmem_low(io_tlb_overflow);
 	printk(KERN_INFO "Placing software IO TLB between 0x%lx - 0x%lx\n",
 	       virt_to_phys(io_tlb_start), virt_to_phys(io_tlb_end));
 }
 
-static inline int address_needs_mapping(struct device *hwdev, dma_addr_t addr)
-{ 
-	dma_addr_t mask = 0xffffffff; 
-	if (hwdev && hwdev->dma_mask) 
-		mask = *hwdev->dma_mask; 
-	return (addr & ~mask) != 0; 		
-} 
+void
+swiotlb_init (void)
+{
+	swiotlb_init_with_default_size(64 * (1<<20));	/* default to 64MB */
+}
+
+static inline int
+address_needs_mapping(struct device *hwdev, dma_addr_t addr)
+{
+	dma_addr_t mask = 0xffffffff;
+	/* If the device has a mask, use it, otherwise default to 32 bits */
+	if (hwdev && hwdev->dma_mask)
+		mask = *hwdev->dma_mask;
+	return (addr & ~mask) != 0;
+}
 
 /*
  * Allocates bounce buffer and returns its kernel virtual address.
  */
 static void *
-map_single (struct device *hwdev, char *buffer, size_t size, int dir)
+map_single(struct device *hwdev, char *buffer, size_t size, int dir)
 {
 	unsigned long flags;
 	char *dma_addr;
@@ -160,11 +177,11 @@
 	int i;
 
 	/*
-	 * For mappings greater than a page size, we limit the stride (and hence alignment)
-	 * to a page size.
+	 * For mappings greater than a page, we limit the stride (and
+	 * hence alignment) to a page size.
 	 */
 	nslots = ALIGN(size, 1 << IO_TLB_SHIFT) >> IO_TLB_SHIFT;
-	if (size > (1 << PAGE_SHIFT))
+	if (size > PAGE_SIZE)
 		stride = (1 << (PAGE_SHIFT - IO_TLB_SHIFT));
 	else
 		stride = 1;
@@ -173,8 +190,8 @@
 		BUG();
 
 	/*
-	 * Find suitable number of IO TLB entries size that will fit this request and
-	 * allocate a buffer from that IO TLB pool.
+	 * Find suitable number of IO TLB entries size that will fit this
+	 * request and allocate a buffer from that IO TLB pool.
 	 */
 	spin_lock_irqsave(&io_tlb_lock, flags);
 	{
@@ -185,22 +202,23 @@
 
 		do {
 			/*
-			 * If we find a slot that indicates we have 'nslots' number of
-			 * contiguous buffers, we allocate the buffers from that slot and
-			 * mark the entries as '0' indicating unavailable.
+			 * If we find a slot that indicates we have 'nslots'
+			 * number of contiguous buffers, we allocate the
+			 * buffers from that slot and mark the entries as '0'
+			 * indicating unavailable.
 			 */
 			if (io_tlb_list[index] >= nslots) {
 				int count = 0;
 
 				for (i = index; i < (int) (index + nslots); i++)
 					io_tlb_list[i] = 0;
-				for (i = index - 1; (OFFSET(i, IO_TLB_SEGSIZE) != IO_TLB_SEGSIZE -1)
-				       && io_tlb_list[i]; i--)
+				for (i = index - 1; (OFFSET(i, IO_TLB_SEGSIZE) != IO_TLB_SEGSIZE -1) && io_tlb_list[i]; i--)
 					io_tlb_list[i] = ++count;
 				dma_addr = io_tlb_start + (index << IO_TLB_SHIFT);
 
 				/*
-				 * Update the indices to avoid searching in the next round.
+				 * Update the indices to avoid searching in
+				 * the next round.
 				 */
 				io_tlb_index = ((index + nslots) < io_tlb_nslabs
 						? (index + nslots) : 0);
@@ -219,8 +237,9 @@
 	spin_unlock_irqrestore(&io_tlb_lock, flags);
 
 	/*
-	 * Save away the mapping from the original address to the DMA address.  This is
-	 * needed when we sync the memory.  Then we sync the buffer if needed.
+	 * Save away the mapping from the original address to the DMA address.
+	 * This is needed when we sync the memory.  Then we sync the buffer if
+	 * needed.
 	 */
 	io_tlb_orig_addr[index] = buffer;
 	if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL)
@@ -233,52 +252,51 @@
  * dma_addr is the kernel virtual address of the bounce buffer to unmap.
  */
 static void
-unmap_single (struct device *hwdev, char *dma_addr, size_t size, int dir)
+unmap_single(struct device *hwdev, char *dma_addr, size_t size, int dir)
 {
 	unsigned long flags;
-	int i, nslots = ALIGN(size, 1 << IO_TLB_SHIFT) >> IO_TLB_SHIFT;
+	int i, count, nslots = ALIGN(size, 1 << IO_TLB_SHIFT) >> IO_TLB_SHIFT;
 	int index = (dma_addr - io_tlb_start) >> IO_TLB_SHIFT;
 	char *buffer = io_tlb_orig_addr[index];
 
 	/*
 	 * First, sync the memory before unmapping the entry
 	 */
-	if ((dir == DMA_FROM_DEVICE) || (dir == DMA_BIDIRECTIONAL))
+	if (buffer && ((dir == DMA_FROM_DEVICE) || (dir == DMA_BIDIRECTIONAL)))
 		/*
-		 * bounce... copy the data back into the original buffer * and delete the
-		 * bounce buffer.
+		 * bounce... copy the data back into the original buffer * and
+		 * delete the bounce buffer.
 		 */
 		memcpy(buffer, dma_addr, size);
 
 	/*
-	 * Return the buffer to the free list by setting the corresponding entries to
-	 * indicate the number of contigous entries available.  While returning the
-	 * entries to the free list, we merge the entries with slots below and above the
-	 * pool being returned.
+	 * Return the buffer to the free list by setting the corresponding
+	 * entries to indicate the number of contigous entries available.
+	 * While returning the entries to the free list, we merge the entries
+	 * with slots below and above the pool being returned.
 	 */
 	spin_lock_irqsave(&io_tlb_lock, flags);
 	{
-		int count = ((index + nslots) < ALIGN(index + 1, IO_TLB_SEGSIZE) ?
-			     io_tlb_list[index + nslots] : 0);
+		count = ((index + nslots) < ALIGN(index + 1, IO_TLB_SEGSIZE) ?
+			 io_tlb_list[index + nslots] : 0);
 		/*
-		 * Step 1: return the slots to the free list, merging the slots with
-		 * superceeding slots
+		 * Step 1: return the slots to the free list, merging the
+		 * slots with superceeding slots
 		 */
 		for (i = index + nslots - 1; i >= index; i--)
 			io_tlb_list[i] = ++count;
 		/*
-		 * Step 2: merge the returned slots with the preceding slots, if
-		 * available (non zero)
+		 * Step 2: merge the returned slots with the preceding slots,
+		 * if available (non zero)
 		 */
-		for (i = index - 1;  (OFFSET(i, IO_TLB_SEGSIZE) != IO_TLB_SEGSIZE -1) &&
-		       io_tlb_list[i]; i--)
+		for (i = index - 1; (OFFSET(i, IO_TLB_SEGSIZE) != IO_TLB_SEGSIZE -1) && io_tlb_list[i]; i--)
 			io_tlb_list[i] = ++count;
 	}
 	spin_unlock_irqrestore(&io_tlb_lock, flags);
 }
 
 static void
-sync_single (struct device *hwdev, char *dma_addr, size_t size, int dir)
+sync_single(struct device *hwdev, char *dma_addr, size_t size, int dir)
 {
 	int index = (dma_addr - io_tlb_start) >> IO_TLB_SHIFT;
 	char *buffer = io_tlb_orig_addr[index];
@@ -296,17 +314,36 @@
 }
 
 void *
-swiotlb_alloc_coherent (struct device *hwdev, size_t size, dma_addr_t *dma_handle, int flags)
+swiotlb_alloc_coherent(struct device *hwdev, size_t size,
+		       dma_addr_t *dma_handle, int flags)
 {
 	unsigned long dev_addr;
 	void *ret;
+	int order = get_order(size);
 
-	/* XXX fix me: the DMA API should pass us an explicit DMA mask instead: */
+	/*
+	 * XXX fix me: the DMA API should pass us an explicit DMA mask
+	 * instead, or use ZONE_DMA32 (ia64 overloads ZONE_DMA to be a ~32
+	 * bit range instead of a 16MB one).
+	 */
 	flags |= GFP_DMA;
 
-	ret = (void *)__get_free_pages(flags, get_order(size));
+	ret = (void *)__get_free_pages(flags, order);
+	if (ret && address_needs_mapping(hwdev, virt_to_phys(ret))) {
+		/*
+		 * The allocated memory isn't reachable by the device.
+		 * Fall back on swiotlb_map_single().
+		 */
+		free_pages((unsigned long) ret, order);
+		ret = NULL;
+	}
 	if (!ret) {
-		 /* DMA_FROM_DEVICE is to avoid the memcpy in map_single */
+		/*
+		 * We are either out of memory or the device can't DMA
+		 * to GFP_DMA memory; fall back on
+		 * swiotlb_map_single(), which will grab memory from
+		 * the lowest available address range.
+		 */
 		dma_addr_t handle;
 		handle = swiotlb_map_single(NULL, NULL, size, DMA_FROM_DEVICE);
 		if (dma_mapping_error(handle))
@@ -317,14 +354,21 @@
 
 	memset(ret, 0, size);
 	dev_addr = virt_to_phys(ret);
-	if (address_needs_mapping(hwdev,dev_addr))
-		panic("swiotlb_alloc_consistent: allocated memory is out of range for device");
+
+	/* Confirm address can be DMA'd by device */
+	if (address_needs_mapping(hwdev, dev_addr)) {
+		printk("hwdev DMA mask = 0x%016Lx, dev_addr = 0x%016lx\n",
+		       (unsigned long long)*hwdev->dma_mask, dev_addr);
+		panic("swiotlb_alloc_coherent: allocated memory is out of "
+		      "range for device");
+	}
 	*dma_handle = dev_addr;
 	return ret;
 }
 
 void
-swiotlb_free_coherent (struct device *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle)
+swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr,
+		      dma_addr_t dma_handle)
 {
 	if (!(vaddr >= (void *)io_tlb_start
                     && vaddr < (void *)io_tlb_end))
@@ -334,66 +378,63 @@
 		swiotlb_unmap_single (hwdev, dma_handle, size, DMA_TO_DEVICE);
 }
 
-static void swiotlb_full(struct device *dev, size_t size, int dir, int do_panic)
+static void
+swiotlb_full(struct device *dev, size_t size, int dir, int do_panic)
 {
-	/* 
+	/*
 	 * Ran out of IOMMU space for this operation. This is very bad.
 	 * Unfortunately the drivers cannot handle this operation properly.
 	 * unless they check for pci_dma_mapping_error (most don't)
 	 * When the mapping is small enough return a static buffer to limit
-	 * the damage, or panic when the transfer is too big. 
-	 */ 
-	
-	printk(KERN_ERR 
-  "PCI-DMA: Out of SW-IOMMU space for %lu bytes at device %s\n",
-	       size, dev ? dev->bus_id : "?");
+	 * the damage, or panic when the transfer is too big.
+	 */
+	printk(KERN_ERR "PCI-DMA: Out of SW-IOMMU space for %lu bytes at "
+	       "device %s\n", size, dev ? dev->bus_id : "?");
 
 	if (size > io_tlb_overflow && do_panic) {
 		if (dir == PCI_DMA_FROMDEVICE || dir == PCI_DMA_BIDIRECTIONAL)
 			panic("PCI-DMA: Memory would be corrupted\n");
-		if (dir == PCI_DMA_TODEVICE || dir == PCI_DMA_BIDIRECTIONAL) 
-			panic("PCI-DMA: Random memory would be DMAed\n"); 
-	} 
-} 
+		if (dir == PCI_DMA_TODEVICE || dir == PCI_DMA_BIDIRECTIONAL)
+			panic("PCI-DMA: Random memory would be DMAed\n");
+	}
+}
 
 /*
- * Map a single buffer of the indicated size for DMA in streaming mode.  The PCI address
- * to use is returned.
+ * Map a single buffer of the indicated size for DMA in streaming mode.  The
+ * PCI address to use is returned.
  *
- * Once the device is given the dma address, the device owns this memory until either
- * swiotlb_unmap_single or swiotlb_dma_sync_single is performed.
+ * Once the device is given the dma address, the device owns this memory until
+ * either swiotlb_unmap_single or swiotlb_dma_sync_single is performed.
  */
 dma_addr_t
-swiotlb_map_single (struct device *hwdev, void *ptr, size_t size, int dir)
+swiotlb_map_single(struct device *hwdev, void *ptr, size_t size, int dir)
 {
 	unsigned long dev_addr = virt_to_phys(ptr);
-	void *map; 
+	void *map;
 
 	if (dir == DMA_NONE)
 		BUG();
 	/*
-	 * Check if the PCI device can DMA to ptr... if so, just return ptr
+	 * If the pointer passed in happens to be in the device's DMA window,
+	 * we can safely return the device addr and not worry about bounce
+	 * buffering it.
 	 */
-	if (!address_needs_mapping(hwdev, dev_addr) && !swiotlb_force) 
-		/*
-		 * Device is bit capable of DMA'ing to the buffer... just return the PCI
-		 * address of ptr
-		 */
+	if (!address_needs_mapping(hwdev, dev_addr) && !swiotlb_force)
 		return dev_addr;
 
 	/*
-	 * get a bounce buffer:
+	 * Oh well, have to allocate and map a bounce buffer.
 	 */
 	map = map_single(hwdev, ptr, size, dir);
-	if (!map) { 
-		swiotlb_full(hwdev, size, dir, 1);		
-		map = io_tlb_overflow_buffer; 
+	if (!map) {
+		swiotlb_full(hwdev, size, dir, 1);
+		map = io_tlb_overflow_buffer;
 	}
 
 	dev_addr = virt_to_phys(map);
 
 	/*
-	 * Ensure that the address returned is DMA'ble:
+	 * Ensure that the address returned is DMA'ble
 	 */
 	if (address_needs_mapping(hwdev, dev_addr))
 		panic("map_single: bounce buffer is not DMA'ble");
@@ -407,7 +448,7 @@
  * flush them when they get mapped into an executable vm-area.
  */
 static void
-mark_clean (void *addr, size_t size)
+mark_clean(void *addr, size_t size)
 {
 	unsigned long pg_addr, end;
 
@@ -421,15 +462,16 @@
 }
 
 /*
- * Unmap a single streaming mode DMA translation.  The dma_addr and size must match what
- * was provided for in a previous swiotlb_map_single call.  All other usages are
- * undefined.
+ * Unmap a single streaming mode DMA translation.  The dma_addr and size must
+ * match what was provided for in a previous swiotlb_map_single call.  All
+ * other usages are undefined.
  *
- * After this call, reads by the cpu to the buffer are guaranteed to see whatever the
- * device wrote there.
+ * After this call, reads by the cpu to the buffer are guaranteed to see
+ * whatever the device wrote there.
  */
 void
-swiotlb_unmap_single (struct device *hwdev, dma_addr_t dev_addr, size_t size, int dir)
+swiotlb_unmap_single(struct device *hwdev, dma_addr_t dev_addr, size_t size,
+		     int dir)
 {
 	char *dma_addr = phys_to_virt(dev_addr);
 
@@ -442,16 +484,18 @@
 }
 
 /*
- * Make physical memory consistent for a single streaming mode DMA translation after a
- * transfer.
+ * Make physical memory consistent for a single streaming mode DMA translation
+ * after a transfer.
  *
- * If you perform a swiotlb_map_single() but wish to interrogate the buffer using the cpu,
- * yet do not wish to teardown the PCI dma mapping, you must call this function before
- * doing so.  At the next point you give the PCI dma address back to the card, you must
- * first perform a swiotlb_dma_sync_for_device, and then the device again owns the buffer
+ * If you perform a swiotlb_map_single() but wish to interrogate the buffer
+ * using the cpu, yet do not wish to teardown the PCI dma mapping, you must
+ * call this function before doing so.  At the next point you give the PCI dma
+ * address back to the card, you must first perform a
+ * swiotlb_dma_sync_for_device, and then the device again owns the buffer
  */
 void
-swiotlb_sync_single_for_cpu (struct device *hwdev, dma_addr_t dev_addr, size_t size, int dir)
+swiotlb_sync_single_for_cpu(struct device *hwdev, dma_addr_t dev_addr,
+			    size_t size, int dir)
 {
 	char *dma_addr = phys_to_virt(dev_addr);
 
@@ -464,7 +508,8 @@
 }
 
 void
-swiotlb_sync_single_for_device (struct device *hwdev, dma_addr_t dev_addr, size_t size, int dir)
+swiotlb_sync_single_for_device(struct device *hwdev, dma_addr_t dev_addr,
+			       size_t size, int dir)
 {
 	char *dma_addr = phys_to_virt(dev_addr);
 
@@ -477,10 +522,11 @@
 }
 
 /*
- * Map a set of buffers described by scatterlist in streaming mode for DMA.  This is the
- * scatter-gather version of the above swiotlb_map_single interface.  Here the scatter
- * gather list elements are each tagged with the appropriate dma address and length.  They
- * are obtained via sg_dma_{address,length}(SG).
+ * Map a set of buffers described by scatterlist in streaming mode for DMA.
+ * This is the scatter-gather version of the above swiotlb_map_single
+ * interface.  Here the scatter gather list elements are each tagged with the
+ * appropriate dma address and length.  They are obtained via
+ * sg_dma_{address,length}(SG).
  *
  * NOTE: An implementation may be able to use a smaller number of
  *       DMA address/length pairs than there are SG table elements.
@@ -488,10 +534,12 @@
  *       The routine returns the number of addr/length pairs actually
  *       used, at most nents.
  *
- * Device ownership issues as mentioned above for swiotlb_map_single are the same here.
+ * Device ownership issues as mentioned above for swiotlb_map_single are the
+ * same here.
  */
 int
-swiotlb_map_sg (struct device *hwdev, struct scatterlist *sg, int nelems, int dir)
+swiotlb_map_sg(struct device *hwdev, struct scatterlist *sg, int nelems,
+	       int dir)
 {
 	void *addr;
 	unsigned long dev_addr;
@@ -506,9 +554,9 @@
 		if (swiotlb_force || address_needs_mapping(hwdev, dev_addr)) {
 			sg->dma_address = (dma_addr_t) virt_to_phys(map_single(hwdev, addr, sg->length, dir));
 			if (!sg->dma_address) {
-				/* Don't panic here, we expect pci_map_sg users
+				/* Don't panic here, we expect map_sg users
 				   to do proper error handling. */
-				swiotlb_full(hwdev, sg->length, dir, 0); 
+				swiotlb_full(hwdev, sg->length, dir, 0);
 				swiotlb_unmap_sg(hwdev, sg - i, i, dir);
 				sg[0].dma_length = 0;
 				return 0;
@@ -521,11 +569,12 @@
 }
 
 /*
- * Unmap a set of streaming mode DMA translations.  Again, cpu read rules concerning calls
- * here are the same as for swiotlb_unmap_single() above.
+ * Unmap a set of streaming mode DMA translations.  Again, cpu read rules
+ * concerning calls here are the same as for swiotlb_unmap_single() above.
  */
 void
-swiotlb_unmap_sg (struct device *hwdev, struct scatterlist *sg, int nelems, int dir)
+swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nelems,
+		 int dir)
 {
 	int i;
 
@@ -540,14 +589,15 @@
 }
 
 /*
- * Make physical memory consistent for a set of streaming mode DMA translations after a
- * transfer.
+ * Make physical memory consistent for a set of streaming mode DMA translations
+ * after a transfer.
  *
- * The same as swiotlb_sync_single_* but for a scatter-gather list, same rules and
- * usage.
+ * The same as swiotlb_sync_single_* but for a scatter-gather list, same rules
+ * and usage.
  */
 void
-swiotlb_sync_sg_for_cpu (struct device *hwdev, struct scatterlist *sg, int nelems, int dir)
+swiotlb_sync_sg_for_cpu(struct device *hwdev, struct scatterlist *sg,
+			int nelems, int dir)
 {
 	int i;
 
@@ -556,11 +606,13 @@
 
 	for (i = 0; i < nelems; i++, sg++)
 		if (sg->dma_address != SG_ENT_PHYS_ADDRESS(sg))
-			sync_single(hwdev, (void *) sg->dma_address, sg->dma_length, dir);
+			sync_single(hwdev, (void *) sg->dma_address,
+				    sg->dma_length, dir);
 }
 
 void
-swiotlb_sync_sg_for_device (struct device *hwdev, struct scatterlist *sg, int nelems, int dir)
+swiotlb_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg,
+			   int nelems, int dir)
 {
 	int i;
 
@@ -569,24 +621,26 @@
 
 	for (i = 0; i < nelems; i++, sg++)
 		if (sg->dma_address != SG_ENT_PHYS_ADDRESS(sg))
-			sync_single(hwdev, (void *) sg->dma_address, sg->dma_length, dir);
+			sync_single(hwdev, (void *) sg->dma_address,
+				    sg->dma_length, dir);
 }
 
 int
-swiotlb_dma_mapping_error (dma_addr_t dma_addr)
+swiotlb_dma_mapping_error(dma_addr_t dma_addr)
 {
 	return (dma_addr == virt_to_phys(io_tlb_overflow_buffer));
 }
 
 /*
- * Return whether the given PCI device DMA address mask can be supported properly.  For
- * example, if your device can only drive the low 24-bits during PCI bus mastering, then
- * you would pass 0x00ffffff as the mask to this function.
+ * Return whether the given PCI device DMA address mask can be supported
+ * properly.  For example, if your device can only drive the low 24-bits
+ * during PCI bus mastering, then you would pass 0x00ffffff as the mask to
+ * this function.
  */
 int
 swiotlb_dma_supported (struct device *hwdev, u64 mask)
 {
-	return 1;
+	return (virt_to_phys (io_tlb_end) - 1) <= mask;
 }
 
 EXPORT_SYMBOL(swiotlb_init);
diff -Nru a/arch/ia64/mm/contig.c b/arch/ia64/mm/contig.c
--- a/arch/ia64/mm/contig.c	2005-03-01 23:38:55 -08:00
+++ b/arch/ia64/mm/contig.c	2005-03-01 23:38:55 -08:00
@@ -24,6 +24,7 @@
 #include <asm/pgalloc.h>
 #include <asm/pgtable.h>
 #include <asm/sections.h>
+#include <asm/mca.h>
 
 #ifdef CONFIG_VIRTUAL_MEM_MAP
 static unsigned long num_dma_physpages;
@@ -214,8 +215,8 @@
 {
 	unsigned long *count = arg;
 
-	if (end <= MAX_DMA_ADDRESS)
-		*count += (end - start) >> PAGE_SHIFT;
+	if (start < MAX_DMA_ADDRESS)
+		*count += (min(end, MAX_DMA_ADDRESS) - start) >> PAGE_SHIFT;
 	return 0;
 }
 #endif
diff -Nru a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c
--- a/arch/ia64/mm/discontig.c	2005-03-01 23:39:09 -08:00
+++ b/arch/ia64/mm/discontig.c	2005-03-01 23:39:09 -08:00
@@ -4,6 +4,10 @@
  * Copyright (c) 2001 Tony Luck <tony.luck@intel.com>
  * Copyright (c) 2002 NEC Corp.
  * Copyright (c) 2002 Kimio Suganuma <k-suganuma@da.jp.nec.com>
+ * Copyright (c) 2004 Silicon Graphics, Inc
+ *	Russ Anderson <rja@sgi.com>
+ *	Jesse Barnes <jbarnes@sgi.com>
+ *	Jack Steiner <steiner@sgi.com>
  */
 
 /*
@@ -39,7 +43,7 @@
 	unsigned long max_pfn;
 };
 
-static struct early_node_data mem_data[NR_NODES] __initdata;
+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
@@ -56,9 +60,9 @@
 	struct node_memblk_s *p;
 	int i, j, k, nnode, nid, cpu, cpunid, pxm;
 	u8 cslit, slit;
-	static DECLARE_BITMAP(nodes_with_mem, NR_NODES) __initdata;
+	static DECLARE_BITMAP(nodes_with_mem, MAX_NUMNODES) __initdata;
 	static u8 numa_slit_fix[MAX_NUMNODES * MAX_NUMNODES] __initdata;
-	static int node_flip[NR_NODES] __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++)
@@ -70,7 +74,7 @@
 	/*
 	 * All nids with memory.
 	 */
-	if (nnode == numnodes)
+	if (nnode == num_online_nodes())
 		return;
 
 	/*
@@ -79,10 +83,17 @@
 	 * 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 numnodes and
+	 * new nid values are fabricated above num_online_nodes() and
 	 * mapped back later to their true value.
 	 */
-	for (nid = 0, i = 0; i < numnodes; i++)  {
+	/* 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
@@ -102,7 +113,7 @@
 			cpunid = nid;
 			nid++;
 		} else
-			cpunid = numnodes;
+			cpunid = MAX_NUMNODES;
 
 		for (cpu = 0; cpu < NR_CPUS; cpu++)
 			if (node_cpuid[cpu].nid == i) {
@@ -110,7 +121,7 @@
 				 * For nodes not being reassigned just
 				 * fix the cpu's nid and reverse pxm map
 				 */
-				if (cpunid < numnodes) {
+				if (cpunid < MAX_NUMNODES) {
 					pxm = nid_to_pxm_map[i];
 					pxm_to_nid_map[pxm] =
 					          node_cpuid[cpu].nid = cpunid;
@@ -120,18 +131,21 @@
 				/*
 				 * For nodes being reassigned, find best node by
 				 * numa_slit information and then make a temporary
-				 * nid value based on current nid and numnodes.
+				 * nid value based on current nid and num_online_nodes().
 				 */
-				for (slit = 0xff, k = numnodes + numnodes, j = 0; j < numnodes; j++)
+				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 * numnodes + j];
+						cslit = numa_slit[i * num_online_nodes() + j];
 						if (cslit < slit) {
-							k = numnodes + j;
+							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;
@@ -143,12 +157,12 @@
 	 * Fixup temporary nid values for CPU-only nodes.
 	 */
 	for (cpu = 0; cpu < NR_CPUS; cpu++)
-		if (node_cpuid[cpu].nid == (numnodes + numnodes)) {
+		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 - numnodes))
+				if (node_flip[i] != (node_cpuid[cpu].nid - num_online_nodes()))
 					continue;
 
 				pxm = nid_to_pxm_map[old_nid_map[cpu]];
@@ -164,14 +178,13 @@
 	for (i = 0; i < nnode; i++)
 		for (j = 0; j < nnode; j++)
 			numa_slit_fix[i * nnode + j] =
-				numa_slit[node_flip[i] * numnodes + node_flip[j]];
+				numa_slit[node_flip[i] * num_online_nodes() + node_flip[j]];
 
 	memcpy(numa_slit, numa_slit_fix, sizeof (numa_slit));
 
-	for (i = nnode; i < numnodes; i++)
-		node_set_offline(i);
-
-	numnodes = nnode;
+	nodes_clear(node_online_map);
+	for (i = 0; i < nnode; i++)
+		node_set_online(i);
 
 	return;
 }
@@ -220,12 +233,34 @@
 }
 
 /**
+ * early_nr_phys_cpus_node - return number of physical 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
+ * acpi_boot_init() (which builds the node_to_cpu_mask array) hasn't been
+ * called yet.
+ */
+static int early_nr_phys_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++;
+
+	return n;
+}
+
+
+/**
  * early_nr_cpus_node - return number of cpus on a given node
  * @node: node to check
  *
  * 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_cpus_node(int node)
 {
@@ -252,7 +287,7 @@
  *   |                        |
  *   |~~~~~~~~~~~~~~~~~~~~~~~~| <-- NODEDATA_ALIGN(start, node) for the first
  *   |    PERCPU_PAGE_SIZE *  |     start and length big enough
- *   |        NR_CPUS         |
+ *   |    cpus_on_this_node   | Node 0 will also have entries for all non-existent cpus.
  *   |------------------------|
  *   |   local pg_data_t *    |
  *   |------------------------|
@@ -269,7 +304,7 @@
 static int __init find_pernode_space(unsigned long start, unsigned long len,
 				     int node)
 {
-	unsigned long epfn, cpu, cpus;
+	unsigned long epfn, cpu, cpus, phys_cpus;
 	unsigned long pernodesize = 0, pernode, pages, mapsize;
 	void *cpu_data;
 	struct bootmem_data *bdp = &mem_data[node].bootmem_data;
@@ -295,7 +330,9 @@
 	 * 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);
@@ -309,6 +346,7 @@
 
 		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));
@@ -370,7 +408,7 @@
 	struct bootmem_data *bdp;
 	int node;
 
-	for (node = 0; node < numnodes; node++) {
+	for_each_online_node(node) {
 		pg_data_t *pdp = mem_data[node].pgdat;
 
 		bdp = pdp->bdata;
@@ -399,13 +437,13 @@
 static void __init initialize_pernode_data(void)
 {
 	int cpu, node;
-	pg_data_t *pgdat_list[NR_NODES];
+	pg_data_t *pgdat_list[MAX_NUMNODES];
 
-	for (node = 0; node < numnodes; node++)
+	for_each_online_node(node)
 		pgdat_list[node] = mem_data[node].pgdat;
 
 	/* Copy the pg_data_t list to each node and init the node field */
-	for (node = 0; node < numnodes; node++) {
+	for_each_online_node(node) {
 		memcpy(mem_data[node].node_data->pg_data_ptrs, pgdat_list,
 		       sizeof(pgdat_list));
 	}
@@ -429,15 +467,15 @@
 
 	reserve_memory();
 
-	if (numnodes == 0) {
+	if (num_online_nodes() == 0) {
 		printk(KERN_ERR "node info missing!\n");
-		numnodes = 1;
+		node_set_online(0);
 	}
 
 	min_low_pfn = -1;
 	max_low_pfn = 0;
 
-	if (numnodes > 1)
+	if (num_online_nodes() > 1)
 		reassign_cpu_only_nodes();
 
 	/* These actually end up getting called by call_pernode_memory() */
@@ -448,10 +486,13 @@
 	 * Initialize the boot memory maps in reverse order since that's
 	 * what the bootmem allocator expects
 	 */
-	for (node = numnodes - 1; node >= 0; node--) {
+	for (node = MAX_NUMNODES - 1; node >= 0; node--) {
 		unsigned long pernode, pernodesize, map;
 		struct bootmem_data *bdp;
 
+		if (!node_online(node))
+			continue;
+
 		bdp = &mem_data[node].bootmem_data;
 		pernode = mem_data[node].pernode_addr;
 		pernodesize = mem_data[node].pernode_size;
@@ -638,12 +679,12 @@
 	max_dma = virt_to_phys((void *) MAX_DMA_ADDRESS) >> PAGE_SHIFT;
 
 	/* so min() will work in count_node_pages */
-	for (node = 0; node < numnodes; node++)
+	for_each_online_node(node)
 		mem_data[node].min_pfn = ~0UL;
 
 	efi_memmap_walk(filter_rsvd_memory, count_node_pages);
 
-	for (node = 0; node < numnodes; node++) {
+	for_each_online_node(node) {
 		memset(zones_size, 0, sizeof(zones_size));
 		memset(zholes_size, 0, sizeof(zholes_size));
 
diff -Nru a/arch/ia64/mm/fault.c b/arch/ia64/mm/fault.c
--- a/arch/ia64/mm/fault.c	2005-03-01 23:39:17 -08:00
+++ b/arch/ia64/mm/fault.c	2005-03-01 23:39:17 -08:00
@@ -51,6 +51,7 @@
 mapped_kernel_page_is_present (unsigned long address)
 {
 	pgd_t *pgd;
+	pud_t *pud;
 	pmd_t *pmd;
 	pte_t *ptep, pte;
 
@@ -58,7 +59,11 @@
 	if (pgd_none(*pgd) || pgd_bad(*pgd))
 		return 0;
 
-	pmd = pmd_offset(pgd, address);
+	pud = pud_offset(pgd, address);
+	if (pud_none(*pud) || pud_bad(*pud))
+		return 0;
+
+	pmd = pmd_offset(pud, address);
 	if (pmd_none(*pmd) || pmd_bad(*pmd))
 		return 0;
 
diff -Nru a/arch/ia64/mm/hugetlbpage.c b/arch/ia64/mm/hugetlbpage.c
--- a/arch/ia64/mm/hugetlbpage.c	2005-03-01 23:38:57 -08:00
+++ b/arch/ia64/mm/hugetlbpage.c	2005-03-01 23:38:57 -08:00
@@ -29,13 +29,17 @@
 {
 	unsigned long taddr = htlbpage_to_page(addr);
 	pgd_t *pgd;
+	pud_t *pud;
 	pmd_t *pmd;
 	pte_t *pte = NULL;
 
 	pgd = pgd_offset(mm, taddr);
-	pmd = pmd_alloc(mm, pgd, taddr);
-	if (pmd)
-		pte = pte_alloc_map(mm, pmd, taddr);
+	pud = pud_alloc(mm, pgd, taddr);
+	if (pud) {
+		pmd = pmd_alloc(mm, pud, taddr);
+		if (pmd)
+			pte = pte_alloc_map(mm, pmd, taddr);
+	}
 	return pte;
 }
 
@@ -44,14 +48,18 @@
 {
 	unsigned long taddr = htlbpage_to_page(addr);
 	pgd_t *pgd;
+	pud_t *pud;
 	pmd_t *pmd;
 	pte_t *pte = NULL;
 
 	pgd = pgd_offset(mm, taddr);
 	if (pgd_present(*pgd)) {
-		pmd = pmd_offset(pgd, taddr);
-		if (pmd_present(*pmd))
-			pte = pte_offset_map(pmd, taddr);
+		pud = pud_offset(pgd, taddr);
+		if (pud_present(*pud)) {
+			pmd = pmd_offset(pud, taddr);
+			if (pmd_present(*pmd))
+				pte = pte_offset_map(pmd, taddr);
+		}
 	}
 
 	return pte;
@@ -187,7 +195,6 @@
 {
 	unsigned long first = start & HUGETLB_PGDIR_MASK;
 	unsigned long last = end + HUGETLB_PGDIR_SIZE - 1;
-	unsigned long start_index, end_index;
 	struct mm_struct *mm = tlb->mm;
 
 	if (!prev) {
@@ -212,23 +219,13 @@
 				last = next->vm_start;
 		}
 		if (prev->vm_end > first)
-			first = prev->vm_end + HUGETLB_PGDIR_SIZE - 1;
+			first = prev->vm_end;
 		break;
 	}
 no_mmaps:
 	if (last < first)	/* for arches with discontiguous pgd indices */
 		return;
-	/*
-	 * If the PGD bits are not consecutive in the virtual address, the
-	 * old method of shifting the VA >> by PGDIR_SHIFT doesn't work.
-	 */
-
-	start_index = pgd_index(htlbpage_to_page(first));
-	end_index = pgd_index(htlbpage_to_page(last));
-
-	if (end_index > start_index) {
-		clear_page_tables(tlb, start_index, end_index - start_index);
-	}
+	clear_page_range(tlb, first, last);
 }
 
 void unmap_hugepage_range(struct vm_area_struct *vma, unsigned long start, unsigned long end)
diff -Nru a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c
--- a/arch/ia64/mm/init.c	2005-03-01 23:38:56 -08:00
+++ b/arch/ia64/mm/init.c	2005-03-01 23:38:56 -08:00
@@ -237,6 +237,7 @@
 put_kernel_page (struct page *page, unsigned long address, pgprot_t pgprot)
 {
 	pgd_t *pgd;
+	pud_t *pud;
 	pmd_t *pmd;
 	pte_t *pte;
 
@@ -248,7 +249,11 @@
 
 	spin_lock(&init_mm.page_table_lock);
 	{
-		pmd = pmd_alloc(&init_mm, pgd, address);
+		pud = pud_alloc(&init_mm, pgd, address);
+		if (!pud)
+			goto out;
+
+		pmd = pmd_alloc(&init_mm, pud, address);
 		if (!pmd)
 			goto out;
 		pte = pte_alloc_map(&init_mm, pmd, address);
@@ -291,7 +296,6 @@
 {
 	unsigned long psr, pta, impl_va_bits;
 	extern void __devinit tlb_init (void);
-	int cpu;
 
 #ifdef CONFIG_DISABLE_VHPT
 #	define VHPT_ENABLE_BIT	0
@@ -356,20 +360,6 @@
 	ia64_set_rr(HPAGE_REGION_BASE, HPAGE_SHIFT << 2);
 	ia64_srlz_d();
 #endif
-
-	cpu = smp_processor_id();
-
-	/* mca handler uses cr.lid as key to pick the right entry */
-	ia64_mca_tlb_list[cpu].cr_lid = ia64_getreg(_IA64_REG_CR_LID);
-
-	/* insert this percpu data information into our list for MCA recovery purposes */
-	ia64_mca_tlb_list[cpu].percpu_paddr = pte_val(mk_pte_phys(__pa(my_cpu_data), PAGE_KERNEL));
-	/* Also save per-cpu tlb flush recipe for use in physical mode mca handler */
-	ia64_mca_tlb_list[cpu].ptce_base = local_cpu_data->ptce_base;
-	ia64_mca_tlb_list[cpu].ptce_count[0] = local_cpu_data->ptce_count[0];
-	ia64_mca_tlb_list[cpu].ptce_count[1] = local_cpu_data->ptce_count[1];
-	ia64_mca_tlb_list[cpu].ptce_stride[0] = local_cpu_data->ptce_stride[0];
-	ia64_mca_tlb_list[cpu].ptce_stride[1] = local_cpu_data->ptce_stride[1];
 }
 
 #ifdef CONFIG_VIRTUAL_MEM_MAP
@@ -381,6 +371,7 @@
 	struct page *map_start, *map_end;
 	int node;
 	pgd_t *pgd;
+	pud_t *pud;
 	pmd_t *pmd;
 	pte_t *pte;
 
@@ -395,7 +386,11 @@
 		pgd = pgd_offset_k(address);
 		if (pgd_none(*pgd))
 			pgd_populate(&init_mm, pgd, alloc_bootmem_pages_node(NODE_DATA(node), PAGE_SIZE));
-		pmd = pmd_offset(pgd, address);
+		pud = pud_offset(pgd, address);
+
+		if (pud_none(*pud))
+			pud_populate(&init_mm, pud, alloc_bootmem_pages_node(NODE_DATA(node), PAGE_SIZE));
+		pmd = pmd_offset(pud, address);
 
 		if (pmd_none(*pmd))
 			pmd_populate_kernel(&init_mm, pmd, alloc_bootmem_pages_node(NODE_DATA(node), PAGE_SIZE));
@@ -422,7 +417,6 @@
 	struct page *map_start, *map_end;
 
 	args = (struct memmap_init_callback_data *) arg;
-
 	map_start = vmem_map + (__pa(start) >> PAGE_SHIFT);
 	map_end   = vmem_map + (__pa(end) >> PAGE_SHIFT);
 
diff -Nru a/arch/ia64/mm/numa.c b/arch/ia64/mm/numa.c
--- a/arch/ia64/mm/numa.c	2005-03-01 23:38:54 -08:00
+++ b/arch/ia64/mm/numa.c	2005-03-01 23:38:54 -08:00
@@ -20,8 +20,6 @@
 #include <asm/mmzone.h>
 #include <asm/numa.h>
 
-static struct node *sysfs_nodes;
-static struct cpu *sysfs_cpus;
 
 /*
  * The following structures are usually initialized by ACPI or
@@ -49,37 +47,3 @@
 
 	return (i < num_node_memblks) ? node_memblk[i].nid : (num_node_memblks ? -1 : 0);
 }
-
-static int __init topology_init(void)
-{
-	int i, err = 0;
-
-	sysfs_nodes = kmalloc(sizeof(struct node) * numnodes, GFP_KERNEL);
-	if (!sysfs_nodes) {
-		err = -ENOMEM;
-		goto out;
-	}
-	memset(sysfs_nodes, 0, sizeof(struct node) * numnodes);
-
-	sysfs_cpus = kmalloc(sizeof(struct cpu) * NR_CPUS, GFP_KERNEL);
-	if (!sysfs_cpus) {
-		kfree(sysfs_nodes);
-		err = -ENOMEM;
-		goto out;
-	}
-	memset(sysfs_cpus, 0, sizeof(struct cpu) * NR_CPUS);
-
-	for (i = 0; i < numnodes; i++)
-		if ((err = register_node(&sysfs_nodes[i], i, NULL)))
-			goto out;
-
-	for (i = 0; i < NR_CPUS; i++)
-		if (cpu_online(i))
-			if((err = register_cpu(&sysfs_cpus[i], i,
-					       &sysfs_nodes[cpu_to_node(i)])))
-				goto out;
- out:
-	return err;
-}
-
-__initcall(topology_init);
diff -Nru a/arch/ia64/mm/tlb.c b/arch/ia64/mm/tlb.c
--- a/arch/ia64/mm/tlb.c	2005-03-01 23:39:08 -08:00
+++ b/arch/ia64/mm/tlb.c	2005-03-01 23:39:08 -08:00
@@ -88,7 +88,7 @@
 void
 ia64_global_tlb_purge (unsigned long start, unsigned long end, unsigned long nbits)
 {
-	static spinlock_t ptcg_lock = SPIN_LOCK_UNLOCKED;
+	static DEFINE_SPINLOCK(ptcg_lock);
 
 	/* HW requires global serialization of ptc.ga.  */
 	spin_lock(&ptcg_lock);
diff -Nru a/arch/ia64/oprofile/Makefile b/arch/ia64/oprofile/Makefile
--- a/arch/ia64/oprofile/Makefile	2005-03-01 23:38:53 -08:00
+++ b/arch/ia64/oprofile/Makefile	2005-03-01 23:38:53 -08:00
@@ -6,5 +6,5 @@
 		oprofilefs.o oprofile_stats.o \
 		timer_int.o )
 
-oprofile-y := $(DRIVER_OBJS) init.o
+oprofile-y := $(DRIVER_OBJS) init.o backtrace.o
 oprofile-$(CONFIG_PERFMON) += perfmon.o
diff -Nru a/arch/ia64/oprofile/backtrace.c b/arch/ia64/oprofile/backtrace.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/ia64/oprofile/backtrace.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,150 @@
+/**
+ * @file backtrace.c
+ *
+ * @remark Copyright 2004 Silicon Graphics Inc.  All Rights Reserved.
+ * @remark Read the file COPYING
+ *
+ * @author Greg Banks <gnb@melbourne.sgi.com>
+ * @author Keith Owens <kaos@melbourne.sgi.com>
+ * Based on work done for the ia64 port of the SGI kernprof patch, which is
+ *    Copyright (c) 2003-2004 Silicon Graphics Inc.  All Rights Reserved.
+ */
+
+#include <linux/oprofile.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <asm/ptrace.h>
+#include <asm/system.h>
+
+/*
+ * For IA64 we need to perform a complex little dance to get both
+ * the struct pt_regs and a synthetic struct switch_stack in place
+ * to allow the unwind code to work.  This dance requires our unwind
+ * using code to be called from a function called from unw_init_running().
+ * There we only get a single void* data pointer, so use this struct
+ * to hold all the data we need during the unwind.
+ */
+typedef struct
+{
+	unsigned int depth;
+	struct pt_regs *regs;
+	struct unw_frame_info frame;
+	u64 *prev_pfs_loc;	/* state for WAR for old spinlock ool code */
+} ia64_backtrace_t;
+
+#if __GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ < 3)
+/*
+ * Returns non-zero if the PC is in the spinlock contention out-of-line code
+ * with non-standard calling sequence (on older compilers).
+ */
+static __inline__ int in_old_ool_spinlock_code(unsigned long pc)
+{
+	extern const char ia64_spinlock_contention_pre3_4[] __attribute__ ((weak));
+	extern const char ia64_spinlock_contention_pre3_4_end[] __attribute__ ((weak));
+	unsigned long sc_start = (unsigned long)ia64_spinlock_contention_pre3_4;
+	unsigned long sc_end = (unsigned long)ia64_spinlock_contention_pre3_4_end;
+	return (sc_start && sc_end && pc >= sc_start && pc < sc_end);
+}
+#else
+/* Newer spinlock code does a proper br.call and works fine with the unwinder */
+#define in_old_ool_spinlock_code(pc)	0
+#endif
+
+/* Returns non-zero if the PC is in the Interrupt Vector Table */
+static __inline__ int in_ivt_code(unsigned long pc)
+{
+	extern char ia64_ivt[];
+	return (pc >= (u_long)ia64_ivt && pc < (u_long)ia64_ivt+32768);
+}
+
+/*
+ * Unwind to next stack frame.
+ */
+static __inline__ int next_frame(ia64_backtrace_t *bt)
+{
+	/*
+	 * Avoid unsightly console message from unw_unwind() when attempting
+	 * to unwind through the Interrupt Vector Table which has no unwind
+	 * information.
+	 */
+	if (in_ivt_code(bt->frame.ip))
+		return 0;
+
+	/*
+	 * WAR for spinlock contention from leaf functions.  ia64_spinlock_contention_pre3_4
+	 * has ar.pfs == r0.  Leaf functions do not modify ar.pfs so ar.pfs remains
+	 * as 0, stopping the backtrace.  Record the previous ar.pfs when the current
+	 * IP is in ia64_spinlock_contention_pre3_4 then unwind, if pfs_loc has not changed
+	 * after unwind then use pt_regs.ar_pfs which is where the real ar.pfs is for
+	 * leaf functions.
+	 */
+	if (bt->prev_pfs_loc && bt->regs && bt->frame.pfs_loc == bt->prev_pfs_loc)
+		bt->frame.pfs_loc = &bt->regs->ar_pfs;
+	bt->prev_pfs_loc = (in_old_ool_spinlock_code(bt->frame.ip) ? bt->frame.pfs_loc : NULL);
+
+	return unw_unwind(&bt->frame) == 0;
+}
+
+
+static void do_ia64_backtrace(struct unw_frame_info *info, void *vdata)
+{
+	ia64_backtrace_t *bt = vdata;
+	struct switch_stack *sw;
+	int count = 0;
+	u_long pc, sp;
+
+	sw = (struct switch_stack *)(info+1);
+	/* padding from unw_init_running */
+	sw = (struct switch_stack *)(((unsigned long)sw + 15) & ~15);
+
+	unw_init_frame_info(&bt->frame, current, sw);
+
+	/* skip over interrupt frame and oprofile calls */
+	do {
+		unw_get_sp(&bt->frame, &sp);
+		if (sp >= (u_long)bt->regs)
+			break;
+		if (!next_frame(bt))
+			return;
+	} while (count++ < 200);
+
+	/* finally, grab the actual sample */
+	while (bt->depth-- && next_frame(bt)) {
+		unw_get_ip(&bt->frame, &pc);
+		oprofile_add_trace(pc);
+		if (unw_is_intr_frame(&bt->frame)) {
+			/*
+			 * Interrupt received on kernel stack; this can
+			 * happen when timer interrupt fires while processing
+			 * a softirq from the tail end of a hardware interrupt
+			 * which interrupted a system call.  Don't laugh, it
+			 * happens!  Splice the backtrace into two parts to
+			 * avoid spurious cycles in the gprof output.
+			 */
+			/* TODO: split rather than drop the 2nd half */
+			break;
+		}
+	}
+}
+
+void
+ia64_backtrace(struct pt_regs * const regs, unsigned int depth)
+{
+	ia64_backtrace_t bt;
+	unsigned long flags;
+
+	/*
+	 * On IA64 there is little hope of getting backtraces from
+	 * user space programs -- the problems of getting the unwind
+	 * information from arbitrary user programs are extreme.
+	 */
+	if (user_mode(regs))
+		return;
+
+	bt.depth = depth;
+	bt.regs = regs;
+	bt.prev_pfs_loc = NULL;
+	local_irq_save(flags);
+	unw_init_running(do_ia64_backtrace, &bt);
+	local_irq_restore(flags);
+}
diff -Nru a/arch/ia64/oprofile/init.c b/arch/ia64/oprofile/init.c
--- a/arch/ia64/oprofile/init.c	2005-03-01 23:38:52 -08:00
+++ b/arch/ia64/oprofile/init.c	2005-03-01 23:38:52 -08:00
@@ -12,15 +12,21 @@
 #include <linux/init.h>
 #include <linux/errno.h>
  
-extern int perfmon_init(struct oprofile_operations ** ops);
+extern int perfmon_init(struct oprofile_operations * ops);
 extern void perfmon_exit(void);
+extern void ia64_backtrace(struct pt_regs * const regs, unsigned int depth);
 
-int __init oprofile_arch_init(struct oprofile_operations ** ops)
+int __init oprofile_arch_init(struct oprofile_operations * ops)
 {
+	int ret = -ENODEV;
+
 #ifdef CONFIG_PERFMON
-	return perfmon_init(ops);
+	/* perfmon_init() can fail, but we have no way to report it */
+	ret = perfmon_init(ops);
 #endif
-	return -ENODEV;
+	ops->backtrace = ia64_backtrace;
+
+	return ret;
 }
 
 
diff -Nru a/arch/ia64/oprofile/perfmon.c b/arch/ia64/oprofile/perfmon.c
--- a/arch/ia64/oprofile/perfmon.c	2005-03-01 23:38:56 -08:00
+++ b/arch/ia64/oprofile/perfmon.c	2005-03-01 23:38:56 -08:00
@@ -21,8 +21,6 @@
 perfmon_handler(struct task_struct *task, void *buf, pfm_ovfl_arg_t *arg,
                 struct pt_regs *regs, unsigned long stamp)
 {
-	int cpu = smp_processor_id();
-	unsigned long eip = instruction_pointer(regs);
 	int event = arg->pmd_eventid;
  
 	arg->ovfl_ctrl.bits.reset_ovfl_pmds = 1;
@@ -31,7 +29,7 @@
 	 * without perfmon being shutdown (e.g. SIGSEGV)
 	 */
 	if (allow_ints)
-		oprofile_add_sample(eip, !user_mode(regs), event, cpu);
+		oprofile_add_sample(regs, event);
 	return 0;
 }
 
@@ -75,21 +73,18 @@
 
 
 /* all the ops are handled via userspace for IA64 perfmon */
-static struct oprofile_operations perfmon_ops = {
-	.start = perfmon_start,
-	.stop = perfmon_stop,
-};
 
 static int using_perfmon;
 
-int perfmon_init(struct oprofile_operations ** ops)
+int perfmon_init(struct oprofile_operations * ops)
 {
 	int ret = pfm_register_buffer_fmt(&oprofile_fmt);
 	if (ret)
 		return -ENODEV;
 
-	perfmon_ops.cpu_type = get_cpu_type();
-	*ops = &perfmon_ops;
+	ops->cpu_type = get_cpu_type();
+	ops->start = perfmon_start;
+	ops->stop = perfmon_stop;
 	using_perfmon = 1;
 	printk(KERN_INFO "oprofile: using perfmon.\n");
 	return 0;
diff -Nru a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
--- a/arch/ia64/pci/pci.c	2005-03-01 23:38:56 -08:00
+++ b/arch/ia64/pci/pci.c	2005-03-01 23:38:56 -08:00
@@ -6,6 +6,7 @@
  * Copyright (C) 2002 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  *	Bjorn Helgaas <bjorn_helgaas@hp.com>
+ * Copyright (C) 2004 Silicon Graphics, Inc.
  *
  * Note: Above list of copyright holders is incomplete...
  */
@@ -70,7 +71,7 @@
 	u64 addr, mode, data = 0;
 	int result = 0;
 
-	if ((seg > 255) || (bus > 255) || (devfn > 255) || (reg > 4095))
+	if ((seg > 65535) || (bus > 255) || (devfn > 255) || (reg > 4095))
 		return -EINVAL;
 
 	if ((seg | reg) <= 255) {
@@ -131,6 +132,19 @@
 	.write = pci_write,
 };
 
+#ifdef CONFIG_NUMA
+extern acpi_status acpi_map_iosapic(acpi_handle, u32, void *, void **);
+static void acpi_map_iosapics(void)
+{
+	acpi_get_devices(NULL, acpi_map_iosapic, NULL, NULL);
+}
+#else
+static void acpi_map_iosapics(void)
+{
+	return;
+}
+#endif /* CONFIG_NUMA */
+
 static int __init
 pci_acpi_init (void)
 {
@@ -138,11 +152,7 @@
 
 	printk(KERN_INFO "PCI: Using ACPI for IRQ routing\n");
 
-#ifdef CONFIG_NUMA
-extern acpi_status acpi_map_iosapic (acpi_handle, u32, void*, void**);
-
-	acpi_get_devices(NULL, acpi_map_iosapic, NULL, NULL);
-#endif
+	acpi_map_iosapics();
 
 	if (pci_routeirq) {
 		/*
@@ -154,7 +164,7 @@
 		printk(KERN_INFO "** was specified.  If this was required to make a driver work,\n");
 		printk(KERN_INFO "** please email the output of \"lspci\" to bjorn.helgaas@hp.com\n");
 		printk(KERN_INFO "** so I can fix the driver.\n");
-		while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL)
+		for_each_pci_dev(dev)
 			acpi_pci_irq_enable(dev);
 	} else {
 		printk(KERN_INFO "** PCI interrupts are no longer routed automatically.  If this\n");
@@ -367,6 +377,7 @@
 	region->start = res->start - offset;
 	region->end = res->end - offset;
 }
+EXPORT_SYMBOL(pcibios_resource_to_bus);
 
 void pcibios_bus_to_resource(struct pci_dev *dev,
 		struct resource *res, struct pci_bus_region *region)
@@ -480,6 +491,14 @@
 	return acpi_pci_irq_enable(dev);
 }
 
+#ifdef CONFIG_ACPI_DEALLOCATE_IRQ
+void
+pcibios_disable_device (struct pci_dev *dev)
+{
+	acpi_pci_irq_disable(dev);
+}
+#endif /* CONFIG_ACPI_DEALLOCATE_IRQ */
+
 void
 pcibios_align_resource (void *data, struct resource *res,
 		        unsigned long size, unsigned long align)
@@ -518,9 +537,10 @@
 	 * 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);
+	vma->vm_flags |= (VM_SHM | VM_RESERVED | VM_IO);
 
-	if (write_combine)
+	if (write_combine && efi_range_is_wc(vma->vm_start,
+					     vma->vm_end - vma->vm_start))
 		vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
 	else
 		vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
@@ -530,6 +550,117 @@
 		return -EAGAIN;
 
 	return 0;
+}
+
+/**
+ * ia64_pci_get_legacy_mem - generic legacy mem routine
+ * @bus: bus to get legacy memory base address for
+ *
+ * Find the base of legacy memory for @bus.  This is typically the first
+ * megabyte of bus address space for @bus or is simply 0 on platforms whose
+ * chipsets support legacy I/O and memory routing.  Returns the base address
+ * or an error pointer if an error occurred.
+ *
+ * This is the ia64 generic version of this routine.  Other platforms
+ * are free to override it with a machine vector.
+ */
+char *ia64_pci_get_legacy_mem(struct pci_bus *bus)
+{
+	return (char *)__IA64_UNCACHED_OFFSET;
+}
+
+/**
+ * pci_mmap_legacy_page_range - map legacy memory space to userland
+ * @bus: bus whose legacy space we're mapping
+ * @vma: vma passed in by mmap
+ *
+ * Map legacy memory space for this device back to userspace using a machine
+ * vector to get the base address.
+ */
+int
+pci_mmap_legacy_page_range(struct pci_bus *bus, struct vm_area_struct *vma)
+{
+	char *addr;
+
+	addr = pci_get_legacy_mem(bus);
+	if (IS_ERR(addr))
+		return PTR_ERR(addr);
+
+	vma->vm_pgoff += (unsigned long)addr >> PAGE_SHIFT;
+	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+	vma->vm_flags |= (VM_SHM | VM_RESERVED | VM_IO);
+
+	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;
+}
+
+/**
+ * ia64_pci_legacy_read - read from legacy I/O space
+ * @bus: bus to read
+ * @port: legacy port value
+ * @val: caller allocated storage for returned value
+ * @size: number of bytes to read
+ *
+ * Simply reads @size bytes from @port and puts the result in @val.
+ *
+ * Again, this (and the write routine) are generic versions that can be
+ * overridden by the platform.  This is necessary on platforms that don't
+ * support legacy I/O routing or that hard fail on legacy I/O timeouts.
+ */
+int ia64_pci_legacy_read(struct pci_bus *bus, u16 port, u32 *val, u8 size)
+{
+	int ret = size;
+
+	switch (size) {
+	case 1:
+		*val = inb(port);
+		break;
+	case 2:
+		*val = inw(port);
+		break;
+	case 4:
+		*val = inl(port);
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+/**
+ * ia64_pci_legacy_write - perform a legacy I/O write
+ * @bus: bus pointer
+ * @port: port to write
+ * @val: value to write
+ * @size: number of bytes to write from @val
+ *
+ * Simply writes @size bytes of @val to @port.
+ */
+int ia64_pci_legacy_write(struct pci_dev *bus, u16 port, u32 val, u8 size)
+{
+	int ret = 0;
+
+	switch (size) {
+	case 1:
+		outb(val, port);
+		break;
+	case 2:
+		outw(val, port);
+		break;
+	case 4:
+		outl(val, port);
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
 }
 
 /**
diff -Nru a/arch/ia64/sn/include/shub.h b/arch/ia64/sn/include/shub.h
--- a/arch/ia64/sn/include/shub.h	2005-03-01 23:38:55 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,39 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (c) 2001-2004 Silicon Graphics, Inc.  All rights reserved.
- */
-
-#ifndef _ASM_IA64_SN_SHUB_H
-#define _ASM_IA64_SN_SHUB_H
-
-
-#define MD_MEM_BANKS            4
-
-
-/*
- * Junk Bus Address Space
- *   The junk bus is used to access the PROM, LED's, and UART. It's 
- *   accessed through the local block MMR space. The data path is
- *   16 bits wide. This space requires address bits 31-27 to be set, and
- *   is further divided by address bits 26:15.
- *   The LED addresses are write-only. To read the LEDs, you need to use
- *   SH_JUNK_BUS_LED0-3, defined in shub_mmr.h
- *		
- */
-#define SH_REAL_JUNK_BUS_LED0           0x7fed00000UL
-#define SH_REAL_JUNK_BUS_LED1           0x7fed10000UL
-#define SH_REAL_JUNK_BUS_LED2           0x7fed20000UL
-#define SH_REAL_JUNK_BUS_LED3           0x7fed30000UL
-#define SH_JUNK_BUS_UART0               0x7fed40000UL
-#define SH_JUNK_BUS_UART1               0x7fed40008UL
-#define SH_JUNK_BUS_UART2               0x7fed40010UL
-#define SH_JUNK_BUS_UART3               0x7fed40018UL
-#define SH_JUNK_BUS_UART4               0x7fed40020UL
-#define SH_JUNK_BUS_UART5               0x7fed40028UL
-#define SH_JUNK_BUS_UART6               0x7fed40030UL
-#define SH_JUNK_BUS_UART7               0x7fed40038UL
-
-#endif /* _ASM_IA64_SN_SHUB_H */
diff -Nru a/arch/ia64/sn/include/shubio.h b/arch/ia64/sn/include/shubio.h
--- a/arch/ia64/sn/include/shubio.h	2005-03-01 23:38:53 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,3476 +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_SHUBIO_H
-#define _ASM_IA64_SN_SHUBIO_H
-
-#define HUB_WIDGET_ID_MAX 0xf
-#define IIO_NUM_ITTES   7
-#define HUB_NUM_BIG_WINDOW      (IIO_NUM_ITTES - 1)
-
-#define    IIO_WID                   0x00400000    /* Crosstalk Widget Identification */
-                                                   /* This register is also accessible from
-                                                    * Crosstalk at address 0x0.  */
-#define    IIO_WSTAT                 0x00400008    /* Crosstalk Widget Status */
-#define    IIO_WCR                   0x00400020    /* Crosstalk Widget Control Register */
-#define    IIO_ILAPR                 0x00400100    /* IO Local Access Protection Register */
-#define    IIO_ILAPO                 0x00400108    /* IO Local Access Protection Override */
-#define    IIO_IOWA                  0x00400110    /* IO Outbound Widget Access */
-#define    IIO_IIWA                  0x00400118    /* IO Inbound Widget Access */
-#define    IIO_IIDEM                 0x00400120    /* IO Inbound Device Error Mask */
-#define    IIO_ILCSR                 0x00400128    /* IO LLP Control and Status Register */
-#define    IIO_ILLR                  0x00400130    /* IO LLP Log Register    */
-#define    IIO_IIDSR                 0x00400138    /* IO Interrupt Destination */
-
-#define    IIO_IGFX0                 0x00400140    /* IO Graphics Node-Widget Map 0 */
-#define    IIO_IGFX1                 0x00400148    /* IO Graphics Node-Widget Map 1 */
-
-#define    IIO_ISCR0                 0x00400150    /* IO Scratch Register 0 */
-#define    IIO_ISCR1                 0x00400158    /* IO Scratch Register 1 */
-
-#define    IIO_ITTE1                 0x00400160    /* IO Translation Table Entry 1 */
-#define    IIO_ITTE2                 0x00400168    /* IO Translation Table Entry 2 */
-#define    IIO_ITTE3                 0x00400170    /* IO Translation Table Entry 3 */
-#define    IIO_ITTE4                 0x00400178    /* IO Translation Table Entry 4 */
-#define    IIO_ITTE5                 0x00400180    /* IO Translation Table Entry 5 */
-#define    IIO_ITTE6                 0x00400188    /* IO Translation Table Entry 6 */
-#define    IIO_ITTE7                 0x00400190    /* IO Translation Table Entry 7 */
-
-#define    IIO_IPRB0                 0x00400198    /* IO PRB Entry 0         */
-#define    IIO_IPRB8                 0x004001A0    /* IO PRB Entry 8         */
-#define    IIO_IPRB9                 0x004001A8    /* IO PRB Entry 9         */
-#define    IIO_IPRBA                 0x004001B0    /* IO PRB Entry A         */
-#define    IIO_IPRBB                 0x004001B8    /* IO PRB Entry B         */
-#define    IIO_IPRBC                 0x004001C0    /* IO PRB Entry C         */
-#define    IIO_IPRBD                 0x004001C8    /* IO PRB Entry D         */
-#define    IIO_IPRBE                 0x004001D0    /* IO PRB Entry E         */
-#define    IIO_IPRBF                 0x004001D8    /* IO PRB Entry F         */
-
-#define    IIO_IXCC                  0x004001E0    /* IO Crosstalk Credit Count Timeout */
-#define    IIO_IMEM                  0x004001E8    /* IO Miscellaneous Error Mask */
-#define    IIO_IXTT                  0x004001F0    /* IO Crosstalk Timeout Threshold */
-#define    IIO_IECLR                 0x004001F8    /* IO Error Clear Register */
-#define    IIO_IBCR                  0x00400200    /* IO BTE Control Register */
-
-#define    IIO_IXSM                  0x00400208    /* IO Crosstalk Spurious Message */
-#define    IIO_IXSS                  0x00400210    /* IO Crosstalk Spurious Sideband */
-
-#define    IIO_ILCT                  0x00400218    /* IO LLP Channel Test    */
-
-#define    IIO_IIEPH1                0x00400220    /* IO Incoming Error Packet Header, Part 1 */
-#define    IIO_IIEPH2                0x00400228    /* IO Incoming Error Packet Header, Part 2 */
-
-
-#define    IIO_ISLAPR                0x00400230    /* IO SXB Local Access Protection Regster */
-#define    IIO_ISLAPO                0x00400238    /* IO SXB Local Access Protection Override */
-
-#define    IIO_IWI                   0x00400240    /* IO Wrapper Interrupt Register */
-#define    IIO_IWEL                  0x00400248    /* IO Wrapper Error Log Register */
-#define    IIO_IWC                   0x00400250    /* IO Wrapper Control Register */
-#define    IIO_IWS                   0x00400258    /* IO Wrapper Status Register */
-#define    IIO_IWEIM                 0x00400260    /* IO Wrapper Error Interrupt Masking Register */
-
-#define    IIO_IPCA                  0x00400300    /* IO PRB Counter Adjust */
-
-#define    IIO_IPRTE0_A              0x00400308    /* IO PIO Read Address Table Entry 0, Part A */
-#define    IIO_IPRTE1_A              0x00400310    /* IO PIO Read Address Table Entry 1, Part A */
-#define    IIO_IPRTE2_A              0x00400318    /* IO PIO Read Address Table Entry 2, Part A */
-#define    IIO_IPRTE3_A               0x00400320    /* IO PIO Read Address Table Entry 3, Part A */
-#define    IIO_IPRTE4_A               0x00400328    /* IO PIO Read Address Table Entry 4, Part A */
-#define    IIO_IPRTE5_A               0x00400330    /* IO PIO Read Address Table Entry 5, Part A */
-#define    IIO_IPRTE6_A               0x00400338    /* IO PIO Read Address Table Entry 6, Part A */
-#define    IIO_IPRTE7_A               0x00400340    /* IO PIO Read Address Table Entry 7, Part A */
-
-#define    IIO_IPRTE0_B              0x00400348    /* IO PIO Read Address Table Entry 0, Part B */
-#define    IIO_IPRTE1_B              0x00400350    /* IO PIO Read Address Table Entry 1, Part B */
-#define    IIO_IPRTE2_B              0x00400358    /* IO PIO Read Address Table Entry 2, Part B */
-#define    IIO_IPRTE3_B               0x00400360    /* IO PIO Read Address Table Entry 3, Part B */
-#define    IIO_IPRTE4_B               0x00400368    /* IO PIO Read Address Table Entry 4, Part B */
-#define    IIO_IPRTE5_B               0x00400370    /* IO PIO Read Address Table Entry 5, Part B */
-#define    IIO_IPRTE6_B               0x00400378    /* IO PIO Read Address Table Entry 6, Part B */
-#define    IIO_IPRTE7_B               0x00400380    /* IO PIO Read Address Table Entry 7, Part B */
-
-#define    IIO_IPDR                  0x00400388    /* IO PIO Deallocation Register */
-#define    IIO_ICDR                  0x00400390    /* IO CRB Entry Deallocation Register */
-#define    IIO_IFDR                  0x00400398    /* IO IOQ FIFO Depth Register */
-#define    IIO_IIAP                  0x004003A0    /* IO IIQ Arbitration Parameters */
-#define    IIO_ICMR                  0x004003A8    /* IO CRB Management Register */
-#define    IIO_ICCR                  0x004003B0    /* IO CRB Control Register */
-#define    IIO_ICTO                  0x004003B8    /* IO CRB Timeout         */
-#define    IIO_ICTP                  0x004003C0    /* IO CRB Timeout Prescalar */
-
-#define    IIO_ICRB0_A               0x00400400    /* IO CRB Entry 0_A       */
-#define    IIO_ICRB0_B               0x00400408    /* IO CRB Entry 0_B       */
-#define    IIO_ICRB0_C               0x00400410    /* IO CRB Entry 0_C       */
-#define    IIO_ICRB0_D               0x00400418    /* IO CRB Entry 0_D       */
-#define    IIO_ICRB0_E               0x00400420    /* IO CRB Entry 0_E       */
-
-#define    IIO_ICRB1_A               0x00400430    /* IO CRB Entry 1_A       */
-#define    IIO_ICRB1_B               0x00400438    /* IO CRB Entry 1_B       */
-#define    IIO_ICRB1_C               0x00400440    /* IO CRB Entry 1_C       */
-#define    IIO_ICRB1_D               0x00400448    /* IO CRB Entry 1_D       */
-#define    IIO_ICRB1_E               0x00400450    /* IO CRB Entry 1_E       */
-
-#define    IIO_ICRB2_A               0x00400460    /* IO CRB Entry 2_A       */
-#define    IIO_ICRB2_B               0x00400468    /* IO CRB Entry 2_B       */
-#define    IIO_ICRB2_C               0x00400470    /* IO CRB Entry 2_C       */
-#define    IIO_ICRB2_D               0x00400478    /* IO CRB Entry 2_D       */
-#define    IIO_ICRB2_E               0x00400480    /* IO CRB Entry 2_E       */
-
-#define    IIO_ICRB3_A               0x00400490    /* IO CRB Entry 3_A       */
-#define    IIO_ICRB3_B               0x00400498    /* IO CRB Entry 3_B       */
-#define    IIO_ICRB3_C               0x004004a0    /* IO CRB Entry 3_C       */
-#define    IIO_ICRB3_D               0x004004a8    /* IO CRB Entry 3_D       */
-#define    IIO_ICRB3_E               0x004004b0    /* IO CRB Entry 3_E       */
-
-#define    IIO_ICRB4_A               0x004004c0    /* IO CRB Entry 4_A       */
-#define    IIO_ICRB4_B               0x004004c8    /* IO CRB Entry 4_B       */
-#define    IIO_ICRB4_C               0x004004d0    /* IO CRB Entry 4_C       */
-#define    IIO_ICRB4_D               0x004004d8    /* IO CRB Entry 4_D       */
-#define    IIO_ICRB4_E               0x004004e0    /* IO CRB Entry 4_E       */
-
-#define    IIO_ICRB5_A               0x004004f0    /* IO CRB Entry 5_A       */
-#define    IIO_ICRB5_B               0x004004f8    /* IO CRB Entry 5_B       */
-#define    IIO_ICRB5_C               0x00400500    /* IO CRB Entry 5_C       */
-#define    IIO_ICRB5_D               0x00400508    /* IO CRB Entry 5_D       */
-#define    IIO_ICRB5_E               0x00400510    /* IO CRB Entry 5_E       */
-
-#define    IIO_ICRB6_A               0x00400520    /* IO CRB Entry 6_A       */
-#define    IIO_ICRB6_B               0x00400528    /* IO CRB Entry 6_B       */
-#define    IIO_ICRB6_C               0x00400530    /* IO CRB Entry 6_C       */
-#define    IIO_ICRB6_D               0x00400538    /* IO CRB Entry 6_D       */
-#define    IIO_ICRB6_E               0x00400540    /* IO CRB Entry 6_E       */
-
-#define    IIO_ICRB7_A               0x00400550    /* IO CRB Entry 7_A       */
-#define    IIO_ICRB7_B               0x00400558    /* IO CRB Entry 7_B       */
-#define    IIO_ICRB7_C               0x00400560    /* IO CRB Entry 7_C       */
-#define    IIO_ICRB7_D               0x00400568    /* IO CRB Entry 7_D       */
-#define    IIO_ICRB7_E               0x00400570    /* IO CRB Entry 7_E       */
-
-#define    IIO_ICRB8_A               0x00400580    /* IO CRB Entry 8_A       */
-#define    IIO_ICRB8_B               0x00400588    /* IO CRB Entry 8_B       */
-#define    IIO_ICRB8_C               0x00400590    /* IO CRB Entry 8_C       */
-#define    IIO_ICRB8_D               0x00400598    /* IO CRB Entry 8_D       */
-#define    IIO_ICRB8_E               0x004005a0    /* IO CRB Entry 8_E       */
-
-#define    IIO_ICRB9_A               0x004005b0    /* IO CRB Entry 9_A       */
-#define    IIO_ICRB9_B               0x004005b8    /* IO CRB Entry 9_B       */
-#define    IIO_ICRB9_C               0x004005c0    /* IO CRB Entry 9_C       */
-#define    IIO_ICRB9_D               0x004005c8    /* IO CRB Entry 9_D       */
-#define    IIO_ICRB9_E               0x004005d0    /* IO CRB Entry 9_E       */
-
-#define    IIO_ICRBA_A               0x004005e0    /* IO CRB Entry A_A       */
-#define    IIO_ICRBA_B               0x004005e8    /* IO CRB Entry A_B       */
-#define    IIO_ICRBA_C               0x004005f0    /* IO CRB Entry A_C       */
-#define    IIO_ICRBA_D               0x004005f8    /* IO CRB Entry A_D       */
-#define    IIO_ICRBA_E               0x00400600    /* IO CRB Entry A_E       */
-
-#define    IIO_ICRBB_A               0x00400610    /* IO CRB Entry B_A       */
-#define    IIO_ICRBB_B               0x00400618    /* IO CRB Entry B_B       */
-#define    IIO_ICRBB_C               0x00400620    /* IO CRB Entry B_C       */
-#define    IIO_ICRBB_D               0x00400628    /* IO CRB Entry B_D       */
-#define    IIO_ICRBB_E               0x00400630    /* IO CRB Entry B_E       */
-
-#define    IIO_ICRBC_A               0x00400640    /* IO CRB Entry C_A       */
-#define    IIO_ICRBC_B               0x00400648    /* IO CRB Entry C_B       */
-#define    IIO_ICRBC_C               0x00400650    /* IO CRB Entry C_C       */
-#define    IIO_ICRBC_D               0x00400658    /* IO CRB Entry C_D       */
-#define    IIO_ICRBC_E               0x00400660    /* IO CRB Entry C_E       */
-
-#define    IIO_ICRBD_A               0x00400670    /* IO CRB Entry D_A       */
-#define    IIO_ICRBD_B               0x00400678    /* IO CRB Entry D_B       */
-#define    IIO_ICRBD_C               0x00400680    /* IO CRB Entry D_C       */
-#define    IIO_ICRBD_D               0x00400688    /* IO CRB Entry D_D       */
-#define    IIO_ICRBD_E               0x00400690    /* IO CRB Entry D_E       */
-
-#define    IIO_ICRBE_A               0x004006a0    /* IO CRB Entry E_A       */
-#define    IIO_ICRBE_B               0x004006a8    /* IO CRB Entry E_B       */
-#define    IIO_ICRBE_C               0x004006b0    /* IO CRB Entry E_C       */
-#define    IIO_ICRBE_D               0x004006b8    /* IO CRB Entry E_D       */
-#define    IIO_ICRBE_E               0x004006c0    /* IO CRB Entry E_E       */
-
-#define    IIO_ICSML                 0x00400700    /* IO CRB Spurious Message Low */
-#define    IIO_ICSMM                 0x00400708    /* IO CRB Spurious Message Middle */
-#define    IIO_ICSMH                 0x00400710    /* IO CRB Spurious Message High */
-
-#define    IIO_IDBSS                 0x00400718    /* IO Debug Submenu Select */
-
-#define    IIO_IBLS0                 0x00410000    /* IO BTE Length Status 0 */
-#define    IIO_IBSA0                 0x00410008    /* IO BTE Source Address 0 */
-#define    IIO_IBDA0                 0x00410010    /* IO BTE Destination Address 0 */
-#define    IIO_IBCT0                 0x00410018    /* IO BTE Control Terminate 0 */
-#define    IIO_IBNA0                 0x00410020    /* IO BTE Notification Address 0 */
-#define    IIO_IBIA0                 0x00410028    /* IO BTE Interrupt Address 0 */
-#define    IIO_IBLS1                 0x00420000    /* IO BTE Length Status 1 */
-#define    IIO_IBSA1                 0x00420008    /* IO BTE Source Address 1 */
-#define    IIO_IBDA1                 0x00420010    /* IO BTE Destination Address 1 */
-#define    IIO_IBCT1                 0x00420018    /* IO BTE Control Terminate 1 */
-#define    IIO_IBNA1                 0x00420020    /* IO BTE Notification Address 1 */
-#define    IIO_IBIA1                 0x00420028    /* IO BTE Interrupt Address 1 */
-
-#define    IIO_IPCR                  0x00430000    /* IO Performance Control */
-#define    IIO_IPPR                  0x00430008    /* IO Performance Profiling */
-
-
-/************************************************************************
- *                                                                      *
- * Description:  This register echoes some information from the         *
- * LB_REV_ID register. It is available through Crosstalk as described   *
- * above. The REV_NUM and MFG_NUM fields receive their values from      *
- * the REVISION and MANUFACTURER fields in the LB_REV_ID register.      *
- * The PART_NUM field's value is the Crosstalk device ID number that    *
- * Steve Miller assigned to the SHub chip.                              *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_wid_u {
-	uint64_t	ii_wid_regval;
-	struct	{
-		uint64_t	w_rsvd_1		  :	 1;
-		uint64_t	w_mfg_num		  :	11;
-		uint64_t	w_part_num		  :	16;
-		uint64_t	w_rev_num		  :	 4;
-		uint64_t	w_rsvd			  :	32;
-	} ii_wid_fld_s;
-} ii_wid_u_t;
-
-
-/************************************************************************
- *                                                                      *
- *  The fields in this register are set upon detection of an error      *
- * and cleared by various mechanisms, as explained in the               *
- * description.                                                         *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_wstat_u {
-	uint64_t	ii_wstat_regval;
-	struct	{
-		uint64_t	w_pending		  :	 4;
-		uint64_t	w_xt_crd_to		  :	 1;
-		uint64_t	w_xt_tail_to		  :	 1;
-		uint64_t	w_rsvd_3		  :	 3;
-		uint64_t       w_tx_mx_rty               :      1;
-		uint64_t	w_rsvd_2		  :	 6;
-		uint64_t	w_llp_tx_cnt		  :	 8;
-		uint64_t	w_rsvd_1		  :	 8;
-		uint64_t	w_crazy			  :	 1;
-		uint64_t	w_rsvd			  :	31;
-	} ii_wstat_fld_s;
-} ii_wstat_u_t;
-
-
-/************************************************************************
- *                                                                      *
- * Description:  This is a read-write enabled register. It controls     *
- * various aspects of the Crosstalk flow control.                       *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_wcr_u {
-	uint64_t	ii_wcr_regval;
-	struct	{
-		uint64_t	w_wid			  :	 4;
-		uint64_t	w_tag			  :	 1;
-		uint64_t	w_rsvd_1		  :	 8;
-		uint64_t	w_dst_crd		  :	 3;
-		uint64_t	w_f_bad_pkt		  :	 1;
-		uint64_t	w_dir_con		  :	 1;
-		uint64_t	w_e_thresh		  :	 5;
-		uint64_t	w_rsvd			  :	41;
-	} ii_wcr_fld_s;
-} ii_wcr_u_t;
-
-
-/************************************************************************
- *                                                                      *
- * Description:  This register's value is a bit vector that guards      *
- * access to local registers within the II as well as to external       *
- * Crosstalk widgets. Each bit in the register corresponds to a         *
- * particular region in the system; a region consists of one, two or    *
- * four nodes (depending on the value of the REGION_SIZE field in the   *
- * LB_REV_ID register, which is documented in Section 8.3.1.1). The     *
- * protection provided by this register applies to PIO read             *
- * operations as well as PIO write operations. The II will perform a    *
- * PIO read or write request only if the bit for the requestor's        *
- * region is set; otherwise, the II will not perform the requested      *
- * operation and will return an error response. When a PIO read or      *
- * write request targets an external Crosstalk widget, then not only    *
- * must the bit for the requestor's region be set in the ILAPR, but     *
- * also the target widget's bit in the IOWA register must be set in     *
- * order for the II to perform the requested operation; otherwise,      *
- * the II will return an error response. Hence, the protection          *
- * provided by the IOWA register supplements the protection provided    *
- * by the ILAPR for requests that target external Crosstalk widgets.    *
- * This register itself can be accessed only by the nodes whose         *
- * region ID bits are enabled in this same register. It can also be     *
- * accessed through the IAlias space by the local processors.           *
- * The reset value of this register allows access by all nodes.         *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_ilapr_u {
-	uint64_t	ii_ilapr_regval;
-	struct  {
-		uint64_t	i_region                  :	64;
-	} ii_ilapr_fld_s;
-} ii_ilapr_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  A write to this register of the 64-bit value           *
- * "SGIrules" in ASCII, will cause the bit in the ILAPR register        *
- * corresponding to the region of the requestor to be set (allow        *
- * access). A write of any other value will be ignored. Access          *
- * protection for this register is "SGIrules".                          *
- * This register can also be accessed through the IAlias space.         *
- * However, this access will not change the access permissions in the   *
- * ILAPR.                                                               *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_ilapo_u {
-	uint64_t	ii_ilapo_regval;
-	struct	{
-		uint64_t	i_io_ovrride            :	64;
-	} ii_ilapo_fld_s;
-} ii_ilapo_u_t;
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register qualifies all the PIO and Graphics writes launched    *
- * from the SHUB towards a widget.                                      *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_iowa_u {
-	uint64_t	ii_iowa_regval;
-	struct	{
-		uint64_t	i_w0_oac		  :	 1;
-		uint64_t	i_rsvd_1		  :	 7;
-                uint64_t       i_wx_oac                  :      8;
-		uint64_t	i_rsvd			  :	48;
-	} ii_iowa_fld_s;
-} ii_iowa_u_t;
-
-
-/************************************************************************
- *                                                                      *
- * Description:  This register qualifies all the requests launched      *
- * from a widget towards the Shub. This register is intended to be      *
- * used by software in case of misbehaving widgets.                     *
- *                                                                      *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_iiwa_u {
-	uint64_t	ii_iiwa_regval;
-	struct  {
-		uint64_t	i_w0_iac                  :	 1;
-		uint64_t	i_rsvd_1		  :	 7;
-		uint64_t	i_wx_iac		  :	 8;
-		uint64_t	i_rsvd			  :	48;
-	} ii_iiwa_fld_s;
-} ii_iiwa_u_t;
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  This register qualifies all the operations launched    *
- * from a widget towards the SHub. It allows individual access          *
- * control for up to 8 devices per widget. A device refers to           *
- * individual DMA master hosted by a widget.                            *
- * The bits in each field of this register are cleared by the Shub      *
- * upon detection of an error which requires the device to be           *
- * disabled. These fields assume that 0=TNUM=7 (i.e., Bridge-centric    *
- * Crosstalk). Whether or not a device has access rights to this        *
- * Shub is determined by an AND of the device enable bit in the         *
- * appropriate field of this register and the corresponding bit in      *
- * the Wx_IAC field (for the widget which this device belongs to).      *
- * The bits in this field are set by writing a 1 to them. Incoming      *
- * replies from Crosstalk are not subject to this access control        *
- * mechanism.                                                           *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_iidem_u {
-	uint64_t	ii_iidem_regval;
-	struct	{
-		uint64_t	i_w8_dxs		  :	 8;
-		uint64_t	i_w9_dxs		  :	 8;
-		uint64_t	i_wa_dxs		  :	 8;
-		uint64_t	i_wb_dxs		  :	 8;
-		uint64_t	i_wc_dxs		  :	 8;
-		uint64_t	i_wd_dxs		  :	 8;
-		uint64_t	i_we_dxs		  :	 8;
-		uint64_t	i_wf_dxs		  :	 8;
-	} ii_iidem_fld_s;
-} ii_iidem_u_t;
-
-
-/************************************************************************
- *                                                                      *
- *  This register contains the various programmable fields necessary    *
- * for controlling and observing the LLP signals.                       *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_ilcsr_u {
-	uint64_t	ii_ilcsr_regval;
-	struct  {
-		uint64_t	i_nullto                  :	 6;
-		uint64_t	i_rsvd_4		  :	 2;
-		uint64_t	i_wrmrst		  :	 1;
-		uint64_t	i_rsvd_3		  :	 1;
-		uint64_t	i_llp_en		  :	 1;
-		uint64_t	i_bm8			  :	 1;
-		uint64_t	i_llp_stat		  :	 2;
-		uint64_t	i_remote_power		  :	 1;
-		uint64_t	i_rsvd_2		  :	 1;
-		uint64_t	i_maxrtry		  :	10;
-		uint64_t	i_d_avail_sel		  :	 2;
-		uint64_t	i_rsvd_1		  :	 4;
-		uint64_t	i_maxbrst		  :	10;
-                uint64_t       i_rsvd                    :     22;
-
-	} ii_ilcsr_fld_s;
-} ii_ilcsr_u_t;
-
-
-/************************************************************************
- *                                                                      *
- *  This is simply a status registers that monitors the LLP error       *
- * rate.                                                                *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_illr_u {
-	uint64_t	ii_illr_regval;
-	struct	{
-		uint64_t	i_sn_cnt		  :	16;
-		uint64_t	i_cb_cnt		  :	16;
-		uint64_t	i_rsvd			  :	32;
-	} ii_illr_fld_s;
-} ii_illr_u_t;
-
-
-/************************************************************************
- *                                                                      *
- * Description:  All II-detected non-BTE error interrupts are           *
- * specified via this register.                                         *
- * NOTE: The PI interrupt register address is hardcoded in the II. If   *
- * PI_ID==0, then the II sends an interrupt request (Duplonet PWRI      *
- * packet) to address offset 0x0180_0090 within the local register      *
- * address space of PI0 on the node specified by the NODE field. If     *
- * PI_ID==1, then the II sends the interrupt request to address         *
- * offset 0x01A0_0090 within the local register address space of PI1    *
- * on the node specified by the NODE field.                             *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_iidsr_u {
-	uint64_t	ii_iidsr_regval;
-	struct  {
-		uint64_t	i_level                   :	 8;
-		uint64_t	i_pi_id			  :	 1;
-		uint64_t	i_node			  :	11;
-		uint64_t       i_rsvd_3                  :      4;
-		uint64_t	i_enable		  :	 1;
-		uint64_t	i_rsvd_2		  :	 3;
-		uint64_t	i_int_sent		  :	 2;
-		uint64_t       i_rsvd_1                  :      2;
-		uint64_t	i_pi0_forward_int	  :	 1;
-		uint64_t	i_pi1_forward_int	  :	 1;
-		uint64_t	i_rsvd			  :	30;
-	} ii_iidsr_fld_s;
-} ii_iidsr_u_t;
-
-
-
-/************************************************************************
- *                                                                      *
- *  There are two instances of this register. This register is used     *
- * for matching up the incoming responses from the graphics widget to   *
- * the processor that initiated the graphics operation. The             *
- * write-responses are converted to graphics credits and returned to    *
- * the processor so that the processor interface can manage the flow    *
- * control.                                                             *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_igfx0_u {
-	uint64_t	ii_igfx0_regval;
-	struct	{
-		uint64_t	i_w_num			  :	 4;
-		uint64_t       i_pi_id                   :      1;
-		uint64_t	i_n_num			  :	12;
-		uint64_t       i_p_num                   :      1;
-		uint64_t       i_rsvd                    :     46;
-	} ii_igfx0_fld_s;
-} ii_igfx0_u_t;
-
-
-/************************************************************************
- *                                                                      *
- *  There are two instances of this register. This register is used     *
- * for matching up the incoming responses from the graphics widget to   *
- * the processor that initiated the graphics operation. The             *
- * write-responses are converted to graphics credits and returned to    *
- * the processor so that the processor interface can manage the flow    *
- * control.                                                             *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_igfx1_u {
-	uint64_t	ii_igfx1_regval;
-	struct  {
-		uint64_t	i_w_num			  :	 4;
-		uint64_t       i_pi_id                   :      1;
-		uint64_t	i_n_num			  :	12;
-		uint64_t       i_p_num                   :      1;
-		uint64_t       i_rsvd                    :     46;
-	} ii_igfx1_fld_s;
-} ii_igfx1_u_t;
-
-
-/************************************************************************
- *                                                                      *
- *  There are two instances of this registers. These registers are      *
- * used as scratch registers for software use.                          *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_iscr0_u {
-	uint64_t	ii_iscr0_regval;
-	struct  {
-		uint64_t	i_scratch                 :	64;
-	} ii_iscr0_fld_s;
-} ii_iscr0_u_t;
-
-
-
-/************************************************************************
- *                                                                      *
- *  There are two instances of this registers. These registers are      *
- * used as scratch registers for software use.                          *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_iscr1_u {
-	uint64_t	ii_iscr1_regval;
-	struct  {
-		uint64_t	i_scratch                 :	64;
-	} ii_iscr1_fld_s;
-} ii_iscr1_u_t;
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There are seven instances of translation table entry   *
- * registers. Each register maps a Shub Big Window to a 48-bit          *
- * address on Crosstalk.                                                *
- * For M-mode (128 nodes, 8 GBytes/node), SysAD[31:29] (Big Window      *
- * number) are used to select one of these 7 registers. The Widget      *
- * number field is then derived from the W_NUM field for synthesizing   *
- * a Crosstalk packet. The 5 bits of OFFSET are concatenated with       *
- * SysAD[28:0] to form Crosstalk[33:0]. The upper Crosstalk[47:34]      *
- * are padded with zeros. Although the maximum Crosstalk space          *
- * addressable by the SHub is thus the lower 16 GBytes per widget       * 
- * (M-mode), however only <SUP >7</SUP>/<SUB >32nds</SUB> of this       *
- * space can be accessed.                                               *
- * For the N-mode (256 nodes, 4 GBytes/node), SysAD[30:28] (Big         *
- * Window number) are used to select one of these 7 registers. The      *
- * Widget number field is then derived from the W_NUM field for         *
- * synthesizing a Crosstalk packet. The 5 bits of OFFSET are            *
- * concatenated with SysAD[27:0] to form Crosstalk[33:0]. The IOSP      *
- * field is used as Crosstalk[47], and remainder of the Crosstalk       *
- * address bits (Crosstalk[46:34]) are always zero. While the maximum   *
- * Crosstalk space addressable by the Shub is thus the lower            *
- * 8-GBytes per widget (N-mode), only <SUP >7</SUP>/<SUB >32nds</SUB>   *
- * of this space can be accessed.                                       *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_itte1_u {
-	uint64_t	ii_itte1_regval;
-	struct  {
-		uint64_t	i_offset                  :	 5;
-		uint64_t	i_rsvd_1		  :	 3;
-		uint64_t	i_w_num			  :	 4;
-		uint64_t	i_iosp			  :	 1;
-		uint64_t	i_rsvd			  :	51;
-	} ii_itte1_fld_s;
-} ii_itte1_u_t;
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There are seven instances of translation table entry   *
- * registers. Each register maps a Shub Big Window to a 48-bit          *
- * address on Crosstalk.                                                *
- * For M-mode (128 nodes, 8 GBytes/node), SysAD[31:29] (Big Window      *
- * number) are used to select one of these 7 registers. The Widget      *
- * number field is then derived from the W_NUM field for synthesizing   *
- * a Crosstalk packet. The 5 bits of OFFSET are concatenated with       *
- * SysAD[28:0] to form Crosstalk[33:0]. The upper Crosstalk[47:34]      *
- * are padded with zeros. Although the maximum Crosstalk space          *
- * addressable by the Shub is thus the lower 16 GBytes per widget       *
- * (M-mode), however only <SUP >7</SUP>/<SUB >32nds</SUB> of this       *
- * space can be accessed.                                               *
- * For the N-mode (256 nodes, 4 GBytes/node), SysAD[30:28] (Big         *
- * Window number) are used to select one of these 7 registers. The      *
- * Widget number field is then derived from the W_NUM field for         *
- * synthesizing a Crosstalk packet. The 5 bits of OFFSET are            *
- * concatenated with SysAD[27:0] to form Crosstalk[33:0]. The IOSP      *
- * field is used as Crosstalk[47], and remainder of the Crosstalk       *
- * address bits (Crosstalk[46:34]) are always zero. While the maximum   *
- * Crosstalk space addressable by the Shub is thus the lower            *
- * 8-GBytes per widget (N-mode), only <SUP >7</SUP>/<SUB >32nds</SUB>   *
- * of this space can be accessed.                                       *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_itte2_u {
-	uint64_t	ii_itte2_regval;
-	struct	{
-		uint64_t	i_offset		  :	 5;
-		uint64_t	i_rsvd_1		  :	 3;
-		uint64_t	i_w_num			  :	 4;
-		uint64_t	i_iosp			  :	 1;
-		uint64_t       i_rsvd                    :     51;
-	} ii_itte2_fld_s;
-} ii_itte2_u_t;
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There are seven instances of translation table entry   *
- * registers. Each register maps a Shub Big Window to a 48-bit          *
- * address on Crosstalk.                                                *
- * For M-mode (128 nodes, 8 GBytes/node), SysAD[31:29] (Big Window      *
- * number) are used to select one of these 7 registers. The Widget      *
- * number field is then derived from the W_NUM field for synthesizing   *
- * a Crosstalk packet. The 5 bits of OFFSET are concatenated with       *
- * SysAD[28:0] to form Crosstalk[33:0]. The upper Crosstalk[47:34]      *
- * are padded with zeros. Although the maximum Crosstalk space          *
- * addressable by the Shub is thus the lower 16 GBytes per widget       *
- * (M-mode), however only <SUP >7</SUP>/<SUB >32nds</SUB> of this       *
- * space can be accessed.                                               *
- * For the N-mode (256 nodes, 4 GBytes/node), SysAD[30:28] (Big         *
- * Window number) are used to select one of these 7 registers. The      *
- * Widget number field is then derived from the W_NUM field for         *
- * synthesizing a Crosstalk packet. The 5 bits of OFFSET are            *
- * concatenated with SysAD[27:0] to form Crosstalk[33:0]. The IOSP      *
- * field is used as Crosstalk[47], and remainder of the Crosstalk       *
- * address bits (Crosstalk[46:34]) are always zero. While the maximum   *
- * Crosstalk space addressable by the SHub is thus the lower            *
- * 8-GBytes per widget (N-mode), only <SUP >7</SUP>/<SUB >32nds</SUB>   *
- * of this space can be accessed.                                       *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_itte3_u {
-	uint64_t	ii_itte3_regval;
-	struct  {
-		uint64_t	i_offset                  :	 5;
-		uint64_t       i_rsvd_1                  :      3;
-		uint64_t       i_w_num                   :      4;
-		uint64_t       i_iosp                    :      1;
-		uint64_t       i_rsvd                    :     51;
-	} ii_itte3_fld_s;
-} ii_itte3_u_t;
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There are seven instances of translation table entry   *
- * registers. Each register maps a SHub Big Window to a 48-bit          *
- * address on Crosstalk.                                                *
- * For M-mode (128 nodes, 8 GBytes/node), SysAD[31:29] (Big Window      *
- * number) are used to select one of these 7 registers. The Widget      *
- * number field is then derived from the W_NUM field for synthesizing   *
- * a Crosstalk packet. The 5 bits of OFFSET are concatenated with       *
- * SysAD[28:0] to form Crosstalk[33:0]. The upper Crosstalk[47:34]      *
- * are padded with zeros. Although the maximum Crosstalk space          *
- * addressable by the SHub is thus the lower 16 GBytes per widget       *
- * (M-mode), however only <SUP >7</SUP>/<SUB >32nds</SUB> of this       *
- * space can be accessed.                                               *
- * For the N-mode (256 nodes, 4 GBytes/node), SysAD[30:28] (Big         *
- * Window number) are used to select one of these 7 registers. The      *
- * Widget number field is then derived from the W_NUM field for         *
- * synthesizing a Crosstalk packet. The 5 bits of OFFSET are            *
- * concatenated with SysAD[27:0] to form Crosstalk[33:0]. The IOSP      *
- * field is used as Crosstalk[47], and remainder of the Crosstalk       *
- * address bits (Crosstalk[46:34]) are always zero. While the maximum   *
- * Crosstalk space addressable by the SHub is thus the lower            *
- * 8-GBytes per widget (N-mode), only <SUP >7</SUP>/<SUB >32nds</SUB>   *
- * of this space can be accessed.                                       *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_itte4_u {
-	uint64_t	ii_itte4_regval;
-	struct  {
-		uint64_t	i_offset                  :	 5;
-		uint64_t	i_rsvd_1		  :	 3;
-		uint64_t       i_w_num                   :      4;
-		uint64_t       i_iosp                    :      1;
-		uint64_t       i_rsvd                    :     51;
-	} ii_itte4_fld_s;
-} ii_itte4_u_t;
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There are seven instances of translation table entry   *
- * registers. Each register maps a SHub Big Window to a 48-bit          *
- * address on Crosstalk.                                                *
- * For M-mode (128 nodes, 8 GBytes/node), SysAD[31:29] (Big Window      *
- * number) are used to select one of these 7 registers. The Widget      *
- * number field is then derived from the W_NUM field for synthesizing   *
- * a Crosstalk packet. The 5 bits of OFFSET are concatenated with       *
- * SysAD[28:0] to form Crosstalk[33:0]. The upper Crosstalk[47:34]      *
- * are padded with zeros. Although the maximum Crosstalk space          *
- * addressable by the Shub is thus the lower 16 GBytes per widget       *
- * (M-mode), however only <SUP >7</SUP>/<SUB >32nds</SUB> of this       *
- * space can be accessed.                                               *
- * For the N-mode (256 nodes, 4 GBytes/node), SysAD[30:28] (Big         *
- * Window number) are used to select one of these 7 registers. The      *
- * Widget number field is then derived from the W_NUM field for         *
- * synthesizing a Crosstalk packet. The 5 bits of OFFSET are            *
- * concatenated with SysAD[27:0] to form Crosstalk[33:0]. The IOSP      *
- * field is used as Crosstalk[47], and remainder of the Crosstalk       *
- * address bits (Crosstalk[46:34]) are always zero. While the maximum   *
- * Crosstalk space addressable by the Shub is thus the lower            *
- * 8-GBytes per widget (N-mode), only <SUP >7</SUP>/<SUB >32nds</SUB>   *
- * of this space can be accessed.                                       *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_itte5_u {
-	uint64_t	ii_itte5_regval;
-	struct  {
-		uint64_t	i_offset                  :	 5;
-		uint64_t       i_rsvd_1                  :      3;
-		uint64_t       i_w_num                   :      4;
-		uint64_t       i_iosp                    :      1;
-		uint64_t       i_rsvd                    :     51;
-	} ii_itte5_fld_s;
-} ii_itte5_u_t;
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There are seven instances of translation table entry   *
- * registers. Each register maps a Shub Big Window to a 48-bit          *
- * address on Crosstalk.                                                *
- * For M-mode (128 nodes, 8 GBytes/node), SysAD[31:29] (Big Window      *
- * number) are used to select one of these 7 registers. The Widget      *
- * number field is then derived from the W_NUM field for synthesizing   *
- * a Crosstalk packet. The 5 bits of OFFSET are concatenated with       *
- * SysAD[28:0] to form Crosstalk[33:0]. The upper Crosstalk[47:34]      *
- * are padded with zeros. Although the maximum Crosstalk space          *
- * addressable by the Shub is thus the lower 16 GBytes per widget       *
- * (M-mode), however only <SUP >7</SUP>/<SUB >32nds</SUB> of this       *
- * space can be accessed.                                               *
- * For the N-mode (256 nodes, 4 GBytes/node), SysAD[30:28] (Big         *
- * Window number) are used to select one of these 7 registers. The      *
- * Widget number field is then derived from the W_NUM field for         *
- * synthesizing a Crosstalk packet. The 5 bits of OFFSET are            *
- * concatenated with SysAD[27:0] to form Crosstalk[33:0]. The IOSP      *
- * field is used as Crosstalk[47], and remainder of the Crosstalk       *
- * address bits (Crosstalk[46:34]) are always zero. While the maximum   *
- * Crosstalk space addressable by the Shub is thus the lower            *
- * 8-GBytes per widget (N-mode), only <SUP >7</SUP>/<SUB >32nds</SUB>   *
- * of this space can be accessed.                                       *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_itte6_u {
-	uint64_t	ii_itte6_regval;
-	struct  {
-		uint64_t	i_offset                  :	 5;
-		uint64_t       i_rsvd_1                  :      3;
-		uint64_t       i_w_num                   :      4;
-		uint64_t       i_iosp                    :      1;
-		uint64_t       i_rsvd                    :     51;
-	} ii_itte6_fld_s;
-} ii_itte6_u_t;
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There are seven instances of translation table entry   *
- * registers. Each register maps a Shub Big Window to a 48-bit          *
- * address on Crosstalk.                                                *
- * For M-mode (128 nodes, 8 GBytes/node), SysAD[31:29] (Big Window      *
- * number) are used to select one of these 7 registers. The Widget      *
- * number field is then derived from the W_NUM field for synthesizing   *
- * a Crosstalk packet. The 5 bits of OFFSET are concatenated with       *
- * SysAD[28:0] to form Crosstalk[33:0]. The upper Crosstalk[47:34]      *
- * are padded with zeros. Although the maximum Crosstalk space          *
- * addressable by the Shub is thus the lower 16 GBytes per widget       *
- * (M-mode), however only <SUP >7</SUP>/<SUB >32nds</SUB> of this       *
- * space can be accessed.                                               *
- * For the N-mode (256 nodes, 4 GBytes/node), SysAD[30:28] (Big         *
- * Window number) are used to select one of these 7 registers. The      *
- * Widget number field is then derived from the W_NUM field for         *
- * synthesizing a Crosstalk packet. The 5 bits of OFFSET are            *
- * concatenated with SysAD[27:0] to form Crosstalk[33:0]. The IOSP      *
- * field is used as Crosstalk[47], and remainder of the Crosstalk       *
- * address bits (Crosstalk[46:34]) are always zero. While the maximum   *
- * Crosstalk space addressable by the SHub is thus the lower            *
- * 8-GBytes per widget (N-mode), only <SUP >7</SUP>/<SUB >32nds</SUB>   *
- * of this space can be accessed.                                       *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_itte7_u {
-	uint64_t	ii_itte7_regval;
-	struct  {
-		uint64_t	i_offset                  :	 5;
-		uint64_t	i_rsvd_1		  :	 3;
-		uint64_t       i_w_num                   :      4;
-		uint64_t       i_iosp                    :      1;
-		uint64_t       i_rsvd                    :     51;
-	} ii_itte7_fld_s;
-} ii_itte7_u_t;
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There are 9 instances of this register, one per        *
- * actual widget in this implementation of SHub and Crossbow.           *
- * Note: Crossbow only has ports for Widgets 8 through F, widget 0      *
- * refers to Crossbow's internal space.                                 *
- * This register contains the state elements per widget that are        *
- * necessary to manage the PIO flow control on Crosstalk and on the     *
- * Router Network. See the PIO Flow Control chapter for a complete      *
- * description of this register                                         *
- * The SPUR_WR bit requires some explanation. When this register is     *
- * written, the new value of the C field is captured in an internal     *
- * register so the hardware can remember what the programmer wrote      *
- * into the credit counter. The SPUR_WR bit sets whenever the C field   *
- * increments above this stored value, which indicates that there       *
- * have been more responses received than requests sent. The SPUR_WR    *
- * bit cannot be cleared until a value is written to the IPRBx          *
- * register; the write will correct the C field and capture its new     *
- * value in the internal register. Even if IECLR[E_PRB_x] is set, the   *
- * SPUR_WR bit will persist if IPRBx hasn't yet been written.           *
- * .                                                                    *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_iprb0_u {
-	uint64_t	ii_iprb0_regval;
-	struct  {
-		uint64_t	i_c                       :	 8;
-		uint64_t	i_na			  :	14;
-		uint64_t       i_rsvd_2                  :      2;
-		uint64_t	i_nb			  :	14;
-		uint64_t	i_rsvd_1		  :	 2;
-		uint64_t	i_m			  :	 2;
-		uint64_t	i_f			  :	 1;
-		uint64_t	i_of_cnt		  :	 5;
-		uint64_t	i_error			  :	 1;
-		uint64_t	i_rd_to			  :	 1;
-		uint64_t	i_spur_wr		  :	 1;
-		uint64_t	i_spur_rd		  :	 1;
-		uint64_t	i_rsvd			  :	11;
-		uint64_t	i_mult_err		  :	 1;
-	} ii_iprb0_fld_s;
-} ii_iprb0_u_t;
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There are 9 instances of this register, one per        *
- * actual widget in this implementation of SHub and Crossbow.           *
- * Note: Crossbow only has ports for Widgets 8 through F, widget 0      *
- * refers to Crossbow's internal space.                                 *
- * This register contains the state elements per widget that are        *
- * necessary to manage the PIO flow control on Crosstalk and on the     *
- * Router Network. See the PIO Flow Control chapter for a complete      *
- * description of this register                                         *
- * The SPUR_WR bit requires some explanation. When this register is     *
- * written, the new value of the C field is captured in an internal     *
- * register so the hardware can remember what the programmer wrote      *
- * into the credit counter. The SPUR_WR bit sets whenever the C field   *
- * increments above this stored value, which indicates that there       *
- * have been more responses received than requests sent. The SPUR_WR    *
- * bit cannot be cleared until a value is written to the IPRBx          *
- * register; the write will correct the C field and capture its new     *
- * value in the internal register. Even if IECLR[E_PRB_x] is set, the   *
- * SPUR_WR bit will persist if IPRBx hasn't yet been written.           *
- * .                                                                    *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_iprb8_u {
-	uint64_t	ii_iprb8_regval;
-	struct  {
-		uint64_t	i_c                       :	 8;
-		uint64_t	i_na			  :	14;
-		uint64_t       i_rsvd_2                  :      2;
-		uint64_t	i_nb			  :	14;
-		uint64_t       i_rsvd_1                  :      2;
-		uint64_t       i_m                       :      2;
-		uint64_t       i_f                       :      1;
-		uint64_t       i_of_cnt                  :      5;
-		uint64_t       i_error                   :      1;
-		uint64_t       i_rd_to                   :      1;
-		uint64_t       i_spur_wr                 :      1;
-		uint64_t	i_spur_rd		  :	 1;
-		uint64_t       i_rsvd                    :     11;
-		uint64_t	i_mult_err		  :	 1;
-	} ii_iprb8_fld_s;
-} ii_iprb8_u_t;
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There are 9 instances of this register, one per        *
- * actual widget in this implementation of SHub and Crossbow.           *
- * Note: Crossbow only has ports for Widgets 8 through F, widget 0      *
- * refers to Crossbow's internal space.                                 *
- * This register contains the state elements per widget that are        *
- * necessary to manage the PIO flow control on Crosstalk and on the     *
- * Router Network. See the PIO Flow Control chapter for a complete      *
- * description of this register                                         *
- * The SPUR_WR bit requires some explanation. When this register is     *
- * written, the new value of the C field is captured in an internal     *
- * register so the hardware can remember what the programmer wrote      *
- * into the credit counter. The SPUR_WR bit sets whenever the C field   *
- * increments above this stored value, which indicates that there       *
- * have been more responses received than requests sent. The SPUR_WR    *
- * bit cannot be cleared until a value is written to the IPRBx          *
- * register; the write will correct the C field and capture its new     *
- * value in the internal register. Even if IECLR[E_PRB_x] is set, the   *
- * SPUR_WR bit will persist if IPRBx hasn't yet been written.           *
- * .                                                                    *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_iprb9_u {
-	uint64_t	ii_iprb9_regval;
-	struct	{
-		uint64_t	i_c			  :	 8;
-		uint64_t	i_na			  :	14;
-		uint64_t	i_rsvd_2		  :	 2;
-		uint64_t	i_nb			  :	14;
-		uint64_t	i_rsvd_1		  :	 2;
-		uint64_t	i_m			  :	 2;
-		uint64_t	i_f			  :	 1;
-		uint64_t	i_of_cnt		  :	 5;
-		uint64_t	i_error			  :	 1;
-		uint64_t	i_rd_to			  :	 1;
-		uint64_t	i_spur_wr		  :	 1;
-		uint64_t	i_spur_rd		  :	 1;
-		uint64_t	i_rsvd			  :	11;
-		uint64_t	i_mult_err		  :	 1;
-	} ii_iprb9_fld_s;
-} ii_iprb9_u_t;
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There are 9 instances of this register, one per        *
- * actual widget in this implementation of SHub and Crossbow.        *
- * Note: Crossbow only has ports for Widgets 8 through F, widget 0      *
- * refers to Crossbow's internal space.                                 *
- * This register contains the state elements per widget that are        *
- * necessary to manage the PIO flow control on Crosstalk and on the     *
- * Router Network. See the PIO Flow Control chapter for a complete      *
- * description of this register                                         *
- * The SPUR_WR bit requires some explanation. When this register is     *
- * written, the new value of the C field is captured in an internal     *
- * register so the hardware can remember what the programmer wrote      *
- * into the credit counter. The SPUR_WR bit sets whenever the C field   *
- * increments above this stored value, which indicates that there       *
- * have been more responses received than requests sent. The SPUR_WR    *
- * bit cannot be cleared until a value is written to the IPRBx          *
- * register; the write will correct the C field and capture its new     *
- * value in the internal register. Even if IECLR[E_PRB_x] is set, the   *
- * SPUR_WR bit will persist if IPRBx hasn't yet been written.           *
- *                                                                      *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_iprba_u {
-	uint64_t	ii_iprba_regval;
-	struct  {
-		uint64_t	i_c                       :	 8;
-		uint64_t	i_na			  :	14;
-		uint64_t       i_rsvd_2                  :      2;
-		uint64_t	i_nb			  :	14;
-		uint64_t	i_rsvd_1		  :	 2;
-		uint64_t	i_m			  :	 2;
-		uint64_t	i_f			  :	 1;
-		uint64_t	i_of_cnt		  :	 5;
-		uint64_t	i_error			  :	 1;
-		uint64_t	i_rd_to			  :	 1;
-		uint64_t	i_spur_wr		  :	 1;
-		uint64_t	i_spur_rd		  :	 1;
-		uint64_t	i_rsvd			  :	11;
-		uint64_t	i_mult_err		  :	 1;
-	} ii_iprba_fld_s;
-} ii_iprba_u_t;
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There are 9 instances of this register, one per        *
- * actual widget in this implementation of SHub and Crossbow.           *
- * Note: Crossbow only has ports for Widgets 8 through F, widget 0      *
- * refers to Crossbow's internal space.                                 *
- * This register contains the state elements per widget that are        *
- * necessary to manage the PIO flow control on Crosstalk and on the     *
- * Router Network. See the PIO Flow Control chapter for a complete      *
- * description of this register                                         *
- * The SPUR_WR bit requires some explanation. When this register is     *
- * written, the new value of the C field is captured in an internal     *
- * register so the hardware can remember what the programmer wrote      *
- * into the credit counter. The SPUR_WR bit sets whenever the C field   *
- * increments above this stored value, which indicates that there       *
- * have been more responses received than requests sent. The SPUR_WR    *
- * bit cannot be cleared until a value is written to the IPRBx          *
- * register; the write will correct the C field and capture its new     *
- * value in the internal register. Even if IECLR[E_PRB_x] is set, the   *
- * SPUR_WR bit will persist if IPRBx hasn't yet been written.           *
- * .                                                                    *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_iprbb_u {
-	uint64_t	ii_iprbb_regval;
-	struct	{
-		uint64_t	i_c			  :	 8;
-		uint64_t	i_na			  :	14;
-		uint64_t	i_rsvd_2		  :	 2;
-		uint64_t	i_nb			  :	14;
-		uint64_t	i_rsvd_1		  :	 2;
-		uint64_t	i_m			  :	 2;
-		uint64_t	i_f			  :	 1;
-		uint64_t	i_of_cnt		  :	 5;
-		uint64_t	i_error			  :	 1;
-		uint64_t	i_rd_to			  :	 1;
-		uint64_t	i_spur_wr		  :	 1;
-		uint64_t	i_spur_rd		  :	 1;
-		uint64_t	i_rsvd			  :	11;
-		uint64_t	i_mult_err		  :	 1;
-	} ii_iprbb_fld_s;
-} ii_iprbb_u_t;
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There are 9 instances of this register, one per        *
- * actual widget in this implementation of SHub and Crossbow.           *
- * Note: Crossbow only has ports for Widgets 8 through F, widget 0      *
- * refers to Crossbow's internal space.                                 *
- * This register contains the state elements per widget that are        *
- * necessary to manage the PIO flow control on Crosstalk and on the     *
- * Router Network. See the PIO Flow Control chapter for a complete      *
- * description of this register                                         *
- * The SPUR_WR bit requires some explanation. When this register is     *
- * written, the new value of the C field is captured in an internal     *
- * register so the hardware can remember what the programmer wrote      *
- * into the credit counter. The SPUR_WR bit sets whenever the C field   *
- * increments above this stored value, which indicates that there       *
- * have been more responses received than requests sent. The SPUR_WR    *
- * bit cannot be cleared until a value is written to the IPRBx          *
- * register; the write will correct the C field and capture its new     *
- * value in the internal register. Even if IECLR[E_PRB_x] is set, the   *
- * SPUR_WR bit will persist if IPRBx hasn't yet been written.           *
- * .                                                                    *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_iprbc_u {
-	uint64_t	ii_iprbc_regval;
-	struct	{
-		uint64_t	i_c			  :	 8;
-		uint64_t	i_na			  :	14;
-		uint64_t	i_rsvd_2		  :	 2;
-		uint64_t	i_nb			  :	14;
-		uint64_t	i_rsvd_1		  :	 2;
-		uint64_t	i_m			  :	 2;
-		uint64_t	i_f			  :	 1;
-		uint64_t	i_of_cnt		  :	 5;
-		uint64_t	i_error			  :	 1;
-		uint64_t	i_rd_to			  :	 1;
-		uint64_t	i_spur_wr		  :	 1;
-		uint64_t	i_spur_rd		  :	 1;
-		uint64_t	i_rsvd			  :	11;
-		uint64_t	i_mult_err		  :	 1;
-	} ii_iprbc_fld_s;
-} ii_iprbc_u_t;
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There are 9 instances of this register, one per        *
- * actual widget in this implementation of SHub and Crossbow.           *
- * Note: Crossbow only has ports for Widgets 8 through F, widget 0      *
- * refers to Crossbow's internal space.                                 *
- * This register contains the state elements per widget that are        *
- * necessary to manage the PIO flow control on Crosstalk and on the     *
- * Router Network. See the PIO Flow Control chapter for a complete      *
- * description of this register                                         *
- * The SPUR_WR bit requires some explanation. When this register is     *
- * written, the new value of the C field is captured in an internal     *
- * register so the hardware can remember what the programmer wrote      *
- * into the credit counter. The SPUR_WR bit sets whenever the C field   *
- * increments above this stored value, which indicates that there       *
- * have been more responses received than requests sent. The SPUR_WR    *
- * bit cannot be cleared until a value is written to the IPRBx          *
- * register; the write will correct the C field and capture its new     *
- * value in the internal register. Even if IECLR[E_PRB_x] is set, the   *
- * SPUR_WR bit will persist if IPRBx hasn't yet been written.           *
- * .                                                                    *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_iprbd_u {
-	uint64_t	ii_iprbd_regval;
-	struct	{
-		uint64_t	i_c			  :	 8;
-		uint64_t	i_na			  :	14;
-		uint64_t	i_rsvd_2		  :	 2;
-		uint64_t	i_nb			  :	14;
-		uint64_t	i_rsvd_1		  :	 2;
-		uint64_t	i_m			  :	 2;
-		uint64_t	i_f			  :	 1;
-		uint64_t	i_of_cnt		  :	 5;
-		uint64_t	i_error			  :	 1;
-		uint64_t	i_rd_to			  :	 1;
-		uint64_t	i_spur_wr		  :	 1;
-		uint64_t	i_spur_rd		  :	 1;
-		uint64_t	i_rsvd			  :	11;
-		uint64_t	i_mult_err		  :	 1;
-	} ii_iprbd_fld_s;
-} ii_iprbd_u_t;
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There are 9 instances of this register, one per        *
- * actual widget in this implementation of SHub and Crossbow.           *
- * Note: Crossbow only has ports for Widgets 8 through F, widget 0      *
- * refers to Crossbow's internal space.                                 *
- * This register contains the state elements per widget that are        *
- * necessary to manage the PIO flow control on Crosstalk and on the     *
- * Router Network. See the PIO Flow Control chapter for a complete      *
- * description of this register                                         *
- * The SPUR_WR bit requires some explanation. When this register is     *
- * written, the new value of the C field is captured in an internal     *
- * register so the hardware can remember what the programmer wrote      *
- * into the credit counter. The SPUR_WR bit sets whenever the C field   *
- * increments above this stored value, which indicates that there       *
- * have been more responses received than requests sent. The SPUR_WR    *
- * bit cannot be cleared until a value is written to the IPRBx          *
- * register; the write will correct the C field and capture its new     *
- * value in the internal register. Even if IECLR[E_PRB_x] is set, the   *
- * SPUR_WR bit will persist if IPRBx hasn't yet been written.           *
- * .                                                                    *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_iprbe_u {
-	uint64_t	ii_iprbe_regval;
-	struct	{
-		uint64_t	i_c			  :	 8;
-		uint64_t	i_na			  :	14;
-		uint64_t	i_rsvd_2		  :	 2;
-		uint64_t	i_nb			  :	14;
-		uint64_t	i_rsvd_1		  :	 2;
-		uint64_t	i_m			  :	 2;
-		uint64_t	i_f			  :	 1;
-		uint64_t	i_of_cnt		  :	 5;
-		uint64_t	i_error			  :	 1;
-		uint64_t	i_rd_to			  :	 1;
-		uint64_t	i_spur_wr		  :	 1;
-		uint64_t	i_spur_rd		  :	 1;
-		uint64_t	i_rsvd			  :	11;
-		uint64_t	i_mult_err		  :	 1;
-	} ii_iprbe_fld_s;
-} ii_iprbe_u_t;
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There are 9 instances of this register, one per        *
- * actual widget in this implementation of Shub and Crossbow.           *
- * Note: Crossbow only has ports for Widgets 8 through F, widget 0      *
- * refers to Crossbow's internal space.                                 *
- * This register contains the state elements per widget that are        *
- * necessary to manage the PIO flow control on Crosstalk and on the     *
- * Router Network. See the PIO Flow Control chapter for a complete      *
- * description of this register                                         *
- * The SPUR_WR bit requires some explanation. When this register is     *
- * written, the new value of the C field is captured in an internal     *
- * register so the hardware can remember what the programmer wrote      *
- * into the credit counter. The SPUR_WR bit sets whenever the C field   *
- * increments above this stored value, which indicates that there       *
- * have been more responses received than requests sent. The SPUR_WR    *
- * bit cannot be cleared until a value is written to the IPRBx          *
- * register; the write will correct the C field and capture its new     *
- * value in the internal register. Even if IECLR[E_PRB_x] is set, the   *
- * SPUR_WR bit will persist if IPRBx hasn't yet been written.           *
- * .                                                                    *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_iprbf_u {
-        uint64_t       ii_iprbf_regval;
-        struct  {
-                uint64_t       i_c                       :      8;
-                uint64_t       i_na                      :     14;
-                uint64_t       i_rsvd_2                  :      2;
-                uint64_t       i_nb                      :     14;
-                uint64_t       i_rsvd_1                  :      2;
-                uint64_t       i_m                       :      2;
-                uint64_t       i_f                       :      1;
-                uint64_t       i_of_cnt                  :      5;
-                uint64_t       i_error                   :      1;
-                uint64_t       i_rd_to                   :      1;
-                uint64_t       i_spur_wr                 :      1;
-                uint64_t       i_spur_rd                 :      1;
-                uint64_t       i_rsvd                    :     11;
-                uint64_t       i_mult_err                :      1;
-        } ii_iprbe_fld_s;
-} ii_iprbf_u_t;
-
-
-/************************************************************************
- *                                                                      *
- *  This register specifies the timeout value to use for monitoring     *
- * Crosstalk credits which are used outbound to Crosstalk. An           *
- * internal counter called the Crosstalk Credit Timeout Counter         *
- * increments every 128 II clocks. The counter starts counting          *
- * anytime the credit count drops below a threshold, and resets to      *
- * zero (stops counting) anytime the credit count is at or above the    *
- * threshold. The threshold is 1 credit in direct connect mode and 2    *
- * in Crossbow connect mode. When the internal Crosstalk Credit         *
- * Timeout Counter reaches the value programmed in this register, a     *
- * Crosstalk Credit Timeout has occurred. The internal counter is not   *
- * readable from software, and stops counting at its maximum value,     *
- * so it cannot cause more than one interrupt.                          *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_ixcc_u {
-	uint64_t	ii_ixcc_regval;
-	struct  {
-		uint64_t	i_time_out                :	26;
-		uint64_t	i_rsvd			  :	38;
-	} ii_ixcc_fld_s;
-} ii_ixcc_u_t;
-
-
-/************************************************************************
- *                                                                      *
- * Description:  This register qualifies all the PIO and DMA            *
- * operations launched from widget 0 towards the SHub. In               *
- * addition, it also qualifies accesses by the BTE streams.             *
- * The bits in each field of this register are cleared by the SHub      *
- * upon detection of an error which requires widget 0 or the BTE        *
- * streams to be terminated. Whether or not widget x has access         *
- * rights to this SHub is determined by an AND of the device            *
- * enable bit in the appropriate field of this register and bit 0 in    *
- * the Wx_IAC field. The bits in this field are set by writing a 1 to   *
- * them. Incoming replies from Crosstalk are not subject to this        *
- * access control mechanism.                                            *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_imem_u {
-	uint64_t	ii_imem_regval;
-	struct  {
-		uint64_t	i_w0_esd                  :	 1;
-		uint64_t	i_rsvd_3		  :	 3;
-		uint64_t	i_b0_esd		  :	 1;
-		uint64_t	i_rsvd_2		  :	 3;
-		uint64_t	i_b1_esd		  :	 1;
-		uint64_t	i_rsvd_1		  :	 3;
-		uint64_t	i_clr_precise		  :	 1;
-		uint64_t       i_rsvd                    :     51;
-	} ii_imem_fld_s;
-} ii_imem_u_t;
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  This register specifies the timeout value to use for   *
- * monitoring Crosstalk tail flits coming into the Shub in the          *
- * TAIL_TO field. An internal counter associated with this register     *
- * is incremented every 128 II internal clocks (7 bits). The counter    *
- * starts counting anytime a header micropacket is received and stops   *
- * counting (and resets to zero) any time a micropacket with a Tail     *
- * bit is received. Once the counter reaches the threshold value        *
- * programmed in this register, it generates an interrupt to the        *
- * processor that is programmed into the IIDSR. The counter saturates   *
- * (does not roll over) at its maximum value, so it cannot cause        *
- * another interrupt until after it is cleared.                         *
- * The register also contains the Read Response Timeout values. The     *
- * Prescalar is 23 bits, and counts II clocks. An internal counter      *
- * increments on every II clock and when it reaches the value in the    *
- * Prescalar field, all IPRTE registers with their valid bits set       *
- * have their Read Response timers bumped. Whenever any of them match   *
- * the value in the RRSP_TO field, a Read Response Timeout has          *
- * occurred, and error handling occurs as described in the Error        *
- * Handling section of this document.                                   *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_ixtt_u {
-	uint64_t	ii_ixtt_regval;
-	struct  {
-		uint64_t	i_tail_to                 :	26;
-		uint64_t	i_rsvd_1		  :	 6;
-		uint64_t	i_rrsp_ps		  :	23;
-		uint64_t	i_rrsp_to		  :	 5;
-		uint64_t	i_rsvd			  :	 4;
-	} ii_ixtt_fld_s;
-} ii_ixtt_u_t;
-
-
-/************************************************************************
- *                                                                      *
- *  Writing a 1 to the fields of this register clears the appropriate   *
- * error bits in other areas of SHub. Note that when the                *
- * E_PRB_x bits are used to clear error bits in PRB registers,          *
- * SPUR_RD and SPUR_WR may persist, because they require additional     *
- * action to clear them. See the IPRBx and IXSS Register                *
- * specifications.                                                      *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_ieclr_u {
-	uint64_t	ii_ieclr_regval;
-	struct  {
-		uint64_t	i_e_prb_0                 :	 1;
-		uint64_t	i_rsvd			  :	 7;
-		uint64_t	i_e_prb_8		  :	 1;
-		uint64_t	i_e_prb_9		  :	 1;
-		uint64_t	i_e_prb_a		  :	 1;
-		uint64_t	i_e_prb_b		  :	 1;
-		uint64_t	i_e_prb_c		  :	 1;
-		uint64_t	i_e_prb_d		  :	 1;
-		uint64_t	i_e_prb_e		  :	 1;
-		uint64_t	i_e_prb_f		  :	 1;
-		uint64_t	i_e_crazy		  :	 1;
-		uint64_t	i_e_bte_0		  :	 1;
-		uint64_t	i_e_bte_1		  :	 1;
-		uint64_t	i_reserved_1		  :	10;
-		uint64_t	i_spur_rd_hdr		  :	 1;
-		uint64_t	i_cam_intr_to		  :	 1;
-		uint64_t	i_cam_overflow		  :	 1;
-		uint64_t	i_cam_read_miss		  :	 1;
-		uint64_t	i_ioq_rep_underflow	  :	 1;
-		uint64_t	i_ioq_req_underflow	  :	 1;
-		uint64_t	i_ioq_rep_overflow	  :	 1;
-		uint64_t	i_ioq_req_overflow	  :	 1;
-		uint64_t	i_iiq_rep_overflow	  :	 1;
-		uint64_t	i_iiq_req_overflow	  :	 1;
-		uint64_t	i_ii_xn_rep_cred_overflow :	 1;
-		uint64_t	i_ii_xn_req_cred_overflow :	 1;
-		uint64_t	i_ii_xn_invalid_cmd	  :	 1;
-		uint64_t	i_xn_ii_invalid_cmd	  :	 1;
-		uint64_t	i_reserved_2		  :	21;
-	} ii_ieclr_fld_s;
-} ii_ieclr_u_t;
-
-
-/************************************************************************
- *                                                                      *
- *  This register controls both BTEs. SOFT_RESET is intended for        *
- * recovery after an error. COUNT controls the total number of CRBs     *
- * that both BTEs (combined) can use, which affects total BTE           *
- * bandwidth.                                                           *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_ibcr_u {
-	uint64_t	ii_ibcr_regval;
-	struct  {
-		uint64_t	i_count                   :	 4;
-		uint64_t	i_rsvd_1		  :	 4;
-		uint64_t	i_soft_reset		  :	 1;
-		uint64_t	i_rsvd			  :	55;
-	} ii_ibcr_fld_s;
-} ii_ibcr_u_t;
-
-
-/************************************************************************
- *                                                                      *
- *  This register contains the header of a spurious read response       *
- * received from Crosstalk. A spurious read response is defined as a    *
- * read response received by II from a widget for which (1) the SIDN    *
- * has a value between 1 and 7, inclusive (II never sends requests to   *
- * these widgets (2) there is no valid IPRTE register which             *
- * corresponds to the TNUM, or (3) the widget indicated in SIDN is      *
- * not the same as the widget recorded in the IPRTE register            *
- * referenced by the TNUM. If this condition is true, and if the        *
- * IXSS[VALID] bit is clear, then the header of the spurious read       *
- * response is capture in IXSM and IXSS, and IXSS[VALID] is set. The    *
- * errant header is thereby captured, and no further spurious read      *
- * respones are captured until IXSS[VALID] is cleared by setting the    *
- * appropriate bit in IECLR.Everytime a spurious read response is       *
- * detected, the SPUR_RD bit of the PRB corresponding to the incoming   *
- * message's SIDN field is set. This always happens, regarless of       *
- * whether a header is captured. The programmer should check            *
- * IXSM[SIDN] to determine which widget sent the spurious response,     *
- * because there may be more than one SPUR_RD bit set in the PRB        *
- * registers. The widget indicated by IXSM[SIDN] was the first          *
- * spurious read response to be received since the last time            *
- * IXSS[VALID] was clear. The SPUR_RD bit of the corresponding PRB      *
- * will be set. Any SPUR_RD bits in any other PRB registers indicate    *
- * spurious messages from other widets which were detected after the    *
- * header was captured..                                                *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_ixsm_u {
-	uint64_t	ii_ixsm_regval;
-	struct  {
-		uint64_t	i_byte_en                 :	32;
-		uint64_t	i_reserved		  :	 1;
-		uint64_t	i_tag			  :	 3;
-		uint64_t	i_alt_pactyp		  :	 4;
-		uint64_t	i_bo			  :	 1;
-		uint64_t	i_error			  :	 1;
-		uint64_t	i_vbpm			  :	 1;
-		uint64_t	i_gbr			  :	 1;
-		uint64_t	i_ds			  :	 2;
-		uint64_t	i_ct			  :	 1;
-		uint64_t	i_tnum			  :	 5;
-		uint64_t	i_pactyp		  :	 4;
-		uint64_t	i_sidn			  :	 4;
-		uint64_t	i_didn			  :	 4;
-	} ii_ixsm_fld_s;
-} ii_ixsm_u_t;
-
-
-/************************************************************************
- *                                                                      *
- *  This register contains the sideband bits of a spurious read         *
- * response received from Crosstalk.                                    *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_ixss_u {
-	uint64_t	ii_ixss_regval;
-	struct  {
-		uint64_t	i_sideband                :	 8;
-		uint64_t	i_rsvd			  :	55;
-		uint64_t	i_valid			  :	 1;
-	} ii_ixss_fld_s;
-} ii_ixss_u_t;
-
-
-/************************************************************************
- *                                                                      *
- *  This register enables software to access the II LLP's test port.    *
- * Refer to the LLP 2.5 documentation for an explanation of the test    *
- * port. Software can write to this register to program the values      *
- * for the control fields (TestErrCapture, TestClear, TestFlit,         *
- * TestMask and TestSeed). Similarly, software can read from this       *
- * register to obtain the values of the test port's status outputs      *
- * (TestCBerr, TestValid and TestData).                                 *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_ilct_u {
-	uint64_t	ii_ilct_regval;
-	struct  {
-		uint64_t	i_test_seed               :	20;
-		uint64_t	i_test_mask               :	 8;
-		uint64_t	i_test_data               :	20;
-		uint64_t	i_test_valid              :	 1;
-		uint64_t	i_test_cberr              :	 1;
-		uint64_t	i_test_flit               :	 3;
-		uint64_t	i_test_clear              :	 1;
-		uint64_t	i_test_err_capture        :	 1;
-		uint64_t	i_rsvd                    :	 9;
-	} ii_ilct_fld_s;
-} ii_ilct_u_t;
-
-
-/************************************************************************
- *                                                                      *
- *  If the II detects an illegal incoming Duplonet packet (request or   *
- * reply) when VALID==0 in the IIEPH1 register, then it saves the       *
- * contents of the packet's header flit in the IIEPH1 and IIEPH2        *
- * registers, sets the VALID bit in IIEPH1, clears the OVERRUN bit,     *
- * and assigns a value to the ERR_TYPE field which indicates the        *
- * specific nature of the error. The II recognizes four different       *
- * types of errors: short request packets (ERR_TYPE==2), short reply    *
- * packets (ERR_TYPE==3), long request packets (ERR_TYPE==4) and long   *
- * reply packets (ERR_TYPE==5). The encodings for these types of        *
- * errors were chosen to be consistent with the same types of errors    *
- * indicated by the ERR_TYPE field in the LB_ERROR_HDR1 register (in    *
- * the LB unit). If the II detects an illegal incoming Duplonet         *
- * packet when VALID==1 in the IIEPH1 register, then it merely sets     *
- * the OVERRUN bit to indicate that a subsequent error has happened,    *
- * and does nothing further.                                            *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_iieph1_u {
-	uint64_t	ii_iieph1_regval;
-	struct	{
-		uint64_t	i_command		  :	 7;
-		uint64_t	i_rsvd_5		  :	 1;
-		uint64_t	i_suppl			  :	14;
-		uint64_t	i_rsvd_4		  :	 1;
-		uint64_t	i_source		  :	14;
-		uint64_t	i_rsvd_3		  :	 1;
-		uint64_t	i_err_type		  :	 4;
-		uint64_t	i_rsvd_2		  :	 4;
-		uint64_t	i_overrun		  :	 1;
-		uint64_t	i_rsvd_1		  :	 3;
-		uint64_t	i_valid			  :	 1;
-		uint64_t	i_rsvd			  :	13;
-	} ii_iieph1_fld_s;
-} ii_iieph1_u_t;
-
-
-/************************************************************************
- *                                                                      *
- *  This register holds the Address field from the header flit of an    *
- * incoming erroneous Duplonet packet, along with the tail bit which    *
- * accompanied this header flit. This register is essentially an        *
- * extension of IIEPH1. Two registers were necessary because the 64     *
- * bits available in only a single register were insufficient to        *
- * capture the entire header flit of an erroneous packet.               *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_iieph2_u {
-	uint64_t	ii_iieph2_regval;
-	struct  {
-		uint64_t	i_rsvd_0		  :	 3;
-		uint64_t	i_address                 :	47;
-		uint64_t	i_rsvd_1		  :	10;
-		uint64_t	i_tail			  :	 1;
-		uint64_t	i_rsvd			  :	 3;
-	} ii_iieph2_fld_s;
-} ii_iieph2_u_t;
-
-
-/******************************/
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register's value is a bit vector that guards access from SXBs  *
- * to local registers within the II as well as to external Crosstalk    *
- * widgets								*
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_islapr_u {
-	uint64_t	ii_islapr_regval;
-	struct  {
-		uint64_t	i_region		  :	64;
-	} ii_islapr_fld_s;
-} ii_islapr_u_t;
-
-
-/************************************************************************
- *                                                                      *
- *  A write to this register of the 56-bit value "Pup+Bun" will cause	*
- * the bit in the ISLAPR register corresponding to the region of the	*
- * requestor to be set (access allowed).				(
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_islapo_u {
-	uint64_t	ii_islapo_regval;
-	struct  {
-		uint64_t	i_io_sbx_ovrride	  :	56;
-		uint64_t	i_rsvd			  :	 8;
-	} ii_islapo_fld_s;
-} ii_islapo_u_t;
-
-/************************************************************************
- *                                                                      *
- *  Determines how long the wrapper will wait aftr an interrupt is	*
- * initially issued from the II before it times out the outstanding	*
- * interrupt and drops it from the interrupt queue.			* 
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_iwi_u {
-	uint64_t	ii_iwi_regval;
-	struct  {
-		uint64_t	i_prescale		  :	24;
-		uint64_t	i_rsvd			  :	 8;
-		uint64_t	i_timeout		  :	 8;
-		uint64_t	i_rsvd1			  :	 8;
-		uint64_t	i_intrpt_retry_period	  :	 8;
-		uint64_t	i_rsvd2			  :	 8;
-	} ii_iwi_fld_s;
-} ii_iwi_u_t;
-
-/************************************************************************
- *                                                                      *
- *  Log errors which have occurred in the II wrapper. The errors are	*
- * cleared by writing to the IECLR register.				* 
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_iwel_u {
-	uint64_t	ii_iwel_regval;
-	struct  {
-		uint64_t	i_intr_timed_out	  :	 1;
-		uint64_t	i_rsvd			  :	 7;
-		uint64_t	i_cam_overflow		  :	 1;
-		uint64_t	i_cam_read_miss		  :	 1;
-		uint64_t	i_rsvd1			  :	 2;
-		uint64_t	i_ioq_rep_underflow	  :	 1;
-		uint64_t	i_ioq_req_underflow	  :	 1;
-		uint64_t	i_ioq_rep_overflow	  :	 1;
-		uint64_t	i_ioq_req_overflow	  :	 1;
-		uint64_t	i_iiq_rep_overflow	  :	 1;
-		uint64_t	i_iiq_req_overflow	  :	 1;
-		uint64_t	i_rsvd2			  :	 6;
-		uint64_t	i_ii_xn_rep_cred_over_under:	 1;
-		uint64_t	i_ii_xn_req_cred_over_under:	 1;
-		uint64_t	i_rsvd3			  :	 6;
-		uint64_t	i_ii_xn_invalid_cmd	  :	 1;
-		uint64_t	i_xn_ii_invalid_cmd	  :	 1;
-		uint64_t	i_rsvd4			  :	30;
-	} ii_iwel_fld_s;
-} ii_iwel_u_t;
-
-/************************************************************************
- *                                                                      *
- *  Controls the II wrapper.						* 
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_iwc_u {
-	uint64_t	ii_iwc_regval;
-	struct  {
-		uint64_t	i_dma_byte_swap		  :	 1;
-		uint64_t	i_rsvd			  :	 3;
-		uint64_t	i_cam_read_lines_reset	  :	 1;
-		uint64_t	i_rsvd1			  :	 3;
-		uint64_t	i_ii_xn_cred_over_under_log:	 1;
-		uint64_t	i_rsvd2			  :	19;
-		uint64_t	i_xn_rep_iq_depth	  :	 5;
-		uint64_t	i_rsvd3			  :	 3;
-		uint64_t	i_xn_req_iq_depth	  :	 5;
-		uint64_t	i_rsvd4			  :	 3;
-		uint64_t	i_iiq_depth		  :	 6;
-		uint64_t	i_rsvd5			  :	12;
-		uint64_t	i_force_rep_cred	  :	 1;
-		uint64_t	i_force_req_cred	  :	 1;
-	} ii_iwc_fld_s;
-} ii_iwc_u_t;
-
-/************************************************************************
- *                                                                      *
- *  Status in the II wrapper.						* 
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_iws_u {
-	uint64_t	ii_iws_regval;
-	struct  {
-		uint64_t	i_xn_rep_iq_credits	  :	 5;
-		uint64_t	i_rsvd			  :	 3;
-		uint64_t	i_xn_req_iq_credits	  :	 5;
-		uint64_t	i_rsvd1			  :	51;
-	} ii_iws_fld_s;
-} ii_iws_u_t;
-
-/************************************************************************
- *                                                                      *
- *  Masks errors in the IWEL register.					*
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_iweim_u {
-	uint64_t	ii_iweim_regval;
-	struct  {
-		uint64_t	i_intr_timed_out	  :	 1;
-		uint64_t	i_rsvd			  :	 7;
-		uint64_t	i_cam_overflow		  :	 1;
-		uint64_t	i_cam_read_miss		  :	 1;
-		uint64_t	i_rsvd1			  :	 2;
-		uint64_t	i_ioq_rep_underflow	  :	 1;
-		uint64_t	i_ioq_req_underflow	  :	 1;
-		uint64_t	i_ioq_rep_overflow	  :	 1;
-		uint64_t	i_ioq_req_overflow	  :	 1;
-		uint64_t	i_iiq_rep_overflow	  :	 1;
-		uint64_t	i_iiq_req_overflow	  :	 1;
-		uint64_t	i_rsvd2			  :	 6;
-		uint64_t	i_ii_xn_rep_cred_overflow :	 1;
-		uint64_t	i_ii_xn_req_cred_overflow :	 1;
-		uint64_t	i_rsvd3			  :	 6;
-		uint64_t	i_ii_xn_invalid_cmd	  :	 1;
-		uint64_t	i_xn_ii_invalid_cmd	  :	 1;
-		uint64_t	i_rsvd4			  :	30;
-	} ii_iweim_fld_s;
-} ii_iweim_u_t;
-
-
-/************************************************************************
- *                                                                      *
- *  A write to this register causes a particular field in the           *
- * corresponding widget's PRB entry to be adjusted up or down by 1.     *
- * This counter should be used when recovering from error and reset     *
- * conditions. Note that software would be capable of causing           *
- * inadvertent overflow or underflow of these counters.                 *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_ipca_u {
-	uint64_t	ii_ipca_regval;
-	struct  {
-		uint64_t	i_wid                     :	 4;
-		uint64_t	i_adjust		  :	 1;
-		uint64_t	i_rsvd_1		  :	 3;
-		uint64_t	i_field			  :	 2;
-		uint64_t	i_rsvd			  :	54;
-	} ii_ipca_fld_s;
-} ii_ipca_u_t;
-
-
-/************************************************************************
- *                                                                      *
- *  There are 8 instances of this register. This register contains      *
- * the information that the II has to remember once it has launched a   *
- * PIO Read operation. The contents are used to form the correct        *
- * Router Network packet and direct the Crosstalk reply to the          *
- * appropriate processor.                                               *
- *                                                                      *
- ************************************************************************/
-
-
-typedef union ii_iprte0a_u {
-	uint64_t	ii_iprte0a_regval;
-	struct  {
-		uint64_t	i_rsvd_1                  :	54;
-		uint64_t	i_widget		  :	 4;
-		uint64_t	i_to_cnt		  :	 5;
-		uint64_t       i_vld                     :      1;
-	} ii_iprte0a_fld_s;
-} ii_iprte0a_u_t;
-
-
-/************************************************************************
- *                                                                      *
- *  There are 8 instances of this register. This register contains      *
- * the information that the II has to remember once it has launched a   *
- * PIO Read operation. The contents are used to form the correct        *
- * Router Network packet and direct the Crosstalk reply to the          *
- * appropriate processor.                                               *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_iprte1a_u {
-	uint64_t	ii_iprte1a_regval;
-	struct  {
-		uint64_t	i_rsvd_1                  :	54;
-		uint64_t	i_widget		  :	 4;
-		uint64_t	i_to_cnt		  :	 5;
-		uint64_t       i_vld                     :      1;
-	} ii_iprte1a_fld_s;
-} ii_iprte1a_u_t;
-
-
-/************************************************************************
- *                                                                      *
- *  There are 8 instances of this register. This register contains      *
- * the information that the II has to remember once it has launched a   *
- * PIO Read operation. The contents are used to form the correct        *
- * Router Network packet and direct the Crosstalk reply to the          *
- * appropriate processor.                                               *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_iprte2a_u {
-	uint64_t	ii_iprte2a_regval;
-	struct  {
-		uint64_t	i_rsvd_1                  :	54;
-		uint64_t	i_widget		  :	 4;
-		uint64_t	i_to_cnt		  :	 5;
-		uint64_t       i_vld                     :      1;
-	} ii_iprte2a_fld_s;
-} ii_iprte2a_u_t;
-
-
-/************************************************************************
- *                                                                      *
- *  There are 8 instances of this register. This register contains      *
- * the information that the II has to remember once it has launched a   *
- * PIO Read operation. The contents are used to form the correct        *
- * Router Network packet and direct the Crosstalk reply to the          *
- * appropriate processor.                                               *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_iprte3a_u {
-	uint64_t	ii_iprte3a_regval;
-	struct  {
-		uint64_t	i_rsvd_1                  :	54;
-		uint64_t	i_widget		  :	 4;
-		uint64_t	i_to_cnt		  :	 5;
-		uint64_t	i_vld			  :	 1;
-	} ii_iprte3a_fld_s;
-} ii_iprte3a_u_t;
-
-
-/************************************************************************
- *                                                                      *
- *  There are 8 instances of this register. This register contains      *
- * the information that the II has to remember once it has launched a   *
- * PIO Read operation. The contents are used to form the correct        *
- * Router Network packet and direct the Crosstalk reply to the          *
- * appropriate processor.                                               *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_iprte4a_u {
-	uint64_t	ii_iprte4a_regval;
-	struct	{
-		uint64_t	i_rsvd_1		  :	54;
-		uint64_t	i_widget		  :	 4;
-		uint64_t	i_to_cnt		  :	 5;
-		uint64_t	i_vld			  :	 1;
-	} ii_iprte4a_fld_s;
-} ii_iprte4a_u_t;
-
-
-/************************************************************************
- *                                                                      *
- *  There are 8 instances of this register. This register contains      *
- * the information that the II has to remember once it has launched a   *
- * PIO Read operation. The contents are used to form the correct        *
- * Router Network packet and direct the Crosstalk reply to the          *
- * appropriate processor.                                               *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_iprte5a_u {
-	uint64_t	ii_iprte5a_regval;
-	struct	{
-		uint64_t	i_rsvd_1		  :	54;
-		uint64_t	i_widget		  :	 4;
-		uint64_t	i_to_cnt		  :	 5;
-		uint64_t	i_vld			  :	 1;
-	} ii_iprte5a_fld_s;
-} ii_iprte5a_u_t;
-
-
-/************************************************************************
- *                                                                      *
- *  There are 8 instances of this register. This register contains      *
- * the information that the II has to remember once it has launched a   *
- * PIO Read operation. The contents are used to form the correct        *
- * Router Network packet and direct the Crosstalk reply to the          *
- * appropriate processor.                                               *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_iprte6a_u {
-	uint64_t	ii_iprte6a_regval;
-	struct	{
-		uint64_t	i_rsvd_1		  :	54;
-		uint64_t	i_widget		  :	 4;
-		uint64_t	i_to_cnt		  :	 5;
-		uint64_t	i_vld			  :	 1;
-	} ii_iprte6a_fld_s;
-} ii_iprte6a_u_t;
-
-
-/************************************************************************
- *                                                                      *
- *  There are 8 instances of this register. This register contains      *
- * the information that the II has to remember once it has launched a   *
- * PIO Read operation. The contents are used to form the correct        *
- * Router Network packet and direct the Crosstalk reply to the          *
- * appropriate processor.                                               *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_iprte7a_u {
-        uint64_t       ii_iprte7a_regval;
-        struct  {
-                uint64_t       i_rsvd_1                  :     54;
-                uint64_t       i_widget                  :      4;
-                uint64_t       i_to_cnt                  :      5;
-                uint64_t       i_vld                     :      1;
-        } ii_iprtea7_fld_s;
-} ii_iprte7a_u_t;
-
-
-
-/************************************************************************
- *                                                                      *
- *  There are 8 instances of this register. This register contains      *
- * the information that the II has to remember once it has launched a   *
- * PIO Read operation. The contents are used to form the correct        *
- * Router Network packet and direct the Crosstalk reply to the          *
- * appropriate processor.                                               *
- *                                                                      *
- ************************************************************************/
-
-
-typedef union ii_iprte0b_u {
-	uint64_t	ii_iprte0b_regval;
-	struct  {
-		uint64_t	i_rsvd_1                  :	 3;
-		uint64_t	i_address		  :	47;
-		uint64_t	i_init			  :	 3;
-		uint64_t       i_source                  :     11;
-	} ii_iprte0b_fld_s;
-} ii_iprte0b_u_t;
-
-
-/************************************************************************
- *                                                                      *
- *  There are 8 instances of this register. This register contains      *
- * the information that the II has to remember once it has launched a   *
- * PIO Read operation. The contents are used to form the correct        *
- * Router Network packet and direct the Crosstalk reply to the          *
- * appropriate processor.                                               *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_iprte1b_u {
-	uint64_t	ii_iprte1b_regval;
-	struct  {
-		uint64_t	i_rsvd_1                  :	 3;
-		uint64_t	i_address		  :	47;
-		uint64_t	i_init			  :	 3;
-		uint64_t       i_source                  :     11;
-	} ii_iprte1b_fld_s;
-} ii_iprte1b_u_t;
-
-
-/************************************************************************
- *                                                                      *
- *  There are 8 instances of this register. This register contains      *
- * the information that the II has to remember once it has launched a   *
- * PIO Read operation. The contents are used to form the correct        *
- * Router Network packet and direct the Crosstalk reply to the          *
- * appropriate processor.                                               *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_iprte2b_u {
-	uint64_t	ii_iprte2b_regval;
-	struct  {
-		uint64_t	i_rsvd_1                  :	 3;
-		uint64_t	i_address		  :	47;
-		uint64_t	i_init			  :	 3;
-		uint64_t       i_source                  :     11;
-	} ii_iprte2b_fld_s;
-} ii_iprte2b_u_t;
-
-
-/************************************************************************
- *                                                                      *
- *  There are 8 instances of this register. This register contains      *
- * the information that the II has to remember once it has launched a   *
- * PIO Read operation. The contents are used to form the correct        *
- * Router Network packet and direct the Crosstalk reply to the          *
- * appropriate processor.                                               *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_iprte3b_u {
-	uint64_t	ii_iprte3b_regval;
-	struct  {
-		uint64_t	i_rsvd_1                  :	 3;
-		uint64_t	i_address		  :	47;
-		uint64_t	i_init			  :	 3;
-		uint64_t       i_source                  :     11;
-	} ii_iprte3b_fld_s;
-} ii_iprte3b_u_t;
-
-
-/************************************************************************
- *                                                                      *
- *  There are 8 instances of this register. This register contains      *
- * the information that the II has to remember once it has launched a   *
- * PIO Read operation. The contents are used to form the correct        *
- * Router Network packet and direct the Crosstalk reply to the          *
- * appropriate processor.                                               *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_iprte4b_u {
-	uint64_t	ii_iprte4b_regval;
-	struct	{
-		uint64_t	i_rsvd_1                  :	 3;
-		uint64_t	i_address		  :	47;
-		uint64_t	i_init			  :	 3;
-		uint64_t       i_source                  :     11;
-	} ii_iprte4b_fld_s;
-} ii_iprte4b_u_t;
-
-
-/************************************************************************
- *                                                                      *
- *  There are 8 instances of this register. This register contains      *
- * the information that the II has to remember once it has launched a   *
- * PIO Read operation. The contents are used to form the correct        *
- * Router Network packet and direct the Crosstalk reply to the          *
- * appropriate processor.                                               *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_iprte5b_u {
-	uint64_t	ii_iprte5b_regval;
-	struct	{
-		uint64_t	i_rsvd_1                  :	 3;
-		uint64_t	i_address		  :	47;
-		uint64_t	i_init			  :	 3;
-		uint64_t       i_source                  :     11;
-	} ii_iprte5b_fld_s;
-} ii_iprte5b_u_t;
-
-
-/************************************************************************
- *                                                                      *
- *  There are 8 instances of this register. This register contains      *
- * the information that the II has to remember once it has launched a   *
- * PIO Read operation. The contents are used to form the correct        *
- * Router Network packet and direct the Crosstalk reply to the          *
- * appropriate processor.                                               *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_iprte6b_u {
-	uint64_t	ii_iprte6b_regval;
-	struct	{
-		uint64_t	i_rsvd_1                  :	 3;
-		uint64_t	i_address		  :	47;
-		uint64_t	i_init			  :	 3;
-		uint64_t       i_source                  :     11;
-
-	} ii_iprte6b_fld_s;
-} ii_iprte6b_u_t;
-
-
-/************************************************************************
- *                                                                      *
- *  There are 8 instances of this register. This register contains      *
- * the information that the II has to remember once it has launched a   *
- * PIO Read operation. The contents are used to form the correct        *
- * Router Network packet and direct the Crosstalk reply to the          *
- * appropriate processor.                                               *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_iprte7b_u {
-        uint64_t       ii_iprte7b_regval;
-        struct  {
-		uint64_t	i_rsvd_1                  :	 3;
-		uint64_t	i_address		  :	47;
-		uint64_t	i_init			  :	 3;
-		uint64_t       i_source                  :     11;
-        } ii_iprte7b_fld_s;
-} ii_iprte7b_u_t;
-
-
-/************************************************************************
- *                                                                      *
- * Description:  SHub II contains a feature which did not exist in      *
- * the Hub which automatically cleans up after a Read Response          *
- * timeout, including deallocation of the IPRTE and recovery of IBuf    *
- * space. The inclusion of this register in SHub is for backward        *
- * compatibility                                                        *
- * A write to this register causes an entry from the table of           *
- * outstanding PIO Read Requests to be freed and returned to the        *
- * stack of free entries. This register is used in handling the         *
- * timeout errors that result in a PIO Reply never returning from       *
- * Crosstalk.                                                           *
- * Note that this register does not affect the contents of the IPRTE    *
- * registers. The Valid bits in those registers have to be              *
- * specifically turned off by software.                                 *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_ipdr_u {
-	uint64_t	ii_ipdr_regval;
-	struct  {
-		uint64_t	i_te                      :	 3;
-		uint64_t	i_rsvd_1		  :	 1;
-		uint64_t	i_pnd			  :	 1;
-		uint64_t	i_init_rpcnt		  :	 1;
-		uint64_t	i_rsvd			  :	58;
-	} ii_ipdr_fld_s;
-} ii_ipdr_u_t;
-
-
-/************************************************************************
- *                                                                      *
- *  A write to this register causes a CRB entry to be returned to the   *
- * queue of free CRBs. The entry should have previously been cleared    *
- * (mark bit) via backdoor access to the pertinent CRB entry. This      *
- * register is used in the last step of handling the errors that are    *
- * captured and marked in CRB entries.  Briefly: 1) first error for     *
- * DMA write from a particular device, and first error for a            *
- * particular BTE stream, lead to a marked CRB entry, and processor     *
- * interrupt, 2) software reads the error information captured in the   *
- * CRB entry, and presumably takes some corrective action, 3)           *
- * software clears the mark bit, and finally 4) software writes to      *
- * the ICDR register to return the CRB entry to the list of free CRB    *
- * entries.                                                             *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_icdr_u {
-	uint64_t	ii_icdr_regval;
-	struct  {
-		uint64_t	i_crb_num                 :	 4;
-		uint64_t	i_pnd			  :	 1;
-		uint64_t       i_rsvd                    :     59;
-	} ii_icdr_fld_s;
-} ii_icdr_u_t;
-
-
-/************************************************************************
- *                                                                      *
- *  This register provides debug access to two FIFOs inside of II.      *
- * Both IOQ_MAX* fields of this register contain the instantaneous      *
- * depth (in units of the number of available entries) of the           *
- * associated IOQ FIFO.  A read of this register will return the        *
- * number of free entries on each FIFO at the time of the read.  So     *
- * when a FIFO is idle, the associated field contains the maximum       *
- * depth of the FIFO.  This register is writable for debug reasons      *
- * and is intended to be written with the maximum desired FIFO depth    *
- * while the FIFO is idle. Software must assure that II is idle when    *
- * this register is written. If there are any active entries in any     *
- * of these FIFOs when this register is written, the results are        *
- * undefined.                                                           *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_ifdr_u {
-	uint64_t	ii_ifdr_regval;
-	struct  {
-		uint64_t	i_ioq_max_rq              :	 7;
-		uint64_t	i_set_ioq_rq		  :	 1;
-		uint64_t	i_ioq_max_rp		  :	 7;
-		uint64_t	i_set_ioq_rp		  :	 1;
-		uint64_t	i_rsvd			  :	48;
-	} ii_ifdr_fld_s;
-} ii_ifdr_u_t;
-
-
-/************************************************************************
- *                                                                      *
- *  This register allows the II to become sluggish in removing          *
- * messages from its inbound queue (IIQ). This will cause messages to   *
- * back up in either virtual channel. Disabling the "molasses" mode     *
- * subsequently allows the II to be tested under stress. In the         *
- * sluggish ("Molasses") mode, the localized effects of congestion      *
- * can be observed.                                                     *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_iiap_u {
-        uint64_t       ii_iiap_regval;
-        struct  {
-                uint64_t       i_rq_mls                  :      6;
-		uint64_t	i_rsvd_1		  :	 2;
-		uint64_t	i_rp_mls		  :	 6;
-		uint64_t       i_rsvd                    :     50;
-        } ii_iiap_fld_s;
-} ii_iiap_u_t;
-
-
-/************************************************************************
- *                                                                      *
- *  This register allows several parameters of CRB operation to be      *
- * set. Note that writing to this register can have catastrophic side   *
- * effects, if the CRB is not quiescent, i.e. if the CRB is             *
- * processing protocol messages when the write occurs.                  *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_icmr_u {
-	uint64_t	ii_icmr_regval;
-	struct  {
-		uint64_t	i_sp_msg                  :	 1;
-		uint64_t	i_rd_hdr		  :	 1;
-		uint64_t	i_rsvd_4		  :	 2;
-		uint64_t	i_c_cnt			  :	 4;
-		uint64_t	i_rsvd_3		  :	 4;
-		uint64_t	i_clr_rqpd		  :	 1;
-		uint64_t	i_clr_rppd		  :	 1;
-		uint64_t	i_rsvd_2		  :	 2;
-		uint64_t	i_fc_cnt		  :	 4;
-		uint64_t	i_crb_vld		  :	15;
-		uint64_t	i_crb_mark		  :	15;
-		uint64_t	i_rsvd_1		  :	 2;
-		uint64_t	i_precise		  :	 1;
-		uint64_t	i_rsvd			  :	11;
-	} ii_icmr_fld_s;
-} ii_icmr_u_t;
-
-
-/************************************************************************
- *                                                                      *
- *  This register allows control of the table portion of the CRB        *
- * logic via software. Control operations from this register have       *
- * priority over all incoming Crosstalk or BTE requests.                *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_iccr_u {
-	uint64_t	ii_iccr_regval;
-	struct  {
-		uint64_t	i_crb_num                 :	 4;
-		uint64_t	i_rsvd_1		  :	 4;
-		uint64_t	i_cmd			  :	 8;
-		uint64_t	i_pending		  :	 1;
-		uint64_t	i_rsvd			  :	47;
-	} ii_iccr_fld_s;
-} ii_iccr_u_t;
-
-
-/************************************************************************
- *                                                                      *
- *  This register allows the maximum timeout value to be programmed.    *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_icto_u {
-	uint64_t	ii_icto_regval;
-	struct  {
-		uint64_t	i_timeout                 :	 8;
-		uint64_t	i_rsvd			  :	56;
-	} ii_icto_fld_s;
-} ii_icto_u_t;
-
-
-/************************************************************************
- *                                                                      *
- *  This register allows the timeout prescalar to be programmed. An     *
- * internal counter is associated with this register. When the          *
- * internal counter reaches the value of the PRESCALE field, the        *
- * timer registers in all valid CRBs are incremented (CRBx_D[TIMEOUT]   *
- * field). The internal counter resets to zero, and then continues      *
- * counting.                                                            *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_ictp_u {
-	uint64_t	ii_ictp_regval;
-	struct  {
-		uint64_t	i_prescale                :	24;
-		uint64_t	i_rsvd			  :	40;
-	} ii_ictp_fld_s;
-} ii_ictp_u_t;
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There are 15 CRB Entries (ICRB0 to ICRBE) that are     *
- * used for Crosstalk operations (both cacheline and partial            *
- * operations) or BTE/IO. Because the CRB entries are very wide, five   *
- * registers (_A to _E) are required to read and write each entry.      *
- * The CRB Entry registers can be conceptualized as rows and columns    *
- * (illustrated in the table above). Each row contains the 4            *
- * registers required for a single CRB Entry. The first doubleword      *
- * (column) for each entry is labeled A, and the second doubleword      *
- * (higher address) is labeled B, the third doubleword is labeled C,    *
- * the fourth doubleword is labeled D and the fifth doubleword is       *
- * labeled E. All CRB entries have their addresses on a quarter         *
- * cacheline aligned boundary.                   *
- * Upon reset, only the following fields are initialized: valid         *
- * (VLD), priority count, timeout, timeout valid, and context valid.    *
- * All other bits should be cleared by software before use (after       *
- * recovering any potential error state from before the reset).         *
- * The following four tables summarize the format for the four          *
- * registers that are used for each ICRB# Entry.                        *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_icrb0_a_u {
-	uint64_t	ii_icrb0_a_regval;
-	struct  {
-		uint64_t	ia_iow                    :	 1;
-		uint64_t	ia_vld			  :	 1;
-		uint64_t	ia_addr			  :	47;
-		uint64_t	ia_tnum			  :	 5;
-		uint64_t	ia_sidn			  :	 4;
-		uint64_t       ia_rsvd                   :      6;
-	} ii_icrb0_a_fld_s;
-} ii_icrb0_a_u_t;
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There are 15 CRB Entries (ICRB0 to ICRBE) that are     *
- * used for Crosstalk operations (both cacheline and partial            *
- * operations) or BTE/IO. Because the CRB entries are very wide, five   *
- * registers (_A to _E) are required to read and write each entry.      *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_icrb0_b_u {
-	uint64_t	ii_icrb0_b_regval;
-	struct	{
-		uint64_t	ib_xt_err		  :	 1;
-		uint64_t	ib_mark			  :	 1;
-		uint64_t	ib_ln_uce		  :	 1;
-		uint64_t	ib_errcode		  :	 3;
-		uint64_t	ib_error		  :	 1;
-		uint64_t	ib_stall__bte_1		  :	 1;
-		uint64_t	ib_stall__bte_0		  :	 1;
-		uint64_t	ib_stall__intr		  :	 1;
-		uint64_t	ib_stall_ib		  :	 1;
-		uint64_t	ib_intvn		  :	 1;
-		uint64_t	ib_wb			  :	 1;
-		uint64_t	ib_hold			  :	 1;
-		uint64_t	ib_ack			  :	 1;
-		uint64_t	ib_resp			  :	 1;
-		uint64_t	ib_ack_cnt		  :	11;
-		uint64_t	ib_rsvd			  :	 7;
-		uint64_t	ib_exc			  :	 5;
-		uint64_t	ib_init			  :	 3;
-		uint64_t	ib_imsg			  :	 8;
-		uint64_t	ib_imsgtype		  :	 2;
-		uint64_t	ib_use_old		  :	 1;
-		uint64_t	ib_rsvd_1		  :	11;
-	} ii_icrb0_b_fld_s;
-} ii_icrb0_b_u_t;
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There are 15 CRB Entries (ICRB0 to ICRBE) that are     *
- * used for Crosstalk operations (both cacheline and partial            *
- * operations) or BTE/IO. Because the CRB entries are very wide, five   *
- * registers (_A to _E) are required to read and write each entry.      *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_icrb0_c_u {
-	uint64_t	ii_icrb0_c_regval;
-	struct	{
-		uint64_t	ic_source		  :	15;
-		uint64_t	ic_size			  :	 2;
-		uint64_t	ic_ct			  :	 1;
-		uint64_t	ic_bte_num		  :	 1;
-		uint64_t	ic_gbr			  :	 1;
-		uint64_t	ic_resprqd		  :	 1;
-		uint64_t	ic_bo			  :	 1;
-		uint64_t	ic_suppl		  :	15;
-		uint64_t	ic_rsvd			  :	27;
-	} ii_icrb0_c_fld_s;
-} ii_icrb0_c_u_t;
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There are 15 CRB Entries (ICRB0 to ICRBE) that are     *
- * used for Crosstalk operations (both cacheline and partial            *
- * operations) or BTE/IO. Because the CRB entries are very wide, five   *
- * registers (_A to _E) are required to read and write each entry.      *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_icrb0_d_u {
-	uint64_t	ii_icrb0_d_regval;
-	struct  {
-		uint64_t	id_pa_be                  :	43;
-		uint64_t	id_bte_op		  :	 1;
-		uint64_t	id_pr_psc		  :	 4;
-		uint64_t	id_pr_cnt		  :	 4;
-		uint64_t	id_sleep		  :	 1;
-		uint64_t	id_rsvd			  :	11;
-	} ii_icrb0_d_fld_s;
-} ii_icrb0_d_u_t;
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There are 15 CRB Entries (ICRB0 to ICRBE) that are     *
- * used for Crosstalk operations (both cacheline and partial            *
- * operations) or BTE/IO. Because the CRB entries are very wide, five   *
- * registers (_A to _E) are required to read and write each entry.      *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_icrb0_e_u {
-	uint64_t	ii_icrb0_e_regval;
-	struct  {
-		uint64_t	ie_timeout                :	 8;
-		uint64_t	ie_context		  :	15;
-		uint64_t	ie_rsvd			  :	 1;
-		uint64_t	ie_tvld			  :	 1;
-		uint64_t	ie_cvld			  :	 1;
-		uint64_t	ie_rsvd_0		  :	38;
-	} ii_icrb0_e_fld_s;
-} ii_icrb0_e_u_t;
-
-
-/************************************************************************
- *                                                                      *
- *  This register contains the lower 64 bits of the header of the       *
- * spurious message captured by II. Valid when the SP_MSG bit in ICMR   *
- * register is set.                                                     *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_icsml_u {
-	uint64_t	ii_icsml_regval;
-	struct  {
-		uint64_t	i_tt_addr                 :	47;
-		uint64_t	i_newsuppl_ex		  :	14;
-		uint64_t	i_reserved		  :	 2;
-		uint64_t       i_overflow                :      1;
-	} ii_icsml_fld_s;
-} ii_icsml_u_t;
-
-
-/************************************************************************
- *                                                                      *
- *  This register contains the middle 64 bits of the header of the      *
- * spurious message captured by II. Valid when the SP_MSG bit in ICMR   *
- * register is set.                                                     *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_icsmm_u {
-	uint64_t	ii_icsmm_regval;
-	struct  {
-		uint64_t	i_tt_ack_cnt              :	11;
-		uint64_t	i_reserved		  :	53;
-	} ii_icsmm_fld_s;
-} ii_icsmm_u_t;
-
-
-/************************************************************************
- *                                                                      *
- *  This register contains the microscopic state, all the inputs to     *
- * the protocol table, captured with the spurious message. Valid when   *
- * the SP_MSG bit in the ICMR register is set.                          *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_icsmh_u {
-	uint64_t	ii_icsmh_regval;
-	struct  {
-		uint64_t	i_tt_vld                  :	 1;
-		uint64_t	i_xerr			  :	 1;
-		uint64_t	i_ft_cwact_o		  :	 1;
-		uint64_t	i_ft_wact_o		  :	 1;
-		uint64_t       i_ft_active_o             :      1;
-		uint64_t	i_sync			  :	 1;
-		uint64_t	i_mnusg			  :	 1;
-		uint64_t	i_mnusz			  :	 1;
-		uint64_t	i_plusz			  :	 1;
-		uint64_t	i_plusg			  :	 1;
-		uint64_t	i_tt_exc		  :	 5;
-		uint64_t	i_tt_wb			  :	 1;
-		uint64_t	i_tt_hold		  :	 1;
-		uint64_t	i_tt_ack		  :	 1;
-		uint64_t	i_tt_resp		  :	 1;
-		uint64_t	i_tt_intvn		  :	 1;
-		uint64_t	i_g_stall_bte1		  :	 1;
-		uint64_t	i_g_stall_bte0		  :	 1;
-		uint64_t	i_g_stall_il		  :	 1;
-		uint64_t	i_g_stall_ib		  :	 1;
-		uint64_t	i_tt_imsg		  :	 8;
-		uint64_t	i_tt_imsgtype		  :	 2;
-		uint64_t	i_tt_use_old		  :	 1;
-		uint64_t	i_tt_respreqd		  :	 1;
-		uint64_t	i_tt_bte_num		  :	 1;
-		uint64_t	i_cbn			  :	 1;
-		uint64_t	i_match			  :	 1;
-		uint64_t	i_rpcnt_lt_34		  :	 1;
-		uint64_t	i_rpcnt_ge_34		  :	 1;
-		uint64_t	i_rpcnt_lt_18		  :	 1;
-		uint64_t	i_rpcnt_ge_18		  :	 1;
-		uint64_t       i_rpcnt_lt_2              :      1;
-		uint64_t	i_rpcnt_ge_2		  :	 1;
-		uint64_t	i_rqcnt_lt_18		  :	 1;
-		uint64_t	i_rqcnt_ge_18		  :	 1;
-		uint64_t	i_rqcnt_lt_2		  :	 1;
-		uint64_t	i_rqcnt_ge_2		  :	 1;
-		uint64_t	i_tt_device		  :	 7;
-		uint64_t	i_tt_init		  :	 3;
-		uint64_t	i_reserved		  :	 5;
-	} ii_icsmh_fld_s;
-} ii_icsmh_u_t;
-
-
-/************************************************************************
- *                                                                      *
- *  The Shub DEBUG unit provides a 3-bit selection signal to the        *
- * II core and a 3-bit selection signal to the fsbclk domain in the II  *
- * wrapper.                                                             *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_idbss_u {
-	uint64_t	ii_idbss_regval;
-	struct  {
-		uint64_t	i_iioclk_core_submenu     :	 3;
-		uint64_t	i_rsvd			  :	 5;
-		uint64_t	i_fsbclk_wrapper_submenu  :	 3;
-		uint64_t	i_rsvd_1		  :	 5;
-		uint64_t	i_iioclk_menu		  :	 5;
-		uint64_t	i_rsvd_2		  :	43;
-	} ii_idbss_fld_s;
-} ii_idbss_u_t;
-
-
-/************************************************************************
- *                                                                      *
- * Description:  This register is used to set up the length for a       *
- * transfer and then to monitor the progress of that transfer. This     *
- * register needs to be initialized before a transfer is started. A     *
- * legitimate write to this register will set the Busy bit, clear the   *
- * Error bit, and initialize the length to the value desired.           *
- * While the transfer is in progress, hardware will decrement the       *
- * length field with each successful block that is copied. Once the     *
- * transfer completes, hardware will clear the Busy bit. The length     *
- * field will also contain the number of cache lines left to be         *
- * transferred.                                                         *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_ibls0_u {
-	uint64_t	ii_ibls0_regval;
-	struct	{
-		uint64_t	i_length		  :	16;
-		uint64_t	i_error			  :	 1;
-		uint64_t	i_rsvd_1		  :	 3;
-		uint64_t	i_busy			  :	 1;
-		uint64_t       i_rsvd                    :     43;
-	} ii_ibls0_fld_s;
-} ii_ibls0_u_t;
-
-
-/************************************************************************
- *                                                                      *
- *  This register should be loaded before a transfer is started. The    *
- * address to be loaded in bits 39:0 is the 40-bit TRex+ physical       *
- * address as described in Section 1.3, Figure2 and Figure3. Since      *
- * the bottom 7 bits of the address are always taken to be zero, BTE    *
- * transfers are always cacheline-aligned.                              *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_ibsa0_u {
-	uint64_t	ii_ibsa0_regval;
-	struct  {
-		uint64_t	i_rsvd_1                  :	 7;
-		uint64_t	i_addr			  :	42;
-		uint64_t       i_rsvd                    :     15;
-	} ii_ibsa0_fld_s;
-} ii_ibsa0_u_t;
-
-
-/************************************************************************
- *                                                                      *
- *  This register should be loaded before a transfer is started. The    *
- * address to be loaded in bits 39:0 is the 40-bit TRex+ physical       *
- * address as described in Section 1.3, Figure2 and Figure3. Since      *
- * the bottom 7 bits of the address are always taken to be zero, BTE    *
- * transfers are always cacheline-aligned.                              *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_ibda0_u {
-	uint64_t	ii_ibda0_regval;
-	struct  {
-		uint64_t	i_rsvd_1                  :	 7;
-		uint64_t	i_addr			  :	42;
-		uint64_t	i_rsvd			  :	15;
-	} ii_ibda0_fld_s;
-} ii_ibda0_u_t;
-
-
-/************************************************************************
- *                                                                      *
- *  Writing to this register sets up the attributes of the transfer     *
- * and initiates the transfer operation. Reading this register has      *
- * the side effect of terminating any transfer in progress. Note:       *
- * stopping a transfer midstream could have an adverse impact on the    *
- * other BTE. If a BTE stream has to be stopped (due to error           *
- * handling for example), both BTE streams should be stopped and        *
- * their transfers discarded.                                           *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_ibct0_u {
-	uint64_t	ii_ibct0_regval;
-	struct  {
-		uint64_t	i_zerofill                :	 1;
-		uint64_t	i_rsvd_2		  :	 3;
-		uint64_t	i_notify		  :	 1;
-		uint64_t	i_rsvd_1		  :	 3;
-		uint64_t       i_poison                  :      1;
-		uint64_t       i_rsvd                    :     55;
-	} ii_ibct0_fld_s;
-} ii_ibct0_u_t;
-
-
-/************************************************************************
- *                                                                      *
- *  This register contains the address to which the WINV is sent.       *
- * This address has to be cache line aligned.                           *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_ibna0_u {
-	uint64_t	ii_ibna0_regval;
-	struct  {
-		uint64_t	i_rsvd_1                  :	 7;
-		uint64_t	i_addr			  :	42;
-		uint64_t	i_rsvd			  :	15;
-	} ii_ibna0_fld_s;
-} ii_ibna0_u_t;
-
-
-/************************************************************************
- *                                                                      *
- *  This register contains the programmable level as well as the node   *
- * ID and PI unit of the processor to which the interrupt will be       *
- * sent.                                                                *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_ibia0_u {
-	uint64_t	ii_ibia0_regval;
-	struct  {
-		uint64_t	i_rsvd_2                   :	 1;
-		uint64_t	i_node_id		  :	11;
-		uint64_t	i_rsvd_1		  :	 4;
-		uint64_t	i_level			  :	 7;
-		uint64_t       i_rsvd                    :     41;
-	} ii_ibia0_fld_s;
-} ii_ibia0_u_t;
-
-
-/************************************************************************
- *                                                                      *
- * Description:  This register is used to set up the length for a       *
- * transfer and then to monitor the progress of that transfer. This     *
- * register needs to be initialized before a transfer is started. A     *
- * legitimate write to this register will set the Busy bit, clear the   *
- * Error bit, and initialize the length to the value desired.           *
- * While the transfer is in progress, hardware will decrement the       *
- * length field with each successful block that is copied. Once the     *
- * transfer completes, hardware will clear the Busy bit. The length     *
- * field will also contain the number of cache lines left to be         *
- * transferred.                                                         *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_ibls1_u {
-	uint64_t	ii_ibls1_regval;
-	struct  {
-		uint64_t	i_length                  :	16;
-		uint64_t	i_error			  :	 1;
-		uint64_t	i_rsvd_1		  :	 3;
-		uint64_t	i_busy			  :	 1;
-		uint64_t       i_rsvd                    :     43;
-	} ii_ibls1_fld_s;
-} ii_ibls1_u_t;
-
-
-/************************************************************************
- *                                                                      *
- *  This register should be loaded before a transfer is started. The    *
- * address to be loaded in bits 39:0 is the 40-bit TRex+ physical       *
- * address as described in Section 1.3, Figure2 and Figure3. Since      *
- * the bottom 7 bits of the address are always taken to be zero, BTE    *
- * transfers are always cacheline-aligned.                              *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_ibsa1_u {
-	uint64_t	ii_ibsa1_regval;
-	struct  {
-		uint64_t	i_rsvd_1                  :	 7;
-		uint64_t	i_addr			  :	33;
-		uint64_t	i_rsvd			  :	24;
-	} ii_ibsa1_fld_s;
-} ii_ibsa1_u_t;
-
-
-/************************************************************************
- *                                                                      *
- *  This register should be loaded before a transfer is started. The    *
- * address to be loaded in bits 39:0 is the 40-bit TRex+ physical       *
- * address as described in Section 1.3, Figure2 and Figure3. Since      *
- * the bottom 7 bits of the address are always taken to be zero, BTE    *
- * transfers are always cacheline-aligned.                              *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_ibda1_u {
-	uint64_t	ii_ibda1_regval;
-	struct  {
-		uint64_t	i_rsvd_1                  :	 7;
-		uint64_t	i_addr			  :	33;
-		uint64_t	i_rsvd			  :	24;
-	} ii_ibda1_fld_s;
-} ii_ibda1_u_t;
-
-
-/************************************************************************
- *                                                                      *
- *  Writing to this register sets up the attributes of the transfer     *
- * and initiates the transfer operation. Reading this register has      *
- * the side effect of terminating any transfer in progress. Note:       *
- * stopping a transfer midstream could have an adverse impact on the    *
- * other BTE. If a BTE stream has to be stopped (due to error           *
- * handling for example), both BTE streams should be stopped and        *
- * their transfers discarded.                                           *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_ibct1_u {
-	uint64_t	ii_ibct1_regval;
-	struct  {
-		uint64_t	i_zerofill                :	 1;
-		uint64_t	i_rsvd_2		  :	 3;
-		uint64_t	i_notify		  :	 1;
-		uint64_t	i_rsvd_1		  :	 3;
-		uint64_t	i_poison		  :	 1;
-		uint64_t	i_rsvd			  :	55;
-	} ii_ibct1_fld_s;
-} ii_ibct1_u_t;
-
-
-/************************************************************************
- *                                                                      *
- *  This register contains the address to which the WINV is sent.       *
- * This address has to be cache line aligned.                           *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_ibna1_u {
-	uint64_t	ii_ibna1_regval;
-	struct  {
-		uint64_t	i_rsvd_1                  :	 7;
-		uint64_t	i_addr			  :	33;
-		uint64_t       i_rsvd                    :     24;
-	} ii_ibna1_fld_s;
-} ii_ibna1_u_t;
-
-
-/************************************************************************
- *                                                                      *
- *  This register contains the programmable level as well as the node   *
- * ID and PI unit of the processor to which the interrupt will be       *
- * sent.                                                                *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_ibia1_u {
-	uint64_t	ii_ibia1_regval;
-	struct  {
-		uint64_t	i_pi_id                   :	 1;
-		uint64_t	i_node_id		  :	 8;
-		uint64_t	i_rsvd_1		  :	 7;
-		uint64_t	i_level			  :	 7;
-		uint64_t	i_rsvd			  :	41;
-	} ii_ibia1_fld_s;
-} ii_ibia1_u_t;
-
-
-/************************************************************************
- *                                                                      *
- *  This register defines the resources that feed information into      *
- * the two performance counters located in the IO Performance           *
- * Profiling Register. There are 17 different quantities that can be    *
- * measured. Given these 17 different options, the two performance      *
- * counters have 15 of them in common; menu selections 0 through 0xE    *
- * are identical for each performance counter. As for the other two     *
- * options, one is available from one performance counter and the       *
- * other is available from the other performance counter. Hence, the    *
- * II supports all 17*16=272 possible combinations of quantities to     *
- * measure.                                                             *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_ipcr_u {
-	uint64_t	ii_ipcr_regval;
-	struct  {
-		uint64_t	i_ippr0_c                 :	 4;
-		uint64_t	i_ippr1_c		  :	 4;
-		uint64_t	i_icct			  :	 8;
-		uint64_t       i_rsvd                    :     48;
-	} ii_ipcr_fld_s;
-} ii_ipcr_u_t;
-
-
-/************************************************************************
- *                                                                      *
- *                                                                      *
- *                                                                      *
- ************************************************************************/
-
-typedef union ii_ippr_u {
-	uint64_t	ii_ippr_regval;
-	struct  {
-		uint64_t	i_ippr0                   :	32;
-		uint64_t	i_ippr1			  :	32;
-	} ii_ippr_fld_s;
-} ii_ippr_u_t;
-
-
-
-/**************************************************************************
- *                                                                        *
- * The following defines which were not formed into structures are        *
- * probably indentical to another register, and the name of the           *
- * register is provided against each of these registers. This             *
- * information needs to be checked carefully                              *
- *                                                                        *
- *           IIO_ICRB1_A                IIO_ICRB0_A                       *
- *           IIO_ICRB1_B                IIO_ICRB0_B                       *
- *           IIO_ICRB1_C                IIO_ICRB0_C                       *
- *           IIO_ICRB1_D                IIO_ICRB0_D                       *
- *           IIO_ICRB1_E                IIO_ICRB0_E                       *
- *           IIO_ICRB2_A                IIO_ICRB0_A                       *
- *           IIO_ICRB2_B                IIO_ICRB0_B                       *
- *           IIO_ICRB2_C                IIO_ICRB0_C                       *
- *           IIO_ICRB2_D                IIO_ICRB0_D                       *
- *           IIO_ICRB2_E                IIO_ICRB0_E                       *
- *           IIO_ICRB3_A                IIO_ICRB0_A                       *
- *           IIO_ICRB3_B                IIO_ICRB0_B                       *
- *           IIO_ICRB3_C                IIO_ICRB0_C                       *
- *           IIO_ICRB3_D                IIO_ICRB0_D                       *
- *           IIO_ICRB3_E                IIO_ICRB0_E                       *
- *           IIO_ICRB4_A                IIO_ICRB0_A                       *
- *           IIO_ICRB4_B                IIO_ICRB0_B                       *
- *           IIO_ICRB4_C                IIO_ICRB0_C                       *
- *           IIO_ICRB4_D                IIO_ICRB0_D                       *
- *           IIO_ICRB4_E                IIO_ICRB0_E                       *
- *           IIO_ICRB5_A                IIO_ICRB0_A                       *
- *           IIO_ICRB5_B                IIO_ICRB0_B                       *
- *           IIO_ICRB5_C                IIO_ICRB0_C                       *
- *           IIO_ICRB5_D                IIO_ICRB0_D                       *
- *           IIO_ICRB5_E                IIO_ICRB0_E                       *
- *           IIO_ICRB6_A                IIO_ICRB0_A                       *
- *           IIO_ICRB6_B                IIO_ICRB0_B                       *
- *           IIO_ICRB6_C                IIO_ICRB0_C                       *
- *           IIO_ICRB6_D                IIO_ICRB0_D                       *
- *           IIO_ICRB6_E                IIO_ICRB0_E                       *
- *           IIO_ICRB7_A                IIO_ICRB0_A                       *
- *           IIO_ICRB7_B                IIO_ICRB0_B                       *
- *           IIO_ICRB7_C                IIO_ICRB0_C                       *
- *           IIO_ICRB7_D                IIO_ICRB0_D                       *
- *           IIO_ICRB7_E                IIO_ICRB0_E                       *
- *           IIO_ICRB8_A                IIO_ICRB0_A                       *
- *           IIO_ICRB8_B                IIO_ICRB0_B                       *
- *           IIO_ICRB8_C                IIO_ICRB0_C                       *
- *           IIO_ICRB8_D                IIO_ICRB0_D                       *
- *           IIO_ICRB8_E                IIO_ICRB0_E                       *
- *           IIO_ICRB9_A                IIO_ICRB0_A                       *
- *           IIO_ICRB9_B                IIO_ICRB0_B                       *
- *           IIO_ICRB9_C                IIO_ICRB0_C                       *
- *           IIO_ICRB9_D                IIO_ICRB0_D                       *
- *           IIO_ICRB9_E                IIO_ICRB0_E                       *
- *           IIO_ICRBA_A                IIO_ICRB0_A                       *
- *           IIO_ICRBA_B                IIO_ICRB0_B                       *
- *           IIO_ICRBA_C                IIO_ICRB0_C                       *
- *           IIO_ICRBA_D                IIO_ICRB0_D                       *
- *           IIO_ICRBA_E                IIO_ICRB0_E                       *
- *           IIO_ICRBB_A                IIO_ICRB0_A                       *
- *           IIO_ICRBB_B                IIO_ICRB0_B                       *
- *           IIO_ICRBB_C                IIO_ICRB0_C                       *
- *           IIO_ICRBB_D                IIO_ICRB0_D                       *
- *           IIO_ICRBB_E                IIO_ICRB0_E                       *
- *           IIO_ICRBC_A                IIO_ICRB0_A                       *
- *           IIO_ICRBC_B                IIO_ICRB0_B                       *
- *           IIO_ICRBC_C                IIO_ICRB0_C                       *
- *           IIO_ICRBC_D                IIO_ICRB0_D                       *
- *           IIO_ICRBC_E                IIO_ICRB0_E                       *
- *           IIO_ICRBD_A                IIO_ICRB0_A                       *
- *           IIO_ICRBD_B                IIO_ICRB0_B                       *
- *           IIO_ICRBD_C                IIO_ICRB0_C                       *
- *           IIO_ICRBD_D                IIO_ICRB0_D                       *
- *           IIO_ICRBD_E                IIO_ICRB0_E                       *
- *           IIO_ICRBE_A                IIO_ICRB0_A                       *
- *           IIO_ICRBE_B                IIO_ICRB0_B                       *
- *           IIO_ICRBE_C                IIO_ICRB0_C                       *
- *           IIO_ICRBE_D                IIO_ICRB0_D                       *
- *           IIO_ICRBE_E                IIO_ICRB0_E                       *
- *                                                                        *
- **************************************************************************/
-
-
-/*
- * Slightly friendlier names for some common registers.
- */
-#define IIO_WIDGET              IIO_WID      /* Widget identification */
-#define IIO_WIDGET_STAT         IIO_WSTAT    /* Widget status register */
-#define IIO_WIDGET_CTRL         IIO_WCR      /* Widget control register */
-#define IIO_PROTECT             IIO_ILAPR    /* IO interface protection */
-#define IIO_PROTECT_OVRRD       IIO_ILAPO    /* IO protect override */
-#define IIO_OUTWIDGET_ACCESS    IIO_IOWA     /* Outbound widget access */
-#define IIO_INWIDGET_ACCESS     IIO_IIWA     /* Inbound widget access */
-#define IIO_INDEV_ERR_MASK      IIO_IIDEM    /* Inbound device error mask */
-#define IIO_LLP_CSR             IIO_ILCSR    /* LLP control and status */
-#define IIO_LLP_LOG             IIO_ILLR     /* LLP log */
-#define IIO_XTALKCC_TOUT        IIO_IXCC     /* Xtalk credit count timeout*/
-#define IIO_XTALKTT_TOUT        IIO_IXTT     /* Xtalk tail timeout */
-#define IIO_IO_ERR_CLR          IIO_IECLR    /* IO error clear */
-#define IIO_IGFX_0 		IIO_IGFX0
-#define IIO_IGFX_1 		IIO_IGFX1
-#define IIO_IBCT_0		IIO_IBCT0
-#define IIO_IBCT_1		IIO_IBCT1
-#define IIO_IBLS_0		IIO_IBLS0
-#define IIO_IBLS_1		IIO_IBLS1
-#define IIO_IBSA_0		IIO_IBSA0
-#define IIO_IBSA_1		IIO_IBSA1
-#define IIO_IBDA_0		IIO_IBDA0
-#define IIO_IBDA_1		IIO_IBDA1
-#define IIO_IBNA_0		IIO_IBNA0
-#define IIO_IBNA_1		IIO_IBNA1
-#define IIO_IBIA_0		IIO_IBIA0
-#define IIO_IBIA_1		IIO_IBIA1
-#define IIO_IOPRB_0		IIO_IPRB0
-
-#define IIO_PRTE_A(_x)		(IIO_IPRTE0_A + (8 * (_x)))
-#define IIO_PRTE_B(_x)		(IIO_IPRTE0_B + (8 * (_x)))
-#define IIO_NUM_PRTES		8	/* Total number of PRB table entries */
-#define IIO_WIDPRTE_A(x)	IIO_PRTE_A(((x) - 8)) /* widget ID to its PRTE num */
-#define IIO_WIDPRTE_B(x)	IIO_PRTE_B(((x) - 8)) /* widget ID to its PRTE num */
-
-#define IIO_NUM_IPRBS 		(9) 
-
-#define IIO_LLP_CSR_IS_UP               0x00002000
-#define IIO_LLP_CSR_LLP_STAT_MASK       0x00003000
-#define IIO_LLP_CSR_LLP_STAT_SHFT       12
-
-#define IIO_LLP_CB_MAX  0xffff	/* in ILLR CB_CNT, Max Check Bit errors */
-#define IIO_LLP_SN_MAX  0xffff	/* in ILLR SN_CNT, Max Sequence Number errors */
-
-/* key to IIO_PROTECT_OVRRD */
-#define IIO_PROTECT_OVRRD_KEY   0x53474972756c6573ull   /* "SGIrules" */
-
-/* BTE register names */
-#define IIO_BTE_STAT_0          IIO_IBLS_0   /* Also BTE length/status 0 */
-#define IIO_BTE_SRC_0           IIO_IBSA_0   /* Also BTE source address  0 */
-#define IIO_BTE_DEST_0          IIO_IBDA_0   /* Also BTE dest. address 0 */
-#define IIO_BTE_CTRL_0          IIO_IBCT_0   /* Also BTE control/terminate 0 */
-#define IIO_BTE_NOTIFY_0        IIO_IBNA_0   /* Also BTE notification 0 */
-#define IIO_BTE_INT_0           IIO_IBIA_0   /* Also BTE interrupt 0 */
-#define IIO_BTE_OFF_0           0            /* Base offset from BTE 0 regs. */
-#define IIO_BTE_OFF_1   	(IIO_IBLS_1 - IIO_IBLS_0) /* Offset from base to BTE 1 */
-
-/* BTE register offsets from base */
-#define BTEOFF_STAT             0
-#define BTEOFF_SRC              (IIO_BTE_SRC_0 - IIO_BTE_STAT_0)
-#define BTEOFF_DEST             (IIO_BTE_DEST_0 - IIO_BTE_STAT_0)
-#define BTEOFF_CTRL             (IIO_BTE_CTRL_0 - IIO_BTE_STAT_0)
-#define BTEOFF_NOTIFY           (IIO_BTE_NOTIFY_0 - IIO_BTE_STAT_0)
-#define BTEOFF_INT              (IIO_BTE_INT_0 - IIO_BTE_STAT_0)
-
-
-/* names used in shub diags */
-#define IIO_BASE_BTE0   IIO_IBLS_0		
-#define IIO_BASE_BTE1   IIO_IBLS_1		
-
-/*
- * Macro which takes the widget number, and returns the
- * IO PRB address of that widget.
- * value _x is expected to be a widget number in the range
- * 0, 8 - 0xF
- */
-#define IIO_IOPRB(_x)   (IIO_IOPRB_0 + ( ( (_x) < HUB_WIDGET_ID_MIN ? \
-                        (_x) : \
-                        (_x) - (HUB_WIDGET_ID_MIN-1)) << 3) )
-
-
-/* GFX Flow Control Node/Widget Register */
-#define IIO_IGFX_W_NUM_BITS	4	/* size of widget num field */
-#define IIO_IGFX_W_NUM_MASK	((1<<IIO_IGFX_W_NUM_BITS)-1)
-#define IIO_IGFX_W_NUM_SHIFT	0
-#define IIO_IGFX_PI_NUM_BITS	1	/* size of PI num field */
-#define IIO_IGFX_PI_NUM_MASK	((1<<IIO_IGFX_PI_NUM_BITS)-1)
-#define IIO_IGFX_PI_NUM_SHIFT	4
-#define IIO_IGFX_N_NUM_BITS	8	/* size of node num field */
-#define IIO_IGFX_N_NUM_MASK	((1<<IIO_IGFX_N_NUM_BITS)-1)
-#define IIO_IGFX_N_NUM_SHIFT	5
-#define IIO_IGFX_P_NUM_BITS	1	/* size of processor num field */
-#define IIO_IGFX_P_NUM_MASK	((1<<IIO_IGFX_P_NUM_BITS)-1)
-#define IIO_IGFX_P_NUM_SHIFT	16
-#define IIO_IGFX_INIT(widget, pi, node, cpu)				(\
-	(((widget) & IIO_IGFX_W_NUM_MASK) << IIO_IGFX_W_NUM_SHIFT) |	 \
-	(((pi)     & IIO_IGFX_PI_NUM_MASK)<< IIO_IGFX_PI_NUM_SHIFT)|	 \
-	(((node)   & IIO_IGFX_N_NUM_MASK) << IIO_IGFX_N_NUM_SHIFT) |	 \
-	(((cpu)    & IIO_IGFX_P_NUM_MASK) << IIO_IGFX_P_NUM_SHIFT))
-
-
-/* Scratch registers (all bits available) */
-#define IIO_SCRATCH_REG0        IIO_ISCR0
-#define IIO_SCRATCH_REG1        IIO_ISCR1
-#define IIO_SCRATCH_MASK        0xffffffffffffffffUL
-
-#define IIO_SCRATCH_BIT0_0      0x0000000000000001UL
-#define IIO_SCRATCH_BIT0_1      0x0000000000000002UL
-#define IIO_SCRATCH_BIT0_2      0x0000000000000004UL
-#define IIO_SCRATCH_BIT0_3      0x0000000000000008UL
-#define IIO_SCRATCH_BIT0_4      0x0000000000000010UL
-#define IIO_SCRATCH_BIT0_5      0x0000000000000020UL
-#define IIO_SCRATCH_BIT0_6      0x0000000000000040UL
-#define IIO_SCRATCH_BIT0_7      0x0000000000000080UL
-#define IIO_SCRATCH_BIT0_8      0x0000000000000100UL
-#define IIO_SCRATCH_BIT0_9      0x0000000000000200UL
-#define IIO_SCRATCH_BIT0_A      0x0000000000000400UL
-
-#define IIO_SCRATCH_BIT1_0      0x0000000000000001UL
-#define IIO_SCRATCH_BIT1_1      0x0000000000000002UL
-/* IO Translation Table Entries */
-#define IIO_NUM_ITTES   7               /* ITTEs numbered 0..6 */
-                                        /* Hw manuals number them 1..7! */
-/*
- * IIO_IMEM Register fields.
- */
-#define IIO_IMEM_W0ESD  0x1UL             /* Widget 0 shut down due to error */
-#define IIO_IMEM_B0ESD  (1UL << 4)        /* BTE 0 shut down due to error */
-#define IIO_IMEM_B1ESD  (1UL << 8)        /* BTE 1 Shut down due to error */
-
-/*
- * As a permanent workaround for a bug in the PI side of the shub, we've
- * redefined big window 7 as small window 0.
- XXX does this still apply for SN1??
- */
-#define HUB_NUM_BIG_WINDOW      (IIO_NUM_ITTES - 1)
-
-/*
- * Use the top big window as a surrogate for the first small window
- */
-#define SWIN0_BIGWIN            HUB_NUM_BIG_WINDOW
-
-#define ILCSR_WARM_RESET        0x100
-
-/*
- * CRB manipulation macros
- *      The CRB macros are slightly complicated, since there are up to
- *      four registers associated with each CRB entry.
- */
-#define IIO_NUM_CRBS            15      /* Number of CRBs */
-#define IIO_NUM_PC_CRBS         4       /* Number of partial cache CRBs */
-#define IIO_ICRB_OFFSET         8
-#define IIO_ICRB_0              IIO_ICRB0_A
-#define IIO_ICRB_ADDR_SHFT	2	/* Shift to get proper address */
-/* XXX - This is now tuneable:
-        #define IIO_FIRST_PC_ENTRY 12
- */
-
-#define IIO_ICRB_A(_x)  ((u64)(IIO_ICRB_0 + (6 * IIO_ICRB_OFFSET * (_x))))
-#define IIO_ICRB_B(_x)  ((u64)((char *)IIO_ICRB_A(_x) + 1*IIO_ICRB_OFFSET))
-#define IIO_ICRB_C(_x)  ((u64)((char *)IIO_ICRB_A(_x) + 2*IIO_ICRB_OFFSET))
-#define IIO_ICRB_D(_x)  ((u64)((char *)IIO_ICRB_A(_x) + 3*IIO_ICRB_OFFSET))
-#define IIO_ICRB_E(_x)  ((u64)((char *)IIO_ICRB_A(_x) + 4*IIO_ICRB_OFFSET))
-
-#define TNUM_TO_WIDGET_DEV(_tnum)	(_tnum & 0x7)
-
-/*
- * values for "ecode" field
- */
-#define IIO_ICRB_ECODE_DERR     0       /* Directory error due to IIO access */
-#define IIO_ICRB_ECODE_PERR     1       /* Poison error on IO access */
-#define IIO_ICRB_ECODE_WERR     2       /* Write error by IIO access
-                                         * e.g. WINV to a Read only line. */
-#define IIO_ICRB_ECODE_AERR     3       /* Access error caused by IIO access */
-#define IIO_ICRB_ECODE_PWERR    4       /* Error on partial write       */
-#define IIO_ICRB_ECODE_PRERR    5       /* Error on partial read        */
-#define IIO_ICRB_ECODE_TOUT     6       /* CRB timeout before deallocating */
-#define IIO_ICRB_ECODE_XTERR    7       /* Incoming xtalk pkt had error bit */
-
-/*
- * Values for field imsgtype
- */
-#define IIO_ICRB_IMSGT_XTALK    0       /* Incoming Meessage from Xtalk */
-#define IIO_ICRB_IMSGT_BTE      1       /* Incoming message from BTE    */
-#define IIO_ICRB_IMSGT_SN1NET   2       /* Incoming message from SN1 net */
-#define IIO_ICRB_IMSGT_CRB      3       /* Incoming message from CRB ???  */
-
-/*
- * values for field initiator.
- */
-#define IIO_ICRB_INIT_XTALK     0       /* Message originated in xtalk  */
-#define IIO_ICRB_INIT_BTE0      0x1     /* Message originated in BTE 0  */
-#define IIO_ICRB_INIT_SN1NET    0x2     /* Message originated in SN1net */
-#define IIO_ICRB_INIT_CRB       0x3     /* Message originated in CRB ?  */
-#define IIO_ICRB_INIT_BTE1      0x5     /* MEssage originated in BTE 1  */
-
-/*
- * Number of credits Hub widget has while sending req/response to
- * xbow.
- * Value of 3 is required by Xbow 1.1
- * We may be able to increase this to 4 with Xbow 1.2.
- */
-#define       HUBII_XBOW_CREDIT       3
-#define       HUBII_XBOW_REV2_CREDIT  4
-
-/*
- * Number of credits that xtalk devices should use when communicating
- * with a SHub (depth of SHub's queue).
- */
-#define HUB_CREDIT 4
-
-/*
- * Some IIO_PRB fields
- */
-#define IIO_PRB_MULTI_ERR	(1LL << 63)
-#define IIO_PRB_SPUR_RD		(1LL << 51)
-#define IIO_PRB_SPUR_WR		(1LL << 50)
-#define IIO_PRB_RD_TO		(1LL << 49)
-#define IIO_PRB_ERROR		(1LL << 48)
-
-/*************************************************************************
-
- Some of the IIO field masks and shifts are defined here.
- This is in order to maintain compatibility in SN0 and SN1 code
- 
-**************************************************************************/
-
-/*
- * ICMR register fields
- * (Note: the IIO_ICMR_P_CNT and IIO_ICMR_PC_VLD from Hub are not
- * present in SHub)
- */
-
-#define IIO_ICMR_CRB_VLD_SHFT   20
-#define IIO_ICMR_CRB_VLD_MASK   (0x7fffUL << IIO_ICMR_CRB_VLD_SHFT)
-
-#define IIO_ICMR_FC_CNT_SHFT    16
-#define IIO_ICMR_FC_CNT_MASK    (0xf << IIO_ICMR_FC_CNT_SHFT)
-
-#define IIO_ICMR_C_CNT_SHFT     4
-#define IIO_ICMR_C_CNT_MASK     (0xf << IIO_ICMR_C_CNT_SHFT)
-
-#define IIO_ICMR_PRECISE        (1UL << 52)
-#define IIO_ICMR_CLR_RPPD       (1UL << 13)
-#define IIO_ICMR_CLR_RQPD       (1UL << 12)
-
-/*
- * IIO PIO Deallocation register field masks : (IIO_IPDR)
- XXX present but not needed in bedrock?  See the manual.
- */
-#define IIO_IPDR_PND    (1 << 4)
-
-/*
- * IIO CRB deallocation register field masks: (IIO_ICDR)
- */
-#define IIO_ICDR_PND    (1 << 4)
-
-/* 
- * IO BTE Length/Status (IIO_IBLS) register bit field definitions
- */
-#define IBLS_BUSY		(0x1UL << 20)
-#define IBLS_ERROR_SHFT		16
-#define IBLS_ERROR		(0x1UL << IBLS_ERROR_SHFT)
-#define IBLS_LENGTH_MASK	0xffff
-
-/*
- * IO BTE Control/Terminate register (IBCT) register bit field definitions
- */
-#define IBCT_POISON		(0x1UL << 8)
-#define IBCT_NOTIFY		(0x1UL << 4)
-#define IBCT_ZFIL_MODE		(0x1UL << 0)
-
-/*
- * IIO Incoming Error Packet Header (IIO_IIEPH1/IIO_IIEPH2)
- */
-#define IIEPH1_VALID		(1UL << 44)
-#define IIEPH1_OVERRUN		(1UL << 40)
-#define IIEPH1_ERR_TYPE_SHFT	32
-#define IIEPH1_ERR_TYPE_MASK	0xf
-#define IIEPH1_SOURCE_SHFT	20
-#define IIEPH1_SOURCE_MASK	11
-#define IIEPH1_SUPPL_SHFT	8
-#define IIEPH1_SUPPL_MASK	11
-#define IIEPH1_CMD_SHFT		0
-#define IIEPH1_CMD_MASK		7
-
-#define IIEPH2_TAIL		(1UL << 40)
-#define IIEPH2_ADDRESS_SHFT	0
-#define IIEPH2_ADDRESS_MASK	38
-
-#define IIEPH1_ERR_SHORT_REQ	2
-#define IIEPH1_ERR_SHORT_REPLY	3
-#define IIEPH1_ERR_LONG_REQ	4
-#define IIEPH1_ERR_LONG_REPLY	5
-
-/*
- * IO Error Clear register bit field definitions
- */
-#define IECLR_PI1_FWD_INT	(1UL << 31)  /* clear PI1_FORWARD_INT in iidsr */
-#define IECLR_PI0_FWD_INT	(1UL << 30)  /* clear PI0_FORWARD_INT in iidsr */
-#define IECLR_SPUR_RD_HDR	(1UL << 29)  /* clear valid bit in ixss reg */
-#define IECLR_BTE1		(1UL << 18)  /* clear bte error 1 */
-#define IECLR_BTE0		(1UL << 17)  /* clear bte error 0 */
-#define IECLR_CRAZY		(1UL << 16)  /* clear crazy bit in wstat reg */
-#define IECLR_PRB_F		(1UL << 15)  /* clear err bit in PRB_F reg */
-#define IECLR_PRB_E		(1UL << 14)  /* clear err bit in PRB_E reg */
-#define IECLR_PRB_D		(1UL << 13)  /* clear err bit in PRB_D reg */
-#define IECLR_PRB_C		(1UL << 12)  /* clear err bit in PRB_C reg */
-#define IECLR_PRB_B		(1UL << 11)  /* clear err bit in PRB_B reg */
-#define IECLR_PRB_A		(1UL << 10)  /* clear err bit in PRB_A reg */
-#define IECLR_PRB_9		(1UL << 9)   /* clear err bit in PRB_9 reg */
-#define IECLR_PRB_8		(1UL << 8)   /* clear err bit in PRB_8 reg */
-#define IECLR_PRB_0		(1UL << 0)   /* clear err bit in PRB_0 reg */
-
-/*
- * IIO CRB control register Fields: IIO_ICCR 
- */
-#define	IIO_ICCR_PENDING	(0x10000)
-#define	IIO_ICCR_CMD_MASK	(0xFF)
-#define	IIO_ICCR_CMD_SHFT	(7)
-#define	IIO_ICCR_CMD_NOP	(0x0)	/* No Op */
-#define	IIO_ICCR_CMD_WAKE	(0x100) /* Reactivate CRB entry and process */
-#define	IIO_ICCR_CMD_TIMEOUT	(0x200)	/* Make CRB timeout & mark invalid */
-#define	IIO_ICCR_CMD_EJECT	(0x400)	/* Contents of entry written to memory 
-					 * via a WB
-					 */
-#define	IIO_ICCR_CMD_FLUSH	(0x800)
-
-/*
- *
- * CRB Register description.
- *
- * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING
- * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING
- * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING
- * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING
- * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING
- *
- * Many of the fields in CRB are status bits used by hardware
- * for implementation of the protocol. It's very dangerous to
- * mess around with the CRB registers.
- *
- * It's OK to read the CRB registers and try to make sense out of the
- * fields in CRB.
- *
- * Updating CRB requires all activities in Hub IIO to be quiesced.
- * otherwise, a write to CRB could corrupt other CRB entries.
- * CRBs are here only as a back door peek to shub IIO's status.
- * Quiescing implies  no dmas no PIOs
- * either directly from the cpu or from sn0net.
- * this is not something that can be done easily. So, AVOID updating
- * CRBs.
- */
-
-/*
- * Easy access macros for CRBs, all 5 registers (A-E)
- */
-typedef ii_icrb0_a_u_t icrba_t;
-#define a_sidn          ii_icrb0_a_fld_s.ia_sidn
-#define a_tnum          ii_icrb0_a_fld_s.ia_tnum
-#define a_addr          ii_icrb0_a_fld_s.ia_addr
-#define a_valid         ii_icrb0_a_fld_s.ia_vld
-#define a_iow           ii_icrb0_a_fld_s.ia_iow
-#define a_regvalue	ii_icrb0_a_regval
-
-typedef ii_icrb0_b_u_t icrbb_t;
-#define b_use_old       ii_icrb0_b_fld_s.ib_use_old
-#define b_imsgtype      ii_icrb0_b_fld_s.ib_imsgtype
-#define b_imsg          ii_icrb0_b_fld_s.ib_imsg
-#define b_initiator     ii_icrb0_b_fld_s.ib_init
-#define b_exc           ii_icrb0_b_fld_s.ib_exc
-#define b_ackcnt        ii_icrb0_b_fld_s.ib_ack_cnt
-#define b_resp          ii_icrb0_b_fld_s.ib_resp
-#define b_ack           ii_icrb0_b_fld_s.ib_ack
-#define b_hold          ii_icrb0_b_fld_s.ib_hold
-#define b_wb            ii_icrb0_b_fld_s.ib_wb
-#define b_intvn         ii_icrb0_b_fld_s.ib_intvn
-#define b_stall_ib      ii_icrb0_b_fld_s.ib_stall_ib
-#define b_stall_int     ii_icrb0_b_fld_s.ib_stall__intr
-#define b_stall_bte_0   ii_icrb0_b_fld_s.ib_stall__bte_0
-#define b_stall_bte_1   ii_icrb0_b_fld_s.ib_stall__bte_1
-#define b_error         ii_icrb0_b_fld_s.ib_error
-#define b_ecode         ii_icrb0_b_fld_s.ib_errcode
-#define b_lnetuce       ii_icrb0_b_fld_s.ib_ln_uce
-#define b_mark          ii_icrb0_b_fld_s.ib_mark
-#define b_xerr          ii_icrb0_b_fld_s.ib_xt_err
-#define b_regvalue	ii_icrb0_b_regval
-
-typedef ii_icrb0_c_u_t icrbc_t;
-#define c_suppl         ii_icrb0_c_fld_s.ic_suppl
-#define c_barrop        ii_icrb0_c_fld_s.ic_bo
-#define c_doresp        ii_icrb0_c_fld_s.ic_resprqd
-#define c_gbr           ii_icrb0_c_fld_s.ic_gbr
-#define c_btenum        ii_icrb0_c_fld_s.ic_bte_num
-#define c_cohtrans      ii_icrb0_c_fld_s.ic_ct
-#define c_xtsize        ii_icrb0_c_fld_s.ic_size
-#define c_source        ii_icrb0_c_fld_s.ic_source
-#define c_regvalue	ii_icrb0_c_regval
-
-
-typedef ii_icrb0_d_u_t icrbd_t;
-#define d_sleep         ii_icrb0_d_fld_s.id_sleep
-#define d_pricnt        ii_icrb0_d_fld_s.id_pr_cnt
-#define d_pripsc        ii_icrb0_d_fld_s.id_pr_psc
-#define d_bteop         ii_icrb0_d_fld_s.id_bte_op
-#define d_bteaddr       ii_icrb0_d_fld_s.id_pa_be /* ic_pa_be fld has 2 names*/
-#define d_benable       ii_icrb0_d_fld_s.id_pa_be /* ic_pa_be fld has 2 names*/
-#define d_regvalue	ii_icrb0_d_regval
-
-typedef ii_icrb0_e_u_t icrbe_t;
-#define icrbe_ctxtvld   ii_icrb0_e_fld_s.ie_cvld
-#define icrbe_toutvld   ii_icrb0_e_fld_s.ie_tvld
-#define icrbe_context   ii_icrb0_e_fld_s.ie_context
-#define icrbe_timeout   ii_icrb0_e_fld_s.ie_timeout
-#define e_regvalue	ii_icrb0_e_regval
-
-
-/* Number of widgets supported by shub */
-#define HUB_NUM_WIDGET          9
-#define HUB_WIDGET_ID_MIN       0x8
-#define HUB_WIDGET_ID_MAX       0xf
-
-#define HUB_WIDGET_PART_NUM     0xc120
-#define MAX_HUBS_PER_XBOW       2
-
-/* A few more #defines for backwards compatibility */
-#define iprb_t          ii_iprb0_u_t
-#define iprb_regval     ii_iprb0_regval
-#define iprb_mult_err	ii_iprb0_fld_s.i_mult_err
-#define iprb_spur_rd	ii_iprb0_fld_s.i_spur_rd
-#define iprb_spur_wr	ii_iprb0_fld_s.i_spur_wr
-#define iprb_rd_to	ii_iprb0_fld_s.i_rd_to
-#define iprb_ovflow     ii_iprb0_fld_s.i_of_cnt
-#define iprb_error      ii_iprb0_fld_s.i_error
-#define iprb_ff         ii_iprb0_fld_s.i_f
-#define iprb_mode       ii_iprb0_fld_s.i_m
-#define iprb_bnakctr    ii_iprb0_fld_s.i_nb
-#define iprb_anakctr    ii_iprb0_fld_s.i_na
-#define iprb_xtalkctr   ii_iprb0_fld_s.i_c
-
-#define LNK_STAT_WORKING        0x2		/* LLP is working */
-
-#define IIO_WSTAT_ECRAZY        (1ULL << 32)    /* Hub gone crazy */
-#define IIO_WSTAT_TXRETRY       (1ULL << 9)     /* Hub Tx Retry timeout */
-#define IIO_WSTAT_TXRETRY_MASK  (0x7F)   /* should be 0xFF?? */
-#define IIO_WSTAT_TXRETRY_SHFT  (16)
-#define IIO_WSTAT_TXRETRY_CNT(w)        (((w) >> IIO_WSTAT_TXRETRY_SHFT) & \
-                                          IIO_WSTAT_TXRETRY_MASK)
-
-/* Number of II perf. counters we can multiplex at once */
-
-#define IO_PERF_SETS	32
-
-/* Bit for the widget in inbound access register */
-#define IIO_IIWA_WIDGET(_w)     ((uint64_t)(1ULL << _w))
-/* Bit for the widget in outbound access register */
-#define IIO_IOWA_WIDGET(_w)     ((uint64_t)(1ULL << _w))
-
-/* NOTE: The following define assumes that we are going to get
- * widget numbers from 8 thru F and the device numbers within
- * widget from 0 thru 7.
- */
-#define IIO_IIDEM_WIDGETDEV_MASK(w, d)  ((uint64_t)(1ULL << (8 * ((w) - 8) + (d))))
-
-/* IO Interrupt Destination Register */
-#define IIO_IIDSR_SENT_SHIFT    28
-#define IIO_IIDSR_SENT_MASK     0x30000000
-#define IIO_IIDSR_ENB_SHIFT     24
-#define IIO_IIDSR_ENB_MASK      0x01000000
-#define IIO_IIDSR_NODE_SHIFT    9
-#define IIO_IIDSR_NODE_MASK     0x000ff700
-#define IIO_IIDSR_PI_ID_SHIFT   8
-#define IIO_IIDSR_PI_ID_MASK    0x00000100
-#define IIO_IIDSR_LVL_SHIFT     0
-#define IIO_IIDSR_LVL_MASK      0x000000ff
-
-/* Xtalk timeout threshhold register (IIO_IXTT) */
-#define IXTT_RRSP_TO_SHFT	55	   /* read response timeout */
-#define IXTT_RRSP_TO_MASK	(0x1FULL << IXTT_RRSP_TO_SHFT)
-#define IXTT_RRSP_PS_SHFT	32	   /* read responsed TO prescalar */
-#define IXTT_RRSP_PS_MASK	(0x7FFFFFULL << IXTT_RRSP_PS_SHFT)
-#define IXTT_TAIL_TO_SHFT	0	   /* tail timeout counter threshold */
-#define IXTT_TAIL_TO_MASK	(0x3FFFFFFULL << IXTT_TAIL_TO_SHFT)
-
-/*
- * The IO LLP control status register and widget control register
- */
-
-typedef union hubii_wcr_u {
-        uint64_t      wcr_reg_value;
-        struct {
-	  uint64_t	wcr_widget_id:   4,     /* LLP crossbar credit */
-			wcr_tag_mode:	 1,	/* Tag mode */
-			wcr_rsvd1:	 8,	/* Reserved */
-			wcr_xbar_crd:	 3,	/* LLP crossbar credit */
-			wcr_f_bad_pkt:	 1,	/* Force bad llp pkt enable */
-			wcr_dir_con:	 1,	/* widget direct connect */
-			wcr_e_thresh:	 5,	/* elasticity threshold */
-			wcr_rsvd:	41;	/* unused */
-        } wcr_fields_s;
-} hubii_wcr_t;
-
-#define iwcr_dir_con    wcr_fields_s.wcr_dir_con
-
-/* The structures below are defined to extract and modify the ii
-performance registers */
-
-/* io_perf_sel allows the caller to specify what tests will be
-   performed */
-
-typedef union io_perf_sel {
-        uint64_t perf_sel_reg;
-        struct {
-               uint64_t	perf_ippr0 :  4,
-				perf_ippr1 :  4,
-				perf_icct  :  8,
-				perf_rsvd  : 48;
-        } perf_sel_bits;
-} io_perf_sel_t;
-
-/* io_perf_cnt is to extract the count from the shub registers. Due to
-   hardware problems there is only one counter, not two. */
-
-typedef union io_perf_cnt {
-        uint64_t      perf_cnt;
-        struct {
-               uint64_t	perf_cnt   : 20,
-				perf_rsvd2 : 12,
-				perf_rsvd1 : 32;
-        } perf_cnt_bits;
-
-} io_perf_cnt_t;
-
-typedef union iprte_a {
-	uint64_t	entry;
-	struct {
-		uint64_t	i_rsvd_1                  :	 3;
-		uint64_t	i_addr			  :	38;
-		uint64_t	i_init			  :	 3;
-		uint64_t	i_source		  :	 8;
-		uint64_t	i_rsvd			  :	 2;
-		uint64_t	i_widget		  :	 4;
-		uint64_t	i_to_cnt		  :	 5;
-		uint64_t       i_vld                     :      1;
-	} iprte_fields;
-} iprte_a_t;
-
-#endif /* _ASM_IA64_SN_SHUBIO_H */
-
diff -Nru a/arch/ia64/sn/kernel/bte.c b/arch/ia64/sn/kernel/bte.c
--- a/arch/ia64/sn/kernel/bte.c	2005-03-01 23:38:58 -08:00
+++ b/arch/ia64/sn/kernel/bte.c	2005-03-01 23:38:58 -08:00
@@ -13,7 +13,7 @@
 #include <asm/sn/arch.h>
 #include <asm/sn/sn_cpuid.h>
 #include <asm/sn/pda.h>
-#include "shubio.h"
+#include <asm/sn/shubio.h>
 #include <asm/nodedata.h>
 #include <asm/delay.h>
 
diff -Nru a/arch/ia64/sn/kernel/bte_error.c b/arch/ia64/sn/kernel/bte_error.c
--- a/arch/ia64/sn/kernel/bte_error.c	2005-03-01 23:38:53 -08:00
+++ b/arch/ia64/sn/kernel/bte_error.c	2005-03-01 23:38:53 -08:00
@@ -10,11 +10,12 @@
 #include <asm/sn/sn_sal.h>
 #include "ioerror.h"
 #include <asm/sn/addrs.h>
-#include "shubio.h"
+#include <asm/sn/shubio.h>
 #include <asm/sn/geo.h>
 #include "xtalk/xwidgetdev.h"
 #include "xtalk/hubdev.h"
 #include <asm/sn/bte.h>
+#include <asm/param.h>
 
 /*
  * Bte error handling is done in two parts.  The first captures
@@ -47,6 +48,7 @@
 	ii_icrb0_d_u_t icrbd;	/* II CRB Register D */
 	ii_ibcr_u_t ibcr;
 	ii_icmr_u_t icmr;
+	ii_ieclr_u_t ieclr;
 
 	BTE_PRINTK(("bte_error_handler(%p) - %d\n", err_nodepda,
 		    smp_processor_id()));
@@ -131,6 +133,14 @@
 	imem.ii_imem_fld_s.i_b0_esd = imem.ii_imem_fld_s.i_b1_esd = 1;
 	REMOTE_HUB_S(nasid, IIO_IMEM, imem.ii_imem_regval);
 
+	/* Clear BTE0/1 error bits */
+	ieclr.ii_ieclr_regval = 0;
+	if (err_nodepda->bte_if[0].bh_error != BTE_SUCCESS)
+		ieclr.ii_ieclr_fld_s.i_e_bte_0 = 1;
+	if (err_nodepda->bte_if[1].bh_error != BTE_SUCCESS)
+		ieclr.ii_ieclr_fld_s.i_e_bte_1 = 1;
+	REMOTE_HUB_S(nasid, IIO_IECLR, ieclr.ii_ieclr_regval);
+
 	/* Reinitialize both BTE state machines. */
 	ibcr.ii_ibcr_regval = REMOTE_HUB_L(nasid, IIO_IBCR);
 	ibcr.ii_ibcr_fld_s.i_soft_reset = 1;
@@ -152,7 +162,7 @@
 		err_nodepda->bte_if[i].cleanup_active = 0;
 		BTE_PRINTK(("eh:%p:%d Unlocked %d\n", err_nodepda,
 			    smp_processor_id(), i));
-		spin_unlock(&pda->cpu_bte_if[i]->spinlock);
+		spin_unlock(&err_nodepda->bte_if[i].spinlock);
 	}
 
 	del_timer(recovery_timer);
diff -Nru a/arch/ia64/sn/kernel/huberror.c b/arch/ia64/sn/kernel/huberror.c
--- a/arch/ia64/sn/kernel/huberror.c	2005-03-01 23:39:08 -08:00
+++ b/arch/ia64/sn/kernel/huberror.c	2005-03-01 23:39:08 -08:00
@@ -13,7 +13,7 @@
 #include <asm/sn/sn_sal.h>
 #include "ioerror.h"
 #include <asm/sn/addrs.h>
-#include "shubio.h"
+#include <asm/sn/shubio.h>
 #include <asm/sn/geo.h>
 #include "xtalk/xwidgetdev.h"
 #include "xtalk/hubdev.h"
diff -Nru a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c
--- a/arch/ia64/sn/kernel/io_init.c	2005-03-01 23:39:08 -08:00
+++ b/arch/ia64/sn/kernel/io_init.c	2005-03-01 23:39:08 -08:00
@@ -7,6 +7,7 @@
  */
 
 #include <linux/bootmem.h>
+#include <linux/nodemask.h>
 #include <asm/sn/types.h>
 #include <asm/sn/sn_sal.h>
 #include <asm/sn/addrs.h>
@@ -201,7 +202,7 @@
 	struct pci_dev *host_pci_dev;
 	int status = 0;
 
-	SN_PCIDEV_INFO(dev) = kmalloc(sizeof(struct pcidev_info), GFP_KERNEL);
+	dev->sysdata = kmalloc(sizeof(struct pcidev_info), GFP_KERNEL);
 	if (SN_PCIDEV_INFO(dev) <= 0)
 		BUG();		/* Cannot afford to run out of memory */
 	memset(SN_PCIDEV_INFO(dev), 0, sizeof(struct pcidev_info));
@@ -309,8 +310,8 @@
 	 * after this point.
 	 */
 
-	PCI_CONTROLLER(bus) = controller;
-	SN_PCIBUS_BUSSOFT(bus) = provider_soft;
+	bus->sysdata = controller;
+	PCI_CONTROLLER(bus)->platform_data = provider_soft;
 
 	nasid = NASID_GET(SN_PCIBUS_BUSSOFT(bus)->bs_base);
 	cnode = nasid_to_cnodeid(nasid);
@@ -382,7 +383,7 @@
 
 	struct hubdev_info *hubdev_info;
 
-	if (node >= numnodes)	/* Headless/memless IO nodes */
+	if (node >= num_online_nodes())	/* Headless/memless IO nodes */
 		hubdev_info =
 		    (struct hubdev_info *)alloc_bootmem_node(NODE_DATA(0),
 							     sizeof(struct
diff -Nru a/arch/ia64/sn/kernel/iomv.c b/arch/ia64/sn/kernel/iomv.c
--- a/arch/ia64/sn/kernel/iomv.c	2005-03-01 23:39:07 -08:00
+++ b/arch/ia64/sn/kernel/iomv.c	2005-03-01 23:39:07 -08:00
@@ -32,7 +32,6 @@
 		return ((void *)(port | __IA64_UNCACHED_OFFSET));
 	} else {
 		/* but the simulator uses them... */
-		unsigned long io_base;
 		unsigned long addr;
 
 		/*
@@ -40,14 +39,9 @@
 		 * for accessing registers in bedrock local block
 		 * (so we don't do port&0xfff)
 		 */
-		if ((port >= 0x1f0 && port <= 0x1f7) ||
-		    port == 0x3f6 || port == 0x3f7) {
-			io_base = (0xc000000fcc000000UL |
-				   ((unsigned long)get_nasid() << 38));
-			addr = io_base | ((port >> 2) << 12) | (port & 0xfff);
-		} else {
-			addr = __ia64_get_io_port_base() | ((port >> 2) << 2);
-		}
+		addr = (is_shub2() ? 0xc00000028c000000UL : 0xc0000087cc000000UL) | ((port >> 2) << 12);
+		if ((port >= 0x1f0 && port <= 0x1f7) || port == 0x3f6 || port == 0x3f7)
+			addr |= port;
 		return (void *)addr;
 	}
 }
@@ -66,9 +60,10 @@
  */
 void __sn_mmiowb(void)
 {
-	while ((((volatile unsigned long)(*pda->pio_write_status_addr)) &
-		SH_PIO_WRITE_STATUS_0_PENDING_WRITE_COUNT_MASK) !=
-	       SH_PIO_WRITE_STATUS_0_PENDING_WRITE_COUNT_MASK)
+	volatile unsigned long *adr = pda->pio_write_status_addr;
+	unsigned long val = pda->pio_write_status_val;
+
+	while ((*adr & SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_MASK) != val)
 		cpu_relax();
 }
 
diff -Nru a/arch/ia64/sn/kernel/irq.c b/arch/ia64/sn/kernel/irq.c
--- a/arch/ia64/sn/kernel/irq.c	2005-03-01 23:38:53 -08:00
+++ b/arch/ia64/sn/kernel/irq.c	2005-03-01 23:38:53 -08:00
@@ -183,7 +183,9 @@
 
 			sn_irq_info = sn_irq_info->irq_next;
 
+#ifdef CONFIG_SMP
 			set_irq_affinity_info((irq & 0xff), cpuphys, 0);
+#endif
 		} else {
 			break;	/* snp_affinity failed the intr_alloc */
 		}
@@ -202,16 +204,6 @@
 	sn_set_affinity_irq
 };
 
-struct irq_desc *sn_irq_desc(unsigned int irq)
-{
-	return (_irq_desc + irq);
-}
-
-u8 sn_irq_to_vector(unsigned int irq)
-{
-	return irq;
-}
-
 unsigned int sn_local_vector_to_irq(u8 vector)
 {
 	return (CPU_VECTOR_TO_IRQ(smp_processor_id(), vector));
@@ -220,7 +212,7 @@
 void sn_irq_init(void)
 {
 	int i;
-	irq_desc_t *base_desc = _irq_desc;
+	irq_desc_t *base_desc = irq_desc;
 
 	for (i = 0; i < NR_IRQS; i++) {
 		if (base_desc[i].handler == &no_irq_type) {
diff -Nru a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c
--- a/arch/ia64/sn/kernel/setup.c	2005-03-01 23:38:54 -08:00
+++ b/arch/ia64/sn/kernel/setup.c	2005-03-01 23:38:54 -08:00
@@ -28,6 +28,7 @@
 #include <linux/compiler.h>
 #include <linux/sched.h>
 #include <linux/root_dev.h>
+#include <linux/nodemask.h>
 
 #include <asm/io.h>
 #include <asm/sal.h>
@@ -40,7 +41,6 @@
 #include <asm/sn/nodepda.h>
 #include <asm/sn/sn_cpuid.h>
 #include <asm/sn/simulator.h>
-#include "shub.h"
 #include <asm/sn/leds.h>
 #include <asm/sn/bte.h>
 #include <asm/sn/shub_mmr.h>
@@ -163,13 +163,12 @@
 
 void __init early_sn_setup(void)
 {
-	void ia64_sal_handler_init(void *entry_point, void *gpval);
 	efi_system_table_t *efi_systab;
 	efi_config_table_t *config_tables;
 	struct ia64_sal_systab *sal_systab;
 	struct ia64_sal_desc_entry_point *ep;
 	char *p;
-	int i;
+	int i, j;
 
 	/*
 	 * Parse enough of the SAL tables to locate the SAL entry point. Since, console
@@ -185,19 +184,21 @@
 		    0) {
 			sal_systab = __va(config_tables[i].table);
 			p = (char *)(sal_systab + 1);
-			for (i = 0; i < sal_systab->entry_count; i++) {
+			for (j = 0; j < sal_systab->entry_count; j++) {
 				if (*p == SAL_DESC_ENTRY_POINT) {
 					ep = (struct ia64_sal_desc_entry_point
 					      *)p;
 					ia64_sal_handler_init(__va
 							      (ep->sal_proc),
 							      __va(ep->gp));
-					break;
+					return;
 				}
 				p += SAL_DESC_SIZE(*p);
 			}
 		}
 	}
+	/* Uh-oh, SAL not available?? */
+	printk(KERN_ERR "failed to find SAL entry point\n");
 }
 
 extern int platform_intr_list[];
@@ -215,8 +216,10 @@
 	unsigned long id;
 	int rev;
 
-	id = REMOTE_HUB_L(nasid, SH_SHUB_ID);
-	rev = (id & SH_SHUB_ID_REVISION_MASK) >> SH_SHUB_ID_REVISION_SHFT;
+	if (is_shub2())
+		return 0;
+	id = REMOTE_HUB_L(nasid, SH1_SHUB_ID);
+	rev = (id & SH1_SHUB_ID_REVISION_MASK) >> SH1_SHUB_ID_REVISION_SHFT;
 	return rev <= 2;
 }
 
@@ -224,9 +227,14 @@
 {
 	int cnode;
 
-	for (cnode = 0; cnode < numnodes; cnode++)
-		if (is_shub_1_1(cnodeid_to_nasid(cnode)))
-			shub_1_1_found = 1;
+	if (is_shub2()) {
+		/* none yet */
+	} else {
+		for_each_online_node(cnode) {
+			if (is_shub_1_1(cnodeid_to_nasid(cnode)))
+				shub_1_1_found = 1;
+		}
+	}
 }
 
 /**
@@ -340,23 +348,23 @@
  *
  * One time setup for Node Data Area.  Called by sn_setup().
  */
-void __init sn_init_pdas(char **cmdline_p)
+static void __init sn_init_pdas(char **cmdline_p)
 {
 	cnodeid_t cnode;
 
 	memset(pda->cnodeid_to_nasid_table, -1,
 	       sizeof(pda->cnodeid_to_nasid_table));
-	for (cnode = 0; cnode < numnodes; cnode++)
+	for_each_online_node(cnode)
 		pda->cnodeid_to_nasid_table[cnode] =
 		    pxm_to_nasid(nid_to_pxm_map[cnode]);
 
-	numionodes = numnodes;
+	numionodes = num_online_nodes();
 	scan_for_ionodes();
 
 	/*
 	 * Allocate & initalize the nodepda for each node.
 	 */
-	for (cnode = 0; cnode < numnodes; cnode++) {
+	for_each_online_node(cnode) {
 		nodepdaindr[cnode] =
 		    alloc_bootmem_node(NODE_DATA(cnode), sizeof(nodepda_t));
 		memset(nodepdaindr[cnode], 0, sizeof(nodepda_t));
@@ -367,7 +375,7 @@
 	/*
 	 * Allocate & initialize nodepda for TIOs.  For now, put them on node 0.
 	 */
-	for (cnode = numnodes; cnode < numionodes; cnode++) {
+	for (cnode = num_online_nodes(); cnode < numionodes; cnode++) {
 		nodepdaindr[cnode] =
 		    alloc_bootmem_node(NODE_DATA(0), sizeof(nodepda_t));
 		memset(nodepdaindr[cnode], 0, sizeof(nodepda_t));
@@ -385,7 +393,7 @@
 	 * The following routine actually sets up the hubinfo struct
 	 * in nodepda.
 	 */
-	for (cnode = 0; cnode < numnodes; cnode++) {
+	for_each_online_node(cnode) {
 		bte_init_node(nodepdaindr[cnode], cnode);
 	}
 
@@ -416,8 +424,17 @@
 	int slice;
 	int cnode;
 	int i;
+	u64 shubtype, nasid_bitmask, nasid_shift;
 	static int wars_have_been_checked;
 
+	memset(pda, 0, sizeof(pda));
+	if (ia64_sn_get_hub_info(0, &shubtype, &nasid_bitmask, &nasid_shift))
+		BUG();
+	pda->shub2 = (u8)shubtype;
+	pda->nasid_bitmask = (u16)nasid_bitmask;
+	pda->nasid_shift = (u8)nasid_shift;
+	pda->as_shift = pda->nasid_shift - 2;
+
 	/*
 	 * The boot cpu makes this call again after platform initialization is
 	 * complete.
@@ -431,7 +448,7 @@
 	if (ia64_sn_get_sapic_info(cpuphyid, &nasid, &subnode, &slice))
 		BUG();
 
-	for (i=0; i < NR_NODES; i++) {
+	for (i=0; i < MAX_NUMNODES; i++) {
 		if (nodepdaindr[i]) {
 			nodepdaindr[i]->phys_cpuid[cpuid].nasid = nasid;
 			nodepdaindr[i]->phys_cpuid[cpuid].slice = slice;
@@ -441,7 +458,6 @@
 
 	cnode = nasid_to_cnodeid(nasid);
 
-	memset(pda, 0, sizeof(pda));
 	pda->p_nodepda = nodepdaindr[cnode];
 	pda->led_address =
 	    (typeof(pda->led_address)) (LED0 + (slice << LED_CPU_SHIFT));
@@ -469,25 +485,29 @@
 	pda->shub_1_1_found = shub_1_1_found;
 
 	/*
-	 * We must use different memory allocators for first cpu (bootmem 
-	 * allocator) than for the other cpus (regular allocator).
+	 * Set up addresses of PIO/MEM write status registers.
 	 */
-	pda->pio_write_status_addr = (volatile unsigned long *)
-	    LOCAL_MMR_ADDR((slice <
-			    2 ? SH_PIO_WRITE_STATUS_0 : SH_PIO_WRITE_STATUS_1));
-	pda->mem_write_status_addr = (volatile u64 *)
-	    LOCAL_MMR_ADDR((slice <
-			    2 ? SH_MEMORY_WRITE_STATUS_0 :
-			    SH_MEMORY_WRITE_STATUS_1));
+	{
+		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, 
+			SH2_PIO_WRITE_STATUS_2, SH2_PIO_WRITE_STATUS_3};
+		u64 *pio;
+		pio = is_shub1() ? pio1 : pio2;
+		pda->pio_write_status_addr = (volatile unsigned long *) LOCAL_MMR_ADDR(pio[slice]);
+		pda->pio_write_status_val = is_shub1() ? SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_MASK : 0;
+	}
 
-	if (local_node_data->active_cpu_count++ == 0) {
+	/*
+	 * WAR addresses for SHUB 1.x.
+	 */
+	if (local_node_data->active_cpu_count++ == 0 && is_shub1()) {
 		int buddy_nasid;
 		buddy_nasid =
 		    cnodeid_to_nasid(numa_node_id() ==
-				     numnodes - 1 ? 0 : numa_node_id() + 1);
+				     num_online_nodes() - 1 ? 0 : numa_node_id() + 1);
 		pda->pio_shub_war_cam_addr =
 		    (volatile unsigned long *)GLOBAL_MMR_ADDR(nasid,
-							      SH_PI_CAM_CONTROL);
+							      SH1_PI_CAM_CONTROL);
 	}
 }
 
@@ -503,15 +523,15 @@
 
 	/* Setup ionodes with memory */
 	for (nasid = 0; nasid < MAX_PHYSNODE_ID; nasid += 2) {
-		u64 klgraph_header;
+		char *klgraph_header;
 		cnodeid_t cnodeid;
 
 		if (physical_node_map[nasid] == -1)
 			continue;
 
-		klgraph_header = cnodeid = -1;
-		klgraph_header = ia64_sn_get_klconfig_addr(nasid);
-		if (klgraph_header <= 0) {
+		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! */
diff -Nru a/arch/ia64/sn/kernel/sn2/prominfo_proc.c b/arch/ia64/sn/kernel/sn2/prominfo_proc.c
--- a/arch/ia64/sn/kernel/sn2/prominfo_proc.c	2005-03-01 23:38:53 -08:00
+++ b/arch/ia64/sn/kernel/sn2/prominfo_proc.c	2005-03-01 23:38:53 -08:00
@@ -12,6 +12,7 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/proc_fs.h>
+#include <linux/nodemask.h>
 #include <asm/system.h>
 #include <asm/io.h>
 #include <asm/sn/sn_sal.h>
@@ -233,14 +234,13 @@
 	if (!ia64_platform_is("sn2"))
 		return 0;
 
-	proc_entries = kmalloc(numnodes * sizeof(struct proc_dir_entry *),
+	proc_entries = kmalloc(num_online_nodes() * sizeof(struct proc_dir_entry *),
 			       GFP_KERNEL);
 
 	sgi_prominfo_entry = proc_mkdir("sgi_prominfo", NULL);
 
-	for (cnodeid = 0, entp = proc_entries;
-	     cnodeid < numnodes;
-	     cnodeid++, entp++) {
+	entp = proc_entries;
+	for_each_online_node(cnodeid) {
 		sprintf(name, "node%d", cnodeid);
 		*entp = proc_mkdir(name, sgi_prominfo_entry);
 		nasid = cnodeid_to_nasid(cnodeid);
@@ -254,6 +254,7 @@
 			(void *)nasid);
 		if (p)
 			p->owner = THIS_MODULE;
+		entp++;
 	}
 
 	return 0;
@@ -265,12 +266,13 @@
 	unsigned cnodeid;
 	char name[NODE_NAME_LEN];
 
-	for (cnodeid = 0, entp = proc_entries;
-	     cnodeid < numnodes; cnodeid++, entp++) {
+	entp = proc_entries;
+	for_each_online_node(cnodeid) {
 		remove_proc_entry("fit", *entp);
 		remove_proc_entry("version", *entp);
 		sprintf(name, "node%d", cnodeid);
 		remove_proc_entry(name, sgi_prominfo_entry);
+		entp++;
 	}
 	remove_proc_entry("sgi_prominfo", NULL);
 	kfree(proc_entries);
diff -Nru 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	2005-03-01 23:39:16 -08:00
+++ b/arch/ia64/sn/kernel/sn2/ptc_deadlock.S	2005-03-01 23:39:16 -08:00
@@ -8,34 +8,33 @@
 
 #include <asm/sn/shub_mmr.h>
 
-#define ZEROVAL		0x3f		// "zero" value for outstanding PIO requests
-#define DEADLOCKBIT	SH_PIO_WRITE_STATUS_0_WRITE_DEADLOCK_SHFT
-#define WRITECOUNT	SH_PIO_WRITE_STATUS_0_PENDING_WRITE_COUNT_SHFT
-#define ALIAS_OFFSET	(SH_PIO_WRITE_STATUS_0_ALIAS-SH_PIO_WRITE_STATUS_0)
+#define DEADLOCKBIT	SH_PIO_WRITE_STATUS_WRITE_DEADLOCK_SHFT
+#define WRITECOUNTMASK	SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_MASK
+#define ALIAS_OFFSET	(SH1_PIO_WRITE_STATUS_0_ALIAS-SH1_PIO_WRITE_STATUS_0)
 
 
 	.global	sn2_ptc_deadlock_recovery_core
 	.proc  	sn2_ptc_deadlock_recovery_core
 
 sn2_ptc_deadlock_recovery_core:
-	.regstk 5,0,0,0
+	.regstk 6,0,0,0
 
 	ptc0  	 = in0
 	data0 	 = in1
 	ptc1  	 = in2
 	data1 	 = in3
 	piowc 	 = in4
+	zeroval  = in5
 	piowcphy = r30
 	psrsave  = r2
-	zeroval  = r3
 	scr1	 = r16
 	scr2	 = r17
+	mask	 = r18
 
 
 	extr.u	piowcphy=piowc,0,61;;	// Convert piowc to uncached physical address
 	dep	piowcphy=-1,piowcphy,63,1
-
-	mov	zeroval=ZEROVAL		// "zero" value for PIO write count
+	movl	mask=WRITECOUNTMASK
 
 1:
 	add	scr2=ALIAS_OFFSET,piowc	// Address of WRITE_STATUS alias register 
@@ -43,7 +42,7 @@
 	st8.rel	[scr2]=scr1;;
 
 5:	ld8.acq	scr1=[piowc];;		// Wait for PIOs to complete.
-	extr.u	scr2=scr1,WRITECOUNT,7;;// PIO count
+	and	scr2=scr1,mask;;	// mask of writecount bits
 	cmp.ne	p6,p0=zeroval,scr2
 (p6)	br.cond.sptk 5b
 	
@@ -57,16 +56,17 @@
 	st8.rel [ptc0]=data0		// Write PTC0 & wait for completion.
 
 5:	ld8.acq	scr1=[piowcphy];;	// Wait for PIOs to complete.
-	extr.u	scr2=scr1,WRITECOUNT,7;;// PIO count
+	and	scr2=scr1,mask;;	// mask of writecount bits
 	cmp.ne	p6,p0=zeroval,scr2
 (p6)	br.cond.sptk 5b;;
 
 	tbit.nz	p8,p7=scr1,DEADLOCKBIT;;// Test for DEADLOCK
+(p7)	cmp.ne p7,p0=r0,ptc1;;		// Test for non-null ptc1
 	
 (p7)	st8.rel [ptc1]=data1;;		// Now write PTC1.
 
 5:	ld8.acq	scr1=[piowcphy];;	// Wait for PIOs to complete.
-	extr.u	scr2=scr1,WRITECOUNT,7;;// PIO count
+	and	scr2=scr1,mask;;	// mask of writecount bits
 	cmp.ne	p6,p0=zeroval,scr2
 (p6)	br.cond.sptk 5b
 	
diff -Nru a/arch/ia64/sn/kernel/sn2/sn2_smp.c b/arch/ia64/sn/kernel/sn2/sn2_smp.c
--- a/arch/ia64/sn/kernel/sn2/sn2_smp.c	2005-03-01 23:39:16 -08:00
+++ b/arch/ia64/sn/kernel/sn2/sn2_smp.c	2005-03-01 23:39:16 -08:00
@@ -19,6 +19,7 @@
 #include <linux/mmzone.h>
 #include <linux/module.h>
 #include <linux/bitops.h>
+#include <linux/nodemask.h>
 
 #include <asm/processor.h>
 #include <asm/irq.h>
@@ -38,23 +39,23 @@
 #include <asm/sn/nodepda.h>
 #include <asm/sn/rw_mmr.h>
 
-void sn2_ptc_deadlock_recovery(unsigned long data0, unsigned long data1);
+void sn2_ptc_deadlock_recovery(volatile unsigned long *, unsigned long data0, 
+	volatile unsigned long *, unsigned long data1);
 
-static spinlock_t sn2_global_ptc_lock __cacheline_aligned = SPIN_LOCK_UNLOCKED;
+static  __cacheline_aligned DEFINE_SPINLOCK(sn2_global_ptc_lock);
 
 static unsigned long sn2_ptc_deadlock_count;
 
 static inline unsigned long wait_piowc(void)
 {
-	volatile unsigned long *piows;
+	volatile unsigned long *piows, zeroval;
 	unsigned long ws;
 
 	piows = pda->pio_write_status_addr;
+	zeroval = pda->pio_write_status_val;
 	do {
-		ia64_mfa();
-	} while (((ws =
-		   *piows) & SH_PIO_WRITE_STATUS_0_PENDING_WRITE_COUNT_MASK) !=
-		 SH_PIO_WRITE_STATUS_0_PENDING_WRITE_COUNT_MASK);
+		cpu_relax();
+	} while (((ws = *piows) & SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_MASK) != zeroval);
 	return ws;
 }
 
@@ -88,20 +89,19 @@
 sn2_global_tlb_purge(unsigned long start, unsigned long end,
 		     unsigned long nbits)
 {
-	int i, cnode, mynasid, cpu, lcpu = 0, nasid, flushed = 0;
+	int i, shub1, cnode, mynasid, cpu, lcpu = 0, nasid, flushed = 0;
 	volatile unsigned long *ptc0, *ptc1;
-	unsigned long flags = 0, data0, data1;
+	unsigned long flags = 0, data0 = 0, data1 = 0;
 	struct mm_struct *mm = current->active_mm;
-	short nasids[NR_NODES], nix;
-	DECLARE_BITMAP(nodes_flushed, NR_NODES);
-
-	bitmap_zero(nodes_flushed, NR_NODES);
+	short nasids[MAX_NUMNODES], nix;
+	nodemask_t nodes_flushed;
 
+	nodes_clear(nodes_flushed);
 	i = 0;
 
 	for_each_cpu_mask(cpu, mm->cpu_vm_mask) {
 		cnode = cpu_to_node(cpu);
-		__set_bit(cnode, nodes_flushed);
+		node_set(cnode, nodes_flushed);
 		lcpu = cpu;
 		i++;
 	}
@@ -125,32 +125,45 @@
 	}
 
 	nix = 0;
-	for (cnode = find_first_bit(&nodes_flushed, NR_NODES); cnode < NR_NODES;
-	     cnode = find_next_bit(&nodes_flushed, NR_NODES, ++cnode))
+	for_each_node_mask(cnode, nodes_flushed)
 		nasids[nix++] = cnodeid_to_nasid(cnode);
 
-	data0 = (1UL << SH_PTC_0_A_SHFT) |
-	    (nbits << SH_PTC_0_PS_SHFT) |
-	    ((ia64_get_rr(start) >> 8) << SH_PTC_0_RID_SHFT) |
-	    (1UL << SH_PTC_0_START_SHFT);
-
-	ptc0 = (long *)GLOBAL_MMR_PHYS_ADDR(0, SH_PTC_0);
-	ptc1 = (long *)GLOBAL_MMR_PHYS_ADDR(0, SH_PTC_1);
+	shub1 = is_shub1();
+	if (shub1) {
+		data0 = (1UL << SH1_PTC_0_A_SHFT) |
+		    	(nbits << SH1_PTC_0_PS_SHFT) |
+		    	((ia64_get_rr(start) >> 8) << SH1_PTC_0_RID_SHFT) |
+		    	(1UL << SH1_PTC_0_START_SHFT);
+		ptc0 = (long *)GLOBAL_MMR_PHYS_ADDR(0, SH1_PTC_0);
+		ptc1 = (long *)GLOBAL_MMR_PHYS_ADDR(0, SH1_PTC_1);
+	} else {
+		data0 = (1UL << SH2_PTC_A_SHFT) |
+			(nbits << SH2_PTC_PS_SHFT) |
+		    	(1UL << SH2_PTC_START_SHFT);
+		ptc0 = (long *)GLOBAL_MMR_PHYS_ADDR(0, SH2_PTC + 
+			((ia64_get_rr(start) >> 8) << SH2_PTC_RID_SHFT) );
+		ptc1 = NULL;
+	}
+	
 
 	mynasid = get_nasid();
 
 	spin_lock_irqsave(&sn2_global_ptc_lock, flags);
 
 	do {
-		data1 = start | (1UL << SH_PTC_1_START_SHFT);
+		if (shub1)
+			data1 = start | (1UL << SH1_PTC_1_START_SHFT);
+		else
+			data0 = (data0 & ~SH2_PTC_ADDR_MASK) | (start & SH2_PTC_ADDR_MASK);
 		for (i = 0; i < nix; i++) {
 			nasid = nasids[i];
-			if (likely(nasid == mynasid)) {
+			if (unlikely(nasid == mynasid)) {
 				ia64_ptcga(start, nbits << 2);
 				ia64_srlz_i();
 			} else {
 				ptc0 = CHANGE_NASID(nasid, ptc0);
-				ptc1 = CHANGE_NASID(nasid, ptc1);
+				if (ptc1)
+					ptc1 = CHANGE_NASID(nasid, ptc1);
 				pio_atomic_phys_write_mmrs(ptc0, data0, ptc1,
 							   data1);
 				flushed = 1;
@@ -159,8 +172,8 @@
 
 		if (flushed
 		    && (wait_piowc() &
-			SH_PIO_WRITE_STATUS_0_WRITE_DEADLOCK_MASK)) {
-			sn2_ptc_deadlock_recovery(data0, data1);
+			SH_PIO_WRITE_STATUS_WRITE_DEADLOCK_MASK)) {
+			sn2_ptc_deadlock_recovery(ptc0, data0, ptc1, data1);
 		}
 
 		start += (1UL << nbits);
@@ -179,28 +192,30 @@
  * TLB flush transaction.  The recovery sequence is somewhat tricky & is
  * coded in assembly language.
  */
-void sn2_ptc_deadlock_recovery(unsigned long data0, unsigned long data1)
+void sn2_ptc_deadlock_recovery(volatile unsigned long *ptc0, unsigned long data0,
+	volatile unsigned long *ptc1, unsigned long data1)
 {
-	extern void sn2_ptc_deadlock_recovery_core(long *, long, long *, long,
-						   long *);
+	extern void sn2_ptc_deadlock_recovery_core(volatile unsigned long *, unsigned long,
+	        volatile unsigned long *, unsigned long, volatile unsigned long *, unsigned long);
 	int cnode, mycnode, nasid;
-	long *ptc0, *ptc1, *piows;
+	volatile unsigned long *piows;
+	volatile unsigned long zeroval;
 
 	sn2_ptc_deadlock_count++;
 
-	ptc0 = (long *)GLOBAL_MMR_PHYS_ADDR(0, SH_PTC_0);
-	ptc1 = (long *)GLOBAL_MMR_PHYS_ADDR(0, SH_PTC_1);
-	piows = (long *)pda->pio_write_status_addr;
+	piows = pda->pio_write_status_addr;
+	zeroval = pda->pio_write_status_val;
 
 	mycnode = numa_node_id();
 
-	for (cnode = 0; cnode < numnodes; cnode++) {
+	for_each_online_node(cnode) {
 		if (is_headless_node(cnode) || cnode == mycnode)
 			continue;
 		nasid = cnodeid_to_nasid(cnode);
 		ptc0 = CHANGE_NASID(nasid, ptc0);
-		ptc1 = CHANGE_NASID(nasid, ptc1);
-		sn2_ptc_deadlock_recovery_core(ptc0, data0, ptc1, data1, piows);
+		if (ptc1)
+			ptc1 = CHANGE_NASID(nasid, ptc1);
+		sn2_ptc_deadlock_recovery_core(ptc0, data0, ptc1, data1, piows, zeroval);
 	}
 }
 
diff -Nru a/arch/ia64/sn/kernel/sn2/sn_hwperf.c b/arch/ia64/sn/kernel/sn2/sn_hwperf.c
--- a/arch/ia64/sn/kernel/sn2/sn_hwperf.c	2005-03-01 23:39:09 -08:00
+++ b/arch/ia64/sn/kernel/sn2/sn_hwperf.c	2005-03-01 23:39:09 -08:00
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2004 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2004-2005 Silicon Graphics, Inc. All rights reserved.
  *
  * SGI Altix topology and hardware performance monitoring API.
  * Mark Goodwin <markgw@sgi.com>. 
@@ -30,6 +30,7 @@
 #include <linux/miscdevice.h>
 #include <linux/cpumask.h>
 #include <linux/smp_lock.h>
+#include <linux/nodemask.h>
 #include <asm/processor.h>
 #include <asm/topology.h>
 #include <asm/smp.h>
@@ -373,6 +374,42 @@
 	return r;
 }
 
+/* map SAL hwperf error code to system error code */
+static int sn_hwperf_map_err(int hwperf_err)
+{
+	int e;
+
+	switch(hwperf_err) {
+	case SN_HWPERF_OP_OK:
+		e = 0;
+		break;
+
+	case SN_HWPERF_OP_NOMEM:
+		e = -ENOMEM;
+		break;
+
+	case SN_HWPERF_OP_NO_PERM:
+		e = -EPERM;
+		break;
+
+	case SN_HWPERF_OP_IO_ERROR:
+		e = -EIO;
+		break;
+
+	case SN_HWPERF_OP_BUSY:
+	case SN_HWPERF_OP_RECONFIGURE:
+		e = -EAGAIN;
+		break;
+
+	case SN_HWPERF_OP_INVAL:
+	default:
+		e = -EINVAL;
+		break;
+	}
+
+	return e;
+}
+
 /*
  * ioctl for "sn_hwperf" misc device
  */
@@ -510,12 +547,20 @@
 		op_info.v0 = &v0;
 		op_info.op = op;
 		r = sn_hwperf_op_cpu(&op_info);
+		if (r) {
+			r = sn_hwperf_map_err(r);
+			goto error;
+		}
 		break;
 
 	default:
 		/* all other ops are a direct SAL call */
 		r = ia64_sn_hwperf_op(sn_hwperf_master_nasid, op,
 			      a.arg, a.sz, (u64) p, 0, 0, &v0);
+		if (r) {
+			r = sn_hwperf_map_err(r);
+			goto error;
+		}
 		a.v0 = v0;
 		break;
 	}
@@ -529,8 +574,7 @@
 	}
 
 error:
-	if (p)
-		vfree(p);
+	vfree(p);
 
 	lock_kernel();
 	return r;
@@ -641,7 +685,6 @@
 {
 	struct seq_file *seq = file->private_data;
 
-	if (seq->private)
-		vfree(seq->private);
+	vfree(seq->private);
 	return seq_release(inode, file);
 }
diff -Nru a/arch/ia64/sn/kernel/sn2/timer.c b/arch/ia64/sn/kernel/sn2/timer.c
--- a/arch/ia64/sn/kernel/sn2/timer.c	2005-03-01 23:38:58 -08:00
+++ b/arch/ia64/sn/kernel/sn2/timer.c	2005-03-01 23:38:58 -08:00
@@ -15,7 +15,6 @@
 #include <asm/hw_irq.h>
 #include <asm/system.h>
 
-#include "shub.h"
 #include <asm/sn/leds.h>
 #include <asm/sn/shub_mmr.h>
 #include <asm/sn/clksupport.h>
@@ -26,12 +25,12 @@
 	.drift = -1,
 	.shift = 10,
 	.mask = (1LL << 55) - 1,
-	.source = TIME_SOURCE_MMIO64,
-	.addr = RTC_COUNTER_ADDR
+	.source = TIME_SOURCE_MMIO64
 };
 
 void __init sn_timer_init(void)
 {
 	sn2_interpolator.frequency = sn_rtc_cycles_per_second;
+	sn2_interpolator.addr = RTC_COUNTER_ADDR;
 	register_time_interpolator(&sn2_interpolator);
 }
diff -Nru a/arch/ia64/sn/kernel/sn2/timer_interrupt.c b/arch/ia64/sn/kernel/sn2/timer_interrupt.c
--- a/arch/ia64/sn/kernel/sn2/timer_interrupt.c	2005-03-01 23:39:16 -08:00
+++ b/arch/ia64/sn/kernel/sn2/timer_interrupt.c	2005-03-01 23:39:16 -08:00
@@ -34,7 +34,6 @@
 
 #include <linux/interrupt.h>
 #include <asm/sn/pda.h>
-#include "shub.h"
 #include <asm/sn/leds.h>
 
 extern void sn_lb_int_war_check(void);
diff -Nru a/arch/ia64/sn/pci/pci_dma.c b/arch/ia64/sn/pci/pci_dma.c
--- a/arch/ia64/sn/pci/pci_dma.c	2005-03-01 23:39:07 -08:00
+++ b/arch/ia64/sn/pci/pci_dma.c	2005-03-01 23:39:07 -08:00
@@ -3,52 +3,85 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2000,2002-2004 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2000,2002-2005 Silicon Graphics, Inc. All rights reserved.
  *
- * Routines for PCI DMA mapping.  See Documentation/DMA-mapping.txt for
+ * Routines for PCI DMA mapping.  See Documentation/DMA-API.txt for
  * a description of how these routines should be used.
  */
 
 #include <linux/module.h>
+#include <asm/dma.h>
 #include <asm/sn/sn_sal.h>
 #include "pci/pcibus_provider_defs.h"
 #include "pci/pcidev.h"
 #include "pci/pcibr_provider.h"
 
-void sn_pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents,
-		     int direction);
+#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))
 
 /**
- * sn_pci_alloc_consistent - allocate memory for coherent DMA
- * @hwdev: device to allocate for
+ * sn_dma_supported - test a DMA mask
+ * @dev: device to test
+ * @mask: DMA mask to test
+ *
+ * Return whether the given PCI device DMA address mask can be supported
+ * properly.  For example, if your device can only drive the low 24-bits
+ * during PCI bus mastering, then you would pass 0x00ffffff as the mask to
+ * this function.  Of course, SN only supports devices that have 32 or more
+ * address bits when using the PMU.
+ */
+int sn_dma_supported(struct device *dev, u64 mask)
+{
+	BUG_ON(dev->bus != &pci_bus_type);
+
+	if (mask < 0x7fffffff)
+		return 0;
+	return 1;
+}
+EXPORT_SYMBOL(sn_dma_supported);
+
+/**
+ * sn_dma_set_mask - set the DMA mask
+ * @dev: device to set
+ * @dma_mask: new mask
+ *
+ * Set @dev's DMA mask if the hw supports it.
+ */
+int sn_dma_set_mask(struct device *dev, u64 dma_mask)
+{
+	BUG_ON(dev->bus != &pci_bus_type);
+
+	if (!sn_dma_supported(dev, dma_mask))
+		return 0;
+
+	*dev->dma_mask = dma_mask;
+	return 1;
+}
+EXPORT_SYMBOL(sn_dma_set_mask);
+
+/**
+ * sn_dma_alloc_coherent - allocate memory for coherent DMA
+ * @dev: device to allocate for
  * @size: size of the region
  * @dma_handle: DMA (bus) address
+ * @flags: memory allocation flags
  *
- * pci_alloc_consistent() returns a pointer to a memory region suitable for
+ * dma_alloc_coherent() returns a pointer to a memory region suitable for
  * coherent DMA traffic to/from a PCI device.  On SN platforms, this means
  * that @dma_handle will have the %PCIIO_DMA_CMD flag set.
  *
  * This interface is usually used for "command" streams (e.g. the command
- * queue for a SCSI controller).  See Documentation/DMA-mapping.txt for
+ * queue for a SCSI controller).  See Documentation/DMA-API.txt for
  * more information.
- *
- * Also known as platform_pci_alloc_consistent() by the IA64 machvec code.
  */
-void *sn_pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
-			      dma_addr_t * dma_handle)
+void *sn_dma_alloc_coherent(struct device *dev, size_t size,
+			    dma_addr_t * dma_handle, int flags)
 {
 	void *cpuaddr;
 	unsigned long phys_addr;
-	struct pcidev_info *pcidev_info = SN_PCIDEV_INFO(hwdev);
-	struct pcibus_bussoft *bussoft = SN_PCIDEV_BUSSOFT(hwdev);
-
-	if (bussoft == NULL) {
-		return NULL;
-	}
+	struct pcidev_info *pcidev_info = SN_PCIDEV_INFO(to_pci_dev(dev));
 
-	if (! IS_PCI_BRIDGE_ASIC(bussoft->bs_asic_type)) {
-		return NULL;		/* unsupported asic type */
-	}
+	BUG_ON(dev->bus != &pci_bus_type);
 
 	/*
 	 * Allocate the memory.
@@ -66,151 +99,52 @@
 	/*
 	 * 64 bit address translations should never fail.
 	 * 32 bit translations can fail if there are insufficient mapping
-	 *   resources.
+	 * resources.
 	 */
 
-	*dma_handle = pcibr_dma_map(pcidev_info, phys_addr, size, SN_PCIDMA_CONSISTENT);
+	*dma_handle = pcibr_dma_map(pcidev_info, phys_addr, size,
+				    SN_PCIDMA_CONSISTENT);
 	if (!*dma_handle) {
-		printk(KERN_ERR
-		       "sn_pci_alloc_consistent():  failed  *dma_handle = 0x%lx hwdev->dev.coherent_dma_mask = 0x%lx \n",
-		       *dma_handle, hwdev->dev.coherent_dma_mask);
+		printk(KERN_ERR "%s: out of ATEs\n", __FUNCTION__);
 		free_pages((unsigned long)cpuaddr, get_order(size));
 		return NULL;
 	}
 
 	return cpuaddr;
 }
+EXPORT_SYMBOL(sn_dma_alloc_coherent);
 
 /**
- * sn_pci_free_consistent - free memory associated with coherent DMAable region
- * @hwdev: device to free for
+ * sn_pci_free_coherent - free memory associated with coherent DMAable region
+ * @dev: device to free for
  * @size: size to free
- * @vaddr: kernel virtual address to free
+ * @cpu_addr: kernel virtual address to free
  * @dma_handle: DMA address associated with this region
  *
- * Frees the memory allocated by pci_alloc_consistent().  Also known
- * as platform_pci_free_consistent() by the IA64 machvec code.
+ * Frees the memory allocated by dma_alloc_coherent(), potentially unmapping
+ * any associated IOMMU mappings.
  */
-void
-sn_pci_free_consistent(struct pci_dev *hwdev, size_t size, void *vaddr,
-		       dma_addr_t dma_handle)
+void sn_dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
+			  dma_addr_t dma_handle)
 {
-	struct pcidev_info *pcidev_info = SN_PCIDEV_INFO(hwdev);
-	struct pcibus_bussoft *bussoft = SN_PCIDEV_BUSSOFT(hwdev);
+	struct pcidev_info *pcidev_info = SN_PCIDEV_INFO(to_pci_dev(dev));
 
-	if (! bussoft) {
-		return;
-	}
+	BUG_ON(dev->bus != &pci_bus_type);
 
 	pcibr_dma_unmap(pcidev_info, dma_handle, 0);
-	free_pages((unsigned long)vaddr, get_order(size));
-}
-
-/**
- * sn_pci_map_sg - map a scatter-gather list for DMA
- * @hwdev: device to map for
- * @sg: scatterlist to map
- * @nents: number of entries
- * @direction: direction of the DMA transaction
- *
- * Maps each entry of @sg for DMA.  Also known as platform_pci_map_sg by the
- * IA64 machvec code.
- */
-int
-sn_pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents,
-	      int direction)
-{
-
-	int i;
-	unsigned long phys_addr;
-	struct scatterlist *saved_sg = sg;
-	struct pcidev_info *pcidev_info = SN_PCIDEV_INFO(hwdev);
-	struct pcibus_bussoft *bussoft = SN_PCIDEV_BUSSOFT(hwdev);
-
-	/* can't go anywhere w/o a direction in life */
-	if (direction == PCI_DMA_NONE)
-		BUG();
-
-	if (! bussoft) {
-		return 0;
-	}
-
-	/* SN cannot support DMA addresses smaller than 32 bits. */
-	if (hwdev->dma_mask < 0x7fffffff)
-		return 0;
-
-	/*
-	 * Setup a DMA address for each entry in the
-	 * scatterlist.
-	 */
-	for (i = 0; i < nents; i++, sg++) {
-		phys_addr =
-		    __pa((unsigned long)page_address(sg->page) + sg->offset);
-		sg->dma_address = pcibr_dma_map(pcidev_info, phys_addr, sg->length, 0);
-
-		if (!sg->dma_address) {
-			printk(KERN_ERR "sn_pci_map_sg: Unable to allocate "
-			       "anymore page map entries.\n");
-			/*
-			 * We will need to free all previously allocated entries.
-			 */
-			if (i > 0) {
-				sn_pci_unmap_sg(hwdev, saved_sg, i, direction);
-			}
-			return (0);
-		}
-
-		sg->dma_length = sg->length;
-	}
-
-	return nents;
-
-}
-
-/**
- * sn_pci_unmap_sg - unmap a scatter-gather list
- * @hwdev: device to unmap
- * @sg: scatterlist to unmap
- * @nents: number of scatterlist entries
- * @direction: DMA direction
- *
- * Unmap a set of streaming mode DMA translations.  Again, cpu read rules
- * concerning calls here are the same as for pci_unmap_single() below.  Also
- * known as sn_pci_unmap_sg() by the IA64 machvec code.
- */
-void
-sn_pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents,
-		int direction)
-{
-	int i;
-	struct pcidev_info *pcidev_info = SN_PCIDEV_INFO(hwdev);
-	struct pcibus_bussoft *bussoft = SN_PCIDEV_BUSSOFT(hwdev);
-
-	/* can't go anywhere w/o a direction in life */
-	if (direction == PCI_DMA_NONE)
-		BUG();
-
-	if (! bussoft) {
-		return;
-	}
-
-	for (i = 0; i < nents; i++, sg++) {
-		pcibr_dma_unmap(pcidev_info, sg->dma_address, direction);
-		sg->dma_address = (dma_addr_t) NULL;
-		sg->dma_length = 0;
-	}
+	free_pages((unsigned long)cpu_addr, get_order(size));
 }
+EXPORT_SYMBOL(sn_dma_free_coherent);
 
 /**
- * sn_pci_map_single - map a single region for DMA
- * @hwdev: device to map for
- * @ptr: kernel virtual address of the region to map
+ * sn_dma_map_single - map a single page for DMA
+ * @dev: device to map for
+ * @cpu_addr: kernel virtual address of the region to map
  * @size: size of the region
  * @direction: DMA direction
  *
- * Map the region pointed to by @ptr for DMA and return the
- * DMA address.   Also known as platform_pci_map_single() by
- * the IA64 machvec code.
+ * Map the region pointed to by @cpu_addr for DMA and return the
+ * DMA address.
  *
  * We map this to the one step pcibr_dmamap_trans interface rather than
  * the two step pcibr_dmamap_alloc/pcibr_dmamap_addr because we have
@@ -218,260 +152,212 @@
  * (which is pretty much unacceptable).
  *
  * TODO: simplify our interface;
- *       get rid of dev_desc and vhdl (seems redundant given a pci_dev);
  *       figure out how to save dmamap handle so can use two step.
  */
-dma_addr_t
-sn_pci_map_single(struct pci_dev *hwdev, void *ptr, size_t size, int direction)
+dma_addr_t sn_dma_map_single(struct device *dev, void *cpu_addr, size_t size,
+			     int direction)
 {
 	dma_addr_t dma_addr;
 	unsigned long phys_addr;
-	struct pcidev_info *pcidev_info = SN_PCIDEV_INFO(hwdev);
-	struct pcibus_bussoft *bussoft = SN_PCIDEV_BUSSOFT(hwdev);
-
-	if (direction == PCI_DMA_NONE)
-		BUG();
-
-	if (bussoft == NULL) {
-		return 0;
-	}
+	struct pcidev_info *pcidev_info = SN_PCIDEV_INFO(to_pci_dev(dev));
 
-	if (! IS_PCI_BRIDGE_ASIC(bussoft->bs_asic_type)) {
-		return 0;		/* unsupported asic type */
-	}
-
-	/* SN cannot support DMA addresses smaller than 32 bits. */
-	if (hwdev->dma_mask < 0x7fffffff)
-		return 0;
-
-	/*
-	 * Call our dmamap interface
-	 */
+	BUG_ON(dev->bus != &pci_bus_type);
 
-	phys_addr = __pa(ptr);
+	phys_addr = __pa(cpu_addr);
 	dma_addr = pcibr_dma_map(pcidev_info, phys_addr, size, 0);
 	if (!dma_addr) {
-		printk(KERN_ERR "pci_map_single: Unable to allocate anymore "
-		       "page map entries.\n");
+		printk(KERN_ERR "%s: out of ATEs\n", __FUNCTION__);
 		return 0;
 	}
-	return ((dma_addr_t) dma_addr);
+	return dma_addr;
 }
+EXPORT_SYMBOL(sn_dma_map_single);
 
 /**
- * sn_pci_dma_sync_single_* - make sure all DMAs or CPU accesses
- * have completed
- * @hwdev: device to sync
- * @dma_handle: DMA address to sync
+ * sn_dma_unmap_single - unamp a DMA mapped page
+ * @dev: device to sync
+ * @dma_addr: DMA address to sync
  * @size: size of region
  * @direction: DMA direction
  *
  * This routine is supposed to sync the DMA region specified
- * by @dma_handle into the 'coherence domain'.  We do not need to do
- * anything on our platform.
+ * by @dma_handle into the coherence domain.  On SN, we're always cache
+ * coherent, so we just need to free any ATEs associated with this mapping.
  */
-void
-sn_pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, size_t size,
-		    int direction)
+void sn_dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
+			 int direction)
 {
-	struct pcidev_info *pcidev_info = SN_PCIDEV_INFO(hwdev);
-	struct pcibus_bussoft *bussoft = SN_PCIDEV_BUSSOFT(hwdev);
-
-	if (direction == PCI_DMA_NONE)
-		BUG();
-
-	if (bussoft == NULL) {
-		return;
-	}
-
-	if (! IS_PCI_BRIDGE_ASIC(bussoft->bs_asic_type)) {
-		return;		/* unsupported asic type */
-	}
+	struct pcidev_info *pcidev_info = SN_PCIDEV_INFO(to_pci_dev(dev));
 
+	BUG_ON(dev->bus != &pci_bus_type);
 	pcibr_dma_unmap(pcidev_info, dma_addr, direction);
 }
+EXPORT_SYMBOL(sn_dma_unmap_single);
 
 /**
- * sn_dma_supported - test a DMA mask
- * @hwdev: device to test
- * @mask: DMA mask to test
+ * sn_dma_unmap_sg - unmap a DMA scatterlist
+ * @dev: device to unmap
+ * @sg: scatterlist to unmap
+ * @nhwentries: number of scatterlist entries
+ * @direction: DMA direction
  *
- * Return whether the given PCI device DMA address mask can be supported
- * properly.  For example, if your device can only drive the low 24-bits
- * during PCI bus mastering, then you would pass 0x00ffffff as the mask to
- * this function.  Of course, SN only supports devices that have 32 or more
- * address bits when using the PMU.  We could theoretically support <32 bit
- * cards using direct mapping, but we'll worry about that later--on the off
- * chance that someone actually wants to use such a card.
+ * Unmap a set of streaming mode DMA translations.
  */
-int sn_pci_dma_supported(struct pci_dev *hwdev, u64 mask)
+void sn_dma_unmap_sg(struct device *dev, struct scatterlist *sg,
+		     int nhwentries, int direction)
 {
-	if (mask < 0x7fffffff)
-		return 0;
-	return 1;
-}
-
-/*
- * New generic DMA routines just wrap sn2 PCI routines until we
- * support other bus types (if ever).
- */
+	int i;
+	struct pcidev_info *pcidev_info = SN_PCIDEV_INFO(to_pci_dev(dev));
 
-int sn_dma_supported(struct device *dev, u64 mask)
-{
 	BUG_ON(dev->bus != &pci_bus_type);
 
-	return sn_pci_dma_supported(to_pci_dev(dev), mask);
+	for (i = 0; i < nhwentries; i++, sg++) {
+		pcibr_dma_unmap(pcidev_info, sg->dma_address, direction);
+		sg->dma_address = (dma_addr_t) NULL;
+		sg->dma_length = 0;
+	}
 }
+EXPORT_SYMBOL(sn_dma_unmap_sg);
 
-EXPORT_SYMBOL(sn_dma_supported);
-
-int sn_dma_set_mask(struct device *dev, u64 dma_mask)
+/**
+ * sn_dma_map_sg - map a scatterlist for DMA
+ * @dev: device to map for
+ * @sg: scatterlist to map
+ * @nhwentries: number of entries
+ * @direction: direction of the DMA transaction
+ *
+ * Maps each entry of @sg for DMA.
+ */
+int sn_dma_map_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
+		  int direction)
 {
+	unsigned long phys_addr;
+	struct scatterlist *saved_sg = sg;
+	struct pcidev_info *pcidev_info = SN_PCIDEV_INFO(to_pci_dev(dev));
+	int i;
+
 	BUG_ON(dev->bus != &pci_bus_type);
 
-	if (!sn_dma_supported(dev, dma_mask))
-		return 0;
+	/*
+	 * Setup a DMA address for each entry in the scatterlist.
+	 */
+	for (i = 0; i < nhwentries; i++, sg++) {
+		phys_addr = SG_ENT_PHYS_ADDRESS(sg);
+		sg->dma_address = pcibr_dma_map(pcidev_info, phys_addr,
+						sg->length, 0);
 
-	*dev->dma_mask = dma_mask;
-	return 1;
-}
+		if (!sg->dma_address) {
+			printk(KERN_ERR "%s: out of ATEs\n", __FUNCTION__);
 
-EXPORT_SYMBOL(sn_dma_set_mask);
+			/*
+			 * Free any successfully allocated entries.
+			 */
+			if (i > 0)
+				sn_dma_unmap_sg(dev, saved_sg, i, direction);
+			return 0;
+		}
 
-void *sn_dma_alloc_coherent(struct device *dev, size_t size,
-			    dma_addr_t * dma_handle, int flag)
-{
-	BUG_ON(dev->bus != &pci_bus_type);
+		sg->dma_length = sg->length;
+	}
 
-	return sn_pci_alloc_consistent(to_pci_dev(dev), size, dma_handle);
+	return nhwentries;
 }
+EXPORT_SYMBOL(sn_dma_map_sg);
 
-EXPORT_SYMBOL(sn_dma_alloc_coherent);
-
-void
-sn_dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
-		     dma_addr_t dma_handle)
+void sn_dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
+				size_t size, int direction)
 {
 	BUG_ON(dev->bus != &pci_bus_type);
-
-	sn_pci_free_consistent(to_pci_dev(dev), size, cpu_addr, dma_handle);
 }
+EXPORT_SYMBOL(sn_dma_sync_single_for_cpu);
 
-EXPORT_SYMBOL(sn_dma_free_coherent);
-
-dma_addr_t
-sn_dma_map_single(struct device *dev, void *cpu_addr, size_t size,
-		  int direction)
+void sn_dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle,
+				   size_t size, int direction)
 {
 	BUG_ON(dev->bus != &pci_bus_type);
-
-	return sn_pci_map_single(to_pci_dev(dev), cpu_addr, size,
-				 (int)direction);
 }
+EXPORT_SYMBOL(sn_dma_sync_single_for_device);
 
-EXPORT_SYMBOL(sn_dma_map_single);
-
-void
-sn_dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
-		    int direction)
+void sn_dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
+			    int nelems, int direction)
 {
 	BUG_ON(dev->bus != &pci_bus_type);
-
-	sn_pci_unmap_single(to_pci_dev(dev), dma_addr, size, (int)direction);
 }
+EXPORT_SYMBOL(sn_dma_sync_sg_for_cpu);
 
-EXPORT_SYMBOL(sn_dma_unmap_single);
-
-dma_addr_t
-sn_dma_map_page(struct device *dev, struct page *page,
-		unsigned long offset, size_t size, int direction)
+void sn_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
+			       int nelems, int direction)
 {
 	BUG_ON(dev->bus != &pci_bus_type);
-
-	return pci_map_page(to_pci_dev(dev), page, offset, size,
-			    (int)direction);
 }
+EXPORT_SYMBOL(sn_dma_sync_sg_for_device);
 
-EXPORT_SYMBOL(sn_dma_map_page);
-
-void
-sn_dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
-		  int direction)
+int sn_dma_mapping_error(dma_addr_t dma_addr)
 {
-	BUG_ON(dev->bus != &pci_bus_type);
-
-	pci_unmap_page(to_pci_dev(dev), dma_address, size, (int)direction);
+	return 0;
 }
+EXPORT_SYMBOL(sn_dma_mapping_error);
 
-EXPORT_SYMBOL(sn_dma_unmap_page);
-
-int
-sn_dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
-	      int direction)
+char *sn_pci_get_legacy_mem(struct pci_bus *bus)
 {
-	BUG_ON(dev->bus != &pci_bus_type);
+	if (!SN_PCIBUS_BUSSOFT(bus))
+		return ERR_PTR(-ENODEV);
 
-	return sn_pci_map_sg(to_pci_dev(dev), sg, nents, (int)direction);
+	return (char *)(SN_PCIBUS_BUSSOFT(bus)->bs_legacy_mem | __IA64_UNCACHED_OFFSET);
 }
 
-EXPORT_SYMBOL(sn_dma_map_sg);
-
-void
-sn_dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
-		int direction)
+int sn_pci_legacy_read(struct pci_bus *bus, u16 port, u32 *val, u8 size)
 {
-	BUG_ON(dev->bus != &pci_bus_type);
+	unsigned long addr;
+	int ret;
 
-	sn_pci_unmap_sg(to_pci_dev(dev), sg, nhwentries, (int)direction);
-}
+	if (!SN_PCIBUS_BUSSOFT(bus))
+		return -ENODEV;
 
-EXPORT_SYMBOL(sn_dma_unmap_sg);
+	addr = SN_PCIBUS_BUSSOFT(bus)->bs_legacy_io | __IA64_UNCACHED_OFFSET;
+	addr += port;
 
-void
-sn_dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
-			   size_t size, int direction)
-{
-	BUG_ON(dev->bus != &pci_bus_type);
-}
+	ret = ia64_sn_probe_mem(addr, (long)size, (void *)val);
 
-EXPORT_SYMBOL(sn_dma_sync_single_for_cpu);
+	if (ret == 2)
+		return -EINVAL;
 
-void
-sn_dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle,
-			      size_t size, int direction)
-{
-	BUG_ON(dev->bus != &pci_bus_type);
-}
+	if (ret == 1)
+		*val = -1;
 
-EXPORT_SYMBOL(sn_dma_sync_single_for_device);
+	return size;
+}
 
-void
-sn_dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
-		       int direction)
+int sn_pci_legacy_write(struct pci_bus *bus, u16 port, u32 val, u8 size)
 {
-	BUG_ON(dev->bus != &pci_bus_type);
-}
+	int ret = size;
+	unsigned long paddr;
+	unsigned long *addr;
 
-EXPORT_SYMBOL(sn_dma_sync_sg_for_cpu);
+	if (!SN_PCIBUS_BUSSOFT(bus)) {
+		ret = -ENODEV;
+		goto out;
+	}
 
-void
-sn_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
-			  int nelems, int direction)
-{
-	BUG_ON(dev->bus != &pci_bus_type);
-}
+	/* Put the phys addr in uncached space */
+	paddr = SN_PCIBUS_BUSSOFT(bus)->bs_legacy_io | __IA64_UNCACHED_OFFSET;
+	paddr += port;
+	addr = (unsigned long *)paddr;
 
-int sn_dma_mapping_error(dma_addr_t dma_addr)
-{
-	return 0;
+	switch (size) {
+	case 1:
+		*(volatile u8 *)(addr) = (u8)(val);
+		break;
+	case 2:
+		*(volatile u16 *)(addr) = (u16)(val);
+		break;
+	case 4:
+		*(volatile u32 *)(addr) = (u32)(val);
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+ out:
+	return ret;
 }
-
-EXPORT_SYMBOL(sn_dma_sync_sg_for_device);
-EXPORT_SYMBOL(sn_pci_unmap_single);
-EXPORT_SYMBOL(sn_pci_map_single);
-EXPORT_SYMBOL(sn_pci_map_sg);
-EXPORT_SYMBOL(sn_pci_unmap_sg);
-EXPORT_SYMBOL(sn_pci_alloc_consistent);
-EXPORT_SYMBOL(sn_pci_free_consistent);
-EXPORT_SYMBOL(sn_pci_dma_supported);
-EXPORT_SYMBOL(sn_dma_mapping_error);
diff -Nru a/arch/m32r/Kconfig b/arch/m32r/Kconfig
--- a/arch/m32r/Kconfig	2005-03-01 23:38:44 -08:00
+++ b/arch/m32r/Kconfig	2005-03-01 23:38:44 -08:00
@@ -14,15 +14,19 @@
 
 config UID16
 	bool
-	default y
+	default n
 
 config GENERIC_ISA_DMA
 	bool
 	default y
 
-#config GENERIC_HARDIRQS
-#	bool
-#	default y
+config GENERIC_HARDIRQS
+	bool
+	default y
+
+config GENERIC_IRQ_PROBE
+	bool
+	default y
 
 source "init/Kconfig"
 
diff -Nru a/arch/m32r/defconfig b/arch/m32r/defconfig
--- a/arch/m32r/defconfig	2005-03-01 23:39:07 -08:00
+++ b/arch/m32r/defconfig	2005-03-01 23:39:07 -08:00
@@ -1,11 +1,13 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc1-bk21
-# Fri Nov 12 16:08:49 2004
+# Linux kernel version: 2.6.11-rc4
+# Wed Feb 16 21:10:44 2005
 #
 CONFIG_M32R=y
-CONFIG_UID16=y
+# CONFIG_UID16 is not set
 CONFIG_GENERIC_ISA_DMA=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
 
 #
 # Code maturity level options
@@ -81,6 +83,7 @@
 # CONFIG_DISCONTIGMEM is not set
 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 is not set
@@ -96,7 +99,6 @@
 #
 CONFIG_PCCARD=y
 # CONFIG_PCMCIA_DEBUG is not set
-# CONFIG_PCMCIA_OBSOLETE is not set
 CONFIG_PCMCIA=y
 
 #
@@ -146,10 +148,12 @@
 # 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=y
 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=""
@@ -162,6 +166,7 @@
 # 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
@@ -219,12 +224,12 @@
 #
 # CONFIG_SCSI_SPI_ATTRS is not set
 # CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
 
 #
 # SCSI low-level drivers
 #
 # CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_QLOGIC_1280_1040 is not set
 # CONFIG_SCSI_DEBUG is not set
 
 #
@@ -396,6 +401,7 @@
 # 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
 
 #
@@ -450,7 +456,6 @@
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_AGP is not set
 # CONFIG_DRM is not set
 
 #
@@ -524,6 +529,7 @@
 CONFIG_LOGO_LINUX_MONO=y
 CONFIG_LOGO_LINUX_VGA16=y
 CONFIG_LOGO_LINUX_CLUT224=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -537,11 +543,25 @@
 # 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=y
@@ -558,6 +578,10 @@
 # CONFIG_REISERFS_PROC_INFO is not set
 # CONFIG_REISERFS_FS_XATTR 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
@@ -628,7 +652,6 @@
 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
@@ -697,7 +720,8 @@
 # Kernel hacking
 #
 # CONFIG_DEBUG_KERNEL is not set
-# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+CONFIG_DEBUG_PREEMPT=y
+# CONFIG_DEBUG_BUGVERBOSE is not set
 # CONFIG_FRAME_POINTER is not set
 
 #
@@ -710,6 +734,10 @@
 # Cryptographic options
 #
 # CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
 
 #
 # Library routines
diff -Nru a/arch/m32r/kernel/entry.S b/arch/m32r/kernel/entry.S
--- a/arch/m32r/kernel/entry.S	2005-03-01 23:39:16 -08:00
+++ b/arch/m32r/kernel/entry.S	2005-03-01 23:39:16 -08:00
@@ -725,25 +725,25 @@
 	.long sys_time
 	.long sys_mknod
 	.long sys_chmod			/* 15 */
-	.long sys_lchown
+	.long sys_ni_syscall		/* lchown16 syscall holder */
 	.long sys_ni_syscall		/* old break syscall holder */
-	.long sys_stat
+	.long sys_ni_syscall		/* old stat syscall holder */
 	.long sys_lseek
 	.long sys_getpid		/* 20 */
 	.long sys_mount
 	.long sys_oldumount
-	.long sys_setuid
-	.long sys_getuid
+	.long sys_ni_syscall		/* setuid16 syscall holder */
+	.long sys_ni_syscall		/* getuid16 syscall holder */
 	.long sys_stime			/* 25 */
 	.long sys_ptrace
 	.long sys_alarm
-	.long sys_fstat
+	.long sys_ni_syscall		/* old fstat syscall holder */
 	.long sys_pause
 	.long sys_utime			/* 30 */
-	.long sys_cacheflush		/* for M32R */ /* old stty syscall holder */
+	.long sys_ni_syscall		/* old stty syscall holder */
 	.long sys_cachectl		/* for M32R */ /* old gtty syscall holder */
 	.long sys_access
-	.long sys_nice
+	.long sys_ni_syscall		/* nice	syscall holder */
 	.long sys_ni_syscall		/* 35  -  old ftime syscall holder */
 	.long sys_sync
 	.long sys_kill
@@ -755,17 +755,17 @@
 	.long sys_times
 	.long sys_ni_syscall		/* old prof syscall holder */
 	.long sys_brk			/* 45 */
-	.long sys_setgid
-	.long sys_getgid
-	.long sys_signal
-	.long sys_geteuid
-	.long sys_getegid		/* 50 */
+	.long sys_ni_syscall		/* setgid16 syscall holder */
+	.long sys_getgid		/* will be unused */
+	.long sys_ni_syscall		/* signal syscall holder */
+	.long sys_ni_syscall		/* geteuid16  syscall holder */
+	.long sys_ni_syscall		/* 50 - getegid16 syscall holder */
 	.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_fcntl			/* 55 - will be unused */
+	.long sys_ni_syscall		/* mpx syscall holder */
 	.long sys_setpgid
 	.long sys_ni_syscall		/* old ulimit syscall holder */
 	.long sys_ni_syscall		/* sys_olduname */
@@ -776,41 +776,41 @@
 	.long sys_getppid
 	.long sys_getpgrp		/* 65 */
 	.long sys_setsid
-	.long sys_sigaction
-	.long sys_sgetmask
-	.long sys_ssetmask
-	.long sys_setreuid		/* 70 */
-	.long sys_setregid
-	.long sys_sigsuspend
-	.long sys_sigpending
+	.long sys_ni_syscall		/* sigaction syscall holder */
+	.long sys_ni_syscall		/* sgetmask syscall holder */
+	.long sys_ni_syscall		/* ssetmask syscall holder */
+	.long sys_ni_syscall		/* 70 - setreuid16 syscall holder */
+	.long sys_ni_syscall		/* setregid16 syscall holder */
+	.long sys_ni_syscall		/* sigsuspend syscall holder */
+	.long sys_ni_syscall		/* sigpending syscall holder */
 	.long sys_sethostname
 	.long sys_setrlimit		/* 75 */
-	.long sys_getrlimit
+	.long sys_getrlimit/*will be unused*/
 	.long sys_getrusage
 	.long sys_gettimeofday
 	.long sys_settimeofday
-	.long sys_getgroups		/* 80 */
-	.long sys_setgroups
+	.long sys_ni_syscall		/* 80 - getgroups16 syscall holder */
+	.long sys_ni_syscall		/* setgroups16 syscall holder */
 	.long sys_ni_syscall		/* sys_oldselect */
 	.long sys_symlink
-	.long sys_lstat
+	.long sys_ni_syscall		/* old lstat syscall holder */
 	.long sys_readlink		/* 85 */
 	.long sys_uselib
 	.long sys_swapon
 	.long sys_reboot
-	.long old_readdir
+	.long sys_ni_syscall		/* readdir syscall holder */
 	.long sys_ni_syscall		/* 90 - old_mmap syscall holder */
 	.long sys_munmap
 	.long sys_truncate
 	.long sys_ftruncate
 	.long sys_fchmod
-	.long sys_fchown		/* 95 */
+	.long sys_ni_syscall		/* 95 - fchwon16  syscall holder */
 	.long sys_getpriority
 	.long sys_setpriority
 	.long sys_ni_syscall		/* old profil syscall holder */
 	.long sys_statfs
 	.long sys_fstatfs		/* 100 */
-	.long sys_ni_syscall		/* ioperm */
+	.long sys_ni_syscall		/* ioperm syscall holder */
 	.long sys_socketcall
 	.long sys_syslog
 	.long sys_setitimer
@@ -818,37 +818,37 @@
 	.long sys_newstat
 	.long sys_newlstat
 	.long sys_newfstat
-	.long sys_uname
-	.long sys_ni_syscall		/* 110  -  iopl */
+	.long sys_ni_syscall		/* old uname syscall holder */
+	.long sys_ni_syscall		/* 110  -  iopl syscall holder */
 	.long sys_vhangup
-	.long sys_ni_syscall		/* for idle */
-	.long sys_ni_syscall		/* for vm86old */
+	.long sys_ni_syscall		/* idle syscall holder */
+	.long sys_ni_syscall		/* vm86old syscall holder */
 	.long sys_wait4
 	.long sys_swapoff		/* 115 */
 	.long sys_sysinfo
 	.long sys_ipc
 	.long sys_fsync
-	.long sys_sigreturn
+	.long sys_ni_syscall		/* sigreturn syscall holder */
 	.long sys_clone			/* 120 */
 	.long sys_setdomainname
 	.long sys_newuname
-	.long sys_ni_syscall		/* sys_modify_ldt */
+	.long sys_ni_syscall		/* modify_ldt syscall holder */
 	.long sys_adjtimex
 	.long sys_mprotect		/* 125 */
-	.long sys_sigprocmask
-	.long sys_ni_syscall		/* sys_create_module */
+	.long sys_ni_syscall		/* sigprocmask syscall holder */
+	.long sys_ni_syscall		/* create_module syscall holder */
 	.long sys_init_module
 	.long sys_delete_module
-	.long sys_ni_syscall		/* 130 sys_get_kernel_syms */
+	.long sys_ni_syscall		/* 130 - 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_setfsuid
-	.long sys_setfsgid
+	.long sys_ni_syscall		/* afs_syscall syscall holder */
+	.long sys_ni_syscall		/* setfsuid16 syscall holder */
+	.long sys_ni_syscall		/* setfsgid16 syscall holder */
 	.long sys_llseek		/* 140 */
 	.long sys_getdents
 	.long sys_select
@@ -873,10 +873,10 @@
 	.long sys_sched_rr_get_interval
 	.long sys_nanosleep
 	.long sys_mremap
-	.long sys_setresuid
-	.long sys_getresuid		/* 165 */
-	.long sys_tas			/* vm86 */
-	.long sys_ni_syscall		/* sys_query_module */
+	.long sys_ni_syscall		/* setresuid16 syscall holder */
+	.long sys_ni_syscall		/* 165 - getresuid16 syscall holder */
+	.long sys_tas			/* vm86 syscall holder */
+	.long sys_ni_syscall		/* query_module syscall holder */
 	.long sys_poll
 	.long sys_nfsservctl
 	.long sys_setresgid		/* 170 */
@@ -891,7 +891,7 @@
 	.long sys_rt_sigsuspend
 	.long sys_pread64		/* 180 */
 	.long sys_pwrite64
-	.long sys_chown
+	.long sys_ni_syscall		/* chown16 syscall holder */
 	.long sys_getcwd
 	.long sys_capget
 	.long sys_capset		/* 185 */
diff -Nru a/arch/m32r/kernel/irq.c b/arch/m32r/kernel/irq.c
--- a/arch/m32r/kernel/irq.c	2005-03-01 23:38:57 -08:00
+++ b/arch/m32r/kernel/irq.c	2005-03-01 23:38:57 -08:00
@@ -1,9 +1,8 @@
 /*
  * linux/arch/m32r/kernel/irq.c
  *
- *  Copyright (c) 2003, 2004 Hitoshi Yamamoto
- *
- *  Taken from i386 2.6.4 version.
+ *  Copyright (c) 2003, 2004  Hitoshi Yamamoto
+ *  Copyright (c) 2004  Hirokazu Takata <takata at linux-m32r.org>
  */
 
 /*
@@ -11,112 +10,17 @@
  *
  *	Copyright (C) 1992, 1998 Linus Torvalds, Ingo Molnar
  *
- * This file contains the code used by various IRQ handling routines:
- * asking for different IRQ's should be done through these routines
- * instead of just grabbing them. Thus setups with different IRQ numbers
- * shouldn't result in any weird surprises, and installing new handlers
- * should be easier.
- */
-
-/*
- * (mostly architecture independent, will move to kernel/irq.c in 2.5.)
- *
- * IRQs are in fact implemented a bit like signal handlers for the kernel.
- * Naturally it's not a 1:1 relation, but there are similarities.
+ * This file contains the lowest level m32r-specific interrupt
+ * entry and irq statistics code. All the remaining irq logic is
+ * done by the generic kernel/irq/ code and in the
+ * m32r-specific irq controller code.
  */
 
-#include <linux/config.h>
-#include <linux/errno.h>
-#include <linux/module.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/ioport.h>
-#include <linux/interrupt.h>
-#include <linux/timex.h>
-#include <linux/slab.h>
-#include <linux/random.h>
-#include <linux/smp_lock.h>
-#include <linux/init.h>
 #include <linux/kernel_stat.h>
-#include <linux/irq.h>
-#include <linux/proc_fs.h>
+#include <linux/interrupt.h>
 #include <linux/seq_file.h>
-#include <linux/kallsyms.h>
-#include <linux/bitops.h>
-
-#include <asm/atomic.h>
-#include <asm/io.h>
-#include <asm/smp.h>
-#include <asm/system.h>
+#include <linux/module.h>
 #include <asm/uaccess.h>
-#include <asm/delay.h>
-#include <asm/irq.h>
-
-/*
- * Linux has a controller-independent x86 interrupt architecture.
- * every controller has a 'controller-template', that is used
- * by the main code to do the right thing. Each driver-visible
- * interrupt source is transparently wired to the apropriate
- * controller. Thus drivers need not be aware of the
- * interrupt-controller.
- *
- * Various interrupt controllers we handle: 8259 PIC, SMP IO-APIC,
- * PIIX4's internal 8259 PIC and SGI's Visual Workstation Cobalt (IO-)APIC.
- * (IO-APICs assumed to be messaging to Pentium local-APICs)
- *
- * the code is designed to be easily extended with new/different
- * interrupt controllers, without having to do assembly magic.
- */
-
-/*
- * Controller mappings for all interrupt sources:
- */
-irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned = {
-	[0 ... NR_IRQS-1] = {
-		.handler = &no_irq_type,
-		.lock = SPIN_LOCK_UNLOCKED
-	}
-};
-
-static void register_irq_proc (unsigned int irq);
-
-/*
- * Special irq handlers.
- */
-
-irqreturn_t no_action(int cpl, void *dev_id, struct pt_regs *regs)
-{ return IRQ_NONE; }
-
-/*
- * Generic no controller code
- */
-
-static void enable_none(unsigned int irq) { }
-static unsigned int startup_none(unsigned int irq) { return 0; }
-static void disable_none(unsigned int irq) { }
-static void ack_none(unsigned int irq)
-{
-/*
- * 'what should we do if we get a hw irq event on an illegal vector'.
- * each architecture has to answer this themselves, it doesn't deserve
- * a generic callback i think.
- */
-	printk("unexpected IRQ trap at vector %02x\n", irq);
-}
-
-/* startup is the same as "enable", shutdown is same as "disable" */
-#define shutdown_none	disable_none
-#define end_none	enable_none
-
-struct hw_interrupt_type no_irq_type = {
-	"none",
-	startup_none,
-	shutdown_none,
-	enable_none,
-	disable_none,
-	ack_none,
-	end_none
-};
 
 atomic_t irq_err_count;
 atomic_t irq_mis_count;
@@ -168,215 +72,6 @@
 	return 0;
 }
 
-#ifdef CONFIG_SMP
-inline void synchronize_irq(unsigned int irq)
-{
-	while (irq_desc[irq].status & IRQ_INPROGRESS)
-		cpu_relax();
-}
-#endif
-
-/*
- * This should really return information about whether
- * we should do bottom half handling etc. Right now we
- * end up _always_ checking the bottom half, which is a
- * waste of time and is not what some drivers would
- * prefer.
- */
-int handle_IRQ_event(unsigned int irq,
-		struct pt_regs *regs, struct irqaction *action)
-{
-	int status = 1;	/* Force the "do bottom halves" bit */
-	int ret, retval = 0;
-
-	if (!(action->flags & SA_INTERRUPT))
-		local_irq_enable();
-
-	do {
-		ret = action->handler(irq, action->dev_id, regs);
-		if (ret == IRQ_HANDLED)
-			status |= action->flags;
-		action = action->next;
-		retval |= ret;
-	} while (action);
-	if (status & SA_SAMPLE_RANDOM)
-		add_interrupt_randomness(irq);
-	local_irq_disable();
-	return retval;
-}
-
-static void __report_bad_irq(int irq, irq_desc_t *desc, irqreturn_t action_ret)
-{
-	struct irqaction *action;
-
-	if (action_ret != IRQ_HANDLED && action_ret != IRQ_NONE) {
-		printk(KERN_ERR "irq event %d: bogus return value %x\n",
-				irq, action_ret);
-	} else {
-		printk(KERN_ERR "irq %d: nobody cared!\n", irq);
-	}
-	dump_stack();
-	printk(KERN_ERR "handlers:\n");
-	action = desc->action;
-	do {
-		printk(KERN_ERR "[<%p>]", action->handler);
-		print_symbol(" (%s)",
-			(unsigned long)action->handler);
-		printk("\n");
-		action = action->next;
-	} while (action);
-}
-
-static void report_bad_irq(int irq, irq_desc_t *desc, irqreturn_t action_ret)
-{
-	static int count = 100;
-
-	if (count) {
-		count--;
-		__report_bad_irq(irq, desc, action_ret);
-	}
-}
-
-static int noirqdebug;
-
-static int __init noirqdebug_setup(char *str)
-{
-	noirqdebug = 1;
-	printk("IRQ lockup detection disabled\n");
-	return 1;
-}
-
-__setup("noirqdebug", noirqdebug_setup);
-
-/*
- * 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 and try to
- * turn the IRQ off.
- *
- * (The other 100-of-100,000 interrupts may have been a correctly-functioning
- *  device sharing an IRQ with the failing one)
- *
- * Called under desc->lock
- */
-static void note_interrupt(int irq, irq_desc_t *desc, irqreturn_t action_ret)
-{
-	if (action_ret != IRQ_HANDLED) {
-		desc->irqs_unhandled++;
-		if (action_ret != IRQ_NONE)
-			report_bad_irq(irq, desc, action_ret);
-	}
-
-	desc->irq_count++;
-	if (desc->irq_count < 100000)
-		return;
-
-	desc->irq_count = 0;
-	if (desc->irqs_unhandled > 99900) {
-		/*
-		 * The interrupt is stuck
-		 */
-		__report_bad_irq(irq, desc, action_ret);
-		/*
-		 * Now kill the IRQ
-		 */
-		printk(KERN_EMERG "Disabling IRQ #%d\n", irq);
-		desc->status |= IRQ_DISABLED;
-		desc->handler->disable(irq);
-	}
-	desc->irqs_unhandled = 0;
-}
-
-/*
- * Generic enable/disable code: this just calls
- * down into the PIC-specific version for the actual
- * hardware disable after having gotten the irq
- * controller lock.
- */
-
-/**
- *	disable_irq_nosync - disable an irq without waiting
- *	@irq: Interrupt to disable
- *
- *	Disable the selected interrupt line.  Disables and Enables are
- *	nested.
- *	Unlike disable_irq(), this function does not ensure existing
- *	instances of the IRQ handler have completed before returning.
- *
- *	This function may be called from IRQ context.
- */
-
-inline void disable_irq_nosync(unsigned int irq)
-{
-	irq_desc_t *desc = irq_desc + irq;
-	unsigned long flags;
-
-	spin_lock_irqsave(&desc->lock, flags);
-	if (!desc->depth++) {
-		desc->status |= IRQ_DISABLED;
-		desc->handler->disable(irq);
-	}
-	spin_unlock_irqrestore(&desc->lock, flags);
-}
-
-/**
- *	disable_irq - disable an irq and wait for completion
- *	@irq: Interrupt to disable
- *
- *	Disable the selected interrupt line.  Enables and Disables are
- *	nested.
- *	This function waits for any pending IRQ handlers for this interrupt
- *	to complete before returning. If you use this function while
- *	holding a resource the IRQ handler may need you will deadlock.
- *
- *	This function may be called - with care - from IRQ context.
- */
-
-void disable_irq(unsigned int irq)
-{
-	irq_desc_t *desc = irq_desc + irq;
-	disable_irq_nosync(irq);
-	if (desc->action)
-		synchronize_irq(irq);
-}
-
-/**
- *	enable_irq - enable handling of an irq
- *	@irq: Interrupt to enable
- *
- *	Undoes the effect of one call to disable_irq().  If this
- *	matches the last disable, processing of interrupts on this
- *	IRQ line is re-enabled.
- *
- *	This function may be called from IRQ context.
- */
-
-void enable_irq(unsigned int irq)
-{
-	irq_desc_t *desc = irq_desc + irq;
-	unsigned long flags;
-
-	spin_lock_irqsave(&desc->lock, flags);
-	switch (desc->depth) {
-	case 1: {
-		unsigned int status = desc->status & ~IRQ_DISABLED;
-		desc->status = status;
-		if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) {
-			desc->status = status | IRQ_REPLAY;
-			hw_resend_irq(desc->handler,irq);
-		}
-		desc->handler->enable(irq);
-		/* fall-through */
-	}
-	default:
-		desc->depth--;
-		break;
-	case 0:
-		printk("enable_irq(%u) unbalanced from %p\n", irq,
-		       __builtin_return_address(0));
-	}
-	spin_unlock_irqrestore(&desc->lock, flags);
-}
-
 /*
  * do_IRQ handles all normal device IRQ's (the special
  * SMP cross-CPU interrupts have their own specific
@@ -384,637 +79,13 @@
  */
 asmlinkage unsigned int do_IRQ(int irq, struct pt_regs *regs)
 {
-	/*
-	 * We ack quickly, we don't want the irq controller
-	 * thinking we're snobs just because some other CPU has
-	 * disabled global interrupts (we have already done the
-	 * INT_ACK cycles, it's too late to try to pretend to the
-	 * controller that we aren't taking the interrupt).
-	 *
-	 * 0 return value means that this irq is already being
-	 * handled by some other CPU. (or is disabled)
-	 */
-	irq_desc_t *desc = irq_desc + irq;
-	struct irqaction * action;
-	unsigned int status;
-
 	irq_enter();
 
 #ifdef CONFIG_DEBUG_STACKOVERFLOW
 	/* FIXME M32R */
 #endif
-	kstat_this_cpu.irqs[irq]++;
-	spin_lock(&desc->lock);
-	desc->handler->ack(irq);
-	/*
-	   REPLAY is when Linux resends an IRQ that was dropped earlier
-	   WAITING is used by probe to mark irqs that are being tested
-	   */
-	status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING);
-	status |= IRQ_PENDING; /* we _want_ to handle it */
-
-	/*
-	 * If the IRQ is disabled for whatever reason, we cannot
-	 * use the action we have.
-	 */
-	action = NULL;
-	if (likely(!(status & (IRQ_DISABLED | IRQ_INPROGRESS)))) {
-		action = desc->action;
-		status &= ~IRQ_PENDING; /* we commit to handling */
-		status |= IRQ_INPROGRESS; /* we are handling it */
-	}
-	desc->status = status;
-
-	/*
-	 * If there is no IRQ handler or it was disabled, exit early.
-	   Since we set PENDING, if another processor is handling
-	   a different instance of this same irq, the other processor
-	   will take care of it.
-	 */
-	if (unlikely(!action))
-		goto out;
-
-	/*
-	 * Edge triggered interrupts need to remember
-	 * pending events.
-	 * This applies to any hw interrupts that allow a second
-	 * instance of the same irq to arrive while we are in do_IRQ
-	 * or in the handler. But the code here only handles the _second_
-	 * instance of the irq, not the third or fourth. So it is mostly
-	 * useful for irq hardware that does not mask cleanly in an
-	 * SMP environment.
-	 */
-	for (;;) {
-		irqreturn_t action_ret;
-
-		spin_unlock(&desc->lock);
-		action_ret = handle_IRQ_event(irq, regs, action);
-		spin_lock(&desc->lock);
-		if (!noirqdebug)
-			note_interrupt(irq, desc, action_ret);
-		if (likely(!(desc->status & IRQ_PENDING)))
-			break;
-		desc->status &= ~IRQ_PENDING;
-	}
-	desc->status &= ~IRQ_INPROGRESS;
-
-out:
-	/*
-	 * The ->end() handler has to deal with interrupts which got
-	 * disabled while the handler was running.
-	 */
-	desc->handler->end(irq);
-	spin_unlock(&desc->lock);
-
+	__do_IRQ(irq, regs);
 	irq_exit();
 
-#if defined(CONFIG_SMP)
-	if (irq == M32R_IRQ_MFT2)
-		smp_send_timer();
-#endif	/* CONFIG_SMP */
-
 	return 1;
 }
-
-int can_request_irq(unsigned int irq, unsigned long irqflags)
-{
-	struct irqaction *action;
-
-	if (irq >= NR_IRQS)
-		return 0;
-	action = irq_desc[irq].action;
-	if (action) {
-		if (irqflags & action->flags & SA_SHIRQ)
-			action = NULL;
-	}
-	return !action;
-}
-
-/**
- *	request_irq - allocate an interrupt line
- *	@irq: Interrupt line to allocate
- *	@handler: Function to be called when the IRQ occurs
- *	@irqflags: Interrupt type flags
- *	@devname: An ascii name for the claiming device
- *	@dev_id: A cookie passed back to the handler function
- *
- *	This call allocates interrupt resources and enables the
- *	interrupt line and IRQ handling. From the point this
- *	call is made your handler function may be invoked. Since
- *	your handler function must clear any interrupt the board
- *	raises, you must take care both to initialise your hardware
- *	and to set up the interrupt handler in the right order.
- *
- *	Dev_id must be globally unique. Normally the address of the
- *	device data structure is used as the cookie. Since the handler
- *	receives this value it makes sense to use it.
- *
- *	If your interrupt is shared you must pass a non NULL dev_id
- *	as this is required when freeing the interrupt.
- *
- *	Flags:
- *
- *	SA_SHIRQ		Interrupt is shared
- *
- *	SA_INTERRUPT		Disable local interrupts while processing
- *
- *	SA_SAMPLE_RANDOM	The interrupt can be used for entropy
- *
- */
-
-int request_irq(unsigned int irq,
-		irqreturn_t (*handler)(int, void *, struct pt_regs *),
-		unsigned long irqflags,
-		const char * devname,
-		void *dev_id)
-{
-	int retval;
-	struct irqaction * action;
-
-#if 1
-	/*
-	 * Sanity-check: shared interrupts should REALLY pass in
-	 * a real dev-ID, otherwise we'll have trouble later trying
-	 * to figure out which interrupt is which (messes up the
-	 * interrupt freeing logic etc).
-	 */
-	if (irqflags & SA_SHIRQ) {
-		if (!dev_id)
-			printk("Bad boy: %s (at 0x%x) called us without a dev_id!\n", devname, (&irq)[-1]);
-	}
-#endif
-
-	if (irq >= NR_IRQS)
-		return -EINVAL;
-	if (!handler)
-		return -EINVAL;
-
-	action = (struct irqaction *)
-			kmalloc(sizeof(struct irqaction), GFP_ATOMIC);
-	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);
-
-/**
- *	free_irq - free an interrupt
- *	@irq: Interrupt line to free
- *	@dev_id: Device identity to free
- *
- *	Remove an interrupt handler. The handler is removed and if the
- *	interrupt line is no longer in use by any driver it is disabled.
- *	On a shared IRQ the caller must ensure the interrupt is disabled
- *	on the card it drives before calling this function. The function
- *	does not return until any executing interrupts for this IRQ
- *	have completed.
- *
- *	This function must not be called from interrupt context.
- */
-
-void free_irq(unsigned int irq, void *dev_id)
-{
-	irq_desc_t *desc;
-	struct irqaction **p;
-	unsigned long flags;
-
-	if (irq >= NR_IRQS)
-		return;
-
-	desc = irq_desc + irq;
-	spin_lock_irqsave(&desc->lock,flags);
-	p = &desc->action;
-	for (;;) {
-		struct irqaction * action = *p;
-		if (action) {
-			struct irqaction **pp = p;
-			p = &action->next;
-			if (action->dev_id != dev_id)
-				continue;
-
-			/* Found it - now remove it from the list of entries */
-			*pp = action->next;
-			if (!desc->action) {
-				desc->status |= IRQ_DISABLED;
-				desc->handler->shutdown(irq);
-			}
-			spin_unlock_irqrestore(&desc->lock,flags);
-
-			/* Wait to make sure it's not being used on another CPU */
-			synchronize_irq(irq);
-			kfree(action);
-			return;
-		}
-		printk("Trying to free free IRQ%d\n",irq);
-		spin_unlock_irqrestore(&desc->lock,flags);
-		return;
-	}
-}
-
-EXPORT_SYMBOL(free_irq);
-
-/*
- * IRQ autodetection code..
- *
- * This depends on the fact that any interrupt that
- * comes in on to an unassigned handler will get stuck
- * with "IRQ_WAITING" cleared and the interrupt
- * disabled.
- */
-
-static DECLARE_MUTEX(probe_sem);
-
-/**
- *	probe_irq_on	- begin an interrupt autodetect
- *
- *	Commence probing for an interrupt. The interrupts are scanned
- *	and a mask of potential interrupt lines is returned.
- *
- */
-
-unsigned long probe_irq_on(void)
-{
-	unsigned int i;
-	irq_desc_t *desc;
-	unsigned long val;
-	unsigned long delay;
-
-	down(&probe_sem);
-	/*
-	 * something may have generated an irq long ago and we want to
-	 * flush such a longstanding irq before considering it as spurious.
-	 */
-	for (i = NR_IRQS-1; i > 0; i--)  {
-		desc = irq_desc + i;
-
-		spin_lock_irq(&desc->lock);
-		if (!irq_desc[i].action)
-			irq_desc[i].handler->startup(i);
-		spin_unlock_irq(&desc->lock);
-	}
-
-	/* Wait for longstanding interrupts to trigger. */
-	for (delay = jiffies + HZ/50; time_after(delay, jiffies); )
-		/* about 20ms delay */ barrier();
-
-	/*
-	 * enable any unassigned irqs
-	 * (we must startup again here because if a longstanding irq
-	 * happened in the previous stage, it may have masked itself)
-	 */
-	for (i = NR_IRQS-1; i > 0; i--) {
-		desc = irq_desc + i;
-
-		spin_lock_irq(&desc->lock);
-		if (!desc->action) {
-			desc->status |= IRQ_AUTODETECT | IRQ_WAITING;
-			if (desc->handler->startup(i))
-				desc->status |= IRQ_PENDING;
-		}
-		spin_unlock_irq(&desc->lock);
-	}
-
-	/*
-	 * Wait for spurious interrupts to trigger
-	 */
-	for (delay = jiffies + HZ/10; time_after(delay, jiffies); )
-		/* about 100ms delay */ barrier();
-
-	/*
-	 * Now filter out any obviously spurious interrupts
-	 */
-	val = 0;
-	for (i = 0; i < NR_IRQS; i++) {
-		irq_desc_t *desc = irq_desc + i;
-		unsigned int status;
-
-		spin_lock_irq(&desc->lock);
-		status = desc->status;
-
-		if (status & IRQ_AUTODETECT) {
-			/* It triggered already - consider it spurious. */
-			if (!(status & IRQ_WAITING)) {
-				desc->status = status & ~IRQ_AUTODETECT;
-				desc->handler->shutdown(i);
-			} else
-				if (i < 32)
-					val |= 1 << i;
-		}
-		spin_unlock_irq(&desc->lock);
-	}
-
-	return val;
-}
-
-EXPORT_SYMBOL(probe_irq_on);
-
-/*
- * Return a mask of triggered interrupts (this
- * can handle only legacy ISA interrupts).
- */
-
-/**
- *	probe_irq_mask - scan a bitmap of interrupt lines
- *	@val:	mask of interrupts to consider
- *
- *	Scan the ISA bus interrupt lines and return a bitmap of
- *	active interrupts. The interrupt probe logic state is then
- *	returned to its previous value.
- *
- *	Note: we need to scan all the irq's even though we will
- *	only return ISA irq numbers - just so that we reset them
- *	all to a known state.
- */
-unsigned int probe_irq_mask(unsigned long val)
-{
-	int i;
-	unsigned int mask;
-
-	mask = 0;
-	for (i = 0; i < NR_IRQS; i++) {
-		irq_desc_t *desc = irq_desc + i;
-		unsigned int status;
-
-		spin_lock_irq(&desc->lock);
-		status = desc->status;
-
-		if (status & IRQ_AUTODETECT) {
-			if (i < 16 && !(status & IRQ_WAITING))
-				mask |= 1 << i;
-
-			desc->status = status & ~IRQ_AUTODETECT;
-			desc->handler->shutdown(i);
-		}
-		spin_unlock_irq(&desc->lock);
-	}
-	up(&probe_sem);
-
-	return mask & val;
-}
-
-/*
- * Return the one interrupt that triggered (this can
- * handle any interrupt source).
- */
-
-/**
- *	probe_irq_off	- end an interrupt autodetect
- *	@val: mask of potential interrupts (unused)
- *
- *	Scans the unused interrupt lines and returns the line which
- *	appears to have triggered the interrupt. If no interrupt was
- *	found then zero is returned. If more than one interrupt is
- *	found then minus the first candidate is returned to indicate
- *	their is doubt.
- *
- *	The interrupt probe logic state is returned to its previous
- *	value.
- *
- *	BUGS: When used in a module (which arguably shouldnt happen)
- *	nothing prevents two IRQ probe callers from overlapping. The
- *	results of this are non-optimal.
- */
-
-int probe_irq_off(unsigned long val)
-{
-	int i, irq_found, nr_irqs;
-
-	nr_irqs = 0;
-	irq_found = 0;
-	for (i = 0; i < NR_IRQS; i++) {
-		irq_desc_t *desc = irq_desc + i;
-		unsigned int status;
-
-		spin_lock_irq(&desc->lock);
-		status = desc->status;
-
-		if (status & IRQ_AUTODETECT) {
-			if (!(status & IRQ_WAITING)) {
-				if (!nr_irqs)
-					irq_found = i;
-				nr_irqs++;
-			}
-			desc->status = status & ~IRQ_AUTODETECT;
-			desc->handler->shutdown(i);
-		}
-		spin_unlock_irq(&desc->lock);
-	}
-	up(&probe_sem);
-
-	if (nr_irqs > 1)
-		irq_found = -irq_found;
-	return irq_found;
-}
-
-EXPORT_SYMBOL(probe_irq_off);
-
-/* this was setup_x86_irq but it seems pretty generic */
-int setup_irq(unsigned int irq, struct irqaction * new)
-{
-	int shared = 0;
-	unsigned long flags;
-	struct irqaction *old, **p;
-	irq_desc_t *desc = irq_desc + irq;
-
-	if (desc->handler == &no_irq_type)
-		return -ENOSYS;
-	/*
-	 * Some drivers like serial.c use request_irq() heavily,
-	 * so we have to be careful not to interfere with a
-	 * running system.
-	 */
-	if (new->flags & SA_SAMPLE_RANDOM) {
-		/*
-		 * This function might sleep, we want to call it first,
-		 * outside of the atomic block.
-		 * Yes, this might clear the entropy pool if the wrong
-		 * driver is attempted to be loaded, without actually
-		 * installing a new handler, but is this really a problem,
-		 * only the sysadmin is able to do this.
-		 */
-		rand_initialize_irq(irq);
-	}
-
-	/*
-	 * The following block of code has to be executed atomically
-	 */
-	spin_lock_irqsave(&desc->lock,flags);
-	p = &desc->action;
-	if ((old = *p) != NULL) {
-		/* Can't share interrupts unless both agree to */
-		if (!(old->flags & new->flags & SA_SHIRQ)) {
-			spin_unlock_irqrestore(&desc->lock,flags);
-			return -EBUSY;
-		}
-
-		/* add new interrupt at end of irq queue */
-		do {
-			p = &old->next;
-			old = *p;
-		} while (old);
-		shared = 1;
-	}
-
-	*p = new;
-
-	if (!shared) {
-		desc->depth = 0;
-		desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT | IRQ_WAITING | IRQ_INPROGRESS);
-		desc->handler->startup(irq);
-	}
-	spin_unlock_irqrestore(&desc->lock,flags);
-
-	register_irq_proc(irq);
-	return 0;
-}
-
-static struct proc_dir_entry * root_irq_dir;
-static struct proc_dir_entry * irq_dir [NR_IRQS];
-
-#ifdef CONFIG_SMP
-
-static struct proc_dir_entry *smp_affinity_entry[NR_IRQS];
-
-cpumask_t irq_affinity[NR_IRQS] = { [0 ... NR_IRQS-1] = CPU_MASK_ALL };
-
-static int irq_affinity_read_proc(char *page, char **start, off_t off,
-			int count, int *eof, void *data)
-{
-	int len = cpumask_scnprintf(page, count, irq_affinity[(long)data]);
-	if (count - len < 2)
-		return -EINVAL;
-	len += sprintf(page + len, "\n");
-	return len;
-}
-
-static int irq_affinity_write_proc(struct file *file, const char __user *buffer,
-					unsigned long count, void *data)
-{
-	int irq = (long)data, full_count = count, err;
-	cpumask_t new_value, tmp;
-
-	if (!irq_desc[irq].handler->set_affinity)
-		return -EIO;
-
-	err = cpumask_parse(buffer, count, new_value);
-	if (err)
-		return err;
-
-	/*
-	 * Do not allow disabling IRQs completely - it's a too easy
-	 * way to make the system unusable accidentally :-) At least
-	 * one online CPU still has to be targeted.
-	 */
-	cpus_and(tmp, new_value, cpu_online_map);
-	if (cpus_empty(tmp))
-		return -EINVAL;
-
-	irq_affinity[irq] = new_value;
-	irq_desc[irq].handler->set_affinity(irq,
-					cpumask_of_cpu(first_cpu(new_value)));
-
-	return full_count;
-}
-
-#endif
-
-static int prof_cpu_mask_read_proc (char *page, char **start, off_t off,
-			int count, int *eof, void *data)
-{
-	int len = cpumask_scnprintf(page, count, *(cpumask_t *)data);
-	if (count - len < 2)
-		return -EINVAL;
-	len += sprintf(page + len, "\n");
-	return len;
-}
-
-static int prof_cpu_mask_write_proc (struct file *file, const char __user *buffer,
-					unsigned long count, void *data)
-{
-	cpumask_t *mask = (cpumask_t *)data;
-	unsigned long full_count = count, err;
-	cpumask_t new_value;
-
-	err = cpumask_parse(buffer, count, new_value);
-	if (err)
-		return err;
-
-	*mask = new_value;
-	return full_count;
-}
-
-#define MAX_NAMELEN 10
-
-static void register_irq_proc (unsigned int irq)
-{
-	char name [MAX_NAMELEN];
-
-	if (!root_irq_dir || (irq_desc[irq].handler == &no_irq_type) ||
-			irq_dir[irq])
-		return;
-
-	memset(name, 0, MAX_NAMELEN);
-	sprintf(name, "%d", irq);
-
-	/* create /proc/irq/1234 */
-	irq_dir[irq] = proc_mkdir(name, root_irq_dir);
-
-#ifdef CONFIG_SMP
-	{
-		struct proc_dir_entry *entry;
-
-		/* create /proc/irq/1234/smp_affinity */
-		entry = create_proc_entry("smp_affinity", 0600, irq_dir[irq]);
-
-		if (entry) {
-			entry->nlink = 1;
-			entry->data = (void *)(long)irq;
-			entry->read_proc = irq_affinity_read_proc;
-			entry->write_proc = irq_affinity_write_proc;
-		}
-
-		smp_affinity_entry[irq] = entry;
-	}
-#endif
-}
-
-unsigned long prof_cpu_mask = -1;
-
-void init_irq_proc (void)
-{
-	struct proc_dir_entry *entry;
-	int i;
-
-	/* create /proc/irq */
-	root_irq_dir = proc_mkdir("irq", NULL);
-
-	/* create /proc/irq/prof_cpu_mask */
-	entry = create_proc_entry("prof_cpu_mask", 0600, root_irq_dir);
-
-	if (!entry)
-	    return;
-
-	entry->nlink = 1;
-	entry->data = (void *)&prof_cpu_mask;
-	entry->read_proc = prof_cpu_mask_read_proc;
-	entry->write_proc = prof_cpu_mask_write_proc;
-
-	/*
-	 * Create entries for all existing IRQs.
-	 */
-	for (i = 0; i < NR_IRQS; i++)
-		register_irq_proc(i);
-}
-
diff -Nru a/arch/m32r/kernel/process.c b/arch/m32r/kernel/process.c
--- a/arch/m32r/kernel/process.c	2005-03-01 23:39:18 -08:00
+++ b/arch/m32r/kernel/process.c	2005-03-01 23:39:18 -08:00
@@ -1,6 +1,5 @@
 /*
  *  linux/arch/m32r/kernel/process.c
- *    orig : sh
  *
  *  Copyright (c) 2001, 2002  Hiroyuki Kondo, Hirokazu Takata,
  *                            Hitoshi Yamamoto
@@ -290,13 +289,16 @@
 }
 
 asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
-	unsigned long r2, unsigned long r3, unsigned long r4, unsigned long r5,
-	unsigned long r6, struct pt_regs regs)
+			 unsigned long parent_tidptr,
+			 unsigned long child_tidptr,
+			 unsigned long r4, unsigned long r5, unsigned long r6,
+			 struct pt_regs regs)
 {
 	if (!newsp)
 		newsp = regs.spu;
 
-	return do_fork(clone_flags, newsp, &regs, 0, NULL, NULL);
+	return do_fork(clone_flags, newsp, &regs, 0,
+		       (int __user *)parent_tidptr, (int __user *)child_tidptr);
 }
 
 /*
@@ -320,9 +322,10 @@
 /*
  * sys_execve() executes a new program.
  */
-asmlinkage int sys_execve(char __user *ufilename, char __user * __user *uargv, char __user * __user *uenvp,
-  unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6,
-  struct pt_regs regs)
+asmlinkage int sys_execve(char __user *ufilename, char __user * __user *uargv,
+			  char __user * __user *uenvp,
+			  unsigned long r3, unsigned long r4, unsigned long r5,
+			  unsigned long r6, struct pt_regs regs)
 {
 	int error;
 	char *filename;
@@ -354,4 +357,3 @@
 	/* M32R_FIXME */
 	return (0);
 }
-
diff -Nru a/arch/m32r/kernel/ptrace.c b/arch/m32r/kernel/ptrace.c
--- a/arch/m32r/kernel/ptrace.c	2005-03-01 23:39:16 -08:00
+++ b/arch/m32r/kernel/ptrace.c	2005-03-01 23:39:16 -08:00
@@ -2,7 +2,7 @@
  * linux/arch/m32r/kernel/ptrace.c
  *
  * Copyright (C) 2002  Hirokazu Takata, Takeo Takahashi
- * Copyright (C) 2004  Hirokazu Takata <takata at linux-m32r.org>
+ * Copyright (C) 2004  Hirokazu Takata, Kei Sakamoto
  *
  * Original x86 implementation:
  *	By Ross Biro 1/23/92
@@ -130,7 +130,7 @@
 #ifndef NO_FPU
 		else if (off >= (long)(&dummy->fpu >> 2) &&
 			 off < (long)(&dummy->u_fpvalid >> 2)) {
-			if (!tsk->used_math) {
+			if (!tsk_used_math(tsk)) {
 				if (off == (long)(&dummy->fpu.fpscr >> 2))
 					tmp = FPSCR_INIT;
 				else
@@ -139,7 +139,7 @@
 				tmp = ((long *)(&tsk->thread.fpu >> 2))
 					[off - (long)&dummy->fpu];
 		} else if (off == (long)(&dummy->u_fpvalid >> 2))
-			tmp = tsk->used_math;
+			tmp = !!tsk_used_math(tsk);
 #endif /* not NO_FPU */
 		else
 			tmp = 0;
@@ -187,12 +187,12 @@
 #ifndef NO_FPU
 		else if (off >= (long)(&dummy->fpu >> 2) &&
 			 off < (long)(&dummy->u_fpvalid >> 2)) {
-			tsk->used_math = 1;
+			set_stopped_child_used_math(tsk);
 			((long *)&tsk->thread.fpu)
 				[off - (long)&dummy->fpu] = data;
 			ret = 0;
 		} else if (off == (long)(&dummy->u_fpvalid >> 2)) {
-			tsk->used_math = data ? 1 : 0;
+			conditional_stopped_child_used_math(data, tsk);
 			ret = 0;
 		}
 #endif /* not NO_FPU */
@@ -450,13 +450,13 @@
 	struct debug_trap *p = &child->thread.debug_trap;
 	unsigned long addr = next_pc & ~3;
 
-	if (p->nr_trap != 0) {
+	if (p->nr_trap == MAX_TRAPS) {
 		printk("kernel BUG at %s %d: p->nr_trap = %d\n",
 					__FILE__, __LINE__, p->nr_trap);
 		return -1;
 	}
-	p->addr = addr;
-	p->insn = next_insn;
+	p->addr[p->nr_trap] = addr;
+	p->insn[p->nr_trap] = next_insn;
 	p->nr_trap++;
 	if (next_pc & 3) {
 		*code = (next_insn & 0xffff0000) | 0x10f1;
@@ -473,35 +473,34 @@
 	return 0;
 }
 
-int withdraw_debug_trap_for_signal(struct task_struct *child)
-{
-	struct debug_trap *p = &child->thread.debug_trap;
-	int nr_trap = p->nr_trap;
-
-	if (nr_trap) {
-		access_process_vm(child, p->addr, &p->insn, sizeof(p->insn), 1);
-		p->nr_trap = 0;
-		p->addr = 0;
-		p->insn = 0;
-	}
-	return nr_trap;
-}
-
 static int
 unregister_debug_trap(struct task_struct *child, unsigned long addr,
 		      unsigned long *code)
 {
 	struct debug_trap *p = &child->thread.debug_trap;
+        int i;
 
-	if (p->nr_trap != 1 || p->addr != addr) {
+	/* Search debug trap entry. */
+	for (i = 0; i < p->nr_trap; i++) {
+		if (p->addr[i] == addr)
+			break;
+	}
+	if (i >= p->nr_trap) {
 		/* The trap may be requested from debugger.
 		 * ptrace should do nothing in this case.
 		 */
 		return 0;
 	}
-	*code = p->insn;
-	p->insn = 0;
-	p->addr = 0;
+
+	/* Recover orignal instruction code. */
+	*code = p->insn[i];
+
+	/* Shift debug trap entries. */
+	while (i < p->nr_trap - 1) {
+		p->insn[i] = p->insn[i + 1];
+		p->addr[i] = p->addr[i + 1];
+		i++;
+	}
 	p->nr_trap--;
 	return 1;
 }
@@ -510,13 +509,11 @@
 unregister_all_debug_traps(struct task_struct *child)
 {
 	struct debug_trap *p = &child->thread.debug_trap;
+	int i;
 
-	if (p->nr_trap) {
-		access_process_vm(child, p->addr, &p->insn, sizeof(p->insn), 1);
-		p->addr = 0;
-		p->insn = 0;
-		p->nr_trap = 0;
-	}
+	for (i = 0; i < p->nr_trap; i++)
+		access_process_vm(child, p->addr[i], &p->insn[i], sizeof(p->insn[i]), 1);
+	p->nr_trap = 0;
 }
 
 static inline void
@@ -576,34 +573,6 @@
 }
 
 void
-embed_debug_trap_for_signal(struct task_struct *child)
-{
-	unsigned long next_pc;
-	unsigned long pc, insn;
-	int ret;
-
-	pc = get_stack_long(child, PT_BPC);
-	ret = access_process_vm(child, pc&~3, &insn, sizeof(insn), 0);
-	if (ret != sizeof(insn)) {
-		printk("kernel BUG at %s %d: access_process_vm returns %d\n",
-		       __FILE__, __LINE__, ret);
-		return;
-	}
-	compute_next_pc(insn, pc, &next_pc, child);
-	if (next_pc & 0x80000000) {
-		printk("kernel BUG at %s %d: next_pc = 0x%08x\n",
-		       __FILE__, __LINE__, (int)next_pc);
-		return;
-	}
-	if (embed_debug_trap(child, next_pc)) {
-		printk("kernel BUG at %s %d: embed_debug_trap error\n",
-		       __FILE__, __LINE__);
-		return;
-	}
-	invalidate_cache();
-}
-
-void
 withdraw_debug_trap(struct pt_regs *regs)
 {
 	unsigned long addr;
@@ -621,9 +590,12 @@
 init_debug_traps(struct task_struct *child)
 {
 	struct debug_trap *p = &child->thread.debug_trap;
+	int i;
 	p->nr_trap = 0;
-	p->addr = 0;
-	p->insn = 0;
+	for (i = 0; i < MAX_TRAPS; i++) {
+		p->addr[i] = 0;
+		p->insn[i] = 0;
+	}
 }
 
 
@@ -855,4 +827,3 @@
 		current->exit_code = 0;
 	}
 }
-
diff -Nru a/arch/m32r/kernel/setup.c b/arch/m32r/kernel/setup.c
--- a/arch/m32r/kernel/setup.c	2005-03-01 23:38:57 -08:00
+++ b/arch/m32r/kernel/setup.c	2005-03-01 23:38:57 -08:00
@@ -251,7 +251,9 @@
 #endif
 
 #ifdef CONFIG_DISCONTIGMEM
-	numnodes = 2;
+	nodes_clear(node_online_map);
+	node_set_online(0);
+	node_set_online(1);
 #endif	/* CONFIG_DISCONTIGMEM */
 
 	init_mm.start_code = (unsigned long) _text;
@@ -389,7 +391,7 @@
 
 	/* Force FPU initialization */
 	current_thread_info()->status = 0;
-	current->used_math = 0;
+	clear_used_math();
 
 #ifdef CONFIG_MMU
 	/* Set up MMU */
diff -Nru a/arch/m32r/kernel/signal.c b/arch/m32r/kernel/signal.c
--- a/arch/m32r/kernel/signal.c	2005-03-01 23:38:56 -08:00
+++ b/arch/m32r/kernel/signal.c	2005-03-01 23:38:56 -08:00
@@ -33,32 +33,6 @@
 
 int do_signal(struct pt_regs *, sigset_t *);
 
-/*
- * Atomically swap in the new signal mask, and wait for a signal.
- */
-asmlinkage int
-sys_sigsuspend(old_sigset_t mask, unsigned long r1,
-	       unsigned long r2, unsigned long r3, unsigned long r4,
-	       unsigned long r5, unsigned long r6, 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.r0 = -EINTR;
-	while (1) {
-		current->state = TASK_INTERRUPTIBLE;
-		schedule();
-		if (do_signal(&regs, &saveset))
-			return regs.r0;
-	}
-}
-
 asmlinkage int
 sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize,
 		  unsigned long r2, unsigned long r3, unsigned long r4,
@@ -90,38 +64,6 @@
 }
 
 asmlinkage int
-sys_sigaction(int sig, const struct old_sigaction __user *act,
-	      struct old_sigaction __user *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(const stack_t __user *uss, stack_t __user *uoss,
 		unsigned long r2, unsigned long r3, unsigned long r4,
 		unsigned long r5, unsigned long r6, struct pt_regs regs)
@@ -134,26 +76,14 @@
  * Do a signal return; undo the signal stack.
  */
 
-struct sigframe
-{
-//	char *pretcode;
-	int sig;
-	struct sigcontext sc;
-//	struct _fpstate fpstate;
-	unsigned long extramask[_NSIG_WORDS-1];
-	char retcode[4];
-};
-
 struct rt_sigframe
 {
-//	char *pretcode;
 	int sig;
 	struct siginfo *pinfo;
 	void *puc;
 	struct siginfo info;
 	struct ucontext uc;
 //	struct _fpstate fpstate;
-	char retcode[8];
 };
 
 static int
@@ -208,38 +138,6 @@
 }
 
 asmlinkage int
-sys_sigreturn(unsigned long r0, unsigned long r1,
-	      unsigned long r2, unsigned long r3, unsigned long r4,
-	      unsigned long r5, unsigned long r6, struct pt_regs regs)
-{
-	struct sigframe __user *frame = (struct sigframe __user *)regs.spu;
-	sigset_t set;
-	int result;
-
-	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, &result))
-		goto badframe;
-	return result;
-
-badframe:
-	force_sig(SIGSEGV, current);
-	return 0;
-}
-
-asmlinkage int
 sys_rt_sigreturn(unsigned long r0, unsigned long r1,
 		 unsigned long r2, unsigned long r3, unsigned long r4,
 		 unsigned long r5, unsigned long r6, struct pt_regs regs)
@@ -342,71 +240,6 @@
 	return (void __user *)((sp - frame_size) & -8ul);
 }
 
-static void setup_frame(int sig, struct k_sigaction *ka,
-			sigset_t *set, struct pt_regs *regs)
-{
-	struct sigframe __user *frame;
-	int err = 0;
-	int signal;
-
-	frame = get_sigframe(ka, regs->spu, sizeof(*frame));
-
-	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 |= __put_user(signal, &frame->sig);
-	if (err)
-		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;
-	}
-
-	if (ka->sa.sa_flags & SA_RESTORER)
-		regs->lr = (unsigned long)ka->sa.sa_restorer;
-	else {
-		/* This is : ldi r7, #__NR_sigreturn ; trap #2 */
-		unsigned long code = 0x670010f2 | (__NR_sigreturn << 16);
-
-		regs->lr = (unsigned long)frame->retcode;
-		err |= __put_user(code, (long __user *)(frame->retcode+0));
-		if (err)
-			goto give_sigsegv;
-		flush_cache_sigtramp((unsigned long)frame->retcode);
-	}
-
-	/* Set up registers for signal handler */
-	regs->spu = (unsigned long)frame;
-	regs->r0 = signal;	/* Arg for signal handler */
-	regs->r1 = (unsigned long)&frame->sc;
-	regs->bpc = (unsigned long)ka->sa.sa_handler;
-
-	set_fs(USER_DS);
-
-#if DEBUG_SIG
-	printk("SIG deliver (%s:%d): sp=%p pc=%p\n",
-		current->comm, current->pid, frame, regs->pc);
-#endif
-
-	return;
-
-give_sigsegv:
-	force_sigsegv(sig, current);
-}
-
 static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
 			   sigset_t *set, struct pt_regs *regs)
 {
@@ -448,20 +281,7 @@
 		goto give_sigsegv;
 
 	/* Set up to return from userspace.  */
-	if (ka->sa.sa_flags & SA_RESTORER)
-		regs->lr = (unsigned long)ka->sa.sa_restorer;
-	else {
-		/* This is : ldi r7, #__NR_rt_sigreturn ; trap #2 */
-		unsigned long code1 = 0x97f00000 | (__NR_rt_sigreturn);
-		unsigned long code2 = 0x10f2f000;
-
-		regs->lr = (unsigned long)frame->retcode;
-		err |= __put_user(code1, (long __user *)(frame->retcode+0));
-		err |= __put_user(code2, (long __user *)(frame->retcode+4));
-		if (err)
-			goto give_sigsegv;
-		flush_cache_sigtramp((unsigned long)frame->retcode);
-	}
+	regs->lr = (unsigned long)ka->sa.sa_restorer;
 
 	/* Set up registers for signal handler */
 	regs->spu = (unsigned long)frame;
@@ -519,10 +339,7 @@
 	}
 
 	/* 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);
+	setup_rt_frame(sig, ka, info, oldset, regs);
 
 	if (!(ka->sa.sa_flags & SA_NODEFER)) {
 		spin_lock_irq(&current->sighand->siglock);
diff -Nru a/arch/m32r/kernel/smp.c b/arch/m32r/kernel/smp.c
--- a/arch/m32r/kernel/smp.c	2005-03-01 23:39:18 -08:00
+++ b/arch/m32r/kernel/smp.c	2005-03-01 23:39:18 -08:00
@@ -38,7 +38,7 @@
  * Structure and data for smp_call_function(). This is designed to minimise
  * static memory requirements. It also looks cleaner.
  */
-static spinlock_t call_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(call_lock);
 
 struct call_data_struct {
 	void (*func) (void *info);
@@ -53,7 +53,7 @@
 /*
  * For flush_cache_all()
  */
-static spinlock_t flushcache_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(flushcache_lock);
 static volatile unsigned long flushcache_cpumask = 0;
 
 /*
@@ -63,7 +63,7 @@
 static struct mm_struct *flush_mm;
 static struct vm_area_struct *flush_vma;
 static volatile unsigned long flush_va;
-static spinlock_t tlbstate_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(tlbstate_lock);
 #define FLUSH_ALL 0xffffffff
 
 DECLARE_PER_CPU(int, prof_multiplier);
@@ -953,7 +953,7 @@
 		"ldi	r4, #1			\n\t"
 		"st	r4, @%2			\n\t"
 		: "=&r"(ipicr_val)
-		: "r"(flags), "r"(&ipilock->lock), "r"(ipicr_addr),
+		: "r"(flags), "r"(&ipilock->slock), "r"(ipicr_addr),
 		  "r"(mask), "r"(try), "r"(my_physid_mask)
 		: "memory", "r4"
 #ifdef CONFIG_CHIP_M32700_TS1
diff -Nru a/arch/m32r/kernel/smpboot.c b/arch/m32r/kernel/smpboot.c
--- a/arch/m32r/kernel/smpboot.c	2005-03-01 23:39:18 -08:00
+++ b/arch/m32r/kernel/smpboot.c	2005-03-01 23:39:18 -08:00
@@ -58,7 +58,6 @@
 #define Dprintk(x...)
 #endif
 
-extern int cpu_idle(void);
 extern cpumask_t cpu_initialized;
 
 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
@@ -248,7 +247,7 @@
 	int ipi;
 
 	for (ipi = 0 ; ipi < NR_IPIS ; ipi++)
-		ipi_lock[ipi] = SPIN_LOCK_UNLOCKED;
+		spin_lock_init(&ipi_lock[ipi]);
 }
 
 /*==========================================================================*
@@ -443,7 +442,8 @@
 	 */
 	local_flush_tlb_all();
 
-	return cpu_idle();
+	cpu_idle();
+	return 0;
 }
 
 /*==========================================================================*
diff -Nru a/arch/m32r/kernel/sys_m32r.c b/arch/m32r/kernel/sys_m32r.c
--- a/arch/m32r/kernel/sys_m32r.c	2005-03-01 23:39:18 -08:00
+++ b/arch/m32r/kernel/sys_m32r.c	2005-03-01 23:39:18 -08:00
@@ -48,7 +48,7 @@
 #else /* CONFIG_SMP */
 #include <linux/spinlock.h>
 
-static spinlock_t tas_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(tas_lock);
 
 asmlinkage int sys_tas(int *addr)
 {
diff -Nru a/arch/m32r/kernel/traps.c b/arch/m32r/kernel/traps.c
--- a/arch/m32r/kernel/traps.c	2005-03-01 23:38:56 -08:00
+++ b/arch/m32r/kernel/traps.c	2005-03-01 23:38:56 -08:00
@@ -223,7 +223,7 @@
 	printk("\n");
 }
 
-spinlock_t die_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(die_lock);
 
 void die(const char * str, struct pt_regs * regs, long err)
 {
diff -Nru a/arch/m32r/lib/csum_partial_copy.c b/arch/m32r/lib/csum_partial_copy.c
--- a/arch/m32r/lib/csum_partial_copy.c	2005-03-01 23:38:44 -08:00
+++ b/arch/m32r/lib/csum_partial_copy.c	2005-03-01 23:38:44 -08:00
@@ -3,16 +3,16 @@
  *		operating system.  INET is implemented using the  BSD Socket
  *		interface as the means of communication with the user level.
  *
- *		MIPS specific IP/TCP/UDP checksumming routines
+ *		M32R specific IP/TCP/UDP checksumming routines
+ *		(Some code taken from MIPS architecture)
  *
- * Authors:	Ralf Baechle, <ralf@waldorf-gmbh.de>
- *		Lots of code moved from tcp.c and ip.c; see those files
- *		for more names.
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
  *
- *		This program is free software; you can redistribute it and/or
- *		modify it under the terms of the 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) 1994, 1995  Waldorf Electronics GmbH
+ * Copyright (C) 1998, 1999  Ralf Baechle
+ * Copyright (C) 2001-2005  Hiroyuki Kondo, Hirokazu Takata
  *
  */
 
@@ -27,8 +27,9 @@
 /*
  * Copy while checksumming, otherwise like csum_partial
  */
-unsigned int csum_partial_copy_nocheck (const char *src, char *dst,
-                                        int len, unsigned int sum)
+unsigned int
+csum_partial_copy_nocheck (const unsigned char *src, unsigned char *dst,
+                           int len, unsigned int sum)
 {
 	sum = csum_partial(src, len, sum);
 	memcpy(dst, src, len);
@@ -41,9 +42,10 @@
  * 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 char __user *src, char *dst,
-                                          int len, unsigned int sum,
-                                          int *err_ptr)
+unsigned int
+csum_partial_copy_from_user (const unsigned char __user *src,
+			     unsigned char *dst,
+			     int len, unsigned int sum, int *err_ptr)
 {
 	int missing;
 
diff -Nru a/arch/m32r/m32700ut/defconfig.m32700ut.smp b/arch/m32r/m32700ut/defconfig.m32700ut.smp
--- a/arch/m32r/m32700ut/defconfig.m32700ut.smp	2005-03-01 23:38:58 -08:00
+++ b/arch/m32r/m32700ut/defconfig.m32700ut.smp	2005-03-01 23:38:58 -08:00
@@ -1,11 +1,13 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc1-bk21
-# Fri Nov 12 16:08:45 2004
+# Linux kernel version: 2.6.11-rc4
+# Wed Feb 16 21:10:50 2005
 #
 CONFIG_M32R=y
-CONFIG_UID16=y
+# CONFIG_UID16 is not set
 CONFIG_GENERIC_ISA_DMA=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
 
 #
 # Code maturity level options
@@ -81,6 +83,7 @@
 # CONFIG_DISCONTIGMEM is not set
 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
@@ -99,7 +102,6 @@
 #
 CONFIG_PCCARD=y
 # CONFIG_PCMCIA_DEBUG is not set
-# CONFIG_PCMCIA_OBSOLETE is not set
 CONFIG_PCMCIA=y
 
 #
@@ -149,10 +151,12 @@
 # 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=y
 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=""
@@ -165,6 +169,7 @@
 # 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
@@ -222,12 +227,12 @@
 #
 # CONFIG_SCSI_SPI_ATTRS is not set
 # CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
 
 #
 # SCSI low-level drivers
 #
 # CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_QLOGIC_1280_1040 is not set
 # CONFIG_SCSI_DEBUG is not set
 
 #
@@ -399,6 +404,7 @@
 # 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
 
 #
@@ -453,7 +459,6 @@
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_AGP is not set
 # CONFIG_DRM is not set
 
 #
@@ -527,6 +532,7 @@
 CONFIG_LOGO_LINUX_MONO=y
 CONFIG_LOGO_LINUX_VGA16=y
 CONFIG_LOGO_LINUX_CLUT224=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -540,11 +546,25 @@
 # 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=y
@@ -561,6 +581,10 @@
 # CONFIG_REISERFS_PROC_INFO is not set
 # CONFIG_REISERFS_FS_XATTR 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
@@ -631,7 +655,6 @@
 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
@@ -700,7 +723,8 @@
 # Kernel hacking
 #
 # CONFIG_DEBUG_KERNEL is not set
-# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+CONFIG_DEBUG_PREEMPT=y
+# CONFIG_DEBUG_BUGVERBOSE is not set
 # CONFIG_FRAME_POINTER is not set
 
 #
@@ -713,6 +737,10 @@
 # Cryptographic options
 #
 # CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
 
 #
 # Library routines
diff -Nru a/arch/m32r/m32700ut/defconfig.m32700ut.up b/arch/m32r/m32700ut/defconfig.m32700ut.up
--- a/arch/m32r/m32700ut/defconfig.m32700ut.up	2005-03-01 23:39:07 -08:00
+++ b/arch/m32r/m32700ut/defconfig.m32700ut.up	2005-03-01 23:39:07 -08:00
@@ -1,11 +1,13 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc1-bk21
-# Fri Nov 12 16:08:49 2004
+# Linux kernel version: 2.6.11-rc4
+# Wed Feb 16 21:10:54 2005
 #
 CONFIG_M32R=y
-CONFIG_UID16=y
+# CONFIG_UID16 is not set
 CONFIG_GENERIC_ISA_DMA=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
 
 #
 # Code maturity level options
@@ -81,6 +83,7 @@
 # CONFIG_DISCONTIGMEM is not set
 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 is not set
@@ -96,7 +99,6 @@
 #
 CONFIG_PCCARD=y
 # CONFIG_PCMCIA_DEBUG is not set
-# CONFIG_PCMCIA_OBSOLETE is not set
 CONFIG_PCMCIA=y
 
 #
@@ -146,10 +148,12 @@
 # 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=y
 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=""
@@ -162,6 +166,7 @@
 # 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
@@ -219,12 +224,12 @@
 #
 # CONFIG_SCSI_SPI_ATTRS is not set
 # CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
 
 #
 # SCSI low-level drivers
 #
 # CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_QLOGIC_1280_1040 is not set
 # CONFIG_SCSI_DEBUG is not set
 
 #
@@ -396,6 +401,7 @@
 # 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
 
 #
@@ -450,7 +456,6 @@
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_AGP is not set
 # CONFIG_DRM is not set
 
 #
@@ -524,6 +529,7 @@
 CONFIG_LOGO_LINUX_MONO=y
 CONFIG_LOGO_LINUX_VGA16=y
 CONFIG_LOGO_LINUX_CLUT224=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -537,11 +543,25 @@
 # 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=y
@@ -558,6 +578,10 @@
 # CONFIG_REISERFS_PROC_INFO is not set
 # CONFIG_REISERFS_FS_XATTR 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
@@ -628,7 +652,6 @@
 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
@@ -697,7 +720,8 @@
 # Kernel hacking
 #
 # CONFIG_DEBUG_KERNEL is not set
-# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+CONFIG_DEBUG_PREEMPT=y
+# CONFIG_DEBUG_BUGVERBOSE is not set
 # CONFIG_FRAME_POINTER is not set
 
 #
@@ -710,6 +734,10 @@
 # Cryptographic options
 #
 # CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
 
 #
 # Library routines
diff -Nru a/arch/m32r/mappi/defconfig.nommu b/arch/m32r/mappi/defconfig.nommu
--- a/arch/m32r/mappi/defconfig.nommu	2005-03-01 23:39:17 -08:00
+++ b/arch/m32r/mappi/defconfig.nommu	2005-03-01 23:39:17 -08:00
@@ -1,11 +1,13 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc1-bk21
-# Fri Nov 12 16:08:51 2004
+# Linux kernel version: 2.6.11-rc4
+# Wed Feb 16 21:10:57 2005
 #
 CONFIG_M32R=y
-CONFIG_UID16=y
+# CONFIG_UID16 is not set
 CONFIG_GENERIC_ISA_DMA=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
 
 #
 # Code maturity level options
@@ -34,12 +36,11 @@
 # 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_TINY_SHMEM=y
 
 #
 # Loadable module support
@@ -79,6 +80,7 @@
 # CONFIG_DISCONTIGMEM is not set
 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 is not set
@@ -94,7 +96,6 @@
 #
 CONFIG_PCCARD=y
 # CONFIG_PCMCIA_DEBUG is not set
-# CONFIG_PCMCIA_OBSOLETE is not set
 CONFIG_PCMCIA=y
 
 #
@@ -144,10 +145,12 @@
 # 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=y
 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=""
@@ -160,6 +163,7 @@
 # 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
@@ -329,6 +333,7 @@
 # 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
 
 #
@@ -380,7 +385,6 @@
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_AGP is not set
 # CONFIG_DRM is not set
 
 #
@@ -430,11 +434,25 @@
 # 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=y
@@ -443,6 +461,10 @@
 # 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
@@ -468,7 +490,6 @@
 # Pseudo filesystems
 #
 CONFIG_PROC_FS=y
-CONFIG_PROC_KCORE=y
 CONFIG_SYSFS=y
 CONFIG_DEVFS_FS=y
 CONFIG_DEVFS_MOUNT=y
@@ -507,7 +528,6 @@
 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
@@ -576,7 +596,8 @@
 # Kernel hacking
 #
 # CONFIG_DEBUG_KERNEL is not set
-# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+CONFIG_DEBUG_PREEMPT=y
+# CONFIG_DEBUG_BUGVERBOSE is not set
 # CONFIG_FRAME_POINTER is not set
 
 #
@@ -589,6 +610,10 @@
 # Cryptographic options
 #
 # CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
 
 #
 # Library routines
diff -Nru a/arch/m32r/mappi/defconfig.smp b/arch/m32r/mappi/defconfig.smp
--- a/arch/m32r/mappi/defconfig.smp	2005-03-01 23:38:59 -08:00
+++ b/arch/m32r/mappi/defconfig.smp	2005-03-01 23:38:59 -08:00
@@ -1,11 +1,13 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc1-bk21
-# Fri Nov 12 16:08:53 2004
+# Linux kernel version: 2.6.11-rc4
+# Wed Feb 16 21:11:02 2005
 #
 CONFIG_M32R=y
-CONFIG_UID16=y
+# CONFIG_UID16 is not set
 CONFIG_GENERIC_ISA_DMA=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
 
 #
 # Code maturity level options
@@ -84,6 +86,7 @@
 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
@@ -102,7 +105,6 @@
 #
 CONFIG_PCCARD=y
 # CONFIG_PCMCIA_DEBUG is not set
-# CONFIG_PCMCIA_OBSOLETE is not set
 CONFIG_PCMCIA=y
 
 #
@@ -140,6 +142,7 @@
 CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_CONCAT is not set
 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
@@ -185,6 +188,7 @@
 # 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
@@ -211,10 +215,12 @@
 # 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=""
@@ -227,6 +233,7 @@
 # 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
@@ -421,6 +428,7 @@
 # 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
 
 #
@@ -472,7 +480,6 @@
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_AGP is not set
 # CONFIG_DRM is not set
 
 #
@@ -522,11 +529,25 @@
 # 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=y
@@ -535,6 +556,10 @@
 # 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
@@ -593,6 +618,7 @@
 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
@@ -615,7 +641,6 @@
 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
@@ -684,7 +709,8 @@
 # Kernel hacking
 #
 # CONFIG_DEBUG_KERNEL is not set
-# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+CONFIG_DEBUG_PREEMPT=y
+# CONFIG_DEBUG_BUGVERBOSE is not set
 # CONFIG_FRAME_POINTER is not set
 
 #
@@ -697,6 +723,10 @@
 # Cryptographic options
 #
 # CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
 
 #
 # Library routines
diff -Nru a/arch/m32r/mappi/defconfig.up b/arch/m32r/mappi/defconfig.up
--- a/arch/m32r/mappi/defconfig.up	2005-03-01 23:38:55 -08:00
+++ b/arch/m32r/mappi/defconfig.up	2005-03-01 23:38:55 -08:00
@@ -1,11 +1,13 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc1-bk21
-# Fri Nov 12 16:08:55 2004
+# Linux kernel version: 2.6.11-rc4
+# Wed Feb 16 21:11:07 2005
 #
 CONFIG_M32R=y
-CONFIG_UID16=y
+# CONFIG_UID16 is not set
 CONFIG_GENERIC_ISA_DMA=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
 
 #
 # Code maturity level options
@@ -83,6 +85,7 @@
 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 is not set
@@ -98,7 +101,6 @@
 #
 CONFIG_PCCARD=y
 # CONFIG_PCMCIA_DEBUG is not set
-# CONFIG_PCMCIA_OBSOLETE is not set
 CONFIG_PCMCIA=y
 
 #
@@ -136,6 +138,7 @@
 CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_CONCAT is not set
 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
@@ -181,6 +184,7 @@
 # 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
@@ -207,10 +211,12 @@
 # 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=""
@@ -223,6 +229,7 @@
 # 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
@@ -417,6 +424,7 @@
 # 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
 
 #
@@ -468,7 +476,6 @@
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_AGP is not set
 # CONFIG_DRM is not set
 
 #
@@ -518,11 +525,25 @@
 # 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=y
@@ -531,6 +552,10 @@
 # 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
@@ -589,6 +614,7 @@
 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
@@ -611,7 +637,6 @@
 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
@@ -680,7 +705,8 @@
 # Kernel hacking
 #
 # CONFIG_DEBUG_KERNEL is not set
-# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+CONFIG_DEBUG_PREEMPT=y
+# CONFIG_DEBUG_BUGVERBOSE is not set
 # CONFIG_FRAME_POINTER is not set
 
 #
@@ -693,6 +719,10 @@
 # Cryptographic options
 #
 # CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
 
 #
 # Library routines
diff -Nru a/arch/m32r/mappi2/defconfig.vdec2 b/arch/m32r/mappi2/defconfig.vdec2
--- a/arch/m32r/mappi2/defconfig.vdec2	2005-03-01 23:39:17 -08:00
+++ b/arch/m32r/mappi2/defconfig.vdec2	2005-03-01 23:39:17 -08:00
@@ -1,11 +1,13 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc1-bk21
-# Fri Nov 12 16:08:58 2004
+# Linux kernel version: 2.6.11-rc4
+# Wed Feb 16 21:11:10 2005
 #
 CONFIG_M32R=y
-CONFIG_UID16=y
+# CONFIG_UID16 is not set
 CONFIG_GENERIC_ISA_DMA=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
 
 #
 # Code maturity level options
@@ -79,6 +81,7 @@
 # CONFIG_DISCONTIGMEM is not set
 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 is not set
@@ -94,7 +97,6 @@
 #
 CONFIG_PCCARD=y
 # CONFIG_PCMCIA_DEBUG is not set
-# CONFIG_PCMCIA_OBSOLETE is not set
 CONFIG_PCMCIA=y
 
 #
@@ -142,10 +144,12 @@
 # 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=y
 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=""
@@ -158,6 +162,7 @@
 # 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
@@ -215,12 +220,12 @@
 #
 # CONFIG_SCSI_SPI_ATTRS is not set
 # CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
 
 #
 # SCSI low-level drivers
 #
 # CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_QLOGIC_1280_1040 is not set
 # CONFIG_SCSI_DEBUG is not set
 
 #
@@ -392,6 +397,7 @@
 # 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
 
 #
@@ -445,7 +451,6 @@
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_AGP is not set
 # CONFIG_DRM is not set
 
 #
@@ -516,11 +521,25 @@
 # 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=y
@@ -537,6 +556,10 @@
 # CONFIG_REISERFS_PROC_INFO is not set
 # CONFIG_REISERFS_FS_XATTR 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
@@ -607,7 +630,6 @@
 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
@@ -676,7 +698,8 @@
 # Kernel hacking
 #
 # CONFIG_DEBUG_KERNEL is not set
-# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+CONFIG_DEBUG_PREEMPT=y
+# CONFIG_DEBUG_BUGVERBOSE is not set
 # CONFIG_FRAME_POINTER is not set
 
 #
@@ -689,6 +712,10 @@
 # Cryptographic options
 #
 # CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
 
 #
 # Library routines
diff -Nru a/arch/m32r/mm/discontig.c b/arch/m32r/mm/discontig.c
--- a/arch/m32r/mm/discontig.c	2005-03-01 23:38:52 -08:00
+++ b/arch/m32r/mm/discontig.c	2005-03-01 23:38:52 -08:00
@@ -75,7 +75,7 @@
 
 	mem_prof_init();
 
-	for (nid = 0 ; nid < numnodes ; nid++) {
+	for_each_online_node(nid) {
 		mp = &mem_prof[nid];
 		NODE_DATA(nid)=(pg_data_t *)&m32r_node_data[nid];
 		NODE_DATA(nid)->bdata = &node_bdata[nid];
@@ -135,12 +135,12 @@
 	mem_prof_t *mp;
 
 	pgdat_list = NULL;
-	for (nid = numnodes - 1 ; nid >= 0 ; nid--) {
+	for (nid = num_online_nodes() - 1 ; nid >= 0 ; nid--) {
 		NODE_DATA(nid)->pgdat_next = pgdat_list;
 		pgdat_list = NODE_DATA(nid);
 	}
 
-	for (nid = 0 ; nid < numnodes ; nid++) {
+	for_each_online_node(nid) {
 		mp = &mem_prof[nid];
 		for (i = 0 ; i < MAX_NR_ZONES ; i++) {
 			zones_size[i] = 0;
diff -Nru a/arch/m32r/mm/fault.c b/arch/m32r/mm/fault.c
--- a/arch/m32r/mm/fault.c	2005-03-01 23:38:54 -08:00
+++ b/arch/m32r/mm/fault.c	2005-03-01 23:38:54 -08:00
@@ -2,13 +2,12 @@
  *  linux/arch/m32r/mm/fault.c
  *
  *  Copyright (c) 2001, 2002  Hitoshi Yamamoto, and H. Kondo
+ *  Copyright (c) 2004  Naoto Sugai, NIIBE Yutaka
  *
  *  Some code taken from i386 version.
  *    Copyright (C) 1995  Linus Torvalds
  */
 
-/* $Id$ */
-
 #include <linux/config.h>
 #include <linux/signal.h>
 #include <linux/sched.h>
@@ -96,6 +95,11 @@
  *  bit 2 == 0 means kernel, 1 means user-mode
  *  bit 3 == 0 means data, 1 means instruction
  *======================================================================*/
+#define ACE_PROTECTION		1
+#define ACE_WRITE		2
+#define ACE_USERMODE		4
+#define ACE_INSTRUCTION		8
+
 asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code,
   unsigned long address)
 {
@@ -126,10 +130,10 @@
 	 * nothing more.
 	 *
 	 * This verifies that the fault happens in kernel space
-	 * (error_code & 4) == 0, and that the fault was not a
-	 * protection error (error_code & 1) == 0.
+	 * (error_code & ACE_USERMODE) == 0, and that the fault was not a
+	 * protection error (error_code & ACE_PROTECTION) == 0.
 	 */
-	if (address >= TASK_SIZE && !(error_code & 4))
+	if (address >= TASK_SIZE && !(error_code & ACE_USERMODE))
 		goto vmalloc_fault;
 
 	mm = tsk->mm;
@@ -157,7 +161,7 @@
 	 * thus avoiding the deadlock.
 	 */
 	if (!down_read_trylock(&mm->mmap_sem)) {
-		if ((error_code & 4) == 0 &&
+		if ((error_code & ACE_USERMODE) == 0 &&
 		    !search_exception_tables(regs->psw))
 			goto bad_area_nosemaphore;
 		down_read(&mm->mmap_sem);
@@ -171,7 +175,7 @@
 	if (!(vma->vm_flags & VM_GROWSDOWN))
 		goto bad_area;
 #if 0
-	if (error_code & 4) {
+	if (error_code & ACE_USERMODE) {
 		/*
 		 * accessing the stack below "spu" is always a bug.
 		 * The "+ 4" is there due to the push instruction
@@ -191,27 +195,34 @@
 good_area:
 	info.si_code = SEGV_ACCERR;
 	write = 0;
-	switch (error_code & 3) {
+	switch (error_code & (ACE_WRITE|ACE_PROTECTION)) {
 		default:	/* 3: write, present */
 			/* fall through */
-		case 2:		/* write, not present */
+		case ACE_WRITE:	/* write, not present */
 			if (!(vma->vm_flags & VM_WRITE))
 				goto bad_area;
 			write++;
 			break;
-		case 1:		/* read, present */
+		case ACE_PROTECTION:	/* read, present */
 		case 0:		/* read, not present */
 			if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
 				goto bad_area;
 	}
 
+	/*
+	 * For instruction access exception, check if the area is executable
+	 */
+	if ((error_code & ACE_INSTRUCTION) && !(vma->vm_flags & VM_EXEC))
+	  goto bad_area;
+
 survive:
 	/*
 	 * If for any reason at all we couldn't handle the fault,
 	 * make sure we exit gracefully rather than endlessly redo
 	 * the fault.
 	 */
-	addr = (address & PAGE_MASK) | (error_code & 8);
+	addr = (address & PAGE_MASK);
+	set_thread_fault_code(error_code);
 	switch (handle_mm_fault(mm, vma, addr, write)) {
 		case VM_FAULT_MINOR:
 			tsk->min_flt++;
@@ -226,7 +237,7 @@
 		default:
 			BUG();
 	}
-
+	set_thread_fault_code(0);
 	up_read(&mm->mmap_sem);
 	return;
 
@@ -239,7 +250,7 @@
 
 bad_area_nosemaphore:
 	/* User mode accesses just cause a SIGSEGV */
-	if (error_code & 4) {
+	if (error_code & ACE_USERMODE) {
 		tsk->thread.address = address;
 		tsk->thread.error_code = error_code | (address >= TASK_SIZE);
 		tsk->thread.trap_no = 14;
@@ -295,7 +306,7 @@
 		goto survive;
 	}
 	printk("VM: killing process %s\n", tsk->comm);
-	if (error_code & 4)
+	if (error_code & ACE_USERMODE)
 		do_exit(SIGKILL);
 	goto no_context;
 
@@ -303,7 +314,7 @@
 	up_read(&mm->mmap_sem);
 
 	/* Kernel mode? Handle exception or die */
-	if (!(error_code & 4))
+	if (!(error_code & ACE_USERMODE))
 		goto no_context;
 
 	tsk->thread.address = address;
@@ -352,7 +363,7 @@
 		if (!pte_present(*pte_k))
 			goto no_context;
 
-		addr = (address & PAGE_MASK) | (error_code & 8);
+		addr = (address & PAGE_MASK) | (error_code & ACE_INSTRUCTION);
 		update_mmu_cache(NULL, addr, *pte_k);
 		return;
 	}
@@ -370,7 +381,7 @@
 	unsigned long *entry1, *entry2;
 	unsigned long pte_data, flags;
 	unsigned int *entry_dat;
-	int inst = vaddr & 8;
+	int inst = get_thread_fault_code() & ACE_INSTRUCTION;
 	int i;
 
 	/* Ptrace may call this routine. */
diff -Nru a/arch/m32r/mm/init.c b/arch/m32r/mm/init.c
--- a/arch/m32r/mm/init.c	2005-03-01 23:39:08 -08:00
+++ b/arch/m32r/mm/init.c	2005-03-01 23:39:08 -08:00
@@ -9,8 +9,6 @@
  *      Copyright (C) 1995  Linus Torvalds
  */
 
-/* $Id$ */
-
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
@@ -19,6 +17,7 @@
 #include <linux/swap.h>
 #include <linux/highmem.h>
 #include <linux/bitops.h>
+#include <linux/nodemask.h>
 #include <asm/types.h>
 #include <asm/processor.h>
 #include <asm/page.h>
@@ -153,7 +152,7 @@
 	int reservedpages, nid, i;
 
 	reservedpages = 0;
-	for (nid = 0 ; nid < numnodes ; nid++)
+	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))
 				reservedpages++;
@@ -174,7 +173,7 @@
 #endif
 
 	num_physpages = 0;
-	for (nid = 0 ; nid < numnodes ; nid++)
+	for_each_online_node(nid)
 		num_physpages += MAX_LOW_PFN(nid) - START_PFN(nid) + 1;
 
 	num_physpages -= hole_pages;
@@ -193,7 +192,7 @@
 	memset(empty_zero_page, 0, PAGE_SIZE);
 
 	/* this will put all low memory onto the freelists */
-	for (nid = 0 ; nid < numnodes ; nid++)
+	for_each_online_node(nid)
 		totalram_pages += free_all_bootmem_node(NODE_DATA(nid));
 
 	reservedpages = reservedpages_count() - hole_pages;
diff -Nru a/arch/m32r/oaks32r/defconfig.nommu b/arch/m32r/oaks32r/defconfig.nommu
--- a/arch/m32r/oaks32r/defconfig.nommu	2005-03-01 23:38:44 -08:00
+++ b/arch/m32r/oaks32r/defconfig.nommu	2005-03-01 23:38:44 -08:00
@@ -1,11 +1,13 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc1-bk21
-# Fri Nov 12 16:09:00 2004
+# Linux kernel version: 2.6.11-rc4
+# Wed Feb 16 21:11:13 2005
 #
 CONFIG_M32R=y
-CONFIG_UID16=y
+# CONFIG_UID16 is not set
 CONFIG_GENERIC_ISA_DMA=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
 
 #
 # Code maturity level options
@@ -33,12 +35,11 @@
 # 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_TINY_SHMEM=y
 
 #
 # Loadable module support
@@ -74,6 +75,7 @@
 # CONFIG_DISCONTIGMEM is not set
 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 is not set
@@ -134,10 +136,12 @@
 # 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=y
 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=""
@@ -150,6 +154,7 @@
 # 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
@@ -314,6 +319,7 @@
 # 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
 
 #
@@ -365,7 +371,6 @@
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_AGP is not set
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -410,11 +415,25 @@
 # 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=y
@@ -423,6 +442,10 @@
 # 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
@@ -448,7 +471,6 @@
 # Pseudo filesystems
 #
 CONFIG_PROC_FS=y
-CONFIG_PROC_KCORE=y
 CONFIG_SYSFS=y
 # CONFIG_DEVFS_FS is not set
 CONFIG_DEVPTS_FS_XATTR=y
@@ -485,7 +507,6 @@
 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
@@ -554,7 +575,8 @@
 # Kernel hacking
 #
 # CONFIG_DEBUG_KERNEL is not set
-# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+CONFIG_DEBUG_PREEMPT=y
+# CONFIG_DEBUG_BUGVERBOSE is not set
 # CONFIG_FRAME_POINTER is not set
 
 #
@@ -567,6 +589,10 @@
 # Cryptographic options
 #
 # CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
 
 #
 # Library routines
diff -Nru a/arch/m32r/oprofile/init.c b/arch/m32r/oprofile/init.c
--- a/arch/m32r/oprofile/init.c	2005-03-01 23:38:52 -08:00
+++ b/arch/m32r/oprofile/init.c	2005-03-01 23:38:52 -08:00
@@ -12,13 +12,10 @@
 #include <linux/errno.h>
 #include <linux/init.h>
 
-extern void timer_init(struct oprofile_operations ** ops);
-
-int __init oprofile_arch_init(struct oprofile_operations ** ops)
+int __init oprofile_arch_init(struct oprofile_operations * ops)
 {
 	return -ENODEV;
 }
-
 
 void oprofile_arch_exit(void)
 {
diff -Nru a/arch/m32r/opsput/defconfig.opsput b/arch/m32r/opsput/defconfig.opsput
--- a/arch/m32r/opsput/defconfig.opsput	2005-03-01 23:38:54 -08:00
+++ b/arch/m32r/opsput/defconfig.opsput	2005-03-01 23:38:54 -08:00
@@ -1,11 +1,13 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc1-bk21
-# Fri Nov 12 16:09:02 2004
+# Linux kernel version: 2.6.11-rc4
+# Wed Feb 16 21:11:41 2005
 #
 CONFIG_M32R=y
-CONFIG_UID16=y
+# CONFIG_UID16 is not set
 CONFIG_GENERIC_ISA_DMA=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
 
 #
 # Code maturity level options
@@ -80,6 +82,7 @@
 # CONFIG_DISCONTIGMEM is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 # CONFIG_PREEMPT is not set
 # CONFIG_SMP is not set
 
@@ -94,7 +97,6 @@
 #
 CONFIG_PCCARD=y
 # CONFIG_PCMCIA_DEBUG is not set
-# CONFIG_PCMCIA_OBSOLETE is not set
 CONFIG_PCMCIA=y
 
 #
@@ -144,10 +146,12 @@
 # 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=4096
 # CONFIG_BLK_DEV_INITRD is not set
 CONFIG_INITRAMFS_SOURCE=""
@@ -160,6 +164,7 @@
 # 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
@@ -194,12 +199,12 @@
 #
 # CONFIG_SCSI_SPI_ATTRS is not set
 # CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
 
 #
 # SCSI low-level drivers
 #
 # CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_QLOGIC_1280_1040 is not set
 # CONFIG_SCSI_DEBUG is not set
 
 #
@@ -371,6 +376,7 @@
 # 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
 
 #
@@ -423,7 +429,6 @@
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_AGP is not set
 # CONFIG_DRM is not set
 
 #
@@ -473,11 +478,25 @@
 # 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=y
@@ -494,6 +513,10 @@
 # CONFIG_REISERFS_PROC_INFO is not set
 # CONFIG_REISERFS_FS_XATTR 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
@@ -564,7 +587,6 @@
 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
@@ -633,15 +655,19 @@
 # Kernel hacking
 #
 CONFIG_DEBUG_KERNEL=y
-# CONFIG_DEBUG_STACKOVERFLOW is not set
-# CONFIG_DEBUG_SLAB is not set
-# CONFIG_DEBUG_IOVIRT is not set
 # CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
 # CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_DEBUG_PAGEALLOC is not set
-CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_FS is not set
 # CONFIG_FRAME_POINTER is not set
+# CONFIG_DEBUG_STACKOVERFLOW is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_PAGEALLOC is not set
 
 #
 # Security options
@@ -653,6 +679,10 @@
 # Cryptographic options
 #
 # CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
 
 #
 # Library routines
diff -Nru a/arch/m68k/Kconfig b/arch/m68k/Kconfig
--- a/arch/m68k/Kconfig	2005-03-01 23:38:58 -08:00
+++ b/arch/m68k/Kconfig	2005-03-01 23:38:58 -08:00
@@ -21,6 +21,10 @@
 config RWSEM_XCHGADD_ALGORITHM
 	bool
 
+config GENERIC_CALIBRATE_DELAY
+	bool
+	default y
+
 mainmenu "Linux/68k Kernel Configuration"
 
 source "init/Kconfig"
@@ -381,8 +385,8 @@
 	bool "Support for ST-RAM as swap space"
 	depends on ATARI && BROKEN
 	---help---
-	  Some Atari 68k macines (including the 520STF and 1020STE) divide
-	  their addressible memory into ST and TT sections.  The TT section
+	  Some Atari 68k machines (including the 520STF and 1020STE) divide
+	  their addressable memory into ST and TT sections.  The TT section
 	  (up to 512MB) is the main memory; the ST section (up to 4MB) is
 	  accessible to the built-in graphics board, runs slower, and is
 	  present mainly for backward compatibility with older machines.
diff -Nru a/arch/m68k/apollo/dn_debug.c b/arch/m68k/apollo/dn_debug.c
--- a/arch/m68k/apollo/dn_debug.c	2005-03-01 23:38:51 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,22 +0,0 @@
-
-#define DN_DEBUG_BUFFER_BASE 0x82800000
-#define DN_DEBUG_BUFFER_SIZE 8*1024*1024
-
-static char *current_dbg_ptr=DN_DEBUG_BUFFER_BASE;
-
-int dn_deb_printf(const char *fmt, ...) {
-
-	va_list args;
-	int i;
-
-	if(current_dbg_ptr<(DN_DEBUG_BUFFER_BASE + DN_DEBUG_BUFFER_SIZE)) {
-		va_start(args,fmt);
-		i=vsprintf(current_dbg_ptr,fmt,args);
-		va_end(args);
-		current_dbg_ptr+=i;
-
-		return i;
-	}
-	else
-		return 0;
-}
diff -Nru a/arch/m68k/atari/stram.c b/arch/m68k/atari/stram.c
--- a/arch/m68k/atari/stram.c	2005-03-01 23:39:08 -08:00
+++ b/arch/m68k/atari/stram.c	2005-03-01 23:39:08 -08:00
@@ -1033,7 +1033,7 @@
 
 static struct gendisk *stram_disk;
 static struct request_queue *stram_queue;
-static spinlock_t stram_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(stram_lock);
 
 int __init stram_device_init(void)
 {
diff -Nru a/arch/m68k/configs/amiga_defconfig b/arch/m68k/configs/amiga_defconfig
--- a/arch/m68k/configs/amiga_defconfig	2005-03-01 23:38:56 -08:00
+++ b/arch/m68k/configs/amiga_defconfig	2005-03-01 23:38:56 -08:00
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc3-m68k
-# Sun Dec  5 14:21:25 2004
+# Linux kernel version: 2.6.10-m68k
+# Sun Dec 26 11:22:54 2004
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -376,7 +376,6 @@
 CONFIG_IP_NF_TARGET_REDIRECT=m
 CONFIG_IP_NF_TARGET_NETMAP=m
 CONFIG_IP_NF_TARGET_SAME=m
-CONFIG_IP_NF_NAT_LOCAL=y
 CONFIG_IP_NF_NAT_SNMP_BASIC=m
 CONFIG_IP_NF_NAT_IRC=m
 CONFIG_IP_NF_NAT_FTP=m
@@ -730,6 +729,11 @@
 # USB Gadget Support
 #
 # CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
 
 #
 # Character devices
diff -Nru a/arch/m68k/configs/apollo_defconfig b/arch/m68k/configs/apollo_defconfig
--- a/arch/m68k/configs/apollo_defconfig	2005-03-01 23:39:09 -08:00
+++ b/arch/m68k/configs/apollo_defconfig	2005-03-01 23:39:09 -08:00
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc3-m68k
-# Sun Dec  5 14:21:29 2004
+# Linux kernel version: 2.6.10-m68k
+# Sun Dec 26 11:22:58 2004
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -302,7 +302,6 @@
 CONFIG_IP_NF_TARGET_REDIRECT=m
 CONFIG_IP_NF_TARGET_NETMAP=m
 CONFIG_IP_NF_TARGET_SAME=m
-CONFIG_IP_NF_NAT_LOCAL=y
 CONFIG_IP_NF_NAT_SNMP_BASIC=m
 CONFIG_IP_NF_NAT_IRC=m
 CONFIG_IP_NF_NAT_FTP=m
@@ -589,6 +588,11 @@
 # USB Gadget Support
 #
 # CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
 
 #
 # Character devices
diff -Nru a/arch/m68k/configs/atari_defconfig b/arch/m68k/configs/atari_defconfig
--- a/arch/m68k/configs/atari_defconfig	2005-03-01 23:38:54 -08:00
+++ b/arch/m68k/configs/atari_defconfig	2005-03-01 23:38:54 -08:00
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc3-m68k
-# Sun Dec  5 14:21:34 2004
+# Linux kernel version: 2.6.10-m68k
+# Sun Dec 26 11:23:11 2004
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -331,7 +331,6 @@
 CONFIG_IP_NF_TARGET_REDIRECT=m
 CONFIG_IP_NF_TARGET_NETMAP=m
 CONFIG_IP_NF_TARGET_SAME=m
-CONFIG_IP_NF_NAT_LOCAL=y
 CONFIG_IP_NF_NAT_SNMP_BASIC=m
 CONFIG_IP_NF_NAT_IRC=m
 CONFIG_IP_NF_NAT_FTP=m
@@ -642,6 +641,11 @@
 # USB Gadget Support
 #
 # CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
 
 #
 # Character devices
diff -Nru a/arch/m68k/configs/bvme6000_defconfig b/arch/m68k/configs/bvme6000_defconfig
--- a/arch/m68k/configs/bvme6000_defconfig	2005-03-01 23:39:07 -08:00
+++ b/arch/m68k/configs/bvme6000_defconfig	2005-03-01 23:39:07 -08:00
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc3-m68k
-# Sun Dec  5 14:21:38 2004
+# Linux kernel version: 2.6.10-m68k
+# Sun Dec 26 11:23:15 2004
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -302,7 +302,6 @@
 CONFIG_IP_NF_TARGET_REDIRECT=m
 CONFIG_IP_NF_TARGET_NETMAP=m
 CONFIG_IP_NF_TARGET_SAME=m
-CONFIG_IP_NF_NAT_LOCAL=y
 CONFIG_IP_NF_NAT_SNMP_BASIC=m
 CONFIG_IP_NF_NAT_IRC=m
 CONFIG_IP_NF_NAT_FTP=m
@@ -588,6 +587,11 @@
 # USB Gadget Support
 #
 # CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
 
 #
 # Character devices
diff -Nru a/arch/m68k/configs/hp300_defconfig b/arch/m68k/configs/hp300_defconfig
--- a/arch/m68k/configs/hp300_defconfig	2005-03-01 23:39:09 -08:00
+++ b/arch/m68k/configs/hp300_defconfig	2005-03-01 23:39:09 -08:00
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc3-m68k
-# Sun Dec  5 14:21:44 2004
+# Linux kernel version: 2.6.10-m68k
+# Sun Dec 26 11:23:40 2004
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -303,7 +303,6 @@
 CONFIG_IP_NF_TARGET_REDIRECT=m
 CONFIG_IP_NF_TARGET_NETMAP=m
 CONFIG_IP_NF_TARGET_SAME=m
-CONFIG_IP_NF_NAT_LOCAL=y
 CONFIG_IP_NF_NAT_SNMP_BASIC=m
 CONFIG_IP_NF_NAT_IRC=m
 CONFIG_IP_NF_NAT_FTP=m
@@ -590,6 +589,11 @@
 # USB Gadget Support
 #
 # CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
 
 #
 # Character devices
diff -Nru a/arch/m68k/configs/mac_defconfig b/arch/m68k/configs/mac_defconfig
--- a/arch/m68k/configs/mac_defconfig	2005-03-01 23:39:08 -08:00
+++ b/arch/m68k/configs/mac_defconfig	2005-03-01 23:39:08 -08:00
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc3-m68k
-# Sun Dec  5 14:21:47 2004
+# Linux kernel version: 2.6.10-m68k
+# Sun Dec 26 11:23:44 2004
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -338,7 +338,6 @@
 CONFIG_IP_NF_TARGET_REDIRECT=m
 CONFIG_IP_NF_TARGET_NETMAP=m
 CONFIG_IP_NF_TARGET_SAME=m
-CONFIG_IP_NF_NAT_LOCAL=y
 CONFIG_IP_NF_NAT_SNMP_BASIC=m
 CONFIG_IP_NF_NAT_IRC=m
 CONFIG_IP_NF_NAT_FTP=m
@@ -651,6 +650,11 @@
 # USB Gadget Support
 #
 # CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
 
 #
 # Character devices
diff -Nru a/arch/m68k/configs/mvme147_defconfig b/arch/m68k/configs/mvme147_defconfig
--- a/arch/m68k/configs/mvme147_defconfig	2005-03-01 23:39:07 -08:00
+++ b/arch/m68k/configs/mvme147_defconfig	2005-03-01 23:39:07 -08:00
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc3-m68k
-# Sun Dec  5 14:21:49 2004
+# Linux kernel version: 2.6.10-m68k
+# Sun Dec 26 11:23:49 2004
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -303,7 +303,6 @@
 CONFIG_IP_NF_TARGET_REDIRECT=m
 CONFIG_IP_NF_TARGET_NETMAP=m
 CONFIG_IP_NF_TARGET_SAME=m
-CONFIG_IP_NF_NAT_LOCAL=y
 CONFIG_IP_NF_NAT_SNMP_BASIC=m
 CONFIG_IP_NF_NAT_IRC=m
 CONFIG_IP_NF_NAT_FTP=m
@@ -605,6 +604,11 @@
 # USB Gadget Support
 #
 # CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
 
 #
 # Character devices
diff -Nru a/arch/m68k/configs/mvme16x_defconfig b/arch/m68k/configs/mvme16x_defconfig
--- a/arch/m68k/configs/mvme16x_defconfig	2005-03-01 23:39:18 -08:00
+++ b/arch/m68k/configs/mvme16x_defconfig	2005-03-01 23:39:18 -08:00
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc3-m68k
-# Sun Dec  5 14:21:52 2004
+# Linux kernel version: 2.6.10-m68k
+# Sun Dec 26 11:23:53 2004
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -302,7 +302,6 @@
 CONFIG_IP_NF_TARGET_REDIRECT=m
 CONFIG_IP_NF_TARGET_NETMAP=m
 CONFIG_IP_NF_TARGET_SAME=m
-CONFIG_IP_NF_NAT_LOCAL=y
 CONFIG_IP_NF_NAT_SNMP_BASIC=m
 CONFIG_IP_NF_NAT_IRC=m
 CONFIG_IP_NF_NAT_FTP=m
@@ -604,6 +603,11 @@
 # USB Gadget Support
 #
 # CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
 
 #
 # Character devices
diff -Nru a/arch/m68k/configs/q40_defconfig b/arch/m68k/configs/q40_defconfig
--- a/arch/m68k/configs/q40_defconfig	2005-03-01 23:38:55 -08:00
+++ b/arch/m68k/configs/q40_defconfig	2005-03-01 23:38:55 -08:00
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc3-m68k
-# Sun Dec  5 14:21:55 2004
+# Linux kernel version: 2.6.10-m68k
+# Sun Dec 26 11:23:57 2004
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -356,7 +356,6 @@
 CONFIG_IP_NF_TARGET_REDIRECT=m
 CONFIG_IP_NF_TARGET_NETMAP=m
 CONFIG_IP_NF_TARGET_SAME=m
-CONFIG_IP_NF_NAT_LOCAL=y
 CONFIG_IP_NF_NAT_SNMP_BASIC=m
 CONFIG_IP_NF_NAT_IRC=m
 CONFIG_IP_NF_NAT_FTP=m
@@ -681,6 +680,11 @@
 # USB Gadget Support
 #
 # CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
 
 #
 # Character devices
diff -Nru a/arch/m68k/configs/sun3_defconfig b/arch/m68k/configs/sun3_defconfig
--- a/arch/m68k/configs/sun3_defconfig	2005-03-01 23:39:07 -08:00
+++ b/arch/m68k/configs/sun3_defconfig	2005-03-01 23:39:07 -08:00
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc3-m68k
-# Sun Dec  5 14:21:58 2004
+# Linux kernel version: 2.6.10-m68k
+# Sun Dec 26 11:24:01 2004
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -291,7 +291,6 @@
 CONFIG_IP_NF_TARGET_REDIRECT=m
 CONFIG_IP_NF_TARGET_NETMAP=m
 CONFIG_IP_NF_TARGET_SAME=m
-CONFIG_IP_NF_NAT_LOCAL=y
 CONFIG_IP_NF_NAT_SNMP_BASIC=m
 CONFIG_IP_NF_NAT_IRC=m
 CONFIG_IP_NF_NAT_FTP=m
@@ -594,6 +593,11 @@
 # USB Gadget Support
 #
 # CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
 
 #
 # Character devices
diff -Nru a/arch/m68k/configs/sun3x_defconfig b/arch/m68k/configs/sun3x_defconfig
--- a/arch/m68k/configs/sun3x_defconfig	2005-03-01 23:38:52 -08:00
+++ b/arch/m68k/configs/sun3x_defconfig	2005-03-01 23:38:52 -08:00
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc3-m68k
-# Sun Dec  5 14:22:01 2004
+# Linux kernel version: 2.6.10-m68k
+# Sun Dec 26 11:24:05 2004
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -302,7 +302,6 @@
 CONFIG_IP_NF_TARGET_REDIRECT=m
 CONFIG_IP_NF_TARGET_NETMAP=m
 CONFIG_IP_NF_TARGET_SAME=m
-CONFIG_IP_NF_NAT_LOCAL=y
 CONFIG_IP_NF_NAT_SNMP_BASIC=m
 CONFIG_IP_NF_NAT_IRC=m
 CONFIG_IP_NF_NAT_FTP=m
@@ -604,6 +603,11 @@
 # USB Gadget Support
 #
 # CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
 
 #
 # Character devices
diff -Nru a/arch/m68k/defconfig b/arch/m68k/defconfig
--- a/arch/m68k/defconfig	2005-03-01 23:38:51 -08:00
+++ b/arch/m68k/defconfig	2005-03-01 23:38:51 -08:00
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc3-m68k
-# Sun Dec  5 14:21:41 2004
+# Linux kernel version: 2.6.10-m68k
+# Sun Dec 26 11:23:36 2004
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -460,6 +460,11 @@
 # USB Gadget Support
 #
 # CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
 
 #
 # Character devices
diff -Nru a/arch/m68k/lib/checksum.c b/arch/m68k/lib/checksum.c
--- a/arch/m68k/lib/checksum.c	2005-03-01 23:39:17 -08:00
+++ b/arch/m68k/lib/checksum.c	2005-03-01 23:39:17 -08:00
@@ -134,8 +134,8 @@
  */
 
 unsigned int
-csum_partial_copy_from_user(const char *src, char *dst, int len,
-			    int sum, int *csum_err)
+csum_partial_copy_from_user(const unsigned char *src, unsigned char *dst,
+			    int len, int sum, int *csum_err)
 {
 	/*
 	 * GCC doesn't like more than 10 operands for the asm
@@ -326,7 +326,7 @@
  */
 
 unsigned int
-csum_partial_copy_nocheck(const char *src, char *dst, int len, int sum)
+csum_partial_copy_nocheck(const unsigned char *src, unsigned char *dst, int len, int sum)
 {
 	unsigned long tmp1, tmp2;
 	__asm__("movel %2,%4\n\t"
diff -Nru a/arch/m68k/sun3x/sun3x_ksyms.c b/arch/m68k/sun3x/sun3x_ksyms.c
--- a/arch/m68k/sun3x/sun3x_ksyms.c	2005-03-01 23:38:56 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,13 +0,0 @@
-#include <linux/module.h>
-#include <linux/types.h>
-#include <asm/dvma.h>
-#include <asm/idprom.h>
-
-/*
- * Add things here when you find the need for it.
- */
-EXPORT_SYMBOL(dvma_map_align);
-EXPORT_SYMBOL(dvma_unmap);
-EXPORT_SYMBOL(dvma_malloc_align);
-EXPORT_SYMBOL(dvma_free);
-EXPORT_SYMBOL(idprom);
diff -Nru a/arch/m68knommu/Kconfig b/arch/m68knommu/Kconfig
--- a/arch/m68knommu/Kconfig	2005-03-01 23:39:08 -08:00
+++ b/arch/m68knommu/Kconfig	2005-03-01 23:39:08 -08:00
@@ -29,6 +29,10 @@
 	bool
 	default n
 
+config GENERIC_CALIBRATE_DELAY
+	bool
+	default y
+
 source "init/Kconfig"
 
 menu "Processor type and features"
@@ -328,12 +332,6 @@
 	help
 	  Support for the senTec COBRA5272 board.
 
-config M5275EVB
-	bool "Freescale (Motorola) M5275EVB board support"
-	depends on M527x
-	help
-	  Support for the Freescale (Motorola) M5275EVB board.
-
 config M5282EVB
 	bool "Motorola M5282EVB board support"
 	depends on M528x
@@ -448,7 +446,7 @@
         bool
 	default y
 	depends on CPU16B
-	
+
 config LARGE_ALLOCS
 	bool "Allow allocating large blocks (> 1MB) of memory"
 	help
@@ -531,11 +529,6 @@
 	bool "ROM"
 	help
 	  The kernel will be resident in FLASH/ROM when running.
-
-config HIMEMKERNEL
-	bool "HIMEM"
-	help
-	  The kernel will be resident in high memory when running.
 
 endchoice
 
diff -Nru a/arch/m68knommu/kernel/process.c b/arch/m68knommu/kernel/process.c
--- a/arch/m68knommu/kernel/process.c	2005-03-01 23:38:53 -08:00
+++ b/arch/m68knommu/kernel/process.c	2005-03-01 23:38:53 -08:00
@@ -199,7 +199,7 @@
 	struct switch_stack * childstack, *stack;
 	unsigned long stack_offset, *retp;
 
-	stack_offset = KTHREAD_SIZE - sizeof(struct pt_regs);
+	stack_offset = THREAD_SIZE - sizeof(struct pt_regs);
 	childregs = (struct pt_regs *) ((unsigned long) p->thread_info + stack_offset);
 
 	*childregs = *regs;
@@ -342,7 +342,7 @@
 			(int) current->mm->brk);
 		printk(KERN_EMERG "USER-STACK=%08x  KERNEL-STACK=%08x\n\n",
 			(int) current->mm->start_stack,
-			(int)(((unsigned long) current) + KTHREAD_SIZE));
+			(int)(((unsigned long) current) + THREAD_SIZE));
 	}
 
 	printk(KERN_EMERG "PC: %08lx\n", fp->pc);
diff -Nru a/arch/m68knommu/kernel/vmlinux.lds.S b/arch/m68knommu/kernel/vmlinux.lds.S
--- a/arch/m68knommu/kernel/vmlinux.lds.S	2005-03-01 23:38:56 -08:00
+++ b/arch/m68knommu/kernel/vmlinux.lds.S	2005-03-01 23:38:56 -08:00
@@ -124,9 +124,8 @@
 #endif
 
 /*
- *   The senTec COBRA5272 board has nearly the same
- *   memory layout as the M5272C3.
- *   We assume 16MB ram.
+ *	The senTec COBRA5272 board has nearly the same memory layout as 
+ *	the M5272C3. We assume 16MiB ram.
  */
 #if defined(CONFIG_COBRA5272)
 #define RAM_START   0x20000
@@ -139,8 +138,7 @@
 #endif
 
 /*
- *   The senTec COBRA5282 board has the same
- *   memory layout as the M5282EVB.
+ *	The senTec COBRA5282 board has the same memory layout as the M5282EVB.
  */
 #if defined(CONFIG_COBRA5282)
 #define  RAM_START   0x10000
diff -Nru a/arch/m68knommu/lib/checksum.c b/arch/m68knommu/lib/checksum.c
--- a/arch/m68knommu/lib/checksum.c	2005-03-01 23:39:18 -08:00
+++ b/arch/m68knommu/lib/checksum.c	2005-03-01 23:39:18 -08:00
@@ -31,6 +31,7 @@
 /* Revised by Kenneth Albanowski for m68knommu. Basic problem: unaligned access kills, so most
    of the assembly has to go. */
 
+#include <linux/module.h>
 #include <net/checksum.h>
 
 static inline unsigned short from32to16(unsigned long x)
@@ -139,7 +140,8 @@
  */
 
 unsigned int
-csum_partial_copy_from_user(const char *src, char *dst, int len, int sum, int *csum_err)
+csum_partial_copy_from_user(const unsigned char *src, unsigned char *dst,
+			    int len, int sum, int *csum_err)
 {
 	if (csum_err) *csum_err = 0;
 	memcpy(dst, src, len);
@@ -151,7 +153,7 @@
  */
 
 unsigned int
-csum_partial_copy(const char *src, char *dst, int len, int sum)
+csum_partial_copy(const unsigned char *src, unsigned char *dst, int len, int sum)
 {
 	memcpy(dst, src, len);
 	return csum_partial(dst, len, sum);
diff -Nru a/arch/m68knommu/lib/delay.c b/arch/m68knommu/lib/delay.c
--- a/arch/m68knommu/lib/delay.c	2005-03-01 23:38:54 -08:00
+++ b/arch/m68knommu/lib/delay.c	2005-03-01 23:38:54 -08:00
@@ -8,8 +8,11 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/module.h>
 #include <asm/param.h>
 #include <asm/delay.h>
+
+EXPORT_SYMBOL(udelay);
 
 void udelay(unsigned long usecs)
 {
diff -Nru a/arch/m68knommu/mm/init.c b/arch/m68knommu/mm/init.c
--- a/arch/m68knommu/mm/init.c	2005-03-01 23:39:07 -08:00
+++ b/arch/m68knommu/mm/init.c	2005-03-01 23:39:07 -08:00
@@ -168,7 +168,7 @@
 	high_memory = (void *) end_mem;
 
 	start_mem = PAGE_ALIGN(start_mem);
-	max_mapnr = num_physpages = MAP_NR(high_memory);
+	max_mapnr = num_physpages = (((unsigned long) high_memory) - PAGE_OFFSET) >> PAGE_SHIFT;
 
 	/* this will put all memory onto the freelists */
 	totalram_pages = free_all_bootmem();
diff -Nru a/arch/m68knommu/platform/5307/head.S b/arch/m68knommu/platform/5307/head.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/m68knommu/platform/5307/head.S	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,253 @@
+/*****************************************************************************/
+
+/*
+ *	head.S -- common startup code for ColdFire CPUs.
+ *
+ *	(C) Copyright 1999-2004, Greg Ungerer (gerg@snapgear.com).
+ */
+
+/*****************************************************************************/
+
+#include <linux/config.h>
+#include <linux/sys.h>
+#include <linux/linkage.h>
+#include <asm/thread_info.h>
+#include <asm/coldfire.h>
+#include <asm/mcfcache.h>
+#include <asm/mcfsim.h>
+
+/*****************************************************************************/
+
+/*
+ *	Define fixed memory sizes. Configuration of a fixed memory size
+ *	overrides everything else. If the user defined a size we just
+ *	blindly use it (they know what they are doing right :-)
+ */
+#if defined(CONFIG_RAM32MB)
+#define MEM_SIZE	0x02000000	/* memory size 32Mb */
+#elif defined(CONFIG_RAM16MB)
+#define MEM_SIZE	0x01000000	/* memory size 16Mb */
+#elif defined(CONFIG_RAM8MB)
+#define MEM_SIZE	0x00800000	/* memory size 8Mb */
+#elif defined(CONFIG_RAM4MB)
+#define MEM_SIZE	0x00400000	/* memory size 4Mb */
+#elif defined(CONFIG_RAM1MB)
+#define MEM_SIZE	0x00100000	/* memory size 1Mb */
+#endif
+
+/*
+ *	Memory size exceptions for special cases. Some boards may be set
+ *	for auto memory sizing, but we can't do it that way for some reason.
+ *	For example the 5206eLITE board has static RAM, and auto-detecting
+ *	the SDRAM will do you no good at all.
+ */
+#ifdef CONFIG_RAMAUTO
+#if defined(CONFIG_M5206eLITE)
+#define	MEM_SIZE	0x00100000		/* 1MiB default memory */
+#endif
+#endif /* CONFIG_RAMAUTO */
+
+/*
+ *	If we don't have a fixed memory size now, then lets build in code
+ *	to auto detect the DRAM size. Obviously this is the prefered
+ *	method, and should work for most boards (it won't work for those
+ *	that do not have their RAM starting at address 0).
+ */
+#if defined(MEM_SIZE)
+.macro GET_MEM_SIZE
+	movel	#MEM_SIZE,%d0		/* hard coded memory size */
+.endm
+
+#elif defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \
+      defined(CONFIG_M5249) || defined(CONFIG_M527x) || \
+      defined(CONFIG_M528x) || defined(CONFIG_M5307) || \
+      defined(CONFIG_M5407)
+/*
+ *	Not all these devices have exactly the same DRAM controller,
+ *	but the DCMR register is virtually identical - give or take
+ *	a couple of bits. The only exception is the 5272 devices, their
+ *	DRAM controller is quite different.
+ */
+.macro GET_MEM_SIZE
+	movel	MCF_MBAR+MCFSIM_DMR0,%d0 /* get mask for 1st bank */
+	btst	#0,%d0			/* check if region enabled */
+	beq	1f
+	andl	#0xfffc0000,%d0
+	beq	1f
+	addl	#0x00040000,%d0		/* convert mask to size */
+1:
+	movel	MCF_MBAR+MCFSIM_DMR1,%d1 /* get mask for 2nd bank */
+	btst	#0,%d1			/* check if region enabled */
+	beq	2f
+	andl	#0xfffc0000, %d1
+	beq	2f
+	addl	#0x00040000,%d1
+	addl	%d1,%d0			/* total mem size in d0 */
+2:
+.endm
+
+#elif defined(CONFIG_M5272)
+.macro GET_MEMORY_SIZE
+	movel	MCF_MBAR+MCFSIM_CSOR7,%d0 /* get SDRAM address mask */
+	andil	#0xfffff000,%d0		/* mask out chip select options */
+	negl	%d0			/* negate bits */
+.endm
+
+#else
+#error "ERROR: I don't know how to determine your boards memory size?"
+#endif
+
+
+/*
+ *	Most ColdFire boards have their DRAM starting at address 0.
+ *	Notable exception is the 5206eLITE board.
+ */
+#if defined(CONFIG_M5206eLITE)
+#define	MEM_BASE	0x30000000
+#endif
+
+#ifndef MEM_BASE
+#define	MEM_BASE	0x00000000	/* memory base at address 0 */
+#endif
+
+/*
+ *	The default location for the vectors is at the base of RAM.
+ *	Some boards might like to use internal SRAM or something like
+ *	that. If no board specific header defines an alternative then
+ *	use the base of RAM.
+ */
+#ifndef	VBR_BASE
+#define	VBR_BASE	MEM_BASE	/* vector address */
+#endif
+
+/*****************************************************************************/
+
+/*
+ *	Boards and platforms can do specific early hardware setup if
+ *	they need to. Most don't need this, define away if not required.
+ */
+#ifndef PLATFORM_SETUP
+#define	PLATFORM_SETUP
+#endif
+
+/*****************************************************************************/
+
+.global	_start
+.global _rambase
+.global _ramvec
+.global	_ramstart
+.global	_ramend
+
+/*****************************************************************************/
+
+.data
+
+/*
+ *	During startup we store away the RAM setup. These are not in the
+ *	bss, since their values are determined and written before the bss
+ *	has been cleared.
+ */
+_rambase:
+.long	0
+_ramvec:
+.long	0
+_ramstart:
+.long	0
+_ramend:
+.long	0
+
+/*****************************************************************************/
+
+.text
+
+/*
+ *	This is the codes first entry point. This is where it all
+ *	begins...
+ */
+
+_start:
+	nop					/* filler */
+	movew	#0x2700, %sr			/* no interrupts */
+
+	/*
+	 *	Do any platform or board specific setup now. Most boards
+	 *	don't need anything. Those exceptions are define this in
+	 *	their board specific includes.
+	 */
+	PLATFORM_SETUP
+
+	/*
+	 *	Create basic memory configuration. Set VBR accordingly,
+	 *	and size memory.
+	 */
+	movel	#VBR_BASE,%a7
+	movec   %a7,%VBR			/* set vectors addr */
+	movel	%a7,_ramvec
+
+	movel	#MEM_BASE,%a7			/* mark the base of RAM */
+	movel	%a7,_rambase
+
+	GET_MEM_SIZE				/* macro code determines size */
+	movel	%d0,_ramend			/* set end ram addr */
+
+	/*
+	 *	Now that we know what the memory is, lets enable cache
+	 *	and get things moving. This is Coldfire CPU specific.
+	 */
+	CACHE_ENABLE				/* enable CPU cache */
+
+
+#ifdef CONFIG_ROMFS_FS
+	/*
+	 *	Move ROM filesystem above bss :-)
+	 */
+	lea	_sbss,%a0			/* get start of bss */
+	lea	_ebss,%a1			/* set up destination  */
+	movel	%a0,%a2				/* copy of bss start */
+
+	movel	8(%a0),%d0			/* get size of ROMFS */
+	addql	#8,%d0				/* allow for rounding */
+	andl	#0xfffffffc, %d0		/* whole words */
+
+	addl	%d0,%a0				/* copy from end */
+	addl	%d0,%a1				/* copy from end */
+	movel	%a1,_ramstart			/* set start of ram */
+
+_copy_romfs:
+	movel	-(%a0),%d0			/* copy dword */
+	movel	%d0,-(%a1)
+	cmpl	%a0,%a2				/* check if at end */
+	bne	_copy_romfs
+
+#else /* CONFIG_ROMFS_FS */
+	lea	_ebss,%a1
+	movel	%a1,_ramstart
+#endif /* CONFIG_ROMFS_FS */
+
+
+	/*
+	 *	Zero out the bss region.
+	 */
+	lea	_sbss,%a0			/* get start of bss */
+	lea	_ebss,%a1			/* get end of bss */
+	clrl	%d0				/* set value */
+_clear_bss:
+	movel	%d0,(%a0)+			/* clear each word */
+	cmpl	%a0,%a1				/* check if at end */
+	bne	_clear_bss
+
+	/*
+	 *	Load the current task pointer and stack.
+	 */
+	lea	init_thread_union,%a0
+	lea	THREAD_SIZE(%a0),%sp
+
+	/*
+	 *	Assember start up done, start code proper.
+	 */
+	jsr	start_kernel			/* start Linux kernel */
+
+_exit:
+	jmp	_exit				/* should never get here */
+
+/*****************************************************************************/
diff -Nru a/arch/mips/Kconfig b/arch/mips/Kconfig
--- a/arch/mips/Kconfig	2005-03-01 23:38:57 -08:00
+++ b/arch/mips/Kconfig	2005-03-01 23:38:57 -08:00
@@ -29,6 +29,10 @@
 
 config MACH_JAZZ
 	bool "Support for the Jazz family of machines"
+	select ARC
+	select ARC32
+	select GENERIC_ISA_DMA
+	select I8259
 	select ISA
 	help
 	 This a family of machines based on the MIPS R4030 chipset which was
@@ -69,6 +73,21 @@
 config MACH_VR41XX
 	bool "Support for NEC VR41XX-based machines"
 
+config NEC_CMBVR4133
+	bool "Support for NEC CMB-VR4133"
+	depends on MACH_VR41XX
+	select CPU_VR41XX
+	select DMA_NONCOHERENT
+	select IRQ_CPU
+	select HW_HAS_PCI
+	select PCI_VR41XX
+
+config ROCKHOPPER
+	bool "Support for Rockhopper baseboard"
+	depends on NEC_CMBVR4133
+	select I8259
+	select HAVE_STD_PC_SERIAL_PORT
+
 config CASIO_E55
 	bool "Support for CASIO CASSIOPEIA E-10/15/55/65"
 	depends on MACH_VR41XX
@@ -103,6 +122,10 @@
 	  The TANBAC TB0229 (VR4131DIMM) is a MIPS-based platform manufactured by TANBAC.
 	  Please refer to <http://www.tanbac.co.jp/> about VR4131DIMM.
 
+config TANBAC_TB0219
+	bool "Added TANBAC TB0219 Base board support"
+	depends on TANBAC_TB0229
+
 config VICTOR_MPC30X
 	bool "Support for Victor MP-C303/304"
 	select DMA_NONCOHERENT
@@ -145,10 +168,12 @@
 	depends on EXPERIMENTAL
 	select DMA_NONCOHERENT
 	select HW_HAS_PCI
+	select I8259
 	select IRQ_CPU
 
 config MACH_DECSTATION
 	bool "Support for DECstations"
+	select BOOT_ELF32
 	select DMA_NONCOHERENT
 	select IRQ_CPU
 	depends on MIPS32 || EXPERIMENTAL
@@ -172,6 +197,7 @@
 	depends on EXPERIMENTAL
 	select DMA_NONCOHERENT
 	select HW_HAS_PCI
+	select MIPS_GT64120
 	help
 	  This is an evaluation board based on the Galileo GT-64120
 	  single-chip system controller that contains a MIPS R5000 compatible
@@ -213,6 +239,7 @@
 	bool "Support for LASAT Networks platforms"
 	select DMA_NONCOHERENT
 	select HW_HAS_PCI
+	select MIPS_GT64120
 	select R5000_CPU_SCACHE
 
 config PICVUE
@@ -253,8 +280,10 @@
 
 config MIPS_ATLAS
 	bool "Support for MIPS Atlas board"
+	select BOOT_ELF32
 	select DMA_NONCOHERENT
 	select HW_HAS_PCI
+	select MIPS_GT64120
 	select SWAP_IO_SPACE
 	help
 	  This enables support for the QED R5231-based MIPS Atlas evaluation
@@ -262,9 +291,13 @@
 
 config MIPS_MALTA
 	bool "Support for MIPS Malta board"
+	select BOOT_ELF32
 	select HAVE_STD_PC_SERIAL_PORT
 	select DMA_NONCOHERENT
+	select GENERIC_ISA_DMA
 	select HW_HAS_PCI
+	select I8259
+	select MIPS_GT64120
 	select SWAP_IO_SPACE
 	help
 	  This enables support for the VR5000-based MIPS Malta evaluation
@@ -282,6 +315,7 @@
 	select HW_HAS_PCI
 	select IRQ_CPU
 	select IRQ_CPU_RM7K
+	select MIPS_GT64120
 	select RM7000_CPU_SCACHE
 	select SWAP_IO_SPACE
 	help
@@ -316,6 +350,7 @@
 
 config MOMENCO_OCELOT_3
 	bool "Support for Momentum Ocelot-3 board"
+	select BOOT_ELF32
 	select DMA_NONCOHERENT
 	select HW_HAS_PCI
 	select IRQ_CPU
@@ -330,6 +365,7 @@
 
 config MOMENCO_JAGUAR_ATX
 	bool "Support for Momentum Jaguar board"
+	select BOOT_ELF32
 	select DMA_NONCOHERENT
 	select HW_HAS_PCI
 	select IRQ_CPU
@@ -356,6 +392,7 @@
 	select HW_HAS_PCI
 	select IRQ_CPU
 	select IRQ_CPU_RM7K
+	select IRQ_CPU_RM9K
 	select SWAP_IO_SPACE
 	help
 	  Yosemite is an evaluation board for the RM9000x2 processor
@@ -372,6 +409,7 @@
 	select HAVE_STD_PC_SERIAL_PORT
 	select HW_HAS_PCI
 	select IRQ_CPU
+	select I8259
 	select ISA
 	help
 	  This enables support for the VR5000-based NEC DDB Vrc-5074
@@ -383,6 +421,7 @@
 	select HAVE_STD_PC_SERIAL_PORT
 	select HW_HAS_PCI
 	select IRQ_CPU
+	select I8259
 	select ISA
 	help
 	  This enables support for the R5432-based NEC DDB Vrc-5476
@@ -396,6 +435,7 @@
 	bool "Support for NEC DDB Vrc-5477"
 	select DMA_NONCOHERENT
 	select HW_HAS_PCI
+	select I8259
 	select IRQ_CPU
 	help
 	  This enables support for the R5432-based NEC DDB Vrc-5477,
@@ -416,6 +456,9 @@
 
 config SGI_IP22
 	bool "Support for SGI IP22 (Indy/Indigo2)"
+	select ARC
+	select ARC32
+	select BOOT_ELF32
 	select DMA_NONCOHERENT
 	select IP22_CPU_SCACHE
 	select IRQ_CPU
@@ -428,6 +471,8 @@
 config SGI_IP27
 	bool "Support for SGI IP27 (Origin200/2000)"
 	depends on MIPS64
+	select ARC
+	select ARC64
 	select DMA_IP27
 	select HW_HAS_PCI
 	select PCI_DOMAINS
@@ -494,6 +539,11 @@
 config SGI_IP32
 	bool "Support for SGI IP32 (O2) (EXPERIMENTAL)"
 	depends on MIPS64 && EXPERIMENTAL
+	select ARC
+	select ARC32
+	select BOOT_ELF32
+	select OWN_DMA
+	select DMA_IP32
 	select DMA_NONCOHERENT
 	select HW_HAS_PCI
 	select R5000_CPU_SCACHE
@@ -508,31 +558,31 @@
 choice
 	prompt "Au1X00 SOC Type"
 	depends on SOC_AU1X00
-        help
-           Say Y here to enable support for one of three AMD/Alchemy
-           SOCs. For additional documentation see www.amd.com.
+	help
+	  Say Y here to enable support for one of three AMD/Alchemy
+	  SOCs. For additional documentation see www.amd.com.
 
 config SOC_AU1000
-        bool "SOC_AU1000"
+	bool "SOC_AU1000"
 config SOC_AU1100
-        bool "SOC_AU1100"
+	bool "SOC_AU1100"
 config SOC_AU1500
-        bool "SOC_AU1500"
+	bool "SOC_AU1500"
 config SOC_AU1550
-        bool "SOC_AU1550"
+	bool "SOC_AU1550"
 
 endchoice
 
 choice
-        prompt "AMD/Alchemy Au1x00 board support"
-        depends on SOC_AU1X00
+	prompt "AMD/Alchemy Au1x00 board support"
+	depends on SOC_AU1X00
 	help
 	  These are evaluation boards built by AMD/Alchemy to
 	  showcase their Au1X00 Internet Edge Processors. The SOC design
 	  is based on the MIPS32 architecture running at 266/400/500MHz
-          with many integrated peripherals. Further information can be
-          found at their website, <http://www.amd.com/>. Say Y here if you
-          wish to build a kernel for this platform.
+	  with many integrated peripherals. Further information can be
+	  found at their website, <http://www.amd.com/>. Say Y here if you
+	  wish to build a kernel for this platform.
 
 config MIPS_PB1000
 	bool "PB1000 board"
@@ -604,6 +654,7 @@
 config MIPS_MTX1
 	bool "4G Systems MTX-1 board"
 	depends on SOC_AU1500
+	select HW_HAS_PCI
 	select DMA_NONCOHERENT
 
 endchoice
@@ -611,6 +662,7 @@
 config SIBYTE_SB1xxx_SOC
 	bool "Support for Broadcom BCM1xxx SOCs (EXPERIMENTAL)"
 	depends on EXPERIMENTAL
+	select BOOT_ELF32
 	select DMA_COHERENT
 	select SWAP_IO_SPACE
 
@@ -721,6 +773,7 @@
 config CPU_SB1_PASS_1
 	bool "1250 Pass1"
 	depends on SIBYTE_SB1250
+	select CPU_HAS_PREFETCH
 
 config CPU_SB1_PASS_2_1250
 	bool "1250 An"
@@ -732,12 +785,14 @@
 config CPU_SB1_PASS_2_2
 	bool "1250 Bn"
 	depends on SIBYTE_SB1250
+	select CPU_HAS_PREFETCH
 	help
 	  Also called BCM1250 Pass 2.2
 
 config CPU_SB1_PASS_4
 	bool "1250 Cn"
 	depends on SIBYTE_SB1250
+	select CPU_HAS_PREFETCH
 	help
 	  Also called BCM1250 Pass 3
 
@@ -749,6 +804,7 @@
 config CPU_SB1_PASS_3
 	bool "112x An"
 	depends on SIBYTE_BCM112X
+	select CPU_HAS_PREFETCH
 
 endchoice
 
@@ -819,9 +875,14 @@
 
 config SNI_RM200_PCI
 	bool "Support for SNI RM200 PCI"
+	select ARC
+	select ARC32
+	select BOOT_ELF32
 	select DMA_NONCOHERENT
+	select GENERIC_ISA_DMA
 	select HAVE_STD_PC_SERIAL_PORT
 	select HW_HAS_PCI
+	select I8259
 	select ISA
 	help
 	  The SNI RM200 PCI was a MIPS-based platform manufactured by Siemens
@@ -833,6 +894,7 @@
 	bool "Support for Toshiba TBTX49[23]7 board"
 	depends on MIPS32
 	select DMA_NONCOHERENT
+	select HAS_TXX9_SERIAL
 	select HW_HAS_PCI
 	select I8259
 	select ISA
@@ -852,6 +914,10 @@
 config RWSEM_XCHGADD_ALGORITHM
 	bool
 
+config GENERIC_CALIBRATE_DELAY
+	bool
+	default y
+
 config HAVE_DEC_LOCK
 	bool
 	default y
@@ -951,6 +1017,7 @@
 config MIPS_TX3927
 	bool
 	depends on TOSHIBA_JMR3927
+	select HAS_TXX9_SERIAL
 	default y
 
 config PCI_MARVELL
@@ -986,7 +1053,7 @@
 
 endchoice
 
-config AU1000_USB_DEVICE
+config AU1X00_USB_DEVICE
 	bool
 	depends on MIPS_PB1500 || MIPS_PB1100 || MIPS_PB1000
 	default n
@@ -1106,10 +1173,6 @@
 	bool
 	depends on TOSHIBA_JMR3927 || TOSHIBA_RBTX4927
 	default y
-
-config TANBAC_TB0219
-	bool "Added TANBAC TB0219 Base board support"
-	depends on TANBAC_TB0229
 
 endmenu
 
diff -Nru a/arch/mips/Makefile b/arch/mips/Makefile
--- a/arch/mips/Makefile	2005-03-01 23:38:44 -08:00
+++ b/arch/mips/Makefile	2005-03-01 23:38:44 -08:00
@@ -482,6 +482,12 @@
 cflags-$(CONFIG_MACH_VR41XX)	+= -Iinclude/asm-mips/mach-vr41xx
 
 #
+# NEC VR4133
+#
+core-$(CONFIG_NEC_CMBVR4133)	+= arch/mips/vr41xx/nec-cmbvr4133/
+load-$(CONFIG_NEC_CMBVR4133)	+= 0xffffffff80100000
+
+#
 # ZAO Networks Capcella (VR4131)
 #
 core-$(CONFIG_ZAO_CAPCELLA)	+= arch/mips/vr41xx/zao-capcella/
@@ -673,6 +679,8 @@
 
 core-y			+= arch/mips/kernel/ arch/mips/mm/ arch/mips/math-emu/
 
+drivers-$(CONFIG_OPROFILE)	+= arch/mips/oprofile/
+
 ifdef CONFIG_LASAT
 rom.bin rom.sw: vmlinux
 	$(call descend,arch/mips/lasat/image,$@)
@@ -744,36 +752,16 @@
 	 echo "#endif /* _ASM_OFFSET_H */" )
 endef
 
-define filechk_gen-asm-reg.h
-	(set -e; \
-	 echo "#ifndef _ASM_REG_H"; \
-	 echo "#define _ASM_REG_H"; \
-	 echo "/*"; \
-	 echo " * DO NOT MODIFY."; \
-	 echo " *"; \
-	 echo " * This file was generated by arch/$(ARCH)/Makefile"; \
-	 echo " *"; \
-	 echo " */"; \
-	 echo ""; \
-	 sed -ne "/^@@@/s///p"; \
-	 echo "#endif /* _ASM_REG_H */" )
-endef
-
-prepare: include/asm-$(ARCH)/offset.h \
-	 include/asm-$(ARCH)/reg.h
+prepare: include/asm-$(ARCH)/offset.h
 
 arch/$(ARCH)/kernel/offset.s: include/asm include/linux/version.h \
 				   include/config/MARKER
 
 include/asm-$(ARCH)/offset.h: arch/$(ARCH)/kernel/offset.s
 	$(call filechk,gen-asm-offset.h)
-include/asm-$(ARCH)/reg.h: arch/$(ARCH)/kernel/reg.s
-	$(call filechk,gen-asm-reg.h)
 
 CLEAN_FILES += include/asm-$(ARCH)/offset.h.tmp \
 	       include/asm-$(ARCH)/offset.h \
-	       include/asm-$(ARCH)/reg.h.tmp \
-	       include/asm-$(ARCH)/reg.h \
 	       vmlinux.32 \
 	       vmlinux.64 \
 	       vmlinux.ecoff
diff -Nru a/arch/mips/au1000/common/au1xxx_irqmap.c b/arch/mips/au1000/common/au1xxx_irqmap.c
--- a/arch/mips/au1000/common/au1xxx_irqmap.c	2005-03-01 23:38:54 -08:00
+++ b/arch/mips/au1000/common/au1xxx_irqmap.c	2005-03-01 23:38:54 -08:00
@@ -25,6 +25,7 @@
  *  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/errno.h>
 #include <linux/init.h>
 #include <linux/irq.h>
diff -Nru a/arch/mips/au1000/common/cputable.c b/arch/mips/au1000/common/cputable.c
--- a/arch/mips/au1000/common/cputable.c	2005-03-01 23:38:52 -08:00
+++ b/arch/mips/au1000/common/cputable.c	2005-03-01 23:38:52 -08:00
@@ -11,8 +11,6 @@
  *  as published by the Free Software Foundation; either version
  *  2 of the License, or (at your option) any later version.
  */
-
-#include <linux/config.h>
 #include <linux/string.h>
 #include <linux/sched.h>
 #include <linux/threads.h>
diff -Nru a/arch/mips/au1000/common/dbdma.c b/arch/mips/au1000/common/dbdma.c
--- a/arch/mips/au1000/common/dbdma.c	2005-03-01 23:38:54 -08:00
+++ b/arch/mips/au1000/common/dbdma.c	2005-03-01 23:38:54 -08:00
@@ -29,7 +29,7 @@
  *  675 Mass Ave, Cambridge, MA 02139, USA.
  *
  */
-
+#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/sched.h>
@@ -55,7 +55,7 @@
  * functions.  The drivers allocate the data buffers and assign them
  * to the descriptors.
  */
-static spinlock_t au1xxx_dbdma_spin_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(au1xxx_dbdma_spin_lock);
 
 /* I couldn't find a macro that did this......
 */
@@ -370,7 +370,7 @@
 	 * and if we try that first we are likely to not waste larger
 	 * slabs of memory.
 	 */
-	desc_base = kmalloc(entries * sizeof(au1x_ddma_desc_t), GFP_KERNEL);
+	desc_base = (u32)kmalloc(entries * sizeof(au1x_ddma_desc_t), GFP_KERNEL);
 	if (desc_base == 0)
 		return 0;
 
@@ -381,7 +381,7 @@
 		kfree((const void *)desc_base);
 		i = entries * sizeof(au1x_ddma_desc_t);
 		i += (sizeof(au1x_ddma_desc_t) - 1);
-		if ((desc_base = kmalloc(i, GFP_KERNEL)) == 0)
+		if ((desc_base = (u32)kmalloc(i, GFP_KERNEL)) == 0)
 			return 0;
 
 		desc_base = ALIGN_ADDR(desc_base, sizeof(au1x_ddma_desc_t));
diff -Nru a/arch/mips/au1000/common/dma.c b/arch/mips/au1000/common/dma.c
--- a/arch/mips/au1000/common/dma.c	2005-03-01 23:39:16 -08:00
+++ b/arch/mips/au1000/common/dma.c	2005-03-01 23:39:16 -08:00
@@ -7,6 +7,7 @@
  * Copyright 2000 MontaVista Software Inc.
  * Author: MontaVista Software, Inc.
  *         	stevel@mvista.com or source@mvista.com
+ * 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
@@ -29,7 +30,7 @@
  *  675 Mass Ave, Cambridge, MA 02139, USA.
  *
  */
-
+#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
@@ -61,7 +62,7 @@
  */
 
 
-spinlock_t au1000_dma_spin_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(au1000_dma_spin_lock);
 
 struct dma_chan au1000_dma_table[NUM_AU1000_DMA_CHANNELS] = {
       {.dev_id = -1,},
diff -Nru a/arch/mips/au1000/common/irq.c b/arch/mips/au1000/common/irq.c
--- a/arch/mips/au1000/common/irq.c	2005-03-01 23:38:55 -08:00
+++ b/arch/mips/au1000/common/irq.c	2005-03-01 23:38:55 -08:00
@@ -86,7 +86,7 @@
 extern void counter0_irq(int irq, void *dev_id, struct pt_regs *regs);
 #endif
 
-static spinlock_t irq_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(irq_lock);
 
 
 static unsigned int startup_irq(unsigned int irq_nr)
diff -Nru a/arch/mips/au1000/common/pci.c b/arch/mips/au1000/common/pci.c
--- a/arch/mips/au1000/common/pci.c	2005-03-01 23:39:09 -08:00
+++ b/arch/mips/au1000/common/pci.c	2005-03-01 23:39:09 -08:00
@@ -78,10 +78,13 @@
 
 #ifdef CONFIG_DMA_NONCOHERENT
 	/* 
-	 *  Set the NC bit in controller for pre-AC silicon
+         *  Set the NC bit in controller for Au1500 pre-AC silicon
 	 */
-	au_writel( 1<<16 | au_readl(Au1500_PCI_CFG), Au1500_PCI_CFG);
-	printk("Non-coherent PCI accesses enabled\n");
+	u32 prid = read_c0_prid();
+	if ( (prid & 0xFF000000) == 0x01000000 && prid < 0x01030202) {
+	       au_writel( 1<<16 | au_readl(Au1500_PCI_CFG), Au1500_PCI_CFG);
+	       printk("Non-coherent PCI accesses enabled\n");
+	}
 #endif
 
 	set_io_port_base(virt_io_addr);
diff -Nru a/arch/mips/au1000/common/platform.c b/arch/mips/au1000/common/platform.c
--- a/arch/mips/au1000/common/platform.c	2005-03-01 23:38:44 -08:00
+++ b/arch/mips/au1000/common/platform.c	2005-03-01 23:38:44 -08:00
@@ -7,7 +7,6 @@
  * 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/device.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
diff -Nru a/arch/mips/au1000/common/power.c b/arch/mips/au1000/common/power.c
--- a/arch/mips/au1000/common/power.c	2005-03-01 23:39:16 -08:00
+++ b/arch/mips/au1000/common/power.c	2005-03-01 23:39:16 -08:00
@@ -66,7 +66,7 @@
 #define	ACPI_SLEEP 21
 
 
-static spinlock_t pm_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(pm_lock);
 
 /* We need to save/restore a bunch of core registers that are
  * either volatile or reset to some state across a processor sleep.
diff -Nru a/arch/mips/au1000/common/sleeper.S b/arch/mips/au1000/common/sleeper.S
--- a/arch/mips/au1000/common/sleeper.S	2005-03-01 23:39:10 -08:00
+++ b/arch/mips/au1000/common/sleeper.S	2005-03-01 23:39:10 -08:00
@@ -9,7 +9,6 @@
  * Free Software Foundation;  either version 2 of the  License, or (at your
  * option) any later version.
  */
-#include <linux/config.h>
 #include <asm/asm.h>
 #include <asm/mipsregs.h>
 #include <asm/addrspace.h>
diff -Nru a/arch/mips/au1000/common/time.c b/arch/mips/au1000/common/time.c
--- a/arch/mips/au1000/common/time.c	2005-03-01 23:38:55 -08:00
+++ b/arch/mips/au1000/common/time.c	2005-03-01 23:38:55 -08:00
@@ -69,7 +69,7 @@
 static unsigned long last_pc0, last_match20;
 #endif
 
-static spinlock_t time_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(time_lock);
 
 static inline void ack_r4ktimer(unsigned long newval)
 {
@@ -304,8 +304,7 @@
 
 /* This is for machines which generate the exact clock. */
 #define USECS_PER_JIFFY (1000000/HZ)
-#define USECS_PER_JIFFY_FRAC (0x100000000*1000000/HZ&0xffffffff)
-
+#define USECS_PER_JIFFY_FRAC (0x100000000LL*1000000/HZ&0xffffffff)
 
 static unsigned long
 div64_32(unsigned long v1, unsigned long v2, unsigned long v3)
@@ -406,10 +405,6 @@
 
 	r4k_cur = (read_c0_count() + r4k_offset);
 	write_c0_compare(r4k_cur);
-
-	/* no RTC on the pb1000 */
-	xtime.tv_sec = 0;
-	//xtime.tv_usec = 0;
 
 #ifdef CONFIG_PM
 	/*
diff -Nru a/arch/mips/au1000/common/usbdev.c b/arch/mips/au1000/common/usbdev.c
--- a/arch/mips/au1000/common/usbdev.c	2005-03-01 23:39:18 -08:00
+++ b/arch/mips/au1000/common/usbdev.c	2005-03-01 23:39:18 -08:00
@@ -766,7 +766,7 @@
 							 dev->conf_desc),
 					    0);
 				} else {
-				int len = dev->conf_desc->wTotalLength;
+				int len = le16_to_cpu(dev->conf_desc->wTotalLength);
 				dbg("sending whole config desc,"
 				    " size=%d, our size=%d", desc_len, len);
 				desc_len = desc_len > len ? len : desc_len;
@@ -1398,7 +1398,7 @@
 		epd->bEndpointAddress |= (u8)ep->address;
 		ep->direction = epd->bEndpointAddress & 0x80;
 		ep->type = epd->bmAttributes & 0x03;
-		ep->max_pkt_size = epd->wMaxPacketSize;
+		ep->max_pkt_size = le16_to_cpu(epd->wMaxPacketSize);
 		spin_lock_init(&ep->lock);
 		ep->desc = epd;
 		ep->reg = &ep_reg[ep->address];
@@ -1407,7 +1407,7 @@
 	/*
 	 * initialize the full config descriptor
 	 */
-	usbdev.full_conf_desc = fcd = kmalloc(config_desc->wTotalLength,
+	usbdev.full_conf_desc = fcd = kmalloc(le16_to_cpu(config_desc->wTotalLength),
 					      ALLOC_FLAGS);
 	if (!fcd) {
 		err("failed to alloc full config descriptor");
diff -Nru a/arch/mips/au1000/csb250/board_setup.c b/arch/mips/au1000/csb250/board_setup.c
--- a/arch/mips/au1000/csb250/board_setup.c	2005-03-01 23:38:58 -08:00
+++ b/arch/mips/au1000/csb250/board_setup.c	2005-03-01 23:38:58 -08:00
@@ -45,16 +45,6 @@
 #include <asm/au1000.h>
 #include <asm/csb250.h>
 
-#ifdef CONFIG_USB_OHCI
-// Enable the workaround for the OHCI DoneHead
-// register corruption problem.
-#define CONFIG_AU1000_OHCI_FIX
-#endif
-
-#ifdef CONFIG_RTC
-extern struct rtc_ops csb250_rtc_ops;
-#endif
-
 extern int (*board_pci_idsel)(unsigned int devsel, int assert);
 int	csb250_pci_idsel(unsigned int devsel, int assert);
 
@@ -203,7 +193,6 @@
 	au_writel(au_readl(SYS_POWERCTRL) | (0x3 << 5), SYS_POWERCTRL);
 
 #ifdef CONFIG_RTC
-	rtc_ops = &csb250_rtc_ops;
 	// Enable the RTC if not already enabled
 	if (!(au_readl(0xac000028) & 0x20)) {
 		printk("enabling clock ...\n");
diff -Nru a/arch/mips/au1000/db1x00/mirage_ts.c b/arch/mips/au1000/db1x00/mirage_ts.c
--- a/arch/mips/au1000/db1x00/mirage_ts.c	2005-03-01 23:39:07 -08:00
+++ b/arch/mips/au1000/db1x00/mirage_ts.c	2005-03-01 23:39:07 -08:00
@@ -42,6 +42,7 @@
 #include <linux/proc_fs.h>
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
+#include <linux/wait.h>
 
 #include <asm/segment.h>
 #include <asm/irq.h>
@@ -147,10 +148,7 @@
 	ts = wm97xx_ts_get_handle(0);
 
 	/* proceed only after everybody is ready */
-	while ( ! wm97xx_ts_ready(ts) ) {
-		/* give a little time for initializations to complete */
-		interruptible_sleep_on_timeout(&pendown_wait, HZ / 4);
-	}
+	wait_event_timeout(pendown_wait, wm97xx_ts_ready(ts), HZ/4);
 
 	/* board-specific calibration */
 	wm97xx_ts_set_cal(ts,
diff -Nru a/arch/mips/au1000/hydrogen3/board_setup.c b/arch/mips/au1000/hydrogen3/board_setup.c
--- a/arch/mips/au1000/hydrogen3/board_setup.c	2005-03-01 23:38:57 -08:00
+++ b/arch/mips/au1000/hydrogen3/board_setup.c	2005-03-01 23:38:57 -08:00
@@ -45,8 +45,6 @@
 #include <asm/pgtable.h>
 #include <asm/au1000.h>
 
-extern struct rtc_ops no_rtc_ops;
-
 void board_reset (void)
 {
 }
@@ -54,8 +52,6 @@
 void __init board_setup(void)
 {
 	u32 pin_func;
-
-	rtc_ops = &no_rtc_ops;
 
 #ifdef CONFIG_AU1X00_USB_DEVICE
 	// 2nd USB port is USB device
diff -Nru a/arch/mips/au1000/mtx-1/board_setup.c b/arch/mips/au1000/mtx-1/board_setup.c
--- a/arch/mips/au1000/mtx-1/board_setup.c	2005-03-01 23:38:52 -08:00
+++ b/arch/mips/au1000/mtx-1/board_setup.c	2005-03-01 23:38:52 -08:00
@@ -34,24 +34,24 @@
 #include <linux/ioport.h>
 #include <linux/mm.h>
 #include <linux/console.h>
-#include <linux/mc146818rtc.h>
 #include <linux/delay.h>
 
 #include <asm/cpu.h>
 #include <asm/bootinfo.h>
 #include <asm/irq.h>
-#include <asm/keyboard.h>
 #include <asm/mipsregs.h>
 #include <asm/reboot.h>
 #include <asm/pgtable.h>
-#include <asm/au1000.h>
+#include <asm/mach-au1x00/au1000.h>
 
-extern struct rtc_ops no_rtc_ops;
+void board_reset (void)
+{
+	/* Hit BCSR.SYSTEM_CONTROL[SW_RST] */
+	au_writel(0x00000000, 0xAE00001C);
+}
 
 void __init board_setup(void)
 {
-	rtc_ops = &no_rtc_ops;
-
 #if defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE)
 #ifdef CONFIG_AU1X00_USB_DEVICE
 	// 2nd USB port is USB device
@@ -60,7 +60,7 @@
 	// enable USB power switch
 	au_writel( au_readl(GPIO2_DIR) | 0x10, GPIO2_DIR );
 	au_writel( 0x100000, GPIO2_OUTPUT );
-#endif // defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1000_USB_DEVICE)
+#endif // defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE)
 
 #ifdef CONFIG_PCI
 #if defined(__MIPSEB__)
diff -Nru a/arch/mips/au1000/mtx-1/init.c b/arch/mips/au1000/mtx-1/init.c
--- a/arch/mips/au1000/mtx-1/init.c	2005-03-01 23:38:53 -08:00
+++ b/arch/mips/au1000/mtx-1/init.c	2005-03-01 23:38:53 -08:00
@@ -28,17 +28,15 @@
  *  with this program; if not, write  to the Free Software Foundation, Inc.,
  *  675 Mass Ave, Cambridge, MA 02139, USA.
  */
-
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
 #include <linux/init.h>
 #include <linux/mm.h>
 #include <linux/sched.h>
 #include <linux/bootmem.h>
 #include <asm/addrspace.h>
 #include <asm/bootinfo.h>
-#include <linux/config.h>
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
 
 int prom_argc;
 char **prom_argv, **prom_envp;
@@ -50,25 +48,24 @@
 	return "MTX-1";
 }
 
-int __init prom_init(int argc, char **argv, char **envp, int *prom_vec)
+void __init prom_init(void)
 {
 	unsigned char *memsize_str;
 	unsigned long memsize;
 
-	prom_argc = argc;
-	prom_argv = argv;
-	prom_envp = envp;
+	prom_argc = fw_arg0;
+	prom_argv = (char **) fw_arg1;
+	prom_envp = (char **) fw_arg2;
 
 	mips_machgroup = MACH_GROUP_ALCHEMY;
 	mips_machtype = MACH_MTX1;	/* set the platform # */
+
 	prom_init_cmdline();
 
 	memsize_str = prom_getenv("memsize");
-	if (!memsize_str) {
+	if (!memsize_str)
 		memsize = 0x04000000;
-	} else {
+	else
 		memsize = simple_strtol(memsize_str, NULL, 0);
-	}
 	add_memory_region(0, memsize, BOOT_MEM_RAM);
-	return 0;
 }
diff -Nru a/arch/mips/au1000/mtx-1/irqmap.c b/arch/mips/au1000/mtx-1/irqmap.c
--- a/arch/mips/au1000/mtx-1/irqmap.c	2005-03-01 23:38:52 -08:00
+++ b/arch/mips/au1000/mtx-1/irqmap.c	2005-03-01 23:38:52 -08:00
@@ -45,12 +45,14 @@
 #include <asm/io.h>
 #include <asm/mipsregs.h>
 #include <asm/system.h>
-#include <asm/au1000.h>
+#include <asm/mach-au1x00/au1000.h>
 
-/* Need to define this.
-*/
 au1xxx_irq_map_t au1xxx_irq_map[] = {
-	{ 0. 0. 0}
+       { AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0},
+       { AU1500_GPIO_201, INTC_INT_LOW_LEVEL, 0 },
+       { AU1500_GPIO_202, INTC_INT_LOW_LEVEL, 0 },
+       { AU1500_GPIO_203, INTC_INT_LOW_LEVEL, 0 },
+       { AU1500_GPIO_205, INTC_INT_LOW_LEVEL, 0 },
 };
 
-int au1xxx_nr_irqs = 0;
+int au1xxx_nr_irqs = sizeof(au1xxx_irq_map)/sizeof(au1xxx_irq_map_t);
diff -Nru a/arch/mips/au1000/pb1000/board_setup.c b/arch/mips/au1000/pb1000/board_setup.c
--- a/arch/mips/au1000/pb1000/board_setup.c	2005-03-01 23:38:53 -08:00
+++ b/arch/mips/au1000/pb1000/board_setup.c	2005-03-01 23:38:53 -08:00
@@ -37,16 +37,8 @@
 #include <asm/mipsregs.h>
 #include <asm/reboot.h>
 #include <asm/pgtable.h>
-#include <asm/au1000.h>
-#include <asm/pb1000.h>
-
-#ifdef CONFIG_USB_OHCI
-// Enable the workaround for the OHCI DoneHead
-// register corruption problem.
-#define CONFIG_AU1000_OHCI_FIX
-        ^^^^^^^^^^^^^^^^^^^^^^
-    !!! I shall not define symbols starting with CONFIG_ !!!
-#endif
+#include <asm/mach-au1x00/au1000.h>
+#include <asm/mach-pb1x00/pb1000.h>
 
 void board_reset (void)
 {
diff -Nru a/arch/mips/au1000/pb1000/irqmap.c b/arch/mips/au1000/pb1000/irqmap.c
--- a/arch/mips/au1000/pb1000/irqmap.c	2005-03-01 23:39:09 -08:00
+++ b/arch/mips/au1000/pb1000/irqmap.c	2005-03-01 23:39:09 -08:00
@@ -45,7 +45,7 @@
 #include <asm/io.h>
 #include <asm/mipsregs.h>
 #include <asm/system.h>
-#include <asm/au1000.h>
+#include <asm/mach-au1x00/au1000.h>
 
 au1xxx_irq_map_t au1xxx_irq_map[] = {
 	{ AU1000_GPIO_15, INTC_INT_LOW_LEVEL, 0 },
diff -Nru a/arch/mips/au1000/pb1100/board_setup.c b/arch/mips/au1000/pb1100/board_setup.c
--- a/arch/mips/au1000/pb1100/board_setup.c	2005-03-01 23:39:09 -08:00
+++ b/arch/mips/au1000/pb1100/board_setup.c	2005-03-01 23:39:09 -08:00
@@ -40,14 +40,6 @@
 #include <asm/mach-au1x00/au1000.h>
 #include <asm/mach-pb1x00/pb1100.h>
 
-#ifdef CONFIG_USB_OHCI
-// Enable the workaround for the OHCI DoneHead
-// register corruption problem.
-#define CONFIG_AU1000_OHCI_FIX
-        ^^^^^^^^^^^^^^^^^^^^^^
-    !!! I shall not define symbols starting with CONFIG_ !!!
-#endif
-
 void board_reset (void)
 {
     /* Hit BCSR.SYSTEM_CONTROL[SW_RST] */
diff -Nru a/arch/mips/au1000/pb1500/board_setup.c b/arch/mips/au1000/pb1500/board_setup.c
--- a/arch/mips/au1000/pb1500/board_setup.c	2005-03-01 23:38:52 -08:00
+++ b/arch/mips/au1000/pb1500/board_setup.c	2005-03-01 23:38:52 -08:00
@@ -40,14 +40,6 @@
 #include <asm/mach-au1x00/au1000.h>
 #include <asm/mach-pb1x00/pb1500.h>
 
-#ifdef CONFIG_USB_OHCI
-// Enable the workaround for the OHCI DoneHead
-// register corruption problem.
-#define CONFIG_AU1000_OHCI_FIX
-        ^^^^^^^^^^^^^^^^^^^^^^
-    !!! I shall not define symbols starting with CONFIG_ !!!
-#endif
-
 void board_reset (void)
 {
     /* Hit BCSR.SYSTEM_CONTROL[SW_RST] */
diff -Nru a/arch/mips/au1000/pb1550/board_setup.c b/arch/mips/au1000/pb1550/board_setup.c
--- a/arch/mips/au1000/pb1550/board_setup.c	2005-03-01 23:39:09 -08:00
+++ b/arch/mips/au1000/pb1550/board_setup.c	2005-03-01 23:39:09 -08:00
@@ -27,7 +27,6 @@
  *  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/sched.h>
 #include <linux/ioport.h>
diff -Nru a/arch/mips/configs/atlas_defconfig b/arch/mips/configs/atlas_defconfig
--- a/arch/mips/configs/atlas_defconfig	2005-03-01 23:39:10 -08:00
+++ b/arch/mips/configs/atlas_defconfig	2005-03-01 23:39:10 -08:00
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc2
-# Sun Nov 21 14:11:55 2004
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:00 2005
 #
 CONFIG_MIPS=y
 # CONFIG_MIPS64 is not set
@@ -26,7 +26,7 @@
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
+CONFIG_HOTPLUG=y
 CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 CONFIG_EMBEDDED=y
@@ -45,7 +45,13 @@
 #
 # 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=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
 
 #
 # Machine selection
@@ -79,6 +85,7 @@
 # CONFIG_SNI_RM200_PCI is not set
 # CONFIG_TOSHIBA_RBTX4927 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_HAVE_DEC_LOCK=y
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_MIPS_BONITO64=y
@@ -89,7 +96,6 @@
 CONFIG_SWAP_IO_SPACE=y
 CONFIG_BOOT_ELF32=y
 CONFIG_MIPS_L1_CACHE_SHIFT=5
-# CONFIG_FB is not set
 
 #
 # CPU selection
@@ -116,7 +122,6 @@
 # CONFIG_PAGE_SIZE_16KB is not set
 # CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_CPU_HAS_PREFETCH=y
-# CONFIG_VTAG_ICACHE is not set
 # CONFIG_64BIT_PHYS_ADDR is not set
 # CONFIG_CPU_ADVANCED is not set
 CONFIG_CPU_HAS_LLSC=y
@@ -133,6 +138,20 @@
 CONFIG_MMU=y
 
 #
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
@@ -148,6 +167,7 @@
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
 
 #
 # Memory Technology Devices (MTD)
@@ -170,17 +190,19 @@
 # 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_LOOP=y
-# CONFIG_BLK_DEV_CRYPTOLOOP is not set
-# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_UMEM=m
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
 # CONFIG_BLK_DEV_SX8 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_LBD is not set
-CONFIG_CDROM_PKTCDVD=y
+CONFIG_CDROM_PKTCDVD=m
 CONFIG_CDROM_PKTCDVD_BUFFERS=8
 # CONFIG_CDROM_PKTCDVD_WCACHE is not set
 
@@ -191,11 +213,35 @@
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
 
 #
 # ATA/ATAPI/MFM/RLL support
 #
-# CONFIG_IDE is not set
+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_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 is not set
+# 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
@@ -207,23 +253,25 @@
 # SCSI support type (disk, tape, CD-ROM)
 #
 CONFIG_BLK_DEV_SD=y
-# CONFIG_CHR_DEV_ST is not set
-# CONFIG_CHR_DEV_OSST is not set
-# CONFIG_BLK_DEV_SR is not set
-# CONFIG_CHR_DEV_SG is not set
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
+CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=m
 
 #
 # 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
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
 
 #
 # SCSI Transport Attributes
 #
-# CONFIG_SCSI_SPI_ATTRS is not set
-# CONFIG_SCSI_FC_ATTRS is not set
+CONFIG_SCSI_SPI_ATTRS=y
+CONFIG_SCSI_FC_ATTRS=m
+CONFIG_SCSI_ISCSI_ATTRS=m
 
 #
 # SCSI low-level drivers
@@ -248,19 +296,21 @@
 # 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_SYM53C8XX_2=y
+CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0
+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_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_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_NSP32 is not set
@@ -269,7 +319,21 @@
 #
 # Multi-device support (RAID and LVM)
 #
-# CONFIG_MD is not set
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=m
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID5=m
+CONFIG_MD_RAID6=m
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
 
 #
 # Fusion MPT device support
@@ -295,54 +359,260 @@
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
+CONFIG_PACKET_MMAP=y
 CONFIG_NETLINK_DEV=y
 CONFIG_UNIX=y
 CONFIG_NET_KEY=y
 CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_FWMARK=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
 CONFIG_IP_PNP=y
-# CONFIG_IP_PNP_DHCP is not set
-# CONFIG_IP_PNP_BOOTP is not set
+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_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
 # 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=y
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_TUNNEL=m
+CONFIG_IP_TCPDIAG=m
+CONFIG_IP_TCPDIAG_IPV6=y
+
+#
+# IP: Virtual Server Configuration
+#
+CONFIG_IP_VS=m
+# CONFIG_IP_VS_DEBUG is not set
+CONFIG_IP_VS_TAB_BITS=12
+
+#
+# IPVS transport protocol load balancing support
+#
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_PROTO_ESP=y
+CONFIG_IP_VS_PROTO_AH=y
+
+#
+# IPVS scheduler
+#
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_WRR=m
+CONFIG_IP_VS_LC=m
+CONFIG_IP_VS_WLC=m
+CONFIG_IP_VS_LBLC=m
+CONFIG_IP_VS_LBLCR=m
+CONFIG_IP_VS_DH=m
+CONFIG_IP_VS_SH=m
+CONFIG_IP_VS_SED=m
+CONFIG_IP_VS_NQ=m
+
+#
+# IPVS application helper
+#
+CONFIG_IP_VS_FTP=m
+CONFIG_IPV6=m
+CONFIG_IPV6_PRIVACY=y
+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
+CONFIG_BRIDGE_NETFILTER=y
+
+#
+# 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_PHYSDEV=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
+
+#
+# IPv6: Netfilter Configuration
+#
+CONFIG_IP6_NF_QUEUE=m
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_MATCH_LIMIT=m
+CONFIG_IP6_NF_MATCH_MAC=m
+CONFIG_IP6_NF_MATCH_RT=m
+CONFIG_IP6_NF_MATCH_OPTS=m
+CONFIG_IP6_NF_MATCH_FRAG=m
+CONFIG_IP6_NF_MATCH_HL=m
+CONFIG_IP6_NF_MATCH_MULTIPORT=m
+CONFIG_IP6_NF_MATCH_OWNER=m
+CONFIG_IP6_NF_MATCH_MARK=m
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+CONFIG_IP6_NF_MATCH_AHESP=m
+CONFIG_IP6_NF_MATCH_LENGTH=m
+CONFIG_IP6_NF_MATCH_EUI64=m
+CONFIG_IP6_NF_MATCH_PHYSDEV=m
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_MANGLE=m
+CONFIG_IP6_NF_TARGET_MARK=m
+CONFIG_IP6_NF_RAW=m
+
+#
+# Bridge: Netfilter Configuration
+#
+CONFIG_BRIDGE_NF_EBTABLES=m
+CONFIG_BRIDGE_EBT_BROUTE=m
+CONFIG_BRIDGE_EBT_T_FILTER=m
+CONFIG_BRIDGE_EBT_T_NAT=m
+CONFIG_BRIDGE_EBT_802_3=m
+CONFIG_BRIDGE_EBT_AMONG=m
+CONFIG_BRIDGE_EBT_ARP=m
+CONFIG_BRIDGE_EBT_IP=m
+CONFIG_BRIDGE_EBT_LIMIT=m
+CONFIG_BRIDGE_EBT_MARK=m
+CONFIG_BRIDGE_EBT_PKTTYPE=m
+CONFIG_BRIDGE_EBT_STP=m
+CONFIG_BRIDGE_EBT_VLAN=m
+CONFIG_BRIDGE_EBT_ARPREPLY=m
+CONFIG_BRIDGE_EBT_DNAT=m
+CONFIG_BRIDGE_EBT_MARK_T=m
+CONFIG_BRIDGE_EBT_REDIRECT=m
+CONFIG_BRIDGE_EBT_SNAT=m
+CONFIG_BRIDGE_EBT_LOG=m
+CONFIG_BRIDGE_EBT_ULOG=m
 CONFIG_XFRM=y
-CONFIG_XFRM_USER=y
+CONFIG_XFRM_USER=m
 
 #
 # SCTP Configuration (EXPERIMENTAL)
 #
-# CONFIG_IP_SCTP is not set
+CONFIG_IP_SCTP=m
+# CONFIG_SCTP_DBG_MSG is not set
+# CONFIG_SCTP_DBG_OBJCNT is not set
+# CONFIG_SCTP_HMAC_NONE is not set
+# CONFIG_SCTP_HMAC_SHA1 is not set
+CONFIG_SCTP_HMAC_MD5=y
 # CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
 # CONFIG_DECNET is not set
+CONFIG_LLC=m
 # CONFIG_LLC2 is not set
 # CONFIG_IPX is not set
-# CONFIG_ATALK is not set
+CONFIG_ATALK=m
+CONFIG_DEV_APPLETALK=y
+CONFIG_IPDDP=m
+CONFIG_IPDDP_ENCAP=y
+CONFIG_IPDDP_DECAP=y
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
+CONFIG_NET_DIVERT=y
 # 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
+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=m
+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=m
+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=y
+# CONFIG_CLS_U32_MARK 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
@@ -354,10 +624,10 @@
 # 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_DUMMY=m
+CONFIG_BONDING=m
+CONFIG_EQUALIZER=m
+CONFIG_TUN=m
 # CONFIG_ETHERTAP is not set
 
 #
@@ -369,7 +639,7 @@
 # Ethernet (10 or 100Mbit)
 #
 CONFIG_NET_ETHERNET=y
-# CONFIG_MII is not set
+CONFIG_MII=y
 # CONFIG_HAPPYMEAL is not set
 # CONFIG_SUNGEM is not set
 # CONFIG_NET_VENDOR_3COM is not set
@@ -379,7 +649,26 @@
 #
 # CONFIG_NET_TULIP is not set
 # CONFIG_HP100 is not set
-# CONFIG_NET_PCI is not set
+CONFIG_NET_PCI=y
+CONFIG_PCNET32=y
+# 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 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
+CONFIG_LAN_SAA9730=y
 
 #
 # Ethernet (1000 Mbit)
@@ -392,6 +681,7 @@
 # CONFIG_YELLOWFIN is not set
 # CONFIG_R8169 is not set
 # CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 
 #
@@ -440,7 +730,7 @@
 #
 # Userland interfaces
 #
-CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV=m
 CONFIG_INPUT_MOUSEDEV_PSAUX=y
 CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
 CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
@@ -459,13 +749,17 @@
 CONFIG_SERIO_SERPORT=y
 # CONFIG_SERIO_CT82C710 is not set
 # CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
 CONFIG_SERIO_RAW=y
 
 #
 # Input Device Drivers
 #
 # CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_MOUSE=y
+# CONFIG_MOUSE_PS2 is not set
+CONFIG_MOUSE_SERIAL=m
+# CONFIG_MOUSE_VSXXXAA is not set
 # CONFIG_INPUT_JOYSTICK is not set
 # CONFIG_INPUT_TOUCHSCREEN is not set
 # CONFIG_INPUT_MISC is not set
@@ -513,7 +807,6 @@
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_AGP is not set
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -544,12 +837,14 @@
 #
 # 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
@@ -564,38 +859,81 @@
 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=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_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
-# CONFIG_QUOTA 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=m
+# CONFIG_REISERFS_CHECK is not set
+CONFIG_REISERFS_PROC_INFO=y
+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
+CONFIG_XFS_FS=m
+# CONFIG_XFS_RT is not set
+CONFIG_XFS_QUOTA=y
+CONFIG_XFS_SECURITY=y
+CONFIG_XFS_POSIX_ACL=y
+CONFIG_MINIX_FS=m
+CONFIG_ROMFS_FS=m
+CONFIG_QUOTA=y
+# CONFIG_QFMT_V1 is not set
+CONFIG_QFMT_V2=y
+CONFIG_QUOTACTL=y
 CONFIG_DNOTIFY=y
-# CONFIG_AUTOFS_FS is not set
+CONFIG_AUTOFS_FS=y
 # CONFIG_AUTOFS4_FS is not set
 
 #
 # CD-ROM/DVD Filesystems
 #
-# CONFIG_ISO9660_FS is not set
-# CONFIG_UDF_FS is not set
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_ZISOFS_FS=m
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
 
 #
 # DOS/FAT/NT Filesystems
 #
-# CONFIG_MSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
+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
 
 #
@@ -615,18 +953,20 @@
 # 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_AFFS_FS=m
+CONFIG_HFS_FS=m
+CONFIG_HFSPLUS_FS=m
+CONFIG_BEFS_FS=m
+# CONFIG_BEFS_DEBUG is not set
+CONFIG_BFS_FS=m
+CONFIG_EFS_FS=m
+CONFIG_CRAMFS=m
+CONFIG_VXFS_FS=m
 # 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_SYSV_FS=m
+CONFIG_UFS_FS=m
+# CONFIG_UFS_FS_WRITE is not set
 
 #
 # Network File Systems
@@ -635,11 +975,14 @@
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V4 is not set
 # CONFIG_NFS_DIRECTIO is not set
-# CONFIG_NFSD is not set
+CONFIG_NFSD=y
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V4 is not set
+# CONFIG_NFSD_TCP is not set
 CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
-# CONFIG_EXPORTFS is not set
+CONFIG_EXPORTFS=y
 CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -658,7 +1001,51 @@
 #
 # Native Language Support
 #
-# CONFIG_NLS is not set
+CONFIG_NLS=m
+CONFIG_NLS_DEFAULT="iso8859-1"
+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=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
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
 
 #
 # Kernel hacking
@@ -670,20 +1057,48 @@
 #
 # Security options
 #
-CONFIG_KEYS=y
-CONFIG_KEYS_DEBUG_PROC_KEYS=y
+# CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 
 #
 # Cryptographic options
 #
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
 
 #
 # Library routines
 #
 # CONFIG_CRC_CCITT is not set
-# CONFIG_CRC32 is not set
-# CONFIG_LIBCRC32C is not set
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
diff -Nru a/arch/mips/configs/capcella_defconfig b/arch/mips/configs/capcella_defconfig
--- a/arch/mips/configs/capcella_defconfig	2005-03-01 23:38:53 -08:00
+++ b/arch/mips/configs/capcella_defconfig	2005-03-01 23:38:53 -08:00
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc2
-# Sun Nov 21 14:11:55 2004
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:00 2005
 #
 CONFIG_MIPS=y
 # CONFIG_MIPS64 is not set
@@ -58,6 +58,7 @@
 #
 # CONFIG_MACH_JAZZ is not set
 CONFIG_MACH_VR41XX=y
+# CONFIG_NEC_CMBVR4133 is not set
 # CONFIG_CASIO_E55 is not set
 # CONFIG_IBM_WORKPAD is not set
 # CONFIG_TANBAC_TB0226 is not set
@@ -93,12 +94,12 @@
 # CONFIG_SNI_RM200_PCI is not set
 # CONFIG_TOSHIBA_RBTX4927 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_HAVE_DEC_LOCK=y
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_CPU_LITTLE_ENDIAN=y
 CONFIG_IRQ_CPU=y
 CONFIG_MIPS_L1_CACHE_SHIFT=5
-# CONFIG_FB is not set
 
 #
 # CPU selection
@@ -138,6 +139,20 @@
 CONFIG_MMU=y
 
 #
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
@@ -153,6 +168,7 @@
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -176,10 +192,12 @@
 # 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_LBD is not set
 CONFIG_CDROM_PKTCDVD=m
@@ -193,6 +211,7 @@
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -418,6 +437,7 @@
 CONFIG_SERIO_SERPORT=y
 # CONFIG_SERIO_CT82C710 is not set
 # CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=m
 CONFIG_SERIO_RAW=m
 
 #
@@ -484,7 +504,6 @@
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_AGP is not set
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -515,12 +534,14 @@
 #
 # 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
@@ -535,11 +556,25 @@
 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=y
@@ -633,6 +668,11 @@
 # CONFIG_NLS is not set
 
 #
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
 # Kernel hacking
 #
 # CONFIG_DEBUG_KERNEL is not set
@@ -650,6 +690,10 @@
 # Cryptographic options
 #
 # CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
 
 #
 # Library routines
diff -Nru a/arch/mips/configs/cobalt_defconfig b/arch/mips/configs/cobalt_defconfig
--- a/arch/mips/configs/cobalt_defconfig	2005-03-01 23:38:54 -08:00
+++ b/arch/mips/configs/cobalt_defconfig	2005-03-01 23:38:54 -08:00
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc2
-# Sun Nov 21 14:11:55 2004
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:00 2005
 #
 CONFIG_MIPS=y
 # CONFIG_MIPS64 is not set
@@ -26,7 +26,7 @@
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
+CONFIG_HOTPLUG=y
 CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 CONFIG_EMBEDDED=y
@@ -79,6 +79,7 @@
 # CONFIG_SNI_RM200_PCI is not set
 # CONFIG_TOSHIBA_RBTX4927 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_HAVE_DEC_LOCK=y
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_I8259=y
@@ -86,7 +87,6 @@
 CONFIG_IRQ_CPU=y
 CONFIG_MIPS_GT64111=y
 CONFIG_MIPS_L1_CACHE_SHIFT=5
-# CONFIG_FB is not set
 
 #
 # CPU selection
@@ -128,6 +128,20 @@
 CONFIG_MMU=y
 
 #
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
@@ -143,6 +157,7 @@
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
 
 #
 # Memory Technology Devices (MTD)
@@ -166,11 +181,13 @@
 # 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_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_LBD is not set
 CONFIG_CDROM_PKTCDVD=y
@@ -184,6 +201,7 @@
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=y
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -405,6 +423,7 @@
 CONFIG_SERIO_SERPORT=y
 # CONFIG_SERIO_CT82C710 is not set
 # CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
 CONFIG_SERIO_RAW=y
 
 #
@@ -459,7 +478,6 @@
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_AGP is not set
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -490,12 +508,14 @@
 #
 # 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
@@ -510,11 +530,25 @@
 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=y
@@ -609,6 +643,11 @@
 # CONFIG_NLS is not set
 
 #
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
 # Kernel hacking
 #
 # CONFIG_DEBUG_KERNEL is not set
@@ -626,6 +665,10 @@
 # Cryptographic options
 #
 # CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
 
 #
 # Library routines
diff -Nru a/arch/mips/configs/db1000_defconfig b/arch/mips/configs/db1000_defconfig
--- a/arch/mips/configs/db1000_defconfig	2005-03-01 23:39:18 -08:00
+++ b/arch/mips/configs/db1000_defconfig	2005-03-01 23:39:18 -08:00
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc2
-# Sun Nov 21 14:11:56 2004
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:01 2005
 #
 CONFIG_MIPS=y
 # CONFIG_MIPS64 is not set
@@ -101,11 +101,11 @@
 # CONFIG_SNI_RM200_PCI is not set
 # CONFIG_TOSHIBA_RBTX4927 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_HAVE_DEC_LOCK=y
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_CPU_LITTLE_ENDIAN=y
 CONFIG_MIPS_L1_CACHE_SHIFT=5
-# CONFIG_FB is not set
 
 #
 # CPU selection
@@ -132,7 +132,6 @@
 # CONFIG_PAGE_SIZE_16KB is not set
 # CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_CPU_HAS_PREFETCH=y
-# CONFIG_VTAG_ICACHE is not set
 CONFIG_64BIT_PHYS_ADDR=y
 # CONFIG_CPU_ADVANCED is not set
 CONFIG_CPU_HAS_LLSC=y
@@ -151,7 +150,6 @@
 #
 CONFIG_PCCARD=m
 # CONFIG_PCMCIA_DEBUG is not set
-# CONFIG_PCMCIA_OBSOLETE is not set
 CONFIG_PCMCIA=m
 
 #
@@ -200,10 +198,12 @@
 # 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=m
@@ -217,6 +217,7 @@
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -293,8 +294,6 @@
 # CONFIG_IP_NF_QUEUE is not set
 # CONFIG_IP_NF_IPTABLES is not set
 # CONFIG_IP_NF_ARPTABLES is not set
-# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
-# CONFIG_IP_NF_COMPAT_IPFWADM is not set
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
 
@@ -426,6 +425,7 @@
 # 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=m
 
 #
@@ -479,7 +479,6 @@
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_AGP is not set
 # CONFIG_DRM is not set
 
 #
@@ -515,12 +514,14 @@
 #
 # 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
@@ -534,11 +535,25 @@
 # 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=y
@@ -686,6 +701,11 @@
 # CONFIG_NLS_UTF8 is not set
 
 #
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
 # Kernel hacking
 #
 # CONFIG_DEBUG_KERNEL is not set
@@ -726,6 +746,10 @@
 CONFIG_CRYPTO_MICHAEL_MIC=y
 CONFIG_CRYPTO_CRC32C=m
 # CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
 
 #
 # Library routines
diff -Nru a/arch/mips/configs/db1100_defconfig b/arch/mips/configs/db1100_defconfig
--- a/arch/mips/configs/db1100_defconfig	2005-03-01 23:38:55 -08:00
+++ b/arch/mips/configs/db1100_defconfig	2005-03-01 23:38:55 -08:00
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc2
-# Sun Nov 21 14:11:56 2004
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:01 2005
 #
 CONFIG_MIPS=y
 # CONFIG_MIPS64 is not set
@@ -101,11 +101,11 @@
 # CONFIG_SNI_RM200_PCI is not set
 # CONFIG_TOSHIBA_RBTX4927 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_HAVE_DEC_LOCK=y
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_CPU_LITTLE_ENDIAN=y
 CONFIG_MIPS_L1_CACHE_SHIFT=5
-# CONFIG_FB is not set
 
 #
 # CPU selection
@@ -132,7 +132,6 @@
 # CONFIG_PAGE_SIZE_16KB is not set
 # CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_CPU_HAS_PREFETCH=y
-# CONFIG_VTAG_ICACHE is not set
 # CONFIG_64BIT_PHYS_ADDR is not set
 # CONFIG_CPU_ADVANCED is not set
 CONFIG_CPU_HAS_LLSC=y
@@ -149,7 +148,6 @@
 #
 CONFIG_PCCARD=m
 # CONFIG_PCMCIA_DEBUG is not set
-# CONFIG_PCMCIA_OBSOLETE is not set
 CONFIG_PCMCIA=m
 
 #
@@ -198,10 +196,12 @@
 # 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=m
@@ -215,6 +215,7 @@
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -291,8 +292,6 @@
 # CONFIG_IP_NF_QUEUE is not set
 # CONFIG_IP_NF_IPTABLES is not set
 # CONFIG_IP_NF_ARPTABLES is not set
-# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
-# CONFIG_IP_NF_COMPAT_IPFWADM is not set
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
 
@@ -424,6 +423,7 @@
 # CONFIG_SERIO_I8042 is not set
 CONFIG_SERIO_SERPORT=y
 # CONFIG_SERIO_CT82C710 is not set
+CONFIG_SERIO_LIBPS2=m
 CONFIG_SERIO_RAW=m
 
 #
@@ -474,7 +474,6 @@
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_AGP is not set
 # CONFIG_DRM is not set
 
 #
@@ -510,12 +509,14 @@
 #
 # 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
@@ -529,11 +530,25 @@
 # 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=y
@@ -681,6 +696,11 @@
 # CONFIG_NLS_UTF8 is not set
 
 #
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
 # Kernel hacking
 #
 # CONFIG_DEBUG_KERNEL is not set
@@ -721,6 +741,10 @@
 CONFIG_CRYPTO_MICHAEL_MIC=y
 CONFIG_CRYPTO_CRC32C=m
 # CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
 
 #
 # Library routines
diff -Nru a/arch/mips/configs/db1500_defconfig b/arch/mips/configs/db1500_defconfig
--- a/arch/mips/configs/db1500_defconfig	2005-03-01 23:38:56 -08:00
+++ b/arch/mips/configs/db1500_defconfig	2005-03-01 23:38:56 -08:00
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc2
-# Sun Nov 21 14:11:56 2004
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:01 2005
 #
 CONFIG_MIPS=y
 # CONFIG_MIPS64 is not set
@@ -101,12 +101,12 @@
 # CONFIG_SNI_RM200_PCI is not set
 # CONFIG_TOSHIBA_RBTX4927 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_HAVE_DEC_LOCK=y
 CONFIG_DMA_COHERENT=y
 CONFIG_MIPS_DISABLE_OBSOLETE_IDE=y
 CONFIG_CPU_LITTLE_ENDIAN=y
 CONFIG_MIPS_L1_CACHE_SHIFT=5
-# CONFIG_FB is not set
 
 #
 # CPU selection
@@ -133,7 +133,6 @@
 # CONFIG_PAGE_SIZE_16KB is not set
 # CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_CPU_HAS_PREFETCH=y
-# CONFIG_VTAG_ICACHE is not set
 CONFIG_64BIT_PHYS_ADDR=y
 # CONFIG_CPU_ADVANCED is not set
 CONFIG_CPU_HAS_LLSC=y
@@ -154,7 +153,6 @@
 #
 CONFIG_PCCARD=m
 # CONFIG_PCMCIA_DEBUG is not set
-# CONFIG_PCMCIA_OBSOLETE is not set
 CONFIG_PCMCIA=m
 CONFIG_CARDBUS=y
 
@@ -234,6 +232,7 @@
 # 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
@@ -252,6 +251,7 @@
 # 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
@@ -282,12 +282,14 @@
 # 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 is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_LBD is not set
 CONFIG_CDROM_PKTCDVD=m
@@ -301,6 +303,7 @@
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -402,8 +405,6 @@
 # CONFIG_IP_NF_QUEUE is not set
 # CONFIG_IP_NF_IPTABLES is not set
 # CONFIG_IP_NF_ARPTABLES is not set
-# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
-# CONFIG_IP_NF_COMPAT_IPFWADM is not set
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
 
@@ -557,6 +558,7 @@
 CONFIG_SERIO_SERPORT=y
 # CONFIG_SERIO_CT82C710 is not set
 # CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
 CONFIG_SERIO_RAW=m
 
 #
@@ -609,7 +611,6 @@
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_AGP is not set
 # CONFIG_DRM is not set
 
 #
@@ -645,6 +646,8 @@
 #
 # Graphics support
 #
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -705,6 +708,7 @@
 # CONFIG_USB_EHCI_HCD is not set
 CONFIG_USB_OHCI_HCD=y
 # CONFIG_USB_UHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
 
 #
 # USB Device Class drivers
@@ -714,6 +718,10 @@
 # CONFIG_USB_MIDI 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
 
 #
@@ -769,7 +777,6 @@
 #
 # 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
@@ -778,6 +785,7 @@
 # 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 ATM/DSL drivers
@@ -789,6 +797,16 @@
 # 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
@@ -938,6 +956,11 @@
 # CONFIG_NLS_UTF8 is not set
 
 #
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
 # Kernel hacking
 #
 # CONFIG_DEBUG_KERNEL is not set
@@ -978,6 +1001,10 @@
 CONFIG_CRYPTO_MICHAEL_MIC=y
 CONFIG_CRYPTO_CRC32C=m
 # CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
 
 #
 # Library routines
diff -Nru a/arch/mips/configs/db1550_defconfig b/arch/mips/configs/db1550_defconfig
--- a/arch/mips/configs/db1550_defconfig	2005-03-01 23:38:52 -08:00
+++ b/arch/mips/configs/db1550_defconfig	2005-03-01 23:38:52 -08:00
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc2
-# Sun Nov 21 14:11:57 2004
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:02 2005
 #
 CONFIG_MIPS=y
 # CONFIG_MIPS64 is not set
@@ -101,12 +101,12 @@
 # CONFIG_SNI_RM200_PCI is not set
 # CONFIG_TOSHIBA_RBTX4927 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_HAVE_DEC_LOCK=y
 CONFIG_DMA_COHERENT=y
 CONFIG_MIPS_DISABLE_OBSOLETE_IDE=y
 CONFIG_CPU_LITTLE_ENDIAN=y
 CONFIG_MIPS_L1_CACHE_SHIFT=5
-# CONFIG_FB is not set
 
 #
 # CPU selection
@@ -133,7 +133,6 @@
 # CONFIG_PAGE_SIZE_16KB is not set
 # CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_CPU_HAS_PREFETCH=y
-# CONFIG_VTAG_ICACHE is not set
 CONFIG_64BIT_PHYS_ADDR=y
 # CONFIG_CPU_ADVANCED is not set
 CONFIG_CPU_HAS_LLSC=y
@@ -154,7 +153,6 @@
 #
 CONFIG_PCCARD=m
 # CONFIG_PCMCIA_DEBUG is not set
-# CONFIG_PCMCIA_OBSOLETE is not set
 CONFIG_PCMCIA=m
 CONFIG_CARDBUS=y
 
@@ -252,6 +250,7 @@
 # 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
@@ -268,6 +267,7 @@
 CONFIG_MTD_NAND_IDS=m
 CONFIG_MTD_NAND_AU1550=m
 # CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
 
 #
 # Parallel port support
@@ -286,11 +286,13 @@
 # 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_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_LBD is not set
 CONFIG_CDROM_PKTCDVD=m
@@ -304,6 +306,7 @@
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -433,8 +436,6 @@
 # CONFIG_IP_NF_QUEUE is not set
 # CONFIG_IP_NF_IPTABLES is not set
 # CONFIG_IP_NF_ARPTABLES is not set
-# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
-# CONFIG_IP_NF_COMPAT_IPFWADM is not set
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
 
@@ -596,6 +597,7 @@
 CONFIG_SERIO_SERPORT=y
 # CONFIG_SERIO_CT82C710 is not set
 # CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
 CONFIG_SERIO_RAW=m
 
 #
@@ -649,7 +651,6 @@
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_AGP is not set
 # CONFIG_DRM is not set
 
 #
@@ -685,6 +686,8 @@
 #
 # Graphics support
 #
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -699,11 +702,25 @@
 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=y
@@ -853,6 +870,11 @@
 # CONFIG_NLS_UTF8 is not set
 
 #
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
 # Kernel hacking
 #
 # CONFIG_DEBUG_KERNEL is not set
@@ -893,6 +915,10 @@
 CONFIG_CRYPTO_MICHAEL_MIC=y
 CONFIG_CRYPTO_CRC32C=m
 # CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
 
 #
 # Library routines
diff -Nru a/arch/mips/configs/ddb5476_defconfig b/arch/mips/configs/ddb5476_defconfig
--- a/arch/mips/configs/ddb5476_defconfig	2005-03-01 23:39:18 -08:00
+++ b/arch/mips/configs/ddb5476_defconfig	2005-03-01 23:39:18 -08:00
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc2
-# Sun Nov 21 14:11:57 2004
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:02 2005
 #
 CONFIG_MIPS=y
 # CONFIG_MIPS64 is not set
@@ -79,6 +79,7 @@
 # CONFIG_SNI_RM200_PCI is not set
 # CONFIG_TOSHIBA_RBTX4927 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_HAVE_DEC_LOCK=y
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_I8259=y
@@ -86,7 +87,6 @@
 CONFIG_IRQ_CPU=y
 CONFIG_DDB5XXX_COMMON=y
 CONFIG_MIPS_L1_CACHE_SHIFT=5
-CONFIG_FB=y
 CONFIG_HAVE_STD_PC_SERIAL_PORT=y
 
 #
@@ -130,6 +130,21 @@
 CONFIG_MMU=y
 
 #
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+CONFIG_PCMCIA_PROBE=y
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
@@ -145,6 +160,7 @@
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -170,10 +186,12 @@
 # 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_LBD is not set
 CONFIG_CDROM_PKTCDVD=y
@@ -187,6 +205,7 @@
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=y
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -424,6 +443,7 @@
 CONFIG_SERIO_SERPORT=y
 # CONFIG_SERIO_CT82C710 is not set
 # CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
 CONFIG_SERIO_RAW=y
 
 #
@@ -478,7 +498,6 @@
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_AGP is not set
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -509,6 +528,7 @@
 #
 # Graphics support
 #
+CONFIG_FB=y
 # CONFIG_FB_MODE_HELPERS is not set
 # CONFIG_FB_TILEBLITTING is not set
 # CONFIG_FB_CIRRUS is not set
@@ -544,6 +564,7 @@
 # Logo configuration
 #
 # CONFIG_LOGO is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -558,11 +579,25 @@
 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=y
@@ -654,6 +689,11 @@
 # CONFIG_NLS is not set
 
 #
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
 # Kernel hacking
 #
 # CONFIG_DEBUG_KERNEL is not set
@@ -671,6 +711,10 @@
 # Cryptographic options
 #
 # CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
 
 #
 # Library routines
diff -Nru a/arch/mips/configs/ddb5477_defconfig b/arch/mips/configs/ddb5477_defconfig
--- a/arch/mips/configs/ddb5477_defconfig	2005-03-01 23:39:08 -08:00
+++ b/arch/mips/configs/ddb5477_defconfig	2005-03-01 23:39:08 -08:00
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc2
-# Sun Nov 21 14:11:58 2004
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:02 2005
 #
 CONFIG_MIPS=y
 # CONFIG_MIPS64 is not set
@@ -80,6 +80,7 @@
 # CONFIG_SNI_RM200_PCI is not set
 # CONFIG_TOSHIBA_RBTX4927 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_HAVE_DEC_LOCK=y
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_I8259=y
@@ -87,7 +88,6 @@
 CONFIG_IRQ_CPU=y
 CONFIG_DDB5XXX_COMMON=y
 CONFIG_MIPS_L1_CACHE_SHIFT=5
-# CONFIG_FB is not set
 
 #
 # CPU selection
@@ -129,6 +129,20 @@
 CONFIG_MMU=y
 
 #
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
@@ -144,6 +158,7 @@
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -167,10 +182,12 @@
 # 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_LBD is not set
 CONFIG_CDROM_PKTCDVD=y
@@ -184,6 +201,7 @@
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=y
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -406,6 +424,7 @@
 CONFIG_SERIO_SERPORT=y
 # CONFIG_SERIO_CT82C710 is not set
 # CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
 CONFIG_SERIO_RAW=y
 
 #
@@ -460,7 +479,6 @@
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_AGP is not set
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -491,12 +509,14 @@
 #
 # 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
@@ -511,11 +531,25 @@
 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=y
@@ -609,6 +643,11 @@
 # CONFIG_NLS is not set
 
 #
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
 # Kernel hacking
 #
 # CONFIG_DEBUG_KERNEL is not set
@@ -626,6 +665,10 @@
 # Cryptographic options
 #
 # CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
 
 #
 # Library routines
diff -Nru a/arch/mips/configs/decstation_defconfig b/arch/mips/configs/decstation_defconfig
--- a/arch/mips/configs/decstation_defconfig	2005-03-01 23:39:07 -08:00
+++ b/arch/mips/configs/decstation_defconfig	2005-03-01 23:39:07 -08:00
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc2
-# Sun Nov 21 14:11:58 2004
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:03 2005
 #
 CONFIG_MIPS=y
 # CONFIG_MIPS64 is not set
@@ -85,6 +85,7 @@
 # CONFIG_SNI_RM200_PCI is not set
 # CONFIG_TOSHIBA_RBTX4927 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_HAVE_DEC_LOCK=y
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_EARLY_PRINTK=y
@@ -92,7 +93,6 @@
 CONFIG_IRQ_CPU=y
 CONFIG_BOOT_ELF32=y
 CONFIG_MIPS_L1_CACHE_SHIFT=4
-# CONFIG_FB is not set
 
 #
 # CPU selection
@@ -129,6 +129,19 @@
 CONFIG_MMU=y
 
 #
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# PCI Hotplug Support
+#
+
+#
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
@@ -144,6 +157,7 @@
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -163,9 +177,11 @@
 # 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=m
@@ -179,6 +195,7 @@
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -212,6 +229,7 @@
 #
 # CONFIG_SCSI_SPI_ATTRS is not set
 # CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
 
 #
 # SCSI low-level drivers
@@ -219,7 +237,6 @@
 CONFIG_SCSI_DECNCR=y
 # CONFIG_SCSI_DECSII is not set
 # CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_QLOGIC_1280_1040 is not set
 # CONFIG_SCSI_DEBUG is not set
 
 #
@@ -382,6 +399,7 @@
 # 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=m
 
 #
@@ -434,7 +452,6 @@
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_AGP is not set
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -465,12 +482,14 @@
 #
 # 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
@@ -484,11 +503,25 @@
 # 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=y
@@ -590,6 +623,11 @@
 # CONFIG_NLS is not set
 
 #
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
 # Kernel hacking
 #
 # CONFIG_DEBUG_KERNEL is not set
@@ -607,6 +645,10 @@
 # Cryptographic options
 #
 # CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
 
 #
 # Library routines
diff -Nru a/arch/mips/configs/e55_defconfig b/arch/mips/configs/e55_defconfig
--- a/arch/mips/configs/e55_defconfig	2005-03-01 23:38:53 -08:00
+++ b/arch/mips/configs/e55_defconfig	2005-03-01 23:38:53 -08:00
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc2
-# Sun Nov 21 14:11:58 2004
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:03 2005
 #
 CONFIG_MIPS=y
 # CONFIG_MIPS64 is not set
@@ -58,6 +58,7 @@
 #
 # CONFIG_MACH_JAZZ is not set
 CONFIG_MACH_VR41XX=y
+# CONFIG_NEC_CMBVR4133 is not set
 CONFIG_CASIO_E55=y
 # CONFIG_IBM_WORKPAD is not set
 # CONFIG_TANBAC_TB0226 is not set
@@ -92,12 +93,12 @@
 # CONFIG_SNI_RM200_PCI is not set
 # CONFIG_TOSHIBA_RBTX4927 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_HAVE_DEC_LOCK=y
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_CPU_LITTLE_ENDIAN=y
 CONFIG_IRQ_CPU=y
 CONFIG_MIPS_L1_CACHE_SHIFT=5
-# CONFIG_FB is not set
 
 #
 # CPU selection
@@ -134,6 +135,20 @@
 CONFIG_MMU=y
 
 #
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+CONFIG_PCMCIA_PROBE=y
+
+#
+# PCI Hotplug Support
+#
+
+#
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
@@ -149,6 +164,7 @@
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -170,9 +186,11 @@
 #
 # 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 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=m
@@ -186,6 +204,7 @@
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -397,6 +416,7 @@
 CONFIG_SERIO_I8042=y
 CONFIG_SERIO_SERPORT=y
 # CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_LIBPS2 is not set
 CONFIG_SERIO_RAW=m
 
 #
@@ -463,7 +483,6 @@
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_AGP is not set
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -494,6 +513,7 @@
 #
 # Graphics support
 #
+# CONFIG_FB is not set
 
 #
 # Console display driver support
@@ -501,6 +521,7 @@
 # CONFIG_VGA_CONSOLE is not set
 # CONFIG_MDA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -514,11 +535,25 @@
 # 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=y
@@ -611,6 +646,11 @@
 # CONFIG_NLS is not set
 
 #
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
 # Kernel hacking
 #
 # CONFIG_DEBUG_KERNEL is not set
@@ -628,6 +668,10 @@
 # Cryptographic options
 #
 # CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
 
 #
 # Library routines
diff -Nru a/arch/mips/configs/ev64120_defconfig b/arch/mips/configs/ev64120_defconfig
--- a/arch/mips/configs/ev64120_defconfig	2005-03-01 23:38:56 -08:00
+++ b/arch/mips/configs/ev64120_defconfig	2005-03-01 23:38:56 -08:00
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc2
-# Sun Nov 21 14:11:59 2004
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:03 2005
 #
 CONFIG_MIPS=y
 # CONFIG_MIPS64 is not set
@@ -86,6 +86,7 @@
 # CONFIG_SNI_RM200_PCI is not set
 # CONFIG_TOSHIBA_RBTX4927 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_HAVE_DEC_LOCK=y
 CONFIG_DMA_NONCOHERENT=y
 # CONFIG_CPU_LITTLE_ENDIAN is not set
@@ -94,7 +95,6 @@
 # CONFIG_SYSCLK_83 is not set
 CONFIG_SYSCLK_100=y
 CONFIG_MIPS_L1_CACHE_SHIFT=5
-# CONFIG_FB is not set
 
 #
 # CPU selection
@@ -137,6 +137,20 @@
 CONFIG_MMU=y
 
 #
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
@@ -152,6 +166,7 @@
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -175,10 +190,12 @@
 # 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_LBD is not set
 CONFIG_CDROM_PKTCDVD=m
@@ -192,6 +209,7 @@
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -400,6 +418,7 @@
 CONFIG_SERIO_SERPORT=y
 # CONFIG_SERIO_CT82C710 is not set
 # CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
 CONFIG_SERIO_RAW=m
 
 #
@@ -454,7 +473,6 @@
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_AGP is not set
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -485,12 +503,14 @@
 #
 # 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
@@ -505,11 +525,25 @@
 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=y
@@ -601,6 +635,11 @@
 # CONFIG_NLS is not set
 
 #
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
 # Kernel hacking
 #
 # CONFIG_DEBUG_KERNEL is not set
@@ -618,6 +657,10 @@
 # Cryptographic options
 #
 # CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
 
 #
 # Library routines
diff -Nru a/arch/mips/configs/ev96100_defconfig b/arch/mips/configs/ev96100_defconfig
--- a/arch/mips/configs/ev96100_defconfig	2005-03-01 23:39:07 -08:00
+++ b/arch/mips/configs/ev96100_defconfig	2005-03-01 23:39:07 -08:00
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc2
-# Sun Nov 21 14:11:59 2004
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:03 2005
 #
 CONFIG_MIPS=y
 # CONFIG_MIPS64 is not set
@@ -85,6 +85,7 @@
 # CONFIG_SNI_RM200_PCI is not set
 # CONFIG_TOSHIBA_RBTX4927 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_HAVE_DEC_LOCK=y
 CONFIG_DMA_NONCOHERENT=y
 # CONFIG_CPU_LITTLE_ENDIAN is not set
@@ -93,7 +94,6 @@
 CONFIG_SWAP_IO_SPACE=y
 CONFIG_MIPS_GT96100=y
 CONFIG_MIPS_L1_CACHE_SHIFT=5
-# CONFIG_FB is not set
 
 #
 # CPU selection
@@ -137,6 +137,19 @@
 CONFIG_MMU=y
 
 #
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# PCI Hotplug Support
+#
+
+#
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
@@ -152,6 +165,7 @@
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -171,9 +185,11 @@
 # 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=m
@@ -187,6 +203,7 @@
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -357,6 +374,7 @@
 # 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=m
 
 #
@@ -410,7 +428,6 @@
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_AGP is not set
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -441,12 +458,14 @@
 #
 # 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
@@ -460,11 +479,25 @@
 # 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=y
@@ -556,6 +589,11 @@
 # CONFIG_NLS is not set
 
 #
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
 # Kernel hacking
 #
 # CONFIG_DEBUG_KERNEL is not set
@@ -573,6 +611,10 @@
 # Cryptographic options
 #
 # CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
 
 #
 # Library routines
diff -Nru a/arch/mips/configs/ip22_defconfig b/arch/mips/configs/ip22_defconfig
--- a/arch/mips/configs/ip22_defconfig	2005-03-01 23:38:55 -08:00
+++ b/arch/mips/configs/ip22_defconfig	2005-03-01 23:38:55 -08:00
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc2
-# Sun Nov 21 14:11:59 2004
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:04 2005
 #
 CONFIG_MIPS=y
 # CONFIG_MIPS64 is not set
@@ -86,16 +86,16 @@
 # CONFIG_SNI_RM200_PCI is not set
 # CONFIG_TOSHIBA_RBTX4927 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_HAVE_DEC_LOCK=y
 CONFIG_ARC=y
 CONFIG_DMA_NONCOHERENT=y
 # CONFIG_CPU_LITTLE_ENDIAN is not set
 CONFIG_IRQ_CPU=y
 CONFIG_SWAP_IO_SPACE=y
+CONFIG_ARC32=y
 CONFIG_BOOT_ELF32=y
 CONFIG_MIPS_L1_CACHE_SHIFT=5
-CONFIG_ARC32=y
-# CONFIG_FB is not set
 CONFIG_ARC_CONSOLE=y
 CONFIG_ARC_PROMLIB=y
 
@@ -139,6 +139,19 @@
 CONFIG_MMU=y
 
 #
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# PCI Hotplug Support
+#
+
+#
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
@@ -154,6 +167,7 @@
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -173,9 +187,11 @@
 # 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=m
@@ -189,6 +205,7 @@
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -223,13 +240,13 @@
 #
 CONFIG_SCSI_SPI_ATTRS=m
 # CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
 
 #
 # SCSI low-level drivers
 #
 CONFIG_SGIWD93_SCSI=y
 # CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_QLOGIC_1280_1040 is not set
 # CONFIG_SCSI_DEBUG is not set
 
 #
@@ -372,7 +389,6 @@
 CONFIG_IP_NF_TARGET_REDIRECT=m
 CONFIG_IP_NF_TARGET_NETMAP=m
 CONFIG_IP_NF_TARGET_SAME=m
-CONFIG_IP_NF_NAT_LOCAL=y
 CONFIG_IP_NF_NAT_SNMP_BASIC=m
 CONFIG_IP_NF_NAT_IRC=m
 CONFIG_IP_NF_NAT_FTP=m
@@ -391,8 +407,6 @@
 CONFIG_IP_NF_ARPTABLES=m
 CONFIG_IP_NF_ARPFILTER=m
 CONFIG_IP_NF_ARP_MANGLE=m
-# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
-# CONFIG_IP_NF_COMPAT_IPFWADM is not set
 
 #
 # IPv6: Netfilter Configuration
@@ -471,6 +485,7 @@
 CONFIG_NET_CLS_U32=m
 # CONFIG_CLS_U32_PERF is not set
 # CONFIG_NET_CLS_IND is not set
+# CONFIG_CLS_U32_MARK is not set
 CONFIG_NET_CLS_RSVP=m
 CONFIG_NET_CLS_RSVP6=m
 # CONFIG_NET_CLS_ACT is not set
@@ -561,6 +576,7 @@
 CONFIG_SERIO_I8042=y
 CONFIG_SERIO_SERPORT=y
 # CONFIG_SERIO_CT82C710 is not set
+CONFIG_SERIO_LIBPS2=y
 CONFIG_SERIO_RAW=m
 
 #
@@ -627,7 +643,6 @@
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_AGP is not set
 # CONFIG_DRM is not set
 CONFIG_RAW_DRIVER=m
 CONFIG_MAX_RAW_DEVS=256
@@ -659,6 +674,7 @@
 #
 # Graphics support
 #
+# CONFIG_FB is not set
 
 #
 # Console display driver support
@@ -676,6 +692,7 @@
 # CONFIG_LOGO_LINUX_VGA16 is not set
 # CONFIG_LOGO_LINUX_CLUT224 is not set
 CONFIG_LOGO_SGI_CLUT224=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -689,11 +706,25 @@
 # 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=m
@@ -798,7 +829,7 @@
 CONFIG_CIFS=m
 # CONFIG_CIFS_STATS is not set
 # CONFIG_CIFS_XATTR is not set
-# CONFIG_CIFS_POSIX is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
 # CONFIG_NCP_FS is not set
 CONFIG_CODA_FS=m
 # CONFIG_CODA_FS_OLD_API is not set
@@ -869,6 +900,11 @@
 CONFIG_NLS_UTF8=m
 
 #
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
 # Kernel hacking
 #
 # CONFIG_DEBUG_KERNEL is not set
@@ -911,10 +947,14 @@
 CONFIG_CRYPTO_TEST=m
 
 #
+# Hardware crypto devices
+#
+
+#
 # Library routines
 #
 # CONFIG_CRC_CCITT is not set
-# CONFIG_CRC32 is not set
+CONFIG_CRC32=m
 CONFIG_LIBCRC32C=m
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
diff -Nru a/arch/mips/configs/ip27_defconfig b/arch/mips/configs/ip27_defconfig
--- a/arch/mips/configs/ip27_defconfig	2005-03-01 23:38:56 -08:00
+++ b/arch/mips/configs/ip27_defconfig	2005-03-01 23:38:56 -08:00
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc2
-# Sun Nov 21 14:12:00 2004
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:04 2005
 #
 CONFIG_MIPS=y
 CONFIG_MIPS64=y
@@ -91,12 +91,12 @@
 # CONFIG_SIBYTE_SB1xxx_SOC is not set
 # CONFIG_SNI_RM200_PCI is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_HAVE_DEC_LOCK=y
 CONFIG_ARC=y
 CONFIG_DMA_IP27=y
 # CONFIG_CPU_LITTLE_ENDIAN is not set
 CONFIG_MIPS_L1_CACHE_SHIFT=7
-# CONFIG_FB is not set
 CONFIG_ARC64=y
 CONFIG_BOOT_ELF64=y
 CONFIG_QL_ISP_A64=y
@@ -145,6 +145,20 @@
 CONFIG_MMU=y
 
 #
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
@@ -165,6 +179,7 @@
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -188,11 +203,13 @@
 # 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 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=m
 CONFIG_CDROM_PKTCDVD_BUFFERS=8
@@ -205,6 +222,7 @@
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -238,6 +256,7 @@
 #
 CONFIG_SCSI_SPI_ATTRS=y
 # CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
 
 #
 # SCSI low-level drivers
@@ -266,14 +285,12 @@
 CONFIG_SCSI_QLOGIC_ISP=y
 # 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_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_DEBUG is not set
@@ -509,6 +526,7 @@
 CONFIG_SERIO_SERPORT=y
 # CONFIG_SERIO_CT82C710 is not set
 # CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
 CONFIG_SERIO_RAW=m
 
 #
@@ -562,7 +580,6 @@
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_AGP is not set
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -593,6 +610,8 @@
 #
 # Graphics support
 #
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -607,11 +626,25 @@
 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=y
@@ -732,6 +765,11 @@
 # CONFIG_NLS is not set
 
 #
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
 # Kernel hacking
 #
 # CONFIG_DEBUG_KERNEL is not set
@@ -772,6 +810,10 @@
 CONFIG_CRYPTO_MICHAEL_MIC=y
 CONFIG_CRYPTO_CRC32C=m
 CONFIG_CRYPTO_TEST=m
+
+#
+# Hardware crypto devices
+#
 
 #
 # Library routines
diff -Nru a/arch/mips/configs/ip32_defconfig b/arch/mips/configs/ip32_defconfig
--- a/arch/mips/configs/ip32_defconfig	2005-03-01 23:38:54 -08:00
+++ b/arch/mips/configs/ip32_defconfig	2005-03-01 23:38:54 -08:00
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc2
-# Sun Nov 21 14:12:00 2004
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:04 2005
 #
 CONFIG_MIPS=y
 CONFIG_MIPS64=y
@@ -78,14 +78,16 @@
 # CONFIG_SIBYTE_SB1xxx_SOC is not set
 # CONFIG_SNI_RM200_PCI is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_HAVE_DEC_LOCK=y
 CONFIG_ARC=y
+CONFIG_DMA_IP32=y
+CONFIG_OWN_DMA=y
 CONFIG_DMA_NONCOHERENT=y
 # CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_ARC32=y
 CONFIG_BOOT_ELF32=y
 CONFIG_MIPS_L1_CACHE_SHIFT=5
-CONFIG_ARC32=y
-# CONFIG_FB is not set
 CONFIG_ARC_MEMORY=y
 CONFIG_ARC_PROMLIB=y
 
@@ -131,6 +133,20 @@
 CONFIG_MMU=y
 
 #
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
@@ -151,6 +167,7 @@
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -174,11 +191,13 @@
 # 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_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_INITRAMFS_SOURCE=""
 CONFIG_CDROM_PKTCDVD=y
 CONFIG_CDROM_PKTCDVD_BUFFERS=8
@@ -191,6 +210,7 @@
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=y
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -225,6 +245,7 @@
 #
 # CONFIG_SCSI_SPI_ATTRS is not set
 # CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
 
 #
 # SCSI low-level drivers
@@ -258,14 +279,12 @@
 # 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_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_DEBUG is not set
@@ -465,6 +484,7 @@
 # CONFIG_SERIO_CT82C710 is not set
 # CONFIG_SERIO_PCIPS2 is not set
 # CONFIG_SERIO_MACEPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
 CONFIG_SERIO_RAW=y
 
 #
@@ -519,7 +539,6 @@
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_AGP is not set
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -550,12 +569,14 @@
 #
 # 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
@@ -570,11 +591,25 @@
 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=y
@@ -678,6 +713,11 @@
 # CONFIG_NLS is not set
 
 #
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
 # Kernel hacking
 #
 # CONFIG_DEBUG_KERNEL is not set
@@ -695,6 +735,10 @@
 # Cryptographic options
 #
 # CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
 
 #
 # Library routines
diff -Nru a/arch/mips/configs/it8172_defconfig b/arch/mips/configs/it8172_defconfig
--- a/arch/mips/configs/it8172_defconfig	2005-03-01 23:38:53 -08:00
+++ b/arch/mips/configs/it8172_defconfig	2005-03-01 23:38:53 -08:00
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc2
-# Sun Nov 21 14:12:00 2004
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:05 2005
 #
 CONFIG_MIPS=y
 # CONFIG_MIPS64 is not set
@@ -87,6 +87,7 @@
 # CONFIG_SNI_RM200_PCI is not set
 # CONFIG_TOSHIBA_RBTX4927 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_HAVE_DEC_LOCK=y
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_CPU_LITTLE_ENDIAN=y
@@ -94,7 +95,6 @@
 CONFIG_IT8172_CIR=y
 CONFIG_IT8712=y
 CONFIG_MIPS_L1_CACHE_SHIFT=5
-# CONFIG_FB is not set
 
 #
 # CPU selection
@@ -134,6 +134,19 @@
 CONFIG_MMU=y
 
 #
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# PCI Hotplug Support
+#
+
+#
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
@@ -149,6 +162,7 @@
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -192,6 +206,7 @@
 # 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
@@ -209,6 +224,7 @@
 # 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
@@ -235,10 +251,12 @@
 # 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=m
@@ -252,6 +270,7 @@
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -443,6 +462,7 @@
 # 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=m
 
 #
@@ -500,7 +520,6 @@
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_AGP is not set
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -531,12 +550,14 @@
 #
 # 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
@@ -570,11 +591,25 @@
 # 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=y
@@ -668,6 +703,11 @@
 # CONFIG_NLS is not set
 
 #
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
 # Kernel hacking
 #
 # CONFIG_DEBUG_KERNEL is not set
@@ -685,6 +725,10 @@
 # Cryptographic options
 #
 # CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
 
 #
 # Library routines
diff -Nru a/arch/mips/configs/ivr_defconfig b/arch/mips/configs/ivr_defconfig
--- a/arch/mips/configs/ivr_defconfig	2005-03-01 23:38:53 -08:00
+++ b/arch/mips/configs/ivr_defconfig	2005-03-01 23:38:53 -08:00
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc2
-# Sun Nov 21 14:12:01 2004
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:05 2005
 #
 CONFIG_MIPS=y
 # CONFIG_MIPS64 is not set
@@ -86,13 +86,13 @@
 # CONFIG_SNI_RM200_PCI is not set
 # CONFIG_TOSHIBA_RBTX4927 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_HAVE_DEC_LOCK=y
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_CPU_LITTLE_ENDIAN=y
 CONFIG_ITE_BOARD_GEN=y
 CONFIG_IT8172_CIR=y
 CONFIG_MIPS_L1_CACHE_SHIFT=5
-# CONFIG_FB is not set
 
 #
 # CPU selection
@@ -134,6 +134,20 @@
 CONFIG_MMU=y
 
 #
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
@@ -149,6 +163,7 @@
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -172,10 +187,12 @@
 # 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_LBD is not set
 CONFIG_CDROM_PKTCDVD=m
@@ -189,6 +206,7 @@
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -413,6 +431,7 @@
 CONFIG_SERIO_SERPORT=y
 # CONFIG_SERIO_CT82C710 is not set
 # CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
 CONFIG_SERIO_RAW=m
 
 #
@@ -468,7 +487,6 @@
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_AGP is not set
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -499,12 +517,14 @@
 #
 # 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
@@ -519,11 +539,25 @@
 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=y
@@ -615,6 +649,11 @@
 # CONFIG_NLS is not set
 
 #
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
 # Kernel hacking
 #
 # CONFIG_DEBUG_KERNEL is not set
@@ -632,6 +671,10 @@
 # Cryptographic options
 #
 # CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
 
 #
 # Library routines
diff -Nru a/arch/mips/configs/jaguar-atx_defconfig b/arch/mips/configs/jaguar-atx_defconfig
--- a/arch/mips/configs/jaguar-atx_defconfig	2005-03-01 23:39:16 -08:00
+++ b/arch/mips/configs/jaguar-atx_defconfig	2005-03-01 23:39:16 -08:00
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc2
-# Sun Nov 21 14:12:01 2004
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:05 2005
 #
 CONFIG_MIPS=y
 # CONFIG_MIPS64 is not set
@@ -78,6 +78,7 @@
 # CONFIG_SNI_RM200_PCI is not set
 # CONFIG_TOSHIBA_RBTX4927 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_HAVE_DEC_LOCK=y
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_LIMITED_DMA=y
@@ -89,7 +90,6 @@
 CONFIG_SWAP_IO_SPACE=y
 CONFIG_BOOT_ELF32=y
 CONFIG_MIPS_L1_CACHE_SHIFT=5
-# CONFIG_FB is not set
 
 #
 # CPU selection
@@ -137,6 +137,19 @@
 CONFIG_MMU=y
 
 #
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# PCI Hotplug Support
+#
+
+#
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
@@ -152,6 +165,7 @@
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -174,10 +188,12 @@
 # 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_LBD is not set
 CONFIG_CDROM_PKTCDVD=m
@@ -191,6 +207,7 @@
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -305,7 +322,6 @@
 # CONFIG_ADAPTEC_STARFIRE is not set
 # CONFIG_DGRS is not set
 CONFIG_EEPRO100=y
-# CONFIG_EEPRO100_PIO is not set
 # CONFIG_E100 is not set
 # CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
@@ -430,7 +446,6 @@
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_AGP is not set
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -461,6 +476,8 @@
 #
 # Graphics support
 #
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -475,11 +492,25 @@
 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
@@ -574,6 +605,10 @@
 # Cryptographic options
 #
 # CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
 
 #
 # Library routines
diff -Nru a/arch/mips/configs/jmr3927_defconfig b/arch/mips/configs/jmr3927_defconfig
--- a/arch/mips/configs/jmr3927_defconfig	2005-03-01 23:38:53 -08:00
+++ b/arch/mips/configs/jmr3927_defconfig	2005-03-01 23:38:53 -08:00
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc2
-# Sun Nov 21 14:12:01 2004
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:06 2005
 #
 CONFIG_MIPS=y
 # CONFIG_MIPS64 is not set
@@ -79,13 +79,13 @@
 # CONFIG_SNI_RM200_PCI is not set
 # CONFIG_TOSHIBA_RBTX4927 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_HAVE_DEC_LOCK=y
 CONFIG_DMA_NONCOHERENT=y
 # CONFIG_CPU_LITTLE_ENDIAN is not set
 CONFIG_MIPS_TX3927=y
 CONFIG_SWAP_IO_SPACE=y
 CONFIG_MIPS_L1_CACHE_SHIFT=5
-CONFIG_FB=y
 CONFIG_TOSHIBA_BOARDS=y
 
 #
@@ -127,6 +127,20 @@
 CONFIG_MMU=y
 
 #
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
@@ -142,6 +156,7 @@
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -165,10 +180,12 @@
 # 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_LBD is not set
 CONFIG_CDROM_PKTCDVD=y
@@ -182,6 +199,7 @@
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=y
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -384,6 +402,7 @@
 CONFIG_SERIO_SERPORT=y
 # CONFIG_SERIO_CT82C710 is not set
 # CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
 CONFIG_SERIO_RAW=y
 
 #
@@ -409,6 +428,7 @@
 # CONFIG_DIGI is not set
 # CONFIG_MOXA_INTELLIO 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
@@ -452,7 +472,6 @@
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_AGP is not set
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -483,6 +502,7 @@
 #
 # Graphics support
 #
+CONFIG_FB=y
 # CONFIG_FB_MODE_HELPERS is not set
 # CONFIG_FB_TILEBLITTING is not set
 # CONFIG_FB_CIRRUS is not set
@@ -517,6 +537,7 @@
 # Logo configuration
 #
 # CONFIG_LOGO is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -531,11 +552,25 @@
 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
@@ -624,6 +659,11 @@
 # CONFIG_NLS is not set
 
 #
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
 # Kernel hacking
 #
 # CONFIG_DEBUG_KERNEL is not set
@@ -641,6 +681,10 @@
 # Cryptographic options
 #
 # CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
 
 #
 # Library routines
diff -Nru a/arch/mips/configs/lasat200_defconfig b/arch/mips/configs/lasat200_defconfig
--- a/arch/mips/configs/lasat200_defconfig	2005-03-01 23:38:58 -08:00
+++ b/arch/mips/configs/lasat200_defconfig	2005-03-01 23:38:58 -08:00
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc2
-# Sun Nov 21 14:12:02 2004
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:06 2005
 #
 CONFIG_MIPS=y
 # CONFIG_MIPS64 is not set
@@ -89,13 +89,13 @@
 # CONFIG_SNI_RM200_PCI is not set
 # CONFIG_TOSHIBA_RBTX4927 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_HAVE_DEC_LOCK=y
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_MIPS_NILE4=y
 CONFIG_CPU_LITTLE_ENDIAN=y
 CONFIG_MIPS_GT64120=y
 CONFIG_MIPS_L1_CACHE_SHIFT=5
-# CONFIG_FB is not set
 
 #
 # CPU selection
@@ -140,6 +140,20 @@
 CONFIG_MMU=y
 
 #
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
@@ -155,6 +169,7 @@
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -216,6 +231,7 @@
 # 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
@@ -246,10 +262,12 @@
 # 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_LBD is not set
 CONFIG_CDROM_PKTCDVD=m
@@ -263,6 +281,7 @@
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -511,6 +530,7 @@
 CONFIG_SERIO_SERPORT=y
 # CONFIG_SERIO_CT82C710 is not set
 # CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
 CONFIG_SERIO_RAW=m
 
 #
@@ -565,7 +585,6 @@
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_AGP is not set
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -596,12 +615,14 @@
 #
 # 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
@@ -616,11 +637,25 @@
 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=y
@@ -719,6 +754,11 @@
 # CONFIG_NLS is not set
 
 #
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
 # Kernel hacking
 #
 # CONFIG_DEBUG_KERNEL is not set
@@ -736,6 +776,10 @@
 # Cryptographic options
 #
 # CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
 
 #
 # Library routines
diff -Nru a/arch/mips/configs/malta_defconfig b/arch/mips/configs/malta_defconfig
--- a/arch/mips/configs/malta_defconfig	2005-03-01 23:39:09 -08:00
+++ b/arch/mips/configs/malta_defconfig	2005-03-01 23:39:09 -08:00
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc2
-# Sun Nov 21 14:12:02 2004
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:53:14 2005
 #
 CONFIG_MIPS=y
 # CONFIG_MIPS64 is not set
@@ -26,7 +26,7 @@
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
+CONFIG_HOTPLUG=y
 CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 CONFIG_EMBEDDED=y
@@ -85,6 +85,7 @@
 # CONFIG_SNI_RM200_PCI is not set
 # CONFIG_TOSHIBA_RBTX4927 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_HAVE_DEC_LOCK=y
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_GENERIC_ISA_DMA=y
@@ -97,7 +98,6 @@
 CONFIG_SWAP_IO_SPACE=y
 CONFIG_BOOT_ELF32=y
 CONFIG_MIPS_L1_CACHE_SHIFT=5
-# CONFIG_FB is not set
 CONFIG_HAVE_STD_PC_SERIAL_PORT=y
 
 #
@@ -124,8 +124,6 @@
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
 # CONFIG_PAGE_SIZE_64KB is not set
-CONFIG_CPU_HAS_PREFETCH=y
-# CONFIG_VTAG_ICACHE is not set
 # CONFIG_64BIT_PHYS_ADDR is not set
 # CONFIG_CPU_ADVANCED is not set
 CONFIG_CPU_HAS_LLSC=y
@@ -142,6 +140,20 @@
 CONFIG_MMU=y
 
 #
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
@@ -157,6 +169,7 @@
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
 
 #
 # Memory Technology Devices (MTD)
@@ -175,15 +188,18 @@
 #
 # Block devices
 #
-# CONFIG_BLK_DEV_FD is not set
+CONFIG_BLK_DEV_FD=m
 # 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_LOOP is not set
-# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_UMEM=m
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
 # CONFIG_BLK_DEV_SX8 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=""
@@ -199,25 +215,162 @@
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
 
 #
 # ATA/ATAPI/MFM/RLL support
 #
-# CONFIG_IDE is not set
+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_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=y
+# CONFIG_BLK_DEV_OPTI621 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 is not set
+# 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=y
+# 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=y
+# CONFIG_BLK_DEV_HD is not set
 
 #
 # SCSI device support
 #
-# CONFIG_SCSI is not set
+CONFIG_SCSI=m
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
+CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=m
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+
+#
+# SCSI Transport Attributes
+#
+CONFIG_SCSI_SPI_ATTRS=m
+CONFIG_SCSI_FC_ATTRS=m
+CONFIG_SCSI_ISCSI_ATTRS=m
+
+#
+# SCSI low-level drivers
+#
+CONFIG_BLK_DEV_3W_XXXX_RAID=m
+CONFIG_SCSI_3W_9XXX=m
+CONFIG_SCSI_ACARD=m
+CONFIG_SCSI_AACRAID=m
+CONFIG_SCSI_AIC7XXX=m
+CONFIG_AIC7XXX_CMDS_PER_DEVICE=32
+CONFIG_AIC7XXX_RESET_DELAY_MS=15000
+# CONFIG_AIC7XXX_DEBUG_ENABLE is not set
+CONFIG_AIC7XXX_DEBUG_MASK=0
+CONFIG_AIC7XXX_REG_PRETTY_PRINT=y
+# 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_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 is not set
+CONFIG_SCSI_QLA2XXX=m
+# 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_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
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=m
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID5=m
+CONFIG_MD_RAID6=m
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
 
 #
 # Fusion MPT device support
 #
+# CONFIG_FUSION is not set
 
 #
 # IEEE 1394 (FireWire) support
@@ -237,54 +390,261 @@
 #
 # Networking options
 #
-# CONFIG_PACKET is not set
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
 CONFIG_NETLINK_DEV=y
 CONFIG_UNIX=y
 CONFIG_NET_KEY=y
 CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_FWMARK=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 is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
 # 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_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
 CONFIG_INET_TUNNEL=m
 CONFIG_IP_TCPDIAG=m
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
+CONFIG_IP_TCPDIAG_IPV6=y
+
+#
+# IP: Virtual Server Configuration
+#
+CONFIG_IP_VS=m
+# CONFIG_IP_VS_DEBUG is not set
+CONFIG_IP_VS_TAB_BITS=12
+
+#
+# IPVS transport protocol load balancing support
+#
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_PROTO_ESP=y
+CONFIG_IP_VS_PROTO_AH=y
+
+#
+# IPVS scheduler
+#
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_WRR=m
+CONFIG_IP_VS_LC=m
+CONFIG_IP_VS_WLC=m
+CONFIG_IP_VS_LBLC=m
+CONFIG_IP_VS_LBLCR=m
+CONFIG_IP_VS_DH=m
+CONFIG_IP_VS_SH=m
+CONFIG_IP_VS_SED=m
+CONFIG_IP_VS_NQ=m
+
+#
+# IPVS application helper
+#
+CONFIG_IP_VS_FTP=m
+CONFIG_IPV6=m
+CONFIG_IPV6_PRIVACY=y
+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
+CONFIG_BRIDGE_NETFILTER=y
+
+#
+# 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_PHYSDEV=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
+
+#
+# IPv6: Netfilter Configuration
+#
+CONFIG_IP6_NF_QUEUE=m
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_MATCH_LIMIT=m
+CONFIG_IP6_NF_MATCH_MAC=m
+CONFIG_IP6_NF_MATCH_RT=m
+CONFIG_IP6_NF_MATCH_OPTS=m
+CONFIG_IP6_NF_MATCH_FRAG=m
+CONFIG_IP6_NF_MATCH_HL=m
+CONFIG_IP6_NF_MATCH_MULTIPORT=m
+CONFIG_IP6_NF_MATCH_OWNER=m
+CONFIG_IP6_NF_MATCH_MARK=m
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+CONFIG_IP6_NF_MATCH_AHESP=m
+CONFIG_IP6_NF_MATCH_LENGTH=m
+CONFIG_IP6_NF_MATCH_EUI64=m
+CONFIG_IP6_NF_MATCH_PHYSDEV=m
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_MANGLE=m
+CONFIG_IP6_NF_TARGET_MARK=m
+CONFIG_IP6_NF_RAW=m
+
+#
+# Bridge: Netfilter Configuration
+#
+CONFIG_BRIDGE_NF_EBTABLES=m
+CONFIG_BRIDGE_EBT_BROUTE=m
+CONFIG_BRIDGE_EBT_T_FILTER=m
+CONFIG_BRIDGE_EBT_T_NAT=m
+CONFIG_BRIDGE_EBT_802_3=m
+CONFIG_BRIDGE_EBT_AMONG=m
+CONFIG_BRIDGE_EBT_ARP=m
+CONFIG_BRIDGE_EBT_IP=m
+CONFIG_BRIDGE_EBT_LIMIT=m
+CONFIG_BRIDGE_EBT_MARK=m
+CONFIG_BRIDGE_EBT_PKTTYPE=m
+CONFIG_BRIDGE_EBT_STP=m
+CONFIG_BRIDGE_EBT_VLAN=m
+CONFIG_BRIDGE_EBT_ARPREPLY=m
+CONFIG_BRIDGE_EBT_DNAT=m
+CONFIG_BRIDGE_EBT_MARK_T=m
+CONFIG_BRIDGE_EBT_REDIRECT=m
+CONFIG_BRIDGE_EBT_SNAT=m
+CONFIG_BRIDGE_EBT_LOG=m
+CONFIG_BRIDGE_EBT_ULOG=m
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
 
 #
 # SCTP Configuration (EXPERIMENTAL)
 #
-# CONFIG_IP_SCTP is not set
+CONFIG_IP_SCTP=m
+# CONFIG_SCTP_DBG_MSG is not set
+# CONFIG_SCTP_DBG_OBJCNT is not set
+# CONFIG_SCTP_HMAC_NONE is not set
+# CONFIG_SCTP_HMAC_SHA1 is not set
+CONFIG_SCTP_HMAC_MD5=y
 # CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
 # CONFIG_DECNET is not set
+CONFIG_LLC=m
 # CONFIG_LLC2 is not set
 # CONFIG_IPX is not set
-# CONFIG_ATALK is not set
+CONFIG_ATALK=m
+CONFIG_DEV_APPLETALK=y
+CONFIG_IPDDP=m
+CONFIG_IPDDP_ENCAP=y
+CONFIG_IPDDP_DECAP=y
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
+CONFIG_NET_DIVERT=y
 # 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
+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=m
+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=m
+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=y
+# CONFIG_CLS_U32_MARK 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
@@ -296,10 +656,10 @@
 # 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_DUMMY=m
+CONFIG_BONDING=m
+CONFIG_EQUALIZER=m
+CONFIG_TUN=m
 # CONFIG_ETHERTAP is not set
 
 #
@@ -380,6 +740,7 @@
 # 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
 
@@ -420,7 +781,8 @@
 CONFIG_SERIO_SERPORT=y
 # CONFIG_SERIO_CT82C710 is not set
 # CONFIG_SERIO_PCIPS2 is not set
-CONFIG_SERIO_RAW=m
+# CONFIG_SERIO_LIBPS2 is not set
+# CONFIG_SERIO_RAW is not set
 
 #
 # Input Device Drivers
@@ -473,7 +835,6 @@
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_AGP is not set
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -504,12 +865,14 @@
 #
 # 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
@@ -524,23 +887,59 @@
 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=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_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
-# CONFIG_QUOTA 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=m
+# CONFIG_REISERFS_CHECK is not set
+CONFIG_REISERFS_PROC_INFO=y
+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
+CONFIG_XFS_FS=m
+# CONFIG_XFS_RT is not set
+CONFIG_XFS_QUOTA=y
+CONFIG_XFS_SECURITY=y
+CONFIG_XFS_POSIX_ACL=y
+CONFIG_MINIX_FS=m
+CONFIG_ROMFS_FS=m
+CONFIG_QUOTA=y
+# CONFIG_QFMT_V1 is not set
+CONFIG_QFMT_V2=y
+CONFIG_QUOTACTL=y
 CONFIG_DNOTIFY=y
 CONFIG_AUTOFS_FS=y
 # CONFIG_AUTOFS4_FS is not set
@@ -548,14 +947,21 @@
 #
 # CD-ROM/DVD Filesystems
 #
-# CONFIG_ISO9660_FS is not set
-# CONFIG_UDF_FS is not set
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_ZISOFS_FS=m
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
 
 #
 # DOS/FAT/NT Filesystems
 #
-# CONFIG_MSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
+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
 
 #
@@ -575,18 +981,20 @@
 # 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=y
-# CONFIG_CRAMFS is not set
-# CONFIG_VXFS_FS is not set
+CONFIG_AFFS_FS=m
+CONFIG_HFS_FS=m
+CONFIG_HFSPLUS_FS=m
+CONFIG_BEFS_FS=m
+# CONFIG_BEFS_DEBUG is not set
+CONFIG_BFS_FS=m
+CONFIG_EFS_FS=m
+CONFIG_CRAMFS=m
+CONFIG_VXFS_FS=m
 # 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_SYSV_FS=m
+CONFIG_UFS_FS=m
+# CONFIG_UFS_FS_WRITE is not set
 
 #
 # Network File Systems
@@ -621,7 +1029,51 @@
 #
 # Native Language Support
 #
-# CONFIG_NLS is not set
+CONFIG_NLS=m
+CONFIG_NLS_DEFAULT="iso8859-1"
+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=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
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
 
 #
 # Kernel hacking
@@ -633,14 +1085,40 @@
 #
 # Security options
 #
-CONFIG_KEYS=y
-CONFIG_KEYS_DEBUG_PROC_KEYS=y
+# CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 
 #
 # Cryptographic options
 #
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
 
 #
 # Library routines
@@ -648,5 +1126,7 @@
 # CONFIG_CRC_CCITT is not set
 CONFIG_CRC32=y
 CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
diff -Nru a/arch/mips/configs/mpc30x_defconfig b/arch/mips/configs/mpc30x_defconfig
--- a/arch/mips/configs/mpc30x_defconfig	2005-03-01 23:39:09 -08:00
+++ b/arch/mips/configs/mpc30x_defconfig	2005-03-01 23:39:09 -08:00
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc2
-# Sun Nov 21 14:12:02 2004
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:07 2005
 #
 CONFIG_MIPS=y
 # CONFIG_MIPS64 is not set
@@ -58,6 +58,7 @@
 #
 # CONFIG_MACH_JAZZ is not set
 CONFIG_MACH_VR41XX=y
+# CONFIG_NEC_CMBVR4133 is not set
 # CONFIG_CASIO_E55 is not set
 # CONFIG_IBM_WORKPAD is not set
 # CONFIG_TANBAC_TB0226 is not set
@@ -93,12 +94,12 @@
 # CONFIG_SNI_RM200_PCI is not set
 # CONFIG_TOSHIBA_RBTX4927 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_HAVE_DEC_LOCK=y
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_CPU_LITTLE_ENDIAN=y
 CONFIG_IRQ_CPU=y
 CONFIG_MIPS_L1_CACHE_SHIFT=5
-# CONFIG_FB is not set
 
 #
 # CPU selection
@@ -138,6 +139,20 @@
 CONFIG_MMU=y
 
 #
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
@@ -153,6 +168,7 @@
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -176,10 +192,12 @@
 # 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_LBD is not set
 CONFIG_CDROM_PKTCDVD=m
@@ -193,6 +211,7 @@
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -396,6 +415,7 @@
 CONFIG_SERIO_SERPORT=y
 # CONFIG_SERIO_CT82C710 is not set
 # CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
 CONFIG_SERIO_RAW=m
 
 #
@@ -450,7 +470,6 @@
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_AGP is not set
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -481,12 +500,14 @@
 #
 # 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
@@ -501,11 +522,25 @@
 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=y
@@ -597,6 +632,11 @@
 # CONFIG_NLS is not set
 
 #
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
 # Kernel hacking
 #
 # CONFIG_DEBUG_KERNEL is not set
@@ -637,6 +677,10 @@
 CONFIG_CRYPTO_MICHAEL_MIC=y
 CONFIG_CRYPTO_CRC32C=m
 # CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
 
 #
 # Library routines
diff -Nru a/arch/mips/configs/ocelot_3_defconfig b/arch/mips/configs/ocelot_3_defconfig
--- a/arch/mips/configs/ocelot_3_defconfig	2005-03-01 23:38:55 -08:00
+++ b/arch/mips/configs/ocelot_3_defconfig	2005-03-01 23:38:55 -08:00
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc2
-# Sun Nov 21 14:12:03 2004
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:07 2005
 #
 CONFIG_MIPS=y
 # CONFIG_MIPS64 is not set
@@ -86,6 +86,7 @@
 # CONFIG_SNI_RM200_PCI is not set
 # CONFIG_TOSHIBA_RBTX4927 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_HAVE_DEC_LOCK=y
 CONFIG_DMA_NONCOHERENT=y
 # CONFIG_CPU_LITTLE_ENDIAN is not set
@@ -96,7 +97,6 @@
 CONFIG_SWAP_IO_SPACE=y
 CONFIG_BOOT_ELF32=y
 CONFIG_MIPS_L1_CACHE_SHIFT=5
-CONFIG_FB=y
 
 #
 # CPU selection
@@ -144,6 +144,20 @@
 CONFIG_MMU=y
 
 #
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
@@ -159,6 +173,7 @@
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -182,11 +197,13 @@
 # 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_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_LBD is not set
 # CONFIG_CDROM_PKTCDVD is not set
@@ -198,6 +215,7 @@
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -231,6 +249,7 @@
 #
 # CONFIG_SCSI_SPI_ATTRS is not set
 # CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
 
 #
 # SCSI low-level drivers
@@ -260,14 +279,12 @@
 # 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=m
 # 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_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_NSP32 is not set
@@ -346,8 +363,6 @@
 # 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
 
 #
 # IPv6: Netfilter Configuration
@@ -524,6 +539,7 @@
 # CONFIG_SERIO_SERPORT is not set
 # CONFIG_SERIO_CT82C710 is not set
 # CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
 # CONFIG_SERIO_RAW is not set
 
 #
@@ -577,7 +593,6 @@
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_AGP is not set
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -608,6 +623,7 @@
 #
 # Graphics support
 #
+CONFIG_FB=y
 CONFIG_FB_MODE_HELPERS=y
 # CONFIG_FB_TILEBLITTING is not set
 # CONFIG_FB_CIRRUS is not set
@@ -648,6 +664,7 @@
 CONFIG_LOGO_LINUX_MONO=y
 CONFIG_LOGO_LINUX_VGA16=y
 CONFIG_LOGO_LINUX_CLUT224=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -662,11 +679,25 @@
 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=y
@@ -817,6 +848,11 @@
 # CONFIG_NLS_UTF8 is not set
 
 #
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
 # Kernel hacking
 #
 # CONFIG_DEBUG_KERNEL is not set
@@ -833,6 +869,10 @@
 # Cryptographic options
 #
 # CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
 
 #
 # Library routines
diff -Nru a/arch/mips/configs/ocelot_c_defconfig b/arch/mips/configs/ocelot_c_defconfig
--- a/arch/mips/configs/ocelot_c_defconfig	2005-03-01 23:38:53 -08:00
+++ b/arch/mips/configs/ocelot_c_defconfig	2005-03-01 23:38:53 -08:00
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc2
-# Sun Nov 21 14:12:03 2004
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:07 2005
 #
 CONFIG_MIPS=y
 CONFIG_MIPS64=y
@@ -77,6 +77,7 @@
 # CONFIG_SIBYTE_SB1xxx_SOC is not set
 # CONFIG_SNI_RM200_PCI is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_HAVE_DEC_LOCK=y
 CONFIG_DMA_NONCOHERENT=y
 # CONFIG_CPU_LITTLE_ENDIAN is not set
@@ -85,7 +86,6 @@
 CONFIG_PCI_MARVELL=y
 CONFIG_SWAP_IO_SPACE=y
 CONFIG_MIPS_L1_CACHE_SHIFT=5
-# CONFIG_FB is not set
 
 #
 # CPU selection
@@ -129,6 +129,20 @@
 CONFIG_MMU=y
 
 #
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
@@ -149,6 +163,7 @@
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -172,10 +187,12 @@
 # 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=y
 CONFIG_CDROM_PKTCDVD_BUFFERS=8
@@ -188,6 +205,7 @@
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=y
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -390,6 +408,7 @@
 CONFIG_SERIO_SERPORT=y
 # CONFIG_SERIO_CT82C710 is not set
 # CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
 CONFIG_SERIO_RAW=y
 
 #
@@ -444,7 +463,6 @@
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_AGP is not set
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -475,12 +493,14 @@
 #
 # 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
@@ -495,11 +515,25 @@
 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=y
@@ -593,6 +627,11 @@
 # CONFIG_NLS is not set
 
 #
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
 # Kernel hacking
 #
 # CONFIG_DEBUG_KERNEL is not set
@@ -610,6 +649,10 @@
 # Cryptographic options
 #
 # CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
 
 #
 # Library routines
diff -Nru a/arch/mips/configs/ocelot_defconfig b/arch/mips/configs/ocelot_defconfig
--- a/arch/mips/configs/ocelot_defconfig	2005-03-01 23:38:56 -08:00
+++ b/arch/mips/configs/ocelot_defconfig	2005-03-01 23:38:56 -08:00
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc2
-# Sun Nov 21 14:12:04 2004
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:08 2005
 #
 CONFIG_MIPS=y
 # CONFIG_MIPS64 is not set
@@ -79,6 +79,7 @@
 # CONFIG_SNI_RM200_PCI is not set
 # CONFIG_TOSHIBA_RBTX4927 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_HAVE_DEC_LOCK=y
 CONFIG_DMA_NONCOHERENT=y
 # CONFIG_CPU_LITTLE_ENDIAN is not set
@@ -90,7 +91,6 @@
 # CONFIG_SYSCLK_83 is not set
 CONFIG_SYSCLK_100=y
 CONFIG_MIPS_L1_CACHE_SHIFT=5
-# CONFIG_FB is not set
 
 #
 # CPU selection
@@ -134,6 +134,19 @@
 CONFIG_MMU=y
 
 #
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# PCI Hotplug Support
+#
+
+#
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
@@ -149,6 +162,7 @@
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -168,9 +182,11 @@
 # 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=y
@@ -184,6 +200,7 @@
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=y
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -353,6 +370,7 @@
 # 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=y
 
 #
@@ -406,7 +424,6 @@
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_AGP is not set
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -437,12 +454,14 @@
 #
 # 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
@@ -456,11 +475,25 @@
 # 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=y
@@ -554,6 +587,11 @@
 # CONFIG_NLS is not set
 
 #
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
 # Kernel hacking
 #
 # CONFIG_DEBUG_KERNEL is not set
@@ -571,6 +609,10 @@
 # Cryptographic options
 #
 # CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
 
 #
 # Library routines
diff -Nru a/arch/mips/configs/ocelot_g_defconfig b/arch/mips/configs/ocelot_g_defconfig
--- a/arch/mips/configs/ocelot_g_defconfig	2005-03-01 23:38:58 -08:00
+++ b/arch/mips/configs/ocelot_g_defconfig	2005-03-01 23:38:58 -08:00
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc2
-# Sun Nov 21 14:12:04 2004
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:08 2005
 #
 CONFIG_MIPS=y
 CONFIG_MIPS64=y
@@ -77,6 +77,7 @@
 # CONFIG_SIBYTE_SB1xxx_SOC is not set
 # CONFIG_SNI_RM200_PCI is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_HAVE_DEC_LOCK=y
 CONFIG_DMA_NONCOHERENT=y
 # CONFIG_CPU_LITTLE_ENDIAN is not set
@@ -88,7 +89,6 @@
 # CONFIG_SYSCLK_83 is not set
 CONFIG_SYSCLK_100=y
 CONFIG_MIPS_L1_CACHE_SHIFT=5
-# CONFIG_FB is not set
 
 #
 # CPU selection
@@ -132,6 +132,20 @@
 CONFIG_MMU=y
 
 #
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
@@ -152,6 +166,7 @@
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -175,10 +190,12 @@
 # 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=y
 CONFIG_CDROM_PKTCDVD_BUFFERS=8
@@ -191,6 +208,7 @@
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=y
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -393,6 +411,7 @@
 CONFIG_SERIO_SERPORT=y
 # CONFIG_SERIO_CT82C710 is not set
 # CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
 CONFIG_SERIO_RAW=y
 
 #
@@ -447,7 +466,6 @@
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_AGP is not set
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -478,12 +496,14 @@
 #
 # 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
@@ -498,11 +518,25 @@
 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=y
@@ -596,6 +630,11 @@
 # CONFIG_NLS is not set
 
 #
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
 # Kernel hacking
 #
 # CONFIG_DEBUG_KERNEL is not set
@@ -613,6 +652,10 @@
 # Cryptographic options
 #
 # CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
 
 #
 # Library routines
diff -Nru a/arch/mips/configs/osprey_defconfig b/arch/mips/configs/osprey_defconfig
--- a/arch/mips/configs/osprey_defconfig	2005-03-01 23:39:18 -08:00
+++ b/arch/mips/configs/osprey_defconfig	2005-03-01 23:39:18 -08:00
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc2
-# Sun Nov 21 14:12:04 2004
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:08 2005
 #
 CONFIG_MIPS=y
 # CONFIG_MIPS64 is not set
@@ -85,12 +85,12 @@
 # CONFIG_SNI_RM200_PCI is not set
 # CONFIG_TOSHIBA_RBTX4927 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_HAVE_DEC_LOCK=y
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_CPU_LITTLE_ENDIAN=y
 CONFIG_IRQ_CPU=y
 CONFIG_MIPS_L1_CACHE_SHIFT=5
-# CONFIG_FB is not set
 CONFIG_VR4181=y
 
 #
@@ -127,6 +127,19 @@
 CONFIG_MMU=y
 
 #
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# PCI Hotplug Support
+#
+
+#
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
@@ -142,6 +155,7 @@
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -161,9 +175,11 @@
 # 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=m
@@ -177,6 +193,7 @@
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -347,6 +364,7 @@
 # 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=m
 
 #
@@ -400,7 +418,6 @@
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_AGP is not set
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -431,12 +448,14 @@
 #
 # 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
@@ -450,11 +469,25 @@
 # 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=y
@@ -548,6 +581,11 @@
 # CONFIG_NLS is not set
 
 #
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
 # Kernel hacking
 #
 # CONFIG_DEBUG_KERNEL is not set
@@ -565,6 +603,10 @@
 # Cryptographic options
 #
 # CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
 
 #
 # Library routines
diff -Nru a/arch/mips/configs/pb1100_defconfig b/arch/mips/configs/pb1100_defconfig
--- a/arch/mips/configs/pb1100_defconfig	2005-03-01 23:38:57 -08:00
+++ b/arch/mips/configs/pb1100_defconfig	2005-03-01 23:38:57 -08:00
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc2
-# Sun Nov 21 14:12:05 2004
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:08 2005
 #
 CONFIG_MIPS=y
 # CONFIG_MIPS64 is not set
@@ -101,13 +101,13 @@
 # CONFIG_SNI_RM200_PCI is not set
 # CONFIG_TOSHIBA_RBTX4927 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_HAVE_DEC_LOCK=y
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_CPU_LITTLE_ENDIAN=y
 CONFIG_SWAP_IO_SPACE=y
-# CONFIG_AU1000_USB_DEVICE is not set
+# CONFIG_AU1X00_USB_DEVICE is not set
 CONFIG_MIPS_L1_CACHE_SHIFT=5
-# CONFIG_FB is not set
 
 #
 # CPU selection
@@ -134,7 +134,6 @@
 # CONFIG_PAGE_SIZE_16KB is not set
 # CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_CPU_HAS_PREFETCH=y
-# CONFIG_VTAG_ICACHE is not set
 # CONFIG_64BIT_PHYS_ADDR is not set
 # CONFIG_CPU_ADVANCED is not set
 CONFIG_CPU_HAS_LLSC=y
@@ -153,7 +152,6 @@
 #
 CONFIG_PCCARD=m
 # CONFIG_PCMCIA_DEBUG is not set
-# CONFIG_PCMCIA_OBSOLETE is not set
 CONFIG_PCMCIA=m
 
 #
@@ -245,6 +243,7 @@
 # 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
@@ -271,10 +270,12 @@
 # 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=m
@@ -288,6 +289,7 @@
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -364,8 +366,6 @@
 # CONFIG_IP_NF_QUEUE is not set
 # CONFIG_IP_NF_IPTABLES is not set
 # CONFIG_IP_NF_ARPTABLES is not set
-# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
-# CONFIG_IP_NF_COMPAT_IPFWADM is not set
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
 
@@ -489,6 +489,7 @@
 # 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=m
 
 #
@@ -539,7 +540,6 @@
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_AGP is not set
 # CONFIG_DRM is not set
 
 #
@@ -575,12 +575,14 @@
 #
 # 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
@@ -594,11 +596,25 @@
 # 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=y
@@ -748,6 +764,11 @@
 # CONFIG_NLS_UTF8 is not set
 
 #
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
 # Kernel hacking
 #
 # CONFIG_DEBUG_KERNEL is not set
@@ -788,6 +809,10 @@
 CONFIG_CRYPTO_MICHAEL_MIC=y
 CONFIG_CRYPTO_CRC32C=m
 # CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
 
 #
 # Library routines
diff -Nru a/arch/mips/configs/pb1500_defconfig b/arch/mips/configs/pb1500_defconfig
--- a/arch/mips/configs/pb1500_defconfig	2005-03-01 23:38:54 -08:00
+++ b/arch/mips/configs/pb1500_defconfig	2005-03-01 23:38:54 -08:00
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc2
-# Sun Nov 21 14:12:05 2004
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:09 2005
 #
 CONFIG_MIPS=y
 # CONFIG_MIPS64 is not set
@@ -101,12 +101,12 @@
 # CONFIG_SNI_RM200_PCI is not set
 # CONFIG_TOSHIBA_RBTX4927 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_HAVE_DEC_LOCK=y
 CONFIG_DMA_COHERENT=y
 CONFIG_CPU_LITTLE_ENDIAN=y
-# CONFIG_AU1000_USB_DEVICE is not set
+# CONFIG_AU1X00_USB_DEVICE is not set
 CONFIG_MIPS_L1_CACHE_SHIFT=5
-# CONFIG_FB is not set
 
 #
 # CPU selection
@@ -133,7 +133,6 @@
 # CONFIG_PAGE_SIZE_16KB is not set
 # CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_CPU_HAS_PREFETCH=y
-# CONFIG_VTAG_ICACHE is not set
 CONFIG_64BIT_PHYS_ADDR=y
 # CONFIG_CPU_ADVANCED is not set
 CONFIG_CPU_HAS_LLSC=y
@@ -154,7 +153,6 @@
 #
 CONFIG_PCCARD=m
 # CONFIG_PCMCIA_DEBUG is not set
-# CONFIG_PCMCIA_OBSOLETE is not set
 CONFIG_PCMCIA=m
 CONFIG_CARDBUS=y
 
@@ -166,6 +164,7 @@
 # CONFIG_I82092 is not set
 # CONFIG_TCIC is not set
 # CONFIG_PCMCIA_AU1X00 is not set
+CONFIG_PCCARD_NONSTATIC=m
 
 #
 # PCI Hotplug Support
@@ -212,11 +211,13 @@
 # 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_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_LBD is not set
 CONFIG_CDROM_PKTCDVD=m
@@ -230,6 +231,7 @@
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -359,8 +361,6 @@
 # CONFIG_IP_NF_QUEUE is not set
 # CONFIG_IP_NF_IPTABLES is not set
 # CONFIG_IP_NF_ARPTABLES is not set
-# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
-# CONFIG_IP_NF_COMPAT_IPFWADM is not set
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
 
@@ -522,6 +522,7 @@
 CONFIG_SERIO_SERPORT=y
 # CONFIG_SERIO_CT82C710 is not set
 # CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
 CONFIG_SERIO_RAW=m
 
 #
@@ -575,7 +576,6 @@
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_AGP is not set
 # CONFIG_DRM is not set
 
 #
@@ -611,6 +611,8 @@
 #
 # Graphics support
 #
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -625,11 +627,25 @@
 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=y
@@ -777,6 +793,11 @@
 # CONFIG_NLS_UTF8 is not set
 
 #
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
 # Kernel hacking
 #
 # CONFIG_DEBUG_KERNEL is not set
@@ -817,6 +838,10 @@
 CONFIG_CRYPTO_MICHAEL_MIC=y
 # CONFIG_CRYPTO_CRC32C is not set
 # CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
 
 #
 # Library routines
diff -Nru a/arch/mips/configs/pb1550_defconfig b/arch/mips/configs/pb1550_defconfig
--- a/arch/mips/configs/pb1550_defconfig	2005-03-01 23:38:53 -08:00
+++ b/arch/mips/configs/pb1550_defconfig	2005-03-01 23:38:53 -08:00
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc2
-# Sun Nov 21 14:12:05 2004
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:09 2005
 #
 CONFIG_MIPS=y
 # CONFIG_MIPS64 is not set
@@ -101,12 +101,12 @@
 # CONFIG_SNI_RM200_PCI is not set
 # CONFIG_TOSHIBA_RBTX4927 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_HAVE_DEC_LOCK=y
 CONFIG_DMA_COHERENT=y
 CONFIG_MIPS_DISABLE_OBSOLETE_IDE=y
 CONFIG_CPU_LITTLE_ENDIAN=y
 CONFIG_MIPS_L1_CACHE_SHIFT=5
-# CONFIG_FB is not set
 
 #
 # CPU selection
@@ -133,7 +133,6 @@
 # CONFIG_PAGE_SIZE_16KB is not set
 # CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_CPU_HAS_PREFETCH=y
-# CONFIG_VTAG_ICACHE is not set
 CONFIG_64BIT_PHYS_ADDR=y
 # CONFIG_CPU_ADVANCED is not set
 CONFIG_CPU_HAS_LLSC=y
@@ -154,7 +153,6 @@
 #
 CONFIG_PCCARD=m
 # CONFIG_PCMCIA_DEBUG is not set
-# CONFIG_PCMCIA_OBSOLETE is not set
 CONFIG_PCMCIA=m
 CONFIG_CARDBUS=y
 
@@ -166,6 +164,7 @@
 # CONFIG_I82092 is not set
 # CONFIG_TCIC is not set
 # CONFIG_PCMCIA_AU1X00 is not set
+CONFIG_PCCARD_NONSTATIC=m
 
 #
 # PCI Hotplug Support
@@ -212,11 +211,13 @@
 # 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_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_LBD is not set
 CONFIG_CDROM_PKTCDVD=m
@@ -230,6 +231,7 @@
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -359,8 +361,6 @@
 # CONFIG_IP_NF_QUEUE is not set
 # CONFIG_IP_NF_IPTABLES is not set
 # CONFIG_IP_NF_ARPTABLES is not set
-# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
-# CONFIG_IP_NF_COMPAT_IPFWADM is not set
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
 
@@ -514,6 +514,7 @@
 CONFIG_SERIO_SERPORT=y
 # CONFIG_SERIO_CT82C710 is not set
 # CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
 CONFIG_SERIO_RAW=m
 
 #
@@ -567,7 +568,6 @@
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_AGP is not set
 # CONFIG_DRM is not set
 
 #
@@ -603,6 +603,8 @@
 #
 # Graphics support
 #
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -617,11 +619,25 @@
 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=y
@@ -769,6 +785,11 @@
 # CONFIG_NLS_UTF8 is not set
 
 #
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
 # Kernel hacking
 #
 # CONFIG_DEBUG_KERNEL is not set
@@ -809,6 +830,10 @@
 CONFIG_CRYPTO_MICHAEL_MIC=y
 CONFIG_CRYPTO_CRC32C=m
 # CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
 
 #
 # Library routines
diff -Nru a/arch/mips/configs/rm200_defconfig b/arch/mips/configs/rm200_defconfig
--- a/arch/mips/configs/rm200_defconfig	2005-03-01 23:38:54 -08:00
+++ b/arch/mips/configs/rm200_defconfig	2005-03-01 23:38:54 -08:00
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc2
-# Sun Nov 21 14:12:06 2004
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:09 2005
 #
 CONFIG_MIPS=y
 # CONFIG_MIPS64 is not set
@@ -87,16 +87,16 @@
 CONFIG_SNI_RM200_PCI=y
 # CONFIG_TOSHIBA_RBTX4927 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_HAVE_DEC_LOCK=y
 CONFIG_ARC=y
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_I8259=y
 CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_ARC32=y
 CONFIG_BOOT_ELF32=y
 CONFIG_MIPS_L1_CACHE_SHIFT=5
-CONFIG_ARC32=y
-# CONFIG_FB is not set
 CONFIG_HAVE_STD_PC_SERIAL_PORT=y
 CONFIG_ARC_CONSOLE=y
 CONFIG_ARC_MEMORY=y
@@ -145,6 +145,21 @@
 CONFIG_MMU=y
 
 #
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+CONFIG_PCMCIA_PROBE=y
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
@@ -160,6 +175,7 @@
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -223,12 +239,14 @@
 # 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
 CONFIG_BLK_DEV_SX8=m
 CONFIG_BLK_DEV_UB=m
 CONFIG_BLK_DEV_RAM=m
+CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
 CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_LBD is not set
@@ -243,6 +261,7 @@
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -277,6 +296,7 @@
 #
 CONFIG_SCSI_SPI_ATTRS=y
 # CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
 
 #
 # SCSI low-level drivers
@@ -326,14 +346,12 @@
 # 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_SYM53C416 is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
@@ -477,7 +495,6 @@
 CONFIG_IP_NF_TARGET_REDIRECT=m
 CONFIG_IP_NF_TARGET_NETMAP=m
 CONFIG_IP_NF_TARGET_SAME=m
-CONFIG_IP_NF_NAT_LOCAL=y
 CONFIG_IP_NF_NAT_SNMP_BASIC=m
 CONFIG_IP_NF_NAT_IRC=m
 CONFIG_IP_NF_NAT_FTP=m
@@ -496,8 +513,6 @@
 CONFIG_IP_NF_ARPTABLES=m
 CONFIG_IP_NF_ARPFILTER=m
 CONFIG_IP_NF_ARP_MANGLE=m
-# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
-# CONFIG_IP_NF_COMPAT_IPFWADM is not set
 
 #
 # IPv6: Netfilter Configuration
@@ -551,6 +566,7 @@
 CONFIG_BRIDGE_EBT_REDIRECT=m
 CONFIG_BRIDGE_EBT_SNAT=m
 CONFIG_BRIDGE_EBT_LOG=m
+# CONFIG_BRIDGE_EBT_ULOG is not set
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
 
@@ -601,6 +617,7 @@
 CONFIG_NET_CLS_U32=m
 # CONFIG_CLS_U32_PERF is not set
 # CONFIG_NET_CLS_IND is not set
+# CONFIG_CLS_U32_MARK is not set
 CONFIG_NET_CLS_RSVP=m
 CONFIG_NET_CLS_RSVP6=m
 # CONFIG_NET_CLS_ACT is not set
@@ -691,7 +708,6 @@
 # CONFIG_CS89x0 is not set
 # CONFIG_DGRS is not set
 CONFIG_EEPRO100=m
-# CONFIG_EEPRO100_PIO is not set
 # CONFIG_E100 is not set
 # CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
@@ -787,6 +803,7 @@
 # CONFIG_SERIO_CT82C710 is not set
 CONFIG_SERIO_PARKBD=m
 # CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
 CONFIG_SERIO_RAW=m
 
 #
@@ -859,7 +876,6 @@
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_AGP is not set
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -874,7 +890,7 @@
 CONFIG_W1=m
 CONFIG_W1_MATROX=m
 CONFIG_W1_DS9490=m
-CONFIG_W1_DS9490R_BRIDGE=m
+CONFIG_W1_DS9490_BRIDGE=m
 CONFIG_W1_THERM=m
 CONFIG_W1_SMEM=m
 
@@ -895,6 +911,7 @@
 #
 # Graphics support
 #
+# CONFIG_FB is not set
 
 #
 # Console display driver support
@@ -902,6 +919,7 @@
 CONFIG_VGA_CONSOLE=y
 # CONFIG_MDA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -932,6 +950,7 @@
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
 CONFIG_USB_OHCI_HCD=m
 CONFIG_USB_UHCI_HCD=m
+# CONFIG_USB_SL811_HCD is not set
 
 #
 # USB Device Class drivers
@@ -939,6 +958,10 @@
 CONFIG_USB_BLUETOOTH_TTY=m
 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
@@ -980,7 +1003,6 @@
 #
 CONFIG_USB_MDC800=m
 CONFIG_USB_MICROTEK=m
-CONFIG_USB_HPUSBSCSI=m
 
 #
 # USB Multimedia devices
@@ -1045,6 +1067,7 @@
 CONFIG_USB_SERIAL_IR=m
 CONFIG_USB_SERIAL_EDGEPORT=m
 CONFIG_USB_SERIAL_EDGEPORT_TI=m
+# CONFIG_USB_SERIAL_GARMIN is not set
 # CONFIG_USB_SERIAL_IPW is not set
 CONFIG_USB_SERIAL_KEYSPAN_PDA=m
 CONFIG_USB_SERIAL_KEYSPAN=m
@@ -1066,6 +1089,7 @@
 CONFIG_USB_SERIAL_PL2303=m
 CONFIG_USB_SERIAL_SAFE=m
 CONFIG_USB_SERIAL_SAFE_PADDED=y
+# CONFIG_USB_SERIAL_TI is not set
 CONFIG_USB_SERIAL_CYBERJACK=m
 CONFIG_USB_SERIAL_XIRCOM=m
 CONFIG_USB_SERIAL_OMNINET=m
@@ -1076,7 +1100,6 @@
 #
 # CONFIG_USB_EMI62 is not set
 # CONFIG_USB_EMI26 is not set
-CONFIG_USB_TIGL=m
 CONFIG_USB_AUERSWALD=m
 CONFIG_USB_RIO500=m
 CONFIG_USB_LEGOTOWER=m
@@ -1085,6 +1108,7 @@
 CONFIG_USB_CYTHERM=m
 CONFIG_USB_PHIDGETKIT=m
 CONFIG_USB_PHIDGETSERVO=m
+# CONFIG_USB_IDMOUSE is not set
 CONFIG_USB_TEST=m
 
 #
@@ -1097,6 +1121,16 @@
 # 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=m
@@ -1180,7 +1214,6 @@
 CONFIG_VXFS_FS=m
 CONFIG_HPFS_FS=m
 CONFIG_QNX4FS_FS=m
-# CONFIG_QNX4FS_RW is not set
 CONFIG_SYSV_FS=m
 CONFIG_UFS_FS=m
 # CONFIG_UFS_FS_WRITE is not set
@@ -1208,7 +1241,7 @@
 CONFIG_CIFS=m
 # CONFIG_CIFS_STATS is not set
 # CONFIG_CIFS_XATTR is not set
-# CONFIG_CIFS_POSIX is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
 CONFIG_NCP_FS=m
 CONFIG_NCPFS_PACKET_SIGNING=y
 CONFIG_NCPFS_IOCTL_LOCKING=y
@@ -1288,6 +1321,11 @@
 CONFIG_NLS_UTF8=m
 
 #
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
 # Kernel hacking
 #
 # CONFIG_DEBUG_KERNEL is not set
@@ -1328,6 +1366,10 @@
 CONFIG_CRYPTO_MICHAEL_MIC=m
 # CONFIG_CRYPTO_CRC32C is not set
 CONFIG_CRYPTO_TEST=m
+
+#
+# Hardware crypto devices
+#
 
 #
 # Library routines
diff -Nru a/arch/mips/configs/sb1250-swarm_defconfig b/arch/mips/configs/sb1250-swarm_defconfig
--- a/arch/mips/configs/sb1250-swarm_defconfig	2005-03-01 23:39:17 -08:00
+++ b/arch/mips/configs/sb1250-swarm_defconfig	2005-03-01 23:39:17 -08:00
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc2
-# Sun Nov 21 14:12:06 2004
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:10 2005
 #
 CONFIG_MIPS=y
 # CONFIG_MIPS64 is not set
@@ -110,13 +110,13 @@
 # CONFIG_SNI_RM200_PCI is not set
 # CONFIG_TOSHIBA_RBTX4927 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_HAVE_DEC_LOCK=y
 CONFIG_DMA_COHERENT=y
 # CONFIG_CPU_LITTLE_ENDIAN is not set
 CONFIG_SWAP_IO_SPACE=y
 CONFIG_BOOT_ELF32=y
 CONFIG_MIPS_L1_CACHE_SHIFT=5
-# CONFIG_FB is not set
 
 #
 # CPU selection
@@ -143,8 +143,7 @@
 # CONFIG_PAGE_SIZE_16KB is not set
 # CONFIG_PAGE_SIZE_64KB is not set
 # CONFIG_SIBYTE_DMA_PAGEOPS is not set
-# CONFIG_CPU_HAS_PREFETCH is not set
-CONFIG_VTAG_ICACHE=y
+CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_SB1_PASS_1_WORKAROUNDS=y
 # CONFIG_64BIT_PHYS_ADDR is not set
 # CONFIG_CPU_ADVANCED is not set
@@ -166,6 +165,20 @@
 CONFIG_MMU=y
 
 #
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
@@ -181,6 +194,7 @@
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -204,10 +218,12 @@
 # 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=y
+CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=9220
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
@@ -223,6 +239,7 @@
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -441,6 +458,7 @@
 CONFIG_SERIO_SERPORT=y
 # CONFIG_SERIO_CT82C710 is not set
 # CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
 CONFIG_SERIO_RAW=m
 
 #
@@ -454,6 +472,8 @@
 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
@@ -491,7 +511,6 @@
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_AGP is not set
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -522,6 +541,8 @@
 #
 # Graphics support
 #
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -536,11 +557,25 @@
 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=y
@@ -636,6 +671,11 @@
 # CONFIG_NLS is not set
 
 #
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
 # Kernel hacking
 #
 # CONFIG_DEBUG_KERNEL is not set
@@ -677,6 +717,10 @@
 CONFIG_CRYPTO_MICHAEL_MIC=y
 # CONFIG_CRYPTO_CRC32C is not set
 # CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
 
 #
 # Library routines
diff -Nru a/arch/mips/configs/sead_defconfig b/arch/mips/configs/sead_defconfig
--- a/arch/mips/configs/sead_defconfig	2005-03-01 23:38:58 -08:00
+++ b/arch/mips/configs/sead_defconfig	2005-03-01 23:38:58 -08:00
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc2
-# Sun Nov 21 14:12:06 2004
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:10 2005
 #
 CONFIG_MIPS=y
 # CONFIG_MIPS64 is not set
@@ -77,13 +77,13 @@
 # CONFIG_SNI_RM200_PCI is not set
 # CONFIG_TOSHIBA_RBTX4927 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_HAVE_DEC_LOCK=y
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_CPU_LITTLE_ENDIAN=y
 CONFIG_IRQ_CPU=y
 CONFIG_MIPS_BOARDS_GEN=y
 CONFIG_MIPS_L1_CACHE_SHIFT=5
-# CONFIG_FB is not set
 
 #
 # CPU selection
@@ -110,7 +110,6 @@
 # CONFIG_PAGE_SIZE_16KB is not set
 # CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_CPU_HAS_PREFETCH=y
-# CONFIG_VTAG_ICACHE is not set
 # CONFIG_64BIT_PHYS_ADDR is not set
 # CONFIG_CPU_ADVANCED is not set
 CONFIG_CPU_HAS_LLSC=y
@@ -123,6 +122,19 @@
 CONFIG_MMU=y
 
 #
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# PCI Hotplug Support
+#
+
+#
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
@@ -138,6 +150,7 @@
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -157,9 +170,11 @@
 # 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_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=18432
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
@@ -245,6 +260,7 @@
 # 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=y
 
 #
@@ -298,7 +314,6 @@
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_AGP is not set
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -328,12 +343,14 @@
 #
 # 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
@@ -347,11 +364,25 @@
 # 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=y
@@ -425,6 +456,11 @@
 # CONFIG_NLS is not set
 
 #
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
 # Kernel hacking
 #
 # CONFIG_DEBUG_KERNEL is not set
@@ -442,6 +478,10 @@
 # Cryptographic options
 #
 # CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
 
 #
 # Library routines
diff -Nru a/arch/mips/configs/tb0226_defconfig b/arch/mips/configs/tb0226_defconfig
--- a/arch/mips/configs/tb0226_defconfig	2005-03-01 23:38:58 -08:00
+++ b/arch/mips/configs/tb0226_defconfig	2005-03-01 23:38:58 -08:00
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc2
-# Sun Nov 21 14:12:07 2004
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:12 2005
 #
 CONFIG_MIPS=y
 # CONFIG_MIPS64 is not set
@@ -58,6 +58,7 @@
 #
 # CONFIG_MACH_JAZZ is not set
 CONFIG_MACH_VR41XX=y
+# CONFIG_NEC_CMBVR4133 is not set
 # CONFIG_CASIO_E55 is not set
 # CONFIG_IBM_WORKPAD is not set
 CONFIG_TANBAC_TB0226=y
@@ -91,12 +92,12 @@
 # CONFIG_SNI_RM200_PCI is not set
 # CONFIG_TOSHIBA_RBTX4927 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_HAVE_DEC_LOCK=y
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_CPU_LITTLE_ENDIAN=y
 CONFIG_IRQ_CPU=y
 CONFIG_MIPS_L1_CACHE_SHIFT=5
-CONFIG_FB=y
 
 #
 # CPU selection
@@ -134,6 +135,19 @@
 CONFIG_MMU=y
 
 #
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# PCI Hotplug Support
+#
+
+#
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
@@ -149,6 +163,7 @@
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -168,10 +183,12 @@
 # Block devices
 #
 # CONFIG_BLK_DEV_FD 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=m
+CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
 CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_LBD is not set
@@ -186,6 +203,7 @@
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -242,12 +260,12 @@
 #
 # CONFIG_SCSI_SPI_ATTRS is not set
 # CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
 
 #
 # SCSI low-level drivers
 #
 # CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_QLOGIC_1280_1040 is not set
 # CONFIG_SCSI_DEBUG is not set
 
 #
@@ -420,6 +438,7 @@
 CONFIG_SERIO_I8042=y
 CONFIG_SERIO_SERPORT=y
 # CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_LIBPS2 is not set
 CONFIG_SERIO_RAW=m
 
 #
@@ -473,7 +492,6 @@
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_AGP is not set
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -504,6 +522,7 @@
 #
 # Graphics support
 #
+CONFIG_FB=y
 # CONFIG_FB_MODE_HELPERS is not set
 # CONFIG_FB_TILEBLITTING is not set
 # CONFIG_FB_VIRTUAL is not set
@@ -519,6 +538,7 @@
 # Logo configuration
 #
 # CONFIG_LOGO is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -542,11 +562,25 @@
 # 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=y
@@ -690,6 +724,11 @@
 # CONFIG_NLS_UTF8 is not set
 
 #
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
 # Kernel hacking
 #
 # CONFIG_DEBUG_KERNEL is not set
@@ -707,6 +746,10 @@
 # Cryptographic options
 #
 # CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
 
 #
 # Library routines
diff -Nru a/arch/mips/configs/tb0229_defconfig b/arch/mips/configs/tb0229_defconfig
--- a/arch/mips/configs/tb0229_defconfig	2005-03-01 23:39:16 -08:00
+++ b/arch/mips/configs/tb0229_defconfig	2005-03-01 23:39:16 -08:00
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc2
-# Sun Nov 21 14:12:07 2004
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:12 2005
 #
 CONFIG_MIPS=y
 # CONFIG_MIPS64 is not set
@@ -58,14 +58,16 @@
 #
 # CONFIG_MACH_JAZZ is not set
 CONFIG_MACH_VR41XX=y
+# CONFIG_NEC_CMBVR4133 is not set
 # CONFIG_CASIO_E55 is not set
 # CONFIG_IBM_WORKPAD is not set
 # CONFIG_TANBAC_TB0226 is not set
 CONFIG_TANBAC_TB0229=y
+CONFIG_TANBAC_TB0219=y
 # CONFIG_VICTOR_MPC30X is not set
 # CONFIG_ZAO_CAPCELLA is not set
 CONFIG_PCI_VR41XX=y
-CONFIG_VRC4173=y
+# CONFIG_VRC4173 is not set
 # CONFIG_TOSHIBA_JMR3927 is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
@@ -93,13 +95,12 @@
 # CONFIG_SNI_RM200_PCI is not set
 # CONFIG_TOSHIBA_RBTX4927 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_HAVE_DEC_LOCK=y
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_CPU_LITTLE_ENDIAN=y
 CONFIG_IRQ_CPU=y
 CONFIG_MIPS_L1_CACHE_SHIFT=5
-# CONFIG_FB is not set
-CONFIG_TANBAC_TB0219=y
 
 #
 # CPU selection
@@ -139,6 +140,20 @@
 CONFIG_MMU=y
 
 #
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
@@ -154,6 +169,7 @@
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -177,11 +193,13 @@
 # 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 is not set
 CONFIG_BLK_DEV_NBD=m
 # CONFIG_BLK_DEV_SX8 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=""
@@ -197,6 +215,7 @@
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -315,7 +334,7 @@
 # Ethernet (10 or 100Mbit)
 #
 CONFIG_NET_ETHERNET=y
-# CONFIG_MII is not set
+CONFIG_MII=y
 # CONFIG_HAPPYMEAL is not set
 # CONFIG_SUNGEM is not set
 # CONFIG_NET_VENDOR_3COM is not set
@@ -325,7 +344,26 @@
 #
 # CONFIG_NET_TULIP is not set
 # CONFIG_HP100 is not set
-# CONFIG_NET_PCI is not set
+CONFIG_NET_PCI=y
+CONFIG_PCNET32=y
+# 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 is not set
+# 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
+# CONFIG_LAN_SAA9730 is not set
 
 #
 # Ethernet (1000 Mbit)
@@ -338,6 +376,7 @@
 # CONFIG_YELLOWFIN is not set
 # CONFIG_R8169 is not set
 # CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 
 #
@@ -414,6 +453,7 @@
 CONFIG_SERIO_SERPORT=y
 # CONFIG_SERIO_CT82C710 is not set
 # CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
 CONFIG_SERIO_RAW=m
 
 #
@@ -468,7 +508,6 @@
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_AGP is not set
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -499,12 +538,14 @@
 #
 # 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
@@ -519,11 +560,25 @@
 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=y
@@ -538,6 +593,7 @@
 # CONFIG_REISERFS_FS is not set
 CONFIG_JFS_FS=m
 # CONFIG_JFS_POSIX_ACL is not set
+# CONFIG_JFS_SECURITY is not set
 # CONFIG_JFS_DEBUG is not set
 # CONFIG_JFS_STATISTICS is not set
 CONFIG_XFS_FS=y
@@ -680,11 +736,16 @@
 # CONFIG_NLS_UTF8 is not set
 
 #
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
 # Kernel hacking
 #
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_CROSSCOMPILE=y
-CONFIG_CMDLINE=""
+CONFIG_CMDLINE="mem=64M console=ttyS0,38400 ip=bootp root=/dev/nfs"
 
 #
 # Security options
@@ -699,10 +760,14 @@
 # CONFIG_CRYPTO is not set
 
 #
+# Hardware crypto devices
+#
+
+#
 # Library routines
 #
 CONFIG_CRC_CCITT=m
-# CONFIG_CRC32 is not set
+CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=m
diff -Nru a/arch/mips/configs/workpad_defconfig b/arch/mips/configs/workpad_defconfig
--- a/arch/mips/configs/workpad_defconfig	2005-03-01 23:39:09 -08:00
+++ b/arch/mips/configs/workpad_defconfig	2005-03-01 23:39:09 -08:00
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc2
-# Sun Nov 21 14:12:08 2004
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:12 2005
 #
 CONFIG_MIPS=y
 # CONFIG_MIPS64 is not set
@@ -58,6 +58,7 @@
 #
 # CONFIG_MACH_JAZZ is not set
 CONFIG_MACH_VR41XX=y
+# CONFIG_NEC_CMBVR4133 is not set
 # CONFIG_CASIO_E55 is not set
 CONFIG_IBM_WORKPAD=y
 # CONFIG_TANBAC_TB0226 is not set
@@ -92,12 +93,12 @@
 # CONFIG_SNI_RM200_PCI is not set
 # CONFIG_TOSHIBA_RBTX4927 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_HAVE_DEC_LOCK=y
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_CPU_LITTLE_ENDIAN=y
 CONFIG_IRQ_CPU=y
 CONFIG_MIPS_L1_CACHE_SHIFT=5
-# CONFIG_FB is not set
 
 #
 # CPU selection
@@ -134,6 +135,20 @@
 CONFIG_MMU=y
 
 #
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+CONFIG_PCMCIA_PROBE=y
+
+#
+# PCI Hotplug Support
+#
+
+#
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
@@ -149,6 +164,7 @@
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -170,9 +186,11 @@
 #
 # 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 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=m
@@ -186,6 +204,7 @@
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -397,6 +416,7 @@
 CONFIG_SERIO_I8042=y
 CONFIG_SERIO_SERPORT=y
 # CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_LIBPS2 is not set
 CONFIG_SERIO_RAW=m
 
 #
@@ -463,7 +483,6 @@
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_AGP is not set
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -494,6 +513,7 @@
 #
 # Graphics support
 #
+# CONFIG_FB is not set
 
 #
 # Console display driver support
@@ -501,6 +521,7 @@
 # CONFIG_VGA_CONSOLE is not set
 # CONFIG_MDA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -514,11 +535,25 @@
 # 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=y
@@ -615,6 +650,11 @@
 # CONFIG_NLS is not set
 
 #
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
 # Kernel hacking
 #
 # CONFIG_DEBUG_KERNEL is not set
@@ -632,6 +672,10 @@
 # Cryptographic options
 #
 # CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
 
 #
 # Library routines
diff -Nru a/arch/mips/configs/yosemite_defconfig b/arch/mips/configs/yosemite_defconfig
--- a/arch/mips/configs/yosemite_defconfig	2005-03-01 23:39:16 -08:00
+++ b/arch/mips/configs/yosemite_defconfig	2005-03-01 23:39:16 -08:00
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc2
-# Fri Nov 26 00:00:39 2004
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:13 2005
 #
 CONFIG_MIPS=y
 # CONFIG_MIPS64 is not set
@@ -80,14 +80,15 @@
 # CONFIG_SNI_RM200_PCI is not set
 # CONFIG_TOSHIBA_RBTX4927 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_HAVE_DEC_LOCK=y
 CONFIG_DMA_COHERENT=y
 # CONFIG_CPU_LITTLE_ENDIAN is not set
 CONFIG_IRQ_CPU=y
 CONFIG_IRQ_CPU_RM7K=y
+CONFIG_IRQ_CPU_RM9K=y
 CONFIG_SWAP_IO_SPACE=y
 CONFIG_MIPS_L1_CACHE_SHIFT=5
-# CONFIG_FB is not set
 
 #
 # CPU selection
@@ -134,6 +135,19 @@
 CONFIG_MMU=y
 
 #
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# PCI Hotplug Support
+#
+
+#
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
@@ -149,6 +163,7 @@
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
 # CONFIG_DEBUG_DRIVER is not set
 
 #
@@ -172,10 +187,12 @@
 # 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_LBD is not set
 CONFIG_CDROM_PKTCDVD=m
@@ -189,6 +206,7 @@
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -401,7 +419,8 @@
 #
 # CONFIG_WATCHDOG is not set
 # CONFIG_RTC is not set
-# CONFIG_GEN_RTC is not set
+CONFIG_GEN_RTC=y
+CONFIG_GEN_RTC_X=y
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -409,7 +428,6 @@
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_AGP is not set
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -440,6 +458,8 @@
 #
 # Graphics support
 #
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -454,11 +474,25 @@
 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
@@ -548,6 +582,7 @@
 # CONFIG_DEBUG_KOBJECT is not set
 # CONFIG_DEBUG_HIGHMEM is not set
 # CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_FS is not set
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
 # CONFIG_DEBUG_STACK_USAGE is not set
@@ -565,6 +600,10 @@
 # Cryptographic options
 #
 # CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
 
 #
 # Library routines
diff -Nru a/arch/mips/ddb5xxx/ddb5074/irq.c b/arch/mips/ddb5xxx/ddb5074/irq.c
--- a/arch/mips/ddb5xxx/ddb5074/irq.c	2005-03-01 23:39:17 -08:00
+++ b/arch/mips/ddb5xxx/ddb5074/irq.c	2005-03-01 23:39:17 -08:00
@@ -4,7 +4,6 @@
  *  Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com>
  *                     Sony Software Development Center Europe (SDCE), Brussels
  */
-#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/irq.h>
 #include <linux/signal.h>
diff -Nru a/arch/mips/ddb5xxx/ddb5074/setup.c b/arch/mips/ddb5xxx/ddb5074/setup.c
--- a/arch/mips/ddb5xxx/ddb5074/setup.c	2005-03-01 23:39:08 -08:00
+++ b/arch/mips/ddb5xxx/ddb5074/setup.c	2005-03-01 23:39:08 -08:00
@@ -4,7 +4,6 @@
  *  Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com>
  *                     Sony Software Development Center Europe (SDCE), Brussels
  */
-#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/kbd_ll.h>
 #include <linux/kernel.h>
@@ -88,8 +87,6 @@
 
 static void __init ddb5074_setup(void)
 {
-	extern int panic_timeout;
-
 	set_io_port_base(NILE4_PCI_IO_BASE);
 	isa_slot_offset = NILE4_PCI_MEM_BASE;
 	board_timer_setup = ddb_timer_init;
diff -Nru a/arch/mips/ddb5xxx/ddb5476/setup.c b/arch/mips/ddb5xxx/ddb5476/setup.c
--- a/arch/mips/ddb5xxx/ddb5476/setup.c	2005-03-01 23:39:07 -08:00
+++ b/arch/mips/ddb5xxx/ddb5476/setup.c	2005-03-01 23:39:07 -08:00
@@ -4,7 +4,6 @@
  *  Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com>
  *                     Sony Software Development Center Europe (SDCE), Brussels
  */
-#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/kbd_ll.h>
 #include <linux/kernel.h>
@@ -127,8 +126,6 @@
 
 static void __init ddb5476_setup(void)
 {
-	extern int panic_timeout;
-
 	set_io_port_base(KSEG1ADDR(DDB_PCI_IO_BASE));
 
 	board_time_init = ddb_time_init;
diff -Nru a/arch/mips/ddb5xxx/ddb5477/setup.c b/arch/mips/ddb5xxx/ddb5477/setup.c
--- a/arch/mips/ddb5xxx/ddb5477/setup.c	2005-03-01 23:39:09 -08:00
+++ b/arch/mips/ddb5xxx/ddb5477/setup.c	2005-03-01 23:39:09 -08:00
@@ -172,8 +172,6 @@
 
 static int  ddb5477_setup(void)
 {
-	extern int panic_timeout;
-
 	/* initialize board - we don't trust the loader */
         ddb5477_board_init();
 
diff -Nru a/arch/mips/dec/boot/decstation.c b/arch/mips/dec/boot/decstation.c
--- a/arch/mips/dec/boot/decstation.c	2005-03-01 23:38:57 -08:00
+++ b/arch/mips/dec/boot/decstation.c	2005-03-01 23:38:57 -08:00
@@ -1,7 +1,6 @@
 /*
  * arch/mips/dec/decstation.c
  */
-#include <linux/config.h>
 
 #define RELOC
 #define INITRD
diff -Nru a/arch/mips/dec/ioasic-irq.c b/arch/mips/dec/ioasic-irq.c
--- a/arch/mips/dec/ioasic-irq.c	2005-03-01 23:39:16 -08:00
+++ b/arch/mips/dec/ioasic-irq.c	2005-03-01 23:39:16 -08:00
@@ -21,7 +21,7 @@
 #include <asm/dec/ioasic_ints.h>
 
 
-static spinlock_t ioasic_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(ioasic_lock);
 
 static int ioasic_irq_base;
 
diff -Nru a/arch/mips/dec/kn02-irq.c b/arch/mips/dec/kn02-irq.c
--- a/arch/mips/dec/kn02-irq.c	2005-03-01 23:39:16 -08:00
+++ b/arch/mips/dec/kn02-irq.c	2005-03-01 23:39:16 -08:00
@@ -29,7 +29,7 @@
  * There is no default value -- it has to be initialized.
  */
 u32 cached_kn02_csr;
-spinlock_t kn02_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(kn02_lock);
 
 
 static int kn02_irq_base;
diff -Nru a/arch/mips/dec/setup.c b/arch/mips/dec/setup.c
--- a/arch/mips/dec/setup.c	2005-03-01 23:38:55 -08:00
+++ b/arch/mips/dec/setup.c	2005-03-01 23:38:55 -08:00
@@ -8,7 +8,6 @@
  * Copyright (C) 1998 Harald Koerfgen
  * Copyright (C) 2000, 2001, 2002, 2003  Maciej W. Rozycki
  */
-#include <linux/config.h>
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <linux/param.h>
diff -Nru a/arch/mips/defconfig b/arch/mips/defconfig
--- a/arch/mips/defconfig	2005-03-01 23:38:52 -08:00
+++ b/arch/mips/defconfig	2005-03-01 23:38:52 -08:00
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc2
-# Sun Nov 21 14:11:54 2004
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:48:59 2005
 #
 CONFIG_MIPS=y
 # CONFIG_MIPS64 is not set
@@ -86,16 +86,16 @@
 # CONFIG_SNI_RM200_PCI is not set
 # CONFIG_TOSHIBA_RBTX4927 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_HAVE_DEC_LOCK=y
 CONFIG_ARC=y
 CONFIG_DMA_NONCOHERENT=y
 # CONFIG_CPU_LITTLE_ENDIAN is not set
 CONFIG_IRQ_CPU=y
 CONFIG_SWAP_IO_SPACE=y
+CONFIG_ARC32=y
 CONFIG_BOOT_ELF32=y
 CONFIG_MIPS_L1_CACHE_SHIFT=5
-CONFIG_ARC32=y
-# CONFIG_FB is not set
 CONFIG_ARC_CONSOLE=y
 CONFIG_ARC_PROMLIB=y
 
@@ -139,6 +139,19 @@
 CONFIG_MMU=y
 
 #
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# PCI Hotplug Support
+#
+
+#
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
@@ -154,6 +167,7 @@
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -173,9 +187,11 @@
 # 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=m
@@ -189,6 +205,7 @@
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -223,13 +240,13 @@
 #
 CONFIG_SCSI_SPI_ATTRS=m
 # CONFIG_SCSI_FC_ATTRS is not set
+CONFIG_SCSI_ISCSI_ATTRS=m
 
 #
 # SCSI low-level drivers
 #
 CONFIG_SGIWD93_SCSI=y
 # CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_QLOGIC_1280_1040 is not set
 # CONFIG_SCSI_DEBUG is not set
 
 #
@@ -372,7 +389,6 @@
 CONFIG_IP_NF_TARGET_REDIRECT=m
 CONFIG_IP_NF_TARGET_NETMAP=m
 CONFIG_IP_NF_TARGET_SAME=m
-CONFIG_IP_NF_NAT_LOCAL=y
 CONFIG_IP_NF_NAT_SNMP_BASIC=m
 CONFIG_IP_NF_NAT_IRC=m
 CONFIG_IP_NF_NAT_FTP=m
@@ -391,8 +407,6 @@
 CONFIG_IP_NF_ARPTABLES=m
 CONFIG_IP_NF_ARPFILTER=m
 CONFIG_IP_NF_ARP_MANGLE=m
-# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
-# CONFIG_IP_NF_COMPAT_IPFWADM is not set
 
 #
 # IPv6: Netfilter Configuration
@@ -471,6 +485,7 @@
 CONFIG_NET_CLS_U32=m
 # CONFIG_CLS_U32_PERF is not set
 # CONFIG_NET_CLS_IND is not set
+# CONFIG_CLS_U32_MARK is not set
 CONFIG_NET_CLS_RSVP=m
 CONFIG_NET_CLS_RSVP6=m
 # CONFIG_NET_CLS_ACT is not set
@@ -561,6 +576,7 @@
 CONFIG_SERIO_I8042=y
 CONFIG_SERIO_SERPORT=y
 # CONFIG_SERIO_CT82C710 is not set
+CONFIG_SERIO_LIBPS2=y
 CONFIG_SERIO_RAW=m
 
 #
@@ -627,7 +643,6 @@
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_AGP is not set
 # CONFIG_DRM is not set
 CONFIG_RAW_DRIVER=m
 CONFIG_MAX_RAW_DEVS=256
@@ -659,6 +674,7 @@
 #
 # Graphics support
 #
+# CONFIG_FB is not set
 
 #
 # Console display driver support
@@ -676,6 +692,7 @@
 # CONFIG_LOGO_LINUX_VGA16 is not set
 # CONFIG_LOGO_LINUX_CLUT224 is not set
 CONFIG_LOGO_SGI_CLUT224=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -689,11 +706,25 @@
 # 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=m
@@ -798,7 +829,7 @@
 CONFIG_CIFS=m
 # CONFIG_CIFS_STATS is not set
 # CONFIG_CIFS_XATTR is not set
-# CONFIG_CIFS_POSIX is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
 # CONFIG_NCP_FS is not set
 CONFIG_CODA_FS=m
 # CONFIG_CODA_FS_OLD_API is not set
@@ -869,6 +900,11 @@
 CONFIG_NLS_UTF8=m
 
 #
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
 # Kernel hacking
 #
 # CONFIG_DEBUG_KERNEL is not set
@@ -911,10 +947,14 @@
 CONFIG_CRYPTO_TEST=m
 
 #
+# Hardware crypto devices
+#
+
+#
 # Library routines
 #
 # CONFIG_CRC_CCITT is not set
-# CONFIG_CRC32 is not set
+CONFIG_CRC32=m
 CONFIG_LIBCRC32C=m
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
diff -Nru a/arch/mips/galileo-boards/ev96100/time.c b/arch/mips/galileo-boards/ev96100/time.c
--- a/arch/mips/galileo-boards/ev96100/time.c	2005-03-01 23:38:57 -08:00
+++ b/arch/mips/galileo-boards/ev96100/time.c	2005-03-01 23:38:57 -08:00
@@ -32,6 +32,7 @@
  *  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/kernel_stat.h>
 #include <linux/module.h>
diff -Nru a/arch/mips/gt64120/ev64120/irq.c b/arch/mips/gt64120/ev64120/irq.c
--- a/arch/mips/gt64120/ev64120/irq.c	2005-03-01 23:39:09 -08:00
+++ b/arch/mips/gt64120/ev64120/irq.c	2005-03-01 23:39:09 -08:00
@@ -119,7 +119,7 @@
 	/* Sets the exception_handler array. */
 	set_except_vector(0, galileo_handle_int);
 
-	cli();
+	local_irq_disable();
 
 	/*
 	 * Enable timer.  Other interrupts will be enabled as they are
@@ -138,7 +138,7 @@
 		irq_desc[i].handler = &no_irq_type;
 		irq_desc[i].action = NULL;
 		irq_desc[i].depth = 0;
-		irq_desc[i].lock = SPIN_LOCK_UNLOCKED;
+		spin_lock_init(&irq_desc[i].lock);
 	}
 
 	gt64120_irq_setup();
diff -Nru a/arch/mips/gt64120/momenco_ocelot/irq.c b/arch/mips/gt64120/momenco_ocelot/irq.c
--- a/arch/mips/gt64120/momenco_ocelot/irq.c	2005-03-01 23:38:44 -08:00
+++ b/arch/mips/gt64120/momenco_ocelot/irq.c	2005-03-01 23:38:44 -08:00
@@ -28,7 +28,6 @@
  *  675 Mass Ave, Cambridge, MA 02139, USA.
  *
  */
-#include <linux/config.h>
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/kernel_stat.h>
diff -Nru a/arch/mips/gt64120/momenco_ocelot/setup.c b/arch/mips/gt64120/momenco_ocelot/setup.c
--- a/arch/mips/gt64120/momenco_ocelot/setup.c	2005-03-01 23:38:57 -08:00
+++ b/arch/mips/gt64120/momenco_ocelot/setup.c	2005-03-01 23:38:57 -08:00
@@ -304,7 +304,7 @@
 	}
 
 	/* Fix up the DiskOnChip mapping */
-	GT_WRITE(0x468, 0xfef73);
+	GT_WRITE(GT_DEV_B3_OFS, 0xfef73);
 }
 
 early_initcall(momenco_ocelot_setup);
@@ -322,8 +322,8 @@
 	printk("Enabling L3 cache...");
 
 	/* Enable the L3 cache in the GT64120A's CPU Configuration register */
-	tmp =  GT_READ(0);
-	GT_WRITE(0, tmp | (1<<14));
+	tmp = GT_READ(GT_CPU_OFS);
+	GT_WRITE(GT_CPU_OFS, tmp | (1<<14));
 
 	/* Enable the L3 cache in the CPU */
 	set_c0_config(1<<12 /* CONF_TE */);
diff -Nru a/arch/mips/ite-boards/generic/irq.c b/arch/mips/ite-boards/generic/irq.c
--- a/arch/mips/ite-boards/generic/irq.c	2005-03-01 23:38:58 -08:00
+++ b/arch/mips/ite-boards/generic/irq.c	2005-03-01 23:38:58 -08:00
@@ -32,7 +32,6 @@
  *  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/errno.h>
 #include <linux/init.h>
 #include <linux/irq.h>
@@ -57,14 +56,6 @@
 #include <asm/it8172/it8172_int.h>
 #include <asm/it8172/it8172_dbg.h>
 
-#undef DEBUG_IRQ
-#ifdef DEBUG_IRQ
-/* note: prints function name for you */
-#define DPRINTK(fmt, args...) printk("%s: " fmt, __FUNCTION__ , ## args)
-#else
-#define DPRINTK(fmt, args...)
-#endif
-
 /* revisit */
 #define EXT_IRQ0_TO_IP 2 /* IP 2 */
 #define EXT_IRQ5_TO_IP 7 /* IP 7 */
@@ -81,111 +72,50 @@
 struct it8172_intc_regs volatile *it8172_hw0_icregs =
 	(struct it8172_intc_regs volatile *)(KSEG1ADDR(IT8172_PCI_IO_BASE + IT_INTC_BASE));
 
-/* Function for careful CP0 interrupt mask access */
-static inline void modify_cp0_intmask(unsigned clr_mask, unsigned set_mask)
-{
-        unsigned long status = read_c0_status();
-        status &= ~((clr_mask & 0xFF) << 8);
-        status |=   (set_mask & 0xFF) << 8;
-        write_c0_status(status);
-}
-
-static inline void mask_irq(unsigned int irq_nr)
-{
-        modify_cp0_intmask(irq_nr, 0);
-}
-
-static inline void unmask_irq(unsigned int irq_nr)
-{
-        modify_cp0_intmask(0, irq_nr);
-}
-
-void local_disable_irq(unsigned int irq_nr)
-{
-        unsigned long flags;
-
-        local_irq_save(flags);
-	disable_it8172_irq(irq_nr);
-        local_irq_restore(flags);
-}
-
-void local_enable_irq(unsigned int irq_nr)
+static void disable_it8172_irq(unsigned int irq_nr)
 {
-	unsigned long flags;
-
-        local_irq_save(flags);
-	enable_it8172_irq(irq_nr);
-        local_irq_restore(flags);
-}
-
-
-void disable_it8172_irq(unsigned int irq_nr)
-{
-	DPRINTK("disable_it8172_irq %d\n", irq_nr);
-
 	if ( (irq_nr >= IT8172_LPC_IRQ_BASE) && (irq_nr <= IT8172_SERIRQ_15)) {
 		/* LPC interrupt */
-		DPRINTK("DB lpc_mask  %x\n", it8172_hw0_icregs->lpc_mask);
 		it8172_hw0_icregs->lpc_mask |=
 			(1 << (irq_nr - IT8172_LPC_IRQ_BASE));
-		DPRINTK("DA lpc_mask  %x\n", it8172_hw0_icregs->lpc_mask);
-	}
-	else if ( (irq_nr >= IT8172_LB_IRQ_BASE) && (irq_nr <= IT8172_IOCHK_IRQ)) {
+	} else if ( (irq_nr >= IT8172_LB_IRQ_BASE) && (irq_nr <= IT8172_IOCHK_IRQ)) {
 		/* Local Bus interrupt */
-		DPRINTK("DB lb_mask  %x\n", it8172_hw0_icregs->lb_mask);
 		it8172_hw0_icregs->lb_mask |=
 			(1 << (irq_nr - IT8172_LB_IRQ_BASE));
-		DPRINTK("DA lb_mask  %x\n", it8172_hw0_icregs->lb_mask);
-	}
-	else if ( (irq_nr >= IT8172_PCI_DEV_IRQ_BASE) && (irq_nr <= IT8172_DMA_IRQ)) {
+	} else if ( (irq_nr >= IT8172_PCI_DEV_IRQ_BASE) && (irq_nr <= IT8172_DMA_IRQ)) {
 		/* PCI and other interrupts */
-		DPRINTK("DB pci_mask  %x\n", it8172_hw0_icregs->pci_mask);
 		it8172_hw0_icregs->pci_mask |=
 			(1 << (irq_nr - IT8172_PCI_DEV_IRQ_BASE));
-		DPRINTK("DA pci_mask  %x\n", it8172_hw0_icregs->pci_mask);
-	}
-	else if ( (irq_nr >= IT8172_NMI_IRQ_BASE) && (irq_nr <= IT8172_POWER_NMI_IRQ)) {
+	} else if ( (irq_nr >= IT8172_NMI_IRQ_BASE) && (irq_nr <= IT8172_POWER_NMI_IRQ)) {
 		/* NMI interrupts */
-		DPRINTK("DB nmi_mask  %x\n", it8172_hw0_icregs->nmi_mask);
 		it8172_hw0_icregs->nmi_mask |=
 			(1 << (irq_nr - IT8172_NMI_IRQ_BASE));
-		DPRINTK("DA nmi_mask  %x\n", it8172_hw0_icregs->nmi_mask);
-	}
-	else {
+	} else {
 		panic("disable_it8172_irq: bad irq %d", irq_nr);
 	}
 }
 
-void enable_it8172_irq(unsigned int irq_nr)
+static void enable_it8172_irq(unsigned int irq_nr)
 {
-	DPRINTK("enable_it8172_irq %d\n", irq_nr);
 	if ( (irq_nr >= IT8172_LPC_IRQ_BASE) && (irq_nr <= IT8172_SERIRQ_15)) {
 		/* LPC interrupt */
-		DPRINTK("EB before lpc_mask  %x\n", it8172_hw0_icregs->lpc_mask);
 		it8172_hw0_icregs->lpc_mask &=
 			~(1 << (irq_nr - IT8172_LPC_IRQ_BASE));
-		DPRINTK("EA after lpc_mask  %x\n", it8172_hw0_icregs->lpc_mask);
 	}
 	else if ( (irq_nr >= IT8172_LB_IRQ_BASE) && (irq_nr <= IT8172_IOCHK_IRQ)) {
 		/* Local Bus interrupt */
-		DPRINTK("EB lb_mask  %x\n", it8172_hw0_icregs->lb_mask);
 		it8172_hw0_icregs->lb_mask &=
 			~(1 << (irq_nr - IT8172_LB_IRQ_BASE));
-		DPRINTK("EA lb_mask  %x\n", it8172_hw0_icregs->lb_mask);
 	}
 	else if ( (irq_nr >= IT8172_PCI_DEV_IRQ_BASE) && (irq_nr <= IT8172_DMA_IRQ)) {
 		/* PCI and other interrupts */
-		DPRINTK("EB pci_mask  %x\n", it8172_hw0_icregs->pci_mask);
 		it8172_hw0_icregs->pci_mask &=
 			~(1 << (irq_nr - IT8172_PCI_DEV_IRQ_BASE));
-		DPRINTK("EA pci_mask  %x\n", it8172_hw0_icregs->pci_mask);
 	}
 	else if ( (irq_nr >= IT8172_NMI_IRQ_BASE) && (irq_nr <= IT8172_POWER_NMI_IRQ)) {
 		/* NMI interrupts */
-		DPRINTK("EB nmi_mask  %x\n", it8172_hw0_icregs->nmi_mask);
 		it8172_hw0_icregs->nmi_mask &=
 			~(1 << (irq_nr - IT8172_NMI_IRQ_BASE));
-		DPRINTK("EA nmi_mask  %x\n", it8172_hw0_icregs->nmi_mask);
 	}
 	else {
 		panic("enable_it8172_irq: bad irq %d", irq_nr);
@@ -243,7 +173,7 @@
         unsigned long flags;
 
         local_irq_save(flags);
-	unmask_irq(1<<EXT_IRQ5_TO_IP); /* timer interrupt */
+	set_c0_status(0x100 << EXT_IRQ5_TO_IP);
         local_irq_restore(flags);
 }
 
@@ -305,7 +235,6 @@
 	cause = read_c0_cause();
 	printk("status %x cause %x\n", status, cause);
 	printk("epc %x badvaddr %x \n", regs->cp0_epc, regs->cp0_badvaddr);
-//	while(1);
 #endif
 }
 
@@ -326,9 +255,7 @@
 			status >>= 1;
 		}
 		irq += IT8172_PCI_DEV_IRQ_BASE;
-		//printk("pci int %d\n", irq);
-	}
-	else if (intstatus & 0x1) {
+	} else if (intstatus & 0x1) {
 		/* Local Bus interrupt */
 		irq = 0;
 		status |= it8172_hw0_icregs->lb_req;
@@ -337,9 +264,7 @@
 			status >>= 1;
 		}
 		irq += IT8172_LB_IRQ_BASE;
-		//printk("lb int %d\n", irq);
-	}
-	else if (intstatus & 0x2) {
+	} else if (intstatus & 0x2) {
 		/* LPC interrupt */
 		/* Since some lpc interrupts are edge triggered,
 		 * we could lose an interrupt this way because
@@ -353,7 +278,6 @@
 			status >>= 1;
 		}
 		irq += IT8172_LPC_IRQ_BASE;
-		//printk("LPC int %d\n", irq);
 	} else
 		return;
 
diff -Nru a/arch/mips/jazz/irq.c b/arch/mips/jazz/irq.c
--- a/arch/mips/jazz/irq.c	2005-03-01 23:38:51 -08:00
+++ b/arch/mips/jazz/irq.c	2005-03-01 23:38:51 -08:00
@@ -17,7 +17,7 @@
 
 extern asmlinkage void jazz_handle_int(void);
 
-static spinlock_t r4030_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(r4030_lock);
 
 static void enable_r4030_irq(unsigned int irq)
 {
diff -Nru a/arch/mips/jazz/jazzdma.c b/arch/mips/jazz/jazzdma.c
--- a/arch/mips/jazz/jazzdma.c	2005-03-01 23:39:16 -08:00
+++ b/arch/mips/jazz/jazzdma.c	2005-03-01 23:39:16 -08:00
@@ -29,7 +29,7 @@
 
 static unsigned long vdma_pagetable_start;
 
-static spinlock_t vdma_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(vdma_lock);
 
 /*
  * Debug stuff
diff -Nru a/arch/mips/jmr3927/rbhma3100/irq.c b/arch/mips/jmr3927/rbhma3100/irq.c
--- a/arch/mips/jmr3927/rbhma3100/irq.c	2005-03-01 23:38:56 -08:00
+++ b/arch/mips/jmr3927/rbhma3100/irq.c	2005-03-01 23:38:56 -08:00
@@ -89,38 +89,10 @@
 	6, 6, 6			/* TMR */
 };
 
-static inline void mask_irq(unsigned int irq_nr)
-{
-	struct tb_irq_space* sp;
-	for (sp = tb_irq_spaces; sp; sp = sp->next) {
-		if (sp->start_irqno <= irq_nr &&
-		    irq_nr < sp->start_irqno + sp->nr_irqs) {
-			if (sp->mask_func)
-				sp->mask_func(irq_nr - sp->start_irqno,
-					      sp->space_id);
-			break;
-		}
-	}
-}
-
-static inline void unmask_irq(unsigned int irq_nr)
-{
-	struct tb_irq_space* sp;
-	for (sp = tb_irq_spaces; sp; sp = sp->next) {
-		if (sp->start_irqno <= irq_nr &&
-		    irq_nr < sp->start_irqno + sp->nr_irqs) {
-			if (sp->unmask_func)
-				sp->unmask_func(irq_nr - sp->start_irqno,
-						sp->space_id);
-			break;
-		}
-	}
-}
-
 static void jmr3927_irq_disable(unsigned int irq_nr);
 static void jmr3927_irq_enable(unsigned int irq_nr);
 
-static spinlock_t jmr3927_irq_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(jmr3927_irq_lock);
 
 static unsigned int jmr3927_irq_startup(unsigned int irq)
 {
@@ -133,9 +105,8 @@
 
 static void jmr3927_irq_ack(unsigned int irq)
 {
-	if (irq == JMR3927_IRQ_IRC_TMR0) {
+	if (irq == JMR3927_IRQ_IRC_TMR0)
 		jmr3927_tmrptr->tisr = 0;       /* ack interrupt */
-	}
 
 	jmr3927_irq_disable(irq);
 }
@@ -147,19 +118,37 @@
 
 static void jmr3927_irq_disable(unsigned int irq_nr)
 {
+	struct tb_irq_space* sp;
 	unsigned long flags;
 
 	spinlock_irqsave(&jmr3927_irq_lock, flags);
-	mask_irq(irq_nr);
+	for (sp = tb_irq_spaces; sp; sp = sp->next) {
+		if (sp->start_irqno <= irq_nr &&
+		    irq_nr < sp->start_irqno + sp->nr_irqs) {
+			if (sp->mask_func)
+				sp->mask_func(irq_nr - sp->start_irqno,
+					      sp->space_id);
+			break;
+		}
+	}
 	spinlock_irqrestore(&jmr3927_irq_lock, flags);
 }
 
 static void jmr3927_irq_enable(unsigned int irq_nr)
 {
+	struct tb_irq_space* sp;
 	unsigned long flags;
 
 	spinlock_irqsave(&jmr3927_irq_lock, flags);
-	unmask_irq(irq_nr);
+	for (sp = tb_irq_spaces; sp; sp = sp->next) {
+		if (sp->start_irqno <= irq_nr &&
+		    irq_nr < sp->start_irqno + sp->nr_irqs) {
+			if (sp->unmask_func)
+				sp->unmask_func(irq_nr - sp->start_irqno,
+						sp->space_id);
+			break;
+		}
+	}
 	spinlock_irqrestore(&jmr3927_irq_lock, flags);
 }
 
diff -Nru a/arch/mips/jmr3927/rbhma3100/setup.c b/arch/mips/jmr3927/rbhma3100/setup.c
--- a/arch/mips/jmr3927/rbhma3100/setup.c	2005-03-01 23:39:16 -08:00
+++ b/arch/mips/jmr3927/rbhma3100/setup.c	2005-03-01 23:39:16 -08:00
@@ -108,7 +108,7 @@
 
 static void jmr3927_machine_restart(char *command)
 {
-	cli();
+	local_irq_disable();
 	puts("Rebooting...");
 	do_reset();
 }
@@ -195,7 +195,6 @@
 
 static void __init jmr3927_setup(void)
 {
-	extern int panic_timeout;
 	char *argptr;
 
 	set_io_port_base(JMR3927_PORT_BASE + JMR3927_PCIIO);
diff -Nru a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
--- a/arch/mips/kernel/Makefile	2005-03-01 23:38:56 -08:00
+++ b/arch/mips/kernel/Makefile	2005-03-01 23:38:56 -08:00
@@ -8,6 +8,9 @@
 		   ptrace.o reset.o semaphore.o setup.o signal.o syscall.o \
 		   time.o traps.o unaligned.o
 
+binfmt_irix-objs	:= irixelf.o irixinv.o irixioctl.o irixsig.o	\
+			   irix5sys.o sysirix.o
+
 ifdef CONFIG_MODULES
 obj-y				+= mips_ksyms.o module.o
 obj-$(CONFIG_MIPS32)		+= module-elf32.o
@@ -35,15 +38,16 @@
 
 obj-$(CONFIG_SMP)		+= smp.o
 
+obj-$(CONFIG_NO_ISA)		+= dma-no-isa.o
 obj-$(CONFIG_I8259)		+= i8259.o
 obj-$(CONFIG_IRQ_CPU)		+= irq_cpu.o
 obj-$(CONFIG_IRQ_CPU_RM7K)	+= irq-rm7000.o
+obj-$(CONFIG_IRQ_CPU_RM9K)	+= irq-rm9000.o
 obj-$(CONFIG_IRQ_MV64340)	+= irq-mv6434x.o
 
 obj-$(CONFIG_MIPS32)		+= scall32-o32.o
 obj-$(CONFIG_MIPS64)		+= scall64-64.o
-obj-$(CONFIG_BINFMT_IRIX)	+= irixelf.o irixioctl.o irixsig.o sysirix.o \
-				   irixinv.o
+obj-$(CONFIG_BINFMT_IRIX)	+= binfmt_irix.o
 obj-$(CONFIG_MIPS32_COMPAT)	+= ioctl32.o linux32.o signal32.o
 obj-$(CONFIG_MIPS32_N32)	+= binfmt_elfn32.o scall64-n32.o signal_n32.o
 obj-$(CONFIG_MIPS32_O32)	+= binfmt_elfo32.o scall64-o32.o ptrace32.o
diff -Nru a/arch/mips/kernel/irix5sys.S b/arch/mips/kernel/irix5sys.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/mips/kernel/irix5sys.S	2005-03-01 23:38:51 -08:00
@@ -0,0 +1,1041 @@
+/*
+ * This file 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.
+ *
+ * 32-bit IRIX5 ABI system call table derived from original file 'irix5sys.h'
+ * created by David S. Miller.
+ *
+ * Copyright (C) 1996 - 2004 David S. Miller <dm@engr.sgi.com>
+ * Copyright (C) 2004 Steven J. Hill <sjhill@realitydiluted.com>
+ */
+#include <asm/asm.h>
+
+	/*
+	 * Key:
+	 *         V == Valid and should work as expected for most cases.
+	 *        HV == Half Valid, some things will work, some likely will not
+	 *        IV == InValid, certainly will not work at all yet
+	 *        ?V == ?'ably Valid, I have not done enough looking into it
+	 *        DC == Don't Care, a rats ass we couldn't give
+	 */
+
+	.macro	irix5syscalltable
+
+	sys	sys_syscall	0	/* 1000  sysindir()	       V*/
+	sys	sys_exit	1	/* 1001  exit()		       V*/
+	sys	sys_fork	0	/* 1002  fork()		       V*/
+	sys	sys_read	3	/* 1003  read()		       V*/
+	sys	sys_write	3	/* 1004  write()	       V*/
+	sys	sys_open	3	/* 1005  open()		       V*/
+	sys	sys_close	1	/* 1006  close()	       V*/
+	sys	irix_unimp	0	/* 1007  (XXX IRIX 4 wait)     V*/
+	sys	sys_creat	2	/* 1008  creat()	       V*/
+	sys	sys_link	2	/* 1009  link()		       V*/
+	sys	sys_unlink	1	/* 1010  unlink()	       V*/
+	sys	irix_exec	0	/* 1011  exec()		       V*/
+	sys	sys_chdir	1	/* 1012  chdir()	       V*/
+	sys	irix_gtime	0	/* 1013  time()		       V*/
+	sys	irix_unimp	0	/* 1014  (XXX IRIX 4 mknod)    V*/
+	sys	sys_chmod	2	/* 1015  chmod()	       V*/
+	sys	sys_chown	3	/* 1016  chown()	       V*/
+	sys	irix_brk	1	/* 1017  break()	       V*/
+	sys	irix_unimp	0	/* 1018  (XXX IRIX 4 stat)     V*/
+	sys	sys_lseek	3	/* 1019  lseek()     XXX64bit HV*/
+	sys	irix_getpid	0	/* 1020  getpid()	       V*/
+	sys	irix_mount	6	/* 1021  mount()	      IV*/
+	sys	sys_umount	1	/* 1022  umount()	       V*/
+	sys	sys_setuid	1	/* 1023  setuid()	       V*/
+	sys	irix_getuid	0	/* 1024  getuid()	       V*/
+	sys	irix_stime	1	/* 1025  stime()	       V*/
+	sys	irix_unimp	4	/* 1026  XXX ptrace()	      IV*/
+	sys	irix_alarm	1	/* 1027  alarm()	       V*/
+	sys	irix_unimp	0	/* 1028  (XXX IRIX 4 fstat)    V*/
+	sys	irix_pause	0	/* 1029  pause()	       V*/
+	sys	sys_utime	2	/* 1030  utime()	       V*/
+	sys	irix_unimp	0	/* 1031  nuthin'	       V*/
+	sys	irix_unimp	0	/* 1032  nobody home man...    V*/
+	sys	sys_access	2	/* 1033  access()	       V*/
+	sys	sys_nice	1	/* 1034  nice()		       V*/
+	sys	irix_statfs	2	/* 1035  statfs()	       V*/
+	sys	sys_sync	0	/* 1036  sync()		       V*/
+	sys	sys_kill	2	/* 1037  kill()		       V*/
+	sys	irix_fstatfs	2	/* 1038  fstatfs()	       V*/
+	sys	irix_setpgrp	1	/* 1039  setpgrp()	       V*/
+	sys	irix_syssgi	0	/* 1040  syssgi()	      HV*/
+	sys	sys_dup		1	/* 1041  dup()		       V*/
+	sys	sys_pipe	0	/* 1042  pipe()		       V*/
+	sys	irix_times	1	/* 1043  times()	       V*/
+	sys	irix_unimp	0	/* 1044  XXX profil()	      IV*/
+	sys	irix_unimp	0	/* 1045  XXX lock()	      IV*/
+	sys	sys_setgid	1	/* 1046  setgid()	       V*/
+	sys	irix_getgid	0	/* 1047  getgid()	       V*/
+	sys	irix_unimp	0	/* 1048  (XXX IRIX 4 ssig)     V*/
+	sys	irix_msgsys	6	/* 1049  sys_msgsys	       V*/
+	sys	sys_sysmips	4	/* 1050  sysmips()	      HV*/
+	sys	irix_unimp	0	/* 1051	 XXX sysacct()	      IV*/
+	sys	irix_shmsys	5	/* 1052  sys_shmsys	       V*/
+	sys	irix_semsys	0	/* 1053  sys_semsys	       V*/
+	sys	irix_ioctl	3	/* 1054  ioctl()	      HV*/
+	sys	irix_uadmin	0	/* 1055  XXX sys_uadmin()     HC*/
+	sys	irix_sysmp	0	/* 1056  sysmp()	      HV*/
+	sys	irix_utssys	4	/* 1057  sys_utssys()	      HV*/
+	sys	irix_unimp	0	/* 1058  nada enchilada	       V*/
+	sys	irix_exece	0	/* 1059  exece()	       V*/
+	sys	sys_umask	1	/* 1060  umask()	       V*/
+	sys	sys_chroot	1	/* 1061  chroot()	       V*/
+	sys	irix_fcntl	3	/* 1062  fcntl()	      ?V*/
+	sys	irix_ulimit	2	/* 1063  ulimit()	      HV*/
+	sys	irix_unimp	0	/* 1064  XXX AFS shit	      DC*/
+	sys	irix_unimp	0	/* 1065  XXX AFS shit	      DC*/
+	sys	irix_unimp	0	/* 1066  XXX AFS shit	      DC*/
+	sys	irix_unimp	0	/* 1067  XXX AFS shit	      DC*/
+	sys	irix_unimp	0	/* 1068  XXX AFS shit	      DC*/
+	sys	irix_unimp	0	/* 1069  XXX AFS shit	      DC*/
+	sys	irix_unimp	0	/* 1070  XXX AFS shit	      DC*/
+	sys	irix_unimp	0	/* 1071  XXX AFS shit	      DC*/
+	sys	irix_unimp	0	/* 1072  XXX AFS shit	      DC*/
+	sys	irix_unimp	0	/* 1073  XXX AFS shit	      DC*/
+	sys	irix_unimp	0	/* 1074  nuttin'	       V*/
+	sys	irix_unimp	0	/* 1075  XXX sys_getrlimit64()IV*/
+	sys	irix_unimp	0	/* 1076  XXX sys_setrlimit64()IV*/
+	sys	sys_nanosleep	2	/* 1077  nanosleep()	       V*/
+	sys	irix_lseek64	5	/* 1078  lseek64()	      ?V*/
+	sys	sys_rmdir	1	/* 1079  rmdir()	       V*/
+	sys	sys_mkdir	2	/* 1080  mkdir()	       V*/
+	sys	sys_getdents	3	/* 1081  getdents()	       V*/
+	sys	irix_sginap	1	/* 1082  sys_sginap()	       V*/
+	sys	irix_sgikopt	3	/* 1083  sys_sgikopt()	      DC*/
+	sys	sys_sysfs	3	/* 1084  sysfs()	      ?V*/
+	sys	irix_unimp	0	/* 1085  XXX sys_getmsg()     DC*/
+	sys	irix_unimp	0	/* 1086  XXX sys_putmsg()     DC*/
+	sys	sys_poll	3	/* 1087  poll()	               V*/
+	sys	irix_sigreturn	0	/* 1088  sigreturn()	      ?V*/
+	sys	sys_accept	3	/* 1089  accept()	       V*/
+	sys	sys_bind	3	/* 1090  bind()		       V*/
+	sys	sys_connect	3	/* 1091  connect()	       V*/
+	sys	irix_gethostid	0	/* 1092  sys_gethostid()      ?V*/
+	sys	sys_getpeername	3	/* 1093  getpeername()	       V*/
+	sys	sys_getsockname	3	/* 1094  getsockname()	       V*/
+	sys	sys_getsockopt	5	/* 1095  getsockopt()	       V*/
+	sys	sys_listen	2	/* 1096  listen()	       V*/
+	sys	sys_recv	4	/* 1097  recv()		       V*/
+	sys	sys_recvfrom	6	/* 1098  recvfrom()	       V*/
+	sys	sys_recvmsg	3	/* 1099  recvmsg()	       V*/
+	sys	sys_select	5	/* 1100  select()	       V*/
+	sys	sys_send	4	/* 1101  send()		       V*/
+	sys	sys_sendmsg	3	/* 1102  sendmsg()	       V*/
+	sys	sys_sendto	6	/* 1103  sendto()	       V*/
+	sys	irix_sethostid	1	/* 1104  sys_sethostid()      ?V*/
+	sys	sys_setsockopt	5	/* 1105  setsockopt()	       V*/
+	sys	sys_shutdown	2	/* 1106  shutdown()	      ?V*/
+	sys	irix_socket	3	/* 1107  socket()	       V*/
+	sys	sys_gethostname	2	/* 1108  sys_gethostname()    ?V*/
+	sys	sys_sethostname	2	/* 1109  sethostname()	      ?V*/
+	sys	irix_getdomainname 2	/* 1110  sys_getdomainname()  ?V*/
+	sys	sys_setdomainname 2	/* 1111  setdomainname()      ?V*/
+	sys	sys_truncate	2	/* 1112  truncate()	       V*/
+	sys	sys_ftruncate	2	/* 1113  ftruncate()	       V*/
+	sys	sys_rename	2	/* 1114  rename()	       V*/
+	sys	sys_symlink	2	/* 1115  symlink()	       V*/
+	sys	sys_readlink	3	/* 1116  readlink()	       V*/
+	sys	irix_unimp	0	/* 1117  XXX IRIX 4 lstat()   DC*/
+	sys	irix_unimp	0	/* 1118  nothin'	       V*/
+	sys	irix_unimp	0	/* 1119  XXX nfs_svc()	      DC*/
+	sys	irix_unimp	0	/* 1120  XXX nfs_getfh()      DC*/
+	sys	irix_unimp	0	/* 1121  XXX async_daemon()   DC*/
+	sys	irix_unimp	0	/* 1122  XXX exportfs()	      DC*/
+	sys	sys_setregid	2	/* 1123  setregid()	       V*/
+	sys	sys_setreuid	2	/* 1124  setreuid()	       V*/
+	sys	sys_getitimer	2	/* 1125  getitimer()	       V*/
+	sys	sys_setitimer	3	/* 1126  setitimer()	       V*/
+	sys	irix_unimp	1	/* 1127  XXX adjtime() 	      IV*/
+	sys	irix_gettimeofday 1	/* 1128  gettimeofday()	       V*/
+	sys	irix_unimp	0	/* 1129  XXX sproc()	      IV*/
+	sys	irix_prctl	0	/* 1130  prctl()	      HV*/
+	sys	irix_unimp	0	/* 1131  XXX procblk()	      IV*/
+	sys	irix_unimp	0	/* 1132  XXX sprocsp()	      IV*/
+	sys	irix_unimp	0	/* 1133  XXX sgigsc()	      IV*/
+	sys	irix_mmap32	6	/* 1134  mmap()	   XXXflags?  ?V*/
+	sys	sys_munmap	2	/* 1135  munmap()	       V*/
+	sys	sys_mprotect	3	/* 1136  mprotect()	       V*/
+	sys	sys_msync	4	/* 1137  msync()	       V*/
+	sys	irix_madvise	3	/* 1138  madvise()	      DC*/
+	sys	irix_pagelock	3	/* 1139  pagelock()	      IV*/
+	sys	irix_getpagesize 0	/* 1140  getpagesize()         V*/
+	sys	irix_quotactl	0	/* 1141  quotactl()	       V*/
+	sys	irix_unimp	0	/* 1142  nobody home man       V*/
+	sys	sys_getpgid	1	/* 1143  BSD getpgrp()	       V*/
+	sys	irix_BSDsetpgrp 2	/* 1143  BSD setpgrp()	       V*/
+	sys	sys_vhangup	0	/* 1144  vhangup()	       V*/
+	sys	sys_fsync	1	/* 1145  fsync()	       V*/
+	sys	sys_fchdir	1	/* 1146  fchdir()	       V*/
+	sys	sys_getrlimit	2	/* 1147  getrlimit()	      ?V*/
+	sys	sys_setrlimit	2	/* 1148  setrlimit()	      ?V*/
+	sys	sys_cacheflush	3	/* 1150  cacheflush()	      HV*/
+	sys	sys_cachectl	3	/* 1151  cachectl()	      HV*/
+	sys	sys_fchown	3	/* 1152  fchown()	      ?V*/
+	sys	sys_fchmod	2	/* 1153  fchmod()	      ?V*/
+	sys	irix_unimp	0	/* 1154  XXX IRIX 4 wait3()    V*/
+	sys	sys_socketpair	4	/* 1155  socketpair()	       V*/
+	sys	irix_systeminfo	3	/* 1156  systeminfo()	      IV*/
+	sys	irix_uname	1	/* 1157  uname()	      IV*/
+	sys	irix_xstat	3	/* 1158  xstat()	       V*/
+	sys	irix_lxstat	3	/* 1159  lxstat()	       V*/
+	sys	irix_fxstat	3	/* 1160  fxstat()	       V*/
+	sys	irix_xmknod	0	/* 1161  xmknod()	      ?V*/
+	sys	irix_sigaction	4	/* 1162  sigaction()	      ?V*/
+	sys	irix_sigpending	1	/* 1163  sigpending()	      ?V*/
+	sys	irix_sigprocmask 3	/* 1164  sigprocmask()	      ?V*/
+	sys	irix_sigsuspend	0	/* 1165  sigsuspend()	      ?V*/
+	sys	irix_sigpoll_sys 3	/* 1166  sigpoll_sys()	      IV*/
+	sys	irix_swapctl	2	/* 1167  swapctl()	      IV*/
+	sys	irix_getcontext	0	/* 1168  getcontext()	      HV*/
+	sys	irix_setcontext	0	/* 1169  setcontext()	      HV*/
+	sys	irix_waitsys	5	/* 1170  waitsys()	      IV*/
+	sys	irix_sigstack	2	/* 1171  sigstack()	      HV*/
+	sys	irix_sigaltstack 2	/* 1172  sigaltstack()	      HV*/
+	sys	irix_sigsendset	2	/* 1173  sigsendset()	      IV*/
+	sys	irix_statvfs	2	/* 1174  statvfs()	       V*/
+	sys	irix_fstatvfs	2	/* 1175  fstatvfs()	       V*/
+	sys	irix_unimp	0	/* 1176  XXX getpmsg()	      DC*/
+	sys	irix_unimp	0	/* 1177  XXX putpmsg()	      DC*/
+	sys	sys_lchown	3	/* 1178  lchown()	       V*/
+	sys	irix_priocntl	0	/* 1179  priocntl()	      DC*/
+	sys	irix_sigqueue	4	/* 1180  sigqueue()	      IV*/
+	sys	sys_readv	3	/* 1181  readv()	       V*/
+	sys	sys_writev	3	/* 1182  writev()	       V*/
+	sys	irix_truncate64 4	/* 1183  truncate64() XX32bit HV*/
+	sys	irix_ftruncate64 4	/* 1184  ftruncate64()XX32bit HV*/
+	sys	irix_mmap64	0	/* 1185  mmap64()     XX32bit HV*/
+	sys	irix_dmi	0	/* 1186  dmi()		      DC*/
+	sys	irix_pread	6	/* 1187  pread()	      IV*/
+	sys	irix_pwrite	6	/* 1188  pwrite()	      IV*/
+	sys	sys_fsync	1	/* 1189  fdatasync()  XXPOSIX HV*/
+	sys	irix_sgifastpath 7	/* 1190  sgifastpath() WHEEE  IV*/
+	sys	irix_unimp	0	/* 1191  XXX attr_get()	      DC*/
+	sys	irix_unimp	0	/* 1192  XXX attr_getf()      DC*/
+	sys	irix_unimp	0	/* 1193  XXX attr_set()	      DC*/
+	sys	irix_unimp	0	/* 1194  XXX attr_setf()      DC*/
+	sys	irix_unimp	0	/* 1195  XXX attr_remove()    DC*/
+	sys	irix_unimp	0	/* 1196  XXX attr_removef()   DC*/
+	sys	irix_unimp	0	/* 1197  XXX attr_list()      DC*/
+	sys	irix_unimp	0	/* 1198  XXX attr_listf()     DC*/
+	sys	irix_unimp	0	/* 1199  XXX attr_multi()     DC*/
+	sys	irix_unimp	0	/* 1200  XXX attr_multif()    DC*/
+	sys	irix_statvfs64	2	/* 1201  statvfs64()	       V*/
+	sys	irix_fstatvfs64	2	/* 1202  fstatvfs64()	       V*/
+	sys	irix_getmountid	2	/* 1203  getmountid()XXXfsids HV*/
+	sys	irix_nsproc	5	/* 1204  nsproc()	      IV*/
+	sys	irix_getdents64 3	/* 1205  getdents64()	      HV*/
+	sys	irix_unimp	0	/* 1206  XXX DFS garbage      DC*/
+	sys	irix_ngetdents	4	/* 1207  ngetdents() XXXeop   HV*/
+	sys	irix_ngetdents64 4	/* 1208  ngetdents64() XXXeop HV*/
+	sys	irix_unimp	0	/* 1209  nothin'	       V*/
+	sys	irix_unimp	0	/* 1210  XXX pidsprocsp()	*/
+	sys	irix_unimp	0	/* 1211  XXX rexec()		*/
+	sys	irix_unimp	0	/* 1212  XXX timer_create()	*/
+	sys	irix_unimp	0	/* 1213  XXX timer_delete()	*/
+	sys	irix_unimp	0	/* 1214  XXX timer_settime()	*/
+	sys	irix_unimp	0	/* 1215  XXX timer_gettime()	*/
+	sys	irix_unimp	0	/* 1216  XXX timer_setoverrun()	*/
+	sys	sys_sched_rr_get_interval 2		/* 1217  sched_rr_get_interval()V*/
+	sys	sys_sched_yield	0	/* 1218  sched_yield()	       V*/
+	sys	sys_sched_getscheduler 1 /* 1219  sched_getscheduler()  V*/
+	sys	sys_sched_setscheduler 3 /* 1220  sched_setscheduler()  V*/
+	sys	sys_sched_getparam 2	/* 1221  sched_getparam()      V*/
+	sys	sys_sched_setparam 2	/* 1222  sched_setparam()      V*/
+	sys	irix_unimp	0	/* 1223  XXX usync_cntl()	*/
+	sys	irix_unimp	0	/* 1224  XXX psema_cntl()	*/
+	sys	irix_unimp	0	/* 1225  XXX restartreturn()	*/
+
+	/* Just to pad things out nicely. */
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+
+	.endm
+
+	/*
+	 * Pre-compute the number of _instruction_ bytes needed to load
+	 * or store the arguments 6-8. Negative values are ignored.
+	 */
+	.macro  sys function, nargs
+	PTR	\function
+	LONG	(\nargs << 2) - (5 << 2)
+	.endm
+
+	.align	4
+EXPORT(sys_call_table_irix5)
+	irix5syscalltable
diff -Nru a/arch/mips/kernel/irix5sys.h b/arch/mips/kernel/irix5sys.h
--- a/arch/mips/kernel/irix5sys.h	2005-03-01 23:38:51 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,1029 +0,0 @@
-/*
- * irix5sys.h: 32-bit IRIX5 ABI system call table.
- *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.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.
- */
-#include <linux/config.h>
-
-/* Keys:
- *         V == Valid and should work as expected for most cases.
- *        HV == Half Valid, some things will work, some likely will not
- *        IV == InValid, certainly will not work at all yet
- *        ?V == ?'ably Valid, I have not done enough looking into it
- *        DC == Don't Care, a rats ass we couldn't give
- */
-
-#ifdef CONFIG_BINFMT_IRIX
-	sys	sys_syscall	0	/* 1000  sysindir()	       V*/
-	sys	sys_exit	1	/* 1001  exit()		       V*/
-	sys	sys_fork	0	/* 1002  fork()		       V*/
-	sys	sys_read	3	/* 1003  read()		       V*/
-	sys	sys_write	3	/* 1004  write()	       V*/
-	sys	sys_open	3	/* 1005  open()		       V*/
-	sys	sys_close	1	/* 1006  close()	       V*/
-	sys	irix_unimp	0	/* 1007  (XXX IRIX 4 wait)     V*/
-	sys	sys_creat	2	/* 1008  creat()	       V*/
-	sys	sys_link	2	/* 1009  link()		       V*/
-	sys	sys_unlink	1	/* 1010  unlink()	       V*/
-	sys	irix_exec	0	/* 1011  exec()		       V*/
-	sys	sys_chdir	1	/* 1012  chdir()	       V*/
-	sys	irix_gtime	0	/* 1013  time()		       V*/
-	sys	irix_unimp	0	/* 1014  (XXX IRIX 4 mknod)    V*/
-	sys	sys_chmod	2	/* 1015  chmod()	       V*/
-	sys	sys_chown	3	/* 1016  chown()	       V*/
-	sys	irix_brk	1	/* 1017  break()	       V*/
-	sys	irix_unimp	0	/* 1018  (XXX IRIX 4 stat)     V*/
-	sys	sys_lseek	3	/* 1019  lseek()     XXX64bit HV*/
-	sys	irix_getpid	0	/* 1020  getpid()	       V*/
-	sys	irix_mount	6	/* 1021  mount()	      IV*/
-	sys	sys_umount	1	/* 1022  umount()	       V*/
-	sys	sys_setuid	1	/* 1023  setuid()	       V*/
-	sys	irix_getuid	0	/* 1024  getuid()	       V*/
-	sys	irix_stime	1	/* 1025  stime()	       V*/
-	sys	irix_unimp	4	/* 1026  XXX ptrace()	      IV*/
-	sys	irix_alarm	1	/* 1027  alarm()	       V*/
-	sys	irix_unimp	0	/* 1028  (XXX IRIX 4 fstat)    V*/
-	sys	irix_pause	0	/* 1029  pause()	       V*/
-	sys	sys_utime	2	/* 1030  utime()	       V*/
-	sys	irix_unimp	0	/* 1031  nuthin'	       V*/
-	sys	irix_unimp	0	/* 1032  nobody home man...    V*/
-	sys	sys_access	2	/* 1033  access()	       V*/
-	sys	sys_nice	1	/* 1034  nice()		       V*/
-	sys	irix_statfs	2	/* 1035  statfs()	       V*/
-	sys	sys_sync	0	/* 1036  sync()		       V*/
-	sys	sys_kill	2	/* 1037  kill()		       V*/
-	sys	irix_fstatfs	2	/* 1038  fstatfs()	       V*/
-	sys	irix_setpgrp	1	/* 1039  setpgrp()	       V*/
-	sys	irix_syssgi	0	/* 1040  syssgi()	      HV*/
-	sys	sys_dup		1	/* 1041  dup()		       V*/
-	sys	sys_pipe	0	/* 1042  pipe()		       V*/
-	sys	irix_times	1	/* 1043  times()	       V*/
-	sys	irix_unimp	0	/* 1044  XXX profil()	      IV*/
-	sys	irix_unimp	0	/* 1045  XXX lock()	      IV*/
-	sys	sys_setgid	1	/* 1046  setgid()	       V*/
-	sys	irix_getgid	0	/* 1047  getgid()	       V*/
-	sys	irix_unimp	0	/* 1048  (XXX IRIX 4 ssig)     V*/
-	sys	irix_msgsys	6	/* 1049  sys_msgsys	       V*/
-	sys	sys_sysmips	4	/* 1050  sysmips()	      HV*/
-	sys	irix_unimp	0	/* 1051	 XXX sysacct()	      IV*/
-	sys	irix_shmsys	5	/* 1052  sys_shmsys	       V*/
-	sys	irix_semsys	0	/* 1053  sys_semsys	       V*/
-	sys	irix_ioctl	3	/* 1054  ioctl()	      HV*/
-	sys	irix_uadmin	0	/* 1055  XXX sys_uadmin()     HC*/
-	sys	irix_sysmp	0	/* 1056  sysmp()	      HV*/
-	sys	irix_utssys	4	/* 1057  sys_utssys()	      HV*/
-	sys	irix_unimp	0	/* 1058  nada enchilada	       V*/
-	sys	irix_exece	0	/* 1059  exece()	       V*/
-	sys	sys_umask	1	/* 1060  umask()	       V*/
-	sys	sys_chroot	1	/* 1061  chroot()	       V*/
-	sys	irix_fcntl	3	/* 1062  fcntl()	      ?V*/
-	sys	irix_ulimit	2	/* 1063  ulimit()	      HV*/
-	sys	irix_unimp	0	/* 1064  XXX AFS shit	      DC*/
-	sys	irix_unimp	0	/* 1065  XXX AFS shit	      DC*/
-	sys	irix_unimp	0	/* 1066  XXX AFS shit	      DC*/
-	sys	irix_unimp	0	/* 1067  XXX AFS shit	      DC*/
-	sys	irix_unimp	0	/* 1068  XXX AFS shit	      DC*/
-	sys	irix_unimp	0	/* 1069  XXX AFS shit	      DC*/
-	sys	irix_unimp	0	/* 1070  XXX AFS shit	      DC*/
-	sys	irix_unimp	0	/* 1071  XXX AFS shit	      DC*/
-	sys	irix_unimp	0	/* 1072  XXX AFS shit	      DC*/
-	sys	irix_unimp	0	/* 1073  XXX AFS shit	      DC*/
-	sys	irix_unimp	0	/* 1074  nuttin'	       V*/
-	sys	irix_unimp	0	/* 1075  XXX sys_getrlimit64()IV*/
-	sys	irix_unimp	0	/* 1076  XXX sys_setrlimit64()IV*/
-	sys	sys_nanosleep	2	/* 1077  nanosleep()	       V*/
-	sys	irix_lseek64	5	/* 1078  lseek64()	      ?V*/
-	sys	sys_rmdir	1	/* 1079  rmdir()	       V*/
-	sys	sys_mkdir	2	/* 1080  mkdir()	       V*/
-	sys	sys_getdents	3	/* 1081  getdents()	       V*/
-	sys	irix_sginap	1	/* 1082  sys_sginap()	       V*/
-	sys	irix_sgikopt	3	/* 1083  sys_sgikopt()	      DC*/
-	sys	sys_sysfs	3	/* 1084  sysfs()	      ?V*/
-	sys	irix_unimp	0	/* 1085  XXX sys_getmsg()     DC*/
-	sys	irix_unimp	0	/* 1086  XXX sys_putmsg()     DC*/
-	sys	sys_poll	3	/* 1087  poll()	               V*/
-	sys	irix_sigreturn	0	/* 1088  sigreturn()	      ?V*/
-	sys	sys_accept	3	/* 1089  accept()	       V*/
-	sys	sys_bind	3	/* 1090  bind()		       V*/
-	sys	sys_connect	3	/* 1091  connect()	       V*/
-	sys	irix_gethostid	0	/* 1092  sys_gethostid()      ?V*/
-	sys	sys_getpeername	3	/* 1093  getpeername()	       V*/
-	sys	sys_getsockname	3	/* 1094  getsockname()	       V*/
-	sys	sys_getsockopt	5	/* 1095  getsockopt()	       V*/
-	sys	sys_listen	2	/* 1096  listen()	       V*/
-	sys	sys_recv	4	/* 1097  recv()		       V*/
-	sys	sys_recvfrom	6	/* 1098  recvfrom()	       V*/
-	sys	sys_recvmsg	3	/* 1099  recvmsg()	       V*/
-	sys	sys_select	5	/* 1100  select()	       V*/
-	sys	sys_send	4	/* 1101  send()		       V*/
-	sys	sys_sendmsg	3	/* 1102  sendmsg()	       V*/
-	sys	sys_sendto	6	/* 1103  sendto()	       V*/
-	sys	irix_sethostid	1	/* 1104  sys_sethostid()      ?V*/
-	sys	sys_setsockopt	5	/* 1105  setsockopt()	       V*/
-	sys	sys_shutdown	2	/* 1106  shutdown()	      ?V*/
-	sys	irix_socket	3	/* 1107  socket()	       V*/
-	sys	sys_gethostname	2	/* 1108  sys_gethostname()    ?V*/
-	sys	sys_sethostname	2	/* 1109  sethostname()	      ?V*/
-	sys	irix_getdomainname 2	/* 1110  sys_getdomainname()  ?V*/
-	sys	sys_setdomainname 2	/* 1111  setdomainname()      ?V*/
-	sys	sys_truncate	2	/* 1112  truncate()	       V*/
-	sys	sys_ftruncate	2	/* 1113  ftruncate()	       V*/
-	sys	sys_rename	2	/* 1114  rename()	       V*/
-	sys	sys_symlink	2	/* 1115  symlink()	       V*/
-	sys	sys_readlink	3	/* 1116  readlink()	       V*/
-	sys	irix_unimp	0	/* 1117  XXX IRIX 4 lstat()   DC*/
-	sys	irix_unimp	0	/* 1118  nothin'	       V*/
-	sys	irix_unimp	0	/* 1119  XXX nfs_svc()	      DC*/
-	sys	irix_unimp	0	/* 1120  XXX nfs_getfh()      DC*/
-	sys	irix_unimp	0	/* 1121  XXX async_daemon()   DC*/
-	sys	irix_unimp	0	/* 1122  XXX exportfs()	      DC*/
-	sys	sys_setregid	2	/* 1123  setregid()	       V*/
-	sys	sys_setreuid	2	/* 1124  setreuid()	       V*/
-	sys	sys_getitimer	2	/* 1125  getitimer()	       V*/
-	sys	sys_setitimer	3	/* 1126  setitimer()	       V*/
-	sys	irix_unimp	1	/* 1127  XXX adjtime() 	      IV*/
-	sys	irix_gettimeofday 1	/* 1128  gettimeofday()	       V*/
-	sys	irix_unimp	0	/* 1129  XXX sproc()	      IV*/
-	sys	irix_prctl	0	/* 1130  prctl()	      HV*/
-	sys	irix_unimp	0	/* 1131  XXX procblk()	      IV*/
-	sys	irix_unimp	0	/* 1132  XXX sprocsp()	      IV*/
-	sys	irix_unimp	0	/* 1133  XXX sgigsc()	      IV*/
-	sys	irix_mmap32	6	/* 1134  mmap()	   XXXflags?  ?V*/
-	sys	sys_munmap	2	/* 1135  munmap()	       V*/
-	sys	sys_mprotect	3	/* 1136  mprotect()	       V*/
-	sys	sys_msync	4	/* 1137  msync()	       V*/
-	sys	irix_madvise	3	/* 1138  madvise()	      DC*/
-	sys	irix_pagelock	3	/* 1139  pagelock()	      IV*/
-	sys	irix_getpagesize 0	/* 1140  getpagesize()         V*/
-	sys	irix_quotactl	0	/* 1141  quotactl()	       V*/
-	sys	irix_unimp	0	/* 1142  nobody home man       V*/
-	sys	sys_getpgid	1	/* 1143  BSD getpgrp()	       V*/
-	sys	irix_BSDsetpgrp 2	/* 1143  BSD setpgrp()	       V*/
-	sys	sys_vhangup	0	/* 1144  vhangup()	       V*/
-	sys	sys_fsync	1	/* 1145  fsync()	       V*/
-	sys	sys_fchdir	1	/* 1146  fchdir()	       V*/
-	sys	sys_getrlimit	2	/* 1147  getrlimit()	      ?V*/
-	sys	sys_setrlimit	2	/* 1148  setrlimit()	      ?V*/
-	sys	sys_cacheflush	3	/* 1150  cacheflush()	      HV*/
-	sys	sys_cachectl	3	/* 1151  cachectl()	      HV*/
-	sys	sys_fchown	3	/* 1152  fchown()	      ?V*/
-	sys	sys_fchmod	2	/* 1153  fchmod()	      ?V*/
-	sys	irix_unimp	0	/* 1154  XXX IRIX 4 wait3()    V*/
-	sys	sys_socketpair	4	/* 1155  socketpair()	       V*/
-	sys	irix_systeminfo	3	/* 1156  systeminfo()	      IV*/
-	sys	irix_uname	1	/* 1157  uname()	      IV*/
-	sys	irix_xstat	3	/* 1158  xstat()	       V*/
-	sys	irix_lxstat	3	/* 1159  lxstat()	       V*/
-	sys	irix_fxstat	3	/* 1160  fxstat()	       V*/
-	sys	irix_xmknod	0	/* 1161  xmknod()	      ?V*/
-	sys	irix_sigaction	4	/* 1162  sigaction()	      ?V*/
-	sys	irix_sigpending	1	/* 1163  sigpending()	      ?V*/
-	sys	irix_sigprocmask 3	/* 1164  sigprocmask()	      ?V*/
-	sys	irix_sigsuspend	0	/* 1165  sigsuspend()	      ?V*/
-	sys	irix_sigpoll_sys 3	/* 1166  sigpoll_sys()	      IV*/
-	sys	irix_swapctl	2	/* 1167  swapctl()	      IV*/
-	sys	irix_getcontext	0	/* 1168  getcontext()	      HV*/
-	sys	irix_setcontext	0	/* 1169  setcontext()	      HV*/
-	sys	irix_waitsys	5	/* 1170  waitsys()	      IV*/
-	sys	irix_sigstack	2	/* 1171  sigstack()	      HV*/
-	sys	irix_sigaltstack 2	/* 1172  sigaltstack()	      HV*/
-	sys	irix_sigsendset	2	/* 1173  sigsendset()	      IV*/
-	sys	irix_statvfs	2	/* 1174  statvfs()	       V*/
-	sys	irix_fstatvfs	2	/* 1175  fstatvfs()	       V*/
-	sys	irix_unimp	0	/* 1176  XXX getpmsg()	      DC*/
-	sys	irix_unimp	0	/* 1177  XXX putpmsg()	      DC*/
-	sys	sys_lchown	3	/* 1178  lchown()	       V*/
-	sys	irix_priocntl	0	/* 1179  priocntl()	      DC*/
-	sys	irix_sigqueue	4	/* 1180  sigqueue()	      IV*/
-	sys	sys_readv	3	/* 1181  readv()	       V*/
-	sys	sys_writev	3	/* 1182  writev()	       V*/
-	sys	irix_truncate64 4	/* 1183  truncate64() XX32bit HV*/
-	sys	irix_ftruncate64 4	/* 1184  ftruncate64()XX32bit HV*/
-	sys	irix_mmap64	0	/* 1185  mmap64()     XX32bit HV*/
-	sys	irix_dmi	0	/* 1186  dmi()		      DC*/
-	sys	irix_pread	6	/* 1187  pread()	      IV*/
-	sys	irix_pwrite	6	/* 1188  pwrite()	      IV*/
-	sys	sys_fsync	1	/* 1189  fdatasync()  XXPOSIX HV*/
-	sys	irix_sgifastpath 7	/* 1190  sgifastpath() WHEEE  IV*/
-	sys	irix_unimp	0	/* 1191  XXX attr_get()	      DC*/
-	sys	irix_unimp	0	/* 1192  XXX attr_getf()      DC*/
-	sys	irix_unimp	0	/* 1193  XXX attr_set()	      DC*/
-	sys	irix_unimp	0	/* 1194  XXX attr_setf()      DC*/
-	sys	irix_unimp	0	/* 1195  XXX attr_remove()    DC*/
-	sys	irix_unimp	0	/* 1196  XXX attr_removef()   DC*/
-	sys	irix_unimp	0	/* 1197  XXX attr_list()      DC*/
-	sys	irix_unimp	0	/* 1198  XXX attr_listf()     DC*/
-	sys	irix_unimp	0	/* 1199  XXX attr_multi()     DC*/
-	sys	irix_unimp	0	/* 1200  XXX attr_multif()    DC*/
-	sys	irix_statvfs64	2	/* 1201  statvfs64()	       V*/
-	sys	irix_fstatvfs64	2	/* 1202  fstatvfs64()	       V*/
-	sys	irix_getmountid	2	/* 1203  getmountid()XXXfsids HV*/
-	sys	irix_nsproc	5	/* 1204  nsproc()	      IV*/
-	sys	irix_getdents64 3	/* 1205  getdents64()	      HV*/
-	sys	irix_unimp	0	/* 1206  XXX DFS garbage      DC*/
-	sys	irix_ngetdents	4	/* 1207  ngetdents() XXXeop   HV*/
-	sys	irix_ngetdents64 4	/* 1208  ngetdents64() XXXeop HV*/
-	sys	irix_unimp	0	/* 1209  nothin'	       V*/
-	sys	irix_unimp	0	/* 1210  XXX pidsprocsp()	*/
-	sys	irix_unimp	0	/* 1211  XXX rexec()		*/
-	sys	irix_unimp	0	/* 1212  XXX timer_create()	*/
-	sys	irix_unimp	0	/* 1213  XXX timer_delete()	*/
-	sys	irix_unimp	0	/* 1214  XXX timer_settime()	*/
-	sys	irix_unimp	0	/* 1215  XXX timer_gettime()	*/
-	sys	irix_unimp	0	/* 1216  XXX timer_setoverrun()	*/
-	sys	sys_sched_rr_get_interval 2		/* 1217  sched_rr_get_interval()V*/
-	sys	sys_sched_yield	0	/* 1218  sched_yield()	       V*/
-	sys	sys_sched_getscheduler 1 /* 1219  sched_getscheduler()  V*/
-	sys	sys_sched_setscheduler 3 /* 1220  sched_setscheduler()  V*/
-	sys	sys_sched_getparam 2	/* 1221  sched_getparam()      V*/
-	sys	sys_sched_setparam 2	/* 1222  sched_setparam()      V*/
-	sys	irix_unimp	0	/* 1223  XXX usync_cntl()	*/
-	sys	irix_unimp	0	/* 1224  XXX psema_cntl()	*/
-	sys	irix_unimp	0	/* 1225  XXX restartreturn()	*/
-
-/* Just to pad things out nicely. */
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-	sys	irix_unimp	0
-#else
-	mille	sys_ni_syscall	0
-#endif
-
-/* YEEEEEEEEEEEEEEEEEE!!!! */
diff -Nru a/arch/mips/kernel/irixelf.c b/arch/mips/kernel/irixelf.c
--- a/arch/mips/kernel/irixelf.c	2005-03-01 23:39:18 -08:00
+++ b/arch/mips/kernel/irixelf.c	2005-03-01 23:39:18 -08:00
@@ -1,15 +1,16 @@
 /*
- * irixelf.c: Code to load IRIX ELF executables which conform to
- *            the MIPS ABI.
+ * This file 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) 1996 David S. Miller (dm@engr.sgi.com)
+ * irixelf.c: Code to load IRIX ELF executables conforming to the MIPS ABI.
+ *            Based off of work by Eric Youngdale.
  *
- * Based upon work which is:
- * Copyright 1993, 1994: Eric Youngdale (ericy@cais.com).
+ * Copyright (C) 1993 - 1994 Eric Youngdale <ericy@cais.com>
+ * Copyright (C) 1996 - 2004 David S. Miller <dm@engr.sgi.com>
+ * Copyright (C) 2004 Steven J. Hill <sjhill@realitydiluted.com>
  */
-
 #include <linux/module.h>
-
 #include <linux/fs.h>
 #include <linux/stat.h>
 #include <linux/sched.h>
@@ -127,7 +128,9 @@
 	end = PAGE_ALIGN(end);
 	if (end <= start)
 		return;
+	down_write(&current->mm->mmap_sem);
 	do_brk(start, end - start);
+	up_write(&current->mm->mmap_sem);
 }
 
 
@@ -209,13 +212,13 @@
 		__put_user((unsigned long)p,argv++);
 		p += strlen_user(p);
 	}
-	__put_user(NULL, argv);
+	__put_user((unsigned long) NULL, argv);
 	current->mm->arg_end = current->mm->env_start = (unsigned long) p;
 	while (envc-->0) {
 		__put_user((unsigned long)p,envp++);
 		p += strlen_user(p);
 	}
-	__put_user(NULL, envp);
+	__put_user((unsigned long) NULL, envp);
 	current->mm->env_end = (unsigned long) p;
 	return sp;
 }
@@ -375,7 +378,9 @@
 
 	/* Map the last of the bss segment */
 	if (last_bss > len) {
+		down_write(&current->mm->mmap_sem);
 		do_brk(len, (last_bss - len));
+		up_write(&current->mm->mmap_sem);
 	}
 	kfree(elf_phdata);
 
@@ -562,7 +567,9 @@
 	unsigned long v;
 	struct prda *pp;
 
+	down_write(&current->mm->mmap_sem);
 	v =  do_brk (PRDA_ADDRESS, PAGE_SIZE);
+	up_write(&current->mm->mmap_sem);
 
 	if (v < 0)
 		return;
@@ -616,6 +623,7 @@
 	}
 
 	retval = kernel_read(bprm->file, elf_ex.e_phoff, (char *)elf_phdata, size);
+
 	if (retval < 0)
 		goto out_free_ph;
 
@@ -685,7 +693,7 @@
 	 * change some of these later.
 	 */
 	current->mm->rss = 0;
-	setup_arg_pages(bprm, EXSTACK_DEFAULT);
+	setup_arg_pages(bprm, STACK_TOP, EXSTACK_DEFAULT);
 	current->mm->start_stack = bprm->p;
 
 	/* At this point, we assume that the image should be loaded at
@@ -852,8 +860,11 @@
 
 	len = (elf_phdata->p_filesz + elf_phdata->p_vaddr+ 0xfff) & 0xfffff000;
 	bss = elf_phdata->p_memsz + elf_phdata->p_vaddr;
-	if (bss > len)
+	if (bss > len) {
+	  down_write(&current->mm->mmap_sem);
 	  do_brk(len, bss-len);
+	  up_write(&current->mm->mmap_sem);
+	}
 	kfree(elf_phdata);
 	return 0;
 }
@@ -925,7 +936,8 @@
 	}
 
 #ifdef DEBUG_ELF
-	printk("irix_mapelf: Success, returning %08lx\n", user_phdrp->p_vaddr);
+	printk("irix_mapelf: Success, returning %08lx\n",
+		(unsigned long) user_phdrp->p_vaddr);
 #endif
 	fput(filp);
 	return user_phdrp->p_vaddr;
@@ -1288,6 +1300,20 @@
 
 static int __init init_irix_binfmt(void)
 {
+	int init_inventory(void);
+	extern asmlinkage unsigned long sys_call_table;
+	extern asmlinkage unsigned long sys_call_table_irix5;
+
+	init_inventory();
+
+	/*
+	 * Copy the IRIX5 syscall table (8000 bytes) into the main syscall
+	 * table. The IRIX5 calls are located by an offset of 8000 bytes
+	 * from the beginning of the main table.
+	 */
+	memcpy((void *) ((unsigned long) &sys_call_table + 8000),
+		&sys_call_table_irix5, 8000);
+
 	return register_binfmt(&irix_format);
 }
 
diff -Nru a/arch/mips/kernel/irixinv.c b/arch/mips/kernel/irixinv.c
--- a/arch/mips/kernel/irixinv.c	2005-03-01 23:38:52 -08:00
+++ b/arch/mips/kernel/irixinv.c	2005-03-01 23:38:52 -08:00
@@ -6,10 +6,8 @@
  * Miguel de Icaza, 1997.
  */
 #include <linux/mm.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <asm/uaccess.h>
 #include <asm/inventory.h>
+#include <asm/uaccess.h>
 
 #define MAX_INVENTORY 50
 int inventory_items = 0;
@@ -49,7 +47,7 @@
 	return inventory_items * sizeof (inventory_t);
 }
 
-static int __init init_inventory(void)
+int __init init_inventory(void)
 {
 	/*
 	 * gross hack while we put the right bits all over the kernel
@@ -77,5 +75,3 @@
 
 	return 0;
 }
-
-module_init(init_inventory);
diff -Nru a/arch/mips/kernel/irixsig.c b/arch/mips/kernel/irixsig.c
--- a/arch/mips/kernel/irixsig.c	2005-03-01 23:39:09 -08:00
+++ b/arch/mips/kernel/irixsig.c	2005-03-01 23:39:09 -08:00
@@ -13,7 +13,6 @@
 #include <linux/smp_lock.h>
 #include <linux/time.h>
 #include <linux/ptrace.h>
-#include <linux/suspend.h>
 
 #include <asm/ptrace.h>
 #include <asm/uaccess.h>
@@ -100,7 +99,7 @@
 	__put_user((u64) regs->hi, &ctx->hi);
 	__put_user((u64) regs->lo, &ctx->lo);
 	__put_user((u64) regs->cp0_epc, &ctx->pc);
-	__put_user(current->used_math, &ctx->usedfp);
+	__put_user(!!used_math(), &ctx->usedfp);
 	__put_user((u64) regs->cp0_cause, &ctx->cp0_cause);
 	__put_user((u64) regs->cp0_badvaddr, &ctx->cp0_badvaddr);
 
@@ -179,10 +178,8 @@
 	if (!user_mode(regs))
 		return 1;
 
-	if (current->flags & PF_FREEZE) {
-		refrigerator(0);
+	if (try_to_freeze(0))
 		goto no_signal;
-	}
 
 	if (!oldset)
 		oldset = &current->blocked;
@@ -583,7 +580,7 @@
 		retval = -EINVAL;
 		goto out;
 	}
-	add_wait_queue(&current->wait_chldexit, &wait);
+	add_wait_queue(&current->signal->wait_chldexit, &wait);
 repeat:
 	flag = 0;
 	current->state = TASK_INTERRUPTIBLE;
@@ -627,7 +624,7 @@
 			}
 			goto end_waitsys;
 
-		case TASK_ZOMBIE:
+		case EXIT_ZOMBIE:
 			current->signal->cutime += p->utime + p->signal->cutime;
 			current->signal->cstime += p->stime + p->signal->cstime;
 			if (ru != NULL)
@@ -672,7 +669,7 @@
 	retval = -ECHILD;
 end_waitsys:
 	current->state = TASK_RUNNING;
-	remove_wait_queue(&current->wait_chldexit, &wait);
+	remove_wait_queue(&current->signal->wait_chldexit, &wait);
 
 out:
 	return retval;
@@ -728,7 +725,7 @@
 	__put_user(regs->cp0_epc, &ctx->regs[35]);
 
 	flags = 0x0f;
-	if(!current->used_math) {
+	if(!used_math()) {
 		flags &= ~(0x08);
 	} else {
 		/* XXX wheee... */
diff -Nru a/arch/mips/kernel/irq-rm9000.c b/arch/mips/kernel/irq-rm9000.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/mips/kernel/irq-rm9000.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2003 Ralf Baechle
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * Handler for RM9000 extended interrupts.  These are a non-standard
+ * feature so we handle them separately from standard interrupts.
+ */
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include <asm/irq_cpu.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+
+static int irq_base;
+
+static inline void unmask_rm9k_irq(unsigned int irq)
+{
+	set_c0_intcontrol(0x1000 << (irq - irq_base));
+}
+
+static inline void mask_rm9k_irq(unsigned int irq)
+{
+	clear_c0_intcontrol(0x1000 << (irq - irq_base));
+}
+
+static inline void rm9k_cpu_irq_enable(unsigned int irq)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	unmask_rm9k_irq(irq);
+	local_irq_restore(flags);
+}
+
+static void rm9k_cpu_irq_disable(unsigned int irq)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	mask_rm9k_irq(irq);
+	local_irq_restore(flags);
+}
+
+static unsigned int rm9k_cpu_irq_startup(unsigned int irq)
+{
+	rm9k_cpu_irq_enable(irq);
+
+	return 0;
+}
+
+#define	rm9k_cpu_irq_shutdown	rm9k_cpu_irq_disable
+
+/*
+ * Performance counter interrupts are global on all processors.
+ */
+static void local_rm9k_perfcounter_irq_startup(void *args)
+{
+	unsigned int irq = (unsigned int) args;
+
+	rm9k_cpu_irq_enable(irq);
+}
+
+static unsigned int rm9k_perfcounter_irq_startup(unsigned int irq)
+{
+	on_each_cpu(local_rm9k_perfcounter_irq_startup, (void *) irq, 0, 1);
+
+	return 0;
+}
+
+static void local_rm9k_perfcounter_irq_shutdown(void *args)
+{
+	unsigned int irq = (unsigned int) args;
+	unsigned long flags;
+
+	local_irq_save(flags);
+	mask_rm9k_irq(irq);
+	local_irq_restore(flags);
+}
+
+static void rm9k_perfcounter_irq_shutdown(unsigned int irq)
+{
+	on_each_cpu(local_rm9k_perfcounter_irq_shutdown, (void *) irq, 0, 1);
+}
+
+
+/*
+ * While we ack the interrupt interrupts are disabled and thus we don't need
+ * to deal with concurrency issues.  Same for rm9k_cpu_irq_end.
+ */
+static void rm9k_cpu_irq_ack(unsigned int irq)
+{
+	mask_rm9k_irq(irq);
+}
+
+static void rm9k_cpu_irq_end(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		unmask_rm9k_irq(irq);
+}
+
+static hw_irq_controller rm9k_irq_controller = {
+	"RM9000",
+	rm9k_cpu_irq_startup,
+	rm9k_cpu_irq_shutdown,
+	rm9k_cpu_irq_enable,
+	rm9k_cpu_irq_disable,
+	rm9k_cpu_irq_ack,
+	rm9k_cpu_irq_end,
+};
+
+static hw_irq_controller rm9k_perfcounter_irq = {
+	"RM9000",
+	rm9k_perfcounter_irq_startup,
+	rm9k_perfcounter_irq_shutdown,
+	rm9k_cpu_irq_enable,
+	rm9k_cpu_irq_disable,
+	rm9k_cpu_irq_ack,
+	rm9k_cpu_irq_end,
+};
+
+unsigned int rm9000_perfcount_irq;
+
+EXPORT_SYMBOL(rm9000_perfcount_irq);
+
+void __init rm9k_cpu_irq_init(int base)
+{
+	int i;
+
+	clear_c0_intcontrol(0x0000f000);		/* Mask all */
+
+	for (i = base; i < base + 4; i++) {
+		irq_desc[i].status = IRQ_DISABLED;
+		irq_desc[i].action = NULL;
+		irq_desc[i].depth = 1;
+		irq_desc[i].handler = &rm9k_irq_controller;
+	}
+
+	rm9000_perfcount_irq = base + 1;
+	irq_desc[rm9000_perfcount_irq].handler = &rm9k_perfcounter_irq;
+
+	irq_base = base;
+}
diff -Nru a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c
--- a/arch/mips/kernel/irq.c	2005-03-01 23:38:52 -08:00
+++ b/arch/mips/kernel/irq.c	2005-03-01 23:38:52 -08:00
@@ -125,7 +125,7 @@
 		irq_desc[i].action  = NULL;
 		irq_desc[i].depth   = 1;
 		irq_desc[i].handler = &no_irq_type;
-		irq_desc[i].lock = SPIN_LOCK_UNLOCKED;
+		spin_lock_init(&irq_desc[i].lock);
 	}
 
 	arch_init_irq();
diff -Nru a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c
--- a/arch/mips/kernel/linux32.c	2005-03-01 23:39:07 -08:00
+++ b/arch/mips/kernel/linux32.c	2005-03-01 23:39:07 -08:00
@@ -99,7 +99,7 @@
 }
 
 asmlinkage unsigned long
-sys32_mmap2(unsigned long addr, size_t len, unsigned long prot,
+sys32_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
          unsigned long flags, unsigned long fd, unsigned long pgoff)
 {
 	struct file * file = NULL;
@@ -468,8 +468,7 @@
 	if (!(file->f_mode & FMODE_READ))
 		goto out;
 	pos = merge_64(a4, a5);
-	ret = locks_verify_area(FLOCK_VERIFY_READ, file->f_dentry->d_inode,
-				file, pos, count);
+	ret = rw_verify_area(READ, file, &pos, count);
 	if (ret)
 		goto out;
 	ret = -EINVAL;
@@ -504,8 +503,7 @@
 	if (!(file->f_mode & FMODE_WRITE))
 		goto out;
 	pos = merge_64(a4, a5);
-	ret = locks_verify_area(FLOCK_VERIFY_WRITE, file->f_dentry->d_inode,
-				file, pos, count);
+	ret = rw_verify_area(WRITE, file, &pos, count);
 	if (ret)
 		goto out;
 	ret = -EINVAL;
@@ -1117,7 +1115,7 @@
 		err = sys_shmdt ((char *)A(ptr));
 		break;
 	case SHMGET:
-		err = sys_shmget (first, second, third);
+		err = sys_shmget (first, (unsigned)second, third);
 		break;
 	case SHMCTL:
 		err = do_sys32_shmctl (first, second, (void *)AA(ptr));
@@ -1192,13 +1190,6 @@
 		copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused));
 	}
 	return error;
-}
-
-#else /* CONFIG_SYSCTL */
-
-asmlinkage long sys32_sysctl(struct sysctl_args32 *args)
-{
-	return -ENOSYS;
 }
 
 #endif /* CONFIG_SYSCTL */
diff -Nru a/arch/mips/kernel/mips_ksyms.c b/arch/mips/kernel/mips_ksyms.c
--- a/arch/mips/kernel/mips_ksyms.c	2005-03-01 23:38:53 -08:00
+++ b/arch/mips/kernel/mips_ksyms.c	2005-03-01 23:38:53 -08:00
@@ -5,9 +5,11 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1996, 97, 98, 99, 2000, 01, 03 by Ralf Baechle
+ * Copyright (C) 1996, 97, 98, 99, 2000, 01, 03, 04, 05 by Ralf Baechle
  * Copyright (C) 1999, 2000, 01 Silicon Graphics, Inc.
  */
+#include <linux/config.h>
+#include <linux/interrupt.h>
 #include <linux/module.h>
 #include <asm/checksum.h>
 #include <asm/pgtable.h>
@@ -60,3 +62,6 @@
 EXPORT_SYMBOL(csum_partial);
 
 EXPORT_SYMBOL(invalid_pte_table);
+#ifdef CONFIG_GENERIC_IRQ_PROBE
+EXPORT_SYMBOL(probe_irq_mask);
+#endif
diff -Nru a/arch/mips/kernel/module.c b/arch/mips/kernel/module.c
--- a/arch/mips/kernel/module.c	2005-03-01 23:38:54 -08:00
+++ b/arch/mips/kernel/module.c	2005-03-01 23:38:54 -08:00
@@ -2,7 +2,7 @@
 #include <linux/spinlock.h>
 
 static LIST_HEAD(dbe_list);
-static spinlock_t dbe_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(dbe_lock);
 
 /* Given an address, look for it in the module exception tables. */
 const struct exception_table_entry *search_module_dbetables(unsigned long addr)
diff -Nru a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
--- a/arch/mips/kernel/process.c	2005-03-01 23:38:56 -08:00
+++ b/arch/mips/kernel/process.c	2005-03-01 23:38:56 -08:00
@@ -76,7 +76,7 @@
 #endif
 	status |= KU_USER;
 	regs->cp0_status = status;
-	current->used_math = 0;
+	clear_used_math();
 	lose_fpu();
 	regs->cp0_epc = pc;
 	regs->regs[29] = sp;
@@ -113,19 +113,15 @@
 	*childregs = *regs;
 	childregs->regs[7] = 0;	/* Clear error flag */
 
-#ifdef CONFIG_BINFMT_IRIX
+#if defined(CONFIG_BINFMT_IRIX)
 	if (current->personality != PER_LINUX) {
 		/* Under IRIX things are a little different. */
-		childregs->regs[2] = 0;
 		childregs->regs[3] = 1;
-		regs->regs[2] = p->pid;
 		regs->regs[3] = 0;
-	} else
-#endif
-	{
-		childregs->regs[2] = 0;	/* Child gets zero as return value */
-		regs->regs[2] = p->pid;
 	}
+#endif
+	childregs->regs[2] = 0;	/* Child gets zero as return value */
+	regs->regs[2] = p->pid;
 
 	if (childregs->cp0_status & ST0_CU0) {
 		childregs->regs[28] = (unsigned long) ti;
@@ -153,6 +149,36 @@
 int dump_fpu(struct pt_regs *regs, elf_fpregset_t *r)
 {
 	memcpy(r, &current->thread.fpu, sizeof(current->thread.fpu));
+
+	return 1;
+}
+
+void dump_regs(elf_greg_t *gp, struct pt_regs *regs)
+{
+	int i;
+
+	for (i = 0; i < EF_R0; i++)
+		gp[i] = 0;
+	gp[EF_R0] = 0;
+	for (i = 1; i <= 31; i++)
+		gp[EF_R0 + i] = regs->regs[i];
+	gp[EF_R26] = 0;
+	gp[EF_R27] = 0;
+	gp[EF_LO] = regs->lo;
+	gp[EF_HI] = regs->hi;
+	gp[EF_CP0_EPC] = regs->cp0_epc;
+	gp[EF_CP0_BADVADDR] = regs->cp0_badvaddr;
+	gp[EF_CP0_STATUS] = regs->cp0_status;
+	gp[EF_CP0_CAUSE] = regs->cp0_cause;
+#ifdef EF_UNUSED0
+	gp[EF_UNUSED0] = 0;
+#endif
+}
+
+int dump_task_fpu (struct task_struct *t, elf_fpregset_t *fpr)
+{
+	memcpy(fpr, &t->thread.fpu, sizeof(current->thread.fpu));
+
 	return 1;
 }
 
@@ -263,7 +289,6 @@
  */
 unsigned long thread_saved_pc(struct task_struct *tsk)
 {
-	extern void ret_from_fork(void);
 	struct thread_struct *t = &tsk->thread;
 
 	/* New born processes are a special case */
diff -Nru a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
--- a/arch/mips/kernel/ptrace.c	2005-03-01 23:39:18 -08:00
+++ b/arch/mips/kernel/ptrace.c	2005-03-01 23:39:18 -08:00
@@ -119,7 +119,7 @@
 			tmp = regs->regs[addr];
 			break;
 		case FPR_BASE ... FPR_BASE + 31:
-			if (child->used_math) {
+			if (tsk_used_math(child)) {
 				fpureg_t *fregs = get_fpu_regs(child);
 
 #ifdef CONFIG_MIPS32
@@ -205,7 +205,7 @@
 		case FPR_BASE ... FPR_BASE + 31: {
 			fpureg_t *fregs = get_fpu_regs(child);
 
-			if (!child->used_math) {
+			if (!tsk_used_math(child)) {
 				/* FP not yet used  */
 				memset(&child->thread.fpu.hard, ~0,
 				       sizeof(child->thread.fpu.hard));
diff -Nru a/arch/mips/kernel/ptrace32.c b/arch/mips/kernel/ptrace32.c
--- a/arch/mips/kernel/ptrace32.c	2005-03-01 23:38:56 -08:00
+++ b/arch/mips/kernel/ptrace32.c	2005-03-01 23:38:56 -08:00
@@ -112,7 +112,7 @@
 			tmp = regs->regs[addr];
 			break;
 		case FPR_BASE ... FPR_BASE + 31:
-			if (child->used_math) {
+			if (tsk_used_math(child)) {
 				fpureg_t *fregs = get_fpu_regs(child);
 
 				/*
@@ -193,7 +193,7 @@
 		case FPR_BASE ... FPR_BASE + 31: {
 			fpureg_t *fregs = get_fpu_regs(child);
 
-			if (!child->used_math) {
+			if (!tsk_used_math(child)) {
 				/* FP not yet used  */
 				memset(&child->thread.fpu.hard, ~0,
 				       sizeof(child->thread.fpu.hard));
diff -Nru a/arch/mips/kernel/reg.c b/arch/mips/kernel/reg.c
--- a/arch/mips/kernel/reg.c	2005-03-01 23:39:09 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,69 +0,0 @@
-/*
- * offset.c: Calculate pt_regs and task_struct indices.
- *
- * Copyright (C) 1996 David S. Miller
- * Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 Ralf Baechle
- */
-#include <linux/types.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-
-#include <asm/ptrace.h>
-#include <asm/processor.h>
-
-#define text(t) __asm__("\n@@@" t)
-#define _offset(type, member) ((unsigned long) &(((type *)NULL)->member))
-#define index(string, ptr, member) \
-	__asm__("\n@@@" string "%0" : : "i" (_offset(ptr, member)/sizeof(long)))
-#define size(string, size) \
-	__asm__("\n@@@" string "%0" : : "i" (sizeof(size)))
-#define linefeed text("")
-
-void output_ptreg_defines(void)
-{
-	text("/* MIPS pt_regs indices. */");
-	index("#define EF_R0     ", struct pt_regs, regs[0]);
-	index("#define EF_R1     ", struct pt_regs, regs[1]);
-	index("#define EF_R2     ", struct pt_regs, regs[2]);
-	index("#define EF_R3     ", struct pt_regs, regs[3]);
-	index("#define EF_R4     ", struct pt_regs, regs[4]);
-	index("#define EF_R5     ", struct pt_regs, regs[5]);
-	index("#define EF_R6     ", struct pt_regs, regs[6]);
-	index("#define EF_R7     ", struct pt_regs, regs[7]);
-	index("#define EF_R8     ", struct pt_regs, regs[8]);
-	index("#define EF_R9     ", struct pt_regs, regs[9]);
-	index("#define EF_R10    ", struct pt_regs, regs[10]);
-	index("#define EF_R11    ", struct pt_regs, regs[11]);
-	index("#define EF_R12    ", struct pt_regs, regs[12]);
-	index("#define EF_R13    ", struct pt_regs, regs[13]);
-	index("#define EF_R14    ", struct pt_regs, regs[14]);
-	index("#define EF_R15    ", struct pt_regs, regs[15]);
-	index("#define EF_R16    ", struct pt_regs, regs[16]);
-	index("#define EF_R17    ", struct pt_regs, regs[17]);
-	index("#define EF_R18    ", struct pt_regs, regs[18]);
-	index("#define EF_R19    ", struct pt_regs, regs[19]);
-	index("#define EF_R20    ", struct pt_regs, regs[20]);
-	index("#define EF_R21    ", struct pt_regs, regs[21]);
-	index("#define EF_R22    ", struct pt_regs, regs[22]);
-	index("#define EF_R23    ", struct pt_regs, regs[23]);
-	index("#define EF_R24    ", struct pt_regs, regs[24]);
-	index("#define EF_R25    ", struct pt_regs, regs[25]);
-	index("#define EF_R26    ", struct pt_regs, regs[26]);
-	index("#define EF_R27    ", struct pt_regs, regs[27]);
-	index("#define EF_R28    ", struct pt_regs, regs[28]);
-	index("#define EF_R29    ", struct pt_regs, regs[29]);
-	index("#define EF_R30    ", struct pt_regs, regs[30]);
-	index("#define EF_R31    ", struct pt_regs, regs[31]);
-	linefeed;
-	index("#define EF_LO     ", struct pt_regs, lo);
-	index("#define EF_HI     ", struct pt_regs, hi);
-	linefeed;
-	index("#define EF_EPC    ", struct pt_regs, cp0_epc);
-	index("#define EF_BVADDR ", struct pt_regs, cp0_badvaddr);
-	index("#define EF_STATUS ", struct pt_regs, cp0_status);
-	index("#define EF_CAUSE  ", struct pt_regs, cp0_cause);
-	linefeed;
-	size("#define EF_SIZE   ", struct pt_regs);
-	linefeed;
-}
diff -Nru a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S
--- a/arch/mips/kernel/scall32-o32.S	2005-03-01 23:38:52 -08:00
+++ b/arch/mips/kernel/scall32-o32.S	2005-03-01 23:38:52 -08:00
@@ -5,6 +5,7 @@
  *
  * Copyright (C) 1995, 96, 97, 98, 99, 2000, 01, 02 by Ralf Baechle
  * Copyright (C) 2001 MIPS Technologies, Inc.
+ * Copyright (C) 2004 Thiemo Seufer
  */
 #include <linux/config.h>
 #include <linux/errno.h>
@@ -32,26 +33,30 @@
 
 	lw	t1, PT_EPC(sp)		# skip syscall on return
 
+#if defined(CONFIG_BINFMT_IRIX)
 	sltiu	t0, v0, MAX_SYSCALL_NO + 1 # check syscall number
+#else
+	subu	v0, v0, __NR_O32_Linux	# check syscall number
+	sltiu	t0, v0, __NR_O32_Linux_syscalls + 1
+#endif
 	addiu	t1, 4			# skip to next instruction
 	sw	t1, PT_EPC(sp)
 	beqz	t0, illegal_syscall
 
-	/* XXX Put both in one cacheline, should save a bit. */
-	sll	t0, v0, 2
-	lw	t2, sys_call_table(t0)	# syscall routine
-	lbu	t3, sys_narg_table(v0)	# number of arguments
-	beqz	t2, illegal_syscall;
+	sll	t0, v0, 3
+	la	t1, sys_call_table
+	addu	t1, t0
+	lw	t2, (t1)		# syscall routine
+	lw	t3, 4(t1)		# >= 0 if we need stack arguments
+	beqz	t2, illegal_syscall
 
-	subu	t0, t3, 5		# 5 or more arguments?
 	sw	a3, PT_R26(sp)		# save a3 for syscall restarting
-	bgez	t0, stackargs
+	bgez	t3, stackargs
 
 stack_done:
-	sw	a3, PT_R26(sp)          # save for syscall restart
-	LONG_L	t0, TI_FLAGS($28)	# syscall tracing enabled?
+	lw	t0, TI_FLAGS($28)	# syscall tracing enabled?
 	li	t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
-	and	t0, t1, t0
+	and	t0, t1
 	bnez	t0, syscall_trace_entry	# -> yes
 
 	jalr	t2			# Do The Real Thing (TM)
@@ -70,9 +75,9 @@
 	local_irq_disable		# make sure need_resched and
 					# signals dont change between
 					# sampling and return
-	LONG_L	a2, TI_FLAGS($28)	# current->work
+	lw	a2, TI_FLAGS($28)	# current->work
 	li	t0, _TIF_ALLWORK_MASK
-	and	t0, a2, t0
+	and	t0, a2
 	bnez	t0, o32_syscall_exit_work
 
 	j	restore_partial
@@ -116,49 +121,48 @@
 	 */
 stackargs:
 	lw	t0, PT_R29(sp)		# get old user stack pointer
-	subu	t3, 4
-	sll	t1, t3, 2		# stack valid?
 
-	addu	t1, t0			# end address
-	or	t0, t1
-	bltz	t0, bad_stack		# -> sp is bad
-
-	lw	t0, PT_R29(sp)		# get old user stack pointer
-	PTR_LA	t1, 4f			# copy 1 to 3 arguments
-	sll	t3, t3, 4
-	subu	t1, t3
-	jr	t1
-
-	/* Ok, copy the args from the luser stack to the kernel stack */
 	/*
-	 * I know Ralf doesn't like nops but this avoids code
-	 * duplication for R3000 targets (and this is the
-	 * only place where ".set reorder" doesn't help).
-	 * Harald.
+	 * We intentionally keep the kernel stack a little below the top of
+	 * userspace so we don't have to do a slower byte accurate check here.
+	 */
+	lw	t5, TI_ADDR_LIMIT($28)
+	addu	t4, t0, 32
+	and	t5, t4
+	bltz	t5, bad_stack		# -> sp is bad
+
+	/* Ok, copy the args from the luser stack to the kernel stack.
+	 * t3 is the precomputed number of instruction bytes needed to
+	 * load or store arguments 6-8.
 	 */
+
+	la	t1, 5f			# load up to 3 arguments
+	subu	t1, t3
+1:	lw	t5, 16(t0)		# argument #5 from usp
 	.set    push
 	.set    noreorder
 	.set	nomacro
-1:	lw	t1, 24(t0)		# argument #7 from usp
-	nop
-	sw	t1, 24(sp)
-	nop
-2:	lw	t1, 20(t0)		# argument #5 from usp
-	nop
-	sw	t1, 20(sp)
-	nop
-3:	lw	t1, 16(t0)		# argument #5 from usp
-	nop
-	sw	t1, 16(sp)
-	nop
-4:	.set	pop
+	jr	t1
+	 addiu	t1, 6f - 5f
 
-	j	stack_done		# go back
+2:	lw	t8, 28(t0)		# argument #8 from usp
+3:	lw	t7, 24(t0)		# argument #7 from usp
+4:	lw	t6, 20(t0)		# argument #6 from usp
+5:	jr	t1
+	 sw	t5, 16(sp)		# argument #5 to ksp
+
+	sw	t8, 28(sp)		# argument #8 to ksp
+	sw	t7, 24(sp)		# argument #7 to ksp
+	sw	t6, 20(sp)		# argument #6 to ksp
+6:	j	stack_done		# go back
+	 nop
+	.set	pop
 
 	.section __ex_table,"a"
 	PTR	1b,bad_stack
 	PTR	2b,bad_stack
 	PTR	3b,bad_stack
+	PTR	4b,bad_stack
 	.previous
 
 	/*
@@ -177,7 +181,7 @@
 	 * The system call does not exist in this kernel
 	 */
 illegal_syscall:
-	li	v0, ENOSYS			# error
+	li	v0, -ENOSYS			# error
 	sw	v0, PT_R2(sp)
 	li	t0, 1				# set error flag
 	sw	t0, PT_R7(sp)
@@ -238,12 +242,12 @@
 	sw	v0, PT_R2(sp)		# result
 
 	/* Success, so skip usual error handling garbage.  */
-	LONG_L	a2, TI_FLAGS($28)	# syscall tracing enabled?
+	lw	a2, TI_FLAGS($28)	# syscall tracing enabled?
 	li	t0, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
 	and	t0, a2, t0
 	bnez	t0, 1f
 
-	b	o32_syscall_exit
+	j	o32_syscall_exit
 
 1:	SAVE_STATIC
 	move	a0, sp
@@ -269,69 +273,49 @@
 	END(sys_sysmips)
 
 	LEAF(sys_syscall)
-	lw	t0, PT_R29(sp)			# user sp
-
-	sltu	v0, a0, __NR_O32_Linux + __NR_O32_Linux_syscalls + 1
-	beqz	v0, enosys
-
-	sll	v0, a0, 2
-	la	v1, sys_syscall
-	lw	t2, sys_call_table(v0)		# function pointer
-	lbu	t4, sys_narg_table(a0)		# number of arguments
-
-	li	v0, -EINVAL
-	beq	t2, v1, out			# do not recurse
+#if defined(CONFIG_BINFMT_IRIX)
+	sltiu	v0, a0, MAX_SYSCALL_NO + 1 # check syscall number
+#else
+	subu	t0, a0, __NR_O32_Linux	# check syscall number
+	sltiu	v0, t0, __NR_O32_Linux_syscalls + 1
+#endif
+	sll	t1, t0, 3
+	beqz	v0, einval
 
-	beqz	t2, enosys			# null function pointer?
+	lw	t2, sys_call_table(t1)		# syscall routine
 
-	andi	v0, t0, 0x3			# unaligned stack pointer?
-	bnez	v0, sigsegv
+#if defined(CONFIG_BINFMT_IRIX)
+	li	v1, 4000			# nr of sys_syscall
+#else
+	li	v1, 4000 - __NR_O32_Linux	# index of sys_syscall
+#endif
+	beq	t0, v1, einval			# do not recurse
 
-	addu	v0, t0, 16			# v0 = usp + 16
-	addu	t1, v0, 12			# 3 32-bit arguments
-	lw	v1, TI_ADDR_LIMIT($28)
-	or	v0, v0, t1
-	and	v1, v1, v0
-	bltz	v1, efault
+	/* Some syscalls like execve get their arguments from struct pt_regs
+	   and claim zero arguments in the syscall table. Thus we have to
+	   assume the worst case and shuffle around all potential arguments.
+	   If you want performance, don't use indirect syscalls. */
 
 	move	a0, a1				# shift argument registers
 	move	a1, a2
 	move	a2, a3
-
-1:	lw	a3, 16(t0)
-2:	lw	t3, 20(t0)
-3:	lw	t4, 24(t0)
-
-	.section	__ex_table, "a"
-	.word	1b, efault
-	.word	2b, efault
-	.word	3b, efault
-	.previous
-
-	sw	t3, 16(sp)			# put into new stackframe
-	sw	t4, 20(sp)
-
-	bnez	t4, 1f				# zero arguments?
-	addu	a0, sp, 32			# then pass sp in a0
-1:
-
-	sw	t3, 16(sp)
-	sw	v1, 20(sp)
+	lw	a3, 16(sp)
+	lw	t4, 20(sp)
+	lw	t5, 24(sp)
+	lw	t6, 28(sp)
+	sw	t4, 16(sp)
+	sw	t5, 20(sp)
+	sw	t6, 24(sp)
+	sw	a0, PT_R4(sp)			# .. and push back a0 - a3, some
+	sw	a1, PT_R5(sp)			# syscalls expect them there
+	sw	a2, PT_R6(sp)
+	sw	a3, PT_R7(sp)
+	sw	a3, PT_R26(sp)			# update a3 for syscall restarting
 	jr	t2
 	/* Unreached */
 
-enosys:	li	v0, -ENOSYS
-	b	out
-
-sigsegv:
-	li	a0, _SIGSEGV
-	move	a1, $28
-	jal	force_sig
-	/* Fall through */
-
-efault:	li	v0, -EFAULT
-
-out:	jr	ra
+einval:	li	v0, -EINVAL
+	jr	ra
 	END(sys_syscall)
 
 	.macro	fifty ptr, nargs, from=1, to=50
@@ -349,12 +333,14 @@
 	.endm
 
 	.macro	syscalltable
+#if defined(CONFIG_BINFMT_IRIX)
 	mille	sys_ni_syscall		0	/*    0 -  999 SVR4 flavour */
-	#include "irix5sys.h"			/* 1000 - 1999 32-bit IRIX */
+	mille	sys_ni_syscall		0	/* 1000 - 1999 32-bit IRIX */
 	mille	sys_ni_syscall		0	/* 2000 - 2999 BSD43 flavour */
 	mille	sys_ni_syscall		0	/* 3000 - 3999 POSIX flavour */
+#endif
 
-	sys	sys_syscall		0	/* 4000 */
+	sys	sys_syscall		8	/* 4000 */
 	sys	sys_exit		1
 	sys	sys_fork		0
 	sys	sys_read		3
@@ -405,7 +391,7 @@
 	sys	sys_ni_syscall		0	/* was signal(2) */
 	sys	sys_geteuid		0
 	sys	sys_getegid		0	/* 4050 */
-	sys	sys_acct		0
+	sys	sys_acct		1
 	sys	sys_umount		2
 	sys	sys_ni_syscall		0
 	sys	sys_ioctl		3
@@ -485,7 +471,7 @@
 	sys	sys_init_module		5
 	sys	sys_delete_module	1
 	sys	sys_ni_syscall		0	/* 4130	was get_kernel_syms */
-	sys	sys_quotactl		0
+	sys	sys_quotactl		4
 	sys	sys_getpgid		1
 	sys	sys_fchdir		1
 	sys	sys_bdflush		2
@@ -506,7 +492,7 @@
 	sys	sys_sysmips		4
 	sys	sys_ni_syscall		0	/* 4150 */
 	sys	sys_getsid		1
-	sys	sys_fdatasync		0
+	sys	sys_fdatasync		1
 	sys	sys_sysctl		1
 	sys	sys_mlock		2
 	sys	sys_munlock		2	/* 4155 */
@@ -640,19 +626,16 @@
 
 	.endm
 
+	/* We pre-compute the number of _instruction_ bytes needed to
+	   load or store the arguments 6-8. Negative values are ignored. */
+
 	.macro  sys function, nargs
 	PTR	\function
+	LONG	(\nargs << 2) - (5 << 2)
 	.endm
 
 	.align	3
-sys_call_table:
+	.type	sys_call_table,@object
+EXPORT(sys_call_table)
 	syscalltable
 	.size	sys_call_table, . - sys_call_table
-
-	.macro	sys function, nargs
-	.byte	\nargs
-	.endm
-
-sys_narg_table:
-	syscalltable
-	.size	sys_narg_table, . - sys_narg_table
diff -Nru a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S
--- a/arch/mips/kernel/scall64-64.S	2005-03-01 23:39:08 -08:00
+++ b/arch/mips/kernel/scall64-64.S	2005-03-01 23:39:08 -08:00
@@ -53,8 +53,10 @@
 
 	sd	a3, PT_R26(sp)		# save a3 for syscall restarting
 
-	LONG_L	t0, TI_FLAGS($28)
-	bltz	t0, syscall_trace_entry	# syscall tracing enabled?
+	li	t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
+	LONG_L	t0, TI_FLAGS($28)	# syscall tracing enabled?
+	and	t0, t1, t0
+	bnez	t0, syscall_trace_entry
 
 	jalr	t2			# Do The Real Thing (TM)
 
@@ -112,7 +114,7 @@
 
 illegal_syscall:
 	/* This also isn't a 64-bit syscall, throw an error.  */
-	li	v0, ENOSYS			# error
+	li	v0, -ENOSYS			# error
 	sd	v0, PT_R2(sp)
 	li	t0, 1				# set error flag
 	sd	t0, PT_R7(sp)
@@ -173,8 +175,8 @@
 	sd	v0, PT_R2(sp)		# result
 
 	/* Success, so skip usual error handling garbage.  */
-	LONG_L	a2, TI_FLAGS($28)	# syscall tracing enabled?
 	li	t0, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
+	LONG_L	a2, TI_FLAGS($28)	# syscall tracing enabled?
 	and	t0, a2, t0
 	bnez	t0, 1f
 
diff -Nru a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S
--- a/arch/mips/kernel/scall64-n32.S	2005-03-01 23:39:16 -08:00
+++ b/arch/mips/kernel/scall64-n32.S	2005-03-01 23:39:16 -08:00
@@ -243,7 +243,7 @@
 	PTR	sys_capget
 	PTR	sys_capset
 	PTR	sys32_rt_sigpending		/* 6125 */
-	PTR	sys32_rt_sigtimedwait
+	PTR	compat_sys_rt_sigtimedwait
 	PTR	sys32_rt_sigqueueinfo
 	PTR	sys32_rt_sigsuspend
 	PTR	sys32_sigaltstack
diff -Nru a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S
--- a/arch/mips/kernel/scall64-o32.S	2005-03-01 23:38:43 -08:00
+++ b/arch/mips/kernel/scall64-o32.S	2005-03-01 23:38:43 -08:00
@@ -6,6 +6,7 @@
  * Copyright (C) 1995 - 2000, 2001 by Ralf Baechle
  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
  * Copyright (C) 2001 MIPS Technologies, Inc.
+ * Copyright (C) 2004 Thiemo Seufer
  *
  * Hairy, the userspace application uses a different argument passing
  * convention than the kernel, so we have to translate things from o32
@@ -43,6 +44,8 @@
  RESTORE_ALL
 #endif
 
+	/* We don't want to stumble over broken sign extensions from
+	   userland. O32 does never use the upper half. */
 	sll	a0, a0, 0
 	sll	a1, a1, 0
 	sll	a2, a2, 0
@@ -68,11 +71,13 @@
 1:	lw	a4, 16(t0)		# argument #5 from usp
 2:	lw	a5, 20(t0)		# argument #6 from usp
 3:	lw	a6, 24(t0)		# argument #7 from usp
+4:	lw	a7, 28(t0)		# argument #8 from usp (for indirect syscalls)
 
 	.section __ex_table,"a"
 	PTR	1b, bad_stack
 	PTR	2b, bad_stack
 	PTR	3b, bad_stack
+	PTR	4b, bad_stack
 	.previous
 
 	li	t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
@@ -91,7 +96,7 @@
 	sd	v0, PT_R0(sp)		# flag for syscall restarting
 1:	sd	v0, PT_R2(sp)		# result
 
-FEXPORT(o32_syscall_exit)
+o32_syscall_exit:
 	local_irq_disable		# make need_resched and
 					# signals dont change between
 					# sampling and return
@@ -109,12 +114,12 @@
 
 trace_a_syscall:
 	SAVE_STATIC
-	sd	a4, PT_R8(sp)
+	sd	a4, PT_R8(sp)		# Save argument registers
 	sd	a5, PT_R9(sp)
 	sd	a6, PT_R10(sp)
-	sd	a7, PT_R11(sp)
+	sd	a7, PT_R11(sp)		# For indirect syscalls
 
-	move	s0, t2
+	move	s0, t2			# Save syscall pointer
 	move	a0, sp
 	li	a1, 0
 	jal	do_syscall_trace
@@ -125,7 +130,8 @@
 	ld	a3, PT_R7(sp)
 	ld	a4, PT_R8(sp)
 	ld	a5, PT_R9(sp)
-	ld	a6, PT_R10(sp)		# For indirect syscalls
+	ld	a6, PT_R10(sp)
+	ld	a7, PT_R11(sp)		# For indirect syscalls
 	jalr	s0
 
 	li	t0, -EMAXERRNO - 1	# error?
@@ -162,40 +168,17 @@
 #else
 	j	handle_sys64
 #endif
-
-illegal_syscall:
-	/* This also isn't a 64-bit syscall, throw an error.  */
-	li	v0, ENOSYS		# error
-	sd	v0, PT_R2(sp)
-	li	t0, 1			# set error flag
-	sd	t0, PT_R7(sp)
-	j	o32_syscall_exit
 	END(handle_sys)
 
 LEAF(sys32_syscall)
-	ld	t0, PT_R29(sp)		# user sp
-
 	sltu	v0, a0, __NR_O32_Linux + __NR_O32_Linux_syscalls + 1
-	beqz	v0, enosys
+	beqz	v0, einval
 
 	dsll	v0, a0, 3
-	dla	v1, sys32_syscall
 	ld	t2, (sys_call_table - (__NR_O32_Linux * 8))(v0)
 
-	li	v0, -EINVAL
-	beq	t2, v1, out		# do not recurse
-
-	beqz	t2, enosys		# null function pointer?
-
-	andi	v0, t0, 0x3		# unaligned stack pointer?
-	bnez	v0, sigsegv
-
-	daddiu	v0, t0, 16		# v0 = usp + 16
-	daddu	t1, v0, 12		# 3 32-bit arguments
-	ld	v1, TI_ADDR_LIMIT($28)
-	or	v0, v0, t1
-	and	v1, v1, v0
-	bnez	v1, efault
+	li	v1, 4000		# indirect syscall number
+	beq	a0, v1, einval		# do not recurse
 
 	move	a0, a1			# shift argument registers
 	move	a1, a2
@@ -203,25 +186,21 @@
 	move	a3, a4
 	move	a4, a5
 	move	a5, a6
+	move	a6, a7
+	sd	a0, PT_R4(sp)		# ... and push back a0 - a3, some
+	sd	a1, PT_R5(sp)		# syscalls expect them there
+	sd	a2, PT_R6(sp)
+	sd	a3, PT_R7(sp)
+	sd	a3, PT_R26(sp)		# update a3 for syscall restarting
 	jr	t2
 	/* Unreached */
 
-enosys:	li	v0, -ENOSYS
-	b	out
-
-sigsegv:
-	li	a0, _SIGSEGV
-	move	a1, $28
-	jal	force_sig
-	/* Fall through */
-
-efault:	li	v0, -EFAULT
-
-out:	jr	ra
+einval:	li	v0, -EINVAL
+	jr	ra
 	END(sys32_syscall)
 
 	.align	3
-	.type	sys_call_table,@object;
+	.type	sys_call_table,@object
 sys_call_table:
 	PTR	sys32_syscall			/* 4000 */
 	PTR	sys_exit
@@ -236,7 +215,7 @@
 	PTR	sys_unlink			/* 4010 */
 	PTR	sys32_execve
 	PTR	sys_chdir
-	PTR	sys_time
+	PTR	compat_sys_time
 	PTR	sys_mknod
 	PTR	sys_chmod			/* 4015 */
 	PTR	sys_lchown
@@ -248,7 +227,7 @@
 	PTR	sys_oldumount
 	PTR	sys_setuid
 	PTR	sys_getuid
-	PTR	sys_stime			/* 4025 */
+	PTR	compat_sys_stime		/* 4025 */
 	PTR	sys32_ptrace
 	PTR	sys_alarm
 	PTR	sys_ni_syscall			/* was sys_fstat */
@@ -420,7 +399,7 @@
 	PTR	sys32_rt_sigaction
 	PTR	sys32_rt_sigprocmask 		/* 4195 */
 	PTR	sys32_rt_sigpending
-	PTR	sys32_rt_sigtimedwait
+	PTR	compat_sys_rt_sigtimedwait
 	PTR	sys32_rt_sigqueueinfo
 	PTR	sys32_rt_sigsuspend
 	PTR	sys32_pread			/* 4200 */
diff -Nru a/arch/mips/kernel/semaphore.c b/arch/mips/kernel/semaphore.c
--- a/arch/mips/kernel/semaphore.c	2005-03-01 23:39:07 -08:00
+++ b/arch/mips/kernel/semaphore.c	2005-03-01 23:39:07 -08:00
@@ -15,7 +15,6 @@
  * indicate that some process(es) are waiting for the semaphore.
  */
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/init.h>
@@ -64,7 +63,7 @@
 		: "=&r" (old_count), "=&r" (tmp), "=m" (sem->count)
 		: "r" (incr), "m" (sem->count));
 	} else {
-		static spinlock_t semaphore_lock = SPIN_LOCK_UNLOCKED;
+		static DEFINE_SPINLOCK(semaphore_lock);
 		unsigned long flags;
 
 		spin_lock_irqsave(&semaphore_lock, flags);
diff -Nru a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
--- a/arch/mips/kernel/setup.c	2005-03-01 23:38:53 -08:00
+++ b/arch/mips/kernel/setup.c	2005-03-01 23:38:53 -08:00
@@ -281,12 +281,12 @@
 		initrd_reserve_bootmem = 1;
 	} else {
 		unsigned long tmp;
-		unsigned long *initrd_header;
+		u32 *initrd_header;
 
-		tmp = ((reserved_end + PAGE_SIZE-1) & PAGE_MASK) - 8;
+		tmp = ((reserved_end + PAGE_SIZE-1) & PAGE_MASK) - sizeof(u32) * 2;
 		if (tmp < reserved_end)
 			tmp += PAGE_SIZE;
-		initrd_header = (unsigned long *)tmp;
+		initrd_header = (u32 *)tmp;
 		if (initrd_header[0] == 0x494E5244) {
 			initrd_start = (unsigned long)&initrd_header[2];
 			initrd_end = initrd_start + initrd_header[1];
@@ -425,8 +425,10 @@
 		if (CPHYSADDR(initrd_end) > PFN_PHYS(max_low_pfn)) {
 			printk("initrd extends beyond end of memory "
 			       "(0x%0*Lx > 0x%0*Lx)\ndisabling initrd\n",
-			       sizeof(long) * 2, CPHYSADDR(initrd_end),
-			       sizeof(long) * 2, PFN_PHYS(max_low_pfn));
+			       sizeof(long) * 2,
+			       (unsigned long long)CPHYSADDR(initrd_end),
+			       sizeof(long) * 2,
+			       (unsigned long long)PFN_PHYS(max_low_pfn));
 			initrd_start = initrd_end = 0;
 			initrd_reserve_bootmem = 0;
 		}
@@ -441,10 +443,21 @@
 {
 	int i;
 
+#if defined(CONFIG_MIPS64) && !defined(CONFIG_BUILD_ELF64)
+	/*
+	 * The 64bit code in 32bit object format trick can't represent
+	 * 64bit wide relocations for linker script symbols.
+	 */
+	code_resource.start = CPHYSADDR(&_text);
+	code_resource.end = CPHYSADDR(&_etext) - 1;
+	data_resource.start = CPHYSADDR(&_etext);
+	data_resource.end = CPHYSADDR(&_edata) - 1;
+#else
 	code_resource.start = virt_to_phys(&_text);
 	code_resource.end = virt_to_phys(&_etext) - 1;
 	data_resource.start = virt_to_phys(&_etext);
 	data_resource.end = virt_to_phys(&_edata) - 1;
+#endif
 
 	/*
 	 * Request address space for all standard RAM.
diff -Nru a/arch/mips/kernel/signal-common.h b/arch/mips/kernel/signal-common.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/mips/kernel/signal-common.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,137 @@
+/*
+ * This file 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) 1991, 1992  Linus Torvalds
+ * Copyright (C) 1994 - 2000  Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ */
+
+static inline int
+setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
+{
+	int err = 0;
+
+	err |= __put_user(regs->cp0_epc, &sc->sc_pc);
+	err |= __put_user(regs->cp0_status, &sc->sc_status);
+
+#define save_gp_reg(i) do {						\
+	err |= __put_user(regs->regs[i], &sc->sc_regs[i]);		\
+} while(0)
+	__put_user(0, &sc->sc_regs[0]); save_gp_reg(1); save_gp_reg(2);
+	save_gp_reg(3); save_gp_reg(4); save_gp_reg(5); save_gp_reg(6);
+	save_gp_reg(7); save_gp_reg(8); save_gp_reg(9); save_gp_reg(10);
+	save_gp_reg(11); save_gp_reg(12); save_gp_reg(13); save_gp_reg(14);
+	save_gp_reg(15); save_gp_reg(16); save_gp_reg(17); save_gp_reg(18);
+	save_gp_reg(19); save_gp_reg(20); save_gp_reg(21); save_gp_reg(22);
+	save_gp_reg(23); save_gp_reg(24); save_gp_reg(25); save_gp_reg(26);
+	save_gp_reg(27); save_gp_reg(28); save_gp_reg(29); save_gp_reg(30);
+	save_gp_reg(31);
+#undef save_gp_reg
+
+	err |= __put_user(regs->hi, &sc->sc_mdhi);
+	err |= __put_user(regs->lo, &sc->sc_mdlo);
+	err |= __put_user(regs->cp0_cause, &sc->sc_cause);
+	err |= __put_user(regs->cp0_badvaddr, &sc->sc_badvaddr);
+
+	err |= __put_user(!!used_math(), &sc->sc_used_math);
+
+	if (!used_math())
+		goto out;
+
+	/*
+	 * Save FPU state to signal context.  Signal handler will "inherit"
+	 * current FPU state.
+	 */
+	preempt_disable();
+
+	if (!is_fpu_owner()) {
+		own_fpu();
+		restore_fp(current);
+	}
+	err |= save_fp_context(sc);
+
+	preempt_enable();
+
+out:
+	return err;
+}
+
+static inline int
+restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
+{
+	int err = 0;
+	unsigned int used_math;
+
+	/* Always make any pending restarted system calls return -EINTR */
+	current_thread_info()->restart_block.fn = do_no_restart_syscall;
+
+	err |= __get_user(regs->cp0_epc, &sc->sc_pc);
+	err |= __get_user(regs->hi, &sc->sc_mdhi);
+	err |= __get_user(regs->lo, &sc->sc_mdlo);
+
+#define restore_gp_reg(i) do {						\
+	err |= __get_user(regs->regs[i], &sc->sc_regs[i]);		\
+} while(0)
+	restore_gp_reg( 1); restore_gp_reg( 2); restore_gp_reg( 3);
+	restore_gp_reg( 4); restore_gp_reg( 5); restore_gp_reg( 6);
+	restore_gp_reg( 7); restore_gp_reg( 8); restore_gp_reg( 9);
+	restore_gp_reg(10); restore_gp_reg(11); restore_gp_reg(12);
+	restore_gp_reg(13); restore_gp_reg(14); restore_gp_reg(15);
+	restore_gp_reg(16); restore_gp_reg(17); restore_gp_reg(18);
+	restore_gp_reg(19); restore_gp_reg(20); restore_gp_reg(21);
+	restore_gp_reg(22); restore_gp_reg(23); restore_gp_reg(24);
+	restore_gp_reg(25); restore_gp_reg(26); restore_gp_reg(27);
+	restore_gp_reg(28); restore_gp_reg(29); restore_gp_reg(30);
+	restore_gp_reg(31);
+#undef restore_gp_reg
+
+	err |= __get_user(used_math, &sc->sc_used_math);
+	conditional_used_math(used_math);
+
+	preempt_disable();
+
+	if (used_math()) {
+		/* restore fpu context if we have used it before */
+		own_fpu();
+		err |= restore_fp_context(sc);
+	} else {
+		/* signal handler may have used FPU.  Give it up. */
+		lose_fpu();
+	}
+
+	preempt_enable();
+
+	return err;
+}
+
+/*
+ * Determine which stack to use..
+ */
+static inline void *
+get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
+{
+	unsigned long sp, almask;
+
+	/* Default to using normal stack */
+	sp = regs->regs[29];
+
+	/*
+ 	 * FPU emulator may have it's own trampoline active just
+ 	 * above the user stack, 16-bytes before the next lowest
+ 	 * 16 byte boundary.  Try to avoid trashing it.
+ 	 */
+ 	sp -= 32;
+
+	/* This is the X/Open sanctioned signal stack switching.  */
+	if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0))
+		sp = current->sas_ss_sp + current->sas_ss_size;
+
+	if (PLAT_TRAMPOLINE_STUFF_LINE)
+		almask = ~(PLAT_TRAMPOLINE_STUFF_LINE - 1);
+	else
+		almask = ALMASK;
+
+	return (void *)((sp - frame_size) & almask);
+}
diff -Nru a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
--- a/arch/mips/kernel/signal.c	2005-03-01 23:39:18 -08:00
+++ b/arch/mips/kernel/signal.c	2005-03-01 23:39:18 -08:00
@@ -18,7 +18,6 @@
 #include <linux/errno.h>
 #include <linux/wait.h>
 #include <linux/ptrace.h>
-#include <linux/suspend.h>
 #include <linux/unistd.h>
 #include <linux/compiler.h>
 
@@ -29,12 +28,15 @@
 #include <asm/sim.h>
 #include <asm/uaccess.h>
 #include <asm/ucontext.h>
+#include <asm/cpu-features.h>
+
+#include "signal-common.h"
 
 #define DEBUG_SIG 0
 
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 
-extern asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs);
+static int do_signal(sigset_t *oldset, struct pt_regs *regs);
 
 /*
  * Atomically swap in the new signal mask, and wait for a signal.
@@ -152,51 +154,6 @@
 	return do_sigaltstack(uss, uoss, usp);
 }
 
-asmlinkage int restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
-{
-	int err = 0;
-
-	/* Always make any pending restarted system calls return -EINTR */
-	current_thread_info()->restart_block.fn = do_no_restart_syscall;
-
-	err |= __get_user(regs->cp0_epc, &sc->sc_pc);
-	err |= __get_user(regs->hi, &sc->sc_mdhi);
-	err |= __get_user(regs->lo, &sc->sc_mdlo);
-
-#define restore_gp_reg(i) do {						\
-	err |= __get_user(regs->regs[i], &sc->sc_regs[i]);		\
-} while(0)
-	restore_gp_reg( 1); restore_gp_reg( 2); restore_gp_reg( 3);
-	restore_gp_reg( 4); restore_gp_reg( 5); restore_gp_reg( 6);
-	restore_gp_reg( 7); restore_gp_reg( 8); restore_gp_reg( 9);
-	restore_gp_reg(10); restore_gp_reg(11); restore_gp_reg(12);
-	restore_gp_reg(13); restore_gp_reg(14); restore_gp_reg(15);
-	restore_gp_reg(16); restore_gp_reg(17); restore_gp_reg(18);
-	restore_gp_reg(19); restore_gp_reg(20); restore_gp_reg(21);
-	restore_gp_reg(22); restore_gp_reg(23); restore_gp_reg(24);
-	restore_gp_reg(25); restore_gp_reg(26); restore_gp_reg(27);
-	restore_gp_reg(28); restore_gp_reg(29); restore_gp_reg(30);
-	restore_gp_reg(31);
-#undef restore_gp_reg
-
-	err |= __get_user(current->used_math, &sc->sc_used_math);
-
-	preempt_disable();
-
-	if (current->used_math) {
-		/* restore fpu context if we have used it before */
-		own_fpu();
-		err |= restore_fp_context(sc);
-	} else {
-		/* signal handler may have used FPU.  Give it up. */
-		lose_fpu();
-	}
-
-	preempt_enable();
-
-	return err;
-}
-
 #if PLAT_TRAMPOLINE_STUFF_LINE
 #define __tramp __attribute__((aligned(PLAT_TRAMPOLINE_STUFF_LINE)))
 #else
@@ -220,7 +177,9 @@
 };
 
 #ifdef CONFIG_TRAD_SIGNALS
-asmlinkage void sys_sigreturn(struct pt_regs regs)
+save_static_function(sys_sigreturn);
+__attribute_used__ noinline static void
+_sys_sigreturn(nabi_no_regargs struct pt_regs regs)
 {
 	struct sigframe *frame;
 	sigset_t blocked;
@@ -257,7 +216,9 @@
 }
 #endif
 
-asmlinkage void sys_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
+save_static_function(sys_rt_sigreturn);
+__attribute_used__ noinline static void
+_sys_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
 {
 	struct rt_sigframe *frame;
 	sigset_t set;
@@ -298,85 +259,6 @@
 	force_sig(SIGSEGV, current);
 }
 
-inline int setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
-{
-	int err = 0;
-
-	err |= __put_user(regs->cp0_epc, &sc->sc_pc);
-	err |= __put_user(regs->cp0_status, &sc->sc_status);
-
-#define save_gp_reg(i) do {						\
-	err |= __put_user(regs->regs[i], &sc->sc_regs[i]);		\
-} while(0)
-	__put_user(0, &sc->sc_regs[0]); save_gp_reg(1); save_gp_reg(2);
-	save_gp_reg(3); save_gp_reg(4); save_gp_reg(5); save_gp_reg(6);
-	save_gp_reg(7); save_gp_reg(8); save_gp_reg(9); save_gp_reg(10);
-	save_gp_reg(11); save_gp_reg(12); save_gp_reg(13); save_gp_reg(14);
-	save_gp_reg(15); save_gp_reg(16); save_gp_reg(17); save_gp_reg(18);
-	save_gp_reg(19); save_gp_reg(20); save_gp_reg(21); save_gp_reg(22);
-	save_gp_reg(23); save_gp_reg(24); save_gp_reg(25); save_gp_reg(26);
-	save_gp_reg(27); save_gp_reg(28); save_gp_reg(29); save_gp_reg(30);
-	save_gp_reg(31);
-#undef save_gp_reg
-
-	err |= __put_user(regs->hi, &sc->sc_mdhi);
-	err |= __put_user(regs->lo, &sc->sc_mdlo);
-	err |= __put_user(regs->cp0_cause, &sc->sc_cause);
-	err |= __put_user(regs->cp0_badvaddr, &sc->sc_badvaddr);
-
-	err |= __put_user(current->used_math, &sc->sc_used_math);
-
-	if (!current->used_math)
-		goto out;
-
-	/*
-	 * Save FPU state to signal context.  Signal handler will "inherit"
-	 * current FPU state.
-	 */
-	preempt_disable();
-
-	if (!is_fpu_owner()) {
-		own_fpu();
-		restore_fp(current);
-	}
-	err |= save_fp_context(sc);
-
-	preempt_enable();
-
-out:
-	return err;
-}
-
-/*
- * Determine which stack to use..
- */
-static inline void *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
-	size_t frame_size)
-{
-	unsigned long sp, almask;
-
-	/* Default to using normal stack */
-	sp = regs->regs[29];
-
-	/*
- 	 * FPU emulator may have it's own trampoline active just
- 	 * above the user stack, 16-bytes before the next lowest
- 	 * 16 byte boundary.  Try to avoid trashing it.
- 	 */
- 	sp -= 32;
-
-	/* This is the X/Open sanctioned signal stack switching.  */
-	if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0))
-		sp = current->sas_ss_sp + current->sas_ss_size;
-
-	if (PLAT_TRAMPOLINE_STUFF_LINE)
-		almask = ~(PLAT_TRAMPOLINE_STUFF_LINE - 1);
-	else
-		almask = ALMASK;
-
-	return (void *)((sp - frame_size) & ~(PLAT_TRAMPOLINE_STUFF_LINE - 1));
-}
-
 #ifdef CONFIG_TRAD_SIGNALS
 static void inline setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
 	int signr, sigset_t *set)
@@ -395,8 +277,7 @@
 	 *         syscall
 	 */
 	if (PLAT_TRAMPOLINE_STUFF_LINE)
-		__builtin_memset(frame->sf_code, '0',
-		                 PLAT_TRAMPOLINE_STUFF_LINE);
+		__clear_user(frame->sf_code, PLAT_TRAMPOLINE_STUFF_LINE);
 	err |= __put_user(0x24020000 + __NR_sigreturn, frame->sf_code + 0);
 	err |= __put_user(0x0000000c                 , frame->sf_code + 1);
 	flush_cache_sigtramp((unsigned long) frame->sf_code);
@@ -452,8 +333,7 @@
 	 *         syscall
 	 */
 	if (PLAT_TRAMPOLINE_STUFF_LINE)
-		__builtin_memset(frame->rs_code, '0',
-		                 PLAT_TRAMPOLINE_STUFF_LINE);
+		__clear_user(frame->rs_code, PLAT_TRAMPOLINE_STUFF_LINE);
 	err |= __put_user(0x24020000 + __NR_rt_sigreturn, frame->rs_code + 0);
 	err |= __put_user(0x0000000c                    , frame->rs_code + 1);
 	flush_cache_sigtramp((unsigned long) frame->rs_code);
@@ -557,7 +437,7 @@
 extern int do_signal32(sigset_t *oldset, struct pt_regs *regs);
 extern int do_irix_signal(sigset_t *oldset, struct pt_regs *regs);
 
-asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs)
+static int do_signal(sigset_t *oldset, struct pt_regs *regs)
 {
 	struct k_sigaction ka;
 	siginfo_t info;
@@ -577,10 +457,8 @@
 	if (!user_mode(regs))
 		return 1;
 
-	if (current->flags & PF_FREEZE) {
-		refrigerator(0);
+	if (try_to_freeze(0))
 		goto no_signal;
-	}
 
 	if (!oldset)
 		oldset = &current->blocked;
@@ -612,8 +490,6 @@
 	}
 	return 0;
 }
-
-extern int do_irix_signal(sigset_t *oldset, struct pt_regs *regs);
 
 /*
  * notification of userspace execution resumption
diff -Nru a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c
--- a/arch/mips/kernel/signal32.c	2005-03-01 23:38:57 -08:00
+++ b/arch/mips/kernel/signal32.c	2005-03-01 23:38:57 -08:00
@@ -37,7 +37,7 @@
 	s32 sival_ptr;
 } sigval_t32;
 
-typedef struct siginfo32 {
+typedef struct compat_siginfo {
 	int si_signo;
 	int si_code;
 	int si_errno;
@@ -93,7 +93,7 @@
 		} _rt;
 
 	} _sifields;
-} siginfo_t32;
+} compat_siginfo_t;
 
 /*
  * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
@@ -106,7 +106,7 @@
 
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 
-extern asmlinkage int do_signal32(sigset_t *oldset, struct pt_regs *regs);
+extern int do_signal32(sigset_t *oldset, struct pt_regs *regs);
 
 /* 32-bit compatibility types */
 
@@ -192,6 +192,7 @@
 /*
  * Atomically swap in the new signal mask, and wait for a signal.
  */
+
 save_static_function(sys32_sigsuspend);
 __attribute_used__ noinline static int
 _sys32_sigsuspend(nabi_no_regargs struct pt_regs regs)
@@ -333,10 +334,10 @@
 	return ret;
 }
 
-static asmlinkage int restore_sigcontext32(struct pt_regs *regs,
-					   struct sigcontext32 *sc)
+static int restore_sigcontext32(struct pt_regs *regs, struct sigcontext32 *sc)
 {
 	int err = 0;
+	__u32 used_math;
 
 	/* Always make any pending restarted system calls return -EINTR */
 	current_thread_info()->restart_block.fn = do_no_restart_syscall;
@@ -361,11 +362,12 @@
 	restore_gp_reg(31);
 #undef restore_gp_reg
 
-	err |= __get_user(current->used_math, &sc->sc_used_math);
+	err |= __get_user(used_math, &sc->sc_used_math);
+	conditional_used_math(used_math);
 
 	preempt_disable();
 
-	if (current->used_math) {
+	if (used_math()) {
 		/* restore fpu context if we have used it before */
 		own_fpu();
 		err |= restore_fp_context32(sc);
@@ -389,15 +391,15 @@
 struct rt_sigframe32 {
 	u32 rs_ass[4];			/* argument save space for o32 */
 	u32 rs_code[2];			/* signal trampoline */
-	struct siginfo32 rs_info;
+	compat_siginfo_t rs_info;
 	struct ucontext32 rs_uc;
 };
 
-static int copy_siginfo_to_user32(siginfo_t32 *to, siginfo_t *from)
+int copy_siginfo_to_user32(compat_siginfo_t *to, siginfo_t *from)
 {
 	int err;
 
-	if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t32)))
+	if (!access_ok (VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
 		return -EFAULT;
 
 	/* If you change siginfo_t structure, please be sure
@@ -440,7 +442,9 @@
 	return err;
 }
 
-asmlinkage void sys32_sigreturn(nabi_no_regargs struct pt_regs regs)
+save_static_function(sys32_sigreturn);
+__attribute_used__ noinline static void
+_sys32_sigreturn(nabi_no_regargs struct pt_regs regs)
 {
 	struct sigframe *frame;
 	sigset_t blocked;
@@ -476,7 +480,9 @@
 	force_sig(SIGSEGV, current);
 }
 
-asmlinkage void sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
+save_static_function(sys32_rt_sigreturn);
+__attribute_used__ noinline static void
+_sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
 {
 	struct rt_sigframe32 *frame;
 	sigset_t set;
@@ -552,9 +558,9 @@
 	err |= __put_user(regs->cp0_cause, &sc->sc_cause);
 	err |= __put_user(regs->cp0_badvaddr, &sc->sc_badvaddr);
 
-	err |= __put_user(current->used_math, &sc->sc_used_math);
+	err |= __put_user(!!used_math(), &sc->sc_used_math);
 
-	if (!current->used_math)
+	if (!used_math())
 		goto out;
 
 	/* 
@@ -677,7 +683,7 @@
 	err |= __put_user(0x0000000c                      , frame->rs_code + 1);
 	flush_cache_sigtramp((unsigned long) frame->rs_code);
 
-	/* Convert (siginfo_t -> siginfo_t32) and copy to user. */
+	/* Convert (siginfo_t -> compat_siginfo_t) and copy to user. */
 	err |= copy_siginfo_to_user32(&frame->rs_info, info);
 
 	/* Create the ucontext.  */
@@ -759,7 +765,7 @@
 	}
 }
 
-asmlinkage int do_signal32(sigset_t *oldset, struct pt_regs *regs)
+int do_signal32(sigset_t *oldset, struct pt_regs *regs)
 {
 	struct k_sigaction ka;
 	siginfo_t info;
@@ -773,10 +779,8 @@
 	if (!user_mode(regs))
 		return 1;
 
-	if (current->flags & PF_FREEZE) {
-		refrigerator(0);
+	if (try_to_freeze(0))
 		goto no_signal;
-	}
 
 	if (!oldset)
 		oldset = &current->blocked;
@@ -890,98 +894,7 @@
 	return ret;
 }
 
-asmlinkage int sys32_rt_sigtimedwait(compat_sigset_t *uthese,
-	siginfo_t32 *uinfo, struct compat_timespec *uts,
-	compat_time_t sigsetsize)
-{
-	int ret, sig;
-	sigset_t these;
-	compat_sigset_t these32;
-	struct timespec ts;
-	siginfo_t info;
-	long timeout = 0;
-
-	/*
-	 * As the result of a brainfarting competition a few years ago the
-	 * size of sigset_t for the 32-bit kernel was choosen to be 128 bits
-	 * but nothing so far is actually using that many, 64 are enough.  So
-	 * for now we just drop the high bits.
-	 */
-	if (copy_from_user (&these32, uthese, sizeof(compat_old_sigset_t)))
-		return -EFAULT;
-
-	switch (_NSIG_WORDS) {
-#ifdef __MIPSEB__
-	case 4: these.sig[3] = these32.sig[6] | (((long)these32.sig[7]) << 32);
-	case 3: these.sig[2] = these32.sig[4] | (((long)these32.sig[5]) << 32);
-	case 2: these.sig[1] = these32.sig[2] | (((long)these32.sig[3]) << 32);
-	case 1: these.sig[0] = these32.sig[0] | (((long)these32.sig[1]) << 32);
-#endif
-#ifdef __MIPSEL__
-	case 4: these.sig[3] = these32.sig[7] | (((long)these32.sig[6]) << 32);
-	case 3: these.sig[2] = these32.sig[5] | (((long)these32.sig[4]) << 32);
-	case 2: these.sig[1] = these32.sig[3] | (((long)these32.sig[2]) << 32);
-	case 1: these.sig[0] = these32.sig[1] | (((long)these32.sig[0]) << 32);
-#endif
-	}
-
-	/*
-	 * Invert the set of allowed signals to get those we
-	 * want to block.
-	 */
-	sigdelsetmask(&these, sigmask(SIGKILL)|sigmask(SIGSTOP));
-	signotset(&these);
-
-	if (uts) {
-		if (get_user (ts.tv_sec, &uts->tv_sec) ||
-		    get_user (ts.tv_nsec, &uts->tv_nsec))
-			return -EINVAL;
-		if (ts.tv_nsec >= 1000000000L || ts.tv_nsec < 0
-		    || ts.tv_sec < 0)
-			return -EINVAL;
-	}
-
-	spin_lock_irq(&current->sighand->siglock);
-	sig = dequeue_signal(current, &these, &info);
-	if (!sig) {
-		/* None ready -- temporarily unblock those we're interested
-		   in so that we'll be awakened when they arrive.  */
-		sigset_t oldblocked = current->blocked;
-		sigandsets(&current->blocked, &current->blocked, &these);
-		recalc_sigpending();
-		spin_unlock_irq(&current->sighand->siglock);
-
-		timeout = MAX_SCHEDULE_TIMEOUT;
-		if (uts)
-			timeout = (timespec_to_jiffies(&ts)
-				   + (ts.tv_sec || ts.tv_nsec));
-
-		current->state = TASK_INTERRUPTIBLE;
-		timeout = schedule_timeout(timeout);
-
-		spin_lock_irq(&current->sighand->siglock);
-		sig = dequeue_signal(current, &these, &info);
-		current->blocked = oldblocked;
-		recalc_sigpending();
-	}
-	spin_unlock_irq(&current->sighand->siglock);
-
-	if (sig) {
-		ret = sig;
-		if (uinfo) {
-			if (copy_siginfo_to_user32(uinfo, &info))
-				ret = -EFAULT;
-		}
-	} else {
-		ret = -EAGAIN;
-		if (timeout)
-			ret = -EINTR;
-	}
-
-	return ret;
-}
-
-asmlinkage int sys32_rt_sigqueueinfo(int pid, int sig, siginfo_t32 *uinfo)
+asmlinkage int sys32_rt_sigqueueinfo(int pid, int sig, compat_siginfo_t *uinfo)
 {
 	siginfo_t info;
 	int ret;
diff -Nru a/arch/mips/kernel/signal_n32.c b/arch/mips/kernel/signal_n32.c
--- a/arch/mips/kernel/signal_n32.c	2005-03-01 23:38:58 -08:00
+++ b/arch/mips/kernel/signal_n32.c	2005-03-01 23:38:58 -08:00
@@ -35,9 +35,12 @@
 #include <asm/ucontext.h>
 #include <asm/system.h>
 #include <asm/fpu.h>
+#include <asm/cpu-features.h>
+
+#include "signal-common.h"
 
 /*
- * Including <asm/unistd.h would give use the 64-bit syscall numbers ...
+ * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
  */
 #define __NR_N32_rt_sigreturn		6211
 #define __NR_N32_restart_syscall	6214
@@ -59,17 +62,22 @@
 	sigset_t            uc_sigmask;   /* mask last for extensibility */
 };
 
+#if PLAT_TRAMPOLINE_STUFF_LINE
+#define __tramp __attribute__((aligned(PLAT_TRAMPOLINE_STUFF_LINE)))
+#else
+#define __tramp
+#endif
+
 struct rt_sigframe_n32 {
 	u32 rs_ass[4];			/* argument save space for o32 */
-	u32 rs_code[2];			/* signal trampoline */
-	struct siginfo rs_info;
+	u32 rs_code[2] __tramp;		/* signal trampoline */
+	struct siginfo rs_info __tramp;
 	struct ucontextn32 rs_uc;
 };
 
-extern asmlinkage int restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc);
-extern int inline setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc);
-
-asmlinkage void sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
+save_static_function(sysn32_rt_sigreturn);
+__attribute_used__ noinline static void
+_sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
 {
 	struct rt_sigframe_n32 *frame;
 	sigset_t set;
@@ -118,31 +126,6 @@
 	force_sig(SIGSEGV, current);
 }
 
-/*
- * Determine which stack to use..
- */
-static inline void *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
-	size_t frame_size)
-{
-	unsigned long sp;
-
-	/* Default to using normal stack */
-	sp = regs->regs[29];
-
-	/*
- 	 * FPU emulator may have it's own trampoline active just
- 	 * above the user stack, 16-bytes before the next lowest
- 	 * 16 byte boundary.  Try to avoid trashing it.
- 	 */
- 	sp -= 32;
-
-	/* This is the X/Open sanctioned signal stack switching.  */
-	if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0))
-		sp = current->sas_ss_sp + current->sas_ss_size;
-
-	return (void *)((sp - frame_size) & ALMASK);
-}
-
 void setup_rt_frame_n32(struct k_sigaction * ka,
 	struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info)
 {
@@ -160,8 +143,10 @@
 	 *         li      v0, __NR_rt_sigreturn
 	 *         syscall
 	 */
+	if (PLAT_TRAMPOLINE_STUFF_LINE)
+		__clear_user(frame->rs_code, PLAT_TRAMPOLINE_STUFF_LINE);
 	err |= __put_user(0x24020000 + __NR_N32_rt_sigreturn, frame->rs_code + 0);
-	err |= __put_user(0x0000000c                    , frame->rs_code + 1);
+	err |= __put_user(0x0000000c                        , frame->rs_code + 1);
 	flush_cache_sigtramp((unsigned long) frame->rs_code);
 
 	/* Create siginfo.  */
diff -Nru a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
--- a/arch/mips/kernel/smp.c	2005-03-01 23:38:53 -08:00
+++ b/arch/mips/kernel/smp.c	2005-03-01 23:38:53 -08:00
@@ -18,7 +18,6 @@
  * Copyright (C) 2000, 2001 Silicon Graphics, Inc.
  * Copyright (C) 2000, 2001, 2003 Broadcom Corporation
  */
-#include <linux/config.h>
 #include <linux/cache.h>
 #include <linux/delay.h>
 #include <linux/init.h>
@@ -94,6 +93,7 @@
 }
 
 extern void __init calibrate_delay(void);
+extern ATTRIB_NORET void cpu_idle(void);
 
 /*
  * First C code run on the secondary CPUs after being started up by
@@ -123,7 +123,7 @@
 	cpu_idle();
 }
 
-spinlock_t smp_call_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(smp_call_lock);
 
 struct call_data_struct *call_data;
 
diff -Nru a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c
--- a/arch/mips/kernel/syscall.c	2005-03-01 23:39:09 -08:00
+++ b/arch/mips/kernel/syscall.c	2005-03-01 23:39:09 -08:00
@@ -3,10 +3,11 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1995, 1996, 1997, 2000, 2001 by Ralf Baechle
+ * Copyright (C) 1995, 1996, 1997, 2000, 2001, 05 by Ralf Baechle
  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
  * Copyright (C) 2001 MIPS Technologies, Inc.
  */
+#include <linux/a.out.h>
 #include <linux/errno.h>
 #include <linux/linkage.h>
 #include <linux/mm.h>
@@ -66,11 +67,7 @@
 	int do_color_align;
 	unsigned long task_size;
 
-#ifdef CONFIG_MIPS32
-	task_size = TASK_SIZE;
-#else
-	task_size = (current->thread.mflags & MF_32BIT_ADDR) ? TASK_SIZE32 : TASK_SIZE;
-#endif
+	task_size = STACK_TOP;
 
 	if (flags & MAP_FIXED) {
 		/*
@@ -116,7 +113,7 @@
 }
 
 /* common code for old and new mmaps */
-static inline long
+static inline unsigned long
 do_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
         unsigned long flags, unsigned long fd, unsigned long pgoff)
 {
@@ -140,8 +137,9 @@
 	return error;
 }
 
-asmlinkage unsigned long old_mmap(unsigned long addr, size_t len, int prot,
-                                  int flags, int fd, off_t offset)
+asmlinkage unsigned long
+old_mmap(unsigned long addr, unsigned long len, int prot,
+	int flags, int fd, off_t offset)
 {
 	unsigned long result;
 
@@ -155,7 +153,7 @@
 	return result;
 }
 
-asmlinkage long
+asmlinkage unsigned long
 sys_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
           unsigned long flags, unsigned long fd, unsigned long pgoff)
 {
diff -Nru a/arch/mips/kernel/sysirix.c b/arch/mips/kernel/sysirix.c
--- a/arch/mips/kernel/sysirix.c	2005-03-01 23:39:16 -08:00
+++ b/arch/mips/kernel/sysirix.c	2005-03-01 23:39:16 -08:00
@@ -1648,7 +1648,7 @@
 	struct kstatfs kbuf;
 	int error, i;
 
-	printk("[%s:%d] Wheee.. irix_statvfs(%s,%p)\n",
+	printk("[%s:%d] Wheee.. irix_statvfs64(%s,%p)\n",
 	       current->comm, current->pid, fname, buf);
 	error = verify_area(VERIFY_WRITE, buf, sizeof(struct irix_statvfs64));
 	if(error)
@@ -1694,7 +1694,7 @@
 	struct file *file;
 	int error, i;
 
-	printk("[%s:%d] Wheee.. irix_fstatvfs(%d,%p)\n",
+	printk("[%s:%d] Wheee.. irix_fstatvfs64(%d,%p)\n",
 	       current->comm, current->pid, fd, buf);
 
 	error = verify_area(VERIFY_WRITE, buf, sizeof(struct irix_statvfs));
diff -Nru a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c
--- a/arch/mips/kernel/time.c	2005-03-01 23:38:56 -08:00
+++ b/arch/mips/kernel/time.c	2005-03-01 23:38:56 -08:00
@@ -11,7 +11,6 @@
  * Free Software Foundation;  either version 2 of the  License, or (at your
  * option) any later version.
  */
-#include <linux/config.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
@@ -53,7 +52,7 @@
  */
 extern volatile unsigned long wall_jiffies;
 
-spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(rtc_lock);
 
 /*
  * By default we provide the null RTC ops
diff -Nru a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
--- a/arch/mips/kernel/traps.c	2005-03-01 23:38:56 -08:00
+++ b/arch/mips/kernel/traps.c	2005-03-01 23:38:56 -08:00
@@ -38,12 +38,9 @@
 #include <asm/watch.h>
 #include <asm/types.h>
 
-extern asmlinkage void handle_mod(void);
+extern asmlinkage void handle_tlbm(void);
 extern asmlinkage void handle_tlbl(void);
 extern asmlinkage void handle_tlbs(void);
-extern asmlinkage void __xtlb_mod(void);
-extern asmlinkage void __xtlb_tlbl(void);
-extern asmlinkage void __xtlb_tlbs(void);
 extern asmlinkage void handle_adel(void);
 extern asmlinkage void handle_ades(void);
 extern asmlinkage void handle_ibe(void);
@@ -82,7 +79,12 @@
 	long stackdata;
 	int i;
 
-	sp = sp ? sp : (unsigned long *) &sp;
+	if (!sp) {
+		if (task && task != current)
+			sp = (unsigned long *) task->thread.reg29;
+		else
+			sp = (unsigned long *) &sp;
+	}
 
 	printk("Stack :");
 	i = 0;
@@ -110,8 +112,12 @@
 	const int field = 2 * sizeof(unsigned long);
 	unsigned long addr;
 
-	if (!stack)
-		stack = (unsigned long*)&stack;
+	if (!stack) {
+		if (task && task != current)
+			stack = (unsigned long *) task->thread.reg29;
+		else
+			stack = (unsigned long *) &stack;
+	}
 
 	printk("Call Trace:");
 #ifdef CONFIG_KALLSYMS
@@ -244,7 +250,7 @@
 	printk("\n");
 }
 
-static spinlock_t die_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(die_lock);
 
 NORET_TYPE void __die(const char * str, struct pt_regs * regs,
 	const char * file, const char * func, unsigned long line)
@@ -655,11 +661,11 @@
 		preempt_disable();
 
 		own_fpu();
-		if (current->used_math) {	/* Using the FPU again.  */
+		if (used_math()) {	/* Using the FPU again.  */
 			restore_fp(current);
 		} else {			/* First time FPU user.  */
 			init_fpu();
-			current->used_math = 1;
+			set_used_math();
 		}
 
 		if (!cpu_has_fpu) {
@@ -1001,16 +1007,10 @@
 	if (board_be_init)
 		board_be_init();
 
-#ifdef CONFIG_MIPS32
-	set_except_vector(1, handle_mod);
+	set_except_vector(1, handle_tlbm);
 	set_except_vector(2, handle_tlbl);
 	set_except_vector(3, handle_tlbs);
-#endif
-#ifdef CONFIG_MIPS64
-	set_except_vector(1, __xtlb_mod);
-	set_except_vector(2, __xtlb_tlbl);
-	set_except_vector(3, __xtlb_tlbs);
-#endif
+
 	set_except_vector(4, handle_adel);
 	set_except_vector(5, handle_ades);
 
@@ -1047,7 +1047,7 @@
 		 * unaligned ldc1/sdc1 exception.  The handlers have not been
 		 * written yet.  Well, anyway there is no R6000 machine on the
 		 * current list of targets for Linux/MIPS.
-		 * (Duh, crap, there is someone with a tripple R6k machine)
+		 * (Duh, crap, there is someone with a triple R6k machine)
 		 */
 		//set_except_vector(14, handle_mc);
 		//set_except_vector(15, handle_ndc);
diff -Nru a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S
--- a/arch/mips/kernel/vmlinux.lds.S	2005-03-01 23:38:55 -08:00
+++ b/arch/mips/kernel/vmlinux.lds.S	2005-03-01 23:38:55 -08:00
@@ -156,6 +156,7 @@
 	*(.options)
 	*(.pdr)
 	*(.reginfo)
+	*(.mdebug*)
   }
 
   /* This is the MIPS specific mdebug section.  */
diff -Nru a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile
--- a/arch/mips/lib/Makefile	2005-03-01 23:38:52 -08:00
+++ b/arch/mips/lib/Makefile	2005-03-01 23:38:52 -08:00
@@ -2,7 +2,7 @@
 # Makefile for MIPS-specific library files..
 #
 
-lib-y	+= csum_partial_copy.o dec_and_lock.o memcpy.o promlib.o strlen_user.o \
-	   strncpy_user.o strnlen_user.o
+lib-y	+= csum_partial_copy.o dec_and_lock.o iomap.o memcpy.o promlib.o \
+	   strlen_user.o strncpy_user.o strnlen_user.o
 
 EXTRA_AFLAGS := $(CFLAGS)
diff -Nru a/arch/mips/lib/csum_partial_copy.c b/arch/mips/lib/csum_partial_copy.c
--- a/arch/mips/lib/csum_partial_copy.c	2005-03-01 23:39:18 -08:00
+++ b/arch/mips/lib/csum_partial_copy.c	2005-03-01 23:39:18 -08:00
@@ -16,7 +16,7 @@
 /*
  * copy while checksumming, otherwise like csum_partial
  */
-unsigned int csum_partial_copy_nocheck(const char *src, char *dst,
+unsigned int csum_partial_copy_nocheck(const unsigned char *src, unsigned char *dst,
 	int len, unsigned int sum)
 {
 	/*
@@ -33,7 +33,7 @@
  * 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 char *src, char *dst,
+unsigned int csum_partial_copy_from_user (const unsigned char *src, unsigned char *dst,
 	int len, unsigned int sum, int *err_ptr)
 {
 	int missing;
diff -Nru a/arch/mips/lib/iomap.c b/arch/mips/lib/iomap.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/mips/lib/iomap.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,78 @@
+/*
+ *  iomap.c, Memory Mapped I/O routines for MIPS architecture.
+ *
+ *  This code is based on lib/iomap.c, by Linus Torvalds.
+ *
+ *  Copyright (C) 2004-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/ioport.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+
+#include <asm/io.h>
+
+void __iomem *ioport_map(unsigned long port, unsigned int nr)
+{
+	unsigned long end;
+
+	end = port + nr - 1UL;
+	if (ioport_resource.start > port ||
+	    ioport_resource.end < end || port > end)
+		return NULL;
+
+	return (void __iomem *)(mips_io_port_base + port);
+}
+
+void ioport_unmap(void __iomem *addr)
+{
+}
+EXPORT_SYMBOL(ioport_map);
+EXPORT_SYMBOL(ioport_unmap);
+
+void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
+{
+	unsigned long start, len, flags;
+
+	if (dev == NULL)
+		return NULL;
+
+	start = pci_resource_start(dev, bar);
+	len = pci_resource_len(dev, bar);
+	if (!start || !len)
+		return NULL;
+
+	if (maxlen != 0 && len > maxlen)
+		len = maxlen;
+
+	flags = pci_resource_flags(dev, bar);
+	if (flags & IORESOURCE_IO)
+		return ioport_map(start, len);
+	if (flags & IORESOURCE_MEM) {
+		if (flags & IORESOURCE_CACHEABLE)
+			return ioremap_cacheable_cow(start, len);
+		return ioremap_nocache(start, len);
+	}
+
+	return NULL;
+}
+
+void pci_iounmap(struct pci_dev *dev, void __iomem *addr)
+{
+	iounmap(addr);
+}
+EXPORT_SYMBOL(pci_iomap);
+EXPORT_SYMBOL(pci_iounmap);
diff -Nru a/arch/mips/lib-32/dump_tlb.c b/arch/mips/lib-32/dump_tlb.c
--- a/arch/mips/lib-32/dump_tlb.c	2005-03-01 23:38:57 -08:00
+++ b/arch/mips/lib-32/dump_tlb.c	2005-03-01 23:38:57 -08:00
@@ -32,6 +32,8 @@
 	case PM_256M:	return "256Mb";
 #endif
 	}
+
+	return "unknown";
 }
 
 #define BARRIER()					\
diff -Nru a/arch/mips/lib-64/dump_tlb.c b/arch/mips/lib-64/dump_tlb.c
--- a/arch/mips/lib-64/dump_tlb.c	2005-03-01 23:39:18 -08:00
+++ b/arch/mips/lib-64/dump_tlb.c	2005-03-01 23:39:18 -08:00
@@ -32,6 +32,8 @@
 	case PM_256M:	return "256Mb";
 #endif
 	}
+
+	return "unknown";
 }
 
 #define BARRIER()					\
@@ -148,16 +150,16 @@
 	printk("tasks->mm.pgd        == %08lx\n", (unsigned long) t->mm->pgd);
 
 	page_dir = pgd_offset(t->mm, 0);
-	printk("page_dir == %08lx\n", (unsigned long) page_dir);
+	printk("page_dir == %016lx\n", (unsigned long) page_dir);
 
 	pgd = pgd_offset(t->mm, addr);
-	printk("pgd == %08lx, ", (unsigned long) pgd);
+	printk("pgd == %016lx\n", (unsigned long) pgd);
 
 	pmd = pmd_offset(pgd, addr);
-	printk("pmd == %08lx, ", (unsigned long) pmd);
+	printk("pmd == %016lx\n", (unsigned long) pmd);
 
 	pte = pte_offset(pmd, addr);
-	printk("pte == %08lx, ", (unsigned long) pte);
+	printk("pte == %016lx\n", (unsigned long) pte);
 
 	page = *pte;
 	printk("page == %08lx\n", pte_val(page));
diff -Nru a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c
--- a/arch/mips/math-emu/cp1emu.c	2005-03-01 23:39:16 -08:00
+++ b/arch/mips/math-emu/cp1emu.c	2005-03-01 23:39:16 -08:00
@@ -2,7 +2,7 @@
  * cp1emu.c: a MIPS coprocessor 1 (fpu) instruction emulator
  *
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
diff -Nru a/arch/mips/math-emu/dp_add.c b/arch/mips/math-emu/dp_add.c
--- a/arch/mips/math-emu/dp_add.c	2005-03-01 23:38:54 -08:00
+++ b/arch/mips/math-emu/dp_add.c	2005-03-01 23:38:54 -08:00
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -Nru a/arch/mips/math-emu/dp_cmp.c b/arch/mips/math-emu/dp_cmp.c
--- a/arch/mips/math-emu/dp_cmp.c	2005-03-01 23:39:09 -08:00
+++ b/arch/mips/math-emu/dp_cmp.c	2005-03-01 23:39:09 -08:00
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -Nru a/arch/mips/math-emu/dp_div.c b/arch/mips/math-emu/dp_div.c
--- a/arch/mips/math-emu/dp_div.c	2005-03-01 23:38:52 -08:00
+++ b/arch/mips/math-emu/dp_div.c	2005-03-01 23:38:52 -08:00
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -Nru a/arch/mips/math-emu/dp_fint.c b/arch/mips/math-emu/dp_fint.c
--- a/arch/mips/math-emu/dp_fint.c	2005-03-01 23:39:16 -08:00
+++ b/arch/mips/math-emu/dp_fint.c	2005-03-01 23:39:16 -08:00
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -Nru a/arch/mips/math-emu/dp_flong.c b/arch/mips/math-emu/dp_flong.c
--- a/arch/mips/math-emu/dp_flong.c	2005-03-01 23:39:07 -08:00
+++ b/arch/mips/math-emu/dp_flong.c	2005-03-01 23:39:07 -08:00
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -Nru a/arch/mips/math-emu/dp_frexp.c b/arch/mips/math-emu/dp_frexp.c
--- a/arch/mips/math-emu/dp_frexp.c	2005-03-01 23:38:54 -08:00
+++ b/arch/mips/math-emu/dp_frexp.c	2005-03-01 23:38:54 -08:00
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -Nru a/arch/mips/math-emu/dp_fsp.c b/arch/mips/math-emu/dp_fsp.c
--- a/arch/mips/math-emu/dp_fsp.c	2005-03-01 23:38:53 -08:00
+++ b/arch/mips/math-emu/dp_fsp.c	2005-03-01 23:38:53 -08:00
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -Nru a/arch/mips/math-emu/dp_logb.c b/arch/mips/math-emu/dp_logb.c
--- a/arch/mips/math-emu/dp_logb.c	2005-03-01 23:38:52 -08:00
+++ b/arch/mips/math-emu/dp_logb.c	2005-03-01 23:38:52 -08:00
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -Nru a/arch/mips/math-emu/dp_modf.c b/arch/mips/math-emu/dp_modf.c
--- a/arch/mips/math-emu/dp_modf.c	2005-03-01 23:39:07 -08:00
+++ b/arch/mips/math-emu/dp_modf.c	2005-03-01 23:39:07 -08:00
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -Nru a/arch/mips/math-emu/dp_mul.c b/arch/mips/math-emu/dp_mul.c
--- a/arch/mips/math-emu/dp_mul.c	2005-03-01 23:38:56 -08:00
+++ b/arch/mips/math-emu/dp_mul.c	2005-03-01 23:38:56 -08:00
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -Nru a/arch/mips/math-emu/dp_scalb.c b/arch/mips/math-emu/dp_scalb.c
--- a/arch/mips/math-emu/dp_scalb.c	2005-03-01 23:39:17 -08:00
+++ b/arch/mips/math-emu/dp_scalb.c	2005-03-01 23:39:17 -08:00
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -Nru a/arch/mips/math-emu/dp_simple.c b/arch/mips/math-emu/dp_simple.c
--- a/arch/mips/math-emu/dp_simple.c	2005-03-01 23:39:09 -08:00
+++ b/arch/mips/math-emu/dp_simple.c	2005-03-01 23:39:09 -08:00
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -Nru a/arch/mips/math-emu/dp_sqrt.c b/arch/mips/math-emu/dp_sqrt.c
--- a/arch/mips/math-emu/dp_sqrt.c	2005-03-01 23:39:09 -08:00
+++ b/arch/mips/math-emu/dp_sqrt.c	2005-03-01 23:39:09 -08:00
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -Nru a/arch/mips/math-emu/dp_sub.c b/arch/mips/math-emu/dp_sub.c
--- a/arch/mips/math-emu/dp_sub.c	2005-03-01 23:39:08 -08:00
+++ b/arch/mips/math-emu/dp_sub.c	2005-03-01 23:39:08 -08:00
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -Nru a/arch/mips/math-emu/dp_tint.c b/arch/mips/math-emu/dp_tint.c
--- a/arch/mips/math-emu/dp_tint.c	2005-03-01 23:38:52 -08:00
+++ b/arch/mips/math-emu/dp_tint.c	2005-03-01 23:38:52 -08:00
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -Nru a/arch/mips/math-emu/dp_tlong.c b/arch/mips/math-emu/dp_tlong.c
--- a/arch/mips/math-emu/dp_tlong.c	2005-03-01 23:38:56 -08:00
+++ b/arch/mips/math-emu/dp_tlong.c	2005-03-01 23:38:56 -08:00
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -Nru a/arch/mips/math-emu/ieee754.c b/arch/mips/math-emu/ieee754.c
--- a/arch/mips/math-emu/ieee754.c	2005-03-01 23:38:51 -08:00
+++ b/arch/mips/math-emu/ieee754.c	2005-03-01 23:38:51 -08:00
@@ -8,7 +8,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -Nru a/arch/mips/math-emu/ieee754.h b/arch/mips/math-emu/ieee754.h
--- a/arch/mips/math-emu/ieee754.h	2005-03-01 23:38:52 -08:00
+++ b/arch/mips/math-emu/ieee754.h	2005-03-01 23:38:52 -08:00
@@ -3,7 +3,7 @@
 */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -Nru a/arch/mips/math-emu/ieee754d.c b/arch/mips/math-emu/ieee754d.c
--- a/arch/mips/math-emu/ieee754d.c	2005-03-01 23:39:10 -08:00
+++ b/arch/mips/math-emu/ieee754d.c	2005-03-01 23:39:10 -08:00
@@ -3,7 +3,7 @@
  *
  * MIPS floating point support
  *
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  *  This program is free software; you can distribute it and/or modify it
diff -Nru a/arch/mips/math-emu/ieee754dp.c b/arch/mips/math-emu/ieee754dp.c
--- a/arch/mips/math-emu/ieee754dp.c	2005-03-01 23:39:07 -08:00
+++ b/arch/mips/math-emu/ieee754dp.c	2005-03-01 23:39:07 -08:00
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -Nru a/arch/mips/math-emu/ieee754dp.h b/arch/mips/math-emu/ieee754dp.h
--- a/arch/mips/math-emu/ieee754dp.h	2005-03-01 23:38:58 -08:00
+++ b/arch/mips/math-emu/ieee754dp.h	2005-03-01 23:38:58 -08:00
@@ -4,7 +4,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -Nru a/arch/mips/math-emu/ieee754int.h b/arch/mips/math-emu/ieee754int.h
--- a/arch/mips/math-emu/ieee754int.h	2005-03-01 23:38:58 -08:00
+++ b/arch/mips/math-emu/ieee754int.h	2005-03-01 23:38:58 -08:00
@@ -4,7 +4,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -Nru a/arch/mips/math-emu/ieee754m.c b/arch/mips/math-emu/ieee754m.c
--- a/arch/mips/math-emu/ieee754m.c	2005-03-01 23:38:58 -08:00
+++ b/arch/mips/math-emu/ieee754m.c	2005-03-01 23:38:58 -08:00
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -Nru a/arch/mips/math-emu/ieee754sp.c b/arch/mips/math-emu/ieee754sp.c
--- a/arch/mips/math-emu/ieee754sp.c	2005-03-01 23:38:55 -08:00
+++ b/arch/mips/math-emu/ieee754sp.c	2005-03-01 23:38:55 -08:00
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -Nru a/arch/mips/math-emu/ieee754sp.h b/arch/mips/math-emu/ieee754sp.h
--- a/arch/mips/math-emu/ieee754sp.h	2005-03-01 23:39:18 -08:00
+++ b/arch/mips/math-emu/ieee754sp.h	2005-03-01 23:39:18 -08:00
@@ -4,7 +4,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -Nru a/arch/mips/math-emu/ieee754xcpt.c b/arch/mips/math-emu/ieee754xcpt.c
--- a/arch/mips/math-emu/ieee754xcpt.c	2005-03-01 23:38:53 -08:00
+++ b/arch/mips/math-emu/ieee754xcpt.c	2005-03-01 23:38:53 -08:00
@@ -1,6 +1,6 @@
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -Nru a/arch/mips/math-emu/sp_add.c b/arch/mips/math-emu/sp_add.c
--- a/arch/mips/math-emu/sp_add.c	2005-03-01 23:39:09 -08:00
+++ b/arch/mips/math-emu/sp_add.c	2005-03-01 23:39:09 -08:00
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -Nru a/arch/mips/math-emu/sp_cmp.c b/arch/mips/math-emu/sp_cmp.c
--- a/arch/mips/math-emu/sp_cmp.c	2005-03-01 23:38:44 -08:00
+++ b/arch/mips/math-emu/sp_cmp.c	2005-03-01 23:38:44 -08:00
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -Nru a/arch/mips/math-emu/sp_div.c b/arch/mips/math-emu/sp_div.c
--- a/arch/mips/math-emu/sp_div.c	2005-03-01 23:39:19 -08:00
+++ b/arch/mips/math-emu/sp_div.c	2005-03-01 23:39:19 -08:00
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -Nru a/arch/mips/math-emu/sp_fdp.c b/arch/mips/math-emu/sp_fdp.c
--- a/arch/mips/math-emu/sp_fdp.c	2005-03-01 23:38:57 -08:00
+++ b/arch/mips/math-emu/sp_fdp.c	2005-03-01 23:38:57 -08:00
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -Nru a/arch/mips/math-emu/sp_fint.c b/arch/mips/math-emu/sp_fint.c
--- a/arch/mips/math-emu/sp_fint.c	2005-03-01 23:38:55 -08:00
+++ b/arch/mips/math-emu/sp_fint.c	2005-03-01 23:38:55 -08:00
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -Nru a/arch/mips/math-emu/sp_flong.c b/arch/mips/math-emu/sp_flong.c
--- a/arch/mips/math-emu/sp_flong.c	2005-03-01 23:39:09 -08:00
+++ b/arch/mips/math-emu/sp_flong.c	2005-03-01 23:39:09 -08:00
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -Nru a/arch/mips/math-emu/sp_frexp.c b/arch/mips/math-emu/sp_frexp.c
--- a/arch/mips/math-emu/sp_frexp.c	2005-03-01 23:38:44 -08:00
+++ b/arch/mips/math-emu/sp_frexp.c	2005-03-01 23:38:44 -08:00
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -Nru a/arch/mips/math-emu/sp_logb.c b/arch/mips/math-emu/sp_logb.c
--- a/arch/mips/math-emu/sp_logb.c	2005-03-01 23:39:09 -08:00
+++ b/arch/mips/math-emu/sp_logb.c	2005-03-01 23:39:09 -08:00
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -Nru a/arch/mips/math-emu/sp_modf.c b/arch/mips/math-emu/sp_modf.c
--- a/arch/mips/math-emu/sp_modf.c	2005-03-01 23:39:16 -08:00
+++ b/arch/mips/math-emu/sp_modf.c	2005-03-01 23:39:16 -08:00
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -Nru a/arch/mips/math-emu/sp_mul.c b/arch/mips/math-emu/sp_mul.c
--- a/arch/mips/math-emu/sp_mul.c	2005-03-01 23:38:59 -08:00
+++ b/arch/mips/math-emu/sp_mul.c	2005-03-01 23:38:59 -08:00
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -Nru a/arch/mips/math-emu/sp_scalb.c b/arch/mips/math-emu/sp_scalb.c
--- a/arch/mips/math-emu/sp_scalb.c	2005-03-01 23:39:18 -08:00
+++ b/arch/mips/math-emu/sp_scalb.c	2005-03-01 23:39:18 -08:00
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -Nru a/arch/mips/math-emu/sp_simple.c b/arch/mips/math-emu/sp_simple.c
--- a/arch/mips/math-emu/sp_simple.c	2005-03-01 23:38:58 -08:00
+++ b/arch/mips/math-emu/sp_simple.c	2005-03-01 23:38:58 -08:00
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -Nru a/arch/mips/math-emu/sp_sqrt.c b/arch/mips/math-emu/sp_sqrt.c
--- a/arch/mips/math-emu/sp_sqrt.c	2005-03-01 23:38:52 -08:00
+++ b/arch/mips/math-emu/sp_sqrt.c	2005-03-01 23:38:52 -08:00
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -Nru a/arch/mips/math-emu/sp_sub.c b/arch/mips/math-emu/sp_sub.c
--- a/arch/mips/math-emu/sp_sub.c	2005-03-01 23:38:55 -08:00
+++ b/arch/mips/math-emu/sp_sub.c	2005-03-01 23:38:55 -08:00
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -Nru a/arch/mips/math-emu/sp_tint.c b/arch/mips/math-emu/sp_tint.c
--- a/arch/mips/math-emu/sp_tint.c	2005-03-01 23:39:17 -08:00
+++ b/arch/mips/math-emu/sp_tint.c	2005-03-01 23:39:17 -08:00
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -Nru a/arch/mips/math-emu/sp_tlong.c b/arch/mips/math-emu/sp_tlong.c
--- a/arch/mips/math-emu/sp_tlong.c	2005-03-01 23:39:17 -08:00
+++ b/arch/mips/math-emu/sp_tlong.c	2005-03-01 23:39:17 -08:00
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -Nru a/arch/mips/mips-boards/atlas/atlas_int.c b/arch/mips/mips-boards/atlas/atlas_int.c
--- a/arch/mips/mips-boards/atlas/atlas_int.c	2005-03-01 23:39:07 -08:00
+++ b/arch/mips/mips-boards/atlas/atlas_int.c	2005-03-01 23:39:07 -08:00
@@ -23,7 +23,6 @@
  * Atlas board.
  *
  */
-#include <linux/config.h>
 #include <linux/compiler.h>
 #include <linux/init.h>
 #include <linux/sched.h>
diff -Nru a/arch/mips/mips-boards/generic/gdb_hook.c b/arch/mips/mips-boards/generic/gdb_hook.c
--- a/arch/mips/mips-boards/generic/gdb_hook.c	2005-03-01 23:38:55 -08:00
+++ b/arch/mips/mips-boards/generic/gdb_hook.c	2005-03-01 23:38:55 -08:00
@@ -18,7 +18,6 @@
  * This is the interface to the remote debugger stub.
  */
 #include <linux/types.h>
-#include <linux/config.h>
 #include <linux/serial.h>
 #include <linux/serialP.h>
 #include <linux/serial_reg.h>
diff -Nru a/arch/mips/mips-boards/malta/malta_int.c b/arch/mips/mips-boards/malta/malta_int.c
--- a/arch/mips/mips-boards/malta/malta_int.c	2005-03-01 23:38:54 -08:00
+++ b/arch/mips/mips-boards/malta/malta_int.c	2005-03-01 23:38:54 -08:00
@@ -1,6 +1,6 @@
 /*
  * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 2000, 2001 MIPS Technologies, Inc.
+ * Copyright (C) 2000, 2001, 2004 MIPS Technologies, Inc.
  * Copyright (C) 2001 Ralf Baechle
  *
  *  This program is free software; you can distribute it and/or modify it
@@ -21,7 +21,6 @@
  * The interrupt controller is located in the South Bridge a PIIX4 device
  * with two internal 82C95 interrupt controllers.
  */
-#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/irq.h>
 #include <linux/sched.h>
@@ -41,7 +40,7 @@
 
 extern asmlinkage void mipsIRQ(void);
 
-static spinlock_t mips_irq_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(mips_irq_lock);
 
 static inline int mips_pcibios_iack(void)
 {
@@ -155,9 +154,9 @@
         case MIPS_REVISION_CORID_CORE_FPGAR2:
                 data = GT_READ(GT_INTRCAUSE_OFS);
                 printk("GT_INTRCAUSE = %08x\n", data);
-                data = GT_READ(0x70);
-                datahi = GT_READ(0x78);
-                printk("GT_CPU_ERR_ADDR = %02x%08x\n", datahi, data);
+                data = GT_READ(GT_CPUERR_ADDRLO_OFS);
+                datahi = GT_READ(GT_CPUERR_ADDRHI_OFS);
+                printk("GT_CPUERR_ADDR = %02x%08x\n", datahi, data);
                 break;
         case MIPS_REVISION_CORID_BONITO64:
         case MIPS_REVISION_CORID_CORE_20K:
diff -Nru a/arch/mips/mm/Makefile b/arch/mips/mm/Makefile
--- a/arch/mips/mm/Makefile	2005-03-01 23:39:07 -08:00
+++ b/arch/mips/mm/Makefile	2005-03-01 23:39:07 -08:00
@@ -3,7 +3,7 @@
 #
 
 obj-y				+= cache.o extable.o fault.o init.o pgtable.o \
-				   tlbex.o
+				   tlbex.o tlbex-fault.o
 
 obj-$(CONFIG_MIPS32)		+= ioremap.o pgtable-32.o
 obj-$(CONFIG_MIPS64)		+= pgtable-64.o
@@ -27,40 +27,6 @@
 obj-$(CONFIG_CPU_TX49XX)	+= c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o
 obj-$(CONFIG_CPU_VR41XX)	+= c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o
 
-#
-# TLB exception handling code differs between 32-bit and 64-bit kernels.
-#
-ifdef CONFIG_MIPS32
-obj-$(CONFIG_CPU_R3000)		+= tlbex32-r3k.o
-obj-$(CONFIG_CPU_TX49XX)	+= tlbex32-r4k.o
-obj-$(CONFIG_CPU_R4300)		+= tlbex32-r4k.o
-obj-$(CONFIG_CPU_R4X00)		+= tlbex32-r4k.o
-obj-$(CONFIG_CPU_VR41XX)	+= tlbex32-r4k.o
-obj-$(CONFIG_CPU_R5000)		+= tlbex32-r4k.o
-obj-$(CONFIG_CPU_NEVADA)	+= tlbex32-r4k.o
-obj-$(CONFIG_CPU_R5432)		+= tlbex32-r4k.o
-obj-$(CONFIG_CPU_RM7000)	+= tlbex32-r4k.o
-obj-$(CONFIG_CPU_RM9000)	+= tlbex32-r4k.o
-obj-$(CONFIG_CPU_R10000)	+= tlbex32-r4k.o
-obj-$(CONFIG_CPU_MIPS32)	+= tlbex32-mips32.o
-obj-$(CONFIG_CPU_MIPS64)	+= tlbex32-r4k.o
-obj-$(CONFIG_CPU_SB1)		+= tlbex32-r4k.o
-obj-$(CONFIG_CPU_TX39XX)	+= tlbex32-r3k.o
-endif
-ifdef CONFIG_MIPS64
-obj-$(CONFIG_CPU_R4300)		+= tlb64-glue-r4k.o
-obj-$(CONFIG_CPU_R4X00)		+= tlb64-glue-r4k.o
-obj-$(CONFIG_CPU_R5000)		+= tlb64-glue-r4k.o
-obj-$(CONFIG_CPU_NEVADA)	+= tlb64-glue-r4k.o
-obj-$(CONFIG_CPU_R5432)		+= tlb64-glue-r4k.o
-obj-$(CONFIG_CPU_RM7000)	+= tlb64-glue-r4k.o
-obj-$(CONFIG_CPU_RM9000)	+= tlb64-glue-r4k.o
-obj-$(CONFIG_CPU_R10000)	+= tlb64-glue-r4k.o
-obj-$(CONFIG_CPU_SB1)		+= tlb64-glue-sb1.o
-obj-$(CONFIG_CPU_MIPS64)	+= tlb64-glue-r4k.o
-endif
-
-
 obj-$(CONFIG_IP22_CPU_SCACHE)	+= sc-ip22.o
 obj-$(CONFIG_R5000_CPU_SCACHE)  += sc-r5k.o
 obj-$(CONFIG_RM7000_CPU_SCACHE)	+= sc-rm7k.o
@@ -68,8 +34,11 @@
 #
 # Choose one DMA coherency model
 #
+ifndef CONFIG_OWN_DMA
 obj-$(CONFIG_DMA_COHERENT)	+= dma-coherent.o
 obj-$(CONFIG_DMA_NONCOHERENT)	+= dma-noncoherent.o
+endif
 obj-$(CONFIG_DMA_IP27)		+= dma-ip27.o
+obj-$(CONFIG_DMA_IP32)		+= dma-ip32.o
 
 EXTRA_AFLAGS := $(CFLAGS)
diff -Nru a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
--- a/arch/mips/mm/c-r4k.c	2005-03-01 23:39:16 -08:00
+++ b/arch/mips/mm/c-r4k.c	2005-03-01 23:39:16 -08:00
@@ -238,6 +238,22 @@
 		r4k_blast_scache_page = blast_scache128_page;
 }
 
+static void (* r4k_blast_scache_page_indexed)(unsigned long addr);
+
+static inline void r4k_blast_scache_page_indexed_setup(void)
+{
+	unsigned long sc_lsize = cpu_scache_line_size();
+
+	if (sc_lsize == 16)
+		r4k_blast_scache_page_indexed = blast_scache16_page_indexed;
+	else if (sc_lsize == 32)
+		r4k_blast_scache_page_indexed = blast_scache32_page_indexed;
+	else if (sc_lsize == 64)
+		r4k_blast_scache_page_indexed = blast_scache64_page_indexed;
+	else if (sc_lsize == 128)
+		r4k_blast_scache_page_indexed = blast_scache128_page_indexed;
+}
+
 static void (* r4k_blast_scache)(void);
 
 static inline void r4k_blast_scache_setup(void)
@@ -318,9 +334,6 @@
 {
 	struct mm_struct *mm = args;
 
-	if (!cpu_has_dc_aliases)
-		return;
-
 	if (!cpu_context(smp_processor_id(), mm))
 		return;
 
@@ -340,6 +353,9 @@
 
 static void r4k_flush_cache_mm(struct mm_struct *mm)
 {
+	if (!cpu_has_dc_aliases)
+		return;
+
 	on_each_cpu(local_r4k_flush_cache_mm, mm, 1, 1);
 }
 
@@ -359,13 +375,6 @@
 	pmd_t *pmdp;
 	pte_t *ptep;
 
-	/*
-	 * If ownes no valid ASID yet, cannot possibly have gotten
-	 * this page into the cache.
-	 */
-	if (cpu_context(smp_processor_id(), mm) == 0)
-		return;
-
 	page &= PAGE_MASK;
 	pgdp = pgd_offset(mm, page);
 	pmdp = pmd_offset(pgdp, page);
@@ -385,8 +394,11 @@
 	 * in that case, which doesn't overly flush the cache too much.
 	 */
 	if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID)) {
-		if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc))
+		if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) {
 			r4k_blast_dcache_page(page);
+			if (exec && !cpu_icache_snoops_remote_store)
+				r4k_blast_scache_page(page);
+		}
 		if (exec)
 			r4k_blast_icache_page(page);
 
@@ -398,8 +410,11 @@
 	 * to work correctly.
 	 */
 	page = INDEX_BASE + (page & (dcache_size - 1));
-	if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc))
+	if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) {
 		r4k_blast_dcache_page_indexed(page);
+		if (exec && !cpu_icache_snoops_remote_store)
+			r4k_blast_scache_page_indexed(page);
+	}
 	if (exec) {
 		if (cpu_has_vtag_icache) {
 			int cpu = smp_processor_id();
@@ -416,6 +431,13 @@
 {
 	struct flush_cache_page_args args;
 
+	/*
+	 * If ownes no valid ASID yet, cannot possibly have gotten
+	 * this page into the cache.
+	 */
+	if (cpu_context(smp_processor_id(), vma->vm_mm) == 0)
+		return;
+
 	args.vma = vma;
 	args.page = page;
 
@@ -442,14 +464,15 @@
 	struct flush_icache_range_args *fir_args = args;
 	unsigned long dc_lsize = current_cpu_data.dcache.linesz;
 	unsigned long ic_lsize = current_cpu_data.icache.linesz;
+	unsigned long sc_lsize = current_cpu_data.scache.linesz;
 	unsigned long start = fir_args->start;
 	unsigned long end = fir_args->end;
 	unsigned long addr, aend;
 
 	if (!cpu_has_ic_fills_f_dc) {
-		if (end - start > dcache_size)
+		if (end - start > dcache_size) {
 			r4k_blast_dcache();
-		else {
+		} else {
 			addr = start & ~(dc_lsize - 1);
 			aend = (end - 1) & ~(dc_lsize - 1);
 
@@ -461,6 +484,23 @@
 				addr += dc_lsize;
 			}
 		}
+
+		if (!cpu_icache_snoops_remote_store) {
+			if (end - start > scache_size) {
+				r4k_blast_scache();
+			} else {
+				addr = start & ~(sc_lsize - 1);
+				aend = (end - 1) & ~(sc_lsize - 1);
+
+				while (1) {
+					/* Hit_Writeback_Inv_D */
+					protected_writeback_scache_line(addr);
+					if (addr == aend)
+						break;
+					addr += sc_lsize;
+				}
+			}
+		}
 	}
 
 	if (end - start > icache_size)
@@ -527,6 +567,8 @@
 	if (!cpu_has_ic_fills_f_dc) {
 		unsigned long addr = (unsigned long) page_address(page);
 		r4k_blast_dcache_page(addr);
+		if (!cpu_icache_snoops_remote_store)
+			r4k_blast_scache_page(addr);
 		ClearPageDcacheDirty(page);
 	}
 
@@ -669,10 +711,13 @@
 {
 	unsigned long ic_lsize = current_cpu_data.icache.linesz;
 	unsigned long dc_lsize = current_cpu_data.dcache.linesz;
+	unsigned long sc_lsize = current_cpu_data.scache.linesz;
 	unsigned long addr = (unsigned long) arg;
 
 	R4600_HIT_CACHEOP_WAR_IMPL;
 	protected_writeback_dcache_line(addr & ~(dc_lsize - 1));
+	if (!cpu_icache_snoops_remote_store)
+		protected_writeback_scache_line(addr & ~(sc_lsize - 1));
 	protected_flush_icache_line(addr & ~(ic_lsize - 1));
 	if (MIPS4K_ICACHE_REFILL_WAR) {
 		__asm__ __volatile__ (
@@ -739,8 +784,8 @@
 	}
 }
 
-static char *way_string[] = { NULL, "direct mapped", "2-way", "3-way", "4-way",
-	"5-way", "6-way", "7-way", "8-way"
+static char *way_string[] __initdata = { NULL, "direct mapped", "2-way",
+	"3-way", "4-way", "5-way", "6-way", "7-way", "8-way"
 };
 
 static void __init probe_pcache(void)
@@ -1178,6 +1223,7 @@
 	r4k_blast_icache_page_indexed_setup();
 	r4k_blast_icache_setup();
 	r4k_blast_scache_page_setup();
+	r4k_blast_scache_page_indexed_setup();
 	r4k_blast_scache_setup();
 
 	/*
diff -Nru a/arch/mips/mm/c-sb1.c b/arch/mips/mm/c-sb1.c
--- a/arch/mips/mm/c-sb1.c	2005-03-01 23:38:57 -08:00
+++ b/arch/mips/mm/c-sb1.c	2005-03-01 23:38:57 -08:00
@@ -503,7 +503,7 @@
 	/* Special cache error handler for SB1 */
 	memcpy((void *)(CAC_BASE   + 0x100), &except_vec2_sb1, 0x80);
 	memcpy((void *)(UNCAC_BASE + 0x100), &except_vec2_sb1, 0x80);
-	memcpy((void *)KSEG1ADDR(&handle_vec2_sb1), &handle_vec2_sb1, 0x80);
+	memcpy((void *)CKSEG1ADDR(&handle_vec2_sb1), &handle_vec2_sb1, 0x80);
 
 	probe_cache_sizes();
 
diff -Nru a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c
--- a/arch/mips/mm/cache.c	2005-03-01 23:38:55 -08:00
+++ b/arch/mips/mm/cache.c	2005-03-01 23:38:55 -08:00
@@ -45,10 +45,17 @@
 
 #endif /* CONFIG_DMA_NONCOHERENT */
 
-asmlinkage int sys_cacheflush(void *addr, int bytes, int cache)
+/*
+ * We could optimize the case where the cache argument is not BCACHE but
+ * that seems very atypical use ...
+ */
+asmlinkage int sys_cacheflush(unsigned long addr, unsigned long int bytes,
+	unsigned int cache)
 {
-	/* This should flush more selectivly ...  */
-	__flush_cache_all();
+	if (verify_area(VERIFY_WRITE, (void *) addr, bytes))
+		return -EFAULT;
+
+	flush_icache_range(addr, addr + bytes);
 
 	return 0;
 }
diff -Nru a/arch/mips/mm/cerr-sb1.c b/arch/mips/mm/cerr-sb1.c
--- a/arch/mips/mm/cerr-sb1.c	2005-03-01 23:39:09 -08:00
+++ b/arch/mips/mm/cerr-sb1.c	2005-03-01 23:39:09 -08:00
@@ -251,14 +251,14 @@
 
 /* Masks to select bits for Hamming parity, mask_72_64[i] for bit[i] */
 static const uint64_t mask_72_64[8] = {
-	0x0738C808099264FFL,
-	0x38C808099264FF07L,
-	0xC808099264FF0738L,
-	0x08099264FF0738C8L,
-	0x099264FF0738C808L,
-	0x9264FF0738C80809L,
-	0x64FF0738C8080992L,
-	0xFF0738C808099264L
+	0x0738C808099264FFULL,
+	0x38C808099264FF07ULL,
+	0xC808099264FF0738ULL,
+	0x08099264FF0738C8ULL,
+	0x099264FF0738C808ULL,
+	0x9264FF0738C80809ULL,
+	0x64FF0738C8080992ULL,
+	0xFF0738C808099264ULL
 };
 
 /* Calculate the parity on a range of bits */
@@ -330,9 +330,9 @@
 				    ((lru >> 4) & 0x3),
 				    ((lru >> 6) & 0x3));
 		}
-		va = (taglo & 0xC0000FFFFFFFE000) | addr;
+		va = (taglo & 0xC0000FFFFFFFE000ULL) | addr;
 		if ((taglo & (1 << 31)) && (((taglo >> 62) & 0x3) == 3))
-			va |= 0x3FFFF00000000000;
+			va |= 0x3FFFF00000000000ULL;
 		valid = ((taghi >> 29) & 1);
 		if (valid) {
 			tlo_tmp = taglo & 0xfff3ff;
@@ -473,7 +473,7 @@
 		: "r" ((way << 13) | addr));
 
 		taglo = ((unsigned long long)taglohi << 32) | taglolo;
-		pa = (taglo & 0xFFFFFFE000) | addr;
+		pa = (taglo & 0xFFFFFFE000ULL) | addr;
 		if (way == 0) {
 			lru = (taghi >> 14) & 0xff;
 			prom_printf("[Bank %d Set 0x%02x]  LRU > %d %d %d %d > MRU\n",
diff -Nru a/arch/mips/mm/cex-sb1.S b/arch/mips/mm/cex-sb1.S
--- a/arch/mips/mm/cex-sb1.S	2005-03-01 23:38:43 -08:00
+++ b/arch/mips/mm/cex-sb1.S	2005-03-01 23:38:43 -08:00
@@ -15,7 +15,6 @@
  * 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/init.h>
 
 #include <asm/asm.h>
diff -Nru a/arch/mips/mm/dma-ip32.c b/arch/mips/mm/dma-ip32.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/mips/mm/dma-ip32.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,382 @@
+/*
+ * This file 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  Ani Joshi <ajoshi@unixbox.com>
+ * Copyright (C) 2000, 2001  Ralf Baechle <ralf@gnu.org>
+ * Copyright (C) 2005 Ilya A. Volynets-Evenbakh <ilya@total-knowledge.com>
+ * swiped from i386, and cloned for MIPS by Geert, polished by Ralf.
+ * IP32 changes by Ilya.
+ */
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/dma-mapping.h>
+
+#include <asm/cache.h>
+#include <asm/io.h>
+#include <asm/ip32/crime.h>
+
+/*
+ * Warning on the terminology - Linux calls an uncached area coherent;
+ * MIPS terminology calls memory areas with hardware maintained coherency
+ * coherent.
+ */
+
+/*
+ * Few notes.
+ * 1. CPU sees memory as two chunks: 0-256M@0x0, and the rest @0x40000000+256M
+ * 2. PCI sees memory as one big chunk @0x0 (or we could use 0x40000000 for native-endian)
+ * 3. All other devices see memory as one big chunk at 0x40000000
+ * 4. Non-PCI devices will pass NULL as struct device*
+ * Thus we translate differently, depending on device.
+ */
+
+#define RAM_OFFSET_MASK	0x3fffffff
+
+void *dma_alloc_noncoherent(struct device *dev, size_t size,
+	dma_addr_t * dma_handle, int gfp)
+{
+	void *ret;
+	/* ignore region specifiers */
+	gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
+
+	if (dev == NULL || (dev->coherent_dma_mask < 0xffffffff))
+		gfp |= GFP_DMA;
+	ret = (void *) __get_free_pages(gfp, get_order(size));
+
+	if (ret != NULL) {
+		unsigned long addr = virt_to_phys(ret)&RAM_OFFSET_MASK;
+		memset(ret, 0, size);
+		if(dev==NULL)
+		    addr+= CRIME_HI_MEM_BASE;
+		*dma_handle = addr;
+	}
+
+	return ret;
+}
+
+EXPORT_SYMBOL(dma_alloc_noncoherent);
+
+void *dma_alloc_coherent(struct device *dev, size_t size,
+	dma_addr_t * dma_handle, int gfp)
+{
+	void *ret;
+
+	ret = dma_alloc_noncoherent(dev, size, dma_handle, gfp);
+	if (ret) {
+		dma_cache_wback_inv((unsigned long) ret, size);
+		ret = UNCAC_ADDR(ret);
+	}
+
+	return ret;
+}
+
+EXPORT_SYMBOL(dma_alloc_coherent);
+
+void dma_free_noncoherent(struct device *dev, size_t size, void *vaddr,
+	dma_addr_t dma_handle)
+{
+	free_pages((unsigned long) vaddr, get_order(size));
+}
+
+EXPORT_SYMBOL(dma_free_noncoherent);
+
+void dma_free_coherent(struct device *dev, size_t size, void *vaddr,
+	dma_addr_t dma_handle)
+{
+	unsigned long addr = (unsigned long) vaddr;
+
+	addr = CAC_ADDR(addr);
+	free_pages(addr, get_order(size));
+}
+
+EXPORT_SYMBOL(dma_free_coherent);
+
+static inline void __dma_sync(unsigned long addr, size_t size,
+	enum dma_data_direction direction)
+{
+	switch (direction) {
+	case DMA_TO_DEVICE:
+		dma_cache_wback(addr, size);
+		break;
+
+	case DMA_FROM_DEVICE:
+		dma_cache_inv(addr, size);
+		break;
+
+	case DMA_BIDIRECTIONAL:
+		dma_cache_wback_inv(addr, size);
+		break;
+
+	default:
+		BUG();
+	}
+}
+
+dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
+	enum dma_data_direction direction)
+{
+	unsigned long addr = (unsigned long) ptr;
+
+	switch (direction) {
+	case DMA_TO_DEVICE:
+		dma_cache_wback(addr, size);
+		break;
+
+	case DMA_FROM_DEVICE:
+		dma_cache_inv(addr, size);
+		break;
+
+	case DMA_BIDIRECTIONAL:
+		dma_cache_wback_inv(addr, size);
+		break;
+
+	default:
+		BUG();
+	}
+
+	addr = virt_to_phys(ptr)&RAM_OFFSET_MASK;;
+	if(dev == NULL)
+	    addr+=CRIME_HI_MEM_BASE;
+	return (dma_addr_t)addr;
+}
+
+EXPORT_SYMBOL(dma_map_single);
+
+void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
+	enum dma_data_direction direction)
+{
+	switch (direction) {
+	case DMA_TO_DEVICE:
+		break;
+
+	case DMA_FROM_DEVICE:
+		break;
+
+	case DMA_BIDIRECTIONAL:
+		break;
+
+	default:
+		BUG();
+	}
+}
+
+EXPORT_SYMBOL(dma_unmap_single);
+
+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++) {
+		unsigned long addr;
+
+		addr = (unsigned long) page_address(sg->page)+sg->offset;
+		if (addr)
+			__dma_sync(addr, sg->length, direction);
+		addr = __pa(addr)&RAM_OFFSET_MASK;;
+		if(dev == NULL)
+			addr +=  CRIME_HI_MEM_BASE;
+		sg->dma_address = (dma_addr_t)addr;
+	}
+
+	return nents;
+}
+
+EXPORT_SYMBOL(dma_map_sg);
+
+dma_addr_t dma_map_page(struct device *dev, struct page *page,
+	unsigned long offset, size_t size, enum dma_data_direction direction)
+{
+	unsigned long addr;
+
+	BUG_ON(direction == DMA_NONE);
+
+	addr = (unsigned long) page_address(page) + offset;
+	dma_cache_wback_inv(addr, size);
+	addr = __pa(addr)&RAM_OFFSET_MASK;;
+	if(dev == NULL)
+		addr +=  CRIME_HI_MEM_BASE;
+
+	return (dma_addr_t)addr;
+}
+
+EXPORT_SYMBOL(dma_map_page);
+
+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);
+
+	if (direction != DMA_TO_DEVICE) {
+		unsigned long addr;
+
+		dma_address&=RAM_OFFSET_MASK;
+		addr = dma_address + PAGE_OFFSET;
+		if(dma_address>=256*1024*1024)
+			addr+=CRIME_HI_MEM_BASE;
+		dma_cache_wback_inv(addr, size);
+	}
+}
+
+EXPORT_SYMBOL(dma_unmap_page);
+
+void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
+	enum dma_data_direction direction)
+{
+	unsigned long addr;
+	int i;
+
+	BUG_ON(direction == DMA_NONE);
+
+	if (direction == DMA_TO_DEVICE)
+		return;
+
+	for (i = 0; i < nhwentries; i++, sg++) {
+		addr = (unsigned long) page_address(sg->page);
+		if (!addr)
+			continue;
+		dma_cache_wback_inv(addr + sg->offset, sg->length);
+	}
+}
+
+EXPORT_SYMBOL(dma_unmap_sg);
+
+void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
+	size_t size, enum dma_data_direction direction)
+{
+	unsigned long addr;
+
+	BUG_ON(direction == DMA_NONE);
+
+	dma_handle&=RAM_OFFSET_MASK;
+	addr = dma_handle + PAGE_OFFSET;
+	if(dma_handle>=256*1024*1024)
+	    addr+=CRIME_HI_MEM_BASE;
+	__dma_sync(addr, size, direction);
+}
+
+EXPORT_SYMBOL(dma_sync_single_for_cpu);
+
+void dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle,
+	size_t size, enum dma_data_direction direction)
+{
+	unsigned long addr;
+
+	BUG_ON(direction == DMA_NONE);
+
+	dma_handle&=RAM_OFFSET_MASK;
+	addr = dma_handle + PAGE_OFFSET;
+	if(dma_handle>=256*1024*1024)
+	    addr+=CRIME_HI_MEM_BASE;
+	__dma_sync(addr, size, direction);
+}
+
+EXPORT_SYMBOL(dma_sync_single_for_device);
+
+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)
+{
+	unsigned long addr;
+
+	BUG_ON(direction == DMA_NONE);
+
+	dma_handle&=RAM_OFFSET_MASK;
+	addr = dma_handle + offset + PAGE_OFFSET;
+	if(dma_handle>=256*1024*1024)
+	    addr+=CRIME_HI_MEM_BASE;
+	__dma_sync(addr, size, direction);
+}
+
+EXPORT_SYMBOL(dma_sync_single_range_for_cpu);
+
+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)
+{
+	unsigned long addr;
+
+	BUG_ON(direction == DMA_NONE);
+
+	dma_handle&=RAM_OFFSET_MASK;
+	addr = dma_handle + offset + PAGE_OFFSET;
+	if(dma_handle>=256*1024*1024)
+	    addr+=CRIME_HI_MEM_BASE;
+	__dma_sync(addr, size, direction);
+}
+
+EXPORT_SYMBOL(dma_sync_single_range_for_device);
+
+void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
+	enum dma_data_direction direction)
+{
+	int i;
+
+	BUG_ON(direction == DMA_NONE);
+
+	/* Make sure that gcc doesn't leave the empty loop body.  */
+	for (i = 0; i < nelems; i++, sg++)
+		__dma_sync((unsigned long)page_address(sg->page),
+		           sg->length, direction);
+}
+
+EXPORT_SYMBOL(dma_sync_sg_for_cpu);
+
+void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems,
+	enum dma_data_direction direction)
+{
+	int i;
+
+	BUG_ON(direction == DMA_NONE);
+
+	/* Make sure that gcc doesn't leave the empty loop body.  */
+	for (i = 0; i < nelems; i++, sg++)
+		__dma_sync((unsigned long)page_address(sg->page),
+		           sg->length, direction);
+}
+
+EXPORT_SYMBOL(dma_sync_sg_for_device);
+
+int dma_mapping_error(dma_addr_t dma_addr)
+{
+	return 0;
+}
+
+EXPORT_SYMBOL(dma_mapping_error);
+
+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;
+}
+
+EXPORT_SYMBOL(dma_supported);
+
+int dma_is_consistent(dma_addr_t dma_addr)
+{
+	return 1;
+}
+
+EXPORT_SYMBOL(dma_is_consistent);
+
+void dma_cache_sync(void *vaddr, size_t size, enum dma_data_direction direction)
+{
+	if (direction == DMA_NONE)
+		return;
+
+	dma_cache_wback_inv((unsigned long)vaddr, size);
+}
+
+EXPORT_SYMBOL(dma_cache_sync);
+
diff -Nru a/arch/mips/mm/highmem.c b/arch/mips/mm/highmem.c
--- a/arch/mips/mm/highmem.c	2005-03-01 23:38:54 -08:00
+++ b/arch/mips/mm/highmem.c	2005-03-01 23:38:54 -08:00
@@ -8,7 +8,7 @@
 	void *addr;
 
 	might_sleep();
-	if (page < highmem_start_page)
+	if (!PageHighMem(page))
 		return page_address(page);
 	addr = kmap_high(page);
 	flush_tlb_one((unsigned long)addr);
@@ -20,7 +20,7 @@
 {
 	if (in_interrupt())
 		BUG();
-	if (page < highmem_start_page)
+	if (!PageHighMem(page))
 		return;
 	kunmap_high(page);
 }
@@ -41,7 +41,7 @@
 
 	/* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */
 	inc_preempt_count();
-	if (page < highmem_start_page)
+	if (!PageHighMem(page))
 		return page_address(page);
 
 	idx = type + KM_TYPE_NR*smp_processor_id();
diff -Nru a/arch/mips/mm/init.c b/arch/mips/mm/init.c
--- a/arch/mips/mm/init.c	2005-03-01 23:39:08 -08:00
+++ b/arch/mips/mm/init.c	2005-03-01 23:39:08 -08:00
@@ -61,7 +61,7 @@
 	else
 		order = 0;
 
-	empty_zero_page = __get_free_pages(GFP_KERNEL, order);
+	empty_zero_page = __get_free_pages(GFP_KERNEL | __GFP_ZERO, order);
 	if (!empty_zero_page)
 		panic("Oh boy, that early out of memory?");
 
@@ -74,7 +74,6 @@
 
 	size = PAGE_SIZE << order;
 	zero_page_mask = (size - 1) & PAGE_MASK;
-	memset((void *)empty_zero_page, 0, size);
 
 	return 1UL << order;
 }
@@ -204,7 +203,6 @@
 	unsigned long tmp, ram;
 
 #ifdef CONFIG_HIGHMEM
-	highmem_start_page = mem_map + highstart_pfn;
 #ifdef CONFIG_DISCONTIGMEM
 #error "CONFIG_HIGHMEM and CONFIG_DISCONTIGMEM dont work together yet"
 #endif
diff -Nru a/arch/mips/mm/pg-r4k.c b/arch/mips/mm/pg-r4k.c
--- a/arch/mips/mm/pg-r4k.c	2005-03-01 23:38:57 -08:00
+++ b/arch/mips/mm/pg-r4k.c	2005-03-01 23:38:57 -08:00
@@ -3,9 +3,8 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2003, 2004 Ralf Baechle (ralf@linux-mips.org)
+ * Copyright (C) 2003, 04, 05 Ralf Baechle (ralf@linux-mips.org)
  */
-#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
@@ -58,12 +57,6 @@
 EXPORT_SYMBOL(copy_page);
 
 /*
- * An address fits into a single register so it's safe to use 64-bit registers
- * if we have 64-bit adresses.
- */
-#define cpu_has_64bit_registers	cpu_has_64bit_addresses
-
-/*
  * This is suboptimal for 32-bit kernels; we assume that R10000 is only used
  * with 64-bit kernels.  The prefetch offsets have been experimentally tuned
  * an Origin 200.
@@ -145,7 +138,7 @@
 	union mips_instruction mi;
 	unsigned int width;
 
-	if (cpu_has_64bit_registers) {
+	if (cpu_has_64bit_gp_regs) {
 		mi.i_format.opcode     = ld_op;
 		width = 8;
 	} else {
@@ -266,7 +259,7 @@
 
 	BUG_ON(offset > 0x7fff);
 
-	mi.i_format.opcode     = cpu_has_64bit_addresses ? daddiu_op : addiu_op;
+	mi.i_format.opcode     = cpu_has_64bit_gp_regs ? daddiu_op : addiu_op;
 	mi.i_format.rs         = 4;		/* $a0 */
 	mi.i_format.rt         = 6;		/* $a2 */
 	mi.i_format.simmediate = offset;
@@ -280,7 +273,7 @@
 
 	BUG_ON(offset > 0x7fff);
 
-	mi.i_format.opcode     = cpu_has_64bit_addresses ? daddiu_op : addiu_op;
+	mi.i_format.opcode     = cpu_has_64bit_gp_regs ? daddiu_op : addiu_op;
 	mi.i_format.rs         = 5;		/* $a1 */
 	mi.i_format.rt         = 5;		/* $a1 */
 	mi.i_format.simmediate = offset;
@@ -296,7 +289,7 @@
 
 	BUG_ON(offset > 0x7fff);
 
-	mi.i_format.opcode     = cpu_has_64bit_addresses ? daddiu_op : addiu_op;
+	mi.i_format.opcode     = cpu_has_64bit_gp_regs ? daddiu_op : addiu_op;
 	mi.i_format.rs         = 4;		/* $a0 */
 	mi.i_format.rt         = 4;		/* $a0 */
 	mi.i_format.simmediate = offset;
diff -Nru a/arch/mips/mm/pg-sb1.c b/arch/mips/mm/pg-sb1.c
--- a/arch/mips/mm/pg-sb1.c	2005-03-01 23:39:18 -08:00
+++ b/arch/mips/mm/pg-sb1.c	2005-03-01 23:39:18 -08:00
@@ -2,6 +2,7 @@
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org)
  * Copyright (C) 2000 SiByte, Inc.
+ * Copyright (C) 2005 Thiemo Seufer
  *
  * Written by Justin Carlson of SiByte, Inc.
  *         and Kip Walker of Broadcom Corp.
@@ -39,11 +40,7 @@
 #define SB1_PREF_STORE_STREAMED_HINT "5"
 #endif
 
-#ifdef CONFIG_SIBYTE_DMA_PAGEOPS
 static inline void clear_page_cpu(void *page)
-#else
-void clear_page(void *page)
-#endif
 {
 	unsigned char *addr = (unsigned char *) page;
 	unsigned char *end = addr + PAGE_SIZE;
@@ -57,90 +54,143 @@
 	 * since we know we're on an SB1, we force the assembler to take
 	 * 64-bit operands to speed things up
 	 */
-	do {
-		__asm__ __volatile__(
-		"	.set	mips4		\n"
+	__asm__ __volatile__(
+	"	.set	push		\n"
+	"	.set	mips4		\n"
+	"	.set	noreorder	\n"
 #ifdef CONFIG_CPU_HAS_PREFETCH
-		"	pref	" SB1_PREF_STORE_STREAMED_HINT ",  0(%0)  \n"  /* Prefetch the first 4 lines */
-		"	pref	" SB1_PREF_STORE_STREAMED_HINT ", 32(%0)  \n"
-		"	pref	" SB1_PREF_STORE_STREAMED_HINT ", 64(%0)  \n"
-		"	pref	" SB1_PREF_STORE_STREAMED_HINT ", 96(%0)  \n"
-#endif
-		"1:	sd	$0,  0(%0)	\n"  /* Throw out a cacheline of 0's */
-		"	sd	$0,  8(%0)	\n"
-		"	sd	$0, 16(%0)	\n"
-		"	sd	$0, 24(%0)	\n"
-#ifdef CONFIG_CPU_HAS_PREFETCH
-		"	pref	" SB1_PREF_STORE_STREAMED_HINT ",128(%0)  \n"  /* Prefetch 4 lines ahead     */
+	"	daddiu	%0, %0, 128	\n"
+	"	pref	" SB1_PREF_STORE_STREAMED_HINT ", -128(%0)  \n"  /* Prefetch the first 4 lines */
+	"	pref	" SB1_PREF_STORE_STREAMED_HINT ",  -96(%0)  \n"
+	"	pref	" SB1_PREF_STORE_STREAMED_HINT ",  -64(%0)  \n"
+	"	pref	" SB1_PREF_STORE_STREAMED_HINT ",  -32(%0)  \n"
+	"1:	sd	$0, -128(%0)	\n"  /* Throw out a cacheline of 0's */
+	"	sd	$0, -120(%0)	\n"
+	"	sd	$0, -112(%0)	\n"
+	"	sd	$0, -104(%0)	\n"
+	"	daddiu	%0, %0, 32	\n"
+	"	bnel	%0, %1, 1b	\n"
+	"	 pref	" SB1_PREF_STORE_STREAMED_HINT ",  -32(%0)  \n"
+	"	daddiu	%0, %0, -128	\n"
 #endif
-		"	.set	mips0		\n"
-		:
-		: "r" (addr)
-		: "memory");
-		addr += 32;
-	} while (addr != end);
+	"	sd	$0, 0(%0)	\n"  /* Throw out a cacheline of 0's */
+	"1:	sd	$0, 8(%0)	\n"
+	"	sd	$0, 16(%0)	\n"
+	"	sd	$0, 24(%0)	\n"
+	"	daddiu	%0, %0, 32	\n"
+	"	bnel	%0, %1, 1b	\n"
+	"	 sd	$0, 0(%0)	\n"
+	"	.set	pop		\n"
+	: "+r" (addr)
+	: "r" (end)
+	: "memory");
 }
 
-#ifdef CONFIG_SIBYTE_DMA_PAGEOPS
 static inline void copy_page_cpu(void *to, void *from)
-#else
-void copy_page(void *to, void *from)
-#endif
 {
-	unsigned char *src = from;
-	unsigned char *dst = to;
+	unsigned char *src = (unsigned char *)from;
+	unsigned char *dst = (unsigned char *)to;
 	unsigned char *end = src + PAGE_SIZE;
 
 	/*
-	 * This should be optimized in assembly...can't use ld/sd, though,
-	 * because the top 32 bits could be nuked if we took an interrupt
-	 * during the routine.	And this is not a good place to be cli()'ing
-	 *
 	 * The pref's used here are using "streaming" hints, which cause the
 	 * copied data to be kicked out of the cache sooner.  A page copy often
 	 * ends up copying a lot more data than is commonly used, so this seems
 	 * to make sense in terms of reducing cache pollution, but I've no real
 	 * performance data to back this up
 	 */
-
-	do {
-		__asm__ __volatile__(
-		"	.set	mips4					\n"
+	__asm__ __volatile__(
+	"	.set	push		\n"
+	"	.set	mips4		\n"
+	"	.set	noreorder	\n"
 #ifdef CONFIG_CPU_HAS_PREFETCH
-		"	pref	" SB1_PREF_LOAD_STREAMED_HINT  ",  0(%0)\n"  /* Prefetch the first 3 lines */
-		"	pref	" SB1_PREF_STORE_STREAMED_HINT ",  0(%1)\n"
-		"	pref	" SB1_PREF_LOAD_STREAMED_HINT  ",  32(%0)\n"
-		"	pref	" SB1_PREF_STORE_STREAMED_HINT ",  32(%1)\n"
-		"	pref	" SB1_PREF_LOAD_STREAMED_HINT  ",  64(%0)\n"
-		"	pref	" SB1_PREF_STORE_STREAMED_HINT ",  64(%1)\n"
-#endif
-		"1:	lw	$2,  0(%0)	\n"  /* Block copy a cacheline */
-		"	lw	$3,  4(%0)	\n"
-		"	lw	$4,  8(%0)	\n"
-		"	lw	$5, 12(%0)	\n"
-		"	lw	$6, 16(%0)	\n"
-		"	lw	$7, 20(%0)	\n"
-		"	lw	$8, 24(%0)	\n"
-		"	lw	$9, 28(%0)	\n"
-#ifdef CONFIG_CPU_HAS_PREFETCH
-		"	pref	" SB1_PREF_LOAD_STREAMED_HINT  ", 96(%0)  \n"  /* Prefetch ahead         */
-		"	pref	" SB1_PREF_STORE_STREAMED_HINT ", 96(%1)  \n"
+	"	daddiu	%0, %0, 128	\n"
+	"	daddiu	%1, %1, 128	\n"
+	"	pref	" SB1_PREF_LOAD_STREAMED_HINT  ", -128(%0)\n"  /* Prefetch the first 4 lines */
+	"	pref	" SB1_PREF_STORE_STREAMED_HINT ", -128(%1)\n"
+	"	pref	" SB1_PREF_LOAD_STREAMED_HINT  ",  -96(%0)\n"
+	"	pref	" SB1_PREF_STORE_STREAMED_HINT ",  -96(%1)\n"
+	"	pref	" SB1_PREF_LOAD_STREAMED_HINT  ",  -64(%0)\n"
+	"	pref	" SB1_PREF_STORE_STREAMED_HINT ",  -64(%1)\n"
+	"	pref	" SB1_PREF_LOAD_STREAMED_HINT  ",  -32(%0)\n"
+	"1:	pref	" SB1_PREF_STORE_STREAMED_HINT ",  -32(%1)\n"
+# ifdef CONFIG_MIPS64
+	"	ld	$8, -128(%0)	\n"  /* Block copy a cacheline */
+	"	ld	$9, -120(%0)	\n"
+	"	ld	$10, -112(%0)	\n"
+	"	ld	$11, -104(%0)	\n"
+	"	sd	$8, -128(%1)	\n"
+	"	sd	$9, -120(%1)	\n"
+	"	sd	$10, -112(%1)	\n"
+	"	sd	$11, -104(%1)	\n"
+# else
+	"	lw	$2, -128(%0)	\n"  /* Block copy a cacheline */
+	"	lw	$3, -124(%0)	\n"
+	"	lw	$6, -120(%0)	\n"
+	"	lw	$7, -116(%0)	\n"
+	"	lw	$8, -112(%0)	\n"
+	"	lw	$9, -108(%0)	\n"
+	"	lw	$10, -104(%0)	\n"
+	"	lw	$11, -100(%0)	\n"
+	"	sw	$2, -128(%1)	\n"
+	"	sw	$3, -124(%1)	\n"
+	"	sw	$6, -120(%1)	\n"
+	"	sw	$7, -116(%1)	\n"
+	"	sw	$8, -112(%1)	\n"
+	"	sw	$9, -108(%1)	\n"
+	"	sw	$10, -104(%1)	\n"
+	"	sw	$11, -100(%1)	\n"
+# endif
+	"	daddiu	%0, %0, 32	\n"
+	"	daddiu	%1, %1, 32	\n"
+	"	bnel	%0, %2, 1b	\n"
+	"	 pref	" SB1_PREF_LOAD_STREAMED_HINT  ",  -32(%0)\n"
+	"	daddiu	%0, %0, -128	\n"
+	"	daddiu	%1, %1, -128	\n"
+#endif
+#ifdef CONFIG_MIPS64
+	"	ld	$8, 0(%0)	\n"  /* Block copy a cacheline */
+	"1:	ld	$9, 8(%0)	\n"
+	"	ld	$10, 16(%0)	\n"
+	"	ld	$11, 24(%0)	\n"
+	"	sd	$8, 0(%1)	\n"
+	"	sd	$9, 8(%1)	\n"
+	"	sd	$10, 16(%1)	\n"
+	"	sd	$11, 24(%1)	\n"
+#else
+	"	lw	$2, 0(%0)	\n"  /* Block copy a cacheline */
+	"1:	lw	$3, 4(%0)	\n"
+	"	lw	$6, 8(%0)	\n"
+	"	lw	$7, 12(%0)	\n"
+	"	lw	$8, 16(%0)	\n"
+	"	lw	$9, 20(%0)	\n"
+	"	lw	$10, 24(%0)	\n"
+	"	lw	$11, 28(%0)	\n"
+	"	sw	$2, 0(%1)	\n"
+	"	sw	$3, 4(%1)	\n"
+	"	sw	$6, 8(%1)	\n"
+	"	sw	$7, 12(%1)	\n"
+	"	sw	$8, 16(%1)	\n"
+	"	sw	$9, 20(%1)	\n"
+	"	sw	$10, 24(%1)	\n"
+	"	sw	$11, 28(%1)	\n"
+#endif
+	"	daddiu	%0, %0, 32	\n"
+	"	daddiu	%1, %1, 32	\n"
+	"	bnel	%0, %2, 1b	\n"
+#ifdef CONFIG_MIPS64
+	"	 ld	$8, 0(%0)	\n"
+#else
+	"	 lw	$2, 0(%0)	\n"
+#endif
+	"	.set	pop		\n"
+	: "+r" (src), "+r" (dst)
+	: "r" (end)
+#ifdef CONFIG_MIPS64
+	: "$8","$9","$10","$11","memory");
+#else
+	: "$2","$3","$6","$7","$8","$9","$10","$11","memory");
 #endif
-		"	sw	$2,  0(%1)	\n"
-		"	sw	$3,  4(%1)	\n"
-		"	sw	$4,  8(%1)	\n"
-		"	sw	$5, 12(%1)	\n"
-		"	sw	$6, 16(%1)	\n"
-		"	sw	$7, 20(%1)	\n"
-		"	sw	$8, 24(%1)	\n"
-		"	sw	$9, 28(%1)	\n"
-		"	.set	mips0		\n"
-		:
-		: "r" (src), "r" (dst)
-		: "$2","$3","$4","$5","$6","$7","$8","$9","memory");
-		src += 32;
-		dst += 32;
-	} while (src != end);
 }
 
 
@@ -151,10 +201,10 @@
  * particular CPU. 
  */
 typedef struct dmadscr_s {
-	uint64_t  dscr_a;
-	uint64_t  dscr_b;
-	uint64_t  pad_a;
-	uint64_t  pad_b;
+	u64 dscr_a;
+	u64 dscr_b;
+	u64 pad_a;
+	u64 pad_b;
 } dmadscr_t;
 
 static dmadscr_t page_descr[NR_CPUS] __attribute__((aligned(SMP_CACHE_BYTES)));
@@ -162,14 +212,14 @@
 void sb1_dma_init(void)
 {
 	int cpu = smp_processor_id();
-	uint64_t base_val = PHYSADDR(&page_descr[cpu]) | V_DM_DSCR_BASE_RINGSZ(1);
+	u64 base_val = CPHYSADDR(&page_descr[cpu]) | V_DM_DSCR_BASE_RINGSZ(1);
 
-	__raw_writeq(base_val,
-		     IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE)));
-	__raw_writeq(base_val | M_DM_DSCR_BASE_RESET,
-		     IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE)));
-	__raw_writeq(base_val | M_DM_DSCR_BASE_ENABL,
-		     IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE)));
+	bus_writeq(base_val,
+		   (void *)IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE)));
+	bus_writeq(base_val | M_DM_DSCR_BASE_RESET,
+		   (void *)IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE)));
+	bus_writeq(base_val | M_DM_DSCR_BASE_ENABL,
+		   (void *)IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE)));
 }
 
 void clear_page(void *page)
@@ -177,46 +227,61 @@
 	int cpu = smp_processor_id();
 
 	/* if the page is above Kseg0, use old way */
-	if (KSEGX(page) != CAC_BASE)
+	if ((long)KSEGX(page) != (long)CKSEG0)
 		return clear_page_cpu(page);
 
-	page_descr[cpu].dscr_a = PHYSADDR(page) | M_DM_DSCRA_ZERO_MEM | M_DM_DSCRA_L2C_DEST | M_DM_DSCRA_INTERRUPT;
+	page_descr[cpu].dscr_a = CPHYSADDR(page) | M_DM_DSCRA_ZERO_MEM | M_DM_DSCRA_L2C_DEST | M_DM_DSCRA_INTERRUPT;
 	page_descr[cpu].dscr_b = V_DM_DSCRB_SRC_LENGTH(PAGE_SIZE);
-	__raw_writeq(1, IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_COUNT)));
+	bus_writeq(1, (void *)IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_COUNT)));
 
 	/*
 	 * Don't really want to do it this way, but there's no
 	 * reliable way to delay completion detection.
 	 */
-	while (!(__raw_readq(IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE_DEBUG)) & M_DM_DSCR_BASE_INTERRUPT)))
+	while (!(bus_readq((void *)(IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE_DEBUG)) &
+			   M_DM_DSCR_BASE_INTERRUPT))))
 		;
-	__raw_readq(IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE)));
+	bus_readq((void *)IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE)));
 }
 
 void copy_page(void *to, void *from)
 {
-	unsigned long from_phys = PHYSADDR(from);
-	unsigned long to_phys = PHYSADDR(to);
+	unsigned long from_phys = CPHYSADDR(from);
+	unsigned long to_phys = CPHYSADDR(to);
 	int cpu = smp_processor_id();
 
 	/* if either page is above Kseg0, use old way */
-	if ((KSEGX(to) != CAC_BASE) || (KSEGX(from) != CAC_BASE))
+	if ((long)KSEGX(to) != (long)CKSEG0
+	    || (long)KSEGX(from) != (long)CKSEG0)
 		return copy_page_cpu(to, from);
 
-	page_descr[cpu].dscr_a = PHYSADDR(to_phys) | M_DM_DSCRA_L2C_DEST | M_DM_DSCRA_INTERRUPT;
-	page_descr[cpu].dscr_b = PHYSADDR(from_phys) | V_DM_DSCRB_SRC_LENGTH(PAGE_SIZE);
-	__raw_writeq(1, IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_COUNT)));
+	page_descr[cpu].dscr_a = CPHYSADDR(to_phys) | M_DM_DSCRA_L2C_DEST | M_DM_DSCRA_INTERRUPT;
+	page_descr[cpu].dscr_b = CPHYSADDR(from_phys) | V_DM_DSCRB_SRC_LENGTH(PAGE_SIZE);
+	bus_writeq(1, (void *)IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_COUNT)));
 
 	/*
 	 * Don't really want to do it this way, but there's no
 	 * reliable way to delay completion detection.
 	 */
-	while (!(__raw_readq(IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE_DEBUG)) & M_DM_DSCR_BASE_INTERRUPT)))
+	while (!(bus_readq((void *)(IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE_DEBUG)) &
+				    M_DM_DSCR_BASE_INTERRUPT))))
 		;
-	__raw_readq(IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE)));
+	bus_readq((void *)IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE)));
 }
 
-#endif
+#else /* !CONFIG_SIBYTE_DMA_PAGEOPS */
+
+void clear_page(void *page)
+{
+	return clear_page_cpu(page);
+}
+
+void copy_page(void *to, void *from)
+{
+	return copy_page_cpu(to, from);
+}
+
+#endif /* !CONFIG_SIBYTE_DMA_PAGEOPS */
 
 EXPORT_SYMBOL(clear_page);
 EXPORT_SYMBOL(copy_page);
diff -Nru a/arch/mips/mm/pgtable-32.c b/arch/mips/mm/pgtable-32.c
--- a/arch/mips/mm/pgtable-32.c	2005-03-01 23:38:52 -08:00
+++ b/arch/mips/mm/pgtable-32.c	2005-03-01 23:38:52 -08:00
@@ -71,8 +71,8 @@
 
 	/* Initialize the entire pgd.  */
 	pgd_init((unsigned long)swapper_pg_dir);
-	pgd_init((unsigned long)swapper_pg_dir +
-	         sizeof(pgd_t ) * USER_PTRS_PER_PGD);
+	pgd_init((unsigned long)swapper_pg_dir
+		 + sizeof(pgd_t) * USER_PTRS_PER_PGD);
 
 #ifdef CONFIG_HIGHMEM
 	pgd_base = swapper_pg_dir;
diff -Nru a/arch/mips/mm/pgtable-64.c b/arch/mips/mm/pgtable-64.c
--- a/arch/mips/mm/pgtable-64.c	2005-03-01 23:38:52 -08:00
+++ b/arch/mips/mm/pgtable-64.c	2005-03-01 23:38:52 -08:00
@@ -55,5 +55,4 @@
 	/* Initialize the entire pgd.  */
 	pgd_init((unsigned long)swapper_pg_dir);
 	pmd_init((unsigned long)invalid_pmd_table, (unsigned long)invalid_pte_table);
-	memset((void *)invalid_pte_table, 0, sizeof(pte_t) * PTRS_PER_PTE);
 }
diff -Nru a/arch/mips/mm/pgtable.c b/arch/mips/mm/pgtable.c
--- a/arch/mips/mm/pgtable.c	2005-03-01 23:38:55 -08:00
+++ b/arch/mips/mm/pgtable.c	2005-03-01 23:38:55 -08:00
@@ -1,3 +1,4 @@
+#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/swap.h>
diff -Nru a/arch/mips/mm/sc-rm7k.c b/arch/mips/mm/sc-rm7k.c
--- a/arch/mips/mm/sc-rm7k.c	2005-03-01 23:39:18 -08:00
+++ b/arch/mips/mm/sc-rm7k.c	2005-03-01 23:39:18 -08:00
@@ -96,13 +96,13 @@
 }
 
 /*
- * This function is executed in the uncached segment KSEG1.
+ * This function is executed in the uncached segment CKSEG1.
  * It must not touch the stack, because the stack pointer still points
- * into KSEG0.
+ * into CKSEG0.
  *
  * Three options:
  *	- Write it in assembly and guarantee that we don't use the stack.
- *	- Disable caching for KSEG0 before calling it.
+ *	- Disable caching for CKSEG0 before calling it.
  *	- Pray that GCC doesn't randomly start using the stack.
  *
  * This being Linux, we obviously take the least sane of those options -
diff -Nru a/arch/mips/mm/tlb-andes.c b/arch/mips/mm/tlb-andes.c
--- a/arch/mips/mm/tlb-andes.c	2005-03-01 23:38:53 -08:00
+++ b/arch/mips/mm/tlb-andes.c	2005-03-01 23:38:53 -08:00
@@ -7,7 +7,6 @@
  * Copyright (C) 1999 Silicon Graphics, Inc.
  * Copyright (C) 2000 Kanoj Sarcar (kanoj@sgi.com)
  */
-#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
diff -Nru a/arch/mips/mm/tlb-sb1.c b/arch/mips/mm/tlb-sb1.c
--- a/arch/mips/mm/tlb-sb1.c	2005-03-01 23:39:17 -08:00
+++ b/arch/mips/mm/tlb-sb1.c	2005-03-01 23:39:17 -08:00
@@ -17,7 +17,6 @@
  * 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/init.h>
 #include <asm/mmu_context.h>
 #include <asm/bootinfo.h>
@@ -25,7 +24,7 @@
 
 extern void build_tlb_refill_handler(void);
 
-#define UNIQUE_ENTRYHI(idx) (KSEG0 + ((idx) << (PAGE_SHIFT + 1)))
+#define UNIQUE_ENTRYHI(idx) (CKSEG0 + ((idx) << (PAGE_SHIFT + 1)))
 
 /* Dump the current entry* and pagemask registers */
 static inline void dump_cur_tlb_regs(void)
diff -Nru a/arch/mips/mm/tlb64-glue-r4k.S b/arch/mips/mm/tlb64-glue-r4k.S
--- a/arch/mips/mm/tlb64-glue-r4k.S	2005-03-01 23:39:16 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,41 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1999 Ralf Baechle
- * Copyright (C) 1999 Silicon Graphics, Inc.
- */
-#include <linux/init.h>
-#include <asm/mipsregs.h>
-#include <asm/regdef.h>
-#include <asm/stackframe.h>
-
-	.macro	__BUILD_cli
-	CLI
-	.endm
-
-	.macro	__BUILD_sti
-	STI
-	.endm
-
-	.macro	__BUILD_kmode
-	KMODE
-	.endm
-
-	.macro	tlb_handler name interruptible writebit
-	NESTED(__\name, PT_SIZE, sp)
-	SAVE_ALL
-	dmfc0	a2, CP0_BADVADDR
-	__BUILD_\interruptible
-	li	a1, \writebit
-	sd	a2, PT_BVADDR(sp)
-	move	a0, sp
-	jal	do_page_fault
-	j	ret_from_exception
-	END(__\name)
-	.endm
-
-	tlb_handler	xtlb_mod kmode 1
-	tlb_handler	xtlb_tlbl kmode 0
-	tlb_handler	xtlb_tlbs kmode 1
diff -Nru a/arch/mips/mm/tlb64-glue-sb1.S b/arch/mips/mm/tlb64-glue-sb1.S
--- a/arch/mips/mm/tlb64-glue-sb1.S	2005-03-01 23:39:17 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,66 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1999 Ralf Baechle
- * Copyright (C) 1999 Silicon Graphics, Inc.
- */
-#include <linux/init.h>
-#include <asm/mipsregs.h>
-#include <asm/page.h>
-#include <asm/regdef.h>
-#include <asm/stackframe.h>
-#include <asm/war.h>
-
-	.macro	__BUILD_cli
-	CLI
-	.endm
-
-	.macro	__BUILD_sti
-	STI
-	.endm
-
-	.macro	__BUILD_kmode
-	KMODE
-	.endm
-
-	.macro	tlb_handler name interruptible writebit
-	NESTED(__\name, PT_SIZE, sp)
-	SAVE_ALL
-	dmfc0	a2, CP0_BADVADDR
-	__BUILD_\interruptible
-	li	a1, \writebit
-	sd	a2, PT_BVADDR(sp)
-	move	a0, sp
-	jal	do_page_fault
-	j	ret_from_exception
-	END(__\name)
-	.endm
-
-	.macro	tlb_handler_m3 name interruptible writebit
-	NESTED(__\name, PT_SIZE, sp)
-	dmfc0	k0, CP0_BADVADDR
-	dmfc0	k1, CP0_ENTRYHI
-	xor	k0, k1
-	dsrl	k0, k0, PAGE_SHIFT + 1
-	bnez	k0, 1f
-	SAVE_ALL
-	dmfc0	a2, CP0_BADVADDR
-	__BUILD_\interruptible
-	li	a1, \writebit
-	sd	a2, PT_BVADDR(sp)
-	move	a0, sp
-	jal	do_page_fault
-1:
-	j	ret_from_exception
-	END(__\name)
-	.endm
-
-	tlb_handler	xtlb_mod kmode 1
-#if BCM1250_M3_WAR
-	tlb_handler_m3	xtlb_tlbl kmode 0
-#else
-	tlb_handler	xtlb_tlbl kmode 0
-#endif
-	tlb_handler	xtlb_tlbs kmode 1
diff -Nru a/arch/mips/mm/tlbex-fault.S b/arch/mips/mm/tlbex-fault.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/mips/mm/tlbex-fault.S	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,28 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1999 Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#include <asm/mipsregs.h>
+#include <asm/page.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+	.macro tlb_do_page_fault, write
+	NESTED(tlb_do_page_fault_\write, PT_SIZE, sp)
+	SAVE_ALL
+	MFC0	a2, CP0_BADVADDR
+	KMODE
+	move	a0, sp
+	REG_S	a2, PT_BVADDR(sp)
+	li	a1, \write
+	jal	do_page_fault
+	j	ret_from_exception
+	END(tlb_do_page_fault_\write)
+	.endm
+
+	tlb_do_page_fault 0
+	tlb_do_page_fault 1
diff -Nru a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
--- a/arch/mips/mm/tlbex.c	2005-03-01 23:38:53 -08:00
+++ b/arch/mips/mm/tlbex.c	2005-03-01 23:38:53 -08:00
@@ -5,7 +5,7 @@
  *
  * Synthesize TLB refill handlers at runtime.
  *
- * Copyright (C) 2004 by Thiemo Seufer
+ * Copyright (C) 2004,2005 by Thiemo Seufer
  */
 
 #include <stdarg.h>
@@ -19,11 +19,11 @@
 
 #include <asm/pgtable.h>
 #include <asm/cacheflush.h>
-#include <asm/cacheflush.h>
 #include <asm/mmu_context.h>
 #include <asm/inst.h>
 #include <asm/elf.h>
 #include <asm/smp.h>
+#include <asm/war.h>
 
 /* #define DEBUG_TLB */
 
@@ -44,6 +44,11 @@
 	return BCM1250_M3_WAR;
 }
 
+static __init int __attribute__((unused)) r10000_llsc_war(void)
+{
+	return R10000_LLSC_WAR;
+}
+
 /*
  * A little micro-assembler, intended for TLB refill handler
  * synthesizing. It is intentionally kept simple, does only support
@@ -84,13 +89,14 @@
 enum opcode {
 	insn_invalid,
 	insn_addu, insn_addiu, insn_and, insn_andi, insn_beq,
-	insn_bgez, insn_bgezl, insn_bltz, insn_bltzl, insn_bne,
-	insn_daddu, insn_daddiu, insn_dmfc0, insn_dmtc0,
+	insn_beql, insn_bgez, insn_bgezl, insn_bltz, insn_bltzl,
+	insn_bne, insn_daddu, insn_daddiu, insn_dmfc0, insn_dmtc0,
 	insn_dsll, insn_dsll32, insn_dsra, insn_dsrl, insn_dsrl32,
 	insn_dsubu, insn_eret, insn_j, insn_jal, insn_jr, insn_ld,
-	insn_lui, insn_lw, insn_mfc0, insn_mtc0, insn_ori, insn_rfe,
-	insn_sd, insn_sll, insn_sra, insn_srl, insn_subu, insn_sw,
-	insn_tlbp, insn_tlbwi, insn_tlbwr, insn_xor, insn_xori
+	insn_ll, insn_lld, insn_lui, insn_lw, insn_mfc0, insn_mtc0,
+	insn_ori, insn_rfe, insn_sc, insn_scd, insn_sd, insn_sll,
+	insn_sra, insn_srl, insn_subu, insn_sw, insn_tlbp, insn_tlbwi,
+	insn_tlbwr, insn_xor, insn_xori
 };
 
 struct insn {
@@ -114,6 +120,7 @@
 	{ insn_and, M(spec_op,0,0,0,0,and_op), RS | RT | RD },
 	{ insn_andi, M(andi_op,0,0,0,0,0), RS | RT | UIMM },
 	{ insn_beq, M(beq_op,0,0,0,0,0), RS | RT | BIMM },
+	{ insn_beql, M(beql_op,0,0,0,0,0), RS | RT | BIMM },
 	{ insn_bgez, M(bcond_op,0,bgez_op,0,0,0), RS | BIMM },
 	{ insn_bgezl, M(bcond_op,0,bgezl_op,0,0,0), RS | BIMM },
 	{ insn_bltz, M(bcond_op,0,bltz_op,0,0,0), RS | BIMM },
@@ -134,12 +141,16 @@
 	{ insn_jal, M(jal_op,0,0,0,0,0), JIMM },
 	{ insn_jr, M(spec_op,0,0,0,0,jr_op), RS },
 	{ insn_ld, M(ld_op,0,0,0,0,0), RS | RT | SIMM },
+	{ insn_ll, M(ll_op,0,0,0,0,0), RS | RT | SIMM },
+	{ insn_lld, M(lld_op,0,0,0,0,0), RS | RT | SIMM },
 	{ insn_lui, M(lui_op,0,0,0,0,0), RT | SIMM },
 	{ insn_lw, M(lw_op,0,0,0,0,0), RS | RT | SIMM },
 	{ insn_mfc0, M(cop0_op,mfc_op,0,0,0,0), RT | RD },
 	{ insn_mtc0, M(cop0_op,mtc_op,0,0,0,0), RT | RD },
 	{ insn_ori, M(ori_op,0,0,0,0,0), RS | RT | UIMM },
 	{ insn_rfe, M(cop0_op,cop_op,0,0,0,rfe_op), 0 },
+	{ insn_sc, M(sc_op,0,0,0,0,0), RS | RT | SIMM },
+	{ insn_scd, M(scd_op,0,0,0,0,0), RS | RT | SIMM },
 	{ insn_sd, M(sd_op,0,0,0,0,0), RS | RT | SIMM },
 	{ insn_sll, M(spec_op,0,0,0,0,sll_op), RT | RD | RE },
 	{ insn_sra, M(spec_op,0,0,0,0,sra_op), RT | RD | RE },
@@ -341,6 +352,7 @@
 I_u2u1u3(_andi);
 I_u3u1u2(_and);
 I_u1u2s3(_beq);
+I_u1u2s3(_beql);
 I_u1s2(_bgez);
 I_u1s2(_bgezl);
 I_u1s2(_bltz);
@@ -361,12 +373,16 @@
 I_u1(_jal);
 I_u1(_jr);
 I_u2s3u1(_ld);
+I_u2s3u1(_ll);
+I_u2s3u1(_lld);
 I_u1s2(_lui);
 I_u2s3u1(_lw);
 I_u1u2(_mfc0);
 I_u1u2(_mtc0);
 I_u2u1u3(_ori);
 I_0(_rfe);
+I_u2s3u1(_sc);
+I_u2s3u1(_scd);
 I_u2s3u1(_sd);
 I_u2u1u3(_sll);
 I_u2u1u3(_sra);
@@ -389,8 +405,14 @@
 	label_leave,
 	label_vmalloc,
 	label_vmalloc_done,
-	label_tlbwr_hazard,
-	label_split
+	label_tlbw_hazard,
+	label_split,
+	label_nopage_tlbl,
+	label_nopage_tlbs,
+	label_nopage_tlbm,
+	label_smp_pgtable_change,
+	label_r3000_write_probe_fail,
+	label_r3000_write_probe_ok
 };
 
 struct label {
@@ -416,8 +438,14 @@
 L_LA(_leave)
 L_LA(_vmalloc)
 L_LA(_vmalloc_done)
-L_LA(_tlbwr_hazard)
+L_LA(_tlbw_hazard)
 L_LA(_split)
+L_LA(_nopage_tlbl)
+L_LA(_nopage_tlbs)
+L_LA(_nopage_tlbm)
+L_LA(_smp_pgtable_change)
+L_LA(_r3000_write_probe_fail)
+L_LA(_r3000_write_probe_ok)
 
 /* convenience macros for instructions */
 #ifdef CONFIG_MIPS64
@@ -431,6 +459,8 @@
 # define i_ADDIU(buf, rs, rt, val) i_daddiu(buf, rs, rt, val)
 # define i_ADDU(buf, rs, rt, rd) i_daddu(buf, rs, rt, rd)
 # define i_SUBU(buf, rs, rt, rd) i_dsubu(buf, rs, rt, rd)
+# define i_LL(buf, rs, rt, off) i_lld(buf, rs, rt, off)
+# define i_SC(buf, rs, rt, off) i_scd(buf, rs, rt, off)
 #else
 # define i_LW(buf, rs, rt, off) i_lw(buf, rs, rt, off)
 # define i_SW(buf, rs, rt, off) i_sw(buf, rs, rt, off)
@@ -442,28 +472,33 @@
 # define i_ADDIU(buf, rs, rt, val) i_addiu(buf, rs, rt, val)
 # define i_ADDU(buf, rs, rt, rd) i_addu(buf, rs, rt, rd)
 # define i_SUBU(buf, rs, rt, rd) i_subu(buf, rs, rt, rd)
+# define i_LL(buf, rs, rt, off) i_ll(buf, rs, rt, off)
+# define i_SC(buf, rs, rt, off) i_sc(buf, rs, rt, off)
 #endif
 
 #define i_b(buf, off) i_beq(buf, 0, 0, off)
+#define i_beqz(buf, rs, off) i_beq(buf, rs, 0, off)
+#define i_beqzl(buf, rs, off) i_beql(buf, rs, 0, off)
 #define i_bnez(buf, rs, off) i_bne(buf, rs, 0, off)
+#define i_bnezl(buf, rs, off) i_bnel(buf, rs, 0, off)
 #define i_move(buf, a, b) i_ADDU(buf, a, 0, b)
 #define i_nop(buf) i_sll(buf, 0, 0, 0)
 #define i_ssnop(buf) i_sll(buf, 0, 0, 1)
 #define i_ehb(buf) i_sll(buf, 0, 0, 3)
 
-#if CONFIG_MIPS64
-static __init int in_compat_space_p(long addr)
+#ifdef CONFIG_MIPS64
+static __init int __attribute__((unused)) in_compat_space_p(long addr)
 {
 	/* Is this address in 32bit compat space? */
 	return (((addr) & 0xffffffff00000000) == 0xffffffff00000000);
 }
 
-static __init int rel_highest(long val)
+static __init int __attribute__((unused)) rel_highest(long val)
 {
 	return ((((val + 0x800080008000L) >> 48) & 0xffff) ^ 0x8000) - 0x8000;
 }
 
-static __init int rel_higher(long val)
+static __init int __attribute__((unused)) rel_higher(long val)
 {
 	return ((((val + 0x80008000L) >> 32) & 0xffff) ^ 0x8000) - 0x8000;
 }
@@ -550,22 +585,33 @@
 				__resolve_relocs(rel, l);
 }
 
-static __init void copy_handler(struct reloc *rel, struct label *lab,
-				u32 *first, u32 *end, u32* target)
+static __init void move_relocs(struct reloc *rel, u32 *first, u32 *end,
+			       long off)
 {
-	long off = (long)(target - first);
-
-	memcpy(target, first, (end - first) * sizeof(u32));
-
 	for (; rel->lab != label_invalid; rel++)
 		if (rel->addr >= first && rel->addr < end)
 			rel->addr += off;
+}
 
+static __init void move_labels(struct label *lab, u32 *first, u32 *end,
+			       long off)
+{
 	for (; lab->lab != label_invalid; lab++)
 		if (lab->addr >= first && lab->addr < end)
 			lab->addr += off;
 }
 
+static __init void copy_handler(struct reloc *rel, struct label *lab,
+				u32 *first, u32 *end, u32 *target)
+{
+	long off = (long)(target - first);
+
+	memcpy(target, first, (end - first) * sizeof(u32));
+
+	move_relocs(rel, first, end, off);
+	move_labels(lab, first, end, off);
+}
+
 static __init int __attribute__((unused)) insn_has_bdelay(struct reloc *rel,
 							  u32 *addr)
 {
@@ -594,6 +640,20 @@
 	i_b(p, 0);
 }
 
+static void il_beqz(u32 **p, struct reloc **r, unsigned int reg,
+		    enum label_id l)
+{
+	r_mips_pc16(r, *p, l);
+	i_beqz(p, reg, 0);
+}
+
+static void __attribute__((unused))
+il_beqzl(u32 **p, struct reloc **r, unsigned int reg, enum label_id l)
+{
+	r_mips_pc16(r, *p, l);
+	i_beqzl(p, reg, 0);
+}
+
 static void il_bnez(u32 **p, struct reloc **r, unsigned int reg,
 		    enum label_id l)
 {
@@ -608,7 +668,7 @@
 	i_bgezl(p, reg, 0);
 }
 
-/* The only registers allowed in TLB handlers. */
+/* The only general purpose registers allowed in TLB handlers. */
 #define K0		26
 #define K1		27
 
@@ -642,7 +702,6 @@
 static __initdata struct label labels[128];
 static __initdata struct reloc relocs[128];
 
-#ifdef CONFIG_MIPS32
 /*
  * The R3000 TLB handler is simple.
  */
@@ -676,10 +735,11 @@
 		panic("TLB refill handler space exceeded");
 
 	printk("Synthesized TLB handler (%u instructions).\n",
-	       p - tlb_handler);
+	       (unsigned int)(p - tlb_handler));
 #ifdef DEBUG_TLB
 	{
 		int i;
+
 		for (i = 0; i < (p - tlb_handler); i++)
 			printk("%08x\n", tlb_handler[i]);
 	}
@@ -688,7 +748,6 @@
 	memcpy((void *)CAC_BASE, tlb_handler, 0x80);
 	flush_icache_range(CAC_BASE, CAC_BASE + 0x80);
 }
-#endif /* CONFIG_MIPS32 */
 
 /*
  * The R4000 TLB handler is much more complicated. We have two
@@ -738,12 +797,22 @@
 }
 
 /*
- * Write random TLB entry, and care about the hazards from the
- * preceeding mtc0 and for the following eret.
+ * Write random or indexed TLB entry, and care about the hazards from
+ * the preceeding mtc0 and for the following eret.
  */
-static __init void build_tlb_write_random_entry(u32 **p, struct label **l,
-						struct reloc **r)
+enum tlb_write_entry { tlb_random, tlb_indexed };
+
+static __init void build_tlb_write_entry(u32 **p, struct label **l,
+					 struct reloc **r,
+					 enum tlb_write_entry wmode)
 {
+	void(*tlbw)(u32 **) = NULL;
+
+	switch (wmode) {
+	case tlb_random: tlbw = i_tlbwr; break;
+	case tlb_indexed: tlbw = i_tlbwi; break;
+	}
+
 	switch (current_cpu_data.cputype) {
 	case CPU_R4000PC:
 	case CPU_R4000SC:
@@ -753,11 +822,11 @@
 	case CPU_R4400MC:
 		/*
 		 * This branch uses up a mtc0 hazard nop slot and saves
-		 * two nops after the tlbwr.
+		 * two nops after the tlbw instruction.
 		 */
-		il_bgezl(p, r, 0, label_tlbwr_hazard);
-		i_tlbwr(p);
-		l_tlbwr_hazard(l, *p);
+		il_bgezl(p, r, 0, label_tlbw_hazard);
+		tlbw(p);
+		l_tlbw_hazard(l, *p);
 		i_nop(p);
 		break;
 
@@ -766,12 +835,13 @@
 	case CPU_R5000:
 	case CPU_R5000A:
 	case CPU_5KC:
+	case CPU_TX49XX:
 	case CPU_AU1000:
 	case CPU_AU1100:
 	case CPU_AU1500:
 	case CPU_AU1550:
 		i_nop(p);
-		i_tlbwr(p);
+		tlbw(p);
 		break;
 
 	case CPU_R10000:
@@ -781,24 +851,32 @@
 	case CPU_4KSC:
 	case CPU_20KC:
 	case CPU_25KF:
-		i_tlbwr(p);
+		tlbw(p);
 		break;
 
 	case CPU_NEVADA:
 		i_nop(p); /* QED specifies 2 nops hazard */
 		/*
 		 * This branch uses up a mtc0 hazard nop slot and saves
-		 * a nop after the tlbwr.
+		 * a nop after the tlbw instruction.
 		 */
-		il_bgezl(p, r, 0, label_tlbwr_hazard);
-		i_tlbwr(p);
-		l_tlbwr_hazard(l, *p);
+		il_bgezl(p, r, 0, label_tlbw_hazard);
+		tlbw(p);
+		l_tlbw_hazard(l, *p);
+		break;
+
+	case CPU_RM7000:
+		i_nop(p);
+		i_nop(p);
+		i_nop(p);
+		i_nop(p);
+		tlbw(p);
 		break;
 
 	case CPU_4KEC:
 	case CPU_24K:
 		i_ehb(p);
-		i_tlbwr(p);
+		tlbw(p);
 		break;
 
 	case CPU_RM9000:
@@ -812,13 +890,32 @@
 		i_ssnop(p);
 		i_ssnop(p);
 		i_ssnop(p);
-		i_tlbwr(p);
+		tlbw(p);
 		i_ssnop(p);
 		i_ssnop(p);
 		i_ssnop(p);
 		i_ssnop(p);
 		break;
 
+	case CPU_VR4111:
+	case CPU_VR4121:
+	case CPU_VR4122:
+	case CPU_VR4181:
+	case CPU_VR4181A:
+		i_nop(p);
+		i_nop(p);
+		tlbw(p);
+		i_nop(p);
+		i_nop(p);
+		break;
+
+	case CPU_VR4131:
+	case CPU_VR4133:
+		i_nop(p);
+		i_nop(p);
+		tlbw(p);
+		break;
+
 	default:
 		panic("No TLB refill handler yet (CPU type: %d)",
 		      current_cpu_data.cputype);
@@ -826,7 +923,7 @@
 	}
 }
 
-#if CONFIG_MIPS64
+#ifdef CONFIG_MIPS64
 /*
  * TMP and PTR are scratch.
  * TMP will be clobbered, PTR will hold the pmd entry.
@@ -844,7 +941,7 @@
 	il_bltz(p, r, tmp, label_vmalloc);
 	/* No i_nop needed here, since the next insn doesn't touch TMP. */
 
-# ifdef CONFIG_SMP
+#ifdef CONFIG_SMP
 	/*
 	 * 64 bit SMP has the lower part of &pgd_current[smp_processor_id()]
 	 * stored in CONTEXT.
@@ -852,7 +949,17 @@
 	if (in_compat_space_p(pgdc)) {
 		i_dmfc0(p, ptr, C0_CONTEXT);
 		i_dsra(p, ptr, ptr, 23);
+		i_ld(p, ptr, 0, ptr);
 	} else {
+#ifdef CONFIG_BUILD_ELF64
+		i_dmfc0(p, ptr, C0_CONTEXT);
+		i_dsrl(p, ptr, ptr, 23);
+		i_dsll(p, ptr, ptr, 3);
+		i_LA_mostly(p, tmp, pgdc);
+		i_daddu(p, ptr, ptr, tmp);
+		i_dmfc0(p, tmp, C0_BADVADDR);
+		i_ld(p, ptr, rel_lo(pgdc), ptr);
+#else
 		i_dmfc0(p, ptr, C0_CONTEXT);
 		i_lui(p, tmp, rel_highest(pgdc));
 		i_dsll(p, ptr, ptr, 9);
@@ -860,12 +967,13 @@
 		i_dsrl32(p, ptr, ptr, 0);
 		i_and(p, ptr, ptr, tmp);
 		i_dmfc0(p, tmp, C0_BADVADDR);
+		i_ld(p, ptr, 0, ptr);
+#endif
 	}
-	i_ld(p, ptr, 0, ptr);
-# else
+#else
 	i_LA_mostly(p, ptr, pgdc);
 	i_ld(p, ptr, rel_lo(pgdc), ptr);
-# endif
+#endif
 
 	l_vmalloc_done(l, *p);
 	i_dsrl(p, tmp, tmp, PGDIR_SHIFT-3); /* get pgd offset in bytes */
@@ -902,13 +1010,14 @@
 	}
 }
 
-#else /* CONFIG_MIPS32 */
+#else /* !CONFIG_MIPS64 */
 
 /*
  * TMP and PTR are scratch.
  * TMP will be clobbered, PTR will hold the pgd entry.
  */
-static __init void build_get_pgde32(u32 **p, unsigned int tmp, unsigned int ptr)
+static __init void __attribute__((unused))
+build_get_pgde32(u32 **p, unsigned int tmp, unsigned int ptr)
 {
 	long pgdc = (long)pgd_current;
 
@@ -928,17 +1037,13 @@
 	i_sll(p, tmp, tmp, PGD_T_LOG2);
 	i_addu(p, ptr, ptr, tmp); /* add in pgd offset */
 }
-#endif /* CONFIG_MIPS32 */
+
+#endif /* !CONFIG_MIPS64 */
 
 static __init void build_adjust_context(u32 **p, unsigned int ctx)
 {
-	unsigned int shift = 0;
-	unsigned int mask = 0xff0;
-
-#if !defined(CONFIG_MIPS64) && !defined(CONFIG_64BIT_PHYS_ADDR)
-	shift++;
-	mask |= 0x008;
-#endif
+	unsigned int shift = 4 - (PTE_T_LOG2 + 1);
+	unsigned int mask = (PTRS_PER_PTE / 2 - 1) << (PTE_T_LOG2 + 1);
 
 	switch (current_cpu_data.cputype) {
 	case CPU_VR41XX:
@@ -994,7 +1099,7 @@
 	 * Kernel is a special case. Only a few CPUs use it.
 	 */
 #ifdef CONFIG_64BIT_PHYS_ADDR
-	if (cpu_has_64bit_gp_regs) {
+	if (cpu_has_64bits) {
 		i_ld(p, tmp, 0, ptep); /* get even pte */
 		i_ld(p, ptep, sizeof(pte_t), ptep); /* get odd pte */
 		i_dsrl(p, tmp, tmp, 6); /* convert to entrylo0 */
@@ -1049,20 +1154,20 @@
 		i_MFC0(&p, K0, C0_BADVADDR);
 		i_MFC0(&p, K1, C0_ENTRYHI);
 		i_xor(&p, K0, K0, K1);
-		i_SRL(&p, K0, K0, PAGE_SHIFT+1);
+		i_SRL(&p, K0, K0, PAGE_SHIFT + 1);
 		il_bnez(&p, &r, K0, label_leave);
 		/* No need for i_nop */
 	}
 
 #ifdef CONFIG_MIPS64
-	build_get_pmde64(&p, &l, &r, K0, K1); /* get pmd ptr in K1 */
+	build_get_pmde64(&p, &l, &r, K0, K1); /* get pmd in K1 */
 #else
-	build_get_pgde32(&p, K0, K1); /* get pgd ptr in K1 */
+	build_get_pgde32(&p, K0, K1); /* get pgd in K1 */
 #endif
 
 	build_get_ptep(&p, K0, K1);
 	build_update_entries(&p, K0, K1);
-	build_tlb_write_random_entry(&p, &l, &r);
+	build_tlb_write_entry(&p, &l, &r, tlb_random);
 	l_leave(&l, p);
 	i_eret(&p); /* return from trap */
 
@@ -1121,6 +1226,7 @@
 			i_nop(&f);
 		else {
 			copy_handler(relocs, labels, split, split + 1, f);
+			move_labels(labels, f, f + 1, -1);
 			f++;
 			split++;
 		}
@@ -1132,7 +1238,8 @@
 #endif /* CONFIG_MIPS64 */
 
 	resolve_relocs(relocs, labels);
-	printk("Synthesized TLB handler (%u instructions).\n", final_len);
+	printk("Synthesized TLB refill handler (%u instructions).\n",
+	       final_len);
 
 #ifdef DEBUG_TLB
 	{
@@ -1147,10 +1254,530 @@
 	flush_icache_range(CAC_BASE, CAC_BASE + 0x100);
 }
 
+/*
+ * TLB load/store/modify handlers.
+ *
+ * Only the fastpath gets synthesized at runtime, the slowpath for
+ * do_page_fault remains normal asm.
+ */
+extern void tlb_do_page_fault_0(void);
+extern void tlb_do_page_fault_1(void);
+
+#define __tlb_handler_align \
+	__attribute__((__aligned__(1 << CONFIG_MIPS_L1_CACHE_SHIFT)))
+
+/*
+ * 128 instructions for the fastpath handler is generous and should
+ * never be exceeded.
+ */
+#define FASTPATH_SIZE 128
+
+u32 __tlb_handler_align handle_tlbl[FASTPATH_SIZE];
+u32 __tlb_handler_align handle_tlbs[FASTPATH_SIZE];
+u32 __tlb_handler_align handle_tlbm[FASTPATH_SIZE];
+
+static void __init
+iPTE_LW(u32 **p, struct label **l, unsigned int pte, int offset,
+	unsigned int ptr)
+{
+#ifdef CONFIG_SMP
+# ifdef CONFIG_64BIT_PHYS_ADDR
+	if (cpu_has_64bits)
+		i_lld(p, pte, offset, ptr);
+	else
+# endif
+		i_LL(p, pte, offset, ptr);
+#else
+# ifdef CONFIG_64BIT_PHYS_ADDR
+	if (cpu_has_64bits)
+		i_ld(p, pte, offset, ptr);
+	else
+# endif
+		i_LW(p, pte, offset, ptr);
+#endif
+}
+
+static void __init
+iPTE_SW(u32 **p, struct reloc **r, unsigned int pte, int offset,
+	unsigned int ptr)
+{
+#ifdef CONFIG_SMP
+# ifdef CONFIG_64BIT_PHYS_ADDR
+	if (cpu_has_64bits)
+		i_scd(p, pte, offset, ptr);
+	else
+# endif
+		i_SC(p, pte, offset, ptr);
+
+	if (r10000_llsc_war())
+		il_beqzl(p, r, pte, label_smp_pgtable_change);
+	else
+		il_beqz(p, r, pte, label_smp_pgtable_change);
+
+# ifdef CONFIG_64BIT_PHYS_ADDR
+	if (!cpu_has_64bits) {
+		/* no i_nop needed */
+		i_ll(p, pte, sizeof(pte_t) / 2, ptr);
+		i_ori(p, pte, pte, _PAGE_VALID);
+		i_sc(p, pte, sizeof(pte_t) / 2, ptr);
+		il_beqz(p, r, pte, label_smp_pgtable_change);
+		/* no i_nop needed */
+		i_lw(p, pte, 0, ptr);
+	} else
+		i_nop(p);
+# else
+	i_nop(p);
+# endif
+#else
+# ifdef CONFIG_64BIT_PHYS_ADDR
+	if (cpu_has_64bits)
+		i_sd(p, pte, offset, ptr);
+	else
+# endif
+		i_SW(p, pte, offset, ptr);
+
+# ifdef CONFIG_64BIT_PHYS_ADDR
+	if (!cpu_has_64bits) {
+		i_lw(p, pte, sizeof(pte_t) / 2, ptr);
+		i_ori(p, pte, pte, _PAGE_VALID);
+		i_sw(p, pte, sizeof(pte_t) / 2, ptr);
+		i_lw(p, pte, 0, ptr);
+	}
+# endif
+#endif
+}
+
+/*
+ * Check if PTE is present, if not then jump to LABEL. PTR points to
+ * the page table where this PTE is located, PTE will be re-loaded
+ * with it's original value.
+ */
+static void __init
+build_pte_present(u32 **p, struct label **l, struct reloc **r,
+		  unsigned int pte, unsigned int ptr, enum label_id lid)
+{
+	i_andi(p, pte, pte, _PAGE_PRESENT | _PAGE_READ);
+	i_xori(p, pte, pte, _PAGE_PRESENT | _PAGE_READ);
+	il_bnez(p, r, pte, lid);
+	iPTE_LW(p, l, pte, 0, ptr);
+}
+
+/* Make PTE valid, store result in PTR. */
+static void __init
+build_make_valid(u32 **p, struct reloc **r, unsigned int pte,
+		 unsigned int ptr)
+{
+	i_ori(p, pte, pte, _PAGE_VALID | _PAGE_ACCESSED);
+	iPTE_SW(p, r, pte, 0, ptr);
+}
+
+/*
+ * Check if PTE can be written to, if not branch to LABEL. Regardless
+ * restore PTE with value from PTR when done.
+ */
+static void __init
+build_pte_writable(u32 **p, struct label **l, struct reloc **r,
+		   unsigned int pte, unsigned int ptr, enum label_id lid)
+{
+	i_andi(p, pte, pte, _PAGE_PRESENT | _PAGE_WRITE);
+	i_xori(p, pte, pte, _PAGE_PRESENT | _PAGE_WRITE);
+	il_bnez(p, r, pte, lid);
+	iPTE_LW(p, l, pte, 0, ptr);
+}
+
+/* Make PTE writable, update software status bits as well, then store
+ * at PTR.
+ */
+static void __init
+build_make_write(u32 **p, struct reloc **r, unsigned int pte,
+		 unsigned int ptr)
+{
+	i_ori(p, pte, pte,
+	      _PAGE_ACCESSED | _PAGE_MODIFIED | _PAGE_VALID | _PAGE_DIRTY);
+	iPTE_SW(p, r, pte, 0, ptr);
+}
+
+/*
+ * Check if PTE can be modified, if not branch to LABEL. Regardless
+ * restore PTE with value from PTR when done.
+ */
+static void __init
+build_pte_modifiable(u32 **p, struct label **l, struct reloc **r,
+		     unsigned int pte, unsigned int ptr, enum label_id lid)
+{
+	i_andi(p, pte, pte, _PAGE_WRITE);
+	il_beqz(p, r, pte, lid);
+	iPTE_LW(p, l, pte, 0, ptr);
+}
+
+/*
+ * R3000 style TLB load/store/modify handlers.
+ */
+
+/* This places the pte in the page table at PTR into ENTRYLO0. */
+static void __init
+build_r3000_pte_reload(u32 **p, unsigned int ptr)
+{
+	i_lw(p, ptr, 0, ptr);
+	i_nop(p); /* load delay */
+	i_mtc0(p, ptr, C0_ENTRYLO0);
+	i_nop(p); /* cp0 delay */
+}
+
+/*
+ * The index register may have the probe fail bit set,
+ * because we would trap on access kseg2, i.e. without refill.
+ */
+static void __init
+build_r3000_tlb_write(u32 **p, struct label **l, struct reloc **r,
+		      unsigned int tmp)
+{
+	i_mfc0(p, tmp, C0_INDEX);
+	i_nop(p); /* cp0 delay */
+	il_bltz(p, r, tmp, label_r3000_write_probe_fail);
+	i_nop(p); /* branch delay */
+	i_tlbwi(p);
+	il_b(p, r, label_r3000_write_probe_ok);
+	i_nop(p); /* branch delay */
+	l_r3000_write_probe_fail(l, *p);
+	i_tlbwr(p);
+	l_r3000_write_probe_ok(l, *p);
+}
+
+static void __init
+build_r3000_tlbchange_handler_head(u32 **p, unsigned int pte,
+				   unsigned int ptr)
+{
+	long pgdc = (long)pgd_current;
+
+	i_mfc0(p, pte, C0_BADVADDR);
+	i_lui(p, ptr, rel_hi(pgdc)); /* cp0 delay */
+	i_lw(p, ptr, rel_lo(pgdc), ptr);
+	i_srl(p, pte, pte, 22); /* load delay */
+	i_sll(p, pte, pte, 2);
+	i_addu(p, ptr, ptr, pte);
+	i_mfc0(p, pte, C0_CONTEXT);
+	i_lw(p, ptr, 0, ptr); /* cp0 delay */
+	i_andi(p, pte, pte, 0xffc); /* load delay */
+	i_addu(p, ptr, ptr, pte);
+	i_lw(p, pte, 0, ptr);
+	i_nop(p); /* load delay */
+	i_tlbp(p);
+}
+
+static void __init
+build_r3000_tlbchange_handler_tail(u32 **p, unsigned int tmp)
+{
+	i_mfc0(p, tmp, C0_EPC);
+	i_nop(p); /* cp0 delay */
+	i_jr(p, tmp);
+	i_rfe(p); /* branch delay */
+}
+
+static void __init build_r3000_tlb_load_handler(void)
+{
+	u32 *p = handle_tlbl;
+	struct label *l = labels;
+	struct reloc *r = relocs;
+
+	memset(handle_tlbl, 0, sizeof(handle_tlbl));
+	memset(labels, 0, sizeof(labels));
+	memset(relocs, 0, sizeof(relocs));
+
+	build_r3000_tlbchange_handler_head(&p, K0, K1);
+	build_pte_present(&p, &l, &r, K0, K1, label_nopage_tlbl);
+	build_make_valid(&p, &r, K0, K1);
+	build_r3000_pte_reload(&p, K1);
+	build_r3000_tlb_write(&p, &l, &r, K0);
+	build_r3000_tlbchange_handler_tail(&p, K0);
+
+	l_nopage_tlbl(&l, p);
+	i_j(&p, (unsigned long)tlb_do_page_fault_0 & 0x0fffffff);
+	i_nop(&p);
+
+	if ((p - handle_tlbl) > FASTPATH_SIZE)
+		panic("TLB load handler fastpath space exceeded");
+
+	resolve_relocs(relocs, labels);
+	printk("Synthesized TLB load handler fastpath (%u instructions).\n",
+	       (unsigned int)(p - handle_tlbl));
+
+#ifdef DEBUG_TLB
+	{
+		int i;
+
+		for (i = 0; i < FASTPATH_SIZE; i++)
+			printk("%08x\n", handle_tlbl[i]);
+	}
+#endif
+
+	flush_icache_range((unsigned long)handle_tlbl,
+			   (unsigned long)handle_tlbl + FASTPATH_SIZE * sizeof(u32));
+}
+
+static void __init build_r3000_tlb_store_handler(void)
+{
+	u32 *p = handle_tlbs;
+	struct label *l = labels;
+	struct reloc *r = relocs;
+
+	memset(handle_tlbs, 0, sizeof(handle_tlbs));
+	memset(labels, 0, sizeof(labels));
+	memset(relocs, 0, sizeof(relocs));
+
+	build_r3000_tlbchange_handler_head(&p, K0, K1);
+	build_pte_writable(&p, &l, &r, K0, K1, label_nopage_tlbs);
+	build_make_write(&p, &r, K0, K1);
+	build_r3000_pte_reload(&p, K1);
+	build_r3000_tlb_write(&p, &l, &r, K0);
+	build_r3000_tlbchange_handler_tail(&p, K0);
+
+	l_nopage_tlbs(&l, p);
+	i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
+	i_nop(&p);
+
+	if ((p - handle_tlbs) > FASTPATH_SIZE)
+		panic("TLB store handler fastpath space exceeded");
+
+	resolve_relocs(relocs, labels);
+	printk("Synthesized TLB store handler fastpath (%u instructions).\n",
+	       (unsigned int)(p - handle_tlbs));
+
+#ifdef DEBUG_TLB
+	{
+		int i;
+
+		for (i = 0; i < FASTPATH_SIZE; i++)
+			printk("%08x\n", handle_tlbs[i]);
+	}
+#endif
+
+	flush_icache_range((unsigned long)handle_tlbs,
+			   (unsigned long)handle_tlbs + FASTPATH_SIZE * sizeof(u32));
+}
+
+static void __init build_r3000_tlb_modify_handler(void)
+{
+	u32 *p = handle_tlbm;
+	struct label *l = labels;
+	struct reloc *r = relocs;
+
+	memset(handle_tlbm, 0, sizeof(handle_tlbm));
+	memset(labels, 0, sizeof(labels));
+	memset(relocs, 0, sizeof(relocs));
+
+	build_r3000_tlbchange_handler_head(&p, K0, K1);
+	build_pte_modifiable(&p, &l, &r, K0, K1, label_nopage_tlbm);
+	build_make_write(&p, &r, K0, K1);
+	build_r3000_pte_reload(&p, K1);
+	i_tlbwi(&p);
+	build_r3000_tlbchange_handler_tail(&p, K0);
+
+	l_nopage_tlbm(&l, p);
+	i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
+	i_nop(&p);
+
+	if ((p - handle_tlbm) > FASTPATH_SIZE)
+		panic("TLB modify handler fastpath space exceeded");
+
+	resolve_relocs(relocs, labels);
+	printk("Synthesized TLB modify handler fastpath (%u instructions).\n",
+	       (unsigned int)(p - handle_tlbm));
+
+#ifdef DEBUG_TLB
+	{
+		int i;
+
+		for (i = 0; i < FASTPATH_SIZE; i++)
+			printk("%08x\n", handle_tlbm[i]);
+	}
+#endif
+
+	flush_icache_range((unsigned long)handle_tlbm,
+			   (unsigned long)handle_tlbm + FASTPATH_SIZE * sizeof(u32));
+}
+
+/*
+ * R4000 style TLB load/store/modify handlers.
+ */
+static void __init
+build_r4000_tlbchange_handler_head(u32 **p, struct label **l,
+				   struct reloc **r, unsigned int pte,
+				   unsigned int ptr)
+{
+#ifdef CONFIG_MIPS64
+	build_get_pmde64(p, l, r, pte, ptr); /* get pmd in ptr */
+#else
+	build_get_pgde32(p, pte, ptr); /* get pgd in ptr */
+#endif
+
+	i_MFC0(p, pte, C0_BADVADDR);
+	i_LW(p, ptr, 0, ptr);
+	i_SRL(p, pte, pte, PAGE_SHIFT + PTE_ORDER - PTE_T_LOG2);
+	i_andi(p, pte, pte, (PTRS_PER_PTE - 1) << PTE_T_LOG2);
+	i_ADDU(p, ptr, ptr, pte);
+
+#ifdef CONFIG_SMP
+	l_smp_pgtable_change(l, *p);
+# endif
+	iPTE_LW(p, l, pte, 0, ptr); /* get even pte */
+	build_tlb_probe_entry(p);
+}
+
+static void __init
+build_r4000_tlbchange_handler_tail(u32 **p, struct label **l,
+				   struct reloc **r, unsigned int tmp,
+				   unsigned int ptr)
+{
+	i_ori(p, ptr, ptr, sizeof(pte_t));
+	i_xori(p, ptr, ptr, sizeof(pte_t));
+	build_update_entries(p, tmp, ptr);
+	build_tlb_write_entry(p, l, r, tlb_indexed);
+	l_leave(l, *p);
+	i_eret(p); /* return from trap */
+
+#ifdef CONFIG_MIPS64
+	build_get_pgd_vmalloc64(p, l, r, tmp, ptr);
+#endif
+}
+
+static void __init build_r4000_tlb_load_handler(void)
+{
+	u32 *p = handle_tlbl;
+	struct label *l = labels;
+	struct reloc *r = relocs;
+
+	memset(handle_tlbl, 0, sizeof(handle_tlbl));
+	memset(labels, 0, sizeof(labels));
+	memset(relocs, 0, sizeof(relocs));
+
+	if (bcm1250_m3_war()) {
+		i_MFC0(&p, K0, C0_BADVADDR);
+		i_MFC0(&p, K1, C0_ENTRYHI);
+		i_xor(&p, K0, K0, K1);
+		i_SRL(&p, K0, K0, PAGE_SHIFT + 1);
+		il_bnez(&p, &r, K0, label_leave);
+		/* No need for i_nop */
+	}
+
+	build_r4000_tlbchange_handler_head(&p, &l, &r, K0, K1);
+	build_pte_present(&p, &l, &r, K0, K1, label_nopage_tlbl);
+	build_make_valid(&p, &r, K0, K1);
+	build_r4000_tlbchange_handler_tail(&p, &l, &r, K0, K1);
+
+	l_nopage_tlbl(&l, p);
+	i_j(&p, (unsigned long)tlb_do_page_fault_0 & 0x0fffffff);
+	i_nop(&p);
+
+	if ((p - handle_tlbl) > FASTPATH_SIZE)
+		panic("TLB load handler fastpath space exceeded");
+
+	resolve_relocs(relocs, labels);
+	printk("Synthesized TLB load handler fastpath (%u instructions).\n",
+	       (unsigned int)(p - handle_tlbl));
+
+#ifdef DEBUG_TLB
+	{
+		int i;
+
+		for (i = 0; i < FASTPATH_SIZE; i++)
+			printk("%08x\n", handle_tlbl[i]);
+	}
+#endif
+
+	flush_icache_range((unsigned long)handle_tlbl,
+			   (unsigned long)handle_tlbl + FASTPATH_SIZE * sizeof(u32));
+}
+
+static void __init build_r4000_tlb_store_handler(void)
+{
+	u32 *p = handle_tlbs;
+	struct label *l = labels;
+	struct reloc *r = relocs;
+
+	memset(handle_tlbs, 0, sizeof(handle_tlbs));
+	memset(labels, 0, sizeof(labels));
+	memset(relocs, 0, sizeof(relocs));
+
+	build_r4000_tlbchange_handler_head(&p, &l, &r, K0, K1);
+	build_pte_writable(&p, &l, &r, K0, K1, label_nopage_tlbs);
+	build_make_write(&p, &r, K0, K1);
+	build_r4000_tlbchange_handler_tail(&p, &l, &r, K0, K1);
+
+	l_nopage_tlbs(&l, p);
+	i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
+	i_nop(&p);
+
+	if ((p - handle_tlbs) > FASTPATH_SIZE)
+		panic("TLB store handler fastpath space exceeded");
+
+	resolve_relocs(relocs, labels);
+	printk("Synthesized TLB store handler fastpath (%u instructions).\n",
+	       (unsigned int)(p - handle_tlbs));
+
+#ifdef DEBUG_TLB
+	{
+		int i;
+
+		for (i = 0; i < FASTPATH_SIZE; i++)
+			printk("%08x\n", handle_tlbs[i]);
+	}
+#endif
+
+	flush_icache_range((unsigned long)handle_tlbs,
+			   (unsigned long)handle_tlbs + FASTPATH_SIZE * sizeof(u32));
+}
+
+static void __init build_r4000_tlb_modify_handler(void)
+{
+	u32 *p = handle_tlbm;
+	struct label *l = labels;
+	struct reloc *r = relocs;
+
+	memset(handle_tlbm, 0, sizeof(handle_tlbm));
+	memset(labels, 0, sizeof(labels));
+	memset(relocs, 0, sizeof(relocs));
+
+	build_r4000_tlbchange_handler_head(&p, &l, &r, K0, K1);
+	build_pte_modifiable(&p, &l, &r, K0, K1, label_nopage_tlbm);
+	/* Present and writable bits set, set accessed and dirty bits. */
+	build_make_write(&p, &r, K0, K1);
+	build_r4000_tlbchange_handler_tail(&p, &l, &r, K0, K1);
+
+	l_nopage_tlbm(&l, p);
+	i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
+	i_nop(&p);
+
+	if ((p - handle_tlbm) > FASTPATH_SIZE)
+		panic("TLB modify handler fastpath space exceeded");
+
+	resolve_relocs(relocs, labels);
+	printk("Synthesized TLB modify handler fastpath (%u instructions).\n",
+	       (unsigned int)(p - handle_tlbm));
+
+#ifdef DEBUG_TLB
+	{
+		int i;
+
+		for (i = 0; i < FASTPATH_SIZE; i++)
+			printk("%08x\n", handle_tlbm[i]);
+	}
+#endif
+
+	flush_icache_range((unsigned long)handle_tlbm,
+			   (unsigned long)handle_tlbm + FASTPATH_SIZE * sizeof(u32));
+}
+
 void __init build_tlb_refill_handler(void)
 {
+	/*
+	 * The refill handler is generated per-CPU, multi-node systems
+	 * may have local storage for it. The other handlers are only
+	 * needed once.
+	 */
+	static int run_once = 0;
+
 	switch (current_cpu_data.cputype) {
-#ifdef CONFIG_MIPS32
 	case CPU_R2000:
 	case CPU_R3000:
 	case CPU_R3000A:
@@ -1159,13 +1786,18 @@
 	case CPU_TX3922:
 	case CPU_TX3927:
 		build_r3000_tlb_refill_handler();
+		if (!run_once) {
+			build_r3000_tlb_load_handler();
+			build_r3000_tlb_store_handler();
+			build_r3000_tlb_modify_handler();
+			run_once++;
+		}
 		break;
 
 	case CPU_R6000:
 	case CPU_R6000A:
 		panic("No R6000 TLB refill handler yet");
 		break;
-#endif
 
 	case CPU_R8000:
 		panic("No R8000 TLB refill handler yet");
@@ -1173,5 +1805,11 @@
 
 	default:
 		build_r4000_tlb_refill_handler();
+		if (!run_once) {
+			build_r4000_tlb_load_handler();
+			build_r4000_tlb_store_handler();
+			build_r4000_tlb_modify_handler();
+			run_once++;
+		}
 	}
 }
diff -Nru a/arch/mips/mm/tlbex32-mips32.S b/arch/mips/mm/tlbex32-mips32.S
--- a/arch/mips/mm/tlbex32-mips32.S	2005-03-01 23:39:07 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,253 +0,0 @@
-/*
- * TLB exception handling code for MIPS32 CPUs.
- *
- * Copyright (C) 1994, 1995, 1996 by Ralf Baechle and Andreas Busse
- *
- * Multi-cpu abstraction and reworking:
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- *
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
- *
- * Pete Popov, ppopov@pacbell.net
- * Added 36 bit phys address support.
- * Copyright (C) 2002 MontaVista Software, Inc.
- */
-#include <linux/init.h>
-#include <asm/asm.h>
-#include <asm/cachectl.h>
-#include <asm/fpregdef.h>
-#include <asm/mipsregs.h>
-#include <asm/page.h>
-#include <asm/pgtable-bits.h>
-#include <asm/regdef.h>
-#include <asm/stackframe.h>
-
-#define TLB_OPTIMIZE /* If you are paranoid, disable this. */
-
-#ifdef CONFIG_64BIT_PHYS_ADDR
-
-/* We really only support 36 bit physical addresses on MIPS32 */
-#define PTE_L		lw
-#define PTE_S		sw
-#define PTE_SRL		srl
-#define P_MTC0		mtc0
-#define PTE_HALF        4 /* pte_high contains pre-shifted, ready to go entry */
-#define PTE_SIZE        8
-#define PTEP_INDX_MSK	0xff0
-#define PTE_INDX_MSK	0xff8
-#define PTE_INDX_SHIFT 9
-#define CONVERT_PTE(pte)
-#define PTE_MAKEWRITE_HIGH(pte, ptr) \
-	lw	pte, PTE_HALF(ptr); \
-	ori	pte, (_PAGE_VALID | _PAGE_DIRTY); \
-	sw	pte, PTE_HALF(ptr); \
-	lw	pte, 0(ptr);
-
-#define PTE_MAKEVALID_HIGH(pte, ptr) \
-	lw	pte, PTE_HALF(ptr); \
-	ori	pte, pte, _PAGE_VALID; \
-	sw	pte, PTE_HALF(ptr); \
-	lw	pte, 0(ptr);
-
-#else
-
-#define PTE_L		lw
-#define PTE_S		sw
-#define PTE_SRL		srl
-#define P_MTC0		mtc0
-#define PTE_HALF        0
-#define PTE_SIZE	4
-#define PTEP_INDX_MSK	0xff8
-#define PTE_INDX_MSK	0xffc
-#define PTE_INDX_SHIFT	10
-#define CONVERT_PTE(pte) srl pte, pte, 6
-#define PTE_MAKEWRITE_HIGH(pte, ptr)
-#define PTE_MAKEVALID_HIGH(pte, ptr)
-
-#endif  /* CONFIG_64BIT_PHYS_ADDR */
-
-#ifdef CONFIG_64BIT_PHYS_ADDR
-#define GET_PTE_OFF(reg)
-#else
-#define GET_PTE_OFF(reg)	srl	reg, reg, 1
-#endif
-
-/*
- * ABUSE of CPP macros 101.
- *
- * After this macro runs, the pte faulted on is
- * in register PTE, a ptr into the table in which
- * the pte belongs is in PTR.
- */
-
-#ifdef CONFIG_SMP
-#define GET_PGD(scratch, ptr)        \
-	mfc0    ptr, CP0_CONTEXT;    \
-	la      scratch, pgd_current;\
-	srl     ptr, 23;             \
-	sll     ptr, 2;              \
-	addu    ptr, scratch, ptr;   \
-	lw      ptr, (ptr);
-#else
-#define GET_PGD(scratch, ptr)    \
-	lw	ptr, pgd_current;
-#endif
-
-#define LOAD_PTE(pte, ptr) \
-	GET_PGD(pte, ptr)          \
-	mfc0	pte, CP0_BADVADDR; \
-	srl	pte, pte, _PGDIR_SHIFT; \
-	sll	pte, pte, 2; \
-	addu	ptr, ptr, pte; \
-	mfc0	pte, CP0_BADVADDR; \
-	lw	ptr, (ptr); \
-	srl	pte, pte, PTE_INDX_SHIFT; \
-	and	pte, pte, PTE_INDX_MSK; \
-	addu	ptr, ptr, pte; \
-	PTE_L	pte, (ptr);
-
-	/* This places the even/odd pte pair in the page
-	 * table at PTR into ENTRYLO0 and ENTRYLO1 using
-	 * TMP as a scratch register.
-	 */
-#define PTE_RELOAD(ptr, tmp) \
-	ori	ptr, ptr, PTE_SIZE; \
-	xori	ptr, ptr, PTE_SIZE; \
-	PTE_L	tmp, (PTE_HALF+PTE_SIZE)(ptr); \
-	CONVERT_PTE(tmp); \
-	P_MTC0	tmp, CP0_ENTRYLO1; \
-	PTE_L	ptr, PTE_HALF(ptr); \
-	CONVERT_PTE(ptr); \
-	P_MTC0	ptr, CP0_ENTRYLO0;
-
-#define DO_FAULT(write) \
-	.set	noat; \
-	SAVE_ALL; \
-	mfc0	a2, CP0_BADVADDR; \
-	KMODE; \
-	.set	at; \
-	move	a0, sp; \
-	jal	do_page_fault; \
-	 li	a1, write; \
-	j	ret_from_exception; \
-	 nop; \
-	.set	noat;
-
-	/* Check is PTE is present, if not then jump to LABEL.
-	 * PTR points to the page table where this PTE is located,
-	 * when the macro is done executing PTE will be restored
-	 * with it's original value.
-	 */
-#define PTE_PRESENT(pte, ptr, label) \
-	andi	pte, pte, (_PAGE_PRESENT | _PAGE_READ); \
-	xori	pte, pte, (_PAGE_PRESENT | _PAGE_READ); \
-	bnez	pte, label; \
-	PTE_L	pte, (ptr);
-
-	/* Make PTE valid, store result in PTR. */
-#define PTE_MAKEVALID(pte, ptr) \
-	ori	pte, pte, (_PAGE_VALID | _PAGE_ACCESSED); \
-	PTE_S	pte, (ptr);
-
-	/* Check if PTE can be written to, if not branch to LABEL.
-	 * Regardless restore PTE with value from PTR when done.
-	 */
-#define PTE_WRITABLE(pte, ptr, label) \
-	andi	pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \
-	xori	pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \
-	bnez	pte, label; \
-	PTE_L	pte, (ptr);
-
-	/* Make PTE writable, update software status bits as well,
-	 * then store at PTR.
-	 */
-#define PTE_MAKEWRITE(pte, ptr) \
-	ori	pte, pte, (_PAGE_ACCESSED | _PAGE_MODIFIED | \
-			   _PAGE_VALID | _PAGE_DIRTY); \
-	PTE_S	pte, (ptr);
-
-	.set	noreorder
-
-	.align	5
-	NESTED(handle_tlbl, PT_SIZE, sp)
-	.set	noat
-invalid_tlbl:
-#ifdef TLB_OPTIMIZE
-	/* Test present bit in entry. */
-	LOAD_PTE(k0, k1)
-	tlbp
-	PTE_PRESENT(k0, k1, nopage_tlbl)
-	PTE_MAKEVALID_HIGH(k0, k1)
-	PTE_MAKEVALID(k0, k1)
-	PTE_RELOAD(k1, k0)
-	nop
-	b	1f
-	 tlbwi
-1:
-	nop
-	.set	mips3
-	eret
-	.set	mips0
-#endif
-
-nopage_tlbl:
-	DO_FAULT(0)
-	END(handle_tlbl)
-
-	.align	5
-	NESTED(handle_tlbs, PT_SIZE, sp)
-	.set	noat
-#ifdef TLB_OPTIMIZE
-	.set	mips3
-        li      k0,0
-	LOAD_PTE(k0, k1)
-	tlbp				# find faulting entry
-	PTE_WRITABLE(k0, k1, nopage_tlbs)
-	PTE_MAKEWRITE(k0, k1)
-	PTE_MAKEWRITE_HIGH(k0, k1)
-	PTE_RELOAD(k1, k0)
-	nop
-	b	1f
-	 tlbwi
-1:
-	nop
-	.set	mips3
-	eret
-	.set	mips0
-#endif
-
-nopage_tlbs:
-	DO_FAULT(1)
-	END(handle_tlbs)
-
-	.align	5
-	NESTED(handle_mod, PT_SIZE, sp)
-	.set	noat
-#ifdef TLB_OPTIMIZE
-	.set	mips3
-	LOAD_PTE(k0, k1)
-	tlbp					# find faulting entry
-	andi	k0, k0, _PAGE_WRITE
-	beqz	k0, nowrite_mod
-	PTE_L	k0, (k1)
-
-	/* Present and writable bits set, set accessed and dirty bits. */
-	PTE_MAKEWRITE(k0, k1)
-	PTE_MAKEWRITE_HIGH(k0, k1)
-	/* Now reload the entry into the tlb. */
-	PTE_RELOAD(k1, k0)
-	nop
-	b	1f
-	 tlbwi
-1:
-	nop
-	.set	mips3
-	eret
-	.set	mips0
-#endif
-
-nowrite_mod:
-	DO_FAULT(1)
-	END(handle_mod)
-
diff -Nru a/arch/mips/mm/tlbex32-r3k.S b/arch/mips/mm/tlbex32-r3k.S
--- a/arch/mips/mm/tlbex32-r3k.S	2005-03-01 23:39:07 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,194 +0,0 @@
-/*
- * TLB exception handling code for R2000/R3000.
- *
- * Copyright (C) 1994, 1995, 1996 by Ralf Baechle and Andreas Busse
- *
- * Multi-CPU abstraction reworking:
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- *
- * Further modifications to make this work:
- * Copyright (c) 1998 Harald Koerfgen
- * Copyright (c) 1998, 1999 Gleb Raiko & Vladimir Roganov
- * Copyright (c) 2001 Ralf Baechle
- * Copyright (c) 2001 MIPS Technologies, Inc.
- */
-#include <linux/init.h>
-#include <asm/asm.h>
-#include <asm/cachectl.h>
-#include <asm/fpregdef.h>
-#include <asm/mipsregs.h>
-#include <asm/page.h>
-#include <asm/pgtable-bits.h>
-#include <asm/regdef.h>
-#include <asm/stackframe.h>
-
-#define TLB_OPTIMIZE /* If you are paranoid, disable this. */
-
-	/* ABUSE of CPP macros 101. */
-
-	/* After this macro runs, the pte faulted on is
-	 * in register PTE, a ptr into the table in which
-	 * the pte belongs is in PTR.
-	 */
-#define LOAD_PTE(pte, ptr) \
-	mfc0	pte, CP0_BADVADDR; \
-	lw	ptr, pgd_current; \
-	srl	pte, pte, 22; \
-	sll	pte, pte, 2; \
-	addu	ptr, ptr, pte; \
-	mfc0	pte, CP0_CONTEXT; \
-	lw	ptr, (ptr); \
-	andi	pte, pte, 0xffc; \
-	addu	ptr, ptr, pte; \
-	lw	pte, (ptr); \
-	nop;
-
-	/* This places the even/odd pte pair in the page
-	 * table at PTR into ENTRYLO0 and ENTRYLO1 using
-	 * TMP as a scratch register.
-	 */
-#define PTE_RELOAD(ptr) \
-	lw	ptr, (ptr)	; \
-	nop			; \
-	mtc0	ptr, CP0_ENTRYLO0; \
-	nop;
-
-#define DO_FAULT(write) \
-	.set	noat; \
-	.set	macro; \
-	SAVE_ALL; \
-	mfc0	a2, CP0_BADVADDR; \
-	KMODE; \
-	.set	at; \
-	move	a0, sp; \
-	jal	do_page_fault; \
-	 li	a1, write; \
-	j	ret_from_exception; \
-	 nop; \
-	.set	noat; \
-	.set	nomacro;
-
-	/* Check is PTE is present, if not then jump to LABEL.
-	 * PTR points to the page table where this PTE is located,
-	 * when the macro is done executing PTE will be restored
-	 * with it's original value.
-	 */
-#define PTE_PRESENT(pte, ptr, label) \
-	andi	pte, pte, (_PAGE_PRESENT | _PAGE_READ); \
-	xori	pte, pte, (_PAGE_PRESENT | _PAGE_READ); \
-	bnez	pte, label; \
-	.set	push;       \
-	.set	reorder;    \
-	 lw	pte, (ptr); \
-	.set	pop;
-
-	/* Make PTE valid, store result in PTR. */
-#define PTE_MAKEVALID(pte, ptr) \
-	ori	pte, pte, (_PAGE_VALID | _PAGE_ACCESSED); \
-	sw	pte, (ptr);
-
-	/* Check if PTE can be written to, if not branch to LABEL.
-	 * Regardless restore PTE with value from PTR when done.
-	 */
-#define PTE_WRITABLE(pte, ptr, label) \
-	andi	pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \
-	xori	pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \
-	bnez	pte, label; \
-	.set    push;       \
-	.set    reorder;    \
-	lw      pte, (ptr); \
-	.set    pop;
-
-
-	/* Make PTE writable, update software status bits as well,
-	 * then store at PTR.
-	 */
-#define PTE_MAKEWRITE(pte, ptr) \
-	ori	pte, pte, (_PAGE_ACCESSED | _PAGE_MODIFIED | \
-			   _PAGE_VALID | _PAGE_DIRTY); \
-	sw	pte, (ptr);
-
-/*
- * The index register may have the probe fail bit set,
- * because we would trap on access kseg2, i.e. without refill.
- */
-#define TLB_WRITE(reg) \
-	mfc0	reg, CP0_INDEX; \
-	nop; \
-	bltz    reg, 1f; \
-	 nop; \
-	tlbwi; \
-	j	2f; \
-	 nop; \
-1:	tlbwr; \
-2:
-
-#define RET(reg) \
-	mfc0	reg, CP0_EPC; \
-	nop; \
-	jr	reg; \
-	 rfe
-
-	.set	noreorder
-
-	.align	5
-NESTED(handle_tlbl, PT_SIZE, sp)
-	.set	noat
-
-#ifdef TLB_OPTIMIZE
-	/* Test present bit in entry. */
-	LOAD_PTE(k0, k1)
-        tlbp
-        PTE_PRESENT(k0, k1, nopage_tlbl)
-        PTE_MAKEVALID(k0, k1)
-        PTE_RELOAD(k1)
-	TLB_WRITE(k0)
-	RET(k0)
-nopage_tlbl:
-#endif
-
-	DO_FAULT(0)
-END(handle_tlbl)
-
-NESTED(handle_tlbs, PT_SIZE, sp)
-	.set	noat
-
-#ifdef TLB_OPTIMIZE
-	LOAD_PTE(k0, k1)
-	tlbp                            # find faulting entry
-	PTE_WRITABLE(k0, k1, nopage_tlbs)
-	PTE_MAKEWRITE(k0, k1)
-	PTE_RELOAD(k1)
-	TLB_WRITE(k0)
-	RET(k0)
-nopage_tlbs:
-#endif
-
-	DO_FAULT(1)
-END(handle_tlbs)
-
-	.align	5
-NESTED(handle_mod, PT_SIZE, sp)
-	.set	noat
-#ifdef TLB_OPTIMIZE
-	LOAD_PTE(k0, k1)
-	tlbp					# find faulting entry
-	andi	k0, k0, _PAGE_WRITE
-	beqz	k0, nowrite_mod
-	.set	push
-	.set    reorder
-	lw	k0, (k1)
-	.set    pop
-
-	/* Present and writable bits set, set accessed and dirty bits. */
-	PTE_MAKEWRITE(k0, k1)
-
-	/* Now reload the entry into the tlb. */
-	PTE_RELOAD(k1)
-	tlbwi
-	RET(k0)
-#endif
-
-nowrite_mod:
-	DO_FAULT(1)
-END(handle_mod)
diff -Nru a/arch/mips/mm/tlbex32-r4k.S b/arch/mips/mm/tlbex32-r4k.S
--- a/arch/mips/mm/tlbex32-r4k.S	2005-03-01 23:39:16 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,262 +0,0 @@
-/*
- * TLB exception handling code for r4k.
- *
- * Copyright (C) 1994, 1995, 1996 by Ralf Baechle and Andreas Busse
- *
- * Multi-cpu abstraction and reworking:
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- *
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
- */
-#include <linux/init.h>
-#include <linux/config.h>
-
-#include <asm/asm.h>
-#include <asm/offset.h>
-#include <asm/cachectl.h>
-#include <asm/fpregdef.h>
-#include <asm/mipsregs.h>
-#include <asm/page.h>
-#include <asm/pgtable-bits.h>
-#include <asm/regdef.h>
-#include <asm/stackframe.h>
-#include <asm/war.h>
-
-#define TLB_OPTIMIZE /* If you are paranoid, disable this. */
-
-#ifdef CONFIG_64BIT_PHYS_ADDR
-#define PTE_L		ld
-#define PTE_S		sd
-#define PTE_SRL		dsrl
-#define P_MTC0		dmtc0
-#define PTE_SIZE	8
-#define PTEP_INDX_MSK	0xff0
-#define PTE_INDX_MSK	0xff8
-#define PTE_INDX_SHIFT	9
-#else
-#define PTE_L		lw
-#define PTE_S		sw
-#define PTE_SRL		srl
-#define P_MTC0		mtc0
-#define PTE_SIZE	4
-#define PTEP_INDX_MSK	0xff8
-#define PTE_INDX_MSK	0xffc
-#define PTE_INDX_SHIFT	10
-#endif
-
-/*
- * ABUSE of CPP macros 101.
- *
- * After this macro runs, the pte faulted on is
- * in register PTE, a ptr into the table in which
- * the pte belongs is in PTR.
- */
-
-#ifdef CONFIG_SMP
-#define GET_PGD(scratch, ptr)        \
-	mfc0    ptr, CP0_CONTEXT;    \
-	la      scratch, pgd_current;\
-	srl     ptr, 23;             \
-	sll     ptr, 2;              \
-	addu    ptr, scratch, ptr;   \
-	lw      ptr, (ptr);
-#else
-#define GET_PGD(scratch, ptr)    \
-	lw	ptr, pgd_current;
-#endif
-
-#define LOAD_PTE(pte, ptr) \
-	GET_PGD(pte, ptr)          \
-	mfc0	pte, CP0_BADVADDR; \
-	srl	pte, pte, _PGDIR_SHIFT; \
-	sll	pte, pte, 2; \
-	addu	ptr, ptr, pte; \
-	mfc0	pte, CP0_BADVADDR; \
-	lw	ptr, (ptr); \
-	srl	pte, pte, PTE_INDX_SHIFT; \
-	and	pte, pte, PTE_INDX_MSK; \
-	addu	ptr, ptr, pte; \
-	PTE_L	pte, (ptr);
-
-	/* This places the even/odd pte pair in the page
-	 * table at PTR into ENTRYLO0 and ENTRYLO1 using
-	 * TMP as a scratch register.
-	 */
-#define PTE_RELOAD(ptr, tmp) \
-	ori	ptr, ptr, PTE_SIZE; \
-	xori	ptr, ptr, PTE_SIZE; \
-	PTE_L	tmp, PTE_SIZE(ptr); \
-	PTE_L	ptr, 0(ptr); \
-	PTE_SRL	tmp, tmp, 6; \
-	P_MTC0	tmp, CP0_ENTRYLO1; \
-	PTE_SRL	ptr, ptr, 6; \
-	P_MTC0	ptr, CP0_ENTRYLO0;
-
-#define DO_FAULT(write) \
-	.set	noat; \
-	SAVE_ALL; \
-	mfc0	a2, CP0_BADVADDR; \
-	KMODE; \
-	.set	at; \
-	move	a0, sp; \
-	jal	do_page_fault; \
-	 li	a1, write; \
-	j	ret_from_exception; \
-	 nop; \
-	.set	noat;
-
-	/* Check is PTE is present, if not then jump to LABEL.
-	 * PTR points to the page table where this PTE is located,
-	 * when the macro is done executing PTE will be restored
-	 * with it's original value.
-	 */
-#define PTE_PRESENT(pte, ptr, label) \
-	andi	pte, pte, (_PAGE_PRESENT | _PAGE_READ); \
-	xori	pte, pte, (_PAGE_PRESENT | _PAGE_READ); \
-	bnez	pte, label; \
-	 PTE_L	pte, (ptr);
-
-	/* Make PTE valid, store result in PTR. */
-#define PTE_MAKEVALID(pte, ptr) \
-	ori	pte, pte, (_PAGE_VALID | _PAGE_ACCESSED); \
-	PTE_S	pte, (ptr);
-
-	/* Check if PTE can be written to, if not branch to LABEL.
-	 * Regardless restore PTE with value from PTR when done.
-	 */
-#define PTE_WRITABLE(pte, ptr, label) \
-	andi	pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \
-	xori	pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \
-	bnez	pte, label; \
-	 PTE_L	pte, (ptr);
-
-	/* Make PTE writable, update software status bits as well,
-	 * then store at PTR.
-	 */
-#define PTE_MAKEWRITE(pte, ptr) \
-	ori	pte, pte, (_PAGE_ACCESSED | _PAGE_MODIFIED | \
-			   _PAGE_VALID | _PAGE_DIRTY); \
-	PTE_S	pte, (ptr);
-
-
-	.set	noreorder
-
-/*
- * From the IDT errata for the QED RM5230 (Nevada), processor revision 1.0:
- * 2. A timing hazard exists for the TLBP instruction.
- *
- *      stalling_instruction
- *      TLBP
- *
- * The JTLB is being read for the TLBP throughout the stall generated by the
- * previous instruction. This is not really correct as the stalling instruction
- * can modify the address used to access the JTLB.  The failure symptom is that
- * the TLBP instruction will use an address created for the stalling instruction
- * and not the address held in C0_ENHI and thus report the wrong results.
- *
- * The software work-around is to not allow the instruction preceding the TLBP
- * to stall - make it an NOP or some other instruction guaranteed not to stall.
- *
- * Errata 2 will not be fixed.  This errata is also on the R5000.
- *
- * As if we MIPS hackers wouldn't know how to nop pipelines happy ...
- */
-#define R5K_HAZARD nop
-
-	/*
-	 * Note for many R4k variants tlb probes cannot be executed out
-	 * of the instruction cache else you get bogus results.
-	 */
-	.align	5
-	NESTED(handle_tlbl, PT_SIZE, sp)
-	.set	noat
-#if BCM1250_M3_WAR
-	mfc0	k0, CP0_BADVADDR
-	mfc0	k1, CP0_ENTRYHI
-	xor	k0, k1
-	srl	k0, k0, PAGE_SHIFT+1
-	beqz	k0, 1f
-	 nop
-	.set	mips3
-	eret
-	.set	mips0
-1:
-#endif
-invalid_tlbl:
-#ifdef TLB_OPTIMIZE
-	.set	mips3
-	/* Test present bit in entry. */
-	LOAD_PTE(k0, k1)
-	R5K_HAZARD
-	tlbp
-	PTE_PRESENT(k0, k1, nopage_tlbl)
-	PTE_MAKEVALID(k0, k1)
-	PTE_RELOAD(k1, k0)
-	mtc0_tlbw_hazard
-	tlbwi
-	nop
-	tlbw_eret_hazard
-	.set	mips3
-	eret
-	.set	mips0
-#endif
-
-nopage_tlbl:
-	DO_FAULT(0)
-	END(handle_tlbl)
-
-	.align	5
-	NESTED(handle_tlbs, PT_SIZE, sp)
-	.set	noat
-#ifdef TLB_OPTIMIZE
-	.set	mips3
-        li      k0,0
-	LOAD_PTE(k0, k1)
-	R5K_HAZARD
-	tlbp				# find faulting entry
-	PTE_WRITABLE(k0, k1, nopage_tlbs)
-	PTE_MAKEWRITE(k0, k1)
-	PTE_RELOAD(k1, k0)
-	mtc0_tlbw_hazard
-	tlbwi
-	nop
-	tlbw_eret_hazard
-	.set	mips3
-	eret
-	.set	mips0
-#endif
-
-nopage_tlbs:
-	DO_FAULT(1)
-	END(handle_tlbs)
-
-	.align	5
-	NESTED(handle_mod, PT_SIZE, sp)
-	.set	noat
-#ifdef TLB_OPTIMIZE
-	.set	mips3
-	LOAD_PTE(k0, k1)
-	R5K_HAZARD
-	tlbp					# find faulting entry
-	andi	k0, k0, _PAGE_WRITE
-	beqz	k0, nowrite_mod
-	 PTE_L	k0, (k1)
-
-	/* Present and writable bits set, set accessed and dirty bits. */
-	PTE_MAKEWRITE(k0, k1)
-
-	/* Now reload the entry into the tlb. */
-	PTE_RELOAD(k1, k0)
-	mtc0_tlbw_hazard
-	tlbwi
-	nop
-	tlbw_eret_hazard
-	.set	mips3
-	eret
-	.set	mips0
-#endif
-
-nowrite_mod:
-	DO_FAULT(1)
-	END(handle_mod)
diff -Nru a/arch/mips/momentum/ocelot_3/reset.c b/arch/mips/momentum/ocelot_3/reset.c
--- a/arch/mips/momentum/ocelot_3/reset.c	2005-03-01 23:38:52 -08:00
+++ b/arch/mips/momentum/ocelot_3/reset.c	2005-03-01 23:38:52 -08:00
@@ -4,7 +4,7 @@
  * Free Software Foundation;  either version 2 of the  License, or (at your
  * option) any later version.
  *
- * Copyright (C) 1997, 2001 Ralf Baechle
+ * Copyright (C) 1997, 01, 05 Ralf Baechle
  * Copyright 2001 MontaVista Software Inc.
  * Author: jsun@mvista.com or jsun@junsun.net
  *
@@ -20,7 +20,6 @@
  * Copyright (C) 2004 MontaVista Software Inc.
  * Author: Manish Lachwani, mlachwani@mvista.com
  */
-#include <linux/config.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
 #include <linux/delay.h>
diff -Nru a/arch/mips/momentum/ocelot_3/setup.c b/arch/mips/momentum/ocelot_3/setup.c
--- a/arch/mips/momentum/ocelot_3/setup.c	2005-03-01 23:38:54 -08:00
+++ b/arch/mips/momentum/ocelot_3/setup.c	2005-03-01 23:38:54 -08:00
@@ -4,7 +4,7 @@
  * BRIEF MODULE DESCRIPTION
  * Momentum Computer Ocelot-3 board dependent boot routines
  *
- * Copyright (C) 1996, 1997, 2001  Ralf Baechle
+ * Copyright (C) 1996, 1997, 01, 05  Ralf Baechle
  * Copyright (C) 2000 RidgeRun, Inc.
  * Copyright (C) 2001 Red Hat, Inc.
  * Copyright (C) 2002 Momentum Computer
@@ -47,7 +47,6 @@
  *  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/kernel.h>
 #include <linux/types.h>
diff -Nru a/arch/mips/momentum/ocelot_c/irq.c b/arch/mips/momentum/ocelot_c/irq.c
--- a/arch/mips/momentum/ocelot_c/irq.c	2005-03-01 23:39:09 -08:00
+++ b/arch/mips/momentum/ocelot_c/irq.c	2005-03-01 23:39:09 -08:00
@@ -5,7 +5,7 @@
  *
  * Copyright 2001 MontaVista Software Inc.
  * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
- * Copyright (C) 2000, 2001 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 2000, 01, 05 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
@@ -28,7 +28,6 @@
  *  675 Mass Ave, Cambridge, MA 02139, USA.
  *
  */
-#include <linux/config.h>
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/kernel_stat.h>
diff -Nru a/arch/mips/momentum/ocelot_g/gt-irq.c b/arch/mips/momentum/ocelot_g/gt-irq.c
--- a/arch/mips/momentum/ocelot_g/gt-irq.c	2005-03-01 23:39:18 -08:00
+++ b/arch/mips/momentum/ocelot_g/gt-irq.c	2005-03-01 23:39:18 -08:00
@@ -11,6 +11,7 @@
  * Free Software Foundation;  either version 2 of the  License, or (at your
  * option) any later version.
  */
+#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
diff -Nru a/arch/mips/momentum/ocelot_g/irq.c b/arch/mips/momentum/ocelot_g/irq.c
--- a/arch/mips/momentum/ocelot_g/irq.c	2005-03-01 23:38:54 -08:00
+++ b/arch/mips/momentum/ocelot_g/irq.c	2005-03-01 23:38:54 -08:00
@@ -5,7 +5,7 @@
  *
  * Copyright 2001 MontaVista Software Inc.
  * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
- * Copyright (C) 2000, 2001 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 2000, 01, 05 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
@@ -28,7 +28,6 @@
  *  675 Mass Ave, Cambridge, MA 02139, USA.
  *
  */
-#include <linux/config.h>
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/kernel_stat.h>
diff -Nru a/arch/mips/oprofile/Kconfig b/arch/mips/oprofile/Kconfig
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/mips/oprofile/Kconfig	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,23 @@
+
+menu "Profiling support"
+	depends on EXPERIMENTAL
+
+config PROFILING
+	bool "Profiling support (EXPERIMENTAL)"
+	help
+	  Say Y here to enable the extended profiling support mechanisms used
+	  by profilers such as OProfile.
+
+
+config OPROFILE
+	tristate "OProfile system profiling (EXPERIMENTAL)"
+	depends on PROFILING
+	help
+	  OProfile is a profiling system capable of profiling the
+	  whole system, include the kernel, kernel modules, libraries,
+	  and applications.
+
+	  If unsure, say N.
+
+endmenu
+
diff -Nru a/arch/mips/oprofile/Makefile b/arch/mips/oprofile/Makefile
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/mips/oprofile/Makefile	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,15 @@
+EXTRA_CFLAGS := -Werror
+
+obj-$(CONFIG_OPROFILE) += oprofile.o
+
+DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \
+		oprof.o cpu_buffer.o buffer_sync.o \
+		event_buffer.o oprofile_files.o \
+		oprofilefs.o oprofile_stats.o \
+		timer_int.o )
+
+oprofile-y				:= $(DRIVER_OBJS) common.o
+
+oprofile-$(CONFIG_CPU_MIPS32)		+= op_model_mipsxx.o
+oprofile-$(CONFIG_CPU_MIPS64)		+= op_model_mipsxx.o
+oprofile-$(CONFIG_CPU_RM9000)		+= op_model_rm9000.o
diff -Nru a/arch/mips/oprofile/common.c b/arch/mips/oprofile/common.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/mips/oprofile/common.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,106 @@
+/*
+ * This file 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 by Ralf Baechle
+ */
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/oprofile.h>
+#include <linux/smp.h>
+#include <asm/cpu-info.h>
+
+#include "op_impl.h"
+
+extern struct op_mips_model op_model_mipsxx __attribute__((weak));
+extern struct op_mips_model op_model_rm9000 __attribute__((weak));
+
+static struct op_mips_model *model;
+
+static struct op_counter_config ctr[20];
+
+static int op_mips_setup(void)
+{
+	/* Pre-compute the values to stuff in the hardware registers.  */
+	model->reg_setup(ctr);
+
+	/* Configure the registers on all cpus.  */
+	on_each_cpu(model->cpu_setup, 0, 0, 1);
+
+        return 0;
+}
+
+static int op_mips_create_files(struct super_block * sb, struct dentry * root)
+{
+	int i;
+
+	for (i = 0; i < model->num_counters; ++i) {
+		struct dentry *dir;
+		char buf[3];
+
+		snprintf(buf, sizeof buf, "%d", i);
+		dir = oprofilefs_mkdir(sb, root, buf);
+
+		oprofilefs_create_ulong(sb, dir, "enabled", &ctr[i].enabled);
+		oprofilefs_create_ulong(sb, dir, "event", &ctr[i].event);
+		oprofilefs_create_ulong(sb, dir, "count", &ctr[i].count);
+		/* Dummies.  */
+		oprofilefs_create_ulong(sb, dir, "kernel", &ctr[i].kernel);
+		oprofilefs_create_ulong(sb, dir, "user", &ctr[i].user);
+		oprofilefs_create_ulong(sb, dir, "exl", &ctr[i].exl);
+		oprofilefs_create_ulong(sb, dir, "unit_mask", &ctr[i].unit_mask);
+	}
+
+	return 0;
+}
+
+static int op_mips_start(void)
+{
+	on_each_cpu(model->cpu_start, NULL, 0, 1);
+
+	return 0;
+}
+
+static void op_mips_stop(void)
+{
+	/* Disable performance monitoring for all counters.  */
+	on_each_cpu(model->cpu_stop, NULL, 0, 1);
+}
+
+void __init oprofile_arch_init(struct oprofile_operations *ops)
+{
+	struct op_mips_model *lmodel = NULL;
+
+	switch (current_cpu_data.cputype) {
+	case CPU_24K:
+		lmodel = &op_model_mipsxx;
+		break;
+
+	case CPU_RM9000:
+		lmodel = &op_model_rm9000;
+		break;
+	};
+
+	if (!lmodel)
+		return;
+
+	if (lmodel->init())
+		return;
+
+	model = lmodel;
+
+	ops->create_files = op_mips_create_files;
+	ops->setup = op_mips_setup;
+	ops->start = op_mips_start;
+	ops->stop = op_mips_stop;
+	ops->cpu_type = lmodel->cpu_type;
+
+	printk(KERN_INFO "oprofile: using %s performance monitoring.\n",
+	       lmodel->cpu_type);
+}
+
+void oprofile_arch_exit(void)
+{
+	model->exit();
+}
diff -Nru a/arch/mips/oprofile/op_impl.h b/arch/mips/oprofile/op_impl.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/mips/oprofile/op_impl.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,37 @@
+/**
+ * @file arch/alpha/oprofile/op_impl.h
+ *
+ * @remark Copyright 2002 OProfile authors
+ * @remark Read the file COPYING
+ *
+ * @author Richard Henderson <rth@twiddle.net>
+ */
+
+#ifndef OP_IMPL_H
+#define OP_IMPL_H 1
+
+/* Per-counter configuration as set via oprofilefs.  */
+struct op_counter_config {
+	unsigned long enabled;
+	unsigned long event;
+	unsigned long count;
+	/* Dummies because I am too lazy to hack the userspace tools.  */
+	unsigned long kernel;
+	unsigned long user;
+	unsigned long exl;
+	unsigned long unit_mask;
+};
+
+/* Per-architecture configury and hooks.  */
+struct op_mips_model {
+	void (*reg_setup) (struct op_counter_config *);
+	void (*cpu_setup) (void * dummy);
+	int (*init)(void);
+	void (*exit)(void);
+	void (*cpu_start)(void *args);
+	void (*cpu_stop)(void *args);
+	char *cpu_type;
+	unsigned char num_counters;
+};
+
+#endif
diff -Nru a/arch/mips/oprofile/op_model_rm9000.c b/arch/mips/oprofile/op_model_rm9000.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/mips/oprofile/op_model_rm9000.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,137 @@
+/*
+ * This file 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 by Ralf Baechle
+ */
+#include <linux/oprofile.h>
+#include <linux/interrupt.h>
+#include <linux/smp.h>
+
+#include "op_impl.h"
+
+#define RM9K_COUNTER1_EVENT(event)	((event) << 0)
+#define RM9K_COUNTER1_SUPERVISOR	(1ULL    <<  7)
+#define RM9K_COUNTER1_KERNEL		(1ULL    <<  8)
+#define RM9K_COUNTER1_USER		(1ULL    <<  9)
+#define RM9K_COUNTER1_ENABLE		(1ULL    << 10)
+#define RM9K_COUNTER1_OVERFLOW		(1ULL    << 15)
+
+#define RM9K_COUNTER2_EVENT(event)	((event) << 16)
+#define RM9K_COUNTER2_SUPERVISOR	(1ULL    << 23)
+#define RM9K_COUNTER2_KERNEL		(1ULL    << 24)
+#define RM9K_COUNTER2_USER		(1ULL    << 25)
+#define RM9K_COUNTER2_ENABLE		(1ULL    << 26)
+#define RM9K_COUNTER2_OVERFLOW		(1ULL    << 31)
+
+extern unsigned int rm9000_perfcount_irq;
+
+static struct rm9k_register_config {
+	unsigned int control;
+	unsigned int reset_counter1;
+	unsigned int reset_counter2;
+} reg;
+
+/* Compute all of the registers in preparation for enabling profiling.  */
+
+static void rm9000_reg_setup(struct op_counter_config *ctr)
+{
+	unsigned int control = 0;
+
+	/* Compute the performance counter control word.  */
+	/* For now count kernel and user mode */
+	if (ctr[0].enabled)
+		control |= RM9K_COUNTER1_EVENT(ctr[0].event) |
+		           RM9K_COUNTER1_KERNEL |
+		           RM9K_COUNTER1_USER |
+		           RM9K_COUNTER1_ENABLE;
+	if (ctr[1].enabled)
+		control |= RM9K_COUNTER2_EVENT(ctr[1].event) |
+		           RM9K_COUNTER2_KERNEL |
+		           RM9K_COUNTER2_USER |
+		           RM9K_COUNTER2_ENABLE;
+	reg.control = control;
+
+	reg.reset_counter1 = 0x80000000 - ctr[0].count;
+	reg.reset_counter2 = 0x80000000 - ctr[1].count;
+}
+
+/* Program all of the registers in preparation for enabling profiling.  */
+
+static void rm9000_cpu_setup (void *args)
+{
+	uint64_t perfcount;
+
+	perfcount = ((uint64_t) reg.reset_counter2 << 32) | reg.reset_counter1;
+	write_c0_perfcount(perfcount);
+}
+
+static void rm9000_cpu_start(void *args)
+{
+	/* Start all counters on current CPU */
+	write_c0_perfcontrol(reg.control);
+}
+
+static void rm9000_cpu_stop(void *args)
+{
+	/* Stop all counters on current CPU */
+	write_c0_perfcontrol(0);
+}
+
+static irqreturn_t rm9000_perfcount_handler(int irq, void * dev_id,
+	struct pt_regs *regs)
+{
+	unsigned int control = read_c0_perfcontrol();
+	uint32_t counter1, counter2;
+	uint64_t counters;
+
+	/*
+	 * RM9000 combines two 32-bit performance counters into a single
+	 * 64-bit coprocessor zero register.  To avoid a race updating the
+	 * registers we need to stop the counters while we're messing with
+	 * them ...
+	 */
+	write_c0_perfcontrol(0);
+
+	counters = read_c0_perfcount();
+	counter1 = counters;
+	counter2 = counters >> 32;
+
+	if (control & RM9K_COUNTER1_OVERFLOW) {
+		oprofile_add_sample(regs, 0);
+		counter1 = reg.reset_counter1;
+	}
+	if (control & RM9K_COUNTER2_OVERFLOW) {
+		oprofile_add_sample(regs, 1);
+		counter2 = reg.reset_counter2;
+	}
+
+	counters = ((uint64_t)counter2 << 32) | counter1;
+	write_c0_perfcount(counters);
+	write_c0_perfcontrol(reg.control);
+
+	return IRQ_HANDLED;
+}
+
+static int rm9000_init(void)
+{
+	return request_irq(rm9000_perfcount_irq, rm9000_perfcount_handler,
+	                   0, "Perfcounter", NULL);
+}
+
+static void rm9000_exit(void)
+{
+	free_irq(rm9000_perfcount_irq, NULL);
+}
+
+struct op_mips_model op_model_rm9000 = {
+	.reg_setup	= rm9000_reg_setup,
+	.cpu_setup	= rm9000_cpu_setup,
+	.init		= rm9000_init,
+	.exit		= rm9000_exit,
+	.cpu_start	= rm9000_cpu_start,
+	.cpu_stop	= rm9000_cpu_stop,
+	.cpu_type	= "mips/rm9000",
+	.num_counters	= 2
+};
diff -Nru a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile
--- a/arch/mips/pci/Makefile	2005-03-01 23:38:44 -08:00
+++ b/arch/mips/pci/Makefile	2005-03-01 23:38:44 -08:00
@@ -17,6 +17,7 @@
 obj-$(CONFIG_MIPS_NILE4)	+= ops-nile4.o
 obj-$(CONFIG_MIPS_TX3927)	+= ops-jmr3927.o
 obj-$(CONFIG_PCI_VR41XX)	+= ops-vr41xx.o pci-vr41xx.o
+obj-$(CONFIG_NEC_CMBVR4133)	+= fixup-vr4133.o
 
 #
 # These are still pretty much in the old state, watch, go blind.
@@ -43,7 +44,7 @@
 				   pci-yosemite.o
 obj-$(CONFIG_SGI_IP27)		+= pci-ip27.o
 obj-$(CONFIG_SGI_IP32)		+= fixup-ip32.o ops-mace.o pci-ip32.o
-obj-$(CONFIG_SIBYTE_SB1250)	+= pci-sb1250.o
+obj-$(CONFIG_SIBYTE_SB1250)	+= fixup-sb1250.o pci-sb1250.o
 obj-$(CONFIG_SNI_RM200_PCI)	+= fixup-sni.o ops-sni.o
 obj-$(CONFIG_TANBAC_TB0219)	+= fixup-tb0219.o
 obj-$(CONFIG_TANBAC_TB0226)	+= fixup-tb0226.o
diff -Nru a/arch/mips/pci/fixup-atlas.c b/arch/mips/pci/fixup-atlas.c
--- a/arch/mips/pci/fixup-atlas.c	2005-03-01 23:39:18 -08:00
+++ b/arch/mips/pci/fixup-atlas.c	2005-03-01 23:39:18 -08:00
@@ -1,3 +1,4 @@
+#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <asm/mips-boards/atlasint.h>
diff -Nru a/arch/mips/pci/fixup-au1000.c b/arch/mips/pci/fixup-au1000.c
--- a/arch/mips/pci/fixup-au1000.c	2005-03-01 23:38:52 -08:00
+++ b/arch/mips/pci/fixup-au1000.c	2005-03-01 23:38:52 -08:00
@@ -98,6 +98,19 @@
 };
 #endif
 
+#ifdef CONFIG_MIPS_MTX1
+static char irq_tab_alchemy[][5] __initdata = {
+ [0] = { -1, INTA, INTB, INTX, INTX},   /* IDSEL 00 - AdapterA-Slot0 (top)    */
+ [1] = { -1, INTB, INTA, INTX, INTX},   /* IDSEL 01 - AdapterA-Slot1 (bottom) */
+ [2] = { -1, INTC, INTD, INTX, INTX},   /* IDSEL 02 - AdapterB-Slot0 (top)    */
+ [3] = { -1, INTD, INTC, INTX, INTX},   /* IDSEL 03 - AdapterB-Slot1 (bottom) */
+ [4] = { -1, INTA, INTB, INTX, INTX},   /* IDSEL 04 - AdapterC-Slot0 (top)    */
+ [5] = { -1, INTB, INTA, INTX, INTX},   /* IDSEL 05 - AdapterC-Slot1 (bottom) */
+ [6] = { -1, INTC, INTD, INTX, INTX},   /* IDSEL 06 - AdapterD-Slot0 (top)    */
+ [7] = { -1, INTD, INTC, INTX, INTX},   /* IDSEL 07 - AdapterD-Slot1 (bottom) */
+};
+#endif
+
 int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
 {
 	return irq_tab_alchemy[slot][pin];
diff -Nru a/arch/mips/pci/fixup-sb1250.c b/arch/mips/pci/fixup-sb1250.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/mips/pci/fixup-sb1250.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,24 @@
+/*
+ *	arch/mips/pci/fixup-sb1250.c
+ *
+ *	Copyright (C) 2004  MIPS Technologies, Inc.  All rights reserved.
+ *	    Author:	Maciej W. Rozycki <macro@mips.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/init.h>
+#include <linux/pci.h>
+
+/*
+ * The BCM1250, etc. PCI/HT bridge reports as a host bridge.
+ */
+static void __init quirk_sb1250_ht(struct pci_dev *dev)
+{
+	dev->class = PCI_CLASS_BRIDGE_PCI << 8;
+}
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SIBYTE, PCI_DEVICE_ID_BCM1250_HT,
+			quirk_sb1250_ht);
diff -Nru a/arch/mips/pci/fixup-vr4133.c b/arch/mips/pci/fixup-vr4133.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/mips/pci/fixup-vr4133.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,204 @@
+/*
+ * arch/mips/vr41xx/nec-cmbvr4133/pci_fixup.c
+ *
+ * The NEC CMB-VR4133 Board specific PCI fixups.
+ *
+ * Author: Yoichi Yuasa <yyuasa@mvista.com, or source@mvista.com> and
+ *         Alex Sapkov <asapkov@ru.mvista.com>
+ *
+ * 2003-2004 (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.
+ *
+ * Modified for support in 2.6
+ * Author: Manish Lachwani (mlachwani@mvista.com)
+ *
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+
+#include <asm/io.h>
+#include <asm/vr41xx/cmbvr4133.h>
+
+extern int vr4133_rockhopper;
+extern void ali_m1535plus_init(struct pci_dev *dev);
+extern void ali_m5229_init(struct pci_dev *dev);
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+	/*
+	 * We have to reset AMD PCnet adapter on Rockhopper since
+	 * PMON leaves it enabled and generating interrupts. This leads
+	 * to a lock if some PCI device driver later enables the IRQ line
+	 * shared with PCnet and there is no AMD PCnet driver to catch its
+	 * interrupts.
+	 */
+#ifdef CONFIG_ROCKHOPPER
+	if (dev->vendor == PCI_VENDOR_ID_AMD &&
+		dev->device == PCI_DEVICE_ID_AMD_LANCE) {
+		inl(pci_resource_start(dev, 0) + 0x18);
+	}
+#endif
+
+	/*
+	 * we have to open the bridges' windows down to 0 because otherwise
+ 	 * we cannot access ISA south bridge I/O registers that get mapped from
+	 * 0. for example, 8259 PIC would be unaccessible without that
+	 */
+	if(dev->vendor == PCI_VENDOR_ID_INTEL && dev->device == PCI_DEVICE_ID_INTEL_S21152BB) {
+		pci_write_config_byte(dev, PCI_IO_BASE, 0);
+		if(dev->bus->number == 0) {
+			pci_write_config_word(dev, PCI_IO_BASE_UPPER16, 0);
+		} else {
+			pci_write_config_word(dev, PCI_IO_BASE_UPPER16, 1);
+		}
+	}
+
+	return 0;
+}
+
+/*
+ * M1535 IRQ mapping
+ * Feel free to change this, although it shouldn't be needed
+ */
+#define M1535_IRQ_INTA  7
+#define M1535_IRQ_INTB  9
+#define M1535_IRQ_INTC  10
+#define M1535_IRQ_INTD  11
+
+#define M1535_IRQ_USB   9
+#define M1535_IRQ_IDE   14
+#define M1535_IRQ_IDE2  15
+#define M1535_IRQ_PS2   12
+#define M1535_IRQ_RTC   8
+#define M1535_IRQ_FDC   6
+#define M1535_IRQ_AUDIO 5
+#define M1535_IRQ_COM1  4
+#define M1535_IRQ_COM2  4
+#define M1535_IRQ_IRDA  3
+#define M1535_IRQ_KBD   1
+#define M1535_IRQ_TMR   0
+
+/* Rockhopper "slots" assignment; this is hard-coded ... */
+#define ROCKHOPPER_M5451_SLOT  1
+#define ROCKHOPPER_M1535_SLOT  2
+#define ROCKHOPPER_M5229_SLOT  11
+#define ROCKHOPPER_M5237_SLOT  15
+#define ROCKHOPPER_PMU_SLOT    12
+/* ... and hard-wired. */
+#define ROCKHOPPER_PCI1_SLOT   3
+#define ROCKHOPPER_PCI2_SLOT   4
+#define ROCKHOPPER_PCI3_SLOT   5
+#define ROCKHOPPER_PCI4_SLOT   6
+#define ROCKHOPPER_PCNET_SLOT  1
+
+#define M1535_IRQ_MASK(n) (1 << (n))
+
+#define M1535_IRQ_EDGE  (M1535_IRQ_MASK(M1535_IRQ_TMR)  | \
+                         M1535_IRQ_MASK(M1535_IRQ_KBD)  | \
+                         M1535_IRQ_MASK(M1535_IRQ_COM1) | \
+                         M1535_IRQ_MASK(M1535_IRQ_COM2) | \
+                         M1535_IRQ_MASK(M1535_IRQ_IRDA) | \
+                         M1535_IRQ_MASK(M1535_IRQ_RTC)  | \
+                         M1535_IRQ_MASK(M1535_IRQ_FDC)  | \
+                         M1535_IRQ_MASK(M1535_IRQ_PS2))
+
+#define M1535_IRQ_LEVEL (M1535_IRQ_MASK(M1535_IRQ_IDE)  | \
+                         M1535_IRQ_MASK(M1535_IRQ_USB)  | \
+                         M1535_IRQ_MASK(M1535_IRQ_INTA) | \
+                         M1535_IRQ_MASK(M1535_IRQ_INTB) | \
+                         M1535_IRQ_MASK(M1535_IRQ_INTC) | \
+                         M1535_IRQ_MASK(M1535_IRQ_INTD))
+
+struct irq_map_entry {
+	u16 bus;
+	u8 slot;
+	u8 irq;
+};
+static struct irq_map_entry int_map[] = {
+	{1, ROCKHOPPER_M5451_SLOT, M1535_IRQ_AUDIO},	/* Audio controller */
+	{1, ROCKHOPPER_PCI1_SLOT, M1535_IRQ_INTD},	/* PCI slot #1 */
+	{1, ROCKHOPPER_PCI2_SLOT, M1535_IRQ_INTC},	/* PCI slot #2 */
+	{1, ROCKHOPPER_M5237_SLOT, M1535_IRQ_USB},	/* USB host controller */
+	{1, ROCKHOPPER_M5229_SLOT, IDE_PRIMARY_IRQ},	/* IDE controller */
+	{2, ROCKHOPPER_PCNET_SLOT, M1535_IRQ_INTD},	/* AMD Am79c973 on-board
+							   ethernet */
+	{2, ROCKHOPPER_PCI3_SLOT, M1535_IRQ_INTB},	/* PCI slot #3 */
+	{2, ROCKHOPPER_PCI4_SLOT, M1535_IRQ_INTC}	/* PCI slot #4 */
+};
+
+static int pci_intlines[] =
+    { M1535_IRQ_INTA, M1535_IRQ_INTB, M1535_IRQ_INTC, M1535_IRQ_INTD };
+
+/* Determine the Rockhopper IRQ line number for the PCI device */
+int rockhopper_get_irq(struct pci_dev *dev, u8 pin, u8 slot)
+{
+	struct pci_bus *bus;
+	int i;
+
+	bus = dev->bus;
+	if (bus == NULL)
+		return -1;
+
+	for (i = 0; i < sizeof (int_map) / sizeof (int_map[0]); i++) {
+		if (int_map[i].bus == bus->number && int_map[i].slot == slot) {
+			int line;
+			for (line = 0; line < 4; line++)
+				if (pci_intlines[line] == int_map[i].irq)
+					break;
+			if (line < 4)
+				return pci_intlines[(line + (pin - 1)) % 4];
+			else
+				return int_map[i].irq;
+		}
+	}
+	return -1;
+}
+
+#ifdef CONFIG_ROCKHOPPER
+void i8259_init(void)
+{
+	outb(0x11, 0x20);		/* Master ICW1 */
+	outb(I8259_IRQ_BASE, 0x21);	/* Master ICW2 */
+	outb(0x04, 0x21);		/* Master ICW3 */
+	outb(0x01, 0x21);		/* Master ICW4 */
+	outb(0xff, 0x21);		/* Master IMW */
+
+	outb(0x11, 0xa0);		/* Slave ICW1 */
+	outb(I8259_IRQ_BASE + 8, 0xa1);	/* Slave ICW2 */
+	outb(0x02, 0xa1);		/* Slave ICW3 */
+	outb(0x01, 0xa1);		/* Slave ICW4 */
+	outb(0xff, 0xa1);		/* Slave IMW */
+
+	outb(0x00, 0x4d0);
+	outb(0x02, 0x4d1);	/* USB IRQ9 is level */
+}
+#endif
+
+int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	extern int pci_probe_only;
+	pci_probe_only = 1;
+
+#ifdef CONFIG_ROCKHOPPER
+	if( dev->bus->number == 1 && vr4133_rockhopper )  {
+		if(slot == ROCKHOPPER_PCI1_SLOT || slot == ROCKHOPPER_PCI2_SLOT)
+			dev->irq = CMBVR41XX_INTA_IRQ;
+		else
+			dev->irq = rockhopper_get_irq(dev, pin, slot);
+	} else
+		dev->irq = CMBVR41XX_INTA_IRQ;
+#else
+	dev->irq = CMBVR41XX_INTA_IRQ;
+#endif
+
+	return dev->irq;
+}
+
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, ali_m1535plus_init);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M5229, ali_m5229_init);
+
+
diff -Nru a/arch/mips/pci/ops-msc.c b/arch/mips/pci/ops-msc.c
--- a/arch/mips/pci/ops-msc.c	2005-03-01 23:39:17 -08:00
+++ b/arch/mips/pci/ops-msc.c	2005-03-01 23:39:17 -08:00
@@ -1,6 +1,9 @@
 /*
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 1999, 2000 MIPS Technologies, Inc.  All rights reserved.
+ * Copyright (C) 1999, 2000, 2004, 2005  MIPS Technologies, Inc.
+ *    All rights reserved.
+ *    Authors: Carsten Langgaard <carstenl@mips.com>
+ *             Maciej W. Rozycki <macro@mips.com>
+ * Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org)
  *
  *  This program is free software; you can distribute it and/or modify it
  *  under the terms of the GNU General Public License (Version 2) as
@@ -18,6 +21,7 @@
  * MIPS boards specific PCI support.
  *
  */
+#include <linux/config.h>
 #include <linux/types.h>
 #include <linux/pci.h>
 #include <linux/kernel.h>
diff -Nru a/arch/mips/pci/ops-sni.c b/arch/mips/pci/ops-sni.c
--- a/arch/mips/pci/ops-sni.c	2005-03-01 23:38:58 -08:00
+++ b/arch/mips/pci/ops-sni.c	2005-03-01 23:38:58 -08:00
@@ -21,9 +21,9 @@
  *
  * ASIC PCI only supports type 1 config cycles.
  */
-static int set_config_address(unsigned char busno, unsigned int devfn, int reg)
+static int set_config_address(unsigned int busno, unsigned int devfn, int reg)
 {
-	if ((busno > 255) || (devfn > 255) || (reg > 255))
+	if ((devfn > 255) || (reg > 255))
 		return PCIBIOS_BAD_REGISTER_NUMBER;
 
 	if (busno == 0 && devfn >= PCI_DEVFN(8, 0))
diff -Nru a/arch/mips/pci/ops-titan.c b/arch/mips/pci/ops-titan.c
--- a/arch/mips/pci/ops-titan.c	2005-03-01 23:38:54 -08:00
+++ b/arch/mips/pci/ops-titan.c	2005-03-01 23:38:54 -08:00
@@ -22,91 +22,69 @@
  *  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/types.h>
 #include <linux/pci.h>
 #include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/version.h>
 
-#include <asm/pci.h>
-#include <asm/io.h>
 #include <asm/titan_dep.h>
 
-/*
- * Titan PCI Config Read Byte
- */
 static int titan_read_config(struct pci_bus *bus, unsigned int devfn, int reg,
 	int size, u32 * val)
 {
+	uint32_t address, tmp;
 	int dev, busno, func;
-	uint32_t address_reg, data_reg;
-	uint32_t address;
 
 	busno = bus->number;
 	dev = PCI_SLOT(devfn);
 	func = PCI_FUNC(devfn);
 
-	address_reg = TITAN_PCI_0_CONFIG_ADDRESS;
-	data_reg = TITAN_PCI_0_CONFIG_DATA;
-
 	address = (busno << 16) | (dev << 11) | (func << 8) |
 	          (reg & 0xfc) | 0x80000000;
 
+
 	/* start the configuration cycle */
-	TITAN_WRITE(address_reg, address);
+	TITAN_WRITE(TITAN_PCI_0_CONFIG_ADDRESS, address);
+	tmp = TITAN_READ(TITAN_PCI_0_CONFIG_DATA) >> ((reg & 3) << 3);
 
 	switch (size) {
 	case 1:
-		*val = TITAN_READ_8(data_reg + (~reg & 0x3));
-		break;
-
+		tmp &= 0xff;
 	case 2:
-		*val = TITAN_READ_16(data_reg + (~reg & 0x2));
-		break;
-
-	case 4:
-		*val = TITAN_READ(data_reg);
-		break;
+		tmp &= 0xffff;
 	}
+	*val = tmp;
 
 	return PCIBIOS_SUCCESSFUL;
 }
 
-/*
- * Titan PCI Config Byte Write
- */
 static int titan_write_config(struct pci_bus *bus, unsigned int devfn, int reg,
 	int size, u32 val)
 {
-	uint32_t address_reg, data_reg, address;
+	uint32_t address;
 	int dev, busno, func;
 
 	busno = bus->number;
 	dev = PCI_SLOT(devfn);
 	func = PCI_FUNC(devfn);
 
-	address_reg = TITAN_PCI_0_CONFIG_ADDRESS;
-	data_reg = TITAN_PCI_0_CONFIG_DATA;
-
 	address = (busno << 16) | (dev << 11) | (func << 8) |
 		(reg & 0xfc) | 0x80000000;
 
 	/* start the configuration cycle */
-	TITAN_WRITE(address_reg, address);
+	TITAN_WRITE(TITAN_PCI_0_CONFIG_ADDRESS, address);
 
 	/* write the data */
 	switch (size) {
 	case 1:
-		TITAN_WRITE_8(data_reg + (~reg & 0x3), val);
+		TITAN_WRITE_8(TITAN_PCI_0_CONFIG_DATA + (~reg & 0x3), val);
 		break;
 
 	case 2:
-		TITAN_WRITE_16(data_reg + (~reg & 0x2), val);
+		TITAN_WRITE_16(TITAN_PCI_0_CONFIG_DATA + (~reg & 0x2), val);
 		break;
 
 	case 4:
-		TITAN_WRITE(data_reg, val);
+		TITAN_WRITE(TITAN_PCI_0_CONFIG_DATA, val);
 		break;
 	}
 
diff -Nru a/arch/mips/pci/ops-tx4927.c b/arch/mips/pci/ops-tx4927.c
--- a/arch/mips/pci/ops-tx4927.c	2005-03-01 23:38:55 -08:00
+++ b/arch/mips/pci/ops-tx4927.c	2005-03-01 23:38:55 -08:00
@@ -42,8 +42,8 @@
 #include <linux/init.h>
 
 #include <asm/addrspace.h>
+#include <asm/byteorder.h>
 #include <asm/tx4927/tx4927_pci.h>
-#include <asm/debug.h>
 
 /* initialize in setup */
 struct resource pci_io_resource = {
@@ -107,16 +107,6 @@
         dev = PCI_SLOT(devfn);
         func = PCI_FUNC(devfn);
 
-	if (size == 2) {
-		if (where & 1)
-	                return PCIBIOS_BAD_REGISTER_NUMBER;
-	}
-
-	if (size == 4) {
-		if (where & 3)
-			return PCIBIOS_BAD_REGISTER_NUMBER;
-	}
-
 	/* check if the bus is top-level */
 	if (bus->parent != NULL) {
 		busno = bus->number;
@@ -130,11 +120,21 @@
 	switch (size) {
 	case 1:
 		*val = *(volatile u8 *) ((ulong) & tx4927_pcicptr->
-                              g2pcfgdata | (where & 3));
+                              g2pcfgdata |
+#ifdef __LITTLE_ENDIAN
+						(where & 3));
+#else
+						((where & 0x3) ^ 0x3));
+#endif
 		break;
 	case 2:
 		*val = *(volatile u16 *) ((ulong) & tx4927_pcicptr->
-                               g2pcfgdata | (where & 3));
+                               g2pcfgdata |
+#ifdef __LITTLE_ENDIAN
+						(where & 3));
+#else
+						((where & 0x3) ^ 0x2));
+#endif
 		break;
 	case 4:
 		*val = tx4927_pcicptr->g2pcfgdata;
@@ -156,16 +156,6 @@
         dev = PCI_SLOT(devfn);
         func = PCI_FUNC(devfn);
 
-	if (size == 1) {
-		if (where & 1)
-			return PCIBIOS_BAD_REGISTER_NUMBER;
-	}
-
-	if (size == 4) {
-		if (where & 3)
-			return PCIBIOS_BAD_REGISTER_NUMBER;
-	}
-
 	/* check if the bus is top-level */
 	if (bus->parent != NULL) {
 		busno = bus->number;
@@ -179,12 +169,22 @@
 	switch (size) {
 	case 1:
 		 *(volatile u8 *) ((ulong) & tx4927_pcicptr->
-                          g2pcfgdata | (where & 3)) = val;
+                          g2pcfgdata |
+#ifdef __LITTLE_ENDIAN
+					(where & 3)) = val;
+#else
+					((where & 0x3) ^ 0x3)) = val;
+#endif
 		break;
 
 	case 2:
 		*(volatile u16 *) ((ulong) & tx4927_pcicptr->
-                           g2pcfgdata | (where & 3)) = val;
+                           g2pcfgdata |
+#ifdef __LITTLE_ENDIAN
+					(where & 3)) = val;
+#else
+					((where & 0x3) ^ 0x2)) = val;
+#endif
 		break;
 	case 4:
 		tx4927_pcicptr->g2pcfgdata = val;
diff -Nru a/arch/mips/pci/pci-sb1250.c b/arch/mips/pci/pci-sb1250.c
--- a/arch/mips/pci/pci-sb1250.c	2005-03-01 23:38:53 -08:00
+++ b/arch/mips/pci/pci-sb1250.c	2005-03-01 23:38:53 -08:00
@@ -182,8 +182,8 @@
 }
 
 struct pci_ops sb1250_pci_ops = {
-	.read = sb1250_pcibios_read,
-	.write = sb1250_pcibios_write
+	.read	= sb1250_pcibios_read,
+	.write	= sb1250_pcibios_write,
 };
 
 static struct resource sb1250_mem_resource = {
@@ -192,7 +192,7 @@
 	.end	= 0x5fffffffUL,
 	.flags	= IORESOURCE_MEM,
 };
-                                                                                
+
 static struct resource sb1250_io_resource = {
 	.name	= "SB1250 PCI I/O",
 	.start	= 0x00000000UL,
@@ -215,9 +215,13 @@
 	/* CFE will assign PCI resources */
 	pci_probe_only = 1;
 
+	/* Avoid ISA compat ranges.  */
+	PCIBIOS_MIN_IO = 0x00008000UL;
+	PCIBIOS_MIN_MEM = 0x01000000UL;
+
 	/* Set I/O resource limits.  */
-	ioport_resource.end = 0x01ffffff;	/* 32MB accessible by sb1250 */
-	iomem_resource.end = 0xffffffff;	/* no HT support yet */
+	ioport_resource.end = 0x01ffffffUL;	/* 32MB accessible by sb1250 */
+	iomem_resource.end = 0xffffffffUL;	/* no HT support yet */
 
 	cfg_space =
 	    ioremap(A_PHYS_LDTPCI_CFG_MATCH_BITS, 16 * 1024 * 1024);
diff -Nru a/arch/mips/pci/pci-vr41xx.c b/arch/mips/pci/pci-vr41xx.c
--- a/arch/mips/pci/pci-vr41xx.c	2005-03-01 23:39:18 -08:00
+++ b/arch/mips/pci/pci-vr41xx.c	2005-03-01 23:39:18 -08:00
@@ -270,7 +270,7 @@
 	/* Clear bus error */
 	readl(BUSERRADREG);
 
-	writel(CONFIG_DONE, PCIENREG);
+	writel(BLOODY_CONFIG_DONE, PCIENREG);
 
 	if (setup->mem_resource != NULL)
 		vr41xx_pci_controller.mem_resource = setup->mem_resource;
diff -Nru a/arch/mips/pci/pci-vr41xx.h b/arch/mips/pci/pci-vr41xx.h
--- a/arch/mips/pci/pci-vr41xx.h	2005-03-01 23:39:07 -08:00
+++ b/arch/mips/pci/pci-vr41xx.h	2005-03-01 23:39:07 -08:00
@@ -73,7 +73,7 @@
 #define PCIRECONTREG		KSEG1ADDR(0x0f000c30)
  #define RTRYCNT(reg)		((reg) & 0x000000ffU)
 #define PCIENREG		KSEG1ADDR(0x0f000c34)
- #define CONFIG_DONE		0x4U
+ #define BLOODY_CONFIG_DONE	0x4U
 #define PCICLKSELREG		KSEG1ADDR(0x0f000c38)
  #define EQUAL_VTCLOCK		0x2U
  #define HALF_VTCLOCK		0x0U
diff -Nru a/arch/mips/pci/pci-yosemite.c b/arch/mips/pci/pci-yosemite.c
--- a/arch/mips/pci/pci-yosemite.c	2005-03-01 23:39:16 -08:00
+++ b/arch/mips/pci/pci-yosemite.c	2005-03-01 23:39:16 -08:00
@@ -9,7 +9,7 @@
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/pci.h>
-#include <asm/gt64240.h>
+#include <asm/titan_dep.h>
 
 extern struct pci_ops titan_pci_ops;
 
@@ -23,6 +23,7 @@
  * anyway.  So we just claim 64kB here.
  */
 #define TITAN_IO_SIZE	0x0000ffffUL
+#define TITAN_IO_BASE	0xe8000000UL
 
 static struct resource py_io_resource = {
 	"Titan IO MEM", 0x00001000UL, TITAN_IO_SIZE - 1, IORESOURCE_IO,
@@ -42,11 +43,12 @@
 {
 	unsigned long io_v_base;
 
-	io_v_base = (unsigned long) ioremap(0xe0000000UL,TITAN_IO_SIZE);
+	io_v_base = (unsigned long) ioremap(TITAN_IO_BASE, TITAN_IO_SIZE);
 	if (!io_v_base)
 		panic(ioremap_failed);
 
 	set_io_port_base(io_v_base);
+	TITAN_WRITE(RM9000x2_OCD_LKM7, TITAN_READ(RM9000x2_OCD_LKM7) | 1);
 
 	ioport_resource.end = TITAN_IO_SIZE - 1;
 
diff -Nru a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c
--- a/arch/mips/pci/pci.c	2005-03-01 23:39:06 -08:00
+++ b/arch/mips/pci/pci.c	2005-03-01 23:39:06 -08:00
@@ -59,7 +59,7 @@
 
 	if (res->flags & IORESOURCE_IO) {
 		/* Make sure we start at our min on all hoses */
-		if (start - hose->io_resource->start < PCIBIOS_MIN_IO)
+		if (start < PCIBIOS_MIN_IO + hose->io_resource->start)
 			start = PCIBIOS_MIN_IO + hose->io_resource->start;
 
 		/*
@@ -69,7 +69,7 @@
 			start = (start + 0x3ff) & ~0x3ff;
 	} else if (res->flags & IORESOURCE_MEM) {
 		/* Make sure we start at our min on all hoses */
-		if (start - hose->mem_resource->start < PCIBIOS_MIN_MEM)
+		if (start < PCIBIOS_MIN_MEM + hose->mem_resource->start)
 			start = PCIBIOS_MIN_MEM + hose->mem_resource->start;
 	}
 
@@ -294,6 +294,8 @@
 
 #ifdef CONFIG_HOTPLUG
 EXPORT_SYMBOL(pcibios_resource_to_bus);
+EXPORT_SYMBOL(PCIBIOS_MIN_IO);
+EXPORT_SYMBOL(PCIBIOS_MIN_MEM);
 #endif
 
 char *pcibios_setup(char *str)
diff -Nru a/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.h b/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.h
--- a/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.h	2005-03-01 23:39:17 -08:00
+++ b/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.h	2005-03-01 23:39:17 -08:00
@@ -3,6 +3,7 @@
  *
  *  Copyright (C) 2003 PMC-Sierra Inc.
  *  Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ *  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
@@ -29,7 +30,6 @@
  * Header file for atmel_read_eeprom.c 
  */
 
-#include <linux/config.h>
 #include <linux/types.h>
 #include <linux/pci.h>
 #include <linux/kernel.h>
diff -Nru a/arch/mips/pmc-sierra/yosemite/dbg_io.c b/arch/mips/pmc-sierra/yosemite/dbg_io.c
--- a/arch/mips/pmc-sierra/yosemite/dbg_io.c	2005-03-01 23:39:09 -08:00
+++ b/arch/mips/pmc-sierra/yosemite/dbg_io.c	2005-03-01 23:39:09 -08:00
@@ -31,9 +31,6 @@
  * the interrupt came from channel A or B.
  */
 
-#include <linux/config.h>
-
-#ifdef CONFIG_KGDB
 #include <asm/serial.h>
 
 /*
@@ -181,4 +178,3 @@
 
 	return 1;
 }
-#endif
diff -Nru a/arch/mips/pmc-sierra/yosemite/irq-handler.S b/arch/mips/pmc-sierra/yosemite/irq-handler.S
--- a/arch/mips/pmc-sierra/yosemite/irq-handler.S	2005-03-01 23:39:09 -08:00
+++ b/arch/mips/pmc-sierra/yosemite/irq-handler.S	2005-03-01 23:39:09 -08:00
@@ -34,37 +34,24 @@
 
 		and	t0, t2
 
+		andi	t2, t0, STATUSF_IP7	/* INTB5 hardware line */
+		bnez	t2, ll_timer_irq	/* Timer */
 		andi	t1, t0, STATUSF_IP2	/* INTB0 hardware line */
 		bnez	t1, ll_pcia_irq		/* 64-bit PCI */
-		andi	t1, t0, STATUSF_IP3	/* INTB1 hardware line */
-		bnez	t1, ll_pcib_irq		/* second 64-bit PCI slot */
+		andi	t2, t0, STATUSF_IP3	/* INTB1 hardware line */
+		bnez	t2, ll_pcib_irq		/* second 64-bit PCI slot */
 		andi	t1, t0, STATUSF_IP4	/* INTB2 hardware line */
 		bnez	t1, ll_duart_irq	/* UART	*/
-		andi    t1, t0, STATUSF_IP5	/* SMP inter-core interrupts */
-		bnez    t1, ll_smp_irq
+		andi    t2, t0, STATUSF_IP5	/* SMP inter-core interrupts */
+		bnez    t2, ll_smp_irq
 		andi	t1, t0, STATUSF_IP6
 		bnez	t1, ll_ht_irq		/* Hypertransport */
-		andi	t1, t0, STATUSF_IP7	/* INTB5 hardware line */
-		bnez	t1, ll_timer_irq	/* Timer */
 
-		nop
-		nop
-
-		/* Extended interrupts */
-                mfc0    t0, CP0_CAUSE
-                cfc0    t1, CP0_S1_INTCONTROL
-
-                sll     t2, t1, 8
-
-                and     t0, t2
-                srl     t0, t0, 16
-
-		.set	reorder
-
-		j	spurious_interrupt
-		nop
+		move	a0, sp
+		j	do_extended_irq
 		END(titan_handle_int)
 
+		.set	reorder
 		.align	5
 
 ll_pcia_irq:
diff -Nru a/arch/mips/pmc-sierra/yosemite/irq.c b/arch/mips/pmc-sierra/yosemite/irq.c
--- a/arch/mips/pmc-sierra/yosemite/irq.c	2005-03-01 23:39:09 -08:00
+++ b/arch/mips/pmc-sierra/yosemite/irq.c	2005-03-01 23:39:09 -08:00
@@ -24,7 +24,7 @@
  *
  * Second level Interrupt handlers for the PMC-Sierra Titan/Yosemite board
  */
-
+#include <linux/config.h>
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/kernel_stat.h>
@@ -58,7 +58,7 @@
 extern asmlinkage void titan_handle_int(void);
 extern void jaguar_mailbox_irq(struct pt_regs *);
 
-/* 
+/*
  * Handle hypertransport & SMP interrupts. The interrupt lines are scarce.
  * For interprocessor interrupts, the best thing to do is to use the INTMSG
  * register. We use the same external interrupt line, i.e. INTB3 and monitor
@@ -66,15 +66,15 @@
  */
 asmlinkage void ll_ht_smp_irq_handler(int irq, struct pt_regs *regs)
 {
-        u32 status = OCD_READ(RM9000x2_OCD_INTP0STATUS4);
+	u32 status = OCD_READ(RM9000x2_OCD_INTP0STATUS4);
 
 	/* Ack all the bits that correspond to the interrupt sources */
 	if (status != 0)
-	        OCD_WRITE(RM9000x2_OCD_INTP0STATUS4, IRQ_ACK_BITS);
+		OCD_WRITE(RM9000x2_OCD_INTP0STATUS4, IRQ_ACK_BITS);
 
 	status = OCD_READ(RM9000x2_OCD_INTP1STATUS4);
 	if (status != 0)
-                OCD_WRITE(RM9000x2_OCD_INTP1STATUS4, IRQ_ACK_BITS);
+		OCD_WRITE(RM9000x2_OCD_INTP1STATUS4, IRQ_ACK_BITS);
 
 #ifdef CONFIG_HT_LEVEL_TRIGGER
 	/*
@@ -110,6 +110,21 @@
 	do_IRQ(irq, regs);
 }
 
+asmlinkage void do_extended_irq(struct pt_regs *regs)
+{
+	unsigned int intcontrol = read_c0_intcontrol();
+	unsigned int cause = read_c0_cause();
+	unsigned int status = read_c0_status();
+	unsigned int pending_sr, pending_ic;
+
+	pending_sr = status & cause & 0xff00;
+	pending_ic = (cause >> 8) & intcontrol & 0xff00;
+
+	if (pending_ic & (1 << 13))
+		do_IRQ(13, regs);
+
+}
+
 #ifdef CONFIG_KGDB
 extern void init_second_port(void);
 #endif
@@ -124,6 +139,7 @@
 	set_except_vector(0, titan_handle_int);
 	mips_cpu_irq_init(0);
 	rm7k_cpu_irq_init(8);
+	rm9k_cpu_irq_init(12);
 
 #ifdef CONFIG_KGDB
 	/* At this point, initialize the second serial port */
diff -Nru a/arch/mips/pmc-sierra/yosemite/prom.c b/arch/mips/pmc-sierra/yosemite/prom.c
--- a/arch/mips/pmc-sierra/yosemite/prom.c	2005-03-01 23:39:19 -08:00
+++ b/arch/mips/pmc-sierra/yosemite/prom.c	2005-03-01 23:39:19 -08:00
@@ -43,7 +43,7 @@
 
 static void prom_cpu0_exit(void *arg)
 {
-	void *nvram = (void *) YOSEMITE_NVRAM_BASE_ADDR;
+	void *nvram = (void *) YOSEMITE_RTC_BASE;
 
 	/* Ask the NVRAM/RTC/watchdog chip to assert reset in 1/16 second */
 	writeb(0x84, nvram + 0xff7);
@@ -94,8 +94,6 @@
 	_machine_halt = prom_halt;
 	_machine_power_off = prom_halt;
 
-#ifdef CONFIG_MIPS32
-
 	debug_vectors = cv;
 	arcs_cmdline[0] = '\0';
 
@@ -109,6 +107,11 @@
 		strcat(arcs_cmdline, " ");
 	}
 
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+	if ((strstr(arcs_cmdline, "console=ttyS")) == NULL)
+		strcat(arcs_cmdline, "console=ttyS0,115200");
+#endif
+
 	while (*env) {
 		if (strncmp("ocd_base", *env, strlen("ocd_base")) == 0)
 			yosemite_base =
@@ -122,7 +125,6 @@
 
 		env++;
 	}
-#endif /* CONFIG_MIPS32 */
 
 	mips_machgroup = MACH_GROUP_TITAN;
 	mips_machtype = MACH_TITAN_YOSEMITE;
diff -Nru a/arch/mips/pmc-sierra/yosemite/py-console.c b/arch/mips/pmc-sierra/yosemite/py-console.c
--- a/arch/mips/pmc-sierra/yosemite/py-console.c	2005-03-01 23:38:57 -08:00
+++ b/arch/mips/pmc-sierra/yosemite/py-console.c	2005-03-01 23:38:57 -08:00
@@ -48,9 +48,12 @@
 #define iu_iir u3.iir
 #define iu_fcr u3.fcr
 
+#define ssnop()		__asm__ __volatile__("sll	$0, $0, 1\n");
+#define ssnop_4()	do { ssnop(); ssnop(); ssnop(); ssnop(); } while (0)
+
 #define IO_BASE_64	0x9000000000000000ULL
 
-static unsigned char readb_outer_space(unsigned long phys)
+static unsigned char readb_outer_space(unsigned long long phys)
 {
 	unsigned long long vaddr = IO_BASE_64 | phys;
 	unsigned char res;
@@ -58,29 +61,23 @@
 
 	sr = read_c0_status();
 	write_c0_status((sr | ST0_KX) & ~ ST0_IE);
-	__asm__("sll	$0, $0, 2\n");
-	__asm__("sll	$0, $0, 2\n");
-	__asm__("sll	$0, $0, 2\n");
-	__asm__("sll	$0, $0, 2\n");
+	ssnop_4();
 
 	__asm__ __volatile__ (
 	"	.set	mips3		\n"
-	"	ld	%0, (%0)	\n"
+	"	ld	%0, %1		\n"
 	"	lbu	%0, (%0)	\n"
 	"	.set	mips0		\n"
 	: "=r" (res)
-	: "0" (&vaddr));
+	: "m" (vaddr));
 
 	write_c0_status(sr);
-	__asm__("sll	$0, $0, 2\n");
-	__asm__("sll	$0, $0, 2\n");
-	__asm__("sll	$0, $0, 2\n");
-	__asm__("sll	$0, $0, 2\n");
+	ssnop_4();
 
 	return res;
 }
 
-static void writeb_outer_space(unsigned long phys, unsigned char c)
+static void writeb_outer_space(unsigned long long phys, unsigned char c)
 {
 	unsigned long long vaddr = IO_BASE_64 | phys;
 	unsigned long tmp;
@@ -88,30 +85,24 @@
 
 	sr = read_c0_status();
 	write_c0_status((sr | ST0_KX) & ~ ST0_IE);
-	__asm__("sll	$0, $0, 2\n");
-	__asm__("sll	$0, $0, 2\n");
-	__asm__("sll	$0, $0, 2\n");
-	__asm__("sll	$0, $0, 2\n");
+	ssnop_4();
 
 	__asm__ __volatile__ (
 	"	.set	mips3		\n"
-	"	ld	%0, (%1)	\n"
+	"	ld	%0, %1		\n"
 	"	sb	%2, (%0)	\n"
 	"	.set	mips0		\n"
-	: "=r" (tmp)
-	: "r" (&vaddr), "r" (c));
+	: "=&r" (tmp)
+	: "m" (vaddr), "r" (c));
 
 	write_c0_status(sr);
-	__asm__("sll	$0, $0, 2\n");
-	__asm__("sll	$0, $0, 2\n");
-	__asm__("sll	$0, $0, 2\n");
-	__asm__("sll	$0, $0, 2\n");
+	ssnop_4();
 }
 
 void prom_putchar(char c)
 {
-	unsigned long lsr = 0xfd000008UL + offsetof(struct yo_uartregs, iu_lsr);
-	unsigned long thr = 0xfd000008UL + offsetof(struct yo_uartregs, iu_thr);
+	unsigned long lsr = 0xfd000008ULL + offsetof(struct yo_uartregs, iu_lsr);
+	unsigned long thr = 0xfd000008ULL + offsetof(struct yo_uartregs, iu_thr);
 
 	while ((readb_outer_space(lsr) & 0x20) == 0);
 	writeb_outer_space(thr, c);
diff -Nru a/arch/mips/pmc-sierra/yosemite/setup.c b/arch/mips/pmc-sierra/yosemite/setup.c
--- a/arch/mips/pmc-sierra/yosemite/setup.c	2005-03-01 23:38:43 -08:00
+++ b/arch/mips/pmc-sierra/yosemite/setup.c	2005-03-01 23:38:43 -08:00
@@ -35,6 +35,10 @@
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <linux/timex.h>
+#include <linux/termios.h>
+#include <linux/tty.h>
+#include <linux/serial.h>
+#include <linux/serial_core.h>
 
 #include <asm/time.h>
 #include <asm/bootinfo.h>
@@ -45,84 +49,80 @@
 #include <asm/ptrace.h>
 #include <asm/reboot.h>
 #include <asm/serial.h>
-#include <linux/termios.h>
-#include <linux/tty.h>
-#include <linux/serial.h>
-#include <linux/serial_core.h>
 #include <asm/titan_dep.h>
+#include <asm/m48t37.h>
 
 #include "setup.h"
 
 unsigned char titan_ge_mac_addr_base[6] = {
-	0x00, 0x03, 0xcc, 0x1d, 0x22, 0x00
+	// 0x00, 0x03, 0xcc, 0x1d, 0x22, 0x00
+	0x00, 0xe0, 0x04, 0x00, 0x00, 0x21
 };
 
 unsigned long cpu_clock;
 unsigned long yosemite_base;
 
+static struct m48t37_rtc *m48t37_base;
+
 void __init bus_error_init(void)
 {
 	/* Do nothing */
 }
 
+
 unsigned long m48t37y_get_time(void)
 {
-	//unsigned char *rtc_base = (unsigned char *) YOSEMITE_RTC_BASE;
-	unsigned char *rtc_base = (unsigned char *) 0xfc000000UL;
 	unsigned int year, month, day, hour, min, sec;
-return;
 
 	/* Stop the update to the time */
-	rtc_base[0x7ff8] = 0x40;
+	m48t37_base->control = 0x40;
 
-	year = BCD2BIN(rtc_base[0x7fff]);
-	year += BCD2BIN(rtc_base[0x7fff1]) * 100;
+	year = BCD2BIN(m48t37_base->year);
+	year += BCD2BIN(m48t37_base->century) * 100;
 
-	month = BCD2BIN(rtc_base[0x7ffe]);
-	day = BCD2BIN(rtc_base[0x7ffd]);
-	hour = BCD2BIN(rtc_base[0x7ffb]);
-	min = BCD2BIN(rtc_base[0x7ffa]);
-	sec = BCD2BIN(rtc_base[0x7ff9]);
+	month = BCD2BIN(m48t37_base->month);
+	day = BCD2BIN(m48t37_base->date);
+	hour = BCD2BIN(m48t37_base->hour);
+	min = BCD2BIN(m48t37_base->min);
+	sec = BCD2BIN(m48t37_base->sec);
 
 	/* Start the update to the time again */
-	rtc_base[0x7ff8] = 0x00;
+	m48t37_base->control = 0x00;
 
 	return mktime(year, month, day, hour, min, sec);
 }
 
 int m48t37y_set_time(unsigned long sec)
 {
-	unsigned char *rtc_base = (unsigned char *) YOSEMITE_RTC_BASE;
 	struct rtc_time tm;
-return;
 
 	/* convert to a more useful format -- note months count from 0 */
 	to_tm(sec, &tm);
 	tm.tm_mon += 1;
 
 	/* enable writing */
-	rtc_base[0x7ff8] = 0x80;
+	m48t37_base->control = 0x80;
 
 	/* year */
-	rtc_base[0x7fff] = BIN2BCD(tm.tm_year % 100);
-	rtc_base[0x7ff1] = BIN2BCD(tm.tm_year / 100);
+	m48t37_base->year = BIN2BCD(tm.tm_year % 100);
+	m48t37_base->century = BIN2BCD(tm.tm_year / 100);
 
 	/* month */
-	rtc_base[0x7ffe] = BIN2BCD(tm.tm_mon);
+	m48t37_base->month = BIN2BCD(tm.tm_mon);
 
 	/* day */
-	rtc_base[0x7ffd] = BIN2BCD(tm.tm_mday);
+	m48t37_base->date = BIN2BCD(tm.tm_mday);
 
 	/* hour/min/sec */
-	rtc_base[0x7ffb] = BIN2BCD(tm.tm_hour);
-	rtc_base[0x7ffa] = BIN2BCD(tm.tm_min);
-	rtc_base[0x7ff9] = BIN2BCD(tm.tm_sec);
+	m48t37_base->hour = BIN2BCD(tm.tm_hour);
+	m48t37_base->min = BIN2BCD(tm.tm_min);
+	m48t37_base->sec = BIN2BCD(tm.tm_sec);
 
 	/* day of week -- not really used, but let's keep it up-to-date */
-	rtc_base[0x7ffc] = BIN2BCD(tm.tm_wday + 1);
+	m48t37_base->day = BIN2BCD(tm.tm_wday + 1);
 
 	/* disable writing */
-	rtc_base[0x7ff8] = 0x00;
+	m48t37_base->control = 0x00;
 
 	return 0;
 }
@@ -136,13 +136,9 @@
 {
 	board_timer_setup = yosemite_timer_setup;
 	mips_hpt_frequency = cpu_clock / 2;
-
-	rtc_get_time = m48t37y_get_time;
-	rtc_set_time = m48t37y_set_time;
+mips_hpt_frequency = 33000000 * 3 * 5;
 }
 
-unsigned long uart_base = 0xfd000000L;
-
 /* No other usable initialization hook than this ...  */
 extern void (*late_time_init)(void);
 
@@ -161,16 +157,18 @@
 
 static void __init py_map_ocd(void)
 {
-        struct uart_port up;
-
-	/*
-	 * Not specifically interrupt stuff but in case of SMP core_send_ipi
-	 * needs this first so I'm mapping it here ...
-	 */
 	ocd_base = (unsigned long) ioremap(OCD_BASE, OCD_SIZE);
 	if (!ocd_base)
 		panic("Mapping OCD failed - game over.  Your score is 0.");
 
+	/* Kludge for PMON bug ... */
+	OCD_WRITE(0x0710, 0x0ffff029);
+}
+
+static void __init py_uart_setup(void)
+{
+	struct uart_port up;
+
 	/*
 	 * Register to interrupt zero because we share the interrupt with
 	 * the serial driver which we don't properly support yet.
@@ -188,12 +186,36 @@
 		printk(KERN_ERR "Early serial init of port 0 failed\n");
 }
 
-static int __init pmc_yosemite_setup(void)
+static void __init py_rtc_setup(void)
+{
+	m48t37_base = ioremap(YOSEMITE_RTC_BASE, YOSEMITE_RTC_SIZE);
+	if (!m48t37_base)
+		printk(KERN_ERR "Mapping the RTC failed\n");
+
+	rtc_get_time = m48t37y_get_time;
+	rtc_set_time = m48t37y_set_time;
+
+	write_seqlock(&xtime_lock);
+	xtime.tv_sec = m48t37y_get_time();
+	xtime.tv_nsec = 0;
+
+	set_normalized_timespec(&wall_to_monotonic,
+	                        -xtime.tv_sec, -xtime.tv_nsec);
+	write_sequnlock(&xtime_lock);
+}
+
+/* Not only time init but that's what the hook it's called through is named */
+static void __init py_late_time_init(void)
 {
-	extern void pmon_smp_bootstrap(void);
+	py_map_ocd();
+	py_uart_setup();
+	py_rtc_setup();
+}
 
+static int __init pmc_yosemite_setup(void)
+{
 	board_time_init = yosemite_time_init;
-	late_time_init = py_map_ocd;
+	late_time_init = py_late_time_init;
 
 	/* Add memory regions */
 	add_memory_region(0x00000000, 0x10000000, BOOT_MEM_RAM);
diff -Nru a/arch/mips/pmc-sierra/yosemite/setup.h b/arch/mips/pmc-sierra/yosemite/setup.h
--- a/arch/mips/pmc-sierra/yosemite/setup.h	2005-03-01 23:38:56 -08:00
+++ b/arch/mips/pmc-sierra/yosemite/setup.h	2005-03-01 23:38:56 -08:00
@@ -1,6 +1,7 @@
 /*
- * Copyright 2003 PMC-Sierra
+ * Copyright 2003, 04 PMC-Sierra
  * Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ * Copyright 2004 Ralf Baechle <ralf@linux-mips.org>
  *
  * Board specific definititions for the PMC-Sierra Yosemite
  *
@@ -12,9 +13,9 @@
 #ifndef __SETUP_H__
 #define __SETUP_H__
 
-/* NVRAM Base */
-#define	YOSEMITE_NVRAM_BASE_ADDR	0xbb000678	/* XXX Need change */
-#define	YOSEMITE_RTC_BASE		0xbb000679	/* XXX Need change */
+/* M48T37 RTC + NVRAM */
+#define	YOSEMITE_RTC_BASE		0xfc800000
+#define	YOSEMITE_RTC_SIZE		0x00800000
 
 #define HYPERTRANSPORT_BAR0_ADDR        0x00000006
 #define HYPERTRANSPORT_SIZE0            0x0fffffff
diff -Nru a/arch/mips/pmc-sierra/yosemite/smp.c b/arch/mips/pmc-sierra/yosemite/smp.c
--- a/arch/mips/pmc-sierra/yosemite/smp.c	2005-03-01 23:38:55 -08:00
+++ b/arch/mips/pmc-sierra/yosemite/smp.c	2005-03-01 23:38:55 -08:00
@@ -4,6 +4,9 @@
 #include <asm/pmon.h>
 #include <asm/titan_dep.h>
 
+extern unsigned int (*mips_hpt_read)(void);
+extern void (*mips_hpt_init)(unsigned int);
+
 #define LAUNCHSTACK_SIZE 256
 
 static spinlock_t launch_lock __initdata;
@@ -37,8 +40,8 @@
 {
 	spin_lock(&launch_lock);
 
-	debug_vectors->cpustart(1, &prom_smp_bootstrap,
-	                        launchstack + LAUNCHSTACK_SIZE, 0);
+	pmon_cpustart(1, &prom_smp_bootstrap,
+	              launchstack + LAUNCHSTACK_SIZE, 0);
 }
 
 /*
@@ -47,23 +50,38 @@
  * We don't want to start the secondary CPU yet nor do we have a nice probing
  * feature in PMON so we just assume presence of the secondary core.
  */
-void prom_prepare_cpus(unsigned int max_cpus)
+static char maxcpus_string[] __initdata =
+	KERN_WARNING "max_cpus set to 0; using 1 instead\n";
+
+void __init prom_prepare_cpus(unsigned int max_cpus)
 {
+	int enabled = 0, i;
+
+	if (max_cpus == 0) {
+		printk(maxcpus_string);
+		max_cpus = 1;
+	}
+
 	cpus_clear(phys_cpu_present_map);
 
-	/*
-	 * The boot CPU
-	 */
-	cpu_set(0, phys_cpu_present_map);
-	__cpu_number_map[0]	= 0;
-	__cpu_logical_map[0]	= 0;
+	for (i = 0; i < 2; i++) {
+		if (i == max_cpus)
+			break;
+
+		/*
+		 * The boot CPU
+		 */
+		cpu_set(i, phys_cpu_present_map);
+		__cpu_number_map[i]	= i;
+		__cpu_logical_map[i]	= i;
+		enabled++;
+	}
 
 	/*
-	 * The secondary core
+	 * Be paranoid.  Enable the IPI only if we're really about to go SMP.
 	 */
-	cpu_set(1, phys_cpu_present_map);
-	__cpu_number_map[1]	= 1;
-	__cpu_logical_map[1]	= 1;
+	if (enabled > 1)
+		set_c0_status(STATUSF_IP5);
 }
 
 /*
@@ -95,6 +113,8 @@
  */
 void prom_init_secondary(void)
 {
+	mips_hpt_init(mips_hpt_read());
+
 	set_c0_status(ST0_CO | ST0_IE | ST0_IM);
 }
 
diff -Nru a/arch/mips/sgi-ip22/ip22-nvram.c b/arch/mips/sgi-ip22/ip22-nvram.c
--- a/arch/mips/sgi-ip22/ip22-nvram.c	2005-03-01 23:39:07 -08:00
+++ b/arch/mips/sgi-ip22/ip22-nvram.c	2005-03-01 23:39:07 -08:00
@@ -26,7 +26,7 @@
 #define EEPROM_DATO	0x08	/* Data out */
 #define EEPROM_DATI	0x10	/* Data in */
 
-/* We need to use this functions early... */
+/* We need to use these functions early... */
 #define delay()	({						\
 	int x;							\
 	for (x=0; x<100000; x++) __asm__ __volatile__(""); })
diff -Nru a/arch/mips/sgi-ip22/ip22-setup.c b/arch/mips/sgi-ip22/ip22-setup.c
--- a/arch/mips/sgi-ip22/ip22-setup.c	2005-03-01 23:38:52 -08:00
+++ b/arch/mips/sgi-ip22/ip22-setup.c	2005-03-01 23:38:52 -08:00
@@ -120,9 +120,8 @@
 	}
 #endif
 
-#ifdef CONFIG_VT
-#ifdef CONFIG_SGI_NEWPORT_CONSOLE
-	if (ctype && *ctype == 'g'){
+#if defined(CONFIG_VT) && defined(CONFIG_SGI_NEWPORT_CONSOLE)
+	{
 		ULONG *gfxinfo;
 		ULONG * (*__vec)(void) = (void *) (long)
 			*((_PULONG *)(long)((PROMBLOCK)->pvector + 0x20));
@@ -137,7 +136,6 @@
 			conswitchp = &newport_con;
 		}
 	}
-#endif
 #endif
 
 	return 0;
diff -Nru a/arch/mips/sgi-ip27/Makefile b/arch/mips/sgi-ip27/Makefile
--- a/arch/mips/sgi-ip27/Makefile	2005-03-01 23:39:16 -08:00
+++ b/arch/mips/sgi-ip27/Makefile	2005-03-01 23:39:16 -08:00
@@ -6,6 +6,7 @@
 	   ip27-klconfig.o ip27-klnuma.o ip27-memory.o ip27-nmi.o ip27-reset.o \
 	   ip27-timer.o ip27-hubio.o ip27-xtalk.o
 
+obj-$(CONFIG_KGDB)	+= ip27-dbgio.o
 obj-$(CONFIG_SMP)	+= ip27-smp.o
 
 EXTRA_AFLAGS := $(CFLAGS)
diff -Nru a/arch/mips/sgi-ip27/ip27-dbgio.c b/arch/mips/sgi-ip27/ip27-dbgio.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/mips/sgi-ip27/ip27-dbgio.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,60 @@
+/*
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU 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.
+ *
+ * Copyright 2004 Ralf Baechle <ralf@linux-mips.org>
+ */
+#include <asm/sn/addrs.h>
+#include <asm/sn/sn0/hub.h>
+#include <asm/sn/klconfig.h>
+#include <asm/sn/ioc3.h>
+#include <asm/sn/sn_private.h>
+
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+#include <linux/serial_reg.h>
+
+#define IOC3_CLK        (22000000 / 3)
+#define IOC3_FLAGS      (0)
+
+static inline struct ioc3_uartregs *console_uart(void)
+{
+	struct ioc3 *ioc3;
+
+	ioc3 = (struct ioc3 *)KL_CONFIG_CH_CONS_INFO(get_nasid())->memory_base;
+
+	return &ioc3->sregs.uarta;
+}
+
+unsigned char getDebugChar(void)
+{
+	struct ioc3_uartregs *uart = console_uart();
+
+	while ((uart->iu_lsr & UART_LSR_DR) == 0);
+	return uart->iu_rbr;
+}
+
+void putDebugChar(unsigned char c)
+{
+	struct ioc3_uartregs *uart = console_uart();
+
+	while ((uart->iu_lsr & UART_LSR_THRE) == 0);
+	uart->iu_thr = c;
+}
diff -Nru a/arch/mips/sgi-ip27/ip27-init.c b/arch/mips/sgi-ip27/ip27-init.c
--- a/arch/mips/sgi-ip27/ip27-init.c	2005-03-01 23:39:16 -08:00
+++ b/arch/mips/sgi-ip27/ip27-init.c	2005-03-01 23:39:16 -08:00
@@ -10,7 +10,6 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/sched.h>
-#include <linux/mmzone.h>	/* for numnodes */
 #include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/cpumask.h>
@@ -78,15 +77,14 @@
 	 * copy over the caliased exception handlers.
 	 */
 	if (get_compact_nodeid() == cnode) {
-		extern char except_vec0, except_vec1_r4k;
 		extern char except_vec2_generic, except_vec3_generic;
+		extern void build_tlb_refill_handler(void);
 
-		memcpy((void *)(KSEG0 + 0x100), &except_vec2_generic, 0x80);
-		memcpy((void *)(KSEG0 + 0x180), &except_vec3_generic, 0x80);
-		memcpy((void *)KSEG0, &except_vec0, 0x80);
-		memcpy((void *)KSEG0 + 0x080, &except_vec1_r4k, 0x80);
-		memcpy((void *)(KSEG0 + 0x100), (void *) KSEG0, 0x80);
-		memcpy((void *)(KSEG0 + 0x180), &except_vec3_generic, 0x100);
+		memcpy((void *)(CKSEG0 + 0x100), &except_vec2_generic, 0x80);
+		memcpy((void *)(CKSEG0 + 0x180), &except_vec3_generic, 0x80);
+		build_tlb_refill_handler();
+		memcpy((void *)(CKSEG0 + 0x100), (void *) CKSEG0, 0x80);
+		memcpy((void *)(CKSEG0 + 0x180), &except_vec3_generic, 0x100);
 		__flush_cache_all();
 	}
 #endif
diff -Nru a/arch/mips/sgi-ip27/ip27-irq-glue.S b/arch/mips/sgi-ip27/ip27-irq-glue.S
--- a/arch/mips/sgi-ip27/ip27-irq-glue.S	2005-03-01 23:39:18 -08:00
+++ b/arch/mips/sgi-ip27/ip27-irq-glue.S	2005-03-01 23:39:18 -08:00
@@ -21,7 +21,7 @@
 	mfc0	t0, CP0_STATUS
 	and	s0, t0
 	move	a0, sp
-	la	ra, ret_from_irq
+	PTR_LA	ra, ret_from_irq
 
 	/* First check for RT interrupt.  */
 	andi	t0, s0, CAUSEF_IP4
diff -Nru a/arch/mips/sgi-ip27/ip27-klnuma.c b/arch/mips/sgi-ip27/ip27-klnuma.c
--- a/arch/mips/sgi-ip27/ip27-klnuma.c	2005-03-01 23:38:55 -08:00
+++ b/arch/mips/sgi-ip27/ip27-klnuma.c	2005-03-01 23:38:55 -08:00
@@ -7,6 +7,7 @@
 #include <linux/init.h>
 #include <linux/mmzone.h>
 #include <linux/kernel.h>
+#include <linux/nodemask.h>
 #include <linux/string.h>
 
 #include <asm/page.h>
@@ -19,7 +20,6 @@
 #include <asm/sn/mapped_kernel.h>
 #include <asm/sn/sn_private.h>
 
-extern char _end;
 static cpumask_t ktext_repmask;
 
 /*
@@ -27,33 +27,25 @@
  * kernel.  For example, we should never put a copy on a headless node,
  * and we should respect the topology of the machine.
  */
-void __init setup_replication_mask(int maxnodes)
+void __init setup_replication_mask()
 {
-	static int 	numa_kernel_replication_ratio;
 	cnodeid_t	cnode;
 
 	/* Set only the master cnode's bit.  The master cnode is always 0. */
 	cpus_clear(ktext_repmask);
 	cpu_set(0, ktext_repmask);
 
-	numa_kernel_replication_ratio = 0;
 #ifdef CONFIG_REPLICATE_KTEXT
 #ifndef CONFIG_MAPPED_KERNEL
 #error Kernel replication works with mapped kernel support. No calias support.
 #endif
-	numa_kernel_replication_ratio = 1;
-#endif
-
-	for (cnode = 1; cnode < numnodes; cnode++) {
-		/* See if this node should get a copy of the kernel */
-		if (numa_kernel_replication_ratio &&
-		    !(cnode % numa_kernel_replication_ratio)) {
-
-			/* Advertise that we have a copy of the kernel */
-			cpu_set(cnode, ktext_repmask);
-		}
+	for_each_online_node(cnode) {
+		if (cnode == 0)
+			continue;
+		/* Advertise that we have a copy of the kernel */
+		cpu_set(cnode, ktext_repmask);
 	}
-
+#endif
 	/* Set up a GDA pointer to the replication mask. */
 	GDA->g_ktext_repmask = &ktext_repmask;
 }
@@ -92,7 +84,7 @@
 	memcpy((void *)dest_kern_start, (void *)source_start, kern_size);
 }
 
-void __init replicate_kernel_text(int maxnodes)
+void __init replicate_kernel_text()
 {
 	cnodeid_t cnode;
 	nasid_t client_nasid;
@@ -103,7 +95,9 @@
 	/* Record where the master node should get its kernel text */
 	set_ktext_source(master_nasid, master_nasid);
 
-	for (cnode = 1; cnode < maxnodes; cnode++) {
+	for_each_online_node(cnode) {
+		if (cnode == 0)
+			continue;
 		client_nasid = COMPACT_TO_NASID_NODEID(cnode);
 
 		/* Check if this node should get a copy of the kernel */
@@ -124,12 +118,12 @@
  */
 pfn_t node_getfirstfree(cnodeid_t cnode)
 {
-	unsigned long loadbase = CKSEG0;
+	unsigned long loadbase = REP_BASE;
 	nasid_t nasid = COMPACT_TO_NASID_NODEID(cnode);
 	unsigned long offset;
 
 #ifdef CONFIG_MAPPED_KERNEL
-	loadbase = CKSSEG + 16777216;
+	loadbase += 16777216;
 #endif
 	offset = PAGE_ALIGN((unsigned long)(&_end)) - loadbase;
 	if ((cnode == 0) || (cpu_isset(cnode, ktext_repmask)))
diff -Nru a/arch/mips/sgi-ip27/ip27-memory.c b/arch/mips/sgi-ip27/ip27-memory.c
--- a/arch/mips/sgi-ip27/ip27-memory.c	2005-03-01 23:38:54 -08:00
+++ b/arch/mips/sgi-ip27/ip27-memory.c	2005-03-01 23:38:54 -08:00
@@ -3,18 +3,20 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2000 by Ralf Baechle
+ * Copyright (C) 2000, 05 by Ralf Baechle (ralf@linux-mips.org)
  * Copyright (C) 2000 by Silicon Graphics, Inc.
  * Copyright (C) 2004 by Christoph Hellwig
  *
  * On SGI IP27 the ARC memory configuration data is completly bogus but
  * alternate easier to use mechanisms are available.
  */
+#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/mmzone.h>
 #include <linux/module.h>
+#include <linux/nodemask.h>
 #include <linux/swap.h>
 #include <linux/bootmem.h>
 #include <asm/page.h>
@@ -59,12 +61,12 @@
 
 static hubreg_t region_mask;
 
-static void gen_region_mask(hubreg_t *region_mask, int maxnodes)
+static void gen_region_mask(hubreg_t *region_mask)
 {
 	cnodeid_t cnode;
 
 	(*region_mask) = 0;
-	for (cnode = 0; cnode < maxnodes; cnode++) {
+	for_each_online_node(cnode) {
 		(*region_mask) |= 1ULL << get_region(cnode);
 	}
 }
@@ -120,7 +122,7 @@
 	int port;
 
 	/* Figure out which routers nodes in question are connected to */
-	for (cnode = 0; cnode < numnodes; cnode++) {
+	for_each_online_node(cnode) {
 		nasid = COMPACT_TO_NASID_NODEID(cnode);
 
 		if (nasid == -1) continue;
@@ -187,9 +189,9 @@
 		for (col = 0; col < MAX_COMPACT_NODES; col++)
 			__node_distances[row][col] = -1;
 
-	for (row = 0; row < numnodes; row++) {
+	for_each_online_node(row) {
 		nasid = COMPACT_TO_NASID_NODEID(row);
-		for (col = 0; col < numnodes; col++) {
+		for_each_online_node(col) {
 			nasid2 = COMPACT_TO_NASID_NODEID(col);
 			__node_distances[row][col] =
 				compute_node_distance(nasid, nasid2);
@@ -210,17 +212,17 @@
 	printk("************** Topology ********************\n");
 
 	printk("    ");
-	for (col = 0; col < numnodes; col++)
+	for_each_online_node(col)
 		printk("%02d ", col);
 	printk("\n");
-	for (row = 0; row < numnodes; row++) {
+	for_each_online_node(row) {
 		printk("%02d  ", row);
-		for (col = 0; col < numnodes; col++)
+		for_each_online_node(col)
 			printk("%2d ", node_distance(row, col));
 		printk("\n");
 	}
 
-	for (cnode = 0; cnode < numnodes; cnode++) {
+	for_each_online_node(cnode) {
 		nasid = COMPACT_TO_NASID_NODEID(cnode);
 
 		if (nasid == -1) continue;
@@ -363,14 +365,14 @@
 	init_topology_matrix();
 	dump_topology();
 
-	gen_region_mask(&region_mask, numnodes);
+	gen_region_mask(&region_mask);
 
-	setup_replication_mask(numnodes);
+	setup_replication_mask();
 
 	/*
 	 * Set all nodes' calias sizes to 8k
 	 */
-	for (i = 0; i < numnodes; i++) {
+	for_each_online_node(i) {
 		nasid_t nasid;
 
 		nasid = COMPACT_TO_NASID_NODEID(i);
@@ -407,7 +409,7 @@
 
 	num_physpages = 0;
 
-	for (node = 0; node < numnodes; node++) {
+	for_each_online_node(node) {
 		ignore = nodebytes = 0;
 		for (slot = 0; slot < MAX_MEM_SLOTS; slot++) {
 			slot_psize = slot_psize_compute(node, slot);
@@ -489,7 +491,7 @@
 	szmem();
 
 	for (node = 0; node < MAX_COMPACT_NODES; node++) {
-		if (node < numnodes) {
+		if (node_online(node)) {
 			node_mem_init(node);
 			continue;
 		}
@@ -513,7 +515,7 @@
 
 	pagetable_init();
 
-	for (node = 0; node < numnodes; node++) {
+	for_each_online_node(node) {
 		pfn_t start_pfn = slot_getbasepfn(node, 0);
 		pfn_t end_pfn = node_getmaxclick(node) + 1;
 
@@ -533,7 +535,7 @@
 
 	high_memory = (void *) __va(num_physpages << PAGE_SHIFT);
 
-	for (node = 0; node < numnodes; node++) {
+	for_each_online_node(node) {
 		unsigned slot, numslots;
 		struct page *end, *p;
 	
diff -Nru a/arch/mips/sgi-ip27/ip27-nmi.c b/arch/mips/sgi-ip27/ip27-nmi.c
--- a/arch/mips/sgi-ip27/ip27-nmi.c	2005-03-01 23:38:44 -08:00
+++ b/arch/mips/sgi-ip27/ip27-nmi.c	2005-03-01 23:38:44 -08:00
@@ -1,6 +1,7 @@
 #include <linux/kallsyms.h>
 #include <linux/kernel.h>
 #include <linux/mmzone.h>
+#include <linux/nodemask.h>
 #include <linux/spinlock.h>
 #include <linux/smp.h>
 #include <asm/atomic.h>
@@ -21,7 +22,7 @@
 
 typedef unsigned long machreg_t;
 
-spinlock_t nmi_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(nmi_lock);
 
 /*
  * Lets see what else we need to do here. Set up sp, gp?
@@ -183,7 +184,7 @@
 {
 	cnodeid_t	cnode;
 
-	for(cnode = 0 ; cnode < numnodes; cnode++)
+	for_each_online_node(cnode)
 		nmi_node_eframe_save(cnode);
 }
 
@@ -214,13 +215,13 @@
 	 * send NMIs to all cpus on a 256p system.
 	 */
 	for (i=0; i < 1500; i++) {
-		for (node=0; node < numnodes; node++)
+		for_each_online_node(node)
 			if (NODEPDA(node)->dump_count == 0)
 				break;
-		if (node == numnodes)
+		if (node == MAX_NUMNODES)
 			break;
 		if (i == 1000) {
-			for (node=0; node < numnodes; node++)
+			for_each_online_node(node)
 				if (NODEPDA(node)->dump_count == 0) {
 					cpu = node_to_first_cpu(node);
 					for (n=0; n < CNODE_NUM_CPUS(node); cpu++, n++) {
diff -Nru a/arch/mips/sgi-ip27/ip27-reset.c b/arch/mips/sgi-ip27/ip27-reset.c
--- a/arch/mips/sgi-ip27/ip27-reset.c	2005-03-01 23:38:58 -08:00
+++ b/arch/mips/sgi-ip27/ip27-reset.c	2005-03-01 23:38:58 -08:00
@@ -14,6 +14,7 @@
 #include <linux/timer.h>
 #include <linux/smp.h>
 #include <linux/mmzone.h>
+#include <linux/nodemask.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
@@ -43,7 +44,7 @@
 	smp_send_stop();
 #endif
 #if 0
-	for (i = 0; i < numnodes; i++)
+	for_each_online_node(i)
 		REMOTE_HUB_S(COMPACT_TO_NASID_NODEID(i), PROMOP_REG,
 							PROMOP_REBOOT);
 #else
@@ -59,7 +60,7 @@
 #ifdef CONFIG_SMP
 	smp_send_stop();
 #endif
-	for (i = 0; i < numnodes; i++)
+	for_each_online_node(i)
 		REMOTE_HUB_S(COMPACT_TO_NASID_NODEID(i), PROMOP_REG,
 							PROMOP_RESTART);
 	LOCAL_HUB_S(NI_PORT_RESET, NPR_PORTRESET | NPR_LOCALRESET);
diff -Nru a/arch/mips/sgi-ip27/ip27-smp.c b/arch/mips/sgi-ip27/ip27-smp.c
--- a/arch/mips/sgi-ip27/ip27-smp.c	2005-03-01 23:39:07 -08:00
+++ b/arch/mips/sgi-ip27/ip27-smp.c	2005-03-01 23:39:07 -08:00
@@ -8,6 +8,7 @@
  */
 #include <linux/init.h>
 #include <linux/sched.h>
+#include <linux/nodemask.h>
 #include <asm/page.h>
 #include <asm/processor.h>
 #include <asm/sn/arch.h>
@@ -108,18 +109,22 @@
 	for (i = 0; i < MAXCPUS; i++)
 		cpuid_to_compact_node[i] = INVALID_CNODEID;
 
-	numnodes = 0;
+	/*
+	 * MCD - this whole "compact node" stuff can probably be dropped,
+	 * as we can handle sparse numbering now
+	 */
+	nodes_clear(node_online_map);
 	for (i = 0; i < MAX_COMPACT_NODES; i++) {
 		nasid_t nasid = gdap->g_nasidtable[i];
 		if (nasid == INVALID_NASID)
 			break;
 		compact_to_nasid_node[i] = nasid;
 		nasid_to_compact_node[nasid] = i;
-		numnodes++;
+		node_set_online(num_online_nodes());
 		highest = do_cpumask(i, nasid, highest);
 	}
 
-	printk("Discovered %d cpus on %d nodes\n", highest + 1, numnodes);
+	printk("Discovered %d cpus on %d nodes\n", highest + 1, num_online_nodes());
 }
 
 static void intr_clear_bits(nasid_t nasid, volatile hubreg_t *pend,
@@ -151,10 +156,10 @@
 {
 	cnodeid_t	cnode;
 
-	for (cnode = 0; cnode < numnodes; cnode++)
+	for_each_online_node(cnode)
 		intr_clear_all(COMPACT_TO_NASID_NODEID(cnode));
 
-	replicate_kernel_text(numnodes);
+	replicate_kernel_text();
 
 	/*
 	 * Assumption to be fixed: we're always booted on logical / physical
diff -Nru a/arch/mips/sgi-ip27/ip27-timer.c b/arch/mips/sgi-ip27/ip27-timer.c
--- a/arch/mips/sgi-ip27/ip27-timer.c	2005-03-01 23:39:18 -08:00
+++ b/arch/mips/sgi-ip27/ip27-timer.c	2005-03-01 23:39:18 -08:00
@@ -1,9 +1,8 @@
 /*
- * Copytight (C) 1999, 2000 Ralf Baechle (ralf@gnu.org)
+ * Copytight (C) 1999, 2000, 05 Ralf Baechle (ralf@linux-mips.org)
  * Copytight (C) 1999, 2000 Silicon Graphics, Inc.
  */
 #include <linux/bcd.h>
-#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
diff -Nru a/arch/mips/sgi-ip32/Makefile b/arch/mips/sgi-ip32/Makefile
--- a/arch/mips/sgi-ip32/Makefile	2005-03-01 23:38:58 -08:00
+++ b/arch/mips/sgi-ip32/Makefile	2005-03-01 23:38:58 -08:00
@@ -4,6 +4,6 @@
 #
 
 obj-y	+= ip32-berr.o ip32-irq.o ip32-irq-glue.o ip32-setup.o ip32-reset.o \
-	   crime.o
+	   crime.o ip32-memory.o
 
 EXTRA_AFLAGS := $(CFLAGS)
diff -Nru a/arch/mips/sgi-ip32/crime.c b/arch/mips/sgi-ip32/crime.c
--- a/arch/mips/sgi-ip32/crime.c	2005-03-01 23:38:53 -08:00
+++ b/arch/mips/sgi-ip32/crime.c	2005-03-01 23:38:53 -08:00
@@ -4,6 +4,7 @@
  * for more details.
  *
  * Copyright (C) 2001, 2003 Keith M Wesolowski
+ * Copyright (C) 2005 Ilya A. Volynets <ilya@total-knowledge.com>
  */
 #include <linux/types.h>
 #include <linux/init.h>
@@ -24,7 +25,8 @@
 {
 	unsigned int id, rev;
 	const int field = 2 * sizeof(unsigned long);
-	
+
+	set_io_port_base((unsigned long) ioremap(MACEPCI_LOW_IO, 0x2000000));
 	crime = ioremap(CRIME_BASE, sizeof(struct sgi_crime));
 	mace = ioremap(MACE_BASE, sizeof(struct sgi_mace));
 
diff -Nru a/arch/mips/sgi-ip32/ip32-irq.c b/arch/mips/sgi-ip32/ip32-irq.c
--- a/arch/mips/sgi-ip32/ip32-irq.c	2005-03-01 23:38:57 -08:00
+++ b/arch/mips/sgi-ip32/ip32-irq.c	2005-03-01 23:38:57 -08:00
@@ -117,7 +117,7 @@
  * IRQ spinlock - Ralf says not to disable CPU interrupts,
  * and I think he knows better.
  */
-static spinlock_t ip32_irq_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(ip32_irq_lock);
 
 /* Some initial interrupts to set up */
 extern irqreturn_t crime_memerr_intr (int irq, void *dev_id,
diff -Nru a/arch/mips/sgi-ip32/ip32-memory.c b/arch/mips/sgi-ip32/ip32-memory.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/mips/sgi-ip32/ip32-memory.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,49 @@
+/*
+ * This file 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 Keith M Wesolowski
+ * Copyright (C) 2005 Ilya A. Volynets (Total Knowledge)
+ */
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+
+#include <asm/ip32/crime.h>
+#include <asm/bootinfo.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+
+extern void crime_init(void);
+
+void __init prom_meminit (void)
+{
+	u64 base, size;
+	int bank;
+
+	crime_init();
+
+	for (bank=0; bank < CRIME_MAXBANKS; bank++) {
+		u64 bankctl = crime->bank_ctrl[bank];
+		base = (bankctl & CRIME_MEM_BANK_CONTROL_ADDR) << 25;
+		if (bank != 0 && base == 0)
+			continue;
+		size = (bankctl & CRIME_MEM_BANK_CONTROL_SDRAM_SIZE) ? 128 : 32;
+		size <<= 20;
+		if (base + size > (256 << 20))
+			base += CRIME_HI_MEM_BASE;
+
+		printk("CRIME MC: bank %u base 0x%016lx size %luMB\n",
+			bank, base, size);
+		add_memory_region (base, size, BOOT_MEM_RAM);
+	}
+}
+
+
+unsigned long __init prom_free_prom_memory (void)
+{
+	return 0;
+}
diff -Nru a/arch/mips/sgi-ip32/ip32-reset.c b/arch/mips/sgi-ip32/ip32-reset.c
--- a/arch/mips/sgi-ip32/ip32-reset.c	2005-03-01 23:39:09 -08:00
+++ b/arch/mips/sgi-ip32/ip32-reset.c	2005-03-01 23:39:09 -08:00
@@ -189,10 +189,12 @@
 	_machine_restart = ip32_machine_restart;
 	_machine_halt = ip32_machine_halt;
 	_machine_power_off = ip32_machine_power_off;
-	request_irq(MACEISA_RTC_IRQ, ip32_rtc_int, 0, "rtc", NULL);
+
 	init_timer(&blink_timer);
 	blink_timer.function = blink_timeout;
 	notifier_chain_register(&panic_notifier_list, &panic_block);
+
+	request_irq(MACEISA_RTC_IRQ, ip32_rtc_int, 0, "rtc", NULL);
 
 	return 0;
 }
diff -Nru a/arch/mips/sgi-ip32/ip32-setup.c b/arch/mips/sgi-ip32/ip32-setup.c
--- a/arch/mips/sgi-ip32/ip32-setup.c	2005-03-01 23:39:09 -08:00
+++ b/arch/mips/sgi-ip32/ip32-setup.c	2005-03-01 23:39:09 -08:00
@@ -6,7 +6,7 @@
  * for more details.
  *
  * Copyright (C) 2000 Harald Koerfgen
- * Copyright (C) 2002, 03 Ilya A. Volynets
+ * Copyright (C) 2002, 2003, 2005 Ilya A. Volynets
  */
 #include <linux/config.h>
 #include <linux/console.h>
@@ -94,10 +94,6 @@
 
 static int __init ip32_setup(void)
 {
-	set_io_port_base((unsigned long) ioremap(MACEPCI_LOW_IO, 0x2000000));
-
-	crime_init();
-
 	board_be_init = ip32_be_init;
 
 	rtc_get_time = mc146818_get_cmos_time;
diff -Nru a/arch/mips/sibyte/sb1250/bcm1250_tbprof.c b/arch/mips/sibyte/sb1250/bcm1250_tbprof.c
--- a/arch/mips/sibyte/sb1250/bcm1250_tbprof.c	2005-03-01 23:38:56 -08:00
+++ b/arch/mips/sibyte/sb1250/bcm1250_tbprof.c	2005-03-01 23:38:56 -08:00
@@ -64,24 +64,24 @@
 	u_int64_t tb_options = M_SCD_TRACE_CFG_FREEZE_FULL;
 	/* Generate an SCD_PERFCNT interrupt in TB_PERIOD Zclks to
 	   trigger start of trace.  XXX vary sampling period */
-	__raw_writeq(0, IOADDR(A_SCD_PERF_CNT_1));
-	scdperfcnt = __raw_readq(IOADDR(A_SCD_PERF_CNT_CFG));
+	bus_writeq(0, IOADDR(A_SCD_PERF_CNT_1));
+	scdperfcnt = bus_readq(IOADDR(A_SCD_PERF_CNT_CFG));
 	/* Unfortunately, in Pass 2 we must clear all counters to knock down
 	   a previous interrupt request.  This means that bus profiling
 	   requires ALL of the SCD perf counters. */
-	__raw_writeq((scdperfcnt & ~M_SPC_CFG_SRC1) | // keep counters 0,2,3 as is
+	bus_writeq((scdperfcnt & ~M_SPC_CFG_SRC1) | // keep counters 0,2,3 as is
 		   M_SPC_CFG_ENABLE |		 // enable counting
 		   M_SPC_CFG_CLEAR |		 // clear all counters
 		   V_SPC_CFG_SRC1(1),		 // counter 1 counts cycles
-	      IOADDR(A_SCD_PERF_CNT_CFG));
-	__raw_writeq(next, IOADDR(A_SCD_PERF_CNT_1));
+		   IOADDR(A_SCD_PERF_CNT_CFG));
+	bus_writeq(next, IOADDR(A_SCD_PERF_CNT_1));
 	/* Reset the trace buffer */
-	__raw_writeq(M_SCD_TRACE_CFG_RESET, IOADDR(A_SCD_TRACE_CFG));
+	bus_writeq(M_SCD_TRACE_CFG_RESET, IOADDR(A_SCD_TRACE_CFG));
 #if 0 && defined(M_SCD_TRACE_CFG_FORCECNT)
 	/* XXXKW may want to expose control to the data-collector */
 	tb_options |= M_SCD_TRACE_CFG_FORCECNT;
 #endif
-	__raw_writeq(tb_options, IOADDR(A_SCD_TRACE_CFG));
+	bus_writeq(tb_options, IOADDR(A_SCD_TRACE_CFG));
 	sbp.tb_armed = 1;
 }
 
@@ -93,22 +93,23 @@
 		/* XXX should use XKPHYS to make writes bypass L2 */
 		u_int64_t *p = sbp.sbprof_tbbuf[sbp.next_tb_sample++];
 		/* Read out trace */
-		__raw_writeq(M_SCD_TRACE_CFG_START_READ, IOADDR(A_SCD_TRACE_CFG));
+		bus_writeq(M_SCD_TRACE_CFG_START_READ, IOADDR(A_SCD_TRACE_CFG));
 		__asm__ __volatile__ ("sync" : : : "memory");
 		/* Loop runs backwards because bundles are read out in reverse order */
 		for (i = 256 * 6; i > 0; i -= 6) {
 			// Subscripts decrease to put bundle in the order
 			//   t0 lo, t0 hi, t1 lo, t1 hi, t2 lo, t2 hi
-			p[i-1] = __raw_readq(IOADDR(A_SCD_TRACE_READ)); // read t2 hi
-			p[i-2] = __raw_readq(IOADDR(A_SCD_TRACE_READ)); // read t2 lo
-			p[i-3] = __raw_readq(IOADDR(A_SCD_TRACE_READ)); // read t1 hi
-			p[i-4] = __raw_readq(IOADDR(A_SCD_TRACE_READ)); // read t1 lo
-			p[i-5] = __raw_readq(IOADDR(A_SCD_TRACE_READ)); // read t0 hi
-			p[i-6] = __raw_readq(IOADDR(A_SCD_TRACE_READ)); // read t0 lo
+			p[i-1] = bus_readq(IOADDR(A_SCD_TRACE_READ)); // read t2 hi
+			p[i-2] = bus_readq(IOADDR(A_SCD_TRACE_READ)); // read t2 lo
+			p[i-3] = bus_readq(IOADDR(A_SCD_TRACE_READ)); // read t1 hi
+			p[i-4] = bus_readq(IOADDR(A_SCD_TRACE_READ)); // read t1 lo
+			p[i-5] = bus_readq(IOADDR(A_SCD_TRACE_READ)); // read t0 hi
+			p[i-6] = bus_readq(IOADDR(A_SCD_TRACE_READ)); // read t0 lo
 		}
 		if (!sbp.tb_enable) {
 			DBG(printk(DEVNAME ": tb_intr shutdown\n"));
-			__raw_writeq(M_SCD_TRACE_CFG_RESET, IOADDR(A_SCD_TRACE_CFG));
+			bus_writeq(M_SCD_TRACE_CFG_RESET,
+				   IOADDR(A_SCD_TRACE_CFG));
 			sbp.tb_armed = 0;
 			wake_up(&sbp.tb_sync);
 		} else {
@@ -117,7 +118,7 @@
 	} else {
 		/* No more trace buffer samples */
 		DBG(printk(DEVNAME ": tb_intr full\n"));
-		__raw_writeq(M_SCD_TRACE_CFG_RESET, IOADDR(A_SCD_TRACE_CFG));
+		bus_writeq(M_SCD_TRACE_CFG_RESET, IOADDR(A_SCD_TRACE_CFG));
 		sbp.tb_armed = 0;
 		if (!sbp.tb_enable) {
 			wake_up(&sbp.tb_sync);
@@ -151,13 +152,13 @@
 		return -EBUSY;
 	}
 	/* Make sure there isn't a perf-cnt interrupt waiting */
-	scdperfcnt = __raw_readq(IOADDR(A_SCD_PERF_CNT_CFG));
+	scdperfcnt = bus_readq(IOADDR(A_SCD_PERF_CNT_CFG));
 	/* Disable and clear counters, override SRC_1 */
-	__raw_writeq((scdperfcnt & ~(M_SPC_CFG_SRC1 | M_SPC_CFG_ENABLE)) |
+	bus_writeq((scdperfcnt & ~(M_SPC_CFG_SRC1 | M_SPC_CFG_ENABLE)) |
 		   M_SPC_CFG_ENABLE |
 		   M_SPC_CFG_CLEAR |
 		   V_SPC_CFG_SRC1(1),
-	      IOADDR(A_SCD_PERF_CNT_CFG));
+		   IOADDR(A_SCD_PERF_CNT_CFG));
 
 	/* We grab this interrupt to prevent others from trying to use
            it, even though we don't want to service the interrupts
@@ -171,52 +172,55 @@
 	/* I need the core to mask these, but the interrupt mapper to
 	   pass them through.  I am exploiting my knowledge that
 	   cp0_status masks out IP[5]. krw */
-	__raw_writeq(K_INT_MAP_I3,
-		     IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) + (K_INT_PERF_CNT<<3)));
+	bus_writeq(K_INT_MAP_I3,
+		   IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) +
+			  (K_INT_PERF_CNT << 3)));
 
 	/* Initialize address traps */
-	__raw_writeq(0, IOADDR(A_ADDR_TRAP_UP_0));
-	__raw_writeq(0, IOADDR(A_ADDR_TRAP_UP_1));
-	__raw_writeq(0, IOADDR(A_ADDR_TRAP_UP_2));
-	__raw_writeq(0, IOADDR(A_ADDR_TRAP_UP_3));
-
-	__raw_writeq(0, IOADDR(A_ADDR_TRAP_DOWN_0));
-	__raw_writeq(0, IOADDR(A_ADDR_TRAP_DOWN_1));
-	__raw_writeq(0, IOADDR(A_ADDR_TRAP_DOWN_2));
-	__raw_writeq(0, IOADDR(A_ADDR_TRAP_DOWN_3));
-
-	__raw_writeq(0, IOADDR(A_ADDR_TRAP_CFG_0));
-	__raw_writeq(0, IOADDR(A_ADDR_TRAP_CFG_1));
-	__raw_writeq(0, IOADDR(A_ADDR_TRAP_CFG_2));
-	__raw_writeq(0, IOADDR(A_ADDR_TRAP_CFG_3));
+	bus_writeq(0, IOADDR(A_ADDR_TRAP_UP_0));
+	bus_writeq(0, IOADDR(A_ADDR_TRAP_UP_1));
+	bus_writeq(0, IOADDR(A_ADDR_TRAP_UP_2));
+	bus_writeq(0, IOADDR(A_ADDR_TRAP_UP_3));
+
+	bus_writeq(0, IOADDR(A_ADDR_TRAP_DOWN_0));
+	bus_writeq(0, IOADDR(A_ADDR_TRAP_DOWN_1));
+	bus_writeq(0, IOADDR(A_ADDR_TRAP_DOWN_2));
+	bus_writeq(0, IOADDR(A_ADDR_TRAP_DOWN_3));
+
+	bus_writeq(0, IOADDR(A_ADDR_TRAP_CFG_0));
+	bus_writeq(0, IOADDR(A_ADDR_TRAP_CFG_1));
+	bus_writeq(0, IOADDR(A_ADDR_TRAP_CFG_2));
+	bus_writeq(0, IOADDR(A_ADDR_TRAP_CFG_3));
 
 	/* Initialize Trace Event 0-7 */
 	//				when interrupt
-	__raw_writeq(M_SCD_TREVT_INTERRUPT, IOADDR(A_SCD_TRACE_EVENT_0));
-	__raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_1));
-	__raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_2));
-	__raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_3));
-	__raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_4));
-	__raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_5));
-	__raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_6));
-	__raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_7));
+	bus_writeq(M_SCD_TREVT_INTERRUPT, IOADDR(A_SCD_TRACE_EVENT_0));
+	bus_writeq(0, IOADDR(A_SCD_TRACE_EVENT_1));
+	bus_writeq(0, IOADDR(A_SCD_TRACE_EVENT_2));
+	bus_writeq(0, IOADDR(A_SCD_TRACE_EVENT_3));
+	bus_writeq(0, IOADDR(A_SCD_TRACE_EVENT_4));
+	bus_writeq(0, IOADDR(A_SCD_TRACE_EVENT_5));
+	bus_writeq(0, IOADDR(A_SCD_TRACE_EVENT_6));
+	bus_writeq(0, IOADDR(A_SCD_TRACE_EVENT_7));
 
 	/* Initialize Trace Sequence 0-7 */
 	//				     Start on event 0 (interrupt)
-	__raw_writeq(V_SCD_TRSEQ_FUNC_START|0x0fff,
-		     IOADDR(A_SCD_TRACE_SEQUENCE_0));
+	bus_writeq(V_SCD_TRSEQ_FUNC_START | 0x0fff,
+		   IOADDR(A_SCD_TRACE_SEQUENCE_0));
 	//			  dsamp when d used | asamp when a used
-	__raw_writeq(M_SCD_TRSEQ_ASAMPLE|M_SCD_TRSEQ_DSAMPLE|K_SCD_TRSEQ_TRIGGER_ALL,
-		     IOADDR(A_SCD_TRACE_SEQUENCE_1));
-	__raw_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_2));
-	__raw_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_3));
-	__raw_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_4));
-	__raw_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_5));
-	__raw_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_6));
-	__raw_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_7));
+	bus_writeq(M_SCD_TRSEQ_ASAMPLE | M_SCD_TRSEQ_DSAMPLE |
+		   K_SCD_TRSEQ_TRIGGER_ALL,
+		   IOADDR(A_SCD_TRACE_SEQUENCE_1));
+	bus_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_2));
+	bus_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_3));
+	bus_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_4));
+	bus_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_5));
+	bus_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_6));
+	bus_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_7));
 
 	/* Now indicate the PERF_CNT interrupt as a trace-relevant interrupt */
-	__raw_writeq((1ULL << K_INT_PERF_CNT), IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_TRACE)));
+	bus_writeq((1ULL << K_INT_PERF_CNT),
+		   IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_TRACE)));
 
 	arm_tb();
 
diff -Nru a/arch/mips/sibyte/sb1250/bus_watcher.c b/arch/mips/sibyte/sb1250/bus_watcher.c
--- a/arch/mips/sibyte/sb1250/bus_watcher.c	2005-03-01 23:38:57 -08:00
+++ b/arch/mips/sibyte/sb1250/bus_watcher.c	2005-03-01 23:38:57 -08:00
@@ -188,7 +188,8 @@
 	csr_out32(M_SCD_TRACE_CFG_START_READ, IOADDR(A_SCD_TRACE_CFG));
 
 	for (i=0; i<256*6; i++)
-		printk("%016llx\n", (unsigned long long)__raw_readq(IOADDR(A_SCD_TRACE_READ)));
+		printk("%016llx\n",
+		       (unsigned long long)bus_readq(IOADDR(A_SCD_TRACE_READ)));
 
 	csr_out32(M_SCD_TRACE_CFG_RESET, IOADDR(A_SCD_TRACE_CFG));
 	csr_out32(M_SCD_TRACE_CFG_START, IOADDR(A_SCD_TRACE_CFG));
diff -Nru a/arch/mips/sibyte/sb1250/irq.c b/arch/mips/sibyte/sb1250/irq.c
--- a/arch/mips/sibyte/sb1250/irq.c	2005-03-01 23:39:16 -08:00
+++ b/arch/mips/sibyte/sb1250/irq.c	2005-03-01 23:39:16 -08:00
@@ -88,7 +88,7 @@
 /* Store the CPU id (not the logical number) */
 int sb1250_irq_owner[SB1250_NR_IRQS];
 
-spinlock_t sb1250_imr_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(sb1250_imr_lock);
 
 void sb1250_mask_irq(int cpu, int irq)
 {
@@ -96,9 +96,11 @@
 	u64 cur_ints;
 
 	spin_lock_irqsave(&sb1250_imr_lock, flags);
-	cur_ints = ____raw_readq(IOADDR(A_IMR_MAPPER(cpu) + R_IMR_INTERRUPT_MASK));
+	cur_ints = __bus_readq(IOADDR(A_IMR_MAPPER(cpu) +
+				      R_IMR_INTERRUPT_MASK));
 	cur_ints |= (((u64) 1) << irq);
-	____raw_writeq(cur_ints, IOADDR(A_IMR_MAPPER(cpu) + R_IMR_INTERRUPT_MASK));
+	__bus_writeq(cur_ints, IOADDR(A_IMR_MAPPER(cpu) +
+				      R_IMR_INTERRUPT_MASK));
 	spin_unlock_irqrestore(&sb1250_imr_lock, flags);
 }
 
@@ -108,9 +110,11 @@
 	u64 cur_ints;
 
 	spin_lock_irqsave(&sb1250_imr_lock, flags);
-	cur_ints = ____raw_readq(IOADDR(A_IMR_MAPPER(cpu) + R_IMR_INTERRUPT_MASK));
+	cur_ints = __bus_readq(IOADDR(A_IMR_MAPPER(cpu) +
+				      R_IMR_INTERRUPT_MASK));
 	cur_ints &= ~(((u64) 1) << irq);
-	____raw_writeq(cur_ints, IOADDR(A_IMR_MAPPER(cpu) + R_IMR_INTERRUPT_MASK));
+	__bus_writeq(cur_ints, IOADDR(A_IMR_MAPPER(cpu) +
+				      R_IMR_INTERRUPT_MASK));
 	spin_unlock_irqrestore(&sb1250_imr_lock, flags);
 }
 
@@ -145,19 +149,23 @@
 
 	/* Swizzle each CPU's IMR (but leave the IP selection alone) */
 	old_cpu = sb1250_irq_owner[irq];
-	cur_ints = ____raw_readq(IOADDR(A_IMR_MAPPER(old_cpu) + R_IMR_INTERRUPT_MASK));
+	cur_ints = __bus_readq(IOADDR(A_IMR_MAPPER(old_cpu) +
+			       R_IMR_INTERRUPT_MASK));
 	int_on = !(cur_ints & (((u64) 1) << irq));
 	if (int_on) {
 		/* If it was on, mask it */
 		cur_ints |= (((u64) 1) << irq);
-		____raw_writeq(cur_ints, IOADDR(A_IMR_MAPPER(old_cpu) + R_IMR_INTERRUPT_MASK));
+		__bus_writeq(cur_ints, IOADDR(A_IMR_MAPPER(old_cpu) +
+					      R_IMR_INTERRUPT_MASK));
 	}
 	sb1250_irq_owner[irq] = cpu;
 	if (int_on) {
 		/* unmask for the new CPU */
-		cur_ints = ____raw_readq(IOADDR(A_IMR_MAPPER(cpu) + R_IMR_INTERRUPT_MASK));
+		cur_ints = __bus_readq(IOADDR(A_IMR_MAPPER(cpu) +
+				       R_IMR_INTERRUPT_MASK));
 		cur_ints &= ~(((u64) 1) << irq);
-		____raw_writeq(cur_ints, IOADDR(A_IMR_MAPPER(cpu) + R_IMR_INTERRUPT_MASK));
+		__bus_writeq(cur_ints, IOADDR(A_IMR_MAPPER(cpu) +
+					      R_IMR_INTERRUPT_MASK));
 	}
 	spin_unlock(&sb1250_imr_lock);
 	spin_unlock_irqrestore(&desc->lock, flags);
@@ -200,8 +208,8 @@
 	 * deliver the interrupts to all CPUs (which makes affinity
 	 * changing easier for us)
 	 */
-	pending = __raw_readq(IOADDR(A_IMR_REGISTER(sb1250_irq_owner[irq],
-						    R_IMR_LDT_INTERRUPT)));
+	pending = bus_readq(IOADDR(A_IMR_REGISTER(sb1250_irq_owner[irq],
+						  R_IMR_LDT_INTERRUPT)));
 	pending &= ((u64)1 << (irq));
 	if (pending) {
 		int i;
@@ -216,8 +224,9 @@
 			 * Clear for all CPUs so an affinity switch
 			 * doesn't find an old status
 			 */
-			__raw_writeq(pending, 
-				     IOADDR(A_IMR_REGISTER(cpu, R_IMR_LDT_INTERRUPT_CLR)));
+			bus_writeq(pending,
+				   IOADDR(A_IMR_REGISTER(cpu,
+						R_IMR_LDT_INTERRUPT_CLR)));
 		}
 
 		/*
@@ -331,14 +340,12 @@
 
 	/* Default everything to IP2 */
 	for (i = 0; i < SB1250_NR_IRQS; i++) {	/* was I0 */
-		__raw_writeq(IMR_IP2_VAL,
-			     IOADDR(A_IMR_REGISTER(0,
-						   R_IMR_INTERRUPT_MAP_BASE) +
-				    (i << 3)));
-		__raw_writeq(IMR_IP2_VAL,
-			     IOADDR(A_IMR_REGISTER(1,
-						    R_IMR_INTERRUPT_MAP_BASE) +
-				    (i << 3)));
+		bus_writeq(IMR_IP2_VAL,
+			   IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) +
+				  (i << 3)));
+		bus_writeq(IMR_IP2_VAL,
+			   IOADDR(A_IMR_REGISTER(1, R_IMR_INTERRUPT_MAP_BASE) +
+				  (i << 3)));
 	}
 
 	init_sb1250_irqs();
@@ -348,21 +355,23 @@
 	 * inter-cpu messages
 	 */
 	/* Was I1 */
-	__raw_writeq(IMR_IP3_VAL, IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) +
-					 (K_INT_MBOX_0 << 3)));
-	__raw_writeq(IMR_IP3_VAL, IOADDR(A_IMR_REGISTER(1, R_IMR_INTERRUPT_MAP_BASE) +
-					 (K_INT_MBOX_0 << 3)));
+	bus_writeq(IMR_IP3_VAL,
+		   IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) +
+			  (K_INT_MBOX_0 << 3)));
+	bus_writeq(IMR_IP3_VAL,
+		   IOADDR(A_IMR_REGISTER(1, R_IMR_INTERRUPT_MAP_BASE) +
+			  (K_INT_MBOX_0 << 3)));
 
 	/* Clear the mailboxes.  The firmware may leave them dirty */
-	__raw_writeq(0xffffffffffffffff,
-		     IOADDR(A_IMR_REGISTER(0, R_IMR_MAILBOX_CLR_CPU)));
-	__raw_writeq(0xffffffffffffffff,
-		     IOADDR(A_IMR_REGISTER(1, R_IMR_MAILBOX_CLR_CPU)));
+	bus_writeq(0xffffffffffffffffULL,
+		   IOADDR(A_IMR_REGISTER(0, R_IMR_MAILBOX_CLR_CPU)));
+	bus_writeq(0xffffffffffffffffULL,
+		   IOADDR(A_IMR_REGISTER(1, R_IMR_MAILBOX_CLR_CPU)));
 
 	/* Mask everything except the mailbox registers for both cpus */
 	tmp = ~((u64) 0) ^ (((u64) 1) << K_INT_MBOX_0);
-	__raw_writeq(tmp, IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MASK)));
-	__raw_writeq(tmp, IOADDR(A_IMR_REGISTER(1, R_IMR_INTERRUPT_MASK)));
+	bus_writeq(tmp, IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MASK)));
+	bus_writeq(tmp, IOADDR(A_IMR_REGISTER(1, R_IMR_INTERRUPT_MASK)));
 
 	sb1250_steal_irq(K_INT_MBOX_0);
 
@@ -387,12 +396,12 @@
 		sb1250_duart_present[kgdb_port] = 0;
 #endif
 		/* Setup uart 1 settings, mapper */
-		__raw_writeq(M_DUART_IMR_BRK, IOADDR(A_DUART_IMRREG(kgdb_port)));
+		bus_writeq(M_DUART_IMR_BRK, IOADDR(A_DUART_IMRREG(kgdb_port)));
 
 		sb1250_steal_irq(kgdb_irq);
-		__raw_writeq(IMR_IP6_VAL,
-			     IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) +
-				    (kgdb_irq<<3)));
+		bus_writeq(IMR_IP6_VAL,
+			   IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) +
+				  (kgdb_irq<<3)));
 		sb1250_unmask_irq(0, kgdb_irq);
 	}
 #endif
diff -Nru a/arch/mips/sibyte/sb1250/irq_handler.S b/arch/mips/sibyte/sb1250/irq_handler.S
--- a/arch/mips/sibyte/sb1250/irq_handler.S	2005-03-01 23:38:57 -08:00
+++ b/arch/mips/sibyte/sb1250/irq_handler.S	2005-03-01 23:38:57 -08:00
@@ -123,7 +123,7 @@
 	 * check the 1250 interrupt registers to figure out what to do
 	 * Need to detect which CPU we're on, now that smp_affinity is supported.
 	 */
-	PTR_LA	v0, KSEG1 + A_IMR_CPU0_BASE
+	PTR_LA	v0, CKSEG1 + A_IMR_CPU0_BASE
 #ifdef CONFIG_SMP
 	lw	t1, TI_CPU($28)
 	sll	t1, IMR_REGISTER_SPACING_SHIFT
diff -Nru a/arch/mips/sibyte/sb1250/setup.c b/arch/mips/sibyte/sb1250/setup.c
--- a/arch/mips/sibyte/sb1250/setup.c	2005-03-01 23:38:53 -08:00
+++ b/arch/mips/sibyte/sb1250/setup.c	2005-03-01 23:38:53 -08:00
@@ -153,7 +153,7 @@
 	int bad_config = 0;
 
 	sb1_pass = read_c0_prid() & 0xff;
-	sys_rev = __raw_readq(IOADDR(A_SCD_SYSTEM_REVISION));
+	sys_rev = bus_readq(IOADDR(A_SCD_SYSTEM_REVISION));
 	soc_type = SYS_SOC_TYPE(sys_rev);
 	soc_pass = G_SYS_REVISION(sys_rev);
 
@@ -162,7 +162,7 @@
 		machine_restart(NULL);
 	}
 
-	plldiv = G_SYS_PLL_DIV(__raw_readq(IOADDR(A_SCD_SYSTEM_CFG)));
+	plldiv = G_SYS_PLL_DIV(bus_readq(IOADDR(A_SCD_SYSTEM_CFG)));
 	zbbus_mhz = ((plldiv >> 1) * 50) + ((plldiv & 1) * 25);
 
 	prom_printf("Broadcom SiByte %s %s @ %d MHz (SB1 rev %d)\n",
diff -Nru a/arch/mips/sibyte/sb1250/smp.c b/arch/mips/sibyte/sb1250/smp.c
--- a/arch/mips/sibyte/sb1250/smp.c	2005-03-01 23:39:18 -08:00
+++ b/arch/mips/sibyte/sb1250/smp.c	2005-03-01 23:39:18 -08:00
@@ -73,7 +73,7 @@
  */
 void core_send_ipi(int cpu, unsigned int action)
 {
-	__raw_writeq((((u64)action)<< 48), mailbox_set_regs[cpu]);
+	bus_writeq((((u64)action) << 48), mailbox_set_regs[cpu]);
 }
 
 void sb1250_mailbox_interrupt(struct pt_regs *regs)
@@ -83,10 +83,10 @@
 
 	kstat_this_cpu.irqs[K_INT_MBOX_0]++;
 	/* Load the mailbox register to figure out what we're supposed to do */
-	action = (____raw_readq(mailbox_regs[cpu]) >> 48) & 0xffff;
+	action = (__bus_readq(mailbox_regs[cpu]) >> 48) & 0xffff;
 
 	/* Clear the mailbox to clear the interrupt */
-	____raw_writeq(((u64)action)<<48, mailbox_clear_regs[cpu]);
+	__bus_writeq(((u64)action) << 48, mailbox_clear_regs[cpu]);
 
 	/*
 	 * Nothing to do for SMP_RESCHEDULE_YOURSELF; returning from the
diff -Nru a/arch/mips/sibyte/sb1250/time.c b/arch/mips/sibyte/sb1250/time.c
--- a/arch/mips/sibyte/sb1250/time.c	2005-03-01 23:38:58 -08:00
+++ b/arch/mips/sibyte/sb1250/time.c	2005-03-01 23:38:58 -08:00
@@ -67,21 +67,24 @@
 	sb1250_mask_irq(cpu, irq);
 
 	/* Map the timer interrupt to ip[4] of this cpu */
-	__raw_writeq(IMR_IP4_VAL, IOADDR(A_IMR_REGISTER(cpu, R_IMR_INTERRUPT_MAP_BASE) +
-					 (irq << 3)));
+	bus_writeq(IMR_IP4_VAL,
+		   IOADDR(A_IMR_REGISTER(cpu, R_IMR_INTERRUPT_MAP_BASE) +
+			  (irq << 3)));
 
 	/* the general purpose timer ticks at 1 Mhz independent if the rest of the system */
 	/* Disable the timer and set up the count */
-	__raw_writeq(0, IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
+	bus_writeq(0, IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
 #ifdef CONFIG_SIMULATION
-	__raw_writeq(50000 / HZ, IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT)));
+	bus_writeq(50000 / HZ,
+		   IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT)));
 #else
-	__raw_writeq(1000000/HZ, IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT)));
+	bus_writeq(1000000/HZ,
+		   IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT)));
 #endif
 
 	/* Set the timer running */
-	__raw_writeq(M_SCD_TIMER_ENABLE|M_SCD_TIMER_MODE_CONTINUOUS,
-		     IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
+	bus_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
+		   IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
 
 	sb1250_unmask_irq(cpu, irq);
 	sb1250_steal_irq(irq);
@@ -102,8 +105,8 @@
 	int irq = K_INT_TIMER_0 + cpu;
 
 	/* Reset the timer */
-	____raw_writeq(M_SCD_TIMER_ENABLE|M_SCD_TIMER_MODE_CONTINUOUS,
-		       IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
+	__bus_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
+		     IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
 
 	/*
 	 * CPU 0 handles the global timer interrupt job
@@ -127,7 +130,7 @@
 unsigned long sb1250_gettimeoffset(void)
 {
 	unsigned long count =
-		__raw_readq(IOADDR(A_SCD_TIMER_REGISTER(0, R_SCD_TIMER_CNT)));
+		bus_readq(IOADDR(A_SCD_TIMER_REGISTER(0, R_SCD_TIMER_CNT)));
 
 	return 1000000/HZ - count;
  }
diff -Nru a/arch/mips/sibyte/swarm/rtc_m41t81.c b/arch/mips/sibyte/swarm/rtc_m41t81.c
--- a/arch/mips/sibyte/swarm/rtc_m41t81.c	2005-03-01 23:38:53 -08:00
+++ b/arch/mips/sibyte/swarm/rtc_m41t81.c	2005-03-01 23:38:53 -08:00
@@ -82,57 +82,59 @@
 #define M41T81REG_SQW	0x13		/* square wave register */
 
 #define M41T81_CCR_ADDRESS	0x68
-#define SMB_CSR(reg) (IOADDR(A_SMB_REGISTER(1, reg)))
+#define SMB_CSR(reg) ((u8 *) (IOADDR(A_SMB_REGISTER(1, reg))))
 
 static int m41t81_read(uint8_t addr)
 {
-	while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+	while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
 		;
 
-	__raw_writeq(addr & 0xff, SMB_CSR(R_SMB_CMD));
-	__raw_writeq((V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_WR1BYTE), SMB_CSR(R_SMB_START));
+	bus_writeq(addr & 0xff, SMB_CSR(R_SMB_CMD));
+	bus_writeq((V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_WR1BYTE),
+		   SMB_CSR(R_SMB_START));
 
-	while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+	while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
 		;
 
-	__raw_writeq((V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_RD1BYTE), SMB_CSR(R_SMB_START));
+	bus_writeq((V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_RD1BYTE),
+		   SMB_CSR(R_SMB_START));
 
-	while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+	while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
 		;
 
-	if (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
+	if (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
 		/* Clear error bit by writing a 1 */
-		__raw_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
+		bus_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
 		return -1;
 	}
 
-	return (__raw_readq(SMB_CSR(R_SMB_DATA)) & 0xff);
+	return (bus_readq(SMB_CSR(R_SMB_DATA)) & 0xff);
 }
 
 static int m41t81_write(uint8_t addr, int b)
 {
-	while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+	while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
 		;
 
-	__raw_writeq((addr & 0xFF), SMB_CSR(R_SMB_CMD));
-	__raw_writeq((b & 0xff), SMB_CSR(R_SMB_DATA));
-	__raw_writeq(V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_WR2BYTE,
-	      SMB_CSR(R_SMB_START));
+	bus_writeq((addr & 0xFF), SMB_CSR(R_SMB_CMD));
+	bus_writeq((b & 0xff), SMB_CSR(R_SMB_DATA));
+	bus_writeq(V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_WR2BYTE,
+		   SMB_CSR(R_SMB_START));
 
-	while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+	while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
 		;
 
-	if (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
+	if (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
 		/* Clear error bit by writing a 1 */
-		__raw_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
+		bus_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
 		return -1;
 	} 
 
 	/* read the same byte again to make sure it is written */
-	__raw_writeq(V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_RD1BYTE,
-	      SMB_CSR(R_SMB_START));
+	bus_writeq(V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_RD1BYTE,
+		   SMB_CSR(R_SMB_START));
 
-	while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+	while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
 		;
 	
 	return 0;
diff -Nru a/arch/mips/sibyte/swarm/rtc_xicor1241.c b/arch/mips/sibyte/swarm/rtc_xicor1241.c
--- a/arch/mips/sibyte/swarm/rtc_xicor1241.c	2005-03-01 23:38:54 -08:00
+++ b/arch/mips/sibyte/swarm/rtc_xicor1241.c	2005-03-01 23:38:54 -08:00
@@ -57,50 +57,52 @@
 
 #define X1241_CCR_ADDRESS	0x6F
 
-#define SMB_CSR(reg) (IOADDR(A_SMB_REGISTER(1, reg)))
+#define SMB_CSR(reg) ((u8 *) (IOADDR(A_SMB_REGISTER(1, reg))))
 
 static int xicor_read(uint8_t addr)
 {
-        while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+        while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
                 ;
 
-	__raw_writeq((addr >> 8) & 0x7, SMB_CSR(R_SMB_CMD));
-	__raw_writeq((addr & 0xff), SMB_CSR(R_SMB_DATA));
-	__raw_writeq((V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR2BYTE), SMB_CSR(R_SMB_START));
+	bus_writeq((addr >> 8) & 0x7, SMB_CSR(R_SMB_CMD));
+	bus_writeq((addr & 0xff), SMB_CSR(R_SMB_DATA));
+	bus_writeq((V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR2BYTE),
+		   SMB_CSR(R_SMB_START));
 
-        while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+        while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
                 ;
 
-	__raw_writeq((V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_RD1BYTE), SMB_CSR(R_SMB_START));
+	bus_writeq((V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_RD1BYTE),
+		   SMB_CSR(R_SMB_START));
 
-        while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+        while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
                 ;
 
-        if (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
+        if (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
                 /* Clear error bit by writing a 1 */
-                __raw_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
+                bus_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
                 return -1;
         }
 
-	return (__raw_readq(SMB_CSR(R_SMB_DATA)) & 0xff);
+	return (bus_readq(SMB_CSR(R_SMB_DATA)) & 0xff);
 }
 
 static int xicor_write(uint8_t addr, int b)
 {
-        while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+        while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
                 ;
 
-	__raw_writeq(addr, SMB_CSR(R_SMB_CMD));
-	__raw_writeq((addr & 0xff) | ((b & 0xff) << 8), SMB_CSR(R_SMB_DATA));
-	__raw_writeq(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR3BYTE,
-	      SMB_CSR(R_SMB_START));
+	bus_writeq(addr, SMB_CSR(R_SMB_CMD));
+	bus_writeq((addr & 0xff) | ((b & 0xff) << 8), SMB_CSR(R_SMB_DATA));
+	bus_writeq(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR3BYTE,
+		   SMB_CSR(R_SMB_START));
 
-        while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+        while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
                 ;
 
-        if (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
+        if (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
                 /* Clear error bit by writing a 1 */
-                __raw_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
+                bus_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
                 return -1;
         } else {
 		return 0;
diff -Nru a/arch/mips/sibyte/swarm/setup.c b/arch/mips/sibyte/swarm/setup.c
--- a/arch/mips/sibyte/swarm/setup.c	2005-03-01 23:38:57 -08:00
+++ b/arch/mips/sibyte/swarm/setup.c	2005-03-01 23:38:57 -08:00
@@ -27,6 +27,7 @@
 #include <linux/bootmem.h>
 #include <linux/blkdev.h>
 #include <linux/init.h>
+#include <linux/kernel.h>
 #include <linux/tty.h>
 #include <linux/initrd.h>
 
@@ -85,8 +86,6 @@
 
 static int __init swarm_setup(void)
 {
-	extern int panic_timeout;
-
 	sb1250_setup();
 
 	panic_timeout = 5;  /* For debug.  */
diff -Nru a/arch/mips/sibyte/swarm/time.c b/arch/mips/sibyte/swarm/time.c
--- a/arch/mips/sibyte/swarm/time.c	2005-03-01 23:38:54 -08:00
+++ b/arch/mips/sibyte/swarm/time.c	2005-03-01 23:38:54 -08:00
@@ -79,46 +79,48 @@
 
 static int xicor_read(uint8_t addr)
 {
-        while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+        while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
                 ;
 
-	__raw_writeq((addr >> 8) & 0x7, SMB_CSR(R_SMB_CMD));
-	__raw_writeq((addr & 0xff), SMB_CSR(R_SMB_DATA));
-	__raw_writeq((V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR2BYTE), SMB_CSR(R_SMB_START));
+	bus_writeq((addr >> 8) & 0x7, SMB_CSR(R_SMB_CMD));
+	bus_writeq((addr & 0xff), SMB_CSR(R_SMB_DATA));
+	bus_writeq((V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR2BYTE),
+		   SMB_CSR(R_SMB_START));
 
-        while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+        while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
                 ;
 
-	__raw_writeq((V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_RD1BYTE), SMB_CSR(R_SMB_START));
+	bus_writeq((V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_RD1BYTE),
+		   SMB_CSR(R_SMB_START));
 
-        while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+        while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
                 ;
 
-        if (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
+        if (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
                 /* Clear error bit by writing a 1 */
-                __raw_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
+                bus_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
                 return -1;
         }
 
-	return (__raw_readq(SMB_CSR(R_SMB_DATA)) & 0xff);
+	return (bus_readq(SMB_CSR(R_SMB_DATA)) & 0xff);
 }
 
 static int xicor_write(uint8_t addr, int b)
 {
-        while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+        while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
                 ;
 
-	__raw_writeq(addr, SMB_CSR(R_SMB_CMD));
-	__raw_writeq((addr & 0xff) | ((b & 0xff) << 8), SMB_CSR(R_SMB_DATA));
-	__raw_writeq(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR3BYTE,
-	      SMB_CSR(R_SMB_START));
+	bus_writeq(addr, SMB_CSR(R_SMB_CMD));
+	bus_writeq((addr & 0xff) | ((b & 0xff) << 8), SMB_CSR(R_SMB_DATA));
+	bus_writeq(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR3BYTE,
+		   SMB_CSR(R_SMB_START));
 
-        while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+        while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
                 ;
 
-        if (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
+        if (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
                 /* Clear error bit by writing a 1 */
-                __raw_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
+                bus_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
                 return -1;
         } else {
 		return 0;
@@ -226,8 +228,8 @@
 	/* Establish communication with the Xicor 1241 RTC */
 	/* XXXKW how do I share the SMBus with the I2C subsystem? */
 
-	__raw_writeq(K_SMB_FREQ_400KHZ, SMB_CSR(R_SMB_FREQ));
-	__raw_writeq(0, SMB_CSR(R_SMB_CONTROL));
+	bus_writeq(K_SMB_FREQ_400KHZ, SMB_CSR(R_SMB_FREQ));
+	bus_writeq(0, SMB_CSR(R_SMB_CONTROL));
 
 	if ((status = xicor_read(X1241REG_SR_RTCF)) < 0) {
 		printk("x1241: couldn't detect on SWARM SMBus 1\n");
diff -Nru a/arch/mips/sni/irq.c b/arch/mips/sni/irq.c
--- a/arch/mips/sni/irq.c	2005-03-01 23:38:54 -08:00
+++ b/arch/mips/sni/irq.c	2005-03-01 23:38:54 -08:00
@@ -17,7 +17,7 @@
 #include <asm/io.h>
 #include <asm/sni.h>
 
-spinlock_t pciasic_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(pciasic_lock);
 
 extern asmlinkage void sni_rm200_pci_handle_int(void);
 
diff -Nru a/arch/mips/tx4927/common/tx4927_irq.c b/arch/mips/tx4927/common/tx4927_irq.c
--- a/arch/mips/tx4927/common/tx4927_irq.c	2005-03-01 23:39:17 -08:00
+++ b/arch/mips/tx4927/common/tx4927_irq.c	2005-03-01 23:39:17 -08:00
@@ -143,8 +143,8 @@
  * Kernel structs for all pic's
  */
 
-static spinlock_t tx4927_cp0_lock = SPIN_LOCK_UNLOCKED;
-static spinlock_t tx4927_pic_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(tx4927_cp0_lock);
+static DEFINE_SPINLOCK(tx4927_pic_lock);
 
 #define TX4927_CP0_NAME "TX4927-CP0"
 static struct hw_interrupt_type tx4927_irq_cp0_type = {
diff -Nru a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c
--- a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c	2005-03-01 23:38:55 -08:00
+++ b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c	2005-03-01 23:38:55 -08:00
@@ -248,7 +248,7 @@
 static void toshiba_rbtx4927_irq_isa_end(unsigned int irq);
 #endif
 
-static spinlock_t toshiba_rbtx4927_ioc_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(toshiba_rbtx4927_ioc_lock);
 
 
 #define TOSHIBA_RBTX4927_IOC_NAME "RBTX4927-IOC"
@@ -669,7 +669,7 @@
 {
 	extern void tx4927_irq_init(void);
 
-	cli();
+	local_irq_disable();
 
 	tx4927_irq_init();
 	toshiba_rbtx4927_irq_ioc_init();
diff -Nru a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
--- a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c	2005-03-01 23:39:07 -08:00
+++ b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c	2005-03-01 23:39:07 -08:00
@@ -727,7 +727,7 @@
 	reg_wr08(RBTX4927_SW_RESET_DO, RBTX4927_SW_RESET_DO_SET);
 
 	/* do something passive while waiting for reset */
-	cli();
+	local_irq_disable();
 	while (1)
 		asm_wait();
 
@@ -738,7 +738,7 @@
 void toshiba_rbtx4927_halt(void)
 {
 	printk(KERN_NOTICE "System Halted\n");
-	cli();
+	local_irq_disable();
 	while (1) {
 		asm_wait();
 	}
diff -Nru a/arch/mips/vr4181/common/irq.c b/arch/mips/vr4181/common/irq.c
--- a/arch/mips/vr4181/common/irq.c	2005-03-01 23:39:16 -08:00
+++ b/arch/mips/vr4181/common/irq.c	2005-03-01 23:39:16 -08:00
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2001 MontaVista Software Inc.
  * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ * Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org)
  *
  * linux/arch/mips/vr4181/common/irq.c
  *	Completely re-written to use the new irq.c
@@ -12,7 +13,6 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  */
-#include <linux/config.h>
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/kernel_stat.h>
diff -Nru a/arch/mips/vr4181/common/time.c b/arch/mips/vr4181/common/time.c
--- a/arch/mips/vr4181/common/time.c	2005-03-01 23:38:58 -08:00
+++ b/arch/mips/vr4181/common/time.c	2005-03-01 23:38:58 -08:00
@@ -29,7 +29,7 @@
  * RTC ops
  */
 
-spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(rtc_lock);
 
 /* per VR41xx docs, bad data can be read if between 2 counts */
 static inline unsigned short
diff -Nru a/arch/mips/vr4181/osprey/setup.c b/arch/mips/vr4181/osprey/setup.c
--- a/arch/mips/vr4181/osprey/setup.c	2005-03-01 23:39:18 -08:00
+++ b/arch/mips/vr4181/osprey/setup.c	2005-03-01 23:39:18 -08:00
@@ -8,6 +8,7 @@
  *
  * Copyright 2001 MontaVista Software Inc.
  * Author: jsun@mvista.com or jsun@junsun.net
+ * Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.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 archive
@@ -15,7 +16,6 @@
  *
  */
 
-#include <linux/config.h>
 #include <linux/ide.h>
 #include <linux/init.h>
 #include <linux/delay.h>
diff -Nru a/arch/mips/vr41xx/common/bcu.c b/arch/mips/vr41xx/common/bcu.c
--- a/arch/mips/vr41xx/common/bcu.c	2005-03-01 23:39:10 -08:00
+++ b/arch/mips/vr41xx/common/bcu.c	2005-03-01 23:39:10 -08:00
@@ -30,6 +30,7 @@
  */
 #include <linux/init.h>
 #include <linux/ioport.h>
+#include <linux/kernel.h>
 #include <linux/smp.h>
 #include <linux/types.h>
 
diff -Nru a/arch/mips/vr41xx/common/giu.c b/arch/mips/vr41xx/common/giu.c
--- a/arch/mips/vr41xx/common/giu.c	2005-03-01 23:38:52 -08:00
+++ b/arch/mips/vr41xx/common/giu.c	2005-03-01 23:38:52 -08:00
@@ -4,6 +4,7 @@
  *  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
@@ -28,7 +29,6 @@
  *  - Added support for NEC VR4133.
  *  - Removed board_irq_init.
  */
-#include <linux/config.h>
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/irq.h>
diff -Nru a/arch/mips/vr41xx/common/icu.c b/arch/mips/vr41xx/common/icu.c
--- a/arch/mips/vr41xx/common/icu.c	2005-03-01 23:38:44 -08:00
+++ b/arch/mips/vr41xx/common/icu.c	2005-03-01 23:38:44 -08:00
@@ -4,6 +4,7 @@
  *  Copyright (C) 2001-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
@@ -28,7 +29,6 @@
  *  Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
  *  - Coped with INTASSIGN of NEC VR4133.
  */
-#include <linux/config.h>
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
diff -Nru a/arch/mips/vr41xx/common/ksyms.c b/arch/mips/vr41xx/common/ksyms.c
--- a/arch/mips/vr41xx/common/ksyms.c	2005-03-01 23:38:53 -08:00
+++ b/arch/mips/vr41xx/common/ksyms.c	2005-03-01 23:38:53 -08:00
@@ -2,6 +2,7 @@
  *   ksyms.c, Export NEC VR4100 series specific functions needed for loadable modules.
  *
  *  Copyright (C) 2003  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
@@ -17,7 +18,6 @@
  *  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 <asm/vr41xx/vr41xx.h>
diff -Nru a/arch/mips/vr41xx/common/pmu.c b/arch/mips/vr41xx/common/pmu.c
--- a/arch/mips/vr41xx/common/pmu.c	2005-03-01 23:39:08 -08:00
+++ b/arch/mips/vr41xx/common/pmu.c	2005-03-01 23:39:08 -08:00
@@ -18,6 +18,7 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 #include <linux/init.h>
+#include <linux/kernel.h>
 #include <linux/smp.h>
 #include <linux/types.h>
 
diff -Nru a/arch/mips/vr41xx/common/vrc4173.c b/arch/mips/vr41xx/common/vrc4173.c
--- a/arch/mips/vr41xx/common/vrc4173.c	2005-03-01 23:39:07 -08:00
+++ b/arch/mips/vr41xx/common/vrc4173.c	2005-03-01 23:39:07 -08:00
@@ -4,6 +4,7 @@
  *  Copyright (C) 2001-2003  MontaVista Software Inc.
  *    Author: Yoichi Yuasa <yyuasa@mvista.com, or source@mvista.com>
  *  Copyright (C) 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
@@ -19,7 +20,6 @@
  *  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/init.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
diff -Nru a/arch/mips/vr41xx/nec-cmbvr4133/Makefile b/arch/mips/vr41xx/nec-cmbvr4133/Makefile
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/mips/vr41xx/nec-cmbvr4133/Makefile	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,8 @@
+#
+# Makefile for the NEC-CMBVR4133
+#
+
+obj-y				:= init.o setup.o
+
+obj-$(CONFIG_PCI)		+= m1535plus.o
+obj-$(CONFIG_ROCKHOPPER)	+= irq.o
diff -Nru a/arch/mips/vr41xx/nec-cmbvr4133/init.c b/arch/mips/vr41xx/nec-cmbvr4133/init.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/mips/vr41xx/nec-cmbvr4133/init.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,78 @@
+/*
+ * arch/mips/vr41xx/nec-cmbvr4133/init.c
+ *
+ * PROM library initialisation code for NEC CMB-VR4133 board.
+ *
+ * Author: Yoichi Yuasa <yyuasa@mvista.com, or source@mvista.com> and
+ *         Jun Sun <jsun@mvista.com, or source@mvista.com> and
+ *         Alex Sapkov <asapkov@ru.mvista.com>
+ *
+ * 2001-2004 (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.
+ *
+ * Support for NEC-CMBVR4133 in 2.6
+ * Manish Lachwani (mlachwani@mvista.com)
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+
+#include <asm/bootinfo.h>
+
+#ifdef CONFIG_ROCKHOPPER
+#include <asm/io.h>
+#include <linux/pci.h>
+
+#define PCICONFDREG	0xaf000c14
+#define PCICONFAREG	0xaf000c18
+#endif
+
+const char *get_system_type(void)
+{
+	return "NEC CMB-VR4133";
+}
+
+#ifdef CONFIG_ROCKHOPPER
+void disable_pcnet(void)
+{
+	u32 data;
+
+	/*
+	 * Workaround for the bug in PMON on VR4133. PMON leaves
+	 * AMD PCNet controller (on Rockhopper) initialized and running in
+	 * bus master mode. We have do disable it before doing any
+	 * further initialization. Or we get problems with PCI bus 2
+	 * and random lockups and crashes.
+	 */
+
+	writel((2 << 16)		|
+	       (PCI_DEVFN(1,0) << 8)	|
+	       (0 & 0xfc)		|
+               1UL,
+	       PCICONFAREG);
+
+	data = readl(PCICONFDREG);
+
+	writel((2 << 16)		|
+	       (PCI_DEVFN(1,0) << 8)	|
+	       (4 & 0xfc)		|
+               1UL,
+	       PCICONFAREG);
+
+	data = readl(PCICONFDREG);
+
+	writel((2 << 16)		|
+	       (PCI_DEVFN(1,0) << 8)	|
+	       (4 & 0xfc)		|
+               1UL,
+	       PCICONFAREG);
+
+	data &= ~4;
+
+	writel(data, PCICONFDREG);
+}
+#endif
+
diff -Nru a/arch/mips/vr41xx/nec-cmbvr4133/irq.c b/arch/mips/vr41xx/nec-cmbvr4133/irq.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/mips/vr41xx/nec-cmbvr4133/irq.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,114 @@
+/*
+ * arch/mips/vr41xx/nec-cmbvr4133/irq.c
+ *
+ * Interrupt routines for the NEC CMB-VR4133 board.
+ *
+ * Author: Yoichi Yuasa <yyuasa@mvista.com, or source@mvista.com> and
+ *         Alex Sapkov <asapkov@ru.mvista.com>
+ *
+ * 2003-2004 (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.
+ *
+ * Support for NEC-CMBVR4133 in 2.6
+ * Manish Lachwani (mlachwani@mvista.com)
+ */
+#include <linux/bitops.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+
+#include <asm/io.h>
+#include <asm/vr41xx/cmbvr4133.h>
+
+extern void enable_8259A_irq(unsigned int irq);
+extern void disable_8259A_irq(unsigned int irq);
+extern void mask_and_ack_8259A(unsigned int irq);
+extern void init_8259A(int hoge);
+
+extern int vr4133_rockhopper;
+
+static unsigned int startup_i8259_irq(unsigned int irq)
+{
+	enable_8259A_irq(irq - I8259_IRQ_BASE);
+	return 0;
+}
+
+static void shutdown_i8259_irq(unsigned int irq)
+{
+	disable_8259A_irq(irq - I8259_IRQ_BASE);
+}
+
+static void enable_i8259_irq(unsigned int irq)
+{
+	enable_8259A_irq(irq - I8259_IRQ_BASE);
+}
+
+static void disable_i8259_irq(unsigned int irq)
+{
+	disable_8259A_irq(irq - I8259_IRQ_BASE);
+}
+
+static void ack_i8259_irq(unsigned int irq)
+{
+	mask_and_ack_8259A(irq - I8259_IRQ_BASE);
+}
+
+static void end_i8259_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_8259A_irq(irq - I8259_IRQ_BASE);
+}
+
+static struct hw_interrupt_type i8259_irq_type = {
+	.typename       = "XT-PIC",
+	.startup        = startup_i8259_irq,
+	.shutdown       = shutdown_i8259_irq,
+	.enable         = enable_i8259_irq,
+	.disable        = disable_i8259_irq,
+	.ack            = ack_i8259_irq,
+	.end            = end_i8259_irq,
+};
+
+static int i8259_get_irq_number(int irq)
+{
+	unsigned long isr;
+
+	isr = inb(0x20);
+	irq = ffz(~isr);
+	if (irq == 2) {
+		isr = inb(0xa0);
+		irq = 8 + ffz(~isr);
+	}
+
+	if (irq < 0 || irq > 15)
+		return -EINVAL;
+
+	return I8259_IRQ_BASE + irq;
+}
+
+static struct irqaction i8259_slave_cascade = {
+	.handler        = &no_action,
+	.name           = "cascade",
+};
+
+void __init rockhopper_init_irq(void)
+{
+	int i;
+
+	if(!vr4133_rockhopper) {
+		printk(KERN_ERR "Not a Rockhopper Board \n");
+		return;
+	}
+
+	for (i = I8259_IRQ_BASE; i <= I8259_IRQ_LAST; i++)
+		irq_desc[i].handler = &i8259_irq_type;
+
+	setup_irq(I8259_SLAVE_IRQ, &i8259_slave_cascade);
+
+	vr41xx_set_irq_trigger(CMBVR41XX_INTC_PIN, TRIGGER_LEVEL, SIGNAL_THROUGH);
+	vr41xx_set_irq_level(CMBVR41XX_INTC_PIN, LEVEL_HIGH);
+	vr41xx_cascade_irq(CMBVR41XX_INTC_IRQ, i8259_get_irq_number);
+}
diff -Nru a/arch/mips/vr41xx/nec-cmbvr4133/m1535plus.c b/arch/mips/vr41xx/nec-cmbvr4133/m1535plus.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/mips/vr41xx/nec-cmbvr4133/m1535plus.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,250 @@
+/*
+ * arch/mips/vr41xx/nec-cmbvr4133/m1535plus.c
+ *
+ * Initialize for ALi M1535+(included M5229 and M5237).
+ *
+ * Author: Yoichi Yuasa <yyuasa@mvista.com, or source@mvista.com> and
+ *         Alex Sapkov <asapkov@ru.mvista.com>
+ *
+ * 2003-2004 (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.
+ *
+ * Support for NEC-CMBVR4133 in 2.6
+ * Author: Manish Lachwani (mlachwani@mvista.com)
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/serial.h>
+
+#include <asm/vr41xx/cmbvr4133.h>
+#include <linux/pci.h>
+#include <asm/io.h>
+
+#define CONFIG_PORT(port)	((port) ? 0x3f0 : 0x370)
+#define DATA_PORT(port)		((port) ? 0x3f1 : 0x371)
+#define INDEX_PORT(port)	CONFIG_PORT(port)
+
+#define ENTER_CONFIG_MODE(port)				\
+	do {						\
+		outb_p(0x51, CONFIG_PORT(port));	\
+		outb_p(0x23, CONFIG_PORT(port));	\
+	} while(0)
+
+#define SELECT_LOGICAL_DEVICE(port, dev_no)		\
+	do {						\
+		outb_p(0x07, INDEX_PORT(port));		\
+		outb_p((dev_no), DATA_PORT(port));	\
+	} while(0)
+
+#define WRITE_CONFIG_DATA(port,index,data)		\
+	do {						\
+		outb_p((index), INDEX_PORT(port));	\
+		outb_p((data), DATA_PORT(port));	\
+	} while(0)
+
+#define EXIT_CONFIG_MODE(port)	outb(0xbb, CONFIG_PORT(port))
+
+#define PCI_CONFIG_ADDR	KSEG1ADDR(0x0f000c18)
+#define PCI_CONFIG_DATA	KSEG1ADDR(0x0f000c14)
+
+#ifdef CONFIG_BLK_DEV_FD
+
+void __devinit ali_m1535plus_fdc_init(int port)
+{
+	ENTER_CONFIG_MODE(port);
+	SELECT_LOGICAL_DEVICE(port, 0);		/* FDC */
+	WRITE_CONFIG_DATA(port, 0x30, 0x01);	/* FDC: enable */
+	WRITE_CONFIG_DATA(port, 0x60, 0x03);	/* I/O port base: 0x3f0 */
+	WRITE_CONFIG_DATA(port, 0x61, 0xf0);
+	WRITE_CONFIG_DATA(port, 0x70, 0x06);	/* IRQ: 6 */
+	WRITE_CONFIG_DATA(port, 0x74, 0x02);	/* DMA: channel 2 */
+	WRITE_CONFIG_DATA(port, 0xf0, 0x08);
+	WRITE_CONFIG_DATA(port, 0xf1, 0x00);
+	WRITE_CONFIG_DATA(port, 0xf2, 0xff);
+	WRITE_CONFIG_DATA(port, 0xf4, 0x00);
+	EXIT_CONFIG_MODE(port);
+}
+
+#endif
+
+void __devinit ali_m1535plus_parport_init(int port)
+{
+	ENTER_CONFIG_MODE(port);
+	SELECT_LOGICAL_DEVICE(port, 3);		/* Parallel Port */
+	WRITE_CONFIG_DATA(port, 0x30, 0x01);
+	WRITE_CONFIG_DATA(port, 0x60, 0x03);	/* I/O port base: 0x378 */
+	WRITE_CONFIG_DATA(port, 0x61, 0x78);
+	WRITE_CONFIG_DATA(port, 0x70, 0x07);	/* IRQ: 7 */
+	WRITE_CONFIG_DATA(port, 0x74, 0x04);	/* DMA: None */
+	WRITE_CONFIG_DATA(port, 0xf0, 0x8c);	/* IRQ polarity: Active Low */
+	WRITE_CONFIG_DATA(port, 0xf1, 0xc5);
+	EXIT_CONFIG_MODE(port);
+}
+
+void __devinit ali_m1535plus_keyboard_init(int port)
+{
+	ENTER_CONFIG_MODE(port);
+	SELECT_LOGICAL_DEVICE(port, 7);		/* KEYBOARD */
+	WRITE_CONFIG_DATA(port, 0x30, 0x01);	/* KEYBOARD: eable */
+	WRITE_CONFIG_DATA(port, 0x70, 0x01);	/* IRQ: 1 */
+	WRITE_CONFIG_DATA(port, 0x72, 0x0c);	/* PS/2 Mouse IRQ: 12 */
+	WRITE_CONFIG_DATA(port, 0xf0, 0x00);
+	EXIT_CONFIG_MODE(port);
+}
+
+void __devinit ali_m1535plus_hotkey_init(int port)
+{
+	ENTER_CONFIG_MODE(port);
+	SELECT_LOGICAL_DEVICE(port, 0xc);	/* HOTKEY */
+	WRITE_CONFIG_DATA(port, 0x30, 0x00);
+	WRITE_CONFIG_DATA(port, 0xf0, 0x35);
+	WRITE_CONFIG_DATA(port, 0xf1, 0x14);
+	WRITE_CONFIG_DATA(port, 0xf2, 0x11);
+	WRITE_CONFIG_DATA(port, 0xf3, 0x71);
+	WRITE_CONFIG_DATA(port, 0xf5, 0x05);
+	EXIT_CONFIG_MODE(port);
+}
+
+void ali_m1535plus_init(struct pci_dev *dev)
+{
+	pci_write_config_byte(dev, 0x40, 0x18); /* PCI Interface Control */
+	pci_write_config_byte(dev, 0x41, 0xc0); /* PS2 keyb & mouse enable */
+	pci_write_config_byte(dev, 0x42, 0x41); /* ISA bus cycle control */
+	pci_write_config_byte(dev, 0x43, 0x00); /* ISA bus cycle control 2 */
+	pci_write_config_byte(dev, 0x44, 0x5d); /* IDE enable & IRQ 14 */
+	pci_write_config_byte(dev, 0x45, 0x0b); /* PCI int polling mode */
+	pci_write_config_byte(dev, 0x47, 0x00); /* BIOS chip select control */
+
+	/* IRQ routing */
+	pci_write_config_byte(dev, 0x48, 0x03); /* INTA IRQ10, INTB disable */
+	pci_write_config_byte(dev, 0x49, 0x00); /* INTC and INTD disable */
+	pci_write_config_byte(dev, 0x4a, 0x00); /* INTE and INTF disable */
+	pci_write_config_byte(dev, 0x4b, 0x90); /* Audio IRQ11, Modem disable */
+
+	pci_write_config_word(dev, 0x50, 0x4000); /* Parity check IDE enable */
+	pci_write_config_word(dev, 0x52, 0x0000); /* USB & RTC disable */
+	pci_write_config_word(dev, 0x54, 0x0002); /* ??? no info */
+	pci_write_config_word(dev, 0x56, 0x0002); /* PCS1J signal disable */
+
+	pci_write_config_byte(dev, 0x59, 0x00); /* PCSDS */
+	pci_write_config_byte(dev, 0x5a, 0x00);
+	pci_write_config_byte(dev, 0x5b, 0x00);
+	pci_write_config_word(dev, 0x5c, 0x0000);
+	pci_write_config_byte(dev, 0x5e, 0x00);
+	pci_write_config_byte(dev, 0x5f, 0x00);
+	pci_write_config_word(dev, 0x60, 0x0000);
+
+	pci_write_config_byte(dev, 0x6c, 0x00);
+	pci_write_config_byte(dev, 0x6d, 0x48); /* ROM address mapping */
+	pci_write_config_byte(dev, 0x6e, 0x00); /* ??? what for? */
+
+	pci_write_config_byte(dev, 0x70, 0x12); /* Serial IRQ control */
+	pci_write_config_byte(dev, 0x71, 0xEF); /* DMA channel select */
+	pci_write_config_byte(dev, 0x72, 0x03); /* USB IDSEL */
+	pci_write_config_byte(dev, 0x73, 0x00); /* ??? no info */
+
+	/*
+	 * IRQ setup ALi M5237 USB Host Controller
+	 * IRQ: 9
+	 */
+	pci_write_config_byte(dev, 0x74, 0x01); /* USB IRQ9 */
+
+	pci_write_config_byte(dev, 0x75, 0x1f); /* IDE2 IRQ 15  */
+	pci_write_config_byte(dev, 0x76, 0x80); /* ACPI disable */
+	pci_write_config_byte(dev, 0x77, 0x40); /* Modem disable */
+	pci_write_config_dword(dev, 0x78, 0x20000000); /* Pin select 2 */
+	pci_write_config_byte(dev, 0x7c, 0x00); /* Pin select 3 */
+	pci_write_config_byte(dev, 0x81, 0x00); /* ID read/write control */
+	pci_write_config_byte(dev, 0x90, 0x00); /* PCI PM block control */
+	pci_write_config_word(dev, 0xa4, 0x0000); /* PMSCR */
+
+#ifdef CONFIG_BLK_DEV_FD
+	ali_m1535plus_fdc_init(1);
+#endif
+
+	ali_m1535plus_keyboard_init(1);
+	ali_m1535plus_hotkey_init(1);
+}
+
+static inline void ali_config_writeb(u8 reg, u8 val, int devfn)
+{
+	u32 data;
+	int shift;
+
+	writel((1 << 16) | (devfn << 8) | (reg & 0xfc) | 1UL, PCI_CONFIG_ADDR);
+        data = readl(PCI_CONFIG_DATA);
+
+	shift = (reg & 3) << 3;
+	data &= ~(0xff << shift);
+	data |= (((u32)val) << shift);
+
+	writel(data, PCI_CONFIG_DATA);
+}
+
+static inline u8 ali_config_readb(u8 reg, int devfn)
+{
+	u32 data;
+
+	writel((1 << 16) | (devfn << 8) | (reg & 0xfc) | 1UL, PCI_CONFIG_ADDR);
+	data = readl(PCI_CONFIG_DATA);
+
+	return (u8)(data >> ((reg & 3) << 3));
+}
+
+static inline u16 ali_config_readw(u8 reg, int devfn)
+{
+	u32 data;
+
+	writel((1 << 16) | (devfn << 8) | (reg & 0xfc) | 1UL, PCI_CONFIG_ADDR);
+	data = readl(PCI_CONFIG_DATA);
+
+	return (u16)(data >> ((reg & 2) << 3));
+}
+
+int vr4133_rockhopper = 0;
+void __init ali_m5229_preinit(void)
+{
+	if (ali_config_readw(PCI_VENDOR_ID,16) == PCI_VENDOR_ID_AL &&
+	    ali_config_readw(PCI_DEVICE_ID,16) == PCI_DEVICE_ID_AL_M1533) {
+		printk(KERN_INFO "Found an NEC Rockhopper \n");
+		vr4133_rockhopper = 1;
+		/*
+		 * Enable ALi M5229 IDE Controller (both channels)
+		 * IDSEL: A27
+		 */
+		ali_config_writeb(0x58, 0x4c, 16);
+	}
+}
+
+void __init ali_m5229_init(struct pci_dev *dev)
+{
+	/*
+	 * Enable Primary/Secondary Channel Cable Detect 40-Pin
+	 */
+	pci_write_config_word(dev, 0x4a, 0xc023);
+
+	/*
+	 * Set only the 3rd byteis for the master IDE's cycle and
+	 * enable Internal IDE Function
+	 */
+	pci_write_config_byte(dev, 0x50, 0x23); /* Class code attr register */
+
+	pci_write_config_byte(dev, 0x09, 0xff); /* Set native mode & stuff */
+	pci_write_config_byte(dev, 0x52, 0x00); /* use timing registers */
+	pci_write_config_byte(dev, 0x58, 0x02); /* Primary addr setup timing */
+	pci_write_config_byte(dev, 0x59, 0x22); /* Primary cmd block timing */
+	pci_write_config_byte(dev, 0x5a, 0x22); /* Pr drv 0 R/W timing */
+	pci_write_config_byte(dev, 0x5b, 0x22); /* Pr drv 1 R/W timing */
+	pci_write_config_byte(dev, 0x5c, 0x02); /* Sec addr setup timing */
+	pci_write_config_byte(dev, 0x5d, 0x22); /* Sec cmd block timing */
+	pci_write_config_byte(dev, 0x5e, 0x22); /* Sec drv 0 R/W timing */
+	pci_write_config_byte(dev, 0x5f, 0x22); /* Sec drv 1 R/W timing */
+	pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x20);
+	pci_write_config_word(dev, PCI_COMMAND,
+	                           PCI_COMMAND_PARITY | PCI_COMMAND_MASTER |
+				   PCI_COMMAND_IO);
+}
+
diff -Nru a/arch/mips/vr41xx/nec-cmbvr4133/setup.c b/arch/mips/vr41xx/nec-cmbvr4133/setup.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/mips/vr41xx/nec-cmbvr4133/setup.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,108 @@
+/*
+ * arch/mips/vr41xx/nec-cmbvr4133/setup.c
+ *
+ * Setup for the NEC CMB-VR4133.
+ *
+ * Author: Yoichi Yuasa <yyuasa@mvista.com, or source@mvista.com> and
+ *         Alex Sapkov <asapkov@ru.mvista.com>
+ *
+ * 2001-2004 (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.
+ *
+ * Support for CMBVR4133 board in 2.6
+ * Author: Manish Lachwani (mlachwani@mvista.com)
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/ide.h>
+#include <linux/ioport.h>
+
+#include <asm/reboot.h>
+#include <asm/time.h>
+#include <asm/vr41xx/cmbvr4133.h>
+#include <asm/bootinfo.h>
+
+#ifdef CONFIG_MTD
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+
+static struct mtd_partition cmbvr4133_mtd_parts[] = {
+	{
+		.name =		"User FS",
+		.size =		0x1be0000,
+		.offset =	0,
+		.mask_flags = 	0,
+	},
+	{
+		.name =		"PMON",
+		.size =		0x140000,
+		.offset =	MTDPART_OFS_APPEND,
+		.mask_flags =	MTD_WRITEABLE,  /* force read-only */
+	},
+	{
+		.name =		"User FS2",
+		.size =		MTDPART_SIZ_FULL,
+		.offset =	MTDPART_OFS_APPEND,
+		.mask_flags = 	0,
+	}
+};
+
+#define number_partitions (sizeof(cmbvr4133_mtd_parts)/sizeof(struct mtd_partition))
+#endif
+
+extern void (*late_time_init)(void);
+
+static void __init vr4133_serial_init(void)
+{
+	vr41xx_select_siu_interface(SIU_RS232C, IRDA_NONE);
+	vr41xx_siu_init();
+	vr41xx_dsiu_init();
+}
+
+extern void i8259_init(void);
+
+static int __init nec_cmbvr4133_setup(void)
+{
+#ifdef CONFIG_ROCKHOPPER
+	extern void disable_pcnet(void);
+
+	disable_pcnet();
+#endif
+	set_io_port_base(KSEG1ADDR(0x16000000));
+
+	mips_machgroup = MACH_GROUP_NEC_VR41XX;
+	mips_machtype = MACH_NEC_CMBVR4133;
+
+	late_time_init = vr4133_serial_init;
+
+#ifdef CONFIG_PCI
+#ifdef CONFIG_ROCKHOPPER
+	ali_m5229_preinit();
+#endif
+#endif
+
+#ifdef CONFIG_ROCKHOPPER
+	rockhopper_init_irq();
+#endif
+
+#ifdef CONFIG_MTD
+	/* we use generic physmap mapping driver and we use partitions */
+	physmap_configure(0x1C000000, 0x02000000, 4, NULL);
+	physmap_set_partitions(cmbvr4133_mtd_parts, number_partitions);
+#endif
+
+	/* 128 MB memory support */
+	add_memory_region(0, 0x08000000, BOOT_MEM_RAM);
+
+#ifdef CONFIG_ROCKHOPPER
+	i8259_init();
+#endif
+	return 0;
+}
+
+early_initcall(nec_cmbvr4133_setup);
diff -Nru a/arch/parisc/Kconfig b/arch/parisc/Kconfig
--- a/arch/parisc/Kconfig	2005-03-01 23:38:59 -08:00
+++ b/arch/parisc/Kconfig	2005-03-01 23:38:59 -08:00
@@ -32,8 +32,18 @@
 config RWSEM_XCHGADD_ALGORITHM
 	bool
 
+config GENERIC_CALIBRATE_DELAY
+	bool
+	default y
+
 config GENERIC_ISA_DMA
 	bool
+
+config GENERIC_HARDIRQS
+	def_bool y
+
+config GENERIC_IRQ_PROBE
+	def_bool y
 
 # unless you want to implement ACPI on PA-RISC ... ;-)
 config PM
diff -Nru a/arch/parisc/configs/712_defconfig b/arch/parisc/configs/712_defconfig
--- a/arch/parisc/configs/712_defconfig	2005-03-01 23:39:17 -08:00
+++ b/arch/parisc/configs/712_defconfig	2005-03-01 23:39:17 -08:00
@@ -1,5 +1,7 @@
 #
 # Automatically generated make config: don't edit
+# Linux kernel version: 2.6.10-pa5
+# Wed Jan  5 13:20:32 2005
 #
 CONFIG_PARISC=y
 CONFIG_MMU=y
@@ -9,37 +11,50 @@
 #
 # Code maturity level options
 #
-# CONFIG_EXPERIMENTAL is not set
-CONFIG_CLEAN_COMPILE=y
-CONFIG_STANDALONE=y
+CONFIG_EXPERIMENTAL=y
+# CONFIG_CLEAN_COMPILE is not set
+CONFIG_BROKEN=y
 CONFIG_BROKEN_ON_SMP=y
 
 #
 # 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_LOG_BUF_SHIFT=15
-# CONFIG_HOTPLUG is not set
-# CONFIG_IKCONFIG is not set
+# CONFIG_AUDIT is not set
+CONFIG_LOG_BUF_SHIFT=16
+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=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=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_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
 CONFIG_OBSOLETE_MODPARM=y
-# CONFIG_KMOD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
 
 #
 # Processor type and features
@@ -47,10 +62,12 @@
 # CONFIG_PA7000 is not set
 CONFIG_PA7100LC=y
 # CONFIG_PA7200 is not set
+# CONFIG_PA7300LC is not set
 # CONFIG_PA8X00 is not set
 CONFIG_PA11=y
 # CONFIG_64BIT is not set
 # CONFIG_SMP is not set
+# CONFIG_DISCONTIGMEM is not set
 # CONFIG_PREEMPT is not set
 # CONFIG_HPUX is not set
 
@@ -61,17 +78,30 @@
 # CONFIG_HPPB is not set
 # CONFIG_IOMMU_CCIO is not set
 CONFIG_GSC_LASI=y
-CONFIG_GSC_WAX=y
+# CONFIG_GSC_WAX is not set
 # CONFIG_EISA is not set
 # CONFIG_PCI is not set
-# CONFIG_CHASSIS_LCD_LED is not set
+CONFIG_CHASSIS_LCD_LED=y
 # CONFIG_PDC_CHASSIS is not set
 
 #
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# PCI Hotplug Support
+#
+
+#
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_MISC is not set
+CONFIG_BINFMT_MISC=m
 
 #
 # Device Drivers
@@ -80,7 +110,10 @@
 #
 # Generic Driver Options
 #
-CONFIG_DEBUG_DRIVER=y
+# CONFIG_STANDALONE is not set
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+CONFIG_FW_LOADER=y
+# CONFIG_DEBUG_DRIVER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -91,9 +124,10 @@
 # Parallel port support
 #
 CONFIG_PARPORT=y
-CONFIG_PARPORT_PC=y
-CONFIG_PARPORT_PC_CML1=y
-# CONFIG_PARPORT_SERIAL is not set
+CONFIG_PARPORT_PC=m
+CONFIG_PARPORT_PC_CML1=m
+# CONFIG_PARPORT_PC_FIFO is not set
+# CONFIG_PARPORT_PC_SUPERIO is not set
 CONFIG_PARPORT_GSC=y
 # CONFIG_PARPORT_OTHER is not set
 # CONFIG_PARPORT_1284 is not set
@@ -110,7 +144,20 @@
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_CRYPTOLOOP=y
 # CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=6144
+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
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -137,7 +184,6 @@
 # Some SCSI devices (e.g. CD jukebox) support multiple LUNs
 #
 # CONFIG_SCSI_MULTI_LUN is not set
-# CONFIG_SCSI_REPORT_LUNS is not set
 # CONFIG_SCSI_CONSTANTS is not set
 # CONFIG_SCSI_LOGGING is not set
 
@@ -145,31 +191,33 @@
 # SCSI Transport Attributes
 #
 CONFIG_SCSI_SPI_ATTRS=y
-CONFIG_SCSI_FC_ATTRS=y
+# CONFIG_SCSI_FC_ATTRS is not set
 
 #
 # SCSI low-level drivers
 #
-# CONFIG_SCSI_AIC7XXX_OLD is not set
-# CONFIG_SCSI_EATA_PIO is not set
+# CONFIG_SCSI_SATA is not set
 # CONFIG_SCSI_PPA is not set
 # CONFIG_SCSI_IMM is not set
 CONFIG_SCSI_LASI700=y
 CONFIG_53C700_MEM_MAPPED=y
 CONFIG_53C700_LE_ON_BE=y
 # CONFIG_SCSI_ZALON is not set
-# CONFIG_SCSI_DEBUG is not set
+CONFIG_SCSI_DEBUG=m
 
 #
 # Multi-device support (RAID and LVM)
 #
 CONFIG_MD=y
-CONFIG_BLK_DEV_MD=y
-CONFIG_MD_LINEAR=y
-CONFIG_MD_RAID0=y
-CONFIG_MD_RAID1=y
-CONFIG_MD_RAID5=y
+CONFIG_BLK_DEV_MD=m
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+# CONFIG_MD_RAID10 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_RAID6 is not set
 # CONFIG_MD_MULTIPATH is not set
+# CONFIG_MD_FAULTY is not set
 # CONFIG_BLK_DEV_DM is not set
 
 #
@@ -197,49 +245,151 @@
 CONFIG_PACKET_MMAP=y
 CONFIG_NETLINK_DEV=y
 CONFIG_UNIX=y
-# CONFIG_NET_KEY is not set
+CONFIG_NET_KEY=m
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
 # CONFIG_IP_ADVANCED_ROUTER is not set
 CONFIG_IP_PNP=y
-# CONFIG_IP_PNP_DHCP is not set
+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 is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
 # CONFIG_INET_IPCOMP is not set
-# CONFIG_DECNET is not set
+CONFIG_INET_TUNNEL=m
+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 is not set
+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 is not set
+# CONFIG_IP_NF_MATCH_REALM is not set
+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_LOCAL is not set
+CONFIG_IP_NF_NAT_SNMP_BASIC=m
+CONFIG_IP_NF_NAT_IRC=m
+CONFIG_IP_NF_NAT_FTP=m
+CONFIG_IP_NF_NAT_TFTP=m
+CONFIG_IP_NF_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_IP_NF_COMPAT_IPCHAINS is not set
+# CONFIG_IP_NF_COMPAT_IPFWADM is not set
+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_NETFILTER is not set
 # CONFIG_VLAN_8021Q is not set
-# CONFIG_LLC2 is not set
+# CONFIG_DECNET is not set
+CONFIG_LLC=m
+CONFIG_LLC2=m
 # 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_NET_PKTGEN=m
+# 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_DUMMY=m
+CONFIG_BONDING=m
 # CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
+CONFIG_TUN=m
+# CONFIG_ETHERTAP is not set
 
 #
 # Ethernet (10 or 100Mbit)
 #
 CONFIG_NET_ETHERNET=y
-# CONFIG_MII is not set
+CONFIG_MII=m
 CONFIG_LASI_82596=y
 
 #
@@ -249,14 +399,10 @@
 #
 # Ethernet (10000 Mbit)
 #
-# CONFIG_PLIP is not set
-CONFIG_PPP=y
-# CONFIG_PPP_FILTER is not set
-# CONFIG_PPP_ASYNC is not set
-# CONFIG_PPP_SYNC_TTY is not set
-# CONFIG_PPP_DEFLATE is not set
-# CONFIG_PPP_BSDCOMP is not set
-# CONFIG_SLIP is not set
+
+#
+# Token Ring devices
+#
 
 #
 # Wireless LAN (non-hamradio)
@@ -267,32 +413,24 @@
 # Obsolete Wireless cards support (pre-802.11)
 #
 # CONFIG_STRIP is not set
-
-#
-# Token Ring devices
-#
+# CONFIG_ATMEL is not set
 
 #
 # Wan interfaces
 #
 # CONFIG_WAN is not set
-
-#
-# Amateur Radio support
-#
-# CONFIG_HAMRADIO is not set
-
-#
-# IrDA (infrared) support
-#
-# CONFIG_IRDA is not set
-
-#
-# Bluetooth support
-#
-# CONFIG_BT is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_PLIP is not set
+CONFIG_PPP=m
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPPOE=m
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
 
 #
 # ISDN subsystem
@@ -318,7 +456,7 @@
 CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 # CONFIG_INPUT_JOYDEV is not set
 # CONFIG_INPUT_TSDEV is not set
-CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVDEV is not set
 # CONFIG_INPUT_EVBUG is not set
 
 #
@@ -327,33 +465,33 @@
 # CONFIG_GAMEPORT is not set
 CONFIG_SOUND_GAMEPORT=y
 CONFIG_SERIO=y
-# CONFIG_SERIO_SERPORT is not set
+CONFIG_SERIO_SERPORT=y
 # CONFIG_SERIO_PARKBD is not set
 CONFIG_SERIO_GSCPS2=y
-# CONFIG_HP_SDC is not set
+CONFIG_HP_SDC=y
+CONFIG_HIL_MLC=y
+# CONFIG_SERIO_RAW is not set
 
 #
 # Input Device Drivers
 #
 CONFIG_INPUT_KEYBOARD=y
-# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_ATKBD=y
+CONFIG_KEYBOARD_ATKBD_HP_KEYCODES=y
+# CONFIG_KEYBOARD_ATKBD_RDI_KEYCODES is not set
 # 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_KEYBOARD_HIL_OLD is not set
 # CONFIG_KEYBOARD_HIL is not set
 CONFIG_INPUT_MOUSE=y
-# CONFIG_MOUSE_PS2 is not set
-# CONFIG_MOUSE_SERIAL is not set
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_SERIAL=m
 # CONFIG_MOUSE_VSXXXAA is not set
-# CONFIG_MOUSE_HIL is not set
+CONFIG_MOUSE_HIL=m
 # CONFIG_INPUT_JOYSTICK is not set
 # CONFIG_INPUT_TOUCHSCREEN is not set
-CONFIG_INPUT_MISC=y
-# CONFIG_INPUT_PCSPKR is not set
-# CONFIG_INPUT_UINPUT is not set
-# CONFIG_HP_SDC_RTC is not set
+# CONFIG_INPUT_MISC is not set
 
 #
 # Character devices
@@ -368,7 +506,7 @@
 #
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_NR_UARTS=8
 CONFIG_SERIAL_8250_EXTENDED=y
 CONFIG_SERIAL_8250_MANY_PORTS=y
 CONFIG_SERIAL_8250_SHARE_IRQ=y
@@ -380,17 +518,16 @@
 # Non-8250 serial port support
 #
 # CONFIG_SERIAL_MUX is not set
-# CONFIG_PDC_CONSOLE is not set
+CONFIG_PDC_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
-CONFIG_PRINTER=y
+CONFIG_LEGACY_PTY_COUNT=64
+CONFIG_PRINTER=m
 # CONFIG_LP_CONSOLE is not set
-# CONFIG_PPDEV is not set
+CONFIG_PPDEV=m
 # CONFIG_TIPAR is not set
-# CONFIG_QIC02_TAPE is not set
 
 #
 # IPMI
@@ -402,18 +539,17 @@
 #
 # CONFIG_WATCHDOG is not set
 CONFIG_GEN_RTC=y
-# CONFIG_GEN_RTC_X is not set
+CONFIG_GEN_RTC_X=y
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
 
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_FTAPE is not set
 # CONFIG_AGP is not set
 # CONFIG_DRM is not set
-# CONFIG_RAW_DRIVER is not set
+CONFIG_RAW_DRIVER=y
+CONFIG_MAX_RAW_DEVS=256
 
 #
 # I2C support
@@ -421,6 +557,11 @@
 # CONFIG_I2C is not set
 
 #
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
 # Misc devices
 #
 
@@ -438,40 +579,86 @@
 # Graphics support
 #
 CONFIG_FB=y
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_TILEBLITTING=y
 CONFIG_FB_STI=y
 # CONFIG_FB_VIRTUAL is not set
 
 #
 # Console display driver support
 #
-# CONFIG_MDA_CONSOLE is not set
 CONFIG_STI_CONSOLE=y
-CONFIG_DUMMY_CONSOLE_COLUMNS=160
-CONFIG_DUMMY_CONSOLE_ROWS=64
+CONFIG_DUMMY_CONSOLE_COLUMNS=128
+CONFIG_DUMMY_CONSOLE_ROWS=48
 CONFIG_DUMMY_CONSOLE=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_PCI_CONSOLE=y
-# CONFIG_FONTS is not set
+CONFIG_FONTS=y
 CONFIG_FONT_8x8=y
 CONFIG_FONT_8x16=y
+# 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=y
-CONFIG_LOGO_LINUX_MONO=y
-CONFIG_LOGO_LINUX_VGA16=y
-CONFIG_LOGO_LINUX_CLUT224=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+# CONFIG_LOGO_LINUX_CLUT224 is not set
 CONFIG_LOGO_PARISC_CLUT224=y
 
 #
 # Sound
 #
-# CONFIG_SOUND is not set
+CONFIG_SOUND=y
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+CONFIG_SND_SEQUENCER=y
+# CONFIG_SND_SEQ_DUMMY is not set
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+CONFIG_SND_SEQUENCER_OSS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_VIRMIDI is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+
+#
+# GSC devices
+#
+CONFIG_SND_HARMONY=y
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME 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
@@ -479,6 +666,11 @@
 # CONFIG_USB_GADGET is not set
 
 #
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
@@ -488,13 +680,22 @@
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
 # CONFIG_REISERFS_FS is not set
-# CONFIG_JFS_FS is not set
-# CONFIG_XFS_FS is not set
+CONFIG_JFS_FS=m
+# CONFIG_JFS_POSIX_ACL is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_XFS_FS=m
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_SECURITY is not set
+# CONFIG_XFS_POSIX_ACL 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
+CONFIG_AUTOFS4_FS=y
 
 #
 # CD-ROM/DVD Filesystems
@@ -502,12 +703,17 @@
 CONFIG_ISO9660_FS=y
 CONFIG_JOLIET=y
 # CONFIG_ZISOFS is not set
-# CONFIG_UDF_FS is not set
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
 
 #
 # DOS/FAT/NT Filesystems
 #
-# CONFIG_FAT_FS is not set
+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
 
 #
@@ -515,38 +721,63 @@
 #
 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
+# CONFIG_TMPFS_SECURITY 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
+CONFIG_UFS_FS=m
+# CONFIG_UFS_FS_WRITE is not set
 
 #
 # Network File Systems
 #
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
-CONFIG_NFSD=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_DIRECTIO=y
+CONFIG_NFSD=m
 CONFIG_NFSD_V3=y
+CONFIG_NFSD_V4=y
+CONFIG_NFSD_TCP=y
 CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
-CONFIG_EXPORTFS=y
+CONFIG_EXPORTFS=m
 CONFIG_SUNRPC=y
-# CONFIG_SMB_FS is not set
-# CONFIG_CIFS is not set
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
+CONFIG_RPCSEC_GSS_SPKM3=m
+CONFIG_SMB_FS=m
+CONFIG_SMB_NLS_DEFAULT=y
+CONFIG_SMB_NLS_REMOTE="cp437"
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_XATTR is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
 
 #
 # Partition Types
@@ -559,85 +790,102 @@
 #
 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_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
+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=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
+
+#
+# Profiling support
+#
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=m
 
 #
 # Kernel hacking
 #
 CONFIG_DEBUG_KERNEL=y
-# CONFIG_DEBUG_SLAB is not set
 CONFIG_MAGIC_SYSRQ=y
-CONFIG_FRAME_POINTER=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_KOBJECT is not set
 # CONFIG_DEBUG_INFO is not set
 
 #
 # Security options
 #
-CONFIG_SECURITY=y
-# CONFIG_SECURITY_NETWORK is not set
-CONFIG_SECURITY_CAPABILITIES=y
-# CONFIG_SECURITY_SELINUX is not set
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+# 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 is not set
-# CONFIG_CRYPTO_SHA1 is not set
-# CONFIG_CRYPTO_SHA256 is not set
-# CONFIG_CRYPTO_SHA512 is not set
-# CONFIG_CRYPTO_DES is not set
-# 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_ARC4 is not set
-# CONFIG_CRYPTO_DEFLATE is not set
-# CONFIG_CRYPTO_MICHAEL_MIC is not set
-# CONFIG_CRYPTO_TEST is not set
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_TEST=m
 
 #
 # Library routines
 #
-# CONFIG_CRC32 is not set
+CONFIG_CRC_CCITT=m
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
diff -Nru a/arch/parisc/configs/a500_defconfig b/arch/parisc/configs/a500_defconfig
--- a/arch/parisc/configs/a500_defconfig	2005-03-01 23:38:53 -08:00
+++ b/arch/parisc/configs/a500_defconfig	2005-03-01 23:38:53 -08:00
@@ -1,5 +1,7 @@
 #
 # Automatically generated make config: don't edit
+# Linux kernel version: 2.6.10-pa5
+# Wed Jan  5 13:22:34 2005
 #
 CONFIG_PARISC=y
 CONFIG_MMU=y
@@ -13,10 +15,12 @@
 # CONFIG_CLEAN_COMPILE is not set
 CONFIG_BROKEN=y
 CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
 
 #
 # General setup
 #
+CONFIG_LOCALVERSION=""
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
@@ -25,6 +29,7 @@
 # CONFIG_AUDIT is not set
 CONFIG_LOG_BUF_SHIFT=16
 CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_EMBEDDED=y
@@ -33,11 +38,13 @@
 # CONFIG_KALLSYMS_EXTRA_PASS 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
@@ -47,6 +54,7 @@
 CONFIG_MODULE_FORCE_UNLOAD=y
 CONFIG_OBSOLETE_MODPARM=y
 # CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_KMOD=y
 CONFIG_STOP_MACHINE=y
 
@@ -64,10 +72,10 @@
 CONFIG_64BIT=y
 CONFIG_SMP=y
 CONFIG_HOTPLUG_CPU=y
-# CONFIG_DISCONTIGMEM is not set
+CONFIG_DISCONTIGMEM=y
 # CONFIG_PREEMPT is not set
 CONFIG_COMPAT=y
-CONFIG_NR_CPUS=4
+CONFIG_NR_CPUS=8
 
 #
 # Bus options (PCI, PCMCIA, EISA, GSC, ISA)
@@ -84,15 +92,21 @@
 CONFIG_PDC_CHASSIS=y
 
 #
-# PCMCIA/CardBus support
+# PCCARD (PCMCIA/CardBus) support
 #
+CONFIG_PCCARD=m
+# CONFIG_PCMCIA_DEBUG is not set
+# CONFIG_PCMCIA_OBSOLETE is not set
 CONFIG_PCMCIA=m
-CONFIG_PCMCIA_DEBUG=y
-CONFIG_YENTA=m
 CONFIG_CARDBUS=y
-# CONFIG_PD6729 is not set
-# CONFIG_I82092 is not set
-# CONFIG_TCIC is not set
+
+#
+# PC-card bridges
+#
+CONFIG_YENTA=m
+CONFIG_PD6729=m
+CONFIG_I82092=m
+CONFIG_TCIC=m
 
 #
 # PCI Hotplug Support
@@ -113,9 +127,9 @@
 # Generic Driver Options
 #
 # CONFIG_STANDALONE is not set
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
-CONFIG_DEBUG_DRIVER=y
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+CONFIG_FW_LOADER=y
+# CONFIG_DEBUG_DRIVER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -144,8 +158,19 @@
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=6144
 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
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -192,7 +217,8 @@
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_AIC79XX is not set
 # CONFIG_SCSI_ADVANSYS is not set
-# CONFIG_SCSI_MEGARAID 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
@@ -216,6 +242,7 @@
 CONFIG_SCSI_QLOGIC_FC=m
 # CONFIG_SCSI_QLOGIC_FC_FIRMWARE is not set
 CONFIG_SCSI_QLOGIC_1280=m
+# CONFIG_SCSI_QLOGIC_1280_1040 is not set
 CONFIG_SCSI_QLA2XXX=y
 # CONFIG_SCSI_QLA21XX is not set
 # CONFIG_SCSI_QLA22XX is not set
@@ -230,9 +257,9 @@
 #
 # PCMCIA SCSI adapter support
 #
-# CONFIG_PCMCIA_FDOMAIN is not set
-# CONFIG_PCMCIA_QLOGIC is not set
-# CONFIG_PCMCIA_SYM53C500 is not set
+CONFIG_PCMCIA_FDOMAIN=m
+CONFIG_PCMCIA_QLOGIC=m
+CONFIG_PCMCIA_SYM53C500=m
 
 #
 # Multi-device support (RAID and LVM)
@@ -242,9 +269,11 @@
 CONFIG_MD_LINEAR=y
 CONFIG_MD_RAID0=y
 CONFIG_MD_RAID1=y
+# CONFIG_MD_RAID10 is not set
 # CONFIG_MD_RAID5 is not set
 # CONFIG_MD_RAID6 is not set
 # CONFIG_MD_MULTIPATH is not set
+# CONFIG_MD_FAULTY is not set
 # CONFIG_BLK_DEV_DM is not set
 
 #
@@ -252,7 +281,6 @@
 #
 CONFIG_FUSION=m
 CONFIG_FUSION_MAX_SGE=40
-CONFIG_FUSION_ISENSE=m
 CONFIG_FUSION_CTL=m
 
 #
@@ -293,6 +321,9 @@
 CONFIG_INET_AH=m
 CONFIG_INET_ESP=m
 # CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_IP_TCPDIAG=y
+# CONFIG_IP_TCPDIAG_IPV6 is not set
 
 #
 # IP: Virtual Server Configuration
@@ -306,6 +337,9 @@
 # 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=m
 CONFIG_IP_NF_FTP=m
 CONFIG_IP_NF_IRC=m
 CONFIG_IP_NF_TFTP=m
@@ -330,15 +364,23 @@
 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=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_LOCAL is not set
 CONFIG_IP_NF_NAT_SNMP_BASIC=m
 CONFIG_IP_NF_NAT_IRC=m
 CONFIG_IP_NF_NAT_FTP=m
@@ -350,18 +392,15 @@
 CONFIG_IP_NF_TARGET_DSCP=m
 CONFIG_IP_NF_TARGET_MARK=m
 CONFIG_IP_NF_TARGET_CLASSIFY=m
-CONFIG_IP_NF_TARGET_LOG=m
-CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_IP_NF_TARGET_TCPMSS=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_IP_NF_COMPAT_IPCHAINS is not set
 # CONFIG_IP_NF_COMPAT_IPFWADM is not set
-CONFIG_IP_NF_TARGET_NOTRACK=m
-CONFIG_IP_NF_RAW=m
-# CONFIG_IP_NF_MATCH_ADDRTYPE is not set
-# CONFIG_IP_NF_MATCH_REALM is not set
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
 
@@ -382,7 +421,6 @@
 # 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
@@ -435,7 +473,7 @@
 # CONFIG_WINBOND_840 is not set
 # CONFIG_DM9102 is not set
 CONFIG_PCMCIA_XIRCOM=m
-CONFIG_PCMCIA_XIRTULIP=m
+# CONFIG_PCMCIA_XIRTULIP is not set
 CONFIG_HP100=m
 CONFIG_NET_PCI=y
 CONFIG_PCNET32=m
@@ -462,7 +500,6 @@
 # CONFIG_SUNDANCE is not set
 CONFIG_VIA_RHINE=m
 CONFIG_VIA_RHINE_MMIO=y
-# CONFIG_VIA_VELOCITY is not set
 
 #
 # Ethernet (1000 Mbit)
@@ -477,6 +514,7 @@
 # CONFIG_YELLOWFIN is not set
 # CONFIG_R8169 is not set
 # CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
 CONFIG_TIGON3=m
 
 #
@@ -501,13 +539,13 @@
 # Obsolete Wireless cards support (pre-802.11)
 #
 # CONFIG_STRIP is not set
-CONFIG_PCMCIA_WAVELAN=m
+# CONFIG_PCMCIA_WAVELAN is not set
 CONFIG_PCMCIA_NETWAVE=m
 
 #
 # Wireless 802.11 Frequency Hopping cards support
 #
-# CONFIG_PCMCIA_RAYCS is not set
+CONFIG_PCMCIA_RAYCS=m
 
 #
 # Wireless 802.11b ISA/PCI cards support
@@ -523,7 +561,7 @@
 #
 CONFIG_PCMCIA_HERMES=m
 CONFIG_AIRO_CS=m
-# CONFIG_PCMCIA_WL3501 is not set
+CONFIG_PCMCIA_WL3501=m
 
 #
 # Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
@@ -616,7 +654,7 @@
 #
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
-# CONFIG_SERIAL_8250_CS is not set
+CONFIG_SERIAL_8250_CS=m
 CONFIG_SERIAL_8250_NR_UARTS=8
 CONFIG_SERIAL_8250_EXTENDED=y
 CONFIG_SERIAL_8250_MANY_PORTS=y
@@ -634,7 +672,6 @@
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_UNIX98_PTYS=y
 # CONFIG_LEGACY_PTYS is not set
-# CONFIG_QIC02_TAPE is not set
 
 #
 # IPMI
@@ -696,7 +733,6 @@
 #
 # Console display driver support
 #
-# CONFIG_MDA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE_COLUMNS=160
 CONFIG_DUMMY_CONSOLE_ROWS=64
 CONFIG_DUMMY_CONSOLE=y
@@ -710,6 +746,12 @@
 # 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
@@ -717,6 +759,11 @@
 # CONFIG_USB_GADGET is not set
 
 #
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
@@ -730,6 +777,7 @@
 # CONFIG_JFS_POSIX_ACL is not set
 # CONFIG_JFS_DEBUG is not set
 # CONFIG_JFS_STATISTICS is not set
+CONFIG_FS_POSIX_ACL=y
 CONFIG_XFS_FS=m
 # CONFIG_XFS_RT is not set
 # CONFIG_XFS_QUOTA is not set
@@ -738,8 +786,9 @@
 # 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
+CONFIG_AUTOFS4_FS=y
 
 #
 # CD-ROM/DVD Filesystems
@@ -808,13 +857,14 @@
 CONFIG_SUNRPC=m
 CONFIG_SUNRPC_GSS=m
 CONFIG_RPCSEC_GSS_KRB5=m
+CONFIG_RPCSEC_GSS_SPKM3=m
 CONFIG_SMB_FS=m
 CONFIG_SMB_NLS_DEFAULT=y
 CONFIG_SMB_NLS_REMOTE="cp437"
 CONFIG_CIFS=m
 # CONFIG_CIFS_STATS is not set
 # CONFIG_CIFS_XATTR is not set
-# CONFIG_CIFS_POSIX is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
@@ -879,16 +929,19 @@
 # Kernel hacking
 #
 CONFIG_DEBUG_KERNEL=y
-# CONFIG_DEBUG_SLAB is not set
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
 # CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_DEBUG_RWLOCK is not set
-# CONFIG_FRAME_POINTER is not set
+# CONFIG_DEBUG_KOBJECT is not set
 # CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_RWLOCK is not set
 
 #
 # Security options
 #
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
 # CONFIG_SECURITY is not set
 
 #
@@ -902,6 +955,7 @@
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
 CONFIG_CRYPTO_DES=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_TWOFISH=m
@@ -909,11 +963,12 @@
 CONFIG_CRYPTO_AES=m
 CONFIG_CRYPTO_CAST5=m
 CONFIG_CRYPTO_CAST6=m
-# CONFIG_CRYPTO_TEA is not set
-# CONFIG_CRYPTO_ARC4 is not set
-# CONFIG_CRYPTO_KHAZAD is not set
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
 CONFIG_CRYPTO_DEFLATE=m
-# CONFIG_CRYPTO_MICHAEL_MIC is not set
+CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_CRC32C=m
 CONFIG_CRYPTO_TEST=m
 
diff -Nru a/arch/parisc/configs/b180_defconfig b/arch/parisc/configs/b180_defconfig
--- a/arch/parisc/configs/b180_defconfig	2005-03-01 23:39:18 -08:00
+++ b/arch/parisc/configs/b180_defconfig	2005-03-01 23:39:18 -08:00
@@ -1,5 +1,7 @@
 #
 # Automatically generated make config: don't edit
+# Linux kernel version: 2.6.10-pa5
+# Wed Jan  5 13:35:54 2005
 #
 CONFIG_PARISC=y
 CONFIG_MMU=y
@@ -11,19 +13,20 @@
 #
 # CONFIG_EXPERIMENTAL is not set
 CONFIG_CLEAN_COMPILE=y
-CONFIG_STANDALONE=y
 CONFIG_BROKEN_ON_SMP=y
 
 #
 # General setup
 #
+CONFIG_LOCALVERSION=""
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=15
+CONFIG_LOG_BUF_SHIFT=16
 # CONFIG_HOTPLUG is not set
+CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
@@ -31,11 +34,13 @@
 # CONFIG_KALLSYMS_EXTRA_PASS 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
@@ -43,6 +48,7 @@
 CONFIG_MODULES=y
 # CONFIG_MODULE_UNLOAD is not set
 CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
 # CONFIG_KMOD is not set
 
 #
@@ -91,8 +97,9 @@
 #
 # Generic Driver Options
 #
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_DEBUG_DRIVER=y
+CONFIG_STANDALONE=y
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+# CONFIG_DEBUG_DRIVER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -129,6 +136,19 @@
 # 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=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -174,12 +194,15 @@
 # CONFIG_SCSI_AHA152X is not set
 # CONFIG_SCSI_AHA1542 is not set
 # CONFIG_SCSI_AHA1740 is not set
+# CONFIG_SCSI_AACRAID is not set
 # CONFIG_SCSI_AIC7XXX is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_AIC79XX is not set
 # CONFIG_SCSI_DPT_I2O is not set
 # CONFIG_SCSI_IN2000 is not set
-# CONFIG_SCSI_MEGARAID 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_DTC3280 is not set
@@ -190,6 +213,7 @@
 # CONFIG_SCSI_GENERIC_NCR5380 is not set
 # CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
 # 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
@@ -240,6 +264,7 @@
 CONFIG_MD_RAID1=y
 CONFIG_MD_RAID5=y
 # CONFIG_MD_MULTIPATH is not set
+# CONFIG_MD_FAULTY is not set
 # CONFIG_BLK_DEV_DM is not set
 
 #
@@ -284,6 +309,9 @@
 # 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_NETFILTER is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_VLAN_8021Q is not set
@@ -446,6 +474,7 @@
 CONFIG_SERIO_GSCPS2=y
 # CONFIG_HP_SDC is not set
 # CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_RAW is not set
 
 #
 # Input Device Drivers
@@ -507,7 +536,6 @@
 # CONFIG_LP_CONSOLE is not set
 # CONFIG_PPDEV is not set
 # CONFIG_TIPAR is not set
-# CONFIG_QIC02_TAPE is not set
 
 #
 # IPMI
@@ -527,7 +555,6 @@
 #
 # 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
@@ -560,6 +587,8 @@
 # Graphics support
 #
 CONFIG_FB=y
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
 # CONFIG_FB_CIRRUS is not set
 # CONFIG_FB_PM2 is not set
 # CONFIG_FB_CYBER2000 is not set
@@ -611,6 +640,12 @@
 # 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
@@ -618,6 +653,11 @@
 # CONFIG_USB_GADGET is not set
 
 #
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
@@ -632,8 +672,9 @@
 # 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
+CONFIG_AUTOFS4_FS=y
 
 #
 # CD-ROM/DVD Filesystems
@@ -658,6 +699,7 @@
 CONFIG_SYSFS=y
 # 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
 
@@ -665,7 +707,6 @@
 # Miscellaneous filesystems
 #
 # CONFIG_HFSPLUS_FS is not set
-# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_HPFS_FS is not set
@@ -745,18 +786,21 @@
 # Kernel hacking
 #
 CONFIG_DEBUG_KERNEL=y
-# CONFIG_DEBUG_SLAB is not set
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
 # CONFIG_DEBUG_SPINLOCK is not set
-CONFIG_FRAME_POINTER=y
+# CONFIG_DEBUG_KOBJECT is not set
 # CONFIG_DEBUG_INFO is not set
 
 #
 # Security options
 #
+# CONFIG_KEYS is not set
 CONFIG_SECURITY=y
 # CONFIG_SECURITY_NETWORK is not set
 CONFIG_SECURITY_CAPABILITIES=y
+# CONFIG_SECURITY_SECLVL is not set
 # CONFIG_SECURITY_SELINUX is not set
 
 #
@@ -770,6 +814,7 @@
 # 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_DES is not set
 # CONFIG_CRYPTO_BLOWFISH is not set
 # CONFIG_CRYPTO_TWOFISH is not set
@@ -779,6 +824,8 @@
 # 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
diff -Nru a/arch/parisc/configs/c3000_defconfig b/arch/parisc/configs/c3000_defconfig
--- a/arch/parisc/configs/c3000_defconfig	2005-03-01 23:38:58 -08:00
+++ b/arch/parisc/configs/c3000_defconfig	2005-03-01 23:38:58 -08:00
@@ -1,5 +1,7 @@
 #
 # Automatically generated make config: don't edit
+# Linux kernel version: 2.6.10-pa5
+# Wed Jan  5 13:26:49 2005
 #
 CONFIG_PARISC=y
 CONFIG_MMU=y
@@ -11,13 +13,13 @@
 #
 CONFIG_EXPERIMENTAL=y
 # CONFIG_CLEAN_COMPILE is not set
-# CONFIG_STANDALONE is not set
 CONFIG_BROKEN=y
 CONFIG_BROKEN_ON_SMP=y
 
 #
 # General setup
 #
+CONFIG_LOCALVERSION=""
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 # CONFIG_POSIX_MQUEUE is not set
@@ -26,18 +28,22 @@
 # CONFIG_AUDIT is not set
 CONFIG_LOG_BUF_SHIFT=16
 CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
+# CONFIG_KALLSYMS_EXTRA_PASS 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
@@ -47,6 +53,7 @@
 CONFIG_MODULE_FORCE_UNLOAD=y
 CONFIG_OBSOLETE_MODPARM=y
 # CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_KMOD=y
 
 #
@@ -62,6 +69,7 @@
 # CONFIG_PARISC64 is not set
 # CONFIG_64BIT is not set
 # CONFIG_SMP is not set
+# CONFIG_DISCONTIGMEM is not set
 # CONFIG_PREEMPT is not set
 # CONFIG_HPUX is not set
 
@@ -80,14 +88,13 @@
 # CONFIG_PDC_CHASSIS is not set
 
 #
-# PCMCIA/CardBus support
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
 #
-CONFIG_PCMCIA=m
-CONFIG_PCMCIA_DEBUG=y
-CONFIG_YENTA=m
-CONFIG_CARDBUS=y
-# CONFIG_I82092 is not set
-# CONFIG_TCIC is not set
 
 #
 # PCI Hotplug Support
@@ -107,8 +114,10 @@
 #
 # Generic Driver Options
 #
+# CONFIG_STANDALONE is not set
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
 CONFIG_FW_LOADER=y
-CONFIG_DEBUG_DRIVER=y
+# CONFIG_DEBUG_DRIVER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -135,8 +144,20 @@
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_CARMEL 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_CDROM_PKTCDVD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -147,16 +168,14 @@
 #
 # Please see Documentation/ide.txt for help/info on IDE drives
 #
+# CONFIG_BLK_DEV_IDE_SATA is not set
 CONFIG_BLK_DEV_IDEDISK=m
 # CONFIG_IDEDISK_MULTI_MODE is not set
-CONFIG_IDEDISK_STROKE=y
-# CONFIG_BLK_DEV_IDECS is not set
 CONFIG_BLK_DEV_IDECD=y
 # CONFIG_BLK_DEV_IDETAPE is not set
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
 CONFIG_BLK_DEV_IDESCSI=y
 # CONFIG_IDE_TASK_IOCTL is not set
-# CONFIG_IDE_TASKFILE_IO is not set
 
 #
 # IDE chipset support/bugfixes
@@ -170,7 +189,6 @@
 CONFIG_BLK_DEV_IDEDMA_PCI=y
 # CONFIG_BLK_DEV_IDEDMA_FORCED is not set
 # CONFIG_IDEDMA_PCI_AUTO is not set
-CONFIG_BLK_DEV_ADMA=y
 # CONFIG_BLK_DEV_AEC62XX is not set
 # CONFIG_BLK_DEV_ALI15X3 is not set
 # CONFIG_BLK_DEV_AMD74XX is not set
@@ -217,7 +235,6 @@
 # Some SCSI devices (e.g. CD jukebox) support multiple LUNs
 #
 CONFIG_SCSI_MULTI_LUN=y
-CONFIG_SCSI_REPORT_LUNS=y
 # CONFIG_SCSI_CONSTANTS is not set
 # CONFIG_SCSI_LOGGING is not set
 
@@ -231,6 +248,7 @@
 # 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
@@ -238,14 +256,18 @@
 # CONFIG_SCSI_AIC79XX is not set
 # CONFIG_SCSI_DPT_I2O is not set
 # CONFIG_SCSI_ADVANSYS is not set
-# CONFIG_SCSI_MEGARAID is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY 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=m
+# CONFIG_SCSI_SATA_NV is not set
 CONFIG_SCSI_SATA_PROMISE=m
 # CONFIG_SCSI_SATA_SX4 is not set
 CONFIG_SCSI_SATA_SIL=m
 # CONFIG_SCSI_SATA_SIS is not set
+# CONFIG_SCSI_SATA_ULI is not set
 CONFIG_SCSI_SATA_VIA=m
 # CONFIG_SCSI_SATA_VITESSE is not set
 # CONFIG_SCSI_BUSLOGIC is not set
@@ -270,6 +292,7 @@
 CONFIG_SCSI_QLOGIC_FC=m
 # CONFIG_SCSI_QLOGIC_FC_FIRMWARE is not set
 CONFIG_SCSI_QLOGIC_1280=m
+# CONFIG_SCSI_QLOGIC_1280_1040 is not set
 CONFIG_SCSI_QLA2XXX=y
 # CONFIG_SCSI_QLA21XX is not set
 # CONFIG_SCSI_QLA22XX is not set
@@ -283,15 +306,6 @@
 CONFIG_SCSI_DEBUG=m
 
 #
-# PCMCIA SCSI adapter support
-#
-# CONFIG_PCMCIA_AHA152X is not set
-# CONFIG_PCMCIA_FDOMAIN is not set
-# CONFIG_PCMCIA_NINJA_SCSI is not set
-CONFIG_PCMCIA_QLOGIC=m
-# CONFIG_PCMCIA_SYM53C500 is not set
-
-#
 # Multi-device support (RAID and LVM)
 #
 CONFIG_MD=y
@@ -299,18 +313,22 @@
 CONFIG_MD_LINEAR=y
 CONFIG_MD_RAID0=y
 CONFIG_MD_RAID1=y
+# CONFIG_MD_RAID10 is not set
 # CONFIG_MD_RAID5 is not set
 # CONFIG_MD_RAID6 is not set
 CONFIG_MD_MULTIPATH=y
+# CONFIG_MD_FAULTY 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
 
 #
 # Fusion MPT device support
 #
 CONFIG_FUSION=m
 CONFIG_FUSION_MAX_SGE=40
-CONFIG_FUSION_ISENSE=m
 CONFIG_FUSION_CTL=m
 
 #
@@ -351,6 +369,9 @@
 CONFIG_INET_AH=m
 CONFIG_INET_ESP=m
 # 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
@@ -364,6 +385,9 @@
 # IP: Netfilter Configuration
 #
 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
@@ -388,15 +412,22 @@
 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=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_LOCAL is not set
 CONFIG_IP_NF_NAT_SNMP_BASIC=m
 CONFIG_IP_NF_NAT_IRC=m
 CONFIG_IP_NF_NAT_FTP=m
@@ -408,15 +439,12 @@
 CONFIG_IP_NF_TARGET_DSCP=m
 CONFIG_IP_NF_TARGET_MARK=m
 CONFIG_IP_NF_TARGET_CLASSIFY=m
-CONFIG_IP_NF_TARGET_LOG=m
-CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_IP_NF_TARGET_TCPMSS=m
+# CONFIG_IP_NF_RAW is not set
 CONFIG_IP_NF_ARPTABLES=m
 CONFIG_IP_NF_ARPFILTER=m
 CONFIG_IP_NF_ARP_MANGLE=m
 CONFIG_IP_NF_COMPAT_IPCHAINS=m
 CONFIG_IP_NF_COMPAT_IPFWADM=m
-# CONFIG_IP_NF_RAW is not set
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
 
@@ -437,12 +465,12 @@
 # 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
@@ -481,13 +509,11 @@
 CONFIG_DE2104X=m
 CONFIG_TULIP=y
 # CONFIG_TULIP_MWI is not set
-# CONFIG_TULIP_MMIO is not set
+CONFIG_TULIP_MMIO=y
 # CONFIG_TULIP_NAPI is not set
-CONFIG_DE4X5=m
-CONFIG_WINBOND_840=m
+# CONFIG_DE4X5 is not set
+# CONFIG_WINBOND_840 is not set
 # CONFIG_DM9102 is not set
-CONFIG_PCMCIA_XIRCOM=m
-CONFIG_PCMCIA_XIRTULIP=m
 # CONFIG_HP100 is not set
 CONFIG_NET_PCI=y
 CONFIG_PCNET32=m
@@ -529,6 +555,7 @@
 # CONFIG_YELLOWFIN is not set
 # CONFIG_R8169 is not set
 # CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
 CONFIG_TIGON3=m
 
 #
@@ -549,19 +576,6 @@
 # CONFIG_NET_RADIO is not set
 
 #
-# PCMCIA network device support
-#
-CONFIG_NET_PCMCIA=y
-CONFIG_PCMCIA_3C589=m
-CONFIG_PCMCIA_3C574=m
-CONFIG_PCMCIA_FMVJ18X=m
-CONFIG_PCMCIA_PCNET=m
-CONFIG_PCMCIA_NMCLAN=m
-CONFIG_PCMCIA_SMC91C92=m
-CONFIG_PCMCIA_XIRC2PS=m
-CONFIG_PCMCIA_AXNET=m
-
-#
 # Wan interfaces
 #
 # CONFIG_WAN is not set
@@ -615,6 +629,7 @@
 CONFIG_SERIO=m
 CONFIG_SERIO_SERPORT=m
 # CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_RAW is not set
 
 #
 # Input Device Drivers
@@ -625,13 +640,10 @@
 # CONFIG_KEYBOARD_LKKBD is not set
 # CONFIG_KEYBOARD_XTKBD is not set
 # CONFIG_KEYBOARD_NEWTON is not set
-# CONFIG_KEYBOARD_HIL_OLD is not set
-# CONFIG_KEYBOARD_HIL is not set
 CONFIG_INPUT_MOUSE=y
 # CONFIG_MOUSE_PS2 is not set
 # CONFIG_MOUSE_SERIAL is not set
 # CONFIG_MOUSE_VSXXXAA is not set
-# CONFIG_MOUSE_HIL is not set
 # CONFIG_INPUT_JOYSTICK is not set
 # CONFIG_INPUT_TOUCHSCREEN is not set
 # CONFIG_INPUT_MISC is not set
@@ -649,7 +661,6 @@
 #
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_CS=m
 CONFIG_SERIAL_8250_NR_UARTS=4
 CONFIG_SERIAL_8250_EXTENDED=y
 CONFIG_SERIAL_8250_MANY_PORTS=y
@@ -668,7 +679,6 @@
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
-# CONFIG_QIC02_TAPE is not set
 
 #
 # IPMI
@@ -688,14 +698,8 @@
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_FTAPE is not set
 # CONFIG_AGP is not set
 # CONFIG_DRM is not set
-
-#
-# PCMCIA character devices
-#
-# CONFIG_SYNCLINK_CS is not set
 CONFIG_RAW_DRIVER=y
 CONFIG_MAX_RAW_DEVS=256
 
@@ -705,6 +709,11 @@
 # CONFIG_I2C is not set
 
 #
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
 # Misc devices
 #
 
@@ -722,6 +731,8 @@
 # Graphics support
 #
 CONFIG_FB=y
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
 # CONFIG_FB_CIRRUS is not set
 # CONFIG_FB_PM2 is not set
 # CONFIG_FB_CYBER2000 is not set
@@ -734,6 +745,7 @@
 # CONFIG_FB_RADEON is not set
 # CONFIG_FB_ATY128 is not set
 # CONFIG_FB_ATY is not set
+# CONFIG_FB_SAVAGE is not set
 # CONFIG_FB_SIS is not set
 # CONFIG_FB_NEOMAGIC is not set
 # CONFIG_FB_KYRO is not set
@@ -746,13 +758,11 @@
 #
 # Console display driver support
 #
-# CONFIG_MDA_CONSOLE is not set
 CONFIG_STI_CONSOLE=y
 CONFIG_DUMMY_CONSOLE_COLUMNS=160
 CONFIG_DUMMY_CONSOLE_ROWS=64
 CONFIG_DUMMY_CONSOLE=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_PCI_CONSOLE=y
 # CONFIG_FONTS is not set
 CONFIG_FONT_8x8=y
 CONFIG_FONT_8x16=y
@@ -793,6 +803,9 @@
 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=y
+CONFIG_USB_ARCH_HAS_OHCI=y
 
 #
 # USB Host Controller Drivers
@@ -800,6 +813,7 @@
 # CONFIG_USB_EHCI_HCD is not set
 CONFIG_USB_OHCI_HCD=y
 # CONFIG_USB_UHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
 
 #
 # USB Device Class drivers
@@ -809,8 +823,13 @@
 # CONFIG_USB_MIDI is not set
 # CONFIG_USB_ACM is not set
 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=y
 CONFIG_USB_STORAGE_FREECOM=y
 # CONFIG_USB_STORAGE_ISD200 is not set
@@ -821,7 +840,7 @@
 CONFIG_USB_STORAGE_JUMPSHOT=y
 
 #
-# USB Human Interface Devices (HID)
+# USB Input Devices
 #
 CONFIG_USB_HID=y
 CONFIG_USB_HIDINPUT=y
@@ -853,7 +872,7 @@
 #
 
 #
-# USB Network adaptors
+# USB Network Adapters
 #
 # CONFIG_USB_CATC is not set
 # CONFIG_USB_KAWETH is not set
@@ -882,15 +901,25 @@
 # 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_TEST is not set
 
 #
+# USB ATM/DSL drivers
+#
+
+#
 # USB Gadget Support
 #
 # CONFIG_USB_GADGET is not set
 
 #
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
@@ -909,8 +938,9 @@
 # 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
+CONFIG_AUTOFS4_FS=y
 
 #
 # CD-ROM/DVD Filesystems
@@ -926,6 +956,8 @@
 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
 
 #
@@ -937,6 +969,7 @@
 # CONFIG_DEVFS_FS 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
@@ -975,6 +1008,7 @@
 CONFIG_EXPORTFS=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
@@ -1015,6 +1049,7 @@
 # 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
@@ -1040,14 +1075,17 @@
 # Kernel hacking
 #
 CONFIG_DEBUG_KERNEL=y
-# CONFIG_DEBUG_SLAB is not set
 CONFIG_MAGIC_SYSRQ=y
-# CONFIG_FRAME_POINTER is not set
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_KOBJECT is not set
 # CONFIG_DEBUG_INFO is not set
 
 #
 # Security options
 #
+# CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 
 #
@@ -1061,6 +1099,7 @@
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 # CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_WP512 is not set
 CONFIG_CRYPTO_DES=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_TWOFISH=m
@@ -1068,7 +1107,10 @@
 CONFIG_CRYPTO_AES=m
 CONFIG_CRYPTO_CAST5=m
 CONFIG_CRYPTO_CAST6=m
+# 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=m
@@ -1077,6 +1119,7 @@
 #
 # Library routines
 #
+CONFIG_CRC_CCITT=m
 CONFIG_CRC32=y
 CONFIG_LIBCRC32C=m
 CONFIG_ZLIB_INFLATE=m
diff -Nru a/arch/parisc/configs/n4000_defconfig b/arch/parisc/configs/n4000_defconfig
--- a/arch/parisc/configs/n4000_defconfig	2005-03-01 23:38:53 -08:00
+++ b/arch/parisc/configs/n4000_defconfig	2005-03-01 23:38:53 -08:00
@@ -1,5 +1,7 @@
 #
 # Automatically generated make config: don't edit
+# Linux kernel version: 2.6.10-pa5
+# Wed Jan  5 13:40:36 2005
 #
 CONFIG_PARISC=y
 CONFIG_MMU=y
@@ -11,13 +13,13 @@
 #
 CONFIG_EXPERIMENTAL=y
 # CONFIG_CLEAN_COMPILE is not set
-# CONFIG_STANDALONE is not set
 CONFIG_BROKEN=y
 CONFIG_BROKEN_ON_SMP=y
 
 #
 # General setup
 #
+CONFIG_LOCALVERSION=""
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
@@ -26,18 +28,22 @@
 # CONFIG_AUDIT is not set
 CONFIG_LOG_BUF_SHIFT=16
 CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
+# CONFIG_KALLSYMS_EXTRA_PASS 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
@@ -47,6 +53,7 @@
 CONFIG_MODULE_FORCE_UNLOAD=y
 CONFIG_OBSOLETE_MODPARM=y
 # CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_KMOD=y
 
 #
@@ -81,14 +88,13 @@
 # CONFIG_PDC_CHASSIS is not set
 
 #
-# PCMCIA/CardBus support
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
 #
-CONFIG_PCMCIA=m
-CONFIG_PCMCIA_DEBUG=y
-CONFIG_YENTA=m
-CONFIG_CARDBUS=y
-# CONFIG_I82092 is not set
-# CONFIG_TCIC is not set
 
 #
 # PCI Hotplug Support
@@ -108,8 +114,10 @@
 #
 # Generic Driver Options
 #
-# CONFIG_FW_LOADER is not set
-CONFIG_DEBUG_DRIVER=y
+# CONFIG_STANDALONE is not set
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+CONFIG_FW_LOADER=y
+# CONFIG_DEBUG_DRIVER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -136,10 +144,23 @@
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_CARMEL is not set
+# CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=6144
 CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -179,13 +200,15 @@
 # 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_ADVANSYS is not set
-# CONFIG_SCSI_MEGARAID 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
@@ -209,6 +232,7 @@
 CONFIG_SCSI_QLOGIC_FC=m
 # CONFIG_SCSI_QLOGIC_FC_FIRMWARE is not set
 CONFIG_SCSI_QLOGIC_1280=m
+# CONFIG_SCSI_QLOGIC_1280_1040 is not set
 CONFIG_SCSI_QLA2XXX=y
 # CONFIG_SCSI_QLA21XX is not set
 # CONFIG_SCSI_QLA22XX is not set
@@ -221,13 +245,6 @@
 CONFIG_SCSI_DEBUG=m
 
 #
-# PCMCIA SCSI adapter support
-#
-# CONFIG_PCMCIA_FDOMAIN is not set
-# CONFIG_PCMCIA_QLOGIC is not set
-# CONFIG_PCMCIA_SYM53C500 is not set
-
-#
 # Multi-device support (RAID and LVM)
 #
 CONFIG_MD=y
@@ -235,9 +252,11 @@
 CONFIG_MD_LINEAR=y
 CONFIG_MD_RAID0=y
 CONFIG_MD_RAID1=y
+# CONFIG_MD_RAID10 is not set
 # CONFIG_MD_RAID5 is not set
 # CONFIG_MD_RAID6 is not set
 # CONFIG_MD_MULTIPATH is not set
+# CONFIG_MD_FAULTY is not set
 # CONFIG_BLK_DEV_DM is not set
 
 #
@@ -245,7 +264,6 @@
 #
 CONFIG_FUSION=m
 CONFIG_FUSION_MAX_SGE=40
-CONFIG_FUSION_ISENSE=m
 CONFIG_FUSION_CTL=m
 
 #
@@ -286,6 +304,9 @@
 CONFIG_INET_AH=m
 CONFIG_INET_ESP=m
 # 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
@@ -299,6 +320,9 @@
 # IP: Netfilter Configuration
 #
 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
@@ -323,15 +347,22 @@
 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_LOCAL is not set
 CONFIG_IP_NF_NAT_SNMP_BASIC=m
 CONFIG_IP_NF_NAT_IRC=m
 CONFIG_IP_NF_NAT_FTP=m
@@ -343,16 +374,13 @@
 CONFIG_IP_NF_TARGET_DSCP=m
 CONFIG_IP_NF_TARGET_MARK=m
 CONFIG_IP_NF_TARGET_CLASSIFY=m
-CONFIG_IP_NF_TARGET_LOG=m
-CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_IP_NF_TARGET_TCPMSS=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_IP_NF_COMPAT_IPCHAINS is not set
 # CONFIG_IP_NF_COMPAT_IPFWADM is not set
-CONFIG_IP_NF_TARGET_NOTRACK=m
-CONFIG_IP_NF_RAW=m
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
 
@@ -373,13 +401,12 @@
 # CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
-# CONFIG_NET_HW_FLOWCONTROL is not set
 
 #
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
+CONFIG_NET_CLS_ROUTE=y
 
 #
 # Network testing
@@ -425,8 +452,6 @@
 # CONFIG_DE4X5 is not set
 # CONFIG_WINBOND_840 is not set
 # CONFIG_DM9102 is not set
-CONFIG_PCMCIA_XIRCOM=m
-CONFIG_PCMCIA_XIRTULIP=m
 CONFIG_HP100=m
 CONFIG_NET_PCI=y
 CONFIG_PCNET32=m
@@ -467,6 +492,7 @@
 # CONFIG_YELLOWFIN is not set
 # CONFIG_R8169 is not set
 # CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
 CONFIG_TIGON3=m
 
 #
@@ -491,18 +517,10 @@
 # Obsolete Wireless cards support (pre-802.11)
 #
 # CONFIG_STRIP is not set
-CONFIG_PCMCIA_WAVELAN=m
-CONFIG_PCMCIA_NETWAVE=m
-
-#
-# Wireless 802.11 Frequency Hopping cards support
-#
-# CONFIG_PCMCIA_RAYCS is not set
 
 #
 # Wireless 802.11b ISA/PCI cards support
 #
-# CONFIG_AIRO is not set
 CONFIG_HERMES=m
 CONFIG_PLX_HERMES=m
 CONFIG_TMD_HERMES=m
@@ -510,32 +528,12 @@
 # CONFIG_ATMEL is not set
 
 #
-# Wireless 802.11b Pcmcia/Cardbus cards support
-#
-CONFIG_PCMCIA_HERMES=m
-CONFIG_AIRO_CS=m
-# CONFIG_PCMCIA_WL3501 is not set
-
-#
 # Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
 #
 # CONFIG_PRISM54 is not set
 CONFIG_NET_WIRELESS=y
 
 #
-# PCMCIA network device support
-#
-CONFIG_NET_PCMCIA=y
-CONFIG_PCMCIA_3C589=m
-CONFIG_PCMCIA_3C574=m
-# CONFIG_PCMCIA_FMVJ18X is not set
-# CONFIG_PCMCIA_PCNET is not set
-# CONFIG_PCMCIA_NMCLAN is not set
-CONFIG_PCMCIA_SMC91C92=m
-CONFIG_PCMCIA_XIRC2PS=m
-# CONFIG_PCMCIA_AXNET is not set
-
-#
 # Wan interfaces
 #
 # CONFIG_WAN is not set
@@ -607,7 +605,6 @@
 #
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
-# CONFIG_SERIAL_8250_CS is not set
 CONFIG_SERIAL_8250_NR_UARTS=8
 CONFIG_SERIAL_8250_EXTENDED=y
 CONFIG_SERIAL_8250_MANY_PORTS=y
@@ -625,7 +622,6 @@
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_UNIX98_PTYS=y
 # CONFIG_LEGACY_PTYS is not set
-# CONFIG_QIC02_TAPE is not set
 
 #
 # IPMI
@@ -645,14 +641,8 @@
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_FTAPE is not set
 # CONFIG_AGP is not set
 # CONFIG_DRM is not set
-
-#
-# PCMCIA character devices
-#
-# CONFIG_SYNCLINK_CS is not set
 CONFIG_RAW_DRIVER=y
 CONFIG_MAX_RAW_DEVS=256
 
@@ -662,6 +652,11 @@
 # CONFIG_I2C is not set
 
 #
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
 # Misc devices
 #
 
@@ -683,7 +678,6 @@
 #
 # Console display driver support
 #
-# CONFIG_MDA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE_COLUMNS=160
 CONFIG_DUMMY_CONSOLE_ROWS=64
 CONFIG_DUMMY_CONSOLE=y
@@ -697,6 +691,12 @@
 # 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
@@ -704,6 +704,11 @@
 # CONFIG_USB_GADGET is not set
 
 #
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
@@ -717,6 +722,7 @@
 # CONFIG_JFS_POSIX_ACL is not set
 # CONFIG_JFS_DEBUG is not set
 # CONFIG_JFS_STATISTICS is not set
+CONFIG_FS_POSIX_ACL=y
 CONFIG_XFS_FS=m
 # CONFIG_XFS_RT is not set
 # CONFIG_XFS_QUOTA is not set
@@ -725,8 +731,9 @@
 # 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
+CONFIG_AUTOFS4_FS=y
 
 #
 # CD-ROM/DVD Filesystems
@@ -735,6 +742,7 @@
 CONFIG_JOLIET=y
 # CONFIG_ZISOFS is not set
 CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
 
 #
 # DOS/FAT/NT Filesystems
@@ -742,6 +750,8 @@
 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
 
 #
@@ -753,6 +763,7 @@
 # CONFIG_DEVFS_FS 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
@@ -793,11 +804,14 @@
 CONFIG_SUNRPC=y
 CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
 CONFIG_SMB_NLS_DEFAULT=y
 CONFIG_SMB_NLS_REMOTE="cp437"
 CONFIG_CIFS=m
 # CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_XATTR is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
@@ -836,6 +850,7 @@
 # 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
@@ -861,15 +876,17 @@
 # Kernel hacking
 #
 CONFIG_DEBUG_KERNEL=y
-# CONFIG_DEBUG_SLAB is not set
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
 # CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_FRAME_POINTER is not set
+# CONFIG_DEBUG_KOBJECT is not set
 # CONFIG_DEBUG_INFO is not set
 
 #
 # Security options
 #
+# CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 
 #
@@ -883,6 +900,7 @@
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
 CONFIG_CRYPTO_DES=y
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_TWOFISH=m
@@ -890,7 +908,10 @@
 CONFIG_CRYPTO_AES=m
 CONFIG_CRYPTO_CAST5=m
 CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
 # CONFIG_CRYPTO_ARC4 is not set
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
 CONFIG_CRYPTO_DEFLATE=m
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
 CONFIG_CRYPTO_CRC32C=m
@@ -899,6 +920,7 @@
 #
 # Library routines
 #
+CONFIG_CRC_CCITT=m
 CONFIG_CRC32=y
 CONFIG_LIBCRC32C=m
 CONFIG_ZLIB_INFLATE=m
diff -Nru a/arch/parisc/hpux/entry_hpux.S b/arch/parisc/hpux/entry_hpux.S
--- a/arch/parisc/hpux/entry_hpux.S	2005-03-01 23:38:55 -08:00
+++ b/arch/parisc/hpux/entry_hpux.S	2005-03-01 23:38:55 -08:00
@@ -227,7 +227,7 @@
 	ENTRY_NAME(hpux_unimplemented_wrapper)
 	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 195 */
 	ENTRY_NAME(hpux_statfs)
-	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_fstatfs)
 	ENTRY_NAME(hpux_unimplemented_wrapper)
 	ENTRY_NAME(hpux_unimplemented_wrapper)
 	ENTRY_NAME(sys_waitpid)	/* 200 */
diff -Nru a/arch/parisc/hpux/sys_hpux.c b/arch/parisc/hpux/sys_hpux.c
--- a/arch/parisc/hpux/sys_hpux.c	2005-03-01 23:38:57 -08:00
+++ b/arch/parisc/hpux/sys_hpux.c	2005-03-01 23:38:57 -08:00
@@ -22,14 +22,16 @@
  *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include <linux/file.h>
 #include <linux/fs.h>
+#include <linux/namei.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/smp_lock.h>
 #include <linux/syscalls.h>
 #include <linux/utsname.h>
-#include <linux/vmalloc.h>
 #include <linux/vfs.h>
+#include <linux/vmalloc.h>
 
 #include <asm/errno.h>
 #include <asm/pgalloc.h>
@@ -65,7 +67,6 @@
 
 int hpux_setpgrp(void)
 {
-	extern int sys_setpgid(int, int);
 	return sys_setpgid(0,0);
 }
 
@@ -133,7 +134,7 @@
  *  aid in porting forward if and when sys_ustat() is changed from
  *  its form in kernel 2.2.5.
  */
-static int hpux_ustat(dev_t dev, struct hpux_ustat *ubuf)
+static int hpux_ustat(dev_t dev, struct hpux_ustat __user *ubuf)
 {
 	struct super_block *s;
 	struct hpux_ustat tmp;  /* Changed to hpux_ustat */
@@ -148,14 +149,13 @@
 	if (err)
 		goto out;
 
-	memset(&tmp,0,sizeof(struct hpux_ustat));  /* Changed to hpux_ustat */
+	memset(&tmp,0,sizeof(tmp));
 
 	tmp.f_tfree = (int32_t)sbuf.f_bfree;
 	tmp.f_tinode = (u_int32_t)sbuf.f_ffree;
 	tmp.f_blksize = (u_int32_t)sbuf.f_bsize;  /*  Added this line  */
 
-	/* Changed to hpux_ustat:  */
-	err = copy_to_user(ubuf,&tmp,sizeof(struct hpux_ustat)) ? -EFAULT : 0;
+	err = copy_to_user(ubuf, &tmp, sizeof(tmp)) ? -EFAULT : 0;
 out:
 	return err;
 }
@@ -185,37 +185,62 @@
      int16_t f_pad;
 };
 
-/* hpux statfs */
-int hpux_statfs(const char *path, struct hpux_statfs *buf)
+static int vfs_statfs_hpux(struct super_block *sb, struct hpux_statfs *buf)
 {
-	int error;
-	int len;
-	char *kpath;
-
-	len = strlen_user((char *)path); 
-
-	kpath = (char *) kmalloc(len+1, GFP_KERNEL);
-	if ( !kpath ) {
-	printk(KERN_DEBUG "failed to kmalloc kpath\n");
-	return 0;
-	}
+	struct kstatfs st;
+	int retval;
+	
+	retval = vfs_statfs(sb, &st);
+	if (retval)
+		return retval;
+
+	memset(buf, 0, sizeof(*buf));
+	buf->f_type = st.f_type;
+	buf->f_bsize = st.f_bsize;
+	buf->f_blocks = st.f_blocks;
+	buf->f_bfree = st.f_bfree;
+	buf->f_bavail = st.f_bavail;
+	buf->f_files = st.f_files;
+	buf->f_ffree = st.f_ffree;
+	buf->f_fsid[0] = st.f_fsid.val[0];
+	buf->f_fsid[1] = st.f_fsid.val[1];
 
-	if ( copy_from_user(kpath, (char *)path, len+1) ) {
-	printk(KERN_DEBUG "failed to copy_from_user kpath\n");
-	kfree(kpath);
 	return 0;
-	}
-
-	printk(KERN_DEBUG "hpux_statfs(\"%s\",-)\n", kpath);
+}
 
-	kfree(kpath);
+/* hpux statfs */
+asmlinkage long hpux_statfs(const char __user *path,
+						struct hpux_statfs __user *buf)
+{
+	struct nameidata nd;
+	int error;
 
-	/* just fake it, beginning of structures match */
-	error = sys_statfs(path, (struct statfs *) buf);
+	error = user_path_walk(path, &nd);
+	if (!error) {
+		struct hpux_statfs tmp;
+		error = vfs_statfs_hpux(nd.dentry->d_inode->i_sb, &tmp);
+		if (!error && copy_to_user(buf, &tmp, sizeof(tmp)))
+			error = -EFAULT;
+		path_release(&nd);
+	}
+	return error;
+}
 
-	/* ignoring rest of statfs struct, but it should be zeros. Need to do 
-		something with f_fsid[1], which is the fstype for sysfs */
+asmlinkage long hpux_fstatfs(unsigned int fd, struct hpux_statfs __user * buf)
+{
+	struct file *file;
+	struct hpux_statfs tmp;
+	int error;
 
+	error = -EBADF;
+	file = fget(fd);
+	if (!file)
+		goto out;
+	error = vfs_statfs_hpux(file->f_dentry->d_inode->i_sb, &tmp);
+	if (!error && copy_to_user(buf, &tmp, sizeof(tmp)))
+		error = -EFAULT;
+	fput(file);
+ out:
 	return error;
 }
 
@@ -671,8 +696,8 @@
 	"setdomainname",         
 	"async_daemon",          
 	"getdirentries",          /* 195 */
-	"statfs",                
-	"fstatfs",               
+	NULL,                
+	NULL,               
 	"vfsmount",              
 	NULL,                    
 	"waitpid",                /* 200 */
diff -Nru a/arch/parisc/kernel/binfmt_elf32.c b/arch/parisc/kernel/binfmt_elf32.c
--- a/arch/parisc/kernel/binfmt_elf32.c	2005-03-01 23:38:55 -08:00
+++ b/arch/parisc/kernel/binfmt_elf32.c	2005-03-01 23:38:55 -08:00
@@ -92,10 +92,12 @@
 	current->thread.map_base = DEFAULT_MAP_BASE32; \
 	current->thread.task_size = DEFAULT_TASK_SIZE32 \
 
-#define jiffies_to_timeval jiffies_to_compat_timeval 
+#undef cputime_to_timeval
+#define cputime_to_timeval cputime_to_compat_timeval
 static __inline__ void
-jiffies_to_compat_timeval(unsigned long jiffies, struct compat_timeval *value)
+cputime_to_compat_timeval(const cputime_t cputime, struct compat_timeval *value)
 {
+	unsigned long jiffies = cputime_to_jiffies(cputime);
 	value->tv_usec = (jiffies % HZ) * (1000000L / HZ);
 	value->tv_sec = jiffies / HZ;
 }
diff -Nru a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c
--- a/arch/parisc/kernel/cache.c	2005-03-01 23:38:56 -08:00
+++ b/arch/parisc/kernel/cache.c	2005-03-01 23:38:56 -08:00
@@ -40,7 +40,7 @@
  * by software.  We put a spinlock around all TLB flushes  to
  * ensure this.
  */
-spinlock_t pa_tlb_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(pa_tlb_lock);
 EXPORT_SYMBOL(pa_tlb_lock);
 #endif
 
@@ -55,6 +55,11 @@
 {
 	on_each_cpu((void (*)(void *))flush_data_cache_local, NULL, 1, 1);
 }
+void 
+flush_instruction_cache(void)
+{
+	on_each_cpu((void (*)(void *))flush_instruction_cache_local, NULL, 1, 1);
+}
 #endif
 
 void
@@ -326,4 +331,36 @@
 	purge_tlb_start();
 	__clear_user_page_asm(page, vaddr);
 	purge_tlb_end();
+}
+
+#define FLUSH_THRESHOLD 0x80000 /* 0.5MB */
+int parisc_cache_flush_threshold = FLUSH_THRESHOLD;
+
+void parisc_setup_cache_timing(void)
+{
+	unsigned long rangetime, alltime;
+	extern char _text;	/* start of kernel code, defined by linker */
+	extern char _end;	/* end of BSS, defined by linker */
+	unsigned long size;
+
+	alltime = mfctl(16);
+	flush_data_cache();
+	alltime = mfctl(16) - alltime;
+
+	size = (unsigned long)(&_end - _text);
+	rangetime = mfctl(16);
+	flush_kernel_dcache_range((unsigned long)&_text, size);
+	rangetime = mfctl(16) - rangetime;
+
+	printk(KERN_DEBUG "Whole cache flush %lu cycles, flushing %lu bytes %lu cycles\n",
+		alltime, size, rangetime);
+
+	/* Racy, but if we see an intermediate value, it's ok too... */
+	parisc_cache_flush_threshold = size * alltime / rangetime;
+
+	parisc_cache_flush_threshold = (parisc_cache_flush_threshold + L1_CACHE_BYTES - 1) &~ (L1_CACHE_BYTES - 1); 
+	if (!parisc_cache_flush_threshold)
+		parisc_cache_flush_threshold = FLUSH_THRESHOLD;
+
+	printk("Setting cache flush threshold to %x (%d CPUs online)\n", parisc_cache_flush_threshold, num_online_cpus());
 }
diff -Nru a/arch/parisc/kernel/drivers.c b/arch/parisc/kernel/drivers.c
--- a/arch/parisc/kernel/drivers.c	2005-03-01 23:39:09 -08:00
+++ b/arch/parisc/kernel/drivers.c	2005-03-01 23:39:09 -08:00
@@ -10,9 +10,21 @@
  * Copyright (c) 2001 Matthew Wilcox for Hewlett Packard
  * Copyright (c) 2001 Helge Deller <deller@gmx.de>
  * Copyright (c) 2001,2002 Ryan Bradetich 
+ * Copyright (c) 2004 Thibaut VARENE <varenet@parisc-linux.org>
  * 
  * The file handles registering devices and drivers, then matching them.
  * It's the closest we get to a dating agency.
+ *
+ * If you're thinking about modifying this file, here are some gotchas to
+ * bear in mind:
+ *  - 715/Mirage device paths have a dummy device between Lasi and its children
+ *  - The EISA adapter may show up as a sibling or child of Wax
+ *  - Dino has an optionally functional serial port.  If firmware enables it,
+ *    it shows up as a child of Dino.  If firmware disables it, the buswalk
+ *    finds it and it shows up as a child of Cujo
+ *  - Dino has both parisc and pci devices as children
+ *  - parisc devices are discovered in a random order, including children
+ *    before parents in some cases.
  */
 
 #include <linux/slab.h>
@@ -30,13 +42,16 @@
 struct hppa_dma_ops *hppa_dma_ops;
 EXPORT_SYMBOL(hppa_dma_ops);
 
-static struct parisc_device root;
+static struct device root = {
+	.bus_id = "parisc",
+};
 
-#define for_each_padev(dev) \
-	for (dev = root.child; dev != NULL; dev = next_dev(dev))
+#define for_each_padev(padev) \
+	for (padev = next_dev(&root); padev != NULL; \
+			padev = next_dev(&padev->dev))
 
-#define check_dev(dev) \
-	(dev->id.hw_type != HPHW_FAULTY) ? dev : next_dev(dev)
+#define check_dev(padev) \
+	(padev->id.hw_type != HPHW_FAULTY) ? padev : next_dev(&padev->dev)
 
 /**
  * next_dev - enumerates registered devices
@@ -45,20 +60,20 @@
  * next_dev does a depth-first search of the tree, returning parents
  * before children.  Returns NULL when there are no more devices.
  */
-struct parisc_device *next_dev(struct parisc_device *dev)
+static struct parisc_device *next_dev(struct device *dev)
 {
-	if (dev->child) {
-		return check_dev(dev->child);
-	} else if (dev->sibling) {
-		return dev->sibling;
+	if (!list_empty(&dev->children)) {
+		dev = list_to_dev(dev->children.next);
+		return check_dev(to_parisc_device(dev));
 	}
 
-	/* Exhausted tree at this level, time to go up. */
-	do {
+	while (dev != &root) {
+		if (dev->node.next != &dev->parent->children) {
+			dev = list_to_dev(dev->node.next);
+			return to_parisc_device(dev);
+		}
 		dev = dev->parent;
-		if (dev && dev->sibling)
-			return dev->sibling;
-	} while (dev != &root);
+	}
 
 	return NULL;
 }
@@ -209,24 +224,58 @@
  * Walks up the device tree looking for a device of the specified type.
  * If it finds it, it returns it.  If not, it returns NULL.
  */
-const struct parisc_device *find_pa_parent_type(const struct parisc_device *dev, int type)
+const struct parisc_device *
+find_pa_parent_type(const struct parisc_device *padev, int type)
 {
+	const struct device *dev = &padev->dev;
 	while (dev != &root) {
-		if (dev->id.hw_type == type)
-			return dev;
+		struct parisc_device *candidate = to_parisc_device(dev);
+		if (candidate->id.hw_type == type)
+			return candidate;
 		dev = dev->parent;
 	}
 
 	return NULL;
 }
 
-static void
-get_node_path(struct parisc_device *dev, struct hardware_path *path)
+#ifdef CONFIG_PCI
+static inline int is_pci_dev(struct device *dev)
+{
+	return dev->bus == &pci_bus_type;
+}
+#else
+static inline int is_pci_dev(struct device *dev)
+{
+	return 0;
+}
+#endif
+
+/*
+ * get_node_path fills in @path with the firmware path to the device.
+ * Note that if @node is a parisc device, we don't fill in the 'mod' field.
+ * This is because both callers pass the parent and fill in the mod
+ * themselves.  If @node is a PCI device, we do fill it in, even though this
+ * is inconsistent.
+ */
+static void get_node_path(struct device *dev, struct hardware_path *path)
 {
 	int i = 5;
 	memset(&path->bc, -1, 6);
+
+	if (is_pci_dev(dev)) {
+		unsigned int devfn = to_pci_dev(dev)->devfn;
+		path->mod = PCI_FUNC(devfn);
+		path->bc[i--] = PCI_SLOT(devfn);
+		dev = dev->parent;
+	}
+
 	while (dev != &root) {
-		path->bc[i--] = dev->hw_path;
+		if (is_pci_dev(dev)) {
+			unsigned int devfn = to_pci_dev(dev)->devfn;
+			path->bc[i--] = PCI_SLOT(devfn) | (PCI_FUNC(devfn)<< 5);
+		} else if (dev->bus == &parisc_bus_type) {
+			path->bc[i--] = to_parisc_device(dev)->hw_path;
+		}
 		dev = dev->parent;
 	}
 }
@@ -256,7 +305,7 @@
 {
 	struct hardware_path path;
 
-	get_node_path(dev->parent, &path);
+	get_node_path(dev->dev.parent, &path);
 	path.mod = dev->hw_path;
 	return print_hwpath(&path, output);
 }
@@ -264,33 +313,17 @@
 
 #if defined(CONFIG_PCI) || defined(CONFIG_ISA)
 /**
- * get_pci_node_path - Returns hardware path for PCI devices
- * dev: The device to return the path for
- * output: Pointer to a previously-allocated array to place the path in.
+ * get_pci_node_path - Determines the hardware path for a PCI device
+ * @pdev: The device to return the path for
+ * @path: Pointer to a previously-allocated array to place the path in.
  *
  * This function fills in the hardware_path structure with the route to
  * the specified PCI device.  This structure is suitable for passing to
  * PDC calls.
  */
-void get_pci_node_path(struct pci_dev *dev, struct hardware_path *path)
+void get_pci_node_path(struct pci_dev *pdev, struct hardware_path *path)
 {
-	struct pci_bus *bus;
-	const struct parisc_device *padev;
-	int i = 5;
-
-	memset(&path->bc, -1, 6);
-	path->mod = PCI_FUNC(dev->devfn);
-	path->bc[i--] = PCI_SLOT(dev->devfn);
-	for (bus = dev->bus; bus->parent; bus = bus->parent) {
-		unsigned int devfn = bus->self->devfn;
-		path->bc[i--] = PCI_SLOT(devfn) | (PCI_FUNC(devfn) << 5);
-	}
-
-	padev = HBA_DATA(bus->bridge->platform_data)->dev;
-	while (padev != &root) {
-		path->bc[i--] = padev->hw_path;
-		padev = padev->parent;
-	}
+	get_node_path(&pdev->dev, path);
 }
 EXPORT_SYMBOL(get_pci_node_path);
 
@@ -314,19 +347,43 @@
 
 #endif /* defined(CONFIG_PCI) || defined(CONFIG_ISA) */
 
+static void setup_bus_id(struct parisc_device *padev)
+{
+	struct hardware_path path;
+	char *output = padev->dev.bus_id;
+	int i;
+
+	get_node_path(padev->dev.parent, &path);
 
-struct parisc_device * create_tree_node(char id, struct parisc_device *parent,
-		struct parisc_device **insert)
+	for (i = 0; i < 6; i++) {
+		if (path.bc[i] == -1)
+			continue;
+		output += sprintf(output, "%u:", (unsigned char) path.bc[i]);
+	}
+	sprintf(output, "%u", (unsigned char) padev->hw_path);
+}
+
+struct parisc_device * create_tree_node(char id, struct device *parent)
 {
 	struct parisc_device *dev = kmalloc(sizeof(*dev), GFP_KERNEL);
 	if (!dev)
 		return NULL;
+
 	memset(dev, 0, sizeof(*dev));
 	dev->hw_path = id;
 	dev->id.hw_type = HPHW_FAULTY;
-	dev->parent = parent;
-	dev->sibling = *insert;
-	*insert = dev;
+
+	dev->dev.parent = parent;
+	setup_bus_id(dev);
+
+	dev->dev.bus = &parisc_bus_type;
+	dev->dma_mask = 0xffffffffUL;	/* PARISC devices are 32-bit */
+
+	/* make the generic dma mask a pointer to the parisc one */
+	dev->dev.dma_mask = &dev->dma_mask;
+	dev->dev.coherent_dma_mask = dev->dma_mask;
+	device_register(&dev->dev);
+
 	return dev;
 }
 
@@ -338,36 +395,27 @@
  * Checks all the children of @parent for a matching @id.  If none
  * found, it allocates a new device and returns it.
  */
-struct parisc_device *
-alloc_tree_node(struct parisc_device *parent, char id)
+static struct parisc_device * alloc_tree_node(struct device *parent, char id)
 {
-	struct parisc_device *prev;
-	if ((!parent->child) || (parent->child->hw_path > id)) {
-		return create_tree_node(id, parent, &parent->child);
-	}
-
-	prev = parent->child;
-	if (prev->hw_path == id)
-		return prev;
+	struct device *dev;
 
-	while (prev->sibling && prev->sibling->hw_path < id) {
-		prev = prev->sibling;
+	list_for_each_entry(dev, &parent->children, node) {
+		struct parisc_device *padev = to_parisc_device(dev);
+		if (padev->hw_path == id)
+			return padev;
 	}
 
-	if ((prev->sibling) && (prev->sibling->hw_path == id))
-		return prev->sibling;
-
-	return create_tree_node(id, parent, &prev->sibling);
+	return create_tree_node(id, parent);
 }
 
-static struct parisc_device *find_parisc_device(struct hardware_path *modpath)
+static struct parisc_device *create_parisc_device(struct hardware_path *modpath)
 {
 	int i;
-	struct parisc_device *parent = &root;
+	struct device *parent = &root;
 	for (i = 0; i < 6; i++) {
 		if (modpath->bc[i] == -1)
 			continue;
-		parent = alloc_tree_node(parent, modpath->bc[i]);
+		parent = &alloc_tree_node(parent, modpath->bc[i])->dev;
 	}
 	return alloc_tree_node(parent, modpath->mod);
 }
@@ -389,7 +437,7 @@
 	if (status != PDC_OK)
 		return NULL;
 
-	dev = find_parisc_device(mod_path);
+	dev = create_parisc_device(mod_path);
 	if (dev->id.hw_type != HPHW_FAULTY) {
 		char p[64];
 		print_pa_hwpath(dev, p);
@@ -414,12 +462,37 @@
 
 static int parisc_generic_match(struct device *dev, struct device_driver *drv)
 {
-	return  match_device(to_parisc_driver(drv), to_parisc_device(dev));
+	return match_device(to_parisc_driver(drv), to_parisc_device(dev));
 }
 
+#define pa_dev_attr(name, field, format_string)				\
+static ssize_t name##_show(struct device *dev, char *buf)		\
+{									\
+	struct parisc_device *padev = to_parisc_device(dev);		\
+	return sprintf(buf, format_string, padev->field);		\
+}
+
+#define pa_dev_attr_id(field, format) pa_dev_attr(field, id.field, format)
+
+pa_dev_attr(irq, irq, "%u\n");
+pa_dev_attr_id(hw_type, "0x%02x\n");
+pa_dev_attr(rev, id.hversion_rev, "0x%x\n");
+pa_dev_attr_id(hversion, "0x%03x\n");
+pa_dev_attr_id(sversion, "0x%05x\n");
+
+static struct device_attribute parisc_device_attrs[] = {
+	__ATTR_RO(irq),
+	__ATTR_RO(hw_type),
+	__ATTR_RO(rev),
+	__ATTR_RO(hversion),
+	__ATTR_RO(sversion),
+	__ATTR_NULL,
+};
+
 struct bus_type parisc_bus_type = {
 	.name = "parisc",
 	.match = parisc_generic_match,
+	.dev_attrs = parisc_device_attrs,
 };
 
 /**
@@ -440,6 +513,104 @@
 	return 0;
 }
 
+/**
+ * match_pci_device - Matches a pci device against a given hardware path
+ * entry.
+ * @dev: the generic device (known to be contained by a pci_dev).
+ * @index: the current BC index
+ * @modpath: the hardware path.
+ * @return: true if the device matches the hardware path.
+ */
+static int match_pci_device(struct device *dev, int index,
+		struct hardware_path *modpath)
+{
+	struct pci_dev *pdev = to_pci_dev(dev);
+	int id;
+
+	if (index == 5) {
+		/* we are at the end of the path, and on the actual device */
+		unsigned int devfn = pdev->devfn;
+		return ((modpath->bc[5] == PCI_SLOT(devfn)) &&
+					(modpath->mod == PCI_FUNC(devfn)));
+	}
+
+	id = PCI_SLOT(pdev->devfn) | (PCI_FUNC(pdev->devfn) << 5);
+	return (modpath->bc[index] == id);
+}
+
+/**
+ * match_parisc_device - Matches a parisc device against a given hardware
+ * path entry.
+ * @dev: the generic device (known to be contained by a parisc_device).
+ * @index: the current BC index
+ * @modpath: the hardware path.
+ * @return: true if the device matches the hardware path.
+ */
+static int match_parisc_device(struct device *dev, int index,
+		struct hardware_path *modpath)
+{
+	struct parisc_device *curr = to_parisc_device(dev);
+	char id = (index == 6) ? modpath->mod : modpath->bc[index];
+
+	return (curr->hw_path == id);
+}
+
+/**
+ * parse_tree_node - returns a device entry in the iotree
+ * @parent: the parent node in the tree
+ * @index: the current BC index
+ * @modpath: the hardware_path struct to match a device against
+ * @return: The corresponding device if found, NULL otherwise.
+ *
+ * Checks all the children of @parent for a matching @id.  If none
+ * found, it returns NULL.
+ */
+static struct device *
+parse_tree_node(struct device *parent, int index, struct hardware_path *modpath)
+{
+	struct device *device;
+	 
+	list_for_each_entry(device, &parent->children, node) {
+		if (device->bus == &parisc_bus_type) {
+			if (match_parisc_device(device, index, modpath))
+				return device;
+		} else if (is_pci_dev(device)) {
+			if (match_pci_device(device, index, modpath))
+				return device;
+		} else if (device->bus == NULL) {
+			/* we are on a bus bridge */
+			struct device *new = parse_tree_node(device, index, modpath);
+			if (new)
+				return new;
+		}
+	}
+
+	return NULL;
+}
+
+/**
+ * hwpath_to_device - Finds the generic device corresponding to a given hardware path.
+ * @modpath: the hardware path.
+ * @return: The target device, NULL if not found.
+ */
+struct device *hwpath_to_device(struct hardware_path *modpath)
+{
+	int i;
+	struct device *parent = &root;
+	for (i = 0; i < 6; i++) {
+		if (modpath->bc[i] == -1)
+			continue;
+		parent = parse_tree_node(parent, i, modpath);
+		if (!parent)
+			return NULL;
+	}
+	if (is_pci_dev(parent)) /* pci devices already parse MOD */
+		return parent;
+	else
+		return parse_tree_node(parent, 6, modpath);
+}
+EXPORT_SYMBOL(hwpath_to_device);
+
 #define BC_PORT_MASK 0x8
 #define BC_LOWER_PORT 0x8
 
@@ -447,7 +618,7 @@
         ((dev->id.hw_type == HPHW_IOA) || (dev->id.hw_type == HPHW_BCPORT))
 
 #define IS_LOWER_PORT(dev) \
-        ((gsc_readl(&((struct bc_module *)dev->hpa)->io_status) \
+        ((gsc_readl(dev->hpa + offsetof(struct bc_module, io_status)) \
                 & BC_PORT_MASK) == BC_LOWER_PORT)
 
 #define MAX_NATIVE_DEVICES 64
@@ -456,11 +627,11 @@
 #define FLEX_MASK 	F_EXTEND(0xfffc0000)
 #define IO_IO_LOW	offsetof(struct bc_module, io_io_low)
 #define IO_IO_HIGH	offsetof(struct bc_module, io_io_high)
-#define READ_IO_IO_LOW(dev)  (unsigned long)(signed int)__raw_readl(dev->hpa + IO_IO_LOW)
-#define READ_IO_IO_HIGH(dev) (unsigned long)(signed int)__raw_readl(dev->hpa + IO_IO_HIGH)
+#define READ_IO_IO_LOW(dev)  (unsigned long)(signed int)gsc_readl(dev->hpa + IO_IO_LOW)
+#define READ_IO_IO_HIGH(dev) (unsigned long)(signed int)gsc_readl(dev->hpa + IO_IO_HIGH)
 
 static void walk_native_bus(unsigned long io_io_low, unsigned long io_io_high,
-                            struct parisc_device *parent);
+                            struct device *parent);
 
 void walk_lower_bus(struct parisc_device *dev)
 {
@@ -477,7 +648,7 @@
 		io_io_high = (READ_IO_IO_HIGH(dev)+ ~FLEX_MASK) & FLEX_MASK;
 	}
 
-	walk_native_bus(io_io_low, io_io_high, dev);
+	walk_native_bus(io_io_low, io_io_high, &dev->dev);
 }
 
 /**
@@ -493,7 +664,7 @@
  * keyboard ports).  This problem is not yet solved.
  */
 static void walk_native_bus(unsigned long io_io_low, unsigned long io_io_high,
-                            struct parisc_device *parent)
+                            struct device *parent)
 {
 	int i, devices_found = 0;
 	unsigned long hpa = io_io_low;
@@ -535,25 +706,6 @@
 			&root);
 }
 
-void fixup_child_irqs(struct parisc_device *parent, int base,
-			int (*choose_irq)(struct parisc_device *))
-{
-	struct parisc_device *dev;
-
-	if (!parent->child)
-		return;
-
-	for (dev = check_dev(parent->child); dev; dev = dev->sibling) {
-		int irq = choose_irq(dev);
-		if (irq > 0) {
-#ifdef __LP64__
-			irq += 32;
-#endif
-			dev->irq = base + irq;
-		}
-	}
-}
-
 static void print_parisc_device(struct parisc_device *dev)
 {
 	char hw_path[64];
@@ -573,68 +725,14 @@
 	printk("\n");
 }
 
-void print_subdevices(struct parisc_device *parent)
-{
-	struct parisc_device *dev;
-	for (dev = parent->child; dev != parent->sibling; dev = next_dev(dev)) {
-		print_parisc_device(dev);
-	}
-}
-
-
-/*
- * parisc_generic_device_register_recursive() - internal function to recursively
- * 	register all parisc devices
- */
-static void parisc_generic_device_register_recursive( struct parisc_device *dev )
-{
-	char tmp1[32];
-	
-	/* has this device been registered already ? */
-	if (dev->dev.dma_mask != NULL)
-		return;
-	
-	/* register all parents recursively */
-	if (dev->parent && dev->parent!=&root)
-		parisc_generic_device_register_recursive(dev->parent);
-	
-	/* set up the generic device tree for this */
-	snprintf(tmp1, sizeof(tmp1), "%d", dev->hw_path);
-	if (dev->parent && dev->parent != &root) {
-		struct parisc_device *ndev;
-		char tmp2[32];
-
-		dev->dev.parent = &dev->parent->dev;
-		for(ndev = dev->parent; ndev != &root;
-		    ndev = ndev->parent) {
-			snprintf(tmp2, sizeof(tmp2), "%d:%s",
-				 ndev->hw_path, tmp1);
-			strlcpy(tmp1, tmp2, sizeof(tmp1));
-		}
-	}
-
-	dev->dev.bus = &parisc_bus_type;
-	snprintf(dev->dev.bus_id, sizeof(dev->dev.bus_id), "parisc%s",
-		 tmp1);
-	/* make the generic dma mask a pointer to the parisc one */
-	dev->dev.dma_mask = &dev->dma_mask;
-	dev->dev.coherent_dma_mask = dev->dma_mask;
-	pr_debug("device_register(%s)\n", dev->dev.bus_id);
-	device_register(&dev->dev);
-}
-
-/*
- * parisc_generic_device_register() - register all parisc devices
+/**
+ * init_parisc_bus - Some preparation to be done before inventory
  */
-void parisc_generic_device_register(void)
+void init_parisc_bus(void)
 {
-	struct parisc_device *dev;
-	
 	bus_register(&parisc_bus_type);
-
-	for_each_padev(dev) {
-		parisc_generic_device_register_recursive( dev );
-	}
+	device_register(&root);
+	get_device(&root);
 }
 
 /**
diff -Nru a/arch/parisc/kernel/firmware.c b/arch/parisc/kernel/firmware.c
--- a/arch/parisc/kernel/firmware.c	2005-03-01 23:38:52 -08:00
+++ b/arch/parisc/kernel/firmware.c	2005-03-01 23:38:52 -08:00
@@ -11,6 +11,7 @@
  * Copyright 1999 The Puffin Group, (Alex deVries, David Kennedy)
  * Copyright 2003 Grant Grundler <grundler parisc-linux org>
  * Copyright 2003,2004 Ryan Bradetich <rbrad@parisc-linux.org>
+ * Copyright 2004 Thibaut VARENE <varenet@parisc-linux.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
@@ -69,7 +70,7 @@
 #include <asm/system.h>
 #include <asm/processor.h>	/* for boot_cpu_data */
 
-static spinlock_t pdc_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(pdc_lock);
 static unsigned long pdc_result[32] __attribute__ ((aligned (8)));
 static unsigned long pdc_result2[32] __attribute__ ((aligned (8)));
 
@@ -573,14 +574,118 @@
 }
 EXPORT_SYMBOL(pdc_lan_station_id);
 
+/**
+ * pdc_stable_read - Read data from Stable Storage.
+ * @staddr: Stable Storage address to access.
+ * @memaddr: The memory address where Stable Storage data shall be copied.
+ * @count: number of bytes to transfert. count is multiple of 4.
+ *
+ * This PDC call reads from the Stable Storage address supplied in staddr
+ * and copies count bytes to the memory address memaddr.
+ * The call will fail if staddr+count > PDC_STABLE size.
+ */
+int pdc_stable_read(unsigned long staddr, void *memaddr, unsigned long count)
+{
+       int retval;
+
+       spin_lock_irq(&pdc_lock);
+       retval = mem_pdc_call(PDC_STABLE, PDC_STABLE_READ, staddr,
+               __pa(pdc_result), count);
+       convert_to_wide(pdc_result);
+       memcpy(memaddr, pdc_result, count);
+       spin_unlock_irq(&pdc_lock);
+
+       return retval;
+}
+EXPORT_SYMBOL(pdc_stable_read);
+
+/**
+ * pdc_stable_write - Write data to Stable Storage.
+ * @staddr: Stable Storage address to access.
+ * @memaddr: The memory address where Stable Storage data shall be read from.
+ * @count: number of bytes to transfert. count is multiple of 4.
+ *
+ * This PDC call reads count bytes from the supplied memaddr address,
+ * and copies count bytes to the Stable Storage address staddr.
+ * The call will fail if staddr+count > PDC_STABLE size.
+ */
+int pdc_stable_write(unsigned long staddr, void *memaddr, unsigned long count)
+{
+       int retval;
+
+       spin_lock_irq(&pdc_lock);
+       memcpy(pdc_result, memaddr, count);
+       convert_to_wide(pdc_result);
+       retval = mem_pdc_call(PDC_STABLE, PDC_STABLE_WRITE, staddr,
+               __pa(pdc_result), count);
+       spin_unlock_irq(&pdc_lock);
+
+       return retval;
+}
+EXPORT_SYMBOL(pdc_stable_write);
+
+/**
+ * pdc_stable_get_size - Get Stable Storage size in bytes.
+ * @size: pointer where the size will be stored.
+ *
+ * This PDC call returns the number of bytes in the processor's Stable
+ * Storage, which is the number of contiguous bytes implemented in Stable
+ * Storage starting from staddr=0. size in an unsigned 64-bit integer
+ * which is a multiple of four.
+ */
+int pdc_stable_get_size(unsigned long *size)
+{
+       int retval;
+
+       spin_lock_irq(&pdc_lock);
+       retval = mem_pdc_call(PDC_STABLE, PDC_STABLE_RETURN_SIZE, __pa(pdc_result));
+       *size = pdc_result[0];
+       spin_unlock_irq(&pdc_lock);
+
+       return retval;
+}
+EXPORT_SYMBOL(pdc_stable_get_size);
+
+/**
+ * pdc_stable_verify_contents - Checks that Stable Storage contents are valid.
+ *
+ * This PDC call is meant to be used to check the integrity of the current
+ * contents of Stable Storage.
+ */
+int pdc_stable_verify_contents(void)
+{
+       int retval;
+
+       spin_lock_irq(&pdc_lock);
+       retval = mem_pdc_call(PDC_STABLE, PDC_STABLE_VERIFY_CONTENTS);
+       spin_unlock_irq(&pdc_lock);
+
+       return retval;
+}
+EXPORT_SYMBOL(pdc_stable_verify_contents);
+
+/**
+ * pdc_stable_initialize - Sets Stable Storage contents to zero and initialize
+ * the validity indicator.
+ *
+ * This PDC call will erase all contents of Stable Storage. Use with care!
+ */
+int pdc_stable_initialize(void)
+{
+       int retval;
+
+       spin_lock_irq(&pdc_lock);
+       retval = mem_pdc_call(PDC_STABLE, PDC_STABLE_INITIALIZE);
+       spin_unlock_irq(&pdc_lock);
+
+       return retval;
+}
+EXPORT_SYMBOL(pdc_stable_initialize);
 
 /**
  * pdc_get_initiator - Get the SCSI Interface Card params (SCSI ID, SDTR, SE or LVD)
  * @hwpath: fully bc.mod style path to the device.
- * @scsi_id: what someone told firmware the ID should be.
- * @period: time in cycles 
- * @width: 8 or 16-bit wide bus
- * @mode: 0,1,2 -> SE,HVD,LVD signalling mode
+ * @initiator: the array to return the result into
  *
  * Get the SCSI operational parameters from PDC.
  * Needed since HPUX never used BIOS or symbios card NVRAM.
@@ -591,8 +696,7 @@
  *    o cable too long (ie SE scsi 10Mhz won't support 6m length),
  *    o bus width exported is less than what the interface chip supports.
  */
-int pdc_get_initiator(struct hardware_path *hwpath, unsigned char *scsi_id,
-		unsigned long *period, char *width, char *mode)
+int pdc_get_initiator(struct hardware_path *hwpath, struct pdc_initiator *initiator)
 {
 	int retval;
 
@@ -604,44 +708,38 @@
 
 	retval = mem_pdc_call(PDC_INITIATOR, PDC_GET_INITIATOR, 
 			      __pa(pdc_result), __pa(hwpath));
-
 	if (retval < PDC_OK)
-		goto fail;
-
-	*scsi_id = (unsigned char) pdc_result[0];
+		goto out;
 
-	/* convert Bus speed in Mhz to period (in 1/10 ns) */
-	switch (pdc_result[1]) {
-		/*
-		 * case  0:   driver determines rate
-		 * case -1:   Settings are uninitialized.
-		 */
-		case  5:  *period = 2000; break;
-		case 10:  *period = 1000; break;
-		case 20:  *period = 500; break;
-		case 40:  *period = 250; break;
-		case 80:  *period = 125; break;
-		default: /* Do nothing */ break;
+	if (pdc_result[0] < 16) {
+		initiator->host_id = pdc_result[0];
+	} else {
+		initiator->host_id = -1;
 	}
 
-	/* 
-	 * pdc_result[2]	PDC suggested SCSI id
-	 * pdc_result[3]	PDC suggested SCSI rate
+	/*
+	 * Sprockets and Piranha return 20 or 40 (MT/s).  Prelude returns
+	 * 1, 2, 5 or 10 for 5, 10, 20 or 40 MT/s, respectively
 	 */
+	switch (pdc_result[1]) {
+		case  1: initiator->factor = 50; break;
+		case  2: initiator->factor = 25; break;
+		case  5: initiator->factor = 12; break;
+		case 25: initiator->factor = 10; break;
+		case 20: initiator->factor = 12; break;
+		case 40: initiator->factor = 10; break;
+		default: initiator->factor = -1; break;
+	}
 
 	if (IS_SPROCKETS()) {
-		/* 0 == 8-bit, 1 == 16-bit */
-		*width = (char) pdc_result[4];
-
-		/* ...in case someone needs it in the future.
-		 * sym53c8xx.c comments say it can't autodetect
-		 * for 825/825A/875 chips.
-		 *	0 == SE, 1 == HVD, 2 == LVD
-		 */
-		*mode = (char) pdc_result[5]; 
+		initiator->width = pdc_result[4];
+		initiator->mode = pdc_result[5];
+	} else {
+		initiator->width = -1;
+		initiator->mode = -1;
 	}
 
- fail:
+ out:
 	spin_unlock_irq(&pdc_lock);
 	return (retval >= PDC_OK);
 }
diff -Nru a/arch/parisc/kernel/inventory.c b/arch/parisc/kernel/inventory.c
--- a/arch/parisc/kernel/inventory.c	2005-03-01 23:38:52 -08:00
+++ b/arch/parisc/kernel/inventory.c	2005-03-01 23:38:52 -08:00
@@ -518,7 +518,7 @@
 }
 
 /**
- * do_system_map_inventory - Retrieve firmware devices via SYSTEM_MAP.
+ * system_map_inventory - Retrieve firmware devices via SYSTEM_MAP.
  *
  * This function attempts to retrieve and register all the devices firmware
  * knows about via the SYSTEM_MAP PDC call.
@@ -528,16 +528,18 @@
 	int i;
 	long status = PDC_OK;
     
-	for (i = 0; status != PDC_BAD_PROC && status != PDC_NE_MOD; i++) {
+	for (i = 0; i < 256; i++) {
 		struct parisc_device *dev;
 		struct pdc_system_map_mod_info module_result;
 		struct pdc_module_path module_path;
 
 		status = pdc_system_map_find_mods(&module_result,
 				&module_path, i);
+		if ((status == PDC_BAD_PROC) || (status == PDC_NE_MOD))
+			break;
 		if (status != PDC_OK)
 			continue;
-		
+
 		dev = alloc_pa_dev(module_result.mod_addr, &module_path.path);
 		if (!dev)
 			continue;
@@ -584,10 +586,10 @@
 
 void __init do_device_inventory(void)
 {
-	extern void parisc_generic_device_register(void);
-
 	printk(KERN_INFO "Searching for devices...\n");
 
+	init_parisc_bus();
+
 	switch (pdc_type) {
 
 	case PDC_TYPE_PAT:
@@ -605,7 +607,6 @@
 	default:
 		panic("Unknown PDC type!\n");
 	}
-	parisc_generic_device_register();
 	printk(KERN_INFO "Found devices:\n");
 	print_parisc_devices();
 }
diff -Nru a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c
--- a/arch/parisc/kernel/irq.c	2005-03-01 23:38:55 -08:00
+++ b/arch/parisc/kernel/irq.c	2005-03-01 23:38:55 -08:00
@@ -54,21 +54,19 @@
 #define DBG_IRQ(irq, x)	do { } while (0)
 #endif /* DEBUG_IRQ */
 
-#define EIEM_MASK(irq)       (1UL<<(MAX_CPU_IRQ-IRQ_OFFSET(irq)))
+#define EIEM_MASK(irq)       (1UL<<(CPU_IRQ_MAX - irq))
 
 /* Bits in EIEM correlate with cpu_irq_action[].
 ** Numbered *Big Endian*! (ie bit 0 is MSB)
 */
 static volatile unsigned long cpu_eiem = 0;
 
-static spinlock_t irq_lock = SPIN_LOCK_UNLOCKED;  /* protect IRQ regions */
-
 static void cpu_set_eiem(void *info)
 {
 	set_eiem((unsigned long) info);
 }
 
-static inline void disable_cpu_irq(void *unused, int irq)
+static inline void cpu_disable_irq(unsigned int irq)
 {
 	unsigned long eirr_bit = EIEM_MASK(irq);
 
@@ -76,7 +74,7 @@
         on_each_cpu(cpu_set_eiem, (void *) cpu_eiem, 1, 1);
 }
 
-static void enable_cpu_irq(void *unused, int irq)
+static void cpu_enable_irq(unsigned int irq)
 {
 	unsigned long eirr_bit = EIEM_MASK(irq);
 
@@ -85,172 +83,56 @@
         on_each_cpu(cpu_set_eiem, (void *) cpu_eiem, 1, 1);
 }
 
-/* mask and disable are the same at the CPU level
-** Difference is enable clears pending interrupts
-*/
-#define mask_cpu_irq	disable_cpu_irq
-
-static inline void unmask_cpu_irq(void *unused, int irq)
+static unsigned int cpu_startup_irq(unsigned int irq)
 {
-	unsigned long eirr_bit = EIEM_MASK(irq);
-	cpu_eiem |= eirr_bit;
-	/* NOTE: sending an IPI will cause do_cpu_irq_mask() to
-	** handle *any* unmasked pending interrupts.
-	** ie We don't need to check for pending interrupts here.
-	*/
-        on_each_cpu(cpu_set_eiem, (void *) cpu_eiem, 1, 1);
+	cpu_enable_irq(irq);
+	return 0;
 }
 
-/*
- * XXX cpu_irq_actions[] will become 2 dimensional for per CPU EIR support.
- * correspond changes needed in:
- * 	processor_probe()	initialize additional action arrays
- * 	request_irq()		handle CPU IRQ region specially
- * 	do_cpu_irq_mask()	index into the matching irq_action array.
- */
-struct irqaction cpu_irq_actions[IRQ_PER_REGION] = {
-	[IRQ_OFFSET(TIMER_IRQ)]	= {
-					.handler = timer_interrupt,
-					.name = "timer",
-				},
-#ifdef CONFIG_SMP
-	[IRQ_OFFSET(IPI_IRQ)]	= {
-					.handler = ipi_interrupt,
-					.name = "IPI",
-				},
-#endif
-};
+void no_ack_irq(unsigned int irq) { }
+void no_end_irq(unsigned int irq) { }
 
-
-struct irq_region cpu0_irq_region = {
-	.ops	= {
-			.disable_irq	= disable_cpu_irq,
-			.enable_irq	= enable_cpu_irq,
-			.mask_irq	= unmask_cpu_irq,
-			.unmask_irq	= unmask_cpu_irq
-	},
-	.data	= {
-			.dev		= &cpu_data[0],
-			.name		= "PARISC-CPU",
-			.irqbase 	= IRQ_FROM_REGION(CPU_IRQ_REGION),
-	},
-	.action	= cpu_irq_actions,
-};
-
-struct irq_region *irq_region[NR_IRQ_REGS] = {
-	[ 0 ]              = NULL, /* reserved for EISA, else causes data page fault (aka code 15) */
-	[ CPU_IRQ_REGION ] = &cpu0_irq_region,
+static struct hw_interrupt_type cpu_interrupt_type = {
+	.typename	= "CPU",
+	.startup	= cpu_startup_irq,
+	.shutdown	= cpu_disable_irq,
+	.enable		= cpu_enable_irq,
+	.disable	= cpu_disable_irq,
+	.ack		= no_ack_irq,
+	.end		= no_end_irq,
+//	.set_affinity	= cpu_set_affinity_irq,
 };
 
-
-/*
-** Generic interfaces that device drivers can use:
-**    mask_irq()	block IRQ
-**    unmask_irq()	re-enable IRQ and trigger if IRQ is pending
-**    disable_irq()	block IRQ
-**    enable_irq()	clear pending and re-enable IRQ
-*/
-
-void mask_irq(int irq)
-{
-	struct irq_region *region;
-
-	DBG_IRQ(irq, ("mask_irq(%d) %d+%d eiem 0x%lx\n", irq,
-				IRQ_REGION(irq), IRQ_OFFSET(irq), cpu_eiem));
-	irq = irq_canonicalize(irq);
-	region = irq_region[IRQ_REGION(irq)];
-	if (region->ops.mask_irq)
-		region->ops.mask_irq(region->data.dev, IRQ_OFFSET(irq));
-}
-
-void unmask_irq(int irq)
-{
-	struct irq_region *region;
-
-	DBG_IRQ(irq, ("unmask_irq(%d) %d+%d eiem 0x%lx\n", irq,
-				IRQ_REGION(irq), IRQ_OFFSET(irq), cpu_eiem));
-	irq = irq_canonicalize(irq);
-	region = irq_region[IRQ_REGION(irq)];
-	if (region->ops.unmask_irq)
-		region->ops.unmask_irq(region->data.dev, IRQ_OFFSET(irq));
-}
-
-void disable_irq(int irq)
-{
-	struct irq_region *region;
-
-	DBG_IRQ(irq, ("disable_irq(%d) %d+%d eiem 0x%lx\n", irq,
-				IRQ_REGION(irq), IRQ_OFFSET(irq), cpu_eiem));
-	irq = irq_canonicalize(irq);
-	region = irq_region[IRQ_REGION(irq)];
-	if (region->ops.disable_irq)
-		region->ops.disable_irq(region->data.dev, IRQ_OFFSET(irq));
-	else
-		BUG();
-}
-EXPORT_SYMBOL(disable_irq);
-
-void enable_irq(int irq)
-{
-	struct irq_region *region;
-
-	DBG_IRQ(irq, ("enable_irq(%d) %d+%d EIRR 0x%lx EIEM 0x%lx\n", irq,
-				IRQ_REGION(irq), IRQ_OFFSET(irq), mfctl(23), mfctl(15)));
-	irq = irq_canonicalize(irq);
-	region = irq_region[IRQ_REGION(irq)];
-
-	if (region->ops.enable_irq)
-		region->ops.enable_irq(region->data.dev, IRQ_OFFSET(irq));
-	else
-		BUG();
-}
-EXPORT_SYMBOL(enable_irq);
-
 int show_interrupts(struct seq_file *p, void *v)
 {
-#ifdef CONFIG_PROC_FS
-	unsigned int regnr = *(loff_t *) v, i = 0;
+	int i = *(loff_t *) v, j;
+	unsigned long flags;
 
-	if (regnr == 0) {
-		seq_puts(p, "     ");
-#ifdef CONFIG_SMP
-		for (i = 0; i < NR_CPUS; i++)
-			if (cpu_online(i))
-#endif
-				seq_printf(p, "      CPU%02d ", i);
+	if (i == 0) {
+		seq_puts(p, "    ");
+		for_each_online_cpu(j)
+			seq_printf(p, "       CPU%d", j);
 
 #ifdef PARISC_IRQ_CR16_COUNTS
-		seq_printf(p, "[min/avg/max] (CPU cycle counts)");
+		seq_printf(p, " [min/avg/max] (CPU cycle counts)");
 #endif
 		seq_putc(p, '\n');
 	}
 
-	/* We don't need *irqsave lock variants since this is
-	** only allowed to change while in the base context.
-	*/
-	spin_lock(&irq_lock);
-	if (regnr < NR_IRQ_REGS) {
-	    struct irq_region *region = irq_region[regnr];
-
-            if (!region || !region->action)
-		    goto skip;
-
-	    for (i = 0; i <= MAX_CPU_IRQ; i++) {
-		struct irqaction *action = &region->action[i];
-		unsigned int irq_no = IRQ_FROM_REGION(regnr) + i;
-		int j = 0;
-		if (!action->handler)
-			continue;
-
-		seq_printf(p, "%3d: ", irq_no);
+	if (i < NR_IRQS) {
+		spin_lock_irqsave(&irq_desc[i].lock, flags);
+		struct irqaction *action = irq_desc[i].action;
+		if (!action)
+			goto skip;
+		seq_printf(p, "%3d: ", i);
 #ifdef CONFIG_SMP
-		for (; j < NR_CPUS; j++)
-			if (cpu_online(j))
+		for_each_online_cpu(j)
+			seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+#else
+		seq_printf(p, "%10u ", kstat_irqs(i));
 #endif
-		  seq_printf(p, "%10u ", kstat_cpu(j).irqs[irq_no]);
 
-		seq_printf(p, " %14s",
-			    region->data.name ? region->data.name : "N/A");
+		seq_printf(p, " %14s", irq_desc[i].handler->typename);
 #ifndef PARISC_IRQ_CR16_COUNTS
 		seq_printf(p, "  %s", action->name);
 
@@ -281,12 +163,10 @@
 #endif
 
 		seq_putc(p, '\n');
-	    }
+ skip:
+		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
 	}
-  skip:
-	spin_unlock(&irq_lock);
 
-#endif	/* CONFIG_PROC_FS */
 	return 0;
 }
 
@@ -300,34 +180,42 @@
 ** Then use that to get the Transaction address and data.
 */
 
-int
-txn_alloc_irq(void)
+int cpu_claim_irq(unsigned int irq, struct hw_interrupt_type *type, void *data)
 {
-	int irq;
-
-	/* never return irq 0 cause that's the interval timer */
-	for (irq = 1; irq <= MAX_CPU_IRQ; irq++) {
-		if (cpu_irq_actions[irq].handler == NULL) {
-			return (IRQ_FROM_REGION(CPU_IRQ_REGION) + irq);
-		}
+	if (irq_desc[irq].action)
+		return -EBUSY;
+	if (irq_desc[irq].handler != &cpu_interrupt_type)
+		return -EBUSY;
+
+	if (type) {
+		irq_desc[irq].handler = type;
+		irq_desc[irq].handler_data = data;
+		cpu_interrupt_type.enable(irq);
 	}
+	return 0;
+}
 
-	/* unlikely, but be prepared */
-	return -1;
+int txn_claim_irq(int irq)
+{
+	return cpu_claim_irq(irq, NULL, NULL) ? -1 : irq;
 }
 
-int
-txn_claim_irq(int irq)
+int txn_alloc_irq(void)
 {
-	if (irq_region[IRQ_REGION(irq)]->action[IRQ_OFFSET(irq)].handler ==NULL)
+	int irq;
+
+	/* never return irq 0 cause that's the interval timer */
+	for (irq = CPU_IRQ_BASE + 1; irq <= CPU_IRQ_MAX; irq++) {
+		if (cpu_claim_irq(irq, NULL, NULL) < 0)
+			continue;
 		return irq;
+	}
 
 	/* unlikely, but be prepared */
 	return -1;
 }
 
-unsigned long
-txn_alloc_addr(int virt_irq)
+unsigned long txn_alloc_addr(int virt_irq)
 {
 	static int next_cpu = -1;
 
@@ -364,68 +252,20 @@
 ** I/O subsystem supports more bits than PA2.0 has. The first
 ** case is the problem.
 */
-unsigned int
-txn_alloc_data(int virt_irq, unsigned int bits_wide)
+unsigned int txn_alloc_data(int virt_irq, unsigned int bits_wide)
 {
 	/* XXX FIXME : bits_wide indicates how wide the transaction
 	** data is allowed to be...we may need a different virt_irq
 	** if this one won't work. Another reason to index virtual
 	** irq's into a table which can manage CPU/IRQ bit separately.
 	*/
-	if (IRQ_OFFSET(virt_irq) > (1 << (bits_wide -1)))
-	{
+	if ((virt_irq - CPU_IRQ_BASE) > (1 << (bits_wide - 1))) {
 		panic("Sorry -- didn't allocate valid IRQ for this device\n");
 	}
 
-	return (IRQ_OFFSET(virt_irq));
+	return virt_irq - CPU_IRQ_BASE;
 }
 
-void do_irq(struct irqaction *action, int irq, struct pt_regs * regs)
-{
-	int cpu = smp_processor_id();
-
-	irq_enter();
-	++kstat_cpu(cpu).irqs[irq];
-
-	DBG_IRQ(irq, ("do_irq(%d) %d+%d eiem 0x%lx\n", irq, IRQ_REGION(irq), IRQ_OFFSET(irq), cpu_eiem));
-
-	for (; action; action = action->next) {
-#ifdef PARISC_IRQ_CR16_COUNTS
-		unsigned long cr_start = mfctl(16);
-#endif
-
-		if (action->handler == NULL) {
-			if (IRQ_REGION(irq) == EISA_IRQ_REGION && irq_region[EISA_IRQ_REGION]) {
-				/* were we called due to autodetecting (E)ISA irqs ? */
-				unsigned int *status;
-				status = &irq_region[EISA_IRQ_REGION]->data.status[IRQ_OFFSET(irq)];
-				if (*status & IRQ_AUTODETECT) {
-					*status &= ~IRQ_WAITING;
-					continue; 
-				}
-			}
-			printk(KERN_ERR "IRQ:  CPU:%d No handler for IRQ %d !\n", cpu, irq);
-			continue;
-		}
-
-		action->handler(irq, action->dev_id, regs);
-
-#ifdef PARISC_IRQ_CR16_COUNTS
-		{
-			unsigned long cr_end = mfctl(16);
-			unsigned long tmp = cr_end - cr_start;
-			/* check for roll over */
-			cr_start = (cr_end < cr_start) ?  -(tmp) : (tmp);
-		}
-		action->cr16_hist[action->cr16_idx++] = (int) cr_start;
-		action->cr16_idx &= PARISC_CR16_HIST_SIZE - 1;
-#endif
-	}
-
-	irq_exit();
-}
-
-
 /* ONLY called from entry.S:intr_extint() */
 void do_cpu_irq_mask(struct pt_regs *regs)
 {
@@ -449,9 +289,12 @@
 	 * 3) Limit the number of times we loop to make sure other
 	 *    processing can occur.
 	 */
-	while ((eirr_val = (mfctl(23) & cpu_eiem)) && --i) {
-		unsigned long bit = (1UL<<MAX_CPU_IRQ);
+	for (;;) {
+		unsigned long bit = (1UL << (BITS_PER_LONG - 1));
 		unsigned int irq;
+		eirr_val = mfctl(23) & cpu_eiem;
+		if (!eirr_val || !i--)
+			break;
 
 		mtctl(eirr_val, 23); /* reset bits we are going to process */
 
@@ -461,408 +304,52 @@
 #endif
 
 		/* Work our way from MSb to LSb...same order we alloc EIRs */
-		for (irq = 0; eirr_val && bit; bit>>=1, irq++)
-		{
+		for (irq = TIMER_IRQ; eirr_val && bit; bit>>=1, irq++) {
 			if (!(bit & eirr_val & cpu_eiem))
 				continue;
 
 			/* clear bit in mask - can exit loop sooner */
 			eirr_val &= ~bit;
 
-			do_irq(&cpu_irq_actions[irq], TIMER_IRQ+irq, regs);
+			__do_IRQ(irq, regs);
 		}
 	}
 	set_eiem(cpu_eiem);
 }
 
 
-/* Called from second level IRQ regions: eg dino or iosapic. */
-void do_irq_mask(unsigned long mask, struct irq_region *region, struct pt_regs *regs)
-{
-	unsigned long bit;
-	unsigned int irq;
-
-#ifdef DEBUG_IRQ
-	if (mask != (1L<<MAX_CPU_IRQ))
-	    printk(KERN_DEBUG "do_irq_mask %08lx %p %p\n", mask, region, regs);
-#endif
-
-	for (bit = (1L<<MAX_CPU_IRQ), irq = 0; mask && bit; bit>>=1, irq++) {
-		unsigned int irq_num;
-		if (!(bit&mask))
-			continue;
-
-		mask &= ~bit;	/* clear bit in mask - can exit loop sooner */
-		irq_num = region->data.irqbase + irq;
-
-		mask_irq(irq_num);
-		do_irq(&region->action[irq], irq_num, regs);
-		unmask_irq(irq_num);
-	}
-}
-
-
-static inline int find_free_region(void)
-{
-	int irqreg;
-
-	for (irqreg=1; irqreg <= (NR_IRQ_REGS); irqreg++) {
-		if (irq_region[irqreg] == NULL)
-			return irqreg;
-	}
-
-	return 0;
-}
-
-
-/*****
- * alloc_irq_region - allocate/init a new IRQ region
- * @count: number of IRQs in this region.
- * @ops: function table with request/release/mask/unmask/etc.. entries.
- * @name: name of region owner for /proc/interrupts output.
- * @dev: private data to associate with the new IRQ region.
- *
- * Every IRQ must become a MMIO write to the CPU's EIRR in
- * order to get CPU service. The IRQ region represents the
- * number of unique events the region handler can (or must)
- * identify. For PARISC CPU, that's the width of the EIR Register.
- * IRQ regions virtualize IRQs (eg EISA or PCI host bus controllers)
- * for line based devices.
- */
-struct irq_region *alloc_irq_region( int count, struct irq_region_ops *ops,
-					const char *name, void *dev)
-{
-	struct irq_region *region;
-	int index;
-
-	index = find_free_region();
-	if (index == 0) {
-		printk(KERN_ERR "Maximum number of irq regions exceeded. Increase NR_IRQ_REGS!\n");
-		return NULL;
-	}
-
-	if ((IRQ_REGION(count-1)))
-		return NULL;
-
-	if (count < IRQ_PER_REGION) {
-	    DBG_IRQ(0, ("alloc_irq_region() using minimum of %d irq lines for %s (%d)\n",
-			IRQ_PER_REGION, name, count));
-	    count = IRQ_PER_REGION;
-	}
-
-	/* if either mask *or* unmask is set, both have to be set. */
-	if((ops->mask_irq || ops->unmask_irq) &&
-		!(ops->mask_irq && ops->unmask_irq))
-			return NULL;
-
-	/* ditto for enable/disable */
-	if( (ops->disable_irq || ops->enable_irq) &&
-		!(ops->disable_irq && ops->enable_irq) )
-			return NULL;
-
-	region = kmalloc(sizeof(*region), GFP_ATOMIC);
-	if (!region)
-		return NULL;
-	memset(region, 0, sizeof(*region));
-
-	region->action = kmalloc(count * sizeof(*region->action), GFP_ATOMIC);
-	if (!region->action) {
-		kfree(region);
-		return NULL;
-	}
-	memset(region->action, 0, count * sizeof(*region->action));
-
-	region->ops = *ops;
-	region->data.irqbase = IRQ_FROM_REGION(index);
-	region->data.name = name;
-	region->data.dev = dev;
-
-	irq_region[index] = region;
-
-	return irq_region[index];
-}
-
-/* FIXME: SMP, flags, bottom halves, rest */
-
-int request_irq(unsigned int irq,
-		irqreturn_t (*handler)(int, void *, struct pt_regs *),
-		unsigned long irqflags,
-		const char * devname,
-		void *dev_id)
-{
-	struct irqaction * action;
+static struct irqaction timer_action = {
+	.handler = timer_interrupt,
+	.name = "timer",
+};
 
-#if 0
-	printk(KERN_INFO "request_irq(%d, %p, 0x%lx, %s, %p)\n",irq, handler, irqflags, devname, dev_id);
+#ifdef CONFIG_SMP
+static struct irqaction ipi_action = {
+	.handler = ipi_interrupt,
+	.name = "IPI",
+};
 #endif
 
-	irq = irq_canonicalize(irq);
-	/* request_irq()/free_irq() may not be called from interrupt context. */
-	if (in_interrupt())
-		BUG();
-
-	if (!handler) {
-		printk(KERN_ERR "request_irq(%d,...): Augh! No handler for irq!\n",
-			irq);
-		return -EINVAL;
-	}
-
-	if (irq_region[IRQ_REGION(irq)] == NULL) {
-		/*
-		** Bug catcher for drivers which use "char" or u8 for
-		** the IRQ number. They lose the region number which
-		** is in pcidev->irq (an int).
-		*/
-		printk(KERN_ERR "%p (%s?) called request_irq with an invalid irq %d\n",
-			__builtin_return_address(0), devname, irq);
-		return -EINVAL;
-	}
-
-	spin_lock(&irq_lock);
-	action = &(irq_region[IRQ_REGION(irq)]->action[IRQ_OFFSET(irq)]);
-
-	/* First one is preallocated. */
-	if (action->handler) {
-		/* But it's in use...find the tail and allocate a new one */
-		while (action->next)
-			action = action->next;
-
-		action->next = kmalloc(sizeof(*action), GFP_ATOMIC);
-		memset(action->next, 0, sizeof(*action));
-
-		action = action->next;
-	}
-
-	if (!action) {
-		spin_unlock(&irq_lock);
-		printk(KERN_ERR "request_irq(): Augh! No action!\n") ;
-		return -ENOMEM;
-	}
-
-	action->handler = handler;
-	action->flags = irqflags;
-	cpus_clear(action->mask);
-	action->name = devname;
-	action->next = NULL;
-	action->dev_id = dev_id;
-	spin_unlock(&irq_lock);
-
-	enable_irq(irq);
-	return 0;
-}
-
-EXPORT_SYMBOL(request_irq);
-
-void free_irq(unsigned int irq, void *dev_id)
+static void claim_cpu_irqs(void)
 {
-	struct irqaction *action, **p;
-
-	/* See comments in request_irq() about interrupt context */
-	irq = irq_canonicalize(irq);
-	
-	if (in_interrupt()) BUG();
-
-	spin_lock(&irq_lock);
-	action = &irq_region[IRQ_REGION(irq)]->action[IRQ_OFFSET(irq)];
-
-	if (action->dev_id == dev_id) {
-		if (action->next == NULL) {
-			action->handler = NULL;
-		} else {
-			memcpy(action, action->next, sizeof(*action));
-		}
-
-		spin_unlock(&irq_lock);
-		return;
-	}
-
-	p = &action->next;
-	action = action->next;
-
-	for (; (action = *p) != NULL; p = &action->next) {
-		if (action->dev_id != dev_id)
-			continue;
-
-		/* Found it - now free it */
-		*p = action->next;
-		kfree(action);
-
-		spin_unlock(&irq_lock);
-		return;
+	int i;
+	for (i = CPU_IRQ_BASE; i <= CPU_IRQ_MAX; i++) {
+		irq_desc[i].handler = &cpu_interrupt_type;
 	}
 
-	spin_unlock(&irq_lock);
-	printk(KERN_ERR "Trying to free free IRQ%d\n",irq);
-}
-
-EXPORT_SYMBOL(free_irq);
-
-
+	irq_desc[TIMER_IRQ].action = &timer_action;
+	irq_desc[TIMER_IRQ].status |= IRQ_PER_CPU;
 #ifdef CONFIG_SMP
-void synchronize_irq(unsigned int irqnum)
-{
-	while (in_irq()) ;
-}
-EXPORT_SYMBOL(synchronize_irq);
+	irq_desc[IPI_IRQ].action = &ipi_action;
+	irq_desc[IPI_IRQ].status = IRQ_PER_CPU;
 #endif
-
-
-/*
- * IRQ autodetection code..
- *
- * This depends on the fact that any interrupt that
- * comes in on to an unassigned handler will get stuck
- * with "IRQ_WAITING" cleared and the interrupt
- * disabled.
- */
-
-static DECLARE_MUTEX(probe_sem);
-
-/**
- *	probe_irq_on	- begin an interrupt autodetect
- *
- *	Commence probing for an interrupt. The interrupts are scanned
- *	and a mask of potential interrupt lines is returned.
- *
- */
-
-/* TODO: spin_lock_irq(desc->lock -> irq_lock) */
-
-unsigned long probe_irq_on(void)
-{
-	unsigned int i;
-	unsigned long val;
-	unsigned long delay;
-	struct irq_region *region;
-
-	/* support for irq autoprobing is limited to EISA (irq region 0) */
-	region = irq_region[EISA_IRQ_REGION];
-	if (!EISA_bus || !region)
-		return 0;
-
-	down(&probe_sem);
-
-	/*
-	 * enable any unassigned irqs
-	 * (we must startup again here because if a longstanding irq
-	 * happened in the previous stage, it may have masked itself)
-	 */
-	for (i = EISA_MAX_IRQS-1; i > 0; i--) {
-		struct irqaction *action;
-		
-		spin_lock_irq(&irq_lock);
-		action = region->action + i;
-		if (!action->handler) {
-			region->data.status[i] |= IRQ_AUTODETECT | IRQ_WAITING;
-			region->ops.enable_irq(region->data.dev,i);
-		}
-		spin_unlock_irq(&irq_lock);
-	}
-
-	/*
-	 * Wait for spurious interrupts to trigger
-	 */
-	for (delay = jiffies + HZ/10; time_after(delay, jiffies); )
-		/* about 100ms delay */ barrier();
-
-	/*
-	 * Now filter out any obviously spurious interrupts
-	 */
-	val = 0;
-	for (i = 0; i < EISA_MAX_IRQS; i++) {
-		unsigned int status;
-
-		spin_lock_irq(&irq_lock);
-		status = region->data.status[i];
-
-		if (status & IRQ_AUTODETECT) {
-			/* It triggered already - consider it spurious. */
-			if (!(status & IRQ_WAITING)) {
-				region->data.status[i] = status & ~IRQ_AUTODETECT;
-				region->ops.disable_irq(region->data.dev,i);
-			} else
-				if (i < BITS_PER_LONG)
-					val |= (1 << i);
-		}
-		spin_unlock_irq(&irq_lock);
-	}
-
-	return val;
-}
-
-EXPORT_SYMBOL(probe_irq_on);
-
-/*
- * Return the one interrupt that triggered (this can
- * handle any interrupt source).
- */
-
-/**
- *	probe_irq_off	- end an interrupt autodetect
- *	@val: mask of potential interrupts (unused)
- *
- *	Scans the unused interrupt lines and returns the line which
- *	appears to have triggered the interrupt. If no interrupt was
- *	found then zero is returned. If more than one interrupt is
- *	found then minus the first candidate is returned to indicate
- *	their is doubt.
- *
- *	The interrupt probe logic state is returned to its previous
- *	value.
- *
- *	BUGS: When used in a module (which arguably shouldnt happen)
- *	nothing prevents two IRQ probe callers from overlapping. The
- *	results of this are non-optimal.
- */
- 
-int probe_irq_off(unsigned long val)
-{
-        struct irq_region *region;
-	int i, irq_found, nr_irqs;
-
-        /* support for irq autoprobing is limited to EISA (irq region 0) */
-        region = irq_region[EISA_IRQ_REGION];
-        if (!EISA_bus || !region)
-		return 0;
-
-	nr_irqs = 0;
-	irq_found = 0;
-	for (i = 0; i < EISA_MAX_IRQS; i++) {
-		unsigned int status;
-		
-		spin_lock_irq(&irq_lock);
-		status = region->data.status[i];
-
-                if (status & IRQ_AUTODETECT) {
-			if (!(status & IRQ_WAITING)) {
-				if (!nr_irqs)
-					irq_found = i;
-				nr_irqs++;
-			}
-			region->ops.disable_irq(region->data.dev,i);
-			region->data.status[i] = status & ~IRQ_AUTODETECT;
-		}
-		spin_unlock_irq(&irq_lock);
-	}
-	up(&probe_sem);
-
-	if (nr_irqs > 1)
-		irq_found = -irq_found;
-	return irq_found;
-}
-
-EXPORT_SYMBOL(probe_irq_off);
-
-unsigned int probe_irq_mask(unsigned long irqs)
-{
-	return 0;
 }
-EXPORT_SYMBOL(probe_irq_mask);
 
 void __init init_IRQ(void)
 {
 	local_irq_disable();	/* PARANOID - should already be disabled */
 	mtctl(~0UL, 23);	/* EIRR : clear all pending external intr */
+	claim_cpu_irqs();
 #ifdef CONFIG_SMP
 	if (!cpu_eiem)
 		cpu_eiem = EIEM_MASK(IPI_IRQ) | EIEM_MASK(TIMER_IRQ);
@@ -873,9 +360,14 @@
 
 }
 
-#ifdef CONFIG_PROC_FS
-/* called from kernel/sysctl.c:sysctl_init() */
-void __init init_irq_proc(void)
+void hw_resend_irq(struct hw_interrupt_type *type, unsigned int irq)
 {
+	/* XXX: Needs to be written.  We managed without it so far, but
+	 * we really ought to write it.
+	 */
+}
+
+void ack_bad_irq(unsigned int irq)
+{
+	printk("unexpected IRQ %d\n", irq);
 }
-#endif
diff -Nru a/arch/parisc/kernel/parisc_ksyms.c b/arch/parisc/kernel/parisc_ksyms.c
--- a/arch/parisc/kernel/parisc_ksyms.c	2005-03-01 23:39:17 -08:00
+++ b/arch/parisc/kernel/parisc_ksyms.c	2005-03-01 23:39:17 -08:00
@@ -87,9 +87,9 @@
 #include <asm/io.h>
 EXPORT_SYMBOL(__ioremap);
 EXPORT_SYMBOL(iounmap);
-EXPORT_SYMBOL(__memcpy_toio);
-EXPORT_SYMBOL(__memcpy_fromio);
-EXPORT_SYMBOL(__memset_io);
+EXPORT_SYMBOL(memcpy_toio);
+EXPORT_SYMBOL(memcpy_fromio);
+EXPORT_SYMBOL(memset_io);
 
 #include <asm/unistd.h>
 EXPORT_SYMBOL(sys_open);
diff -Nru a/arch/parisc/kernel/processor.c b/arch/parisc/kernel/processor.c
--- a/arch/parisc/kernel/processor.c	2005-03-01 23:39:17 -08:00
+++ b/arch/parisc/kernel/processor.c	2005-03-01 23:39:17 -08:00
@@ -153,7 +153,7 @@
 	p->cpuid = cpuid;	/* save CPU id */
 	p->txn_addr = txn_addr;	/* save CPU IRQ address */
 #ifdef CONFIG_SMP
-	p->lock = SPIN_LOCK_UNLOCKED;
+	spin_lock_init(&p->lock);
 
 	/*
 	** FIXME: review if any other initialization is clobbered
diff -Nru a/arch/parisc/kernel/ptrace.c b/arch/parisc/kernel/ptrace.c
--- a/arch/parisc/kernel/ptrace.c	2005-03-01 23:38:52 -08:00
+++ b/arch/parisc/kernel/ptrace.c	2005-03-01 23:38:52 -08:00
@@ -30,9 +30,9 @@
 #undef DEBUG_PTRACE
 
 #ifdef DEBUG_PTRACE
-#define DBG(x)	printk x
+#define DBG(x...)	printk(x)
 #else
-#define DBG(x)
+#define DBG(x...)
 #endif
 
 #ifdef __LP64__
@@ -138,9 +138,9 @@
 			if (copied != sizeof(tmp))
 				goto out_tsk;
 			ret = put_user(tmp,(unsigned int *) data);
-			DBG(("sys_ptrace(PEEK%s, %d, %lx, %lx) returning %ld, data %x\n",
+			DBG("sys_ptrace(PEEK%s, %d, %lx, %lx) returning %ld, data %x\n",
 				request == PTRACE_PEEKTEXT ? "TEXT" : "DATA",
-				pid, oaddr, odata, ret, tmp));
+				pid, oaddr, odata, ret, tmp);
 		}
 		else
 #endif
@@ -163,9 +163,9 @@
 #ifdef __LP64__
 		if (is_compat_task(child)) {
 			unsigned int tmp = (unsigned int)data;
-			DBG(("sys_ptrace(POKE%s, %d, %lx, %lx)\n",
+			DBG("sys_ptrace(POKE%s, %d, %lx, %lx)\n",
 				request == PTRACE_POKETEXT ? "TEXT" : "DATA",
-				pid, oaddr, odata));
+				pid, oaddr, odata);
 			addr &= 0xffffffffL;
 			if (access_process_vm(child, addr, &tmp, sizeof(tmp), 1) == sizeof(tmp))
 				goto out_tsk;
@@ -194,8 +194,8 @@
 
 			tmp = *(unsigned int *) ((char *) task_regs(child) + addr);
 			ret = put_user(tmp, (unsigned int *) data);
-			DBG(("sys_ptrace(PEEKUSR, %d, %lx, %lx) returning %ld, addr %lx, data %x\n",
-				pid, oaddr, odata, ret, addr, tmp));
+			DBG("sys_ptrace(PEEKUSR, %d, %lx, %lx) returning %ld, addr %lx, data %x\n",
+				pid, oaddr, odata, ret, addr, tmp);
 		}
 		else
 #endif
@@ -234,8 +234,8 @@
 			 * BEWARE, if you set N, and then single step, it won't
 			 * stop on the nullified instruction.
 			 */
-			DBG(("sys_ptrace(POKEUSR, %d, %lx, %lx)\n",
-				pid, oaddr, odata));
+			DBG("sys_ptrace(POKEUSR, %d, %lx, %lx)\n",
+				pid, oaddr, odata);
 			data &= USER_PSW_BITS;
 			task_regs(child)->gr[0] &= ~USER_PSW_BITS;
 			task_regs(child)->gr[0] |= data;
@@ -248,9 +248,9 @@
 				goto out_tsk;
 			if ((addr = translate_usr_offset(addr)) < 0)
 				goto out_tsk;
-			DBG(("sys_ptrace(POKEUSR, %d, %lx, %lx) addr %lx\n",
-				pid, oaddr, odata, addr));
-			if (addr >= PT_FR0 && addr <= PT_FR31) {
+			DBG("sys_ptrace(POKEUSR, %d, %lx, %lx) addr %lx\n",
+				pid, oaddr, odata, addr);
+			if (addr >= PT_FR0 && addr <= PT_FR31 + 4) {
 				/* Special case, fp regs are 64 bits anyway */
 				*(unsigned int *) ((char *) task_regs(child) + addr) = data;
 				ret = 0;
@@ -272,7 +272,7 @@
 				goto out_tsk;
 			if ((addr >= PT_GR1 && addr <= PT_GR31) ||
 					addr == PT_IAOQ0 || addr == PT_IAOQ1 ||
-					(addr >= PT_FR0 && addr <= PT_FR31) ||
+					(addr >= PT_FR0 && addr <= PT_FR31 + 4) ||
 					addr == PT_SAR) {
 				*(unsigned long *) ((char *) task_regs(child) + addr) = data;
 				ret = 0;
@@ -283,8 +283,8 @@
 	case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
 	case PTRACE_CONT:
 		ret = -EIO;
-		DBG(("sys_ptrace(%s)\n",
-			request == PTRACE_SYSCALL ? "SYSCALL" : "CONT"));
+		DBG("sys_ptrace(%s)\n",
+			request == PTRACE_SYSCALL ? "SYSCALL" : "CONT");
 		if ((unsigned long) data > _NSIG)
 			goto out_tsk;
 		child->ptrace &= ~(PT_SINGLESTEP|PT_BLOCKSTEP);
@@ -302,14 +302,14 @@
 		 * sigkill.  perhaps it should be put in the status
 		 * that it wants to exit.
 		 */
-		DBG(("sys_ptrace(KILL)\n"));
+		DBG("sys_ptrace(KILL)\n");
 		if (child->exit_state == EXIT_ZOMBIE)	/* already dead */
 			goto out_tsk;
 		child->exit_code = SIGKILL;
 		goto out_wake_notrap;
 
 	case PTRACE_SINGLEBLOCK:
-		DBG(("sys_ptrace(SINGLEBLOCK)\n"));
+		DBG("sys_ptrace(SINGLEBLOCK)\n");
 		ret = -EIO;
 		if ((unsigned long) data > _NSIG)
 			goto out_tsk;
@@ -326,10 +326,11 @@
 		goto out_wake;
 
 	case PTRACE_SINGLESTEP:
-		DBG(("sys_ptrace(SINGLESTEP)\n"));
+		DBG("sys_ptrace(SINGLESTEP)\n");
 		ret = -EIO;
 		if ((unsigned long) data > _NSIG)
 			goto out_tsk;
+
 		clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
 		child->ptrace &= ~PT_BLOCKSTEP;
 		child->ptrace |= PT_SINGLESTEP;
@@ -351,7 +352,7 @@
 			/* Don't wake up the child, but let the
 			   parent know something happened. */
 			si.si_code = TRAP_TRACE;
-			si.si_addr = (void *) (task_regs(child)->iaoq[0] & ~3);
+			si.si_addr = (void __user *) (task_regs(child)->iaoq[0] & ~3);
 			si.si_signo = SIGTRAP;
 			si.si_errno = 0;
 			force_sig_info(SIGTRAP, &si, child);
@@ -397,8 +398,8 @@
 	put_task_struct(child);
 out:
 	unlock_kernel();
-	DBG(("sys_ptrace(%ld, %d, %lx, %lx) returning %ld\n",
-		request, pid, oaddr, odata, ret));
+	DBG("sys_ptrace(%ld, %d, %lx, %lx) returning %ld\n",
+		request, pid, oaddr, odata, ret);
 	return ret;
 }
 
diff -Nru a/arch/parisc/kernel/setup.c b/arch/parisc/kernel/setup.c
--- a/arch/parisc/kernel/setup.c	2005-03-01 23:39:16 -08:00
+++ b/arch/parisc/kernel/setup.c	2005-03-01 23:39:16 -08:00
@@ -307,6 +307,8 @@
 			boot_cpu_data.cpu_hz / 1000000,
 			boot_cpu_data.cpu_hz % 1000000	);
 
+	parisc_setup_cache_timing();
+
 	/* These are in a non-obvious order, will fix when we have an iotree */
 #if defined(CONFIG_IOSAPIC)
 	iosapic_init();
diff -Nru a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c
--- a/arch/parisc/kernel/smp.c	2005-03-01 23:39:17 -08:00
+++ b/arch/parisc/kernel/smp.c	2005-03-01 23:39:17 -08:00
@@ -54,7 +54,7 @@
 
 #define kDEBUG 0
 
-spinlock_t smp_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(smp_lock);
 
 volatile struct task_struct *smp_init_current_idle_task;
 
@@ -277,7 +277,7 @@
 
 	spin_lock_irqsave(&(p->lock),flags);
 	p->pending_ipi |= 1 << op;
-	__raw_writel(IRQ_OFFSET(IPI_IRQ), cpu_data[cpu].hpa);
+	gsc_writel(IPI_IRQ - CPU_IRQ_BASE, cpu_data[cpu].hpa);
 	spin_unlock_irqrestore(&(p->lock),flags);
 }
 
@@ -332,7 +332,7 @@
 {
 	struct smp_call_struct data;
 	unsigned long timeout;
-	static spinlock_t lock = SPIN_LOCK_UNLOCKED;
+	static DEFINE_SPINLOCK(lock);
 	int retries = 0;
 
 	if (num_online_cpus() < 2)
@@ -459,7 +459,6 @@
  */
 void __init smp_callin(void)
 {
-	extern void cpu_idle(void);	/* arch/parisc/kernel/process.c */
 	int slave_id = cpu_now_booting;
 #if 0
 	void *istack;
@@ -534,7 +533,7 @@
 	** EIR{0}). MEM_RENDEZ is valid only when it is nonzero and the 
 	** contents of memory are valid."
 	*/
-	__raw_writel(IRQ_OFFSET(TIMER_IRQ), cpu_data[cpuid].hpa);
+	gsc_writel(TIMER_IRQ - CPU_IRQ_BASE, cpu_data[cpuid].hpa);
 	mb();
 
 	/* 
diff -Nru a/arch/parisc/kernel/sys_parisc32.c b/arch/parisc/kernel/sys_parisc32.c
--- a/arch/parisc/kernel/sys_parisc32.c	2005-03-01 23:38:55 -08:00
+++ b/arch/parisc/kernel/sys_parisc32.c	2005-03-01 23:38:55 -08:00
@@ -165,12 +165,6 @@
 	return error;
 }
 
-#else /* CONFIG_SYSCTL */
-
-asmlinkage long sys32_sysctl(struct __sysctl_args *args)
-{
-	return -ENOSYS;
-}
 #endif /* CONFIG_SYSCTL */
 
 asmlinkage long sys32_sched_rr_get_interval(pid_t pid,
@@ -204,21 +198,6 @@
 		return -EFAULT;
 	o->tv_nsec = usec * 1000;
 	return 0;
-}
-
-asmlinkage long sys32_time(compat_time_t *tloc)
-{
-	struct timeval tv;
-	compat_time_t now32;
-
-	do_gettimeofday(&tv);
-	now32 = tv.tv_sec;
-
-	if (tloc)
-		if (put_user(now32, tloc))
-			now32 = -EFAULT;
-
-	return now32;
 }
 
 asmlinkage int
diff -Nru a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S
--- a/arch/parisc/kernel/syscall_table.S	2005-03-01 23:38:51 -08:00
+++ b/arch/parisc/kernel/syscall_table.S	2005-03-01 23:38:51 -08:00
@@ -74,7 +74,7 @@
 	ENTRY_DIFF(execve_wrapper)
 	ENTRY_SAME(chdir)
 	/* See comments in kernel/time.c!!! Maybe we don't need this? */
-	ENTRY_DIFF(time)
+	ENTRY_COMP(time)
 	ENTRY_SAME(mknod)
 	ENTRY_SAME(chmod)		/* 15 */
 	ENTRY_SAME(lchown)
@@ -91,7 +91,7 @@
 	ENTRY_SAME(bind)
 	ENTRY_SAME(setuid)
 	ENTRY_SAME(getuid)
-	ENTRY_SAME(stime)		/* 25 */
+	ENTRY_COMP(stime)		/* 25 */
 	ENTRY_SAME(ptrace)
 	ENTRY_SAME(alarm)
 	/* see stat comment */
@@ -275,7 +275,7 @@
 	ENTRY_DIFF(rt_sigaction)
 	ENTRY_DIFF(rt_sigprocmask)	/* 175 */
 	ENTRY_DIFF(rt_sigpending)
-	ENTRY_UHOH(rt_sigtimedwait)
+	ENTRY_COMP(rt_sigtimedwait)
 	/* even though the struct siginfo_t is different, it appears like
 	 * all the paths use values which should be same wide and narrow.
 	 * Also the struct is padded to 128 bytes which means we don't have
diff -Nru a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c
--- a/arch/parisc/kernel/traps.c	2005-03-01 23:39:18 -08:00
+++ b/arch/parisc/kernel/traps.c	2005-03-01 23:39:18 -08:00
@@ -46,7 +46,7 @@
 			  /*  dumped to the console via printk)          */
 
 #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
-spinlock_t pa_dbit_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(pa_dbit_lock);
 #endif
 
 int printbinary(char *buf, unsigned long x, int nbits)
@@ -385,7 +385,7 @@
  */
 void parisc_terminate(char *msg, struct pt_regs *regs, int code, unsigned long offset)
 {
-	static spinlock_t terminate_lock = SPIN_LOCK_UNLOCKED;
+	static DEFINE_SPINLOCK(terminate_lock);
 
 	oops_in_progress = 1;
 
diff -Nru a/arch/parisc/lib/Makefile b/arch/parisc/lib/Makefile
--- a/arch/parisc/lib/Makefile	2005-03-01 23:38:58 -08:00
+++ b/arch/parisc/lib/Makefile	2005-03-01 23:38:58 -08:00
@@ -4,4 +4,6 @@
 
 lib-y	:= lusercopy.o bitops.o checksum.o io.o memset.o fixup.o memcpy.o
 
+obj-y	:= iomap.o
+
 lib-$(CONFIG_SMP) += debuglocks.o
diff -Nru a/arch/parisc/lib/checksum.c b/arch/parisc/lib/checksum.c
--- a/arch/parisc/lib/checksum.c	2005-03-01 23:39:07 -08:00
+++ b/arch/parisc/lib/checksum.c	2005-03-01 23:39:07 -08:00
@@ -113,7 +113,7 @@
 /*
  * copy while checksumming, otherwise like csum_partial
  */
-unsigned int csum_partial_copy_nocheck(const char *src, char *dst, 
+unsigned int csum_partial_copy_nocheck(const unsigned char *src, unsigned char *dst,
 				       int len, unsigned int sum)
 {
 	/*
@@ -131,7 +131,7 @@
  * 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 char *src, 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 -Nru a/arch/parisc/lib/io.c b/arch/parisc/lib/io.c
--- a/arch/parisc/lib/io.c	2005-03-01 23:38:52 -08:00
+++ b/arch/parisc/lib/io.c	2005-03-01 23:38:52 -08:00
@@ -15,24 +15,24 @@
  * Assumes the device can cope with 32-bit transfers.  If it can't,
  * don't use this function.
  */
-void __memcpy_toio(unsigned long dest, unsigned long src, int count)
+void memcpy_toio(volatile void __iomem *dst, const void *src, int count)
 {
-	if ((dest & 3) != (src & 3))
+	if (((unsigned long)dst & 3) != ((unsigned long)src & 3))
 		goto bytecopy;
-	while (dest & 3) {
-		writeb(*(char *)src, dest++);
+	while ((unsigned long)dst & 3) {
+		writeb(*(char *)src, dst++);
 		src++;
 		count--;
 	}
 	while (count > 3) {
-		__raw_writel(*(u32 *)src, dest);
+		__raw_writel(*(u32 *)src, dst);
 		src += 4;
-		dest += 4;
+		dst += 4;
 		count -= 4;
 	}
  bytecopy:
 	while (count--) {
-		writeb(*(char *)src, dest++);
+		writeb(*(char *)src, dst++);
 		src++;
 	}
 }
@@ -50,51 +50,51 @@
 **      Minimize total number of transfers at cost of CPU cycles.
 **	TODO: only look at src alignment and adjust the stores to dest.
 */
-void __memcpy_fromio(unsigned long dest, unsigned long src, int count)
+void memcpy_fromio(void *dst, const volatile void __iomem *src, int count)
 {
 	/* first compare alignment of src/dst */ 
-	if ( ((dest ^ src) & 1) || (count < 2) )
+	if ( (((unsigned long)dst ^ (unsigned long)src) & 1) || (count < 2) )
 		goto bytecopy;
 
-	if ( ((dest ^ src) & 2) || (count < 4) )
+	if ( (((unsigned long)dst ^ (unsigned long)src) & 2) || (count < 4) )
 		goto shortcopy;
 
 	/* Then check for misaligned start address */
-	if (src & 1) {
-		*(u8 *)dest = readb(src);
+	if ((unsigned long)src & 1) {
+		*(u8 *)dst = readb(src);
 		src++;
-		dest++;
+		dst++;
 		count--;
 		if (count < 2) goto bytecopy;
 	}
 
-	if (src & 2) {
-		*(u16 *)dest = __raw_readw(src);
+	if ((unsigned long)src & 2) {
+		*(u16 *)dst = __raw_readw(src);
 		src += 2;
-		dest += 2;
+		dst += 2;
 		count -= 2;
 	}
 
 	while (count > 3) {
-		*(u32 *)dest = __raw_readl(src);
-		dest += 4;
+		*(u32 *)dst = __raw_readl(src);
+		dst += 4;
 		src += 4;
 		count -= 4;
 	}
 
  shortcopy:
 	while (count > 1) {
-		*(u16 *)dest = __raw_readw(src);
+		*(u16 *)dst = __raw_readw(src);
 		src += 2;
-		dest += 2;
+		dst += 2;
 		count -= 2;
 	}
 
  bytecopy:
 	while (count--) {
-		*(char *)dest = readb(src);
+		*(char *)dst = readb(src);
 		src++;
-		dest++;
+		dst++;
 	}
 }
 
@@ -102,20 +102,20 @@
  * Assumes the device can cope with 32-bit transfers.  If it can't,
  * don't use this function.
  */
-void __memset_io(unsigned long dest, char fill, int count)
+void memset_io(volatile void __iomem *addr, unsigned char val, int count)
 {
-	u32 fill32 = (fill << 24) | (fill << 16) | (fill << 8) | fill;
-	while (dest & 3) {
-		writeb(fill, dest++);
+	u32 val32 = (val << 24) | (val << 16) | (val << 8) | val;
+	while ((unsigned long)addr & 3) {
+		writeb(val, addr++);
 		count--;
 	}
 	while (count > 3) {
-		__raw_writel(fill32, dest);
-		dest += 4;
+		__raw_writel(val32, addr);
+		addr += 4;
 		count -= 4;
 	}
 	while (count--) {
-		writeb(fill, dest++);
+		writeb(val, addr++);
 	}
 }
 
diff -Nru a/arch/parisc/lib/iomap.c b/arch/parisc/lib/iomap.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/parisc/lib/iomap.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,422 @@
+/*
+ * iomap.c - Implement iomap interface for PA-RISC
+ * Copyright (c) 2004 Matthew Wilcox
+ */
+
+#include <linux/ioport.h>
+#include <linux/pci.h>
+#include <asm/io.h>
+
+/*
+ * The iomap space on 32-bit PA-RISC is intended to look like this:
+ * 00000000-7fffffff virtual mapped IO
+ * 80000000-8fffffff ISA/EISA port space that can't be virtually mapped
+ * 90000000-9fffffff Dino port space
+ * a0000000-afffffff Astro port space
+ * b0000000-bfffffff PAT port space
+ * c0000000-cfffffff non-swapped memory IO
+ * f0000000-ffffffff legacy IO memory pointers
+ *
+ * For the moment, here's what it looks like:
+ * 80000000-8fffffff All ISA/EISA port space
+ * f0000000-ffffffff legacy IO memory pointers
+ *
+ * On 64-bit, everything is extended, so:
+ * 8000000000000000-8fffffffffffffff All ISA/EISA port space
+ * f000000000000000-ffffffffffffffff legacy IO memory pointers
+ */
+
+/*
+ * Technically, this should be 'if (VMALLOC_START < addr < VMALLOC_END),
+ * but that's slow and we know it'll be within the first 2GB.
+ */
+#ifdef CONFIG_64BIT
+#define INDIRECT_ADDR(addr)	(((unsigned long)(addr) & 1UL<<63) != 0)
+#define ADDR_TO_REGION(addr)    (((unsigned long)addr >> 60) & 7)
+#define IOPORT_MAP_BASE		(8UL << 60)
+#else
+#define INDIRECT_ADDR(addr)     (((unsigned long)(addr) & 1UL<<31) != 0)
+#define ADDR_TO_REGION(addr)    (((unsigned long)addr >> 28) & 7)
+#define IOPORT_MAP_BASE		(8UL << 28)
+#endif
+
+struct iomap_ops {
+	unsigned int (*read8)(void __iomem *);
+	unsigned int (*read16)(void __iomem *);
+	unsigned int (*read32)(void __iomem *);
+	void (*write8)(u8, void __iomem *);
+	void (*write16)(u16, void __iomem *);
+	void (*write32)(u32, void __iomem *);
+	void (*read8r)(void __iomem *, void *, unsigned long);
+	void (*read16r)(void __iomem *, void *, unsigned long);
+	void (*read32r)(void __iomem *, void *, unsigned long);
+	void (*write8r)(void __iomem *, const void *, unsigned long);
+	void (*write16r)(void __iomem *, const void *, unsigned long);
+	void (*write32r)(void __iomem *, const void *, unsigned long);
+};
+
+/* Generic ioport ops.  To be replaced later by specific dino/elroy/wax code */
+
+#define ADDR2PORT(addr) ((unsigned long __force)(addr) & 0xffffff)
+
+static unsigned int ioport_read8(void __iomem *addr)
+{
+	return inb(ADDR2PORT(addr));
+}
+
+static unsigned int ioport_read16(void __iomem *addr)
+{
+	return inw(ADDR2PORT(addr));
+}
+
+static unsigned int ioport_read32(void __iomem *addr)
+{
+	return inl(ADDR2PORT(addr));
+}
+
+static void ioport_write8(u8 datum, void __iomem *addr)
+{
+	outb(datum, ADDR2PORT(addr));
+}
+
+static void ioport_write16(u16 datum, void __iomem *addr)
+{
+	outw(datum, ADDR2PORT(addr));
+}
+
+static void ioport_write32(u32 datum, void __iomem *addr)
+{
+	outl(datum, ADDR2PORT(addr));
+}
+
+static void ioport_read8r(void __iomem *addr, void *dst, unsigned long count)
+{
+	insb(ADDR2PORT(addr), dst, count);
+}
+
+static void ioport_read16r(void __iomem *addr, void *dst, unsigned long count)
+{
+	insw(ADDR2PORT(addr), dst, count);
+}
+
+static void ioport_read32r(void __iomem *addr, void *dst, unsigned long count)
+{
+	insl(ADDR2PORT(addr), dst, count);
+}
+
+static void ioport_write8r(void __iomem *addr, const void *s, unsigned long n)
+{
+	outsb(ADDR2PORT(addr), s, n);
+}
+
+static void ioport_write16r(void __iomem *addr, const void *s, unsigned long n)
+{
+	outsw(ADDR2PORT(addr), s, n);
+}
+
+static void ioport_write32r(void __iomem *addr, const void *s, unsigned long n)
+{
+	outsl(ADDR2PORT(addr), s, n);
+}
+
+static const struct iomap_ops ioport_ops = {
+	ioport_read8,
+	ioport_read16,
+	ioport_read32,
+	ioport_write8,
+	ioport_write16,
+	ioport_write32,
+	ioport_read8r,
+	ioport_read16r,
+	ioport_read32r,
+	ioport_write8r,
+	ioport_write16r,
+	ioport_write32r,
+};
+
+/* Legacy I/O memory ops */
+
+static unsigned int iomem_read8(void __iomem *addr)
+{
+	return readb(addr);
+}
+
+static unsigned int iomem_read16(void __iomem *addr)
+{
+	return readw(addr);
+}
+
+static unsigned int iomem_read32(void __iomem *addr)
+{
+	return readl(addr);
+}
+
+static void iomem_write8(u8 datum, void __iomem *addr)
+{
+	writeb(datum, addr);
+}
+
+static void iomem_write16(u16 datum, void __iomem *addr)
+{
+	writew(datum, addr);
+}
+
+static void iomem_write32(u32 datum, void __iomem *addr)
+{
+	writel(datum, addr);
+}
+
+static void iomem_read8r(void __iomem *addr, void *dst, unsigned long count)
+{
+	while (count--) {
+		*(u8 *)dst = __raw_readb(addr);
+		dst++;
+	}
+}
+
+static void iomem_read16r(void __iomem *addr, void *dst, unsigned long count)
+{
+	while (count--) {
+		*(u16 *)dst = __raw_readw(addr);
+		dst += 2;
+	}
+}
+
+static void iomem_read32r(void __iomem *addr, void *dst, unsigned long count)
+{
+	while (count--) {
+		*(u32 *)dst = __raw_readl(addr);
+		dst += 4;
+	}
+}
+
+static void iomem_write8r(void __iomem *addr, const void *s, unsigned long n)
+{
+	while (n--) {
+		__raw_writeb(*(u8 *)s, addr);
+		s++;
+	}
+}
+
+static void iomem_write16r(void __iomem *addr, const void *s, unsigned long n)
+{
+	while (n--) {
+		__raw_writew(*(u16 *)s, addr);
+		s += 2;
+	}
+}
+
+static void iomem_write32r(void __iomem *addr, const void *s, unsigned long n)
+{
+	while (n--) {
+		__raw_writel(*(u32 *)s, addr);
+		s += 4;
+	}
+}
+
+static const struct iomap_ops iomem_ops = {
+	iomem_read8,
+	iomem_read16,
+	iomem_read32,
+	iomem_write8,
+	iomem_write16,
+	iomem_write32,
+	iomem_read8r,
+	iomem_read16r,
+	iomem_read32r,
+	iomem_write8r,
+	iomem_write16r,
+	iomem_write32r,
+};
+
+const struct iomap_ops *iomap_ops[8] = {
+	[0] = &ioport_ops,
+#ifdef CONFIG_DEBUG_IOREMAP
+	[6] = &iomem_ops,
+#else
+	[7] = &iomem_ops
+#endif
+};
+
+
+unsigned int ioread8(void __iomem *addr)
+{
+	if (unlikely(INDIRECT_ADDR(addr)))
+		return iomap_ops[ADDR_TO_REGION(addr)]->read8(addr);
+	return *((u8 *)addr);
+}
+
+unsigned int ioread16(void __iomem *addr)
+{
+	if (unlikely(INDIRECT_ADDR(addr)))
+		return iomap_ops[ADDR_TO_REGION(addr)]->read16(addr);
+	return le16_to_cpup((u16 *)addr);
+}
+
+unsigned int ioread32(void __iomem *addr)
+{
+	if (unlikely(INDIRECT_ADDR(addr)))
+		return iomap_ops[ADDR_TO_REGION(addr)]->read32(addr);
+	return le32_to_cpup((u32 *)addr);
+}
+
+void iowrite8(u8 datum, void __iomem *addr)
+{
+	if (unlikely(INDIRECT_ADDR(addr))) {
+		iomap_ops[ADDR_TO_REGION(addr)]->write8(datum, addr);
+	} else {
+		*((u8 *)addr) = datum;
+	}
+}
+
+void iowrite16(u16 datum, void __iomem *addr)
+{
+	if (unlikely(INDIRECT_ADDR(addr))) {
+		iomap_ops[ADDR_TO_REGION(addr)]->write16(datum, addr);
+	} else {
+		*((u16 *)addr) = cpu_to_le16(datum);
+	}
+}
+
+void iowrite32(u32 datum, void __iomem *addr)
+{
+	if (unlikely(INDIRECT_ADDR(addr))) {
+		iomap_ops[ADDR_TO_REGION(addr)]->write32(datum, addr);
+	} else {
+		*((u32 *)addr) = cpu_to_le32(datum);
+	}
+}
+
+/* Repeating interfaces */
+
+void ioread8_rep(void __iomem *addr, void *dst, unsigned long count)
+{
+	if (unlikely(INDIRECT_ADDR(addr))) {
+		iomap_ops[ADDR_TO_REGION(addr)]->read8r(addr, dst, count);
+	} else {
+		while (count--) {
+			*(u8 *)dst = *(u8 *)addr;
+			dst++;
+		}
+	}
+}
+
+void ioread16_rep(void __iomem *addr, void *dst, unsigned long count)
+{
+	if (unlikely(INDIRECT_ADDR(addr))) {
+		iomap_ops[ADDR_TO_REGION(addr)]->read16r(addr, dst, count);
+	} else {
+		while (count--) {
+			*(u16 *)dst = *(u16 *)addr;
+			dst += 2;
+		}
+	}
+}
+
+void ioread32_rep(void __iomem *addr, void *dst, unsigned long count)
+{
+	if (unlikely(INDIRECT_ADDR(addr))) {
+		iomap_ops[ADDR_TO_REGION(addr)]->read32r(addr, dst, count);
+	} else {
+		while (count--) {
+			*(u32 *)dst = *(u32 *)addr;
+			dst += 4;
+		}
+	}
+}
+
+void iowrite8_rep(void __iomem *addr, const void *src, unsigned long count)
+{
+	if (unlikely(INDIRECT_ADDR(addr))) {
+		iomap_ops[ADDR_TO_REGION(addr)]->write8r(addr, src, count);
+	} else {
+		while (count--) {
+			*(u8 *)addr = *(u8 *)src;
+			src++;
+		}
+	}
+}
+
+void iowrite16_rep(void __iomem *addr, const void *src, unsigned long count)
+{
+	if (unlikely(INDIRECT_ADDR(addr))) {
+		iomap_ops[ADDR_TO_REGION(addr)]->write16r(addr, src, count);
+	} else {
+		while (count--) {
+			*(u16 *)addr = *(u16 *)src;
+			src += 2;
+		}
+	}
+}
+
+void iowrite32_rep(void __iomem *addr, const void *src, unsigned long count)
+{
+	if (unlikely(INDIRECT_ADDR(addr))) {
+		iomap_ops[ADDR_TO_REGION(addr)]->write32r(addr, src, count);
+	} else {
+		while (count--) {
+			*(u32 *)addr = *(u32 *)src;
+			src += 4;
+		}
+	}
+}
+
+/* Mapping interfaces */
+
+void __iomem *ioport_map(unsigned long port, unsigned int nr)
+{
+	return (void __iomem *)(IOPORT_MAP_BASE | port);
+}
+
+void ioport_unmap(void __iomem *addr)
+{
+	if (!INDIRECT_ADDR(addr)) {
+		iounmap(addr);
+	}
+}
+
+/* Create a virtual mapping cookie for a PCI BAR (memory or IO) */
+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);
+	}
+	/* What? */
+	return NULL;
+}
+
+void pci_iounmap(struct pci_dev *dev, void __iomem * addr)
+{
+	if (!INDIRECT_ADDR(addr)) {
+		iounmap(addr);
+	}
+}
+
+EXPORT_SYMBOL(ioread8);
+EXPORT_SYMBOL(ioread16);
+EXPORT_SYMBOL(ioread32);
+EXPORT_SYMBOL(iowrite8);
+EXPORT_SYMBOL(iowrite16);
+EXPORT_SYMBOL(iowrite32);
+EXPORT_SYMBOL(ioread8_rep);
+EXPORT_SYMBOL(ioread16_rep);
+EXPORT_SYMBOL(ioread32_rep);
+EXPORT_SYMBOL(iowrite8_rep);
+EXPORT_SYMBOL(iowrite16_rep);
+EXPORT_SYMBOL(iowrite32_rep);
+EXPORT_SYMBOL(ioport_map);
+EXPORT_SYMBOL(ioport_unmap);
+EXPORT_SYMBOL(pci_iomap);
+EXPORT_SYMBOL(pci_iounmap);
diff -Nru a/arch/parisc/lib/memcpy.c b/arch/parisc/lib/memcpy.c
--- a/arch/parisc/lib/memcpy.c	2005-03-01 23:39:17 -08:00
+++ b/arch/parisc/lib/memcpy.c	2005-03-01 23:39:17 -08:00
@@ -515,16 +515,8 @@
 	return dst;
 }
 
-void bcopy(const void * srcp, void * destp, size_t count)
-{
-	mtsp(get_kernel_space(), 1);
-	mtsp(get_kernel_space(), 2);
-	pa_memcpy(destp, srcp, count);
-}
-
 EXPORT_SYMBOL(copy_to_user);
 EXPORT_SYMBOL(copy_from_user);
 EXPORT_SYMBOL(copy_in_user);
 EXPORT_SYMBOL(memcpy);
-EXPORT_SYMBOL(bcopy);
 #endif
diff -Nru a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c
--- a/arch/parisc/mm/init.c	2005-03-01 23:38:57 -08:00
+++ b/arch/parisc/mm/init.c	2005-03-01 23:38:57 -08:00
@@ -269,8 +269,6 @@
 	}
 	memset(pfnnid_map, 0xff, sizeof(pfnnid_map));
 
-	numnodes = npmem_ranges;
-
 	for (i = 0; i < npmem_ranges; i++)
 		node_set_online(i);
 #endif
@@ -855,7 +853,7 @@
 static unsigned long free_space_ids = NR_SPACE_IDS - 1;
 static unsigned long dirty_space_ids = 0;
 
-static spinlock_t sid_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(sid_lock);
 
 unsigned long alloc_sid(void)
 {
diff -Nru a/arch/parisc/mm/ioremap.c b/arch/parisc/mm/ioremap.c
--- a/arch/parisc/mm/ioremap.c	2005-03-01 23:38:55 -08:00
+++ b/arch/parisc/mm/ioremap.c	2005-03-01 23:38:55 -08:00
@@ -11,6 +11,7 @@
 
 #include <linux/vmalloc.h>
 #include <linux/errno.h>
+#include <linux/module.h>
 #include <asm/io.h>
 #include <asm/pgalloc.h>
 
@@ -94,6 +95,30 @@
 }
 #endif /* USE_HPPA_IOREMAP */
 
+#ifdef CONFIG_DEBUG_IOREMAP
+static unsigned long last = 0;
+
+void gsc_bad_addr(unsigned long addr)
+{
+	if (time_after(jiffies, last + HZ*10)) {
+		printk("gsc_foo() called with bad address 0x%lx\n", addr);
+		dump_stack();
+		last = jiffies;
+	}
+}
+EXPORT_SYMBOL(gsc_bad_addr);
+
+void __raw_bad_addr(const volatile void __iomem *addr)
+{
+	if (time_after(jiffies, last + HZ*10)) {
+		printk("__raw_foo() called with bad address 0x%p\n", addr);
+		dump_stack();
+		last = jiffies;
+	}
+}
+EXPORT_SYMBOL(__raw_bad_addr);
+#endif
+
 /*
  * Generic mapping function (not visible outside):
  */
@@ -107,7 +132,7 @@
  * 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(unsigned long phys_addr, unsigned long size, unsigned long flags)
 {
 #if !(USE_HPPA_IOREMAP)
 
@@ -118,7 +143,11 @@
 		phys_addr |= 0xfc000000;
 	}
 
-	return (void *)phys_addr;
+#ifdef CONFIG_DEBUG_IOREMAP
+	return (void __iomem *)(phys_addr - (0x1UL << NYBBLE_SHIFT));
+#else
+	return (void __iomem *)phys_addr;
+#endif
 
 #else
 	void * addr;
@@ -163,16 +192,16 @@
 		vfree(addr);
 		return NULL;
 	}
-	return (void *) (offset + (char *)addr);
+	return (void __iomem *) (offset + (char *)addr);
 #endif
 }
 
-void iounmap(void *addr)
+void iounmap(void __iomem *addr)
 {
 #if !(USE_HPPA_IOREMAP)
 	return;
 #else
 	if (addr > high_memory)
-		return vfree((void *) (PAGE_MASK & (unsigned long) addr));
+		return vfree((void *) (PAGE_MASK & (unsigned long __force) addr));
 #endif
 }
diff -Nru a/arch/parisc/oprofile/init.c b/arch/parisc/oprofile/init.c
--- a/arch/parisc/oprofile/init.c	2005-03-01 23:38:57 -08:00
+++ b/arch/parisc/oprofile/init.c	2005-03-01 23:38:57 -08:00
@@ -12,9 +12,7 @@
 #include <linux/kernel.h>
 #include <linux/oprofile.h>
 
-extern void timer_init(struct oprofile_operations ** ops);
-
-int __init oprofile_arch_init(struct oprofile_operations ** ops)
+int __init oprofile_arch_init(struct oprofile_operations * ops)
 {
 	return -ENODEV;
 }
diff -Nru a/arch/ppc/4xx_io/serial_sicc.c b/arch/ppc/4xx_io/serial_sicc.c
--- a/arch/ppc/4xx_io/serial_sicc.c	2005-03-01 23:38:44 -08:00
+++ b/arch/ppc/4xx_io/serial_sicc.c	2005-03-01 23:38:44 -08:00
@@ -264,6 +264,7 @@
     unsigned int        flags;
     int         count;
     struct SICC_info    *info;
+    spinlock_t		sicc_lock;
 };
 
 #define SICC_XMIT_SIZE 1024
@@ -385,9 +386,10 @@
     struct SICC_info *info = tty->driver_data;
     unsigned long flags;
 
-    save_flags(flags); cli();
+    /* disable interrupts while stopping serial port interrupts */
+    spin_lock_irqsave(&info->state->sicc_lock,flags);
     siccuart_disable_tx_interrupt(info);
-    restore_flags(flags);
+    spin_unlock_irqrestore(&info->state->sicc_lock,flags);
 }
 
 static void siccuart_start(struct tty_struct *tty)
@@ -395,11 +397,12 @@
     struct SICC_info *info = tty->driver_data;
     unsigned long flags;
 
-    save_flags(flags); cli();
+    /* disable interrupts while starting serial port interrupts */
+    spin_lock_irqsave(&info->state->sicc_lock,flags);
     if (info->xmit.head != info->xmit.tail
         && info->xmit.buf)
         siccuart_enable_tx_interrupt(info);
-    restore_flags(flags);
+    spin_unlock_irqrestore(&info->state->sicc_lock,flags);
 }
 
 
@@ -604,7 +607,8 @@
 	return -ENOMEM;
     }
 
-    save_flags(flags); cli();
+    /* lock access to info while doing setup */
+    spin_lock_irqsave(&info->state->sicc_lock,flags);
 
     if (info->xmit.buf)
         free_page(page);
@@ -688,12 +692,12 @@
     siccuart_enable_rx_interrupt(info);
 
     info->flags |= ASYNC_INITIALIZED;
-    restore_flags(flags);
+    spin_unlock_irqrestore(&info->state->sicc_lock,flags);
     return 0;
 
 
 errout:
-    restore_flags(flags);
+    spin_unlock_irqrestore(&info->state->sicc_lock,flags);
     return retval;
 }
 
@@ -708,7 +712,8 @@
     if (!(info->flags & ASYNC_INITIALIZED))
         return;
 
-    save_flags(flags); cli(); /* Disable interrupts */
+    /* lock while shutting down port */
+    spin_lock_irqsave(&info->state->sicc_lock,flags); /* Disable interrupts */
 
     /*
      * clear delta_msr_wait queue to avoid mem leaks: we may free the irq
@@ -746,7 +751,7 @@
 
     info->flags &= ~ASYNC_INITIALIZED;
 
-    restore_flags(flags);
+    spin_unlock_irqrestore(&info->state->sicc_lock,flags);
 }
 
 
@@ -868,8 +873,8 @@
             info->ignore_status_mask |=  _LSR_OE_MASK;
     }
 
-    /* first, disable everything */
-    save_flags(flags); cli();
+    /* disable interrupts while reading and clearing registers */
+    spin_lock_irqsave(&info->state->sicc_lock,flags);
 
     old_rcr = readb(info->port->uart_base + BL_SICC_RCR);
     old_tcr = readb(info->port->uart_base + BL_SICC_TxCR);
@@ -881,7 +886,7 @@
     /*RLBtrace (&ppc403Chan0, 0x2000000c, 0, 0);*/
 
 
-    restore_flags(flags);
+    spin_unlock_irqrestore(&info->state->sicc_lock,flags);
 
 
     /* Set baud rate */
@@ -909,12 +914,13 @@
     if (!tty || !info->xmit.buf)
         return;
 
-    save_flags(flags); cli();
+    /* lock info->xmit while adding character to tx buffer */
+    spin_lock_irqsave(&info->state->sicc_lock,flags);
     if (CIRC_SPACE(info->xmit.head, info->xmit.tail, SICC_XMIT_SIZE) != 0) {
         info->xmit.buf[info->xmit.head] = ch;
         info->xmit.head = (info->xmit.head + 1) & (SICC_XMIT_SIZE - 1);
     }
-    restore_flags(flags);
+    spin_unlock_irqrestore(&info->state->sicc_lock,flags);
 }
 
 static void siccuart_flush_chars(struct tty_struct *tty)
@@ -928,9 +934,10 @@
         || !info->xmit.buf)
         return;
 
-    save_flags(flags); cli();
+    /* disable interrupts while transmitting characters */
+    spin_lock_irqsave(&info->state->sicc_lock,flags);
     siccuart_enable_tx_interrupt(info);
-    restore_flags(flags);
+    spin_unlock_irqrestore(&info->state->sicc_lock,flags);
 }
 
 static int siccuart_write(struct tty_struct *tty,
@@ -943,8 +950,8 @@
     if (!tty || !info->xmit.buf || !tmp_buf)
         return 0;
 
-    save_flags(flags);
-    cli();
+    /* lock info->xmit while removing characters from buffer */
+    spin_lock_irqsave(&info->state->sicc_lock,flags);
     while (1) {
         c = CIRC_SPACE_TO_END(info->xmit.head,
                       info->xmit.tail,
@@ -960,11 +967,11 @@
         count -= c;
         ret += c;
     }
-    restore_flags(flags);
     if (info->xmit.head != info->xmit.tail
         && !tty->stopped
         && !tty->hw_stopped)
         siccuart_enable_tx_interrupt(info);
+    spin_unlock_irqrestore(&info->state->sicc_lock,flags);
     return ret;
 }
 
@@ -988,9 +995,10 @@
     unsigned long flags;
 
     pr_debug("siccuart_flush_buffer(%d) called\n", tty->index);
-    save_flags(flags); cli();
+    /* lock info->xmit while zeroing buffer counts */
+    spin_lock_irqsave(&info->state->sicc_lock,flags);
     info->xmit.head = info->xmit.tail = 0;
-    restore_flags(flags);
+    spin_unlock_irqrestore(&info->state->sicc_lock,flags);
     wake_up_interruptible(&tty->write_wait);
     if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
         tty->ldisc.write_wakeup)
@@ -1019,10 +1027,11 @@
         siccuart_send_xchar(tty, STOP_CHAR(tty));
 
     if (tty->termios->c_cflag & CRTSCTS) {
-        save_flags(flags); cli();
+        /* disable interrupts while setting modem control lines */
+        spin_lock_irqsave(&info->state->sicc_lock,flags);
         info->mctrl &= ~TIOCM_RTS;
         info->port->set_mctrl(info->port, info->mctrl);
-        restore_flags(flags);
+        spin_unlock_irqrestore(&info->state->sicc_lock,flags);
     }
 }
 
@@ -1039,10 +1048,11 @@
     }
 
     if (tty->termios->c_cflag & CRTSCTS) {
-        save_flags(flags); cli();
+        /* disable interrupts while setting modem control lines */
+        spin_lock_irqsave(&info->state->sicc_lock,flags);
         info->mctrl |= TIOCM_RTS;
         info->port->set_mctrl(info->port, info->mctrl);
-        restore_flags(flags);
+        spin_unlock_irqrestore(&info->state->sicc_lock,flags);
     }
 }
 
@@ -1181,9 +1191,10 @@
     unsigned int result, status;
     unsigned long flags;
 
-    save_flags(flags); cli();
+    /* disable interrupts while reading status from port */
+    spin_lock_irqsave(&info->state->sicc_lock,flags);
     status = readb(info->port->uart_base +  BL_SICC_LSR);
-    restore_flags(flags);
+    spin_unlock_irqrestore(&info->state->sicc_lock,flags);
     result = status & _LSR_TSR_EMPTY ? TIOCSER_TEMT : 0;
 
     /*
@@ -1234,10 +1245,11 @@
     default:
         return -EINVAL;
     }
-    save_flags(flags); cli();
+    /* disable interrupts while setting modem control lines */
+    spin_lock_irqsave(&info->state->sicc_lock,flags);
     if (old != info->mctrl)
         info->port->set_mctrl(info->port, info->mctrl);
-    restore_flags(flags);
+    spin_unlock_irqrestore(&info->state->sicc_lock,flags);
     return 0;
 }
 
@@ -1248,14 +1260,15 @@
     unsigned int lcr_h;
 
 
-    save_flags(flags); cli();
+    /* disable interrupts while setting break state */
+    spin_lock_irqsave(&info->state->sicc_lock,flags);
     lcr_h = readb(info->port + BL_SICC_LSR);
     if (break_state == -1)
         lcr_h |=  _LSR_LB_MASK;
     else
         lcr_h &= ~_LSR_LB_MASK;
     writeb(lcr_h, info->port + BL_SICC_LSRS);
-    restore_flags(flags);
+    spin_unlock_irqrestore(&info->state->sicc_lock,flags);
 }
 
 static int siccuart_ioctl(struct tty_struct *tty, struct file *file,
@@ -1303,9 +1316,10 @@
          *     RI where only 0->1 is counted.
          */
         case TIOCGICOUNT:
-            save_flags(flags); cli();
+            /* disable interrupts while getting interrupt count */
+            spin_lock_irqsave(&info->state->sicc_lock,flags);
             cnow = info->state->icount;
-            restore_flags(flags);
+            spin_unlock_irqrestore(&info->state->sicc_lock,flags);
             icount.cts = cnow.cts;
             icount.dsr = cnow.dsr;
             icount.rng = cnow.rng;
@@ -1342,22 +1356,24 @@
     /* Handle transition to B0 status */
     if ((old_termios->c_cflag & CBAUD) &&
         !(cflag & CBAUD)) {
-        save_flags(flags); cli();
+        /* disable interrupts while setting break state */
+        spin_lock_irqsave(&info->state->sicc_lock,flags);
         info->mctrl &= ~(TIOCM_RTS | TIOCM_DTR);
         info->port->set_mctrl(info->port, info->mctrl);
-        restore_flags(flags);
+        spin_unlock_irqrestore(&info->state->sicc_lock,flags);
     }
 
     /* Handle transition away from B0 status */
     if (!(old_termios->c_cflag & CBAUD) &&
         (cflag & CBAUD)) {
-        save_flags(flags); cli();
+        /* disable interrupts while setting break state */
+        spin_lock_irqsave(&info->state->sicc_lock,flags);
         info->mctrl |= TIOCM_DTR;
         if (!(cflag & CRTSCTS) ||
             !test_bit(TTY_THROTTLED, &tty->flags))
             info->mctrl |= TIOCM_RTS;
         info->port->set_mctrl(info->port, info->mctrl);
-        restore_flags(flags);
+        spin_unlock_irqrestore(&info->state->sicc_lock,flags);
     }
 
     /* Handle turning off CRTSCTS */
@@ -1393,11 +1409,11 @@
 
     //pr_debug("siccuart_close() called\n");
 
-    save_flags(flags); cli();
+    /* lock tty->driver_data while closing port */
+    spin_lock_irqsave(&info->state->sicc_lock,flags);
 
     if (tty_hung_up_p(filp)) {
-        restore_flags(flags);
-        return;
+        goto quick_close;
     }
 
     if ((tty->count == 1) && (state->count != 1)) {
@@ -1416,11 +1432,10 @@
         state->count = 0;
     }
     if (state->count) {
-        restore_flags(flags);
-        return;
+        goto quick_close;
     }
     info->flags |= ASYNC_CLOSING;
-    restore_flags(flags);
+    spin_unlock_irqrestore(&info->state->sicc_lock,flags);
     /*
      * Now we wait for the transmit buffer to clear; and we notify
      * the line discipline to only process XON/XOFF characters.
@@ -1458,6 +1473,11 @@
     }
     info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
     wake_up_interruptible(&info->close_wait);
+    return;
+
+quick_close:
+    spin_unlock_irqrestore(&info->state->sicc_lock,flags);
+    return;
 }
 
 static void siccuart_wait_until_sent(struct tty_struct *tty, int timeout)
@@ -1569,20 +1589,22 @@
      */
     retval = 0;
     add_wait_queue(&info->open_wait, &wait);
-    save_flags(flags); cli();
+    /* lock while decrementing state->count */
+    spin_lock_irqsave(&info->state->sicc_lock,flags);
     if (!tty_hung_up_p(filp)) {
         extra_count = 1;
         state->count--;
     }
-    restore_flags(flags);
+    spin_unlock_irqrestore(&info->state->sicc_lock,flags);
     info->blocked_open++;
     while (1) {
-        save_flags(flags); cli();
+        /* disable interrupts while setting modem control lines */
+        spin_lock_irqsave(&info->state->sicc_lock,flags);
         if (tty->termios->c_cflag & CBAUD) {
             info->mctrl = TIOCM_DTR | TIOCM_RTS;
             info->port->set_mctrl(info->port, info->mctrl);
         }
-        restore_flags(flags);
+        spin_unlock_irqrestore(&info->state->sicc_lock,flags);
         set_current_state(TASK_INTERRUPTIBLE);
         if (tty_hung_up_p(filp) ||
             !(info->flags & ASYNC_INITIALIZED)) {
@@ -1753,6 +1775,7 @@
         state->line     = i;
         state->close_delay  = 5 * HZ / 10;
         state->closing_wait = 30 * HZ;
+	spin_lock_init(&state->sicc_lock);
     }
 
 
diff -Nru a/arch/ppc/8xx_io/Kconfig b/arch/ppc/8xx_io/Kconfig
--- a/arch/ppc/8xx_io/Kconfig	2005-03-01 23:39:07 -08:00
+++ b/arch/ppc/8xx_io/Kconfig	2005-03-01 23:39:07 -08:00
@@ -10,7 +10,7 @@
 	depends on NET_ETHERNET
 	help
 	  Enable Ethernet support via the Motorola MPC8xx serial
-	  commmunications controller.
+	  communications controller.
 
 choice
 	prompt "SCC used for Ethernet"
diff -Nru a/arch/ppc/8xx_io/cs4218_tdm.c b/arch/ppc/8xx_io/cs4218_tdm.c
--- a/arch/ppc/8xx_io/cs4218_tdm.c	2005-03-01 23:38:52 -08:00
+++ b/arch/ppc/8xx_io/cs4218_tdm.c	2005-03-01 23:38:52 -08:00
@@ -55,6 +55,8 @@
 static char **sound_buffers = NULL;
 static char **sound_read_buffers = NULL;
 
+static spinlock_t cs4218_lock = SPIN_LOCK_UNLOCKED;
+
 /* Local copies of things we put in the control register.  Output
  * volume, like most codecs is really attenuation.
  */
@@ -1206,7 +1208,8 @@
 	volatile cbd_t	*bdp;
 	volatile cpm8xx_t *cp;
 
-	save_flags(flags); cli();
+	/* Protect buffer */
+	spin_lock_irqsave(&cs4218_lock, flags);
 #if 0
 	if (awacs_beep_state) {
 		/* sound takes precedence over beeps */
@@ -1263,7 +1266,7 @@
 
 		++sq.active;
 	}
-	restore_flags(flags);
+	spin_unlock_irqrestore(&cs4218_lock, flags);
 }
 
 
@@ -1275,7 +1278,8 @@
 	if (read_sq.active)
 		return;
 
-	save_flags(flags); cli();
+	/* Protect buffer */
+	spin_lock_irqsave(&cs4218_lock, flags);
 
 	/* This is all we have to do......Just start it up.
 	*/
@@ -1284,7 +1288,7 @@
 
 	read_sq.active = 1;
 
-        restore_flags(flags);
+        spin_unlock_irqrestore(&cs4218_lock, flags);
 }
 
 
@@ -1365,14 +1369,15 @@
 {
 	unsigned long flags;
 
-	save_flags(flags); cli();
+	/* not sure if this is needed, since hardware command is #if 0'd */
+	spin_lock_irqsave(&cs4218_lock, flags);
 	if (beep_playing) {
 #if 0
 		st_le16(&beep_dbdma_cmd->command, DBDMA_STOP);
 #endif
 		beep_playing = 0;
 	}
-	restore_flags(flags);
+	spin_unlock_irqrestore(&cs4218_lock, flags);
 }
 
 static struct timer_list beep_timer = TIMER_INITIALIZER(cs_nosound, 0, 0);
@@ -1401,21 +1406,22 @@
 		return;
 #endif
 	}
-	save_flags(flags); cli();
+	/* lock while modifying beep_timer */
+	spin_lock_irqsave(&cs4218_lock, flags);
 	del_timer(&beep_timer);
 	if (ticks) {
 		beep_timer.expires = jiffies + ticks;
 		add_timer(&beep_timer);
 	}
 	if (beep_playing || sq.active || beep_buf == NULL) {
-		restore_flags(flags);
+		spin_unlock_irqrestore(&cs4218_lock, flags);
 		return;		/* too hard, sorry :-( */
 	}
 	beep_playing = 1;
 #if 0
 	st_le16(&beep_dbdma_cmd->command, OUTPUT_MORE + BR_ALWAYS);
 #endif
-	restore_flags(flags);
+	spin_unlock_irqrestore(&cs4218_lock, flags);
 
 	if (hz == beep_hz_cache && beep_volume == beep_volume_cache) {
 		nsamples = beep_nsamples_cache;
@@ -1442,7 +1448,7 @@
 	st_le32(&beep_dbdma_cmd->phy_addr, virt_to_bus(beep_buf));
 	awacs_beep_state = 1;
 
-	save_flags(flags); cli();
+	spin_lock_irqsave(&cs4218_lock, flags);
 	if (beep_playing) {	/* i.e. haven't been terminated already */
 		out_le32(&awacs_txdma->control, (RUN|WAKE|FLUSH|PAUSE) << 16);
 		out_le32(&awacs->control,
@@ -1452,8 +1458,8 @@
 		out_le32(&awacs_txdma->cmdptr, virt_to_bus(beep_dbdma_cmd));
 		out_le32(&awacs_txdma->control, RUN | (RUN << 16));
 	}
+	spin_unlock_irqrestore(&cs4218_lock, flags);
 #endif
-	restore_flags(flags);
 }
 
 static MACHINE mach_cs4218 = {
diff -Nru a/arch/ppc/8xx_io/fec.c b/arch/ppc/8xx_io/fec.c
--- a/arch/ppc/8xx_io/fec.c	2005-03-01 23:39:16 -08:00
+++ b/arch/ppc/8xx_io/fec.c	2005-03-01 23:39:16 -08:00
@@ -389,6 +389,7 @@
 	flush_dcache_range((unsigned long)skb->data,
 			   (unsigned long)skb->data + skb->len);
 
+	/* disable interrupts while triggering transmit */
 	spin_lock_irq(&fep->lock);
 
 	/* Send it on its way.  Tell FEC its ready, interrupt when done,
@@ -539,6 +540,7 @@
 	struct	sk_buff	*skb;
 
 	fep = dev->priv;
+	/* lock while transmitting */
 	spin_lock(&fep->lock);
 	bdp = fep->dirty_tx;
 
@@ -799,6 +801,7 @@
 
 	if ((mip = mii_head) != NULL) {
 		ep->fec_mii_data = mip->mii_regval;
+
 	}
 }
 
@@ -817,8 +820,8 @@
 
 	retval = 0;
 
-	save_flags(flags);
-	cli();
+	/* lock while modifying mii_list */
+	spin_lock_irqsave(&fep->lock, flags);
 
 	if ((mip = mii_free) != NULL) {
 		mii_free = mip->mii_next;
@@ -836,7 +839,7 @@
 		retval = 1;
 	}
 
-	restore_flags(flags);
+	spin_unlock_irqrestore(&fep->lock, flags);
 
 	return(retval);
 }
diff -Nru a/arch/ppc/Kconfig b/arch/ppc/Kconfig
--- a/arch/ppc/Kconfig	2005-03-01 23:39:17 -08:00
+++ b/arch/ppc/Kconfig	2005-03-01 23:39:17 -08:00
@@ -22,6 +22,10 @@
 	bool
 	default y
 
+config GENERIC_CALIBRATE_DELAY
+	bool
+	default y
+
 config HAVE_DEC_LOCK
 	bool
 	default y
@@ -97,6 +101,11 @@
 	depends on 44x
 	default y
 
+config PHYS_64BIT
+	bool
+	depends on 44x
+	default y
+
 config ALTIVEC
 	bool "AltiVec Support"
 	depends on 6xx || POWER4
@@ -317,7 +326,7 @@
 
 	  HERMES:
 	  Hermes-Pro ISDN/LAN router with integrated 8 x hub
-	  Manufacturer: Multidata Gesellschaft fÃ¼r Datentechnik und Informatik
+	  Manufacturer: Multidata Gesellschaft fur Datentechnik und Informatik
 	  <http://www.multidata.de/>
 	  Date of Release: 2000 (?)
 	  End of life: -
@@ -500,21 +509,41 @@
 	  More information is available at:
 	  <http://linux-apus.sourceforge.net/>.
 
+config KATANA
+	bool "Artesyn-Katana"
+	help
+	  Select KATANA if configuring an Artesyn KATANA 750i or 3750
+	  cPCI board.
+
 config WILLOW
 	bool "Cogent-Willow"
 
+config CPCI690
+	bool "Force-CPCI690"
+	help
+	  Select CPCI690 if configuring a Force CPCI690 cPCI board.
+
 config PCORE
 	bool "Force-PowerCore"
 
 config POWERPMC250
 	bool "Force-PowerPMC250"
 
-config EV64260
-	bool "Galileo-EV-64260-BP"
+config CHESTNUT
+	bool "IBM 750FX Eval board or 750GX Eval board"
+	help
+	  Select CHESTNUT if configuring an IBM 750FX Eval Board or a
+	  IBM 750GX Eval board.
 
 config SPRUCE
 	bool "IBM-Spruce"
 
+config EV64260
+	bool "Marvell-EV64260BP"
+	help
+	  Select EV64260 if configuring a Marvell (formerly Galileo)
+	  EV64260BP Evaluation platform.
+
 config LOPEC
 	bool "Motorola-LoPEC"
 
@@ -594,6 +623,12 @@
 config ADS8272
 	bool "ADS8272"
 
+config PQ2FADS
+	bool "Freescale-PQ2FADS"
+	help
+	  Select PQ2FADS if you wish to configure for a Freescale
+	  PQ2FADS board (-VR or -ZU).
+
 config LITE5200
 	bool "Freescale LITE5200 / (IceCube)"
 	select PPC_MPC52xx
@@ -626,7 +661,7 @@
 config 8260
 	bool "CPM2 Support" if WILLOW
 	depends on 6xx
-	default y if TQM8260 || RPX8260 || EST8260 || SBS8260 || SBC82xx
+	default y if TQM8260 || RPX8260 || EST8260 || SBS8260 || SBC82xx || PQ2FADS
 	help
 	  The MPC8260 is a typical embedded CPU made by Motorola.  Selecting
 	  this option means that you wish to build a kernel for a machine with
@@ -643,7 +678,7 @@
 
 config CPM2
 	bool
-	depends on 8260 || MPC8560
+	depends on 8260 || MPC8560 || MPC8555
 	default y
 	help
 	  The CPM2 (Communications Processor Module) is a coprocessor on
@@ -679,7 +714,8 @@
 config PPC_GEN550
 	bool
 	depends on SANDPOINT || MCPN765 || SPRUCE || PPLUS || PCORE || \
-		PRPMC750 || K2 || PRPMC800 || LOPEC
+		PRPMC750 || K2 || PRPMC800 || LOPEC || \
+		(EV64260 && !SERIAL_MPSC) || CHESTNUT
 	default y
 
 config FORCE
@@ -689,8 +725,52 @@
 
 config GT64260
 	bool
-	depends on EV64260
+	depends on EV64260 || CPCI690
+	default y
+
+config MV64360
+	bool
+	depends on KATANA
+	default y
+
+config MV64360
+	bool
+	depends on CHESTNUT
+  	default y
+
+config MV64X60
+	bool
+	depends on (GT64260 || MV64360)
 	default y
+
+menu "Set bridge options"
+	depends on MV64X60
+
+config NOT_COHERENT_CACHE
+	bool "Turn off Cache Coherency"
+	default n
+	help
+	  Some 64x60 bridges lock up when trying to enforce cache coherency.
+	  When this option is selected, cache coherency will be turned off.
+	  Note that this can cause other problems (e.g., stale data being
+	  speculatively loaded via a cached mapping).  Use at your own risk.
+
+config MV64X60_BASE
+	hex "Set bridge base used by firmware"
+	default "0xf1000000"
+	help
+	  A firmware can leave the base address of the bridge's registers at
+	  a non-standard location.  If so, set this value to reflect the
+	  address of that non-standard location.
+
+config MV64X60_NEW_BASE
+	hex "Set bridge base used by kernel"
+	default "0xf1000000"
+	help
+	  If the current base address of the bridge's registers is not where
+	  you want it, set this value to the address that you want it moved to.
+
+endmenu
 
 config NONMONARCH_SUPPORT
 	bool "Enable Non-Monarch Support"
diff -Nru a/arch/ppc/Makefile b/arch/ppc/Makefile
--- a/arch/ppc/Makefile	2005-03-01 23:38:52 -08:00
+++ b/arch/ppc/Makefile	2005-03-01 23:38:52 -08:00
@@ -42,6 +42,9 @@
 AFLAGS += $(cpu-as-y)
 CFLAGS += $(cpu-as-y)
 
+# Default to the common case.
+KBUILD_DEFCONFIG := common_defconfig
+
 head-y				:= arch/ppc/kernel/head.o
 head-$(CONFIG_8xx)		:= arch/ppc/kernel/head_8xx.o
 head-$(CONFIG_4xx)		:= arch/ppc/kernel/head_4xx.o
@@ -68,7 +71,7 @@
 
 .PHONY: $(BOOT_TARGETS)
 
-all: zImage
+all: uImage zImage
 
 CPPFLAGS_vmlinux.lds	:= -Upowerpc
 
diff -Nru a/arch/ppc/boot/common/misc-common.c b/arch/ppc/boot/common/misc-common.c
--- a/arch/ppc/boot/common/misc-common.c	2005-03-01 23:38:57 -08:00
+++ b/arch/ppc/boot/common/misc-common.c	2005-03-01 23:38:57 -08:00
@@ -52,7 +52,6 @@
 void puts(const char *);
 void putc(const char c);
 void puthex(unsigned long val);
-void _bcopy(char *src, char *dst, int len);
 void gunzip(void *, int, unsigned char *, int *);
 static int _cvt(unsigned long val, char *buf, long radix, char *digits);
 
@@ -60,7 +59,8 @@
 unsigned char *ISA_io = NULL;
 
 #if defined(CONFIG_SERIAL_CPM_CONSOLE) || defined(CONFIG_SERIAL_8250_CONSOLE) \
-	|| defined(CONFIG_SERIAL_MPC52xx_CONSOLE)
+	|| defined(CONFIG_SERIAL_MPC52xx_CONSOLE) \
+	|| defined(CONFIG_SERIAL_MPSC_CONSOLE)
 extern unsigned long com_port;
 
 extern int serial_tstc(unsigned long com_port);
@@ -82,7 +82,8 @@
 int tstc(void)
 {
 #if defined(CONFIG_SERIAL_CPM_CONSOLE) || defined(CONFIG_SERIAL_8250_CONSOLE) \
-	|| defined(CONFIG_SERIAL_MPC52xx_CONSOLE)
+	|| defined(CONFIG_SERIAL_MPC52xx_CONSOLE) \
+	|| defined(CONFIG_SERIAL_MPSC_CONSOLE)
 	if(keyb_present)
 		return (CRT_tstc() || serial_tstc(com_port));
 	else
@@ -96,7 +97,8 @@
 {
 	while (1) {
 #if defined(CONFIG_SERIAL_CPM_CONSOLE) || defined(CONFIG_SERIAL_8250_CONSOLE) \
-	|| defined(CONFIG_SERIAL_MPC52xx_CONSOLE)
+	|| defined(CONFIG_SERIAL_MPC52xx_CONSOLE) \
+	|| defined(CONFIG_SERIAL_MPSC_CONSOLE)
 		if (serial_tstc(com_port))
 			return (serial_getc(com_port));
 #endif /* serial console */
@@ -112,7 +114,8 @@
 	int x,y;
 
 #if defined(CONFIG_SERIAL_CPM_CONSOLE) || defined(CONFIG_SERIAL_8250_CONSOLE) \
-	|| defined(CONFIG_SERIAL_MPC52xx_CONSOLE)
+	|| defined(CONFIG_SERIAL_MPC52xx_CONSOLE) \
+	|| defined(CONFIG_SERIAL_MPSC_CONSOLE)
 	serial_putc(com_port, c);
 	if ( c == '\n' )
 		serial_putc(com_port, '\r');
@@ -160,7 +163,8 @@
 
 	while ( ( c = *s++ ) != '\0' ) {
 #if defined(CONFIG_SERIAL_CPM_CONSOLE) || defined(CONFIG_SERIAL_8250_CONSOLE) \
-	|| defined(CONFIG_SERIAL_MPC52xx_CONSOLE)
+	|| defined(CONFIG_SERIAL_MPC52xx_CONSOLE) \
+	|| defined(CONFIG_SERIAL_MPSC_CONSOLE)
 	        serial_putc(com_port, c);
 	        if ( c == '\n' ) serial_putc(com_port, '\r');
 #endif /* serial console */
diff -Nru a/arch/ppc/boot/include/mpsc_defs.h b/arch/ppc/boot/include/mpsc_defs.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/ppc/boot/include/mpsc_defs.h	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,146 @@
+/*
+ * drivers/serial/mpsc/mpsc_defs.h
+ *
+ * Register definitions for the Marvell Multi-Protocol Serial Controller (MPSC),
+ * Serial DMA Controller (SDMA), and Baud Rate Generator (BRG).
+ *
+ * Author: Mark A. Greer <mgreer@mvista.com>
+ *
+ * 2004 (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.
+ */
+#ifndef	_PPC_BOOT_MPSC_DEFS_H__
+#define	_PPC_BOOT_MPSC_DEFS_H__
+
+#define	MPSC_NUM_CTLRS		2
+
+/*
+ *****************************************************************************
+ *
+ *	Multi-Protocol Serial Controller Interface Registers
+ *
+ *****************************************************************************
+ */
+
+/* Main Configuratino Register Offsets */
+#define	MPSC_MMCRL			0x0000
+#define	MPSC_MMCRH			0x0004
+#define	MPSC_MPCR			0x0008
+#define	MPSC_CHR_1			0x000c
+#define	MPSC_CHR_2			0x0010
+#define	MPSC_CHR_3			0x0014
+#define	MPSC_CHR_4			0x0018
+#define	MPSC_CHR_5			0x001c
+#define	MPSC_CHR_6			0x0020
+#define	MPSC_CHR_7			0x0024
+#define	MPSC_CHR_8			0x0028
+#define	MPSC_CHR_9			0x002c
+#define	MPSC_CHR_10			0x0030
+#define	MPSC_CHR_11			0x0034
+
+#define	MPSC_MPCR_CL_5			0
+#define	MPSC_MPCR_CL_6			1
+#define	MPSC_MPCR_CL_7			2
+#define	MPSC_MPCR_CL_8			3
+#define	MPSC_MPCR_SBL_1			0
+#define	MPSC_MPCR_SBL_2			3
+
+#define	MPSC_CHR_2_TEV			(1<<1)
+#define	MPSC_CHR_2_TA			(1<<7)
+#define	MPSC_CHR_2_TTCS			(1<<9)
+#define	MPSC_CHR_2_REV			(1<<17)
+#define	MPSC_CHR_2_RA			(1<<23)
+#define	MPSC_CHR_2_CRD			(1<<25)
+#define	MPSC_CHR_2_EH			(1<<31)
+#define	MPSC_CHR_2_PAR_ODD		0
+#define	MPSC_CHR_2_PAR_SPACE		1
+#define	MPSC_CHR_2_PAR_EVEN		2
+#define	MPSC_CHR_2_PAR_MARK		3
+
+/* MPSC Signal Routing */
+#define	MPSC_MRR			0x0000
+#define	MPSC_RCRR			0x0004
+#define	MPSC_TCRR			0x0008
+
+/*
+ *****************************************************************************
+ *
+ *	Serial DMA Controller Interface Registers
+ *
+ *****************************************************************************
+ */
+
+#define	SDMA_SDC			0x0000
+#define	SDMA_SDCM			0x0008
+#define	SDMA_RX_DESC			0x0800
+#define	SDMA_RX_BUF_PTR			0x0808
+#define	SDMA_SCRDP			0x0810
+#define	SDMA_TX_DESC			0x0c00
+#define	SDMA_SCTDP			0x0c10
+#define	SDMA_SFTDP			0x0c14
+
+#define	SDMA_DESC_CMDSTAT_PE		(1<<0)
+#define	SDMA_DESC_CMDSTAT_CDL		(1<<1)
+#define	SDMA_DESC_CMDSTAT_FR		(1<<3)
+#define	SDMA_DESC_CMDSTAT_OR		(1<<6)
+#define	SDMA_DESC_CMDSTAT_BR		(1<<9)
+#define	SDMA_DESC_CMDSTAT_MI		(1<<10)
+#define	SDMA_DESC_CMDSTAT_A		(1<<11)
+#define	SDMA_DESC_CMDSTAT_AM		(1<<12)
+#define	SDMA_DESC_CMDSTAT_CT		(1<<13)
+#define	SDMA_DESC_CMDSTAT_C		(1<<14)
+#define	SDMA_DESC_CMDSTAT_ES		(1<<15)
+#define	SDMA_DESC_CMDSTAT_L		(1<<16)
+#define	SDMA_DESC_CMDSTAT_F		(1<<17)
+#define	SDMA_DESC_CMDSTAT_P		(1<<18)
+#define	SDMA_DESC_CMDSTAT_EI		(1<<23)
+#define	SDMA_DESC_CMDSTAT_O		(1<<31)
+
+#define SDMA_DESC_DFLT			(SDMA_DESC_CMDSTAT_O |	\
+					SDMA_DESC_CMDSTAT_EI)
+
+#define	SDMA_SDC_RFT			(1<<0)
+#define	SDMA_SDC_SFM			(1<<1)
+#define	SDMA_SDC_BLMR			(1<<6)
+#define	SDMA_SDC_BLMT			(1<<7)
+#define	SDMA_SDC_POVR			(1<<8)
+#define	SDMA_SDC_RIFB			(1<<9)
+
+#define	SDMA_SDCM_ERD			(1<<7)
+#define	SDMA_SDCM_AR			(1<<15)
+#define	SDMA_SDCM_STD			(1<<16)
+#define	SDMA_SDCM_TXD			(1<<23)
+#define	SDMA_SDCM_AT			(1<<31)
+
+#define	SDMA_0_CAUSE_RXBUF		(1<<0)
+#define	SDMA_0_CAUSE_RXERR		(1<<1)
+#define	SDMA_0_CAUSE_TXBUF		(1<<2)
+#define	SDMA_0_CAUSE_TXEND		(1<<3)
+#define	SDMA_1_CAUSE_RXBUF		(1<<8)
+#define	SDMA_1_CAUSE_RXERR		(1<<9)
+#define	SDMA_1_CAUSE_TXBUF		(1<<10)
+#define	SDMA_1_CAUSE_TXEND		(1<<11)
+
+#define	SDMA_CAUSE_RX_MASK	(SDMA_0_CAUSE_RXBUF | SDMA_0_CAUSE_RXERR | \
+	SDMA_1_CAUSE_RXBUF | SDMA_1_CAUSE_RXERR)
+#define	SDMA_CAUSE_TX_MASK	(SDMA_0_CAUSE_TXBUF | SDMA_0_CAUSE_TXEND | \
+	SDMA_1_CAUSE_TXBUF | SDMA_1_CAUSE_TXEND)
+
+/* SDMA Interrupt registers */
+#define	SDMA_INTR_CAUSE			0x0000
+#define	SDMA_INTR_MASK			0x0080
+
+/*
+ *****************************************************************************
+ *
+ *	Baud Rate Generator Interface Registers
+ *
+ *****************************************************************************
+ */
+
+#define	BRG_BCR				0x0000
+#define	BRG_BTR				0x0004
+
+#endif /*_PPC_BOOT_MPSC_DEFS_H__ */
diff -Nru a/arch/ppc/boot/simple/Makefile b/arch/ppc/boot/simple/Makefile
--- a/arch/ppc/boot/simple/Makefile	2005-03-01 23:38:44 -08:00
+++ b/arch/ppc/boot/simple/Makefile	2005-03-01 23:38:44 -08:00
@@ -47,6 +47,12 @@
 # See arch/ppc/kconfig and arch/ppc/platforms/Kconfig
 # for definition of what platform each config option refer to.
 #----------------------------------------------------------------------------
+      zimage-$(CONFIG_CPCI690)		:= zImage-STRIPELF
+zimageinitrd-$(CONFIG_CPCI690)		:= zImage.initrd-STRIPELF
+     extra.o-$(CONFIG_CPCI690)		:= misc-cpci690.o mv64x60_stub.o
+         end-$(CONFIG_CPCI690)		:= cpci690
+   cacheflag-$(CONFIG_CPCI690)		:= -include $(clear_L2_L3)
+
       zimage-$(CONFIG_IBM_OPENBIOS)	:= zImage-TREE
 zimageinitrd-$(CONFIG_IBM_OPENBIOS)	:= zImage.initrd-TREE
          end-$(CONFIG_IBM_OPENBIOS)	:= treeboot
@@ -60,16 +66,25 @@
          end-$(CONFIG_EBONY)		:= ebony
   entrypoint-$(CONFIG_EBONY)		:= 0x01000000
 
+      zimage-$(CONFIG_LUAN)		:= zImage-TREE
+zimageinitrd-$(CONFIG_LUAN)		:= zImage.initrd-TREE
+         end-$(CONFIG_LUAN)		:= luan
+  entrypoint-$(CONFIG_LUAN)		:= 0x01000000
+     extra.o-$(CONFIG_LUAN)		:= pibs.o
+
       zimage-$(CONFIG_OCOTEA)		:= zImage-TREE
 zimageinitrd-$(CONFIG_OCOTEA)		:= zImage.initrd-TREE
          end-$(CONFIG_OCOTEA)		:= ocotea
   entrypoint-$(CONFIG_OCOTEA)		:= 0x01000000
      extra.o-$(CONFIG_OCOTEA)		:= pibs.o
 
-     extra.o-$(CONFIG_EV64260)		:= direct.o misc-ev64260.o
+     extra.o-$(CONFIG_EV64260)		:= misc-ev64260.o
          end-$(CONFIG_EV64260)		:= ev64260
    cacheflag-$(CONFIG_EV64260)		:= -include $(clear_L2_L3)
 
+     extra.o-$(CONFIG_CHESTNUT)		:= misc-chestnut.o
+         end-$(CONFIG_CHESTNUT)		:= chestnut
+
       zimage-$(CONFIG_GEMINI)		:= zImage-STRIPELF
 zimageinitrd-$(CONFIG_GEMINI)		:= zImage.initrd-STRIPELF
          end-$(CONFIG_GEMINI)		:= gemini
@@ -78,6 +93,10 @@
          end-$(CONFIG_K2)		:= k2
    cacheflag-$(CONFIG_K2)		:= -include $(clear_L2_L3)
 
+     extra.o-$(CONFIG_KATANA)		:= misc-katana.o mv64x60_stub.o
+         end-$(CONFIG_KATANA)		:= katana
+   cacheflag-$(CONFIG_KATANA)		:= -include $(clear_L2_L3)
+
 # kconfig 'feature', only one of these will ever be 'y' at a time.
 # The rest will be unset.
 motorola := $(CONFIG_MCPN765)$(CONFIG_MVME5100)$(CONFIG_PRPMC750) \
@@ -143,6 +162,7 @@
 boot-$(CONFIG_8260)		+= embed_config.o
 boot-$(CONFIG_BSEIP)		+= iic.o
 boot-$(CONFIG_MBX)		+= iic.o pci.o qspan_pci.o
+boot-$(CONFIG_MV64X60)		+= misc-mv64x60.o
 boot-$(CONFIG_RPXCLASSIC)	+= iic.o pci.o qspan_pci.o
 boot-$(CONFIG_RPXLITE)		+= iic.o
 # Different boards need different serial implementations.
@@ -150,8 +170,8 @@
 boot-$(CONFIG_8xx)		+= m8xx_tty.o
 boot-$(CONFIG_8260)		+= m8260_tty.o
 endif
-boot-$(CONFIG_SERIAL_MPC52xx_CONSOLE) += mpc52xx_tty.o
-boot-$(CONFIG_GT64260_CONSOLE)	+= gt64260_tty.o
+boot-$(CONFIG_SERIAL_MPC52xx_CONSOLE)	+= mpc52xx_tty.o
+boot-$(CONFIG_SERIAL_MPSC_CONSOLE)	+= mv64x60_tty.o
 
 LIBS				:= $(common)/lib.a $(bootlib)/lib.a
 ifeq ($(CONFIG_PPC_PREP),y)
diff -Nru a/arch/ppc/boot/simple/gt64260_tty.c b/arch/ppc/boot/simple/gt64260_tty.c
--- a/arch/ppc/boot/simple/gt64260_tty.c	2005-03-01 23:38:56 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,322 +0,0 @@
-/*
- * arch/ppc/boot/simple/gt64260_tty.c
- *
- * Bootloader version of the embedded MPSC/UART driver for the GT64260[A].
- * Note: Due to 64260A errata, DMA will be used for UART input (via SDMA).
- *
- * Author: Mark A. Greer <mgreer@mvista.com>
- *
- * 2001 (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 code assumes that the data cache has been disabled (L1, L2, L3). */
-
-#include <linux/config.h>
-#include <linux/serialP.h>
-#include <linux/serial_reg.h>
-#include <asm/serial.h>
-#include <asm/gt64260_defs.h>
-
-extern void udelay(long);
-static void stop_dma(int chan);
-
-static u32	gt64260_base = EV64260_BRIDGE_REG_BASE; /* base addr of 64260 */
-
-inline unsigned
-gt64260_in_le32(volatile unsigned *addr)
-{
-	unsigned ret;
-
-	__asm__ __volatile__("lwbrx %0,0,%1; eieio" : "=r" (ret) :
-				     "r" (addr), "m" (*addr));
-	return ret;
-}
-
-inline void
-gt64260_out_le32(volatile unsigned *addr, int val)
-{
-	__asm__ __volatile__("stwbrx %1,0,%2; eieio" : "=m" (*addr) :
-				     "r" (val), "r" (addr));
-}
-
-#define GT64260_REG_READ(offs)						\
-	(gt64260_in_le32((volatile uint *)(gt64260_base + (offs))))
-#define GT64260_REG_WRITE(offs, d)					\
-        (gt64260_out_le32((volatile uint *)(gt64260_base + (offs)), (int)(d)))
-
-
-static struct {
-	u32	sdc;
-	u32	sdcm;
-	u32	rx_desc;
-	u32	rx_buf_ptr;
-	u32	scrdp;
-	u32	tx_desc;
-	u32	sctdp;
-	u32	sftdp;
-} sdma_regs;
-
-#define	SDMA_REGS_INIT(chan) {						\
-	sdma_regs.sdc        = GT64260_SDMA_##chan##_SDC;		\
-	sdma_regs.sdcm       = GT64260_SDMA_##chan##_SDCM;		\
-	sdma_regs.rx_desc    = GT64260_SDMA_##chan##_RX_DESC;		\
-	sdma_regs.rx_buf_ptr = GT64260_SDMA_##chan##_RX_BUF_PTR;	\
-	sdma_regs.scrdp      = GT64260_SDMA_##chan##_SCRDP;		\
-	sdma_regs.tx_desc    = GT64260_SDMA_##chan##_TX_DESC;		\
-	sdma_regs.sctdp      = GT64260_SDMA_##chan##_SCTDP;		\
-	sdma_regs.sftdp      = GT64260_SDMA_##chan##_SFTDP;		\
-}
-
-typedef struct {
-	volatile u16 bufsize;
-	volatile u16 bytecnt;
-	volatile u32 cmd_stat;
-	volatile u32 next_desc_ptr;
-	volatile u32 buffer;
-} gt64260_rx_desc_t;
-
-typedef struct {
-	volatile u16 bytecnt;
-	volatile u16 shadow;
-	volatile u32 cmd_stat;
-	volatile u32 next_desc_ptr;
-	volatile u32 buffer;
-} gt64260_tx_desc_t;
-
-#define	MAX_RESET_WAIT	10000
-#define	MAX_TX_WAIT	10000
-
-#define	RX_NUM_DESC	2
-#define	TX_NUM_DESC	2
-
-#define	RX_BUF_SIZE	16
-#define	TX_BUF_SIZE	16
-
-static gt64260_rx_desc_t rd[RX_NUM_DESC] __attribute__ ((aligned(32)));
-static gt64260_tx_desc_t td[TX_NUM_DESC] __attribute__ ((aligned(32)));
-
-static char rx_buf[RX_NUM_DESC * RX_BUF_SIZE] __attribute__ ((aligned(32)));
-static char tx_buf[TX_NUM_DESC * TX_BUF_SIZE] __attribute__ ((aligned(32)));
-
-static int cur_rd = 0;
-static int cur_td = 0;
-
-
-#define	RX_INIT_RDP(rdp) {						\
-	(rdp)->bufsize = 2;						\
-	(rdp)->bytecnt = 0;						\
-	(rdp)->cmd_stat = GT64260_SDMA_DESC_CMDSTAT_L |			\
-			  GT64260_SDMA_DESC_CMDSTAT_F |			\
-			  GT64260_SDMA_DESC_CMDSTAT_O;			\
-}
-
-unsigned long
-serial_init(int chan, void *ignored)
-{
-	u32	mpsc_adjust, sdma_adjust, brg_bcr;
-	int	i;
-
-	stop_dma(0);
-	stop_dma(1);
-
-	if (chan != 1) {
-		chan = 0;  /* default to chan 0 if anything but 1 */
-		mpsc_adjust = 0;
-		sdma_adjust = 0;
-		brg_bcr = GT64260_BRG_0_BCR;
-		SDMA_REGS_INIT(0);
-	}
-	else {
-		mpsc_adjust = 0x1000;
-		sdma_adjust = 0x2000;
-		brg_bcr = GT64260_BRG_1_BCR;
-		SDMA_REGS_INIT(1);
-	}
-
-	/* Set up ring buffers */
-	for (i=0; i<RX_NUM_DESC; i++) {
-		RX_INIT_RDP(&rd[i]);
-		rd[i].buffer = (u32)&rx_buf[i * RX_BUF_SIZE];
-		rd[i].next_desc_ptr = (u32)&rd[i+1];
-	}
-	rd[RX_NUM_DESC - 1].next_desc_ptr = (u32)&rd[0];
-
-	for (i=0; i<TX_NUM_DESC; i++) {
-		td[i].bytecnt = 0;
-		td[i].shadow = 0;
-		td[i].buffer = (u32)&tx_buf[i * TX_BUF_SIZE];
-		td[i].cmd_stat = GT64260_SDMA_DESC_CMDSTAT_F |
-				 GT64260_SDMA_DESC_CMDSTAT_L;
-		td[i].next_desc_ptr = (u32)&td[i+1];
-	}
-	td[TX_NUM_DESC - 1].next_desc_ptr = (u32)&td[0];
-
-	/* Set MPSC Routing */
-        GT64260_REG_WRITE(GT64260_MPSC_MRR, 0x3ffffe38);
-        GT64260_REG_WRITE(GT64260_MPP_SERIAL_PORTS_MULTIPLEX, 0x00001102);
-
-	/* MPSC 0/1 Rx & Tx get clocks BRG0/1 */
-        GT64260_REG_WRITE(GT64260_MPSC_RCRR, 0x00000100);
-        GT64260_REG_WRITE(GT64260_MPSC_TCRR, 0x00000100);
-
-	/* clear pending interrupts */
-        GT64260_REG_WRITE(GT64260_SDMA_INTR_MASK, 0);
-
-	GT64260_REG_WRITE(GT64260_SDMA_0_SCRDP + sdma_adjust, &rd[0]);
-	GT64260_REG_WRITE(GT64260_SDMA_0_SCTDP + sdma_adjust,
-		&td[TX_NUM_DESC - 1]);
-	GT64260_REG_WRITE(GT64260_SDMA_0_SFTDP + sdma_adjust,
-		&td[TX_NUM_DESC - 1]);
-
-	GT64260_REG_WRITE(GT64260_SDMA_0_SDC + sdma_adjust,
-			  GT64260_SDMA_SDC_RFT | GT64260_SDMA_SDC_SFM |
-			  GT64260_SDMA_SDC_BLMR | GT64260_SDMA_SDC_BLMT |
-			  (3 << 12));
-
-	/* Set BRG to generate proper baud rate */
-	GT64260_REG_WRITE(brg_bcr, ((8 << 18) | (1 << 16) | 36));
-
-	/* Put MPSC into UART mode, no null modem, 16x clock mode */
-	GT64260_REG_WRITE(GT64260_MPSC_0_MMCRL + mpsc_adjust, 0x000004c4);
-	GT64260_REG_WRITE(GT64260_MPSC_0_MMCRH + mpsc_adjust, 0x04400400);
-
-        GT64260_REG_WRITE(GT64260_MPSC_0_CHR_1 + mpsc_adjust, 0);
-        GT64260_REG_WRITE(GT64260_MPSC_0_CHR_9 + mpsc_adjust, 0);
-        GT64260_REG_WRITE(GT64260_MPSC_0_CHR_10 + mpsc_adjust, 0);
-        GT64260_REG_WRITE(GT64260_MPSC_0_CHR_3 + mpsc_adjust, 4);
-        GT64260_REG_WRITE(GT64260_MPSC_0_CHR_4 + mpsc_adjust, 0);
-        GT64260_REG_WRITE(GT64260_MPSC_0_CHR_5 + mpsc_adjust, 0);
-        GT64260_REG_WRITE(GT64260_MPSC_0_CHR_6 + mpsc_adjust, 0);
-        GT64260_REG_WRITE(GT64260_MPSC_0_CHR_7 + mpsc_adjust, 0);
-        GT64260_REG_WRITE(GT64260_MPSC_0_CHR_8 + mpsc_adjust, 0);
-
-	/* 8 data bits, 1 stop bit */
-	GT64260_REG_WRITE(GT64260_MPSC_0_MPCR + mpsc_adjust, (3 << 12));
-
-	GT64260_REG_WRITE(GT64260_SDMA_0_SDCM + sdma_adjust,
-		GT64260_SDMA_SDCM_ERD);
-
-	GT64260_REG_WRITE(GT64260_MPSC_0_CHR_2 + sdma_adjust,
-		GT64260_MPSC_UART_CR_EH);
-
-	udelay(100);
-
-	return (ulong)chan;
-}
-
-static void
-stop_dma(int chan)
-{
-	u32	sdma_sdcm = GT64260_SDMA_0_SDCM;
-	int	i;
-
-	if (chan == 1) {
-		sdma_sdcm = GT64260_SDMA_1_SDCM;
-	}
-
-	/* Abort SDMA Rx, Tx */
-	GT64260_REG_WRITE(sdma_sdcm,
-		GT64260_SDMA_SDCM_AR | GT64260_SDMA_SDCM_STD);
-
-	for (i=0; i<MAX_RESET_WAIT; i++) {
-		if ((GT64260_REG_READ(sdma_sdcm) & (GT64260_SDMA_SDCM_AR |
-					GT64260_SDMA_SDCM_AT)) == 0) break;
-		udelay(100);
-	}
-
-	return;
-}
-
-static int
-wait_for_ownership(void)
-{
-	int	i;
-
-	for (i=0; i<MAX_TX_WAIT; i++) {
-		if ((GT64260_REG_READ(sdma_regs.sdcm) &
-					GT64260_SDMA_SDCM_TXD) == 0) break;
-		udelay(1000);
-	}
-
-	return (i < MAX_TX_WAIT);
-}
-
-void
-serial_putc(unsigned long com_port, unsigned char c)
-{
-	gt64260_tx_desc_t	*tdp;
-
-	if (wait_for_ownership() == 0) return;
-
-	tdp = &td[cur_td];
-	if (++cur_td >= TX_NUM_DESC) cur_td = 0;
-
-	*(unchar *)(tdp->buffer ^ 7) = c;
-	tdp->bytecnt = 1;
-	tdp->shadow = 1;
-	tdp->cmd_stat = GT64260_SDMA_DESC_CMDSTAT_L |
-		GT64260_SDMA_DESC_CMDSTAT_F | GT64260_SDMA_DESC_CMDSTAT_O;
-
-	GT64260_REG_WRITE(sdma_regs.sctdp, tdp);
-	GT64260_REG_WRITE(sdma_regs.sftdp, tdp);
-	GT64260_REG_WRITE(sdma_regs.sdcm,
-		GT64260_REG_READ(sdma_regs.sdcm) | GT64260_SDMA_SDCM_TXD);
-
-	return;
-}
-
-unsigned char
-serial_getc(unsigned long com_port)
-{
-	gt64260_rx_desc_t	*rdp;
-	unchar			c = '\0';
-
-	rdp = &rd[cur_rd];
-
-	if ((rdp->cmd_stat & (GT64260_SDMA_DESC_CMDSTAT_O |
-			      GT64260_SDMA_DESC_CMDSTAT_ES)) == 0) {
-		c = *(unchar *)(rdp->buffer ^ 7);
-		RX_INIT_RDP(rdp);
-		if (++cur_rd >= RX_NUM_DESC) cur_rd = 0;
-	}
-
-	return c;
-}
-
-int
-serial_tstc(unsigned long com_port)
-{
-	gt64260_rx_desc_t	*rdp;
-	int			loop_count = 0;
-	int			rc = 0;
-
-	rdp = &rd[cur_rd];
-
-	/* Go thru rcv desc's until empty looking for one with data (no error)*/
-	while (((rdp->cmd_stat & GT64260_SDMA_DESC_CMDSTAT_O) == 0) &&
-	       (loop_count++ < RX_NUM_DESC)) {
-
-		/* If there was an error, reinit the desc & continue */
-		if ((rdp->cmd_stat & GT64260_SDMA_DESC_CMDSTAT_ES) != 0) {
-			RX_INIT_RDP(rdp);
-			if (++cur_rd >= RX_NUM_DESC) cur_rd = 0;
-			rdp = (gt64260_rx_desc_t *)rdp->next_desc_ptr;
-		}
-		else {
-			rc = 1;
-			break;
-		}
-	}
-
-	return rc;
-}
-
-void
-serial_close(unsigned long com_port)
-{
-	stop_dma(com_port);
-	return;
-}
diff -Nru a/arch/ppc/boot/simple/head.S b/arch/ppc/boot/simple/head.S
--- a/arch/ppc/boot/simple/head.S	2005-03-01 23:39:07 -08:00
+++ b/arch/ppc/boot/simple/head.S	2005-03-01 23:39:07 -08:00
@@ -135,9 +135,9 @@
 			 */
 #endif
 
-#ifdef	CONFIG_EV64260
-	/* Move 64260's base regs & CS window for external UART */
-	bl	ev64260_init
+#ifdef	CONFIG_MV64X60
+	/* mv64x60 specific hook to do things like moving register base, etc. */
+	bl	mv64x60_init
 #endif
 
 	/* Get the load address.
diff -Nru a/arch/ppc/boot/simple/misc-chestnut.S b/arch/ppc/boot/simple/misc-chestnut.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/ppc/boot/simple/misc-chestnut.S	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,41 @@
+/*
+ * arch/ppc/boot/simple/misc-chestnut.S
+ *
+ * Setup for the IBM Chestnut (ibm-750fxgx_eval)
+ *
+ * Author: <source@mvista.com>
+ *
+ * <2004> (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 <asm/ppc_asm.h>
+#include <asm/mv64x60_defs.h>
+#include <platforms/chestnut.h>
+
+	.globl	mv64x60_board_init
+mv64x60_board_init:
+	/*
+	 * move UART to 0xffc00000
+	 */
+
+	li      r23,16
+
+	addis	r25,0,CONFIG_MV64X60_BASE@h
+	ori     r25,r25,MV64x60_CPU2DEV_2_BASE
+	addis   r26,0,CHESTNUT_UART_BASE@h
+	srw     r26,r26,r23
+	stwbrx  r26,0,(r25)
+	sync
+
+	addis	r25,0,CONFIG_MV64X60_BASE@h
+	ori     r25,r25,MV64x60_CPU2DEV_2_SIZE
+	addis   r26,0,0x00100000@h
+	srw     r26,r26,r23
+	stwbrx  r26,0,(r25)
+	sync
+
+	blr
diff -Nru a/arch/ppc/boot/simple/misc-cpci690.c b/arch/ppc/boot/simple/misc-cpci690.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/ppc/boot/simple/misc-cpci690.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,15 @@
+/*
+ * arch/ppc/boot/simple/misc-cpci690.c
+ *
+ * Add birec data for Force CPCI690 board.
+ *
+ * Author: Mark A. Greer <source@mvista.com>
+ *
+ * 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/types.h>
+long	mv64x60_mpsc_clk_freq = 133000000;
diff -Nru a/arch/ppc/boot/simple/misc-ev64260.S b/arch/ppc/boot/simple/misc-ev64260.S
--- a/arch/ppc/boot/simple/misc-ev64260.S	2005-03-01 23:39:18 -08:00
+++ b/arch/ppc/boot/simple/misc-ev64260.S	2005-03-01 23:39:18 -08:00
@@ -6,55 +6,63 @@
  *
  * Author: Mark Greer <mgreer@mvista.com>
  *
- * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
- * the terms of the GNU General Public License version 2.  This program
+ * 2001 (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 <asm/ppc_asm.h>
+#include <asm/processor.h>
 #include <asm/cache.h>
-#include <asm/gt64260_defs.h>
-
+#include <asm/mv64x60_defs.h>
 #include <platforms/ev64260.h>
 
-	.globl	ev64260_init
-ev64260_init:
-	li	r20,0
+	.globl	mv64x60_board_init
+mv64x60_board_init:
+	/* DINK doesn't enable 745x timebase, so enable here (Adrian Cox) */
+	mfspr	r25,PVR
+	srwi	r25,r25,16
+	cmplwi	r25,(PVR_7450 >> 16)
+	bne	1f
+	mfspr	r25,HID0
+	oris	r25,r25,(HID0_TBEN >> 16)
+	mtspr	HID0,r25
+1:
+#if (CONFIG_MV64X60_NEW_BASE != CONFIG_MV64X60_BASE)
 	li	r23,20
 
-	/* Relocate galileo's regs */
-        addis	r25,0,GT64260_INTERNAL_SPACE_DEFAULT_ADDR@h
-        ori	r25,r25,GT64260_INTERNAL_SPACE_DECODE
-        lwbrx	r26,0,(r25)
-	lis	r24,0xffff
-	and	r26,r26,r24
-	addis	r24,0,EV64260_BRIDGE_REG_BASE@h
-	srw	r24,r24,r23
-	or	r26,r26,r24
-        stwbrx  r26,0,(r25)
-	sync
-
-	/* Wait for write to take effect */
-        addis	r25,0,EV64260_BRIDGE_REG_BASE@h
-	ori	r25,r25,GT64260_INTERNAL_SPACE_DECODE
-1:	lwbrx	r24,0,(r25)
-	cmpw	r24,r26
-	bne	1b
-
-        /* Change CS2 (UARTS on device module) window */
-        addis	r25,0,EV64260_BRIDGE_REG_BASE@h
-        ori	r25,r25,GT64260_CPU_CS_DECODE_2_BOT
+	/*
+	 * Change the CS2 window for the UART so that the bootloader
+	 * can do I/O thru the UARTs.
+	 */
+	addis	r25,0,CONFIG_MV64X60_NEW_BASE@h
+	ori	r25,r25,MV64x60_CPU2DEV_2_BASE
 	addis	r26,0,EV64260_UART_BASE@h
 	srw	r26,r26,r23
-        stwbrx  r26,0,(r25)
+	stwbrx	r26,0,(r25)
 	sync
 
-        addis	r25,0,EV64260_BRIDGE_REG_BASE@h
-        ori	r25,r25,GT64260_CPU_CS_DECODE_2_TOP
+	addis	r25,0,CONFIG_MV64X60_NEW_BASE@h
+	ori	r25,r25,MV64x60_CPU2DEV_2_SIZE
 	addis	r26,0,EV64260_UART_END@h
 	srw	r26,r26,r23
-        stwbrx  r26,0,(r25)
+	stwbrx	r26,0,(r25)
 	sync
+#endif
+	blr
 
-        blr
+#if defined(CONFIG_SERIAL_MPSC_CONSOLE)
+.data
+	.globl	mv64x60_console_baud
+mv64x60_console_baud:
+.long	EV64260_DEFAULT_BAUD
+
+	.globl	mv64x60_mpsc_clk_src
+mv64x60_mpsc_clk_src:
+.long	EV64260_MPSC_CLK_SRC
+
+	.globl	mv64x60_mpsc_clk_freq
+mv64x60_mpsc_clk_freq:
+.long	EV64260_MPSC_CLK_FREQ
+#endif
diff -Nru a/arch/ppc/boot/simple/misc-katana.c b/arch/ppc/boot/simple/misc-katana.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/ppc/boot/simple/misc-katana.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,15 @@
+/*
+ * arch/ppc/boot/simple/misc-katana.c
+ *
+ * Add birec data for Artesyn KATANA board.
+ *
+ * Author: Mark A. Greer <source@mvista.com>
+ *
+ * 2004 (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/types.h>
+long	mv64x60_mpsc_clk_freq = 133333333;
diff -Nru a/arch/ppc/boot/simple/misc-mv64x60.S b/arch/ppc/boot/simple/misc-mv64x60.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/ppc/boot/simple/misc-mv64x60.S	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,57 @@
+/*
+ * arch/ppc/boot/simple/misc-mv64x60.S
+ *
+ * Code to change the base address of the host bridges and call board specific
+ * init routine.
+ *
+ * Author: Mark Greer <mgreer@mvista.com>
+ *
+ * 2002 (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 <asm/ppc_asm.h>
+#include <asm/processor.h>
+#include <asm/cache.h>
+#include <asm/mv64x60_defs.h>
+
+	.globl	mv64x60_init
+mv64x60_init:
+	mflr	r27
+
+#if (CONFIG_MV64X60_NEW_BASE != CONFIG_MV64X60_BASE)
+	bl	move_base
+#endif
+	bl	mv64x60_board_init
+
+	mtlr	r27
+	blr
+
+#if (CONFIG_MV64X60_NEW_BASE != CONFIG_MV64X60_BASE)
+move_base:
+	li	r20,0
+	li	r23,20
+
+	/* Relocate bridge's regs */
+	addis	r25,0,CONFIG_MV64X60_BASE@h
+	ori	r25,r25,MV64x60_INTERNAL_SPACE_DECODE
+	lwbrx	r26,0,(r25)
+	lis	r24,0xffff
+	and	r26,r26,r24
+	addis	r24,0,CONFIG_MV64X60_NEW_BASE@h
+	srw	r24,r24,r23
+	or	r26,r26,r24
+	stwbrx	r26,0,(r25)
+	sync
+
+	/* Wait for write to take effect */
+	addis	r25,0,CONFIG_MV64X60_NEW_BASE@h
+	ori	r25,r25,MV64x60_INTERNAL_SPACE_DECODE
+1:	lwbrx	r24,0,(r25)
+	cmpw	r24,r26
+	bne	1b
+
+	blr
+#endif
diff -Nru a/arch/ppc/boot/simple/misc.c b/arch/ppc/boot/simple/misc.c
--- a/arch/ppc/boot/simple/misc.c	2005-03-01 23:39:09 -08:00
+++ b/arch/ppc/boot/simple/misc.c	2005-03-01 23:39:09 -08:00
@@ -50,7 +50,8 @@
  */
 #if (defined(CONFIG_SERIAL_8250_CONSOLE) \
 	|| defined(CONFIG_VGA_CONSOLE) \
-	|| defined(CONFIG_SERIAL_MPC52xx_CONSOLE)) \
+	|| defined(CONFIG_SERIAL_MPC52xx_CONSOLE) \
+	|| defined(CONFIG_SERIAL_MPSC_CONSOLE)) \
 	&& !defined(CONFIG_GEMINI)
 #define INTERACTIVE_CONSOLE	1
 #endif
@@ -98,11 +99,11 @@
 	struct bi_record *rec;
 	unsigned long initrd_loc = 0, TotalMemory = 0;
 
-#ifdef CONFIG_SERIAL_8250_CONSOLE
+#if defined(CONFIG_SERIAL_8250_CONSOLE) || defined(CONFIG_SERIAL_MPSC_CONSOLE)
 	com_port = serial_init(0, NULL);
 #endif
 
-#ifdef CONFIG_44x
+#if defined(CONFIG_44x) && defined(PPC44x_EMAC0_MR0)
 	/* Reset MAL */
 	mtdcr(DCRN_MALCR(DCRN_MAL_BASE), MALCR_MMSR);
 	/* Wait for reset */
diff -Nru a/arch/ppc/boot/simple/mv64x60_stub.c b/arch/ppc/boot/simple/mv64x60_stub.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/ppc/boot/simple/mv64x60_stub.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,24 @@
+/*
+ * arch/ppc/boot/simple/mv64x60_stub.c
+ *
+ * Stub for board_init() routine called from mv64x60_init().
+ *
+ * Author: Mark A. Greer <mgreer@mvista.com>
+ *
+ * 2002 (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>
+
+#if defined(CONFIG_SERIAL_MPSC_CONSOLE)
+long __attribute__ ((weak))	mv64x60_console_baud = 9600;
+long __attribute__ ((weak))	mv64x60_mpsc_clk_src = 8; /* TCLK */
+long __attribute__ ((weak))	mv64x60_mpsc_clk_freq = 100000000;
+#endif
+
+void __attribute__ ((weak))
+mv64x60_board_init(void)
+{
+}
diff -Nru a/arch/ppc/boot/simple/mv64x60_tty.c b/arch/ppc/boot/simple/mv64x60_tty.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/ppc/boot/simple/mv64x60_tty.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,384 @@
+/*
+ * arch/ppc/boot/simple/mv64x60_tty.c
+ *
+ * Bootloader version of the embedded MPSC/UART driver for the Marvell 64x60.
+ * Note: Due to a GT64260A erratum, DMA will be used for UART input (via SDMA).
+ *
+ * Author: Mark A. Greer <mgreer@mvista.com>
+ *
+ * 2001 (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 code assumes that the data cache has been disabled (L1, L2, L3). */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/serial_reg.h>
+#include <asm/serial.h>
+#include <asm/mv64x60_defs.h>
+#include <mpsc_defs.h>
+
+extern void udelay(long);
+static void stop_dma(int chan);
+
+static u32	mv64x60_base = CONFIG_MV64X60_NEW_BASE;
+
+inline unsigned
+mv64x60_in_le32(volatile unsigned *addr)
+{
+	unsigned ret;
+
+	__asm__ __volatile__("lwbrx %0,0,%1; eieio" : "=r" (ret) :
+				"r" (addr), "m" (*addr));
+	return ret;
+}
+
+inline void
+mv64x60_out_le32(volatile unsigned *addr, int val)
+{
+	__asm__ __volatile__("stwbrx %1,0,%2; eieio" : "=m" (*addr) :
+				"r" (val), "r" (addr));
+}
+
+#define MV64x60_REG_READ(offs)						\
+	(mv64x60_in_le32((volatile uint *)(mv64x60_base + (offs))))
+#define MV64x60_REG_WRITE(offs, d)					\
+	(mv64x60_out_le32((volatile uint *)(mv64x60_base + (offs)), (int)(d)))
+
+
+struct sdma_regs {
+	u32	sdc;
+	u32	sdcm;
+	u32	rx_desc;
+	u32	rx_buf_ptr;
+	u32	scrdp;
+	u32	tx_desc;
+	u32	sctdp;
+	u32	sftdp;
+};
+
+static struct sdma_regs	sdma_regs[2];
+
+#define	SDMA_REGS_INIT(s, reg_base) {			\
+	(s)->sdc	= (reg_base) + SDMA_SDC;	\
+	(s)->sdcm	= (reg_base) + SDMA_SDCM;	\
+	(s)->rx_desc	= (reg_base) + SDMA_RX_DESC;	\
+	(s)->rx_buf_ptr = (reg_base) + SDMA_RX_BUF_PTR;	\
+	(s)->scrdp	= (reg_base) + SDMA_SCRDP;	\
+	(s)->tx_desc	= (reg_base) + SDMA_TX_DESC;	\
+	(s)->sctdp	= (reg_base) + SDMA_SCTDP;	\
+	(s)->sftdp	= (reg_base) + SDMA_SFTDP;	\
+}
+
+static u32	mpsc_base[2] = { MV64x60_MPSC_0_OFFSET, MV64x60_MPSC_1_OFFSET };
+
+struct mv64x60_rx_desc {
+	u16	bufsize;
+	u16	bytecnt;
+	u32	cmd_stat;
+	u32	next_desc_ptr;
+	u32	buffer;
+};
+
+struct mv64x60_tx_desc {
+	u16	bytecnt;
+	u16	shadow;
+	u32	cmd_stat;
+	u32	next_desc_ptr;
+	u32	buffer;
+};
+
+#define	MAX_RESET_WAIT	10000
+#define	MAX_TX_WAIT	10000
+
+#define	RX_NUM_DESC	2
+#define	TX_NUM_DESC	2
+
+#define	RX_BUF_SIZE	32
+#define	TX_BUF_SIZE	32
+
+static struct mv64x60_rx_desc rd[2][RX_NUM_DESC] __attribute__ ((aligned(32)));
+static struct mv64x60_tx_desc td[2][TX_NUM_DESC] __attribute__ ((aligned(32)));
+
+static char rx_buf[2][RX_NUM_DESC * RX_BUF_SIZE] __attribute__ ((aligned(32)));
+static char tx_buf[2][TX_NUM_DESC * TX_BUF_SIZE] __attribute__ ((aligned(32)));
+
+static int cur_rd[2] = { 0, 0 };
+static int cur_td[2] = { 0, 0 };
+
+static char chan_initialized[2] = { 0, 0 };
+
+
+#define	RX_INIT_RDP(rdp) {			\
+	(rdp)->bufsize = 2;			\
+	(rdp)->bytecnt = 0;			\
+	(rdp)->cmd_stat = SDMA_DESC_CMDSTAT_L | SDMA_DESC_CMDSTAT_F |	\
+		SDMA_DESC_CMDSTAT_O;	\
+}
+
+#ifdef CONFIG_MV64360
+static u32 cpu2mem_tab[MV64x60_CPU2MEM_WINDOWS][2] = {
+		{ MV64x60_CPU2MEM_0_BASE, MV64x60_CPU2MEM_0_SIZE },
+		{ MV64x60_CPU2MEM_1_BASE, MV64x60_CPU2MEM_1_SIZE },
+		{ MV64x60_CPU2MEM_2_BASE, MV64x60_CPU2MEM_2_SIZE },
+		{ MV64x60_CPU2MEM_3_BASE, MV64x60_CPU2MEM_3_SIZE }
+};
+
+static u32 com2mem_tab[MV64x60_CPU2MEM_WINDOWS][2] = {
+		{ MV64360_MPSC2MEM_0_BASE, MV64360_MPSC2MEM_0_SIZE },
+		{ MV64360_MPSC2MEM_1_BASE, MV64360_MPSC2MEM_1_SIZE },
+		{ MV64360_MPSC2MEM_2_BASE, MV64360_MPSC2MEM_2_SIZE },
+		{ MV64360_MPSC2MEM_3_BASE, MV64360_MPSC2MEM_3_SIZE }
+};
+
+static u32 dram_selects[MV64x60_CPU2MEM_WINDOWS] = { 0xe, 0xd, 0xb, 0x7 };
+#endif
+
+unsigned long
+serial_init(int chan, void *ignored)
+{
+	u32		mpsc_routing_base, sdma_base, brg_bcr, cdv;
+	int		i;
+	extern long	mv64x60_console_baud;
+	extern long	mv64x60_mpsc_clk_src;
+	extern long	mv64x60_mpsc_clk_freq;
+
+	chan = (chan == 1); /* default to chan 0 if anything but 1 */
+
+	if (chan_initialized[chan])
+		return chan;
+
+	chan_initialized[chan] = 1;
+
+	if (chan == 0) {
+		sdma_base = MV64x60_SDMA_0_OFFSET;
+		brg_bcr = MV64x60_BRG_0_OFFSET + BRG_BCR;
+		SDMA_REGS_INIT(&sdma_regs[0], MV64x60_SDMA_0_OFFSET);
+	}
+	else {
+		sdma_base = MV64x60_SDMA_1_OFFSET;
+		brg_bcr = MV64x60_BRG_1_OFFSET + BRG_BCR;
+		SDMA_REGS_INIT(&sdma_regs[0], MV64x60_SDMA_1_OFFSET);
+	}
+
+	mpsc_routing_base = MV64x60_MPSC_ROUTING_OFFSET;
+
+	stop_dma(chan);
+
+	/* Set up ring buffers */
+	for (i=0; i<RX_NUM_DESC; i++) {
+		RX_INIT_RDP(&rd[chan][i]);
+		rd[chan][i].buffer = (u32)&rx_buf[chan][i * RX_BUF_SIZE];
+		rd[chan][i].next_desc_ptr = (u32)&rd[chan][i+1];
+	}
+	rd[chan][RX_NUM_DESC - 1].next_desc_ptr = (u32)&rd[chan][0];
+
+	for (i=0; i<TX_NUM_DESC; i++) {
+		td[chan][i].bytecnt = 0;
+		td[chan][i].shadow = 0;
+		td[chan][i].buffer = (u32)&tx_buf[chan][i * TX_BUF_SIZE];
+		td[chan][i].cmd_stat = SDMA_DESC_CMDSTAT_F|SDMA_DESC_CMDSTAT_L;
+		td[chan][i].next_desc_ptr = (u32)&td[chan][i+1];
+	}
+	td[chan][TX_NUM_DESC - 1].next_desc_ptr = (u32)&td[chan][0];
+
+	/* Set MPSC Routing */
+	MV64x60_REG_WRITE(mpsc_routing_base + MPSC_MRR, 0x3ffffe38);
+
+#ifdef CONFIG_GT64260
+	MV64x60_REG_WRITE(GT64260_MPP_SERIAL_PORTS_MULTIPLEX, 0x00001102);
+#else /* Must be MV64360 or MV64460 */
+	{
+	u32	enables, prot_bits, v;
+
+	/* Set up comm unit to memory mapping windows */
+	/* Note: Assumes MV64x60_CPU2MEM_WINDOWS == 4 */
+
+	enables = MV64x60_REG_READ(MV64360_CPU_BAR_ENABLE) & 0xf;
+	prot_bits = 0;
+
+	for (i=0; i<MV64x60_CPU2MEM_WINDOWS; i++) {
+		if (!(enables & (1 << i))) {
+			v = MV64x60_REG_READ(cpu2mem_tab[i][0]);
+			v = ((v & 0xffff) << 16) | (dram_selects[i] << 8);
+			MV64x60_REG_WRITE(com2mem_tab[i][0], v);
+
+			v = MV64x60_REG_READ(cpu2mem_tab[i][1]);
+			v = (v & 0xffff) << 16;
+			MV64x60_REG_WRITE(com2mem_tab[i][1], v);
+
+			prot_bits |= (0x3 << (i << 1)); /* r/w access */
+		}
+	}
+
+	MV64x60_REG_WRITE(MV64360_MPSC_0_REMAP, 0);
+	MV64x60_REG_WRITE(MV64360_MPSC_1_REMAP, 0);
+	MV64x60_REG_WRITE(MV64360_MPSC2MEM_ACC_PROT_0, prot_bits);
+	MV64x60_REG_WRITE(MV64360_MPSC2MEM_ACC_PROT_1, prot_bits);
+	MV64x60_REG_WRITE(MV64360_MPSC2MEM_BAR_ENABLE, enables);
+	}
+#endif
+
+	/* MPSC 0/1 Rx & Tx get clocks BRG0/1 */
+	MV64x60_REG_WRITE(mpsc_routing_base + MPSC_RCRR, 0x00000100);
+	MV64x60_REG_WRITE(mpsc_routing_base + MPSC_TCRR, 0x00000100);
+
+	/* clear pending interrupts */
+	MV64x60_REG_WRITE(MV64x60_SDMA_INTR_OFFSET + SDMA_INTR_MASK, 0);
+
+	MV64x60_REG_WRITE(SDMA_SCRDP + sdma_base, &rd[chan][0]);
+	MV64x60_REG_WRITE(SDMA_SCTDP + sdma_base, &td[chan][TX_NUM_DESC - 1]);
+	MV64x60_REG_WRITE(SDMA_SFTDP + sdma_base, &td[chan][TX_NUM_DESC - 1]);
+
+	MV64x60_REG_WRITE(SDMA_SDC + sdma_base,
+		SDMA_SDC_RFT | SDMA_SDC_SFM | SDMA_SDC_BLMR | SDMA_SDC_BLMT |
+		(3 << 12));
+
+	cdv = ((mv64x60_mpsc_clk_freq/(32*mv64x60_console_baud))-1);
+	MV64x60_REG_WRITE(brg_bcr,
+		((mv64x60_mpsc_clk_src << 18) | (1 << 16) | cdv));
+
+	/* Put MPSC into UART mode, no null modem, 16x clock mode */
+	MV64x60_REG_WRITE(MPSC_MMCRL + mpsc_base[chan], 0x000004c4);
+	MV64x60_REG_WRITE(MPSC_MMCRH + mpsc_base[chan], 0x04400400);
+
+	MV64x60_REG_WRITE(MPSC_CHR_1 + mpsc_base[chan], 0);
+	MV64x60_REG_WRITE(MPSC_CHR_9 + mpsc_base[chan], 0);
+	MV64x60_REG_WRITE(MPSC_CHR_10 + mpsc_base[chan], 0);
+	MV64x60_REG_WRITE(MPSC_CHR_3 + mpsc_base[chan], 4);
+	MV64x60_REG_WRITE(MPSC_CHR_4 + mpsc_base[chan], 0);
+	MV64x60_REG_WRITE(MPSC_CHR_5 + mpsc_base[chan], 0);
+	MV64x60_REG_WRITE(MPSC_CHR_6 + mpsc_base[chan], 0);
+	MV64x60_REG_WRITE(MPSC_CHR_7 + mpsc_base[chan], 0);
+	MV64x60_REG_WRITE(MPSC_CHR_8 + mpsc_base[chan], 0);
+
+	/* 8 data bits, 1 stop bit */
+	MV64x60_REG_WRITE(MPSC_MPCR + mpsc_base[chan], (3 << 12));
+	MV64x60_REG_WRITE(SDMA_SDCM + sdma_base, SDMA_SDCM_ERD);
+	MV64x60_REG_WRITE(MPSC_CHR_2 + mpsc_base[chan], MPSC_CHR_2_EH);
+
+	udelay(100);
+
+	return chan;
+}
+
+static void
+stop_dma(int chan)
+{
+	int	i;
+
+	/* Abort MPSC Rx (aborting Tx messes things up) */
+	MV64x60_REG_WRITE(MPSC_CHR_2 + mpsc_base[chan], MPSC_CHR_2_RA);
+
+	/* Abort SDMA Rx, Tx */
+	MV64x60_REG_WRITE(sdma_regs[chan].sdcm, SDMA_SDCM_AR | SDMA_SDCM_STD);
+
+	for (i=0; i<MAX_RESET_WAIT; i++) {
+		if ((MV64x60_REG_READ(sdma_regs[chan].sdcm) &
+				(SDMA_SDCM_AR | SDMA_SDCM_AT)) == 0)
+			break;
+
+		udelay(100);
+	}
+
+	return;
+}
+
+static int
+wait_for_ownership(int chan)
+{
+	int	i;
+
+	for (i=0; i<MAX_TX_WAIT; i++) {
+		if ((MV64x60_REG_READ(sdma_regs[chan].sdcm) &
+				SDMA_SDCM_TXD) == 0)
+			break;
+
+		udelay(1000);
+	}
+
+	return (i < MAX_TX_WAIT);
+}
+
+void
+serial_putc(unsigned long com_port, unsigned char c)
+{
+	struct mv64x60_tx_desc	*tdp;
+
+	if (wait_for_ownership(com_port) == 0)
+		return;
+
+	tdp = &td[com_port][cur_td[com_port]];
+	if (++cur_td[com_port] >= TX_NUM_DESC)
+		cur_td[com_port] = 0;
+
+	*(unchar *)(tdp->buffer ^ 7) = c;
+	tdp->bytecnt = 1;
+	tdp->shadow = 1;
+	tdp->cmd_stat = SDMA_DESC_CMDSTAT_L | SDMA_DESC_CMDSTAT_F |
+		SDMA_DESC_CMDSTAT_O;
+
+	MV64x60_REG_WRITE(sdma_regs[com_port].sctdp, tdp);
+	MV64x60_REG_WRITE(sdma_regs[com_port].sftdp, tdp);
+	MV64x60_REG_WRITE(sdma_regs[com_port].sdcm,
+		MV64x60_REG_READ(sdma_regs[com_port].sdcm) | SDMA_SDCM_TXD);
+
+	return;
+}
+
+unsigned char
+serial_getc(unsigned long com_port)
+{
+	struct mv64x60_rx_desc	*rdp;
+	unchar			c = '\0';
+
+	rdp = &rd[com_port][cur_rd[com_port]];
+
+	if ((rdp->cmd_stat & (SDMA_DESC_CMDSTAT_O|SDMA_DESC_CMDSTAT_ES)) == 0) {
+		c = *(unchar *)(rdp->buffer ^ 7);
+		RX_INIT_RDP(rdp);
+		if (++cur_rd[com_port] >= RX_NUM_DESC)
+			cur_rd[com_port] = 0;
+	}
+
+	return c;
+}
+
+int
+serial_tstc(unsigned long com_port)
+{
+	struct mv64x60_rx_desc	*rdp;
+	int			loop_count = 0;
+	int			rc = 0;
+
+	rdp = &rd[com_port][cur_rd[com_port]];
+
+	/* Go thru rcv desc's until empty looking for one with data (no error)*/
+	while (((rdp->cmd_stat & SDMA_DESC_CMDSTAT_O) == 0) &&
+		(loop_count++ < RX_NUM_DESC)) {
+
+		/* If there was an error, reinit the desc & continue */
+		if ((rdp->cmd_stat & SDMA_DESC_CMDSTAT_ES) != 0) {
+			RX_INIT_RDP(rdp);
+			if (++cur_rd[com_port] >= RX_NUM_DESC)
+				cur_rd[com_port] = 0;
+			rdp = (struct mv64x60_rx_desc *)rdp->next_desc_ptr;
+		}
+		else {
+			rc = 1;
+			break;
+		}
+	}
+
+	return rc;
+}
+
+void
+serial_close(unsigned long com_port)
+{
+	stop_dma(com_port);
+	return;
+}
diff -Nru a/arch/ppc/boot/simple/pibs.c b/arch/ppc/boot/simple/pibs.c
--- a/arch/ppc/boot/simple/pibs.c	2005-03-01 23:38:56 -08:00
+++ b/arch/ppc/boot/simple/pibs.c	2005-03-01 23:38:56 -08:00
@@ -1,5 +1,5 @@
 /*
- * 2004 (c) MontaVista, Software, Inc.  This file is licensed under
+ * 2004-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.
@@ -10,7 +10,7 @@
 #include <linux/string.h>
 #include <linux/ctype.h>
 #include <asm/ppcboot.h>
-#include <platforms/4xx/ocotea.h>
+#include <asm/ibm4xx.h>
 
 extern unsigned long decompress_kernel(unsigned long load_addr, int num_words,
 				       unsigned long cksum);
@@ -89,13 +89,15 @@
 
 	decompress_kernel(load_addr, num_words, cksum);
 
-	mac64 = simple_strtoull((char *)OCOTEA_PIBS_MAC_BASE, 0, 16);
+	mac64 = simple_strtoull((char *)PIBS_MAC_BASE, 0, 16);
 	memcpy(hold_residual->bi_enetaddr, (char *)&mac64+2, 6);
-	mac64 = simple_strtoull((char *)(OCOTEA_PIBS_MAC_BASE+OCOTEA_PIBS_MAC_OFFSET), 0, 16);
+#ifdef CONFIG_440GX
+	mac64 = simple_strtoull((char *)(PIBS_MAC_BASE+PIBS_MAC_OFFSET), 0, 16);
 	memcpy(hold_residual->bi_enet1addr, (char *)&mac64+2, 6);
-	mac64 = simple_strtoull((char *)(OCOTEA_PIBS_MAC_BASE+OCOTEA_PIBS_MAC_OFFSET*2), 0, 16);
+	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 *)(OCOTEA_PIBS_MAC_BASE+OCOTEA_PIBS_MAC_OFFSET*3), 0, 16);
+	mac64 = simple_strtoull((char *)(PIBS_MAC_BASE+PIBS_MAC_OFFSET*3), 0, 16);
 	memcpy(hold_residual->bi_enet3addr, (char *)&mac64+2, 6);
+#endif
 	return (void *)hold_residual;
 }
diff -Nru a/arch/ppc/configs/adir_defconfig b/arch/ppc/configs/adir_defconfig
--- a/arch/ppc/configs/adir_defconfig	2005-03-01 23:39:08 -08:00
+++ b/arch/ppc/configs/adir_defconfig	2005-03-01 23:39:08 -08:00
@@ -302,7 +302,6 @@
 CONFIG_IP_NF_NAT_NEEDED=y
 CONFIG_IP_NF_TARGET_MASQUERADE=m
 CONFIG_IP_NF_TARGET_REDIRECT=m
-# CONFIG_IP_NF_NAT_LOCAL is not set
 CONFIG_IP_NF_NAT_SNMP_BASIC=m
 CONFIG_IP_NF_NAT_IRC=m
 CONFIG_IP_NF_NAT_FTP=m
diff -Nru a/arch/ppc/configs/apus_defconfig b/arch/ppc/configs/apus_defconfig
--- a/arch/ppc/configs/apus_defconfig	2005-03-01 23:39:09 -08:00
+++ b/arch/ppc/configs/apus_defconfig	2005-03-01 23:39:09 -08:00
@@ -354,7 +354,6 @@
 CONFIG_IP_NF_NAT_NEEDED=y
 CONFIG_IP_NF_TARGET_MASQUERADE=m
 CONFIG_IP_NF_TARGET_REDIRECT=m
-# CONFIG_IP_NF_NAT_LOCAL is not set
 CONFIG_IP_NF_NAT_SNMP_BASIC=m
 CONFIG_IP_NF_NAT_IRC=m
 CONFIG_IP_NF_NAT_FTP=m
diff -Nru a/arch/ppc/configs/chestnut_defconfig b/arch/ppc/configs/chestnut_defconfig
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/ppc/configs/chestnut_defconfig	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,739 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.10-rc2
+# Tue Dec  7 16:02:09 2004
+#
+CONFIG_MMU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_HAVE_DEC_LOCK=y
+CONFIG_PPC=y
+CONFIG_PPC32=y
+CONFIG_GENERIC_NVRAM=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=y
+# CONFIG_IKCONFIG is not set
+# CONFIG_EMBEDDED is not set
+CONFIG_KALLSYMS=y
+# 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=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=y
+# 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 is not set
+CONFIG_ALTIVEC=y
+# CONFIG_TAU is not set
+# CONFIG_CPU_FREQ is not set
+CONFIG_PPC_GEN550=y
+CONFIG_PPC_STD_MMU=y
+CONFIG_NOT_COHERENT_CACHE=y
+
+#
+# Platform options
+#
+# CONFIG_PPC_MULTIPLATFORM is not set
+# CONFIG_APUS is not set
+# CONFIG_WILLOW is not set
+# CONFIG_PCORE is not set
+# CONFIG_POWERPMC250 is not set
+CONFIG_CHESTNUT=y
+# CONFIG_SPRUCE 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_ADIR is not set
+# CONFIG_K2 is not set
+# CONFIG_PAL4 is not set
+# CONFIG_GEMINI is not set
+# CONFIG_EST8260 is not set
+# CONFIG_SBC82xx is not set
+# CONFIG_SBS8260 is not set
+# CONFIG_RPX8260 is not set
+# CONFIG_TQM8260 is not set
+# CONFIG_ADS8272 is not set
+# CONFIG_LITE5200 is not set
+CONFIG_MV64360=y
+CONFIG_MV64X60=y
+
+#
+# Set bridge options
+#
+CONFIG_MV64X60_BASE=0xf1000000
+CONFIG_MV64X60_NEW_BASE=0xf1000000
+# CONFIG_SMP is not set
+# CONFIG_PREEMPT is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_MISC=y
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttyS0,115200 ip=on"
+
+#
+# Bus options
+#
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_LEGACY_PROC=y
+CONFIG_PCI_NAMES=y
+
+#
+# Advanced setup
+#
+CONFIG_ADVANCED_OPTIONS=y
+CONFIG_HIGHMEM_START=0xfe000000
+# CONFIG_LOWMEM_SIZE_BOOL is not set
+CONFIG_LOWMEM_SIZE=0x30000000
+# CONFIG_KERNEL_START_BOOL is not set
+CONFIG_KERNEL_START=0xc0000000
+# CONFIG_TASK_SIZE_BOOL is not set
+CONFIG_TASK_SIZE=0x80000000
+# CONFIG_CONSISTENT_START_BOOL is not set
+CONFIG_CONSISTENT_START=0xff100000
+# CONFIG_CONSISTENT_SIZE_BOOL is not set
+CONFIG_CONSISTENT_SIZE=0x00200000
+# CONFIG_BOOT_LOAD_BOOL is not set
+CONFIG_BOOT_LOAD=0x00800000
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_CONCAT is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+
+#
+# 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=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=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# 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
+# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_CHESTNUT=y
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# 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
+
+#
+# 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_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_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=4096
+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
+
+#
+# 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
+
+#
+# Macintosh device drivers
+#
+
+#
+# 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=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=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
+
+#
+# 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=y
+# CONFIG_DE2104X is not set
+CONFIG_TULIP=y
+# CONFIG_TULIP_MWI is not set
+CONFIG_TULIP_MMIO=y
+# CONFIG_TULIP_NAPI is not set
+# CONFIG_DE4X5 is not set
+# CONFIG_WINBOND_840 is not set
+# CONFIG_DM9102 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=y
+# CONFIG_E100_NAPI is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# 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 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_VIA_VELOCITY 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 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=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
+#
+# 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=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=2
+# 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
+# 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
+
+#
+# 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
+
+#
+# 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
+
+#
+# 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_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=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_JFFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+# CONFIG_JFFS2_FS_NAND 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_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
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_SERIAL_TEXT_DEBUG is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
diff -Nru a/arch/ppc/configs/common_defconfig b/arch/ppc/configs/common_defconfig
--- a/arch/ppc/configs/common_defconfig	2005-03-01 23:38:54 -08:00
+++ b/arch/ppc/configs/common_defconfig	2005-03-01 23:38:54 -08:00
@@ -1,7 +1,10 @@
 #
 # Automatically generated make config: don't edit
+# Linux kernel version: 2.6.10-rc2
+# Thu Nov 18 08:22:35 2004
 #
 CONFIG_MMU=y
+CONFIG_GENERIC_HARDIRQS=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 CONFIG_HAVE_DEC_LOCK=y
 CONFIG_PPC=y
@@ -13,12 +16,12 @@
 #
 CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
-# CONFIG_STANDALONE is not set
 CONFIG_BROKEN_ON_SMP=y
 
 #
 # General setup
 #
+CONFIG_LOCALVERSION=""
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
@@ -27,17 +30,21 @@
 # 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_EXTRA_PASS 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
@@ -46,7 +53,8 @@
 CONFIG_MODULE_UNLOAD=y
 CONFIG_MODULE_FORCE_UNLOAD=y
 CONFIG_OBSOLETE_MODPARM=y
-# CONFIG_MODVERSIONS is not set
+CONFIG_MODVERSIONS=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_KMOD=y
 
 #
@@ -58,11 +66,22 @@
 # CONFIG_POWER3 is not set
 # CONFIG_POWER4 is not set
 # CONFIG_8xx is not set
+# CONFIG_E500 is not set
 CONFIG_ALTIVEC=y
 CONFIG_TAU=y
 # CONFIG_TAU_INT is not set
 # CONFIG_TAU_AVERAGE is not set
-# CONFIG_CPU_FREQ is not set
+CONFIG_CPU_FREQ=y
+# CONFIG_CPU_FREQ_DEBUG is not set
+CONFIG_CPU_FREQ_PROC_INTF=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_PMAC=y
+CONFIG_CPU_FREQ_TABLE=y
 CONFIG_PPC601_SYNC_FIX=y
 CONFIG_PM=y
 CONFIG_PPC_STD_MMU=y
@@ -89,9 +108,12 @@
 # CONFIG_PAL4 is not set
 # CONFIG_GEMINI is not set
 # CONFIG_EST8260 is not set
+# CONFIG_SBC82xx is not set
 # CONFIG_SBS8260 is not set
-# CONFIG_RPX6 is not set
+# CONFIG_RPX8260 is not set
 # CONFIG_TQM8260 is not set
+# CONFIG_ADS8272 is not set
+# CONFIG_LITE5200 is not set
 CONFIG_PPC_CHRP=y
 CONFIG_PPC_PMAC=y
 CONFIG_PPC_PREP=y
@@ -100,11 +122,9 @@
 # CONFIG_SMP is not set
 # CONFIG_PREEMPT is not set
 # CONFIG_HIGHMEM is not set
-CONFIG_KERNEL_ELF=y
 CONFIG_BINFMT_ELF=y
 CONFIG_BINFMT_MISC=m
 CONFIG_PROC_DEVICETREE=y
-CONFIG_PPC_RTAS=y
 CONFIG_PREP_RESIDUAL=y
 CONFIG_PROC_PREPRESIDUAL=y
 CONFIG_CMDLINE_BOOL=y
@@ -121,9 +141,13 @@
 CONFIG_PCI_NAMES=y
 
 #
-# PCMCIA/CardBus support
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
 #
-# CONFIG_PCMCIA is not set
 CONFIG_PCMCIA_PROBE=y
 
 #
@@ -147,6 +171,8 @@
 #
 # Generic Driver Options
 #
+# CONFIG_STANDALONE is not set
+CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_FW_LOADER is not set
 
 #
@@ -168,6 +194,7 @@
 # Block devices
 #
 CONFIG_BLK_DEV_FD=m
+# CONFIG_MAC_FLOPPY is not set
 # CONFIG_BLK_DEV_XD is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
@@ -176,11 +203,22 @@
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_CARMEL 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_SIZE=4096
 CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
 CONFIG_LBD=y
+# CONFIG_CDROM_PKTCDVD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -191,15 +229,14 @@
 #
 # 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_IDEDISK_STROKE is not set
 CONFIG_BLK_DEV_IDECD=y
 # CONFIG_BLK_DEV_IDETAPE is not set
 CONFIG_BLK_DEV_IDEFLOPPY=y
 CONFIG_BLK_DEV_IDESCSI=y
 # CONFIG_IDE_TASK_IOCTL is not set
-# CONFIG_IDE_TASKFILE_IO is not set
 
 #
 # IDE chipset support/bugfixes
@@ -215,7 +252,6 @@
 # CONFIG_BLK_DEV_IDEDMA_FORCED is not set
 CONFIG_IDEDMA_PCI_AUTO=y
 # CONFIG_IDEDMA_ONLYDISK is not set
-CONFIG_BLK_DEV_ADMA=y
 # CONFIG_BLK_DEV_AEC62XX is not set
 # CONFIG_BLK_DEV_ALI15X3 is not set
 # CONFIG_BLK_DEV_AMD74XX is not set
@@ -241,7 +277,7 @@
 CONFIG_BLK_DEV_IDE_PMAC_ATA100FIRST=y
 CONFIG_BLK_DEV_IDEDMA_PMAC=y
 CONFIG_BLK_DEV_IDE_PMAC_BLINK=y
-CONFIG_BLK_DEV_IDEDMA_PMAC_AUTO=y
+# CONFIG_IDE_ARM is not set
 # CONFIG_IDE_CHIPSETS is not set
 CONFIG_BLK_DEV_IDEDMA=y
 # CONFIG_IDEDMA_IVB is not set
@@ -268,7 +304,6 @@
 # Some SCSI devices (e.g. CD jukebox) support multiple LUNs
 #
 # CONFIG_SCSI_MULTI_LUN is not set
-# CONFIG_SCSI_REPORT_LUNS is not set
 CONFIG_SCSI_CONSTANTS=y
 # CONFIG_SCSI_LOGGING is not set
 
@@ -282,6 +317,7 @@
 # SCSI low-level drivers
 #
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
 # CONFIG_SCSI_7000FASST is not set
 # CONFIG_SCSI_ACARD is not set
 # CONFIG_SCSI_AHA152X is not set
@@ -290,18 +326,17 @@
 CONFIG_SCSI_AIC7XXX=m
 CONFIG_AIC7XXX_CMDS_PER_DEVICE=253
 CONFIG_AIC7XXX_RESET_DELAY_MS=15000
-# CONFIG_AIC7XXX_BUILD_FIRMWARE is not set
 CONFIG_AIC7XXX_DEBUG_ENABLE=y
 CONFIG_AIC7XXX_DEBUG_MASK=0
 CONFIG_AIC7XXX_REG_PRETTY_PRINT=y
 CONFIG_SCSI_AIC7XXX_OLD=m
 # CONFIG_SCSI_AIC79XX is not set
-CONFIG_SCSI_ADVANSYS=m
+# CONFIG_SCSI_DPT_I2O is not set
 # CONFIG_SCSI_IN2000 is not set
-# CONFIG_SCSI_MEGARAID 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
@@ -311,6 +346,7 @@
 # CONFIG_SCSI_GENERIC_NCR5380 is not set
 # CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
 # CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
 # CONFIG_SCSI_NCR53C406A is not set
 CONFIG_SCSI_SYM53C8XX_2=y
@@ -325,6 +361,7 @@
 # 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
@@ -378,8 +415,6 @@
 CONFIG_PMAC_PBOOK=y
 CONFIG_PMAC_APM_EMU=y
 CONFIG_PMAC_BACKLIGHT=y
-# CONFIG_MAC_FLOPPY is not set
-CONFIG_MAC_SERIAL=m
 CONFIG_ADB_MACIO=y
 CONFIG_INPUT_ADBHID=y
 CONFIG_MAC_EMUMOUSEBTN=y
@@ -412,6 +447,9 @@
 # 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
@@ -425,6 +463,9 @@
 # IP: Netfilter Configuration
 #
 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
@@ -449,29 +490,33 @@
 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_LOCAL is not set
 CONFIG_IP_NF_NAT_SNMP_BASIC=m
 CONFIG_IP_NF_NAT_IRC=m
 CONFIG_IP_NF_NAT_FTP=m
 CONFIG_IP_NF_NAT_TFTP=m
 CONFIG_IP_NF_NAT_AMANDA=m
 # CONFIG_IP_NF_MANGLE is not set
-# CONFIG_IP_NF_TARGET_LOG is not set
-CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_IP_NF_TARGET_TCPMSS=m
+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
-CONFIG_IP_NF_TARGET_NOTRACK=m
-CONFIG_IP_NF_RAW=m
 
 #
 # SCTP Configuration (EXPERIMENTAL)
@@ -489,12 +534,12 @@
 # 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
@@ -524,7 +569,6 @@
 CONFIG_MACE=y
 # CONFIG_MACE_AAUI_PORT is not set
 CONFIG_BMAC=y
-# CONFIG_OAKNET is not set
 # CONFIG_HAPPYMEAL is not set
 CONFIG_SUNGEM=y
 # CONFIG_NET_VENDOR_3COM is not set
@@ -583,6 +627,7 @@
 # CONFIG_YELLOWFIN is not set
 # CONFIG_R8169 is not set
 # CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 
 #
@@ -641,7 +686,6 @@
 # CONFIG_PPPOE is not set
 # CONFIG_SLIP is not set
 # CONFIG_NET_FC is not set
-# CONFIG_RCPCI is not set
 # CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
 
@@ -682,6 +726,7 @@
 # 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
@@ -702,6 +747,7 @@
 # CONFIG_INPUT_JOYSTICK is not set
 # CONFIG_INPUT_TOUCHSCREEN is not set
 CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_PCSPKR is not set
 CONFIG_INPUT_UINPUT=m
 
 #
@@ -728,7 +774,6 @@
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
-# CONFIG_QIC02_TAPE is not set
 
 #
 # IPMI
@@ -749,7 +794,6 @@
 #
 # 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
@@ -765,6 +809,7 @@
 #
 CONFIG_I2C_ALGOBIT=y
 # CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
 
 #
 # I2C Hardware Bus support
@@ -789,26 +834,36 @@
 # 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
 
 #
 # 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
@@ -820,12 +875,18 @@
 # 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_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
 #
 
@@ -843,6 +904,9 @@
 # Graphics support
 #
 CONFIG_FB=y
+CONFIG_FB_MODE_HELPERS=y
+# CONFIG_FB_TILEBLITTING is not set
+# CONFIG_FB_CIRRUS is not set
 # CONFIG_FB_PM2 is not set
 # CONFIG_FB_CYBER2000 is not set
 CONFIG_FB_OF=y
@@ -850,8 +914,8 @@
 CONFIG_FB_PLATINUM=y
 CONFIG_FB_VALKYRIE=y
 CONFIG_FB_CT65550=y
+# CONFIG_FB_ASILIANT is not set
 CONFIG_FB_IMSTT=y
-# CONFIG_FB_S3TRIO is not set
 # CONFIG_FB_VGA16 is not set
 # CONFIG_FB_RIVA is not set
 CONFIG_FB_MATROX=y
@@ -868,12 +932,15 @@
 CONFIG_FB_ATY128=y
 CONFIG_FB_ATY=y
 CONFIG_FB_ATY_CT=y
-CONFIG_FB_ATY_GX=y
+# CONFIG_FB_ATY_GENERIC_LCD is not set
 # CONFIG_FB_ATY_XL_INIT is not set
+CONFIG_FB_ATY_GX=y
+# CONFIG_FB_SAVAGE is not set
 # CONFIG_FB_SIS is not set
 # CONFIG_FB_NEOMAGIC is not set
 # CONFIG_FB_KYRO is not set
 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_VIRTUAL is not set
@@ -885,7 +952,6 @@
 # CONFIG_MDA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_PCI_CONSOLE=y
 # CONFIG_FONTS is not set
 CONFIG_FONT_8x8=y
 CONFIG_FONT_8x16=y
@@ -964,6 +1030,7 @@
 #
 # CONFIG_SND_ALI5451 is not set
 # CONFIG_SND_ATIIXP is not set
+# CONFIG_SND_ATIIXP_MODEM is not set
 # CONFIG_SND_AU8810 is not set
 # CONFIG_SND_AU8820 is not set
 # CONFIG_SND_AU8830 is not set
@@ -1003,9 +1070,10 @@
 CONFIG_SND_POWERMAC=m
 
 #
-# ALSA USB devices
+# USB devices
 #
 CONFIG_SND_USB_AUDIO=m
+# CONFIG_SND_USB_USX2Y is not set
 
 #
 # Open Sound System
@@ -1024,6 +1092,10 @@
 CONFIG_USB_DEVICEFS=y
 # 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
@@ -1042,6 +1114,7 @@
 CONFIG_USB_PRINTER=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=y
 # CONFIG_USB_STORAGE_ISD200 is not set
@@ -1052,7 +1125,7 @@
 # CONFIG_USB_STORAGE_JUMPSHOT is not set
 
 #
-# USB Human Interface Devices (HID)
+# USB Input Devices
 #
 CONFIG_USB_HID=y
 CONFIG_USB_HIDINPUT=y
@@ -1063,6 +1136,7 @@
 # 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
 
@@ -1083,7 +1157,7 @@
 #
 
 #
-# USB Network adaptors
+# USB Network Adapters
 #
 # CONFIG_USB_CATC is not set
 # CONFIG_USB_KAWETH is not set
@@ -1103,6 +1177,7 @@
 # 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_CYPRESS_M8 is not set
 # CONFIG_USB_SERIAL_EMPEG is not set
 # CONFIG_USB_SERIAL_FTDI_SIO is not set
 CONFIG_USB_SERIAL_VISOR=m
@@ -1110,6 +1185,7 @@
 # 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_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
@@ -1146,9 +1222,15 @@
 # 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_TEST is not set
 
 #
+# USB ATM/DSL drivers
+#
+
+#
 # USB Gadget Support
 #
 # CONFIG_USB_GADGET is not set
@@ -1166,6 +1248,7 @@
 # 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
 
@@ -1183,6 +1266,8 @@
 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
 
 #
@@ -1196,6 +1281,7 @@
 # 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
 
@@ -1226,12 +1312,13 @@
 CONFIG_NFSD=y
 CONFIG_NFSD_V3=y
 # CONFIG_NFSD_V4 is not set
-# CONFIG_NFSD_TCP is not set
+CONFIG_NFSD_TCP=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_EXPORTFS=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
@@ -1253,7 +1340,6 @@
 # CONFIG_SOLARIS_X86_PARTITION is not set
 # CONFIG_UNIXWARE_DISKLABEL is not set
 # CONFIG_LDM_PARTITION is not set
-# CONFIG_NEC98_PARTITION is not set
 # CONFIG_SGI_PARTITION is not set
 # CONFIG_ULTRIX_PARTITION is not set
 # CONFIG_SUN_PARTITION is not set
@@ -1287,6 +1373,7 @@
 # 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 is not set
 # CONFIG_NLS_ISO8859_3 is not set
@@ -1305,12 +1392,18 @@
 #
 # Library routines
 #
+CONFIG_CRC_CCITT=y
 CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
 
 #
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
 # Kernel hacking
 #
 # CONFIG_DEBUG_KERNEL is not set
@@ -1319,6 +1412,7 @@
 #
 # Security options
 #
+# CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 
 #
diff -Nru a/arch/ppc/configs/cpci690_defconfig b/arch/ppc/configs/cpci690_defconfig
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/ppc/configs/cpci690_defconfig	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,686 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.10-rc2
+# Fri Dec  3 15:56:10 2004
+#
+CONFIG_MMU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_HAVE_DEC_LOCK=y
+CONFIG_PPC=y
+CONFIG_PPC32=y
+CONFIG_GENERIC_NVRAM=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+
+#
+# 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_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_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=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=y
+# 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 is not set
+CONFIG_ALTIVEC=y
+# CONFIG_TAU is not set
+# CONFIG_CPU_FREQ is not set
+CONFIG_PPC_STD_MMU=y
+# CONFIG_NOT_COHERENT_CACHE is not set
+
+#
+# Platform options
+#
+# CONFIG_PPC_MULTIPLATFORM is not set
+# CONFIG_APUS is not set
+# CONFIG_KATANA is not set
+# CONFIG_DMV182 is not set
+# CONFIG_WILLOW is not set
+CONFIG_CPCI690=y
+# CONFIG_PCORE is not set
+# CONFIG_POWERPMC250 is not set
+# CONFIG_EV64260 is not set
+# CONFIG_DB64360 is not set
+# CONFIG_CHESTNUT is not set
+# CONFIG_SPRUCE 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_PRPMC880 is not set
+# CONFIG_SANDPOINT is not set
+# 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
+# CONFIG_SBC82xx is not set
+# CONFIG_SBS8260 is not set
+# CONFIG_RPX8260 is not set
+# CONFIG_TQM8260 is not set
+# CONFIG_ADS8272 is not set
+# CONFIG_LITE5200 is not set
+
+#
+# Set bridge options
+#
+CONFIG_MV64X60_BASE=0xf1000000
+CONFIG_MV64X60_NEW_BASE=0xf1000000
+CONFIG_GT64260=y
+CONFIG_MV64X60=y
+# CONFIG_SMP is not set
+# CONFIG_PREEMPT is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_MISC=y
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttyMM0,9600 ip=on"
+
+#
+# Bus options
+#
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_LEGACY_PROC=y
+CONFIG_PCI_NAMES=y
+
+#
+# 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
+
+#
+# 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_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_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+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
+
+#
+# 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
+
+#
+# Macintosh device drivers
+#
+
+#
+# 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=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=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
+
+#
+# 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=y
+# CONFIG_DE2104X is not set
+CONFIG_TULIP=y
+# CONFIG_TULIP_MWI is not set
+# CONFIG_TULIP_MMIO is not set
+# CONFIG_TULIP_NAPI is not set
+# CONFIG_DE4X5 is not set
+# CONFIG_WINBOND_840 is not set
+# CONFIG_DM9102 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=y
+# CONFIG_EEPRO100_PIO is not set
+# CONFIG_E100 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# 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 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_VIA_VELOCITY 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 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=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
+#
+# 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_SERIAL_MPSC=y
+CONFIG_SERIAL_MPSC_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_GEN_RTC=y
+# CONFIG_GEN_RTC_X 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
+
+#
+# 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
+
+#
+# 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
+
+#
+# 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_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=y
+# CONFIG_DEVFS_MOUNT is not set
+# 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=y
+# 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_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
+
+#
+# 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_DEBUG_KERNEL is not set
+# CONFIG_SERIAL_TEXT_DEBUG is not set
+
+#
+# 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_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
diff -Nru a/arch/ppc/configs/ev64260_defconfig b/arch/ppc/configs/ev64260_defconfig
--- a/arch/ppc/configs/ev64260_defconfig	2005-03-01 23:39:10 -08:00
+++ b/arch/ppc/configs/ev64260_defconfig	2005-03-01 23:39:10 -08:00
@@ -1,26 +1,49 @@
 #
 # Automatically generated make config: don't edit
+# Linux kernel version: 2.6.10-rc2
+# Fri Nov 19 11:17:02 2004
 #
 CONFIG_MMU=y
+CONFIG_GENERIC_HARDIRQS=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 CONFIG_HAVE_DEC_LOCK=y
+CONFIG_PPC=y
+CONFIG_PPC32=y
+CONFIG_GENERIC_NVRAM=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=y
+# CONFIG_IKCONFIG is not set
 # CONFIG_EMBEDDED is not set
+CONFIG_KALLSYMS=y
+# 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
@@ -30,31 +53,38 @@
 # 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
 
 #
-# Platform support
+# Processor
 #
-CONFIG_PPC=y
-CONFIG_PPC32=y
 CONFIG_6xx=y
 # 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 is not set
+CONFIG_ALTIVEC=y
+CONFIG_TAU=y
+# CONFIG_TAU_INT is not set
+# CONFIG_TAU_AVERAGE is not set
+# CONFIG_CPU_FREQ is not set
+CONFIG_PPC_GEN550=y
+CONFIG_PPC_STD_MMU=y
+# CONFIG_NOT_COHERENT_CACHE is not set
 
 #
-# IBM 4xx options
+# Platform options
 #
-# CONFIG_8260 is not set
-CONFIG_GENERIC_ISA_DMA=y
-CONFIG_PPC_STD_MMU=y
 # CONFIG_PPC_MULTIPLATFORM is not set
 # CONFIG_APUS is not set
-# CONFIG_WILLOW_2 is not set
+# CONFIG_WILLOW is not set
 # CONFIG_PCORE is not set
 # CONFIG_POWERPMC250 is not set
-CONFIG_EV64260=y
 # CONFIG_SPRUCE is not set
+CONFIG_EV64260=y
 # CONFIG_LOPEC is not set
 # CONFIG_MCPN765 is not set
 # CONFIG_MVME5100 is not set
@@ -66,37 +96,37 @@
 # CONFIG_K2 is not set
 # CONFIG_PAL4 is not set
 # CONFIG_GEMINI is not set
+# CONFIG_EST8260 is not set
+# CONFIG_SBC82xx is not set
+# CONFIG_SBS8260 is not set
+# CONFIG_RPX8260 is not set
+# CONFIG_TQM8260 is not set
+# CONFIG_ADS8272 is not set
+# CONFIG_LITE5200 is not set
 CONFIG_GT64260=y
-CONFIG_SERIAL_CONSOLE_BAUD=115200
-# CONFIG_SMP is not set
-# CONFIG_PREEMPT is not set
-CONFIG_ALTIVEC=y
-CONFIG_TAU=y
-# CONFIG_TAU_INT is not set
-# CONFIG_TAU_AVERAGE is not set
-# CONFIG_CPU_FREQ is not set
+CONFIG_MV64X60=y
 
 #
-# General setup
+# Set bridge options
 #
+CONFIG_MV64X60_BASE=0xf1000000
+CONFIG_MV64X60_NEW_BASE=0xfbe00000
+# CONFIG_SMP is not set
+# CONFIG_PREEMPT is not set
 # CONFIG_HIGHMEM is not set
-CONFIG_PCI=y
-CONFIG_PCI_DOMAINS=y
-CONFIG_KCORE_ELF=y
 CONFIG_BINFMT_ELF=y
-CONFIG_KERNEL_ELF=y
 CONFIG_BINFMT_MISC=y
-CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
-# CONFIG_HOTPLUG is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttyS0,115200 ip=on"
 
 #
-# Parallel port support
+# Bus options
 #
-# CONFIG_PARPORT is not set
-# CONFIG_PPC601_SYNC_FIX is not set
-CONFIG_CMDLINE_BOOL=y
-CONFIG_CMDLINE="console=ttyS0,115200 ip=on"
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_LEGACY_PROC=y
+CONFIG_PCI_NAMES=y
 
 #
 # Advanced setup
@@ -113,14 +143,28 @@
 CONFIG_BOOT_LOAD=0x00800000
 
 #
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+
+#
 # 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
@@ -131,32 +175,45 @@
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM 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_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=4096
 CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_LBD is not set
+# CONFIG_CDROM_PKTCDVD is not set
 
 #
-# Multi-device support (RAID and LVM)
+# IO Schedulers
 #
-# CONFIG_MD is not set
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
 
 #
-# ATA/IDE/MFM/RLL support
+# ATA/ATAPI/MFM/RLL support
 #
 # CONFIG_IDE is not set
 
 #
-# SCSI support
+# 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 (EXPERIMENTAL)
+# IEEE 1394 (FireWire) support
 #
 # CONFIG_IEEE1394 is not set
 
@@ -166,6 +223,10 @@
 # CONFIG_I2O is not set
 
 #
+# Macintosh device drivers
+#
+
+#
 # Networking support
 #
 CONFIG_NET=y
@@ -176,8 +237,6 @@
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 # CONFIG_NETLINK_DEV is not set
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
@@ -191,68 +250,81 @@
 # CONFIG_NET_IPGRE is not set
 # CONFIG_IP_MROUTE is not set
 # CONFIG_ARPD is not set
-# CONFIG_INET_ECN is not set
 CONFIG_SYN_COOKIES=y
 # CONFIG_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
 # CONFIG_IP_NF_COMPAT_IPCHAINS is not set
 # CONFIG_IP_NF_COMPAT_IPFWADM is not set
-# CONFIG_IPV6 is not set
-# CONFIG_XFRM_USER is not set
 
 #
 # SCTP Configuration (EXPERIMENTAL)
 #
-CONFIG_IPV6_SCTP__=y
 # CONFIG_IP_SCTP is not set
 # CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
 # CONFIG_VLAN_8021Q is not set
-# CONFIG_LLC is not set
 # CONFIG_DECNET is not set
-# CONFIG_BRIDGE 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_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
 #
 # 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
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
 
 #
 # Ethernet (10 or 100Mbit)
 #
 CONFIG_NET_ETHERNET=y
-# CONFIG_MII is not set
-# CONFIG_OAKNET is not set
+CONFIG_MII=y
 # CONFIG_HAPPYMEAL is not set
 # CONFIG_SUNGEM is not set
 # CONFIG_NET_VENDOR_3COM is not set
@@ -260,17 +332,26 @@
 #
 # Tulip family network device support
 #
-# CONFIG_NET_TULIP is not set
+CONFIG_NET_TULIP=y
+# CONFIG_DE2104X is not set
+CONFIG_TULIP=y
+# CONFIG_TULIP_MWI is not set
+# CONFIG_TULIP_MMIO is not set
+# CONFIG_TULIP_NAPI is not set
+# CONFIG_DE4X5 is not set
+# CONFIG_WINBOND_840 is not set
+# CONFIG_DM9102 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=y
-# CONFIG_EEPRO100_PIO is not set
-# CONFIG_E100 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
@@ -293,85 +374,98 @@
 # CONFIG_YELLOWFIN is not set
 # CONFIG_R8169 is not set
 # CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 
 #
 # Ethernet (10000 Mbit)
 #
 # CONFIG_IXGB is not set
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
-# CONFIG_PPP is not set
-# CONFIG_SLIP is not set
+# CONFIG_S2IO is not set
 
 #
-# Wireless LAN (non-hamradio)
+# Token Ring devices
 #
-# CONFIG_NET_RADIO is not set
+# CONFIG_TR is not set
 
 #
-# Token Ring devices (depends on LLC=y)
+# Wireless LAN (non-hamradio)
 #
-# CONFIG_RCPCI is not set
-# CONFIG_SHAPER is not set
+# CONFIG_NET_RADIO is not set
 
 #
 # Wan interfaces
 #
 # CONFIG_WAN is not set
-
-#
-# Amateur Radio support
-#
-# CONFIG_HAMRADIO is not set
-
-#
-# IrDA (infrared) support
-#
-# CONFIG_IRDA is not set
+# 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_BOOL is not set
+# CONFIG_ISDN is not set
 
 #
-# Graphics support
+# Telephony Support
 #
-# CONFIG_FB is not set
-
-#
-# Old CD-ROM drivers (not SCSI, not IDE)
-#
-# CONFIG_CD_NO_IDESCSI is not set
+# CONFIG_PHONE is not set
 
 #
 # 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
 #
 # CONFIG_GAMEPORT is not set
 CONFIG_SOUND_GAMEPORT=y
-# CONFIG_SERIO is not set
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_RAW is not set
 
 #
 # Input Device Drivers
 #
-
-#
-# Macintosh 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
 #
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
@@ -379,6 +473,7 @@
 #
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=4
 # CONFIG_SERIAL_8250_EXTENDED is not set
 
 #
@@ -387,68 +482,120 @@
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_UNIX98_PTYS=y
-CONFIG_UNIX98_PTY_COUNT=256
+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
+# 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
 
 #
 # I2C support
 #
 CONFIG_I2C=m
+CONFIG_I2C_CHARDEV=m
+
+#
+# I2C Algorithms
+#
 # CONFIG_I2C_ALGOBIT is not set
 # CONFIG_I2C_ALGOPCF is not set
-CONFIG_I2C_CHARDEV=m
+# CONFIG_I2C_ALGOPCA is not set
 
 #
-# I2C Hardware Sensors Mainboard support
+# 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_ISA 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
+# CONFIG_I2C_PCA_ISA is not set
 
 #
-# I2C Hardware Sensors Chip support
+# 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_I2C_SENSOR is not set
-
-#
-# Mice
-#
-# CONFIG_BUSMOUSE is not set
-# CONFIG_QIC02_TAPE is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83627HF is not set
 
 #
-# IPMI
+# Other I2C Chip support
 #
-# CONFIG_IPMI_HANDLER 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_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
 
 #
-# Watchdog Cards
+# Dallas's 1-wire bus
 #
-# 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
-# CONFIG_APPLICOM is not set
+# CONFIG_W1 is not set
 
 #
-# Ftape, the floppy tape device driver
+# Misc devices
 #
-# CONFIG_FTAPE is not set
-# CONFIG_AGP is not set
-# CONFIG_DRM is not set
-# CONFIG_RAW_DRIVER is not set
-# CONFIG_HANGCHECK_TIMER is not set
 
 #
 # Multimedia devices
@@ -461,6 +608,34 @@
 # CONFIG_DVB is not set
 
 #
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Console display driver support
+#
+CONFIG_VGA_CONSOLE=y
+CONFIG_DUMMY_CONSOLE=y
+
+#
+# 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
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
@@ -473,6 +648,7 @@
 # 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,19 +661,23 @@
 #
 # 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
 
 #
 # 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=y
 # 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
 
 #
@@ -506,6 +686,7 @@
 # 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
@@ -522,18 +703,19 @@
 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_SUNRPC_GSS is not set
+# 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
 
 #
@@ -543,36 +725,32 @@
 CONFIG_MSDOS_PARTITION=y
 
 #
-# Sound
-#
-# CONFIG_SOUND is not set
-
-#
-# USB support
+# Native Language Support
 #
-# CONFIG_USB is not set
-# CONFIG_USB_GADGET is not set
+# CONFIG_NLS is not set
 
 #
-# Bluetooth support
+# Library routines
 #
-# CONFIG_BT is not set
+# CONFIG_CRC_CCITT is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
 
 #
-# Library routines
+# Profiling support
 #
-# CONFIG_CRC32 is not set
+# CONFIG_PROFILING is not set
 
 #
 # Kernel hacking
 #
 # CONFIG_DEBUG_KERNEL is not set
-# CONFIG_KALLSYMS is not set
 # CONFIG_SERIAL_TEXT_DEBUG is not set
 
 #
 # Security options
 #
+# CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 
 #
diff -Nru a/arch/ppc/configs/ibmchrp_defconfig b/arch/ppc/configs/ibmchrp_defconfig
--- a/arch/ppc/configs/ibmchrp_defconfig	2005-03-01 23:38:57 -08:00
+++ b/arch/ppc/configs/ibmchrp_defconfig	2005-03-01 23:38:57 -08:00
@@ -367,7 +367,6 @@
 CONFIG_IP_NF_TARGET_REDIRECT=m
 CONFIG_IP_NF_TARGET_NETMAP=m
 CONFIG_IP_NF_TARGET_SAME=m
-# CONFIG_IP_NF_NAT_LOCAL is not set
 CONFIG_IP_NF_NAT_SNMP_BASIC=m
 CONFIG_IP_NF_NAT_IRC=m
 CONFIG_IP_NF_NAT_FTP=m
diff -Nru a/arch/ppc/configs/k2_defconfig b/arch/ppc/configs/k2_defconfig
--- a/arch/ppc/configs/k2_defconfig	2005-03-01 23:38:51 -08:00
+++ b/arch/ppc/configs/k2_defconfig	2005-03-01 23:38:51 -08:00
@@ -319,7 +319,6 @@
 CONFIG_IP_NF_TARGET_REDIRECT=m
 # CONFIG_IP_NF_TARGET_NETMAP is not set
 # CONFIG_IP_NF_TARGET_SAME is not set
-# CONFIG_IP_NF_NAT_LOCAL is not set
 # CONFIG_IP_NF_NAT_SNMP_BASIC is not set
 CONFIG_IP_NF_NAT_FTP=m
 # CONFIG_IP_NF_MANGLE is not set
diff -Nru a/arch/ppc/configs/katana_defconfig b/arch/ppc/configs/katana_defconfig
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/ppc/configs/katana_defconfig	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,691 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.11-rc2
+# Tue Jan 25 16:31:13 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
+
+#
+# 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=y
+# CONFIG_IKCONFIG is not set
+# CONFIG_EMBEDDED is not set
+CONFIG_KALLSYMS=y
+# 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=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=y
+# 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 is not set
+CONFIG_ALTIVEC=y
+# CONFIG_TAU is not set
+# CONFIG_CPU_FREQ is not set
+CONFIG_PPC_STD_MMU=y
+CONFIG_NOT_COHERENT_CACHE=y
+
+#
+# Platform options
+#
+# CONFIG_PPC_MULTIPLATFORM is not set
+# CONFIG_APUS is not set
+CONFIG_KATANA=y
+# 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_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_ADIR is not set
+# CONFIG_K2 is not set
+# CONFIG_PAL4 is not set
+# CONFIG_GEMINI is not set
+# CONFIG_EST8260 is not set
+# CONFIG_SBC82xx is not set
+# CONFIG_SBS8260 is not set
+# 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_MV64360=y
+CONFIG_MV64X60=y
+
+#
+# Set bridge options
+#
+CONFIG_MV64X60_BASE=0xf8100000
+CONFIG_MV64X60_NEW_BASE=0xf8100000
+# CONFIG_SMP is not set
+# CONFIG_PREEMPT is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_MISC=y
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttyMM0,9600 ip=on"
+
+#
+# Bus options
+#
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_LEGACY_PROC=y
+CONFIG_PCI_NAMES=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# Advanced setup
+#
+CONFIG_ADVANCED_OPTIONS=y
+CONFIG_HIGHMEM_START=0xfe000000
+# CONFIG_LOWMEM_SIZE_BOOL is not set
+CONFIG_LOWMEM_SIZE=0x30000000
+# CONFIG_KERNEL_START_BOOL is not set
+CONFIG_KERNEL_START=0xc0000000
+# CONFIG_TASK_SIZE_BOOL is not set
+CONFIG_TASK_SIZE=0x80000000
+CONFIG_CONSISTENT_START_BOOL=y
+CONFIG_CONSISTENT_START=0xf0000000
+# CONFIG_CONSISTENT_SIZE_BOOL is not set
+CONFIG_CONSISTENT_SIZE=0x00200000
+# CONFIG_BOOT_LOAD_BOOL is not set
+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_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_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+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
+#
+# 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_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 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=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
+
+#
+# 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=y
+# CONFIG_DE2104X is not set
+CONFIG_TULIP=y
+# CONFIG_TULIP_MWI is not set
+# CONFIG_TULIP_MMIO is not set
+# CONFIG_TULIP_NAPI is not set
+# CONFIG_DE4X5 is not set
+# CONFIG_WINBOND_840 is not set
+# CONFIG_DM9102 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=y
+# CONFIG_E100_NAPI is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# 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 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_VIA_VELOCITY 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 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=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
+#
+# 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_SERIAL_MPSC=y
+CONFIG_SERIAL_MPSC_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_GEN_RTC=y
+# CONFIG_GEN_RTC_X 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
+
+#
+# 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=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_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=y
+# CONFIG_DEVFS_MOUNT is not set
+# 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 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
+
+#
+# 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_DEBUG_KERNEL 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
+#
diff -Nru a/arch/ppc/configs/luan_defconfig b/arch/ppc/configs/luan_defconfig
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/ppc/configs/luan_defconfig	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,668 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.11-rc2
+# Mon Jan 31 16:26:31 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
+
+#
+# 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=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_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=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_E500 is not set
+CONFIG_BOOKE=y
+CONFIG_PTE_64BIT=y
+CONFIG_PHYS_64BIT=y
+# CONFIG_MATH_EMULATION is not set
+# CONFIG_CPU_FREQ is not set
+CONFIG_4xx=y
+
+#
+# IBM 4xx options
+#
+# CONFIG_EBONY is not set
+CONFIG_LUAN=y
+# CONFIG_OCOTEA is not set
+CONFIG_440SP=y
+CONFIG_440=y
+CONFIG_IBM_OCP=y
+CONFIG_IBM_EMAC4=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_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="ip=on console=ttyS0,115200"
+
+#
+# Bus options
+#
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=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
+#
+
+#
+# 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_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
+#
+# 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_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 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
+
+#
+# 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_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=128
+CONFIG_IBM_EMAC_TXB=128
+CONFIG_IBM_EMAC_FGAP=8
+CONFIG_IBM_EMAC_SKBRES=0
+# 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 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=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
+#
+# 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_LIBPS2 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 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_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_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
+
+#
+# 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 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=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_ROOT_NFS=y
+CONFIG_LOCKD=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
+
+#
+# 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_DEBUG_KERNEL=y
+# CONFIG_MAGIC_SYSRQ is not set
+# 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 -Nru a/arch/ppc/configs/menf1_defconfig b/arch/ppc/configs/menf1_defconfig
--- a/arch/ppc/configs/menf1_defconfig	2005-03-01 23:39:18 -08:00
+++ b/arch/ppc/configs/menf1_defconfig	2005-03-01 23:39:18 -08:00
@@ -249,7 +249,6 @@
 CONFIG_IP_NF_NAT_NEEDED=y
 CONFIG_IP_NF_TARGET_MASQUERADE=m
 CONFIG_IP_NF_TARGET_REDIRECT=m
-# CONFIG_IP_NF_NAT_LOCAL is not set
 # CONFIG_IP_NF_NAT_SNMP_BASIC is not set
 CONFIG_IP_NF_NAT_IRC=m
 CONFIG_IP_NF_NAT_FTP=m
diff -Nru a/arch/ppc/configs/mpc8540_ads_defconfig b/arch/ppc/configs/mpc8540_ads_defconfig
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/ppc/configs/mpc8540_ads_defconfig	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,707 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.11-rc1
+# Thu Jan 20 01:23:13 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
+
+#
+# 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=y
+# CONFIG_IKCONFIG is not set
+CONFIG_EMBEDDED=y
+# CONFIG_KALLSYMS is not set
+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
+
+#
+# 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_SPE=y
+CONFIG_MATH_EMULATION=y
+# CONFIG_CPU_FREQ is not set
+CONFIG_PPC_GEN550=y
+CONFIG_85xx=y
+CONFIG_PPC_INDIRECT_PCI_BE=y
+
+#
+# Freescale 85xx options
+#
+CONFIG_MPC8540_ADS=y
+# CONFIG_MPC8555_CDS is not set
+# CONFIG_MPC8560_ADS is not set
+# CONFIG_SBC8560 is not set
+CONFIG_MPC8540=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
+
+#
+# Bus options
+#
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+# CONFIG_PCI_LEGACY_PROC is not set
+CONFIG_PCI_NAMES=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# 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_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_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
+#
+# 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_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 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_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
+CONFIG_GIANFAR=y
+CONFIG_GFAR_NAPI=y
+
+#
+# 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
+
+#
+# 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 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
+# 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
+
+#
+# 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_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_ISA is not set
+CONFIG_I2C_MPC=y
+# 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_VIA is not set
+# 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
+#
+# 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_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
+# 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=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
+# 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_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=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_DEBUG_KERNEL is not set
+# CONFIG_SERIAL_TEXT_DEBUG 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
+#
diff -Nru a/arch/ppc/configs/mpc8555_cds_defconfig b/arch/ppc/configs/mpc8555_cds_defconfig
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/ppc/configs/mpc8555_cds_defconfig	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,718 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.11-rc1
+# Thu Jan 20 01:25: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
+
+#
+# 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=y
+# CONFIG_IKCONFIG is not set
+CONFIG_EMBEDDED=y
+# CONFIG_KALLSYMS is not set
+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
+
+#
+# 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_SPE=y
+CONFIG_MATH_EMULATION=y
+# CONFIG_CPU_FREQ is not set
+CONFIG_PPC_GEN550=y
+CONFIG_85xx=y
+CONFIG_PPC_INDIRECT_PCI_BE=y
+
+#
+# Freescale 85xx options
+#
+# CONFIG_MPC8540_ADS is not set
+CONFIG_MPC8555_CDS=y
+# CONFIG_MPC8560_ADS is not set
+# CONFIG_SBC8560 is not set
+CONFIG_MPC8555=y
+CONFIG_85xx_PCI2=y
+
+#
+# Platform options
+#
+CONFIG_CPM2=y
+# CONFIG_PC_KEYBOARD 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
+
+#
+# Bus options
+#
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+# CONFIG_PCI_LEGACY_PROC is not set
+CONFIG_PCI_NAMES=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# 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_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_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
+#
+# 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_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 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_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
+CONFIG_GIANFAR=y
+CONFIG_GFAR_NAPI=y
+
+#
+# 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
+
+#
+# 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 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_SERIAL_CPM 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=y
+# CONFIG_GEN_RTC_X 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
+
+#
+# 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_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_ISA is not set
+CONFIG_I2C_MPC=y
+# 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_VIA is not set
+# 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
+#
+# 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_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
+# 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=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
+# 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_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=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
+# CONFIG_SCC_ENET is not set
+# CONFIG_FEC_ENET is not set
+
+#
+# CPM2 Options
+#
+
+#
+# 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_DEBUG_KERNEL is not set
+# CONFIG_KGDB_CONSOLE is not set
+# CONFIG_SERIAL_TEXT_DEBUG 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
+#
diff -Nru a/arch/ppc/configs/mpc8560_ads_defconfig b/arch/ppc/configs/mpc8560_ads_defconfig
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/ppc/configs/mpc8560_ads_defconfig	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,719 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.11-rc1
+# Thu Jan 20 01:24:56 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
+
+#
+# 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=y
+# CONFIG_IKCONFIG is not set
+CONFIG_EMBEDDED=y
+# CONFIG_KALLSYMS is not set
+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
+
+#
+# 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_SPE=y
+CONFIG_MATH_EMULATION=y
+# CONFIG_CPU_FREQ is not set
+CONFIG_85xx=y
+CONFIG_PPC_INDIRECT_PCI_BE=y
+
+#
+# Freescale 85xx options
+#
+# CONFIG_MPC8540_ADS is not set
+# CONFIG_MPC8555_CDS is not set
+CONFIG_MPC8560_ADS=y
+# CONFIG_SBC8560 is not set
+CONFIG_MPC8560=y
+
+#
+# Platform options
+#
+CONFIG_CPM2=y
+# CONFIG_PC_KEYBOARD 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
+
+#
+# Bus options
+#
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+# CONFIG_PCI_LEGACY_PROC is not set
+CONFIG_PCI_NAMES=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# 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_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_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
+#
+# 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_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 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_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
+CONFIG_GIANFAR=y
+CONFIG_GFAR_NAPI=y
+
+#
+# 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
+
+#
+# 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 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=y
+# CONFIG_SERIAL_CPM_SCC2 is not set
+# CONFIG_SERIAL_CPM_SCC3 is not set
+CONFIG_SERIAL_CPM_SCC4=y
+# CONFIG_SERIAL_CPM_SMC1 is not set
+# CONFIG_SERIAL_CPM_SMC2 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=y
+# CONFIG_GEN_RTC_X 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
+
+#
+# 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_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_ISA is not set
+CONFIG_I2C_MPC=y
+# 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_VIA is not set
+# 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
+#
+# 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_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
+# 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=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
+# 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_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=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
+# CONFIG_SCC_ENET is not set
+# CONFIG_FEC_ENET is not set
+
+#
+# CPM2 Options
+#
+
+#
+# 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_DEBUG_KERNEL is not set
+# CONFIG_KGDB_CONSOLE 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
+#
diff -Nru a/arch/ppc/configs/pcore_defconfig b/arch/ppc/configs/pcore_defconfig
--- a/arch/ppc/configs/pcore_defconfig	2005-03-01 23:38:57 -08:00
+++ b/arch/ppc/configs/pcore_defconfig	2005-03-01 23:38:57 -08:00
@@ -332,7 +332,6 @@
 CONFIG_IP_NF_TARGET_REDIRECT=m
 # CONFIG_IP_NF_TARGET_NETMAP is not set
 # CONFIG_IP_NF_TARGET_SAME is not set
-# CONFIG_IP_NF_NAT_LOCAL is not set
 # CONFIG_IP_NF_NAT_SNMP_BASIC is not set
 CONFIG_IP_NF_NAT_IRC=m
 CONFIG_IP_NF_NAT_FTP=m
diff -Nru a/arch/ppc/configs/pmac_defconfig b/arch/ppc/configs/pmac_defconfig
--- a/arch/ppc/configs/pmac_defconfig	2005-03-01 23:39:16 -08:00
+++ b/arch/ppc/configs/pmac_defconfig	2005-03-01 23:39:16 -08:00
@@ -479,7 +479,6 @@
 CONFIG_IP_NF_TARGET_REDIRECT=m
 CONFIG_IP_NF_TARGET_NETMAP=m
 CONFIG_IP_NF_TARGET_SAME=m
-# CONFIG_IP_NF_NAT_LOCAL is not set
 CONFIG_IP_NF_NAT_SNMP_BASIC=m
 CONFIG_IP_NF_NAT_IRC=m
 CONFIG_IP_NF_NAT_FTP=m
diff -Nru a/arch/ppc/configs/pplus_defconfig b/arch/ppc/configs/pplus_defconfig
--- a/arch/ppc/configs/pplus_defconfig	2005-03-01 23:38:59 -08:00
+++ b/arch/ppc/configs/pplus_defconfig	2005-03-01 23:38:59 -08:00
@@ -343,7 +343,6 @@
 CONFIG_IP_NF_TARGET_REDIRECT=m
 # CONFIG_IP_NF_TARGET_NETMAP is not set
 # CONFIG_IP_NF_TARGET_SAME is not set
-# CONFIG_IP_NF_NAT_LOCAL is not set
 # CONFIG_IP_NF_NAT_SNMP_BASIC is not set
 CONFIG_IP_NF_NAT_FTP=m
 # CONFIG_IP_NF_MANGLE is not set
diff -Nru a/arch/ppc/configs/stx_gp3_defconfig b/arch/ppc/configs/stx_gp3_defconfig
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/ppc/configs/stx_gp3_defconfig	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,972 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 14:32:58 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
+
+#
+# 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=y
+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_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
+#
+# 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_SPE is not set
+CONFIG_MATH_EMULATION=y
+# CONFIG_CPU_FREQ is not set
+CONFIG_85xx=y
+CONFIG_PPC_INDIRECT_PCI_BE=y
+
+#
+# Freescale 85xx options
+#
+# CONFIG_MPC8540_ADS is not set
+# CONFIG_MPC8555_CDS is not set
+# CONFIG_MPC8560_ADS is not set
+# CONFIG_SBC8560 is not set
+CONFIG_STX_GP3=y
+CONFIG_MPC8560=y
+
+#
+# Platform options
+#
+CONFIG_CPM2=y
+# CONFIG_PC_KEYBOARD is not set
+# CONFIG_SMP is not set
+# CONFIG_PREEMPT is not set
+CONFIG_HIGHMEM=y
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_MISC=m
+# CONFIG_CMDLINE_BOOL is not set
+
+#
+# Bus options
+#
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=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
+#
+
+#
+# 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
+# CONFIG_DEBUG_DRIVER is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+CONFIG_PARPORT=m
+CONFIG_PARPORT_PC=m
+# CONFIG_PARPORT_PC_FIFO is not set
+# CONFIG_PARPORT_PC_SUPERIO is not set
+# CONFIG_PARPORT_OTHER is not set
+# CONFIG_PARPORT_1284 is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD 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=m
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+CONFIG_BLK_DEV_NBD=m
+# CONFIG_BLK_DEV_SX8 is not set
+CONFIG_BLK_DEV_RAM=m
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+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=m
+# 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 is not set
+# 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=m
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+CONFIG_CHR_DEV_ST=m
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=m
+# CONFIG_BLK_DEV_SR_VENDOR is not set
+CONFIG_CHR_DEV_SG=m
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI Transport Attributes
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# 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_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_PPA is not set
+# CONFIG_SCSI_IMM 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 is not set
+CONFIG_SCSI_QLA2XXX=m
+# 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_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
+
+#
+# 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_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 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
+
+#
+# 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 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 is not set
+# CONFIG_IP_NF_AMANDA is not set
+# CONFIG_IP_NF_QUEUE is not set
+CONFIG_IP_NF_IPTABLES=m
+# CONFIG_IP_NF_MATCH_LIMIT is not set
+# CONFIG_IP_NF_MATCH_IPRANGE is not set
+# CONFIG_IP_NF_MATCH_MAC is not set
+# CONFIG_IP_NF_MATCH_PKTTYPE is not set
+# CONFIG_IP_NF_MATCH_MARK is not set
+# CONFIG_IP_NF_MATCH_MULTIPORT is not set
+# CONFIG_IP_NF_MATCH_TOS is not set
+# CONFIG_IP_NF_MATCH_RECENT is not set
+# CONFIG_IP_NF_MATCH_ECN is not set
+# CONFIG_IP_NF_MATCH_DSCP is not set
+# CONFIG_IP_NF_MATCH_AH_ESP is not set
+# CONFIG_IP_NF_MATCH_LENGTH is not set
+# CONFIG_IP_NF_MATCH_TTL is not set
+# CONFIG_IP_NF_MATCH_TCPMSS is not set
+# CONFIG_IP_NF_MATCH_HELPER is not set
+# CONFIG_IP_NF_MATCH_STATE is not set
+# CONFIG_IP_NF_MATCH_CONNTRACK is not set
+# CONFIG_IP_NF_MATCH_OWNER is not set
+# 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 is not set
+# CONFIG_IP_NF_TARGET_LOG is not set
+# CONFIG_IP_NF_TARGET_ULOG is not set
+# CONFIG_IP_NF_TARGET_TCPMSS is not set
+CONFIG_IP_NF_NAT=m
+CONFIG_IP_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+# CONFIG_IP_NF_TARGET_NETMAP is not set
+# CONFIG_IP_NF_TARGET_SAME is not set
+CONFIG_IP_NF_NAT_SNMP_BASIC=m
+CONFIG_IP_NF_NAT_IRC=m
+CONFIG_IP_NF_NAT_FTP=m
+# CONFIG_IP_NF_MANGLE is not set
+# CONFIG_IP_NF_RAW 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_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
+CONFIG_GIANFAR=y
+CONFIG_GFAR_NAPI=y
+
+#
+# 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_PLIP 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=1280
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=1024
+CONFIG_INPUT_JOYDEV=m
+# CONFIG_INPUT_TSDEV is not set
+CONFIG_INPUT_EVDEV=m
+# 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=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_CT82C710 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
+
+#
+# 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
+#
+# 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=y
+# CONFIG_SERIAL_CPM_SCC3 is not set
+# CONFIG_SERIAL_CPM_SCC4 is not set
+# CONFIG_SERIAL_CPM_SMC1 is not set
+# CONFIG_SERIAL_CPM_SMC2 is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+CONFIG_PRINTER=m
+# CONFIG_LP_CONSOLE is not set
+# CONFIG_PPDEV is not set
+# CONFIG_TIPAR 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
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+CONFIG_AGP=m
+CONFIG_DRM=m
+# CONFIG_DRM_TDFX is not set
+# CONFIG_DRM_R128 is not set
+# CONFIG_DRM_RADEON is not set
+# CONFIG_DRM_MGA is not set
+# CONFIG_DRM_SIS is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=m
+CONFIG_I2C_CHARDEV=m
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=m
+# 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_ISA is not set
+# 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
+# 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
+
+#
+# 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
+#
+# 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_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
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+CONFIG_SOUND=m
+
+#
+# Advanced Linux Sound Architecture
+#
+# CONFIG_SND is not set
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME 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=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=y
+CONFIG_FS_MBCACHE=y
+# 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=m
+CONFIG_AUTOFS4_FS=y
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=m
+# CONFIG_JOLIET is not set
+# 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 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=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=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
+
+#
+# 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=m
+# CONFIG_SMB_NLS_DEFAULT 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
+# CONFIG_SCC_ENET is not set
+# CONFIG_FEC_ENET is not set
+
+#
+# CPM2 Options
+#
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=y
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=m
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_MAGIC_SYSRQ is not set
+# 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_INFO is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_KGDB_CONSOLE is not set
+# CONFIG_XMON is not set
+CONFIG_BDI_SWITCH=y
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
diff -Nru a/arch/ppc/defconfig b/arch/ppc/defconfig
--- a/arch/ppc/defconfig	2005-03-01 23:39:09 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,1330 +0,0 @@
-#
-# Automatically generated make config: don't edit
-#
-CONFIG_MMU=y
-CONFIG_RWSEM_XCHGADD_ALGORITHM=y
-CONFIG_HAVE_DEC_LOCK=y
-CONFIG_PPC=y
-CONFIG_PPC32=y
-CONFIG_GENERIC_NVRAM=y
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-# CONFIG_STANDALONE is not set
-CONFIG_BROKEN_ON_SMP=y
-
-#
-# General setup
-#
-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_LOG_BUF_SHIFT=14
-CONFIG_HOTPLUG=y
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-# CONFIG_EMBEDDED is not set
-CONFIG_KALLSYMS=y
-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
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
-CONFIG_MODVERSIONS=y
-CONFIG_KMOD=y
-
-#
-# Processor
-#
-CONFIG_6xx=y
-# 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_ALTIVEC=y
-CONFIG_TAU=y
-# CONFIG_TAU_INT is not set
-# CONFIG_TAU_AVERAGE is not set
-CONFIG_CPU_FREQ=y
-CONFIG_CPU_FREQ_PROC_INTF=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=y
-CONFIG_CPU_FREQ_GOV_USERSPACE=y
-# CONFIG_CPU_FREQ_24_API is not set
-CONFIG_CPU_FREQ_PMAC=y
-CONFIG_CPU_FREQ_TABLE=y
-CONFIG_PPC601_SYNC_FIX=y
-CONFIG_PM=y
-CONFIG_PPC_STD_MMU=y
-
-#
-# Platform options
-#
-CONFIG_PPC_MULTIPLATFORM=y
-# CONFIG_APUS is not set
-# CONFIG_WILLOW is not set
-# CONFIG_PCORE is not set
-# CONFIG_POWERPMC250 is not set
-# CONFIG_EV64260 is not set
-# CONFIG_SPRUCE 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_ADIR is not set
-# CONFIG_K2 is not set
-# CONFIG_PAL4 is not set
-# CONFIG_GEMINI is not set
-# CONFIG_EST8260 is not set
-# CONFIG_SBS8260 is not set
-# CONFIG_RPX6 is not set
-# CONFIG_TQM8260 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_KERNEL_ELF=y
-CONFIG_BINFMT_ELF=y
-CONFIG_BINFMT_MISC=m
-CONFIG_PROC_DEVICETREE=y
-CONFIG_PPC_RTAS=y
-CONFIG_PREP_RESIDUAL=y
-CONFIG_PROC_PREPRESIDUAL=y
-CONFIG_CMDLINE_BOOL=y
-CONFIG_CMDLINE="console=ttyS0,9600 console=tty0 root=/dev/sda2"
-
-#
-# Bus options
-#
-CONFIG_ISA=y
-CONFIG_GENERIC_ISA_DMA=y
-CONFIG_PCI=y
-CONFIG_PCI_DOMAINS=y
-CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
-
-#
-# PCMCIA/CardBus support
-#
-# CONFIG_PCMCIA is not set
-CONFIG_PCMCIA_PROBE=y
-
-#
-# Advanced setup
-#
-CONFIG_ADVANCED_OPTIONS=y
-CONFIG_HIGHMEM_START=0xfe000000
-# CONFIG_LOWMEM_SIZE_BOOL is not set
-CONFIG_LOWMEM_SIZE=0x30000000
-# CONFIG_KERNEL_START_BOOL is not set
-CONFIG_KERNEL_START=0xc0000000
-# CONFIG_TASK_SIZE_BOOL is not set
-CONFIG_TASK_SIZE=0x80000000
-CONFIG_BOOT_LOAD=0x00800000
-
-#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-# 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=m
-# CONFIG_BLK_DEV_XD 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_LOOP=y
-# CONFIG_BLK_DEV_CRYPTOLOOP is not set
-# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_CARMEL is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_LBD=y
-
-#
-# 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_IDEDISK=y
-# CONFIG_IDEDISK_MULTI_MODE is not set
-# CONFIG_IDEDISK_STROKE is not set
-CONFIG_BLK_DEV_IDECD=y
-# CONFIG_BLK_DEV_IDETAPE is not set
-CONFIG_BLK_DEV_IDEFLOPPY=y
-CONFIG_BLK_DEV_IDESCSI=y
-# CONFIG_IDE_TASK_IOCTL is not set
-# CONFIG_IDE_TASKFILE_IO 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=y
-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_ADMA=y
-# 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_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_BLK_DEV_IDE_PMAC=y
-CONFIG_BLK_DEV_IDE_PMAC_ATA100FIRST=y
-CONFIG_BLK_DEV_IDEDMA_PMAC=y
-CONFIG_BLK_DEV_IDE_PMAC_BLINK=y
-CONFIG_BLK_DEV_IDEDMA_PMAC_AUTO=y
-# CONFIG_IDE_CHIPSETS 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=y
-CONFIG_SCSI_PROC_FS=y
-
-#
-# SCSI support type (disk, tape, CD-ROM)
-#
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_ST=y
-# CONFIG_CHR_DEV_OSST is not set
-CONFIG_BLK_DEV_SR=y
-CONFIG_BLK_DEV_SR_VENDOR=y
-CONFIG_CHR_DEV_SG=y
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
-# CONFIG_SCSI_MULTI_LUN is not set
-CONFIG_SCSI_REPORT_LUNS=y
-CONFIG_SCSI_CONSTANTS=y
-# CONFIG_SCSI_LOGGING is not set
-
-#
-# SCSI Transport Attributes
-#
-CONFIG_SCSI_SPI_ATTRS=y
-# CONFIG_SCSI_FC_ATTRS is not set
-
-#
-# SCSI low-level drivers
-#
-# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
-# CONFIG_SCSI_7000FASST is not set
-# CONFIG_SCSI_ACARD is not set
-# CONFIG_SCSI_AHA152X is not set
-# CONFIG_SCSI_AHA1542 is not set
-# CONFIG_SCSI_AACRAID is not set
-CONFIG_SCSI_AIC7XXX=m
-CONFIG_AIC7XXX_CMDS_PER_DEVICE=253
-CONFIG_AIC7XXX_RESET_DELAY_MS=15000
-# CONFIG_AIC7XXX_BUILD_FIRMWARE is not set
-CONFIG_AIC7XXX_DEBUG_ENABLE=y
-CONFIG_AIC7XXX_DEBUG_MASK=0
-CONFIG_AIC7XXX_REG_PRETTY_PRINT=y
-CONFIG_SCSI_AIC7XXX_OLD=m
-# CONFIG_SCSI_AIC79XX is not set
-CONFIG_SCSI_ADVANSYS=m
-# CONFIG_SCSI_IN2000 is not set
-# CONFIG_SCSI_MEGARAID 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
-# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
-# CONFIG_SCSI_IPS is not set
-# CONFIG_SCSI_INIA100 is not set
-# CONFIG_SCSI_NCR53C406A is not set
-CONFIG_SCSI_SYM53C8XX_2=y
-CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0
-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_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_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_SYM53C416 is not set
-# CONFIG_SCSI_DC395x is not set
-# CONFIG_SCSI_DC390T is not set
-# CONFIG_SCSI_T128 is not set
-# CONFIG_SCSI_U14_34F is not set
-# CONFIG_SCSI_NSP32 is not set
-# CONFIG_SCSI_DEBUG is not set
-CONFIG_SCSI_MESH=y
-CONFIG_SCSI_MESH_SYNC_RATE=5
-CONFIG_SCSI_MESH_RESET_DELAY_MS=4000
-CONFIG_SCSI_MAC53C94=y
-
-#
-# Old CD-ROM drivers (not SCSI, not IDE)
-#
-# CONFIG_CD_NO_IDESCSI 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
-#
-CONFIG_ADB=y
-CONFIG_ADB_CUDA=y
-CONFIG_ADB_PMU=y
-CONFIG_PMAC_PBOOK=y
-CONFIG_PMAC_APM_EMU=y
-CONFIG_PMAC_BACKLIGHT=y
-# CONFIG_MAC_FLOPPY is not set
-CONFIG_MAC_SERIAL=m
-CONFIG_ADB_MACIO=y
-CONFIG_INPUT_ADBHID=y
-CONFIG_MAC_EMUMOUSEBTN=y
-CONFIG_THERM_WINDTUNNEL=m
-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
-
-#
-# 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_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_FILTER=m
-CONFIG_IP_NF_TARGET_REJECT=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_LOCAL is not set
-CONFIG_IP_NF_NAT_SNMP_BASIC=m
-CONFIG_IP_NF_NAT_IRC=m
-CONFIG_IP_NF_NAT_FTP=m
-CONFIG_IP_NF_NAT_TFTP=m
-CONFIG_IP_NF_NAT_AMANDA=m
-# CONFIG_IP_NF_MANGLE is not set
-# CONFIG_IP_NF_TARGET_LOG is not set
-# CONFIG_IP_NF_TARGET_ULOG is not set
-CONFIG_IP_NF_TARGET_TCPMSS=m
-CONFIG_IP_NF_ARPTABLES=m
-CONFIG_IP_NF_ARPFILTER=m
-CONFIG_IP_NF_ARP_MANGLE=m
-CONFIG_IP_NF_COMPAT_IPCHAINS=m
-# CONFIG_IP_NF_COMPAT_IPFWADM is not set
-CONFIG_IP_NF_TARGET_NOTRACK=m
-CONFIG_IP_NF_RAW=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_HW_FLOWCONTROL is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED 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_MACE=y
-# CONFIG_MACE_AAUI_PORT is not set
-CONFIG_BMAC=y
-# CONFIG_OAKNET is not set
-# CONFIG_HAPPYMEAL is not set
-# CONFIG_SUNGEM is not set
-# CONFIG_NET_VENDOR_3COM is not set
-# CONFIG_LANCE is not set
-# CONFIG_NET_VENDOR_SMC is not set
-# CONFIG_NET_VENDOR_RACAL is not set
-
-#
-# Tulip family network device support
-#
-# CONFIG_NET_TULIP is not set
-# CONFIG_AT1700 is not set
-# CONFIG_DEPCA is not set
-# CONFIG_HP100 is not set
-# CONFIG_NET_ISA is not set
-CONFIG_NET_PCI=y
-CONFIG_PCNET32=y
-# CONFIG_AMD8111_ETH is not set
-# CONFIG_ADAPTEC_STARFIRE is not set
-# CONFIG_AC3200 is not set
-# CONFIG_APRICOT is not set
-# CONFIG_B44 is not set
-# CONFIG_FORCEDETH is not set
-# CONFIG_CS89x0 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 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
-# CONFIG_NET_POCKET is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-# CONFIG_ACENIC is not set
-# CONFIG_DL2K is not set
-# CONFIG_E1000 is not set
-# CONFIG_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 is not set
-# CONFIG_ARLAN is not set
-# CONFIG_WAVELAN is not set
-
-#
-# Wireless 802.11b ISA/PCI cards support
-#
-# CONFIG_AIRO is not set
-CONFIG_HERMES=m
-CONFIG_APPLE_AIRPORT=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=y
-CONFIG_PPP_MULTILINK=y
-# CONFIG_PPP_FILTER is not set
-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_SLIP is not set
-# CONFIG_NET_FC is not set
-# CONFIG_RCPCI 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=y
-CONFIG_INPUT_EVBUG=y
-
-#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-CONFIG_SERIO_I8042=y
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PCIPS2 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
-
-#
-# 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 is not set
-CONFIG_SERIAL_8250_NR_UARTS=4
-# CONFIG_SERIAL_8250_EXTENDED is not set
-
-#
-# Non-8250 serial port support
-#
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_PMACZILOG=y
-# CONFIG_SERIAL_PMACZILOG_CONSOLE is not set
-CONFIG_UNIX98_PTYS=y
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
-# CONFIG_QIC02_TAPE is not set
-
-#
-# IPMI
-#
-# CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
-CONFIG_NVRAM=y
-CONFIG_GEN_RTC=y
-# CONFIG_GEN_RTC_X 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
-
-#
-# I2C support
-#
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=m
-
-#
-# I2C Algorithms
-#
-CONFIG_I2C_ALGOBIT=y
-# CONFIG_I2C_ALGOPCF 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_ELEKTOR is not set
-CONFIG_I2C_HYDRA=y
-# CONFIG_I2C_I801 is not set
-# CONFIG_I2C_I810 is not set
-# CONFIG_I2C_ISA is not set
-CONFIG_I2C_KEYWEST=m
-# 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_VIA is not set
-# CONFIG_I2C_VIAPRO is not set
-# CONFIG_I2C_VOODOO3 is not set
-
-#
-# Hardware Sensors Chip support
-#
-# CONFIG_I2C_SENSOR is not set
-# CONFIG_SENSORS_ADM1021 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_LM75 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_LM90 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_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
-
-#
-# 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_PM2 is not set
-# CONFIG_FB_CYBER2000 is not set
-CONFIG_FB_OF=y
-CONFIG_FB_CONTROL=y
-CONFIG_FB_PLATINUM=y
-CONFIG_FB_VALKYRIE=y
-CONFIG_FB_CT65550=y
-CONFIG_FB_IMSTT=y
-# CONFIG_FB_S3TRIO is not set
-# CONFIG_FB_VGA16 is not set
-# CONFIG_FB_RIVA 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=y
-CONFIG_FB_MATROX_G100=y
-CONFIG_FB_MATROX_I2C=y
-# CONFIG_FB_MATROX_MAVEN is not set
-# CONFIG_FB_MATROX_MULTIHEAD is not set
-# CONFIG_FB_RADEON_OLD is not set
-CONFIG_FB_RADEON=y
-CONFIG_FB_RADEON_I2C=y
-# CONFIG_FB_RADEON_DEBUG is not set
-CONFIG_FB_ATY128=y
-CONFIG_FB_ATY=y
-CONFIG_FB_ATY_CT=y
-CONFIG_FB_ATY_GX=y
-# CONFIG_FB_ATY_XL_INIT is not set
-# CONFIG_FB_SIS is not set
-# CONFIG_FB_NEOMAGIC is not set
-# CONFIG_FB_KYRO is not set
-CONFIG_FB_3DFX=y
-# CONFIG_FB_VOODOO1 is not set
-# CONFIG_FB_TRIDENT is not set
-# CONFIG_FB_VIRTUAL is not set
-
-#
-# Console display driver support
-#
-CONFIG_VGA_CONSOLE=y
-# CONFIG_MDA_CONSOLE is not set
-CONFIG_DUMMY_CONSOLE=y
-CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_PCI_CONSOLE=y
-# CONFIG_FONTS is not set
-CONFIG_FONT_8x8=y
-CONFIG_FONT_8x16=y
-
-#
-# Logo configuration
-#
-CONFIG_LOGO=y
-CONFIG_LOGO_LINUX_MONO=y
-CONFIG_LOGO_LINUX_VGA16=y
-CONFIG_LOGO_LINUX_CLUT224=y
-
-#
-# Sound
-#
-CONFIG_SOUND=m
-CONFIG_DMASOUND_PMAC=m
-CONFIG_DMASOUND=m
-
-#
-# Advanced Linux Sound Architecture
-#
-CONFIG_SND=m
-CONFIG_SND_TIMER=m
-CONFIG_SND_PCM=m
-CONFIG_SND_HWDEP=m
-CONFIG_SND_RAWMIDI=m
-CONFIG_SND_SEQUENCER=m
-CONFIG_SND_SEQ_DUMMY=m
-CONFIG_SND_OSSEMUL=y
-CONFIG_SND_MIXER_OSS=m
-CONFIG_SND_PCM_OSS=m
-CONFIG_SND_SEQUENCER_OSS=y
-# CONFIG_SND_VERBOSE_PRINTK is not set
-# CONFIG_SND_DEBUG is not set
-
-#
-# Generic devices
-#
-CONFIG_SND_MPU401_UART=m
-CONFIG_SND_OPL3_LIB=m
-# CONFIG_SND_DUMMY is not set
-# CONFIG_SND_VIRMIDI is not set
-# CONFIG_SND_MTPAV is not set
-# CONFIG_SND_SERIAL_U16550 is not set
-# CONFIG_SND_MPU401 is not set
-
-#
-# ISA devices
-#
-# CONFIG_SND_AD1848 is not set
-# CONFIG_SND_CS4231 is not set
-CONFIG_SND_CS4232=m
-# CONFIG_SND_CS4236 is not set
-# CONFIG_SND_ES1688 is not set
-# CONFIG_SND_ES18XX is not set
-# CONFIG_SND_GUSCLASSIC is not set
-# CONFIG_SND_GUSEXTREME is not set
-# CONFIG_SND_GUSMAX is not set
-# CONFIG_SND_INTERWAVE is not set
-# CONFIG_SND_INTERWAVE_STB is not set
-# CONFIG_SND_OPTI92X_AD1848 is not set
-# CONFIG_SND_OPTI92X_CS4231 is not set
-# CONFIG_SND_OPTI93X is not set
-# CONFIG_SND_SB8 is not set
-# CONFIG_SND_SB16 is not set
-# CONFIG_SND_SBAWE is not set
-# CONFIG_SND_WAVEFRONT is not set
-# CONFIG_SND_CMI8330 is not set
-# CONFIG_SND_OPL3SA2 is not set
-# CONFIG_SND_SGALAXY is not set
-# CONFIG_SND_SSCAPE is not set
-
-#
-# PCI devices
-#
-# CONFIG_SND_ALI5451 is not set
-# CONFIG_SND_ATIIXP is not set
-# CONFIG_SND_AU8810 is not set
-# CONFIG_SND_AU8820 is not set
-# CONFIG_SND_AU8830 is not set
-# CONFIG_SND_AZT3328 is not set
-# CONFIG_SND_BT87X is not set
-# CONFIG_SND_CS46XX is not set
-# CONFIG_SND_CS4281 is not set
-# CONFIG_SND_EMU10K1 is not set
-# CONFIG_SND_KORG1212 is not set
-# CONFIG_SND_MIXART is not set
-# CONFIG_SND_NM256 is not set
-# CONFIG_SND_RME32 is not set
-# CONFIG_SND_RME96 is not set
-# CONFIG_SND_RME9652 is not set
-# CONFIG_SND_HDSP is not set
-# CONFIG_SND_TRIDENT is not set
-# CONFIG_SND_YMFPCI is not set
-# CONFIG_SND_ALS4000 is not set
-# CONFIG_SND_CMIPCI is not set
-# CONFIG_SND_ENS1370 is not set
-# CONFIG_SND_ENS1371 is not set
-# CONFIG_SND_ES1938 is not set
-# CONFIG_SND_ES1968 is not set
-# CONFIG_SND_MAESTRO3 is not set
-# CONFIG_SND_FM801 is not set
-# CONFIG_SND_ICE1712 is not set
-# CONFIG_SND_ICE1724 is not set
-# CONFIG_SND_INTEL8X0 is not set
-# CONFIG_SND_INTEL8X0M is not set
-# CONFIG_SND_SONICVIBES is not set
-# CONFIG_SND_VIA82XX is not set
-# CONFIG_SND_VX222 is not set
-
-#
-# ALSA PowerMac devices
-#
-CONFIG_SND_POWERMAC=m
-
-#
-# ALSA USB devices
-#
-CONFIG_SND_USB_AUDIO=m
-
-#
-# Open Sound System
-#
-# CONFIG_SOUND_PRIME is not set
-
-#
-# USB support
-#
-CONFIG_USB=y
-# CONFIG_USB_DEBUG is not set
-
-#
-# Miscellaneous USB options
-#
-CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_BANDWIDTH is not set
-# CONFIG_USB_DYNAMIC_MINORS is not set
-
-#
-# USB Host Controller Drivers
-#
-# CONFIG_USB_EHCI_HCD is not set
-CONFIG_USB_OHCI_HCD=y
-# CONFIG_USB_UHCI_HCD is not set
-
-#
-# USB Device Class drivers
-#
-# CONFIG_USB_AUDIO is not set
-# CONFIG_USB_BLUETOOTH_TTY is not set
-# CONFIG_USB_MIDI is not set
-CONFIG_USB_ACM=m
-CONFIG_USB_PRINTER=m
-CONFIG_USB_STORAGE=m
-# CONFIG_USB_STORAGE_DEBUG is not set
-# CONFIG_USB_STORAGE_DATAFAB is not set
-CONFIG_USB_STORAGE_FREECOM=y
-# CONFIG_USB_STORAGE_ISD200 is not set
-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
-
-#
-# USB Human Interface Devices (HID)
-#
-CONFIG_USB_HID=y
-CONFIG_USB_HIDINPUT=y
-# CONFIG_HID_FF is not set
-# CONFIG_USB_HIDDEV 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_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
-# CONFIG_USB_HPUSBSCSI is not set
-
-#
-# USB Multimedia devices
-#
-# CONFIG_USB_DABUSB is not set
-
-#
-# Video4Linux support is needed for USB Multimedia device support
-#
-
-#
-# USB Network adaptors
-#
-# CONFIG_USB_CATC is not set
-# CONFIG_USB_KAWETH is not set
-# CONFIG_USB_PEGASUS is not set
-# CONFIG_USB_RTL8150 is not set
-# CONFIG_USB_USBNET is not set
-
-#
-# USB port drivers
-#
-
-#
-# USB Serial Converter support
-#
-CONFIG_USB_SERIAL=m
-# CONFIG_USB_SERIAL_GENERIC is not set
-# CONFIG_USB_SERIAL_BELKIN is not set
-# CONFIG_USB_SERIAL_WHITEHEAT is not set
-# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
-# CONFIG_USB_SERIAL_EMPEG is not set
-# CONFIG_USB_SERIAL_FTDI_SIO is not set
-CONFIG_USB_SERIAL_VISOR=m
-# CONFIG_USB_SERIAL_IPAQ is not set
-# 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_KEYSPAN_PDA is not set
-CONFIG_USB_SERIAL_KEYSPAN=m
-# CONFIG_USB_SERIAL_KEYSPAN_MPR is not set
-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_USA19=y
-CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
-CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
-# CONFIG_USB_SERIAL_KEYSPAN_USA19QW is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA19QI is not set
-CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
-# CONFIG_USB_SERIAL_KEYSPAN_USA49WLC is not set
-# 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_SAFE is not set
-# CONFIG_USB_SERIAL_CYBERJACK is not set
-# CONFIG_USB_SERIAL_XIRCOM is not set
-# CONFIG_USB_SERIAL_OMNINET is not set
-CONFIG_USB_EZUSB=y
-
-#
-# USB Miscellaneous drivers
-#
-# 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
-# CONFIG_USB_LCD is not set
-# CONFIG_USB_LED is not set
-# CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_TEST is not set
-
-#
-# USB Gadget Support
-#
-# CONFIG_USB_GADGET 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
-# CONFIG_XFS_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
-# CONFIG_QUOTA is not set
-# 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_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 is not set
-# CONFIG_DEVFS_DEBUG is not set
-# CONFIG_DEVPTS_FS_XATTR is not set
-CONFIG_TMPFS=y
-# 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=m
-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_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=y
-CONFIG_NFSD_V3=y
-# CONFIG_NFSD_V4 is not set
-CONFIG_NFSD_TCP=y
-CONFIG_LOCKD=y
-CONFIG_LOCKD_V4=y
-CONFIG_EXPORTFS=y
-CONFIG_SUNRPC=y
-# CONFIG_RPCSEC_GSS_KRB5 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=y
-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_NEC98_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=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_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
-
-#
-# Library routines
-#
-CONFIG_CRC32=y
-# CONFIG_LIBCRC32C is not set
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
-
-#
-# Kernel hacking
-#
-# CONFIG_DEBUG_KERNEL is not set
-CONFIG_BOOTX_TEXT=y
-
-#
-# Security options
-#
-# CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
-# CONFIG_CRYPTO is not set
diff -Nru a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile
--- a/arch/ppc/kernel/Makefile	2005-03-01 23:39:10 -08:00
+++ b/arch/ppc/kernel/Makefile	2005-03-01 23:39:10 -08:00
@@ -14,7 +14,7 @@
 obj-y				:= entry.o traps.o irq.o idle.o time.o misc.o \
 					process.o signal.o ptrace.o align.o \
 					semaphore.o syscalls.o setup.o \
-					cputable.o ppc_htab.o
+					cputable.o ppc_htab.o perfmon.o
 obj-$(CONFIG_6xx)		+= l2cr.o cpu_setup_6xx.o
 obj-$(CONFIG_POWER4)		+= cpu_setup_power4.o
 obj-$(CONFIG_MODULES)		+= module.o ppc_ksyms.o
@@ -24,6 +24,7 @@
 obj-$(CONFIG_SMP)		+= smp.o smp-tbsync.o
 obj-$(CONFIG_TAU)		+= temp.o
 obj-$(CONFIG_ALTIVEC)		+= vecemu.o vector.o
+obj-$(CONFIG_FSL_BOOKE)		+= perfmon_fsl_booke.o
 
 ifndef CONFIG_MATH_EMULATION
 obj-$(CONFIG_8xx)		+= softemu8xx.o
diff -Nru a/arch/ppc/kernel/cpu_setup_6xx.S b/arch/ppc/kernel/cpu_setup_6xx.S
--- a/arch/ppc/kernel/cpu_setup_6xx.S	2005-03-01 23:38:53 -08:00
+++ b/arch/ppc/kernel/cpu_setup_6xx.S	2005-03-01 23:38:53 -08:00
@@ -292,13 +292,15 @@
 	cmplwi	cr2,r3,0x800c	/* 7410 */
 	cmplwi	cr3,r3,0x8001	/* 7455 */
 	cmplwi	cr4,r3,0x8002	/* 7457 */
-	cmplwi	cr5,r3,0x7000	/* 750FX */
+	cmplwi	cr5,r3,0x8003	/* 7447A */
+	cmplwi	cr6,r3,0x7000	/* 750FX */
 	/* cr1 is 7400 || 7410 */
 	cror	4*cr1+eq,4*cr1+eq,4*cr2+eq
 	/* cr0 is 74xx */
 	cror	4*cr0+eq,4*cr0+eq,4*cr3+eq
 	cror	4*cr0+eq,4*cr0+eq,4*cr4+eq
 	cror	4*cr0+eq,4*cr0+eq,4*cr1+eq
+	cror	4*cr0+eq,4*cr0+eq,4*cr5+eq
 	bne	1f
 	/* Backup 74xx specific regs */
 	mfspr	r4,SPRN_MSSCR0
@@ -316,7 +318,7 @@
 	mfspr	r4,SPRN_LDSTDB
 	stw	r4,CS_LDSTDB(r5)
 1:
-	bne	cr5,1f
+	bne	cr6,1f
 	/* Backup 750FX specific registers */
 	mfspr	r4,SPRN_HID1
 	stw	r4,CS_HID1(r5)
@@ -359,13 +361,15 @@
 	cmplwi	cr2,r3,0x800c	/* 7410 */
 	cmplwi	cr3,r3,0x8001	/* 7455 */
 	cmplwi	cr4,r3,0x8002	/* 7457 */
-	cmplwi	cr5,r3,0x7000	/* 750FX */
+	cmplwi	cr5,r3,0x8003	/* 7447A */
+	cmplwi	cr6,r3,0x7000	/* 750FX */
 	/* cr1 is 7400 || 7410 */
 	cror	4*cr1+eq,4*cr1+eq,4*cr2+eq
 	/* cr0 is 74xx */
 	cror	4*cr0+eq,4*cr0+eq,4*cr3+eq
 	cror	4*cr0+eq,4*cr0+eq,4*cr4+eq
 	cror	4*cr0+eq,4*cr0+eq,4*cr1+eq
+	cror	4*cr0+eq,4*cr0+eq,4*cr5+eq
 	bne	2f
 	/* Restore 74xx specific regs */
 	lwz	r4,CS_MSSCR0(r5)
@@ -404,7 +408,7 @@
 	mtspr	SPRN_LDSTDB,r4
 	isync
 	sync
-2:	bne	cr5,1f
+2:	bne	cr6,1f
 	/* Restore 750FX specific registers
 	 * that is restore HID2 on rev 2.x and PLL config & switch
 	 * to PLL 0 on all
diff -Nru a/arch/ppc/kernel/dma-mapping.c b/arch/ppc/kernel/dma-mapping.c
--- a/arch/ppc/kernel/dma-mapping.c	2005-03-01 23:38:43 -08:00
+++ b/arch/ppc/kernel/dma-mapping.c	2005-03-01 23:38:43 -08:00
@@ -71,7 +71,7 @@
  * This is the page table (2MB) covering uncached, DMA consistent allocations
  */
 static pte_t *consistent_pte;
-static spinlock_t consistent_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(consistent_lock);
 
 /*
  * VM region handling support.
diff -Nru a/arch/ppc/kernel/entry.S b/arch/ppc/kernel/entry.S
--- a/arch/ppc/kernel/entry.S	2005-03-01 23:39:09 -08:00
+++ b/arch/ppc/kernel/entry.S	2005-03-01 23:39:09 -08:00
@@ -111,8 +111,10 @@
 	addi	r11,r1,STACK_FRAME_OVERHEAD
 	stw	r11,PT_REGS(r12)
 #if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
-	lwz	r12,PTRACE-THREAD(r12)
-	andi.	r12,r12,PT_PTRACED
+	/* Check to see if the dbcr0 register is set up to debug.  Use the
+	   single-step bit to do this. */
+	lwz	r12,THREAD_DBCR0(r12)
+	andis.	r12,r12,DBCR0_IC@h
 	beq+	3f
 	/* From user and task is ptraced - load up global dbcr0 */
 	li	r12,-1			/* clear all pending debug events */
@@ -242,9 +244,10 @@
 	bne-	syscall_exit_work
 syscall_exit_cont:
 #if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
-	/* If the process has its own DBCR0 value, load it up */
-	lwz	r0,PTRACE(r2)
-	andi.	r0,r0,PT_PTRACED
+	/* If the process has its own DBCR0 value, load it up.  The single
+	   step bit tells us that dbcr0 should be loaded. */
+	lwz	r0,THREAD+THREAD_DBCR0(r2)
+	andis.	r10,r0,DBCR0_IC@h
 	bnel-	load_dbcr0
 #endif
 	stwcx.	r0,0,r1			/* to clear the reservation */
@@ -599,9 +602,10 @@
 
 restore_user:
 #if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
-	/* Check whether this process has its own DBCR0 value */
-	lwz	r0,PTRACE(r2)
-	andi.	r0,r0,PT_PTRACED
+	/* Check whether this process has its own DBCR0 value.  The single
+	   step bit tells us that dbcr0 should be loaded. */
+	lwz	r0,THREAD+THREAD_DBCR0(r2)
+	andis.	r10,r0,DBCR0_IC@h
 	bnel-	load_dbcr0
 #endif
 
@@ -620,18 +624,8 @@
 	beq+	restore
 	andi.	r0,r3,MSR_EE	/* interrupts off? */
 	beq	restore		/* don't schedule if so */
-1:	lis	r0,PREEMPT_ACTIVE@h
-	stw	r0,TI_PREEMPT(r9)
-	ori	r10,r10,MSR_EE
-	SYNC
-	MTMSRD(r10)		/* hard-enable interrupts */
-	bl	schedule
-	LOAD_MSR_KERNEL(r10,MSR_KERNEL)
-	SYNC
-	MTMSRD(r10)		/* disable interrupts */
+1:	bl	preempt_schedule_irq
 	rlwinm	r9,r1,0,0,18
-	li	r0,0
-	stw	r0,TI_PREEMPT(r9)
 	lwz	r3,TI_FLAGS(r9)
 	andi.	r0,r3,_TIF_NEED_RESCHED
 	bne-	1b
@@ -876,17 +870,17 @@
 
 /*
  * Load the DBCR0 value for a task that is being ptraced,
- * having first saved away the global DBCR0.
+ * having first saved away the global DBCR0.  Note that r0
+ * has the dbcr0 value to set upon entry to this.
  */
 load_dbcr0:
-	mfmsr	r0		/* first disable debug exceptions */
-	rlwinm	r0,r0,0,~MSR_DE
-	mtmsr	r0
+	mfmsr	r10		/* first disable debug exceptions */
+	rlwinm	r10,r10,0,~MSR_DE
+	mtmsr	r10
 	isync
 	mfspr	r10,SPRN_DBCR0
 	lis	r11,global_dbcr0@ha
 	addi	r11,r11,global_dbcr0@l
-	lwz	r0,THREAD+THREAD_DBCR0(r2)
 	stw	r10,0(r11)
 	mtspr	SPRN_DBCR0,r0
 	lwz	r10,4(r11)
diff -Nru a/arch/ppc/kernel/head_44x.S b/arch/ppc/kernel/head_44x.S
--- a/arch/ppc/kernel/head_44x.S	2005-03-01 23:38:54 -08:00
+++ b/arch/ppc/kernel/head_44x.S	2005-03-01 23:38:54 -08:00
@@ -21,7 +21,7 @@
  * 	Author: MontaVista Software, Inc.
  *         	frank_rowand@mvista.com or source@mvista.com
  * 	   	debbie_chu@mvista.com
- *    Copyright 2002-2004 MontaVista Software, Inc.
+ *    Copyright 2002-2005 MontaVista Software, Inc.
  *      PowerPC 44x support, Matt Porter <mporter@kernel.crashing.org>
  *
  * This program is free software; you can redistribute  it and/or modify it
@@ -185,11 +185,11 @@
 	 * are used for polled operation.
 	 */
  	/* pageid fields */
-	lis	r3,0xe000	
+	lis	r3,UART0_IO_BASE@h
 	ori	r3,r3,PPC44x_TLB_VALID | PPC44x_TLB_256M
 
 	/* xlat fields */
-	lis	r4,0x4000		/* RPN is 0x40000000 */
+	lis	r4,UART0_PHYS_IO_BASE@h		/* RPN depends on SoC */
 	ori	r4,r4,0x0001		/* ERPN is 1 for second 4GB page */
 
 	/* attrib fields */
@@ -414,30 +414,16 @@
 	b	data_access
 
 	/* Instruction Storage Interrupt */
-	START_EXCEPTION(InstructionStorage)
-	NORMAL_EXCEPTION_PROLOG
-	mr      r4,r12                  /* Pass SRR0 as arg2 */
-	li      r5,0                    /* Pass zero as arg3 */
-	EXC_XFER_EE_LITE(0x0400, handle_page_fault)
+	INSTRUCTION_STORAGE_EXCEPTION
 
 	/* External Input Interrupt */
 	EXCEPTION(0x0500, ExternalInput, do_IRQ, EXC_XFER_LITE)
 
 	/* Alignment Interrupt */
-	START_EXCEPTION(Alignment)
-	NORMAL_EXCEPTION_PROLOG
-	mfspr   r4,SPRN_DEAR            /* Grab the DEAR and save it */
-	stw     r4,_DEAR(r11)
-	addi    r3,r1,STACK_FRAME_OVERHEAD
-	EXC_XFER_EE(0x0600, AlignmentException)
+	ALIGNMENT_EXCEPTION
 
 	/* Program Interrupt */
-	START_EXCEPTION(Program)
-	NORMAL_EXCEPTION_PROLOG
-	mfspr	r4,SPRN_ESR		/* Grab the ESR and save it */
-	stw	r4,_ESR(r11)
-	addi	r3,r1,STACK_FRAME_OVERHEAD
-	EXC_XFER_STD(0x700, ProgramCheckException)
+	PROGRAM_EXCEPTION
 
 	/* Floating Point Unavailable Interrupt */
 	EXCEPTION(0x2010, FloatingPointUnavailable, UnknownException, EXC_XFER_EE)
@@ -451,12 +437,7 @@
 	EXCEPTION(0x2020, AuxillaryProcessorUnavailable, UnknownException, EXC_XFER_EE)
 
 	/* Decrementer Interrupt */
-	START_EXCEPTION(Decrementer)
-	NORMAL_EXCEPTION_PROLOG
-	lis     r0,TSR_DIS@h            /* Setup the DEC interrupt mask */
-	mtspr   SPRN_TSR,r0		/* Clear the DEC interrupt */
-	addi    r3,r1,STACK_FRAME_OVERHEAD
-	EXC_XFER_LITE(0x1000, timer_interrupt)
+	DECREMENTER_EXCEPTION
 
 	/* Fixed Internal Timer Interrupt */
 	/* TODO: Add FIT support */
diff -Nru a/arch/ppc/kernel/head_8xx.S b/arch/ppc/kernel/head_8xx.S
--- a/arch/ppc/kernel/head_8xx.S	2005-03-01 23:38:57 -08:00
+++ b/arch/ppc/kernel/head_8xx.S	2005-03-01 23:38:57 -08:00
@@ -343,7 +343,7 @@
 	 * set.  All other Linux PTE bits control the behavior
 	 * of the MMU.
 	 */
-	li	r11, 0x00f0
+2:	li	r11, 0x00f0
 	rlwimi	r10, r11, 0, 24, 28	/* Set 24-27, clear 28 */
 	DO_8xx_CPU6(0x2d80, r3)
 	mtspr	MI_RPN, r10	/* Update TLB entry */
@@ -357,15 +357,6 @@
 #endif
 	rfi
 
-2:	mfspr	r10, M_TW	/* Restore registers */
-	lwz	r11, 0(r0)
-	mtcr	r11
-	lwz	r11, 4(r0)
-#ifdef CONFIG_8xx_CPU6
-	lwz	r3, 8(r0)
-#endif
-	b	InstructionAccess
-
 	. = 0x1200
 DataStoreTLBMiss:
 #ifdef CONFIG_8xx_CPU6
@@ -419,7 +410,7 @@
 	 * set.  All other Linux PTE bits control the behavior
 	 * of the MMU.
 	 */
-	li	r11, 0x00f0
+2:	li	r11, 0x00f0
 	rlwimi	r10, r11, 0, 24, 28	/* Set 24-27, clear 28 */
 	DO_8xx_CPU6(0x3d80, r3)
 	mtspr	MD_RPN, r10	/* Update TLB entry */
@@ -432,15 +423,6 @@
 	lwz	r3, 8(r0)
 #endif
 	rfi
-
-2:	mfspr	r10, M_TW	/* Restore registers */
-	lwz	r11, 0(r0)
-	mtcr	r11
-	lwz	r11, 4(r0)
-#ifdef CONFIG_8xx_CPU6
-	lwz	r3, 8(r0)
-#endif
-	b	DataAccess
 
 /* This is an instruction TLB error on the MPC8xx.  This could be due
  * to many reasons, such as executing guarded memory or illegal instruction
diff -Nru a/arch/ppc/kernel/head_booke.h b/arch/ppc/kernel/head_booke.h
--- a/arch/ppc/kernel/head_booke.h	2005-03-01 23:38:52 -08:00
+++ b/arch/ppc/kernel/head_booke.h	2005-03-01 23:38:52 -08:00
@@ -303,4 +303,37 @@
 	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)
 
+#define INSTRUCTION_STORAGE_EXCEPTION					      \
+	START_EXCEPTION(InstructionStorage)				      \
+	NORMAL_EXCEPTION_PROLOG;					      \
+	mfspr	r5,SPRN_ESR;		/* Grab the ESR and save it */	      \
+	stw	r5,_ESR(r11);						      \
+	mr      r4,r12;                 /* Pass SRR0 as arg2 */		      \
+	li      r5,0;                   /* Pass zero as arg3 */		      \
+	EXC_XFER_EE_LITE(0x0400, handle_page_fault)
+
+#define ALIGNMENT_EXCEPTION						      \
+	START_EXCEPTION(Alignment)					      \
+	NORMAL_EXCEPTION_PROLOG;					      \
+	mfspr   r4,SPRN_DEAR;           /* Grab the DEAR and save it */	      \
+	stw     r4,_DEAR(r11);						      \
+	addi    r3,r1,STACK_FRAME_OVERHEAD;				      \
+	EXC_XFER_EE(0x0600, AlignmentException)
+
+#define PROGRAM_EXCEPTION						      \
+	START_EXCEPTION(Program)					      \
+	NORMAL_EXCEPTION_PROLOG;					      \
+	mfspr	r4,SPRN_ESR;		/* Grab the ESR and save it */	      \
+	stw	r4,_ESR(r11);						      \
+	addi	r3,r1,STACK_FRAME_OVERHEAD;				      \
+	EXC_XFER_STD(0x0700, ProgramCheckException)
+
+#define DECREMENTER_EXCEPTION						      \
+	START_EXCEPTION(Decrementer)					      \
+	NORMAL_EXCEPTION_PROLOG;					      \
+	lis     r0,TSR_DIS@h;           /* Setup the DEC interrupt mask */    \
+	mtspr   SPRN_TSR,r0;		/* Clear the DEC interrupt */	      \
+	addi    r3,r1,STACK_FRAME_OVERHEAD;				      \
+	EXC_XFER_LITE(0x0900, timer_interrupt)
+
 #endif /* __HEAD_BOOKE_H__ */
diff -Nru a/arch/ppc/kernel/head_e500.S b/arch/ppc/kernel/head_e500.S
--- a/arch/ppc/kernel/head_e500.S	2005-03-01 23:39:08 -08:00
+++ b/arch/ppc/kernel/head_e500.S	2005-03-01 23:39:08 -08:00
@@ -119,7 +119,7 @@
 	tlbsx	0,r6				/* Fall through, we had to match */
 match_TLB:
 	mfspr	r7,SPRN_MAS0
-	rlwinm	r3,r7,16,28,31			/* Extract MAS0(Entry) */
+	rlwinm	r3,r7,16,20,31			/* Extract MAS0(Entry) */
 
 	mfspr	r7,SPRN_MAS1			/* Insure IPROT set */
 	oris	r7,r7,MAS1_IPROT@h
@@ -131,7 +131,7 @@
 	andi.	r9,r9,0xfff
 	li	r6,0				/* Set Entry counter to 0 */
 1:	lis	r7,0x1000			/* Set MAS0(TLBSEL) = 1 */
-	rlwimi	r7,r6,16,12,15			/* Setup MAS0 = TLBSEL | ESEL(r6) */
+	rlwimi	r7,r6,16,4,15			/* Setup MAS0 = TLBSEL | ESEL(r6) */
 	mtspr	SPRN_MAS0,r7
 	tlbre
 	mfspr	r7,SPRN_MAS1
@@ -163,13 +163,13 @@
 	andi.	r5, r3, 0x1	/* Find an entry not used and is non-zero */
 	addi	r5, r5, 0x1
 	lis	r7,0x1000	/* Set MAS0(TLBSEL) = 1 */
-	rlwimi	r7,r3,16,12,15	/* Setup MAS0 = TLBSEL | ESEL(r3) */
+	rlwimi	r7,r3,16,4,15	/* Setup MAS0 = TLBSEL | ESEL(r3) */
 	mtspr	SPRN_MAS0,r7
 	tlbre
 
 	/* Just modify the entry ID and EPN for the temp mapping */
 	lis	r7,0x1000	/* Set MAS0(TLBSEL) = 1 */
-	rlwimi	r7,r5,16,12,15	/* Setup MAS0 = TLBSEL | ESEL(r5) */
+	rlwimi	r7,r5,16,4,15	/* Setup MAS0 = TLBSEL | ESEL(r5) */
 	mtspr	SPRN_MAS0,r7
 	xori	r6,r4,1		/* Setup TMP mapping in the other Address space */
 	slwi	r6,r6,12
@@ -201,7 +201,7 @@
 
 /* 5. Invalidate mapping we started in */
 	lis	r7,0x1000	/* Set MAS0(TLBSEL) = 1 */
-	rlwimi	r7,r3,16,12,15	/* Setup MAS0 = TLBSEL | ESEL(r3) */
+	rlwimi	r7,r3,16,4,15	/* Setup MAS0 = TLBSEL | ESEL(r3) */
 	mtspr	SPRN_MAS0,r7
 	tlbre
 	li	r6,0
@@ -242,7 +242,7 @@
 
 /* 8. Clear out the temp mapping */
 	lis	r7,0x1000	/* Set MAS0(TLBSEL) = 1 */
-	rlwimi	r7,r5,16,12,15	/* Setup MAS0 = TLBSEL | ESEL(r5) */
+	rlwimi	r7,r5,16,4,15	/* Setup MAS0 = TLBSEL | ESEL(r5) */
 	mtspr	SPRN_MAS0,r7
 	tlbre
 	mtspr	SPRN_MAS1,r8
@@ -282,7 +282,7 @@
 	mtspr	SPRN_IVPR,r4
 
 	/* Setup the defaults for TLB entries */
-	li	r2,MAS4_TSIZED(BOOKE_PAGESZ_4K)
+	li	r2,(MAS4_TSIZED(BOOKE_PAGESZ_4K))@l
    	mtspr	SPRN_MAS4, r2
 
 #if 0
@@ -464,32 +464,16 @@
 	b	data_access
 
 	/* Instruction Storage Interrupt */
-	START_EXCEPTION(InstructionStorage)
-	NORMAL_EXCEPTION_PROLOG
-	mfspr	r5,SPRN_ESR		/* Grab the ESR and save it */
-	stw	r5,_ESR(r11)
-	mr      r4,r12                  /* Pass SRR0 as arg2 */
-	li      r5,0                    /* Pass zero as arg3 */
-	EXC_XFER_EE_LITE(0x0400, handle_page_fault)
+	INSTRUCTION_STORAGE_EXCEPTION
 
 	/* External Input Interrupt */
 	EXCEPTION(0x0500, ExternalInput, do_IRQ, EXC_XFER_LITE)
 
 	/* Alignment Interrupt */
-	START_EXCEPTION(Alignment)
-	NORMAL_EXCEPTION_PROLOG
-	mfspr   r4,SPRN_DEAR            /* Grab the DEAR and save it */
-	stw     r4,_DEAR(r11)
-	addi    r3,r1,STACK_FRAME_OVERHEAD
-	EXC_XFER_EE(0x0600, AlignmentException)
+	ALIGNMENT_EXCEPTION
 
 	/* Program Interrupt */
-	START_EXCEPTION(Program)
-	NORMAL_EXCEPTION_PROLOG
-	mfspr	r4,SPRN_ESR		/* Grab the ESR and save it */
-	stw	r4,_ESR(r11)
-	addi	r3,r1,STACK_FRAME_OVERHEAD
-	EXC_XFER_STD(0x0700, ProgramCheckException)
+	PROGRAM_EXCEPTION
 
 	/* Floating Point Unavailable Interrupt */
 	EXCEPTION(0x0800, FloatingPointUnavailable, UnknownException, EXC_XFER_EE)
@@ -503,12 +487,7 @@
 	EXCEPTION(0x2900, AuxillaryProcessorUnavailable, UnknownException, EXC_XFER_EE)
 
 	/* Decrementer Interrupt */
-	START_EXCEPTION(Decrementer)
-	NORMAL_EXCEPTION_PROLOG
-	lis     r0,TSR_DIS@h            /* Setup the DEC interrupt mask */
-	mtspr   SPRN_TSR,r0		/* Clear the DEC interrupt */
-	addi    r3,r1,STACK_FRAME_OVERHEAD
-	EXC_XFER_LITE(0x0900, timer_interrupt)
+	DECREMENTER_EXCEPTION
 
 	/* Fixed Internal Timer Interrupt */
 	/* TODO: Add FIT support */
@@ -539,8 +518,7 @@
 	ori	r11, r11, swapper_pg_dir@l
 
 	mfspr	r12,SPRN_MAS1		/* Set TID to 0 */
-	li	r13,MAS1_TID@l
-	andc	r12,r12,r13
+	rlwinm	r12,r12,0,16,1
 	mtspr	SPRN_MAS1,r12
 
 	b	4f
@@ -604,8 +582,7 @@
 	ori	r11, r11, swapper_pg_dir@l
 
 	mfspr	r12,SPRN_MAS1		/* Set TID to 0 */
-	li	r13,MAS1_TID@l
-	andc	r12,r12,r13
+	rlwinm	r12,r12,0,16,1
 	mtspr	SPRN_MAS1,r12
 
 	b	4f
@@ -666,7 +643,8 @@
 	EXCEPTION(0x2050, SPEFloatingPointRound, UnknownException, EXC_XFER_EE)
 
 	/* Performance Monitor */
-	EXCEPTION(0x2060, PerformanceMonitor, UnknownException, EXC_XFER_EE)
+	EXCEPTION(0x2060, PerformanceMonitor, PerformanceMonitorException, EXC_XFER_STD)
+
 
 	/* Debug Interrupt */
 	DEBUG_EXCEPTION
diff -Nru a/arch/ppc/kernel/idle.c b/arch/ppc/kernel/idle.c
--- a/arch/ppc/kernel/idle.c	2005-03-01 23:38:51 -08:00
+++ b/arch/ppc/kernel/idle.c	2005-03-01 23:38:51 -08:00
@@ -57,14 +57,13 @@
 /*
  * The body of the idle task.
  */
-int cpu_idle(void)
+void cpu_idle(void)
 {
 	for (;;)
 		if (ppc_md.idle != NULL)
 			ppc_md.idle();
 		else
 			default_idle();
-	return 0;
 }
 
 #if defined(CONFIG_SYSCTL) && defined(CONFIG_6xx)
diff -Nru a/arch/ppc/kernel/l2cr.S b/arch/ppc/kernel/l2cr.S
--- a/arch/ppc/kernel/l2cr.S	2005-03-01 23:38:58 -08:00
+++ b/arch/ppc/kernel/l2cr.S	2005-03-01 23:38:58 -08:00
@@ -45,6 +45,7 @@
 #include <asm/cputable.h>
 #include <asm/ppc_asm.h>
 #include <asm/cache.h>
+#include <asm/page.h>
 
 /* Usage:
 
@@ -284,7 +285,7 @@
 	/* Tweak some bits */
 	rlwinm	r5,r3,0,0,0		/* r5 contains the new enable bit */
 	rlwinm	r3,r3,0,22,20		/* Turn off the invalidate bit */
-	rlwinm	r3,r3,0,1,31		/* Turn off the enable bit */
+	rlwinm	r3,r3,0,2,31		/* Turn off the enable & PE bits */
 	rlwinm	r3,r3,0,5,3		/* Turn off the clken bit */
 	/* Check to see if we need to flush */
 	rlwinm.	r4,r4,0,0,0
@@ -379,7 +380,7 @@
 /* flush_disable_L1()	- Flush and disable L1 cache
  *
  * clobbers r0, r3, ctr, cr0
- *
+ * Must be called with interrupts disabled and MMU enabled.
  */
 _GLOBAL(__flush_disable_L1)
 	/* Stop pending alitvec streams and memory accesses */
@@ -393,7 +394,7 @@
 	 */
 	li	r3,0x4000	/* 512kB / 32B */
 	mtctr	r3
-	li	r3, 0
+	lis	r3,KERNELBASE@h
 1:
 	lwz	r0,0(r3)
 	addi	r3,r3,0x0020	/* Go to start of next cache line */
@@ -404,7 +405,7 @@
 	/* Now flush those cache lines */
 	li	r3,0x4000	/* 512kB / 32B */
 	mtctr	r3
-	li	r3, 0
+	lis	r3,KERNELBASE@h
 1:
 	dcbf	0,r3
 	addi	r3,r3,0x0020	/* Go to start of next cache line */
diff -Nru a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S
--- a/arch/ppc/kernel/misc.S	2005-03-01 23:39:16 -08:00
+++ b/arch/ppc/kernel/misc.S	2005-03-01 23:39:16 -08:00
@@ -1434,7 +1434,7 @@
 	.long sys_fstatfs64
 	.long ppc_fadvise64_64
 	.long sys_ni_syscall		/* 255 - rtas (used on ppc64) */
-	.long sys_ni_syscall		/* 256 reserved for sys_debug_setcontext */
+	.long sys_debug_setcontext
 	.long sys_ni_syscall		/* 257 reserved for vserver */
 	.long sys_ni_syscall		/* 258 reserved for new sys_remap_file_pages */
 	.long sys_ni_syscall		/* 259 reserved for new sys_mbind */
diff -Nru a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c
--- a/arch/ppc/kernel/pci.c	2005-03-01 23:38:57 -08:00
+++ b/arch/ppc/kernel/pci.c	2005-03-01 23:38:57 -08:00
@@ -1712,7 +1712,11 @@
 	if (flags & IORESOURCE_IO)
 		return ioport_map(start, len);
 	if (flags & IORESOURCE_MEM)
-		return (void __iomem *) start;
+		/* Not checking IORESOURCE_CACHEABLE because PPC does
+		 * not currently distinguish between ioremap and
+		 * ioremap_nocache.
+		 */
+		return ioremap(start, len);
 	/* What? */
 	return NULL;
 }
diff -Nru a/arch/ppc/kernel/perfmon.c b/arch/ppc/kernel/perfmon.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/ppc/kernel/perfmon.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,93 @@
+/* kernel/perfmon.c
+ * PPC 32 Performance Monitor Infrastructure
+ *
+ * Author: Andy Fleming
+ * Copyright (c) 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.
+ */
+
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/stddef.h>
+#include <linux/unistd.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/user.h>
+#include <linux/a.out.h>
+#include <linux/interrupt.h>
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/prctl.h>
+
+#include <asm/pgtable.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/reg.h>
+#include <asm/xmon.h>
+
+/* A lock to regulate grabbing the interrupt */
+DEFINE_SPINLOCK(perfmon_lock);
+
+#ifdef CONFIG_FSL_BOOKE
+static void dummy_perf(struct pt_regs *regs)
+{
+	unsigned int pmgc0 = mfpmr(PMRN_PMGC0);
+
+	pmgc0 &= ~PMGC0_PMIE;
+	mtpmr(PMRN_PMGC0, pmgc0);
+}
+
+#else
+/* Ensure exceptions are disabled */
+
+static void dummy_perf(struct pt_regs *regs)
+{
+	unsigned int mmcr0 = mfspr(SPRN_MMCR0);
+
+	mmcr0 &= ~MMCR0_PMXE;
+	mtspr(SPRN_MMCR0, mmcr0);
+}
+#endif
+
+void (*perf_irq)(struct pt_regs *) = dummy_perf;
+
+/* Grab the interrupt, if it's free.
+ * Returns 0 on success, -1 if the interrupt is taken already */
+int request_perfmon_irq(void (*handler)(struct pt_regs *))
+{
+	int err = 0;
+
+	spin_lock(&perfmon_lock);
+
+	if (perf_irq == dummy_perf)
+		perf_irq = handler;
+	else {
+		pr_info("perfmon irq already handled by %p\n", perf_irq);
+		err = -1;
+	}
+
+	spin_unlock(&perfmon_lock);
+
+	return err;
+}
+
+void free_perfmon_irq(void)
+{
+	spin_lock(&perfmon_lock);
+
+	perf_irq = dummy_perf;
+
+	spin_unlock(&perfmon_lock);
+}
+
+EXPORT_SYMBOL(perf_irq);
+EXPORT_SYMBOL(request_perfmon_irq);
+EXPORT_SYMBOL(free_perfmon_irq);
diff -Nru a/arch/ppc/kernel/perfmon_fsl_booke.c b/arch/ppc/kernel/perfmon_fsl_booke.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/ppc/kernel/perfmon_fsl_booke.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,222 @@
+/* kernel/perfmon_fsl_booke.c
+ * Freescale Book-E Performance Monitor code
+ *
+ * Author: Andy Fleming
+ * Copyright (c) 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.
+ */
+
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/stddef.h>
+#include <linux/unistd.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/user.h>
+#include <linux/a.out.h>
+#include <linux/interrupt.h>
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/prctl.h>
+
+#include <asm/pgtable.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/reg.h>
+#include <asm/xmon.h>
+#include <asm/perfmon.h>
+
+static inline u32 get_pmlca(int ctr);
+static inline void set_pmlca(int ctr, u32 pmlca);
+
+static inline u32 get_pmlca(int ctr)
+{
+	u32 pmlca;
+
+	switch (ctr) {
+		case 0:
+			pmlca = mfpmr(PMRN_PMLCA0);
+			break;
+		case 1:
+			pmlca = mfpmr(PMRN_PMLCA1);
+			break;
+		case 2:
+			pmlca = mfpmr(PMRN_PMLCA2);
+			break;
+		case 3:
+			pmlca = mfpmr(PMRN_PMLCA3);
+			break;
+		default:
+			panic("Bad ctr number\n");
+	}
+
+	return pmlca;
+}
+
+static inline void set_pmlca(int ctr, u32 pmlca)
+{
+	switch (ctr) {
+		case 0:
+			mtpmr(PMRN_PMLCA0, pmlca);
+			break;
+		case 1:
+			mtpmr(PMRN_PMLCA1, pmlca);
+			break;
+		case 2:
+			mtpmr(PMRN_PMLCA2, pmlca);
+			break;
+		case 3:
+			mtpmr(PMRN_PMLCA3, pmlca);
+			break;
+		default:
+			panic("Bad ctr number\n");
+	}
+}
+
+void init_pmc_stop(int ctr)
+{
+	u32 pmlca = (PMLCA_FC | PMLCA_FCS | PMLCA_FCU |
+			PMLCA_FCM1 | PMLCA_FCM0);
+	u32 pmlcb = 0;
+
+	switch (ctr) {
+		case 0:
+			mtpmr(PMRN_PMLCA0, pmlca);
+			mtpmr(PMRN_PMLCB0, pmlcb);
+			break;
+		case 1:
+			mtpmr(PMRN_PMLCA1, pmlca);
+			mtpmr(PMRN_PMLCB1, pmlcb);
+			break;
+		case 2:
+			mtpmr(PMRN_PMLCA2, pmlca);
+			mtpmr(PMRN_PMLCB2, pmlcb);
+			break;
+		case 3:
+			mtpmr(PMRN_PMLCA3, pmlca);
+			mtpmr(PMRN_PMLCB3, pmlcb);
+			break;
+		default:
+			panic("Bad ctr number!\n");
+	}
+}
+
+void set_pmc_event(int ctr, int event)
+{
+	u32 pmlca;
+
+	pmlca = get_pmlca(ctr);
+
+	pmlca = (pmlca & ~PMLCA_EVENT_MASK) |
+		((event << PMLCA_EVENT_SHIFT) &
+		 PMLCA_EVENT_MASK);
+
+	set_pmlca(ctr, pmlca);
+}
+
+void set_pmc_user_kernel(int ctr, int user, int kernel)
+{
+	u32 pmlca;
+
+	pmlca = get_pmlca(ctr);
+
+	if(user)
+		pmlca &= ~PMLCA_FCU;
+	else
+		pmlca |= PMLCA_FCU;
+
+	if(kernel)
+		pmlca &= ~PMLCA_FCS;
+	else
+		pmlca |= PMLCA_FCS;
+
+	set_pmlca(ctr, pmlca);
+}
+
+void set_pmc_marked(int ctr, int mark0, int mark1)
+{
+	u32 pmlca = get_pmlca(ctr);
+
+	if(mark0)
+		pmlca &= ~PMLCA_FCM0;
+	else
+		pmlca |= PMLCA_FCM0;
+
+	if(mark1)
+		pmlca &= ~PMLCA_FCM1;
+	else
+		pmlca |= PMLCA_FCM1;
+
+	set_pmlca(ctr, pmlca);
+}
+
+void pmc_start_ctr(int ctr, int enable)
+{
+	u32 pmlca = get_pmlca(ctr);
+
+	pmlca &= ~PMLCA_FC;
+
+	if (enable)
+		pmlca |= PMLCA_CE;
+	else
+		pmlca &= ~PMLCA_CE;
+
+	set_pmlca(ctr, pmlca);
+}
+
+void pmc_start_ctrs(int enable)
+{
+	u32 pmgc0 = mfpmr(PMRN_PMGC0);
+
+	pmgc0 &= ~PMGC0_FAC;
+	pmgc0 |= PMGC0_FCECE;
+
+	if (enable)
+		pmgc0 |= PMGC0_PMIE;
+	else
+		pmgc0 &= ~PMGC0_PMIE;
+
+	mtpmr(PMRN_PMGC0, pmgc0);
+}
+
+void pmc_stop_ctrs(void)
+{
+	u32 pmgc0 = mfpmr(PMRN_PMGC0);
+
+	pmgc0 |= PMGC0_FAC;
+
+	pmgc0 &= ~(PMGC0_PMIE | PMGC0_FCECE);
+
+	mtpmr(PMRN_PMGC0, pmgc0);
+}
+
+void dump_pmcs(void)
+{
+	printk("pmgc0: %x\n", mfpmr(PMRN_PMGC0));
+	printk("pmc\t\tpmlca\t\tpmlcb\n");
+	printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC0),
+			mfpmr(PMRN_PMLCA0), mfpmr(PMRN_PMLCB0));
+	printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC1),
+			mfpmr(PMRN_PMLCA1), mfpmr(PMRN_PMLCB1));
+	printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC2),
+			mfpmr(PMRN_PMLCA2), mfpmr(PMRN_PMLCB2));
+	printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC3),
+			mfpmr(PMRN_PMLCA3), mfpmr(PMRN_PMLCB3));
+}
+
+EXPORT_SYMBOL(init_pmc_stop);
+EXPORT_SYMBOL(set_pmc_event);
+EXPORT_SYMBOL(set_pmc_user_kernel);
+EXPORT_SYMBOL(set_pmc_marked);
+EXPORT_SYMBOL(pmc_start_ctr);
+EXPORT_SYMBOL(pmc_start_ctrs);
+EXPORT_SYMBOL(pmc_stop_ctrs);
+EXPORT_SYMBOL(dump_pmcs);
diff -Nru a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c
--- a/arch/ppc/kernel/ppc_ksyms.c	2005-03-01 23:39:16 -08:00
+++ b/arch/ppc/kernel/ppc_ksyms.c	2005-03-01 23:39:16 -08:00
@@ -190,6 +190,7 @@
 EXPORT_SYMBOL(flush_dcache_page);
 EXPORT_SYMBOL(flush_tlb_kernel_range);
 EXPORT_SYMBOL(flush_tlb_page);
+EXPORT_SYMBOL(_tlbie);
 #ifdef CONFIG_ALTIVEC
 EXPORT_SYMBOL(last_task_used_altivec);
 EXPORT_SYMBOL(giveup_altivec);
diff -Nru a/arch/ppc/kernel/process.c b/arch/ppc/kernel/process.c
--- a/arch/ppc/kernel/process.c	2005-03-01 23:38:57 -08:00
+++ b/arch/ppc/kernel/process.c	2005-03-01 23:38:57 -08:00
@@ -325,17 +325,6 @@
 	       current, current->pid, current->comm, current->thread_info);
 	printk("Last syscall: %ld ", current->thread.last_syscall);
 
-#if defined(CONFIG_4xx) && defined(DCRN_PLB0_BEAR)
-	printk("\nPLB0: bear= 0x%8.8x acr=   0x%8.8x besr=  0x%8.8x\n",
-	    mfdcr(DCRN_PLB0_BEAR), mfdcr(DCRN_PLB0_ACR),
-	    mfdcr(DCRN_PLB0_BESR));
-#endif
-#if defined(CONFIG_4xx) && defined(DCRN_POB0_BEAR)
-	printk("PLB0 to OPB: bear= 0x%8.8x besr0= 0x%8.8x besr1= 0x%8.8x\n",
-	    mfdcr(DCRN_POB0_BEAR), mfdcr(DCRN_POB0_BESR0),
-	    mfdcr(DCRN_POB0_BESR1));
-#endif
-
 #ifdef CONFIG_SMP
 	printk(" CPU: %d", smp_processor_id());
 #endif /* CONFIG_SMP */
diff -Nru a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c
--- a/arch/ppc/kernel/setup.c	2005-03-01 23:39:16 -08:00
+++ b/arch/ppc/kernel/setup.c	2005-03-01 23:39:16 -08:00
@@ -7,6 +7,7 @@
 #include <linux/string.h>
 #include <linux/sched.h>
 #include <linux/init.h>
+#include <linux/kernel.h>
 #include <linux/reboot.h>
 #include <linux/delay.h>
 #include <linux/initrd.h>
@@ -681,7 +682,6 @@
 /* Warning, IO base is not yet inited */
 void __init setup_arch(char **cmdline_p)
 {
-	extern int panic_timeout;
 	extern char *klimit;
 	extern void do_init_bootmem(void);
 
diff -Nru a/arch/ppc/kernel/signal.c b/arch/ppc/kernel/signal.c
--- a/arch/ppc/kernel/signal.c	2005-03-01 23:39:17 -08:00
+++ b/arch/ppc/kernel/signal.c	2005-03-01 23:39:17 -08:00
@@ -509,6 +509,96 @@
 	return 0;
 }
 
+int sys_debug_setcontext(struct ucontext __user *ctx,
+			 int ndbg, struct sig_dbg_op *dbg,
+			 int r6, int r7, int r8,
+			 struct pt_regs *regs)
+{
+	struct sig_dbg_op op;
+	int i;
+	unsigned long new_msr = regs->msr;
+#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
+	unsigned long new_dbcr0 = current->thread.dbcr0;
+#endif
+
+	for (i=0; i<ndbg; i++) {
+		if (__copy_from_user(&op, dbg, sizeof(op)))
+			return -EFAULT;
+		switch (op.dbg_type) {
+		case SIG_DBG_SINGLE_STEPPING:
+#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
+			if (op.dbg_value) {
+				new_msr |= MSR_DE;
+				new_dbcr0 |= (DBCR0_IDM | DBCR0_IC);
+			} else {
+				new_msr &= ~MSR_DE;
+				new_dbcr0 &= ~(DBCR0_IDM | DBCR0_IC);
+			}
+#else
+			if (op.dbg_value)
+				new_msr |= MSR_SE;
+			else
+				new_msr &= ~MSR_SE;
+#endif
+			break;
+		case SIG_DBG_BRANCH_TRACING:
+#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
+			return -EINVAL;
+#else
+			if (op.dbg_value)
+				new_msr |= MSR_BE;
+			else
+				new_msr &= ~MSR_BE;
+#endif
+			break;
+
+		default:
+			return -EINVAL;
+		}
+	}
+
+	/* We wait until here to actually install the values in the
+	   registers so if we fail in the above loop, it will not
+	   affect the contents of these registers.  After this point,
+	   failure is a problem, anyway, and it's very unlikely unless
+	   the user is really doing something wrong. */
+	regs->msr = new_msr;
+#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
+	current->thread.dbcr0 = new_dbcr0;
+#endif
+
+	/*
+	 * If we get a fault copying the context into the kernel's
+	 * image of the user's registers, we can't just return -EFAULT
+	 * because the user's registers will be corrupted.  For instance
+	 * the NIP value may have been updated but not some of the
+	 * other registers.  Given that we have done the verify_area
+	 * and successfully read the first and last bytes of the region
+	 * above, this should only happen in an out-of-memory situation
+	 * or if another thread unmaps the region containing the context.
+	 * We kill the task with a SIGSEGV in this situation.
+	 */
+	if (do_setcontext(ctx, regs, 1)) {
+		force_sig(SIGSEGV, current);
+		goto out;
+	}
+
+	/*
+	 * It's not clear whether or why it is desirable to save the
+	 * sigaltstack setting on signal delivery and restore it on
+	 * signal return.  But other architectures do this and we have
+	 * always done it up until now so it is probably better not to
+	 * change it.  -- paulus
+	 */
+	do_sigaltstack(&ctx->uc_stack, NULL, regs->gpr[1]);
+
+	sigreturn_exit(regs);
+	/* doesn't actually return back to here */
+
+ out:
+	return 0;
+}
+
 /*
  * OK, we're invoking a handler
  */
diff -Nru a/arch/ppc/kernel/smp.c b/arch/ppc/kernel/smp.c
--- a/arch/ppc/kernel/smp.c	2005-03-01 23:39:16 -08:00
+++ b/arch/ppc/kernel/smp.c	2005-03-01 23:39:16 -08:00
@@ -42,8 +42,6 @@
 struct klock_info_struct klock_info = { KLOCK_CLEAR, 0 };
 atomic_t ipi_recv;
 atomic_t ipi_sent;
-DEFINE_PER_CPU(unsigned int, prof_multiplier);
-DEFINE_PER_CPU(unsigned int, prof_counter);
 unsigned long cache_decay_ticks = HZ/100;
 cpumask_t cpu_online_map;
 cpumask_t cpu_possible_map;
@@ -60,7 +58,6 @@
 volatile unsigned long cpu_callin_map[NR_CPUS];
 
 int start_secondary(void *);
-extern int cpu_idle(void *unused);
 void smp_call_function_interrupt(void);
 static int __smp_call_function(void (*func) (void *info), void *info,
 			       int wait, int target);
@@ -89,16 +86,6 @@
 /*
  * Common functions
  */
-void smp_local_timer_interrupt(struct pt_regs * regs)
-{
-	int cpu = smp_processor_id();
-
-	if (!--per_cpu(prof_counter, cpu)) {
-		update_process_times(user_mode(regs));
-		per_cpu(prof_counter, cpu) = per_cpu(prof_multiplier, cpu);
-	}
-}
-
 void smp_message_recv(int msg, struct pt_regs *regs)
 {
 	atomic_inc(&ipi_recv);
@@ -176,7 +163,7 @@
  * static memory requirements. It also looks cleaner.
  * Stolen from the i386 version.
  */
-static spinlock_t call_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(call_lock);
 
 static struct call_data_struct {
 	void (*func) (void *info);
@@ -297,8 +284,6 @@
 	/* assume bogomips are same for everything */
         c->loops_per_jiffy = loops_per_jiffy;
         c->pvr = mfspr(PVR);
-	per_cpu(prof_counter, id) = 1;
-	per_cpu(prof_multiplier, id) = 1;
 }
 
 void __init smp_prepare_cpus(unsigned int max_cpus)
@@ -358,7 +343,8 @@
 	smp_ops->take_timebase();
 	printk("CPU %i done timebase take...\n", cpu);
 
-	return cpu_idle(NULL);
+	cpu_idle();
+	return 0;
 }
 
 int __cpu_up(unsigned int cpu)
diff -Nru a/arch/ppc/kernel/time.c b/arch/ppc/kernel/time.c
--- a/arch/ppc/kernel/time.c	2005-03-01 23:39:08 -08:00
+++ b/arch/ppc/kernel/time.c	2005-03-01 23:39:08 -08:00
@@ -91,7 +91,7 @@
 
 static long time_offset;
 
-spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(rtc_lock);
 
 EXPORT_SYMBOL(rtc_lock);
 
@@ -142,6 +142,7 @@
 		jiffy_stamp += tb_ticks_per_jiffy;
 		
 		profile_tick(CPU_PROFILING, regs);
+		update_process_times(user_mode(regs));
 
 	  	if (smp_processor_id())
 			continue;
@@ -150,9 +151,6 @@
 		write_seqlock(&xtime_lock);
 		tb_last_stamp = jiffy_stamp;
 		do_timer(regs);
-#ifndef CONFIG_SMP
-		update_process_times(user_mode(regs));
-#endif
 
 		/*
 		 * update the rtc when needed, this should be performed on the
@@ -185,10 +183,6 @@
 	if ( !disarm_decr[smp_processor_id()] )
 		set_dec(next_dec);
 	last_jiffy_stamp(cpu) = jiffy_stamp;
-
-#ifdef CONFIG_SMP
-	smp_local_timer_interrupt(regs);
-#endif /* CONFIG_SMP */
 
 	if (ppc_md.heartbeat && !ppc_md.heartbeat_count--)
 		ppc_md.heartbeat();
diff -Nru a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c
--- a/arch/ppc/kernel/traps.c	2005-03-01 23:38:53 -08:00
+++ b/arch/ppc/kernel/traps.c	2005-03-01 23:38:53 -08:00
@@ -41,6 +41,7 @@
 #ifdef CONFIG_PMAC_BACKLIGHT
 #include <asm/backlight.h>
 #endif
+#include <asm/perfmon.h>
 
 #ifdef CONFIG_XMON
 void (*debugger)(struct pt_regs *regs) = xmon;
@@ -71,8 +72,7 @@
  * Trap & Exception support
  */
 
-
-spinlock_t die_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(die_lock);
 
 void die(const char * str, struct pt_regs * fp, long err)
 {
@@ -199,6 +199,15 @@
 #define clear_single_step(regs)	((regs)->msr &= ~MSR_SE)
 #endif
 
+/*
+ * This is "fall-back" implementation for configurations
+ * which don't provide platform-specific machine check info
+ */
+void __attribute__ ((weak))
+platform_machine_check(struct pt_regs *regs)
+{
+}
+
 void MachineCheckException(struct pt_regs *regs)
 {
 	unsigned long reason = get_mc_reason(regs);
@@ -323,6 +332,12 @@
 	}
 #endif /* CONFIG_4xx */
 
+	/*
+	 * Optional platform-provided routine to print out
+	 * additional info, e.g. bus error registers.
+	 */
+	platform_machine_check(regs);
+
 	debugger(regs);
 	die("machine check", regs, SIGBUS);
 }
@@ -566,7 +581,7 @@
 
 void SingleStepException(struct pt_regs *regs)
 {
-	regs->msr &= ~MSR_SE;  /* Turn off 'trace' bit */
+	regs->msr &= ~(MSR_SE | MSR_BE);  /* Turn off 'trace' bits */
 	if (debugger_sstep(regs))
 		return;
 	_exception(SIGTRAP, regs, TRAP_TRACE, 0);
@@ -725,6 +740,11 @@
 	}
 }
 #endif /* CONFIG_ALTIVEC */
+
+void PerformanceMonitorException(struct pt_regs *regs)
+{
+	perf_irq(regs);
+}
 
 #ifdef CONFIG_FSL_BOOKE
 void CacheLockingException(struct pt_regs *regs, unsigned long address,
diff -Nru a/arch/ppc/lib/locks.c b/arch/ppc/lib/locks.c
--- a/arch/ppc/lib/locks.c	2005-03-01 23:38:53 -08:00
+++ b/arch/ppc/lib/locks.c	2005-03-01 23:38:53 -08:00
@@ -91,44 +91,57 @@
 }
 EXPORT_SYMBOL(_raw_spin_unlock);
 
-
 /*
- * Just like x86, implement read-write locks as a 32-bit counter
- * with the high bit (sign) being the "write" bit.
- * -- Cort
+ * For rwlocks, zero is unlocked, -1 is write-locked,
+ * positive is read-locked.
  */
+static __inline__ int __read_trylock(rwlock_t *rw)
+{
+	signed int tmp;
+
+	__asm__ __volatile__(
+"2:	lwarx	%0,0,%1		# __read_trylock\n\
+	addic.	%0,%0,1\n\
+	ble-	1f\n"
+	PPC405_ERR77(0,%1)
+"	stwcx.	%0,0,%1\n\
+	bne-	2b\n\
+	isync\n\
+1:"
+	: "=&r"(tmp)
+	: "r"(&rw->lock)
+	: "cr0", "memory");
+
+	return tmp;
+}
+
+int _raw_read_trylock(rwlock_t *rw)
+{
+	return __read_trylock(rw) > 0;
+}
+EXPORT_SYMBOL(_raw_read_trylock);
+
 void _raw_read_lock(rwlock_t *rw)
 {
-	unsigned long stuck = INIT_STUCK;
-	int cpu = smp_processor_id();
+	unsigned int stuck;
 
-again:
-	/* get our read lock in there */
-	atomic_inc((atomic_t *) &(rw)->lock);
-	if ( (signed long)((rw)->lock) < 0) /* someone has a write lock */
-	{
-		/* turn off our read lock */
-		atomic_dec((atomic_t *) &(rw)->lock);
-		/* wait for the write lock to go away */
-		while ((signed long)((rw)->lock) < 0)
-		{
-			if(!--stuck)
-			{
-				printk("_read_lock(%p) CPU#%d\n", rw, cpu);
+	while (__read_trylock(rw) <= 0) {
+		stuck = INIT_STUCK;
+		while (!read_can_lock(rw)) {
+			if (--stuck == 0) {
+				printk("_read_lock(%p) CPU#%d lock %d\n",
+				       rw, _smp_processor_id(), rw->lock);
 				stuck = INIT_STUCK;
 			}
 		}
-		/* try to get the read lock again */
-		goto again;
 	}
-	wmb();
 }
 EXPORT_SYMBOL(_raw_read_lock);
 
 void _raw_read_unlock(rwlock_t *rw)
 {
 	if ( rw->lock == 0 )
-		printk("_read_unlock(): %s/%d (nip %08lX) lock %lx\n",
+		printk("_read_unlock(): %s/%d (nip %08lX) lock %d\n",
 		       current->comm,current->pid,current->thread.regs->nip,
 		      rw->lock);
 	wmb();
@@ -138,40 +151,17 @@
 
 void _raw_write_lock(rwlock_t *rw)
 {
-	unsigned long stuck = INIT_STUCK;
-	int cpu = smp_processor_id();
+	unsigned int stuck;
 
-again:
-	if ( test_and_set_bit(31,&(rw)->lock) ) /* someone has a write lock */
-	{
-		while ( (rw)->lock & (1<<31) ) /* wait for write lock */
-		{
-			if(!--stuck)
-			{
-				printk("write_lock(%p) CPU#%d lock %lx)\n",
-				       rw, cpu,rw->lock);
+	while (cmpxchg(&rw->lock, 0, -1) != 0) {
+		stuck = INIT_STUCK;
+		while (!write_can_lock(rw)) {
+			if (--stuck == 0) {
+				printk("write_lock(%p) CPU#%d lock %d)\n",
+				       rw, _smp_processor_id(), rw->lock);
 				stuck = INIT_STUCK;
 			}
-			barrier();
 		}
-		goto again;
-	}
-
-	if ( (rw)->lock & ~(1<<31)) /* someone has a read lock */
-	{
-		/* clear our write lock and wait for reads to go away */
-		clear_bit(31,&(rw)->lock);
-		while ( (rw)->lock & ~(1<<31) )
-		{
-			if(!--stuck)
-			{
-				printk("write_lock(%p) 2 CPU#%d lock %lx)\n",
-				       rw, cpu,rw->lock);
-				stuck = INIT_STUCK;
-			}
-			barrier();
-		}
-		goto again;
 	}
 	wmb();
 }
@@ -179,14 +169,8 @@
 
 int _raw_write_trylock(rwlock_t *rw)
 {
-	if (test_and_set_bit(31, &(rw)->lock)) /* someone has a write lock */
-		return 0;
-
-	if ((rw)->lock & ~(1<<31)) {	/* someone has a read lock */
-		/* clear our write lock and wait for reads to go away */
-		clear_bit(31,&(rw)->lock);
+	if (cmpxchg(&rw->lock, 0, -1) != 0)
 		return 0;
-	}
 	wmb();
 	return 1;
 }
@@ -194,12 +178,12 @@
 
 void _raw_write_unlock(rwlock_t *rw)
 {
-	if ( !(rw->lock & (1<<31)) )
-		printk("_write_lock(): %s/%d (nip %08lX) lock %lx\n",
+	if (rw->lock >= 0)
+		printk("_write_lock(): %s/%d (nip %08lX) lock %d\n",
 		      current->comm,current->pid,current->thread.regs->nip,
 		      rw->lock);
 	wmb();
-	clear_bit(31,&(rw)->lock);
+	rw->lock = 0;
 }
 EXPORT_SYMBOL(_raw_write_unlock);
 
diff -Nru a/arch/ppc/lib/string.S b/arch/ppc/lib/string.S
--- a/arch/ppc/lib/string.S	2005-03-01 23:38:59 -08:00
+++ b/arch/ppc/lib/string.S	2005-03-01 23:38:59 -08:00
@@ -216,12 +216,6 @@
 	bdnz	8b
 	blr
 
-_GLOBAL(bcopy)
-	mr	r6,r3
-	mr	r3,r4
-	mr	r4,r6
-	b	memcpy
-
 /*
  * This version uses dcbz on the complete cache lines in the
  * destination area to reduce memory traffic.  This requires that
diff -Nru a/arch/ppc/mm/fsl_booke_mmu.c b/arch/ppc/mm/fsl_booke_mmu.c
--- a/arch/ppc/mm/fsl_booke_mmu.c	2005-03-01 23:39:18 -08:00
+++ b/arch/ppc/mm/fsl_booke_mmu.c	2005-03-01 23:39:18 -08:00
@@ -124,8 +124,8 @@
 		flags |= _PAGE_COHERENT;
 #endif
 
-	TLBCAM[index].MAS0 = MAS0_TLBSEL | (index << 16);
-	TLBCAM[index].MAS1 = MAS1_VALID | MAS1_IPROT | MAS1_TSIZE(tsize) | ((pid << 16) & MAS1_TID);
+	TLBCAM[index].MAS0 = MAS0_TLBSEL(1) | MAS0_ESEL(index);
+	TLBCAM[index].MAS1 = MAS1_VALID | MAS1_IPROT | MAS1_TSIZE(tsize) | MAS1_TID(pid);
 	TLBCAM[index].MAS2 = virt & PAGE_MASK;
 
 	TLBCAM[index].MAS2 |= (flags & _PAGE_WRITETHRU) ? MAS2_W : 0;
@@ -156,7 +156,7 @@
 
 void invalidate_tlbcam_entry(int index)
 {
-	TLBCAM[index].MAS0 = MAS0_TLBSEL | (index << 16);
+	TLBCAM[index].MAS0 = MAS0_TLBSEL(1) | MAS0_ESEL(index);
 	TLBCAM[index].MAS1 = ~MAS1_VALID;
 
 	loadcam_entry(index);
diff -Nru a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c
--- a/arch/ppc/mm/init.c	2005-03-01 23:38:53 -08:00
+++ b/arch/ppc/mm/init.c	2005-03-01 23:38:53 -08:00
@@ -31,6 +31,7 @@
 #include <linux/bootmem.h>
 #include <linux/highmem.h>
 #include <linux/initrd.h>
+#include <linux/pagemap.h>
 
 #include <asm/pgalloc.h>
 #include <asm/prom.h>
@@ -411,7 +412,6 @@
 	unsigned long highmem_mapnr;
 
 	highmem_mapnr = total_lowmem >> PAGE_SHIFT;
-	highmem_start_page = mem_map + highmem_mapnr;
 #endif /* CONFIG_HIGHMEM */
 	max_mapnr = total_memory >> PAGE_SHIFT;
 
diff -Nru a/arch/ppc/mm/pgtable.c b/arch/ppc/mm/pgtable.c
--- a/arch/ppc/mm/pgtable.c	2005-03-01 23:38:53 -08:00
+++ b/arch/ppc/mm/pgtable.c	2005-03-01 23:38:53 -08:00
@@ -85,8 +85,7 @@
 {
 	pgd_t *ret;
 
-	if ((ret = (pgd_t *)__get_free_pages(GFP_KERNEL, PGDIR_ORDER)) != NULL)
-		clear_pages(ret, PGDIR_ORDER);
+	ret = (pgd_t *)__get_free_pages(GFP_KERNEL|__GFP_ZERO, PGDIR_ORDER);
 	return ret;
 }
 
@@ -102,16 +101,17 @@
 	extern void *early_get_page(void);
 
 	if (mem_init_done) {
-		pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT);
+		pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO);
 		if (pte) {
 			struct page *ptepage = virt_to_page(pte);
 			ptepage->mapping = (void *) mm;
 			ptepage->index = address & PMD_MASK;
 		}
-	} else
+	} else {
 		pte = (pte_t *)early_get_page();
-	if (pte)
-		clear_page(pte);
+		if (pte)
+			clear_page(pte);
+	}
 	return pte;
 }
 
diff -Nru a/arch/ppc/mm/tlb.c b/arch/ppc/mm/tlb.c
--- a/arch/ppc/mm/tlb.c	2005-03-01 23:39:07 -08:00
+++ b/arch/ppc/mm/tlb.c	2005-03-01 23:39:07 -08:00
@@ -62,7 +62,7 @@
 	ptepage = virt_to_page(ptep);
 	mm = (struct mm_struct *) ptepage->mapping;
 	ptephys = __pa(ptep) & PAGE_MASK;
-	addr = ptepage->index + (((unsigned long)ptep & ~PAGE_MASK) << 9);
+	addr = ptepage->index + (((unsigned long)ptep & ~PAGE_MASK) << 10);
 	flush_hash_pages(mm->context, addr, ptephys, 1);
 }
 
diff -Nru a/arch/ppc/oprofile/Makefile b/arch/ppc/oprofile/Makefile
--- a/arch/ppc/oprofile/Makefile	2005-03-01 23:39:16 -08:00
+++ b/arch/ppc/oprofile/Makefile	2005-03-01 23:39:16 -08:00
@@ -6,4 +6,9 @@
 		oprofilefs.o oprofile_stats.o \
 		timer_int.o )
 
-oprofile-y := $(DRIVER_OBJS) init.o
+oprofile-y := $(DRIVER_OBJS) common.o
+
+ifeq ($(CONFIG_FSL_BOOKE),y)
+	oprofile-y += op_model_fsl_booke.o
+endif
+
diff -Nru a/arch/ppc/oprofile/common.c b/arch/ppc/oprofile/common.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/ppc/oprofile/common.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,161 @@
+/*
+ * PPC 32 oprofile support
+ * Based on PPC64 oprofile support
+ * Copyright (C) 2004 Anton Blanchard <anton@au.ibm.com>, IBM
+ *
+ * Copyright (C) Freescale Semiconductor, Inc 2004
+ *
+ * Author: Andy Fleming
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the 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/oprofile.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <linux/errno.h>
+#include <asm/ptrace.h>
+#include <asm/system.h>
+#include <asm/perfmon.h>
+#include <asm/cputable.h>
+
+#include "op_impl.h"
+
+static struct op_ppc32_model *model;
+
+static struct op_counter_config ctr[OP_MAX_COUNTER];
+static struct op_system_config sys;
+
+static void op_handle_interrupt(struct pt_regs *regs)
+{
+	model->handle_interrupt(regs, ctr);
+}
+
+static int op_ppc32_setup(void)
+{
+	/* Install our interrupt handler into the existing hook.  */
+	if(request_perfmon_irq(&op_handle_interrupt))
+		return -EBUSY;
+
+	mb();
+
+	/* Pre-compute the values to stuff in the hardware registers.  */
+	model->reg_setup(ctr, &sys, model->num_counters);
+
+#if 0
+	/* FIXME: Make multi-cpu work */
+	/* Configure the registers on all cpus.  */
+	on_each_cpu(model->reg_setup, NULL, 0, 1);
+#endif
+
+	return 0;
+}
+
+static void op_ppc32_shutdown(void)
+{
+	mb();
+
+	/* Remove our interrupt handler. We may be removing this module. */
+	free_perfmon_irq();
+}
+
+static void op_ppc32_cpu_start(void *dummy)
+{
+	model->start(ctr);
+}
+
+static int op_ppc32_start(void)
+{
+	on_each_cpu(op_ppc32_cpu_start, NULL, 0, 1);
+	return 0;
+}
+
+static inline void op_ppc32_cpu_stop(void *dummy)
+{
+	model->stop();
+}
+
+static void op_ppc32_stop(void)
+{
+	on_each_cpu(op_ppc32_cpu_stop, NULL, 0, 1);
+}
+
+static int op_ppc32_create_files(struct super_block *sb, struct dentry *root)
+{
+	int i;
+
+	for (i = 0; i < model->num_counters; ++i) {
+		struct dentry *dir;
+		char buf[3];
+
+		snprintf(buf, sizeof buf, "%d", i);
+		dir = oprofilefs_mkdir(sb, root, buf);
+
+		oprofilefs_create_ulong(sb, dir, "enabled", &ctr[i].enabled);
+		oprofilefs_create_ulong(sb, dir, "event", &ctr[i].event);
+		oprofilefs_create_ulong(sb, dir, "count", &ctr[i].count);
+		oprofilefs_create_ulong(sb, dir, "kernel", &ctr[i].kernel);
+		oprofilefs_create_ulong(sb, dir, "user", &ctr[i].user);
+
+		/* FIXME: Not sure if this is used */
+		oprofilefs_create_ulong(sb, dir, "unit_mask", &ctr[i].unit_mask);
+	}
+
+	oprofilefs_create_ulong(sb, root, "enable_kernel", &sys.enable_kernel);
+	oprofilefs_create_ulong(sb, root, "enable_user", &sys.enable_user);
+
+	/* Default to tracing both kernel and user */
+	sys.enable_kernel = 1;
+	sys.enable_user = 1;
+
+	return 0;
+}
+
+static struct oprofile_operations oprof_ppc32_ops = {
+	.create_files	= op_ppc32_create_files,
+	.setup		= op_ppc32_setup,
+	.shutdown	= op_ppc32_shutdown,
+	.start		= op_ppc32_start,
+	.stop		= op_ppc32_stop,
+	.cpu_type	= NULL		/* To be filled in below. */
+};
+
+int __init oprofile_arch_init(struct oprofile_operations *ops)
+{
+	char *name;
+	int cpu_id = smp_processor_id();
+
+#ifdef CONFIG_FSL_BOOKE
+	model = &op_model_fsl_booke;
+#else
+	return -ENODEV;
+#endif
+
+	name = kmalloc(32, GFP_KERNEL);
+
+	if (NULL == name)
+		return -ENOMEM;
+
+	sprintf(name, "ppc/%s", cur_cpu_spec[cpu_id]->cpu_name);
+
+	oprof_ppc32_ops.cpu_type = name;
+
+	model->num_counters = cur_cpu_spec[cpu_id]->num_pmcs;
+
+	*ops = oprof_ppc32_ops;
+
+	printk(KERN_INFO "oprofile: using %s performance monitoring.\n",
+	       oprof_ppc32_ops.cpu_type);
+
+	return 0;
+}
+
+void oprofile_arch_exit(void)
+{
+	kfree(oprof_ppc32_ops.cpu_type);
+	oprof_ppc32_ops.cpu_type = NULL;
+}
diff -Nru a/arch/ppc/oprofile/init.c b/arch/ppc/oprofile/init.c
--- a/arch/ppc/oprofile/init.c	2005-03-01 23:38:51 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,23 +0,0 @@
-/**
- * @file init.c
- *
- * @remark Copyright 2002 OProfile authors
- * @remark Read the file COPYING
- *
- * @author John Levon <levon@movementarian.org>
- */
-
-#include <linux/kernel.h>
-#include <linux/oprofile.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-
-int __init oprofile_arch_init(struct oprofile_operations ** ops)
-{
-	return -ENODEV;
-}
-
-
-void oprofile_arch_exit(void)
-{
-}
diff -Nru a/arch/ppc/oprofile/op_impl.h b/arch/ppc/oprofile/op_impl.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/ppc/oprofile/op_impl.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2004 Anton Blanchard <anton@au.ibm.com>, IBM
+ *
+ * Based on alpha 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.
+ */
+
+#ifndef OP_IMPL_H
+#define OP_IMPL_H 1
+
+#define OP_MAX_COUNTER 8
+
+/* Per-counter configuration as set via oprofilefs.  */
+struct op_counter_config {
+	unsigned long enabled;
+	unsigned long event;
+	unsigned long count;
+	unsigned long kernel;
+	unsigned long user;
+	unsigned long unit_mask;
+};
+
+/* System-wide configuration as set via oprofilefs.  */
+struct op_system_config {
+	unsigned long enable_kernel;
+	unsigned long enable_user;
+};
+
+/* Per-arch configuration */
+struct op_ppc32_model {
+	void (*reg_setup) (struct op_counter_config *,
+			   struct op_system_config *,
+			   int num_counters);
+	void (*start) (struct op_counter_config *);
+	void (*stop) (void);
+	void (*handle_interrupt) (struct pt_regs *,
+				  struct op_counter_config *);
+	int num_counters;
+};
+
+#endif /* OP_IMPL_H */
diff -Nru a/arch/ppc/oprofile/op_model_fsl_booke.c b/arch/ppc/oprofile/op_model_fsl_booke.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/ppc/oprofile/op_model_fsl_booke.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,185 @@
+/*
+ * oprofile/op_model_e500.c
+ *
+ * Freescale Book-E oprofile support, based on ppc64 oprofile support
+ * Copyright (C) 2004 Anton Blanchard <anton@au.ibm.com>, IBM
+ *
+ * Copyright (c) 2004 Freescale Semiconductor, Inc
+ *
+ * Author: Andy Fleming
+ * Maintainer: Kumar Gala <Kumar.Gala@freescale.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/oprofile.h>
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <asm/ptrace.h>
+#include <asm/system.h>
+#include <asm/processor.h>
+#include <asm/cputable.h>
+#include <asm/reg_booke.h>
+#include <asm/page.h>
+#include <asm/perfmon.h>
+
+#include "op_impl.h"
+
+static unsigned long reset_value[OP_MAX_COUNTER];
+
+static int num_counters;
+static int oprofile_running;
+
+static inline unsigned int ctr_read(unsigned int i)
+{
+	switch(i) {
+		case 0:
+			return mfpmr(PMRN_PMC0);
+		case 1:
+			return mfpmr(PMRN_PMC1);
+		case 2:
+			return mfpmr(PMRN_PMC2);
+		case 3:
+			return mfpmr(PMRN_PMC3);
+		default:
+			return 0;
+	}
+}
+
+static inline void ctr_write(unsigned int i, unsigned int val)
+{
+	switch(i) {
+		case 0:
+			mtpmr(PMRN_PMC0, val);
+			break;
+		case 1:
+			mtpmr(PMRN_PMC1, val);
+			break;
+		case 2:
+			mtpmr(PMRN_PMC2, val);
+			break;
+		case 3:
+			mtpmr(PMRN_PMC3, val);
+			break;
+		default:
+			break;
+	}
+}
+
+
+static void fsl_booke_reg_setup(struct op_counter_config *ctr,
+			     struct op_system_config *sys,
+			     int num_ctrs)
+{
+	int i;
+
+	num_counters = num_ctrs;
+
+	/* freeze all counters */
+	pmc_stop_ctrs();
+
+	/* Our counters count up, and "count" refers to
+	 * how much before the next interrupt, and we interrupt
+	 * on overflow.  So we calculate the starting value
+	 * which will give us "count" until overflow.
+	 * Then we set the events on the enabled counters */
+	for (i = 0; i < num_counters; ++i) {
+		reset_value[i] = 0x80000000UL - ctr[i].count;
+
+		init_pmc_stop(i);
+
+		set_pmc_event(i, ctr[i].event);
+
+		set_pmc_user_kernel(i, ctr[i].user, ctr[i].kernel);
+	}
+}
+
+static void fsl_booke_start(struct op_counter_config *ctr)
+{
+	int i;
+
+	mtmsr(mfmsr() | MSR_PMM);
+
+	for (i = 0; i < num_counters; ++i) {
+		if (ctr[i].enabled) {
+			ctr_write(i, reset_value[i]);
+			/* Set Each enabled counterd to only
+			 * count when the Mark bit is not set */
+			set_pmc_marked(i, 1, 0);
+			pmc_start_ctr(i, 1);
+		} else {
+			ctr_write(i, 0);
+
+			/* Set the ctr to be stopped */
+			pmc_start_ctr(i, 0);
+		}
+	}
+
+	/* Clear the freeze bit, and enable the interrupt.
+	 * The counters won't actually start until the rfi clears
+	 * the PMM bit */
+	pmc_start_ctrs(1);
+
+	oprofile_running = 1;
+
+	pr_debug("start on cpu %d, pmgc0 %x\n", smp_processor_id(),
+			mfpmr(PMRN_PMGC0));
+}
+
+static void fsl_booke_stop(void)
+{
+	/* freeze counters */
+	pmc_stop_ctrs();
+
+	oprofile_running = 0;
+
+	pr_debug("stop on cpu %d, pmgc0 %x\n", smp_processor_id(),
+			mfpmr(PMRN_PMGC0));
+
+	mb();
+}
+
+
+static void fsl_booke_handle_interrupt(struct pt_regs *regs,
+				    struct op_counter_config *ctr)
+{
+	unsigned long pc;
+	int is_kernel;
+	int val;
+	int i;
+	unsigned int cpu = smp_processor_id();
+
+	/* set the PMM bit (see comment below) */
+	mtmsr(mfmsr() | MSR_PMM);
+
+	pc = regs->nip;
+	is_kernel = (pc >= KERNELBASE);
+
+	for (i = 0; i < num_counters; ++i) {
+		val = ctr_read(i);
+		if (val < 0) {
+			if (oprofile_running && ctr[i].enabled) {
+				oprofile_add_sample(pc, is_kernel, i, cpu);
+				ctr_write(i, reset_value[i]);
+			} else {
+				ctr_write(i, 0);
+			}
+		}
+	}
+
+	/* The freeze bit was set by the interrupt. */
+	/* Clear the freeze bit, and reenable the interrupt.
+	 * The counters won't actually start until the rfi clears
+	 * the PMM bit */
+	pmc_start_ctrs(1);
+}
+
+struct op_ppc32_model op_model_fsl_booke = {
+	.reg_setup		= fsl_booke_reg_setup,
+	.start			= fsl_booke_start,
+	.stop			= fsl_booke_stop,
+	.handle_interrupt	= fsl_booke_handle_interrupt,
+};
diff -Nru a/arch/ppc/platforms/4xx/Kconfig b/arch/ppc/platforms/4xx/Kconfig
--- a/arch/ppc/platforms/4xx/Kconfig	2005-03-01 23:38:52 -08:00
+++ b/arch/ppc/platforms/4xx/Kconfig	2005-03-01 23:38:52 -08:00
@@ -73,6 +73,11 @@
 	help
 	  This option enables support for the IBM PPC440GP evaluation board.
 
+config LUAN
+	bool "Luan"
+	help
+	  This option enables support for the IBM PPC440SP evaluation board.
+
 config OCOTEA
 	bool "Ocotea"
 	help
@@ -103,9 +108,14 @@
 	depends on OCOTEA
 	default y
 
+config 440SP
+	bool
+	depends on LUAN
+	default y
+
 config 440
 	bool
-	depends on 440GP
+	depends on 440GP || 440SP
 	default y
 
 config 440A
@@ -132,7 +142,7 @@
 
 config IBM_OCP
 	bool
-	depends on ASH || BUBINGA || CPCI405 || EBONY || EP405 || OCOTEA || REDWOOD_5 || REDWOOD_6 || SYCAMORE || WALNUT
+	depends on ASH || BUBINGA || CPCI405 || EBONY || EP405 || LUAN || OCOTEA || REDWOOD_5 || REDWOOD_6 || SYCAMORE || WALNUT
 	default y
 
 config XILINX_OCP
@@ -142,7 +152,7 @@
 
 config IBM_EMAC4
 	bool
-	depends on 440GX
+	depends on 440GX || 440SP
 	default y
 
 config BIOS_FIXUP
diff -Nru a/arch/ppc/platforms/4xx/Makefile b/arch/ppc/platforms/4xx/Makefile
--- a/arch/ppc/platforms/4xx/Makefile	2005-03-01 23:39:10 -08:00
+++ b/arch/ppc/platforms/4xx/Makefile	2005-03-01 23:39:10 -08:00
@@ -6,6 +6,7 @@
 obj-$(CONFIG_EBONY)		+= ebony.o
 obj-$(CONFIG_EP405)		+= ep405.o
 obj-$(CONFIG_BUBINGA)		+= bubinga.o
+obj-$(CONFIG_LUAN)		+= luan.o
 obj-$(CONFIG_OAK)		+= oak.o
 obj-$(CONFIG_OCOTEA)		+= ocotea.o
 obj-$(CONFIG_REDWOOD_5)		+= redwood5.o
@@ -20,6 +21,7 @@
 obj-$(CONFIG_REDWOOD_6)		+= ibmstbx25.o
 obj-$(CONFIG_440GP)		+= ibm440gp.o
 obj-$(CONFIG_440GX)		+= ibm440gx.o
+obj-$(CONFIG_440SP)		+= ibm440sp.o
 obj-$(CONFIG_405EP)		+= ibm405ep.o
 obj-$(CONFIG_405GPR)		+= ibm405gpr.o
 obj-$(CONFIG_VIRTEX_II_PRO)	+= virtex-ii_pro.o
diff -Nru a/arch/ppc/platforms/4xx/ebony.c b/arch/ppc/platforms/4xx/ebony.c
--- a/arch/ppc/platforms/4xx/ebony.c	2005-03-01 23:39:17 -08:00
+++ b/arch/ppc/platforms/4xx/ebony.c	2005-03-01 23:39:17 -08:00
@@ -4,7 +4,7 @@
  * Ebony board specific routines
  *
  * Matt Porter <mporter@kernel.crashing.org>
- * Copyright 2002-2004 MontaVista Software Inc.
+ * Copyright 2002-2005 MontaVista Software Inc.
  *
  * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
  * Copyright (c) 2003, 2004 Zultys Technologies
@@ -55,73 +55,22 @@
 static struct ibm44x_clocks clocks __initdata;
 
 /*
- * Ebony IRQ triggering/polarity settings
+ * Ebony external IRQ triggering/polarity settings
  */
-static u_char ebony_IRQ_initsenses[] __initdata = {
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 0: UART 0 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 1: UART 1 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 2: IIC 0 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 3: IIC 1 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 4: PCI Inb Mess */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 5: PCI Cmd Wrt */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 6: PCI PM */
-	(IRQ_SENSE_EDGE  | IRQ_POLARITY_POSITIVE),	/* 7: PCI MSI 0 */
-	(IRQ_SENSE_EDGE  | IRQ_POLARITY_POSITIVE),	/* 8: PCI MSI 1 */
-	(IRQ_SENSE_EDGE  | IRQ_POLARITY_POSITIVE),	/* 9: PCI MSI 2 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 10: MAL TX EOB */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 11: MAL RX EOB */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 12: DMA Chan 0 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 13: DMA Chan 1 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 14: DMA Chan 2 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 15: DMA Chan 3 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 16: Reserved */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 17: Reserved */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 18: GPT Timer 0 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 19: GPT Timer 1 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 20: GPT Timer 2 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 21: GPT Timer 3 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 22: GPT Timer 4 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* 23: Ext Int 0 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* 24: Ext Int 1 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* 25: Ext Int 2 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* 26: Ext Int 3 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 27: Ext Int 4 */
-	(IRQ_SENSE_EDGE  | IRQ_POLARITY_NEGATIVE),	/* 28: Ext Int 5 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* 29: Ext Int 6 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 30: UIC1 NC Int */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 31: UIC1 Crit Int */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 32: MAL SERR */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 33: MAL TXDE */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 34: MAL RXDE */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 35: ECC Unc Err */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 36: ECC Corr Err */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 37: Ext Bus Ctrl */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 38: Ext Bus Mstr */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 39: OPB->PLB */
-	(IRQ_SENSE_EDGE  | IRQ_POLARITY_POSITIVE),	/* 40: PCI MSI 3 */
-	(IRQ_SENSE_EDGE  | IRQ_POLARITY_POSITIVE),	/* 41: PCI MSI 4 */
-	(IRQ_SENSE_EDGE  | IRQ_POLARITY_POSITIVE),	/* 42: PCI MSI 5 */
-	(IRQ_SENSE_EDGE  | IRQ_POLARITY_POSITIVE),	/* 43: PCI MSI 6 */
-	(IRQ_SENSE_EDGE  | IRQ_POLARITY_POSITIVE),	/* 44: PCI MSI 7 */
-	(IRQ_SENSE_EDGE  | IRQ_POLARITY_POSITIVE),	/* 45: PCI MSI 8 */
-	(IRQ_SENSE_EDGE  | IRQ_POLARITY_POSITIVE),	/* 46: PCI MSI 9 */
-	(IRQ_SENSE_EDGE  | IRQ_POLARITY_POSITIVE),	/* 47: PCI MSI 10 */
-	(IRQ_SENSE_EDGE  | IRQ_POLARITY_POSITIVE),	/* 48: PCI MSI 11 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 49: PLB Perf Mon */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 50: Ext Int 7 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* 51: Ext Int 8 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* 52: Ext Int 9 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* 53: Ext Int 10 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* 54: Ext Int 11 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* 55: Ext Int 12 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 56: Ser ROM Err */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 57: Reserved */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 58: Reserved */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 59: PCI Async Err */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 60: EMAC 0 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 61: EMAC 0 WOL */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 62: EMAC 1 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 63: EMAC 1 WOL */
+unsigned char ppc4xx_uic_ext_irq_cfg[] __initdata = {
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* IRQ0: PCI slot 0 */
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* IRQ1: PCI slot 1 */
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* IRQ2: PCI slot 2 */
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* IRQ3: PCI slot 3 */
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* IRQ4: IRDA */
+	(IRQ_SENSE_EDGE  | IRQ_POLARITY_NEGATIVE),	/* IRQ5: SMI pushbutton */
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* IRQ6: PHYs */
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* IRQ7: AUX */
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* IRQ8: EXT */
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* IRQ9: EXT */
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* IRQ10: EXT */
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* IRQ11: EXT */
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* IRQ12: EXT */
 };
 
 static void __init
@@ -179,7 +128,7 @@
 }
 
 #define PCIX_WRITEL(value, offset) \
-	(writel(value, (u32)pcix_reg_base+offset))
+	(writel(value, pcix_reg_base + offset))
 
 /*
  * FIXME: This is only here to "make it work".  This will move
@@ -191,7 +140,7 @@
 {
 	void *pcix_reg_base;
 
-	pcix_reg_base = ioremap64(PCIX0_REG_BASE, PCIX0_REG_SIZE);
+	pcix_reg_base = ioremap64(PCIX0_REG_BASE, PCIX_REG_SIZE);
 
 	/* Disable all windows */
 	PCIX_WRITEL(0, PCIX0_POM0SA);
@@ -357,9 +306,6 @@
 #endif
 
 	ebony_early_serial_map();
-
-	ibm4xxPIC_InitSenses = ebony_IRQ_initsenses;
-	ibm4xxPIC_NumInitSenses = sizeof(ebony_IRQ_initsenses);
 
 	/* Identify the system */
 	printk("IBM Ebony port (MontaVista Software, Inc. (source@mvista.com))\n");
diff -Nru a/arch/ppc/platforms/4xx/ibm405ep.c b/arch/ppc/platforms/4xx/ibm405ep.c
--- a/arch/ppc/platforms/4xx/ibm405ep.c	2005-03-01 23:38:56 -08:00
+++ b/arch/ppc/platforms/4xx/ibm405ep.c	2005-03-01 23:38:56 -08:00
@@ -21,6 +21,7 @@
 
 #include <asm/ibm4xx.h>
 #include <asm/ocp.h>
+#include <asm/ppc4xx_pic.h>
 
 #include <platforms/4xx/ibm405ep.h>
 
@@ -130,5 +131,13 @@
 	  .show		= &ocp_show_emac_data
 	},
 	{ .vendor	= OCP_VENDOR_INVALID
+	}
+};
+
+/* Polarity and triggering settings for internal interrupt sources */
+struct ppc4xx_uic_settings ppc4xx_core_uic_cfg[] __initdata = {
+	{ .polarity 	= 0xffff7f80,
+	  .triggering	= 0x00000000,
+	  .ext_irq_mask	= 0x0000007f,	/* IRQ0 - IRQ6 */
 	}
 };
diff -Nru a/arch/ppc/platforms/4xx/ibm405gp.c b/arch/ppc/platforms/4xx/ibm405gp.c
--- a/arch/ppc/platforms/4xx/ibm405gp.c	2005-03-01 23:38:58 -08:00
+++ b/arch/ppc/platforms/4xx/ibm405gp.c	2005-03-01 23:38:58 -08:00
@@ -22,6 +22,7 @@
 #include <platforms/4xx/ibm405gp.h>
 #include <asm/ibm4xx.h>
 #include <asm/ocp.h>
+#include <asm/ppc4xx_pic.h>
 
 static struct ocp_func_emac_data ibm405gp_emac0_def = {
 	.rgmii_idx	= -1,		/* No RGMII */
@@ -107,5 +108,13 @@
 	  .show		= &ocp_show_emac_data,
 	},
 	{ .vendor	= OCP_VENDOR_INVALID
+	}
+};
+
+/* Polarity and triggering settings for internal interrupt sources */
+struct ppc4xx_uic_settings ppc4xx_core_uic_cfg[] __initdata = {
+	{ .polarity 	= 0xffffff80,
+	  .triggering	= 0x10000000,
+	  .ext_irq_mask	= 0x0000007f,	/* IRQ0 - IRQ6 */
 	}
 };
diff -Nru a/arch/ppc/platforms/4xx/ibm405gpr.c b/arch/ppc/platforms/4xx/ibm405gpr.c
--- a/arch/ppc/platforms/4xx/ibm405gpr.c	2005-03-01 23:39:07 -08:00
+++ b/arch/ppc/platforms/4xx/ibm405gpr.c	2005-03-01 23:39:07 -08:00
@@ -18,6 +18,7 @@
 #include <platforms/4xx/ibm405gpr.h>
 #include <asm/ibm4xx.h>
 #include <asm/ocp.h>
+#include <asm/ppc4xx_pic.h>
 
 static struct ocp_func_emac_data ibm405gpr_emac0_def = {
 	.rgmii_idx	= -1,		/* No RGMII */
@@ -104,5 +105,13 @@
 	  .show		= &ocp_show_emac_data,
 	},
 	{ .vendor	= OCP_VENDOR_INVALID
+	}
+};
+
+/* Polarity and triggering settings for internal interrupt sources */
+struct ppc4xx_uic_settings ppc4xx_core_uic_cfg[] __initdata = {
+	{ .polarity 	= 0xffffe000,
+	  .triggering	= 0x10000000,
+	  .ext_irq_mask	= 0x00001fff,	/* IRQ7 - IRQ12, IRQ0 - IRQ6 */
 	}
 };
diff -Nru a/arch/ppc/platforms/4xx/ibm440gp.c b/arch/ppc/platforms/4xx/ibm440gp.c
--- a/arch/ppc/platforms/4xx/ibm440gp.c	2005-03-01 23:39:07 -08:00
+++ b/arch/ppc/platforms/4xx/ibm440gp.c	2005-03-01 23:39:07 -08:00
@@ -19,6 +19,7 @@
 #include <linux/module.h>
 #include <platforms/4xx/ibm440gp.h>
 #include <asm/ocp.h>
+#include <asm/ppc4xx_pic.h>
 
 static struct ocp_func_emac_data ibm440gp_emac0_def = {
 	.rgmii_idx	= -1,           /* No RGMII */
@@ -148,4 +149,16 @@
 	},
 	{ .vendor	= OCP_VENDOR_INVALID
 	}
+};
+
+/* Polarity and triggering settings for internal interrupt sources */
+struct ppc4xx_uic_settings ppc4xx_core_uic_cfg[] __initdata = {
+	{ .polarity 	= 0xfffffe03,
+	  .triggering	= 0x01c00000,
+	  .ext_irq_mask	= 0x000001fc,	/* IRQ0 - IRQ6 */
+	},
+	{ .polarity 	= 0xffffc0ff,
+	  .triggering	= 0x00ff8000,
+	  .ext_irq_mask	= 0x00003f00,	/* IRQ7 - IRQ12 */
+	},
 };
diff -Nru a/arch/ppc/platforms/4xx/ibm440gx.c b/arch/ppc/platforms/4xx/ibm440gx.c
--- a/arch/ppc/platforms/4xx/ibm440gx.c	2005-03-01 23:39:06 -08:00
+++ b/arch/ppc/platforms/4xx/ibm440gx.c	2005-03-01 23:39:06 -08:00
@@ -19,6 +19,7 @@
 #include <linux/module.h>
 #include <platforms/4xx/ibm440gx.h>
 #include <asm/ocp.h>
+#include <asm/ppc4xx_pic.h>
 
 static struct ocp_func_emac_data ibm440gx_emac0_def = {
 	.rgmii_idx	= -1,		/* No RGMII */
@@ -214,4 +215,20 @@
 	},
 	{ .vendor	= OCP_VENDOR_INVALID
 	}
+};
+
+/* Polarity and triggering settings for internal interrupt sources */
+struct ppc4xx_uic_settings ppc4xx_core_uic_cfg[] __initdata = {
+	{ .polarity 	= 0xfffffe03,
+	  .triggering	= 0x01c00000,
+	  .ext_irq_mask	= 0x000001fc,	/* IRQ0 - IRQ6 */
+	},
+	{ .polarity 	= 0xffffc0ff,
+	  .triggering	= 0x00ff8000,
+	  .ext_irq_mask	= 0x00003f00,	/* IRQ7 - IRQ12 */
+	},
+	{ .polarity 	= 0xffff83ff,
+	  .triggering	= 0x000f83c0,
+	  .ext_irq_mask	= 0x00007c00,	/* IRQ13 - IRQ17 */
+	},
 };
diff -Nru a/arch/ppc/platforms/4xx/ibm440sp.c b/arch/ppc/platforms/4xx/ibm440sp.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/ppc/platforms/4xx/ibm440sp.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,131 @@
+/*
+ * arch/ppc/platforms/4xx/ibm440sp.c
+ *
+ * PPC440SP I/O descriptions
+ *
+ * Matt Porter <mporter@kernel.crashing.org>
+ * Copyright 2002-2005 MontaVista Software Inc.
+ *
+ * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
+ * Copyright (c) 2003, 2004 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
+ * 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/ibm440sp.h>
+#include <asm/ocp.h>
+
+static struct ocp_func_emac_data ibm440sp_emac0_def = {
+	.rgmii_idx	= -1,		/* No RGMII */
+	.rgmii_mux	= -1,		/* No RGMII */
+	.zmii_idx       = -1,           /* No ZMII */
+	.zmii_mux       = -1,           /* No ZMII */
+	.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 */
+	.jumbo		= 1,		/* Jumbo frames supported */
+};
+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 */
+	.txeob_irq	= 38,		/* TX End Of Buffer IRQ  */
+	.rxeob_irq	= 39,		/* RX End Of Buffer IRQ  */
+	.txde_irq	= 34,		/* TX Descriptor Error IRQ */
+	.rxde_irq	= 35,		/* RX Descriptor Error IRQ */
+	.serr_irq	= 33,		/* MAL System Error IRQ    */
+};
+OCP_SYSFS_MAL_DATA()
+
+static struct ocp_func_iic_data ibm440sp_iic0_def = {
+	.fast_mode	= 0,		/* Use standad mode (100Khz) */
+};
+
+static struct ocp_func_iic_data ibm440sp_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	= 0x0000000140000000ULL,
+	  .irq		= OCP_IRQ_NA,
+	  .pm		= OCP_CPM_NA,
+	},
+	{ .vendor	= OCP_VENDOR_IBM,
+	  .function	= OCP_FUNC_16550,
+	  .index	= 0,
+	  .paddr	= PPC440SP_UART0_ADDR,
+	  .irq		= UART0_INT,
+	  .pm		= IBM_CPM_UART0,
+	},
+	{ .vendor	= OCP_VENDOR_IBM,
+	  .function	= OCP_FUNC_16550,
+	  .index	= 1,
+	  .paddr	= PPC440SP_UART1_ADDR,
+	  .irq		= UART1_INT,
+	  .pm		= IBM_CPM_UART1,
+	},
+	{ .vendor	= OCP_VENDOR_IBM,
+	  .function	= OCP_FUNC_16550,
+	  .index	= 2,
+	  .paddr	= PPC440SP_UART2_ADDR,
+	  .irq		= UART2_INT,
+	  .pm		= IBM_CPM_UART2,
+	},
+	{ .vendor	= OCP_VENDOR_IBM,
+	  .function	= OCP_FUNC_IIC,
+	  .index	= 0,
+	  .paddr	= 0x00000001f0000400ULL,
+	  .irq		= 2,
+	  .pm		= IBM_CPM_IIC0,
+	  .additions	= &ibm440sp_iic0_def,
+	  .show		= &ocp_show_iic_data
+	},
+	{ .vendor	= OCP_VENDOR_IBM,
+	  .function	= OCP_FUNC_IIC,
+	  .index	= 1,
+	  .paddr	= 0x00000001f0000500ULL,
+	  .irq		= 3,
+	  .pm		= IBM_CPM_IIC1,
+	  .additions	= &ibm440sp_iic1_def,
+	  .show		= &ocp_show_iic_data
+	},
+	{ .vendor	= OCP_VENDOR_IBM,
+	  .function	= OCP_FUNC_GPIO,
+	  .index	= 0,
+	  .paddr	= 0x00000001f0000700ULL,
+	  .irq		= OCP_IRQ_NA,
+	  .pm		= IBM_CPM_GPIO0,
+	},
+	{ .vendor	= OCP_VENDOR_IBM,
+	  .function	= OCP_FUNC_MAL,
+	  .paddr	= OCP_PADDR_NA,
+	  .irq		= OCP_IRQ_NA,
+	  .pm		= OCP_CPM_NA,
+	  .additions	= &ibm440sp_mal0_def,
+	  .show		= &ocp_show_mal_data,
+	},
+	{ .vendor	= OCP_VENDOR_IBM,
+	  .function	= OCP_FUNC_EMAC,
+	  .index	= 0,
+	  .paddr	= 0x00000001f0000800ULL,
+	  .irq		= 60,
+	  .pm		= OCP_CPM_NA,
+	  .additions	= &ibm440sp_emac0_def,
+	  .show		= &ocp_show_emac_data,
+	},
+	{ .vendor	= OCP_VENDOR_INVALID
+	}
+};
diff -Nru a/arch/ppc/platforms/4xx/ibm440sp.h b/arch/ppc/platforms/4xx/ibm440sp.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/ppc/platforms/4xx/ibm440sp.h	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,64 @@
+/*
+ * arch/ppc/platforms/4xx/ibm440sp.h
+ *
+ * PPC440SP definitions
+ *
+ * Matt Porter <mporter@kernel.crashing.org>
+ *
+ * Copyright 2004-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 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_IBM440SP_H
+#define __PPC_PLATFORMS_IBM440SP_H
+
+#include <linux/config.h>
+
+#include <asm/ibm44x.h>
+
+/* UART */
+#define PPC440SP_UART0_ADDR	0x00000001f0000200ULL
+#define PPC440SP_UART1_ADDR	0x00000001f0000300ULL
+#define PPC440SP_UART2_ADDR	0x00000001f0000600ULL
+#define UART0_INT		0
+#define UART1_INT		1
+#define UART2_INT		2
+
+/* 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_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 Bux Controller */
+#define IBM_CPM_EBM		    0x00100000	/* Ext Bus Master Interface */
+#define IBM_CPM_DMC		    0x00080000	/* SDRAM peripheral controller */
+#define IBM_CPM_PLB		    0x00040000	/* PLB bus arbiter */
+#define IBM_CPM_SRAM		0x00020000	/* SRAM memory controller */
+#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_UART2		0x00000100	/* serial port 1 */
+#define IBM_CPM_UIC0		0x00000080	/* Universal Interrupt Controller */
+#define IBM_CPM_TMRCLK		0x00000040	/* CPU timers */
+#define IBM_CPM_EMAC0  		0x00000020	/* EMAC 0     */
+
+#define DFLT_IBM4xx_PM		~(IBM_CPM_UIC | IBM_CPM_UIC1 | IBM_CPM_CPU \
+				| IBM_CPM_EBC | IBM_CPM_SRAM | IBM_CPM_BGO \
+				| IBM_CPM_EBM | IBM_CPM_PLB | IBM_CPM_OPB \
+				| IBM_CPM_TMRCLK | IBM_CPM_DMA | IBM_CPM_PCI \
+				| IBM_CPM_TAHOE0 | IBM_CPM_TAHOE1 \
+				| IBM_CPM_EMAC0 | IBM_CPM_EMAC1 \
+			  	| IBM_CPM_EMAC2 | IBM_CPM_EMAC3 )
+#endif /* __PPC_PLATFORMS_IBM440SP_H */
+#endif /* __KERNEL__ */
diff -Nru a/arch/ppc/platforms/4xx/ibmnp405h.h b/arch/ppc/platforms/4xx/ibmnp405h.h
--- a/arch/ppc/platforms/4xx/ibmnp405h.h	2005-03-01 23:38:57 -08:00
+++ b/arch/ppc/platforms/4xx/ibmnp405h.h	2005-03-01 23:38:57 -08:00
@@ -132,8 +132,7 @@
 #define DCRN_UIC1_BASE	0x0D0
 #define DCRN_CPC0_EPRCSR 0x0F3
 
-#define UIC0_UIC1NC      30	/* UIC1 non-critical interrupt */
-#define UIC0_UIC1CR      31	/* UIC1 critical interrupt */
+#define UIC0_UIC1NC	0x00000002
 
 #define CHR1_CETE	0x00000004	/* CPU external timer enable */
 #define UIC0	DCRN_UIC0_BASE
@@ -141,7 +140,6 @@
 
 #undef NR_UICS
 #define NR_UICS	2
-#define UIC_CASCADE_MASK 0x0003	/* bits 30 & 31 */
 
 /* EMAC DCRN's FIXME: armin */
 #define DCRN_MALRXCTP2R(base)	((base) + 0x42)	/* Channel Rx 2 Channel Table Pointer */
diff -Nru a/arch/ppc/platforms/4xx/ibmstbx25.c b/arch/ppc/platforms/4xx/ibmstbx25.c
--- a/arch/ppc/platforms/4xx/ibmstbx25.c	2005-03-01 23:38:53 -08:00
+++ b/arch/ppc/platforms/4xx/ibmstbx25.c	2005-03-01 23:38:53 -08:00
@@ -12,6 +12,7 @@
 #include <linux/init.h>
 #include <asm/ocp.h>
 #include <platforms/4xx/ibmstbx25.h>
+#include <asm/ppc4xx_pic.h>
 
 static struct ocp_func_iic_data ibmstbx25_iic0_def = {
 	.fast_mode	= 0,		/* Use standad mode (100Khz) */
@@ -55,5 +56,13 @@
 	  .pm		= IBM_CPM_GPIO0,
 	},
 	{ .vendor	= OCP_VENDOR_INVALID
+	}
+};
+
+/* Polarity and triggering settings for internal interrupt sources */
+struct ppc4xx_uic_settings ppc4xx_core_uic_cfg[] __initdata = {
+	{ .polarity 	= 0xffff8f80,
+	  .triggering	= 0x00000000,
+	  .ext_irq_mask	= 0x0000707f,	/* IRQ7 - IRQ9, IRQ0 - IRQ6 */
 	}
 };
diff -Nru a/arch/ppc/platforms/4xx/luan.c b/arch/ppc/platforms/4xx/luan.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/ppc/platforms/4xx/luan.c	2005-03-01 23:39:26 -08:00
@@ -0,0 +1,387 @@
+/*
+ * arch/ppc/platforms/4xx/luan.c
+ *
+ * Luan board specific routines
+ *
+ * Matt Porter <mporter@kernel.crashing.org>
+ *
+ * Copyright 2004-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 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 <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/ibm44x_common.h>
+#include <syslib/ibm440gx_common.h>
+#include <syslib/ibm440sp_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;
+
+static void __init
+luan_calibrate_decr(void)
+{
+	unsigned int freq;
+
+	if (mfspr(SPRN_CCR1) & CCR1_TCS)
+		freq = LUAN_TMR_CLK;
+	else
+		freq = clocks.cpu;
+
+	ibm44x_calibrate_decr(freq);
+}
+
+static int
+luan_show_cpuinfo(struct seq_file *m)
+{
+	seq_printf(m, "vendor\t\t: IBM\n");
+	seq_printf(m, "machine\t\t: PPC440SP EVB (Luan)\n");
+
+	return 0;
+}
+
+static inline int
+luan_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
+{
+	struct pci_controller *hose = pci_bus_to_hose(dev->bus->number);
+
+	/* PCIX0 in adapter mode, no host interrupt routing */
+
+	/* PCIX1 */
+	if (hose->index == 0) {
+		static char pci_irq_table[][4] =
+		/*
+		 *	PCI IDSEL/INTPIN->INTLINE
+		 *	  A   B   C   D
+		 */
+		{
+			{ 49, 49, 49, 49 },	/* IDSEL 1 - PCIX1 Slot 0 */
+			{ 49, 49, 49, 49 },	/* IDSEL 2 - PCIX1 Slot 1 */
+			{ 49, 49, 49, 49 },	/* IDSEL 3 - PCIX1 Slot 2 */
+			{ 49, 49, 49, 49 },	/* IDSEL 4 - PCIX1 Slot 3 */
+		};
+		const long min_idsel = 1, max_idsel = 4, irqs_per_slot = 4;
+		return PCI_IRQ_TABLE_LOOKUP;
+	/* PCIX2 */
+	} else if (hose->index == 1) {
+		static char pci_irq_table[][4] =
+		/*
+		 *	PCI IDSEL/INTPIN->INTLINE
+		 *	  A   B   C   D
+		 */
+		{
+			{ 50, 50, 50, 50 },	/* IDSEL 1 - PCIX2 Slot 0 */
+			{ 50, 50, 50, 50 },	/* IDSEL 2 - PCIX2 Slot 1 */
+			{ 50, 50, 50, 50 },	/* IDSEL 3 - PCIX2 Slot 2 */
+			{ 50, 50, 50, 50 },	/* IDSEL 4 - PCIX2 Slot 3 */
+		};
+		const long min_idsel = 1, max_idsel = 4, irqs_per_slot = 4;
+		return PCI_IRQ_TABLE_LOOKUP;
+	}
+	return -1;
+}
+
+static void __init luan_set_emacdata(void)
+{
+	struct ocp_def *def;
+	struct ocp_func_emac_data *emacdata;
+
+	/* Set phy_map, phy_mode, and mac_addr for the EMAC */
+	def = ocp_get_one_device(OCP_VENDOR_IBM, OCP_FUNC_EMAC, 0);
+	emacdata = def->additions;
+	emacdata->phy_map = 0x00000001;	/* Skip 0x00 */
+	emacdata->phy_mode = PHY_MODE_GMII;
+	memcpy(emacdata->mac_addr, __res.bi_enetaddr, 6);
+}
+
+#define PCIX_READW(offset) \
+	(readw((void *)((u32)pcix_reg_base+offset)))
+
+#define PCIX_WRITEW(value, offset) \
+	(writew(value, (void *)((u32)pcix_reg_base+offset)))
+
+#define PCIX_WRITEL(value, offset) \
+	(writel(value, (void *)((u32)pcix_reg_base+offset)))
+
+static void __init
+luan_setup_pcix(void)
+{
+	int i;
+	void *pcix_reg_base;
+
+	for (i=0;i<3;i++) {
+		pcix_reg_base = ioremap64(PCIX0_REG_BASE + i*PCIX_REG_OFFSET, PCIX_REG_SIZE);
+
+		/* Enable PCIX0 I/O, Mem, and Busmaster cycles */
+		PCIX_WRITEW(PCIX_READW(PCIX0_COMMAND) | PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER, PCIX0_COMMAND);
+
+		/* Disable all windows */
+		PCIX_WRITEL(0, PCIX0_POM0SA);
+		PCIX_WRITEL(0, PCIX0_POM1SA);
+		PCIX_WRITEL(0, PCIX0_POM2SA);
+		PCIX_WRITEL(0, PCIX0_PIM0SA);
+		PCIX_WRITEL(0, PCIX0_PIM0SAH);
+		PCIX_WRITEL(0, PCIX0_PIM1SA);
+		PCIX_WRITEL(0, PCIX0_PIM2SA);
+		PCIX_WRITEL(0, PCIX0_PIM2SAH);
+
+		/*
+		 * Setup 512MB PLB->PCI outbound mem window
+		 * (a_n000_0000->0_n000_0000)
+		 * */
+		PCIX_WRITEL(0x0000000a, PCIX0_POM0LAH);
+		PCIX_WRITEL(0x80000000 | i*LUAN_PCIX_MEM_SIZE, PCIX0_POM0LAL);
+		PCIX_WRITEL(0x00000000, PCIX0_POM0PCIAH);
+		PCIX_WRITEL(0x80000000 | i*LUAN_PCIX_MEM_SIZE, PCIX0_POM0PCIAL);
+		PCIX_WRITEL(0xe0000001, PCIX0_POM0SA);
+
+		/* Setup 2GB PCI->PLB inbound memory window at 0, enable MSIs */
+		PCIX_WRITEL(0x00000000, PCIX0_PIM0LAH);
+		PCIX_WRITEL(0x00000000, PCIX0_PIM0LAL);
+		PCIX_WRITEL(0xe0000007, PCIX0_PIM0SA);
+		PCIX_WRITEL(0xffffffff, PCIX0_PIM0SAH);
+
+		iounmap(pcix_reg_base);
+	}
+
+	eieio();
+}
+
+static void __init
+luan_setup_hose(struct pci_controller *hose,
+		int lower_mem,
+		int upper_mem,
+		int cfga,
+		int cfgd,
+		u64 pcix_io_base)
+{
+	char name[20];
+
+	sprintf(name, "PCIX%d host bridge", hose->index);
+
+	hose->pci_mem_offset = LUAN_PCIX_MEM_OFFSET;
+
+	pci_init_resource(&hose->io_resource,
+			LUAN_PCIX_LOWER_IO,
+			LUAN_PCIX_UPPER_IO,
+			IORESOURCE_IO,
+			name);
+
+	pci_init_resource(&hose->mem_resources[0],
+			lower_mem,
+			upper_mem,
+			IORESOURCE_MEM,
+			name);
+
+	hose->io_space.start = LUAN_PCIX_LOWER_IO;
+	hose->io_space.end = LUAN_PCIX_UPPER_IO;
+	hose->mem_space.start = lower_mem;
+	hose->mem_space.end = upper_mem;
+	isa_io_base =
+		(unsigned long)ioremap64(pcix_io_base, PCIX_IO_SIZE);
+	hose->io_base_virt = (void *)isa_io_base;
+
+	setup_indirect_pci(hose, cfga, cfgd);
+	hose->set_cfg_type = 1;
+}
+
+static void __init
+luan_setup_hoses(void)
+{
+	struct pci_controller *hose1, *hose2;
+
+	/* Configure windows on the PCI-X host bridge */
+	luan_setup_pcix();
+
+	/* Allocate hoses for PCIX1 and PCIX2 */
+	hose1 = pcibios_alloc_controller();
+	hose2 = pcibios_alloc_controller();
+	if (!hose1 || !hose2)
+		return;
+
+	/* Setup PCIX1 */
+	hose1->first_busno = 0;
+	hose1->last_busno = 0xff;
+
+	luan_setup_hose(hose1,
+			LUAN_PCIX1_LOWER_MEM,
+			LUAN_PCIX1_UPPER_MEM,
+			PCIX1_CFGA,
+			PCIX1_CFGD,
+			PCIX1_IO_BASE);
+
+	hose1->last_busno = pciauto_bus_scan(hose1, hose1->first_busno);
+
+	/* Setup PCIX2 */
+	hose2->first_busno = hose1->last_busno + 1;
+	hose2->last_busno = 0xff;
+
+	luan_setup_hose(hose2,
+			LUAN_PCIX2_LOWER_MEM,
+			LUAN_PCIX2_UPPER_MEM,
+			PCIX2_CFGA,
+			PCIX2_CFGD,
+			PCIX2_IO_BASE);
+
+	hose2->last_busno = pciauto_bus_scan(hose2, hose2->first_busno);
+
+	ppc_md.pci_swizzle = common_swizzle;
+	ppc_md.pci_map_irq = luan_map_irq;
+}
+
+TODC_ALLOC();
+
+static void __init
+luan_early_serial_map(void)
+{
+	struct uart_port port;
+
+	/* Setup ioremapped serial port access */
+	memset(&port, 0, sizeof(port));
+	port.membase = ioremap64(PPC440SP_UART0_ADDR, 8);
+	port.irq = UART0_INT;
+	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");
+	}
+
+	port.membase = ioremap64(PPC440SP_UART1_ADDR, 8);
+	port.irq = UART1_INT;
+	port.uartclk = clocks.uart1;
+	port.line = 1;
+
+	if (early_serial_setup(&port) != 0) {
+		printk("Early serial init of port 1 failed\n");
+	}
+
+	port.membase = ioremap64(PPC440SP_UART2_ADDR, 8);
+	port.irq = UART2_INT;
+	port.uartclk = BASE_BAUD;
+	port.line = 2;
+
+	if (early_serial_setup(&port) != 0) {
+		printk("Early serial init of port 2 failed\n");
+	}
+}
+
+static void __init
+luan_setup_arch(void)
+{
+	luan_set_emacdata();
+
+#if !defined(CONFIG_BDI_SWITCH)
+	/*
+	 * The Abatron BDI JTAG debugger does not tolerate others
+	 * mucking with the debug registers.
+	 */
+        mtspr(SPRN_DBCR0, (DBCR0_TDE | DBCR0_IDM));
+#endif
+
+	/*
+	 * Determine various clocks.
+	 * To be completely correct we should get SysClk
+	 * from FPGA, because it can be changed by on-board switches
+	 * --ebs
+	 */
+	/* 440GX and 440SP clocking is the same -mdp */
+	ibm440gx_get_clocks(&clocks, 33333333, 6 * 1843200);
+	ocp_sys_info.opb_bus_freq = clocks.opb;
+
+	/* init to some ~sane value until calibrate_delay() runs */
+        loops_per_jiffy = 50000000/HZ;
+
+	/* Setup PCIXn host bridges */
+	luan_setup_hoses();
+
+#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
+
+	luan_early_serial_map();
+
+	/* Identify the system */
+	printk("Luan 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 = luan_setup_arch;
+	ppc_md.show_cpuinfo = luan_show_cpuinfo;
+	ppc_md.find_end_of_memory = ibm440sp_find_end_of_memory;
+	ppc_md.get_irq = NULL;		/* Set in ppc4xx_pic_init() */
+
+	ppc_md.calibrate_decr = luan_calibrate_decr;
+#ifdef CONFIG_KGDB
+	ppc_md.early_serial_map = luan_early_serial_map;
+#endif
+}
diff -Nru a/arch/ppc/platforms/4xx/luan.h b/arch/ppc/platforms/4xx/luan.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/ppc/platforms/4xx/luan.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,80 @@
+/*
+ * arch/ppc/platforms/4xx/luan.h
+ *
+ * Luan board definitions
+ *
+ * Matt Porter <mporter@kernel.crashing.org>
+ *
+ * Copyright 2004-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 as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
+
+#ifdef __KERNEL__
+#ifndef __ASM_LUAN_H__
+#define __ASM_LUAN_H__
+
+#include <linux/config.h>
+#include <platforms/4xx/ibm440sp.h>
+
+/* F/W TLB mapping used in bootloader glue to reset EMAC */
+#define PPC44x_EMAC0_MR0	0xa0000800
+
+/* Location of MAC addresses in PIBS image */
+#define PIBS_FLASH_BASE		0xffe00000
+#define PIBS_MAC_BASE		(PIBS_FLASH_BASE+0x1b0400)
+
+/* External timer clock frequency */
+#define LUAN_TMR_CLK		25000000
+
+/* Flash */
+#define LUAN_FPGA_REG_0			0x0000000148300000ULL
+#define LUAN_BOOT_LARGE_FLASH(x)	(x & 0x40)
+#define LUAN_SMALL_FLASH_LOW		0x00000001ff900000ULL
+#define LUAN_SMALL_FLASH_HIGH		0x00000001ffe00000ULL
+#define LUAN_SMALL_FLASH_SIZE		0x100000
+#define LUAN_LARGE_FLASH_LOW		0x00000001ff800000ULL
+#define LUAN_LARGE_FLASH_HIGH		0x00000001ffc00000ULL
+#define LUAN_LARGE_FLASH_SIZE		0x400000
+
+/*
+ * Serial port defines
+ */
+#define RS_TABLE_SIZE	3
+
+/* PIBS defined UART mappings, used before early_serial_setup */
+#define UART0_IO_BASE	(u8 *) 0xa0000200
+#define UART1_IO_BASE	(u8 *) 0xa0000300
+#define UART2_IO_BASE	(u8 *) 0xa0000600
+
+#define BASE_BAUD	11059200
+#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)
+
+/* PCI support */
+#define LUAN_PCIX_LOWER_IO	0x00000000
+#define LUAN_PCIX_UPPER_IO	0x0000ffff
+#define LUAN_PCIX0_LOWER_MEM	0x80000000
+#define LUAN_PCIX0_UPPER_MEM	0x9fffffff
+#define LUAN_PCIX1_LOWER_MEM	0xa0000000
+#define LUAN_PCIX1_UPPER_MEM	0xbfffffff
+#define LUAN_PCIX2_LOWER_MEM	0xc0000000
+#define LUAN_PCIX2_UPPER_MEM	0xdfffffff
+
+#define LUAN_PCIX_MEM_SIZE	0x20000000
+#define LUAN_PCIX_MEM_OFFSET	0x00000000
+
+#endif				/* __ASM_LUAN_H__ */
+#endif				/* __KERNEL__ */
diff -Nru a/arch/ppc/platforms/4xx/oak.c b/arch/ppc/platforms/4xx/oak.c
--- a/arch/ppc/platforms/4xx/oak.c	2005-03-01 23:39:09 -08:00
+++ b/arch/ppc/platforms/4xx/oak.c	2005-03-01 23:39:09 -08:00
@@ -101,8 +101,8 @@
 	ppc_md.setup_arch	 	= oak_setup_arch;
 	ppc_md.show_percpuinfo	 	= oak_show_percpuinfo;
 	ppc_md.irq_canonicalize 	= NULL;
-	ppc_md.init_IRQ		 	= oak_init_IRQ;
-	ppc_md.get_irq		 	= oak_get_irq;
+	ppc_md.init_IRQ		 	= ppc4xx_pic_init;
+	ppc_md.get_irq		 	= NULL;  /* Set in ppc4xx_pic_init() */
 	ppc_md.init		 	= NULL;
 
 	ppc_md.restart		 	= oak_restart;
@@ -153,32 +153,6 @@
 		   bp->bi_busfreq / 1000000);
 
 	return 0;
-}
-
-/*
- * Document me.
- */
-void __init
-oak_init_IRQ(void)
-{
-	int i;
-
-	ppc4xx_pic_init();
-
-	for (i = 0; i < NR_IRQS; i++) {
-		irq_desc[i].handler = ppc4xx_pic;
-	}
-
-	return;
-}
-
-/*
- * Document me.
- */
-int
-oak_get_irq(struct pt_regs *regs)
-{
-	return (ppc4xx_pic_get_irq(regs));
 }
 
 /*
diff -Nru a/arch/ppc/platforms/4xx/ocotea.c b/arch/ppc/platforms/4xx/ocotea.c
--- a/arch/ppc/platforms/4xx/ocotea.c	2005-03-01 23:39:09 -08:00
+++ b/arch/ppc/platforms/4xx/ocotea.c	2005-03-01 23:39:09 -08:00
@@ -5,7 +5,7 @@
  *
  * Matt Porter <mporter@kernel.crashing.org>
  *
- * Copyright 2003-2004 MontaVista Software Inc.
+ * Copyright 2003-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 as published by the
@@ -163,7 +163,7 @@
 {
 	void *pcix_reg_base;
 
-	pcix_reg_base = ioremap64(PCIX0_REG_BASE, PCIX0_REG_SIZE);
+	pcix_reg_base = ioremap64(PCIX0_REG_BASE, PCIX_REG_SIZE);
 
 	/* Enable PCIX0 I/O, Mem, and Busmaster cycles */
 	PCIX_WRITEW(PCIX_READW(PCIX0_COMMAND) | PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER, PCIX0_COMMAND);
@@ -346,12 +346,6 @@
 	 */
 	ibm440gx_get_clocks(&clocks, 33333333, 6 * 1843200);
 	ocp_sys_info.opb_bus_freq = clocks.opb;
-
-	/* XXX Fix L2C IRQ triggerring setting (edge-sensitive).
-	 * Firmware (at least PIBS v1.72 OCT/28/2003) sets it incorrectly
-	 * --ebs
-	 */
-	mtdcr(DCRN_UIC_TR(UIC2), mfdcr(DCRN_UIC_TR(UIC2)) | 0x00000100);
 
 	ibm44x_platform_init();
 
diff -Nru a/arch/ppc/platforms/4xx/ocotea.h b/arch/ppc/platforms/4xx/ocotea.h
--- a/arch/ppc/platforms/4xx/ocotea.h	2005-03-01 23:38:57 -08:00
+++ b/arch/ppc/platforms/4xx/ocotea.h	2005-03-01 23:38:57 -08:00
@@ -3,9 +3,9 @@
  *
  * Ocotea board definitions
  *
- * Matt Porter <mporter@mvista.com>
+ * Matt Porter <mporter@kernel.crashing.org>
  *
- * Copyright 2003 MontaVista Software Inc.
+ * Copyright 2003-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 as published by the
@@ -22,13 +22,13 @@
 #include <platforms/4xx/ibm440gx.h>
 
 /* F/W TLB mapping used in bootloader glue to reset EMAC */
-#define PPC44x_EMAC0_MR0	0xE0000800
+#define PPC44x_EMAC0_MR0	0xe0000800
 
 /* Location of MAC addresses in PIBS image */
-#define OCOTEA_PIBS_FLASH	0xfff00000
-#define OCOTEA_PIBS_MAC_BASE	(OCOTEA_PIBS_FLASH+0xb0500)
-#define OCOTEA_PIBS_MAC_SIZE	0x200
-#define OCOTEA_PIBS_MAC_OFFSET	0x100
+#define PIBS_FLASH_BASE		0xfff00000
+#define PIBS_MAC_BASE		(PIBS_FLASH_BASE+0xb0500)
+#define PIBS_MAC_SIZE		0x200
+#define PIBS_MAC_OFFSET		0x100
 
 /* External timer clock frequency */
 #define OCOTEA_TMR_CLK	25000000
diff -Nru a/arch/ppc/platforms/4xx/redwood6.c b/arch/ppc/platforms/4xx/redwood6.c
--- a/arch/ppc/platforms/4xx/redwood6.c	2005-03-01 23:39:19 -08:00
+++ b/arch/ppc/platforms/4xx/redwood6.c	2005-03-01 23:39:19 -08:00
@@ -19,44 +19,20 @@
 #include <linux/delay.h>
 #include <asm/machdep.h>
 
-
 /*
- * Define all of the IRQ senses and polarities.
+ * Define external IRQ senses and polarities.
  */
-
-static u_char redwood6_IRQ_initsenses[] __initdata = {
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 0: RTC/FPC */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 1: Transport */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 2: Audio Dec */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 3: Video Dec */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 4: DMA Chan 0 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 5: DMA Chan 1 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 6: DMA Chan 2 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 7: DMA Chan 3 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 8: SmartCard 0 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 9: IIC0 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 10: IRR */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 11: Cap Timers */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 12: Cmp Timers */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 13: Serial Port */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 14: Soft Modem */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 15: Down Ctrs */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 16: SmartCard 1 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* 17: Ext Int 7 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* 18: Ext Int 8 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* 19: Ext Int 9 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 20: Serial 0 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 21: Serial 1 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 22: Serial 2 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 23: XPT_DMA */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 24: DCR timeout */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* 25: Ext Int 0 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* 26: Ext Int 1 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* 27: Ext Int 2 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* 28: Ext Int 3 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* 29: Ext Int 4 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* 30: Ext Int 5 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* 31: Ext Int 6 */
+unsigned char ppc4xx_uic_ext_irq_cfg[] __initdata = {
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* Ext Int 7 */
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* Ext Int 8 */
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* Ext Int 9 */
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* Ext Int 0 */
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* Ext Int 1 */
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* Ext Int 2 */
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* Ext Int 3 */
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* Ext Int 4 */
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* Ext Int 5 */
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* Ext Int 6 */
 };
 
 static struct resource smc91x_resources[] = {
@@ -144,8 +120,6 @@
 
 	printk("\n");
 #endif
-	ibm4xxPIC_InitSenses = redwood6_IRQ_initsenses;
-	ibm4xxPIC_NumInitSenses = sizeof(redwood6_IRQ_initsenses);
 
 	/* Identify the system */
 	printk(KERN_INFO "IBM Redwood6 (STBx25XX) Platform\n");
diff -Nru a/arch/ppc/platforms/4xx/sycamore.c b/arch/ppc/platforms/4xx/sycamore.c
--- a/arch/ppc/platforms/4xx/sycamore.c	2005-03-01 23:39:07 -08:00
+++ b/arch/ppc/platforms/4xx/sycamore.c	2005-03-01 23:39:07 -08:00
@@ -44,42 +44,22 @@
 void *sycamore_rtc_base;
 
 /*
- * Define all of the IRQ senses and polarities.
+ * Define external IRQ senses and polarities.
  */
-
-static u_char Sycamore_IRQ_initsenses[] __initdata = {
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 0: Uart 0*/
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 1: Uart 1*/
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 2: IIC */
-	(IRQ_SENSE_EDGE  | IRQ_POLARITY_POSITIVE),	/* 3: External Master */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 4: PCI ext cmd write*/
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 5: DMA Chan 0 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 6: DMA Chan 1 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 7: DMA Chan 2 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 8: DMA Chan 3 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 9: Ethernet wakeup (WOL)*/
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 10: Mal (SEER) */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 11: Mal TXEOB */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 12: Mal RXEOB */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 13: Mal TXDE*/
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 14: Mal RXDE*/
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 15: Ethernet */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 16: Ext PCI SERR */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 17: ECC */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* 18: PCI PM*/
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* 19: Ext Int 7 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* 20: Ext Int 8 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* 21: Ext Int 9 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* 22: Ext Int 10 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* 23: Ext Int 11 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* 24: Ext Int 12 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* 25: Ext Int 0 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* 26: Ext Int 1 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* 27: Ext Int 2 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* 28: Ext Int 3 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* 29: Ext Int 4 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* 30: Ext Int 5 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* 31: Ext Int 6 */
+unsigned char ppc4xx_uic_ext_irq_cfg[] __initdata = {
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* Ext Int 7 */
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* Ext Int 8 */
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* Ext Int 9 */
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* Ext Int 10 */
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* Ext Int 11 */
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* Ext Int 12 */
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* Ext Int 0 */
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* Ext Int 1 */
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* Ext Int 2 */
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* Ext Int 3 */
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* Ext Int 4 */
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* Ext Int 5 */
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* Ext Int 6 */
 };
 
 
@@ -158,8 +138,6 @@
 	sycamore_rtc_base = (void *) SYCAMORE_RTC_VADDR;
 	TODC_INIT(TODC_TYPE_DS1743, sycamore_rtc_base, sycamore_rtc_base,
 		  sycamore_rtc_base, 8);
-	ibm4xxPIC_InitSenses = Sycamore_IRQ_initsenses;
-	ibm4xxPIC_NumInitSenses = sizeof(Sycamore_IRQ_initsenses);
 
 	/* Identify the system */
 	printk(KERN_INFO "IBM Sycamore (IBM405GPr) Platform\n");
diff -Nru a/arch/ppc/platforms/85xx/Kconfig b/arch/ppc/platforms/85xx/Kconfig
--- a/arch/ppc/platforms/85xx/Kconfig	2005-03-01 23:39:17 -08:00
+++ b/arch/ppc/platforms/85xx/Kconfig	2005-03-01 23:39:17 -08:00
@@ -37,6 +37,12 @@
 	  This option enables support for the WindRiver PowerQUICC III 
 	  SBC8560 board.
 
+config STX_GP3
+	bool "Silicon Turnkey Express GP3"
+	help
+	  This option enables support for the Silicon Turnkey Express GP3
+	  board.
+
 endchoice
 
 # It's often necessary to know the specific 85xx processor type.
@@ -54,17 +60,12 @@
 
 config MPC8560
 	bool
-	depends on SBC8560 || MPC8560_ADS
+	depends on SBC8560 || MPC8560_ADS || STX_GP3
 	default y
 
 config 85xx_PCI2
 	bool "Supprt for 2nd PCI host controller"
 	depends on MPC8555_CDS
-	default y
-
-config FSL_OCP
-	bool
-	depends on 85xx
 	default y
 
 config PPC_GEN550
diff -Nru a/arch/ppc/platforms/85xx/Makefile b/arch/ppc/platforms/85xx/Makefile
--- a/arch/ppc/platforms/85xx/Makefile	2005-03-01 23:38:52 -08:00
+++ b/arch/ppc/platforms/85xx/Makefile	2005-03-01 23:38:52 -08:00
@@ -1,12 +1,10 @@
 #
 # Makefile for the PowerPC 85xx linux kernel.
 #
+obj-$(CONFIG_85xx)		+= mpc85xx_sys.o mpc85xx_devices.o
 
 obj-$(CONFIG_MPC8540_ADS)	+= mpc85xx_ads_common.o mpc8540_ads.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
-
-obj-$(CONFIG_MPC8540)		+= mpc8540.o
-obj-$(CONFIG_MPC8555)		+= mpc8555.o
-obj-$(CONFIG_MPC8560)		+= mpc8560.o
+obj-$(CONFIG_STX_GP3)		+= stx_gp3.o
diff -Nru a/arch/ppc/platforms/85xx/mpc8540.c b/arch/ppc/platforms/85xx/mpc8540.c
--- a/arch/ppc/platforms/85xx/mpc8540.c	2005-03-01 23:39:09 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,97 +0,0 @@
-/*
- * arch/ppc/platforms/85xx/mpc8540.c
- *
- * MPC8540 I/O descriptions
- *
- * 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.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <asm/mpc85xx.h>
-#include <asm/ocp.h>
-
-/* These should be defined in platform code */
-extern struct ocp_gfar_data mpc85xx_tsec1_def;
-extern struct ocp_gfar_data mpc85xx_tsec2_def;
-extern struct ocp_gfar_data mpc85xx_fec_def;
-extern struct ocp_mpc_i2c_data mpc85xx_i2c1_def;
-
-/* We use offsets for paddr since we do not know at compile time
- * what CCSRBAR is, platform code should fix this up in
- * setup_arch
- *
- * Only the first IRQ is given even if a device has
- * multiple lines associated with ita
- */
-struct ocp_def core_ocp[] = {
-        { .vendor       = OCP_VENDOR_FREESCALE,
-          .function     = OCP_FUNC_IIC,
-          .index        = 0,
-          .paddr        = MPC85xx_IIC1_OFFSET,
-          .irq          = MPC85xx_IRQ_IIC1,
-          .pm           = OCP_CPM_NA,
-          .additions    = &mpc85xx_i2c1_def,
-        },
-        { .vendor       = OCP_VENDOR_FREESCALE,
-          .function     = OCP_FUNC_16550,
-          .index        = 0,
-          .paddr        = MPC85xx_UART0_OFFSET,
-          .irq          = MPC85xx_IRQ_DUART,
-          .pm           = OCP_CPM_NA,
-        },
-        { .vendor       = OCP_VENDOR_FREESCALE,
-          .function     = OCP_FUNC_16550,
-          .index        = 1,
-          .paddr        = MPC85xx_UART1_OFFSET,
-          .irq          = MPC85xx_IRQ_DUART,
-          .pm           = OCP_CPM_NA,
-        },
-        { .vendor       = OCP_VENDOR_FREESCALE,
-          .function     = OCP_FUNC_GFAR,
-          .index        = 0,
-          .paddr        = MPC85xx_ENET1_OFFSET,
-          .irq          = MPC85xx_IRQ_TSEC1_TX,
-          .pm           = OCP_CPM_NA,
-          .additions    = &mpc85xx_tsec1_def,
-        },
-        { .vendor       = OCP_VENDOR_FREESCALE,
-          .function     = OCP_FUNC_GFAR,
-          .index        = 1,
-          .paddr        = MPC85xx_ENET2_OFFSET,
-          .irq          = MPC85xx_IRQ_TSEC2_TX,
-          .pm           = OCP_CPM_NA,
-          .additions    = &mpc85xx_tsec2_def,
-        },
-        { .vendor       = OCP_VENDOR_FREESCALE,
-          .function     = OCP_FUNC_GFAR,
-          .index        = 2,
-          .paddr        = MPC85xx_ENET3_OFFSET,
-          .irq          = MPC85xx_IRQ_FEC,
-          .pm           = OCP_CPM_NA,
-          .additions    = &mpc85xx_fec_def,
-        },
-        { .vendor       = OCP_VENDOR_FREESCALE,
-          .function     = OCP_FUNC_DMA,
-          .index        = 0,
-          .paddr        = MPC85xx_DMA_OFFSET,
-          .irq          = MPC85xx_IRQ_DMA0,
-          .pm           = OCP_CPM_NA,
-        },
-        { .vendor       = OCP_VENDOR_FREESCALE,
-          .function     = OCP_FUNC_PERFMON,
-          .index        = 0,
-          .paddr        = MPC85xx_PERFMON_OFFSET,
-          .irq          = MPC85xx_IRQ_PERFMON,
-          .pm           = OCP_CPM_NA,
-        },
-        { .vendor       = OCP_VENDOR_INVALID
-        }
-};
diff -Nru a/arch/ppc/platforms/85xx/mpc8540_ads.c b/arch/ppc/platforms/85xx/mpc8540_ads.c
--- a/arch/ppc/platforms/85xx/mpc8540_ads.c	2005-03-01 23:38:55 -08:00
+++ b/arch/ppc/platforms/85xx/mpc8540_ads.c	2005-03-01 23:38:55 -08:00
@@ -32,6 +32,7 @@
 #include <linux/serial_core.h>
 #include <linux/initrd.h>
 #include <linux/module.h>
+#include <linux/fsl_devices.h>
 
 #include <asm/system.h>
 #include <asm/pgtable.h>
@@ -48,50 +49,11 @@
 #include <asm/irq.h>
 #include <asm/immap_85xx.h>
 #include <asm/kgdb.h>
-#include <asm/ocp.h>
+#include <asm/ppc_sys.h>
 #include <mm/mmu_decl.h>
 
-#include <syslib/ppc85xx_common.h>
 #include <syslib/ppc85xx_setup.h>
 
-struct ocp_gfar_data mpc85xx_tsec1_def = {
-	.interruptTransmit = MPC85xx_IRQ_TSEC1_TX,
-	.interruptError = MPC85xx_IRQ_TSEC1_ERROR,
-	.interruptReceive = MPC85xx_IRQ_TSEC1_RX,
-	.interruptPHY = MPC85xx_IRQ_EXT5,
-	.flags = (GFAR_HAS_GIGABIT | GFAR_HAS_MULTI_INTR
-			| GFAR_HAS_RMON
-			| GFAR_HAS_PHY_INTR | GFAR_HAS_COALESCE),
-	.phyid = 0,
-	.phyregidx = 0,
-};
-
-struct ocp_gfar_data mpc85xx_tsec2_def = {
-	.interruptTransmit = MPC85xx_IRQ_TSEC2_TX,
-	.interruptError = MPC85xx_IRQ_TSEC2_ERROR,
-	.interruptReceive = MPC85xx_IRQ_TSEC2_RX,
-	.interruptPHY = MPC85xx_IRQ_EXT5,
-	.flags = (GFAR_HAS_GIGABIT | GFAR_HAS_MULTI_INTR
-			| GFAR_HAS_RMON
-			| GFAR_HAS_PHY_INTR | GFAR_HAS_COALESCE),
-	.phyid = 1,
-	.phyregidx = 0,
-};
-
-struct ocp_gfar_data mpc85xx_fec_def = {
-	.interruptTransmit = MPC85xx_IRQ_FEC,
-	.interruptError = MPC85xx_IRQ_FEC,
-	.interruptReceive = MPC85xx_IRQ_FEC,
-	.interruptPHY = MPC85xx_IRQ_EXT5,
-	.flags = 0,
-	.phyid = 3,
-	.phyregidx = 0,
-};
-
-struct ocp_fs_i2c_data mpc85xx_i2c1_def = {
-	.flags = FS_I2C_SEPARATE_DFSRR,
-};
-
 /* ************************************************************************
  *
  * Setup the architecture
@@ -100,10 +62,9 @@
 static void __init
 mpc8540ads_setup_arch(void)
 {
-	struct ocp_def *def;
-	struct ocp_gfar_data *einfo;
 	bd_t *binfo = (bd_t *) __res;
 	unsigned int freq;
+	struct gianfar_platform_data *pdata;
 
 	/* get the core frequency */
 	freq = binfo->bi_intfreq;
@@ -130,23 +91,30 @@
 	invalidate_tlbcam_entry(NUM_TLBCAMS - 1);
 #endif
 
-	def = ocp_get_one_device(OCP_VENDOR_FREESCALE, OCP_FUNC_GFAR, 0);
-	if (def) {
-		einfo = (struct ocp_gfar_data *) def->additions;
-		memcpy(einfo->mac_addr, binfo->bi_enetaddr, 6);
-	}
-
-	def = ocp_get_one_device(OCP_VENDOR_FREESCALE, OCP_FUNC_GFAR, 1);
-	if (def) {
-		einfo = (struct ocp_gfar_data *) def->additions;
-		memcpy(einfo->mac_addr, binfo->bi_enet1addr, 6);
-	}
-
-	def = ocp_get_one_device(OCP_VENDOR_FREESCALE, OCP_FUNC_GFAR, 2);
-	if (def) {
-		einfo = (struct ocp_gfar_data *) def->additions;
-		memcpy(einfo->mac_addr, binfo->bi_enet2addr, 6);
-	}
+	/* 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);
+
+	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);
+
+	pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_FEC);
+	pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
+	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)
@@ -158,8 +126,6 @@
 #else
 		ROOT_DEV = Root_HDA1;
 #endif
-
-	ocp_for_each_device(mpc85xx_update_paddr_ocp, &(binfo->bi_immr_base));
 }
 
 /* ************************************************************************ */
@@ -181,10 +147,25 @@
 #ifdef CONFIG_SERIAL_TEXT_DEBUG
 	{
 		bd_t *binfo = (bd_t *) __res;
+		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,
 			  binfo->bi_immr_base, MPC85xx_CCSRBAR_SIZE, _PAGE_IO, 0);
+
+		memset(&p, 0, sizeof (p));
+		p.iotype = SERIAL_IO_MEM;
+		p.membase = (void *) binfo->bi_immr_base + MPC85xx_UART0_OFFSET;
+		p.uartclk = binfo->bi_busfreq;
+
+		gen550_init(0, &p);
+
+		memset(&p, 0, sizeof (p));
+		p.iotype = SERIAL_IO_MEM;
+		p.membase = (void *) binfo->bi_immr_base + MPC85xx_UART1_OFFSET;
+		p.uartclk = binfo->bi_busfreq;
+
+		gen550_init(1, &p);
 	}
 #endif
 
@@ -205,6 +186,8 @@
 		*(char *) (r7 + KERNELBASE) = 0;
 		strcpy(cmd_line, (char *) (r6 + KERNELBASE));
 	}
+
+	identify_ppc_sys_by_id(mfspr(SVR));
 
 	/* setup the PowerPC module struct */
 	ppc_md.setup_arch = mpc8540ads_setup_arch;
diff -Nru a/arch/ppc/platforms/85xx/mpc8540_ads.h b/arch/ppc/platforms/85xx/mpc8540_ads.h
--- a/arch/ppc/platforms/85xx/mpc8540_ads.h	2005-03-01 23:39:18 -08:00
+++ b/arch/ppc/platforms/85xx/mpc8540_ads.h	2005-03-01 23:39:18 -08:00
@@ -22,8 +22,4 @@
 #include <syslib/ppc85xx_setup.h>
 #include <platforms/85xx/mpc85xx_ads_common.h>
 
-#define SERIAL_PORT_DFNS	\
-	STD_UART_OP(0)		\
-	STD_UART_OP(1)
-
 #endif /* __MACH_MPC8540ADS_H__ */
diff -Nru a/arch/ppc/platforms/85xx/mpc8555.c b/arch/ppc/platforms/85xx/mpc8555.c
--- a/arch/ppc/platforms/85xx/mpc8555.c	2005-03-01 23:39:08 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,95 +0,0 @@
-/*
- * arch/ppc/platform/85xx/mpc8555.c
- *
- * MPC8555 I/O descriptions
- *
- * 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.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <asm/mpc85xx.h>
-#include <asm/ocp.h>
-
-/* These should be defined in platform code */
-extern struct ocp_gfar_data mpc85xx_tsec1_def;
-extern struct ocp_gfar_data mpc85xx_tsec2_def;
-extern struct ocp_mpc_i2c_data mpc85xx_i2c1_def;
-
-/* We use offsets for paddr since we do not know at compile time
- * what CCSRBAR is, platform code should fix this up in
- * setup_arch
- *
- * Only the first IRQ is given even if a device has
- * multiple lines associated with ita
- */
-struct ocp_def core_ocp[] = {
-        { .vendor       = OCP_VENDOR_FREESCALE,
-          .function     = OCP_FUNC_IIC,
-          .index        = 0,
-          .paddr        = MPC85xx_IIC1_OFFSET,
-          .irq          = MPC85xx_IRQ_IIC1,
-          .pm           = OCP_CPM_NA,
-	  .additions	= &mpc85xx_i2c1_def,
-        },
-        { .vendor       = OCP_VENDOR_FREESCALE,
-          .function     = OCP_FUNC_16550,
-          .index        = 0,
-          .paddr        = MPC85xx_UART0_OFFSET,
-          .irq          = MPC85xx_IRQ_DUART,
-          .pm           = OCP_CPM_NA,
-        },
-        { .vendor       = OCP_VENDOR_FREESCALE,
-          .function     = OCP_FUNC_16550,
-          .index        = 1,
-          .paddr        = MPC85xx_UART1_OFFSET,
-          .irq          = MPC85xx_IRQ_DUART,
-          .pm           = OCP_CPM_NA,
-        },
-        { .vendor       = OCP_VENDOR_FREESCALE,
-          .function     = OCP_FUNC_GFAR,
-          .index        = 0,
-          .paddr        = MPC85xx_ENET1_OFFSET,
-          .irq          = MPC85xx_IRQ_TSEC1_TX,
-          .pm           = OCP_CPM_NA,
-          .additions    = &mpc85xx_tsec1_def,
-        },
-        { .vendor       = OCP_VENDOR_FREESCALE,
-          .function     = OCP_FUNC_GFAR,
-          .index        = 1,
-          .paddr        = MPC85xx_ENET2_OFFSET,
-          .irq          = MPC85xx_IRQ_TSEC2_TX,
-          .pm           = OCP_CPM_NA,
-          .additions    = &mpc85xx_tsec2_def,
-        },
-        { .vendor       = OCP_VENDOR_FREESCALE,
-          .function     = OCP_FUNC_DMA,
-          .index        = 0,
-          .paddr        = MPC85xx_DMA_OFFSET,
-          .irq          = MPC85xx_IRQ_DMA0,
-          .pm           = OCP_CPM_NA,
-        },
-        { .vendor       = OCP_VENDOR_FREESCALE,
-          .function     = OCP_FUNC_SEC2,
-          .index        = 0,
-          .paddr        = MPC85xx_SEC2_OFFSET,
-          .irq          = MPC85xx_IRQ_SEC2,
-          .pm           = OCP_CPM_NA,
-	},
-	{ .vendor       = OCP_VENDOR_FREESCALE,
-          .function     = OCP_FUNC_PERFMON,
-          .index        = 0,
-          .paddr        = MPC85xx_PERFMON_OFFSET,
-          .irq          = MPC85xx_IRQ_PERFMON,
-          .pm           = OCP_CPM_NA,
-        },
-        { .vendor       = OCP_VENDOR_INVALID
-        }
-};
diff -Nru a/arch/ppc/platforms/85xx/mpc8555_cds.h b/arch/ppc/platforms/85xx/mpc8555_cds.h
--- a/arch/ppc/platforms/85xx/mpc8555_cds.h	2005-03-01 23:38:52 -08:00
+++ b/arch/ppc/platforms/85xx/mpc8555_cds.h	2005-03-01 23:38:52 -08:00
@@ -18,7 +18,7 @@
 #define __MACH_MPC8555CDS_H__
 
 #include <linux/config.h>
-#include <linux/serial.h>
+#include <syslib/ppc85xx_setup.h>
 #include <platforms/85xx/mpc85xx_cds_common.h>
 
 #define CPM_MAP_ADDR	(CCSRBAR + MPC85xx_CPM_OFFSET)
diff -Nru a/arch/ppc/platforms/85xx/mpc8560.c b/arch/ppc/platforms/85xx/mpc8560.c
--- a/arch/ppc/platforms/85xx/mpc8560.c	2005-03-01 23:38:57 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,74 +0,0 @@
-/*
- * arch/ppc/platforms/85xx/mpc8560.c
- * 
- * MPC8560 I/O descriptions
- * 
- * 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.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <asm/mpc85xx.h>
-#include <asm/ocp.h>
-
-/* These should be defined in platform code */
-extern struct ocp_gfar_data mpc85xx_tsec1_def;
-extern struct ocp_gfar_data mpc85xx_tsec2_def;
-extern struct ocp_mpc_i2c_data mpc85xx_i2c1_def;
-
-/* We use offsets for paddr since we do not know at compile time
- * what CCSRBAR is, platform code should fix this up in
- * setup_arch
- *
- * Only the first IRQ is given even if a device has
- * multiple lines associated with ita
- */
-struct ocp_def core_ocp[] = {
-        { .vendor       = OCP_VENDOR_FREESCALE,
-          .function     = OCP_FUNC_IIC,
-          .index        = 0,
-          .paddr        = MPC85xx_IIC1_OFFSET,
-          .irq          = MPC85xx_IRQ_IIC1,
-          .pm           = OCP_CPM_NA,
-          .additions    = &mpc85xx_i2c1_def,
-        },
-        { .vendor       = OCP_VENDOR_FREESCALE,
-          .function     = OCP_FUNC_GFAR,
-          .index        = 0,
-          .paddr        = MPC85xx_ENET1_OFFSET,
-          .irq          = MPC85xx_IRQ_TSEC1_TX,
-          .pm           = OCP_CPM_NA,
-          .additions    = &mpc85xx_tsec1_def,
-        },
-        { .vendor       = OCP_VENDOR_FREESCALE,
-          .function     = OCP_FUNC_GFAR,
-          .index        = 1,
-          .paddr        = MPC85xx_ENET2_OFFSET,
-          .irq          = MPC85xx_IRQ_TSEC2_TX,
-          .pm           = OCP_CPM_NA,
-          .additions    = &mpc85xx_tsec2_def,
-        },
-        { .vendor       = OCP_VENDOR_FREESCALE,
-          .function     = OCP_FUNC_DMA,
-          .index        = 0,
-          .paddr        = MPC85xx_DMA_OFFSET,
-          .irq          = MPC85xx_IRQ_DMA0,
-          .pm           = OCP_CPM_NA,
-        },
-        { .vendor       = OCP_VENDOR_FREESCALE,
-          .function     = OCP_FUNC_PERFMON,
-          .index        = 0,
-          .paddr        = MPC85xx_PERFMON_OFFSET,
-          .irq          = MPC85xx_IRQ_PERFMON,
-          .pm           = OCP_CPM_NA,
-        },
-        { .vendor       = OCP_VENDOR_INVALID
-        }
-};
diff -Nru a/arch/ppc/platforms/85xx/mpc8560_ads.c b/arch/ppc/platforms/85xx/mpc8560_ads.c
--- a/arch/ppc/platforms/85xx/mpc8560_ads.c	2005-03-01 23:39:19 -08:00
+++ b/arch/ppc/platforms/85xx/mpc8560_ads.c	2005-03-01 23:39:19 -08:00
@@ -32,6 +32,7 @@
 #include <linux/serial_core.h>
 #include <linux/initrd.h>
 #include <linux/module.h>
+#include <linux/fsl_devices.h>
 
 #include <asm/system.h>
 #include <asm/pgtable.h>
@@ -48,7 +49,7 @@
 #include <asm/irq.h>
 #include <asm/immap_85xx.h>
 #include <asm/kgdb.h>
-#include <asm/ocp.h>
+#include <asm/ppc_sys.h>
 #include <asm/cpm2.h>
 #include <mm/mmu_decl.h>
 
@@ -58,34 +59,6 @@
 
 extern void cpm2_reset(void);
 
-struct ocp_gfar_data mpc85xx_tsec1_def = {
-        .interruptTransmit = MPC85xx_IRQ_TSEC1_TX,
-        .interruptError = MPC85xx_IRQ_TSEC1_ERROR,
-        .interruptReceive = MPC85xx_IRQ_TSEC1_RX,
-        .interruptPHY = MPC85xx_IRQ_EXT5,
-        .flags = (GFAR_HAS_GIGABIT | GFAR_HAS_MULTI_INTR
-			| GFAR_HAS_RMON | GFAR_HAS_COALESCE
-                        | GFAR_HAS_PHY_INTR),
-        .phyid = 0,
-        .phyregidx = 0,
-};
-
-struct ocp_gfar_data mpc85xx_tsec2_def = {
-        .interruptTransmit = MPC85xx_IRQ_TSEC2_TX,
-        .interruptError = MPC85xx_IRQ_TSEC2_ERROR,
-        .interruptReceive = MPC85xx_IRQ_TSEC2_RX,
-        .interruptPHY = MPC85xx_IRQ_EXT5,
-        .flags = (GFAR_HAS_GIGABIT | GFAR_HAS_MULTI_INTR
-			| GFAR_HAS_RMON | GFAR_HAS_COALESCE
-                        | GFAR_HAS_PHY_INTR),
-        .phyid = 1,
-        .phyregidx = 0,
-};
-
-struct ocp_fs_i2c_data mpc85xx_i2c1_def = {
-	.flags = FS_I2C_SEPARATE_DFSRR,
-};
-
 /* ************************************************************************
  *
  * Setup the architecture
@@ -95,10 +68,9 @@
 static void __init
 mpc8560ads_setup_arch(void)
 {
-	struct ocp_def *def;
-	struct ocp_gfar_data *einfo;
 	bd_t *binfo = (bd_t *) __res;
 	unsigned int freq;
+	struct gianfar_platform_data *pdata;
 
 	cpm2_reset();
 
@@ -117,17 +89,22 @@
 	mpc85xx_setup_hose();
 #endif
 
-	def = ocp_get_one_device(OCP_VENDOR_FREESCALE, OCP_FUNC_GFAR, 0);
-	if (def) {
-		einfo = (struct ocp_gfar_data *) def->additions;
-		memcpy(einfo->mac_addr, binfo->bi_enetaddr, 6);
-	}
-
-	def = ocp_get_one_device(OCP_VENDOR_FREESCALE, OCP_FUNC_GFAR, 1);
-	if (def) {
-		einfo = (struct ocp_gfar_data *) def->additions;
-		memcpy(einfo->mac_addr, binfo->bi_enet1addr, 6);
-	}
+	/* 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);
+
+	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);
 
 #ifdef CONFIG_BLK_DEV_INITRD
 	if (initrd_start)
@@ -139,8 +116,6 @@
 #else
 		ROOT_DEV = Root_HDA1;
 #endif
-
-	ocp_for_each_device(mpc85xx_update_paddr_ocp, &(binfo->bi_immr_base));
 }
 
 static irqreturn_t cpm2_cascade(int irq, void *dev_id, struct pt_regs *regs)
@@ -221,6 +196,8 @@
 		*(char *) (r7 + KERNELBASE) = 0;
 		strcpy(cmd_line, (char *) (r6 + KERNELBASE));
 	}
+
+	identify_ppc_sys_by_id(mfspr(SVR));
 
 	/* setup the PowerPC module struct */
 	ppc_md.setup_arch = mpc8560ads_setup_arch;
diff -Nru 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	2005-03-01 23:39:17 -08:00
+++ b/arch/ppc/platforms/85xx/mpc85xx_ads_common.c	2005-03-01 23:39:17 -08:00
@@ -43,7 +43,6 @@
 #include <asm/mpc85xx.h>
 #include <asm/irq.h>
 #include <asm/immap_85xx.h>
-#include <asm/ocp.h>
 
 #include <mm/mmu_decl.h>
 
diff -Nru 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	2005-03-01 23:39:16 -08:00
+++ b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c	2005-03-01 23:39:16 -08:00
@@ -32,6 +32,7 @@
 #include <linux/initrd.h>
 #include <linux/tty.h>
 #include <linux/serial_core.h>
+#include <linux/fsl_devices.h>
 
 #include <asm/system.h>
 #include <asm/pgtable.h>
@@ -48,7 +49,7 @@
 #include <asm/irq.h>
 #include <asm/immap_85xx.h>
 #include <asm/immap_cpm2.h>
-#include <asm/ocp.h>
+#include <asm/ppc_sys.h>
 #include <asm/kgdb.h>
 
 #include <mm/mmu_decl.h>
@@ -129,32 +130,6 @@
 #endif
 };
 
-struct ocp_gfar_data mpc85xx_tsec1_def = {
-        .interruptTransmit = MPC85xx_IRQ_TSEC1_TX,
-        .interruptError = MPC85xx_IRQ_TSEC1_ERROR,
-        .interruptReceive = MPC85xx_IRQ_TSEC1_RX,
-        .interruptPHY = MPC85xx_IRQ_EXT5,
-        .flags = (GFAR_HAS_GIGABIT | GFAR_HAS_MULTI_INTR |
-                        GFAR_HAS_PHY_INTR),
-        .phyid = 0,
-        .phyregidx = 0,
-};
-
-struct ocp_gfar_data mpc85xx_tsec2_def = {
-        .interruptTransmit = MPC85xx_IRQ_TSEC2_TX,
-        .interruptError = MPC85xx_IRQ_TSEC2_ERROR,
-        .interruptReceive = MPC85xx_IRQ_TSEC2_RX,
-        .interruptPHY = MPC85xx_IRQ_EXT5,
-        .flags = (GFAR_HAS_GIGABIT | GFAR_HAS_MULTI_INTR |
-                        GFAR_HAS_PHY_INTR),
-        .phyid = 1,
-        .phyregidx = 0,
-};
-
-struct ocp_fs_i2c_data mpc85xx_i2c1_def = {
-	.flags = FS_I2C_SEPARATE_DFSRR,
-};
-
 /* ************************************************************************ */
 int
 mpc85xx_cds_show_cpuinfo(struct seq_file *m)
@@ -306,16 +281,17 @@
 #define ARCADIA_HOST_BRIDGE_IDSEL     17
 #define ARCADIA_2ND_BRIDGE_IDSEL     3
 
+extern int mpc85xx_pci1_last_busno;
+
 int
 mpc85xx_exclude_device(u_char bus, u_char devfn)
 {
 	if (bus == 0 && PCI_SLOT(devfn) == 0)
 		return PCIBIOS_DEVICE_NOT_FOUND;
 #ifdef CONFIG_85xx_PCI2
-	/* With the current code we know PCI2 will be bus 2, however this may
-	 * not be guarnteed */
-	if (bus == 2 && PCI_SLOT(devfn) == 0)
-		return PCIBIOS_DEVICE_NOT_FOUND;
+	if (mpc85xx_pci1_last_busno) 
+		if (bus == (mpc85xx_pci1_last_busno + 1) && PCI_SLOT(devfn) == 0)
+			return PCIBIOS_DEVICE_NOT_FOUND;
 #endif
 	/* We explicitly do not go past the Tundra 320 Bridge */
 	if (bus == 1)
@@ -335,10 +311,9 @@
 static void __init
 mpc85xx_cds_setup_arch(void)
 {
-        struct ocp_def *def;
-        struct ocp_gfar_data *einfo;
         bd_t *binfo = (bd_t *) __res;
         unsigned int freq;
+	struct gianfar_platform_data *pdata;
 
         /* get the core frequency */
         freq = binfo->bi_intfreq;
@@ -372,17 +347,23 @@
 	invalidate_tlbcam_entry(NUM_TLBCAMS - 1);
 #endif
 
-        def = ocp_get_one_device(OCP_VENDOR_FREESCALE, OCP_FUNC_GFAR, 0);
-        if (def) {
-                einfo = (struct ocp_gfar_data *) def->additions;
-                memcpy(einfo->mac_addr, binfo->bi_enetaddr, 6);
-        }
+	/* 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);
+
+	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);
 
-        def = ocp_get_one_device(OCP_VENDOR_FREESCALE, OCP_FUNC_GFAR, 1);
-        if (def) {
-                einfo = (struct ocp_gfar_data *) def->additions;
-                memcpy(einfo->mac_addr, binfo->bi_enet1addr, 6);
-        }
 
 #ifdef CONFIG_BLK_DEV_INITRD
         if (initrd_start)
@@ -394,8 +375,6 @@
 #else
                 ROOT_DEV = Root_HDA1;
 #endif
-
-	ocp_for_each_device(mpc85xx_update_paddr_ocp, &(binfo->bi_immr_base));
 }
 
 /* ************************************************************************ */
@@ -418,11 +397,25 @@
 #ifdef CONFIG_SERIAL_TEXT_DEBUG
 	{
 		bd_t *binfo = (bd_t *) __res;
+		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,
-			binfo->bi_immr_base, MPC85xx_CCSRBAR_SIZE, _PAGE_IO, 0);
+			  binfo->bi_immr_base, MPC85xx_CCSRBAR_SIZE, _PAGE_IO, 0);
+
+		memset(&p, 0, sizeof (p));
+		p.iotype = SERIAL_IO_MEM;
+		p.membase = (void *) binfo->bi_immr_base + MPC85xx_UART0_OFFSET;
+		p.uartclk = binfo->bi_busfreq;
 
+		gen550_init(0, &p);
+
+		memset(&p, 0, sizeof (p));
+		p.iotype = SERIAL_IO_MEM;
+		p.membase = (void *) binfo->bi_immr_base + MPC85xx_UART1_OFFSET;
+		p.uartclk = binfo->bi_busfreq;
+
+		gen550_init(1, &p);
 	}
 #endif
 
@@ -443,6 +436,8 @@
                 *(char *) (r7 + KERNELBASE) = 0;
                 strcpy(cmd_line, (char *) (r6 + KERNELBASE));
         }
+
+	identify_ppc_sys_by_id(mfspr(SVR));
 
         /* setup the PowerPC module struct */
         ppc_md.setup_arch = mpc85xx_cds_setup_arch;
diff -Nru a/arch/ppc/platforms/85xx/mpc85xx_cds_common.h b/arch/ppc/platforms/85xx/mpc85xx_cds_common.h
--- a/arch/ppc/platforms/85xx/mpc85xx_cds_common.h	2005-03-01 23:38:53 -08:00
+++ b/arch/ppc/platforms/85xx/mpc85xx_cds_common.h	2005-03-01 23:38:53 -08:00
@@ -60,8 +60,10 @@
 #define MPC85XX_PCI1_IO_SIZE         0x01000000
 
 /* PCI 2 memory map */
-#define MPC85XX_PCI2_LOWER_IO        0x01000000
-#define MPC85XX_PCI2_UPPER_IO        0x01ffffff
+/* Note: the standard PPC fixups will cause IO space to get bumped by
+ * hose->io_base_virt - isa_io_base => MPC85XX_PCI1_IO_SIZE */
+#define MPC85XX_PCI2_LOWER_IO        0x00000000
+#define MPC85XX_PCI2_UPPER_IO        0x00ffffff
 
 #define MPC85XX_PCI2_LOWER_MEM       0xa0000000
 #define MPC85XX_PCI2_UPPER_MEM       0xbfffffff
@@ -70,9 +72,5 @@
 #define MPC85XX_PCI2_MEM_OFFSET      0x00000000
 
 #define MPC85XX_PCI2_IO_SIZE         0x01000000
-
-#define SERIAL_PORT_DFNS		\
-	       STD_UART_OP(0)		\
-	       STD_UART_OP(1)
 
 #endif /* __MACH_MPC85XX_CDS_H__ */
diff -Nru a/arch/ppc/platforms/85xx/mpc85xx_devices.c b/arch/ppc/platforms/85xx/mpc85xx_devices.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/ppc/platforms/85xx/mpc85xx_devices.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,552 @@
+/*
+ * arch/ppc/platforms/85xx/mpc85xx_devices.c
+ *
+ * MPC85xx Device descriptions
+ *
+ * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ *
+ * Copyright 2005 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.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/serial_8250.h>
+#include <linux/fsl_devices.h>
+#include <asm/mpc85xx.h>
+#include <asm/irq.h>
+#include <asm/ppc_sys.h>
+
+/* We use offsets for IORESOURCE_MEM since we do not know at compile time
+ * what CCSRBAR is, will get fixed up by mach_mpc85xx_fixup
+ */
+
+static struct gianfar_platform_data mpc85xx_tsec1_pdata = {
+	.device_flags = FSL_GIANFAR_DEV_HAS_GIGABIT |
+	    FSL_GIANFAR_DEV_HAS_COALESCE | FSL_GIANFAR_DEV_HAS_RMON |
+	    FSL_GIANFAR_DEV_HAS_MULTI_INTR,
+	.phy_reg_addr = MPC85xx_ENET1_OFFSET,
+};
+
+static struct gianfar_platform_data mpc85xx_tsec2_pdata = {
+	.device_flags = FSL_GIANFAR_DEV_HAS_GIGABIT |
+	    FSL_GIANFAR_DEV_HAS_COALESCE | FSL_GIANFAR_DEV_HAS_RMON |
+	    FSL_GIANFAR_DEV_HAS_MULTI_INTR,
+	.phy_reg_addr = MPC85xx_ENET1_OFFSET,
+};
+
+static struct gianfar_platform_data mpc85xx_fec_pdata = {
+	.phy_reg_addr = MPC85xx_ENET1_OFFSET,
+};
+
+static struct fsl_i2c_platform_data mpc85xx_fsl_i2c_pdata = {
+	.device_flags = FSL_I2C_DEV_SEPARATE_DFSRR,
+};
+
+static struct plat_serial8250_port serial_platform_data[] = {
+	[0] = {
+		.mapbase	= 0x4500,
+		.irq		= MPC85xx_IRQ_DUART,
+		.iotype		= UPIO_MEM,
+		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ,
+	},
+	[1] = {
+		.mapbase	= 0x4600,
+		.irq		= MPC85xx_IRQ_DUART,
+		.iotype		= UPIO_MEM,
+		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ,
+	},
+};
+
+struct platform_device ppc_sys_platform_devices[] = {
+	[MPC85xx_TSEC1] = {
+		.name = "fsl-gianfar",
+		.id	= 1,
+		.dev.platform_data = &mpc85xx_tsec1_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_TSEC2] = {
+		.name = "fsl-gianfar",
+		.id	= 2,
+		.dev.platform_data = &mpc85xx_tsec2_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_FEC] =	{
+		.name = "fsl-gianfar",
+		.id	= 3,
+		.dev.platform_data = &mpc85xx_fec_pdata,
+		.num_resources	 = 2,
+		.resource = (struct resource[]) {
+			{
+				.start	= MPC85xx_ENET3_OFFSET,
+				.end	= MPC85xx_ENET3_OFFSET +
+						MPC85xx_ENET3_SIZE - 1,
+				.flags	= IORESOURCE_MEM,
+
+			},
+			{
+				.start	= MPC85xx_IRQ_FEC,
+				.end	= MPC85xx_IRQ_FEC,
+				.flags	= IORESOURCE_IRQ,
+			},
+		},
+	},
+	[MPC85xx_IIC1] = {
+		.name = "fsl-i2c",
+		.id	= 1,
+		.dev.platform_data = &mpc85xx_fsl_i2c_pdata,
+		.num_resources	 = 2,
+		.resource = (struct resource[]) {
+			{
+				.start	= MPC85xx_IIC1_OFFSET,
+				.end	= MPC85xx_IIC1_OFFSET +
+						MPC85xx_IIC1_SIZE - 1,
+				.flags	= IORESOURCE_MEM,
+			},
+			{
+				.start	= MPC85xx_IRQ_IIC1,
+				.end	= MPC85xx_IRQ_IIC1,
+				.flags	= IORESOURCE_IRQ,
+			},
+		},
+	},
+	[MPC85xx_DMA0] = {
+		.name = "fsl-dma",
+		.id	= 0,
+		.num_resources	 = 2,
+		.resource = (struct resource[]) {
+			{
+				.start	= MPC85xx_DMA0_OFFSET,
+				.end	= MPC85xx_DMA0_OFFSET +
+						MPC85xx_DMA0_SIZE - 1,
+				.flags	= IORESOURCE_MEM,
+			},
+			{
+				.start	= MPC85xx_IRQ_DMA0,
+				.end	= MPC85xx_IRQ_DMA0,
+				.flags	= IORESOURCE_IRQ,
+			},
+		},
+	},
+	[MPC85xx_DMA1] = {
+		.name = "fsl-dma",
+		.id	= 1,
+		.num_resources	 = 2,
+		.resource = (struct resource[]) {
+			{
+				.start	= MPC85xx_DMA1_OFFSET,
+				.end	= MPC85xx_DMA1_OFFSET +
+						MPC85xx_DMA1_SIZE - 1,
+				.flags	= IORESOURCE_MEM,
+			},
+			{
+				.start	= MPC85xx_IRQ_DMA1,
+				.end	= MPC85xx_IRQ_DMA1,
+				.flags	= IORESOURCE_IRQ,
+			},
+		},
+	},
+	[MPC85xx_DMA2] = {
+		.name = "fsl-dma",
+		.id	= 2,
+		.num_resources	 = 2,
+		.resource = (struct resource[]) {
+			{
+				.start	= MPC85xx_DMA2_OFFSET,
+				.end	= MPC85xx_DMA2_OFFSET +
+						MPC85xx_DMA2_SIZE - 1,
+				.flags	= IORESOURCE_MEM,
+			},
+			{
+				.start	= MPC85xx_IRQ_DMA2,
+				.end	= MPC85xx_IRQ_DMA2,
+				.flags	= IORESOURCE_IRQ,
+			},
+		},
+	},
+	[MPC85xx_DMA3] = {
+		.name = "fsl-dma",
+		.id	= 3,
+		.num_resources	 = 2,
+		.resource = (struct resource[]) {
+			{
+				.start	= MPC85xx_DMA3_OFFSET,
+				.end	= MPC85xx_DMA3_OFFSET +
+						MPC85xx_DMA3_SIZE - 1,
+				.flags	= IORESOURCE_MEM,
+			},
+			{
+				.start	= MPC85xx_IRQ_DMA3,
+				.end	= MPC85xx_IRQ_DMA3,
+				.flags	= IORESOURCE_IRQ,
+			},
+		},
+	},
+	[MPC85xx_DUART] = {
+		.name = "serial8250",
+		.id	= 0,
+		.dev.platform_data = serial_platform_data,
+	},
+	[MPC85xx_PERFMON] = {
+		.name = "fsl-perfmon",
+		.id	= 1,
+		.num_resources	 = 2,
+		.resource = (struct resource[]) {
+			{
+				.start	= MPC85xx_PERFMON_OFFSET,
+				.end	= MPC85xx_PERFMON_OFFSET +
+						MPC85xx_PERFMON_SIZE - 1,
+				.flags	= IORESOURCE_MEM,
+			},
+			{
+				.start	= MPC85xx_IRQ_PERFMON,
+				.end	= MPC85xx_IRQ_PERFMON,
+				.flags	= IORESOURCE_IRQ,
+			},
+		},
+	},
+	[MPC85xx_SEC2] = {
+		.name = "fsl-sec2",
+		.id	= 1,
+		.num_resources	 = 2,
+		.resource = (struct resource[]) {
+			{
+				.start	= MPC85xx_SEC2_OFFSET,
+				.end	= MPC85xx_SEC2_OFFSET +
+						MPC85xx_SEC2_SIZE - 1,
+				.flags	= IORESOURCE_MEM,
+			},
+			{
+				.start	= MPC85xx_IRQ_SEC2,
+				.end	= MPC85xx_IRQ_SEC2,
+				.flags	= IORESOURCE_IRQ,
+			},
+		},
+	},
+#ifdef CONFIG_CPM2
+	[MPC85xx_CPM_FCC1] = {
+		.name = "fsl-cpm-fcc",
+		.id	= 1,
+		.num_resources	 = 3,
+		.resource = (struct resource[]) {
+			{
+				.start	= 0x91300,
+				.end	= 0x9131F,
+				.flags	= IORESOURCE_MEM,
+			},
+			{
+				.start	= 0x91380,
+				.end	= 0x9139F,
+				.flags	= IORESOURCE_MEM,
+			},
+			{
+				.start	= SIU_INT_FCC1,
+				.end	= SIU_INT_FCC1,
+				.flags	= IORESOURCE_IRQ,
+			},
+		},
+	},
+	[MPC85xx_CPM_FCC2] = {
+		.name = "fsl-cpm-fcc",
+		.id	= 2,
+		.num_resources	 = 3,
+		.resource = (struct resource[]) {
+			{
+				.start	= 0x91320,
+				.end	= 0x9133F,
+				.flags	= IORESOURCE_MEM,
+			},
+			{
+				.start	= 0x913A0,
+				.end	= 0x913CF,
+				.flags	= IORESOURCE_MEM,
+			},
+			{
+				.start	= SIU_INT_FCC2,
+				.end	= SIU_INT_FCC2,
+				.flags	= IORESOURCE_IRQ,
+			},
+		},
+	},
+	[MPC85xx_CPM_FCC3] = {
+		.name = "fsl-cpm-fcc",
+		.id	= 3,
+		.num_resources	 = 3,
+		.resource = (struct resource[]) {
+			{
+				.start	= 0x91340,
+				.end	= 0x9135F,
+				.flags	= IORESOURCE_MEM,
+			},
+			{
+				.start	= 0x913D0,
+				.end	= 0x913FF,
+				.flags	= IORESOURCE_MEM,
+			},
+			{
+				.start	= SIU_INT_FCC3,
+				.end	= SIU_INT_FCC3,
+				.flags	= IORESOURCE_IRQ,
+			},
+		},
+	},
+	[MPC85xx_CPM_I2C] = {
+		.name = "fsl-cpm-i2c",
+		.id	= 1,
+		.num_resources	 = 2,
+		.resource = (struct resource[]) {
+			{
+				.start	= 0x91860,
+				.end	= 0x918BF,
+				.flags	= IORESOURCE_MEM,
+			},
+			{
+				.start	= SIU_INT_I2C,
+				.end	= SIU_INT_I2C,
+				.flags	= IORESOURCE_IRQ,
+			},
+		},
+	},
+	[MPC85xx_CPM_SCC1] = {
+		.name = "fsl-cpm-scc",
+		.id	= 1,
+		.num_resources	 = 2,
+		.resource = (struct resource[]) {
+			{
+				.start	= 0x91A00,
+				.end	= 0x91A1F,
+				.flags	= IORESOURCE_MEM,
+			},
+			{
+				.start	= SIU_INT_SCC1,
+				.end	= SIU_INT_SCC1,
+				.flags	= IORESOURCE_IRQ,
+			},
+		},
+	},
+	[MPC85xx_CPM_SCC2] = {
+		.name = "fsl-cpm-scc",
+		.id	= 2,
+		.num_resources	 = 2,
+		.resource = (struct resource[]) {
+			{
+				.start	= 0x91A20,
+				.end	= 0x91A3F,
+				.flags	= IORESOURCE_MEM,
+			},
+			{
+				.start	= SIU_INT_SCC2,
+				.end	= SIU_INT_SCC2,
+				.flags	= IORESOURCE_IRQ,
+			},
+		},
+	},
+	[MPC85xx_CPM_SCC3] = {
+		.name = "fsl-cpm-scc",
+		.id	= 3,
+		.num_resources	 = 2,
+		.resource = (struct resource[]) {
+			{
+				.start	= 0x91A40,
+				.end	= 0x91A5F,
+				.flags	= IORESOURCE_MEM,
+			},
+			{
+				.start	= SIU_INT_SCC3,
+				.end	= SIU_INT_SCC3,
+				.flags	= IORESOURCE_IRQ,
+			},
+		},
+	},
+	[MPC85xx_CPM_SCC4] = {
+		.name = "fsl-cpm-scc",
+		.id	= 4,
+		.num_resources	 = 2,
+		.resource = (struct resource[]) {
+			{
+				.start	= 0x91A60,
+				.end	= 0x91A7F,
+				.flags	= IORESOURCE_MEM,
+			},
+			{
+				.start	= SIU_INT_SCC4,
+				.end	= SIU_INT_SCC4,
+				.flags	= IORESOURCE_IRQ,
+			},
+		},
+	},
+	[MPC85xx_CPM_SPI] = {
+		.name = "fsl-cpm-spi",
+		.id	= 1,
+		.num_resources	 = 2,
+		.resource = (struct resource[]) {
+			{
+				.start	= 0x91AA0,
+				.end	= 0x91AFF,
+				.flags	= IORESOURCE_MEM,
+			},
+			{
+				.start	= SIU_INT_SPI,
+				.end	= SIU_INT_SPI,
+				.flags	= IORESOURCE_IRQ,
+			},
+		},
+	},
+	[MPC85xx_CPM_MCC1] = {
+		.name = "fsl-cpm-mcc",
+		.id	= 1,
+		.num_resources	 = 2,
+		.resource = (struct resource[]) {
+			{
+				.start	= 0x91B30,
+				.end	= 0x91B3F,
+				.flags	= IORESOURCE_MEM,
+			},
+			{
+				.start	= SIU_INT_MCC1,
+				.end	= SIU_INT_MCC1,
+				.flags	= IORESOURCE_IRQ,
+			},
+		},
+	},
+	[MPC85xx_CPM_MCC2] = {
+		.name = "fsl-cpm-mcc",
+		.id	= 2,
+		.num_resources	 = 2,
+		.resource = (struct resource[]) {
+			{
+				.start	= 0x91B50,
+				.end	= 0x91B5F,
+				.flags	= IORESOURCE_MEM,
+			},
+			{
+				.start	= SIU_INT_MCC2,
+				.end	= SIU_INT_MCC2,
+				.flags	= IORESOURCE_IRQ,
+			},
+		},
+	},
+	[MPC85xx_CPM_SMC1] = {
+		.name = "fsl-cpm-smc",
+		.id	= 1,
+		.num_resources	 = 2,
+		.resource = (struct resource[]) {
+			{
+				.start	= 0x91A80,
+				.end	= 0x91A8F,
+				.flags	= IORESOURCE_MEM,
+			},
+			{
+				.start	= SIU_INT_SMC1,
+				.end	= SIU_INT_SMC1,
+				.flags	= IORESOURCE_IRQ,
+			},
+		},
+	},
+	[MPC85xx_CPM_SMC2] = {
+		.name = "fsl-cpm-smc",
+		.id	= 2,
+		.num_resources	 = 2,
+		.resource = (struct resource[]) {
+			{
+				.start	= 0x91A90,
+				.end	= 0x91A9F,
+				.flags	= IORESOURCE_MEM,
+			},
+			{
+				.start	= SIU_INT_SMC2,
+				.end	= SIU_INT_SMC2,
+				.flags	= IORESOURCE_IRQ,
+			},
+		},
+	},
+	[MPC85xx_CPM_USB] = {
+		.name = "fsl-cpm-usb",
+		.id	= 2,
+		.num_resources	 = 2,
+		.resource = (struct resource[]) {
+			{
+				.start	= 0x91B60,
+				.end	= 0x91B7F,
+				.flags	= IORESOURCE_MEM,
+			},
+			{
+				.start	= SIU_INT_USB,
+				.end	= SIU_INT_USB,
+				.flags	= IORESOURCE_IRQ,
+			},
+		},
+	},
+#endif /* CONFIG_CPM2 */
+};
+
+static int __init mach_mpc85xx_fixup(struct platform_device *pdev)
+{
+	ppc_sys_fixup_mem_resource(pdev, CCSRBAR);
+	return 0;
+}
+
+static int __init mach_mpc85xx_init(void)
+{
+	ppc_sys_device_fixup = mach_mpc85xx_fixup;
+	return 0;
+}
+
+postcore_initcall(mach_mpc85xx_init);
diff -Nru a/arch/ppc/platforms/85xx/mpc85xx_sys.c b/arch/ppc/platforms/85xx/mpc85xx_sys.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/ppc/platforms/85xx/mpc85xx_sys.c	2005-03-01 23:39:26 -08:00
@@ -0,0 +1,118 @@
+/*
+ * arch/ppc/platforms/85xx/mpc85xx_sys.c
+ *
+ * MPC85xx System descriptions
+ *
+ * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ *
+ * Copyright 2005 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.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <asm/ppc_sys.h>
+
+struct ppc_sys_spec *cur_ppc_sys_spec;
+struct ppc_sys_spec ppc_sys_specs[] = {
+	{
+		.ppc_sys_name	= "MPC8540",
+		.mask 		= 0xFFFF0000,
+		.value 		= 0x80300000,
+		.num_devices	= 10,
+		.device_list	= (enum ppc_sys_devices[])
+		{
+			MPC85xx_TSEC1, MPC85xx_TSEC2, MPC85xx_FEC, MPC85xx_IIC1,
+			MPC85xx_DMA0, MPC85xx_DMA1, MPC85xx_DMA2, MPC85xx_DMA3,
+			MPC85xx_PERFMON, MPC85xx_DUART,
+		},
+	},
+	{
+		.ppc_sys_name	= "MPC8560",
+		.mask 		= 0xFFFF0000,
+		.value 		= 0x80700000,
+		.num_devices	= 19,
+		.device_list	= (enum ppc_sys_devices[])
+		{
+			MPC85xx_TSEC1, MPC85xx_TSEC2, MPC85xx_IIC1,
+			MPC85xx_DMA0, MPC85xx_DMA1, MPC85xx_DMA2, MPC85xx_DMA3,
+			MPC85xx_PERFMON,
+			MPC85xx_CPM_SPI, MPC85xx_CPM_I2C, MPC85xx_CPM_SCC1,
+			MPC85xx_CPM_SCC2, MPC85xx_CPM_SCC3, MPC85xx_CPM_SCC4,
+			MPC85xx_CPM_FCC1, MPC85xx_CPM_FCC2, MPC85xx_CPM_FCC3,
+			MPC85xx_CPM_MCC1, MPC85xx_CPM_MCC2,
+		},
+	},
+	{
+		.ppc_sys_name	= "MPC8541",
+		.mask 		= 0xFFFF0000,
+		.value 		= 0x80720000,
+		.num_devices	= 13,
+		.device_list	= (enum ppc_sys_devices[])
+		{
+			MPC85xx_TSEC1, MPC85xx_TSEC2, MPC85xx_IIC1,
+			MPC85xx_DMA0, MPC85xx_DMA1, MPC85xx_DMA2, MPC85xx_DMA3,
+			MPC85xx_PERFMON, MPC85xx_DUART,
+			MPC85xx_CPM_SPI, MPC85xx_CPM_I2C,
+			MPC85xx_CPM_FCC1, MPC85xx_CPM_FCC2,
+		},
+	},
+	{
+		.ppc_sys_name	= "MPC8541E",
+		.mask 		= 0xFFFF0000,
+		.value 		= 0x807A0000,
+		.num_devices	= 14,
+		.device_list	= (enum ppc_sys_devices[])
+		{
+			MPC85xx_TSEC1, MPC85xx_TSEC2, MPC85xx_IIC1,
+			MPC85xx_DMA0, MPC85xx_DMA1, MPC85xx_DMA2, MPC85xx_DMA3,
+			MPC85xx_PERFMON, MPC85xx_DUART, MPC85xx_SEC2,
+			MPC85xx_CPM_SPI, MPC85xx_CPM_I2C,
+			MPC85xx_CPM_FCC1, MPC85xx_CPM_FCC2,
+		},
+	},
+	{
+		.ppc_sys_name	= "MPC8555",
+		.mask 		= 0xFFFF0000,
+		.value 		= 0x80710000,
+		.num_devices	= 20,
+		.device_list	= (enum ppc_sys_devices[])
+		{
+			MPC85xx_TSEC1, MPC85xx_TSEC2, MPC85xx_IIC1,
+			MPC85xx_DMA0, MPC85xx_DMA1, MPC85xx_DMA2, MPC85xx_DMA3,
+			MPC85xx_PERFMON, MPC85xx_DUART,
+			MPC85xx_CPM_SPI, MPC85xx_CPM_I2C, MPC85xx_CPM_SCC1,
+			MPC85xx_CPM_SCC2, MPC85xx_CPM_SCC3,
+			MPC85xx_CPM_FCC1, MPC85xx_CPM_FCC2, MPC85xx_CPM_FCC3,
+			MPC85xx_CPM_SMC1, MPC85xx_CPM_SMC2,
+			MPC85xx_CPM_USB,
+		},
+	},
+	{
+		.ppc_sys_name	= "MPC8555E",
+		.mask 		= 0xFFFF0000,
+		.value 		= 0x80790000,
+		.num_devices	= 21,
+		.device_list	= (enum ppc_sys_devices[])
+		{
+			MPC85xx_TSEC1, MPC85xx_TSEC2, MPC85xx_IIC1,
+			MPC85xx_DMA0, MPC85xx_DMA1, MPC85xx_DMA2, MPC85xx_DMA3,
+			MPC85xx_PERFMON, MPC85xx_DUART, MPC85xx_SEC2,
+			MPC85xx_CPM_SPI, MPC85xx_CPM_I2C, MPC85xx_CPM_SCC1,
+			MPC85xx_CPM_SCC2, MPC85xx_CPM_SCC3,
+			MPC85xx_CPM_FCC1, MPC85xx_CPM_FCC2, MPC85xx_CPM_FCC3,
+			MPC85xx_CPM_SMC1, MPC85xx_CPM_SMC2,
+			MPC85xx_CPM_USB,
+		},
+	},
+	{	/* default match */
+		.ppc_sys_name	= "",
+		.mask 		= 0x00000000,
+		.value 		= 0x00000000,
+	},
+};
diff -Nru a/arch/ppc/platforms/85xx/sbc8560.c b/arch/ppc/platforms/85xx/sbc8560.c
--- a/arch/ppc/platforms/85xx/sbc8560.c	2005-03-01 23:39:18 -08:00
+++ b/arch/ppc/platforms/85xx/sbc8560.c	2005-03-01 23:39:18 -08:00
@@ -32,6 +32,7 @@
 #include <linux/serial_core.h>
 #include <linux/initrd.h>
 #include <linux/module.h>
+#include <linux/fsl_devices.h>
 
 #include <asm/system.h>
 #include <asm/pgtable.h>
@@ -48,37 +49,12 @@
 #include <asm/irq.h>
 #include <asm/immap_85xx.h>
 #include <asm/kgdb.h>
-#include <asm/ocp.h>
+#include <asm/ppc_sys.h>
 #include <mm/mmu_decl.h>
 
 #include <syslib/ppc85xx_common.h>
 #include <syslib/ppc85xx_setup.h>
 
-struct ocp_gfar_data mpc85xx_tsec1_def = {
-	.interruptTransmit = MPC85xx_IRQ_TSEC1_TX,
-	.interruptError = MPC85xx_IRQ_TSEC1_ERROR,
-	.interruptReceive = MPC85xx_IRQ_TSEC1_RX,
-	.interruptPHY = MPC85xx_IRQ_EXT6,
-	.flags = (GFAR_HAS_GIGABIT | GFAR_HAS_MULTI_INTR | GFAR_HAS_PHY_INTR),
-	.phyid = 25,
-	.phyregidx = 0,
-};
-
-struct ocp_gfar_data mpc85xx_tsec2_def = {
-	.interruptTransmit = MPC85xx_IRQ_TSEC2_TX,
-	.interruptError = MPC85xx_IRQ_TSEC2_ERROR,
-	.interruptReceive = MPC85xx_IRQ_TSEC2_RX,
-	.interruptPHY = MPC85xx_IRQ_EXT7,
-	.flags = (GFAR_HAS_GIGABIT | GFAR_HAS_MULTI_INTR | GFAR_HAS_PHY_INTR),
-	.phyid = 26,
-	.phyregidx = 0,
-};
-
-struct ocp_fs_i2c_data mpc85xx_i2c1_def = {
-	.flags = FS_I2C_SEPARATE_DFSRR,
-};
-
-
 #ifdef CONFIG_SERIAL_8250
 static void __init
 sbc8560_early_serial_map(void)
@@ -125,10 +101,9 @@
 static void __init
 sbc8560_setup_arch(void)
 {
-	struct ocp_def *def;
-	struct ocp_gfar_data *einfo;
 	bd_t *binfo = (bd_t *) __res;
 	unsigned int freq;
+	struct gianfar_platform_data *pdata;
 
 	/* get the core frequency */
 	freq = binfo->bi_intfreq;
@@ -153,18 +128,22 @@
 	invalidate_tlbcam_entry(NUM_TLBCAMS - 1);
 #endif
 
-	/* Set up MAC addresses for the Ethernet devices */
-	def = ocp_get_one_device(OCP_VENDOR_FREESCALE, OCP_FUNC_GFAR, 0);
-	if (def) {
-		einfo = (struct ocp_gfar_data *) def->additions;
-		memcpy(einfo->mac_addr, binfo->bi_enetaddr, 6);
-	}
-
-	def = ocp_get_one_device(OCP_VENDOR_FREESCALE, OCP_FUNC_GFAR, 1);
-	if (def) {
-		einfo = (struct ocp_gfar_data *) def->additions;
-		memcpy(einfo->mac_addr, binfo->bi_enet1addr, 6);
-	}
+	/* 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);
+
+	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);
 
 #ifdef CONFIG_BLK_DEV_INITRD
 	if (initrd_start)
@@ -176,8 +155,6 @@
 #else
 		ROOT_DEV = Root_HDA1;
 #endif
-
-	ocp_for_each_device(mpc85xx_update_paddr_ocp, &(binfo->bi_immr_base));
 }
 
 /* ************************************************************************ */
@@ -220,6 +197,8 @@
 		*(char *) (r7 + KERNELBASE) = 0;
 		strcpy(cmd_line, (char *) (r6 + KERNELBASE));
 	}
+
+	identify_ppc_sys_by_id(mfspr(SVR));
 
 	/* setup the PowerPC module struct */
 	ppc_md.setup_arch = sbc8560_setup_arch;
diff -Nru a/arch/ppc/platforms/85xx/sbc85xx.c b/arch/ppc/platforms/85xx/sbc85xx.c
--- a/arch/ppc/platforms/85xx/sbc85xx.c	2005-03-01 23:39:07 -08:00
+++ b/arch/ppc/platforms/85xx/sbc85xx.c	2005-03-01 23:39:07 -08:00
@@ -42,7 +42,6 @@
 #include <asm/mpc85xx.h>
 #include <asm/irq.h>
 #include <asm/immap_85xx.h>
-#include <asm/ocp.h>
 
 #include <mm/mmu_decl.h>
 
diff -Nru a/arch/ppc/platforms/85xx/stx_gp3.c b/arch/ppc/platforms/85xx/stx_gp3.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/ppc/platforms/85xx/stx_gp3.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,381 @@
+/*
+ * arch/ppc/platforms/85xx/stx_gp3.c
+ *
+ * STx GP3 board specific routines
+ *
+ * Dan Malek <dan@embeddededge.com>
+ * Copyright 2004 Embedded Edge, LLC
+ *
+ * Copied from mpc8560_ads.c
+ * Copyright 2002, 2003 Motorola Inc.
+ *
+ * Ported to 2.6, Matt Porter <mporter@kernel.crashing.org>
+ * Copyright 2004-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 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/major.h>
+#include <linux/blkdev.h>
+#include <linux/console.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/root_dev.h>
+#include <linux/seq_file.h>
+#include <linux/serial.h>
+#include <linux/module.h>
+#include <linux/fsl_devices.h>
+
+#include <asm/system.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/atomic.h>
+#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/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)];
+
+#ifndef CONFIG_PCI
+unsigned long isa_io_base = 0;
+unsigned long isa_mem_base = 0;
+unsigned long pci_dram_offset = 0;
+#endif
+
+/* 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 */
+	0x0,						/* External  0: */
+#if defined(CONFIG_PCI)
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* External 1: PCI slot 0 */
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* External 2: PCI slot 1 */
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* External 3: PCI slot 2 */
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* External 4: PCI slot 3 */
+#else
+	0x0,				/* External  1: */
+	0x0,				/* External  2: */
+	0x0,				/* External  3: */
+	0x0,				/* External  4: */
+#endif
+	0x0,				/* External  5: */
+	0x0,				/* External  6: */
+	0x0,				/* External  7: */
+	0x0,				/* External  8: */
+	0x0,				/* External  9: */
+	0x0,				/* External 10: */
+	0x0,				/* External 11: */
+};
+
+/*
+ * Setup the architecture
+ */
+static void __init
+gp3_setup_arch(void)
+{
+	bd_t *binfo = (bd_t *) __res;
+	unsigned int freq;
+	struct gianfar_platform_data *pdata;
+
+	cpm2_reset();
+
+	/* get the core frequency */
+	freq = binfo->bi_intfreq;
+
+	if (ppc_md.progress)
+		ppc_md.progress("gp3_setup_arch()", 0);
+
+	/* Set loops_per_jiffy to a half-way reasonable value,
+	   for use until calibrate_delay gets called. */
+	loops_per_jiffy = freq / HZ;
+
+#ifdef CONFIG_PCI
+	/* setup PCI host bridges */
+	mpc85xx_setup_hose();
+#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 = 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);
+
+#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
+
+	printk ("bi_immr_base = %8.8lx\n", binfo->bi_immr_base);
+}
+
+static irqreturn_t cpm2_cascade(int irq, void *dev_id, struct pt_regs *regs)
+{
+	while ((irq = cpm2_get_irq(regs)) >= 0)
+		__do_IRQ(irq, regs);
+
+	return IRQ_HANDLED;
+}
+
+static struct irqaction cpm2_irqaction = {
+	.handler	= cpm2_cascade,
+	.flags		= SA_INTERRUPT,
+	.mask		= CPU_MASK_NONE,
+	.name		= "cpm2_cascade",
+};
+
+static void __init
+gp3_init_IRQ(void)
+{
+	int i;
+	volatile cpm2_map_t *immap = cpm2_immr;
+	bd_t *binfo = (bd_t *) __res;
+
+	/*
+	 * Setup OpenPIC
+	 */
+
+	/* Determine the Physical Address of the OpenPIC regs */
+	phys_addr_t OpenPIC_PAddr =
+	    binfo->bi_immr_base + MPC85xx_OPENPIC_OFFSET;
+	OpenPIC_Addr = ioremap(OpenPIC_PAddr, MPC85xx_OPENPIC_SIZE);
+	OpenPIC_InitSenses = gp3_openpic_initsenses;
+	OpenPIC_NumInitSenses = sizeof (gp3_openpic_initsenses);
+
+	/* 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);
+
+	/*
+	 * Let openpic interrupts starting from an offset, to
+	 * leave space for cascading interrupts underneath.
+	 */
+	openpic_init(MPC85xx_OPENPIC_IRQ_OFFSET);
+
+	/*
+	 * Setup CPM2 PIC
+	 */
+
+	/* disable all CPM interupts */
+	immap->im_intctl.ic_simrh = 0x0;
+	immap->im_intctl.ic_simrl = 0x0;
+
+	for (i = CPM_IRQ_OFFSET; i < (NR_CPM_INTS + CPM_IRQ_OFFSET); i++)
+		irq_desc[i].handler = &cpm2_pic;
+
+	/*
+	 * Initialize the default interrupt mapping priorities,
+	 * in case the boot rom changed something on us.
+	 */
+	immap->im_intctl.ic_sicr = 0;
+	immap->im_intctl.ic_scprrh = 0x05309770;
+	immap->im_intctl.ic_scprrl = 0x05309770;
+
+	setup_irq(MPC85xx_IRQ_CPM, &cpm2_irqaction);
+
+	return;
+}
+
+static int
+gp3_show_cpuinfo(struct seq_file *m)
+{
+	uint pvid, svid, phid1;
+	bd_t *binfo = (bd_t *) __res;
+	uint	memsize;
+	unsigned int freq;
+	extern unsigned long total_memory;	/* in mm/init */
+
+	/* get the core frequency */
+	freq = binfo->bi_intfreq;
+
+	pvid = mfspr(PVR);
+	svid = mfspr(SVR);
+
+	memsize = total_memory;
+
+	seq_printf(m, "Vendor\t\t: RPC Electronics STx \n");
+
+	switch (svid & 0xffff0000) {
+	case SVR_8540:
+		seq_printf(m, "Machine\t\t: GP3 - MPC8540\n");
+		break;
+	case SVR_8560:
+		seq_printf(m, "Machine\t\t: GP3 - MPC8560\n");
+		break;
+	default:
+		seq_printf(m, "Machine\t\t: unknown\n");
+		break;
+	}
+	seq_printf(m, "bus freq\t: %u.%.6u MHz\n", freq / 1000000,
+		   freq % 1000000);
+	seq_printf(m, "PVR\t\t: 0x%x\n", pvid);
+	seq_printf(m, "SVR\t\t: 0x%x\n", svid);
+
+	/* Display cpu Pll setting */
+	phid1 = mfspr(HID1);
+	seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f));
+
+	/* Display the amount of memory */
+	seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024));
+
+	return 0;
+}
+
+#ifdef CONFIG_PCI
+int mpc85xx_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
+	     */
+	{
+		{PIRQA, PIRQB, PIRQC, PIRQD},
+		{PIRQD, PIRQA, PIRQB, PIRQC},
+		{PIRQC, PIRQD, PIRQA, PIRQB},
+		{PIRQB, PIRQC, PIRQD, PIRQA},
+	};
+
+	const long min_idsel = 12, max_idsel = 15, irqs_per_slot = 4;
+	return PCI_IRQ_TABLE_LOOKUP;
+}
+
+int mpc85xx_exclude_device(u_char bus, u_char devfn)
+{
+	if (bus == 0 && PCI_SLOT(devfn) == 0)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	else
+		return PCIBIOS_SUCCESSFUL;
+}
+#endif /* CONFIG_PCI */
+
+void __init
+platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
+	      unsigned long r6, unsigned long r7)
+{
+	/* parse_bootinfo must always be called first */
+	parse_bootinfo(find_bootinfo());
+
+	/*
+	 * If we were passed in a board information, copy it into the
+	 * residual data area.
+	 */
+	if (r3) {
+		memcpy((void *) __res, (void *) (r3 + KERNELBASE),
+		       sizeof (bd_t));
+
+	}
+#if defined(CONFIG_BLK_DEV_INITRD)
+	/*
+	 * If the init RAM disk has been configured in, and there's a valid
+	 * starting address for it, set it up.
+	 */
+	if (r4) {
+		initrd_start = r4 + KERNELBASE;
+		initrd_end = r5 + KERNELBASE;
+	}
+#endif				/* CONFIG_BLK_DEV_INITRD */
+
+	/* Copy the kernel command line arguments to a safe place. */
+
+	if (r6) {
+		*(char *) (r7 + KERNELBASE) = 0;
+		strcpy(cmd_line, (char *) (r6 + KERNELBASE));
+	}
+
+	identify_ppc_sys_by_id(mfspr(SVR));
+
+	/* setup the PowerPC module struct */
+	ppc_md.setup_arch = gp3_setup_arch;
+	ppc_md.show_cpuinfo = gp3_show_cpuinfo;
+
+	ppc_md.init_IRQ = gp3_init_IRQ;
+	ppc_md.get_irq = openpic_get_irq;
+
+	ppc_md.restart = mpc85xx_restart;
+	ppc_md.power_off = mpc85xx_power_off;
+	ppc_md.halt = mpc85xx_halt;
+
+	ppc_md.find_end_of_memory = mpc85xx_find_end_of_memory;
+
+	ppc_md.calibrate_decr = mpc85xx_calibrate_decr;
+
+	if (ppc_md.progress)
+		ppc_md.progress("platform_init(): exit", 0);
+
+	return;
+}
diff -Nru a/arch/ppc/platforms/85xx/stx_gp3.h b/arch/ppc/platforms/85xx/stx_gp3.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/ppc/platforms/85xx/stx_gp3.h	2005-03-01 23:39:26 -08:00
@@ -0,0 +1,74 @@
+/*
+ * arch/ppc/platforms/stx8560_gp3.h
+ *
+ * STx GP3 board definitions
+ *
+ * Dan Malek (dan@embeddededge.com)
+ * Copyright 2004 Embedded Edge, LLC
+ *
+ * Ported to 2.6, Matt Porter <mporter@kernel.crashing.org>
+ * Copyright 2004-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 as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
+
+#ifndef __MACH_STX_GP3_H
+#define __MACH_STX_GP3_H
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/seq_file.h>
+#include <asm/ppcboot.h>
+
+#define BOARD_CCSRBAR		((uint)0xe0000000)
+#define CCSRBAR_SIZE		((uint)1024*1024)
+
+#define CPM_MAP_ADDR		(CCSRBAR + MPC85xx_CPM_OFFSET)
+
+#define BCSR_ADDR		((uint)0xfc000000)
+#define BCSR_SIZE		((uint)(16 * 1024))
+
+#define BCSR_TSEC1_RESET	0x00000080
+#define BCSR_TSEC2_RESET	0x00000040
+#define BCSR_LED1		0x00000008
+#define BCSR_LED2		0x00000004
+#define BCSR_LED3		0x00000002
+#define BCSR_LED4		0x00000001
+
+extern void mpc85xx_setup_hose(void) __init;
+extern void mpc85xx_restart(char *cmd);
+extern void mpc85xx_power_off(void);
+extern void mpc85xx_halt(void);
+extern int mpc85xx_show_cpuinfo(struct seq_file *m);
+extern void mpc85xx_init_IRQ(void) __init;
+extern unsigned long mpc85xx_find_end_of_memory(void) __init;
+extern void mpc85xx_calibrate_decr(void) __init;
+
+#define PCI_CFG_ADDR_OFFSET	(0x8000)
+#define PCI_CFG_DATA_OFFSET	(0x8004)
+
+/* PCI interrupt controller */
+#define PIRQA		MPC85xx_IRQ_EXT1
+#define PIRQB		MPC85xx_IRQ_EXT2
+#define PIRQC		MPC85xx_IRQ_EXT3
+#define PIRQD		MPC85xx_IRQ_EXT4
+#define PCI_MIN_IDSEL	16
+#define PCI_MAX_IDSEL	19
+#define PCI_IRQ_SLOT	4
+
+#define MPC85XX_PCI1_LOWER_IO	0x00000000
+#define MPC85XX_PCI1_UPPER_IO	0x00ffffff
+
+#define MPC85XX_PCI1_LOWER_MEM	0x80000000
+#define MPC85XX_PCI1_UPPER_MEM	0x9fffffff
+
+#define MPC85XX_PCI1_IO_BASE	0xe2000000
+#define MPC85XX_PCI1_MEM_OFFSET	0x00000000
+
+#define MPC85XX_PCI1_IO_SIZE	0x01000000
+
+#endif /* __MACH_STX_GP3_H */
diff -Nru a/arch/ppc/platforms/Makefile b/arch/ppc/platforms/Makefile
--- a/arch/ppc/platforms/Makefile	2005-03-01 23:39:18 -08:00
+++ b/arch/ppc/platforms/Makefile	2005-03-01 23:39:18 -08:00
@@ -11,7 +11,7 @@
 endif
 obj-$(CONFIG_PPC_PMAC)		+= pmac_pic.o pmac_setup.o pmac_time.o \
 					pmac_feature.o pmac_pci.o pmac_sleep.o \
-					pmac_low_i2c.o
+					pmac_low_i2c.o pmac_cache.o
 obj-$(CONFIG_PPC_CHRP)		+= chrp_setup.o chrp_time.o chrp_pci.o
 obj-$(CONFIG_PPC_PREP)		+= prep_pci.o prep_setup.o
 ifeq ($(CONFIG_PPC_PMAC),y)
@@ -23,10 +23,13 @@
 obj-$(CONFIG_ADIR)		+= adir_setup.o adir_pic.o adir_pci.o
 obj-$(CONFIG_PQ2ADS)		+= pq2ads.o
 obj-$(CONFIG_TQM8260)		+= tqm8260_setup.o
-obj-$(CONFIG_EV64260)		+= ev64260_setup.o
+obj-$(CONFIG_CPCI690)		+= cpci690.o
+obj-$(CONFIG_EV64260)		+= ev64260.o
+obj-$(CONFIG_CHESTNUT)		+= chestnut.o
 obj-$(CONFIG_GEMINI)		+= gemini_pci.o gemini_setup.o gemini_prom.o
 obj-$(CONFIG_K2)		+= k2.o
 obj-$(CONFIG_LOPEC)		+= lopec.o
+obj-$(CONFIG_KATANA)		+= katana.o
 obj-$(CONFIG_MCPN765)		+= mcpn765.o
 obj-$(CONFIG_MENF1)		+= menf1_setup.o menf1_pci.o
 obj-$(CONFIG_MVME5100)		+= mvme5100.o
diff -Nru a/arch/ppc/platforms/apus_setup.c b/arch/ppc/platforms/apus_setup.c
--- a/arch/ppc/platforms/apus_setup.c	2005-03-01 23:38:58 -08:00
+++ b/arch/ppc/platforms/apus_setup.c	2005-03-01 23:38:58 -08:00
@@ -480,7 +480,7 @@
 void
 apus_restart(char *cmd)
 {
-	cli();
+	local_irq_disable();
 
 	APUS_WRITE(APUS_REG_LOCK,
 		   REGLOCK_BLACKMAGICK1|REGLOCK_BLACKMAGICK2);
diff -Nru a/arch/ppc/platforms/chestnut.c b/arch/ppc/platforms/chestnut.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/ppc/platforms/chestnut.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,623 @@
+/*
+ * arch/ppc/platforms/chestnut.c
+ *
+ * Board setup routines for IBM Chestnut
+ *
+ * Author: <source@mvista.com>
+ *
+ * <2004> (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/stddef.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/reboot.h>
+#include <linux/kdev_t.h>
+#include <linux/major.h>
+#include <linux/blkdev.h>
+#include <linux/console.h>
+#include <linux/root_dev.h>
+#include <linux/initrd.h>
+#include <linux/delay.h>
+#include <linux/seq_file.h>
+#include <linux/ide.h>
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+#include <asm/system.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/time.h>
+#include <asm/dma.h>
+#include <asm/io.h>
+#include <linux/irq.h>
+#include <asm/hw_irq.h>
+#include <asm/machdep.h>
+#include <asm/kgdb.h>
+#include <asm/bootinfo.h>
+#include <asm/mv64x60.h>
+#include <platforms/chestnut.h>
+
+static u32 boot_base; /* Virtual addr of 8bit boot */
+static u32 cpld_base; /* Virtual addr of CPLD Regs */
+
+static mv64x60_handle_t	bh;
+
+extern void gen550_progress(char *, unsigned short);
+extern void gen550_init(int, struct uart_port *);
+extern void mv64360_pcibios_fixup(mv64x60_handle_t *bh);
+
+#define BIT(x) (1<<x)
+#define CHESTNUT_PRESERVE_MASK (BIT(MV64x60_CPU2DEV_0_WIN) | \
+				BIT(MV64x60_CPU2DEV_1_WIN) | \
+				BIT(MV64x60_CPU2DEV_2_WIN) | \
+				BIT(MV64x60_CPU2DEV_3_WIN) | \
+				BIT(MV64x60_CPU2BOOT_WIN))
+/**************************************************************************
+ * FUNCTION: chestnut_calibrate_decr
+ *
+ * DESCRIPTION: initialize decrementer interrupt frequency (used as system
+ *              timer)
+ *
+ ****/
+static void __init
+chestnut_calibrate_decr(void){
+	ulong freq;
+
+	freq = CHESTNUT_BUS_SPEED / 4;
+
+	printk("time_init: decrementer frequency = %lu.%.6lu MHz\n",
+		freq/1000000, freq%1000000);
+
+	tb_ticks_per_jiffy = freq / HZ;
+	tb_to_us = mulhwu_scale_factor(freq, 1000000);
+
+	return;
+}
+
+static int
+chestnut_show_cpuinfo(struct seq_file *m)
+{
+	seq_printf(m, "vendor\t\t: IBM\n");
+	seq_printf(m, "machine\t\t: 750FX/GX Eval Board (Chestnut/Buckeye)\n");
+
+	return 0;
+}
+
+/**************************************************************************
+ * FUNCTION: chestnut_find_end_of_memory
+ *
+ * DESCRIPTION: ppc_md memory size callback
+ *
+ ****/
+unsigned long __init
+chestnut_find_end_of_memory(void)
+{
+   	static int  mem_size = 0;
+
+   	if (mem_size == 0) {
+      		mem_size = mv64x60_get_mem_size(CONFIG_MV64X60_NEW_BASE,
+				MV64x60_TYPE_MV64460);
+   	}
+   	return(mem_size);
+}
+
+#if defined(CONFIG_SERIAL_8250)
+static void __init
+chestnut_early_serial_map(void)
+{
+	struct uart_port port;
+
+	/* Setup serial port access */
+	memset(&port, 0, sizeof(port));
+	port.uartclk = BASE_BAUD * 16;
+	port.irq = UART0_INT;
+	port.flags = STD_COM_FLAGS | UPF_IOREMAP;
+	port.iotype = SERIAL_IO_MEM;
+	port.mapbase = CHESTNUT_UART0_IO_BASE;
+	port.regshift = 0;
+
+	if (early_serial_setup(&port) != 0)
+		printk("Early serial init of port 0 failed\n");
+
+	/* Assume early_serial_setup() doesn't modify serial_req */
+	port.line = 1;
+	port.irq = UART1_INT;
+	port.mapbase = CHESTNUT_UART1_IO_BASE;
+
+	if (early_serial_setup(&port) != 0)
+		printk("Early serial init of port 1 failed\n");
+}
+#endif
+
+/**************************************************************************
+ * FUNCTION: chestnut_map_irq
+ *
+ * DESCRIPTION: 0 return since PCI IRQs not needed
+ *
+ ****/
+static int __init
+chestnut_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
+{
+	static char pci_irq_table[][4] = {
+		{CHESTNUT_PCI_SLOT0_IRQ, CHESTNUT_PCI_SLOT0_IRQ,
+		 CHESTNUT_PCI_SLOT0_IRQ, CHESTNUT_PCI_SLOT0_IRQ},
+		{CHESTNUT_PCI_SLOT1_IRQ, CHESTNUT_PCI_SLOT1_IRQ,
+		 CHESTNUT_PCI_SLOT1_IRQ, CHESTNUT_PCI_SLOT1_IRQ},
+		{CHESTNUT_PCI_SLOT2_IRQ, CHESTNUT_PCI_SLOT2_IRQ,
+		 CHESTNUT_PCI_SLOT2_IRQ, CHESTNUT_PCI_SLOT2_IRQ},
+		{CHESTNUT_PCI_SLOT3_IRQ, CHESTNUT_PCI_SLOT3_IRQ,
+		 CHESTNUT_PCI_SLOT3_IRQ, CHESTNUT_PCI_SLOT3_IRQ},
+	};
+	const long min_idsel = 1, max_idsel = 4, irqs_per_slot = 4;
+
+	return (PCI_IRQ_TABLE_LOOKUP);
+}
+
+
+/**************************************************************************
+ * FUNCTION: chestnut_setup_bridge
+ *
+ * DESCRIPTION: initalize board-specific settings on the MV64360
+ *
+ ****/
+static void __init
+chestnut_setup_bridge(void)
+{
+	struct mv64x60_setup_info	si;
+	int i;
+
+   	if ( ppc_md.progress )
+		ppc_md.progress("chestnut_setup_bridge: enter", 0);
+
+	memset(&si, 0, sizeof(si));
+
+	si.phys_reg_base = CONFIG_MV64X60_NEW_BASE;
+
+	/* setup only PCI bus 0 (bus 1 not used) */
+	si.pci_0.enable_bus = 1;
+	si.pci_0.pci_io.cpu_base = CHESTNUT_PCI0_IO_PROC_ADDR;
+	si.pci_0.pci_io.pci_base_hi = 0;
+	si.pci_0.pci_io.pci_base_lo = CHESTNUT_PCI0_IO_PCI_ADDR;
+	si.pci_0.pci_io.size = CHESTNUT_PCI0_IO_SIZE;
+	si.pci_0.pci_io.swap = MV64x60_CPU2PCI_SWAP_NONE; /* no swapping */
+	si.pci_0.pci_mem[0].cpu_base = CHESTNUT_PCI0_MEM_PROC_ADDR;
+	si.pci_0.pci_mem[0].pci_base_hi = CHESTNUT_PCI0_MEM_PCI_HI_ADDR;
+	si.pci_0.pci_mem[0].pci_base_lo = CHESTNUT_PCI0_MEM_PCI_LO_ADDR;
+	si.pci_0.pci_mem[0].size = CHESTNUT_PCI0_MEM_SIZE;
+	si.pci_0.pci_mem[0].swap = MV64x60_CPU2PCI_SWAP_NONE; /* no swapping */
+	si.pci_0.pci_cmd_bits = 0;
+	si.pci_0.latency_timer = 0x80;
+
+	si.window_preserve_mask_32_lo = CHESTNUT_PRESERVE_MASK;
+
+	for (i=0; i<MV64x60_CPU2MEM_WINDOWS; i++) {
+		si.cpu_prot_options[i] = 0;
+#ifdef CONFIG_NOT_CACHE_COHERENT
+		si.cpu_snoop_options[i] = MV64360_CPU_SNOOP_NONE;
+#else
+		si.cpu_snoop_options[i] = MV64360_CPU_SNOOP_WB; /* risky */
+#endif
+		si.pci_0.acc_cntl_options[i] =
+#ifdef CONFIG_NOT_CACHE_COHERENT
+			MV64360_PCI_ACC_CNTL_SNOOP_NONE |
+#else
+			MV64360_PCI_ACC_CNTL_SNOOP_WB | /* risky */
+#endif
+			MV64360_PCI_ACC_CNTL_SWAP_NONE |
+			MV64360_PCI_ACC_CNTL_MBURST_32_BYTES |
+			MV64360_PCI_ACC_CNTL_RDSIZE_32_BYTES;
+	}
+
+   	/* Lookup host bridge - on CPU 0 - no SMP support */
+   	if (mv64x60_init(&bh, &si)) {
+        	printk("\n\nPCI Bridge initialization failed!\n");
+   	}
+
+	pci_dram_offset = 0;
+	ppc_md.pci_swizzle = common_swizzle;
+	ppc_md.pci_map_irq = chestnut_map_irq;
+	ppc_md.pci_exclude_device = mv64x60_pci_exclude_device;
+
+	mv64x60_set_bus(&bh, 0, 0);
+	bh.hose_a->first_busno = 0;
+	bh.hose_a->last_busno = 0xff;
+	bh.hose_a->last_busno = pciauto_bus_scan(bh.hose_a, 0);
+
+}
+
+void __init
+chestnut_setup_peripherals(void)
+{
+
+   	mv64x60_set_32bit_window(&bh, MV64x60_CPU2BOOT_WIN,
+			CHESTNUT_BOOT_8BIT_BASE, CHESTNUT_BOOT_8BIT_SIZE, 0);
+
+	mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_0_WIN,
+			CHESTNUT_32BIT_BASE, CHESTNUT_32BIT_SIZE, 0);
+	mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_1_WIN,
+			CHESTNUT_CPLD_BASE, CHESTNUT_CPLD_SIZE, 0);
+
+	mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_2_WIN,
+			CHESTNUT_UART_BASE, CHESTNUT_UART_SIZE, 0);
+	mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_3_WIN,
+			CHESTNUT_FRAM_BASE, CHESTNUT_FRAM_SIZE, 0);
+   	/* Set up window for internal sram (256KByte insize) */
+   	mv64x60_set_32bit_window(&bh, MV64x60_CPU2SRAM_WIN,
+			CHESTNUT_INTERNAL_SRAM_BASE,
+			CHESTNUT_INTERNAL_SRAM_SIZE, 0);
+
+	boot_base = (u32)ioremap(CHESTNUT_BOOT_8BIT_BASE,
+				CHESTNUT_BOOT_8BIT_SIZE);
+	cpld_base = (u32)ioremap(CHESTNUT_CPLD_BASE, CHESTNUT_CPLD_SIZE);
+
+   	/*
+    	 * Configure internal SRAM -
+    	 * Cache coherent write back, incase
+	 *      CONFIG_MV64360_SRAM_CACHE_COHERENT set
+    	 * Parity enabled.
+    	 * Parity error propagation
+    	 * Arbitration not parked for CPU only
+    	 * Other bits are reserved.
+    	 */
+#ifdef CONFIG_MV64360_SRAM_CACHE_COHERENT
+   	mv64x60_write(&bh, MV64360_SRAM_CONFIG, 0x001600b2);
+#else
+   	mv64x60_write(&bh, MV64360_SRAM_CONFIG, 0x001600b0);
+#endif
+
+   	/*
+    	 * Setting the SRAM to 0. Note that this generates parity errors on
+	 * internal data path in SRAM since it's first time accessing it
+	 * while after reset it's not configured
+    	*/
+   	memset((void *)CHESTNUT_INTERNAL_SRAM_BASE, 0, CHESTNUT_INTERNAL_SRAM_SIZE);
+	/*
+	 * Configure MPP pins for PCI DMA
+	 *
+	 * PCI Slot	GNT pin		REQ pin
+	 *	0	MPP16		MPP17
+	 *	1	MPP18		MPP19
+	 *	2	MPP20		MPP21
+	 *	3	MPP22		MPP23
+	 */
+	mv64x60_write(&bh, MV64x60_MPP_CNTL_2,
+			(0x1 << 0)  |	/* MPPSel16 PCI0_GNT[0] */
+			(0x1 << 4)  |	/* MPPSel17 PCI0_REQ[0] */
+			(0x1 << 8)  |	/* MPPSel18 PCI0_GNT[1] */
+			(0x1 << 12) |	/* MPPSel19 PCI0_REQ[1] */
+			(0x1 << 16) |	/* MPPSel20 PCI0_GNT[2] */
+			(0x1 << 20) |	/* MPPSel21 PCI0_REQ[2] */
+			(0x1 << 24) |	/* MPPSel22 PCI0_GNT[3] */
+			(0x1 << 28));	/* MPPSel23 PCI0_REQ[3] */
+	/*
+	 * Set unused MPP pins for output, as per schematic note
+	 *
+	 * Unused Pins: MPP01, MPP02, MPP04, MPP05, MPP06
+	 *		MPP09, MPP10, MPP13, MPP14, MPP15
+	 */
+	mv64x60_clr_bits(&bh, MV64x60_MPP_CNTL_0,
+			(0xf << 4)  |	/* MPPSel01 GPIO[1] */
+			(0xf << 8)  |	/* MPPSel02 GPIO[2] */
+			(0xf << 16) |	/* MPPSel04 GPIO[4] */
+			(0xf << 20) |	/* MPPSel05 GPIO[5] */
+			(0xf << 24));	/* MPPSel06 GPIO[6] */
+	mv64x60_clr_bits(&bh, MV64x60_MPP_CNTL_1,
+			(0xf << 4)  |	/* MPPSel09 GPIO[9] */
+			(0xf << 8)  |	/* MPPSel10 GPIO[10] */
+			(0xf << 20) |	/* MPPSel13 GPIO[13] */
+			(0xf << 24) |	/* MPPSel14 GPIO[14] */
+			(0xf << 28));	/* MPPSel15 GPIO[15] */
+	mv64x60_set_bits(&bh, MV64x60_GPP_IO_CNTL,
+			BIT(1)  | BIT(2)  | BIT(4)  | BIT(5)  | BIT(6)  |
+			BIT(9)  | BIT(10) | BIT(13) | BIT(14) | BIT(15)); /* Output */
+
+   	/*
+    	 * Configure the following MPP pins to indicate a level
+    	 * triggered interrupt
+    	 *
+       	 * MPP24 - Board Reset (just map the MPP & GPP for chestnut_reset)
+       	 * MPP25 - UART A  (high)
+       	 * MPP26 - UART B  (high)
+	 * MPP28 - PCI Slot 3 (low)
+	 * MPP29 - PCI Slot 2 (low)
+	 * MPP30 - PCI Slot 1 (low)
+	 * MPP31 - PCI Slot 0 (low)
+    	 */
+        mv64x60_clr_bits(&bh, MV64x60_MPP_CNTL_3,
+                        BIT(3) | BIT(2) | BIT(1) | BIT(0)	 | /* MPP 24 */
+                        BIT(7) | BIT(6) | BIT(5) | BIT(4)	 | /* MPP 25 */
+                        BIT(11) | BIT(10) | BIT(9) | BIT(8)	 | /* MPP 26 */
+			BIT(19) | BIT(18) | BIT(17) | BIT(16)	 | /* MPP 28 */
+			BIT(23) | BIT(22) | BIT(21) | BIT(20)	 | /* MPP 29 */
+			BIT(27) | BIT(26) | BIT(25) | BIT(24)	 | /* MPP 30 */
+			BIT(31) | BIT(30) | BIT(29) | BIT(28));    /* MPP 31 */
+
+   	/*
+	 * Define GPP 25 (high), 26 (high), 28 (low), 29 (low), 30 (low),
+	 * 31 (low) interrupt polarity input signal and level triggered
+    	 */
+   	mv64x60_clr_bits(&bh, MV64x60_GPP_LEVEL_CNTL, BIT(25) | BIT(26));
+   	mv64x60_set_bits(&bh, MV64x60_GPP_LEVEL_CNTL,
+			BIT(28) | BIT(29) | BIT(30) | BIT(31));
+   	mv64x60_clr_bits(&bh, MV64x60_GPP_IO_CNTL,
+			BIT(25) | BIT(26) | BIT(28) | BIT(29) | BIT(30) |
+			BIT(31));
+
+   	/* Config GPP interrupt controller to respond to level trigger */
+   	mv64x60_set_bits(&bh, MV64360_COMM_ARBITER_CNTL, BIT(10));
+
+   	/*
+    	 * Dismiss and then enable interrupt on GPP interrupt cause for CPU #0
+    	 */
+   	mv64x60_write(&bh, MV64x60_GPP_INTR_CAUSE,
+			~(BIT(25) | BIT(26) | BIT(28) | BIT(29) | BIT(30) |
+			  BIT(31)));
+   	mv64x60_set_bits(&bh, MV64x60_GPP_INTR_MASK,
+			BIT(25) | BIT(26) | BIT(28) | BIT(29) | BIT(30) |
+			BIT(31));
+
+   	/*
+    	 * Dismiss and then enable interrupt on CPU #0 high cause register
+    	 * BIT27 summarizes GPP interrupts 24-31
+    	*/
+   	mv64x60_set_bits(&bh, MV64360_IC_CPU0_INTR_MASK_HI, BIT(27));
+
+   	if (ppc_md.progress)
+		ppc_md.progress("chestnut_setup_bridge: exit", 0);
+}
+
+/**************************************************************************
+ * FUNCTION: chestnut_setup_arch
+ *
+ * DESCRIPTION: ppc_md machine configuration callback
+ *
+ ****/
+static void __init
+chestnut_setup_arch(void)
+{
+	if (ppc_md.progress)
+      		ppc_md.progress("chestnut_setup_arch: enter", 0);
+
+	/* init to some ~sane value until calibrate_delay() runs */
+	loops_per_jiffy = 50000000 / HZ;
+
+   	/* if the time base value is greater than bus freq/4 (the TB and
+    	* decrementer tick rate) + signed integer rollover value, we
+    	* can spend a fair amount of time waiting for the rollover to
+    	* happen.  To get around this, initialize the time base register
+    	* to a "safe" value.
+    	*/
+   	set_tb(0, 0);
+
+#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_SDA2;
+#endif
+
+   	/*
+    	* Set up the L2CR register.
+    	*/
+ 	_set_L2CR(_get_L2CR() | L2CR_L2E);
+
+	chestnut_setup_bridge();
+	chestnut_setup_peripherals();
+
+#ifdef CONFIG_DUMMY_CONSOLE
+	conswitchp = &dummy_con;
+#endif
+
+#if defined(CONFIG_SERIAL_8250)
+	chestnut_early_serial_map();
+#endif
+
+	/* Identify the system */
+	printk(KERN_INFO "System Identification: IBM 750FX/GX Eval Board\n");
+	printk(KERN_INFO "IBM 750FX/GX port (C) 2004 MontaVista Software, Inc. (source@mvista.com)\n");
+
+	if (ppc_md.progress)
+      		ppc_md.progress("chestnut_setup_arch: exit", 0);
+
+	return;
+}
+
+/**************************************************************************
+ * FUNCTION: chestnut_restart
+ *
+ * DESCRIPTION: ppc_md machine reset callback
+ *              reset the board via the CPLD command register
+ *
+ ****/
+static void
+chestnut_restart(char *cmd)
+{
+	volatile ulong i = 10000000;
+
+	local_irq_disable();
+
+        /*
+         * Set CPLD Reg 3 bit 0 to 1 to allow MPP signals on reset to work
+         *
+         * MPP24 - board reset
+         */
+   	writeb(0x1, (void __iomem *)(cpld_base+3));
+
+	/* GPP pin tied to MPP earlier */
+        mv64x60_set_bits(&bh, MV64x60_GPP_VALUE_SET, BIT(24));
+
+   	while (i-- > 0);
+   	panic("restart failed\n");
+}
+
+static void
+chestnut_halt(void)
+{
+	local_irq_disable();
+	for (;;);
+	/* NOTREACHED */
+}
+
+static void
+chestnut_power_off(void)
+{
+	chestnut_halt();
+	/* NOTREACHED */
+}
+
+#define SET_PCI_COMMAND_INVALIDATE
+#ifdef SET_PCI_COMMAND_INVALIDATE
+/*
+ * Dave Wilhardt found that PCI_COMMAND_INVALIDATE must
+ * be set for each device if you are using cache coherency.
+ */
+static void __init
+set_pci_command_invalidate(void)
+{
+	struct pci_dev *dev = NULL;
+	u16 val;
+
+	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
+		pci_read_config_word(dev, PCI_COMMAND, &val);
+		val |= PCI_COMMAND_INVALIDATE;
+		pci_write_config_word(dev, PCI_COMMAND, val);
+
+		pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE,
+				      L1_CACHE_LINE_SIZE >> 2);
+	}
+}
+#endif
+
+static void __init
+chestnut_pci_fixups(void)
+{
+#ifdef SET_PCI_COMMAND_INVALIDATE
+	set_pci_command_invalidate();
+#endif
+}
+
+/**************************************************************************
+ * FUNCTION: chestnut_map_io
+ *
+ * DESCRIPTION: configure fixed memory-mapped IO
+ *
+ ****/
+static void __init
+chestnut_map_io(void)
+{
+#ifdef CONFIG_MV64360_SRAM_CACHEABLE
+   	io_block_mapping(CHESTNUT_INTERNAL_SRAM_BASE,
+       			CHESTNUT_INTERNAL_SRAM_BASE,
+       			CHESTNUT_INTERNAL_SRAM_SIZE,
+       			_PAGE_KERNEL | _PAGE_GUARDED);
+#else
+#ifdef CONFIG_MV64360_SRAM_CACHE_COHERENT
+   	io_block_mapping(CHESTNUT_INTERNAL_SRAM_BASE,
+       			CHESTNUT_INTERNAL_SRAM_BASE,
+       			CHESTNUT_INTERNAL_SRAM_SIZE,
+       			_PAGE_KERNEL | _PAGE_GUARDED | _PAGE_COHERENT);
+#else
+   	io_block_mapping(CHESTNUT_INTERNAL_SRAM_BASE,
+       			CHESTNUT_INTERNAL_SRAM_BASE,
+       			CHESTNUT_INTERNAL_SRAM_SIZE,
+       			_PAGE_IO);
+#endif /* !CONFIG_MV64360_SRAM_CACHE_COHERENT */
+#endif /* !CONFIG_MV64360_SRAM_CACHEABLE */
+
+#if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)
+	io_block_mapping(CHESTNUT_UART_BASE, CHESTNUT_UART_BASE, 0x100000, _PAGE_IO);
+#endif
+}
+
+/**************************************************************************
+ * FUNCTION: chestnut_set_bat
+ *
+ * DESCRIPTION: configures a (temporary) bat mapping for early access to
+ *              device I/O
+ *
+ ****/
+static __inline__ void
+chestnut_set_bat(void)
+{
+        mb();
+        mtspr(DBAT3U, 0xf0001ffe);
+        mtspr(DBAT3L, 0xf000002a);
+        mb();
+
+	return;
+}
+
+/**************************************************************************
+ * FUNCTION: platform_init
+ *
+ * DESCRIPTION: main entry point for configuring board-specific machine
+ *              callbacks
+ *
+ ****/
+void __init
+platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
+	      unsigned long r6, unsigned long r7)
+{
+	parse_bootinfo(find_bootinfo());
+
+        /* Copy the kernel command line arguments to a safe place. */
+
+        if (r6) {
+                *(char *) (r7 + KERNELBASE) = 0;
+                strcpy(cmd_line, (char *) (r6 + KERNELBASE));
+        }
+
+	isa_mem_base = 0;
+
+	ppc_md.setup_arch = chestnut_setup_arch;
+	ppc_md.show_cpuinfo = chestnut_show_cpuinfo;
+	ppc_md.irq_canonicalize = NULL;
+	ppc_md.init_IRQ = mv64360_init_irq;
+	ppc_md.get_irq = mv64360_get_irq;
+	ppc_md.init = NULL;
+
+	ppc_md.find_end_of_memory = chestnut_find_end_of_memory;
+	ppc_md.setup_io_mappings  = chestnut_map_io;
+	ppc_md.pcibios_fixup = chestnut_pci_fixups;
+
+	ppc_md.restart = chestnut_restart;
+   	ppc_md.power_off = chestnut_power_off;
+   	ppc_md.halt = chestnut_halt;
+
+	ppc_md.time_init = NULL;
+	ppc_md.set_rtc_time = NULL;
+	ppc_md.get_rtc_time = NULL;
+	ppc_md.calibrate_decr = chestnut_calibrate_decr;
+
+	ppc_md.nvram_read_val = NULL;
+	ppc_md.nvram_write_val = NULL;
+
+	ppc_md.heartbeat = NULL;
+
+	ppc_md.pcibios_fixup = chestnut_pci_fixups;
+
+	bh.p_base = CONFIG_MV64X60_NEW_BASE;
+
+	chestnut_set_bat();
+
+#if defined(CONFIG_SERIAL_TEXT_DEBUG)
+	ppc_md.progress = gen550_progress;
+#endif
+#if defined(CONFIG_KGDB)
+	ppc_md.kgdb_map_scc = gen550_kgdb_map_scc;
+#endif
+
+	if (ppc_md.progress)
+                ppc_md.progress("chestnut_init(): exit", 0);
+
+        return;
+}
diff -Nru a/arch/ppc/platforms/chestnut.h b/arch/ppc/platforms/chestnut.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/ppc/platforms/chestnut.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,128 @@
+/*
+ * arch/ppc/platforms/chestnut.h
+ *
+ * Definitions for IBM 750FXGX Eval (Chestnut)
+ *
+ * Author: <source@mvista.com>
+ *
+ * Based on Artesyn Katana code done by Tim Montgomery <timm@artesyncp.com>
+ * Based on code done by Rabeeh Khoury - rabeeh@galileo.co.il
+ * Based on code done by Mark A. Greer <mgreer@mvista.com>
+ *
+ * <2004> (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 is the CPU physical memory map (windows must be at least 1MB and start
+ * on a boundary that is a multiple of the window size):
+ *
+ * Seems on the IBM 750FXGX Eval board, the MV64460 Registers can be in
+ * only 2 places per switch U17 0x14000000 or 0xf1000000 easily - chose to
+ * implement at 0xf1000000 only at this time
+ *
+ *    0xfff00000-0xffffffff      - 8 Flash
+ *    0xffd00000-0xffd00004      - CPLD
+ *    0xffc00000-0xffc0000f      - UART
+ *    0xffb00000-0xffb07fff      - FRAM
+ *    0xffa00000-0xffafffff      - *** HOLE ***
+ *    0xff900000-0xff9fffff      - MV64460 Integrated SRAM
+ *    0xfe000000-0xff8fffff      - *** HOLE ***
+ *    0xfc000000-0xfdffffff      - 32bit Flash
+ *    0xf1010000-0xfbffffff      - *** HOLE ***
+ *    0xf1000000-0xf100ffff      - MV64460 Registers
+ */
+
+#ifndef __PPC_PLATFORMS_CHESTNUT_H__
+#define __PPC_PLATFORMS_CHESTNUT_H__
+
+#define CHESTNUT_BOOT_8BIT_BASE			0xfff00000
+#define CHESTNUT_BOOT_8BIT_SIZE_ACTUAL		(1024*1024)
+#define CHESTNUT_BOOT_SRAM_BASE			0xffe00000
+#define CHESTNUT_BOOT_SRAM_SIZE_ACTUAL		(1024*1024)
+#define CHESTNUT_CPLD_BASE			0xffd00000
+#define CHESTNUT_CPLD_SIZE_ACTUAL		5
+#define CHESTNUT_CPLD_REG3			(CHESTNUT_CPLD_BASE+3)
+#define CHESTNUT_UART_BASE			0xffc00000
+#define CHESTNUT_UART_SIZE_ACTUAL		16
+#define CHESTNUT_FRAM_BASE			0xffb00000
+#define CHESTNUT_FRAM_SIZE_ACTUAL		(32*1024)
+#define CHESTNUT_BRIDGE_REG_BASE		0xf1000000
+#define CHESTNUT_INTERNAL_SRAM_BASE		0xff900000
+#define CHESTNUT_INTERNAL_SRAM_SIZE_ACTUAL	(256*1024)
+#define CHESTNUT_32BIT_BASE			0xfc000000
+#define CHESTNUT_32BIT_SIZE			(32*1024*1024)
+
+#define CHESTNUT_BOOT_8BIT_SIZE		max(MV64360_WINDOW_SIZE_MIN, \
+					CHESTNUT_BOOT_8BIT_SIZE_ACTUAL)
+#define CHESTNUT_BOOT_SRAM_SIZE		max(MV64360_WINDOW_SIZE_MIN, \
+					CHESTNUT_BOOT_SRAM_SIZE_ACTUAL)
+#define CHESTNUT_CPLD_SIZE		max(MV64360_WINDOW_SIZE_MIN, \
+					CHESTNUT_CPLD_SIZE_ACTUAL)
+#define CHESTNUT_UART_SIZE		max(MV64360_WINDOW_SIZE_MIN, \
+					CHESTNUT_UART_SIZE_ACTUAL)
+#define CHESTNUT_FRAM_SIZE		max(MV64360_WINDOW_SIZE_MIN, \
+					CHESTNUT_FRAM_SIZE_ACTUAL)
+#define CHESTNUT_INTERNAL_SRAM_SIZE	max(MV64360_WINDOW_SIZE_MIN, \
+					CHESTNUT_INTERNAL_SRAM_SIZE_ACTUAL)
+
+#define CHESTNUT_BUS_SPEED		200000000
+#define CHESTNUT_PIBS_DATABASE		0xf0000 /* from PIBS src code */
+
+#define MV64360_ETH_PORT_SERIAL_CONTROL_REG_PORT0 	0x243c
+#define MV64360_ETH_PORT_SERIAL_CONTROL_REG_PORT1 	0x283c
+
+/*
+ * PCI windows
+ */
+
+#define CHESTNUT_PCI0_MEM_PROC_ADDR	0x80000000
+#define CHESTNUT_PCI0_MEM_PCI_HI_ADDR	0x00000000
+#define CHESTNUT_PCI0_MEM_PCI_LO_ADDR	0x80000000
+#define CHESTNUT_PCI0_MEM_SIZE		0x10000000
+#define CHESTNUT_PCI0_IO_PROC_ADDR	0xa0000000
+#define CHESTNUT_PCI0_IO_PCI_ADDR	0x00000000
+#define CHESTNUT_PCI0_IO_SIZE		0x01000000
+
+/*
+ * Board-specific IRQ info
+ */
+#define CHESTNUT_PCI_SLOT0_IRQ	64+31
+#define CHESTNUT_PCI_SLOT1_IRQ	64+30
+#define CHESTNUT_PCI_SLOT2_IRQ	64+29
+#define CHESTNUT_PCI_SLOT3_IRQ	64+28
+
+/* serial port definitions */
+#define CHESTNUT_UART0_IO_BASE  CHESTNUT_UART_BASE+8
+#define CHESTNUT_UART1_IO_BASE  CHESTNUT_UART_BASE
+
+#define UART0_INT           	64+25
+#define UART1_INT        	64+26
+
+#ifdef CONFIG_SERIAL_MANY_PORTS
+#define RS_TABLE_SIZE  64
+#else
+#define RS_TABLE_SIZE  2
+#endif
+
+/* Rate for the 3.6864 Mhz clock for the onboard serial chip */
+#define BASE_BAUD 		( 3686400 / 16 )
+
+#ifdef CONFIG_SERIAL_DETECT_IRQ
+#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST|ASYNC_AUTO_IRQ)
+#else
+#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST)
+#endif
+
+#define STD_UART_OP(num)						\
+        { 0, BASE_BAUD, 0, UART##num##_INT, STD_COM_FLAGS,		\
+                iomem_base: (u8 *)CHESTNUT_UART##num##_IO_BASE,	\
+		io_type: SERIAL_IO_MEM},
+
+#define SERIAL_PORT_DFNS        \
+        STD_UART_OP(0)          \
+        STD_UART_OP(1)
+
+#endif /* __PPC_PLATFORMS_CHESTNUT_H__ */
diff -Nru a/arch/ppc/platforms/chrp_pci.c b/arch/ppc/platforms/chrp_pci.c
--- a/arch/ppc/platforms/chrp_pci.c	2005-03-01 23:39:17 -08:00
+++ b/arch/ppc/platforms/chrp_pci.c	2005-03-01 23:39:17 -08:00
@@ -23,7 +23,7 @@
 #include <asm/open_pic.h>
 
 /* LongTrail */
-unsigned long gg2_pci_config_base;
+void __iomem *gg2_pci_config_base;
 
 /*
  * The VLSI Golden Gate II has only 512K of PCI configuration space, so we
@@ -33,7 +33,7 @@
 int __chrp gg2_read_config(struct pci_bus *bus, unsigned int devfn, int off,
 			   int len, u32 *val)
 {
-	volatile unsigned char *cfg_data;
+	volatile void __iomem *cfg_data;
 	struct pci_controller *hose = bus->sysdata;
 
 	if (bus->number > 7)
@@ -45,13 +45,13 @@
 	cfg_data = hose->cfg_data + ((bus->number<<16) | (devfn<<8) | off);
 	switch (len) {
 	case 1:
-		*val =  in_8((u8 *)cfg_data);
+		*val =  in_8(cfg_data);
 		break;
 	case 2:
-		*val = in_le16((u16 *)cfg_data);
+		*val = in_le16(cfg_data);
 		break;
 	default:
-		*val = in_le32((u32 *)cfg_data);
+		*val = in_le32(cfg_data);
 		break;
 	}
 	return PCIBIOS_SUCCESSFUL;
@@ -60,7 +60,7 @@
 int __chrp gg2_write_config(struct pci_bus *bus, unsigned int devfn, int off,
 			    int len, u32 val)
 {
-	volatile unsigned char *cfg_data;
+	volatile void __iomem *cfg_data;
 	struct pci_controller *hose = bus->sysdata;
 
 	if (bus->number > 7)
@@ -72,13 +72,13 @@
 	cfg_data = hose->cfg_data + ((bus->number<<16) | (devfn<<8) | off);
 	switch (len) {
 	case 1:
-		out_8((u8 *)cfg_data, val);
+		out_8(cfg_data, val);
 		break;
 	case 2:
-		out_le16((u16 *)cfg_data, val);
+		out_le16(cfg_data, val);
 		break;
 	default:
-		out_le32((u32 *)cfg_data, val);
+		out_le32(cfg_data, val);
 		break;
 	}
 	return PCIBIOS_SUCCESSFUL;
@@ -97,8 +97,10 @@
 rtas_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
 		 int len, u32 *val)
 {
+	struct pci_controller *hose = bus->sysdata;
 	unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8)
-		| ((bus->number & 0xff) << 16);
+		| (((bus->number - hose->first_busno) & 0xff) << 16)
+		| (hose->index << 24);
         unsigned long ret = ~0UL;
 	int rval;
 
@@ -111,8 +113,10 @@
 rtas_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
 		  int len, u32 val)
 {
+	struct pci_controller *hose = bus->sysdata;
 	unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8)
-		| ((bus->number & 0xff) << 16);
+		| (((bus->number - hose->first_busno) & 0xff) << 16)
+		| (hose->index << 24);
 	int rval;
 
 	rval = call_rtas("write-pci-config", 3, 1, NULL, addr, len, val);
@@ -186,6 +190,22 @@
 	iounmap(reg);
 }
 
+/* Marvell Discovery II based Pegasos 2 */
+static void __init setup_peg2(struct pci_controller *hose, struct device_node *dev)
+{
+	struct device_node *root = find_path_device("/");
+	struct device_node *rtas;
+
+	rtas = of_find_node_by_name (root, "rtas");
+	if (rtas) {
+		hose->ops = &rtas_pci_ops;
+	} else {
+		printk ("RTAS supporting Pegasos OF not found, please upgrade"
+			" your firmware\n");
+	}
+	pci_assign_all_busses = 1;
+}
+
 void __init
 chrp_find_bridges(void)
 {
@@ -195,7 +215,7 @@
 	struct pci_controller *hose;
 	unsigned int *dma;
 	char *model, *machine;
-	int is_longtrail = 0, is_mot = 0;
+	int is_longtrail = 0, is_mot = 0, is_pegasos = 0;
 	struct device_node *root = find_path_device("/");
 
 	/*
@@ -207,6 +227,10 @@
 	if (machine != NULL) {
 		is_longtrail = strncmp(machine, "IBM,LongTrail", 13) == 0;
 		is_mot = strncmp(machine, "MOT", 3) == 0;
+		if (strncmp(machine, "Pegasos2", 8) == 0)
+			is_pegasos = 2;
+		else if (strncmp(machine, "Pegasos", 7) == 0)
+			is_pegasos = 1;
 	}
 	for (dev = root->child; dev != NULL; dev = dev->sibling) {
 		if (dev->type == NULL || strcmp(dev->type, "pci") != 0)
@@ -253,10 +277,14 @@
 			   || strncmp(model, "Motorola, Grackle", 17) == 0) {
 			setup_grackle(hose);
 		} else if (is_longtrail) {
+			void __iomem *p = ioremap(GG2_PCI_CONFIG_BASE, 0x80000);
 			hose->ops = &gg2_pci_ops;
-			hose->cfg_data = (unsigned char *)
-				ioremap(GG2_PCI_CONFIG_BASE, 0x80000);
-			gg2_pci_config_base = (unsigned long) hose->cfg_data;
+			hose->cfg_data = p;
+			gg2_pci_config_base = p;
+		} else if (is_pegasos == 1) {
+			setup_indirect_pci(hose, 0xfec00cf8, 0xfee00cfc);
+		} else if (is_pegasos == 2) {
+			setup_peg2(hose, dev);
 		} else {
 			printk("No methods for %s (model %s), using RTAS\n",
 			       dev->full_name, model);
@@ -275,5 +303,7 @@
 		}
 	}
 
-	ppc_md.pcibios_fixup = chrp_pcibios_fixup;
+	/* Do not fixup interrupts from OF tree on pegasos */
+	if (is_pegasos == 0)
+		ppc_md.pcibios_fixup = chrp_pcibios_fixup;
 }
diff -Nru a/arch/ppc/platforms/chrp_setup.c b/arch/ppc/platforms/chrp_setup.c
--- a/arch/ppc/platforms/chrp_setup.c	2005-03-01 23:39:09 -08:00
+++ b/arch/ppc/platforms/chrp_setup.c	2005-03-01 23:39:09 -08:00
@@ -37,6 +37,7 @@
 #include <linux/seq_file.h>
 #include <linux/root_dev.h>
 #include <linux/initrd.h>
+#include <linux/module.h>
 
 #include <asm/io.h>
 #include <asm/pgtable.h>
@@ -68,6 +69,9 @@
 extern unsigned long pmac_find_end_of_memory(void);
 extern int of_show_percpuinfo(struct seq_file *, int);
 
+int _chrp_type;
+EXPORT_SYMBOL(_chrp_type);
+
 /*
  * XXX this should be in xmon.h, but putting it there means xmon.h
  * has to include <linux/interrupt.h> (to get irqreturn_t), which
@@ -118,13 +122,12 @@
 	if (!strncmp(model, "IBM,LongTrail", 13)) {
 		/* VLSI VAS96011/12 `Golden Gate 2' */
 		/* Memory banks */
-		sdramen = (in_le32((unsigned *)(gg2_pci_config_base+
-						GG2_PCI_DRAM_CTRL))
+		sdramen = (in_le32(gg2_pci_config_base + GG2_PCI_DRAM_CTRL)
 			   >>31) & 1;
 		for (i = 0; i < (sdramen ? 4 : 6); i++) {
-			t = in_le32((unsigned *)(gg2_pci_config_base+
+			t = in_le32(gg2_pci_config_base+
 						 GG2_PCI_DRAM_BANK0+
-						 i*4));
+						 i*4);
 			if (!(t & 1))
 				continue;
 			switch ((t>>8) & 0x1f) {
@@ -154,7 +157,7 @@
 				   gg2_memtypes[sdramen ? 1 : ((t>>1) & 3)]);
 		}
 		/* L2 cache */
-		t = in_le32((unsigned *)(gg2_pci_config_base+GG2_PCI_CC_CTRL));
+		t = in_le32(gg2_pci_config_base+GG2_PCI_CC_CTRL);
 		seq_printf(m, "board l2\t: %s %s (%s)\n",
 			   gg2_cachesizes[(t>>7) & 3],
 			   gg2_cachetypes[(t>>2) & 3],
@@ -215,8 +218,33 @@
 }
 
 
-void __init
-chrp_setup_arch(void)
+static void __init pegasos_set_l2cr(void)
+{
+	struct device_node *np;
+
+	/* On Pegasos, enable the l2 cache if needed, as the OF forgets it */
+	if (_chrp_type != _CHRP_Pegasos)
+		return;
+
+	/* Enable L2 cache if needed */
+	np = find_type_devices("cpu");
+	if (np != NULL) {
+		unsigned int *l2cr = (unsigned int *)
+			get_property (np, "l2cr", NULL);
+		if (l2cr == NULL) {
+			printk ("Pegasos l2cr : no cpu l2cr property found\n");
+			return;
+		}
+		if (!((*l2cr) & 0x80000000)) {
+			printk ("Pegasos l2cr : L2 cache was not active, "
+				"activating\n");
+			_set_L2CR(0);
+			_set_L2CR((*l2cr) | 0x80000000);
+		}
+	}
+}
+
+void __init chrp_setup_arch(void)
 {
 	struct device_node *device;
 
@@ -233,6 +261,9 @@
 #endif
 		ROOT_DEV = Root_SDA2; /* sda2 (sda1 is for the kernel) */
 
+	/* On pegasos, enable the L2 cache if not already done by OF */
+	pegasos_set_l2cr();
+
 	/* Lookup PCI host bridges */
 	chrp_find_bridges();
 
@@ -403,15 +434,17 @@
 
 	chrp_find_openpic();
 
-	prom_get_irq_senses(init_senses, NUM_8259_INTERRUPTS, NR_IRQS);
-	OpenPIC_InitSenses = init_senses;
-	OpenPIC_NumInitSenses = NR_IRQS - NUM_8259_INTERRUPTS;
-
-	openpic_init(NUM_8259_INTERRUPTS);
-	/* We have a cascade on OpenPIC IRQ 0, Linux IRQ 16 */
-	openpic_hookup_cascade(NUM_8259_INTERRUPTS, "82c59 cascade",
-			       i8259_irq);
+	if (OpenPIC_Addr) {
+		prom_get_irq_senses(init_senses, NUM_8259_INTERRUPTS, NR_IRQS);
+		OpenPIC_InitSenses = init_senses;
+		OpenPIC_NumInitSenses = NR_IRQS - NUM_8259_INTERRUPTS;
+
+		openpic_init(NUM_8259_INTERRUPTS);
+		/* We have a cascade on OpenPIC IRQ 0, Linux IRQ 16 */
+		openpic_hookup_cascade(NUM_8259_INTERRUPTS, "82c59 cascade",
+				       i8259_irq);
 
+	}
 	for (i = 0; i < NUM_8259_INTERRUPTS; i++)
 		irq_desc[i].handler = &i8259_pic;
 	i8259_init(chrp_int_ack);
@@ -451,6 +484,9 @@
 chrp_init(unsigned long r3, unsigned long r4, unsigned long r5,
 	  unsigned long r6, unsigned long r7)
 {
+	struct device_node *root = find_path_device ("/");
+	char *machine = NULL;
+
 #ifdef CONFIG_BLK_DEV_INITRD
 	/* take care of initrd if we have one */
 	if ( r6 )
@@ -465,12 +501,29 @@
 	DMA_MODE_WRITE = 0x48;
 	isa_io_base = CHRP_ISA_IO_BASE;		/* default value */
 
+	if (root)
+		machine = get_property(root, "model", NULL);
+	if (machine && strncmp(machine, "Pegasos", 7) == 0) {
+		_chrp_type = _CHRP_Pegasos;
+	} else if (machine && strncmp(machine, "IBM", 3) == 0) {
+		_chrp_type = _CHRP_IBM;
+	} else if (machine && strncmp(machine, "MOT", 3) == 0) {
+		_chrp_type = _CHRP_Motorola;
+	} else {
+		/* Let's assume it is an IBM chrp if all else fails */
+		_chrp_type = _CHRP_IBM;
+	}
+
 	ppc_md.setup_arch     = chrp_setup_arch;
 	ppc_md.show_percpuinfo = of_show_percpuinfo;
 	ppc_md.show_cpuinfo   = chrp_show_cpuinfo;
+
 	ppc_md.irq_canonicalize = chrp_irq_canonicalize;
 	ppc_md.init_IRQ       = chrp_init_IRQ;
-	ppc_md.get_irq        = openpic_get_irq;
+	if (_chrp_type == _CHRP_Pegasos)
+		ppc_md.get_irq        = i8259_irq;
+	else
+		ppc_md.get_irq        = openpic_get_irq;
 
 	ppc_md.init           = chrp_init2;
 
diff -Nru a/arch/ppc/platforms/chrp_smp.c b/arch/ppc/platforms/chrp_smp.c
--- a/arch/ppc/platforms/chrp_smp.c	2005-03-01 23:38:55 -08:00
+++ b/arch/ppc/platforms/chrp_smp.c	2005-03-01 23:38:55 -08:00
@@ -57,7 +57,7 @@
 		do_openpic_setup_cpu();
 }
 
-static spinlock_t timebase_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(timebase_lock);
 static unsigned int timebase_upper = 0, timebase_lower = 0;
 
 void __devinit
diff -Nru a/arch/ppc/platforms/chrp_time.c b/arch/ppc/platforms/chrp_time.c
--- a/arch/ppc/platforms/chrp_time.c	2005-03-01 23:38:52 -08:00
+++ b/arch/ppc/platforms/chrp_time.c	2005-03-01 23:38:52 -08:00
@@ -41,6 +41,8 @@
 	int base;
 
 	rtcs = find_compatible_devices("rtc", "pnpPNP,b00");
+	if (rtcs == NULL)
+		rtcs = find_compatible_devices("rtc", "ds1385-rtc");
 	if (rtcs == NULL || rtcs->addrs == NULL)
 		return 0;
 	base = rtcs->addrs[0].address;
diff -Nru a/arch/ppc/platforms/cpci690.c b/arch/ppc/platforms/cpci690.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/ppc/platforms/cpci690.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,512 @@
+/*
+ * arch/ppc/platforms/cpci690.c
+ *
+ * Board setup routines for the Force CPCI690 board.
+ *
+ * Author: Mark A. Greer <mgreer@mvista.com>
+ *
+ * 2003 (c) MontaVista Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.  This programr
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#include <linux/config.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+#include <linux/ide.h>
+#include <linux/irq.h>
+#include <linux/fs.h>
+#include <linux/seq_file.h>
+#include <linux/console.h>
+#include <linux/initrd.h>
+#include <linux/root_dev.h>
+#include <linux/mv643xx.h>
+#include <asm/bootinfo.h>
+#include <asm/machdep.h>
+#include <asm/todc.h>
+#include <asm/time.h>
+#include <asm/mv64x60.h>
+#include <platforms/cpci690.h>
+
+#define BOARD_VENDOR	"Force"
+#define BOARD_MACHINE	"CPCI690"
+
+/* Set IDE controllers into Native mode? */
+#define SET_PCI_IDE_NATIVE
+
+static struct mv64x60_handle	bh;
+static u32 cpci690_br_base;
+
+static const unsigned int cpu_7xx[16] = { /* 7xx & 74xx (but not 745x) */
+	18, 15, 14, 2, 4, 13, 5, 9, 6, 11, 8, 10, 16, 12, 7, 0
+};
+
+TODC_ALLOC();
+
+static int __init
+cpci690_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
+{
+	struct pci_controller	*hose = pci_bus_to_hose(dev->bus->number);
+
+	if (hose->index == 0) {
+		static char pci_irq_table[][4] =
+		/*
+		 *	PCI IDSEL/INTPIN->INTLINE
+		 * 	   A   B   C   D
+		 */
+		{
+			{ 90, 91, 88, 89}, /* IDSEL 30/20 - Sentinel */
+		};
+
+		const long min_idsel = 20, max_idsel = 20, irqs_per_slot = 4;
+		return PCI_IRQ_TABLE_LOOKUP;
+	}
+	else {
+		static char pci_irq_table[][4] =
+		/*
+		 *	PCI IDSEL/INTPIN->INTLINE
+		 * 	   A   B   C   D
+		 */
+		{
+			{ 93, 94, 95, 92}, /* IDSEL 28/18 - PMC slot 2 */
+			{  0,  0,  0,  0}, /* IDSEL 29/19 - Not used */
+			{ 94, 95, 92, 93}, /* IDSEL 30/20 - PMC slot 1 */
+		};
+
+		const long min_idsel = 18, max_idsel = 20, irqs_per_slot = 4;
+		return PCI_IRQ_TABLE_LOOKUP;
+	}
+}
+
+static int
+cpci690_get_bus_speed(void)
+{
+	return 133333333;
+}
+
+static int
+cpci690_get_cpu_speed(void)
+{
+	unsigned long	hid1;
+
+	hid1 = mfspr(HID1) >> 28;
+	return cpci690_get_bus_speed() * cpu_7xx[hid1]/2;
+}
+
+#define	KB	(1024UL)
+#define	MB	(1024UL * KB)
+#define	GB	(1024UL * MB)
+
+unsigned long __init
+cpci690_find_end_of_memory(void)
+{
+	u32		mem_ctlr_size;
+	static u32	board_size;
+	static u8	first_time = 1;
+
+	if (first_time) {
+		/* Using cpci690_set_bat() mapping ==> virt addr == phys addr */
+		switch (in_8((u8 *) (cpci690_br_base +
+			CPCI690_BR_MEM_CTLR)) & 0x07) {
+		case 0x01:
+			board_size = 256*MB;
+			break;
+		case 0x02:
+			board_size = 512*MB;
+			break;
+		case 0x03:
+			board_size = 768*MB;
+			break;
+		case 0x04:
+			board_size = 1*GB;
+			break;
+		case 0x05:
+			board_size = 1*GB + 512*MB;
+			break;
+		case 0x06:
+			board_size = 2*GB;
+			break;
+		default:
+			board_size = 0xffffffff; /* use mem ctlr size */
+		} /* switch */
+
+		mem_ctlr_size =  mv64x60_get_mem_size(CONFIG_MV64X60_NEW_BASE,
+			MV64x60_TYPE_GT64260A);
+
+		/* Check that mem ctlr & board reg agree.  If not, pick MIN. */
+		if (board_size != mem_ctlr_size) {
+			printk(KERN_WARNING "Board register & memory controller"
+				"mem size disagree (board reg: 0x%lx, "
+				"mem ctlr: 0x%lx)\n",
+				(ulong)board_size, (ulong)mem_ctlr_size);
+			board_size = min(board_size, mem_ctlr_size);
+		}
+
+		first_time = 0;
+	} /* if */
+
+	return board_size;
+}
+
+static void __init
+cpci690_setup_bridge(void)
+{
+	struct mv64x60_setup_info	si;
+	int				i;
+
+	memset(&si, 0, sizeof(si));
+
+	si.phys_reg_base = CONFIG_MV64X60_NEW_BASE;
+
+	si.pci_0.enable_bus = 1;
+	si.pci_0.pci_io.cpu_base = CPCI690_PCI0_IO_START_PROC_ADDR;
+	si.pci_0.pci_io.pci_base_hi = 0;
+	si.pci_0.pci_io.pci_base_lo = CPCI690_PCI0_IO_START_PCI_ADDR;
+	si.pci_0.pci_io.size = CPCI690_PCI0_IO_SIZE;
+	si.pci_0.pci_io.swap = MV64x60_CPU2PCI_SWAP_NONE;
+	si.pci_0.pci_mem[0].cpu_base = CPCI690_PCI0_MEM_START_PROC_ADDR;
+	si.pci_0.pci_mem[0].pci_base_hi = CPCI690_PCI0_MEM_START_PCI_HI_ADDR;
+	si.pci_0.pci_mem[0].pci_base_lo = CPCI690_PCI0_MEM_START_PCI_LO_ADDR;
+	si.pci_0.pci_mem[0].size = CPCI690_PCI0_MEM_SIZE;
+	si.pci_0.pci_mem[0].swap = MV64x60_CPU2PCI_SWAP_NONE;
+	si.pci_0.pci_cmd_bits = 0;
+	si.pci_0.latency_timer = 0x80;
+
+	si.pci_1.enable_bus = 1;
+	si.pci_1.pci_io.cpu_base = CPCI690_PCI1_IO_START_PROC_ADDR;
+	si.pci_1.pci_io.pci_base_hi = 0;
+	si.pci_1.pci_io.pci_base_lo = CPCI690_PCI1_IO_START_PCI_ADDR;
+	si.pci_1.pci_io.size = CPCI690_PCI1_IO_SIZE;
+	si.pci_1.pci_io.swap = MV64x60_CPU2PCI_SWAP_NONE;
+	si.pci_1.pci_mem[0].cpu_base = CPCI690_PCI1_MEM_START_PROC_ADDR;
+	si.pci_1.pci_mem[0].pci_base_hi = CPCI690_PCI1_MEM_START_PCI_HI_ADDR;
+	si.pci_1.pci_mem[0].pci_base_lo = CPCI690_PCI1_MEM_START_PCI_LO_ADDR;
+	si.pci_1.pci_mem[0].size = CPCI690_PCI1_MEM_SIZE;
+	si.pci_1.pci_mem[0].swap = MV64x60_CPU2PCI_SWAP_NONE;
+	si.pci_1.pci_cmd_bits = 0;
+	si.pci_1.latency_timer = 0x80;
+
+	for (i=0; i<MV64x60_CPU2MEM_WINDOWS; i++) {
+		si.cpu_prot_options[i] = 0;
+		si.cpu_snoop_options[i] = GT64260_CPU_SNOOP_WB;
+		si.pci_0.acc_cntl_options[i] =
+			GT64260_PCI_ACC_CNTL_DREADEN |
+			GT64260_PCI_ACC_CNTL_RDPREFETCH |
+			GT64260_PCI_ACC_CNTL_RDLINEPREFETCH |
+			GT64260_PCI_ACC_CNTL_RDMULPREFETCH |
+			GT64260_PCI_ACC_CNTL_SWAP_NONE |
+			GT64260_PCI_ACC_CNTL_MBURST_32_BTYES;
+		si.pci_0.snoop_options[i] = GT64260_PCI_SNOOP_WB;
+		si.pci_1.acc_cntl_options[i] =
+			GT64260_PCI_ACC_CNTL_DREADEN |
+			GT64260_PCI_ACC_CNTL_RDPREFETCH |
+			GT64260_PCI_ACC_CNTL_RDLINEPREFETCH |
+			GT64260_PCI_ACC_CNTL_RDMULPREFETCH |
+			GT64260_PCI_ACC_CNTL_SWAP_NONE |
+			GT64260_PCI_ACC_CNTL_MBURST_32_BTYES;
+		si.pci_1.snoop_options[i] = GT64260_PCI_SNOOP_WB;
+	}
+
+        /* Lookup PCI host bridges */
+        if (mv64x60_init(&bh, &si))
+                printk(KERN_ERR "Bridge initialization failed.\n");
+
+	pci_dram_offset = 0; /* System mem at same addr on PCI & cpu bus */
+	ppc_md.pci_swizzle = common_swizzle;
+	ppc_md.pci_map_irq = cpci690_map_irq;
+	ppc_md.pci_exclude_device = mv64x60_pci_exclude_device;
+
+	mv64x60_set_bus(&bh, 0, 0);
+	bh.hose_a->first_busno = 0;
+	bh.hose_a->last_busno = 0xff;
+	bh.hose_a->last_busno = pciauto_bus_scan(bh.hose_a, 0);
+
+	bh.hose_b->first_busno = bh.hose_a->last_busno + 1;
+	mv64x60_set_bus(&bh, 1, bh.hose_b->first_busno);
+	bh.hose_b->last_busno = 0xff;
+	bh.hose_b->last_busno = pciauto_bus_scan(bh.hose_b,
+		bh.hose_b->first_busno);
+
+	return;
+}
+
+static void __init
+cpci690_setup_peripherals(void)
+{
+	/* Set up windows to CPLD, RTC/TODC, IPMI. */
+	mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_0_WIN, CPCI690_BR_BASE,
+		CPCI690_BR_SIZE, 0);
+	bh.ci->enable_window_32bit(&bh, MV64x60_CPU2DEV_0_WIN);
+	cpci690_br_base = (u32)ioremap(CPCI690_BR_BASE, CPCI690_BR_SIZE);
+
+	mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_1_WIN, CPCI690_TODC_BASE,
+		CPCI690_TODC_SIZE, 0);
+	bh.ci->enable_window_32bit(&bh, MV64x60_CPU2DEV_1_WIN);
+	TODC_INIT(TODC_TYPE_MK48T35, 0, 0,
+			ioremap(CPCI690_TODC_BASE, CPCI690_TODC_SIZE), 8);
+
+	mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_2_WIN, CPCI690_IPMI_BASE,
+		CPCI690_IPMI_SIZE, 0);
+	bh.ci->enable_window_32bit(&bh, MV64x60_CPU2DEV_2_WIN);
+
+	mv64x60_set_bits(&bh, MV64x60_PCI0_ARBITER_CNTL, (1<<31));
+	mv64x60_set_bits(&bh, MV64x60_PCI1_ARBITER_CNTL, (1<<31));
+
+        mv64x60_set_bits(&bh, MV64x60_CPU_MASTER_CNTL, (1<<9)); /* Only 1 cpu */
+
+	/*
+	 * Turn off timer/counters.  Not turning off watchdog timer because
+	 * can't read its reg on the 64260A so don't know if we'll be enabling
+	 * or disabling.
+	 */
+	mv64x60_clr_bits(&bh, MV64x60_TIMR_CNTR_0_3_CNTL,
+			((1<<0) | (1<<8) | (1<<16) | (1<<24)));
+	mv64x60_clr_bits(&bh, GT64260_TIMR_CNTR_4_7_CNTL,
+			((1<<0) | (1<<8) | (1<<16) | (1<<24)));
+
+	/*
+	 * Set MPSC Multiplex RMII
+	 * NOTE: ethernet driver modifies bit 0 and 1
+	 */
+	mv64x60_write(&bh, GT64260_MPP_SERIAL_PORTS_MULTIPLEX, 0x00001102);
+
+#define GPP_EXTERNAL_INTERRUPTS \
+		((1<<24) | (1<<25) | (1<<26) | (1<<27) | \
+		 (1<<28) | (1<<29) | (1<<30) | (1<<31))
+	/* PCI interrupts are inputs */
+	mv64x60_clr_bits(&bh, MV64x60_GPP_IO_CNTL, GPP_EXTERNAL_INTERRUPTS);
+	/* PCI interrupts are active low */
+	mv64x60_set_bits(&bh, MV64x60_GPP_LEVEL_CNTL, GPP_EXTERNAL_INTERRUPTS);
+
+	/* Clear any pending interrupts for these inputs and enable them. */
+	mv64x60_write(&bh, MV64x60_GPP_INTR_CAUSE, ~GPP_EXTERNAL_INTERRUPTS);
+	mv64x60_set_bits(&bh, MV64x60_GPP_INTR_MASK, GPP_EXTERNAL_INTERRUPTS);
+
+	/* Route MPP interrupt inputs to GPP */
+	mv64x60_write(&bh, MV64x60_MPP_CNTL_2, 0x00000000);
+	mv64x60_write(&bh, MV64x60_MPP_CNTL_3, 0x00000000);
+
+	return;
+}
+
+static void __init
+cpci690_setup_arch(void)
+{
+	if (ppc_md.progress)
+		ppc_md.progress("cpci690_setup_arch: enter", 0);
+#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_SDA2;
+#endif
+
+	if (ppc_md.progress)
+		ppc_md.progress("cpci690_setup_arch: Enabling L2 cache", 0);
+
+	/* Enable L2 and L3 caches (if 745x) */
+	_set_L2CR(_get_L2CR() | L2CR_L2E);
+	_set_L3CR(_get_L3CR() | L3CR_L3E);
+
+	if (ppc_md.progress)
+		ppc_md.progress("cpci690_setup_arch: Initializing bridge", 0);
+
+	cpci690_setup_bridge();		/* set up PCI bridge(s) */
+	cpci690_setup_peripherals();	/* set up chip selects/GPP/MPP etc */
+
+	if (ppc_md.progress)
+		ppc_md.progress("cpci690_setup_arch: bridge init complete", 0);
+
+	printk(KERN_INFO "%s %s port (C) 2003 MontaVista Software, Inc. "
+		"(source@mvista.com)\n", BOARD_VENDOR, BOARD_MACHINE);
+
+	if (ppc_md.progress)
+		ppc_md.progress("cpci690_setup_arch: exit", 0);
+
+	return;
+}
+
+/* Platform device data fixup routines. */
+#if defined(CONFIG_SERIAL_MPSC)
+static void __init
+cpci690_fixup_mpsc_pdata(struct platform_device *pdev)
+{
+	struct mpsc_pdata *pdata;
+
+	pdata = (struct mpsc_pdata *)pdev->dev.platform_data;
+
+	pdata->max_idle = 40;
+	pdata->default_baud = 9600;
+	pdata->brg_clk_src = 8;
+	pdata->brg_clk_freq = 133000000;
+
+	return;
+}
+
+static int __init
+cpci690_platform_notify(struct device *dev)
+{
+	static struct {
+		char	*bus_id;
+		void	((*rtn)(struct platform_device *pdev));
+	} dev_map[] = {
+		{ MPSC_CTLR_NAME "0", cpci690_fixup_mpsc_pdata },
+		{ MPSC_CTLR_NAME "1", cpci690_fixup_mpsc_pdata },
+	};
+	struct platform_device	*pdev;
+	int	i;
+
+	if (dev && dev->bus_id)
+		for (i=0; i<ARRAY_SIZE(dev_map); i++)
+			if (!strncmp(dev->bus_id, dev_map[i].bus_id,
+				BUS_ID_SIZE)) {
+
+				pdev = container_of(dev,
+					struct platform_device, dev);
+				dev_map[i].rtn(pdev);
+			}
+
+	return 0;
+}
+#endif
+
+static void
+cpci690_reset_board(void)
+{
+	u32	i = 10000;
+
+	local_irq_disable();
+	out_8((u8 *)(cpci690_br_base + CPCI690_BR_SW_RESET), 0x11);
+
+	while (i != 0) i++;
+	panic("restart failed\n");
+}
+
+static void
+cpci690_restart(char *cmd)
+{
+	cpci690_reset_board();
+}
+
+static void
+cpci690_halt(void)
+{
+	while (1);
+	/* NOTREACHED */
+}
+
+static void
+cpci690_power_off(void)
+{
+	cpci690_halt();
+	/* NOTREACHED */
+}
+
+static int
+cpci690_show_cpuinfo(struct seq_file *m)
+{
+	seq_printf(m, "vendor\t\t: " BOARD_VENDOR "\n");
+	seq_printf(m, "machine\t\t: " BOARD_MACHINE "\n");
+	seq_printf(m, "cpu MHz\t\t: %d\n", cpci690_get_cpu_speed()/1000/1000);
+	seq_printf(m, "bus MHz\t\t: %d\n", cpci690_get_bus_speed()/1000/1000);
+
+	return 0;
+}
+
+static void __init
+cpci690_calibrate_decr(void)
+{
+	ulong freq;
+
+	freq = cpci690_get_bus_speed()/4;
+
+	printk(KERN_INFO "time_init: decrementer frequency = %lu.%.6lu MHz\n",
+	       freq/1000000, freq%1000000);
+
+	tb_ticks_per_jiffy = freq / HZ;
+	tb_to_us = mulhwu_scale_factor(freq, 1000000);
+
+	return;
+}
+
+static __inline__ void
+cpci690_set_bat(u32 addr, u32 size)
+{
+	addr &= 0xfffe0000;
+	size &= 0x1ffe0000;
+	size = ((size >> 17) - 1) << 2;
+
+	mb();
+	mtspr(DBAT1U, addr | size | 0x2); /* Vs == 1; Vp == 0 */
+	mtspr(DBAT1L, addr | 0x2a); /* WIMG bits == 0101; PP == r/w access */
+	mb();
+
+	return;
+}
+
+#if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)
+static void __init
+cpci690_map_io(void)
+{
+	io_block_mapping(CONFIG_MV64X60_NEW_BASE, CONFIG_MV64X60_NEW_BASE,
+		128 * KB, _PAGE_IO);
+}
+#endif
+
+void __init
+platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
+	      unsigned long r6, unsigned long r7)
+{
+#ifdef CONFIG_BLK_DEV_INITRD
+	initrd_start=initrd_end=0;
+	initrd_below_start_ok=0;
+#endif /* CONFIG_BLK_DEV_INITRD */
+
+	parse_bootinfo(find_bootinfo());
+
+	loops_per_jiffy = cpci690_get_cpu_speed() / HZ;
+
+	isa_mem_base = 0;
+
+	ppc_md.setup_arch = cpci690_setup_arch;
+	ppc_md.show_cpuinfo = cpci690_show_cpuinfo;
+	ppc_md.init_IRQ = gt64260_init_irq;
+	ppc_md.get_irq = gt64260_get_irq;
+	ppc_md.restart = cpci690_restart;
+	ppc_md.power_off = cpci690_power_off;
+	ppc_md.halt = cpci690_halt;
+	ppc_md.find_end_of_memory = cpci690_find_end_of_memory;
+	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;
+	ppc_md.calibrate_decr = cpci690_calibrate_decr;
+
+	/*
+	 * Need to map in board regs (used by cpci690_find_end_of_memory())
+	 * and the bridge's regs (used by progress);
+	 */
+	cpci690_set_bat(CPCI690_BR_BASE, 32 * MB);
+	cpci690_br_base = CPCI690_BR_BASE;
+
+#ifdef	CONFIG_SERIAL_TEXT_DEBUG
+	ppc_md.setup_io_mappings = cpci690_map_io;
+	ppc_md.progress = mv64x60_mpsc_progress;
+	mv64x60_progress_init(CONFIG_MV64X60_NEW_BASE);
+#endif	/* CONFIG_SERIAL_TEXT_DEBUG */
+#ifdef	CONFIG_KGDB
+	ppc_md.setup_io_mappings = cpci690_map_io;
+	ppc_md.early_serial_map = cpci690_early_serial_map;
+#endif	/* CONFIG_KGDB */
+
+#if defined(CONFIG_SERIAL_MPSC)
+	platform_notify = cpci690_platform_notify;
+#endif
+
+	return;
+}
diff -Nru a/arch/ppc/platforms/cpci690.h b/arch/ppc/platforms/cpci690.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/ppc/platforms/cpci690.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,73 @@
+/*
+ * arch/ppc/platforms/cpci690.h
+ *
+ * Definitions for Force CPCI690
+ *
+ * Author: Mark A. Greer <mgreer@mvista.com>
+ *
+ * 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.
+ */
+
+/*
+ * The GT64260 has 2 PCI buses each with 1 window from the CPU bus to
+ * PCI I/O space and 4 windows from the CPU bus to PCI MEM space.
+ */
+
+#ifndef __PPC_PLATFORMS_CPCI690_H
+#define __PPC_PLATFORMS_CPCI690_H
+
+/*
+ * Define bd_t to pass in the MAC addresses used by the GT64260's enet ctlrs.
+ */
+#define	CPCI690_BI_MAGIC		0xFE8765DC
+
+typedef struct board_info {
+	u32	bi_magic;
+	u8	bi_enetaddr[3][6];
+} bd_t;
+
+/* PCI bus Resource setup */
+#define CPCI690_PCI0_MEM_START_PROC_ADDR	0x80000000
+#define CPCI690_PCI0_MEM_START_PCI_HI_ADDR	0x00000000
+#define CPCI690_PCI0_MEM_START_PCI_LO_ADDR	0x80000000
+#define CPCI690_PCI0_MEM_SIZE			0x10000000
+#define CPCI690_PCI0_IO_START_PROC_ADDR		0xa0000000
+#define CPCI690_PCI0_IO_START_PCI_ADDR		0x00000000
+#define CPCI690_PCI0_IO_SIZE			0x01000000
+
+#define CPCI690_PCI1_MEM_START_PROC_ADDR	0x90000000
+#define CPCI690_PCI1_MEM_START_PCI_HI_ADDR	0x00000000
+#define CPCI690_PCI1_MEM_START_PCI_LO_ADDR	0x90000000
+#define CPCI690_PCI1_MEM_SIZE			0x10000000
+#define CPCI690_PCI1_IO_START_PROC_ADDR		0xa1000000
+#define CPCI690_PCI1_IO_START_PCI_ADDR		0x01000000
+#define CPCI690_PCI1_IO_SIZE			0x01000000
+
+/* Board Registers */
+#define	CPCI690_BR_BASE				0xf0000000
+#define	CPCI690_BR_SIZE_ACTUAL			0x8
+#define	CPCI690_BR_SIZE			max(GT64260_WINDOW_SIZE_MIN,	\
+						CPCI690_BR_SIZE_ACTUAL)
+#define	CPCI690_BR_LED_CNTL			0x00
+#define	CPCI690_BR_SW_RESET			0x01
+#define	CPCI690_BR_MISC_STATUS			0x02
+#define	CPCI690_BR_SWITCH_STATUS		0x03
+#define	CPCI690_BR_MEM_CTLR			0x04
+#define	CPCI690_BR_LAST_RESET_1			0x05
+#define	CPCI690_BR_LAST_RESET_2			0x06
+
+#define	CPCI690_TODC_BASE			0xf0100000
+#define	CPCI690_TODC_SIZE_ACTUAL		0x8000 /* Size or NVRAM + RTC */
+#define	CPCI690_TODC_SIZE		max(GT64260_WINDOW_SIZE_MIN,	\
+						CPCI690_TODC_SIZE_ACTUAL)
+#define	CPCI690_MAC_OFFSET			0x7c10 /* MAC in RTC NVRAM */
+
+#define	CPCI690_IPMI_BASE			0xf0200000
+#define	CPCI690_IPMI_SIZE_ACTUAL		0x10 /* 16 bytes of IPMI */
+#define	CPCI690_IPMI_SIZE		max(GT64260_WINDOW_SIZE_MIN,	\
+						CPCI690_IPMI_SIZE_ACTUAL)
+
+#endif /* __PPC_PLATFORMS_CPCI690_H */
diff -Nru a/arch/ppc/platforms/ev64260.c b/arch/ppc/platforms/ev64260.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/ppc/platforms/ev64260.c	2005-03-01 23:39:26 -08:00
@@ -0,0 +1,651 @@
+/*
+ * arch/ppc/platforms/ev64260.c
+ *
+ * Board setup routines for the Marvell/Galileo EV-64260-BP Evaluation Board.
+ *
+ * Author: Mark A. Greer <mgreer@mvista.com>
+ *
+ * 2001-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.
+ */
+
+/*
+ * The EV-64260-BP port is the result of hard work from many people from
+ * many companies.  In particular, employees of Marvell/Galileo, Mission
+ * Critical Linux, Xyterra, and MontaVista Software were heavily involved.
+ *
+ * Note: I have not been able to get *all* PCI slots to work reliably
+ *	at 66 MHz.  I recommend setting jumpers J15 & J16 to short pins 1&2
+ *	so that 33 MHz is used. --MAG
+ * Note: The 750CXe and 7450 are not stable with a 125MHz or 133MHz TCLK/SYSCLK.
+ * 	At 100MHz, they are solid.
+ */
+#include <linux/config.h>
+
+#include <linux/delay.h>
+#include <linux/pci.h>
+#include <linux/ide.h>
+#include <linux/irq.h>
+#include <linux/fs.h>
+#include <linux/seq_file.h>
+#include <linux/console.h>
+#include <linux/initrd.h>
+#include <linux/root_dev.h>
+#if !defined(CONFIG_SERIAL_MPSC_CONSOLE)
+#include <linux/serial.h>
+#include <linux/tty.h>
+#include <linux/serial_core.h>
+#else
+#include <linux/mv643xx.h>
+#endif
+#include <asm/bootinfo.h>
+#include <asm/machdep.h>
+#include <asm/mv64x60.h>
+#include <asm/todc.h>
+#include <asm/time.h>
+
+#include <platforms/ev64260.h>
+
+#define BOARD_VENDOR	"Marvell/Galileo"
+#define BOARD_MACHINE	"EV-64260-BP"
+
+static struct mv64x60_handle	bh;
+
+#if !defined(CONFIG_SERIAL_MPSC_CONSOLE)
+extern void gen550_progress(char *, unsigned short);
+extern void gen550_init(int, struct uart_port *);
+#endif
+
+static const unsigned int cpu_7xx[16] = { /* 7xx & 74xx (but not 745x) */
+	18, 15, 14, 2, 4, 13, 5, 9, 6, 11, 8, 10, 16, 12, 7, 0
+};
+static const unsigned int cpu_745x[2][16] = { /* PLL_EXT 0 & 1 */
+	{ 1, 15, 14,  2,  4, 13,  5,  9,  6, 11,  8, 10, 16, 12,  7,  0 },
+	{ 0, 30,  0,  2,  0, 26,  0, 18,  0, 22, 20, 24, 28, 32,  0,  0 }
+};
+
+
+TODC_ALLOC();
+
+static int
+ev64260_get_bus_speed(void)
+{
+	return 100000000;
+}
+
+static int
+ev64260_get_cpu_speed(void)
+{
+	unsigned long	pvr, hid1, pll_ext;
+
+	pvr = PVR_VER(mfspr(PVR));
+
+	if (pvr != PVR_VER(PVR_7450)) {
+		hid1 = mfspr(HID1) >> 28;
+		return ev64260_get_bus_speed() * cpu_7xx[hid1]/2;
+	}
+	else {
+		hid1 = (mfspr(HID1) & 0x0001e000) >> 13;
+		pll_ext = 0; /* No way to read; must get from schematic */
+		return ev64260_get_bus_speed() * cpu_745x[pll_ext][hid1]/2;
+	}
+}
+
+unsigned long __init
+ev64260_find_end_of_memory(void)
+{
+	return mv64x60_get_mem_size(CONFIG_MV64X60_NEW_BASE,
+		MV64x60_TYPE_GT64260A);
+}
+
+/*
+ * Marvell/Galileo EV-64260-BP Evaluation Board PCI interrupt routing.
+ * Note: By playing with J8 and JP1-4, you can get 2 IRQ's from the first
+ *	PCI bus (in which cast, INTPIN B would be EV64260_PCI_1_IRQ).
+ *	This is the most IRQs you can get from one bus with this board, though.
+ */
+static int __init
+ev64260_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
+{
+	struct pci_controller	*hose = pci_bus_to_hose(dev->bus->number);
+
+	if (hose->index == 0) {
+		static char pci_irq_table[][4] =
+		/*
+		 *	PCI IDSEL/INTPIN->INTLINE
+		 * 	   A   B   C   D
+		 */
+		{
+			{EV64260_PCI_0_IRQ,0,0,0}, /* IDSEL 7 - PCI bus 0 */
+			{EV64260_PCI_0_IRQ,0,0,0}, /* IDSEL 8 - PCI bus 0 */
+		};
+
+		const long min_idsel = 7, max_idsel = 8, irqs_per_slot = 4;
+		return PCI_IRQ_TABLE_LOOKUP;
+	}
+	else {
+		static char pci_irq_table[][4] =
+		/*
+		 *	PCI IDSEL/INTPIN->INTLINE
+		 * 	   A   B   C   D
+		 */
+		{
+			{ EV64260_PCI_1_IRQ,0,0,0}, /* IDSEL 7 - PCI bus 1 */
+			{ EV64260_PCI_1_IRQ,0,0,0}, /* IDSEL 8 - PCI bus 1 */
+		};
+
+		const long min_idsel = 7, max_idsel = 8, irqs_per_slot = 4;
+		return PCI_IRQ_TABLE_LOOKUP;
+	}
+}
+
+static void __init
+ev64260_setup_peripherals(void)
+{
+	mv64x60_set_32bit_window(&bh, MV64x60_CPU2BOOT_WIN,
+		EV64260_EMB_FLASH_BASE, EV64260_EMB_FLASH_SIZE, 0);
+	bh.ci->enable_window_32bit(&bh, MV64x60_CPU2BOOT_WIN);
+	mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_0_WIN,
+		EV64260_EXT_SRAM_BASE, EV64260_EXT_SRAM_SIZE, 0);
+	bh.ci->enable_window_32bit(&bh, MV64x60_CPU2DEV_0_WIN);
+	mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_1_WIN,
+		EV64260_TODC_BASE, EV64260_TODC_SIZE, 0);
+	bh.ci->enable_window_32bit(&bh, MV64x60_CPU2DEV_1_WIN);
+	mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_2_WIN,
+		EV64260_UART_BASE, EV64260_UART_SIZE, 0);
+	bh.ci->enable_window_32bit(&bh, MV64x60_CPU2DEV_2_WIN);
+	mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_3_WIN,
+		EV64260_EXT_FLASH_BASE, EV64260_EXT_FLASH_SIZE, 0);
+	bh.ci->enable_window_32bit(&bh, MV64x60_CPU2DEV_3_WIN);
+
+	TODC_INIT(TODC_TYPE_DS1501, 0, 0,
+			ioremap(EV64260_TODC_BASE, EV64260_TODC_SIZE), 8);
+
+	mv64x60_clr_bits(&bh, MV64x60_CPU_CONFIG,((1<<12) | (1<<28) | (1<<29)));
+	mv64x60_set_bits(&bh, MV64x60_CPU_CONFIG, (1<<27));
+
+	if (ev64260_get_bus_speed() > 100000000)
+		mv64x60_set_bits(&bh, MV64x60_CPU_CONFIG, (1<<23));
+
+	mv64x60_set_bits(&bh, MV64x60_PCI0_PCI_DECODE_CNTL, ((1<<0) | (1<<3)));
+	mv64x60_set_bits(&bh, MV64x60_PCI1_PCI_DECODE_CNTL, ((1<<0) | (1<<3)));
+
+        /*
+         * Enabling of PCI internal-vs-external arbitration
+         * is a platform- and errata-dependent decision.
+         */
+        if (bh.type == MV64x60_TYPE_GT64260A )  {
+                mv64x60_set_bits(&bh, MV64x60_PCI0_ARBITER_CNTL, (1<<31));
+                mv64x60_set_bits(&bh, MV64x60_PCI1_ARBITER_CNTL, (1<<31));
+        }
+
+        mv64x60_set_bits(&bh, MV64x60_CPU_MASTER_CNTL, (1<<9)); /* Only 1 cpu */
+
+	/*
+	 * Turn off timer/counters.  Not turning off watchdog timer because
+	 * can't read its reg on the 64260A so don't know if we'll be enabling
+	 * or disabling.
+	 */
+	mv64x60_clr_bits(&bh, MV64x60_TIMR_CNTR_0_3_CNTL,
+			((1<<0) | (1<<8) | (1<<16) | (1<<24)));
+	mv64x60_clr_bits(&bh, GT64260_TIMR_CNTR_4_7_CNTL,
+			((1<<0) | (1<<8) | (1<<16) | (1<<24)));
+
+	/*
+	 * Set MPSC Multiplex RMII
+	 * NOTE: ethernet driver modifies bit 0 and 1
+	 */
+	mv64x60_write(&bh, GT64260_MPP_SERIAL_PORTS_MULTIPLEX, 0x00001102);
+
+	/*
+	 * The EV-64260-BP uses several Multi-Purpose Pins (MPP) on the 64260
+	 * bridge as interrupt inputs (via the General Purpose Ports (GPP)
+	 * register).  Need to route the MPP inputs to the GPP and set the
+	 * polarity correctly.
+	 *
+	 * In MPP Control 2 Register
+	 *   MPP 21 -> GPP 21 (DUART channel A intr) bits 20-23 -> 0
+	 *   MPP 22 -> GPP 22 (DUART channel B intr) bits 24-27 -> 0
+	 */
+	mv64x60_clr_bits(&bh, MV64x60_MPP_CNTL_2, (0xf<<20) | (0xf<<24) );
+
+	/*
+	 * In MPP Control 3 Register
+	 *   MPP 26 -> GPP 26 (RTC INT)		bits  8-11 -> 0
+	 *   MPP 27 -> GPP 27 (PCI 0 INTA)	bits 12-15 -> 0
+	 *   MPP 29 -> GPP 29 (PCI 1 INTA)	bits 20-23 -> 0
+	 */
+	mv64x60_clr_bits(&bh, MV64x60_MPP_CNTL_3, (0xf<<8)|(0xf<<12)|(0xf<<20));
+
+#define GPP_EXTERNAL_INTERRUPTS \
+		((1<<21) | (1<<22) | (1<<26) | (1<<27) | (1<<29))
+	/* DUART & PCI interrupts are inputs */
+	mv64x60_clr_bits(&bh, MV64x60_GPP_IO_CNTL, GPP_EXTERNAL_INTERRUPTS);
+	/* DUART & PCI interrupts are active low */
+	mv64x60_set_bits(&bh, MV64x60_GPP_LEVEL_CNTL, GPP_EXTERNAL_INTERRUPTS);
+
+	/* Clear any pending interrupts for these inputs and enable them. */
+	mv64x60_write(&bh, MV64x60_GPP_INTR_CAUSE, ~GPP_EXTERNAL_INTERRUPTS);
+	mv64x60_set_bits(&bh, MV64x60_GPP_INTR_MASK, GPP_EXTERNAL_INTERRUPTS);
+
+	return;
+}
+
+static void __init
+ev64260_setup_bridge(void)
+{
+	struct mv64x60_setup_info	si;
+	int				i;
+
+	memset(&si, 0, sizeof(si));
+
+	si.phys_reg_base = CONFIG_MV64X60_NEW_BASE;
+
+	si.pci_0.enable_bus = 1;
+	si.pci_0.pci_io.cpu_base = EV64260_PCI0_IO_CPU_BASE;
+	si.pci_0.pci_io.pci_base_hi = 0;
+	si.pci_0.pci_io.pci_base_lo = EV64260_PCI0_IO_PCI_BASE;
+	si.pci_0.pci_io.size = EV64260_PCI0_IO_SIZE;
+	si.pci_0.pci_io.swap = MV64x60_CPU2PCI_SWAP_NONE;
+	si.pci_0.pci_mem[0].cpu_base = EV64260_PCI0_MEM_CPU_BASE;
+	si.pci_0.pci_mem[0].pci_base_hi = 0;
+	si.pci_0.pci_mem[0].pci_base_lo = EV64260_PCI0_MEM_PCI_BASE;
+	si.pci_0.pci_mem[0].size = EV64260_PCI0_MEM_SIZE;
+	si.pci_0.pci_mem[0].swap = MV64x60_CPU2PCI_SWAP_NONE;
+	si.pci_0.pci_cmd_bits = 0;
+	si.pci_0.latency_timer = 0x8;
+
+	si.pci_1.enable_bus = 1;
+	si.pci_1.pci_io.cpu_base = EV64260_PCI1_IO_CPU_BASE;
+	si.pci_1.pci_io.pci_base_hi = 0;
+	si.pci_1.pci_io.pci_base_lo = EV64260_PCI1_IO_PCI_BASE;
+	si.pci_1.pci_io.size = EV64260_PCI1_IO_SIZE;
+	si.pci_1.pci_io.swap = MV64x60_CPU2PCI_SWAP_NONE;
+	si.pci_1.pci_mem[0].cpu_base = EV64260_PCI1_MEM_CPU_BASE;
+	si.pci_1.pci_mem[0].pci_base_hi = 0;
+	si.pci_1.pci_mem[0].pci_base_lo = EV64260_PCI1_MEM_PCI_BASE;
+	si.pci_1.pci_mem[0].size = EV64260_PCI1_MEM_SIZE;
+	si.pci_1.pci_mem[0].swap = MV64x60_CPU2PCI_SWAP_NONE;
+	si.pci_1.pci_cmd_bits = 0;
+	si.pci_1.latency_timer = 0x8;
+
+	for (i=0; i<MV64x60_CPU2MEM_WINDOWS; i++) {
+		si.cpu_prot_options[i] = 0;
+		si.cpu_snoop_options[i] = GT64260_CPU_SNOOP_WB;
+		si.pci_0.acc_cntl_options[i] =
+			GT64260_PCI_ACC_CNTL_DREADEN |
+			GT64260_PCI_ACC_CNTL_RDPREFETCH |
+			GT64260_PCI_ACC_CNTL_RDLINEPREFETCH |
+			GT64260_PCI_ACC_CNTL_RDMULPREFETCH |
+			GT64260_PCI_ACC_CNTL_SWAP_NONE |
+			GT64260_PCI_ACC_CNTL_MBURST_32_BTYES;
+		si.pci_0.snoop_options[i] = GT64260_PCI_SNOOP_WB;
+		si.pci_1.acc_cntl_options[i] =
+			GT64260_PCI_ACC_CNTL_DREADEN |
+			GT64260_PCI_ACC_CNTL_RDPREFETCH |
+			GT64260_PCI_ACC_CNTL_RDLINEPREFETCH |
+			GT64260_PCI_ACC_CNTL_RDMULPREFETCH |
+			GT64260_PCI_ACC_CNTL_SWAP_NONE |
+			GT64260_PCI_ACC_CNTL_MBURST_32_BTYES;
+		si.pci_1.snoop_options[i] = GT64260_PCI_SNOOP_WB;
+	}
+
+        /* Lookup PCI host bridges */
+        if (mv64x60_init(&bh, &si))
+                printk(KERN_ERR "Bridge initialization failed.\n");
+
+	pci_dram_offset = 0; /* System mem at same addr on PCI & cpu bus */
+	ppc_md.pci_swizzle = common_swizzle;
+	ppc_md.pci_map_irq = ev64260_map_irq;
+	ppc_md.pci_exclude_device = mv64x60_pci_exclude_device;
+
+	mv64x60_set_bus(&bh, 0, 0);
+	bh.hose_a->first_busno = 0;
+	bh.hose_a->last_busno = 0xff;
+	bh.hose_a->last_busno = pciauto_bus_scan(bh.hose_a, 0);
+
+	bh.hose_b->first_busno = bh.hose_a->last_busno + 1;
+	mv64x60_set_bus(&bh, 1, bh.hose_b->first_busno);
+	bh.hose_b->last_busno = 0xff;
+	bh.hose_b->last_busno = pciauto_bus_scan(bh.hose_b,
+		bh.hose_b->first_busno);
+
+	return;
+}
+
+#if defined(CONFIG_SERIAL_8250) && !defined(CONFIG_SERIAL_MPSC_CONSOLE)
+static void __init
+ev64260_early_serial_map(void)
+{
+	struct uart_port	port;
+	static char		first_time = 1;
+
+	if (first_time) {
+		memset(&port, 0, sizeof(port));
+
+		port.membase = ioremap(EV64260_SERIAL_0, EV64260_UART_SIZE);
+		port.irq = EV64260_UART_0_IRQ;
+		port.uartclk = BASE_BAUD * 16;
+		port.regshift = 2;
+		port.iotype = SERIAL_IO_MEM;
+		port.flags = STD_COM_FLAGS;
+
+#if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)
+		gen550_init(0, &port);
+#endif
+
+		if (early_serial_setup(&port) != 0)
+			printk(KERN_WARNING "Early serial init of port 0"
+				"failed\n");
+
+		first_time = 0;
+	}
+
+	return;
+}
+#elif defined(CONFIG_SERIAL_MPSC_CONSOLE)
+static void __init
+ev64260_early_serial_map(void)
+{
+}
+#endif
+
+static void __init
+ev64260_setup_arch(void)
+{
+	if (ppc_md.progress)
+		ppc_md.progress("ev64260_setup_arch: enter", 0);
+
+#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_SDA2;
+#endif
+
+	if (ppc_md.progress)
+		ppc_md.progress("ev64260_setup_arch: Enabling L2 cache", 0);
+
+	/* Enable L2 and L3 caches (if 745x) */
+	_set_L2CR(_get_L2CR() | L2CR_L2E);
+	_set_L3CR(_get_L3CR() | L3CR_L3E);
+
+	if (ppc_md.progress)
+		ppc_md.progress("ev64260_setup_arch: Initializing bridge", 0);
+
+	ev64260_setup_bridge();		/* set up PCI bridge(s) */
+	ev64260_setup_peripherals();	/* set up chip selects/GPP/MPP etc */
+
+	if (ppc_md.progress)
+		ppc_md.progress("ev64260_setup_arch: bridge init complete", 0);
+
+#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_MPSC_CONSOLE)
+	ev64260_early_serial_map();
+#endif
+
+	printk(KERN_INFO "%s %s port (C) 2001 MontaVista Software, Inc."
+		"(source@mvista.com)\n", BOARD_VENDOR, BOARD_MACHINE);
+
+	if (ppc_md.progress)
+		ppc_md.progress("ev64260_setup_arch: exit", 0);
+
+	return;
+}
+
+/* Platform device data fixup routines. */
+#if defined(CONFIG_SERIAL_MPSC)
+static void __init
+ev64260_fixup_mpsc_pdata(struct platform_device *pdev)
+{
+	struct mpsc_pdata *pdata;
+
+	pdata = (struct mpsc_pdata *)pdev->dev.platform_data;
+
+	pdata->max_idle = 40;
+	pdata->default_baud = EV64260_DEFAULT_BAUD;
+	pdata->brg_clk_src = EV64260_MPSC_CLK_SRC;
+	pdata->brg_clk_freq = EV64260_MPSC_CLK_FREQ;
+
+	return;
+}
+
+static int __init
+ev64260_platform_notify(struct device *dev)
+{
+	static struct {
+		char	*bus_id;
+		void	((*rtn)(struct platform_device *pdev));
+	} dev_map[] = {
+		{ MPSC_CTLR_NAME "0", ev64260_fixup_mpsc_pdata },
+		{ MPSC_CTLR_NAME "1", ev64260_fixup_mpsc_pdata },
+	};
+	struct platform_device	*pdev;
+	int	i;
+
+	if (dev && dev->bus_id)
+		for (i=0; i<ARRAY_SIZE(dev_map); i++)
+			if (!strncmp(dev->bus_id, dev_map[i].bus_id,
+				BUS_ID_SIZE)) {
+
+				pdev = container_of(dev,
+					struct platform_device, dev);
+				dev_map[i].rtn(pdev);
+			}
+
+	return 0;
+}
+#endif
+
+static void
+ev64260_reset_board(void *addr)
+{
+	local_irq_disable();
+
+	/* disable and invalidate the L2 cache */
+	_set_L2CR(0);
+	_set_L2CR(0x200000);
+
+	/* flush and disable L1 I/D cache */
+	__asm__ __volatile__
+	("mfspr   3,1008\n\t"
+	 "ori	5,5,0xcc00\n\t"
+	 "ori	4,3,0xc00\n\t"
+	 "andc	5,3,5\n\t"
+	 "sync\n\t"
+	 "mtspr	1008,4\n\t"
+	 "isync\n\t"
+	 "sync\n\t"
+	 "mtspr	1008,5\n\t"
+	 "isync\n\t"
+	 "sync\n\t");
+
+	/* unmap any other random cs's that might overlap with bootcs */
+	mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_0_WIN, 0, 0, 0);
+	bh.ci->disable_window_32bit(&bh, MV64x60_CPU2DEV_0_WIN);
+	mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_1_WIN, 0, 0, 0);
+	bh.ci->disable_window_32bit(&bh, MV64x60_CPU2DEV_1_WIN);
+	mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_2_WIN, 0, 0, 0);
+	bh.ci->disable_window_32bit(&bh, MV64x60_CPU2DEV_2_WIN);
+	mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_3_WIN, 0, 0, 0);
+	bh.ci->disable_window_32bit(&bh, MV64x60_CPU2DEV_3_WIN);
+
+	/* map bootrom back in to gt @ reset defaults */
+	mv64x60_set_32bit_window(&bh, MV64x60_CPU2BOOT_WIN,
+						0xff800000, 8*1024*1024, 0);
+	bh.ci->enable_window_32bit(&bh, MV64x60_CPU2BOOT_WIN);
+
+	/* move reg base back to default, setup default pci0 */
+	mv64x60_write(&bh, MV64x60_INTERNAL_SPACE_DECODE,
+		(1<<24) | CONFIG_MV64X60_BASE >> 20);
+
+	/* NOTE: FROM NOW ON no more GT_REGS accesses.. 0x1 is not mapped
+	 * via BAT or MMU, and MSR IR/DR is ON */
+	/* SRR0 has system reset vector, SRR1 has default MSR value */
+	/* rfi restores MSR from SRR1 and sets the PC to the SRR0 value */
+	/* NOTE: assumes reset vector is at 0xfff00100 */
+	__asm__ __volatile__
+	("mtspr   26, %0\n\t"
+	 "li      4,(1<<6)\n\t"
+	 "mtspr   27,4\n\t"
+	 "rfi\n\t"
+	 :: "r" (addr):"r4");
+
+	return;
+}
+
+static void
+ev64260_restart(char *cmd)
+{
+	volatile ulong	i = 10000000;
+
+	ev64260_reset_board((void *)0xfff00100);
+
+	while (i-- > 0);
+	panic("restart failed\n");
+}
+
+static void
+ev64260_halt(void)
+{
+	local_irq_disable();
+	while (1);
+	/* NOTREACHED */
+}
+
+static void
+ev64260_power_off(void)
+{
+	ev64260_halt();
+	/* NOTREACHED */
+}
+
+static int
+ev64260_show_cpuinfo(struct seq_file *m)
+{
+	uint pvid;
+
+	pvid = mfspr(PVR);
+	seq_printf(m, "vendor\t\t: " BOARD_VENDOR "\n");
+	seq_printf(m, "machine\t\t: " BOARD_MACHINE "\n");
+	seq_printf(m, "cpu MHz\t\t: %d\n", ev64260_get_cpu_speed()/1000/1000);
+	seq_printf(m, "bus MHz\t\t: %d\n", ev64260_get_bus_speed()/1000/1000);
+
+	return 0;
+}
+
+/* DS1501 RTC has too much variation to use RTC for calibration */
+static void __init
+ev64260_calibrate_decr(void)
+{
+	ulong freq;
+
+	freq = ev64260_get_bus_speed()/4;
+
+	printk(KERN_INFO "time_init: decrementer frequency = %lu.%.6lu MHz\n",
+	       freq/1000000, freq%1000000);
+
+	tb_ticks_per_jiffy = freq / HZ;
+	tb_to_us = mulhwu_scale_factor(freq, 1000000);
+
+	return;
+}
+
+/*
+ * Set BAT 3 to map 0xfb000000 to 0xfc000000 of physical memory space.
+ */
+static __inline__ void
+ev64260_set_bat(void)
+{
+	mb();
+	mtspr(DBAT1U, 0xfb0001fe);
+	mtspr(DBAT1L, 0xfb00002a);
+	mb();
+
+	return;
+}
+
+#if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)
+static void __init
+ev64260_map_io(void)
+{
+	io_block_mapping(0xfb000000, 0xfb000000, 0x01000000, _PAGE_IO);
+}
+#endif
+
+void __init
+platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
+	      unsigned long r6, unsigned long r7)
+{
+#ifdef CONFIG_BLK_DEV_INITRD
+	extern int	initrd_below_start_ok;
+
+	initrd_start=initrd_end=0;
+	initrd_below_start_ok=0;
+#endif /* CONFIG_BLK_DEV_INITRD */
+
+	parse_bootinfo(find_bootinfo());
+
+	isa_mem_base = 0;
+	isa_io_base = EV64260_PCI0_IO_CPU_BASE;
+	pci_dram_offset = EV64260_PCI0_MEM_CPU_BASE;
+
+	loops_per_jiffy = ev64260_get_cpu_speed() / HZ;
+
+	ppc_md.setup_arch = ev64260_setup_arch;
+	ppc_md.show_cpuinfo = ev64260_show_cpuinfo;
+	ppc_md.init_IRQ = gt64260_init_irq;
+	ppc_md.get_irq = gt64260_get_irq;
+
+	ppc_md.restart = ev64260_restart;
+	ppc_md.power_off = ev64260_power_off;
+	ppc_md.halt = ev64260_halt;
+
+	ppc_md.find_end_of_memory = ev64260_find_end_of_memory;
+
+	ppc_md.init = NULL;
+
+	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;
+	ppc_md.calibrate_decr = ev64260_calibrate_decr;
+
+	bh.p_base = CONFIG_MV64X60_NEW_BASE;
+
+	ev64260_set_bat();
+
+#ifdef	CONFIG_SERIAL_8250
+#if defined(CONFIG_SERIAL_TEXT_DEBUG)
+	ppc_md.setup_io_mappings = ev64260_map_io;
+	ppc_md.progress = gen550_progress;
+#endif
+#if defined(CONFIG_KGDB)
+	ppc_md.setup_io_mappings = ev64260_map_io;
+	ppc_md.early_serial_map = ev64260_early_serial_map;
+#endif
+#elif defined(CONFIG_SERIAL_MPSC_CONSOLE)
+#ifdef	CONFIG_SERIAL_TEXT_DEBUG
+	ppc_md.setup_io_mappings = ev64260_map_io;
+	ppc_md.progress = mv64x60_mpsc_progress;
+	mv64x60_progress_init(CONFIG_MV64X60_NEW_BASE);
+#endif	/* CONFIG_SERIAL_TEXT_DEBUG */
+#ifdef	CONFIG_KGDB
+	ppc_md.setup_io_mappings = ev64260_map_io;
+	ppc_md.early_serial_map = ev64260_early_serial_map;
+#endif	/* CONFIG_KGDB */
+
+#endif
+
+#if defined(CONFIG_SERIAL_MPSC)
+	platform_notify = ev64260_platform_notify;
+#endif
+
+	return;
+}
diff -Nru a/arch/ppc/platforms/ev64260.h b/arch/ppc/platforms/ev64260.h
--- a/arch/ppc/platforms/ev64260.h	2005-03-01 23:38:44 -08:00
+++ b/arch/ppc/platforms/ev64260.h	2005-03-01 23:38:44 -08:00
@@ -5,38 +5,103 @@
  *
  * Author: Mark A. Greer <mgreer@mvista.com>
  *
- * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * 2001-2002 (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.
  */
 
 /*
- * The GT64260 has 2 PCI buses each with 1 window from the CPU bus to
+ * The MV64x60 has 2 PCI buses each with 1 window from the CPU bus to
  * PCI I/O space and 4 windows from the CPU bus to PCI MEM space.
  * We'll only use one PCI MEM window on each PCI bus.
+ *
+ * This is the CPU physical memory map (windows must be at least 1MB and start
+ * on a boundary that is a multiple of the window size):
+ *
+ * 	0xfc000000-0xffffffff		- External FLASH on device module
+ * 	0xfbf00000-0xfbffffff		- Embedded (on board) FLASH
+ * 	0xfbe00000-0xfbefffff		- GT64260 Registers (preferably)
+ * 					  but really a config option
+ * 	0xfbd00000-0xfbdfffff		- External SRAM on device module
+ * 	0xfbc00000-0xfbcfffff		- TODC chip on device module
+ * 	0xfbb00000-0xfbbfffff		- External UART on device module
+ * 	0xa2000000-0xfbafffff		- <hole>
+ * 	0xa1000000-0xa1ffffff		- PCI 1 I/O (defined in gt64260.h)
+ * 	0xa0000000-0xa0ffffff		- PCI 0 I/O (defined in gt64260.h)
+ * 	0x90000000-0x9fffffff		- PCI 1 MEM (defined in gt64260.h)
+ * 	0x80000000-0x8fffffff		- PCI 0 MEM (defined in gt64260.h)
  */
 
 #ifndef __PPC_PLATFORMS_EV64260_H
 #define __PPC_PLATFORMS_EV64260_H
 
-#define	EV64260_BRIDGE_REG_BASE		0xf8000000
-#define	EV64260_BRIDGE_REG_BASE_TO_TOP	0x08000000U
+/* PCI mappings */
+#define	EV64260_PCI0_IO_CPU_BASE	0xa0000000
+#define	EV64260_PCI0_IO_PCI_BASE	0x00000000
+#define	EV64260_PCI0_IO_SIZE		0x01000000
+
+#define	EV64260_PCI0_MEM_CPU_BASE	0x80000000
+#define	EV64260_PCI0_MEM_PCI_BASE	0x80000000
+#define	EV64260_PCI0_MEM_SIZE		0x10000000
+
+#define	EV64260_PCI1_IO_CPU_BASE	(EV64260_PCI0_IO_CPU_BASE + \
+						EV64260_PCI0_IO_SIZE)
+#define	EV64260_PCI1_IO_PCI_BASE	(EV64260_PCI0_IO_PCI_BASE + \
+						EV64260_PCI0_IO_SIZE)
+#define	EV64260_PCI1_IO_SIZE		0x01000000
+
+#define	EV64260_PCI1_MEM_CPU_BASE	(EV64260_PCI0_MEM_CPU_BASE + \
+						EV64260_PCI0_MEM_SIZE)
+#define	EV64260_PCI1_MEM_PCI_BASE	(EV64260_PCI0_MEM_PCI_BASE + \
+						EV64260_PCI0_MEM_SIZE)
+#define	EV64260_PCI1_MEM_SIZE		0x10000000
+
+/* CPU Physical Memory Map setup (other than PCI) */
+#define	EV64260_EXT_FLASH_BASE		0xfc000000
+#define	EV64260_EMB_FLASH_BASE		0xfbf00000
+#define	EV64260_EXT_SRAM_BASE		0xfbd00000
+#define	EV64260_TODC_BASE		0xfbc00000
+#define	EV64260_UART_BASE		0xfbb00000
+
+#define	EV64260_EXT_FLASH_SIZE_ACTUAL	0x04000000  /* <= 64MB Extern FLASH */
+#define	EV64260_EMB_FLASH_SIZE_ACTUAL	0x00080000  /* 512KB of Embed FLASH */
+#define	EV64260_EXT_SRAM_SIZE_ACTUAL	0x00100000  /* 1MB SDRAM */
+#define	EV64260_TODC_SIZE_ACTUAL	0x00000020  /* 32 bytes for TODC */
+#define	EV64260_UART_SIZE_ACTUAL	0x00000040  /* 64 bytes for DUART */
+
+#define	EV64260_EXT_FLASH_SIZE		max(GT64260_WINDOW_SIZE_MIN,	\
+						EV64260_EXT_FLASH_SIZE_ACTUAL)
+#define	EV64260_EMB_FLASH_SIZE		max(GT64260_WINDOW_SIZE_MIN,	\
+						EV64260_EMB_FLASH_SIZE_ACTUAL)
+#define	EV64260_EXT_SRAM_SIZE		max(GT64260_WINDOW_SIZE_MIN,	\
+						EV64260_EXT_SRAM_SIZE_ACTUAL)
+#define	EV64260_TODC_SIZE		max(GT64260_WINDOW_SIZE_MIN,	\
+						EV64260_TODC_SIZE_ACTUAL)
+/* Assembler in bootwrapper blows up if 'max' is used */
+#define	EV64260_UART_SIZE		GT64260_WINDOW_SIZE_MIN
+#define	EV64260_UART_END		((EV64260_UART_BASE +		\
+					EV64260_UART_SIZE - 1) & 0xfff00000)
+
+/* Board-specific IRQ info */
+#define	EV64260_UART_0_IRQ		85
+#define	EV64260_UART_1_IRQ		86
+#define	EV64260_PCI_0_IRQ		91
+#define	EV64260_PCI_1_IRQ		93
 
-#define	EV64260_TODC_BASE		0xfc800000
-#define	EV64260_TODC_LEN		0x00800000
-#define	EV64260_TODC_END		(EV64260_TODC_BASE + \
-					 EV64260_TODC_LEN - 1)
-
-#define	EV64260_UART_BASE		0xfd000000
-#define	EV64260_UART_LEN		0x00800000
-#define	EV64260_UART_END		(EV64260_UART_BASE + \
-					 EV64260_UART_LEN - 1)
-/* Serial driver setup.  */
+/* Serial port setup */
+#define	EV64260_DEFAULT_BAUD		115200
+
+#if defined(CONFIG_SERIAL_MPSC_CONSOLE)
+#define SERIAL_PORT_DFNS
+
+#define	EV64260_MPSC_CLK_SRC		8		/* TCLK */
+#define	EV64260_MPSC_CLK_FREQ		100000000	/* 100MHz clk */
+#else
 #define EV64260_SERIAL_0		(EV64260_UART_BASE + 0x20)
 #define EV64260_SERIAL_1		EV64260_UART_BASE
 
-#define BASE_BAUD ( 3686400 / 16 )
+#define BASE_BAUD	(EV64260_DEFAULT_BAUD * 2)
 
 #ifdef CONFIG_SERIAL_MANY_PORTS
 #define RS_TABLE_SIZE	64
@@ -50,18 +115,14 @@
 #define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST)
 #endif
 
-#if	!defined(CONFIG_GT64260_CONSOLE)
 /* Required for bootloader's ns16550.c code */
 #define STD_SERIAL_PORT_DFNS 						\
-        { 0, BASE_BAUD, EV64260_SERIAL_0, 85, STD_COM_FLAGS, /* ttyS0 */\
-	iomem_base: (u8 *)EV64260_SERIAL_0,				\
+        { 0, BASE_BAUD, EV64260_SERIAL_0, EV64260_UART_0_IRQ, STD_COM_FLAGS, \
+	iomem_base: (u8 *)EV64260_SERIAL_0,	/* ttyS0 */		\
 	iomem_reg_shift: 2,						\
 	io_type: SERIAL_IO_MEM },
 
 #define SERIAL_PORT_DFNS \
         STD_SERIAL_PORT_DFNS
-#else
-#define SERIAL_PORT_DFNS
 #endif
-
 #endif /* __PPC_PLATFORMS_EV64260_H */
diff -Nru a/arch/ppc/platforms/ev64260_setup.c b/arch/ppc/platforms/ev64260_setup.c
--- a/arch/ppc/platforms/ev64260_setup.c	2005-03-01 23:38:54 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,476 +0,0 @@
-/*
- * arch/ppc/platforms/ev64260_setup.c
- *
- * Board setup routines for the Marvell/Galileo EV-64260-BP Evaluation Board.
- *
- * Author: Mark A. Greer <mgreer@mvista.com>
- *
- * 2001 (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.
- */
-
-/*
- * The EV-64260-BP port is the result of hard work from many people from
- * many companies.  In particular, employees of Marvell/Galileo, Mission
- * Critical Linux, Xyterra, and MontaVista Software were heavily involved.
- */
-#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/major.h>
-#include <linux/initrd.h>
-#include <linux/console.h>
-#include <linux/delay.h>
-#include <linux/irq.h>
-#include <linux/ide.h>
-#include <linux/seq_file.h>
-#include <linux/root_dev.h>
-#if	!defined(CONFIG_GT64260_CONSOLE)
-#include <linux/serial.h>
-#endif
-
-#include <asm/system.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
-#include <asm/time.h>
-#include <asm/dma.h>
-#include <asm/io.h>
-#include <asm/machdep.h>
-#include <asm/prom.h>
-#include <asm/smp.h>
-#include <asm/todc.h>
-#include <asm/bootinfo.h>
-#include <asm/gt64260.h>
-#include <platforms/ev64260.h>
-
-
-extern char cmd_line[];
-unsigned long ev64260_find_end_of_memory(void);
-
-TODC_ALLOC();
-
-/*
- * Marvell/Galileo EV-64260-BP Evaluation Board PCI interrupt routing.
- */
-static int __init
-ev64260_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
-{
-	struct pci_controller	*hose = pci_bus_to_hose(dev->bus->number);
-
-	if (hose->index == 0) {
-		static char pci_irq_table[][4] =
-		/*
-		 *	PCI IDSEL/INTPIN->INTLINE
-		 * 	   A   B   C   D
-		 */
-		{
-			{ 91, 0, 0, 0 },	/* IDSEL 7 - PCI bus 0 */
-			{ 91, 0, 0, 0 },	/* IDSEL 8 - PCI bus 0 */
-		};
-
-		const long min_idsel = 7, max_idsel = 8, irqs_per_slot = 4;
-		return PCI_IRQ_TABLE_LOOKUP;
-	}
-	else {
-		static char pci_irq_table[][4] =
-		/*
-		 *	PCI IDSEL/INTPIN->INTLINE
-		 * 	   A   B   C   D
-		 */
-		{
-			{ 93, 0, 0, 0 },	/* IDSEL 7 - PCI bus 1 */
-			{ 93, 0, 0, 0 },	/* IDSEL 8 - PCI bus 1 */
-		};
-
-		const long min_idsel = 7, max_idsel = 8, irqs_per_slot = 4;
-		return PCI_IRQ_TABLE_LOOKUP;
-	}
-}
-
-static void __init
-ev64260_setup_bridge(void)
-{
-	gt64260_bridge_info_t		info;
-	int				window;
-
-	GT64260_BRIDGE_INFO_DEFAULT(&info, ev64260_find_end_of_memory());
-
-	/* Lookup PCI host bridges */
-	if (gt64260_find_bridges(EV64260_BRIDGE_REG_BASE,
-				 &info,
-				 ev64260_map_irq)) {
-		printk("Bridge initialization failed.\n");
-	}
-
-	/*
-	 * Enabling of PCI internal-vs-external arbitration
-	 * is a platform- and errata-dependent decision.
-	 */
-	if(gt64260_revision == GT64260)  {
-		/* FEr#35 */
-		gt_clr_bits(GT64260_PCI_0_ARBITER_CNTL, (1<<31));
-		gt_clr_bits(GT64260_PCI_1_ARBITER_CNTL, (1<<31));
-	} else if( gt64260_revision == GT64260A )  {
-		gt_set_bits(GT64260_PCI_0_ARBITER_CNTL, (1<<31));
-		gt_set_bits(GT64260_PCI_1_ARBITER_CNTL, (1<<31));
-		/* Make external GPP interrupts level sensitive */
-		gt_set_bits(GT64260_COMM_ARBITER_CNTL, (1<<10));
-		/* Doc Change 9: > 100 MHz so must be set */
-		gt_set_bits(GT64260_CPU_CONFIG, (1<<23));
-	}
-
-	gt_set_bits(GT64260_CPU_MASTER_CNTL, (1<<9)); /* Only 1 cpu */
-
-	/* SCS windows not disabled above, disable all but SCS 0 */
-	for (window=1; window<GT64260_CPU_SCS_DECODE_WINDOWS; window++) {
-		gt64260_cpu_scs_set_window(window, 0, 0);
-	}
-
-	/* Set up windows to RTC/TODC and DUART on device module (CS 1 & 2) */
-	gt64260_cpu_cs_set_window(1, EV64260_TODC_BASE, EV64260_TODC_LEN);
-	gt64260_cpu_cs_set_window(2, EV64260_UART_BASE, EV64260_UART_LEN);
-
-	/*
-	 * The EV-64260-BP uses several Multi-Purpose Pins (MPP) on the 64260
-	 * bridge as interrupt inputs (via the General Purpose Ports (GPP)
-	 * register).  Need to route the MPP inputs to the GPP and set the
-	 * polarity correctly.
-	 *
-	 * In MPP Control 2 Register
-	 *   MPP 21 -> GPP 21 (DUART channel A intr)
-	 *   MPP 22 -> GPP 22 (DUART channel B intr)
-	 *
-	 * In MPP Control 3 Register
-	 *   MPP 27 -> GPP 27 (PCI 0 INTA)
-	 *   MPP 29 -> GPP 29 (PCI 1 INTA)
-	 */
-	gt_clr_bits(GT64260_MPP_CNTL_2,
-			       ((1<<20) | (1<<21) | (1<<22) | (1<<23) |
-			        (1<<24) | (1<<25) | (1<<26) | (1<<27)));
-
-	gt_clr_bits(GT64260_MPP_CNTL_3,
-			       ((1<<12) | (1<<13) | (1<<14) | (1<<15) |
-			        (1<<20) | (1<<21) | (1<<22) | (1<<23)));
-
-	gt_write(GT64260_GPP_LEVEL_CNTL, 0x000002c6);
-
-	/* DUART & PCI interrupts are active low */
-	gt_set_bits(GT64260_GPP_LEVEL_CNTL,
-			     ((1<<21) | (1<<22) | (1<<27) | (1<<29)));
-
-	/* Clear any pending interrupts for these inputs and enable them. */
-	gt_write(GT64260_GPP_INTR_CAUSE,
-			  ~((1<<21) | (1<<22) | (1<<27) | (1<<29)));
-	gt_set_bits(GT64260_GPP_INTR_MASK,
-			     ((1<<21) | (1<<22)| (1<<27) | (1<<29)));
-	gt_set_bits(GT64260_IC_CPU_INTR_MASK_HI, ((1<<26) | (1<<27)));
-
-	/* Set MPSC Multiplex RMII */
-	/* NOTE: ethernet driver modifies bit 0 and 1 */
-	gt_write(GT64260_MPP_SERIAL_PORTS_MULTIPLEX, 0x00001102);
-
-	return;
-}
-
-
-static void __init
-ev64260_setup_arch(void)
-{
-#if	!defined(CONFIG_GT64260_CONSOLE)
-	struct serial_struct	serial_req;
-#endif
-
-	if ( ppc_md.progress )
-		ppc_md.progress("ev64260_setup_arch: enter", 0);
-
-	loops_per_jiffy = 50000000 / HZ;
-
-#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_SDA2;
-#endif
-
-	if ( ppc_md.progress )
-		ppc_md.progress("ev64260_setup_arch: find_bridges", 0);
-
-	/*
-	 * Set up the L2CR register.
-	 * L2 cache was invalidated by bootloader.
-	 */
-	switch (PVR_VER(mfspr(PVR))) {
-		case PVR_VER(PVR_750):
-			_set_L2CR(0xfd100000);
-			break;
-		case PVR_VER(PVR_7400):
-		case PVR_VER(PVR_7410):
-			_set_L2CR(0xcd100000);
-			break;
-		/* case PVR_VER(PVR_7450): */
-			/* XXXX WHAT VALUE?? FIXME */
-			break;
-	}
-
-	ev64260_setup_bridge();
-
-	TODC_INIT(TODC_TYPE_DS1501, 0, 0, ioremap(EV64260_TODC_BASE,0x20), 8);
-
-#if	!defined(CONFIG_GT64260_CONSOLE)
-	memset(&serial_req, 0, sizeof(serial_req));
-	serial_req.line = 0;
-	serial_req.baud_base = BASE_BAUD;
-	serial_req.port = 0;
-	serial_req.irq = 85;
-	serial_req.flags = STD_COM_FLAGS;
-	serial_req.io_type = SERIAL_IO_MEM;
-	serial_req.iomem_base = ioremap(EV64260_SERIAL_0, 0x20);
-	serial_req.iomem_reg_shift = 2;
-
-	if (early_serial_setup(&serial_req) != 0) {
-		printk("Early serial init of port 0 failed\n");
-	}
-
-	/* Assume early_serial_setup() doesn't modify serial_req */
-	serial_req.line = 1;
-	serial_req.port = 1;
-	serial_req.irq = 86;
-	serial_req.iomem_base = ioremap(EV64260_SERIAL_1, 0x20);
-
-	if (early_serial_setup(&serial_req) != 0) {
-		printk("Early serial init of port 1 failed\n");
-	}
-#endif
-
-	printk("Marvell/Galileo EV-64260-BP Evaluation Board\n");
-	printk("EV-64260-BP port (C) 2001 MontaVista Software, Inc. (source@mvista.com)\n");
-
-	if ( ppc_md.progress )
-		ppc_md.progress("ev64260_setup_arch: exit", 0);
-
-	return;
-}
-
-static void __init
-ev64260_init_irq(void)
-{
-	gt64260_init_irq();
-
-	if(gt64260_revision != GT64260)  {
-		/* XXXX Kludge--need to fix gt64260_init_irq() interface */
-		/* Mark PCI intrs level sensitive */
-		irq_desc[91].status |= IRQ_LEVEL;
-		irq_desc[93].status |= IRQ_LEVEL;
-	}
-}
-
-unsigned long __init
-ev64260_find_end_of_memory(void)
-{
-	return 32*1024*1024;	/* XXXX FIXME */
-}
-
-static void
-ev64260_reset_board(void)
-{
-	local_irq_disable();
-
-	/* Set exception prefix high - to the firmware */
-	_nmask_and_or_msr(0, MSR_IP);
-
-	/* XXX FIXME */
-	printk("XXXX **** trying to reset board ****\n");
-	return;
-}
-
-static void
-ev64260_restart(char *cmd)
-{
-	volatile ulong	i = 10000000;
-
-	ev64260_reset_board();
-
-	while (i-- > 0);
-	panic("restart failed\n");
-}
-
-static void
-ev64260_halt(void)
-{
-	local_irq_disable();
-	while (1);
-	/* NOTREACHED */
-}
-
-static void
-ev64260_power_off(void)
-{
-	ev64260_halt();
-	/* NOTREACHED */
-}
-
-static int
-ev64260_show_cpuinfo(struct seq_file *m)
-{
-	uint pvid;
-
-	pvid = mfspr(PVR);
-	seq_printf(m, "vendor\t\t: Marvell/Galileo\n");
-	seq_printf(m, "machine\t\t: EV-64260-BP\n");
-	seq_printf(m, "PVID\t\t: 0x%x, vendor: %s\n",
-			pvid, (pvid & (1<<15) ? "IBM" : "Motorola"));
-
-	return 0;
-}
-
-/* DS1501 RTC has too much variation to use RTC for calibration */
-static void __init
-ev64260_calibrate_decr(void)
-{
-	ulong freq;
-
-	freq = 100000000 / 4;
-
-	printk("time_init: decrementer frequency = %lu.%.6lu MHz\n",
-	       freq/1000000, freq%1000000);
-
-	tb_ticks_per_jiffy = freq / HZ;
-	tb_to_us = mulhwu_scale_factor(freq, 1000000);
-
-	return;
-}
-
-#if defined(CONFIG_SERIAL_TEXT_DEBUG)
-/*
- * Set BAT 3 to map 0xf0000000 to end of physical memory space.
- */
-static __inline__ void
-ev64260_set_bat(void)
-{
-	unsigned long   bat3u, bat3l;
-	static int	mapping_set = 0;
-
-	if (!mapping_set) {
-
-		__asm__ __volatile__(
-		" lis %0,0xf000\n \
-		  ori %1,%0,0x002a\n \
-		  ori %0,%0,0x1ffe\n \
-		  mtspr 0x21e,%0\n \
-		  mtspr 0x21f,%1\n \
-		  isync\n \
-		  sync "
-		: "=r" (bat3u), "=r" (bat3l));
-
-		mapping_set = 1;
-	}
-
-	return;
-}
-
-#if !defined(CONFIG_GT64260_CONSOLE)
-#include <linux/serialP.h>
-#include <linux/serial_reg.h>
-#include <asm/serial.h>
-
-static struct serial_state rs_table[RS_TABLE_SIZE] = {
-	SERIAL_PORT_DFNS	/* Defined in <asm/serial.h> */
-};
-
-static void
-ev64260_16550_progress(char *s, unsigned short hex)
-{
-	volatile char c;
-	volatile unsigned long com_port;
-	u16 shift;
-
-	com_port = rs_table[0].port;
-	shift = rs_table[0].iomem_reg_shift;
-
-	while ((c = *s++) != 0) {
-		while ((*((volatile unsigned char *)com_port +
-				(UART_LSR << shift)) & UART_LSR_THRE) == 0)
-		                ;
-	        *(volatile unsigned char *)com_port = c;
-
-		if (c == '\n') {
-			while ((*((volatile unsigned char *)com_port +
-				(UART_LSR << shift)) & UART_LSR_THRE) == 0)
-					;
-	        	*(volatile unsigned char *)com_port = '\r';
-		}
-	}
-
-	/* Move to next line on */
-	while ((*((volatile unsigned char *)com_port +
-		(UART_LSR << shift)) & UART_LSR_THRE) == 0)
-			;
-	*(volatile unsigned char *)com_port = '\n';
-	while ((*((volatile unsigned char *)com_port +
-		(UART_LSR << shift)) & UART_LSR_THRE) == 0)
-			;
-	*(volatile unsigned char *)com_port = '\r';
-
-	return;
-}
-#endif	/* !CONFIG_GT64260_CONSOLE */
-#endif	/* CONFIG_SERIAL_TEXT_DEBUG */
-
-void __init
-platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
-	      unsigned long r6, unsigned long r7)
-{
-	parse_bootinfo(find_bootinfo());
-
-	isa_mem_base = 0;
-
-	ppc_md.setup_arch = ev64260_setup_arch;
-	ppc_md.show_cpuinfo = ev64260_show_cpuinfo;
-	ppc_md.irq_canonicalize = NULL;
-	ppc_md.init_IRQ = ev64260_init_irq;
-	ppc_md.get_irq = gt64260_get_irq;
-	ppc_md.init = NULL;
-
-	ppc_md.restart = ev64260_restart;
-	ppc_md.power_off = ev64260_power_off;
-	ppc_md.halt = ev64260_halt;
-
-	ppc_md.find_end_of_memory = ev64260_find_end_of_memory;
-
-	ppc_md.time_init = todc_time_init;
-	ppc_md.set_rtc_time = todc_set_rtc_time;
-	ppc_md.get_rtc_time = todc_get_rtc_time;
-	ppc_md.calibrate_decr = ev64260_calibrate_decr;
-
-	ppc_md.nvram_read_val = todc_direct_read_val;
-	ppc_md.nvram_write_val = todc_direct_write_val;
-
-	ppc_md.heartbeat = NULL;
-	ppc_md.heartbeat_reset = 0;
-	ppc_md.heartbeat_count = 0;
-
-#ifdef	CONFIG_SERIAL_TEXT_DEBUG
-	ev64260_set_bat();
-#ifdef	CONFIG_GT64260_CONSOLE
-	gt64260_base = EV64260_BRIDGE_REG_BASE;
-	ppc_md.progress = gt64260_mpsc_progress; /* embedded UART */
-#else
-	ppc_md.progress = ev64260_16550_progress; /* Dev module DUART */
-#endif
-#else	/* !CONFIG_SERIAL_TEXT_DEBUG */
-	ppc_md.progress = NULL;
-#endif	/* CONFIG_SERIAL_TEXT_DEBUG */
-
-	return;
-}
diff -Nru a/arch/ppc/platforms/katana.c b/arch/ppc/platforms/katana.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/ppc/platforms/katana.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,684 @@
+/*
+ * arch/ppc/platforms/katana.c
+ *
+ * Board setup routines for the Artesyn Katana 750 based boards.
+ *
+ * Tim Montgomery <timm@artesyncp.com>
+ *
+ * Based on code done by Rabeeh Khoury - rabeeh@galileo.co.il
+ * Based on code done by - Mark A. Greer <mgreer@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.
+ */
+/*
+ * Supports the Artesyn 750i, 752i, and 3750.  The 752i is virtually identical
+ * to the 750i except that it has an mv64460 bridge.
+ */
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/kdev_t.h>
+#include <linux/console.h>
+#include <linux/initrd.h>
+#include <linux/root_dev.h>
+#include <linux/delay.h>
+#include <linux/seq_file.h>
+#include <linux/smp.h>
+#include <linux/mv643xx.h>
+#ifdef CONFIG_BOOTIMG
+#include <linux/bootimg.h>
+#endif
+#include <asm/page.h>
+#include <asm/time.h>
+#include <asm/smp.h>
+#include <asm/todc.h>
+#include <asm/bootinfo.h>
+#include <asm/mv64x60.h>
+#include <platforms/katana.h>
+
+static struct		mv64x60_handle bh;
+static katana_id_t	katana_id;
+static u32		cpld_base;
+static u32		sram_base;
+
+/* PCI Interrupt routing */
+static int __init
+katana_irq_lookup_750i(unsigned char idsel, unsigned char pin)
+{
+	static char pci_irq_table[][4] = {
+		/*
+		 * PCI IDSEL/INTPIN->INTLINE
+		 *       A   B   C   D
+		 */
+		/* IDSEL 4  (PMC 1) */
+		{ KATANA_PCI_INTB_IRQ_750i, KATANA_PCI_INTC_IRQ_750i,
+			KATANA_PCI_INTD_IRQ_750i, KATANA_PCI_INTA_IRQ_750i },
+		/* IDSEL 5  (PMC 2) */
+		{ KATANA_PCI_INTC_IRQ_750i, KATANA_PCI_INTD_IRQ_750i,
+			KATANA_PCI_INTA_IRQ_750i, KATANA_PCI_INTB_IRQ_750i },
+		/* IDSEL 6 (T8110) */
+		{KATANA_PCI_INTD_IRQ_750i, 0, 0, 0 },
+	};
+	const long min_idsel = 4, max_idsel = 6, irqs_per_slot = 4;
+
+	return PCI_IRQ_TABLE_LOOKUP;
+}
+
+static int __init
+katana_irq_lookup_3750(unsigned char idsel, unsigned char pin)
+{
+	static char pci_irq_table[][4] = {
+		/*
+		 * PCI IDSEL/INTPIN->INTLINE
+		 *       A   B   C   D
+		 */
+		{ KATANA_PCI_INTA_IRQ_3750, 0, 0, 0 }, /* IDSEL 3 (BCM5691) */
+		{ KATANA_PCI_INTB_IRQ_3750, 0, 0, 0 }, /* IDSEL 4 (MV64360 #2)*/
+		{ KATANA_PCI_INTC_IRQ_3750, 0, 0, 0 }, /* IDSEL 5 (MV64360 #3)*/
+	};
+	const long min_idsel = 3, max_idsel = 5, irqs_per_slot = 4;
+
+	return PCI_IRQ_TABLE_LOOKUP;
+}
+
+static int __init
+katana_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
+{
+	switch (katana_id) {
+	case KATANA_ID_750I:
+	case KATANA_ID_752I:
+		return katana_irq_lookup_750i(idsel, pin);
+
+	case KATANA_ID_3750:
+		return katana_irq_lookup_3750(idsel, pin);
+
+	default:
+		printk(KERN_ERR "Bogus board ID\n");
+		return 0;
+	}
+}
+
+/* Board info retrieval routines */
+void __init
+katana_get_board_id(void)
+{
+	switch (in_8((volatile char *)(cpld_base + KATANA_CPLD_PRODUCT_ID))) {
+	case KATANA_PRODUCT_ID_3750:
+		katana_id = KATANA_ID_3750;
+		break;
+
+	case KATANA_PRODUCT_ID_750i:
+		katana_id = KATANA_ID_750I;
+		break;
+
+	case KATANA_PRODUCT_ID_752i:
+		katana_id = KATANA_ID_752I;
+		break;
+
+	default:
+		printk(KERN_ERR "Unsupported board\n");
+	}
+}
+
+int __init
+katana_get_proc_num(void)
+{
+	u16		val;
+	u8		save_exclude;
+	static int	proc = -1;
+	static u8	first_time = 1;
+
+	if (first_time) {
+		if (katana_id != KATANA_ID_3750)
+			proc = 0;
+		else {
+			save_exclude = mv64x60_pci_exclude_bridge;
+			mv64x60_pci_exclude_bridge = 0;
+
+			early_read_config_word(bh.hose_a, 0,
+				PCI_DEVFN(0,0), PCI_DEVICE_ID, &val);
+
+			mv64x60_pci_exclude_bridge = save_exclude;
+
+			switch(val) {
+			case PCI_DEVICE_ID_KATANA_3750_PROC0:
+				proc = 0;
+				break;
+
+			case PCI_DEVICE_ID_KATANA_3750_PROC1:
+				proc = 1;
+				break;
+
+			case PCI_DEVICE_ID_KATANA_3750_PROC2:
+				proc = 2;
+				break;
+
+			default:
+				printk(KERN_ERR "Bogus Device ID\n");
+			}
+		}
+
+		first_time = 0;
+	}
+
+	return proc;
+}
+
+static inline int
+katana_is_monarch(void)
+{
+	return in_8((volatile char *)(cpld_base + KATANA_CPLD_BD_CFG_3)) &
+		KATANA_CPLD_BD_CFG_3_MONARCH;
+}
+
+static void __init
+katana_enable_ipmi(void)
+{
+	u8 reset_out;
+
+	/* Enable access to IPMI ctlr by clearing IPMI PORTSEL bit in CPLD */
+	reset_out = in_8((volatile char *)(cpld_base + KATANA_CPLD_RESET_OUT));
+	reset_out &= ~KATANA_CPLD_RESET_OUT_PORTSEL;
+	out_8((volatile void *)(cpld_base + KATANA_CPLD_RESET_OUT), reset_out);
+	return;
+}
+
+static unsigned long
+katana_bus_freq(void)
+{
+	u8 bd_cfg_0;
+
+	bd_cfg_0 = in_8((volatile char *)(cpld_base + KATANA_CPLD_BD_CFG_0));
+
+	switch (bd_cfg_0 & KATANA_CPLD_BD_CFG_0_SYSCLK_MASK) {
+	case KATANA_CPLD_BD_CFG_0_SYSCLK_200:
+		return 200000000;
+		break;
+
+	case KATANA_CPLD_BD_CFG_0_SYSCLK_166:
+		return 166666666;
+		break;
+
+	case KATANA_CPLD_BD_CFG_0_SYSCLK_133:
+		return 133333333;
+		break;
+
+	case KATANA_CPLD_BD_CFG_0_SYSCLK_100:
+		return 100000000;
+		break;
+
+	default:
+		return 133333333;
+		break;
+	}
+}
+
+/* Bridge & platform setup routines */
+void __init
+katana_intr_setup(void)
+{
+	/* MPP 8, 9, and 10 */
+	mv64x60_clr_bits(&bh, MV64x60_MPP_CNTL_1, 0xfff);
+
+	/* MPP 14 */
+	if ((katana_id == KATANA_ID_750I) || (katana_id == KATANA_ID_752I))
+		mv64x60_clr_bits(&bh, MV64x60_MPP_CNTL_1, 0x0f000000);
+
+	/*
+	 * Define GPP 8,9,and 10 interrupt polarity as active low
+	 * input signal and level triggered
+	 */
+	mv64x60_set_bits(&bh, MV64x60_GPP_LEVEL_CNTL, 0x700);
+	mv64x60_clr_bits(&bh, MV64x60_GPP_IO_CNTL, 0x700);
+
+	if ((katana_id == KATANA_ID_750I) || (katana_id == KATANA_ID_752I)) {
+		mv64x60_set_bits(&bh, MV64x60_GPP_LEVEL_CNTL, (1<<14));
+		mv64x60_clr_bits(&bh, MV64x60_GPP_IO_CNTL, (1<<14));
+	}
+
+	/* Config GPP intr ctlr to respond to level trigger */
+	mv64x60_set_bits(&bh, MV64x60_COMM_ARBITER_CNTL, (1<<10));
+
+	/* Erranum FEr PCI-#8 */
+	mv64x60_clr_bits(&bh, MV64x60_PCI0_CMD, (1<<5) | (1<<9));
+	mv64x60_clr_bits(&bh, MV64x60_PCI1_CMD, (1<<5) | (1<<9));
+
+	/*
+	 * Dismiss and then enable interrupt on GPP interrupt cause
+	 * for CPU #0
+	 */
+	mv64x60_write(&bh, MV64x60_GPP_INTR_CAUSE, ~0x700);
+	mv64x60_set_bits(&bh, MV64x60_GPP_INTR_MASK, 0x700);
+
+	if ((katana_id == KATANA_ID_750I) || (katana_id == KATANA_ID_752I)) {
+		mv64x60_write(&bh, MV64x60_GPP_INTR_CAUSE, ~(1<<14));
+		mv64x60_set_bits(&bh, MV64x60_GPP_INTR_MASK, (1<<14));
+	}
+
+	/*
+	 * Dismiss and then enable interrupt on CPU #0 high cause reg
+	 * BIT25 summarizes GPP interrupts 8-15
+	 */
+	mv64x60_set_bits(&bh, MV64360_IC_CPU0_INTR_MASK_HI, (1<<25));
+	return;
+}
+
+void __init
+katana_setup_peripherals(void)
+{
+	u32 base, size_0, size_1;
+
+	/* Set up windows for boot CS, soldered & socketed flash, and CPLD */
+	mv64x60_set_32bit_window(&bh, MV64x60_CPU2BOOT_WIN,
+		 KATANA_BOOT_WINDOW_BASE, KATANA_BOOT_WINDOW_SIZE, 0);
+	bh.ci->enable_window_32bit(&bh, MV64x60_CPU2BOOT_WIN);
+
+	/* Assume firmware set up window sizes correctly for dev 0 & 1 */
+	mv64x60_get_32bit_window(&bh, MV64x60_CPU2DEV_0_WIN, &base, &size_0);
+
+	if (size_0 > 0) {
+		mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_0_WIN,
+			 KATANA_SOLDERED_FLASH_BASE, size_0, 0);
+		bh.ci->enable_window_32bit(&bh, MV64x60_CPU2DEV_0_WIN);
+	}
+
+	mv64x60_get_32bit_window(&bh, MV64x60_CPU2DEV_1_WIN, &base, &size_1);
+
+	if (size_1 > 0) {
+		mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_1_WIN,
+			 (KATANA_SOLDERED_FLASH_BASE + size_0), size_1, 0);
+		bh.ci->enable_window_32bit(&bh, MV64x60_CPU2DEV_1_WIN);
+	}
+
+	mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_2_WIN,
+		 KATANA_SOCKET_BASE, KATANA_SOCKETED_FLASH_SIZE, 0);
+	bh.ci->enable_window_32bit(&bh, MV64x60_CPU2DEV_2_WIN);
+
+	mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_3_WIN,
+		 KATANA_CPLD_BASE, KATANA_CPLD_SIZE, 0);
+	bh.ci->enable_window_32bit(&bh, MV64x60_CPU2DEV_3_WIN);
+	cpld_base = (u32)ioremap(KATANA_CPLD_BASE, KATANA_CPLD_SIZE);
+
+	mv64x60_set_32bit_window(&bh, MV64x60_CPU2SRAM_WIN,
+		 KATANA_INTERNAL_SRAM_BASE, MV64360_SRAM_SIZE, 0);
+	bh.ci->enable_window_32bit(&bh, MV64x60_CPU2SRAM_WIN);
+	sram_base = (u32)ioremap(KATANA_INTERNAL_SRAM_BASE, MV64360_SRAM_SIZE);
+
+	/* Set up Enet->SRAM window */
+	mv64x60_set_32bit_window(&bh, MV64x60_ENET2MEM_4_WIN,
+		KATANA_INTERNAL_SRAM_BASE, MV64360_SRAM_SIZE, 0x2);
+	bh.ci->enable_window_32bit(&bh, MV64x60_ENET2MEM_4_WIN);
+
+	/* Give enet r/w access to memory region */
+	mv64x60_set_bits(&bh, MV64360_ENET2MEM_ACC_PROT_0, (0x3 << (4 << 1)));
+	mv64x60_set_bits(&bh, MV64360_ENET2MEM_ACC_PROT_1, (0x3 << (4 << 1)));
+	mv64x60_set_bits(&bh, MV64360_ENET2MEM_ACC_PROT_2, (0x3 << (4 << 1)));
+
+	mv64x60_clr_bits(&bh, MV64x60_PCI1_PCI_DECODE_CNTL, (1 << 3));
+	mv64x60_clr_bits(&bh, MV64x60_TIMR_CNTR_0_3_CNTL,
+			 ((1 << 0) | (1 << 8) | (1 << 16) | (1 << 24)));
+
+	/* Must wait until window set up before retrieving board id */
+	katana_get_board_id();
+
+	/* Enumerate pci bus (must know board id before getting proc number) */
+	if (katana_get_proc_num() == 0)
+		bh.hose_b->last_busno = pciauto_bus_scan(bh.hose_b, 0);
+
+#if defined(CONFIG_NOT_COHERENT_CACHE)
+	mv64x60_write(&bh, MV64360_SRAM_CONFIG, 0x00160000);
+#else
+	mv64x60_write(&bh, MV64360_SRAM_CONFIG, 0x001600b2);
+#endif
+
+	/*
+	 * Setting the SRAM to 0. Note that this generates parity errors on
+	 * internal data path in SRAM since it's first time accessing it
+	 * while after reset it's not configured.
+	 */
+	memset((void *)sram_base, 0, MV64360_SRAM_SIZE);
+
+	/* Only processor zero [on 3750] is an PCI interrupt controller */
+	if (katana_get_proc_num() == 0)
+		katana_intr_setup();
+
+	return;
+}
+
+static void __init
+katana_setup_bridge(void)
+{
+	struct mv64x60_setup_info si;
+	int i;
+
+	memset(&si, 0, sizeof(si));
+
+	si.phys_reg_base = KATANA_BRIDGE_REG_BASE;
+
+	si.pci_1.enable_bus = 1;
+	si.pci_1.pci_io.cpu_base = KATANA_PCI1_IO_START_PROC_ADDR;
+	si.pci_1.pci_io.pci_base_hi = 0;
+	si.pci_1.pci_io.pci_base_lo = KATANA_PCI1_IO_START_PCI_ADDR;
+	si.pci_1.pci_io.size = KATANA_PCI1_IO_SIZE;
+	si.pci_1.pci_io.swap = MV64x60_CPU2PCI_SWAP_NONE;
+	si.pci_1.pci_mem[0].cpu_base = KATANA_PCI1_MEM_START_PROC_ADDR;
+	si.pci_1.pci_mem[0].pci_base_hi = KATANA_PCI1_MEM_START_PCI_HI_ADDR;
+	si.pci_1.pci_mem[0].pci_base_lo = KATANA_PCI1_MEM_START_PCI_LO_ADDR;
+	si.pci_1.pci_mem[0].size = KATANA_PCI1_MEM_SIZE;
+	si.pci_1.pci_mem[0].swap = MV64x60_CPU2PCI_SWAP_NONE;
+	si.pci_1.pci_cmd_bits = 0;
+	si.pci_1.latency_timer = 0x80;
+
+	for (i = 0; i < MV64x60_CPU2MEM_WINDOWS; i++) {
+#if defined(CONFIG_NOT_COHERENT_CACHE)
+		si.cpu_prot_options[i] = 0;
+		si.enet_options[i] = MV64360_ENET2MEM_SNOOP_NONE;
+		si.mpsc_options[i] = MV64360_MPSC2MEM_SNOOP_NONE;
+		si.idma_options[i] = MV64360_IDMA2MEM_SNOOP_NONE;
+
+		si.pci_1.acc_cntl_options[i] =
+		    MV64360_PCI_ACC_CNTL_SNOOP_NONE |
+		    MV64360_PCI_ACC_CNTL_SWAP_NONE |
+		    MV64360_PCI_ACC_CNTL_MBURST_128_BYTES |
+		    MV64360_PCI_ACC_CNTL_RDSIZE_256_BYTES;
+#else
+		si.cpu_prot_options[i] = 0;
+		si.enet_options[i] = MV64360_ENET2MEM_SNOOP_NONE; /* errata */
+		si.mpsc_options[i] = MV64360_MPSC2MEM_SNOOP_NONE; /* errata */
+		si.idma_options[i] = MV64360_IDMA2MEM_SNOOP_NONE; /* errata */
+
+		si.pci_1.acc_cntl_options[i] =
+		    MV64360_PCI_ACC_CNTL_SNOOP_WB |
+		    MV64360_PCI_ACC_CNTL_SWAP_NONE |
+		    MV64360_PCI_ACC_CNTL_MBURST_32_BYTES |
+		    MV64360_PCI_ACC_CNTL_RDSIZE_32_BYTES;
+#endif
+	}
+
+	/* Lookup PCI host bridges */
+	if (mv64x60_init(&bh, &si))
+		printk(KERN_WARNING "Bridge initialization failed.\n");
+
+	pci_dram_offset = 0; /* sys mem at same addr on PCI & cpu bus */
+	ppc_md.pci_swizzle = common_swizzle;
+	ppc_md.pci_map_irq = katana_map_irq;
+	ppc_md.pci_exclude_device = mv64x60_pci_exclude_device;
+
+	mv64x60_set_bus(&bh, 1, 0);
+	bh.hose_b->first_busno = 0;
+	bh.hose_b->last_busno = 0xff;
+
+	return;
+}
+
+static void __init
+katana_setup_arch(void)
+{
+	if (ppc_md.progress)
+		ppc_md.progress("katana_setup_arch: enter", 0);
+
+	set_tb(0, 0);
+
+#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_SDA2;
+#endif
+
+	/*
+	 * Set up the L2CR register.
+	 *
+	 * 750FX has only L2E, L2PE (bits 2-8 are reserved)
+	 * DD2.0 has bug that requires the L2 to be in WRT mode
+	 * avoid dirty data in cache
+	 */
+	if (PVR_REV(mfspr(PVR)) == 0x0200) {
+		printk(KERN_INFO "DD2.0 detected. Setting L2 cache"
+			"to Writethrough mode\n");
+		_set_L2CR(L2CR_L2E | L2CR_L2PE | L2CR_L2WT);
+	}
+	else
+		_set_L2CR(L2CR_L2E | L2CR_L2PE);
+
+	if (ppc_md.progress)
+		ppc_md.progress("katana_setup_arch: calling setup_bridge", 0);
+
+	katana_setup_bridge();
+	katana_setup_peripherals();
+	katana_enable_ipmi();
+
+	printk(KERN_INFO "Artesyn Communication Products, LLC - Katana(TM)\n");
+	if (ppc_md.progress)
+		ppc_md.progress("katana_setup_arch: exit", 0);
+	return;
+}
+
+/* Platform device data fixup routines. */
+#if defined(CONFIG_SERIAL_MPSC)
+static void __init
+katana_fixup_mpsc_pdata(struct platform_device *pdev)
+{
+	struct mpsc_pdata *pdata;
+
+	pdata = (struct mpsc_pdata *)pdev->dev.platform_data;
+
+	pdata->max_idle = 40;
+	pdata->default_baud = KATANA_DEFAULT_BAUD;
+	pdata->brg_clk_src = KATANA_MPSC_CLK_SRC;
+	pdata->brg_clk_freq = KATANA_MPSC_CLK_FREQ;
+
+	return;
+}
+#endif
+
+#if defined(CONFIG_MV643XX_ETH)
+static void __init
+katana_fixup_eth_pdata(struct platform_device *pdev)
+{
+	struct mv64xxx_eth_platform_data *eth_pd;
+	static u16 phy_addr[] = {
+		KATANA_ETH0_PHY_ADDR,
+		KATANA_ETH1_PHY_ADDR,
+		KATANA_ETH2_PHY_ADDR,
+	};
+	int	rx_size = KATANA_ETH_RX_QUEUE_SIZE * MV64340_ETH_DESC_SIZE;
+	int	tx_size = KATANA_ETH_TX_QUEUE_SIZE * MV64340_ETH_DESC_SIZE;
+
+	eth_pd = pdev->dev.platform_data;
+	eth_pd->force_phy_addr = 1;
+	eth_pd->phy_addr = phy_addr[pdev->id];
+	eth_pd->tx_queue_size = KATANA_ETH_TX_QUEUE_SIZE;
+	eth_pd->rx_queue_size = KATANA_ETH_RX_QUEUE_SIZE;
+	eth_pd->tx_sram_addr = mv643xx_sram_alloc(tx_size);
+
+	if (eth_pd->tx_sram_addr)
+		eth_pd->tx_sram_size = tx_size;
+	else
+		printk(KERN_ERR "mv643xx_sram_alloc failed\n");
+
+	eth_pd->rx_sram_addr = mv643xx_sram_alloc(rx_size);
+	if (eth_pd->rx_sram_addr)
+		eth_pd->rx_sram_size = rx_size;
+	else
+		printk(KERN_ERR "mv643xx_sram_alloc failed\n");
+}
+#endif
+
+static int __init
+katana_platform_notify(struct device *dev)
+{
+	static struct {
+		char	*bus_id;
+		void	((*rtn)(struct platform_device *pdev));
+	} dev_map[] = {
+#if defined(CONFIG_SERIAL_MPSC)
+		{ MPSC_CTLR_NAME "0", katana_fixup_mpsc_pdata },
+		{ MPSC_CTLR_NAME "1", katana_fixup_mpsc_pdata },
+#endif
+#if defined(CONFIG_MV643XX_ETH)
+		{ MV64XXX_ETH_NAME "0", katana_fixup_eth_pdata },
+		{ MV64XXX_ETH_NAME "1", katana_fixup_eth_pdata },
+		{ MV64XXX_ETH_NAME "2", katana_fixup_eth_pdata },
+#endif
+	};
+	struct platform_device	*pdev;
+	int	i;
+
+	if (dev && dev->bus_id)
+		for (i=0; i<ARRAY_SIZE(dev_map); i++)
+			if (!strncmp(dev->bus_id, dev_map[i].bus_id,
+				BUS_ID_SIZE)) {
+
+				pdev = container_of(dev,
+					struct platform_device, dev);
+				dev_map[i].rtn(pdev);
+			}
+
+	return 0;
+}
+
+static void
+katana_restart(char *cmd)
+{
+	volatile ulong i = 10000000;
+
+	/* issue hard reset to the reset command register */
+	out_8((volatile char *)(cpld_base + KATANA_CPLD_RST_CMD),
+		KATANA_CPLD_RST_CMD_HR);
+
+	while (i-- > 0) ;
+	panic("restart failed\n");
+}
+
+static void
+katana_halt(void)
+{
+	while (1) ;
+	/* NOTREACHED */
+}
+
+static void
+katana_power_off(void)
+{
+	katana_halt();
+	/* NOTREACHED */
+}
+
+static int
+katana_show_cpuinfo(struct seq_file *m)
+{
+	seq_printf(m, "vendor\t\t: Artesyn Communication Products, LLC\n");
+
+	seq_printf(m, "board\t\t: ");
+
+	switch (katana_id) {
+	case KATANA_ID_3750:
+		seq_printf(m, "Katana 3750\n");
+		break;
+
+	case KATANA_ID_750I:
+		seq_printf(m, "Katana 750i\n");
+		break;
+
+	case KATANA_ID_752I:
+		seq_printf(m, "Katana 752i\n");
+		break;
+
+	default:
+		seq_printf(m, "Unknown\n");
+		break;
+	}
+
+	seq_printf(m, "product ID\t: 0x%x\n",
+		   in_8((volatile char *)(cpld_base + KATANA_CPLD_PRODUCT_ID)));
+	seq_printf(m, "hardware rev\t: 0x%x\n",
+		   in_8((volatile char *)(cpld_base+KATANA_CPLD_HARDWARE_VER)));
+	seq_printf(m, "PLD rev\t\t: 0x%x\n",
+		   in_8((volatile char *)(cpld_base + KATANA_CPLD_PLD_VER)));
+	seq_printf(m, "PLB freq\t: %ldMhz\n", katana_bus_freq() / 1000000);
+	seq_printf(m, "PCI\t\t: %sMonarch\n", katana_is_monarch()? "" : "Non-");
+
+	return 0;
+}
+
+static void __init
+katana_calibrate_decr(void)
+{
+	ulong freq;
+
+	freq = katana_bus_freq() / 4;
+
+	printk(KERN_INFO "time_init: decrementer frequency = %lu.%.6lu MHz\n",
+	       freq / 1000000, freq % 1000000);
+
+	tb_ticks_per_jiffy = freq / HZ;
+	tb_to_us = mulhwu_scale_factor(freq, 1000000);
+
+	return;
+}
+
+unsigned long __init
+katana_find_end_of_memory(void)
+{
+	return mv64x60_get_mem_size(KATANA_BRIDGE_REG_BASE,
+		MV64x60_TYPE_MV64360);
+}
+
+static inline void
+katana_set_bat(void)
+{
+	mb();
+	mtspr(DBAT2U, 0xf0001ffe);
+	mtspr(DBAT2L, 0xf000002a);
+	mb();
+
+	return;
+}
+
+#if defined(CONFIG_SERIAL_TEXT_DEBUG) && defined(CONFIG_SERIAL_MPSC_CONSOLE)
+static void __init
+katana_map_io(void)
+{
+	io_block_mapping(0xf8100000, 0xf8100000, 0x00020000, _PAGE_IO);
+}
+#endif
+
+void __init
+platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
+	      unsigned long r6, unsigned long r7)
+{
+	parse_bootinfo(find_bootinfo());
+
+	isa_mem_base = 0;
+
+	ppc_md.setup_arch = katana_setup_arch;
+	ppc_md.show_cpuinfo = katana_show_cpuinfo;
+	ppc_md.init_IRQ = mv64360_init_irq;
+	ppc_md.get_irq = mv64360_get_irq;
+	ppc_md.restart = katana_restart;
+	ppc_md.power_off = katana_power_off;
+	ppc_md.halt = katana_halt;
+	ppc_md.find_end_of_memory = katana_find_end_of_memory;
+	ppc_md.calibrate_decr = katana_calibrate_decr;
+
+#if defined(CONFIG_SERIAL_TEXT_DEBUG) && defined(CONFIG_SERIAL_MPSC_CONSOLE)
+	ppc_md.setup_io_mappings = katana_map_io;
+	ppc_md.progress = mv64x60_mpsc_progress;
+	mv64x60_progress_init(KATANA_BRIDGE_REG_BASE);
+#endif
+
+#if defined(CONFIG_SERIAL_MPSC) || defined(CONFIG_MV643XX_ETH)
+	platform_notify = katana_platform_notify;
+#endif
+
+	katana_set_bat(); /* Need for katana_find_end_of_memory and progress */
+	return;
+}
diff -Nru a/arch/ppc/platforms/katana.h b/arch/ppc/platforms/katana.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/ppc/platforms/katana.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,233 @@
+/*
+ * arch/ppc/platforms/katana.h
+ *
+ * Definitions for Artesyn Katana750i/3750 board.
+ *
+ * Tim Montgomery <timm@artesyncp.com>
+ *
+ * Based on code done by Rabeeh Khoury - rabeeh@galileo.co.il
+ * Based on code done by Mark A. Greer <mgreer@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.
+ */
+
+/*
+ * The MV64360 has 2 PCI buses each with 1 window from the CPU bus to
+ * PCI I/O space and 4 windows from the CPU bus to PCI MEM space.
+ * We'll only use one PCI MEM window on each PCI bus.
+ *
+ * This is the CPU physical memory map (windows must be at least 1MB and start
+ * on a boundary that is a multiple of the window size):
+ *
+ *    0xff800000-0xffffffff      - Boot window
+ *    0xf8400000-0xf85fffff      - Internal SRAM
+ *    0xf8200000-0xf823ffff      - CPLD
+ *    0xf8100000-0xf810ffff      - MV64360 Registers
+ *    0xf8000000-0xf80fffff      - PLCC socket
+ *    0xf0000000-0xf01fffff	 - Consistent memory pool
+ *    0xe8000000-0xefffffff      - soldered flash
+ *    0xc0000000-0xc0ffffff      - PCI I/O
+ *    0x80000000-0xbfffffff      - PCI MEM
+ */
+
+#ifndef __PPC_PLATFORMS_KATANA_H
+#define __PPC_PLATFORMS_KATANA_H
+
+/* CPU Physical Memory Map setup. */
+#define KATANA_BOOT_WINDOW_BASE			0xff800000
+#define KATANA_INTERNAL_SRAM_BASE		0xf8400000
+#define KATANA_CPLD_BASE			0xf8200000
+#define KATANA_BRIDGE_REG_BASE			0xf8100000
+#define KATANA_SOCKET_BASE			0xf8000000
+#define KATANA_SOLDERED_FLASH_BASE		0xe8000000
+
+#define KATANA_BOOT_WINDOW_SIZE_ACTUAL		0x00800000 /* 8MB */
+#define KATANA_CPLD_SIZE_ACTUAL			0x00020000 /* 128KB */
+#define KATANA_SOCKETED_FLASH_SIZE_ACTUAL	0x00080000 /* 512KB */
+#define KATANA_SOLDERED_FLASH_SIZE_ACTUAL	0x02000000 /* 32MB */
+
+#define KATANA_BOOT_WINDOW_SIZE		max(MV64360_WINDOW_SIZE_MIN,	\
+		KATANA_BOOT_WINDOW_SIZE_ACTUAL)
+#define KATANA_CPLD_SIZE		max(MV64360_WINDOW_SIZE_MIN,	\
+		KATANA_CPLD_SIZE_ACTUAL)
+#define KATANA_SOCKETED_FLASH_SIZE	max(MV64360_WINDOW_SIZE_MIN,	\
+		KATANA_SOCKETED_FLASH_SIZE_ACTUAL)
+#define KATANA_SOLDERED_FLASH_SIZE	max(MV64360_WINDOW_SIZE_MIN,	\
+		KATANA_SOLDERED_FLASH_SIZE_ACTUAL)
+
+#define KATANA_PCI1_MEM_START_PROC_ADDR         0x80000000
+#define KATANA_PCI1_MEM_START_PCI_HI_ADDR       0x00000000
+#define KATANA_PCI1_MEM_START_PCI_LO_ADDR       0x80000000
+#define KATANA_PCI1_MEM_SIZE                    0x40000000
+#define KATANA_PCI1_IO_START_PROC_ADDR          0xc0000000
+#define KATANA_PCI1_IO_START_PCI_ADDR           0x00000000
+#define KATANA_PCI1_IO_SIZE                     0x01000000
+
+/* Board-specific IRQ info */
+#define  KATANA_PCI_INTA_IRQ_3750		64+8
+#define  KATANA_PCI_INTB_IRQ_3750		64+9
+#define  KATANA_PCI_INTC_IRQ_3750		64+10
+
+#define  KATANA_PCI_INTA_IRQ_750i		64+8
+#define  KATANA_PCI_INTB_IRQ_750i		64+9
+#define  KATANA_PCI_INTC_IRQ_750i		64+10
+#define  KATANA_PCI_INTD_IRQ_750i		64+14
+
+#define KATANA_CPLD_RST_EVENT			0x00000000
+#define KATANA_CPLD_RST_CMD			0x00001000
+#define KATANA_CPLD_PCI_ERR_INT_EN		0x00002000
+#define KATANA_CPLD_PCI_ERR_INT_PEND		0x00003000
+#define KATANA_CPLD_PRODUCT_ID			0x00004000
+#define KATANA_CPLD_EREADY			0x00005000
+
+#define KATANA_CPLD_HARDWARE_VER		0x00007000
+#define KATANA_CPLD_PLD_VER			0x00008000
+#define KATANA_CPLD_BD_CFG_0			0x00009000
+#define KATANA_CPLD_BD_CFG_1			0x0000a000
+#define KATANA_CPLD_BD_CFG_3			0x0000c000
+#define KATANA_CPLD_LED				0x0000d000
+#define KATANA_CPLD_RESET_OUT			0x0000e000
+
+#define KATANA_CPLD_RST_EVENT_INITACT		0x80
+#define KATANA_CPLD_RST_EVENT_SW		0x40
+#define KATANA_CPLD_RST_EVENT_WD		0x20
+#define KATANA_CPLD_RST_EVENT_COPS		0x10
+#define KATANA_CPLD_RST_EVENT_COPH		0x08
+#define KATANA_CPLD_RST_EVENT_CPCI		0x02
+#define KATANA_CPLD_RST_EVENT_FP		0x01
+
+#define KATANA_CPLD_RST_CMD_SCL			0x80
+#define KATANA_CPLD_RST_CMD_SDA			0x40
+#define KATANA_CPLD_RST_CMD_I2C			0x10
+#define KATANA_CPLD_RST_CMD_FR			0x08
+#define KATANA_CPLD_RST_CMD_SR			0x04
+#define KATANA_CPLD_RST_CMD_HR			0x01
+
+#define KATANA_CPLD_BD_CFG_0_SYSCLK_MASK	0xc0
+#define KATANA_CPLD_BD_CFG_0_SYSCLK_200		0x00
+#define KATANA_CPLD_BD_CFG_0_SYSCLK_166		0x80
+#define KATANA_CPLD_BD_CFG_0_SYSCLK_133		0xc0
+#define KATANA_CPLD_BD_CFG_0_SYSCLK_100		0x40
+
+#define KATANA_CPLD_BD_CFG_1_FL_BANK_MASK	0x03
+#define KATANA_CPLD_BD_CFG_1_FL_BANK_16MB	0x00
+#define KATANA_CPLD_BD_CFG_1_FL_BANK_32MB	0x01
+#define KATANA_CPLD_BD_CFG_1_FL_BANK_64MB	0x02
+#define KATANA_CPLD_BD_CFG_1_FL_BANK_128MB	0x03
+
+#define KATANA_CPLD_BD_CFG_1_FL_NUM_BANKS_MASK	0x04
+#define KATANA_CPLD_BD_CFG_1_FL_NUM_BANKS_ONE	0x00
+#define KATANA_CPLD_BD_CFG_1_FL_NUM_BANKS_TWO	0x04
+
+#define KATANA_CPLD_BD_CFG_3_MONARCH		0x04
+
+#define KATANA_CPLD_RESET_OUT_PORTSEL		0x80
+#define KATANA_CPLD_RESET_OUT_WD		0x20
+#define KATANA_CPLD_RESET_OUT_COPH		0x08
+#define KATANA_CPLD_RESET_OUT_PCI_RST_PCI	0x02
+#define KATANA_CPLD_RESET_OUT_PCI_RST_FP	0x01
+
+#define KATANA_MBOX_RESET_REQUEST		0xC83A
+#define KATANA_MBOX_RESET_ACK			0xE430
+#define KATANA_MBOX_RESET_DONE			0x32E5
+
+#define HSL_PLD_BASE				0x00010000
+#define HSL_PLD_J4SGA_REG_OFF			0
+#define HSL_PLD_J4GA_REG_OFF			1
+#define HSL_PLD_J2GA_REG_OFF			2
+#define GA_MASK					0x1f
+#define HSL_PLD_SIZE				0x1000
+#define K3750_GPP_GEO_ADDR_PINS			0xf8000000
+#define K3750_GPP_GEO_ADDR_SHIFT		27
+
+#define K3750_GPP_EVENT_PROC_0			(1 << 21)
+#define K3750_GPP_EVENT_PROC_1_2		(1 << 2)
+
+#define PCI_VENDOR_ID_ARTESYN			0x1223
+#define PCI_DEVICE_ID_KATANA_3750_PROC0		0x0041
+#define PCI_DEVICE_ID_KATANA_3750_PROC1		0x0042
+#define PCI_DEVICE_ID_KATANA_3750_PROC2		0x0043
+
+#define COPROC_MEM_FUNCTION			0
+#define COPROC_MEM_BAR				0
+#define COPROC_REGS_FUNCTION			0
+#define COPROC_REGS_BAR				4
+#define COPROC_FLASH_FUNCTION			2
+#define COPROC_FLASH_BAR			4
+
+#define KATANA_IPMB_LOCAL_I2C_ADDR		0x08
+
+#define	KATANA_DEFAULT_BAUD			9600
+#define	KATANA_MPSC_CLK_SRC			8	  /* TCLK */
+#define	KATANA_MPSC_CLK_FREQ			133333333 /* 133.3333... MHz */
+
+#define	KATANA_ETH0_PHY_ADDR			12
+#define	KATANA_ETH1_PHY_ADDR			11
+#define	KATANA_ETH2_PHY_ADDR			4
+
+#define KATANA_PRODUCT_ID_3750			0x01
+#define KATANA_PRODUCT_ID_750i			0x02
+#define KATANA_PRODUCT_ID_752i			0x04
+
+#define KATANA_ETH_TX_QUEUE_SIZE		800
+#define KATANA_ETH_RX_QUEUE_SIZE		400
+
+#define	KATANA_ETH_PORT_CONFIG_VALUE			\
+	ETH_UNICAST_NORMAL_MODE			|	\
+	ETH_DEFAULT_RX_QUEUE_0			|	\
+	ETH_DEFAULT_RX_ARP_QUEUE_0		|	\
+	ETH_RECEIVE_BC_IF_NOT_IP_OR_ARP		|	\
+	ETH_RECEIVE_BC_IF_IP			|	\
+	ETH_RECEIVE_BC_IF_ARP			|	\
+	ETH_CAPTURE_TCP_FRAMES_DIS		|	\
+	ETH_CAPTURE_UDP_FRAMES_DIS		|	\
+	ETH_DEFAULT_RX_TCP_QUEUE_0		|	\
+	ETH_DEFAULT_RX_UDP_QUEUE_0		|	\
+	ETH_DEFAULT_RX_BPDU_QUEUE_0
+
+#define	KATANA_ETH_PORT_CONFIG_EXTEND_VALUE		\
+	ETH_SPAN_BPDU_PACKETS_AS_NORMAL		|	\
+	ETH_PARTITION_DISABLE
+
+#define	GT_ETH_IPG_INT_RX(value)			\
+	((value & 0x3fff) << 8)
+
+#define	KATANA_ETH_PORT_SDMA_CONFIG_VALUE		\
+	ETH_RX_BURST_SIZE_4_64BIT		|	\
+	GT_ETH_IPG_INT_RX(0)			|	\
+	ETH_TX_BURST_SIZE_4_64BIT
+
+#define	KATANA_ETH_PORT_SERIAL_CONTROL_VALUE		\
+	ETH_FORCE_LINK_PASS			|	\
+	ETH_ENABLE_AUTO_NEG_FOR_DUPLX		|	\
+	ETH_DISABLE_AUTO_NEG_FOR_FLOW_CTRL	|	\
+	ETH_ADV_SYMMETRIC_FLOW_CTRL		|	\
+	ETH_FORCE_FC_MODE_NO_PAUSE_DIS_TX	|	\
+	ETH_FORCE_BP_MODE_NO_JAM		|	\
+	BIT9					|	\
+	ETH_DO_NOT_FORCE_LINK_FAIL		|	\
+	ETH_RETRANSMIT_16_ATTEMPTS		|	\
+	ETH_ENABLE_AUTO_NEG_SPEED_GMII		|	\
+	ETH_DTE_ADV_0				|	\
+	ETH_DISABLE_AUTO_NEG_BYPASS		|	\
+	ETH_AUTO_NEG_NO_CHANGE			|	\
+	ETH_MAX_RX_PACKET_9700BYTE		|	\
+	ETH_CLR_EXT_LOOPBACK			|	\
+	ETH_SET_FULL_DUPLEX_MODE		|	\
+	ETH_ENABLE_FLOW_CTRL_TX_RX_IN_FULL_DUPLEX
+
+#ifndef __ASSEMBLY__
+
+typedef enum {
+	KATANA_ID_3750,
+	KATANA_ID_750I,
+	KATANA_ID_752I,
+	KATANA_ID_MAX
+} katana_id_t;
+
+#endif
+
+#endif				/* __PPC_PLATFORMS_KATANA_H */
diff -Nru a/arch/ppc/platforms/pal4_setup.c b/arch/ppc/platforms/pal4_setup.c
--- a/arch/ppc/platforms/pal4_setup.c	2005-03-01 23:39:16 -08:00
+++ b/arch/ppc/platforms/pal4_setup.c	2005-03-01 23:39:16 -08:00
@@ -81,7 +81,7 @@
 static void
 pal4_restart(char *cmd)
 {
-        __cli();
+        local_irq_disable();
         __asm__ __volatile__("lis  3,0xfff0\n \
                               ori  3,3,0x100\n \
                               mtspr 26,3\n \
@@ -95,7 +95,7 @@
 static void
 pal4_power_off(void)
 {
-	__cli();
+	local_irq_disable();
 	for(;;);
 }
 
diff -Nru a/arch/ppc/platforms/pmac_cache.S b/arch/ppc/platforms/pmac_cache.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/ppc/platforms/pmac_cache.S	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,325 @@
+/*
+ * This file contains low-level cache management functions
+ * used for sleep and CPU speed changes on Apple machines.
+ * (In fact the only thing that is Apple-specific is that we assume
+ * that we can read from ROM at physical address 0xfff00000.)
+ *
+ *    Copyright (C) 2004 Paul Mackerras (paulus@samba.org) and
+ *                       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.
+ *
+ */
+
+#include <linux/config.h>
+#include <asm/processor.h>
+#include <asm/ppc_asm.h>
+#include <asm/cputable.h>
+
+/*
+ * Flush and disable all data caches (dL1, L2, L3). This is used
+ * when going to sleep, when doing a PMU based cpufreq transition,
+ * or when "offlining" a CPU on SMP machines. This code is over
+ * paranoid, but I've had enough issues with various CPU revs and
+ * bugs that I decided it was worth beeing over cautious
+ */
+
+_GLOBAL(flush_disable_caches)
+BEGIN_FTR_SECTION
+	b	flush_disable_745x
+END_FTR_SECTION_IFSET(CPU_FTR_SPEC7450)
+BEGIN_FTR_SECTION
+	b	flush_disable_75x
+END_FTR_SECTION_IFSET(CPU_FTR_L2CR)
+	b	__flush_disable_L1
+
+/* This is the code for G3 and 74[01]0 */
+flush_disable_75x:
+	mflr	r10
+
+	/* Turn off EE and DR in MSR */
+	mfmsr	r11
+	rlwinm	r0,r11,0,~MSR_EE
+	rlwinm	r0,r0,0,~MSR_DR
+	sync
+	mtmsr	r0
+	isync
+
+	/* Stop DST streams */
+BEGIN_FTR_SECTION
+	DSSALL
+	sync
+END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
+
+	/* Stop DPM */
+	mfspr	r8,SPRN_HID0		/* Save HID0 in r8 */
+	rlwinm	r4,r8,0,12,10		/* Turn off HID0[DPM] */
+	sync
+	mtspr	SPRN_HID0,r4		/* Disable DPM */
+	sync
+
+	/* disp-flush L1 */
+	li	r4,0x4000
+	mtctr	r4
+	lis	r4,0xfff0
+1:	lwzx	r0,r0,r4
+	addi	r4,r4,32
+	bdnz	1b
+	sync
+	isync
+
+	/* disable / invalidate / enable L1 data */
+	mfspr	r3,SPRN_HID0
+	rlwinm	r0,r0,0,~HID0_DCE
+	mtspr	SPRN_HID0,r3
+	sync
+	isync
+	ori	r3,r3,HID0_DCE|HID0_DCI
+	sync
+	isync
+	mtspr	SPRN_HID0,r3
+	xori	r3,r3,HID0_DCI
+	mtspr	SPRN_HID0,r3
+	sync
+
+	/* Get the current enable bit of the L2CR into r4 */
+	mfspr	r5,L2CR
+	/* Set to data-only (pre-745x bit) */
+	oris	r3,r5,L2CR_L2DO@h
+	b	2f
+	/* When disabling L2, code must be in L1 */
+	.balign 32
+1:	mtspr	L2CR,r3
+3:	sync
+	isync
+	b	1f
+2:	b	3f
+3:	sync
+	isync
+	b	1b
+1:	/* disp-flush L2. The interesting thing here is that the L2 can be
+	 * up to 2Mb ... so using the ROM, we'll end up wrapping back to memory
+	 * but that is probbaly fine. We disp-flush over 4Mb to be safe
+	 */
+	lis	r4,2
+	mtctr	r4
+	lis	r4,0xfff0
+1:	lwzx	r0,r0,r4
+	addi	r4,r4,32
+	bdnz	1b
+	sync
+	isync
+	/* now disable L2 */
+	rlwinm	r5,r5,0,~L2CR_L2E
+	b	2f
+	/* When disabling L2, code must be in L1 */
+	.balign 32
+1:	mtspr	L2CR,r5
+3:	sync
+	isync
+	b	1f
+2:	b	3f
+3:	sync
+	isync
+	b	1b
+1:	sync
+	isync
+	/* Invalidate L2. This is pre-745x, we clear the L2I bit ourselves */
+	oris	r4,r5,L2CR_L2I@h
+	mtspr	L2CR,r4
+	sync
+	isync
+	xoris	r4,r4,L2CR_L2I@h
+	sync
+	mtspr	L2CR,r4
+	sync
+
+	/* now disable the L1 data cache */
+	mfspr	r0,HID0
+	rlwinm	r0,r0,0,~HID0_DCE
+	mtspr	HID0,r0
+	sync
+	isync
+
+	/* Restore HID0[DPM] to whatever it was before */
+	sync
+	mtspr	SPRN_HID0,r8
+	sync
+
+	/* restore DR and EE */
+	sync
+	mtmsr	r11
+	isync
+
+	mtlr	r10
+	blr
+
+/* This code is for 745x processors */
+flush_disable_745x:
+	/* Turn off EE and DR in MSR */
+	mfmsr	r11
+	rlwinm	r0,r11,0,~MSR_EE
+	rlwinm	r0,r0,0,~MSR_DR
+	sync
+	mtmsr	r0
+	isync
+
+	/* Stop prefetch streams */
+	DSSALL
+	sync
+
+	/* Disable L2 prefetching */
+	mfspr	r0,SPRN_MSSCR0
+	rlwinm	r0,r0,0,0,29
+	mtspr	SPRN_MSSCR0,r0
+	sync
+	isync
+	lis	r4,0
+	dcbf	0,r4
+	dcbf	0,r4
+	dcbf	0,r4
+	dcbf	0,r4
+	dcbf	0,r4
+	dcbf	0,r4
+	dcbf	0,r4
+	dcbf	0,r4
+
+	/* Due to a bug with the HW flush on some CPU revs, we occasionally
+	 * experience data corruption. I'm adding a displacement flush along
+	 * with a dcbf loop over a few Mb to "help". The problem isn't totally
+	 * fixed by this in theory, but at least, in practice, I couldn't reproduce
+	 * it even with a big hammer...
+	 */
+
+        lis     r4,0x0002
+        mtctr   r4
+ 	li      r4,0
+1:
+        lwzx    r0,r0,r4
+        addi    r4,r4,32                /* Go to start of next cache line */
+        bdnz    1b
+        isync
+
+        /* Now, flush the first 4MB of memory */
+        lis     r4,0x0002
+        mtctr   r4
+	li      r4,0
+        sync
+1:
+        dcbf    0,r4
+        addi    r4,r4,32                /* Go to start of next cache line */
+        bdnz    1b
+
+	/* Flush and disable the L1 data cache */
+	mfspr	r6,SPRN_LDSTCR
+	lis	r3,0xfff0	/* read from ROM for displacement flush */
+	li	r4,0xfe		/* start with only way 0 unlocked */
+	li	r5,128		/* 128 lines in each way */
+1:	mtctr	r5
+	rlwimi	r6,r4,0,24,31
+	mtspr	SPRN_LDSTCR,r6
+	sync
+	isync
+2:	lwz	r0,0(r3)	/* touch each cache line */
+	addi	r3,r3,32
+	bdnz	2b
+	rlwinm	r4,r4,1,24,30	/* move on to the next way */
+	ori	r4,r4,1
+	cmpwi	r4,0xff		/* all done? */
+	bne	1b
+	/* now unlock the L1 data cache */
+	li	r4,0
+	rlwimi	r6,r4,0,24,31
+	sync
+	mtspr	SPRN_LDSTCR,r6
+	sync
+	isync
+
+	/* Flush the L2 cache using the hardware assist */
+	mfspr	r3,L2CR
+	cmpwi	r3,0		/* check if it is enabled first */
+	bge	4f
+	oris	r0,r3,(L2CR_L2IO_745x|L2CR_L2DO_745x)@h
+	b	2f
+	/* When disabling/locking L2, code must be in L1 */
+	.balign 32
+1:	mtspr	L2CR,r0		/* lock the L2 cache */
+3:	sync
+	isync
+	b	1f
+2:	b	3f
+3:	sync
+	isync
+	b	1b
+1:	sync
+	isync
+	ori	r0,r3,L2CR_L2HWF_745x
+	sync
+	mtspr	L2CR,r0		/* set the hardware flush bit */
+3:	mfspr	r0,L2CR		/* wait for it to go to 0 */
+	andi.	r0,r0,L2CR_L2HWF_745x
+	bne	3b
+	sync
+	rlwinm	r3,r3,0,~L2CR_L2E
+	b	2f
+	/* When disabling L2, code must be in L1 */
+	.balign 32
+1:	mtspr	L2CR,r3		/* disable the L2 cache */
+3:	sync
+	isync
+	b	1f
+2:	b	3f
+3:	sync
+	isync
+	b	1b
+1:	sync
+	isync
+	oris	r4,r3,L2CR_L2I@h
+	mtspr	L2CR,r4
+	sync
+	isync
+1:	mfspr	r4,L2CR
+	andis.	r0,r4,L2CR_L2I@h
+	bne	1b
+	sync
+
+BEGIN_FTR_SECTION
+	/* Flush the L3 cache using the hardware assist */
+4:	mfspr	r3,L3CR
+	cmpwi	r3,0		/* check if it is enabled */
+	bge	6f
+	oris	r0,r3,L3CR_L3IO@h
+	ori	r0,r0,L3CR_L3DO
+	sync
+	mtspr	L3CR,r0		/* lock the L3 cache */
+	sync
+	isync
+	ori	r0,r0,L3CR_L3HWF
+	sync
+	mtspr	L3CR,r0		/* set the hardware flush bit */
+5:	mfspr	r0,L3CR		/* wait for it to go to zero */
+	andi.	r0,r0,L3CR_L3HWF
+	bne	5b
+	rlwinm	r3,r3,0,~L3CR_L3E
+	sync
+	mtspr	L3CR,r3		/* disable the L3 cache */
+	sync
+	ori	r4,r3,L3CR_L3I
+	mtspr	SPRN_L3CR,r4
+1:	mfspr	r4,SPRN_L3CR
+	andi.	r0,r4,L3CR_L3I
+	bne	1b
+	sync
+END_FTR_SECTION_IFSET(CPU_FTR_L3CR)
+
+6:	mfspr	r0,HID0		/* now disable the L1 data cache */
+	rlwinm	r0,r0,0,~HID0_DCE
+	mtspr	HID0,r0
+	sync
+	isync
+	mtmsr	r11		/* restore DR and EE */
+	isync
+	blr
diff -Nru a/arch/ppc/platforms/pmac_cpufreq.c b/arch/ppc/platforms/pmac_cpufreq.c
--- a/arch/ppc/platforms/pmac_cpufreq.c	2005-03-01 23:38:58 -08:00
+++ b/arch/ppc/platforms/pmac_cpufreq.c	2005-03-01 23:38:58 -08:00
@@ -154,6 +154,14 @@
 	return 0;
 }
 
+static unsigned int __pmac dfs_get_cpu_speed(unsigned int cpu)
+{
+	if (mfspr(HID1) & HID1_DFS)
+		return low_freq;
+	else
+		return hi_freq;
+}
+
 
 /* Switch CPU speed using slewing GPIOs
  */
@@ -229,10 +237,6 @@
 	/* Save & disable L2 and L3 caches */
 	save_l3cr = _get_L3CR();	/* (returns -1 if not available) */
 	save_l2cr = _get_L2CR();	/* (returns -1 if not available) */
-	if (save_l3cr != 0xffffffff && (save_l3cr & L3CR_L3E) != 0)
-		_set_L3CR(save_l3cr & 0x7fffffff);
-	if (save_l2cr != 0xffffffff && (save_l2cr & L2CR_L2E) != 0)
-		_set_L2CR(save_l2cr & 0x7fffffff);
 
 	/* Send the new speed command. My assumption is that this command
 	 * will cause PLL_CFG[0..3] to be changed next time CPU goes to sleep
@@ -458,14 +462,13 @@
 {
 	struct device_node *volt_gpio_np;
 	u32 *reg;
+	struct cpufreq_driver *driver = &pmac_cpufreq_driver;
 
 	/* OF only reports the high frequency */
 	hi_freq = cur_freq;
 	low_freq = cur_freq/2;
-	if (mfspr(HID1) & HID1_DFS)
-		cur_freq = low_freq;
-	else
-		cur_freq = hi_freq;
+	driver->get = dfs_get_cpu_speed;
+	cur_freq = driver->get(0);
 
 	volt_gpio_np = of_find_node_by_name(NULL, "cpu-vcore-select");
 	if (!volt_gpio_np){
diff -Nru a/arch/ppc/platforms/pmac_feature.c b/arch/ppc/platforms/pmac_feature.c
--- a/arch/ppc/platforms/pmac_feature.c	2005-03-01 23:39:16 -08:00
+++ b/arch/ppc/platforms/pmac_feature.c	2005-03-01 23:39:16 -08:00
@@ -56,14 +56,14 @@
 #endif
 
 extern int powersave_nap;
-extern struct pci_dev *k2_skiplist[2];
+extern struct device_node *k2_skiplist[2];
 
 
 /*
  * We use a single global lock to protect accesses. Each driver has
  * to take care of its own locking
  */
-static spinlock_t feature_lock  __pmacdata = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(feature_lock  __pmacdata);
 
 #define LOCK(flags)	spin_lock_irqsave(&feature_lock, flags);
 #define UNLOCK(flags)	spin_unlock_irqrestore(&feature_lock, flags);
@@ -1177,6 +1177,39 @@
 			(void)MACIO_IN32(KEYLARGO_FCR3);
 			udelay(10);
 		}
+		if (macio->type == macio_intrepid) {
+			/* wait for clock stopped bits to clear */
+			u32 test0 = 0, test1 = 0;
+			u32 status0, status1;
+			int timeout = 1000;
+
+			UNLOCK(flags);
+			switch (number) {
+			case 0:
+				test0 = UNI_N_CLOCK_STOPPED_USB0;
+				test1 = UNI_N_CLOCK_STOPPED_USB0PCI;
+				break;
+			case 2:
+				test0 = UNI_N_CLOCK_STOPPED_USB1;
+				test1 = UNI_N_CLOCK_STOPPED_USB1PCI;
+				break;
+			case 4:
+				test0 = UNI_N_CLOCK_STOPPED_USB2;
+				test1 = UNI_N_CLOCK_STOPPED_USB2PCI;
+				break;
+			}
+			do {
+				if (--timeout <= 0) {
+					printk(KERN_ERR "core99_usb_enable: "
+					       "Timeout waiting for clocks\n");
+					break;
+				}
+				mdelay(1);
+				status0 = UN_IN(UNI_N_CLOCK_STOP_STATUS0);
+				status1 = UN_IN(UNI_N_CLOCK_STOP_STATUS1);
+			} while ((status0 & test0) | (status1 & test1));
+			LOCK(flags);
+		}
 	} else {
 		/* Turn OFF */
 		if (number < 4) {
@@ -1199,20 +1232,20 @@
 			udelay(1);
 		}
 		if (number == 0) {
-			MACIO_BIC(KEYLARGO_FCR0, KL0_USB0_CELL_ENABLE);
+			if (macio->type != macio_intrepid)
+				MACIO_BIC(KEYLARGO_FCR0, KL0_USB0_CELL_ENABLE);
 			(void)MACIO_IN32(KEYLARGO_FCR0);
 			udelay(1);
 			MACIO_BIS(KEYLARGO_FCR0, (KL0_USB0_PAD_SUSPEND0 | KL0_USB0_PAD_SUSPEND1));
 			(void)MACIO_IN32(KEYLARGO_FCR0);
 		} else if (number == 2) {
-			MACIO_BIC(KEYLARGO_FCR0, KL0_USB1_CELL_ENABLE);
+			if (macio->type != macio_intrepid)
+				MACIO_BIC(KEYLARGO_FCR0, KL0_USB1_CELL_ENABLE);
 			(void)MACIO_IN32(KEYLARGO_FCR0);
 			udelay(1);
 			MACIO_BIS(KEYLARGO_FCR0, (KL0_USB1_PAD_SUSPEND0 | KL0_USB1_PAD_SUSPEND1));
 			(void)MACIO_IN32(KEYLARGO_FCR0);
 		} else if (number == 4) {
-			MACIO_BIC(KEYLARGO_FCR1, KL1_USB2_CELL_ENABLE);
-			(void)MACIO_IN32(KEYLARGO_FCR1);
 			udelay(1);
 			MACIO_BIS(KEYLARGO_FCR1, (KL1_USB2_PAD_SUSPEND0 | KL1_USB2_PAD_SUSPEND1));
 			(void)MACIO_IN32(KEYLARGO_FCR1);
@@ -1328,24 +1361,15 @@
 {
 	struct macio_chip* macio = &macio_chips[0];
 	unsigned long flags;
-	struct pci_dev *pdev;
 	u8 pbus, pid;
 
-	/* XXX FIXME: We should fix pci_device_from_OF_node here, and
-	 * get to a real pci_dev or we'll get into trouble with PCI
-	 * domains the day we get overlapping numbers (like if we ever
-	 * decide to show the HT root
-	 */
-	if (pci_device_from_OF_node(node, &pbus, &pid) == 0)
-		pdev = pci_find_slot(pbus, pid);
-
 	LOCK(flags);
 	if (value) {
 		MACIO_BIS(KEYLARGO_FCR1, K2_FCR1_GMAC_CLK_ENABLE);
 		mb();
 		k2_skiplist[0] = NULL;
 	} else {
-		k2_skiplist[0] = pdev;
+		k2_skiplist[0] = node;
 		mb();
 		MACIO_BIC(KEYLARGO_FCR1, K2_FCR1_GMAC_CLK_ENABLE);
 	}
@@ -1361,16 +1385,6 @@
 {
 	struct macio_chip* macio = &macio_chips[0];
 	unsigned long flags;
-	struct pci_dev *pdev;
-	u8 pbus, pid;
-
-	/* XXX FIXME: We should fix pci_device_from_OF_node here, and
-	 * get to a real pci_dev or we'll get into trouble with PCI
-	 * domains the day we get overlapping numbers (like if we ever
-	 * decide to show the HT root
-	 */
-	if (pci_device_from_OF_node(node, &pbus, &pid) == 0)
-		pdev = pci_find_slot(pbus, pid);
 
 	LOCK(flags);
 	if (value) {
@@ -1378,7 +1392,7 @@
 		mb();
 		k2_skiplist[1] = NULL;
 	} else {
-		k2_skiplist[1] = pdev;
+		k2_skiplist[1] = node;
 		mb();
 		MACIO_BIC(KEYLARGO_FCR1, K2_FCR1_FW_CLK_ENABLE);
 	}
@@ -1554,22 +1568,17 @@
 	u32 temp;
 
 	MACIO_BIC(KEYLARGO_FCR0,KL0_SCCA_ENABLE | KL0_SCCB_ENABLE |
-				KL0_SCC_CELL_ENABLE |
-				KL0_USB0_CELL_ENABLE | KL0_USB1_CELL_ENABLE);
+		  KL0_SCC_CELL_ENABLE);
 
 	MACIO_BIC(KEYLARGO_FCR1,
-		KL1_USB2_CELL_ENABLE |
+		  /*KL1_USB2_CELL_ENABLE |*/
 		KL1_I2S0_CELL_ENABLE | KL1_I2S0_CLK_ENABLE_BIT |
 		KL1_I2S0_ENABLE | KL1_I2S1_CELL_ENABLE |
 		KL1_I2S1_CLK_ENABLE_BIT | KL1_I2S1_ENABLE);
 	if (pmac_mb.board_flags & PMAC_MB_MOBILE)
 		MACIO_BIC(KEYLARGO_FCR1, KL1_UIDE_RESET_N);
 
-	MACIO_BIS(KEYLARGO_FCR2, KL2_ALT_DATA_OUT);
-
 	temp = MACIO_IN32(KEYLARGO_FCR3);
-	temp |= KL3_IT_SHUTDOWN_PLL1 | KL3_IT_SHUTDOWN_PLL2 |
-		KL3_IT_SHUTDOWN_PLL3;
 	temp &= ~(KL3_CLK49_ENABLE | KL3_CLK45_ENABLE |
 		  KL3_I2S1_CLK18_ENABLE | KL3_I2S0_CLK18_ENABLE);
 	if (sleep_mode)
@@ -1577,7 +1586,8 @@
 	MACIO_OUT32(KEYLARGO_FCR3, temp);
 
 	/* Flush posted writes & wait a bit */
-	(void)MACIO_IN32(KEYLARGO_FCR0); mdelay(1);
+	(void)MACIO_IN32(KEYLARGO_FCR0);
+	mdelay(10);
 }
 
 static int __pmac
@@ -1591,6 +1601,12 @@
 	    macio->type != macio_intrepid)
 		return -ENODEV;
 
+	/* The device-tree contains that in the hwclock node */
+	if (macio->type == macio_intrepid) {
+		UN_OUT(UNI_N_CLOCK_SPREADING, 0);
+		mdelay(40);
+	}
+
 	/* We power off the wireless slot in case it was not done
 	 * by the driver. We don't power it on automatically however
 	 */
@@ -1653,11 +1669,15 @@
 	 */
 
 	save_unin_clock_ctl = UN_IN(UNI_N_CLOCK_CNTL);
+	/* Note: do not switch GMAC off, driver does it when necessary, WOL must keep it
+	 * enabled !
+	 */
 	UN_OUT(UNI_N_CLOCK_CNTL, save_unin_clock_ctl &
-		~(UNI_N_CLOCK_CNTL_GMAC|UNI_N_CLOCK_CNTL_FW/*|UNI_N_CLOCK_CNTL_PCI*/));
+	       ~(/*UNI_N_CLOCK_CNTL_GMAC|*/UNI_N_CLOCK_CNTL_FW/*|UNI_N_CLOCK_CNTL_PCI*/));
 	udelay(100);
 	UN_OUT(UNI_N_HWINIT_STATE, UNI_N_HWINIT_STATE_SLEEPING);
 	UN_OUT(UNI_N_POWER_MGT, UNI_N_POWER_MGT_SLEEP);
+	mdelay(10);
 
 	/*
 	 * FIXME: A bit of black magic with OpenPIC (don't ask me why)
@@ -1729,6 +1749,12 @@
 	UN_OUT(UNI_N_CLOCK_CNTL, save_unin_clock_ctl);
 	udelay(100);
 
+	/* Restore clock spreading */
+	if (macio->type == macio_intrepid) {
+		UN_OUT(UNI_N_CLOCK_SPREADING, 2);
+		mdelay(40);
+	}
+
 	return 0;
 }
 
@@ -1752,6 +1778,33 @@
 	}
 	if ((pmac_mb.board_flags & PMAC_MB_CAN_SLEEP) == 0)
 		return -EPERM;
+
+#ifdef CONFIG_CPU_FREQ_PMAC
+	/* XXX should be elsewhere */
+	if (machine_is_compatible("PowerBook6,5") ||
+	    machine_is_compatible("PowerBook6,4") ||
+	    machine_is_compatible("PowerBook5,5") ||
+	    machine_is_compatible("PowerBook5,4")) {
+		struct device_node *volt_gpio_np;
+		u32 *reg = NULL;
+
+		volt_gpio_np = of_find_node_by_name(NULL, "cpu-vcore-select");
+		if (volt_gpio_np != NULL)
+			reg = (u32 *)get_property(volt_gpio_np, "reg", NULL);
+		if (reg != NULL) {
+			/* Set the CPU voltage high if sleeping */
+			if (value == 1) {
+				pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL,
+						  *reg, 0x05);
+			} else if (value == 0 && (mfspr(HID1) & HID1_DFS)) {
+				pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL,
+						  *reg, 0x04);
+			}
+			mdelay(2);
+		}
+	}
+#endif /* CONFIG_CPU_FREQ_PMAC */
+
 	if (value == 1)
 		return core99_sleep();
 	else if (value == 0)
@@ -1762,6 +1815,18 @@
 #endif /* CONFIG_POWER4 */
 
 static long __pmac
+generic_dev_can_wake(struct device_node* node, long param, long value)
+{
+	/* Todo: eventually check we are really dealing with on-board
+	 * video device ...
+	 */
+
+	if (pmac_mb.board_flags & PMAC_MB_MAY_SLEEP)
+		pmac_mb.board_flags |= PMAC_MB_CAN_SLEEP;
+	return 0;
+}
+
+static long __pmac
 generic_get_mb_info(struct device_node* node, long param, long value)
 {
 	switch(param) {
@@ -1786,6 +1851,7 @@
  */
 static struct feature_table_entry any_features[]  __pmacdata = {
 	{ PMAC_FTR_GET_MB_INFO,		generic_get_mb_info },
+	{ PMAC_FTR_DEVICE_CAN_WAKE,	generic_dev_can_wake },
 	{ 0, NULL }
 };
 
@@ -2014,7 +2080,7 @@
 	},
 	{	"PowerBook1,1",			"PowerBook 101 (Lombard)",
 		PMAC_TYPE_101_PBOOK,		paddington_features,
-		PMAC_MB_CAN_SLEEP | PMAC_MB_MOBILE
+		PMAC_MB_MAY_SLEEP | PMAC_MB_MOBILE
 	},
 	{	"iMac,1",			"iMac (first generation)",
 		PMAC_TYPE_ORIG_IMAC,		paddington_features,
@@ -2022,23 +2088,23 @@
 	},
 	{	"PowerMac4,1",			"iMac \"Flower Power\"",
 		PMAC_TYPE_PANGEA_IMAC,		pangea_features,
-		PMAC_MB_CAN_SLEEP
+		PMAC_MB_MAY_SLEEP
 	},
 	{	"PowerBook4,3",			"iBook 2 rev. 2",
 		PMAC_TYPE_IBOOK2,		pangea_features,
-		PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
+		PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
 	},
 	{	"PowerBook4,2",			"iBook 2",
 		PMAC_TYPE_IBOOK2,		pangea_features,
-		PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
+		PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
 	},
 	{	"PowerBook4,1",			"iBook 2",
 		PMAC_TYPE_IBOOK2,		pangea_features,
-		PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
+		PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
 	},
 	{	"PowerMac4,4",			"eMac",
 		PMAC_TYPE_EMAC,			core99_features,
-		PMAC_MB_CAN_SLEEP
+		PMAC_MB_MAY_SLEEP
 	},
 	{	"PowerMac4,2",			"Flat panel iMac",
 		PMAC_TYPE_FLAT_PANEL_IMAC,	pangea_features,
@@ -2062,55 +2128,57 @@
 	},
 	{	"PowerMac3,2",			"PowerMac G4 AGP Graphics",
 		PMAC_TYPE_SAWTOOTH,		core99_features,
-		PMAC_MB_OLD_CORE99
+		PMAC_MB_MAY_SLEEP | PMAC_MB_OLD_CORE99
 	},
 	{	"PowerMac3,3",			"PowerMac G4 AGP Graphics",
 		PMAC_TYPE_SAWTOOTH,		core99_features,
-		PMAC_MB_OLD_CORE99
+		PMAC_MB_MAY_SLEEP | PMAC_MB_OLD_CORE99
 	},
 	{	"PowerMac2,1",			"iMac FireWire",
 		PMAC_TYPE_FW_IMAC,		core99_features,
-		PMAC_MB_CAN_SLEEP | PMAC_MB_OLD_CORE99
+		PMAC_MB_MAY_SLEEP | PMAC_MB_OLD_CORE99
 	},
 	{	"PowerMac2,2",			"iMac FireWire",
 		PMAC_TYPE_FW_IMAC,		core99_features,
-		PMAC_MB_CAN_SLEEP | PMAC_MB_OLD_CORE99
+		PMAC_MB_MAY_SLEEP | PMAC_MB_OLD_CORE99
 	},
 	{	"PowerBook2,2",			"iBook FireWire",
 		PMAC_TYPE_FW_IBOOK,		core99_features,
-		PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_OLD_CORE99 | PMAC_MB_MOBILE
+		PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER |
+		PMAC_MB_OLD_CORE99 | PMAC_MB_MOBILE
 	},
 	{	"PowerMac5,1",			"PowerMac G4 Cube",
 		PMAC_TYPE_CUBE,			core99_features,
-		PMAC_MB_OLD_CORE99
+		PMAC_MB_MAY_SLEEP | PMAC_MB_OLD_CORE99
 	},
 	{	"PowerMac3,4",			"PowerMac G4 Silver",
 		PMAC_TYPE_QUICKSILVER,		core99_features,
-		0
+		PMAC_MB_MAY_SLEEP
 	},
 	{	"PowerMac3,5",			"PowerMac G4 Silver",
 		PMAC_TYPE_QUICKSILVER,		core99_features,
-		0
+		PMAC_MB_MAY_SLEEP
 	},
 	{	"PowerBook3,1",			"PowerBook Pismo",
 		PMAC_TYPE_PISMO,		core99_features,
-		PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_OLD_CORE99 | PMAC_MB_MOBILE
+		PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER |
+		PMAC_MB_OLD_CORE99 | PMAC_MB_MOBILE
 	},
 	{	"PowerBook3,2",			"PowerBook Titanium",
 		PMAC_TYPE_TITANIUM,		core99_features,
-		PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
+		PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
 	},
 	{	"PowerBook3,3",			"PowerBook Titanium II",
 		PMAC_TYPE_TITANIUM2,		core99_features,
-		PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
+		PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
 	},
 	{	"PowerBook3,4",			"PowerBook Titanium III",
 		PMAC_TYPE_TITANIUM3,		core99_features,
-		PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
+		PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
 	},
 	{	"PowerBook3,5",			"PowerBook Titanium IV",
 		PMAC_TYPE_TITANIUM4,		core99_features,
-		PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
+		PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
 	},
 	{	"RackMac1,1",			"XServe",
 		PMAC_TYPE_RACKMAC,		rackmac_features,
@@ -2122,7 +2190,7 @@
 	},
 	{	"PowerMac3,6",			"PowerMac G4 Windtunnel",
 		PMAC_TYPE_WINDTUNNEL,		core99_features,
-		0,
+		PMAC_MB_MAY_SLEEP,
 	},
 	{	"PowerBook5,1",			"PowerBook G4 17\"",
 		PMAC_TYPE_UNKNOWN_INTREPID,	intrepid_features,
@@ -2130,39 +2198,39 @@
 	},
 	{	"PowerBook5,2",			"PowerBook G4 15\"",
 		PMAC_TYPE_UNKNOWN_INTREPID,	intrepid_features,
-		PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
+		PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
 	},
 	{	"PowerBook5,3",			"PowerBook G4 17\"",
 		PMAC_TYPE_UNKNOWN_INTREPID,	intrepid_features,
-		PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
+		PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
 	},
 	{	"PowerBook5,4",			"PowerBook G4 15\"",
 		PMAC_TYPE_UNKNOWN_INTREPID,	intrepid_features,
-		PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
+		PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
 	},
 	{	"PowerBook5,5",			"PowerBook G4 17\"",
 		PMAC_TYPE_UNKNOWN_INTREPID,	intrepid_features,
-		PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
+		PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
 	},
 	{	"PowerBook6,1",			"PowerBook G4 12\"",
 		PMAC_TYPE_UNKNOWN_INTREPID,	intrepid_features,
-		PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
+		PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
 	},
 	{	"PowerBook6,2",			"PowerBook G4",
 		PMAC_TYPE_UNKNOWN_INTREPID,	intrepid_features,
-		PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
+		PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
 	},
 	{	"PowerBook6,3",			"iBook G4",
 		PMAC_TYPE_UNKNOWN_INTREPID,	intrepid_features,
-		PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
+		PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
 	},
 	{	"PowerBook6,4",			"PowerBook G4 12\"",
 		PMAC_TYPE_UNKNOWN_INTREPID,	intrepid_features,
-		PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
+		PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
 	},
 	{	"PowerBook6,5",			"iBook G4",
 		PMAC_TYPE_UNKNOWN_INTREPID,	intrepid_features,
-		PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
+		PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
 	},
 #else /* CONFIG_POWER4 */
 	{	"PowerMac7,2",			"PowerMac G5",
@@ -2839,3 +2907,27 @@
 }
 
 #endif /* CONFIG_POWER4 */
+
+/*
+ * Early video resume hook
+ */
+
+static void (*pmac_early_vresume_proc)(void *data) __pmacdata;
+static void *pmac_early_vresume_data __pmacdata;
+
+void pmac_set_early_video_resume(void (*proc)(void *data), void *data)
+{
+	if (_machine != _MACH_Pmac)
+		return;
+	preempt_disable();
+	pmac_early_vresume_proc = proc;
+	pmac_early_vresume_data = data;
+	preempt_enable();
+}
+EXPORT_SYMBOL(pmac_set_early_video_resume);
+
+void __pmac pmac_call_early_video_resume(void)
+{
+	if (pmac_early_vresume_proc)
+		pmac_early_vresume_proc(pmac_early_vresume_data);
+}
diff -Nru a/arch/ppc/platforms/pmac_nvram.c b/arch/ppc/platforms/pmac_nvram.c
--- a/arch/ppc/platforms/pmac_nvram.c	2005-03-01 23:38:56 -08:00
+++ b/arch/ppc/platforms/pmac_nvram.c	2005-03-01 23:38:56 -08:00
@@ -80,7 +80,7 @@
 static int nvram_mult, is_core_99;
 static int core99_bank = 0;
 static int nvram_partitions[3];
-static spinlock_t nv_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(nv_lock);
 
 extern int pmac_newworld;
 extern int system_running;
diff -Nru a/arch/ppc/platforms/pmac_pci.c b/arch/ppc/platforms/pmac_pci.c
--- a/arch/ppc/platforms/pmac_pci.c	2005-03-01 23:38:57 -08:00
+++ b/arch/ppc/platforms/pmac_pci.c	2005-03-01 23:38:57 -08:00
@@ -52,7 +52,7 @@
 extern u8 pci_cache_line_size;
 extern int pcibios_assign_bus_offset;
 
-struct pci_dev *k2_skiplist[2];
+struct device_node *k2_skiplist[2];
 
 /*
  * Magic constants for enabling cache coherency in the bandit/PSX bridge.
@@ -142,14 +142,14 @@
 	|(((unsigned long)(off)) & 0xFCUL) \
 	|1UL)
 
-static unsigned int __pmac
+static void volatile __iomem * __pmac
 macrisc_cfg_access(struct pci_controller* hose, u8 bus, u8 dev_fn, u8 offset)
 {
 	unsigned int caddr;
 
 	if (bus == hose->first_busno) {
 		if (dev_fn < (11 << 3))
-			return 0;
+			return NULL;
 		caddr = MACRISC_CFA0(dev_fn, offset);
 	} else
 		caddr = MACRISC_CFA1(bus, dev_fn, offset);
@@ -160,7 +160,7 @@
 	} while (in_le32(hose->cfg_addr) != caddr);
 
 	offset &= has_uninorth ? 0x07 : 0x03;
-	return (unsigned int)(hose->cfg_data) + (unsigned int)offset;
+	return hose->cfg_data + offset;
 }
 
 static int __pmac
@@ -168,7 +168,7 @@
 		    int len, u32 *val)
 {
 	struct pci_controller *hose = bus->sysdata;
-	unsigned int addr;
+	void volatile __iomem *addr;
 
 	addr = macrisc_cfg_access(hose, bus->number, devfn, offset);
 	if (!addr)
@@ -179,13 +179,13 @@
 	 */
 	switch (len) {
 	case 1:
-		*val = in_8((u8 *)addr);
+		*val = in_8(addr);
 		break;
 	case 2:
-		*val = in_le16((u16 *)addr);
+		*val = in_le16(addr);
 		break;
 	default:
-		*val = in_le32((u32 *)addr);
+		*val = in_le32(addr);
 		break;
 	}
 	return PCIBIOS_SUCCESSFUL;
@@ -196,7 +196,7 @@
 		     int len, u32 val)
 {
 	struct pci_controller *hose = bus->sysdata;
-	unsigned int addr;
+	void volatile __iomem *addr;
 
 	addr = macrisc_cfg_access(hose, bus->number, devfn, offset);
 	if (!addr)
@@ -207,16 +207,16 @@
 	 */
 	switch (len) {
 	case 1:
-		out_8((u8 *)addr, val);
-		(void) in_8((u8 *)addr);
+		out_8(addr, val);
+		(void) in_8(addr);
 		break;
 	case 2:
-		out_le16((u16 *)addr, val);
-		(void) in_le16((u16 *)addr);
+		out_le16(addr, val);
+		(void) in_le16(addr);
 		break;
 	default:
-		out_le32((u32 *)addr, val);
-		(void) in_le32((u32 *)addr);
+		out_le32(addr, val);
+		(void) in_le32(addr);
 		break;
 	}
 	return PCIBIOS_SUCCESSFUL;
@@ -295,7 +295,7 @@
 		+ (((unsigned long)bus) << 16) \
 		+ 0x01000000UL)
 
-static unsigned long __pmac
+static void volatile __iomem * __pmac
 u3_ht_cfg_access(struct pci_controller* hose, u8 bus, u8 devfn, u8 offset)
 {
 	if (bus == hose->first_busno) {
@@ -303,9 +303,9 @@
 		if (PCI_FUNC(devfn) != 0 || PCI_SLOT(devfn) > 7 ||
 		    PCI_SLOT(devfn) < 1)
 			return 0;
-		return ((unsigned long)hose->cfg_data) + U3_HT_CFA0(devfn, offset);
+		return hose->cfg_data + U3_HT_CFA0(devfn, offset);
 	} else
-		return ((unsigned long)hose->cfg_data) + U3_HT_CFA1(bus, devfn, offset);
+		return hose->cfg_data + U3_HT_CFA1(bus, devfn, offset);
 }
 
 static int __pmac
@@ -313,7 +313,7 @@
 		    int len, u32 *val)
 {
 	struct pci_controller *hose = bus->sysdata;
-	unsigned int addr;
+	void volatile __iomem *addr;
 	int i;
 
 	struct device_node *np = pci_busdev_to_OF_node(bus, devfn);
@@ -325,8 +325,7 @@
 	 * cycle accesses. Fix that here.
 	 */
 	for (i=0; i<2; i++)
-		if (k2_skiplist[i] && k2_skiplist[i]->bus == bus &&
-		    k2_skiplist[i]->devfn == devfn) {
+		if (k2_skiplist[i] == np) {
 			switch (len) {
 			case 1:
 				*val = 0xff; break;
@@ -347,13 +346,13 @@
 	 */
 	switch (len) {
 	case 1:
-		*val = in_8((u8 *)addr);
+		*val = in_8(addr);
 		break;
 	case 2:
-		*val = in_le16((u16 *)addr);
+		*val = in_le16(addr);
 		break;
 	default:
-		*val = in_le32((u32 *)addr);
+		*val = in_le32(addr);
 		break;
 	}
 	return PCIBIOS_SUCCESSFUL;
@@ -364,7 +363,7 @@
 		     int len, u32 val)
 {
 	struct pci_controller *hose = bus->sysdata;
-	unsigned int addr;
+	void volatile __iomem *addr;
 	int i;
 
 	struct device_node *np = pci_busdev_to_OF_node(bus, devfn);
@@ -375,8 +374,7 @@
 	 * cycle accesses. Fix that here.
 	 */
 	for (i=0; i<2; i++)
-		if (k2_skiplist[i] && k2_skiplist[i]->bus == bus &&
-		    k2_skiplist[i]->devfn == devfn)
+		if (k2_skiplist[i] == np)
 			return PCIBIOS_SUCCESSFUL;
 
 	addr = u3_ht_cfg_access(hose, bus->number, devfn, offset);
@@ -388,16 +386,16 @@
 	 */
 	switch (len) {
 	case 1:
-		out_8((u8 *)addr, val);
-		(void) in_8((u8 *)addr);
+		out_8(addr, val);
+		(void) in_8(addr);
 		break;
 	case 2:
-		out_le16((u16 *)addr, val);
-		(void) in_le16((u16 *)addr);
+		out_le16(addr, val);
+		(void) in_le16(addr);
 		break;
 	default:
-		out_le32((u32 *)addr, val);
-		(void) in_le32((u32 *)addr);
+		out_le32(addr, val);
+		(void) in_le32(addr);
 		break;
 	}
 	return PCIBIOS_SUCCESSFUL;
@@ -424,7 +422,7 @@
 	/* read the word at offset 0 in config space for device 11 */
 	out_le32(bp->cfg_addr, (1UL << BANDIT_DEVNUM) + PCI_VENDOR_ID);
 	udelay(2);
-	vendev = in_le32((volatile unsigned int *)bp->cfg_data);
+	vendev = in_le32(bp->cfg_data);
 	if (vendev == (PCI_DEVICE_ID_APPLE_BANDIT << 16) +
 			PCI_VENDOR_ID_APPLE) {
 		/* read the revision id */
@@ -443,12 +441,12 @@
 	/* read the word at offset 0x50 */
 	out_le32(bp->cfg_addr, (1UL << BANDIT_DEVNUM) + BANDIT_MAGIC);
 	udelay(2);
-	magic = in_le32((volatile unsigned int *)bp->cfg_data);
+	magic = in_le32(bp->cfg_data);
 	if ((magic & BANDIT_COHERENT) != 0)
 		return;
 	magic |= BANDIT_COHERENT;
 	udelay(2);
-	out_le32((volatile unsigned int *)bp->cfg_data, magic);
+	out_le32(bp->cfg_data, magic);
 	printk(KERN_INFO "Cache coherency enabled for bandit/PSX\n");
 }
 
@@ -622,12 +620,12 @@
 	unsigned int val;
 
 	out_be32(bp->cfg_addr, GRACKLE_CFA(0, 0, 0xa8));
-	val = in_le32((volatile unsigned int *)bp->cfg_data);
+	val = in_le32(bp->cfg_data);
 	val = enable? (val | GRACKLE_PICR1_STG) :
 		(val & ~GRACKLE_PICR1_STG);
 	out_be32(bp->cfg_addr, GRACKLE_CFA(0, 0, 0xa8));
-	out_le32((volatile unsigned int *)bp->cfg_data, val);
-	(void)in_le32((volatile unsigned int *)bp->cfg_data);
+	out_le32(bp->cfg_data, val);
+	(void)in_le32(bp->cfg_data);
 }
 
 static inline void grackle_set_loop_snoop(struct pci_controller *bp, int enable)
@@ -635,12 +633,12 @@
 	unsigned int val;
 
 	out_be32(bp->cfg_addr, GRACKLE_CFA(0, 0, 0xa8));
-	val = in_le32((volatile unsigned int *)bp->cfg_data);
+	val = in_le32(bp->cfg_data);
 	val = enable? (val | GRACKLE_PICR1_LOOPSNOOP) :
 		(val & ~GRACKLE_PICR1_LOOPSNOOP);
 	out_be32(bp->cfg_addr, GRACKLE_CFA(0, 0, 0xa8));
-	out_le32((volatile unsigned int *)bp->cfg_data, val);
-	(void)in_le32((volatile unsigned int *)bp->cfg_data);
+	out_le32(bp->cfg_data, val);
+	(void)in_le32(bp->cfg_data);
 }
 
 static int __init
@@ -659,10 +657,8 @@
 setup_bandit(struct pci_controller* hose, struct reg_property* addr)
 {
 	hose->ops = &macrisc_pci_ops;
-	hose->cfg_addr = (volatile unsigned int *)
-		ioremap(addr->address + 0x800000, 0x1000);
-	hose->cfg_data = (volatile unsigned char *)
-		ioremap(addr->address + 0xc00000, 0x1000);
+	hose->cfg_addr = ioremap(addr->address + 0x800000, 0x1000);
+	hose->cfg_data = ioremap(addr->address + 0xc00000, 0x1000);
 	init_bandit(hose);
 }
 
@@ -671,10 +667,8 @@
 {
 	/* assume a `chaos' bridge */
 	hose->ops = &chaos_pci_ops;
-	hose->cfg_addr = (volatile unsigned int *)
-		ioremap(addr->address + 0x800000, 0x1000);
-	hose->cfg_data = (volatile unsigned char *)
-		ioremap(addr->address + 0xc00000, 0x1000);
+	hose->cfg_addr = ioremap(addr->address + 0x800000, 0x1000);
+	hose->cfg_data = ioremap(addr->address + 0xc00000, 0x1000);
 }
 
 #ifdef CONFIG_POWER4
@@ -713,7 +707,7 @@
 	 * the reg address cell, we shall fix that by killing struct
 	 * reg_property and using some accessor functions instead
 	 */
-	hose->cfg_data = (volatile unsigned char *)ioremap(0xf2000000, 0x02000000);
+	hose->cfg_data = ioremap(0xf2000000, 0x02000000);
 
 	/*
 	 * /ht node doesn't expose a "ranges" property, so we "remove" regions that
@@ -919,8 +913,12 @@
 	 * (iBook second controller)
 	 */
 	if (dev->vendor == PCI_VENDOR_ID_APPLE
-	    && dev->device == PCI_DEVICE_ID_APPLE_KL_USB && !node)
+	    && (dev->class == ((PCI_CLASS_SERIAL_USB << 8) | 0x10))
+	    && !node) {
+		printk(KERN_INFO "Apple USB OHCI %s disabled by firmware\n",
+		       pci_name(dev));
 		return -EINVAL;
+	}
 
 	if (!node)
 		return 0;
diff -Nru a/arch/ppc/platforms/pmac_pic.c b/arch/ppc/platforms/pmac_pic.c
--- a/arch/ppc/platforms/pmac_pic.c	2005-03-01 23:39:10 -08:00
+++ b/arch/ppc/platforms/pmac_pic.c	2005-03-01 23:39:10 -08:00
@@ -68,7 +68,7 @@
 static int max_real_irqs __pmacdata;
 static u32 level_mask[4] __pmacdata;
 
-static spinlock_t pmac_pic_lock __pmacdata = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(pmac_pic_lock __pmacdata);
 
 
 #define GATWICK_IRQ_POOL_SIZE        10
diff -Nru a/arch/ppc/platforms/pmac_sleep.S b/arch/ppc/platforms/pmac_sleep.S
--- a/arch/ppc/platforms/pmac_sleep.S	2005-03-01 23:38:52 -08:00
+++ b/arch/ppc/platforms/pmac_sleep.S	2005-03-01 23:38:52 -08:00
@@ -161,12 +161,8 @@
 	addi r3,r3,sleep_storage@l
 	stw r5,0(r3)
 
-	/* Disable DPM during cache flush */
-	mfspr	r3, SPRN_HID0
-	rlwinm	r3,r3,0,12,10
-	sync
-	mtspr	SPRN_HID0,r3
-	sync
+	/* Flush & disable all caches */
+	bl	flush_disable_caches
 
 	/* Turn off data relocation. */
 	mfmsr	r3		/* Save MSR in r7 */
@@ -175,8 +171,13 @@
 	mtmsr	r3
 	isync
 
-	/* Flush & disable L1 cache */
-	bl	__flush_disable_L1
+BEGIN_FTR_SECTION
+	/* Flush any pending L2 data prefetches to work around HW bug */
+	sync
+	lis	r3,0xfff0
+	lwz	r0,0(r3)	/* perform cache-inhibited load to ROM */
+	sync			/* (caches are disabled at this point) */
+END_FTR_SECTION_IFSET(CPU_FTR_SPEC7450)
 
 /*
  * Set the HID0 and MSR for sleep.
@@ -212,17 +213,16 @@
  * r4 has the physical address of SL_PC(sp) (unused)
  */
 _GLOBAL(core99_wake_up)
-	/* Make sure HID0 no longer contains any sleep bit */
+	/* Make sure HID0 no longer contains any sleep bit and that data cache
+	 * is disabled
+	 */
 	mfspr	r3,HID0
 	rlwinm	r3,r3,0,11,7		/* clear SLEEP, NAP, DOZE bits */
+	rlwinm	3,r3,0,18,15		/* clear DCE, ICE */
 	mtspr	HID0,r3
 	sync
 	isync
 
-	/* Won't that cause problems on CPU that doesn't support it ? */
-	lis	r3, 0
-	mtspr	SPRN_MMCR0, r3
-
 	/* sanitize MSR */
 	mfmsr	r3
 	ori	r3,r3,MSR_EE|MSR_IP
@@ -246,10 +246,6 @@
  */
 
 grackle_wake_up:
-	/* Invalidate & enable L1 cache, we don't care about
-	 * whatever the ROM may have tried to write to memory
-	 */
-	bl	__inval_enable_L1
 
 	/* Restore the kernel's segment registers before
 	 * we do any r1 memory access as we are not sure they
@@ -270,6 +266,11 @@
 
 	/* Restore various CPU config stuffs */
 	bl	__restore_cpu_setup
+
+	/* Invalidate & enable L1 cache, we don't care about
+	 * whatever the ROM may have tried to write to memory
+	 */
+	bl	__inval_enable_L1
 
 	/* Restore the BATs, and SDR1.  Then we can turn on the MMU. */
 	lwz	r4,SL_SDR1(r1)
diff -Nru a/arch/ppc/platforms/pq2ads.c b/arch/ppc/platforms/pq2ads.c
--- a/arch/ppc/platforms/pq2ads.c	2005-03-01 23:39:18 -08:00
+++ b/arch/ppc/platforms/pq2ads.c	2005-03-01 23:39:18 -08:00
@@ -19,8 +19,8 @@
 #include <asm/mpc8260.h>
 
 void __init
-m82xx_board_init(void)
+m82xx_board_setup(void)
 {
 	/* Enable the 2nd UART port */
-        *(volatile uint *)(BCSR_ADDR + 4) &= ~BCSR1_RS232_EN2;
+	*(volatile uint *)(BCSR_ADDR + 4) &= ~BCSR1_RS232_EN2;
 }
diff -Nru a/arch/ppc/platforms/pq2ads.h b/arch/ppc/platforms/pq2ads.h
--- a/arch/ppc/platforms/pq2ads.h	2005-03-01 23:38:58 -08:00
+++ b/arch/ppc/platforms/pq2ads.h	2005-03-01 23:38:58 -08:00
@@ -40,6 +40,8 @@
 #define BCSR1_FETH_RST		((uint)0x04000000)	/* 0 == reset */
 #define BCSR1_RS232_EN1		((uint)0x02000000)	/* 0 == enable */
 #define BCSR1_RS232_EN2		((uint)0x01000000)	/* 0 == enable */
+#define BCSR3_FETHIEN2		((uint)0x10000000)	/* 0 == enable */
+#define BCSR3_FETH2_RST 	((uint)0x80000000)	/* 0 == reset */
 
 #define PHY_INTERRUPT	SIU_INT_IRQ7
 
diff -Nru a/arch/ppc/platforms/prep_pci.c b/arch/ppc/platforms/prep_pci.c
--- a/arch/ppc/platforms/prep_pci.c	2005-03-01 23:39:17 -08:00
+++ b/arch/ppc/platforms/prep_pci.c	2005-03-01 23:39:17 -08:00
@@ -627,7 +627,7 @@
 		 int len, u32 *val)
 {
 	struct pci_controller *hose = bus->sysdata;
-	volatile unsigned char *cfg_data;
+	volatile void __iomem *cfg_data;
 
 	if (bus->number != 0 || DEVNO(devfn) < MIN_DEVNR
 	    || DEVNO(devfn) > MAX_DEVNR)
@@ -640,13 +640,13 @@
 	cfg_data = hose->cfg_data + CFGADDR(devfn) + offset;
 	switch (len) {
 	case 1:
-		*val = in_8((u8 *)cfg_data);
+		*val = in_8(cfg_data);
 		break;
 	case 2:
-		*val = in_le16((u16 *)cfg_data);
+		*val = in_le16(cfg_data);
 		break;
 	default:
-		*val = in_le32((u32 *)cfg_data);
+		*val = in_le32(cfg_data);
 		break;
 	}
 	return PCIBIOS_SUCCESSFUL;
@@ -657,7 +657,7 @@
 		  int len, u32 val)
 {
 	struct pci_controller *hose = bus->sysdata;
-	volatile unsigned char *cfg_data;
+	volatile void __iomem *cfg_data;
 
 	if (bus->number != 0 || DEVNO(devfn) < MIN_DEVNR
 	    || DEVNO(devfn) > MAX_DEVNR)
@@ -670,13 +670,13 @@
 	cfg_data = hose->cfg_data + CFGADDR(devfn) + offset;
 	switch (len) {
 	case 1:
-		out_8((u8 *)cfg_data, val);
+		out_8(cfg_data, val);
 		break;
 	case 2:
-		out_le16((u16 *)cfg_data, val);
+		out_le16(cfg_data, val);
 		break;
 	default:
-		out_le32((u32 *)cfg_data, val);
+		out_le32(cfg_data, val);
 		break;
 	}
 	return PCIBIOS_SUCCESSFUL;
diff -Nru a/arch/ppc/platforms/prep_setup.c b/arch/ppc/platforms/prep_setup.c
--- a/arch/ppc/platforms/prep_setup.c	2005-03-01 23:39:09 -08:00
+++ b/arch/ppc/platforms/prep_setup.c	2005-03-01 23:39:09 -08:00
@@ -645,7 +645,7 @@
 static void __init
 prep_init_vesa(void)
 {
-#if     (defined(CONFIG_FB_VGA16) || defined(CONFIG_FB_VGA_16_MODULE) || \
+#if     (defined(CONFIG_FB_VGA16) || defined(CONFIG_FB_VGA16_MODULE) || \
 	 defined(CONFIG_FB_VESA))
 	PPC_DEVICE *vgadev = NULL;
 
@@ -1126,7 +1126,7 @@
 		_prep_type = _PREP_Motorola;
 	}
 
-#ifdef CONFIG_PREP_PRESIDUAL
+#ifdef CONFIG_PREP_RESIDUAL
 	/* Switch off all residual data processing if the user requests it */
 	if (strstr(cmd_line, "noresidual") != NULL)
 			res = NULL;
diff -Nru a/arch/ppc/platforms/sbc82xx.c b/arch/ppc/platforms/sbc82xx.c
--- a/arch/ppc/platforms/sbc82xx.c	2005-03-01 23:38:54 -08:00
+++ b/arch/ppc/platforms/sbc82xx.c	2005-03-01 23:38:54 -08:00
@@ -68,7 +68,7 @@
 
 static volatile char *sbc82xx_i8259_map;
 static char sbc82xx_i8259_mask = 0xff;
-static spinlock_t sbc82xx_i8259_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(sbc82xx_i8259_lock);
 
 static void sbc82xx_i8259_mask_and_ack_irq(unsigned int irq_nr)
 {
diff -Nru a/arch/ppc/syslib/Makefile b/arch/ppc/syslib/Makefile
--- a/arch/ppc/syslib/Makefile	2005-03-01 23:38:52 -08:00
+++ b/arch/ppc/syslib/Makefile	2005-03-01 23:38:52 -08:00
@@ -13,12 +13,17 @@
 obj-$(CONFIG_44x)		+= ibm44x_common.o
 obj-$(CONFIG_440GP)		+= ibm440gp_common.o
 obj-$(CONFIG_440GX)		+= ibm440gx_common.o
+obj-$(CONFIG_440SP)		+= ibm440gx_common.o ibm440sp_common.o
 ifeq ($(CONFIG_4xx),y)
 ifeq ($(CONFIG_VIRTEX_II_PRO),y)
 obj-$(CONFIG_40x)		+= xilinx_pic.o
 else
+ifeq ($(CONFIG_403),y)
+obj-$(CONFIG_40x)		+= ppc403_pic.o
+else
 obj-$(CONFIG_40x)		+= ppc4xx_pic.o
 endif
+endif
 obj-$(CONFIG_44x)		+= ppc4xx_pic.o
 obj-$(CONFIG_40x)		+= ppc4xx_setup.o
 obj-$(CONFIG_GEN_RTC)		+= todc_time.o
@@ -39,17 +44,23 @@
 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_CPCI690)		+= todc_time.o pci_auto.o
 obj-$(CONFIG_EBONY)		+= indirect_pci.o pci_auto.o todc_time.o
-obj-$(CONFIG_EV64260)		+= gt64260_common.o gt64260_pic.o \
-					indirect_pci.o todc_time.o pci_auto.o
+obj-$(CONFIG_EV64260)		+= todc_time.o pci_auto.o
+obj-$(CONFIG_CHESTNUT)		+= mv64360_pic.o pci_auto.o
 obj-$(CONFIG_GEMINI)		+= open_pic.o indirect_pci.o
+obj-$(CONFIG_GT64260)		+= gt64260_pic.o
 obj-$(CONFIG_K2)		+= i8259.o indirect_pci.o todc_time.o \
 					pci_auto.o
 obj-$(CONFIG_LOPEC)		+= i8259.o pci_auto.o todc_time.o
+obj-$(CONFIG_LUAN)		+= indirect_pci.o pci_auto.o todc_time.o
+obj-$(CONFIG_KATANA)		+= pci_auto.o
 obj-$(CONFIG_MCPN765)		+= todc_time.o indirect_pci.o pci_auto.o \
 					open_pic.o i8259.o hawk_common.o
 obj-$(CONFIG_MENF1)		+= todc_time.o i8259.o mpc10x_common.o \
 					pci_auto.o indirect_pci.o
+obj-$(CONFIG_MV64360)		+= mv64360_pic.o
+obj-$(CONFIG_MV64X60)		+= mv64x60.o mv64x60_win.o indirect_pci.o
 obj-$(CONFIG_MVME5100)		+= open_pic.o todc_time.o indirect_pci.o \
 					pci_auto.o hawk_common.o
 obj-$(CONFIG_MVME5100_IPMC761_PRESENT)	+= i8259.o
@@ -75,12 +86,16 @@
 obj-$(CONFIG_KGDB)		+= gen550_kgdb.o gen550_dbg.o
 obj-$(CONFIG_SERIAL_TEXT_DEBUG)	+= gen550_dbg.o
 endif
+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_OPENPIC)	+= open_pic.o
 obj-$(CONFIG_40x)		+= dcr.o
 obj-$(CONFIG_BOOKE)		+= dcr.o
-obj-$(CONFIG_85xx)		+= open_pic.o ppc85xx_common.o ppc85xx_setup.o
+obj-$(CONFIG_85xx)		+= open_pic.o ppc85xx_common.o ppc85xx_setup.o \
+					ppc_sys.o
 ifeq ($(CONFIG_85xx),y)
 obj-$(CONFIG_PCI)		+= indirect_pci.o pci_auto.o
 endif
diff -Nru a/arch/ppc/syslib/gen550_dbg.c b/arch/ppc/syslib/gen550_dbg.c
--- a/arch/ppc/syslib/gen550_dbg.c	2005-03-01 23:38:56 -08:00
+++ b/arch/ppc/syslib/gen550_dbg.c	2005-03-01 23:38:56 -08:00
@@ -29,6 +29,11 @@
 
 #define SERIAL_BAUD	9600
 
+/* SERIAL_PORT_DFNS is defined in <asm/serial.h> */
+#ifndef SERIAL_PORT_DFNS
+#define SERIAL_PORT_DFNS
+#endif
+
 static struct serial_state rs_table[RS_TABLE_SIZE] = {
 	SERIAL_PORT_DFNS	/* defined in <asm/serial.h> */
 };
@@ -154,6 +159,7 @@
 	rs_table[i].port = serial_req->iobase;
 	rs_table[i].iomem_base = serial_req->membase;
 	rs_table[i].iomem_reg_shift = serial_req->regshift;
+	rs_table[i].baud_base = serial_req->uartclk ? serial_req->uartclk / 16 : BASE_BAUD;
 }
 
 #ifdef CONFIG_SERIAL_TEXT_DEBUG
diff -Nru a/arch/ppc/syslib/gt64260_common.c b/arch/ppc/syslib/gt64260_common.c
--- a/arch/ppc/syslib/gt64260_common.c	2005-03-01 23:39:18 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,1664 +0,0 @@
-/*
- * arch/ppc/syslib/gt64260_common.c
- *
- * Common routines for the Marvell/Galileo GT64260 (Discovery) host bridge,
- * interrupt controller, memory controller, serial controller, enet controller,
- * etc.
- *
- * Author: Mark A. Greer <mgreer@mvista.com>
- *
- * 2001 (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.
- */
-
-/*
- * The GT64260 port is the result of hard work from many people from
- * many companies.  In particular, employees of Marvell/Galileo, Mission
- * Critical Linux, Xyterra, and MontaVista Software were heavily involved.
- */
-
-/*
- * At last count, the 64260-B-0 has 65 errata and 24 restrictions.  The odds of
- * you getting it to work well, under stress, for a long period of time are
- * low.  If nothing else, you will likely run into an interrupt controller
- * bug.
- *
- * The newer 64260A-B-0 is much improved but has its own problems.
- * Dave Wilhardt <dwilhardt@zyterra.com> has discovered that you must set
- * up your PCI snoop regions to be prefetchable with 4-word bursts AND set the
- * "Memory Write and Invalidate bit" (bit 4) in the cmd reg of each PCI device
- * before coherency works between PCI and other devices.  Many thanks to Dave.
- *
- * So far this code has been tested on Marvell/Galileo EV-64260-BP and
- * an EV-64260A-BP uni-processor boards with 750 and 7400 processors.
- * It has not yet been tested with a 7410 or 7450, or on an smp system.
- *
- * Note: I have not had any luck moving the base register address of the bridge
- * 	 with the gt64260_set_base() routine.  I move it in the bootloader
- * 	 before starting the kernel.  I haven't really looked into it so it
- * 	 may be an easy fix. -- MAG
- */
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-
-#include <asm/byteorder.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/uaccess.h>
-#include <asm/machdep.h>
-#include <asm/pci-bridge.h>
-#include <asm/gt64260.h>
-#include <asm/delay.h>
-
-
-u32	gt64260_base; /* Virtual base address of 64260's regs */
-u32	gt64260_revision; /* Revision of the chip */
-u8	gt64260_pci_exclude_bridge = TRUE;
-
-
-/*
- *****************************************************************************
- *
- *	Bridge Initialization Routines
- *
- *****************************************************************************
- */
-static void gt64260_check_errata(struct pci_controller *hose_a,
-				 struct pci_controller *hose_b);
-
-/*
- * Typical '_find_bridges()' routine for boards with a GT64260 bridge.
- */
-int __init
-gt64260_find_bridges(u32 phys_base_addr, gt64260_bridge_info_t *info,
-	int ((*map_irq)(struct pci_dev *, unsigned char, unsigned char)))
-{
-	struct pci_controller		*hose_a, *hose_b;
-	u32				io_base_a, io_base_b;
-	int				rc;
-
-
-	gt64260_base = (u32)ioremap(phys_base_addr,GT64260_INTERNAL_SPACE_SIZE);
-
-	hose_a = pcibios_alloc_controller();
-	if (!hose_a)
-		return -1;
-
-	hose_b = pcibios_alloc_controller();
-	if (!hose_b)
-		return -1;
-
-	info->hose_a = hose_a;
-	info->hose_b = hose_b;
-
-	/* Ends up mapping PCI Config addr/data pairs twice */
-	setup_indirect_pci(hose_a,
-			   phys_base_addr + GT64260_PCI_0_CONFIG_ADDR,
-			   phys_base_addr + GT64260_PCI_0_CONFIG_DATA);
-
-	setup_indirect_pci(hose_b,
-			   phys_base_addr + GT64260_PCI_1_CONFIG_ADDR,
-			   phys_base_addr + GT64260_PCI_1_CONFIG_DATA);
-
-	if ((rc = gt64260_bridge_init(info)) != 0) {
-		iounmap((void *)hose_a->cfg_addr);
-		iounmap((void *)hose_a->cfg_data);
-		iounmap((void *)hose_b->cfg_addr);
-		iounmap((void *)hose_b->cfg_data);
-		iounmap((void *)gt64260_base);
-		return rc;
-	}
-
-	/* ioremap PCI I/O regions */
-	io_base_b = (u32)ioremap(info->pci_1_io_start_proc,info->pci_1_io_size);
-	io_base_a = (u32)ioremap(info->pci_0_io_start_proc,info->pci_0_io_size);
-	isa_io_base = io_base_a;
-
-	hose_a->first_busno = 0;
-	hose_a->last_busno  = 0xff;
-
-	pci_init_resource(&hose_a->io_resource,
-			  0,	/* really: io_base_a - isa_io_base */
-			  info->pci_0_io_size - 1,
-			  IORESOURCE_IO,
-			  "host bridge PCI bus 0");
-	hose_a->io_space.start = info->pci_0_io_start_pci;
-	hose_a->io_space.end   = info->pci_0_io_start_pci +
-					info->pci_0_io_size - 1;
-	hose_a->io_base_virt = (void *)isa_io_base;
-
-	pci_init_resource(&hose_a->mem_resources[0],
-			  info->pci_0_mem_start_proc,
-			  info->pci_0_mem_start_proc + info->pci_0_mem_size - 1,
-			  IORESOURCE_MEM,
-			  "host bridge PCI bus 0");
-	hose_a->mem_space.start = info->pci_0_mem_start_pci_lo;
-	hose_a->mem_space.end   = info->pci_0_mem_start_pci_lo +
-					info->pci_0_mem_size - 1;
-	hose_a->pci_mem_offset = (info->pci_0_mem_start_proc -
-					info->pci_0_mem_start_pci_lo);
-
-	hose_a->last_busno = pciauto_bus_scan(hose_a, hose_a->first_busno);
-
-
-	hose_b->first_busno = hose_a->last_busno + 1;
-	hose_b->bus_offset  = hose_b->first_busno;
-	hose_b->last_busno  = 0xff;
-
-	pci_init_resource(&hose_b->io_resource,
-			  io_base_b - isa_io_base,
-			  io_base_b - isa_io_base + info->pci_1_io_size - 1,
-			  IORESOURCE_IO,
-			  "host bridge PCI bus 1");
-	hose_b->io_space.start = info->pci_1_io_start_pci;
-	hose_b->io_space.end   = info->pci_1_io_start_pci +
-					info->pci_1_io_size - 1;
-	hose_b->io_base_virt = (void *)isa_io_base;
-
-	pci_init_resource(&hose_b->mem_resources[0],
-			  info->pci_1_mem_start_proc,
-			  info->pci_1_mem_start_proc + info->pci_1_mem_size - 1,
-			  IORESOURCE_MEM,
-			  "host bridge PCI bus 1");
-	hose_b->mem_space.start = info->pci_1_mem_start_pci_lo;
-	hose_b->mem_space.end   = info->pci_1_mem_start_pci_lo +
-					info->pci_1_mem_size - 1;
-	hose_b->pci_mem_offset = (info->pci_1_mem_start_proc -
-					info->pci_1_mem_start_pci_lo);
-
-	hose_b->last_busno = pciauto_bus_scan(hose_b, hose_b->first_busno);
-
-
-	ppc_md.pci_exclude_device = gt64260_pci_exclude_device;
-	ppc_md.pci_swizzle        = common_swizzle;
-	ppc_md.pci_map_irq        = map_irq;
-
-	return 0;
-} /* gt64260_find_bridges() */
-
-/*
- * gt64260_bridge_init()
- *
- * Perform bridge initialization for a "typical" setup for a PPC system.
- */
-int __init
-gt64260_bridge_init(gt64260_bridge_info_t *info)
-{
-	int	window;
-	u16	u16_val;
-	u32	u32_val;
-	int	rc = 0;
-	u8	save_exclude;
-
-	/*
-	 * Count on firmware to set/clear other bits in this register.
-	 *
-	 * Set CPU CONFIG Reg bit:
-	 *	bit 13 - Pipeline
-	 *	bit 16 - RdOOO
-	 *
-	 * Clear CPU Config Reg bit:
-	 * 	bit 12 - endianess
-	 *	bit 27 - RemapWrDis
-	 */
-	u32_val = gt_read(GT64260_CPU_CONFIG);
-	u32_val |= ((1<<13) | (1<<16));
-	u32_val &= ~((1<<8) | (1<<12) | (1<<27));
-	gt_write(GT64260_CPU_CONFIG, u32_val);
-
-	/* PCI 0/1 Timeout and Retry limits */
-	u32_val = gt_read(GT64260_PCI_0_TO_RETRY);
-	u32_val |= 0x0000ffff;
-	gt_write(GT64260_PCI_0_TO_RETRY, u32_val);
-
-	u32_val = gt_read(GT64260_PCI_1_TO_RETRY);
-	u32_val |= 0x0000ffff;
-	gt_write(GT64260_PCI_1_TO_RETRY, u32_val);
-
-	save_exclude = gt64260_pci_exclude_bridge;
-	gt64260_pci_exclude_bridge = FALSE;
-
-	/* Set class code to indicate host bridge */
-	early_read_config_dword(info->hose_a,
-			        info->hose_a->first_busno,
-			        PCI_DEVFN(0,0),
-			        PCI_CLASS_REVISION,
-			        &u32_val);
-	u32_val &= 0x000000ff;
-	gt64260_revision = u32_val;	/* a 64260 or 64260A? */
-	u32_val |= (PCI_CLASS_BRIDGE_HOST << 16);
-	early_write_config_dword(info->hose_a,
-				 info->hose_a->first_busno,
-				 PCI_DEVFN(0,0),
-				 PCI_CLASS_REVISION,
-				 u32_val);
-
-	early_read_config_dword(info->hose_b,
-			        info->hose_b->first_busno,
-			        PCI_DEVFN(0,0),
-			        PCI_CLASS_REVISION,
-			        &u32_val);
-	u32_val &= 0x000000ff;
-	u32_val |= (PCI_CLASS_BRIDGE_HOST << 16);
-	early_write_config_dword(info->hose_b,
-				 info->hose_b->first_busno,
-				 PCI_DEVFN(0,0),
-				 PCI_CLASS_REVISION,
-				 u32_val);
-
-	/* Enable 64260 to be PCI master & respond to PCI MEM cycles */
-	early_read_config_word(info->hose_a,
-			       info->hose_a->first_busno,
-			       PCI_DEVFN(0,0),
-			       PCI_COMMAND,
-			       &u16_val);
-	u16_val |= (PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
-	early_write_config_word(info->hose_a,
-				info->hose_a->first_busno,
-				PCI_DEVFN(0,0),
-				PCI_COMMAND,
-				u16_val);
-
-	early_read_config_word(info->hose_b,
-			       info->hose_b->first_busno,
-			       PCI_DEVFN(0,0),
-			       PCI_COMMAND,
-			       &u16_val);
-	u16_val |= (PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
-	early_write_config_word(info->hose_b,
-				info->hose_b->first_busno,
-				PCI_DEVFN(0,0),
-				PCI_COMMAND,
-				u16_val);
-
-	gt64260_pci_exclude_bridge = save_exclude;
-
-	/*
-	 * Disable all CPU windows on the bridge except for SCS 0 which
-	 * is covering all of system memory.:
-	 */
-	gt64260_cpu_disable_all_windows();
-
-	/*
-	 * Set CPU snoop window to indicate all of system memory
-	 * is covered with wirte-back cache.
-	 */
-	gt64260_cpu_snoop_set_window(0,
-				     0x00000000,
-				     info->mem_size,
-				     GT64260_CPU_SNOOP_WB);
-
-	/*
-	 * Set up CPU->PCI mappings (so CPU can get at PCI dev regs/mem).
-	 * Will only use one of the four CPU->PCI MEM windows on each bus.
-	 */
-	gt64260_cpu_set_pci_io_window(0,
-				      info->pci_0_io_start_proc,
-				      info->pci_0_io_start_pci,
-				      info->pci_0_io_size,
-				      info->pci_0_io_swap);
-
-	gt64260_cpu_set_pci_mem_window(0,
-				       0,
-				       info->pci_0_mem_start_proc,
-				       info->pci_0_mem_start_pci_hi,
-				       info->pci_0_mem_start_pci_lo,
-				       info->pci_0_mem_size,
-				       info->pci_0_mem_swap);
-
-	gt64260_cpu_set_pci_io_window(1,
-				      info->pci_1_io_start_proc,
-				      info->pci_1_io_start_pci,
-				      info->pci_1_io_size,
-				      info->pci_1_io_swap);
-
-	gt64260_cpu_set_pci_mem_window(1,
-				       0,
-				       info->pci_1_mem_start_proc,
-				       info->pci_1_mem_start_pci_hi,
-				       info->pci_1_mem_start_pci_lo,
-				       info->pci_1_mem_size,
-				       info->pci_1_mem_swap);
-
-	/*
-	 * Set up PCI MEM->system memory mapping (bridge slave PCI window).
-	 *
-	 * Set BAR enables to allow only the SCS0 slave window to respond
-	 * to PCI read/write cycles.
-	 */
-	gt64260_pci_bar_enable(0, GT64260_PCI_SLAVE_BAR_REG_ENABLES_SCS_0);
-	gt64260_pci_bar_enable(1, GT64260_PCI_SLAVE_BAR_REG_ENABLES_SCS_0);
-
-	/*
-	 * For virt_to_bus & bus_to_virt to work correctly, this mapping
-	 * must be the same on both PCI buses.
-	 */
-	gt64260_pci_slave_scs_set_window(info->hose_a,
-					 0,
-					 0x00000000,
-					 0x00000000,
-					 info->mem_size);
-
-	gt64260_pci_slave_scs_set_window(info->hose_b,
-					 0,
-					 0x00000000,
-					 0x00000000,
-					 info->mem_size);
-	pci_dram_offset = 0; /* System mem at same addr on PCI & cpu bus */
-
-	/* Disable all the access control windows */
-	for (window=0; window<GT64260_PCI_ACC_CNTL_WINDOWS; window++) {
-		gt64260_pci_acc_cntl_set_window(0, window, 0, 0, 0, 0);
-		gt64260_pci_acc_cntl_set_window(1, window, 0, 0, 0, 0);
-	}
-
-	/* Disable all the PCI snoop regions */
-	for (window=0; window<GT64260_PCI_SNOOP_WINDOWS; window++) {
-		gt64260_pci_snoop_set_window(0, window, 0, 0, 0, 0);
-		gt64260_pci_snoop_set_window(1, window, 0, 0, 0, 0);
-	}
-
-	gt64260_pci_acc_cntl_set_window(0,
-					0,
-					0x00000000,
-					0x00000000,
-					info->mem_size,
-					(GT64260_PCI_ACC_CNTL_PREFETCHEN |
-					 GT64260_PCI_ACC_CNTL_MBURST_4_WORDS |
-					 GT64260_PCI_ACC_CNTL_SWAP_BYTE));
-
-	gt64260_pci_acc_cntl_set_window(1,
-					0,
-					0x00000000,
-					0x00000000,
-					info->mem_size,
-					(GT64260_PCI_ACC_CNTL_PREFETCHEN |
-					 GT64260_PCI_ACC_CNTL_MBURST_4_WORDS |
-					 GT64260_PCI_ACC_CNTL_SWAP_BYTE));
-
-	gt64260_pci_snoop_set_window(0,
-				     0,
-				     0x00000000,
-				     0x00000000,
-				     info->mem_size,
-				     GT64260_PCI_SNOOP_WB);
-				
-	gt64260_pci_snoop_set_window(1,
-				     0,
-				     0x00000000,
-				     0x00000000,
-				     info->mem_size,
-				     GT64260_PCI_SNOOP_WB);
-
-	gt64260_check_errata(info->hose_a, info->hose_b);
-
-
-	/* Set latency timer (to 64) & cacheline size; clear BIST */
-	gt64260_pci_exclude_bridge = FALSE;
-	u32_val = ((0x04 << 8) | (L1_CACHE_LINE_SIZE / 4));
-
-	early_write_config_dword(info->hose_a,
-				 info->hose_a->first_busno,
-				 PCI_DEVFN(0,0),
-				 PCI_CACHE_LINE_SIZE,
-				 u32_val);
-	early_write_config_dword(info->hose_b,
-				 info->hose_b->first_busno,
-				 PCI_DEVFN(0,0),
-				 PCI_CACHE_LINE_SIZE,
-				 u32_val);
-	gt64260_pci_exclude_bridge = TRUE;
-
-	return rc;
-} /* gt64260_bridge_init() */
-
-/*
- * gt64260_check_errata()
- *
- * Apply applicable errata and restrictions from 0.5 of the
- * Errata and Restrictions document from Marvell/Galileo.
- */
-static void __init
-gt64260_check_errata(struct pci_controller *hose_a,
-		     struct pci_controller *hose_b)
-{
-	u32	val;
-	u8	save_exclude;
-
-	/* Currently 2 versions, 64260 and 64260A */
-	if (gt64260_revision == GT64260) {
-		save_exclude = gt64260_pci_exclude_bridge;
-		gt64260_pci_exclude_bridge = FALSE;
-
-		/* FEr#5, FEr#12 */
-		early_read_config_dword(hose_a,
-					hose_a->first_busno,
-					PCI_DEVFN(0,0),
-					PCI_COMMAND,
-					&val);
-		val &= ~(PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY);
-		early_write_config_dword(hose_a,
-					 hose_a->first_busno,
-					 PCI_DEVFN(0,0),
-					 PCI_COMMAND,
-					 val);
-
-		early_read_config_dword(hose_b,
-					hose_b->first_busno,
-					PCI_DEVFN(0,0),
-					PCI_COMMAND,
-					&val);
-		val &= ~(PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY);
-		early_write_config_dword(hose_b,
-					 hose_b->first_busno,
-					 PCI_DEVFN(0,0),
-					 PCI_COMMAND,
-					 val);
-		gt64260_pci_exclude_bridge = save_exclude;
-
-		/* FEr#12, FEr#13 */
-		gt_clr_bits(GT64260_PCI_0_CMD, ((1<<4) | (1<<5) | (1<<9)));
-		gt_clr_bits(GT64260_PCI_1_CMD, ((1<<4) | (1<<5) | (1<<9)));
-
-		/* FEr#54 */
-		gt_clr_bits(GT64260_CPU_SNOOP_BASE_0, 0xfffcf000);
-		gt_clr_bits(GT64260_CPU_SNOOP_BASE_1, 0xfffcf000);
-		gt_clr_bits(GT64260_CPU_SNOOP_BASE_2, 0xfffcf000);
-		gt_clr_bits(GT64260_CPU_SNOOP_BASE_3, 0xfffcf000);
-
-		/* R#18 */
-		gt_set_bits(GT64260_SDRAM_CONFIG, (1<<26));
-
-	} else if (gt64260_revision == GT64260A) {
-		/* R#18 */
-		gt_set_bits(GT64260_SDRAM_CONFIG, (1<<26));
-
-		/* No longer errata so turn on */
-		gt_set_bits(GT64260_PCI_0_CMD, ((1<<4) | (1<<5) | (1<<9)));
-		gt_set_bits(GT64260_PCI_1_CMD, ((1<<4) | (1<<5) | (1<<9)));
-	}
-} /* gt64260_check_errata() */
-
-
-/*
- *****************************************************************************
- *
- *	General Window Setting Routines
- *
- *****************************************************************************
- */
-
-static int
-gt64260_set_32bit_window(u32 base_addr,
-			 u32 size,
-			 u32 other_bits,
-			 u32 bot_reg,
-			 u32 top_reg)
-{
-	u32	val;
-
-	if (size > 0) {
-		/* Set up the window on the CPU side */
-		gt_write(bot_reg, (base_addr >> 20) | other_bits);
-		gt_write(top_reg, (base_addr + size - 1) >> 20);
-	} else { /* Disable window */
-		gt_write(top_reg, 0x00000000);
-		gt_write(bot_reg, 0x00000fff | other_bits);
-	}
-
-	val = gt_read(bot_reg); /* Flush FIFO */
-	return 0;
-} /* gt64260_set_32bit_window() */
-
-static int
-gt64260_set_64bit_window(u32 base_addr_hi,
-			 u32 base_addr_lo,
-			 u32 size,
-			 u32 other_bits,
-			 u32 bot_reg_hi,
-			 u32 bot_reg_lo,
-			 u32 top_reg)
-{
-	int	rc;
-
-	if ((rc = gt64260_set_32bit_window(base_addr_lo,
-					   size,
-					   other_bits,
-					   bot_reg_lo,
-					   top_reg)) == 0) {
-
-		gt_write(bot_reg_hi, base_addr_hi);
-		base_addr_hi = gt_read(bot_reg_hi); /* Flush FIFO */
-	}
-
-	return rc;
-} /* gt64260_set_64bit_window() */
-
-
-/*
- *****************************************************************************
- *
- *	CPU Configuration Routines
- *
- *****************************************************************************
- */
-
-int
-gt64260_cpu_scs_set_window(u32 window,
-			   u32 base_addr,
-			   u32 size)
-{
-	static u32
-	cpu_scs_windows[GT64260_CPU_SCS_DECODE_WINDOWS][2] = {
-		{ GT64260_CPU_SCS_DECODE_0_BOT, GT64260_CPU_SCS_DECODE_0_TOP },
-		{ GT64260_CPU_SCS_DECODE_1_BOT, GT64260_CPU_SCS_DECODE_1_TOP },
-		{ GT64260_CPU_SCS_DECODE_2_BOT, GT64260_CPU_SCS_DECODE_2_TOP },
-		{ GT64260_CPU_SCS_DECODE_3_BOT, GT64260_CPU_SCS_DECODE_3_TOP },
-	}; /* cpu_scs_windows[][] */
-	int	rc = -1;
-
-	if (window < GT64260_CPU_SCS_DECODE_WINDOWS) {
-		rc = gt64260_set_32bit_window(base_addr,
-					      size,
-					      0,
-					      cpu_scs_windows[window][0],
-					      cpu_scs_windows[window][1]);
-	}
-
-	return rc;
-} /* gt64260_cpu_scs_set_window() */
-
-int
-gt64260_cpu_cs_set_window(u32 window,
-			  u32 base_addr,
-			  u32 size)
-{
-	static u32
-	cpu_cs_windows[GT64260_CPU_CS_DECODE_WINDOWS][2] = {
-		{ GT64260_CPU_CS_DECODE_0_BOT, GT64260_CPU_CS_DECODE_0_TOP },
-		{ GT64260_CPU_CS_DECODE_1_BOT, GT64260_CPU_CS_DECODE_1_TOP },
-		{ GT64260_CPU_CS_DECODE_2_BOT, GT64260_CPU_CS_DECODE_2_TOP },
-		{ GT64260_CPU_CS_DECODE_3_BOT, GT64260_CPU_CS_DECODE_3_TOP },
-	}; /* cpu_cs_windows[][] */
-	int	rc = -1;
-
-	if (window < GT64260_CPU_CS_DECODE_WINDOWS) {
-		rc = gt64260_set_32bit_window(base_addr,
-					      size,
-					      0,
-					      cpu_cs_windows[window][0],
-					      cpu_cs_windows[window][1]);
-	}
-
-	return rc;
-} /* gt64260_cpu_cs_set_window() */
-
-int
-gt64260_cpu_boot_set_window(u32 base_addr,
-			    u32 size)
-{
-	int	rc;
-
-	rc = gt64260_set_32bit_window(base_addr,
-				      size,
-				      0,
-				      GT64260_CPU_BOOT_CS_DECODE_0_BOT,
-				      GT64260_CPU_BOOT_CS_DECODE_0_TOP);
-
-	return rc;
-} /* gt64260_cpu_boot_set_window() */
-
-/*
- * gt64260_cpu_set_pci_io_window()
- *
- * Set up a CPU window into PCI I/O or MEM space.
- * Always do Read/Modify/Write to window regs.
- */
-static int
-gt64260_cpu_pci_set_window(u32 cpu_base_addr,
-			   u32 pci_base_addr,
-			   u32 size,
-			   u32 other_bits,
-			   u32 bot_reg,
-			   u32 top_reg,
-			   u32 remap_reg)
-{
-	u32	val;
-	int	rc;
-
-	if ((rc = gt64260_set_32bit_window(cpu_base_addr,
-					   size,
-					   other_bits,
-					   bot_reg,
-					   top_reg)) == 0) {
-
-		/* Set up CPU->PCI remapping (on lower 32 bits) */
-		gt_write(remap_reg, pci_base_addr >> 20);
-		val = gt_read(bot_reg); /* Flush FIFO */
-	}
-
-	return rc;
-} /* gt64260_cpu_pci_set_window() */
-
-
-/*
- * gt64260_cpu_set_pci_io_window()
- *
- * Set up a CPU window into PCI I/O space.
- * Always do Read/Modify/Write to window regs.
- */
-int
-gt64260_cpu_set_pci_io_window(u32 pci_bus,
-			      u32 cpu_base_addr,
-			      u32 pci_base_addr,
-			      u32 size,
-			      u32 swap)
-{
-	/* 2 PCI buses with 1 I/O window each (from CPU point of view) */
-	static u32
-	cpu_pci_io_windows[GT64260_PCI_BUSES][3] = {
-		{ GT64260_CPU_PCI_0_IO_DECODE_BOT,
-		  GT64260_CPU_PCI_0_IO_DECODE_TOP,
-		  GT64260_CPU_PCI_0_IO_REMAP },
-
-		{ GT64260_CPU_PCI_1_IO_DECODE_BOT,
-		  GT64260_CPU_PCI_1_IO_DECODE_TOP,
-		  GT64260_CPU_PCI_1_IO_REMAP },
-	}; /* cpu_pci_io_windows[][] */
-	int	rc = -1;
-
-	if (pci_bus < GT64260_PCI_BUSES) {
-		rc =  gt64260_cpu_pci_set_window(cpu_base_addr,
-					  pci_base_addr,
-					  size,
-					  swap,
-					  cpu_pci_io_windows[pci_bus][0],
-					  cpu_pci_io_windows[pci_bus][1],
-					  cpu_pci_io_windows[pci_bus][2]);
-	}
-
-	return rc;
-} /* gt64260_cpu_set_pci_io_window() */
-
-/*
- * gt64260_cpu_set_pci_mem_window()
- *
- * Set up a CPU window into PCI MEM space (4 PCI MEM windows per PCI bus).
- * Always do Read/Modify/Write to window regs.
- */
-int
-gt64260_cpu_set_pci_mem_window(u32 pci_bus,
-			       u32 window,
-			       u32 cpu_base_addr,
-			       u32 pci_base_addr_hi,
-			       u32 pci_base_addr_lo,
-			       u32 size,
-			       u32 swap_64bit)
-{
-	/* 2 PCI buses with 4 memory windows each (from CPU point of view) */
-	static u32
-	cpu_pci_mem_windows[GT64260_PCI_BUSES][GT64260_PCI_MEM_WINDOWS_PER_BUS][4] = {
-		{ /* PCI 0 */
-			{ GT64260_CPU_PCI_0_MEM_0_DECODE_BOT,
-			  GT64260_CPU_PCI_0_MEM_0_DECODE_TOP,
-			  GT64260_CPU_PCI_0_MEM_0_REMAP_HI,
-			  GT64260_CPU_PCI_0_MEM_0_REMAP_LO },
-
-			{ GT64260_CPU_PCI_0_MEM_1_DECODE_BOT,
-			  GT64260_CPU_PCI_0_MEM_1_DECODE_TOP,
-			  GT64260_CPU_PCI_0_MEM_1_REMAP_HI,
-			  GT64260_CPU_PCI_0_MEM_1_REMAP_LO },
-
-			{ GT64260_CPU_PCI_0_MEM_2_DECODE_BOT,
-			  GT64260_CPU_PCI_0_MEM_2_DECODE_TOP,
-			  GT64260_CPU_PCI_0_MEM_2_REMAP_HI,
-			  GT64260_CPU_PCI_0_MEM_2_REMAP_LO },
-
-			{ GT64260_CPU_PCI_0_MEM_3_DECODE_BOT,
-			  GT64260_CPU_PCI_0_MEM_3_DECODE_TOP,
-			  GT64260_CPU_PCI_0_MEM_3_REMAP_HI,
-			  GT64260_CPU_PCI_0_MEM_3_REMAP_LO }
-		},
-
-		{ /* PCI 1 */
-			{ GT64260_CPU_PCI_1_MEM_0_DECODE_BOT,
-			  GT64260_CPU_PCI_1_MEM_0_DECODE_TOP,
-			  GT64260_CPU_PCI_1_MEM_0_REMAP_HI,
-			  GT64260_CPU_PCI_1_MEM_0_REMAP_LO },
-
-			{ GT64260_CPU_PCI_1_MEM_1_DECODE_BOT,
-			  GT64260_CPU_PCI_1_MEM_1_DECODE_TOP,
-			  GT64260_CPU_PCI_1_MEM_1_REMAP_HI,
-			  GT64260_CPU_PCI_1_MEM_1_REMAP_LO },
-
-			{ GT64260_CPU_PCI_1_MEM_2_DECODE_BOT,
-			  GT64260_CPU_PCI_1_MEM_2_DECODE_TOP,
-			  GT64260_CPU_PCI_1_MEM_2_REMAP_HI,
-			  GT64260_CPU_PCI_1_MEM_2_REMAP_LO },
-
-			{ GT64260_CPU_PCI_1_MEM_3_DECODE_BOT,
-			  GT64260_CPU_PCI_1_MEM_3_DECODE_TOP,
-			  GT64260_CPU_PCI_1_MEM_3_REMAP_HI,
-			  GT64260_CPU_PCI_1_MEM_3_REMAP_LO },
-		}
-	}; /* cpu_pci_mem_windows[][][] */
-	u32		remap_reg, remap;
-	int		rc = -1;
-
-	if ((pci_bus < GT64260_PCI_BUSES) &&
-	    (window < GT64260_PCI_MEM_WINDOWS_PER_BUS)) {
-
-		if (gt64260_cpu_pci_set_window(
-			cpu_base_addr,
-			pci_base_addr_lo,
-			size,
-			swap_64bit,
-			cpu_pci_mem_windows[pci_bus][window][0],
-			cpu_pci_mem_windows[pci_bus][window][1],
-			cpu_pci_mem_windows[pci_bus][window][3]) == 0) {
-
-			remap_reg = cpu_pci_mem_windows[pci_bus][window][2];
-			gt_write(remap_reg, pci_base_addr_hi);
-
-			remap = gt_read(remap_reg); /* Flush FIFO */
-
-			rc = 0;
-		}
-	}
-
-	return rc;
-} /* gt64260_cpu_set_pci_mem_window() */
-
-int
-gt64260_cpu_prot_set_window(u32 window,
-			    u32 base_addr,
-			    u32 size,
-			    u32 access_bits)
-{
-	static u32
-	cpu_prot_windows[GT64260_CPU_PROT_WINDOWS][2] = {
-		{ GT64260_CPU_PROT_BASE_0, GT64260_CPU_PROT_TOP_0 },
-		{ GT64260_CPU_PROT_BASE_1, GT64260_CPU_PROT_TOP_1 },
-		{ GT64260_CPU_PROT_BASE_2, GT64260_CPU_PROT_TOP_2 },
-		{ GT64260_CPU_PROT_BASE_3, GT64260_CPU_PROT_TOP_3 },
-		{ GT64260_CPU_PROT_BASE_4, GT64260_CPU_PROT_TOP_4 },
-		{ GT64260_CPU_PROT_BASE_5, GT64260_CPU_PROT_TOP_5 },
-		{ GT64260_CPU_PROT_BASE_6, GT64260_CPU_PROT_TOP_6 },
-		{ GT64260_CPU_PROT_BASE_7, GT64260_CPU_PROT_TOP_7 },
-	}; /* cpu_prot_windows[][] */
-	int	rc = -1;
-
-	if (window < GT64260_CPU_PROT_WINDOWS) {
-		rc = gt64260_set_32bit_window(base_addr,
-					      size,
-					      access_bits,
-					      cpu_prot_windows[window][0],
-					      cpu_prot_windows[window][1]);
-	}
-
-	return rc;
-} /* gt64260_cpu_prot_set_window() */
-
-int
-gt64260_cpu_snoop_set_window(u32 window,
-			     u32 base_addr,
-			     u32 size,
-			     u32  snoop_type)
-{
-	static u32
-	cpu_snoop_windows[GT64260_CPU_SNOOP_WINDOWS][2] = {
-		{ GT64260_CPU_SNOOP_BASE_0, GT64260_CPU_SNOOP_TOP_0 },
-		{ GT64260_CPU_SNOOP_BASE_1, GT64260_CPU_SNOOP_TOP_1 },
-		{ GT64260_CPU_SNOOP_BASE_2, GT64260_CPU_SNOOP_TOP_2 },
-		{ GT64260_CPU_SNOOP_BASE_3, GT64260_CPU_SNOOP_TOP_3 },
-	}; /* cpu_snoop_windows[][] */
-	int	rc = -1;
-
-	if ((window < GT64260_CPU_SNOOP_WINDOWS) &&
-	    (snoop_type <= GT64260_CPU_SNOOP_WB)) {
-
-		rc = gt64260_set_32bit_window(base_addr,
-					      size,
-					      snoop_type,
-					      cpu_snoop_windows[window][0],
-					      cpu_snoop_windows[window][1]);
-	}
-
-	return rc;
-} /* gt64260_cpu_snoop_set_window() */
-
-void
-gt64260_cpu_disable_all_windows(void)
-{
-	int	pci_bus, window;
-
-	/* Don't disable SCS windows b/c we need to access system memory */
-
-	for (window=0; window<GT64260_CPU_CS_DECODE_WINDOWS; window++) {
-		gt64260_cpu_cs_set_window(window, 0, 0);
-	}
-
-	gt64260_cpu_boot_set_window(0, 0);
-
-	for (pci_bus=0; pci_bus<GT64260_PCI_BUSES; pci_bus++) {
-		gt64260_cpu_set_pci_io_window(pci_bus, 0, 0, 0, 0);
-
-		for (window=0;window<GT64260_PCI_MEM_WINDOWS_PER_BUS;window++) {
-			gt64260_cpu_set_pci_mem_window(pci_bus,
-						       window,
-						       0, 0, 0, 0, 0);
-		}
-	}
-
-	for (window=0; window<GT64260_CPU_PROT_WINDOWS; window++) {
-		gt64260_cpu_prot_set_window(window, 0, 0, 0);
-	}
-
-	for (window=0; window<GT64260_CPU_SNOOP_WINDOWS; window++) {
-		gt64260_cpu_snoop_set_window(window, 0, 0, 0);
-	}
-
-	return;
-} /* gt64260_cpu_disable_all_windows() */
-
-
-/*
- *****************************************************************************
- *
- *	PCI Slave Window Configuration Routines
- *
- *****************************************************************************
- */
-
-int
-gt64260_pci_bar_enable(u32 pci_bus,
-		       u32 enable_bits)
-{
-	u32	reg, val;
-	int	rc = -1;
-
-	if (pci_bus < GT64260_PCI_BUSES) {
-		reg = (pci_bus == 0) ? GT64260_PCI_0_SLAVE_BAR_REG_ENABLES :
-				       GT64260_PCI_1_SLAVE_BAR_REG_ENABLES;
-
-
-		/* Note: '0' enables, '1' disables */
-		val = gt_read(reg);
-		val |= 0xffffffff;	/* Disable everything by default */
-		val &= ~enable_bits;
-		gt_write(reg, val);
-
-		gt_read(reg); /* Flush FIFO */
-
-		rc = 0;
-	}
-
-	return rc;
-} /* gt64260_pci_bar_enable() */
-
-static int
-gt64260_pci_slave_set_window(struct pci_controller *hose,
-			     u32 pci_base_addr,
-			     u32 cpu_base_addr,
-			     u32 bar_size,
-			     u32 pci_cfg_fcn,
-			     u32 pci_cfg_hdr_offset,
-			     u32 bar_size_reg,
-			     u32 remap_reg)
-{
-	u32	val;
-	int	devfn;
-	u8	save_exclude;
-
-	pci_base_addr &= 0xfffff000;
-	cpu_base_addr &= 0xfffff000;
-	bar_size &= 0xfffff000;
-	devfn = PCI_DEVFN(0, pci_cfg_fcn);
-
-	gt_write(bar_size_reg, (bar_size - 1) & 0xfffff000);
-	gt_write(remap_reg, cpu_base_addr);
-	gt_read(remap_reg); /* Flush FIFO */
-
-	save_exclude = gt64260_pci_exclude_bridge;
-	gt64260_pci_exclude_bridge = FALSE;
-	early_read_config_dword(hose,
-				hose->first_busno,
-				devfn,
-				pci_cfg_hdr_offset,
-				&val);
-	val &= 0x0000000f;
-	early_write_config_dword(hose,
-				 hose->first_busno,
-				 devfn,
-				 pci_cfg_hdr_offset,
-				 pci_base_addr | val);
-	gt64260_pci_exclude_bridge = save_exclude;
-
-	return 0;
-} /* gt64260_pci_slave_set_window() */
-
-int
-gt64260_pci_slave_scs_set_window(struct pci_controller *hose,
-				 u32 window,
-				 u32 pci_base_addr,
-				 u32 cpu_base_addr,
-				 u32 size)
-{
-	static u32
-	pci_scs_windows[GT64260_PCI_BUSES][GT64260_PCI_SCS_WINDOWS][4] = {
-		{ /* PCI 0 */
-			{ 0, 0x10,
-			  GT64260_PCI_0_SLAVE_SCS_0_SIZE,
-			  GT64260_PCI_0_SLAVE_SCS_0_REMAP },
-			{ 0, 0x14,
-			  GT64260_PCI_0_SLAVE_SCS_1_SIZE,
-			  GT64260_PCI_0_SLAVE_SCS_1_REMAP },
-			{ 0, 0x18,
-			  GT64260_PCI_0_SLAVE_SCS_2_SIZE,
-			  GT64260_PCI_0_SLAVE_SCS_2_REMAP },
-			{ 0, 0x1c,
-			  GT64260_PCI_0_SLAVE_SCS_3_SIZE,
-			  GT64260_PCI_0_SLAVE_SCS_3_REMAP },
-		},
-		{ /* PCI 1 */
-			{ 0, 0x10,
-			  GT64260_PCI_1_SLAVE_SCS_0_SIZE,
-			  GT64260_PCI_1_SLAVE_SCS_0_REMAP },
-			{ 0, 0x14,
-			  GT64260_PCI_1_SLAVE_SCS_1_SIZE,
-			  GT64260_PCI_1_SLAVE_SCS_1_REMAP },
-			{ 0, 0x18,
-			  GT64260_PCI_1_SLAVE_SCS_2_SIZE,
-			  GT64260_PCI_1_SLAVE_SCS_2_REMAP },
-			{ 0, 0x1c,
-			  GT64260_PCI_1_SLAVE_SCS_3_SIZE,
-			  GT64260_PCI_1_SLAVE_SCS_3_REMAP },
-		}
-	}; /* pci_scs_windows[][][] */
-	int	pci_bus;
-	int	rc = -1;
-
-	if (window < GT64260_PCI_SCS_WINDOWS) {
-		pci_bus = (hose->first_busno == 0) ? 0 : 1;
-
-		rc = gt64260_pci_slave_set_window(
-				hose,
-				pci_base_addr,
-				cpu_base_addr,
-				size,
-				pci_scs_windows[pci_bus][window][0],
-				pci_scs_windows[pci_bus][window][1],
-				pci_scs_windows[pci_bus][window][2],
-				pci_scs_windows[pci_bus][window][3]);
-	}
-
-	return rc;
-} /* gt64260_pci_slave_scs_set_window() */
-
-int
-gt64260_pci_slave_cs_set_window(struct pci_controller *hose,
-				u32 window,
-				u32 pci_base_addr,
-				u32 cpu_base_addr,
-				u32 size)
-{
-	static u32
-	pci_cs_windows[GT64260_PCI_BUSES][GT64260_PCI_CS_WINDOWS][4] = {
-		{ /* PCI 0 */
-			{ 1, 0x10,
-			  GT64260_PCI_0_SLAVE_CS_0_SIZE,
-			  GT64260_PCI_0_SLAVE_CS_0_REMAP },
-			{ 1, 0x14,
-			  GT64260_PCI_0_SLAVE_CS_1_SIZE,
-			  GT64260_PCI_0_SLAVE_CS_1_REMAP },
-			{ 1, 0x18,
-			  GT64260_PCI_0_SLAVE_CS_2_SIZE,
-			  GT64260_PCI_0_SLAVE_CS_2_REMAP },
-			{ 1, 0x1c,
-			  GT64260_PCI_0_SLAVE_CS_3_SIZE,
-			  GT64260_PCI_0_SLAVE_CS_3_REMAP },
-		},
-		{ /* PCI 1 */
-			{ 1, 0x10,
-			  GT64260_PCI_1_SLAVE_CS_0_SIZE,
-			  GT64260_PCI_1_SLAVE_CS_0_REMAP },
-			{ 1, 0x14,
-			  GT64260_PCI_1_SLAVE_CS_1_SIZE,
-			  GT64260_PCI_1_SLAVE_CS_1_REMAP },
-			{ 1, 0x18,
-			  GT64260_PCI_1_SLAVE_CS_2_SIZE,
-			  GT64260_PCI_1_SLAVE_CS_2_REMAP },
-			{ 1, 0x1c,
-			  GT64260_PCI_1_SLAVE_CS_3_SIZE,
-			  GT64260_PCI_1_SLAVE_CS_3_REMAP },
-		}
-	}; /* pci_cs_windows[][][] */
-	int	pci_bus;
-	int	rc = -1;
-
-	if (window < GT64260_PCI_CS_WINDOWS) {
-		pci_bus = (hose->first_busno == 0) ? 0 : 1;
-
-		rc = gt64260_pci_slave_set_window(
-				hose,
-				pci_base_addr,
-				cpu_base_addr,
-				size,
-				pci_cs_windows[pci_bus][window][0],
-				pci_cs_windows[pci_bus][window][1],
-				pci_cs_windows[pci_bus][window][2],
-				pci_cs_windows[pci_bus][window][3]);
-	}
-
-	return rc;
-} /* gt64260_pci_slave_cs_set_window() */
-
-int
-gt64260_pci_slave_boot_set_window(struct pci_controller *hose,
-				  u32 pci_base_addr,
-				  u32 cpu_base_addr,
-				  u32 size)
-{
-	int	rc;
-
-	rc = gt64260_pci_slave_set_window(hose,
-					  pci_base_addr,
-					  cpu_base_addr,
-					  size,
-					  1,
-					  0x20,
-					  GT64260_PCI_1_SLAVE_BOOT_SIZE,
-					  GT64260_PCI_1_SLAVE_BOOT_REMAP);
-
-	return rc;
-} /* gt64260_pci_slave_boot_set_window() */
-
-int
-gt64260_pci_slave_p2p_mem_set_window(struct pci_controller *hose,
-				     u32 window,
-				     u32 pci_base_addr,
-				     u32 other_bus_base_addr,
-				     u32 size)
-{
-	static u32
-	pci_p2p_mem_windows[GT64260_PCI_BUSES][GT64260_PCI_P2P_MEM_WINDOWS][4]={
-		{ /* PCI 0 */
-			{ 2, 0x10,
-			  GT64260_PCI_0_SLAVE_P2P_MEM_0_SIZE,
-			  GT64260_PCI_0_SLAVE_P2P_MEM_0_REMAP_LO },
-			{ 2, 0x14,
-			  GT64260_PCI_0_SLAVE_P2P_MEM_1_SIZE,
-			  GT64260_PCI_0_SLAVE_P2P_MEM_1_REMAP_LO },
-		},
-		{ /* PCI 1 */
-			{ 2, 0x10,
-			  GT64260_PCI_1_SLAVE_P2P_MEM_0_SIZE,
-			  GT64260_PCI_1_SLAVE_P2P_MEM_0_REMAP_LO },
-			{ 2, 0x14,
-			  GT64260_PCI_1_SLAVE_P2P_MEM_1_SIZE,
-			  GT64260_PCI_1_SLAVE_P2P_MEM_1_REMAP_LO },
-		}
-	}; /* pci_p2p_mem_windows[][][] */
-	int	pci_bus;
-	int	rc = -1;
-
-	if (window < GT64260_PCI_P2P_MEM_WINDOWS) {
-		pci_bus = (hose->first_busno == 0) ? 0 : 1;
-
-		rc = gt64260_pci_slave_set_window(
-				hose,
-				pci_base_addr,
-				other_bus_base_addr,
-				size,
-				pci_p2p_mem_windows[pci_bus][window][0],
-				pci_p2p_mem_windows[pci_bus][window][1],
-				pci_p2p_mem_windows[pci_bus][window][2],
-				pci_p2p_mem_windows[pci_bus][window][3]);
-	}
-
-	return rc;
-} /* gt64260_pci_slave_p2p_mem_set_window() */
-
-int
-gt64260_pci_slave_p2p_io_set_window(struct pci_controller *hose,
-				    u32 pci_base_addr,
-				    u32 other_bus_base_addr,
-				    u32 size)
-{
-	int	rc;
-
-	rc = gt64260_pci_slave_set_window(hose,
-					  pci_base_addr,
-					  other_bus_base_addr,
-					  size,
-					  2,
-					  0x18,
-					  GT64260_PCI_1_SLAVE_P2P_IO_SIZE,
-					  GT64260_PCI_1_SLAVE_P2P_IO_REMAP);
-
-	return rc;
-} /* gt64260_pci_slave_p2p_io_set_window() */
-
-int
-gt64260_pci_slave_dac_scs_set_window(struct pci_controller *hose,
-				     u32 window,
-				     u32 pci_base_addr_hi,
-				     u32 pci_base_addr_lo,
-				     u32 cpu_base_addr,
-				     u32 size)
-{
-	static u32
-	pci_dac_scs_windows[GT64260_PCI_BUSES][GT64260_PCI_DAC_SCS_WINDOWS][5]={
-		{ /* PCI 0 */
-			{ 4, 0x10, 0x14,
-			  GT64260_PCI_0_SLAVE_DAC_SCS_0_SIZE,
-			  GT64260_PCI_0_SLAVE_DAC_SCS_0_REMAP },
-			{ 4, 0x18, 0x1c,
-			  GT64260_PCI_0_SLAVE_DAC_SCS_1_SIZE,
-			  GT64260_PCI_0_SLAVE_DAC_SCS_1_REMAP },
-			{ 5, 0x10, 0x14,
-			  GT64260_PCI_0_SLAVE_DAC_SCS_2_SIZE,
-			  GT64260_PCI_0_SLAVE_DAC_SCS_2_REMAP },
-			{ 5, 0x18, 0x1c,
-			  GT64260_PCI_0_SLAVE_DAC_SCS_3_SIZE,
-			  GT64260_PCI_0_SLAVE_DAC_SCS_3_REMAP },
-		},
-		{ /* PCI 1 */
-			{ 4, 0x10, 0x14,
-			  GT64260_PCI_1_SLAVE_DAC_SCS_0_SIZE,
-			  GT64260_PCI_1_SLAVE_DAC_SCS_0_REMAP },
-			{ 4, 0x18, 0x1c,
-			  GT64260_PCI_1_SLAVE_DAC_SCS_1_SIZE,
-			  GT64260_PCI_1_SLAVE_DAC_SCS_1_REMAP },
-			{ 5, 0x10, 0x14,
-			  GT64260_PCI_1_SLAVE_DAC_SCS_2_SIZE,
-			  GT64260_PCI_1_SLAVE_DAC_SCS_2_REMAP },
-			{ 5, 0x18, 0x1c,
-			  GT64260_PCI_1_SLAVE_DAC_SCS_3_SIZE,
-			  GT64260_PCI_1_SLAVE_DAC_SCS_3_REMAP },
-		}
-	}; /* pci_dac_scs_windows[][][] */
-	int	pci_bus;
-	int	rc = -1;
-
-	if (window < GT64260_PCI_DAC_SCS_WINDOWS) {
-		pci_bus = (hose->first_busno == 0) ? 0 : 1;
-
-		rc = gt64260_pci_slave_set_window(
-				hose,
-				pci_base_addr_lo,
-				cpu_base_addr,
-				size,
-				pci_dac_scs_windows[pci_bus][window][0],
-				pci_dac_scs_windows[pci_bus][window][1],
-				pci_dac_scs_windows[pci_bus][window][3],
-				pci_dac_scs_windows[pci_bus][window][4]);
-
-		early_write_config_dword(
-			hose,
-			hose->first_busno,
-			PCI_DEVFN(0, pci_dac_scs_windows[pci_bus][window][0]),
-			pci_dac_scs_windows[pci_bus][window][2],
-			pci_base_addr_hi);
-	}
-
-	return rc;
-} /* gt64260_pci_slave_dac_scs_set_window() */
-
-int
-gt64260_pci_slave_dac_cs_set_window(struct pci_controller *hose,
-				    u32 window,
-				    u32 pci_base_addr_hi,
-				    u32 pci_base_addr_lo,
-				    u32 cpu_base_addr,
-				    u32 size)
-{
-	static u32
-	pci_dac_cs_windows[GT64260_PCI_BUSES][GT64260_PCI_DAC_CS_WINDOWS][5] = {
-		{ /* PCI 0 */
-			{ 6, 0x10, 0x14,
-			  GT64260_PCI_0_SLAVE_DAC_CS_0_SIZE,
-			  GT64260_PCI_0_SLAVE_DAC_CS_0_REMAP },
-			{ 6, 0x18, 0x1c,
-			  GT64260_PCI_0_SLAVE_DAC_CS_1_SIZE,
-			  GT64260_PCI_0_SLAVE_DAC_CS_1_REMAP },
-			{ 6, 0x20, 0x24,
-			  GT64260_PCI_0_SLAVE_DAC_CS_2_SIZE,
-			  GT64260_PCI_0_SLAVE_DAC_CS_2_REMAP },
-			{ 7, 0x10, 0x14,
-			  GT64260_PCI_0_SLAVE_DAC_CS_3_SIZE,
-			  GT64260_PCI_0_SLAVE_DAC_CS_3_REMAP },
-		},
-		{ /* PCI 1 */
-			{ 6, 0x10, 0x14,
-			  GT64260_PCI_1_SLAVE_DAC_CS_0_SIZE,
-			  GT64260_PCI_1_SLAVE_DAC_CS_0_REMAP },
-			{ 6, 0x18, 0x1c,
-			  GT64260_PCI_1_SLAVE_DAC_CS_1_SIZE,
-			  GT64260_PCI_1_SLAVE_DAC_CS_1_REMAP },
-			{ 6, 0x20, 0x24,
-			  GT64260_PCI_1_SLAVE_DAC_CS_2_SIZE,
-			  GT64260_PCI_1_SLAVE_DAC_CS_2_REMAP },
-			{ 7, 0x10, 0x14,
-			  GT64260_PCI_1_SLAVE_DAC_CS_3_SIZE,
-			  GT64260_PCI_1_SLAVE_DAC_CS_3_REMAP },
-		}
-	}; /* pci_dac_cs_windows[][][] */
-	int	pci_bus;
-	int	rc = -1;
-
-	if (window < GT64260_PCI_CS_WINDOWS) {
-		pci_bus = (hose->first_busno == 0) ? 0 : 1;
-
-		rc = gt64260_pci_slave_set_window(
-				hose,
-				pci_base_addr_lo,
-				cpu_base_addr,
-				size,
-				pci_dac_cs_windows[pci_bus][window][0],
-				pci_dac_cs_windows[pci_bus][window][1],
-				pci_dac_cs_windows[pci_bus][window][3],
-				pci_dac_cs_windows[pci_bus][window][4]);
-
-		early_write_config_dword(
-			hose,
-			hose->first_busno,
-			PCI_DEVFN(0, pci_dac_cs_windows[pci_bus][window][0]),
-			pci_dac_cs_windows[pci_bus][window][2],
-			pci_base_addr_hi);
-	}
-
-	return rc;
-} /* gt64260_pci_slave_dac_cs_set_window() */
-
-int
-gt64260_pci_slave_dac_boot_set_window(struct pci_controller *hose,
-				      u32 pci_base_addr_hi,
-				      u32 pci_base_addr_lo,
-				      u32 cpu_base_addr,
-				      u32 size)
-{
-	int	rc;
-
-	rc = gt64260_pci_slave_set_window(hose,
-					  pci_base_addr_lo,
-					  cpu_base_addr,
-					  size,
-					  7,
-					  0x18,
-					  GT64260_PCI_1_SLAVE_BOOT_SIZE,
-					  GT64260_PCI_1_SLAVE_BOOT_REMAP);
-
-	early_write_config_dword(hose,
-				 hose->first_busno,
-				 PCI_DEVFN(0, 7),
-				 0x1c,
-				 pci_base_addr_hi);
-
-	return rc;
-} /* gt64260_pci_slave_dac_boot_set_window() */
-
-int
-gt64260_pci_slave_dac_p2p_mem_set_window(struct pci_controller *hose,
-				         u32 window,
-				         u32 pci_base_addr_hi,
-				         u32 pci_base_addr_lo,
-				         u32 other_bus_base_addr,
-				         u32 size)
-{
-	static u32
-	pci_dac_p2p_mem_windows[GT64260_PCI_BUSES][GT64260_PCI_DAC_P2P_MEM_WINDOWS][5] = {
-		{ /* PCI 0 */
-			{ 4, 0x20, 0x24,
-			  GT64260_PCI_0_SLAVE_DAC_P2P_MEM_0_SIZE,
-			  GT64260_PCI_0_SLAVE_DAC_P2P_MEM_0_REMAP_LO },
-			{ 5, 0x20, 0x24,
-			  GT64260_PCI_0_SLAVE_DAC_P2P_MEM_1_SIZE,
-			  GT64260_PCI_0_SLAVE_DAC_P2P_MEM_1_REMAP_LO },
-		},
-		{ /* PCI 1 */
-			{ 4, 0xa0, 0xa4,
-			  GT64260_PCI_0_SLAVE_DAC_P2P_MEM_0_SIZE,
-			  GT64260_PCI_0_SLAVE_DAC_P2P_MEM_0_REMAP_LO },
-			{ 5, 0xa0, 0xa4,
-			  GT64260_PCI_0_SLAVE_DAC_P2P_MEM_1_SIZE,
-			  GT64260_PCI_0_SLAVE_DAC_P2P_MEM_1_REMAP_LO },
-		}
-	}; /* pci_dac_p2p_windows[][][] */
-	int	pci_bus;
-	int	rc = -1;
-
-	if (window < GT64260_PCI_P2P_MEM_WINDOWS) {
-		pci_bus = (hose->first_busno == 0) ? 0 : 1;
-
-		rc = gt64260_pci_slave_set_window(
-				hose,
-				pci_base_addr_lo,
-				other_bus_base_addr,
-				size,
-				pci_dac_p2p_mem_windows[pci_bus][window][0],
-				pci_dac_p2p_mem_windows[pci_bus][window][1],
-				pci_dac_p2p_mem_windows[pci_bus][window][3],
-				pci_dac_p2p_mem_windows[pci_bus][window][4]);
-
-		early_write_config_dword(
-		    hose,
-		    hose->first_busno,
-		    PCI_DEVFN(0, pci_dac_p2p_mem_windows[pci_bus][window][0]),
-		    pci_dac_p2p_mem_windows[pci_bus][window][2],
-		    pci_base_addr_hi);
-	}
-
-	return rc;
-} /* gt64260_pci_slave_dac_p2p_mem_set_window() */
-
-
-/*
- *****************************************************************************
- *
- *	PCI Control Configuration Routines
- *
- *****************************************************************************
- */
-
-
-int
-gt64260_pci_acc_cntl_set_window(u32 pci_bus,
-			        u32 window,
-			        u32 base_addr_hi,
-			        u32 base_addr_lo,
-			        u32 size,
-			        u32 features)
-{
-	static u32
-	pci_acc_cntl_windows[GT64260_PCI_BUSES][GT64260_PCI_ACC_CNTL_WINDOWS][3] = {
-		{ /* PCI 0 */
-			{ GT64260_PCI_0_ACC_CNTL_0_BASE_HI,
-			  GT64260_PCI_0_ACC_CNTL_0_BASE_LO,
-			  GT64260_PCI_0_ACC_CNTL_0_TOP },
-
-			{ GT64260_PCI_0_ACC_CNTL_1_BASE_HI,
-			  GT64260_PCI_0_ACC_CNTL_1_BASE_LO,
-			  GT64260_PCI_0_ACC_CNTL_1_TOP },
-
-			{ GT64260_PCI_0_ACC_CNTL_2_BASE_HI,
-			  GT64260_PCI_0_ACC_CNTL_2_BASE_LO,
-			  GT64260_PCI_0_ACC_CNTL_2_TOP },
-
-			{ GT64260_PCI_0_ACC_CNTL_3_BASE_HI,
-			  GT64260_PCI_0_ACC_CNTL_3_BASE_LO,
-			  GT64260_PCI_0_ACC_CNTL_3_TOP },
-
-			{ GT64260_PCI_0_ACC_CNTL_4_BASE_HI,
-			  GT64260_PCI_0_ACC_CNTL_4_BASE_LO,
-			  GT64260_PCI_0_ACC_CNTL_4_TOP },
-
-			{ GT64260_PCI_0_ACC_CNTL_5_BASE_HI,
-			  GT64260_PCI_0_ACC_CNTL_5_BASE_LO,
-			  GT64260_PCI_0_ACC_CNTL_5_TOP },
-
-			{ GT64260_PCI_0_ACC_CNTL_6_BASE_HI,
-			  GT64260_PCI_0_ACC_CNTL_6_BASE_LO,
-			  GT64260_PCI_0_ACC_CNTL_6_TOP },
-
-			{ GT64260_PCI_0_ACC_CNTL_7_BASE_HI,
-			  GT64260_PCI_0_ACC_CNTL_7_BASE_LO,
-			  GT64260_PCI_0_ACC_CNTL_7_TOP },
-		},
-		{ /* PCI 1 */
-			{ GT64260_PCI_1_ACC_CNTL_0_BASE_HI,
-			  GT64260_PCI_1_ACC_CNTL_0_BASE_LO,
-			  GT64260_PCI_1_ACC_CNTL_0_TOP },
-
-			{ GT64260_PCI_1_ACC_CNTL_1_BASE_HI,
-			  GT64260_PCI_1_ACC_CNTL_1_BASE_LO,
-			  GT64260_PCI_1_ACC_CNTL_1_TOP },
-
-			{ GT64260_PCI_1_ACC_CNTL_2_BASE_HI,
-			  GT64260_PCI_1_ACC_CNTL_2_BASE_LO,
-			  GT64260_PCI_1_ACC_CNTL_2_TOP },
-
-			{ GT64260_PCI_1_ACC_CNTL_3_BASE_HI,
-			  GT64260_PCI_1_ACC_CNTL_3_BASE_LO,
-			  GT64260_PCI_1_ACC_CNTL_3_TOP },
-
-			{ GT64260_PCI_1_ACC_CNTL_4_BASE_HI,
-			  GT64260_PCI_1_ACC_CNTL_4_BASE_LO,
-			  GT64260_PCI_1_ACC_CNTL_4_TOP },
-
-			{ GT64260_PCI_1_ACC_CNTL_5_BASE_HI,
-			  GT64260_PCI_1_ACC_CNTL_5_BASE_LO,
-			  GT64260_PCI_1_ACC_CNTL_5_TOP },
-
-			{ GT64260_PCI_1_ACC_CNTL_6_BASE_HI,
-			  GT64260_PCI_1_ACC_CNTL_6_BASE_LO,
-			  GT64260_PCI_1_ACC_CNTL_6_TOP },
-
-			{ GT64260_PCI_1_ACC_CNTL_7_BASE_HI,
-			  GT64260_PCI_1_ACC_CNTL_7_BASE_LO,
-			  GT64260_PCI_1_ACC_CNTL_7_TOP },
-		}
-	}; /* pci_acc_cntl_windows[][][] */
-	int	rc = -1;
-
-	if ((pci_bus < GT64260_PCI_BUSES) &&
-	    (window < GT64260_PCI_ACC_CNTL_WINDOWS)) {
-
-		rc = gt64260_set_64bit_window(
-			      base_addr_hi,
-			      base_addr_lo,
-			      size,
-			      features,
-			      pci_acc_cntl_windows[pci_bus][window][0],
-			      pci_acc_cntl_windows[pci_bus][window][1],
-			      pci_acc_cntl_windows[pci_bus][window][2]);
-	}
-
-	return rc;
-} /* gt64260_pci_acc_cntl_set_window() */
-
-int
-gt64260_pci_snoop_set_window(u32 pci_bus,
-			     u32 window,
-			     u32 base_addr_hi,
-			     u32 base_addr_lo,
-			     u32 size,
-			     u32 snoop_type)
-{
-	static u32
-	pci_snoop_windows[GT64260_PCI_BUSES][GT64260_PCI_SNOOP_WINDOWS][3] = {
-		{ /* PCI 0 */
-			{ GT64260_PCI_0_SNOOP_0_BASE_HI,
-			  GT64260_PCI_0_SNOOP_0_BASE_LO,
-			  GT64260_PCI_0_SNOOP_0_TOP },
-
-			{ GT64260_PCI_0_SNOOP_1_BASE_HI,
-			  GT64260_PCI_0_SNOOP_1_BASE_LO,
-			  GT64260_PCI_0_SNOOP_1_TOP },
-
-			{ GT64260_PCI_0_SNOOP_2_BASE_HI,
-			  GT64260_PCI_0_SNOOP_2_BASE_LO,
-			  GT64260_PCI_0_SNOOP_2_TOP },
-
-			{ GT64260_PCI_0_SNOOP_3_BASE_HI,
-			  GT64260_PCI_0_SNOOP_3_BASE_LO,
-			  GT64260_PCI_0_SNOOP_3_TOP },
-		},
-		{ /* PCI 1 */
-			{ GT64260_PCI_1_SNOOP_0_BASE_HI,
-			  GT64260_PCI_1_SNOOP_0_BASE_LO,
-			  GT64260_PCI_1_SNOOP_0_TOP },
-
-			{ GT64260_PCI_1_SNOOP_1_BASE_HI,
-			  GT64260_PCI_1_SNOOP_1_BASE_LO,
-			  GT64260_PCI_1_SNOOP_1_TOP },
-
-			{ GT64260_PCI_1_SNOOP_2_BASE_HI,
-			  GT64260_PCI_1_SNOOP_2_BASE_LO,
-			  GT64260_PCI_1_SNOOP_2_TOP },
-
-			{ GT64260_PCI_1_SNOOP_3_BASE_HI,
-			  GT64260_PCI_1_SNOOP_3_BASE_LO,
-			  GT64260_PCI_1_SNOOP_3_TOP },
-		},
-	}; /* pci_snoop_windows[][][] */
-	int	rc = -1;
-
-	if ((pci_bus < GT64260_PCI_BUSES) &&
-	    (window < GT64260_PCI_SNOOP_WINDOWS)) {
-
-		rc = gt64260_set_64bit_window(
-			      base_addr_hi,
-			      base_addr_lo,
-			      size,
-			      snoop_type,
-			      pci_snoop_windows[pci_bus][window][0],
-			      pci_snoop_windows[pci_bus][window][1],
-			      pci_snoop_windows[pci_bus][window][2]);
-	}
-
-	return rc;
-} /* gt64260_pci_snoop_set_window() */
-
-/*
- *****************************************************************************
- *
- *	64260's Register Base Address Routines
- *
- *****************************************************************************
- */
-
-/*
- * gt64260_remap_bridge_regs()
- *
- * Move the bridge's register to the specified base address.
- * Assume that there are no other windows overlapping this area and that
- * all but the highest 3 nibbles are 0.
- */
-int
-gt64260_set_base(u32 new_base)
-{
-	u32	val;
-	int	limit = 100000;
-	int	rc = 0;
-
-	val = gt_read(GT64260_INTERNAL_SPACE_DECODE);
-	val = (new_base >> 20) | (val & 0xffff0000);
-	gt_write(GT64260_INTERNAL_SPACE_DECODE, val);
-
-	iounmap((void *)gt64260_base);
-	gt64260_base = (u32)ioremap((new_base & 0xfff00000),
-				    GT64260_INTERNAL_SPACE_SIZE);
-
-	do { /* Wait for bridge to move its regs */
-		val = gt_read(GT64260_INTERNAL_SPACE_DECODE);
-	} while ((val != 0xffffffff) && (limit-- > 0));
-
-	if (limit <= 0) {
-		rc = -1;
-	}
-
-	return rc;
-} /* gt64260_remap_bridge_regs() */
-
-/*
- * gt64260_get_base()
- *
- * Return the current virtual base address of the 64260's registers.
- */
-int
-gt64260_get_base(u32 *base)
-{
-	*base = gt64260_base;
-	return 0;
-} /* gt64260_remap_bridge_regs() */
-
-/*
- *****************************************************************************
- *
- *	Exclude PCI config space access to bridge itself
- *
- *****************************************************************************
- */
-
-/*
- * gt64260_exclude_pci_device()
- *
- * This routine causes the PCI subsystem to skip the PCI device in slot 0
- * (which is the 64260 itself) unless explicitly allowed.
- */
-int
-gt64260_pci_exclude_device(u8 bus, u8 devfn)
-{
-	struct pci_controller	*hose;
-
-	hose = pci_bus_to_hose(bus);
-
-	/* Skip slot 0 and 1 on both hoses */
-	if ((gt64260_pci_exclude_bridge == TRUE) &&
-	    (PCI_SLOT(devfn) == 0) &&
-	    (hose->first_busno == bus)) {
-
-		return PCIBIOS_DEVICE_NOT_FOUND;
-	}
-	else {
-		return PCIBIOS_SUCCESSFUL;
-	}
-} /* gt64260_pci_exclude_device() */
-
-#if defined(CONFIG_SERIAL_TEXT_DEBUG)
-
-/*
- * gt64260_putc()
- *
- * Dump a character out the MPSC port for gt64260_mpsc_progress
- * this assumes the baud rate has already been set up and the
- * MPSC initialized by the bootloader or firmware.
- */
-
-static inline void
-gt_putc(char c){
-	mb();
-	gt_write(GT64260_MPSC_0_CHR_1, c);
-	mb();
-	gt_write(GT64260_MPSC_0_CHR_2, 0x200);
-	mb();
-
-	udelay(10000);
-}
-
-void
-puthex(unsigned long val){
-
-        int i;
-
-        for (i = 7;  i >= 0;  i--) {
-		gt_putc("0123456789ABCDEF"[(val>>28) & 0x0f]);
-		val <<= 4;
-	}
-	gt_putc('\r');
-	gt_putc('\n');
-
-}
-
-
-void
-gt64260_mpsc_progress(char *s, unsigned short hex){
-	/* spit stuff out the 64260 mpsc */
-
-	volatile char	c;
-	while ((c = *s++) != 0){
-		gt_putc(c);
-		if ( c == '\n' ) gt_putc('\r');
-	}
-	gt_putc('\n');
-	gt_putc('\r');
-
-	return;
-}
-
-#endif /* CONFIG_DEBUG_TEXT */
diff -Nru a/arch/ppc/syslib/gt64260_pic.c b/arch/ppc/syslib/gt64260_pic.c
--- a/arch/ppc/syslib/gt64260_pic.c	2005-03-01 23:39:07 -08:00
+++ b/arch/ppc/syslib/gt64260_pic.c	2005-03-01 23:39:07 -08:00
@@ -3,7 +3,7 @@
  *
  * Interrupt controller support for Galileo's GT64260.
  *
- * Author: Chris Zankel <chris@mvista.com>
+ * Author: Chris Zankel <source@mvista.com>
  * Modified by: Mark A. Greer <mgreer@mvista.com>
  *
  * Based on sources from Rabeeh Khoury / Galileo Technology
@@ -34,6 +34,7 @@
 
 #include <linux/stddef.h>
 #include <linux/init.h>
+#include <linux/interrupt.h>
 #include <linux/sched.h>
 #include <linux/signal.h>
 #include <linux/stddef.h>
@@ -43,8 +44,11 @@
 #include <asm/io.h>
 #include <asm/system.h>
 #include <asm/irq.h>
-#include <asm/gt64260.h>
+#include <asm/mv64x60.h>
 
+#define CPU_INTR_STR	"gt64260 cpu interface error"
+#define PCI0_INTR_STR	"gt64260 pci 0 error"
+#define PCI1_INTR_STR	"gt64260 pci 1 error"
 
 /* ========================== forward declaration ========================== */
 
@@ -54,63 +58,55 @@
 /* ========================== local declarations =========================== */
 
 struct hw_interrupt_type gt64260_pic = {
-	" GT64260_PIC ",		/* typename */
-	NULL,				/* startup */
-	NULL,				/* shutdown */
-	gt64260_unmask_irq,		/* enable */
-	gt64260_mask_irq,		/* disable */
-	gt64260_mask_irq,		/* ack */
-	NULL,				/* end */
-	NULL				/* set_affinity */
+	.typename = " gt64260_pic ",
+	.enable   = gt64260_unmask_irq,
+	.disable  = gt64260_mask_irq,
+	.ack      = gt64260_mask_irq,
+	.end      = gt64260_unmask_irq,
 };
 
-u32 gt64260_irq_base = 0;      /* GT64260 handles the next 96 IRQs from here */
+u32 gt64260_irq_base = 0;	/* GT64260 handles the next 96 IRQs from here */
+
+static struct mv64x60_handle bh;
 
 /* gt64260_init_irq()
  *
  *  This function initializes the interrupt controller. It assigns
  *  all interrupts from IRQ0 to IRQ95 to the gt64260 interrupt controller.
  *
- * Input Variable(s):
- *  None.
- *
- * Outpu. Variable(s):
- *  None.
- *
- * Returns:
- *  void
- *
  * Note:
  *  We register all GPP inputs as interrupt source, but disable them.
  */
-
-__init void
+void __init
 gt64260_init_irq(void)
 {
 	int i;
 
-	if ( ppc_md.progress ) ppc_md.progress("gt64260_init_irq: enter", 0x0);
+	if (ppc_md.progress)
+		ppc_md.progress("gt64260_init_irq: enter", 0x0);
+
+	bh.v_base = mv64x60_get_bridge_vbase();
 
 	ppc_cached_irq_mask[0] = 0;
-	ppc_cached_irq_mask[1] = 0x0f000000; /* Enable GPP intrs */
+	ppc_cached_irq_mask[1] = 0x0f000000;	/* Enable GPP intrs */
 	ppc_cached_irq_mask[2] = 0;
 
 	/* disable all interrupts and clear current interrupts */
-	gt_write(GT64260_GPP_INTR_MASK, ppc_cached_irq_mask[2]);
-	gt_write(GT64260_GPP_INTR_CAUSE,0);
-	gt_write(GT64260_IC_CPU_INTR_MASK_LO, ppc_cached_irq_mask[0]);
-	gt_write(GT64260_IC_CPU_INTR_MASK_HI, ppc_cached_irq_mask[1]);
+	mv64x60_write(&bh, MV64x60_GPP_INTR_MASK, ppc_cached_irq_mask[2]);
+	mv64x60_write(&bh, MV64x60_GPP_INTR_CAUSE, 0);
+	mv64x60_write(&bh, GT64260_IC_CPU_INTR_MASK_LO, ppc_cached_irq_mask[0]);
+	mv64x60_write(&bh, GT64260_IC_CPU_INTR_MASK_HI, ppc_cached_irq_mask[1]);
 
 	/* use the gt64260 for all (possible) interrupt sources */
-	for( i = gt64260_irq_base;  i < (gt64260_irq_base + 96);  i++ )  {
+	for (i = gt64260_irq_base; i < (gt64260_irq_base + 96); i++)
 		irq_desc[i].handler = &gt64260_pic;
-	}
 
-	if ( ppc_md.progress ) ppc_md.progress("gt64260_init_irq: exit", 0x0);
+	if (ppc_md.progress)
+		ppc_md.progress("gt64260_init_irq: exit", 0x0);
 }
 
-
-/* gt64260_get_irq()
+/*
+ * gt64260_get_irq()
  *
  *  This function returns the lowest interrupt number of all interrupts that
  *  are currently asserted.
@@ -123,7 +119,6 @@
  *
  * Returns:
  *  int	<interrupt number> or -2 (bogus interrupt)
- *
  */
 int
 gt64260_get_irq(struct pt_regs *regs)
@@ -131,38 +126,41 @@
 	int irq;
 	int irq_gpp;
 
-	irq = gt_read(GT64260_IC_MAIN_CAUSE_LO);
+	irq = mv64x60_read(&bh, GT64260_IC_MAIN_CAUSE_LO);
 	irq = __ilog2((irq & 0x3dfffffe) & ppc_cached_irq_mask[0]);
 
 	if (irq == -1) {
-		irq = gt_read(GT64260_IC_MAIN_CAUSE_HI);
+		irq = mv64x60_read(&bh, GT64260_IC_MAIN_CAUSE_HI);
 		irq = __ilog2((irq & 0x0f000db7) & ppc_cached_irq_mask[1]);
 
-		if (irq == -1) {
-			irq = -2;   /* bogus interrupt, should never happen */
-		} else {
+		if (irq == -1)
+			irq = -2; /* bogus interrupt, should never happen */
+		else {
 			if (irq >= 24) {
-				irq_gpp = gt_read(GT64260_GPP_INTR_CAUSE);
+				irq_gpp = mv64x60_read(&bh,
+					MV64x60_GPP_INTR_CAUSE);
 				irq_gpp = __ilog2(irq_gpp &
-						  ppc_cached_irq_mask[2]);
+					ppc_cached_irq_mask[2]);
 
-				if (irq_gpp == -1) {
+				if (irq_gpp == -1)
 					irq = -2;
-				} else {
+				else {
 					irq = irq_gpp + 64;
-					gt_write(GT64260_GPP_INTR_CAUSE, ~(1<<(irq-64)));
+					mv64x60_write(&bh,
+						MV64x60_GPP_INTR_CAUSE,
+						~(1 << (irq - 64)));
 				}
-			} else {
+			} else
 				irq += 32;
-			}
 		}
 	}
 
-	if( irq < 0 )  {
-		return( irq );
-	} else  {
-		return( gt64260_irq_base + irq );
-	}
+	(void)mv64x60_read(&bh, MV64x60_GPP_INTR_CAUSE);
+
+	if (irq < 0)
+		return (irq);
+	else
+		return (gt64260_irq_base + irq);
 }
 
 /* gt64260_unmask_irq()
@@ -178,32 +176,29 @@
  * Returns:
  *  void
  */
-
 static void
 gt64260_unmask_irq(unsigned int irq)
 {
 	irq -= gt64260_irq_base;
-	if (irq > 31) {
-		if (irq > 63) {
-			/* unmask GPP irq */
-			gt_write(GT64260_GPP_INTR_MASK,
-				     ppc_cached_irq_mask[2] |= (1<<(irq-64)));
-		} else {
-			/* mask high interrupt register */
-			gt_write(GT64260_IC_CPU_INTR_MASK_HI,
-				     ppc_cached_irq_mask[1] |= (1<<(irq-32)));
-		}
-	} else {
-		/* mask low interrupt register */
-		gt_write(GT64260_IC_CPU_INTR_MASK_LO,
-			     ppc_cached_irq_mask[0] |= (1<<irq));
-	}
-}
 
+	if (irq > 31)
+		if (irq > 63) /* unmask GPP irq */
+			mv64x60_write(&bh, MV64x60_GPP_INTR_MASK,
+				ppc_cached_irq_mask[2] |= (1 << (irq - 64)));
+		else /* mask high interrupt register */
+			mv64x60_write(&bh, GT64260_IC_CPU_INTR_MASK_HI,
+				ppc_cached_irq_mask[1] |= (1 << (irq - 32)));
+	else /* mask low interrupt register */
+		mv64x60_write(&bh, GT64260_IC_CPU_INTR_MASK_LO,
+			ppc_cached_irq_mask[0] |= (1 << irq));
+
+	(void)mv64x60_read(&bh, MV64x60_GPP_INTR_MASK);
+	return;
+}
 
 /* gt64260_mask_irq()
  *
- *  This funktion disables the requested interrupt.
+ *  This function disables the requested interrupt.
  *
  * Input Variable(s):
  *  unsigned int	interrupt number (IRQ0...IRQ95).
@@ -214,28 +209,120 @@
  * Returns:
  *  void
  */
-
 static void
 gt64260_mask_irq(unsigned int irq)
 {
 	irq -= gt64260_irq_base;
-	if (irq > 31) {
-		if (irq > 63) {
-			/* mask GPP irq */
-			gt_write(GT64260_GPP_INTR_MASK,
-				     ppc_cached_irq_mask[2] &= ~(1<<(irq-64)));
-		} else {
-			/* mask high interrupt register */
-			gt_write(GT64260_IC_CPU_INTR_MASK_HI,
-				     ppc_cached_irq_mask[1] &= ~(1<<(irq-32)));
-		}
-	} else {
-		/* mask low interrupt register */
-		gt_write(GT64260_IC_CPU_INTR_MASK_LO,
-			     ppc_cached_irq_mask[0] &= ~(1<<irq));
-	}
 
-	if (irq == 36) { /* Seems necessary for SDMA interrupts */
-		udelay(1);
+	if (irq > 31)
+		if (irq > 63) /* mask GPP irq */
+			mv64x60_write(&bh, MV64x60_GPP_INTR_MASK,
+				ppc_cached_irq_mask[2] &= ~(1 << (irq - 64)));
+		else /* mask high interrupt register */
+			mv64x60_write(&bh, GT64260_IC_CPU_INTR_MASK_HI,
+				ppc_cached_irq_mask[1] &= ~(1 << (irq - 32)));
+	else /* mask low interrupt register */
+		mv64x60_write(&bh, GT64260_IC_CPU_INTR_MASK_LO,
+			ppc_cached_irq_mask[0] &= ~(1 << irq));
+
+	(void)mv64x60_read(&bh, MV64x60_GPP_INTR_MASK);
+	return;
+}
+
+static irqreturn_t
+gt64260_cpu_error_int_handler(int irq, void *dev_id, struct pt_regs *regs)
+{
+	printk(KERN_ERR "gt64260_cpu_error_int_handler: %s 0x%08x\n",
+		"Error on CPU interface - Cause regiser",
+		mv64x60_read(&bh, MV64x60_CPU_ERR_CAUSE));
+	printk(KERN_ERR "\tCPU error register dump:\n");
+	printk(KERN_ERR "\tAddress low  0x%08x\n",
+	       mv64x60_read(&bh, MV64x60_CPU_ERR_ADDR_LO));
+	printk(KERN_ERR "\tAddress high 0x%08x\n",
+	       mv64x60_read(&bh, MV64x60_CPU_ERR_ADDR_HI));
+	printk(KERN_ERR "\tData low     0x%08x\n",
+	       mv64x60_read(&bh, MV64x60_CPU_ERR_DATA_LO));
+	printk(KERN_ERR "\tData high    0x%08x\n",
+	       mv64x60_read(&bh, MV64x60_CPU_ERR_DATA_HI));
+	printk(KERN_ERR "\tParity       0x%08x\n",
+	       mv64x60_read(&bh, MV64x60_CPU_ERR_PARITY));
+	mv64x60_write(&bh, MV64x60_CPU_ERR_CAUSE, 0);
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t
+gt64260_pci_error_int_handler(int irq, void *dev_id, struct pt_regs *regs)
+{
+	u32 val;
+	unsigned int pci_bus = (unsigned int)dev_id;
+
+	if (pci_bus == 0) {	/* Error on PCI 0 */
+		val = mv64x60_read(&bh, MV64x60_PCI0_ERR_CAUSE);
+		printk(KERN_ERR "%s: Error in PCI %d Interface\n",
+			"gt64260_pci_error_int_handler", pci_bus);
+		printk(KERN_ERR "\tPCI %d error register dump:\n", pci_bus);
+		printk(KERN_ERR "\tCause register 0x%08x\n", val);
+		printk(KERN_ERR "\tAddress Low    0x%08x\n",
+		       mv64x60_read(&bh, MV64x60_PCI0_ERR_ADDR_LO));
+		printk(KERN_ERR "\tAddress High   0x%08x\n",
+		       mv64x60_read(&bh, MV64x60_PCI0_ERR_ADDR_HI));
+		printk(KERN_ERR "\tAttribute      0x%08x\n",
+		       mv64x60_read(&bh, MV64x60_PCI0_ERR_DATA_LO));
+		printk(KERN_ERR "\tCommand        0x%08x\n",
+		       mv64x60_read(&bh, MV64x60_PCI0_ERR_CMD));
+		mv64x60_write(&bh, MV64x60_PCI0_ERR_CAUSE, ~val);
+	}
+	if (pci_bus == 1) {	/* Error on PCI 1 */
+		val = mv64x60_read(&bh, MV64x60_PCI1_ERR_CAUSE);
+		printk(KERN_ERR "%s: Error in PCI %d Interface\n",
+			"gt64260_pci_error_int_handler", pci_bus);
+		printk(KERN_ERR "\tPCI %d error register dump:\n", pci_bus);
+		printk(KERN_ERR "\tCause register 0x%08x\n", val);
+		printk(KERN_ERR "\tAddress Low    0x%08x\n",
+		       mv64x60_read(&bh, MV64x60_PCI1_ERR_ADDR_LO));
+		printk(KERN_ERR "\tAddress High   0x%08x\n",
+		       mv64x60_read(&bh, MV64x60_PCI1_ERR_ADDR_HI));
+		printk(KERN_ERR "\tAttribute      0x%08x\n",
+		       mv64x60_read(&bh, MV64x60_PCI1_ERR_DATA_LO));
+		printk(KERN_ERR "\tCommand        0x%08x\n",
+		       mv64x60_read(&bh, MV64x60_PCI1_ERR_CMD));
+		mv64x60_write(&bh, MV64x60_PCI1_ERR_CAUSE, ~val);
 	}
+	return IRQ_HANDLED;
+}
+
+static int __init
+gt64260_register_hdlrs(void)
+{
+	int rc;
+
+	/* Register CPU interface error interrupt handler */
+	if ((rc = request_irq(MV64x60_IRQ_CPU_ERR,
+		gt64260_cpu_error_int_handler, SA_INTERRUPT, CPU_INTR_STR, 0)))
+		printk(KERN_WARNING "Can't register cpu error handler: %d", rc);
+
+	mv64x60_write(&bh, MV64x60_CPU_ERR_MASK, 0);
+	mv64x60_write(&bh, MV64x60_CPU_ERR_MASK, 0x000000fe);
+
+	/* Register PCI 0 error interrupt handler */
+	if ((rc = request_irq(MV64360_IRQ_PCI0, gt64260_pci_error_int_handler,
+		    SA_INTERRUPT, PCI0_INTR_STR, (void *)0)))
+		printk(KERN_WARNING "Can't register pci 0 error handler: %d",
+			rc);
+
+	mv64x60_write(&bh, MV64x60_PCI0_ERR_MASK, 0);
+	mv64x60_write(&bh, MV64x60_PCI0_ERR_MASK, 0x003c0c24);
+
+	/* Register PCI 1 error interrupt handler */
+	if ((rc = request_irq(MV64360_IRQ_PCI1, gt64260_pci_error_int_handler,
+		    SA_INTERRUPT, PCI1_INTR_STR, (void *)1)))
+		printk(KERN_WARNING "Can't register pci 1 error handler: %d",
+			rc);
+
+	mv64x60_write(&bh, MV64x60_PCI1_ERR_MASK, 0);
+	mv64x60_write(&bh, MV64x60_PCI1_ERR_MASK, 0x003c0c24);
+
+	return 0;
 }
+
+arch_initcall(gt64260_register_hdlrs);
diff -Nru a/arch/ppc/syslib/i8259.c b/arch/ppc/syslib/i8259.c
--- a/arch/ppc/syslib/i8259.c	2005-03-01 23:38:56 -08:00
+++ b/arch/ppc/syslib/i8259.c	2005-03-01 23:38:56 -08:00
@@ -10,7 +10,7 @@
 #define cached_A1 (cached_8259[0])
 #define cached_21 (cached_8259[1])
 
-static spinlock_t i8259_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(i8259_lock);
 
 int i8259_pic_irq_offset;
 
@@ -140,15 +140,24 @@
 };
 
 static struct resource pic1_iores = {
-	"8259 (master)", 0x20, 0x21, IORESOURCE_BUSY
+	.name = "8259 (master)",
+	.start = 0x20,
+	.end = 0x21,
+	.flags = IORESOURCE_BUSY,
 };
 
 static struct resource pic2_iores = {
-	"8259 (slave)", 0xa0, 0xa1, IORESOURCE_BUSY
+	.name = "8259 (slave)",
+	.start = 0xa0,
+	.end = 0xa1,
+	.flags = IORESOURCE_BUSY,
 };
 
 static struct resource pic_edgectrl_iores = {
-	"8259 edge control", 0x4d0, 0x4d1, IORESOURCE_BUSY
+	.name = "8259 edge control",
+	.start = 0x4d0,
+	.end = 0x4d1,
+	.flags = IORESOURCE_BUSY,
 };
 
 static struct irqaction i8259_irqaction = {
diff -Nru a/arch/ppc/syslib/ibm440sp_common.c b/arch/ppc/syslib/ibm440sp_common.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/ppc/syslib/ibm440sp_common.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,71 @@
+/*
+ * arch/ppc/syslib/ibm440sp_common.c
+ *
+ * PPC440SP system library
+ *
+ * Matt Porter <mporter@kernel.crashing.org>
+ * Copyright 2002-2005 MontaVista Software Inc.
+ *
+ * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
+ * Copyright (c) 2003, 2004 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
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/serial.h>
+
+#include <asm/param.h>
+#include <asm/ibm44x.h>
+#include <asm/mmu.h>
+#include <asm/machdep.h>
+#include <asm/time.h>
+#include <asm/ppc4xx_pic.h>
+
+/*
+ * Read the 440SP memory controller to get size of system memory.
+ */
+unsigned long __init ibm440sp_find_end_of_memory(void)
+{
+	u32 i;
+	u32 mem_size = 0;
+
+	/* Read two bank sizes and sum */
+	for (i=0; i<2; i++)
+		switch (mfdcr(DCRN_MQ0_BS0BAS + i) & MQ0_CONFIG_SIZE_MASK) {
+			case MQ0_CONFIG_SIZE_8M:
+				mem_size += PPC44x_MEM_SIZE_8M;
+				break;
+			case MQ0_CONFIG_SIZE_16M:
+				mem_size += PPC44x_MEM_SIZE_16M;
+				break;
+			case MQ0_CONFIG_SIZE_32M:
+				mem_size += PPC44x_MEM_SIZE_32M;
+				break;
+			case MQ0_CONFIG_SIZE_64M:
+				mem_size += PPC44x_MEM_SIZE_64M;
+				break;
+			case MQ0_CONFIG_SIZE_128M:
+				mem_size += PPC44x_MEM_SIZE_128M;
+				break;
+			case MQ0_CONFIG_SIZE_256M:
+				mem_size += PPC44x_MEM_SIZE_256M;
+				break;
+			case MQ0_CONFIG_SIZE_512M:
+				mem_size += PPC44x_MEM_SIZE_512M;
+				break;
+			case MQ0_CONFIG_SIZE_1G:
+				mem_size += PPC44x_MEM_SIZE_1G;
+				break;
+			case MQ0_CONFIG_SIZE_2G:
+				mem_size += PPC44x_MEM_SIZE_2G;
+				break;
+			default:
+				break;
+		}
+	return mem_size;
+}
diff -Nru a/arch/ppc/syslib/ibm440sp_common.h b/arch/ppc/syslib/ibm440sp_common.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/ppc/syslib/ibm440sp_common.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,25 @@
+/*
+ * arch/ppc/syslib/ibm440sp_common.h
+ *
+ * PPC440SP system library
+ *
+ * Matt Porter <mporter@kernel.crashing.org>
+ * Copyright 2004-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 as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
+#ifdef __KERNEL__
+#ifndef __PPC_SYSLIB_IBM440SP_COMMON_H
+#define __PPC_SYSLIB_IBM440SP_COMMON_H
+
+#ifndef __ASSEMBLY__
+
+extern unsigned long __init ibm440sp_find_end_of_memory(void);
+
+#endif /* __ASSEMBLY__ */
+#endif /* __PPC_SYSLIB_IBM440SP_COMMON_H */
+#endif /* __KERNEL__ */
diff -Nru a/arch/ppc/syslib/ibm44x_common.c b/arch/ppc/syslib/ibm44x_common.c
--- a/arch/ppc/syslib/ibm44x_common.c	2005-03-01 23:38:56 -08:00
+++ b/arch/ppc/syslib/ibm44x_common.c	2005-03-01 23:38:56 -08:00
@@ -4,7 +4,7 @@
  * PPC44x system library
  *
  * Matt Porter <mporter@kernel.crashing.org>
- * Copyright 2002-2004 MontaVista Software Inc.
+ * Copyright 2002-2005 MontaVista Software Inc.
  *
  * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
  * Copyright (c) 2003, 2004 Zultys Technologies
@@ -19,6 +19,7 @@
 #include <linux/time.h>
 #include <linux/types.h>
 #include <linux/serial.h>
+#include <linux/module.h>
 
 #include <asm/ibm44x.h>
 #include <asm/mmu.h>
@@ -38,15 +39,22 @@
 	 * address in the 440's 36-bit address space.  Fix
 	 * them up with the appropriate ERPN
 	 */
-	if ((addr >= PPC44x_IO_LO) && (addr < PPC44x_IO_HI))
+	if ((addr >= PPC44x_IO_LO) && (addr <= PPC44x_IO_HI))
 		page_4gb = PPC44x_IO_PAGE;
-	else if ((addr >= PPC44x_PCICFG_LO) && (addr < PPC44x_PCICFG_HI))
+	else if ((addr >= PPC44x_PCI0CFG_LO) && (addr <= PPC44x_PCI0CFG_HI))
 		page_4gb = PPC44x_PCICFG_PAGE;
-	else if ((addr >= PPC44x_PCIMEM_LO) && (addr < PPC44x_PCIMEM_HI))
+#ifdef CONFIG_440SP
+	else if ((addr >= PPC44x_PCI1CFG_LO) && (addr <= PPC44x_PCI1CFG_HI))
+		page_4gb = PPC44x_PCICFG_PAGE;
+	else if ((addr >= PPC44x_PCI2CFG_LO) && (addr <= PPC44x_PCI2CFG_HI))
+		page_4gb = PPC44x_PCICFG_PAGE;
+#endif
+	else if ((addr >= PPC44x_PCIMEM_LO) && (addr <= PPC44x_PCIMEM_HI))
 		page_4gb = PPC44x_PCIMEM_PAGE;
 
 	return (page_4gb | addr);
 };
+EXPORT_SYMBOL(fixup_bigphys_addr);
 
 void __init ibm44x_calibrate_decr(unsigned int freq)
 {
@@ -142,19 +150,9 @@
 	return mem_size;
 }
 
-static void __init ibm44x_init_irq(void)
-{
-	int i;
-
-	ppc4xx_pic_init();
-
-	for (i = 0; i < NR_IRQS; i++)
-		irq_desc[i].handler = ppc4xx_pic;
-}
-
 void __init ibm44x_platform_init(void)
 {
-	ppc_md.init_IRQ = ibm44x_init_irq;
+	ppc_md.init_IRQ = ppc4xx_pic_init;
 	ppc_md.find_end_of_memory = ibm44x_find_end_of_memory;
 	ppc_md.restart = ibm44x_restart;
 	ppc_md.power_off = ibm44x_power_off;
@@ -180,3 +178,16 @@
 #endif
 }
 
+/* Called from MachineCheckException */
+void platform_machine_check(struct pt_regs *regs)
+{
+    	printk("PLB0: BEAR=0x%08x%08x ACR=  0x%08x BESR= 0x%08x\n",
+		mfdcr(DCRN_PLB0_BEARH), mfdcr(DCRN_PLB0_BEARL),
+		mfdcr(DCRN_PLB0_ACR),  mfdcr(DCRN_PLB0_BESR));
+	printk("POB0: BEAR=0x%08x%08x BESR0=0x%08x BESR1=0x%08x\n",
+		mfdcr(DCRN_POB0_BEARH), mfdcr(DCRN_POB0_BEARL),
+		mfdcr(DCRN_POB0_BESR0), mfdcr(DCRN_POB0_BESR1));
+	printk("OPB0: BEAR=0x%08x%08x BSTAT=0x%08x\n",
+		mfdcr(DCRN_OPB0_BEARH), mfdcr(DCRN_OPB0_BEARL),
+		mfdcr(DCRN_OPB0_BSTAT));
+}
diff -Nru a/arch/ppc/syslib/indirect_pci.c b/arch/ppc/syslib/indirect_pci.c
--- a/arch/ppc/syslib/indirect_pci.c	2005-03-01 23:38:52 -08:00
+++ b/arch/ppc/syslib/indirect_pci.c	2005-03-01 23:38:52 -08:00
@@ -32,7 +32,7 @@
 		     int len, u32 *val)
 {
 	struct pci_controller *hose = bus->sysdata;
-	volatile unsigned char *cfg_data;
+	volatile void __iomem *cfg_data;
 	u8 cfg_type = 0;
 
 	if (ppc_md.pci_exclude_device)
@@ -54,13 +54,13 @@
 	cfg_data = hose->cfg_data + (offset & 3);
 	switch (len) {
 	case 1:
-		*val = in_8((u8 *)cfg_data);
+		*val = in_8(cfg_data);
 		break;
 	case 2:
-		*val = in_le16((u16 *)cfg_data);
+		*val = in_le16(cfg_data);
 		break;
 	default:
-		*val = in_le32((u32 *)cfg_data);
+		*val = in_le32(cfg_data);
 		break;
 	}
 	return PCIBIOS_SUCCESSFUL;
@@ -71,7 +71,7 @@
 		      int len, u32 val)
 {
 	struct pci_controller *hose = bus->sysdata;
-	volatile unsigned char *cfg_data;
+	volatile void __iomem *cfg_data;
 	u8 cfg_type = 0;
 
 	if (ppc_md.pci_exclude_device)
@@ -93,13 +93,13 @@
 	cfg_data = hose->cfg_data + (offset & 3);
 	switch (len) {
 	case 1:
-		out_8((u8 *)cfg_data, val);
+		out_8(cfg_data, val);
 		break;
 	case 2:
-		out_le16((u16 *)cfg_data, val);
+		out_le16(cfg_data, val);
 		break;
 	default:
-		out_le32((u32 *)cfg_data, val);
+		out_le32(cfg_data, val);
 		break;
 	}
 	return PCIBIOS_SUCCESSFUL;
@@ -112,11 +112,11 @@
 };
 
 void __init
-setup_indirect_pci_nomap(struct pci_controller* hose, u32 cfg_addr,
-	u32 cfg_data)
+setup_indirect_pci_nomap(struct pci_controller* hose, void __iomem * cfg_addr,
+	void __iomem * cfg_data)
 {
-	hose->cfg_addr = (unsigned int *)cfg_addr;
-	hose->cfg_data = (unsigned char *)cfg_data;
+	hose->cfg_addr = cfg_addr;
+	hose->cfg_data = cfg_data;
 	hose->ops = &indirect_pci_ops;
 }
 
@@ -124,12 +124,12 @@
 setup_indirect_pci(struct pci_controller* hose, u32 cfg_addr, u32 cfg_data)
 {
 	unsigned long base = cfg_addr & PAGE_MASK;
-	char *mbase;
+	void __iomem *mbase, *addr, *data;
 
 	mbase = ioremap(base, PAGE_SIZE);
-	cfg_addr = (u32)(mbase + (cfg_addr & ~PAGE_MASK));
+	addr = mbase + (cfg_addr & ~PAGE_MASK);
 	if ((cfg_data & PAGE_MASK) != base)
 		mbase = ioremap(cfg_data & PAGE_MASK, PAGE_SIZE);
-	cfg_data = (u32)(mbase + (cfg_data & ~PAGE_MASK));
-	setup_indirect_pci_nomap(hose, cfg_addr, cfg_data);
+	data = mbase + (cfg_data & ~PAGE_MASK);
+	setup_indirect_pci_nomap(hose, addr, data);
 }
diff -Nru a/arch/ppc/syslib/m8260_setup.c b/arch/ppc/syslib/m8260_setup.c
--- a/arch/ppc/syslib/m8260_setup.c	2005-03-01 23:38:57 -08:00
+++ b/arch/ppc/syslib/m8260_setup.c	2005-03-01 23:38:57 -08:00
@@ -37,6 +37,12 @@
 extern void m8260_find_bridges(void);
 extern void idma_pci9_init(void);
 
+/* Place-holder for board-specific init */
+void __attribute__ ((weak)) __init
+m82xx_board_setup(void)
+{
+}
+
 static void __init
 m8260_setup_arch(void)
 {
@@ -56,6 +62,7 @@
 	if (initrd_start)
 		ROOT_DEV = Root_RAM0;
 #endif
+	m82xx_board_setup();
 }
 
 /* The decrementer counts at the system (internal) clock frequency
@@ -203,7 +210,7 @@
 	io_block_mapping(IO_VIRT_ADDR, IO_PHYS_ADDR, 0x10000000, _PAGE_IO);
 }
 
-/* Place-holder for board-specific init */
+/* Place-holder for board-specific ppc_md hooking */
 void __attribute__ ((weak)) __init
 m82xx_board_init(void)
 {
diff -Nru a/arch/ppc/syslib/m8xx_setup.c b/arch/ppc/syslib/m8xx_setup.c
--- a/arch/ppc/syslib/m8xx_setup.c	2005-03-01 23:38:56 -08:00
+++ b/arch/ppc/syslib/m8xx_setup.c	2005-03-01 23:38:56 -08:00
@@ -238,7 +238,7 @@
 {
 	__volatile__ unsigned char dummy;
 
-	cli();
+	local_irq_disable();
 	((immap_t *)IMAP_ADDR)->im_clkrst.car_plprcr |= 0x00000080;
 
 	/* Clear the ME bit in MSR to cause checkstop on machine check
diff -Nru a/arch/ppc/syslib/mpc10x_common.c b/arch/ppc/syslib/mpc10x_common.c
--- a/arch/ppc/syslib/mpc10x_common.c	2005-03-01 23:38:53 -08:00
+++ b/arch/ppc/syslib/mpc10x_common.c	2005-03-01 23:38:53 -08:00
@@ -306,6 +306,41 @@
 	mpc10x_disable_store_gathering(hose);
 #endif
 
+	/*
+	 * 8240 erratum 26, 8241/8245 erratum 29, 107 erratum 23: speculative
+	 * PCI reads may return stale data so turn off.
+	 */
+	if ((host_bridge == MPC10X_BRIDGE_8240)
+		|| (host_bridge == MPC10X_BRIDGE_8245)
+		|| (host_bridge == MPC10X_BRIDGE_107)) {
+
+		early_read_config_dword(hose, 0, PCI_DEVFN(0,0),
+			MPC10X_CFG_PICR1_REG, &picr1);
+
+		picr1 &= ~MPC10X_CFG_PICR1_SPEC_PCI_RD;
+
+		early_write_config_dword(hose, 0, PCI_DEVFN(0,0),
+			MPC10X_CFG_PICR1_REG, picr1);
+	}
+
+	/*
+	 * 8241/8245 erratum 28: PCI reads from local memory may return
+	 * stale data.  Workaround by setting PICR2[0] to disable copyback
+	 * optimization.  Oddly, the latest available user manual for the
+	 * 8245 (Rev 2., dated 10/2003) says PICR2[0] is reserverd.
+	 */
+	if (host_bridge == MPC10X_BRIDGE_8245) {
+		ulong	picr2;
+
+		early_read_config_dword(hose, 0, PCI_DEVFN(0,0),
+			MPC10X_CFG_PICR2_REG, &picr2);
+
+		picr2 |= MPC10X_CFG_PICR2_COPYBACK_OPT;
+
+		early_write_config_dword(hose, 0, PCI_DEVFN(0,0),
+			 MPC10X_CFG_PICR2_REG, picr2);
+	}
+
 	if (ppc_md.progress) ppc_md.progress("mpc10x:exit", 0x100);
 	return 0;
 }
diff -Nru a/arch/ppc/syslib/mv64360_pic.c b/arch/ppc/syslib/mv64360_pic.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/ppc/syslib/mv64360_pic.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,421 @@
+/*
+ * arch/ppc/kernel/mv64360_pic.c
+ *
+ * Interrupt controller support for Marvell's MV64360.
+ *
+ * Author: Rabeeh Khoury <rabeeh@galileo.co.il>
+ * Based on MV64360 PIC written by
+ * Chris Zankel <chris@mvista.com>
+ * Mark A. Greer <mgreer@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.
+ */
+
+/*
+ * This file contains the specific functions to support the MV64360
+ * interrupt controller.
+ *
+ * The MV64360 has two main interrupt registers (high and low) that
+ * summarizes the interrupts generated by the units of the MV64360.
+ * Each bit is assigned to an interrupt number, where the low register
+ * are assigned from IRQ0 to IRQ31 and the high cause register
+ * from IRQ32 to IRQ63
+ * The GPP (General Purpose Pins) interrupts are assigned from IRQ64 (GPP0)
+ * to IRQ95 (GPP31).
+ * get_irq() returns the lowest interrupt number that is currently asserted.
+ *
+ * Note:
+ *  - This driver does not initialize the GPP when used as an interrupt
+ *    input.
+ */
+
+#include <linux/stddef.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/signal.h>
+#include <linux/stddef.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+
+#include <asm/io.h>
+#include <asm/processor.h>
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/mv64x60.h>
+
+#ifdef CONFIG_IRQ_ALL_CPUS
+#error "The mv64360 does not support distribution of IRQs on all CPUs"
+#endif
+/* ========================== forward declaration ========================== */
+
+static void mv64360_unmask_irq(unsigned int);
+static void mv64360_mask_irq(unsigned int);
+static irqreturn_t mv64360_cpu_error_int_handler(int, void *, struct pt_regs *);
+static irqreturn_t mv64360_sram_error_int_handler(int, void *,
+						  struct pt_regs *);
+static irqreturn_t mv64360_pci_error_int_handler(int, void *, struct pt_regs *);
+
+/* ========================== local declarations =========================== */
+
+struct hw_interrupt_type mv64360_pic = {
+	.typename = " mv64360_pic ",
+	.enable   = mv64360_unmask_irq,
+	.disable  = mv64360_mask_irq,
+	.ack      = mv64360_mask_irq,
+	.end      = mv64360_unmask_irq,
+};
+
+#define CPU_INTR_STR	"mv64360 cpu interface error"
+#define SRAM_INTR_STR	"mv64360 internal sram error"
+#define PCI0_INTR_STR	"mv64360 pci 0 error"
+#define PCI1_INTR_STR	"mv64360 pci 1 error"
+
+static struct mv64x60_handle bh;
+
+u32 mv64360_irq_base = 0;	/* MV64360 handles the next 96 IRQs from here */
+
+/* mv64360_init_irq()
+ *
+ * This function initializes the interrupt controller. It assigns
+ * all interrupts from IRQ0 to IRQ95 to the mv64360 interrupt controller.
+ *
+ * Input Variable(s):
+ *  None.
+ *
+ * Outpu. Variable(s):
+ *  None.
+ *
+ * Returns:
+ *  void
+ *
+ * Note:
+ *  We register all GPP inputs as interrupt source, but disable them.
+ */
+void __init
+mv64360_init_irq(void)
+{
+	int i;
+
+	if (ppc_md.progress)
+		ppc_md.progress("mv64360_init_irq: enter", 0x0);
+
+	bh.v_base = mv64x60_get_bridge_vbase();
+
+	ppc_cached_irq_mask[0] = 0;
+	ppc_cached_irq_mask[1] = 0x0f000000;	/* Enable GPP intrs */
+	ppc_cached_irq_mask[2] = 0;
+
+	/* disable all interrupts and clear current interrupts */
+	mv64x60_write(&bh, MV64x60_GPP_INTR_CAUSE, 0);
+	mv64x60_write(&bh, MV64x60_GPP_INTR_MASK, ppc_cached_irq_mask[2]);
+	mv64x60_write(&bh, MV64360_IC_CPU0_INTR_MASK_LO,ppc_cached_irq_mask[0]);
+	mv64x60_write(&bh, MV64360_IC_CPU0_INTR_MASK_HI,ppc_cached_irq_mask[1]);
+
+	/* All interrupts are level interrupts */
+	for (i = mv64360_irq_base; i < (mv64360_irq_base + 96); i++) {
+		irq_desc[i].status |= IRQ_LEVEL;
+		irq_desc[i].handler = &mv64360_pic;
+	}
+
+	if (ppc_md.progress)
+		ppc_md.progress("mv64360_init_irq: exit", 0x0);
+}
+
+/* mv64360_get_irq()
+ *
+ * This function returns the lowest interrupt number of all interrupts that
+ * are currently asserted.
+ *
+ * Input Variable(s):
+ *  struct pt_regs*	not used
+ *
+ * Output Variable(s):
+ *  None.
+ *
+ * Returns:
+ *  int	<interrupt number> or -2 (bogus interrupt)
+ *
+ */
+int
+mv64360_get_irq(struct pt_regs *regs)
+{
+	int irq;
+	int irq_gpp;
+
+#ifdef CONFIG_SMP
+	/*
+	 * Second CPU gets only doorbell (message) interrupts.
+	 * The doorbell interrupt is BIT28 in the main interrupt low cause reg.
+	 */
+	int cpu_nr = smp_processor_id();
+	if (cpu_nr == 1) {
+		if (!(mv64x60_read(&bh, MV64360_IC_MAIN_CAUSE_LO) & (1 << 28)))
+			return -1;
+		return 28;
+	}
+#endif
+
+	irq = mv64x60_read(&bh, MV64360_IC_MAIN_CAUSE_LO);
+	irq = __ilog2((irq & 0x3dfffffe) & ppc_cached_irq_mask[0]);
+
+	if (irq == -1) {
+		irq = mv64x60_read(&bh, MV64360_IC_MAIN_CAUSE_HI);
+		irq = __ilog2((irq & 0x1f0003f7) & ppc_cached_irq_mask[1]);
+
+		if (irq == -1)
+			irq = -2; /* bogus interrupt, should never happen */
+		else {
+			if ((irq >= 24) && (irq < 28)) {
+				irq_gpp = mv64x60_read(&bh,
+					MV64x60_GPP_INTR_CAUSE);
+				irq_gpp = __ilog2(irq_gpp &
+					ppc_cached_irq_mask[2]);
+
+				if (irq_gpp == -1)
+					irq = -2;
+				else {
+					irq = irq_gpp + 64;
+					mv64x60_write(&bh,
+						MV64x60_GPP_INTR_CAUSE,
+						~(1 << (irq - 64)));
+				}
+			}
+			else
+				irq += 32;
+		}
+	}
+
+	(void)mv64x60_read(&bh, MV64x60_GPP_INTR_CAUSE);
+
+	if (irq < 0)
+		return (irq);
+	else
+		return (mv64360_irq_base + irq);
+}
+
+/* mv64360_unmask_irq()
+ *
+ * This function enables an interrupt.
+ *
+ * Input Variable(s):
+ *  unsigned int	interrupt number (IRQ0...IRQ95).
+ *
+ * Output Variable(s):
+ *  None.
+ *
+ * Returns:
+ *  void
+ */
+static void
+mv64360_unmask_irq(unsigned int irq)
+{
+#ifdef CONFIG_SMP
+	/* second CPU gets only doorbell interrupts */
+	if ((irq - mv64360_irq_base) == 28) {
+		mv64x60_set_bits(&bh, MV64360_IC_CPU1_INTR_MASK_LO, (1 << 28));
+		return;
+	}
+#endif
+	irq -= mv64360_irq_base;
+
+	if (irq > 31) {
+		if (irq > 63) /* unmask GPP irq */
+			mv64x60_write(&bh, MV64x60_GPP_INTR_MASK,
+				ppc_cached_irq_mask[2] |= (1 << (irq - 64)));
+		else /* mask high interrupt register */
+			mv64x60_write(&bh, MV64360_IC_CPU0_INTR_MASK_HI,
+				ppc_cached_irq_mask[1] |= (1 << (irq - 32)));
+	}
+	else /* mask low interrupt register */
+		mv64x60_write(&bh, MV64360_IC_CPU0_INTR_MASK_LO,
+			ppc_cached_irq_mask[0] |= (1 << irq));
+
+	(void)mv64x60_read(&bh, MV64x60_GPP_INTR_MASK);
+	return;
+}
+
+/* mv64360_mask_irq()
+ *
+ * This function disables the requested interrupt.
+ *
+ * Input Variable(s):
+ *  unsigned int	interrupt number (IRQ0...IRQ95).
+ *
+ * Output Variable(s):
+ *  None.
+ *
+ * Returns:
+ *  void
+ */
+static void
+mv64360_mask_irq(unsigned int irq)
+{
+#ifdef CONFIG_SMP
+	if ((irq - mv64360_irq_base) == 28) {
+		mv64x60_clr_bits(&bh, MV64360_IC_CPU1_INTR_MASK_LO, (1 << 28));
+		return;
+	}
+#endif
+	irq -= mv64360_irq_base;
+
+	if (irq > 31) {
+		if (irq > 63) /* mask GPP irq */
+			mv64x60_write(&bh, MV64x60_GPP_INTR_MASK,
+				ppc_cached_irq_mask[2] &= ~(1 << (irq - 64)));
+		else /* mask high interrupt register */
+			mv64x60_write(&bh, MV64360_IC_CPU0_INTR_MASK_HI,
+				ppc_cached_irq_mask[1] &= ~(1 << (irq - 32)));
+	}
+	else /* mask low interrupt register */
+		mv64x60_write(&bh, MV64360_IC_CPU0_INTR_MASK_LO,
+			ppc_cached_irq_mask[0] &= ~(1 << irq));
+
+	(void)mv64x60_read(&bh, MV64x60_GPP_INTR_MASK);
+	return;
+}
+
+static irqreturn_t
+mv64360_cpu_error_int_handler(int irq, void *dev_id, struct pt_regs *regs)
+{
+	printk(KERN_ERR "mv64360_cpu_error_int_handler: %s 0x%08x\n",
+		"Error on CPU interface - Cause regiser",
+		mv64x60_read(&bh, MV64x60_CPU_ERR_CAUSE));
+	printk(KERN_ERR "\tCPU error register dump:\n");
+	printk(KERN_ERR "\tAddress low  0x%08x\n",
+	       mv64x60_read(&bh, MV64x60_CPU_ERR_ADDR_LO));
+	printk(KERN_ERR "\tAddress high 0x%08x\n",
+	       mv64x60_read(&bh, MV64x60_CPU_ERR_ADDR_HI));
+	printk(KERN_ERR "\tData low     0x%08x\n",
+	       mv64x60_read(&bh, MV64x60_CPU_ERR_DATA_LO));
+	printk(KERN_ERR "\tData high    0x%08x\n",
+	       mv64x60_read(&bh, MV64x60_CPU_ERR_DATA_HI));
+	printk(KERN_ERR "\tParity       0x%08x\n",
+	       mv64x60_read(&bh, MV64x60_CPU_ERR_PARITY));
+	mv64x60_write(&bh, MV64x60_CPU_ERR_CAUSE, 0);
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t
+mv64360_sram_error_int_handler(int irq, void *dev_id, struct pt_regs *regs)
+{
+	printk(KERN_ERR "mv64360_sram_error_int_handler: %s 0x%08x\n",
+		"Error in internal SRAM - Cause register",
+		mv64x60_read(&bh, MV64360_SRAM_ERR_CAUSE));
+	printk(KERN_ERR "\tSRAM error register dump:\n");
+	printk(KERN_ERR "\tAddress Low  0x%08x\n",
+	       mv64x60_read(&bh, MV64360_SRAM_ERR_ADDR_LO));
+	printk(KERN_ERR "\tAddress High 0x%08x\n",
+	       mv64x60_read(&bh, MV64360_SRAM_ERR_ADDR_HI));
+	printk(KERN_ERR "\tData Low     0x%08x\n",
+	       mv64x60_read(&bh, MV64360_SRAM_ERR_DATA_LO));
+	printk(KERN_ERR "\tData High    0x%08x\n",
+	       mv64x60_read(&bh, MV64360_SRAM_ERR_DATA_HI));
+	printk(KERN_ERR "\tParity       0x%08x\n",
+		mv64x60_read(&bh, MV64360_SRAM_ERR_PARITY));
+	mv64x60_write(&bh, MV64360_SRAM_ERR_CAUSE, 0);
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t
+mv64360_pci_error_int_handler(int irq, void *dev_id, struct pt_regs *regs)
+{
+	u32 val;
+	unsigned int pci_bus = (unsigned int)dev_id;
+
+	if (pci_bus == 0) {	/* Error on PCI 0 */
+		val = mv64x60_read(&bh, MV64x60_PCI0_ERR_CAUSE);
+		printk(KERN_ERR "%s: Error in PCI %d Interface\n",
+			"mv64360_pci_error_int_handler", pci_bus);
+		printk(KERN_ERR "\tPCI %d error register dump:\n", pci_bus);
+		printk(KERN_ERR "\tCause register 0x%08x\n", val);
+		printk(KERN_ERR "\tAddress Low    0x%08x\n",
+		       mv64x60_read(&bh, MV64x60_PCI0_ERR_ADDR_LO));
+		printk(KERN_ERR "\tAddress High   0x%08x\n",
+		       mv64x60_read(&bh, MV64x60_PCI0_ERR_ADDR_HI));
+		printk(KERN_ERR "\tAttribute      0x%08x\n",
+		       mv64x60_read(&bh, MV64x60_PCI0_ERR_DATA_LO));
+		printk(KERN_ERR "\tCommand        0x%08x\n",
+		       mv64x60_read(&bh, MV64x60_PCI0_ERR_CMD));
+		mv64x60_write(&bh, MV64x60_PCI0_ERR_CAUSE, ~val);
+	}
+	if (pci_bus == 1) {	/* Error on PCI 1 */
+		val = mv64x60_read(&bh, MV64x60_PCI1_ERR_CAUSE);
+		printk(KERN_ERR "%s: Error in PCI %d Interface\n",
+			"mv64360_pci_error_int_handler", pci_bus);
+		printk(KERN_ERR "\tPCI %d error register dump:\n", pci_bus);
+		printk(KERN_ERR "\tCause register 0x%08x\n", val);
+		printk(KERN_ERR "\tAddress Low    0x%08x\n",
+		       mv64x60_read(&bh, MV64x60_PCI1_ERR_ADDR_LO));
+		printk(KERN_ERR "\tAddress High   0x%08x\n",
+		       mv64x60_read(&bh, MV64x60_PCI1_ERR_ADDR_HI));
+		printk(KERN_ERR "\tAttribute      0x%08x\n",
+		       mv64x60_read(&bh, MV64x60_PCI1_ERR_DATA_LO));
+		printk(KERN_ERR "\tCommand        0x%08x\n",
+		       mv64x60_read(&bh, MV64x60_PCI1_ERR_CMD));
+		mv64x60_write(&bh, MV64x60_PCI1_ERR_CAUSE, ~val);
+	}
+	return IRQ_HANDLED;
+}
+
+static int __init
+mv64360_register_hdlrs(void)
+{
+	u32	mask;
+	int	rc;
+
+	/* Clear old errors and register CPU interface error intr handler */
+	mv64x60_write(&bh, MV64x60_CPU_ERR_CAUSE, 0);
+	if ((rc = request_irq(MV64x60_IRQ_CPU_ERR,
+		mv64360_cpu_error_int_handler, SA_INTERRUPT, CPU_INTR_STR, 0)))
+		printk(KERN_WARNING "Can't register cpu error handler: %d", rc);
+
+	mv64x60_write(&bh, MV64x60_CPU_ERR_MASK, 0);
+	mv64x60_write(&bh, MV64x60_CPU_ERR_MASK, 0x000000ff);
+
+	/* Clear old errors and register internal SRAM error intr handler */
+	mv64x60_write(&bh, MV64360_SRAM_ERR_CAUSE, 0);
+	if ((rc = request_irq(MV64360_IRQ_SRAM_PAR_ERR,
+		mv64360_sram_error_int_handler,SA_INTERRUPT,SRAM_INTR_STR, 0)))
+		printk(KERN_WARNING "Can't register SRAM error handler: %d",rc);
+
+	/*
+	 * Bit 0 reserved on 64360 and erratum FEr PCI-#11 (PCI internal
+	 * data parity error set incorrectly) on rev 0 & 1 of 64460 requires
+	 * bit 0 to be cleared.
+	 */
+	mask = 0x00a50c24;
+
+	if ((mv64x60_get_bridge_type() == MV64x60_TYPE_MV64460) &&
+		(mv64x60_get_bridge_rev() > 1))
+		mask |= 0x1;	/* enable DPErr on 64460 */
+
+	/* Clear old errors and register PCI 0 error intr handler */
+	mv64x60_write(&bh, MV64x60_PCI0_ERR_CAUSE, 0);
+	if ((rc = request_irq(MV64360_IRQ_PCI0, mv64360_pci_error_int_handler,
+			SA_INTERRUPT, PCI0_INTR_STR, (void *)0)))
+		printk(KERN_WARNING "Can't register pci 0 error handler: %d",
+			rc);
+
+	mv64x60_write(&bh, MV64x60_PCI0_ERR_MASK, 0);
+	mv64x60_write(&bh, MV64x60_PCI0_ERR_MASK, mask);
+
+	/* Clear old errors and register PCI 1 error intr handler */
+	mv64x60_write(&bh, MV64x60_PCI1_ERR_CAUSE, 0);
+	if ((rc = request_irq(MV64360_IRQ_PCI1, mv64360_pci_error_int_handler,
+			SA_INTERRUPT, PCI1_INTR_STR, (void *)1)))
+		printk(KERN_WARNING "Can't register pci 1 error handler: %d",
+			rc);
+
+	mv64x60_write(&bh, MV64x60_PCI1_ERR_MASK, 0);
+	mv64x60_write(&bh, MV64x60_PCI1_ERR_MASK, mask);
+
+	return 0;
+}
+
+arch_initcall(mv64360_register_hdlrs);
diff -Nru a/arch/ppc/syslib/mv64x60.c b/arch/ppc/syslib/mv64x60.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/ppc/syslib/mv64x60.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,2392 @@
+/*
+ * arch/ppc/syslib/mv64x60.c
+ *
+ * Common routines for the Marvell/Galileo Discovery line of host bridges
+ * (gt64260, mv64360, mv64460, ...).
+ *
+ * Author: Mark A. Greer <mgreer@mvista.com>
+ *
+ * 2004 (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/kernel.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/bootmem.h>
+#include <linux/spinlock.h>
+#include <linux/mv643xx.h>
+
+#include <asm/byteorder.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+#include <asm/machdep.h>
+#include <asm/pci-bridge.h>
+#include <asm/delay.h>
+#include <asm/mv64x60.h>
+
+
+u8		mv64x60_pci_exclude_bridge = 1;
+spinlock_t	mv64x60_lock = SPIN_LOCK_UNLOCKED;
+
+static phys_addr_t 	mv64x60_bridge_pbase = 0;
+static void 		*mv64x60_bridge_vbase = 0;
+static u32		mv64x60_bridge_type = MV64x60_TYPE_INVALID;
+static u32		mv64x60_bridge_rev = 0;
+
+static u32 gt64260_translate_size(u32 base, u32 size, u32 num_bits);
+static u32 gt64260_untranslate_size(u32 base, u32 size, u32 num_bits);
+static void gt64260_set_pci2mem_window(struct pci_controller *hose, u32 bus,
+	u32 window, u32 base);
+static void gt64260_set_pci2regs_window(struct mv64x60_handle *bh,
+	struct pci_controller *hose, u32 bus, u32 base);
+static u32 gt64260_is_enabled_32bit(struct mv64x60_handle *bh, u32 window);
+static void gt64260_enable_window_32bit(struct mv64x60_handle *bh, u32 window);
+static void gt64260_disable_window_32bit(struct mv64x60_handle *bh, u32 window);
+static void gt64260_enable_window_64bit(struct mv64x60_handle *bh, u32 window);
+static void gt64260_disable_window_64bit(struct mv64x60_handle *bh, u32 window);
+static void gt64260_disable_all_windows(struct mv64x60_handle *bh,
+	struct mv64x60_setup_info *si);
+static void gt64260a_chip_specific_init(struct mv64x60_handle *bh,
+	struct mv64x60_setup_info *si);
+static void gt64260b_chip_specific_init(struct mv64x60_handle *bh,
+	struct mv64x60_setup_info *si);
+
+static u32 mv64360_translate_size(u32 base, u32 size, u32 num_bits);
+static u32 mv64360_untranslate_size(u32 base, u32 size, u32 num_bits);
+static void mv64360_set_pci2mem_window(struct pci_controller *hose, u32 bus,
+	u32 window, u32 base);
+static void mv64360_set_pci2regs_window(struct mv64x60_handle *bh,
+	struct pci_controller *hose, u32 bus, u32 base);
+static u32 mv64360_is_enabled_32bit(struct mv64x60_handle *bh, u32 window);
+static void mv64360_enable_window_32bit(struct mv64x60_handle *bh, u32 window);
+static void mv64360_disable_window_32bit(struct mv64x60_handle *bh, u32 window);
+static void mv64360_enable_window_64bit(struct mv64x60_handle *bh, u32 window);
+static void mv64360_disable_window_64bit(struct mv64x60_handle *bh, u32 window);
+static void mv64360_disable_all_windows(struct mv64x60_handle *bh,
+	struct mv64x60_setup_info *si);
+static void mv64360_config_io2mem_windows(struct mv64x60_handle *bh,
+	struct mv64x60_setup_info *si,
+	u32 mem_windows[MV64x60_CPU2MEM_WINDOWS][2]);
+static void mv64360_set_mpsc2regs_window(struct mv64x60_handle *bh, u32 base);
+static void mv64360_chip_specific_init(struct mv64x60_handle *bh,
+	struct mv64x60_setup_info *si);
+static void mv64460_chip_specific_init(struct mv64x60_handle *bh,
+	struct mv64x60_setup_info *si);
+
+
+/*
+ * Define tables that have the chip-specific info for each type of
+ * Marvell bridge chip.
+ */
+static struct mv64x60_chip_info gt64260a_ci __initdata = { /* GT64260A */
+	.translate_size		= gt64260_translate_size,
+	.untranslate_size	= gt64260_untranslate_size,
+	.set_pci2mem_window	= gt64260_set_pci2mem_window,
+	.set_pci2regs_window	= gt64260_set_pci2regs_window,
+	.is_enabled_32bit	= gt64260_is_enabled_32bit,
+	.enable_window_32bit	= gt64260_enable_window_32bit,
+	.disable_window_32bit	= gt64260_disable_window_32bit,
+	.enable_window_64bit	= gt64260_enable_window_64bit,
+	.disable_window_64bit	= gt64260_disable_window_64bit,
+	.disable_all_windows	= gt64260_disable_all_windows,
+	.chip_specific_init	= gt64260a_chip_specific_init,
+	.window_tab_32bit	= gt64260_32bit_windows,
+	.window_tab_64bit	= gt64260_64bit_windows,
+};
+
+static struct mv64x60_chip_info gt64260b_ci __initdata = { /* GT64260B */
+	.translate_size		= gt64260_translate_size,
+	.untranslate_size	= gt64260_untranslate_size,
+	.set_pci2mem_window	= gt64260_set_pci2mem_window,
+	.set_pci2regs_window	= gt64260_set_pci2regs_window,
+	.is_enabled_32bit	= gt64260_is_enabled_32bit,
+	.enable_window_32bit	= gt64260_enable_window_32bit,
+	.disable_window_32bit	= gt64260_disable_window_32bit,
+	.enable_window_64bit	= gt64260_enable_window_64bit,
+	.disable_window_64bit	= gt64260_disable_window_64bit,
+	.disable_all_windows	= gt64260_disable_all_windows,
+	.chip_specific_init	= gt64260b_chip_specific_init,
+	.window_tab_32bit	= gt64260_32bit_windows,
+	.window_tab_64bit	= gt64260_64bit_windows,
+};
+
+static struct mv64x60_chip_info mv64360_ci __initdata = { /* MV64360 */
+	.translate_size		= mv64360_translate_size,
+	.untranslate_size	= mv64360_untranslate_size,
+	.set_pci2mem_window	= mv64360_set_pci2mem_window,
+	.set_pci2regs_window	= mv64360_set_pci2regs_window,
+	.is_enabled_32bit	= mv64360_is_enabled_32bit,
+	.enable_window_32bit	= mv64360_enable_window_32bit,
+	.disable_window_32bit	= mv64360_disable_window_32bit,
+	.enable_window_64bit	= mv64360_enable_window_64bit,
+	.disable_window_64bit	= mv64360_disable_window_64bit,
+	.disable_all_windows	= mv64360_disable_all_windows,
+	.config_io2mem_windows	= mv64360_config_io2mem_windows,
+	.set_mpsc2regs_window	= mv64360_set_mpsc2regs_window,
+	.chip_specific_init	= mv64360_chip_specific_init,
+	.window_tab_32bit	= mv64360_32bit_windows,
+	.window_tab_64bit	= mv64360_64bit_windows,
+};
+
+static struct mv64x60_chip_info mv64460_ci __initdata = { /* MV64460 */
+	.translate_size		= mv64360_translate_size,
+	.untranslate_size	= mv64360_untranslate_size,
+	.set_pci2mem_window	= mv64360_set_pci2mem_window,
+	.set_pci2regs_window	= mv64360_set_pci2regs_window,
+	.is_enabled_32bit	= mv64360_is_enabled_32bit,
+	.enable_window_32bit	= mv64360_enable_window_32bit,
+	.disable_window_32bit	= mv64360_disable_window_32bit,
+	.enable_window_64bit	= mv64360_enable_window_64bit,
+	.disable_window_64bit	= mv64360_disable_window_64bit,
+	.disable_all_windows	= mv64360_disable_all_windows,
+	.config_io2mem_windows	= mv64360_config_io2mem_windows,
+	.set_mpsc2regs_window	= mv64360_set_mpsc2regs_window,
+	.chip_specific_init	= mv64460_chip_specific_init,
+	.window_tab_32bit	= mv64360_32bit_windows,
+	.window_tab_64bit	= mv64360_64bit_windows,
+};
+
+/*
+ *****************************************************************************
+ *
+ *	Platform Device Definitions
+ *
+ *****************************************************************************
+ */
+#ifdef CONFIG_SERIAL_MPSC
+static struct mpsc_shared_pdata mv64x60_mpsc_shared_pdata = {
+	.mrr_val		= 0x3ffffe38,
+	.rcrr_val		= 0,
+	.tcrr_val		= 0,
+	.intr_cause_val		= 0,
+	.intr_mask_val		= 0,
+};
+
+static struct resource mv64x60_mpsc_shared_resources[] = {
+	/* Do not change the order of the IORESOURCE_MEM resources */
+	[0] = {
+		.name	= "mpsc routing base",
+		.start	= MV64x60_MPSC_ROUTING_OFFSET,
+		.end	= MV64x60_MPSC_ROUTING_OFFSET +
+			MPSC_ROUTING_REG_BLOCK_SIZE - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.name	= "sdma intr base",
+		.start	= MV64x60_SDMA_INTR_OFFSET,
+		.end	= MV64x60_SDMA_INTR_OFFSET +
+			MPSC_SDMA_INTR_REG_BLOCK_SIZE - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device mpsc_shared_device = { /* Shared device */
+	.name		= MPSC_SHARED_NAME,
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(mv64x60_mpsc_shared_resources),
+	.resource	= mv64x60_mpsc_shared_resources,
+	.dev = {
+		.platform_data = &mv64x60_mpsc_shared_pdata,
+	},
+};
+
+static struct mpsc_pdata mv64x60_mpsc0_pdata = {
+	.mirror_regs		= 0,
+	.cache_mgmt		= 0,
+	.max_idle		= 0,
+	.default_baud		= 9600,
+	.default_bits		= 8,
+	.default_parity		= 'n',
+	.default_flow		= 'n',
+	.chr_1_val		= 0x00000000,
+	.chr_2_val		= 0x00000000,
+	.chr_10_val		= 0x00000003,
+	.mpcr_val		= 0,
+	.bcr_val		= 0,
+	.brg_can_tune		= 0,
+	.brg_clk_src		= 8,		/* Default to TCLK */
+	.brg_clk_freq		= 100000000,	/* Default to 100 MHz */
+};
+
+static struct resource mv64x60_mpsc0_resources[] = {
+	/* Do not change the order of the IORESOURCE_MEM resources */
+	[0] = {
+		.name	= "mpsc 0 base",
+		.start	= MV64x60_MPSC_0_OFFSET,
+		.end	= MV64x60_MPSC_0_OFFSET + MPSC_REG_BLOCK_SIZE - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.name	= "sdma 0 base",
+		.start	= MV64x60_SDMA_0_OFFSET,
+		.end	= MV64x60_SDMA_0_OFFSET + MPSC_SDMA_REG_BLOCK_SIZE - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[2] = {
+		.name	= "brg 0 base",
+		.start	= MV64x60_BRG_0_OFFSET,
+		.end	= MV64x60_BRG_0_OFFSET + MPSC_BRG_REG_BLOCK_SIZE - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[3] = {
+		.name	= "sdma 0 irq",
+		.start	= MV64x60_IRQ_SDMA_0,
+		.end	= MV64x60_IRQ_SDMA_0,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device mpsc0_device = {
+	.name		= MPSC_CTLR_NAME,
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(mv64x60_mpsc0_resources),
+	.resource	= mv64x60_mpsc0_resources,
+	.dev = {
+		.platform_data = &mv64x60_mpsc0_pdata,
+	},
+};
+
+static struct mpsc_pdata mv64x60_mpsc1_pdata = {
+	.mirror_regs		= 0,
+	.cache_mgmt		= 0,
+	.max_idle		= 0,
+	.default_baud		= 9600,
+	.default_bits		= 8,
+	.default_parity		= 'n',
+	.default_flow		= 'n',
+	.chr_1_val		= 0x00000000,
+	.chr_1_val		= 0x00000000,
+	.chr_2_val		= 0x00000000,
+	.chr_10_val		= 0x00000003,
+	.mpcr_val		= 0,
+	.bcr_val		= 0,
+	.brg_can_tune		= 0,
+	.brg_clk_src		= 8,		/* Default to TCLK */
+	.brg_clk_freq		= 100000000,	/* Default to 100 MHz */
+};
+
+static struct resource mv64x60_mpsc1_resources[] = {
+	/* Do not change the order of the IORESOURCE_MEM resources */
+	[0] = {
+		.name	= "mpsc 1 base",
+		.start	= MV64x60_MPSC_1_OFFSET,
+		.end	= MV64x60_MPSC_1_OFFSET + MPSC_REG_BLOCK_SIZE - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.name	= "sdma 1 base",
+		.start	= MV64x60_SDMA_1_OFFSET,
+		.end	= MV64x60_SDMA_1_OFFSET + MPSC_SDMA_REG_BLOCK_SIZE - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[2] = {
+		.name	= "brg 1 base",
+		.start	= MV64x60_BRG_1_OFFSET,
+		.end	= MV64x60_BRG_1_OFFSET + MPSC_BRG_REG_BLOCK_SIZE - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[3] = {
+		.name	= "sdma 1 irq",
+		.start	= MV64360_IRQ_SDMA_1,
+		.end	= MV64360_IRQ_SDMA_1,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device mpsc1_device = {
+	.name		= MPSC_CTLR_NAME,
+	.id		= 1,
+	.num_resources	= ARRAY_SIZE(mv64x60_mpsc1_resources),
+	.resource	= mv64x60_mpsc1_resources,
+	.dev = {
+		.platform_data = &mv64x60_mpsc1_pdata,
+	},
+};
+#endif
+
+#ifdef CONFIG_MV643XX_ETH
+static struct resource mv64x60_eth_shared_resources[] = {
+	[0] = {
+		.name	= "ethernet shared base",
+		.start	= MV64340_ETH_SHARED_REGS,
+		.end	= MV64340_ETH_SHARED_REGS +
+					MV64340_ETH_SHARED_REGS_SIZE - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device mv64x60_eth_shared_device = {
+	.name		= MV64XXX_ETH_SHARED_NAME,
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(mv64x60_eth_shared_resources),
+	.resource	= mv64x60_eth_shared_resources,
+};
+
+#ifdef CONFIG_MV643XX_ETH_0
+static struct resource mv64x60_eth0_resources[] = {
+	[0] = {
+		.name	= "eth0 irq",
+		.start	= MV64x60_IRQ_ETH_0,
+		.end	= MV64x60_IRQ_ETH_0,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct mv64xxx_eth_platform_data eth0_pd;
+
+static struct platform_device eth0_device = {
+	.name		= MV64XXX_ETH_NAME,
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(mv64x60_eth0_resources),
+	.resource	= mv64x60_eth0_resources,
+	.dev = {
+		.platform_data = &eth0_pd,
+	},
+};
+#endif
+
+#ifdef CONFIG_MV643XX_ETH_1
+static struct resource mv64x60_eth1_resources[] = {
+	[0] = {
+		.name	= "eth1 irq",
+		.start	= MV64x60_IRQ_ETH_1,
+		.end	= MV64x60_IRQ_ETH_1,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct mv64xxx_eth_platform_data eth1_pd;
+
+static struct platform_device eth1_device = {
+	.name		= MV64XXX_ETH_NAME,
+	.id		= 1,
+	.num_resources	= ARRAY_SIZE(mv64x60_eth1_resources),
+	.resource	= mv64x60_eth1_resources,
+	.dev = {
+		.platform_data = &eth1_pd,
+	},
+};
+#endif
+
+#ifdef CONFIG_MV643XX_ETH_2
+static struct resource mv64x60_eth2_resources[] = {
+	[0] = {
+		.name	= "eth2 irq",
+		.start	= MV64x60_IRQ_ETH_2,
+		.end	= MV64x60_IRQ_ETH_2,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct mv64xxx_eth_platform_data eth2_pd;
+
+static struct platform_device eth2_device = {
+	.name		= MV64XXX_ETH_NAME,
+	.id		= 2,
+	.num_resources	= ARRAY_SIZE(mv64x60_eth2_resources),
+	.resource	= mv64x60_eth2_resources,
+	.dev = {
+		.platform_data = &eth2_pd,
+	},
+};
+#endif
+#endif
+
+#ifdef	CONFIG_I2C_MV64XXX
+static struct mv64xxx_i2c_pdata mv64xxx_i2c_pdata = {
+	.freq_m			= 8,
+	.freq_n			= 3,
+	.timeout		= 1000, /* Default timeout of 1 second */
+	.retries		= 1,
+};
+
+static struct resource mv64xxx_i2c_resources[] = {
+	/* Do not change the order of the IORESOURCE_MEM resources */
+	[0] = {
+		.name	= "mv64xxx i2c base",
+		.start	= MV64XXX_I2C_OFFSET,
+		.end	= MV64XXX_I2C_OFFSET + MV64XXX_I2C_REG_BLOCK_SIZE - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.name	= "mv64xxx i2c irq",
+		.start	= MV64x60_IRQ_I2C,
+		.end	= MV64x60_IRQ_I2C,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device i2c_device = {
+	.name		= MV64XXX_I2C_CTLR_NAME,
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(mv64xxx_i2c_resources),
+	.resource	= mv64xxx_i2c_resources,
+	.dev = {
+		.platform_data = &mv64xxx_i2c_pdata,
+	},
+};
+#endif
+
+static struct platform_device *mv64x60_pd_devs[] __initdata = {
+#ifdef CONFIG_SERIAL_MPSC
+	&mpsc_shared_device,
+	&mpsc0_device,
+	&mpsc1_device,
+#endif
+#ifdef CONFIG_MV643XX_ETH
+	&mv64x60_eth_shared_device,
+#endif
+#ifdef CONFIG_MV643XX_ETH_0
+	&eth0_device,
+#endif
+#ifdef CONFIG_MV643XX_ETH_1
+	&eth1_device,
+#endif
+#ifdef CONFIG_MV643XX_ETH_2
+	&eth2_device,
+#endif
+#ifdef	CONFIG_I2C_MV64XXX
+	&i2c_device,
+#endif
+};
+
+/*
+ *****************************************************************************
+ *
+ *	Bridge Initialization Routines
+ *
+ *****************************************************************************
+ */
+/*
+ * mv64x60_init()
+ *
+ * Initialze the bridge based on setting passed in via 'si'.  The bridge
+ * handle, 'bh', will be set so that it can be used to make subsequent
+ * calls to routines in this file.
+ */
+int __init
+mv64x60_init(struct mv64x60_handle *bh, struct mv64x60_setup_info *si)
+{
+	u32	mem_windows[MV64x60_CPU2MEM_WINDOWS][2];
+
+	if (ppc_md.progress)
+		ppc_md.progress("mv64x60 initialization", 0x0);
+
+	spin_lock_init(&mv64x60_lock);
+	mv64x60_early_init(bh, si);
+
+	if (mv64x60_get_type(bh) || mv64x60_setup_for_chip(bh)) {
+		iounmap(bh->v_base);
+		bh->v_base = 0;
+		if (ppc_md.progress)
+			ppc_md.progress("mv64x60_init: Can't determine chip",0);
+		return -1;
+	}
+
+	bh->ci->disable_all_windows(bh, si);
+	mv64x60_get_mem_windows(bh, mem_windows);
+	mv64x60_config_cpu2mem_windows(bh, si, mem_windows);
+
+	if (bh->ci->config_io2mem_windows)
+		bh->ci->config_io2mem_windows(bh, si, mem_windows);
+	if (bh->ci->set_mpsc2regs_window)
+		bh->ci->set_mpsc2regs_window(bh, si->phys_reg_base);
+
+	if (si->pci_1.enable_bus) {
+		bh->io_base_b = (u32)ioremap(si->pci_1.pci_io.cpu_base,
+			si->pci_1.pci_io.size);
+		isa_io_base = bh->io_base_b;
+	}
+
+	if (si->pci_0.enable_bus) {
+		bh->io_base_a = (u32)ioremap(si->pci_0.pci_io.cpu_base,
+			si->pci_0.pci_io.size);
+		isa_io_base = bh->io_base_a;
+
+		mv64x60_alloc_hose(bh, MV64x60_PCI0_CONFIG_ADDR,
+			MV64x60_PCI0_CONFIG_DATA, &bh->hose_a);
+		mv64x60_config_resources(bh->hose_a, &si->pci_0, bh->io_base_a);
+		mv64x60_config_pci_params(bh->hose_a, &si->pci_0);
+
+		mv64x60_config_cpu2pci_windows(bh, &si->pci_0, 0);
+		mv64x60_config_pci2mem_windows(bh, bh->hose_a, &si->pci_0, 0,
+			mem_windows);
+		bh->ci->set_pci2regs_window(bh, bh->hose_a, 0,
+			si->phys_reg_base);
+	}
+
+	if (si->pci_1.enable_bus) {
+		mv64x60_alloc_hose(bh, MV64x60_PCI1_CONFIG_ADDR,
+			MV64x60_PCI1_CONFIG_DATA, &bh->hose_b);
+		mv64x60_config_resources(bh->hose_b, &si->pci_1, bh->io_base_b);
+		mv64x60_config_pci_params(bh->hose_b, &si->pci_1);
+
+		mv64x60_config_cpu2pci_windows(bh, &si->pci_1, 1);
+		mv64x60_config_pci2mem_windows(bh, bh->hose_b, &si->pci_1, 1,
+			mem_windows);
+		bh->ci->set_pci2regs_window(bh, bh->hose_b, 1,
+			si->phys_reg_base);
+	}
+
+	bh->ci->chip_specific_init(bh, si);
+	mv64x60_pd_fixup(bh, mv64x60_pd_devs, ARRAY_SIZE(mv64x60_pd_devs));
+
+	return 0;
+}
+
+/*
+ * mv64x60_early_init()
+ *
+ * Do some bridge work that must take place before we start messing with
+ * the bridge for real.
+ */
+void __init
+mv64x60_early_init(struct mv64x60_handle *bh, struct mv64x60_setup_info *si)
+{
+	struct pci_controller	hose_a, hose_b;
+
+	memset(bh, 0, sizeof(*bh));
+
+	bh->p_base = si->phys_reg_base;
+	bh->v_base = ioremap(bh->p_base, MV64x60_INTERNAL_SPACE_SIZE);
+
+	mv64x60_bridge_pbase = bh->p_base;
+	mv64x60_bridge_vbase = bh->v_base;
+
+	/* Assuming pci mode [reserved] bits 4:5 on 64260 are 0 */
+	bh->pci_mode_a = mv64x60_read(bh, MV64x60_PCI0_MODE) &
+		MV64x60_PCIMODE_MASK;
+	bh->pci_mode_b = mv64x60_read(bh, MV64x60_PCI1_MODE) &
+		MV64x60_PCIMODE_MASK;
+
+	/* Need temporary hose structs to call mv64x60_set_bus() */
+	memset(&hose_a, 0, sizeof(hose_a));
+	memset(&hose_b, 0, sizeof(hose_b));
+	setup_indirect_pci_nomap(&hose_a, bh->v_base + MV64x60_PCI0_CONFIG_ADDR,
+		bh->v_base + MV64x60_PCI0_CONFIG_DATA);
+	setup_indirect_pci_nomap(&hose_b, bh->v_base + MV64x60_PCI1_CONFIG_ADDR,
+		bh->v_base + MV64x60_PCI1_CONFIG_DATA);
+	bh->hose_a = &hose_a;
+	bh->hose_b = &hose_b;
+
+	mv64x60_set_bus(bh, 0, 0);
+	mv64x60_set_bus(bh, 1, 0);
+
+	bh->hose_a = NULL;
+	bh->hose_b = NULL;
+
+	/* Clear bit 0 of PCI addr decode control so PCI->CPU remap 1:1 */
+	mv64x60_clr_bits(bh, MV64x60_PCI0_PCI_DECODE_CNTL, 0x00000001);
+	mv64x60_clr_bits(bh, MV64x60_PCI1_PCI_DECODE_CNTL, 0x00000001);
+
+	/* Bit 12 MUST be 0; set bit 27--don't auto-update cpu remap regs */
+	mv64x60_clr_bits(bh, MV64x60_CPU_CONFIG, (1<<12));
+	mv64x60_set_bits(bh, MV64x60_CPU_CONFIG, (1<<27));
+
+	mv64x60_set_bits(bh, MV64x60_PCI0_TO_RETRY, 0xffff);
+	mv64x60_set_bits(bh, MV64x60_PCI1_TO_RETRY, 0xffff);
+
+	return;
+}
+
+/*
+ *****************************************************************************
+ *
+ *	Window Config Routines
+ *
+ *****************************************************************************
+ */
+/*
+ * mv64x60_get_32bit_window()
+ *
+ * Determine the base address and size of a 32-bit window on the bridge.
+ */
+void __init
+mv64x60_get_32bit_window(struct mv64x60_handle *bh, u32 window,
+	u32 *base, u32 *size)
+{
+	u32	val, base_reg, size_reg, base_bits, size_bits;
+	u32	(*get_from_field)(u32 val, u32 num_bits);
+
+	base_reg = bh->ci->window_tab_32bit[window].base_reg;
+
+	if (base_reg != 0) {
+		size_reg  = bh->ci->window_tab_32bit[window].size_reg;
+		base_bits = bh->ci->window_tab_32bit[window].base_bits;
+		size_bits = bh->ci->window_tab_32bit[window].size_bits;
+		get_from_field= bh->ci->window_tab_32bit[window].get_from_field;
+
+		val = mv64x60_read(bh, base_reg);
+		*base = get_from_field(val, base_bits);
+
+		if (size_reg != 0) {
+			val = mv64x60_read(bh, size_reg);
+			val = get_from_field(val, size_bits);
+			*size = bh->ci->untranslate_size(*base, val, size_bits);
+		}
+		else
+			*size = 0;
+	}
+	else {
+		*base = 0;
+		*size = 0;
+	}
+
+	pr_debug("get 32bit window: %d, base: 0x%x, size: 0x%x\n",
+		window, *base, *size);
+
+	return;
+}
+
+/*
+ * mv64x60_set_32bit_window()
+ *
+ * Set the base address and size of a 32-bit window on the bridge.
+ */
+void __init
+mv64x60_set_32bit_window(struct mv64x60_handle *bh, u32 window,
+	u32 base, u32 size, u32 other_bits)
+{
+	u32	val, base_reg, size_reg, base_bits, size_bits;
+	u32	(*map_to_field)(u32 val, u32 num_bits);
+
+	pr_debug("set 32bit window: %d, base: 0x%x, size: 0x%x, other: 0x%x\n",
+		window, base, size, other_bits);
+
+	base_reg = bh->ci->window_tab_32bit[window].base_reg;
+
+	if (base_reg != 0) {
+		size_reg  = bh->ci->window_tab_32bit[window].size_reg;
+		base_bits = bh->ci->window_tab_32bit[window].base_bits;
+		size_bits = bh->ci->window_tab_32bit[window].size_bits;
+		map_to_field = bh->ci->window_tab_32bit[window].map_to_field;
+
+		val = map_to_field(base, base_bits) | other_bits;
+		mv64x60_write(bh, base_reg, val);
+
+		if (size_reg != 0) {
+			val = bh->ci->translate_size(base, size, size_bits);
+			val = map_to_field(val, size_bits);
+			mv64x60_write(bh, size_reg, val);
+		}
+
+		(void)mv64x60_read(bh, base_reg); /* Flush FIFO */
+	}
+
+	return;
+}
+
+/*
+ * mv64x60_get_64bit_window()
+ *
+ * Determine the base address and size of a 64-bit window on the bridge.
+ */
+void __init
+mv64x60_get_64bit_window(struct mv64x60_handle *bh, u32 window,
+	u32 *base_hi, u32 *base_lo, u32 *size)
+{
+	u32	val, base_lo_reg, size_reg, base_lo_bits, size_bits;
+	u32	(*get_from_field)(u32 val, u32 num_bits);
+
+	base_lo_reg = bh->ci->window_tab_64bit[window].base_lo_reg;
+
+	if (base_lo_reg != 0) {
+		size_reg = bh->ci->window_tab_64bit[window].size_reg;
+		base_lo_bits = bh->ci->window_tab_64bit[window].base_lo_bits;
+		size_bits = bh->ci->window_tab_64bit[window].size_bits;
+		get_from_field= bh->ci->window_tab_64bit[window].get_from_field;
+
+		*base_hi = mv64x60_read(bh,
+			bh->ci->window_tab_64bit[window].base_hi_reg);
+
+		val = mv64x60_read(bh, base_lo_reg);
+		*base_lo = get_from_field(val, base_lo_bits);
+
+		if (size_reg != 0) {
+			val = mv64x60_read(bh, size_reg);
+			val = get_from_field(val, size_bits);
+			*size = bh->ci->untranslate_size(*base_lo, val,
+								size_bits);
+		}
+		else
+			*size = 0;
+	}
+	else {
+		*base_hi = 0;
+		*base_lo = 0;
+		*size = 0;
+	}
+
+	pr_debug("get 64bit window: %d, base hi: 0x%x, base lo: 0x%x, "
+		"size: 0x%x\n", window, *base_hi, *base_lo, *size);
+
+	return;
+}
+
+/*
+ * mv64x60_set_64bit_window()
+ *
+ * Set the base address and size of a 64-bit window on the bridge.
+ */
+void __init
+mv64x60_set_64bit_window(struct mv64x60_handle *bh, u32 window,
+	u32 base_hi, u32 base_lo, u32 size, u32 other_bits)
+{
+	u32	val, base_lo_reg, size_reg, base_lo_bits, size_bits;
+	u32	(*map_to_field)(u32 val, u32 num_bits);
+
+	pr_debug("set 64bit window: %d, base hi: 0x%x, base lo: 0x%x, "
+		"size: 0x%x, other: 0x%x\n",
+		window, base_hi, base_lo, size, other_bits);
+
+	base_lo_reg = bh->ci->window_tab_64bit[window].base_lo_reg;
+
+	if (base_lo_reg != 0) {
+		size_reg = bh->ci->window_tab_64bit[window].size_reg;
+		base_lo_bits = bh->ci->window_tab_64bit[window].base_lo_bits;
+		size_bits = bh->ci->window_tab_64bit[window].size_bits;
+		map_to_field = bh->ci->window_tab_64bit[window].map_to_field;
+
+		mv64x60_write(bh, bh->ci->window_tab_64bit[window].base_hi_reg,
+			base_hi);
+
+		val = map_to_field(base_lo, base_lo_bits) | other_bits;
+		mv64x60_write(bh, base_lo_reg, val);
+
+		if (size_reg != 0) {
+			val = bh->ci->translate_size(base_lo, size, size_bits);
+			val = map_to_field(val, size_bits);
+			mv64x60_write(bh, size_reg, val);
+		}
+
+		(void)mv64x60_read(bh, base_lo_reg); /* Flush FIFO */
+	}
+
+	return;
+}
+
+/*
+ * mv64x60_mask()
+ *
+ * Take the high-order 'num_bits' of 'val' & mask off low bits.
+ */
+u32 __init
+mv64x60_mask(u32 val, u32 num_bits)
+{
+	return val & (0xffffffff << (32 - num_bits));
+}
+
+/*
+ * mv64x60_shift_left()
+ *
+ * Take the low-order 'num_bits' of 'val', shift left to align at bit 31 (MSB).
+ */
+u32 __init
+mv64x60_shift_left(u32 val, u32 num_bits)
+{
+	return val << (32 - num_bits);
+}
+
+/*
+ * mv64x60_shift_right()
+ *
+ * Take the high-order 'num_bits' of 'val', shift right to align at bit 0 (LSB).
+ */
+u32 __init
+mv64x60_shift_right(u32 val, u32 num_bits)
+{
+	return val >> (32 - num_bits);
+}
+
+/*
+ *****************************************************************************
+ *
+ *	Chip Identification Routines
+ *
+ *****************************************************************************
+ */
+/*
+ * mv64x60_get_type()
+ *
+ * Determine the type of bridge chip we have.
+ */
+int __init
+mv64x60_get_type(struct mv64x60_handle *bh)
+{
+	struct pci_controller hose;
+	u16	val;
+	u8	save_exclude;
+
+	memset(&hose, 0, sizeof(hose));
+	setup_indirect_pci_nomap(&hose, bh->v_base + MV64x60_PCI0_CONFIG_ADDR,
+		bh->v_base + MV64x60_PCI0_CONFIG_DATA);
+
+	save_exclude = mv64x60_pci_exclude_bridge;
+	mv64x60_pci_exclude_bridge = 0;
+	/* Sanity check of bridge's Vendor ID */
+	early_read_config_word(&hose, 0, PCI_DEVFN(0, 0), PCI_VENDOR_ID, &val);
+
+	if (val != PCI_VENDOR_ID_MARVELL) {
+		mv64x60_pci_exclude_bridge = save_exclude;
+		return -1;
+	}
+
+	/* Get the revision of the chip */
+	early_read_config_word(&hose, 0, PCI_DEVFN(0, 0), PCI_CLASS_REVISION,
+		&val);
+	bh->rev = (u32)(val & 0xff);
+
+	/* Figure out the type of Marvell bridge it is */
+	early_read_config_word(&hose, 0, PCI_DEVFN(0, 0), PCI_DEVICE_ID, &val);
+	mv64x60_pci_exclude_bridge = save_exclude;
+
+	switch (val) {
+	case PCI_DEVICE_ID_MARVELL_GT64260:
+		switch (bh->rev) {
+		case GT64260_REV_A:
+			bh->type = MV64x60_TYPE_GT64260A;
+			break;
+
+		default:
+			printk(KERN_WARNING "Unsupported GT64260 rev %04x\n",
+				bh->rev);
+			/* Assume its similar to a 'B' rev and fallthru */
+		case GT64260_REV_B:
+			bh->type = MV64x60_TYPE_GT64260B;
+			break;
+		}
+		break;
+
+	case PCI_DEVICE_ID_MARVELL_MV64360:
+		/* Marvell won't tell me how to distinguish a 64361 & 64362 */
+		bh->type = MV64x60_TYPE_MV64360;
+		break;
+
+	case PCI_DEVICE_ID_MARVELL_MV64460:
+		bh->type = MV64x60_TYPE_MV64460;
+		break;
+
+	default:
+		printk(KERN_ERR "Unknown Marvell bridge type %04x\n", val);
+		return -1;
+	}
+
+	/* Hang onto bridge type & rev for PIC code */
+	mv64x60_bridge_type = bh->type;
+	mv64x60_bridge_rev = bh->rev;
+
+	return 0;
+}
+
+/*
+ * mv64x60_setup_for_chip()
+ *
+ * Set 'bh' to use the proper set of routine for the bridge chip that we have.
+ */
+int __init
+mv64x60_setup_for_chip(struct mv64x60_handle *bh)
+{
+	int	rc = 0;
+
+	/* Set up chip-specific info based on the chip/bridge type */
+	switch(bh->type) {
+	case MV64x60_TYPE_GT64260A:
+		bh->ci = &gt64260a_ci;
+		break;
+
+	case MV64x60_TYPE_GT64260B:
+		bh->ci = &gt64260b_ci;
+		break;
+
+	case MV64x60_TYPE_MV64360:
+		bh->ci = &mv64360_ci;
+		break;
+
+	case MV64x60_TYPE_MV64460:
+		bh->ci = &mv64460_ci;
+		break;
+
+	case MV64x60_TYPE_INVALID:
+	default:
+		if (ppc_md.progress)
+			ppc_md.progress("mv64x60: Unsupported bridge", 0x0);
+		printk(KERN_ERR "mv64x60: Unsupported bridge\n");
+		rc = -1;
+	}
+
+	return rc;
+}
+
+/*
+ * mv64x60_get_bridge_vbase()
+ *
+ * Return the virtual address of the bridge's registers.
+ */
+void *
+mv64x60_get_bridge_vbase(void)
+{
+	return mv64x60_bridge_vbase;
+}
+
+/*
+ * mv64x60_get_bridge_type()
+ *
+ * Return the type of bridge on the platform.
+ */
+u32
+mv64x60_get_bridge_type(void)
+{
+	return mv64x60_bridge_type;
+}
+
+/*
+ * mv64x60_get_bridge_rev()
+ *
+ * Return the revision of the bridge on the platform.
+ */
+u32
+mv64x60_get_bridge_rev(void)
+{
+	return mv64x60_bridge_rev;
+}
+
+/*
+ *****************************************************************************
+ *
+ *	System Memory Window Related Routines
+ *
+ *****************************************************************************
+ */
+/*
+ * mv64x60_get_mem_size()
+ *
+ * Calculate the amount of memory that the memory controller is set up for.
+ * This should only be used by board-specific code if there is no other
+ * way to determine the amount of memory in the system.
+ */
+u32 __init
+mv64x60_get_mem_size(u32 bridge_base, u32 chip_type)
+{
+	struct mv64x60_handle	bh;
+	u32	mem_windows[MV64x60_CPU2MEM_WINDOWS][2];
+	u32	rc = 0;
+
+	memset(&bh, 0, sizeof(bh));
+
+	bh.type = chip_type;
+	bh.v_base = (void *)bridge_base;
+
+	if (!mv64x60_setup_for_chip(&bh)) {
+		mv64x60_get_mem_windows(&bh, mem_windows);
+		rc = mv64x60_calc_mem_size(&bh, mem_windows);
+	}
+
+	return rc;
+}
+
+/*
+ * mv64x60_get_mem_windows()
+ *
+ * Get the values in the memory controller & return in the 'mem_windows' array.
+ */
+void __init
+mv64x60_get_mem_windows(struct mv64x60_handle *bh,
+	u32 mem_windows[MV64x60_CPU2MEM_WINDOWS][2])
+{
+	u32	i, win;
+
+	for (win=MV64x60_CPU2MEM_0_WIN,i=0;win<=MV64x60_CPU2MEM_3_WIN;win++,i++)
+		if (bh->ci->is_enabled_32bit(bh, win))
+			mv64x60_get_32bit_window(bh, win,
+				&mem_windows[i][0], &mem_windows[i][1]);
+		else {
+			mem_windows[i][0] = 0;
+			mem_windows[i][1] = 0;
+		}
+
+	return;
+}
+
+/*
+ * mv64x60_calc_mem_size()
+ *
+ * Using the memory controller register values in 'mem_windows', determine
+ * how much memory it is set up for.
+ */
+u32 __init
+mv64x60_calc_mem_size(struct mv64x60_handle *bh,
+	u32 mem_windows[MV64x60_CPU2MEM_WINDOWS][2])
+{
+	u32	i, total = 0;
+
+	for (i=0; i<MV64x60_CPU2MEM_WINDOWS; i++)
+		total += mem_windows[i][1];
+
+	return total;
+}
+
+/*
+ *****************************************************************************
+ *
+ *	CPU->System MEM, PCI Config Routines
+ *
+ *****************************************************************************
+ */
+/*
+ * mv64x60_config_cpu2mem_windows()
+ *
+ * Configure CPU->Memory windows on the bridge.
+ */
+static u32 prot_tab[] __initdata = {
+	MV64x60_CPU_PROT_0_WIN, MV64x60_CPU_PROT_1_WIN,
+	MV64x60_CPU_PROT_2_WIN, MV64x60_CPU_PROT_3_WIN
+};
+
+static u32 cpu_snoop_tab[] __initdata = {
+	MV64x60_CPU_SNOOP_0_WIN, MV64x60_CPU_SNOOP_1_WIN,
+	MV64x60_CPU_SNOOP_2_WIN, MV64x60_CPU_SNOOP_3_WIN
+};
+
+void __init
+mv64x60_config_cpu2mem_windows(struct mv64x60_handle *bh,
+	struct mv64x60_setup_info *si,
+	u32 mem_windows[MV64x60_CPU2MEM_WINDOWS][2])
+{
+	u32	i, win;
+
+	/* Set CPU protection & snoop windows */
+	for (win=MV64x60_CPU2MEM_0_WIN,i=0;win<=MV64x60_CPU2MEM_3_WIN;win++,i++)
+		if (bh->ci->is_enabled_32bit(bh, win)) {
+			mv64x60_set_32bit_window(bh, prot_tab[i],
+				mem_windows[i][0], mem_windows[i][1],
+				si->cpu_prot_options[i]);
+			bh->ci->enable_window_32bit(bh, prot_tab[i]);
+
+			if (bh->ci->window_tab_32bit[cpu_snoop_tab[i]].
+								base_reg != 0) {
+				mv64x60_set_32bit_window(bh, cpu_snoop_tab[i],
+					mem_windows[i][0], mem_windows[i][1],
+					si->cpu_snoop_options[i]);
+				bh->ci->enable_window_32bit(bh,
+					cpu_snoop_tab[i]);
+			}
+
+		}
+
+	return;
+}
+
+/*
+ * mv64x60_config_cpu2pci_windows()
+ *
+ * Configure the CPU->PCI windows for one of the PCI buses.
+ */
+static u32 win_tab[2][4] __initdata = {
+	{ MV64x60_CPU2PCI0_IO_WIN, MV64x60_CPU2PCI0_MEM_0_WIN,
+	  MV64x60_CPU2PCI0_MEM_1_WIN, MV64x60_CPU2PCI0_MEM_2_WIN },
+	{ MV64x60_CPU2PCI1_IO_WIN, MV64x60_CPU2PCI1_MEM_0_WIN,
+	  MV64x60_CPU2PCI1_MEM_1_WIN, MV64x60_CPU2PCI1_MEM_2_WIN },
+};
+
+static u32 remap_tab[2][4] __initdata = {
+	{ MV64x60_CPU2PCI0_IO_REMAP_WIN, MV64x60_CPU2PCI0_MEM_0_REMAP_WIN,
+	  MV64x60_CPU2PCI0_MEM_1_REMAP_WIN, MV64x60_CPU2PCI0_MEM_2_REMAP_WIN },
+	{ MV64x60_CPU2PCI1_IO_REMAP_WIN, MV64x60_CPU2PCI1_MEM_0_REMAP_WIN,
+	  MV64x60_CPU2PCI1_MEM_1_REMAP_WIN, MV64x60_CPU2PCI1_MEM_2_REMAP_WIN }
+};
+
+void __init
+mv64x60_config_cpu2pci_windows(struct mv64x60_handle *bh,
+	struct mv64x60_pci_info *pi, u32 bus)
+{
+	int	i;
+
+	if (pi->pci_io.size > 0) {
+		mv64x60_set_32bit_window(bh, win_tab[bus][0],
+			pi->pci_io.cpu_base, pi->pci_io.size, pi->pci_io.swap);
+		mv64x60_set_32bit_window(bh, remap_tab[bus][0],
+			pi->pci_io.pci_base_lo, 0, 0);
+		bh->ci->enable_window_32bit(bh, win_tab[bus][0]);
+	}
+	else /* Actually, the window should already be disabled */
+		bh->ci->disable_window_32bit(bh, win_tab[bus][0]);
+
+	for (i=0; i<3; i++)
+		if (pi->pci_mem[i].size > 0) {
+			mv64x60_set_32bit_window(bh, win_tab[bus][i+1],
+				pi->pci_mem[i].cpu_base, pi->pci_mem[i].size,
+				pi->pci_mem[i].swap);
+			mv64x60_set_64bit_window(bh, remap_tab[bus][i+1],
+				pi->pci_mem[i].pci_base_hi,
+				pi->pci_mem[i].pci_base_lo, 0, 0);
+			bh->ci->enable_window_32bit(bh, win_tab[bus][i+1]);
+		}
+		else /* Actually, the window should already be disabled */
+			bh->ci->disable_window_32bit(bh, win_tab[bus][i+1]);
+
+	return;
+}
+
+/*
+ *****************************************************************************
+ *
+ *	PCI->System MEM Config Routines
+ *
+ *****************************************************************************
+ */
+/*
+ * mv64x60_config_pci2mem_windows()
+ *
+ * Configure the PCI->Memory windows on the bridge.
+ */
+static u32 pci_acc_tab[2][4] __initdata = {
+	{ MV64x60_PCI02MEM_ACC_CNTL_0_WIN, MV64x60_PCI02MEM_ACC_CNTL_1_WIN,
+	  MV64x60_PCI02MEM_ACC_CNTL_2_WIN, MV64x60_PCI02MEM_ACC_CNTL_3_WIN },
+	{ MV64x60_PCI12MEM_ACC_CNTL_0_WIN, MV64x60_PCI12MEM_ACC_CNTL_1_WIN,
+	  MV64x60_PCI12MEM_ACC_CNTL_2_WIN, MV64x60_PCI12MEM_ACC_CNTL_3_WIN }
+};
+
+static u32 pci_snoop_tab[2][4] __initdata = {
+	{ MV64x60_PCI02MEM_SNOOP_0_WIN, MV64x60_PCI02MEM_SNOOP_1_WIN,
+	  MV64x60_PCI02MEM_SNOOP_2_WIN, MV64x60_PCI02MEM_SNOOP_3_WIN },
+	{ MV64x60_PCI12MEM_SNOOP_0_WIN, MV64x60_PCI12MEM_SNOOP_1_WIN,
+	  MV64x60_PCI12MEM_SNOOP_2_WIN, MV64x60_PCI12MEM_SNOOP_3_WIN }
+};
+
+static u32 pci_size_tab[2][4] __initdata = {
+	{ MV64x60_PCI0_MEM_0_SIZE, MV64x60_PCI0_MEM_1_SIZE,
+	  MV64x60_PCI0_MEM_2_SIZE, MV64x60_PCI0_MEM_3_SIZE },
+	{ MV64x60_PCI1_MEM_0_SIZE, MV64x60_PCI1_MEM_1_SIZE,
+	  MV64x60_PCI1_MEM_2_SIZE, MV64x60_PCI1_MEM_3_SIZE }
+};
+
+void __init
+mv64x60_config_pci2mem_windows(struct mv64x60_handle *bh,
+	struct pci_controller *hose, struct mv64x60_pci_info *pi,
+	u32 bus, u32 mem_windows[MV64x60_CPU2MEM_WINDOWS][2])
+{
+	u32	i, win;
+
+	/*
+	 * Set the access control, snoop, BAR size, and window base addresses.
+	 * PCI->MEM windows base addresses will match exactly what the
+	 * CPU->MEM windows are.
+	 */
+	for (win=MV64x60_CPU2MEM_0_WIN,i=0;win<=MV64x60_CPU2MEM_3_WIN;win++,i++)
+		if (bh->ci->is_enabled_32bit(bh, win)) {
+			mv64x60_set_64bit_window(bh,
+				pci_acc_tab[bus][i], 0,
+				mem_windows[i][0], mem_windows[i][1],
+				pi->acc_cntl_options[i]);
+			bh->ci->enable_window_64bit(bh, pci_acc_tab[bus][i]);
+
+			if (bh->ci->window_tab_64bit[
+				pci_snoop_tab[bus][i]].base_lo_reg != 0) {
+
+				mv64x60_set_64bit_window(bh,
+					pci_snoop_tab[bus][i], 0,
+					mem_windows[i][0], mem_windows[i][1],
+					pi->snoop_options[i]);
+				bh->ci->enable_window_64bit(bh,
+					pci_snoop_tab[bus][i]);
+			}
+
+			bh->ci->set_pci2mem_window(hose, bus, i,
+				mem_windows[i][0]);
+			mv64x60_write(bh, pci_size_tab[bus][i],
+				mv64x60_mask(mem_windows[i][1] - 1, 20));
+
+			/* Enable the window */
+			mv64x60_clr_bits(bh, ((bus == 0) ?
+				MV64x60_PCI0_BAR_ENABLE :
+				MV64x60_PCI1_BAR_ENABLE), (1 << i));
+		}
+
+	return;
+}
+
+/*
+ *****************************************************************************
+ *
+ *	Hose & Resource Alloc/Init Routines
+ *
+ *****************************************************************************
+ */
+/*
+ * mv64x60_alloc_hoses()
+ *
+ * Allocate the PCI hose structures for the bridge's PCI buses.
+ */
+void __init
+mv64x60_alloc_hose(struct mv64x60_handle *bh, u32 cfg_addr, u32 cfg_data,
+	struct pci_controller **hose)
+{
+	*hose = pcibios_alloc_controller();
+	setup_indirect_pci_nomap(*hose, bh->v_base + cfg_addr,
+		bh->v_base + cfg_data);
+	return;
+}
+
+/*
+ * mv64x60_config_resources()
+ *
+ * Calculate the offsets, etc. for the hose structures to reflect all of
+ * the address remapping that happens as you go from CPU->PCI and PCI->MEM.
+ */
+void __init
+mv64x60_config_resources(struct pci_controller *hose,
+	struct mv64x60_pci_info *pi, u32 io_base)
+{
+	int		i;
+	/* 2 hoses; 4 resources/hose; string <= 64 bytes */
+	static char	s[2][4][64];
+
+	if (pi->pci_io.size != 0) {
+		sprintf(s[hose->index][0], "PCI hose %d I/O Space",
+			hose->index);
+		pci_init_resource(&hose->io_resource, io_base - isa_io_base,
+			io_base - isa_io_base + pi->pci_io.size - 1,
+			IORESOURCE_IO, s[hose->index][0]);
+		hose->io_space.start = pi->pci_io.pci_base_lo;
+		hose->io_space.end = pi->pci_io.pci_base_lo + pi->pci_io.size-1;
+		hose->io_base_phys = pi->pci_io.cpu_base;
+		hose->io_base_virt = (void *)isa_io_base;
+	}
+
+	for (i=0; i<3; i++)
+		if (pi->pci_mem[i].size != 0) {
+			sprintf(s[hose->index][i+1], "PCI hose %d MEM Space %d",
+				hose->index, i);
+			pci_init_resource(&hose->mem_resources[i],
+				pi->pci_mem[i].cpu_base,
+				pi->pci_mem[i].cpu_base + pi->pci_mem[i].size-1,
+				IORESOURCE_MEM, s[hose->index][i+1]);
+		}
+
+	hose->mem_space.end = pi->pci_mem[0].pci_base_lo +
+						pi->pci_mem[0].size - 1;
+	hose->pci_mem_offset = pi->pci_mem[0].cpu_base -
+						pi->pci_mem[0].pci_base_lo;
+	return;
+}
+
+/*
+ * mv64x60_config_pci_params()
+ *
+ * Configure a hose's PCI config space parameters.
+ */
+void __init
+mv64x60_config_pci_params(struct pci_controller *hose,
+	struct mv64x60_pci_info *pi)
+{
+	u32	devfn;
+	u16	u16_val;
+	u8	save_exclude;
+
+	devfn = PCI_DEVFN(0,0);
+
+	save_exclude = mv64x60_pci_exclude_bridge;
+	mv64x60_pci_exclude_bridge = 0;
+
+	/* Set class code to indicate host bridge */
+	u16_val = PCI_CLASS_BRIDGE_HOST; /* 0x0600 (host bridge) */
+	early_write_config_word(hose, 0, devfn, PCI_CLASS_DEVICE, u16_val);
+
+	/* Enable bridge to be PCI master & respond to PCI MEM cycles */
+	early_read_config_word(hose, 0, devfn, PCI_COMMAND, &u16_val);
+	u16_val &= ~(PCI_COMMAND_IO | PCI_COMMAND_INVALIDATE |
+		PCI_COMMAND_PARITY | PCI_COMMAND_SERR | PCI_COMMAND_FAST_BACK);
+	u16_val |= pi->pci_cmd_bits | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
+	early_write_config_word(hose, 0, devfn, PCI_COMMAND, u16_val);
+
+	/* Set latency timer, cache line size, clear BIST */
+	u16_val = (pi->latency_timer << 8) | (L1_CACHE_LINE_SIZE >> 2);
+	early_write_config_word(hose, 0, devfn, PCI_CACHE_LINE_SIZE, u16_val);
+
+	mv64x60_pci_exclude_bridge = save_exclude;
+	return;
+}
+
+/*
+ *****************************************************************************
+ *
+ *	PCI Related Routine
+ *
+ *****************************************************************************
+ */
+/*
+ * mv64x60_set_bus()
+ *
+ * Set the bus number for the hose directly under the bridge.
+ */
+void __init
+mv64x60_set_bus(struct mv64x60_handle *bh, u32 bus, u32 child_bus)
+{
+	struct pci_controller	*hose;
+	u32	pci_mode, p2p_cfg, pci_cfg_offset, val;
+	u8	save_exclude;
+
+	if (bus == 0) {
+		pci_mode = bh->pci_mode_a;
+		p2p_cfg = MV64x60_PCI0_P2P_CONFIG;
+		pci_cfg_offset = 0x64;
+		hose = bh->hose_a;
+	}
+	else {
+		pci_mode = bh->pci_mode_b;
+		p2p_cfg = MV64x60_PCI1_P2P_CONFIG;
+		pci_cfg_offset = 0xe4;
+		hose = bh->hose_b;
+	}
+
+	child_bus &= 0xff;
+	val = mv64x60_read(bh, p2p_cfg);
+
+	if (pci_mode == MV64x60_PCIMODE_CONVENTIONAL) {
+		val &= 0xe0000000; /* Force dev num to 0, turn off P2P bridge */
+		val |= (child_bus << 16) | 0xff;
+		mv64x60_write(bh, p2p_cfg, val);
+		(void)mv64x60_read(bh, p2p_cfg); /* Flush FIFO */
+	}
+	else { /* PCI-X */
+		/*
+		 * Need to use the current bus/dev number (that's in the
+		 * P2P CONFIG reg) to access the bridge's pci config space.
+		 */
+		save_exclude = mv64x60_pci_exclude_bridge;
+		mv64x60_pci_exclude_bridge = 0;
+		early_write_config_dword(hose, (val & 0x00ff0000) >> 16,
+			PCI_DEVFN(((val & 0x1f000000) >> 24), 0),
+			pci_cfg_offset, child_bus << 8);
+		mv64x60_pci_exclude_bridge = save_exclude;
+	}
+
+	return;
+}
+
+/*
+ * mv64x60_pci_exclude_device()
+ *
+ * This routine is used to make the bridge not appear when the
+ * PCI subsystem is accessing PCI devices (in PCI config space).
+ */
+int
+mv64x60_pci_exclude_device(u8 bus, u8 devfn)
+{
+	struct pci_controller	*hose;
+
+	hose = pci_bus_to_hose(bus);
+
+	/* Skip slot 0 on both hoses */
+	if ((mv64x60_pci_exclude_bridge == 1) && (PCI_SLOT(devfn) == 0) &&
+		(hose->first_busno == bus))
+
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	else
+		return PCIBIOS_SUCCESSFUL;
+} /* mv64x60_pci_exclude_device() */
+
+/*
+ *****************************************************************************
+ *
+ *	Platform Device Routines
+ *
+ *****************************************************************************
+ */
+
+/*
+ * mv64x60_pd_fixup()
+ *
+ * Need to add the base addr of where the bridge's regs are mapped in the
+ * physical addr space so drivers can ioremap() them.
+ */
+void __init
+mv64x60_pd_fixup(struct mv64x60_handle *bh, struct platform_device *pd_devs[],
+	u32 entries)
+{
+	struct resource	*r;
+	u32		i, j;
+
+	for (i=0; i<entries; i++) {
+		j = 0;
+
+		while ((r = platform_get_resource(pd_devs[i],IORESOURCE_MEM,j))
+			!= NULL) {
+
+			r->start += bh->p_base;
+			r->end += bh->p_base;
+			j++;
+		}
+	}
+
+	return;
+}
+
+/*
+ * mv64x60_add_pds()
+ *
+ * Add the mv64x60 platform devices to the list of platform devices.
+ */
+static int __init
+mv64x60_add_pds(void)
+{
+	return platform_add_devices(mv64x60_pd_devs,
+		ARRAY_SIZE(mv64x60_pd_devs));
+}
+arch_initcall(mv64x60_add_pds);
+
+/*
+ *****************************************************************************
+ *
+ *	GT64260-Specific Routines
+ *
+ *****************************************************************************
+ */
+/*
+ * gt64260_translate_size()
+ *
+ * On the GT64260, the size register is really the "top" address of the window.
+ */
+static u32 __init
+gt64260_translate_size(u32 base, u32 size, u32 num_bits)
+{
+	return base + mv64x60_mask(size - 1, num_bits);
+}
+
+/*
+ * gt64260_untranslate_size()
+ *
+ * Translate the top address of a window into a window size.
+ */
+static u32 __init
+gt64260_untranslate_size(u32 base, u32 size, u32 num_bits)
+{
+	if (size >= base)
+		size = size - base + (1 << (32 - num_bits));
+	else
+		size = 0;
+
+	return size;
+}
+
+/*
+ * gt64260_set_pci2mem_window()
+ *
+ * The PCI->MEM window registers are actually in PCI config space so need
+ * to set them by setting the correct config space BARs.
+ */
+static u32 gt64260_reg_addrs[2][4] __initdata = {
+	{ 0x10, 0x14, 0x18, 0x1c }, { 0x90, 0x94, 0x98, 0x9c }
+};
+
+static void __init
+gt64260_set_pci2mem_window(struct pci_controller *hose, u32 bus, u32 window,
+	u32 base)
+{
+	u8	save_exclude;
+
+	pr_debug("set pci->mem window: %d, hose: %d, base: 0x%x\n", window,
+		hose->index, base);
+
+	save_exclude = mv64x60_pci_exclude_bridge;
+	mv64x60_pci_exclude_bridge = 0;
+	early_write_config_dword(hose, 0, PCI_DEVFN(0, 0),
+		gt64260_reg_addrs[bus][window], mv64x60_mask(base, 20) | 0x8);
+	mv64x60_pci_exclude_bridge = save_exclude;
+
+	return;
+}
+
+/*
+ * gt64260_set_pci2regs_window()
+ *
+ * Set where the bridge's registers appear in PCI MEM space.
+ */
+static u32 gt64260_offset[2] __initdata = {0x20, 0xa0};
+
+static void __init
+gt64260_set_pci2regs_window(struct mv64x60_handle *bh,
+	struct pci_controller *hose, u32 bus, u32 base)
+{
+	u8	save_exclude;
+
+	pr_debug("set pci->internal regs hose: %d, base: 0x%x\n", hose->index,
+		base);
+
+	save_exclude = mv64x60_pci_exclude_bridge;
+	mv64x60_pci_exclude_bridge = 0;
+	early_write_config_dword(hose, 0, PCI_DEVFN(0,0), gt64260_offset[bus],
+		(base << 16));
+	mv64x60_pci_exclude_bridge = save_exclude;
+
+	return;
+}
+
+/*
+ * gt64260_is_enabled_32bit()
+ *
+ * On a GT64260, a window is enabled iff its top address is >= to its base
+ * address.
+ */
+static u32 __init
+gt64260_is_enabled_32bit(struct mv64x60_handle *bh, u32 window)
+{
+	u32	rc = 0;
+
+	if ((gt64260_32bit_windows[window].base_reg != 0) &&
+		(gt64260_32bit_windows[window].size_reg != 0) &&
+		((mv64x60_read(bh, gt64260_32bit_windows[window].size_reg) &
+			((1 << gt64260_32bit_windows[window].size_bits) - 1)) >=
+		 (mv64x60_read(bh, gt64260_32bit_windows[window].base_reg) &
+			((1 << gt64260_32bit_windows[window].base_bits) - 1))))
+
+		rc = 1;
+
+	return rc;
+}
+
+/*
+ * gt64260_enable_window_32bit()
+ *
+ * On the GT64260, a window is enabled iff the top address is >= to the base
+ * address of the window.  Since the window has already been configured by
+ * the time this routine is called, we have nothing to do here.
+ */
+static void __init
+gt64260_enable_window_32bit(struct mv64x60_handle *bh, u32 window)
+{
+	pr_debug("enable 32bit window: %d\n", window);
+	return;
+}
+
+/*
+ * gt64260_disable_window_32bit()
+ *
+ * On a GT64260, you disable a window by setting its top address to be less
+ * than its base address.
+ */
+static void __init
+gt64260_disable_window_32bit(struct mv64x60_handle *bh, u32 window)
+{
+	pr_debug("disable 32bit window: %d, base_reg: 0x%x, size_reg: 0x%x\n",
+		window, gt64260_32bit_windows[window].base_reg,
+		gt64260_32bit_windows[window].size_reg);
+
+	if ((gt64260_32bit_windows[window].base_reg != 0) &&
+		(gt64260_32bit_windows[window].size_reg != 0)) {
+
+		/* To disable, make bottom reg higher than top reg */
+		mv64x60_write(bh, gt64260_32bit_windows[window].base_reg,0xfff);
+		mv64x60_write(bh, gt64260_32bit_windows[window].size_reg, 0);
+	}
+
+	return;
+}
+
+/*
+ * gt64260_enable_window_64bit()
+ *
+ * On the GT64260, a window is enabled iff the top address is >= to the base
+ * address of the window.  Since the window has already been configured by
+ * the time this routine is called, we have nothing to do here.
+ */
+static void __init
+gt64260_enable_window_64bit(struct mv64x60_handle *bh, u32 window)
+{
+	pr_debug("enable 64bit window: %d\n", window);
+	return;	/* Enabled when window configured (i.e., when top >= base) */
+}
+
+/*
+ * gt64260_disable_window_64bit()
+ *
+ * On a GT64260, you disable a window by setting its top address to be less
+ * than its base address.
+ */
+static void __init
+gt64260_disable_window_64bit(struct mv64x60_handle *bh, u32 window)
+{
+	pr_debug("disable 64bit window: %d, base_reg: 0x%x, size_reg: 0x%x\n",
+		window, gt64260_64bit_windows[window].base_lo_reg,
+		gt64260_64bit_windows[window].size_reg);
+
+	if ((gt64260_64bit_windows[window].base_lo_reg != 0) &&
+		(gt64260_64bit_windows[window].size_reg != 0)) {
+
+		/* To disable, make bottom reg higher than top reg */
+		mv64x60_write(bh, gt64260_64bit_windows[window].base_lo_reg,
+									0xfff);
+		mv64x60_write(bh, gt64260_64bit_windows[window].base_hi_reg, 0);
+		mv64x60_write(bh, gt64260_64bit_windows[window].size_reg, 0);
+	}
+
+	return;
+}
+
+/*
+ * gt64260_disable_all_windows()
+ *
+ * The GT64260 has several windows that aren't represented in the table of
+ * windows at the top of this file.  This routine turns all of them off
+ * except for the memory controller windows, of course.
+ */
+static void __init
+gt64260_disable_all_windows(struct mv64x60_handle *bh,
+	struct mv64x60_setup_info *si)
+{
+	u32	i, preserve;
+
+	/* Disable 32bit windows (don't disable cpu->mem windows) */
+	for (i=MV64x60_CPU2DEV_0_WIN; i<MV64x60_32BIT_WIN_COUNT; i++) {
+		if (i < 32)
+			preserve = si->window_preserve_mask_32_lo & (1 << i);
+		else
+			preserve = si->window_preserve_mask_32_hi & (1<<(i-32));
+
+		if (!preserve)
+			gt64260_disable_window_32bit(bh, i);
+	}
+
+	/* Disable 64bit windows */
+	for (i=0; i<MV64x60_64BIT_WIN_COUNT; i++)
+		if (!(si->window_preserve_mask_64 & (1<<i)))
+			gt64260_disable_window_64bit(bh, i);
+
+	/* Turn off cpu protection windows not in gt64260_32bit_windows[] */
+	mv64x60_write(bh, GT64260_CPU_PROT_BASE_4, 0xfff);
+	mv64x60_write(bh, GT64260_CPU_PROT_SIZE_4, 0);
+	mv64x60_write(bh, GT64260_CPU_PROT_BASE_5, 0xfff);
+	mv64x60_write(bh, GT64260_CPU_PROT_SIZE_5, 0);
+	mv64x60_write(bh, GT64260_CPU_PROT_BASE_6, 0xfff);
+	mv64x60_write(bh, GT64260_CPU_PROT_SIZE_6, 0);
+	mv64x60_write(bh, GT64260_CPU_PROT_BASE_7, 0xfff);
+	mv64x60_write(bh, GT64260_CPU_PROT_SIZE_7, 0);
+
+	/* Turn off PCI->MEM access cntl wins not in gt64260_64bit_windows[] */
+	mv64x60_write(bh, MV64x60_PCI0_ACC_CNTL_4_BASE_LO, 0xfff);
+	mv64x60_write(bh, MV64x60_PCI0_ACC_CNTL_4_BASE_HI, 0);
+	mv64x60_write(bh, MV64x60_PCI0_ACC_CNTL_4_SIZE, 0);
+	mv64x60_write(bh, MV64x60_PCI0_ACC_CNTL_5_BASE_LO, 0xfff);
+	mv64x60_write(bh, MV64x60_PCI0_ACC_CNTL_5_BASE_HI, 0);
+	mv64x60_write(bh, MV64x60_PCI0_ACC_CNTL_5_SIZE, 0);
+	mv64x60_write(bh, GT64260_PCI0_ACC_CNTL_6_BASE_LO, 0xfff);
+	mv64x60_write(bh, GT64260_PCI0_ACC_CNTL_6_BASE_HI, 0);
+	mv64x60_write(bh, GT64260_PCI0_ACC_CNTL_6_SIZE, 0);
+	mv64x60_write(bh, GT64260_PCI0_ACC_CNTL_7_BASE_LO, 0xfff);
+	mv64x60_write(bh, GT64260_PCI0_ACC_CNTL_7_BASE_HI, 0);
+	mv64x60_write(bh, GT64260_PCI0_ACC_CNTL_7_SIZE, 0);
+
+	mv64x60_write(bh, MV64x60_PCI1_ACC_CNTL_4_BASE_LO, 0xfff);
+	mv64x60_write(bh, MV64x60_PCI1_ACC_CNTL_4_BASE_HI, 0);
+	mv64x60_write(bh, MV64x60_PCI1_ACC_CNTL_4_SIZE, 0);
+	mv64x60_write(bh, MV64x60_PCI1_ACC_CNTL_5_BASE_LO, 0xfff);
+	mv64x60_write(bh, MV64x60_PCI1_ACC_CNTL_5_BASE_HI, 0);
+	mv64x60_write(bh, MV64x60_PCI1_ACC_CNTL_5_SIZE, 0);
+	mv64x60_write(bh, GT64260_PCI1_ACC_CNTL_6_BASE_LO, 0xfff);
+	mv64x60_write(bh, GT64260_PCI1_ACC_CNTL_6_BASE_HI, 0);
+	mv64x60_write(bh, GT64260_PCI1_ACC_CNTL_6_SIZE, 0);
+	mv64x60_write(bh, GT64260_PCI1_ACC_CNTL_7_BASE_LO, 0xfff);
+	mv64x60_write(bh, GT64260_PCI1_ACC_CNTL_7_BASE_HI, 0);
+	mv64x60_write(bh, GT64260_PCI1_ACC_CNTL_7_SIZE, 0);
+
+	/* Disable all PCI-><whatever> windows */
+	mv64x60_set_bits(bh, MV64x60_PCI0_BAR_ENABLE, 0x07fffdff);
+	mv64x60_set_bits(bh, MV64x60_PCI1_BAR_ENABLE, 0x07fffdff);
+
+	/*
+	 * Some firmwares enable a bunch of intr sources
+	 * for the PCI INT output pins.
+	 */
+	mv64x60_write(bh, GT64260_IC_CPU_INTR_MASK_LO, 0);
+	mv64x60_write(bh, GT64260_IC_CPU_INTR_MASK_HI, 0);
+	mv64x60_write(bh, GT64260_IC_PCI0_INTR_MASK_LO, 0);
+	mv64x60_write(bh, GT64260_IC_PCI0_INTR_MASK_HI, 0);
+	mv64x60_write(bh, GT64260_IC_PCI1_INTR_MASK_LO, 0);
+	mv64x60_write(bh, GT64260_IC_PCI1_INTR_MASK_HI, 0);
+	mv64x60_write(bh, GT64260_IC_CPU_INT_0_MASK, 0);
+	mv64x60_write(bh, GT64260_IC_CPU_INT_1_MASK, 0);
+	mv64x60_write(bh, GT64260_IC_CPU_INT_2_MASK, 0);
+	mv64x60_write(bh, GT64260_IC_CPU_INT_3_MASK, 0);
+
+	return;
+}
+
+/*
+ * gt64260a_chip_specific_init()
+ *
+ * Implement errata work arounds for the GT64260A.
+ */
+static void __init
+gt64260a_chip_specific_init(struct mv64x60_handle *bh,
+	struct mv64x60_setup_info *si)
+{
+#ifdef CONFIG_SERIAL_MPSC
+	struct resource	*r;
+#endif
+#if !defined(CONFIG_NOT_COHERENT_CACHE)
+	u32	val;
+	u8	save_exclude;
+#endif
+
+	if (si->pci_0.enable_bus)
+		mv64x60_set_bits(bh, MV64x60_PCI0_CMD,
+			((1<<4) | (1<<5) | (1<<9) | (1<<13)));
+
+	if (si->pci_1.enable_bus)
+		mv64x60_set_bits(bh, MV64x60_PCI1_CMD,
+			((1<<4) | (1<<5) | (1<<9) | (1<<13)));
+
+	/*
+	 * Dave Wilhardt found that bit 4 in the PCI Command registers must
+	 * be set if you are using cache coherency.
+	 */
+#if !defined(CONFIG_NOT_COHERENT_CACHE)
+	/* Res #MEM-4 -- cpu read buffer to buffer 1 */
+	if ((mv64x60_read(bh, MV64x60_CPU_MODE) & 0xf0) == 0x40)
+		mv64x60_set_bits(bh, GT64260_SDRAM_CONFIG, (1<<26));
+
+	save_exclude = mv64x60_pci_exclude_bridge;
+	mv64x60_pci_exclude_bridge = 0;
+	if (si->pci_0.enable_bus) {
+		early_read_config_dword(bh->hose_a, 0, PCI_DEVFN(0,0),
+			PCI_COMMAND, &val);
+		val |= PCI_COMMAND_INVALIDATE;
+		early_write_config_dword(bh->hose_a, 0, PCI_DEVFN(0,0),
+			PCI_COMMAND, val);
+	}
+
+	if (si->pci_1.enable_bus) {
+		early_read_config_dword(bh->hose_b, 0, PCI_DEVFN(0,0),
+			PCI_COMMAND, &val);
+		val |= PCI_COMMAND_INVALIDATE;
+		early_write_config_dword(bh->hose_b, 0, PCI_DEVFN(0,0),
+			PCI_COMMAND, val);
+	}
+	mv64x60_pci_exclude_bridge = save_exclude;
+#endif
+
+	/* Disable buffer/descriptor snooping */
+	mv64x60_clr_bits(bh, 0xf280, (1<< 6) | (1<<14) | (1<<22) | (1<<30));
+	mv64x60_clr_bits(bh, 0xf2c0, (1<< 6) | (1<<14) | (1<<22) | (1<<30));
+
+#ifdef CONFIG_SERIAL_MPSC
+	mv64x60_mpsc0_pdata.mirror_regs = 1;
+	mv64x60_mpsc0_pdata.cache_mgmt = 1;
+	mv64x60_mpsc1_pdata.mirror_regs = 1;
+	mv64x60_mpsc1_pdata.cache_mgmt = 1;
+
+	if ((r = platform_get_resource(&mpsc1_device, IORESOURCE_IRQ, 0))
+		!= NULL) {
+
+		r->start = MV64x60_IRQ_SDMA_0;
+		r->end = MV64x60_IRQ_SDMA_0;
+	}
+#endif
+
+	return;
+}
+
+/*
+ * gt64260b_chip_specific_init()
+ *
+ * Implement errata work arounds for the GT64260B.
+ */
+static void __init
+gt64260b_chip_specific_init(struct mv64x60_handle *bh,
+	struct mv64x60_setup_info *si)
+{
+#ifdef CONFIG_SERIAL_MPSC
+	struct resource	*r;
+#endif
+#if !defined(CONFIG_NOT_COHERENT_CACHE)
+	u32	val;
+	u8	save_exclude;
+#endif
+
+	if (si->pci_0.enable_bus)
+		mv64x60_set_bits(bh, MV64x60_PCI0_CMD,
+			((1<<4) | (1<<5) | (1<<9) | (1<<13)));
+
+	if (si->pci_1.enable_bus)
+		mv64x60_set_bits(bh, MV64x60_PCI1_CMD,
+			((1<<4) | (1<<5) | (1<<9) | (1<<13)));
+
+	/*
+	 * Dave Wilhardt found that bit 4 in the PCI Command registers must
+	 * be set if you are using cache coherency.
+	 */
+#if !defined(CONFIG_NOT_COHERENT_CACHE)
+	mv64x60_set_bits(bh, GT64260_CPU_WB_PRIORITY_BUFFER_DEPTH, 0xf);
+
+	/* Res #MEM-4 -- cpu read buffer to buffer 1 */
+	if ((mv64x60_read(bh, MV64x60_CPU_MODE) & 0xf0) == 0x40)
+		mv64x60_set_bits(bh, GT64260_SDRAM_CONFIG, (1<<26));
+
+	save_exclude = mv64x60_pci_exclude_bridge;
+	mv64x60_pci_exclude_bridge = 0;
+	if (si->pci_0.enable_bus) {
+		early_read_config_dword(bh->hose_a, 0, PCI_DEVFN(0,0),
+			PCI_COMMAND, &val);
+		val |= PCI_COMMAND_INVALIDATE;
+		early_write_config_dword(bh->hose_a, 0, PCI_DEVFN(0,0),
+			PCI_COMMAND, val);
+	}
+
+	if (si->pci_1.enable_bus) {
+		early_read_config_dword(bh->hose_b, 0, PCI_DEVFN(0,0),
+			PCI_COMMAND, &val);
+		val |= PCI_COMMAND_INVALIDATE;
+		early_write_config_dword(bh->hose_b, 0, PCI_DEVFN(0,0),
+			PCI_COMMAND, val);
+	}
+	mv64x60_pci_exclude_bridge = save_exclude;
+#endif
+
+	/* Disable buffer/descriptor snooping */
+	mv64x60_clr_bits(bh, 0xf280, (1<< 6) | (1<<14) | (1<<22) | (1<<30));
+	mv64x60_clr_bits(bh, 0xf2c0, (1<< 6) | (1<<14) | (1<<22) | (1<<30));
+
+#ifdef CONFIG_SERIAL_MPSC
+	/*
+	 * The 64260B is not supposed to have the bug where the MPSC & ENET
+	 * can't access cache coherent regions.  However, testing has shown
+	 * that the MPSC, at least, still has this bug.
+	 */
+	mv64x60_mpsc0_pdata.cache_mgmt = 1;
+	mv64x60_mpsc1_pdata.cache_mgmt = 1;
+
+	if ((r = platform_get_resource(&mpsc1_device, IORESOURCE_IRQ, 0))
+		!= NULL) {
+
+		r->start = MV64x60_IRQ_SDMA_0;
+		r->end = MV64x60_IRQ_SDMA_0;
+	}
+#endif
+
+	return;
+}
+
+/*
+ *****************************************************************************
+ *
+ *	MV64360-Specific Routines
+ *
+ *****************************************************************************
+ */
+/*
+ * mv64360_translate_size()
+ *
+ * On the MV64360, the size register is set similar to the size you get
+ * from a pci config space BAR register.  That is, programmed from LSB to MSB
+ * as a sequence of 1's followed by a sequence of 0's. IOW, "size -1" with the
+ * assumption that the size is a power of 2.
+ */
+static u32 __init
+mv64360_translate_size(u32 base_addr, u32 size, u32 num_bits)
+{
+	return mv64x60_mask(size - 1, num_bits);
+}
+
+/*
+ * mv64360_untranslate_size()
+ *
+ * Translate the size register value of a window into a window size.
+ */
+static u32 __init
+mv64360_untranslate_size(u32 base_addr, u32 size, u32 num_bits)
+{
+	if (size > 0) {
+		size >>= (32 - num_bits);
+		size++;
+		size <<= (32 - num_bits);
+	}
+
+	return size;
+}
+
+/*
+ * mv64360_set_pci2mem_window()
+ *
+ * The PCI->MEM window registers are actually in PCI config space so need
+ * to set them by setting the correct config space BARs.
+ */
+struct {
+	u32	fcn;
+	u32	base_hi_bar;
+	u32	base_lo_bar;
+} static mv64360_reg_addrs[2][4] __initdata = {
+	{{ 0, 0x14, 0x10 }, { 0, 0x1c, 0x18 },
+	 { 1, 0x14, 0x10 }, { 1, 0x1c, 0x18 }},
+	{{ 0, 0x94, 0x90 }, { 0, 0x9c, 0x98 },
+	 { 1, 0x94, 0x90 }, { 1, 0x9c, 0x98 }}
+};
+
+static void __init
+mv64360_set_pci2mem_window(struct pci_controller *hose, u32 bus, u32 window,
+	u32 base)
+{
+	u8 save_exclude;
+
+	pr_debug("set pci->mem window: %d, hose: %d, base: 0x%x\n", window,
+		hose->index, base);
+
+	save_exclude = mv64x60_pci_exclude_bridge;
+	mv64x60_pci_exclude_bridge = 0;
+	early_write_config_dword(hose, 0,
+		PCI_DEVFN(0, mv64360_reg_addrs[bus][window].fcn),
+		mv64360_reg_addrs[bus][window].base_hi_bar, 0);
+	early_write_config_dword(hose, 0,
+		PCI_DEVFN(0, mv64360_reg_addrs[bus][window].fcn),
+		mv64360_reg_addrs[bus][window].base_lo_bar,
+		mv64x60_mask(base,20) | 0xc);
+	mv64x60_pci_exclude_bridge = save_exclude;
+
+	return;
+}
+
+/*
+ * mv64360_set_pci2regs_window()
+ *
+ * Set where the bridge's registers appear in PCI MEM space.
+ */
+static u32 mv64360_offset[2][2] __initdata = {{0x20, 0x24}, {0xa0, 0xa4}};
+
+static void __init
+mv64360_set_pci2regs_window(struct mv64x60_handle *bh,
+	struct pci_controller *hose, u32 bus, u32 base)
+{
+	u8	save_exclude;
+
+	pr_debug("set pci->internal regs hose: %d, base: 0x%x\n", hose->index,
+		base);
+
+	save_exclude = mv64x60_pci_exclude_bridge;
+	mv64x60_pci_exclude_bridge = 0;
+	early_write_config_dword(hose, 0, PCI_DEVFN(0,0),
+		mv64360_offset[bus][0], (base << 16));
+	early_write_config_dword(hose, 0, PCI_DEVFN(0,0),
+		mv64360_offset[bus][1], 0);
+	mv64x60_pci_exclude_bridge = save_exclude;
+
+	return;
+}
+
+/*
+ * mv64360_is_enabled_32bit()
+ *
+ * On a MV64360, a window is enabled by either clearing a bit in the
+ * CPU BAR Enable reg or setting a bit in the window's base reg.
+ * Note that this doesn't work for windows on the PCI slave side but we don't
+ * check those so its okay.
+ */
+static u32 __init
+mv64360_is_enabled_32bit(struct mv64x60_handle *bh, u32 window)
+{
+	u32	extra, rc = 0;
+
+	if (((mv64360_32bit_windows[window].base_reg != 0) &&
+		(mv64360_32bit_windows[window].size_reg != 0)) ||
+		(window == MV64x60_CPU2SRAM_WIN)) {
+
+		extra = mv64360_32bit_windows[window].extra;
+
+		switch (extra & MV64x60_EXTRA_MASK) {
+		case MV64x60_EXTRA_CPUWIN_ENAB:
+			rc = (mv64x60_read(bh, MV64360_CPU_BAR_ENABLE) &
+				(1 << (extra & 0x1f))) == 0;
+			break;
+
+		case MV64x60_EXTRA_CPUPROT_ENAB:
+			rc = (mv64x60_read(bh,
+				mv64360_32bit_windows[window].base_reg) &
+					(1 << (extra & 0x1f))) != 0;
+			break;
+
+		case MV64x60_EXTRA_ENET_ENAB:
+			rc = (mv64x60_read(bh, MV64360_ENET2MEM_BAR_ENABLE) &
+				(1 << (extra & 0x7))) == 0;
+			break;
+
+		case MV64x60_EXTRA_MPSC_ENAB:
+			rc = (mv64x60_read(bh, MV64360_MPSC2MEM_BAR_ENABLE) &
+				(1 << (extra & 0x3))) == 0;
+			break;
+
+		case MV64x60_EXTRA_IDMA_ENAB:
+			rc = (mv64x60_read(bh, MV64360_IDMA2MEM_BAR_ENABLE) &
+				(1 << (extra & 0x7))) == 0;
+			break;
+
+		default:
+			printk(KERN_ERR "mv64360_is_enabled: %s\n",
+				"32bit table corrupted");
+		}
+	}
+
+	return rc;
+}
+
+/*
+ * mv64360_enable_window_32bit()
+ *
+ * On a MV64360, a window is enabled by either clearing a bit in the
+ * CPU BAR Enable reg or setting a bit in the window's base reg.
+ */
+static void __init
+mv64360_enable_window_32bit(struct mv64x60_handle *bh, u32 window)
+{
+	u32	extra;
+
+	pr_debug("enable 32bit window: %d\n", window);
+
+	if (((mv64360_32bit_windows[window].base_reg != 0) &&
+		(mv64360_32bit_windows[window].size_reg != 0)) ||
+		(window == MV64x60_CPU2SRAM_WIN)) {
+
+		extra = mv64360_32bit_windows[window].extra;
+
+		switch (extra & MV64x60_EXTRA_MASK) {
+		case MV64x60_EXTRA_CPUWIN_ENAB:
+			mv64x60_clr_bits(bh, MV64360_CPU_BAR_ENABLE,
+				(1 << (extra & 0x1f)));
+			break;
+
+		case MV64x60_EXTRA_CPUPROT_ENAB:
+			mv64x60_set_bits(bh,
+				mv64360_32bit_windows[window].base_reg,
+				(1 << (extra & 0x1f)));
+			break;
+
+		case MV64x60_EXTRA_ENET_ENAB:
+			mv64x60_clr_bits(bh, MV64360_ENET2MEM_BAR_ENABLE,
+				(1 << (extra & 0x7)));
+			break;
+
+		case MV64x60_EXTRA_MPSC_ENAB:
+			mv64x60_clr_bits(bh, MV64360_MPSC2MEM_BAR_ENABLE,
+				(1 << (extra & 0x3)));
+			break;
+
+		case MV64x60_EXTRA_IDMA_ENAB:
+			mv64x60_clr_bits(bh, MV64360_IDMA2MEM_BAR_ENABLE,
+				(1 << (extra & 0x7)));
+			break;
+
+		default:
+			printk(KERN_ERR "mv64360_enable: %s\n",
+				"32bit table corrupted");
+		}
+	}
+
+	return;
+}
+
+/*
+ * mv64360_disable_window_32bit()
+ *
+ * On a MV64360, a window is disabled by either setting a bit in the
+ * CPU BAR Enable reg or clearing a bit in the window's base reg.
+ */
+static void __init
+mv64360_disable_window_32bit(struct mv64x60_handle *bh, u32 window)
+{
+	u32	extra;
+
+	pr_debug("disable 32bit window: %d, base_reg: 0x%x, size_reg: 0x%x\n",
+		window, mv64360_32bit_windows[window].base_reg,
+		mv64360_32bit_windows[window].size_reg);
+
+	if (((mv64360_32bit_windows[window].base_reg != 0) &&
+		(mv64360_32bit_windows[window].size_reg != 0)) ||
+		(window == MV64x60_CPU2SRAM_WIN)) {
+
+		extra = mv64360_32bit_windows[window].extra;
+
+		switch (extra & MV64x60_EXTRA_MASK) {
+		case MV64x60_EXTRA_CPUWIN_ENAB:
+			mv64x60_set_bits(bh, MV64360_CPU_BAR_ENABLE,
+				(1 << (extra & 0x1f)));
+			break;
+
+		case MV64x60_EXTRA_CPUPROT_ENAB:
+			mv64x60_clr_bits(bh,
+				mv64360_32bit_windows[window].base_reg,
+				(1 << (extra & 0x1f)));
+			break;
+
+		case MV64x60_EXTRA_ENET_ENAB:
+			mv64x60_set_bits(bh, MV64360_ENET2MEM_BAR_ENABLE,
+				(1 << (extra & 0x7)));
+			break;
+
+		case MV64x60_EXTRA_MPSC_ENAB:
+			mv64x60_set_bits(bh, MV64360_MPSC2MEM_BAR_ENABLE,
+				(1 << (extra & 0x3)));
+			break;
+
+		case MV64x60_EXTRA_IDMA_ENAB:
+			mv64x60_set_bits(bh, MV64360_IDMA2MEM_BAR_ENABLE,
+				(1 << (extra & 0x7)));
+			break;
+
+		default:
+			printk(KERN_ERR "mv64360_disable: %s\n",
+				"32bit table corrupted");
+		}
+	}
+
+	return;
+}
+
+/*
+ * mv64360_enable_window_64bit()
+ *
+ * On the MV64360, a 64-bit window is enabled by setting a bit in the window's
+ * base reg.
+ */
+static void __init
+mv64360_enable_window_64bit(struct mv64x60_handle *bh, u32 window)
+{
+	pr_debug("enable 64bit window: %d\n", window);
+
+	if ((mv64360_64bit_windows[window].base_lo_reg!= 0) &&
+		(mv64360_64bit_windows[window].size_reg != 0)) {
+
+		if ((mv64360_64bit_windows[window].extra & MV64x60_EXTRA_MASK)
+			== MV64x60_EXTRA_PCIACC_ENAB)
+
+			mv64x60_set_bits(bh,
+				mv64360_64bit_windows[window].base_lo_reg,
+				(1 << (mv64360_64bit_windows[window].extra &
+									0x1f)));
+		else
+			printk(KERN_ERR "mv64360_enable: %s\n",
+				"64bit table corrupted");
+	}
+
+	return;
+}
+
+/*
+ * mv64360_disable_window_64bit()
+ *
+ * On a MV64360, a 64-bit window is disabled by clearing a bit in the window's
+ * base reg.
+ */
+static void __init
+mv64360_disable_window_64bit(struct mv64x60_handle *bh, u32 window)
+{
+	pr_debug("disable 64bit window: %d, base_reg: 0x%x, size_reg: 0x%x\n",
+		window, mv64360_64bit_windows[window].base_lo_reg,
+		mv64360_64bit_windows[window].size_reg);
+
+	if ((mv64360_64bit_windows[window].base_lo_reg != 0) &&
+		(mv64360_64bit_windows[window].size_reg != 0)) {
+
+		if ((mv64360_64bit_windows[window].extra & MV64x60_EXTRA_MASK)
+			== MV64x60_EXTRA_PCIACC_ENAB)
+
+			mv64x60_clr_bits(bh,
+				mv64360_64bit_windows[window].base_lo_reg,
+				(1 << (mv64360_64bit_windows[window].extra &
+									0x1f)));
+		else
+			printk(KERN_ERR "mv64360_disable: %s\n",
+				"64bit table corrupted");
+	}
+
+	return;
+}
+
+/*
+ * mv64360_disable_all_windows()
+ *
+ * The MV64360 has a few windows that aren't represented in the table of
+ * windows at the top of this file.  This routine turns all of them off
+ * except for the memory controller windows, of course.
+ */
+static void __init
+mv64360_disable_all_windows(struct mv64x60_handle *bh,
+	struct mv64x60_setup_info *si)
+{
+	u32	preserve, i;
+
+	/* Disable 32bit windows (don't disable cpu->mem windows) */
+	for (i=MV64x60_CPU2DEV_0_WIN; i<MV64x60_32BIT_WIN_COUNT; i++) {
+		if (i < 32)
+			preserve = si->window_preserve_mask_32_lo & (1 << i);
+		else
+			preserve = si->window_preserve_mask_32_hi & (1<<(i-32));
+
+		if (!preserve)
+			mv64360_disable_window_32bit(bh, i);
+	}
+
+	/* Disable 64bit windows */
+	for (i=0; i<MV64x60_64BIT_WIN_COUNT; i++)
+		if (!(si->window_preserve_mask_64 & (1<<i)))
+			mv64360_disable_window_64bit(bh, i);
+
+	/* Turn off PCI->MEM access cntl wins not in mv64360_64bit_windows[] */
+	mv64x60_clr_bits(bh, MV64x60_PCI0_ACC_CNTL_4_BASE_LO, 0);
+	mv64x60_clr_bits(bh, MV64x60_PCI0_ACC_CNTL_5_BASE_LO, 0);
+	mv64x60_clr_bits(bh, MV64x60_PCI1_ACC_CNTL_4_BASE_LO, 0);
+	mv64x60_clr_bits(bh, MV64x60_PCI1_ACC_CNTL_5_BASE_LO, 0);
+
+	/* Disable all PCI-><whatever> windows */
+	mv64x60_set_bits(bh, MV64x60_PCI0_BAR_ENABLE, 0x0000f9ff);
+	mv64x60_set_bits(bh, MV64x60_PCI1_BAR_ENABLE, 0x0000f9ff);
+
+	return;
+}
+
+/*
+ * mv64360_config_io2mem_windows()
+ *
+ * ENET, MPSC, and IDMA ctlrs on the MV64[34]60 have separate windows that
+ * must be set up so that the respective ctlr can access system memory.
+ */
+static u32 enet_tab[MV64x60_CPU2MEM_WINDOWS] __initdata = {
+	MV64x60_ENET2MEM_0_WIN, MV64x60_ENET2MEM_1_WIN,
+	MV64x60_ENET2MEM_2_WIN, MV64x60_ENET2MEM_3_WIN,
+};
+
+static u32 mpsc_tab[MV64x60_CPU2MEM_WINDOWS] __initdata = {
+	MV64x60_MPSC2MEM_0_WIN, MV64x60_MPSC2MEM_1_WIN,
+	MV64x60_MPSC2MEM_2_WIN, MV64x60_MPSC2MEM_3_WIN,
+};
+
+static u32 idma_tab[MV64x60_CPU2MEM_WINDOWS] __initdata = {
+	MV64x60_IDMA2MEM_0_WIN, MV64x60_IDMA2MEM_1_WIN,
+	MV64x60_IDMA2MEM_2_WIN, MV64x60_IDMA2MEM_3_WIN,
+};
+
+static u32 dram_selects[MV64x60_CPU2MEM_WINDOWS] __initdata =
+	{ 0xe, 0xd, 0xb, 0x7 };
+
+static void __init
+mv64360_config_io2mem_windows(struct mv64x60_handle *bh,
+	struct mv64x60_setup_info *si,
+	u32 mem_windows[MV64x60_CPU2MEM_WINDOWS][2])
+{
+	u32	i, win;
+
+	pr_debug("config_io2regs_windows: enet, mpsc, idma -> bridge regs\n");
+
+	mv64x60_write(bh, MV64360_ENET2MEM_ACC_PROT_0, 0);
+	mv64x60_write(bh, MV64360_ENET2MEM_ACC_PROT_1, 0);
+	mv64x60_write(bh, MV64360_ENET2MEM_ACC_PROT_2, 0);
+
+	mv64x60_write(bh, MV64360_MPSC2MEM_ACC_PROT_0, 0);
+	mv64x60_write(bh, MV64360_MPSC2MEM_ACC_PROT_1, 0);
+
+	mv64x60_write(bh, MV64360_IDMA2MEM_ACC_PROT_0, 0);
+	mv64x60_write(bh, MV64360_IDMA2MEM_ACC_PROT_1, 0);
+	mv64x60_write(bh, MV64360_IDMA2MEM_ACC_PROT_2, 0);
+	mv64x60_write(bh, MV64360_IDMA2MEM_ACC_PROT_3, 0);
+
+	/* Assume that mem ctlr has no more windows than embedded I/O ctlr */
+	for (win=MV64x60_CPU2MEM_0_WIN,i=0;win<=MV64x60_CPU2MEM_3_WIN;win++,i++)
+		if (bh->ci->is_enabled_32bit(bh, win)) {
+			mv64x60_set_32bit_window(bh, enet_tab[i],
+				mem_windows[i][0], mem_windows[i][1],
+				(dram_selects[i] << 8) |
+				(si->enet_options[i] & 0x3000));
+			bh->ci->enable_window_32bit(bh, enet_tab[i]);
+
+			/* Give enet r/w access to memory region */
+			mv64x60_set_bits(bh, MV64360_ENET2MEM_ACC_PROT_0,
+				(0x3 << (i << 1)));
+			mv64x60_set_bits(bh, MV64360_ENET2MEM_ACC_PROT_1,
+				(0x3 << (i << 1)));
+			mv64x60_set_bits(bh, MV64360_ENET2MEM_ACC_PROT_2,
+				(0x3 << (i << 1)));
+
+			mv64x60_set_32bit_window(bh, mpsc_tab[i],
+				mem_windows[i][0], mem_windows[i][1],
+				(dram_selects[i] << 8) |
+				(si->mpsc_options[i] & 0x3000));
+			bh->ci->enable_window_32bit(bh, mpsc_tab[i]);
+
+			/* Give mpsc r/w access to memory region */
+			mv64x60_set_bits(bh, MV64360_MPSC2MEM_ACC_PROT_0,
+				(0x3 << (i << 1)));
+			mv64x60_set_bits(bh, MV64360_MPSC2MEM_ACC_PROT_1,
+				(0x3 << (i << 1)));
+
+			mv64x60_set_32bit_window(bh, idma_tab[i],
+				mem_windows[i][0], mem_windows[i][1],
+				(dram_selects[i] << 8) |
+				(si->idma_options[i] & 0x3000));
+			bh->ci->enable_window_32bit(bh, idma_tab[i]);
+
+			/* Give idma r/w access to memory region */
+			mv64x60_set_bits(bh, MV64360_IDMA2MEM_ACC_PROT_0,
+				(0x3 << (i << 1)));
+			mv64x60_set_bits(bh, MV64360_IDMA2MEM_ACC_PROT_1,
+				(0x3 << (i << 1)));
+			mv64x60_set_bits(bh, MV64360_IDMA2MEM_ACC_PROT_2,
+				(0x3 << (i << 1)));
+			mv64x60_set_bits(bh, MV64360_IDMA2MEM_ACC_PROT_3,
+				(0x3 << (i << 1)));
+		}
+
+	return;
+}
+
+/*
+ * mv64360_set_mpsc2regs_window()
+ *
+ * MPSC has a window to the bridge's internal registers.  Call this routine
+ * to change that window so it doesn't conflict with the windows mapping the
+ * mpsc to system memory.
+ */
+static void __init
+mv64360_set_mpsc2regs_window(struct mv64x60_handle *bh, u32 base)
+{
+	pr_debug("set mpsc->internal regs, base: 0x%x\n", base);
+
+	mv64x60_write(bh, MV64360_MPSC2REGS_BASE, base & 0xffff0000);
+	return;
+}
+
+/*
+ * mv64360_chip_specific_init()
+ *
+ * No errata work arounds for the MV64360 implemented at this point.
+ */
+static void __init
+mv64360_chip_specific_init(struct mv64x60_handle *bh,
+	struct mv64x60_setup_info *si)
+{
+#ifdef CONFIG_SERIAL_MPSC
+	mv64x60_mpsc0_pdata.brg_can_tune = 1;
+	mv64x60_mpsc0_pdata.cache_mgmt = 1;
+	mv64x60_mpsc1_pdata.brg_can_tune = 1;
+	mv64x60_mpsc1_pdata.cache_mgmt = 1;
+#endif
+
+	return;
+}
+
+/*
+ * mv64460_chip_specific_init()
+ *
+ * No errata work arounds for the MV64460 implemented at this point.
+ */
+static void __init
+mv64460_chip_specific_init(struct mv64x60_handle *bh,
+	struct mv64x60_setup_info *si)
+{
+#ifdef CONFIG_SERIAL_MPSC
+	mv64x60_mpsc0_pdata.brg_can_tune = 1;
+	mv64x60_mpsc1_pdata.brg_can_tune = 1;
+#endif
+	return;
+}
diff -Nru a/arch/ppc/syslib/mv64x60_dbg.c b/arch/ppc/syslib/mv64x60_dbg.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/ppc/syslib/mv64x60_dbg.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,123 @@
+/*
+ * arch/ppc/syslib/mv64x60_dbg.c
+ *
+ * KGDB and progress routines for the Marvell/Galileo MV64x60 (Discovery).
+ *
+ * Author: Mark A. Greer <mgreer@mvista.com>
+ *
+ * 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.
+ */
+
+/*
+ *****************************************************************************
+ *
+ *	Low-level MPSC/UART I/O routines
+ *
+ *****************************************************************************
+ */
+
+
+#include <linux/config.h>
+#include <linux/irq.h>
+#include <asm/delay.h>
+#include <asm/mv64x60.h>
+
+
+#if defined(CONFIG_SERIAL_TEXT_DEBUG)
+
+#define	MPSC_CHR_1	0x000c
+#define	MPSC_CHR_2	0x0010
+
+static struct mv64x60_handle	mv64x60_dbg_bh;
+
+void
+mv64x60_progress_init(u32 base)
+{
+	mv64x60_dbg_bh.v_base = base;
+	return;
+}
+
+static void
+mv64x60_polled_putc(int chan, char c)
+{
+	u32	offset;
+
+	if (chan == 0)
+		offset = 0x8000;
+	else
+		offset = 0x9000;
+
+	mv64x60_write(&mv64x60_dbg_bh, offset + MPSC_CHR_1, (u32)c);
+	mv64x60_write(&mv64x60_dbg_bh, offset + MPSC_CHR_2, 0x200);
+	udelay(2000);
+}
+
+void
+mv64x60_mpsc_progress(char *s, unsigned short hex)
+{
+	volatile char	c;
+
+	mv64x60_polled_putc(0, '\r');
+
+	while ((c = *s++) != 0)
+		mv64x60_polled_putc(0, c);
+
+	mv64x60_polled_putc(0, '\n');
+	mv64x60_polled_putc(0, '\r');
+
+	return;
+}
+#endif	/* CONFIG_SERIAL_TEXT_DEBUG */
+
+
+#if defined(CONFIG_KGDB)
+
+#if defined(CONFIG_KGDB_TTYS0)
+#define KGDB_PORT 0
+#elif defined(CONFIG_KGDB_TTYS1)
+#define KGDB_PORT 1
+#else
+#error "Invalid kgdb_tty port"
+#endif
+
+void
+putDebugChar(unsigned char c)
+{
+	mv64x60_polled_putc(KGDB_PORT, (char)c);
+}
+
+int
+getDebugChar(void)
+{
+	unsigned char	c;
+
+	while (!mv64x60_polled_getc(KGDB_PORT, &c));
+	return (int)c;
+}
+
+void
+putDebugString(char* str)
+{
+	while (*str != '\0') {
+		putDebugChar(*str);
+		str++;
+	}
+	putDebugChar('\r');
+	return;
+}
+
+void
+kgdb_interruptible(int enable)
+{
+}
+
+void
+kgdb_map_scc(void)
+{
+	if (ppc_md.early_serial_map)
+		ppc_md.early_serial_map();
+}
+#endif	/* CONFIG_KGDB */
diff -Nru a/arch/ppc/syslib/mv64x60_win.c b/arch/ppc/syslib/mv64x60_win.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/ppc/syslib/mv64x60_win.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,1168 @@
+/*
+ * arch/ppc/syslib/mv64x60_win.c
+ *
+ * Tables with info on how to manipulate the 32 & 64 bit windows on the
+ * various types of Marvell bridge chips.
+ *
+ * Author: Mark A. Greer <mgreer@mvista.com>
+ *
+ * 2004 (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/kernel.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/bootmem.h>
+#include <linux/mv643xx.h>
+
+#include <asm/byteorder.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+#include <asm/machdep.h>
+#include <asm/pci-bridge.h>
+#include <asm/delay.h>
+#include <asm/mv64x60.h>
+
+
+/*
+ *****************************************************************************
+ *
+ *	Tables describing how to set up windows on each type of bridge
+ *
+ *****************************************************************************
+ */
+struct mv64x60_32bit_window
+	gt64260_32bit_windows[MV64x60_32BIT_WIN_COUNT] __initdata = {
+	/* CPU->MEM Windows */
+	[MV64x60_CPU2MEM_0_WIN] = {
+		.base_reg		= MV64x60_CPU2MEM_0_BASE,
+		.size_reg		= MV64x60_CPU2MEM_0_SIZE,
+		.base_bits		= 12,
+		.size_bits		= 12,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= 0 },
+	[MV64x60_CPU2MEM_1_WIN] = {
+		.base_reg		= MV64x60_CPU2MEM_1_BASE,
+		.size_reg		= MV64x60_CPU2MEM_1_SIZE,
+		.base_bits		= 12,
+		.size_bits		= 12,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= 0 },
+	[MV64x60_CPU2MEM_2_WIN] = {
+		.base_reg		= MV64x60_CPU2MEM_2_BASE,
+		.size_reg		= MV64x60_CPU2MEM_2_SIZE,
+		.base_bits		= 12,
+		.size_bits		= 12,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= 0 },
+	[MV64x60_CPU2MEM_3_WIN] = {
+		.base_reg		= MV64x60_CPU2MEM_3_BASE,
+		.size_reg		= MV64x60_CPU2MEM_3_SIZE,
+		.base_bits		= 12,
+		.size_bits		= 12,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= 0 },
+	/* CPU->Device Windows */
+	[MV64x60_CPU2DEV_0_WIN] = {
+		.base_reg		= MV64x60_CPU2DEV_0_BASE,
+		.size_reg		= MV64x60_CPU2DEV_0_SIZE,
+		.base_bits		= 12,
+		.size_bits		= 12,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= 0 },
+	[MV64x60_CPU2DEV_1_WIN] = {
+		.base_reg		= MV64x60_CPU2DEV_1_BASE,
+		.size_reg		= MV64x60_CPU2DEV_1_SIZE,
+		.base_bits		= 12,
+		.size_bits		= 12,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= 0 },
+	[MV64x60_CPU2DEV_2_WIN] = {
+		.base_reg		= MV64x60_CPU2DEV_2_BASE,
+		.size_reg		= MV64x60_CPU2DEV_2_SIZE,
+		.base_bits		= 12,
+		.size_bits		= 12,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= 0 },
+	[MV64x60_CPU2DEV_3_WIN] = {
+		.base_reg		= MV64x60_CPU2DEV_3_BASE,
+		.size_reg		= MV64x60_CPU2DEV_3_SIZE,
+		.base_bits		= 12,
+		.size_bits		= 12,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= 0 },
+	/* CPU->Boot Window */
+	[MV64x60_CPU2BOOT_WIN] = {
+		.base_reg		= MV64x60_CPU2BOOT_0_BASE,
+		.size_reg		= MV64x60_CPU2BOOT_0_SIZE,
+		.base_bits		= 12,
+		.size_bits		= 12,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= 0 },
+	/* CPU->PCI 0 Windows */
+	[MV64x60_CPU2PCI0_IO_WIN] = {
+		.base_reg		= MV64x60_CPU2PCI0_IO_BASE,
+		.size_reg		= MV64x60_CPU2PCI0_IO_SIZE,
+		.base_bits		= 12,
+		.size_bits		= 12,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= 0 },
+	[MV64x60_CPU2PCI0_MEM_0_WIN] = {
+		.base_reg		= MV64x60_CPU2PCI0_MEM_0_BASE,
+		.size_reg		= MV64x60_CPU2PCI0_MEM_0_SIZE,
+		.base_bits		= 12,
+		.size_bits		= 12,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= 0 },
+	[MV64x60_CPU2PCI0_MEM_1_WIN] = {
+		.base_reg		= MV64x60_CPU2PCI0_MEM_1_BASE,
+		.size_reg		= MV64x60_CPU2PCI0_MEM_1_SIZE,
+		.base_bits		= 12,
+		.size_bits		= 12,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= 0 },
+	[MV64x60_CPU2PCI0_MEM_2_WIN] = {
+		.base_reg		= MV64x60_CPU2PCI0_MEM_2_BASE,
+		.size_reg		= MV64x60_CPU2PCI0_MEM_2_SIZE,
+		.base_bits		= 12,
+		.size_bits		= 12,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= 0 },
+	[MV64x60_CPU2PCI0_MEM_3_WIN] = {
+		.base_reg		= MV64x60_CPU2PCI0_MEM_3_BASE,
+		.size_reg		= MV64x60_CPU2PCI0_MEM_3_SIZE,
+		.base_bits		= 12,
+		.size_bits		= 12,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= 0 },
+	/* CPU->PCI 1 Windows */
+	[MV64x60_CPU2PCI1_IO_WIN] = {
+		.base_reg		= MV64x60_CPU2PCI1_IO_BASE,
+		.size_reg		= MV64x60_CPU2PCI1_IO_SIZE,
+		.base_bits		= 12,
+		.size_bits		= 12,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= 0 },
+	[MV64x60_CPU2PCI1_MEM_0_WIN] = {
+		.base_reg		= MV64x60_CPU2PCI1_MEM_0_BASE,
+		.size_reg		= MV64x60_CPU2PCI1_MEM_0_SIZE,
+		.base_bits		= 12,
+		.size_bits		= 12,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= 0 },
+	[MV64x60_CPU2PCI1_MEM_1_WIN] = {
+		.base_reg		= MV64x60_CPU2PCI1_MEM_1_BASE,
+		.size_reg		= MV64x60_CPU2PCI1_MEM_1_SIZE,
+		.base_bits		= 12,
+		.size_bits		= 12,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= 0 },
+	[MV64x60_CPU2PCI1_MEM_2_WIN] = {
+		.base_reg		= MV64x60_CPU2PCI1_MEM_2_BASE,
+		.size_reg		= MV64x60_CPU2PCI1_MEM_2_SIZE,
+		.base_bits		= 12,
+		.size_bits		= 12,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= 0 },
+	[MV64x60_CPU2PCI1_MEM_3_WIN] = {
+		.base_reg		= MV64x60_CPU2PCI1_MEM_3_BASE,
+		.size_reg		= MV64x60_CPU2PCI1_MEM_3_SIZE,
+		.base_bits		= 12,
+		.size_bits		= 12,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= 0 },
+	/* CPU->SRAM Window (64260 has no integrated SRAM) */
+	/* CPU->PCI 0 Remap I/O Window */
+	[MV64x60_CPU2PCI0_IO_REMAP_WIN] = {
+		.base_reg		= MV64x60_CPU2PCI0_IO_REMAP,
+		.size_reg		= 0,
+		.base_bits		= 12,
+		.size_bits		= 0,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= 0 },
+	/* CPU->PCI 1 Remap I/O Window */
+	[MV64x60_CPU2PCI1_IO_REMAP_WIN] = {
+		.base_reg		= MV64x60_CPU2PCI1_IO_REMAP,
+		.size_reg		= 0,
+		.base_bits		= 12,
+		.size_bits		= 0,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= 0 },
+	/* CPU Memory Protection Windows */
+	[MV64x60_CPU_PROT_0_WIN] = {
+		.base_reg		= MV64x60_CPU_PROT_BASE_0,
+		.size_reg		= MV64x60_CPU_PROT_SIZE_0,
+		.base_bits		= 12,
+		.size_bits		= 12,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= 0 },
+	[MV64x60_CPU_PROT_1_WIN] = {
+		.base_reg		= MV64x60_CPU_PROT_BASE_1,
+		.size_reg		= MV64x60_CPU_PROT_SIZE_1,
+		.base_bits		= 12,
+		.size_bits		= 12,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= 0 },
+	[MV64x60_CPU_PROT_2_WIN] = {
+		.base_reg		= MV64x60_CPU_PROT_BASE_2,
+		.size_reg		= MV64x60_CPU_PROT_SIZE_2,
+		.base_bits		= 12,
+		.size_bits		= 12,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= 0 },
+	[MV64x60_CPU_PROT_3_WIN] = {
+		.base_reg		= MV64x60_CPU_PROT_BASE_3,
+		.size_reg		= MV64x60_CPU_PROT_SIZE_3,
+		.base_bits		= 12,
+		.size_bits		= 12,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= 0 },
+	/* CPU Snoop Windows */
+	[MV64x60_CPU_SNOOP_0_WIN] = {
+		.base_reg		= GT64260_CPU_SNOOP_BASE_0,
+		.size_reg		= GT64260_CPU_SNOOP_SIZE_0,
+		.base_bits		= 12,
+		.size_bits		= 12,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= 0 },
+	[MV64x60_CPU_SNOOP_1_WIN] = {
+		.base_reg		= GT64260_CPU_SNOOP_BASE_1,
+		.size_reg		= GT64260_CPU_SNOOP_SIZE_1,
+		.base_bits		= 12,
+		.size_bits		= 12,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= 0 },
+	[MV64x60_CPU_SNOOP_2_WIN] = {
+		.base_reg		= GT64260_CPU_SNOOP_BASE_2,
+		.size_reg		= GT64260_CPU_SNOOP_SIZE_2,
+		.base_bits		= 12,
+		.size_bits		= 12,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= 0 },
+	[MV64x60_CPU_SNOOP_3_WIN] = {
+		.base_reg		= GT64260_CPU_SNOOP_BASE_3,
+		.size_reg		= GT64260_CPU_SNOOP_SIZE_3,
+		.base_bits		= 12,
+		.size_bits		= 12,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= 0 },
+	/* PCI 0->System Memory Remap Windows */
+	[MV64x60_PCI02MEM_REMAP_0_WIN] = {
+		.base_reg		= MV64x60_PCI0_SLAVE_MEM_0_REMAP,
+		.size_reg		= 0,
+		.base_bits		= 20,
+		.size_bits		= 0,
+		.get_from_field		= mv64x60_mask,
+		.map_to_field		= mv64x60_mask,
+		.extra			= 0 },
+	[MV64x60_PCI02MEM_REMAP_1_WIN] = {
+		.base_reg		= MV64x60_PCI0_SLAVE_MEM_1_REMAP,
+		.size_reg		= 0,
+		.base_bits		= 20,
+		.size_bits		= 0,
+		.get_from_field		= mv64x60_mask,
+		.map_to_field		= mv64x60_mask,
+		.extra			= 0 },
+	[MV64x60_PCI02MEM_REMAP_2_WIN] = {
+		.base_reg		= MV64x60_PCI0_SLAVE_MEM_1_REMAP,
+		.size_reg		= 0,
+		.base_bits		= 20,
+		.size_bits		= 0,
+		.get_from_field		= mv64x60_mask,
+		.map_to_field		= mv64x60_mask,
+		.extra			= 0 },
+	[MV64x60_PCI02MEM_REMAP_3_WIN] = {
+		.base_reg		= MV64x60_PCI0_SLAVE_MEM_1_REMAP,
+		.size_reg		= 0,
+		.base_bits		= 20,
+		.size_bits		= 0,
+		.get_from_field		= mv64x60_mask,
+		.map_to_field		= mv64x60_mask,
+		.extra			= 0 },
+	/* PCI 1->System Memory Remap Windows */
+	[MV64x60_PCI12MEM_REMAP_0_WIN] = {
+		.base_reg		= MV64x60_PCI1_SLAVE_MEM_0_REMAP,
+		.size_reg		= 0,
+		.base_bits		= 20,
+		.size_bits		= 0,
+		.get_from_field		= mv64x60_mask,
+		.map_to_field		= mv64x60_mask,
+		.extra			= 0 },
+	[MV64x60_PCI12MEM_REMAP_1_WIN] = {
+		.base_reg		= MV64x60_PCI1_SLAVE_MEM_1_REMAP,
+		.size_reg		= 0,
+		.base_bits		= 20,
+		.size_bits		= 0,
+		.get_from_field		= mv64x60_mask,
+		.map_to_field		= mv64x60_mask,
+		.extra			= 0 },
+	[MV64x60_PCI12MEM_REMAP_2_WIN] = {
+		.base_reg		= MV64x60_PCI1_SLAVE_MEM_1_REMAP,
+		.size_reg		= 0,
+		.base_bits		= 20,
+		.size_bits		= 0,
+		.get_from_field		= mv64x60_mask,
+		.map_to_field		= mv64x60_mask,
+		.extra			= 0 },
+	[MV64x60_PCI12MEM_REMAP_3_WIN] = {
+		.base_reg		= MV64x60_PCI1_SLAVE_MEM_1_REMAP,
+		.size_reg		= 0,
+		.base_bits		= 20,
+		.size_bits		= 0,
+		.get_from_field		= mv64x60_mask,
+		.map_to_field		= mv64x60_mask,
+		.extra			= 0 },
+	/* ENET->SRAM Window (64260 doesn't have separate windows) */
+	/* MPSC->SRAM Window (64260 doesn't have separate windows) */
+	/* IDMA->SRAM Window (64260 doesn't have separate windows) */
+};
+
+struct mv64x60_64bit_window
+	gt64260_64bit_windows[MV64x60_64BIT_WIN_COUNT] __initdata = {
+	/* CPU->PCI 0 MEM Remap Windows */
+	[MV64x60_CPU2PCI0_MEM_0_REMAP_WIN] = {
+		.base_hi_reg		= MV64x60_CPU2PCI0_MEM_0_REMAP_HI,
+		.base_lo_reg		= MV64x60_CPU2PCI0_MEM_0_REMAP_LO,
+		.size_reg		= 0,
+		.base_lo_bits		= 12,
+		.size_bits		= 0,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= 0 },
+	[MV64x60_CPU2PCI0_MEM_1_REMAP_WIN] = {
+		.base_hi_reg		= MV64x60_CPU2PCI0_MEM_1_REMAP_HI,
+		.base_lo_reg		= MV64x60_CPU2PCI0_MEM_1_REMAP_LO,
+		.size_reg		= 0,
+		.base_lo_bits		= 12,
+		.size_bits		= 0,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= 0 },
+	[MV64x60_CPU2PCI0_MEM_2_REMAP_WIN] = {
+		.base_hi_reg		= MV64x60_CPU2PCI0_MEM_2_REMAP_HI,
+		.base_lo_reg		= MV64x60_CPU2PCI0_MEM_2_REMAP_LO,
+		.size_reg		= 0,
+		.base_lo_bits		= 12,
+		.size_bits		= 0,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= 0 },
+	[MV64x60_CPU2PCI0_MEM_3_REMAP_WIN] = {
+		.base_hi_reg		= MV64x60_CPU2PCI0_MEM_3_REMAP_HI,
+		.base_lo_reg		= MV64x60_CPU2PCI0_MEM_3_REMAP_LO,
+		.size_reg		= 0,
+		.base_lo_bits		= 12,
+		.size_bits		= 0,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= 0 },
+	/* CPU->PCI 1 MEM Remap Windows */
+	[MV64x60_CPU2PCI1_MEM_0_REMAP_WIN] = {
+		.base_hi_reg		= MV64x60_CPU2PCI1_MEM_0_REMAP_HI,
+		.base_lo_reg		= MV64x60_CPU2PCI1_MEM_0_REMAP_LO,
+		.size_reg		= 0,
+		.base_lo_bits		= 12,
+		.size_bits		= 0,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= 0 },
+	[MV64x60_CPU2PCI1_MEM_1_REMAP_WIN] = {
+		.base_hi_reg		= MV64x60_CPU2PCI1_MEM_1_REMAP_HI,
+		.base_lo_reg		= MV64x60_CPU2PCI1_MEM_1_REMAP_LO,
+		.size_reg		= 0,
+		.base_lo_bits		= 12,
+		.size_bits		= 0,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= 0 },
+	[MV64x60_CPU2PCI1_MEM_2_REMAP_WIN] = {
+		.base_hi_reg		= MV64x60_CPU2PCI1_MEM_2_REMAP_HI,
+		.base_lo_reg		= MV64x60_CPU2PCI1_MEM_2_REMAP_LO,
+		.size_reg		= 0,
+		.base_lo_bits		= 12,
+		.size_bits		= 0,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= 0 },
+	[MV64x60_CPU2PCI1_MEM_3_REMAP_WIN] = {
+		.base_hi_reg		= MV64x60_CPU2PCI1_MEM_3_REMAP_HI,
+		.base_lo_reg		= MV64x60_CPU2PCI1_MEM_3_REMAP_LO,
+		.size_reg		= 0,
+		.base_lo_bits		= 12,
+		.size_bits		= 0,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= 0 },
+	/* PCI 0->MEM Access Control Windows */
+	[MV64x60_PCI02MEM_ACC_CNTL_0_WIN] = {
+		.base_hi_reg		= MV64x60_PCI0_ACC_CNTL_0_BASE_HI,
+		.base_lo_reg		= MV64x60_PCI0_ACC_CNTL_0_BASE_LO,
+		.size_reg		= MV64x60_PCI0_ACC_CNTL_0_SIZE,
+		.base_lo_bits		= 12,
+		.size_bits		= 12,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= 0 },
+	[MV64x60_PCI02MEM_ACC_CNTL_1_WIN] = {
+		.base_hi_reg		= MV64x60_PCI0_ACC_CNTL_1_BASE_HI,
+		.base_lo_reg		= MV64x60_PCI0_ACC_CNTL_1_BASE_LO,
+		.size_reg		= MV64x60_PCI0_ACC_CNTL_1_SIZE,
+		.base_lo_bits		= 12,
+		.size_bits		= 12,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= 0 },
+	[MV64x60_PCI02MEM_ACC_CNTL_2_WIN] = {
+		.base_hi_reg		= MV64x60_PCI0_ACC_CNTL_2_BASE_HI,
+		.base_lo_reg		= MV64x60_PCI0_ACC_CNTL_2_BASE_LO,
+		.size_reg		= MV64x60_PCI0_ACC_CNTL_2_SIZE,
+		.base_lo_bits		= 12,
+		.size_bits		= 12,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= 0 },
+	[MV64x60_PCI02MEM_ACC_CNTL_3_WIN] = {
+		.base_hi_reg		= MV64x60_PCI0_ACC_CNTL_3_BASE_HI,
+		.base_lo_reg		= MV64x60_PCI0_ACC_CNTL_3_BASE_LO,
+		.size_reg		= MV64x60_PCI0_ACC_CNTL_3_SIZE,
+		.base_lo_bits		= 12,
+		.size_bits		= 12,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= 0 },
+	/* PCI 1->MEM Access Control Windows */
+	[MV64x60_PCI12MEM_ACC_CNTL_0_WIN] = {
+		.base_hi_reg		= MV64x60_PCI1_ACC_CNTL_0_BASE_HI,
+		.base_lo_reg		= MV64x60_PCI1_ACC_CNTL_0_BASE_LO,
+		.size_reg		= MV64x60_PCI1_ACC_CNTL_0_SIZE,
+		.base_lo_bits		= 12,
+		.size_bits		= 12,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= 0 },
+	[MV64x60_PCI12MEM_ACC_CNTL_1_WIN] = {
+		.base_hi_reg		= MV64x60_PCI1_ACC_CNTL_1_BASE_HI,
+		.base_lo_reg		= MV64x60_PCI1_ACC_CNTL_1_BASE_LO,
+		.size_reg		= MV64x60_PCI1_ACC_CNTL_1_SIZE,
+		.base_lo_bits		= 12,
+		.size_bits		= 12,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= 0 },
+	[MV64x60_PCI12MEM_ACC_CNTL_2_WIN] = {
+		.base_hi_reg		= MV64x60_PCI1_ACC_CNTL_2_BASE_HI,
+		.base_lo_reg		= MV64x60_PCI1_ACC_CNTL_2_BASE_LO,
+		.size_reg		= MV64x60_PCI1_ACC_CNTL_2_SIZE,
+		.base_lo_bits		= 12,
+		.size_bits		= 12,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= 0 },
+	[MV64x60_PCI12MEM_ACC_CNTL_3_WIN] = {
+		.base_hi_reg		= MV64x60_PCI1_ACC_CNTL_3_BASE_HI,
+		.base_lo_reg		= MV64x60_PCI1_ACC_CNTL_3_BASE_LO,
+		.size_reg		= MV64x60_PCI1_ACC_CNTL_3_SIZE,
+		.base_lo_bits		= 12,
+		.size_bits		= 12,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= 0 },
+	/* PCI 0->MEM Snoop Windows */
+	[MV64x60_PCI02MEM_SNOOP_0_WIN] = {
+		.base_hi_reg		= GT64260_PCI0_SNOOP_0_BASE_HI,
+		.base_lo_reg		= GT64260_PCI0_SNOOP_0_BASE_LO,
+		.size_reg		= GT64260_PCI0_SNOOP_0_SIZE,
+		.base_lo_bits		= 12,
+		.size_bits		= 12,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= 0 },
+	[MV64x60_PCI02MEM_SNOOP_1_WIN] = {
+		.base_hi_reg		= GT64260_PCI0_SNOOP_1_BASE_HI,
+		.base_lo_reg		= GT64260_PCI0_SNOOP_1_BASE_LO,
+		.size_reg		= GT64260_PCI0_SNOOP_1_SIZE,
+		.base_lo_bits		= 12,
+		.size_bits		= 12,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= 0 },
+	[MV64x60_PCI02MEM_SNOOP_2_WIN] = {
+		.base_hi_reg		= GT64260_PCI0_SNOOP_2_BASE_HI,
+		.base_lo_reg		= GT64260_PCI0_SNOOP_2_BASE_LO,
+		.size_reg		= GT64260_PCI0_SNOOP_2_SIZE,
+		.base_lo_bits		= 12,
+		.size_bits		= 12,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= 0 },
+	[MV64x60_PCI02MEM_SNOOP_3_WIN] = {
+		.base_hi_reg		= GT64260_PCI0_SNOOP_3_BASE_HI,
+		.base_lo_reg		= GT64260_PCI0_SNOOP_3_BASE_LO,
+		.size_reg		= GT64260_PCI0_SNOOP_3_SIZE,
+		.base_lo_bits		= 12,
+		.size_bits		= 12,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= 0 },
+	/* PCI 1->MEM Snoop Windows */
+	[MV64x60_PCI12MEM_SNOOP_0_WIN] = {
+		.base_hi_reg		= GT64260_PCI1_SNOOP_0_BASE_HI,
+		.base_lo_reg		= GT64260_PCI1_SNOOP_0_BASE_LO,
+		.size_reg		= GT64260_PCI1_SNOOP_0_SIZE,
+		.base_lo_bits		= 12,
+		.size_bits		= 12,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= 0 },
+	[MV64x60_PCI12MEM_SNOOP_1_WIN] = {
+		.base_hi_reg		= GT64260_PCI1_SNOOP_1_BASE_HI,
+		.base_lo_reg		= GT64260_PCI1_SNOOP_1_BASE_LO,
+		.size_reg		= GT64260_PCI1_SNOOP_1_SIZE,
+		.base_lo_bits		= 12,
+		.size_bits		= 12,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= 0 },
+	[MV64x60_PCI12MEM_SNOOP_2_WIN] = {
+		.base_hi_reg		= GT64260_PCI1_SNOOP_2_BASE_HI,
+		.base_lo_reg		= GT64260_PCI1_SNOOP_2_BASE_LO,
+		.size_reg		= GT64260_PCI1_SNOOP_2_SIZE,
+		.base_lo_bits		= 12,
+		.size_bits		= 12,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= 0 },
+	[MV64x60_PCI12MEM_SNOOP_3_WIN] = {
+		.base_hi_reg		= GT64260_PCI1_SNOOP_3_BASE_HI,
+		.base_lo_reg		= GT64260_PCI1_SNOOP_3_BASE_LO,
+		.size_reg		= GT64260_PCI1_SNOOP_3_SIZE,
+		.base_lo_bits		= 12,
+		.size_bits		= 12,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= 0 },
+};
+
+struct mv64x60_32bit_window
+	mv64360_32bit_windows[MV64x60_32BIT_WIN_COUNT] __initdata = {
+	/* CPU->MEM Windows */
+	[MV64x60_CPU2MEM_0_WIN] = {
+		.base_reg		= MV64x60_CPU2MEM_0_BASE,
+		.size_reg		= MV64x60_CPU2MEM_0_SIZE,
+		.base_bits		= 16,
+		.size_bits		= 16,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= MV64x60_EXTRA_CPUWIN_ENAB | 0 },
+	[MV64x60_CPU2MEM_1_WIN] = {
+		.base_reg		= MV64x60_CPU2MEM_1_BASE,
+		.size_reg		= MV64x60_CPU2MEM_1_SIZE,
+		.base_bits		= 16,
+		.size_bits		= 16,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= MV64x60_EXTRA_CPUWIN_ENAB | 1 },
+	[MV64x60_CPU2MEM_2_WIN] = {
+		.base_reg		= MV64x60_CPU2MEM_2_BASE,
+		.size_reg		= MV64x60_CPU2MEM_2_SIZE,
+		.base_bits		= 16,
+		.size_bits		= 16,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= MV64x60_EXTRA_CPUWIN_ENAB | 2 },
+	[MV64x60_CPU2MEM_3_WIN] = {
+		.base_reg		= MV64x60_CPU2MEM_3_BASE,
+		.size_reg		= MV64x60_CPU2MEM_3_SIZE,
+		.base_bits		= 16,
+		.size_bits		= 16,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= MV64x60_EXTRA_CPUWIN_ENAB | 3 },
+	/* CPU->Device Windows */
+	[MV64x60_CPU2DEV_0_WIN] = {
+		.base_reg		= MV64x60_CPU2DEV_0_BASE,
+		.size_reg		= MV64x60_CPU2DEV_0_SIZE,
+		.base_bits		= 16,
+		.size_bits		= 16,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= MV64x60_EXTRA_CPUWIN_ENAB | 4 },
+	[MV64x60_CPU2DEV_1_WIN] = {
+		.base_reg		= MV64x60_CPU2DEV_1_BASE,
+		.size_reg		= MV64x60_CPU2DEV_1_SIZE,
+		.base_bits		= 16,
+		.size_bits		= 16,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= MV64x60_EXTRA_CPUWIN_ENAB | 5 },
+	[MV64x60_CPU2DEV_2_WIN] = {
+		.base_reg		= MV64x60_CPU2DEV_2_BASE,
+		.size_reg		= MV64x60_CPU2DEV_2_SIZE,
+		.base_bits		= 16,
+		.size_bits		= 16,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= MV64x60_EXTRA_CPUWIN_ENAB | 6 },
+	[MV64x60_CPU2DEV_3_WIN] = {
+		.base_reg		= MV64x60_CPU2DEV_3_BASE,
+		.size_reg		= MV64x60_CPU2DEV_3_SIZE,
+		.base_bits		= 16,
+		.size_bits		= 16,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= MV64x60_EXTRA_CPUWIN_ENAB | 7 },
+	/* CPU->Boot Window */
+	[MV64x60_CPU2BOOT_WIN] = {
+		.base_reg		= MV64x60_CPU2BOOT_0_BASE,
+		.size_reg		= MV64x60_CPU2BOOT_0_SIZE,
+		.base_bits		= 16,
+		.size_bits		= 16,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= MV64x60_EXTRA_CPUWIN_ENAB | 8 },
+	/* CPU->PCI 0 Windows */
+	[MV64x60_CPU2PCI0_IO_WIN] = {
+		.base_reg		= MV64x60_CPU2PCI0_IO_BASE,
+		.size_reg		= MV64x60_CPU2PCI0_IO_SIZE,
+		.base_bits		= 16,
+		.size_bits		= 16,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= MV64x60_EXTRA_CPUWIN_ENAB | 9 },
+	[MV64x60_CPU2PCI0_MEM_0_WIN] = {
+		.base_reg		= MV64x60_CPU2PCI0_MEM_0_BASE,
+		.size_reg		= MV64x60_CPU2PCI0_MEM_0_SIZE,
+		.base_bits		= 16,
+		.size_bits		= 16,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= MV64x60_EXTRA_CPUWIN_ENAB | 10 },
+	[MV64x60_CPU2PCI0_MEM_1_WIN] = {
+		.base_reg		= MV64x60_CPU2PCI0_MEM_1_BASE,
+		.size_reg		= MV64x60_CPU2PCI0_MEM_1_SIZE,
+		.base_bits		= 16,
+		.size_bits		= 16,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= MV64x60_EXTRA_CPUWIN_ENAB | 11 },
+	[MV64x60_CPU2PCI0_MEM_2_WIN] = {
+		.base_reg		= MV64x60_CPU2PCI0_MEM_2_BASE,
+		.size_reg		= MV64x60_CPU2PCI0_MEM_2_SIZE,
+		.base_bits		= 16,
+		.size_bits		= 16,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= MV64x60_EXTRA_CPUWIN_ENAB | 12 },
+	[MV64x60_CPU2PCI0_MEM_3_WIN] = {
+		.base_reg		= MV64x60_CPU2PCI0_MEM_3_BASE,
+		.size_reg		= MV64x60_CPU2PCI0_MEM_3_SIZE,
+		.base_bits		= 16,
+		.size_bits		= 16,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= MV64x60_EXTRA_CPUWIN_ENAB | 13 },
+	/* CPU->PCI 1 Windows */
+	[MV64x60_CPU2PCI1_IO_WIN] = {
+		.base_reg		= MV64x60_CPU2PCI1_IO_BASE,
+		.size_reg		= MV64x60_CPU2PCI1_IO_SIZE,
+		.base_bits		= 16,
+		.size_bits		= 16,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= MV64x60_EXTRA_CPUWIN_ENAB | 14 },
+	[MV64x60_CPU2PCI1_MEM_0_WIN] = {
+		.base_reg		= MV64x60_CPU2PCI1_MEM_0_BASE,
+		.size_reg		= MV64x60_CPU2PCI1_MEM_0_SIZE,
+		.base_bits		= 16,
+		.size_bits		= 16,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= MV64x60_EXTRA_CPUWIN_ENAB | 15 },
+	[MV64x60_CPU2PCI1_MEM_1_WIN] = {
+		.base_reg		= MV64x60_CPU2PCI1_MEM_1_BASE,
+		.size_reg		= MV64x60_CPU2PCI1_MEM_1_SIZE,
+		.base_bits		= 16,
+		.size_bits		= 16,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= MV64x60_EXTRA_CPUWIN_ENAB | 16 },
+	[MV64x60_CPU2PCI1_MEM_2_WIN] = {
+		.base_reg		= MV64x60_CPU2PCI1_MEM_2_BASE,
+		.size_reg		= MV64x60_CPU2PCI1_MEM_2_SIZE,
+		.base_bits		= 16,
+		.size_bits		= 16,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= MV64x60_EXTRA_CPUWIN_ENAB | 17 },
+	[MV64x60_CPU2PCI1_MEM_3_WIN] = {
+		.base_reg		= MV64x60_CPU2PCI1_MEM_3_BASE,
+		.size_reg		= MV64x60_CPU2PCI1_MEM_3_SIZE,
+		.base_bits		= 16,
+		.size_bits		= 16,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= MV64x60_EXTRA_CPUWIN_ENAB | 18 },
+	/* CPU->SRAM Window */
+	[MV64x60_CPU2SRAM_WIN] = {
+		.base_reg		= MV64360_CPU2SRAM_BASE,
+		.size_reg		= 0,
+		.base_bits		= 16,
+		.size_bits		= 0,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= MV64x60_EXTRA_CPUWIN_ENAB | 19 },
+	/* CPU->PCI 0 Remap I/O Window */
+	[MV64x60_CPU2PCI0_IO_REMAP_WIN] = {
+		.base_reg		= MV64x60_CPU2PCI0_IO_REMAP,
+		.size_reg		= 0,
+		.base_bits		= 16,
+		.size_bits		= 0,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= 0 },
+	/* CPU->PCI 1 Remap I/O Window */
+	[MV64x60_CPU2PCI1_IO_REMAP_WIN] = {
+		.base_reg		= MV64x60_CPU2PCI1_IO_REMAP,
+		.size_reg		= 0,
+		.base_bits		= 16,
+		.size_bits		= 0,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= 0 },
+	/* CPU Memory Protection Windows */
+	[MV64x60_CPU_PROT_0_WIN] = {
+		.base_reg		= MV64x60_CPU_PROT_BASE_0,
+		.size_reg		= MV64x60_CPU_PROT_SIZE_0,
+		.base_bits		= 16,
+		.size_bits		= 16,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= MV64x60_EXTRA_CPUPROT_ENAB | 31 },
+	[MV64x60_CPU_PROT_1_WIN] = {
+		.base_reg		= MV64x60_CPU_PROT_BASE_1,
+		.size_reg		= MV64x60_CPU_PROT_SIZE_1,
+		.base_bits		= 16,
+		.size_bits		= 16,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= MV64x60_EXTRA_CPUPROT_ENAB | 31 },
+	[MV64x60_CPU_PROT_2_WIN] = {
+		.base_reg		= MV64x60_CPU_PROT_BASE_2,
+		.size_reg		= MV64x60_CPU_PROT_SIZE_2,
+		.base_bits		= 16,
+		.size_bits		= 16,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= MV64x60_EXTRA_CPUPROT_ENAB | 31 },
+	[MV64x60_CPU_PROT_3_WIN] = {
+		.base_reg		= MV64x60_CPU_PROT_BASE_3,
+		.size_reg		= MV64x60_CPU_PROT_SIZE_3,
+		.base_bits		= 16,
+		.size_bits		= 16,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= MV64x60_EXTRA_CPUPROT_ENAB | 31 },
+	/* CPU Snoop Windows -- don't exist on 64360 */
+	/* PCI 0->System Memory Remap Windows */
+	[MV64x60_PCI02MEM_REMAP_0_WIN] = {
+		.base_reg		= MV64x60_PCI0_SLAVE_MEM_0_REMAP,
+		.size_reg		= 0,
+		.base_bits		= 20,
+		.size_bits		= 0,
+		.get_from_field		= mv64x60_mask,
+		.map_to_field		= mv64x60_mask,
+		.extra			= 0 },
+	[MV64x60_PCI02MEM_REMAP_1_WIN] = {
+		.base_reg		= MV64x60_PCI0_SLAVE_MEM_1_REMAP,
+		.size_reg		= 0,
+		.base_bits		= 20,
+		.size_bits		= 0,
+		.get_from_field		= mv64x60_mask,
+		.map_to_field		= mv64x60_mask,
+		.extra			= 0 },
+	[MV64x60_PCI02MEM_REMAP_2_WIN] = {
+		.base_reg		= MV64x60_PCI0_SLAVE_MEM_1_REMAP,
+		.size_reg		= 0,
+		.base_bits		= 20,
+		.size_bits		= 0,
+		.get_from_field		= mv64x60_mask,
+		.map_to_field		= mv64x60_mask,
+		.extra			= 0 },
+	[MV64x60_PCI02MEM_REMAP_3_WIN] = {
+		.base_reg		= MV64x60_PCI0_SLAVE_MEM_1_REMAP,
+		.size_reg		= 0,
+		.base_bits		= 20,
+		.size_bits		= 0,
+		.get_from_field		= mv64x60_mask,
+		.map_to_field		= mv64x60_mask,
+		.extra			= 0 },
+	/* PCI 1->System Memory Remap Windows */
+	[MV64x60_PCI12MEM_REMAP_0_WIN] = {
+		.base_reg		= MV64x60_PCI1_SLAVE_MEM_0_REMAP,
+		.size_reg		= 0,
+		.base_bits		= 20,
+		.size_bits		= 0,
+		.get_from_field		= mv64x60_mask,
+		.map_to_field		= mv64x60_mask,
+		.extra			= 0 },
+	[MV64x60_PCI12MEM_REMAP_1_WIN] = {
+		.base_reg		= MV64x60_PCI1_SLAVE_MEM_1_REMAP,
+		.size_reg		= 0,
+		.base_bits		= 20,
+		.size_bits		= 0,
+		.get_from_field		= mv64x60_mask,
+		.map_to_field		= mv64x60_mask,
+		.extra			= 0 },
+	[MV64x60_PCI12MEM_REMAP_2_WIN] = {
+		.base_reg		= MV64x60_PCI1_SLAVE_MEM_1_REMAP,
+		.size_reg		= 0,
+		.base_bits		= 20,
+		.size_bits		= 0,
+		.get_from_field		= mv64x60_mask,
+		.map_to_field		= mv64x60_mask,
+		.extra			= 0 },
+	[MV64x60_PCI12MEM_REMAP_3_WIN] = {
+		.base_reg		= MV64x60_PCI1_SLAVE_MEM_1_REMAP,
+		.size_reg		= 0,
+		.base_bits		= 20,
+		.size_bits		= 0,
+		.get_from_field		= mv64x60_mask,
+		.map_to_field		= mv64x60_mask,
+		.extra			= 0 },
+	/* ENET->System Memory Windows */
+	[MV64x60_ENET2MEM_0_WIN] = {
+		.base_reg		= MV64360_ENET2MEM_0_BASE,
+		.size_reg		= MV64360_ENET2MEM_0_SIZE,
+		.base_bits		= 16,
+		.size_bits		= 16,
+		.get_from_field		= mv64x60_mask,
+		.map_to_field		= mv64x60_mask,
+		.extra			= MV64x60_EXTRA_ENET_ENAB | 0 },
+	[MV64x60_ENET2MEM_1_WIN] = {
+		.base_reg		= MV64360_ENET2MEM_1_BASE,
+		.size_reg		= MV64360_ENET2MEM_1_SIZE,
+		.base_bits		= 16,
+		.size_bits		= 16,
+		.get_from_field		= mv64x60_mask,
+		.map_to_field		= mv64x60_mask,
+		.extra			= MV64x60_EXTRA_ENET_ENAB | 1 },
+	[MV64x60_ENET2MEM_2_WIN] = {
+		.base_reg		= MV64360_ENET2MEM_2_BASE,
+		.size_reg		= MV64360_ENET2MEM_2_SIZE,
+		.base_bits		= 16,
+		.size_bits		= 16,
+		.get_from_field		= mv64x60_mask,
+		.map_to_field		= mv64x60_mask,
+		.extra			= MV64x60_EXTRA_ENET_ENAB | 2 },
+	[MV64x60_ENET2MEM_3_WIN] = {
+		.base_reg		= MV64360_ENET2MEM_3_BASE,
+		.size_reg		= MV64360_ENET2MEM_3_SIZE,
+		.base_bits		= 16,
+		.size_bits		= 16,
+		.get_from_field		= mv64x60_mask,
+		.map_to_field		= mv64x60_mask,
+		.extra			= MV64x60_EXTRA_ENET_ENAB | 3 },
+	[MV64x60_ENET2MEM_4_WIN] = {
+		.base_reg		= MV64360_ENET2MEM_4_BASE,
+		.size_reg		= MV64360_ENET2MEM_4_SIZE,
+		.base_bits		= 16,
+		.size_bits		= 16,
+		.get_from_field		= mv64x60_mask,
+		.map_to_field		= mv64x60_mask,
+		.extra			= MV64x60_EXTRA_ENET_ENAB | 4 },
+	[MV64x60_ENET2MEM_5_WIN] = {
+		.base_reg		= MV64360_ENET2MEM_5_BASE,
+		.size_reg		= MV64360_ENET2MEM_5_SIZE,
+		.base_bits		= 16,
+		.size_bits		= 16,
+		.get_from_field		= mv64x60_mask,
+		.map_to_field		= mv64x60_mask,
+		.extra			= MV64x60_EXTRA_ENET_ENAB | 5 },
+	/* MPSC->System Memory Windows */
+	[MV64x60_MPSC2MEM_0_WIN] = {
+		.base_reg		= MV64360_MPSC2MEM_0_BASE,
+		.size_reg		= MV64360_MPSC2MEM_0_SIZE,
+		.base_bits		= 16,
+		.size_bits		= 16,
+		.get_from_field		= mv64x60_mask,
+		.map_to_field		= mv64x60_mask,
+		.extra			= MV64x60_EXTRA_MPSC_ENAB | 0 },
+	[MV64x60_MPSC2MEM_1_WIN] = {
+		.base_reg		= MV64360_MPSC2MEM_1_BASE,
+		.size_reg		= MV64360_MPSC2MEM_1_SIZE,
+		.base_bits		= 16,
+		.size_bits		= 16,
+		.get_from_field		= mv64x60_mask,
+		.map_to_field		= mv64x60_mask,
+		.extra			= MV64x60_EXTRA_MPSC_ENAB | 1 },
+	[MV64x60_MPSC2MEM_2_WIN] = {
+		.base_reg		= MV64360_MPSC2MEM_2_BASE,
+		.size_reg		= MV64360_MPSC2MEM_2_SIZE,
+		.base_bits		= 16,
+		.size_bits		= 16,
+		.get_from_field		= mv64x60_mask,
+		.map_to_field		= mv64x60_mask,
+		.extra			= MV64x60_EXTRA_MPSC_ENAB | 2 },
+	[MV64x60_MPSC2MEM_3_WIN] = {
+		.base_reg		= MV64360_MPSC2MEM_3_BASE,
+		.size_reg		= MV64360_MPSC2MEM_3_SIZE,
+		.base_bits		= 16,
+		.size_bits		= 16,
+		.get_from_field		= mv64x60_mask,
+		.map_to_field		= mv64x60_mask,
+		.extra			= MV64x60_EXTRA_MPSC_ENAB | 3 },
+	/* IDMA->System Memory Windows */
+	[MV64x60_IDMA2MEM_0_WIN] = {
+		.base_reg		= MV64360_IDMA2MEM_0_BASE,
+		.size_reg		= MV64360_IDMA2MEM_0_SIZE,
+		.base_bits		= 16,
+		.size_bits		= 16,
+		.get_from_field		= mv64x60_mask,
+		.map_to_field		= mv64x60_mask,
+		.extra			= MV64x60_EXTRA_IDMA_ENAB | 0 },
+	[MV64x60_IDMA2MEM_1_WIN] = {
+		.base_reg		= MV64360_IDMA2MEM_1_BASE,
+		.size_reg		= MV64360_IDMA2MEM_1_SIZE,
+		.base_bits		= 16,
+		.size_bits		= 16,
+		.get_from_field		= mv64x60_mask,
+		.map_to_field		= mv64x60_mask,
+		.extra			= MV64x60_EXTRA_IDMA_ENAB | 1 },
+	[MV64x60_IDMA2MEM_2_WIN] = {
+		.base_reg		= MV64360_IDMA2MEM_2_BASE,
+		.size_reg		= MV64360_IDMA2MEM_2_SIZE,
+		.base_bits		= 16,
+		.size_bits		= 16,
+		.get_from_field		= mv64x60_mask,
+		.map_to_field		= mv64x60_mask,
+		.extra			= MV64x60_EXTRA_IDMA_ENAB | 2 },
+	[MV64x60_IDMA2MEM_3_WIN] = {
+		.base_reg		= MV64360_IDMA2MEM_3_BASE,
+		.size_reg		= MV64360_IDMA2MEM_3_SIZE,
+		.base_bits		= 16,
+		.size_bits		= 16,
+		.get_from_field		= mv64x60_mask,
+		.map_to_field		= mv64x60_mask,
+		.extra			= MV64x60_EXTRA_IDMA_ENAB | 3 },
+	[MV64x60_IDMA2MEM_4_WIN] = {
+		.base_reg		= MV64360_IDMA2MEM_4_BASE,
+		.size_reg		= MV64360_IDMA2MEM_4_SIZE,
+		.base_bits		= 16,
+		.size_bits		= 16,
+		.get_from_field		= mv64x60_mask,
+		.map_to_field		= mv64x60_mask,
+		.extra			= MV64x60_EXTRA_IDMA_ENAB | 4 },
+	[MV64x60_IDMA2MEM_5_WIN] = {
+		.base_reg		= MV64360_IDMA2MEM_5_BASE,
+		.size_reg		= MV64360_IDMA2MEM_5_SIZE,
+		.base_bits		= 16,
+		.size_bits		= 16,
+		.get_from_field		= mv64x60_mask,
+		.map_to_field		= mv64x60_mask,
+		.extra			= MV64x60_EXTRA_IDMA_ENAB | 5 },
+	[MV64x60_IDMA2MEM_6_WIN] = {
+		.base_reg		= MV64360_IDMA2MEM_6_BASE,
+		.size_reg		= MV64360_IDMA2MEM_6_SIZE,
+		.base_bits		= 16,
+		.size_bits		= 16,
+		.get_from_field		= mv64x60_mask,
+		.map_to_field		= mv64x60_mask,
+		.extra			= MV64x60_EXTRA_IDMA_ENAB | 6 },
+	[MV64x60_IDMA2MEM_7_WIN] = {
+		.base_reg		= MV64360_IDMA2MEM_7_BASE,
+		.size_reg		= MV64360_IDMA2MEM_7_SIZE,
+		.base_bits		= 16,
+		.size_bits		= 16,
+		.get_from_field		= mv64x60_mask,
+		.map_to_field		= mv64x60_mask,
+		.extra			= MV64x60_EXTRA_IDMA_ENAB | 7 },
+};
+
+struct mv64x60_64bit_window
+	mv64360_64bit_windows[MV64x60_64BIT_WIN_COUNT] __initdata = {
+	/* CPU->PCI 0 MEM Remap Windows */
+	[MV64x60_CPU2PCI0_MEM_0_REMAP_WIN] = {
+		.base_hi_reg		= MV64x60_CPU2PCI0_MEM_0_REMAP_HI,
+		.base_lo_reg		= MV64x60_CPU2PCI0_MEM_0_REMAP_LO,
+		.size_reg		= 0,
+		.base_lo_bits		= 16,
+		.size_bits		= 0,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= 0 },
+	[MV64x60_CPU2PCI0_MEM_1_REMAP_WIN] = {
+		.base_hi_reg		= MV64x60_CPU2PCI0_MEM_1_REMAP_HI,
+		.base_lo_reg		= MV64x60_CPU2PCI0_MEM_1_REMAP_LO,
+		.size_reg		= 0,
+		.base_lo_bits		= 16,
+		.size_bits		= 0,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= 0 },
+	[MV64x60_CPU2PCI0_MEM_2_REMAP_WIN] = {
+		.base_hi_reg		= MV64x60_CPU2PCI0_MEM_2_REMAP_HI,
+		.base_lo_reg		= MV64x60_CPU2PCI0_MEM_2_REMAP_LO,
+		.size_reg		= 0,
+		.base_lo_bits		= 16,
+		.size_bits		= 0,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= 0 },
+	[MV64x60_CPU2PCI0_MEM_3_REMAP_WIN] = {
+		.base_hi_reg		= MV64x60_CPU2PCI0_MEM_3_REMAP_HI,
+		.base_lo_reg		= MV64x60_CPU2PCI0_MEM_3_REMAP_LO,
+		.size_reg		= 0,
+		.base_lo_bits		= 16,
+		.size_bits		= 0,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= 0 },
+	/* CPU->PCI 1 MEM Remap Windows */
+	[MV64x60_CPU2PCI1_MEM_0_REMAP_WIN] = {
+		.base_hi_reg		= MV64x60_CPU2PCI1_MEM_0_REMAP_HI,
+		.base_lo_reg		= MV64x60_CPU2PCI1_MEM_0_REMAP_LO,
+		.size_reg		= 0,
+		.base_lo_bits		= 16,
+		.size_bits		= 0,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= 0 },
+	[MV64x60_CPU2PCI1_MEM_1_REMAP_WIN] = {
+		.base_hi_reg		= MV64x60_CPU2PCI1_MEM_1_REMAP_HI,
+		.base_lo_reg		= MV64x60_CPU2PCI1_MEM_1_REMAP_LO,
+		.size_reg		= 0,
+		.base_lo_bits		= 16,
+		.size_bits		= 0,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= 0 },
+	[MV64x60_CPU2PCI1_MEM_2_REMAP_WIN] = {
+		.base_hi_reg		= MV64x60_CPU2PCI1_MEM_2_REMAP_HI,
+		.base_lo_reg		= MV64x60_CPU2PCI1_MEM_2_REMAP_LO,
+		.size_reg		= 0,
+		.base_lo_bits		= 16,
+		.size_bits		= 0,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= 0 },
+	[MV64x60_CPU2PCI1_MEM_3_REMAP_WIN] = {
+		.base_hi_reg		= MV64x60_CPU2PCI1_MEM_3_REMAP_HI,
+		.base_lo_reg		= MV64x60_CPU2PCI1_MEM_3_REMAP_LO,
+		.size_reg		= 0,
+		.base_lo_bits		= 16,
+		.size_bits		= 0,
+		.get_from_field		= mv64x60_shift_left,
+		.map_to_field		= mv64x60_shift_right,
+		.extra			= 0 },
+	/* PCI 0->MEM Access Control Windows */
+	[MV64x60_PCI02MEM_ACC_CNTL_0_WIN] = {
+		.base_hi_reg		= MV64x60_PCI0_ACC_CNTL_0_BASE_HI,
+		.base_lo_reg		= MV64x60_PCI0_ACC_CNTL_0_BASE_LO,
+		.size_reg		= MV64x60_PCI0_ACC_CNTL_0_SIZE,
+		.base_lo_bits		= 20,
+		.size_bits		= 20,
+		.get_from_field		= mv64x60_mask,
+		.map_to_field		= mv64x60_mask,
+		.extra			= MV64x60_EXTRA_PCIACC_ENAB | 0 },
+	[MV64x60_PCI02MEM_ACC_CNTL_1_WIN] = {
+		.base_hi_reg		= MV64x60_PCI0_ACC_CNTL_1_BASE_HI,
+		.base_lo_reg		= MV64x60_PCI0_ACC_CNTL_1_BASE_LO,
+		.size_reg		= MV64x60_PCI0_ACC_CNTL_1_SIZE,
+		.base_lo_bits		= 20,
+		.size_bits		= 20,
+		.get_from_field		= mv64x60_mask,
+		.map_to_field		= mv64x60_mask,
+		.extra			= MV64x60_EXTRA_PCIACC_ENAB | 0 },
+	[MV64x60_PCI02MEM_ACC_CNTL_2_WIN] = {
+		.base_hi_reg		= MV64x60_PCI0_ACC_CNTL_2_BASE_HI,
+		.base_lo_reg		= MV64x60_PCI0_ACC_CNTL_2_BASE_LO,
+		.size_reg		= MV64x60_PCI0_ACC_CNTL_2_SIZE,
+		.base_lo_bits		= 20,
+		.size_bits		= 20,
+		.get_from_field		= mv64x60_mask,
+		.map_to_field		= mv64x60_mask,
+		.extra			= MV64x60_EXTRA_PCIACC_ENAB | 0 },
+	[MV64x60_PCI02MEM_ACC_CNTL_3_WIN] = {
+		.base_hi_reg		= MV64x60_PCI0_ACC_CNTL_3_BASE_HI,
+		.base_lo_reg		= MV64x60_PCI0_ACC_CNTL_3_BASE_LO,
+		.size_reg		= MV64x60_PCI0_ACC_CNTL_3_SIZE,
+		.base_lo_bits		= 20,
+		.size_bits		= 20,
+		.get_from_field		= mv64x60_mask,
+		.map_to_field		= mv64x60_mask,
+		.extra			= MV64x60_EXTRA_PCIACC_ENAB | 0 },
+	/* PCI 1->MEM Access Control Windows */
+	[MV64x60_PCI12MEM_ACC_CNTL_0_WIN] = {
+		.base_hi_reg		= MV64x60_PCI1_ACC_CNTL_0_BASE_HI,
+		.base_lo_reg		= MV64x60_PCI1_ACC_CNTL_0_BASE_LO,
+		.size_reg		= MV64x60_PCI1_ACC_CNTL_0_SIZE,
+		.base_lo_bits		= 20,
+		.size_bits		= 20,
+		.get_from_field		= mv64x60_mask,
+		.map_to_field		= mv64x60_mask,
+		.extra			= MV64x60_EXTRA_PCIACC_ENAB | 0 },
+	[MV64x60_PCI12MEM_ACC_CNTL_1_WIN] = {
+		.base_hi_reg		= MV64x60_PCI1_ACC_CNTL_1_BASE_HI,
+		.base_lo_reg		= MV64x60_PCI1_ACC_CNTL_1_BASE_LO,
+		.size_reg		= MV64x60_PCI1_ACC_CNTL_1_SIZE,
+		.base_lo_bits		= 20,
+		.size_bits		= 20,
+		.get_from_field		= mv64x60_mask,
+		.map_to_field		= mv64x60_mask,
+		.extra			= MV64x60_EXTRA_PCIACC_ENAB | 0 },
+	[MV64x60_PCI12MEM_ACC_CNTL_2_WIN] = {
+		.base_hi_reg		= MV64x60_PCI1_ACC_CNTL_2_BASE_HI,
+		.base_lo_reg		= MV64x60_PCI1_ACC_CNTL_2_BASE_LO,
+		.size_reg		= MV64x60_PCI1_ACC_CNTL_2_SIZE,
+		.base_lo_bits		= 20,
+		.size_bits		= 20,
+		.get_from_field		= mv64x60_mask,
+		.map_to_field		= mv64x60_mask,
+		.extra			= MV64x60_EXTRA_PCIACC_ENAB | 0 },
+	[MV64x60_PCI12MEM_ACC_CNTL_3_WIN] = {
+		.base_hi_reg		= MV64x60_PCI1_ACC_CNTL_3_BASE_HI,
+		.base_lo_reg		= MV64x60_PCI1_ACC_CNTL_3_BASE_LO,
+		.size_reg		= MV64x60_PCI1_ACC_CNTL_3_SIZE,
+		.base_lo_bits		= 20,
+		.size_bits		= 20,
+		.get_from_field		= mv64x60_mask,
+		.map_to_field		= mv64x60_mask,
+		.extra			= MV64x60_EXTRA_PCIACC_ENAB | 0 },
+	/* PCI 0->MEM Snoop Windows -- don't exist on 64360 */
+	/* PCI 1->MEM Snoop Windows -- don't exist on 64360 */
+};
diff -Nru a/arch/ppc/syslib/open_pic.c b/arch/ppc/syslib/open_pic.c
--- a/arch/ppc/syslib/open_pic.c	2005-03-01 23:38:58 -08:00
+++ b/arch/ppc/syslib/open_pic.c	2005-03-01 23:38:58 -08:00
@@ -32,8 +32,8 @@
 #define OPENPIC_BIG_ENDIAN
 #endif
 
-void* OpenPIC_Addr;
-static volatile struct OpenPIC *OpenPIC = NULL;
+void __iomem *OpenPIC_Addr;
+static volatile struct OpenPIC __iomem *OpenPIC = NULL;
 
 /*
  * We define OpenPIC_InitSenses table thusly:
@@ -47,7 +47,7 @@
 static u_int NumProcessors;
 static u_int NumSources;
 static int open_pic_irq_offset;
-static volatile OpenPIC_Source *ISR[NR_IRQS];
+static volatile OpenPIC_Source __iomem *ISR[NR_IRQS];
 static int openpic_cascade_irq = -1;
 static int (*openpic_cascade_fn)(struct pt_regs *);
 
@@ -163,7 +163,7 @@
 #define check_arg_cpu(cpu)	do {} while (0)
 #endif
 
-u_int openpic_read(volatile u_int *addr)
+u_int openpic_read(volatile u_int __iomem *addr)
 {
 	u_int val;
 
@@ -175,7 +175,7 @@
 	return val;
 }
 
-static inline void openpic_write(volatile u_int *addr, u_int val)
+static inline void openpic_write(volatile u_int __iomem *addr, u_int val)
 {
 #ifdef OPENPIC_BIG_ENDIAN
 	out_be32(addr, val);
@@ -184,30 +184,30 @@
 #endif
 }
 
-static inline u_int openpic_readfield(volatile u_int *addr, u_int mask)
+static inline u_int openpic_readfield(volatile u_int __iomem *addr, u_int mask)
 {
 	u_int val = openpic_read(addr);
 	return val & mask;
 }
 
-inline void openpic_writefield(volatile u_int *addr, u_int mask,
+inline void openpic_writefield(volatile u_int __iomem *addr, u_int mask,
 			       u_int field)
 {
 	u_int val = openpic_read(addr);
 	openpic_write(addr, (val & ~mask) | (field & mask));
 }
 
-static inline void openpic_clearfield(volatile u_int *addr, u_int mask)
+static inline void openpic_clearfield(volatile u_int __iomem *addr, u_int mask)
 {
 	openpic_writefield(addr, mask, 0);
 }
 
-static inline void openpic_setfield(volatile u_int *addr, u_int mask)
+static inline void openpic_setfield(volatile u_int __iomem *addr, u_int mask)
 {
 	openpic_writefield(addr, mask, mask);
 }
 
-static void openpic_safe_writefield(volatile u_int *addr, u_int mask,
+static void openpic_safe_writefield(volatile u_int __iomem *addr, u_int mask,
 				    u_int field)
 {
 	openpic_setfield(addr, OPENPIC_MASK);
@@ -217,7 +217,7 @@
 
 #ifdef CONFIG_SMP
 /* yes this is right ... bug, feature, you decide! -- tgall */
-u_int openpic_read_IPI(volatile u_int* addr)
+u_int openpic_read_IPI(volatile u_int __iomem * addr)
 {
          u_int val = 0;
 #if defined(OPENPIC_BIG_ENDIAN) || defined(CONFIG_POWER3)
@@ -229,23 +229,23 @@
 }
 
 /* because of the power3 be / le above, this is needed */
-inline void openpic_writefield_IPI(volatile u_int* addr, u_int mask, u_int field)
+inline void openpic_writefield_IPI(volatile u_int __iomem * addr, u_int mask, u_int field)
 {
         u_int  val = openpic_read_IPI(addr);
         openpic_write(addr, (val & ~mask) | (field & mask));
 }
 
-static inline void openpic_clearfield_IPI(volatile u_int *addr, u_int mask)
+static inline void openpic_clearfield_IPI(volatile u_int __iomem *addr, u_int mask)
 {
         openpic_writefield_IPI(addr, mask, 0);
 }
 
-static inline void openpic_setfield_IPI(volatile u_int *addr, u_int mask)
+static inline void openpic_setfield_IPI(volatile u_int __iomem *addr, u_int mask)
 {
         openpic_writefield_IPI(addr, mask, mask);
 }
 
-static void openpic_safe_writefield_IPI(volatile u_int *addr, u_int mask, u_int field)
+static void openpic_safe_writefield_IPI(volatile u_int __iomem *addr, u_int mask, u_int field)
 {
         openpic_setfield_IPI(addr, OPENPIC_MASK);
 
@@ -287,16 +287,16 @@
 }
 #endif
 
-void __init openpic_set_sources(int first_irq, int num_irqs, void *first_ISR)
+void __init openpic_set_sources(int first_irq, int num_irqs, void __iomem *first_ISR)
 {
-	volatile OpenPIC_Source *src = first_ISR;
+	volatile OpenPIC_Source __iomem *src = first_ISR;
 	int i, last_irq;
 
 	last_irq = first_irq + num_irqs;
 	if (last_irq > NumSources)
 		NumSources = last_irq;
 	if (src == 0)
-		src = &((struct OpenPIC *)OpenPIC_Addr)->Source[first_irq];
+		src = &((struct OpenPIC __iomem *)OpenPIC_Addr)->Source[first_irq];
 	for (i = first_irq; i < last_irq; ++i, ++src)
 		ISR[i] = src;
 }
@@ -318,7 +318,7 @@
 		printk("No OpenPIC found !\n");
 		return;
 	}
-	OpenPIC = (volatile struct OpenPIC *)OpenPIC_Addr;
+	OpenPIC = (volatile struct OpenPIC __iomem *)OpenPIC_Addr;
 
 #ifdef CONFIG_EPIC_SERIAL_MODE
 	/* Have to start from ground zero.
@@ -531,7 +531,7 @@
 }
 
 #if defined(CONFIG_SMP) || defined(CONFIG_PM)
-static spinlock_t openpic_setup_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(openpic_setup_lock);
 #endif
 
 #ifdef CONFIG_SMP
@@ -711,7 +711,7 @@
  */
 static void openpic_enable_irq(u_int irq)
 {
-	volatile u_int *vpp;
+	volatile u_int __iomem *vpp;
 
 	check_arg_irq(irq);
 	vpp = &ISR[irq - open_pic_irq_offset]->Vector_Priority;
@@ -724,7 +724,7 @@
 
 static void openpic_disable_irq(u_int irq)
 {
-	volatile u_int *vpp;
+	volatile u_int __iomem *vpp;
 	u32 vp;
 
 	check_arg_irq(irq);
diff -Nru a/arch/ppc/syslib/open_pic2.c b/arch/ppc/syslib/open_pic2.c
--- a/arch/ppc/syslib/open_pic2.c	2005-03-01 23:38:54 -08:00
+++ b/arch/ppc/syslib/open_pic2.c	2005-03-01 23:38:54 -08:00
@@ -386,7 +386,7 @@
 			   vec);
 }
 
-static spinlock_t openpic2_setup_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(openpic2_setup_lock);
 
 /*
  *  Initialize a timer interrupt (and disable it)
diff -Nru a/arch/ppc/syslib/open_pic_defs.h b/arch/ppc/syslib/open_pic_defs.h
--- a/arch/ppc/syslib/open_pic_defs.h	2005-03-01 23:39:08 -08:00
+++ b/arch/ppc/syslib/open_pic_defs.h	2005-03-01 23:39:08 -08:00
@@ -172,7 +172,7 @@
     OpenPIC_Processor Processor[OPENPIC_MAX_PROCESSORS];
 };
 
-extern volatile struct OpenPIC *OpenPIC;
+extern volatile struct OpenPIC __iomem *OpenPIC;
 
 
     /*
diff -Nru a/arch/ppc/syslib/ppc403_pic.c b/arch/ppc/syslib/ppc403_pic.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/ppc/syslib/ppc403_pic.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,127 @@
+/*
+ *
+ *    Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
+ *
+ *    Module name: ppc403_pic.c
+ *
+ *    Description:
+ *      Interrupt controller driver for PowerPC 403-based processors.
+ */
+
+/*
+ * The PowerPC 403 cores' Asynchronous Interrupt Controller (AIC) has
+ * 32 possible interrupts, a majority of which are not implemented on
+ * all cores. There are six configurable, external interrupt pins and
+ * there are eight internal interrupts for the on-chip serial port
+ * (SPU), DMA controller, and JTAG controller.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/signal.h>
+#include <linux/stddef.h>
+
+#include <asm/processor.h>
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/ppc4xx_pic.h>
+
+/* Function Prototypes */
+
+static void ppc403_aic_enable(unsigned int irq);
+static void ppc403_aic_disable(unsigned int irq);
+static void ppc403_aic_disable_and_ack(unsigned int irq);
+
+static struct hw_interrupt_type ppc403_aic = {
+	"403GC AIC",
+	NULL,
+	NULL,
+	ppc403_aic_enable,
+	ppc403_aic_disable,
+	ppc403_aic_disable_and_ack,
+	0
+};
+
+int
+ppc403_pic_get_irq(struct pt_regs *regs)
+{
+	int irq;
+	unsigned long bits;
+
+	/*
+	 * Only report the status of those interrupts that are actually
+	 * enabled.
+	 */
+
+	bits = mfdcr(DCRN_EXISR) & mfdcr(DCRN_EXIER);
+
+	/*
+	 * Walk through the interrupts from highest priority to lowest, and
+	 * report the first pending interrupt found.
+	 * We want PPC, not C bit numbering, so just subtract the ffs()
+	 * result from 32.
+	 */
+	irq = 32 - ffs(bits);
+
+	if (irq == NR_AIC_IRQS)
+		irq = -1;
+
+	return (irq);
+}
+
+static void
+ppc403_aic_enable(unsigned int irq)
+{
+	int bit, word;
+
+	bit = irq & 0x1f;
+	word = irq >> 5;
+
+	ppc_cached_irq_mask[word] |= (1 << (31 - bit));
+	mtdcr(DCRN_EXIER, ppc_cached_irq_mask[word]);
+}
+
+static void
+ppc403_aic_disable(unsigned int irq)
+{
+	int bit, word;
+
+	bit = irq & 0x1f;
+	word = irq >> 5;
+
+	ppc_cached_irq_mask[word] &= ~(1 << (31 - bit));
+	mtdcr(DCRN_EXIER, ppc_cached_irq_mask[word]);
+}
+
+static void
+ppc403_aic_disable_and_ack(unsigned int irq)
+{
+	int bit, word;
+
+	bit = irq & 0x1f;
+	word = irq >> 5;
+
+	ppc_cached_irq_mask[word] &= ~(1 << (31 - bit));
+	mtdcr(DCRN_EXIER, ppc_cached_irq_mask[word]);
+	mtdcr(DCRN_EXISR, (1 << (31 - bit)));
+}
+
+void __init
+ppc4xx_pic_init(void)
+{
+	int i;
+
+	/*
+	 * Disable all external interrupts until they are
+	 * explicity requested.
+	 */
+	ppc_cached_irq_mask[0] = 0;
+
+	mtdcr(DCRN_EXIER, ppc_cached_irq_mask[0]);
+
+	ppc_md.get_irq = ppc403_pic_get_irq;
+
+	for (i = 0; i < NR_IRQS; i++)
+		irq_desc[i].handler = &ppc403_aic;
+}
diff -Nru a/arch/ppc/syslib/ppc4xx_dma.c b/arch/ppc/syslib/ppc4xx_dma.c
--- a/arch/ppc/syslib/ppc4xx_dma.c	2005-03-01 23:39:17 -08:00
+++ b/arch/ppc/syslib/ppc4xx_dma.c	2005-03-01 23:39:17 -08:00
@@ -48,7 +48,7 @@
 		return;
 	}
 
-#ifdef PPC4xx_DMA64BIT
+#ifdef PPC4xx_DMA_64BIT
 	mtdcr(DCRN_DMASAH0 + dmanr*2, (u32)(src_addr >> 32));
 #else
 	mtdcr(DCRN_DMASA0 + dmanr*2, (u32)src_addr);
@@ -63,7 +63,7 @@
 		return;
 	}
 
-#ifdef PPC4xx_DMA64BIT
+#ifdef PPC4xx_DMA_64BIT
 	mtdcr(DCRN_DMADAH0 + dmanr*2, (u32)(dst_addr >> 32));
 #else
 	mtdcr(DCRN_DMADA0 + dmanr*2, (u32)dst_addr);
@@ -512,6 +512,8 @@
 		return DMA_STATUS_BAD_CHANNEL;
 	}
 
+	memcpy(p_dma_ch, &dma_channels[dmanr], sizeof (ppc_dma_ch_t));
+
 #if DCRN_POL > 0
 	polarity = mfdcr(DCRN_POL);
 #else
@@ -604,6 +606,84 @@
 	return (GET_DMA_PW(control));
 }
 
+/*
+ * Clears the channel status bits
+ */
+int
+ppc4xx_clr_dma_status(unsigned int dmanr)
+{
+	if (dmanr >= MAX_PPC4xx_DMA_CHANNELS) {
+		printk(KERN_ERR "ppc4xx_clr_dma_status: bad channel: %d\n", dmanr);
+		return DMA_STATUS_BAD_CHANNEL;
+	}
+	mtdcr(DCRN_DMASR, ((u32)DMA_CH0_ERR | (u32)DMA_CS0 | (u32)DMA_TS0) >> dmanr);
+	return DMA_STATUS_GOOD;
+}
+
+/*
+ * Enables the burst on the channel (BTEN bit in the control/count register)
+ * Note:
+ * For scatter/gather dma, this function MUST be called before the
+ * ppc4xx_alloc_dma_handle() func as the chan count register is copied into the
+ * sgl list and used as each sgl element is added.
+ */
+int
+ppc4xx_enable_burst(unsigned int dmanr)
+{
+	unsigned int ctc;
+	if (dmanr >= MAX_PPC4xx_DMA_CHANNELS) {
+		printk(KERN_ERR "ppc4xx_enable_burst: bad channel: %d\n", dmanr);
+		return DMA_STATUS_BAD_CHANNEL;
+	}
+        ctc = mfdcr(DCRN_DMACT0 + (dmanr * 0x8)) | DMA_CTC_BTEN;
+	mtdcr(DCRN_DMACT0 + (dmanr * 0x8), ctc);
+	return DMA_STATUS_GOOD;
+}
+/*
+ * Disables the burst on the channel (BTEN bit in the control/count register)
+ * Note:
+ * For scatter/gather dma, this function MUST be called before the
+ * ppc4xx_alloc_dma_handle() func as the chan count register is copied into the
+ * sgl list and used as each sgl element is added.
+ */
+int
+ppc4xx_disable_burst(unsigned int dmanr)
+{
+	unsigned int ctc;
+	if (dmanr >= MAX_PPC4xx_DMA_CHANNELS) {
+		printk(KERN_ERR "ppc4xx_disable_burst: bad channel: %d\n", dmanr);
+		return DMA_STATUS_BAD_CHANNEL;
+	}
+	ctc = mfdcr(DCRN_DMACT0 + (dmanr * 0x8)) &~ DMA_CTC_BTEN;
+	mtdcr(DCRN_DMACT0 + (dmanr * 0x8), ctc);
+	return DMA_STATUS_GOOD;
+}
+/*
+ * Sets the burst size (number of peripheral widths) for the channel
+ * (BSIZ bits in the control/count register))
+ * must be one of:
+ *    DMA_CTC_BSIZ_2
+ *    DMA_CTC_BSIZ_4
+ *    DMA_CTC_BSIZ_8
+ *    DMA_CTC_BSIZ_16
+ * Note:
+ * For scatter/gather dma, this function MUST be called before the
+ * ppc4xx_alloc_dma_handle() func as the chan count register is copied into the
+ * sgl list and used as each sgl element is added.
+ */
+int
+ppc4xx_set_burst_size(unsigned int dmanr, unsigned int bsize)
+{
+	unsigned int ctc;
+	if (dmanr >= MAX_PPC4xx_DMA_CHANNELS) {
+		printk(KERN_ERR "ppc4xx_set_burst_size: bad channel: %d\n", dmanr);
+		return DMA_STATUS_BAD_CHANNEL;
+	}
+	ctc = mfdcr(DCRN_DMACT0 + (dmanr * 0x8)) &~ DMA_CTC_BSIZ_MSK;
+	ctc |= (bsize & DMA_CTC_BSIZ_MSK);
+	mtdcr(DCRN_DMACT0 + (dmanr * 0x8), ctc);
+	return DMA_STATUS_GOOD;
+}
 
 EXPORT_SYMBOL(ppc4xx_init_dma_channel);
 EXPORT_SYMBOL(ppc4xx_get_channel_config);
@@ -622,3 +702,7 @@
 EXPORT_SYMBOL(ppc4xx_enable_dma_interrupt);
 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 -Nru a/arch/ppc/syslib/ppc4xx_pic.c b/arch/ppc/syslib/ppc4xx_pic.c
--- a/arch/ppc/syslib/ppc4xx_pic.c	2005-03-01 23:38:43 -08:00
+++ b/arch/ppc/syslib/ppc4xx_pic.c	2005-03-01 23:38:43 -08:00
@@ -1,31 +1,21 @@
 /*
+ * arch/ppc/syslib/ppc4xx_pic.c
  *
- *    Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
- *
- *    Module name: ppc4xx_pic.c
- *
- *    Description:
- *      Interrupt controller driver for PowerPC 4xx-based processors.
- */
-
-/*
- * The PowerPC 403 cores' Asynchronous Interrupt Controller (AIC) has
- * 32 possible interrupts, a majority of which are not implemented on
- * all cores. There are six configurable, external interrupt pins and
- * there are eight internal interrupts for the on-chip serial port
- * (SPU), DMA controller, and JTAG controller.
+ * Interrupt controller driver for PowerPC 4xx-based processors.
  *
- * The PowerPC 405/440 cores' Universal Interrupt Controller (UIC) has
- * 32 possible interrupts as well.  Depending on the core and SoC
- * implementation, a portion of the interrrupts are used for on-chip
- * peripherals and a portion of the interrupts are available to be
- * configured for external devices generating interrupts.
+ * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
+ * Copyright (c) 2004 Zultys Technologies
  *
- * The PowerNP and 440GP (and most likely future implementations) have
- * cascaded UICs.
+ * Based on original code by
+ *    Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
+ *    Armin Custer <akuster@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/config.h>
 #include <linux/init.h>
 #include <linux/sched.h>
 #include <linux/signal.h>
@@ -36,493 +26,212 @@
 #include <asm/irq.h>
 #include <asm/ppc4xx_pic.h>
 
-/* Global Variables */
-struct hw_interrupt_type *ppc4xx_pic;
-/*
- * We define 4xxIRQ_InitSenses table thusly:
- * bit 0x1: sense, 1 for edge and 0 for level.
- * bit 0x2: polarity, 0 for negative, 1 for positive.
+/* See comment in include/arch-ppc/ppc4xx_pic.h
+ * for more info about these two variables
  */
-unsigned int ibm4xxPIC_NumInitSenses __initdata = 0;
-unsigned char *ibm4xxPIC_InitSenses __initdata = NULL;
-
-/* Six of one, half dozen of the other....#ifdefs, separate files,
- * other tricks.....
- *
- * There are basically two types of interrupt controllers, the 403 AIC
- * and the "others" with UIC.  I just kept them both here separated
- * with #ifdefs, but it seems to change depending upon how supporting
- * files (like ppc4xx.h) change.		-- Dan.
- */
-
-#ifdef CONFIG_403
-
-/* Function Prototypes */
-
-static void ppc403_aic_enable(unsigned int irq);
-static void ppc403_aic_disable(unsigned int irq);
-static void ppc403_aic_disable_and_ack(unsigned int irq);
-
-static struct hw_interrupt_type ppc403_aic = {
-	"403GC AIC",
-	NULL,
-	NULL,
-	ppc403_aic_enable,
-	ppc403_aic_disable,
-	ppc403_aic_disable_and_ack,
-	0
-};
+extern struct ppc4xx_uic_settings ppc4xx_core_uic_cfg[NR_UICS] __attribute__((weak));
+extern unsigned char ppc4xx_uic_ext_irq_cfg[] __attribute__((weak));
 
-int
-ppc403_pic_get_irq(struct pt_regs *regs)
-{
-	int irq;
-	unsigned long bits;
-
-	/*
-	 * Only report the status of those interrupts that are actually
-	 * enabled.
-	 */
-
-	bits = mfdcr(DCRN_EXISR) & mfdcr(DCRN_EXIER);
-
-	/*
-	 * Walk through the interrupts from highest priority to lowest, and
-	 * report the first pending interrupt found.
-	 * We want PPC, not C bit numbering, so just subtract the ffs()
-	 * result from 32.
-	 */
-	irq = 32 - ffs(bits);
-
-	if (irq == NR_AIC_IRQS)
-		irq = -1;
-
-	return (irq);
+#define IRQ_MASK_UIC0(irq)		(1 << (31 - (irq)))
+#define IRQ_MASK_UICx(irq)		(1 << (31 - ((irq) & 0x1f)))
+#define IRQ_MASK_UIC1(irq)		IRQ_MASK_UICx(irq)
+#define IRQ_MASK_UIC2(irq)		IRQ_MASK_UICx(irq)
+
+#define UIC_HANDLERS(n)							\
+static void ppc4xx_uic##n##_enable(unsigned int irq)			\
+{									\
+	ppc_cached_irq_mask[n] |= IRQ_MASK_UIC##n(irq);			\
+	mtdcr(DCRN_UIC_ER(UIC##n), ppc_cached_irq_mask[n]);		\
+}									\
+									\
+static void ppc4xx_uic##n##_disable(unsigned int irq)			\
+{									\
+	ppc_cached_irq_mask[n] &= ~IRQ_MASK_UIC##n(irq);		\
+	mtdcr(DCRN_UIC_ER(UIC##n), ppc_cached_irq_mask[n]);		\
+}									\
+									\
+static void ppc4xx_uic##n##_ack(unsigned int irq)			\
+{									\
+	u32 mask = IRQ_MASK_UIC##n(irq);				\
+	ppc_cached_irq_mask[n] &= ~mask;				\
+	mtdcr(DCRN_UIC_ER(UIC##n), ppc_cached_irq_mask[n]);		\
+	mtdcr(DCRN_UIC_SR(UIC##n), mask);				\
+	ACK_UIC##n##_PARENT						\
+}									\
+									\
+static void ppc4xx_uic##n##_end(unsigned int irq)			\
+{									\
+	unsigned int status = irq_desc[irq].status;			\
+	u32 mask = IRQ_MASK_UIC##n(irq);				\
+	if (status & IRQ_LEVEL){					\
+		mtdcr(DCRN_UIC_SR(UIC##n), mask);			\
+		ACK_UIC##n##_PARENT					\
+	}								\
+	if (!(status & (IRQ_DISABLED | IRQ_INPROGRESS))){		\
+		ppc_cached_irq_mask[n] |= mask;				\
+		mtdcr(DCRN_UIC_ER(UIC##n), ppc_cached_irq_mask[n]);	\
+	}								\
+}
+
+#define DECLARE_UIC(n)							\
+{									\
+	.typename 	= "UIC"#n,					\
+	.enable 	= ppc4xx_uic##n##_enable,			\
+	.disable 	= ppc4xx_uic##n##_disable,			\
+	.ack 		= ppc4xx_uic##n##_ack,				\
+	.end 		= ppc4xx_uic##n##_end,				\
+}									\
+
+#if NR_UICS == 3
+#define ACK_UIC0_PARENT	mtdcr(DCRN_UIC_SR(UICB), UICB_UIC0NC);
+#define ACK_UIC1_PARENT	mtdcr(DCRN_UIC_SR(UICB), UICB_UIC1NC);
+#define ACK_UIC2_PARENT	mtdcr(DCRN_UIC_SR(UICB), UICB_UIC2NC);
+UIC_HANDLERS(0); UIC_HANDLERS(1); UIC_HANDLERS(2);
+
+static int ppc4xx_pic_get_irq(struct pt_regs *regs)
+{
+	u32 uicb = mfdcr(DCRN_UIC_MSR(UICB));
+	if (uicb & UICB_UIC0NC)
+		return 32 - ffs(mfdcr(DCRN_UIC_MSR(UIC0)));
+	else if (uicb & UICB_UIC1NC)
+		return 64 - ffs(mfdcr(DCRN_UIC_MSR(UIC1)));
+	else if (uicb & UICB_UIC2NC)
+		return 96 - ffs(mfdcr(DCRN_UIC_MSR(UIC2)));
+	else
+		return -1;
 }
 
-static void
-ppc403_aic_enable(unsigned int irq)
+static void __init ppc4xx_pic_impl_init(void)
 {
-	int bit, word;
-
-	bit = irq & 0x1f;
-	word = irq >> 5;
-
-	ppc_cached_irq_mask[word] |= (1 << (31 - bit));
-	mtdcr(DCRN_EXIER, ppc_cached_irq_mask[word]);
+	/* Configure Base UIC */
+	mtdcr(DCRN_UIC_CR(UICB), 0);
+	mtdcr(DCRN_UIC_TR(UICB), 0);
+	mtdcr(DCRN_UIC_PR(UICB), 0xffffffff);
+	mtdcr(DCRN_UIC_SR(UICB), 0xffffffff);
+	mtdcr(DCRN_UIC_ER(UICB), UICB_UIC0NC | UICB_UIC1NC | UICB_UIC2NC);
 }
 
-static void
-ppc403_aic_disable(unsigned int irq)
-{
-	int bit, word;
-
-	bit = irq & 0x1f;
-	word = irq >> 5;
-
-	ppc_cached_irq_mask[word] &= ~(1 << (31 - bit));
-	mtdcr(DCRN_EXIER, ppc_cached_irq_mask[word]);
-}
+#elif NR_UICS == 2
+#define ACK_UIC0_PARENT
+#define ACK_UIC1_PARENT	mtdcr(DCRN_UIC_SR(UIC0), UIC0_UIC1NC);
+UIC_HANDLERS(0); UIC_HANDLERS(1);
 
-static void
-ppc403_aic_disable_and_ack(unsigned int irq)
+static int ppc4xx_pic_get_irq(struct pt_regs *regs)
 {
-	int bit, word;
-
-	bit = irq & 0x1f;
-	word = irq >> 5;
-
-	ppc_cached_irq_mask[word] &= ~(1 << (31 - bit));
-	mtdcr(DCRN_EXIER, ppc_cached_irq_mask[word]);
-	mtdcr(DCRN_EXISR, (1 << (31 - bit)));
+	u32 uic0 = mfdcr(DCRN_UIC_MSR(UIC0));
+	if (uic0 & UIC0_UIC1NC)
+		return 64 - ffs(mfdcr(DCRN_UIC_MSR(UIC1)));
+	else
+		return uic0 ? 32 - ffs(uic0) : -1;
 }
 
-#else
-
-#ifndef UIC1
-#define UIC1 UIC0
-#endif
-#ifndef UIC2
-#define UIC2 UIC1
-#endif
-
-static void
-ppc4xx_uic_enable(unsigned int irq)
+static void __init ppc4xx_pic_impl_init(void)
 {
-	int bit, word;
-	irq_desc_t *desc = irq_desc + irq;
-
-	bit = irq & 0x1f;
-	word = irq >> 5;
-
-#ifdef UIC_DEBUG
-	printk("ppc4xx_uic_enable - irq %d word %d bit 0x%x\n", irq, word, bit);
-#endif
-	ppc_cached_irq_mask[word] |= 1 << (31 - bit);
-	switch (word) {
-	case 0:
-		mtdcr(DCRN_UIC_ER(UIC0), ppc_cached_irq_mask[word]);
-		if ((mfdcr(DCRN_UIC_TR(UIC0)) & (1 << (31 - bit))) == 0)
-			desc->status |= IRQ_LEVEL;
-		else
-			desc->status = desc->status & ~IRQ_LEVEL;
-		break;
-	case 1:
-		mtdcr(DCRN_UIC_ER(UIC1), ppc_cached_irq_mask[word]);
-		if ((mfdcr(DCRN_UIC_TR(UIC1)) & (1 << (31 - bit))) == 0)
-			desc->status |= IRQ_LEVEL;
-		else
-			desc->status = desc->status & ~IRQ_LEVEL;
-		break;
-	case 2:
-		mtdcr(DCRN_UIC_ER(UIC2), ppc_cached_irq_mask[word]);
-		if ((mfdcr(DCRN_UIC_TR(UIC2)) & (1 << (31 - bit))) == 0)
-			desc->status |= IRQ_LEVEL;
-		else
-			desc->status = desc->status & ~IRQ_LEVEL;
-		break;
-	}
-
+	/* Enable cascade interrupt in UIC0 */
+	ppc_cached_irq_mask[0] |= UIC0_UIC1NC;
+	mtdcr(DCRN_UIC_SR(UIC0), UIC0_UIC1NC);
+	mtdcr(DCRN_UIC_ER(UIC0), ppc_cached_irq_mask[0]);
 }
 
-static void
-ppc4xx_uic_disable(unsigned int irq)
-{
-	int bit, word;
+#elif NR_UICS == 1
+#define ACK_UIC0_PARENT
+UIC_HANDLERS(0);
 
-	bit = irq & 0x1f;
-	word = irq >> 5;
-#ifdef UIC_DEBUG
-	printk("ppc4xx_uic_disable - irq %d word %d bit 0x%x\n", irq, word,
-	       bit);
-#endif
-	ppc_cached_irq_mask[word] &= ~(1 << (31 - bit));
-	switch (word) {
-	case 0:
-		mtdcr(DCRN_UIC_ER(UIC0), ppc_cached_irq_mask[word]);
-		break;
-	case 1:
-		mtdcr(DCRN_UIC_ER(UIC1), ppc_cached_irq_mask[word]);
-		break;
-	case 2:
-		mtdcr(DCRN_UIC_ER(UIC2), ppc_cached_irq_mask[word]);
-		break;
-	}
-}
-
-static void
-ppc4xx_uic_disable_and_ack(unsigned int irq)
+static int ppc4xx_pic_get_irq(struct pt_regs *regs)
 {
-	int bit, word;
-
-	bit = irq & 0x1f;
-	word = irq >> 5;
-
-#ifdef UIC_DEBUG
-	printk("ppc4xx_uic_disable_and_ack - irq %d word %d bit 0x%x\n", irq,
-	       word, bit);
-#endif
-	ppc_cached_irq_mask[word] &= ~(1 << (31 - bit));
-	switch (word) {
-	case 0:
-		mtdcr(DCRN_UIC_ER(UIC0), ppc_cached_irq_mask[word]);
-		mtdcr(DCRN_UIC_SR(UIC0), (1 << (31 - bit)));
-#if (NR_UICS > 2)
-		mtdcr(DCRN_UIC_SR(UICB), UICB_UIC0NC);
-#endif
-		break;
-	case 1:
-		mtdcr(DCRN_UIC_ER(UIC1), ppc_cached_irq_mask[word]);
-		mtdcr(DCRN_UIC_SR(UIC1), (1 << (31 - bit)));
-#if (NR_UICS == 2)
-		mtdcr(DCRN_UIC_SR(UIC0), (1 << (31 - UIC0_UIC1NC)));
-#endif
-#if (NR_UICS > 2)
-		mtdcr(DCRN_UIC_SR(UICB), UICB_UIC1NC);
-#endif
-		break;
-	case 2:
-		mtdcr(DCRN_UIC_ER(UIC2), ppc_cached_irq_mask[word]);
-		mtdcr(DCRN_UIC_SR(UIC2), (1 << (31 - bit)));
-#if (NR_UICS > 2)
-		mtdcr(DCRN_UIC_SR(UICB), UICB_UIC2NC);
-#endif
-		break;
-	}
-
+	u32 uic0 = mfdcr(DCRN_UIC_MSR(UIC0));
+	return uic0 ? 32 - ffs(uic0) : -1;
 }
 
-static void
-ppc4xx_uic_end(unsigned int irq)
-{
-	int bit, word;
-	unsigned int tr_bits = 0;
-
-	bit = irq & 0x1f;
-	word = irq >> 5;
-
-#ifdef UIC_DEBUG
-	printk("ppc4xx_uic_end - irq %d word %d bit 0x%x\n", irq, word, bit);
+static inline void ppc4xx_pic_impl_init(void){}
 #endif
 
-	switch (word) {
-	case 0:
-		tr_bits = mfdcr(DCRN_UIC_TR(UIC0));
-		break;
-	case 1:
-		tr_bits = mfdcr(DCRN_UIC_TR(UIC1));
-		break;
-	case 2:
-		tr_bits = mfdcr(DCRN_UIC_TR(UIC2));
-		break;
-	}
-
-	if ((tr_bits & (1 << (31 - bit))) == 0) {
-		/* level trigger */
-		switch (word) {
-		case 0:
-			mtdcr(DCRN_UIC_SR(UIC0), 1 << (31 - bit));
-#if (NR_UICS > 2)
-			mtdcr(DCRN_UIC_SR(UICB),  UICB_UIC0NC);
-#endif
-			break;
-		case 1:
-			mtdcr(DCRN_UIC_SR(UIC1), 1 << (31 - bit));
-#if (NR_UICS == 2)
-			mtdcr(DCRN_UIC_SR(UIC0), (1 << (31 - UIC0_UIC1NC)));
-#endif
-#if (NR_UICS > 2)
-			mtdcr(DCRN_UIC_SR(UICB),  UICB_UIC1NC);
-#endif
-			break;
-		case 2:
-			mtdcr(DCRN_UIC_SR(UIC2), 1 << (31 - bit));
-#if (NR_UICS > 2)
-			mtdcr(DCRN_UIC_SR(UICB),  UICB_UIC2NC);
+static struct ppc4xx_uic_impl {
+	struct hw_interrupt_type decl;
+	int			 base;		/* Base DCR number */
+} __uic[] = {
+    { .decl = DECLARE_UIC(0), .base = UIC0 },
+#if NR_UICS > 1
+    { .decl = DECLARE_UIC(1), .base = UIC1 },
+#if NR_UICS > 2
+    { .decl = DECLARE_UIC(2), .base = UIC2 },
 #endif
-			break;
-		}
-	}
-
-	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
-		ppc_cached_irq_mask[word] |= 1 << (31 - bit);
-		switch (word) {
-		case 0:
-			mtdcr(DCRN_UIC_ER(UIC0), ppc_cached_irq_mask[word]);
-			break;
-		case 1:
-			mtdcr(DCRN_UIC_ER(UIC1), ppc_cached_irq_mask[word]);
-			break;
-		case 2:
-			mtdcr(DCRN_UIC_ER(UIC2), ppc_cached_irq_mask[word]);
-			break;
-		}
-	}
-}
-
-static struct hw_interrupt_type ppc4xx_uic = {
-#if (NR_UICS == 1)
-	"IBM UIC",
-#else
-	"IBM UIC Cascade",
 #endif
-	NULL,
-	NULL,
-	ppc4xx_uic_enable,
-	ppc4xx_uic_disable,
-	ppc4xx_uic_disable_and_ack,
-	ppc4xx_uic_end,
-	0
 };
 
-int
-ppc4xx_pic_get_irq(struct pt_regs *regs)
+static inline int is_level_sensitive(int irq)
 {
-	int irq, cas_irq;
-	unsigned long bits;
-	cas_irq = 0;
-	/*
-	 * Only report the status of those interrupts that are actually
-	 * enabled.
-	 */
-
-#if (NR_UICS > 2)
-	bits = mfdcr(DCRN_UIC_MSR(UICB));
-#else
-	bits = mfdcr(DCRN_UIC_MSR(UIC0));
-#endif
-#if (NR_UICS > 2)
-	if (bits & UICB_UIC0NC) {
-		bits = mfdcr(DCRN_UIC_MSR(UIC0));
-		irq = 32 - ffs(bits);
-	} else if (bits & UICB_UIC1NC) {
-		bits = mfdcr(DCRN_UIC_MSR(UIC1));
-		irq = 64 - ffs(bits);
-	} else if (bits & UICB_UIC2NC) {
-		bits = mfdcr(DCRN_UIC_MSR(UIC2));
-		irq = 96 - ffs(bits);
-	} else {
-		irq = -1;
-	}
-#elif (NR_UICS > 1)
-	if (bits & UIC_CASCADE_MASK) {
-		bits = mfdcr(DCRN_UIC_MSR(UIC1));
-		cas_irq = 32 - ffs(bits);
-		irq = 32 + cas_irq;
-	} else {
-		irq = 32 - ffs(bits);
-		if (irq == 32)
-			irq = -1;
-	}
-#else
-	/*
-	 * Walk through the interrupts from highest priority to lowest, and
-	 * report the first pending interrupt found.
-	 * We want PPC, not C bit numbering, so just subtract the ffs()
-	 * result from 32.
-	 */
-	irq = 32 - ffs(bits);
-#endif
-	if (irq == (NR_UIC_IRQS * NR_UICS))
-		irq = -1;
-
-#ifdef UIC_DEBUG
-	printk("ppc4xx_pic_get_irq - irq %d bit 0x%x\n", irq, bits);
-#endif
-
-	return (irq);
+	u32 tr = mfdcr(DCRN_UIC_TR(__uic[irq >> 5].base));
+	return (tr & IRQ_MASK_UICx(irq)) == 0;
 }
-#endif
 
-void __init
-ppc4xx_extpic_init(void)
+void __init ppc4xx_pic_init(void)
 {
-	/* set polarity
-	 * 1 = default/pos/rising  , 0= neg/falling internal
-	 * 1 = neg/falling , 0= pos/rising external
-	 * Sense
-	 * 0 = default level internal
-	 * 0 = level, 1 = edge external
-	 */
-
-	unsigned int sense, irq;
-	int bit, word;
-	unsigned long ppc_cached_sense_mask[NR_MASK_WORDS];
-	unsigned long ppc_cached_pol_mask[NR_MASK_WORDS];
-	ppc_cached_sense_mask[0] = 0;
-	ppc_cached_sense_mask[1] = 0;
-	ppc_cached_sense_mask[2] = 0;
-	ppc_cached_pol_mask[0] = 0;
-	ppc_cached_pol_mask[1] = 0;
-	ppc_cached_pol_mask[2] = 0;
-
-	for (irq = 0; irq < NR_IRQS; irq++) {
-
-		bit = irq & 0x1f;
-		word = irq >> 5;
-
-		sense =
-		    (irq <
-		     ibm4xxPIC_NumInitSenses) ? ibm4xxPIC_InitSenses[irq] : 3;
-#ifdef PPC4xx_PIC_DEBUG
-		printk("PPC4xx_picext %d word:%x bit:%x sense:%x", irq, word,
-		       bit, sense);
-#endif
-		ppc_cached_sense_mask[word] |=
-		    (~sense & IRQ_SENSE_MASK) << (31 - bit);
-		ppc_cached_pol_mask[word] |=
-		    ((sense & IRQ_POLARITY_MASK) >> 1) << (31 - bit);
-		switch (word) {
-		case 0:
-#ifdef PPC4xx_PIC_DEBUG
-			printk("Pol %x ", mfdcr(DCRN_UIC_PR(UIC0)));
-			printk("Level %x\n", mfdcr(DCRN_UIC_TR(UIC0)));
-#endif
-			/* polarity  setting */
-			mtdcr(DCRN_UIC_PR(UIC0), ppc_cached_pol_mask[word]);
-
-			/* Level setting */
-			mtdcr(DCRN_UIC_TR(UIC0), ppc_cached_sense_mask[word]);
-
-			break;
-		case 1:
-#ifdef PPC4xx_PIC_DEBUG
-			printk("Pol %x ", mfdcr(DCRN_UIC_PR(UIC1)));
-			printk("Level %x\n", mfdcr(DCRN_UIC_TR(UIC1)));
-#endif
-			/* polarity  setting */
-			mtdcr(DCRN_UIC_PR(UIC1), ppc_cached_pol_mask[word]);
-
-			/* Level setting */
-			mtdcr(DCRN_UIC_TR(UIC1), ppc_cached_sense_mask[word]);
-
-			break;
-		case 2:
-#ifdef PPC4xx_PIC_DEBUG
-			printk("Pol %x ", mfdcr(DCRN_UIC_PR(UIC2)));
-			printk("Level %x\n", mfdcr(DCRN_UIC_TR(UIC2)));
-#endif
-			/* polarity  setting */
-			mtdcr(DCRN_UIC_PR(UIC2), ppc_cached_pol_mask[word]);
-
-			/* Level setting */
-			mtdcr(DCRN_UIC_TR(UIC2), ppc_cached_sense_mask[word]);
-
-			break;
+	int i;
+	unsigned char* eirqs = ppc4xx_uic_ext_irq_cfg;
+
+	for (i = 0; i < NR_UICS; ++i){
+		int base = __uic[i].base;
+
+		/* Disable everything by default */
+		ppc_cached_irq_mask[i] = 0;
+		mtdcr(DCRN_UIC_ER(base), 0);
+
+		/* We don't use critical interrupts */
+		mtdcr(DCRN_UIC_CR(base), 0);
+
+		/* Configure polarity and triggering */
+		if (ppc4xx_core_uic_cfg){
+			struct ppc4xx_uic_settings* p = ppc4xx_core_uic_cfg + i;
+			u32 mask = p->ext_irq_mask;
+			u32 pr = mfdcr(DCRN_UIC_PR(base)) & mask;
+			u32 tr = mfdcr(DCRN_UIC_TR(base)) & mask;
+
+			/* "Fixed" interrupts (on-chip devices) */
+			pr |= p->polarity   & ~mask;
+			tr |= p->triggering & ~mask;
+
+			/* Merge external IRQs settings if board port
+			 * provided them
+			 */
+			if (eirqs && mask){
+				pr &= ~mask;
+				tr &= ~mask;
+				while (mask){
+					/* Extract current external IRQ mask */
+					u32 eirq_mask = 1 << __ilog2(mask);
+
+					if (!(*eirqs & IRQ_SENSE_LEVEL))
+						tr |= eirq_mask;
+
+					if (*eirqs & IRQ_POLARITY_POSITIVE)
+						pr |= eirq_mask;
+
+					mask &= ~eirq_mask;
+					++eirqs;
+				}
+			}
+			mtdcr(DCRN_UIC_PR(base), pr);
+			mtdcr(DCRN_UIC_TR(base), tr);
 		}
-	}
-
-}
-void __init
-ppc4xx_pic_init(void)
-{
-	/*
-	 * Disable all external interrupts until they are
-	 * explicity requested.
-	 */
-	ppc_cached_irq_mask[0] = 0;
-	ppc_cached_irq_mask[1] = 0;
-	ppc_cached_irq_mask[2] = 0;
-
-#if defined CONFIG_403
-	mtdcr(DCRN_EXIER, ppc_cached_irq_mask[0]);
-
-	ppc4xx_pic = &ppc403_aic;
-	ppc_md.get_irq = ppc403_pic_get_irq;
-#else
-#if  (NR_UICS > 2)
-	mtdcr(DCRN_UIC_ER(UICB), UICB_UIC0NC | UICB_UIC1NC | UICB_UIC2NC);
-	mtdcr(DCRN_UIC_CR(UICB), 0);
-
-	mtdcr(DCRN_UIC_ER(UIC2), ppc_cached_irq_mask[2]);
-	mtdcr(DCRN_UIC_CR(UIC2), 0);
-
-#endif
-#if  (NR_UICS > 1)
-#if  (NR_UICS == 2)
-	/* enable cascading interrupt */
-	ppc_cached_irq_mask[0] |= 1 << (31 - UIC0_UIC1NC);
-#endif
-	mtdcr(DCRN_UIC_ER(UIC1), ppc_cached_irq_mask[1]);
-	mtdcr(DCRN_UIC_CR(UIC1), 0);
-#endif
-	mtdcr(DCRN_UIC_ER(UIC0), ppc_cached_irq_mask[0]);
-	mtdcr(DCRN_UIC_CR(UIC0), 0);
-
-	if (ibm4xxPIC_InitSenses != NULL)
-		ppc4xx_extpic_init();
 
-	/* Clear any pending interrupts */
-#if (NR_UICS > 2)
-	mtdcr(DCRN_UIC_SR(UICB), 0xffffffff);
-	mtdcr(DCRN_UIC_SR(UIC2), 0xffffffff);
-#endif
-#if (NR_UICS > 1)
-	mtdcr(DCRN_UIC_SR(UIC1), 0xffffffff);
-#endif
-	mtdcr(DCRN_UIC_SR(UIC0), 0xffffffff);
+		/* ACK any pending interrupts to prevent false
+		 * triggering after first enable
+		 */
+		mtdcr(DCRN_UIC_SR(base), 0xffffffff);
+	}
+
+	/* Perform optional implementation specific setup
+	 * (e.g. enable cascade interrupts for multi-UIC configurations)
+	 */
+	ppc4xx_pic_impl_init();
+
+	/* Attach low-level handlers */
+	for (i = 0; i < (NR_UICS << 5); ++i){
+    		irq_desc[i].handler = &__uic[i >> 5].decl;
+		if (is_level_sensitive(i))
+			irq_desc[i].status |= IRQ_LEVEL;
+	}
 
-	ppc4xx_pic = &ppc4xx_uic;
 	ppc_md.get_irq = ppc4xx_pic_get_irq;
-#endif
 }
diff -Nru a/arch/ppc/syslib/ppc4xx_setup.c b/arch/ppc/syslib/ppc4xx_setup.c
--- a/arch/ppc/syslib/ppc4xx_setup.c	2005-03-01 23:38:44 -08:00
+++ b/arch/ppc/syslib/ppc4xx_setup.c	2005-03-01 23:38:44 -08:00
@@ -133,12 +133,7 @@
 void __init
 ppc4xx_init_IRQ(void)
 {
-	int i;
-
 	ppc4xx_pic_init();
-
-	for (i = 0; i < NR_IRQS; i++)
-		irq_desc[i].handler = ppc4xx_pic;
 }
 
 static void
@@ -307,4 +302,20 @@
 #if defined(CONFIG_PCI) && defined(CONFIG_IDE)
 	ppc_ide_md.ide_init_hwif = ppc4xx_ide_init_hwif_ports;
 #endif /* defined(CONFIG_PCI) && defined(CONFIG_IDE) */
+}
+
+/* Called from MachineCheckException */
+void platform_machine_check(struct pt_regs *regs)
+{
+#if defined(DCRN_PLB0_BEAR)
+	printk("PLB0: BEAR= 0x%08x ACR=   0x%08x BESR=  0x%08x\n",
+	    mfdcr(DCRN_PLB0_BEAR), mfdcr(DCRN_PLB0_ACR),
+	    mfdcr(DCRN_PLB0_BESR));
+#endif
+#if defined(DCRN_POB0_BEAR)
+	printk("PLB0 to OPB: BEAR= 0x%08x BESR0= 0x%08x BESR1= 0x%08x\n",
+	    mfdcr(DCRN_POB0_BEAR), mfdcr(DCRN_POB0_BESR0),
+	    mfdcr(DCRN_POB0_BESR1));
+#endif
+
 }
diff -Nru a/arch/ppc/syslib/ppc4xx_sgdma.c b/arch/ppc/syslib/ppc4xx_sgdma.c
--- a/arch/ppc/syslib/ppc4xx_sgdma.c	2005-03-01 23:39:07 -08:00
+++ b/arch/ppc/syslib/ppc4xx_sgdma.c	2005-03-01 23:39:07 -08:00
@@ -120,6 +120,12 @@
 		psgl->ptail = psgl->phead;
 		psgl->ptail_dma = psgl->phead_dma;
 	} else {
+		if(p_dma_ch->int_on_final_sg) {
+			/* mask out all dma interrupts, except error, on tail
+			before adding new tail. */
+			psgl->ptail->control_count &=
+				~(SG_TCI_ENABLE | SG_ETI_ENABLE);
+		}
 		psgl->ptail->next = psgl->ptail_dma + sizeof(ppc_sgl_t);
 		psgl->ptail++;
 		psgl->ptail_dma += sizeof(ppc_sgl_t);
@@ -217,7 +223,7 @@
 	}
 
 	sgl_addr = (ppc_sgl_t *) __va(mfdcr(DCRN_ASG0 + (psgl->dmanr * 0x8)));
-	count_left = mfdcr(DCRN_DMACT0 + (psgl->dmanr * 0x8));
+	count_left = mfdcr(DCRN_DMACT0 + (psgl->dmanr * 0x8)) & SG_COUNT_MASK;
 
 	if (!sgl_addr) {
 		printk("ppc4xx_get_dma_sgl_residue: sgl addr register is null\n");
@@ -351,10 +357,11 @@
 int
 ppc4xx_alloc_dma_handle(sgl_handle_t * phandle, unsigned int mode, unsigned int dmanr)
 {
-	sgl_list_info_t *psgl;
+	sgl_list_info_t *psgl=NULL;
 	dma_addr_t dma_addr;
 	ppc_dma_ch_t *p_dma_ch = &dma_channels[dmanr];
 	uint32_t sg_command;
+	uint32_t ctc_settings;
 	void *ret;
 
 	if (dmanr >= MAX_PPC4xx_DMA_CHANNELS) {
@@ -411,6 +418,11 @@
 	/* Enable SGL control access */
 	mtdcr(DCRN_ASGC, sg_command);
 	psgl->sgl_control = SG_ERI_ENABLE | SG_LINK;
+
+	/* keep control count register settings */
+	ctc_settings = mfdcr(DCRN_DMACT0 + (dmanr * 0x8))
+		& (DMA_CTC_BSIZ_MSK | DMA_CTC_BTEN); /*burst mode settings*/
+	psgl->sgl_control |= ctc_settings;
 
 	if (p_dma_ch->int_enable) {
 		if (p_dma_ch->tce_enable)
diff -Nru a/arch/ppc/syslib/ppc85xx_common.c b/arch/ppc/syslib/ppc85xx_common.c
--- a/arch/ppc/syslib/ppc85xx_common.c	2005-03-01 23:39:18 -08:00
+++ b/arch/ppc/syslib/ppc85xx_common.c	2005-03-01 23:39:18 -08:00
@@ -20,7 +20,6 @@
 
 #include <asm/mpc85xx.h>
 #include <asm/mmu.h>
-#include <asm/ocp.h>
 
 /* ************************************************************************ */
 /* Return the value of CCSRBAR for the current board */
@@ -29,18 +28,6 @@
 get_ccsrbar(void)
 {
         return BOARD_CCSRBAR;
-}
-
-/* ************************************************************************ */
-/* Update the 85xx OCP tables paddr field */
-void
-mpc85xx_update_paddr_ocp(struct ocp_device *dev, void *arg)
-{
-	phys_addr_t ccsrbar;
-	if (arg) {
-		ccsrbar = *(phys_addr_t *)arg;
-		dev->def->paddr += ccsrbar;
-	}
 }
 
 EXPORT_SYMBOL(get_ccsrbar);
diff -Nru a/arch/ppc/syslib/ppc85xx_common.h b/arch/ppc/syslib/ppc85xx_common.h
--- a/arch/ppc/syslib/ppc85xx_common.h	2005-03-01 23:39:16 -08:00
+++ b/arch/ppc/syslib/ppc85xx_common.h	2005-03-01 23:39:16 -08:00
@@ -18,12 +18,8 @@
 
 #include <linux/config.h>
 #include <linux/init.h>
-#include <asm/ocp.h>
 
 /* Provide access to ccsrbar for any modules, etc */
 phys_addr_t get_ccsrbar(void);
-
-/* Update the 85xx OCP tables paddr field */
-void mpc85xx_update_paddr_ocp(struct ocp_device *dev, void *ccsrbar);
 
 #endif /* __PPC_SYSLIB_PPC85XX_COMMON_H */
diff -Nru a/arch/ppc/syslib/ppc85xx_setup.c b/arch/ppc/syslib/ppc85xx_setup.c
--- a/arch/ppc/syslib/ppc85xx_setup.c	2005-03-01 23:39:16 -08:00
+++ b/arch/ppc/syslib/ppc85xx_setup.c	2005-03-01 23:39:16 -08:00
@@ -21,13 +21,14 @@
 #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/prom.h>
 #include <asm/time.h>
 #include <asm/mpc85xx.h>
 #include <asm/immap_85xx.h>
 #include <asm/mmu.h>
-#include <asm/ocp.h>
+#include <asm/ppc_sys.h>
 #include <asm/kgdb.h>
 
 #include <syslib/ppc85xx_setup.h>
@@ -73,40 +74,39 @@
 void __init
 mpc85xx_early_serial_map(void)
 {
+#if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)
 	struct uart_port serial_req;
+#endif
+	struct plat_serial8250_port *pdata;
 	bd_t *binfo = (bd_t *) __res;
-	phys_addr_t duart_paddr = binfo->bi_immr_base + MPC85xx_UART0_OFFSET;
+	pdata = (struct plat_serial8250_port *) ppc_sys_get_pdata(MPC85xx_DUART);
 
 	/* Setup serial port access */
+	pdata[0].uartclk = binfo->bi_busfreq;
+	pdata[0].mapbase += binfo->bi_immr_base;
+	pdata[0].membase = ioremap(pdata[0].mapbase, MPC85xx_UART0_SIZE);
+
+#if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)
 	memset(&serial_req, 0, sizeof (serial_req));
-	serial_req.uartclk = binfo->bi_busfreq;
-	serial_req.line = 0;
-	serial_req.irq = MPC85xx_IRQ_DUART;
-	serial_req.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST;
 	serial_req.iotype = SERIAL_IO_MEM;
-	serial_req.membase = ioremap(duart_paddr, MPC85xx_UART0_SIZE);
-	serial_req.mapbase = duart_paddr;
+	serial_req.mapbase = pdata[0].mapbase;
+	serial_req.membase = pdata[0].membase;
 	serial_req.regshift = 0;
 
-#if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)
 	gen550_init(0, &serial_req);
 #endif
 
-	if (early_serial_setup(&serial_req) != 0)
-		printk("Early serial init of port 0 failed\n");
-
-	/* Assume early_serial_setup() doesn't modify serial_req */
-	duart_paddr = binfo->bi_immr_base + MPC85xx_UART1_OFFSET;
-	serial_req.line = 1;
-	serial_req.mapbase = duart_paddr;
-	serial_req.membase = ioremap(duart_paddr, MPC85xx_UART1_SIZE);
+	pdata[1].uartclk = binfo->bi_busfreq;
+	pdata[1].mapbase += binfo->bi_immr_base;
+	pdata[1].membase = ioremap(pdata[1].mapbase, MPC85xx_UART0_SIZE);
 
 #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)
+	/* Assume gen550_init() doesn't modify serial_req */
+	serial_req.mapbase = pdata[1].mapbase;
+	serial_req.membase = pdata[1].membase;
+
 	gen550_init(1, &serial_req);
 #endif
-
-	if (early_serial_setup(&serial_req) != 0)
-		printk("Early serial init of port 1 failed\n");
 }
 #endif
 
@@ -243,6 +243,8 @@
 }
 #endif /* CONFIG_85xx_PCI2 */
 
+int mpc85xx_pci1_last_busno = 0;
+
 void __init
 mpc85xx_setup_hose(void)
 {
@@ -341,6 +343,9 @@
 			IORESOURCE_IO, "PCI2 host bridge");
 
 	hose_b->last_busno = pciauto_bus_scan(hose_b, hose_b->first_busno);
+
+	/* let board code know what the last bus number was on PCI1 */
+	mpc85xx_pci1_last_busno = hose_a->last_busno;
 #endif
 	return;
 }
diff -Nru a/arch/ppc/syslib/ppc85xx_setup.h b/arch/ppc/syslib/ppc85xx_setup.h
--- a/arch/ppc/syslib/ppc85xx_setup.h	2005-03-01 23:39:07 -08:00
+++ b/arch/ppc/syslib/ppc85xx_setup.h	2005-03-01 23:39:07 -08:00
@@ -43,9 +43,6 @@
 #define PCIX_STATUS	0x64
 
 /* Serial Config */
-#define MPC85XX_0_SERIAL                (CCSRBAR + 0x4500)
-#define MPC85XX_1_SERIAL                (CCSRBAR + 0x4600)
-
 #ifdef CONFIG_SERIAL_MANY_PORTS
 #define RS_TABLE_SIZE  64
 #else
@@ -55,12 +52,6 @@
 #ifndef BASE_BAUD
 #define BASE_BAUD 115200
 #endif
-
-#define STD_UART_OP(num)					\
-	{ 0, BASE_BAUD, num, MPC85xx_IRQ_DUART,			\
-		(ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST),	\
-		iomem_base: (u8 *)MPC85XX_##num##_SERIAL,	\
-		io_type: SERIAL_IO_MEM},
 
 /* Offset of CPM register space */
 #define CPM_MAP_ADDR	(CCSRBAR + MPC85xx_CPM_OFFSET)
diff -Nru a/arch/ppc/syslib/ppc_sys.c b/arch/ppc/syslib/ppc_sys.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/ppc/syslib/ppc_sys.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,103 @@
+/*
+ * arch/ppc/syslib/ppc_sys.c
+ *
+ * PPC System library functions
+ *
+ * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ *
+ * Copyright 2005 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.
+ */
+
+#include <asm/ppc_sys.h>
+
+int (*ppc_sys_device_fixup) (struct platform_device * pdev);
+
+static int ppc_sys_inited;
+
+void __init identify_ppc_sys_by_id(u32 id)
+{
+	unsigned int i = 0;
+	while (1) {
+		if ((ppc_sys_specs[i].mask & id) == ppc_sys_specs[i].value)
+			break;
+		i++;
+	}
+
+	cur_ppc_sys_spec = &ppc_sys_specs[i];
+
+	return;
+}
+
+void __init identify_ppc_sys_by_name(char *name)
+{
+	/* TODO */
+	return;
+}
+
+/* Update all memory resources by paddr, call before platform_device_register */
+void __init
+ppc_sys_fixup_mem_resource(struct platform_device *pdev, phys_addr_t paddr)
+{
+	int i;
+	for (i = 0; i < pdev->num_resources; i++) {
+		struct resource *r = &pdev->resource[i];
+		if ((r->flags & IORESOURCE_MEM) == IORESOURCE_MEM) {
+			r->start += paddr;
+			r->end += paddr;
+		}
+	}
+}
+
+/* Get platform_data pointer out of platform device, call before platform_device_register */
+void *__init ppc_sys_get_pdata(enum ppc_sys_devices dev)
+{
+	return ppc_sys_platform_devices[dev].dev.platform_data;
+}
+
+void ppc_sys_device_remove(enum ppc_sys_devices dev)
+{
+	unsigned int i;
+
+	if (ppc_sys_inited) {
+		platform_device_unregister(&ppc_sys_platform_devices[dev]);
+	} else {
+		if (cur_ppc_sys_spec == NULL)
+			return;
+		for (i = 0; i < cur_ppc_sys_spec->num_devices; i++)
+			if (cur_ppc_sys_spec->device_list[i] == dev)
+				cur_ppc_sys_spec->device_list[i] = -1;
+	}
+}
+
+static int __init ppc_sys_init(void)
+{
+	unsigned int i, dev_id, ret = 0;
+
+	BUG_ON(cur_ppc_sys_spec == NULL);
+
+	for (i = 0; i < cur_ppc_sys_spec->num_devices; i++) {
+		dev_id = cur_ppc_sys_spec->device_list[i];
+		if (dev_id != -1) {
+			if (ppc_sys_device_fixup != NULL)
+				ppc_sys_device_fixup(&ppc_sys_platform_devices
+						     [dev_id]);
+			if (platform_device_register
+			    (&ppc_sys_platform_devices[dev_id])) {
+				ret = 1;
+				printk(KERN_ERR
+				       "unable to register device %d\n",
+				       dev_id);
+			}
+		}
+	}
+
+	ppc_sys_inited = 1;
+	return ret;
+}
+
+subsys_initcall(ppc_sys_init);
diff -Nru a/arch/ppc/syslib/prom.c b/arch/ppc/syslib/prom.c
--- a/arch/ppc/syslib/prom.c	2005-03-01 23:38:52 -08:00
+++ b/arch/ppc/syslib/prom.c	2005-03-01 23:38:52 -08:00
@@ -1397,7 +1397,7 @@
 }
 #endif
 
-static spinlock_t rtas_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(rtas_lock);
 
 /* this can be called after setup -- Cort */
 int __openfirmware
diff -Nru a/arch/ppc/syslib/prom_init.c b/arch/ppc/syslib/prom_init.c
--- a/arch/ppc/syslib/prom_init.c	2005-03-01 23:39:17 -08:00
+++ b/arch/ppc/syslib/prom_init.c	2005-03-01 23:39:17 -08:00
@@ -810,6 +810,9 @@
 	char *p, *d;
  	unsigned long phys;
 	void *result[3];
+	char model[32];
+	phandle node;
+	int rc;
 
  	/* Default */
  	phys = (unsigned long) &_stext;
@@ -866,11 +869,20 @@
 
 	klimit = (char *) (mem - offset);
 
-	/* If we are already running at 0xc0000000, we assume we were
-	 * loaded by an OF bootloader which did set a BAT for us.
-	 * This breaks OF translate so we force phys to be 0.
-	 */
-	if (offset == 0) {
+	node = call_prom("finddevice", 1, 1, "/");
+	rc = call_prom("getprop", 4, 1, node, "model", model, sizeof(model));
+	if (rc > 0 && !strncmp (model, "Pegasos", 7)
+		&& strncmp (model, "Pegasos2", 8)) {
+		/* Pegasos 1 has a broken translate method in the OF,
+		 * and furthermore the BATs are mapped 1:1 so the phys
+		 * address calculated above is correct, so let's use
+		 * it directly.
+		 */
+	} else if (offset == 0) {
+		/* If we are already running at 0xc0000000, we assume we were
+	 	 * loaded by an OF bootloader which did set a BAT for us.
+	 	 * This breaks OF translate so we force phys to be 0.
+	 	 */
 		prom_print("(already at 0xc0000000) phys=0\n");
 		phys = 0;
 	} else if ((int) call_prom("getprop", 4, 1, prom_chosen, "mmu",
diff -Nru a/arch/ppc/syslib/qspan_pci.c b/arch/ppc/syslib/qspan_pci.c
--- a/arch/ppc/syslib/qspan_pci.c	2005-03-01 23:38:53 -08:00
+++ b/arch/ppc/syslib/qspan_pci.c	2005-03-01 23:38:53 -08:00
@@ -94,6 +94,8 @@
 #define mk_config_type1(bus, dev, offset) \
 	mk_config_addr(bus, dev, offset) | 1;
 
+static spinlock_t pcibios_lock = SPIN_LOCK_UNLOCKED;
+
 int qspan_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn,
 				  unsigned char offset, unsigned char *val)
 {
@@ -109,8 +111,8 @@
 	}
 
 #ifdef CONFIG_RPXCLASSIC
-	save_flags(flags);
-	cli();
+	/* disable interrupts */
+	spin_lock_irqsave(&pcibios_lock, flags);
 	*((uint *)RPX_CSR_ADDR) &= ~BCSR2_QSPACESEL;
 	eieio();
 #endif
@@ -124,7 +126,7 @@
 #ifdef CONFIG_RPXCLASSIC
 	*((uint *)RPX_CSR_ADDR) |= BCSR2_QSPACESEL;
 	eieio();
-	restore_flags(flags);
+	spin_unlock_irqrestore(&pcibios_lock, flags);
 #endif
 
 	offset ^= 0x03;
@@ -148,8 +150,8 @@
 	}
 
 #ifdef CONFIG_RPXCLASSIC
-	save_flags(flags);
-	cli();
+	/* disable interrupts */
+	spin_lock_irqsave(&pcibios_lock, flags);
 	*((uint *)RPX_CSR_ADDR) &= ~BCSR2_QSPACESEL;
 	eieio();
 #endif
@@ -164,7 +166,7 @@
 #ifdef CONFIG_RPXCLASSIC
 	*((uint *)RPX_CSR_ADDR) |= BCSR2_QSPACESEL;
 	eieio();
-	restore_flags(flags);
+	spin_unlock_irqrestore(&pcibios_lock, flags);
 #endif
 
 	sp = ((ushort *)&temp) + ((offset >> 1) & 1);
@@ -185,8 +187,8 @@
 	}
 
 #ifdef CONFIG_RPXCLASSIC
-	save_flags(flags);
-	cli();
+	/* disable interrupts */
+	spin_lock_irqsave(&pcibios_lock, flags);
 	*((uint *)RPX_CSR_ADDR) &= ~BCSR2_QSPACESEL;
 	eieio();
 #endif
@@ -200,7 +202,7 @@
 #ifdef CONFIG_RPXCLASSIC
 	*((uint *)RPX_CSR_ADDR) |= BCSR2_QSPACESEL;
 	eieio();
-	restore_flags(flags);
+	spin_unlock_irqrestore(&pcibios_lock, flags);
 #endif
 
 	return PCIBIOS_SUCCESSFUL;
@@ -225,8 +227,8 @@
 	*cp = val;
 
 #ifdef CONFIG_RPXCLASSIC
-	save_flags(flags);
-	cli();
+	/* disable interrupts */
+	spin_lock_irqsave(&pcibios_lock, flags);
 	*((uint *)RPX_CSR_ADDR) &= ~BCSR2_QSPACESEL;
 	eieio();
 #endif
@@ -240,7 +242,7 @@
 #ifdef CONFIG_RPXCLASSIC
 	*((uint *)RPX_CSR_ADDR) |= BCSR2_QSPACESEL;
 	eieio();
-	restore_flags(flags);
+	spin_unlock_irqrestore(&pcibios_lock, flags);
 #endif
 
 	return PCIBIOS_SUCCESSFUL;
@@ -265,8 +267,8 @@
 	*sp = val;
 
 #ifdef CONFIG_RPXCLASSIC
-	save_flags(flags);
-	cli();
+	/* disable interrupts */
+	spin_lock_irqsave(&pcibios_lock, flags);
 	*((uint *)RPX_CSR_ADDR) &= ~BCSR2_QSPACESEL;
 	eieio();
 #endif
@@ -280,7 +282,7 @@
 #ifdef CONFIG_RPXCLASSIC
 	*((uint *)RPX_CSR_ADDR) |= BCSR2_QSPACESEL;
 	eieio();
-	restore_flags(flags);
+	spin_unlock_irqrestore(&pcibios_lock, flags);
 #endif
 
 	return PCIBIOS_SUCCESSFUL;
@@ -297,8 +299,8 @@
 		return PCIBIOS_DEVICE_NOT_FOUND;
 
 #ifdef CONFIG_RPXCLASSIC
-	save_flags(flags);
-	cli();
+	/* disable interrupts */
+	spin_lock_irqsave(&pcibios_lock, flags);
 	*((uint *)RPX_CSR_ADDR) &= ~BCSR2_QSPACESEL;
 	eieio();
 #endif
@@ -312,7 +314,7 @@
 #ifdef CONFIG_RPXCLASSIC
 	*((uint *)RPX_CSR_ADDR) |= BCSR2_QSPACESEL;
 	eieio();
-	restore_flags(flags);
+	spin_unlock_irqrestore(&pcibios_lock, flags);
 #endif
 
 	return PCIBIOS_SUCCESSFUL;
diff -Nru a/arch/ppc/syslib/xilinx_pic.c b/arch/ppc/syslib/xilinx_pic.c
--- a/arch/ppc/syslib/xilinx_pic.c	2005-03-01 23:39:16 -08:00
+++ b/arch/ppc/syslib/xilinx_pic.c	2005-03-01 23:39:16 -08:00
@@ -38,9 +38,6 @@
 #define intc_in_be32(addr)            mfdcr((addr))
 #endif
 
-/* Global Variables */
-struct hw_interrupt_type *ppc4xx_pic;
-
 static void
 xilinx_intc_enable(unsigned int irq)
 {
@@ -115,6 +112,8 @@
 void __init
 ppc4xx_pic_init(void)
 {
+	int i;
+
 #if XPAR_XINTC_USE_DCR == 0
 	intc = ioremap(XPAR_INTC_0_BASEADDR, 32);
 
@@ -137,6 +136,8 @@
 	/* Turn on the Master Enable. */
 	intc_out_be32(intc + MER, 0x3UL);
 
-	ppc4xx_pic = &xilinx_intc;
 	ppc_md.get_irq = xilinx_pic_get_irq;
+
+	for (i = 0; i < NR_IRQS; ++i)
+		irq_desc[i].handler = &xilinx_intc;
 }
diff -Nru a/arch/ppc64/Kconfig b/arch/ppc64/Kconfig
--- a/arch/ppc64/Kconfig	2005-03-01 23:38:58 -08:00
+++ b/arch/ppc64/Kconfig	2005-03-01 23:38:58 -08:00
@@ -20,6 +20,10 @@
 	bool
 	default y
 
+config GENERIC_CALIBRATE_DELAY
+	bool
+	default y
+
 config GENERIC_ISA_DMA
 	bool
 	default y
@@ -88,7 +92,7 @@
 	default n
 	help
           This option enables support for the Maple 970FX Evaluation Board.
-	  For more informations, refer to http://www.970eval.com
+	  For more informations, refer to <http://www.970eval.com>
 
 config PPC
 	bool
@@ -182,14 +186,6 @@
 
 	  If you don't know what to do here, say Y.
 
-config IRQ_ALL_CPUS
-	bool "Distribute interrupts on all CPUs by default"
-	depends on SMP && PPC_MULTIPLATFORM
-	help
-	  This option gives the kernel permission to distribute IRQs across
-	  multiple CPUs.  Saying N here will route all IRQs to the first
-	  CPU.
-
 config NR_CPUS
 	int "Maximum number of CPUs (2-128)"
 	range 2 128
@@ -227,6 +223,22 @@
 	  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.
+
+config EEH
+	bool "PCI Extended Error Handling (EEH)" if EMBEDDED
+	depends on PPC_PSERIES
+	default y if !EMBEDDED
+
 #
 # Use the generic interrupt handling code in kernel/irq/:
 #
@@ -301,7 +313,8 @@
 
 config HOTPLUG_CPU
 	bool "Support for hot-pluggable CPUs"
-	depends on SMP && HOTPLUG && EXPERIMENTAL && PPC_PSERIES
+	depends on SMP && EXPERIMENTAL && PPC_PSERIES
+	select HOTPLUG
 	---help---
 	  Say Y here to be able to turn CPUs off and on.
 
diff -Nru a/arch/ppc64/Kconfig.debug b/arch/ppc64/Kconfig.debug
--- a/arch/ppc64/Kconfig.debug	2005-03-01 23:39:10 -08:00
+++ b/arch/ppc64/Kconfig.debug	2005-03-01 23:39:10 -08:00
@@ -6,6 +6,16 @@
 	bool "Check for stack overflows"
 	depends on DEBUG_KERNEL
 
+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".
+
 config DEBUG_STACK_USAGE
 	bool "Stack utilization instrumentation"
 	depends on DEBUG_KERNEL
@@ -24,7 +34,7 @@
 
 config XMON
 	bool "Include xmon kernel debugger"
-	depends on DEBUGGER
+	depends on DEBUGGER && !PPC_ISERIES
 	help
 	  Include in-kernel hooks for the xmon kernel monitor/debugger.
 	  Unless you are intending to debug the kernel, say N here.
diff -Nru a/arch/ppc64/Makefile b/arch/ppc64/Makefile
--- a/arch/ppc64/Makefile	2005-03-01 23:38:52 -08:00
+++ b/arch/ppc64/Makefile	2005-03-01 23:38:52 -08:00
@@ -36,7 +36,11 @@
 		   -mcall-aixdesc
 
 ifeq ($(CONFIG_POWER4_ONLY),y)
+ifeq ($(CONFIG_ALTIVEC),y)
+	CFLAGS += $(call cc-option,-mcpu=970)
+else
 	CFLAGS += $(call cc-option,-mcpu=power4)
+endif
 else
 	CFLAGS += $(call cc-option,-mtune=power4)
 endif
diff -Nru a/arch/ppc64/boot/main.c b/arch/ppc64/boot/main.c
--- a/arch/ppc64/boot/main.c	2005-03-01 23:39:18 -08:00
+++ b/arch/ppc64/boot/main.c	2005-03-01 23:39:18 -08:00
@@ -73,7 +73,7 @@
 void *stdout;
 void *stderr;
 
-#define DEBUG
+#undef DEBUG
 
 static unsigned long claim_base = PROG_START;
 
diff -Nru a/arch/ppc64/boot/string.S b/arch/ppc64/boot/string.S
--- a/arch/ppc64/boot/string.S	2005-03-01 23:38:44 -08:00
+++ b/arch/ppc64/boot/string.S	2005-03-01 23:38:44 -08:00
@@ -96,13 +96,6 @@
 	bdnz	8b
 	blr
 
-	.globl	bcopy
-bcopy:
-	mr	r6,r3
-	mr	r3,r4
-	mr	r4,r6
-	b	memcpy
-
 	.globl	memmove
 memmove:
 	cmplw	0,r3,r4
diff -Nru a/arch/ppc64/configs/g5_defconfig b/arch/ppc64/configs/g5_defconfig
--- a/arch/ppc64/configs/g5_defconfig	2005-03-01 23:38:51 -08:00
+++ b/arch/ppc64/configs/g5_defconfig	2005-03-01 23:38:51 -08:00
@@ -440,7 +440,6 @@
 CONFIG_IP_NF_TARGET_REDIRECT=y
 CONFIG_IP_NF_TARGET_NETMAP=y
 CONFIG_IP_NF_TARGET_SAME=y
-# CONFIG_IP_NF_NAT_LOCAL is not set
 # CONFIG_IP_NF_NAT_SNMP_BASIC is not set
 CONFIG_IP_NF_MANGLE=y
 CONFIG_IP_NF_TARGET_TOS=y
diff -Nru a/arch/ppc64/configs/iSeries_defconfig b/arch/ppc64/configs/iSeries_defconfig
--- a/arch/ppc64/configs/iSeries_defconfig	2005-03-01 23:39:17 -08:00
+++ b/arch/ppc64/configs/iSeries_defconfig	2005-03-01 23:39:17 -08:00
@@ -316,7 +316,6 @@
 CONFIG_IP_NF_TARGET_REDIRECT=m
 CONFIG_IP_NF_TARGET_NETMAP=m
 CONFIG_IP_NF_TARGET_SAME=m
-# CONFIG_IP_NF_NAT_LOCAL is not set
 CONFIG_IP_NF_NAT_SNMP_BASIC=m
 CONFIG_IP_NF_NAT_IRC=m
 CONFIG_IP_NF_NAT_FTP=m
diff -Nru a/arch/ppc64/configs/pSeries_defconfig b/arch/ppc64/configs/pSeries_defconfig
--- a/arch/ppc64/configs/pSeries_defconfig	2005-03-01 23:39:16 -08:00
+++ b/arch/ppc64/configs/pSeries_defconfig	2005-03-01 23:39:16 -08:00
@@ -268,7 +268,7 @@
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
 # CONFIG_SCSI_GDTH is not set
 # CONFIG_SCSI_IPS is not set
-CONFIG_SCSI_IBMVSCSI=m
+CONFIG_SCSI_IBMVSCSI=y
 # CONFIG_SCSI_INIA100 is not set
 CONFIG_SCSI_SYM53C8XX_2=y
 CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0
@@ -408,7 +408,6 @@
 CONFIG_IP_NF_TARGET_REDIRECT=m
 CONFIG_IP_NF_TARGET_NETMAP=m
 CONFIG_IP_NF_TARGET_SAME=m
-# CONFIG_IP_NF_NAT_LOCAL is not set
 CONFIG_IP_NF_NAT_SNMP_BASIC=m
 CONFIG_IP_NF_NAT_IRC=m
 CONFIG_IP_NF_NAT_FTP=m
@@ -493,7 +492,7 @@
 #
 # CONFIG_NET_TULIP is not set
 # CONFIG_HP100 is not set
-CONFIG_IBMVETH=m
+CONFIG_IBMVETH=y
 CONFIG_NET_PCI=y
 CONFIG_PCNET32=y
 # CONFIG_AMD8111_ETH is not set
diff -Nru a/arch/ppc64/defconfig b/arch/ppc64/defconfig
--- a/arch/ppc64/defconfig	2005-03-01 23:38:54 -08:00
+++ b/arch/ppc64/defconfig	2005-03-01 23:38:54 -08:00
@@ -374,7 +374,6 @@
 CONFIG_IP_NF_TARGET_REDIRECT=m
 CONFIG_IP_NF_TARGET_NETMAP=m
 CONFIG_IP_NF_TARGET_SAME=m
-# CONFIG_IP_NF_NAT_LOCAL is not set
 CONFIG_IP_NF_NAT_SNMP_BASIC=m
 CONFIG_IP_NF_NAT_IRC=m
 CONFIG_IP_NF_NAT_FTP=m
diff -Nru a/arch/ppc64/kernel/HvLpEvent.c b/arch/ppc64/kernel/HvLpEvent.c
--- a/arch/ppc64/kernel/HvLpEvent.c	2005-03-01 23:38:57 -08:00
+++ b/arch/ppc64/kernel/HvLpEvent.c	2005-03-01 23:38:57 -08:00
@@ -34,10 +34,18 @@
 int HvLpEvent_unregisterHandler( HvLpEvent_Type eventType )
 {
 	int rc = 1;
+
+	might_sleep();
+
 	if ( eventType < HvLpEvent_Type_NumTypes ) {
 		if ( !lpEventHandlerPaths[eventType] ) {
 			lpEventHandler[eventType] = NULL;
 			rc = 0;
+
+			/* We now sleep until all other CPUs have scheduled. This ensures that
+			 * the deletion is seen by all other CPUs, and that the deleted handler
+			 * isn't still running on another CPU when we return. */
+			synchronize_kernel();
 		}
 	}
 	return rc;
diff -Nru a/arch/ppc64/kernel/LparData.c b/arch/ppc64/kernel/LparData.c
--- a/arch/ppc64/kernel/LparData.c	2005-03-01 23:38:54 -08:00
+++ b/arch/ppc64/kernel/LparData.c	2005-03-01 23:38:54 -08:00
@@ -16,7 +16,7 @@
 #include <asm/naca.h>
 #include <asm/abs_addr.h>
 #include <asm/iSeries/ItLpNaca.h>
-#include <asm/iSeries/ItLpPaca.h>
+#include <asm/lppaca.h>
 #include <asm/iSeries/ItLpRegSave.h>
 #include <asm/paca.h>
 #include <asm/iSeries/HvReleaseData.h>
@@ -41,86 +41,91 @@
  */
 
 struct HvReleaseData hvReleaseData = {
-	0xc8a5d9c4,	/* desc = "HvRD" ebcdic */
-	sizeof(struct HvReleaseData),
-	offsetof(struct naca_struct, xItVpdAreas),
-	(struct naca_struct *)(NACA_VIRT_ADDR), /* 64-bit Naca address */
-	0x6000,		/* offset of LparMap within loadarea (see head.S) */
-	0,
-	1,		/* tags inactive       */
-	0,		/* 64 bit              */
-	0,		/* shared processors   */
-	0,		/* HMT allowed         */
-	6,		/* TEMP: This allows non-GA driver */
-	4,		/* We are v5r2m0               */
-	3,		/* Min supported PLIC = v5r1m0 */
-	3,		/* Min usable PLIC   = v5r1m0 */
-	{ 0xd3, 0x89, 0x95, 0xa4, /* "Linux 2.4   "*/
-	  0xa7, 0x40, 0xf2, 0x4b,
-	  0xf4, 0x4b, 0xf6, 0xf4 },
-	{0}  
+	.xDesc = 0xc8a5d9c4,	/* "HvRD" ebcdic */
+	.xSize = sizeof(struct HvReleaseData),
+	.xVpdAreasPtrOffset = offsetof(struct naca_struct, xItVpdAreas),
+	.xSlicNacaAddr = &naca,		/* 64-bit Naca address */
+	.xMsNucDataOffset = 0x6000,	/* 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 */
+	.xVrmIndex = 4,			/* We are v5r2m0               */
+	.xMinSupportedPlicVrmIndex = 3,		/* v5r1m0 */
+	.xMinCompatablePlicVrmIndex = 3,	/* v5r1m0 */
+	.xVrmName = { 0xd3, 0x89, 0x95, 0xa4,	/* "Linux 2.4.64" ebcdic */
+		0xa7, 0x40, 0xf2, 0x4b,
+		0xf4, 0x4b, 0xf6, 0xf4 },
 };
 
-extern void SystemReset_Iseries(void);
-extern void MachineCheck_Iseries(void);
-extern void DataAccess_Iseries(void);
-extern void InstructionAccess_Iseries(void);
-extern void HardwareInterrupt_Iseries(void);
-extern void Alignment_Iseries(void);
-extern void ProgramCheck_Iseries(void);
-extern void FPUnavailable_Iseries(void);
-extern void Decrementer_Iseries(void);
-extern void Trap_0a_Iseries(void);
-extern void Trap_0b_Iseries(void);
-extern void SystemCall_Iseries(void);
-extern void SingleStep_Iseries(void);
-extern void Trap_0e_Iseries(void);
-extern void PerformanceMonitor_Iseries(void);
-extern void DataAccessSLB_Iseries(void);
-extern void InstructionAccessSLB_Iseries(void);
+extern void system_reset_iSeries(void);
+extern void machine_check_iSeries(void);
+extern void data_access_iSeries(void);
+extern void instruction_access_iSeries(void);
+extern void hardware_interrupt_iSeries(void);
+extern void alignment_iSeries(void);
+extern void program_check_iSeries(void);
+extern void fp_unavailable_iSeries(void);
+extern void decrementer_iSeries(void);
+extern void trap_0a_iSeries(void);
+extern void trap_0b_iSeries(void);
+extern void system_call_iSeries(void);
+extern void single_step_iSeries(void);
+extern void trap_0e_iSeries(void);
+extern void performance_monitor_iSeries(void);
+extern void data_access_slb_iSeries(void);
+extern void instruction_access_slb_iSeries(void);
 	
 struct ItLpNaca itLpNaca = {
-	0xd397d581,	/* desc = "LpNa" ebcdic */
-	0x0400,		/* size of ItLpNaca     */
-	0x0300, 19,	/* offset to int array, # ents */
-	0, 0, 0,	/* Part # of primary, serv, me */
-	0, 0x100,	/* # of LP queues, offset */
-	0, 0, 0,	/* Piranha stuff */
-	{ 0,0,0,0,0 },	/* reserved */
-	0,0,0,0,0,0,0,	/* stuff    */
-	{ 0,0,0,0,0 },	/* reserved */
-	0,		/* reserved */
-	0,		/* VRM index of PLIC */
-	0, 0,		/* min supported, compat SLIC */
-	0,		/* 64-bit addr of load area   */
-	0,		/* chunks for load area  */
-	0, 0,		/* PASE mask, seg table  */
-	{ 0 },		/* 64 reserved bytes  */
-	{ 0 }, 		/* 128 reserved bytes */
-	{ 0 }, 		/* Old LP Queue       */
-	{ 0 }, 		/* 384 reserved bytes */
-	{
-		(u64)SystemReset_Iseries,	/* 0x100 System Reset */
-		(u64)MachineCheck_Iseries,	/* 0x200 Machine Check */
-		(u64)DataAccess_Iseries,	/* 0x300 Data Access */
-		(u64)InstructionAccess_Iseries,	/* 0x400 Instruction Access */
-		(u64)HardwareInterrupt_Iseries,	/* 0x500 External */
-		(u64)Alignment_Iseries,		/* 0x600 Alignment */
-		(u64)ProgramCheck_Iseries,	/* 0x700 Program Check */
-		(u64)FPUnavailable_Iseries,	/* 0x800 FP Unavailable */
-		(u64)Decrementer_Iseries,	/* 0x900 Decrementer */
-		(u64)Trap_0a_Iseries,		/* 0xa00 Trap 0A */
-		(u64)Trap_0b_Iseries,		/* 0xb00 Trap 0B */
-		(u64)SystemCall_Iseries,	/* 0xc00 System Call */
-		(u64)SingleStep_Iseries,	/* 0xd00 Single Step */
-		(u64)Trap_0e_Iseries,		/* 0xe00 Trap 0E */
-		(u64)PerformanceMonitor_Iseries,/* 0xf00 Performance Monitor */
+	.xDesc = 0xd397d581,		/* "LpNa" ebcdic */
+	.xSize = 0x0400,		/* size of ItLpNaca */
+	.xIntHdlrOffset = 0x0300,	/* offset to int array */
+	.xMaxIntHdlrEntries = 19,	/* # ents */
+	.xPrimaryLpIndex = 0,		/* Part # of primary */
+	.xServiceLpIndex = 0,		/* Part # of serv */
+	.xLpIndex = 0,			/* Part # of me */
+	.xMaxLpQueues = 0,		/* # of LP queues */
+	.xLpQueueOffset = 0x100,	/* offset of start of LP queues */
+	.xPirEnvironMode = 0,		/* Piranha stuff */
+	.xPirConsoleMode = 0,
+	.xPirDasdMode = 0,
+	.xLparInstalled = 0,
+	.xSysPartitioned = 0,
+	.xHwSyncedTBs = 0,
+	.xIntProcUtilHmt = 0,
+	.xSpVpdFormat = 0,
+	.xIntProcRatio = 0,
+	.xPlicVrmIndex = 0,		/* VRM index of PLIC */
+	.xMinSupportedSlicVrmInd = 0,	/* min supported SLIC */
+	.xMinCompatableSlicVrmInd = 0,	/* min compat SLIC */
+	.xLoadAreaAddr = 0,		/* 64-bit addr of load area */
+	.xLoadAreaChunks = 0,		/* chunks for load area */
+	.xPaseSysCallCRMask = 0,	/* PASE mask */
+	.xSlicSegmentTablePtr = 0,	/* seg table */
+	.xOldLpQueue = { 0 }, 		/* Old LP Queue */
+	.xInterruptHdlr = {
+		(u64)system_reset_iSeries,	/* 0x100 System Reset */
+		(u64)machine_check_iSeries,	/* 0x200 Machine Check */
+		(u64)data_access_iSeries,	/* 0x300 Data Access */
+		(u64)instruction_access_iSeries, /* 0x400 Instruction Access */
+		(u64)hardware_interrupt_iSeries, /* 0x500 External */
+		(u64)alignment_iSeries,		/* 0x600 Alignment */
+		(u64)program_check_iSeries,	/* 0x700 Program Check */
+		(u64)fp_unavailable_iSeries,	/* 0x800 FP Unavailable */
+		(u64)decrementer_iSeries,	/* 0x900 Decrementer */
+		(u64)trap_0a_iSeries,		/* 0xa00 Trap 0A */
+		(u64)trap_0b_iSeries,		/* 0xb00 Trap 0B */
+		(u64)system_call_iSeries,	/* 0xc00 System Call */
+		(u64)single_step_iSeries,	/* 0xd00 Single Step */
+		(u64)trap_0e_iSeries,		/* 0xe00 Trap 0E */
+		(u64)performance_monitor_iSeries,/* 0xf00 Performance Monitor */
 		0,				/* int 0x1000 */
 		0,				/* int 0x1010 */
 		0,				/* int 0x1020 CPU ctls */
-		(u64)HardwareInterrupt_Iseries, /* SC Ret Hdlr */
-		(u64)DataAccessSLB_Iseries,	/* 0x380 D-SLB */
-		(u64)InstructionAccessSLB_Iseries /* 0x480 I-SLB */
+		(u64)hardware_interrupt_iSeries, /* SC Ret Hdlr */
+		(u64)data_access_slb_iSeries,	/* 0x380 D-SLB */
+		(u64)instruction_access_slb_iSeries /* 0x480 I-SLB */
 	}
 };
 EXPORT_SYMBOL(itLpNaca);
@@ -153,10 +158,8 @@
 u64    xRecoveryLogBuffer[32] __attribute__((__section__(".data")));
 
 struct SpCommArea xSpCommArea = {
-	0xE2D7C3C2,
-	1,
-	{0},
-	0, 0, 0, 0, {0}
+	.xDesc = 0xE2D7C3C2,
+	.xFormat = 1,
 };
 
 /* The LparMap data is now located at offset 0x6000 in head.S
@@ -168,22 +171,21 @@
  * offset into the Naca of the pointer to the ItVpdAreas.
  */
 struct ItVpdAreas itVpdAreas = {
-	0xc9a3e5c1,	/* "ItVA" */
-	sizeof( struct ItVpdAreas ),
-	0, 0,
-	26,		/* # VPD array entries */
-	10,		/* # DMA array entries */
-	NR_CPUS*2, maxPhysicalProcessors,	/* Max logical, physical procs */
-	offsetof(struct ItVpdAreas,xPlicDmaToks),/* offset to DMA toks */
-	offsetof(struct ItVpdAreas,xSlicVpdAdrs),/* offset to VPD addrs */
-	offsetof(struct ItVpdAreas,xPlicDmaLens),/* offset to DMA lens */
-	offsetof(struct ItVpdAreas,xSlicVpdLens),/* offset to VPD lens */
-	0,		/* max slot labels */
-	1,		/* max LP queues */
-	{0}, {0},	/* reserved */
-	{0},		/* DMA lengths */
-	{0},		/* DMA tokens */
-	{		/* VPD lengths */
+	.xSlicDesc = 0xc9a3e5c1,		/* "ItVA" */
+	.xSlicSize = sizeof(struct ItVpdAreas),
+	.xSlicVpdEntries = ItVpdMaxEntries,	/* # VPD array entries */
+	.xSlicDmaEntries = ItDmaMaxEntries,	/* # DMA array entries */
+	.xSlicMaxLogicalProcs = NR_CPUS * 2,	/* Max logical procs */
+	.xSlicMaxPhysicalProcs = maxPhysicalProcessors,	/* Max physical procs */
+	.xSlicDmaToksOffset = offsetof(struct ItVpdAreas, xPlicDmaToks),
+	.xSlicVpdAdrsOffset = offsetof(struct ItVpdAreas, xSlicVpdAdrs),
+	.xSlicDmaLensOffset = offsetof(struct ItVpdAreas, xPlicDmaLens),
+	.xSlicVpdLensOffset = offsetof(struct ItVpdAreas, xSlicVpdLens),
+	.xSlicMaxSlotLabels = 0,		/* max slot labels */
+	.xSlicMaxLpQueues = 1,			/* max LP queues */
+	.xPlicDmaLens = { 0 },			/* DMA lengths */
+	.xPlicDmaToks = { 0 },			/* DMA tokens */
+	.xSlicVpdLens = {			/* VPD lengths */
 	        0,0,0,		        /*  0 - 2 */
 		sizeof(xItExtVpdPanel), /*       3 Extended VPD   */
 		sizeof(struct paca_struct),	/*       4 length of Paca  */
@@ -201,7 +203,7 @@
 		sizeof(struct ItLpQueue),/*     23 length of Lp Queue */
 		0,0			/* 24 - 25 */
 		},
-	{			/* VPD addresses */
+	.xSlicVpdAdrs = {			/* VPD addresses */
 		0,0,0,  		/*	 0 -  2 */
 		&xItExtVpdPanel,        /*       3 Extended VPD */
 		&paca[0],		/*       4 first Paca */
diff -Nru a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile
--- a/arch/ppc64/kernel/Makefile	2005-03-01 23:39:17 -08:00
+++ b/arch/ppc64/kernel/Makefile	2005-03-01 23:39:17 -08:00
@@ -16,7 +16,7 @@
 obj-$(CONFIG_PPC_OF) +=	of_device.o
 
 pci-obj-$(CONFIG_PPC_ISERIES)	+= iSeries_pci.o iSeries_pci_reset.o
-pci-obj-$(CONFIG_PPC_MULTIPLATFORM)	+= pci_dn.o pci_dma_direct.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)
 
@@ -30,9 +30,10 @@
 obj-$(CONFIG_PPC_MULTIPLATFORM) += nvram.o i8259.o prom_init.o prom.o mpic.o
 
 obj-$(CONFIG_PPC_PSERIES) += pSeries_pci.o pSeries_lpar.o pSeries_hvCall.o \
-			     eeh.o pSeries_nvram.o rtasd.o ras.o \
+			     pSeries_nvram.o rtasd.o ras.o \
 			     xics.o rtas.o pSeries_setup.o pSeries_iommu.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
@@ -61,5 +62,6 @@
 endif
 
 obj-$(CONFIG_ALTIVEC)		+= vecemu.o vector.o
+obj-$(CONFIG_KPROBES)		+= kprobes.o
 
 CFLAGS_ioctl32.o += -Ifs/
diff -Nru a/arch/ppc64/kernel/asm-offsets.c b/arch/ppc64/kernel/asm-offsets.c
--- a/arch/ppc64/kernel/asm-offsets.c	2005-03-01 23:39:07 -08:00
+++ b/arch/ppc64/kernel/asm-offsets.c	2005-03-01 23:39:07 -08:00
@@ -28,13 +28,13 @@
 #include <asm/pgtable.h>
 #include <asm/processor.h>
 
-#include <asm/naca.h>
 #include <asm/paca.h>
-#include <asm/iSeries/ItLpPaca.h>
+#include <asm/lppaca.h>
 #include <asm/iSeries/ItLpQueue.h>
 #include <asm/iSeries/HvLpEvent.h>
 #include <asm/rtas.h>
 #include <asm/cputable.h>
+#include <asm/cache.h>
 
 #define DEFINE(sym, val) \
 	asm volatile("\n->" #sym " %0 " #val : : "i" (val))
@@ -67,14 +67,12 @@
 #endif /* CONFIG_ALTIVEC */
 	DEFINE(MM, offsetof(struct task_struct, mm));
 
-	/* naca */
-        DEFINE(PACA, offsetof(struct naca_struct, paca));
-	DEFINE(DCACHEL1LINESIZE, offsetof(struct systemcfg, dCacheL1LineSize));
-        DEFINE(DCACHEL1LOGLINESIZE, offsetof(struct naca_struct, dCacheL1LogLineSize));
-        DEFINE(DCACHEL1LINESPERPAGE, offsetof(struct naca_struct, dCacheL1LinesPerPage));
-        DEFINE(ICACHEL1LINESIZE, offsetof(struct systemcfg, iCacheL1LineSize));
-        DEFINE(ICACHEL1LOGLINESIZE, offsetof(struct naca_struct, iCacheL1LogLineSize));
-        DEFINE(ICACHEL1LINESPERPAGE, offsetof(struct naca_struct, iCacheL1LinesPerPage));
+	DEFINE(DCACHEL1LINESIZE, offsetof(struct ppc64_caches, dline_size));
+	DEFINE(DCACHEL1LOGLINESIZE, offsetof(struct ppc64_caches, log_dline_size));
+	DEFINE(DCACHEL1LINESPERPAGE, offsetof(struct ppc64_caches, dlines_per_page));
+	DEFINE(ICACHEL1LINESIZE, offsetof(struct ppc64_caches, iline_size));
+	DEFINE(ICACHEL1LOGLINESIZE, offsetof(struct ppc64_caches, log_iline_size));
+	DEFINE(ICACHEL1LINESPERPAGE, offsetof(struct ppc64_caches, ilines_per_page));
 	DEFINE(PLATFORM, offsetof(struct systemcfg, platform));
 
 	/* paca */
@@ -104,10 +102,10 @@
         DEFINE(PACAEMERGSP, offsetof(struct paca_struct, emergency_sp));
 	DEFINE(PACALPPACA, offsetof(struct paca_struct, lppaca));
 	DEFINE(PACAHWCPUID, offsetof(struct paca_struct, hw_cpu_id));
-        DEFINE(LPPACASRR0, offsetof(struct ItLpPaca, xSavedSrr0));
-        DEFINE(LPPACASRR1, offsetof(struct ItLpPaca, xSavedSrr1));
-	DEFINE(LPPACAANYINT, offsetof(struct ItLpPaca, xIntDword.xAnyInt));
-	DEFINE(LPPACADECRINT, offsetof(struct ItLpPaca, xIntDword.xFields.xDecrInt));
+	DEFINE(LPPACASRR0, offsetof(struct lppaca, saved_srr0));
+	DEFINE(LPPACASRR1, offsetof(struct lppaca, saved_srr1));
+	DEFINE(LPPACAANYINT, offsetof(struct lppaca, int_dword.any_int));
+	DEFINE(LPPACADECRINT, offsetof(struct lppaca, int_dword.fields.decr_int));
 
 	/* RTAS */
 	DEFINE(RTASBASE, offsetof(struct rtas_t, base));
diff -Nru a/arch/ppc64/kernel/binfmt_elf32.c b/arch/ppc64/kernel/binfmt_elf32.c
--- a/arch/ppc64/kernel/binfmt_elf32.c	2005-03-01 23:39:07 -08:00
+++ b/arch/ppc64/kernel/binfmt_elf32.c	2005-03-01 23:39:07 -08:00
@@ -60,10 +60,12 @@
 
 #include <linux/time.h>
 
-#define jiffies_to_timeval jiffies_to_compat_timeval
+#undef cputime_to_timeval
+#define cputime_to_timeval cputime_to_compat_timeval
 static __inline__ void
-jiffies_to_compat_timeval(unsigned long jiffies, struct compat_timeval *value)
+cputime_to_compat_timeval(const cputime_t cputime, struct compat_timeval *value)
 {
+	unsigned long jiffies = cputime_to_jiffies(cputime);
 	value->tv_usec = (jiffies % HZ) * (1000000L / HZ);
 	value->tv_sec = jiffies / HZ;
 }
diff -Nru a/arch/ppc64/kernel/eeh.c b/arch/ppc64/kernel/eeh.c
--- a/arch/ppc64/kernel/eeh.c	2005-03-01 23:39:07 -08:00
+++ b/arch/ppc64/kernel/eeh.c	2005-03-01 23:39:07 -08:00
@@ -32,6 +32,7 @@
 #include <asm/machdep.h>
 #include <asm/rtas.h>
 #include <asm/atomic.h>
+#include <asm/systemcfg.h>
 #include "pci.h"
 
 #undef DEBUG
@@ -75,7 +76,7 @@
 #define BUID_LO(buid) ((buid) & 0xffffffff)
 
 /* EEH event workqueue setup. */
-static spinlock_t eeh_eventlist_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(eeh_eventlist_lock);
 LIST_HEAD(eeh_eventlist);
 static void eeh_event_handler(void *);
 DECLARE_WORK(eeh_event_wq, eeh_event_handler, NULL);
@@ -95,13 +96,14 @@
 static int ibm_set_eeh_option;
 static int ibm_set_slot_reset;
 static int ibm_read_slot_reset_state;
+static int ibm_read_slot_reset_state2;
 static int ibm_slot_error_detail;
 
 static int eeh_subsystem_enabled;
 
 /* Buffer for reporting slot-error-detail rtas calls */
 static unsigned char slot_errbuf[RTAS_ERROR_LOG_MAX];
-static spinlock_t slot_errbuf_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(slot_errbuf_lock);
 static int eeh_error_buf_size;
 
 /* System monitoring statistics */
@@ -407,6 +409,27 @@
 }
 
 /**
+ * read_slot_reset_state - Read the reset state of a device node's slot
+ * @dn: device node to read
+ * @rets: array to return results in
+ */
+static int read_slot_reset_state(struct device_node *dn, int rets[])
+{
+	int token, outputs;
+
+	if (ibm_read_slot_reset_state2 != RTAS_UNKNOWN_SERVICE) {
+		token = ibm_read_slot_reset_state2;
+		outputs = 4;
+	} else {
+		token = ibm_read_slot_reset_state;
+		outputs = 3;
+	}
+
+	return rtas_call(token, 3, outputs, rets, dn->eeh_config_addr,
+			 BUID_HI(dn->phb->buid), BUID_LO(dn->phb->buid));
+}
+
+/**
  * eeh_panic - call panic() for an eeh event that cannot be handled.
  * The philosophy of this routine is that it is better to panic and
  * halt the OS than it is to risk possible data corruption by
@@ -508,7 +531,7 @@
 int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
 {
 	int ret;
-	int rets[2];
+	int rets[3];
 	unsigned long flags;
 	int rc, reset_state;
 	struct eeh_event  *event;
@@ -539,11 +562,8 @@
 		atomic_inc(&eeh_fail_count);
 		if (atomic_read(&eeh_fail_count) >= EEH_MAX_FAILS) {
 			/* re-read the slot reset state */
-			rets[0] = -1;
-			rtas_call(ibm_read_slot_reset_state, 3, 3, rets,
-				  dn->eeh_config_addr,
-				  BUID_HI(dn->phb->buid),
-				  BUID_LO(dn->phb->buid));
+			if (read_slot_reset_state(dn, rets) != 0)
+				rets[0] = -1;	/* reset state unknown */
 			eeh_panic(dev, rets[0]);
 		}
 		return 0;
@@ -556,10 +576,7 @@
 	 * function zero of a multi-function device.
 	 * In any case they must share a common PHB.
 	 */
-	ret = rtas_call(ibm_read_slot_reset_state, 3, 3, rets,
-			dn->eeh_config_addr, BUID_HI(dn->phb->buid),
-			BUID_LO(dn->phb->buid));
-
+	ret = read_slot_reset_state(dn, rets);
 	if (!(ret == 0 && rets[1] == 1 && (rets[0] == 2 || rets[0] == 4))) {
 		__get_cpu_var(false_positives)++;
 		return 0;
@@ -747,14 +764,13 @@
 	struct device_node *phb, *np;
 	struct eeh_early_enable_info info;
 
-	init_pci_config_tokens();
-
 	np = of_find_node_by_path("/rtas");
 	if (np == NULL)
 		return;
 
 	ibm_set_eeh_option = rtas_token("ibm,set-eeh-option");
 	ibm_set_slot_reset = rtas_token("ibm,set-slot-reset");
+	ibm_read_slot_reset_state2 = rtas_token("ibm,read-slot-reset-state2");
 	ibm_read_slot_reset_state = rtas_token("ibm,read-slot-reset-state");
 	ibm_slot_error_detail = rtas_token("ibm,slot-error-detail");
 
diff -Nru a/arch/ppc64/kernel/entry.S b/arch/ppc64/kernel/entry.S
--- a/arch/ppc64/kernel/entry.S	2005-03-01 23:38:51 -08:00
+++ b/arch/ppc64/kernel/entry.S	2005-03-01 23:38:51 -08:00
@@ -54,8 +54,8 @@
 
 #undef SHOW_SYSCALLS
 
-	.globl SystemCall_common
-SystemCall_common:
+	.globl system_call_common
+system_call_common:
 	andi.	r10,r12,MSR_PR
 	mr	r10,r1
 	addi	r1,r1,-INT_FRAME_SIZE
@@ -100,7 +100,7 @@
 	cmpdi	cr1,r0,0x5555		/* syscall 0x5555 */
 	andi.	r10,r12,MSR_PR		/* from kernel */
 	crand	4*cr0+eq,4*cr1+eq,4*cr0+eq
-	beq	HardwareInterrupt_entry
+	beq	hardware_interrupt_entry
 	lbz	r10,PACAPROCENABLED(r13)
 	std	r10,SOFTE(r1)
 #endif
@@ -185,10 +185,10 @@
 	beq-	1f			/* only restore r13 if */
 	ld	r13,GPR13(r1)		/* returning to usermode */
 1:	ld	r2,GPR2(r1)
-	ld	r1,GPR1(r1)
 	li	r12,MSR_RI
 	andc	r10,r10,r12
 	mtmsrd	r10,1			/* clear MSR.RI */
+	ld	r1,GPR1(r1)
 	mtlr	r4
 	mtcr	r5
 	mtspr	SRR0,r7
@@ -231,6 +231,7 @@
 syscall_exit_trace:
 	std	r3,GPR3(r1)
 	bl	.save_nvgprs
+	addi	r3,r1,STACK_FRAME_OVERHEAD
 	bl	.do_syscall_trace_leave
 	REST_NVGPRS(r1)
 	ld	r3,GPR3(r1)
@@ -324,6 +325,7 @@
 	ld	r4,TI_FLAGS(r4)
 	andi.	r4,r4,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP)
 	beq+	81f
+	addi	r3,r1,STACK_FRAME_OVERHEAD
 	bl	.do_syscall_trace_leave
 81:	b	.ret_from_except
 
@@ -574,25 +576,22 @@
 	crandc	eq,cr1*4+eq,eq
 	bne	restore
 	/* here we are preempting the current task */
-1:	lis	r0,PREEMPT_ACTIVE@h
-	stw	r0,TI_PREEMPT(r9)
+1:
 #ifdef CONFIG_PPC_ISERIES
 	li	r0,1
 	stb	r0,PACAPROCENABLED(r13)
 #endif
 	ori	r10,r10,MSR_EE
 	mtmsrd	r10,1		/* reenable interrupts */
-	bl	.schedule
+	bl	.preempt_schedule
 	mfmsr	r10
 	clrrdi	r9,r1,THREAD_SHIFT
 	rldicl	r10,r10,48,1	/* disable interrupts again */
-	li	r0,0
 	rotldi	r10,r10,16
 	mtmsrd	r10,1
 	ld	r4,TI_FLAGS(r9)
 	andi.	r0,r4,_TIF_NEED_RESCHED
 	bne	1b
-	stw	r0,TI_PREEMPT(r9)
 	b	restore
 
 user_work:
diff -Nru a/arch/ppc64/kernel/head.S b/arch/ppc64/kernel/head.S
--- a/arch/ppc64/kernel/head.S	2005-03-01 23:38:57 -08:00
+++ b/arch/ppc64/kernel/head.S	2005-03-01 23:38:57 -08:00
@@ -78,7 +78,7 @@
  *
  *  For iSeries:
  *   1. The MMU is on (as it always is for iSeries)
- *   2. The kernel is entered at SystemReset_Iseries
+ *   2. The kernel is entered at system_reset_iSeries
  */
 
 	.text
@@ -165,7 +165,7 @@
 #else
 #ifdef CONFIG_SMP
 	mr	r3,r24
-	b	.pseries_secondary_smp_init
+	b	.pSeries_secondary_smp_init
 #else
 	BUG_OPCODE
 #endif
@@ -305,15 +305,15 @@
  */
 #define STD_EXCEPTION_PSERIES(n, label)			\
 	. = n;						\
-	.globl label##_Pseries;				\
-label##_Pseries:					\
+	.globl label##_pSeries;				\
+label##_pSeries:					\
 	HMT_MEDIUM;					\
 	mtspr	SPRG1,r13;		/* save r13 */	\
 	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common)
 
 #define STD_EXCEPTION_ISERIES(n, label, area)		\
-	.globl label##_Iseries;				\
-label##_Iseries:					\
+	.globl label##_iSeries;				\
+label##_iSeries:					\
 	HMT_MEDIUM;					\
 	mtspr	SPRG1,r13;		/* save r13 */	\
 	EXCEPTION_PROLOG_ISERIES_1(area);		\
@@ -321,14 +321,14 @@
 	b	label##_common
 
 #define MASKABLE_EXCEPTION_ISERIES(n, label)				\
-	.globl label##_Iseries;						\
-label##_Iseries:							\
+	.globl label##_iSeries;						\
+label##_iSeries:							\
 	HMT_MEDIUM;							\
 	mtspr	SPRG1,r13;		/* save r13 */			\
 	EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN);				\
 	lbz	r10,PACAPROCENABLED(r13);				\
 	cmpwi	0,r10,0;						\
-	beq-	label##_Iseries_masked;					\
+	beq-	label##_iSeries_masked;					\
 	EXCEPTION_PROLOG_ISERIES_2;					\
 	b	label##_common;						\
 
@@ -388,17 +388,17 @@
 	.globl __start_interrupts
 __start_interrupts:
 
-	STD_EXCEPTION_PSERIES(0x100, SystemReset)
+	STD_EXCEPTION_PSERIES(0x100, system_reset)
 
 	. = 0x200
-_MachineCheckPseries:
+_machine_check_pSeries:
 	HMT_MEDIUM
 	mtspr	SPRG1,r13		/* save r13 */
-	EXCEPTION_PROLOG_PSERIES(PACA_EXMC, MachineCheck_common)
+	EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common)
 
 	. = 0x300
-	.globl DataAccess_Pseries
-DataAccess_Pseries:
+	.globl data_access_pSeries
+data_access_pSeries:
 	HMT_MEDIUM
 	mtspr	SPRG1,r13
 BEGIN_FTR_SECTION
@@ -409,15 +409,15 @@
 	rlwimi	r13,r12,16,0x20
 	mfcr	r12
 	cmpwi	r13,0x2c
-	beq	.do_stab_bolted_Pseries
+	beq	.do_stab_bolted_pSeries
 	mtcrf	0x80,r12
 	mfspr	r12,SPRG2
 END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
-	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, DataAccess_common)
+	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, data_access_common)
 
 	. = 0x380
-	.globl DataAccessSLB_Pseries
-DataAccessSLB_Pseries:
+	.globl data_access_slb_pSeries
+data_access_slb_pSeries:
 	HMT_MEDIUM
 	mtspr	SPRG1,r13
 	mfspr	r13,SPRG3		/* get paca address into r13 */
@@ -433,11 +433,11 @@
 	mfspr	r3,DAR
 	b	.do_slb_miss		/* Rel. branch works in real mode */
 
-	STD_EXCEPTION_PSERIES(0x400, InstructionAccess)
+	STD_EXCEPTION_PSERIES(0x400, instruction_access)
 
 	. = 0x480
-	.globl InstructionAccessSLB_Pseries
-InstructionAccessSLB_Pseries:
+	.globl instruction_access_slb_pSeries
+instruction_access_slb_pSeries:
 	HMT_MEDIUM
 	mtspr	SPRG1,r13
 	mfspr	r13,SPRG3		/* get paca address into r13 */
@@ -453,25 +453,25 @@
 	mfspr	r3,SRR0			/* SRR0 is faulting address */
 	b	.do_slb_miss		/* Rel. branch works in real mode */
 
-	STD_EXCEPTION_PSERIES(0x500, HardwareInterrupt)
-	STD_EXCEPTION_PSERIES(0x600, Alignment)
-	STD_EXCEPTION_PSERIES(0x700, ProgramCheck)
-	STD_EXCEPTION_PSERIES(0x800, FPUnavailable)
-	STD_EXCEPTION_PSERIES(0x900, Decrementer)
-	STD_EXCEPTION_PSERIES(0xa00, Trap_0a)
-	STD_EXCEPTION_PSERIES(0xb00, Trap_0b)
+	STD_EXCEPTION_PSERIES(0x500, hardware_interrupt)
+	STD_EXCEPTION_PSERIES(0x600, alignment)
+	STD_EXCEPTION_PSERIES(0x700, program_check)
+	STD_EXCEPTION_PSERIES(0x800, fp_unavailable)
+	STD_EXCEPTION_PSERIES(0x900, decrementer)
+	STD_EXCEPTION_PSERIES(0xa00, trap_0a)
+	STD_EXCEPTION_PSERIES(0xb00, trap_0b)
 
 	. = 0xc00
-	.globl	SystemCall_Pseries
-SystemCall_Pseries:
+	.globl	system_call_pSeries
+system_call_pSeries:
 	HMT_MEDIUM
 	mr	r9,r13
 	mfmsr	r10
 	mfspr	r13,SPRG3
 	mfspr	r11,SRR0
 	clrrdi	r12,r13,32
-	oris	r12,r12,SystemCall_common@h
-	ori	r12,r12,SystemCall_common@l
+	oris	r12,r12,system_call_common@h
+	ori	r12,r12,system_call_common@l
 	mtspr	SRR0,r12
 	ori	r10,r10,MSR_IR|MSR_DR|MSR_RI
 	mfspr	r12,SRR1
@@ -479,8 +479,8 @@
 	rfid
 	b	.	/* prevent speculative execution */
 
-	STD_EXCEPTION_PSERIES(0xd00, SingleStep)
-	STD_EXCEPTION_PSERIES(0xe00, Trap_0e)
+	STD_EXCEPTION_PSERIES(0xd00, single_step)
+	STD_EXCEPTION_PSERIES(0xe00, trap_0e)
 
 	/* We need to deal with the Altivec unavailable exception
 	 * here which is at 0xf20, thus in the middle of the
@@ -488,18 +488,18 @@
 	 * trickery is thus necessary
 	 */
 	. = 0xf00
-	b	PerformanceMonitor_Pseries
+	b	performance_monitor_pSeries
 
-	STD_EXCEPTION_PSERIES(0xf20, AltivecUnavailable)
+	STD_EXCEPTION_PSERIES(0xf20, altivec_unavailable)
 
-	STD_EXCEPTION_PSERIES(0x1300, InstructionBreakpoint)
-	STD_EXCEPTION_PSERIES(0x1700, AltivecAssist)
+	STD_EXCEPTION_PSERIES(0x1300, instruction_breakpoint)
+	STD_EXCEPTION_PSERIES(0x1700, altivec_assist)
 
 	/* moved from 0xf00 */
-	STD_EXCEPTION_PSERIES(0x3000, PerformanceMonitor)
+	STD_EXCEPTION_PSERIES(0x3000, performance_monitor)
 
 	. = 0x3100
-_GLOBAL(do_stab_bolted_Pseries)
+_GLOBAL(do_stab_bolted_pSeries)
 	mtcrf	0x80,r12
 	mfspr	r12,SPRG2
 	EXCEPTION_PROLOG_PSERIES(PACA_EXSLB, .do_stab_bolted)
@@ -512,22 +512,15 @@
 	 */
 	. = NACA_PHYS_ADDR
 	.globl __end_interrupts
-	.globl __start_naca
 __end_interrupts:
-__start_naca:
 #ifdef CONFIG_PPC_ISERIES
+	.globl naca
+naca:
 	.llong itVpdAreas
-#else
-	.llong 0x0
 #endif
-	.llong 0x0
-	.llong 0x0
-	.llong paca
 
 	. = SYSTEMCFG_PHYS_ADDR
-	.globl __end_naca
 	.globl __start_systemcfg
-__end_naca:
 __start_systemcfg:
 	. = (SYSTEMCFG_PHYS_ADDR + PAGE_SIZE)
 	.globl __end_systemcfg
@@ -565,10 +558,10 @@
 
 /***  ISeries-LPAR interrupt handlers ***/
 
-	STD_EXCEPTION_ISERIES(0x200, MachineCheck, PACA_EXMC)
+	STD_EXCEPTION_ISERIES(0x200, machine_check, PACA_EXMC)
 
-	.globl DataAccess_Iseries
-DataAccess_Iseries:
+	.globl data_access_iSeries
+data_access_iSeries:
 	mtspr	SPRG1,r13
 BEGIN_FTR_SECTION
 	mtspr	SPRG2,r12
@@ -578,23 +571,23 @@
 	rlwimi	r13,r12,16,0x20
 	mfcr	r12
 	cmpwi	r13,0x2c
-	beq	.do_stab_bolted_Iseries
+	beq	.do_stab_bolted_iSeries
 	mtcrf	0x80,r12
 	mfspr	r12,SPRG2
 END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
 	EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN)
 	EXCEPTION_PROLOG_ISERIES_2
-	b	DataAccess_common
+	b	data_access_common
 
-.do_stab_bolted_Iseries:
+.do_stab_bolted_iSeries:
 	mtcrf	0x80,r12
 	mfspr	r12,SPRG2
 	EXCEPTION_PROLOG_ISERIES_1(PACA_EXSLB)
 	EXCEPTION_PROLOG_ISERIES_2
 	b	.do_stab_bolted
 
-	.globl	DataAccessSLB_Iseries
-DataAccessSLB_Iseries:
+	.globl	data_access_slb_iSeries
+data_access_slb_iSeries:
 	mtspr	SPRG1,r13		/* save r13 */
 	EXCEPTION_PROLOG_ISERIES_1(PACA_EXSLB)
 	std	r3,PACA_EXSLB+EX_R3(r13)
@@ -602,10 +595,10 @@
 	mfspr	r3,DAR
 	b	.do_slb_miss
 
-	STD_EXCEPTION_ISERIES(0x400, InstructionAccess, PACA_EXGEN)
+	STD_EXCEPTION_ISERIES(0x400, instruction_access, PACA_EXGEN)
 
-	.globl	InstructionAccessSLB_Iseries
-InstructionAccessSLB_Iseries:
+	.globl	instruction_access_slb_iSeries
+instruction_access_slb_iSeries:
 	mtspr	SPRG1,r13		/* save r13 */
 	EXCEPTION_PROLOG_ISERIES_1(PACA_EXSLB)
 	std	r3,PACA_EXSLB+EX_R3(r13)
@@ -613,27 +606,27 @@
 	ld	r3,PACALPPACA+LPPACASRR0(r13)
 	b	.do_slb_miss
 
-	MASKABLE_EXCEPTION_ISERIES(0x500, HardwareInterrupt)
-	STD_EXCEPTION_ISERIES(0x600, Alignment, PACA_EXGEN)
-	STD_EXCEPTION_ISERIES(0x700, ProgramCheck, PACA_EXGEN)
-	STD_EXCEPTION_ISERIES(0x800, FPUnavailable, PACA_EXGEN)
-	MASKABLE_EXCEPTION_ISERIES(0x900, Decrementer)
-	STD_EXCEPTION_ISERIES(0xa00, Trap_0a, PACA_EXGEN)
-	STD_EXCEPTION_ISERIES(0xb00, Trap_0b, PACA_EXGEN)
+	MASKABLE_EXCEPTION_ISERIES(0x500, hardware_interrupt)
+	STD_EXCEPTION_ISERIES(0x600, alignment, PACA_EXGEN)
+	STD_EXCEPTION_ISERIES(0x700, program_check, PACA_EXGEN)
+	STD_EXCEPTION_ISERIES(0x800, fp_unavailable, PACA_EXGEN)
+	MASKABLE_EXCEPTION_ISERIES(0x900, decrementer)
+	STD_EXCEPTION_ISERIES(0xa00, trap_0a, PACA_EXGEN)
+	STD_EXCEPTION_ISERIES(0xb00, trap_0b, PACA_EXGEN)
 
-	.globl	SystemCall_Iseries
-SystemCall_Iseries:
+	.globl	system_call_iSeries
+system_call_iSeries:
 	mr	r9,r13
 	mfspr	r13,SPRG3
 	EXCEPTION_PROLOG_ISERIES_2
-	b	SystemCall_common
+	b	system_call_common
 
-	STD_EXCEPTION_ISERIES( 0xd00, SingleStep, PACA_EXGEN)
-	STD_EXCEPTION_ISERIES( 0xe00, Trap_0e, PACA_EXGEN)
-	STD_EXCEPTION_ISERIES( 0xf00, PerformanceMonitor, PACA_EXGEN)
+	STD_EXCEPTION_ISERIES( 0xd00, single_step, PACA_EXGEN)
+	STD_EXCEPTION_ISERIES( 0xe00, trap_0e, PACA_EXGEN)
+	STD_EXCEPTION_ISERIES( 0xf00, performance_monitor, PACA_EXGEN)
 
-	.globl SystemReset_Iseries
-SystemReset_Iseries:
+	.globl system_reset_iSeries
+system_reset_iSeries:
 	mfspr	r13,SPRG3		/* Get paca address */
 	mfmsr	r24
 	ori	r24,r24,MSR_RI
@@ -659,11 +652,11 @@
 	subi	r1,r1,STACK_FRAME_OVERHEAD
 
 	cmpwi	0,r23,0
-	beq	iseries_secondary_smp_loop	/* Loop until told to go */
+	beq	iSeries_secondary_smp_loop	/* Loop until told to go */
 #ifdef SECONDARY_PROCESSORS
 	bne	.__secondary_start		/* Loop until told to go */
 #endif
-iseries_secondary_smp_loop:
+iSeries_secondary_smp_loop:
 	/* Let the Hypervisor know we are alive */
 	/* 8002 is a call to HvCallCfg::getLps, a harmless Hypervisor function */
 	lis	r3,0x8002
@@ -683,16 +676,16 @@
 	b	1b			/* If SMP not configured, secondaries
 					 * loop forever */
 
-	.globl Decrementer_Iseries_masked
-Decrementer_Iseries_masked:
+	.globl decrementer_iSeries_masked
+decrementer_iSeries_masked:
 	li	r11,1
 	stb	r11,PACALPPACA+LPPACADECRINT(r13)
 	lwz	r12,PACADEFAULTDECR(r13)
 	mtspr	SPRN_DEC,r12
 	/* fall through */
 
-	.globl HardwareInterrupt_Iseries_masked
-HardwareInterrupt_Iseries_masked:
+	.globl hardware_interrupt_iSeries_masked
+hardware_interrupt_iSeries_masked:
 	mtcrf	0x80,r9		/* Restore regs */
 	ld	r11,PACALPPACA+LPPACASRR0(r13)
 	ld	r12,PACALPPACA+LPPACASRR1(r13)
@@ -718,16 +711,16 @@
  * Vectors for the FWNMI option.  Share common code.
  */
 	. = 0x8000
-	.globl SystemReset_FWNMI
-SystemReset_FWNMI:
+	.globl system_reset_fwnmi
+system_reset_fwnmi:
 	HMT_MEDIUM
 	mtspr	SPRG1,r13		/* save r13 */
-	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, SystemReset_common)
-	.globl MachineCheck_FWNMI
-MachineCheck_FWNMI:
+	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common)
+	.globl machine_check_fwnmi
+machine_check_fwnmi:
 	HMT_MEDIUM
 	mtspr	SPRG1,r13		/* save r13 */
-	EXCEPTION_PROLOG_PSERIES(PACA_EXMC, MachineCheck_common)
+	EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common)
 
 	/*
 	 * Space for the initial segment table
@@ -745,33 +738,33 @@
 
 /*** Common interrupt handlers ***/
 
-	STD_EXCEPTION_COMMON(0x100, SystemReset, .SystemResetException)
+	STD_EXCEPTION_COMMON(0x100, system_reset, .system_reset_exception)
 
 	/*
 	 * Machine check is different because we use a different
 	 * save area: PACA_EXMC instead of PACA_EXGEN.
 	 */
 	.align	7
-	.globl MachineCheck_common
-MachineCheck_common:
+	.globl machine_check_common
+machine_check_common:
 	EXCEPTION_PROLOG_COMMON(0x200, PACA_EXMC)
 	DISABLE_INTS
 	bl	.save_nvgprs
 	addi	r3,r1,STACK_FRAME_OVERHEAD
-	bl	.MachineCheckException
+	bl	.machine_check_exception
 	b	.ret_from_except
 
-	STD_EXCEPTION_COMMON_LITE(0x900, Decrementer, .timer_interrupt)
-	STD_EXCEPTION_COMMON(0xa00, Trap_0a, .UnknownException)
-	STD_EXCEPTION_COMMON(0xb00, Trap_0b, .UnknownException)
-	STD_EXCEPTION_COMMON(0xd00, SingleStep, .SingleStepException)
-	STD_EXCEPTION_COMMON(0xe00, Trap_0e, .UnknownException)
-	STD_EXCEPTION_COMMON(0xf00, PerformanceMonitor, .PerformanceMonitorException)
-	STD_EXCEPTION_COMMON(0x1300, InstructionBreakpoint, .InstructionBreakpointException)
+	STD_EXCEPTION_COMMON_LITE(0x900, decrementer, .timer_interrupt)
+	STD_EXCEPTION_COMMON(0xa00, trap_0a, .unknown_exception)
+	STD_EXCEPTION_COMMON(0xb00, trap_0b, .unknown_exception)
+	STD_EXCEPTION_COMMON(0xd00, single_step, .single_step_exception)
+	STD_EXCEPTION_COMMON(0xe00, trap_0e, .unknown_exception)
+	STD_EXCEPTION_COMMON(0xf00, performance_monitor, .performance_monitor_exception)
+	STD_EXCEPTION_COMMON(0x1300, instruction_breakpoint, .instruction_breakpoint_exception)
 #ifdef CONFIG_ALTIVEC
-	STD_EXCEPTION_COMMON(0x1700, AltivecAssist, .AltivecAssistException)
+	STD_EXCEPTION_COMMON(0x1700, altivec_assist, .altivec_assist_exception)
 #else
-	STD_EXCEPTION_COMMON(0x1700, AltivecAssist, .UnknownException)
+	STD_EXCEPTION_COMMON(0x1700, altivec_assist, .unknown_exception)
 #endif
 
 /*
@@ -861,8 +854,8 @@
  * r9 - r13 are saved in paca->exgen.
  */
 	.align	7
-	.globl DataAccess_common
-DataAccess_common:
+	.globl data_access_common
+data_access_common:
 	mfspr	r10,DAR
 	std	r10,PACA_EXGEN+EX_DAR(r13)
 	mfspr	r10,DSISR
@@ -874,8 +867,8 @@
 	b	.do_hash_page	 	/* Try to handle as hpte fault */
 
 	.align	7
-	.globl InstructionAccess_common
-InstructionAccess_common:
+	.globl instruction_access_common
+instruction_access_common:
 	EXCEPTION_PROLOG_COMMON(0x400, PACA_EXGEN)
 	ld	r3,_NIP(r1)
 	andis.	r4,r12,0x5820
@@ -883,19 +876,19 @@
 	b	.do_hash_page		/* Try to handle as hpte fault */
 
 	.align	7
-	.globl HardwareInterrupt_common
-	.globl HardwareInterrupt_entry
-HardwareInterrupt_common:
+	.globl hardware_interrupt_common
+	.globl hardware_interrupt_entry
+hardware_interrupt_common:
 	EXCEPTION_PROLOG_COMMON(0x500, PACA_EXGEN)
-HardwareInterrupt_entry:
+hardware_interrupt_entry:
 	DISABLE_INTS
 	addi	r3,r1,STACK_FRAME_OVERHEAD
 	bl	.do_IRQ
 	b	.ret_from_except_lite
 
 	.align	7
-	.globl Alignment_common
-Alignment_common:
+	.globl alignment_common
+alignment_common:
 	mfspr	r10,DAR
 	std	r10,PACA_EXGEN+EX_DAR(r13)
 	mfspr	r10,DSISR
@@ -908,33 +901,33 @@
 	bl	.save_nvgprs
 	addi	r3,r1,STACK_FRAME_OVERHEAD
 	ENABLE_INTS
-	bl	.AlignmentException
+	bl	.alignment_exception
 	b	.ret_from_except
 
 	.align	7
-	.globl ProgramCheck_common
-ProgramCheck_common:
+	.globl program_check_common
+program_check_common:
 	EXCEPTION_PROLOG_COMMON(0x700, PACA_EXGEN)
 	bl	.save_nvgprs
 	addi	r3,r1,STACK_FRAME_OVERHEAD
 	ENABLE_INTS
-	bl	.ProgramCheckException
+	bl	.program_check_exception
 	b	.ret_from_except
 
 	.align	7
-	.globl FPUnavailable_common
-FPUnavailable_common:
+	.globl fp_unavailable_common
+fp_unavailable_common:
 	EXCEPTION_PROLOG_COMMON(0x800, PACA_EXGEN)
 	bne	.load_up_fpu		/* if from user, just load it up */
 	bl	.save_nvgprs
 	addi	r3,r1,STACK_FRAME_OVERHEAD
 	ENABLE_INTS
-	bl	.KernelFPUnavailableException
+	bl	.kernel_fp_unavailable_exception
 	BUG_OPCODE
 
 	.align	7
-	.globl AltivecUnavailable_common
-AltivecUnavailable_common:
+	.globl altivec_unavailable_common
+altivec_unavailable_common:
 	EXCEPTION_PROLOG_COMMON(0xf20, PACA_EXGEN)
 #ifdef CONFIG_ALTIVEC
 	bne	.load_up_altivec	/* if from user, just load it up */
@@ -942,7 +935,7 @@
 	bl	.save_nvgprs
 	addi	r3,r1,STACK_FRAME_OVERHEAD
 	ENABLE_INTS
-	bl	.AltivecUnavailableException
+	bl	.altivec_unavailable_exception
 	b	.ret_from_except
 
 /*
@@ -1195,7 +1188,7 @@
  * On pSeries, secondary processors spin in the following code.
  * At entry, r3 = this processor's number (physical cpu id)
  */
-_GLOBAL(pseries_secondary_smp_init)
+_GLOBAL(pSeries_secondary_smp_init)
 	mr	r24,r3
 	
 	/* turn on 64-bit mode */
@@ -1241,6 +1234,7 @@
 #endif
 #endif
 	b 	3b			/* Loop until told to go	 */
+
 #ifdef CONFIG_PPC_ISERIES
 _STATIC(__start_initialization_iSeries)
 	/* Clear out the BSS */
@@ -1274,14 +1268,6 @@
 	SET_REG_TO_CONST(r4, SYSTEMCFG_VIRT_ADDR)
 	std	r4,0(r9)		/* set the systemcfg pointer */
 
-	LOADADDR(r9,naca)
-	SET_REG_TO_CONST(r4, NACA_VIRT_ADDR)
-	std	r4,0(r9)		/* set the naca pointer */
-
-	/* Get the pointer to the segment table */
-	ld	r6,PACA(r4)		/* Get the base paca pointer	*/
-	ld	r4,PACASTABVIRT(r6)
-
 	bl	.iSeries_early_setup
 
 	/* relocation is on at this point */
@@ -1881,12 +1867,6 @@
 	li	r27,SYSTEMCFG_PHYS_ADDR
 	std	r27,0(r6)	 	/* set the value of systemcfg	*/
 
-	/* setup the naca pointer which is needed by *tab_initialize	*/
-	LOADADDR(r6,naca)
-	sub	r6,r6,r26		/* addr of the variable naca	*/
-	li	r27,NACA_PHYS_ADDR
-	std	r27,0(r6)	 	/* set the value of naca	*/
-
 #ifdef CONFIG_HMT
 	/* Start up the second thread on cpu 0 */
 	mfspr	r3,PVR
@@ -2023,11 +2003,6 @@
 	SET_REG_TO_CONST(r8, SYSTEMCFG_VIRT_ADDR)
 	std	r8,0(r9)
 
-	/* setup the naca pointer */
-	LOADADDR(r9,naca)
-	SET_REG_TO_CONST(r8, NACA_VIRT_ADDR)
-	std	r8,0(r9)		/* set the value of the naca ptr */
-
 	LOADADDR(r26, boot_cpuid)
 	lwz	r26,0(r26)
 
@@ -2108,7 +2083,7 @@
 101:
 #endif
 	mr	r3,r24
-	b	.pseries_secondary_smp_init
+	b	.pSeries_secondary_smp_init
 
 #ifdef CONFIG_HMT
 _GLOBAL(hmt_start_secondary)
@@ -2170,10 +2145,12 @@
 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
diff -Nru a/arch/ppc64/kernel/i8259.c b/arch/ppc64/kernel/i8259.c
--- a/arch/ppc64/kernel/i8259.c	2005-03-01 23:39:17 -08:00
+++ b/arch/ppc64/kernel/i8259.c	2005-03-01 23:39:17 -08:00
@@ -21,7 +21,7 @@
 #define cached_A1 (cached_8259[0])
 #define cached_21 (cached_8259[1])
 
-static spinlock_t i8259_lock __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
+static  __cacheline_aligned_in_smp DEFINE_SPINLOCK(i8259_lock);
 
 static int i8259_pic_irq_offset;
 static int i8259_present;
diff -Nru a/arch/ppc64/kernel/iSeries_VpdInfo.c b/arch/ppc64/kernel/iSeries_VpdInfo.c
--- a/arch/ppc64/kernel/iSeries_VpdInfo.c	2005-03-01 23:38:52 -08:00
+++ b/arch/ppc64/kernel/iSeries_VpdInfo.c	2005-03-01 23:38:52 -08:00
@@ -36,7 +36,6 @@
 #include <asm/iSeries/HvTypes.h>
 #include <asm/iSeries/mf.h>
 #include <asm/iSeries/LparData.h>
-//#include <asm/iSeries/iSeries_VpdInfo.h>
 #include <asm/iSeries/iSeries_pci.h>
 #include "pci.h"
 
@@ -85,30 +84,6 @@
 #define SLOT_ENTRY_SIZE   16
 
 /*
- * Bus, Card, Board, FrameId, CardLocation.
- */
-LocationData* iSeries_GetLocationData(struct pci_dev *PciDev)
-{
-	struct iSeries_Device_Node *DevNode =
-		(struct iSeries_Device_Node *)PciDev->sysdata;
-	LocationData *LocationPtr =
-		(LocationData *)kmalloc(LOCATION_DATA_SIZE, GFP_KERNEL);
-
-	if (LocationPtr == NULL) {
-		printk("PCI: LocationData area allocation failed!\n");
-		return NULL;
-	}
-	memset(LocationPtr, 0, LOCATION_DATA_SIZE);
-	LocationPtr->Bus = ISERIES_BUS(DevNode);
-	LocationPtr->Board = DevNode->Board;
-	LocationPtr->FrameId = DevNode->FrameId;
-	LocationPtr->Card = PCI_SLOT(DevNode->DevFn);
-	strcpy(&LocationPtr->CardLocation[0], &DevNode->CardLocation[0]);
-	return LocationPtr;
-}
-EXPORT_SYMBOL(iSeries_GetLocationData);
-
-/*
  * 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
@@ -146,18 +121,6 @@
 				pci_class_name(PciDev->class >> 8));
 #endif
 	return len;
-}
-
-/*
- * Build a character string of the device location, Frame  1, Card  C10
- */
-int device_Location(struct pci_dev *PciDev, char *BufPtr)
-{
-	struct iSeries_Device_Node *DevNode =
-		(struct iSeries_Device_Node *)PciDev->sysdata;
-	return sprintf(BufPtr, "PCI: Bus%3d, AgentId%3d, Vendor %04X, Location %s",
-		       DevNode->DsaAddr.Dsa.busNumber, DevNode->AgentId,
-		       DevNode->Vendor, DevNode->Location);
 }
 
 /*
diff -Nru a/arch/ppc64/kernel/iSeries_iommu.c b/arch/ppc64/kernel/iSeries_iommu.c
--- a/arch/ppc64/kernel/iSeries_iommu.c	2005-03-01 23:38:51 -08:00
+++ b/arch/ppc64/kernel/iSeries_iommu.c	2005-03-01 23:38:51 -08:00
@@ -132,11 +132,11 @@
 	if (parms->itc_size == 0)
 		panic("PCI_DMA: parms->size is zero, parms is 0x%p", parms);
 
-	tbl->it_size = parms->itc_size;
+	/* itc_size is in pages worth of table, it_size is in # of entries */
+	tbl->it_size = (parms->itc_size * PAGE_SIZE) / sizeof(union tce_entry);
 	tbl->it_busno = parms->itc_busno;
 	tbl->it_offset = parms->itc_offset;
 	tbl->it_index = parms->itc_index;
-	tbl->it_entrysize = sizeof(union tce_entry);
 	tbl->it_blocksize = 1;
 	tbl->it_type = TCE_PCI;
 
@@ -160,11 +160,16 @@
 		kfree(tbl);
 }
 
+static void iommu_dev_setup_iSeries(struct pci_dev *dev) { }
+static void iommu_bus_setup_iSeries(struct pci_bus *bus) { }
 
-void tce_init_iSeries(void)
+void iommu_init_early_iSeries(void)
 {
 	ppc_md.tce_build = tce_build_iSeries;
 	ppc_md.tce_free  = tce_free_iSeries;
+
+	ppc_md.iommu_dev_setup = iommu_dev_setup_iSeries;
+	ppc_md.iommu_bus_setup = iommu_bus_setup_iSeries;
 
 	pci_iommu_init();
 }
diff -Nru a/arch/ppc64/kernel/iSeries_pci.c b/arch/ppc64/kernel/iSeries_pci.c
--- a/arch/ppc64/kernel/iSeries_pci.c	2005-03-01 23:39:17 -08:00
+++ b/arch/ppc64/kernel/iSeries_pci.c	2005-03-01 23:39:17 -08:00
@@ -35,7 +35,6 @@
 #include <asm/machdep.h>
 #include <asm/pci-bridge.h>
 #include <asm/ppcdebug.h>
-#include <asm/naca.h>
 #include <asm/iommu.h>
 
 #include <asm/iSeries/HvCallPci.h>
@@ -48,8 +47,6 @@
 
 #include "pci.h"
 
-extern int panic_timeout;
-
 extern unsigned long io_page_mask;
 
 /*
@@ -99,7 +96,7 @@
  * Static and Global variables
  */
 static char *pci_io_text = "iSeries PCI I/O";
-static spinlock_t iomm_table_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(iomm_table_lock);
 
 /*
  * iomm_table_initialize
diff -Nru a/arch/ppc64/kernel/iSeries_pci_reset.c b/arch/ppc64/kernel/iSeries_pci_reset.c
--- a/arch/ppc64/kernel/iSeries_pci_reset.c	2005-03-01 23:39:08 -08:00
+++ b/arch/ppc64/kernel/iSeries_pci_reset.c	2005-03-01 23:39:08 -08:00
@@ -32,6 +32,7 @@
 #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>
@@ -49,7 +50,7 @@
 int iSeries_Device_ToggleReset(struct pci_dev *PciDev, int AssertTime,
 		int DelayTime)
 {
-	unsigned long AssertDelay, WaitDelay;
+	unsigned int AssertDelay, WaitDelay;
 	struct iSeries_Device_Node *DeviceNode =
 		(struct iSeries_Device_Node *)PciDev->sysdata;
 
@@ -62,14 +63,14 @@
 	 * Set defaults, Assert is .5 second, Wait is 3 seconds.
 	 */
 	if (AssertTime == 0)
-		AssertDelay = (5 * HZ) / 10;
+		AssertDelay = 500;
 	else
-		AssertDelay = (AssertTime * HZ) / 10;
+		AssertDelay = AssertTime * 100;
 
 	if (DelayTime == 0)
-		WaitDelay = (30 * HZ) / 10;
+		WaitDelay = 3000;
 	else
-		WaitDelay = (DelayTime * HZ) / 10;
+		WaitDelay = DelayTime * 100;
 
 	/*
 	 * Assert reset
@@ -77,8 +78,7 @@
 	DeviceNode->ReturnCode = HvCallPci_setSlotReset(ISERIES_BUS(DeviceNode),
 			0x00, DeviceNode->AgentId, 1);
 	if (DeviceNode->ReturnCode == 0) {
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(AssertDelay);       /* Sleep for the time */
+		msleep(AssertDelay);			/* Sleep for the time */
 		DeviceNode->ReturnCode =
 			HvCallPci_setSlotReset(ISERIES_BUS(DeviceNode),
 					0x00, DeviceNode->AgentId, 0);
@@ -86,8 +86,7 @@
 		/*
    		 * Wait for device to reset
 		 */
-		set_current_state(TASK_UNINTERRUPTIBLE);  
-		schedule_timeout(WaitDelay);
+		msleep(WaitDelay);
 	}
 	if (DeviceNode->ReturnCode == 0)
 		PCIFR("Slot 0x%04X.%02 Reset\n", ISERIES_BUS(DeviceNode),
diff -Nru a/arch/ppc64/kernel/iSeries_proc.c b/arch/ppc64/kernel/iSeries_proc.c
--- a/arch/ppc64/kernel/iSeries_proc.c	2005-03-01 23:38:54 -08:00
+++ b/arch/ppc64/kernel/iSeries_proc.c	2005-03-01 23:38:54 -08:00
@@ -24,8 +24,7 @@
 #include <asm/paca.h>
 #include <asm/processor.h>
 #include <asm/time.h>
-#include <asm/naca.h>
-#include <asm/iSeries/ItLpPaca.h>
+#include <asm/lppaca.h>
 #include <asm/iSeries/ItLpQueue.h>
 #include <asm/iSeries/HvCallXm.h>
 #include <asm/iSeries/IoHriMainStore.h>
diff -Nru a/arch/ppc64/kernel/iSeries_setup.c b/arch/ppc64/kernel/iSeries_setup.c
--- a/arch/ppc64/kernel/iSeries_setup.c	2005-03-01 23:39:08 -08:00
+++ b/arch/ppc64/kernel/iSeries_setup.c	2005-03-01 23:39:08 -08:00
@@ -44,6 +44,7 @@
 #include "iSeries_setup.h"
 #include <asm/naca.h>
 #include <asm/paca.h>
+#include <asm/cache.h>
 #include <asm/sections.h>
 #include <asm/iSeries/LparData.h>
 #include <asm/iSeries/HvCallHpt.h>
@@ -67,7 +68,6 @@
 
 /* Function Prototypes */
 extern void ppcdbg_initialize(void);
-extern void tce_init_iSeries(void);
 
 static void build_iSeries_Memory_Map(void);
 static void setup_iSeries_cache_sizes(void);
@@ -313,13 +313,13 @@
 	 * If the init RAM disk has been configured and there is
 	 * a non-zero starting address for it, set it up
 	 */
-	if (naca->xRamDisk) {
-		initrd_start = (unsigned long)__va(naca->xRamDisk);
-		initrd_end = initrd_start + naca->xRamDiskSize * PAGE_SIZE;
+	if (naca.xRamDisk) {
+		initrd_start = (unsigned long)__va(naca.xRamDisk);
+		initrd_end = initrd_start + naca.xRamDiskSize * PAGE_SIZE;
 		initrd_below_start_ok = 1;	// ramdisk in kernel space
 		ROOT_DEV = Root_RAM0;
-		if (((rd_size * 1024) / PAGE_SIZE) < naca->xRamDiskSize)
-			rd_size = (naca->xRamDiskSize * PAGE_SIZE) / 1024;
+		if (((rd_size * 1024) / PAGE_SIZE) < naca.xRamDiskSize)
+			rd_size = (naca.xRamDiskSize * PAGE_SIZE) / 1024;
 	} else
 #endif /* CONFIG_BLK_DEV_INITRD */
 	{
@@ -343,7 +343,7 @@
 	/*
 	 * Initialize the DMA/TCE management
 	 */
-	tce_init_iSeries();
+	iommu_init_early_iSeries();
 
 	/*
 	 * Initialize the table which translate Linux physical addresses to
@@ -471,18 +471,16 @@
 	printk("HPT absolute addr = %016lx, size = %dK\n",
 			chunk_to_addr(hptFirstChunk), hptSizeChunks * 256);
 
-	/* Fill in the htab_data structure */
-	/* Fill in size of hashed page table */
+	/* Fill in the hashed page table hash mask */
 	num_ptegs = hptSizePages *
 		(PAGE_SIZE / (sizeof(HPTE) * HPTES_PER_GROUP));
-	htab_data.htab_num_ptegs = num_ptegs;
-	htab_data.htab_hash_mask = num_ptegs - 1;
+	htab_hash_mask = num_ptegs - 1;
 	
 	/*
 	 * The actual hashed page table is in the hypervisor,
 	 * we have no direct access
 	 */
-	htab_data.htab = NULL;
+	htab_address = NULL;
 
 	/*
 	 * Determine if absolute memory has any
@@ -558,35 +556,38 @@
 static void __init setup_iSeries_cache_sizes(void)
 {
 	unsigned int i, n;
-	unsigned int procIx = get_paca()->lppaca.xDynHvPhysicalProcIndex;
+	unsigned int procIx = get_paca()->lppaca.dyn_hv_phys_proc_index;
 
-	systemcfg->iCacheL1Size =
-		xIoHriProcessorVpd[procIx].xInstCacheSize * 1024;
-	systemcfg->iCacheL1LineSize =
+	systemcfg->icache_size =
+	ppc64_caches.isize = xIoHriProcessorVpd[procIx].xInstCacheSize * 1024;
+	systemcfg->icache_line_size =
+	ppc64_caches.iline_size =
 		xIoHriProcessorVpd[procIx].xInstCacheOperandSize;
-	systemcfg->dCacheL1Size =
+	systemcfg->dcache_size =
+	ppc64_caches.dsize =
 		xIoHriProcessorVpd[procIx].xDataL1CacheSizeKB * 1024;
-	systemcfg->dCacheL1LineSize =
+	systemcfg->dcache_line_size =
+	ppc64_caches.dline_size =
 		xIoHriProcessorVpd[procIx].xDataCacheOperandSize;
-	naca->iCacheL1LinesPerPage = PAGE_SIZE / systemcfg->iCacheL1LineSize;
-	naca->dCacheL1LinesPerPage = PAGE_SIZE / systemcfg->dCacheL1LineSize;
+	ppc64_caches.ilines_per_page = PAGE_SIZE / ppc64_caches.iline_size;
+	ppc64_caches.dlines_per_page = PAGE_SIZE / ppc64_caches.dline_size;
 
-	i = systemcfg->iCacheL1LineSize;
+	i = ppc64_caches.iline_size;
 	n = 0;
 	while ((i = (i / 2)))
 		++n;
-	naca->iCacheL1LogLineSize = n;
+	ppc64_caches.log_iline_size = n;
 
-	i = systemcfg->dCacheL1LineSize;
+	i = ppc64_caches.dline_size;
 	n = 0;
 	while ((i = (i / 2)))
 		++n;
-	naca->dCacheL1LogLineSize = n;
+	ppc64_caches.log_dline_size = n;
 
 	printk("D-cache line size = %d\n",
-			(unsigned int)systemcfg->dCacheL1LineSize);
+			(unsigned int)ppc64_caches.dline_size);
 	printk("I-cache line size = %d\n",
-			(unsigned int)systemcfg->iCacheL1LineSize);
+			(unsigned int)ppc64_caches.iline_size);
 }
 
 /*
@@ -652,7 +653,7 @@
 void __init iSeries_setup_arch(void)
 {
 	void *eventStack;
-	unsigned procIx = get_paca()->lppaca.xDynHvPhysicalProcIndex;
+	unsigned procIx = get_paca()->lppaca.dyn_hv_phys_proc_index;
 
 	/* Add an eye catcher and the systemcfg layout version number */
 	strcpy(systemcfg->eye_catcher, "SYSTEMCFG:PPC64");
@@ -809,9 +810,9 @@
 	 * Change klimit to take into account any ram disk
 	 * that may be included
 	 */
-	if (naca->xRamDisk)
-		klimit = KERNELBASE + (u64)naca->xRamDisk +
-			(naca->xRamDiskSize * PAGE_SIZE);
+	if (naca.xRamDisk)
+		klimit = KERNELBASE + (u64)naca.xRamDisk +
+			(naca.xRamDiskSize * PAGE_SIZE);
 	else {
 		/*
 		 * No ram disk was included - check and see if there
diff -Nru a/arch/ppc64/kernel/iSeries_smp.c b/arch/ppc64/kernel/iSeries_smp.c
--- a/arch/ppc64/kernel/iSeries_smp.c	2005-03-01 23:39:08 -08:00
+++ b/arch/ppc64/kernel/iSeries_smp.c	2005-03-01 23:39:08 -08:00
@@ -37,7 +37,6 @@
 #include <asm/pgtable.h>
 #include <asm/io.h>
 #include <asm/smp.h>
-#include <asm/naca.h>
 #include <asm/paca.h>
 #include <asm/iSeries/LparData.h>
 #include <asm/iSeries/HvCall.h>
@@ -91,7 +90,7 @@
 
 	np = 0;
         for (i=0; i < NR_CPUS; ++i) {
-                if (paca[i].lppaca.xDynProcStatus < 2) {
+                if (paca[i].lppaca.dyn_proc_status < 2) {
 			cpu_set(i, cpu_possible_map);
 			cpu_set(i, cpu_present_map);
 			cpu_set(i, cpu_sibling_map[i]);
@@ -107,7 +106,7 @@
 	unsigned np = 0;
 
 	for (i=0; i < NR_CPUS; ++i) {
-		if (paca[i].lppaca.xDynProcStatus < 2) {
+		if (paca[i].lppaca.dyn_proc_status < 2) {
 			/*paca[i].active = 1;*/
 			++np;
 		}
@@ -121,7 +120,7 @@
 	BUG_ON(nr < 0 || nr >= NR_CPUS);
 
 	/* Verify that our partition has a processor nr */
-	if (paca[nr].lppaca.xDynProcStatus >= 2)
+	if (paca[nr].lppaca.dyn_proc_status >= 2)
 		return;
 
 	/* The processor is currently spinning, waiting
diff -Nru a/arch/ppc64/kernel/idle.c b/arch/ppc64/kernel/idle.c
--- a/arch/ppc64/kernel/idle.c	2005-03-01 23:39:09 -08:00
+++ b/arch/ppc64/kernel/idle.c	2005-03-01 23:39:09 -08:00
@@ -32,6 +32,7 @@
 #include <asm/iSeries/HvCall.h>
 #include <asm/iSeries/ItLpQueue.h>
 #include <asm/plpar_wrappers.h>
+#include <asm/systemcfg.h>
 
 extern void power4_idle(void);
 
@@ -66,7 +67,7 @@
 	 * 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.xIntDword.xFields.xDecrInt = 1;
+	get_paca()->lppaca.int_dword.fields.decr_int = 1;
 	process_iSeries_events();
 }
 
@@ -85,7 +86,7 @@
 	lpaca = get_paca();
 
 	while (1) {
-		if (lpaca->lppaca.xSharedProc) {
+		if (lpaca->lppaca.shared_proc) {
 			if (ItLpQueue_isLpIntPending(lpaca->lpqueue_ptr))
 				process_iSeries_events();
 			if (!need_resched())
@@ -172,7 +173,7 @@
 		 * Indicate to the HV that we are idle. Now would be
 		 * a good time to find other work to dispatch.
 		 */
-		lpaca->lppaca.xIdle = 1;
+		lpaca->lppaca.idle = 1;
 
 		oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED);
 		if (!oldval) {
@@ -193,7 +194,7 @@
 
 				HMT_medium();
 
-				if (!(ppaca->lppaca.xIdle)) {
+				if (!(ppaca->lppaca.idle)) {
 					local_irq_disable();
 
 					/*
@@ -232,7 +233,7 @@
 		}
 
 		HMT_medium();
-		lpaca->lppaca.xIdle = 0;
+		lpaca->lppaca.idle = 0;
 		schedule();
 		if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING)
 			cpu_die();
@@ -250,7 +251,7 @@
 		 * Indicate to the HV that we are idle. Now would be
 		 * a good time to find other work to dispatch.
 		 */
-		lpaca->lppaca.xIdle = 1;
+		lpaca->lppaca.idle = 1;
 
 		while (!need_resched() && !cpu_is_offline(cpu)) {
 			local_irq_disable();
@@ -272,7 +273,7 @@
 		}
 
 		HMT_medium();
-		lpaca->lppaca.xIdle = 0;
+		lpaca->lppaca.idle = 0;
 		schedule();
 		if (cpu_is_offline(smp_processor_id()) &&
 		    system_state == SYSTEM_RUNNING)
@@ -298,10 +299,9 @@
 
 #endif /* CONFIG_PPC_ISERIES */
 
-int cpu_idle(void)
+void cpu_idle(void)
 {
 	idle_loop();
-	return 0;
 }
 
 int powersave_nap;
@@ -351,7 +351,7 @@
 #ifdef CONFIG_PPC_PSERIES
 	if (systemcfg->platform & PLATFORM_PSERIES) {
 		if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR) {
-			if (get_paca()->lppaca.xSharedProc) {
+			if (get_paca()->lppaca.shared_proc) {
 				printk(KERN_INFO "Using shared processor idle loop\n");
 				idle_loop = shared_idle;
 			} else {
diff -Nru a/arch/ppc64/kernel/iomap.c b/arch/ppc64/kernel/iomap.c
--- a/arch/ppc64/kernel/iomap.c	2005-03-01 23:38:56 -08:00
+++ b/arch/ppc64/kernel/iomap.c	2005-03-01 23:38:56 -08:00
@@ -113,7 +113,7 @@
 	if (flags & IORESOURCE_IO)
 		return ioport_map(start, len);
 	if (flags & IORESOURCE_MEM)
-		return (void __iomem *) start;
+		return ioremap(start, len);
 	/* What? */
 	return NULL;
 }
diff -Nru a/arch/ppc64/kernel/iommu.c b/arch/ppc64/kernel/iommu.c
--- a/arch/ppc64/kernel/iommu.c	2005-03-01 23:38:44 -08:00
+++ b/arch/ppc64/kernel/iommu.c	2005-03-01 23:38:44 -08:00
@@ -87,7 +87,7 @@
 		start = largealloc ? tbl->it_largehint : tbl->it_hint;
 
 	/* Use only half of the table for small allocs (15 pages or less) */
-	limit = largealloc ? tbl->it_mapsize : tbl->it_halfpoint;
+	limit = largealloc ? tbl->it_size : tbl->it_halfpoint;
 
 	if (largealloc && start < tbl->it_halfpoint)
 		start = tbl->it_halfpoint;
@@ -114,7 +114,7 @@
 			 * Second failure, rescan the other half of the table.
 			 */
 			start = (largealloc ^ pass) ? tbl->it_halfpoint : 0;
-			limit = pass ? tbl->it_mapsize : limit;
+			limit = pass ? tbl->it_size : limit;
 			pass++;
 			goto again;
 		} else {
@@ -194,7 +194,7 @@
 	entry = dma_addr >> PAGE_SHIFT;
 	free_entry = entry - tbl->it_offset;
 
-	if (((free_entry + npages) > tbl->it_mapsize) ||
+	if (((free_entry + npages) > tbl->it_size) ||
 	    (entry < tbl->it_offset)) {
 		if (printk_ratelimit()) {
 			printk(KERN_INFO "iommu_free: invalid entry\n");
@@ -202,7 +202,7 @@
 			printk(KERN_INFO "\tdma_addr  = 0x%lx\n", (u64)dma_addr);
 			printk(KERN_INFO "\tTable     = 0x%lx\n", (u64)tbl);
 			printk(KERN_INFO "\tbus#      = 0x%lx\n", (u64)tbl->it_busno);
-			printk(KERN_INFO "\tmapsize   = 0x%lx\n", (u64)tbl->it_mapsize);
+			printk(KERN_INFO "\tsize      = 0x%lx\n", (u64)tbl->it_size);
 			printk(KERN_INFO "\tstartOff  = 0x%lx\n", (u64)tbl->it_offset);
 			printk(KERN_INFO "\tindex     = 0x%lx\n", (u64)tbl->it_index);
 			WARN_ON(1);
@@ -407,14 +407,11 @@
 	unsigned long sz;
 	static int welcomed = 0;
 
-	/* it_size is in pages, it_mapsize in number of entries */
-	tbl->it_mapsize = (tbl->it_size << PAGE_SHIFT) / tbl->it_entrysize;
-
 	/* Set aside 1/4 of the table for large allocations. */
-	tbl->it_halfpoint = tbl->it_mapsize * 3 / 4;
+	tbl->it_halfpoint = tbl->it_size * 3 / 4;
 
 	/* number of bytes needed for the bitmap */
-	sz = (tbl->it_mapsize + 7) >> 3;
+	sz = (tbl->it_size + 7) >> 3;
 
 	tbl->it_map = (unsigned long *)__get_free_pages(GFP_ATOMIC, get_order(sz));
 	if (!tbl->it_map)
@@ -448,8 +445,8 @@
 	}
 
 	/* verify that table contains no entries */
-	/* it_mapsize is in entries, and we're examining 64 at a time */
-	for (i = 0; i < (tbl->it_mapsize/64); i++) {
+	/* it_size is in entries, and we're examining 64 at a time */
+	for (i = 0; i < (tbl->it_size/64); i++) {
 		if (tbl->it_map[i] != 0) {
 			printk(KERN_WARNING "%s: Unexpected TCEs for %s\n",
 				__FUNCTION__, dn->full_name);
@@ -458,7 +455,7 @@
 	}
 
 	/* calculate bitmap size in bytes */
-	bitmap_sz = (tbl->it_mapsize + 7) / 8;
+	bitmap_sz = (tbl->it_size + 7) / 8;
 
 	/* free bitmap */
 	order = get_order(bitmap_sz);
diff -Nru a/arch/ppc64/kernel/irq.c b/arch/ppc64/kernel/irq.c
--- a/arch/ppc64/kernel/irq.c	2005-03-01 23:38:56 -08:00
+++ b/arch/ppc64/kernel/irq.c	2005-03-01 23:38:56 -08:00
@@ -62,9 +62,11 @@
 
 extern irq_desc_t irq_desc[NR_IRQS];
 
+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)
 {
@@ -258,8 +260,8 @@
 
 	lpaca = get_paca();
 #ifdef CONFIG_SMP
-	if (lpaca->lppaca.xIntDword.xFields.xIpiCnt) {
-		lpaca->lppaca.xIntDword.xFields.xIpiCnt = 0;
+	if (lpaca->lppaca.int_dword.fields.ipi_cnt) {
+		lpaca->lppaca.int_dword.fields.ipi_cnt = 0;
 		iSeries_smp_message_recv(regs);
 	}
 #endif /* CONFIG_SMP */
@@ -269,8 +271,8 @@
 
 	irq_exit();
 
-	if (lpaca->lppaca.xIntDword.xFields.xDecrInt) {
-		lpaca->lppaca.xIntDword.xFields.xDecrInt = 0;
+	if (lpaca->lppaca.int_dword.fields.decr_int) {
+		lpaca->lppaca.int_dword.fields.decr_int = 0;
 		/* Signal a fake decrementer interrupt */
 		timer_interrupt(regs);
 	}
@@ -360,7 +362,7 @@
 	unsigned int virq, first_virq;
 	static int warned;
 
-	if (naca->interrupt_controller == IC_OPEN_PIC)
+	if (ppc64_interrupt_controller == IC_OPEN_PIC)
 		return real_irq;	/* no mapping for openpic (for now) */
 
 	/* don't map interrupts < MIN_VIRT_IRQ */
@@ -478,3 +480,10 @@
 
 #endif /* CONFIG_IRQSTACKS */
 
+static int __init setup_noirqdistrib(char *str)
+{
+	distribute_irqs = 0;
+	return 1;
+}
+
+__setup("noirqdistrib", setup_noirqdistrib);
diff -Nru a/arch/ppc64/kernel/kprobes.c b/arch/ppc64/kernel/kprobes.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/ppc64/kernel/kprobes.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,266 @@
+/*
+ *  Kernel Probes (KProbes)
+ *  arch/ppc64/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
+ *
+ * 2002-Oct	Created by Vamsi Krishna S <vamsi_krishna@in.ibm.com> Kernel
+ *		Probes initial implementation ( includes contributions from
+ *		Rusty Russell).
+ * 2004-July	Suparna Bhattacharya <suparna@in.ibm.com> added jumper probes
+ *		interface to access function arguments.
+ * 2004-Nov	Ananth N Mavinakayanahalli <ananth@in.ibm.com> kprobes port
+ *		for PPC64
+ */
+
+#include <linux/config.h>
+#include <linux/kprobes.h>
+#include <linux/ptrace.h>
+#include <linux/spinlock.h>
+#include <linux/preempt.h>
+#include <asm/kdebug.h>
+#include <asm/sstep.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_saved_msr;
+static struct pt_regs jprobe_saved_regs;
+
+int arch_prepare_kprobe(struct kprobe *p)
+{
+	kprobe_opcode_t insn = *p->addr;
+
+	if (IS_MTMSRD(insn) || IS_RFID(insn))
+		/* cannot put bp on RFID/MTMSRD */
+		return 1;
+	return 0;
+}
+
+void arch_copy_kprobe(struct kprobe *p)
+{
+	memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
+}
+
+void arch_remove_kprobe(struct kprobe *p)
+{
+}
+
+static inline void disarm_kprobe(struct kprobe *p, struct pt_regs *regs)
+{
+	*p->addr = p->opcode;
+	regs->nip = (unsigned long)p->addr;
+}
+
+static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
+{
+	regs->msr |= MSR_SE;
+	regs->nip = (unsigned long)&p->ainsn.insn;
+}
+
+static inline int kprobe_handler(struct pt_regs *regs)
+{
+	struct kprobe *p;
+	int ret = 0;
+	unsigned int *addr = (unsigned int *)regs->nip;
+
+	/* We're in an interrupt, but this is clear and BUG()-safe. */
+	preempt_disable();
+
+	/* Check we're not actually recursing */
+	if (kprobe_running()) {
+		/* We *are* holding lock here, so this is safe.
+		   Disarm the probe we just hit, and ignore it. */
+		p = get_kprobe(addr);
+		if (p) {
+			disarm_kprobe(p, regs);
+			ret = 1;
+		} else {
+			p = current_kprobe;
+			if (p->break_handler && p->break_handler(p, regs)) {
+				goto ss_probe;
+			}
+		}
+		/* If it's not ours, can't be delete race, (we hold lock). */
+		goto no_kprobe;
+	}
+
+	lock_kprobes();
+	p = get_kprobe(addr);
+	if (!p) {
+		unlock_kprobes();
+#if 0
+		if (*addr != BREAKPOINT_INSTRUCTION) {
+			/*
+			 * The breakpoint instruction was removed right
+			 * after we hit it.  Another cpu has removed
+			 * either a probepoint or a debugger breakpoint
+			 * at this address.  In either case, no further
+			 * handling of this interrupt is appropriate.
+			 */
+			ret = 1;
+		}
+#endif
+		/* Not one of ours: let kernel handle it */
+		goto no_kprobe;
+	}
+
+	kprobe_status = KPROBE_HIT_ACTIVE;
+	current_kprobe = p;
+	kprobe_saved_msr = regs->msr;
+	if (p->pre_handler(p, regs)) {
+		/* handler has already set things up, so skip ss setup */
+		return 1;
+	}
+
+ss_probe:
+	prepare_singlestep(p, regs);
+	kprobe_status = KPROBE_HIT_SS;
+	return 1;
+
+no_kprobe:
+	preempt_enable_no_resched();
+	return ret;
+}
+
+/*
+ * 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
+ * temporarily put back the original opcode to single-step, we
+ * single-stepped a copy of the instruction.  The address of this
+ * copy is p->ainsn.insn.
+ */
+static void resume_execution(struct kprobe *p, struct pt_regs *regs)
+{
+	int ret;
+
+	regs->nip = (unsigned long)p->addr;
+	ret = emulate_step(regs, p->ainsn.insn[0]);
+	if (ret == 0)
+		regs->nip = (unsigned long)p->addr + 4;
+
+	regs->msr &= ~MSR_SE;
+}
+
+static inline int post_kprobe_handler(struct pt_regs *regs)
+{
+	if (!kprobe_running())
+		return 0;
+
+	if (current_kprobe->post_handler)
+		current_kprobe->post_handler(current_kprobe, regs, 0);
+
+	resume_execution(current_kprobe, regs);
+	regs->msr |= kprobe_saved_msr;
+
+	unlock_kprobes();
+	preempt_enable_no_resched();
+
+	/*
+	 * if somebody else is singlestepping across a probe point, msr
+	 * will have SE set, in which case, continue the remaining processing
+	 * of do_debug, as if this is not a probe hit.
+	 */
+	if (regs->msr & MSR_SE)
+		return 0;
+
+	return 1;
+}
+
+/* Interrupts disabled, kprobe_lock held. */
+static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr)
+{
+	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);
+		regs->msr |= kprobe_saved_msr;
+
+		unlock_kprobes();
+		preempt_enable_no_resched();
+	}
+	return 0;
+}
+
+/*
+ * Wrapper routine to for handling exceptions.
+ */
+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_IABR_MATCH:
+	case DIE_DABR_MATCH:
+	case DIE_BPT:
+		if (kprobe_handler(args->regs))
+			return NOTIFY_STOP;
+		break;
+	case DIE_SSTEP:
+		if (post_kprobe_handler(args->regs))
+			return NOTIFY_STOP;
+		break;
+	case DIE_GPF:
+	case DIE_PAGE_FAULT:
+		if (kprobe_running() &&
+		    kprobe_fault_handler(args->regs, args->trapnr))
+			return NOTIFY_STOP;
+		break;
+	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);
+
+	memcpy(&jprobe_saved_regs, regs, sizeof(struct pt_regs));
+
+	/* setup return addr to the jprobe handler routine */
+	regs->nip = (unsigned long)(((func_descr_t *)jp->entry)->entry);
+	regs->gpr[2] = (unsigned long)(((func_descr_t *)jp->entry)->toc);
+
+	return 1;
+}
+
+void jprobe_return(void)
+{
+	preempt_enable_no_resched();
+	asm volatile("trap" ::: "memory");
+}
+
+void jprobe_return_end(void)
+{
+};
+
+int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
+{
+	/*
+	 * FIXME - we should ideally be validating that we got here 'cos
+	 * of the "trap" in jprobe_return() above, before restoring the
+	 * saved regs...
+	 */
+	memcpy(regs, &jprobe_saved_regs, sizeof(struct pt_regs));
+	return 1;
+}
diff -Nru a/arch/ppc64/kernel/lparcfg.c b/arch/ppc64/kernel/lparcfg.c
--- a/arch/ppc64/kernel/lparcfg.c	2005-03-01 23:38:52 -08:00
+++ b/arch/ppc64/kernel/lparcfg.c	2005-03-01 23:38:52 -08:00
@@ -27,7 +27,7 @@
 #include <linux/seq_file.h>
 #include <asm/uaccess.h>
 #include <asm/iSeries/HvLpConfig.h>
-#include <asm/iSeries/ItLpPaca.h>
+#include <asm/lppaca.h>
 #include <asm/iSeries/LparData.h>
 #include <asm/hvcall.h>
 #include <asm/cputable.h>
@@ -72,7 +72,7 @@
 
 /*
  * For iSeries legacy systems, the PPA purr function is available from the
- * xEmulatedTimeBase field in the paca.
+ * emulated_time_base field in the paca.
  */
 static unsigned long get_purr(void)
 {
@@ -82,11 +82,11 @@
 
 	for_each_cpu(cpu) {
 		lpaca = paca + cpu;
-		sum_purr += lpaca->lppaca.xEmulatedTimeBase;
+		sum_purr += lpaca->lppaca.emulated_time_base;
 
 #ifdef PURR_DEBUG
 		printk(KERN_INFO "get_purr for cpu (%d) has value (%ld) \n",
-			cpu, lpaca->lppaca.xEmulatedTimeBase);
+			cpu, lpaca->lppaca.emulated_time_base);
 #endif
 	}
 	return sum_purr;
@@ -107,7 +107,7 @@
 
 	seq_printf(m, "%s %s \n", MODULE_NAME, MODULE_VERS);
 
-	shared = (int)(lpaca->lppaca_ptr->xSharedProc);
+	shared = (int)(lpaca->lppaca_ptr->shared_proc);
 	seq_printf(m, "serial_number=%c%c%c%c%c%c%c\n",
 		   e2a(xItExtVpdPanel.mfgID[2]),
 		   e2a(xItExtVpdPanel.mfgID[3]),
@@ -395,7 +395,7 @@
 			   (h_resource >> 0 * 8) & 0xffff);
 
 		/* pool related entries are apropriate for shared configs */
-		if (paca[0].lppaca.xSharedProc) {
+		if (paca[0].lppaca.shared_proc) {
 
 			h_pic(&pool_idle_time, &pool_procs);
 
@@ -444,7 +444,7 @@
 	seq_printf(m, "partition_potential_processors=%d\n",
 		   partition_potential_processors);
 
-	seq_printf(m, "shared_processor_mode=%d\n", paca[0].lppaca.xSharedProc);
+	seq_printf(m, "shared_processor_mode=%d\n", paca[0].lppaca.shared_proc);
 
 	return 0;
 }
diff -Nru a/arch/ppc64/kernel/maple_pci.c b/arch/ppc64/kernel/maple_pci.c
--- a/arch/ppc64/kernel/maple_pci.c	2005-03-01 23:39:16 -08:00
+++ b/arch/ppc64/kernel/maple_pci.c	2005-03-01 23:39:16 -08:00
@@ -382,12 +382,6 @@
 	/* Do the mapping of the IO space */
 	phbs_remap_io();
 
-	/* Fixup the pci_bus sysdata pointers */
-	pci_fix_bus_sysdata();
-
-	/* Setup the iommu */
-	iommu_setup_u3();
-
 	DBG(" <- maple_pcibios_fixup\n");
 }
 
diff -Nru a/arch/ppc64/kernel/maple_setup.c b/arch/ppc64/kernel/maple_setup.c
--- a/arch/ppc64/kernel/maple_setup.c	2005-03-01 23:38:53 -08:00
+++ b/arch/ppc64/kernel/maple_setup.c	2005-03-01 23:38:53 -08:00
@@ -75,7 +75,8 @@
 extern void maple_pci_init(void);
 extern void maple_pcibios_fixup(void);
 extern int maple_pci_get_legacy_ide_irq(struct pci_dev *dev, int channel);
-extern void generic_find_legacy_serial_ports(unsigned int *default_speed);
+extern void generic_find_legacy_serial_ports(u64 *physport,
+		unsigned int *default_speed);
 
 
 static void maple_restart(char *cmd)
@@ -110,11 +111,6 @@
 #ifdef CONFIG_SMP
 	smp_ops = &maple_smp_ops;
 #endif
-	/* Setup the PCI DMA to "direct" by default. May be overriden
-	 * by iommu later on
-	 */
-	pci_dma_init_direct();
-
 	/* Lookup PCI hosts */
        	maple_pci_init();
 
@@ -129,6 +125,7 @@
 static void __init maple_init_early(void)
 {
 	unsigned int default_speed;
+	u64 physport;
 
 	DBG(" -> maple_init_early\n");
 
@@ -138,14 +135,14 @@
 	hpte_init_native();
 
 	/* Find the serial port */
-       	generic_find_legacy_serial_ports(&default_speed);
+	generic_find_legacy_serial_ports(&physport, &default_speed);
 
-	DBG("naca->serialPortAddr: %lx\n", (long)naca->serialPortAddr);
+	DBG("phys port addr: %lx\n", (long)physport);
 
-	if (naca->serialPortAddr) {
+	if (physport) {
 		void *comport;
 		/* Map the uart for udbg. */
-		comport = (void *)__ioremap(naca->serialPortAddr, 16, _PAGE_NO_CACHE);
+		comport = (void *)__ioremap(physport, 16, _PAGE_NO_CACHE);
 		udbg_init_uart(comport, default_speed);
 
 		ppc_md.udbg_putc = udbg_putc;
@@ -155,7 +152,9 @@
 	}
 
 	/* Setup interrupt mapping options */
-	naca->interrupt_controller = IC_OPEN_PIC;
+	ppc64_interrupt_controller = IC_OPEN_PIC;
+
+	iommu_init_early_u3();
 
 	DBG(" <- maple_init_early\n");
 }
diff -Nru a/arch/ppc64/kernel/misc.S b/arch/ppc64/kernel/misc.S
--- a/arch/ppc64/kernel/misc.S	2005-03-01 23:39:09 -08:00
+++ b/arch/ppc64/kernel/misc.S	2005-03-01 23:39:09 -08:00
@@ -167,27 +167,12 @@
 	xori	r0,r0,MSR_IR|MSR_DR
 	mtspr	SPRN_SRR1,r0
 	rfid
-	
-/*
- * Flush instruction cache.
- */
-_GLOBAL(flush_instruction_cache)
 
-/*
- * This is called by kgdb code
- * and should probably go away
- * to be replaced by invalidating
- * the cache lines that are actually
- * modified
- */
-	/* use invalidate-all bit in HID0
-	 *  - is this consistent across all 64-bit cpus?  -- paulus */
-	mfspr	r3,HID0
-	ori	r3,r3,HID0_ICFI
-	mtspr	HID0,r3
-	sync
-	isync
-	blr
+
+	.section	".toc","aw"
+PPC64_CACHES:
+	.tc		ppc64_caches[TC],ppc64_caches
+	.section	".text"
 
 /*
  * Write any modified data cache blocks out to memory
@@ -207,11 +192,8 @@
  * and in some cases i-cache and d-cache line sizes differ from
  * each other.
  */
-	LOADADDR(r10,naca)		/* Get Naca address */
-	ld	r10,0(r10)
-	LOADADDR(r11,systemcfg)		/* Get systemcfg address */
-	ld	r11,0(r11)
-	lwz	r7,DCACHEL1LINESIZE(r11)/* Get cache line size */
+ 	ld	r10,PPC64_CACHES@toc(r2)
+	lwz	r7,DCACHEL1LINESIZE(r10)/* Get cache line size */
 	addi	r5,r7,-1
 	andc	r6,r3,r5		/* round low to line bdy */
 	subf	r8,r6,r4		/* compute length */
@@ -227,7 +209,7 @@
 
 /* Now invalidate the instruction cache */
 	
-	lwz	r7,ICACHEL1LINESIZE(r11)	/* Get Icache line size */
+	lwz	r7,ICACHEL1LINESIZE(r10)	/* Get Icache line size */
 	addi	r5,r7,-1
 	andc	r6,r3,r5		/* round low to line bdy */
 	subf	r8,r6,r4		/* compute length */
@@ -256,11 +238,8 @@
  * 
  * Different systems have different cache line sizes
  */
-	LOADADDR(r10,naca)		/* Get Naca address */
-	ld	r10,0(r10)
-	LOADADDR(r11,systemcfg)		/* Get systemcfg address */
-	ld	r11,0(r11)
-	lwz	r7,DCACHEL1LINESIZE(r11)	/* Get dcache line size */
+ 	ld	r10,PPC64_CACHES@toc(r2)
+	lwz	r7,DCACHEL1LINESIZE(r10)	/* Get dcache line size */
 	addi	r5,r7,-1
 	andc	r6,r3,r5		/* round low to line bdy */
 	subf	r8,r6,r4		/* compute length */
@@ -286,11 +265,8 @@
  *    flush all bytes from start to stop-1 inclusive
  */
 _GLOBAL(flush_dcache_phys_range)
-	LOADADDR(r10,naca)		/* Get Naca address */
-	ld	r10,0(r10)
-	LOADADDR(r11,systemcfg)		/* Get systemcfg address */
-	ld	r11,0(r11)
-	lwz	r7,DCACHEL1LINESIZE(r11)	/* Get dcache line size */
+ 	ld	r10,PPC64_CACHES@toc(r2)
+	lwz	r7,DCACHEL1LINESIZE(r10)	/* Get dcache line size */
 	addi	r5,r7,-1
 	andc	r6,r3,r5		/* round low to line bdy */
 	subf	r8,r6,r4		/* compute length */
@@ -332,13 +308,10 @@
  */
 
 /* Flush the dcache */
-	LOADADDR(r7,naca)
-	ld	r7,0(r7)
-	LOADADDR(r8,systemcfg)			/* Get systemcfg address */
-	ld	r8,0(r8)
+ 	ld	r7,PPC64_CACHES@toc(r2)
 	clrrdi	r3,r3,12           	    /* Page align */
 	lwz	r4,DCACHEL1LINESPERPAGE(r7)	/* Get # dcache lines per page */
-	lwz	r5,DCACHEL1LINESIZE(r8)		/* Get dcache line size */
+	lwz	r5,DCACHEL1LINESIZE(r7)		/* Get dcache line size */
 	mr	r6,r3
 	mtctr	r4
 0:	dcbst	0,r6
@@ -349,7 +322,7 @@
 /* Now invalidate the icache */	
 
 	lwz	r4,ICACHEL1LINESPERPAGE(r7)	/* Get # icache lines per page */
-	lwz	r5,ICACHEL1LINESIZE(r8)		/* Get icache line size */
+	lwz	r5,ICACHEL1LINESIZE(r7)		/* Get icache line size */
 	mtctr	r4
 1:	icbi	0,r3
 	add	r3,r3,r5
@@ -707,7 +680,7 @@
 	.llong .sys_unlink      	/* 10 */
 	.llong .sys32_execve
 	.llong .sys_chdir
-	.llong .sys32_time
+	.llong .compat_sys_time
 	.llong .sys_mknod
 	.llong .sys_chmod		/* 15 */
 	.llong .sys_lchown
@@ -719,7 +692,7 @@
 	.llong .sys_oldumount
 	.llong .sys_setuid
 	.llong .sys_getuid
-	.llong .ppc64_sys32_stime       /* 25 */
+	.llong .compat_sys_stime	/* 25 */
 	.llong .sys32_ptrace
 	.llong .sys_alarm
 	.llong .sys_ni_syscall		/* old fstat syscall */
@@ -870,7 +843,7 @@
 	.llong .sys32_rt_sigaction
 	.llong .sys32_rt_sigprocmask
 	.llong .sys32_rt_sigpending     /* 175 */
-	.llong .sys32_rt_sigtimedwait
+	.llong .compat_sys_rt_sigtimedwait
 	.llong .sys32_rt_sigqueueinfo
 	.llong .ppc32_rt_sigsuspend
 	.llong .sys32_pread64
@@ -994,7 +967,7 @@
 	.llong .sys_ni_syscall		/* old umount syscall */
 	.llong .sys_setuid
 	.llong .sys_getuid
-	.llong .ppc64_sys_stime		/* 25 */
+	.llong .sys_stime		/* 25 */
 	.llong .sys_ptrace
 	.llong .sys_alarm
 	.llong .sys_ni_syscall		/* old fstat syscall */
diff -Nru a/arch/ppc64/kernel/mpic.c b/arch/ppc64/kernel/mpic.c
--- a/arch/ppc64/kernel/mpic.c	2005-03-01 23:39:17 -08:00
+++ b/arch/ppc64/kernel/mpic.c	2005-03-01 23:39:17 -08:00
@@ -42,7 +42,7 @@
 
 static struct mpic *mpics;
 static struct mpic *mpic_primary;
-static spinlock_t mpic_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(mpic_lock);
 
 
 /*
@@ -765,10 +765,8 @@
 #ifdef CONFIG_SMP
 	struct mpic *mpic = mpic_primary;
 	unsigned long flags;
-#ifdef CONFIG_IRQ_ALL_CPUS
 	u32 msk = 1 << hard_smp_processor_id();
 	unsigned int i;
-#endif
 
 	BUG_ON(mpic == NULL);
 
@@ -776,16 +774,16 @@
 
 	spin_lock_irqsave(&mpic_lock, flags);
 
-#ifdef CONFIG_IRQ_ALL_CPUS
  	/* let the mpic know we want intrs. default affinity is 0xffffffff
 	 * until changed via /proc. That's how it's done on x86. If we want
 	 * it differently, then we should make sure we also change the default
 	 * values of irq_affinity in irq.c.
  	 */
- 	for (i = 0; i < mpic->num_sources ; i++)
-		mpic_irq_write(i, MPIC_IRQ_DESTINATION,
-			mpic_irq_read(i, MPIC_IRQ_DESTINATION) | msk);
-#endif /* CONFIG_IRQ_ALL_CPUS */
+	if (distribute_irqs) {
+	 	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 0 */
 	mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0);
diff -Nru a/arch/ppc64/kernel/nvram.c b/arch/ppc64/kernel/nvram.c
--- a/arch/ppc64/kernel/nvram.c	2005-03-01 23:38:51 -08:00
+++ b/arch/ppc64/kernel/nvram.c	2005-03-01 23:38:51 -08:00
@@ -31,6 +31,7 @@
 #include <asm/rtas.h>
 #include <asm/prom.h>
 #include <asm/machdep.h>
+#include <asm/systemcfg.h>
 
 #undef DEBUG_NVRAM
 
diff -Nru a/arch/ppc64/kernel/pSeries_iommu.c b/arch/ppc64/kernel/pSeries_iommu.c
--- a/arch/ppc64/kernel/pSeries_iommu.c	2005-03-01 23:38:53 -08:00
+++ b/arch/ppc64/kernel/pSeries_iommu.c	2005-03-01 23:38:53 -08:00
@@ -43,8 +43,12 @@
 #include <asm/machdep.h>
 #include <asm/abs_addr.h>
 #include <asm/plpar_wrappers.h>
+#include <asm/systemcfg.h>
 #include "pci.h"
 
+#define DBG(fmt...)
+
+extern int is_python(struct device_node *);
 
 static void tce_build_pSeries(struct iommu_table *tbl, long index, 
 			      long npages, unsigned long uaddr, 
@@ -120,7 +124,7 @@
 	}
 }
 
-DEFINE_PER_CPU(void *, tce_page) = NULL;
+static DEFINE_PER_CPU(void *, tce_page) = NULL;
 
 static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
 				     long npages, unsigned long uaddr,
@@ -232,85 +236,6 @@
 	}
 }
 
-
-static void iommu_buses_init(void)
-{
-	struct pci_controller *phb, *tmp;
-	struct device_node *dn, *first_dn;
-	int num_slots, num_slots_ilog2;
-	int first_phb = 1;
-	unsigned long tcetable_ilog2;
-
-	/*
-	 * We default to a TCE table that maps 2GB (4MB table, 22 bits),
-	 * however some machines have a 3GB IO hole and for these we
-	 * create a table that maps 1GB (2MB table, 21 bits)
-	 */
-	if (io_hole_start < 0x80000000UL)
-		tcetable_ilog2 = 21;
-	else
-		tcetable_ilog2 = 22;
-
-	/* XXX Should we be using pci_root_buses instead?  -ojn
-	 */
-
-	list_for_each_entry_safe(phb, tmp, &hose_list, list_node) {
-		first_dn = ((struct device_node *)phb->arch_data)->child;
-
-		/* Carve 2GB into the largest dma_window_size possible */
-		for (dn = first_dn, num_slots = 0; dn != NULL; dn = dn->sibling)
-			num_slots++;
-		num_slots_ilog2 = __ilog2(num_slots);
-
-		if ((1<<num_slots_ilog2) != num_slots)
-			num_slots_ilog2++;
-
-		phb->dma_window_size = 1 << (tcetable_ilog2 - num_slots_ilog2);
-
-		/* Reserve 16MB of DMA space on the first PHB.
-		 * We should probably be more careful and use firmware props.
-		 * In reality this space is remapped, not lost.  But we don't
-		 * want to get that smart to handle it -- too much work.
-		 */
-		phb->dma_window_base_cur = first_phb ? (1 << 12) : 0;
-		first_phb = 0;
-
-		for (dn = first_dn; dn != NULL; dn = dn->sibling)
-			iommu_devnode_init_pSeries(dn);
-	}
-}
-
-
-static void iommu_buses_init_lpar(struct list_head *bus_list)
-{
-	struct list_head *ln;
-	struct pci_bus *bus;
-	struct device_node *busdn;
-	unsigned int *dma_window;
-
-	for (ln=bus_list->next; ln != bus_list; ln=ln->next) {
-		bus = pci_bus_b(ln);
-
-		if (bus->self)
-			busdn = pci_device_to_OF_node(bus->self);
-		else
-			busdn = bus->sysdata;   /* must be a phb */
-
-		dma_window = (unsigned int *)get_property(busdn, "ibm,dma-window", NULL);
-		if (dma_window) {
-			/* Bussubno hasn't been copied yet.
-			 * Do it now because iommu_table_setparms_lpar needs it.
-			 */
-			busdn->bussubno = bus->number;
-			iommu_devnode_init_pSeries(busdn);
-		}
-
-		/* look for a window on a bridge even if the PHB had one */
-		iommu_buses_init_lpar(&bus->children);
-	}
-}
-
-
 static void iommu_table_setparms(struct pci_controller *phb,
 				 struct device_node *dn,
 				 struct iommu_table *tbl) 
@@ -335,27 +260,18 @@
 	tbl->it_busno = phb->bus->number;
 	
 	/* Units of tce entries */
-	tbl->it_offset = phb->dma_window_base_cur;
-	
-	/* Adjust the current table offset to the next
-	 * region.  Measured in TCE entries. Force an
-	 * alignment to the size allotted per IOA. This
-	 * makes it easier to remove the 1st 16MB.
-      	 */
-	phb->dma_window_base_cur += (phb->dma_window_size>>3);
-	phb->dma_window_base_cur &= 
-		~((phb->dma_window_size>>3)-1);
-	
-	/* Set the tce table size - measured in pages */
-	tbl->it_size = ((phb->dma_window_base_cur -
-			 tbl->it_offset) << 3) >> PAGE_SHIFT;
+	tbl->it_offset = phb->dma_window_base_cur >> PAGE_SHIFT;
 	
 	/* Test if we are going over 2GB of DMA space */
-	if (phb->dma_window_base_cur > (1 << 19))
+	if (phb->dma_window_base_cur + phb->dma_window_size > (1L << 31))
 		panic("PCI_DMA: Unexpected number of IOAs under this PHB.\n"); 
 	
+	phb->dma_window_base_cur += phb->dma_window_size;
+
+	/* Set the tce table size - measured in entries */
+	tbl->it_size = phb->dma_window_size >> PAGE_SHIFT;
+
 	tbl->it_index = 0;
-	tbl->it_entrysize = sizeof(union tce_entry);
 	tbl->it_blocksize = 16;
 	tbl->it_type = TCE_PCI;
 }
@@ -374,81 +290,202 @@
  */
 static void iommu_table_setparms_lpar(struct pci_controller *phb,
 				      struct device_node *dn,
-				      struct iommu_table *tbl)
+				      struct iommu_table *tbl,
+				      unsigned int *dma_window)
 {
-	unsigned int *dma_window;
-
-	dma_window = (unsigned int *)get_property(dn, "ibm,dma-window", NULL);
-
-	if (!dma_window)
-		panic("iommu_table_setparms_lpar: device %s has no"
-		      " ibm,dma-window property!\n", dn->full_name);
-
 	tbl->it_busno  = dn->bussubno;
-	tbl->it_size   = (((((unsigned long)dma_window[4] << 32) | 
-			   (unsigned long)dma_window[5]) >> PAGE_SHIFT) << 3) >> PAGE_SHIFT;
-	tbl->it_offset = ((((unsigned long)dma_window[2] << 32) | 
-			   (unsigned long)dma_window[3]) >> 12);
+
+	/* TODO: Parse field size properties properly. */
+	tbl->it_size   = (((unsigned long)dma_window[4] << 32) |
+			   (unsigned long)dma_window[5]) >> PAGE_SHIFT;
+	tbl->it_offset = (((unsigned long)dma_window[2] << 32) |
+			   (unsigned long)dma_window[3]) >> PAGE_SHIFT;
 	tbl->it_base   = 0;
 	tbl->it_index  = dma_window[0];
-	tbl->it_entrysize = sizeof(union tce_entry);
 	tbl->it_blocksize  = 16;
 	tbl->it_type = TCE_PCI;
 }
 
+static void iommu_bus_setup_pSeries(struct pci_bus *bus)
+{
+	struct device_node *dn, *pdn;
+	struct iommu_table *tbl;
+
+	DBG("iommu_bus_setup_pSeries, bus %p, bus->self %p\n", bus, bus->self);
+
+	/* For each (root) bus, we carve up the available DMA space in 256MB
+	 * pieces. Since each piece is used by one (sub) bus/device, that would
+	 * give a maximum of 7 devices per PHB. In most cases, this is plenty.
+	 *
+	 * The exception is on Python PHBs (pre-POWER4). Here we don't have EADS
+	 * bridges below the PHB to allocate the sectioned tables to, so instead
+	 * we allocate a 1GB table at the PHB level.
+	 */
+
+	dn = pci_bus_to_OF_node(bus);
+
+	if (!bus->self) {
+		/* Root bus */
+		if (is_python(dn)) {
+			unsigned int *iohole;
+
+			DBG("Python root bus %s\n", bus->name);
+
+			iohole = (unsigned int *)get_property(dn, "io-hole", 0);
+
+			if (iohole) {
+				/* On first bus we need to leave room for the
+				 * ISA address space. Just skip the first 256MB
+				 * alltogether. This leaves 768MB for the window.
+				 */
+				DBG("PHB has io-hole, reserving 256MB\n");
+				dn->phb->dma_window_size = 3 << 28;
+				dn->phb->dma_window_base_cur = 1 << 28;
+			} else {
+				/* 1GB window by default */
+				dn->phb->dma_window_size = 1 << 30;
+				dn->phb->dma_window_base_cur = 0;
+			}
+
+			tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
+
+			iommu_table_setparms(dn->phb, dn, tbl);
+			dn->iommu_table = iommu_init_table(tbl);
+		} else {
+			/* Do a 128MB table at root. This is used for the IDE
+			 * controller on some SMP-mode POWER4 machines. It
+			 * doesn't hurt to allocate it on other machines
+			 * -- it'll just be unused since new tables are
+			 * allocated on the EADS level.
+			 *
+			 * Allocate at offset 128MB to avoid having to deal
+			 * with ISA holes; 128MB table for IDE is plenty.
+			 */
+			dn->phb->dma_window_size = 1 << 27;
+			dn->phb->dma_window_base_cur = 1 << 27;
+
+			tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
+
+			iommu_table_setparms(dn->phb, dn, tbl);
+			dn->iommu_table = iommu_init_table(tbl);
+
+			/* All child buses have 256MB tables */
+			dn->phb->dma_window_size = 1 << 28;
+		}
+	} else {
+		pdn = pci_bus_to_OF_node(bus->parent);
+
+		if (!bus->parent->self && !is_python(pdn)) {
+			struct iommu_table *tbl;
+			/* First child and not python means this is the EADS
+			 * level. Allocate new table for this slot with 256MB
+			 * window.
+			 */
+
+			tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
+
+			iommu_table_setparms(dn->phb, dn, tbl);
+
+			dn->iommu_table = iommu_init_table(tbl);
+		} else {
+			/* Lower than first child or under python, use parent table */
+			dn->iommu_table = pdn->iommu_table;
+		}
+	}
+}
+
 
-void iommu_devnode_init_pSeries(struct device_node *dn)
+static void iommu_bus_setup_pSeriesLP(struct pci_bus *bus)
 {
 	struct iommu_table *tbl;
+	struct device_node *dn, *pdn;
+	unsigned int *dma_window = NULL;
 
-	tbl = (struct iommu_table *)kmalloc(sizeof(struct iommu_table), 
-					    GFP_KERNEL);
-	
-	if (systemcfg->platform == PLATFORM_PSERIES_LPAR)
-		iommu_table_setparms_lpar(dn->phb, dn, tbl);
-	else
-		iommu_table_setparms(dn->phb, dn, tbl);
+	dn = pci_bus_to_OF_node(bus);
+
+	/* Find nearest ibm,dma-window, walking up the device tree */
+	for (pdn = dn; pdn != NULL; pdn = pdn->parent) {
+		dma_window = (unsigned int *)get_property(pdn, "ibm,dma-window", NULL);
+		if (dma_window != NULL)
+			break;
+	}
+
+	if (dma_window == NULL) {
+		DBG("iommu_bus_setup_pSeriesLP: bus %s seems to have no ibm,dma-window property\n", dn->full_name);
+		return;
+	}
+
+	if (!pdn->iommu_table) {
+		/* Bussubno hasn't been copied yet.
+		 * Do it now because iommu_table_setparms_lpar needs it.
+		 */
+		pdn->bussubno = bus->number;
+
+		tbl = (struct iommu_table *)kmalloc(sizeof(struct iommu_table),
+						    GFP_KERNEL);
 	
-	dn->iommu_table = iommu_init_table(tbl);
+		iommu_table_setparms_lpar(pdn->phb, pdn, tbl, dma_window);
+
+		pdn->iommu_table = iommu_init_table(tbl);
+	}
+
+	if (pdn != dn)
+		dn->iommu_table = pdn->iommu_table;
 }
 
-void iommu_setup_pSeries(void)
+
+static void iommu_dev_setup_pSeries(struct pci_dev *dev)
 {
-	struct pci_dev *dev = NULL;
 	struct device_node *dn, *mydn;
 
-	if (systemcfg->platform == PLATFORM_PSERIES_LPAR)
-		iommu_buses_init_lpar(&pci_root_buses);
-	else
-		iommu_buses_init();
-
-	/* Now copy the iommu_table ptr from the bus devices down to every
+	DBG("iommu_dev_setup_pSeries, dev %p (%s)\n", dev, dev->pretty_name);
+	/* Now copy the iommu_table ptr from the bus device down to the
 	 * pci device_node.  This means get_iommu_table() won't need to search
 	 * up the device tree to find it.
 	 */
-	for_each_pci_dev(dev) {
-		mydn = dn = pci_device_to_OF_node(dev);
+	mydn = dn = pci_device_to_OF_node(dev);
+
+	while (dn && dn->iommu_table == NULL)
+		dn = dn->parent;
 
-		while (dn && dn->iommu_table == NULL)
-			dn = dn->parent;
-		if (dn)
-			mydn->iommu_table = dn->iommu_table;
+	if (dn) {
+		mydn->iommu_table = dn->iommu_table;
+	} else {
+		DBG("iommu_dev_setup_pSeries, dev %p (%s) has no iommu table\n", dev, dev->pretty_name);
 	}
 }
 
+static void iommu_bus_setup_null(struct pci_bus *b) { }
+static void iommu_dev_setup_null(struct pci_dev *d) { }
+
 /* These are called very early. */
-void tce_init_pSeries(void)
+void iommu_init_early_pSeries(void)
 {
-	if (!(systemcfg->platform & PLATFORM_LPAR)) {
+	if (of_chosen && get_property(of_chosen, "linux,iommu-off", NULL)) {
+		/* Direct I/O, IOMMU off */
+		ppc_md.iommu_dev_setup = iommu_dev_setup_null;
+		ppc_md.iommu_bus_setup = iommu_bus_setup_null;
+		pci_direct_iommu_init();
+
+		return;
+	}
+
+	if (systemcfg->platform & PLATFORM_LPAR) {
+		if (cur_cpu_spec->firmware_features & FW_FEATURE_MULTITCE) {
+			ppc_md.tce_build = tce_buildmulti_pSeriesLP;
+			ppc_md.tce_free	 = tce_freemulti_pSeriesLP;
+		} else {
+			ppc_md.tce_build = tce_build_pSeriesLP;
+			ppc_md.tce_free	 = tce_free_pSeriesLP;
+		}
+		ppc_md.iommu_bus_setup = iommu_bus_setup_pSeriesLP;
+	} else {
 		ppc_md.tce_build = tce_build_pSeries;
 		ppc_md.tce_free  = tce_free_pSeries;
-	} else if (cur_cpu_spec->firmware_features & FW_FEATURE_MULTITCE) {
-		ppc_md.tce_build = tce_buildmulti_pSeriesLP;
-		ppc_md.tce_free	 = tce_freemulti_pSeriesLP;
-	} else {
-		ppc_md.tce_build = tce_build_pSeriesLP;
-		ppc_md.tce_free	 = tce_free_pSeriesLP;
+		ppc_md.iommu_bus_setup = iommu_bus_setup_pSeries;
 	}
+
+	ppc_md.iommu_dev_setup = iommu_dev_setup_pSeries;
 
 	pci_iommu_init();
 }
diff -Nru a/arch/ppc64/kernel/pSeries_lpar.c b/arch/ppc64/kernel/pSeries_lpar.c
--- a/arch/ppc64/kernel/pSeries_lpar.c	2005-03-01 23:39:17 -08:00
+++ b/arch/ppc64/kernel/pSeries_lpar.c	2005-03-01 23:39:17 -08:00
@@ -33,7 +33,6 @@
 #include <asm/mmu_context.h>
 #include <asm/ppcdebug.h>
 #include <asm/iommu.h>
-#include <asm/naca.h>
 #include <asm/tlbflush.h>
 #include <asm/tlb.h>
 #include <asm/prom.h>
@@ -336,7 +335,7 @@
 	return (slot & 7) | (secondary << 3);
 }
 
-static spinlock_t pSeries_lpar_tlbie_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(pSeries_lpar_tlbie_lock);
 
 static long pSeries_lpar_hpte_remove(unsigned long hpte_group)
 {
@@ -368,7 +367,7 @@
 
 static void pSeries_lpar_hptab_clear(void)
 {
-	unsigned long size_bytes = 1UL << naca->pftSize;
+	unsigned long size_bytes = 1UL << ppc64_pft_size;
 	unsigned long hpte_count = size_bytes >> 4;
 	unsigned long dummy1, dummy2;
 	int i;
@@ -437,7 +436,7 @@
 	hash = hpt_hash(vpn, 0);
 
 	for (j = 0; j < 2; j++) {
-		slot = (hash & htab_data.htab_hash_mask) * HPTES_PER_GROUP;
+		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;
@@ -504,7 +503,7 @@
 				   int local)
 {
 	int i;
-	unsigned long flags;
+	unsigned long flags = 0;
 	struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch);
 	int lock_tlbie = !(cur_cpu_spec->cpu_features & CPU_FTR_LOCKLESS_TLBIE);
 
diff -Nru a/arch/ppc64/kernel/pSeries_nvram.c b/arch/ppc64/kernel/pSeries_nvram.c
--- a/arch/ppc64/kernel/pSeries_nvram.c	2005-03-01 23:39:09 -08:00
+++ b/arch/ppc64/kernel/pSeries_nvram.c	2005-03-01 23:39:09 -08:00
@@ -31,7 +31,7 @@
 static unsigned int nvram_size;
 static int nvram_fetch, nvram_store;
 static char nvram_buf[NVRW_CNT];	/* assume this is in the first 4GB */
-static spinlock_t nvram_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(nvram_lock);
 
 
 static ssize_t pSeries_nvram_read(char *buf, size_t count, loff_t *index)
diff -Nru a/arch/ppc64/kernel/pSeries_pci.c b/arch/ppc64/kernel/pSeries_pci.c
--- a/arch/ppc64/kernel/pSeries_pci.c	2005-03-01 23:39:18 -08:00
+++ b/arch/ppc64/kernel/pSeries_pci.c	2005-03-01 23:39:18 -08:00
@@ -36,7 +36,6 @@
 #include <asm/prom.h>
 #include <asm/machdep.h>
 #include <asm/pci-bridge.h>
-#include <asm/naca.h>
 #include <asm/iommu.h>
 #include <asm/rtas.h>
 
@@ -149,7 +148,7 @@
 	rtas_pci_write_config
 };
 
-static int is_python(struct device_node *dev)
+int is_python(struct device_node *dev)
 {
 	char *model = (char *)get_property(dev, "model", NULL);
 
@@ -353,7 +352,7 @@
 	unsigned int *opprop = NULL;
 	struct device_node *root = of_find_node_by_path("/");
 
-	if (naca->interrupt_controller == IC_OPEN_PIC) {
+	if (ppc64_interrupt_controller == IC_OPEN_PIC) {
 		opprop = (unsigned int *)get_property(root,
 				"platform-open-pic", NULL);
 	}
@@ -375,7 +374,7 @@
 		pci_process_bridge_OF_ranges(phb, node);
 		pci_setup_phb_io(phb, index == 0);
 
-		if (naca->interrupt_controller == IC_OPEN_PIC && pSeries_mpic) {
+		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]);
 		}
@@ -553,10 +552,6 @@
 
 	phbs_remap_io();
 	pSeries_request_regions();
-	pci_fix_bus_sysdata();
-
-	if (!of_chosen || !get_property(of_chosen, "linux,iommu-off", NULL))
-		iommu_setup_pSeries();
 
 	pci_addr_cache_build();
 }
diff -Nru a/arch/ppc64/kernel/pSeries_setup.c b/arch/ppc64/kernel/pSeries_setup.c
--- a/arch/ppc64/kernel/pSeries_setup.c	2005-03-01 23:38:52 -08:00
+++ b/arch/ppc64/kernel/pSeries_setup.c	2005-03-01 23:38:52 -08:00
@@ -40,7 +40,6 @@
 #include <linux/adb.h>
 #include <linux/module.h>
 #include <linux/delay.h>
-
 #include <linux/irq.h>
 #include <linux/seq_file.h>
 #include <linux/root_dev.h>
@@ -56,16 +55,15 @@
 #include <asm/dma.h>
 #include <asm/machdep.h>
 #include <asm/irq.h>
-#include <asm/naca.h>
 #include <asm/time.h>
 #include <asm/nvram.h>
-
-#include "i8259.h"
+#include <asm/plpar_wrappers.h>
 #include <asm/xics.h>
-#include <asm/ppcdebug.h>
 #include <asm/cputable.h>
 
+#include "i8259.h"
 #include "mpic.h"
+#include "pci.h"
 
 #ifdef DEBUG
 #define DBG(fmt...) udbg_printf(fmt)
@@ -73,25 +71,25 @@
 #define DBG(fmt...)
 #endif
 
-extern void find_and_init_phbs(void);
 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 SystemReset_FWNMI(void), MachineCheck_FWNMI(void);	/* from head.S */
-extern void generic_find_legacy_serial_ports(unsigned int *default_speed);
+extern void system_reset_fwnmi(void);	/* from head.S */
+extern void machine_check_fwnmi(void);	/* from head.S */
+extern void generic_find_legacy_serial_ports(u64 *physport,
+		unsigned int *default_speed);
 
 int fwnmi_active;  /* TRUE if an FWNMI handler is present */
 
-unsigned long  virtPython0Facilities = 0;  // python0 facility area (memory mapped io) (64-bit format) VIRTUAL address.
-
-extern unsigned long loops_per_jiffy;
-
 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 volatile void __iomem * chrp_int_ack_special;
 struct mpic *pSeries_mpic;
 
@@ -118,8 +116,8 @@
 	if (ibm_nmi_register == RTAS_UNKNOWN_SERVICE)
 		return;
 	ret = rtas_call(ibm_nmi_register, 2, 1, NULL,
-			__pa((unsigned long)SystemReset_FWNMI),
-			__pa((unsigned long)MachineCheck_FWNMI));
+			__pa((unsigned long)system_reset_fwnmi),
+			__pa((unsigned long)machine_check_fwnmi));
 	if (ret == 0)
 		fwnmi_active = 1;
 }
@@ -196,7 +194,7 @@
 static void __init pSeries_setup_arch(void)
 {
 	/* Fixup ppc_md depending on the type of interrupt controller */
-	if (naca->interrupt_controller == IC_OPEN_PIC) {
+	if (ppc64_interrupt_controller == IC_OPEN_PIC) {
 		ppc_md.init_IRQ       = pSeries_init_mpic; 
 		ppc_md.get_irq        = mpic_get_irq;
 		/* Allocate the mpic now, so that find_and_init_phbs() can
@@ -225,7 +223,7 @@
 	fwnmi_init();
 
 	/* Find and initialize PCI host bridges */
-	/* iSeries needs to be done much later. */
+	init_pci_config_tokens();
 	eeh_init();
 	find_and_init_phbs();
 
@@ -308,15 +306,15 @@
 	 * to properly parse the OF interrupt tree & do the virtual irq mapping
 	 */
 	__irq_offset_value = NUM_ISA_INTERRUPTS;
-	naca->interrupt_controller = IC_INVALID;
+	ppc64_interrupt_controller = IC_INVALID;
 	for (np = NULL; (np = of_find_node_by_name(np, "interrupt-controller"));) {
 		typep = (char *)get_property(np, "compatible", NULL);
 		if (strstr(typep, "open-pic"))
-			naca->interrupt_controller = IC_OPEN_PIC;
+			ppc64_interrupt_controller = IC_OPEN_PIC;
 		else if (strstr(typep, "ppc-xicp"))
-			naca->interrupt_controller = IC_PPC_XIC;
+			ppc64_interrupt_controller = IC_PPC_XIC;
 		else
-			printk("initialize_naca: failed to recognize"
+			printk("pSeries_discover_pic: failed to recognize"
 			       " interrupt-controller\n");
 		break;
 	}
@@ -344,6 +342,7 @@
 	void *comport;
 	int iommu_off = 0;
 	unsigned int default_speed;
+	u64 physport;
 
 	DBG(" -> pSeries_init_early()\n");
 
@@ -357,13 +356,13 @@
 			     get_property(of_chosen, "linux,iommu-off", NULL));
 	}
 
-	generic_find_legacy_serial_ports(&default_speed);
+	generic_find_legacy_serial_ports(&physport, &default_speed);
 
 	if (systemcfg->platform & PLATFORM_LPAR)
 		find_udbg_vterm();
-	else if (naca->serialPortAddr) {
+	else if (physport) {
 		/* Map the uart for udbg. */
-		comport = (void *)__ioremap(naca->serialPortAddr, 16, _PAGE_NO_CACHE);
+		comport = (void *)__ioremap(physport, 16, _PAGE_NO_CACHE);
 		udbg_init_uart(comport, default_speed);
 
 		ppc_md.udbg_putc = udbg_putc;
@@ -373,10 +372,7 @@
 	}
 
 
-	if (iommu_off)
-		pci_dma_init_direct();
-	else
-		tce_init_pSeries();
+	iommu_init_early_pSeries();
 
 	pSeries_discover_pic();
 
@@ -391,7 +387,7 @@
 	char *os;
 	static int display_character, set_indicator;
 	static int max_width;
-	static spinlock_t progress_lock = SPIN_LOCK_UNLOCKED;
+	static DEFINE_SPINLOCK(progress_lock);
 	static int pending_newline = 0;  /* did last write end with unprinted newline? */
 
 	if (!rtas.base)
@@ -610,4 +606,6 @@
 	.calibrate_decr		= pSeries_calibrate_decr,
 	.progress		= pSeries_progress,
 	.check_legacy_ioport	= pSeries_check_legacy_ioport,
+	.system_reset_exception = pSeries_system_reset_exception,
+	.machine_check_exception = pSeries_machine_check_exception,
 };
diff -Nru a/arch/ppc64/kernel/pSeries_smp.c b/arch/ppc64/kernel/pSeries_smp.c
--- a/arch/ppc64/kernel/pSeries_smp.c	2005-03-01 23:38:58 -08:00
+++ b/arch/ppc64/kernel/pSeries_smp.c	2005-03-01 23:38:58 -08:00
@@ -19,9 +19,7 @@
 #include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/interrupt.h>
-#include <linux/kernel_stat.h>
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/spinlock.h>
@@ -38,10 +36,8 @@
 #include <asm/io.h>
 #include <asm/prom.h>
 #include <asm/smp.h>
-#include <asm/naca.h>
 #include <asm/paca.h>
 #include <asm/time.h>
-#include <asm/ppcdebug.h>
 #include <asm/machdep.h>
 #include <asm/xics.h>
 #include <asm/cputable.h>
@@ -57,7 +53,7 @@
 #define DBG(fmt...)
 #endif
 
-extern void pseries_secondary_smp_init(unsigned long); 
+extern void pSeries_secondary_smp_init(unsigned long);
 
 /* Get state of physical CPU.
  * Return codes:
@@ -88,11 +84,8 @@
 
 #ifdef CONFIG_HOTPLUG_CPU
 
-int __cpu_disable(void)
+int pSeries_cpu_disable(void)
 {
-	/* FIXME: go put this in a header somewhere */
-	extern void xics_migrate_irqs_away(void);
-
 	systemcfg->processorCount--;
 
 	/*fix boot_cpuid here*/
@@ -104,7 +97,7 @@
 	return 0;
 }
 
-void __cpu_die(unsigned int cpu)
+void pSeries_cpu_die(unsigned int cpu)
 {
 	int tries;
 	int cpu_status;
@@ -114,8 +107,7 @@
 		cpu_status = query_cpu_stopped(pcpu);
 		if (cpu_status == 0 || cpu_status == -1)
 			break;
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(HZ/5);
+		msleep(200);
 	}
 	if (cpu_status != 0) {
 		printk("Querying DEAD? cpu %i (%i) shows %i\n",
@@ -193,7 +185,7 @@
 {
 	int status;
 	unsigned long start_here = __pa((u32)*((unsigned long *)
-					       pseries_secondary_smp_init));
+					       pSeries_secondary_smp_init));
 	unsigned int pcpu;
 
 	/* At boot time the cpus are already spinning in hold
@@ -251,8 +243,6 @@
 	}
 }
 
-extern void xics_request_IPIs(void);
-
 static int __init smp_xics_probe(void)
 {
 	xics_request_IPIs();
@@ -264,9 +254,20 @@
 {
 	if (cpu != boot_cpuid)
 		xics_setup_cpu();
+
+	if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR)
+		vpa_init(cpu);
+
+	/*
+	 * Put the calling processor into the GIQ.  This is really only
+	 * necessary from a secondary thread as the OF start-cpu interface
+	 * performs this function for us on primary threads.
+	 */
+	rtas_set_indicator(GLOBAL_INTERRUPT_QUEUE,
+		(1UL << interrupt_server_size) - 1 - default_distrib_server, 1);
 }
 
-static spinlock_t timebase_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(timebase_lock);
 static unsigned long timebase = 0;
 
 static void __devinit pSeries_give_timebase(void)
@@ -291,26 +292,7 @@
 	spin_unlock(&timebase_lock);
 }
 
-static void __devinit pSeries_late_setup_cpu(int cpu)
-{
-	extern unsigned int default_distrib_server;
-
-	if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR) {
-		vpa_init(cpu); 
-	}
-
-#ifdef CONFIG_IRQ_ALL_CPUS
-	/* Put the calling processor into the GIQ.  This is really only
-	 * necessary from a secondary thread as the OF start-cpu interface
-	 * performs this function for us on primary threads.
-	 */
-	/* TODO: 9005 is #defined in rtas-proc.c -- move to a header */
-	rtas_set_indicator(9005, default_distrib_server, 1);
-#endif
-}
-
-
-void __devinit smp_pSeries_kick_cpu(int nr)
+static void __devinit smp_pSeries_kick_cpu(int nr)
 {
 	BUG_ON(nr < 0 || nr >= NR_CPUS);
 
@@ -330,7 +312,6 @@
 	.probe		= smp_mpic_probe,
 	.kick_cpu	= smp_pSeries_kick_cpu,
 	.setup_cpu	= smp_mpic_setup_cpu,
-	.late_setup_cpu	= pSeries_late_setup_cpu,
 };
 
 static struct smp_ops_t pSeries_xics_smp_ops = {
@@ -338,7 +319,6 @@
 	.probe		= smp_xics_probe,
 	.kick_cpu	= smp_pSeries_kick_cpu,
 	.setup_cpu	= smp_xics_setup_cpu,
-	.late_setup_cpu	= pSeries_late_setup_cpu,
 };
 
 /* This is called very early */
@@ -348,11 +328,16 @@
 
 	DBG(" -> smp_init_pSeries()\n");
 
-	if (naca->interrupt_controller == IC_OPEN_PIC)
+	if (ppc64_interrupt_controller == IC_OPEN_PIC)
 		smp_ops = &pSeries_mpic_smp_ops;
 	else
 		smp_ops = &pSeries_xics_smp_ops;
 
+#ifdef CONFIG_HOTPLUG_CPU
+	smp_ops->cpu_disable = pSeries_cpu_disable;
+	smp_ops->cpu_die = pSeries_cpu_die;
+#endif
+
 	/* Start secondary threads on SMT systems; primary threads
 	 * are already in the running state.
 	 */
@@ -363,13 +348,10 @@
 			rtas_call(rtas_token("start-cpu"), 3, 1, &ret,
 				  get_hard_smp_processor_id(i),
 				  __pa((u32)*((unsigned long *)
-					      pseries_secondary_smp_init)),
+					      pSeries_secondary_smp_init)),
 				  i);
 		}
 	}
-
-	if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR)
-		vpa_init(boot_cpuid);
 
 	/* Non-lpar has additional take/give timebase */
 	if (rtas_token("freeze-time-base") != RTAS_UNKNOWN_SERVICE) {
diff -Nru a/arch/ppc64/kernel/pacaData.c b/arch/ppc64/kernel/pacaData.c
--- a/arch/ppc64/kernel/pacaData.c	2005-03-01 23:39:08 -08:00
+++ b/arch/ppc64/kernel/pacaData.c	2005-03-01 23:39:08 -08:00
@@ -10,24 +10,25 @@
 #include <linux/config.h>
 #include <linux/types.h>
 #include <linux/threads.h>
+#include <linux/module.h>
+
 #include <asm/processor.h>
 #include <asm/ptrace.h>
 #include <asm/page.h>
 
-#include <asm/iSeries/ItLpPaca.h>
+#include <asm/lppaca.h>
 #include <asm/iSeries/ItLpQueue.h>
-#include <asm/naca.h>
 #include <asm/paca.h>
 
-struct naca_struct *naca;
 struct systemcfg *systemcfg;
+EXPORT_SYMBOL(systemcfg);
 
 /* This symbol is provided by the linker - let it fill in the paca
  * field correctly */
 extern unsigned long __toc_start;
 
 /* The Paca is an array with one entry per processor.  Each contains an 
- * ItLpPaca, which contains the information shared between the 
+ * lppaca, which contains the information shared between the
  * hypervisor and Linux.  Each also contains an ItLpRegSave area which
  * is used by the hypervisor to save registers.
  * On systems with hardware multi-threading, there are two threads
@@ -60,13 +61,13 @@
 	.cpu_start = (start),		/* Processor start */		    \
 	.hw_cpu_id = 0xffff,						    \
 	.lppaca = {							    \
-		.xDesc = 0xd397d781,	/* "LpPa" */			    \
-		.xSize = sizeof(struct ItLpPaca),			    \
-		.xFPRegsInUse = 1,					    \
-		.xDynProcStatus = 2,					    \
-		.xDecrVal = 0x00ff0000,					    \
-		.xEndOfQuantum = 0xfffffffffffffffful,			    \
-		.xSLBCount = 64,					    \
+		.desc = 0xd397d781,	/* "LpPa" */			    \
+		.size = sizeof(struct lppaca),				    \
+		.dyn_proc_status = 2,					    \
+		.decr_val = 0x00ff0000,					    \
+		.fpregs_in_use = 1,					    \
+		.end_of_quantum = 0xfffffffffffffffful,			    \
+		.slb_count = 64,					    \
 	},								    \
 	EXTRA_INITS((number), (lpq))					    \
 }
@@ -77,13 +78,16 @@
 #else
 	PACAINITDATA( 0, 1, NULL, STAB0_PHYS_ADDR, STAB0_VIRT_ADDR),
 #endif
+#if NR_CPUS > 1
 	PACAINITDATA( 1, 0, NULL, 0, 0),
 	PACAINITDATA( 2, 0, NULL, 0, 0),
 	PACAINITDATA( 3, 0, NULL, 0, 0),
+#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),
+#if NR_CPUS > 8
 	PACAINITDATA( 8, 0, NULL, 0, 0),
 	PACAINITDATA( 9, 0, NULL, 0, 0),
 	PACAINITDATA(10, 0, NULL, 0, 0),
@@ -206,6 +210,9 @@
 	PACAINITDATA(125, 0, NULL, 0, 0),
 	PACAINITDATA(126, 0, NULL, 0, 0),
 	PACAINITDATA(127, 0, NULL, 0, 0),
+#endif
+#endif
+#endif
 #endif
 #endif
 };
diff -Nru a/arch/ppc64/kernel/pci.c b/arch/ppc64/kernel/pci.c
--- a/arch/ppc64/kernel/pci.c	2005-03-01 23:39:09 -08:00
+++ b/arch/ppc64/kernel/pci.c	2005-03-01 23:39:09 -08:00
@@ -91,7 +91,7 @@
 			      struct resource *res)
 {
 	unsigned long offset = 0;
-	struct pci_controller *hose = PCI_GET_PHB_PTR(dev);
+	struct pci_controller *hose = pci_bus_to_host(dev->bus);
 
 	if (!hose)
 		return;
@@ -127,7 +127,7 @@
 			    unsigned long size, unsigned long align)
 {
 	struct pci_dev *dev = data;
-	struct pci_controller *hose = PCI_GET_PHB_PTR(dev);
+	struct pci_controller *hose = pci_bus_to_host(dev->bus);
 	unsigned long start = res->start;
 	unsigned long alignto;
 
@@ -157,7 +157,7 @@
 	res->start = start;
 }
 
-static spinlock_t hose_spinlock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(hose_spinlock);
 
 /*
  * pci_controller(phb) initialized common variables.
@@ -292,7 +292,7 @@
 #ifdef CONFIG_PPC_ISERIES
 	return 0;
 #else
-	struct pci_controller *hose = PCI_GET_PHB_PTR(bus);
+	struct pci_controller *hose = pci_bus_to_host(bus);
 
 	return hose->global_number;
 #endif
@@ -304,7 +304,7 @@
 int pci_name_bus(char *name, struct pci_bus *bus)
 {
 #ifndef CONFIG_PPC_ISERIES
-	struct pci_controller *hose = PCI_GET_PHB_PTR(bus);
+	struct pci_controller *hose = pci_bus_to_host(bus);
 
 	if (hose->buid)
 		sprintf(name, "%04x:%02x", pci_domain_nr(bus), bus->number);
@@ -336,7 +336,7 @@
 					     struct vm_area_struct *vma,
 					     enum pci_mmap_state mmap_state)
 {
-	struct pci_controller *hose = PCI_GET_PHB_PTR(dev);
+	struct pci_controller *hose = pci_bus_to_host(dev->bus);
 	unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
 	unsigned long io_offset = 0;
 	int i, res_bit;
@@ -643,7 +643,7 @@
 static int get_bus_io_range(struct pci_bus *bus, unsigned long *start_phys,
 				unsigned long *start_virt, unsigned long *size)
 {
-	struct pci_controller *hose = PCI_GET_PHB_PTR(bus);
+	struct pci_controller *hose = pci_bus_to_host(bus);
 	struct pci_bus_region region;
 	struct resource *res;
 
@@ -728,23 +728,6 @@
 		remap_bus_range(hose->bus);
 }
 
-
-/*
- * This function finds the PHB that matching device_node in the 
- * OpenFirmware by scanning all the pci_controllers.
- */
-struct pci_controller* pci_find_hose_for_OF_device(struct device_node *node)
-{
-	while (node) {
-		struct pci_controller *hose, *tmp;
-		list_for_each_entry_safe(hose, tmp, &hose_list, list_node)
-			if (hose->arch_data == node)
-				return hose;
-		node=node->parent;
-	}
-	return NULL;
-}
-
 /*
  * ppc64 can have multifunction devices that do not respond to function 0.
  * In this case we must scan all functions.
@@ -778,7 +761,7 @@
 					   struct pci_bus *bus)
 {
 	/* Update device resources.  */
-	struct pci_controller *hose = PCI_GET_PHB_PTR(bus);
+	struct pci_controller *hose = pci_bus_to_host(bus);
 	int i;
 
 	for (i = 0; i < PCI_NUM_RESOURCES; i++) {
@@ -814,7 +797,7 @@
 
 void __devinit pcibios_fixup_bus(struct pci_bus *bus)
 {
-	struct pci_controller *hose = PCI_GET_PHB_PTR(bus);
+	struct pci_controller *hose = pci_bus_to_host(bus);
 	struct pci_dev *dev = bus->self;
 	struct resource *res;
 	int i;
@@ -844,6 +827,11 @@
 		pci_read_bridge_bases(bus);
 		pcibios_fixup_device_resources(dev, bus);
 	}
+
+	ppc_md.iommu_bus_setup(bus);
+
+	list_for_each_entry(dev, &bus->devices, bus_list)
+		ppc_md.iommu_dev_setup(dev);
 
 	if (!pci_probe_only)
 		return;
diff -Nru a/arch/ppc64/kernel/pci.h b/arch/ppc64/kernel/pci.h
--- a/arch/ppc64/kernel/pci.h	2005-03-01 23:38:44 -08:00
+++ b/arch/ppc64/kernel/pci.h	2005-03-01 23:38:44 -08:00
@@ -17,7 +17,6 @@
 extern void pci_setup_pci_controller(struct pci_controller *hose);
 extern void pci_setup_phb_io(struct pci_controller *hose, int primary);
 
-extern struct pci_controller* pci_find_hose_for_OF_device(struct device_node* node);
 extern void pci_setup_phb_io_dynamic(struct pci_controller *hose);
 
 
@@ -36,10 +35,7 @@
 
 void pci_devs_phb_init(void);
 void pci_devs_phb_init_dynamic(struct pci_controller *phb);
-void pci_fix_bus_sysdata(void);
 struct device_node *fetch_dev_dn(struct pci_dev *dev);
-
-#define PCI_GET_PHB_PTR(dev)    (((struct device_node *)(dev)->sysdata)->phb)
 
 /* PCI address cache management routines */
 void pci_addr_cache_insert_device(struct pci_dev *dev);
diff -Nru a/arch/ppc64/kernel/pci_direct_iommu.c b/arch/ppc64/kernel/pci_direct_iommu.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/ppc64/kernel/pci_direct_iommu.c	2005-03-01 23:38:44 -08:00
@@ -0,0 +1,89 @@
+/*
+ * Support for DMA from PCI devices to main memory on
+ * machines without an iommu or with directly addressable
+ * RAM (typically a pmac with 2Gb of RAM or less)
+ *
+ * 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.
+ */
+
+#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/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 "pci.h"
+
+static void *pci_direct_alloc_consistent(struct pci_dev *hwdev, size_t size,
+				   dma_addr_t *dma_handle)
+{
+	void *ret;
+
+	ret = (void *)__get_free_pages(GFP_ATOMIC, get_order(size));
+	if (ret != NULL) {
+		memset(ret, 0, size);
+		*dma_handle = virt_to_abs(ret);
+	}
+	return ret;
+}
+
+static void pci_direct_free_consistent(struct pci_dev *hwdev, size_t size,
+				 void *vaddr, dma_addr_t dma_handle)
+{
+	free_pages((unsigned long)vaddr, get_order(size));
+}
+
+static dma_addr_t pci_direct_map_single(struct pci_dev *hwdev, void *ptr,
+		size_t size, enum dma_data_direction direction)
+{
+	return virt_to_abs(ptr);
+}
+
+static void pci_direct_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr,
+		size_t size, enum dma_data_direction direction)
+{
+}
+
+static int pci_direct_map_sg(struct pci_dev *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;
+		sg->dma_length = sg->length;
+	}
+
+	return nents;
+}
+
+static void pci_direct_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg,
+		int nents, enum dma_data_direction direction)
+{
+}
+
+void __init pci_direct_iommu_init(void)
+{
+	pci_dma_ops.pci_alloc_consistent = pci_direct_alloc_consistent;
+	pci_dma_ops.pci_free_consistent = pci_direct_free_consistent;
+	pci_dma_ops.pci_map_single = pci_direct_map_single;
+	pci_dma_ops.pci_unmap_single = pci_direct_unmap_single;
+	pci_dma_ops.pci_map_sg = pci_direct_map_sg;
+	pci_dma_ops.pci_unmap_sg = pci_direct_unmap_sg;
+}
diff -Nru a/arch/ppc64/kernel/pci_dma_direct.c b/arch/ppc64/kernel/pci_dma_direct.c
--- a/arch/ppc64/kernel/pci_dma_direct.c	2005-03-01 23:38:44 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,89 +0,0 @@
-/*
- * Support for DMA from PCI devices to main memory on
- * machines without an iommu or with directly addressable
- * RAM (typically a pmac with 2Gb of RAM or less)
- *
- * 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.
- */
-
-#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/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 "pci.h"
-
-static void *pci_direct_alloc_consistent(struct pci_dev *hwdev, size_t size,
-				   dma_addr_t *dma_handle)
-{
-	void *ret;
-
-	ret = (void *)__get_free_pages(GFP_ATOMIC, get_order(size));
-	if (ret != NULL) {
-		memset(ret, 0, size);
-		*dma_handle = virt_to_abs(ret);
-	}
-	return ret;
-}
-
-static void pci_direct_free_consistent(struct pci_dev *hwdev, size_t size,
-				 void *vaddr, dma_addr_t dma_handle)
-{
-	free_pages((unsigned long)vaddr, get_order(size));
-}
-
-static dma_addr_t pci_direct_map_single(struct pci_dev *hwdev, void *ptr,
-		size_t size, enum dma_data_direction direction)
-{
-	return virt_to_abs(ptr);
-}
-
-static void pci_direct_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr,
-		size_t size, enum dma_data_direction direction)
-{
-}
-
-static int pci_direct_map_sg(struct pci_dev *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;
-		sg->dma_length = sg->length;
-	}
-
-	return nents;
-}
-
-static void pci_direct_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg,
-		int nents, enum dma_data_direction direction)
-{
-}
-
-void __init pci_dma_init_direct(void)
-{
-	pci_dma_ops.pci_alloc_consistent = pci_direct_alloc_consistent;
-	pci_dma_ops.pci_free_consistent = pci_direct_free_consistent;
-	pci_dma_ops.pci_map_single = pci_direct_map_single;
-	pci_dma_ops.pci_unmap_single = pci_direct_unmap_single;
-	pci_dma_ops.pci_map_sg = pci_direct_map_sg;
-	pci_dma_ops.pci_unmap_sg = pci_direct_unmap_sg;
-}
diff -Nru a/arch/ppc64/kernel/pci_dn.c b/arch/ppc64/kernel/pci_dn.c
--- a/arch/ppc64/kernel/pci_dn.c	2005-03-01 23:39:17 -08:00
+++ b/arch/ppc64/kernel/pci_dn.c	2005-03-01 23:39:17 -08:00
@@ -21,20 +21,12 @@
  */
 #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 <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/ppcdebug.h>
-#include <asm/naca.h>
-#include <asm/iommu.h>
 
 #include "pci.h"
 
@@ -178,30 +170,4 @@
 	/* This must be done first so the device nodes have valid pci info! */
 	list_for_each_entry_safe(phb, tmp, &hose_list, list_node)
 		pci_devs_phb_init_dynamic(phb);
-}
-
-
-static void __init pci_fixup_bus_sysdata_list(struct list_head *bus_list)
-{
-	struct pci_bus *bus;
-
-	list_for_each_entry(bus, bus_list, node) {
-		if (bus->self)
-			bus->sysdata = bus->self->sysdata;
-		pci_fixup_bus_sysdata_list(&bus->children);
-	}
-}
-
-/*
- * Fixup the bus->sysdata ptrs to point to the bus' device_node.
- * This is done late in pcibios_init().  We do this mostly for
- * sanity, but pci_dma.c uses these at DMA time so they must be
- * correct.
- * To do this we recurse down the bus hierarchy.  Note that PHB's
- * have bus->self == NULL, but fortunately bus->sysdata is already
- * correct in this case.
- */
-void __init pci_fix_bus_sysdata(void)
-{
-	pci_fixup_bus_sysdata_list(&pci_root_buses);
 }
diff -Nru a/arch/ppc64/kernel/pmac_feature.c b/arch/ppc64/kernel/pmac_feature.c
--- a/arch/ppc64/kernel/pmac_feature.c	2005-03-01 23:39:08 -08:00
+++ b/arch/ppc64/kernel/pmac_feature.c	2005-03-01 23:39:08 -08:00
@@ -53,7 +53,7 @@
  * We use a single global lock to protect accesses. Each driver has
  * to take care of its own locking
  */
-static spinlock_t feature_lock  __pmacdata = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(feature_lock  __pmacdata);
 
 #define LOCK(flags)	spin_lock_irqsave(&feature_lock, flags);
 #define UNLOCK(flags)	spin_unlock_irqrestore(&feature_lock, flags);
@@ -111,7 +111,7 @@
 static u32 uninorth_rev __pmacdata;
 static void *u3_ht;
 
-extern struct pci_dev *k2_skiplist[2];
+extern struct device_node *k2_skiplist[2];
 
 /*
  * For each motherboard family, we have a table of functions pointers
@@ -160,30 +160,17 @@
 {
 	struct macio_chip* macio = &macio_chips[0];
 	unsigned long flags;
-	struct pci_dev *pdev = NULL;
 
 	if (node == NULL)
 		return -ENODEV;
 
-	/* XXX FIXME: We should fix pci_device_from_OF_node here, and
-	 * get to a real pci_dev or we'll get into trouble with PCI
-	 * domains the day we get overlapping numbers (like if we ever
-	 * decide to show the HT root.
-	 * Note that we only get the slot when value is 0. This is called
-	 * early during boot with value 1 to enable all devices, at which
-	 * point, we don't yet have probed pci_find_slot, so it would fail
-	 * to look for the slot at this point.
-	 */
-	if (!value)
-		pdev = pci_find_slot(node->busno, node->devfn);
-
 	LOCK(flags);
 	if (value) {
 		MACIO_BIS(KEYLARGO_FCR1, K2_FCR1_GMAC_CLK_ENABLE);
 		mb();
 		k2_skiplist[0] = NULL;
 	} else {
-		k2_skiplist[0] = pdev;
+		k2_skiplist[0] = node;
 		mb();
 		MACIO_BIC(KEYLARGO_FCR1, K2_FCR1_GMAC_CLK_ENABLE);
 	}
@@ -198,30 +185,17 @@
 {
 	struct macio_chip* macio = &macio_chips[0];
 	unsigned long flags;
-	struct pci_dev *pdev = NULL;
 
-	/* XXX FIXME: We should fix pci_device_from_OF_node here, and
-	 * get to a real pci_dev or we'll get into trouble with PCI
-	 * domains the day we get overlapping numbers (like if we ever
-	 * decide to show the HT root
-	 * Note that we only get the slot when value is 0. This is called
-	 * early during boot with value 1 to enable all devices, at which
-	 * point, we don't yet have probed pci_find_slot, so it would fail
-	 * to look for the slot at this point.
-	 */
 	if (node == NULL)
 		return -ENODEV;
 
-	if (!value)
-		pdev = pci_find_slot(node->busno, node->devfn);
-
 	LOCK(flags);
 	if (value) {
 		MACIO_BIS(KEYLARGO_FCR1, K2_FCR1_FW_CLK_ENABLE);
 		mb();
 		k2_skiplist[1] = NULL;
 	} else {
-		k2_skiplist[1] = pdev;
+		k2_skiplist[1] = node;
 		mb();
 		MACIO_BIC(KEYLARGO_FCR1, K2_FCR1_FW_CLK_ENABLE);
 	}
diff -Nru a/arch/ppc64/kernel/pmac_nvram.c b/arch/ppc64/kernel/pmac_nvram.c
--- a/arch/ppc64/kernel/pmac_nvram.c	2005-03-01 23:39:19 -08:00
+++ b/arch/ppc64/kernel/pmac_nvram.c	2005-03-01 23:39:19 -08:00
@@ -75,7 +75,7 @@
 static volatile unsigned char *nvram_data;
 static int core99_bank = 0;
 // XXX Turn that into a sem
-static spinlock_t nv_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(nv_lock);
 
 extern int system_running;
 
diff -Nru a/arch/ppc64/kernel/pmac_pci.c b/arch/ppc64/kernel/pmac_pci.c
--- a/arch/ppc64/kernel/pmac_pci.c	2005-03-01 23:39:07 -08:00
+++ b/arch/ppc64/kernel/pmac_pci.c	2005-03-01 23:39:07 -08:00
@@ -43,7 +43,7 @@
  * assuming we won't have both UniNorth and Bandit */
 static int has_uninorth;
 static struct pci_controller *u3_agp;
-struct pci_dev *k2_skiplist[2];
+struct device_node *k2_skiplist[2];
 
 static int __init fixup_one_level_bus_range(struct device_node *node, int higher)
 {
@@ -233,15 +233,6 @@
 	struct device_node *busdn, *dn;
 	int i;
 
-	/*
-	 * When a device in K2 is powered down, we die on config
-	 * cycle accesses. Fix that here.
-	 */
-	for (i=0; i<2; i++)
-		if (k2_skiplist[i] && k2_skiplist[i]->bus == bus &&
-		    k2_skiplist[i]->devfn == devfn)
-			return 1;
-
 	/* We only allow config cycles to devices that are in OF device-tree
 	 * as we are apparently having some weird things going on with some
 	 * revs of K2 on recent G5s
@@ -256,6 +247,14 @@
 	if (dn == NULL)
 		return -1;
 
+	/*
+	 * When a device in K2 is powered down, we die on config
+	 * cycle accesses. Fix that here.
+	 */
+	for (i=0; i<2; i++)
+		if (k2_skiplist[i] == dn)
+			return 1;
+
 	return 0;
 }
 
@@ -664,10 +663,6 @@
 
 	for_each_pci_dev(dev)
 		pci_read_irq_line(dev);
-
-	pci_fix_bus_sysdata();
-
-	iommu_setup_u3();
 }
 
 static void __init pmac_fixup_phb_resources(void)
diff -Nru a/arch/ppc64/kernel/pmac_setup.c b/arch/ppc64/kernel/pmac_setup.c
--- a/arch/ppc64/kernel/pmac_setup.c	2005-03-01 23:38:52 -08:00
+++ b/arch/ppc64/kernel/pmac_setup.c	2005-03-01 23:38:52 -08:00
@@ -166,11 +166,6 @@
 	pmac_setup_smp();
 #endif
 
-	/* Setup the PCI DMA to "direct" by default. May be overriden
-	 * by iommu later on
-	 */
-	pci_dma_init_direct();
-
 	/* Lookup PCI hosts */
        	pmac_pci_init();
 
@@ -315,7 +310,9 @@
 	}
 
 	/* Setup interrupt mapping options */
-	naca->interrupt_controller = IC_OPEN_PIC;
+	ppc64_interrupt_controller = IC_OPEN_PIC;
+
+	iommu_init_early_u3();
 
 	DBG(" <- pmac_init_early\n");
 }
diff -Nru a/arch/ppc64/kernel/pmac_smp.c b/arch/ppc64/kernel/pmac_smp.c
--- a/arch/ppc64/kernel/pmac_smp.c	2005-03-01 23:38:52 -08:00
+++ b/arch/ppc64/kernel/pmac_smp.c	2005-03-01 23:38:52 -08:00
@@ -68,7 +68,7 @@
 
 static void (*pmac_tb_freeze)(int freeze);
 static struct device_node *pmac_tb_clock_chip_host;
-static spinlock_t timebase_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(timebase_lock);
 static unsigned long timebase;
 
 static void smp_core99_cypress_tb_freeze(int freeze)
diff -Nru a/arch/ppc64/kernel/ppc_ksyms.c b/arch/ppc64/kernel/ppc_ksyms.c
--- a/arch/ppc64/kernel/ppc_ksyms.c	2005-03-01 23:38:53 -08:00
+++ b/arch/ppc64/kernel/ppc_ksyms.c	2005-03-01 23:38:53 -08:00
@@ -67,11 +67,7 @@
 
 EXPORT_SYMBOL(__down_interruptible);
 EXPORT_SYMBOL(__up);
-EXPORT_SYMBOL(naca);
 EXPORT_SYMBOL(__down);
-#ifdef CONFIG_PPC_ISERIES
-EXPORT_SYMBOL(itLpNaca);
-#endif
 
 EXPORT_SYMBOL(csum_partial);
 EXPORT_SYMBOL(csum_partial_copy_generic);
@@ -118,7 +114,6 @@
 EXPORT_SYMBOL(start_thread);
 EXPORT_SYMBOL(kernel_thread);
 
-EXPORT_SYMBOL(flush_instruction_cache);
 EXPORT_SYMBOL(giveup_fpu);
 #ifdef CONFIG_ALTIVEC
 EXPORT_SYMBOL(giveup_altivec);
@@ -162,4 +157,3 @@
 EXPORT_SYMBOL(tb_ticks_per_usec);
 EXPORT_SYMBOL(paca);
 EXPORT_SYMBOL(cur_cpu_spec);
-EXPORT_SYMBOL(systemcfg);
diff -Nru a/arch/ppc64/kernel/proc_ppc64.c b/arch/ppc64/kernel/proc_ppc64.c
--- a/arch/ppc64/kernel/proc_ppc64.c	2005-03-01 23:39:08 -08:00
+++ b/arch/ppc64/kernel/proc_ppc64.c	2005-03-01 23:39:08 -08:00
@@ -25,8 +25,6 @@
 #include <linux/slab.h>
 #include <linux/kernel.h>
 
-#include <asm/naca.h>
-#include <asm/paca.h>
 #include <asm/systemcfg.h>
 #include <asm/rtas.h>
 #include <asm/uaccess.h>
@@ -58,26 +56,6 @@
 #endif
 
 /*
- * NOTE: since paca data is always in flux the values will never be a
- * consistant set.
- */
-static void __init proc_create_paca(struct proc_dir_entry *dir, int num)
-{
-	struct proc_dir_entry *ent;
-	struct paca_struct *lpaca = paca + num;
-	char buf[16];
-
-	sprintf(buf, "%02x", num);
-	ent = create_proc_entry(buf, S_IRUSR, dir);
-	if (ent) {
-		ent->nlink = 1;
-		ent->data = lpaca;
-		ent->size = 4096;
-		ent->proc_fops = &page_map_fops;
-	}
-}
-
-/*
  * Create the ppc64 and ppc64/rtas directories early. This allows us to
  * assume that they have been previously created in drivers.
  */
@@ -104,17 +82,8 @@
 
 static int __init proc_ppc64_init(void)
 {
-	unsigned long i;
 	struct proc_dir_entry *pde;
 
-	pde = create_proc_entry("ppc64/naca", S_IRUSR, NULL);
-	if (!pde)
-		return 1;
-	pde->nlink = 1;
-	pde->data = naca;
-	pde->size = 4096;
-	pde->proc_fops = &page_map_fops;
-
 	pde = create_proc_entry("ppc64/systemcfg", S_IFREG|S_IRUGO, NULL);
 	if (!pde)
 		return 1;
@@ -122,13 +91,6 @@
 	pde->data = systemcfg;
 	pde->size = 4096;
 	pde->proc_fops = &page_map_fops;
-
-	/* /proc/ppc64/paca/XX -- raw paca contents.  Only readable to root */
-	pde = proc_mkdir("ppc64/paca", NULL);
-	if (!pde)
-		return 1;
-	for_each_cpu(i)
-		proc_create_paca(pde, i);
 
 #ifdef CONFIG_PPC_PSERIES
 	if ((systemcfg->platform & PLATFORM_PSERIES))
diff -Nru a/arch/ppc64/kernel/process.c b/arch/ppc64/kernel/process.c
--- a/arch/ppc64/kernel/process.c	2005-03-01 23:38:58 -08:00
+++ b/arch/ppc64/kernel/process.c	2005-03-01 23:38:58 -08:00
@@ -35,7 +35,7 @@
 #include <linux/ptrace.h>
 #include <linux/kallsyms.h>
 #include <linux/interrupt.h>
-#include <linux/version.h>
+#include <linux/utsname.h>
 
 #include <asm/pgtable.h>
 #include <asm/uaccess.h>
@@ -214,23 +214,57 @@
 	return last;
 }
 
+static int instructions_to_print = 16;
+
+static void show_instructions(struct pt_regs *regs)
+{
+	int i;
+	unsigned long pc = regs->nip - (instructions_to_print * 3 / 4 *
+			sizeof(int));
+
+	printk("Instruction dump:");
+
+	for (i = 0; i < instructions_to_print; i++) {
+		int instr;
+
+		if (!(i % 8))
+			printk("\n");
+
+		if (((REGION_ID(pc) != KERNEL_REGION_ID) &&
+		     (REGION_ID(pc) != VMALLOC_REGION_ID)) ||
+		     __get_user(instr, (unsigned int *)pc)) {
+			printk("XXXXXXXX ");
+		} else {
+			if (regs->nip == pc)
+				printk("<%08x> ", instr);
+			else
+				printk("%08x ", instr);
+		}
+
+		pc += sizeof(int);
+	}
+
+	printk("\n");
+}
+
 void show_regs(struct pt_regs * regs)
 {
 	int i;
 	unsigned long trap;
 
-	printk("NIP: %016lX XER: %016lX LR: %016lX\n",
-	       regs->nip, regs->xer, regs->link);
+	printk("NIP: %016lX XER: %08X LR: %016lX CTR: %016lX\n",
+	       regs->nip, (unsigned int)regs->xer, regs->link, regs->ctr);
 	printk("REGS: %p TRAP: %04lx   %s  (%s)\n",
-	       regs, regs->trap, print_tainted(), UTS_RELEASE);
-	printk("MSR: %016lx EE: %01x PR: %01x FP: %01x ME: %01x IR/DR: %01x%01x\n",
+	       regs, regs->trap, print_tainted(), system_utsname.release);
+	printk("MSR: %016lx EE: %01x PR: %01x FP: %01x ME: %01x "
+	       "IR/DR: %01x%01x CR: %08X\n",
 	       regs->msr, regs->msr&MSR_EE ? 1 : 0, regs->msr&MSR_PR ? 1 : 0,
 	       regs->msr & MSR_FP ? 1 : 0,regs->msr&MSR_ME ? 1 : 0,
 	       regs->msr&MSR_IR ? 1 : 0,
-	       regs->msr&MSR_DR ? 1 : 0);
+	       regs->msr&MSR_DR ? 1 : 0,
+	       (unsigned int)regs->ccr);
 	trap = TRAP(regs);
-	if (trap == 0x300 || trap == 0x380 || trap == 0x600)
-		printk("DAR: %016lx, DSISR: %016lx\n", regs->dar, regs->dsisr);
+	printk("DAR: %016lx DSISR: %016lx\n", regs->dar, regs->dsisr);
 	printk("TASK: %p[%d] '%s' THREAD: %p",
 	       current, current->pid, current->comm, current->thread_info);
 
@@ -257,6 +291,8 @@
 	printk("LR [%016lx] ", regs->link);
 	print_symbol("%s\n", regs->link);
 	show_stack(current, (unsigned long *)regs->gpr[1]);
+	if (!user_mode(regs))
+		show_instructions(regs);
 }
 
 void exit_thread(void)
diff -Nru a/arch/ppc64/kernel/prom.c b/arch/ppc64/kernel/prom.c
--- a/arch/ppc64/kernel/prom.c	2005-03-01 23:39:08 -08:00
+++ b/arch/ppc64/kernel/prom.c	2005-03-01 23:39:08 -08:00
@@ -44,7 +44,6 @@
 #include <asm/system.h>
 #include <asm/mmu.h>
 #include <asm/pgtable.h>
-#include <asm/naca.h>
 #include <asm/pci.h>
 #include <asm/iommu.h>
 #include <asm/bootinfo.h>
@@ -96,7 +95,7 @@
 /* use when traversing tree through the allnext, child, sibling,
  * or parent members of struct device_node.
  */
-static rwlock_t devtree_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(devtree_lock);
 
 /* export that to outside world */
 struct device_node *of_chosen;
@@ -557,7 +556,7 @@
 
 	DBG(" -> finish_device_tree\n");
 
-	if (naca->interrupt_controller == IC_INVALID) {
+	if (ppc64_interrupt_controller == IC_INVALID) {
 		DBG("failed to configure interrupt controller type\n");
 		panic("failed to configure interrupt controller type\n");
 	}
@@ -718,6 +717,7 @@
 				dad->next->sibling = np;
 			dad->next = np;
 		}
+		kref_init(&np->kref);
 	}
 	while(1) {
 		u32 sz, noff;
@@ -844,12 +844,12 @@
 
 	/* On LPAR, look for the first ibm,pft-size property for the  hash table size
 	 */
-	if (systemcfg->platform == PLATFORM_PSERIES_LPAR && naca->pftSize == 0) {
+	if (systemcfg->platform == PLATFORM_PSERIES_LPAR && ppc64_pft_size == 0) {
 		u32 *pft_size;
 		pft_size = (u32 *)get_flat_dt_prop(node, "ibm,pft-size", NULL);
 		if (pft_size != NULL) {
 			/* pft_size[0] is the NUMA CEC cookie */
-			naca->pftSize = pft_size[1];
+			ppc64_pft_size = pft_size[1];
 		}
 	}
 
@@ -1018,7 +1018,7 @@
 	initial_boot_params = params;
 
 	/* By default, hash size is not set */
-	naca->pftSize = 0;
+	ppc64_pft_size = 0;
 
 	/* Retreive various informations from the /chosen node of the
 	 * device-tree, including the platform type, initrd location and
@@ -1047,7 +1047,7 @@
 	/* If hash size wasn't obtained above, we calculate it now based on
 	 * the total RAM size
 	 */
-	if (naca->pftSize == 0) {
+	if (ppc64_pft_size == 0) {
 		unsigned long rnd_mem_size, pteg_count;
 
 		/* round mem_size up to next power of 2 */
@@ -1056,12 +1056,12 @@
 			rnd_mem_size <<= 1;
 
 		/* # pages / 2 */
-		pteg_count = (rnd_mem_size >> (12 + 1));
+		pteg_count = max(rnd_mem_size >> (12 + 1), 1UL << 11);
 
-		naca->pftSize = __ilog2(pteg_count << 7);
+		ppc64_pft_size = __ilog2(pteg_count << 7);
 	}
 
-	DBG("Hash pftSize: %x\n", (int)naca->pftSize);
+	DBG("Hash pftSize: %x\n", (int)ppc64_pft_size);
 	DBG(" <- early_init_devtree()\n");
 }
 
@@ -1476,24 +1476,31 @@
  *	@node:	Node to inc refcount, NULL is supported to
  *		simplify writing of callers
  *
- *	Returns the node itself or NULL if gone.
+ *	Returns node.
  */
 struct device_node *of_node_get(struct device_node *node)
 {
-	if (node && !OF_IS_STALE(node)) {
-		atomic_inc(&node->_users);
-		return node;
-	}
-	return NULL;
+	if (node)
+		kref_get(&node->kref);
+	return node;
 }
 EXPORT_SYMBOL(of_node_get);
 
+static inline struct device_node * kref_to_device_node(struct kref *kref)
+{
+	return container_of(kref, struct device_node, kref);
+}
+
 /**
- *	of_node_cleanup - release a dynamically allocated node
- *	@arg:  Node to be released
+ *	of_node_release - release a dynamically allocated node
+ *	@kref:  kref element of the node to be released
+ *
+ *	In of_node_put() this function is passed to kref_put()
+ *	as the destructor.
  */
-static void of_node_cleanup(struct device_node *node)
+static void of_node_release(struct kref *kref)
 {
+	struct device_node *node = kref_to_device_node(kref);
 	struct property *prop = node->properties;
 
 	if (!OF_IS_DYNAMIC(node))
@@ -1519,19 +1526,8 @@
  */
 void of_node_put(struct device_node *node)
 {
-	if (!node)
-		return;
-
-	WARN_ON(0 == atomic_read(&node->_users));
-
-	if (OF_IS_STALE(node)) {
-		if (atomic_dec_and_test(&node->_users)) {
-			of_node_cleanup(node);
-			return;
-		}
-	}
-	else
-		atomic_dec(&node->_users);
+	if (node)
+		kref_put(&node->kref, of_node_release);
 }
 EXPORT_SYMBOL(of_node_put);
 
@@ -1744,17 +1740,6 @@
 		node->devfn = (regs[0] >> 8) & 0xff;
 	}
 
-	/* fixing up iommu_table */
-
-#ifdef CONFIG_PPC_PSERIES
-	if (strcmp(node->name, "pci") == 0 &&
-	    get_property(node, "ibm,dma-window", NULL)) {
-		node->bussubno = node->busno;
-		iommu_devnode_init_pSeries(node);
-	} else
-		node->iommu_table = parent->iommu_table;
-#endif /* CONFIG_PPC_PSERIES */
-
 out:
 	of_node_put(parent);
 	return err;
@@ -1785,6 +1770,7 @@
 
 	np->properties = proplist;
 	OF_MARK_DYNAMIC(np);
+	kref_init(&np->kref);
 	of_node_get(np);
 	np->parent = derive_parent(path);
 	if (!np->parent) {
@@ -1821,8 +1807,9 @@
 }
 
 /*
- * Remove an OF device node from the system.
- * Caller should have already "gotten" np.
+ * "Unplug" a node from the device tree.  The caller must hold
+ * a reference to the node.  The memory associated with the node
+ * is not freed until its refcount goes to zero.
  */
 int of_remove_node(struct device_node *np)
 {
@@ -1840,7 +1827,6 @@
 	of_cleanup_node(np);
 
 	write_lock(&devtree_lock);
-	OF_MARK_STALE(np);
 	remove_node_proc_entries(np);
 	if (allnodes == np)
 		allnodes = np->allnext;
@@ -1865,6 +1851,7 @@
 	}
 	write_unlock(&devtree_lock);
 	of_node_put(parent);
+	of_node_put(np); /* Must decrement the refcount */
 	return 0;
 }
 
diff -Nru a/arch/ppc64/kernel/prom_init.c b/arch/ppc64/kernel/prom_init.c
--- a/arch/ppc64/kernel/prom_init.c	2005-03-01 23:39:16 -08:00
+++ b/arch/ppc64/kernel/prom_init.c	2005-03-01 23:39:16 -08:00
@@ -43,7 +43,6 @@
 #include <asm/system.h>
 #include <asm/mmu.h>
 #include <asm/pgtable.h>
-#include <asm/naca.h>
 #include <asm/pci.h>
 #include <asm/iommu.h>
 #include <asm/bootinfo.h>
@@ -846,7 +845,7 @@
 
 		prom_debug("TCE table: %s\n", path);
 		prom_debug("\tnode = 0x%x\n", node);
-		prom_debug("\tbase = 0x%x\n", vbase);
+		prom_debug("\tbase = 0x%x\n", base);
 		prom_debug("\tsize = 0x%x\n", minsize);
 
 		/* Initialize the table to have a one-to-one mapping
diff -Nru a/arch/ppc64/kernel/ptrace.c b/arch/ppc64/kernel/ptrace.c
--- a/arch/ppc64/kernel/ptrace.c	2005-03-01 23:39:09 -08:00
+++ b/arch/ppc64/kernel/ptrace.c	2005-03-01 23:39:09 -08:00
@@ -313,10 +313,10 @@
 		do_syscall_trace();
 }
 
-void do_syscall_trace_leave(void)
+void do_syscall_trace_leave(struct pt_regs *regs)
 {
 	if (unlikely(current->audit_context))
-		audit_syscall_exit(current, 0);	/* FIXME: pass pt_regs */
+		audit_syscall_exit(current, regs->result);
 
 	if ((test_thread_flag(TIF_SYSCALL_TRACE)
 	     || test_thread_flag(TIF_SINGLESTEP))
diff -Nru a/arch/ppc64/kernel/ras.c b/arch/ppc64/kernel/ras.c
--- a/arch/ppc64/kernel/ras.c	2005-03-01 23:38:54 -08:00
+++ b/arch/ppc64/kernel/ras.c	2005-03-01 23:38:54 -08:00
@@ -53,7 +53,14 @@
 #include <asm/ppcdebug.h>
 
 static unsigned char ras_log_buf[RTAS_ERROR_LOG_MAX];
-static spinlock_t ras_log_buf_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(ras_log_buf_lock);
+
+char mce_data_buf[RTAS_ERROR_LOG_MAX]
+;
+/* This is true if we are using the firmware NMI handler (typically LPAR) */
+extern int fwnmi_active;
+
+extern void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr);
 
 static int ras_get_sensor_state_token;
 static int ras_check_exception_token;
@@ -233,4 +240,117 @@
 
 	spin_unlock(&ras_log_buf_lock);
 	return IRQ_HANDLED;
+}
+
+/* Get the error information for errors coming through the
+ * FWNMI vectors.  The pt_regs' r3 will be updated to reflect
+ * the actual r3 if possible, and a ptr to the error log entry
+ * will be returned if found.
+ *
+ * The mce_data_buf does not have any locks or protection around it,
+ * if a second machine check comes in, or a system reset is done
+ * before we have logged the error, then we will get corruption in the
+ * error log.  This is preferable over holding off on calling
+ * ibm,nmi-interlock which would result in us checkstopping if a
+ * second machine check did come in.
+ */
+static struct rtas_error_log *fwnmi_get_errinfo(struct pt_regs *regs)
+{
+	unsigned long errdata = regs->gpr[3];
+	struct rtas_error_log *errhdr = NULL;
+	unsigned long *savep;
+
+	if ((errdata >= 0x7000 && errdata < 0x7fff0) ||
+	    (errdata >= rtas.base && errdata < rtas.base + rtas.size - 16)) {
+		savep = __va(errdata);
+		regs->gpr[3] = savep[0];	/* restore original r3 */
+		memset(mce_data_buf, 0, RTAS_ERROR_LOG_MAX);
+		memcpy(mce_data_buf, (char *)(savep + 1), RTAS_ERROR_LOG_MAX);
+		errhdr = (struct rtas_error_log *)mce_data_buf;
+	} else {
+		printk("FWNMI: corrupt r3\n");
+	}
+	return errhdr;
+}
+
+/* Call this when done with the data returned by FWNMI_get_errinfo.
+ * It will release the saved data area for other CPUs in the
+ * partition to receive FWNMI errors.
+ */
+static void fwnmi_release_errinfo(void)
+{
+	int ret = rtas_call(rtas_token("ibm,nmi-interlock"), 0, 1, NULL);
+	if (ret != 0)
+		printk("FWNMI: nmi-interlock failed: %d\n", ret);
+}
+
+void pSeries_system_reset_exception(struct pt_regs *regs)
+{
+	if (fwnmi_active) {
+		struct rtas_error_log *errhdr = fwnmi_get_errinfo(regs);
+		if (errhdr) {
+			/* XXX Should look at FWNMI information */
+		}
+		fwnmi_release_errinfo();
+	}
+}
+
+/*
+ * See if we can recover from a machine check exception.
+ * This is only called on power4 (or above) and only via
+ * the Firmware Non-Maskable Interrupts (fwnmi) handler
+ * which provides the error analysis for us.
+ *
+ * Return 1 if corrected (or delivered a signal).
+ * Return 0 if there is nothing we can do.
+ */
+static int recover_mce(struct pt_regs *regs, struct rtas_error_log * err)
+{
+	int nonfatal = 0;
+
+	if (err->disposition == RTAS_DISP_FULLY_RECOVERED) {
+		/* Platform corrected itself */
+		nonfatal = 1;
+	} else if ((regs->msr & MSR_RI) &&
+		   user_mode(regs) &&
+		   err->severity == RTAS_SEVERITY_ERROR_SYNC &&
+		   err->disposition == RTAS_DISP_NOT_RECOVERED &&
+		   err->target == RTAS_TARGET_MEMORY &&
+		   err->type == RTAS_TYPE_ECC_UNCORR &&
+		   !(current->pid == 0 || current->pid == 1)) {
+		/* Kill off a user process with an ECC error */
+		printk(KERN_ERR "MCE: uncorrectable ecc error for pid %d\n",
+		       current->pid);
+		/* XXX something better for ECC error? */
+		_exception(SIGBUS, regs, BUS_ADRERR, regs->nip);
+		nonfatal = 1;
+	}
+
+ 	log_error((char *)err, ERR_TYPE_RTAS_LOG, !nonfatal);
+
+	return nonfatal;
+}
+
+/*
+ * Handle a machine check.
+ *
+ * Note that on Power 4 and beyond Firmware Non-Maskable Interrupts (fwnmi)
+ * should be present.  If so the handler which called us tells us if the
+ * error was recovered (never true if RI=0).
+ *
+ * On hardware prior to Power 4 these exceptions were asynchronous which
+ * means we can't tell exactly where it occurred and so we can't recover.
+ */
+int pSeries_machine_check_exception(struct pt_regs *regs)
+{
+	struct rtas_error_log *errp;
+
+	if (fwnmi_active) {
+		errp = fwnmi_get_errinfo(regs);
+		fwnmi_release_errinfo();
+		if (errp && recover_mce(regs, errp))
+			return 1;
+	}
+
+	return 0;
 }
diff -Nru a/arch/ppc64/kernel/rtas-proc.c b/arch/ppc64/kernel/rtas-proc.c
--- a/arch/ppc64/kernel/rtas-proc.c	2005-03-01 23:38:57 -08:00
+++ b/arch/ppc64/kernel/rtas-proc.c	2005-03-01 23:38:57 -08:00
@@ -31,6 +31,7 @@
 #include <asm/rtas.h>
 #include <asm/machdep.h> /* for ppc_md */
 #include <asm/time.h>
+#include <asm/systemcfg.h>
 
 /* Token for Sensors */
 #define KEY_SWITCH		0x0001
@@ -51,7 +52,6 @@
 #define IBM_VOLTAGE		0x232a /* 9002 */
 #define IBM_DRCONNECTOR		0x232b /* 9003 */
 #define IBM_POWERSUPPLY		0x232c /* 9004 */
-#define IBM_INTQUEUE		0x232d /* 9005 */
 
 /* Status return values */
 #define SENSOR_CRITICAL_HIGH	13
@@ -106,7 +106,6 @@
 #define DR_ACTION		0x2329 /* 9001 */
 #define DR_INDICATOR		0x232a /* 9002 */
 /* 9003 - 9004: Vendor specific */
-#define GLOBAL_INTERRUPT_QUEUE	0x232d /* 9005 */
 /* 9006 - 9999: Vendor specific */
 
 /* other */
@@ -552,7 +551,6 @@
 						"No current flow" };
 	const char * ibm_drconnector[]     = { "Empty", "Present", "Unusable", 
 						"Exchange" };
-	const char * ibm_intqueue[]        = { "Disabled", "Enabled" };
 
 	int have_strings = 0;
 	int num_states = 0;
@@ -663,15 +661,6 @@
 			break;
 		case IBM_POWERSUPPLY:
 			seq_printf(m, "Powersupply:\t");
-			break;
-		case IBM_INTQUEUE:
-			seq_printf(m, "Interrupt queue:\t");
-			num_states = sizeof(ibm_intqueue) / sizeof(char *);
-			if (state < num_states) {
-				seq_printf(m, "%s\t", 
-						ibm_intqueue[state]);
-				have_strings = 1;
-			}
 			break;
 		default:
 			seq_printf(m,  "Unknown sensor (type %d), ignoring it\n",
diff -Nru a/arch/ppc64/kernel/rtas.c b/arch/ppc64/kernel/rtas.c
--- a/arch/ppc64/kernel/rtas.c	2005-03-01 23:38:53 -08:00
+++ b/arch/ppc64/kernel/rtas.c	2005-03-01 23:38:53 -08:00
@@ -29,6 +29,7 @@
 #include <asm/udbg.h>
 #include <asm/delay.h>
 #include <asm/uaccess.h>
+#include <asm/systemcfg.h>
 
 struct flash_block_list_header rtas_firmware_flash_list = {0, NULL};
 
@@ -40,7 +41,7 @@
 
 char rtas_err_buf[RTAS_ERROR_LOG_MAX];
 
-spinlock_t rtas_data_buf_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(rtas_data_buf_lock);
 char rtas_data_buf[RTAS_DATA_BUF_SIZE]__page_aligned;
 unsigned long rtas_rmo_buf;
 
diff -Nru a/arch/ppc64/kernel/rtas_flash.c b/arch/ppc64/kernel/rtas_flash.c
--- a/arch/ppc64/kernel/rtas_flash.c	2005-03-01 23:39:16 -08:00
+++ b/arch/ppc64/kernel/rtas_flash.c	2005-03-01 23:39:16 -08:00
@@ -105,7 +105,7 @@
 	unsigned int update_results;	/* Update results token */
 };
 
-static spinlock_t flash_file_open_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(flash_file_open_lock);
 static struct proc_dir_entry *firmware_flash_pde;
 static struct proc_dir_entry *firmware_update_pde;
 static struct proc_dir_entry *validate_pde;
diff -Nru a/arch/ppc64/kernel/rtasd.c b/arch/ppc64/kernel/rtasd.c
--- a/arch/ppc64/kernel/rtasd.c	2005-03-01 23:38:54 -08:00
+++ b/arch/ppc64/kernel/rtasd.c	2005-03-01 23:38:54 -08:00
@@ -26,6 +26,7 @@
 #include <asm/prom.h>
 #include <asm/nvram.h>
 #include <asm/atomic.h>
+#include <asm/systemcfg.h>
 
 #if 0
 #define DEBUG(A...)	printk(KERN_ERR A)
@@ -33,7 +34,7 @@
 #define DEBUG(A...)
 #endif
 
-static spinlock_t rtasd_log_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(rtasd_log_lock);
 
 DECLARE_WAIT_QUEUE_HEAD(rtas_log_wait);
 
@@ -485,8 +486,8 @@
 
 	/* 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 RTAS on system\n");
+		if (systemcfg->platform & PLATFORM_PSERIES)
+			printk(KERN_ERR "rtasd: no event-scan on system\n");
 		return 1;
 	}
 
diff -Nru a/arch/ppc64/kernel/setup.c b/arch/ppc64/kernel/setup.c
--- a/arch/ppc64/kernel/setup.c	2005-03-01 23:38:57 -08:00
+++ b/arch/ppc64/kernel/setup.c	2005-03-01 23:38:57 -08:00
@@ -17,6 +17,7 @@
 #include <linux/string.h>
 #include <linux/sched.h>
 #include <linux/init.h>
+#include <linux/kernel.h>
 #include <linux/reboot.h>
 #include <linux/delay.h>
 #include <linux/initrd.h>
@@ -41,7 +42,6 @@
 #include <asm/elf.h>
 #include <asm/machdep.h>
 #include <asm/iSeries/LparData.h>
-#include <asm/naca.h>
 #include <asm/paca.h>
 #include <asm/ppcdebug.h>
 #include <asm/time.h>
@@ -54,6 +54,9 @@
 #include <asm/rtas.h>
 #include <asm/iommu.h>
 #include <asm/serial.h>
+#include <asm/cache.h>
+#include <asm/page.h>
+#include <asm/mmu.h>
 
 #ifdef DEBUG
 #define DBG(fmt...) udbg_printf(fmt)
@@ -89,7 +92,6 @@
 #endif
 
 /* extern void *stab; */
-extern HTAB htab_data;
 extern unsigned long klimit;
 
 extern void mm_init_ppc64(void);
@@ -110,6 +112,11 @@
 int boot_cpuid = 0;
 int boot_cpuid_phys = 0;
 dev_t boot_dev;
+u64 ppc64_pft_size;
+u64 ppc64_debug_switch;
+
+struct ppc64_caches ppc64_caches;
+EXPORT_SYMBOL_GPL(ppc64_caches);
 
 /*
  * These are used in binfmt_elf.c to put aux entries on the stack
@@ -156,7 +163,7 @@
  */
 void __init ppcdbg_initialize(void)
 {
-	naca->debug_switch = PPC_DEBUG_DEFAULT; /* | PPCDBG_BUSWALK | */
+	ppc64_debug_switch = PPC_DEBUG_DEFAULT; /* | PPCDBG_BUSWALK | */
 	/* PPCDBG_PHBINIT | PPCDBG_MM | PPCDBG_MMINIT | PPCDBG_TCEINIT | PPCDBG_TCE */;
 }
 
@@ -394,7 +401,7 @@
 	DBG(" -> early_setup()\n");
 
 	/*
-	 * Fill the default DBG level in naca (do we want to keep
+	 * Fill the default DBG level (do we want to keep
 	 * that old mecanism around forever ?)
 	 */
 	ppcdbg_initialize();
@@ -448,17 +455,17 @@
 
 
 /*
- * Initialize some remaining members of the naca and systemcfg structures
+ * Initialize some remaining members of the ppc64_caches and systemcfg structures
  * (at least until we get rid of them completely). This is mostly some
  * cache informations about the CPU that will be used by cache flush
  * routines and/or provided to userland
  */
-static void __init initialize_naca(void)
+static void __init initialize_cache_info(void)
 {
 	struct device_node *np;
 	unsigned long num_cpus = 0;
 
-	DBG(" -> initialize_naca()\n");
+	DBG(" -> initialize_cache_info()\n");
 
 	for (np = NULL; (np = of_find_node_by_type(np, "cpu"));) {
 		num_cpus += 1;
@@ -489,15 +496,15 @@
 			lsizep = (u32 *) get_property(np, dc, NULL);
 			if (lsizep != NULL)
 				lsize = *lsizep;
-
 			if (sizep == 0 || lsizep == 0)
 				DBG("Argh, can't find dcache properties ! "
 				    "sizep: %p, lsizep: %p\n", sizep, lsizep);
 
-			systemcfg->dCacheL1Size = size;
-			systemcfg->dCacheL1LineSize = lsize;
-			naca->dCacheL1LogLineSize = __ilog2(lsize);
-			naca->dCacheL1LinesPerPage = PAGE_SIZE/(lsize);
+			systemcfg->dcache_size = ppc64_caches.dsize = size;
+			systemcfg->dcache_line_size =
+				ppc64_caches.dline_size = lsize;
+			ppc64_caches.log_dline_size = __ilog2(lsize);
+			ppc64_caches.dlines_per_page = PAGE_SIZE / lsize;
 
 			size = 0;
 			lsize = cur_cpu_spec->icache_bsize;
@@ -511,11 +518,11 @@
 				DBG("Argh, can't find icache properties ! "
 				    "sizep: %p, lsizep: %p\n", sizep, lsizep);
 
-			systemcfg->iCacheL1Size = size;
-			systemcfg->iCacheL1LineSize = lsize;
-			naca->iCacheL1LogLineSize = __ilog2(lsize);
-			naca->iCacheL1LinesPerPage = PAGE_SIZE/(lsize);
-
+			systemcfg->icache_size = ppc64_caches.isize = size;
+			systemcfg->icache_line_size =
+				ppc64_caches.iline_size = lsize;
+			ppc64_caches.log_iline_size = __ilog2(lsize);
+			ppc64_caches.ilines_per_page = PAGE_SIZE / lsize;
 		}
 	}
 
@@ -525,7 +532,7 @@
 	systemcfg->version.minor = SYSTEMCFG_MINOR;
 	systemcfg->processor = mfspr(SPRN_PVR);
 
-	DBG(" <- initialize_naca()\n");
+	DBG(" <- initialize_cache_info()\n");
 }
 
 static void __init check_for_initrd(void)
@@ -586,7 +593,7 @@
 	unflatten_device_tree();
 
 	/*
-	 * Fill the naca & systemcfg structures with informations
+	 * Fill the ppc64_caches & systemcfg structures with informations
 	 * retreived from the device-tree. Need to be called before
 	 * finish_device_tree() since the later requires some of the
 	 * informations filled up here to properly parse the interrupt
@@ -595,7 +602,7 @@
 	 * routines like flush_icache_range (used by the hash init
 	 * later on).
 	 */
-	initialize_naca();
+	initialize_cache_info();
 
 #ifdef CONFIG_PPC_PSERIES
 	/*
@@ -656,18 +663,19 @@
 	printk("Starting Linux PPC64 %s\n", UTS_RELEASE);
 
 	printk("-----------------------------------------------------\n");
-	printk("naca                          = 0x%p\n", naca);
-	printk("naca->pftSize                 = 0x%lx\n", naca->pftSize);
-	printk("naca->debug_switch            = 0x%lx\n", naca->debug_switch);
-	printk("naca->interrupt_controller    = 0x%ld\n", naca->interrupt_controller);
+	printk("ppc64_pft_size                = 0x%lx\n", ppc64_pft_size);
+	printk("ppc64_debug_switch            = 0x%lx\n", ppc64_debug_switch);
+	printk("ppc64_interrupt_controller    = 0x%ld\n", ppc64_interrupt_controller);
 	printk("systemcfg                     = 0x%p\n", systemcfg);
 	printk("systemcfg->platform           = 0x%x\n", systemcfg->platform);
 	printk("systemcfg->processorCount     = 0x%lx\n", systemcfg->processorCount);
 	printk("systemcfg->physicalMemorySize = 0x%lx\n", systemcfg->physicalMemorySize);
-	printk("systemcfg->dCacheL1LineSize   = 0x%x\n", systemcfg->dCacheL1LineSize);
-	printk("systemcfg->iCacheL1LineSize   = 0x%x\n", systemcfg->iCacheL1LineSize);
-	printk("htab_data.htab                = 0x%p\n", htab_data.htab);
-	printk("htab_data.num_ptegs           = 0x%lx\n", htab_data.htab_num_ptegs);
+	printk("ppc64_caches.dcache_line_size = 0x%x\n",
+			ppc64_caches.dline_size);
+	printk("ppc64_caches.icache_line_size = 0x%x\n",
+			ppc64_caches.iline_size);
+	printk("htab_address                  = 0x%p\n", htab_address);
+	printk("htab_hash_mask                = 0x%lx\n", htab_hash_mask);
 	printk("-----------------------------------------------------\n");
 
 	mm_init_ppc64();
@@ -988,7 +996,6 @@
  */
 void __init setup_arch(char **cmdline_p)
 {
-	extern int panic_timeout;
 	extern void do_init_bootmem(void);
 
 	ppc64_boot_msg(0x12, "Setup Arch");
@@ -1000,8 +1007,8 @@
 	 * Systems with OF can look in the properties on the cpu node(s)
 	 * for a possibly more accurate value.
 	 */
-	dcache_bsize = systemcfg->dCacheL1LineSize; 
-	icache_bsize = systemcfg->iCacheL1LineSize; 
+	dcache_bsize = ppc64_caches.dline_size;
+	icache_bsize = ppc64_caches.iline_size;
 
 	/* reboot on panic */
 	panic_timeout = 180;
@@ -1147,7 +1154,8 @@
 static struct plat_serial8250_port serial_ports[MAX_LEGACY_SERIAL_PORTS+1];
 static unsigned int old_serial_count;
 
-void __init generic_find_legacy_serial_ports(unsigned int *default_speed)
+void __init generic_find_legacy_serial_ports(u64 *physport,
+		unsigned int *default_speed)
 {
 	struct device_node *np;
 	u32 *sizeprop;
@@ -1165,7 +1173,7 @@
 
 	DBG(" -> generic_find_legacy_serial_port()\n");
 
-	naca->serialPortAddr = 0;
+	*physport = 0;
 	if (default_speed)
 		*default_speed = 0;
 
@@ -1287,7 +1295,7 @@
 				io_base = (io_base << 32) | rangesp[4];
 		}
 		if (io_base != 0) {
-			naca->serialPortAddr = io_base + reg->address;
+			*physport = io_base + reg->address;
 			if (default_speed && spd)
 				*default_speed = *spd;
 		}
@@ -1337,6 +1345,7 @@
 
 void cpu_die(void)
 {
+	idle_task_exit();
 	if (ppc_md.cpu_die)
 		ppc_md.cpu_die();
 	local_irq_disable();
diff -Nru a/arch/ppc64/kernel/signal.c b/arch/ppc64/kernel/signal.c
--- a/arch/ppc64/kernel/signal.c	2005-03-01 23:38:44 -08:00
+++ b/arch/ppc64/kernel/signal.c	2005-03-01 23:38:44 -08:00
@@ -67,7 +67,7 @@
 	struct siginfo info;
 	/* 64 bit ABI allows for 288 bytes below sp before decrementing it. */
 	char abigap[288];
-};
+} __attribute__ ((aligned (16)));
 
 
 /*
@@ -254,7 +254,7 @@
 			newsp = (current->sas_ss_sp + current->sas_ss_size);
 	}
 
-        return (void __user *)((newsp - frame_size) & -8ul);
+        return (void __user *)((newsp - frame_size) & -16ul);
 }
 
 /*
diff -Nru a/arch/ppc64/kernel/signal32.c b/arch/ppc64/kernel/signal32.c
--- a/arch/ppc64/kernel/signal32.c	2005-03-01 23:39:16 -08:00
+++ b/arch/ppc64/kernel/signal32.c	2005-03-01 23:39:16 -08:00
@@ -72,7 +72,7 @@
  *
  */
 struct rt_sigframe32 {
-	struct compat_siginfo	info;
+	compat_siginfo_t	info;
 	struct ucontext32	uc;
 	/*
 	 * Programs using the rs6000/xcoff abi can save up to 19 gp
@@ -341,7 +341,6 @@
  *       sigpending               sys32_rt_sigpending
  *       sigprocmask              sys32_rt_sigprocmask
  *       sigreturn                sys32_rt_sigreturn
- *       sigtimedwait             sys32_rt_sigtimedwait
  *       sigqueueinfo             sys32_rt_sigqueueinfo
  *       sigsuspend               sys32_rt_sigsuspend
  *
@@ -445,9 +444,9 @@
 }
 
 
-static long copy_siginfo_to_user32(compat_siginfo_t __user *d, siginfo_t *s)
+int copy_siginfo_to_user32(struct compat_siginfo __user *d, siginfo_t *s)
 {
-	long err;
+	int err;
 
 	if (!access_ok (VERIFY_WRITE, d, sizeof(*d)))
 		return -EFAULT;
@@ -498,35 +497,6 @@
 		break;
 	}
 	return err;
-}
-
-long sys32_rt_sigtimedwait(compat_sigset_t __user *uthese, compat_siginfo_t __user *uinfo,
-		struct compat_timespec __user *uts, compat_size_t sigsetsize)
-{
-	sigset_t s;
-	compat_sigset_t s32;
-	struct timespec t;
-	int ret;
-	mm_segment_t old_fs = get_fs();
-	siginfo_t info;
-
-	if (copy_from_user(&s32, uthese, sizeof(compat_sigset_t)))
-		return -EFAULT;
-	sigset_from_compat(&s, &s32);
-	if (uts && get_compat_timespec(&t, uts))
-		return -EFAULT;
-	set_fs(KERNEL_DS);
-	/* The __user pointer casts are valid because of the set_fs() */
-	ret = sys_rt_sigtimedwait((sigset_t __user *) &s,
-			uinfo ? (siginfo_t __user *) &info : NULL,
-			uts ? (struct timespec __user *) &t : NULL,
-			sigsetsize);
-	set_fs(old_fs);
-	if (ret >= 0 && uinfo) {
-		if (copy_siginfo_to_user32(uinfo, &info))
-			return -EFAULT;
-	}
-	return ret;
 }
 
 /*
diff -Nru a/arch/ppc64/kernel/smp.c b/arch/ppc64/kernel/smp.c
--- a/arch/ppc64/kernel/smp.c	2005-03-01 23:39:08 -08:00
+++ b/arch/ppc64/kernel/smp.c	2005-03-01 23:39:08 -08:00
@@ -22,9 +22,7 @@
 #include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/interrupt.h>
-#include <linux/kernel_stat.h>
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/spinlock.h>
@@ -38,13 +36,10 @@
 #include <asm/irq.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
-#include <asm/io.h>
 #include <asm/prom.h>
 #include <asm/smp.h>
-#include <asm/naca.h>
 #include <asm/paca.h>
 #include <asm/time.h>
-#include <asm/ppcdebug.h>
 #include <asm/machdep.h>
 #include <asm/cputable.h>
 #include <asm/system.h>
@@ -59,7 +54,6 @@
 #endif
 
 int smp_threads_ready;
-unsigned long cache_decay_ticks;
 
 cpumask_t cpu_possible_map = CPU_MASK_NONE;
 cpumask_t cpu_online_map = CPU_MASK_NONE;
@@ -74,15 +68,10 @@
 
 extern unsigned char stab_array[];
 
-extern int cpu_idle(void *unused);
 void smp_call_function_interrupt(void);
 
 int smt_enabled_at_boot = 1;
 
-/* Low level assembly function used to backup CPU 0 state */
-extern void __save_cpu_setup(void);
-
-
 #ifdef CONFIG_PPC_MULTIPLATFORM
 void smp_mpic_message_pass(int target, int msg)
 {
@@ -157,11 +146,6 @@
 	}
 }
 
-void smp_local_timer_interrupt(struct pt_regs * regs)
-{
-	update_process_times(user_mode(regs));
-}
-
 void smp_message_recv(int msg, struct pt_regs *regs)
 {
 	switch(msg) {
@@ -218,7 +202,7 @@
  * static memory requirements. It also looks cleaner.
  * Stolen from the i386 version.
  */
-static spinlock_t call_lock __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
+static  __cacheline_aligned_in_smp DEFINE_SPINLOCK(call_lock);
 
 static struct call_data_struct {
 	void (*func) (void *info);
@@ -475,8 +459,7 @@
 		 * hotplug case.  Wait five seconds.
 		 */
 		for (c = 25; c && !cpu_callin_map[cpu]; c--) {
-			set_current_state(TASK_UNINTERRUPTIBLE);
-			schedule_timeout(HZ/5);
+			msleep(200);
 		}
 #endif
 
@@ -514,16 +497,14 @@
 	if (smp_ops->take_timebase)
 		smp_ops->take_timebase();
 
-	if (smp_ops->late_setup_cpu)
-		smp_ops->late_setup_cpu(cpu);
-
 	spin_lock(&call_lock);
 	cpu_set(cpu, cpu_online_map);
 	spin_unlock(&call_lock);
 
 	local_irq_enable();
 
-	return cpu_idle(NULL);
+	cpu_idle();
+	return 0;
 }
 
 int setup_profiling_timer(unsigned int multiplier)
@@ -544,9 +525,6 @@
 	
 	smp_ops->setup_cpu(boot_cpuid);
 
-	/* XXX fix this, xics currently relies on it - Anton */
-	smp_threads_ready = 1;
-
 	set_cpus_allowed(current, old_mask);
 
 	/*
@@ -557,3 +535,19 @@
 	 */
 	cpu_present_map = cpu_possible_map;
 }
+
+#ifdef CONFIG_HOTPLUG_CPU
+int __cpu_disable(void)
+{
+	if (smp_ops->cpu_disable)
+		return smp_ops->cpu_disable();
+
+	return -ENOSYS;
+}
+
+void __cpu_die(unsigned int cpu)
+{
+	if (smp_ops->cpu_die)
+		smp_ops->cpu_die(cpu);
+}
+#endif
diff -Nru a/arch/ppc64/kernel/sys_ppc32.c b/arch/ppc64/kernel/sys_ppc32.c
--- a/arch/ppc64/kernel/sys_ppc32.c	2005-03-01 23:39:08 -08:00
+++ b/arch/ppc64/kernel/sys_ppc32.c	2005-03-01 23:39:08 -08:00
@@ -73,6 +73,7 @@
 #include <asm/ppcdebug.h>
 #include <asm/time.h>
 #include <asm/mmu_context.h>
+#include <asm/systemcfg.h>
 
 #include "pci.h"
 
@@ -491,6 +492,7 @@
 	return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL);
 }
 
+#ifdef CONFIG_SYSVIPC
 long sys32_ipc(u32 call, u32 first, u32 second, u32 third, compat_uptr_t ptr,
 	       u32 fifth)
 {
@@ -555,6 +557,7 @@
 
 	return -ENOSYS;
 }
+#endif
 
 /* Note: it is necessary to treat out_fd and in_fd as unsigned ints, 
  * with the corresponding cast to a signed int to insure that the 
@@ -1103,6 +1106,7 @@
 	return sys_umask((int)mask);
 }
 
+#ifdef CONFIG_SYSCTL
 struct __sysctl_args32 {
 	u32 name;
 	int nlen;
@@ -1152,23 +1156,7 @@
 	}
 	return error;
 }
-
-asmlinkage long sys32_time(compat_time_t __user * tloc)
-{
-	compat_time_t secs;
-
-	struct timeval tv;
-
-	do_gettimeofday( &tv );
-	secs = tv.tv_sec;
-
-	if (tloc) {
-		if (put_user(secs,tloc))
-			secs = -EFAULT;
-	}
-
-	return secs;
-}
+#endif
 
 asmlinkage int sys32_olduname(struct oldold_utsname __user * name)
 {
diff -Nru a/arch/ppc64/kernel/syscalls.c b/arch/ppc64/kernel/syscalls.c
--- a/arch/ppc64/kernel/syscalls.c	2005-03-01 23:39:08 -08:00
+++ b/arch/ppc64/kernel/syscalls.c	2005-03-01 23:39:08 -08:00
@@ -57,7 +57,8 @@
  * This is really horribly ugly.
  */
 asmlinkage int 
-sys_ipc (uint call, int first, int second, long third, void __user *ptr, long fifth)
+sys_ipc (uint call, int first, unsigned long second, long third,
+	 void __user *ptr, long fifth)
 {
 	int version, ret;
 
@@ -67,15 +68,16 @@
 	ret = -ENOSYS;
 	switch (call) {
 	case SEMOP:
-		ret = sys_semtimedop (first, (struct sembuf __user *)ptr, second,
-				      NULL);
+		ret = sys_semtimedop(first, (struct sembuf __user *)ptr,
+				      (unsigned)second, NULL);
 		break;
 	case SEMTIMEDOP:
-		ret = sys_semtimedop (first, (struct sembuf __user *)ptr, second,
+		ret = sys_semtimedop(first, (struct sembuf __user *)ptr,
+				      (unsigned)second,
 				      (const struct timespec __user *) fifth);
 		break;
 	case SEMGET:
-		ret = sys_semget (first, second, third);
+		ret = sys_semget (first, (int)second, third);
 		break;
 	case SEMCTL: {
 		union semun fourth;
@@ -85,11 +87,12 @@
 			break;
 		if ((ret = get_user(fourth.__pad, (void __user * __user *)ptr)))
 			break;
-		ret = sys_semctl (first, second, third, fourth);
+		ret = sys_semctl(first, (int)second, third, fourth);
 		break;
 	}
 	case MSGSND:
-		ret = sys_msgsnd (first, (struct msgbuf __user *) ptr, second, third);
+		ret = sys_msgsnd(first, (struct msgbuf __user *)ptr,
+				  (size_t)second, third);
 		break;
 	case MSGRCV:
 		switch (version) {
@@ -103,27 +106,29 @@
 						(struct ipc_kludge __user *) ptr,
 						sizeof (tmp)) ? -EFAULT : 0))
 				break;
-			ret = sys_msgrcv (first, tmp.msgp, second, tmp.msgtyp,
-					  third);
+			ret = sys_msgrcv(first, tmp.msgp, (size_t) second,
+					  tmp.msgtyp, third);
 			break;
 		}
 		default:
 			ret = sys_msgrcv (first, (struct msgbuf __user *) ptr,
-					  second, fifth, third);
+					  (size_t)second, fifth, third);
 			break;
 		}
 		break;
 	case MSGGET:
-		ret = sys_msgget ((key_t) first, second);
+		ret = sys_msgget ((key_t)first, (int)second);
 		break;
 	case MSGCTL:
-		ret = sys_msgctl (first, second, (struct msqid_ds __user *) ptr);
+		ret = sys_msgctl(first, (int)second,
+				  (struct msqid_ds __user *)ptr);
 		break;
 	case SHMAT:
 		switch (version) {
 		default: {
 			ulong raddr;
-			ret = do_shmat (first, (char __user *) ptr, second, &raddr);
+			ret = do_shmat(first, (char __user *) ptr,
+					(int)second, &raddr);
 			if (ret)
 				break;
 			ret = put_user (raddr, (ulong __user *) third);
@@ -133,8 +138,8 @@
 			ret = -EINVAL;
 			if (!segment_eq(get_fs(), get_ds()))
 				break;
-			ret = do_shmat (first, (char __user *) ptr, second,
-					 (ulong *) third);
+			ret = do_shmat(first, (char __user *)ptr,
+					(int)second, (ulong *)third);
 			break;
 		}
 		break;
@@ -142,10 +147,11 @@
 		ret = sys_shmdt ((char __user *)ptr);
 		break;
 	case SHMGET:
-		ret = sys_shmget (first, second, third);
+		ret = sys_shmget (first, (size_t)second, third);
 		break;
 	case SHMCTL:
-		ret = sys_shmctl (first, second, (struct shmid_ds __user *) ptr);
+		ret = sys_shmctl(first, (int)second,
+				  (struct shmid_ds __user *)ptr);
 		break;
 	}
 
diff -Nru a/arch/ppc64/kernel/sysfs.c b/arch/ppc64/kernel/sysfs.c
--- a/arch/ppc64/kernel/sysfs.c	2005-03-01 23:38:52 -08:00
+++ b/arch/ppc64/kernel/sysfs.c	2005-03-01 23:38:52 -08:00
@@ -7,14 +7,21 @@
 #include <linux/sched.h>
 #include <linux/module.h>
 #include <linux/nodemask.h>
+#include <linux/cpumask.h>
+#include <linux/notifier.h>
 
 #include <asm/current.h>
 #include <asm/processor.h>
 #include <asm/cputable.h>
 #include <asm/hvcall.h>
 #include <asm/prom.h>
+#include <asm/systemcfg.h>
+#include <asm/paca.h>
+#include <asm/lppaca.h>
 
 
+static DEFINE_PER_CPU(struct cpu, cpu_devices);
+
 /* SMT stuff */
 
 #ifdef CONFIG_PPC_MULTIPLATFORM
@@ -153,10 +160,8 @@
 
 #ifdef CONFIG_PPC_PSERIES
 	/* instruct hypervisor to maintain PMCs */
-	if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR) {
-		char *ptr = (char *)&paca[smp_processor_id()].lppaca;
-		ptr[0xBB] = 1;
-	}
+	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
@@ -255,8 +260,18 @@
 static SYSDEV_ATTR(pmc8, 0600, show_pmc8, store_pmc8);
 static SYSDEV_ATTR(purr, 0600, show_purr, NULL);
 
-static void __init register_cpu_pmc(struct sys_device *s)
+static void register_cpu_online(unsigned int cpu)
 {
+	struct cpu *c = &per_cpu(cpu_devices, cpu);
+	struct sys_device *s = &c->sysdev;
+
+#ifndef CONFIG_PPC_ISERIES
+	if (cur_cpu_spec->cpu_features & CPU_FTR_SMT)
+		sysdev_create_file(s, &attr_smt_snooze_delay);
+#endif
+
+	/* PMC stuff */
+
 	sysdev_create_file(s, &attr_mmcr0);
 	sysdev_create_file(s, &attr_mmcr1);
 
@@ -279,6 +294,65 @@
 		sysdev_create_file(s, &attr_purr);
 }
 
+#ifdef CONFIG_HOTPLUG_CPU
+static void unregister_cpu_online(unsigned int cpu)
+{
+	struct cpu *c = &per_cpu(cpu_devices, cpu);
+	struct sys_device *s = &c->sysdev;
+
+	BUG_ON(c->no_control);
+
+#ifndef CONFIG_PPC_ISERIES
+	if (cur_cpu_spec->cpu_features & CPU_FTR_SMT)
+		sysdev_remove_file(s, &attr_smt_snooze_delay);
+#endif
+
+	/* PMC stuff */
+
+	sysdev_remove_file(s, &attr_mmcr0);
+	sysdev_remove_file(s, &attr_mmcr1);
+
+	if (cur_cpu_spec->cpu_features & CPU_FTR_MMCRA)
+		sysdev_remove_file(s, &attr_mmcra);
+
+	sysdev_remove_file(s, &attr_pmc1);
+	sysdev_remove_file(s, &attr_pmc2);
+	sysdev_remove_file(s, &attr_pmc3);
+	sysdev_remove_file(s, &attr_pmc4);
+	sysdev_remove_file(s, &attr_pmc5);
+	sysdev_remove_file(s, &attr_pmc6);
+
+	if (cur_cpu_spec->cpu_features & CPU_FTR_PMC8) {
+		sysdev_remove_file(s, &attr_pmc7);
+		sysdev_remove_file(s, &attr_pmc8);
+	}
+
+	if (cur_cpu_spec->cpu_features & CPU_FTR_SMT)
+		sysdev_remove_file(s, &attr_purr);
+}
+#endif /* CONFIG_HOTPLUG_CPU */
+
+static int __devinit sysfs_cpu_notify(struct notifier_block *self,
+				      unsigned long action, void *hcpu)
+{
+	unsigned int cpu = (unsigned int)(long)hcpu;
+
+	switch (action) {
+	case CPU_ONLINE:
+		register_cpu_online(cpu);
+		break;
+#ifdef CONFIG_HOTPLUG_CPU
+	case CPU_DEAD:
+		unregister_cpu_online(cpu);
+		break;
+#endif
+	}
+	return NOTIFY_OK;
+}
+
+static struct notifier_block __devinitdata sysfs_cpu_nb = {
+	.notifier_call	= sysfs_cpu_notify,
+};
 
 /* NUMA stuff */
 
@@ -308,19 +382,15 @@
 }
 #endif
 
-
-/* Only valid if CPU is online. */
+/* Only valid if CPU is present. */
 static ssize_t show_physical_id(struct sys_device *dev, char *buf)
 {
 	struct cpu *cpu = container_of(dev, struct cpu, sysdev);
 
-	return sprintf(buf, "%u\n", get_hard_smp_processor_id(cpu->sysdev.id));
+	return sprintf(buf, "%d\n", get_hard_smp_processor_id(cpu->sysdev.id));
 }
 static SYSDEV_ATTR(physical_id, 0444, show_physical_id, NULL);
 
-
-static DEFINE_PER_CPU(struct cpu, cpu_devices);
-
 static int __init topology_init(void)
 {
 	int cpu;
@@ -328,6 +398,8 @@
 
 	register_nodes();
 
+	register_cpu_notifier(&sysfs_cpu_nb);
+
 	for_each_cpu(cpu) {
 		struct cpu *c = &per_cpu(cpu_devices, cpu);
 
@@ -341,19 +413,19 @@
 		 * CPU.  For instance, the boot cpu might never be valid
 		 * for hotplugging.
 		 */
+#ifdef CONFIG_HOTPLUG_CPU
 		if (systemcfg->platform != PLATFORM_PSERIES_LPAR)
+#endif
 			c->no_control = 1;
 
-		register_cpu(c, cpu, parent);
-
-		register_cpu_pmc(&c->sysdev);
+		if (cpu_online(cpu) || (c->no_control == 0)) {
+			register_cpu(c, cpu, parent);
 
-		sysdev_create_file(&c->sysdev, &attr_physical_id);
+			sysdev_create_file(&c->sysdev, &attr_physical_id);
+		}
 
-#ifndef CONFIG_PPC_ISERIES
-		if (cur_cpu_spec->cpu_features & CPU_FTR_SMT)
-			sysdev_create_file(&c->sysdev, &attr_smt_snooze_delay);
-#endif
+		if (cpu_online(cpu))
+			register_cpu_online(cpu);
 	}
 
 	return 0;
diff -Nru a/arch/ppc64/kernel/time.c b/arch/ppc64/kernel/time.c
--- a/arch/ppc64/kernel/time.c	2005-03-01 23:39:16 -08:00
+++ b/arch/ppc64/kernel/time.c	2005-03-01 23:39:16 -08:00
@@ -66,8 +66,7 @@
 #include <asm/ppcdebug.h>
 #include <asm/prom.h>
 #include <asm/sections.h>
-
-void smp_local_timer_interrupt(struct pt_regs *);
+#include <asm/systemcfg.h>
 
 u64 jiffies_64 __cacheline_aligned_in_smp = INITIAL_JIFFIES;
 
@@ -92,7 +91,7 @@
 unsigned long tb_to_xs;
 unsigned      tb_to_us;
 unsigned long processor_freq;
-spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(rtc_lock);
 
 unsigned long tb_to_ns_scale;
 unsigned long tb_to_ns_shift;
@@ -143,16 +142,54 @@
         }
 }
 
+/*
+ * This version of gettimeofday has microsecond resolution.
+ */
+static inline void __do_gettimeofday(struct timeval *tv, unsigned long tb_val)
+{
+	unsigned long sec, usec, tb_ticks;
+	unsigned long xsec, tb_xsec;
+	struct gettimeofday_vars * temp_varp;
+	unsigned long temp_tb_to_xs, temp_stamp_xsec;
+
+	/*
+	 * These calculations are faster (gets rid of divides)
+	 * if done in units of 1/2^20 rather than microseconds.
+	 * The conversion to microseconds at the end is done
+	 * without a divide (and in fact, without a multiply)
+	 */
+	tb_ticks = tb_val - do_gtod.tb_orig_stamp;
+	temp_varp = do_gtod.varp;
+	temp_tb_to_xs = temp_varp->tb_to_xs;
+	temp_stamp_xsec = temp_varp->stamp_xsec;
+	tb_xsec = mulhdu( tb_ticks, temp_tb_to_xs );
+	xsec = temp_stamp_xsec + tb_xsec;
+	sec = xsec / XSEC_PER_SEC;
+	xsec -= sec * XSEC_PER_SEC;
+	usec = (xsec * USEC_PER_SEC)/XSEC_PER_SEC;
+
+	tv->tv_sec = sec;
+	tv->tv_usec = usec;
+}
+
+void do_gettimeofday(struct timeval *tv)
+{
+	__do_gettimeofday(tv, get_tb());
+}
+
+EXPORT_SYMBOL(do_gettimeofday);
+
 /* Synchronize xtime with do_gettimeofday */ 
 
-static __inline__ void timer_sync_xtime( unsigned long cur_tb )
+static inline void timer_sync_xtime(unsigned long cur_tb)
 {
 	struct timeval my_tv;
 
-	if ( cur_tb > next_xtime_sync_tb ) {
+	if (cur_tb > next_xtime_sync_tb) {
 		next_xtime_sync_tb = cur_tb + xtime_sync_interval;
-		do_gettimeofday( &my_tv );
-		if ( xtime.tv_sec <= my_tv.tv_sec ) {
+		__do_gettimeofday(&my_tv, cur_tb);
+
+		if (xtime.tv_sec <= my_tv.tv_sec) {
 			xtime.tv_sec = my_tv.tv_sec;
 			xtime.tv_nsec = my_tv.tv_usec * 1000;
 		}
@@ -229,7 +266,7 @@
 /*
  * For iSeries shared processors, we have to let the hypervisor
  * set the hardware decrementer.  We set a virtual decrementer
- * in the ItLpPaca and call the hypervisor if the virtual
+ * in the lppaca and call the hypervisor if the virtual
  * decrementer is less than the current value in the hardware
  * decrementer. (almost always the new decrementer value will
  * be greater than the current hardware decementer so the hypervisor
@@ -255,11 +292,9 @@
 	profile_tick(CPU_PROFILING, regs);
 #endif
 
-	lpaca->lppaca.xIntDword.xFields.xDecrInt = 0;
+	lpaca->lppaca.int_dword.fields.decr_int = 0;
 
 	while (lpaca->next_jiffy_update_tb <= (cur_tb = get_tb())) {
-
-#ifdef CONFIG_SMP
 		/*
 		 * We cannot disable the decrementer, so in the period
 		 * between this cpu's being marked offline in cpu_online_map
@@ -268,8 +303,7 @@
 		 * is the case.
 		 */
 		if (!cpu_is_offline(cpu))
-			smp_local_timer_interrupt(regs);
-#endif
+			update_process_times(user_mode(regs));
 		/*
 		 * No need to check whether cpu is offline here; boot_cpuid
 		 * should have been fixed up by now.
@@ -278,10 +312,7 @@
 			write_seqlock(&xtime_lock);
 			tb_last_stamp = lpaca->next_jiffy_update_tb;
 			do_timer(regs);
-#ifndef CONFIG_SMP
-			update_process_times(user_mode(regs));
-#endif
-			timer_sync_xtime( cur_tb );
+			timer_sync_xtime(lpaca->next_jiffy_update_tb);
 			timer_check_rtc();
 			write_sequnlock(&xtime_lock);
 			if ( adjusting_time && (time_adjust == 0) )
@@ -320,36 +351,6 @@
 	return mulhdu(get_tb(), tb_to_ns_scale) << tb_to_ns_shift;
 }
 
-/*
- * This version of gettimeofday has microsecond resolution.
- */
-void do_gettimeofday(struct timeval *tv)
-{
-        unsigned long sec, usec, tb_ticks;
-	unsigned long xsec, tb_xsec;
-	struct gettimeofday_vars * temp_varp;
-	unsigned long temp_tb_to_xs, temp_stamp_xsec;
-
-	/* These calculations are faster (gets rid of divides)
-	 * if done in units of 1/2^20 rather than microseconds.
-	 * The conversion to microseconds at the end is done
-	 * without a divide (and in fact, without a multiply) */
-	tb_ticks = get_tb() - do_gtod.tb_orig_stamp;
-	temp_varp = do_gtod.varp;
-	temp_tb_to_xs = temp_varp->tb_to_xs;
-	temp_stamp_xsec = temp_varp->stamp_xsec;
-	tb_xsec = mulhdu( tb_ticks, temp_tb_to_xs );
-	xsec = temp_stamp_xsec + tb_xsec;
-	sec = xsec / XSEC_PER_SEC;
-	xsec -= sec * XSEC_PER_SEC;
-	usec = (xsec * USEC_PER_SEC)/XSEC_PER_SEC;
-
-        tv->tv_sec = sec;
-        tv->tv_usec = usec;
-}
-
-EXPORT_SYMBOL(do_gettimeofday);
-
 int do_settimeofday(struct timespec *tv)
 {
 	time_t wtm_sec, new_sec = tv->tv_sec;
@@ -424,60 +425,6 @@
 }
 
 EXPORT_SYMBOL(do_settimeofday);
-
-/*
- * This function is a copy of the architecture independent function
- * but which calls do_settimeofday rather than setting the xtime
- * fields itself.  This way, the fields which are used for 
- * do_settimeofday get updated too.
- */
-long ppc64_sys32_stime(int __user * tptr)
-{
-	int value;
-	struct timespec myTimeval;
-	int err;
-
-	if (get_user(value, tptr))
-		return -EFAULT;
-
-	myTimeval.tv_sec = value;
-	myTimeval.tv_nsec = 0;
-
-	err = security_settime(&myTimeval, NULL);
-	if (err)
-		return err;
-
-	do_settimeofday(&myTimeval);
-
-	return 0;
-}
-
-/*
- * This function is a copy of the architecture independent function
- * but which calls do_settimeofday rather than setting the xtime
- * fields itself.  This way, the fields which are used for 
- * do_settimeofday get updated too.
- */
-long ppc64_sys_stime(long __user * tptr)
-{
-	long value;
-	struct timespec myTimeval;
-	int err;
-
-	if (get_user(value, tptr))
-		return -EFAULT;
-
-	myTimeval.tv_sec = value;
-	myTimeval.tv_nsec = 0;
-
-	err = security_settime(&myTimeval, NULL);
-	if (err)
-		return err;
-
-	do_settimeofday(&myTimeval);
-
-	return 0;
-}
 
 void __init time_init(void)
 {
diff -Nru a/arch/ppc64/kernel/traps.c b/arch/ppc64/kernel/traps.c
--- a/arch/ppc64/kernel/traps.c	2005-03-01 23:38:57 -08:00
+++ b/arch/ppc64/kernel/traps.c	2005-03-01 23:38:57 -08:00
@@ -29,6 +29,8 @@
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/delay.h>
+#include <asm/kdebug.h>
 
 #include <asm/pgtable.h>
 #include <asm/uaccess.h>
@@ -37,11 +39,8 @@
 #include <asm/processor.h>
 #include <asm/ppcdebug.h>
 #include <asm/rtas.h>
-
-#ifdef CONFIG_PPC_PSERIES
-/* This is true if we are using the firmware NMI handler (typically LPAR) */
-extern int fwnmi_active;
-#endif
+#include <asm/systemcfg.h>
+#include <asm/machdep.h>
 
 #ifdef CONFIG_DEBUGGER
 int (*__debugger)(struct pt_regs *regs);
@@ -61,11 +60,25 @@
 EXPORT_SYMBOL(__debugger_fault_handler);
 #endif
 
+struct notifier_block *ppc64_die_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(&ppc64_die_chain, nb);
+	spin_unlock_irqrestore(&die_notifier_lock, flags);
+	return err;
+}
+
 /*
  * Trap & Exception support
  */
 
-static spinlock_t die_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(die_lock);
 
 int die(const char *str, struct pt_regs *regs, long err)
 {
@@ -115,6 +128,7 @@
 	}
 	if (nl)
 		printk("\n");
+	print_modules();
 	show_regs(regs);
 	bust_spinlocks(0);
 	spin_unlock_irq(&die_lock);
@@ -124,8 +138,7 @@
 
 	if (panic_on_oops) {
 		printk(KERN_EMERG "Fatal exception: panic in 5 seconds\n");
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(5 * HZ);
+		ssleep(5);
 		panic("Fatal exception");
 	}
 	do_exit(SIGSEGV);
@@ -133,8 +146,7 @@
 	return 0;
 }
 
-static void
-_exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
+void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
 {
 	siginfo_t info;
 
@@ -150,53 +162,11 @@
 	force_sig_info(signr, &info, current);
 }
 
-#ifdef CONFIG_PPC_PSERIES
-/* Get the error information for errors coming through the
- * FWNMI vectors.  The pt_regs' r3 will be updated to reflect
- * the actual r3 if possible, and a ptr to the error log entry
- * will be returned if found.
- */
-static struct rtas_error_log *FWNMI_get_errinfo(struct pt_regs *regs)
+void system_reset_exception(struct pt_regs *regs)
 {
-	unsigned long errdata = regs->gpr[3];
-	struct rtas_error_log *errhdr = NULL;
-	unsigned long *savep;
-
-	if ((errdata >= 0x7000 && errdata < 0x7fff0) ||
-	    (errdata >= rtas.base && errdata < rtas.base + rtas.size - 16)) {
-		savep = __va(errdata);
-		regs->gpr[3] = savep[0];	/* restore original r3 */
-		errhdr = (struct rtas_error_log *)(savep + 1);
-	} else {
-		printk("FWNMI: corrupt r3\n");
-	}
-	return errhdr;
-}
-
-/* Call this when done with the data returned by FWNMI_get_errinfo.
- * It will release the saved data area for other CPUs in the
- * partition to receive FWNMI errors.
- */
-static void FWNMI_release_errinfo(void)
-{
-	int ret = rtas_call(rtas_token("ibm,nmi-interlock"), 0, 1, NULL);
-	if (ret != 0)
-		printk("FWNMI: nmi-interlock failed: %d\n", ret);
-}
-#endif
-
-void
-SystemResetException(struct pt_regs *regs)
-{
-#ifdef CONFIG_PPC_PSERIES
-	if (fwnmi_active) {
-		struct rtas_error_log *errhdr = FWNMI_get_errinfo(regs);
-		if (errhdr) {
-			/* XXX Should look at FWNMI information */
-		}
-		FWNMI_release_errinfo();
-	}
-#endif
+	/* See if any machine dependent calls */
+	if (ppc_md.system_reset_exception)
+		ppc_md.system_reset_exception(regs);
 
 	die("System Reset", regs, 0);
 
@@ -207,64 +177,16 @@
 	/* What should we do here? We could issue a shutdown or hard reset. */
 }
 
-#ifdef CONFIG_PPC_PSERIES
-/* 
- * See if we can recover from a machine check exception.
- * This is only called on power4 (or above) and only via
- * the Firmware Non-Maskable Interrupts (fwnmi) handler
- * which provides the error analysis for us.
- *
- * Return 1 if corrected (or delivered a signal).
- * Return 0 if there is nothing we can do.
- */
-static int recover_mce(struct pt_regs *regs, struct rtas_error_log err)
+void machine_check_exception(struct pt_regs *regs)
 {
-	if (err.disposition == RTAS_DISP_FULLY_RECOVERED) {
-		/* Platform corrected itself */
-		return 1;
-	} else if ((regs->msr & MSR_RI) &&
-		   user_mode(regs) &&
-		   err.severity == RTAS_SEVERITY_ERROR_SYNC &&
-		   err.disposition == RTAS_DISP_NOT_RECOVERED &&
-		   err.target == RTAS_TARGET_MEMORY &&
-		   err.type == RTAS_TYPE_ECC_UNCORR &&
-		   !(current->pid == 0 || current->pid == 1)) {
-		/* Kill off a user process with an ECC error */
-		printk(KERN_ERR "MCE: uncorrectable ecc error for pid %d\n",
-		       current->pid);
-		/* XXX something better for ECC error? */
-		_exception(SIGBUS, regs, BUS_ADRERR, regs->nip);
-		return 1;
-	}
-	return 0;
-}
-#endif
+	int recover = 0;
 
-/*
- * Handle a machine check.
- *
- * Note that on Power 4 and beyond Firmware Non-Maskable Interrupts (fwnmi)
- * should be present.  If so the handler which called us tells us if the
- * error was recovered (never true if RI=0).
- *
- * On hardware prior to Power 4 these exceptions were asynchronous which
- * means we can't tell exactly where it occurred and so we can't recover.
- */
-void
-MachineCheckException(struct pt_regs *regs)
-{
-#ifdef CONFIG_PPC_PSERIES
-	struct rtas_error_log err, *errp;
+	/* See if any machine dependent calls */
+	if (ppc_md.machine_check_exception)
+		recover = ppc_md.machine_check_exception(regs);
 
-	if (fwnmi_active) {
-		errp = FWNMI_get_errinfo(regs);
-		if (errp)
-			err = *errp;
-		FWNMI_release_errinfo();	/* frees errp */
-		if (errp && recover_mce(regs, err))
-			return;
-	}
-#endif
+	if (recover)
+		return;
 
 	if (debugger_fault_handler(regs))
 		return;
@@ -275,8 +197,7 @@
 		panic("Unrecoverable Machine check");
 }
 
-void
-UnknownException(struct pt_regs *regs)
+void unknown_exception(struct pt_regs *regs)
 {
 	printk("Bad trap at PC: %lx, SR: %lx, vector=%lx\n",
 	       regs->nip, regs->msr, regs->trap);
@@ -284,19 +205,23 @@
 	_exception(SIGTRAP, regs, 0, 0);
 }
 
-void
-InstructionBreakpointException(struct pt_regs *regs)
+void instruction_breakpoint_exception(struct pt_regs *regs)
 {
+	if (notify_die(DIE_IABR_MATCH, "iabr_match", regs, 5,
+					5, SIGTRAP) == NOTIFY_STOP)
+		return;
 	if (debugger_iabr_match(regs))
 		return;
 	_exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip);
 }
 
-void
-SingleStepException(struct pt_regs *regs)
+void single_step_exception(struct pt_regs *regs)
 {
 	regs->msr &= ~MSR_SE;  /* Turn off 'trace' bit */
 
+	if (notify_die(DIE_SSTEP, "single_step", regs, 5,
+					5, SIGTRAP) == NOTIFY_STOP)
+		return;
 	if (debugger_sstep(regs))
 		return;
 
@@ -312,7 +237,7 @@
 static inline void emulate_single_step(struct pt_regs *regs)
 {
 	if (regs->msr & MSR_SE)
-		SingleStepException(regs);
+		single_step_exception(regs);
 }
 
 static void parse_fpe(struct pt_regs *regs)
@@ -419,7 +344,7 @@
 #define module_find_bug(x)	NULL
 #endif
 
-static struct bug_entry *find_bug(unsigned long bugaddr)
+struct bug_entry *find_bug(unsigned long bugaddr)
 {
 	struct bug_entry *bug;
 
@@ -429,7 +354,7 @@
 	return module_find_bug(bugaddr);
 }
 
-int
+static int
 check_bug_trap(struct pt_regs *regs)
 {
 	struct bug_entry *bug;
@@ -456,9 +381,11 @@
 	return 0;
 }
 
-void
-ProgramCheckException(struct pt_regs *regs)
+void program_check_exception(struct pt_regs *regs)
 {
+	if (debugger_fault_handler(regs))
+		return;
+
 	if (regs->msr & 0x100000) {
 		/* IEEE FP exception */
 		parse_fpe(regs);
@@ -470,6 +397,9 @@
 	} else if (regs->msr & 0x20000) {
 		/* trap exception */
 
+		if (notify_die(DIE_BPT, "breakpoint", regs, 5,
+					5, SIGTRAP) == NOTIFY_STOP)
+			return;
 		if (debugger_bpt(regs))
 			return;
 
@@ -498,14 +428,14 @@
 	}
 }
 
-void KernelFPUnavailableException(struct pt_regs *regs)
+void kernel_fp_unavailable_exception(struct pt_regs *regs)
 {
 	printk(KERN_EMERG "Unrecoverable FP Unavailable Exception "
 			  "%lx at %lx\n", regs->trap, regs->nip);
 	die("Unrecoverable FP Unavailable Exception", regs, SIGABRT);
 }
 
-void AltivecUnavailableException(struct pt_regs *regs)
+void altivec_unavailable_exception(struct pt_regs *regs)
 {
 #ifndef CONFIG_ALTIVEC
 	if (user_mode(regs)) {
@@ -521,9 +451,6 @@
 }
 
 /* Ensure exceptions are disabled */
-#define MMCR0_PMXE      (1UL << (31 - 5))
-#define MMCR0_PMAO      (1UL << (31 - 24))
-
 static void dummy_perf(struct pt_regs *regs)
 {
 	unsigned int mmcr0 = mfspr(SPRN_MMCR0);
@@ -536,14 +463,12 @@
 
 EXPORT_SYMBOL(perf_irq);
 
-void
-PerformanceMonitorException(struct pt_regs *regs)
+void performance_monitor_exception(struct pt_regs *regs)
 {
 	perf_irq(regs);
 }
 
-void
-AlignmentException(struct pt_regs *regs)
+void alignment_exception(struct pt_regs *regs)
 {
 	int fixed;
 
@@ -571,8 +496,7 @@
 }
 
 #ifdef CONFIG_ALTIVEC
-void
-AltivecAssistException(struct pt_regs *regs)
+void altivec_assist_exception(struct pt_regs *regs)
 {
 	int err;
 	siginfo_t info;
diff -Nru a/arch/ppc64/kernel/u3_iommu.c b/arch/ppc64/kernel/u3_iommu.c
--- a/arch/ppc64/kernel/u3_iommu.c	2005-03-01 23:39:17 -08:00
+++ b/arch/ppc64/kernel/u3_iommu.c	2005-03-01 23:39:17 -08:00
@@ -91,6 +91,7 @@
 static unsigned int dart_emptyval;
 
 static struct iommu_table iommu_table_u3;
+static int iommu_table_u3_inited;
 static int dart_dirty;
 
 #define DBG(...)
@@ -192,7 +193,6 @@
 	unsigned int regword;
 	unsigned int i;
 	unsigned long tmp;
-	struct page *p;
 
 	if (dart_tablebase == 0 || dart_tablesize == 0) {
 		printk(KERN_INFO "U3-DART: table not allocated, using direct DMA\n");
@@ -209,16 +209,15 @@
 	 * that to work around what looks like a problem with the HT bridge
 	 * prefetching into invalid pages and corrupting data
 	 */
-	tmp = __get_free_pages(GFP_ATOMIC, 1);
-	if (tmp == 0)
-		panic("U3-DART: Cannot allocate spare page !");
-	dart_emptyval = DARTMAP_VALID |
-		((virt_to_abs(tmp) >> PAGE_SHIFT) & DARTMAP_RPNMASK);
+	tmp = lmb_alloc(PAGE_SIZE, PAGE_SIZE);
+	if (!tmp)
+		panic("U3-DART: Cannot allocate spare page!");
+	dart_emptyval = DARTMAP_VALID | ((tmp >> PAGE_SHIFT) & DARTMAP_RPNMASK);
 
 	/* Map in DART registers. FIXME: Use device node to get base address */
 	dart = ioremap(DART_BASE, 0x7000);
 	if (dart == NULL)
-		panic("U3-DART: Cannot map registers !");
+		panic("U3-DART: Cannot map registers!");
 
 	/* Set initial control register contents: table base, 
 	 * table size and enable bit
@@ -227,7 +226,6 @@
 		((dart_tablebase >> PAGE_SHIFT) << DARTCNTL_BASE_SHIFT) |
 		(((dart_tablesize >> PAGE_SHIFT) & DARTCNTL_SIZE_MASK)
 				 << DARTCNTL_SIZE_SHIFT);
-	p = virt_to_page(dart_tablebase);
 	dart_vbase = ioremap(virt_to_abs(dart_tablebase), dart_tablesize);
 
 	/* Fill initial table */
@@ -240,35 +238,67 @@
 	/* Invalidate DART to get rid of possible stale TLBs */
 	dart_tlb_invalidate_all();
 
+	printk(KERN_INFO "U3/CPC925 DART IOMMU initialized\n");
+
+	return 0;
+}
+
+static void iommu_table_u3_setup(void)
+{
 	iommu_table_u3.it_busno = 0;
-	
-	/* Units of tce entries */
 	iommu_table_u3.it_offset = 0;
-	
-	/* Set the tce table size - measured in pages */
-	iommu_table_u3.it_size = dart_tablesize >> PAGE_SHIFT;
+	/* it_size is in number of entries */
+	iommu_table_u3.it_size = dart_tablesize / sizeof(u32);
 
 	/* Initialize the common IOMMU code */
 	iommu_table_u3.it_base = (unsigned long)dart_vbase;
 	iommu_table_u3.it_index = 0;
 	iommu_table_u3.it_blocksize = 1;
-	iommu_table_u3.it_entrysize = sizeof(u32);
 	iommu_init_table(&iommu_table_u3);
 
 	/* Reserve the last page of the DART to avoid possible prefetch
 	 * past the DART mapped area
 	 */
-	set_bit(iommu_table_u3.it_mapsize - 1, iommu_table_u3.it_map);
+	set_bit(iommu_table_u3.it_size - 1, iommu_table_u3.it_map);
+}
 
-	printk(KERN_INFO "U3/CPC925 DART IOMMU initialized\n");
+static void iommu_dev_setup_u3(struct pci_dev *dev)
+{
+	struct device_node *dn;
 
-	return 0;
+	/* We only have one iommu table on the mac for now, which makes
+	 * things simple. Setup all PCI devices to point to this table
+	 *
+	 * We must use pci_device_to_OF_node() to make sure that
+	 * we get the real "final" pointer to the device in the
+	 * pci_dev sysdata and not the temporary PHB one
+	 */
+	dn = pci_device_to_OF_node(dev);
+
+	if (dn)
+		dn->iommu_table = &iommu_table_u3;
+}
+
+static void iommu_bus_setup_u3(struct pci_bus *bus)
+{
+	struct device_node *dn;
+
+	if (!iommu_table_u3_inited) {
+		iommu_table_u3_inited = 1;
+		iommu_table_u3_setup();
+	}
+
+	dn = pci_bus_to_OF_node(bus);
+
+	if (dn)
+		dn->iommu_table = &iommu_table_u3;
 }
 
-void iommu_setup_u3(void)
+static void iommu_dev_setup_null(struct pci_dev *dev) { }
+static void iommu_bus_setup_null(struct pci_bus *bus) { }
+
+void iommu_init_early_u3(void)
 {
-	struct pci_controller *phb, *tmp;
-	struct pci_dev *dev = NULL;
 	struct device_node *dn;
 
 	/* Find the DART in the device-tree */
@@ -282,30 +312,22 @@
 	ppc_md.tce_flush = dart_flush;
 
 	/* Initialize the DART HW */
-	if (dart_init(dn))
-		return;
+	if (dart_init(dn)) {
+		/* If init failed, use direct iommu and null setup functions */
+		ppc_md.iommu_dev_setup = iommu_dev_setup_null;
+		ppc_md.iommu_bus_setup = iommu_bus_setup_null;
+
+		/* Setup pci_dma ops */
+		pci_direct_iommu_init();
+	} else {
+		ppc_md.iommu_dev_setup = iommu_dev_setup_u3;
+		ppc_md.iommu_bus_setup = iommu_bus_setup_u3;
 
-	/* Setup pci_dma ops */
-	pci_iommu_init();
-
-	/* We only have one iommu table on the mac for now, which makes
-	 * things simple. Setup all PCI devices to point to this table
-	 */
-	for_each_pci_dev(dev) {
-		/* We must use pci_device_to_OF_node() to make sure that
-		 * we get the real "final" pointer to the device in the
-		 * pci_dev sysdata and not the temporary PHB one
-		 */
-		struct device_node *dn = pci_device_to_OF_node(dev);
-		if (dn)
-			dn->iommu_table = &iommu_table_u3;
-	}
-	/* We also make sure we set all PHBs ... */
-	list_for_each_entry_safe(phb, tmp, &hose_list, list_node) {
-		dn = (struct device_node *)phb->arch_data;
-		dn->iommu_table = &iommu_table_u3;
+		/* Setup pci_dma ops */
+		pci_iommu_init();
 	}
 }
+
 
 void __init alloc_u3_dart_table(void)
 {
diff -Nru a/arch/ppc64/kernel/udbg.c b/arch/ppc64/kernel/udbg.c
--- a/arch/ppc64/kernel/udbg.c	2005-03-01 23:38:52 -08:00
+++ b/arch/ppc64/kernel/udbg.c	2005-03-01 23:38:52 -08:00
@@ -15,7 +15,6 @@
 #include <linux/types.h>
 #include <asm/ppcdebug.h>
 #include <asm/processor.h>
-#include <asm/naca.h>
 #include <asm/uaccess.h>
 #include <asm/machdep.h>
 #include <asm/io.h>
@@ -323,7 +322,7 @@
 /* Special print used by PPCDBG() macro */
 void udbg_ppcdbg(unsigned long debug_flags, const char *fmt, ...)
 {
-	unsigned long active_debugs = debug_flags & naca->debug_switch;
+	unsigned long active_debugs = debug_flags & ppc64_debug_switch;
 
 	if (active_debugs) {
 		va_list ap;
@@ -357,5 +356,5 @@
 
 unsigned long udbg_ifdebug(unsigned long flags)
 {
-	return (flags & naca->debug_switch);
+	return (flags & ppc64_debug_switch);
 }
diff -Nru a/arch/ppc64/kernel/vio.c b/arch/ppc64/kernel/vio.c
--- a/arch/ppc64/kernel/vio.c	2005-03-01 23:38:54 -08:00
+++ b/arch/ppc64/kernel/vio.c	2005-03-01 23:38:54 -08:00
@@ -158,6 +158,7 @@
 	struct iommu_table *t;
 	struct iommu_table_cb cb;
 	unsigned long cbp;
+	unsigned long itc_entries;
 
 	cb.itc_busno = 255;    /* Bus 255 is the virtual bus */
 	cb.itc_virtbus = 0xff; /* Ask for virtual bus */
@@ -165,12 +166,12 @@
 	cbp = virt_to_abs(&cb);
 	HvCallXm_getTceTableParms(cbp);
 
-	veth_iommu_table.it_size        = cb.itc_size / 2;
+	itc_entries = cb.itc_size * PAGE_SIZE / sizeof(union tce_entry);
+	veth_iommu_table.it_size        = itc_entries / 2;
 	veth_iommu_table.it_busno       = cb.itc_busno;
 	veth_iommu_table.it_offset      = cb.itc_offset;
 	veth_iommu_table.it_index       = cb.itc_index;
 	veth_iommu_table.it_type        = TCE_VB;
-	veth_iommu_table.it_entrysize	= sizeof(union tce_entry);
 	veth_iommu_table.it_blocksize	= 1;
 
 	t = iommu_init_table(&veth_iommu_table);
@@ -178,13 +179,12 @@
 	if (!t)
 		printk("Virtual Bus VETH TCE table failed.\n");
 
-	vio_iommu_table.it_size         = cb.itc_size - veth_iommu_table.it_size;
+	vio_iommu_table.it_size         = itc_entries - veth_iommu_table.it_size;
 	vio_iommu_table.it_busno        = cb.itc_busno;
 	vio_iommu_table.it_offset       = cb.itc_offset +
-		veth_iommu_table.it_size * (PAGE_SIZE/sizeof(union tce_entry));
+					  veth_iommu_table.it_size;
 	vio_iommu_table.it_index        = cb.itc_index;
 	vio_iommu_table.it_type         = TCE_VB;
-	vio_iommu_table.it_entrysize	= sizeof(union tce_entry);
 	vio_iommu_table.it_blocksize	= 1;
 
 	t = iommu_init_table(&vio_iommu_table);
@@ -511,7 +511,6 @@
 	unsigned int *dma_window;
 	struct iommu_table *newTceTable;
 	unsigned long offset;
-	unsigned long size;
 	int dma_window_property_size;
 
 	dma_window = (unsigned int *) get_property(dev->dev.platform_data, "ibm,my-dma-window", &dma_window_property_size);
@@ -521,21 +520,18 @@
 
 	newTceTable = (struct iommu_table *) kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
 
-	size = ((dma_window[4] >> PAGE_SHIFT) << 3) >> PAGE_SHIFT;
-
 	/*  There should be some code to extract the phys-encoded offset
 		using prom_n_addr_cells(). However, according to a comment
 		on earlier versions, it's always zero, so we don't bother */
 	offset = dma_window[1] >>  PAGE_SHIFT;
 
-	/* TCE table size - measured in units of pages of tce table */
-	newTceTable->it_size		= size;
+	/* TCE table size - measured in tce entries */
+	newTceTable->it_size		= dma_window[4] >> PAGE_SHIFT;
 	/* offset for VIO should always be 0 */
 	newTceTable->it_offset		= offset;
 	newTceTable->it_busno		= 0;
 	newTceTable->it_index		= (unsigned long)dma_window[0];
 	newTceTable->it_type		= TCE_VB;
-	newTceTable->it_entrysize	= sizeof(union tce_entry);
 
 	return iommu_init_table(newTceTable);
 }
diff -Nru a/arch/ppc64/kernel/viopath.c b/arch/ppc64/kernel/viopath.c
--- a/arch/ppc64/kernel/viopath.c	2005-03-01 23:38:52 -08:00
+++ b/arch/ppc64/kernel/viopath.c	2005-03-01 23:38:52 -08:00
@@ -64,7 +64,7 @@
 	int numberAllocated;
 } viopathStatus[HVMAXARCHITECTEDLPS];
 
-static spinlock_t statuslock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(statuslock);
 
 /*
  * For each kind of event we allocate a buffer that is
diff -Nru a/arch/ppc64/kernel/xics.c b/arch/ppc64/kernel/xics.c
--- a/arch/ppc64/kernel/xics.c	2005-03-01 23:38:58 -08:00
+++ b/arch/ppc64/kernel/xics.c	2005-03-01 23:38:58 -08:00
@@ -24,7 +24,6 @@
 #include <asm/io.h>
 #include <asm/pgtable.h>
 #include <asm/smp.h>
-#include <asm/naca.h>
 #include <asm/rtas.h>
 #include <asm/xics.h>
 #include <asm/hvcall.h>
@@ -92,6 +91,7 @@
 static unsigned int default_server = 0xFF;
 /* also referenced in smp.c... */
 unsigned int default_distrib_server = 0;
+unsigned int interrupt_server_size = 8;
 
 /*
  * XICS only has a single IPI, so encode the messages per CPU
@@ -242,28 +242,24 @@
 static int get_irq_server(unsigned int irq)
 {
 	unsigned int server;
-
-#ifdef CONFIG_IRQ_ALL_CPUS
 	/* For the moment only implement delivery to all cpus or one cpu */
-	if (smp_threads_ready) {
-		cpumask_t cpumask = irq_affinity[irq];
-		cpumask_t tmp = CPU_MASK_NONE;
-		if (cpus_equal(cpumask, CPU_MASK_ALL)) {
-			server = default_distrib_server;
-		} else {
-			cpus_and(tmp, cpu_online_map, cpumask);
+	cpumask_t cpumask = irq_affinity[irq];
+	cpumask_t tmp = CPU_MASK_NONE;
 
-			if (cpus_empty(tmp))
-				server = default_distrib_server;
-			else
-				server = get_hard_smp_processor_id(first_cpu(tmp));
-		}
+	if (!distribute_irqs)
+		return default_server;
+
+	if (cpus_equal(cpumask, CPU_MASK_ALL)) {
+		server = default_distrib_server;
 	} else {
-		server = default_server;
+		cpus_and(tmp, cpu_online_map, cpumask);
+
+		if (cpus_empty(tmp))
+			server = default_distrib_server;
+		else
+			server = get_hard_smp_processor_id(first_cpu(tmp));
 	}
-#else
-	server = default_server;
-#endif
+
 	return server;
 
 }
@@ -512,6 +508,10 @@
 				default_server = ireg[0];
 				default_distrib_server = ireg[i-1]; /* take last element */
 			}
+			ireg = (uint *)get_property(np,
+					"ibm,interrupt-server#-size", NULL);
+			if (ireg)
+				interrupt_server_size = *ireg;
 			break;
 		}
 	}
@@ -575,7 +575,7 @@
  */
 static int __init xics_setup_i8259(void)
 {
-	if (naca->interrupt_controller == IC_PPC_XIC &&
+	if (ppc64_interrupt_controller == IC_PPC_XIC &&
 	    xics_irq_8259_cascade != -1) {
 		if (request_irq(irq_offset_up(xics_irq_8259_cascade),
 				no_action, 0, "8259 cascade", NULL))
@@ -644,20 +644,16 @@
 /* Interrupts are disabled. */
 void xics_migrate_irqs_away(void)
 {
-	int set_indicator = rtas_token("set-indicator");
-	const unsigned int giqs = 9005UL; /* Global Interrupt Queue Server */
-	int status = 0;
+	int status;
 	unsigned int irq, virq, cpu = smp_processor_id();
 
-	BUG_ON(set_indicator == RTAS_UNKNOWN_SERVICE);
-
 	/* Reject any interrupt that was queued to us... */
 	ops->cppr_info(cpu, 0);
 	iosync();
 
-	/* Refuse any new interrupts... */
-	rtas_call(set_indicator, 3, 1, &status, giqs,
-		  hard_smp_processor_id(), 0);
+	/* remove ourselves from the global interrupt queue */
+	status = rtas_set_indicator(GLOBAL_INTERRUPT_QUEUE,
+		(1UL << interrupt_server_size) - 1 - default_distrib_server, 0);
 	WARN_ON(status != 0);
 
 	/* Allow IPIs again... */
diff -Nru a/arch/ppc64/lib/Makefile b/arch/ppc64/lib/Makefile
--- a/arch/ppc64/lib/Makefile	2005-03-01 23:39:18 -08:00
+++ b/arch/ppc64/lib/Makefile	2005-03-01 23:39:18 -08:00
@@ -15,4 +15,4 @@
 obj-$(CONFIG_PCI)	+= e2a.o
 endif
 
-lib-$(CONFIG_XMON) += sstep.o
+lib-$(CONFIG_DEBUG_KERNEL) += sstep.o
diff -Nru a/arch/ppc64/lib/locks.c b/arch/ppc64/lib/locks.c
--- a/arch/ppc64/lib/locks.c	2005-03-01 23:39:07 -08:00
+++ b/arch/ppc64/lib/locks.c	2005-03-01 23:39:07 -08:00
@@ -34,7 +34,7 @@
 	holder_cpu = lock_value & 0xffff;
 	BUG_ON(holder_cpu >= NR_CPUS);
 	holder_paca = &paca[holder_cpu];
-	yield_count = holder_paca->lppaca.xYieldCount;
+	yield_count = holder_paca->lppaca.yield_count;
 	if ((yield_count & 1) == 0)
 		return;		/* virtual cpu is currently running */
 	rmb();
@@ -66,7 +66,7 @@
 	holder_cpu = lock_value & 0xffff;
 	BUG_ON(holder_cpu >= NR_CPUS);
 	holder_paca = &paca[holder_cpu];
-	yield_count = holder_paca->lppaca.xYieldCount;
+	yield_count = holder_paca->lppaca.yield_count;
 	if ((yield_count & 1) == 0)
 		return;		/* virtual cpu is currently running */
 	rmb();
diff -Nru a/arch/ppc64/lib/sstep.c b/arch/ppc64/lib/sstep.c
--- a/arch/ppc64/lib/sstep.c	2005-03-01 23:39:16 -08:00
+++ b/arch/ppc64/lib/sstep.c	2005-03-01 23:39:16 -08:00
@@ -13,7 +13,7 @@
 #include <asm/sstep.h>
 #include <asm/processor.h>
 
-extern char SystemCall_common[];
+extern char system_call_common[];
 
 /* Bits in SRR1 that are copied from MSR */
 #define MSR_MASK	0xffffffff87c0ffff
@@ -76,7 +76,7 @@
 		regs->gpr[11] = regs->nip + 4;
 		regs->gpr[12] = regs->msr & MSR_MASK;
 		regs->gpr[13] = (unsigned long) get_paca();
-		regs->nip = (unsigned long) &SystemCall_common;
+		regs->nip = (unsigned long) &system_call_common;
 		regs->msr = MSR_KERNEL;
 		return 1;
 	case 18:	/* b */
diff -Nru a/arch/ppc64/mm/fault.c b/arch/ppc64/mm/fault.c
--- a/arch/ppc64/mm/fault.c	2005-03-01 23:39:08 -08:00
+++ b/arch/ppc64/mm/fault.c	2005-03-01 23:39:08 -08:00
@@ -36,6 +36,7 @@
 #include <asm/mmu_context.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
+#include <asm/kdebug.h>
 
 /*
  * Check whether the instruction at regs->nip is a store using
@@ -95,6 +96,10 @@
 
 	BUG_ON((trap == 0x380) || (trap == 0x480));
 
+	if (notify_die(DIE_PAGE_FAULT, "page_fault", regs, error_code,
+				11, SIGSEGV) == NOTIFY_STOP)
+		return 0;
+
 	if (trap == 0x300) {
 		if (debugger_fault_handler(regs))
 			return 0;
@@ -105,6 +110,9 @@
 		return SIGSEGV;
 
 	if (error_code & 0x00400000) {
+		if (notify_die(DIE_DABR_MATCH, "dabr_match", regs, error_code,
+					11, SIGSEGV) == NOTIFY_STOP)
+			return 0;
 		if (debugger_dabr_match(regs))
 			return 0;
 	}
diff -Nru a/arch/ppc64/mm/hash_low.S b/arch/ppc64/mm/hash_low.S
--- a/arch/ppc64/mm/hash_low.S	2005-03-01 23:39:09 -08:00
+++ b/arch/ppc64/mm/hash_low.S	2005-03-01 23:39:09 -08:00
@@ -139,8 +139,8 @@
 	std	r3,STK_PARM(r4)(r1)
 
 	/* Get htab_hash_mask */
-	ld	r4,htab_data@got(2)
-	ld	r27,16(r4)	/* htab_data.htab_hash_mask -> r27 */
+	ld	r4,htab_hash_mask@got(2)
+	ld	r27,0(r4)	/* htab_hash_mask -> r27 */
 
 	/* Check if we may already be in the hashtable, in this case, we
 	 * go to out-of-line code to try to modify the HPTE
diff -Nru a/arch/ppc64/mm/hash_native.c b/arch/ppc64/mm/hash_native.c
--- a/arch/ppc64/mm/hash_native.c	2005-03-01 23:38:55 -08:00
+++ b/arch/ppc64/mm/hash_native.c	2005-03-01 23:38:55 -08:00
@@ -25,7 +25,7 @@
 
 #define HPTE_LOCK_BIT 3
 
-static spinlock_t native_tlbie_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(native_tlbie_lock);
 
 static inline void native_lock_hpte(HPTE *hptep)
 {
@@ -52,7 +52,7 @@
 			unsigned long hpteflags, int bolted, int large)
 {
 	unsigned long arpn = physRpn_to_absRpn(prpn);
-	HPTE *hptep = htab_data.htab + hpte_group;
+	HPTE *hptep = htab_address + hpte_group;
 	Hpte_dword0 dw0;
 	HPTE lhpte;
 	int i;
@@ -117,7 +117,7 @@
 	slot_offset = mftb() & 0x7;
 
 	for (i = 0; i < HPTES_PER_GROUP; i++) {
-		hptep = htab_data.htab + hpte_group + slot_offset;
+		hptep = htab_address + hpte_group + slot_offset;
 		dw0 = hptep->dw0.dw0;
 
 		if (dw0.v && !dw0.bolted) {
@@ -172,9 +172,9 @@
 	hash = hpt_hash(vpn, 0);
 
 	for (j = 0; j < 2; j++) {
-		slot = (hash & htab_data.htab_hash_mask) * HPTES_PER_GROUP;
+		slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
 		for (i = 0; i < HPTES_PER_GROUP; i++) {
-			hptep = htab_data.htab + slot;
+			hptep = htab_address + slot;
 			dw0 = hptep->dw0.dw0;
 
 			if ((dw0.avpn == (vpn >> 11)) && dw0.v &&
@@ -195,7 +195,7 @@
 static long native_hpte_updatepp(unsigned long slot, unsigned long newpp,
 				 unsigned long va, int large, int local)
 {
-	HPTE *hptep = htab_data.htab + slot;
+	HPTE *hptep = htab_address + slot;
 	Hpte_dword0 dw0;
 	unsigned long avpn = va >> 23;
 	int ret = 0;
@@ -242,7 +242,7 @@
  */
 static void native_hpte_updateboltedpp(unsigned long newpp, unsigned long ea)
 {
-	unsigned long vsid, va, vpn, flags;
+	unsigned long vsid, va, vpn, flags = 0;
 	long slot;
 	HPTE *hptep;
 	int lock_tlbie = !(cur_cpu_spec->cpu_features & CPU_FTR_LOCKLESS_TLBIE);
@@ -254,7 +254,7 @@
 	slot = native_hpte_find(vpn);
 	if (slot == -1)
 		panic("could not find page to bolt\n");
-	hptep = htab_data.htab + slot;
+	hptep = htab_address + slot;
 
 	set_pp_bit(newpp, hptep);
 
@@ -269,7 +269,7 @@
 static void native_hpte_invalidate(unsigned long slot, unsigned long va,
 				    int large, int local)
 {
-	HPTE *hptep = htab_data.htab + slot;
+	HPTE *hptep = htab_address + slot;
 	Hpte_dword0 dw0;
 	unsigned long avpn = va >> 23;
 	unsigned long flags;
@@ -336,10 +336,10 @@
 		secondary = (pte_val(batch->pte[i]) & _PAGE_SECONDARY) >> 15;
 		if (secondary)
 			hash = ~hash;
-		slot = (hash & htab_data.htab_hash_mask) * HPTES_PER_GROUP;
+		slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
 		slot += (pte_val(batch->pte[i]) & _PAGE_GROUP_IX) >> 12;
 
-		hptep = htab_data.htab + slot;
+		hptep = htab_address + slot;
 
 		avpn = va >> 23;
 		if (large)
diff -Nru a/arch/ppc64/mm/hash_utils.c b/arch/ppc64/mm/hash_utils.c
--- a/arch/ppc64/mm/hash_utils.c	2005-03-01 23:38:58 -08:00
+++ b/arch/ppc64/mm/hash_utils.c	2005-03-01 23:38:58 -08:00
@@ -41,7 +41,6 @@
 #include <asm/types.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
-#include <asm/naca.h>
 #include <asm/machdep.h>
 #include <asm/lmb.h>
 #include <asm/abs_addr.h>
@@ -75,7 +74,8 @@
 extern unsigned long dart_tablebase;
 #endif /* CONFIG_U3_DART */
 
-HTAB htab_data = {NULL, 0, 0, 0, 0};
+HPTE		*htab_address;
+unsigned long	htab_hash_mask;
 
 extern unsigned long _SDR1;
 
@@ -114,7 +114,7 @@
 
 		hash = hpt_hash(vpn, large);
 
-		hpteg = ((hash & htab_data.htab_hash_mask)*HPTES_PER_GROUP);
+		hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP);
 
 #ifdef CONFIG_PPC_PSERIES
 		if (systemcfg->platform & PLATFORM_LPAR)
@@ -147,7 +147,7 @@
 	 * Calculate the required size of the htab.  We want the number of
 	 * PTEGs to equal one half the number of real pages.
 	 */ 
-	htab_size_bytes = 1UL << naca->pftSize;
+	htab_size_bytes = 1UL << ppc64_pft_size;
 	pteg_count = htab_size_bytes >> 7;
 
 	/* For debug, make the HTAB 1/8 as big as it normally would be. */
@@ -156,12 +156,11 @@
 		htab_size_bytes = pteg_count << 7;
 	}
 
-	htab_data.htab_num_ptegs = pteg_count;
-	htab_data.htab_hash_mask = pteg_count - 1;
+	htab_hash_mask = pteg_count - 1;
 
 	if (systemcfg->platform & PLATFORM_LPAR) {
 		/* Using a hypervisor which owns the htab */
-		htab_data.htab = NULL;
+		htab_address = NULL;
 		_SDR1 = 0; 
 	} else {
 		/* Find storage for the HPT.  Must be contiguous in
@@ -176,7 +175,7 @@
 			ppc64_terminate_msg(0x20, "hpt space");
 			loop_forever();
 		}
-		htab_data.htab = abs_to_virt(table);
+		htab_address = abs_to_virt(table);
 
 		/* htab absolute addr + encoded htabsize */
 		_SDR1 = table + __ilog2(pteg_count) - 11;
@@ -295,12 +294,6 @@
 		vsid = get_kernel_vsid(ea);
 		break;
 #if 0
-	case EEH_REGION_ID:
-		/*
-		 * Should only be hit if there is an access to MMIO space
-		 * which is protected by EEH.
-		 * Send the problem up to do_page_fault 
-		 */
 	case KERNEL_REGION_ID:
 		/*
 		 * Should never get here - entire 0xC0... region is bolted.
@@ -357,7 +350,7 @@
 	secondary = (pte_val(pte) & _PAGE_SECONDARY) >> 15;
 	if (secondary)
 		hash = ~hash;
-	slot = (hash & htab_data.htab_hash_mask) * HPTES_PER_GROUP;
+	slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
 	slot += (pte_val(pte) & _PAGE_GROUP_IX) >> 12;
 
 	ppc_md.hpte_invalidate(slot, va, huge, local);
diff -Nru a/arch/ppc64/mm/hugetlbpage.c b/arch/ppc64/mm/hugetlbpage.c
--- a/arch/ppc64/mm/hugetlbpage.c	2005-03-01 23:38:57 -08:00
+++ b/arch/ppc64/mm/hugetlbpage.c	2005-03-01 23:38:57 -08:00
@@ -264,6 +264,10 @@
 				return -EBUSY;
 
 	mm->context.htlb_segs |= newsegs;
+
+	/* update the paca copy of the context struct */
+	get_paca()->context = mm->context;
+
 	/* the context change must make it to memory before the flush,
 	 * so that further SLB misses do the right thing. */
 	mb();
@@ -745,7 +749,7 @@
 
 	pgdir = mm->context.huge_pgdir;
 	if (! pgdir)
-		return;
+		goto out;
 
 	mm->context.huge_pgdir = NULL;
 
@@ -768,6 +772,7 @@
 	BUG_ON(memcmp(pgdir, empty_zero_page, PAGE_SIZE));
 	kmem_cache_free(zero_cache, pgdir);
 
+ out:
 	spin_unlock(&mm->page_table_lock);
 }
 
@@ -832,7 +837,7 @@
 		hash = hpt_hash(vpn, 1);
 		if (pte_val(old_pte) & _PAGE_SECONDARY)
 			hash = ~hash;
-		slot = (hash & htab_data.htab_hash_mask) * HPTES_PER_GROUP;
+		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)
@@ -846,7 +851,7 @@
 		prpn = pte_pfn(old_pte);
 
 repeat:
-		hpte_group = ((hash & htab_data.htab_hash_mask) *
+		hpte_group = ((hash & htab_hash_mask) *
 			      HPTES_PER_GROUP) & ~0x7UL;
 
 		/* Update the linux pte with the HPTE slot */
@@ -863,13 +868,13 @@
 		/* Primary is full, try the secondary */
 		if (unlikely(slot == -1)) {
 			pte_val(new_pte) |= _PAGE_SECONDARY;
-			hpte_group = ((~hash & htab_data.htab_hash_mask) *
+			hpte_group = ((~hash & htab_hash_mask) *
 				      HPTES_PER_GROUP) & ~0x7UL; 
 			slot = ppc_md.hpte_insert(hpte_group, va, prpn,
 						  1, hpteflags, 0, 1);
 			if (slot == -1) {
 				if (mftb() & 0x1)
-					hpte_group = ((hash & htab_data.htab_hash_mask) * HPTES_PER_GROUP) & ~0x7UL;
+					hpte_group = ((hash & htab_hash_mask) * HPTES_PER_GROUP) & ~0x7UL;
 
 				ppc_md.hpte_remove(hpte_group);
 				goto repeat;
diff -Nru a/arch/ppc64/mm/init.c b/arch/ppc64/mm/init.c
--- a/arch/ppc64/mm/init.c	2005-03-01 23:38:58 -08:00
+++ b/arch/ppc64/mm/init.c	2005-03-01 23:38:58 -08:00
@@ -37,6 +37,7 @@
 #include <linux/bootmem.h>
 #include <linux/highmem.h>
 #include <linux/idr.h>
+#include <linux/nodemask.h>
 
 #include <asm/pgalloc.h>
 #include <asm/page.h>
@@ -52,7 +53,6 @@
 #include <asm/smp.h>
 #include <asm/machdep.h>
 #include <asm/tlb.h>
-#include <asm/naca.h>
 #include <asm/eeh.h>
 #include <asm/processor.h>
 #include <asm/mmzone.h>
@@ -169,7 +169,7 @@
 
 		hash = hpt_hash(vpn, 0);
 
-		hpteg = ((hash & htab_data.htab_hash_mask)*HPTES_PER_GROUP);
+		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,
@@ -470,7 +470,7 @@
 }
 #endif
 
-static spinlock_t mmu_context_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(mmu_context_lock);
 static DEFINE_IDR(mmu_context_idr);
 
 int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
@@ -703,7 +703,7 @@
 	high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
 
 #ifdef CONFIG_DISCONTIGMEM
-        for (nid = 0; nid < numnodes; nid++) {
+        for_each_online_node(nid) {
 		if (NODE_DATA(nid)->node_spanned_pages != 0) {
 			printk("freeing bootmem node %x\n", nid);
 			totalram_pages +=
diff -Nru a/arch/ppc64/mm/numa.c b/arch/ppc64/mm/numa.c
--- a/arch/ppc64/mm/numa.c	2005-03-01 23:39:07 -08:00
+++ b/arch/ppc64/mm/numa.c	2005-03-01 23:39:07 -08:00
@@ -216,7 +216,7 @@
 
 	numa_domain = of_node_numa_domain(cpu);
 
-	if (numa_domain >= numnodes) {
+	if (numa_domain >= num_online_nodes()) {
 		/*
 		 * POWER4 LPAR uses 0xffff as invalid node,
 		 * dont warn in this case.
@@ -345,8 +345,6 @@
 			numa_domain = 0;
 		}
 
-		node_set_online(numa_domain);
-
 		if (max_domain < numa_domain)
 			max_domain = numa_domain;
 
@@ -361,14 +359,19 @@
 				init_node_data[numa_domain].node_start_pfn +
 				init_node_data[numa_domain].node_spanned_pages;
 			if (shouldstart != (start / PAGE_SIZE)) {
-				printk(KERN_ERR "WARNING: Hole in node, "
-						"disabling region start %lx "
-						"length %lx\n", start, size);
-				continue;
+				/* Revert to non-numa for now */
+				printk(KERN_ERR
+				       "WARNING: Unexpected node layout: "
+				       "region start %lx length %lx\n",
+				       start, size);
+				printk(KERN_ERR "NUMA is disabled\n");
+				goto err;
 			}
 			init_node_data[numa_domain].node_spanned_pages +=
 				size / PAGE_SIZE;
 		} else {
+			node_set_online(numa_domain);
+
 			init_node_data[numa_domain].node_start_pfn =
 				start / PAGE_SIZE;
 			init_node_data[numa_domain].node_spanned_pages =
@@ -384,9 +387,18 @@
 			goto new_range;
 	}
 
-	numnodes = max_domain + 1;
+	for (i = 0; i <= max_domain; i++)
+		node_set_online(i);
 
 	return 0;
+err:
+	/* Something has gone wrong; revert any setup we've done */
+	for_each_node(i) {
+		node_set_offline(i);
+		init_node_data[i].node_start_pfn = 0;
+		init_node_data[i].node_spanned_pages = 0;
+	}
+	return -1;
 }
 
 static void __init setup_nonnuma(void)
@@ -430,12 +442,9 @@
 	if (min_common_depth == -1 || !numa_enabled)
 		return;
 
-	for (node = 0; node < MAX_NUMNODES; node++) {
+	for_each_online_node(node) {
 		unsigned long i;
 
-		if (!node_online(node))
-			continue;
-
 		printk(KERN_INFO "Node %d Memory:", node);
 
 		count = 0;
@@ -519,7 +528,7 @@
 
 	register_cpu_notifier(&ppc64_numa_nb);
 
-	for (nid = 0; nid < numnodes; nid++) {
+	for_each_online_node(nid) {
 		unsigned long start_paddr, end_paddr;
 		int i;
 		unsigned long bootmem_paddr;
@@ -619,7 +628,7 @@
 	memset(zones_size, 0, sizeof(zones_size));
 	memset(zholes_size, 0, sizeof(zholes_size));
 
-	for (nid = 0; nid < numnodes; nid++) {
+	for_each_online_node(nid) {
 		unsigned long start_pfn;
 		unsigned long end_pfn;
 
diff -Nru a/arch/ppc64/mm/slb.c b/arch/ppc64/mm/slb.c
--- a/arch/ppc64/mm/slb.c	2005-03-01 23:38:57 -08:00
+++ b/arch/ppc64/mm/slb.c	2005-03-01 23:38:57 -08:00
@@ -19,7 +19,6 @@
 #include <asm/mmu.h>
 #include <asm/mmu_context.h>
 #include <asm/paca.h>
-#include <asm/naca.h>
 #include <asm/cputable.h>
 
 extern void slb_allocate(unsigned long ea);
@@ -79,7 +78,7 @@
 void switch_slb(struct task_struct *tsk, struct mm_struct *mm)
 {
 	unsigned long offset = get_paca()->slb_cache_ptr;
-	unsigned long esid_data;
+	unsigned long esid_data = 0;
 	unsigned long pc = KSTK_EIP(tsk);
 	unsigned long stack = KSTK_ESP(tsk);
 	unsigned long unmapped_base;
@@ -98,11 +97,8 @@
 	}
 
 	/* Workaround POWER5 < DD2.1 issue */
-	if (offset == 1 || offset > SLB_CACHE_ENTRIES) {
-		/* flush segment in EEH region, we shouldn't ever
-		 * access addresses in this region. */
-		asm volatile("slbie %0" : : "r"(EEHREGIONBASE));
-	}
+	if (offset == 1 || offset > SLB_CACHE_ENTRIES)
+		asm volatile("slbie %0" : : "r" (esid_data));
 
 	get_paca()->slb_cache_ptr = 0;
 	get_paca()->context = mm->context;
diff -Nru a/arch/ppc64/mm/stab.c b/arch/ppc64/mm/stab.c
--- a/arch/ppc64/mm/stab.c	2005-03-01 23:39:18 -08:00
+++ b/arch/ppc64/mm/stab.c	2005-03-01 23:39:18 -08:00
@@ -17,7 +17,6 @@
 #include <asm/mmu.h>
 #include <asm/mmu_context.h>
 #include <asm/paca.h>
-#include <asm/naca.h>
 #include <asm/cputable.h>
 
 /* Both the segment table and SLB code uses the following cache */
diff -Nru a/arch/ppc64/mm/tlb.c b/arch/ppc64/mm/tlb.c
--- a/arch/ppc64/mm/tlb.c	2005-03-01 23:38:57 -08:00
+++ b/arch/ppc64/mm/tlb.c	2005-03-01 23:38:57 -08:00
@@ -85,8 +85,12 @@
 
 	ptepage = virt_to_page(ptep);
 	mm = (struct mm_struct *) ptepage->mapping;
-	addr = ptepage->index +
-		(((unsigned long)ptep & ~PAGE_MASK) * PTRS_PER_PTE);
+	addr = ptepage->index;
+	if (pte_huge(pte))
+		addr +=  ((unsigned long)ptep & ~PAGE_MASK)
+			/ sizeof(*ptep) * HPAGE_SIZE;
+	else
+		addr += ((unsigned long)ptep & ~PAGE_MASK) * PTRS_PER_PTE;
 
 	if (REGION_ID(addr) == USER_REGION_ID)
 		context = mm->context.id;
diff -Nru a/arch/ppc64/oprofile/common.c b/arch/ppc64/oprofile/common.c
--- a/arch/ppc64/oprofile/common.c	2005-03-01 23:39:17 -08:00
+++ b/arch/ppc64/oprofile/common.c	2005-03-01 23:39:17 -08:00
@@ -125,16 +125,7 @@
 	return 0;
 }
 
-static struct oprofile_operations oprof_ppc64_ops = {
-	.create_files	= op_ppc64_create_files,
-	.setup		= op_ppc64_setup,
-	.shutdown	= op_ppc64_shutdown,
-	.start		= op_ppc64_start,
-	.stop		= op_ppc64_stop,
-	.cpu_type	= NULL		/* To be filled in below. */
-};
-
-int __init oprofile_arch_init(struct oprofile_operations **ops)
+int __init oprofile_arch_init(struct oprofile_operations *ops)
 {
 	unsigned int pvr;
 
@@ -145,7 +136,7 @@
 		case PV_630p:
 			model = &op_model_rs64;
 			model->num_counters = 8;
-			oprof_ppc64_ops.cpu_type = "ppc64/power3";
+			ops->cpu_type = "ppc64/power3";
 			break;
 
 		case PV_NORTHSTAR:
@@ -154,38 +145,42 @@
 		case PV_SSTAR:
 			model = &op_model_rs64;
 			model->num_counters = 8;
-			oprof_ppc64_ops.cpu_type = "ppc64/rs64";
+			ops->cpu_type = "ppc64/rs64";
 			break;
 
 		case PV_POWER4:
 		case PV_POWER4p:
 			model = &op_model_power4;
 			model->num_counters = 8;
-			oprof_ppc64_ops.cpu_type = "ppc64/power4";
+			ops->cpu_type = "ppc64/power4";
 			break;
 
 		case PV_970:
 		case PV_970FX:
 			model = &op_model_power4;
 			model->num_counters = 8;
-			oprof_ppc64_ops.cpu_type = "ppc64/970";
+			ops->cpu_type = "ppc64/970";
 			break;
 
 		case PV_POWER5:
 		case PV_POWER5p:
 			model = &op_model_power4;
 			model->num_counters = 6;
-			oprof_ppc64_ops.cpu_type = "ppc64/power5";
+			ops->cpu_type = "ppc64/power5";
 			break;
 
 		default:
 			return -ENODEV;
 	}
 
-	*ops = &oprof_ppc64_ops;
+	ops->create_files = op_ppc64_create_files;
+	ops->setup = op_ppc64_setup;
+	ops->shutdown = op_ppc64_shutdown;
+	ops->start = op_ppc64_start;
+	ops->stop = op_ppc64_stop;
 
 	printk(KERN_INFO "oprofile: using %s performance monitoring.\n",
-	       oprof_ppc64_ops.cpu_type);
+	       ops->cpu_type);
 
 	return 0;
 }
diff -Nru a/arch/ppc64/oprofile/op_impl.h b/arch/ppc64/oprofile/op_impl.h
--- a/arch/ppc64/oprofile/op_impl.h	2005-03-01 23:38:58 -08:00
+++ b/arch/ppc64/oprofile/op_impl.h	2005-03-01 23:38:58 -08:00
@@ -14,44 +14,6 @@
 
 #define OP_MAX_COUNTER 8
 
-#define MSR_PMM		(1UL << (63 - 61))
-
-/* freeze counters. set to 1 on a perfmon exception */
-#define MMCR0_FC	(1UL << (31 - 0))
-
-/* freeze in supervisor state */
-#define MMCR0_KERNEL_DISABLE (1UL << (31 - 1))
-
-/* freeze in problem state */
-#define MMCR0_PROBLEM_DISABLE (1UL << (31 - 2))
-
-/* freeze counters while MSR mark = 1 */
-#define MMCR0_FCM1	(1UL << (31 - 3))
-
-/* performance monitor exception enable */
-#define MMCR0_PMXE	(1UL << (31 - 5))
-
-/* freeze counters on enabled condition or event */
-#define MMCR0_FCECE	(1UL << (31 - 6))
-
-/* PMC1 count enable*/
-#define MMCR0_PMC1INTCONTROL	(1UL << (31 - 16))
-
-/* PMCn count enable*/
-#define MMCR0_PMCNINTCONTROL	(1UL << (31 - 17))
-
-/* performance monitor alert has occurred, set to 0 after handling exception */
-#define MMCR0_PMAO	(1UL << (31 - 24))
-
-/* state of MSR HV when SIAR set */
-#define MMCRA_SIHV	(1UL << (63 - 35))
-
-/* state of MSR PR when SIAR set */
-#define MMCRA_SIPR	(1UL << (63 - 36))
-
-/* enable sampling */
-#define MMCRA_SAMPLE_ENABLE	(1UL << (63 - 63))
-
 /* Per-counter configuration as set via oprofilefs.  */
 struct op_counter_config {
 	unsigned long valid;
diff -Nru a/arch/ppc64/oprofile/op_model_power4.c b/arch/ppc64/oprofile/op_model_power4.c
--- a/arch/ppc64/oprofile/op_model_power4.c	2005-03-01 23:39:08 -08:00
+++ b/arch/ppc64/oprofile/op_model_power4.c	2005-03-01 23:39:08 -08:00
@@ -97,7 +97,7 @@
 	mtspr(SPRN_MMCR0, mmcr0);
 
 	mmcr0 |= MMCR0_FCM1|MMCR0_PMXE|MMCR0_FCECE;
-	mmcr0 |= MMCR0_PMC1INTCONTROL|MMCR0_PMCNINTCONTROL;
+	mmcr0 |= MMCR0_PMC1CE|MMCR0_PMCjCE;
 	mtspr(SPRN_MMCR0, mmcr0);
 
 	mtspr(SPRN_MMCR1, mmcr1_val);
@@ -264,7 +264,6 @@
 	int is_kernel;
 	int val;
 	int i;
-	unsigned int cpu = smp_processor_id();
 	unsigned int mmcr0;
 
 	pc = get_pc(regs);
@@ -277,7 +276,7 @@
 		val = ctr_read(i);
 		if (val < 0) {
 			if (oprofile_running && ctr[i].enabled) {
-				oprofile_add_sample(pc, is_kernel, i, cpu);
+				oprofile_add_pc(pc, is_kernel, i);
 				ctr_write(i, reset_value[i]);
 			} else {
 				ctr_write(i, 0);
diff -Nru a/arch/ppc64/oprofile/op_model_rs64.c b/arch/ppc64/oprofile/op_model_rs64.c
--- a/arch/ppc64/oprofile/op_model_rs64.c	2005-03-01 23:39:16 -08:00
+++ b/arch/ppc64/oprofile/op_model_rs64.c	2005-03-01 23:39:16 -08:00
@@ -119,7 +119,7 @@
 
 	mmcr0 |= MMCR0_FCM1|MMCR0_PMXE|MMCR0_FCECE;
 	/* Only applies to POWER3, but should be safe on RS64 */
-	mmcr0 |= MMCR0_PMC1INTCONTROL|MMCR0_PMCNINTCONTROL;
+	mmcr0 |= MMCR0_PMC1CE|MMCR0_PMCjCE;
 	mtspr(SPRN_MMCR0, mmcr0);
 
 	dbg("setup on cpu %d, mmcr0 %lx\n", smp_processor_id(),
@@ -180,7 +180,6 @@
 	int i;
 	unsigned long pc = mfspr(SPRN_SIAR);
 	int is_kernel = (pc >= KERNELBASE);
-	unsigned int cpu = smp_processor_id();
 
 	/* set the PMM bit (see comment below) */
 	mtmsrd(mfmsr() | MSR_PMM);
@@ -189,7 +188,7 @@
 		val = ctr_read(i);
 		if (val < 0) {
 			if (ctr[i].enabled) {
-				oprofile_add_sample(pc, is_kernel, i, cpu);
+				oprofile_add_pc(pc, is_kernel, i);
 				ctr_write(i, reset_value[i]);
 			} else {
 				ctr_write(i, 0);
diff -Nru a/arch/ppc64/xmon/setjmp.S b/arch/ppc64/xmon/setjmp.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/ppc64/xmon/setjmp.S	2005-03-01 23:39:09 -08:00
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 1996 Paul Mackerras.
+ *
+ *      This program is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU General Public License
+ *      as published by the Free Software Foundation; either version
+ *      2 of the License, or (at your option) any later version.
+ *
+ * NOTE: assert(sizeof(buf) > 184)
+ */
+#include <asm/processor.h>
+#include <asm/ppc_asm.h>
+
+_GLOBAL(xmon_setjmp)
+	mflr    r0
+	std     r0,0(r3)
+	std     r1,8(r3)
+	std     r2,16(r3)
+	mfcr    r0
+	std     r0,24(r3)
+	std     r13,32(r3)
+	std     r14,40(r3)
+	std     r15,48(r3)
+	std     r16,56(r3)
+	std     r17,64(r3)
+	std     r18,72(r3)
+	std     r19,80(r3)
+	std     r20,88(r3)
+	std     r21,96(r3)
+	std     r22,104(r3)
+	std     r23,112(r3)
+	std     r24,120(r3)
+	std     r25,128(r3)
+	std     r26,136(r3)
+	std     r27,144(r3)
+	std     r28,152(r3)
+	std     r29,160(r3)
+	std     r30,168(r3)
+	std     r31,176(r3)
+	li      r3,0
+	blr
+
+_GLOBAL(xmon_longjmp)
+	cmpdi   r4,0
+	bne     1f
+	li      r4,1
+1:	ld      r13,32(r3)
+	ld      r14,40(r3)
+	ld      r15,48(r3)
+	ld      r16,56(r3)
+	ld      r17,64(r3)
+	ld      r18,72(r3)
+	ld      r19,80(r3)
+	ld      r20,88(r3)
+	ld      r21,96(r3)
+	ld      r22,104(r3)
+	ld      r23,112(r3)
+	ld      r24,120(r3)
+	ld      r25,128(r3)
+	ld      r26,136(r3)
+	ld      r27,144(r3)
+	ld      r28,152(r3)
+	ld      r29,160(r3)
+	ld      r30,168(r3)
+	ld      r31,176(r3)
+	ld      r0,24(r3)
+	mtcrf   56,r0
+	ld      r0,0(r3)
+	ld      r1,8(r3)
+	ld      r2,16(r3)
+	mtlr    r0
+	mr      r3,r4
+	blr
diff -Nru a/arch/ppc64/xmon/setjmp.c b/arch/ppc64/xmon/setjmp.c
--- a/arch/ppc64/xmon/setjmp.c	2005-03-01 23:39:09 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 1996 Paul Mackerras.
- *
- *      This program is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU General Public License
- *      as published by the Free Software Foundation; either version
- *      2 of the License, or (at your option) any later version.
- *
- * NB this file must be compiled with -O2.
- */
-
-int
-xmon_setjmp(long *buf)  /* NOTE: assert(sizeof(buf) > 184) */
-{
-	/* XXX should save fp regs as well */
-	asm volatile (
-	"mflr 0; std 0,0(%0)\n\
-	 std	1,8(%0)\n\
-	 std	2,16(%0)\n\
-	 mfcr 0; std 0,24(%0)\n\
-	 std	13,32(%0)\n\
-	 std	14,40(%0)\n\
-	 std	15,48(%0)\n\
-	 std	16,56(%0)\n\
-	 std	17,64(%0)\n\
-	 std	18,72(%0)\n\
-	 std	19,80(%0)\n\
-	 std	20,88(%0)\n\
-	 std	21,96(%0)\n\
-	 std	22,104(%0)\n\
-	 std	23,112(%0)\n\
-	 std	24,120(%0)\n\
-	 std	25,128(%0)\n\
-	 std	26,136(%0)\n\
-	 std	27,144(%0)\n\
-	 std	28,152(%0)\n\
-	 std	29,160(%0)\n\
-	 std	30,168(%0)\n\
-	 std	31,176(%0)\n\
-	 " : : "r" (buf));
-    return 0;
-}
-
-void
-xmon_longjmp(long *buf, int val)
-{
-	if (val == 0)
-		val = 1;
-	asm volatile (
-	"ld	13,32(%0)\n\
-	 ld	14,40(%0)\n\
-	 ld	15,48(%0)\n\
-	 ld	16,56(%0)\n\
-	 ld	17,64(%0)\n\
-	 ld	18,72(%0)\n\
-	 ld	19,80(%0)\n\
-	 ld	20,88(%0)\n\
-	 ld	21,96(%0)\n\
-	 ld	22,104(%0)\n\
-	 ld	23,112(%0)\n\
-	 ld	24,120(%0)\n\
-	 ld	25,128(%0)\n\
-	 ld	26,136(%0)\n\
-	 ld	27,144(%0)\n\
-	 ld	28,152(%0)\n\
-	 ld	29,160(%0)\n\
-	 ld	30,168(%0)\n\
-	 ld	31,176(%0)\n\
-	 ld	0,24(%0)\n\
-	 mtcrf	0x38,0\n\
-	 ld	0,0(%0)\n\
-	 ld	1,8(%0)\n\
-	 ld	2,16(%0)\n\
-	 mtlr	0\n\
-	 mr	3,%1\n\
-	 " : : "r" (buf), "r" (val));
-}
diff -Nru a/arch/ppc64/xmon/start.c b/arch/ppc64/xmon/start.c
--- a/arch/ppc64/xmon/start.c	2005-03-01 23:39:18 -08:00
+++ b/arch/ppc64/xmon/start.c	2005-03-01 23:39:18 -08:00
@@ -40,7 +40,7 @@
 
 static int __init setup_xmon_sysrq(void)
 {
-	__sysrq_put_key_op('x', &sysrq_xmon_op);
+	register_sysrq_key('x', &sysrq_xmon_op);
 	return 0;
 }
 __initcall(setup_xmon_sysrq);
diff -Nru a/arch/ppc64/xmon/xmon.c b/arch/ppc64/xmon/xmon.c
--- a/arch/ppc64/xmon/xmon.c	2005-03-01 23:39:09 -08:00
+++ b/arch/ppc64/xmon/xmon.c	2005-03-01 23:39:09 -08:00
@@ -26,12 +26,12 @@
 #include <asm/pgtable.h>
 #include <asm/mmu.h>
 #include <asm/mmu_context.h>
-#include <asm/naca.h>
 #include <asm/paca.h>
 #include <asm/ppcdebug.h>
 #include <asm/cputable.h>
 #include <asm/rtas.h>
 #include <asm/sstep.h>
+#include <asm/bug.h>
 
 #include "nonstdio.h"
 #include "privinst.h"
@@ -50,6 +50,7 @@
 
 static unsigned long adrs;
 static int size = 1;
+#define MAX_DUMP (128 * 1024)
 static unsigned long ndump = 64;
 static unsigned long nidump = 16;
 static unsigned long ncsum = 4096;
@@ -146,8 +147,6 @@
 extern void longjmp(long *, int);
 extern unsigned long _ASR;
 
-pte_t *find_linux_pte(pgd_t *pgdir, unsigned long va);	/* from htab.c */
-
 #define GETWORD(v)	(((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
 
 #define isxdigit(c)	(('0' <= (c) && (c) <= '9') \
@@ -229,17 +228,6 @@
  */
 
 /*
- * We don't allow single-stepping an mtmsrd that would clear
- * MSR_RI, since that would make the exception unrecoverable.
- * Since we need to single-step to proceed from a breakpoint,
- * we don't allow putting a breakpoint on an mtmsrd instruction.
- * Similarly we don't allow breakpoints on rfid instructions.
- * These macros tell us if an instruction is a mtmsrd or rfid.
- */
-#define IS_MTMSRD(instr)	(((instr) & 0xfc0007fe) == 0x7c000164)
-#define IS_RFID(instr)		(((instr) & 0xfc0007fe) == 0x4c000024)
-
-/*
  * Disable surveillance (the service processor watchdog function)
  * while we are in xmon.
  * XXX we should re-enable it when we leave. :)
@@ -636,6 +624,19 @@
 	return 0;
 }
 
+/* On systems with a hypervisor, we can't set the DABR
+   (data address breakpoint register) directly. */
+static void set_controlled_dabr(unsigned long val)
+{
+#ifdef CONFIG_PPC_PSERIES
+	if (systemcfg->platform == PLATFORM_PSERIES_LPAR) {
+		int rc = plpar_hcall_norets(H_SET_DABR, val);
+		if (rc != H_Success)
+			xmon_printf("Warning: setting DABR failed (%d)\n", rc);
+	} else
+#endif
+		set_dabr(val);
+}
 
 static struct bpt *at_breakpoint(unsigned long pc)
 {
@@ -723,7 +724,7 @@
 static void insert_cpu_bpts(void)
 {
 	if (dabr.enabled)
-		set_dabr(dabr.address | (dabr.enabled & 7));
+		set_controlled_dabr(dabr.address | (dabr.enabled & 7));
 	if (iabr && (cur_cpu_spec->cpu_features & CPU_FTR_IABR))
 		set_iabr(iabr->address
 			 | (iabr->enabled & (BP_IABR|BP_IABR_TE)));
@@ -751,7 +752,7 @@
 
 static void remove_cpu_bpts(void)
 {
-	set_dabr(0);
+	set_controlled_dabr(0);
 	if ((cur_cpu_spec->cpu_features & CPU_FTR_IABR))
 		set_iabr(0);
 }
@@ -1061,8 +1062,8 @@
     "b <addr> [cnt]   set breakpoint at given instr addr\n"
     "bc               clear all breakpoints\n"
     "bc <n/addr>      clear breakpoint number n or at addr\n"
-    "bi <addr> [cnt]  set hardware instr breakpoint (broken?)\n"
-    "bd <addr> [cnt]  set hardware data breakpoint (broken?)\n"
+    "bi <addr> [cnt]  set hardware instr breakpoint (POWER3/RS64 only)\n"
+    "bd <addr> [cnt]  set hardware data breakpoint\n"
     "";
 
 static void
@@ -1332,6 +1333,26 @@
 	scannl();
 }
 
+static void print_bug_trap(struct pt_regs *regs)
+{
+	struct bug_entry *bug;
+	unsigned long addr;
+
+	if (regs->msr & MSR_PR)
+		return;		/* not in kernel */
+	addr = regs->nip;	/* address of trap instruction */
+	if (addr < PAGE_OFFSET)
+		return;
+	bug = find_bug(regs->nip);
+	if (bug == NULL)
+		return;
+	if (bug->line & BUG_WARNING_TRAP)
+		return;
+
+	printf("kernel BUG in %s at %s:%d!\n",
+	       bug->function, bug->file, (unsigned int)bug->line);
+}
+
 void excprint(struct pt_regs *fp)
 {
 	unsigned long trap;
@@ -1363,6 +1384,9 @@
 		printf("    pid   = %ld, comm = %s\n",
 		       current->pid, current->comm);
 	}
+
+	if (trap == 0x700)
+		print_bug_trap(fp);
 }
 
 void prregs(struct pt_regs *fp)
@@ -1455,7 +1479,17 @@
 	store_inst(instrs+1);
 	code = (unsigned long (*)(void)) opd;
 
-	ret = code();
+	if (setjmp(bus_error_jmp) == 0) {
+		catch_memory_errors = 1;
+		sync();
+
+		ret = code();
+
+		sync();
+		/* wait a little while to see if we get a machine check */
+		__delay(200);
+		n = size;
+	}
 
 	return ret;
 }
@@ -1476,7 +1510,17 @@
 	store_inst(instrs+1);
 	code = (unsigned long (*)(unsigned long)) opd;
 
-	code(val);
+	if (setjmp(bus_error_jmp) == 0) {
+		catch_memory_errors = 1;
+		sync();
+
+		code(val);
+
+		sync();
+		/* wait a little while to see if we get a machine check */
+		__delay(200);
+		n = size;
+	}
 }
 
 static unsigned long regno;
@@ -1490,7 +1534,7 @@
 	unsigned long val;
 #ifdef CONFIG_PPC_ISERIES
 	struct paca_struct *ptrPaca = NULL;
-	struct ItLpPaca *ptrLpPaca = NULL;
+	struct lppaca *ptrLpPaca = NULL;
 	struct ItLpRegSave *ptrLpRegSave = NULL;
 #endif
 
@@ -1514,10 +1558,10 @@
 		printf("  Local Processor Control Area (LpPaca): \n");
 		ptrLpPaca = ptrPaca->lppaca_ptr;
 		printf("    Saved Srr0=%.16lx  Saved Srr1=%.16lx \n",
-		       ptrLpPaca->xSavedSrr0, ptrLpPaca->xSavedSrr1);
+		       ptrLpPaca->saved_srr0, ptrLpPaca->saved_srr1);
 		printf("    Saved Gpr3=%.16lx  Saved Gpr4=%.16lx \n",
-		       ptrLpPaca->xSavedGpr3, ptrLpPaca->xSavedGpr4);
-		printf("    Saved Gpr5=%.16lx \n", ptrLpPaca->xSavedGpr5);
+		       ptrLpPaca->saved_gpr3, ptrLpPaca->saved_gpr4);
+		printf("    Saved Gpr5=%.16lx \n", ptrLpPaca->saved_gpr5);
     
 		printf("  Local Processor Register Save Area (LpRegSave): \n");
 		ptrLpRegSave = ptrPaca->reg_save_ptr;
@@ -1895,18 +1939,22 @@
 	if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
 		termch = c;
 	scanhex((void *)&adrs);
-	if( termch != '\n')
+	if (termch != '\n')
 		termch = 0;
-	if( c == 'i' ){
+	if (c == 'i') {
 		scanhex(&nidump);
-		if( nidump == 0 )
+		if (nidump == 0)
 			nidump = 16;
+		else if (nidump > MAX_DUMP)
+			nidump = MAX_DUMP;
 		adrs += ppc_inst_dump(adrs, nidump, 1);
 		last_cmd = "di\n";
 	} else {
 		scanhex(&ndump);
-		if( ndump == 0 )
+		if (ndump == 0)
 			ndump = 64;
+		else if (ndump > MAX_DUMP)
+			ndump = MAX_DUMP;
 		prdump(adrs, ndump);
 		adrs += ndump;
 		last_cmd = "d\n";
@@ -2360,9 +2408,9 @@
 	if (cmd == '\n') {
 		/* show current state */
 		unsigned long i;
-		printf("naca->debug_switch = 0x%lx\n", naca->debug_switch);
+		printf("ppc64_debug_switch = 0x%lx\n", ppc64_debug_switch);
 		for (i = 0; i < PPCDBG_NUM_FLAGS ;i++) {
-			on = PPCDBG_BITVAL(i) & naca->debug_switch;
+			on = PPCDBG_BITVAL(i) & ppc64_debug_switch;
 			printf("%02x %s %12s   ", i, on ? "on " : "off",  trace_names[i] ? trace_names[i] : "");
 			if (((i+1) % 3) == 0)
 				printf("\n");
@@ -2376,7 +2424,7 @@
 			on = (cmd == '+');
 			cmd = inchar();
 			if (cmd == ' ' || cmd == '\n') {  /* Turn on or off based on + or - */
-				naca->debug_switch = on ? PPCDBG_ALL:PPCDBG_NONE;
+				ppc64_debug_switch = on ? PPCDBG_ALL:PPCDBG_NONE;
 				printf("Setting all values to %s...\n", on ? "on" : "off");
 				if (cmd == '\n') return;
 				else cmd = skipbl(); 
@@ -2391,10 +2439,10 @@
 			return;
 		}
 		if (on) {
-			naca->debug_switch |= PPCDBG_BITVAL(val);
+			ppc64_debug_switch |= PPCDBG_BITVAL(val);
 			printf("enable debug %x %s\n", val, trace_names[val] ? trace_names[val] : "");
 		} else {
-			naca->debug_switch &= ~PPCDBG_BITVAL(val);
+			ppc64_debug_switch &= ~PPCDBG_BITVAL(val);
 			printf("disable debug %x %s\n", val, trace_names[val] ? trace_names[val] : "");
 		}
 		cmd = skipbl();
diff -Nru a/arch/s390/Kconfig b/arch/s390/Kconfig
--- a/arch/s390/Kconfig	2005-03-01 23:38:55 -08:00
+++ b/arch/s390/Kconfig	2005-03-01 23:38:55 -08:00
@@ -14,6 +14,10 @@
 	bool
 	default y
 
+config GENERIC_CALIBRATE_DELAY
+	bool
+	default y
+
 config GENERIC_BUST_SPINLOCK
 	bool
 
@@ -81,7 +85,8 @@
 
 config HOTPLUG_CPU
 	bool "Support for hot-pluggable CPUs (EXPERIMENTAL)"
-	depends on SMP && HOTPLUG && EXPERIMENTAL
+	depends on SMP && EXPERIMENTAL
+	select HOTPLUG
 	default n
 	help
 	  Say Y here to experiment with turning CPUs off and on.  CPUs
@@ -361,6 +366,13 @@
 	help
 	  This provides a kernel interface for virtual CPU timers.
 	  Default is disabled.
+
+config VIRT_CPU_ACCOUNTING
+	bool "Base user process accounting on virtual cpu timer"
+	depends on VIRT_TIMER
+	help
+	  Select this option to use CPU timer deltas to do user
+	  process accounting.
 
 config APPLDATA_BASE
 	bool "Linux - VM Monitor Stream, base infrastructure"
diff -Nru a/arch/s390/appldata/appldata_base.c b/arch/s390/appldata/appldata_base.c
--- a/arch/s390/appldata/appldata_base.c	2005-03-01 23:39:18 -08:00
+++ b/arch/s390/appldata/appldata_base.c	2005-03-01 23:39:18 -08:00
@@ -128,7 +128,7 @@
 DEFINE_PER_CPU(struct vtimer_list, appldata_timer);
 static atomic_t appldata_expire_count = ATOMIC_INIT(0);
 
-static spinlock_t appldata_timer_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(appldata_timer_lock);
 static int appldata_interval = APPLDATA_CPU_INTERVAL;
 static int appldata_timer_active;
 
@@ -140,7 +140,7 @@
 /*
  * Ops list
  */
-static spinlock_t appldata_ops_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(appldata_ops_lock);
 static LIST_HEAD(appldata_ops_list);
 
 
diff -Nru a/arch/s390/defconfig b/arch/s390/defconfig
--- a/arch/s390/defconfig	2005-03-01 23:39:09 -08:00
+++ b/arch/s390/defconfig	2005-03-01 23:39:09 -08:00
@@ -1,10 +1,11 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc2
-# Tue Nov 30 14:00:30 2004
+# Linux kernel version: 2.6.11-rc2
+# Mon Jan 31 16:27:12 2005
 #
 CONFIG_MMU=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_ARCH_S390=y
 CONFIG_UID16=y
 
@@ -142,6 +143,7 @@
 #
 # CONFIG_SCSI_SPI_ATTRS is not set
 CONFIG_SCSI_FC_ATTRS=y
+# CONFIG_SCSI_ISCSI_ATTRS is not set
 
 #
 # SCSI low-level drivers
@@ -154,10 +156,12 @@
 #
 # Block devices
 #
+# 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=y
+CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
@@ -183,6 +187,7 @@
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
+# CONFIG_ATA_OVER_ETH is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -529,6 +534,7 @@
 # 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
 
 #
 # Security options
@@ -567,8 +573,12 @@
 # CONFIG_CRYPTO_TEST is not set
 
 #
+# Hardware crypto devices
+#
+
+#
 # Library routines
 #
 # CONFIG_CRC_CCITT is not set
-# CONFIG_CRC32 is not set
+CONFIG_CRC32=m
 # CONFIG_LIBCRC32C is not set
diff -Nru a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile
--- a/arch/s390/kernel/Makefile	2005-03-01 23:39:17 -08:00
+++ b/arch/s390/kernel/Makefile	2005-03-01 23:39:17 -08:00
@@ -17,7 +17,7 @@
 
 obj-$(CONFIG_S390_SUPPORT)	+= compat_linux.o compat_signal.o \
 					compat_ioctl.o compat_wrapper.o \
-					compat_exec.o compat_exec_domain.o
+					compat_exec_domain.o
 obj-$(CONFIG_BINFMT_ELF32)	+= binfmt_elf32.o
 
 obj-$(CONFIG_ARCH_S390_31)	+= entry.o reipl.o
diff -Nru a/arch/s390/kernel/binfmt_elf32.c b/arch/s390/kernel/binfmt_elf32.c
--- a/arch/s390/kernel/binfmt_elf32.c	2005-03-01 23:39:16 -08:00
+++ b/arch/s390/kernel/binfmt_elf32.c	2005-03-01 23:39:16 -08:00
@@ -140,8 +140,6 @@
 #include <linux/binfmts.h>
 #include <linux/compat.h>
 
-int setup_arg_pages32(struct linux_binprm *bprm, int executable_stack);
-
 #define elf_prstatus elf_prstatus32
 struct elf_prstatus32
 {
@@ -191,7 +189,6 @@
 
 #undef start_thread
 #define start_thread                    start_thread31 
-#define setup_arg_pages(bprm, exec)     setup_arg_pages32(bprm, exec)
 
 MODULE_DESCRIPTION("Binary format loader for compatibility with 32bit Linux for S390 binaries,"
                    " Copyright 2000 IBM Corporation"); 
@@ -200,12 +197,13 @@
 #undef MODULE_DESCRIPTION
 #undef MODULE_AUTHOR
 
-#define jiffies_to_timeval jiffies_to_compat_timeval
+#undef cputime_to_timeval
+#define cputime_to_timeval cputime_to_compat_timeval
 static __inline__ void
-jiffies_to_compat_timeval(unsigned long jiffies, struct compat_timeval *value)
+cputime_to_compat_timeval(const cputime_t cputime, struct compat_timeval *value)
 {
-	value->tv_usec = (jiffies % HZ) * (1000000L / HZ);
-	value->tv_sec = jiffies / HZ;
+	value->tv_usec = cputime % 1000000;
+	value->tv_sec = cputime / 1000000;
 }
 
 #include "../../../fs/binfmt_elf.c"
diff -Nru a/arch/s390/kernel/compat_exec.c b/arch/s390/kernel/compat_exec.c
--- a/arch/s390/kernel/compat_exec.c	2005-03-01 23:39:09 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,92 +0,0 @@
-/*
- * Support for 32-bit Linux for S390 ELF binaries.
- *
- * Copyright (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
- * Author(s): Gerhard Tonn (ton@de.ibm.com)
- *
- * Separated from binfmt_elf32.c to reduce exports for module enablement.
- *
- */
-
-#include <linux/config.h>
-#include <linux/slab.h>
-#include <linux/file.h>
-#include <linux/mman.h>
-#include <linux/a.out.h>
-#include <linux/stat.h>
-#include <linux/fcntl.h>
-#include <linux/smp_lock.h>
-#include <linux/init.h>
-#include <linux/pagemap.h>
-#include <linux/mm.h>
-#include <linux/highmem.h>
-#include <linux/spinlock.h>
-#include <linux/binfmts.h>
-#include <linux/module.h>
-#include <linux/security.h>
-
-#include <asm/uaccess.h>
-#include <asm/pgalloc.h>
-#include <asm/mmu_context.h>
-
-#ifdef CONFIG_KMOD
-#include <linux/kmod.h>
-#endif
-
-
-int setup_arg_pages32(struct linux_binprm *bprm, int executable_stack)
-{
-	unsigned long stack_base;
-	struct vm_area_struct *mpnt;
-	struct mm_struct *mm = current->mm;
-	int i, ret;
-
-	stack_base = STACK_TOP - MAX_ARG_PAGES*PAGE_SIZE;
-	mm->arg_start = bprm->p + stack_base;
-
-	bprm->p += stack_base;
-	if (bprm->loader)
-		bprm->loader += stack_base;
-	bprm->exec += stack_base;
-
-	mpnt = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
-	if (!mpnt) 
-		return -ENOMEM; 
-	
-	if (security_vm_enough_memory((STACK_TOP - (PAGE_MASK & (unsigned long) bprm->p))>>PAGE_SHIFT)) {
-		kmem_cache_free(vm_area_cachep, mpnt);
-		return -ENOMEM;
-	}
-
-	memset(mpnt, 0, sizeof(*mpnt));
-
-	down_write(&mm->mmap_sem);
-	{
-		mpnt->vm_mm = mm;
-		mpnt->vm_start = PAGE_MASK & (unsigned long) bprm->p;
-		mpnt->vm_end = STACK_TOP;
-		/* executable stack setting would be applied here */
-		mpnt->vm_page_prot = PAGE_COPY;
-		mpnt->vm_flags = VM_STACK_FLAGS;
-		if ((ret = insert_vm_struct(mm, mpnt))) {
-			up_write(&mm->mmap_sem);
-			kmem_cache_free(vm_area_cachep, mpnt);
-			return ret;
-		}
-		mm->stack_vm = mm->total_vm = vma_pages(mpnt);
-	} 
-
-	for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
-		struct page *page = bprm->page[i];
-		if (page) {
-			bprm->page[i] = NULL;
-			install_arg_page(mpnt, page, stack_base);
-		}
-		stack_base += PAGE_SIZE;
-	}
-	up_write(&mm->mmap_sem);
-	
-	return 0;
-}
-
-EXPORT_SYMBOL(setup_arg_pages32);
diff -Nru a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c
--- a/arch/s390/kernel/compat_linux.c	2005-03-01 23:39:09 -08:00
+++ b/arch/s390/kernel/compat_linux.c	2005-03-01 23:39:09 -08:00
@@ -331,7 +331,7 @@
 	case SHMDT:
 		return sys_shmdt(compat_ptr(ptr));
 	case SHMGET:
-		return sys_shmget(first, second, third);
+		return sys_shmget(first, (unsigned)second, third);
 	case SHMCTL:
 		return compat_sys_shmctl(first, second, compat_ptr(ptr));
 	}
@@ -355,136 +355,6 @@
 		return sys_ftruncate(fd, (high << 32) | low);
 }
 
-/* readdir & getdents */
-
-#define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
-#define ROUND_UP(x) (((x)+sizeof(u32)-1) & ~(sizeof(u32)-1))
-
-struct old_linux_dirent32 {
-	u32		d_ino;
-	u32		d_offset;
-	unsigned short	d_namlen;
-	char		d_name[1];
-};
-
-struct readdir_callback32 {
-	struct old_linux_dirent32 * dirent;
-	int count;
-};
-
-static int fillonedir(void * __buf, const char * name, int namlen,
-		      loff_t offset, ino_t ino, unsigned int d_type)
-{
-	struct readdir_callback32 * buf = (struct readdir_callback32 *) __buf;
-	struct old_linux_dirent32 * dirent;
-
-	if (buf->count)
-		return -EINVAL;
-	buf->count++;
-	dirent = buf->dirent;
-	put_user(ino, &dirent->d_ino);
-	put_user(offset, &dirent->d_offset);
-	put_user(namlen, &dirent->d_namlen);
-	copy_to_user(dirent->d_name, name, namlen);
-	put_user(0, dirent->d_name + namlen);
-	return 0;
-}
-
-asmlinkage long old32_readdir(unsigned int fd, struct old_linux_dirent32 *dirent, unsigned int count)
-{
-	int error = -EBADF;
-	struct file * file;
-	struct readdir_callback32 buf;
-
-	file = fget(fd);
-	if (!file)
-		goto out;
-
-	buf.count = 0;
-	buf.dirent = dirent;
-
-	error = vfs_readdir(file, fillonedir, &buf);
-	if (error < 0)
-		goto out_putf;
-	error = buf.count;
-
-out_putf:
-	fput(file);
-out:
-	return error;
-}
-
-struct linux_dirent32 {
-	u32		d_ino;
-	u32		d_off;
-	unsigned short	d_reclen;
-	char		d_name[1];
-};
-
-struct getdents_callback32 {
-	struct linux_dirent32 * current_dir;
-	struct linux_dirent32 * previous;
-	int count;
-	int error;
-};
-
-static int filldir(void * __buf, const char * name, int namlen, loff_t offset, ino_t ino,
-		   unsigned int d_type)
-{
-	struct linux_dirent32 * dirent;
-	struct getdents_callback32 * buf = (struct getdents_callback32 *) __buf;
-	int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);
-
-	buf->error = -EINVAL;	/* only used if we fail.. */
-	if (reclen > buf->count)
-		return -EINVAL;
-	dirent = buf->previous;
-	if (dirent)
-		put_user(offset, &dirent->d_off);
-	dirent = buf->current_dir;
-	buf->previous = dirent;
-	put_user(ino, &dirent->d_ino);
-	put_user(reclen, &dirent->d_reclen);
-	copy_to_user(dirent->d_name, name, namlen);
-	put_user(0, dirent->d_name + namlen);
-	buf->current_dir = ((void *)dirent) + reclen;
-	buf->count -= reclen;
-	return 0;
-}
-
-asmlinkage long sys32_getdents(unsigned int fd, struct linux_dirent32 *dirent, unsigned int count)
-{
-	struct file * file;
-	struct linux_dirent32 * lastdirent;
-	struct getdents_callback32 buf;
-	int error = -EBADF;
-
-	file = fget(fd);
-	if (!file)
-		goto out;
-
-	buf.current_dir = dirent;
-	buf.previous = NULL;
-	buf.count = count;
-	buf.error = 0;
-
-	error = vfs_readdir(file, filldir, &buf);
-	if (error < 0)
-		goto out_putf;
-	lastdirent = buf.previous;
-	error = buf.error;
-	if(lastdirent) {
-		put_user(file->f_pos, &lastdirent->d_off);
-		error = count - buf.count;
-	}
-out_putf:
-	fput(file);
-out:
-	return error;
-}
-
-/* end of readdir & getdents */
-
 int cp_compat_stat(struct kstat *stat, struct compat_stat *statbuf)
 {
 	int err;
@@ -634,92 +504,8 @@
 	return ret;
 }
 
-extern int
-copy_siginfo_to_user32(siginfo_t32 *to, siginfo_t *from);
-
-asmlinkage long
-sys32_rt_sigtimedwait(compat_sigset_t *uthese, siginfo_t32 *uinfo,
-		      struct compat_timespec *uts, size_t sigsetsize)
-{
-	int ret, sig;
-	sigset_t these;
-	compat_sigset_t these32;
-	struct timespec ts;
-	siginfo_t info;
-	long timeout = 0;
-
-	/* XXX: Don't preclude handling different sized sigset_t's.  */
-	if (sigsetsize != sizeof(sigset_t))
-		return -EINVAL;
-
-	if (copy_from_user (&these32, uthese, sizeof(compat_sigset_t)))
-		return -EFAULT;
-
-	switch (_NSIG_WORDS) {
-	case 4: these.sig[3] = these32.sig[6] | (((long)these32.sig[7]) << 32);
-	case 3: these.sig[2] = these32.sig[4] | (((long)these32.sig[5]) << 32);
-	case 2: these.sig[1] = these32.sig[2] | (((long)these32.sig[3]) << 32);
-	case 1: these.sig[0] = these32.sig[0] | (((long)these32.sig[1]) << 32);
-	}
-		
-	/*
-	 * Invert the set of allowed signals to get those we
-	 * want to block.
-	 */
-	sigdelsetmask(&these, sigmask(SIGKILL)|sigmask(SIGSTOP));
-	signotset(&these);
-
-	if (uts) {
-		if (get_compat_timespec(&ts, uts))
-			return -EINVAL;
-		if (ts.tv_nsec >= 1000000000L || ts.tv_nsec < 0
-		    || ts.tv_sec < 0)
-			return -EINVAL;
-	}
-
-	spin_lock_irq(&current->sighand->siglock);
-	sig = dequeue_signal(current, &these, &info);
-	if (!sig) {
-		/* None ready -- temporarily unblock those we're interested
-		   in so that we'll be awakened when they arrive.  */
-		current->real_blocked = current->blocked;
-		sigandsets(&current->blocked, &current->blocked, &these);
-		recalc_sigpending();
-		spin_unlock_irq(&current->sighand->siglock);
-
-		timeout = MAX_SCHEDULE_TIMEOUT;
-		if (uts)
-			timeout = (timespec_to_jiffies(&ts)
-				   + (ts.tv_sec || ts.tv_nsec));
-
-		current->state = TASK_INTERRUPTIBLE;
-		timeout = schedule_timeout(timeout);
-
-		spin_lock_irq(&current->sighand->siglock);
-		sig = dequeue_signal(current, &these, &info);
-		current->blocked = current->real_blocked;
-		siginitset(&current->real_blocked, 0);
-		recalc_sigpending();
-	}
-	spin_unlock_irq(&current->sighand->siglock);
-
-	if (sig) {
-		ret = sig;
-		if (uinfo) {
-			if (copy_siginfo_to_user32(uinfo, &info))
-				ret = -EFAULT;
-		}
-	} else {
-		ret = -EAGAIN;
-		if (timeout)
-			ret = -EINTR;
-	}
-
-	return ret;
-}
-
 asmlinkage long
-sys32_rt_sigqueueinfo(int pid, int sig, siginfo_t32 __user *uinfo)
+sys32_rt_sigqueueinfo(int pid, int sig, compat_siginfo_t __user *uinfo)
 {
 	siginfo_t info;
 	int ret;
@@ -990,6 +776,7 @@
 	return ret;
 }
 
+#ifdef CONFIG_SYSCTL
 struct __sysctl_args32 {
 	u32 name;
 	int nlen;
@@ -1037,6 +824,7 @@
 	}
 	return error;
 }
+#endif
 
 struct stat64_emu31 {
 	unsigned long long  st_dev;
diff -Nru a/arch/s390/kernel/compat_linux.h b/arch/s390/kernel/compat_linux.h
--- a/arch/s390/kernel/compat_linux.h	2005-03-01 23:39:07 -08:00
+++ b/arch/s390/kernel/compat_linux.h	2005-03-01 23:39:07 -08:00
@@ -34,7 +34,7 @@
         __u32   sival_ptr;
 } sigval_t32;
                  
-typedef struct siginfo32 {
+typedef struct compat_siginfo {
 	int	si_signo;
 	int	si_errno;
 	int	si_code;
@@ -50,9 +50,10 @@
 
 		/* POSIX.1b timers */
 		struct {
-			unsigned int	_timer1;
-			unsigned int	_timer2;
-                
+			timer_t _tid;		/* timer id */
+			int _overrun;		/* overrun count */
+			sigval_t _sigval;	/* same as below */
+			int _sys_private;       /* not to be passed to user */
 		} _timer;
 
 		/* POSIX.1b signals */
@@ -82,7 +83,7 @@
 			int	_fd;
 		} _sigpoll;
 	} _sifields;
-} siginfo_t32;  
+} compat_siginfo_t;
 
 /*
  * How these fields are to be accessed.
@@ -98,6 +99,8 @@
 #define si_addr		_sifields._sigfault._addr
 #define si_band		_sifields._sigpoll._band
 #define si_fd		_sifields._sigpoll._fd    
+#define si_tid		_sifields._timer._tid
+#define si_overrun	_sifields._timer._overrun
 
 /* asm/sigcontext.h */
 typedef union
@@ -213,8 +216,5 @@
 		} _sigev_thread;
 	} _sigev_un;
 };
-
-extern int copy_siginfo_to_user32(siginfo_t32 __user *to, siginfo_t *from);
-extern int copy_siginfo_from_user32(siginfo_t *to, siginfo_t32 __user *from);
 
 #endif /* _ASM_S390X_S390_H */
diff -Nru a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c
--- a/arch/s390/kernel/compat_signal.c	2005-03-01 23:39:16 -08:00
+++ b/arch/s390/kernel/compat_signal.c	2005-03-01 23:39:16 -08:00
@@ -48,17 +48,17 @@
 {
 	__u8 callee_used_stack[__SIGNAL_FRAMESIZE32];
 	__u8 retcode[S390_SYSCALL_SIZE];
-	struct siginfo32 info;
+	compat_siginfo_t info;
 	struct ucontext32 uc;
 } rt_sigframe32;
 
 asmlinkage int FASTCALL(do_signal(struct pt_regs *regs, sigset_t *oldset));
 
-int copy_siginfo_to_user32(siginfo_t32 __user *to, siginfo_t *from)
+int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
 {
 	int err;
 
-	if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t32)))
+	if (!access_ok (VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
 		return -EFAULT;
 
 	/* If you change siginfo_t structure, please be sure
@@ -95,10 +95,14 @@
 					  &to->si_addr);
 			break;
 		case __SI_POLL >> 16:
-		case __SI_TIMER >> 16:
 			err |= __put_user(from->si_band, &to->si_band);
 			err |= __put_user(from->si_fd, &to->si_fd);
 			break;
+		case __SI_TIMER >> 16:
+			err |= __put_user(from->si_tid, &to->si_tid);
+			err |= __put_user(from->si_overrun, &to->si_overrun);
+			err |= __put_user(from->si_int, &to->si_int);
+			break;
 		default:
 			break;
 		}
@@ -106,12 +110,12 @@
 	return err;
 }
 
-int copy_siginfo_from_user32(siginfo_t *to, siginfo_t32 __user *from)
+int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
 {
 	int err;
 	u32 tmp;
 
-	if (!access_ok (VERIFY_READ, from, sizeof(siginfo_t32)))
+	if (!access_ok (VERIFY_READ, from, sizeof(compat_siginfo_t)))
 		return -EFAULT;
 
 	err = __get_user(to->si_signo, &from->si_signo);
@@ -142,9 +146,13 @@
 			to->si_addr = (void *)(u64) (tmp & PSW32_ADDR_INSN);
 			break;
 		case __SI_POLL >> 16:
-		case __SI_TIMER >> 16:
 			err |= __get_user(to->si_band, &from->si_band);
 			err |= __get_user(to->si_fd, &from->si_fd);
+			break;
+		case __SI_TIMER >> 16:
+			err |= __get_user(to->si_tid, &from->si_tid);
+			err |= __get_user(to->si_overrun, &from->si_overrun);
+			err |= __get_user(to->si_int, &from->si_int);
 			break;
 		default:
 			break;
diff -Nru a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S
--- a/arch/s390/kernel/compat_wrapper.S	2005-03-01 23:39:18 -08:00
+++ b/arch/s390/kernel/compat_wrapper.S	2005-03-01 23:39:18 -08:00
@@ -64,7 +64,7 @@
 	.globl  sys32_time_wrapper 
 sys32_time_wrapper:
 	llgtr	%r2,%r2			# int *
-	jg	sys_time		# branch to system call
+	jg	compat_sys_time		# branch to system call
 
 	.globl  sys32_mknod_wrapper 
 sys32_mknod_wrapper:
@@ -391,7 +391,7 @@
 	llgfr	%r2,%r2			# unsigned int
 	llgtr	%r3,%r3			# void *
 	llgfr	%r4,%r4			# unsigned int
-	jg	old32_readdir		# branch to system call
+	jg	compat_sys_old_readdir	# branch to system call
 
 	.globl  old32_mmap_wrapper 
 old32_mmap_wrapper:
@@ -639,7 +639,7 @@
 	llgfr	%r2,%r2			# unsigned int
 	llgtr	%r3,%r3			# void *
 	llgfr	%r4,%r4			# unsigned int
-	jg	sys32_getdents		# branch to system call
+	jg	compat_sys_getdents	# branch to system call
 
 	.globl  compat_sys_select_wrapper
 compat_sys_select_wrapper:
@@ -840,13 +840,13 @@
 	llgfr	%r3,%r3			# size_t
 	jg	sys32_rt_sigpending	# branch to system call
 
-	.globl  sys32_rt_sigtimedwait_wrapper 
-sys32_rt_sigtimedwait_wrapper:
+	.globl  compat_sys_rt_sigtimedwait_wrapper
+compat_sys_rt_sigtimedwait_wrapper:
 	llgtr	%r2,%r2			# const sigset_emu31_t *
 	llgtr	%r3,%r3			# siginfo_emu31_t *
 	llgtr	%r4,%r4			# const struct compat_timespec *
 	llgfr	%r5,%r5			# size_t
-	jg	sys32_rt_sigtimedwait	# branch to system call
+	jg	compat_sys_rt_sigtimedwait	# branch to system call
 
 	.globl  sys32_rt_sigqueueinfo_wrapper 
 sys32_rt_sigqueueinfo_wrapper:
@@ -1076,8 +1076,8 @@
 
 	.globl	sys32_stime_wrapper
 sys32_stime_wrapper:
-	llgtr	%r2,%r2			# int *
-	jg	sys_stime		# branch to system call
+	llgtr	%r2,%r2			# long *
+	jg	compat_sys_stime	# branch to system call
 
 	.globl  sys32_sysctl_wrapper
 sys32_sysctl_wrapper:
diff -Nru a/arch/s390/kernel/cpcmd.c b/arch/s390/kernel/cpcmd.c
--- a/arch/s390/kernel/cpcmd.c	2005-03-01 23:38:56 -08:00
+++ b/arch/s390/kernel/cpcmd.c	2005-03-01 23:38:56 -08:00
@@ -4,34 +4,41 @@
  *  S390 version
  *    Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
  *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
+ *               Christian Borntraeger (cborntra@de.ibm.com),
  */
 
-#include <linux/stddef.h>
 #include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/stddef.h>
 #include <linux/string.h>
 #include <asm/ebcdic.h>
-#include <linux/spinlock.h>
 #include <asm/cpcmd.h>
 #include <asm/system.h>
 
-static spinlock_t cpcmd_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(cpcmd_lock);
 static char cpcmd_buf[240];
 
-void cpcmd(char *cmd, char *response, int rlen)
+/*
+ * the caller of __cpcmd has to ensure that the response buffer is below 2 GB
+ */
+void __cpcmd(char *cmd, char *response, int rlen)
 {
-        const int mask = 0x40000000L;
+	const int mask = 0x40000000L;
 	unsigned long flags;
-        int cmdlen;
+	int cmdlen;
 
 	spin_lock_irqsave(&cpcmd_lock, flags);
 	cmdlen = strlen(cmd);
-	BUG_ON(cmdlen>240);
+	BUG_ON(cmdlen > 240);
 	strcpy(cpcmd_buf, cmd);
 	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"
+		asm volatile ("LRA   2,0(%0)\n\t"
                               "LR    4,%1\n\t"
                               "O     4,%4\n\t"
                               "LRA   3,0(%2)\n\t"
@@ -78,3 +85,27 @@
 	spin_unlock_irqrestore(&cpcmd_lock, flags);
 }
 
+EXPORT_SYMBOL(__cpcmd);
+
+#ifdef CONFIG_ARCH_S390X
+void cpcmd(char *cmd, char *response, int rlen)
+{
+	char *lowbuf;
+	if ((rlen == 0) || (response == NULL)
+	    || !((unsigned long)response >> 31))
+		__cpcmd(cmd, response, rlen);
+	else {
+		lowbuf = kmalloc(rlen, GFP_KERNEL | GFP_DMA);
+		if (!lowbuf) {
+			printk(KERN_WARNING
+				"cpcmd: could not allocate response buffer\n");
+			return;
+		}
+		__cpcmd(cmd, lowbuf, rlen);
+		memcpy(response, lowbuf, rlen);
+		kfree(lowbuf);
+	}
+}
+
+EXPORT_SYMBOL(cpcmd);
+#endif		/* CONFIG_ARCH_S390X */
diff -Nru a/arch/s390/kernel/debug.c b/arch/s390/kernel/debug.c
--- a/arch/s390/kernel/debug.c	2005-03-01 23:38:52 -08:00
+++ b/arch/s390/kernel/debug.c	2005-03-01 23:38:52 -08:00
@@ -931,7 +931,7 @@
 	int rc = 0;
 	int i;
 	unsigned long flags;
-	mode_t mode = S_IFREG;
+	mode_t mode = S_IFREG | S_IRUSR | S_IWUSR;
 	struct proc_dir_entry *pde;
 
 	if (!id)
diff -Nru a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
--- a/arch/s390/kernel/entry.S	2005-03-01 23:38:53 -08:00
+++ b/arch/s390/kernel/entry.S	2005-03-01 23:38:53 -08:00
@@ -66,6 +66,27 @@
  *    R15 - kernel stack pointer
  */
 
+	.macro  STORE_TIMER lc_offset
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+	stpt	\lc_offset
+#endif
+	.endm
+
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+	.macro  UPDATE_VTIME lc_from,lc_to,lc_sum
+	lm	%r10,%r11,\lc_from
+	sl	%r10,\lc_to
+	sl	%r11,\lc_to+4
+	bc	3,BASED(0f)
+	sl	%r10,BASED(.Lc_1)
+0:	al	%r10,\lc_sum
+	al	%r11,\lc_sum+4
+	bc	12,BASED(1f)
+	al	%r10,BASED(.Lc_1)
+1:	stm	%r10,%r11,\lc_sum
+	.endm
+#endif
+
 	.macro	SAVE_ALL_BASE savearea
 	stm	%r12,%r15,\savearea
 	l	%r13,__LC_SVC_NEW_PSW+4	# load &system_call to %r13
@@ -118,6 +139,7 @@
 	ni	__LC_RETURN_PSW+1,0xfd	# clear wait state bit
 	.endif
 	lm	%r0,%r15,SP_R0(%r15)	# load gprs 0-15 of user
+	STORE_TIMER __LC_EXIT_TIMER
 	lpsw	__LC_RETURN_PSW		# back to caller
 	.endm
 
@@ -159,9 +181,21 @@
 
 	.globl  system_call
 system_call:
+	STORE_TIMER __LC_SYNC_ENTER_TIMER
+sysc_saveall:
 	SAVE_ALL_BASE __LC_SAVE_AREA
         SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1
 	lh	%r7,0x8a	  # get svc number from lowcore
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+sysc_vtime:
+	tm	SP_PSW+1(%r15),0x01	# interrupting from user ?
+	bz	BASED(sysc_do_svc)
+	UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
+sysc_stime:
+	UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
+sysc_update:
+	mvc	__LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
+#endif
 sysc_do_svc:
 	l	%r9,__LC_THREAD_INFO	# load pointer to thread_info struct
 	sla	%r7,2             # *4 and test for svc 0
@@ -391,10 +425,19 @@
  * we just ignore the PER event (FIXME: is there anything we have to do
  * for LPSW?).
  */
+	STORE_TIMER __LC_SYNC_ENTER_TIMER
 	SAVE_ALL_BASE __LC_SAVE_AREA
         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
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+	tm	SP_PSW+1(%r15),0x01	# interrupting from user ?
+	bz	BASED(pgm_no_vtime)
+	UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
+	UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
+	mvc	__LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
+pgm_no_vtime:
+#endif
 	l	%r9,__LC_THREAD_INFO	# load pointer to thread_info struct
         l       %r3,__LC_PGM_ILC         # load program interruption code
 	la	%r8,0x7f
@@ -425,6 +468,14 @@
 #
 pgm_per_std:
 	SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+	tm	SP_PSW+1(%r15),0x01	# interrupting from user ?
+	bz	BASED(pgm_no_vtime2)
+	UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
+	UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
+	mvc	__LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
+pgm_no_vtime2:
+#endif
 	l	%r9,__LC_THREAD_INFO	# load pointer to thread_info struct
 	l	%r1,__TI_task(%r9)
 	mvc	__THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID
@@ -442,6 +493,14 @@
 #
 pgm_svcper:
 	SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+	tm	SP_PSW+1(%r15),0x01	# interrupting from user ?
+	bz	BASED(pgm_no_vtime3)
+	UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
+	UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
+	mvc	__LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
+pgm_no_vtime3:
+#endif
 	lh	%r7,0x8a		# get svc number from lowcore
 	l	%r9,__LC_THREAD_INFO	# load pointer to thread_info struct
 	l	%r1,__TI_task(%r9)
@@ -458,9 +517,18 @@
 
         .globl io_int_handler
 io_int_handler:
+	STORE_TIMER __LC_ASYNC_ENTER_TIMER
 	stck	__LC_INT_CLOCK
 	SAVE_ALL_BASE __LC_SAVE_AREA+16
         SAVE_ALL __LC_IO_OLD_PSW,__LC_SAVE_AREA+16,0
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+	tm	SP_PSW+1(%r15),0x01	# interrupting from user ?
+	bz	BASED(io_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
+io_no_vtime:
+#endif
 	l	%r9,__LC_THREAD_INFO	# load pointer to thread_info struct
         l       %r1,BASED(.Ldo_IRQ)        # load address of do_IRQ
         la      %r2,SP_PTREGS(%r15) # address of register-save area
@@ -549,9 +617,18 @@
 
         .globl  ext_int_handler
 ext_int_handler:
+	STORE_TIMER __LC_ASYNC_ENTER_TIMER
 	stck	__LC_INT_CLOCK
 	SAVE_ALL_BASE __LC_SAVE_AREA+16
         SAVE_ALL __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16,0
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+	tm	SP_PSW+1(%r15),0x01	# interrupting from user ?
+	bz	BASED(ext_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
+ext_no_vtime:
+#endif
 	l	%r9,__LC_THREAD_INFO	# load pointer to thread_info struct
 	la	%r2,SP_PTREGS(%r15)    # address of register-save area
 	lh	%r3,__LC_EXT_INT_CODE  # get interruption code
@@ -565,8 +642,17 @@
 
         .globl mcck_int_handler
 mcck_int_handler:
+	STORE_TIMER __LC_ASYNC_ENTER_TIMER
 	SAVE_ALL_BASE __LC_SAVE_AREA+32
         SAVE_ALL __LC_MCK_OLD_PSW,__LC_SAVE_AREA+32,0
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+	tm	SP_PSW+1(%r15),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
 	l       %r1,BASED(.Ls390_mcck)
 	basr    %r14,%r1	  # call machine check handler
 mcck_return:
@@ -661,17 +747,47 @@
 	br	%r14
 
 cleanup_system_call:
-	mvc	__LC_RETURN_PSW(4),0(%r12)
-	clc	4(4,%r12),BASED(cleanup_table_system_call)
-	bne	BASED(0f)
+	mvc	__LC_RETURN_PSW(8),0(%r12)
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+	clc	__LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+4)
+	bh	BASED(0f)
+	mvc	__LC_SYNC_ENTER_TIMER(8),__LC_ASYNC_ENTER_TIMER
+0:	clc	__LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+8)
+	bhe	BASED(cleanup_vtime)
+#endif
+	clc	__LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn)
+	bh	BASED(0f)
 	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
 	st	%r15,__LC_SAVE_AREA+28
 	lh	%r7,0x8a
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+cleanup_vtime:
+	clc	__LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+12)
+	bhe	BASED(cleanup_stime)
+	tm	SP_PSW+1(%r15),0x01	# interrupting from user ?
+	bz	BASED(cleanup_novtime)
+	UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
+cleanup_stime:
+	clc	__LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+16)
+	bh	BASED(cleanup_update)
+	UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
+cleanup_update:
+	mvc	__LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
+cleanup_novtime:
+#endif
 	mvc	__LC_RETURN_PSW+4(4),BASED(cleanup_table_system_call+4)
 	la	%r12,__LC_RETURN_PSW
 	br	%r14
+cleanup_system_call_insn:
+	.long	sysc_saveall + 0x80000000
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+	.long   system_call + 0x80000000
+	.long   sysc_vtime + 0x80000000
+	.long   sysc_stime + 0x80000000
+	.long   sysc_update + 0x80000000
+#endif
 
 cleanup_sysc_return:
 	mvc	__LC_RETURN_PSW(4),0(%r12)
@@ -680,15 +796,23 @@
 	br	%r14
 
 cleanup_sysc_leave:
-	clc	4(4,%r12),BASED(cleanup_sysc_leave_lpsw)
+	clc	4(4,%r12),BASED(cleanup_sysc_leave_insn)
+	be	BASED(0f)
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+	mvc	__LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER
+	clc	4(4,%r12),BASED(cleanup_sysc_leave_insn+4)
 	be	BASED(0f)
+#endif
 	mvc	__LC_RETURN_PSW(8),SP_PSW(%r15)
 	mvc	__LC_SAVE_AREA+16(16),SP_R12(%r15)
 	lm	%r0,%r11,SP_R0(%r15)
 	l	%r15,SP_R15(%r15)
 0:	la	%r12,__LC_RETURN_PSW
 	br	%r14
-cleanup_sysc_leave_lpsw:
+cleanup_sysc_leave_insn:
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+	.long	sysc_leave + 14 + 0x80000000
+#endif
 	.long	sysc_leave + 10 + 0x80000000
 
 /*
@@ -704,6 +828,7 @@
 .L0x028:       .short 0x028
 .L0x030:       .short 0x030
 .L0x038:       .short 0x038
+.Lc_1:         .long  1
 
 /*
  * Symbol constants
diff -Nru a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
--- a/arch/s390/kernel/entry64.S	2005-03-01 23:38:53 -08:00
+++ b/arch/s390/kernel/entry64.S	2005-03-01 23:38:53 -08:00
@@ -58,6 +58,21 @@
 
 #define BASED(name) name-system_call(%r13)
 
+	.macro  STORE_TIMER lc_offset
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+	stpt	\lc_offset
+#endif
+	.endm
+
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+	.macro  UPDATE_VTIME lc_from,lc_to,lc_sum
+	lg	%r10,\lc_from
+	slg	%r10,\lc_to
+	alg	%r10,\lc_sum
+	stg	%r10,\lc_sum
+	.endm
+#endif
+
 /*
  * Register usage in interrupt handlers:
  *    R9  - pointer to current task structure
@@ -117,6 +132,7 @@
 	ni	__LC_RETURN_PSW+1,0xfd	# clear wait state bit
 	.endif
 	lmg	%r0,%r15,SP_R0(%r15)	# load gprs 0-15 of user
+	STORE_TIMER __LC_EXIT_TIMER
 	lpswe	__LC_RETURN_PSW		# back to caller
 	.endm
 
@@ -156,9 +172,21 @@
 
 	.globl  system_call
 system_call:
+	STORE_TIMER __LC_SYNC_ENTER_TIMER
+sysc_saveall:
 	SAVE_ALL_BASE __LC_SAVE_AREA
         SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1
 	llgh    %r7,__LC_SVC_INT_CODE # get svc number from lowcore
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+sysc_vtime:
+	tm	SP_PSW+1(%r15),0x01	# interrupting from user ?
+	jz	sysc_do_svc
+	UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
+sysc_stime:
+	UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
+sysc_update:
+	mvc	__LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
+#endif
 sysc_do_svc:
 	lg	%r9,__LC_THREAD_INFO	# load pointer to thread_info struct
         slag    %r7,%r7,2         # *4 and test for svc 0
@@ -441,10 +469,19 @@
  * we just ignore the PER event (FIXME: is there anything we have to do
  * for LPSW?).
  */
+	STORE_TIMER __LC_SYNC_ENTER_TIMER
 	SAVE_ALL_BASE __LC_SAVE_AREA
         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
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+	tm	SP_PSW+1(%r15),0x01	# interrupting from user ?
+	jz	pgm_no_vtime
+	UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
+	UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
+	mvc	__LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
+pgm_no_vtime:
+#endif
 	lg	%r9,__LC_THREAD_INFO	# load pointer to thread_info struct
 	lgf     %r3,__LC_PGM_ILC	 # load program interruption code
 	lghi	%r8,0x7f
@@ -475,6 +512,14 @@
 #
 pgm_per_std:
 	SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+	tm	SP_PSW+1(%r15),0x01	# interrupting from user ?
+	jz	pgm_no_vtime2
+	UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
+	UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
+	mvc	__LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
+pgm_no_vtime2:
+#endif
 	lg	%r9,__LC_THREAD_INFO	# load pointer to thread_info struct
 	lg	%r1,__TI_task(%r9)
 	mvc	__THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID
@@ -492,6 +537,14 @@
 #
 pgm_svcper:
 	SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+	tm	SP_PSW+1(%r15),0x01	# interrupting from user ?
+	jz	pgm_no_vtime3
+	UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
+	UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
+	mvc	__LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
+pgm_no_vtime3:
+#endif
 	llgh    %r7,__LC_SVC_INT_CODE	# get svc number from lowcore
 	lg	%r9,__LC_THREAD_INFO	# load pointer to thread_info struct
 	lg	%r1,__TI_task(%r9)
@@ -507,9 +560,18 @@
  */
         .globl io_int_handler
 io_int_handler:
+	STORE_TIMER __LC_ASYNC_ENTER_TIMER
 	stck	__LC_INT_CLOCK
 	SAVE_ALL_BASE __LC_SAVE_AREA+32
         SAVE_ALL __LC_IO_OLD_PSW,__LC_SAVE_AREA+32,0
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+	tm	SP_PSW+1(%r15),0x01	# interrupting from user ?
+	jz	io_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
+io_no_vtime:
+#endif
 	lg	%r9,__LC_THREAD_INFO	# load pointer to thread_info struct
         la      %r2,SP_PTREGS(%r15)    # address of register-save area
 	brasl   %r14,do_IRQ            # call standard irq handler
@@ -595,9 +657,18 @@
  */
         .globl  ext_int_handler
 ext_int_handler:
+	STORE_TIMER __LC_ASYNC_ENTER_TIMER
 	stck	__LC_INT_CLOCK
 	SAVE_ALL_BASE __LC_SAVE_AREA+32
         SAVE_ALL __LC_EXT_OLD_PSW,__LC_SAVE_AREA+32,0
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+	tm	SP_PSW+1(%r15),0x01	# interrupting from user ?
+	jz	ext_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
+ext_no_vtime:
+#endif
 	lg	%r9,__LC_THREAD_INFO	# load pointer to thread_info struct
 	la	%r2,SP_PTREGS(%r15)    # address of register-save area
 	llgh	%r3,__LC_EXT_INT_CODE  # get interruption code
@@ -609,8 +680,17 @@
  */
         .globl mcck_int_handler
 mcck_int_handler:
+	STORE_TIMER __LC_ASYNC_ENTER_TIMER
 	SAVE_ALL_BASE __LC_SAVE_AREA+64
         SAVE_ALL __LC_MCK_OLD_PSW,__LC_SAVE_AREA+64,0
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+	tm	SP_PSW+1(%r15),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
 mcck_return:
         RESTORE_ALL 0
@@ -700,17 +780,47 @@
 	br	%r14
 
 cleanup_system_call:
-	mvc	__LC_RETURN_PSW(8),0(%r12)
-	clc	8(8,%r12),BASED(cleanup_table_system_call)
-	jne	0f
+	mvc	__LC_RETURN_PSW(16),0(%r12)
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+	clc	__LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn+8)
+	jh	0f
+	mvc	__LC_SYNC_ENTER_TIMER(8),__LC_ASYNC_ENTER_TIMER
+0:	clc	__LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn+16)
+	jhe	cleanup_vtime
+#endif
+	clc	__LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn)
+	jh	0f
 	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
 	stg	%r15,__LC_SAVE_AREA+56
 	llgh	%r7,__LC_SVC_INT_CODE
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+cleanup_vtime:
+	clc	__LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn+24)
+	jhe	cleanup_stime
+	tm	SP_PSW+1(%r15),0x01	# interrupting from user ?
+	jz	cleanup_novtime
+	UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
+cleanup_stime:
+	clc	__LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn+32)
+	jh	cleanup_update
+	UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
+cleanup_update:
+	mvc	__LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
+cleanup_novtime:
+#endif
 	mvc	__LC_RETURN_PSW+8(8),BASED(cleanup_table_system_call+8)
 	la	%r12,__LC_RETURN_PSW
 	br	%r14
+cleanup_system_call_insn:
+	.quad	sysc_saveall
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+	.quad   system_call
+	.quad   sysc_vtime
+	.quad   sysc_stime
+	.quad   sysc_update
+#endif
 
 cleanup_sysc_return:
 	mvc	__LC_RETURN_PSW(8),0(%r12)
@@ -719,15 +829,23 @@
 	br	%r14
 
 cleanup_sysc_leave:
-	clc	8(8,%r12),BASED(cleanup_sysc_leave_lpsw)
+	clc	8(8,%r12),BASED(cleanup_sysc_leave_insn)
+	je	0f
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+	mvc	__LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER
+	clc	8(8,%r12),BASED(cleanup_sysc_leave_insn+8)
 	je	0f
+#endif
 	mvc	__LC_RETURN_PSW(16),SP_PSW(%r15)
 	mvc	__LC_SAVE_AREA+32(32),SP_R12(%r15)
 	lmg	%r0,%r11,SP_R0(%r15)
 	lg	%r15,SP_R15(%r15)
 0:	la	%r12,__LC_RETURN_PSW
 	br	%r14
-cleanup_sysc_leave_lpsw:
+cleanup_sysc_leave_insn:
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+	.quad	sysc_leave + 16
+#endif
 	.quad	sysc_leave + 12
 
 /*
diff -Nru a/arch/s390/kernel/irq.c b/arch/s390/kernel/irq.c
--- a/arch/s390/kernel/irq.c	2005-03-01 23:38:58 -08:00
+++ b/arch/s390/kernel/irq.c	2005-03-01 23:38:58 -08:00
@@ -71,6 +71,10 @@
 
 	local_irq_save(flags);
 
+	account_system_vtime(current);
+
+	local_bh_disable();
+
 	if (local_softirq_pending()) {
 		/* Get current stack pointer. */
 		asm volatile("la %0,0(15)" : "=a" (old));
@@ -92,6 +96,10 @@
 			/* We are already on the async stack. */
 			__do_softirq();
 	}
+
+	account_system_vtime(current);
+
+	__local_bh_enable();
 
 	local_irq_restore(flags);
 }
diff -Nru a/arch/s390/kernel/module.c b/arch/s390/kernel/module.c
--- a/arch/s390/kernel/module.c	2005-03-01 23:39:10 -08:00
+++ b/arch/s390/kernel/module.c	2005-03-01 23:39:10 -08:00
@@ -396,8 +396,7 @@
 		    const Elf_Shdr *sechdrs,
 		    struct module *me)
 {
-	if (me->arch.syminfo)
-		vfree(me->arch.syminfo);
+	vfree(me->arch.syminfo);
 	return 0;
 }
 
diff -Nru a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
--- a/arch/s390/kernel/process.c	2005-03-01 23:39:08 -08:00
+++ b/arch/s390/kernel/process.c	2005-03-01 23:39:08 -08:00
@@ -159,11 +159,10 @@
 #endif /* CONFIG_ARCH_S390X */
 }
 
-int cpu_idle(void)
+void cpu_idle(void)
 {
 	for (;;)
 		default_idle();
-	return 0;
 }
 
 void show_regs(struct pt_regs *regs)
@@ -216,8 +215,7 @@
 
 void flush_thread(void)
 {
-
-        current->used_math = 0;
+	clear_used_math();
 	clear_tsk_thread_flag(current, TIF_USEDFPU);
 }
 
diff -Nru a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c
--- a/arch/s390/kernel/ptrace.c	2005-03-01 23:39:10 -08:00
+++ b/arch/s390/kernel/ptrace.c	2005-03-01 23:39:10 -08:00
@@ -559,13 +559,13 @@
 	case PTRACE_GETSIGINFO:
 		if (child->last_siginfo == NULL)
 			return -EINVAL;
-		return copy_siginfo_to_user32((siginfo_t32 __user *) data,
+		return copy_siginfo_to_user32((compat_siginfo_t __user *) data,
 					      child->last_siginfo);
 	case PTRACE_SETSIGINFO:
 		if (child->last_siginfo == NULL)
 			return -EINVAL;
 		return copy_siginfo_from_user32(child->last_siginfo,
-						(siginfo_t32 __user *) data);
+						(compat_siginfo_t __user *) data);
 	}
 	return ptrace_request(child, request, addr, data);
 }
diff -Nru a/arch/s390/kernel/s390_ksyms.c b/arch/s390/kernel/s390_ksyms.c
--- a/arch/s390/kernel/s390_ksyms.c	2005-03-01 23:39:07 -08:00
+++ b/arch/s390/kernel/s390_ksyms.c	2005-03-01 23:39:07 -08:00
@@ -63,4 +63,3 @@
 EXPORT_SYMBOL(console_devno);
 EXPORT_SYMBOL(console_irq);
 EXPORT_SYMBOL(sys_wait4);
-EXPORT_SYMBOL(cpcmd);
diff -Nru a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
--- a/arch/s390/kernel/setup.c	2005-03-01 23:38:52 -08:00
+++ b/arch/s390/kernel/setup.c	2005-03-01 23:38:52 -08:00
@@ -76,8 +76,15 @@
 
 static char command_line[COMMAND_LINE_SIZE] = { 0, };
 
-static struct resource code_resource = { "Kernel code", 0x100000, 0 };
-static struct resource data_resource = { "Kernel data", 0, 0 };
+static struct resource code_resource = {
+	.name  = "Kernel code",
+	.flags = IORESOURCE_BUSY | IORESOURCE_MEM,
+};
+
+static struct resource data_resource = {
+	.name = "Kernel data",
+	.flags = IORESOURCE_BUSY | IORESOURCE_MEM,
+};
 
 /*
  * cpu_init() initializes state that is per-CPU.
@@ -96,11 +103,10 @@
          * Force FPU initialization:
          */
         clear_thread_flag(TIF_USEDFPU);
-        current->used_math = 0;
+        clear_used_math();
 
-        /* Setup active_mm for idle_task  */
-        atomic_inc(&init_mm.mm_count);
-        current->active_mm = &init_mm;
+	atomic_inc(&init_mm.mm_count);
+	current->active_mm = &init_mm;
         if (current->mm)
                 BUG();
         enter_lazy_tlb(&init_mm, current);
@@ -185,11 +191,11 @@
 	char *ptr;
 
         if (MACHINE_IS_VM) {
-		cpcmd("QUERY CONSOLE", query_buffer, 1024);
+		__cpcmd("QUERY CONSOLE", query_buffer, 1024);
 		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);
 		ptr = strstr(query_buffer, "CONMODE");
 		/*
 		 * Set the conmode to 3215 so that the device recognition 
@@ -198,7 +204,7 @@
 		 * 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);
 		if (ptr == NULL) {
 #if defined(CONFIG_SCLP_CONSOLE)
 			SET_CONSOLE_SCLP;
@@ -315,7 +321,6 @@
         unsigned long bootmap_size;
         unsigned long memory_start, memory_end;
         char c = ' ', cn, *to = command_line, *from = COMMAND_LINE;
-	struct resource *res;
 	unsigned long start_pfn, end_pfn;
         static unsigned int smptrap=0;
         unsigned long delay = 0;
@@ -473,6 +478,30 @@
         }
 #endif
 
+	for (i = 0; i < 16 && memory_chunk[i].size > 0; i++) {
+		struct resource *res;
+
+		res = alloc_bootmem_low(sizeof(struct resource));
+		res->flags = IORESOURCE_BUSY | IORESOURCE_MEM;
+
+		switch (memory_chunk[i].type) {
+		case CHUNK_READ_WRITE:
+			res->name = "System RAM";
+			break;
+		case CHUNK_READ_ONLY:
+			res->name = "System ROM";
+			res->flags |= IORESOURCE_READONLY;
+			break;
+		default:
+			res->name = "reserved";
+		}
+		res->start = memory_chunk[i].addr;
+		res->end = memory_chunk[i].addr +  memory_chunk[i].size - 1;
+		request_resource(&iomem_resource, res);
+		request_resource(res, &code_resource);
+		request_resource(res, &data_resource);
+	}
+
         /*
          * Setup lowcore for boot cpu
          */
@@ -524,14 +553,6 @@
 	 * Create kernel page tables and switch to virtual addressing.
 	 */
         paging_init();
-
-	res = alloc_bootmem_low(sizeof(struct resource));
-	res->start = 0;
-	res->end = memory_end;
-	res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
-	request_resource(&iomem_resource, res);
-	request_resource(res, &code_resource);
-	request_resource(res, &data_resource);
 
         /* Setup default console */
 	conmode_default();
diff -Nru a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
--- a/arch/s390/kernel/smp.c	2005-03-01 23:39:18 -08:00
+++ b/arch/s390/kernel/smp.c	2005-03-01 23:39:18 -08:00
@@ -42,7 +42,6 @@
 #include <asm/tlbflush.h>
 
 /* prototypes */
-extern int cpu_idle(void * unused);
 
 extern volatile int __cpu_logical_map[];
 
@@ -77,7 +76,7 @@
  * Structure and data for smp_call_function(). This is designed to minimise
  * static memory requirements. It also looks cleaner.
  */
-static spinlock_t call_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(call_lock);
 
 struct call_data_struct {
 	void (*func) (void *info);
@@ -487,55 +486,45 @@
  * Lets check how many CPUs we have.
  */
 
-#ifdef CONFIG_HOTPLUG_CPU
-
 void
 __init smp_check_cpus(unsigned int max_cpus)
 {
-	int cpu;
+	int cpu, num_cpus;
+	__u16 boot_cpu_addr;
 
 	/*
 	 * cpu 0 is the boot cpu. See smp_prepare_boot_cpu.
 	 */
-	for (cpu = 1; cpu < max_cpus; cpu++)
-		cpu_set(cpu, cpu_possible_map);
-}
 
-#else /* CONFIG_HOTPLUG_CPU */
+	boot_cpu_addr = S390_lowcore.cpu_data.cpu_addr;
+	__cpu_logical_map[0] = boot_cpu_addr;
+	current_thread_info()->cpu = 0;
+	num_cpus = 1;
+	for (cpu = 0; cpu <= 65535 && num_cpus < max_cpus; cpu++) {
+		if ((__u16) cpu == boot_cpu_addr)
+			continue;
+		__cpu_logical_map[num_cpus] = (__u16) cpu;
+		if (signal_processor(num_cpus, sigp_sense) ==
+		    sigp_not_operational)
+			continue;
+		cpu_set(num_cpus, cpu_present_map);
+		num_cpus++;
+	}
 
-void
-__init smp_check_cpus(unsigned int max_cpus)
-{
-        int curr_cpu, num_cpus;
-	__u16 boot_cpu_addr;
+	for (cpu = 1; cpu < max_cpus; cpu++)
+		cpu_set(cpu, cpu_possible_map);
 
-	boot_cpu_addr = S390_lowcore.cpu_data.cpu_addr;
-        current_thread_info()->cpu = 0;
-        num_cpus = 1;
-        for (curr_cpu = 0;
-             curr_cpu <= 65535 && num_cpus < max_cpus; curr_cpu++) {
-                if ((__u16) curr_cpu == boot_cpu_addr)
-                        continue;
-                __cpu_logical_map[num_cpus] = (__u16) curr_cpu;
-                if (signal_processor(num_cpus, sigp_sense) ==
-                    sigp_not_operational)
-                        continue;
-		cpu_set(num_cpus, cpu_possible_map);
-                num_cpus++;
-        }
-        printk("Detected %d CPU's\n",(int) num_cpus);
-        printk("Boot cpu address %2X\n", boot_cpu_addr);
+	printk("Detected %d CPU's\n",(int) num_cpus);
+	printk("Boot cpu address %2X\n", boot_cpu_addr);
 }
 
-#endif /* CONFIG_HOTPLUG_CPU */
-
 /*
  *      Activate a secondary processor.
  */
 extern void init_cpu_timer(void);
 extern void init_cpu_vtimer(void);
 extern int pfault_init(void);
-extern int pfault_token(void);
+extern void pfault_fini(void);
 
 int __devinit start_secondary(void *cpuvoid)
 {
@@ -557,7 +546,8 @@
         /* Print info about this processor */
         print_cpu_info(&S390_lowcore.cpu_data);
         /* cpu_idle will call schedule for us */
-        return cpu_idle(NULL);
+        cpu_idle();
+        return 0;
 }
 
 static void __init smp_create_idle(unsigned int cpu)
@@ -576,7 +566,7 @@
 
 /* Reserving and releasing of CPUs */
 
-static spinlock_t smp_reserve_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(smp_reserve_lock);
 static int smp_cpu_reserved[NR_CPUS];
 
 int
@@ -679,7 +669,8 @@
 	eieio();
 	signal_processor(cpu,sigp_restart);
 
-	while (!cpu_online(cpu));
+	while (!cpu_online(cpu))
+		cpu_relax();
 	return 0;
 }
 
@@ -695,6 +686,11 @@
 		return -EBUSY;
 	}
 
+#ifdef CONFIG_PFAULT
+	/* Disable pfault pseudo page faults on this cpu. */
+	pfault_fini();
+#endif
+
 	/* disable all external interrupts */
 
 	cr_parms.start_ctl = 0;
@@ -729,13 +725,15 @@
 __cpu_die(unsigned int cpu)
 {
 	/* Wait until target cpu is down */
-	while (!cpu_stopped(cpu));
+	while (!cpu_stopped(cpu))
+		cpu_relax();
 	printk("Processor %d spun down\n", cpu);
 }
 
 void
 cpu_die(void)
 {
+	idle_task_exit();
 	signal_processor(smp_processor_id(), sigp_stop);
 	BUG();
 	for(;;);
@@ -799,6 +797,7 @@
 
 void smp_cpus_done(unsigned int max_cpus)
 {
+	cpu_present_map = cpu_possible_map;
 }
 
 /*
diff -Nru a/arch/s390/kernel/sys_s390.c b/arch/s390/kernel/sys_s390.c
--- a/arch/s390/kernel/sys_s390.c	2005-03-01 23:38:55 -08:00
+++ b/arch/s390/kernel/sys_s390.c	2005-03-01 23:38:55 -08:00
@@ -145,7 +145,7 @@
  *
  * This is really horribly ugly.
  */
-asmlinkage long sys_ipc(uint call, int first, int second,
+asmlinkage long sys_ipc(uint call, int first, unsigned long second,
 				  unsigned long third, void __user *ptr)
 {
         struct ipc_kludge tmp;
@@ -153,24 +153,25 @@
 
         switch (call) {
         case SEMOP:
-		return sys_semtimedop (first, (struct sembuf __user *) ptr, second,
-				       NULL);
+		return sys_semtimedop(first, (struct sembuf __user *)ptr,
+				       (unsigned)second, NULL);
 	case SEMTIMEDOP:
-		return sys_semtimedop (first, (struct sembuf __user *) ptr, second,
+		return sys_semtimedop(first, (struct sembuf __user *)ptr,
+				       (unsigned)second,
 				       (const struct timespec __user *) third);
         case SEMGET:
-                return sys_semget (first, second, third);
+                return sys_semget(first, (int)second, third);
         case SEMCTL: {
                 union semun fourth;
                 if (!ptr)
                         return -EINVAL;
                 if (get_user(fourth.__pad, (void __user * __user *) ptr))
                         return -EFAULT;
-                return sys_semctl (first, second, third, fourth);
+                return sys_semctl(first, (int)second, third, fourth);
         }
         case MSGSND:
 		return sys_msgsnd (first, (struct msgbuf __user *) ptr,
-                                   second, third);
+                                   (size_t)second, third);
 		break;
         case MSGRCV:
                 if (!ptr)
@@ -179,15 +180,17 @@
                                     sizeof (struct ipc_kludge)))
                         return -EFAULT;
                 return sys_msgrcv (first, tmp.msgp,
-                                   second, tmp.msgtyp, third);
+                                   (size_t)second, tmp.msgtyp, third);
         case MSGGET:
-                return sys_msgget ((key_t) first, second);
+                return sys_msgget((key_t)first, (int)second);
         case MSGCTL:
-                return sys_msgctl (first, second, (struct msqid_ds __user *) ptr);
+                return sys_msgctl(first, (int)second,
+				   (struct msqid_ds __user *)ptr);
 
 	case SHMAT: {
 		ulong raddr;
-		ret = do_shmat (first, (char __user *) ptr, second, &raddr);
+		ret = do_shmat(first, (char __user *)ptr,
+				(int)second, &raddr);
 		if (ret)
 			return ret;
 		return put_user (raddr, (ulong __user *) third);
@@ -196,9 +199,9 @@
 	case SHMDT:
 		return sys_shmdt ((char __user *)ptr);
 	case SHMGET:
-		return sys_shmget (first, second, third);
+		return sys_shmget(first, (size_t)second, third);
 	case SHMCTL:
-		return sys_shmctl (first, second,
+		return sys_shmctl(first, (int)second,
                                    (struct shmid_ds __user *) ptr);
 	default:
 		return -ENOSYS;
diff -Nru a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S
--- a/arch/s390/kernel/syscalls.S	2005-03-01 23:38:52 -08:00
+++ b/arch/s390/kernel/syscalls.S	2005-03-01 23:38:52 -08:00
@@ -185,7 +185,7 @@
 SYSCALL(sys_rt_sigaction,sys_rt_sigaction,sys32_rt_sigaction_wrapper)
 SYSCALL(sys_rt_sigprocmask,sys_rt_sigprocmask,sys32_rt_sigprocmask_wrapper)	/* 175 */
 SYSCALL(sys_rt_sigpending,sys_rt_sigpending,sys32_rt_sigpending_wrapper)
-SYSCALL(sys_rt_sigtimedwait,sys_rt_sigtimedwait,sys32_rt_sigtimedwait_wrapper)
+SYSCALL(sys_rt_sigtimedwait,sys_rt_sigtimedwait,compat_sys_rt_sigtimedwait_wrapper)
 SYSCALL(sys_rt_sigqueueinfo,sys_rt_sigqueueinfo,sys32_rt_sigqueueinfo_wrapper)
 SYSCALL(sys_rt_sigsuspend_glue,sys_rt_sigsuspend_glue,sys32_rt_sigsuspend_glue)
 SYSCALL(sys_pread64,sys_pread64,sys32_pread64_wrapper)		/* 180 */
diff -Nru a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
--- a/arch/s390/kernel/time.c	2005-03-01 23:38:44 -08:00
+++ b/arch/s390/kernel/time.c	2005-03-01 23:38:44 -08:00
@@ -150,28 +150,6 @@
 
 EXPORT_SYMBOL(do_settimeofday);
 
-#ifndef CONFIG_ARCH_S390X
-
-static inline __u32
-__calculate_ticks(__u64 elapsed)
-{
-	register_pair rp;
-
-	rp.pair = elapsed >> 1;
-	asm ("dr %0,%1" : "+d" (rp) : "d" (CLK_TICKS_PER_JIFFY >> 1));
-	return rp.subreg.odd;
-}
-
-#else /* CONFIG_ARCH_S390X */
-
-static inline __u32
-__calculate_ticks(__u64 elapsed)
-{
-	return elapsed / CLK_TICKS_PER_JIFFY;
-}
-
-#endif /* CONFIG_ARCH_S390X */
-
 
 #ifdef CONFIG_PROFILING
 #define s390_do_profile(regs)	profile_tick(CPU_PROFILING, regs)
@@ -187,14 +165,14 @@
 void account_ticks(struct pt_regs *regs)
 {
 	__u64 tmp;
-	__u32 ticks;
+	__u32 ticks, xticks;
 
 	/* Calculate how many ticks have passed. */
 	if (S390_lowcore.int_clock < S390_lowcore.jiffy_timer)
 		return;
 	tmp = S390_lowcore.int_clock - S390_lowcore.jiffy_timer;
 	if (tmp >= 2*CLK_TICKS_PER_JIFFY) {  /* more than two ticks ? */
-		ticks = __calculate_ticks(tmp) + 1;
+		ticks = __div(tmp, CLK_TICKS_PER_JIFFY) + 1;
 		S390_lowcore.jiffy_timer +=
 			CLK_TICKS_PER_JIFFY * (__u64) ticks;
 	} else if (tmp >= CLK_TICKS_PER_JIFFY) {
@@ -216,11 +194,9 @@
 	 */
 	write_seqlock(&xtime_lock);
 	if (S390_lowcore.jiffy_timer > xtime_cc) {
-		__u32 xticks;
-
 		tmp = S390_lowcore.jiffy_timer - xtime_cc;
 		if (tmp >= 2*CLK_TICKS_PER_JIFFY) {
-			xticks = __calculate_ticks(tmp);
+			xticks = __div(tmp, CLK_TICKS_PER_JIFFY);
 			xtime_cc += (__u64) xticks * CLK_TICKS_PER_JIFFY;
 		} else {
 			xticks = 1;
@@ -230,14 +206,18 @@
 			do_timer(regs);
 	}
 	write_sequnlock(&xtime_lock);
-	while (ticks--)
-		update_process_times(user_mode(regs));
 #else
-	while (ticks--) {
+	for (xticks = ticks; xticks > 0; xticks--)
 		do_timer(regs);
+#endif
+
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+	account_user_vtime(current);
+#else
+	while (ticks--)
 		update_process_times(user_mode(regs));
-	}
 #endif
+
 	s390_do_profile(regs);
 }
 
diff -Nru a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c
--- a/arch/s390/kernel/traps.c	2005-03-01 23:38:55 -08:00
+++ b/arch/s390/kernel/traps.c	2005-03-01 23:38:55 -08:00
@@ -273,7 +273,7 @@
 	return buffer;
 }
 
-spinlock_t die_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(die_lock);
 
 void die(const char * str, struct pt_regs * regs, long err)
 {
diff -Nru a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c
--- a/arch/s390/kernel/vtime.c	2005-03-01 23:39:16 -08:00
+++ b/arch/s390/kernel/vtime.c	2005-03-01 23:39:16 -08:00
@@ -17,6 +17,8 @@
 #include <linux/types.h>
 #include <linux/timex.h>
 #include <linux/notifier.h>
+#include <linux/kernel_stat.h>
+#include <linux/rcupdate.h>
 
 #include <asm/s390_ext.h>
 #include <asm/timer.h>
@@ -25,7 +27,95 @@
 static ext_int_info_t ext_int_info_timer;
 DEFINE_PER_CPU(struct vtimer_queue, virt_cpu_timer);
 
-void start_cpu_timer(void)
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+/*
+ * Update process times based on virtual cpu times stored by entry.S
+ * to the lowcore fields user_timer, system_timer & steal_clock.
+ */
+void account_user_vtime(struct task_struct *tsk)
+{
+	cputime_t cputime;
+	__u64 timer, clock;
+	int rcu_user_flag;
+
+	timer = S390_lowcore.last_update_timer;
+	clock = S390_lowcore.last_update_clock;
+	asm volatile ("  STPT %0\n"    /* Store current cpu timer value */
+		      "  STCK %1"      /* Store current tod clock value */
+		      : "=m" (S390_lowcore.last_update_timer),
+		        "=m" (S390_lowcore.last_update_clock) );
+	S390_lowcore.system_timer += timer - S390_lowcore.last_update_timer;
+	S390_lowcore.steal_clock += S390_lowcore.last_update_clock - clock;
+
+	cputime = S390_lowcore.user_timer >> 12;
+	rcu_user_flag = cputime != 0;
+	S390_lowcore.user_timer -= cputime << 12;
+	S390_lowcore.steal_clock -= cputime << 12;
+	account_user_time(tsk, cputime);
+
+	cputime =  S390_lowcore.system_timer >> 12;
+	S390_lowcore.system_timer -= cputime << 12;
+	S390_lowcore.steal_clock -= cputime << 12;
+	account_system_time(tsk, HARDIRQ_OFFSET, cputime);
+
+	cputime = S390_lowcore.steal_clock;
+	if ((__s64) cputime > 0) {
+		cputime >>= 12;
+		S390_lowcore.steal_clock -= cputime << 12;
+		account_steal_time(tsk, cputime);
+	}
+
+	run_local_timers();
+	if (rcu_pending(smp_processor_id()))
+		rcu_check_callbacks(smp_processor_id(), rcu_user_flag);
+	scheduler_tick();
+}
+
+/*
+ * Update process times based on virtual cpu times stored by entry.S
+ * to the lowcore fields user_timer, system_timer & steal_clock.
+ */
+void account_system_vtime(struct task_struct *tsk)
+{
+	cputime_t cputime;
+	__u64 timer;
+
+	timer = S390_lowcore.last_update_timer;
+	asm volatile ("  STPT %0"    /* Store current cpu timer value */
+		      : "=m" (S390_lowcore.last_update_timer) );
+	S390_lowcore.system_timer += timer - S390_lowcore.last_update_timer;
+
+	cputime =  S390_lowcore.system_timer >> 12;
+	S390_lowcore.system_timer -= cputime << 12;
+	S390_lowcore.steal_clock -= cputime << 12;
+	account_system_time(tsk, 0, cputime);
+}
+
+static inline void set_vtimer(__u64 expires)
+{
+	__u64 timer;
+
+	asm volatile ("  STPT %0\n"  /* Store current cpu timer value */
+		      "  SPT %1"     /* Set new value immediatly afterwards */
+		      : "=m" (timer) : "m" (expires) );
+	S390_lowcore.system_timer += S390_lowcore.last_update_timer - timer;
+	S390_lowcore.last_update_timer = expires;
+
+	/* store expire time for this CPU timer */
+	per_cpu(virt_cpu_timer, smp_processor_id()).to_expire = expires;
+}
+#else
+static inline void set_vtimer(__u64 expires)
+{
+	S390_lowcore.last_update_timer = expires;
+	asm volatile ("SPT %0" : : "m" (S390_lowcore.last_update_timer));
+
+	/* store expire time for this CPU timer */
+	per_cpu(virt_cpu_timer, smp_processor_id()).to_expire = expires;
+}
+#endif
+
+static void start_cpu_timer(void)
 {
 	struct vtimer_queue *vt_list;
 
@@ -33,7 +123,7 @@
 	set_vtimer(vt_list->idle);
 }
 
-void stop_cpu_timer(void)
+static void stop_cpu_timer(void)
 {
 	__u64 done;
 	struct vtimer_queue *vt_list;
@@ -71,19 +161,11 @@
 	set_vtimer(VTIMER_MAX_SLICE);
 }
 
-void set_vtimer(__u64 expires)
-{
-	asm volatile ("SPT %0" : : "m" (expires));
-
-	/* store expire time for this CPU timer */
-	per_cpu(virt_cpu_timer, smp_processor_id()).to_expire = expires;
-}
-
 /*
  * Sorted add to a list. List is linear searched until first bigger
  * element is found.
  */
-void list_add_sorted(struct vtimer_list *timer, struct list_head *head)
+static void list_add_sorted(struct vtimer_list *timer, struct list_head *head)
 {
 	struct vtimer_list *event;
 
@@ -429,11 +511,12 @@
 {
 	struct vtimer_queue *vt_list;
 	unsigned long cr0;
-	__u64 timer;
 
 	/* kick the virtual timer */
-	timer = VTIMER_MAX_SLICE;
-	asm volatile ("SPT %0" : : "m" (timer));
+	S390_lowcore.exit_timer = VTIMER_MAX_SLICE;
+	S390_lowcore.last_update_timer = VTIMER_MAX_SLICE;
+	asm volatile ("SPT %0" : : "m" (S390_lowcore.last_update_timer));
+	asm volatile ("STCK %0" : "=m" (S390_lowcore.last_update_clock));
 	__ctl_store(cr0, 0, 0);
 	cr0 |= 0x400;
 	__ctl_load(cr0, 0, 0);
diff -Nru a/arch/s390/lib/string.c b/arch/s390/lib/string.c
--- a/arch/s390/lib/string.c	2005-03-01 23:38:55 -08:00
+++ b/arch/s390/lib/string.c	2005-03-01 23:38:55 -08:00
@@ -357,21 +357,6 @@
 EXPORT_SYMBOL(memcpy);
 
 /**
- * bcopy - Copy one area of memory to another
- * @src: Where to copy from
- * @dest: Where to copy to
- * @n: The size of the area.
- *
- * Note that this is the same as memcpy(), with the arguments reversed.
- * memcpy() is the standard, bcopy() is a legacy BSD function.
- */
-void bcopy(const void *srcp, void *destp, size_t n)
-{
-	__builtin_memcpy(destp, srcp, n);
-}
-EXPORT_SYMBOL(bcopy);
-
-/**
  * memset - Fill a region of memory with the given value
  * @s: Pointer to the start of the area.
  * @c: The byte to fill the area with
diff -Nru a/arch/s390/mm/cmm.c b/arch/s390/mm/cmm.c
--- a/arch/s390/mm/cmm.c	2005-03-01 23:39:07 -08:00
+++ b/arch/s390/mm/cmm.c	2005-03-01 23:39:07 -08:00
@@ -19,7 +19,6 @@
 
 #include <asm/pgalloc.h>
 #include <asm/uaccess.h>
-#include <asm/smp.h>
 
 #include "../../../drivers/s390/net/smsgiucv.h"
 
@@ -124,7 +123,6 @@
 	int rc;
 
 	daemonize("cmmthread");
-	set_cpus_allowed(current, cpumask_of_cpu(0));
 	while (1) {
 		rc = wait_event_interruptible(cmm_thread_wait,
 			(cmm_pages != cmm_pages_target ||
@@ -408,14 +406,6 @@
 static int
 cmm_init (void)
 {
-	int rc;
-
-	/* Prevent logical cpu 0 from being set offline. */
-	rc = smp_get_cpu(cpumask_of_cpu(0));
-	if (rc) {
-		printk(KERN_ERR "CMM: unable to reserve cpu 0\n");
-		return rc;
-	}
 #ifdef CONFIG_CMM_PROC
 	cmm_sysctl_header = register_sysctl_table(cmm_dir_table, 1);
 #endif
@@ -439,8 +429,6 @@
 #ifdef CONFIG_CMM_IUCV
 	smsg_unregister_callback(SMSG_PREFIX, cmm_smsg_target);
 #endif
-	/* Allow logical cpu 0 to be set offline again. */
-	smp_put_cpu(0);
 }
 
 module_init(cmm_init);
diff -Nru a/arch/s390/mm/extmem.c b/arch/s390/mm/extmem.c
--- a/arch/s390/mm/extmem.c	2005-03-01 23:39:08 -08:00
+++ b/arch/s390/mm/extmem.c	2005-03-01 23:39:08 -08:00
@@ -77,7 +77,7 @@
 	int segcnt;
 };
 
-static spinlock_t dcss_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(dcss_lock);
 static struct list_head dcss_list = LIST_HEAD_INIT(dcss_list);
 static char *segtype_string[] = { "SW", "EW", "SR", "ER", "SN", "EN", "SC",
 					"EW/EN-MIXED" };
@@ -117,7 +117,7 @@
 	struct list_head *l;
 	struct dcss_segment *tmp, *retval = NULL;
 
-	BUG_ON (!spin_is_locked(&dcss_lock));
+	assert_spin_locked(&dcss_lock);
 	dcss_mkname (name, dcss_name);
 	list_for_each (l, &dcss_list) {
 		tmp = list_entry (l, struct dcss_segment, list);
@@ -271,7 +271,7 @@
 	struct list_head *l;
 	struct dcss_segment *tmp;
 
-	BUG_ON (!spin_is_locked(&dcss_lock));
+	assert_spin_locked(&dcss_lock);
 	list_for_each(l, &dcss_list) {
 		tmp = list_entry(l, struct dcss_segment, list);
 		if ((tmp->start_addr >> 20) > (seg->end >> 20))
@@ -545,7 +545,8 @@
 /*
  * save segment content permanently
  */
-void segment_save(char *name)
+void
+segment_save(char *name)
 {
 	struct dcss_segment *seg;
 	int startpfn = 0;
@@ -575,8 +576,8 @@
 			segtype_string[seg->range[i].start & 0xff]);
 	}
 	sprintf(cmd2, "SAVESEG %s", name);
-	cpcmd(cmd1, NULL, 80);
-	cpcmd(cmd2, NULL, 80);
+	cpcmd(cmd1, NULL, 0);
+	cpcmd(cmd2, NULL, 0);
 	spin_unlock(&dcss_lock);
 }
 
diff -Nru a/arch/s390/mm/init.c b/arch/s390/mm/init.c
--- a/arch/s390/mm/init.c	2005-03-01 23:39:08 -08:00
+++ b/arch/s390/mm/init.c	2005-03-01 23:39:08 -08:00
@@ -45,11 +45,24 @@
         if (addr >= 0x7ff00000)
                 return;
 #ifdef __s390x__
-        asm volatile ("sam31\n\t"
-                      "diag %0,%0,0x10\n\t"
-                      "sam64" : : "a" (addr) );
+        asm volatile (
+		"   sam31\n"
+		"   diag %0,%0,0x10\n"
+		"0: sam64\n"
+		".section __ex_table,\"a\"\n"
+		"   .align 8\n"
+		"   .quad 0b, 0b\n"
+		".previous\n"
+		: : "a" (addr));
 #else
-        asm volatile ("diag %0,%0,0x10" : : "a" (addr) );
+        asm volatile (
+		"   diag %0,%0,0x10\n"
+		"0:\n"
+		".section __ex_table,\"a\"\n"
+		"   .align 4\n"
+		"   .long 0b, 0b\n"
+		".previous\n"
+		: : "a" (addr));
 #endif
 }
 
diff -Nru a/arch/s390/mm/mmap.c b/arch/s390/mm/mmap.c
--- a/arch/s390/mm/mmap.c	2005-03-01 23:38:44 -08:00
+++ b/arch/s390/mm/mmap.c	2005-03-01 23:38:44 -08:00
@@ -26,6 +26,7 @@
 
 #include <linux/personality.h>
 #include <linux/mm.h>
+#include <linux/module.h>
 
 /*
  * Top of mmap area (just below the process stack).
@@ -81,3 +82,5 @@
 		mm->unmap_area = arch_unmap_area_topdown;
 	}
 }
+EXPORT_SYMBOL_GPL(arch_pick_mmap_layout);
+
diff -Nru a/arch/s390/oprofile/init.c b/arch/s390/oprofile/init.c
--- a/arch/s390/oprofile/init.c	2005-03-01 23:39:07 -08:00
+++ b/arch/s390/oprofile/init.c	2005-03-01 23:39:07 -08:00
@@ -12,13 +12,9 @@
 #include <linux/init.h>
 #include <linux/errno.h>
 
-//extern int irq_init(struct oprofile_operations** ops);
-extern void timer_init(struct oprofile_operations** ops);
-
-int __init oprofile_arch_init(struct oprofile_operations** ops)
+int __init oprofile_arch_init(struct oprofile_operations* ops)
 {
-	timer_init(ops);
-	return 0;
+	return -ENODEV;
 }
 
 void oprofile_arch_exit(void)
diff -Nru a/arch/sh/Kconfig b/arch/sh/Kconfig
--- a/arch/sh/Kconfig	2005-03-01 23:39:17 -08:00
+++ b/arch/sh/Kconfig	2005-03-01 23:39:17 -08:00
@@ -25,6 +25,10 @@
 config RWSEM_XCHGADD_ALGORITHM
 	bool
 
+config GENERIC_CALIBRATE_DELAY
+	bool
+	default y
+
 source "init/Kconfig"
 
 menu "System type"
@@ -37,25 +41,25 @@
 	bool "SolutionEngine"
 	help
 	  Select SolutionEngine if configuring for a Hitachi SH7709
-	  or SH7750 evalutation board.
+	  or SH7750 evaluation board.
 
 config SH_7751_SOLUTION_ENGINE
 	bool "SolutionEngine7751"
 	help
 	  Select 7751 SolutionEngine if configuring for a Hitachi SH7751
-	  evalutation board.
+	  evaluation board.
 
 config SH_7300_SOLUTION_ENGINE
 	bool "SolutionEngine7300"
 	help
 	  Select 7300 SolutionEngine if configuring for a Hitachi SH7300(SH-Mobile V)
-	  evalutation board.
+	  evaluation board.
 
 config SH_73180_SOLUTION_ENGINE
        bool "SolutionEngine73180"
        help
          Select 73180 SolutionEngine if configuring for a Hitachi SH73180(SH-Mobile 3)
-         evalutation board.
+         evaluation board.
 
 config SH_7751_SYSTEMH
 	bool "SystemH7751R"
diff -Nru a/arch/sh/boards/renesas/hs7751rvoip/io.c b/arch/sh/boards/renesas/hs7751rvoip/io.c
--- a/arch/sh/boards/renesas/hs7751rvoip/io.c	2005-03-01 23:38:54 -08:00
+++ b/arch/sh/boards/renesas/hs7751rvoip/io.c	2005-03-01 23:38:54 -08:00
@@ -166,7 +166,7 @@
 
         if (PXSEG(port))
                 *(volatile unsigned char *)port = value;
-#if defined(CONFIG_HS7751RVOIP_CIDEC)
+#if defined(CONFIG_HS7751RVOIP_CODEC)
 	else if (codec_port(port))
 		*(volatile unsigned cjar *)((unsigned long)area6_io8_base+(port-CODEC_IO_BASE)) = value;
 #endif
@@ -180,7 +180,7 @@
 {
         if (PXSEG(port))
                 *(volatile unsigned char *)port = value;
-#if defined(CONFIG_HS7751RVOIP_CIDEC)
+#if defined(CONFIG_HS7751RVOIP_CODEC)
 	else if (codec_port(port))
 		*(volatile unsigned cjar *)((unsigned long)area6_io8_base+(port-CODEC_IO_BASE)) = value;
 #endif
diff -Nru a/arch/sh/cchips/voyagergx/consistent.c b/arch/sh/cchips/voyagergx/consistent.c
--- a/arch/sh/cchips/voyagergx/consistent.c	2005-03-01 23:39:16 -08:00
+++ b/arch/sh/cchips/voyagergx/consistent.c	2005-03-01 23:39:16 -08:00
@@ -23,7 +23,7 @@
 	unsigned long len;
 };
 
-static spinlock_t voya_list_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(voya_list_lock);
 static LIST_HEAD(voya_alloc_list);
 
 #define OHCI_SRAM_START	0xb0000000
diff -Nru a/arch/sh/drivers/dma/dma-api.c b/arch/sh/drivers/dma/dma-api.c
--- a/arch/sh/drivers/dma/dma-api.c	2005-03-01 23:39:09 -08:00
+++ b/arch/sh/drivers/dma/dma-api.c	2005-03-01 23:39:09 -08:00
@@ -17,7 +17,7 @@
 #include <linux/list.h>
 #include <asm/dma.h>
 
-spinlock_t dma_spin_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(dma_spin_lock);
 static LIST_HEAD(registered_dmac_list);
 
 /*
diff -Nru a/arch/sh/drivers/pci/Kconfig b/arch/sh/drivers/pci/Kconfig
--- a/arch/sh/drivers/pci/Kconfig	2005-03-01 23:38:51 -08:00
+++ b/arch/sh/drivers/pci/Kconfig	2005-03-01 23:38:51 -08:00
@@ -3,8 +3,7 @@
 	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.
+	  your box. If you have PCI, say Y, otherwise N.
 
 	  The PCI-HOWTO, available from
 	  <http://www.tldp.org/docs.html#howto>, contains valuable
diff -Nru a/arch/sh/kernel/cpu/init.c b/arch/sh/kernel/cpu/init.c
--- a/arch/sh/kernel/cpu/init.c	2005-03-01 23:39:18 -08:00
+++ b/arch/sh/kernel/cpu/init.c	2005-03-01 23:39:18 -08:00
@@ -194,7 +194,7 @@
 	/* FPU initialization */
 	if ((cpu_data->flags & CPU_HAS_FPU)) {
 		clear_thread_flag(TIF_USEDFPU);
-		current->used_math = 0;
+		clear_used_math();
 	}
 
 #ifdef CONFIG_SH_DSP
diff -Nru a/arch/sh/kernel/cpu/sh4/fpu.c b/arch/sh/kernel/cpu/sh4/fpu.c
--- a/arch/sh/kernel/cpu/sh4/fpu.c	2005-03-01 23:38:54 -08:00
+++ b/arch/sh/kernel/cpu/sh4/fpu.c	2005-03-01 23:38:54 -08:00
@@ -323,13 +323,13 @@
 		return;
 	}
 
-	if (tsk->used_math) {
+	if (used_math()) {
 		/* Using the FPU again.  */
 		restore_fpu(tsk);
 	} else	{
 		/* First time FPU user.  */
 		fpu_init();
-		tsk->used_math = 1;
+		set_used_math();
 	}
 	set_tsk_thread_flag(tsk, TIF_USEDFPU);
 }
diff -Nru a/arch/sh/kernel/cpu/sh4/sq.c b/arch/sh/kernel/cpu/sh4/sq.c
--- a/arch/sh/kernel/cpu/sh4/sq.c	2005-03-01 23:38:56 -08:00
+++ b/arch/sh/kernel/cpu/sh4/sq.c	2005-03-01 23:38:56 -08:00
@@ -32,7 +32,7 @@
 #include <asm/cpu/sq.h>
 
 static LIST_HEAD(sq_mapping_list);
-static spinlock_t sq_mapping_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(sq_mapping_lock);
 
 /**
  * sq_flush - Flush (prefetch) the store queue cache
diff -Nru a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c
--- a/arch/sh/kernel/process.c	2005-03-01 23:39:08 -08:00
+++ b/arch/sh/kernel/process.c	2005-03-01 23:39:08 -08:00
@@ -68,7 +68,7 @@
 	}
 }
 
-void cpu_idle(void *unused)
+void cpu_idle(void)
 {
 	default_idle();
 }
@@ -208,7 +208,7 @@
 
 	/* Forget lazy FPU state */
 	clear_fpu(tsk, regs);
-	tsk->used_math = 0;
+	clear_used_math();
 #endif
 }
 
@@ -225,7 +225,7 @@
 #if defined(CONFIG_SH_FPU)
 	struct task_struct *tsk = current;
 
-	fpvalid = tsk->used_math;
+	fpvalid = !!tsk_used_math(tsk);
 	if (fpvalid) {
 		unlazy_fpu(tsk, regs);
 		memcpy(fpu, &tsk->thread.fpu.hard, sizeof(*fpu));
@@ -260,7 +260,7 @@
 	int fpvalid = 0;
 
 #if defined(CONFIG_SH_FPU)
-	fpvalid = tsk->used_math;
+	fpvalid = !!tsk_used_math(tsk);
 	if (fpvalid) {
 		struct pt_regs *regs = (struct pt_regs *)
 					((unsigned long)tsk->thread_info
@@ -286,7 +286,7 @@
 
 	unlazy_fpu(tsk, regs);
 	p->thread.fpu = tsk->thread.fpu;
-	p->used_math = tsk->used_math;
+	copy_to_stopped_child_used_math(p);
 #endif
 
 	childregs = ((struct pt_regs *)
diff -Nru a/arch/sh/kernel/ptrace.c b/arch/sh/kernel/ptrace.c
--- a/arch/sh/kernel/ptrace.c	2005-03-01 23:38:52 -08:00
+++ b/arch/sh/kernel/ptrace.c	2005-03-01 23:38:52 -08:00
@@ -150,7 +150,7 @@
 			tmp = get_stack_long(child, addr);
 		else if (addr >= (long) &dummy->fpu &&
 			 addr < (long) &dummy->u_fpvalid) {
-			if (!child->used_math) {
+			if (!tsk_used_math(child)) {
 				if (addr == (long)&dummy->fpu.fpscr)
 					tmp = FPSCR_INIT;
 				else
@@ -159,7 +159,7 @@
 				tmp = ((long *)&child->thread.fpu)
 					[(addr - (long)&dummy->fpu) >> 2];
 		} else if (addr == (long) &dummy->u_fpvalid)
-			tmp = child->used_math;
+			tmp = !!tsk_used_math(child);
 		else
 			tmp = 0;
 		ret = put_user(tmp, (unsigned long *)data);
@@ -185,12 +185,12 @@
 			ret = put_stack_long(child, addr, data);
 		else if (addr >= (long) &dummy->fpu &&
 			 addr < (long) &dummy->u_fpvalid) {
-			child->used_math = 1;
+			set_stopped_child_used_math(child);
 			((long *)&child->thread.fpu)
 				[(addr - (long)&dummy->fpu) >> 2] = data;
 			ret = 0;
 		} else if (addr == (long) &dummy->u_fpvalid) {
-			child->used_math = data?1:0;
+			conditional_stopped_child_used_math(data, child);
 			ret = 0;
 		}
 		break;
diff -Nru a/arch/sh/kernel/sh_ksyms.c b/arch/sh/kernel/sh_ksyms.c
--- a/arch/sh/kernel/sh_ksyms.c	2005-03-01 23:38:53 -08:00
+++ b/arch/sh/kernel/sh_ksyms.c	2005-03-01 23:38:53 -08:00
@@ -89,7 +89,7 @@
 
 EXPORT_SYMBOL(__div64_32);
 
-#define DECLARE_EXPORT(name) extern void name(void);EXPORT_SYMBOL_NOVERS(name)
+#define DECLARE_EXPORT(name) extern void name(void);EXPORT_SYMBOL(name)
 
 /* These symbols are generated by the compiler itself */
 DECLARE_EXPORT(__udivsi3);
@@ -100,7 +100,7 @@
 DECLARE_EXPORT(__lshrdi3);
 DECLARE_EXPORT(__movstr);
 
-EXPORT_SYMBOL_NOVERS(strcpy);
+EXPORT_SYMBOL(strcpy);
 
 #ifdef CONFIG_CPU_SH4
 DECLARE_EXPORT(__movstr_i4_even);
diff -Nru a/arch/sh/kernel/signal.c b/arch/sh/kernel/signal.c
--- a/arch/sh/kernel/signal.c	2005-03-01 23:39:18 -08:00
+++ b/arch/sh/kernel/signal.c	2005-03-01 23:39:18 -08:00
@@ -24,7 +24,6 @@
 #include <linux/tty.h>
 #include <linux/personality.h>
 #include <linux/binfmts.h>
-#include <linux/suspend.h>
 
 #include <asm/ucontext.h>
 #include <asm/uaccess.h>
@@ -163,7 +162,7 @@
 	if (!(cpu_data->flags & CPU_HAS_FPU))
 		return 0;
 
-	tsk->used_math = 1;
+	set_used_math();
 	return __copy_from_user(&tsk->thread.fpu.hard, &sc->sc_fpregs[0],
 				sizeof(long)*(16*2+2));
 }
@@ -176,7 +175,7 @@
 	if (!(cpu_data->flags & CPU_HAS_FPU))
 		return 0;
 
-	if (!tsk->used_math) {
+	if (!used_math()) {
 		__put_user(0, &sc->sc_ownedfp);
 		return 0;
 	}
@@ -186,7 +185,7 @@
 	/* This will cause a "finit" to be triggered by the next
 	   attempted FPU operation by the 'current' process.
 	   */
-	tsk->used_math = 0;
+	clear_used_math();
 
 	unlazy_fpu(tsk, regs);
 	return __copy_to_user(&sc->sc_fpregs[0], &tsk->thread.fpu.hard,
@@ -220,7 +219,7 @@
 
 		regs->sr |= SR_FD; /* Release FPU */
 		clear_fpu(tsk, regs);
-		tsk->used_math = 0;
+		clear_used_math();
 		__get_user (owned_fp, &sc->sc_ownedfp);
 		if (owned_fp)
 			err |= restore_sigcontext_fpu(sc);
@@ -579,10 +578,8 @@
 	if (!user_mode(regs))
 		return 1;
 
-	if (current->flags & PF_FREEZE) {
-		refrigerator(0);
+	if (try_to_freeze(0))
 		goto no_signal;
-	}
 
 	if (!oldset)
 		oldset = &current->blocked;
diff -Nru a/arch/sh/kernel/smp.c b/arch/sh/kernel/smp.c
--- a/arch/sh/kernel/smp.c	2005-03-01 23:38:57 -08:00
+++ b/arch/sh/kernel/smp.c	2005-03-01 23:38:57 -08:00
@@ -37,7 +37,6 @@
 int smp_threads_ready = 0;
 struct sh_cpuinfo cpu_data[NR_CPUS];
 
-extern int cpu_idle(void *unused);
 extern void per_cpu_trap_init(void);
 
 cpumask_t cpu_possible_map;
@@ -124,7 +123,8 @@
 	
 	atomic_inc(&cpus_booted);
 
-	return cpu_idle(0);
+	cpu_idle();
+	return 0;
 }
 
 void __init smp_cpus_done(unsigned int max_cpus)
diff -Nru a/arch/sh/kernel/time.c b/arch/sh/kernel/time.c
--- a/arch/sh/kernel/time.c	2005-03-01 23:38:44 -08:00
+++ b/arch/sh/kernel/time.c	2005-03-01 23:38:44 -08:00
@@ -83,7 +83,7 @@
 
 extern unsigned long wall_jiffies;
 #define TICK_SIZE (tick_nsec / 1000)
-spinlock_t tmu0_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(tmu0_lock);
 
 u64 jiffies_64 = INITIAL_JIFFIES;
 
diff -Nru a/arch/sh/lib/delay.c b/arch/sh/lib/delay.c
--- a/arch/sh/lib/delay.c	2005-03-01 23:38:57 -08:00
+++ b/arch/sh/lib/delay.c	2005-03-01 23:38:57 -08:00
@@ -24,7 +24,7 @@
 	__asm__("dmulu.l	%0, %2\n\t"
 		"sts	mach, %0"
 		: "=r" (xloops)
-		: "0" (xloops), "r" (current_cpu_data.loops_per_jiffy)
+		: "0" (xloops), "r" (cpu_data[_smp_processor_id()].loops_per_jiffy)
 		: "macl", "mach");
 	__delay(xloops * HZ);
 }
diff -Nru a/arch/sh/oprofile/op_model_null.c b/arch/sh/oprofile/op_model_null.c
--- a/arch/sh/oprofile/op_model_null.c	2005-03-01 23:38:54 -08:00
+++ b/arch/sh/oprofile/op_model_null.c	2005-03-01 23:38:54 -08:00
@@ -12,7 +12,7 @@
 #include <linux/init.h>
 #include <linux/errno.h>
 
-int __init oprofile_arch_init(struct oprofile_operations **ops)
+int __init oprofile_arch_init(struct oprofile_operations *ops)
 {
 	return -ENODEV;
 }
diff -Nru a/arch/sh/oprofile/op_model_sh7750.c b/arch/sh/oprofile/op_model_sh7750.c
--- a/arch/sh/oprofile/op_model_sh7750.c	2005-03-01 23:39:18 -08:00
+++ b/arch/sh/oprofile/op_model_sh7750.c	2005-03-01 23:39:18 -08:00
@@ -112,14 +112,9 @@
  */
 
 static int sh7750_timer_notify(struct notifier_block *self,
-			       unsigned long val, void *data)
+			       unsigned long val, void *regs)
 {
-	struct pt_regs *regs = data;
-	unsigned long pc;
-
-	pc = instruction_pointer(regs);
-	oprofile_add_sample(pc, !user_mode(regs), 0, smp_processor_id());
-
+	oprofile_add_sample((struct pt_regs *)regs, 0);
 	return 0;
 }
 
diff -Nru a/arch/sh64/Kconfig b/arch/sh64/Kconfig
--- a/arch/sh64/Kconfig	2005-03-01 23:39:09 -08:00
+++ b/arch/sh64/Kconfig	2005-03-01 23:39:09 -08:00
@@ -25,6 +25,10 @@
 	bool
 	default y
 
+config GENERIC_CALIBRATE_DELAY
+	bool
+	default y
+
 config LOG_BUF_SHIFT
 	int
 	default 14
diff -Nru a/arch/sh64/kernel/fpu.c b/arch/sh64/kernel/fpu.c
--- a/arch/sh64/kernel/fpu.c	2005-03-01 23:38:57 -08:00
+++ b/arch/sh64/kernel/fpu.c	2005-03-01 23:38:57 -08:00
@@ -158,12 +158,12 @@
 		fpsave(&last_task_used_math->thread.fpu.hard);
         }
         last_task_used_math = current;
-        if (current->used_math) {
+        if (used_math()) {
                 fpload(&current->thread.fpu.hard);
         } else {
 		/* First time FPU user.  */
 		fpload(&init_fpuregs.hard);
-                current->used_math = 1;
+                set_used_math();
         }
 	release_fpu();
 }
diff -Nru a/arch/sh64/kernel/process.c b/arch/sh64/kernel/process.c
--- a/arch/sh64/kernel/process.c	2005-03-01 23:39:18 -08:00
+++ b/arch/sh64/kernel/process.c	2005-03-01 23:39:18 -08:00
@@ -338,7 +338,7 @@
 	}
 }
 
-void cpu_idle(void *unused)
+void cpu_idle(void)
 {
 	default_idle();
 }
@@ -688,7 +688,7 @@
 		last_task_used_math = NULL;
 	}
 	/* Force FPU state to be reinitialised after exec */
-	current->used_math = 0;
+	clear_used_math();
 #endif
 
 	/* if we are a kernel thread, about to change to user thread,
@@ -713,7 +713,7 @@
 	int fpvalid;
 	struct task_struct *tsk = current;
 
-	fpvalid = tsk->used_math;
+	fpvalid = !!tsk_used_math(tsk);
 	if (fpvalid) {
 		if (current == last_task_used_math) {
 			grab_fpu();
diff -Nru a/arch/sh64/kernel/ptrace.c b/arch/sh64/kernel/ptrace.c
--- a/arch/sh64/kernel/ptrace.c	2005-03-01 23:39:07 -08:00
+++ b/arch/sh64/kernel/ptrace.c	2005-03-01 23:39:07 -08:00
@@ -63,7 +63,7 @@
 	struct pt_regs *regs;
 	regs = (struct pt_regs*)((unsigned char *)task + THREAD_SIZE) - 1;
 
-	if (!task->used_math) {
+	if (!tsk_used_math(task)) {
 		if (addr == offsetof(struct user_fpu_struct, fpscr)) {
 			tmp = FPSCR_INIT;
 		} else {
@@ -105,9 +105,9 @@
 
 	regs = (struct pt_regs*)((unsigned char *)task + THREAD_SIZE) - 1;
 
-	if (!task->used_math) {
+	if (!tsk_used_math(task)) {
 		fpinit(&task->thread.fpu.hard);
-		task->used_math = 1;
+		set_stopped_child_used_math(task);
 	} else if (last_task_used_math == task) {
 		grab_fpu();
 		fpsave(&task->thread.fpu.hard);
@@ -187,7 +187,7 @@
 			 (addr <  offsetof(struct user, u_fpvalid))) {
 			tmp = get_fpu_long(child, addr - offsetof(struct user, fpu));
 		} else if (addr == offsetof(struct user, u_fpvalid)) {
-			tmp = child->used_math;
+			tmp = !!tsk_used_math(child);
 		} else {
 			break;
 		}
diff -Nru a/arch/sh64/kernel/signal.c b/arch/sh64/kernel/signal.c
--- a/arch/sh64/kernel/signal.c	2005-03-01 23:38:57 -08:00
+++ b/arch/sh64/kernel/signal.c	2005-03-01 23:38:57 -08:00
@@ -186,7 +186,7 @@
 	int fpvalid;
 
 	err |= __get_user (fpvalid, &sc->sc_fpvalid);
-	current->used_math = fpvalid;
+	conditional_used_math(fpvalid);
 	if (! fpvalid)
 		return err;
 
@@ -207,7 +207,7 @@
 	int err = 0;
 	int fpvalid;
 
-	fpvalid = current->used_math;
+	fpvalid = !!used_math();
 	err |= __put_user(fpvalid, &sc->sc_fpvalid);
 	if (! fpvalid)
 		return err;
@@ -222,7 +222,7 @@
 
 	err |= __copy_to_user(&sc->sc_fpregs[0], &current->thread.fpu.hard,
 			      (sizeof(long long) * 32) + (sizeof(int) * 1));
-	current->used_math = 0;
+	clear_used_math();
 
 	return err;
 }
@@ -701,10 +701,8 @@
 	if (!user_mode(regs))
 		return 1;
 
-	if (current->flags & PF_FREEZE) {
-		refrigerator(0);
+	if (try_to_freeze(0))
 		goto no_signal;
-		}
 
 	if (!oldset)
 		oldset = &current->blocked;
diff -Nru a/arch/sh64/lib/c-checksum.c b/arch/sh64/lib/c-checksum.c
--- a/arch/sh64/lib/c-checksum.c	2005-03-01 23:38:58 -08:00
+++ b/arch/sh64/lib/c-checksum.c	2005-03-01 23:38:58 -08:00
@@ -136,7 +136,7 @@
 
 /* Copy while checksumming, otherwise like csum_partial.  */
 unsigned int
-csum_partial_copy(const char *src, char *dst, int len, unsigned int sum)
+csum_partial_copy(const unsigned char *src, unsigned char *dst, int len, unsigned int sum)
 {
 	sum = csum_partial(src, len, sum);
 	memcpy(dst, src, len);
@@ -147,7 +147,7 @@
 /* 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 char *src, char *dst, int len,
+csum_partial_copy_from_user(const unsigned char *src, unsigned char *dst, int len,
 			    unsigned int sum, int *err_ptr)
 {
 	int missing;
@@ -168,7 +168,7 @@
 
 /* Copy to userspace and compute checksum.  */
 unsigned int
-csum_partial_copy_to_user(const char *src, char *dst, int len,
+csum_partial_copy_to_user(const unsigned char *src, unsigned char *dst, int len,
 			  unsigned int sum, int *err_ptr)
 {
 	sum = csum_partial(src, len, sum);
@@ -221,7 +221,7 @@
 
 // Post SIM:
 unsigned int
-csum_partial_copy_nocheck(const char *src, char *dst, int len, unsigned int sum)
+csum_partial_copy_nocheck(const unsigned char *src, unsigned char *dst, int len, unsigned int sum)
 {
 	//  unsigned dummy;
 	pr_debug("csum_partial_copy_nocheck src %p dst %p len %d\n", src, dst,
diff -Nru a/arch/sparc/Kconfig b/arch/sparc/Kconfig
--- a/arch/sparc/Kconfig	2005-03-01 23:38:43 -08:00
+++ b/arch/sparc/Kconfig	2005-03-01 23:38:43 -08:00
@@ -207,6 +207,10 @@
 config RWSEM_XCHGADD_ALGORITHM
 	bool
 
+config GENERIC_CALIBRATE_DELAY
+	bool
+	default y
+
 config SUN_PM
 	bool
 	default y
@@ -375,6 +379,8 @@
 source "sound/Kconfig"
 
 source "drivers/usb/Kconfig"
+
+source "drivers/infiniband/Kconfig"
 
 source "drivers/char/watchdog/Kconfig"
 
diff -Nru a/arch/sparc/kernel/auxio.c b/arch/sparc/kernel/auxio.c
--- a/arch/sparc/kernel/auxio.c	2005-03-01 23:39:08 -08:00
+++ b/arch/sparc/kernel/auxio.c	2005-03-01 23:39:08 -08:00
@@ -18,7 +18,7 @@
  * in entry.S::floppy_tdone
  */
 void __iomem *auxio_register = NULL;
-static spinlock_t auxio_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(auxio_lock);
 
 void __init auxio_probe(void)
 {
@@ -53,7 +53,8 @@
 #endif
 		}
 	}
-	prom_getproperty(auxio_nd, "reg", (char *) auxregs, sizeof(auxregs));
+	if(prom_getproperty(auxio_nd, "reg", (char *) auxregs, sizeof(auxregs)) <= 0)
+		return;
 	prom_apply_obio_ranges(auxregs, 0x1);
 	/* Map the register both read and write */
 	r.flags = auxregs[0].which_io & 0xF;
@@ -121,7 +122,8 @@
 		return;
 
 	/* Map the power control register. */
-	prom_getproperty(node, "reg", (char *)&regs, sizeof(regs));
+	if (prom_getproperty(node, "reg", (char *)&regs, sizeof(regs)) <= 0)
+		return;
 	prom_apply_obio_ranges(&regs, 1);
 	memset(&r, 0, sizeof(r));
 	r.flags = regs.which_io & 0xF;
diff -Nru a/arch/sparc/kernel/idprom.c b/arch/sparc/kernel/idprom.c
--- a/arch/sparc/kernel/idprom.c	2005-03-01 23:38:53 -08:00
+++ b/arch/sparc/kernel/idprom.c	2005-03-01 23:38:53 -08:00
@@ -53,13 +53,12 @@
 
 	for (i = 0; i < NUM_SUN_MACHINES; i++) {
 		if(Sun_Machines[i].id_machtype == machtype) {
-			if (machtype != (SM_SUN4M_OBP | 0x00))
+			if (machtype != (SM_SUN4M_OBP | 0x00) ||
+			    prom_getproperty(prom_root_node, "banner-name",
+					     sysname, sizeof(sysname)) <= 0)
 				printk("TYPE: %s\n", Sun_Machines[i].name);
-			else {
-				prom_getproperty(prom_root_node, "banner-name",
-						 sysname, sizeof(sysname));
+			else
 				printk("TYPE: %s\n", sysname);
-			}
 			return;
 		}
 	}
diff -Nru a/arch/sparc/kernel/irq.c b/arch/sparc/kernel/irq.c
--- a/arch/sparc/kernel/irq.c	2005-03-01 23:38:51 -08:00
+++ b/arch/sparc/kernel/irq.c	2005-03-01 23:38:51 -08:00
@@ -159,7 +159,7 @@
 };
 
 /* Used to protect the IRQ action lists */
-spinlock_t irq_action_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(irq_action_lock);
 
 int show_interrupts(struct seq_file *p, void *v)
 {
diff -Nru a/arch/sparc/kernel/muldiv.c b/arch/sparc/kernel/muldiv.c
--- a/arch/sparc/kernel/muldiv.c	2005-03-01 23:39:08 -08:00
+++ b/arch/sparc/kernel/muldiv.c	2005-03-01 23:39:08 -08:00
@@ -4,6 +4,9 @@
  *
  * Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ *
+ * 2004-12-25	Krzysztof Helt (krzysztof.h1@wp.pl) 
+ *		- fixed registers constrains in inline assembly declarations
  */
 
 #include <linux/kernel.h>
@@ -132,7 +135,7 @@
 			"mov	%%o0, %0\n\t"
 			"mov	%%o1, %1\n\t"
 			: "=r" (rs1), "=r" (rs2)
-		        :
+		        : "0" (rs1), "1" (rs2)
 			: "o0", "o1", "o2", "o3", "o4", "o5", "o7", "cc");
 #ifdef DEBUG_MULDIV
 		printk ("0x%x%08x\n", rs2, rs1);
@@ -152,7 +155,7 @@
 			"mov	%%o0, %0\n\t"
 			"mov	%%o1, %1\n\t"
 			: "=r" (rs1), "=r" (rs2)
-			:
+		        : "0" (rs1), "1" (rs2)
 			: "o0", "o1", "o2", "o3", "o4", "o5", "o7", "cc");
 #ifdef DEBUG_MULDIV
 		printk ("0x%x%08x\n", rs2, rs1);
@@ -181,7 +184,7 @@
 			"mov	%%o1, %0\n\t"
 			"mov	%%o0, %1\n\t"
 			: "=r" (rs1), "=r" (rs2)
-			: "r" (regs->y)
+			: "r" (regs->y), "0" (rs1), "1" (rs2)
 			: "o0", "o1", "o2", "o3", "o4", "o5", "o7",
 			  "g1", "g2", "g3", "cc");
 #ifdef DEBUG_MULDIV
@@ -210,7 +213,7 @@
 			"mov	%%o1, %0\n\t"
 			"mov	%%o0, %1\n\t"
 			: "=r" (rs1), "=r" (rs2)
-			: "r" (regs->y)
+			: "r" (regs->y), "0" (rs1), "1" (rs2)
 			: "o0", "o1", "o2", "o3", "o4", "o5", "o7",
 			  "g1", "g2", "g3", "cc");
 #ifdef DEBUG_MULDIV
diff -Nru a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c
--- a/arch/sparc/kernel/pcic.c	2005-03-01 23:38:58 -08:00
+++ b/arch/sparc/kernel/pcic.c	2005-03-01 23:38:58 -08:00
@@ -161,7 +161,7 @@
 static int pcic0_up;
 static struct linux_pcic pcic0;
 
-unsigned int pcic_regs;
+void * __iomem pcic_regs;
 volatile int pcic_speculative;
 volatile int pcic_trapped;
 
@@ -313,8 +313,7 @@
 	pcic0_up = 1;
 
 	pcic->pcic_res_regs.name = "pcic_registers";
-	pcic->pcic_regs = (unsigned long)
-	    ioremap(regs[0].phys_addr, regs[0].reg_size);
+	pcic->pcic_regs = ioremap(regs[0].phys_addr, regs[0].reg_size);
 	if (!pcic->pcic_regs) {
 		prom_printf("PCIC: Error, cannot map PCIC registers.\n");
 		prom_halt();
@@ -328,7 +327,7 @@
 	}
 
 	pcic->pcic_res_cfg_addr.name = "pcic_cfg_addr";
-	if ((pcic->pcic_config_space_addr = (unsigned long)
+	if ((pcic->pcic_config_space_addr =
 	    ioremap(regs[2].phys_addr, regs[2].reg_size * 2)) == 0) {
 		prom_printf("PCIC: Error, cannot map" 
 			    "PCI Configuration Space Address.\n");
@@ -340,7 +339,7 @@
 	 * must be the same. Thus, we need adjust size of data.
 	 */
 	pcic->pcic_res_cfg_data.name = "pcic_cfg_data";
-	if ((pcic->pcic_config_space_data = (unsigned long)
+	if ((pcic->pcic_config_space_data =
 	    ioremap(regs[3].phys_addr, regs[3].reg_size * 2)) == 0) {
 		prom_printf("PCIC: Error, cannot map" 
 			    "PCI Configuration Space Data.\n");
@@ -976,60 +975,66 @@
  * 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) {
+void outsb(unsigned long addr, const void *src, unsigned long count)
+{
 	while (count) {
 		count -= 1;
-		writeb(*(const char *)src, addr);
+		outb(*(const char *)src, addr);
 		src += 1;
-		addr += 1;
+		/* addr += 1; */
 	}
 }
 
-void outsw(unsigned long addr, const void *src, unsigned long count) {
+void outsw(unsigned long addr, const void *src, unsigned long count)
+{
 	while (count) {
 		count -= 2;
-		writew(*(const short *)src, addr);
+		outw(*(const short *)src, addr);
 		src += 2;
-		addr += 2;
+		/* addr += 2; */
 	}
 }
 
-void outsl(unsigned long addr, const void *src, unsigned long count) {
+void outsl(unsigned long addr, const void *src, unsigned long count)
+{
 	while (count) {
 		count -= 4;
-		writel(*(const long *)src, addr);
+		outl(*(const long *)src, addr);
 		src += 4;
-		addr += 4;
+		/* addr += 4; */
 	}
 }
 
-void insb(unsigned long addr, void *dst, unsigned long count) {
+void insb(unsigned long addr, void *dst, unsigned long count)
+{
 	while (count) {
 		count -= 1;
-		*(unsigned char *)dst = readb(addr);
+		*(unsigned char *)dst = inb(addr);
 		dst += 1;
-		addr += 1;
+		/* addr += 1; */
 	}
 }
 
-void insw(unsigned long addr, void *dst, unsigned long count) {
+void insw(unsigned long addr, void *dst, unsigned long count)
+{
 	while (count) {
 		count -= 2;
-		*(unsigned short *)dst = readw(addr);
+		*(unsigned short *)dst = inw(addr);
 		dst += 2;
-		addr += 2;
+		/* addr += 2; */
 	}
 }
 
-void insl(unsigned long addr, void *dst, unsigned long count) {
+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);
+		*(unsigned long *)dst = inl(addr);
 		dst += 4;
-		addr += 4;
+		/* addr += 4; */
 	}
 }
 
diff -Nru a/arch/sparc/kernel/process.c b/arch/sparc/kernel/process.c
--- a/arch/sparc/kernel/process.c	2005-03-01 23:38:52 -08:00
+++ b/arch/sparc/kernel/process.c	2005-03-01 23:38:52 -08:00
@@ -81,10 +81,8 @@
 /*
  * the idle loop on a Sparc... ;)
  */
-int cpu_idle(void)
+void cpu_idle(void)
 {
-	int ret = -EPERM;
-
 	if (current->pid != 0)
 		goto out;
 
@@ -128,15 +126,14 @@
 		schedule();
 		check_pgt_cache();
 	}
-	ret = 0;
 out:
-	return ret;
+	return;
 }
 
 #else
 
 /* This is being executed in task 0 'user space'. */
-int cpu_idle(void)
+void cpu_idle(void)
 {
 	/* endless idle loop with no priority at all */
 	while(1) {
@@ -201,7 +198,7 @@
 
 EXPORT_SYMBOL(machine_power_off);
 
-static spinlock_t sparc_backtrace_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(sparc_backtrace_lock);
 
 void __show_backtrace(unsigned long fp)
 {
@@ -552,6 +549,11 @@
 		}
 	}
 
+#ifdef CONFIG_SMP
+	/* FPU must be disabled on SMP. */
+	childregs->psr &= ~PSR_EF;
+#endif
+
 	/* Set the return value for the child. */
 	childregs->u_regs[UREG_I0] = current->pid;
 	childregs->u_regs[UREG_I1] = 1;
@@ -602,7 +604,7 @@
  */
 int dump_fpu (struct pt_regs * regs, elf_fpregset_t * fpregs)
 {
-	if (current->used_math == 0) {
+	if (used_math()) {
 		memset(fpregs, 0, sizeof(*fpregs));
 		fpregs->pr_q_entrysize = 8;
 		return 1;
diff -Nru a/arch/sparc/kernel/ptrace.c b/arch/sparc/kernel/ptrace.c
--- a/arch/sparc/kernel/ptrace.c	2005-03-01 23:39:17 -08:00
+++ b/arch/sparc/kernel/ptrace.c	2005-03-01 23:39:17 -08:00
@@ -48,9 +48,9 @@
 }
 
 static void
-pt_succ_return_linux(struct pt_regs *regs, unsigned long value, long *addr)
+pt_succ_return_linux(struct pt_regs *regs, unsigned long value, long __user *addr)
 {
-	if (put_user(value, (long __user *) addr)) {
+	if (put_user(value, addr)) {
 		pt_error_return(regs, EFAULT);
 		return;
 	}
@@ -61,7 +61,7 @@
 }
 
 static void
-pt_os_succ_return (struct pt_regs *regs, unsigned long val, long *addr)
+pt_os_succ_return (struct pt_regs *regs, unsigned long val, long __user *addr)
 {
 	if (current->personality == PER_SUNOS)
 		pt_succ_return (regs, val);
@@ -71,7 +71,7 @@
 
 /* Fuck me gently with a chainsaw... */
 static inline void read_sunos_user(struct pt_regs *regs, unsigned long offset,
-				   struct task_struct *tsk, long *addr)
+				   struct task_struct *tsk, long __user *addr)
 {
 	struct pt_regs *cregs = tsk->thread.kregs;
 	struct thread_info *t = tsk->thread_info;
@@ -345,14 +345,14 @@
 
 		if (access_process_vm(child, addr,
 				      &tmp, sizeof(tmp), 0) == sizeof(tmp))
-			pt_os_succ_return(regs, tmp, (long *)data);
+			pt_os_succ_return(regs, tmp, (long __user *)data);
 		else
 			pt_error_return(regs, EIO);
 		goto out_tsk;
 	}
 
 	case PTRACE_PEEKUSR:
-		read_sunos_user(regs, addr, child, (long *) data);
+		read_sunos_user(regs, addr, child, (long __user *) data);
 		goto out_tsk;
 
 	case PTRACE_POKEUSR:
diff -Nru a/arch/sparc/kernel/semaphore.c b/arch/sparc/kernel/semaphore.c
--- a/arch/sparc/kernel/semaphore.c	2005-03-01 23:39:16 -08:00
+++ b/arch/sparc/kernel/semaphore.c	2005-03-01 23:39:16 -08:00
@@ -44,7 +44,7 @@
 	wake_up(&sem->wait);
 }
 
-static spinlock_t semaphore_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(semaphore_lock);
 
 void __sched __down(struct semaphore * sem)
 {
diff -Nru a/arch/sparc/kernel/signal.c b/arch/sparc/kernel/signal.c
--- a/arch/sparc/kernel/signal.c	2005-03-01 23:39:08 -08:00
+++ b/arch/sparc/kernel/signal.c	2005-03-01 23:39:08 -08:00
@@ -202,7 +202,7 @@
 		regs->psr &= ~PSR_EF;
 	}
 #endif
-	current->used_math = 1;
+	set_used_math();
 	clear_tsk_thread_flag(current, TIF_USEDFPU);
 
 	if (verify_area(VERIFY_READ, fpu, sizeof(*fpu)))
@@ -535,7 +535,7 @@
 			sig_address = NULL;
 		}
 	}
-	err |= __put_user((long)sig_address, &sframep->sig_address);
+	err |= __put_user((unsigned long)sig_address, &sframep->sig_address);
 	err |= __put_user(sig_code, &sframep->sig_code);
 	err |= __put_user(sc, &sframep->sig_scptr);
 	if (err)
@@ -584,7 +584,7 @@
 				      &current->thread.fpqueue[0],
 				      ((sizeof(unsigned long) +
 				      (sizeof(unsigned long *)))*16));
-	current->used_math = 0;
+	clear_used_math();
 	return err;
 }
 
@@ -599,7 +599,7 @@
 	synchronize_user_stack();
 
 	sigframe_size = NF_ALIGNEDSZ;
-	if (!current->used_math)
+	if (!used_math())
 		sigframe_size -= sizeof(__siginfo_fpu_t);
 
 	sf = (struct new_signal_frame __user *)
@@ -616,7 +616,7 @@
 	
 	err |= __put_user(0, &sf->extra_size);
 
-	if (current->used_math) {
+	if (used_math()) {
 		err |= save_fpu_state(regs, &sf->fpu_state);
 		err |= __put_user(&sf->fpu_state, &sf->fpu_save);
 	} else {
@@ -677,7 +677,7 @@
 
 	synchronize_user_stack();
 	sigframe_size = RT_ALIGNEDSZ;
-	if (!current->used_math)
+	if (!used_math())
 		sigframe_size -= sizeof(__siginfo_fpu_t);
 	sf = (struct rt_signal_frame __user *)
 		get_sigframe(&ka->sa, regs, sigframe_size);
@@ -690,7 +690,7 @@
 	err |= __put_user(regs->npc, &sf->regs.npc);
 	err |= __put_user(regs->y, &sf->regs.y);
 	psr = regs->psr;
-	if (current->used_math)
+	if (used_math())
 		psr |= PSR_EF;
 	err |= __put_user(psr, &sf->regs.psr);
 	err |= __copy_to_user(&sf->regs.u_regs, regs->u_regs, sizeof(regs->u_regs));
@@ -832,7 +832,7 @@
 	 *    to flush the user windows.
 	 */
 	for (window = 0; window < tp->w_saved; window++) {
-		err |= __put_user((int *) &(gw->win[window]), &gw->winptr[window]);
+		err |= __put_user((int __user *) &(gw->win[window]), &gw->winptr[window]);
 		err |= __copy_to_user(&gw->win[window],
 				      &tp->reg_window[window],
 				      sizeof(svr4_rwindow_t));
@@ -1016,6 +1016,7 @@
 
 sigsegv_and_return:
 	force_sig(SIGSEGV, current);
+	return -EFAULT;
 }
 
 static inline void
diff -Nru a/arch/sparc/kernel/smp.c b/arch/sparc/kernel/smp.c
--- a/arch/sparc/kernel/smp.c	2005-03-01 23:38:54 -08:00
+++ b/arch/sparc/kernel/smp.c	2005-03-01 23:38:54 -08:00
@@ -234,7 +234,7 @@
 extern unsigned int lvl14_resolution;
 
 /* /proc/profile writes can call this, don't __init it please. */
-static spinlock_t prof_setup_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(prof_setup_lock);
 
 int setup_profiling_timer(unsigned int multiplier)
 {
diff -Nru a/arch/sparc/kernel/sparc_ksyms.c b/arch/sparc/kernel/sparc_ksyms.c
--- a/arch/sparc/kernel/sparc_ksyms.c	2005-03-01 23:38:52 -08:00
+++ b/arch/sparc/kernel/sparc_ksyms.c	2005-03-01 23:38:52 -08:00
@@ -75,7 +75,6 @@
 extern int __memcmp(const void *, const void *, __kernel_size_t);
 extern int __strncmp(const char *, const char *, __kernel_size_t);
 
-extern void bcopy (const char *, char *, int);
 extern int __ashrdi3(int, int);
 extern int __ashldi3(int, int);
 extern int __lshrdi3(int, int);
@@ -203,6 +202,10 @@
 #endif
 #ifdef CONFIG_PCI
 EXPORT_SYMBOL(ebus_chain);
+EXPORT_SYMBOL(insb);
+EXPORT_SYMBOL(outsb);
+EXPORT_SYMBOL(insw);
+EXPORT_SYMBOL(outsw);
 EXPORT_SYMBOL(insl);
 EXPORT_SYMBOL(outsl);
 EXPORT_SYMBOL(pci_alloc_consistent);
@@ -261,7 +264,6 @@
 EXPORT_SYMBOL(__prom_getsibling);
 
 /* sparc library symbols */
-EXPORT_SYMBOL(bcopy);
 EXPORT_SYMBOL(memchr);
 EXPORT_SYMBOL(memscan);
 EXPORT_SYMBOL(strlen);
diff -Nru a/arch/sparc/kernel/sun4c_irq.c b/arch/sparc/kernel/sun4c_irq.c
--- a/arch/sparc/kernel/sun4c_irq.c	2005-03-01 23:38:52 -08:00
+++ b/arch/sparc/kernel/sun4c_irq.c	2005-03-01 23:38:52 -08:00
@@ -217,13 +217,18 @@
 			panic("Cannot find /interrupt-enable node");
 
 		/* Depending on the "address" property is bad news... */
-		prom_getproperty(ie_node, "reg", (char *) int_regs, sizeof(int_regs));
-		memset(&phyres, 0, sizeof(struct resource));
-		phyres.flags = int_regs[0].which_io;
-		phyres.start = int_regs[0].phys_addr;
-		interrupt_enable = (char *) sbus_ioremap(&phyres, 0,
-		    int_regs[0].reg_size, "sun4c_intr");
+		interrupt_enable = NULL;
+		if (prom_getproperty(ie_node, "reg", (char *) int_regs,
+				     sizeof(int_regs)) != -1) {
+			memset(&phyres, 0, sizeof(struct resource));
+			phyres.flags = int_regs[0].which_io;
+			phyres.start = int_regs[0].phys_addr;
+			interrupt_enable = (char *) sbus_ioremap(&phyres, 0,
+			    int_regs[0].reg_size, "sun4c_intr");
+		}
 	}
+	if (!interrupt_enable)
+		panic("Cannot map interrupt_enable");
 
 	BTFIXUPSET_CALL(sbint_to_irq, sun4c_sbint_to_irq, BTFIXUPCALL_NORM);
 	BTFIXUPSET_CALL(enable_irq, sun4c_enable_irq, BTFIXUPCALL_NORM);
diff -Nru a/arch/sparc/kernel/sun4d_irq.c b/arch/sparc/kernel/sun4d_irq.c
--- a/arch/sparc/kernel/sun4d_irq.c	2005-03-01 23:38:43 -08:00
+++ b/arch/sparc/kernel/sun4d_irq.c	2005-03-01 23:38:43 -08:00
@@ -72,7 +72,7 @@
 
 static int nsbi;
 #ifdef CONFIG_SMP
-spinlock_t sun4d_imsk_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(sun4d_imsk_lock);
 #endif
 
 int show_sun4d_interrupts(struct seq_file *p, void *v)
diff -Nru a/arch/sparc/kernel/sun4d_smp.c b/arch/sparc/kernel/sun4d_smp.c
--- a/arch/sparc/kernel/sun4d_smp.c	2005-03-01 23:38:52 -08:00
+++ b/arch/sparc/kernel/sun4d_smp.c	2005-03-01 23:38:52 -08:00
@@ -122,8 +122,7 @@
 		
 	/* Fix idle thread fields. */
 	__asm__ __volatile__("ld [%0], %%g6\n\t"
-			     "sta %%g6, [%%g0] %1\n\t"
-			     : : "r" (&current_set[cpuid]), "i" (ASI_M_VIKING_TMP2)
+			     : : "r" (&current_set[cpuid])
 			     : "memory" /* paranoid */);
 
 	cpu_leds[cpuid] = 0x9;
@@ -146,7 +145,6 @@
 	spin_unlock_irqrestore(&sun4d_imsk_lock, flags);
 }
 
-extern int cpu_idle(void *unused);
 extern void init_IRQ(void);
 extern void cpu_panic(void);
 
@@ -302,7 +300,7 @@
 	unsigned char processors_out[NR_CPUS]; /* Set when ipi exited. */
 } ccall_info __attribute__((aligned(8)));
 
-static spinlock_t cross_call_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(cross_call_lock);
 
 /* Cross calls must be serialized, at least currently. */
 void smp4d_cross_call(smpfunc_t func, unsigned long arg1, unsigned long arg2,
@@ -399,7 +397,7 @@
 	SMP_PRINTK(("smp4d_message_pass %d %d %08lx %d\n", target, msg, data, wait));
 	if (msg == MSG_STOP_CPU && target == MSG_ALL_BUT_SELF) {
 		unsigned long flags;
-		static spinlock_t stop_cpu_lock = SPIN_LOCK_UNLOCKED;
+		static DEFINE_SPINLOCK(stop_cpu_lock);
 		spin_lock_irqsave(&stop_cpu_lock, flags);
 		smp4d_stop_cpu_sender = me;
 		smp4d_cross_call((smpfunc_t)smp4d_stop_cpu, 0, 0, 0, 0, 0);
@@ -460,25 +458,18 @@
 
 void __init smp4d_blackbox_current(unsigned *addr)
 {
-	/* We have a nice Linux current register :) */
-	int rd = addr[1] & 0x3e000000;
+	int rd = *addr & 0x3e000000;
 	
-	addr[0] = 0x10800006;			/* b .+24 */
-	addr[1] = 0xc0800820 | rd;		/* lda [%g0] ASI_M_VIKING_TMP2, reg */
+	addr[0] = 0xc0800800 | rd;		/* lda [%g0] ASI_M_VIKING_TMP1, reg */
+	addr[2] = 0x81282002 | rd | (rd >> 11);	/* sll reg, 2, reg */
+	addr[4] = 0x01000000;			/* nop */
 }
 
 void __init sun4d_init_smp(void)
 {
 	int i;
-	extern unsigned int patchme_store_new_current[];
 	extern unsigned int t_nmi[], linux_trap_ipi15_sun4d[], linux_trap_ipi15_sun4m[];
 
-	/* Store current into Linux current register :) */
-	__asm__ __volatile__("sta %%g6, [%%g0] %0" : : "i"(ASI_M_VIKING_TMP2));
-	
-	/* Patch switch_to */
-	patchme_store_new_current[0] = (patchme_store_new_current[0] & 0x3e000000) | 0xc0a00820;
-	
 	/* Patch ipi15 trap table */
 	t_nmi[1] = t_nmi[1] + (linux_trap_ipi15_sun4d - linux_trap_ipi15_sun4m);
 	
diff -Nru a/arch/sparc/kernel/sun4m_smp.c b/arch/sparc/kernel/sun4m_smp.c
--- a/arch/sparc/kernel/sun4m_smp.c	2005-03-01 23:39:09 -08:00
+++ b/arch/sparc/kernel/sun4m_smp.c	2005-03-01 23:39:09 -08:00
@@ -121,7 +121,6 @@
 	local_irq_enable();
 }
 
-extern int cpu_idle(void *unused);
 extern void init_IRQ(void);
 extern void cpu_panic(void);
 
@@ -322,7 +321,7 @@
 	unsigned long processors_out[NR_CPUS]; /* Set when ipi exited. */
 } ccall_info;
 
-static spinlock_t cross_call_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(cross_call_lock);
 
 /* Cross calls must be serialized, at least currently. */
 void smp4m_cross_call(smpfunc_t func, unsigned long arg1, unsigned long arg2,
diff -Nru a/arch/sparc/kernel/sys_sparc.c b/arch/sparc/kernel/sys_sparc.c
--- a/arch/sparc/kernel/sys_sparc.c	2005-03-01 23:38:55 -08:00
+++ b/arch/sparc/kernel/sys_sparc.c	2005-03-01 23:38:55 -08:00
@@ -197,8 +197,7 @@
 				goto out;
 				}
 			case 1:	/* iBCS2 emulator entry point */
-				err = do_shmat (first, (char __user *) ptr,
-						second, (ulong *) third);
+				err = -EINVAL;
 				goto out;
 			}
 		case SHMDT: 
diff -Nru a/arch/sparc/kernel/time.c b/arch/sparc/kernel/time.c
--- a/arch/sparc/kernel/time.c	2005-03-01 23:39:18 -08:00
+++ b/arch/sparc/kernel/time.c	2005-03-01 23:39:18 -08:00
@@ -50,9 +50,9 @@
 
 EXPORT_SYMBOL(jiffies_64);
 
-spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(rtc_lock);
 enum sparc_clock_type sp_clock_typ;
-spinlock_t mostek_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(mostek_lock);
 void __iomem *mstk48t02_regs = NULL;
 static struct mostek48t08 *mstk48t08_regs = NULL;
 static int set_rtc_mmss(unsigned long);
diff -Nru a/arch/sparc/kernel/traps.c b/arch/sparc/kernel/traps.c
--- a/arch/sparc/kernel/traps.c	2005-03-01 23:38:57 -08:00
+++ b/arch/sparc/kernel/traps.c	2005-03-01 23:38:57 -08:00
@@ -246,17 +246,17 @@
 		       &fptask->thread.fpqueue[0], &fptask->thread.fpqdepth);
 	}
 	last_task_used_math = current;
-	if(current->used_math) {
+	if(used_math()) {
 		fpload(&current->thread.float_regs[0], &current->thread.fsr);
 	} else {
 		/* Set initial sane state. */
 		fpload(&init_fregs[0], &init_fsr);
-		current->used_math = 1;
+		set_used_math();
 	}
 #else
-	if(!current->used_math) {
+	if(!used_math()) {
 		fpload(&init_fregs[0], &init_fsr);
-		current->used_math = 1;
+		set_used_math();
 	} else {
 		fpload(&current->thread.float_regs[0], &current->thread.fsr);
 	}
diff -Nru a/arch/sparc/lib/atomic32.c b/arch/sparc/lib/atomic32.c
--- a/arch/sparc/lib/atomic32.c	2005-03-01 23:38:57 -08:00
+++ b/arch/sparc/lib/atomic32.c	2005-03-01 23:38:57 -08:00
@@ -20,8 +20,9 @@
 
 #else /* SMP */
 
+static spinlock_t dummy = SPIN_LOCK_UNLOCKED;
 #define ATOMIC_HASH_SIZE	1
-#define ATOMIC_HASH(a)		0
+#define ATOMIC_HASH(a)		(&dummy)
 
 #endif /* SMP */
 
diff -Nru a/arch/sparc/lib/bitext.c b/arch/sparc/lib/bitext.c
--- a/arch/sparc/lib/bitext.c	2005-03-01 23:38:57 -08:00
+++ b/arch/sparc/lib/bitext.c	2005-03-01 23:38:57 -08:00
@@ -29,10 +29,17 @@
 	int offset, count;	/* siamese twins */
 	int off_new;
 	int align1;
-	int i;
+	int i, color;
 
-	if (align == 0)
-		align = 1;
+	if (t->num_colors) {
+		/* align is overloaded to be the page color */
+		color = align;
+		align = t->num_colors;
+	} else {
+		color = 0;
+		if (align == 0)
+			align = 1;
+	}
 	align1 = align - 1;
 	if ((align & align1) != 0)
 		BUG();
@@ -40,6 +47,7 @@
 		BUG();
 	if (len <= 0 || len > t->size)
 		BUG();
+	color &= align1;
 
 	spin_lock(&t->lock);
 	if (len < t->last_size)
@@ -49,7 +57,7 @@
 	count = 0;
 	for (;;) {
 		off_new = find_next_zero_bit(t->map, t->size, offset);
-		off_new = (off_new + align1) & ~align1;
+		off_new = ((off_new + align1) & ~align1) + color;
 		count += off_new - offset;
 		offset = off_new;
 		if (offset >= t->size)
@@ -121,6 +129,4 @@
 	spin_lock_init(&t->lock);
 	t->map = map;
 	t->size = size;
-	t->last_size = 0;
-	t->first_free = 0;
 }
diff -Nru a/arch/sparc/lib/memcpy.S b/arch/sparc/lib/memcpy.S
--- a/arch/sparc/lib/memcpy.S	2005-03-01 23:39:17 -08:00
+++ b/arch/sparc/lib/memcpy.S	2005-03-01 23:39:17 -08:00
@@ -1,5 +1,5 @@
-/* memcpy.S: Sparc optimized memcpy, bcopy and memmove code
- * Hand optimized from GNU libc's memcpy, bcopy and memmove
+/* memcpy.S: Sparc optimized memcpy and memmove code
+ * Hand optimized from GNU libc's memcpy and memmove
  * Copyright (C) 1991,1996 Free Software Foundation
  * Copyright (C) 1995 Linus Torvalds (Linus.Torvalds@helsinki.fi)
  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -192,13 +192,6 @@
 	retl
 	 nop		! Only bcopy returns here and it retuns void...
 
-FUNC(bcopy)
-	mov		%o0, %o3
-	mov		%o1, %o0
-	mov		%o3, %o1
-	tst		%o2
-	bcs		0b
-	 /* Do the cmp in the delay slot */
 #ifdef __KERNEL__
 FUNC(amemmove)
 FUNC(__memmove)
diff -Nru a/arch/sparc/mm/fault.c b/arch/sparc/mm/fault.c
--- a/arch/sparc/mm/fault.c	2005-03-01 23:39:18 -08:00
+++ b/arch/sparc/mm/fault.c	2005-03-01 23:39:18 -08:00
@@ -294,16 +294,17 @@
 	 * the fault.
 	 */
 	switch (handle_mm_fault(mm, vma, address, write)) {
-	case 1:
-		current->min_flt++;
-		break;
-	case 2:
+	case VM_FAULT_SIGBUS:
+		goto do_sigbus;
+	case VM_FAULT_OOM:
+		goto out_of_memory;
+	case VM_FAULT_MAJOR:
 		current->maj_flt++;
 		break;
-	case 0:
-		goto do_sigbus;
+	case VM_FAULT_MINOR:
 	default:
-		goto out_of_memory;
+		current->min_flt++;
+		break;
 	}
 	up_read(&mm->mmap_sem);
 	return;
@@ -535,8 +536,11 @@
 		if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
 			goto bad_area;
 	}
-	if (!handle_mm_fault(mm, vma, address, write))
+	switch (handle_mm_fault(mm, vma, address, write)) {
+	case VM_FAULT_SIGBUS:
+	case VM_FAULT_OOM:
 		goto do_sigbus;
+	}
 	up_read(&mm->mmap_sem);
 	return;
 bad_area:
diff -Nru a/arch/sparc/mm/highmem.c b/arch/sparc/mm/highmem.c
--- a/arch/sparc/mm/highmem.c	2005-03-01 23:38:54 -08:00
+++ b/arch/sparc/mm/highmem.c	2005-03-01 23:38:54 -08:00
@@ -36,7 +36,7 @@
 
 	/* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */
 	inc_preempt_count();
-	if (page < highmem_start_page)
+	if (!PageHighMem(page))
 		return page_address(page);
 
 	idx = type + KM_TYPE_NR*smp_processor_id();
diff -Nru a/arch/sparc/mm/init.c b/arch/sparc/mm/init.c
--- a/arch/sparc/mm/init.c	2005-03-01 23:38:56 -08:00
+++ b/arch/sparc/mm/init.c	2005-03-01 23:38:56 -08:00
@@ -402,8 +402,6 @@
 	int reservedpages = 0;
 	int i;
 
-	highmem_start_page = pfn_to_page(highstart_pfn);
-
 	if (PKMAP_BASE+LAST_PKMAP*PAGE_SIZE >= FIXADDR_START) {
 		prom_printf("BUG: fixmap and pkmap areas overlap\n");
 		prom_printf("pkbase: 0x%lx pkend: 0x%lx fixstart 0x%lx\n",
diff -Nru a/arch/sparc/mm/io-unit.c b/arch/sparc/mm/io-unit.c
--- a/arch/sparc/mm/io-unit.c	2005-03-01 23:38:56 -08:00
+++ b/arch/sparc/mm/io-unit.c	2005-03-01 23:38:56 -08:00
@@ -52,13 +52,15 @@
 	iounit->rotor[1] = IOUNIT_BMAP2_START;
 	iounit->rotor[2] = IOUNIT_BMAPM_START;
 
-	prom_getproperty(sbi_node, "reg", (void *) iommu_promregs,
-			 sizeof(iommu_promregs));
-	prom_apply_generic_ranges(io_node, 0, iommu_promregs, 3);
-	memset(&r, 0, sizeof(r));
-	r.flags = iommu_promregs[2].which_io;
-	r.start = iommu_promregs[2].phys_addr;
-	xpt = (iopte_t *) sbus_ioremap(&r, 0, PAGE_SIZE * 16, "XPT");
+	xpt = NULL;
+	if(prom_getproperty(sbi_node, "reg", (void *) iommu_promregs,
+			    sizeof(iommu_promregs)) != -1) {
+		prom_apply_generic_ranges(io_node, 0, iommu_promregs, 3);
+		memset(&r, 0, sizeof(r));
+		r.flags = iommu_promregs[2].which_io;
+		r.start = iommu_promregs[2].phys_addr;
+		xpt = (iopte_t *) sbus_ioremap(&r, 0, PAGE_SIZE * 16, "XPT");
+	}
 	if(!xpt) panic("Cannot map External Page Table.");
 	
 	sbus->iommu = (struct iommu_struct *)iounit;
@@ -196,7 +198,7 @@
 			pte_t *ptep;
 			long i;
 
-			pgdp = pgd_offset(init_task.mm, addr);
+			pgdp = pgd_offset(&init_mm, addr);
 			pmdp = pmd_offset(pgdp, addr);
 			ptep = pte_offset_map(pmdp, addr);
 
diff -Nru a/arch/sparc/mm/iommu.c b/arch/sparc/mm/iommu.c
--- a/arch/sparc/mm/iommu.c	2005-03-01 23:39:17 -08:00
+++ b/arch/sparc/mm/iommu.c	2005-03-01 23:39:17 -08:00
@@ -71,14 +71,16 @@
 		prom_printf("Unable to allocate iommu structure\n");
 		prom_halt();
 	}
-	prom_getproperty(iommund, "reg", (void *) iommu_promregs,
-			 sizeof(iommu_promregs));
-	memset(&r, 0, sizeof(r));
-	r.flags = iommu_promregs[0].which_io;
-	r.start = iommu_promregs[0].phys_addr;
-	iommu->regs = (struct iommu_regs *)
-		sbus_ioremap(&r, 0, PAGE_SIZE * 3, "iommu_regs");
-	if(!iommu->regs) {
+	iommu->regs = NULL;
+	if (prom_getproperty(iommund, "reg", (void *) iommu_promregs,
+			 sizeof(iommu_promregs)) != -1) {
+		memset(&r, 0, sizeof(r));
+		r.flags = iommu_promregs[0].which_io;
+		r.start = iommu_promregs[0].phys_addr;
+		iommu->regs = (struct iommu_regs *)
+			sbus_ioremap(&r, 0, PAGE_SIZE * 3, "iommu_regs");
+	}
+	if (!iommu->regs) {
 		prom_printf("Cannot map IOMMU registers\n");
 		prom_halt();
 	}
@@ -119,6 +121,13 @@
 		prom_halt();
 	}
 	bit_map_init(&iommu->usemap, bitmap, IOMMU_NPTES);
+	/* To be coherent on HyperSparc, the page color of DVMA
+	 * and physical addresses must match.
+	 */
+	if (srmmu_modtype == HyperSparc)
+		iommu->usemap.num_colors = vac_cache_size >> PAGE_SHIFT;
+	else
+		iommu->usemap.num_colors = 1;
 
 	printk("IOMMU: impl %d vers %d table 0x%p[%d B] map [%d b]\n",
 	    impl, vers, iommu->page_table,
@@ -128,7 +137,9 @@
 }
 
 /* This begs to be btfixup-ed by srmmu. */
-static void iommu_viking_flush_iotlb(iopte_t *iopte, unsigned int niopte)
+/* Flush the iotlb entries to ram. */
+/* This could be better if we didn't have to flush whole pages. */
+static void iommu_flush_iotlb(iopte_t *iopte, unsigned int niopte)
 {
 	unsigned long start;
 	unsigned long end;
@@ -145,6 +156,11 @@
 			viking_flush_page(start);
 			start += PAGE_SIZE;
 		}
+	} else {
+		while(start < end) {
+			__flush_page_to_ram(start);
+			start += PAGE_SIZE;
+		}
 	}
 }
 
@@ -156,7 +172,8 @@
 	unsigned int busa, busa0;
 	int i;
 
-	ioptex = bit_map_string_get(&iommu->usemap, npages, 1);
+	/* page color = pfn of page */
+	ioptex = bit_map_string_get(&iommu->usemap, npages, page_to_pfn(page));
 	if (ioptex < 0)
 		panic("iommu out");
 	busa0 = iommu->start + (ioptex << PAGE_SHIFT);
@@ -172,8 +189,7 @@
 		page++;
 	}
 
-	iommu_viking_flush_iotlb(iopte0, npages);
-	flush_cache_all(); // hack to fix dma errors with hypersparc
+	iommu_flush_iotlb(iopte0, npages);
 
 	return busa0;
 }
@@ -328,7 +344,9 @@
 	if ((addr & ~PAGE_MASK) != 0) BUG();
 	if ((len & ~PAGE_MASK) != 0) BUG();
 
-	ioptex = bit_map_string_get(&iommu->usemap, len >> PAGE_SHIFT, 1);
+	/* page color = physical address */
+	ioptex = bit_map_string_get(&iommu->usemap, len >> PAGE_SHIFT,
+		addr >> PAGE_SHIFT);
 	if (ioptex < 0)
 		panic("iommu out");
 
@@ -372,7 +390,7 @@
 	 *        to handle the latter case as well.
 	 */
 	flush_cache_all();
-	iommu_viking_flush_iotlb(first, len >> PAGE_SHIFT);
+	iommu_flush_iotlb(first, len >> PAGE_SHIFT);
 	flush_tlb_all();
 	iommu_invalidate(iommu->regs);
 
diff -Nru a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c
--- a/arch/sparc/mm/srmmu.c	2005-03-01 23:38:58 -08:00
+++ b/arch/sparc/mm/srmmu.c	2005-03-01 23:38:58 -08:00
@@ -88,7 +88,7 @@
 ctxd_t *srmmu_context_table;
 
 int viking_mxcc_present;
-static spinlock_t srmmu_context_spinlock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(srmmu_context_spinlock);
 
 int is_hypersparc;
 
@@ -133,11 +133,12 @@
 static unsigned long srmmu_pte_pfn(pte_t pte)
 {
 	if (srmmu_device_memory(pte_val(pte))) {
-		/* XXX Anton obviously had something in mind when he did this.
-		 * But what?
+		/* Just return something that will cause
+		 * pfn_valid() to return false.  This makes
+		 * copy_one_pte() to just directly copy to
+		 * PTE over.
 		 */
-		/* return (struct page *)~0; */
-		BUG();
+		return ~0UL;
 	}
 	return (pte_val(pte) & SRMMU_PTE_PMASK) >> (PAGE_SHIFT-4);
 }
@@ -2197,6 +2198,7 @@
 	BTFIXUPSET_CALL(free_pgd_fast, srmmu_free_pgd_fast, BTFIXUPCALL_NORM);
 	BTFIXUPSET_CALL(get_pgd_fast, srmmu_get_pgd_fast, BTFIXUPCALL_NORM);
 
+	BTFIXUPSET_HALF(pte_readi, SRMMU_NOREAD);
 	BTFIXUPSET_HALF(pte_writei, SRMMU_WRITE);
 	BTFIXUPSET_HALF(pte_dirtyi, SRMMU_DIRTY);
 	BTFIXUPSET_HALF(pte_youngi, SRMMU_REF);
diff -Nru a/arch/sparc/mm/sun4c.c b/arch/sparc/mm/sun4c.c
--- a/arch/sparc/mm/sun4c.c	2005-03-01 23:39:08 -08:00
+++ b/arch/sparc/mm/sun4c.c	2005-03-01 23:39:08 -08:00
@@ -511,7 +511,8 @@
 		node = prom_searchsiblings(prom_root_node, "memory-error");
 		if (!node)
 			return;
-		prom_getproperty(node, "reg", (char *)regs, sizeof(regs));
+		if (prom_getproperty(node, "reg", (char *)regs, sizeof(regs)) <= 0)
+			return;
 		/* hmm I think regs[0].which_io is zero here anyways */
 		sun4c_memerr_reg = ioremap(regs[0].phys_addr, regs[0].reg_size);
 	}
@@ -2225,6 +2226,7 @@
 	BTFIXUPSET_CALL(free_pgd_fast, sun4c_free_pgd_fast, BTFIXUPCALL_NORM);
 	BTFIXUPSET_CALL(get_pgd_fast, sun4c_get_pgd_fast, BTFIXUPCALL_NORM);
 
+	BTFIXUPSET_HALF(pte_readi, _SUN4C_PAGE_READ);
 	BTFIXUPSET_HALF(pte_writei, _SUN4C_PAGE_WRITE);
 	BTFIXUPSET_HALF(pte_dirtyi, _SUN4C_PAGE_MODIFIED);
 	BTFIXUPSET_HALF(pte_youngi, _SUN4C_PAGE_ACCESSED);
diff -Nru a/arch/sparc/prom/console.c b/arch/sparc/prom/console.c
--- a/arch/sparc/prom/console.c	2005-03-01 23:38:55 -08:00
+++ b/arch/sparc/prom/console.c	2005-03-01 23:38:55 -08:00
@@ -111,6 +111,7 @@
 	int st_p;
 	char propb[64];
 	char *p;
+	int propl;
 
 	switch(prom_vers) {
 	case PROM_V0:
@@ -139,14 +140,16 @@
 		if(strncmp(propb, "serial", sizeof("serial")))
 			return PROMDEV_I_UNK;
 		}
-		prom_getproperty(prom_root_node, "stdin-path", propb, sizeof(propb));
-		p = propb;
-		while(*p) p++; p -= 2;
-		if(p[0] == ':') {
-			if(p[1] == 'a')
-				return PROMDEV_ITTYA;
-			else if(p[1] == 'b')
-				return PROMDEV_ITTYB;
+		propl = prom_getproperty(prom_root_node, "stdin-path", propb, sizeof(propb));
+		if(propl > 2) {
+			p = propb;
+			while(*p) p++; p -= 2;
+			if(p[0] == ':') {
+				if(p[1] == 'a')
+					return PROMDEV_ITTYA;
+				else if(p[1] == 'b')
+					return PROMDEV_ITTYB;
+			}
 		}
 		return PROMDEV_I_UNK;
 	}
@@ -179,7 +182,7 @@
 		restore_current();
 		spin_unlock_irqrestore(&prom_lock, flags);
 		propl = prom_getproperty(st_p, "device_type", propb, sizeof(propb));
-		if (propl >= 0 && propl == sizeof("display") &&
+		if (propl == sizeof("display") &&
 			strncmp("display", propb, sizeof("display")) == 0)
 		{
 			return PROMDEV_OSCREEN;
@@ -188,16 +191,20 @@
 			if(propl >= 0 &&
 			    strncmp("serial", propb, sizeof("serial")) != 0)
 				return PROMDEV_O_UNK;
-			prom_getproperty(prom_root_node, "stdout-path", propb, sizeof(propb));
-			if(strncmp(propb, con_name_jmc, CON_SIZE_JMC) == 0)
+			propl = prom_getproperty(prom_root_node, "stdout-path",
+						 propb, sizeof(propb));
+			if(propl == CON_SIZE_JMC &&
+			    strncmp(propb, con_name_jmc, CON_SIZE_JMC) == 0)
 				return PROMDEV_OTTYA;
-			p = propb;
-			while(*p) p++; p -= 2;
-			if(p[0]==':') {
-				if(p[1] == 'a')
-					return PROMDEV_OTTYA;
-				else if(p[1] == 'b')
-					return PROMDEV_OTTYB;
+			if(propl > 2) {
+				p = propb;
+				while(*p) p++; p-= 2;
+				if(p[0]==':') {
+					if(p[1] == 'a')
+						return PROMDEV_OTTYA;
+					else if(p[1] == 'b')
+						return PROMDEV_OTTYB;
+				}
 			}
 		} else {
 			switch(*romvec->pv_stdin) {
diff -Nru a/arch/sparc/prom/misc.c b/arch/sparc/prom/misc.c
--- a/arch/sparc/prom/misc.c	2005-03-01 23:39:18 -08:00
+++ b/arch/sparc/prom/misc.c	2005-03-01 23:39:18 -08:00
@@ -16,7 +16,7 @@
 
 extern void restore_current(void);
 
-spinlock_t prom_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(prom_lock);
 
 /* Reset and reboot the machine with the command 'bcommand'. */
 void
diff -Nru a/arch/sparc/prom/ranges.c b/arch/sparc/prom/ranges.c
--- a/arch/sparc/prom/ranges.c	2005-03-01 23:38:56 -08:00
+++ b/arch/sparc/prom/ranges.c	2005-03-01 23:38:56 -08:00
@@ -34,7 +34,7 @@
 	}
 }
 
-static void
+void
 prom_adjust_ranges(struct linux_prom_ranges *ranges1, int nranges1,
 		   struct linux_prom_ranges *ranges2, int nranges2)
 {
diff -Nru a/arch/sparc/prom/tree.c b/arch/sparc/prom/tree.c
--- a/arch/sparc/prom/tree.c	2005-03-01 23:38:55 -08:00
+++ b/arch/sparc/prom/tree.c	2005-03-01 23:38:55 -08:00
@@ -176,8 +176,11 @@
  */
 int prom_nodematch(int node, char *name)
 {
+	int error;
+
 	static char namebuf[128];
-	prom_getproperty(node, "name", namebuf, sizeof(namebuf));
+	error = prom_getproperty(node, "name", namebuf, sizeof(namebuf));
+	if (error == -1) return 0;
 	if(strcmp(namebuf, name) == 0) return 1;
 	return 0;
 }
diff -Nru a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig
--- a/arch/sparc64/Kconfig	2005-03-01 23:39:09 -08:00
+++ b/arch/sparc64/Kconfig	2005-03-01 23:39:09 -08:00
@@ -18,6 +18,11 @@
 
 source "init/Kconfig"
 
+config SYSVIPC_COMPAT
+	bool
+	depends on COMPAT && SYSVIPC
+	default y
+
 menu "General machine setup"
 
 config BBC_I2C
@@ -92,8 +97,8 @@
 	bool "Symmetric multi-processing support"
 	---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
-	  you have a system with more than one CPU, say Y.
+	  a system with only one CPU, say N. If you have a system with more than
+	  one CPU, say Y.
 
 	  If you say N here, the kernel will run on single and multiprocessor
 	  machines, but will use only one CPU of a multiprocessor machine. If
@@ -101,17 +106,11 @@
 	  singleprocessor machines. On a singleprocessor machine, the kernel
 	  will run faster if you say N here.
 
-	  Note that if you say Y here and choose architecture "586" or
-	  "Pentium" under "Processor family", the kernel will not work on 486
-	  architectures. Similarly, multiprocessor kernels for the "PPro"
-	  architecture may not work on all Pentium based boards.
-
 	  People using multiprocessor machines who say Y here should also say
 	  Y to "Enhanced Real Time Clock Support", below. The "Advanced Power
 	  Management" code will be disabled if you say Y here.
 
 	  See also the <file:Documentation/smp.txt>,
-	  <file:Documentation/i386/IO-APIC.txt>,
 	  <file:Documentation/nmi_watchdog.txt> and the SMP-HOWTO available at
 	  <http://www.tldp.org/docs.html#howto>.
 
@@ -186,6 +185,10 @@
 	bool
 	default y
 
+config GENERIC_CALIBRATE_DELAY
+	bool
+	default y
+
 choice
 	prompt "SPARC64 Huge TLB Page Size"
 	depends on HUGETLB_PAGE
@@ -556,7 +559,7 @@
 
 config DRM_FFB
 	tristate "Creator/Creator3D"
-	depends on DRM
+	depends on DRM && BROKEN
 	help
 	  Choose this option if you have one of Sun's Creator3D-based graphics
 	  and frame buffer cards.  Product page at
@@ -590,6 +593,8 @@
 source "sound/Kconfig"
 
 source "drivers/usb/Kconfig"
+
+source "drivers/infiniband/Kconfig"
 
 source "drivers/char/watchdog/Kconfig"
 
diff -Nru a/arch/sparc64/defconfig b/arch/sparc64/defconfig
--- a/arch/sparc64/defconfig	2005-03-01 23:38:55 -08:00
+++ b/arch/sparc64/defconfig	2005-03-01 23:38:55 -08:00
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc3
-# Wed Dec  8 21:14:26 2004
+# Linux kernel version: 2.6.11-rc4
+# Thu Feb 17 15:32:19 2005
 #
 CONFIG_64BIT=y
 CONFIG_MMU=y
@@ -53,6 +53,7 @@
 CONFIG_MODULE_SRCVERSION_ALL=y
 CONFIG_KMOD=y
 CONFIG_STOP_MACHINE=y
+CONFIG_SYSVIPC_COMPAT=y
 
 #
 # General machine setup
@@ -66,19 +67,20 @@
 CONFIG_NR_CPUS=4
 CONFIG_CPU_FREQ=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=m
 CONFIG_CPU_FREQ_GOV_USERSPACE=m
-# CONFIG_CPU_FREQ_24_API is not set
 CONFIG_CPU_FREQ_GOV_ONDEMAND=m
 CONFIG_CPU_FREQ_TABLE=y
 CONFIG_US3_FREQ=m
 CONFIG_US2E_FREQ=m
 CONFIG_SPARC64=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_HUGETLB_PAGE_SIZE_4MB=y
 # CONFIG_HUGETLB_PAGE_SIZE_512K is not set
 # CONFIG_HUGETLB_PAGE_SIZE_64K is not set
@@ -188,6 +190,7 @@
 # CONFIG_LOGO_LINUX_VGA16 is not set
 # CONFIG_LOGO_LINUX_CLUT224 is not set
 CONFIG_LOGO_SUN_CLUT224=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Serial drivers
@@ -227,6 +230,7 @@
 # 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
@@ -246,6 +250,7 @@
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -336,6 +341,7 @@
 #
 CONFIG_SCSI_SPI_ATTRS=y
 CONFIG_SCSI_FC_ATTRS=m
+CONFIG_SCSI_ISCSI_ATTRS=m
 
 #
 # SCSI low-level drivers
@@ -395,7 +401,6 @@
 # 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_DC395x=m
 # CONFIG_SCSI_DC390T is not set
 CONFIG_SCSI_DEBUG=m
@@ -601,7 +606,6 @@
 CONFIG_IP_NF_TARGET_REDIRECT=m
 CONFIG_IP_NF_TARGET_NETMAP=m
 CONFIG_IP_NF_TARGET_SAME=m
-CONFIG_IP_NF_NAT_LOCAL=y
 CONFIG_IP_NF_NAT_SNMP_BASIC=m
 CONFIG_IP_NF_NAT_IRC=m
 CONFIG_IP_NF_NAT_FTP=m
@@ -620,8 +624,6 @@
 CONFIG_IP_NF_ARPTABLES=m
 CONFIG_IP_NF_ARPFILTER=m
 CONFIG_IP_NF_ARP_MANGLE=m
-CONFIG_IP_NF_COMPAT_IPCHAINS=m
-CONFIG_IP_NF_COMPAT_IPFWADM=m
 
 #
 # IPv6: Netfilter Configuration
@@ -675,6 +677,7 @@
 CONFIG_BRIDGE_EBT_REDIRECT=m
 CONFIG_BRIDGE_EBT_SNAT=m
 CONFIG_BRIDGE_EBT_LOG=m
+CONFIG_BRIDGE_EBT_ULOG=m
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
 
@@ -741,6 +744,7 @@
 CONFIG_NET_CLS_U32=m
 CONFIG_CLS_U32_PERF=y
 CONFIG_NET_CLS_IND=y
+CONFIG_CLS_U32_MARK=y
 CONFIG_NET_CLS_RSVP=m
 CONFIG_NET_CLS_RSVP6=m
 CONFIG_NET_CLS_ACT=y
@@ -842,6 +846,7 @@
 CONFIG_BT_HCIUART_BCSP=y
 CONFIG_BT_HCIUART_BCSP_TXCRC=y
 CONFIG_BT_HCIBCM203X=m
+CONFIG_BT_HCIBPA10X=m
 CONFIG_BT_HCIBFUSB=m
 CONFIG_BT_HCIVHCI=m
 CONFIG_NETDEVICES=y
@@ -893,7 +898,6 @@
 CONFIG_FORCEDETH=m
 CONFIG_DGRS=m
 CONFIG_EEPRO100=m
-# CONFIG_EEPRO100_PIO is not set
 CONFIG_E100=m
 CONFIG_E100_NAPI=y
 CONFIG_FEALNX=m
@@ -926,6 +930,7 @@
 CONFIG_YELLOWFIN=m
 CONFIG_R8169=m
 CONFIG_R8169_NAPI=y
+CONFIG_R8169_VLAN=y
 CONFIG_SK98LIN=m
 CONFIG_VIA_VELOCITY=m
 CONFIG_TIGON3=m
@@ -937,6 +942,7 @@
 CONFIG_IXGB_NAPI=y
 CONFIG_S2IO=m
 CONFIG_S2IO_NAPI=y
+CONFIG_2BUFF_MODE=y
 
 #
 # Token Ring devices
@@ -1078,7 +1084,6 @@
 # XFree86 DRI support
 #
 CONFIG_DRM=y
-CONFIG_DRM_FFB=m
 CONFIG_DRM_TDFX=m
 # CONFIG_DRM_R128 is not set
 
@@ -1109,13 +1114,14 @@
 # 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_GAMEPORT_CS461X=m
 CONFIG_SERIO=y
 CONFIG_SERIO_I8042=y
 # CONFIG_SERIO_SERPORT is not set
 # CONFIG_SERIO_CT82C710 is not set
 # CONFIG_SERIO_PARKBD is not set
 CONFIG_SERIO_PCIPS2=m
+CONFIG_SERIO_LIBPS2=y
 CONFIG_SERIO_RAW=m
 
 #
@@ -1201,6 +1207,7 @@
 CONFIG_SENSORS_LM90=m
 CONFIG_SENSORS_MAX1619=m
 CONFIG_SENSORS_PC87360=m
+CONFIG_SENSORS_SMSC47B397=m
 CONFIG_SENSORS_SMSC47M1=m
 CONFIG_SENSORS_VIA686A=m
 CONFIG_SENSORS_W83781D=m
@@ -1236,10 +1243,16 @@
 # CONFIG_REISERFS_FS is not set
 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=y
 CONFIG_XFS_SECURITY=y
@@ -1305,7 +1318,6 @@
 CONFIG_VXFS_FS=m
 CONFIG_HPFS_FS=m
 CONFIG_QNX4FS_FS=m
-# CONFIG_QNX4FS_RW is not set
 CONFIG_SYSV_FS=m
 CONFIG_UFS_FS=m
 CONFIG_UFS_FS_WRITE=y
@@ -1333,7 +1345,7 @@
 CONFIG_CIFS=m
 # CONFIG_CIFS_STATS is not set
 # CONFIG_CIFS_XATTR is not set
-CONFIG_CIFS_POSIX=y
+# CONFIG_CIFS_EXPERIMENTAL is not set
 CONFIG_NCP_FS=m
 # CONFIG_NCPFS_PACKET_SIGNING is not set
 # CONFIG_NCPFS_IOCTL_LOCKING is not set
@@ -1460,7 +1472,7 @@
 # CONFIG_DVB_TTUSB_BUDGET is not set
 CONFIG_DVB_TTUSB_DEC=m
 CONFIG_DVB_DIBUSB=m
-CONFIG_DVB_DIBUSB_MISDESIGNED_AN2235=y
+# CONFIG_DVB_DIBUSB_MISDESIGNED_DEVICES is not set
 CONFIG_DVB_DIBCOM_DEBUG=y
 CONFIG_DVB_CINERGYT2=m
 # CONFIG_DVB_CINERGYT2_TUNING is not set
@@ -1469,6 +1481,7 @@
 # Supported FlexCopII (B2C2) Adapters
 #
 CONFIG_DVB_B2C2_SKYSTAR=m
+CONFIG_DVB_B2C2_USB=m
 
 #
 # Supported BT878 Adapters
@@ -1505,6 +1518,7 @@
 CONFIG_DVB_NXT6000=m
 CONFIG_DVB_MT352=m
 CONFIG_DVB_DIB3000MB=m
+CONFIG_DVB_DIB3000MC=m
 
 #
 # DVB-C (cable) frontends
@@ -1513,6 +1527,11 @@
 CONFIG_DVB_VES1820=m
 CONFIG_DVB_TDA10021=m
 CONFIG_DVB_STV0297=m
+
+#
+# ATSC (North American/Korean Terresterial DTV) frontends
+#
+CONFIG_DVB_NXT2002=m
 CONFIG_VIDEO_SAA7146=m
 CONFIG_VIDEO_SAA7146_VV=m
 CONFIG_VIDEO_VIDEOBUF=m
@@ -1520,6 +1539,7 @@
 CONFIG_VIDEO_BUF=m
 CONFIG_VIDEO_BTCX=m
 CONFIG_VIDEO_IR=m
+CONFIG_VIDEO_TVEEPROM=m
 
 #
 # Sound
@@ -1574,6 +1594,8 @@
 # CONFIG_SND_CS46XX_NEW_DSP is not set
 CONFIG_SND_CS4281=m
 CONFIG_SND_EMU10K1=m
+CONFIG_SND_EMU10K1X=m
+CONFIG_SND_CA0106=m
 CONFIG_SND_KORG1212=m
 CONFIG_SND_MIXART=m
 CONFIG_SND_NM256=m
@@ -1598,13 +1620,13 @@
 CONFIG_SND_INTEL8X0M=m
 CONFIG_SND_SONICVIBES=m
 # CONFIG_SND_VIA82XX is not set
+CONFIG_SND_VIA82XX_MODEM=m
 CONFIG_SND_VX222=m
 
 #
 # USB devices
 #
 # CONFIG_SND_USB_AUDIO is not set
-CONFIG_SND_USB_USX2Y=m
 
 #
 # ALSA Sparc devices
@@ -1636,6 +1658,7 @@
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
 CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_UHCI_HCD=m
+CONFIG_USB_SL811_HCD=m
 
 #
 # USB Device Class drivers
@@ -1685,7 +1708,6 @@
 #
 CONFIG_USB_MDC800=m
 CONFIG_USB_MICROTEK=m
-CONFIG_USB_HPUSBSCSI=m
 
 #
 # USB Multimedia devices
@@ -1754,6 +1776,7 @@
 # CONFIG_USB_SERIAL_IR is not set
 CONFIG_USB_SERIAL_EDGEPORT=m
 # CONFIG_USB_SERIAL_EDGEPORT_TI is not set
+CONFIG_USB_SERIAL_GARMIN=m
 CONFIG_USB_SERIAL_IPW=m
 CONFIG_USB_SERIAL_KEYSPAN_PDA=m
 CONFIG_USB_SERIAL_KEYSPAN=m
@@ -1774,6 +1797,7 @@
 CONFIG_USB_SERIAL_MCT_U232=m
 CONFIG_USB_SERIAL_PL2303=m
 # CONFIG_USB_SERIAL_SAFE is not set
+CONFIG_USB_SERIAL_TI=m
 CONFIG_USB_SERIAL_CYBERJACK=m
 CONFIG_USB_SERIAL_XIRCOM=m
 CONFIG_USB_SERIAL_OMNINET=m
@@ -1784,7 +1808,6 @@
 #
 CONFIG_USB_EMI62=m
 CONFIG_USB_EMI26=m
-# CONFIG_USB_TIGL is not set
 CONFIG_USB_AUERSWALD=m
 CONFIG_USB_RIO500=m
 CONFIG_USB_LEGOTOWER=m
@@ -1793,6 +1816,7 @@
 CONFIG_USB_CYTHERM=m
 CONFIG_USB_PHIDGETKIT=m
 CONFIG_USB_PHIDGETSERVO=m
+CONFIG_USB_IDMOUSE=m
 CONFIG_USB_TEST=m
 
 #
@@ -1807,6 +1831,15 @@
 # CONFIG_USB_GADGET is not set
 
 #
+# InfiniBand support
+#
+CONFIG_INFINIBAND=m
+CONFIG_INFINIBAND_MTHCA=m
+# CONFIG_INFINIBAND_MTHCA_DEBUG is not set
+CONFIG_INFINIBAND_IPOIB=m
+# CONFIG_INFINIBAND_IPOIB_DEBUG is not set
+
+#
 # Watchdog Cards
 #
 CONFIG_WATCHDOG=y
@@ -1847,8 +1880,9 @@
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_KOBJECT is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_INFO is not set
+CONFIG_DEBUG_FS=y
 # CONFIG_DEBUG_STACK_USAGE is not set
 CONFIG_KPROBES=y
 # CONFIG_DEBUG_DCFLUSH is not set
@@ -1890,6 +1924,10 @@
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_CRC32C=m
 CONFIG_CRYPTO_TEST=m
+
+#
+# Hardware crypto devices
+#
 
 #
 # Library routines
diff -Nru a/arch/sparc64/kernel/auxio.c b/arch/sparc64/kernel/auxio.c
--- a/arch/sparc64/kernel/auxio.c	2005-03-01 23:39:07 -08:00
+++ b/arch/sparc64/kernel/auxio.c	2005-03-01 23:39:07 -08:00
@@ -17,7 +17,7 @@
 #include <asm/auxio.h>
 
 /* This cannot be static, as it is referenced in entry.S */
-void __iomem *auxio_register = 0UL;
+void __iomem *auxio_register = NULL;
 
 enum auxio_type {
 	AUXIO_TYPE_NODEV,
@@ -26,7 +26,7 @@
 };
 
 static enum auxio_type auxio_devtype = AUXIO_TYPE_NODEV;
-static spinlock_t auxio_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(auxio_lock);
 
 static void __auxio_sbus_set(u8 bits_on, u8 bits_off)
 {
diff -Nru a/arch/sparc64/kernel/binfmt_aout32.c b/arch/sparc64/kernel/binfmt_aout32.c
--- a/arch/sparc64/kernel/binfmt_aout32.c	2005-03-01 23:38:57 -08:00
+++ b/arch/sparc64/kernel/binfmt_aout32.c	2005-03-01 23:38:57 -08:00
@@ -49,7 +49,9 @@
 	end = PAGE_ALIGN(end);
 	if (end <= start)
 		return;
+	down_write(&current->mm->mmap_sem);
 	do_brk(start, end - start);
+	up_write(&current->mm->mmap_sem);
 }
 
 /*
@@ -95,7 +97,7 @@
 	set_fs(KERNEL_DS);
 	has_dumped = 1;
 	current->flags |= PF_DUMPCORE;
-       	strncpy(dump.u_comm, current->comm, sizeof(current->comm));
+       	strncpy(dump.u_comm, current->comm, sizeof(dump.u_comm));
 	dump.signal = signr;
 	dump_thread(regs, &dump);
 
@@ -246,10 +248,14 @@
 	if (N_MAGIC(ex) == NMAGIC) {
 		loff_t pos = fd_offset;
 		/* Fuck me plenty... */
+		down_write(&current->mm->mmap_sem);	
 		error = do_brk(N_TXTADDR(ex), ex.a_text);
+		up_write(&current->mm->mmap_sem);
 		bprm->file->f_op->read(bprm->file, (char __user *)N_TXTADDR(ex),
 			  ex.a_text, &pos);
+		down_write(&current->mm->mmap_sem);
 		error = do_brk(N_DATADDR(ex), ex.a_data);
+		up_write(&current->mm->mmap_sem);
 		bprm->file->f_op->read(bprm->file, (char __user *)N_DATADDR(ex),
 			  ex.a_data, &pos);
 		goto beyond_if;
@@ -257,8 +263,10 @@
 
 	if (N_MAGIC(ex) == OMAGIC) {
 		loff_t pos = fd_offset;
+		down_write(&current->mm->mmap_sem);
 		do_brk(N_TXTADDR(ex) & PAGE_MASK,
 			ex.a_text+ex.a_data + PAGE_SIZE - 1);
+		up_write(&current->mm->mmap_sem);
 		bprm->file->f_op->read(bprm->file, (char __user *)N_TXTADDR(ex),
 			  ex.a_text+ex.a_data, &pos);
 	} else {
@@ -272,7 +280,9 @@
 
 		if (!bprm->file->f_op->mmap) {
 			loff_t pos = fd_offset;
+			down_write(&current->mm->mmap_sem);
 			do_brk(0, ex.a_text+ex.a_data);
+			up_write(&current->mm->mmap_sem);
 			bprm->file->f_op->read(bprm->file,
 				  (char __user *)N_TXTADDR(ex),
 				  ex.a_text+ex.a_data, &pos);
@@ -311,7 +321,7 @@
 	orig_thr_flags = current_thread_info()->flags;
 	current_thread_info()->flags |= _TIF_32BIT;
 
-	retval = setup_arg_pages(bprm, EXSTACK_DEFAULT);
+	retval = setup_arg_pages(bprm, STACK_TOP, EXSTACK_DEFAULT);
 	if (retval < 0) { 
 		current_thread_info()->flags = orig_thr_flags;
 
@@ -323,9 +333,8 @@
 	current->mm->start_stack =
 		(unsigned long) create_aout32_tables((char __user *)bprm->p, bprm);
 	if (!(orig_thr_flags & _TIF_32BIT)) {
-		unsigned long pgd_cache;
+		unsigned long pgd_cache = get_pgd_cache(current->mm->pgd);
 
-		pgd_cache = ((unsigned long)current->mm->pgd[0])<<11UL;
 		__asm__ __volatile__("stxa\t%0, [%1] %2\n\t"
 				     "membar #Sync"
 				     : /* no outputs */
@@ -389,7 +398,9 @@
 	len = PAGE_ALIGN(ex.a_text + ex.a_data);
 	bss = ex.a_text + ex.a_data + ex.a_bss;
 	if (bss > len) {
+		down_write(&current->mm->mmap_sem);
 		error = do_brk(start_addr + len, bss - len);
+		up_write(&current->mm->mmap_sem);
 		retval = error;
 		if (error != start_addr + len)
 			goto out;
diff -Nru a/arch/sparc64/kernel/binfmt_elf32.c b/arch/sparc64/kernel/binfmt_elf32.c
--- a/arch/sparc64/kernel/binfmt_elf32.c	2005-03-01 23:39:09 -08:00
+++ b/arch/sparc64/kernel/binfmt_elf32.c	2005-03-01 23:39:09 -08:00
@@ -132,10 +132,12 @@
 
 #include <linux/time.h>
 
-#define jiffies_to_timeval jiffies_to_compat_timeval
+#undef cputime_to_timeval
+#define cputime_to_timeval cputime_to_compat_timeval
 static __inline__ void
-jiffies_to_compat_timeval(unsigned long jiffies, struct compat_timeval *value)
+cputime_to_compat_timeval(const cputime_t cputime, struct compat_timeval *value)
 {
+	unsigned long jiffies = cputime_to_jiffies(cputime);
 	value->tv_usec = (jiffies % HZ) * (1000000L / HZ);
 	value->tv_sec = jiffies / HZ;
 }
diff -Nru a/arch/sparc64/kernel/devices.c b/arch/sparc64/kernel/devices.c
--- a/arch/sparc64/kernel/devices.c	2005-03-01 23:38:54 -08:00
+++ b/arch/sparc64/kernel/devices.c	2005-03-01 23:38:54 -08:00
@@ -24,7 +24,7 @@
 /* Used to synchronize acceses to NatSemi SUPER I/O chip configure
  * operations in asm/ns87303.h
  */
-spinlock_t ns87303_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(ns87303_lock);
 
 extern void cpu_probe(void);
 extern void central_probe(void);
diff -Nru a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c
--- a/arch/sparc64/kernel/irq.c	2005-03-01 23:39:16 -08:00
+++ b/arch/sparc64/kernel/irq.c	2005-03-01 23:39:16 -08:00
@@ -101,7 +101,7 @@
  * read things in the table.  IRQ handler processing orders
  * its' accesses such that no locking is needed.
  */
-static spinlock_t irq_action_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(irq_action_lock);
 
 static void register_irq_proc (unsigned int irq);
 
diff -Nru a/arch/sparc64/kernel/kprobes.c b/arch/sparc64/kernel/kprobes.c
--- a/arch/sparc64/kernel/kprobes.c	2005-03-01 23:39:16 -08:00
+++ b/arch/sparc64/kernel/kprobes.c	2005-03-01 23:39:16 -08:00
@@ -40,9 +40,13 @@
 
 int arch_prepare_kprobe(struct kprobe *p)
 {
+	return 0;
+}
+
+void arch_copy_kprobe(struct kprobe *p)
+{
 	p->ainsn.insn[0] = *p->addr;
 	p->ainsn.insn[1] = BREAKPOINT_INSTRUCTION_2;
-	return 0;
 }
 
 void arch_remove_kprobe(struct kprobe *p)
diff -Nru a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c
--- a/arch/sparc64/kernel/pci.c	2005-03-01 23:38:43 -08:00
+++ b/arch/sparc64/kernel/pci.c	2005-03-01 23:38:43 -08:00
@@ -56,7 +56,7 @@
 volatile int pci_poke_cpu = -1;
 volatile int pci_poke_faulted;
 
-static spinlock_t pci_poke_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(pci_poke_lock);
 
 void pci_config_read8(u8 *addr, u8 *ret)
 {
diff -Nru a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c
--- a/arch/sparc64/kernel/pci_psycho.c	2005-03-01 23:38:58 -08:00
+++ b/arch/sparc64/kernel/pci_psycho.c	2005-03-01 23:38:58 -08:00
@@ -433,7 +433,7 @@
 #define  PSYCHO_STCLINE_VALID	 0x0000000000000002UL	/* Valid */
 #define  PSYCHO_STCLINE_FOFN	 0x0000000000000001UL	/* Fetch Outstanding / Flush Necessary */
 
-static spinlock_t stc_buf_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(stc_buf_lock);
 static unsigned long stc_error_buf[128];
 static unsigned long stc_tag_buf[16];
 static unsigned long stc_line_buf[16];
@@ -453,9 +453,9 @@
 		tag_base = regbase + PSYCHO_STC_TAG_A;
 		line_base = regbase + PSYCHO_STC_LINE_A;
 	} else {
-		err_base = regbase + PSYCHO_STC_ERR_A;
-		tag_base = regbase + PSYCHO_STC_TAG_A;
-		line_base = regbase + PSYCHO_STC_LINE_A;
+		err_base = regbase + PSYCHO_STC_ERR_B;
+		tag_base = regbase + PSYCHO_STC_TAG_B;
+		line_base = regbase + PSYCHO_STC_LINE_B;
 	}
 
 	spin_lock(&stc_buf_lock);
diff -Nru a/arch/sparc64/kernel/pci_schizo.c b/arch/sparc64/kernel/pci_schizo.c
--- a/arch/sparc64/kernel/pci_schizo.c	2005-03-01 23:39:07 -08:00
+++ b/arch/sparc64/kernel/pci_schizo.c	2005-03-01 23:39:07 -08:00
@@ -377,7 +377,7 @@
 	UE_ERR, CE_ERR, PCI_ERR, SAFARI_ERR
 };
 
-static spinlock_t stc_buf_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(stc_buf_lock);
 static unsigned long stc_error_buf[128];
 static unsigned long stc_tag_buf[16];
 static unsigned long stc_line_buf[16];
diff -Nru a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c
--- a/arch/sparc64/kernel/process.c	2005-03-01 23:38:56 -08:00
+++ b/arch/sparc64/kernel/process.c	2005-03-01 23:38:56 -08:00
@@ -60,10 +60,10 @@
 /*
  * the idle loop on a Sparc... ;)
  */
-int cpu_idle(void)
+void cpu_idle(void)
 {
 	if (current->pid != 0)
-		return -EPERM;
+		return;
 
 	/* endless idle loop with no priority at all */
 	for (;;) {
@@ -80,7 +80,7 @@
 		schedule();
 		check_pgt_cache();
 	}
-	return 0;
+	return;
 }
 
 #else
@@ -90,7 +90,7 @@
  */
 #define idle_me_harder()	(cpu_data(smp_processor_id()).idle_volume += 1)
 #define unidle_me()		(cpu_data(smp_processor_id()).idle_volume = 0)
-int cpu_idle(void)
+void cpu_idle(void)
 {
 	set_thread_flag(TIF_POLLING_NRFLAG);
 	while(1) {
@@ -167,7 +167,7 @@
 	mm_segment_t old_fs;
 	
 	__asm__ __volatile__ ("flushw");
-	rw = (struct reg_window32 __user *)((long)(unsigned)regs->u_regs[14]);
+	rw = compat_ptr((unsigned)regs->u_regs[14]);
 	old_fs = get_fs();
 	set_fs (USER_DS);
 	if (copy_from_user (&r_w, rw, sizeof(r_w))) {
@@ -282,7 +282,7 @@
 }
 
 #ifdef CONFIG_SMP
-static spinlock_t regdump_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(regdump_lock);
 #endif
 
 void __show_regs(struct pt_regs * regs)
@@ -434,14 +434,13 @@
 		if (test_thread_flag(TIF_32BIT)) {
 			struct mm_struct *mm = t->task->mm;
 			pgd_t *pgd0 = &mm->pgd[0];
+			pud_t *pud0 = pud_offset(pgd0, 0);
 
-			if (pgd_none(*pgd0)) {
-				pmd_t *page = pmd_alloc_one_fast(NULL, 0);
-				if (!page)
-					page = pmd_alloc_one(NULL, 0);
-				pgd_set(pgd0, page);
+			if (pud_none(*pud0)) {
+				pmd_t *page = pmd_alloc_one(mm, 0);
+				pud_set(pud0, page);
 			}
-			pgd_cache = ((unsigned long) pgd_val(*pgd0)) << 11UL;
+			pgd_cache = get_pgd_cache(pgd0);
 		}
 		__asm__ __volatile__("stxa %0, [%1] %2\n\t"
 				     "membar #Sync"
diff -Nru a/arch/sparc64/kernel/ptrace.c b/arch/sparc64/kernel/ptrace.c
--- a/arch/sparc64/kernel/ptrace.c	2005-03-01 23:39:17 -08:00
+++ b/arch/sparc64/kernel/ptrace.c	2005-03-01 23:39:17 -08:00
@@ -50,7 +50,7 @@
 }
 
 static inline void
-pt_succ_return_linux(struct pt_regs *regs, unsigned long value, long *addr)
+pt_succ_return_linux(struct pt_regs *regs, unsigned long value, void __user *addr)
 {
 	if (test_thread_flag(TIF_32BIT)) {
 		if (put_user(value, (unsigned int __user *) addr)) {
@@ -70,7 +70,7 @@
 }
 
 static void
-pt_os_succ_return (struct pt_regs *regs, unsigned long val, long *addr)
+pt_os_succ_return (struct pt_regs *regs, unsigned long val, void __user *addr)
 {
 	if (current->personality == PER_SUNOS)
 		pt_succ_return (regs, val);
@@ -226,7 +226,7 @@
 		if (res < 0)
 			pt_error_return(regs, -res);
 		else
-			pt_os_succ_return(regs, tmp64, (long *) data);
+			pt_os_succ_return(regs, tmp64, (void __user *) data);
 		goto flush_and_out;
 	}
 
diff -Nru a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c
--- a/arch/sparc64/kernel/setup.c	2005-03-01 23:38:55 -08:00
+++ b/arch/sparc64/kernel/setup.c	2005-03-01 23:38:55 -08:00
@@ -151,6 +151,7 @@
 			struct task_struct *p;
 			struct mm_struct *mm = NULL;
 			pgd_t *pgdp;
+			pud_t *pudp;
 			pmd_t *pmdp;
 			pte_t *ptep;
 
@@ -166,7 +167,10 @@
 			pgdp = pgd_offset(mm, va);
 			if (pgd_none(*pgdp))
 				goto done;
-			pmdp = pmd_offset(pgdp, va);
+			pudp = pud_offset(pgdp, va);
+			if (pud_none(*pudp))
+				goto done;
+			pmdp = pmd_offset(pudp, va);
 			if (pmd_none(*pmdp))
 				goto done;
 
@@ -208,6 +212,7 @@
 			 * vmalloc or prom_inherited mapping.
 			 */
 			pgd_t *pgdp;
+			pud_t *pudp;
 			pmd_t *pmdp;
 			pte_t *ptep;
 			int error;
@@ -221,7 +226,10 @@
 			pgdp = pgd_offset_k(va);
 			if (pgd_none(*pgdp))
 				goto done;
-			pmdp = pmd_offset(pgdp, va);
+			pudp = pud_offset(pgdp, va);
+			if (pud_none(*pudp))
+				goto done;
+			pmdp = pmd_offset(pudp, va);
 			if (pmd_none(*pmdp))
 				goto done;
 
diff -Nru a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c
--- a/arch/sparc64/kernel/signal32.c	2005-03-01 23:38:44 -08:00
+++ b/arch/sparc64/kernel/signal32.c	2005-03-01 23:38:44 -08:00
@@ -86,7 +86,7 @@
 	__siginfo_fpu_t		fpu_state;
 };
 
-struct siginfo32 {
+typedef struct compat_siginfo{
 	int si_signo;
 	int si_errno;
 	int si_code;
@@ -136,11 +136,11 @@
 			int _fd;
 		} _sigpoll;
 	} _sifields;
-};
+}compat_siginfo_t;
 
 struct rt_signal_frame32 {
 	struct sparc_stackf32	ss;
-	struct siginfo32	info;
+	compat_siginfo_t	info;
 	struct pt_regs32	regs;
 	compat_sigset_t		mask;
 	/* __siginfo_fpu32_t * */ u32 fpu_save;
@@ -157,11 +157,11 @@
 #define NF_ALIGNEDSZ  (((sizeof(struct new_signal_frame32) + 7) & (~7)))
 #define RT_ALIGNEDSZ  (((sizeof(struct rt_signal_frame32) + 7) & (~7)))
 
-int copy_siginfo_to_user32(struct siginfo32 __user *to, siginfo_t *from)
+int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
 {
 	int err;
 
-	if (!access_ok(VERIFY_WRITE, to, sizeof(struct siginfo32)))
+	if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
 		return -EFAULT;
 
 	/* If you change siginfo_t structure, please be sure
@@ -194,7 +194,7 @@
 		case __SI_FAULT >> 16:
 		case __SI_POLL >> 16:
 			err |= __put_user(from->si_trapno, &to->si_trapno);
-			err |= __put_user((long)from->si_addr, &to->si_addr);
+			err |= __put_user((unsigned long)from->si_addr, &to->si_addr);
 			break;
 		case __SI_RT >> 16: /* This is not generated by the kernel as of now.  */
 		case __SI_MESGQ >> 16:
@@ -210,9 +210,9 @@
 /* CAUTION: This is just a very minimalist implementation for the
  *          sake of compat_sys_rt_sigqueueinfo()
  */
-int copy_siginfo_to_kernel32(siginfo_t *to, struct siginfo32 __user *from)
+int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
 {
-	if (!access_ok(VERIFY_WRITE, from, sizeof(struct siginfo32)))
+	if (!access_ok(VERIFY_WRITE, from, sizeof(compat_siginfo_t)))
 		return -EFAULT;
 
 	if (copy_from_user(to, from, 3*sizeof(int)) ||
@@ -275,7 +275,7 @@
 		regs->u_regs[UREG_I0] = EINVAL;
 		return;
 	}
-	if (copy_from_user(&set32, (void __user *)(long)uset, sizeof(set32))) {
+	if (copy_from_user(&set32, compat_ptr(uset), sizeof(set32))) {
 		regs->tstate |= TSTATE_ICARRY;
 		regs->u_regs[UREG_I0] = EFAULT;
 		return;
@@ -720,9 +720,9 @@
 			sig_address = NULL;
 		}
 	}
-	err |= __put_user((long)sig_address, &sframep->sig_address);
+	err |= __put_user(ptr_to_compat(sig_address), &sframep->sig_address);
 	err |= __put_user(sig_code, &sframep->sig_code);
-	err |= __put_user((u64)sc, &sframep->sig_scptr);
+	err |= __put_user(ptr_to_compat(sc), &sframep->sig_scptr);
 	if (err)
 		goto sigsegv;
 
@@ -857,7 +857,8 @@
 		/* Flush instruction space. */
 		unsigned long address = ((unsigned long)&(sf->insns[0]));
 		pgd_t *pgdp = pgd_offset(current->mm, address);
-		pmd_t *pmdp = pmd_offset(pgdp, address);
+		pud_t *pudp = pud_offset(pgdp, address);
+		pmd_t *pmdp = pmd_offset(pudp, address);
 		pte_t *ptep;
 
 		regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2);
@@ -967,7 +968,7 @@
 	/* Save the currently window file: */
 
 	/* 1. Link sfp->uc->gwins to our windows */
-	err |= __put_user((u32)(long)gw, &mc->gwin);
+	err |= __put_user(ptr_to_compat(gw), &mc->gwin);
 	    
 	/* 2. Number of windows to restore at setcontext (): */
 	err |= __put_user(get_thread_wsaved(), &gw->count);
@@ -1268,7 +1269,8 @@
 		/* Flush instruction space. */
 		unsigned long address = ((unsigned long)&(sf->insns[0]));
 		pgd_t *pgdp = pgd_offset(current->mm, address);
-		pmd_t *pmdp = pmd_offset(pgdp, address);
+		pud_t *pudp = pud_offset(pgdp, address);
+		pmd_t *pmdp = pmd_offset(pudp, address);
 		pte_t *ptep;
 
 		regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2);
@@ -1446,10 +1448,12 @@
 	u32 u_ss_sp = 0;
 	int ret;
 	mm_segment_t old_fs;
+	stack_t32 __user *uss32 = compat_ptr(ussa);
+	stack_t32 __user *uoss32 = compat_ptr(uossa);
 	
-	if (ussa && (get_user(u_ss_sp, &((stack_t32 __user *)(long)ussa)->ss_sp) ||
-		    __get_user(uss.ss_flags, &((stack_t32 __user *)(long)ussa)->ss_flags) ||
-		    __get_user(uss.ss_size, &((stack_t32 __user *)(long)ussa)->ss_size)))
+	if (ussa && (get_user(u_ss_sp, &uss32->ss_sp) ||
+		    __get_user(uss.ss_flags, &uss32->ss_flags) ||
+		    __get_user(uss.ss_size, &uss32->ss_size)))
 		return -EFAULT;
 	uss.ss_sp = compat_ptr(u_ss_sp);
 	old_fs = get_fs();
@@ -1457,9 +1461,9 @@
 	ret = do_sigaltstack(ussa ? (stack_t __user *) &uss : NULL,
 			     uossa ? (stack_t __user *) &uoss : NULL, sp);
 	set_fs(old_fs);
-	if (!ret && uossa && (put_user((long)uoss.ss_sp, &((stack_t32 __user *)(long)uossa)->ss_sp) ||
-		    __put_user(uoss.ss_flags, &((stack_t32 __user *)(long)uossa)->ss_flags) ||
-		    __put_user(uoss.ss_size, &((stack_t32 __user *)(long)uossa)->ss_size)))
+	if (!ret && uossa && (put_user(ptr_to_compat(uoss.ss_sp), &uoss32->ss_sp) ||
+		    __put_user(uoss.ss_flags, &uoss32->ss_flags) ||
+		    __put_user(uoss.ss_size, &uoss32->ss_size)))
 		return -EFAULT;
 	return ret;
 }
diff -Nru a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c
--- a/arch/sparc64/kernel/smp.c	2005-03-01 23:38:44 -08:00
+++ b/arch/sparc64/kernel/smp.c	2005-03-01 23:38:44 -08:00
@@ -154,7 +154,7 @@
 #define NUM_ROUNDS	64	/* magic value */
 #define NUM_ITERS	5	/* likewise */
 
-static spinlock_t itc_sync_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(itc_sync_lock);
 static unsigned long go[SLAVE + 1];
 
 #define DEBUG_TICK_SYNC	0
@@ -546,7 +546,7 @@
 	int wait;
 };
 
-static spinlock_t call_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(call_lock);
 static struct call_data_struct *call_data;
 
 extern unsigned long xcall_call_function;
@@ -894,9 +894,8 @@
 
 void smp_capture(void)
 {
-	int result = __atomic_add(1, &smp_capture_depth);
+	int result = atomic_add_ret(1, &smp_capture_depth);
 
-	membar("#StoreStore | #LoadStore");
 	if (result == 1) {
 		int ncpus = num_online_cpus();
 
@@ -1146,7 +1145,7 @@
 }
 
 /* /proc/profile writes can call this, don't __init it please. */
-static spinlock_t prof_setup_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(prof_setup_lock);
 
 int setup_profiling_timer(unsigned int multiplier)
 {
diff -Nru a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c
--- a/arch/sparc64/kernel/sparc64_ksyms.c	2005-03-01 23:39:09 -08:00
+++ b/arch/sparc64/kernel/sparc64_ksyms.c	2005-03-01 23:39:09 -08:00
@@ -86,7 +86,7 @@
 extern int svr4_setcontext(svr4_ucontext_t *uc, struct pt_regs *regs);
 extern int compat_sys_ioctl(unsigned int fd, unsigned int cmd, u32 arg);
 extern int (*handle_mathemu)(struct pt_regs *, struct fpustate *);
-extern long sparc32_open(const char * filename, int flags, int mode);
+extern long sparc32_open(const char __user * filename, int flags, int mode);
 extern int io_remap_page_range(struct vm_area_struct *vma, unsigned long from, unsigned long offset, unsigned long size, pgprot_t prot, int space);
 extern void (*prom_palette)(int);
 
@@ -172,18 +172,25 @@
 EXPORT_SYMBOL(up);
 
 /* Atomic counter implementation. */
-EXPORT_SYMBOL(__atomic_add);
-EXPORT_SYMBOL(__atomic_sub);
-EXPORT_SYMBOL(__atomic64_add);
-EXPORT_SYMBOL(__atomic64_sub);
+EXPORT_SYMBOL(atomic_add);
+EXPORT_SYMBOL(atomic_add_ret);
+EXPORT_SYMBOL(atomic_sub);
+EXPORT_SYMBOL(atomic_sub_ret);
+EXPORT_SYMBOL(atomic64_add);
+EXPORT_SYMBOL(atomic64_add_ret);
+EXPORT_SYMBOL(atomic64_sub);
+EXPORT_SYMBOL(atomic64_sub_ret);
 #ifdef CONFIG_SMP
 EXPORT_SYMBOL(_atomic_dec_and_lock);
 #endif
 
 /* Atomic bit operations. */
-EXPORT_SYMBOL(___test_and_set_bit);
-EXPORT_SYMBOL(___test_and_clear_bit);
-EXPORT_SYMBOL(___test_and_change_bit);
+EXPORT_SYMBOL(test_and_set_bit);
+EXPORT_SYMBOL(test_and_clear_bit);
+EXPORT_SYMBOL(test_and_change_bit);
+EXPORT_SYMBOL(set_bit);
+EXPORT_SYMBOL(clear_bit);
+EXPORT_SYMBOL(change_bit);
 
 /* Bit searching */
 EXPORT_SYMBOL(find_next_bit);
diff -Nru a/arch/sparc64/kernel/sys_sparc.c b/arch/sparc64/kernel/sys_sparc.c
--- a/arch/sparc64/kernel/sys_sparc.c	2005-03-01 23:38:58 -08:00
+++ b/arch/sparc64/kernel/sys_sparc.c	2005-03-01 23:38:58 -08:00
@@ -199,7 +199,8 @@
  * This is really horribly ugly.
  */
 
-asmlinkage long sys_ipc(unsigned int call, int first, int second, unsigned long third, void __user *ptr, long fifth)
+asmlinkage long sys_ipc(unsigned int call, int first, unsigned long second,
+			unsigned long third, void __user *ptr, long fifth)
 {
 	int err;
 
@@ -207,14 +208,15 @@
 	if (call <= SEMCTL) {
 		switch (call) {
 		case SEMOP:
-			err = sys_semtimedop(first, ptr, second, NULL);
+			err = sys_semtimedop(first, ptr,
+					     (unsigned)second, NULL);
 			goto out;
 		case SEMTIMEDOP:
-			err = sys_semtimedop(first, ptr, second,
+			err = sys_semtimedop(first, ptr, (unsigned)second,
 				(const struct timespec __user *) fifth);
 			goto out;
 		case SEMGET:
-			err = sys_semget(first, second, (int)third);
+			err = sys_semget(first, (int)second, (int)third);
 			goto out;
 		case SEMCTL: {
 			union semun fourth;
@@ -225,7 +227,7 @@
 			if (get_user(fourth.__pad,
 				     (void __user * __user *) ptr))
 				goto out;
-			err = sys_semctl(first, second | IPC_64,
+			err = sys_semctl(first, (int)second | IPC_64,
 					 (int)third, fourth);
 			goto out;
 		}
@@ -237,17 +239,18 @@
 	if (call <= MSGCTL) {
 		switch (call) {
 		case MSGSND:
-			err = sys_msgsnd(first, ptr, second, (int)third);
+			err = sys_msgsnd(first, ptr, (size_t)second,
+					 (int)third);
 			goto out;
 		case MSGRCV:
-			err = sys_msgrcv(first, ptr, second, fifth,
+			err = sys_msgrcv(first, ptr, (size_t)second, fifth,
 					 (int)third);
 			goto out;
 		case MSGGET:
-			err = sys_msgget((key_t) first, second);
+			err = sys_msgget((key_t)first, (int)second);
 			goto out;
 		case MSGCTL:
-			err = sys_msgctl(first, second | IPC_64, ptr);
+			err = sys_msgctl(first, (int)second | IPC_64, ptr);
 			goto out;
 		default:
 			err = -ENOSYS;
@@ -258,7 +261,7 @@
 		switch (call) {
 		case SHMAT: {
 			ulong raddr;
-			err = do_shmat(first, ptr, second, &raddr);
+			err = do_shmat(first, ptr, (int)second, &raddr);
 			if (!err) {
 				if (put_user(raddr,
 					     (ulong __user *) third))
@@ -270,10 +273,10 @@
 			err = sys_shmdt(ptr);
 			goto out;
 		case SHMGET:
-			err = sys_shmget(first, second, (int)third);
+			err = sys_shmget(first, (size_t)second, (int)third);
 			goto out;
 		case SHMCTL:
-			err = sys_shmctl(first, second | IPC_64, ptr);
+			err = sys_shmctl(first, (int)second | IPC_64, ptr);
 			goto out;
 		default:
 			err = -ENOSYS;
diff -Nru a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c
--- a/arch/sparc64/kernel/sys_sparc32.c	2005-03-01 23:39:07 -08:00
+++ b/arch/sparc64/kernel/sys_sparc32.c	2005-03-01 23:39:07 -08:00
@@ -242,7 +242,7 @@
 
 static long get_tv32(struct timeval *o, struct compat_timeval __user *i)
 {
-	return (!access_ok(VERIFY_READ, tv32, sizeof(*tv32)) ||
+	return (!access_ok(VERIFY_READ, i, sizeof(*i)) ||
 		(__get_user(o->tv_sec, &i->tv_sec) |
 		 __get_user(o->tv_usec, &i->tv_usec)));
 }
@@ -254,602 +254,70 @@
 		 __put_user(i->tv_usec, &o->tv_usec)));
 }
 
-struct msgbuf32 { s32 mtype; char mtext[1]; };
-
-struct ipc_perm32 {
-	key_t    	  key;
-        compat_uid_t  uid;
-        compat_gid_t  gid;
-        compat_uid_t  cuid;
-        compat_gid_t  cgid;
-        compat_mode_t mode;
-        unsigned short  seq;
-};
-
-struct semid_ds32 {
-        struct ipc_perm32 sem_perm;               /* permissions .. see ipc.h */
-        compat_time_t   sem_otime;              /* last semop time */
-        compat_time_t   sem_ctime;              /* last change time */
-        u32 sem_base;              /* ptr to first semaphore in array */
-        u32 sem_pending;          /* pending operations to be processed */
-        u32 sem_pending_last;    /* last pending operation */
-        u32 undo;                  /* undo requests on this array */
-        unsigned short  sem_nsems;              /* no. of semaphores in array */
-};
-
-struct semid64_ds32 {
-	struct ipc64_perm sem_perm;		  /* this structure is the same on sparc32 and sparc64 */
-	unsigned int	  __pad1;
-	compat_time_t   sem_otime;
-	unsigned int	  __pad2;
-	compat_time_t   sem_ctime;
-	u32 sem_nsems;
-	u32 __unused1;
-	u32 __unused2;
-};
-
-struct msqid_ds32
-{
-        struct ipc_perm32 msg_perm;
-        u32 msg_first;
-        u32 msg_last;
-        compat_time_t   msg_stime;
-        compat_time_t   msg_rtime;
-        compat_time_t   msg_ctime;
-        u32 wwait;
-        u32 rwait;
-        unsigned short msg_cbytes;
-        unsigned short msg_qnum;  
-        unsigned short msg_qbytes;
-        compat_ipc_pid_t msg_lspid;
-        compat_ipc_pid_t msg_lrpid;
-};
-
-struct msqid64_ds32 {
-	struct ipc64_perm msg_perm;
-	unsigned int   __pad1;
-	compat_time_t   msg_stime;
-	unsigned int   __pad2;
-	compat_time_t   msg_rtime;
-	unsigned int   __pad3;
-	compat_time_t   msg_ctime;
-	unsigned int  msg_cbytes;
-	unsigned int  msg_qnum;
-	unsigned int  msg_qbytes;
-	compat_pid_t msg_lspid;
-	compat_pid_t msg_lrpid;
-	unsigned int  __unused1;
-	unsigned int  __unused2;
-};
-
-
-struct shmid_ds32 {
-	struct ipc_perm32       shm_perm;
-	int                     shm_segsz;
-	compat_time_t         shm_atime;
-	compat_time_t         shm_dtime;
-	compat_time_t         shm_ctime;
-	compat_ipc_pid_t    shm_cpid; 
-	compat_ipc_pid_t    shm_lpid; 
-	unsigned short          shm_nattch;
-};
-
-struct shmid64_ds32 {
-	struct ipc64_perm	shm_perm;
-	unsigned int		__pad1;
-	compat_time_t  	shm_atime;
-	unsigned int		__pad2;
-	compat_time_t  	shm_dtime;
-	unsigned int		__pad3;
-	compat_time_t  	shm_ctime;
-	compat_size_t	shm_segsz;
-	compat_pid_t	shm_cpid;
-	compat_pid_t	shm_lpid;
-	unsigned int		shm_nattch;
-	unsigned int		__unused1;
-	unsigned int		__unused2;
-};
-
-                                                        
-/*
- * sys32_ipc() is the de-multiplexer for the SysV IPC calls in 32bit emulation..
- *
- * This is really horribly ugly.
- */
-#define IPCOP_MASK(__x)	(1UL << ((__x)&~IPC_64))
-static int do_sys32_semctl(int first, int second, int third,
-			   compat_uptr_t __user *uptr)
-{
-	union semun fourth;
-	compat_uptr_t pad;
-	int err = -EINVAL;
-
-	if (!uptr)
-		goto out;
-	err = -EFAULT;
-	if (get_user(pad, uptr))
-		goto out;
-	if ((third & ~IPC_64) == SETVAL)
-		fourth.val = (int)pad;
-	else
-		fourth.__pad = compat_ptr(pad);
-	if (IPCOP_MASK (third) &
-	    (IPCOP_MASK (IPC_INFO) | IPCOP_MASK (SEM_INFO) | IPCOP_MASK (GETVAL) |
-	     IPCOP_MASK (GETPID) | IPCOP_MASK (GETNCNT) | IPCOP_MASK (GETZCNT) |
-	     IPCOP_MASK (GETALL) | IPCOP_MASK (SETALL) | IPCOP_MASK (IPC_RMID))) {
-		err = sys_semctl (first, second, third, fourth);
-	} else if (third & IPC_64) {
-		struct semid64_ds s;
-		struct semid64_ds32 __user *usp = compat_ptr(pad);
-		mm_segment_t old_fs;
-		int need_back_translation;
-
-		if (third == (IPC_SET|IPC_64)) {
-			err = get_user (s.sem_perm.uid, &usp->sem_perm.uid);
-			err |= __get_user (s.sem_perm.gid, &usp->sem_perm.gid);
-			err |= __get_user (s.sem_perm.mode, &usp->sem_perm.mode);
-			if (err)
-				goto out;
-			fourth.__pad = (void __user *) &s;
-		}
-		need_back_translation =
-			(IPCOP_MASK (third) &
-			 (IPCOP_MASK (SEM_STAT) | IPCOP_MASK (IPC_STAT))) != 0;
-		if (need_back_translation)
-			fourth.__pad = (void __user *) &s;
-		old_fs = get_fs ();
-		set_fs (KERNEL_DS);
-		err = sys_semctl (first, second, third, fourth);
-		set_fs (old_fs);
-		if (need_back_translation) {
-			int err2 = copy_to_user (&usp->sem_perm, &s.sem_perm, sizeof(struct ipc64_perm) + 2*sizeof(time_t));
-			err2 |= __put_user (s.sem_nsems, &usp->sem_nsems);
-			if (err2) err = -EFAULT;
-		}
-	} else {
-		struct semid_ds s;
-		struct semid_ds32 __user *usp = compat_ptr(pad);
-		mm_segment_t old_fs;
-		int need_back_translation;
-
-		if (third == IPC_SET) {
-			err = get_user (s.sem_perm.uid, &usp->sem_perm.uid);
-			err |= __get_user (s.sem_perm.gid, &usp->sem_perm.gid);
-			err |= __get_user (s.sem_perm.mode, &usp->sem_perm.mode);
-			if (err)
-				goto out;
-			fourth.__pad = (void __user *) &s;
-		}
-		need_back_translation =
-			(IPCOP_MASK (third) &
-			 (IPCOP_MASK (SEM_STAT) | IPCOP_MASK (IPC_STAT))) != 0;
-		if (need_back_translation)
-			fourth.__pad = (void __user *) &s;
-		old_fs = get_fs ();
-		set_fs (KERNEL_DS);
-		err = sys_semctl (first, second, third, fourth);
-		set_fs (old_fs);
-		if (need_back_translation) {
-			int err2 = put_user (s.sem_perm.key, &usp->sem_perm.key);
-			err2 |= __put_user (high2lowuid(s.sem_perm.uid), &usp->sem_perm.uid);
-			err2 |= __put_user (high2lowgid(s.sem_perm.gid), &usp->sem_perm.gid);
-			err2 |= __put_user (high2lowuid(s.sem_perm.cuid), &usp->sem_perm.cuid);
-			err2 |= __put_user (high2lowgid(s.sem_perm.cgid), &usp->sem_perm.cgid);
-			err2 |= __put_user (s.sem_perm.mode, &usp->sem_perm.mode);
-			err2 |= __put_user (s.sem_perm.seq, &usp->sem_perm.seq);
-			err2 |= __put_user (s.sem_otime, &usp->sem_otime);
-			err2 |= __put_user (s.sem_ctime, &usp->sem_ctime);
-			err2 |= __put_user (s.sem_nsems, &usp->sem_nsems);
-			if (err2) err = -EFAULT;
-		}
-	}
-out:
-	return err;
-}
-
-static int do_sys32_msgsnd(int first, int second, int third,
-			   void __user *uptr)
-{
-	struct msgbuf32 __user *up = uptr;
-	struct msgbuf *p;
-	mm_segment_t old_fs;
-	int err;
-
-	p = kmalloc(second + sizeof (struct msgbuf), GFP_USER);
-	if (!p)
-		return -ENOMEM;
-	err = -EFAULT;
-	if (get_user (p->mtype, &up->mtype) ||
-	    __copy_from_user (p->mtext, &up->mtext, second))
-		goto out;
-	old_fs = get_fs ();
-	set_fs (KERNEL_DS);
-	err = sys_msgsnd (first, (struct msgbuf __user *) p,
-			  second, third);
-	set_fs (old_fs);
-out:
-	kfree (p);
-	return err;
-}
-
-static int do_sys32_msgrcv(int first, int second, int msgtyp, int third,
-			   int version, void __user *uptr)
-{
-	struct msgbuf32 __user *up;
-	struct msgbuf *p;
-	mm_segment_t old_fs;
-	int err;
-
-	if (!version) {
-		struct ipc_kludge __user *uipck = uptr;
-		struct ipc_kludge ipck;
-
-		err = -EINVAL;
-		if (!uptr)
-			goto out;
-		err = -EFAULT;
-		if (copy_from_user (&ipck, uipck,
-				    sizeof (struct ipc_kludge)))
-			goto out;
-		uptr = compat_ptr(ipck.msgp);
-		msgtyp = ipck.msgtyp;
-	}
-	err = -ENOMEM;
-	p = kmalloc(second + sizeof (struct msgbuf), GFP_USER);
-	if (!p)
-		goto out;
-	old_fs = get_fs ();
-	set_fs (KERNEL_DS);
-	err = sys_msgrcv (first, (struct msgbuf __user *) p, second,
-			  msgtyp, third);
-	set_fs (old_fs);
-	if (err < 0)
-		goto free_then_out;
-	up = uptr;
-	if (put_user (p->mtype, &up->mtype) ||
-	    __copy_to_user (&up->mtext, p->mtext, err))
-		err = -EFAULT;
-free_then_out:
-	kfree (p);
-out:
-	return err;
-}
-
-static int do_sys32_msgctl(int first, int second, void __user *uptr)
-{
-	int err;
-
-	if (IPCOP_MASK (second) &
-	    (IPCOP_MASK (IPC_INFO) | IPCOP_MASK (MSG_INFO) |
-	     IPCOP_MASK (IPC_RMID))) {
-		err = sys_msgctl (first, second, uptr);
-	} else if (second & IPC_64) {
-		struct msqid64_ds m;
-		struct msqid64_ds32 __user *up = uptr;
-		mm_segment_t old_fs;
-
-		if (second == (IPC_SET|IPC_64)) {
-			err = get_user (m.msg_perm.uid,
-					&up->msg_perm.uid);
-			err |= __get_user (m.msg_perm.gid,
-					   &up->msg_perm.gid);
-			err |= __get_user (m.msg_perm.mode,
-					   &up->msg_perm.mode);
-			err |= __get_user (m.msg_qbytes,
-					   &up->msg_qbytes);
-			if (err)
-				goto out;
-		}
-		old_fs = get_fs ();
-		set_fs (KERNEL_DS);
-		err = sys_msgctl(first, second,
-				 (struct msqid_ds __user *)&m);
-		set_fs (old_fs);
-		if (IPCOP_MASK (second) &
-		    (IPCOP_MASK (MSG_STAT) | IPCOP_MASK (IPC_STAT))) {
-			int err2 = copy_to_user(&up->msg_perm,
-						&m.msg_perm,
-						(sizeof(struct ipc64_perm) + 3*sizeof(time_t)));
-			err2 |= __put_user (m.msg_cbytes,
-					    &up->msg_cbytes);
-			err2 |= __put_user (m.msg_qnum, &up->msg_qnum);
-			err2 |= __put_user (m.msg_qbytes,
-					    &up->msg_qbytes);
-			err2 |= __put_user (m.msg_lspid, &up->msg_lspid);
-			err2 |= __put_user (m.msg_lrpid, &up->msg_lrpid);
-			if (err2)
-				err = -EFAULT;
-		}
-	} else {
-		struct msqid_ds m;
-		struct msqid_ds32 __user *up = uptr;
-		mm_segment_t old_fs;
-
-		if (second == IPC_SET) {
-			err = get_user(m.msg_perm.uid,
-				       &up->msg_perm.uid);
-			err |= __get_user(m.msg_perm.gid,
-					  &up->msg_perm.gid);
-			err |= __get_user(m.msg_perm.mode,
-					  &up->msg_perm.mode);
-			err |= __get_user(m.msg_qbytes,
-					  &up->msg_qbytes);
-			if (err)
-				goto out;
-		}
-		old_fs = get_fs ();
-		set_fs (KERNEL_DS);
-		err = sys_msgctl(first, second,
-				 (struct msqid_ds __user *) &m);
-		set_fs (old_fs);
-		if (IPCOP_MASK (second) &
-		    (IPCOP_MASK (MSG_STAT) | IPCOP_MASK (IPC_STAT))) {
-			int err2 = put_user(m.msg_perm.key,
-					    &up->msg_perm.key);
-			err2 |= __put_user(high2lowuid(m.msg_perm.uid),
-					   &up->msg_perm.uid);
-			err2 |= __put_user(high2lowgid(m.msg_perm.gid),
-					   &up->msg_perm.gid);
-			err2 |= __put_user(high2lowuid(m.msg_perm.cuid),
-					   &up->msg_perm.cuid);
-			err2 |= __put_user(high2lowgid(m.msg_perm.cgid),
-					   &up->msg_perm.cgid);
-			err2 |= __put_user(m.msg_perm.mode,
-					   &up->msg_perm.mode);
-			err2 |= __put_user(m.msg_perm.seq,
-					   &up->msg_perm.seq);
-			err2 |= __put_user(m.msg_stime, &up->msg_stime);
-			err2 |= __put_user(m.msg_rtime, &up->msg_rtime);
-			err2 |= __put_user(m.msg_ctime, &up->msg_ctime);
-			err2 |= __put_user(m.msg_cbytes,
-					   &up->msg_cbytes);
-			err2 |= __put_user(m.msg_qnum, &up->msg_qnum);
-			err2 |= __put_user(m.msg_qbytes,
-					   &up->msg_qbytes);
-			err2 |= __put_user(m.msg_lspid, &up->msg_lspid);
-			err2 |= __put_user(m.msg_lrpid, &up->msg_lrpid);
-			if (err2)
-				err = -EFAULT;
-		}
-	}
-
-out:
-	return err;
-}
-
-static int do_sys32_shmat (int first, int second, int third, int version, void __user *uptr)
-{
-	unsigned long raddr;
-	u32 __user *uaddr = compat_ptr((compat_uptr_t)third);
-	int err = -EINVAL;
-
-	if (version == 1)
-		goto out;
-	err = do_shmat (first, uptr, second, &raddr);
-	if (err)
-		goto out;
-	err = put_user (raddr, uaddr);
-out:
-	return err;
-}
-
-static int do_sys32_shmctl(int first, int second, void __user *uptr)
-{
-	int err;
-
-	if (IPCOP_MASK (second) &
-	    (IPCOP_MASK (IPC_INFO) | IPCOP_MASK (SHM_LOCK) |
-	     IPCOP_MASK (SHM_UNLOCK) | IPCOP_MASK (IPC_RMID))) {
-		if (second == (IPC_INFO|IPC_64)) {
-			/* So that we don't have to translate it */
-			second = IPC_INFO;
-		}
-		err = sys_shmctl(first, second, uptr);
-	} else if ((second & IPC_64) && second != (SHM_INFO|IPC_64)) {
-		struct shmid64_ds s;
-		struct shmid64_ds32 __user *up = uptr;
-		mm_segment_t old_fs;
-
-		if (second == (IPC_SET|IPC_64)) {
-			err = get_user(s.shm_perm.uid,
-				       &up->shm_perm.uid);
-			err |= __get_user(s.shm_perm.gid,
-					  &up->shm_perm.gid);
-			err |= __get_user(s.shm_perm.mode,
-					  &up->shm_perm.mode);
-			if (err)
-				goto out;
-		}
-		old_fs = get_fs();
-		set_fs(KERNEL_DS);
-		err = sys_shmctl(first, second,
-				 (struct shmid_ds __user *)&s);
-		set_fs(old_fs);
-		if (err < 0)
-			goto out;
-
-		/* Mask it even in this case so it becomes a CSE. */
-		if (IPCOP_MASK (second) &
-		    (IPCOP_MASK (SHM_STAT) | IPCOP_MASK (IPC_STAT))) {
-			int err2 = copy_to_user(&up->shm_perm,
-						&s.shm_perm,
-						sizeof(struct ipc64_perm) + 3*sizeof(time_t));
-			err2 |= __put_user(s.shm_segsz, &up->shm_segsz);
-			err2 |= __put_user(s.shm_nattch,&up->shm_nattch);
-			err2 |= __put_user(s.shm_cpid, &up->shm_cpid);
-			err2 |= __put_user(s.shm_lpid, &up->shm_lpid);
-			if (err2)
-				err = -EFAULT;
-		}
-	} else {
-		struct shmid_ds s;
-		struct shmid_ds32 __user *up = uptr;
-		mm_segment_t old_fs;
-
-		second &= ~IPC_64;
-		if (second == IPC_SET) {
-			err = get_user(s.shm_perm.uid,
-				       &up->shm_perm.uid);
-			err |= __get_user(s.shm_perm.gid,
-					  &up->shm_perm.gid);
-			err |= __get_user(s.shm_perm.mode,
-					  &up->shm_perm.mode);
-			if (err)
-				goto out;
-		}
-		old_fs = get_fs();
-		set_fs(KERNEL_DS);
-		err = sys_shmctl(first, second,
-				 (struct shmid_ds __user *) &s);
-		set_fs(old_fs);
-		if (err < 0)
-			goto out;
-
-		/* Mask it even in this case so it becomes a CSE. */
-		if (second == SHM_INFO) {
-			struct shm_info32 {
-				int used_ids;
-				u32 shm_tot, shm_rss, shm_swp;
-				u32 swap_attempts, swap_successes;
-			};
-			struct shm_info32 __user *uip = uptr;
-			struct shm_info *kp = (struct shm_info *) &s;
-			int err2 = put_user(kp->used_ids,
-					    &uip->used_ids);
-			err2 |= __put_user(kp->shm_tot, &uip->shm_tot);
-			err2 |= __put_user(kp->shm_rss, &uip->shm_rss);
-			err2 |= __put_user(kp->shm_swp, &uip->shm_swp);
-			err2 |= __put_user(kp->swap_attempts,
-					   &uip->swap_attempts);
-			err2 |= __put_user(kp->swap_successes,
-					   &uip->swap_successes);
-			if (err2)
-				err = -EFAULT;
-		} else if (IPCOP_MASK (second) &
-			   (IPCOP_MASK (SHM_STAT) |
-			    IPCOP_MASK (IPC_STAT))) {
-			int err2;
-
-			err2  = put_user(s.shm_perm.key,
-					 &up->shm_perm.key);
-			err2 |= __put_user(high2lowuid(s.shm_perm.uid),
-					   &up->shm_perm.uid);
-			err2 |= __put_user(high2lowuid(s.shm_perm.gid),
-					   &up->shm_perm.gid);
-			err2 |= __put_user(high2lowuid(s.shm_perm.cuid),
-					   &up->shm_perm.cuid);
-			err2 |= __put_user(high2lowuid(s.shm_perm.cgid),
-					   &up->shm_perm.cgid);
-			err2 |= __put_user(s.shm_perm.mode,
-					   &up->shm_perm.mode);
-			err2 |= __put_user(s.shm_perm.seq,
-					   &up->shm_perm.seq);
-			err2 |= __put_user(s.shm_atime, &up->shm_atime);
-			err2 |= __put_user(s.shm_dtime, &up->shm_dtime);
-			err2 |= __put_user(s.shm_ctime, &up->shm_ctime);
-			err2 |= __put_user(s.shm_segsz, &up->shm_segsz);
-			err2 |= __put_user(s.shm_nattch,&up->shm_nattch);
-			err2 |= __put_user(s.shm_cpid, &up->shm_cpid);
-			err2 |= __put_user(s.shm_lpid, &up->shm_lpid);
-			if (err2)
-				err = -EFAULT;
-		}
-	}
-out:
-	return err;
-}
-
-static int sys32_semtimedop(int semid, struct sembuf __user *tsems,
-		int nsems,
-		const struct compat_timespec __user *timeout32)
-{
-	struct compat_timespec t32;
-	struct timespec __user *t64;
-
-	t64 = compat_alloc_user_space(sizeof(*t64));
-	if (copy_from_user(&t32, timeout32, sizeof(t32)))
-		return -EFAULT;
-
-	if (put_user(t32.tv_sec, &t64->tv_sec) ||
-	    put_user(t32.tv_nsec, &t64->tv_nsec))
-		return -EFAULT;
-
-	return sys_semtimedop(semid, tsems, nsems, t64);
-}
-
-asmlinkage long compat_sys_ipc(u32 call, int first, int second, int third, compat_uptr_t __ptr, u32 fifth)
+#ifdef CONFIG_SYSVIPC                                                        
+asmlinkage long compat_sys_ipc(u32 call, u32 first, u32 second, u32 third, compat_uptr_t ptr, u32 fifth)
 {
-	int version, err;
-	void __user *ptr = compat_ptr(__ptr);
+	int version;
 
 	version = call >> 16; /* hack for backward compatibility */
 	call &= 0xffff;
 
-	if (call <= SEMCTL) {
-		switch (call) {
-		case SEMOP:
-			/* struct sembuf is the same on 32 and 64 :)) */
-			err = sys_semtimedop (first, ptr, second, NULL);
-			goto out;
-		case SEMTIMEDOP:
-			err = sys32_semtimedop(first, ptr, second,
-					       compat_ptr(fifth));
-		case SEMGET:
-			err = sys_semget(first, second, third);
-			goto out;
-		case SEMCTL:
-			err = do_sys32_semctl(first, second, third, ptr);
-			goto out;
-		default:
-			err = -ENOSYS;
-			goto out;
-		};
-	}
-	if (call <= MSGCTL) {
-		switch (call) {
-		case MSGSND:
-			err = do_sys32_msgsnd(first, second, third, ptr);
-			goto out;
-		case MSGRCV:
-			err = do_sys32_msgrcv(first, second, fifth,
-					      third, version, ptr);
-			goto out;
-		case MSGGET:
-			err = sys_msgget((key_t) first, second);
-			goto out;
-		case MSGCTL:
-			err = do_sys32_msgctl(first, second, ptr);
-			goto out;
-		default:
-			err = -ENOSYS;
-			goto out;
-		};
-	}
-	if (call <= SHMCTL) {
-		switch (call) {
-		case SHMAT:
-			err = do_sys32_shmat(first, second, third,
-					     version, ptr);
-			goto out;
-		case SHMDT: 
-			err = sys_shmdt(ptr);
-			goto out;
-		case SHMGET:
-			err = sys_shmget(first, second, third);
-			goto out;
-		case SHMCTL:
-			err = do_sys32_shmctl(first, second, ptr);
-			goto out;
-		default:
-			err = -ENOSYS;
-			goto out;
-		};
-	}
-	err = -ENOSYS;
+	switch (call) {
+	case SEMTIMEDOP:
+		if (third)
+			/* sign extend semid */
+			return compat_sys_semtimedop((int)first,
+						     compat_ptr(ptr), second,
+						     compat_ptr(third));
+		/* else fall through for normal semop() */
+	case SEMOP:
+		/* struct sembuf is the same on 32 and 64bit :)) */
+		/* sign extend semid */
+		return sys_semtimedop((int)first, compat_ptr(ptr), second,
+				      NULL);
+	case SEMGET:
+		/* sign extend key, nsems */
+		return sys_semget((int)first, (int)second, third);
+	case SEMCTL:
+		/* sign extend semid, semnum */
+		return compat_sys_semctl((int)first, (int)second, third,
+					 compat_ptr(ptr));
+
+	case MSGSND:
+		/* sign extend msqid */
+		return compat_sys_msgsnd((int)first, (int)second, third,
+					 compat_ptr(ptr));
+	case MSGRCV:
+		/* sign extend msqid, msgtyp */
+		return compat_sys_msgrcv((int)first, second, (int)fifth,
+					 third, version, compat_ptr(ptr));
+	case MSGGET:
+		/* sign extend key */
+		return sys_msgget((int)first, second);
+	case MSGCTL:
+		/* sign extend msqid */
+		return compat_sys_msgctl((int)first, second, compat_ptr(ptr));
+
+	case SHMAT:
+		/* sign extend shmid */
+		return compat_sys_shmat((int)first, second, third, version,
+					compat_ptr(ptr));
+	case SHMDT:
+		return sys_shmdt(compat_ptr(ptr));
+	case SHMGET:
+		/* sign extend key_t */
+		return sys_shmget((int)first, second, third);
+	case SHMCTL:
+		/* sign extend shmid */
+		return compat_sys_shmctl((int)first, second, compat_ptr(ptr));
+
+	default:
+		return -ENOSYS;
+	};
 
-out:
-	return err;
+	return -ENOSYS;
 }
+#endif
 
 asmlinkage long sys32_truncate64(const char __user * path, unsigned long high, unsigned long low)
 {
@@ -1044,99 +512,14 @@
 	return ret;
 }
 
-asmlinkage long sys32_rt_sigtimedwait(compat_sigset_t __user *uthese,
-				      struct siginfo32 __user *uinfo,
-				      struct compat_timespec __user *uts,
-				      compat_size_t sigsetsize)
-{
-	int ret, sig;
-	sigset_t these;
-	compat_sigset_t these32;
-	struct timespec ts;
-	siginfo_t info;
-	long timeout = 0;
-
-	/* XXX: Don't preclude handling different sized sigset_t's.  */
-	if (sigsetsize != sizeof(sigset_t))
-		return -EINVAL;
-
-	if (copy_from_user (&these32, uthese, sizeof(compat_sigset_t)))
-		return -EFAULT;
-
-	switch (_NSIG_WORDS) {
-	case 4: these.sig[3] = these32.sig[6] | (((long)these32.sig[7]) << 32);
-	case 3: these.sig[2] = these32.sig[4] | (((long)these32.sig[5]) << 32);
-	case 2: these.sig[1] = these32.sig[2] | (((long)these32.sig[3]) << 32);
-	case 1: these.sig[0] = these32.sig[0] | (((long)these32.sig[1]) << 32);
-	}
-		
-	/*
-	 * Invert the set of allowed signals to get those we
-	 * want to block.
-	 */
-	sigdelsetmask(&these, sigmask(SIGKILL)|sigmask(SIGSTOP));
-	signotset(&these);
-
-	if (uts) {
-		if (get_compat_timespec(&ts, uts))
-			return -EINVAL;
-		if (ts.tv_nsec >= 1000000000L || ts.tv_nsec < 0
-		    || ts.tv_sec < 0)
-			return -EINVAL;
-	}
-
-	spin_lock_irq(&current->sighand->siglock);
-	sig = dequeue_signal(current, &these, &info);
-	if (!sig) {
-		timeout = MAX_SCHEDULE_TIMEOUT;
-		if (uts)
-			timeout = (timespec_to_jiffies(&ts)
-				   + (ts.tv_sec || ts.tv_nsec));
-
-		if (timeout) {
-			/* None ready -- temporarily unblock those we're
-			 * interested while we are sleeping in so that we'll
-			 * be awakened when they arrive.  */
-			current->real_blocked = current->blocked;
-			sigandsets(&current->blocked, &current->blocked, &these);
-			recalc_sigpending();
-			spin_unlock_irq(&current->sighand->siglock);
-
-			current->state = TASK_INTERRUPTIBLE;
-			timeout = schedule_timeout(timeout);
-
-			spin_lock_irq(&current->sighand->siglock);
-			sig = dequeue_signal(current, &these, &info);
-			current->blocked = current->real_blocked;
-			siginitset(&current->real_blocked, 0);
-			recalc_sigpending();
-		}
-	}
-	spin_unlock_irq(&current->sighand->siglock);
-
-	if (sig) {
-		ret = sig;
-		if (uinfo) {
-			if (copy_siginfo_to_user32(uinfo, &info))
-				ret = -EFAULT;
-		}
-	} else {
-		ret = -EAGAIN;
-		if (timeout)
-			ret = -EINTR;
-	}
-
-	return ret;
-}
-
 asmlinkage long compat_sys_rt_sigqueueinfo(int pid, int sig,
-					   struct siginfo32 __user *uinfo)
+					   struct compat_siginfo __user *uinfo)
 {
 	siginfo_t info;
 	int ret;
 	mm_segment_t old_fs = get_fs();
 	
-	if (copy_siginfo_to_kernel32(&info, uinfo))
+	if (copy_siginfo_from_user32(&info, uinfo))
 		return -EFAULT;
 
 	set_fs (KERNEL_DS);
@@ -1175,8 +558,8 @@
         ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
 
 	if (!ret && oact) {
-		ret = put_user((long)old_ka.sa.sa_handler, &oact->sa_handler);
-		ret |= __put_user((long)old_ka.sa.sa_restorer, &oact->sa_restorer);
+		ret = put_user(ptr_to_compat(old_ka.sa.sa_handler), &oact->sa_handler);
+		ret |= __put_user(ptr_to_compat(old_ka.sa.sa_restorer), &oact->sa_restorer);
 		ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
 		ret |= __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
         }
@@ -1232,10 +615,10 @@
 		case 2: set32.sig[3] = (old_ka.sa.sa_mask.sig[1] >> 32); set32.sig[2] = old_ka.sa.sa_mask.sig[1];
 		case 1: set32.sig[1] = (old_ka.sa.sa_mask.sig[0] >> 32); set32.sig[0] = old_ka.sa.sa_mask.sig[0];
 		}
-		ret = put_user((long)old_ka.sa.sa_handler, &oact->sa_handler);
+		ret = put_user(ptr_to_compat(old_ka.sa.sa_handler), &oact->sa_handler);
 		ret |= __copy_to_user(&oact->sa_mask, &set32, sizeof(compat_sigset_t));
 		ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
-		ret |= __put_user((long)old_ka.sa.sa_restorer, &oact->sa_restorer);
+		ret |= __put_user(ptr_to_compat(old_ka.sa.sa_restorer), &oact->sa_restorer);
 		if (ret)
 			ret = -EFAULT;
         }
@@ -1683,7 +1066,8 @@
 			    put_user(oldlen, (u32 __user *)(unsigned long) tmp.oldlenp))
 				error = -EFAULT;
 		}
-		copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused));
+		if (copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused)))
+			error = -EFAULT;
 	}
 	return error;
 #endif
@@ -1739,8 +1123,8 @@
 }
 
 asmlinkage long compat_sys_waitid(u32 which, u32 pid,
-				  struct siginfo32 __user *uinfo, u32 options,
-				  struct compat_rusage __user *uru)
+				  struct compat_siginfo __user *uinfo,
+				  u32 options, struct compat_rusage __user *uru)
 {
 	siginfo_t info;
 	struct rusage ru;
diff -Nru a/arch/sparc64/kernel/sys_sunos32.c b/arch/sparc64/kernel/sys_sunos32.c
--- a/arch/sparc64/kernel/sys_sunos32.c	2005-03-01 23:39:06 -08:00
+++ b/arch/sparc64/kernel/sys_sunos32.c	2005-03-01 23:39:06 -08:00
@@ -291,7 +291,8 @@
 	put_user(ino, &dirent->d_ino);
 	put_user(namlen, &dirent->d_namlen);
 	put_user(reclen, &dirent->d_reclen);
-	copy_to_user(dirent->d_name, name, namlen);
+	if (copy_to_user(dirent->d_name, name, namlen))
+		return -EFAULT;
 	put_user(0, dirent->d_name + namlen);
 	dirent = (void __user *) dirent + reclen;
 	buf->curr = dirent;
@@ -371,7 +372,8 @@
 	put_user(ino, &dirent->d_ino);
 	put_user(namlen, &dirent->d_namlen);
 	put_user(reclen, &dirent->d_reclen);
-	copy_to_user(dirent->d_name, name, namlen);
+	if (copy_to_user(dirent->d_name, name, namlen))
+		return -EFAULT;
 	put_user(0, dirent->d_name + namlen);
 	dirent = (void __user *) dirent + reclen;
 	buf->curr = dirent;
@@ -1175,11 +1177,11 @@
 	return rval;
 }
 
-extern asmlinkage long sparc32_open(const char * filename, int flags, int mode);
+extern asmlinkage long sparc32_open(const char __user * filename, int flags, int mode);
 
 asmlinkage int sunos_open(u32 fname, int flags, int mode)
 {
-	const char *filename = (const char *)(long)fname;
+	const char __user *filename = compat_ptr(fname);
 
 	return sparc32_open(filename, flags, mode);
 }
@@ -1292,7 +1294,7 @@
 
 	if (!ret && oact) {
 		old_ka.sa.sa_flags ^= SUNOS_SV_INTERRUPT;
-		if (put_user((long)old_ka.sa.sa_handler, &oact->sa_handler) ||
+		if (put_user(ptr_to_compat(old_ka.sa.sa_handler), &oact->sa_handler) ||
 		    __put_user(old_ka.sa.sa_flags, &oact->sa_flags))
 			return -EFAULT;
 		__put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
diff -Nru a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S
--- a/arch/sparc64/kernel/systbls.S	2005-03-01 23:38:56 -08:00
+++ b/arch/sparc64/kernel/systbls.S	2005-03-01 23:38:56 -08:00
@@ -25,7 +25,7 @@
 /*10*/  .word sys_unlink, sunos_execv, sys_chdir, sys32_chown16, sys32_mknod
 /*15*/	.word sys_chmod, sys32_lchown16, sparc_brk, sys32_perfctr, sys32_lseek
 /*20*/	.word sys_getpid, sys_capget, sys_capset, sys32_setuid16, sys32_getuid16
-/*25*/	.word sys_time, sys_ptrace, sys_alarm, sys32_sigaltstack, sys32_pause
+/*25*/	.word compat_sys_time, sys_ptrace, sys_alarm, sys32_sigaltstack, sys32_pause
 /*30*/	.word compat_sys_utime, sys_lchown, sys_fchown, sys32_access, sys32_nice
 	.word sys_chown, sys_sync, sys32_kill, compat_sys_newstat, sys32_sendfile
 /*40*/	.word compat_sys_newlstat, sys_dup, sys_pipe, compat_sys_times, sys_getuid
@@ -41,7 +41,7 @@
 /*90*/	.word sys_dup2, sys_setfsuid, compat_sys_fcntl, sys32_select, sys_setfsgid
 	.word sys_fsync, sys32_setpriority, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
 /*100*/ .word sys32_getpriority, sys32_rt_sigreturn, sys32_rt_sigaction, sys32_rt_sigprocmask, sys32_rt_sigpending
-	.word sys32_rt_sigtimedwait, sys32_rt_sigqueueinfo, sys32_rt_sigsuspend, sys_setresuid, sys_getresuid
+	.word compat_sys_rt_sigtimedwait, sys32_rt_sigqueueinfo, sys32_rt_sigsuspend, sys_setresuid, sys_getresuid
 /*110*/	.word sys_setresgid, sys_getresgid, sys_setregid, sys_nis_syscall, sys_nis_syscall
 	.word sys32_getgroups, sys32_gettimeofday, sys32_getrusage, sys_nis_syscall, sys_getcwd
 /*120*/	.word compat_sys_readv, compat_sys_writev, sys32_settimeofday, sys32_fchown16, sys_fchmod
@@ -66,7 +66,7 @@
 	.word sys32_ipc, sys32_sigreturn, sys_clone, sys_nis_syscall, 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, sys_time, sys_nis_syscall, sys_stime, compat_sys_statfs64
+/*230*/	.word sys32_select, compat_sys_time, sys_nis_syscall, compat_sys_stime, compat_sys_statfs64
 	.word compat_sys_fstatfs64, sys_llseek, sys_mlock, sys_munlock, sys32_mlockall
 /*240*/	.word sys_munlockall, sys32_sched_setparam, sys32_sched_getparam, sys32_sched_setscheduler, sys32_sched_getscheduler
 	.word sys_sched_yield, sys32_sched_get_priority_max, sys32_sched_get_priority_min, sys32_sched_rr_get_interval, compat_sys_nanosleep
diff -Nru a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c
--- a/arch/sparc64/kernel/time.c	2005-03-01 23:38:57 -08:00
+++ b/arch/sparc64/kernel/time.c	2005-03-01 23:38:57 -08:00
@@ -46,8 +46,8 @@
 #include <asm/sections.h>
 #include <asm/cpudata.h>
 
-spinlock_t mostek_lock = SPIN_LOCK_UNLOCKED;
-spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(mostek_lock);
+DEFINE_SPINLOCK(rtc_lock);
 unsigned long mstk48t02_regs = 0UL;
 #ifdef CONFIG_PCI
 unsigned long ds1287_regs = 0UL;
diff -Nru a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c
--- a/arch/sparc64/kernel/traps.c	2005-03-01 23:39:17 -08:00
+++ b/arch/sparc64/kernel/traps.c	2005-03-01 23:39:17 -08:00
@@ -42,7 +42,7 @@
 #endif
 
 struct notifier_block *sparc64die_chain;
-static spinlock_t die_notifier_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(die_notifier_lock);
 
 int register_die_notifier(struct notifier_block *nb)
 {
diff -Nru a/arch/sparc64/lib/U1memcpy.S b/arch/sparc64/lib/U1memcpy.S
--- a/arch/sparc64/lib/U1memcpy.S	2005-03-01 23:38:55 -08:00
+++ b/arch/sparc64/lib/U1memcpy.S	2005-03-01 23:38:55 -08:00
@@ -119,6 +119,9 @@
 	.globl		FUNC_NAME
 	.type		FUNC_NAME,#function
 FUNC_NAME:		/* %o0=dst, %o1=src, %o2=len */
+	srlx		%o2, 31, %g2
+	cmp		%g2, 0
+	tne		%xcc, 5
 	PREAMBLE
 	mov		%o0, %g5
 	cmp		%o2, 0
diff -Nru a/arch/sparc64/lib/U3memcpy.S b/arch/sparc64/lib/U3memcpy.S
--- a/arch/sparc64/lib/U3memcpy.S	2005-03-01 23:39:18 -08:00
+++ b/arch/sparc64/lib/U3memcpy.S	2005-03-01 23:39:18 -08:00
@@ -80,6 +80,9 @@
 	.globl	FUNC_NAME
 	.type	FUNC_NAME,#function
 FUNC_NAME:	/* %o0=dst, %o1=src, %o2=len */
+	srlx		%o2, 31, %g2
+	cmp		%g2, 0
+	tne		%xcc, 5
 	PREAMBLE
 	mov		%o0, %g5
 	cmp		%o2, 0
diff -Nru a/arch/sparc64/lib/atomic.S b/arch/sparc64/lib/atomic.S
--- a/arch/sparc64/lib/atomic.S	2005-03-01 23:39:10 -08:00
+++ b/arch/sparc64/lib/atomic.S	2005-03-01 23:39:10 -08:00
@@ -4,59 +4,136 @@
  * Copyright (C) 1999 David S. Miller (davem@redhat.com)
  */
 
+#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
-	.align	64
 
-	.globl	__atomic_add
-	.type	__atomic_add,#function
-__atomic_add: /* %o0 = increment, %o1 = atomic_ptr */
-	lduw	[%o1], %g5
+	/* Two versions of the atomic routines, one that
+	 * does not return a value and does not perform
+	 * memory barriers, and a second which returns
+	 * a value and does the barriers.
+	 */
+	.globl	atomic_add
+	.type	atomic_add,#function
+atomic_add: /* %o0 = increment, %o1 = atomic_ptr */
+1:	lduw	[%o1], %g5
+	add	%g5, %o0, %g7
+	cas	[%o1], %g5, %g7
+	cmp	%g5, %g7
+	bne,pn	%icc, 1b
+	 nop
+	retl
+	 nop
+	.size	atomic_add, .-atomic_add
+
+	.globl	atomic_sub
+	.type	atomic_sub,#function
+atomic_sub: /* %o0 = decrement, %o1 = atomic_ptr */
+1:	lduw	[%o1], %g5
+	sub	%g5, %o0, %g7
+	cas	[%o1], %g5, %g7
+	cmp	%g5, %g7
+	bne,pn	%icc, 1b
+	 nop
+	retl
+	 nop
+	.size	atomic_sub, .-atomic_sub
+
+	.globl	atomic_add_ret
+	.type	atomic_add_ret,#function
+atomic_add_ret: /* %o0 = increment, %o1 = atomic_ptr */
+	ATOMIC_PRE_BARRIER
+1:	lduw	[%o1], %g5
 	add	%g5, %o0, %g7
 	cas	[%o1], %g5, %g7
 	cmp	%g5, %g7
-	bne,pn	%icc, __atomic_add
-	 membar	#StoreLoad | #StoreStore
+	bne,pn	%icc, 1b
+	 add	%g7, %o0, %g7
+	ATOMIC_POST_BARRIER
 	retl
-	 add	%g7, %o0, %o0
-	.size	__atomic_add, .-__atomic_add
+	 sra	%g7, 0, %o0
+	.size	atomic_add_ret, .-atomic_add_ret
 
-	.globl	__atomic_sub
-	.type	__atomic_sub,#function
-__atomic_sub: /* %o0 = increment, %o1 = atomic_ptr */
-	lduw	[%o1], %g5
+	.globl	atomic_sub_ret
+	.type	atomic_sub_ret,#function
+atomic_sub_ret: /* %o0 = decrement, %o1 = atomic_ptr */
+	ATOMIC_PRE_BARRIER
+1:	lduw	[%o1], %g5
 	sub	%g5, %o0, %g7
 	cas	[%o1], %g5, %g7
 	cmp	%g5, %g7
-	bne,pn	%icc, __atomic_sub
-	 membar	#StoreLoad | #StoreStore
+	bne,pn	%icc, 1b
+	 sub	%g7, %o0, %g7
+	ATOMIC_POST_BARRIER
+	retl
+	 sra	%g7, 0, %o0
+	.size	atomic_sub_ret, .-atomic_sub_ret
+
+	.globl	atomic64_add
+	.type	atomic64_add,#function
+atomic64_add: /* %o0 = increment, %o1 = atomic_ptr */
+1:	ldx	[%o1], %g5
+	add	%g5, %o0, %g7
+	casx	[%o1], %g5, %g7
+	cmp	%g5, %g7
+	bne,pn	%xcc, 1b
+	 nop
+	retl
+	 nop
+	.size	atomic64_add, .-atomic64_add
+
+	.globl	atomic64_sub
+	.type	atomic64_sub,#function
+atomic64_sub: /* %o0 = decrement, %o1 = atomic_ptr */
+1:	ldx	[%o1], %g5
+	sub	%g5, %o0, %g7
+	casx	[%o1], %g5, %g7
+	cmp	%g5, %g7
+	bne,pn	%xcc, 1b
+	 nop
 	retl
-	 sub	%g7, %o0, %o0
-	.size	__atomic_sub, .-__atomic_sub
+	 nop
+	.size	atomic64_sub, .-atomic64_sub
 
-	.globl	__atomic64_add
-	.type	__atomic64_add,#function
-__atomic64_add: /* %o0 = increment, %o1 = atomic_ptr */
-	ldx	[%o1], %g5
+	.globl	atomic64_add_ret
+	.type	atomic64_add_ret,#function
+atomic64_add_ret: /* %o0 = increment, %o1 = atomic_ptr */
+	ATOMIC_PRE_BARRIER
+1:	ldx	[%o1], %g5
 	add	%g5, %o0, %g7
 	casx	[%o1], %g5, %g7
 	cmp	%g5, %g7
-	bne,pn	%xcc, __atomic64_add
-	 membar	#StoreLoad | #StoreStore
+	bne,pn	%xcc, 1b
+	 add	%g7, %o0, %g7
+	ATOMIC_POST_BARRIER
 	retl
-	 add	%g7, %o0, %o0
-	.size	__atomic64_add, .-__atomic64_add
+	 mov	%g7, %o0
+	.size	atomic64_add_ret, .-atomic64_add_ret
 
-	.globl	__atomic64_sub
-	.type	__atomic64_sub,#function
-__atomic64_sub: /* %o0 = increment, %o1 = atomic_ptr */
-	ldx	[%o1], %g5
+	.globl	atomic64_sub_ret
+	.type	atomic64_sub_ret,#function
+atomic64_sub_ret: /* %o0 = decrement, %o1 = atomic_ptr */
+	ATOMIC_PRE_BARRIER
+1:	ldx	[%o1], %g5
 	sub	%g5, %o0, %g7
 	casx	[%o1], %g5, %g7
 	cmp	%g5, %g7
-	bne,pn	%xcc, __atomic64_sub
-	 membar	#StoreLoad | #StoreStore
+	bne,pn	%xcc, 1b
+	 sub	%g7, %o0, %g7
+	ATOMIC_POST_BARRIER
 	retl
-	 sub	%g7, %o0, %o0
-	.size	__atomic64_sub, .-__atomic64_sub
+	 mov	%g7, %o0
+	.size	atomic64_sub_ret, .-atomic64_sub_ret
diff -Nru a/arch/sparc64/lib/bitops.S b/arch/sparc64/lib/bitops.S
--- a/arch/sparc64/lib/bitops.S	2005-03-01 23:39:09 -08:00
+++ b/arch/sparc64/lib/bitops.S	2005-03-01 23:39:09 -08:00
@@ -4,69 +4,142 @@
  * Copyright (C) 2000 David S. Miller (davem@redhat.com)
  */
 
+#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 BITOP_PRE_BARRIER	membar #StoreLoad | #LoadLoad
+#define BITOP_POST_BARRIER	membar #StoreLoad | #StoreStore
+#else
+#define BITOP_PRE_BARRIER	nop
+#define BITOP_POST_BARRIER	nop
+#endif
+
 	.text
-	.align	64
-	.globl	___test_and_set_bit
-	.type	___test_and_set_bit,#function
-___test_and_set_bit:	/* %o0=nr, %o1=addr */
+
+	.globl	test_and_set_bit
+	.type	test_and_set_bit,#function
+test_and_set_bit:	/* %o0=nr, %o1=addr */
+	BITOP_PRE_BARRIER
+	srlx	%o0, 6, %g1
+	mov	1, %g5
+	sllx	%g1, 3, %g3
+	and	%o0, 63, %g2
+	sllx	%g5, %g2, %g5
+	add	%o1, %g3, %o1
+1:	ldx	[%o1], %g7
+	or	%g7, %g5, %g1
+	casx	[%o1], %g7, %g1
+	cmp	%g7, %g1
+	bne,pn	%xcc, 1b
+	 and	%g7, %g5, %g2
+	BITOP_POST_BARRIER
+	clr	%o0
+	retl
+	 movrne	%g2, 1, %o0
+	.size	test_and_set_bit, .-test_and_set_bit
+
+	.globl	test_and_clear_bit
+	.type	test_and_clear_bit,#function
+test_and_clear_bit:	/* %o0=nr, %o1=addr */
+	BITOP_PRE_BARRIER
+	srlx	%o0, 6, %g1
+	mov	1, %g5
+	sllx	%g1, 3, %g3
+	and	%o0, 63, %g2
+	sllx	%g5, %g2, %g5
+	add	%o1, %g3, %o1
+1:	ldx	[%o1], %g7
+	andn	%g7, %g5, %g1
+	casx	[%o1], %g7, %g1
+	cmp	%g7, %g1
+	bne,pn	%xcc, 1b
+	 and	%g7, %g5, %g2
+	BITOP_POST_BARRIER
+	clr	%o0
+	retl
+	 movrne	%g2, 1, %o0
+	.size	test_and_clear_bit, .-test_and_clear_bit
+
+	.globl	test_and_change_bit
+	.type	test_and_change_bit,#function
+test_and_change_bit:	/* %o0=nr, %o1=addr */
+	BITOP_PRE_BARRIER
+	srlx	%o0, 6, %g1
+	mov	1, %g5
+	sllx	%g1, 3, %g3
+	and	%o0, 63, %g2
+	sllx	%g5, %g2, %g5
+	add	%o1, %g3, %o1
+1:	ldx	[%o1], %g7
+	xor	%g7, %g5, %g1
+	casx	[%o1], %g7, %g1
+	cmp	%g7, %g1
+	bne,pn	%xcc, 1b
+	 and	%g7, %g5, %g2
+	BITOP_POST_BARRIER
+	clr	%o0
+	retl
+	 movrne	%g2, 1, %o0
+	.size	test_and_change_bit, .-test_and_change_bit
+
+	.globl	set_bit
+	.type	set_bit,#function
+set_bit:		/* %o0=nr, %o1=addr */
 	srlx	%o0, 6, %g1
 	mov	1, %g5
 	sllx	%g1, 3, %g3
 	and	%o0, 63, %g2
 	sllx	%g5, %g2, %g5
 	add	%o1, %g3, %o1
-	ldx	[%o1], %g7
-1:	andcc	%g7, %g5, %o0
-	bne,pn	%xcc, 2f
-	 xor	%g7, %g5, %g1
+1:	ldx	[%o1], %g7
+	or	%g7, %g5, %g1
 	casx	[%o1], %g7, %g1
 	cmp	%g7, %g1
-	bne,a,pn %xcc, 1b
-	 ldx	[%o1], %g7
-2:	retl
-	 membar	#StoreLoad | #StoreStore
-	.size	___test_and_set_bit, .-___test_and_set_bit
+	bne,pn	%xcc, 1b
+	 nop
+	retl
+	 nop
+	.size	set_bit, .-set_bit
 
-	.globl	___test_and_clear_bit
-	.type	___test_and_clear_bit,#function
-___test_and_clear_bit:	/* %o0=nr, %o1=addr */
+	.globl	clear_bit
+	.type	clear_bit,#function
+clear_bit:		/* %o0=nr, %o1=addr */
 	srlx	%o0, 6, %g1
 	mov	1, %g5
 	sllx	%g1, 3, %g3
 	and	%o0, 63, %g2
 	sllx	%g5, %g2, %g5
 	add	%o1, %g3, %o1
-	ldx	[%o1], %g7
-1:	andcc	%g7, %g5, %o0
-	be,pn	%xcc, 2f
-	 xor	%g7, %g5, %g1
+1:	ldx	[%o1], %g7
+	andn	%g7, %g5, %g1
 	casx	[%o1], %g7, %g1
 	cmp	%g7, %g1
-	bne,a,pn %xcc, 1b
-	 ldx	[%o1], %g7
-2:	retl
-	 membar	#StoreLoad | #StoreStore
-	.size	___test_and_clear_bit, .-___test_and_clear_bit
+	bne,pn	%xcc, 1b
+	 nop
+	retl
+	 nop
+	.size	clear_bit, .-clear_bit
 
-	.globl	___test_and_change_bit
-	.type	___test_and_change_bit,#function
-___test_and_change_bit:	/* %o0=nr, %o1=addr */
+	.globl	change_bit
+	.type	change_bit,#function
+change_bit:		/* %o0=nr, %o1=addr */
 	srlx	%o0, 6, %g1
 	mov	1, %g5
 	sllx	%g1, 3, %g3
 	and	%o0, 63, %g2
 	sllx	%g5, %g2, %g5
 	add	%o1, %g3, %o1
-	ldx	[%o1], %g7
-1:	and	%g7, %g5, %o0
+1:	ldx	[%o1], %g7
 	xor	%g7, %g5, %g1
 	casx	[%o1], %g7, %g1
 	cmp	%g7, %g1
-	bne,a,pn %xcc, 1b
-	 ldx	[%o1], %g7
-2:	retl
-	 membar	#StoreLoad | #StoreStore
-	nop
-	.size	___test_and_change_bit, .-___test_and_change_bit
+	bne,pn	%xcc, 1b
+	 nop
+	retl
+	 nop
+	.size	change_bit, .-change_bit
diff -Nru a/arch/sparc64/lib/debuglocks.c b/arch/sparc64/lib/debuglocks.c
--- a/arch/sparc64/lib/debuglocks.c	2005-03-01 23:39:06 -08:00
+++ b/arch/sparc64/lib/debuglocks.c	2005-03-01 23:39:06 -08:00
@@ -172,6 +172,7 @@
 runlock_again:
 	/* Spin trying to decrement the counter using casx.  */
 	__asm__ __volatile__(
+"	membar	#StoreLoad | #LoadLoad\n"
 "	ldx	[%0], %%g5\n"
 "	sub	%%g5, 1, %%g7\n"
 "	casx	[%0], %%g5, %%g7\n"
@@ -290,6 +291,7 @@
 	current->thread.smp_lock_count--;
 wlock_again:
 	__asm__ __volatile__(
+"	membar	#StoreLoad | #LoadLoad\n"
 "	mov	1, %%g3\n"
 "	sllx	%%g3, 63, %%g3\n"
 "	ldx	[%0], %%g5\n"
diff -Nru a/arch/sparc64/lib/delay.c b/arch/sparc64/lib/delay.c
--- a/arch/sparc64/lib/delay.c	2005-03-01 23:38:52 -08:00
+++ b/arch/sparc64/lib/delay.c	2005-03-01 23:38:52 -08:00
@@ -31,7 +31,7 @@
 {
 	n *= 4;
 
-	n *= (cpu_data(smp_processor_id()).udelay_val * (HZ/4));
+	n *= (cpu_data(_smp_processor_id()).udelay_val * (HZ/4));
 	n >>= 32;
 
 	__delay(n + 1);
diff -Nru a/arch/sparc64/lib/find_bit.c b/arch/sparc64/lib/find_bit.c
--- a/arch/sparc64/lib/find_bit.c	2005-03-01 23:38:58 -08:00
+++ b/arch/sparc64/lib/find_bit.c	2005-03-01 23:38:58 -08:00
@@ -50,9 +50,10 @@
  * on Linus's ALPHA routines, which are pretty portable BTW.
  */
 
-unsigned long find_next_zero_bit(unsigned long *addr, unsigned long size, unsigned long offset)
+unsigned long find_next_zero_bit(const unsigned long *addr,
+			unsigned long size, unsigned long offset)
 {
-	unsigned long *p = addr + (offset >> 6);
+	const unsigned long *p = addr + (offset >> 6);
 	unsigned long result = offset & ~63UL;
 	unsigned long tmp;
 
diff -Nru a/arch/sparc64/lib/memmove.S b/arch/sparc64/lib/memmove.S
--- a/arch/sparc64/lib/memmove.S	2005-03-01 23:39:17 -08:00
+++ b/arch/sparc64/lib/memmove.S	2005-03-01 23:39:17 -08:00
@@ -8,18 +8,16 @@
 	.align		32
 	.globl		memmove
 	.type		memmove,#function
-memmove:
+memmove:		/* o0=dst o1=src o2=len */
 	mov		%o0, %g1
 	cmp		%o0, %o1
-	blu,pt		%xcc, memcpy
-	 sub		%o0, %o1, %g5
-	add		%o1, %o2, %g3
-	cmp		%g3, %o0
 	bleu,pt		%xcc, memcpy
 	 add		%o1, %o2, %g5
-	add		%o0, %o2, %o5
-
+	cmp		%g5, %o0
+	bleu,pt		%xcc, memcpy
+	 add		%o0, %o2, %o5
 	sub		%g5, 1, %o1
+
 	sub		%o5, 1, %o0
 1:	ldub		[%o1], %g5
 	subcc		%o2, 1, %o2
diff -Nru a/arch/sparc64/lib/user_fixup.c b/arch/sparc64/lib/user_fixup.c
--- a/arch/sparc64/lib/user_fixup.c	2005-03-01 23:39:07 -08:00
+++ b/arch/sparc64/lib/user_fixup.c	2005-03-01 23:39:07 -08:00
@@ -20,11 +20,12 @@
 	char *dst = to;
 	const char __user *src = from;
 
-	while (size--) {
+	while (size) {
 		if (__get_user(*dst, src))
 			break;
 		dst++;
 		src++;
+		size--;
 	}
 
 	if (size)
@@ -38,11 +39,12 @@
 	char __user *dst = to;
 	const char *src = from;
 
-	while (size--) {
+	while (size) {
 		if (__put_user(*src, dst))
 			break;
 		dst++;
 		src++;
+		size--;
 	}
 
 	return size;
@@ -53,7 +55,7 @@
 	char __user *dst = to;
 	char __user *src = from;
 
-	while (size--) {
+	while (size) {
 		char tmp;
 
 		if (__get_user(tmp, src))
@@ -62,6 +64,7 @@
 			break;
 		dst++;
 		src++;
+		size--;
 	}
 
 	return size;
diff -Nru a/arch/sparc64/mm/fault.c b/arch/sparc64/mm/fault.c
--- a/arch/sparc64/mm/fault.c	2005-03-01 23:39:17 -08:00
+++ b/arch/sparc64/mm/fault.c	2005-03-01 23:39:17 -08:00
@@ -175,6 +175,7 @@
 static unsigned int get_user_insn(unsigned long tpc)
 {
 	pgd_t *pgdp = pgd_offset(current->mm, tpc);
+	pud_t *pudp;
 	pmd_t *pmdp;
 	pte_t *ptep, pte;
 	unsigned long pa;
@@ -183,7 +184,10 @@
 
 	if (pgd_none(*pgdp))
 		goto outret;
-	pmdp = pmd_offset(pgdp, tpc);
+	pudp = pud_offset(pgdp, tpc);
+	if (pud_none(*pudp))
+		goto outret;
+	pmdp = pmd_offset(pudp, tpc);
 	if (pmd_none(*pmdp))
 		goto outret;
 
diff -Nru a/arch/sparc64/mm/generic.c b/arch/sparc64/mm/generic.c
--- a/arch/sparc64/mm/generic.c	2005-03-01 23:39:09 -08:00
+++ b/arch/sparc64/mm/generic.c	2005-03-01 23:39:09 -08:00
@@ -96,6 +96,27 @@
 	return 0;
 }
 
+static inline int io_remap_pud_range(pud_t * pud, unsigned long address, unsigned long size,
+	unsigned long offset, pgprot_t prot, int space)
+{
+	unsigned long end;
+
+	address &= ~PUD_MASK;
+	end = address + size;
+	if (end > PUD_SIZE)
+		end = PUD_SIZE;
+	offset -= address;
+	do {
+		pmd_t *pmd = pmd_alloc(current->mm, pud, address);
+		if (!pud)
+			return -ENOMEM;
+		io_remap_pmd_range(pmd, address, end - address, address + offset, prot, space);
+		address = (address + PUD_SIZE) & PUD_MASK;
+		pud++;
+	} while (address < end);
+	return 0;
+}
+
 int io_remap_page_range(struct vm_area_struct *vma, unsigned long from, unsigned long offset, unsigned long size, pgprot_t prot, int space)
 {
 	int error = 0;
@@ -111,11 +132,11 @@
 
 	spin_lock(&mm->page_table_lock);
 	while (from < end) {
-		pmd_t *pmd = pmd_alloc(current->mm, dir, from);
+		pud_t *pud = pud_alloc(current->mm, dir, from);
 		error = -ENOMEM;
-		if (!pmd)
+		if (!pud)
 			break;
-		error = io_remap_pmd_range(pmd, from, end - from, offset + from, prot, space);
+		error = io_remap_pud_range(pud, from, end - from, offset + from, prot, space);
 		if (error)
 			break;
 		from = (from + PGDIR_SIZE) & PGDIR_MASK;
diff -Nru a/arch/sparc64/mm/hugetlbpage.c b/arch/sparc64/mm/hugetlbpage.c
--- a/arch/sparc64/mm/hugetlbpage.c	2005-03-01 23:39:07 -08:00
+++ b/arch/sparc64/mm/hugetlbpage.c	2005-03-01 23:39:07 -08:00
@@ -24,14 +24,18 @@
 static pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr)
 {
 	pgd_t *pgd;
+	pud_t *pud;
 	pmd_t *pmd;
 	pte_t *pte = NULL;
 
 	pgd = pgd_offset(mm, addr);
 	if (pgd) {
-		pmd = pmd_alloc(mm, pgd, addr);
-		if (pmd)
-			pte = pte_alloc_map(mm, pmd, addr);
+		pud = pud_offset(pgd, addr);
+		if (pud) {
+			pmd = pmd_alloc(mm, pud, addr);
+			if (pmd)
+				pte = pte_alloc_map(mm, pmd, addr);
+		}
 	}
 	return pte;
 }
@@ -39,14 +43,18 @@
 static pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
 {
 	pgd_t *pgd;
+	pud_t *pud;
 	pmd_t *pmd;
 	pte_t *pte = NULL;
 
 	pgd = pgd_offset(mm, addr);
 	if (pgd) {
-		pmd = pmd_offset(pgd, addr);
-		if (pmd)
-			pte = pte_offset_map(pmd, addr);
+		pud = pud_offset(pgd, addr);
+		if (pud) {
+			pmd = pmd_offset(pud, addr);
+			if (pmd)
+				pte = pte_offset_map(pmd, addr);
+		}
 	}
 	return pte;
 }
diff -Nru a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c
--- a/arch/sparc64/mm/init.c	2005-03-01 23:38:55 -08:00
+++ b/arch/sparc64/mm/init.c	2005-03-01 23:38:55 -08:00
@@ -59,7 +59,7 @@
 static unsigned long bootmap_base;
 
 /* get_new_mmu_context() uses "cache + 1".  */
-spinlock_t ctx_alloc_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(ctx_alloc_lock);
 unsigned long tlb_context_cache = CTX_FIRST_VERSION - 1;
 #define CTX_BMAP_SLOTS (1UL << (CTX_VERSION_SHIFT - 6))
 unsigned long mmu_context_bmap[CTX_BMAP_SLOTS];
@@ -1462,7 +1462,8 @@
 	memset(swapper_pmd_dir, 0, sizeof(swapper_pmd_dir));
 
 	/* Now can init the kernel/bad page tables. */
-	pgd_set(&swapper_pg_dir[0], swapper_pmd_dir + (shift / sizeof(pgd_t)));
+	pud_set(pud_offset(&swapper_pg_dir[0], 0),
+		swapper_pmd_dir + (shift / sizeof(pgd_t)));
 	
 	sparc64_vpte_patchme1[0] |=
 		(((unsigned long)pgd_val(init_mm.pgd[0])) >> 10);
@@ -1687,13 +1688,12 @@
 	 * Set up the zero page, mark it reserved, so that page count
 	 * is not manipulated when freeing the page from user ptes.
 	 */
-	mem_map_zero = alloc_pages(GFP_KERNEL, 0);
+	mem_map_zero = alloc_pages(GFP_KERNEL|__GFP_ZERO, 0);
 	if (mem_map_zero == NULL) {
 		prom_printf("paging_init: Cannot alloc zero page.\n");
 		prom_halt();
 	}
 	SetPageReserved(mem_map_zero);
-	clear_page(page_address(mem_map_zero));
 
 	codepages = (((unsigned long) _etext) - ((unsigned long) _start));
 	codepages = PAGE_ALIGN(codepages) >> PAGE_SHIFT;
diff -Nru a/arch/sparc64/mm/tlb.c b/arch/sparc64/mm/tlb.c
--- a/arch/sparc64/mm/tlb.c	2005-03-01 23:38:57 -08:00
+++ b/arch/sparc64/mm/tlb.c	2005-03-01 23:38:57 -08:00
@@ -118,11 +118,9 @@
 	 */
 	BUG_ON(s > e);
 
-#if 0
-	/* Currently free_pgtables guarantees this.  */
 	s &= PMD_MASK;
 	e = (e + PMD_SIZE - 1) & PMD_MASK;
-#endif
+
 	vpte_base = (tlb_type == spitfire ?
 		     VPTE_BASE_SPITFIRE :
 		     VPTE_BASE_CHEETAH);
diff -Nru a/arch/sparc64/oprofile/init.c b/arch/sparc64/oprofile/init.c
--- a/arch/sparc64/oprofile/init.c	2005-03-01 23:39:06 -08:00
+++ b/arch/sparc64/oprofile/init.c	2005-03-01 23:39:06 -08:00
@@ -12,9 +12,7 @@
 #include <linux/errno.h>
 #include <linux/init.h>
  
-extern void timer_init(struct oprofile_operations ** ops);
-
-int __init oprofile_arch_init(struct oprofile_operations ** ops)
+int __init oprofile_arch_init(struct oprofile_operations * ops)
 {
 	return -ENODEV;
 }
diff -Nru a/arch/sparc64/prom/Makefile b/arch/sparc64/prom/Makefile
--- a/arch/sparc64/prom/Makefile	2005-03-01 23:39:09 -08:00
+++ b/arch/sparc64/prom/Makefile	2005-03-01 23:39:09 -08:00
@@ -7,4 +7,4 @@
 EXTRA_CFLAGS := -Werror
 
 lib-y   := bootstr.o devops.o init.o memory.o misc.o \
-	   tree.o console.o printf.o p1275.o map.o
+	   tree.o console.o printf.o p1275.o map.o cif.o
diff -Nru a/arch/sparc64/prom/cif.S b/arch/sparc64/prom/cif.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/sparc64/prom/cif.S	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,225 @@
+/* cif.S: PROM entry/exit assembler trampolines.
+ *
+ * Copyright (C) 1996,1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+ * Copyright (C) 2005 David S. Miller <davem@davemloft.net>
+ */
+
+#include <asm/pstate.h>
+
+	.text
+	.globl	prom_cif_interface
+prom_cif_interface:
+	sethi	%hi(p1275buf), %o0
+	or	%o0, %lo(p1275buf), %o0
+	ldx	[%o0 + 0x010], %o1	! prom_cif_stack
+	save	%o1, -0x190, %sp
+	ldx	[%i0 + 0x008], %l2	! prom_cif_handler
+	rdpr	%pstate, %l4
+	wrpr	%g0, 0x15, %pstate	! save alternate globals
+	stx	%g1, [%sp + 2047 + 0x0b0]
+	stx	%g2, [%sp + 2047 + 0x0b8]
+	stx	%g3, [%sp + 2047 + 0x0c0]
+	stx	%g4, [%sp + 2047 + 0x0c8]
+	stx	%g5, [%sp + 2047 + 0x0d0]
+	stx	%g6, [%sp + 2047 + 0x0d8]
+	stx	%g7, [%sp + 2047 + 0x0e0]
+	wrpr	%g0, 0x814, %pstate	! save interrupt globals
+	stx	%g1, [%sp + 2047 + 0x0e8]
+	stx	%g2, [%sp + 2047 + 0x0f0]
+	stx	%g3, [%sp + 2047 + 0x0f8]
+	stx	%g4, [%sp + 2047 + 0x100]
+	stx	%g5, [%sp + 2047 + 0x108]
+	stx	%g6, [%sp + 2047 + 0x110]
+	stx	%g7, [%sp + 2047 + 0x118]
+	wrpr	%g0, 0x14, %pstate	! save normal globals
+	stx	%g1, [%sp + 2047 + 0x120]
+	stx	%g2, [%sp + 2047 + 0x128]
+	stx	%g3, [%sp + 2047 + 0x130]
+	stx	%g4, [%sp + 2047 + 0x138]
+	stx	%g5, [%sp + 2047 + 0x140]
+	stx	%g6, [%sp + 2047 + 0x148]
+	stx	%g7, [%sp + 2047 + 0x150]
+	wrpr	%g0, 0x414, %pstate	! save mmu globals
+	stx	%g1, [%sp + 2047 + 0x158]
+	stx	%g2, [%sp + 2047 + 0x160]
+	stx	%g3, [%sp + 2047 + 0x168]
+	stx	%g4, [%sp + 2047 + 0x170]
+	stx	%g5, [%sp + 2047 + 0x178]
+	stx	%g6, [%sp + 2047 + 0x180]
+	stx	%g7, [%sp + 2047 + 0x188]
+	mov	%g1, %l0		! also save to locals, so we can handle
+	mov	%g2, %l1		! tlb faults later on, when accessing
+	mov	%g3, %l3		! the stack.
+	mov	%g7, %l5
+	wrpr	%l4, PSTATE_IE, %pstate	! turn off interrupts
+	call	%l2
+	 add	%i0, 0x018, %o0		! prom_args
+	wrpr	%g0, 0x414, %pstate	! restore mmu globals
+	mov	%l0, %g1
+	mov	%l1, %g2
+	mov	%l3, %g3
+	mov	%l5, %g7
+	wrpr	%g0, 0x14, %pstate	! restore normal globals
+	ldx	[%sp + 2047 + 0x120], %g1
+	ldx	[%sp + 2047 + 0x128], %g2
+	ldx	[%sp + 2047 + 0x130], %g3
+	ldx	[%sp + 2047 + 0x138], %g4
+	ldx	[%sp + 2047 + 0x140], %g5
+	ldx	[%sp + 2047 + 0x148], %g6
+	ldx	[%sp + 2047 + 0x150], %g7
+	wrpr	%g0, 0x814, %pstate	! restore interrupt globals
+	ldx	[%sp + 2047 + 0x0e8], %g1
+	ldx	[%sp + 2047 + 0x0f0], %g2
+	ldx	[%sp + 2047 + 0x0f8], %g3
+	ldx	[%sp + 2047 + 0x100], %g4
+	ldx	[%sp + 2047 + 0x108], %g5
+	ldx	[%sp + 2047 + 0x110], %g6
+	ldx	[%sp + 2047 + 0x118], %g7
+	wrpr	%g0, 0x15, %pstate	! restore alternate globals
+	ldx	[%sp + 2047 + 0x0b0], %g1
+	ldx	[%sp + 2047 + 0x0b8], %g2
+	ldx	[%sp + 2047 + 0x0c0], %g3
+	ldx	[%sp + 2047 + 0x0c8], %g4
+	ldx	[%sp + 2047 + 0x0d0], %g5
+	ldx	[%sp + 2047 + 0x0d8], %g6
+	ldx	[%sp + 2047 + 0x0e0], %g7
+	wrpr	%l4, 0, %pstate	! restore original pstate
+	ret
+	 restore
+
+	.globl	prom_cif_callback
+prom_cif_callback:
+	sethi	%hi(p1275buf), %o1
+	or	%o1, %lo(p1275buf), %o1
+	save	%sp, -0x270, %sp
+	rdpr	%pstate, %l4
+	wrpr	%g0, 0x15, %pstate	! save PROM alternate globals
+	stx	%g1, [%sp + 2047 + 0x0b0]
+	stx	%g2, [%sp + 2047 + 0x0b8]
+	stx	%g3, [%sp + 2047 + 0x0c0]
+	stx	%g4, [%sp + 2047 + 0x0c8]
+	stx	%g5, [%sp + 2047 + 0x0d0]
+	stx	%g6, [%sp + 2047 + 0x0d8]
+	stx	%g7, [%sp + 2047 + 0x0e0]
+					! restore Linux alternate globals
+	ldx	[%sp + 2047 + 0x190], %g1
+	ldx	[%sp + 2047 + 0x198], %g2
+	ldx	[%sp + 2047 + 0x1a0], %g3
+	ldx	[%sp + 2047 + 0x1a8], %g4
+	ldx	[%sp + 2047 + 0x1b0], %g5
+	ldx	[%sp + 2047 + 0x1b8], %g6
+	ldx	[%sp + 2047 + 0x1c0], %g7
+	wrpr	%g0, 0x814, %pstate	! save PROM interrupt globals
+	stx	%g1, [%sp + 2047 + 0x0e8]
+	stx	%g2, [%sp + 2047 + 0x0f0]
+	stx	%g3, [%sp + 2047 + 0x0f8]
+	stx	%g4, [%sp + 2047 + 0x100]
+	stx	%g5, [%sp + 2047 + 0x108]
+	stx	%g6, [%sp + 2047 + 0x110]
+	stx	%g7, [%sp + 2047 + 0x118]
+					! restore Linux interrupt globals
+	ldx	[%sp + 2047 + 0x1c8], %g1
+	ldx	[%sp + 2047 + 0x1d0], %g2
+	ldx	[%sp + 2047 + 0x1d8], %g3
+	ldx	[%sp + 2047 + 0x1e0], %g4
+	ldx	[%sp + 2047 + 0x1e8], %g5
+	ldx	[%sp + 2047 + 0x1f0], %g6
+	ldx	[%sp + 2047 + 0x1f8], %g7
+	wrpr	%g0, 0x14, %pstate	! save PROM normal globals
+	stx	%g1, [%sp + 2047 + 0x120]
+	stx	%g2, [%sp + 2047 + 0x128]
+	stx	%g3, [%sp + 2047 + 0x130]
+	stx	%g4, [%sp + 2047 + 0x138]
+	stx	%g5, [%sp + 2047 + 0x140]
+	stx	%g6, [%sp + 2047 + 0x148]
+	stx	%g7, [%sp + 2047 + 0x150]
+					! restore Linux normal globals
+	ldx	[%sp + 2047 + 0x200], %g1
+	ldx	[%sp + 2047 + 0x208], %g2
+	ldx	[%sp + 2047 + 0x210], %g3
+	ldx	[%sp + 2047 + 0x218], %g4
+	ldx	[%sp + 2047 + 0x220], %g5
+	ldx	[%sp + 2047 + 0x228], %g6
+	ldx	[%sp + 2047 + 0x230], %g7
+	wrpr	%g0, 0x414, %pstate	! save PROM mmu globals
+	stx	%g1, [%sp + 2047 + 0x158]
+	stx	%g2, [%sp + 2047 + 0x160]
+	stx	%g3, [%sp + 2047 + 0x168]
+	stx	%g4, [%sp + 2047 + 0x170]
+	stx	%g5, [%sp + 2047 + 0x178]
+	stx	%g6, [%sp + 2047 + 0x180]
+	stx	%g7, [%sp + 2047 + 0x188]
+					! restore Linux mmu globals
+	ldx	[%sp + 2047 + 0x238], %o0
+	ldx	[%sp + 2047 + 0x240], %o1
+	ldx	[%sp + 2047 + 0x248], %l2
+	ldx	[%sp + 2047 + 0x250], %l3
+	ldx	[%sp + 2047 + 0x258], %l5
+	ldx	[%sp + 2047 + 0x260], %l6
+	ldx	[%sp + 2047 + 0x268], %l7
+					! switch to Linux tba
+	sethi	%hi(sparc64_ttable_tl0), %l1
+	rdpr	%tba, %l0		! save PROM tba
+	mov	%o0, %g1
+	mov	%o1, %g2
+	mov	%l2, %g3
+	mov	%l3, %g4
+	mov	%l5, %g5
+	mov	%l6, %g6
+	mov	%l7, %g7
+	wrpr	%l1, %tba		! install Linux tba
+	wrpr	%l4, 0, %pstate		! restore PSTATE
+	call	prom_world
+	 mov	%g0, %o0
+	ldx	[%i1 + 0x000], %l2
+	call	%l2
+	 mov	%i0, %o0
+	mov	%o0, %l1
+	call	prom_world
+	 or	%g0, 1, %o0
+	wrpr	%g0, 0x14, %pstate	! interrupts off
+					! restore PROM mmu globals
+	ldx	[%sp + 2047 + 0x158], %o0
+	ldx	[%sp + 2047 + 0x160], %o1
+	ldx	[%sp + 2047 + 0x168], %l2
+	ldx	[%sp + 2047 + 0x170], %l3
+	ldx	[%sp + 2047 + 0x178], %l5
+	ldx	[%sp + 2047 + 0x180], %l6
+	ldx	[%sp + 2047 + 0x188], %l7
+	wrpr	%g0, 0x414, %pstate	! restore PROM mmu globals
+	mov	%o0, %g1
+	mov	%o1, %g2
+	mov	%l2, %g3
+	mov	%l3, %g4
+	mov	%l5, %g5
+	mov	%l6, %g6
+	mov	%l7, %g7
+	wrpr	%l0, %tba		! restore PROM tba
+	wrpr	%g0, 0x14, %pstate	! restore PROM normal globals
+	ldx	[%sp + 2047 + 0x120], %g1
+	ldx	[%sp + 2047 + 0x128], %g2
+	ldx	[%sp + 2047 + 0x130], %g3
+	ldx	[%sp + 2047 + 0x138], %g4
+	ldx	[%sp + 2047 + 0x140], %g5
+	ldx	[%sp + 2047 + 0x148], %g6
+	ldx	[%sp + 2047 + 0x150], %g7
+	wrpr	%g0, 0x814, %pstate	! restore PROM interrupt globals
+	ldx	[%sp + 2047 + 0x0e8], %g1
+	ldx	[%sp + 2047 + 0x0f0], %g2
+	ldx	[%sp + 2047 + 0x0f8], %g3
+	ldx	[%sp + 2047 + 0x100], %g4
+	ldx	[%sp + 2047 + 0x108], %g5
+	ldx	[%sp + 2047 + 0x110], %g6
+	ldx	[%sp + 2047 + 0x118], %g7
+	wrpr	%g0, 0x15, %pstate	! restore PROM alternate globals
+	ldx	[%sp + 2047 + 0x0b0], %g1
+	ldx	[%sp + 2047 + 0x0b8], %g2
+	ldx	[%sp + 2047 + 0x0c0], %g3
+	ldx	[%sp + 2047 + 0x0c8], %g4
+	ldx	[%sp + 2047 + 0x0d0], %g5
+	ldx	[%sp + 2047 + 0x0d8], %g6
+	ldx	[%sp + 2047 + 0x0e0], %g7
+	wrpr	%l4, 0, %pstate
+	ret
+	 restore %l1, 0, %o0
+
diff -Nru a/arch/sparc64/prom/memory.c b/arch/sparc64/prom/memory.c
--- a/arch/sparc64/prom/memory.c	2005-03-01 23:39:08 -08:00
+++ b/arch/sparc64/prom/memory.c	2005-03-01 23:39:08 -08:00
@@ -45,9 +45,9 @@
 	unsigned long tmpaddr, tmpsize;
 	unsigned long lowest;
 
-	for(i=0; thislist[i].theres_more != 0; i++) {
+	for(i=0; thislist[i].theres_more; i++) {
 		lowest = thislist[i].start_adr;
-		for(mitr = i+1; thislist[mitr-1].theres_more != 0; mitr++)
+		for(mitr = i+1; thislist[mitr-1].theres_more; mitr++)
 			if(thislist[mitr].start_adr < lowest) {
 				lowest = thislist[mitr].start_adr;
 				swapi = mitr;
@@ -83,7 +83,7 @@
 		prom_phys_avail[iter].theres_more =
 			&prom_phys_avail[iter+1];
 	}
-	prom_phys_avail[iter-1].theres_more = 0x0;
+	prom_phys_avail[iter-1].theres_more = NULL;
 
 	num_regs = prom_getproperty(node, "reg",
 				    (char *) prom_reg_memlist,
@@ -97,7 +97,7 @@
 		prom_phys_total[iter].theres_more =
 			&prom_phys_total[iter+1];
 	}
-	prom_phys_total[iter-1].theres_more = 0x0;
+	prom_phys_total[iter-1].theres_more = NULL;
 
 	node = prom_finddevice("/virtual-memory");
 	num_regs = prom_getproperty(node, "available",
@@ -116,7 +116,7 @@
 		prom_prom_taken[iter].theres_more =
 			&prom_prom_taken[iter+1];
 	}
-	prom_prom_taken[iter-1].theres_more = 0x0;
+	prom_prom_taken[iter-1].theres_more = NULL;
 
 	prom_sortmemlist(prom_prom_taken);
 
diff -Nru a/arch/sparc64/prom/p1275.c b/arch/sparc64/prom/p1275.c
--- a/arch/sparc64/prom/p1275.c	2005-03-01 23:38:53 -08:00
+++ b/arch/sparc64/prom/p1275.c	2005-03-01 23:38:53 -08:00
@@ -27,231 +27,14 @@
 
 extern void prom_world(int);
 
-void prom_cif_interface (void)
-{
-	__asm__ __volatile__ (
-"	mov	%0, %%o0\n"
-"	ldx	[%%o0 + 0x010], %%o1	! prom_cif_stack\n"
-"	save	%%o1, -0x190, %%sp\n"
-"	ldx	[%%i0 + 0x008], %%l2	! prom_cif_handler\n"
-"	rdpr	%%pstate, %%l4\n"
-"	wrpr	%%g0, 0x15, %%pstate	! save alternate globals\n"
-"	stx	%%g1, [%%sp + 2047 + 0x0b0]\n"
-"	stx	%%g2, [%%sp + 2047 + 0x0b8]\n"
-"	stx	%%g3, [%%sp + 2047 + 0x0c0]\n"
-"	stx	%%g4, [%%sp + 2047 + 0x0c8]\n"
-"	stx	%%g5, [%%sp + 2047 + 0x0d0]\n"
-"	stx	%%g6, [%%sp + 2047 + 0x0d8]\n"
-"	stx	%%g7, [%%sp + 2047 + 0x0e0]\n"
-"	wrpr	%%g0, 0x814, %%pstate	! save interrupt globals\n"
-"	stx	%%g1, [%%sp + 2047 + 0x0e8]\n"
-"	stx	%%g2, [%%sp + 2047 + 0x0f0]\n"
-"	stx	%%g3, [%%sp + 2047 + 0x0f8]\n"
-"	stx	%%g4, [%%sp + 2047 + 0x100]\n"
-"	stx	%%g5, [%%sp + 2047 + 0x108]\n"
-"	stx	%%g6, [%%sp + 2047 + 0x110]\n"
-"	stx	%%g7, [%%sp + 2047 + 0x118]\n"
-"	wrpr	%%g0, 0x14, %%pstate	! save normal globals\n"
-"	stx	%%g1, [%%sp + 2047 + 0x120]\n"
-"	stx	%%g2, [%%sp + 2047 + 0x128]\n"
-"	stx	%%g3, [%%sp + 2047 + 0x130]\n"
-"	stx	%%g4, [%%sp + 2047 + 0x138]\n"
-"	stx	%%g5, [%%sp + 2047 + 0x140]\n"
-"	stx	%%g6, [%%sp + 2047 + 0x148]\n"
-"	stx	%%g7, [%%sp + 2047 + 0x150]\n"
-"	wrpr	%%g0, 0x414, %%pstate	! save mmu globals\n"
-"	stx	%%g1, [%%sp + 2047 + 0x158]\n"
-"	stx	%%g2, [%%sp + 2047 + 0x160]\n"
-"	stx	%%g3, [%%sp + 2047 + 0x168]\n"
-"	stx	%%g4, [%%sp + 2047 + 0x170]\n"
-"	stx	%%g5, [%%sp + 2047 + 0x178]\n"
-"	stx	%%g6, [%%sp + 2047 + 0x180]\n"
-"	stx	%%g7, [%%sp + 2047 + 0x188]\n"
-"	mov	%%g1, %%l0		! also save to locals, so we can handle\n"
-"	mov	%%g2, %%l1		! tlb faults later on, when accessing\n"
-"	mov	%%g3, %%l3		! the stack.\n"
-"	mov	%%g7, %%l5\n"
-"	wrpr	%%l4, %1, %%pstate	! turn off interrupts\n"
-"	call	%%l2\n"
-"	 add	%%i0, 0x018, %%o0	! prom_args\n"
-"	wrpr	%%g0, 0x414, %%pstate	! restore mmu globals\n"
-"	mov	%%l0, %%g1\n"
-"	mov	%%l1, %%g2\n"
-"	mov	%%l3, %%g3\n"
-"	mov	%%l5, %%g7\n"
-"	wrpr	%%g0, 0x14, %%pstate	! restore normal globals\n"
-"	ldx	[%%sp + 2047 + 0x120], %%g1\n"
-"	ldx	[%%sp + 2047 + 0x128], %%g2\n"
-"	ldx	[%%sp + 2047 + 0x130], %%g3\n"
-"	ldx	[%%sp + 2047 + 0x138], %%g4\n"
-"	ldx	[%%sp + 2047 + 0x140], %%g5\n"
-"	ldx	[%%sp + 2047 + 0x148], %%g6\n"
-"	ldx	[%%sp + 2047 + 0x150], %%g7\n"
-"	wrpr	%%g0, 0x814, %%pstate	! restore interrupt globals\n"
-"	ldx	[%%sp + 2047 + 0x0e8], %%g1\n"
-"	ldx	[%%sp + 2047 + 0x0f0], %%g2\n"
-"	ldx	[%%sp + 2047 + 0x0f8], %%g3\n"
-"	ldx	[%%sp + 2047 + 0x100], %%g4\n"
-"	ldx	[%%sp + 2047 + 0x108], %%g5\n"
-"	ldx	[%%sp + 2047 + 0x110], %%g6\n"
-"	ldx	[%%sp + 2047 + 0x118], %%g7\n"
-"	wrpr	%%g0, 0x15, %%pstate	! restore alternate globals\n"
-"	ldx	[%%sp + 2047 + 0x0b0], %%g1\n"
-"	ldx	[%%sp + 2047 + 0x0b8], %%g2\n"
-"	ldx	[%%sp + 2047 + 0x0c0], %%g3\n"
-"	ldx	[%%sp + 2047 + 0x0c8], %%g4\n"
-"	ldx	[%%sp + 2047 + 0x0d0], %%g5\n"
-"	ldx	[%%sp + 2047 + 0x0d8], %%g6\n"
-"	ldx	[%%sp + 2047 + 0x0e0], %%g7\n"
-"	wrpr	%%l4, 0, %%pstate	! restore original pstate\n"
-"	ret\n"
-"	 restore\n"
-"	" : : "r" (&p1275buf), "i" (PSTATE_IE));
-}
-
-void prom_cif_callback(void)
-{
-	__asm__ __volatile__ (
-"	mov	%0, %%o1\n"
-"	save	%%sp, -0x270, %%sp\n"
-"	rdpr	%%pstate, %%l4\n"
-"	wrpr	%%g0, 0x15, %%pstate	! save PROM alternate globals\n"
-"	stx	%%g1, [%%sp + 2047 + 0x0b0]\n"
-"	stx	%%g2, [%%sp + 2047 + 0x0b8]\n"
-"	stx	%%g3, [%%sp + 2047 + 0x0c0]\n"
-"	stx	%%g4, [%%sp + 2047 + 0x0c8]\n"
-"	stx	%%g5, [%%sp + 2047 + 0x0d0]\n"
-"	stx	%%g6, [%%sp + 2047 + 0x0d8]\n"
-"	stx	%%g7, [%%sp + 2047 + 0x0e0]\n"
-"					! restore Linux alternate globals\n"
-"	ldx	[%%sp + 2047 + 0x190], %%g1\n"
-"	ldx	[%%sp + 2047 + 0x198], %%g2\n"
-"	ldx	[%%sp + 2047 + 0x1a0], %%g3\n"
-"	ldx	[%%sp + 2047 + 0x1a8], %%g4\n"
-"	ldx	[%%sp + 2047 + 0x1b0], %%g5\n"
-"	ldx	[%%sp + 2047 + 0x1b8], %%g6\n"
-"	ldx	[%%sp + 2047 + 0x1c0], %%g7\n"
-"	wrpr	%%g0, 0x814, %%pstate	! save PROM interrupt globals\n"
-"	stx	%%g1, [%%sp + 2047 + 0x0e8]\n"
-"	stx	%%g2, [%%sp + 2047 + 0x0f0]\n"
-"	stx	%%g3, [%%sp + 2047 + 0x0f8]\n"
-"	stx	%%g4, [%%sp + 2047 + 0x100]\n"
-"	stx	%%g5, [%%sp + 2047 + 0x108]\n"
-"	stx	%%g6, [%%sp + 2047 + 0x110]\n"
-"	stx	%%g7, [%%sp + 2047 + 0x118]\n"
-"					! restore Linux interrupt globals\n"
-"	ldx	[%%sp + 2047 + 0x1c8], %%g1\n"
-"	ldx	[%%sp + 2047 + 0x1d0], %%g2\n"
-"	ldx	[%%sp + 2047 + 0x1d8], %%g3\n"
-"	ldx	[%%sp + 2047 + 0x1e0], %%g4\n"
-"	ldx	[%%sp + 2047 + 0x1e8], %%g5\n"
-"	ldx	[%%sp + 2047 + 0x1f0], %%g6\n"
-"	ldx	[%%sp + 2047 + 0x1f8], %%g7\n"
-"	wrpr	%%g0, 0x14, %%pstate	! save PROM normal globals\n"
-"	stx	%%g1, [%%sp + 2047 + 0x120]\n"
-"	stx	%%g2, [%%sp + 2047 + 0x128]\n"
-"	stx	%%g3, [%%sp + 2047 + 0x130]\n"
-"	stx	%%g4, [%%sp + 2047 + 0x138]\n"
-"	stx	%%g5, [%%sp + 2047 + 0x140]\n"
-"	stx	%%g6, [%%sp + 2047 + 0x148]\n"
-"	stx	%%g7, [%%sp + 2047 + 0x150]\n"
-"					! restore Linux normal globals\n"
-"	ldx	[%%sp + 2047 + 0x200], %%g1\n"
-"	ldx	[%%sp + 2047 + 0x208], %%g2\n"
-"	ldx	[%%sp + 2047 + 0x210], %%g3\n"
-"	ldx	[%%sp + 2047 + 0x218], %%g4\n"
-"	ldx	[%%sp + 2047 + 0x220], %%g5\n"
-"	ldx	[%%sp + 2047 + 0x228], %%g6\n"
-"	ldx	[%%sp + 2047 + 0x230], %%g7\n"
-"	wrpr	%%g0, 0x414, %%pstate	! save PROM mmu globals\n"
-"	stx	%%g1, [%%sp + 2047 + 0x158]\n"
-"	stx	%%g2, [%%sp + 2047 + 0x160]\n"
-"	stx	%%g3, [%%sp + 2047 + 0x168]\n"
-"	stx	%%g4, [%%sp + 2047 + 0x170]\n"
-"	stx	%%g5, [%%sp + 2047 + 0x178]\n"
-"	stx	%%g6, [%%sp + 2047 + 0x180]\n"
-"	stx	%%g7, [%%sp + 2047 + 0x188]\n"
-"					! restore Linux mmu globals\n"
-"	ldx	[%%sp + 2047 + 0x238], %%o0\n"
-"	ldx	[%%sp + 2047 + 0x240], %%o1\n"
-"	ldx	[%%sp + 2047 + 0x248], %%l2\n"
-"	ldx	[%%sp + 2047 + 0x250], %%l3\n"
-"	ldx	[%%sp + 2047 + 0x258], %%l5\n"
-"	ldx	[%%sp + 2047 + 0x260], %%l6\n"
-"	ldx	[%%sp + 2047 + 0x268], %%l7\n"
-"					! switch to Linux tba\n"
-"	sethi	%%hi(sparc64_ttable_tl0), %%l1\n"
-"	rdpr	%%tba, %%l0		! save PROM tba\n"
-"	mov	%%o0, %%g1\n"
-"	mov	%%o1, %%g2\n"
-"	mov	%%l2, %%g3\n"
-"	mov	%%l3, %%g4\n"
-"	mov	%%l5, %%g5\n"
-"	mov	%%l6, %%g6\n"
-"	mov	%%l7, %%g7\n"
-"	wrpr	%%l1, %%tba		! install Linux tba\n"
-"	wrpr	%%l4, 0, %%pstate	! restore PSTATE\n"
-"	call	prom_world\n"
-"	 mov	%%g0, %%o0\n"
-"	ldx	[%%i1 + 0x000], %%l2\n"
-"	call	%%l2\n"
-"	 mov	%%i0, %%o0\n"
-"	mov	%%o0, %%l1\n"
-"	call	prom_world\n"
-"	 or	%%g0, 1, %%o0\n"
-"	wrpr	%%g0, 0x14, %%pstate	! interrupts off\n"
-"					! restore PROM mmu globals\n"
-"	ldx	[%%sp + 2047 + 0x158], %%o0\n"
-"	ldx	[%%sp + 2047 + 0x160], %%o1\n"
-"	ldx	[%%sp + 2047 + 0x168], %%l2\n"
-"	ldx	[%%sp + 2047 + 0x170], %%l3\n"
-"	ldx	[%%sp + 2047 + 0x178], %%l5\n"
-"	ldx	[%%sp + 2047 + 0x180], %%l6\n"
-"	ldx	[%%sp + 2047 + 0x188], %%l7\n"
-"	wrpr	%%g0, 0x414, %%pstate	! restore PROM mmu globals\n"
-"	mov	%%o0, %%g1\n"
-"	mov	%%o1, %%g2\n"
-"	mov	%%l2, %%g3\n"
-"	mov	%%l3, %%g4\n"
-"	mov	%%l5, %%g5\n"
-"	mov	%%l6, %%g6\n"
-"	mov	%%l7, %%g7\n"
-"	wrpr	%%l0, %%tba		! restore PROM tba\n"
-"	wrpr	%%g0, 0x14, %%pstate	! restore PROM normal globals\n"
-"	ldx	[%%sp + 2047 + 0x120], %%g1\n"
-"	ldx	[%%sp + 2047 + 0x128], %%g2\n"
-"	ldx	[%%sp + 2047 + 0x130], %%g3\n"
-"	ldx	[%%sp + 2047 + 0x138], %%g4\n"
-"	ldx	[%%sp + 2047 + 0x140], %%g5\n"
-"	ldx	[%%sp + 2047 + 0x148], %%g6\n"
-"	ldx	[%%sp + 2047 + 0x150], %%g7\n"
-"	wrpr	%%g0, 0x814, %%pstate	! restore PROM interrupt globals\n"
-"	ldx	[%%sp + 2047 + 0x0e8], %%g1\n"
-"	ldx	[%%sp + 2047 + 0x0f0], %%g2\n"
-"	ldx	[%%sp + 2047 + 0x0f8], %%g3\n"
-"	ldx	[%%sp + 2047 + 0x100], %%g4\n"
-"	ldx	[%%sp + 2047 + 0x108], %%g5\n"
-"	ldx	[%%sp + 2047 + 0x110], %%g6\n"
-"	ldx	[%%sp + 2047 + 0x118], %%g7\n"
-"	wrpr	%%g0, 0x15, %%pstate	! restore PROM alternate globals\n"
-"	ldx	[%%sp + 2047 + 0x0b0], %%g1\n"
-"	ldx	[%%sp + 2047 + 0x0b8], %%g2\n"
-"	ldx	[%%sp + 2047 + 0x0c0], %%g3\n"
-"	ldx	[%%sp + 2047 + 0x0c8], %%g4\n"
-"	ldx	[%%sp + 2047 + 0x0d0], %%g5\n"
-"	ldx	[%%sp + 2047 + 0x0d8], %%g6\n"
-"	ldx	[%%sp + 2047 + 0x0e0], %%g7\n"
-"	wrpr	%%l4, 0, %%pstate\n"
-"	ret\n"
-"	 restore %%l1, 0, %%o0\n"
-"	" : : "r" (&p1275buf), "i" (PSTATE_PRIV));
-}
+extern void prom_cif_interface(void);
+extern void prom_cif_callback(void);
 
 /*
  * This provides SMP safety on the p1275buf. prom_callback() drops this lock
  * to allow recursuve acquisition.
  */
-spinlock_t prom_entry_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(prom_entry_lock);
 
 long p1275_cmd (char *service, long fmt, ...)
 {
diff -Nru a/arch/sparc64/solaris/ioctl.c b/arch/sparc64/solaris/ioctl.c
--- a/arch/sparc64/solaris/ioctl.c	2005-03-01 23:38:58 -08:00
+++ b/arch/sparc64/solaris/ioctl.c	2005-03-01 23:38:58 -08:00
@@ -298,7 +298,7 @@
 	if (! current->files->fd[fd] ||
 	    ! current->files->fd[fd]->f_dentry ||
 	    ! (ino = current->files->fd[fd]->f_dentry->d_inode) ||
-	    ! ino->i_sock) {
+	    ! S_ISSOCK(ino->i_mode)) {
 		spin_unlock(&current->files->file_lock);
 		return TBADF;
 	}
@@ -478,7 +478,7 @@
         struct module_info *mi;
 
         ino = filp->f_dentry->d_inode;
-        if (! ino->i_sock)
+        if (!S_ISSOCK(ino->i_mode))
 		return -EBADF;
         sock = filp->private_data;
         if (! sock) {
diff -Nru a/arch/sparc64/solaris/socksys.c b/arch/sparc64/solaris/socksys.c
--- a/arch/sparc64/solaris/socksys.c	2005-03-01 23:38:55 -08:00
+++ b/arch/sparc64/solaris/socksys.c	2005-03-01 23:38:55 -08:00
@@ -150,7 +150,7 @@
 	unsigned int mask = 0;
 
 	ino=filp->f_dentry->d_inode;
-	if (ino && ino->i_sock) {
+	if (ino && S_ISSOCK(ino->i_mode)) {
 		struct sol_socket_struct *sock;
 		sock = (struct sol_socket_struct*)filp->private_data;
 		if (sock && sock->pfirst) {
diff -Nru a/arch/sparc64/solaris/timod.c b/arch/sparc64/solaris/timod.c
--- a/arch/sparc64/solaris/timod.c	2005-03-01 23:38:56 -08:00
+++ b/arch/sparc64/solaris/timod.c	2005-03-01 23:38:56 -08:00
@@ -29,7 +29,7 @@
 
 asmlinkage int solaris_ioctl(unsigned int fd, unsigned int cmd, u32 arg);
 
-static spinlock_t timod_pagelock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(timod_pagelock);
 static char * page = NULL ;
 
 #ifndef DEBUG_SOLARIS_KMALLOC
@@ -853,9 +853,7 @@
 	if(!filp) goto out;
 
 	ino = filp->f_dentry->d_inode;
-	if (!ino) goto out;
-
-	if (!ino->i_sock)
+	if (!ino || !S_ISSOCK(ino->i_mode))
 		goto out;
 
 	ctlptr = (struct strbuf __user *)A(arg1);
@@ -923,7 +921,7 @@
 	ino = filp->f_dentry->d_inode;
 	if (!ino) goto out;
 
-	if (!ino->i_sock &&
+	if (!S_ISSOCK(ino->i_mode) &&
 		(imajor(ino) != 30 || iminor(ino) != 1))
 		goto out;
 
diff -Nru a/arch/um/Kconfig b/arch/um/Kconfig
--- a/arch/um/Kconfig	2005-03-01 23:38:57 -08:00
+++ b/arch/um/Kconfig	2005-03-01 23:38:57 -08:00
@@ -31,6 +31,10 @@
 	bool
 	default y
 
+config GENERIC_CALIBRATE_DELAY
+	bool
+	default y
+
 menu "UML-specific options"
 
 config MODE_TT
@@ -64,6 +68,18 @@
 	to CONFIG_MODE_TT).  Otherwise, it is safe to say Y.  Disabling this
 	option will shrink the UML binary slightly.
 
+source "arch/um/Kconfig_arch"
+
+config LD_SCRIPT_STATIC
+	bool
+	default y
+	depends on MODE_TT || STATIC_LINK
+
+config LD_SCRIPT_DYN
+	bool
+	default y
+	depends on !LD_SCRIPT_STATIC
+
 config NET
 	bool "Networking support"
 	help
@@ -74,7 +90,7 @@
 	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
-	of which are given in Documentation/Changes.
+	of which are given in <file:Documentation/Changes>.
 
 	For a general introduction to Linux networking, it is highly
 	recommended to read the NET-HOWTO, available from
@@ -114,7 +130,7 @@
 	by removing or changing anything in /proc which gives away the
 	identity of a UML.
 
-	See http://user-mode-linux.sf.net/hppfs.html for more information.
+	See <http://user-mode-linux.sf.net/hppfs.html> for more information.
 
 	You only need this if you are setting up a UML honeypot.  Otherwise,
 	it is safe to say 'N' here.
@@ -139,6 +155,25 @@
 
         It is safe to say 'Y' here.
 
+config MAGIC_SYSRQ
+	bool "Magic SysRq key"
+	depends on MCONSOLE
+	---help---
+	If you say Y here, you will have some control over the system even
+	if the system crashes for example during kernel debugging (e.g., you
+	will be able to flush the buffer cache to disk, reboot the system
+	immediately or dump some status information). A key for each of the
+	possible requests is provided.
+
+	This is the feature normally accomplished by pressing a key
+	while holding SysRq (Alt+PrintScreen).
+
+	On UML, this is accomplished by sending a "sysrq" command with
+	mconsole, followed by the letter for the requested command.
+
+	The keys are documented in <file:Documentation/sysrq.txt>. Don't say Y
+	unless you really know what this hack does.
+
 config HOST_2G_2G
 	bool "2G/2G host address space split"
 	default n
@@ -238,7 +273,7 @@
 
 source "arch/um/Kconfig_char"
 
-source "arch/um/Kconfig_block"
+source "drivers/block/Kconfig"
 
 config NETDEVICES
 	bool
@@ -278,6 +313,7 @@
 	source "drivers/mtd/Kconfig"
 endif
 
+#This is just to shut up some Kconfig warnings, so no prompt.
 config INPUT
 	bool
 	default n
diff -Nru a/arch/um/Kconfig_block b/arch/um/Kconfig_block
--- a/arch/um/Kconfig_block	2005-03-01 23:39:07 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,105 +0,0 @@
-
-menu "Block Devices"
-
-config BLK_DEV_UBD
-	bool "Virtual block device"
-	help
-        The User-Mode Linux port includes a driver called UBD which will let
-        you access arbitrary files on the host computer as block devices.
-        Unless you know that you do not need such virtual block devices say
-        Y here.
-
-config BLK_DEV_UBD_SYNC
-	bool "Always do synchronous disk IO for UBD"
-	depends on BLK_DEV_UBD
-	help
-        Writes to the virtual block device are not immediately written to the 
-	host's disk; this may cause problems if, for example, the 
-	User-Mode Linux 'Virtual Machine' uses a journalling filesystem and 
-	the host computer crashes.
-
-        Synchronous operation (i.e. always writing data to the host's disk
-        immediately) is configurable on a per-UBD basis by using a special
-        kernel command line option.  Alternatively, you can say Y here to
-        turn on synchronous operation by default for all block devices.
-
-        If you're running a journalling file system (like reiserfs, for
-        example) in your virtual machine, you will want to say Y here.  If
-        you care for the safety of the data in your virtual machine, Y is a
-        wise choice too.  In all other cases (for example, if you're just
-        playing around with User-Mode Linux) you can choose N.
-
-config BLK_DEV_COW_COMMON
-	bool
-	default BLK_DEV_UBD
-
-config BLK_DEV_LOOP
-	tristate "Loopback device support"
-
-config BLK_DEV_NBD
-	tristate "Network block device support"
-	depends on NET
-
-config BLK_DEV_RAM
-	tristate "RAM disk support"
-
-config BLK_DEV_RAM_COUNT
-	int "Default number of RAM disks" if BLK_DEV_RAM
-	default "16"
-
-config BLK_DEV_RAM_SIZE
-	int "Default RAM disk size"
-	depends on BLK_DEV_RAM
-	default "4096"
-
-config BLK_DEV_INITRD
-	bool "Initial RAM disk (initrd) support"
-	depends on BLK_DEV_RAM=y
-
-#Copied directly from drivers/block/Kconfig
-config INITRAMFS_SOURCE
-	string "Source directory of cpio_list"
-	default ""
-	help
-	  This can be set to either a directory containing files, etc to be
-	  included in the initramfs archive, or a file containing newline
-	  separated entries.
-
-	  If it is a file, it should be in the following format:
-	    # a comment
-	    file <name> <location> <mode> <uid> <gid>
-	    dir <name> <mode> <uid> <gid>
-	    nod <name> <mode> <uid> <gid> <dev_type> <maj> <min>
-
-	  Where:
-	    <name>      name of the file/dir/nod in the archive
-	    <location>  location of the file in the current filesystem
-	    <mode>      mode/permissions of the file
-	    <uid>       user id (0=root)
-	    <gid>       group id (0=root)
-	    <dev_type>  device type (b=block, c=character)
-	    <maj>       major number of nod
-	    <min>       minor number of nod
-
-	  If you are not sure, leave it blank.
-
-config MMAPPER
-	tristate "Example IO memory driver"
-	depends on BROKEN
-	help
-        The User-Mode Linux port can provide support for IO Memory
-        emulation with this option.  This allows a host file to be
-        specified as an I/O region on the kernel command line. That file
-        will be mapped into UML's kernel address space where a driver can
-        locate it and do whatever it wants with the memory, including
-        providing an interface to it for UML processes to use.
-
-        For more information, see
-        <http://user-mode-linux.sourceforge.net/iomem.html>.
-
-        If you'd like to be able to provide a simulated IO port space for
-        User-Mode Linux processes, say Y.  If unsure, say N.
-
-source "drivers/block/Kconfig.iosched"
-
-endmenu
diff -Nru a/arch/um/Kconfig_char b/arch/um/Kconfig_char
--- a/arch/um/Kconfig_char	2005-03-01 23:38:56 -08:00
+++ b/arch/um/Kconfig_char	2005-03-01 23:38:56 -08:00
@@ -1,6 +1,12 @@
 
 menu "Character Devices"
 
+config STDERR_CONSOLE
+	bool "stderr console"
+	default y
+	help
+	console driver which dumps all printk messages to stderr.
+
 config STDIO_CONSOLE
 	bool
 	default y
@@ -17,15 +23,6 @@
 
         Unless you have a specific reason for disabling this, say Y.
 
-config FD_CHAN
-	bool "file descriptor channel support"
-	help
-        This option enables support for attaching UML consoles and serial
-        lines to already set up file descriptors.  Generally, the main
-        console is attached to file descriptors 0 and 1 (stdin and stdout),
-        so it would be wise to leave this enabled unless you intend to
-        attach it to some other host device.
-
 config NULL_CHAN
 	bool "null channel support"
 	help
@@ -74,7 +71,7 @@
 
 config NOCONFIG_CHAN
 	bool
-	default !(XTERM_CHAN && TTY_CHAN && PTY_CHAN && PORT_CHAN && FD_CHAN && NULL_CHAN)
+	default !(XTERM_CHAN && TTY_CHAN && PTY_CHAN && PORT_CHAN && NULL_CHAN)
 
 config CON_ZERO_CHAN
 	string "Default main console channel initialization"
diff -Nru a/arch/um/Kconfig_i386 b/arch/um/Kconfig_i386
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/um/Kconfig_i386	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,24 @@
+config 64_BIT
+	bool
+	default n
+
+config TOP_ADDR
+ 	hex
+ 	default 0xc0000000 if !HOST_2G_2G
+ 	default 0x80000000 if HOST_2G_2G
+
+config 3_LEVEL_PGTABLES
+	bool "Three-level pagetables"
+	default n
+	help
+	Three-level pagetables will let UML have more than 4G of physical
+	memory.  All the memory that can't be mapped directly will be treated
+	as high memory.
+
+config ARCH_HAS_SC_SIGNALS
+	bool
+	default y
+
+config ARCH_REUSE_HOST_VSYSCALL_AREA
+	bool
+	default y
diff -Nru a/arch/um/Kconfig_x86_64 b/arch/um/Kconfig_x86_64
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/um/Kconfig_x86_64	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,15 @@
+config 64_BIT
+	bool
+	default y
+
+config 3_LEVEL_PGTABLES
+       bool
+       default y
+
+config ARCH_HAS_SC_SIGNALS
+	bool
+	default n
+
+config ARCH_REUSE_HOST_VSYSCALL_AREA
+	bool
+	default n
diff -Nru a/arch/um/Makefile b/arch/um/Makefile
--- a/arch/um/Makefile	2005-03-01 23:39:07 -08:00
+++ b/arch/um/Makefile	2005-03-01 23:39:07 -08:00
@@ -3,7 +3,7 @@
 # Licensed under the GPL
 #
 
-ARCH_DIR = arch/um
+ARCH_DIR := arch/um
 OS := $(shell uname -s)
 # We require bash because the vmlinux link and loader script cpp use bash
 # features.
@@ -13,30 +13,43 @@
 
 core-y			+= $(ARCH_DIR)/kernel/		\
 			   $(ARCH_DIR)/drivers/		\
-			   $(ARCH_DIR)/sys-$(SUBARCH)/
+			   $(ARCH_DIR)/os-$(OS)/
 
 # Have to precede the include because the included Makefiles reference them.
-SYMLINK_HEADERS = archparam.h system.h sigcontext.h processor.h ptrace.h \
-	arch-signal.h module.h
+SYMLINK_HEADERS := archparam.h system.h sigcontext.h processor.h ptrace.h \
+	arch-signal.h module.h vm-flags.h
 SYMLINK_HEADERS := $(foreach header,$(SYMLINK_HEADERS),include/asm-um/$(header))
 
+# XXX: The "os" symlink is only used by arch/um/include/os.h, which includes
+# ../os/include/file.h
+#
+# These are cleaned up during mrproper. Please DO NOT fix it again, this is
+# the Correct Thing(tm) to do!
 ARCH_SYMLINKS = include/asm-um/arch $(ARCH_DIR)/include/sysdep $(ARCH_DIR)/os \
 	$(SYMLINK_HEADERS) $(ARCH_DIR)/include/uml-config.h
 
 GEN_HEADERS += $(ARCH_DIR)/include/task.h $(ARCH_DIR)/include/kern_constants.h
 
-MAKEFILE-$(CONFIG_MODE_TT) += Makefile-tt
-MAKEFILE-$(CONFIG_MODE_SKAS) += Makefile-skas
+um-modes-$(CONFIG_MODE_TT) += tt
+um-modes-$(CONFIG_MODE_SKAS) += skas
 
-ifneq ($(MAKEFILE-y),)
-  include $(addprefix $(srctree)/$(ARCH_DIR)/,$(MAKEFILE-y))
+MODE_INCLUDE	+= $(foreach mode,$(um-modes-y),\
+		   -I$(srctree)/$(ARCH_DIR)/kernel/$(mode)/include)
+
+MAKEFILES-INCL	+= $(foreach mode,$(um-modes-y),\
+		   $(srctree)/$(ARCH_DIR)/Makefile-$(mode))
+
+ifneq ($(MAKEFILES-INCL),)
+  include $(MAKEFILES-INCL)
 endif
 
 ARCH_INCLUDE	:= -I$(ARCH_DIR)/include
 SYS_DIR		:= $(ARCH_DIR)/include/sysdep-$(SUBARCH)
 
 include $(srctree)/$(ARCH_DIR)/Makefile-$(SUBARCH)
-include $(srctree)/$(ARCH_DIR)/Makefile-os-$(OS)
+
+core-y += $(SUBARCH_CORE)
+libs-y += $(SUBARCH_LIBS)
 
 # -Derrno=kernel_errno - This turns all kernel references to errno into
 # kernel_errno to separate them from the libc errno.  This allows -fno-common
@@ -44,12 +57,16 @@
 # errnos.
 
 CFLAGS += $(CFLAGS-y) -D__arch_um__ -DSUBARCH=\"$(SUBARCH)\" \
-	-D_LARGEFILE64_SOURCE $(ARCH_INCLUDE) -Derrno=kernel_errno \
-	-Dsigprocmask=kernel_sigprocmask $(MODE_INCLUDE)
+	$(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,)
 
-LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc
+#This will adjust *FLAGS accordingly to the platform.
+include $(srctree)/$(ARCH_DIR)/Makefile-os-$(OS)
 
 # These are needed for clean and mrproper, since in that case .config is not
 # included; the values here are meaningless
@@ -77,31 +94,18 @@
   echo '		   find in the kernel root.'
 endef
 
+$(shell cd $(ARCH_DIR) && ln -sf Kconfig_$(SUBARCH) Kconfig_arch)
+
 prepare: $(ARCH_SYMLINKS) $(SYS_HEADERS) $(GEN_HEADERS) \
 	$(ARCH_DIR)/kernel/vmlinux.lds.S
 
-# These aren't in Makefile-tt because they are needed in the !CONFIG_MODE_TT +
-# CONFIG_MODE_SKAS + CONFIG_STATIC_LINK case.
-
-LINK_TT = -static
-LD_SCRIPT_TT := uml.lds.S
+LINK-$(CONFIG_LD_SCRIPT_STATIC) += -static
+LINK-$(CONFIG_LD_SCRIPT_DYN) += -Wl,-rpath,/lib
 
-ifeq ($(CONFIG_STATIC_LINK),y)
-  LINK-y += $(LINK_TT)
-  LD_SCRIPT-y := $(LD_SCRIPT_TT)
-else
-ifeq ($(CONFIG_MODE_TT),y)
-  LINK-y += $(LINK_TT)
-  LD_SCRIPT-y := $(LD_SCRIPT_TT)
-else
-ifeq ($(CONFIG_MODE_SKAS),y)
-  LINK-y += $(LINK_SKAS)
-  LD_SCRIPT-y := $(LD_SCRIPT_SKAS)
-endif
-endif
-endif
+LD_SCRIPT-$(CONFIG_LD_SCRIPT_STATIC) := uml.lds.S
+LD_SCRIPT-$(CONFIG_LD_SCRIPT_DYN) := dyn.lds.S
 
-CPP_MODE_TT := $(shell [ "$(CONFIG_MODE_TT)" = "y" ] && echo -DMODE_TT)
+CPP_MODE-$(CONFIG_MODE_TT) := -DMODE_TT
 CONFIG_KERNEL_STACK_ORDER ?= 2
 STACK_SIZE := $(shell echo $$[ 4096 * (1 << $(CONFIG_KERNEL_STACK_ORDER)) ] )
 
@@ -111,9 +115,12 @@
 
 CPPFLAGS_vmlinux.lds = $(shell echo -U$(SUBARCH) \
 	-DSTART=$(START) -DELF_ARCH=$(ELF_ARCH) \
-	-DELF_FORMAT=\"$(ELF_FORMAT)\" $(CPP_MODE_TT) \
+	-DELF_FORMAT=\"$(ELF_FORMAT)\" $(CPP_MODE-y) \
 	-DKERNEL_STACK_SIZE=$(STACK_SIZE))
 
+#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)
 define cmd_vmlinux__
 	$(CC) $(CFLAGS_vmlinux) -o $@ \
@@ -124,26 +131,14 @@
 	FORCE ,$^) ; rm -f linux
 endef
 
-USER_CFLAGS := $(patsubst -I%,,$(CFLAGS))
-USER_CFLAGS := $(patsubst -Derrno=kernel_errno,,$(USER_CFLAGS))
-USER_CFLAGS := $(patsubst -Dsigprocmask=kernel_sigprocmask,,$(USER_CFLAGS))
-USER_CFLAGS := $(patsubst -D__KERNEL__,,$(USER_CFLAGS)) $(ARCH_INCLUDE) \
-	$(MODE_INCLUDE)
-USER_CFLAGS += $(ARCH_USER_CFLAGS)
-
-# To get a definition of F_SETSIG
-USER_CFLAGS += -D_GNU_SOURCE
-
 #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
 
 MRPROPER_FILES += $(SYMLINK_HEADERS) $(ARCH_SYMLINKS) \
-	$(addprefix $(ARCH_DIR)/kernel/,$(KERN_SYMLINKS)) $(ARCH_DIR)/os
-
-archmrproper:
-	@:
+	$(addprefix $(ARCH_DIR)/kernel/,$(KERN_SYMLINKS)) $(ARCH_DIR)/os \
+	$(ARCH_DIR)/Kconfig_arch
 
 archclean:
 	$(Q)$(MAKE) $(clean)=$(ARCH_DIR)/util
@@ -151,11 +146,13 @@
 		-o -name '*.gcov' \) -type f -print | xargs rm -f
 
 #We need to re-preprocess this when the symlink dest changes.
-#So we touch it.
+#So we touch it when needed.
 $(ARCH_DIR)/kernel/vmlinux.lds.S: FORCE
-	@echo '  SYMLINK $@'
-	$(Q)ln -sf $(LD_SCRIPT-y) $@
-	$(Q)touch $@
+	$(Q)if [ "$(shell readlink $@)" != "$(LD_SCRIPT-y)" ]; then \
+		echo '  SYMLINK $@'; \
+		ln -sf $(LD_SCRIPT-y) $@; \
+		touch $@; \
+	fi;
 
 $(SYMLINK_HEADERS):
 	@echo '  SYMLINK $@'
diff -Nru a/arch/um/Makefile-i386 b/arch/um/Makefile-i386
--- a/arch/um/Makefile-i386	2005-03-01 23:39:09 -08:00
+++ b/arch/um/Makefile-i386	2005-03-01 23:39:09 -08:00
@@ -1,8 +1,6 @@
-ifeq ($(CONFIG_HOST_2G_2G), y)
-TOP_ADDR := 0x80000000
-else
-TOP_ADDR := 0xc0000000
-endif
+SUBARCH_CORE := arch/um/sys-i386/
+
+TOP_ADDR := $(CONFIG_TOP_ADDR)
 
 ifeq ($(CONFIG_MODE_SKAS),y)
   ifneq ($(CONFIG_MODE_TT),y)
diff -Nru a/arch/um/Makefile-os-Linux b/arch/um/Makefile-os-Linux
--- a/arch/um/Makefile-os-Linux	2005-03-01 23:39:18 -08:00
+++ b/arch/um/Makefile-os-Linux	2005-03-01 23:39:18 -08:00
@@ -3,4 +3,6 @@
 # Licensed under the GPL
 #
 
-core-y		+= $(ARCH_DIR)/os-$(OS)/
+# To get a definition of F_SETSIG
+USER_CFLAGS += -D_GNU_SOURCE -D_LARGEFILE64_SOURCE
+CFLAGS += -D_LARGEFILE64_SOURCE
diff -Nru a/arch/um/Makefile-skas b/arch/um/Makefile-skas
--- a/arch/um/Makefile-skas	2005-03-01 23:38:56 -08:00
+++ b/arch/um/Makefile-skas	2005-03-01 23:38:56 -08:00
@@ -9,9 +9,4 @@
 CFLAGS-$(CONFIG_GPROF) += $(PROFILE)
 LINK-$(CONFIG_GPROF) += $(PROFILE)
 
-MODE_INCLUDE += -I$(srctree)/$(ARCH_DIR)/kernel/skas/include
-
-LINK_SKAS = -Wl,-rpath,/lib 
-LD_SCRIPT_SKAS = dyn.lds.S
-
 GEN_HEADERS += $(ARCH_DIR)/include/skas_ptregs.h
diff -Nru a/arch/um/Makefile-tt b/arch/um/Makefile-tt
--- a/arch/um/Makefile-tt	2005-03-01 23:39:09 -08:00
+++ b/arch/um/Makefile-tt	2005-03-01 23:39:09 -08:00
@@ -3,4 +3,3 @@
 # Licensed under the GPL
 #
 
-MODE_INCLUDE += -I$(srctree)/$(ARCH_DIR)/kernel/tt/include
diff -Nru a/arch/um/Makefile-x86_64 b/arch/um/Makefile-x86_64
--- a/arch/um/Makefile-x86_64	2005-03-01 23:39:16 -08:00
+++ b/arch/um/Makefile-x86_64	2005-03-01 23:39:16 -08:00
@@ -1 +1,36 @@
+# Copyright 2003 - 2004 Pathscale, Inc
+# Released under the GPL
+
+SUBARCH_LIBS := arch/um/sys-x86_64/
+START := 0x60000000
+
+CFLAGS += -U__$(SUBARCH)__ -fno-builtin
 ARCH_USER_CFLAGS := -D__x86_64__
+
+ELF_ARCH := i386:x86-64
+ELF_FORMAT := elf64-x86-64
+
+SYS_UTIL_DIR := $(ARCH_DIR)/sys-x86_64/util
+SYS_DIR := $(ARCH_DIR)/include/sysdep-x86_64
+
+SYS_HEADERS = $(SYS_DIR)/sc.h $(SYS_DIR)/thread.h
+
+prepare: $(SYS_HEADERS)
+
+$(SYS_DIR)/sc.h: $(SYS_UTIL_DIR)/mk_sc
+	$(call filechk,gen_header)
+
+$(SYS_DIR)/thread.h: $(SYS_UTIL_DIR)/mk_thread
+	$(call filechk,gen_header)
+
+$(SYS_UTIL_DIR)/mk_sc: scripts_basic FORCE
+	$(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@
+
+$(SYS_UTIL_DIR)/mk_thread: scripts_basic $(ARCH_SYMLINKS) $(GEN_HEADERS) FORCE
+	$(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@
+
+CLEAN_FILES += $(SYS_HEADERS)
+
+LIBC_DIR := /usr/lib64
+
+export LIBC_DIR
diff -Nru a/arch/um/defconfig b/arch/um/defconfig
--- a/arch/um/defconfig	2005-03-01 23:39:07 -08:00
+++ b/arch/um/defconfig	2005-03-01 23:39:07 -08:00
@@ -1,11 +1,13 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc1-mm5
-# Sun Nov 14 15:27:58 2004
+# Linux kernel version: 2.6.10-rc2-mm4
+# Wed Dec  1 13:45:40 2004
 #
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_USERMODE=y
 CONFIG_MMU=y
+# CONFIG_64_BIT is not set
+CONFIG_TOP_ADDR=0xc0000000
 CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
@@ -15,6 +17,7 @@
 #
 CONFIG_MODE_TT=y
 CONFIG_MODE_SKAS=y
+# CONFIG_3_LEVEL_PGTABLES is not set
 CONFIG_NET=y
 CONFIG_BINFMT_ELF=y
 CONFIG_BINFMT_MISC=m
@@ -24,6 +27,7 @@
 # CONFIG_SMP is not set
 CONFIG_NEST_LEVEL=0
 CONFIG_KERNEL_HALF_GIGS=1
+# CONFIG_HIGHMEM is not set
 CONFIG_KERNEL_STACK_ORDER=2
 CONFIG_UML_REAL_TIME_CLOCK=y
 
@@ -85,15 +89,15 @@
 #
 # Character Devices
 #
+CONFIG_STDERR_CONSOLE=y
 CONFIG_STDIO_CONSOLE=y
 CONFIG_SSL=y
-CONFIG_FD_CHAN=y
 CONFIG_NULL_CHAN=y
 CONFIG_PORT_CHAN=y
 CONFIG_PTY_CHAN=y
 CONFIG_TTY_CHAN=y
 CONFIG_XTERM_CHAN=y
-# CONFIG_NOCONFIG_CHAN is not set
+CONFIG_NOCONFIG_CHAN=y
 CONFIG_CON_ZERO_CHAN="fd:0,fd:1"
 CONFIG_CON_CHAN="xterm"
 CONFIG_SSL_CHAN="pty"
@@ -113,9 +117,7 @@
 CONFIG_BLK_DEV_COW_COMMON=y
 CONFIG_BLK_DEV_LOOP=m
 CONFIG_BLK_DEV_NBD=m
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_BLK_DEV_INITRD=y
+# CONFIG_BLK_DEV_RAM is not set
 CONFIG_INITRAMFS_SOURCE=""
 
 #
diff -Nru a/arch/um/drivers/Makefile b/arch/um/drivers/Makefile
--- a/arch/um/drivers/Makefile	2005-03-01 23:39:18 -08:00
+++ b/arch/um/drivers/Makefile	2005-03-01 23:39:18 -08:00
@@ -20,8 +20,10 @@
 port-objs := port_kern.o port_user.o
 harddog-objs := harddog_kern.o harddog_user.o
 
-obj-y = 
-obj-$(CONFIG_SSL) += ssl.o 
+obj-y := stdio_console.o fd.o $(CHAN_OBJS)
+obj-$(CONFIG_SSL) += ssl.o
+obj-$(CONFIG_STDERR_CONSOLE) += stderr_console.o
+
 obj-$(CONFIG_UML_NET_SLIP) += slip.o
 obj-$(CONFIG_UML_NET_SLIRP) += slirp.o
 obj-$(CONFIG_UML_NET_DAEMON) += daemon.o 
@@ -32,7 +34,6 @@
 obj-$(CONFIG_MMAPPER) += mmapper_kern.o 
 obj-$(CONFIG_BLK_DEV_UBD) += ubd.o 
 obj-$(CONFIG_HOSTAUDIO) += hostaudio.o
-obj-$(CONFIG_FD_CHAN) += fd.o 
 obj-$(CONFIG_NULL_CHAN) += null.o 
 obj-$(CONFIG_PORT_CHAN) += port.o
 obj-$(CONFIG_PTY_CHAN) += pty.o
@@ -41,7 +42,6 @@
 obj-$(CONFIG_UML_WATCHDOG) += harddog.o
 obj-$(CONFIG_BLK_DEV_COW_COMMON) += cow_user.o
 
-obj-y += stdio_console.o $(CHAN_OBJS)
 
 USER_SINGLE_OBJS = $(foreach f,$(patsubst %.o,%,$(obj-y) $(obj-m)),$($(f)-objs))
 
diff -Nru a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c
--- a/arch/um/drivers/chan_kern.c	2005-03-01 23:39:17 -08:00
+++ b/arch/um/drivers/chan_kern.c	2005-03-01 23:39:17 -08:00
@@ -189,7 +189,7 @@
 	return(err);
 }
 
-void chan_enable_winch(struct list_head *chans, void *line)
+void chan_enable_winch(struct list_head *chans, struct tty_struct *tty)
 {
 	struct list_head *ele;
 	struct chan *chan;
@@ -197,13 +197,13 @@
 	list_for_each(ele, chans){
 		chan = list_entry(ele, struct chan, list);
 		if(chan->primary && chan->output && chan->ops->winch){
-			register_winch(chan->fd, line);
+			register_winch(chan->fd, tty);
 			return;
 		}
 	}
 }
 
-void enable_chan(struct list_head *chans, void *data)
+void enable_chan(struct list_head *chans, struct tty_struct *tty)
 {
 	struct list_head *ele;
 	struct chan *chan;
@@ -212,7 +212,7 @@
 		chan = list_entry(ele, struct chan, list);
 		if(!chan->opened) continue;
 
-		line_setup_irq(chan->fd, chan->input, chan->output, data);
+		line_setup_irq(chan->fd, chan->input, chan->output, tty);
 	}
 }
 
@@ -240,18 +240,20 @@
 	       int write_irq)
 {
 	struct list_head *ele;
-	struct chan *chan;
+	struct chan *chan = NULL;
 	int n, ret = 0;
 
-	list_for_each(ele, chans){
+	list_for_each(ele, chans) {
 		chan = list_entry(ele, struct chan, list);
-		if(!chan->output || (chan->ops->write == NULL)) continue;
+		if (!chan->output || (chan->ops->write == NULL))
+			continue;
 		n = chan->ops->write(chan->fd, buf, len, chan->data);
-		if(chan->primary){
+		if (chan->primary) {
 			ret = n;
-			if((ret == -EAGAIN) || ((ret >= 0) && (ret < len))){
+			if ((ret == -EAGAIN) || ((ret >= 0) && (ret < len))){
 				reactivate_fd(chan->fd, write_irq);
-				if(ret == -EAGAIN) ret = 0;
+				if (ret == -EAGAIN)
+					ret = 0;
 			}
 		}
 	}
@@ -274,6 +276,20 @@
 	return(ret);
 }
 
+int console_open_chan(struct line *line, struct console *co, struct chan_opts *opts)
+{
+	if (!list_empty(&line->chan_list))
+		return 0;
+
+	if (0 != parse_chan_pair(line->init_str, &line->chan_list,
+				 line->init_pri, co->index, opts))
+		return -1;
+	if (0 != open_chan(&line->chan_list))
+		return -1;
+	printk("Console initialized on /dev/%s%d\n",co->name,co->index);
+	return 0;
+}
+
 int chan_window_size(struct list_head *chans, unsigned short *rows_out,
 		      unsigned short *cols_out)
 {
@@ -383,11 +399,7 @@
 };
 
 struct chan_type chan_table[] = {
-#ifdef CONFIG_FD_CHAN
 	{ "fd", &fd_ops },
-#else
-	{ "fd", &not_configged_ops },
-#endif
 
 #ifdef CONFIG_NULL_CHAN
 	{ "null", &null_ops },
@@ -516,7 +528,7 @@
 }
 
 void chan_interrupt(struct list_head *chans, struct work_struct *task,
-		    struct tty_struct *tty, int irq, void *dev)
+		    struct tty_struct *tty, int irq)
 {
 	struct list_head *ele, *next;
 	struct chan *chan;
@@ -542,7 +554,7 @@
 			if(chan->primary){
 				if(tty != NULL)
 					tty_hangup(tty);
-				line_disable(dev, irq);
+				line_disable(tty, irq);
 				close_chan(chans);
 				free_chan(chans);
 				return;
diff -Nru a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c
--- a/arch/um/drivers/chan_user.c	2005-03-01 23:38:51 -08:00
+++ b/arch/um/drivers/chan_user.c	2005-03-01 23:38:51 -08:00
@@ -49,6 +49,24 @@
 	return(-errno);
 }
 
+/*
+ * UML SIGWINCH handling
+ *
+ * The point of this is to handle SIGWINCH on consoles which have host ttys and
+ * relay them inside UML to whatever might be running on the console and cares
+ * about the window size (since SIGWINCH notifies about terminal size changes).
+ *
+ * So, we have a separate thread for each host tty attached to a UML device
+ * (side-issue - I'm annoyed that one thread can't have multiple controlling
+ * ttys for purposed of handling SIGWINCH, but I imagine there are other reasons
+ * that doesn't make any sense).
+ *
+ * SIGWINCH can't be received synchronously, so you have to set up to receive it
+ * as a signal.  That being the case, if you are going to wait for it, it is
+ * convenient to sit in a pause() and wait for the signal to bounce you out of
+ * it (see below for how we make sure to exit only on SIGWINCH).
+ */
+
 static void winch_handler(int sig)
 {
 }
@@ -75,9 +93,14 @@
 		printk("winch_thread : failed to write synchronization "
 		       "byte, err = %d\n", -count);
 
+	/* We are not using SIG_IGN on purpose, so don't fix it as I thought to
+	 * do! If using SIG_IGN, the pause() call below would not stop on
+	 * SIGWINCH. */
+
 	signal(SIGWINCH, winch_handler);
 	sigfillset(&sigs);
 	sigdelset(&sigs, SIGWINCH);
+	/* Block anything else than SIGWINCH. */
 	if(sigprocmask(SIG_SETMASK, &sigs, NULL) < 0){
 		printk("winch_thread : sigprocmask failed, errno = %d\n", 
 		       errno);
@@ -95,12 +118,18 @@
 		exit(1);
 	}
 
+	/* These are synchronization calls between various UML threads on the
+	 * host - since they are not different kernel threads, we cannot use
+	 * kernel semaphores. We don't use SysV semaphores because they are
+	 * persistant. */
 	count = os_read_file(pipe_fd, &c, sizeof(c));
 	if(count != sizeof(c))
 		printk("winch_thread : failed to read synchronization byte, "
 		       "err = %d\n", -count);
 
 	while(1){
+		/* This will be interrupted by SIGWINCH only, since other signals
+		 * are blocked.*/
 		pause();
 
 		count = os_write_file(pipe_fd, &c, sizeof(c));
@@ -110,7 +139,7 @@
 	}
 }
 
-static int winch_tramp(int fd, void *device_data, int *fd_out)
+static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out)
 {
 	struct winch_data data;
 	unsigned long stack;
@@ -144,7 +173,7 @@
 	return(pid);
 }
 
-void register_winch(int fd, void *device_data)
+void register_winch(int fd, struct tty_struct *tty)
 {
 	int pid, thread, thread_fd;
 	int count;
@@ -155,10 +184,10 @@
 
 	pid = tcgetpgrp(fd);
 	if(!CHOOSE_MODE_PROC(is_tracer_winch, is_skas_winch, pid, fd,
-			     device_data) && (pid == -1)){
-		thread = winch_tramp(fd, device_data, &thread_fd);
+			     tty) && (pid == -1)){
+		thread = winch_tramp(fd, tty, &thread_fd);
 		if(fd != -1){
-			register_winch_irq(thread_fd, fd, thread, device_data);
+			register_winch_irq(thread_fd, fd, thread, tty);
 
 			count = os_write_file(thread_fd, &c, sizeof(c));
 			if(count != sizeof(c))
diff -Nru a/arch/um/drivers/cow.h b/arch/um/drivers/cow.h
--- a/arch/um/drivers/cow.h	2005-03-01 23:39:17 -08:00
+++ b/arch/um/drivers/cow.h	2005-03-01 23:39:17 -08:00
@@ -21,11 +21,12 @@
 extern int read_cow_header(int (*reader)(__u64, char *, int, void *),
 			   void *arg, __u32 *version_out,
 			   char **backing_file_out, time_t *mtime_out,
-			   __u64 *size_out, int *sectorsize_out,
+			   unsigned long long *size_out, int *sectorsize_out,
 			   __u32 *align_out, int *bitmap_offset_out);
 
 extern int write_cow_header(char *cow_file, int fd, char *backing_file,
-			    int sectorsize, int alignment, long long *size);
+			    int sectorsize, int alignment,
+			    unsigned long long *size);
 
 extern void cow_sizes(int version, __u64 size, int sectorsize, int align,
 		      int bitmap_offset, unsigned long *bitmap_len_out,
diff -Nru a/arch/um/drivers/cow_sys.h b/arch/um/drivers/cow_sys.h
--- a/arch/um/drivers/cow_sys.h	2005-03-01 23:39:18 -08:00
+++ b/arch/um/drivers/cow_sys.h	2005-03-01 23:39:18 -08:00
@@ -23,12 +23,12 @@
 	return(uml_strdup(str));
 }
 
-static inline int cow_seek_file(int fd, __u64 offset)
+static inline int cow_seek_file(int fd, unsigned long long offset)
 {
 	return(os_seek_file(fd, offset));
 }
 
-static inline int cow_file_size(char *file, __u64 *size_out)
+static inline int cow_file_size(char *file, unsigned long long *size_out)
 {
 	return(os_file_size(file, size_out));
 }
diff -Nru a/arch/um/drivers/cow_user.c b/arch/um/drivers/cow_user.c
--- a/arch/um/drivers/cow_user.c	2005-03-01 23:38:58 -08:00
+++ b/arch/um/drivers/cow_user.c	2005-03-01 23:38:58 -08:00
@@ -159,7 +159,7 @@
 }
 
 int write_cow_header(char *cow_file, int fd, char *backing_file,
-		     int sectorsize, int alignment, long long *size)
+		     int sectorsize, int alignment, unsigned long long *size)
 {
 	struct cow_header_v3 *header;
 	unsigned long modtime;
@@ -236,7 +236,7 @@
 
 int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg,
 		    __u32 *version_out, char **backing_file_out,
-		    time_t *mtime_out, __u64 *size_out,
+		    time_t *mtime_out, unsigned long long *size_out,
 		    int *sectorsize_out, __u32 *align_out,
 		    int *bitmap_offset_out)
 {
@@ -329,7 +329,7 @@
 		  int alignment, int *bitmap_offset_out,
 		  unsigned long *bitmap_len_out, int *data_offset_out)
 {
-	__u64 size, offset;
+	unsigned long long size, offset;
 	char zero = 0;
 	int err;
 
diff -Nru a/arch/um/drivers/line.c b/arch/um/drivers/line.c
--- a/arch/um/drivers/line.c	2005-03-01 23:39:10 -08:00
+++ b/arch/um/drivers/line.c	2005-03-01 23:39:10 -08:00
@@ -6,6 +6,7 @@
 #include "linux/sched.h"
 #include "linux/slab.h"
 #include "linux/list.h"
+#include "linux/kd.h"
 #include "linux/interrupt.h"
 #include "linux/devfs_fs_kernel.h"
 #include "asm/uaccess.h"
@@ -22,30 +23,33 @@
 
 static irqreturn_t line_interrupt(int irq, void *data, struct pt_regs *unused)
 {
-	struct line *dev = data;
+	struct tty_struct *tty = data;
+	struct line *line = tty->driver_data;
 
-	if(dev->count > 0) 
-		chan_interrupt(&dev->chan_list, &dev->task, dev->tty, irq, 
-			       dev);
+	if (line)
+		chan_interrupt(&line->chan_list, &line->task, tty, irq);
 	return IRQ_HANDLED;
 }
 
 static void line_timer_cb(void *arg)
 {
-	struct line *dev = arg;
+	struct tty_struct *tty = arg;
+	struct line *line = tty->driver_data;
 
-	line_interrupt(dev->driver->read_irq, dev, NULL);
+	line_interrupt(line->driver->read_irq, arg, NULL);
 }
 
 static int write_room(struct line *dev)
 {
 	int n;
 
-	if(dev->buffer == NULL) return(LINE_BUFSIZE - 1);
+	if (dev->buffer == NULL)
+		return (LINE_BUFSIZE - 1);
 
 	n = dev->head - dev->tail;
-	if(n <= 0) n = LINE_BUFSIZE + n;
-	return(n - 1);
+	if (n <= 0)
+		n = LINE_BUFSIZE + n;
+	return (n - 1);
 }
 
 static int buffer_data(struct line *line, const char *buf, int len)
@@ -54,7 +58,7 @@
 
 	if(line->buffer == NULL){
 		line->buffer = kmalloc(LINE_BUFSIZE, GFP_ATOMIC);
-		if(line->buffer == NULL){
+		if (line->buffer == NULL) {
 			printk("buffer_data - atomic allocation failed\n");
 			return(0);
 		}
@@ -84,14 +88,17 @@
 {
 	int n, count;
 
-	if((line->buffer == NULL) || (line->head == line->tail)) return(1);
+	if ((line->buffer == NULL) || (line->head == line->tail))
+		return(1);
 
-	if(line->tail < line->head){
+	if (line->tail < line->head) {
 		count = line->buffer + LINE_BUFSIZE - line->head;
 		n = write_chan(&line->chan_list, line->head, count,
 			       line->driver->write_irq);
-		if(n < 0) return(n);
-		if(n == count) line->head = line->buffer;
+		if (n < 0)
+			return(n);
+		if (n == count)
+			line->head = line->buffer;
 		else {
 			line->head += n;
 			return(0);
@@ -107,25 +114,22 @@
 	return(line->head == line->tail);
 }
 
-int line_write(struct line *lines, struct tty_struct *tty, const char *buf, int len)
+int line_write(struct tty_struct *tty, const unsigned char *buf, int len)
 {
-	struct line *line;
+	struct line *line = tty->driver_data;
 	unsigned long flags;
-	int n, err, i, ret = 0;
+	int n, err, ret = 0;
 
 	if(tty->stopped) return 0;
 
-	i = tty->index;
-	line = &lines[i];
-
 	down(&line->sem);
 	if(line->head != line->tail){
 		local_irq_save(flags);
-		ret += buffer_data(line, buf, len);
+		ret = buffer_data(line, buf, len);
 		err = flush_buffer(line);
 		local_irq_restore(flags);
 		if(err <= 0)
-			goto out_up;
+			ret = err;
 	}
 	else {
 		n = write_chan(&line->chan_list, buf, len, 
@@ -145,19 +149,123 @@
 	return(ret);
 }
 
+void line_put_char(struct tty_struct *tty, unsigned char ch)
+{
+	line_write(tty, &ch, sizeof(ch));
+}
+
+void line_set_termios(struct tty_struct *tty, struct termios * old)
+{
+	/* nothing */
+}
+
+int line_chars_in_buffer(struct tty_struct *tty)
+{
+	return 0;
+}
+
+static struct {
+	int  cmd;
+	char *level;
+	char *name;
+} tty_ioctls[] = {
+	/* don't print these, they flood the log ... */
+	{ TCGETS,      NULL,       "TCGETS"      },
+        { TCSETS,      NULL,       "TCSETS"      },
+        { TCSETSW,     NULL,       "TCSETSW"     },
+        { TCFLSH,      NULL,       "TCFLSH"      },
+        { TCSBRK,      NULL,       "TCSBRK"      },
+
+	/* general tty stuff */
+        { TCSETSF,     KERN_DEBUG, "TCSETSF"     },
+        { TCGETA,      KERN_DEBUG, "TCGETA"      },
+        { TIOCMGET,    KERN_DEBUG, "TIOCMGET"    },
+        { TCSBRKP,     KERN_DEBUG, "TCSBRKP"     },
+        { TIOCMSET,    KERN_DEBUG, "TIOCMSET"    },
+
+	/* linux-specific ones */
+	{ TIOCLINUX,   KERN_INFO,  "TIOCLINUX"   },
+	{ KDGKBMODE,   KERN_INFO,  "KDGKBMODE"   },
+	{ KDGKBTYPE,   KERN_INFO,  "KDGKBTYPE"   },
+	{ KDSIGACCEPT, KERN_INFO,  "KDSIGACCEPT" },
+};
+
+int line_ioctl(struct tty_struct *tty, struct file * file,
+	       unsigned int cmd, unsigned long arg)
+{
+	int ret;
+	int i;
+
+	ret = 0;
+	switch(cmd) {
+#ifdef TIOCGETP
+	case TIOCGETP:
+	case TIOCSETP:
+	case TIOCSETN:
+#endif
+#ifdef TIOCGETC
+	case TIOCGETC:
+	case TIOCSETC:
+#endif
+#ifdef TIOCGLTC
+	case TIOCGLTC:
+	case TIOCSLTC:
+#endif
+	case TCGETS:
+	case TCSETSF:
+	case TCSETSW:
+	case TCSETS:
+	case TCGETA:
+	case TCSETAF:
+	case TCSETAW:
+	case TCSETA:
+	case TCXONC:
+	case TCFLSH:
+	case TIOCOUTQ:
+	case TIOCINQ:
+	case TIOCGLCKTRMIOS:
+	case TIOCSLCKTRMIOS:
+	case TIOCPKT:
+	case TIOCGSOFTCAR:
+	case TIOCSSOFTCAR:
+		return -ENOIOCTLCMD;
+#if 0
+	case TCwhatever:
+		/* do something */
+		break;
+#endif
+	default:
+		for (i = 0; i < ARRAY_SIZE(tty_ioctls); i++)
+			if (cmd == tty_ioctls[i].cmd)
+				break;
+		if (i < ARRAY_SIZE(tty_ioctls)) {
+			if (NULL != tty_ioctls[i].level)
+				printk("%s%s: %s: ioctl %s called\n",
+				       tty_ioctls[i].level, __FUNCTION__,
+				       tty->name, tty_ioctls[i].name);
+		} else {
+			printk(KERN_ERR "%s: %s: unknown ioctl: 0x%x\n",
+			       __FUNCTION__, tty->name, cmd);
+		}
+		ret = -ENOIOCTLCMD;
+		break;
+	}
+	return(ret);
+}
+
 static irqreturn_t line_write_interrupt(int irq, void *data,
 					struct pt_regs *unused)
 {
-	struct line *dev = data;
-	struct tty_struct *tty = dev->tty;
+	struct tty_struct *tty = data;
+	struct line *line = tty->driver_data;
 	int err;
 
-	err = flush_buffer(dev);
+	err = flush_buffer(line);
 	if(err == 0)
 		return(IRQ_NONE);
 	else if(err < 0){
-		dev->head = dev->buffer;
-		dev->tail = dev->buffer;
+		line->head = line->buffer;
+		line->tail = line->buffer;
 	}
 
 	if(tty == NULL)
@@ -178,39 +286,42 @@
 	return(IRQ_HANDLED);
 }
 
-int line_setup_irq(int fd, int input, int output, void *data)
+int line_setup_irq(int fd, int input, int output, struct tty_struct *tty)
 {
-	struct line *line = data;
+	struct line *line = tty->driver_data;
 	struct line_driver *driver = line->driver;
 	int err = 0, flags = SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM;
 
 	if(input) err = um_request_irq(driver->read_irq, fd, IRQ_READ, 
 				       line_interrupt, flags, 
-				       driver->read_irq_name, line);
+				       driver->read_irq_name, tty);
 	if(err) return(err);
 	if(output) err = um_request_irq(driver->write_irq, fd, IRQ_WRITE, 
 					line_write_interrupt, flags, 
-					driver->write_irq_name, line);
+					driver->write_irq_name, tty);
 	line->have_irq = 1;
 	return(err);
 }
 
-void line_disable(struct line *line, int current_irq)
+void line_disable(struct tty_struct *tty, int current_irq)
 {
-	if(!line->have_irq) return;
+	struct line *line = tty->driver_data;
+
+	if(!line->have_irq)
+		return;
 
 	if(line->driver->read_irq == current_irq)
-		free_irq_later(line->driver->read_irq, line);
+		free_irq_later(line->driver->read_irq, tty);
 	else {
-		free_irq_by_irq_and_dev(line->driver->read_irq, line);
-		free_irq(line->driver->read_irq, line);
+		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, line);
+		free_irq_later(line->driver->write_irq, tty);
 	else {
-		free_irq_by_irq_and_dev(line->driver->write_irq, line);
-		free_irq(line->driver->write_irq, line);
+		free_irq_by_irq_and_dev(line->driver->write_irq, tty);
+		free_irq(line->driver->write_irq, tty);
 	}
 
 	line->have_irq = 0;
@@ -220,73 +331,51 @@
 	      struct chan_opts *opts)
 {
 	struct line *line;
-	int n, err = 0;
+	int err = 0;
 
-	if(tty == NULL) n = 0;
-	else n = tty->index;
-	line = &lines[n];
+	line = &lines[tty->index];
+	tty->driver_data = line;
 
 	down(&line->sem);
-	if(line->count == 0){
-		if(!line->valid){
+	if (tty->count == 1) {
+		if (!line->valid) {
 			err = -ENODEV;
 			goto out;
 		}
-		if(list_empty(&line->chan_list)){
+		if (list_empty(&line->chan_list)) {
 			err = parse_chan_pair(line->init_str, &line->chan_list,
-					      line->init_pri, n, opts);
+					      line->init_pri, tty->index, opts);
 			if(err) goto out;
 			err = open_chan(&line->chan_list);
 			if(err) goto out;
 		}
-		enable_chan(&line->chan_list, line);
-		INIT_WORK(&line->task, line_timer_cb, line);
+		enable_chan(&line->chan_list, tty);
+		INIT_WORK(&line->task, line_timer_cb, tty);
 	}
 
 	if(!line->sigio){
-		chan_enable_winch(&line->chan_list, line);
+		chan_enable_winch(&line->chan_list, tty);
 		line->sigio = 1;
 	}
-
-	/* This is outside the if because the initial console is opened
-	 * with tty == NULL
-	 */
-	line->tty = tty;
-
-	if(tty != NULL){
-		tty->driver_data = line;
-		chan_window_size(&line->chan_list, &tty->winsize.ws_row, 
-				 &tty->winsize.ws_col);
-	}
-
+	chan_window_size(&line->chan_list, &tty->winsize.ws_row,
+			 &tty->winsize.ws_col);
 	line->count++;
- out:
+
+out:
 	up(&line->sem);
 	return(err);
 }
 
-void line_close(struct line *lines, struct tty_struct *tty)
+void line_close(struct tty_struct *tty, struct file * filp)
 {
-	struct line *line;
-	int n;
-
-	if(tty == NULL) n = 0;
-	else n = tty->index;
-	line = &lines[n];
+	struct line *line = tty->driver_data;
 
 	down(&line->sem);
 	line->count--;
-
-	/* I don't like this, but I can't think of anything better.  What's
-	 * going on is that the tty is in the process of being closed for
-	 * the last time.  Its count hasn't been dropped yet, so it's still
-	 * at 1.  This may happen when line->count != 0 because of the initial
-	 * console open (without a tty) bumping it up to 1.
-	 */
-	if((line->tty != NULL) && (line->tty->count == 1))
-		line->tty = NULL;
-	if(line->count == 0)
-		line_disable(line, -1);
+	if (tty->count == 1) {
+		line_disable(tty, -1);
+		tty->driver_data = NULL;
+	}
 	up(&line->sem);
 }
 
@@ -319,14 +408,15 @@
 		       n, num - 1);
 		return(0);
 	}
-	else if(n >= 0){
-		if(lines[n].count > 0){
+	else if (n >= 0){
+		if (lines[n].count > 0) {
 			printk("line_setup - device %d is open\n", n);
 			return(0);
 		}
-		if(lines[n].init_pri <= INIT_ONE){
+		if (lines[n].init_pri <= INIT_ONE){
 			lines[n].init_pri = INIT_ONE;
-			if(!strcmp(init, "none")) lines[n].valid = 0;
+			if (!strcmp(init, "none"))
+				lines[n].valid = 0;
 			else {
 				lines[n].init_str = init;
 				lines[n].valid = 1;
@@ -406,8 +496,15 @@
 int line_write_room(struct tty_struct *tty)
 {
 	struct line *dev = tty->driver_data;
+	int room;
 
-	return(write_room(dev));
+	if (tty->stopped)
+		return 0;
+	room = write_room(dev);
+	if (0 == room)
+		printk(KERN_DEBUG "%s: %s: no room left in buffer\n",
+		       __FUNCTION__,tty->name);
+	return room;
 }
 
 struct tty_driver *line_register_devfs(struct lines *set,
@@ -415,8 +512,7 @@
 			 struct tty_operations *ops, struct line *lines,
 			 int nlines)
 {
-	int err, i;
-	char *from, *to;
+	int i;
 	struct tty_driver *driver = alloc_tty_driver(nlines);
 
 	if (!driver)
@@ -433,14 +529,12 @@
 	driver->init_termios = tty_std_termios;
 	tty_set_operations(driver, ops);
 
-	if (tty_register_driver(driver))
-		panic("line_register_devfs : Couldn't register driver\n");
-
-	from = line_driver->symlink_from;
-	to = line_driver->symlink_to;
-	err = devfs_mk_symlink(from, to);
-	if(err) printk("Symlink creation from /dev/%s to /dev/%s "
-		       "returned %d\n", from, to, err);
+	if (tty_register_driver(driver)) {
+		printk("%s: can't register %s driver\n",
+		       __FUNCTION__,line_driver->name);
+		put_tty_driver(driver);
+		return NULL;
+	}
 
 	for(i = 0; i < nlines; i++){
 		if(!lines[i].valid) 
@@ -474,13 +568,14 @@
 	int fd;
 	int tty_fd;
 	int pid;
-	struct line *line;
+	struct tty_struct *tty;
 };
 
 irqreturn_t winch_interrupt(int irq, void *data, struct pt_regs *unused)
 {
 	struct winch *winch = data;
 	struct tty_struct *tty;
+	struct line *line;
 	int err;
 	char c;
 
@@ -497,9 +592,10 @@
 			goto out;
 		}
 	}
-	tty = winch->line->tty;
-	if(tty != NULL){
-		chan_window_size(&winch->line->chan_list, 
+	tty  = winch->tty;
+	if (tty != NULL) {
+		line = tty->driver_data;
+		chan_window_size(&line->chan_list,
 				 &tty->winsize.ws_row, 
 				 &tty->winsize.ws_col);
 		kill_pg(tty->pgrp, SIGWINCH, 1);
@@ -513,13 +609,13 @@
 DECLARE_MUTEX(winch_handler_sem);
 LIST_HEAD(winch_handlers);
 
-void register_winch_irq(int fd, int tty_fd, int pid, void *line)
+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){
+	if (winch == NULL) {
 		printk("register_winch_irq - kmalloc failed\n");
 		goto out;
 	}
@@ -527,7 +623,7 @@
 				   .fd  	= fd,
 				   .tty_fd 	= tty_fd,
 				   .pid  	= pid,
-				   .line 	= line });
+				   .tty 	= tty });
 	list_add(&winch->list, &winch_handlers);
 	if(um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt, 
 			  SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, 
@@ -552,7 +648,6 @@
 			os_kill_process(winch->pid, 1);
 	}
 }
-
 __uml_exitcall(winch_cleanup);
 
 char *add_xterm_umid(char *base)
diff -Nru a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c
--- a/arch/um/drivers/mconsole_kern.c	2005-03-01 23:38:51 -08:00
+++ b/arch/um/drivers/mconsole_kern.c	2005-03-01 23:38:51 -08:00
@@ -73,11 +73,12 @@
 static irqreturn_t mconsole_interrupt(int irq, void *dev_id,
 				      struct pt_regs *regs)
 {
-	int fd;
+	/* long to avoid size mismatch warnings from gcc */
+	long fd;
 	struct mconsole_entry *new;
 	struct mc_request req;
 
-	fd = (int) dev_id;
+	fd = (long) dev_id;
 	while (mconsole_get_request(fd, &req)){
 		if(req.cmd->context == MCONSOLE_INTR)
 			(*req.cmd->handler)(&req);
@@ -457,7 +458,9 @@
 
 int mconsole_init(void)
 {
-	int err, sock;
+	/* long to avoid size mismatch warnings from gcc */
+	long sock;
+	int err;
 	char file[256];
 
 	if(umid_file_name("mconsole", file, sizeof(file))) return(-1);
@@ -496,7 +499,7 @@
 
 __initcall(mconsole_init);
 
-static int write_proc_mconsole(struct file *file, const char *buffer,
+static int write_proc_mconsole(struct file *file, const char __user *buffer,
 			       unsigned long count, void *data)
 {
 	char *buf;
@@ -535,7 +538,7 @@
 	return(0);
 }
 
-static spinlock_t notify_spinlock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(notify_spinlock);
 
 void lock_notify(void)
 {
diff -Nru a/arch/um/drivers/mmapper_kern.c b/arch/um/drivers/mmapper_kern.c
--- a/arch/um/drivers/mmapper_kern.c	2005-03-01 23:38:52 -08:00
+++ b/arch/um/drivers/mmapper_kern.c	2005-03-01 23:38:52 -08:00
@@ -8,6 +8,8 @@
  *         Greg Lonnon glonnon@ridgerun.com or info@ridgerun.com
  *
  */
+
+#include <linux/types.h>
 #include <linux/kdev_t.h>
 #include <linux/time.h>
 #include <linux/devfs_fs_kernel.h>
@@ -128,7 +130,6 @@
 	p_buf = __pa(v_buf);
 
 	devfs_mk_cdev(MKDEV(30, 0), S_IFCHR|S_IRUGO|S_IWUGO, "mmapper");
-	devfs_mk_symlink("mmapper0", "mmapper");
 	return(0);
 }
 
diff -Nru a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c
--- a/arch/um/drivers/net_kern.c	2005-03-01 23:38:57 -08:00
+++ b/arch/um/drivers/net_kern.c	2005-03-01 23:38:57 -08:00
@@ -30,7 +30,9 @@
 #include "irq_user.h"
 #include "irq_kern.h"
 
-static spinlock_t opened_lock = SPIN_LOCK_UNLOCKED;
+#define DRIVER_NAME "uml-netdev"
+
+static DEFINE_SPINLOCK(opened_lock);
 LIST_HEAD(opened);
 
 static int uml_net_rx(struct net_device *dev)
@@ -126,10 +128,6 @@
 	lp->tl.data = (unsigned long) &lp->user;
 	netif_start_queue(dev);
 
-	spin_lock(&opened_lock);
-	list_add(&lp->list, &opened);
-	spin_unlock(&opened_lock);
-
 	/* clear buffer - it can happen that the host side of the interface
 	 * is full when we get here.  In this case, new data is never queued,
 	 * SIGIOs never arrive, and the net never works.
@@ -150,11 +148,9 @@
 
 	free_irq_by_irq_and_dev(dev->irq, dev);
 	free_irq(dev->irq, dev);
-	if(lp->close != NULL) (*lp->close)(lp->fd, &lp->user);
+	if(lp->close != NULL)
+		(*lp->close)(lp->fd, &lp->user);
 	lp->fd = -1;
-	spin_lock(&opened_lock);
-	list_del(&lp->list);
-	spin_unlock(&opened_lock);
 
 	spin_unlock(&lp->lock);
 	return 0;
@@ -252,7 +248,7 @@
 {
 	static const struct ethtool_drvinfo info = {
 		.cmd     = ETHTOOL_GDRVINFO,
-		.driver  = "uml virtual ethernet",
+		.driver  = DRIVER_NAME,
 		.version = "42",
 	};
 	void *useraddr;
@@ -286,9 +282,15 @@
 #endif
 }
 
-static spinlock_t devices_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(devices_lock);
 static struct list_head devices = LIST_HEAD_INIT(devices);
 
+static struct device_driver uml_net_driver = {
+	.name  = DRIVER_NAME,
+	.bus   = &platform_bus_type,
+};
+static int driver_registered;
+
 static int eth_configure(int n, void *init, char *mac,
 			 struct transport *transport)
 {
@@ -330,6 +332,16 @@
 		return 1;
 	}
 
+	/* sysfs register */
+	if (!driver_registered) {
+		driver_register(&uml_net_driver);
+		driver_registered = 1;
+	}
+	device->pdev.id = n;
+	device->pdev.name = DRIVER_NAME;
+	platform_device_register(&device->pdev);
+	SET_NETDEV_DEV(dev,&device->pdev.dev);
+
 	/* If this name ends up conflicting with an existing registered
 	 * netdevice, that is OK, register_netdev{,ice}() will notice this
 	 * and fail.
@@ -397,6 +409,11 @@
 
 	if (device->have_mac)
 		set_ether_mac(dev, device->mac);
+
+	spin_lock(&opened_lock);
+	list_add(&lp->list, &opened);
+	spin_unlock(&opened_lock);
+
 	return(0);
 }
 
@@ -560,6 +577,7 @@
 "    Configure a network device.\n\n"
 );
 
+#if 0
 static int eth_init(void)
 {
 	struct list_head *ele, *next;
@@ -574,8 +592,8 @@
 	
 	return(1);
 }
-
 __initcall(eth_init);
+#endif
 
 static int net_config(char *str)
 {
@@ -616,6 +634,7 @@
 	if(lp->fd > 0) return(-1);
 	if(lp->remove != NULL) (*lp->remove)(&lp->user);
 	unregister_netdev(dev);
+	platform_device_unregister(&device->pdev);
 
 	list_del(&device->list);
 	kfree(device);
@@ -705,7 +724,7 @@
 static void close_devices(void)
 {
 	struct list_head *ele;
-	struct uml_net_private *lp;	
+	struct uml_net_private *lp;
 
 	list_for_each(ele, &opened){
 		lp = list_entry(ele, struct uml_net_private, list);
diff -Nru a/arch/um/drivers/net_user.c b/arch/um/drivers/net_user.c
--- a/arch/um/drivers/net_user.c	2005-03-01 23:38:53 -08:00
+++ b/arch/um/drivers/net_user.c	2005-03-01 23:38:53 -08:00
@@ -173,10 +173,12 @@
 	pe_data.stdout = fds[1];
 	pid = run_helper(change_pre_exec, &pe_data, argv, NULL);
 
-	os_close_file(fds[1]);
 	read_output(fds[0], output, output_len);
+	os_close_file(fds[0]);
+	os_close_file(fds[1]);
 
-	CATCH_EINTR(err = waitpid(pid, NULL, 0));
+	if (pid > 0)
+		CATCH_EINTR(err = waitpid(pid, NULL, 0));
 	return(pid);
 }
 
diff -Nru a/arch/um/drivers/pty.c b/arch/um/drivers/pty.c
--- a/arch/um/drivers/pty.c	2005-03-01 23:39:09 -08:00
+++ b/arch/um/drivers/pty.c	2005-03-01 23:39:09 -08:00
@@ -58,7 +58,8 @@
 	dev = ptsname(fd);
 	sprintf(data->dev_name, "%s", dev);
 	*dev_out = data->dev_name;
-	if(data->announce) (*data->announce)(dev, data->dev);
+	if (data->announce)
+		(*data->announce)(dev, data->dev);
 	return(fd);
 }
 
diff -Nru a/arch/um/drivers/ssl.c b/arch/um/drivers/ssl.c
--- a/arch/um/drivers/ssl.c	2005-03-01 23:38:57 -08:00
+++ b/arch/um/drivers/ssl.c	2005-03-01 23:38:57 -08:00
@@ -54,7 +54,7 @@
 
 static struct line_driver driver = {
 	.name 			= "UML serial line",
-	.device_name 		= "ttS",
+	.device_name 		= "ttyS",
 	.devfs_name 		= "tts/",
 	.major 			= TTY_MAJOR,
 	.minor_start 		= 64,
@@ -103,30 +103,10 @@
 
 int ssl_open(struct tty_struct *tty, struct file *filp)
 {
-	return(line_open(serial_lines, tty, &opts));
-}
-
-static void ssl_close(struct tty_struct *tty, struct file * filp)
-{
-	line_close(serial_lines, tty);
-}
-
-static int ssl_write(struct tty_struct * tty,
-		     const unsigned char *buf, int count)
-{
-	return(line_write(serial_lines, tty, buf, count));
-}
-
-static void ssl_put_char(struct tty_struct *tty, unsigned char ch)
-{
-	line_write(serial_lines, tty, &ch, sizeof(ch));
-}
-
-static void ssl_flush_chars(struct tty_struct *tty)
-{
-	return;
+	return line_open(serial_lines, tty, &opts);
 }
 
+#if 0
 static int ssl_chars_in_buffer(struct tty_struct *tty)
 {
 	return(0);
@@ -137,34 +117,6 @@
 	return;
 }
 
-static int ssl_ioctl(struct tty_struct *tty, struct file * file,
-		     unsigned int cmd, unsigned long arg)
-{
-	int ret;
-
-	ret = 0;
-	switch(cmd){
-	case TCGETS:
-	case TCSETS:
-	case TCFLSH:
-	case TCSETSF:
-	case TCSETSW:
-	case TCGETA:
-	case TIOCMGET:
-	case TCSBRK:
-	case TCSBRKP:
-	case TIOCMSET:
-		ret = -ENOIOCTLCMD;
-		break;
-	default:
-		printk(KERN_ERR 
-		       "Unimplemented ioctl in ssl_ioctl : 0x%x\n", cmd);
-		ret = -ENOIOCTLCMD;
-		break;
-	}
-	return(ret);
-}
-
 static void ssl_throttle(struct tty_struct * tty)
 {
 	printk(KERN_ERR "Someone should implement ssl_throttle\n");
@@ -175,11 +127,6 @@
 	printk(KERN_ERR "Someone should implement ssl_unthrottle\n");
 }
 
-static void ssl_set_termios(struct tty_struct *tty, 
-			    struct termios *old_termios)
-{
-}
-
 static void ssl_stop(struct tty_struct *tty)
 {
 	printk(KERN_ERR "Someone should implement ssl_stop\n");
@@ -193,23 +140,26 @@
 void ssl_hangup(struct tty_struct *tty)
 {
 }
+#endif
 
 static struct tty_operations ssl_ops = {
 	.open 	 		= ssl_open,
-	.close 	 		= ssl_close,
-	.write 	 		= ssl_write,
-	.put_char 		= ssl_put_char,
+	.close 	 		= line_close,
+	.write 	 		= line_write,
+	.put_char 		= line_put_char,
+	.write_room		= line_write_room,
+	.chars_in_buffer 	= line_chars_in_buffer,
+	.set_termios 		= line_set_termios,
+	.ioctl 	 		= line_ioctl,
+#if 0
 	.flush_chars 		= ssl_flush_chars,
-	.chars_in_buffer 	= ssl_chars_in_buffer,
 	.flush_buffer 		= ssl_flush_buffer,
-	.ioctl 	 		= ssl_ioctl,
 	.throttle 		= ssl_throttle,
 	.unthrottle 		= ssl_unthrottle,
-	.set_termios 		= ssl_set_termios,
 	.stop 	 		= ssl_stop,
 	.start 	 		= ssl_start,
 	.hangup 	 	= ssl_hangup,
-	.write_room		= line_write_room,
+#endif
 };
 
 /* Changed by ssl_init and referenced by ssl_exit, which are both serialized
@@ -221,11 +171,10 @@
 			      unsigned len)
 {
 	struct line *line = &serial_lines[c->index];
-	if(ssl_init_done)
-		down(&line->sem);
+
+	down(&line->sem);
 	console_write_chan(&line->chan_list, string, len);
-	if(ssl_init_done)
-		up(&line->sem);
+	up(&line->sem);
 }
 
 static struct tty_driver *ssl_console_device(struct console *c, int *index)
@@ -236,16 +185,18 @@
 
 static int ssl_console_setup(struct console *co, char *options)
 {
-	return(0);
+	struct line *line = &serial_lines[co->index];
+
+	return console_open_chan(line,co,&opts);
 }
 
 static struct console ssl_cons = {
-	name:		"ttyS",
-	write:		ssl_console_write,
-	device:		ssl_console_device,
-	setup:		ssl_console_setup,
-	flags:		CON_PRINTBUFFER,
-	index:		-1,
+	.name		= "ttyS",
+	.write		= ssl_console_write,
+	.device		= ssl_console_device,
+	.setup		= ssl_console_setup,
+	.flags		= CON_PRINTBUFFER,
+	.index		= -1,
 };
 
 int ssl_init(void)
@@ -254,22 +205,30 @@
 
 	printk(KERN_INFO "Initializing software serial port version %d\n", 
 	       ssl_version);
-
 	ssl_driver = line_register_devfs(&lines, &driver, &ssl_ops,
-		serial_lines, sizeof(serial_lines)/sizeof(serial_lines[0]));
+					 serial_lines, ARRAY_SIZE(serial_lines));
 
 	lines_init(serial_lines, sizeof(serial_lines)/sizeof(serial_lines[0]));
 
 	new_title = add_xterm_umid(opts.xterm_title);
-	if(new_title != NULL) opts.xterm_title = new_title;
+	if (new_title != NULL)
+		opts.xterm_title = new_title;
 
-	register_console(&ssl_cons);
 	ssl_init_done = 1;
+	register_console(&ssl_cons);
 	return(0);
 }
-
 late_initcall(ssl_init);
 
+static void ssl_exit(void)
+{
+	if (!ssl_init_done)
+		return;
+	close_lines(serial_lines,
+		    sizeof(serial_lines)/sizeof(serial_lines[0]));
+}
+__uml_exitcall(ssl_exit);
+
 static int ssl_chan_setup(char *str)
 {
 	return(line_setup(serial_lines,
@@ -279,15 +238,6 @@
 
 __setup("ssl", ssl_chan_setup);
 __channel_help(ssl_chan_setup, "ssl");
-
-static void ssl_exit(void)
-{
-	if(!ssl_init_done) return;
-	close_lines(serial_lines, 
-		    sizeof(serial_lines)/sizeof(serial_lines[0]));
-}
-
-__uml_exitcall(ssl_exit);
 
 /*
  * Overrides for Emacs so that we follow Linus's tabbing style.
diff -Nru a/arch/um/drivers/stderr_console.c b/arch/um/drivers/stderr_console.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/um/drivers/stderr_console.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,45 @@
+#include <linux/init.h>
+#include <linux/console.h>
+
+#include "chan_user.h"
+
+/* ----------------------------------------------------------------------------- */
+/* trivial console driver -- simply dump everything to stderr                    */
+
+/*
+ * Don't register by default -- as this registeres very early in the
+ * boot process it becomes the default console.  And as this isn't a
+ * real tty driver init isn't able to open /dev/console then.
+ *
+ * In most cases this isn't what you want ...
+ */
+static int use_stderr_console = 0;
+
+static void stderr_console_write(struct console *console, const char *string,
+				 unsigned len)
+{
+	generic_write(2 /* stderr */, string, len, NULL);
+}
+
+static struct console stderr_console = {
+	.name		"stderr",
+	.write		stderr_console_write,
+	.flags		CON_PRINTBUFFER,
+};
+
+static int __init stderr_console_init(void)
+{
+	if (use_stderr_console)
+		register_console(&stderr_console);
+	return 0;
+}
+console_initcall(stderr_console_init);
+
+static int stderr_setup(char *str)
+{
+	if (!str)
+		return 0;
+	use_stderr_console = simple_strtoul(str,&str,0);
+	return 1;
+}
+__setup("stderr=", stderr_setup);
diff -Nru a/arch/um/drivers/stdio_console.c b/arch/um/drivers/stdio_console.c
--- a/arch/um/drivers/stdio_console.c	2005-03-01 23:38:54 -08:00
+++ b/arch/um/drivers/stdio_console.c	2005-03-01 23:38:54 -08:00
@@ -30,7 +30,9 @@
 #include "init.h"
 #include "2_5compat.h"
 
-#define MAX_TTYS (8)
+#define MAX_TTYS (16)
+
+/* ----------------------------------------------------------------------------- */
 
 /* Referenced only by tty_driver below - presumably it's locked correctly
  * by the tty driver.
@@ -38,31 +40,6 @@
 
 static struct tty_driver *console_driver;
 
-static struct chan_ops init_console_ops = {
-	.type		= "you shouldn't see this",
-	.init  		= NULL,
-	.open  		= NULL,
-	.close 		= NULL,
-	.read  		= NULL,
-	.write 		= NULL,
-	.console_write 	= generic_write,
-	.window_size 	= NULL,
-	.free  		= NULL,
-	.winch		= 0,
-};
-
-static struct chan init_console_chan = {
-	.list  		= { },
-	.primary 	= 1,
-	.input 		= 0,
-	.output 	= 1,
-	.opened 	= 1,
-	.fd 		= 1,
-	.pri 		= INIT_STATIC,
-	.ops 		= &init_console_ops,
-	.data 		= NULL
-};
-
 void stdio_announce(char *dev_name, int dev)
 {
 	printk(KERN_INFO "Virtual console %d assigned device '%s'\n", dev,
@@ -128,79 +105,31 @@
 	return(line_remove(vts, sizeof(vts)/sizeof(vts[0]), str));
 }
 
-static int open_console(struct tty_struct *tty)
-{
-	return(line_open(vts, tty, &opts));
-}
-
 static int con_open(struct tty_struct *tty, struct file *filp)
 {
-	return(open_console(tty));
-}
-
-static void con_close(struct tty_struct *tty, struct file *filp)
-{
-	line_close(vts, tty);
-}
-
-static int con_write(struct tty_struct *tty, 
-		     const unsigned char *buf, int count)
-{
-	 return(line_write(vts, tty, buf, count));
-}
-
-static void set_termios(struct tty_struct *tty, struct termios * old)
-{
-}
-
-static int chars_in_buffer(struct tty_struct *tty)
-{
-	return(0);
+	return line_open(vts, tty, &opts);
 }
 
 static int con_init_done = 0;
 
 static struct tty_operations console_ops = {
 	.open 	 		= con_open,
-	.close 	 		= con_close,
-	.write 	 		= con_write,
-	.chars_in_buffer 	= chars_in_buffer,
-	.set_termios 		= set_termios,
-	.write_room		= line_write_room,
+	.close 	 		= line_close,
+	.write 	 		= line_write,
+ 	.write_room		= line_write_room,
+	.chars_in_buffer 	= line_chars_in_buffer,
+	.set_termios 		= line_set_termios,
+	.ioctl 	 		= line_ioctl,
 };
 
-int stdio_init(void)
-{
-	char *new_title;
-
-	printk(KERN_INFO "Initializing stdio console driver\n");
-
-	console_driver = line_register_devfs(&console_lines, &driver,
-					     &console_ops, vts,
-					     sizeof(vts)/sizeof(vts[0]));
-
-	lines_init(vts, sizeof(vts)/sizeof(vts[0]));
-
-	new_title = add_xterm_umid(opts.xterm_title);
-	if(new_title != NULL) opts.xterm_title = new_title;
-
-	open_console(NULL);
-	con_init_done = 1;
-	return(0);
-}
-
-late_initcall(stdio_init);
-
 static void uml_console_write(struct console *console, const char *string,
 			  unsigned len)
 {
 	struct line *line = &vts[console->index];
 
-	if(con_init_done)
-		down(&line->sem);
+	down(&line->sem);
 	console_write_chan(&line->chan_list, string, len);
-	if(con_init_done)
-		up(&line->sem);
+	up(&line->sem);
 }
 
 static struct tty_driver *uml_console_device(struct console *c, int *index)
@@ -211,43 +140,58 @@
 
 static int uml_console_setup(struct console *co, char *options)
 {
-	return(0);
+	struct line *line = &vts[co->index];
+
+	return console_open_chan(line,co,&opts);
 }
 
 static struct console stdiocons = {
-	name:		"tty",
-	write:		uml_console_write,
-	device:		uml_console_device,
-	setup:		uml_console_setup,
-	flags:		CON_PRINTBUFFER,
-	index:		-1,
+	.name		= "tty",
+	.write		= uml_console_write,
+	.device		= uml_console_device,
+	.setup		= uml_console_setup,
+	.flags		= CON_PRINTBUFFER,
+	.index		= -1,
+	.data           = &vts,
 };
 
-static int __init stdio_console_init(void)
+int stdio_init(void)
 {
-	INIT_LIST_HEAD(&vts[0].chan_list);
-	list_add(&init_console_chan.list, &vts[0].chan_list);
+	char *new_title;
+
+	console_driver = line_register_devfs(&console_lines, &driver,
+					     &console_ops, vts,
+					     ARRAY_SIZE(vts));
+	if (NULL == console_driver)
+		return -1;
+	printk(KERN_INFO "Initialized stdio console driver\n");
+
+	lines_init(vts, sizeof(vts)/sizeof(vts[0]));
+
+	new_title = add_xterm_umid(opts.xterm_title);
+	if(new_title != NULL)
+		opts.xterm_title = new_title;
+
+	con_init_done = 1;
 	register_console(&stdiocons);
 	return(0);
 }
+late_initcall(stdio_init);
 
-console_initcall(stdio_console_init);
+static void console_exit(void)
+{
+	if (!con_init_done)
+		return;
+	close_lines(vts, sizeof(vts)/sizeof(vts[0]));
+}
+__uml_exitcall(console_exit);
 
 static int console_chan_setup(char *str)
 {
 	return(line_setup(vts, sizeof(vts)/sizeof(vts[0]), str, 1));
 }
-
 __setup("con", console_chan_setup);
 __channel_help(console_chan_setup, "con");
-
-static void console_exit(void)
-{
-	if(!con_init_done) return;
-	close_lines(vts, sizeof(vts)/sizeof(vts[0]));
-}
-
-__uml_exitcall(console_exit);
 
 /*
  * Overrides for Emacs so that we follow Linus's tabbing style.
diff -Nru a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
--- a/arch/um/drivers/ubd_kern.c	2005-03-01 23:38:57 -08:00
+++ b/arch/um/drivers/ubd_kern.c	2005-03-01 23:38:57 -08:00
@@ -53,9 +53,65 @@
 #include "os.h"
 #include "mem.h"
 #include "mem_kern.h"
+#include "cow.h"
 
-static spinlock_t ubd_io_lock = SPIN_LOCK_UNLOCKED;
-static spinlock_t ubd_lock = SPIN_LOCK_UNLOCKED;
+enum ubd_req { UBD_READ, UBD_WRITE, UBD_MMAP };
+
+struct io_thread_req {
+	enum ubd_req op;
+	int fds[2];
+	unsigned long offsets[2];
+	unsigned long long offset;
+	unsigned long length;
+	char *buffer;
+	int sectorsize;
+	unsigned long sector_mask;
+	unsigned long long cow_offset;
+	unsigned long bitmap_words[2];
+	int map_fd;
+	unsigned long long map_offset;
+	int error;
+};
+
+extern int open_ubd_file(char *file, struct openflags *openflags,
+			 char **backing_file_out, int *bitmap_offset_out,
+			 unsigned long *bitmap_len_out, int *data_offset_out,
+			 int *create_cow_out);
+extern int create_cow_file(char *cow_file, char *backing_file,
+			   struct openflags flags, int sectorsize,
+			   int alignment, int *bitmap_offset_out,
+			   unsigned long *bitmap_len_out,
+			   int *data_offset_out);
+extern int read_cow_bitmap(int fd, void *buf, int offset, int len);
+extern void do_io(struct io_thread_req *req);
+
+static inline int ubd_test_bit(__u64 bit, unsigned char *data)
+{
+	__u64 n;
+	int bits, off;
+
+	bits = sizeof(data[0]) * 8;
+	n = bit / bits;
+	off = bit % bits;
+	return((data[n] & (1 << off)) != 0);
+}
+
+static inline void ubd_set_bit(__u64 bit, unsigned char *data)
+{
+	__u64 n;
+	int bits, off;
+
+	bits = sizeof(data[0]) * 8;
+	n = bit / bits;
+	off = bit % bits;
+	data[n] |= (1 << off);
+}
+/*End stuff from ubd_user.h*/
+
+#define DRIVER_NAME "uml-blkdev"
+
+static DEFINE_SPINLOCK(ubd_io_lock);
+static DEFINE_SPINLOCK(ubd_lock);
 
 static void (*do_ubd)(void);
 
@@ -117,6 +173,7 @@
 	struct openflags openflags;
 	int no_cow;
 	struct cow cow;
+	struct platform_device pdev;
 
 	int map_writes;
 	int map_reads;
@@ -169,7 +226,7 @@
 
 static void make_proc_ide(void)
 {
-	proc_ide_root = proc_mkdir("ide", 0);
+	proc_ide_root = proc_mkdir("ide", NULL);
 	proc_ide = proc_mkdir("ide0", proc_ide_root);
 }
 
@@ -247,7 +304,7 @@
 	struct ubd *dev;
 	struct openflags flags = global_openflags;
 	char *backing_file;
-	int n, err;
+	int n, err, i;
 
 	if(index_out) *index_out = -1;
 	n = *str;
@@ -264,7 +321,7 @@
 		}
 
 		if(!strcmp(str, "sync")){
-			global_openflags.s = 1;
+			global_openflags = of_sync(global_openflags);
 			return(0);
 		}
 		major = simple_strtoul(str, &end, 0);
@@ -309,31 +366,47 @@
 	dev = &ubd_dev[n];
 	if(dev->file != NULL){
 		printk(KERN_ERR "ubd_setup : device already configured\n");
-		goto out2;
+		goto out;
 	}
 
-	if(index_out) *index_out = n;
+	if (index_out)
+		*index_out = n;
 
-	if (*str == 'r'){
-		flags.w = 0;
-		str++;
-	}
-	if (*str == 's'){
-		flags.s = 1;
-		str++;
-	}
-	if (*str == 'd'){
-		dev->no_cow = 1;
+	for (i = 0; i < 4; i++) {
+		switch (*str) {
+		case 'r':
+			flags.w = 0;
+			break;
+		case 's':
+			flags.s = 1;
+			break;
+		case 'd':
+			dev->no_cow = 1;
+			break;
+		case '=':
+			str++;
+			goto break_loop;
+		default:
+			printk(KERN_ERR "ubd_setup : Expected '=' or flag letter (r,s or d)\n");
+			goto out;
+		}
 		str++;
 	}
 
-	if(*str++ != '='){
+        if (*str == '=')
+		printk(KERN_ERR "ubd_setup : Too many flags specified\n");
+        else
 		printk(KERN_ERR "ubd_setup : Expected '='\n");
-		goto out2;
-	}
+	goto out;
 
+break_loop:
 	err = 0;
 	backing_file = strchr(str, ',');
+
+	if (!backing_file) {
+		backing_file = strchr(str, ':');
+	}
+
 	if(backing_file){
 		if(dev->no_cow)
 			printk(KERN_ERR "Can't specify both 'd' and a "
@@ -346,7 +419,7 @@
 	dev->file = str;
 	dev->cow.file = backing_file;
 	dev->boot_openflags = flags;
- out2:
+out:
 	spin_unlock(&ubd_lock);
 	return(err);
 }
@@ -359,17 +432,25 @@
 
 __setup("ubd", ubd_setup);
 __uml_help(ubd_setup,
-"ubd<n>=<filename>\n"
+"ubd<n><flags>=<filename>[(:|,)<filename2>]\n"
 "    This is used to associate a device with a file in the underlying\n"
-"    filesystem. Usually, there is a filesystem in the file, but \n"
+"    filesystem. When specifying two filenames, the first one is the\n"
+"    COW name and the second is the backing file name. As separator you can\n"
+"    use either a ':' or a ',': the first one allows writing things like;\n"
+"	ubd0=~/Uml/root_cow:~/Uml/root_backing_file\n"
+"    while with a ',' the shell would not expand the 2nd '~'.\n"
+"    When using only one filename, UML will detect whether to thread it like\n"
+"    a COW file or a backing file. To override this detection, add the 'd'\n"
+"    flag:\n"
+"	ubd0d=BackingFile\n"
+"    Usually, there is a filesystem in the file, but \n"
 "    that's not required. Swap devices containing swap files can be\n"
 "    specified like this. Also, a file which doesn't contain a\n"
 "    filesystem can have its contents read in the virtual \n"
-"    machine by running dd on the device. n must be in the range\n"
+"    machine by running 'dd' on the device. <n> must be in the range\n"
 "    0 to 7. Appending an 'r' to the number will cause that device\n"
 "    to be mounted read-only. For example ubd1r=./ext_fs. Appending\n"
-"    an 's' (has to be _after_ 'r', if there is one) will cause data\n"
-"    to be written to disk on the host immediately.\n\n"
+"    an 's' will cause data to be written to disk on the host immediately.\n\n"
 );
 
 static int fakehd_set = 0;
@@ -430,7 +511,7 @@
 
 	do_ubd = NULL;
 	intr_count++;
-	n = read_ubd_fs(thread_fd, &req, sizeof(req));
+	n = os_read_file(thread_fd, &req, sizeof(req));
 	if(n != sizeof(req)){
 		printk(KERN_ERR "Pid %d - spurious interrupt in ubd_handler, "
 		       "err = %d\n", os_getpid(), -n);
@@ -585,6 +666,14 @@
 		sprintf(disk->devfs_name, "ubd_fake/disc%d", unit);
 	}
 
+	/* sysfs register (not for ide fake devices) */
+	if (major == MAJOR_NR) {
+		ubd_dev[unit].pdev.id   = unit;
+		ubd_dev[unit].pdev.name = DRIVER_NAME;
+		platform_device_register(&ubd_dev[unit].pdev);
+		disk->driverfs_dev = &ubd_dev[unit].pdev.dev;
+	}
+
 	disk->private_data = &ubd_dev[unit];
 	disk->queue = ubd_queue;
 	add_disk(disk);
@@ -593,6 +682,8 @@
 	return 0;
 }
 
+#define ROUND_BLOCK(n) ((n + ((1 << 9) - 1)) & (-1 << 9))
+
 static int ubd_add(int n)
 {
 	struct ubd *dev = &ubd_dev[n];
@@ -608,6 +699,8 @@
 	if(err < 0)
 		return(err);
 
+	dev->size = ROUND_BLOCK(dev->size);
+
 	err = ubd_new_disk(MAJOR_NR, dev->size, n, &ubd_gendisk[n]);
 	if(err) 
 		return(err);
@@ -718,6 +811,7 @@
 		fake_gendisk[n] = NULL;
 	}
 
+	platform_device_unregister(&dev->pdev);
 	*dev = ((struct ubd) DEFAULT_UBD);
 	err = 0;
  out:
@@ -740,6 +834,11 @@
 
 __initcall(ubd_mc_init);
 
+static struct device_driver ubd_driver = {
+	.name  = DRIVER_NAME,
+	.bus   = &platform_bus_type,
+};
+
 int ubd_init(void)
 {
         int i;
@@ -762,6 +861,7 @@
 		if (register_blkdev(fake_major, "ubd"))
 			return -1;
 	}
+	driver_register(&ubd_driver);
 	for (i = 0; i < MAX_DEV; i++) 
 		ubd_add(i);
 	return 0;
@@ -1057,7 +1157,7 @@
 		err = prepare_request(req, &io_req);
 		if(!err){
 			do_ubd = ubd_handler;
-			n = write_ubd_fs(thread_fd, (char *) &io_req, 
+			n = os_write_file(thread_fd, (char *) &io_req,
 					 sizeof(io_req));
 			if(n != sizeof(io_req))
 				printk("write to io thread failed, "
@@ -1069,7 +1169,7 @@
 static int ubd_ioctl(struct inode * inode, struct file * file,
 		     unsigned int cmd, unsigned long arg)
 {
-	struct hd_geometry *loc = (struct hd_geometry *) arg;
+	struct hd_geometry __user *loc = (struct hd_geometry __user *) arg;
 	struct ubd *dev = inode->i_bdev->bd_disk->private_data;
 	struct hd_driveid ubd_id = {
 		.cyls		= 0,
@@ -1090,19 +1190,19 @@
 
 	case HDIO_GET_IDENTITY:
 		ubd_id.cyls = dev->size / (128 * 32 * 512);
-		if(copy_to_user((char *) arg, (char *) &ubd_id, 
+		if(copy_to_user((char __user *) arg, (char *) &ubd_id,
 				 sizeof(ubd_id)))
 			return(-EFAULT);
 		return(0);
 		
 	case CDROMVOLREAD:
-		if(copy_from_user(&volume, (char *) arg, sizeof(volume)))
+		if(copy_from_user(&volume, (char __user *) arg, sizeof(volume)))
 			return(-EFAULT);
 		volume.channel0 = 255;
 		volume.channel1 = 255;
 		volume.channel2 = 255;
 		volume.channel3 = 255;
-		if(copy_to_user((char *) arg, &volume, sizeof(volume)))
+		if(copy_to_user((char __user *) arg, &volume, sizeof(volume)))
 			return(-EFAULT);
 		return(0);
 	}
@@ -1244,6 +1344,304 @@
 }
 
 __initcall(ubd_remapper_setup);
+
+static int same_backing_files(char *from_cmdline, char *from_cow, char *cow)
+{
+	struct uml_stat buf1, buf2;
+	int err;
+
+	if(from_cmdline == NULL) return(1);
+	if(!strcmp(from_cmdline, from_cow)) return(1);
+
+	err = os_stat_file(from_cmdline, &buf1);
+	if(err < 0){
+		printk("Couldn't stat '%s', err = %d\n", from_cmdline, -err);
+		return(1);
+	}
+	err = os_stat_file(from_cow, &buf2);
+	if(err < 0){
+		printk("Couldn't stat '%s', err = %d\n", from_cow, -err);
+		return(1);
+	}
+	if((buf1.ust_dev == buf2.ust_dev) && (buf1.ust_ino == buf2.ust_ino))
+		return(1);
+
+	printk("Backing file mismatch - \"%s\" requested,\n"
+	       "\"%s\" specified in COW header of \"%s\"\n",
+	       from_cmdline, from_cow, cow);
+	return(0);
+}
+
+static int backing_file_mismatch(char *file, __u64 size, time_t mtime)
+{
+	unsigned long modtime;
+	long long actual;
+	int err;
+
+	err = os_file_modtime(file, &modtime);
+	if(err < 0){
+		printk("Failed to get modification time of backing file "
+		       "\"%s\", err = %d\n", file, -err);
+		return(err);
+	}
+
+	err = os_file_size(file, &actual);
+	if(err < 0){
+		printk("Failed to get size of backing file \"%s\", "
+		       "err = %d\n", file, -err);
+		return(err);
+	}
+
+  	if(actual != size){
+		/*__u64 can be a long on AMD64 and with %lu GCC complains; so
+		 * the typecast.*/
+		printk("Size mismatch (%llu vs %llu) of COW header vs backing "
+		       "file\n", (unsigned long long) size, actual);
+		return(-EINVAL);
+	}
+	if(modtime != mtime){
+		printk("mtime mismatch (%ld vs %ld) of COW header vs backing "
+		       "file\n", mtime, modtime);
+		return(-EINVAL);
+	}
+	return(0);
+}
+
+int read_cow_bitmap(int fd, void *buf, int offset, int len)
+{
+	int err;
+
+	err = os_seek_file(fd, offset);
+	if(err < 0)
+		return(err);
+
+	err = os_read_file(fd, buf, len);
+	if(err < 0)
+		return(err);
+
+	return(0);
+}
+
+int open_ubd_file(char *file, struct openflags *openflags,
+		  char **backing_file_out, int *bitmap_offset_out,
+		  unsigned long *bitmap_len_out, int *data_offset_out,
+		  int *create_cow_out)
+{
+	time_t mtime;
+	unsigned long long size;
+	__u32 version, align;
+	char *backing_file;
+	int fd, err, sectorsize, same, mode = 0644;
+
+	fd = os_open_file(file, *openflags, mode);
+	if(fd < 0){
+		if((fd == -ENOENT) && (create_cow_out != NULL))
+			*create_cow_out = 1;
+                if(!openflags->w ||
+                   ((fd != -EROFS) && (fd != -EACCES))) return(fd);
+		openflags->w = 0;
+		fd = os_open_file(file, *openflags, mode);
+		if(fd < 0)
+			return(fd);
+        }
+
+	err = os_lock_file(fd, openflags->w);
+	if(err < 0){
+		printk("Failed to lock '%s', err = %d\n", file, -err);
+		goto out_close;
+	}
+
+	if(backing_file_out == NULL) return(fd);
+
+	err = read_cow_header(file_reader, &fd, &version, &backing_file, &mtime,
+			      &size, &sectorsize, &align, bitmap_offset_out);
+	if(err && (*backing_file_out != NULL)){
+		printk("Failed to read COW header from COW file \"%s\", "
+		       "errno = %d\n", file, -err);
+		goto out_close;
+	}
+	if(err) return(fd);
+
+	if(backing_file_out == NULL) return(fd);
+
+	same = same_backing_files(*backing_file_out, backing_file, file);
+
+	if(!same && !backing_file_mismatch(*backing_file_out, size, mtime)){
+		printk("Switching backing file to '%s'\n", *backing_file_out);
+		err = write_cow_header(file, fd, *backing_file_out,
+				       sectorsize, align, &size);
+		if(err){
+			printk("Switch failed, errno = %d\n", -err);
+			return(err);
+		}
+	}
+	else {
+		*backing_file_out = backing_file;
+		err = backing_file_mismatch(*backing_file_out, size, mtime);
+		if(err) goto out_close;
+	}
+
+	cow_sizes(version, size, sectorsize, align, *bitmap_offset_out,
+		  bitmap_len_out, data_offset_out);
+
+        return(fd);
+ out_close:
+	os_close_file(fd);
+	return(err);
+}
+
+int create_cow_file(char *cow_file, char *backing_file, struct openflags flags,
+		    int sectorsize, int alignment, int *bitmap_offset_out,
+		    unsigned long *bitmap_len_out, int *data_offset_out)
+{
+	int err, fd;
+
+	flags.c = 1;
+	fd = open_ubd_file(cow_file, &flags, NULL, NULL, NULL, NULL, NULL);
+	if(fd < 0){
+		err = fd;
+		printk("Open of COW file '%s' failed, errno = %d\n", cow_file,
+		       -err);
+		goto out;
+	}
+
+	err = init_cow_file(fd, cow_file, backing_file, sectorsize, alignment,
+			    bitmap_offset_out, bitmap_len_out,
+			    data_offset_out);
+	if(!err)
+		return(fd);
+	os_close_file(fd);
+ out:
+	return(err);
+}
+
+static int update_bitmap(struct io_thread_req *req)
+{
+	int n;
+
+	if(req->cow_offset == -1)
+		return(0);
+
+	n = os_seek_file(req->fds[1], req->cow_offset);
+	if(n < 0){
+		printk("do_io - bitmap lseek failed : err = %d\n", -n);
+		return(1);
+	}
+
+	n = os_write_file(req->fds[1], &req->bitmap_words,
+		          sizeof(req->bitmap_words));
+	if(n != sizeof(req->bitmap_words)){
+		printk("do_io - bitmap update failed, err = %d fd = %d\n", -n,
+		       req->fds[1]);
+		return(1);
+	}
+
+	return(0);
+}
+
+void do_io(struct io_thread_req *req)
+{
+	char *buf;
+	unsigned long len;
+	int n, nsectors, start, end, bit;
+	int err;
+	__u64 off;
+
+	if(req->op == UBD_MMAP){
+		/* Touch the page to force the host to do any necessary IO to
+		 * get it into memory
+		 */
+		n = *((volatile int *) req->buffer);
+		req->error = update_bitmap(req);
+		return;
+	}
+
+	nsectors = req->length / req->sectorsize;
+	start = 0;
+	do {
+		bit = ubd_test_bit(start, (unsigned char *) &req->sector_mask);
+		end = start;
+		while((end < nsectors) &&
+		      (ubd_test_bit(end, (unsigned char *)
+				    &req->sector_mask) == bit))
+			end++;
+
+		off = req->offset + req->offsets[bit] +
+			start * req->sectorsize;
+		len = (end - start) * req->sectorsize;
+		buf = &req->buffer[start * req->sectorsize];
+
+		err = os_seek_file(req->fds[bit], off);
+		if(err < 0){
+			printk("do_io - lseek failed : err = %d\n", -err);
+			req->error = 1;
+			return;
+		}
+		if(req->op == UBD_READ){
+			n = 0;
+			do {
+				buf = &buf[n];
+				len -= n;
+				n = os_read_file(req->fds[bit], buf, len);
+				if (n < 0) {
+					printk("do_io - read failed, err = %d "
+					       "fd = %d\n", -n, req->fds[bit]);
+					req->error = 1;
+					return;
+				}
+			} while((n < len) && (n != 0));
+			if (n < len) memset(&buf[n], 0, len - n);
+		}
+		else {
+			n = os_write_file(req->fds[bit], buf, len);
+			if(n != len){
+				printk("do_io - write failed err = %d "
+				       "fd = %d\n", -n, req->fds[bit]);
+				req->error = 1;
+				return;
+			}
+		}
+
+		start = end;
+	} while(start < nsectors);
+
+	req->error = update_bitmap(req);
+}
+
+/* Changed in start_io_thread, which is serialized by being called only
+ * from ubd_init, which is an initcall.
+ */
+int kernel_fd = -1;
+
+/* Only changed by the io thread */
+int io_count = 0;
+
+int io_thread(void *arg)
+{
+	struct io_thread_req req;
+	int n;
+
+	ignore_sigwinch_sig();
+	while(1){
+		n = os_read_file(kernel_fd, &req, sizeof(req));
+		if(n != sizeof(req)){
+			if(n < 0)
+				printk("io_thread - read failed, fd = %d, "
+				       "err = %d\n", kernel_fd, -n);
+			else {
+				printk("io_thread - short read, fd = %d, "
+				       "length = %d\n", kernel_fd, n);
+			}
+			continue;
+		}
+		io_count++;
+		do_io(&req);
+		n = os_write_file(kernel_fd, &req, sizeof(req));
+		if(n != sizeof(req))
+			printk("io_thread - write failed, fd = %d, err = %d\n",
+			       kernel_fd, -n);
+	}
+}
 
 /*
  * Overrides for Emacs so that we follow Linus's tabbing style.
diff -Nru a/arch/um/drivers/ubd_user.c b/arch/um/drivers/ubd_user.c
--- a/arch/um/drivers/ubd_user.c	2005-03-01 23:38:54 -08:00
+++ b/arch/um/drivers/ubd_user.c	2005-03-01 23:38:54 -08:00
@@ -26,311 +26,9 @@
 #include <endian.h>
 #include <byteswap.h>
 
-static int same_backing_files(char *from_cmdline, char *from_cow, char *cow)
+void ignore_sigwinch_sig(void)
 {
-	struct uml_stat buf1, buf2;
-	int err;
-
-	if(from_cmdline == NULL) return(1);
-	if(!strcmp(from_cmdline, from_cow)) return(1);
-
-	err = os_stat_file(from_cmdline, &buf1);
-	if(err < 0){
-		printk("Couldn't stat '%s', err = %d\n", from_cmdline, -err);
-		return(1);
-	}
-	err = os_stat_file(from_cow, &buf2);
-	if(err < 0){
-		printk("Couldn't stat '%s', err = %d\n", from_cow, -err);
-		return(1);
-	}
-	if((buf1.ust_dev == buf2.ust_dev) && (buf1.ust_ino == buf2.ust_ino))
-		return(1);
-
-	printk("Backing file mismatch - \"%s\" requested,\n"
-	       "\"%s\" specified in COW header of \"%s\"\n",
-	       from_cmdline, from_cow, cow);
-	return(0);
-}
-
-static int backing_file_mismatch(char *file, __u64 size, time_t mtime)
-{
-	unsigned long modtime;
-	long long actual;
-	int err;
-
-	err = os_file_modtime(file, &modtime);
-	if(err < 0){
-		printk("Failed to get modification time of backing file "
-		       "\"%s\", err = %d\n", file, -err);
-		return(err);
-	}
-
-	err = os_file_size(file, &actual);
-	if(err < 0){
-		printk("Failed to get size of backing file \"%s\", "
-		       "err = %d\n", file, -err);
-		return(err);
-	}
-
-  	if(actual != size){
-		printk("Size mismatch (%ld vs %ld) of COW header vs backing "
-		       "file\n", size, actual);
-		return(-EINVAL);
-	}
-	if(modtime != mtime){
-		printk("mtime mismatch (%ld vs %ld) of COW header vs backing "
-		       "file\n", mtime, modtime);
-		return(-EINVAL);
-	}
-	return(0);
-}
-
-int read_cow_bitmap(int fd, void *buf, int offset, int len)
-{
-	int err;
-
-	err = os_seek_file(fd, offset);
-	if(err < 0)
-		return(err);
-
-	err = os_read_file(fd, buf, len);
-	if(err < 0)
-		return(err);
-
-	return(0);
-}
-
-int open_ubd_file(char *file, struct openflags *openflags, 
-		  char **backing_file_out, int *bitmap_offset_out, 
-		  unsigned long *bitmap_len_out, int *data_offset_out, 
-		  int *create_cow_out)
-{
-	time_t mtime;
-	__u64 size;
-	__u32 version, align;
-	char *backing_file;
-	int fd, err, sectorsize, same, mode = 0644;
-
-	fd = os_open_file(file, *openflags, mode);
-	if(fd < 0){
-		if((fd == -ENOENT) && (create_cow_out != NULL))
-			*create_cow_out = 1;
-                if(!openflags->w ||
-                   ((errno != EROFS) && (errno != EACCES))) return(-errno);
-		openflags->w = 0;
-		fd = os_open_file(file, *openflags, mode);
-		if(fd < 0)
-			return(fd);
-        }
-
-	err = os_lock_file(fd, openflags->w);
-	if(err < 0){
-		printk("Failed to lock '%s', err = %d\n", file, -err);
-		goto out_close;
-	}
-
-	if(backing_file_out == NULL) return(fd);
-
-	err = read_cow_header(file_reader, &fd, &version, &backing_file, &mtime,
-			      &size, &sectorsize, &align, bitmap_offset_out);
-	if(err && (*backing_file_out != NULL)){
-		printk("Failed to read COW header from COW file \"%s\", "
-		       "errno = %d\n", file, -err);
-		goto out_close;
-	}
-	if(err) return(fd);
-
-	if(backing_file_out == NULL) return(fd);
-	
-	same = same_backing_files(*backing_file_out, backing_file, file);
-
-	if(!same && !backing_file_mismatch(*backing_file_out, size, mtime)){
-		printk("Switching backing file to '%s'\n", *backing_file_out);
-		err = write_cow_header(file, fd, *backing_file_out,
-				       sectorsize, align, &size);
-		if(err){
-			printk("Switch failed, errno = %d\n", -err);
-			return(err);
-		}
-	}
-	else {
-		*backing_file_out = backing_file;
-		err = backing_file_mismatch(*backing_file_out, size, mtime);
-		if(err) goto out_close;
-	}
-
-	cow_sizes(version, size, sectorsize, align, *bitmap_offset_out,
-		  bitmap_len_out, data_offset_out);
-
-        return(fd);
- out_close:
-	os_close_file(fd);
-	return(err);
-}
-
-int create_cow_file(char *cow_file, char *backing_file, struct openflags flags,
-		    int sectorsize, int alignment, int *bitmap_offset_out,
-		    unsigned long *bitmap_len_out, int *data_offset_out)
-{
-	int err, fd;
-
-	flags.c = 1;
-	fd = open_ubd_file(cow_file, &flags, NULL, NULL, NULL, NULL, NULL);
-	if(fd < 0){
-		err = fd;
-		printk("Open of COW file '%s' failed, errno = %d\n", cow_file,
-		       -err);
-		goto out;
-	}
-
-	err = init_cow_file(fd, cow_file, backing_file, sectorsize, alignment,
-			    bitmap_offset_out, bitmap_len_out,
-			    data_offset_out);
-	if(!err)
-		return(fd);
-	os_close_file(fd);
- out:
-	return(err);
-}
-
-/* XXX Just trivial wrappers around os_read_file and os_write_file */
-int read_ubd_fs(int fd, void *buffer, int len)
-{
-	return(os_read_file(fd, buffer, len));
-}
-
-int write_ubd_fs(int fd, char *buffer, int len)
-{
-	return(os_write_file(fd, buffer, len));
-}
-
-static int update_bitmap(struct io_thread_req *req)
-{
-	int n;
-
-	if(req->cow_offset == -1)
-		return(0);
-
-	n = os_seek_file(req->fds[1], req->cow_offset);
-	if(n < 0){
-		printk("do_io - bitmap lseek failed : err = %d\n", -n);
-		return(1);
-	}
-
-	n = os_write_file(req->fds[1], &req->bitmap_words,
-		          sizeof(req->bitmap_words));
-	if(n != sizeof(req->bitmap_words)){
-		printk("do_io - bitmap update failed, err = %d fd = %d\n", -n,
-		       req->fds[1]);
-		return(1);
-	}
-
-	return(0);
-}
-
-void do_io(struct io_thread_req *req)
-{
-	char *buf;
-	unsigned long len;
-	int n, nsectors, start, end, bit;
-	int err;
-	__u64 off;
-
-	if(req->op == UBD_MMAP){
-		/* Touch the page to force the host to do any necessary IO to
-		 * get it into memory
-		 */
-		n = *((volatile int *) req->buffer);
-		req->error = update_bitmap(req);
-		return;
-	}
-
-	nsectors = req->length / req->sectorsize;
-	start = 0;
-	do {
-		bit = ubd_test_bit(start, (unsigned char *) &req->sector_mask);
-		end = start;
-		while((end < nsectors) && 
-		      (ubd_test_bit(end, (unsigned char *) 
-				    &req->sector_mask) == bit))
-			end++;
-
-		off = req->offset + req->offsets[bit] + 
-			start * req->sectorsize;
-		len = (end - start) * req->sectorsize;
-		buf = &req->buffer[start * req->sectorsize];
-
-		err = os_seek_file(req->fds[bit], off);
-		if(err < 0){
-			printk("do_io - lseek failed : err = %d\n", -err);
-			req->error = 1;
-			return;
-		}
-		if(req->op == UBD_READ){
-			n = 0;
-			do {
-				buf = &buf[n];
-				len -= n;
-				n = os_read_file(req->fds[bit], buf, len);
-				if (n < 0) {
-					printk("do_io - read failed, err = %d "
-					       "fd = %d\n", -n, req->fds[bit]);
-					req->error = 1;
-					return;
-				}
-			} while((n < len) && (n != 0));
-			if (n < len) memset(&buf[n], 0, len - n);
-		}
-		else {
-			n = os_write_file(req->fds[bit], buf, len);
-			if(n != len){
-				printk("do_io - write failed err = %d "
-				       "fd = %d\n", -n, req->fds[bit]);
-				req->error = 1;
-				return;
-			}
-		}
-
-		start = end;
-	} while(start < nsectors);
-
-	req->error = update_bitmap(req);
-}
-
-/* Changed in start_io_thread, which is serialized by being called only
- * from ubd_init, which is an initcall.
- */
-int kernel_fd = -1;
-
-/* Only changed by the io thread */
-int io_count = 0;
-
-int io_thread(void *arg)
-{
-	struct io_thread_req req;
-	int n;
-
 	signal(SIGWINCH, SIG_IGN);
-	while(1){
-		n = os_read_file(kernel_fd, &req, sizeof(req));
-		if(n != sizeof(req)){
-			if(n < 0)
-				printk("io_thread - read failed, fd = %d, "
-				       "err = %d\n", kernel_fd, -n);
-			else {
-				printk("io_thread - short read, fd = %d, "
-				       "length = %d\n", kernel_fd, n);
-			}
-			continue;
-		}
-		io_count++;
-		do_io(&req);
-		n = os_write_file(kernel_fd, &req, sizeof(req));
-		if(n != sizeof(req))
-			printk("io_thread - write failed, fd = %d, err = %d\n",
-			       kernel_fd, -n);
-	}
 }
 
 int start_io_thread(unsigned long sp, int *fd_out)
diff -Nru a/arch/um/drivers/xterm.c b/arch/um/drivers/xterm.c
--- a/arch/um/drivers/xterm.c	2005-03-01 23:38:52 -08:00
+++ b/arch/um/drivers/xterm.c	2005-03-01 23:38:52 -08:00
@@ -97,6 +97,13 @@
 	if(os_access(argv[4], OS_ACC_X_OK) < 0)
 		argv[4] = "port-helper";
 
+	/* Check that DISPLAY is set, this doesn't guarantee the xterm
+	 * will work but w/o it we can be pretty sure it won't. */
+	if (!getenv("DISPLAY")) {
+		printk("xterm_open: $DISPLAY not set.\n");
+		return -ENODEV;
+	}
+
 	fd = mkstemp(file);
 	if(fd < 0){
 		printk("xterm_open : mkstemp failed, errno = %d\n", errno);
@@ -126,9 +133,9 @@
 
 	if(data->stack == 0) free_stack(stack, 0);
 
-	if(data->direct_rcv)
+	if (data->direct_rcv) {
 		new = os_rcv_fd(fd, &data->helper_pid);
-	else {
+	} else {
 		err = os_set_fd_block(fd, 0);
 		if(err < 0){
 			printk("xterm_open : failed to set descriptor "
diff -Nru a/arch/um/drivers/xterm_kern.c b/arch/um/drivers/xterm_kern.c
--- a/arch/um/drivers/xterm_kern.c	2005-03-01 23:39:08 -08:00
+++ b/arch/um/drivers/xterm_kern.c	2005-03-01 23:39:08 -08:00
@@ -46,6 +46,8 @@
 		printk(KERN_ERR "xterm_fd : failed to allocate xterm_wait\n");
 		return(-ENOMEM);
 	}
+
+	/* This is a locked semaphore... */
 	*data = ((struct xterm_wait) 
 		{ .sem  	= __SEMAPHORE_INITIALIZER(data->sem, 0),
 		  .fd 		= socket,
@@ -55,12 +57,17 @@
 	err = um_request_irq(XTERM_IRQ, socket, IRQ_READ, xterm_interrupt, 
 			     SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, 
 			     "xterm", data);
-	if(err){
+	if (err){
 		printk(KERN_ERR "xterm_fd : failed to get IRQ for xterm, "
 		       "err = %d\n",  err);
 		ret = err;
 		goto out;
 	}
+
+	/* ... so here we wait for an xterm interrupt.
+	 *
+	 * XXX Note, if the xterm doesn't work for some reason (eg. DISPLAY
+	 * isn't set) this will hang... */
 	down(&data->sem);
 
 	free_irq_by_irq_and_dev(XTERM_IRQ, data);
diff -Nru a/arch/um/include/chan_kern.h b/arch/um/include/chan_kern.h
--- a/arch/um/include/chan_kern.h	2005-03-01 23:38:57 -08:00
+++ b/arch/um/include/chan_kern.h	2005-03-01 23:38:57 -08:00
@@ -8,7 +8,9 @@
 
 #include "linux/tty.h"
 #include "linux/list.h"
+#include "linux/console.h"
 #include "chan_user.h"
+#include "line.h"
 
 struct chan {
 	struct list_head list;
@@ -24,7 +26,7 @@
 };
 
 extern void chan_interrupt(struct list_head *chans, struct work_struct *task,
-			   struct tty_struct *tty, int irq, void *dev);
+			   struct tty_struct *tty, int irq);
 extern int parse_chan_pair(char *str, struct list_head *chans, int pri, 
 			   int device, struct chan_opts *opts);
 extern int open_chan(struct list_head *chans);
@@ -32,9 +34,11 @@
 			     int write_irq);
 extern int console_write_chan(struct list_head *chans, const char *buf, 
 			      int len);
+extern int console_open_chan(struct line *line, struct console *co,
+			     struct chan_opts *opts);
 extern void close_chan(struct list_head *chans);
-extern void chan_enable_winch(struct list_head *chans, void *line);
-extern void enable_chan(struct list_head *chans, void *data);
+extern void chan_enable_winch(struct list_head *chans, struct tty_struct *tty);
+extern void enable_chan(struct list_head *chans, struct tty_struct *tty);
 extern int chan_window_size(struct list_head *chans, 
 			     unsigned short *rows_out, 
 			     unsigned short *cols_out);
diff -Nru a/arch/um/include/chan_user.h b/arch/um/include/chan_user.h
--- a/arch/um/include/chan_user.h	2005-03-01 23:38:57 -08:00
+++ b/arch/um/include/chan_user.h	2005-03-01 23:38:57 -08:00
@@ -42,8 +42,9 @@
 			       unsigned short *cols_out);
 extern void generic_free(void *data);
 
-extern void register_winch(int fd, void *device_data);
-extern void register_winch_irq(int fd, int tty_fd, int pid, void *line);
+struct tty_struct;
+extern void register_winch(int fd,  struct tty_struct *tty);
+extern void register_winch_irq(int fd, int tty_fd, int pid, struct tty_struct *tty);
 
 #define __channel_help(fn, prefix) \
 __uml_help(fn, prefix "[0-9]*=<channel description>\n" \
diff -Nru a/arch/um/include/elf_user.h b/arch/um/include/elf_user.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/um/include/elf_user.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2004 Fujitsu Siemens Computers GmbH
+ * Author: Bodo Stroesser <bstroesser@fujitsu-siemens.com>
+ * Licensed under the GPL
+ */
+
+#ifndef __ELF_USER_H__
+#define __ELF_USER_H__
+
+/* For compilation on a host that doesn't support AT_SYSINFO (Linux 2.4)  */
+
+#ifndef AT_SYSINFO
+#define AT_SYSINFO 32
+#endif
+#ifndef AT_SYSINFO_EHDR
+#define AT_SYSINFO_EHDR 33
+#endif
+
+#endif
diff -Nru a/arch/um/include/frame.h b/arch/um/include/frame.h
--- a/arch/um/include/frame.h	2005-03-01 23:38:55 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,53 +0,0 @@
-/* 
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#ifndef __FRAME_H_
-#define __FRAME_H_
-
-#include "sysdep/frame.h"
-
-struct frame_common {
-	void *data;
-	int len;
-	int sig_index;
-	int sr_index;
-	int sr_relative;
-	int sp_index;
-	struct arch_frame_data arch;
-};
-
-struct sc_frame {
-	struct frame_common common;
-	int sc_index;
-};
-
-extern struct sc_frame signal_frame_sc;
-
-extern struct sc_frame signal_frame_sc_sr;
-
-struct si_frame {
-	struct frame_common common;
-	int sip_index;
-	int si_index;
-	int ucp_index;
-	int uc_index;
-};
-
-extern struct si_frame signal_frame_si;
-
-extern void capture_signal_stack(void);
-
-#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 -Nru a/arch/um/include/frame_kern.h b/arch/um/include/frame_kern.h
--- a/arch/um/include/frame_kern.h	2005-03-01 23:38:57 -08:00
+++ b/arch/um/include/frame_kern.h	2005-03-01 23:38:57 -08:00
@@ -6,8 +6,8 @@
 #ifndef __FRAME_KERN_H_
 #define __FRAME_KERN_H_
 
-#include "frame.h"
-#include "sysdep/frame_kern.h"
+#define _S(nr) (1<<((nr)-1))
+#define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP)))
 
 extern int setup_signal_stack_sc(unsigned long stack_top, int sig, 
 				 struct k_sigaction *ka,
diff -Nru a/arch/um/include/frame_user.h b/arch/um/include/frame_user.h
--- a/arch/um/include/frame_user.h	2005-03-01 23:38:51 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,23 +0,0 @@
-/* 
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#ifndef __FRAME_USER_H_
-#define __FRAME_USER_H_
-
-#include "sysdep/frame_user.h"
-#include "frame.h"
-
-#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 -Nru a/arch/um/include/init.h b/arch/um/include/init.h
--- a/arch/um/include/init.h	2005-03-01 23:38:56 -08:00
+++ b/arch/um/include/init.h	2005-03-01 23:38:56 -08:00
@@ -40,9 +40,18 @@
 typedef int (*initcall_t)(void);
 typedef void (*exitcall_t)(void);
 
-#define __init          __attribute__ ((__section__ (".text.init")))
-#define __exit          __attribute__ ((unused, __section__(".text.exit")))
-#define __initdata      __attribute__ ((__section__ (".data.init")))
+/* These are for everybody (although not all archs will actually
+   discard it in modules) */
+#define __init		__attribute__ ((__section__ (".init.text")))
+#define __initdata	__attribute__ ((__section__ (".init.data")))
+#define __exitdata	__attribute__ ((__section__(".exit.data")))
+#define __exit_call	__attribute_used__ __attribute__ ((__section__ (".exitcall.exit")))
+
+#ifdef MODULE
+#define __exit		__attribute__ ((__section__(".exit.text")))
+#else
+#define __exit		__attribute_used__ __attribute__ ((__section__(".exit.text")))
+#endif
 
 #endif
 
@@ -94,11 +103,20 @@
  * Mark functions and data as being only used at initialization
  * or exit time.
  */
-#define __uml_init_setup	__attribute__ ((unused,__section__ (".uml.setup.init")))
-#define __uml_setup_help	__attribute__ ((unused,__section__ (".uml.help.init")))
-#define __uml_init_call		__attribute__ ((unused,__section__ (".uml.initcall.init")))
-#define __uml_postsetup_call	__attribute__ ((unused,__section__ (".uml.postsetup.init")))
-#define __uml_exit_call		__attribute__ ((unused,__section__ (".uml.exitcall.exit")))
+#define __uml_init_setup	__attribute_used__ __attribute__ ((__section__ (".uml.setup.init")))
+#define __uml_setup_help	__attribute_used__ __attribute__ ((__section__ (".uml.help.init")))
+#define __uml_init_call		__attribute_used__ __attribute__ ((__section__ (".uml.initcall.init")))
+#define __uml_postsetup_call	__attribute_used__ __attribute__ ((__section__ (".uml.postsetup.init")))
+#define __uml_exit_call		__attribute_used__ __attribute__ ((__section__ (".uml.exitcall.exit")))
+
+#ifndef __KERNEL__
+
+#define __initcall(fn) static initcall_t __initcall_##fn __init_call = fn
+#define __exitcall(fn) static exitcall_t __exitcall_##fn __exit_call = fn
+
+#define __init_call __attribute__ ((unused,__section__ (".initcall.init")))
+
+#endif
 
 #endif /* _LINUX_UML_INIT_H */
 
diff -Nru a/arch/um/include/line.h b/arch/um/include/line.h
--- a/arch/um/include/line.h	2005-03-01 23:39:08 -08:00
+++ b/arch/um/include/line.h	2005-03-01 23:39:08 -08:00
@@ -37,7 +37,6 @@
 	struct list_head chan_list;
 	int valid;
 	int count;
-	struct tty_struct *tty;
 	struct semaphore sem;
 	char *buffer;
 	char *head;
@@ -53,8 +52,6 @@
 	  init_pri :	INIT_STATIC, \
 	  chan_list : 	{ }, \
 	  valid :	1, \
-	  count :	0, \
-	  tty :		NULL, \
 	  sem : 	{ }, \
 	  buffer :	NULL, \
 	  head :	NULL, \
@@ -69,17 +66,22 @@
 
 #define LINES_INIT(n) {  num :		n }
 
-extern void line_close(struct line *lines, struct tty_struct *tty);
+extern void line_close(struct tty_struct *tty, struct file * filp);
 extern int line_open(struct line *lines, struct tty_struct *tty, 
 		     struct chan_opts *opts);
 extern int line_setup(struct line *lines, int num, char *init, 
 		      int all_allowed);
-extern int line_write(struct line *line, struct tty_struct *tty, const char *buf, int len);
+extern int line_write(struct tty_struct *tty, const unsigned char *buf, int len);
+extern void line_put_char(struct tty_struct *tty, unsigned char ch);
+extern void line_set_termios(struct tty_struct *tty, struct termios * old);
+extern int line_chars_in_buffer(struct tty_struct *tty);
 extern int line_write_room(struct tty_struct *tty);
+extern int line_ioctl(struct tty_struct *tty, struct file * file,
+		      unsigned int cmd, unsigned long arg);
 extern char *add_xterm_umid(char *base);
-extern int line_setup_irq(int fd, int input, int output, void *data);
+extern int line_setup_irq(int fd, int input, int output, struct tty_struct *tty);
 extern void line_close_chan(struct line *line);
-extern void line_disable(struct line *line, int current_irq);
+extern void line_disable(struct tty_struct *tty, int current_irq);
 extern struct tty_driver * line_register_devfs(struct lines *set, 
 				struct line_driver *line_driver, 
 				struct tty_operations *driver,
diff -Nru a/arch/um/include/net_kern.h b/arch/um/include/net_kern.h
--- a/arch/um/include/net_kern.h	2005-03-01 23:39:09 -08:00
+++ b/arch/um/include/net_kern.h	2005-03-01 23:39:09 -08:00
@@ -14,6 +14,7 @@
 struct uml_net {
 	struct list_head list;
 	struct net_device *dev;
+	struct platform_device pdev;
 	int index;
 	unsigned char mac[ETH_ALEN];
 	int have_mac;
diff -Nru a/arch/um/include/process.h b/arch/um/include/process.h
--- a/arch/um/include/process.h	2005-03-01 23:38:53 -08:00
+++ b/arch/um/include/process.h	2005-03-01 23:38:53 -08:00
@@ -6,7 +6,7 @@
 #ifndef __PROCESS_H__
 #define __PROCESS_H__
 
-#include <asm/sigcontext.h>
+#include <signal.h>
 
 extern void sig_handler(int sig, struct sigcontext sc);
 extern void alarm_handler(int sig, struct sigcontext sc);
diff -Nru a/arch/um/include/ptrace_user.h b/arch/um/include/ptrace_user.h
--- a/arch/um/include/ptrace_user.h	2005-03-01 23:38:52 -08:00
+++ b/arch/um/include/ptrace_user.h	2005-03-01 23:38:52 -08:00
@@ -11,6 +11,7 @@
 extern int ptrace_getregs(long pid, unsigned long *regs_out);
 extern int ptrace_setregs(long pid, unsigned long *regs_in);
 extern int ptrace_getfpregs(long pid, unsigned long *regs_out);
+extern int ptrace_setfpregs(long pid, unsigned long *regs);
 extern void arch_enter_kernel(void *task, int pid);
 extern void arch_leave_kernel(void *task, int pid);
 extern void ptrace_pokeuser(unsigned long addr, unsigned long data);
@@ -21,9 +22,39 @@
 #ifndef PTRACE_SYSEMU
 #define PTRACE_SYSEMU 31
 #endif
+#ifndef PTRACE_SYSEMU_SINGLESTEP
+#define PTRACE_SYSEMU_SINGLESTEP 32
+#endif
+
+/* On architectures, that started to support PTRACE_O_TRACESYSGOOD
+ * in linux 2.4, there are two different definitions of
+ * PTRACE_SETOPTIONS: linux 2.4 uses 21 while linux 2.6 uses 0x4200.
+ * For binary compatibility, 2.6 also supports the old "21", named
+ * PTRACE_OLDSETOPTION. On these architectures, UML always must use
+ * "21", to ensure the kernel runs on 2.4 and 2.6 host without
+ * recompilation. So, we use PTRACE_OLDSETOPTIONS in UML.
+ * We also want to be able to build the kernel on 2.4, which doesn't
+ * have PTRACE_OLDSETOPTIONS. So, if it is missing, we declare
+ * PTRACE_OLDSETOPTIONS to to be the same as PTRACE_SETOPTIONS.
+ *
+ * On architectures, that start to support PTRACE_O_TRACESYSGOOD on
+ * linux 2.6, PTRACE_OLDSETOPTIONS never is defined, and also isn't
+ * supported by the host kernel. In that case, our trick lets us use
+ * the new 0x4200 with the name PTRACE_OLDSETOPTIONS.
+ */
+#ifndef PTRACE_OLDSETOPTIONS
+#define PTRACE_OLDSETOPTIONS PTRACE_SETOPTIONS
+#endif
 
 void set_using_sysemu(int value);
 int get_using_sysemu(void);
 extern int sysemu_supported;
+
+#define SELECT_PTRACE_OPERATION(sysemu_mode, singlestep_mode) \
+	(((int[3][3] ) { \
+		{ PTRACE_SYSCALL, PTRACE_SYSCALL, PTRACE_SINGLESTEP }, \
+		{ PTRACE_SYSEMU, PTRACE_SYSEMU, PTRACE_SINGLESTEP }, \
+		{ PTRACE_SYSEMU, PTRACE_SYSEMU_SINGLESTEP, PTRACE_SYSEMU_SINGLESTEP }}) \
+		[sysemu_mode][singlestep_mode])
 
 #endif
diff -Nru a/arch/um/include/registers.h b/arch/um/include/registers.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/um/include/registers.h	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2004 PathScale, Inc
+ * Licensed under the GPL
+ */
+
+#ifndef __REGISTERS_H
+#define __REGISTERS_H
+
+#include "sysdep/ptrace.h"
+
+extern void init_thread_registers(union uml_pt_regs *to);
+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);
+
+#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 -Nru a/arch/um/include/sysdep-i386/checksum.h b/arch/um/include/sysdep-i386/checksum.h
--- a/arch/um/include/sysdep-i386/checksum.h	2005-03-01 23:39:18 -08:00
+++ b/arch/um/include/sysdep-i386/checksum.h	2005-03-01 23:39:18 -08:00
@@ -31,10 +31,10 @@
  * better 64-bit) boundary
  */
 
-unsigned int csum_partial_copy_to(const char *src, char *dst, int len, 
-				  int sum, int *err_ptr);
-unsigned int csum_partial_copy_from(const char *src, char *dst, int len, 
-				    int sum, int *err_ptr);
+unsigned int csum_partial_copy_to(const unsigned char *src, unsigned char *dst,
+				  int len, int sum, int *err_ptr);
+unsigned int csum_partial_copy_from(const unsigned char *src, unsigned char *dst,
+				    int len, int sum, int *err_ptr);
 
 /*
  *	Note: when you get a NULL pointer exception here this means someone
@@ -45,7 +45,7 @@
  */
 
 static __inline__
-unsigned int csum_partial_copy_nocheck(const char *src, char *dst,
+unsigned int csum_partial_copy_nocheck(const unsigned char *src, unsigned char *dst,
 				       int len, int sum)
 {
 	memcpy(dst, src, len);
@@ -53,7 +53,7 @@
 }
 
 static __inline__
-unsigned int csum_partial_copy_from_user(const char *src, char *dst,
+unsigned int csum_partial_copy_from_user(const unsigned char *src, unsigned char *dst,
 					 int len, int sum, int *err_ptr)
 {
 	return csum_partial_copy_from(src, dst, len, sum, err_ptr);
@@ -67,7 +67,7 @@
  */
 
 #define csum_partial_copy_fromuser csum_partial_copy_from_user
-unsigned int csum_partial_copy( const char *src, char *dst, int len, int sum);
+unsigned int csum_partial_copy(const unsigned char *src, unsigned char *dst, int len, int sum);
 
 /*
  *	This is a version of ip_compute_csum() optimized for IP headers,
@@ -192,9 +192,9 @@
  *	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)
+static __inline__ unsigned int csum_and_copy_to_user(const unsigned char *src,
+						     unsigned char *dst,
+						     int len, int sum, int *err_ptr)
 {
 	if (access_ok(VERIFY_WRITE, dst, len))
 		return(csum_partial_copy_to(src, dst, len, sum, err_ptr));
diff -Nru a/arch/um/include/sysdep-i386/frame.h b/arch/um/include/sysdep-i386/frame.h
--- a/arch/um/include/sysdep-i386/frame.h	2005-03-01 23:39:07 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,29 +0,0 @@
-/* 
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#ifndef __FRAME_I386_H
-#define __FRAME_I386_H
-
-struct arch_frame_data_raw {
-	unsigned long fp_start;
-	unsigned long sr;
-};
-
-struct arch_frame_data {
-	int fpstate_size;
-};
-
-#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 -Nru a/arch/um/include/sysdep-i386/frame_kern.h b/arch/um/include/sysdep-i386/frame_kern.h
--- a/arch/um/include/sysdep-i386/frame_kern.h	2005-03-01 23:38:53 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,69 +0,0 @@
-/* 
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#ifndef __FRAME_KERN_I386_H
-#define __FRAME_KERN_I386_H
-
-/* This is called from sys_sigreturn.  It takes the sp at the point of the
- * sigreturn system call and returns the address of the sigcontext struct
- * on the stack.
- */
-
-static inline void *sp_to_sc(unsigned long sp)
-{
-	return((void *) sp);
-}
-
-static inline void *sp_to_uc(unsigned long sp)
-{
-	unsigned long uc;
-
-	uc = sp + signal_frame_si.uc_index - 
-		signal_frame_si.common.sp_index - 4;
-	return((void *) uc);
-}
-
-static inline void *sp_to_rt_sc(unsigned long sp)
-{
-	unsigned long sc;
-
-	sc = sp - signal_frame_si.common.sp_index + 
-		signal_frame_si.common.len - 4;
-	return((void *) sc);
-}
-
-static inline void *sp_to_mask(unsigned long sp)
-{
-	unsigned long mask;
-
-	mask = sp - signal_frame_sc.common.sp_index + 
-		signal_frame_sc.common.len - 8;
-	return((void *) mask);
-}
-
-extern int sc_size(void *data);
-
-static inline void *sp_to_rt_mask(unsigned long sp)
-{
-	unsigned long mask;
-
-	mask = sp - signal_frame_si.common.sp_index + 
-		signal_frame_si.common.len + 
-		sc_size(&signal_frame_si.common.arch) - 4;
-	return((void *) mask);
-}
-
-#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 -Nru a/arch/um/include/sysdep-i386/frame_user.h b/arch/um/include/sysdep-i386/frame_user.h
--- a/arch/um/include/sysdep-i386/frame_user.h	2005-03-01 23:39:16 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,91 +0,0 @@
-/* 
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#ifndef __FRAME_USER_I386_H
-#define __FRAME_USER_I386_H
-
-#include <asm/page.h>
-#include "sysdep/frame.h"
-
-/* This stuff is to calculate the size of the fp state struct at runtime
- * because it has changed between 2.2 and 2.4 and it would be good for a
- * UML compiled on one to work on the other.
- * So, setup_arch_frame_raw fills in the arch struct with the raw data, which
- * just contains the address of the end of the sigcontext.  This is invoked
- * from the signal handler.
- * setup_arch_frame uses that data to figure out what 
- * arch_frame_data.fpstate_size should be.  It really has no idea, since it's
- * not allowed to do sizeof(struct fpstate) but it's safe to consider that it's
- * everything from the end of the sigcontext up to the top of the stack.  So,
- * it masks off the page number to get the offset within the page and subtracts
- * that from the page size, and that's how big the fpstate struct will be
- * considered to be.
- */
-
-static inline void setup_arch_frame_raw(struct arch_frame_data_raw *data,
-					void *end, unsigned long srp)
-{
-	unsigned long sr = *((unsigned long *) srp);
-
-	data->fp_start = (unsigned long) end;
-	if((sr & PAGE_MASK) == ((unsigned long) end & PAGE_MASK))
-		data->sr = sr;
-	else data->sr = 0;
-}
-
-static inline void setup_arch_frame(struct arch_frame_data_raw *in, 
-				    struct arch_frame_data *out)
-{
-	unsigned long fpstate_start = in->fp_start;
-
-	if(in->sr == 0){
-		fpstate_start &= ~PAGE_MASK;
-		out->fpstate_size = PAGE_SIZE - fpstate_start;
-	}
-	else {
-		out->fpstate_size = in->sr - fpstate_start;
-	}
-}
-
-/* This figures out where on the stack the SA_RESTORER function address
- * is stored.  For i386, it's the signal handler return address, so it's
- * located next to the frame pointer.
- * This is inlined, so __builtin_frame_address(0) is correct.  Otherwise,
- * it would have to be __builtin_frame_address(1).
- */
-
-#define frame_restorer() \
-({ \
-	unsigned long *fp; \
-\
-	fp = __builtin_frame_address(0); \
-	((unsigned long) (fp + 1)); \
-})
-
-/* Similarly, this returns the value of sp when the handler was first
- * entered.  This is used to calculate the proper sp when delivering
- * signals.
- */
-
-#define frame_sp() \
-({ \
-	unsigned long *fp; \
-\
-	fp = __builtin_frame_address(0); \
-	((unsigned long) (fp + 1)); \
-})
-
-#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 -Nru a/arch/um/include/sysdep-i386/ptrace.h b/arch/um/include/sysdep-i386/ptrace.h
--- a/arch/um/include/sysdep-i386/ptrace.h	2005-03-01 23:38:53 -08:00
+++ b/arch/um/include/sysdep-i386/ptrace.h	2005-03-01 23:38:53 -08:00
@@ -9,11 +9,55 @@
 #include "uml-config.h"
 
 #ifdef UML_CONFIG_MODE_TT
-#include "ptrace-tt.h"
+#include "sysdep/sc.h"
 #endif
 
 #ifdef UML_CONFIG_MODE_SKAS
-#include "ptrace-skas.h"
+
+/* syscall emulation path in ptrace */
+
+#ifndef PTRACE_SYSEMU
+#define PTRACE_SYSEMU 31
+#endif
+
+void set_using_sysemu(int value);
+int get_using_sysemu(void);
+extern int sysemu_supported;
+
+#include "skas_ptregs.h"
+
+#define HOST_FRAME_SIZE 17
+
+#define REGS_IP(r) ((r)[HOST_IP])
+#define REGS_SP(r) ((r)[HOST_SP])
+#define REGS_EFLAGS(r) ((r)[HOST_EFLAGS])
+#define REGS_EAX(r) ((r)[HOST_EAX])
+#define REGS_EBX(r) ((r)[HOST_EBX])
+#define REGS_ECX(r) ((r)[HOST_ECX])
+#define REGS_EDX(r) ((r)[HOST_EDX])
+#define REGS_ESI(r) ((r)[HOST_ESI])
+#define REGS_EDI(r) ((r)[HOST_EDI])
+#define REGS_EBP(r) ((r)[HOST_EBP])
+#define REGS_CS(r) ((r)[HOST_CS])
+#define REGS_SS(r) ((r)[HOST_SS])
+#define REGS_DS(r) ((r)[HOST_DS])
+#define REGS_ES(r) ((r)[HOST_ES])
+#define REGS_FS(r) ((r)[HOST_FS])
+#define REGS_GS(r) ((r)[HOST_GS])
+
+#define REGS_SET_SYSCALL_RETURN(r, res) REGS_EAX(r) = (res)
+
+#define REGS_RESTART_SYSCALL(r) IP_RESTART_SYSCALL(REGS_IP(r))
+
+#define REGS_SEGV_IS_FIXABLE(r) SEGV_IS_FIXABLE((r)->trap_type)
+
+#define REGS_FAULT_ADDR(r) ((r)->fault_addr)
+
+#define REGS_FAULT_WRITE(r) FAULT_WRITE((r)->fault_type)
+
+#endif
+#ifndef PTRACE_SYSEMU_SINGLESTEP
+#define PTRACE_SYSEMU_SINGLESTEP 32
 #endif
 
 #include "choose-mode.h"
diff -Nru 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	2005-03-01 23:39:09 -08:00
+++ b/arch/um/include/sysdep-i386/ptrace_user.h	2005-03-01 23:39:09 -08:00
@@ -33,6 +33,9 @@
 #define FP_FRAME_SIZE (27)
 #define FPX_FRAME_SIZE (128)
 
+#define MAX_REG_OFFSET (FRAME_SIZE_OFFSET)
+#define MAX_REG_NR (FRAME_SIZE)
+
 #ifdef PTRACE_GETREGS
 #define UM_HAVE_GETREGS
 #endif
diff -Nru a/arch/um/include/sysdep-i386/signal.h b/arch/um/include/sysdep-i386/signal.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/um/include/sysdep-i386/signal.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2004 PathScale, Inc
+ * Licensed under the GPL
+ */
+
+#ifndef __I386_SIGNAL_H_
+#define __I386_SIGNAL_H_
+
+#include <signal.h>
+
+#define ARCH_GET_SIGCONTEXT(sc, sig) \
+	do sc = (struct sigcontext *) (&sig + 1); while(0)
+
+#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 -Nru a/arch/um/include/sysdep-i386/syscalls.h b/arch/um/include/sysdep-i386/syscalls.h
--- a/arch/um/include/sysdep-i386/syscalls.h	2005-03-01 23:38:52 -08:00
+++ b/arch/um/include/sysdep-i386/syscalls.h	2005-03-01 23:38:52 -08:00
@@ -8,11 +8,70 @@
 
 typedef long syscall_handler_t(struct pt_regs);
 
+/* Not declared on x86, incompatible declarations on x86_64, so these have
+ * to go here rather than in sys_call_table.c
+ */
+extern syscall_handler_t sys_ptrace;
+extern syscall_handler_t sys_rt_sigaction;
+
+extern syscall_handler_t old_mmap_i386;
+
 #define EXECUTE_SYSCALL(syscall, regs) \
 	((long (*)(struct syscall_args)) (*sys_call_table[syscall]))(SYSCALL_ARGS(&regs->regs))
 
+extern long sys_mmap2(unsigned long addr, unsigned long len,
+		      unsigned long prot, unsigned long flags,
+		      unsigned long fd, unsigned long pgoff);
+
 #define ARCH_SYSCALLS \
+	[ __NR_waitpid ] = (syscall_handler_t *) sys_waitpid, \
+	[ __NR_break ] = (syscall_handler_t *) sys_ni_syscall, \
+	[ __NR_oldstat ] = (syscall_handler_t *) sys_stat, \
+	[ __NR_umount ] = (syscall_handler_t *) sys_oldumount, \
+	[ __NR_stime ] = um_stime, \
+	[ __NR_oldfstat ] = (syscall_handler_t *) sys_fstat, \
+	[ __NR_stty ] = (syscall_handler_t *) sys_ni_syscall, \
+	[ __NR_gtty ] = (syscall_handler_t *) sys_ni_syscall, \
+	[ __NR_nice ] = (syscall_handler_t *) sys_nice, \
+	[ __NR_ftime ] = (syscall_handler_t *) sys_ni_syscall, \
+	[ __NR_prof ] = (syscall_handler_t *) sys_ni_syscall, \
+	[ __NR_signal ] = (syscall_handler_t *) sys_signal, \
+	[ __NR_lock ] = (syscall_handler_t *) sys_ni_syscall, \
+	[ __NR_mpx ] = (syscall_handler_t *) sys_ni_syscall, \
+	[ __NR_ulimit ] = (syscall_handler_t *) sys_ni_syscall, \
+	[ __NR_oldolduname ] = (syscall_handler_t *) sys_olduname, \
+	[ __NR_sigaction ] = (syscall_handler_t *) sys_sigaction, \
+	[ __NR_sgetmask ] = (syscall_handler_t *) sys_sgetmask, \
+	[ __NR_ssetmask ] = (syscall_handler_t *) sys_ssetmask, \
+	[ __NR_sigsuspend ] = (syscall_handler_t *) sys_sigsuspend, \
+	[ __NR_sigpending ] = (syscall_handler_t *) sys_sigpending, \
+	[ __NR_oldlstat ] = (syscall_handler_t *) sys_lstat, \
+	[ __NR_readdir ] = old_readdir, \
+	[ __NR_profil ] = (syscall_handler_t *) sys_ni_syscall, \
+	[ __NR_socketcall ] = (syscall_handler_t *) sys_socketcall, \
+	[ __NR_olduname ] = (syscall_handler_t *) sys_uname, \
+	[ __NR_iopl ] = (syscall_handler_t *) sys_ni_syscall, \
+	[ __NR_idle ] = (syscall_handler_t *) sys_ni_syscall, \
+	[ __NR_ipc ] = (syscall_handler_t *) sys_ipc, \
+	[ __NR_sigreturn ] = (syscall_handler_t *) sys_sigreturn, \
+	[ __NR_sigprocmask ] = (syscall_handler_t *) sys_sigprocmask, \
+	[ __NR_bdflush ] = (syscall_handler_t *) sys_bdflush, \
+	[ __NR__llseek ] = (syscall_handler_t *) sys_llseek, \
+	[ __NR__newselect ] = (syscall_handler_t *) sys_select, \
+	[ __NR_vm86 ] = (syscall_handler_t *) sys_ni_syscall, \
 	[ __NR_mmap ] = (syscall_handler_t *) old_mmap_i386, \
+	[ __NR_ugetrlimit ] = (syscall_handler_t *) sys_getrlimit, \
+	[ __NR_mmap2 ] = (syscall_handler_t *) sys_mmap2, \
+	[ __NR_truncate64 ] = (syscall_handler_t *) sys_truncate64, \
+	[ __NR_ftruncate64 ] = (syscall_handler_t *) sys_ftruncate64, \
+	[ __NR_stat64 ] = (syscall_handler_t *) sys_stat64, \
+	[ __NR_lstat64 ] = (syscall_handler_t *) sys_lstat64, \
+	[ __NR_fstat64 ] = (syscall_handler_t *) sys_fstat64, \
+	[ __NR_fcntl64 ] = (syscall_handler_t *) sys_fcntl64, \
+	[ __NR_sendfile64 ] = (syscall_handler_t *) sys_sendfile64, \
+	[ __NR_statfs64 ] = (syscall_handler_t *) sys_statfs64, \
+	[ __NR_fstatfs64 ] = (syscall_handler_t *) sys_fstatfs64, \
+	[ __NR_fadvise64_64 ] = (syscall_handler_t *) sys_fadvise64_64, \
 	[ __NR_select ] = (syscall_handler_t *) old_select, \
 	[ __NR_vm86old ] = (syscall_handler_t *) sys_ni_syscall, \
         [ __NR_modify_ldt ] = (syscall_handler_t *) sys_modify_ldt, \
@@ -38,11 +97,19 @@
 	[ __NR_pivot_root ] = (syscall_handler_t *) sys_pivot_root, \
 	[ __NR_mincore ] = (syscall_handler_t *) sys_mincore, \
 	[ __NR_madvise ] = (syscall_handler_t *) sys_madvise, \
-        [ 222 ] = (syscall_handler_t *) sys_ni_syscall,
+        [ 222 ] = (syscall_handler_t *) sys_ni_syscall, \
+	[ 223 ] = (syscall_handler_t *) sys_ni_syscall, \
+	[ __NR_set_thread_area ] = (syscall_handler_t *) sys_ni_syscall, \
+	[ __NR_get_thread_area ] = (syscall_handler_t *) sys_ni_syscall, \
+	[ __NR_fadvise64 ] = (syscall_handler_t *) sys_fadvise64, \
+	[ 251 ] = (syscall_handler_t *) sys_ni_syscall, \
+        [ __NR_remap_file_pages ] = (syscall_handler_t *) sys_remap_file_pages, \
+	[ __NR_utimes ] = (syscall_handler_t *) sys_utimes, \
+	[ __NR_vserver ] = (syscall_handler_t *) sys_ni_syscall,
         
 /* 222 doesn't yet have a name in include/asm-i386/unistd.h */
 
-#define LAST_ARCH_SYSCALL 222
+#define LAST_ARCH_SYSCALL __NR_vserver
 
 /*
  * Overrides for Emacs so that we follow Linus's tabbing style.
diff -Nru a/arch/um/include/sysdep-ppc/syscalls.h b/arch/um/include/sysdep-ppc/syscalls.h
--- a/arch/um/include/sysdep-ppc/syscalls.h	2005-03-01 23:38:44 -08:00
+++ b/arch/um/include/sysdep-ppc/syscalls.h	2005-03-01 23:38:44 -08:00
@@ -34,9 +34,12 @@
 	[ __NR_multiplexer ] = sys_ni_syscall, \
 	[ __NR_mmap ] = old_mmap, \
 	[ __NR_madvise ] = sys_madvise, \
-	[ __NR_mincore ] = sys_mincore, 
+	[ __NR_mincore ] = sys_mincore, \
+	[ __NR_iopl ] = (syscall_handler_t *) sys_ni_syscall, \
+	[ __NR_utimes ] = (syscall_handler_t *) sys_utimes, \
+	[ __NR_fadvise64 ] = (syscall_handler_t *) sys_fadvise64,
 
-#define LAST_ARCH_SYSCALL __NR_mincore
+#define LAST_ARCH_SYSCALL __NR_fadvise64
 
 /*
  * Overrides for Emacs so that we follow Linus's tabbing style.
diff -Nru a/arch/um/include/sysdep-x86_64/checksum.h b/arch/um/include/sysdep-x86_64/checksum.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/um/include/sysdep-x86_64/checksum.h	2005-03-01 23:39:26 -08:00
@@ -0,0 +1,151 @@
+/*
+ * Licensed under the GPL
+ */
+
+#ifndef __UM_SYSDEP_CHECKSUM_H
+#define __UM_SYSDEP_CHECKSUM_H
+
+#include "linux/string.h"
+#include "linux/in6.h"
+#include "asm/uaccess.h"
+
+extern unsigned int csum_partial_copy_from(const char *src, char *dst, int len,
+					   int sum, int *err_ptr);
+extern unsigned csum_partial(const unsigned char *buff, unsigned len,
+                             unsigned sum);
+
+/*
+ *	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().
+ */
+
+static __inline__
+unsigned int csum_partial_copy_nocheck(const char *src, char *dst,
+				       int len, int sum)
+{
+	memcpy(dst, src, len);
+	return(csum_partial(dst, len, sum));
+}
+
+static __inline__
+unsigned int csum_partial_copy_from_user(const char *src, char *dst,
+					 int len, int sum, int *err_ptr)
+{
+	return csum_partial_copy_from(src, dst, len, sum, err_ptr);
+}
+
+/**
+ * csum_fold - Fold and invert a 32bit checksum.
+ * sum: 32bit unfolded sum
+ *
+ * Fold a 32bit running checksum to 16bit and invert it. This is usually
+ * the last step before putting a checksum into a packet.
+ * Make sure not to mix with 64bit checksums.
+ */
+static inline unsigned int csum_fold(unsigned int sum)
+{
+	__asm__(
+		"  addl %1,%0\n"
+		"  adcl $0xffff,%0"
+		: "=r" (sum)
+		: "r" (sum << 16), "0" (sum & 0xffff0000)
+	);
+	return (~sum) >> 16;
+}
+
+/**
+ * csum_tcpup_nofold - Compute an IPv4 pseudo header checksum.
+ * @saddr: source address
+ * @daddr: destination address
+ * @len: length of packet
+ * @proto: ip protocol of packet
+ * @sum: initial sum to be added in (32bit unfolded)
+ *
+ * Returns the pseudo header checksum the input data. Result is
+ * 32bit unfolded.
+ */
+static inline unsigned long
+csum_tcpudp_nofold(unsigned saddr, unsigned daddr, unsigned short len,
+		   unsigned short proto, unsigned int sum)
+{
+	asm("  addl %1, %0\n"
+	    "  adcl %2, %0\n"
+	    "  adcl %3, %0\n"
+	    "  adcl $0, %0\n"
+		: "=r" (sum)
+	    : "g" (daddr), "g" (saddr), "g" ((ntohs(len)<<16)+proto*256), "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));
+}
+
+/**
+ * ip_fast_csum - Compute the IPv4 header checksum efficiently.
+ * iph: ipv4 header
+ * ihl: length of header / 4
+ */
+static inline unsigned short ip_fast_csum(unsigned char *iph, unsigned int ihl)
+{
+	unsigned int sum;
+
+	asm(	"  movl (%1), %0\n"
+		"  subl $4, %2\n"
+		"  jbe 2f\n"
+		"  addl 4(%1), %0\n"
+		"  adcl 8(%1), %0\n"
+		"  adcl 12(%1), %0\n"
+		"1: adcl 16(%1), %0\n"
+		"  lea 4(%1), %1\n"
+		"  decl %2\n"
+		"  jne	1b\n"
+		"  adcl $0, %0\n"
+		"  movl %0, %2\n"
+		"  shrl $16, %0\n"
+		"  addw %w2, %w0\n"
+		"  adcl $0, %0\n"
+		"  notl %0\n"
+		"2:"
+	/* Since the input registers which are loaded with iph and ipl
+	   are modified, we must also specify them as outputs, or gcc
+	   will assume they contain their original values. */
+	: "=r" (sum), "=r" (iph), "=r" (ihl)
+	: "1" (iph), "2" (ihl)
+	: "memory");
+	return(sum);
+}
+
+static inline unsigned add32_with_carry(unsigned a, unsigned b)
+{
+        asm("addl %2,%0\n\t"
+            "adcl $0,%0"
+            : "=r" (a)
+            : "0" (a), "r" (b));
+        return a;
+}
+
+#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 -Nru a/arch/um/include/sysdep-x86_64/ptrace.h b/arch/um/include/sysdep-x86_64/ptrace.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/um/include/sysdep-x86_64/ptrace.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,260 @@
+/*
+ * Copyright 2003 PathScale, Inc.
+ *
+ * Licensed under the GPL
+ */
+
+#ifndef __SYSDEP_X86_64_PTRACE_H
+#define __SYSDEP_X86_64_PTRACE_H
+
+#include "uml-config.h"
+
+#ifdef UML_CONFIG_MODE_TT
+#include "sysdep/sc.h"
+#endif
+
+#ifdef UML_CONFIG_MODE_SKAS
+#include "skas_ptregs.h"
+
+#define REGS_IP(r) ((r)[HOST_IP])
+#define REGS_SP(r) ((r)[HOST_SP])
+
+#define REGS_RBX(r) ((r)[HOST_RBX])
+#define REGS_RCX(r) ((r)[HOST_RCX])
+#define REGS_RDX(r) ((r)[HOST_RDX])
+#define REGS_RSI(r) ((r)[HOST_RSI])
+#define REGS_RDI(r) ((r)[HOST_RDI])
+#define REGS_RBP(r) ((r)[HOST_RBP])
+#define REGS_RAX(r) ((r)[HOST_RAX])
+#define REGS_R8(r) ((r)[HOST_R8])
+#define REGS_R9(r) ((r)[HOST_R9])
+#define REGS_R10(r) ((r)[HOST_R10])
+#define REGS_R11(r) ((r)[HOST_R11])
+#define REGS_R12(r) ((r)[HOST_R12])
+#define REGS_R13(r) ((r)[HOST_R13])
+#define REGS_R14(r) ((r)[HOST_R14])
+#define REGS_R15(r) ((r)[HOST_R15])
+#define REGS_CS(r) ((r)[HOST_CS])
+#define REGS_EFLAGS(r) ((r)[HOST_EFLAGS])
+#define REGS_SS(r) ((r)[HOST_SS])
+
+#define HOST_FS_BASE 21
+#define HOST_GS_BASE 22
+#define HOST_DS 23
+#define HOST_ES 24
+#define HOST_FS 25
+#define HOST_GS 26
+
+#define REGS_FS_BASE(r) ((r)[HOST_FS_BASE])
+#define REGS_GS_BASE(r) ((r)[HOST_GS_BASE])
+#define REGS_DS(r) ((r)[HOST_DS])
+#define REGS_ES(r) ((r)[HOST_ES])
+#define REGS_FS(r) ((r)[HOST_FS])
+#define REGS_GS(r) ((r)[HOST_GS])
+
+#define REGS_ORIG_RAX(r) ((r)[HOST_ORIG_RAX])
+
+#define REGS_SET_SYSCALL_RETURN(r, res) REGS_RAX(r) = (res)
+
+#define REGS_RESTART_SYSCALL(r) IP_RESTART_SYSCALL(REGS_IP(r))
+
+#define REGS_SEGV_IS_FIXABLE(r) SEGV_IS_FIXABLE((r)->trap_type)
+
+#define REGS_FAULT_ADDR(r) ((r)->fault_addr)
+
+#define REGS_FAULT_WRITE(r) FAULT_WRITE((r)->fault_type)
+
+#define REGS_TRAP(r) ((r)->trap_type)
+
+#define REGS_ERR(r) ((r)->fault_type)
+
+#endif
+
+#include "choose-mode.h"
+
+/* XXX */
+union uml_pt_regs {
+#ifdef UML_CONFIG_MODE_TT
+	struct tt_regs {
+		long syscall;
+		unsigned long orig_rax;
+		void *sc;
+	} tt;
+#endif
+#ifdef UML_CONFIG_MODE_SKAS
+	struct skas_regs {
+		/* XXX */
+		unsigned long regs[27];
+		unsigned long fp[65];
+		unsigned long fault_addr;
+		unsigned long fault_type;
+		unsigned long trap_type;
+		long syscall;
+		int is_user;
+	} skas;
+#endif
+};
+
+#define EMPTY_UML_PT_REGS { }
+
+/* XXX */
+extern int mode_tt;
+
+#define UPT_RBX(r) CHOOSE_MODE(SC_RBX(UPT_SC(r)), REGS_RBX((r)->skas.regs))
+#define UPT_RCX(r) CHOOSE_MODE(SC_RCX(UPT_SC(r)), REGS_RCX((r)->skas.regs))
+#define UPT_RDX(r) CHOOSE_MODE(SC_RDX(UPT_SC(r)), REGS_RDX((r)->skas.regs))
+#define UPT_RSI(r) CHOOSE_MODE(SC_RSI(UPT_SC(r)), REGS_RSI((r)->skas.regs))
+#define UPT_RDI(r) CHOOSE_MODE(SC_RDI(UPT_SC(r)), REGS_RDI((r)->skas.regs))
+#define UPT_RBP(r) CHOOSE_MODE(SC_RBP(UPT_SC(r)), REGS_RBP((r)->skas.regs))
+#define UPT_RAX(r) CHOOSE_MODE(SC_RAX(UPT_SC(r)), REGS_RAX((r)->skas.regs))
+#define UPT_R8(r) CHOOSE_MODE(SC_R8(UPT_SC(r)), REGS_R8((r)->skas.regs))
+#define UPT_R9(r) CHOOSE_MODE(SC_R9(UPT_SC(r)), REGS_R9((r)->skas.regs))
+#define UPT_R10(r) CHOOSE_MODE(SC_R10(UPT_SC(r)), REGS_R10((r)->skas.regs))
+#define UPT_R11(r) CHOOSE_MODE(SC_R11(UPT_SC(r)), REGS_R11((r)->skas.regs))
+#define UPT_R12(r) CHOOSE_MODE(SC_R12(UPT_SC(r)), REGS_R12((r)->skas.regs))
+#define UPT_R13(r) CHOOSE_MODE(SC_R13(UPT_SC(r)), REGS_R13((r)->skas.regs))
+#define UPT_R14(r) CHOOSE_MODE(SC_R14(UPT_SC(r)), REGS_R14((r)->skas.regs))
+#define UPT_R15(r) CHOOSE_MODE(SC_R15(UPT_SC(r)), REGS_R15((r)->skas.regs))
+#define UPT_CS(r) CHOOSE_MODE(SC_CS(UPT_SC(r)), REGS_CS((r)->skas.regs))
+#define UPT_FS(r) CHOOSE_MODE(SC_FS(UPT_SC(r)), REGS_FS((r)->skas.regs))
+#define UPT_GS(r) CHOOSE_MODE(SC_GS(UPT_SC(r)), REGS_GS((r)->skas.regs))
+#define UPT_DS(r) CHOOSE_MODE(SC_DS(UPT_SC(r)), REGS_DS((r)->skas.regs))
+#define UPT_ES(r) CHOOSE_MODE(SC_ES(UPT_SC(r)), REGS_ES((r)->skas.regs))
+#define UPT_CS(r) CHOOSE_MODE(SC_CS(UPT_SC(r)), REGS_CS((r)->skas.regs))
+#define UPT_ORIG_RAX(r) \
+	CHOOSE_MODE((r)->tt.orig_rax, REGS_ORIG_RAX((r)->skas.regs))
+
+#define UPT_IP(r) CHOOSE_MODE(SC_IP(UPT_SC(r)), REGS_IP((r)->skas.regs))
+#define UPT_SP(r) CHOOSE_MODE(SC_SP(UPT_SC(r)), REGS_SP((r)->skas.regs))
+
+#define UPT_EFLAGS(r) \
+	CHOOSE_MODE(SC_EFLAGS(UPT_SC(r)), REGS_EFLAGS((r)->skas.regs))
+#define UPT_SC(r) ((r)->tt.sc)
+#define UPT_SYSCALL_NR(r) CHOOSE_MODE((r)->tt.syscall, (r)->skas.syscall)
+
+extern int user_context(unsigned long sp);
+
+#define UPT_IS_USER(r) \
+	CHOOSE_MODE(user_context(UPT_SP(r)), (r)->skas.is_user)
+
+#define UPT_SYSCALL_ARG1(r) UPT_RDI(r)
+#define UPT_SYSCALL_ARG2(r) UPT_RSI(r)
+#define UPT_SYSCALL_ARG3(r) UPT_RDX(r)
+#define UPT_SYSCALL_ARG4(r) UPT_R10(r)
+#define UPT_SYSCALL_ARG5(r) UPT_R8(r)
+#define UPT_SYSCALL_ARG6(r) UPT_R9(r)
+
+struct syscall_args {
+	unsigned long args[6];
+};
+
+#define SYSCALL_ARGS(r) ((struct syscall_args) \
+                        { .args = { UPT_SYSCALL_ARG1(r), \
+                                    UPT_SYSCALL_ARG2(r), \
+ 			            UPT_SYSCALL_ARG3(r), \
+                                    UPT_SYSCALL_ARG4(r), \
+		                    UPT_SYSCALL_ARG5(r), \
+                                    UPT_SYSCALL_ARG6(r) } } )
+
+#define UPT_REG(regs, reg) \
+        ({      unsigned long val; \
+                switch(reg){ \
+		case R8: val = UPT_R8(regs); break; \
+		case R9: val = UPT_R9(regs); break; \
+		case R10: val = UPT_R10(regs); break; \
+		case R11: val = UPT_R11(regs); break; \
+		case R12: val = UPT_R12(regs); break; \
+		case R13: val = UPT_R13(regs); break; \
+		case R14: val = UPT_R14(regs); break; \
+		case R15: val = UPT_R15(regs); break; \
+                case RIP: val = UPT_IP(regs); break; \
+                case RSP: val = UPT_SP(regs); break; \
+                case RAX: val = UPT_RAX(regs); break; \
+                case RBX: val = UPT_RBX(regs); break; \
+                case RCX: val = UPT_RCX(regs); break; \
+                case RDX: val = UPT_RDX(regs); break; \
+                case RSI: val = UPT_RSI(regs); break; \
+                case RDI: val = UPT_RDI(regs); break; \
+                case RBP: val = UPT_RBP(regs); break; \
+                case ORIG_RAX: val = UPT_ORIG_RAX(regs); break; \
+                case CS: val = UPT_CS(regs); break; \
+                case DS: val = UPT_DS(regs); break; \
+                case ES: val = UPT_ES(regs); break; \
+                case FS: val = UPT_FS(regs); break; \
+                case GS: val = UPT_GS(regs); break; \
+                case EFLAGS: val = UPT_EFLAGS(regs); break; \
+                default :  \
+                        panic("Bad register in UPT_REG : %d\n", reg);  \
+                        val = -1; \
+                } \
+                val; \
+        })
+
+
+#define UPT_SET(regs, reg, val) \
+        ({      unsigned long val; \
+                switch(reg){ \
+		case R8: UPT_R8(regs) = val; break; \
+		case R9: UPT_R9(regs) = val; break; \
+		case R10: UPT_R10(regs) = val; break; \
+		case R11: UPT_R11(regs) = val; break; \
+		case R12: UPT_R12(regs) = val; break; \
+		case R13: UPT_R13(regs) = val; break; \
+		case R14: UPT_R14(regs) = val; break; \
+		case R15: UPT_R15(regs) = val; break; \
+                case RIP: UPT_IP(regs) = val; break; \
+                case RSP: UPT_SP(regs) = val; break; \
+                case RAX: UPT_RAX(regs) = val; break; \
+                case RBX: UPT_RBX(regs) = val; break; \
+                case RCX: UPT_RCX(regs) = val; break; \
+                case RDX: UPT_RDX(regs) = val; break; \
+                case RSI: UPT_RSI(regs) = val; break; \
+                case RDI: UPT_RDI(regs) = val; break; \
+                case RBP: UPT_RBP(regs) = val; break; \
+                case ORIG_RAX: UPT_ORIG_RAX(regs) = val; break; \
+                case CS: UPT_CS(regs) = val; break; \
+                case DS: UPT_DS(regs) = val; break; \
+                case ES: UPT_ES(regs) = val; break; \
+                case FS: UPT_FS(regs) = val; break; \
+                case GS: UPT_GS(regs) = val; break; \
+                case EFLAGS: UPT_EFLAGS(regs) = val; break; \
+                default :  \
+                        panic("Bad register in UPT_SET : %d\n", reg);  \
+			break; \
+                } \
+                val; \
+        })
+
+#define UPT_SET_SYSCALL_RETURN(r, res) \
+	CHOOSE_MODE(SC_SET_SYSCALL_RETURN(UPT_SC(r), (res)), \
+                    REGS_SET_SYSCALL_RETURN((r)->skas.regs, (res)))
+
+#define UPT_RESTART_SYSCALL(r) \
+	CHOOSE_MODE(SC_RESTART_SYSCALL(UPT_SC(r)), \
+		    REGS_RESTART_SYSCALL((r)->skas.regs))
+
+#define UPT_SEGV_IS_FIXABLE(r) \
+	CHOOSE_MODE(SC_SEGV_IS_FIXABLE(UPT_SC(r)), \
+                    REGS_SEGV_IS_FIXABLE(&r->skas))
+
+#define UPT_FAULT_ADDR(r) \
+	CHOOSE_MODE(SC_FAULT_ADDR(UPT_SC(r)), REGS_FAULT_ADDR(&r->skas))
+
+#define UPT_FAULT_WRITE(r) \
+	CHOOSE_MODE(SC_FAULT_WRITE(UPT_SC(r)), REGS_FAULT_WRITE(&r->skas))
+
+#define UPT_TRAP(r) CHOOSE_MODE(SC_TRAP_TYPE(UPT_SC(r)), REGS_TRAP(&r->skas))
+#define UPT_ERR(r) CHOOSE_MODE(SC_FAULT_TYPE(UPT_SC(r)), REGS_ERR(&r->skas))
+
+#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 -Nru a/arch/um/include/sysdep-x86_64/ptrace_user.h b/arch/um/include/sysdep-x86_64/ptrace_user.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/um/include/sysdep-x86_64/ptrace_user.h	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2003 PathScale, Inc.
+ *
+ * Licensed under the GPL
+ */
+
+#ifndef __SYSDEP_X86_64_PTRACE_USER_H__
+#define __SYSDEP_X86_64_PTRACE_USER_H__
+
+#define __FRAME_OFFSETS
+#include <asm/ptrace.h>
+#undef __FRAME_OFFSETS
+
+#define PT_INDEX(off) ((off) / sizeof(unsigned long))
+
+#define PT_SYSCALL_NR(regs) ((regs)[PT_INDEX(ORIG_RAX)])
+#define PT_SYSCALL_NR_OFFSET (ORIG_RAX)
+
+#define PT_SYSCALL_ARG1(regs) (((unsigned long *) (regs))[PT_INDEX(RDI)])
+#define PT_SYSCALL_ARG1_OFFSET (RDI)
+
+#define PT_SYSCALL_ARG2(regs) (((unsigned long *) (regs))[PT_INDEX(RSI)])
+#define PT_SYSCALL_ARG2_OFFSET (RSI)
+
+#define PT_SYSCALL_ARG3(regs) (((unsigned long *) (regs))[PT_INDEX(RDX)])
+#define PT_SYSCALL_ARG3_OFFSET (RDX)
+
+#define PT_SYSCALL_ARG4(regs) (((unsigned long *) (regs))[PT_INDEX(RCX)])
+#define PT_SYSCALL_ARG4_OFFSET (RCX)
+
+#define PT_SYSCALL_ARG5(regs) (((unsigned long *) (regs))[PT_INDEX(R8)])
+#define PT_SYSCALL_ARG5_OFFSET (R8)
+
+#define PT_SYSCALL_ARG6(regs) (((unsigned long *) (regs))[PT_INDEX(R9)])
+#define PT_SYSCALL_ARG6_OFFSET (R9)
+
+#define PT_SYSCALL_RET_OFFSET (RAX)
+
+#define PT_IP_OFFSET (RIP)
+#define PT_IP(regs) ((regs)[PT_INDEX(RIP)])
+
+#define PT_SP_OFFSET (RSP)
+#define PT_SP(regs) ((regs)[PT_INDEX(RSP)])
+
+#define PT_ORIG_RAX_OFFSET (ORIG_RAX)
+#define PT_ORIG_RAX(regs) ((regs)[PT_INDEX(ORIG_RAX)])
+
+#define MAX_REG_OFFSET (FRAME_SIZE)
+#define MAX_REG_NR ((MAX_REG_OFFSET) / sizeof(unsigned long))
+
+/* x86_64 FC3 doesn't define this in /usr/include/linux/ptrace.h even though
+ * it's defined in the kernel's include/linux/ptrace.h. Additionally, use the
+ * 2.4 name and value for 2.4 host compatibility.
+ */
+#ifndef PTRACE_OLDSETOPTIONS
+#define PTRACE_OLDSETOPTIONS 21
+#endif
+
+#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 -Nru a/arch/um/include/sysdep-x86_64/sigcontext.h b/arch/um/include/sysdep-x86_64/sigcontext.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/um/include/sysdep-x86_64/sigcontext.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2003 PathScale, Inc.
+ *
+ * Licensed under the GPL
+ */
+
+#ifndef __SYSDEP_X86_64_SIGCONTEXT_H
+#define __SYSDEP_X86_64_SIGCONTEXT_H
+
+#include "sc.h"
+
+#define IP_RESTART_SYSCALL(ip) ((ip) -= 2)
+
+#define SC_RESTART_SYSCALL(sc) IP_RESTART_SYSCALL(SC_IP(sc))
+#define SC_SET_SYSCALL_RETURN(sc, result) SC_RAX(sc) = (result)
+
+#define SC_FAULT_ADDR(sc) SC_CR2(sc)
+#define SC_FAULT_TYPE(sc) SC_ERR(sc)
+
+#define FAULT_WRITE(err) ((err) & 2)
+
+#define SC_FAULT_WRITE(sc) FAULT_WRITE(SC_FAULT_TYPE(sc))
+
+#define SC_TRAP_TYPE(sc) SC_TRAPNO(sc)
+
+/* ptrace expects that, at the start of a system call, %eax contains
+ * -ENOSYS, so this makes it so.
+ */
+
+#define SC_START_SYSCALL(sc) do SC_RAX(sc) = -ENOSYS; while(0)
+
+#define SEGV_IS_FIXABLE(trap) ((trap) == 14)
+#define SC_SEGV_IS_FIXABLE(sc) SEGV_IS_FIXABLE(SC_TRAP_TYPE(sc))
+
+extern unsigned long *sc_sigmask(void *sc_ptr);
+
+#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 -Nru a/arch/um/include/sysdep-x86_64/signal.h b/arch/um/include/sysdep-x86_64/signal.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/um/include/sysdep-x86_64/signal.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2004 PathScale, Inc
+ * Licensed under the GPL
+ */
+
+#ifndef __X86_64_SIGNAL_H_
+#define __X86_64_SIGNAL_H_
+
+#define ARCH_GET_SIGCONTEXT(sc, sig_addr) \
+	do { \
+		struct ucontext *__uc; \
+		asm("movq %%rdx, %0" : "=r" (__uc)); \
+		sc = (struct sigcontext *) &__uc->uc_mcontext; \
+	} while(0)
+
+#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 -Nru a/arch/um/include/sysdep-x86_64/syscalls.h b/arch/um/include/sysdep-x86_64/syscalls.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/um/include/sysdep-x86_64/syscalls.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2003 PathScale, Inc.
+ *
+ * Licensed under the GPL
+ */
+
+#ifndef __SYSDEP_X86_64_SYSCALLS_H__
+#define __SYSDEP_X86_64_SYSCALLS_H__
+
+#include <linux/msg.h>
+#include <linux/shm.h>
+
+typedef long syscall_handler_t(void);
+
+extern syscall_handler_t *ia32_sys_call_table[];
+
+#define EXECUTE_SYSCALL(syscall, regs) \
+	(((long (*)(long, long, long, long, long, long)) \
+	  (*sys_call_table[syscall]))(UPT_SYSCALL_ARG1(&regs->regs), \
+		 		      UPT_SYSCALL_ARG2(&regs->regs), \
+				      UPT_SYSCALL_ARG3(&regs->regs), \
+				      UPT_SYSCALL_ARG4(&regs->regs), \
+				      UPT_SYSCALL_ARG5(&regs->regs), \
+				      UPT_SYSCALL_ARG6(&regs->regs)))
+
+extern long old_mmap(unsigned long addr, unsigned long len,
+		     unsigned long prot, unsigned long flags,
+		     unsigned long fd, unsigned long pgoff);
+extern syscall_handler_t wrap_sys_shmat;
+extern syscall_handler_t sys_modify_ldt;
+extern syscall_handler_t sys_arch_prctl;
+
+#define ARCH_SYSCALLS \
+	[ __NR_mmap ] = (syscall_handler_t *) old_mmap, \
+	[ __NR_select ] = (syscall_handler_t *) sys_select, \
+	[ __NR_mincore ] = (syscall_handler_t *) sys_mincore, \
+	[ __NR_madvise ] = (syscall_handler_t *) sys_madvise, \
+	[ __NR_shmget ] = (syscall_handler_t *) sys_shmget, \
+	[ __NR_shmat ] = (syscall_handler_t *) wrap_sys_shmat, \
+	[ __NR_shmctl ] = (syscall_handler_t *) sys_shmctl, \
+	[ __NR_semop ] = (syscall_handler_t *) sys_semop, \
+	[ __NR_semget ] = (syscall_handler_t *) sys_semget, \
+	[ __NR_semctl ] = (syscall_handler_t *) sys_semctl, \
+	[ __NR_shmdt ] = (syscall_handler_t *) sys_shmdt, \
+	[ __NR_msgget ] = (syscall_handler_t *) sys_msgget, \
+	[ __NR_msgsnd ] = (syscall_handler_t *) sys_msgsnd, \
+	[ __NR_msgrcv ] = (syscall_handler_t *) sys_msgrcv, \
+	[ __NR_msgctl ] = (syscall_handler_t *) sys_msgctl, \
+	[ __NR_pivot_root ] = (syscall_handler_t *) sys_pivot_root, \
+	[ __NR_tuxcall ] = (syscall_handler_t *) sys_ni_syscall, \
+	[ __NR_security ] = (syscall_handler_t *) sys_ni_syscall, \
+	[ __NR_epoll_ctl_old ] = (syscall_handler_t *) sys_ni_syscall, \
+	[ __NR_epoll_wait_old ] = (syscall_handler_t *) sys_ni_syscall, \
+	[ __NR_modify_ldt ] = (syscall_handler_t *) sys_modify_ldt, \
+	[ __NR_arch_prctl ] = (syscall_handler_t *) sys_arch_prctl, \
+	[ __NR_socket ] = (syscall_handler_t *) sys_socket, \
+	[ __NR_connect ] = (syscall_handler_t *) sys_connect, \
+	[ __NR_accept ] = (syscall_handler_t *) sys_accept, \
+	[ __NR_recvfrom ] = (syscall_handler_t *) sys_recvfrom, \
+	[ __NR_recvmsg ] = (syscall_handler_t *) sys_recvmsg, \
+	[ __NR_sendmsg ] = (syscall_handler_t *) sys_sendmsg, \
+	[ __NR_bind ] = (syscall_handler_t *) sys_bind, \
+	[ __NR_listen ] = (syscall_handler_t *) sys_listen, \
+	[ __NR_getsockname ] = (syscall_handler_t *) sys_getsockname, \
+	[ __NR_getpeername ] = (syscall_handler_t *) sys_getpeername, \
+	[ __NR_socketpair ] = (syscall_handler_t *) sys_socketpair, \
+	[ __NR_sendto ] = (syscall_handler_t *) sys_sendto, \
+	[ __NR_shutdown ] = (syscall_handler_t *) sys_shutdown, \
+	[ __NR_setsockopt ] = (syscall_handler_t *) sys_setsockopt, \
+	[ __NR_getsockopt ] = (syscall_handler_t *) sys_getsockopt, \
+	[ __NR_iopl ] = (syscall_handler_t *) sys_ni_syscall, \
+	[ __NR_set_thread_area ] = (syscall_handler_t *) sys_ni_syscall, \
+	[ __NR_get_thread_area ] = (syscall_handler_t *) sys_ni_syscall, \
+        [ __NR_remap_file_pages ] = (syscall_handler_t *) sys_remap_file_pages, \
+	[ __NR_semtimedop ] = (syscall_handler_t *) sys_semtimedop, \
+	[ __NR_fadvise64 ] = (syscall_handler_t *) sys_fadvise64, \
+	[ 223 ] = (syscall_handler_t *) sys_ni_syscall, \
+	[ __NR_utimes ] = (syscall_handler_t *) sys_utimes, \
+	[ __NR_vserver ] = (syscall_handler_t *) sys_ni_syscall, \
+	[ 251 ] = (syscall_handler_t *) sys_ni_syscall,
+
+#define LAST_ARCH_SYSCALL 251
+#define NR_syscalls 1024
+
+#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 -Nru a/arch/um/include/ubd_user.h b/arch/um/include/ubd_user.h
--- a/arch/um/include/ubd_user.h	2005-03-01 23:38:58 -08:00
+++ b/arch/um/include/ubd_user.h	2005-03-01 23:38:58 -08:00
@@ -7,63 +7,10 @@
 #ifndef __UM_UBD_USER_H
 #define __UM_UBD_USER_H
 
-#include "os.h"
-
-enum ubd_req { UBD_READ, UBD_WRITE, UBD_MMAP };
-
-struct io_thread_req {
-	enum ubd_req op;
-	int fds[2];
-	unsigned long offsets[2];
-	unsigned long long offset;
-	unsigned long length;
-	char *buffer;
-	int sectorsize;
-	unsigned long sector_mask;
-	unsigned long long cow_offset;
-	unsigned long bitmap_words[2];
-	int map_fd;
-	unsigned long long map_offset;
-	int error;
-};
-
-extern int open_ubd_file(char *file, struct openflags *openflags, 
-			 char **backing_file_out, int *bitmap_offset_out, 
-			 unsigned long *bitmap_len_out, int *data_offset_out,
-			 int *create_cow_out);
-extern int create_cow_file(char *cow_file, char *backing_file, 
-			   struct openflags flags, int sectorsize, 
-			   int alignment, int *bitmap_offset_out,
-			   unsigned long *bitmap_len_out,
-			   int *data_offset_out);
-extern int read_cow_bitmap(int fd, void *buf, int offset, int len);
-extern int read_ubd_fs(int fd, void *buffer, int len);
-extern int write_ubd_fs(int fd, char *buffer, int len);
+extern void ignore_sigwinch_sig(void);
 extern int start_io_thread(unsigned long sp, int *fds_out);
-extern void do_io(struct io_thread_req *req);
-
-static inline int ubd_test_bit(__u64 bit, unsigned char *data)
-{
-	__u64 n;
-	int bits, off;
-
-	bits = sizeof(data[0]) * 8;
-	n = bit / bits;
-	off = bit % bits;
-	return((data[n] & (1 << off)) != 0);
-}
-
-static inline void ubd_set_bit(__u64 bit, unsigned char *data)
-{
-	__u64 n;
-	int bits, off;
-
-	bits = sizeof(data[0]) * 8;
-	n = bit / bits;
-	off = bit % bits;
-	data[n] |= (1 << off);
-}
-
+extern int io_thread(void *arg);
+extern int kernel_fd;
 
 #endif
 
diff -Nru a/arch/um/include/um_uaccess.h b/arch/um/include/um_uaccess.h
--- a/arch/um/include/um_uaccess.h	2005-03-01 23:39:08 -08:00
+++ b/arch/um/include/um_uaccess.h	2005-03-01 23:39:08 -08:00
@@ -20,19 +20,19 @@
 #define access_ok(type, addr, size) \
 	CHOOSE_MODE_PROC(access_ok_tt, access_ok_skas, type, addr, size)
 
-static inline int verify_area(int type, const void * addr, unsigned long size)
+static inline int verify_area(int type, const void __user *addr, unsigned long size)
 {
-	return(CHOOSE_MODE_PROC(verify_area_tt, verify_area_skas, type, addr,
+	return (CHOOSE_MODE_PROC(verify_area_tt, verify_area_skas, type, addr,
 				size));
 }
 
-static inline int copy_from_user(void *to, const void *from, int n)
+static inline int copy_from_user(void *to, const void __user *from, int n)
 {
 	return(CHOOSE_MODE_PROC(copy_from_user_tt, copy_from_user_skas, to,
 				from, n));
 }
 
-static inline int copy_to_user(void *to, const void *from, int n)
+static inline int copy_to_user(void __user *to, const void *from, int n)
 {
 	return(CHOOSE_MODE_PROC(copy_to_user_tt, copy_to_user_skas, to, 
 				from, n));
@@ -57,7 +57,7 @@
  * and returns @count.
  */
 
-static inline int strncpy_from_user(char *dst, const char *src, int count)
+static inline int strncpy_from_user(char *dst, const char __user *src, int count)
 {
 	return(CHOOSE_MODE_PROC(strncpy_from_user_tt, strncpy_from_user_skas,
 				dst, src, count));
@@ -89,7 +89,7 @@
  * Returns number of bytes that could not be cleared.
  * On success, this will be zero.
  */
-static inline int clear_user(void *mem, int len)
+static inline int clear_user(void __user *mem, int len)
 {
 	return(CHOOSE_MODE_PROC(clear_user_tt, clear_user_skas, mem, len));
 }
@@ -105,7 +105,7 @@
  * On exception, returns 0.
  * If the string is too long, returns a value greater than @n.
  */
-static inline int strnlen_user(const void *str, int len)
+static inline int strnlen_user(const void __user *str, long len)
 {
 	return(CHOOSE_MODE_PROC(strnlen_user_tt, strnlen_user_skas, str, len));
 }
diff -Nru a/arch/um/include/uml_uaccess.h b/arch/um/include/uml_uaccess.h
--- a/arch/um/include/uml_uaccess.h	2005-03-01 23:38:52 -08:00
+++ b/arch/um/include/uml_uaccess.h	2005-03-01 23:38:52 -08:00
@@ -7,7 +7,7 @@
 #define __UML_UACCESS_H__
 
 extern int __do_copy_to_user(void *to, const void *from, int n,
-				  void **fault_addr, void **fault_catcher);
+			     void **fault_addr, void **fault_catcher);
 extern unsigned long __do_user_copy(void *to, const void *from, int n,
 				    void **fault_addr, void **fault_catcher,
 				    void (*op)(void *to, const void *from,
diff -Nru a/arch/um/include/umn.h b/arch/um/include/umn.h
--- a/arch/um/include/umn.h	2005-03-01 23:38:55 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,27 +0,0 @@
-/* 
- * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#ifndef __UMN_H
-#define __UMN_H
-
-extern int open_umn_tty(int *slave_out, int *slipno_out);
-extern void close_umn_tty(int master, int slave);
-extern int umn_send_packet(int fd, void *data, int len);
-extern int set_umn_addr(int fd, char *addr, char *ptp_addr);
-extern void slip_unesc(unsigned char s);
-extern void umn_read(int fd);
-
-#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 -Nru a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile
--- a/arch/um/kernel/Makefile	2005-03-01 23:39:07 -08:00
+++ b/arch/um/kernel/Makefile	2005-03-01 23:39:07 -08:00
@@ -6,7 +6,7 @@
 extra-y := vmlinux.lds
 clean-files := vmlinux.lds.S
 
-obj-y = checksum.o config.o exec_kern.o exitcode.o frame_kern.o frame.o \
+obj-y = checksum.o config.o exec_kern.o exitcode.o \
 	helper.o init_task.o irq.o irq_user.o ksyms.o main.o mem.o mem_user.o \
 	physmem.o process.o process_kern.o ptrace.o reboot.o resource.o \
 	sigio_user.o sigio_kern.o signal_kern.o signal_user.o smp.o \
diff -Nru a/arch/um/kernel/checksum.c b/arch/um/kernel/checksum.c
--- a/arch/um/kernel/checksum.c	2005-03-01 23:39:07 -08:00
+++ b/arch/um/kernel/checksum.c	2005-03-01 23:39:07 -08:00
@@ -2,17 +2,17 @@
 #include "linux/errno.h"
 #include "linux/module.h"
 
-extern unsigned int arch_csum_partial(const char *buff, int len, int sum);
+unsigned int arch_csum_partial(const unsigned char *buff, int len, int sum);
 
-extern unsigned int csum_partial(char *buff, int len, int sum)
+unsigned int csum_partial(unsigned char *buff, int len, int sum)
 {
-	return(arch_csum_partial(buff, len, sum));
+	return arch_csum_partial(buff, len, sum);
 }
 
 EXPORT_SYMBOL(csum_partial);
 
-unsigned int csum_partial_copy_to(const char *src, char *dst, int len, 
-				  int sum, int *err_ptr)
+unsigned int csum_partial_copy_to(const unsigned char *src, char __user *dst,
+				int len, int sum, int *err_ptr)
 {
 	if(copy_to_user(dst, src, len)){
 		*err_ptr = -EFAULT;
@@ -22,15 +22,15 @@
 	return(arch_csum_partial(src, len, sum));
 }
 
-unsigned int csum_partial_copy_from(const char *src, char *dst, int len, 
-				    int sum, int *err_ptr)
+unsigned int csum_partial_copy_from(const unsigned char __user *src, char *dst,
+				int len, int sum, int *err_ptr)
 {
 	if(copy_from_user(dst, src, len)){
 		*err_ptr = -EFAULT;
 		return(-1);
 	}
 
-	return(arch_csum_partial(dst, len, sum));
+	return arch_csum_partial(dst, len, sum);
 }
 
 /*
diff -Nru a/arch/um/kernel/dyn.lds.S b/arch/um/kernel/dyn.lds.S
--- a/arch/um/kernel/dyn.lds.S	2005-03-01 23:38:57 -08:00
+++ b/arch/um/kernel/dyn.lds.S	2005-03-01 23:38:57 -08:00
@@ -7,8 +7,11 @@
 
 SECTIONS
 {
+  PROVIDE (__executable_start = START);
   . = START + SIZEOF_HEADERS;
   .interp         : { *(.interp) }
+  /* Used in arch/um/kernel/mem.c. Any memory between START and __binary_start
+   * is remapped.*/
   __binary_start = .;
   . = ALIGN(4096);		/* Init code and data */
   _stext = .;
diff -Nru a/arch/um/kernel/exec_kern.c b/arch/um/kernel/exec_kern.c
--- a/arch/um/kernel/exec_kern.c	2005-03-01 23:38:54 -08:00
+++ b/arch/um/kernel/exec_kern.c	2005-03-01 23:38:54 -08:00
@@ -34,7 +34,8 @@
 
 extern void log_exec(char **argv, void *tty);
 
-static long execve1(char *file, char **argv, char **env)
+static long execve1(char *file, char __user * __user *argv,
+		    char *__user __user *env)
 {
         long error;
 
@@ -51,7 +52,7 @@
         return(error);
 }
 
-long um_execve(char *file, char **argv, char **env)
+long um_execve(char *file, char __user *__user *argv, char __user *__user *env)
 {
 	long err;
 
@@ -61,13 +62,14 @@
 	return(err);
 }
 
-long sys_execve(char *file, char **argv, char **env)
+long sys_execve(char *file, char __user *__user *argv,
+		char __user *__user *env)
 {
 	long error;
 	char *filename;
 
 	lock_kernel();
-	filename = getname((char *) file);
+	filename = getname((char __user *) file);
 	error = PTR_ERR(filename);
 	if (IS_ERR(filename)) goto out;
 	error = execve1(filename, argv, env);
diff -Nru a/arch/um/kernel/exitcode.c b/arch/um/kernel/exitcode.c
--- a/arch/um/kernel/exitcode.c	2005-03-01 23:38:54 -08:00
+++ b/arch/um/kernel/exitcode.c	2005-03-01 23:38:54 -08:00
@@ -27,7 +27,7 @@
 	return(len);
 }
 
-static int write_proc_exitcode(struct file *file, const char *buffer,
+static int write_proc_exitcode(struct file *file, const char __user *buffer,
 			       unsigned long count, void *data)
 {
 	char *end, buf[sizeof("nnnnn\0")];
diff -Nru a/arch/um/kernel/frame.c b/arch/um/kernel/frame.c
--- a/arch/um/kernel/frame.c	2005-03-01 23:38:55 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,343 +0,0 @@
-/* 
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <signal.h>
-#include <wait.h>
-#include <sched.h>
-#include <errno.h>
-#include <sys/ptrace.h>
-#include <sys/syscall.h>
-#include <sys/mman.h>
-#include <asm/page.h>
-#include <asm/ptrace.h>
-#include <asm/sigcontext.h>
-#include "sysdep/ptrace.h"
-#include "sysdep/sigcontext.h"
-#include "frame_user.h"
-#include "kern_util.h"
-#include "user_util.h"
-#include "ptrace_user.h"
-#include "os.h"
-
-static int capture_stack(int (*child)(void *arg), void *arg, void *sp,
-			 unsigned long top, void **data_out)
-{
-	unsigned long regs[FRAME_SIZE];
-	int pid, status, n, len;
-
-	/* Start the child as a thread */
-	pid = clone(child, sp, CLONE_VM | SIGCHLD, arg);
-	if(pid < 0){
-		printf("capture_stack : clone failed - errno = %d\n", errno);
-		exit(1);
-	}
-
-	/* Wait for it to stop itself and continue it with a SIGUSR1 to force 
-	 * it into the signal handler.
-	 */
-	CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
-	if(n < 0){
-		printf("capture_stack : waitpid failed - errno = %d\n", errno);
-		exit(1);
-	}
-	if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)){
-		fprintf(stderr, "capture_stack : Expected SIGSTOP, "
-			"got status = 0x%x\n", status);
-		exit(1);
-	}
-	if(ptrace(PTRACE_CONT, pid, 0, SIGUSR1) < 0){
-		printf("capture_stack : PTRACE_CONT failed - errno = %d\n", 
-		       errno);
-		exit(1);
-	}
-
-	/* Wait for it to stop itself again and grab its registers again.  
-	 * At this point, the handler has stuffed the addresses of
-	 * sig, sc, and SA_RESTORER in raw.
-	 */
-	CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
-	if(n < 0){
-		printf("capture_stack : waitpid failed - errno = %d\n", errno);
-		exit(1);
-	}
-	if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)){
-		fprintf(stderr, "capture_stack : Expected SIGSTOP, "
-			"got status = 0x%x\n", status);
-		exit(1);
-	}
-	if(ptrace(PTRACE_GETREGS, pid, 0, regs) < 0){
-		printf("capture_stack : PTRACE_GETREGS failed - errno = %d\n", 
-		       errno);
-		exit(1);
-	}
-
-	/* It has outlived its usefulness, so continue it so it can exit */
-	if(ptrace(PTRACE_CONT, pid, 0, 0) < 0){
-		printf("capture_stack : PTRACE_CONT failed - errno = %d\n", 
-		       errno);
-		exit(1);
-	}
-	CATCH_EINTR(n = waitpid(pid, &status, 0));
-	if(n < 0){
-		printf("capture_stack : waitpid failed - errno = %d\n", errno);
-		exit(1);
-	}
-	if(!WIFSIGNALED(status) || (WTERMSIG(status) != 9)){
-		printf("capture_stack : Expected exit signal 9, "
-		       "got status = 0x%x\n", status);
-		exit(1);
-	}
-
-	/* The frame that we want is the top of the signal stack */
-
-	len = top - PT_SP(regs);
-	*data_out = malloc(len);
-	if(*data_out == NULL){
-		printf("capture_stack : malloc failed - errno = %d\n", errno);
-		exit(1);
-	}
-	memcpy(*data_out, (void *) PT_SP(regs), len);
-
-	return(len);
-}
-
-struct common_raw {
-	void *stack;
-	int size;
-	unsigned long sig;
-	unsigned long sr;
-	unsigned long sp;	
-	struct arch_frame_data_raw arch;
-};
-
-#define SA_RESTORER (0x04000000)
-
-typedef unsigned long old_sigset_t;
-
-struct old_sigaction {
-	__sighandler_t handler;
-	old_sigset_t sa_mask;
-	unsigned long sa_flags;
-	void (*sa_restorer)(void);
-};
-
-static void child_common(struct common_raw *common, sighandler_t handler,
-			 int restorer, int flags)
-{
-	stack_t ss = ((stack_t) { .ss_sp	= common->stack,
-				  .ss_flags	= 0,
-				  .ss_size	= common->size });
-	int err;
-
-	if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0){
-		printf("PTRACE_TRACEME failed, errno = %d\n", errno);
-	}
-	if(sigaltstack(&ss, NULL) < 0){
-		printf("sigaltstack failed - errno = %d\n", errno);
-		kill(os_getpid(), SIGKILL);
-	}
-
-	if(restorer){
-		struct sigaction sa;
-
-		sa.sa_handler = handler;
-		sigemptyset(&sa.sa_mask);
-		sa.sa_flags = SA_ONSTACK | flags;
-		err = sigaction(SIGUSR1, &sa, NULL);
-	}
-	else {
-		struct old_sigaction sa;
-
-		sa.handler = handler;
-		sa.sa_mask = 0;
-		sa.sa_flags = (SA_ONSTACK | flags) & ~SA_RESTORER;
-		err = syscall(__NR_sigaction, SIGUSR1, &sa, NULL);
-	}
-	
-	if(err < 0){
-		printf("sigaction failed - errno = %d\n", errno);
-		kill(os_getpid(), SIGKILL);
-	}
-
-	os_stop_process(os_getpid());
-}
-
-/* Changed only during early boot */
-struct sc_frame signal_frame_sc;
-
-struct sc_frame signal_frame_sc_sr;
-
-struct sc_frame_raw {
-	struct common_raw common;
-	unsigned long sc;
-	int restorer;
-};
-
-/* Changed only during early boot */
-static struct sc_frame_raw *raw_sc = NULL;
-
-static void sc_handler(int sig, struct sigcontext sc)
-{
-	raw_sc->common.sig = (unsigned long) &sig;
-	raw_sc->common.sr = frame_restorer();
-	raw_sc->common.sp = frame_sp();
-	raw_sc->sc = (unsigned long) &sc;
-	setup_arch_frame_raw(&raw_sc->common.arch, &sc + 1, raw_sc->common.sr);
-
-	os_stop_process(os_getpid());
-	kill(os_getpid(), SIGKILL);
-}
-
-static int sc_child(void *arg)
-{
-	raw_sc = arg;
-	child_common(&raw_sc->common, (sighandler_t) sc_handler, 
-		     raw_sc->restorer, 0);
-	return(-1);
-}
-
-/* Changed only during early boot */
-struct si_frame signal_frame_si;
-
-struct si_frame_raw {
-	struct common_raw common;
-	unsigned long sip;
-	unsigned long si;
-	unsigned long ucp;
-	unsigned long uc;
-};
-
-/* Changed only during early boot */
-static struct si_frame_raw *raw_si = NULL;
-
-static void si_handler(int sig, siginfo_t *si, struct ucontext *ucontext)
-{
-	raw_si->common.sig = (unsigned long) &sig;
-	raw_si->common.sr = frame_restorer();
-	raw_si->common.sp = frame_sp();
-	raw_si->sip = (unsigned long) &si;
-	raw_si->si = (unsigned long) si;
-	raw_si->ucp = (unsigned long) &ucontext;
-	raw_si->uc = (unsigned long) ucontext;
-	setup_arch_frame_raw(&raw_si->common.arch, 
-			     ucontext->uc_mcontext.fpregs, raw_si->common.sr);
-	
-	os_stop_process(os_getpid());
-	kill(os_getpid(), SIGKILL);
-}
-
-static int si_child(void *arg)
-{
-	raw_si = arg;
-	child_common(&raw_si->common, (sighandler_t) si_handler, 1, 
- 		     SA_SIGINFO);
-	return(-1);
-}
-
-static int relative_sr(unsigned long sr, int sr_index, void *stack, 
-		       void *framep)
-{
-	unsigned long *srp = (unsigned long *) sr;
-	unsigned long frame = (unsigned long) framep;
-
-	if((*srp & PAGE_MASK) == (unsigned long) stack){
-		*srp -= sr;
-		*((unsigned long *) (frame + sr_index)) = *srp;
-		return(1);
-	}
-	else return(0);
-}
-
-static unsigned long capture_stack_common(int (*proc)(void *), void *arg, 
-					  struct common_raw *common_in, 
-					  void *top, void *sigstack, 
-					  int stack_len, 
-					  struct frame_common *common_out)
-{
-	unsigned long sig_top = (unsigned long) sigstack + stack_len, base;
-
-	common_in->stack = (void *) sigstack;
-	common_in->size = stack_len;
-	common_out->len = capture_stack(proc, arg, top, sig_top, 
-					&common_out->data);
-	base = sig_top - common_out->len;
-	common_out->sig_index = common_in->sig - base;
-	common_out->sp_index = common_in->sp - base;
-	common_out->sr_index = common_in->sr - base;
-	common_out->sr_relative = relative_sr(common_in->sr, 
-					      common_out->sr_index, sigstack, 
-					      common_out->data);
-	return(base);
-}
-
-void capture_signal_stack(void)
-{
-	struct sc_frame_raw raw_sc;
-	struct si_frame_raw raw_si;
-	void *stack, *sigstack;
-	unsigned long top, base;
-
-	stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
-		     MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
-	sigstack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
-			MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
-	if((stack == MAP_FAILED) || (sigstack == MAP_FAILED)){
-		printf("capture_signal_stack : mmap failed - errno = %d\n", 
-		       errno);
-		exit(1);
-	}
-
-	top = (unsigned long) stack + PAGE_SIZE - sizeof(void *);
-
-	/* Get the sigcontext, no sigrestorer layout */
-	raw_sc.restorer = 0;
-	base = capture_stack_common(sc_child, &raw_sc, &raw_sc.common, 
-				    (void *) top, sigstack, PAGE_SIZE, 
-				    &signal_frame_sc.common);
-
-	signal_frame_sc.sc_index = raw_sc.sc - base;
-	setup_arch_frame(&raw_sc.common.arch, &signal_frame_sc.common.arch);
-
-	/* Ditto for the sigcontext, sigrestorer layout */
-	raw_sc.restorer = 1;
-	base = capture_stack_common(sc_child, &raw_sc, &raw_sc.common, 
-				    (void *) top, sigstack, PAGE_SIZE, 
-				    &signal_frame_sc_sr.common);
-	signal_frame_sc_sr.sc_index = raw_sc.sc - base;
-	setup_arch_frame(&raw_sc.common.arch, &signal_frame_sc_sr.common.arch);
-
-	/* And the siginfo layout */
-
-	base = capture_stack_common(si_child, &raw_si, &raw_si.common, 
-				    (void *) top, sigstack, PAGE_SIZE, 
-				    &signal_frame_si.common);
-	signal_frame_si.sip_index = raw_si.sip - base;
-	signal_frame_si.si_index = raw_si.si - base;
-	signal_frame_si.ucp_index = raw_si.ucp - base;
-	signal_frame_si.uc_index = raw_si.uc - base;
-	setup_arch_frame(&raw_si.common.arch, &signal_frame_si.common.arch);
-
-	if((munmap(stack, PAGE_SIZE) < 0) || 
-	   (munmap(sigstack, PAGE_SIZE) < 0)){
-		printf("capture_signal_stack : munmap failed - errno = %d\n", 
-		       errno);
-		exit(1);
-	}
-}
-
-/*
- * 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 -Nru a/arch/um/kernel/frame_kern.c b/arch/um/kernel/frame_kern.c
--- a/arch/um/kernel/frame_kern.c	2005-03-01 23:39:18 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,148 +0,0 @@
-/* 
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#include "asm/ptrace.h"
-#include "asm/uaccess.h"
-#include "asm/signal.h"
-#include "asm/ucontext.h"
-#include "frame_kern.h"
-#include "sigcontext.h"
-#include "sysdep/ptrace.h"
-#include "choose-mode.h"
-#include "mode.h"
-
-static int copy_restorer(void (*restorer)(void), unsigned long start, 
-			 unsigned long sr_index, int sr_relative)
-{
-	unsigned long sr;
-
-	if(sr_relative){
-		sr = (unsigned long) restorer;
-		sr += start + sr_index;
-		restorer = (void (*)(void)) sr;
-	}
-
-	return(copy_to_user((void *) (start + sr_index), &restorer, 
-			    sizeof(restorer)));
-}
-
-extern int userspace_pid[];
-
-static int copy_sc_to_user(void *to, void *fp, struct pt_regs *from, 
-			   struct arch_frame_data *arch)
-{
-	return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs), 
-					      arch),
-			   copy_sc_to_user_skas(userspace_pid[0], to, fp,
-						&from->regs,
-						current->thread.cr2,
-						current->thread.err)));
-}
-
-static int copy_ucontext_to_user(struct ucontext *uc, void *fp, sigset_t *set,
-				 unsigned long sp)
-{
-	int err = 0;
-
-	err |= put_user(current->sas_ss_sp, &uc->uc_stack.ss_sp);
-	err |= put_user(sas_ss_flags(sp), &uc->uc_stack.ss_flags);
-	err |= put_user(current->sas_ss_size, &uc->uc_stack.ss_size);
-	err |= copy_sc_to_user(&uc->uc_mcontext, fp, &current->thread.regs,
-			       &signal_frame_si.common.arch);
-	err |= copy_to_user(&uc->uc_sigmask, set, sizeof(*set));
-	return(err);
-}
-
-int setup_signal_stack_si(unsigned long stack_top, int sig, 
-			  struct k_sigaction *ka, struct pt_regs *regs,
-			  siginfo_t *info, sigset_t *mask)
-{
-	unsigned long start;
-	void *restorer;
-	void *sip, *ucp, *fp;
-
-	start = stack_top - signal_frame_si.common.len;
-	sip = (void *) (start + signal_frame_si.si_index);
-	ucp = (void *) (start + signal_frame_si.uc_index);
-	fp = (void *) (((unsigned long) ucp) + sizeof(struct ucontext));
-
-	restorer = NULL;
-	if(ka->sa.sa_flags & SA_RESTORER)
-		restorer = ka->sa.sa_restorer;
-
-	if(restorer == NULL)
-		panic("setup_signal_stack_si - no restorer");
-
-	if(copy_to_user((void *) start, signal_frame_si.common.data,
-			signal_frame_si.common.len) ||
-	   copy_to_user((void *) (start + signal_frame_si.common.sig_index), 
-			&sig, sizeof(sig)) ||
-	   copy_siginfo_to_user(sip, info) ||
-	   copy_to_user((void *) (start + signal_frame_si.sip_index), &sip,
-			sizeof(sip)) ||
-	   copy_ucontext_to_user(ucp, fp, mask, PT_REGS_SP(regs)) ||
-	   copy_to_user((void *) (start + signal_frame_si.ucp_index), &ucp,
-			sizeof(ucp)) ||
-	   copy_restorer(restorer, start, signal_frame_si.common.sr_index,
-			 signal_frame_si.common.sr_relative))
-		return(1);
-	
-	PT_REGS_IP(regs) = (unsigned long) ka->sa.sa_handler;
-	PT_REGS_SP(regs) = start + signal_frame_si.common.sp_index;
-	return(0);
-}
-
-int setup_signal_stack_sc(unsigned long stack_top, int sig, 
-			  struct k_sigaction *ka, struct pt_regs *regs,
-			  sigset_t *mask)
-{
-	struct frame_common *frame = &signal_frame_sc_sr.common;
-	void *restorer;
-	void *user_sc;
-	int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long);
-	unsigned long sigs, sr;
-	unsigned long start = stack_top - frame->len - sig_size;
-
-	restorer = NULL;
-	if(ka->sa.sa_flags & SA_RESTORER)
-		restorer = ka->sa.sa_restorer;
-
-	user_sc = (void *) (start + signal_frame_sc_sr.sc_index);
-	if(restorer == NULL){
-		frame = &signal_frame_sc.common;
-		user_sc = (void *) (start + signal_frame_sc.sc_index);
-		sr = (unsigned long) frame->data;
-		sr += frame->sr_index;
-		sr = *((unsigned long *) sr);
-		restorer = ((void (*)(void)) sr);
-	}
-
-	sigs = start + frame->len;
-	if(copy_to_user((void *) start, frame->data, frame->len) ||
-	   copy_to_user((void *) (start + frame->sig_index), &sig, 
-			sizeof(sig)) ||
-	   copy_sc_to_user(user_sc, NULL, regs, 
-			   &signal_frame_sc.common.arch) ||
-	   copy_to_user(sc_sigmask(user_sc), mask, sizeof(mask->sig[0])) ||
-	   copy_to_user((void *) sigs, &mask->sig[1], sig_size) ||
-	   copy_restorer(restorer, start, frame->sr_index, frame->sr_relative))
-		return(1);
-
-	PT_REGS_IP(regs) = (unsigned long) ka->sa.sa_handler;
-	PT_REGS_SP(regs) = start + frame->sp_index;
-
-	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 -Nru a/arch/um/kernel/helper.c b/arch/um/kernel/helper.c
--- a/arch/um/kernel/helper.c	2005-03-01 23:38:57 -08:00
+++ b/arch/um/kernel/helper.c	2005-03-01 23:38:57 -08:00
@@ -49,14 +49,14 @@
 	return(0);
 }
 
-/* XXX The alloc_stack here breaks if this is called in the tracing thread */
-
+/* Returns either the pid of the child process we run or -E* on failure.
+ * XXX The alloc_stack here breaks if this is called in the tracing thread */
 int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
 	       unsigned long *stack_out)
 {
 	struct helper_data data;
 	unsigned long stack, sp;
-	int pid, fds[2], err, n;
+	int pid, fds[2], ret, n;
 
 	if((stack_out != NULL) && (*stack_out != 0))
 		stack = *stack_out;
@@ -64,16 +64,16 @@
 	if(stack == 0)
 		return(-ENOMEM);
 
-	err = os_pipe(fds, 1, 0);
-	if(err < 0){
-		printk("run_helper : pipe failed, err = %d\n", -err);
+	ret = os_pipe(fds, 1, 0);
+	if(ret < 0){
+		printk("run_helper : pipe failed, ret = %d\n", -ret);
 		goto out_free;
 	}
 
-	err = os_set_exec_close(fds[1], 1);
-	if(err < 0){
-		printk("run_helper : setting FD_CLOEXEC failed, err = %d\n",
-		       -err);
+	ret = os_set_exec_close(fds[1], 1);
+	if(ret < 0){
+		printk("run_helper : setting FD_CLOEXEC failed, ret = %d\n",
+		       -ret);
 		goto out_close;
 	}
 
@@ -85,34 +85,36 @@
 	pid = clone(helper_child, (void *) sp, CLONE_VM | SIGCHLD, &data);
 	if(pid < 0){
 		printk("run_helper : clone failed, errno = %d\n", errno);
-		err = -errno;
+		ret = -errno;
 		goto out_close;
 	}
 
 	os_close_file(fds[1]);
-	n = os_read_file(fds[0], &err, sizeof(err));
+	fds[1] = -1;
+
+	/*Read the errno value from the child.*/
+	n = os_read_file(fds[0], &ret, sizeof(ret));
 	if(n < 0){
-		printk("run_helper : read on pipe failed, err = %d\n", -n);
-		err = n;
-		goto out_kill;
+		printk("run_helper : read on pipe failed, ret = %d\n", -n);
+		ret = n;
+		os_kill_process(pid, 1);
 	}
 	else if(n != 0){
 		CATCH_EINTR(n = waitpid(pid, NULL, 0));
-		pid = -errno;
+		ret = -errno;
+	} else {
+		ret = pid;
 	}
 
-	if(stack_out == NULL) free_stack(stack, 0);
-        else *stack_out = stack;
-	return(pid);
-
- out_kill:
-	os_kill_process(pid, 1);
- out_close:
+out_close:
+	if (fds[1] != -1)
+		os_close_file(fds[1]);
 	os_close_file(fds[0]);
-	os_close_file(fds[1]);
- out_free:
-	free_stack(stack, 0);
-	return(err);
+out_free:
+	if(stack_out == NULL)
+		free_stack(stack, 0);
+	else *stack_out = stack;
+	return(ret);
 }
 
 int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags, 
@@ -143,7 +145,7 @@
 			       "0x%x\n", status);
 		free_stack(stack, stack_order);
 	}
-        else *stack_out = stack;
+	else *stack_out = stack;
 	return(pid);
 }
 
diff -Nru a/arch/um/kernel/initrd_user.c b/arch/um/kernel/initrd_user.c
--- a/arch/um/kernel/initrd_user.c	2005-03-01 23:38:53 -08:00
+++ b/arch/um/kernel/initrd_user.c	2005-03-01 23:38:53 -08:00
@@ -29,6 +29,8 @@
 		       filename, -n);
 		return(-1);
 	}
+
+	os_close_file(fd);
 	return(0);
 }
 
diff -Nru a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c
--- a/arch/um/kernel/irq.c	2005-03-01 23:39:09 -08:00
+++ b/arch/um/kernel/irq.c	2005-03-01 23:39:09 -08:00
@@ -45,9 +45,8 @@
 
 	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_online_cpu(j)
+			seq_printf(p, "CPU%d       ",j);
 		seq_putc(p, '\n');
 	}
 
@@ -60,9 +59,8 @@
 #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_online_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);
@@ -111,7 +109,7 @@
 EXPORT_SYMBOL(um_request_irq);
 EXPORT_SYMBOL(reactivate_fd);
 
-static spinlock_t irq_spinlock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(irq_spinlock);
 
 unsigned long irq_lock(void)
 {
@@ -154,13 +152,13 @@
 	int i;
 
 	irq_desc[TIMER_IRQ].status = IRQ_DISABLED;
-	irq_desc[TIMER_IRQ].action = 0;
+	irq_desc[TIMER_IRQ].action = NULL;
 	irq_desc[TIMER_IRQ].depth = 1;
 	irq_desc[TIMER_IRQ].handler = &SIGVTALRM_irq_type;
 	enable_irq(TIMER_IRQ);
 	for(i=1;i<NR_IRQS;i++){
 		irq_desc[i].status = IRQ_DISABLED;
-		irq_desc[i].action = 0;
+		irq_desc[i].action = NULL;
 		irq_desc[i].depth = 1;
 		irq_desc[i].handler = &SIGIO_irq_type;
 		enable_irq(i);
diff -Nru a/arch/um/kernel/irq_user.c b/arch/um/kernel/irq_user.c
--- a/arch/um/kernel/irq_user.c	2005-03-01 23:38:56 -08:00
+++ b/arch/um/kernel/irq_user.c	2005-03-01 23:38:56 -08:00
@@ -83,8 +83,11 @@
 				 * can be freed here.
 				 */
 				next = irq_fd->next;
-				if(irq_fd->freed)
+				if(irq_fd->freed){
 					free_irq(irq_fd->irq, irq_fd->id);
+					free_irq_by_irq_and_dev(irq_fd->irq,
+								irq_fd->id);
+				}
 			}
 		}
 	}
@@ -374,6 +377,8 @@
 		if(err)
 			return(err);
 	}
+	/* If there is a signal already queued, after unblocking ignore it */
+	set_handler(SIGIO, SIG_IGN, 0, -1);
 
 	return(0);
 }
diff -Nru a/arch/um/kernel/ksyms.c b/arch/um/kernel/ksyms.c
--- a/arch/um/kernel/ksyms.c	2005-03-01 23:38:51 -08:00
+++ b/arch/um/kernel/ksyms.c	2005-03-01 23:38:51 -08:00
@@ -48,6 +48,7 @@
 EXPORT_SYMBOL(mode_tt);
 EXPORT_SYMBOL(handle_page_fault);
 EXPORT_SYMBOL(find_iomem);
+EXPORT_SYMBOL(end_iomem);
 
 #ifdef CONFIG_MODE_TT
 EXPORT_SYMBOL(strncpy_from_user_tt);
diff -Nru a/arch/um/kernel/main.c b/arch/um/kernel/main.c
--- a/arch/um/kernel/main.c	2005-03-01 23:39:09 -08:00
+++ b/arch/um/kernel/main.c	2005-03-01 23:39:09 -08:00
@@ -81,6 +81,8 @@
 
 extern int uml_exitcode;
 
+extern void scan_elf_aux( char **envp);
+
 int main(int argc, char **argv, char **envp)
 {
 	char **new_argv;
@@ -147,26 +149,38 @@
 	set_handler(SIGTERM, last_ditch_exit, SA_ONESHOT | SA_NODEFER, -1);
 	set_handler(SIGHUP, last_ditch_exit, SA_ONESHOT | SA_NODEFER, -1);
 
+	scan_elf_aux( envp);
+
 	do_uml_initcalls();
 	ret = linux_main(argc, argv);
 
+	/* Disable SIGPROF - I have no idea why libc doesn't do this or turn
+	 * off the profiling time, but UML dies with a SIGPROF just before
+	 * exiting when profiling is active.
+	 */
+	change_sig(SIGPROF, 0);
+
 	/* Reboot */
 	if(ret){
 		int err;
 
 		printf("\n");
 
-		/* Let any pending signals fire, then disable them.  This
-		 * ensures that they won't be delivered after the exec, when
-		 * they are definitely not expected.
-		 */
-		unblock_signals();
+		/* stop timers and set SIG*ALRM to be ignored */
 		disable_timer();
+
+		/* disable SIGIO for the fds and set SIGIO to be ignored */
 		err = deactivate_all_fds();
 		if(err)
 			printf("deactivate_all_fds failed, errno = %d\n",
 			       -err);
 
+		/* Let any pending signals fire now.  This ensures
+		 * that they won't be delivered after the exec, when
+		 * they are definitely not expected.
+		 */
+		unblock_signals();
+
 		execvp(new_argv[0], new_argv);
 		perror("Failed to exec kernel");
 		ret = 1;
@@ -222,13 +236,16 @@
 	 * 	physical memory - kmalloc/kfree
 	 *	kernel virtual memory - vmalloc/vfree
 	 * 	anywhere else - malloc/free
-	 * If kmalloc is not yet possible, then the kernel memory regions
-	 * may not be set up yet, and the variables not initialized.  So,
-	 * free is called.
+	 * If kmalloc is not yet possible, then either high_physmem and/or
+	 * end_vm are still 0 (as at startup), in which case we call free, or
+	 * we have set them, but anyway addr has not been allocated from those
+	 * areas. So, in both cases __real_free is called.
 	 *
 	 * CAN_KMALLOC is checked because it would be bad to free a buffer
 	 * with kmalloc/vmalloc after they have been turned off during
 	 * shutdown.
+	 * XXX: However, we sometimes shutdown CAN_KMALLOC temporarily, so
+	 * there is a possibility for memory leaks.
 	 */
 
 	if((addr >= uml_physmem) && (addr < high_physmem)){
diff -Nru a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c
--- a/arch/um/kernel/mem.c	2005-03-01 23:38:56 -08:00
+++ b/arch/um/kernel/mem.c	2005-03-01 23:38:56 -08:00
@@ -25,7 +25,7 @@
 /* Changed during early boot */
 unsigned long *empty_zero_page = NULL;
 unsigned long *empty_bad_page = NULL;
-pgd_t swapper_pg_dir[1024];
+pgd_t swapper_pg_dir[PTRS_PER_PGD];
 unsigned long highmem;
 int kmalloc_ok = 0;
 
@@ -49,8 +49,6 @@
 	unsigned long highmem_pfn;
 	int i;
 
-	highmem_start_page = virt_to_page(highmem_start);
-
 	highmem_pfn = __pa(highmem_start) >> PAGE_SHIFT;
 	for(i = 0; i < highmem_len >> PAGE_SHIFT; i++){
 		page = &mem_map[highmem_pfn + i];
@@ -67,9 +65,6 @@
 	unsigned long start;
 
 	max_low_pfn = (high_physmem - uml_physmem) >> PAGE_SHIFT;
-#ifdef CONFIG_HIGHMEM
-	highmem_start_page = phys_page(__pa(high_physmem));
-#endif
 
         /* clear the zero-page */
         memset((void *) empty_zero_page, 0, PAGE_SIZE);
@@ -84,7 +79,7 @@
 	uml_reserved = brk_end;
 
 	/* Fill in any hole at the start of the binary */
-	start = (unsigned long) &__binary_start;
+	start = (unsigned long) &__binary_start & PAGE_MASK;
 	if(uml_physmem != start){
 		map_memory(uml_physmem, __pa(uml_physmem), start - uml_physmem,
 			   1, 1, 0);
@@ -135,12 +130,13 @@
 	}
 }
 
-#if CONFIG_HIGHMEM
+#ifdef CONFIG_HIGHMEM
 pte_t *kmap_pte;
 pgprot_t kmap_prot;
 
 #define kmap_get_fixmap_pte(vaddr)					\
-	pte_offset(pmd_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr))
+	pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), (vaddr)),\
+ 			  (vaddr)), (vaddr))
 
 void __init kmap_init(void)
 {
@@ -156,6 +152,7 @@
 static void init_highmem(void)
 {
 	pgd_t *pgd;
+	pud_t *pud;
 	pmd_t *pmd;
 	pte_t *pte;
 	unsigned long vaddr;
@@ -167,7 +164,8 @@
 	fixrange_init(vaddr, vaddr + PAGE_SIZE*LAST_PKMAP, swapper_pg_dir);
 
 	pgd = swapper_pg_dir + pgd_index(vaddr);
-	pmd = pmd_offset(pgd, vaddr);
+	pud = pud_offset(pgd, vaddr);
+	pmd = pmd_offset(pud, vaddr);
 	pte = pte_offset_kernel(pmd, vaddr);
 	pkmap_page_table = pte;
 
@@ -175,6 +173,33 @@
 }
 #endif /* CONFIG_HIGHMEM */
 
+static void __init fixaddr_user_init( void)
+{
+#if CONFIG_ARCH_REUSE_HOST_VSYSCALL_AREA
+	long size = FIXADDR_USER_END - FIXADDR_USER_START;
+	pgd_t *pgd;
+	pud_t *pud;
+	pmd_t *pmd;
+	pte_t *pte;
+	unsigned long paddr, vaddr = FIXADDR_USER_START;
+
+	if (  ! size )
+		return;
+
+	fixrange_init( FIXADDR_USER_START, FIXADDR_USER_END, swapper_pg_dir);
+	paddr = (unsigned long)alloc_bootmem_low_pages( size);
+	memcpy( (void *)paddr, (void *)FIXADDR_USER_START, size);
+	paddr = __pa(paddr);
+	for ( ; size > 0; size-=PAGE_SIZE, vaddr+=PAGE_SIZE, paddr+=PAGE_SIZE){
+		pgd = swapper_pg_dir + pgd_index(vaddr);
+		pud = pud_offset(pgd, vaddr);
+		pmd = pmd_offset(pud, vaddr);
+		pte = pte_offset_kernel(pmd, vaddr);
+		pte_set_val( (*pte), paddr, PAGE_READONLY);
+	}
+#endif
+}
+
 void paging_init(void)
 {
 	unsigned long zones_size[MAX_NR_ZONES], vaddr;
@@ -195,6 +220,8 @@
 	vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
 	fixrange_init(vaddr, FIXADDR_TOP, swapper_pg_dir);
 
+	fixaddr_user_init();
+
 #ifdef CONFIG_HIGHMEM
 	init_highmem();
 #endif
@@ -212,7 +239,7 @@
 	addr = (unsigned long) page_address(page);
 	for(i = 0; i < (1 << order); i++){
 		current->thread.fault_addr = (void *) addr;
-		if(__do_copy_to_user((void *) addr, &zero,
+		if(__do_copy_to_user((void __user *) addr, &zero,
 				     sizeof(zero),
 				     &current->thread.fault_addr,
 				     &current->thread.fault_catcher)){
@@ -221,6 +248,7 @@
 		}
 		addr += PAGE_SIZE;
 	}
+
 	if(i == (1 << order)) return(page);
 	page = alloc_pages(mask, order);
 	goto again;
@@ -307,9 +335,7 @@
 {
 	pte_t *pte;
 
-	pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT);
-	if (pte)
-		clear_page(pte);
+	pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO);
 	return pte;
 }
 
@@ -317,9 +343,7 @@
 {
 	struct page *pte;
    
-	pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT, 0);
-	if (pte)
-		clear_highpage(pte);
+	pte = alloc_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO);
 	return pte;
 }
 
diff -Nru a/arch/um/kernel/mem_user.c b/arch/um/kernel/mem_user.c
--- a/arch/um/kernel/mem_user.c	2005-03-01 23:38:58 -08:00
+++ b/arch/um/kernel/mem_user.c	2005-03-01 23:38:58 -08:00
@@ -48,8 +48,6 @@
 #include "tempfile.h"
 #include "kern_constants.h"
 
-extern struct mem_region physmem_region;
-
 #define TEMPNAME_TEMPLATE "vm_file-XXXXXX"
 
 static int create_tmp_file(unsigned long len)
@@ -101,6 +99,8 @@
 	}
 	printf("OK\n");
 	munmap(addr, UM_KERN_PAGE_SIZE);
+
+	os_close_file(fd);
 }
 
 static int have_devanon = 0;
@@ -133,7 +133,7 @@
 
 	addr = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
 	if(addr == MAP_FAILED){
-		os_print_error((int) addr, "mapping physmem file");
+		perror("mapping physmem file");
 		exit(1);
 	}
 	munmap(addr, len);
diff -Nru a/arch/um/kernel/physmem.c b/arch/um/kernel/physmem.c
--- a/arch/um/kernel/physmem.c	2005-03-01 23:39:07 -08:00
+++ b/arch/um/kernel/physmem.c	2005-03-01 23:39:07 -08:00
@@ -309,7 +309,7 @@
 	return(&mem_map[__pa(virt) >> PAGE_SHIFT]);
 }
 
-unsigned long page_to_phys(struct page *page)
+phys_t page_to_phys(struct page *page)
 {
 	return((page - mem_map) << PAGE_SHIFT);
 }
@@ -318,8 +318,9 @@
 {
 	pte_t pte;
 
-	pte_val(pte) = page_to_phys(page) + pgprot_val(pgprot);
-	if(pte_present(pte)) pte_mknewprot(pte_mknewpage(pte));
+	pte_set_val(pte, page_to_phys(page), pgprot);
+	if(pte_present(pte))
+		pte_mknewprot(pte_mknewpage(pte));
 	return(pte);
 }
 
diff -Nru a/arch/um/kernel/process.c b/arch/um/kernel/process.c
--- a/arch/um/kernel/process.c	2005-03-01 23:39:09 -08:00
+++ b/arch/um/kernel/process.c	2005-03-01 23:39:09 -08:00
@@ -13,13 +13,14 @@
 #include <setjmp.h>
 #include <sys/time.h>
 #include <sys/ptrace.h>
+
+/*Userspace header, must be after sys/ptrace.h, and both must be included. */
+#include <linux/ptrace.h>
+
 #include <sys/wait.h>
 #include <sys/mman.h>
-#include <asm/ptrace.h>
-#include <asm/sigcontext.h>
 #include <asm/unistd.h>
 #include <asm/page.h>
-#include <asm/user.h>
 #include "user_util.h"
 #include "kern_util.h"
 #include "user.h"
@@ -27,6 +28,7 @@
 #include "signal_kern.h"
 #include "signal_user.h"
 #include "sysdep/ptrace.h"
+#include "sysdep/ptrace_user.h"
 #include "sysdep/sigcontext.h"
 #include "irq_user.h"
 #include "ptrace_user.h"
@@ -39,6 +41,7 @@
 #ifdef UML_CONFIG_MODE_SKAS
 #include "skas.h"
 #include "skas_ptrace.h"
+#include "registers.h"
 #endif
 
 void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int))
@@ -240,7 +243,7 @@
 static void __init check_sysemu(void)
 {
 	void *stack;
-	int pid, n, status;
+	int pid, syscall, n, status, count=0;
 
 	printk("Checking syscall emulation patch for ptrace...");
 	sysemu_supported = 0;
@@ -268,12 +271,46 @@
 	sysemu_supported = 1;
 	printk("OK\n");
 	set_using_sysemu(!force_sysemu_disabled);
+
+	printk("Checking advanced syscall emulation patch for ptrace...");
+	pid = start_ptraced_child(&stack);
+	while(1){
+		count++;
+		if(ptrace(PTRACE_SYSEMU_SINGLESTEP, pid, 0, 0) < 0)
+			goto fail;
+		CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
+		if(n < 0)
+			panic("check_ptrace : wait failed, errno = %d", errno);
+		if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP))
+			panic("check_ptrace : expected (SIGTRAP|SYSCALL_TRAP), "
+			      "got status = %d", status);
+
+		syscall = ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_NR_OFFSET,
+				 0);
+		if(syscall == __NR_getpid){
+			if (!count)
+				panic("check_ptrace : SYSEMU_SINGLESTEP doesn't singlestep");
+			n = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_RET_OFFSET,
+				   os_getpid());
+			if(n < 0)
+				panic("check_sysemu : failed to modify system "
+				      "call return, errno = %d", errno);
+			break;
+		}
+	}
+	if (stop_ptraced_child(pid, stack, 0, 0) < 0)
+		goto fail_stopped;
+
+	sysemu_supported = 2;
+	printk("OK\n");
+
+	if ( !force_sysemu_disabled )
+		set_using_sysemu(sysemu_supported);
 	return;
 
 fail:
 	stop_ptraced_child(pid, stack, 1, 0);
 fail_stopped:
-	sysemu_supported = 0;
 	printk("missing\n");
 }
 
@@ -285,6 +322,9 @@
 	printk("Checking that ptrace can change system call numbers...");
 	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);
+
 	while(1){
 		if(ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0)
 			panic("check_ptrace : ptrace failed, errno = %d", 
@@ -292,8 +332,8 @@
 		CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
 		if(n < 0)
 			panic("check_ptrace : wait failed, errno = %d", errno);
-		if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP))
-			panic("check_ptrace : expected SIGTRAP, "
+		if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP + 0x80))
+			panic("check_ptrace : expected SIGTRAP + 0x80, "
 			      "got status = %d", status);
 		
 		syscall = ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_NR_OFFSET,
@@ -335,9 +375,9 @@
 		kill(target, SIGIO);
 }
 
-int can_do_skas(void)
-{
 #ifdef UML_CONFIG_MODE_SKAS
+static inline int check_skas3_ptrace_support(void)
+{
 	struct ptrace_faultinfo fi;
 	void *stack;
 	int pid, n, ret = 1;
@@ -346,37 +386,43 @@
 	pid = start_ptraced_child(&stack);
 
 	n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi);
-	if(n < 0){
+	if (n < 0) {
 		if(errno == EIO)
 			printf("not found\n");
-		else printf("No (unexpected errno - %d)\n", errno);
+		else {
+			perror("not found");
+		}
 		ret = 0;
+	} else {
+		printf("found\n");
 	}
-	else printf("found\n");
 
 	init_registers(pid);
 	stop_ptraced_child(pid, stack, 1, 1);
 
+	return(ret);
+}
+
+int can_do_skas(void)
+{
+	int ret = 1;
+
 	printf("Checking for /proc/mm...");
-	if(os_access("/proc/mm", OS_ACC_W_OK) < 0){
+	if (os_access("/proc/mm", OS_ACC_W_OK) < 0) {
 		printf("not found\n");
 		ret = 0;
+		goto out;
+	} else {
+		printf("found\n");
 	}
-	else printf("found\n");
 
-	return(ret);
+	ret = check_skas3_ptrace_support();
+out:
+	return ret;
+}
 #else
+int can_do_skas(void)
+{
 	return(0);
-#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:
- */
+#endif
diff -Nru a/arch/um/kernel/process_kern.c b/arch/um/kernel/process_kern.c
--- a/arch/um/kernel/process_kern.c	2005-03-01 23:38:57 -08:00
+++ b/arch/um/kernel/process_kern.c	2005-03-01 23:38:57 -08:00
@@ -235,18 +235,28 @@
 		      pte_t *pte_out)
 {
 	pgd_t *pgd;
+	pud_t *pud;
 	pmd_t *pmd;
 	pte_t *pte;
 
 	if(task->mm == NULL) 
 		return(ERR_PTR(-EINVAL));
 	pgd = pgd_offset(task->mm, addr);
-	pmd = pmd_offset(pgd, addr);
+	if(!pgd_present(*pgd))
+		return(ERR_PTR(-EINVAL));
+
+	pud = pud_offset(pgd, addr);
+	if(!pud_present(*pud))
+		return(ERR_PTR(-EINVAL));
+
+	pmd = pmd_offset(pud, addr);
 	if(!pmd_present(*pmd)) 
 		return(ERR_PTR(-EINVAL));
+
 	pte = pte_offset_kernel(pmd, addr);
 	if(!pte_present(*pte)) 
 		return(ERR_PTR(-EINVAL));
+
 	if(pte_out != NULL)
 		*pte_out = *pte;
 	return((void *) (pte_val(*pte) & PAGE_MASK) + (addr & ~PAGE_MASK));
@@ -291,8 +301,6 @@
 
 EXPORT_SYMBOL(disable_hlt);
 
-extern int signal_frame_size;
-
 void *um_kmalloc(int size)
 {
 	return(kmalloc(size, GFP_KERNEL));
@@ -360,22 +368,22 @@
 	return(&init_thread_union.thread_info.task);
 }
 
-int copy_to_user_proc(void *to, void *from, int size)
+int copy_to_user_proc(void __user *to, void *from, int size)
 {
 	return(copy_to_user(to, from, size));
 }
 
-int copy_from_user_proc(void *to, void *from, int size)
+int copy_from_user_proc(void *to, void __user *from, int size)
 {
 	return(copy_from_user(to, from, size));
 }
 
-int clear_user_proc(void *buf, int size)
+int clear_user_proc(void __user *buf, int size)
 {
 	return(clear_user(buf, size));
 }
 
-int strlen_user_proc(char *str)
+int strlen_user_proc(char __user *str)
 {
 	return(strlen_user(str));
 }
@@ -406,7 +414,9 @@
 
 void set_using_sysemu(int value)
 {
-	atomic_set(&using_sysemu, sysemu_supported && value);
+	if (value > sysemu_supported)
+		return;
+	atomic_set(&using_sysemu, value);
 }
 
 int get_using_sysemu(void)
@@ -429,7 +439,7 @@
 	if (copy_from_user(tmp, buf, 1))
 		return -EFAULT;
 
-	if (tmp[0] == '0' || tmp[0] == '1')
+	if (tmp[0] >= '0' && tmp[0] <= '2')
 		set_using_sysemu(tmp[0] - '0');
 	return count; /*We use the first char, but pretend to write everything*/
 }
@@ -464,9 +474,9 @@
 		return(0);
 
 	if (task->thread.singlestep_syscall)
-		return(0);
+		return(1);
 
-	return 1;
+	return 2;
 }
 
 /*
diff -Nru a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c
--- a/arch/um/kernel/ptrace.c	2005-03-01 23:39:18 -08:00
+++ b/arch/um/kernel/ptrace.c	2005-03-01 23:39:18 -08:00
@@ -16,6 +16,7 @@
 #include "asm/uaccess.h"
 #include "kern_util.h"
 #include "ptrace_user.h"
+#include "skas_ptrace.h"
 
 /*
  * Called by kernel/ptrace.c when detaching..
@@ -80,7 +81,7 @@
 		copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
 		if (copied != sizeof(tmp))
 			break;
-		ret = put_user(tmp,(unsigned long *) data);
+		ret = put_user(tmp, (unsigned long __user *) data);
 		break;
 	}
 
@@ -93,7 +94,7 @@
 			break;
 
 		tmp = 0;  /* Default return condition */
-		if(addr < FRAME_SIZE_OFFSET){
+		if(addr < MAX_REG_OFFSET){
 			tmp = getreg(child, addr);
 		}
 		else if((addr >= offsetof(struct user, u_debugreg[0])) &&
@@ -102,7 +103,7 @@
 			addr = addr >> 2;
 			tmp = child->thread.arch.debugregs[addr];
 		}
-		ret = put_user(tmp, (unsigned long *) data);
+		ret = put_user(tmp, (unsigned long __user *) data);
 		break;
 	}
 
@@ -121,10 +122,11 @@
 		if ((addr & 3) || addr < 0)
 			break;
 
-		if (addr < FRAME_SIZE_OFFSET) {
+		if (addr < MAX_REG_OFFSET) {
 			ret = putreg(child, addr, data);
 			break;
 		}
+#if 0 /* XXX x86_64 */
 		else if((addr >= offsetof(struct user, u_debugreg[0])) &&
 			(addr <= offsetof(struct user, u_debugreg[7]))){
 			  addr -= offsetof(struct user, u_debugreg[0]);
@@ -133,6 +135,7 @@
 			  child->thread.arch.debugregs[addr] = data;
 			  ret = 0;
 		}
+#endif
 
 		break;
 
@@ -195,12 +198,13 @@
 #ifdef PTRACE_GETREGS
 	case PTRACE_GETREGS: { /* Get all gp regs from the child. */
 	  	if (!access_ok(VERIFY_WRITE, (unsigned long *)data, 
-			       FRAME_SIZE_OFFSET)) {
+			       MAX_REG_OFFSET)) {
 			ret = -EIO;
 			break;
 		}
-		for ( i = 0; i < FRAME_SIZE_OFFSET; i += sizeof(long) ) {
-			__put_user(getreg(child, i), (unsigned long *) data);
+		for ( i = 0; i < MAX_REG_OFFSET; i += sizeof(long) ) {
+			__put_user(getreg(child, i),
+				   (unsigned long __user *) data);
 			data += sizeof(long);
 		}
 		ret = 0;
@@ -211,12 +215,12 @@
 	case PTRACE_SETREGS: { /* Set all gp regs in the child. */
 		unsigned long tmp = 0;
 	  	if (!access_ok(VERIFY_READ, (unsigned *)data, 
-			       FRAME_SIZE_OFFSET)) {
+			       MAX_REG_OFFSET)) {
 			ret = -EIO;
 			break;
 		}
-		for ( i = 0; i < FRAME_SIZE_OFFSET; i += sizeof(long) ) {
-			__get_user(tmp, (unsigned long *) data);
+		for ( i = 0; i < MAX_REG_OFFSET; i += sizeof(long) ) {
+			__get_user(tmp, (unsigned long __user *) data);
 			putreg(child, i, tmp);
 			data += sizeof(long);
 		}
@@ -250,14 +254,14 @@
 		fault = ((struct ptrace_faultinfo) 
 			{ .is_write	= child->thread.err,
 			  .addr		= child->thread.cr2 });
-		ret = copy_to_user((unsigned long *) data, &fault, 
+		ret = copy_to_user((unsigned long __user *) data, &fault,
 				   sizeof(fault));
 		if(ret)
 			break;
 		break;
 	}
 	case PTRACE_SIGPENDING:
-		ret = copy_to_user((unsigned long *) data, 
+		ret = copy_to_user((unsigned long __user *) data,
 				   &child->pending.signal,
 				   sizeof(child->pending.signal));
 		break;
@@ -265,7 +269,7 @@
 	case PTRACE_LDT: {
 		struct ptrace_ldt ldt;
 
-		if(copy_from_user(&ldt, (unsigned long *) data, 
+		if(copy_from_user(&ldt, (unsigned long __user *) data,
 				  sizeof(ldt))){
 			ret = -EIO;
 			break;
@@ -306,6 +310,25 @@
 	return ret;
 }
 
+void send_sigtrap(struct task_struct *tsk, union uml_pt_regs *regs,
+		  int error_code)
+{
+	struct siginfo info;
+
+	memset(&info, 0, sizeof(info));
+	info.si_signo = SIGTRAP;
+	info.si_code = TRAP_BRKPT;
+
+	/* User-mode eip? */
+	info.si_addr = UPT_IS_USER(regs) ? (void __user *) UPT_IP(regs) : NULL;
+
+	/* Send us the fakey SIGTRAP */
+	force_sig_info(SIGTRAP, &info, tsk);
+}
+
+/* XXX Check PT_DTRACE vs TIF_SINGLESTEP for singlestepping check and
+ * PT_PTRACED vs TIF_SYSCALL_TRACE for syscall tracing check
+ */
 void syscall_trace(union uml_pt_regs *regs, int entryexit)
 {
 	int is_singlestep = (current->ptrace & PT_DTRACE) && entryexit;
@@ -320,18 +343,23 @@
 			audit_syscall_exit(current, regs->eax);
 	}
 
-	if (!test_thread_flag(TIF_SYSCALL_TRACE) && !is_singlestep)
+	/* Fake a debug trap */
+	if (is_singlestep)
+		send_sigtrap(current, regs, 0);
+
+	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 */
-	tracesysgood = (current->ptrace & PT_TRACESYSGOOD) && !is_singlestep;
+	tracesysgood = (current->ptrace & PT_TRACESYSGOOD);
 	ptrace_notify(SIGTRAP | (tracesysgood ? 0x80 : 0));
 
-	/* force do_signal() --> is_syscall() */
-	set_thread_flag(TIF_SIGPENDING);
+	if (entryexit) /* force do_signal() --> is_syscall() */
+		set_thread_flag(TIF_SIGPENDING);
 
 	/* 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
diff -Nru a/arch/um/kernel/sigio_kern.c b/arch/um/kernel/sigio_kern.c
--- a/arch/um/kernel/sigio_kern.c	2005-03-01 23:38:54 -08:00
+++ b/arch/um/kernel/sigio_kern.c	2005-03-01 23:38:54 -08:00
@@ -39,7 +39,7 @@
 	return(0);
 }
 
-static spinlock_t sigio_spinlock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(sigio_spinlock);
 
 void sigio_lock(void)
 {
diff -Nru a/arch/um/kernel/signal_kern.c b/arch/um/kernel/signal_kern.c
--- a/arch/um/kernel/signal_kern.c	2005-03-01 23:38:58 -08:00
+++ b/arch/um/kernel/signal_kern.c	2005-03-01 23:38:58 -08:00
@@ -74,10 +74,12 @@
 	if((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags(sp) == 0))
 		sp = current->sas_ss_sp + current->sas_ss_size;
 
-	if(ka->sa.sa_flags & SA_SIGINFO)
-		err = setup_signal_stack_si(sp, signr, ka, regs, info, oldset);
-	else
+#ifdef CONFIG_ARCH_HAS_SC_SIGNALS
+	if(!(ka->sa.sa_flags & SA_SIGINFO))
 		err = setup_signal_stack_sc(sp, signr, ka, regs, oldset);
+	else
+#endif
+		err = setup_signal_stack_si(sp, signr, ka, regs, info, oldset);
 
 	if(err){
 		spin_lock_irq(&current->sighand->siglock);
@@ -194,87 +196,9 @@
 	}
 }
 
-int sys_sigaction(int sig, const struct old_sigaction __user *act,
-			 struct old_sigaction __user *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;
-}
-
-long sys_sigaltstack(const stack_t *uss, stack_t *uoss)
+long sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss)
 {
 	return(do_sigaltstack(uss, uoss, PT_REGS_SP(&current->thread.regs)));
-}
-
-extern int userspace_pid[];
-
-static int copy_sc_from_user(struct pt_regs *to, void *from, 
-			     struct arch_frame_data *arch)
-{
-	int ret;
-
-	ret = CHOOSE_MODE(copy_sc_from_user_tt(UPT_SC(&to->regs), from, arch),
-			  copy_sc_from_user_skas(userspace_pid[0],
-						 &to->regs, from));
-	return(ret);
-}
-
-long sys_sigreturn(struct pt_regs regs)
-{
-	void __user *sc = sp_to_sc(PT_REGS_SP(&current->thread.regs));
-	void __user *mask = sp_to_mask(PT_REGS_SP(&current->thread.regs));
-	int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long);
-
-	spin_lock_irq(&current->sighand->siglock);
-	copy_from_user(&current->blocked.sig[0], sc_sigmask(sc), 
-		       sizeof(current->blocked.sig[0]));
-	copy_from_user(&current->blocked.sig[1], mask, sig_size);
-	sigdelsetmask(&current->blocked, ~_BLOCKABLE);
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
-	copy_sc_from_user(&current->thread.regs, sc, 
-			  &signal_frame_sc.common.arch);
-	return(PT_REGS_SYSCALL_RET(&current->thread.regs));
-}
-
-long sys_rt_sigreturn(struct pt_regs regs)
-{
-	unsigned long sp = PT_REGS_SP(&current->thread.regs);
-	struct ucontext __user *uc = sp_to_uc(sp);
-	int sig_size = _NSIG_WORDS * sizeof(unsigned long);
-
-	spin_lock_irq(&current->sighand->siglock);
-	copy_from_user(&current->blocked, &uc->uc_sigmask, sig_size);
-	sigdelsetmask(&current->blocked, ~_BLOCKABLE);
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
-	copy_sc_from_user(&current->thread.regs, &uc->uc_mcontext,
-			  &signal_frame_si.common.arch);
-	return(PT_REGS_SYSCALL_RET(&current->thread.regs));
 }
 
 /*
diff -Nru a/arch/um/kernel/signal_user.c b/arch/um/kernel/signal_user.c
--- a/arch/um/kernel/signal_user.c	2005-03-01 23:39:08 -08:00
+++ b/arch/um/kernel/signal_user.c	2005-03-01 23:39:08 -08:00
@@ -41,6 +41,7 @@
 	while((mask = va_arg(ap, int)) != -1){
 		sigaddset(&action.sa_mask, mask);
 	}
+	va_end(ap);
 	action.sa_flags = flags;
 	action.sa_restorer = NULL;
 	if(sigaction(sig, &action, NULL) < 0)
diff -Nru a/arch/um/kernel/skas/Makefile b/arch/um/kernel/skas/Makefile
--- a/arch/um/kernel/skas/Makefile	2005-03-01 23:38:54 -08:00
+++ b/arch/um/kernel/skas/Makefile	2005-03-01 23:38:54 -08:00
@@ -5,12 +5,11 @@
 
 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 \
-	sys-$(SUBARCH)/
-
-subdir-y := util
 
 USER_OBJS = $(filter %_user.o,$(obj-y)) process.o time.o
 USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
 
 $(USER_OBJS) : %.o: %.c
 	$(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
+
+subdir- := util
diff -Nru 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	2005-03-01 23:38:58 -08:00
+++ b/arch/um/kernel/skas/include/mode-skas.h	2005-03-01 23:38:58 -08:00
@@ -14,11 +14,6 @@
 extern int have_fpx_regs;
 
 extern void user_time_init_skas(void);
-extern int copy_sc_from_user_skas(int pid, union uml_pt_regs *regs,
-				  void *from_ptr);
-extern int copy_sc_to_user_skas(int pid, void *to_ptr, void *fp,
-				union uml_pt_regs *regs,
-				unsigned long fault_addr, int fault_type);
 extern void sig_handler_common_skas(int sig, void *sc_ptr);
 extern void halt_skas(void);
 extern void reboot_skas(void);
diff -Nru a/arch/um/kernel/skas/include/ptrace-skas.h b/arch/um/kernel/skas/include/ptrace-skas.h
--- a/arch/um/kernel/skas/include/ptrace-skas.h	2005-03-01 23:38:52 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,57 +0,0 @@
-/* 
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#ifndef __PTRACE_SKAS_H
-#define __PTRACE_SKAS_H
-
-#include "uml-config.h"
-
-#ifdef UML_CONFIG_MODE_SKAS
-
-#include "skas_ptregs.h"
-
-#define HOST_FRAME_SIZE 17
-
-#define REGS_IP(r) ((r)[HOST_IP])
-#define REGS_SP(r) ((r)[HOST_SP])
-#define REGS_EFLAGS(r) ((r)[HOST_EFLAGS])
-#define REGS_EAX(r) ((r)[HOST_EAX])
-#define REGS_EBX(r) ((r)[HOST_EBX])
-#define REGS_ECX(r) ((r)[HOST_ECX])
-#define REGS_EDX(r) ((r)[HOST_EDX])
-#define REGS_ESI(r) ((r)[HOST_ESI])
-#define REGS_EDI(r) ((r)[HOST_EDI])
-#define REGS_EBP(r) ((r)[HOST_EBP])
-#define REGS_CS(r) ((r)[HOST_CS])
-#define REGS_SS(r) ((r)[HOST_SS])
-#define REGS_DS(r) ((r)[HOST_DS])
-#define REGS_ES(r) ((r)[HOST_ES])
-#define REGS_FS(r) ((r)[HOST_FS])
-#define REGS_GS(r) ((r)[HOST_GS])
-
-#define REGS_SET_SYSCALL_RETURN(r, res) REGS_EAX(r) = (res)
-
-#define REGS_RESTART_SYSCALL(r) IP_RESTART_SYSCALL(REGS_IP(r))
-
-#define REGS_SEGV_IS_FIXABLE(r) SEGV_IS_FIXABLE((r)->trap_type)
-
-#define REGS_FAULT_ADDR(r) ((r)->fault_addr)
-
-#define REGS_FAULT_WRITE(r) FAULT_WRITE((r)->fault_type)
-
-#endif
-
-#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 -Nru a/arch/um/kernel/skas/include/skas.h b/arch/um/kernel/skas/include/skas.h
--- a/arch/um/kernel/skas/include/skas.h	2005-03-01 23:38:54 -08:00
+++ b/arch/um/kernel/skas/include/skas.h	2005-03-01 23:38:54 -08:00
@@ -29,10 +29,7 @@
 		   int r, int w, int x, int must_succeed);
 extern void user_signal(int sig, union uml_pt_regs *regs);
 extern int new_mm(int from);
-extern void save_registers(union uml_pt_regs *regs);
-extern void restore_registers(union uml_pt_regs *regs);
 extern void start_userspace(int cpu);
-extern void init_registers(int pid);
 
 #endif
 
diff -Nru a/arch/um/kernel/skas/include/uaccess-skas.h b/arch/um/kernel/skas/include/uaccess-skas.h
--- a/arch/um/kernel/skas/include/uaccess-skas.h	2005-03-01 23:38:56 -08:00
+++ b/arch/um/kernel/skas/include/uaccess-skas.h	2005-03-01 23:38:56 -08:00
@@ -7,11 +7,16 @@
 #define __SKAS_UACCESS_H
 
 #include "asm/errno.h"
+#include "asm/fixmap.h"
 
 #define access_ok_skas(type, addr, size) \
 	((segment_eq(get_fs(), KERNEL_DS)) || \
 	 (((unsigned long) (addr) < TASK_SIZE) && \
-	  ((unsigned long) (addr) + (size) <= TASK_SIZE)))
+	  ((unsigned long) (addr) + (size) <= TASK_SIZE)) || \
+	 ((type == VERIFY_READ ) && \
+	  ((unsigned long) (addr) >= FIXADDR_USER_START) && \
+	  ((unsigned long) (addr) + (size) <= FIXADDR_USER_END) && \
+	  ((unsigned long) (addr) + (size) >= (unsigned long)(addr))))
 
 static inline int verify_area_skas(int type, const void * addr,
 				   unsigned long size)
diff -Nru a/arch/um/kernel/skas/mem.c b/arch/um/kernel/skas/mem.c
--- a/arch/um/kernel/skas/mem.c	2005-03-01 23:39:10 -08:00
+++ b/arch/um/kernel/skas/mem.c	2005-03-01 23:39:10 -08:00
@@ -13,8 +13,13 @@
 	/* Round up to the nearest 4M */
 	unsigned long top = ROUND_4M((unsigned long) &arg);
 
+#ifdef CONFIG_HOST_TASK_SIZE
+	*host_size_out = CONFIG_HOST_TASK_SIZE;
+	*task_size_out = CONFIG_HOST_TASK_SIZE;
+#else
 	*host_size_out = top;
 	*task_size_out = top;
+#endif
 	return(((unsigned long) set_task_sizes_skas) & ~0xffffff);
 }
 
diff -Nru a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c
--- a/arch/um/kernel/skas/process.c	2005-03-01 23:39:16 -08:00
+++ b/arch/um/kernel/skas/process.c	2005-03-01 23:39:16 -08:00
@@ -11,6 +11,7 @@
 #include <sched.h>
 #include <sys/wait.h>
 #include <sys/ptrace.h>
+#include <linux/ptrace.h>
 #include <sys/mman.h>
 #include <sys/user.h>
 #include <asm/unistd.h>
@@ -27,6 +28,7 @@
 #include "skas_ptrace.h"
 #include "chan_user.h"
 #include "signal_user.h"
+#include "registers.h"
 
 int is_skas_winch(int pid, int fd, void *data)
 {
@@ -37,13 +39,6 @@
 	return(1);
 }
 
-/* These are set once at boot time and not changed thereafter */
-
-unsigned long exec_regs[FRAME_SIZE];
-unsigned long exec_fp_regs[HOST_FP_SIZE];
-unsigned long exec_fpx_regs[HOST_XFP_SIZE];
-int have_fpx_regs = 1;
-
 static void handle_segv(int pid)
 {
 	struct ptrace_faultinfo fault;
@@ -60,14 +55,10 @@
 /*To use the same value of using_sysemu as the caller, ask it that value (in local_using_sysemu)*/
 static void handle_trap(int pid, union uml_pt_regs *regs, int local_using_sysemu)
 {
-	int err, syscall_nr, status;
+	int err, status;
 
-	syscall_nr = PT_SYSCALL_NR(regs->skas.regs);
-	UPT_SYSCALL_NR(regs) = syscall_nr;
-	if(syscall_nr < 0){
-		relay_signal(SIGTRAP, regs);
-		return;
-	}
+	/* Mark this as a syscall */
+	UPT_SYSCALL_NR(regs) = PT_SYSCALL_NR(regs->skas.regs);
 
 	if (!local_using_sysemu)
 	{
@@ -82,7 +73,8 @@
 			      "errno = %d\n", errno);
 
 		CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED));
-		if((err < 0) || !WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP))
+		if((err < 0) || !WIFSTOPPED(status) ||
+		   (WSTOPSIG(status) != SIGTRAP + 0x80))
 			panic("handle_trap - failed to wait at end of syscall, "
 			      "errno = %d, status = %d\n", errno, status);
 	}
@@ -100,6 +92,7 @@
 }
 
 /* Each element set once, and only accessed by a single processor anyway */
+#undef NR_CPUS
 #define NR_CPUS 1
 int userspace_pid[NR_CPUS];
 
@@ -131,6 +124,10 @@
 		panic("start_userspace : expected SIGSTOP, got status = %d",
 		      status);
 
+	if (ptrace(PTRACE_OLDSETOPTIONS, pid, NULL, (void *)PTRACE_O_TRACESYSGOOD) < 0)
+		panic("start_userspace : PTRACE_SETOPTIONS failed, errno=%d\n",
+		      errno);
+
 	if(munmap(stack, PAGE_SIZE) < 0)
 		panic("start_userspace : munmap failed, errno = %d\n", errno);
 
@@ -139,15 +136,15 @@
 
 void userspace(union uml_pt_regs *regs)
 {
-	int err, status, op, pt_syscall_parm, pid = userspace_pid[0];
+	int err, status, op, pid = userspace_pid[0];
 	int local_using_sysemu; /*To prevent races if using_sysemu changes under us.*/
 
-	restore_registers(regs);
+	restore_registers(pid, regs);
 		
 	local_using_sysemu = get_using_sysemu();
 
-	pt_syscall_parm = local_using_sysemu ? PTRACE_SYSEMU : PTRACE_SYSCALL;
-	err = ptrace(pt_syscall_parm, pid, 0, 0);
+	op = local_using_sysemu ? PTRACE_SYSEMU : PTRACE_SYSCALL;
+	err = ptrace(op, pid, 0, 0);
 
 	if(err)
 		panic("userspace - PTRACE_%s failed, errno = %d\n",
@@ -159,16 +156,20 @@
 			      errno);
 
 		regs->skas.is_user = 1;
-		save_registers(regs);
+		save_registers(pid, regs);
+		UPT_SYSCALL_NR(regs) = -1; /* Assume: It's not a syscall */
 
 		if(WIFSTOPPED(status)){
 		  	switch(WSTOPSIG(status)){
 			case SIGSEGV:
 				handle_segv(pid);
 				break;
-			case SIGTRAP:
+			case SIGTRAP + 0x80:
 			        handle_trap(pid, regs, local_using_sysemu);
 				break;
+			case SIGTRAP:
+				relay_signal(SIGTRAP, regs);
+				break;
 			case SIGIO:
 			case SIGVTALRM:
 			case SIGILL:
@@ -182,16 +183,17 @@
 				       "%d\n", WSTOPSIG(status));
 			}
 			interrupt_end();
+
+			/* Avoid -ERESTARTSYS handling in host */
+			PT_SYSCALL_NR(regs->skas.regs) = -1;
 		}
 
-		restore_registers(regs);
+		restore_registers(pid, regs);
 
 		/*Now we ended the syscall, so re-read local_using_sysemu.*/
 		local_using_sysemu = get_using_sysemu();
-		pt_syscall_parm = local_using_sysemu ? PTRACE_SYSEMU : PTRACE_SYSCALL;
 
-		op = singlestepping(NULL) ? PTRACE_SINGLESTEP :
-			pt_syscall_parm;
+		op = SELECT_PTRACE_OPERATION(local_using_sysemu, singlestepping(NULL));
 
 		err = ptrace(op, pid, 0, 0);
 		if(err)
@@ -222,9 +224,10 @@
 	block_signals();
 	if(sigsetjmp(fork_buf, 1) == 0)
 		new_thread_proc(stack, handler);
-	set_signals(flags);
 
 	remove_sigstack();
+
+	set_signals(flags);
 }
 
 void thread_wait(void *sw, void *fb)
@@ -237,58 +240,6 @@
 		siglongjmp(*fork_buf, 1);
 }
 
-static int move_registers(int pid, int int_op, int fp_op,
-			  union uml_pt_regs *regs, unsigned long *fp_regs)
-{
-	if(ptrace(int_op, pid, 0, regs->skas.regs) < 0)
-		return(-errno);
-	if(ptrace(fp_op, pid, 0, fp_regs) < 0)
-		return(-errno);
-	return(0);
-}
-
-void save_registers(union uml_pt_regs *regs)
-{
-	unsigned long *fp_regs;
-	int err, fp_op;
-
-	if(have_fpx_regs){
-		fp_op = PTRACE_GETFPXREGS;
-		fp_regs = regs->skas.xfp;
-	}
-	else {
-		fp_op = PTRACE_GETFPREGS;
-		fp_regs = regs->skas.fp;
-	}
-
-	err = move_registers(userspace_pid[0], PTRACE_GETREGS, fp_op, regs,
-			     fp_regs);
-	if(err)
-		panic("save_registers - saving registers failed, errno = %d\n",
-		      -err);
-}
-
-void restore_registers(union uml_pt_regs *regs)
-{
-	unsigned long *fp_regs;
-	int err, fp_op;
-
-	if(have_fpx_regs){
-		fp_op = PTRACE_SETFPXREGS;
-		fp_regs = regs->skas.xfp;
-	}
-	else {
-		fp_op = PTRACE_SETFPREGS;
-		fp_regs = regs->skas.fp;
-	}
-
-	err = move_registers(userspace_pid[0], PTRACE_SETREGS, fp_op, regs,
-			     fp_regs);
-	if(err)
-		panic("restore_registers - saving registers failed, "
-		      "errno = %d\n", -err);
-}
-
 void switch_threads(void *me, void *next)
 {
 	sigjmp_buf my_buf, **me_ptr = me, *next_buf = next;
@@ -386,29 +337,6 @@
 {
 #warning need to loop over userspace_pids in kill_off_processes_skas
 	os_kill_ptraced_process(userspace_pid[0], 1);
-}
-
-void init_registers(int pid)
-{
-	int err;
-
-	if(ptrace(PTRACE_GETREGS, pid, 0, exec_regs) < 0)
-		panic("check_ptrace : PTRACE_GETREGS failed, errno = %d", 
-		      errno);
-
-	err = ptrace(PTRACE_GETFPXREGS, pid, 0, exec_fpx_regs);
-	if(!err)
-		return;
-
-	have_fpx_regs = 0;
-	if(errno != EIO)
-		panic("check_ptrace : PTRACE_GETFPXREGS failed, errno = %d", 
-		      errno);
-
-	err = ptrace(PTRACE_GETFPREGS, pid, 0, exec_fp_regs);
-	if(err)
-		panic("check_ptrace : PTRACE_GETFPREGS failed, errno = %d", 
-		      errno);
 }
 
 /*
diff -Nru a/arch/um/kernel/skas/process_kern.c b/arch/um/kernel/skas/process_kern.c
--- a/arch/um/kernel/skas/process_kern.c	2005-03-01 23:39:18 -08:00
+++ b/arch/um/kernel/skas/process_kern.c	2005-03-01 23:39:18 -08:00
@@ -19,10 +19,10 @@
 #include "os.h"
 #include "user_util.h"
 #include "tlb.h"
-#include "frame.h"
 #include "kern.h"
 #include "mode.h"
 #include "proc_mm.h"
+#include "registers.h"
 
 void *switch_to_skas(void *prev, void *next)
 {
@@ -119,12 +119,7 @@
 		handler = fork_handler;
 	}
 	else {
-	  	memcpy(p->thread.regs.regs.skas.regs, exec_regs, 
-		       sizeof(p->thread.regs.regs.skas.regs));
-		memcpy(p->thread.regs.regs.skas.fp, exec_fp_regs, 
-		       sizeof(p->thread.regs.regs.skas.fp));
-	  	memcpy(p->thread.regs.regs.skas.xfp, exec_fpx_regs, 
-		       sizeof(p->thread.regs.regs.skas.xfp));
+		init_thread_registers(&p->thread.regs.regs);
                 p->thread.request.u.thread = current->thread.request.u.thread;
 		handler = new_thread_handler;
 	}
@@ -183,7 +178,6 @@
 int start_uml_skas(void)
 {
 	start_userspace(0);
-	capture_signal_stack();
 
 	init_new_thread_signals(1);
 	uml_idle_timer();
diff -Nru a/arch/um/kernel/skas/sys-i386/Makefile b/arch/um/kernel/skas/sys-i386/Makefile
--- a/arch/um/kernel/skas/sys-i386/Makefile	2005-03-01 23:39:09 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,12 +0,0 @@
-# 
-# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
-# Licensed under the GPL
-#
-
-obj-y = sigcontext.o
-
-USER_OBJS = sigcontext.o
-USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
-
-$(USER_OBJS) : %.o: %.c
-	$(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
diff -Nru a/arch/um/kernel/skas/sys-i386/sigcontext.c b/arch/um/kernel/skas/sys-i386/sigcontext.c
--- a/arch/um/kernel/skas/sys-i386/sigcontext.c	2005-03-01 23:38:52 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,114 +0,0 @@
-/* 
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#include <errno.h>
-#include <asm/sigcontext.h>
-#include <sys/ptrace.h>
-#include <linux/ptrace.h>
-#include "sysdep/ptrace.h"
-#include "sysdep/ptrace_user.h"
-#include "kern_util.h"
-#include "user.h"
-#include "sigcontext.h"
-#include "mode.h"
-
-int copy_sc_from_user_skas(int pid, union uml_pt_regs *regs, void *from_ptr)
-{
-  	struct sigcontext sc, *from = from_ptr;
-	unsigned long fpregs[FP_FRAME_SIZE];
-	int err;
-
-	err = copy_from_user_proc(&sc, from, sizeof(sc));
-	err |= copy_from_user_proc(fpregs, sc.fpstate, sizeof(fpregs));
-	if(err)
-		return(err);
-
-	regs->skas.regs[GS] = sc.gs;
-	regs->skas.regs[FS] = sc.fs;
-	regs->skas.regs[ES] = sc.es;
-	regs->skas.regs[DS] = sc.ds;
-	regs->skas.regs[EDI] = sc.edi;
-	regs->skas.regs[ESI] = sc.esi;
-	regs->skas.regs[EBP] = sc.ebp;
-	regs->skas.regs[UESP] = sc.esp;
-	regs->skas.regs[EBX] = sc.ebx;
-	regs->skas.regs[EDX] = sc.edx;
-	regs->skas.regs[ECX] = sc.ecx;
-	regs->skas.regs[EAX] = sc.eax;
-	regs->skas.regs[EIP] = sc.eip;
-	regs->skas.regs[CS] = sc.cs;
-	regs->skas.regs[EFL] = sc.eflags;
-	regs->skas.regs[SS] = sc.ss;
-	regs->skas.fault_addr = sc.cr2;
-	regs->skas.fault_type = FAULT_WRITE(sc.err);
-	regs->skas.trap_type = sc.trapno;
-
-	err = ptrace(PTRACE_SETFPREGS, pid, 0, fpregs);
-	if(err < 0){
-	  	printk("copy_sc_to_user - PTRACE_SETFPREGS failed, "
-		       "errno = %d\n", errno);
-		return(1);
-	}
-
-	return(0);
-}
-
-int copy_sc_to_user_skas(int pid, void *to_ptr, void *fp,
-			 union uml_pt_regs *regs, unsigned long fault_addr,
-			 int fault_type)
-{
-  	struct sigcontext sc, *to = to_ptr;
-	struct _fpstate *to_fp;
-	unsigned long fpregs[FP_FRAME_SIZE];
-	int err;
-
-	sc.gs = regs->skas.regs[GS];
-	sc.fs = regs->skas.regs[FS];
-	sc.es = regs->skas.regs[ES];
-	sc.ds = regs->skas.regs[DS];
-	sc.edi = regs->skas.regs[EDI];
-	sc.esi = regs->skas.regs[ESI];
-	sc.ebp = regs->skas.regs[EBP];
-	sc.esp = regs->skas.regs[UESP];
-	sc.ebx = regs->skas.regs[EBX];
-	sc.edx = regs->skas.regs[EDX];
-	sc.ecx = regs->skas.regs[ECX];
-	sc.eax = regs->skas.regs[EAX];
-	sc.eip = regs->skas.regs[EIP];
-	sc.cs = regs->skas.regs[CS];
-	sc.eflags = regs->skas.regs[EFL];
-	sc.esp_at_signal = regs->skas.regs[UESP];
-	sc.ss = regs->skas.regs[SS];
-	sc.cr2 = fault_addr;
-	sc.err = TO_SC_ERR(fault_type);
-	sc.trapno = regs->skas.trap_type;
-
-	err = ptrace(PTRACE_GETFPREGS, pid, 0, fpregs);
-	if(err < 0){
-	  	printk("copy_sc_to_user - PTRACE_GETFPREGS failed, "
-		       "errno = %d\n", errno);
-		return(1);
-	}
-	to_fp = (struct _fpstate *) 
-		(fp ? (unsigned long) fp : ((unsigned long) to + sizeof(*to)));
-	sc.fpstate = to_fp;
-
-	if(err)
-	  	return(err);
-
-	return(copy_to_user_proc(to, &sc, sizeof(sc)) ||
-	       copy_to_user_proc(to_fp, fpregs, sizeof(fpregs)));
-}
-
-/*
- * 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 -Nru a/arch/um/kernel/skas/tlb.c b/arch/um/kernel/skas/tlb.c
--- a/arch/um/kernel/skas/tlb.c	2005-03-01 23:38:58 -08:00
+++ b/arch/um/kernel/skas/tlb.c	2005-03-01 23:38:58 -08:00
@@ -1,5 +1,6 @@
 /* 
  * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
+ * Copyright 2003 PathScale, Inc.
  * Licensed under the GPL
  */
 
@@ -18,52 +19,86 @@
 		      unsigned long end_addr, int force)
 {
 	pgd_t *npgd;
+	pud_t *npud;
 	pmd_t *npmd;
 	pte_t *npte;
-	unsigned long addr;
+	unsigned long addr,  end;
 	int r, w, x, err, fd;
 
 	if(mm == NULL) return;
 	fd = mm->context.skas.mm_fd;
 	for(addr = start_addr; addr < end_addr;){
 		npgd = pgd_offset(mm, addr);
-		npmd = pmd_offset(npgd, addr);
-		if(pmd_present(*npmd)){
-			npte = pte_offset_kernel(npmd, addr);
-			r = pte_read(*npte);
-			w = pte_write(*npte);
-			x = pte_exec(*npte);
-			if(!pte_dirty(*npte)) w = 0;
-			if(!pte_young(*npte)){
-				r = 0;
-				w = 0;
-			}
-			if(force || pte_newpage(*npte)){
-				err = unmap(fd, (void *) addr, PAGE_SIZE);
+		if(!pgd_present(*npgd)){
+			if(force || pgd_newpage(*npgd)){
+				end = addr + PGDIR_SIZE;
+				if(end > end_addr)
+					end = end_addr;
+				err = unmap(fd, (void *) addr, end - addr);
 				if(err < 0)
 					panic("munmap failed, errno = %d\n",
 					      -err);
-				if(pte_present(*npte))
-					map(fd, addr, 
-					    pte_val(*npte) & PAGE_MASK,
-					    PAGE_SIZE, r, w, x);
+				pgd_mkuptodate(*npgd);
 			}
-			else if(pte_newprot(*npte)){
-				protect(fd, addr, PAGE_SIZE, r, w, x, 1);
+			addr += PGDIR_SIZE;
+			continue;
+		}
+
+		npud = pud_offset(npgd, addr);
+		if(!pud_present(*npud)){
+			if(force || pud_newpage(*npud)){
+				end = addr + PUD_SIZE;
+				if(end > end_addr)
+					end = end_addr;
+				err = unmap(fd, (void *) addr, end - addr);
+				if(err < 0)
+					panic("munmap failed, errno = %d\n",
+					      -err);
+				pud_mkuptodate(*npud);
 			}
-			*npte = pte_mkuptodate(*npte);
-			addr += PAGE_SIZE;
+			addr += PUD_SIZE;
+			continue;
 		}
-		else {
+
+		npmd = pmd_offset(npud, addr);
+		if(!pmd_present(*npmd)){
 			if(force || pmd_newpage(*npmd)){
-				err = unmap(fd, (void *) addr, PMD_SIZE);
+				end = addr + PMD_SIZE;
+				if(end > end_addr)
+					end = end_addr;
+				err = unmap(fd, (void *) addr, end - addr);
 				if(err < 0)
 					panic("munmap failed, errno = %d\n",
 					      -err);
 				pmd_mkuptodate(*npmd);
 			}
 			addr += PMD_SIZE;
+			continue;
+		}
+
+		npte = pte_offset_kernel(npmd, addr);
+		r = pte_read(*npte);
+		w = pte_write(*npte);
+		x = pte_exec(*npte);
+		if(!pte_dirty(*npte))
+			w = 0;
+		if(!pte_young(*npte)){
+			r = 0;
+			w = 0;
+		}
+		if(force || pte_newpage(*npte)){
+			err = unmap(fd, (void *) addr, PAGE_SIZE);
+			if(err < 0)
+				panic("munmap failed, errno = %d\n", -err);
+			if(pte_present(*npte))
+				map(fd, addr, pte_val(*npte) & PAGE_MASK,
+				    PAGE_SIZE, r, w, x);
 		}
+		else if(pte_newprot(*npte))
+			protect(fd, addr, PAGE_SIZE, r, w, x, 1);
+
+		*npte = pte_mkuptodate(*npte);
+		addr += PAGE_SIZE;
 	}
 }
 
@@ -71,45 +106,82 @@
 {
 	struct mm_struct *mm;
 	pgd_t *pgd;
+	pud_t *pud;
 	pmd_t *pmd;
 	pte_t *pte;
-	unsigned long addr;
+	unsigned long addr, last;
 	int updated = 0, err;
 
 	mm = &init_mm;
 	for(addr = start; addr < end;){
 		pgd = pgd_offset(mm, addr);
-		pmd = pmd_offset(pgd, addr);
-		if(pmd_present(*pmd)){
-			pte = pte_offset_kernel(pmd, addr);
-			if(!pte_present(*pte) || pte_newpage(*pte)){
+		pud = pud_offset(pgd, addr);
+		pmd = pmd_offset(pud, addr);
+ 		if(!pgd_present(*pgd)){
+			if(pgd_newpage(*pgd)){
 				updated = 1;
+				last = addr + PGDIR_SIZE;
+				if(last > end)
+					last = end;
 				err = os_unmap_memory((void *) addr, 
-						      PAGE_SIZE);
+						      last - addr);
 				if(err < 0)
 					panic("munmap failed, errno = %d\n",
 					      -err);
-				if(pte_present(*pte))
-					map_memory(addr, 
-						   pte_val(*pte) & PAGE_MASK,
-						   PAGE_SIZE, 1, 1, 1);
 			}
-			else if(pte_newprot(*pte)){
+			addr += PGDIR_SIZE;
+			continue;
+		}
+
+		pud = pud_offset(pgd, addr);
+		if(!pud_present(*pud)){
+			if(pud_newpage(*pud)){
 				updated = 1;
-				protect_memory(addr, PAGE_SIZE, 1, 1, 1, 1);
+				last = addr + PUD_SIZE;
+				if(last > end)
+					last = end;
+				err = os_unmap_memory((void *) addr,
+						      last - addr);
+				if(err < 0)
+					panic("munmap failed, errno = %d\n",
+					      -err);
 			}
-			addr += PAGE_SIZE;
+			addr += PUD_SIZE;
+			continue;
 		}
-		else {
+
+		pmd = pmd_offset(pud, addr);
+		if(!pmd_present(*pmd)){
 			if(pmd_newpage(*pmd)){
 				updated = 1;
-				err = os_unmap_memory((void *) addr, PMD_SIZE);
+				last = addr + PMD_SIZE;
+				if(last > end)
+					last = end;
+				err = os_unmap_memory((void *) addr,
+						      last - addr);
 				if(err < 0)
 					panic("munmap failed, errno = %d\n",
 					      -err);
 			}
 			addr += PMD_SIZE;
+			continue;
+		}
+
+		pte = pte_offset_kernel(pmd, addr);
+		if(!pte_present(*pte) || pte_newpage(*pte)){
+			updated = 1;
+			err = os_unmap_memory((void *) addr, PAGE_SIZE);
+			if(err < 0)
+				panic("munmap failed, errno = %d\n", -err);
+			if(pte_present(*pte))
+				map_memory(addr, pte_val(*pte) & PAGE_MASK,
+					   PAGE_SIZE, 1, 1, 1);
 		}
+		else if(pte_newprot(*pte)){
+			updated = 1;
+			protect_memory(addr, PAGE_SIZE, 1, 1, 1, 1);
+  		}
+		addr += PAGE_SIZE;
 	}
 }
 
diff -Nru a/arch/um/kernel/skas/trap_user.c b/arch/um/kernel/skas/trap_user.c
--- a/arch/um/kernel/skas/trap_user.c	2005-03-01 23:38:56 -08:00
+++ b/arch/um/kernel/skas/trap_user.c	2005-03-01 23:38:56 -08:00
@@ -5,7 +5,6 @@
 
 #include <signal.h>
 #include <errno.h>
-#include <asm/sigcontext.h>
 #include "sysdep/ptrace.h"
 #include "signal_user.h"
 #include "user_util.h"
@@ -20,6 +19,14 @@
 	struct signal_info *info;
 	int save_errno = errno;
 	int save_user;
+
+	/* This is done because to allow SIGSEGV to be delivered inside a SEGV
+	 * handler.  This can happen in copy_user, and if SEGV is disabled,
+	 * the process will die.
+	 * XXX Figure out why this is better than SA_NODEFER
+	 */
+	if(sig == SIGSEGV)
+		change_sig(SIGSEGV, 1);
 
 	r = &TASK_REGS(get_current())->skas;
 	save_user = r->is_user;
diff -Nru a/arch/um/kernel/skas/uaccess.c b/arch/um/kernel/skas/uaccess.c
--- a/arch/um/kernel/skas/uaccess.c	2005-03-01 23:39:17 -08:00
+++ b/arch/um/kernel/skas/uaccess.c	2005-03-01 23:39:17 -08:00
@@ -54,15 +54,23 @@
 
 static void do_buffer_op(void *jmpbuf, void *arg_ptr)
 {
-	va_list args = *((va_list *) arg_ptr);
-	unsigned long addr = va_arg(args, unsigned long);
-	int len = va_arg(args, int);
-	int is_write = va_arg(args, int);
-	int (*op)(unsigned long, int, void *) = va_arg(args, void *);
-	void *arg = va_arg(args, void *);
-	int *res = va_arg(args, int *);
-	int size = min(PAGE_ALIGN(addr) - addr, (unsigned long) len);
-	int remain = len, n;
+	va_list args;
+	unsigned long addr;
+	int len, is_write, size, remain, n;
+	int (*op)(unsigned long, int, void *);
+	void *arg;
+	int *res;
+
+	va_copy(args, *(va_list *)arg_ptr);
+	addr = va_arg(args, unsigned long);
+	len = va_arg(args, int);
+	is_write = va_arg(args, int);
+	op = va_arg(args, void *);
+	arg = va_arg(args, void *);
+	res = va_arg(args, int *);
+	va_end(args);
+	size = min(PAGE_ALIGN(addr) - addr, (unsigned long) len);
+	remain = len;
 
 	current->thread.fault_catcher = jmpbuf;
 	n = do_op(addr, size, is_write, op, arg);
@@ -124,10 +132,10 @@
 	return(0);
 }
 
-int copy_from_user_skas(void *to, const void *from, int n)
+int copy_from_user_skas(void *to, const void __user *from, int n)
 {
 	if(segment_eq(get_fs(), KERNEL_DS)){
-		memcpy(to, from, n);
+		memcpy(to, (__force void*)from, n);
 		return(0);
 	}
 
@@ -145,10 +153,10 @@
 	return(0);
 }
 
-int copy_to_user_skas(void *to, const void *from, int n)
+int copy_to_user_skas(void __user *to, const void *from, int n)
 {
 	if(segment_eq(get_fs(), KERNEL_DS)){
-		memcpy(to, from, n);
+		memcpy((__force void*)to, from, n);
 		return(0);
 	}
 
@@ -171,13 +179,13 @@
 	return(0);
 }
 
-int strncpy_from_user_skas(char *dst, const char *src, int count)
+int strncpy_from_user_skas(char *dst, const char __user *src, int count)
 {
 	int n;
 	char *ptr = dst;
 
 	if(segment_eq(get_fs(), KERNEL_DS)){
-		strncpy(dst, src, count);
+		strncpy(dst, (__force void*)src, count);
 		return(strnlen(dst, count));
 	}
 
@@ -197,15 +205,15 @@
 	return(0);
 }
 
-int __clear_user_skas(void *mem, int len)
+int __clear_user_skas(void __user *mem, int len)
 {
 	return(buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL));
 }
 
-int clear_user_skas(void *mem, int len)
+int clear_user_skas(void __user *mem, int len)
 {
 	if(segment_eq(get_fs(), KERNEL_DS)){
-		memset(mem, 0, len);
+		memset((__force void*)mem, 0, len);
 		return(0);
 	}
 
@@ -225,12 +233,12 @@
 	return(0);
 }
 
-int strnlen_user_skas(const void *str, int len)
+int strnlen_user_skas(const void __user *str, int len)
 {
 	int count = 0, n;
 
 	if(segment_eq(get_fs(), KERNEL_DS))
-		return(strnlen(str, len) + 1);
+		return(strnlen((__force char*)str, len) + 1);
 
 	n = buffer_op((unsigned long) str, len, 0, strnlen_chunk, &count);
 	if(n == 0)
diff -Nru a/arch/um/kernel/skas/util/Makefile b/arch/um/kernel/skas/util/Makefile
--- a/arch/um/kernel/skas/util/Makefile	2005-03-01 23:39:09 -08:00
+++ b/arch/um/kernel/skas/util/Makefile	2005-03-01 23:39:09 -08:00
@@ -1,2 +1,4 @@
 hostprogs-y		:= mk_ptregs
 always			:= $(hostprogs-y)
+
+mk_ptregs-objs := mk_ptregs-$(SUBARCH).o
diff -Nru a/arch/um/kernel/skas/util/mk_ptregs-i386.c b/arch/um/kernel/skas/util/mk_ptregs-i386.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/um/kernel/skas/util/mk_ptregs-i386.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,51 @@
+#include <stdio.h>
+#include <asm/ptrace.h>
+#include <asm/user.h>
+
+#define PRINT_REG(name, val) printf("#define HOST_%s %d\n", (name), (val))
+
+int main(int argc, char **argv)
+{
+	printf("/* Automatically generated by "
+	       "arch/um/kernel/skas/util/mk_ptregs */\n");
+	printf("\n");
+	printf("#ifndef __SKAS_PT_REGS_\n");
+	printf("#define __SKAS_PT_REGS_\n");
+	printf("\n");
+	printf("#define HOST_FRAME_SIZE %d\n", FRAME_SIZE);
+	printf("#define HOST_FP_SIZE %d\n",
+	       sizeof(struct user_i387_struct) / sizeof(unsigned long));
+	printf("#define HOST_XFP_SIZE %d\n",
+	       sizeof(struct user_fxsr_struct) / sizeof(unsigned long));
+
+	PRINT_REG("IP", EIP);
+	PRINT_REG("SP", UESP);
+	PRINT_REG("EFLAGS", EFL);
+	PRINT_REG("EAX", EAX);
+	PRINT_REG("EBX", EBX);
+	PRINT_REG("ECX", ECX);
+	PRINT_REG("EDX", EDX);
+	PRINT_REG("ESI", ESI);
+	PRINT_REG("EDI", EDI);
+	PRINT_REG("EBP", EBP);
+	PRINT_REG("CS", CS);
+	PRINT_REG("SS", SS);
+	PRINT_REG("DS", DS);
+	PRINT_REG("FS", FS);
+	PRINT_REG("ES", ES);
+	PRINT_REG("GS", GS);
+	printf("\n");
+	printf("#endif\n");
+	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 -Nru a/arch/um/kernel/skas/util/mk_ptregs-x86_64.c b/arch/um/kernel/skas/util/mk_ptregs-x86_64.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/um/kernel/skas/util/mk_ptregs-x86_64.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2003 PathScale, Inc.
+ *
+ * Licensed under the GPL
+ */
+
+#include <stdio.h>
+#define __FRAME_OFFSETS
+#include <asm/ptrace.h>
+
+#define PRINT_REG(name, val) \
+	printf("#define HOST_%s (%d / sizeof(unsigned long))\n", (name), (val))
+
+int main(int argc, char **argv)
+{
+	printf("/* Automatically generated by "
+	       "arch/um/kernel/skas/util/mk_ptregs */\n");
+	printf("\n");
+	printf("#ifndef __SKAS_PT_REGS_\n");
+	printf("#define __SKAS_PT_REGS_\n");
+	printf("#define HOST_FRAME_SIZE (%d / sizeof(unsigned long))\n",
+	       FRAME_SIZE);
+	PRINT_REG("RBX", RBX);
+	PRINT_REG("RCX", RCX);
+	PRINT_REG("RDI", RDI);
+	PRINT_REG("RSI", RSI);
+	PRINT_REG("RDX", RDX);
+	PRINT_REG("RBP", RBP);
+	PRINT_REG("RAX", RAX);
+	PRINT_REG("R8", R8);
+	PRINT_REG("R9", R9);
+	PRINT_REG("R10", R10);
+	PRINT_REG("R11", R11);
+	PRINT_REG("R12", R12);
+	PRINT_REG("R13", R13);
+	PRINT_REG("R14", R14);
+	PRINT_REG("R15", R15);
+	PRINT_REG("ORIG_RAX", ORIG_RAX);
+	PRINT_REG("CS", CS);
+	PRINT_REG("SS", SS);
+	PRINT_REG("EFLAGS", EFLAGS);
+#if 0
+	PRINT_REG("FS", FS);
+	PRINT_REG("GS", GS);
+	PRINT_REG("DS", DS);
+	PRINT_REG("ES", ES);
+#endif
+
+	PRINT_REG("IP", RIP);
+	PRINT_REG("SP", RSP);
+	printf("#define HOST_FP_SIZE 0\n");
+	printf("#define HOST_XFP_SIZE 0\n");
+	printf("\n");
+	printf("\n");
+	printf("#endif\n");
+	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 -Nru a/arch/um/kernel/skas/util/mk_ptregs.c b/arch/um/kernel/skas/util/mk_ptregs.c
--- a/arch/um/kernel/skas/util/mk_ptregs.c	2005-03-01 23:38:56 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,51 +0,0 @@
-#include <stdio.h>
-#include <asm/ptrace.h>
-#include <asm/user.h>
-
-#define PRINT_REG(name, val) printf("#define HOST_%s %d\n", (name), (val))
-
-int main(int argc, char **argv)
-{
-	printf("/* Automatically generated by "
-	       "arch/um/kernel/skas/util/mk_ptregs */\n");
-	printf("\n");
-	printf("#ifndef __SKAS_PT_REGS_\n");
-	printf("#define __SKAS_PT_REGS_\n");
-	printf("\n");
-	printf("#define HOST_FRAME_SIZE %d\n", FRAME_SIZE);
-	printf("#define HOST_FP_SIZE %d\n", 
-	       sizeof(struct user_i387_struct) / sizeof(unsigned long));
-	printf("#define HOST_XFP_SIZE %d\n", 
-	       sizeof(struct user_fxsr_struct) / sizeof(unsigned long));
-
-	PRINT_REG("IP", EIP);
-	PRINT_REG("SP", UESP);
-	PRINT_REG("EFLAGS", EFL);
-	PRINT_REG("EAX", EAX);
-	PRINT_REG("EBX", EBX);
-	PRINT_REG("ECX", ECX);
-	PRINT_REG("EDX", EDX);
-	PRINT_REG("ESI", ESI);
-	PRINT_REG("EDI", EDI);
-	PRINT_REG("EBP", EBP);
-	PRINT_REG("CS", CS);
-	PRINT_REG("SS", SS);
-	PRINT_REG("DS", DS);
-	PRINT_REG("FS", FS);
-	PRINT_REG("ES", ES);
-	PRINT_REG("GS", GS);
-	printf("\n");
-	printf("#endif\n");
-	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 -Nru a/arch/um/kernel/smp.c b/arch/um/kernel/smp.c
--- a/arch/um/kernel/smp.c	2005-03-01 23:39:18 -08:00
+++ b/arch/um/kernel/smp.c	2005-03-01 23:39:18 -08:00
@@ -216,7 +216,7 @@
 	return(pid_to_processor_id(os_getpid()));
 }
 
-static spinlock_t call_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(call_lock);
 static atomic_t scf_started;
 static atomic_t scf_finished;
 static void (*func)(void *info);
@@ -247,10 +247,8 @@
 	func = _func;
 	info = _info;
 
-	for (i=0;i<NR_CPUS;i++)
-		if((i != current_thread->cpu) &&
-		   cpu_isset(i, cpu_online_map))
-			os_write_file(cpu_data[i].ipi_pipe[1], "C", 1);
+	for_each_online_cpu(i)
+		os_write_file(cpu_data[i].ipi_pipe[1], "C", 1);
 
 	while (atomic_read(&scf_started) != cpus)
 		barrier();
diff -Nru a/arch/um/kernel/sys_call_table.c b/arch/um/kernel/sys_call_table.c
--- a/arch/um/kernel/sys_call_table.c	2005-03-01 23:39:09 -08:00
+++ b/arch/um/kernel/sys_call_table.c	2005-03-01 23:39:09 -08:00
@@ -1,5 +1,6 @@
 /* 
  * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
+ * Copyright 2003 PathScale, Inc.
  * Licensed under the GPL
  */
 
@@ -19,7 +20,7 @@
 #define NFSSERVCTL sys_ni_syscall
 #endif
 
-#define LAST_GENERIC_SYSCALL __NR_vserver
+#define LAST_GENERIC_SYSCALL __NR_keyctl
 
 #if LAST_GENERIC_SYSCALL > LAST_ARCH_SYSCALL
 #define LAST_SYSCALL LAST_GENERIC_SYSCALL
@@ -32,7 +33,6 @@
 extern syscall_handler_t um_time;
 extern syscall_handler_t um_mount;
 extern syscall_handler_t um_stime;
-extern syscall_handler_t sys_ptrace;
 extern syscall_handler_t sys_pipe;
 extern syscall_handler_t sys_olduname;
 extern syscall_handler_t sys_sigaction;
@@ -43,282 +43,238 @@
 extern syscall_handler_t sys_sigreturn;
 extern syscall_handler_t sys_clone;
 extern syscall_handler_t sys_rt_sigreturn;
-extern syscall_handler_t sys_rt_sigaction;
 extern syscall_handler_t sys_sigaltstack;
 extern syscall_handler_t sys_vfork;
-extern syscall_handler_t sys_mmap2;
-extern syscall_handler_t old_mmap_i386;
 extern syscall_handler_t old_select;
 extern syscall_handler_t sys_modify_ldt;
 extern syscall_handler_t sys_rt_sigsuspend;
+extern syscall_handler_t sys_vserver;
+extern syscall_handler_t sys_mbind;
+extern syscall_handler_t sys_get_mempolicy;
+extern syscall_handler_t sys_set_mempolicy;
+extern syscall_handler_t sys_sys_setaltroot;
 
 syscall_handler_t *sys_call_table[] = {
 	[ __NR_restart_syscall ] = (syscall_handler_t *) sys_restart_syscall,
-	[ __NR_exit ] (syscall_handler_t *) sys_exit,
-	[ __NR_fork ] (syscall_handler_t *) sys_fork,
+	[ __NR_exit ] = (syscall_handler_t *) sys_exit,
+	[ __NR_fork ] = (syscall_handler_t *) sys_fork,
 	[ __NR_read ] = (syscall_handler_t *) sys_read,
 	[ __NR_write ] = (syscall_handler_t *) sys_write,
 
 	/* These three are declared differently in asm/unistd.h */
 	[ __NR_open ] = (syscall_handler_t *) sys_open,
 	[ __NR_close ] = (syscall_handler_t *) sys_close,
-	[ __NR_waitpid ] = (syscall_handler_t *) sys_waitpid,
-	[ __NR_creat ] (syscall_handler_t *) sys_creat,
-	[ __NR_link ] (syscall_handler_t *) sys_link,
-	[ __NR_unlink ] (syscall_handler_t *) sys_unlink,
+	[ __NR_creat ] = (syscall_handler_t *) sys_creat,
+	[ __NR_link ] = (syscall_handler_t *) sys_link,
+	[ __NR_unlink ] = (syscall_handler_t *) sys_unlink,
 	[ __NR_execve ] = (syscall_handler_t *) sys_execve,
 
 	/* declared differently in kern_util.h */
-	[ __NR_chdir ] (syscall_handler_t *) sys_chdir,
+	[ __NR_chdir ] = (syscall_handler_t *) sys_chdir,
 	[ __NR_time ] = um_time,
-	[ __NR_mknod ] (syscall_handler_t *) sys_mknod,
-	[ __NR_chmod ] (syscall_handler_t *) sys_chmod,
-	[ __NR_lchown ] (syscall_handler_t *) sys_lchown16,
-	[ __NR_break ] (syscall_handler_t *) sys_ni_syscall,
-	[ __NR_oldstat ] (syscall_handler_t *) sys_stat,
+	[ __NR_mknod ] = (syscall_handler_t *) sys_mknod,
+	[ __NR_chmod ] = (syscall_handler_t *) sys_chmod,
+	[ __NR_lchown ] = (syscall_handler_t *) sys_lchown16,
 	[ __NR_lseek ] = (syscall_handler_t *) sys_lseek,
-	[ __NR_getpid ] (syscall_handler_t *) sys_getpid,
+	[ __NR_getpid ] = (syscall_handler_t *) sys_getpid,
 	[ __NR_mount ] = um_mount,
-	[ __NR_umount ] (syscall_handler_t *) sys_oldumount,
-	[ __NR_setuid ] (syscall_handler_t *) sys_setuid16,
-	[ __NR_getuid ] (syscall_handler_t *) sys_getuid16,
-	[ __NR_stime ] = um_stime,
-	[ __NR_ptrace ] (syscall_handler_t *) sys_ptrace,
-	[ __NR_alarm ] (syscall_handler_t *) sys_alarm,
-	[ __NR_oldfstat ] (syscall_handler_t *) sys_fstat,
-	[ __NR_pause ] (syscall_handler_t *) sys_pause,
-	[ __NR_utime ] (syscall_handler_t *) sys_utime,
-	[ __NR_stty ] (syscall_handler_t *) sys_ni_syscall,
-	[ __NR_gtty ] (syscall_handler_t *) sys_ni_syscall,
-	[ __NR_access ] (syscall_handler_t *) sys_access,
-	[ __NR_nice ] (syscall_handler_t *) sys_nice,
-	[ __NR_ftime ] (syscall_handler_t *) sys_ni_syscall,
-	[ __NR_sync ] (syscall_handler_t *) sys_sync,
-	[ __NR_kill ] (syscall_handler_t *) sys_kill,
-	[ __NR_rename ] (syscall_handler_t *) sys_rename,
-	[ __NR_mkdir ] (syscall_handler_t *) sys_mkdir,
-	[ __NR_rmdir ] (syscall_handler_t *) sys_rmdir,
+	[ __NR_setuid ] = (syscall_handler_t *) sys_setuid16,
+	[ __NR_getuid ] = (syscall_handler_t *) sys_getuid16,
+ 	[ __NR_ptrace ] = (syscall_handler_t *) sys_ptrace,
+	[ __NR_alarm ] = (syscall_handler_t *) sys_alarm,
+	[ __NR_pause ] = (syscall_handler_t *) sys_pause,
+	[ __NR_utime ] = (syscall_handler_t *) sys_utime,
+	[ __NR_access ] = (syscall_handler_t *) sys_access,
+	[ __NR_sync ] = (syscall_handler_t *) sys_sync,
+	[ __NR_kill ] = (syscall_handler_t *) sys_kill,
+	[ __NR_rename ] = (syscall_handler_t *) sys_rename,
+	[ __NR_mkdir ] = (syscall_handler_t *) sys_mkdir,
+	[ __NR_rmdir ] = (syscall_handler_t *) sys_rmdir,
 
 	/* Declared differently in asm/unistd.h */
 	[ __NR_dup ] = (syscall_handler_t *) sys_dup,
-	[ __NR_pipe ] (syscall_handler_t *) sys_pipe,
-	[ __NR_times ] (syscall_handler_t *) sys_times,
-	[ __NR_prof ] (syscall_handler_t *) sys_ni_syscall,
-	[ __NR_brk ] (syscall_handler_t *) sys_brk,
-	[ __NR_setgid ] (syscall_handler_t *) sys_setgid16,
-	[ __NR_getgid ] (syscall_handler_t *) sys_getgid16,
-	[ __NR_signal ] (syscall_handler_t *) sys_signal,
-	[ __NR_geteuid ] (syscall_handler_t *) sys_geteuid16,
-	[ __NR_getegid ] (syscall_handler_t *) sys_getegid16,
-	[ __NR_acct ] (syscall_handler_t *) sys_acct,
-	[ __NR_umount2 ] (syscall_handler_t *) sys_umount,
-	[ __NR_lock ] (syscall_handler_t *) sys_ni_syscall,
-	[ __NR_ioctl ] (syscall_handler_t *) sys_ioctl,
-	[ __NR_fcntl ] (syscall_handler_t *) sys_fcntl,
-	[ __NR_mpx ] (syscall_handler_t *) sys_ni_syscall,
-	[ __NR_setpgid ] (syscall_handler_t *) sys_setpgid,
-	[ __NR_ulimit ] (syscall_handler_t *) sys_ni_syscall,
-	[ __NR_oldolduname ] (syscall_handler_t *) sys_olduname,
-	[ __NR_umask ] (syscall_handler_t *) sys_umask,
-	[ __NR_chroot ] (syscall_handler_t *) sys_chroot,
-	[ __NR_ustat ] (syscall_handler_t *) sys_ustat,
-	[ __NR_dup2 ] (syscall_handler_t *) sys_dup2,
-	[ __NR_getppid ] (syscall_handler_t *) sys_getppid,
-	[ __NR_getpgrp ] (syscall_handler_t *) sys_getpgrp,
+	[ __NR_pipe ] = (syscall_handler_t *) sys_pipe,
+	[ __NR_times ] = (syscall_handler_t *) sys_times,
+	[ __NR_brk ] = (syscall_handler_t *) sys_brk,
+	[ __NR_setgid ] = (syscall_handler_t *) sys_setgid16,
+	[ __NR_getgid ] = (syscall_handler_t *) sys_getgid16,
+	[ __NR_geteuid ] = (syscall_handler_t *) sys_geteuid16,
+	[ __NR_getegid ] = (syscall_handler_t *) sys_getegid16,
+	[ __NR_acct ] = (syscall_handler_t *) sys_acct,
+	[ __NR_umount2 ] = (syscall_handler_t *) sys_umount,
+	[ __NR_ioctl ] = (syscall_handler_t *) sys_ioctl,
+	[ __NR_fcntl ] = (syscall_handler_t *) sys_fcntl,
+	[ __NR_setpgid ] = (syscall_handler_t *) sys_setpgid,
+	[ __NR_umask ] = (syscall_handler_t *) sys_umask,
+	[ __NR_chroot ] = (syscall_handler_t *) sys_chroot,
+	[ __NR_ustat ] = (syscall_handler_t *) sys_ustat,
+	[ __NR_dup2 ] = (syscall_handler_t *) sys_dup2,
+	[ __NR_getppid ] = (syscall_handler_t *) sys_getppid,
+	[ __NR_getpgrp ] = (syscall_handler_t *) sys_getpgrp,
 	[ __NR_setsid ] = (syscall_handler_t *) sys_setsid,
-	[ __NR_sigaction ] (syscall_handler_t *) sys_sigaction,
-	[ __NR_sgetmask ] (syscall_handler_t *) sys_sgetmask,
-	[ __NR_ssetmask ] (syscall_handler_t *) sys_ssetmask,
-	[ __NR_setreuid ] (syscall_handler_t *) sys_setreuid16,
-	[ __NR_setregid ] (syscall_handler_t *) sys_setregid16,
-	[ __NR_sigsuspend ] (syscall_handler_t *) sys_sigsuspend,
-	[ __NR_sigpending ] (syscall_handler_t *) sys_sigpending,
-	[ __NR_sethostname ] (syscall_handler_t *) sys_sethostname,
-	[ __NR_setrlimit ] (syscall_handler_t *) sys_setrlimit,
-	[ __NR_getrlimit ] (syscall_handler_t *) sys_old_getrlimit,
-	[ __NR_getrusage ] (syscall_handler_t *) sys_getrusage,
-	[ __NR_gettimeofday ] (syscall_handler_t *) sys_gettimeofday,
-	[ __NR_settimeofday ] (syscall_handler_t *) sys_settimeofday,
-	[ __NR_getgroups ] (syscall_handler_t *) sys_getgroups16,
-	[ __NR_setgroups ] (syscall_handler_t *) sys_setgroups16,
-	[ __NR_symlink ] (syscall_handler_t *) sys_symlink,
-	[ __NR_oldlstat ] (syscall_handler_t *) sys_lstat,
-	[ __NR_readlink ] (syscall_handler_t *) sys_readlink,
-	[ __NR_uselib ] (syscall_handler_t *) sys_uselib,
+	[ __NR_setreuid ] = (syscall_handler_t *) sys_setreuid16,
+	[ __NR_setregid ] = (syscall_handler_t *) sys_setregid16,
+	[ __NR_sethostname ] = (syscall_handler_t *) sys_sethostname,
+	[ __NR_setrlimit ] = (syscall_handler_t *) sys_setrlimit,
+	[ __NR_getrlimit ] = (syscall_handler_t *) sys_old_getrlimit,
+	[ __NR_getrusage ] = (syscall_handler_t *) sys_getrusage,
+	[ __NR_gettimeofday ] = (syscall_handler_t *) sys_gettimeofday,
+	[ __NR_settimeofday ] = (syscall_handler_t *) sys_settimeofday,
+	[ __NR_getgroups ] = (syscall_handler_t *) sys_getgroups16,
+	[ __NR_setgroups ] = (syscall_handler_t *) sys_setgroups16,
+	[ __NR_symlink ] = (syscall_handler_t *) sys_symlink,
+	[ __NR_readlink ] = (syscall_handler_t *) sys_readlink,
+	[ __NR_uselib ] = (syscall_handler_t *) sys_uselib,
 	[ __NR_swapon ] = (syscall_handler_t *) sys_swapon,
-	[ __NR_reboot ] (syscall_handler_t *) sys_reboot,
-	[ __NR_readdir ] = old_readdir,
-	[ __NR_munmap ] (syscall_handler_t *) sys_munmap,
-	[ __NR_truncate ] (syscall_handler_t *) sys_truncate,
-	[ __NR_ftruncate ] (syscall_handler_t *) sys_ftruncate,
-	[ __NR_fchmod ] (syscall_handler_t *) sys_fchmod,
-	[ __NR_fchown ] (syscall_handler_t *) sys_fchown16,
-	[ __NR_getpriority ] (syscall_handler_t *) sys_getpriority,
-	[ __NR_setpriority ] (syscall_handler_t *) sys_setpriority,
-	[ __NR_profil ] (syscall_handler_t *) sys_ni_syscall,
-	[ __NR_statfs ] (syscall_handler_t *) sys_statfs,
-	[ __NR_fstatfs ] (syscall_handler_t *) sys_fstatfs,
-	[ __NR_ioperm ] (syscall_handler_t *) sys_ni_syscall,
-	[ __NR_socketcall ] (syscall_handler_t *) sys_socketcall,
-	[ __NR_syslog ] (syscall_handler_t *) sys_syslog,
-	[ __NR_setitimer ] (syscall_handler_t *) sys_setitimer,
-	[ __NR_getitimer ] (syscall_handler_t *) sys_getitimer,
-	[ __NR_stat ] (syscall_handler_t *) sys_newstat,
-	[ __NR_lstat ] (syscall_handler_t *) sys_newlstat,
-	[ __NR_fstat ] (syscall_handler_t *) sys_newfstat,
-	[ __NR_olduname ] (syscall_handler_t *) sys_uname,
-	[ __NR_iopl ] (syscall_handler_t *) sys_ni_syscall,
-	[ __NR_vhangup ] (syscall_handler_t *) sys_vhangup,
-	[ __NR_idle ] (syscall_handler_t *) sys_ni_syscall,
+	[ __NR_reboot ] = (syscall_handler_t *) sys_reboot,
+	[ __NR_munmap ] = (syscall_handler_t *) sys_munmap,
+	[ __NR_truncate ] = (syscall_handler_t *) sys_truncate,
+	[ __NR_ftruncate ] = (syscall_handler_t *) sys_ftruncate,
+	[ __NR_fchmod ] = (syscall_handler_t *) sys_fchmod,
+	[ __NR_fchown ] = (syscall_handler_t *) sys_fchown16,
+	[ __NR_getpriority ] = (syscall_handler_t *) sys_getpriority,
+	[ __NR_setpriority ] = (syscall_handler_t *) sys_setpriority,
+	[ __NR_statfs ] = (syscall_handler_t *) sys_statfs,
+	[ __NR_fstatfs ] = (syscall_handler_t *) sys_fstatfs,
+	[ __NR_ioperm ] = (syscall_handler_t *) sys_ni_syscall,
+	[ __NR_syslog ] = (syscall_handler_t *) sys_syslog,
+	[ __NR_setitimer ] = (syscall_handler_t *) sys_setitimer,
+	[ __NR_getitimer ] = (syscall_handler_t *) sys_getitimer,
+	[ __NR_stat ] = (syscall_handler_t *) sys_newstat,
+	[ __NR_lstat ] = (syscall_handler_t *) sys_newlstat,
+	[ __NR_fstat ] = (syscall_handler_t *) sys_newfstat,
+	[ __NR_vhangup ] = (syscall_handler_t *) sys_vhangup,
 	[ __NR_wait4 ] = (syscall_handler_t *) sys_wait4,
 	[ __NR_swapoff ] = (syscall_handler_t *) sys_swapoff,
-	[ __NR_sysinfo ] (syscall_handler_t *) sys_sysinfo,
-	[ __NR_ipc ] (syscall_handler_t *) sys_ipc,
-	[ __NR_fsync ] (syscall_handler_t *) sys_fsync,
-	[ __NR_sigreturn ] (syscall_handler_t *) sys_sigreturn,
-	[ __NR_clone ] (syscall_handler_t *) sys_clone,
-	[ __NR_setdomainname ] (syscall_handler_t *) sys_setdomainname,
-	[ __NR_uname ] (syscall_handler_t *) sys_newuname,
-	[ __NR_adjtimex ] (syscall_handler_t *) sys_adjtimex,
-	[ __NR_mprotect ] (syscall_handler_t *) sys_mprotect,
-	[ __NR_sigprocmask ] (syscall_handler_t *) sys_sigprocmask,
-	[ __NR_create_module ] (syscall_handler_t *) sys_ni_syscall,
-	[ __NR_init_module ] (syscall_handler_t *) sys_init_module,
-	[ __NR_delete_module ] (syscall_handler_t *) sys_delete_module,
-	[ __NR_get_kernel_syms ] (syscall_handler_t *) sys_ni_syscall,
-	[ __NR_quotactl ] (syscall_handler_t *) sys_quotactl,
-	[ __NR_getpgid ] (syscall_handler_t *) sys_getpgid,
-	[ __NR_fchdir ] (syscall_handler_t *) sys_fchdir,
-	[ __NR_bdflush ] (syscall_handler_t *) sys_bdflush,
-	[ __NR_sysfs ] (syscall_handler_t *) sys_sysfs,
-	[ __NR_personality ] (syscall_handler_t *) sys_personality,
-	[ __NR_afs_syscall ] (syscall_handler_t *) sys_ni_syscall,
-	[ __NR_setfsuid ] (syscall_handler_t *) sys_setfsuid16,
-	[ __NR_setfsgid ] (syscall_handler_t *) sys_setfsgid16,
-	[ __NR__llseek ] (syscall_handler_t *) sys_llseek,
-	[ __NR_getdents ] (syscall_handler_t *) sys_getdents,
-	[ __NR__newselect ] = (syscall_handler_t *) sys_select,
-	[ __NR_flock ] (syscall_handler_t *) sys_flock,
-	[ __NR_msync ] (syscall_handler_t *) sys_msync,
-	[ __NR_readv ] (syscall_handler_t *) sys_readv,
-	[ __NR_writev ] (syscall_handler_t *) sys_writev,
-	[ __NR_getsid ] (syscall_handler_t *) sys_getsid,
-	[ __NR_fdatasync ] (syscall_handler_t *) sys_fdatasync,
+	[ __NR_sysinfo ] = (syscall_handler_t *) sys_sysinfo,
+	[ __NR_fsync ] = (syscall_handler_t *) sys_fsync,
+	[ __NR_clone ] = (syscall_handler_t *) sys_clone,
+	[ __NR_setdomainname ] = (syscall_handler_t *) sys_setdomainname,
+	[ __NR_uname ] = (syscall_handler_t *) sys_newuname,
+	[ __NR_adjtimex ] = (syscall_handler_t *) sys_adjtimex,
+	[ __NR_mprotect ] = (syscall_handler_t *) sys_mprotect,
+	[ __NR_create_module ] = (syscall_handler_t *) sys_ni_syscall,
+	[ __NR_init_module ] = (syscall_handler_t *) sys_init_module,
+	[ __NR_delete_module ] = (syscall_handler_t *) sys_delete_module,
+	[ __NR_get_kernel_syms ] = (syscall_handler_t *) sys_ni_syscall,
+	[ __NR_quotactl ] = (syscall_handler_t *) sys_quotactl,
+	[ __NR_getpgid ] = (syscall_handler_t *) sys_getpgid,
+	[ __NR_fchdir ] = (syscall_handler_t *) sys_fchdir,
+	[ __NR_sysfs ] = (syscall_handler_t *) sys_sysfs,
+	[ __NR_personality ] = (syscall_handler_t *) sys_personality,
+	[ __NR_afs_syscall ] = (syscall_handler_t *) sys_ni_syscall,
+	[ __NR_setfsuid ] = (syscall_handler_t *) sys_setfsuid16,
+	[ __NR_setfsgid ] = (syscall_handler_t *) sys_setfsgid16,
+	[ __NR_getdents ] = (syscall_handler_t *) sys_getdents,
+	[ __NR_flock ] = (syscall_handler_t *) sys_flock,
+	[ __NR_msync ] = (syscall_handler_t *) sys_msync,
+	[ __NR_readv ] = (syscall_handler_t *) sys_readv,
+	[ __NR_writev ] = (syscall_handler_t *) sys_writev,
+	[ __NR_getsid ] = (syscall_handler_t *) sys_getsid,
+	[ __NR_fdatasync ] = (syscall_handler_t *) sys_fdatasync,
 	[ __NR__sysctl ] = (syscall_handler_t *) sys_sysctl,
-	[ __NR_mlock ] (syscall_handler_t *) sys_mlock,
-	[ __NR_munlock ] (syscall_handler_t *) sys_munlock,
-	[ __NR_mlockall ] (syscall_handler_t *) sys_mlockall,
-	[ __NR_munlockall ] (syscall_handler_t *) sys_munlockall,
-	[ __NR_sched_setparam ] (syscall_handler_t *) sys_sched_setparam,
-	[ __NR_sched_getparam ] (syscall_handler_t *) sys_sched_getparam,
-	[ __NR_sched_setscheduler ] (syscall_handler_t *) sys_sched_setscheduler,
-	[ __NR_sched_getscheduler ] (syscall_handler_t *) sys_sched_getscheduler,
+	[ __NR_mlock ] = (syscall_handler_t *) sys_mlock,
+	[ __NR_munlock ] = (syscall_handler_t *) sys_munlock,
+	[ __NR_mlockall ] = (syscall_handler_t *) sys_mlockall,
+	[ __NR_munlockall ] = (syscall_handler_t *) sys_munlockall,
+	[ __NR_sched_setparam ] = (syscall_handler_t *) sys_sched_setparam,
+	[ __NR_sched_getparam ] = (syscall_handler_t *) sys_sched_getparam,
+	[ __NR_sched_setscheduler ] = (syscall_handler_t *) sys_sched_setscheduler,
+	[ __NR_sched_getscheduler ] = (syscall_handler_t *) sys_sched_getscheduler,
 	[ __NR_sched_yield ] = (syscall_handler_t *) yield,
-	[ __NR_sched_get_priority_max ] (syscall_handler_t *) sys_sched_get_priority_max,
-	[ __NR_sched_get_priority_min ] (syscall_handler_t *) sys_sched_get_priority_min,
-	[ __NR_sched_rr_get_interval ] (syscall_handler_t *) sys_sched_rr_get_interval,
-	[ __NR_nanosleep ] (syscall_handler_t *) sys_nanosleep,
-	[ __NR_mremap ] (syscall_handler_t *) sys_mremap,
-	[ __NR_setresuid ] (syscall_handler_t *) sys_setresuid16,
-	[ __NR_getresuid ] (syscall_handler_t *) sys_getresuid16,
-	[ __NR_vm86 ] (syscall_handler_t *) sys_ni_syscall,
-	[ __NR_query_module ] (syscall_handler_t *) sys_ni_syscall,
-	[ __NR_poll ] (syscall_handler_t *) sys_poll,
+	[ __NR_sched_get_priority_max ] = (syscall_handler_t *) sys_sched_get_priority_max,
+	[ __NR_sched_get_priority_min ] = (syscall_handler_t *) sys_sched_get_priority_min,
+	[ __NR_sched_rr_get_interval ] = (syscall_handler_t *) sys_sched_rr_get_interval,
+	[ __NR_nanosleep ] = (syscall_handler_t *) sys_nanosleep,
+	[ __NR_mremap ] = (syscall_handler_t *) sys_mremap,
+	[ __NR_setresuid ] = (syscall_handler_t *) sys_setresuid16,
+	[ __NR_getresuid ] = (syscall_handler_t *) sys_getresuid16,
+	[ __NR_query_module ] = (syscall_handler_t *) sys_ni_syscall,
+	[ __NR_poll ] = (syscall_handler_t *) sys_poll,
 	[ __NR_nfsservctl ] = (syscall_handler_t *) NFSSERVCTL,
-	[ __NR_setresgid ] (syscall_handler_t *) sys_setresgid16,
-	[ __NR_getresgid ] (syscall_handler_t *) sys_getresgid16,
-	[ __NR_prctl ] (syscall_handler_t *) sys_prctl,
-	[ __NR_rt_sigreturn ] (syscall_handler_t *) sys_rt_sigreturn,
-	[ __NR_rt_sigaction ] (syscall_handler_t *) sys_rt_sigaction,
-	[ __NR_rt_sigprocmask ] (syscall_handler_t *) sys_rt_sigprocmask,
-	[ __NR_rt_sigpending ] (syscall_handler_t *) sys_rt_sigpending,
-	[ __NR_rt_sigtimedwait ] (syscall_handler_t *) sys_rt_sigtimedwait,
-	[ __NR_rt_sigqueueinfo ] (syscall_handler_t *) sys_rt_sigqueueinfo,
-	[ __NR_rt_sigsuspend ] (syscall_handler_t *) sys_rt_sigsuspend,
-	[ __NR_pread64 ] (syscall_handler_t *) sys_pread64,
-	[ __NR_pwrite64 ] (syscall_handler_t *) sys_pwrite64,
-	[ __NR_chown ] (syscall_handler_t *) sys_chown16,
-	[ __NR_getcwd ] (syscall_handler_t *) sys_getcwd,
-	[ __NR_capget ] (syscall_handler_t *) sys_capget,
-	[ __NR_capset ] (syscall_handler_t *) sys_capset,
-	[ __NR_sigaltstack ] (syscall_handler_t *) sys_sigaltstack,
-	[ __NR_sendfile ] (syscall_handler_t *) sys_sendfile,
-	[ __NR_getpmsg ] (syscall_handler_t *) sys_ni_syscall,
-	[ __NR_putpmsg ] (syscall_handler_t *) sys_ni_syscall,
-	[ __NR_vfork ] (syscall_handler_t *) sys_vfork,
-	[ __NR_ugetrlimit ] (syscall_handler_t *) sys_getrlimit,
-	[ __NR_mmap2 ] (syscall_handler_t *) sys_mmap2,
-	[ __NR_truncate64 ] (syscall_handler_t *) sys_truncate64,
-	[ __NR_ftruncate64 ] (syscall_handler_t *) sys_ftruncate64,
-	[ __NR_stat64 ] (syscall_handler_t *) sys_stat64,
-	[ __NR_lstat64 ] (syscall_handler_t *) sys_lstat64,
-	[ __NR_fstat64 ] (syscall_handler_t *) sys_fstat64,
-	[ __NR_getdents64 ] (syscall_handler_t *) sys_getdents64,
-	[ __NR_fcntl64 ] (syscall_handler_t *) sys_fcntl64,
-	[ 223 ] (syscall_handler_t *) sys_ni_syscall,
-	[ __NR_gettid ] (syscall_handler_t *) sys_gettid,
-	[ __NR_readahead ] (syscall_handler_t *) sys_readahead,
-	[ __NR_setxattr ] (syscall_handler_t *) sys_setxattr,
-	[ __NR_lsetxattr ] (syscall_handler_t *) sys_lsetxattr,
-	[ __NR_fsetxattr ] (syscall_handler_t *) sys_fsetxattr,
-	[ __NR_getxattr ] (syscall_handler_t *) sys_getxattr,
-	[ __NR_lgetxattr ] (syscall_handler_t *) sys_lgetxattr,
-	[ __NR_fgetxattr ] (syscall_handler_t *) sys_fgetxattr,
-	[ __NR_listxattr ] (syscall_handler_t *) sys_listxattr,
-	[ __NR_llistxattr ] (syscall_handler_t *) sys_llistxattr,
-	[ __NR_flistxattr ] (syscall_handler_t *) sys_flistxattr,
-	[ __NR_removexattr ] (syscall_handler_t *) sys_removexattr,
-	[ __NR_lremovexattr ] (syscall_handler_t *) sys_lremovexattr,
-	[ __NR_fremovexattr ] (syscall_handler_t *) sys_fremovexattr,
-	[ __NR_tkill ] (syscall_handler_t *) sys_tkill,
-	[ __NR_sendfile64 ] (syscall_handler_t *) sys_sendfile64,
-	[ __NR_futex ] (syscall_handler_t *) sys_futex,
-	[ __NR_sched_setaffinity ] (syscall_handler_t *) sys_sched_setaffinity,
-	[ __NR_sched_getaffinity ] (syscall_handler_t *) sys_sched_getaffinity,
-	[ __NR_set_thread_area ] (syscall_handler_t *) sys_ni_syscall,
-	[ __NR_get_thread_area ] (syscall_handler_t *) sys_ni_syscall,
-	[ __NR_io_setup ] (syscall_handler_t *) sys_io_setup,
-	[ __NR_io_destroy ] (syscall_handler_t *) sys_io_destroy,
-	[ __NR_io_getevents ] (syscall_handler_t *) sys_io_getevents,
-	[ __NR_io_submit ] (syscall_handler_t *) sys_io_submit,
-	[ __NR_io_cancel ] (syscall_handler_t *) sys_io_cancel,
-	[ __NR_fadvise64 ] (syscall_handler_t *) sys_fadvise64,
-	[ 251 ] (syscall_handler_t *) sys_ni_syscall,
-	[ __NR_exit_group ] (syscall_handler_t *) sys_exit_group,
-	[ __NR_lookup_dcookie ] (syscall_handler_t *) sys_lookup_dcookie,
-	[ __NR_epoll_create ] (syscall_handler_t *) sys_epoll_create,
-	[ __NR_epoll_ctl ] (syscall_handler_t *) sys_epoll_ctl,
-	[ __NR_epoll_wait ] (syscall_handler_t *) sys_epoll_wait,
-        [ __NR_remap_file_pages ] (syscall_handler_t *) sys_remap_file_pages,
-        [ __NR_set_tid_address ] (syscall_handler_t *) sys_set_tid_address,
-	[ __NR_timer_create ] (syscall_handler_t *) sys_timer_create,
-	[ __NR_timer_settime ] (syscall_handler_t *) sys_timer_settime,
-	[ __NR_timer_gettime ] (syscall_handler_t *) sys_timer_gettime,
-	[ __NR_timer_getoverrun ] (syscall_handler_t *) sys_timer_getoverrun,
-	[ __NR_timer_delete ] (syscall_handler_t *) sys_timer_delete,
-	[ __NR_clock_settime ] (syscall_handler_t *) sys_clock_settime,
-	[ __NR_clock_gettime ] (syscall_handler_t *) sys_clock_gettime,
-	[ __NR_clock_getres ] (syscall_handler_t *) sys_clock_getres,
-	[ __NR_clock_nanosleep ] (syscall_handler_t *) sys_clock_nanosleep,
-	[ __NR_statfs64 ] (syscall_handler_t *) sys_statfs64,
-	[ __NR_fstatfs64 ] (syscall_handler_t *) sys_fstatfs64,
-	[ __NR_tgkill ] (syscall_handler_t *) sys_tgkill,
-	[ __NR_utimes ] (syscall_handler_t *) sys_utimes,
-	[ __NR_fadvise64_64 ] (syscall_handler_t *) sys_fadvise64_64,
-	[ __NR_vserver ] (syscall_handler_t *) sys_ni_syscall,
+	[ __NR_setresgid ] = (syscall_handler_t *) sys_setresgid16,
+	[ __NR_getresgid ] = (syscall_handler_t *) sys_getresgid16,
+	[ __NR_prctl ] = (syscall_handler_t *) sys_prctl,
+	[ __NR_rt_sigreturn ] = (syscall_handler_t *) sys_rt_sigreturn,
+	[ __NR_rt_sigaction ] = (syscall_handler_t *) sys_rt_sigaction,
+	[ __NR_rt_sigprocmask ] = (syscall_handler_t *) sys_rt_sigprocmask,
+	[ __NR_rt_sigpending ] = (syscall_handler_t *) sys_rt_sigpending,
+	[ __NR_rt_sigtimedwait ] = (syscall_handler_t *) sys_rt_sigtimedwait,
+	[ __NR_rt_sigqueueinfo ] = (syscall_handler_t *) sys_rt_sigqueueinfo,
+	[ __NR_rt_sigsuspend ] = (syscall_handler_t *) sys_rt_sigsuspend,
+	[ __NR_pread64 ] = (syscall_handler_t *) sys_pread64,
+	[ __NR_pwrite64 ] = (syscall_handler_t *) sys_pwrite64,
+	[ __NR_chown ] = (syscall_handler_t *) sys_chown16,
+	[ __NR_getcwd ] = (syscall_handler_t *) sys_getcwd,
+	[ __NR_capget ] = (syscall_handler_t *) sys_capget,
+	[ __NR_capset ] = (syscall_handler_t *) sys_capset,
+	[ __NR_sigaltstack ] = (syscall_handler_t *) sys_sigaltstack,
+	[ __NR_sendfile ] = (syscall_handler_t *) sys_sendfile,
+	[ __NR_getpmsg ] = (syscall_handler_t *) sys_ni_syscall,
+	[ __NR_putpmsg ] = (syscall_handler_t *) sys_ni_syscall,
+	[ __NR_vfork ] = (syscall_handler_t *) sys_vfork,
+	[ __NR_getdents64 ] = (syscall_handler_t *) sys_getdents64,
+	[ __NR_gettid ] = (syscall_handler_t *) sys_gettid,
+	[ __NR_readahead ] = (syscall_handler_t *) sys_readahead,
+	[ __NR_setxattr ] = (syscall_handler_t *) sys_setxattr,
+	[ __NR_lsetxattr ] = (syscall_handler_t *) sys_lsetxattr,
+	[ __NR_fsetxattr ] = (syscall_handler_t *) sys_fsetxattr,
+	[ __NR_getxattr ] = (syscall_handler_t *) sys_getxattr,
+	[ __NR_lgetxattr ] = (syscall_handler_t *) sys_lgetxattr,
+	[ __NR_fgetxattr ] = (syscall_handler_t *) sys_fgetxattr,
+	[ __NR_listxattr ] = (syscall_handler_t *) sys_listxattr,
+	[ __NR_llistxattr ] = (syscall_handler_t *) sys_llistxattr,
+	[ __NR_flistxattr ] = (syscall_handler_t *) sys_flistxattr,
+	[ __NR_removexattr ] = (syscall_handler_t *) sys_removexattr,
+	[ __NR_lremovexattr ] = (syscall_handler_t *) sys_lremovexattr,
+	[ __NR_fremovexattr ] = (syscall_handler_t *) sys_fremovexattr,
+	[ __NR_tkill ] = (syscall_handler_t *) sys_tkill,
+	[ __NR_futex ] = (syscall_handler_t *) sys_futex,
+	[ __NR_sched_setaffinity ] = (syscall_handler_t *) sys_sched_setaffinity,
+	[ __NR_sched_getaffinity ] = (syscall_handler_t *) sys_sched_getaffinity,
+	[ __NR_io_setup ] = (syscall_handler_t *) sys_io_setup,
+	[ __NR_io_destroy ] = (syscall_handler_t *) sys_io_destroy,
+	[ __NR_io_getevents ] = (syscall_handler_t *) sys_io_getevents,
+	[ __NR_io_submit ] = (syscall_handler_t *) sys_io_submit,
+	[ __NR_io_cancel ] = (syscall_handler_t *) sys_io_cancel,
+	[ __NR_exit_group ] = (syscall_handler_t *) sys_exit_group,
+	[ __NR_lookup_dcookie ] = (syscall_handler_t *) sys_lookup_dcookie,
+	[ __NR_epoll_create ] = (syscall_handler_t *) sys_epoll_create,
+	[ __NR_epoll_ctl ] = (syscall_handler_t *) sys_epoll_ctl,
+	[ __NR_epoll_wait ] = (syscall_handler_t *) sys_epoll_wait,
+        [ __NR_set_tid_address ] = (syscall_handler_t *) sys_set_tid_address,
+	[ __NR_timer_create ] = (syscall_handler_t *) sys_timer_create,
+	[ __NR_timer_settime ] = (syscall_handler_t *) sys_timer_settime,
+	[ __NR_timer_gettime ] = (syscall_handler_t *) sys_timer_gettime,
+	[ __NR_timer_getoverrun ] = (syscall_handler_t *) sys_timer_getoverrun,
+	[ __NR_timer_delete ] = (syscall_handler_t *) sys_timer_delete,
+	[ __NR_clock_settime ] = (syscall_handler_t *) sys_clock_settime,
+	[ __NR_clock_gettime ] = (syscall_handler_t *) sys_clock_gettime,
+	[ __NR_clock_getres ] = (syscall_handler_t *) sys_clock_getres,
+	[ __NR_clock_nanosleep ] = (syscall_handler_t *) sys_clock_nanosleep,
+	[ __NR_statfs64 ] = (syscall_handler_t *) sys_statfs64,
+	[ __NR_fstatfs64 ] = (syscall_handler_t *) sys_fstatfs64,
+	[ __NR_tgkill ] = (syscall_handler_t *) sys_tgkill,
+	[ __NR_utimes ] = (syscall_handler_t *) sys_utimes,
+	[ __NR_fadvise64_64 ] = (syscall_handler_t *) sys_fadvise64_64,
+	[ __NR_vserver ] = (syscall_handler_t *) sys_vserver,
+	[ __NR_mbind ] = (syscall_handler_t *) sys_mbind,
+	[ __NR_get_mempolicy ] = (syscall_handler_t *) sys_get_mempolicy,
+	[ __NR_set_mempolicy ] = (syscall_handler_t *) sys_set_mempolicy,
+	[ __NR_mq_open ] = (syscall_handler_t *) sys_mq_open,
+	[ __NR_mq_unlink ] = (syscall_handler_t *) sys_mq_unlink,
+	[ __NR_mq_timedsend ] = (syscall_handler_t *) sys_mq_timedsend,
+	[ __NR_mq_timedreceive ] = (syscall_handler_t *) sys_mq_timedreceive,
+	[ __NR_mq_notify ] = (syscall_handler_t *) sys_mq_notify,
+	[ __NR_mq_getsetattr ] = (syscall_handler_t *) sys_mq_getsetattr,
+	[ __NR_sys_kexec_load ] = (syscall_handler_t *) sys_ni_syscall,
+	[ __NR_waitid ] = (syscall_handler_t *) sys_waitid,
+	[ 285 ] = (syscall_handler_t *) sys_ni_syscall,
+	[ __NR_add_key ] = (syscall_handler_t *) sys_add_key,
+	[ __NR_request_key ] = (syscall_handler_t *) sys_request_key,
+	[ __NR_keyctl ] = (syscall_handler_t *) sys_keyctl,
 
 	ARCH_SYSCALLS
 	[ LAST_SYSCALL + 1 ... NR_syscalls ] = 
 	        (syscall_handler_t *) sys_ni_syscall
 };
-
-/*
- * 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 -Nru a/arch/um/kernel/syscall_kern.c b/arch/um/kernel/syscall_kern.c
--- a/arch/um/kernel/syscall_kern.c	2005-03-01 23:39:08 -08:00
+++ b/arch/um/kernel/syscall_kern.c	2005-03-01 23:39:08 -08:00
@@ -27,10 +27,9 @@
 /*  Unlocked, I don't care if this is a bit off */
 int nsyscalls = 0;
 
-long um_mount(char * dev_name, char * dir_name, char * type,
-	      unsigned long new_flags, void * data)
+long um_mount(char __user * dev_name, char __user * dir_name,
+	      char __user * type, unsigned long new_flags, void __user * data)
 {
-	if(type == NULL) type = "";
 	return(sys_mount(dev_name, dir_name, type, new_flags, data));
 }
 
@@ -56,12 +55,11 @@
 }
 
 /* common code for old and new mmaps */
-static inline long do_mmap2(
-	unsigned long addr, unsigned long len,
-	unsigned long prot, unsigned long flags,
-	unsigned long fd, unsigned long pgoff)
+long sys_mmap2(unsigned long addr, unsigned long len,
+	       unsigned long prot, unsigned long flags,
+	       unsigned long fd, unsigned long pgoff)
 {
-	int error = -EBADF;
+	long error = -EBADF;
 	struct file * file = NULL;
 
 	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
@@ -81,38 +79,15 @@
 	return error;
 }
 
-long sys_mmap2(unsigned long addr, unsigned long len,
-	       unsigned long prot, unsigned long flags,
-	       unsigned long fd, unsigned long pgoff)
-{
-	return do_mmap2(addr, len, prot, flags, fd, pgoff);
-}
-
-/*
- * Perform the select(nd, in, out, ex, tv) and mmap() system
- * calls. Linux/i386 didn't use to be able to handle more than
- * 4 system call parameters, so these system calls used a memory
- * block for parameter passing..
- */
-
-struct mmap_arg_struct {
-	unsigned long addr;
-	unsigned long len;
-	unsigned long prot;
-	unsigned long flags;
-	unsigned long fd;
-	unsigned long offset;
-};
-
 long old_mmap(unsigned long addr, unsigned long len,
-	     unsigned long prot, unsigned long flags,
-	     unsigned long fd, unsigned long offset)
+	      unsigned long prot, unsigned long flags,
+	      unsigned long fd, unsigned long offset)
 {
 	long err = -EINVAL;
 	if (offset & ~PAGE_MASK)
 		goto out;
 
-	err = do_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
+	err = sys_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
  out:
 	return err;
 }
@@ -120,7 +95,7 @@
  * sys_pipe() is the normal C calling standard for creating
  * a pipe. It's not the way unix traditionally does this, though.
  */
-long sys_pipe(unsigned long * fildes)
+long sys_pipe(unsigned long __user * fildes)
 {
         int fd[2];
         long error;
@@ -133,90 +108,6 @@
         return error;
 }
 
-/*
- * sys_ipc() is the de-multiplexer for the SysV IPC calls..
- *
- * This is really horribly ugly.
- */
-int sys_ipc (uint call, int first, int second,
-	     int third, void *ptr, long fifth)
-{
-	int version, ret;
-
-	version = call >> 16; /* hack for backward compatibility */
-	call &= 0xffff;
-
-	switch (call) {
-	case SEMOP:
-		return sys_semtimedop(first, (struct sembuf *) ptr, second, 
-				      NULL);
-	case SEMTIMEDOP:
-		return sys_semtimedop(first, (struct sembuf *) ptr, second,
-				      (const struct timespec *) fifth);
-	case SEMGET:
-		return sys_semget (first, second, third);
-	case SEMCTL: {
-		union semun fourth;
-		if (!ptr)
-			return -EINVAL;
-		if (get_user(fourth.__pad, (void **) ptr))
-			return -EFAULT;
-		return sys_semctl (first, second, third, fourth);
-	}
-
-	case MSGSND:
-		return sys_msgsnd (first, (struct msgbuf *) ptr, 
-				   second, third);
-	case MSGRCV:
-		switch (version) {
-		case 0: {
-			struct ipc_kludge tmp;
-			if (!ptr)
-				return -EINVAL;
-			
-			if (copy_from_user(&tmp,
-					   (struct ipc_kludge *) ptr, 
-					   sizeof (tmp)))
-				return -EFAULT;
-			return sys_msgrcv (first, tmp.msgp, second,
-					   tmp.msgtyp, third);
-		}
-		default:
-		        panic("msgrcv with version != 0");
-			return sys_msgrcv (first,
-					   (struct msgbuf *) ptr,
-					   second, fifth, third);
-		}
-	case MSGGET:
-		return sys_msgget ((key_t) first, second);
-	case MSGCTL:
-		return sys_msgctl (first, second, (struct msqid_ds *) ptr);
-
-	case SHMAT:
-		switch (version) {
-		default: {
-			ulong raddr;
-			ret = do_shmat (first, (char *) ptr, second, &raddr);
-			if (ret)
-				return ret;
-			return put_user (raddr, (ulong *) third);
-		}
-		case 1:	/* iBCS2 emulator entry point */
-			if (!segment_eq(get_fs(), get_ds()))
-				return -EINVAL;
-			return do_shmat (first, (char *) ptr, second, (ulong *) third);
-		}
-	case SHMDT: 
-		return sys_shmdt ((char *)ptr);
-	case SHMGET:
-		return sys_shmget (first, second, third);
-	case SHMCTL:
-		return sys_shmctl (first, second,
-				   (struct shmid_ds *) ptr);
-	default:
-		return -ENOSYS;
-	}
-}
 
 long sys_uname(struct old_utsname * name)
 {
@@ -268,7 +159,7 @@
 	return(CHOOSE_MODE_PROC(execute_syscall_tt, execute_syscall_skas, r));
 }
 
-spinlock_t syscall_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(syscall_lock);
 
 static int syscall_index = 0;
 
diff -Nru a/arch/um/kernel/sysrq.c b/arch/um/kernel/sysrq.c
--- a/arch/um/kernel/sysrq.c	2005-03-01 23:38:55 -08:00
+++ b/arch/um/kernel/sysrq.c	2005-03-01 23:38:55 -08:00
@@ -15,26 +15,30 @@
 void show_trace(unsigned long * stack)
 {
 	/* XXX: Copy the CONFIG_FRAME_POINTER stack-walking backtrace from
-	 * arch/i386/kernel/traps.c. */
+	 * arch/i386/kernel/traps.c, and then move this to sys-i386/sysrq.c.*/
         unsigned long addr;
 
-        if (!stack)
+        if (!stack) {
                 stack = (unsigned long*) &stack;
+		WARN_ON(1);
+	}
 
         printk("Call Trace: \n");
         while (((long) stack & (THREAD_SIZE-1)) != 0) {
-                addr = *stack++;
+                addr = *stack;
 		if (__kernel_text_address(addr)) {
-			printk(" [<%08lx>]", addr);
+			printk("%08lx:  [<%08lx>]", (unsigned long) stack, addr);
 			print_symbol(" %s", addr);
 			printk("\n");
                 }
+                stack++;
         }
         printk("\n");
 }
 
 /*
- * The architecture-independent dump_stack generator
+ * stack dumps generator - this is used by arch-independent code.
+ * And this is identical to i386 currently.
  */
 void dump_stack(void)
 {
@@ -44,7 +48,34 @@
 }
 EXPORT_SYMBOL(dump_stack);
 
-void show_stack(struct task_struct *task, unsigned long *sp)
+/*Stolen from arch/i386/kernel/traps.c */
+static int kstack_depth_to_print = 24;
+
+/* This recently started being used in arch-independent code too, as in
+ * kernel/sched.c.*/
+void show_stack(struct task_struct *task, unsigned long *esp)
 {
-	show_trace(sp);
+	unsigned long *stack;
+	int i;
+
+	if (esp == NULL) {
+		if (task != current) {
+			esp = (unsigned long *) KSTK_ESP(task);
+			/* Which one? No actual difference - just coding style.*/
+			//esp = (unsigned long *) PT_REGS_IP(&task->thread.regs);
+		} else {
+			esp = (unsigned long *) &esp;
+		}
+	}
+
+	stack = esp;
+	for(i = 0; i < kstack_depth_to_print; i++) {
+		if (kstack_end(stack))
+			break;
+		if (i && ((i % 8) == 0))
+			printk("\n       ");
+		printk("%08lx ", *stack++);
+	}
+
+	show_trace(esp);
 }
diff -Nru a/arch/um/kernel/time.c b/arch/um/kernel/time.c
--- a/arch/um/kernel/time.c	2005-03-01 23:38:53 -08:00
+++ b/arch/um/kernel/time.c	2005-03-01 23:38:53 -08:00
@@ -60,6 +60,9 @@
 	   (setitimer(ITIMER_REAL, &disable, NULL) < 0))
 		printk("disnable_timer - setitimer failed, errno = %d\n",
 		       errno);
+	/* If there are signals already queued, after unblocking ignore them */
+	set_handler(SIGALRM, SIG_IGN, 0, -1);
+	set_handler(SIGVTALRM, SIG_IGN, 0, -1);
 }
 
 void switch_timers(int to_real)
diff -Nru a/arch/um/kernel/time_kern.c b/arch/um/kernel/time_kern.c
--- a/arch/um/kernel/time_kern.c	2005-03-01 23:39:07 -08:00
+++ b/arch/um/kernel/time_kern.c	2005-03-01 23:39:07 -08:00
@@ -22,7 +22,7 @@
 #include "mode.h"
 #include "os.h"
 
-u64 jiffies_64;
+u64 jiffies_64 = INITIAL_JIFFIES;
 
 EXPORT_SYMBOL(jiffies_64);
 
@@ -111,19 +111,19 @@
 	return(IRQ_HANDLED);
 }
 
-long um_time(int * tloc)
+long um_time(int __user *tloc)
 {
 	struct timeval now;
 
 	do_gettimeofday(&now);
 	if (tloc) {
- 		if (put_user(now.tv_sec,tloc))
+ 		if (put_user(now.tv_sec, tloc))
 			now.tv_sec = -EFAULT;
 	}
 	return now.tv_sec;
 }
 
-long um_stime(int * tptr)
+long um_stime(int __user *tptr)
 {
 	int value;
 	struct timespec new;
@@ -136,22 +136,7 @@
 	return 0;
 }
 
-/* XXX Needs to be moved under sys-i386 */
-void __delay(um_udelay_t time)
-{
-	/* Stolen from the i386 __loop_delay */
-	int d0;
-	__asm__ __volatile__(
-		"\tjmp 1f\n"
-		".align 16\n"
-		"1:\tjmp 2f\n"
-		".align 16\n"
-		"2:\tdecl %0\n\tjns 2b"
-		:"=&a" (d0)
-		:"0" (time));
-}
-
-void __udelay(um_udelay_t usecs)
+void __udelay(unsigned long usecs)
 {
 	int i, n;
 
@@ -159,7 +144,7 @@
 	for(i=0;i<n;i++) ;
 }
 
-void __const_udelay(um_udelay_t usecs)
+void __const_udelay(unsigned long usecs)
 {
 	int i, n;
 
@@ -170,13 +155,13 @@
 void timer_handler(int sig, union uml_pt_regs *regs)
 {
 	local_irq_disable();
-	update_process_times(user_context(UPT_SP(regs)));
+	update_process_times(CHOOSE_MODE(user_context(UPT_SP(regs)), (regs)->skas.is_user));
 	local_irq_enable();
 	if(current_thread->cpu == 0)
 		timer_irq(regs);
 }
 
-static spinlock_t timer_spinlock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(timer_spinlock);
 
 unsigned long time_lock(void)
 {
diff -Nru a/arch/um/kernel/tlb.c b/arch/um/kernel/tlb.c
--- a/arch/um/kernel/tlb.c	2005-03-01 23:39:08 -08:00
+++ b/arch/um/kernel/tlb.c	2005-03-01 23:39:08 -08:00
@@ -59,9 +59,14 @@
 	return(pgd_offset(mm, address));
 }
 
-pmd_t *pmd_offset_proc(pgd_t *pgd, unsigned long address)
+pud_t *pud_offset_proc(pgd_t *pgd, unsigned long address)
 {
-	return(pmd_offset(pgd, address));
+	return(pud_offset(pgd, address));
+}
+
+pmd_t *pmd_offset_proc(pud_t *pud, unsigned long address)
+{
+	return(pmd_offset(pud, address));
 }
 
 pte_t *pte_offset_proc(pmd_t *pmd, unsigned long address)
@@ -71,8 +76,11 @@
 
 pte_t *addr_pte(struct task_struct *task, unsigned long addr)
 {
-	return(pte_offset_kernel(pmd_offset(pgd_offset(task->mm, addr), addr), 
-				 addr));
+	pgd_t *pgd = pgd_offset(task->mm, addr);
+	pud_t *pud = pud_offset(pgd, addr);
+	pmd_t *pmd = pmd_offset(pud, addr);
+
+	return(pte_offset_map(pmd, addr));
 }
 
 /*
diff -Nru a/arch/um/kernel/trap_kern.c b/arch/um/kernel/trap_kern.c
--- a/arch/um/kernel/trap_kern.c	2005-03-01 23:38:52 -08:00
+++ b/arch/um/kernel/trap_kern.c	2005-03-01 23:38:52 -08:00
@@ -13,6 +13,7 @@
 #include "linux/ptrace.h"
 #include "asm/semaphore.h"
 #include "asm/pgtable.h"
+#include "asm/pgalloc.h"
 #include "asm/tlbflush.h"
 #include "asm/a.out.h"
 #include "asm/current.h"
@@ -32,6 +33,7 @@
 	struct mm_struct *mm = current->mm;
 	struct vm_area_struct *vma;
 	pgd_t *pgd;
+	pud_t *pud;
 	pmd_t *pmd;
 	pte_t *pte;
 	unsigned long page;
@@ -46,6 +48,8 @@
 		goto good_area;
 	else if(!(vma->vm_flags & VM_GROWSDOWN)) 
 		goto out;
+	else if(!ARCH_IS_STACKGROW(address))
+		goto out;
 	else if(expand_stack(vma, address)) 
 		goto out;
 
@@ -55,7 +59,8 @@
 		goto out;
 	page = address & PAGE_MASK;
 	pgd = pgd_offset(mm, page);
-	pmd = pmd_offset(pgd, page);
+	pud = pud_offset(pgd, page);
+	pmd = pmd_offset(pud, page);
 	do {
  survive:
 		switch (handle_mm_fault(mm, vma, address, is_write)){
@@ -74,6 +79,9 @@
 		default:
 			BUG();
 		}
+		pgd = pgd_offset(mm, page);
+		pud = pud_offset(pgd, page);
+		pmd = pmd_offset(pud, page);
 		pte = pte_offset_kernel(pmd, page);
 	} while(!pte_present(*pte));
 	err = 0;
@@ -215,7 +223,7 @@
 {
 }
 
-spinlock_t trap_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(trap_lock);
 
 static int trap_index = 0;
 
diff -Nru a/arch/um/kernel/trap_user.c b/arch/um/kernel/trap_user.c
--- a/arch/um/kernel/trap_user.c	2005-03-01 23:38:57 -08:00
+++ b/arch/um/kernel/trap_user.c	2005-03-01 23:38:57 -08:00
@@ -18,7 +18,6 @@
 #include "sigcontext.h"
 #include "sysdep/sigcontext.h"
 #include "irq_user.h"
-#include "frame_user.h"
 #include "signal_user.h"
 #include "time_user.h"
 #include "task.h"
@@ -102,28 +101,6 @@
 	[ SIGUSR2 ] { .handler 		= usr2_handler,
 		      .is_irq 		= 0 },
 };
-
-void sig_handler(int sig, struct sigcontext sc)
-{
-	CHOOSE_MODE_PROC(sig_handler_common_tt, sig_handler_common_skas,
-			 sig, &sc);
-}
-
-extern int timer_irq_inited;
-
-void alarm_handler(int sig, struct sigcontext sc)
-{
-	if(!timer_irq_inited) return;
-
-	if(sig == SIGALRM)
-		switch_timers(0);
-
-	CHOOSE_MODE_PROC(sig_handler_common_tt, sig_handler_common_skas,
-			 sig, &sc);
-
-	if(sig == SIGALRM)
-		switch_timers(1);
-}
 
 void do_longjmp(void *b, int val)
 {
diff -Nru a/arch/um/kernel/tt/Makefile b/arch/um/kernel/tt/Makefile
--- a/arch/um/kernel/tt/Makefile	2005-03-01 23:38:57 -08:00
+++ b/arch/um/kernel/tt/Makefile	2005-03-01 23:38:57 -08:00
@@ -8,7 +8,7 @@
 
 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 \
-	uaccess.o uaccess_user.o sys-$(SUBARCH)/
+	uaccess.o uaccess_user.o
 
 obj-$(CONFIG_PT_PROXY) += gdb_kern.o ptproxy/
 
@@ -24,6 +24,9 @@
 $(obj)/unmap.o: $(src)/unmap.c
 	$(CC) $(UNMAP_CFLAGS) -c -o $@ $<
 
+LIBC_DIR ?= /usr/lib
+
 $(obj)/unmap_fin.o : $(obj)/unmap.o
-	ld -r -o $(obj)/unmap_tmp.o  $< -lc -L/usr/lib
+	ld -r -o $(obj)/unmap_tmp.o  $< -lc -L$(LIBC_DIR)
 	objcopy $(obj)/unmap_tmp.o $@ -G switcheroo
+
diff -Nru a/arch/um/kernel/tt/exec_user.c b/arch/um/kernel/tt/exec_user.c
--- a/arch/um/kernel/tt/exec_user.c	2005-03-01 23:39:09 -08:00
+++ b/arch/um/kernel/tt/exec_user.c	2005-03-01 23:39:09 -08:00
@@ -10,11 +10,13 @@
 #include <errno.h>
 #include <sys/wait.h>
 #include <sys/ptrace.h>
+#include <linux/ptrace.h>
 #include <signal.h>
 #include "user_util.h"
 #include "kern_util.h"
 #include "user.h"
 #include "ptrace_user.h"
+#include "os.h"
 
 void do_exec(int old_pid, int new_pid)
 {
@@ -35,7 +37,10 @@
 		tracer_panic("do_exec failed to get registers - errno = %d",
 			     errno);
 
-	kill(old_pid, SIGKILL);
+	os_kill_ptraced_process(old_pid, 0);
+
+	if (ptrace(PTRACE_OLDSETOPTIONS, new_pid, 0, (void *)PTRACE_O_TRACESYSGOOD) < 0)
+		tracer_panic("do_exec: PTRACE_SETOPTIONS failed, errno = %d", errno);
 
 	if(ptrace_setregs(new_pid, regs) < 0)
 		tracer_panic("do_exec failed to start new proc - errno = %d",
diff -Nru a/arch/um/kernel/tt/gdb.c b/arch/um/kernel/tt/gdb.c
--- a/arch/um/kernel/tt/gdb.c	2005-03-01 23:38:52 -08:00
+++ b/arch/um/kernel/tt/gdb.c	2005-03-01 23:38:52 -08:00
@@ -162,7 +162,7 @@
 void signal_usr1(int sig)
 {
 	if(debugger_pid != -1){
-		printk(UM_KERN_ERR "The debugger is already running\n");
+		printf("The debugger is already running\n");
 		return;
 	}
 	debugger_pid = start_debugger(linux_prog, 0, 0, &debugger_fd);
@@ -228,19 +228,19 @@
 void child_signal(pid_t pid, int status){ }
 int init_ptrace_proxy(int idle_pid, int startup, int stop)
 {
-	printk(UM_KERN_ERR "debug requested when CONFIG_PT_PROXY is off\n");
+	printf("debug requested when CONFIG_PT_PROXY is off\n");
 	kill_child_dead(idle_pid);
 	exit(1);
 }
 
 void signal_usr1(int sig)
 {
-	printk(UM_KERN_ERR "debug requested when CONFIG_PT_PROXY is off\n");
+	printf("debug requested when CONFIG_PT_PROXY is off\n");
 }
 
 int attach_debugger(int idle_pid, int pid, int stop)
 {
-	printk(UM_KERN_ERR "attach_debugger called when CONFIG_PT_PROXY "
+	printf("attach_debugger called when CONFIG_PT_PROXY "
 	       "is off\n");
 	return(-1);
 }
diff -Nru 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	2005-03-01 23:39:07 -08:00
+++ b/arch/um/kernel/tt/include/mode-tt.h	2005-03-01 23:39:07 -08:00
@@ -14,9 +14,6 @@
 
 extern int tracer(int (*init_proc)(void *), void *sp);
 extern void user_time_init_tt(void);
-extern int copy_sc_from_user_tt(void *to_ptr, void *from_ptr, void *data);
-extern int copy_sc_to_user_tt(void *to_ptr, void *fp, void *from_ptr,
-			      void *data);
 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 -Nru a/arch/um/kernel/tt/include/ptrace-tt.h b/arch/um/kernel/tt/include/ptrace-tt.h
--- a/arch/um/kernel/tt/include/ptrace-tt.h	2005-03-01 23:39:16 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,26 +0,0 @@
-/* 
- * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#ifndef __PTRACE_TT_H
-#define __PTRACE_TT_H
-
-#include "uml-config.h"
-
-#ifdef UML_CONFIG_MODE_TT
-#include "sysdep/sc.h"
-#endif
-
-#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 -Nru a/arch/um/kernel/tt/include/tt.h b/arch/um/kernel/tt/include/tt.h
--- a/arch/um/kernel/tt/include/tt.h	2005-03-01 23:38:58 -08:00
+++ b/arch/um/kernel/tt/include/tt.h	2005-03-01 23:38:58 -08:00
@@ -26,7 +26,8 @@
 extern int is_tracing(void *task);
 extern void syscall_handler(int sig, union uml_pt_regs *regs);
 extern void exit_kernel(int pid, void *task);
-extern int do_syscall(void *task, int pid, int local_using_sysemu);
+extern void do_syscall(void *task, int pid, int local_using_sysemu);
+extern void do_sigtrap(void *task);
 extern int is_valid_pid(int pid);
 extern void remap_data(void *segment_start, void *segment_end, int w);
 
diff -Nru a/arch/um/kernel/tt/process_kern.c b/arch/um/kernel/tt/process_kern.c
--- a/arch/um/kernel/tt/process_kern.c	2005-03-01 23:39:09 -08:00
+++ b/arch/um/kernel/tt/process_kern.c	2005-03-01 23:39:09 -08:00
@@ -65,7 +65,8 @@
 		panic("write of switch_pipe failed, err = %d", -err);
 
 	reading = 1;
-	if((from->exit_state == EXIT_ZOMBIE) || (from->exit_state == EXIT_DEAD))
+	if((from->exit_state == EXIT_ZOMBIE) ||
+	   (from->exit_state == EXIT_DEAD))
 		os_kill_process(os_getpid(), 0);
 
 	err = os_read_file(from->thread.mode.tt.switch_pipe[0], &c, sizeof(c));
@@ -82,7 +83,7 @@
 	prev_sched = current->thread.prev_sched;
 	if((prev_sched->exit_state == EXIT_ZOMBIE) ||
 	   (prev_sched->exit_state == EXIT_DEAD))
-		os_kill_ptraced_process(prev_sched->thread.mode.tt.extern_pid, 1);
+		os_kill_process(prev_sched->thread.mode.tt.extern_pid, 1);
 
 	/* This works around a nasty race with 'jail'.  If we are switching
 	 * between two threads of a threaded app and the incoming process 
diff -Nru a/arch/um/kernel/tt/ptproxy/proxy.c b/arch/um/kernel/tt/ptproxy/proxy.c
--- a/arch/um/kernel/tt/ptproxy/proxy.c	2005-03-01 23:38:59 -08:00
+++ b/arch/um/kernel/tt/ptproxy/proxy.c	2005-03-01 23:38:59 -08:00
@@ -94,7 +94,9 @@
 		debugger->handle_trace = debugger_syscall;
 		return(ret);
 
+#ifdef __NR_waitpid
 	case __NR_waitpid:
+#endif
 	case __NR_wait4:
 		if(!debugger_wait(debugger, (int *) arg2, arg3, 
 				  debugger_syscall, debugger_normal_return, 
@@ -153,7 +155,11 @@
 
 	syscall = get_syscall(pid, &arg1, &arg2, &arg3, &arg4, &arg5);
 		
-	if((syscall == __NR_waitpid) || (syscall == __NR_wait4)){
+	if((syscall == __NR_wait4)
+#ifdef __NR_waitpid
+	   || (syscall == __NR_waitpid)
+#endif
+	){
 		debugger_wait(&parent, (int *) arg2, arg3, parent_syscall,
 			      parent_normal_return, parent_wait_return);
 	}
diff -Nru a/arch/um/kernel/tt/ptproxy/sysdep.c b/arch/um/kernel/tt/ptproxy/sysdep.c
--- a/arch/um/kernel/tt/ptproxy/sysdep.c	2005-03-01 23:39:08 -08:00
+++ b/arch/um/kernel/tt/ptproxy/sysdep.c	2005-03-01 23:39:08 -08:00
@@ -12,7 +12,6 @@
 #include <errno.h>
 #include <sys/types.h>
 #include <sys/ptrace.h>
-#include <asm/ptrace.h>
 #include <linux/unistd.h>
 #include "ptrace_user.h"
 #include "user_util.h"
diff -Nru a/arch/um/kernel/tt/ptproxy/wait.c b/arch/um/kernel/tt/ptproxy/wait.c
--- a/arch/um/kernel/tt/ptproxy/wait.c	2005-03-01 23:39:09 -08:00
+++ b/arch/um/kernel/tt/ptproxy/wait.c	2005-03-01 23:39:09 -08:00
@@ -10,7 +10,6 @@
 #include <signal.h>
 #include <sys/wait.h>
 #include <sys/ptrace.h>
-#include <asm/ptrace.h>
 
 #include "ptproxy.h"
 #include "sysdep.h"
diff -Nru a/arch/um/kernel/tt/sys-i386/Makefile b/arch/um/kernel/tt/sys-i386/Makefile
--- a/arch/um/kernel/tt/sys-i386/Makefile	2005-03-01 23:38:56 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,12 +0,0 @@
-# 
-# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
-# Licensed under the GPL
-#
-
-obj-y = sigcontext.o
-
-USER_OBJS = sigcontext.o
-USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
-
-$(USER_OBJS) : %.o: %.c
-	$(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
diff -Nru a/arch/um/kernel/tt/sys-i386/sigcontext.c b/arch/um/kernel/tt/sys-i386/sigcontext.c
--- a/arch/um/kernel/tt/sys-i386/sigcontext.c	2005-03-01 23:39:17 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,60 +0,0 @@
-/* 
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#include <stdlib.h>
-#include <asm/sigcontext.h>
-#include "kern_util.h"
-#include "sysdep/frame.h"
-
-int copy_sc_from_user_tt(void *to_ptr, void *from_ptr, void *data)
-{
-	struct arch_frame_data *arch = data;
-	struct sigcontext *to = to_ptr, *from = from_ptr;
-	struct _fpstate *to_fp, *from_fp;
-	unsigned long sigs;
-	int err;
-
-	to_fp = to->fpstate;
-	from_fp = from->fpstate;
-	sigs = to->oldmask;
-	err = copy_from_user_proc(to, from, sizeof(*to));
-	to->oldmask = sigs;
-	if(to_fp != NULL){
-		err |= copy_from_user_proc(&to->fpstate, &to_fp,
-					   sizeof(to->fpstate));
-		err |= copy_from_user_proc(to_fp, from_fp, arch->fpstate_size);
-	}
-	return(err);
-}
-
-int copy_sc_to_user_tt(void *to_ptr, void *fp, void *from_ptr, void *data)
-{
-	struct arch_frame_data *arch = data;
-	struct sigcontext *to = to_ptr, *from = from_ptr;
-	struct _fpstate *to_fp, *from_fp;
-	int err;
-
-	to_fp = (struct _fpstate *) 
-		(fp ? (unsigned long) fp : ((unsigned long) to + sizeof(*to)));
-	from_fp = from->fpstate;
-	err = copy_to_user_proc(to, from, sizeof(*to));
-	if(from_fp != NULL){
-		err |= copy_to_user_proc(&to->fpstate, &to_fp,
-					 sizeof(to->fpstate));
-		err |= copy_to_user_proc(to_fp, from_fp, arch->fpstate_size);
-	}
-	return(err);
-}
-
-/*
- * 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 -Nru a/arch/um/kernel/tt/syscall_kern.c b/arch/um/kernel/tt/syscall_kern.c
--- a/arch/um/kernel/tt/syscall_kern.c	2005-03-01 23:38:44 -08:00
+++ b/arch/um/kernel/tt/syscall_kern.c	2005-03-01 23:38:44 -08:00
@@ -14,95 +14,6 @@
 #include "sysdep/syscalls.h"
 #include "kern_util.h"
 
-static inline int check_area(void *ptr, int size)
-{
-	return(verify_area(VERIFY_WRITE, ptr, size));
-}
-
-static int check_readlink(struct pt_regs *regs)
-{
-	return(check_area((void *) UPT_SYSCALL_ARG1(&regs->regs),
-			  UPT_SYSCALL_ARG2(&regs->regs)));
-}
-
-static int check_utime(struct pt_regs *regs)
-{
-	return(check_area((void *) UPT_SYSCALL_ARG1(&regs->regs),
-			  sizeof(struct utimbuf)));
-}
-
-static int check_oldstat(struct pt_regs *regs)
-{
-	return(check_area((void *) UPT_SYSCALL_ARG1(&regs->regs), 
-			  sizeof(struct __old_kernel_stat)));
-}
-
-static int check_stat(struct pt_regs *regs)
-{
-	return(check_area((void *) UPT_SYSCALL_ARG1(&regs->regs), 
-			  sizeof(struct stat)));
-}
-
-static int check_stat64(struct pt_regs *regs)
-{
-	return(check_area((void *) UPT_SYSCALL_ARG1(&regs->regs), 
-			  sizeof(struct stat64)));
-}
-
-struct bogus {
-	int kernel_ds;
-	int (*check_params)(struct pt_regs *);
-};
-
-struct bogus this_is_bogus[256] = {
-	[ __NR_mknod ] = { 1, NULL },
-	[ __NR_mkdir ] = { 1, NULL },
-	[ __NR_rmdir ] = { 1, NULL },
-	[ __NR_unlink ] = { 1, NULL },
-	[ __NR_symlink ] = { 1, NULL },
-	[ __NR_link ] = { 1, NULL },
-	[ __NR_rename ] = { 1, NULL },
-	[ __NR_umount ] = { 1, NULL },
-	[ __NR_mount ] = { 1, NULL },
-	[ __NR_pivot_root ] = { 1, NULL },
-	[ __NR_chdir ] = { 1, NULL },
-	[ __NR_chroot ] = { 1, NULL },
-	[ __NR_open ] = { 1, NULL },
-	[ __NR_quotactl ] = { 1, NULL },
-	[ __NR_sysfs ] = { 1, NULL },
-	[ __NR_readlink ] = { 1, check_readlink },
-	[ __NR_acct ] = { 1, NULL },
-	[ __NR_execve ] = { 1, NULL },
-	[ __NR_uselib ] = { 1, NULL },
-	[ __NR_statfs ] = { 1, NULL },
-	[ __NR_truncate ] = { 1, NULL },
-	[ __NR_access ] = { 1, NULL },
-	[ __NR_chmod ] = { 1, NULL },
-	[ __NR_chown ] = { 1, NULL },
-	[ __NR_lchown ] = { 1, NULL },
-	[ __NR_utime ] = { 1, check_utime },
-	[ __NR_oldlstat ] = { 1, check_oldstat },
-	[ __NR_oldstat ] = { 1, check_oldstat },
-	[ __NR_stat ] = { 1, check_stat },
-	[ __NR_lstat ] = { 1, check_stat },
-	[ __NR_stat64 ] = { 1, check_stat64 },
-	[ __NR_lstat64 ] = { 1, check_stat64 },
-	[ __NR_chown32 ] = { 1, NULL },
-};
-
-/* sys_utimes */
-
-static int check_bogosity(struct pt_regs *regs)
-{
-	struct bogus *bogon = &this_is_bogus[UPT_SYSCALL_NR(&regs->regs)];
-
-	if(!bogon->kernel_ds) return(0);
-	if(bogon->check_params && (*bogon->check_params)(regs))
-		return(-EFAULT);
-	set_fs(KERNEL_DS);
-	return(0);
-}
-
 extern syscall_handler_t *sys_call_table[];
 
 long execute_syscall_tt(void *r)
@@ -117,11 +28,7 @@
 
 	if((syscall >= NR_syscalls) || (syscall < 0))
 		res = -ENOSYS;
-	else if(honeypot && check_bogosity(regs))
-		res = -EFAULT;
 	else res = EXECUTE_SYSCALL(syscall, regs);
-
-	set_fs(USER_DS);
 
 	return(res);
 }
diff -Nru a/arch/um/kernel/tt/syscall_user.c b/arch/um/kernel/tt/syscall_user.c
--- a/arch/um/kernel/tt/syscall_user.c	2005-03-01 23:39:07 -08:00
+++ b/arch/um/kernel/tt/syscall_user.c	2005-03-01 23:39:07 -08:00
@@ -43,35 +43,33 @@
 	record_syscall_end(index, result);
 }
 
-int do_syscall(void *task, int pid, int local_using_sysemu)
+void do_sigtrap(void *task)
+{
+	UPT_SYSCALL_NR(TASK_REGS(task)) = -1;
+}
+
+void do_syscall(void *task, int pid, int local_using_sysemu)
 {
 	unsigned long proc_regs[FRAME_SIZE];
-	union uml_pt_regs *regs;
-	int syscall;
 
 	if(ptrace_getregs(pid, proc_regs) < 0)
 		tracer_panic("Couldn't read registers");
-	syscall = PT_SYSCALL_NR(proc_regs);
-
-	regs = TASK_REGS(task);
-	UPT_SYSCALL_NR(regs) = syscall;
 
-	if(syscall < 0)
-		return(0);
+	UPT_SYSCALL_NR(TASK_REGS(task)) = PT_SYSCALL_NR(proc_regs);
 
-	if((syscall != __NR_sigreturn) &&
-	   ((unsigned long *) PT_IP(proc_regs) >= &_stext) && 
+	if(((unsigned long *) PT_IP(proc_regs) >= &_stext) &&
 	   ((unsigned long *) PT_IP(proc_regs) <= &_etext))
 		tracer_panic("I'm tracing myself and I can't get out");
 
-	if(local_using_sysemu)
-		return(1);
+	/* advanced sysemu mode set syscall number to -1 automatically */
+	if (local_using_sysemu==2)
+		return;
 
+	/* syscall number -1 in sysemu skips syscall restarting in host */
 	if(ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, 
-		  __NR_getpid) < 0)
+		  local_using_sysemu ? -1 : __NR_getpid) < 0)
 		tracer_panic("do_syscall : Nullifying syscall failed, "
 			     "errno = %d", errno);
-	return(1);
 }
 
 /*
diff -Nru a/arch/um/kernel/tt/tlb.c b/arch/um/kernel/tt/tlb.c
--- a/arch/um/kernel/tt/tlb.c	2005-03-01 23:38:52 -08:00
+++ b/arch/um/kernel/tt/tlb.c	2005-03-01 23:38:52 -08:00
@@ -1,5 +1,6 @@
 /* 
  * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
+ * Copyright 2003 PathScale, Inc.
  * Licensed under the GPL
  */
 
@@ -19,9 +20,10 @@
 		      unsigned long end_addr, int force)
 {
 	pgd_t *npgd;
+	pud_t *npud;
 	pmd_t *npmd;
 	pte_t *npte;
-	unsigned long addr;
+	unsigned long addr, end;
 	int r, w, x, err;
 
 	if((current->thread.mode.tt.extern_pid != -1) && 
@@ -41,45 +43,81 @@
 			addr = STACK_TOP - ABOVE_KMEM;
 			continue;
 		}
+
 		npgd = pgd_offset(mm, addr);
-		npmd = pmd_offset(npgd, addr);
-		if(pmd_present(*npmd)){
-			npte = pte_offset_kernel(npmd, addr);
-			r = pte_read(*npte);
-			w = pte_write(*npte);
-			x = pte_exec(*npte);
-			if(!pte_dirty(*npte)) w = 0;
-			if(!pte_young(*npte)){
-				r = 0;
-				w = 0;
-			}
-			if(force || pte_newpage(*npte)){
+ 		if(!pgd_present(*npgd)){
+ 			if(force || pgd_newpage(*npgd)){
+ 				end = addr + PGDIR_SIZE;
+ 				if(end > end_addr)
+ 					end = end_addr;
+				err = os_unmap_memory((void *) addr,
+ 						      end - addr);
+				if(err < 0)
+					panic("munmap failed, errno = %d\n",
+					      -err);
+				pgd_mkuptodate(*npgd);
+ 			}
+			addr += PGDIR_SIZE;
+			continue;
+ 		}
+
+		npud = pud_offset(npgd, addr);
+		if(!pud_present(*npud)){
+			if(force || pud_newpage(*npud)){
+ 				end = addr + PUD_SIZE;
+ 				if(end > end_addr)
+ 					end = end_addr;
 				err = os_unmap_memory((void *) addr, 
-						      PAGE_SIZE);
+						      end - addr);
 				if(err < 0)
 					panic("munmap failed, errno = %d\n",
 					      -err);
-				if(pte_present(*npte))
-					map_memory(addr, 
-						   pte_val(*npte) & PAGE_MASK,
-						   PAGE_SIZE, r, w, x);
+				pud_mkuptodate(*npud);
 			}
-			else if(pte_newprot(*npte)){
-				protect_memory(addr, PAGE_SIZE, r, w, x, 1);
-			}
-			*npte = pte_mkuptodate(*npte);
-			addr += PAGE_SIZE;
+			addr += PUD_SIZE;
+			continue;
 		}
-		else {
+
+		npmd = pmd_offset(npud, addr);
+		if(!pmd_present(*npmd)){
 			if(force || pmd_newpage(*npmd)){
-				err = os_unmap_memory((void *) addr, PMD_SIZE);
+ 				end = addr + PMD_SIZE;
+ 				if(end > end_addr)
+ 					end = end_addr;
+				err = os_unmap_memory((void *) addr,
+						      end - addr);
 				if(err < 0)
 					panic("munmap failed, errno = %d\n",
 					      -err);
 				pmd_mkuptodate(*npmd);
 			}
 			addr += PMD_SIZE;
+			continue;
+		}
+
+		npte = pte_offset_kernel(npmd, addr);
+		r = pte_read(*npte);
+		w = pte_write(*npte);
+		x = pte_exec(*npte);
+		if(!pte_dirty(*npte))
+			w = 0;
+		if(!pte_young(*npte)){
+			r = 0;
+			w = 0;
+		}
+		if(force || pte_newpage(*npte)){
+			err = os_unmap_memory((void *) addr, PAGE_SIZE);
+			if(err < 0)
+				panic("munmap failed, errno = %d\n", -err);
+			if(pte_present(*npte))
+				map_memory(addr, pte_val(*npte) & PAGE_MASK,
+					   PAGE_SIZE, r, w, x);
 		}
+		else if(pte_newprot(*npte))
+			protect_memory(addr, PAGE_SIZE, r, w, x, 1);
+
+		*npte = pte_mkuptodate(*npte);
+		addr += PAGE_SIZE;
 	}
 }
 
@@ -90,45 +128,83 @@
 {
 	struct mm_struct *mm;
 	pgd_t *pgd;
+	pud_t *pud;
 	pmd_t *pmd;
 	pte_t *pte;
-	unsigned long addr;
+	unsigned long addr, last;
 	int updated = 0, err;
 
 	mm = &init_mm;
 	for(addr = start; addr < end;){
 		pgd = pgd_offset(mm, addr);
-		pmd = pmd_offset(pgd, addr);
-		if(pmd_present(*pmd)){
-			pte = pte_offset_kernel(pmd, addr);
-			if(!pte_present(*pte) || pte_newpage(*pte)){
+ 		if(!pgd_present(*pgd)){
+ 			if(pgd_newpage(*pgd)){
 				updated = 1;
+ 				last = addr + PGDIR_SIZE;
+ 				if(last > end)
+ 					last = end;
 				err = os_unmap_memory((void *) addr, 
-						      PAGE_SIZE);
+						      last - addr);
 				if(err < 0)
 					panic("munmap failed, errno = %d\n",
 					      -err);
-				if(pte_present(*pte))
-					map_memory(addr, 
-						   pte_val(*pte) & PAGE_MASK,
-						   PAGE_SIZE, 1, 1, 1);
 			}
-			else if(pte_newprot(*pte)){
+			addr += PGDIR_SIZE;
+			continue;
+		}
+
+		pud = pud_offset(pgd, addr);
+		if(!pud_present(*pud)){
+			if(pud_newpage(*pud)){
 				updated = 1;
-				protect_memory(addr, PAGE_SIZE, 1, 1, 1, 1);
+				last = addr + PUD_SIZE;
+				if(last > end)
+					last = end;
+				err = os_unmap_memory((void *) addr,
+						      last - addr);
+				if(err < 0)
+					panic("munmap failed, errno = %d\n",
+					      -err);
 			}
-			addr += PAGE_SIZE;
+			addr += PUD_SIZE;
+			continue;
 		}
-		else {
+
+		pmd = pmd_offset(pud, addr);
+		if(!pmd_present(*pmd)){
 			if(pmd_newpage(*pmd)){
 				updated = 1;
-				err = os_unmap_memory((void *) addr, PMD_SIZE);
+				last = addr + PMD_SIZE;
+				if(last > end)
+					last = end;
+				err = os_unmap_memory((void *) addr,
+						      last - addr);
 				if(err < 0)
 					panic("munmap failed, errno = %d\n",
 					      -err);
 			}
 			addr += PMD_SIZE;
+			continue;
+		}
+
+		pte = pte_offset_kernel(pmd, addr);
+		if(!pte_present(*pte) || pte_newpage(*pte)){
+			updated = 1;
+			err = os_unmap_memory((void *) addr,
+					      PAGE_SIZE);
+			if(err < 0)
+				panic("munmap failed, errno = %d\n",
+				      -err);
+			if(pte_present(*pte))
+				map_memory(addr,
+					   pte_val(*pte) & PAGE_MASK,
+					   PAGE_SIZE, 1, 1, 1);
+		}
+		else if(pte_newprot(*pte)){
+			updated = 1;
+			protect_memory(addr, PAGE_SIZE, 1, 1, 1, 1);
 		}
+		addr += PAGE_SIZE;
 	}
 	if(updated && update_seq) atomic_inc(&vmchange_seq);
 }
@@ -155,6 +231,7 @@
 {
 	struct mm_struct *mm;
 	pgd_t *pgd;
+	pud_t *pud;
 	pmd_t *pmd;
 	pte_t *pte;
 	unsigned long addr;
@@ -162,7 +239,8 @@
 	mm = &init_mm;
 	for(addr = start_vm; addr < end_vm;){
 		pgd = pgd_offset(mm, addr);
-		pmd = pmd_offset(pgd, addr);
+		pud = pud_offset(pgd, addr);
+		pmd = pmd_offset(pud, addr);
 		if(pmd_present(*pmd)){
 			pte = pte_offset_kernel(pmd, addr);
 			if(pte_present(*pte)) protect_vm_page(addr, w, 0);
diff -Nru a/arch/um/kernel/tt/tracer.c b/arch/um/kernel/tt/tracer.c
--- a/arch/um/kernel/tt/tracer.c	2005-03-01 23:38:51 -08:00
+++ b/arch/um/kernel/tt/tracer.c	2005-03-01 23:38:51 -08:00
@@ -13,6 +13,7 @@
 #include <string.h>
 #include <sys/mman.h>
 #include <sys/ptrace.h>
+#include <linux/ptrace.h>
 #include <sys/time.h>
 #include <sys/wait.h>
 #include "user.h"
@@ -25,7 +26,6 @@
 #include "mem_user.h"
 #include "process.h"
 #include "kern_util.h"
-#include "frame.h"
 #include "chan_user.h"
 #include "ptrace_user.h"
 #include "mode.h"
@@ -72,6 +72,8 @@
 	   (ptrace(PTRACE_CONT, pid, 0, 0) < 0))
 		tracer_panic("OP_FORK failed to attach pid");
 	wait_for_stop(pid, SIGSTOP, PTRACE_CONT, NULL);
+	if (ptrace(PTRACE_OLDSETOPTIONS, pid, 0, (void *)PTRACE_O_TRACESYSGOOD) < 0)
+		tracer_panic("OP_FORK: PTRACE_SETOPTIONS failed, errno = %d", errno);
 	if(ptrace(PTRACE_CONT, pid, 0, 0) < 0)
 		tracer_panic("OP_FORK failed to continue process");
 }
@@ -82,6 +84,7 @@
 
 	va_start(ap, format);
 	vprintf(format, ap);
+	va_end(ap);
 	printf("\n");
 	while(1) pause();
 }
@@ -141,7 +144,7 @@
 	 * any more, the trace of those will land here.  So, we need to just 
 	 * PTRACE_SYSCALL it.
 	 */
-	case SIGTRAP:
+	case (SIGTRAP + 0x80):
 		if(ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0)
 			tracer_panic("sleeping_process_signal : Failed to "
 				     "PTRACE_SYSCALL pid %d, errno = %d\n",
@@ -184,9 +187,8 @@
 	unsigned long eip = 0;
 	int status, pid = 0, sig = 0, cont_type, tracing = 0, op = 0;
 	int last_index, proc_id = 0, n, err, old_tracing = 0, strace = 0;
-	int pt_syscall_parm, local_using_sysemu;
+	int local_using_sysemu = 0;
 
-	capture_signal_stack();
 	signal(SIGPIPE, SIG_IGN);
 	setup_tracer_winch();
 	tracing_pid = os_getpid();
@@ -198,6 +200,10 @@
 		printf("waitpid on idle thread failed, errno = %d\n", errno);
 		exit(1);
 	}
+	if (ptrace(PTRACE_OLDSETOPTIONS, pid, 0, (void *)PTRACE_O_TRACESYSGOOD) < 0) {
+		printf("Failed to PTRACE_SETOPTIONS for idle thread, errno = %d\n", errno);
+		exit(1);
+	}
 	if((ptrace(PTRACE_CONT, pid, 0, 0) < 0)){
 		printf("Failed to continue idle thread, errno = %d\n", errno);
 		exit(1);
@@ -298,14 +304,24 @@
 			tracing = is_tracing(task);
 			old_tracing = tracing;
 
-			local_using_sysemu = get_using_sysemu();
-			pt_syscall_parm = local_using_sysemu ? PTRACE_SYSEMU : PTRACE_SYSCALL;
+			/* Assume: no syscall, when coming from user */
+			if ( tracing )
+				do_sigtrap(task);
 
 			switch(sig){
 			case SIGUSR1:
 				sig = 0;
 				op = do_proc_op(task, proc_id);
 				switch(op){
+				/*
+				 * This is called when entering user mode; after
+				 * this, we start intercepting syscalls.
+				 *
+				 * In fact, a process is started in kernel mode,
+				 * so with is_tracing() == 0 (and that is reset
+				 * when executing syscalls, since UML kernel has
+				 * the right to do syscalls);
+				 */
 				case OP_TRACE_ON:
 					arch_leave_kernel(task, pid);
 					tracing = 1;
@@ -314,7 +330,13 @@
 				case OP_HALT:
 					unmap_physmem();
 					kmalloc_ok = 0;
-					ptrace(PTRACE_KILL, pid, 0, 0);
+					os_kill_ptraced_process(pid, 0);
+					/* Now let's reap remaining zombies */
+					errno = 0;
+					do {
+						waitpid(-1, &status,
+							WUNTRACED);
+					} while (errno != ECHILD);
 					return(op == OP_REBOOT);
 				case OP_NONE:
 					printf("Detaching pid %d\n", pid);
@@ -328,14 +350,26 @@
 				 */
 				pid = cpu_tasks[proc_id].pid;
 				break;
+			case (SIGTRAP + 0x80):
+				if(!tracing && (debugger_pid != -1)){
+					child_signal(pid, status & 0x7fff);
+					continue;
+				}
+				tracing = 0;
+				/* local_using_sysemu has been already set
+				 * below, since if we are here, is_tracing() on
+				 * the traced task was 1, i.e. the process had
+				 * already run through one iteration of the
+				 * loop which executed a OP_TRACE_ON request.*/
+				do_syscall(task, pid, local_using_sysemu);
+				sig = SIGUSR2;
+				break;
 			case SIGTRAP:
 				if(!tracing && (debugger_pid != -1)){
 					child_signal(pid, status);
 					continue;
 				}
 				tracing = 0;
-				if(do_syscall(task, pid, local_using_sysemu))
-					sig = SIGUSR2;
 				break;
 			case SIGPROF:
 				if(tracing) sig = 0;
@@ -371,16 +405,15 @@
 				continue;
 			}
 
-			if(tracing){
-				if(singlestepping(task))
-					cont_type = PTRACE_SINGLESTEP;
-				else cont_type = pt_syscall_parm;
-			}
-			else cont_type = PTRACE_CONT;
+			local_using_sysemu = get_using_sysemu();
 
-			if((cont_type == PTRACE_CONT) && 
-			   (debugger_pid != -1) && strace)
+			if(tracing)
+				cont_type = SELECT_PTRACE_OPERATION(local_using_sysemu,
+				                                    singlestepping(task));
+			else if((debugger_pid != -1) && strace)
 				cont_type = PTRACE_SYSCALL;
+			else
+				cont_type = PTRACE_CONT;
 
 			if(ptrace(cont_type, pid, 0, sig) != 0){
 				tracer_panic("ptrace failed to continue "
diff -Nru a/arch/um/kernel/tt/trap_user.c b/arch/um/kernel/tt/trap_user.c
--- a/arch/um/kernel/tt/trap_user.c	2005-03-01 23:38:58 -08:00
+++ b/arch/um/kernel/tt/trap_user.c	2005-03-01 23:38:58 -08:00
@@ -6,7 +6,6 @@
 #include <stdlib.h>
 #include <errno.h>
 #include <signal.h>
-#include <asm/sigcontext.h>
 #include "sysdep/ptrace.h"
 #include "signal_user.h"
 #include "user_util.h"
@@ -22,13 +21,6 @@
 	int save_errno = errno, is_user;
 
 	unprotect_kernel_mem();
-
-	/* This is done because to allow SIGSEGV to be delivered inside a SEGV
-	 * handler.  This can happen in copy_user, and if SEGV is disabled,
-	 * the process will die.
-	 */
-	if(sig == SIGSEGV)
-		change_sig(SIGSEGV, 1);
 
 	/* This is done because to allow SIGSEGV to be delivered inside a SEGV
 	 * handler.  This can happen in copy_user, and if SEGV is disabled,
diff -Nru a/arch/um/kernel/tt/uaccess.c b/arch/um/kernel/tt/uaccess.c
--- a/arch/um/kernel/tt/uaccess.c	2005-03-01 23:38:54 -08:00
+++ b/arch/um/kernel/tt/uaccess.c	2005-03-01 23:38:54 -08:00
@@ -6,7 +6,7 @@
 #include "linux/sched.h"
 #include "asm/uaccess.h"
 
-int copy_from_user_tt(void *to, const void *from, int n)
+int copy_from_user_tt(void *to, const void __user *from, int n)
 {
 	if(!access_ok_tt(VERIFY_READ, from, n))
 		return(n);
@@ -15,7 +15,7 @@
 				   &current->thread.fault_catcher));
 }
 
-int copy_to_user_tt(void *to, const void *from, int n)
+int copy_to_user_tt(void __user *to, const void *from, int n)
 {
 	if(!access_ok_tt(VERIFY_WRITE, to, n))
 		return(n);
@@ -24,7 +24,7 @@
 				 &current->thread.fault_catcher));
 }
 
-int strncpy_from_user_tt(char *dst, const char *src, int count)
+int strncpy_from_user_tt(char *dst, const char __user *src, int count)
 {
 	int n;
 
@@ -38,14 +38,14 @@
 	return(n);
 }
 
-int __clear_user_tt(void *mem, int len)
+int __clear_user_tt(void __user *mem, int len)
 {
 	return(__do_clear_user(mem, len,
 			       &current->thread.fault_addr,
 			       &current->thread.fault_catcher));
 }
 
-int clear_user_tt(void *mem, int len)
+int clear_user_tt(void __user *mem, int len)
 {
 	if(!access_ok_tt(VERIFY_WRITE, mem, len))
 		return(len);
@@ -54,7 +54,7 @@
 			       &current->thread.fault_catcher));
 }
 
-int strnlen_user_tt(const void *str, int len)
+int strnlen_user_tt(const void __user *str, int len)
 {
 	return(__do_strnlen_user(str, len,
 				 &current->thread.fault_addr,
diff -Nru a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
--- a/arch/um/kernel/um_arch.c	2005-03-01 23:39:09 -08:00
+++ b/arch/um/kernel/um_arch.c	2005-03-01 23:39:09 -08:00
@@ -17,6 +17,7 @@
 #include "linux/sysrq.h"
 #include "linux/seq_file.h"
 #include "linux/delay.h"
+#include "linux/module.h"
 #include "asm/page.h"
 #include "asm/pgtable.h"
 #include "asm/ptrace.h"
@@ -44,11 +45,6 @@
 	.ipi_pipe		= { -1, -1 }
 };
 
-/* Placeholder to make UML link until the vsyscall stuff is actually
- * implemented
- */
-void *__kernel_vsyscall;
-
 unsigned long thread_saved_pc(struct task_struct *task)
 {
 	return(os_process_pc(CHOOSE_MODE_PROC(thread_pid_tt, thread_pid_skas,
@@ -161,6 +157,8 @@
 {
 	printf("%s\n", system_utsname.release);
 	exit(0);
+
+	return 0;
 }
 
 __uml_setup("--version", uml_version_setup,
@@ -200,7 +198,7 @@
 );
 #endif
 
-int force_tt = 0;
+static int force_tt = 0;
 
 #if defined(CONFIG_MODE_TT) && defined(CONFIG_MODE_SKAS)
 #define DEFAULT_TT 0
@@ -261,6 +259,8 @@
  		p++;
  	}
 	exit(0);
+
+	return 0;
 }
 
 __uml_setup("--help", Usage,
@@ -300,6 +300,7 @@
 /* Set during early boot */
 unsigned long brk_start;
 unsigned long end_iomem;
+EXPORT_SYMBOL(end_iomem);
 
 #define MIN_VMALLOC (32 * 1024 * 1024)
 
@@ -318,6 +319,14 @@
 	if(have_root == 0) add_arg(saved_command_line, DEFAULT_COMMAND_LINE);
 
 	mode_tt = force_tt ? 1 : !can_do_skas();
+#ifndef CONFIG_MODE_TT
+	if (mode_tt) {
+		/*Since CONFIG_MODE_TT is #undef'ed, force_tt cannot be 1. So,
+		 * can_do_skas() returned 0, and the message is correct. */
+		printf("Support for TT mode is disabled, and no SKAS support is present on the host.\n");
+		exit(1);
+	}
+#endif
 	uml_start = CHOOSE_MODE_PROC(set_task_sizes_tt, set_task_sizes_skas, 0,
 				     &host_task_size, &task_size);
 
diff -Nru a/arch/um/kernel/umid.c b/arch/um/kernel/umid.c
--- a/arch/um/kernel/umid.c	2005-03-01 23:39:16 -08:00
+++ b/arch/um/kernel/umid.c	2005-03-01 23:39:16 -08:00
@@ -93,8 +93,8 @@
 	fd = os_open_file(file, of_create(of_excl(of_rdwr(OPENFLAGS()))), 
 			  0644);
 	if(fd < 0){
-		printf("Open of machine pid file \"%s\" failed - "
-		       "err = %d\n", file, -fd);
+		printf("Open of machine pid file \"%s\" failed: %s\n",
+		       file, strerror(-fd));
 		return 0;
 	}
 
@@ -248,7 +248,7 @@
 	strcpy(uml_dir, dir);
 	
 	if((mkdir(uml_dir, 0777) < 0) && (errno != EEXIST)){
-	        printf("Failed to mkdir %s - errno = %i\n", uml_dir, errno);
+	        printf("Failed to mkdir %s: %s\n", uml_dir, strerror(errno));
 		return(-1);
 	}
 	return 0;
@@ -265,8 +265,8 @@
 		strcat(tmp, "XXXXXX");
 		fd = mkstemp(tmp);
 		if(fd < 0){
-			(*printer)("make_umid - mkstemp failed, errno = %d\n",
-				   errno);
+			(*printer)("make_umid - mkstemp(%s) failed: %s\n",
+				   tmp,strerror(errno));
 			return(1);
 		}
 
@@ -304,15 +304,14 @@
 "    The location to place the pid and umid files.\n\n"
 );
 
-__uml_postsetup(make_uml_dir);
-
 static int __init make_umid_setup(void)
 {
-	return(make_umid(printf));
+	/* one function with the ordering we need ... */
+	make_uml_dir();
+	make_umid(printf);
+	return create_pid_file();
 }
-
 __uml_postsetup(make_umid_setup);
-__uml_postsetup(create_pid_file);
 
 /*
  * Overrides for Emacs so that we follow Linus's tabbing style.
diff -Nru a/arch/um/kernel/uml.lds.S b/arch/um/kernel/uml.lds.S
--- a/arch/um/kernel/uml.lds.S	2005-03-01 23:38:56 -08:00
+++ b/arch/um/kernel/uml.lds.S	2005-03-01 23:38:56 -08:00
@@ -7,8 +7,12 @@
 
 SECTIONS
 {
+  /*This must contain the right address - not quite the default ELF one.*/
+  PROVIDE (__executable_start = START);
   . = START + SIZEOF_HEADERS;
 
+  /* Used in arch/um/kernel/mem.c. Any memory between START and __binary_start
+   * is remapped.*/
   __binary_start = .;
 #ifdef MODE_TT
   .thread_private : {
@@ -20,9 +24,13 @@
   }
   . = ALIGN(4096);
   .remap : { arch/um/kernel/tt/unmap_fin.o (.text) }
-#endif
+
+  /* We want it only if we are in MODE_TT. In both cases, however, when MODE_TT
+   * is off the resulting binary segfaults.*/
 
   . = ALIGN(4096);		/* Init code and data */
+#endif
+
   _stext = .;
   __init_begin = .;
   .init.text : {
diff -Nru a/arch/um/os-Linux/Makefile b/arch/um/os-Linux/Makefile
--- a/arch/um/os-Linux/Makefile	2005-03-01 23:38:58 -08:00
+++ b/arch/um/os-Linux/Makefile	2005-03-01 23:38:58 -08:00
@@ -3,9 +3,13 @@
 # Licensed under the GPL
 #
 
-obj-y = file.o process.o time.o tty.o user_syms.o drivers/
+obj-y = elf_aux.o file.o process.o signal.o time.o tty.o user_syms.o drivers/ \
+	sys-$(SUBARCH)/
 
-USER_OBJS := $(foreach file,file.o process.o time.o tty.o,$(obj)/$(file))
+USER_OBJS := elf_aux.o file.o process.o signal.o time.o tty.o
+USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
 
 $(USER_OBJS) : %.o: %.c
 	$(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
+
+CFLAGS_user_syms.o += -DSUBARCH_$(SUBARCH)
diff -Nru a/arch/um/os-Linux/elf_aux.c b/arch/um/os-Linux/elf_aux.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/um/os-Linux/elf_aux.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,66 @@
+/*
+ *  arch/um/kernel/elf_aux.c
+ *
+ *  Scan the Elf auxiliary vector provided by the host to extract
+ *  information about vsyscall-page, etc.
+ *
+ *  Copyright (C) 2004 Fujitsu Siemens Computers GmbH
+ *  Author: Bodo Stroesser (bodo.stroesser@fujitsu-siemens.com)
+ */
+#include <elf.h>
+#include <stddef.h>
+#include "init.h"
+#include "elf_user.h"
+
+#if ELF_CLASS == ELFCLASS32
+typedef Elf32_auxv_t elf_auxv_t;
+#else
+typedef Elf64_auxv_t elf_auxv_t;
+#endif
+
+char * elf_aux_platform;
+long elf_aux_hwcap;
+
+unsigned long vsyscall_ehdr;
+unsigned long vsyscall_end;
+
+unsigned long __kernel_vsyscall;
+
+__init void scan_elf_aux( char **envp)
+{
+	long page_size = 0;
+	elf_auxv_t * auxv;
+
+	while ( *envp++ != NULL) ;
+
+	for ( auxv = (elf_auxv_t *)envp; auxv->a_type != AT_NULL; auxv++) {
+		switch ( auxv->a_type ) {
+			case AT_SYSINFO:
+				__kernel_vsyscall = auxv->a_un.a_val;
+				break;
+			case AT_SYSINFO_EHDR:
+				vsyscall_ehdr = auxv->a_un.a_val;
+				break;
+			case AT_HWCAP:
+				elf_aux_hwcap = auxv->a_un.a_val;
+				break;
+			case AT_PLATFORM:
+				elf_aux_platform = auxv->a_un.a_ptr;
+				break;
+			case AT_PAGESZ:
+				page_size = auxv->a_un.a_val;
+				break;
+		}
+	}
+	if ( ! __kernel_vsyscall || ! vsyscall_ehdr ||
+	     ! elf_aux_hwcap || ! elf_aux_platform ||
+	     ! page_size || (vsyscall_ehdr % page_size) ) {
+		__kernel_vsyscall = 0;
+		vsyscall_ehdr = 0;
+		elf_aux_hwcap = 0;
+		elf_aux_platform = "i586";
+	}
+	else {
+		vsyscall_end = vsyscall_ehdr + page_size;
+	}
+}
diff -Nru a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c
--- a/arch/um/os-Linux/process.c	2005-03-01 23:38:52 -08:00
+++ b/arch/um/os-Linux/process.c	2005-03-01 23:38:52 -08:00
@@ -95,9 +95,16 @@
 		
 }
 
+/* Kill off a ptraced child by all means available.  kill it normally first,
+ * then PTRACE_KILL it, then PTRACE_CONT it in case it's in a run state from
+ * which it can't exit directly.
+ */
+
 void os_kill_ptraced_process(int pid, int reap_child)
 {
+	kill(pid, SIGKILL);
 	ptrace(PTRACE_KILL, pid);
+	ptrace(PTRACE_CONT, pid);
 	if(reap_child)
 		CATCH_EINTR(waitpid(pid, NULL, 0));
 }
diff -Nru a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/um/os-Linux/signal.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2004 PathScale, Inc
+ * Licensed under the GPL
+ */
+
+#include <signal.h>
+#include "time_user.h"
+#include "mode.h"
+#include "sysdep/signal.h"
+
+void sig_handler(int sig)
+{
+	struct sigcontext *sc;
+
+	ARCH_GET_SIGCONTEXT(sc, sig);
+	CHOOSE_MODE_PROC(sig_handler_common_tt, sig_handler_common_skas,
+			 sig, sc);
+}
+
+extern int timer_irq_inited;
+
+void alarm_handler(int sig)
+{
+	struct sigcontext *sc;
+
+	ARCH_GET_SIGCONTEXT(sc, sig);
+	if(!timer_irq_inited) return;
+
+	if(sig == SIGALRM)
+		switch_timers(0);
+
+	CHOOSE_MODE_PROC(sig_handler_common_tt, sig_handler_common_skas,
+			 sig, sc);
+
+	if(sig == SIGALRM)
+		switch_timers(1);
+}
+
+/*
+ * 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 -Nru a/arch/um/os-Linux/sys-i386/Makefile b/arch/um/os-Linux/sys-i386/Makefile
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/um/os-Linux/sys-i386/Makefile	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,11 @@
+#
+# Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
+# Licensed under the GPL
+#
+
+obj-$(CONFIG_MODE_SKAS) = registers.o
+
+USER_OBJS := $(foreach file,$(obj-y),$(obj)/$(file))
+
+$(USER_OBJS) : %.o: %.c
+	$(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
diff -Nru a/arch/um/os-Linux/sys-i386/registers.c b/arch/um/os-Linux/sys-i386/registers.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/um/os-Linux/sys-i386/registers.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2004 PathScale, Inc
+ * Licensed under the GPL
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <sys/ptrace.h>
+#include "sysdep/ptrace.h"
+#include "uml-config.h"
+#include "skas_ptregs.h"
+#include "registers.h"
+#include "user.h"
+
+/* These are set once at boot time and not changed thereafter */
+
+static unsigned long exec_regs[HOST_FRAME_SIZE];
+static unsigned long exec_fp_regs[HOST_FP_SIZE];
+static unsigned long exec_fpx_regs[HOST_XFP_SIZE];
+static int have_fpx_regs = 1;
+
+void init_thread_registers(union uml_pt_regs *to)
+{
+	memcpy(to->skas.regs, exec_regs, sizeof(to->skas.regs));
+	memcpy(to->skas.fp, exec_fp_regs, sizeof(to->skas.fp));
+	if(have_fpx_regs)
+		memcpy(to->skas.xfp, exec_fpx_regs, sizeof(to->skas.xfp));
+}
+
+static int move_registers(int pid, int int_op, union uml_pt_regs *regs,
+			  int fp_op, unsigned long *fp_regs)
+{
+	if(ptrace(int_op, pid, 0, regs->skas.regs) < 0)
+		return(-errno);
+
+	if(ptrace(fp_op, pid, 0, fp_regs) < 0)
+		return(-errno);
+
+	return(0);
+}
+
+void save_registers(int pid, union uml_pt_regs *regs)
+{
+	unsigned long *fp_regs;
+	int err, fp_op;
+
+	if(have_fpx_regs){
+		fp_op = PTRACE_GETFPXREGS;
+		fp_regs = regs->skas.xfp;
+	}
+	else {
+		fp_op = PTRACE_GETFPREGS;
+		fp_regs = regs->skas.fp;
+	}
+
+	err = move_registers(pid, PTRACE_GETREGS, regs, fp_op, fp_regs);
+	if(err)
+		panic("save_registers - saving registers failed, errno = %d\n",
+		      -err);
+}
+
+void restore_registers(int pid, union uml_pt_regs *regs)
+{
+	unsigned long *fp_regs;
+	int err, fp_op;
+
+	if(have_fpx_regs){
+		fp_op = PTRACE_SETFPXREGS;
+		fp_regs = regs->skas.xfp;
+	}
+	else {
+		fp_op = PTRACE_SETFPREGS;
+		fp_regs = regs->skas.fp;
+	}
+
+	err = move_registers(pid, PTRACE_SETREGS, regs, fp_op, fp_regs);
+	if(err)
+		panic("restore_registers - saving registers failed, "
+		      "errno = %d\n", -err);
+}
+
+void init_registers(int pid)
+{
+	int err;
+
+	err = ptrace(PTRACE_GETREGS, pid, 0, exec_regs);
+	if(err)
+		panic("check_ptrace : PTRACE_GETREGS failed, errno = %d",
+		      err);
+
+	err = ptrace(PTRACE_GETFPXREGS, pid, 0, exec_fpx_regs);
+	if(!err)
+		return;
+
+	have_fpx_regs = 0;
+	if(err != EIO)
+		panic("check_ptrace : PTRACE_GETFPXREGS failed, errno = %d",
+		      err);
+
+	err = ptrace(PTRACE_GETFPREGS, pid, 0, exec_fp_regs);
+	if(err)
+		panic("check_ptrace : PTRACE_GETFPREGS failed, errno = %d",
+		      err);
+}
+
+/*
+ * 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 -Nru a/arch/um/os-Linux/sys-x86_64/Makefile b/arch/um/os-Linux/sys-x86_64/Makefile
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/um/os-Linux/sys-x86_64/Makefile	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,11 @@
+#
+# Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
+# Licensed under the GPL
+#
+
+obj-$(CONFIG_MODE_SKAS) = registers.o
+
+USER_OBJS := $(foreach file,$(obj-y),$(obj)/$(file))
+
+$(USER_OBJS) : %.o: %.c
+	$(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
diff -Nru a/arch/um/os-Linux/sys-x86_64/registers.c b/arch/um/os-Linux/sys-x86_64/registers.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/um/os-Linux/sys-x86_64/registers.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2004 PathScale, Inc
+ * Licensed under the GPL
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <sys/ptrace.h>
+#include "sysdep/ptrace.h"
+#include "uml-config.h"
+#include "skas_ptregs.h"
+#include "registers.h"
+#include "user.h"
+
+/* These are set once at boot time and not changed thereafter */
+
+static unsigned long exec_regs[HOST_FRAME_SIZE];
+static unsigned long exec_fp_regs[HOST_FP_SIZE];
+
+void init_thread_registers(union uml_pt_regs *to)
+{
+	memcpy(to->skas.regs, exec_regs, sizeof(to->skas.regs));
+	memcpy(to->skas.fp, exec_fp_regs, sizeof(to->skas.fp));
+}
+
+static int move_registers(int pid, int int_op, int fp_op,
+			  union uml_pt_regs *regs)
+{
+	if(ptrace(int_op, pid, 0, regs->skas.regs) < 0)
+		return(-errno);
+
+	if(ptrace(fp_op, pid, 0, regs->skas.fp) < 0)
+		return(-errno);
+
+	return(0);
+}
+
+void save_registers(int pid, union uml_pt_regs *regs)
+{
+	int err;
+
+	err = move_registers(pid, PTRACE_GETREGS, PTRACE_GETFPREGS, regs);
+	if(err)
+		panic("save_registers - saving registers failed, errno = %d\n",
+		      -err);
+}
+
+void restore_registers(int pid, union uml_pt_regs *regs)
+{
+	int err;
+
+	err = move_registers(pid, PTRACE_SETREGS, PTRACE_SETFPREGS, regs);
+	if(err)
+		panic("restore_registers - saving registers failed, "
+		      "errno = %d\n", -err);
+}
+
+void init_registers(int pid)
+{
+	int err;
+
+	err = ptrace(PTRACE_GETREGS, pid, 0, exec_regs);
+	if(err)
+		panic("check_ptrace : PTRACE_GETREGS failed, errno = %d",
+		      err);
+
+	err = ptrace(PTRACE_GETFPREGS, pid, 0, exec_fp_regs);
+	if(err)
+		panic("check_ptrace : PTRACE_GETFPREGS failed, errno = %d",
+		      err);
+}
+
+/*
+ * 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 -Nru a/arch/um/os-Linux/user_syms.c b/arch/um/os-Linux/user_syms.c
--- a/arch/um/os-Linux/user_syms.c	2005-03-01 23:39:08 -08:00
+++ b/arch/um/os-Linux/user_syms.c	2005-03-01 23:39:08 -08:00
@@ -34,6 +34,11 @@
        int sym(void);                  \
        EXPORT_SYMBOL(sym);
 
+#ifdef SUBARCH_i386
+EXPORT_SYMBOL(vsyscall_ehdr);
+EXPORT_SYMBOL(vsyscall_end);
+#endif
+
 EXPORT_SYMBOL_PROTO(__errno_location);
 
 EXPORT_SYMBOL_PROTO(access);
diff -Nru a/arch/um/sys-i386/Makefile b/arch/um/sys-i386/Makefile
--- a/arch/um/sys-i386/Makefile	2005-03-01 23:38:53 -08:00
+++ b/arch/um/sys-i386/Makefile	2005-03-01 23:38:53 -08:00
@@ -1,5 +1,5 @@
-obj-y = bitops.o bugs.o checksum.o fault.o ksyms.o ldt.o ptrace.o \
-	ptrace_user.o semaphore.o sigcontext.o syscalls.o sysrq.o
+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
 
 obj-$(CONFIG_HIGHMEM) += highmem.o
 obj-$(CONFIG_MODULES) += module.o
diff -Nru a/arch/um/sys-i386/delay.c b/arch/um/sys-i386/delay.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/um/sys-i386/delay.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,14 @@
+void __delay(unsigned long time)
+{
+	/* Stolen from the i386 __loop_delay */
+	int d0;
+	__asm__ __volatile__(
+		"\tjmp 1f\n"
+		".align 16\n"
+		"1:\tjmp 2f\n"
+		".align 16\n"
+		"2:\tdecl %0\n\tjns 2b"
+		:"=&a" (d0)
+		:"0" (time));
+}
+
diff -Nru a/arch/um/sys-i386/ldt.c b/arch/um/sys-i386/ldt.c
--- a/arch/um/sys-i386/ldt.c	2005-03-01 23:38:57 -08:00
+++ b/arch/um/sys-i386/ldt.c	2005-03-01 23:38:57 -08:00
@@ -15,17 +15,21 @@
 
 /* XXX this needs copy_to_user and copy_from_user */
 
-int sys_modify_ldt_tt(int func, void *ptr, unsigned long bytecount)
+int sys_modify_ldt_tt(int func, void __user *ptr, unsigned long bytecount)
 {
-	if(verify_area(VERIFY_READ, ptr, bytecount)) return(-EFAULT);
-	return(modify_ldt(func, ptr, bytecount));
+	if (verify_area(VERIFY_READ, ptr, bytecount))
+		return -EFAULT;
+
+	return modify_ldt(func, ptr, bytecount);
 }
 #endif
 
 #ifdef CONFIG_MODE_SKAS
 extern int userspace_pid;
 
-int sys_modify_ldt_skas(int func, void *ptr, unsigned long bytecount)
+#include "skas_ptrace.h"
+
+int sys_modify_ldt_skas(int func, void __user *ptr, unsigned long bytecount)
 {
 	struct ptrace_ldt ldt;
 	void *buf;
@@ -74,7 +78,7 @@
 }
 #endif
 
-int sys_modify_ldt(int func, void *ptr, unsigned long bytecount)
+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));
diff -Nru a/arch/um/sys-i386/ptrace.c b/arch/um/sys-i386/ptrace.c
--- a/arch/um/sys-i386/ptrace.c	2005-03-01 23:39:08 -08:00
+++ b/arch/um/sys-i386/ptrace.c	2005-03-01 23:39:08 -08:00
@@ -3,6 +3,8 @@
  * Licensed under the GPL
  */
 
+#include <linux/config.h>
+#include <linux/compiler.h>
 #include "linux/sched.h"
 #include "asm/elf.h"
 #include "asm/ptrace.h"
@@ -22,7 +24,7 @@
 	unsigned short instr;
 	int n;
 
-	n = copy_from_user(&instr, (void *) addr, sizeof(instr));
+	n = copy_from_user(&instr, (void __user *) addr, sizeof(instr));
 	if(n){
 		printk("is_syscall : failed to read instruction from 0x%lx\n",
 		       addr);
@@ -175,12 +177,12 @@
  */
 
 #ifdef CONFIG_MODE_TT
-static inline int convert_fxsr_to_user_tt(struct _fpstate *buf, 
+static inline int convert_fxsr_to_user_tt(struct _fpstate __user *buf,
 					  struct pt_regs *regs)
 {
 	struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs));
 	unsigned long env[7];
-	struct _fpreg *to;
+	struct _fpreg __user *to;
 	struct _fpxreg *from;
 	int i;
 
@@ -205,7 +207,7 @@
 }
 #endif
 
-static inline int convert_fxsr_to_user(struct _fpstate *buf, 
+static inline int convert_fxsr_to_user(struct _fpstate __user *buf,
 				       struct pt_regs *regs)
 {
 	return(CHOOSE_MODE(convert_fxsr_to_user_tt(buf, regs), 0));
@@ -213,12 +215,12 @@
 
 #ifdef CONFIG_MODE_TT
 static inline int convert_fxsr_from_user_tt(struct pt_regs *regs,
-					    struct _fpstate *buf)
+					    struct _fpstate __user *buf)
 {
 	struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs));
 	unsigned long env[7];
 	struct _fpxreg *to;
-	struct _fpreg *from;
+	struct _fpreg __user *from;
 	int i;
 
 	if ( __copy_from_user( env, buf, 7 * sizeof(long) ) )
@@ -244,7 +246,7 @@
 #endif
 
 static inline int convert_fxsr_from_user(struct pt_regs *regs, 
-					 struct _fpstate *buf)
+					 struct _fpstate __user *buf)
 {
 	return(CHOOSE_MODE(convert_fxsr_from_user_tt(regs, buf), 0));
 }
@@ -253,7 +255,7 @@
 {
 	int err;
 
-	err = convert_fxsr_to_user((struct _fpstate *) buf, 
+	err = convert_fxsr_to_user((struct _fpstate __user *) buf,
 				   &child->thread.regs);
 	if(err) return(-EFAULT);
 	else return(0);
@@ -264,7 +266,7 @@
 	int err;
 
 	err = convert_fxsr_from_user(&child->thread.regs, 
-				     (struct _fpstate *) buf);
+				     (struct _fpstate __user *) buf);
 	if(err) return(-EFAULT);
 	else return(0);
 }
@@ -276,7 +278,7 @@
 	struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs));
 	int err;
 
-	err = __copy_to_user((void *) buf, fxsave,
+	err = __copy_to_user((void __user *) buf, fxsave,
 			     sizeof(struct user_fxsr_struct));
 	if(err) return -EFAULT;
 	else return 0;
@@ -295,7 +297,7 @@
 	struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs));
 	int err;
 
-	err = __copy_from_user(fxsave, (void *) buf,
+	err = __copy_from_user(fxsave, (void __user *) buf,
 			       sizeof(struct user_fxsr_struct) );
 	if(err) return -EFAULT;
 	else return 0;
diff -Nru a/arch/um/sys-i386/ptrace_user.c b/arch/um/sys-i386/ptrace_user.c
--- a/arch/um/sys-i386/ptrace_user.c	2005-03-01 23:39:18 -08:00
+++ b/arch/um/sys-i386/ptrace_user.c	2005-03-01 23:39:18 -08:00
@@ -17,17 +17,30 @@
 
 int ptrace_getregs(long pid, unsigned long *regs_out)
 {
-	return(ptrace(PTRACE_GETREGS, pid, 0, regs_out));
+	if (ptrace(PTRACE_GETREGS, pid, 0, regs_out) < 0)
+		return -errno;
+	return 0;
 }
 
 int ptrace_setregs(long pid, unsigned long *regs)
 {
-	return(ptrace(PTRACE_SETREGS, pid, 0, regs));
+	if (ptrace(PTRACE_SETREGS, pid, 0, regs) < 0)
+		return -errno;
+	return 0;
 }
 
 int ptrace_getfpregs(long pid, unsigned long *regs)
 {
-	return(ptrace(PTRACE_GETFPREGS, pid, 0, regs));
+	if (ptrace(PTRACE_GETFPREGS, pid, 0, regs) < 0)
+		return -errno;
+	return 0;
+}
+
+int ptrace_setfpregs(long pid, unsigned long *regs)
+{
+	if (ptrace(PTRACE_SETFPREGS, pid, 0, regs) < 0)
+		return -errno;
+	return 0;
 }
 
 static void write_debugregs(int pid, unsigned long *regs)
diff -Nru a/arch/um/sys-i386/sigcontext.c b/arch/um/sys-i386/sigcontext.c
--- a/arch/um/sys-i386/sigcontext.c	2005-03-01 23:38:51 -08:00
+++ b/arch/um/sys-i386/sigcontext.c	2005-03-01 23:38:51 -08:00
@@ -9,29 +9,20 @@
 #include <asm/sigcontext.h>
 #include "sysdep/ptrace.h"
 #include "kern_util.h"
-#include "frame_user.h"
-
-int sc_size(void *data)
-{
-	struct arch_frame_data *arch = data;
-
-	return(sizeof(struct sigcontext) + arch->fpstate_size);
-}
 
 void sc_to_sc(void *to_ptr, void *from_ptr)
 {
 	struct sigcontext *to = to_ptr, *from = from_ptr;
-	int size = sizeof(*to) + signal_frame_sc.common.arch.fpstate_size;
 
-	memcpy(to, from, size);
-	if(from->fpstate != NULL) to->fpstate = (struct _fpstate *) (to + 1);
+	memcpy(to, from, sizeof(*to) + sizeof(struct _fpstate));
+	if(from->fpstate != NULL)
+		to->fpstate = (struct _fpstate *) (to + 1);
 }
 
 unsigned long *sc_sigmask(void *sc_ptr)
 {
 	struct sigcontext *sc = sc_ptr;
-
-	return(&sc->oldmask);
+	return &sc->oldmask;
 }
 
 int sc_get_fpregs(unsigned long buf, void *sc_ptr)
diff -Nru a/arch/um/sys-i386/signal.c b/arch/um/sys-i386/signal.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/um/sys-i386/signal.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,376 @@
+/*
+ * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com)
+ * Licensed under the GPL
+ */
+
+#include "linux/signal.h"
+#include "linux/ptrace.h"
+#include "asm/current.h"
+#include "asm/ucontext.h"
+#include "asm/uaccess.h"
+#include "asm/unistd.h"
+#include "frame_kern.h"
+#include "signal_user.h"
+#include "ptrace_user.h"
+#include "sigcontext.h"
+#include "mode.h"
+
+#ifdef CONFIG_MODE_SKAS
+
+#include "skas.h"
+
+static int copy_sc_from_user_skas(struct pt_regs *regs,
+				  struct sigcontext *from)
+{
+  	struct sigcontext sc;
+	unsigned long fpregs[HOST_FP_SIZE];
+	int err;
+
+	err = copy_from_user(&sc, from, sizeof(sc));
+	err |= copy_from_user(fpregs, sc.fpstate, sizeof(fpregs));
+	if(err)
+		return(err);
+
+	REGS_GS(regs->regs.skas.regs) = sc.gs;
+	REGS_FS(regs->regs.skas.regs) = sc.fs;
+	REGS_ES(regs->regs.skas.regs) = sc.es;
+	REGS_DS(regs->regs.skas.regs) = sc.ds;
+	REGS_EDI(regs->regs.skas.regs) = sc.edi;
+	REGS_ESI(regs->regs.skas.regs) = sc.esi;
+	REGS_EBP(regs->regs.skas.regs) = sc.ebp;
+	REGS_SP(regs->regs.skas.regs) = sc.esp;
+	REGS_EBX(regs->regs.skas.regs) = sc.ebx;
+	REGS_EDX(regs->regs.skas.regs) = sc.edx;
+	REGS_ECX(regs->regs.skas.regs) = sc.ecx;
+	REGS_EAX(regs->regs.skas.regs) = sc.eax;
+	REGS_IP(regs->regs.skas.regs) = sc.eip;
+	REGS_CS(regs->regs.skas.regs) = sc.cs;
+	REGS_EFLAGS(regs->regs.skas.regs) = sc.eflags;
+	REGS_SS(regs->regs.skas.regs) = sc.ss;
+	regs->regs.skas.fault_addr = sc.cr2;
+	regs->regs.skas.fault_type = FAULT_WRITE(sc.err);
+	regs->regs.skas.trap_type = sc.trapno;
+
+	err = ptrace_setfpregs(userspace_pid[0], fpregs);
+	if(err < 0){
+	  	printk("copy_sc_from_user_skas - PTRACE_SETFPREGS failed, "
+		       "errno = %d\n", err);
+		return(1);
+	}
+
+	return(0);
+}
+
+int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate *to_fp,
+			 struct pt_regs *regs, unsigned long fault_addr,
+			 int fault_type)
+{
+  	struct sigcontext sc;
+	unsigned long fpregs[HOST_FP_SIZE];
+	int err;
+
+	sc.gs = REGS_GS(regs->regs.skas.regs);
+	sc.fs = REGS_FS(regs->regs.skas.regs);
+	sc.es = REGS_ES(regs->regs.skas.regs);
+	sc.ds = REGS_DS(regs->regs.skas.regs);
+	sc.edi = REGS_EDI(regs->regs.skas.regs);
+	sc.esi = REGS_ESI(regs->regs.skas.regs);
+	sc.ebp = REGS_EBP(regs->regs.skas.regs);
+	sc.esp = REGS_SP(regs->regs.skas.regs);
+	sc.ebx = REGS_EBX(regs->regs.skas.regs);
+	sc.edx = REGS_EDX(regs->regs.skas.regs);
+	sc.ecx = REGS_ECX(regs->regs.skas.regs);
+	sc.eax = REGS_EAX(regs->regs.skas.regs);
+	sc.eip = REGS_IP(regs->regs.skas.regs);
+	sc.cs = REGS_CS(regs->regs.skas.regs);
+	sc.eflags = REGS_EFLAGS(regs->regs.skas.regs);
+	sc.esp_at_signal = regs->regs.skas.regs[UESP];
+	sc.ss = regs->regs.skas.regs[SS];
+	sc.cr2 = fault_addr;
+	sc.err = TO_SC_ERR(fault_type);
+	sc.trapno = regs->regs.skas.trap_type;
+
+	err = ptrace_getfpregs(userspace_pid[0], fpregs);
+	if(err < 0){
+	  	printk("copy_sc_to_user_skas - PTRACE_GETFPREGS failed, "
+		       "errno = %d\n", err);
+		return(1);
+	}
+	to_fp = (to_fp ? to_fp : (struct _fpstate *) (to + 1));
+	sc.fpstate = to_fp;
+
+	if(err)
+	  	return(err);
+
+	return(copy_to_user(to, &sc, sizeof(sc)) ||
+	       copy_to_user(to_fp, fpregs, sizeof(fpregs)));
+}
+#endif
+
+#ifdef CONFIG_MODE_TT
+int copy_sc_from_user_tt(struct sigcontext *to, struct sigcontext *from,
+			 int fpsize)
+{
+	struct _fpstate *to_fp, *from_fp;
+	unsigned long sigs;
+	int err;
+
+	to_fp = to->fpstate;
+	from_fp = from->fpstate;
+	sigs = to->oldmask;
+	err = copy_from_user(to, from, sizeof(*to));
+	to->oldmask = sigs;
+	if(to_fp != NULL){
+		err |= copy_from_user(&to->fpstate, &to_fp,
+				      sizeof(to->fpstate));
+		err |= copy_from_user(to_fp, from_fp, fpsize);
+	}
+	return(err);
+}
+
+int copy_sc_to_user_tt(struct sigcontext *to, struct _fpstate *fp,
+		       struct sigcontext *from, int fpsize)
+{
+	struct _fpstate *to_fp, *from_fp;
+	int err;
+
+	to_fp =	(fp ? fp : (struct _fpstate *) (to + 1));
+	from_fp = from->fpstate;
+	err = copy_to_user(to, from, sizeof(*to));
+	if(from_fp != NULL){
+		err |= copy_to_user(&to->fpstate, &to_fp,
+					 sizeof(to->fpstate));
+		err |= copy_to_user(to_fp, from_fp, fpsize);
+	}
+	return(err);
+}
+#endif
+
+static int copy_sc_from_user(struct pt_regs *to, void __user *from)
+{
+	int ret;
+
+	ret = CHOOSE_MODE(copy_sc_from_user_tt(UPT_SC(&to->regs), from,
+					       sizeof(struct _fpstate)),
+			  copy_sc_from_user_skas(to, from));
+	return(ret);
+}
+
+static int copy_sc_to_user(struct sigcontext *to, struct _fpstate *fp,
+			   struct pt_regs *from)
+{
+	return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs),
+					      sizeof(*fp)),
+			   copy_sc_to_user_skas(to, fp, from,
+						current->thread.cr2,
+						current->thread.err)));
+}
+
+static int copy_ucontext_to_user(struct ucontext *uc, struct _fpstate *fp,
+				 sigset_t *set, unsigned long sp)
+{
+	int err = 0;
+
+	err |= put_user(current->sas_ss_sp, &uc->uc_stack.ss_sp);
+	err |= put_user(sas_ss_flags(sp), &uc->uc_stack.ss_flags);
+	err |= put_user(current->sas_ss_size, &uc->uc_stack.ss_size);
+	err |= copy_sc_to_user(&uc->uc_mcontext, fp, &current->thread.regs);
+	err |= copy_to_user(&uc->uc_sigmask, set, sizeof(*set));
+	return(err);
+}
+
+struct sigframe
+{
+	char *pretcode;
+	int sig;
+	struct sigcontext sc;
+	struct _fpstate fpstate;
+	unsigned long extramask[_NSIG_WORDS-1];
+	char retcode[8];
+};
+
+struct rt_sigframe
+{
+	char *pretcode;
+	int sig;
+	struct siginfo *pinfo;
+	void *puc;
+	struct siginfo info;
+	struct ucontext uc;
+	struct _fpstate fpstate;
+	char retcode[8];
+};
+
+int setup_signal_stack_sc(unsigned long stack_top, int sig,
+			  struct k_sigaction *ka, struct pt_regs *regs,
+			  sigset_t *mask)
+{
+	struct sigframe __user *frame;
+	void *restorer;
+	int err = 0;
+
+	stack_top &= -8UL;
+	frame = (struct sigframe *) stack_top - 1;
+	if(verify_area(VERIFY_WRITE, frame, sizeof(*frame)))
+		return(1);
+
+	restorer = (void *) frame->retcode;
+	if(ka->sa.sa_flags & SA_RESTORER)
+		restorer = ka->sa.sa_restorer;
+
+	err |= __put_user(restorer, &frame->pretcode);
+	err |= __put_user(sig, &frame->sig);
+	err |= copy_sc_to_user(&frame->sc, NULL, regs);
+	err |= __put_user(mask->sig[0], &frame->sc.oldmask);
+	if (_NSIG_WORDS > 1)
+		err |= __copy_to_user(&frame->extramask, &mask->sig[1],
+				      sizeof(frame->extramask));
+
+	/*
+	 * This is popl %eax ; movl $,%eax ; int $0x80
+	 *
+	 * 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(0xb858, (short __user *)(frame->retcode+0));
+	err |= __put_user(__NR_sigreturn, (int __user *)(frame->retcode+2));
+	err |= __put_user(0x80cd, (short __user *)(frame->retcode+6));
+
+	if(err)
+		return(err);
+
+	PT_REGS_SP(regs) = (unsigned long) frame;
+	PT_REGS_IP(regs) = (unsigned long) ka->sa.sa_handler;
+	PT_REGS_EAX(regs) = (unsigned long) sig;
+	PT_REGS_EDX(regs) = (unsigned long) 0;
+	PT_REGS_ECX(regs) = (unsigned long) 0;
+
+	if ((current->ptrace & PT_DTRACE) && (current->ptrace & PT_PTRACED))
+		ptrace_notify(SIGTRAP);
+	return(0);
+}
+
+int setup_signal_stack_si(unsigned long stack_top, int sig,
+			  struct k_sigaction *ka, struct pt_regs *regs,
+			  siginfo_t *info, sigset_t *mask)
+{
+	struct rt_sigframe __user *frame;
+	void *restorer;
+	int err = 0;
+
+	stack_top &= -8UL;
+	frame = (struct rt_sigframe *) stack_top - 1;
+	if(verify_area(VERIFY_WRITE, frame, sizeof(*frame)))
+		return(1);
+
+	restorer = (void *) frame->retcode;
+	if(ka->sa.sa_flags & SA_RESTORER)
+		restorer = ka->sa.sa_restorer;
+
+	err |= __put_user(restorer, &frame->pretcode);
+	err |= __put_user(sig, &frame->sig);
+	err |= __put_user(&frame->info, &frame->pinfo);
+	err |= __put_user(&frame->uc, &frame->puc);
+	err |= copy_siginfo_to_user(&frame->info, info);
+	err |= copy_ucontext_to_user(&frame->uc, &frame->fpstate, mask,
+				     PT_REGS_SP(regs));
+
+	/*
+	 * This is movl $,%eax ; int $0x80
+	 *
+	 * 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(0xb8, (char __user *)(frame->retcode+0));
+	err |= __put_user(__NR_rt_sigreturn, (int __user *)(frame->retcode+1));
+	err |= __put_user(0x80cd, (short __user *)(frame->retcode+5));
+
+	if(err)
+		return(err);
+
+	PT_REGS_SP(regs) = (unsigned long) frame;
+	PT_REGS_IP(regs) = (unsigned long) ka->sa.sa_handler;
+	PT_REGS_EAX(regs) = (unsigned long) sig;
+	PT_REGS_EDX(regs) = (unsigned long) &frame->info;
+	PT_REGS_ECX(regs) = (unsigned long) &frame->uc;
+
+	if ((current->ptrace & PT_DTRACE) && (current->ptrace & PT_PTRACED))
+		ptrace_notify(SIGTRAP);
+	return(0);
+}
+
+long sys_sigreturn(struct pt_regs regs)
+{
+	unsigned long __user sp = PT_REGS_SP(&current->thread.regs);
+	struct sigframe __user *frame = (struct sigframe *)(sp - 8);
+	sigset_t set;
+	struct sigcontext __user *sc = &frame->sc;
+	unsigned long __user *oldmask = &sc->oldmask;
+	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])) ||
+	   copy_from_user(&set.sig[1], extramask, sig_size))
+		goto segfault;
+
+	sigdelsetmask(&set, ~_BLOCKABLE);
+
+	spin_lock_irq(&current->sighand->siglock);
+	current->blocked = set;
+	recalc_sigpending();
+	spin_unlock_irq(&current->sighand->siglock);
+
+	if(copy_sc_from_user(&current->thread.regs, sc))
+		goto segfault;
+
+	/* Avoid ERESTART handling */
+	PT_REGS_SYSCALL_NR(&current->thread.regs) = -1;
+	return(PT_REGS_SYSCALL_RET(&current->thread.regs));
+
+ segfault:
+	force_sig(SIGSEGV, current);
+	return 0;
+}
+
+long sys_rt_sigreturn(struct pt_regs regs)
+{
+	unsigned long __user sp = PT_REGS_SP(&current->thread.regs);
+	struct rt_sigframe __user *frame = (struct rt_sigframe *) (sp - 4);
+	sigset_t set;
+	struct ucontext __user *uc = &frame->uc;
+	int sig_size = _NSIG_WORDS * sizeof(unsigned long);
+
+	if(copy_from_user(&set, &uc->uc_sigmask, sig_size))
+		goto segfault;
+
+	sigdelsetmask(&set, ~_BLOCKABLE);
+
+	spin_lock_irq(&current->sighand->siglock);
+	current->blocked = set;
+	recalc_sigpending();
+	spin_unlock_irq(&current->sighand->siglock);
+
+	if(copy_sc_from_user(&current->thread.regs, &uc->uc_mcontext))
+		goto segfault;
+
+	/* Avoid ERESTART handling */
+	PT_REGS_SYSCALL_NR(&current->thread.regs) = -1;
+	return(PT_REGS_SYSCALL_RET(&current->thread.regs));
+
+ segfault:
+	force_sig(SIGSEGV, current);
+	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 -Nru a/arch/um/sys-i386/syscalls.c b/arch/um/sys-i386/syscalls.c
--- a/arch/um/sys-i386/syscalls.c	2005-03-01 23:38:57 -08:00
+++ b/arch/um/sys-i386/syscalls.c	2005-03-01 23:38:57 -08:00
@@ -1,9 +1,11 @@
 /* 
- * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
  * Licensed under the GPL
  */
 
 #include "linux/sched.h"
+#include "linux/shm.h"
+#include "asm/ipc.h"
 #include "asm/mman.h"
 #include "asm/uaccess.h"
 #include "asm/unistd.h"
@@ -28,7 +30,7 @@
 		    unsigned long prot, unsigned long flags,
 		    unsigned long fd, unsigned long offset);
 
-int old_mmap_i386(struct mmap_arg_struct *arg)
+long old_mmap_i386(struct mmap_arg_struct __user *arg)
 {
 	struct mmap_arg_struct a;
 	int err = -EFAULT;
@@ -43,11 +45,13 @@
 
 struct sel_arg_struct {
 	unsigned long n;
-	fd_set *inp, *outp, *exp;
-	struct timeval *tvp;
+	fd_set __user *inp;
+	fd_set __user *outp;
+	fd_set __user *exp;
+	struct timeval __user *tvp;
 };
 
-int old_select(struct sel_arg_struct *arg)
+long old_select(struct sel_arg_struct __user *arg)
 {
 	struct sel_arg_struct a;
 
@@ -60,8 +64,8 @@
 /* The i386 version skips reading from %esi, the fourth argument. So we must do
  * this, too.
  */
-int sys_clone(unsigned long clone_flags, unsigned long newsp, int *parent_tid,
-	      int unused, int *child_tid)
+long sys_clone(unsigned long clone_flags, unsigned long newsp,
+	       int __user *parent_tid, int unused, int __user *child_tid)
 {
 	long ret;
 
@@ -76,6 +80,122 @@
 	ret = do_fork(clone_flags, newsp, NULL, 0, parent_tid, child_tid);
 	current->thread.forking = 0;
 	return(ret);
+}
+
+/*
+ * sys_ipc() is the de-multiplexer for the SysV IPC calls..
+ *
+ * This is really horribly ugly.
+ */
+long sys_ipc (uint call, int first, int second,
+	     int third, void *__user ptr, long fifth)
+{
+	int version, ret;
+
+	version = call >> 16; /* hack for backward compatibility */
+	call &= 0xffff;
+
+	switch (call) {
+	case SEMOP:
+		return sys_semtimedop(first, (struct sembuf *) ptr, second,
+				      NULL);
+	case SEMTIMEDOP:
+		return sys_semtimedop(first, (struct sembuf *) ptr, second,
+				      (const struct timespec *) fifth);
+	case SEMGET:
+		return sys_semget (first, second, third);
+	case SEMCTL: {
+		union semun fourth;
+		if (!ptr)
+			return -EINVAL;
+		if (get_user(fourth.__pad, (void **) ptr))
+			return -EFAULT;
+		return sys_semctl (first, second, third, fourth);
+	}
+
+	case MSGSND:
+		return sys_msgsnd (first, (struct msgbuf *) ptr,
+				   second, third);
+	case MSGRCV:
+		switch (version) {
+		case 0: {
+			struct ipc_kludge tmp;
+			if (!ptr)
+				return -EINVAL;
+
+			if (copy_from_user(&tmp,
+					   (struct ipc_kludge *) ptr,
+					   sizeof (tmp)))
+				return -EFAULT;
+			return sys_msgrcv (first, tmp.msgp, second,
+					   tmp.msgtyp, third);
+		}
+		default:
+		        panic("msgrcv with version != 0");
+			return sys_msgrcv (first,
+					   (struct msgbuf *) ptr,
+					   second, fifth, third);
+		}
+	case MSGGET:
+		return sys_msgget ((key_t) first, second);
+	case MSGCTL:
+		return sys_msgctl (first, second, (struct msqid_ds *) ptr);
+
+	case SHMAT:
+		switch (version) {
+		default: {
+			ulong raddr;
+			ret = do_shmat (first, (char *) ptr, second, &raddr);
+			if (ret)
+				return ret;
+			return put_user (raddr, (ulong *) third);
+		}
+		case 1:	/* iBCS2 emulator entry point */
+			if (!segment_eq(get_fs(), get_ds()))
+				return -EINVAL;
+			return do_shmat (first, (char *) ptr, second, (ulong *) third);
+		}
+	case SHMDT:
+		return sys_shmdt ((char *)ptr);
+	case SHMGET:
+		return sys_shmget (first, second, third);
+	case SHMCTL:
+		return sys_shmctl (first, second,
+				   (struct shmid_ds *) ptr);
+	default:
+		return -ENOSYS;
+	}
+}
+
+long sys_sigaction(int sig, const struct old_sigaction __user *act,
+			 struct old_sigaction __user *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;
 }
 
 /*
diff -Nru a/arch/um/sys-x86_64/Makefile b/arch/um/sys-x86_64/Makefile
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/um/sys-x86_64/Makefile	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,39 @@
+#
+# Copyright 2003 PathScale, Inc.
+#
+# Licensed under the GPL
+#
+
+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
+
+USER_OBJS := ptrace_user.o sigcontext.o
+USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
+
+SYMLINKS = bitops.c csum-copy.S csum-partial.c csum-wrappers.c memcpy.S \
+	semaphore.c thunk.S
+SYMLINKS := $(foreach f,$(SYMLINKS),$(src)/$f)
+
+clean-files := $(SYMLINKS)
+
+bitops.c-dir = lib
+csum-copy.S-dir = lib
+csum-partial.c-dir = lib
+csum-wrappers.c-dir = lib
+memcpy.S-dir = lib
+semaphore.c-dir = kernel
+thunk.S-dir = lib
+
+define make_link
+       -rm -f $1
+       ln -sf $(TOPDIR)/arch/x86_64/$($(notdir $1)-dir)/$(notdir $1) $1
+endef
+
+$(SYMLINKS):
+	$(call make_link,$@)
+
+$(USER_OBJS) : %.o: %.c
+	$(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
+
+CFLAGS_csum-partial.o := -Dcsum_partial=arch_csum_partial
diff -Nru a/arch/um/sys-x86_64/bugs.c b/arch/um/sys-x86_64/bugs.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/um/sys-x86_64/bugs.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2003 PathScale, Inc.
+ *
+ * Licensed under the GPL
+ */
+
+#include "linux/sched.h"
+#include "linux/errno.h"
+#include "asm/system.h"
+#include "asm/pda.h"
+#include "sysdep/ptrace.h"
+#include "os.h"
+
+void arch_init_thread(void)
+{
+}
+
+void arch_check_bugs(void)
+{
+}
+
+int arch_handle_signal(int sig, union uml_pt_regs *regs)
+{
+	return(0);
+}
+
+#define MAXTOKEN 64
+
+/* Set during early boot */
+int host_has_cmov = 1;
+int host_has_xmm = 0;
+
+static char token(int fd, char *buf, int len, char stop)
+{
+	int n;
+	char *ptr, *end, c;
+
+	ptr = buf;
+	end = &buf[len];
+	do {
+		n = os_read_file(fd, ptr, sizeof(*ptr));
+		c = *ptr++;
+		if(n != sizeof(*ptr)){
+			if(n == 0) return(0);
+			printk("Reading /proc/cpuinfo failed, err = %d\n", -n);
+			if(n < 0)
+				return(n);
+			else
+				return(-EIO);
+		}
+	} while((c != '\n') && (c != stop) && (ptr < end));
+
+	if(ptr == end){
+		printk("Failed to find '%c' in /proc/cpuinfo\n", stop);
+		return(-1);
+	}
+	*(ptr - 1) = '\0';
+	return(c);
+}
+
+static int find_cpuinfo_line(int fd, char *key, char *scratch, int len)
+{
+	int n;
+	char c;
+
+	scratch[len - 1] = '\0';
+	while(1){
+		c = token(fd, scratch, len - 1, ':');
+		if(c <= 0)
+			return(0);
+		else if(c != ':'){
+			printk("Failed to find ':' in /proc/cpuinfo\n");
+			return(0);
+		}
+
+		if(!strncmp(scratch, key, strlen(key)))
+			return(1);
+
+		do {
+			n = os_read_file(fd, &c, sizeof(c));
+			if(n != sizeof(c)){
+				printk("Failed to find newline in "
+				       "/proc/cpuinfo, err = %d\n", -n);
+				return(0);
+			}
+		} while(c != '\n');
+	}
+	return(0);
+}
+
+int cpu_feature(char *what, char *buf, int len)
+{
+	int fd, ret = 0;
+
+	fd = os_open_file("/proc/cpuinfo", of_read(OPENFLAGS()), 0);
+	if(fd < 0){
+		printk("Couldn't open /proc/cpuinfo, err = %d\n", -fd);
+		return(0);
+	}
+
+	if(!find_cpuinfo_line(fd, what, buf, len)){
+		printk("Couldn't find '%s' line in /proc/cpuinfo\n", what);
+		goto out_close;
+	}
+
+	token(fd, buf, len, '\n');
+	ret = 1;
+
+ out_close:
+	os_close_file(fd);
+	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 -Nru a/arch/um/sys-x86_64/delay.c b/arch/um/sys-x86_64/delay.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/um/sys-x86_64/delay.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2003 PathScale, Inc.
+ * Copied from arch/x86_64
+ *
+ * Licensed under the GPL
+ */
+
+#include "asm/processor.h"
+
+void __delay(unsigned long loops)
+{
+	unsigned long i;
+
+	for(i = 0; i < loops; i++) ;
+}
+
+/*
+ * 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 -Nru a/arch/um/sys-x86_64/fault.c b/arch/um/sys-x86_64/fault.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/um/sys-x86_64/fault.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2003 PathScale, Inc.
+ *
+ * Licensed under the GPL
+ */
+
+#include "user.h"
+
+int arch_fixup(unsigned long address, void *sc_ptr)
+{
+	/* XXX search_exception_tables() */
+	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 -Nru a/arch/um/sys-x86_64/mem.c b/arch/um/sys-x86_64/mem.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/um/sys-x86_64/mem.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2003 PathScale, Inc.
+ *
+ * Licensed under the GPL
+ */
+
+#include "linux/mm.h"
+#include "asm/page.h"
+#include "asm/mman.h"
+
+unsigned long vm_stack_flags = __VM_STACK_FLAGS;
+unsigned long vm_stack_flags32 = __VM_STACK_FLAGS;
+unsigned long vm_data_default_flags = __VM_DATA_DEFAULT_FLAGS;
+unsigned long vm_data_default_flags32 = __VM_DATA_DEFAULT_FLAGS;
+unsigned long vm_force_exec32 = PROT_EXEC;
+
+/* 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 -Nru a/arch/um/sys-x86_64/ptrace.c b/arch/um/sys-x86_64/ptrace.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/um/sys-x86_64/ptrace.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,138 @@
+/*
+ * Copyright 2003 PathScale, Inc.
+ *
+ * Licensed under the GPL
+ */
+
+#define __FRAME_OFFSETS
+#include "asm/ptrace.h"
+#include "linux/sched.h"
+#include "linux/errno.h"
+#include "asm/elf.h"
+
+/* XXX x86_64 */
+unsigned long not_ss;
+unsigned long not_ds;
+unsigned long not_es;
+
+#define SC_SS(r) (not_ss)
+#define SC_DS(r) (not_ds)
+#define SC_ES(r) (not_es)
+
+/* determines which flags the user has access to. */
+/* 1 = access 0 = no access */
+#define FLAG_MASK 0x44dd5UL
+
+int putreg(struct task_struct *child, int regno, unsigned long value)
+{
+	unsigned long tmp;
+
+#ifdef TIF_IA32
+	/* Some code in the 64bit emulation may not be 64bit clean.
+	   Don't take any chances. */
+	if (test_tsk_thread_flag(child, TIF_IA32))
+		value &= 0xffffffff;
+#endif
+	switch (regno){
+	case FS:
+	case GS:
+	case DS:
+	case ES:
+	case SS:
+	case CS:
+		if (value && (value & 3) != 3)
+			return -EIO;
+		value &= 0xffff;
+		break;
+
+	case FS_BASE:
+	case GS_BASE:
+		if (!((value >> 48) == 0 || (value >> 48) == 0xffff))
+			return -EIO;
+		break;
+
+	case EFLAGS:
+		value &= FLAG_MASK;
+		tmp = PT_REGS_EFLAGS(&child->thread.regs) & ~FLAG_MASK;
+		value |= tmp;
+		break;
+	}
+
+	PT_REGS_SET(&child->thread.regs, regno, value);
+	return 0;
+}
+
+unsigned long getreg(struct task_struct *child, int regno)
+{
+	unsigned long retval = ~0UL;
+	switch (regno) {
+	case FS:
+	case GS:
+	case DS:
+	case ES:
+	case SS:
+	case CS:
+		retval = 0xffff;
+		/* fall through */
+	default:
+		retval &= PT_REG(&child->thread.regs, regno);
+#ifdef TIF_IA32
+		if (test_tsk_thread_flag(child, TIF_IA32))
+			retval &= 0xffffffff;
+#endif
+	}
+	return retval;
+}
+
+void arch_switch(void)
+{
+/* XXX
+	printk("arch_switch\n");
+*/
+}
+
+int is_syscall(unsigned long addr)
+{
+	panic("is_syscall");
+}
+
+int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu )
+{
+	panic("dump_fpu");
+	return(1);
+}
+
+int get_fpregs(unsigned long buf, struct task_struct *child)
+{
+	panic("get_fpregs");
+	return(0);
+}
+
+int set_fpregs(unsigned long buf, struct task_struct *child)
+{
+	panic("set_fpregs");
+	return(0);
+}
+
+int get_fpxregs(unsigned long buf, struct task_struct *tsk)
+{
+	panic("get_fpxregs");
+	return(0);
+}
+
+int set_fpxregs(unsigned long buf, struct task_struct *tsk)
+{
+	panic("set_fxpregs");
+	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 -Nru a/arch/um/sys-x86_64/ptrace_user.c b/arch/um/sys-x86_64/ptrace_user.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/um/sys-x86_64/ptrace_user.c	2005-03-01 23:39:26 -08:00
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2003 PathScale, Inc.
+ *
+ * Licensed under the GPL
+ */
+
+#include <stddef.h>
+#include <errno.h>
+#define __FRAME_OFFSETS
+#include <sys/ptrace.h>
+#include <asm/ptrace.h>
+#include "user.h"
+#include "kern_constants.h"
+
+int ptrace_getregs(long pid, unsigned long *regs_out)
+{
+	if(ptrace(PTRACE_GETREGS, pid, 0, regs_out) < 0)
+		return(-errno);
+	return(0);
+}
+
+int ptrace_setregs(long pid, unsigned long *regs)
+{
+	if(ptrace(PTRACE_SETREGS, pid, 0, regs) < 0)
+		return(-errno);
+	return(0);
+}
+
+void ptrace_pokeuser(unsigned long addr, unsigned long data)
+{
+	panic("ptrace_pokeuser");
+}
+
+#define DS 184
+#define ES 192
+#define __USER_DS     0x2b
+
+void arch_enter_kernel(void *task, int pid)
+{
+}
+
+void arch_leave_kernel(void *task, int pid)
+{
+#ifdef UM_USER_CS
+	if(ptrace(PTRACE_POKEUSER, pid, CS, UM_USER_CS) < 0)
+		tracer_panic("POKEUSER CS failed");
+#endif
+
+	if(ptrace(PTRACE_POKEUSER, pid, DS, __USER_DS) < 0)
+		tracer_panic("POKEUSER DS failed");
+	if(ptrace(PTRACE_POKEUSER, pid, ES, __USER_DS) < 0)
+		tracer_panic("POKEUSER ES failed");
+}
+
+/*
+ * 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 -Nru a/arch/um/sys-x86_64/sigcontext.c b/arch/um/sys-x86_64/sigcontext.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/um/sys-x86_64/sigcontext.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2003 PathScale, Inc.
+ *
+ * Licensed under the GPL
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <signal.h>
+#include "user.h"
+
+void sc_to_sc(void *to_ptr, void *from_ptr)
+{
+        struct sigcontext *to = to_ptr, *from = from_ptr;
+        int size = sizeof(*to); /* + sizeof(struct _fpstate); */
+
+        memcpy(to, from, size);
+        if(from->fpstate != NULL)
+		to->fpstate = (struct _fpstate *) (to + 1);
+
+	to->fpstate = NULL;
+}
+
+unsigned long *sc_sigmask(void *sc_ptr)
+{
+	struct sigcontext *sc = sc_ptr;
+
+	return(&sc->oldmask);
+}
+
+/* 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 -Nru a/arch/um/sys-x86_64/signal.c b/arch/um/sys-x86_64/signal.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/um/sys-x86_64/signal.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,276 @@
+/*
+ * Copyright (C) 2003 PathScale, Inc.
+ * Licensed under the GPL
+ */
+
+#include "linux/stddef.h"
+#include "linux/errno.h"
+#include "linux/personality.h"
+#include "linux/ptrace.h"
+#include "asm/current.h"
+#include "asm/uaccess.h"
+#include "asm/sigcontext.h"
+#include "asm/ptrace.h"
+#include "asm/arch/ucontext.h"
+#include "choose-mode.h"
+#include "sysdep/ptrace.h"
+#include "frame_kern.h"
+
+#ifdef CONFIG_MODE_SKAS
+
+#include "skas.h"
+
+static int copy_sc_from_user_skas(struct pt_regs *regs,
+                                 struct sigcontext *from)
+{
+       int err = 0;
+
+#define GETREG(regs, regno, sc, regname) \
+       __get_user((regs)->regs.skas.regs[(regno) / sizeof(unsigned long)], \
+                  &(sc)->regname)
+
+       err |= GETREG(regs, R8, from, r8);
+       err |= GETREG(regs, R9, from, r9);
+       err |= GETREG(regs, R10, from, r10);
+       err |= GETREG(regs, R11, from, r11);
+       err |= GETREG(regs, R12, from, r12);
+       err |= GETREG(regs, R13, from, r13);
+       err |= GETREG(regs, R14, from, r14);
+       err |= GETREG(regs, R15, from, r15);
+       err |= GETREG(regs, RDI, from, rdi);
+       err |= GETREG(regs, RSI, from, rsi);
+       err |= GETREG(regs, RBP, from, rbp);
+       err |= GETREG(regs, RBX, from, rbx);
+       err |= GETREG(regs, RDX, from, rdx);
+       err |= GETREG(regs, RAX, from, rax);
+       err |= GETREG(regs, RCX, from, rcx);
+       err |= GETREG(regs, RSP, from, rsp);
+       err |= GETREG(regs, RIP, from, rip);
+       err |= GETREG(regs, EFLAGS, from, eflags);
+       err |= GETREG(regs, CS, from, cs);
+
+#undef GETREG
+
+       return(err);
+}
+
+int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate *to_fp,
+                        struct pt_regs *regs, unsigned long mask)
+{
+	unsigned long eflags;
+	int err = 0;
+
+	err |= __put_user(0, &to->gs);
+	err |= __put_user(0, &to->fs);
+
+#define PUTREG(regs, regno, sc, regname) \
+       __put_user((regs)->regs.skas.regs[(regno) / sizeof(unsigned long)], \
+                  &(sc)->regname)
+
+	err |= PUTREG(regs, RDI, to, rdi);
+	err |= PUTREG(regs, RSI, to, rsi);
+	err |= PUTREG(regs, RBP, to, rbp);
+	err |= PUTREG(regs, RSP, to, rsp);
+	err |= PUTREG(regs, RBX, to, rbx);
+	err |= PUTREG(regs, RDX, to, rdx);
+	err |= PUTREG(regs, RCX, to, rcx);
+	err |= PUTREG(regs, RAX, to, rax);
+	err |= PUTREG(regs, R8, to, r8);
+	err |= PUTREG(regs, R9, to, r9);
+	err |= PUTREG(regs, R10, to, r10);
+	err |= PUTREG(regs, R11, to, r11);
+	err |= PUTREG(regs, R12, to, r12);
+	err |= PUTREG(regs, R13, to, r13);
+	err |= PUTREG(regs, R14, to, r14);
+	err |= PUTREG(regs, R15, to, r15);
+	err |= PUTREG(regs, CS, to, cs); /* XXX x86_64 doesn't do this */
+	err |= __put_user(current->thread.err, &to->err);
+	err |= __put_user(current->thread.trap_no, &to->trapno);
+	err |= PUTREG(regs, RIP, to, rip);
+	err |= PUTREG(regs, EFLAGS, to, eflags);
+#undef PUTREG
+
+	err |= __put_user(mask, &to->oldmask);
+	err |= __put_user(current->thread.cr2, &to->cr2);
+
+	return(err);
+}
+
+#endif
+
+#ifdef CONFIG_MODE_TT
+int copy_sc_from_user_tt(struct sigcontext *to, struct sigcontext *from,
+                        int fpsize)
+{
+       struct _fpstate *to_fp, *from_fp;
+       unsigned long sigs;
+       int err;
+
+       to_fp = to->fpstate;
+       from_fp = from->fpstate;
+       sigs = to->oldmask;
+       err = copy_from_user(to, from, sizeof(*to));
+       to->oldmask = sigs;
+       return(err);
+}
+
+int copy_sc_to_user_tt(struct sigcontext *to, struct _fpstate *fp,
+                      struct sigcontext *from, int fpsize)
+{
+       struct _fpstate *to_fp, *from_fp;
+       int err;
+
+       to_fp = (fp ? fp : (struct _fpstate *) (to + 1));
+       from_fp = from->fpstate;
+       err = copy_to_user(to, from, sizeof(*to));
+       return(err);
+}
+
+#endif
+
+static int copy_sc_from_user(struct pt_regs *to, void __user *from)
+{
+       int ret;
+
+       ret = CHOOSE_MODE(copy_sc_from_user_tt(UPT_SC(&to->regs), from,
+                                              sizeof(struct _fpstate)),
+                         copy_sc_from_user_skas(to, from));
+       return(ret);
+}
+
+static int copy_sc_to_user(struct sigcontext *to, struct _fpstate *fp,
+                          struct pt_regs *from, unsigned long mask)
+{
+       return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs),
+                                             sizeof(*fp)),
+                          copy_sc_to_user_skas(to, fp, from, mask)));
+}
+
+struct rt_sigframe
+{
+       char *pretcode;
+       struct ucontext uc;
+       struct siginfo info;
+};
+
+#define round_down(m, n) (((m) / (n)) * (n))
+
+int setup_signal_stack_si(unsigned long stack_top, int sig,
+			  struct k_sigaction *ka, struct pt_regs * regs,
+			  siginfo_t *info, sigset_t *set)
+{
+	struct rt_sigframe __user *frame;
+	struct _fpstate __user *fp = NULL;
+	int err = 0;
+	struct task_struct *me = current;
+
+	frame = (struct rt_sigframe __user *)
+		round_down(stack_top - sizeof(struct rt_sigframe), 16) - 8;
+	frame -= 128;
+
+	if (!access_ok(VERIFY_WRITE, fp, sizeof(struct _fpstate)))
+		goto out;
+
+#if 0 /* XXX */
+	if (save_i387(fp) < 0)
+		err |= -1;
+#endif
+	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
+		goto out;
+
+	if (ka->sa.sa_flags & SA_SIGINFO) {
+		err |= copy_siginfo_to_user(&frame->info, info);
+		if (err)
+			goto out;
+	}
+
+	/* Create the ucontext.  */
+	err |= __put_user(0, &frame->uc.uc_flags);
+	err |= __put_user(0, &frame->uc.uc_link);
+	err |= __put_user(me->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
+	err |= __put_user(sas_ss_flags(PT_REGS_SP(regs)),
+			  &frame->uc.uc_stack.ss_flags);
+	err |= __put_user(me->sas_ss_size, &frame->uc.uc_stack.ss_size);
+	err |= copy_sc_to_user(&frame->uc.uc_mcontext, fp, regs, set->sig[0]);
+	err |= __put_user(fp, &frame->uc.uc_mcontext.fpstate);
+	if (sizeof(*set) == 16) {
+		__put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]);
+		__put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]);
+	}
+	else
+		err |= __copy_to_user(&frame->uc.uc_sigmask, set,
+				      sizeof(*set));
+
+	/* Set up to return from userspace.  If provided, use a stub
+	   already in userspace.  */
+	/* x86-64 should always use SA_RESTORER. */
+	if (ka->sa.sa_flags & SA_RESTORER)
+		err |= __put_user(ka->sa.sa_restorer, &frame->pretcode);
+	else
+		/* could use a vstub here */
+		goto out;
+
+	if (err)
+		goto out;
+
+	/* Set up registers for signal handler */
+	{
+		struct exec_domain *ed = current_thread_info()->exec_domain;
+		if (unlikely(ed && ed->signal_invmap && sig < 32))
+			sig = ed->signal_invmap[sig];
+	}
+
+	PT_REGS_RDI(regs) = sig;
+	/* In case the signal handler was declared without prototypes */
+	PT_REGS_RAX(regs) = 0;
+
+	/* This also works for non SA_SIGINFO handlers because they expect the
+	   next argument after the signal number on the stack. */
+	PT_REGS_RSI(regs) = (unsigned long) &frame->info;
+	PT_REGS_RDX(regs) = (unsigned long) &frame->uc;
+	PT_REGS_RIP(regs) = (unsigned long) ka->sa.sa_handler;
+
+	PT_REGS_RSP(regs) = (unsigned long) frame;
+ out:
+	return(err);
+}
+
+long sys_rt_sigreturn(struct pt_regs *regs)
+{
+	unsigned long __user sp = PT_REGS_SP(&current->thread.regs);
+	struct rt_sigframe __user *frame =
+		(struct rt_sigframe __user *)(sp - 8);
+	struct ucontext __user *uc = &frame->uc;
+	sigset_t set;
+
+	if(copy_from_user(&set, &uc->uc_sigmask, sizeof(set)))
+		goto segfault;
+
+	sigdelsetmask(&set, ~_BLOCKABLE);
+
+	spin_lock_irq(&current->sighand->siglock);
+	current->blocked = set;
+	recalc_sigpending();
+	spin_unlock_irq(&current->sighand->siglock);
+
+	if(copy_sc_from_user(&current->thread.regs, &uc->uc_mcontext))
+		goto segfault;
+
+	/* Avoid ERESTART handling */
+	PT_REGS_SYSCALL_NR(&current->thread.regs) = -1;
+	return(PT_REGS_SYSCALL_RET(&current->thread.regs));
+
+ segfault:
+	force_sig(SIGSEGV, current);
+	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 -Nru a/arch/um/sys-x86_64/syscalls.c b/arch/um/sys-x86_64/syscalls.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/um/sys-x86_64/syscalls.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,191 @@
+/*
+ * Copyright 2003 PathScale, Inc.
+ *
+ * Licensed under the GPL
+ */
+
+#include "linux/linkage.h"
+#include "linux/slab.h"
+#include "linux/shm.h"
+#include "asm/uaccess.h"
+#define __FRAME_OFFSETS
+#include "asm/ptrace.h"
+#include "asm/unistd.h"
+#include "asm/prctl.h" /* XXX This should get the constants from libc */
+#include "choose-mode.h"
+
+asmlinkage long wrap_sys_shmat(int shmid, char __user *shmaddr, int shmflg)
+{
+	unsigned long raddr;
+
+	return do_shmat(shmid, shmaddr, shmflg, &raddr) ?: (long) raddr;
+}
+
+#ifdef CONFIG_MODE_TT
+extern int modify_ldt(int func, void *ptr, unsigned long bytecount);
+
+long sys_modify_ldt_tt(int func, void *ptr, unsigned long bytecount)
+{
+	/* XXX This should check VERIFY_WRITE depending on func, check this
+	 * in i386 as well.
+	 */
+	if(verify_area(VERIFY_READ, ptr, bytecount))
+		return(-EFAULT);
+	return(modify_ldt(func, ptr, bytecount));
+}
+#endif
+
+#ifdef CONFIG_MODE_SKAS
+extern int userspace_pid;
+
+#ifndef __NR_mm_indirect
+#define __NR_mm_indirect 241
+#endif
+
+long sys_modify_ldt_skas(int func, void *ptr, unsigned long bytecount)
+{
+	unsigned long args[6];
+        void *buf;
+        int res, n;
+
+        buf = kmalloc(bytecount, GFP_KERNEL);
+        if(buf == NULL)
+                return(-ENOMEM);
+
+        res = 0;
+
+        switch(func){
+        case 1:
+        case 0x11:
+                res = copy_from_user(buf, ptr, bytecount);
+                break;
+        }
+
+        if(res != 0){
+                res = -EFAULT;
+                goto out;
+        }
+
+	args[0] = func;
+	args[1] = (unsigned long) buf;
+	args[2] = bytecount;
+	res = syscall(__NR_mm_indirect, &current->mm->context.u,
+		      __NR_modify_ldt, args);
+
+        if(res < 0)
+                goto out;
+
+        switch(func){
+        case 0:
+        case 2:
+                n = res;
+                res = copy_to_user(ptr, buf, n);
+                if(res != 0)
+                        res = -EFAULT;
+                else
+                        res = n;
+                break;
+        }
+
+ out:
+        kfree(buf);
+        return(res);
+}
+#endif
+
+long sys_modify_ldt(int func, void *ptr, unsigned long bytecount)
+{
+        return(CHOOSE_MODE_PROC(sys_modify_ldt_tt, sys_modify_ldt_skas, func,
+                                ptr, bytecount));
+}
+
+#ifdef CONFIG_MODE_TT
+extern long arch_prctl(int code, unsigned long addr);
+
+static long arch_prctl_tt(int code, unsigned long addr)
+{
+	unsigned long tmp;
+	long ret;
+
+	switch(code){
+	case ARCH_SET_GS:
+	case ARCH_SET_FS:
+		ret = arch_prctl(code, addr);
+		break;
+	case ARCH_GET_FS:
+	case ARCH_GET_GS:
+		ret = arch_prctl(code, (unsigned long) &tmp);
+		if(!ret)
+			ret = put_user(tmp, &addr);
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	return(ret);
+}
+#endif
+
+#ifdef CONFIG_MODE_SKAS
+
+static long arch_prctl_skas(int code, unsigned long addr)
+{
+	long ret = 0;
+
+	switch(code){
+	case ARCH_SET_GS:
+		current->thread.regs.regs.skas.regs[GS_BASE / sizeof(unsigned long)] = addr;
+		break;
+	case ARCH_SET_FS:
+		current->thread.regs.regs.skas.regs[FS_BASE / sizeof(unsigned long)] = addr;
+		break;
+	case ARCH_GET_FS:
+		ret = put_user(current->thread.regs.regs.skas.regs[GS / sizeof(unsigned long)], &addr);
+	        break;
+	case ARCH_GET_GS:
+		ret = put_user(current->thread.regs.regs.skas.regs[FS / sizeof(unsigned \
+long)], &addr);
+	        break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	return(ret);
+}
+#endif
+
+long sys_arch_prctl(int code, unsigned long addr)
+{
+	return(CHOOSE_MODE_PROC(arch_prctl_tt, arch_prctl_skas, code, addr));
+}
+
+long sys_clone(unsigned long clone_flags, unsigned long newsp,
+	       void __user *parent_tid, void __user *child_tid)
+{
+	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);*/
+	current->thread.forking = 1;
+	ret = do_fork(clone_flags, newsp, NULL, 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 -Nru a/arch/um/sys-x86_64/sysrq.c b/arch/um/sys-x86_64/sysrq.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/um/sys-x86_64/sysrq.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2003 PathScale, Inc.
+ *
+ * Licensed under the GPL
+ */
+
+#include "linux/kernel.h"
+#include "linux/utsname.h"
+#include "linux/module.h"
+#include "asm/current.h"
+#include "asm/ptrace.h"
+#include "sysrq.h"
+
+void __show_regs(struct pt_regs * regs)
+{
+	printk("\n");
+	print_modules();
+	printk("Pid: %d, comm: %.20s %s %s\n",
+	       current->pid, current->comm, print_tainted(), system_utsname.release);
+	printk("RIP: %04lx:[<%016lx>] ", PT_REGS_CS(regs) & 0xffff,
+	       PT_REGS_RIP(regs));
+	printk("\nRSP: %016lx  EFLAGS: %08lx\n", PT_REGS_RSP(regs),
+	       PT_REGS_EFLAGS(regs));
+	printk("RAX: %016lx RBX: %016lx RCX: %016lx\n",
+	       PT_REGS_RAX(regs), PT_REGS_RBX(regs), PT_REGS_RCX(regs));
+	printk("RDX: %016lx RSI: %016lx RDI: %016lx\n",
+	       PT_REGS_RDX(regs), PT_REGS_RSI(regs), PT_REGS_RDI(regs));
+	printk("RBP: %016lx R08: %016lx R09: %016lx\n",
+	       PT_REGS_RBP(regs), PT_REGS_R8(regs), PT_REGS_R9(regs));
+	printk("R10: %016lx R11: %016lx R12: %016lx\n",
+	       PT_REGS_R10(regs), PT_REGS_R11(regs), PT_REGS_R12(regs));
+	printk("R13: %016lx R14: %016lx R15: %016lx\n",
+	       PT_REGS_R13(regs), PT_REGS_R14(regs), PT_REGS_R15(regs));
+}
+
+void show_regs(struct pt_regs *regs)
+{
+	__show_regs(regs);
+	show_trace((unsigned long *) &regs);
+}
+
+/* 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 -Nru a/arch/um/sys-x86_64/util/Makefile b/arch/um/sys-x86_64/util/Makefile
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/um/sys-x86_64/util/Makefile	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,10 @@
+# Copyright 2003 - 2004 Pathscale, Inc
+# Released under the GPL
+
+hostprogs-y	:= mk_sc mk_thread
+always		:= $(hostprogs-y)
+
+mk_thread-objs	:= mk_thread_kern.o mk_thread_user.o
+
+HOSTCFLAGS_mk_thread_kern.o	:= $(CFLAGS) $(CPPFLAGS)
+HOSTCFLAGS_mk_thread_user.o	:= $(USER_CFLAGS)
diff -Nru a/arch/um/sys-x86_64/util/mk_sc.c b/arch/um/sys-x86_64/util/mk_sc.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/um/sys-x86_64/util/mk_sc.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,58 @@
+/* Copyright (C) 2003 - 2004 PathScale, Inc
+ * Released under the GPL
+ */
+
+#include <stdio.h>
+#include <signal.h>
+#include <linux/stddef.h>
+
+#define SC_OFFSET(name, field) \
+  printf("#define " name \
+	 "(sc) *((unsigned long *) &(((char *) (sc))[%ld]))\n",\
+	 offsetof(struct sigcontext, field))
+
+#define SC_FP_OFFSET(name, field) \
+  printf("#define " name \
+	 "(sc) *((unsigned long *) &(((char *) (SC_FPSTATE(sc)))[%ld]))\n",\
+	 offsetof(struct _fpstate, field))
+
+#define SC_FP_OFFSET_PTR(name, field, type) \
+  printf("#define " name \
+	 "(sc) ((" type " *) &(((char *) (SC_FPSTATE(sc)))[%d]))\n",\
+	 offsetof(struct _fpstate, field))
+
+int main(int argc, char **argv)
+{
+  SC_OFFSET("SC_RBX", rbx);
+  SC_OFFSET("SC_RCX", rcx);
+  SC_OFFSET("SC_RDX", rdx);
+  SC_OFFSET("SC_RSI", rsi);
+  SC_OFFSET("SC_RDI", rdi);
+  SC_OFFSET("SC_RBP", rbp);
+  SC_OFFSET("SC_RAX", rax);
+  SC_OFFSET("SC_R8", r8);
+  SC_OFFSET("SC_R9", r9);
+  SC_OFFSET("SC_R10", r10);
+  SC_OFFSET("SC_R11", r11);
+  SC_OFFSET("SC_R12", r12);
+  SC_OFFSET("SC_R13", r13);
+  SC_OFFSET("SC_R14", r14);
+  SC_OFFSET("SC_R15", r15);
+  SC_OFFSET("SC_IP", rip);
+  SC_OFFSET("SC_SP", rsp);
+  SC_OFFSET("SC_CR2", cr2);
+  SC_OFFSET("SC_ERR", err);
+  SC_OFFSET("SC_TRAPNO", trapno);
+  SC_OFFSET("SC_CS", cs);
+  SC_OFFSET("SC_FS", fs);
+  SC_OFFSET("SC_GS", gs);
+  SC_OFFSET("SC_EFLAGS", eflags);
+  SC_OFFSET("SC_SIGMASK", oldmask);
+#if 0
+  SC_OFFSET("SC_ORIG_RAX", orig_rax);
+  SC_OFFSET("SC_DS", ds);
+  SC_OFFSET("SC_ES", es);
+  SC_OFFSET("SC_SS", ss);
+#endif
+  return(0);
+}
diff -Nru a/arch/um/sys-x86_64/util/mk_thread_kern.c b/arch/um/sys-x86_64/util/mk_thread_kern.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/um/sys-x86_64/util/mk_thread_kern.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,21 @@
+#include "linux/config.h"
+#include "linux/stddef.h"
+#include "linux/sched.h"
+
+extern void print_head(void);
+extern void print_constant_ptr(char *name, int value);
+extern void print_constant(char *name, char *type, int value);
+extern void print_tail(void);
+
+#define THREAD_OFFSET(field) offsetof(struct task_struct, thread.field)
+
+int main(int argc, char **argv)
+{
+  print_head();
+#ifdef CONFIG_MODE_TT
+  print_constant("TASK_EXTERN_PID", "int", THREAD_OFFSET(mode.tt.extern_pid));
+#endif
+  print_tail();
+  return(0);
+}
+
diff -Nru a/arch/um/sys-x86_64/util/mk_thread_user.c b/arch/um/sys-x86_64/util/mk_thread_user.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/um/sys-x86_64/util/mk_thread_user.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,30 @@
+#include <stdio.h>
+
+void print_head(void)
+{
+  printf("/*\n");
+  printf(" * Generated by mk_thread\n");
+  printf(" */\n");
+  printf("\n");
+  printf("#ifndef __UM_THREAD_H\n");
+  printf("#define __UM_THREAD_H\n");
+  printf("\n");
+}
+
+void print_constant_ptr(char *name, int value)
+{
+  printf("#define %s(task) ((unsigned long *) "
+	 "&(((char *) (task))[%d]))\n", name, value);
+}
+
+void print_constant(char *name, char *type, int value)
+{
+  printf("#define %s(task) *((%s *) &(((char *) (task))[%d]))\n", name, type,
+	 value);
+}
+
+void print_tail(void)
+{
+  printf("\n");
+  printf("#endif\n");
+}
diff -Nru a/arch/v850/Kconfig b/arch/v850/Kconfig
--- a/arch/v850/Kconfig	2005-03-01 23:38:56 -08:00
+++ b/arch/v850/Kconfig	2005-03-01 23:38:56 -08:00
@@ -19,6 +19,9 @@
 config RWSEM_XCHGADD_ALGORITHM
 	bool
 	default n
+config GENERIC_CALIBRATE_DELAY
+	bool
+	default y
 
 # Turn off some random 386 crap that can affect device config
 config ISA
diff -Nru a/arch/v850/kernel/fpga85e2c.c b/arch/v850/kernel/fpga85e2c.c
--- a/arch/v850/kernel/fpga85e2c.c	2005-03-01 23:39:16 -08:00
+++ b/arch/v850/kernel/fpga85e2c.c	2005-03-01 23:39:16 -08:00
@@ -42,7 +42,6 @@
 	int i;
 	const u32 *src;
 	register u32 *dst asm ("ep");
-	extern int panic_timeout;
 	extern u32 _intv_end, _intv_load_start;
 
 	/* Set bus sizes: CS0 32-bit, CS1 16-bit, CS7 8-bit,
diff -Nru a/arch/v850/kernel/memcons.c b/arch/v850/kernel/memcons.c
--- a/arch/v850/kernel/memcons.c	2005-03-01 23:39:16 -08:00
+++ b/arch/v850/kernel/memcons.c	2005-03-01 23:39:16 -08:00
@@ -25,7 +25,7 @@
 static unsigned long memcons_offs = 0;
 
 /* Spinlock protecting memcons_offs.  */
-static spinlock_t memcons_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(memcons_lock);
 
 
 static size_t write (const char *buf, size_t len)
diff -Nru a/arch/v850/kernel/rte_cb_leds.c b/arch/v850/kernel/rte_cb_leds.c
--- a/arch/v850/kernel/rte_cb_leds.c	2005-03-01 23:38:52 -08:00
+++ b/arch/v850/kernel/rte_cb_leds.c	2005-03-01 23:38:52 -08:00
@@ -25,7 +25,7 @@
 static unsigned char leds_image[LED_NUM_DIGITS] = { 0 };
 
 /* Spinlock protecting the above leds.  */
-static spinlock_t leds_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(leds_lock);
 
 /* Common body of LED read/write functions, checks POS and LEN for
    correctness, declares a variable using IMG_DECL, initialized pointing at
diff -Nru 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	2005-03-01 23:38:54 -08:00
+++ b/arch/v850/kernel/rte_mb_a_pci.c	2005-03-01 23:38:54 -08:00
@@ -359,7 +359,7 @@
 static struct mb_sram_free_area *mb_sram_free_free_areas = 0;
 
 /* Spinlock protecting the above globals.  */
-static spinlock_t mb_sram_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(mb_sram_lock);
 
 /* Allocate a memory block at least SIZE bytes long in the Mother-A SRAM
    space.  */
@@ -514,7 +514,7 @@
 static struct dma_mapping *free_dma_mappings = 0;
 
 /* Spinlock protecting the above globals.  */
-static spinlock_t dma_mappings_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(dma_mappings_lock);
 
 static struct dma_mapping *new_dma_mapping (size_t size)
 {
diff -Nru a/arch/v850/kernel/semaphore.c b/arch/v850/kernel/semaphore.c
--- a/arch/v850/kernel/semaphore.c	2005-03-01 23:39:09 -08:00
+++ b/arch/v850/kernel/semaphore.c	2005-03-01 23:39:09 -08:00
@@ -55,7 +55,7 @@
 	wake_up(&sem->wait);
 }
 
-static spinlock_t semaphore_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(semaphore_lock);
 
 void __sched __down(struct semaphore * sem)
 {
diff -Nru a/arch/v850/kernel/sim85e2.c b/arch/v850/kernel/sim85e2.c
--- a/arch/v850/kernel/sim85e2.c	2005-03-01 23:38:58 -08:00
+++ b/arch/v850/kernel/sim85e2.c	2005-03-01 23:38:58 -08:00
@@ -65,8 +65,6 @@
 
 void EARLY_INIT_SECTION_ATTR mach_early_init (void)
 {
-	extern int panic_timeout;
-
 	/* The sim85e2 simulator tracks `undefined' values, so to make
 	   debugging easier, we begin by zeroing out all otherwise
 	   undefined registers.  This is not strictly necessary.
diff -Nru a/arch/v850/lib/checksum.c b/arch/v850/lib/checksum.c
--- a/arch/v850/lib/checksum.c	2005-03-01 23:39:16 -08:00
+++ b/arch/v850/lib/checksum.c	2005-03-01 23:39:16 -08:00
@@ -121,7 +121,7 @@
 /*
  * copy while checksumming, otherwise like csum_partial
  */
-unsigned int csum_partial_copy(const char *src, char *dst, 
+unsigned int csum_partial_copy(const unsigned char *src, unsigned char *dst,
                                int len, unsigned int sum)
 {
 	/*
@@ -138,7 +138,7 @@
  * 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 char *src, 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 -Nru a/arch/v850/lib/memcpy.c b/arch/v850/lib/memcpy.c
--- a/arch/v850/lib/memcpy.c	2005-03-01 23:38:52 -08:00
+++ b/arch/v850/lib/memcpy.c	2005-03-01 23:38:52 -08:00
@@ -60,11 +60,6 @@
 	return dst;
 }
 
-void bcopy (const char *src, char *dst, int size)
-{
-	memcpy (dst, src, size);
-}
-
 void *memmove (void *dst, const void *src, __kernel_size_t size)
 {
 	if ((unsigned long)dst < (unsigned long)src
diff -Nru a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig
--- a/arch/x86_64/Kconfig	2005-03-01 23:39:09 -08:00
+++ b/arch/x86_64/Kconfig	2005-03-01 23:39:09 -08:00
@@ -41,6 +41,10 @@
 config RWSEM_XCHGADD_ALGORITHM
 	bool
 
+config GENERIC_CALIBRATE_DELAY
+	bool
+	default y
+
 config X86_CMPXCHG
 	bool
 	default y
@@ -48,15 +52,6 @@
 config EARLY_PRINTK
 	bool
 	default y
-	help
-	  Write kernel log output directly into the VGA buffer or to a serial
-	  port.
-
-	  This is useful for kernel debugging when your machine crashes very
-	  early before the console code is initialized. For normal operation
-	  it is not recommended because it looks ugly and doesn't cooperate
-	  with klogd/syslogd or the X server. You should normally N here,
-	  unless you want to debug such a crash.
 
 config HPET_TIMER
 	bool
@@ -98,10 +93,11 @@
 	  Optimize for AMD Opteron/Athlon64/Hammer/K8 CPUs.
 
 config MPSC
-       bool "Intel x86-64"
+       bool "Intel EM64T"
        help
-	  Optimize for Intel IA32 with 64bit extension CPUs
-	  (Prescott/Nocona/Potomac)
+	  Optimize for Intel Pentium 4 and Xeon CPUs with Intel
+	  Extended Memory 64 Technology(EM64T). For details see
+	  <http://www.intel.com/technology/64bitextensions/>.
 
 config GENERIC_CPU
 	bool "Generic-x86-64"
@@ -244,6 +240,17 @@
 	  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
@@ -289,17 +296,15 @@
 	depends on SMP
 	default y
 
-# actually 64 maximum, but you need to fix the APIC code first
-# to use clustered mode or whatever your big iron needs
 config NR_CPUS
-	int "Maximum number of CPUs (2-8)"
-	range 2 8
+	int "Maximum number of CPUs (2-256)"
+	range 2 256
 	depends on SMP
 	default "8"
 	help
 	  This allows you to specify the maximum number of CPUs which this
-	  kernel will support.  The maximum supported value is 32 and the
-	  minimum value which makes sense is 2.
+	  kernel will support. Current maximum is 256 CPUs due to
+	  APIC addressing limits. Less depending on the hardware.
 
 	  This is purely to save memory - each supported CPU requires
 	  memory in the static kernel configuration.
@@ -338,6 +343,13 @@
 	   machine check error logs. See
 	   ftp://ftp.x86-64.org/pub/linux/tools/mcelog
 
+config X86_MCE_INTEL
+	bool "Intel MCE features"
+	depends on X86_MCE && X86_LOCAL_APIC
+	default y
+	help
+	   Additional support for intel specific MCE features such as
+	   the thermal monitor.
 endmenu
 
 #
diff -Nru a/arch/x86_64/Makefile b/arch/x86_64/Makefile
--- a/arch/x86_64/Makefile	2005-03-01 23:39:09 -08:00
+++ b/arch/x86_64/Makefile	2005-03-01 23:39:09 -08:00
@@ -59,6 +59,8 @@
 # -funit-at-a-time shrinks the kernel .text considerably
 # unfortunately it makes reading oopses harder.
 CFLAGS += $(call cc-option,-funit-at-a-time)
+# prevent gcc from generating any FP code by mistake
+CFLAGS += $(call cc-option,-mno-sse -mno-mmx -mno-sse2 -mno-3dnow,)
 
 head-y := arch/x86_64/kernel/head.o arch/x86_64/kernel/head64.o arch/x86_64/kernel/init_task.o
 
diff -Nru a/arch/x86_64/boot/setup.S b/arch/x86_64/boot/setup.S
--- a/arch/x86_64/boot/setup.S	2005-03-01 23:39:17 -08:00
+++ b/arch/x86_64/boot/setup.S	2005-03-01 23:39:17 -08:00
@@ -158,7 +158,9 @@
 ramdisk_max:	.long 0xffffffff
 	
 trampoline:	call	start_of_setup
-		.space	1024
+		.align 16
+					# The offset at this point is 0x240
+		.space  (0x7ff-0x240+1)	# E820 & EDD space (ending at 0x7ff)
 # End of setup header #####################################################
 
 start_of_setup:
diff -Nru a/arch/x86_64/defconfig b/arch/x86_64/defconfig
--- a/arch/x86_64/defconfig	2005-03-01 23:39:07 -08:00
+++ b/arch/x86_64/defconfig	2005-03-01 23:39:07 -08:00
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc1-bk6
-# Thu Oct 28 00:07:32 2004
+# Linux kernel version: 2.6.10-bk7
+# Fri Jan  7 06:27:52 2005
 #
 CONFIG_X86_64=y
 CONFIG_64BIT=y
@@ -45,6 +45,10 @@
 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
 
 #
@@ -88,6 +92,7 @@
 CONFIG_GART_IOMMU=y
 CONFIG_SWIOTLB=y
 CONFIG_X86_MCE=y
+CONFIG_X86_MCE_INTEL=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 
@@ -110,10 +115,13 @@
 CONFIG_ACPI_AC=y
 CONFIG_ACPI_BATTERY=y
 CONFIG_ACPI_BUTTON=y
+# CONFIG_ACPI_VIDEO is not set
 CONFIG_ACPI_FAN=y
 CONFIG_ACPI_PROCESSOR=y
 CONFIG_ACPI_THERMAL=y
+CONFIG_ACPI_NUMA=y
 # CONFIG_ACPI_ASUS is not set
+# CONFIG_ACPI_IBM is not set
 CONFIG_ACPI_TOSHIBA=y
 CONFIG_ACPI_BLACKLIST_YEAR=2001
 CONFIG_ACPI_DEBUG=y
@@ -122,11 +130,35 @@
 CONFIG_ACPI_POWER=y
 CONFIG_ACPI_PCI=y
 CONFIG_ACPI_SYSTEM=y
+# CONFIG_ACPI_CONTAINER is not set
 
 #
 # CPU Frequency scaling
 #
-# CONFIG_CPU_FREQ is not set
+CONFIG_CPU_FREQ=y
+# CONFIG_CPU_FREQ_DEBUG is not set
+CONFIG_CPU_FREQ_PROC_INTF=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=y
+CONFIG_CPU_FREQ_24_API=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_TABLE=y
+
+#
+# CPUFreq processor drivers
+#
+CONFIG_X86_POWERNOW_K8=y
+CONFIG_X86_POWERNOW_K8_ACPI=y
+# CONFIG_X86_SPEEDSTEP_CENTRINO is not set
+CONFIG_X86_ACPI_CPUFREQ=y
+
+#
+# shared options
+#
+CONFIG_X86_ACPI_CPUFREQ_PROC_INTF=y
 
 #
 # Bus options (PCI etc.)
@@ -174,6 +206,7 @@
 #
 # Plug and Play support
 #
+# CONFIG_PNP is not set
 
 #
 # Block devices
@@ -189,6 +222,7 @@
 # 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=""
@@ -292,6 +326,7 @@
 #
 # CONFIG_SCSI_SPI_ATTRS is not set
 # CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
 
 #
 # SCSI low-level drivers
@@ -337,14 +372,12 @@
 # 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_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_DEBUG is not set
@@ -397,6 +430,8 @@
 # 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
@@ -508,7 +543,9 @@
 # Ethernet (10000 Mbit)
 #
 # CONFIG_IXGB is not set
-# CONFIG_S2IO is not set
+CONFIG_S2IO=m
+# CONFIG_S2IO_NAPI is not set
+# CONFIG_2BUFF_MODE is not set
 
 #
 # Token Ring devices
@@ -743,6 +780,7 @@
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
 CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_UHCI_HCD=y
+# CONFIG_USB_SL811_HCD is not set
 
 #
 # USB Device Class drivers
@@ -752,6 +790,10 @@
 # CONFIG_USB_MIDI is not set
 # CONFIG_USB_ACM is not set
 CONFIG_USB_PRINTER=y
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
 CONFIG_USB_STORAGE=y
 # CONFIG_USB_STORAGE_DEBUG is not set
 # CONFIG_USB_STORAGE_RW_DETECT is not set
@@ -797,7 +839,7 @@
 #
 
 #
-# USB Network adaptors
+# USB Network Adapters
 #
 # CONFIG_USB_CATC is not set
 # CONFIG_USB_KAWETH is not set
@@ -840,6 +882,16 @@
 # CONFIG_USB_GADGET is not set
 
 #
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
 # Firmware Drivers
 #
 # CONFIG_EDD is not set
@@ -870,6 +922,7 @@
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 # CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
 CONFIG_AUTOFS_FS=y
 # CONFIG_AUTOFS4_FS is not set
 
@@ -884,8 +937,11 @@
 #
 # DOS/FAT/NT Filesystems
 #
-# CONFIG_MSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 # CONFIG_NTFS_FS is not set
 
 #
@@ -951,7 +1007,46 @@
 #
 # Native Language Support
 #
-# CONFIG_NLS is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# 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=y
+CONFIG_NLS_ISO8859_1=y
+# 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=y
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=y
 
 #
 # Profiling support
@@ -972,6 +1067,7 @@
 # CONFIG_DEBUG_INFO is not set
 CONFIG_INIT_DEBUG=y
 # CONFIG_IOMMU_DEBUG is not set
+CONFIG_KPROBES=y
 
 #
 # Security options
@@ -983,6 +1079,10 @@
 # Cryptographic options
 #
 # CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
 
 #
 # Library routines
diff -Nru a/arch/x86_64/ia32/fpu32.c b/arch/x86_64/ia32/fpu32.c
--- a/arch/x86_64/ia32/fpu32.c	2005-03-01 23:38:51 -08:00
+++ b/arch/x86_64/ia32/fpu32.c	2005-03-01 23:38:51 -08:00
@@ -28,16 +28,17 @@
 static inline unsigned long twd_fxsr_to_i387(struct i387_fxsave_struct *fxsave)
 {
 	struct _fpxreg *st = NULL;
+	unsigned long tos = (fxsave->swd >> 11) & 7;
 	unsigned long twd = (unsigned long) fxsave->twd;
 	unsigned long tag;
 	unsigned long ret = 0xffff0000;
 	int i;
 
-#define FPREG_ADDR(f, n)	((char *)&(f)->st_space + (n) * 16);
+#define FPREG_ADDR(f, n)	((void *)&(f)->st_space + (n) * 16);
 
 	for (i = 0 ; i < 8 ; i++) {
 		if (twd & 0x1) {
-			st = (struct _fpxreg *) FPREG_ADDR( fxsave, i );
+			st = FPREG_ADDR( fxsave, (i - tos) & 7 );
 
 			switch (st->exponent & 0x7fff) {
 			case 0x7fff:
@@ -156,7 +157,7 @@
 				     sizeof(struct i387_fxsave_struct)))
 			return -1;
 		tsk->thread.i387.fxsave.mxcsr &= mxcsr_feature_mask;
-		tsk->used_math = 1;
+		set_stopped_child_used_math(tsk);
 	} 
 	return convert_fxsr_from_user(&tsk->thread.i387.fxsave, buf);
 }  
diff -Nru a/arch/x86_64/ia32/ia32_aout.c b/arch/x86_64/ia32/ia32_aout.c
--- a/arch/x86_64/ia32/ia32_aout.c	2005-03-01 23:39:17 -08:00
+++ b/arch/x86_64/ia32/ia32_aout.c	2005-03-01 23:39:17 -08:00
@@ -36,7 +36,8 @@
 #undef WARN_OLD
 #undef CORE_DUMP /* probably broken */
 
-extern int ia32_setup_arg_pages(struct linux_binprm *bprm, int exec_stack);
+extern int ia32_setup_arg_pages(struct linux_binprm *bprm,
+				unsigned long stack_top, int exec_stack);
 
 static int load_aout_binary(struct linux_binprm *, struct pt_regs * regs);
 static int load_aout_library(struct file*);
@@ -114,7 +115,9 @@
 	end = PAGE_ALIGN(end);
 	if (end <= start)
 		return;
+	down_write(&current->mm->mmap_sem);
 	do_brk(start, end - start);
+	up_write(&current->mm->mmap_sem);
 }
 
 #if CORE_DUMP
@@ -324,7 +327,10 @@
 		pos = 32;
 		map_size = ex.a_text+ex.a_data;
 
+		down_write(&current->mm->mmap_sem);
 		error = do_brk(text_addr & PAGE_MASK, map_size);
+		up_write(&current->mm->mmap_sem);
+
 		if (error != (text_addr & PAGE_MASK)) {
 			send_sig(SIGKILL, current, 0);
 			return error;
@@ -360,7 +366,9 @@
 
 		if (!bprm->file->f_op->mmap||((fd_offset & ~PAGE_MASK) != 0)) {
 			loff_t pos = fd_offset;
+			down_write(&current->mm->mmap_sem);
 			do_brk(N_TXTADDR(ex), ex.a_text+ex.a_data);
+			up_write(&current->mm->mmap_sem);
 			bprm->file->f_op->read(bprm->file,(char *)N_TXTADDR(ex),
 					ex.a_text+ex.a_data, &pos);
 			flush_icache_range((unsigned long) N_TXTADDR(ex),
@@ -397,7 +405,7 @@
 
 	set_brk(current->mm->start_brk, current->mm->brk);
 
-	retval = ia32_setup_arg_pages(bprm, EXSTACK_DEFAULT);
+	retval = ia32_setup_arg_pages(bprm, IA32_STACK_TOP, EXSTACK_DEFAULT);
 	if (retval < 0) { 
 		/* Someone check-me: is this error path enough? */ 
 		send_sig(SIGKILL, current, 0); 
@@ -468,8 +476,9 @@
 			error_time = jiffies;
 		}
 #endif
-
+		down_write(&current->mm->mmap_sem);
 		do_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss);
+		up_write(&current->mm->mmap_sem);
 		
 		file->f_op->read(file, (char *)start_addr,
 			ex.a_text + ex.a_data, &pos);
@@ -493,7 +502,9 @@
 	len = PAGE_ALIGN(ex.a_text + ex.a_data);
 	bss = ex.a_text + ex.a_data + ex.a_bss;
 	if (bss > len) {
+		down_write(&current->mm->mmap_sem);
 		error = do_brk(start_addr + len, bss - len);
+		up_write(&current->mm->mmap_sem);
 		retval = error;
 		if (error != start_addr + len)
 			goto out;
diff -Nru a/arch/x86_64/ia32/ia32_binfmt.c b/arch/x86_64/ia32/ia32_binfmt.c
--- a/arch/x86_64/ia32/ia32_binfmt.c	2005-03-01 23:38:51 -08:00
+++ b/arch/x86_64/ia32/ia32_binfmt.c	2005-03-01 23:38:51 -08:00
@@ -214,7 +214,7 @@
 	struct _fpstate_ia32 *fpstate = (void*)fpu; 
 	mm_segment_t oldfs = get_fs();
 
-	if (!tsk->used_math) 
+	if (!tsk_used_math(tsk))
 		return 0;
 	if (!regs)
 		regs = (struct pt_regs *)tsk->thread.rsp0;
@@ -235,7 +235,7 @@
 elf_core_copy_task_xfpregs(struct task_struct *t, elf_fpxregset_t *xfpu)
 {
 	struct pt_regs *regs = ((struct pt_regs *)(t->thread.rsp0))-1; 
-	if (!t->used_math) 
+	if (!tsk_used_math(t))
 		return 0;
 	if (t == current)
 		unlazy_fpu(t); 
@@ -249,6 +249,8 @@
 #define elf_check_arch(x) \
 	((x)->e_machine == EM_386)
 
+extern int force_personality32;
+
 #define ELF_EXEC_PAGESIZE PAGE_SIZE
 #define ELF_HWCAP (boot_cpu_data.x86_capability[0])
 #define ELF_PLATFORM  ("i686")
@@ -262,6 +264,8 @@
 		set_thread_flag(TIF_ABI_PENDING);		\
 	else							\
 		clear_thread_flag(TIF_ABI_PENDING);		\
+	/* XXX This overwrites the user set personality */	\
+	current->personality |= force_personality32;		\
 } while (0)
 
 /* Override some function names */
@@ -273,8 +277,9 @@
 #define load_elf_binary load_elf32_binary
 
 #define ELF_PLAT_INIT(r, load_addr)	elf32_init(r)
-#define setup_arg_pages(bprm, exec_stack)	ia32_setup_arg_pages(bprm, exec_stack)
-int ia32_setup_arg_pages(struct linux_binprm *bprm, int executable_stack);
+#define setup_arg_pages(bprm, stack_top, exec_stack) \
+	ia32_setup_arg_pages(bprm, stack_top, exec_stack)
+int ia32_setup_arg_pages(struct linux_binprm *bprm, unsigned long stack_top, int executable_stack);
 
 #undef start_thread
 #define start_thread(regs,new_rip,new_rsp) do { \
@@ -329,7 +334,7 @@
 	me->thread.es = __USER_DS;
 }
 
-int setup_arg_pages(struct linux_binprm *bprm, int executable_stack)
+int setup_arg_pages(struct linux_binprm *bprm, unsigned long stack_top, int executable_stack)
 {
 	unsigned long stack_base;
 	struct vm_area_struct *mpnt;
diff -Nru a/arch/x86_64/ia32/ia32_signal.c b/arch/x86_64/ia32/ia32_signal.c
--- a/arch/x86_64/ia32/ia32_signal.c	2005-03-01 23:39:17 -08:00
+++ b/arch/x86_64/ia32/ia32_signal.c	2005-03-01 23:39:17 -08:00
@@ -35,8 +35,6 @@
 #include <asm/proto.h>
 #include <asm/vsyscall32.h>
 
-#define ptr_to_u32(x) ((u32)(u64)(x))	/* avoid gcc warning */ 
-
 #define DEBUG_SIG 0
 
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
@@ -44,10 +42,10 @@
 asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset);
 void signal_fault(struct pt_regs *regs, void __user *frame, char *where);
 
-int ia32_copy_siginfo_to_user(siginfo_t32 __user *to, siginfo_t *from)
+int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
 {
 	int err;
-	if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t32)))
+	if (!access_ok (VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
 		return -EFAULT;
 
 	/* If you change siginfo_t structure, please make sure that
@@ -62,7 +60,7 @@
 	if (from->si_code < 0) {
 		err |= __put_user(from->si_pid, &to->si_pid);
  		err |= __put_user(from->si_uid, &to->si_uid);
- 		err |= __put_user((u32)(u64)from->si_ptr, &to->si_ptr);
+ 		err |= __put_user(ptr_to_compat(from->si_ptr), &to->si_ptr);
 	} else {
  		/* First 32bits of unions are always present:
  		 * si_pid === si_band === si_tid === si_addr(LS half) */
@@ -83,7 +81,7 @@
 			break;
 		case __SI_TIMER >> 16:
 			err |= __put_user(from->si_overrun, &to->si_overrun); 
-			err |= __put_user((u32)(u64)from->si_ptr, &to->si_ptr);
+			err |= __put_user(ptr_to_compat(from->si_ptr), &to->si_ptr);
 			break;
 		case __SI_RT >> 16: /* This is not generated by the kernel as of now.  */
 		case __SI_MESGQ >> 16:
@@ -95,11 +93,11 @@
 	return err;
 }
 
-int ia32_copy_siginfo_from_user(siginfo_t *to, siginfo_t32 __user *from)
+int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
 {
 	int err;
 	u32 ptr32;
-	if (!access_ok (VERIFY_READ, from, sizeof(siginfo_t32)))
+	if (!access_ok (VERIFY_READ, from, sizeof(compat_siginfo_t)))
 		return -EFAULT;
 
 	err = __get_user(to->si_signo, &from->si_signo);
@@ -160,7 +158,7 @@
 	set_fs(seg); 
 	if (ret >= 0 && uoss_ptr)  {
 		if (!access_ok(VERIFY_WRITE,uoss_ptr,sizeof(stack_ia32_t)) ||
-		    __put_user((u32)(u64)uoss.ss_sp, &uoss_ptr->ss_sp) ||
+		    __put_user(ptr_to_compat(uoss.ss_sp), &uoss_ptr->ss_sp) ||
 		    __put_user(uoss.ss_flags, &uoss_ptr->ss_flags) ||
 		    __put_user(uoss.ss_size, &uoss_ptr->ss_size))
 			ret = -EFAULT;
@@ -188,7 +186,7 @@
 	int sig;
 	u32 pinfo;
 	u32 puc;
-	struct siginfo32 info;
+	compat_siginfo_t info;
 	struct ucontext_ia32 uc;
 	struct _fpstate_ia32 fpstate;
 	char retcode[8];
@@ -261,6 +259,12 @@
 			if (verify_area(VERIFY_READ, buf, sizeof(*buf)))
 				goto badframe;
 			err |= restore_i387_ia32(current, buf, 0);
+		} else {
+			struct task_struct *me = current;
+			if (used_math()) {
+				clear_fpu(me);
+				clear_used_math();
+			}
 		}
 	}
 
@@ -383,9 +387,9 @@
 	if (tmp < 0)
 	  err = -EFAULT;
 	else { 
-		current->used_math = 0;
+		clear_used_math();
 		stts();
-	  err |= __put_user((u32)(u64)(tmp ? fpstate : NULL), &sc->fpstate);
+	  err |= __put_user(ptr_to_compat(tmp ? fpstate : NULL), &sc->fpstate);
 	}
 
 	/* non-iBCS2 extensions.. */
@@ -461,7 +465,7 @@
 		void __user *restorer = VSYSCALL32_SIGRETURN; 
 		if (ka->sa.sa_flags & SA_RESTORER)
 			restorer = ka->sa.sa_restorer;       
-		err |= __put_user(ptr_to_u32(restorer), &frame->pretcode);
+		err |= __put_user(ptr_to_compat(restorer), &frame->pretcode);
 	}
 	/* These are actually not used anymore, but left because some 
 	   gdb versions depend on them as a marker. */
@@ -534,9 +538,9 @@
 			   : sig),
 			  &frame->sig);
 	}
-	err |= __put_user((u32)(u64)&frame->info, &frame->pinfo);
-	err |= __put_user((u32)(u64)&frame->uc, &frame->puc);
-	err |= ia32_copy_siginfo_to_user(&frame->info, info);
+	err |= __put_user(ptr_to_compat(&frame->info), &frame->pinfo);
+	err |= __put_user(ptr_to_compat(&frame->uc), &frame->puc);
+	err |= copy_siginfo_to_user32(&frame->info, info);
 	if (err)
 		goto give_sigsegv;
 
@@ -558,7 +562,7 @@
 		void __user *restorer = VSYSCALL32_RTSIGRETURN; 
 		if (ka->sa.sa_flags & SA_RESTORER)
 			restorer = ka->sa.sa_restorer;       
-		err |= __put_user(ptr_to_u32(restorer), &frame->pretcode);
+		err |= __put_user(ptr_to_compat(restorer), &frame->pretcode);
 	}
 
 	/* This is movl $,%eax ; int $0x80 */
diff -Nru a/arch/x86_64/ia32/ia32entry.S b/arch/x86_64/ia32/ia32entry.S
--- a/arch/x86_64/ia32/ia32entry.S	2005-03-01 23:38:56 -08:00
+++ b/arch/x86_64/ia32/ia32entry.S	2005-03-01 23:38:56 -08:00
@@ -315,7 +315,7 @@
 	.quad sys_unlink		/* 10 */
 	.quad stub32_execve
 	.quad sys_chdir
-	.quad sys32_time
+	.quad compat_sys_time
 	.quad sys_mknod
 	.quad sys_chmod		/* 15 */
 	.quad sys_lchown16
@@ -327,7 +327,7 @@
 	.quad sys_oldumount	/* old_umount  */
 	.quad sys_setuid16
 	.quad sys_getuid16
-	.quad sys_stime		/* stime */		/* 25 */
+	.quad compat_sys_stime	/* stime */		/* 25 */
 	.quad sys32_ptrace	/* ptrace */
 	.quad sys_alarm
 	.quad sys_fstat	/* (old)fstat */
@@ -388,7 +388,11 @@
 	.quad sys_symlink
 	.quad sys_lstat
 	.quad sys_readlink		/* 85 */
+#ifdef CONFIG_IA32_AOUT
 	.quad sys_uselib
+#else
+	.quad quiet_ni_syscall
+#endif
 	.quad sys_swapon
 	.quad sys_reboot
 	.quad compat_sys_old_readdir
@@ -479,7 +483,7 @@
 	.quad sys32_rt_sigaction
 	.quad sys32_rt_sigprocmask	/* 175 */
 	.quad sys32_rt_sigpending
-	.quad sys32_rt_sigtimedwait
+	.quad compat_sys_rt_sigtimedwait
 	.quad sys32_rt_sigqueueinfo
 	.quad stub32_rt_sigsuspend
 	.quad sys32_pread		/* 180 */
@@ -587,6 +591,10 @@
 	.quad compat_sys_mq_getsetattr
 	.quad quiet_ni_syscall		/* reserved for kexec */
 	.quad sys32_waitid
+	.quad quiet_ni_syscall		/* sys_altroot */
+	.quad sys_add_key
+	.quad sys_request_key
+	.quad sys_keyctl
 	/* don't forget to change IA32_NR_syscalls */
 ia32_syscall_end:		
 	.rept IA32_NR_syscalls-(ia32_syscall_end-ia32_sys_call_table)/8
diff -Nru a/arch/x86_64/ia32/ipc32.c b/arch/x86_64/ia32/ipc32.c
--- a/arch/x86_64/ia32/ipc32.c	2005-03-01 23:38:56 -08:00
+++ b/arch/x86_64/ia32/ipc32.c	2005-03-01 23:38:56 -08:00
@@ -49,7 +49,7 @@
 	      case SHMDT:
 		return sys_shmdt(compat_ptr(ptr));
 	      case SHMGET:
-		return sys_shmget(first, second, third);
+		return sys_shmget(first, (unsigned)second, third);
 	      case SHMCTL:
 		return compat_sys_shmctl(first, second, compat_ptr(ptr));
 	}
diff -Nru a/arch/x86_64/ia32/ptrace32.c b/arch/x86_64/ia32/ptrace32.c
--- a/arch/x86_64/ia32/ptrace32.c	2005-03-01 23:38:54 -08:00
+++ b/arch/x86_64/ia32/ptrace32.c	2005-03-01 23:38:54 -08:00
@@ -358,14 +358,14 @@
 			break;
 		/* no checking to be bug-to-bug compatible with i386 */
 		__copy_from_user(&child->thread.i387.fxsave, u, sizeof(*u));
-		child->used_math = 1;
+		set_stopped_child_used_math(child);
 		child->thread.i387.fxsave.mxcsr &= mxcsr_feature_mask;
 		ret = 0; 
 		break;
 	}
 
 	case PTRACE_GETEVENTMSG:
-		ret = put_user(child->ptrace_message,(unsigned int __user *)(u64)data);
+		ret = put_user(child->ptrace_message,(unsigned int __user *)compat_ptr(data));
 		break;
 
 	default:
diff -Nru a/arch/x86_64/ia32/sys_ia32.c b/arch/x86_64/ia32/sys_ia32.c
--- a/arch/x86_64/ia32/sys_ia32.c	2005-03-01 23:38:56 -08:00
+++ b/arch/x86_64/ia32/sys_ia32.c	2005-03-01 23:38:56 -08:00
@@ -73,10 +73,7 @@
 #include <net/sock.h>
 #include <asm/ia32.h>
 
-#define A(__x)		((unsigned long)(__x))
 #define AA(__x)		((unsigned long)(__x))
-#define ROUND_UP(x,a)	((__typeof__(x))(((unsigned long)(x) + ((a) - 1)) & ~((a) - 1)))
-#define NAME_OFFSET(de) ((int) ((de)->d_name - (char __user *) (de)))
 
 int cp_compat_stat(struct kstat *kbuf, struct compat_stat __user *ubuf)
 {
@@ -305,8 +302,8 @@
 			set32.sig[0] = old_ka.sa.sa_mask.sig[0];
 		}
 		if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
-		    __put_user((long)old_ka.sa.sa_handler, &oact->sa_handler) ||
-		    __put_user((long)old_ka.sa.sa_restorer, &oact->sa_restorer) ||
+		    __put_user(ptr_to_compat(old_ka.sa.sa_handler), &oact->sa_handler) ||
+		    __put_user(ptr_to_compat(old_ka.sa.sa_restorer), &oact->sa_restorer) ||
 		    __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
 		    __copy_to_user(&oact->sa_mask, &set32, sizeof(compat_sigset_t)))
 			return -EFAULT;
@@ -342,8 +339,8 @@
 
 	if (!ret && oact) {
 		if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
-		    __put_user((long)old_ka.sa.sa_handler, &oact->sa_handler) ||
-		    __put_user((long)old_ka.sa.sa_restorer, &oact->sa_restorer) ||
+		    __put_user(ptr_to_compat(old_ka.sa.sa_handler), &oact->sa_handler) ||
+		    __put_user(ptr_to_compat(old_ka.sa.sa_restorer), &oact->sa_restorer) ||
 		    __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
 		    __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask))
 			return -EFAULT;
@@ -492,26 +489,6 @@
 				 compat_ptr(a.exp), compat_ptr(a.tvp));
 }
 
-/*
- * sys_time() can be implemented in user-level using
- * sys_gettimeofday().  x86-64 did this but i386 Linux did not
- * so we have to implement this system call here.
- */
-asmlinkage long sys32_time(int __user * tloc)
-{
-	int i;
-	struct timeval tv;
-
-	do_gettimeofday(&tv);
-	i = tv.tv_sec;
-
-	if (tloc) {
-		if (put_user(i,tloc))
-			i = -EFAULT;
-	}
-	return i;
-}
-
 extern asmlinkage long
 compat_sys_wait4(compat_pid_t pid, compat_uint_t * stat_addr, int options,
 		 struct compat_rusage *ru);
@@ -648,53 +625,14 @@
 	return ret;
 }
 
-
-asmlinkage long
-sys32_rt_sigtimedwait(compat_sigset_t __user *uthese, siginfo_t32 __user *uinfo,
-		      struct compat_timespec __user *uts, compat_size_t sigsetsize)
-{
-	sigset_t s;
-	compat_sigset_t s32;
-	struct timespec t;
-	int ret;
-	mm_segment_t old_fs = get_fs();
-	siginfo_t info;
-		
-	if (copy_from_user (&s32, uthese, sizeof(compat_sigset_t)))
-		return -EFAULT;
-	switch (_NSIG_WORDS) {
-	case 4: s.sig[3] = s32.sig[6] | (((long)s32.sig[7]) << 32);
-	case 3: s.sig[2] = s32.sig[4] | (((long)s32.sig[5]) << 32);
-	case 2: s.sig[1] = s32.sig[2] | (((long)s32.sig[3]) << 32);
-	case 1: s.sig[0] = s32.sig[0] | (((long)s32.sig[1]) << 32);
-	}
-	if (uts && get_compat_timespec(&t, uts))
-		return -EFAULT;
-	if (uinfo) {
-		/* stop data leak to user space in case of structure fill mismatch
-		 * between sys_rt_sigtimedwait & ia32_copy_siginfo_to_user.
-		 */
-		memset(&info, 0, sizeof(info));
-	}
-	set_fs (KERNEL_DS);
-	ret = sys_rt_sigtimedwait(&s, uinfo ? &info : NULL, uts ? &t : NULL,
-			sigsetsize);
-	set_fs (old_fs);
-	if (ret >= 0 && uinfo) {
-		if (ia32_copy_siginfo_to_user(uinfo, &info))
-			return -EFAULT;
-	}
-	return ret;
-}
-
 asmlinkage long
-sys32_rt_sigqueueinfo(int pid, int sig, siginfo_t32 __user *uinfo)
+sys32_rt_sigqueueinfo(int pid, int sig, compat_siginfo_t __user *uinfo)
 {
 	siginfo_t info;
 	int ret;
 	mm_segment_t old_fs = get_fs();
 	
-	if (ia32_copy_siginfo_from_user(&info, uinfo))
+	if (copy_siginfo_from_user32(&info, uinfo))
 		return -EFAULT;
 	set_fs (KERNEL_DS);
 	ret = sys_rt_sigqueueinfo(pid, sig, &info);
@@ -712,6 +650,7 @@
 }
 
 
+#ifdef CONFIG_SYSCTL
 struct sysctl_ia32 {
 	unsigned int	name;
 	int		nlen;
@@ -726,14 +665,11 @@
 asmlinkage long
 sys32_sysctl(struct sysctl_ia32 __user *args32)
 {
-#ifndef CONFIG_SYSCTL
-	return -ENOSYS; 
-#else
 	struct sysctl_ia32 a32;
 	mm_segment_t old_fs = get_fs ();
-	void *oldvalp, *newvalp;
+	void __user *oldvalp, *newvalp;
 	size_t oldlen;
-	int *namep;
+	int __user *namep;
 	long ret;
 	extern int do_sysctl(int *name, int nlen, void *oldval, size_t *oldlenp,
 		     void *newval, size_t newlen);
@@ -749,9 +685,9 @@
 	 * addresses, we KNOW that access_ok() will always succeed, so this is an
 	 * expensive NOP, but so what...
 	 */
-	namep = (int *) A(a32.name);
-	oldvalp = (void *) A(a32.oldval);
-	newvalp = (void *) A(a32.newval);
+	namep = compat_ptr(a32.name);
+	oldvalp = compat_ptr(a32.oldval);
+	newvalp =  compat_ptr(a32.newval);
 
 	if ((oldvalp && get_user(oldlen, (int __user *)compat_ptr(a32.oldlenp)))
 	    || !access_ok(VERIFY_WRITE, namep, 0)
@@ -769,8 +705,8 @@
 		return -EFAULT;
 
 	return ret;
-#endif
 }
+#endif
 
 /* warning: next two assume little endian */ 
 asmlinkage long
@@ -1020,7 +956,7 @@
 }
 
 asmlinkage long sys32_waitid(int which, compat_pid_t pid,
-			     siginfo_t32 __user *uinfo, int options,
+			     compat_siginfo_t __user *uinfo, int options,
 			     struct compat_rusage __user *uru)
 {
 	siginfo_t info;
@@ -1042,7 +978,7 @@
 
 	BUG_ON(info.si_code & __SI_MASK);
 	info.si_code |= __SI_CHLD;
-	return ia32_copy_siginfo_to_user(uinfo, &info);
+	return copy_siginfo_to_user32(uinfo, &info);
 }
 
 /*
@@ -1140,8 +1076,6 @@
 {
 	return sys_lookup_dcookie(((u64)addr_high << 32) | addr_low, buf, len);
 }
-
-cond_syscall(sys32_ipc)
 
 static int __init ia32_init (void)
 {
diff -Nru a/arch/x86_64/ia32/syscall32.c b/arch/x86_64/ia32/syscall32.c
--- a/arch/x86_64/ia32/syscall32.c	2005-03-01 23:39:07 -08:00
+++ b/arch/x86_64/ia32/syscall32.c	2005-03-01 23:39:07 -08:00
@@ -40,23 +40,30 @@
  */
 int __map_syscall32(struct mm_struct *mm, unsigned long address)
 { 
+	pgd_t *pgd;
+	pud_t *pud;
 	pte_t *pte;
 	pmd_t *pmd;
-	int err = 0;
+	int err = -ENOMEM;
 
 	spin_lock(&mm->page_table_lock); 
-	pmd = pmd_alloc(mm, pgd_offset(mm, address), address); 
-	if (pmd && (pte = pte_alloc_map(mm, pmd, address)) != NULL) { 
-		if (pte_none(*pte)) { 
-			set_pte(pte, 
-				mk_pte(virt_to_page(syscall32_page), 
-				       PAGE_KERNEL_VSYSCALL)); 
+ 	pgd = pgd_offset(mm, address);
+ 	pud = pud_alloc(mm, pgd, address);
+ 	if (pud) {
+ 		pmd = pmd_alloc(mm, pud, address);
+ 		if (pmd && (pte = pte_alloc_map(mm, pmd, address)) != NULL) {
+ 			if (pte_none(*pte)) {
+ 				set_pte(pte,
+ 					mk_pte(virt_to_page(syscall32_page),
+ 					       PAGE_KERNEL_VSYSCALL32));
+ 			}
+ 			/* Flush only the local CPU. Other CPUs taking a fault
+ 			   will just end up here again
+			   This probably not needed and just paranoia. */
+ 			__flush_tlb_one(address);
+ 			err = 0;
 		}
-		/* Flush only the local CPU. Other CPUs taking a fault
-		   will just end up here again */
-		__flush_tlb_one(address); 
-	} else
-		err = -ENOMEM; 
+	}
 	spin_unlock(&mm->page_table_lock);
 	return err;
 }
diff -Nru a/arch/x86_64/kernel/Makefile b/arch/x86_64/kernel/Makefile
--- a/arch/x86_64/kernel/Makefile	2005-03-01 23:39:08 -08:00
+++ b/arch/x86_64/kernel/Makefile	2005-03-01 23:39:08 -08:00
@@ -7,9 +7,10 @@
 obj-y	:= process.o semaphore.o signal.o entry.o traps.o irq.o \
 		ptrace.o time.o ioport.o ldt.o setup.o i8259.o sys_x86_64.o \
 		x8664_ksyms.o i387.o syscall.o vsyscall.o \
-		setup64.o bootflag.o e820.o reboot.o warmreboot.o quirks.o
+		setup64.o bootflag.o e820.o reboot.o quirks.o
 
 obj-$(CONFIG_X86_MCE)         += mce.o
+obj-$(CONFIG_X86_MCE_INTEL)	+= mce_intel.o
 obj-$(CONFIG_MTRR)		+= ../../i386/kernel/cpu/mtrr/
 obj-$(CONFIG_ACPI_BOOT)		+= acpi/
 obj-$(CONFIG_X86_MSR)		+= msr.o
@@ -32,6 +33,8 @@
 
 obj-y				+= topology.o
 obj-y				+= intel_cacheinfo.o
+
+CFLAGS_vsyscall.o		:= $(PROFILING) -g0
 
 bootflag-y			+= ../../i386/kernel/bootflag.o
 cpuid-$(subst m,y,$(CONFIG_X86_CPUID))  += ../../i386/kernel/cpuid.o
diff -Nru a/arch/x86_64/kernel/acpi/sleep.c b/arch/x86_64/kernel/acpi/sleep.c
--- a/arch/x86_64/kernel/acpi/sleep.c	2005-03-01 23:38:52 -08:00
+++ b/arch/x86_64/kernel/acpi/sleep.c	2005-03-01 23:38:52 -08:00
@@ -61,9 +61,13 @@
 
 extern unsigned long FASTCALL(acpi_copy_wakeup_routine(unsigned long));
 
+static pgd_t low_ptr;
+
 static void init_low_mapping(void)
 {
-	cpu_pda[0].level4_pgt[0] = cpu_pda[0].level4_pgt[pml4_index(PAGE_OFFSET)];
+	pgd_t *slot0 = pgd_offset(current->mm, 0UL);
+	low_ptr = *slot0;
+	set_pgd(slot0, *pgd_offset(current->mm, PAGE_OFFSET));
 	flush_tlb_all();
 }
 
@@ -97,7 +101,7 @@
  */
 void acpi_restore_state_mem (void)
 {
-	cpu_pda[0].level4_pgt[0] = 0;
+	set_pgd(pgd_offset(current->mm, 0UL), low_ptr);
 	flush_tlb_all();
 }
 
diff -Nru a/arch/x86_64/kernel/acpi/wakeup.S b/arch/x86_64/kernel/acpi/wakeup.S
--- a/arch/x86_64/kernel/acpi/wakeup.S	2005-03-01 23:39:07 -08:00
+++ b/arch/x86_64/kernel/acpi/wakeup.S	2005-03-01 23:39:07 -08:00
@@ -429,9 +429,6 @@
 do_suspend_lowlevel:
 .LFB5:
 	subq	$8, %rsp
-.LCFI2:
-	testl	%edi, %edi
-	jne	.L99
 	xorl	%eax, %eax
 	call	save_processor_state
 
diff -Nru a/arch/x86_64/kernel/aperture.c b/arch/x86_64/kernel/aperture.c
--- a/arch/x86_64/kernel/aperture.c	2005-03-01 23:39:08 -08:00
+++ b/arch/x86_64/kernel/aperture.c	2005-03-01 23:39:08 -08:00
@@ -200,8 +200,8 @@
 void __init iommu_hole_init(void) 
 { 
 	int fix, num; 
-	u32 aper_size, aper_alloc = 0, aper_order;
-	u64 aper_base; 
+	u32 aper_size, aper_alloc = 0, aper_order, last_aper_order = 0;
+	u64 aper_base, last_aper_base = 0;
 	int valid_agp = 0;
 
 	if (iommu_aperture_disabled || !fix_aperture)
@@ -230,7 +230,15 @@
 		if (!aperture_valid(name, aper_base, aper_size)) { 
 			fix = 1; 
 			break; 
-		} 
+		}
+
+		if ((last_aper_order && aper_order != last_aper_order) ||
+		    (last_aper_base && aper_base != last_aper_base)) {
+			fix = 1;
+			break;
+		}
+		last_aper_order = aper_order;
+		last_aper_base = aper_base;
 	} 
 
 	if (!fix && !fallback_aper_force) 
diff -Nru a/arch/x86_64/kernel/apic.c b/arch/x86_64/kernel/apic.c
--- a/arch/x86_64/kernel/apic.c	2005-03-01 23:38:53 -08:00
+++ b/arch/x86_64/kernel/apic.c	2005-03-01 23:38:53 -08:00
@@ -225,6 +225,11 @@
 
 void __init sync_Arb_IDs(void)
 {
+	/* Unsupported on P4 - see Intel Dev. Manual Vol. 3, Ch. 8.6.1 */
+	unsigned int ver = GET_APIC_VERSION(apic_read(APIC_LVR));
+	if (ver >= 0x14)	/* P4 or higher */
+		return;
+
 	/*
 	 * Wait for idle.
 	 */
diff -Nru a/arch/x86_64/kernel/asm-offsets.c b/arch/x86_64/kernel/asm-offsets.c
--- a/arch/x86_64/kernel/asm-offsets.c	2005-03-01 23:38:58 -08:00
+++ b/arch/x86_64/kernel/asm-offsets.c	2005-03-01 23:38:58 -08:00
@@ -8,6 +8,7 @@
 #include <linux/stddef.h>
 #include <linux/errno.h> 
 #include <linux/hardirq.h>
+#include <linux/suspend.h>
 #include <asm/pda.h>
 #include <asm/processor.h>
 #include <asm/segment.h>
@@ -61,6 +62,8 @@
 	       offsetof (struct rt_sigframe32, uc.uc_mcontext));
 	BLANK();
 #endif
-
+	DEFINE(SIZEOF_PBE, sizeof(struct pbe));
+	DEFINE(pbe_address, offsetof(struct pbe, address));
+	DEFINE(pbe_orig_address, offsetof(struct pbe, orig_address));
 	return 0;
 }
diff -Nru a/arch/x86_64/kernel/early_printk.c b/arch/x86_64/kernel/early_printk.c
--- a/arch/x86_64/kernel/early_printk.c	2005-03-01 23:39:08 -08:00
+++ b/arch/x86_64/kernel/early_printk.c	2005-03-01 23:39:08 -08:00
@@ -10,7 +10,7 @@
 #ifdef __i386__
 #define VGABASE		(__ISA_IO_base + 0xb8000)
 #else
-#define VGABASE		((void *)0xffffffff800b8000UL)
+#define VGABASE		((void __iomem *)0xffffffff800b8000UL)
 #endif
 
 #define MAX_YPOS	25
@@ -198,9 +198,6 @@
 		early_console = &early_serial_console;		
 	} else if (!strncmp(buf, "vga", 3)) {
 		early_console = &early_vga_console; 
-	} else {
-		early_console = NULL; 		
-		return -1; 
 	}
 	early_console_initialized = 1;
 	register_console(early_console);       
diff -Nru a/arch/x86_64/kernel/entry.S b/arch/x86_64/kernel/entry.S
--- a/arch/x86_64/kernel/entry.S	2005-03-01 23:38:55 -08:00
+++ b/arch/x86_64/kernel/entry.S	2005-03-01 23:38:55 -08:00
@@ -41,7 +41,6 @@
 #include <asm/unistd.h>
 #include <asm/thread_info.h>
 #include <asm/hw_irq.h>
-#include <asm/errno.h>
 
 	.code64
 
@@ -537,6 +536,9 @@
 	jmp ret_from_intr
 	CFI_ENDPROC
 	.endm
+
+ENTRY(thermal_interrupt)
+	apicinterrupt THERMAL_APIC_VECTOR,smp_thermal_interrupt
 
 #ifdef CONFIG_SMP	
 ENTRY(reschedule_interrupt)
diff -Nru a/arch/x86_64/kernel/genapic.c b/arch/x86_64/kernel/genapic.c
--- a/arch/x86_64/kernel/genapic.c	2005-03-01 23:39:18 -08:00
+++ b/arch/x86_64/kernel/genapic.c	2005-03-01 23:39:18 -08:00
@@ -41,6 +41,12 @@
 	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;
+	}
+
 	memset(cluster_cnt, 0, sizeof(cluster_cnt));
 
 	for (i = 0; i < NR_CPUS; i++) {
@@ -71,6 +77,7 @@
 	else
 		genapic = &apic_cluster;
 
+print:
 	printk(KERN_INFO "Setting APIC routing to %s\n", genapic->name);
 }
 
diff -Nru a/arch/x86_64/kernel/head.S b/arch/x86_64/kernel/head.S
--- a/arch/x86_64/kernel/head.S	2005-03-01 23:39:07 -08:00
+++ b/arch/x86_64/kernel/head.S	2005-03-01 23:39:07 -08:00
@@ -225,7 +225,6 @@
 	.quad	0x0000000000103007		/* -> level3_kernel_pgt */
 
 .org 0x2000
-/* Kernel does not "know" about 4-th level of page tables. */
 ENTRY(level3_ident_pgt)
 	.quad	0x0000000000104007
 	.fill	511,8,0
@@ -356,7 +355,7 @@
 	.quad	0x008f9a000000ffff	/* __KERNEL_COMPAT32_CS */	
 	.quad	0x00af9a000000ffff	/* __KERNEL_CS */
 	.quad	0x00cf92000000ffff	/* __KERNEL_DS */
-	.quad	0x00cffe000000ffff	/* __USER32_CS */
+	.quad	0x00cffa000000ffff	/* __USER32_CS */
 	.quad	0x00cff2000000ffff	/* __USER_DS, __USER32_DS  */		
 	.quad	0x00affa000000ffff	/* __USER_CS */
 	.quad	0x00cf9a000000ffff	/* __KERNEL32_CS */
diff -Nru a/arch/x86_64/kernel/head64.c b/arch/x86_64/kernel/head64.c
--- a/arch/x86_64/kernel/head64.c	2005-03-01 23:38:56 -08:00
+++ b/arch/x86_64/kernel/head64.c	2005-03-01 23:38:56 -08:00
@@ -61,16 +61,17 @@
 
 static void __init setup_boot_cpu_data(void)
 {
-	int dummy, eax;
+	unsigned int dummy, eax;
 
 	/* get vendor info */
-	cpuid(0, &boot_cpu_data.cpuid_level,
-	      (int *)&boot_cpu_data.x86_vendor_id[0],
-	      (int *)&boot_cpu_data.x86_vendor_id[8],
-	      (int *)&boot_cpu_data.x86_vendor_id[4]);
+	cpuid(0, (unsigned int *)&boot_cpu_data.cpuid_level,
+	      (unsigned int *)&boot_cpu_data.x86_vendor_id[0],
+	      (unsigned int *)&boot_cpu_data.x86_vendor_id[8],
+	      (unsigned int *)&boot_cpu_data.x86_vendor_id[4]);
 
 	/* get cpu type */
-	cpuid(1, &eax, &dummy, &dummy, (int *) &boot_cpu_data.x86_capability);
+	cpuid(1, &eax, &dummy, &dummy,
+		(unsigned int *) &boot_cpu_data.x86_capability);
 	boot_cpu_data.x86 = (eax >> 8) & 0xf;
 	boot_cpu_data.x86_model = (eax >> 4) & 0xf;
 	boot_cpu_data.x86_mask = eax & 0xf;
diff -Nru a/arch/x86_64/kernel/i387.c b/arch/x86_64/kernel/i387.c
--- a/arch/x86_64/kernel/i387.c	2005-03-01 23:38:54 -08:00
+++ b/arch/x86_64/kernel/i387.c	2005-03-01 23:38:54 -08:00
@@ -57,12 +57,12 @@
 	mxcsr_feature_mask_init();
 	/* clean state in init */
 	current_thread_info()->status = 0;
-	current->used_math = 0;
+	clear_used_math();
 }
 
 void init_fpu(struct task_struct *child)
 {
-	if (child->used_math) { 
+	if (tsk_used_math(child)) {
 		if (child == current)
 			unlazy_fpu(child);
 		return;
@@ -70,7 +70,8 @@
 	memset(&child->thread.i387.fxsave, 0, sizeof(struct i387_fxsave_struct));
 	child->thread.i387.fxsave.cwd = 0x37f;
 	child->thread.i387.fxsave.mxcsr = 0x1f80;
-	child->used_math = 1;
+	/* only the device not available exception or ptrace can call init_fpu */
+	set_stopped_child_used_math(child);
 }
 
 /*
@@ -91,9 +92,9 @@
 	if ((unsigned long)buf % 16) 
 		printk("save_i387: bad fpstate %p\n",buf); 
 
-	if (!tsk->used_math) 
+	if (!used_math())
 		return 0;
-	tsk->used_math = 0; /* trigger finit */ 
+	clear_used_math(); /* trigger finit */
 	if (tsk->thread_info->status & TS_USEDFPU) {
 		err = save_i387_checking((struct i387_fxsave_struct __user *)buf);
 		if (err) return err;
@@ -133,7 +134,7 @@
 {
 	struct task_struct *tsk = current;
 
-	if (!tsk->used_math) 
+	if (!used_math())
 		return 0;
 
 	unlazy_fpu(tsk);
@@ -143,7 +144,7 @@
 
 int dump_task_fpu(struct task_struct *tsk, struct user_i387_struct *fpu)
 {
-	int fpvalid = tsk->used_math;
+	int fpvalid = !!tsk_used_math(tsk);
 
 	if (fpvalid) {
 		if (tsk == current)
diff -Nru a/arch/x86_64/kernel/i8259.c b/arch/x86_64/kernel/i8259.c
--- a/arch/x86_64/kernel/i8259.c	2005-03-01 23:38:53 -08:00
+++ b/arch/x86_64/kernel/i8259.c	2005-03-01 23:38:53 -08:00
@@ -130,7 +130,7 @@
  * moves to arch independent land
  */
 
-spinlock_t i8259A_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(i8259A_lock);
 
 static void end_8259A_irq (unsigned int irq)
 {
@@ -476,6 +476,7 @@
 void reschedule_interrupt(void);
 void call_function_interrupt(void);
 void invalidate_interrupt(void);
+void thermal_interrupt(void);
 
 static void setup_timer(void)
 {
@@ -550,6 +551,7 @@
 	/* IPI for generic function call */
 	set_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt);
 #endif	
+	set_intr_gate(THERMAL_APIC_VECTOR, thermal_interrupt);
 
 #ifdef CONFIG_X86_LOCAL_APIC
 	/* self generated IPI for local APIC timer */
diff -Nru a/arch/x86_64/kernel/init_task.c b/arch/x86_64/kernel/init_task.c
--- a/arch/x86_64/kernel/init_task.c	2005-03-01 23:38:58 -08:00
+++ b/arch/x86_64/kernel/init_task.c	2005-03-01 23:38:58 -08:00
@@ -47,5 +47,3 @@
 DEFINE_PER_CPU(struct tss_struct, init_tss) ____cacheline_maxaligned_in_smp;
 
 #define ALIGN_TO_4K __attribute__((section(".data.init_task")))
-
-pgd_t boot_vmalloc_pgt[512]  ALIGN_TO_4K;
diff -Nru a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c
--- a/arch/x86_64/kernel/io_apic.c	2005-03-01 23:38:57 -08:00
+++ b/arch/x86_64/kernel/io_apic.c	2005-03-01 23:38:57 -08:00
@@ -42,7 +42,7 @@
 
 int sis_apic_bug; /* not actually supported, dummy for compile */
 
-static spinlock_t ioapic_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(ioapic_lock);
 
 /*
  * # of IRQ routing registers
@@ -1160,13 +1160,6 @@
 		
 		old_id = mp_ioapics[apic].mpc_apicid;
 
-		if (mp_ioapics[apic].mpc_apicid >= 0xf) {
-			apic_printk(APIC_QUIET,KERN_ERR "BIOS bug, IO-APIC#%d ID is %d in the MPC table!...\n",
-				apic, mp_ioapics[apic].mpc_apicid);
-			apic_printk(APIC_QUIET,KERN_ERR "... fixing up to %d. (tell your hw vendor)\n",
-				reg_00.bits.ID);
-			mp_ioapics[apic].mpc_apicid = reg_00.bits.ID;
-		}
 
 		printk(KERN_INFO "Using IO-APIC %d\n", mp_ioapics[apic].mpc_apicid);
 
diff -Nru a/arch/x86_64/kernel/kprobes.c b/arch/x86_64/kernel/kprobes.c
--- a/arch/x86_64/kernel/kprobes.c	2005-03-01 23:39:07 -08:00
+++ b/arch/x86_64/kernel/kprobes.c	2005-03-01 23:39:07 -08:00
@@ -39,6 +39,8 @@
 #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
@@ -75,17 +77,25 @@
 int arch_prepare_kprobe(struct kprobe *p)
 {
 	/* insn: must be on special executable page on x86_64. */
+	up(&kprobe_mutex);
 	p->ainsn.insn = get_insn_slot();
+	down(&kprobe_mutex);
 	if (!p->ainsn.insn) {
 		return -ENOMEM;
 	}
-	memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE);
 	return 0;
 }
 
+void arch_copy_kprobe(struct kprobe *p)
+{
+	memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE);
+}
+
 void arch_remove_kprobe(struct kprobe *p)
 {
+	up(&kprobe_mutex);
 	free_insn_slot(p->ainsn.insn);
+	down(&kprobe_mutex);
 }
 
 static inline void disarm_kprobe(struct kprobe *p, struct pt_regs *regs)
@@ -425,12 +435,12 @@
 	}
 
 	/* All out of space.  Need to allocate a new page. Use slot 0.*/
-	kip = kmalloc(sizeof(struct kprobe_insn_page), GFP_ATOMIC);
+	kip = kmalloc(sizeof(struct kprobe_insn_page), GFP_KERNEL);
 	if (!kip) {
 		return NULL;
 	}
 	kip->insns = (kprobe_opcode_t*) __vmalloc(PAGE_SIZE,
-		GFP_ATOMIC|__GFP_HIGHMEM, __pgprot(__PAGE_KERNEL_EXEC));
+		GFP_KERNEL|__GFP_HIGHMEM, __pgprot(__PAGE_KERNEL_EXEC));
 	if (!kip->insns) {
 		kfree(kip);
 		return NULL;
diff -Nru a/arch/x86_64/kernel/mce.c b/arch/x86_64/kernel/mce.c
--- a/arch/x86_64/kernel/mce.c	2005-03-01 23:38:54 -08:00
+++ b/arch/x86_64/kernel/mce.c	2005-03-01 23:38:54 -08:00
@@ -31,6 +31,8 @@
 static int tolerant = 1;
 static int banks;
 static unsigned long bank[NR_BANKS] = { [0 ... NR_BANKS-1] = ~0UL };
+static unsigned long console_logged;
+static int notify_user;
 
 /*
  * Lockless MCE logging infrastructure.
@@ -43,7 +45,7 @@
 	MCE_LOG_LEN,
 }; 
 
-static void mce_log(struct mce *mce)
+void mce_log(struct mce *mce)
 {
 	unsigned next, entry;
 	mce->finished = 0;
@@ -68,6 +70,9 @@
 	smp_wmb();
 	mcelog.entry[entry].finished = 1;
 	smp_wmb();
+
+	if (!test_and_set_bit(0, &console_logged))
+		notify_user = 1;
 }
 
 static void print_mce(struct mce *m)
@@ -252,6 +257,19 @@
 {
 	on_each_cpu(mcheck_check_cpu, NULL, 1, 1);
 	schedule_delayed_work(&mcheck_work, check_interval * HZ);
+
+	/*
+	 * It's ok to read stale data here for notify_user and
+	 * console_logged as we'll simply get the updated versions
+	 * on the next mcheck_timer execution and atomic operations
+	 * on console_logged act as synchronization for notify_user
+	 * writes.
+	 */
+	if (notify_user && console_logged) {
+		notify_user = 0;
+		clear_bit(0, &console_logged);
+		printk(KERN_INFO "Machine check events logged\n");
+	}
 }
 
 
@@ -305,22 +323,34 @@
 	}
 }			
 
+static void __init mce_cpu_features(struct cpuinfo_x86 *c)
+{
+	switch (c->x86_vendor) {
+	case X86_VENDOR_INTEL:
+		mce_intel_feature_init(c);
+		break;
+	default:
+		break;
+	}
+}
+
 /* 
  * Called for each booted CPU to set up machine checks.
  * Must be called with preempt off. 
  */
 void __init mcheck_init(struct cpuinfo_x86 *c)
 {
-	static unsigned long mce_cpus __initdata = 0;
+	static cpumask_t mce_cpus __initdata = CPU_MASK_NONE;
 
 	mce_cpu_quirks(c); 
 
 	if (mce_dont_init ||
-	    test_and_set_bit(smp_processor_id(), &mce_cpus) ||
+	    cpu_test_and_set(smp_processor_id(), mce_cpus) ||
 	    !mce_available(c))
 		return;
 
 	mce_init(NULL);
+	mce_cpu_features(c);
 }
 
 /*
diff -Nru a/arch/x86_64/kernel/mce_intel.c b/arch/x86_64/kernel/mce_intel.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/x86_64/kernel/mce_intel.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,99 @@
+/*
+ * Intel specific MCE features.
+ * Copyright 2004 Zwane Mwaikambo <zwane@linuxpower.ca>
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/percpu.h>
+#include <asm/processor.h>
+#include <asm/msr.h>
+#include <asm/mce.h>
+#include <asm/hw_irq.h>
+
+static DEFINE_PER_CPU(unsigned long, next_check);
+
+asmlinkage void smp_thermal_interrupt(void)
+{
+	struct mce m;
+
+	ack_APIC_irq();
+
+	irq_enter();
+	if (time_before(jiffies, __get_cpu_var(next_check)))
+		goto done;
+
+	__get_cpu_var(next_check) = jiffies + HZ*300;
+	memset(&m, 0, sizeof(m));
+	m.cpu = smp_processor_id();
+	m.bank = MCE_THERMAL_BANK;
+	rdtscll(m.tsc);
+	rdmsrl(MSR_IA32_THERM_STATUS, m.status);
+	if (m.status & 0x1) {
+		printk(KERN_EMERG
+			"CPU%d: Temperature above threshold, cpu clock throttled\n", m.cpu);
+		add_taint(TAINT_MACHINE_CHECK);
+	} else {
+		printk(KERN_EMERG "CPU%d: Temperature/speed normal\n", m.cpu);
+	}
+
+	mce_log(&m);
+done:
+	irq_exit();
+}
+
+static void __init intel_init_thermal(struct cpuinfo_x86 *c)
+{
+	u32 l, h;
+	int tm2 = 0;
+	unsigned int cpu = smp_processor_id();
+
+	if (!cpu_has(c, X86_FEATURE_ACPI))
+		return;
+
+	if (!cpu_has(c, X86_FEATURE_ACC))
+		return;
+
+	/* first check if TM1 is already enabled by the BIOS, in which
+	 * case there might be some SMM goo which handles it, so we can't even
+	 * put a handler since it might be delivered via SMI already.
+	 */
+	rdmsr(MSR_IA32_MISC_ENABLE, l, h);
+	h = apic_read(APIC_LVTTHMR);
+	if ((l & (1 << 3)) && (h & APIC_DM_SMI)) {
+		printk(KERN_DEBUG
+		       "CPU%d: Thermal monitoring handled by SMI\n", cpu);
+		return;
+	}
+
+	if (cpu_has(c, X86_FEATURE_TM2) && (l & (1 << 13)))
+		tm2 = 1;
+
+	if (h & APIC_VECTOR_MASK) {
+		printk(KERN_DEBUG
+		       "CPU%d: Thermal LVT vector (%#x) already "
+		       "installed\n", cpu, (h & APIC_VECTOR_MASK));
+		return;
+	}
+
+	h = THERMAL_APIC_VECTOR;
+	h |= (APIC_DM_FIXED | APIC_LVT_MASKED);
+	apic_write_around(APIC_LVTTHMR, h);
+
+	rdmsr(MSR_IA32_THERM_INTERRUPT, l, h);
+	wrmsr(MSR_IA32_THERM_INTERRUPT, l | 0x03, h);
+
+	rdmsr(MSR_IA32_MISC_ENABLE, l, h);
+	wrmsr(MSR_IA32_MISC_ENABLE, l | (1 << 3), h);
+
+	l = apic_read(APIC_LVTTHMR);
+	apic_write_around(APIC_LVTTHMR, l & ~APIC_LVT_MASKED);
+	printk(KERN_INFO "CPU%d: Thermal monitoring enabled (%s)\n",
+		cpu, tm2 ? "TM2" : "TM1");
+	return;
+}
+
+void __init mce_intel_feature_init(struct cpuinfo_x86 *c)
+{
+	intel_init_thermal(c);
+}
diff -Nru a/arch/x86_64/kernel/module.c b/arch/x86_64/kernel/module.c
--- a/arch/x86_64/kernel/module.c	2005-03-01 23:39:10 -08:00
+++ b/arch/x86_64/kernel/module.c	2005-03-01 23:39:10 -08:00
@@ -23,7 +23,6 @@
 #include <linux/string.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
-#include <linux/vmalloc.h>
 
 #include <asm/system.h>
 #include <asm/page.h>
diff -Nru a/arch/x86_64/kernel/mpparse.c b/arch/x86_64/kernel/mpparse.c
--- a/arch/x86_64/kernel/mpparse.c	2005-03-01 23:38:54 -08:00
+++ b/arch/x86_64/kernel/mpparse.c	2005-03-01 23:38:54 -08:00
@@ -576,7 +576,6 @@
 	extern void __bad_mpf_size(void); 
 	unsigned int *bp = phys_to_virt(base);
 	struct intel_mp_floating *mpf;
-	static int printed __initdata; 
 
 	Dprintk("Scan SMP from %p for %ld bytes.\n", bp,length);
 	if (sizeof(*mpf) != 16)
@@ -600,10 +599,6 @@
 		bp += 4;
 		length -= 16;
 	}
-	if (!printed) {		
-		printk(KERN_INFO "No mptable found.\n");
-		printed = 1;
-	}
 	return 0;
 }
 
@@ -640,7 +635,11 @@
 
 	address = *(unsigned short *)phys_to_virt(0x40E);
 	address <<= 4;
-	smp_scan_config(address, 0x1000);
+	if (smp_scan_config(address, 0x1000))
+		return;
+
+	/* If we have come this far, we did not find an MP table  */
+	 printk(KERN_INFO "No mptable found.\n");
 }
 
 /*
diff -Nru a/arch/x86_64/kernel/nmi.c b/arch/x86_64/kernel/nmi.c
--- a/arch/x86_64/kernel/nmi.c	2005-03-01 23:38:56 -08:00
+++ b/arch/x86_64/kernel/nmi.c	2005-03-01 23:38:56 -08:00
@@ -43,7 +43,7 @@
  * This is maintained separately from nmi_active because the NMI
  * watchdog may also be driven from the I/O APIC timer.
  */
-static spinlock_t lapic_nmi_owner_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(lapic_nmi_owner_lock);
 static unsigned int lapic_nmi_owner;
 #define LAPIC_NMI_WATCHDOG	(1<<0)
 #define LAPIC_NMI_RESERVED	(1<<1)
@@ -130,8 +130,12 @@
 	mdelay((10*1000)/nmi_hz); // wait 10 ticks
 
 	for (cpu = 0; cpu < NR_CPUS; cpu++) {
-		if (!cpu_online(cpu))
+#ifdef CONFIG_SMP
+		/* Check cpu_callin_map here because that is set
+		   after the timer is started. */
+		if (!cpu_isset(cpu, cpu_callin_map))
 			continue;
+#endif
 		if (cpu_pda[cpu].__nmi_count - counts[cpu] <= 5) {
 			printk("CPU#%d: NMI appears to be stuck (%d)!\n", 
 			       cpu,
diff -Nru a/arch/x86_64/kernel/pci-gart.c b/arch/x86_64/kernel/pci-gart.c
--- a/arch/x86_64/kernel/pci-gart.c	2005-03-01 23:38:56 -08:00
+++ b/arch/x86_64/kernel/pci-gart.c	2005-03-01 23:38:56 -08:00
@@ -65,7 +65,7 @@
 #define MAX_NB 8
 
 /* Allocation bitmap for the remapping area */ 
-static spinlock_t iommu_bitmap_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(iommu_bitmap_lock);
 static unsigned long *iommu_gart_bitmap; /* guarded by iommu_bitmap_lock */
 
 static u32 gart_unmapped_entry; 
diff -Nru a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c
--- a/arch/x86_64/kernel/process.c	2005-03-01 23:38:58 -08:00
+++ b/arch/x86_64/kernel/process.c	2005-03-01 23:38:58 -08:00
@@ -32,7 +32,7 @@
 #include <linux/delay.h>
 #include <linux/irq.h>
 #include <linux/ptrace.h>
-#include <linux/version.h>
+#include <linux/utsname.h>
 
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
@@ -61,6 +61,7 @@
  * Powermanagement idle function, if any..
  */
 void (*pm_idle)(void);
+static cpumask_t cpu_idle_map;
 
 void disable_hlt(void)
 {
@@ -123,6 +124,23 @@
 	}
 }
 
+
+void cpu_idle_wait(void)
+{
+        int cpu;
+        cpumask_t map;
+
+        for_each_online_cpu(cpu)
+                cpu_set(cpu, cpu_idle_map);
+
+        wmb();
+        do {
+                ssleep(1);
+                cpus_and(map, cpu_idle_map, cpu_online_map);
+        } while (!cpus_empty(map));
+}
+EXPORT_SYMBOL_GPL(cpu_idle_wait);
+
 /*
  * The idle thread. There's no useful work to be
  * done, so just try to conserve power and have a
@@ -131,21 +149,20 @@
  */
 void cpu_idle (void)
 {
+	int cpu = smp_processor_id();
+
 	/* endless idle loop with no priority at all */
 	while (1) {
 		while (!need_resched()) {
 			void (*idle)(void);
-			/*
-			 * Mark this as an RCU critical section so that
-			 * synchronize_kernel() in the unload path waits
-			 * for our completion.
-			 */
-			rcu_read_lock();
+
+			if (cpu_isset(cpu, cpu_idle_map))
+				cpu_clear(cpu, cpu_idle_map);
+			rmb();
 			idle = pm_idle;
 			if (!idle)
 				idle = default_idle;
 			idle();
-			rcu_read_unlock();
 		}
 		schedule();
 	}
@@ -215,7 +232,7 @@
 	printk("\n");
 	print_modules();
 	printk("Pid: %d, comm: %.20s %s %s\n", 
-	       current->pid, current->comm, print_tainted(), UTS_RELEASE);
+	       current->pid, current->comm, print_tainted(), system_utsname.release);
 	printk("RIP: %04lx:[<%016lx>] ", regs->cs & 0xffff, regs->rip);
 	printk_address(regs->rip); 
 	printk("\nRSP: %04lx:%016lx  EFLAGS: %08lx\n", regs->ss, regs->rsp, regs->eflags);
@@ -297,7 +314,7 @@
 	 * Forget coprocessor state..
 	 */
 	clear_fpu(tsk);
-	tsk->used_math = 0;
+	clear_used_math();
 }
 
 void release_thread(struct task_struct *dead_task)
@@ -560,6 +577,12 @@
 
 	/* Make sure to be in 64bit mode */
 	clear_thread_flag(TIF_IA32); 
+
+	/* TBD: overwrites user setup. Should have two bits.
+	   But 64bit processes have always behaved this way,
+	   so it's not too bad. The main problem is just that
+   	   32bit childs are affected again. */
+	current->personality &= ~READ_IMPLIES_EXEC;
 }
 
 asmlinkage long sys_fork(struct pt_regs *regs)
diff -Nru a/arch/x86_64/kernel/ptrace.c b/arch/x86_64/kernel/ptrace.c
--- a/arch/x86_64/kernel/ptrace.c	2005-03-01 23:38:54 -08:00
+++ b/arch/x86_64/kernel/ptrace.c	2005-03-01 23:38:54 -08:00
@@ -480,7 +480,7 @@
 			ret = -EIO;
 			break;
 		}
-		child->used_math = 1;
+		set_stopped_child_used_math(child);
 		ret = set_fpregs(child, (struct user_i387_struct __user *)data);
 		break;
 	}
diff -Nru a/arch/x86_64/kernel/reboot.c b/arch/x86_64/kernel/reboot.c
--- a/arch/x86_64/kernel/reboot.c	2005-03-01 23:39:09 -08:00
+++ b/arch/x86_64/kernel/reboot.c	2005-03-01 23:39:09 -08:00
@@ -22,18 +22,18 @@
 
 static long no_idt[3];
 static enum { 
-	BOOT_BIOS = 'b',
 	BOOT_TRIPLE = 't',
 	BOOT_KBD = 'k'
 } reboot_type = BOOT_KBD;
 static int reboot_mode = 0;
+int reboot_force;
 
-/* reboot=b[ios] | t[riple] | k[bd] [, [w]arm | [c]old]
-   bios	  Use the CPU reboot vector for warm reset
+/* reboot=t[riple] | k[bd] [, [w]arm | [c]old]
    warm   Don't set the cold reboot flag
    cold   Set the cold reboot flag
    triple Force a triple fault (init)
    kbd    Use the keyboard controller. cold reset (default)
+   force  Avoid anything that could hang.
  */ 
 static int __init reboot_setup(char *str)
 {
@@ -52,6 +52,9 @@
 		case 'k':
 			reboot_type = *str;
 			break;
+		case 'f':
+			reboot_force = 1;
+			break;
 		}
 		if((str = strchr(str,',')) != NULL)
 			str++;
@@ -63,44 +66,19 @@
 
 __setup("reboot=", reboot_setup);
 
-/* overwrites random kernel memory. Should not be kernel .text */
-#define WARMBOOT_TRAMP 0x1000UL
-
-static void reboot_warm(void)
-{
-	extern unsigned char warm_reboot[], warm_reboot_end[];
-	printk("warm reboot\n");
-
-	local_irq_disable(); 
-		
-	/* restore identity mapping */
-	init_level4_pgt[0] = __pml4(__pa(level3_ident_pgt) | 7); 
-	__flush_tlb_all(); 
-
-	/* Move the trampoline to low memory */
-	memcpy(__va(WARMBOOT_TRAMP), warm_reboot, warm_reboot_end - warm_reboot); 
-
-	/* Start it in compatibility mode. */
-	asm volatile( "   pushq $0\n" 		/* ss */
-		     "   pushq $0x2000\n" 	/* rsp */
-	             "   pushfq\n"		/* eflags */
-		     "   pushq %[cs]\n"
-		     "   pushq %[target]\n"
-		     "   iretq" :: 
-		      [cs] "i" (__KERNEL_COMPAT32_CS), 
-		      [target] "b" (WARMBOOT_TRAMP));
-}
-
 #ifdef CONFIG_SMP
 static void smp_halt(void)
 {
 	int cpuid = safe_smp_processor_id(); 
-		static int first_entry = 1;
+	static int first_entry = 1;
+
+	if (reboot_force)
+		return;
 
-		if (first_entry) { 
-			first_entry = 0;
-			smp_call_function((void *)machine_restart, NULL, 1, 0);
-		} 
+	if (first_entry) {
+		first_entry = 0;
+		smp_call_function((void *)machine_restart, NULL, 1, 0);
+	}
 			
 	smp_stop_cpu(); 
 
@@ -129,19 +107,20 @@
 {
 	int i;
 
+	printk("machine restart\n");
+
 #ifdef CONFIG_SMP
 	smp_halt(); 
 #endif
 
-	local_irq_disable();
-       
+	if (!reboot_force) {
+		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();
+	}
 	
 	/* Tell the BIOS if we want cold or warm reboot */
 	*((unsigned short *)__va(0x472)) = reboot_mode;
@@ -149,9 +128,6 @@
 	for (;;) {
 		/* Could also try the reset bit in the Hammer NB */
 		switch (reboot_type) { 
-		case BOOT_BIOS:
-			reboot_warm();
-
 		case BOOT_KBD:
 		for (i=0; i<100; i++) {
 			kb_wait();
@@ -161,8 +137,8 @@
 		}
 
 		case BOOT_TRIPLE: 
-		__asm__ __volatile__("lidt (%0)": :"r" (&no_idt));
-		__asm__ __volatile__("int3");
+			__asm__ __volatile__("lidt (%0)": :"r" (&no_idt));
+			__asm__ __volatile__("int3");
 
 			reboot_type = BOOT_KBD;
 			break;
diff -Nru a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c
--- a/arch/x86_64/kernel/setup.c	2005-03-01 23:38:51 -08:00
+++ b/arch/x86_64/kernel/setup.c	2005-03-01 23:38:51 -08:00
@@ -53,10 +53,10 @@
 #include <asm/mpspec.h>
 #include <asm/mmu_context.h>
 #include <asm/bootsetup.h>
-#include <asm/smp.h>
 #include <asm/proto.h>
 #include <asm/setup.h>
 #include <asm/mach_apic.h>
+#include <asm/numa.h>
 
 /*
  * Machine setup..
@@ -75,9 +75,14 @@
 int __initdata acpi_force = 0;
 #endif
 
+int acpi_numa __initdata;
+
 /* For PCI or other memory-mapped resources */
 unsigned long pci_mem_start = 0x10000000;
 
+/* Boot loader ID as an integer, for the benefit of proc_dointvec */
+int bootloader_type;
+
 unsigned long saved_video_mode;
 
 #ifdef CONFIG_SWIOTLB
@@ -106,15 +111,24 @@
 char command_line[COMMAND_LINE_SIZE];
 
 struct resource standard_io_resources[] = {
-	{ "dma1", 0x00, 0x1f, IORESOURCE_BUSY | IORESOURCE_IO },
-	{ "pic1", 0x20, 0x21, IORESOURCE_BUSY | IORESOURCE_IO },
-	{ "timer0", 0x40, 0x43, IORESOURCE_BUSY | IORESOURCE_IO },
-	{ "timer1", 0x50, 0x53, IORESOURCE_BUSY | IORESOURCE_IO },
-	{ "keyboard", 0x60, 0x6f, IORESOURCE_BUSY | IORESOURCE_IO },
-	{ "dma page reg", 0x80, 0x8f, IORESOURCE_BUSY | IORESOURCE_IO },
-	{ "pic2", 0xa0, 0xa1, IORESOURCE_BUSY | IORESOURCE_IO },
-	{ "dma2", 0xc0, 0xdf, IORESOURCE_BUSY | IORESOURCE_IO },
-	{ "fpu", 0xf0, 0xff, IORESOURCE_BUSY | IORESOURCE_IO }
+	{ .name = "dma1", .start = 0x00, .end = 0x1f,
+		.flags = IORESOURCE_BUSY | IORESOURCE_IO },
+	{ .name = "pic1", .start = 0x20, .end = 0x21,
+		.flags = IORESOURCE_BUSY | IORESOURCE_IO },
+	{ .name = "timer0", .start = 0x40, .end = 0x43,
+		.flags = IORESOURCE_BUSY | IORESOURCE_IO },
+	{ .name = "timer1", .start = 0x50, .end = 0x53,
+		.flags = IORESOURCE_BUSY | IORESOURCE_IO },
+	{ .name = "keyboard", .start = 0x60, .end = 0x6f,
+		.flags = IORESOURCE_BUSY | IORESOURCE_IO },
+	{ .name = "dma page reg", .start = 0x80, .end = 0x8f,
+		.flags = IORESOURCE_BUSY | IORESOURCE_IO },
+	{ .name = "pic2", .start = 0xa0, .end = 0xa1,
+		.flags = IORESOURCE_BUSY | IORESOURCE_IO },
+	{ .name = "dma2", .start = 0xc0, .end = 0xdf,
+		.flags = IORESOURCE_BUSY | IORESOURCE_IO },
+	{ .name = "fpu", .start = 0xf0, .end = 0xff,
+		.flags = IORESOURCE_BUSY | IORESOURCE_IO }
 };
 
 #define STANDARD_IO_RESOURCES \
@@ -122,28 +136,66 @@
 
 #define IORESOURCE_RAM (IORESOURCE_BUSY | IORESOURCE_MEM)
 
-struct resource data_resource = { "Kernel data", 0, 0, IORESOURCE_RAM };
-struct resource code_resource = { "Kernel code", 0, 0, IORESOURCE_RAM };
+struct resource data_resource = {
+	.name = "Kernel data",
+	.start = 0,
+	.end = 0,
+	.flags = IORESOURCE_RAM,
+};
+struct resource code_resource = {
+	.name = "Kernel code",
+	.start = 0,
+	.end = 0,
+	.flags = IORESOURCE_RAM,
+};
 
 #define IORESOURCE_ROM (IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM)
 
-static struct resource system_rom_resource = { "System ROM", 0xf0000, 0xfffff, IORESOURCE_ROM };
-static struct resource extension_rom_resource = { "Extension ROM", 0xe0000, 0xeffff, IORESOURCE_ROM };
+static struct resource system_rom_resource = {
+	.name = "System ROM",
+	.start = 0xf0000,
+	.end = 0xfffff,
+	.flags = IORESOURCE_ROM,
+};
+
+static struct resource extension_rom_resource = {
+	.name = "Extension ROM",
+	.start = 0xe0000,
+	.end = 0xeffff,
+	.flags = IORESOURCE_ROM,
+};
 
 static struct resource adapter_rom_resources[] = {
-	{ "Adapter ROM", 0xc8000, 0, IORESOURCE_ROM },
-	{ "Adapter ROM", 0, 0, IORESOURCE_ROM },
-	{ "Adapter ROM", 0, 0, IORESOURCE_ROM },
-	{ "Adapter ROM", 0, 0, IORESOURCE_ROM },
-	{ "Adapter ROM", 0, 0, IORESOURCE_ROM },
-	{ "Adapter ROM", 0, 0, IORESOURCE_ROM }
+	{ .name = "Adapter ROM", .start = 0xc8000, .end = 0,
+		.flags = IORESOURCE_ROM },
+	{ .name = "Adapter ROM", .start = 0, .end = 0,
+		.flags = IORESOURCE_ROM },
+	{ .name = "Adapter ROM", .start = 0, .end = 0,
+		.flags = IORESOURCE_ROM },
+	{ .name = "Adapter ROM", .start = 0, .end = 0,
+		.flags = IORESOURCE_ROM },
+	{ .name = "Adapter ROM", .start = 0, .end = 0,
+		.flags = IORESOURCE_ROM },
+	{ .name = "Adapter ROM", .start = 0, .end = 0,
+		.flags = IORESOURCE_ROM }
 };
 
 #define ADAPTER_ROM_RESOURCES \
 	(sizeof adapter_rom_resources / sizeof adapter_rom_resources[0])
 
-static struct resource video_rom_resource = { "Video ROM", 0xc0000, 0xc7fff, IORESOURCE_ROM };
-static struct resource video_ram_resource = { "Video RAM area", 0xa0000, 0xbffff, IORESOURCE_RAM };
+static struct resource video_rom_resource = {
+	.name = "Video ROM",
+	.start = 0xc0000,
+	.end = 0xc7fff,
+	.flags = IORESOURCE_ROM,
+};
+
+static struct resource video_ram_resource = {
+	.name = "Video RAM area",
+	.start = 0xa0000,
+	.end = 0xbffff,
+	.flags = IORESOURCE_RAM,
+};
 
 #define romsignature(x) (*(unsigned short *)(x) == 0xaa55)
 
@@ -312,6 +364,9 @@
 		if (!memcmp(from,"oops=panic", 10))
 			panic_on_oops = 1;
 
+		if (!memcmp(from, "noexec=", 7))
+			nonx_setup(from + 7);
+
 	next_char:
 		c = *(from++);
 		if (!c)
@@ -452,6 +507,7 @@
 	edid_info = EDID_INFO;
 	aux_device_present = AUX_DEVICE_INFO;
 	saved_video_mode = SAVED_VIDEO_MODE;
+	bootloader_type = LOADER_TYPE;
 
 #ifdef CONFIG_BLK_DEV_RAM
 	rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK;
@@ -475,6 +531,8 @@
 
 	parse_cmdline_early(cmdline_p);
 
+	early_identify_cpu(&boot_cpu_data);
+
 	/*
 	 * partially used pages are not usable - thus
 	 * we are rounding upwards:
@@ -483,7 +541,22 @@
 
 	check_efer();
 
-	init_memory_mapping(); 
+	init_memory_mapping(0, (end_pfn_map << PAGE_SHIFT));
+
+#ifdef CONFIG_ACPI_BOOT
+	/*
+	 * Initialize the ACPI boot-time table parser (gets the RSDP and SDT).
+	 * Call this early for SRAT node setup.
+	 */
+	acpi_boot_table_init();
+#endif
+
+#ifdef CONFIG_ACPI_NUMA
+	/*
+	 * Parse SRAT to discover nodes.
+	 */
+	acpi_numa_init();
+#endif
 
 #ifdef CONFIG_DISCONTIGMEM
 	numa_initmem_init(0, end_pfn); 
@@ -551,16 +624,15 @@
 #endif
 	paging_init();
 
-		check_ioapic();
+	check_ioapic();
+
 #ifdef CONFIG_ACPI_BOOT
-       /*
-        * Initialize the ACPI boot-time table parser (gets the RSDP and SDT).
-        * Must do this after paging_init (due to reliance on fixmap, and thus
-        * the bootmem allocator) but before get_smp_config (to allow parsing
-        * of MADT).
-        */
+	/*
+	 * Read APIC and some other early information from ACPI tables.
+	 */
 	acpi_boot_init();
 #endif
+
 #ifdef CONFIG_X86_LOCAL_APIC
 	/*
 	 * get boot-time SMP configuration:
@@ -611,7 +683,7 @@
 {
 	unsigned int *v;
 
-	if (cpuid_eax(0x80000000) < 0x80000004)
+	if (c->x86_cpuid_level < 0x80000004)
 		return 0;
 
 	v = (unsigned int *) c->x86_model_id;
@@ -627,24 +699,24 @@
 {
 	unsigned int n, dummy, eax, ebx, ecx, edx;
 
-	n = cpuid_eax(0x80000000);
+	n = c->x86_cpuid_level;
 
 	if (n >= 0x80000005) {
 		cpuid(0x80000005, &dummy, &ebx, &ecx, &edx);
 		printk(KERN_INFO "CPU: L1 I Cache: %dK (%d bytes/line), D cache %dK (%d bytes/line)\n",
 			edx>>24, edx&0xFF, ecx>>24, ecx&0xFF);
-		c->x86_cache_size=(ecx>>24)+(edx>>24);	
-		/* DTLB and ITLB together, but only 4K */
-		c->x86_tlbsize = ((ebx>>16)&0xff) + (ebx&0xff);
+		c->x86_cache_size=(ecx>>24)+(edx>>24);
+		/* On K8 L1 TLB is inclusive, so don't count it */
+		c->x86_tlbsize = 0;
 	}
 
 	if (n >= 0x80000006) {
 		cpuid(0x80000006, &dummy, &ebx, &ecx, &edx);
-	ecx = cpuid_ecx(0x80000006);
-	c->x86_cache_size = ecx >> 16;
+		ecx = cpuid_ecx(0x80000006);
+		c->x86_cache_size = ecx >> 16;
 		c->x86_tlbsize += ((ebx >> 16) & 0xfff) + (ebx & 0xfff);
 
-	printk(KERN_INFO "CPU: L2 Cache: %dK (%d bytes/line)\n",
+		printk(KERN_INFO "CPU: L2 Cache: %dK (%d bytes/line)\n",
 		c->x86_cache_size, ecx & 0xFF);
 	}
 
@@ -662,6 +734,9 @@
 {
 	int r;
 	int level;
+#ifdef CONFIG_NUMA
+	int cpu;
+#endif
 
 	/* Bit 31 in normal CPUID used for nonstandard 3DNow ID;
 	   3DNow is IDd by bit 31 in extended CPUID (1*32+31) anyway */
@@ -684,7 +759,7 @@
 	} 
 	display_cacheinfo(c);
 
-	if (c->cpuid_level >= 0x80000008) {
+	if (c->x86_cpuid_level >= 0x80000008) {
 		c->x86_num_cores = (cpuid_ecx(0x80000008) & 0xff) + 1;
 		if (c->x86_num_cores & (c->x86_num_cores - 1))
 			c->x86_num_cores = 1;
@@ -693,13 +768,16 @@
 		/* On a dual core setup the lower bits of apic id
 		   distingush the cores. Fix up the CPU<->node mappings
 		   here based on that.
-		   Assumes number of cores is a power of two. */
-		if (c->x86_num_cores > 1) {
-			int cpu = c->x86_apicid;
+		   Assumes number of cores is a power of two.
+		   When using SRAT use mapping from SRAT. */
+		cpu = c->x86_apicid;
+		if (acpi_numa <= 0 && c->x86_num_cores > 1) {
 			cpu_to_node[cpu] = cpu >> hweight32(c->x86_num_cores - 1);
-			printk(KERN_INFO "CPU %d -> Node %d\n",
-			       cpu, cpu_to_node[cpu]);
+			if (!node_online(cpu_to_node[cpu]))
+				cpu_to_node[cpu] = first_node(node_online_map);
 		}
+		printk(KERN_INFO "CPU %d(%d) -> Node %d\n",
+				cpu, c->x86_num_cores, cpu_to_node[cpu]);
 #endif
 	}
 
@@ -752,6 +830,19 @@
 	}
 #endif
 }
+
+static void __init sched_cmp_hack(struct cpuinfo_x86 *c)
+{
+#ifdef CONFIG_SMP
+	/* AMD dual core looks like HT but isn't really. Hide it from the
+	   scheduler. This works around problems with the domain scheduler.
+	   Also probably gives slightly better scheduling and disables
+	   SMT nice which is harmful on dual core.
+	   TBD tune the domain scheduler for dual core. */
+	if (c->x86_vendor == X86_VENDOR_AMD && cpu_has(c, X86_FEATURE_CMP_LEGACY))
+		smp_num_siblings = 1;
+#endif
+}
 	
 static void __init init_intel(struct cpuinfo_x86 *c)
 {
@@ -759,7 +850,7 @@
 	unsigned n;
 
 	init_intel_cacheinfo(c);
-	n = cpuid_eax(0x80000000);
+	n = c->x86_cpuid_level;
 	if (n >= 0x80000008) {
 		unsigned eax = cpuid_eax(0x80000008);
 		c->x86_virt_bits = (eax >> 8) & 0xff;
@@ -805,13 +896,14 @@
 	c->x86_cache_alignment = c->x86_clflush_size;
 	c->x86_num_cores = 1;
 	c->x86_apicid = c == &boot_cpu_data ? 0 : c - cpu_data;
+	c->x86_cpuid_level = 0;
 	memset(&c->x86_capability, 0, sizeof c->x86_capability);
 
 	/* Get vendor name */
-	cpuid(0x00000000, &c->cpuid_level,
-	      (int *)&c->x86_vendor_id[0],
-	      (int *)&c->x86_vendor_id[8],
-	      (int *)&c->x86_vendor_id[4]);
+	cpuid(0x00000000, (unsigned int *)&c->cpuid_level,
+	      (unsigned int *)&c->x86_vendor_id[0],
+	      (unsigned int *)&c->x86_vendor_id[8],
+	      (unsigned int *)&c->x86_vendor_id[4]);
 		
 	get_cpu_vendor(c);
 
@@ -851,19 +943,21 @@
 
 	/* AMD-defined flags: level 0x80000001 */
 	xlvl = cpuid_eax(0x80000000);
-	if ( (xlvl & 0xffff0000) == 0x80000000 ) {
-		if ( xlvl >= 0x80000001 ) {
+	c->x86_cpuid_level = xlvl;
+	if ((xlvl & 0xffff0000) == 0x80000000) {
+		if (xlvl >= 0x80000001) {
 			c->x86_capability[1] = cpuid_edx(0x80000001);
 			c->x86_capability[5] = cpuid_ecx(0x80000001);
 		}
-		if ( xlvl >= 0x80000004 )
+		if (xlvl >= 0x80000004)
 			get_model_name(c); /* Default name */
 	}
 
 	/* Transmeta-defined flags: level 0x80860001 */
 	xlvl = cpuid_eax(0x80860000);
-	if ( (xlvl & 0xffff0000) == 0x80860000 ) {
-		if (  xlvl >= 0x80860001 )
+	if ((xlvl & 0xffff0000) == 0x80860000) {
+		/* Don't set x86_cpuid_level here for now to not confuse. */
+		if (xlvl >= 0x80860001)
 			c->x86_capability[2] = cpuid_edx(0x80860001);
 	}
 
@@ -877,40 +971,44 @@
 	 * At the end of this section, c->x86_capability better
 	 * indicate the features this CPU genuinely supports!
 	 */
-	switch ( c->x86_vendor ) {
-
-		case X86_VENDOR_AMD:
-			init_amd(c);
-			break;
+	switch (c->x86_vendor) {
+	case X86_VENDOR_AMD:
+		init_amd(c);
+		break;
 
-		case X86_VENDOR_INTEL:
-			init_intel(c); 
-			break; 
+	case X86_VENDOR_INTEL:
+		init_intel(c);
+		break;
 
-		case X86_VENDOR_UNKNOWN:
-		default:
-			display_cacheinfo(c);
-			break;
+	case X86_VENDOR_UNKNOWN:
+	default:
+		display_cacheinfo(c);
+		break;
 	}
 
 	select_idle_routine(c);
 	detect_ht(c); 
-		
+	sched_cmp_hack(c);
+
 	/*
 	 * On SMP, boot_cpu_data holds the common feature set between
 	 * all CPUs; so make sure that we indicate which features are
 	 * common between the CPUs.  The first time this routine gets
 	 * executed, c == &boot_cpu_data.
 	 */
-	if ( c != &boot_cpu_data ) {
+	if (c != &boot_cpu_data) {
 		/* AND the already accumulated flags with these */
-		for ( i = 0 ; i < NCAPINTS ; i++ )
+		for (i = 0 ; i < NCAPINTS ; i++)
 			boot_cpu_data.x86_capability[i] &= c->x86_capability[i];
 	}
 
 #ifdef CONFIG_X86_MCE
 	mcheck_init(c);
 #endif
+#ifdef CONFIG_NUMA
+	if (c != &boot_cpu_data)
+		numa_add_cpu(c - cpu_data);
+#endif
 }
  
 
@@ -973,7 +1071,7 @@
 		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 
 		/* AMD-defined (#2) */
-		"lahf_lm", "htvalid", NULL, NULL, NULL, NULL, NULL, NULL,
+		"lahf_lm", "cmp_legacy", NULL, NULL, NULL, NULL, NULL, NULL,
 		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
@@ -1016,11 +1114,9 @@
 	if (c->x86_cache_size >= 0) 
 		seq_printf(m, "cache size\t: %d KB\n", c->x86_cache_size);
 	
-#ifdef CONFIG_X86_HT
-	if (smp_num_siblings > 1) {
-		seq_printf(m, "physical id\t: %d\n", phys_proc_id[c - cpu_data]);
-		seq_printf(m, "siblings\t: %d\n", smp_num_siblings);
-	}
+#ifdef CONFIG_SMP
+	seq_printf(m, "physical id\t: %d\n", phys_proc_id[c - cpu_data]);
+	seq_printf(m, "siblings\t: %d\n", c->x86_num_cores * smp_num_siblings);
 #endif	
 
 	seq_printf(m,
@@ -1062,6 +1158,7 @@
 					seq_printf(m, " [%d]", i);
 			}
 	}
+	seq_printf(m, "\n");
 
 	if (c->x86_num_cores > 1)
 		seq_printf(m, "cpu cores\t: %d\n", c->x86_num_cores);
diff -Nru a/arch/x86_64/kernel/setup64.c b/arch/x86_64/kernel/setup64.c
--- a/arch/x86_64/kernel/setup64.c	2005-03-01 23:38:54 -08:00
+++ b/arch/x86_64/kernel/setup64.c	2005-03-01 23:38:54 -08:00
@@ -28,7 +28,7 @@
 
 char x86_boot_params[2048] __initdata = {0,};
 
-unsigned long cpu_initialized __initdata = 0;
+cpumask_t cpu_initialized __initdata = CPU_MASK_NONE;
 
 struct x8664_pda cpu_pda[NR_CPUS] __cacheline_aligned; 
 
@@ -50,23 +50,41 @@
 on	Enable(default)
 off	Disable
 */ 
-static int __init nonx_setup(char *str)
+int __init nonx_setup(char *str)
 {
-	if (!strcmp(str, "on")) {
+	if (!strncmp(str, "on", 2)) {
                 __supported_pte_mask |= _PAGE_NX; 
  		do_not_nx = 0; 
-	} else if (!strcmp(str, "off")) {
+	} else if (!strncmp(str, "off", 3)) {
 		do_not_nx = 1;
 		__supported_pte_mask &= ~_PAGE_NX;
-        } 
-        return 1;
+        }
+	return 0;
 } 
+__setup("noexec=", nonx_setup);	/* parsed early actually */
 
-__setup("noexec=", nonx_setup); 
+int force_personality32 = READ_IMPLIES_EXEC;
+
+/* noexec32=on|off
+Control non executable heap for 32bit processes.
+To control the stack too use noexec=off
+
+on	PROT_READ does not imply PROT_EXEC for 32bit processes
+off	PROT_READ implies PROT_EXEC (default)
+*/
+static int __init nonx32_setup(char *str)
+{
+	if (!strcmp(str, "on"))
+		force_personality32 &= ~READ_IMPLIES_EXEC;
+	else if (!strcmp(str, "off"))
+		force_personality32 |= READ_IMPLIES_EXEC;
+	return 0;
+}
+__setup("noexec32=", nonx32_setup);
 
 /*
  * Great future plan:
- * Declare PDA itself and support (irqstack,tss,pml4) as per cpu data.
+ * Declare PDA itself and support (irqstack,tss,pgd) as per cpu data.
  * Always point %gs to its beginning
  */
 void __init setup_per_cpu_areas(void)
@@ -83,13 +101,13 @@
 
 	for (i = 0; i < NR_CPUS; i++) { 
 		unsigned char *ptr;
-		/* If possible allocate on the node of the CPU.
-		   In case it doesn't exist round-robin nodes. */
-		if (!NODE_DATA(i % numnodes)) { 
-			printk("cpu with no node %d, numnodes %d\n", i, numnodes);
+
+		if (!NODE_DATA(cpu_to_node(i))) {
+			printk("cpu with no node %d, num_online_nodes %d\n",
+			       i, num_online_nodes());
 			ptr = alloc_bootmem(size);
 		} else { 
-			ptr = alloc_bootmem_node(NODE_DATA(i % numnodes), size);
+			ptr = alloc_bootmem_node(NODE_DATA(cpu_to_node(i)), size);
 		}
 		if (!ptr)
 			panic("Cannot allocate cpu data for CPU %d\n", i);
@@ -100,7 +118,6 @@
 
 void pda_init(int cpu)
 { 
-        pml4_t *level4;
 	struct x8664_pda *pda = &cpu_pda[cpu];
 
 	/* Setup up data that may be needed in __get_free_pages early */
@@ -119,22 +136,14 @@
 		/* others are initialized in smpboot.c */
 		pda->pcurrent = &init_task;
 		pda->irqstackptr = boot_cpu_stack; 
-		level4 = init_level4_pgt; 
 	} else {
-		level4 = (pml4_t *)__get_free_pages(GFP_ATOMIC, 0); 
-		if (!level4) 
-			panic("Cannot allocate top level page for cpu %d", cpu); 
 		pda->irqstackptr = (char *)
 			__get_free_pages(GFP_ATOMIC, IRQSTACK_ORDER);
 		if (!pda->irqstackptr)
 			panic("cannot allocate irqstack for cpu %d", cpu); 
 	}
 
-	pda->level4_pgt = (unsigned long *)level4; 
-	if (level4 != init_level4_pgt)
-		memcpy(level4, &init_level4_pgt, PAGE_SIZE); 
-	set_pml4(level4 + 510, mk_kernel_pml4(__pa_symbol(boot_vmalloc_pgt)));
-	asm volatile("movq %0,%%cr3" :: "r" (__pa(level4))); 
+	asm volatile("movq %0,%%cr3" :: "r" (__pa_symbol(&init_level4_pgt)));
 
 	pda->irqstackptr += IRQSTACKSIZE-64;
 } 
@@ -199,7 +208,7 @@
 
 	me = current;
 
-	if (test_and_set_bit(cpu, &cpu_initialized))
+	if (cpu_test_and_set(cpu, cpu_initialized))
 		panic("CPU#%d already initialized!\n", cpu);
 
 	printk("Initializing CPU#%d\n", cpu);
@@ -227,9 +236,6 @@
 
 	asm volatile("pushfq ; popq %%rax ; btr $14,%%rax ; pushq %%rax ; popfq" ::: "eax");
 
-	if (cpu == 0) 
-		early_identify_cpu(&boot_cpu_data);
-
 	syscall_init();
 
 	wrmsrl(MSR_FS_BASE, 0);
@@ -283,8 +289,4 @@
 	set_debug(0UL, 7);
 
 	fpu_init(); 
-
-#ifdef CONFIG_NUMA
-	numa_add_cpu(cpu);
-#endif
 }
diff -Nru a/arch/x86_64/kernel/signal.c b/arch/x86_64/kernel/signal.c
--- a/arch/x86_64/kernel/signal.c	2005-03-01 23:39:07 -08:00
+++ b/arch/x86_64/kernel/signal.c	2005-03-01 23:39:07 -08:00
@@ -24,7 +24,6 @@
 #include <linux/stddef.h>
 #include <linux/personality.h>
 #include <linux/compiler.h>
-#include <linux/suspend.h>
 #include <asm/ucontext.h>
 #include <asm/uaccess.h>
 #include <asm/i387.h>
@@ -125,6 +124,12 @@
 			if (verify_area(VERIFY_READ, buf, sizeof(*buf)))
 				goto badframe;
 			err |= restore_i387(buf);
+		} else {
+			struct task_struct *me = current;
+			if (used_math()) {
+				clear_fpu(me);
+				clear_used_math();
+			}
 		}
 	}
 
@@ -139,7 +144,7 @@
 {
 	struct rt_sigframe __user *frame;
 	sigset_t set;
-	long eax;
+	unsigned long eax;
 
 	frame = (struct rt_sigframe __user *)(regs->rsp - 8);
 	if (verify_area(VERIFY_READ, frame, sizeof(*frame))) { 
@@ -246,7 +251,7 @@
 	int err = 0;
 	struct task_struct *me = current;
 
-	if (me->used_math) {
+	if (used_math()) {
 		fp = get_stack(ka, regs, sizeof(struct _fpstate)); 
 		frame = (void __user *)round_down((unsigned long)fp - sizeof(struct rt_sigframe), 16) - 8;
 
@@ -417,10 +422,8 @@
 		return 1;
 	} 	
 
-	if (current->flags & PF_FREEZE) {
-		refrigerator(0);
+	if (try_to_freeze(0))
 		goto no_signal;
-	}
 
 	if (!oldset)
 		oldset = &current->blocked;
diff -Nru a/arch/x86_64/kernel/smp.c b/arch/x86_64/kernel/smp.c
--- a/arch/x86_64/kernel/smp.c	2005-03-01 23:39:18 -08:00
+++ b/arch/x86_64/kernel/smp.c	2005-03-01 23:39:18 -08:00
@@ -25,6 +25,7 @@
 #include <asm/pgalloc.h>
 #include <asm/tlbflush.h>
 #include <asm/mach_apic.h>
+#include <asm/proto.h>
 
 /*
  *	Smarter SMP flushing macros. 
@@ -39,7 +40,7 @@
 static cpumask_t flush_cpumask;
 static struct mm_struct * flush_mm;
 static unsigned long flush_va;
-static spinlock_t tlbstate_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(tlbstate_lock);
 #define FLUSH_ALL	0xffffffff
 
 /*
@@ -268,7 +269,7 @@
  * Structure and data for smp_call_function(). This is designed to minimise
  * static memory requirements. It also looks cleaner.
  */
-static spinlock_t call_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(call_lock);
 
 struct call_data_struct {
 	void (*func) (void *info);
@@ -361,6 +362,8 @@
 void smp_send_stop(void)
 {
 	int nolock = 0;
+	if (reboot_force)
+		return;
 	/* Don't deadlock on the call lock in panic */
 	if (!spin_trylock(&call_lock)) {
 		/* ignore locking because we have paniced anyways */
diff -Nru a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c
--- a/arch/x86_64/kernel/smpboot.c	2005-03-01 23:39:18 -08:00
+++ b/arch/x86_64/kernel/smpboot.c	2005-03-01 23:39:18 -08:00
@@ -58,11 +58,12 @@
 int smp_num_siblings = 1;
 /* Package ID of each logical CPU */
 u8 phys_proc_id[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID };
+EXPORT_SYMBOL(phys_proc_id);
 
 /* Bitmask of currently online CPUs */
 cpumask_t cpu_online_map;
 
-static cpumask_t cpu_callin_map;
+cpumask_t cpu_callin_map;
 cpumask_t cpu_callout_map;
 static cpumask_t smp_commenced_mask;
 
diff -Nru a/arch/x86_64/kernel/suspend_asm.S b/arch/x86_64/kernel/suspend_asm.S
--- a/arch/x86_64/kernel/suspend_asm.S	2005-03-01 23:39:16 -08:00
+++ b/arch/x86_64/kernel/suspend_asm.S	2005-03-01 23:39:16 -08:00
@@ -1,6 +1,9 @@
-/* Originally gcc generated, modified by hand
+/* Copyright 2004,2005 Pavel Machek <pavel@suse.cz>, Andi Kleen <ak@suse.de>, Rafael J. Wysocki <rjw@sisk.pl>
  *
- * This may not use any stack, nor any variable that is not "NoSave":
+ * Distribute under GPLv2.
+ *
+ * swsusp_arch_resume may not use any stack, nor any variable that is
+ * not "NoSave" during copying pages:
  *
  * Its rewriting one kernel image with another. What is stack in "old"
  * image could very well be data page in "new" image, and overwriting
@@ -11,6 +14,7 @@
 #include <linux/linkage.h>
 #include <asm/segment.h>
 #include <asm/page.h>
+#include <asm/offset.h>
 
 ENTRY(swsusp_arch_suspend)
 
@@ -49,43 +53,28 @@
 	movq	%rcx, %cr3;
 	movq	%rax, %cr4;  # turn PGE back on
 
+	movq	pagedir_nosave(%rip), %rdx
+	/* compute the limit */
 	movl	nr_copy_pages(%rip), %eax
-	xorl	%ecx, %ecx
-	movq	$0, %r10
 	testl	%eax, %eax
 	jz	done
-.L105:
-	xorl	%esi, %esi
-	movq	$0, %r11
-	jmp	.L104
-	.p2align 4,,7
-copy_one_page:
-	movq	%r10, %rcx
-.L104:
-	movq	pagedir_nosave(%rip), %rdx
-	movq	%rcx, %rax
-	salq	$5, %rax
-	movq	8(%rdx,%rax), %rcx
-	movq	(%rdx,%rax), %rax
-	movzbl	(%rsi,%rax), %eax
-	movb	%al, (%rsi,%rcx)
-
-	movq	%cr3, %rax;  # flush TLB
-	movq	%rax, %cr3;
-
-	movq	%r11, %rax
-	incq	%rax
-	cmpq	$4095, %rax
-	movq	%rax, %rsi
-	movq	%rax, %r11
-	jbe	copy_one_page
-	movq	%r10, %rax
-	incq	%rax
-	movq	%rax, %rcx
-	movq	%rax, %r10
-	mov	nr_copy_pages(%rip), %eax
-	cmpq	%rax, %rcx
-	jb	.L105
+	movq	%rdx,%r8
+	movl	$SIZEOF_PBE,%r9d
+	mul		%r9  # with rax, clobbers rdx
+	movq 	%r8, %rdx
+	addq	%r8, %rax
+loop:
+	/* get addresses from the pbe and copy the page */
+	movq	pbe_address(%rdx), %rsi
+	movq	pbe_orig_address(%rdx), %rdi
+	movq	$512, %rcx
+	rep
+	movsq
+
+	/* progress to the next pbe */
+	addq	$SIZEOF_PBE, %rdx
+	cmpq	%rax, %rdx
+	jb	loop
 done:
 	movl	$24, %eax
 	movl	%eax, %ds
diff -Nru a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c
--- a/arch/x86_64/kernel/time.c	2005-03-01 23:39:07 -08:00
+++ b/arch/x86_64/kernel/time.c	2005-03-01 23:39:07 -08:00
@@ -49,8 +49,8 @@
 
 extern int using_apic_timer;
 
-spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
-spinlock_t i8253_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(rtc_lock);
+DEFINE_SPINLOCK(i8253_lock);
 
 static int nohpet __initdata = 0;
 static int notsc __initdata = 0;
@@ -956,14 +956,18 @@
 __setup("report_lost_ticks", time_setup);
 
 static long clock_cmos_diff;
+static unsigned long sleep_start;
 
 static int timer_suspend(struct sys_device *dev, u32 state)
 {
 	/*
 	 * Estimate time zone so that set_time can update the clock
 	 */
-	clock_cmos_diff = -get_cmos_time();
+	long cmos_time =  get_cmos_time();
+
+	clock_cmos_diff = -cmos_time;
 	clock_cmos_diff += get_seconds();
+	sleep_start = cmos_time;
 	return 0;
 }
 
@@ -971,15 +975,19 @@
 {
 	unsigned long flags;
 	unsigned long sec;
+	unsigned long ctime = get_cmos_time();
+	unsigned long sleep_length = (ctime - sleep_start) * HZ;
 
 	if (vxtime.hpet_address)
 		hpet_reenable();
 
-	sec = get_cmos_time() + clock_cmos_diff;
+	sec = ctime + clock_cmos_diff;
 	write_seqlock_irqsave(&xtime_lock,flags);
 	xtime.tv_sec = sec;
 	xtime.tv_nsec = 0;
 	write_sequnlock_irqrestore(&xtime_lock,flags);
+	jiffies += sleep_length;
+	wall_jiffies += sleep_length;
 	return 0;
 }
 
@@ -1021,7 +1029,6 @@
  * For (3), we use interrupts at 64Hz or user specified periodic
  * frequency, whichever is higher.
  */
-#include <linux/mc146818rtc.h>
 #include <linux/rtc.h>
 
 extern irqreturn_t rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs);
diff -Nru a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c
--- a/arch/x86_64/kernel/traps.c	2005-03-01 23:38:44 -08:00
+++ b/arch/x86_64/kernel/traps.c	2005-03-01 23:38:44 -08:00
@@ -74,7 +74,7 @@
 asmlinkage void call_debug(void);
 
 struct notifier_block *die_chain;
-static spinlock_t die_notifier_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(die_notifier_lock);
 
 int register_die_notifier(struct notifier_block *nb)
 {
@@ -324,7 +324,7 @@
 	BUG(); 
 } 
 
-static spinlock_t die_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(die_lock);
 static int die_owner = -1;
 
 void oops_begin(void)
@@ -405,15 +405,6 @@
 	do_exit(SIGSEGV);
 }
 
-static inline unsigned long get_cr2(void)
-{
-	unsigned long address;
-
-	/* get the address */
-	__asm__("movq %%cr2,%0":"=r" (address));
-	return address;
-}
-
 static void do_trap(int trapnr, int signr, char *str, 
 			   struct pt_regs * regs, long error_code, siginfo_t *info)
 {
@@ -556,8 +547,9 @@
 			regs->rip = fixup->fixup;
 			return;
 		}
-		notify_die(DIE_GPF, "general protection fault", regs, error_code,
-			   13, SIGSEGV); 
+		if (notify_die(DIE_GPF, "general protection fault", regs,
+					error_code, 13, SIGSEGV) == NOTIFY_STOP)
+			return;
 		die("general protection fault", regs, error_code);
 	}
 }
@@ -690,7 +682,9 @@
 	tsk->thread.debugreg6 = condition;
 
 	/* Mask out spurious TF errors due to lazy TF clearing */
-	if (condition & DR_STEP) {
+	if ((condition & DR_STEP) &&
+	    (notify_die(DIE_DEBUGSTEP, "debugstep", regs, condition,
+			1, SIGTRAP) != NOTIFY_STOP)) {
 		/*
 		 * The TF error should be masked out only if the current
 		 * process is not traced and if the TRAP flag has been set
@@ -882,6 +876,10 @@
 {
 }
 
+asmlinkage void __attribute__((weak)) smp_thermal_interrupt(void)
+{
+}
+
 /*
  *  'math_state_restore()' saves the current math information in the
  * old math state array, and gets the new ones from the current task
@@ -894,7 +892,7 @@
 	struct task_struct *me = current;
 	clts();			/* Allow maths ops (or we recurse) */
 
-	if (!me->used_math)
+	if (!used_math())
 		init_fpu(me);
 	restore_fpu_checking(&me->thread.i387.fxsave);
 	me->thread_info->status |= TS_USEDFPU;
@@ -910,7 +908,7 @@
 	set_intr_gate(0,&divide_error);
 	set_intr_gate_ist(1,&debug,DEBUG_STACK);
 	set_intr_gate_ist(2,&nmi,NMI_STACK);
-	set_intr_gate(3,&int3);
+	set_system_gate(3,&int3);
 	set_system_gate(4,&overflow);	/* int4-5 can be called from all */
 	set_system_gate(5,&bounds);
 	set_intr_gate(6,&invalid_op);
diff -Nru a/arch/x86_64/kernel/warmreboot.S b/arch/x86_64/kernel/warmreboot.S
--- a/arch/x86_64/kernel/warmreboot.S	2005-03-01 23:38:52 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,83 +0,0 @@
-/*
- * Switch back to real mode and call the BIOS reboot vector.
- * This is a trampoline copied around in process.c 
- * Written 2003 by Andi Kleen, SuSE Labs.	 	
- */			
-	
-#include <asm/msr.h>
-
-#define R(x) x-warm_reboot(%ebx)
-#define R64(x) x-warm_reboot(%rbx)
-		
-	/* running in identity mapping and in the first 64k of memory
-	   and in compatibility mode. This must be position independent */
-
-	/* Follows 14.7 "Leaving Long Mode" in the AMD x86-64 manual, volume 2
-	   and 8.9.2 "Switching Back to Real-Address Mode" in the Intel IA32
-	   manual, volume 2 */
-
-	/* ebx:	self pointer to warm_reboot */
-
-	.globl warm_reboot
-warm_reboot:
-	addl  %ebx,  R64(real_mode_desc)	/* relocate tables */
-	addl  %ebx,2+R64(warm_gdt_desc)		
-
-	movq  %cr0,%rax
-	btr  $31,%rax		
-	movq %rax,%cr0		/* disable paging */
-	jmp  1f			/* flush prefetch queue */
-	
-	.code32	
-1:	movl $MSR_EFER,%ecx
-	rdmsr
-	andl $~((1<<_EFER_LME)|(1<<_EFER_SCE)|(1<<_EFER_NX)),%eax
-	wrmsr			/* disable long mode in EFER */
-		
-	xorl %eax,%eax
-	movl %eax,%cr3		/* flush tlb */
-
-	/* Running protected mode without paging now */
-	
-	wbinvd			/* flush caches. Needed? */
-
-	lidt R(warm_idt_desc)
-	lgdt R(warm_gdt_desc)
-	
-	movl $0x10,%ecx		/* load segment registers with real mode settings */
-	movl %ecx,%ds
-	movl %ecx,%es
-	movl %ecx,%fs
-	movl %ecx,%gs
-	movl %ecx,%ss
-	
-	lea  R(real_mode_desc),%eax		
-	ljmp *(%eax)
-
-	.code16:
-real_mode:
-	xorl %eax,%eax
-	movl %eax,%cr0
-	
-	/* some people claim $0xf000,0xfff0 is better. Use what 32bit linux uses. */
-	/* code as bytes because gas has problems with it */
-	.byte 	0xea,0xf0,0xff,0x00,0xf0	/* ljmp  0xf000:0xfff0 */
-
-real_mode_desc:
-	.long  real_mode - warm_reboot
-	.short 8	
-warm_gdt_desc:
-	.short 8*3
-	.long warm_gdt - warm_reboot
-warm_gdt:	
-	.quad   0
-	.quad 	0x00009a000000ffff	/* 16-bit real-mode 64k code at 0x00000000 */
-	.quad   0x000092000100ffff	/* 16-bit real-mode 64k data at 0x00000100 */
-	
-warm_idt_desc:
-	.short 0x3ff
-	.long  0
-				
-	.globl warm_reboot_end
-warm_reboot_end:
-
diff -Nru a/arch/x86_64/kernel/x8664_ksyms.c b/arch/x86_64/kernel/x8664_ksyms.c
--- a/arch/x86_64/kernel/x8664_ksyms.c	2005-03-01 23:38:53 -08:00
+++ b/arch/x86_64/kernel/x8664_ksyms.c	2005-03-01 23:38:53 -08:00
@@ -30,7 +30,6 @@
 #include <asm/nmi.h>
 #include <asm/kdebug.h>
 #include <asm/unistd.h>
-#include <asm/delay.h>
 #include <asm/tlbflush.h>
 #include <asm/kdebug.h>
 
diff -Nru a/arch/x86_64/lib/csum-wrappers.c b/arch/x86_64/lib/csum-wrappers.c
--- a/arch/x86_64/lib/csum-wrappers.c	2005-03-01 23:38:44 -08:00
+++ b/arch/x86_64/lib/csum-wrappers.c	2005-03-01 23:38:44 -08:00
@@ -19,7 +19,7 @@
  * src and dst are best aligned to 64bits. 
  */ 
 unsigned int 
-csum_partial_copy_from_user(const char __user *src, char *dst, 
+csum_partial_copy_from_user(const unsigned char __user *src, unsigned char *dst,
 			    int len, unsigned int isum, int *errp)
 { 
 	might_sleep();
@@ -67,7 +67,7 @@
  * src and dst are best aligned to 64bits.
  */ 
 unsigned int 
-csum_partial_copy_to_user(const char *src, char __user *dst, 
+csum_partial_copy_to_user(unsigned const char *src, unsigned char __user *dst,
 			  int len, unsigned int isum, int *errp)
 { 
 	might_sleep();
@@ -105,7 +105,7 @@
  * Returns an 32bit unfolded checksum of the buffer.
  */ 
 unsigned int 
-csum_partial_copy_nocheck(const char *src, char *dst, int len, unsigned int sum)
+csum_partial_copy_nocheck(const unsigned char *src, unsigned char *dst, int len, unsigned int sum)
 { 
 	return csum_partial_copy_generic(src,dst,len,sum,NULL,NULL);
 } 
diff -Nru a/arch/x86_64/lib/delay.c b/arch/x86_64/lib/delay.c
--- a/arch/x86_64/lib/delay.c	2005-03-01 23:39:18 -08:00
+++ b/arch/x86_64/lib/delay.c	2005-03-01 23:39:18 -08:00
@@ -34,7 +34,7 @@
 
 inline void __const_udelay(unsigned long xloops)
 {
-        __delay(((xloops * current_cpu_data.loops_per_jiffy) >> 32) * HZ);
+	__delay(((xloops * cpu_data[_smp_processor_id()].loops_per_jiffy) >> 32) * HZ);
 }
 
 void __udelay(unsigned long usecs)
diff -Nru a/arch/x86_64/lib/io.c b/arch/x86_64/lib/io.c
--- a/arch/x86_64/lib/io.c	2005-03-01 23:38:52 -08:00
+++ b/arch/x86_64/lib/io.c	2005-03-01 23:38:52 -08:00
@@ -2,14 +2,22 @@
 #include <asm/io.h>
 #include <linux/module.h>
 
-void *__memcpy_toio(unsigned long dst,const void*src,unsigned len)
+void __memcpy_toio(unsigned long dst,const void*src,unsigned len)
 {
-	return __inline_memcpy((void *) dst,src,len);
+	__inline_memcpy((void *) dst,src,len);
 }
 EXPORT_SYMBOL(__memcpy_toio);
 
-void *__memcpy_fromio(void *dst,unsigned long src,unsigned len)
+void __memcpy_fromio(void *dst,unsigned long src,unsigned len)
 {
-	return __inline_memcpy(dst,(const void *) src,len);
+	__inline_memcpy(dst,(const void *) src,len);
 }
 EXPORT_SYMBOL(__memcpy_fromio);
+
+void memset_io(volatile void __iomem *a, int b, size_t c)
+{
+	/* XXX: memset can mangle the IO patterns quite a bit.
+	   perhaps it would be better to use a dumb one */
+	memset((void *)a,b,c);
+}
+EXPORT_SYMBOL(memset_io);
diff -Nru a/arch/x86_64/lib/old-checksum.c b/arch/x86_64/lib/old-checksum.c
--- a/arch/x86_64/lib/old-checksum.c	2005-03-01 23:39:09 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,33 +0,0 @@
-/*
- * Temporal C versions of the checksum functions until optimized assembler versions
- * can go in.
- */
-
-#include <net/checksum.h>
-
-/*
- * 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 char *src, char *dst,
-                                          int len, unsigned int sum,
-                                          int *err_ptr)
-{
-	int missing;
-
-	missing = copy_from_user(dst, src, len);
-	if (missing) {
-		memset(dst + len - missing, 0, missing);
-		*err_ptr = -EFAULT;
-	}
-		
-	return csum_partial(dst, len, sum);
-}
-
-unsigned int csum_partial_copy_nocheck(const char *src, char *dst, int len, unsigned int sum)
-{
-	memcpy(dst,src,len);
-	return csum_partial(dst,len,sum);
-}
-
-/* Fallback for csum_and_copy_to_user is currently in include/net/checksum.h */
diff -Nru a/arch/x86_64/mm/Makefile b/arch/x86_64/mm/Makefile
--- a/arch/x86_64/mm/Makefile	2005-03-01 23:39:08 -08:00
+++ b/arch/x86_64/mm/Makefile	2005-03-01 23:39:08 -08:00
@@ -6,5 +6,6 @@
 obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
 obj-$(CONFIG_DISCONTIGMEM) += numa.o
 obj-$(CONFIG_K8_NUMA) += k8topology.o
+obj-$(CONFIG_ACPI_NUMA) += srat.o
 
 hugetlbpage-y = ../../i386/mm/hugetlbpage.o
diff -Nru a/arch/x86_64/mm/fault.c b/arch/x86_64/mm/fault.c
--- a/arch/x86_64/mm/fault.c	2005-03-01 23:38:44 -08:00
+++ b/arch/x86_64/mm/fault.c	2005-03-01 23:38:44 -08:00
@@ -143,25 +143,25 @@
 
 void dump_pagetable(unsigned long address)
 {
-	pml4_t *pml4;
 	pgd_t *pgd;
+	pud_t *pud;
 	pmd_t *pmd;
 	pte_t *pte;
 
-	asm("movq %%cr3,%0" : "=r" (pml4));
+	asm("movq %%cr3,%0" : "=r" (pgd));
 
-	pml4 = __va((unsigned long)pml4 & PHYSICAL_PAGE_MASK); 
-	pml4 += pml4_index(address);
-	printk("PML4 %lx ", pml4_val(*pml4));
-	if (bad_address(pml4)) goto bad;
-	if (!pml4_present(*pml4)) goto ret; 
-
-	pgd = __pgd_offset_k((pgd_t *)pml4_page(*pml4), address);
+	pgd = __va((unsigned long)pgd & PHYSICAL_PAGE_MASK); 
+	pgd += pgd_index(address);
+	printk("PGD %lx ", pgd_val(*pgd));
 	if (bad_address(pgd)) goto bad;
-	printk("PGD %lx ", pgd_val(*pgd)); 
-	if (!pgd_present(*pgd))	goto ret;
+	if (!pgd_present(*pgd)) goto ret; 
+
+	pud = __pud_offset_k((pud_t *)pgd_page(*pgd), address);
+	if (bad_address(pud)) goto bad;
+	printk("PUD %lx ", pud_val(*pud));
+	if (!pud_present(*pud))	goto ret;
 
-	pmd = pmd_offset(pgd, address);
+	pmd = pmd_offset(pud, address);
 	if (bad_address(pmd)) goto bad;
 	printk("PMD %lx ", pmd_val(*pmd));
 	if (!pmd_present(*pmd))	goto ret;	 
@@ -212,6 +212,8 @@
 
 int unhandled_signal(struct task_struct *tsk, int sig)
 {
+	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))
@@ -232,7 +234,53 @@
 	do_exit(SIGKILL);
 }
 
-int page_fault_trace; 
+/*
+ * Handle a fault on the vmalloc or module mapping area
+ */
+static int vmalloc_fault(unsigned long address)
+{
+	pgd_t *pgd, *pgd_ref;
+	pud_t *pud, *pud_ref;
+	pmd_t *pmd, *pmd_ref;
+	pte_t *pte, *pte_ref;
+
+	/* Copy kernel mappings over when needed. This can also
+	   happen within a race in page table update. In the later
+	   case just flush. */
+
+	pgd = pgd_offset(current->mm ?: &init_mm, address);
+	pgd_ref = pgd_offset_k(address);
+	if (pgd_none(*pgd_ref))
+		return -1;
+	if (pgd_none(*pgd))
+		set_pgd(pgd, *pgd_ref);
+
+	/* Below here mismatches are bugs because these lower tables
+	   are shared */
+
+	pud = pud_offset(pgd, address);
+	pud_ref = pud_offset(pgd_ref, address);
+	if (pud_none(*pud_ref))
+		return -1;
+	if (pud_none(*pud) || pud_page(*pud) != pud_page(*pud_ref))
+		BUG();
+	pmd = pmd_offset(pud, address);
+	pmd_ref = pmd_offset(pud_ref, address);
+	if (pmd_none(*pmd_ref))
+		return -1;
+	if (pmd_none(*pmd) || pmd_page(*pmd) != pmd_page(*pmd_ref))
+		BUG();
+	pte_ref = pte_offset_kernel(pmd_ref, address);
+	if (!pte_present(*pte_ref))
+		return -1;
+	pte = pte_offset_kernel(pmd, address);
+	if (!pte_present(*pte) || pte_page(*pte) != pte_page(*pte_ref))
+		BUG();
+	__flush_tlb_all();
+	return 0;
+}
+
+int page_fault_trace = 0;
 int exception_trace = 1;
 
 /*
@@ -300,8 +348,11 @@
 	 * protection error (error_code & 1) == 0.
 	 */
 	if (unlikely(address >= TASK_SIZE)) {
-		if (!(error_code & 5))
-			goto vmalloc_fault;
+		if (!(error_code & 5)) {
+			if (vmalloc_fault(address) < 0)
+				goto bad_area_nosemaphore;
+			return;
+		}
 		/*
 		 * Don't take the mm semaphore here. If we fixup a prefetch
 		 * fault we could otherwise deadlock.
@@ -310,7 +361,7 @@
 	}
 
 	if (unlikely(error_code & (1 << 3)))
-		goto page_table_corruption;
+		pgtable_bad(address, regs, error_code);
 
 	/*
 	 * If we're in an interrupt or have no user
@@ -411,7 +462,7 @@
 #ifdef CONFIG_IA32_EMULATION
 	/* 32bit vsyscall. map on demand. */
 	if (test_thread_flag(TIF_IA32) &&
-	    address >= 0xffffe000 && address < 0xffffe000 + PAGE_SIZE) { 
+	    address >= VSYSCALL32_BASE && address < VSYSCALL32_END) {
 		if (map_syscall32(mm, address) < 0)
 			goto out_of_memory2;
 		return;
@@ -434,8 +485,9 @@
 			return;
 
 		if (exception_trace && unhandled_signal(tsk, SIGSEGV)) {
-			printk(KERN_INFO
-		       "%s[%d]: segfault at %016lx rip %016lx rsp %016lx error %lx\n",
+			printk(
+		       "%s%s[%d]: segfault at %016lx rip %016lx rsp %016lx error %lx\n",
+					tsk->pid > 1 ? KERN_INFO : KERN_EMERG,
 					tsk->comm, tsk->pid, address, regs->rip,
 					regs->rsp, error_code);
 		}
@@ -524,34 +576,4 @@
 	info.si_addr = (void __user *)address;
 	force_sig_info(SIGBUS, &info, tsk);
 	return;
-
-vmalloc_fault:
-	{
-		pgd_t *pgd;
-		pmd_t *pmd;
-		pte_t *pte; 
-
-		/*
-		 * x86-64 has the same kernel 3rd level pages for all CPUs.
-		 * But for vmalloc/modules the TLB synchronization works lazily,
-		 * so it can happen that we get a page fault for something
-		 * that is really already in the page table. Just check if it
-		 * is really there and when yes flush the local TLB. 
-		 */
-		pgd = pgd_offset_k(address);
-		if (!pgd_present(*pgd))
-			goto bad_area_nosemaphore;
-		pmd = pmd_offset(pgd, address);
-		if (!pmd_present(*pmd))
-			goto bad_area_nosemaphore;
-		pte = pte_offset_kernel(pmd, address); 
-		if (!pte_present(*pte))
-			goto bad_area_nosemaphore;
-
-		__flush_tlb_all();		
-		return;
-	}
-
-page_table_corruption:
-	pgtable_bad(address, regs, error_code);
 }
diff -Nru a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c
--- a/arch/x86_64/mm/init.c	2005-03-01 23:38:53 -08:00
+++ b/arch/x86_64/mm/init.c	2005-03-01 23:38:53 -08:00
@@ -68,8 +68,8 @@
 
 	for_each_pgdat(pgdat) {
                for (i = 0; i < pgdat->node_spanned_pages; ++i) {
-                       page = pgdat->node_mem_map + i;
-		total++;
+			page = pfn_to_page(pgdat->node_start_pfn + i);
+			total++;
                        if (PageReserved(page))
 			reserved++;
                        else if (PageSwapCache(page))
@@ -108,28 +108,28 @@
 static void set_pte_phys(unsigned long vaddr,
 			 unsigned long phys, pgprot_t prot)
 {
-	pml4_t *level4;
 	pgd_t *pgd;
+	pud_t *pud;
 	pmd_t *pmd;
 	pte_t *pte, new_pte;
 
 	Dprintk("set_pte_phys %lx to %lx\n", vaddr, phys);
 
-	level4 = pml4_offset_k(vaddr);
-	if (pml4_none(*level4)) {
-		printk("PML4 FIXMAP MISSING, it should be setup in head.S!\n");
+	pgd = pgd_offset_k(vaddr);
+	if (pgd_none(*pgd)) {
+		printk("PGD FIXMAP MISSING, it should be setup in head.S!\n");
 		return;
 	}
-	pgd = level3_offset_k(level4, vaddr);
-	if (pgd_none(*pgd)) {
+	pud = pud_offset(pgd, vaddr);
+	if (pud_none(*pud)) {
 		pmd = (pmd_t *) spp_getpage(); 
-		set_pgd(pgd, __pgd(__pa(pmd) | _KERNPG_TABLE | _PAGE_USER));
-		if (pmd != pmd_offset(pgd, 0)) {
-			printk("PAGETABLE BUG #01! %p <-> %p\n", pmd, pmd_offset(pgd,0));
+		set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE | _PAGE_USER));
+		if (pmd != pmd_offset(pud, 0)) {
+			printk("PAGETABLE BUG #01! %p <-> %p\n", pmd, pmd_offset(pud,0));
 			return;
 		}
 	}
-	pmd = pmd_offset(pgd, vaddr);
+	pmd = pmd_offset(pud, vaddr);
 	if (pmd_none(*pmd)) {
 		pte = (pte_t *) spp_getpage();
 		set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE | _PAGE_USER));
@@ -210,31 +210,31 @@
 	ti->allocated = 0; 
 } 
 
-static void __init phys_pgd_init(pgd_t *pgd, unsigned long address, unsigned long end)
+static void __init phys_pud_init(pud_t *pud, unsigned long address, unsigned long end)
 { 
 	long i, j; 
 
-	i = pgd_index(address);
-	pgd = pgd + i;
-	for (; i < PTRS_PER_PGD; pgd++, i++) {
+	i = pud_index(address);
+	pud = pud + i;
+	for (; i < PTRS_PER_PUD; pud++, i++) {
 		int map; 
 		unsigned long paddr, pmd_phys;
 		pmd_t *pmd;
 
-		paddr = (address & PML4_MASK) + i*PGDIR_SIZE;
+		paddr = address + i*PUD_SIZE;
 		if (paddr >= end) { 
-			for (; i < PTRS_PER_PGD; i++, pgd++) 
-				set_pgd(pgd, __pgd(0)); 
+			for (; i < PTRS_PER_PUD; i++, pud++) 
+				set_pud(pud, __pud(0)); 
 			break;
 		} 
 
-		if (!e820_mapped(paddr, paddr+PGDIR_SIZE, 0)) { 
-			set_pgd(pgd, __pgd(0)); 
+		if (!e820_mapped(paddr, paddr+PUD_SIZE, 0)) { 
+			set_pud(pud, __pud(0)); 
 			continue;
 		} 
 
 		pmd = alloc_low_page(&map, &pmd_phys);
-		set_pgd(pgd, __pgd(pmd_phys | _KERNPG_TABLE));
+		set_pud(pud, __pud(pmd_phys | _KERNPG_TABLE));
 		for (j = 0; j < PTRS_PER_PMD; pmd++, j++, paddr += PMD_SIZE) {
 			unsigned long pe;
 
@@ -252,51 +252,55 @@
 	__flush_tlb();
 } 
 
+static void __init find_early_table_space(unsigned long end)
+{
+	unsigned long puds, pmds, tables;
+
+	puds = (end + PUD_SIZE - 1) >> PUD_SHIFT;
+	pmds = (end + PMD_SIZE - 1) >> PMD_SHIFT;
+	tables = round_up(puds * sizeof(pud_t), PAGE_SIZE) +
+		 round_up(pmds * sizeof(pmd_t), PAGE_SIZE);
+
+	table_start = find_e820_area(0x8000, __pa_symbol(&_text), tables);
+	if (table_start == -1UL)
+		panic("Cannot find space for the kernel page tables");
+
+	table_start >>= PAGE_SHIFT;
+	table_end = table_start;
+}
+
 /* Setup the direct mapping of the physical memory at PAGE_OFFSET.
    This runs before bootmem is initialized and gets pages directly from the 
    physical memory. To access them they are temporarily mapped. */
-void __init init_memory_mapping(void) 
+void __init init_memory_mapping(unsigned long start, unsigned long end)
 { 
-	unsigned long adr;	       
-	unsigned long end;
 	unsigned long next; 
-	unsigned long pgds, pmds, tables; 
 
 	Dprintk("init_memory_mapping\n");
 
-	end = end_pfn_map << PAGE_SHIFT;
-
 	/* 
 	 * Find space for the kernel direct mapping tables.
 	 * Later we should allocate these tables in the local node of the memory
 	 * mapped.  Unfortunately this is done currently before the nodes are 
 	 * discovered.
 	 */
+	find_early_table_space(end);
 
-	pgds = (end + PGDIR_SIZE - 1) >> PGDIR_SHIFT;
-	pmds = (end + PMD_SIZE - 1) >> PMD_SHIFT; 
-	tables = round_up(pgds*8, PAGE_SIZE) + round_up(pmds * 8, PAGE_SIZE); 
-
-	table_start = find_e820_area(0x8000, __pa_symbol(&_text), tables); 
-	if (table_start == -1UL) 
-		panic("Cannot find space for the kernel page tables"); 
-
-	table_start >>= PAGE_SHIFT; 
-	table_end = table_start;
-       
-	end += __PAGE_OFFSET; /* turn virtual */  	
+	start = (unsigned long)__va(start);
+	end = (unsigned long)__va(end);
 
-	for (adr = PAGE_OFFSET; adr < end; adr = next) { 
+	for (; start < end; start = next) {
 		int map;
-		unsigned long pgd_phys; 
-		pgd_t *pgd = alloc_low_page(&map, &pgd_phys);
-		next = adr + PML4_SIZE;
+		unsigned long pud_phys; 
+		pud_t *pud = alloc_low_page(&map, &pud_phys);
+		next = start + PGDIR_SIZE;
 		if (next > end) 
 			next = end; 
-		phys_pgd_init(pgd, adr-PAGE_OFFSET, next-PAGE_OFFSET); 
-		set_pml4(init_level4_pgt + pml4_index(adr), mk_kernel_pml4(pgd_phys));
+		phys_pud_init(pud, __pa(start), __pa(next));
+		set_pgd(pgd_offset_k(start), mk_kernel_pgd(pud_phys));
 		unmap_low_page(map);   
 	} 
+
 	asm volatile("movq %%cr4,%0" : "=r" (mmu_cr4_features));
 	__flush_tlb_all();
 	early_printk("kernel direct mapping tables upto %lx @ %lx-%lx\n", end, 
@@ -306,25 +310,12 @@
 
 extern struct x8664_pda cpu_pda[NR_CPUS];
 
-static unsigned long low_pml4[NR_CPUS];
-
-void swap_low_mappings(void)
-{
-	int i;
-	for (i = 0; i < NR_CPUS; i++) {
-	        unsigned long t;
-		if (!cpu_pda[i].level4_pgt) 
-			continue;
-		t = cpu_pda[i].level4_pgt[0];
-		cpu_pda[i].level4_pgt[0] = low_pml4[i];
-		low_pml4[i] = t;
-	}
-	flush_tlb_all();
-}
-
+/* Assumes all CPUs still execute in init_mm */
 void zap_low_mappings(void)
 {
-	swap_low_mappings();
+	pgd_t *pgd = pgd_offset_k(0UL);
+	pgd_clear(pgd);
+	flush_tlb_all();
 }
 
 #ifndef CONFIG_DISCONTIGMEM
@@ -361,10 +352,14 @@
 	
 	for (; address < end; address += LARGE_PAGE_SIZE) { 
 		pgd_t *pgd = pgd_offset_k(address);
-               pmd_t *pmd;
-		if (!pgd || pgd_none(*pgd))
+		pud_t *pud;
+		pmd_t *pmd;
+		if (pgd_none(*pgd))
+			continue;
+		pud = pud_offset(pgd, address);
+		if (pud_none(*pud))
 			continue; 
-               pmd = pmd_offset(pgd, address);
+		pmd = pmd_offset(pud, address);
 		if (!pmd || pmd_none(*pmd))
 			continue; 
 		if (0 == (pmd_val(*pmd) & _PAGE_PSE)) { 
@@ -446,7 +441,7 @@
 		/*
 		 * Only count reserved RAM pages
 		 */
-		if (page_is_ram(tmp) && PageReserved(mem_map+tmp))
+		if (page_is_ram(tmp) && PageReserved(pfn_to_page(tmp)))
 			reservedpages++;
 #endif
 
@@ -531,29 +526,29 @@
 int kern_addr_valid(unsigned long addr) 
 { 
 	unsigned long above = ((long)addr) >> __VIRTUAL_MASK_SHIFT;
-       pml4_t *pml4;
        pgd_t *pgd;
+       pud_t *pud;
        pmd_t *pmd;
        pte_t *pte;
 
 	if (above != 0 && above != -1UL)
 		return 0; 
 	
-       pml4 = pml4_offset_k(addr);
-	if (pml4_none(*pml4))
+	pgd = pgd_offset_k(addr);
+	if (pgd_none(*pgd))
 		return 0;
 
-       pgd = pgd_offset_k(addr);
-	if (pgd_none(*pgd))
+	pud = pud_offset(pgd, addr);
+	if (pud_none(*pud))
 		return 0; 
 
-       pmd = pmd_offset(pgd, addr);
+	pmd = pmd_offset(pud, addr);
 	if (pmd_none(*pmd))
 		return 0;
 	if (pmd_large(*pmd))
 		return pfn_valid(pmd_pfn(*pmd));
 
-       pte = pte_offset_kernel(pmd, addr);
+	pte = pte_offset_kernel(pmd, addr);
 	if (pte_none(*pte))
 		return 0;
 	return pfn_valid(pte_pfn(*pte));
@@ -610,7 +605,7 @@
 	if (test_tsk_thread_flag(tsk, TIF_IA32)) {
 		/* lookup code assumes the pages are present. set them up
 		   now */
-		if (__map_syscall32(tsk->mm, 0xfffe000) < 0)
+		if (__map_syscall32(tsk->mm, VSYSCALL32_BASE) < 0)
 			return NULL;
 		return &gate32_vma;
 	}
@@ -622,4 +617,14 @@
 {
 	struct vm_area_struct *vma = get_gate_vma(task);
 	return (addr >= vma->vm_start) && (addr < vma->vm_end);
+}
+
+/* Use this when you have no reliable task/vma, typically from interrupt
+ * context.  It is less reliable than using the task's vma and may give
+ * false positives.
+ */
+int in_gate_area_no_task(unsigned long addr)
+{
+	return (((addr >= VSYSCALL_START) && (addr < VSYSCALL_END)) ||
+		((addr >= VSYSCALL32_BASE) && (addr < VSYSCALL32_END)));
 }
diff -Nru a/arch/x86_64/mm/ioremap.c b/arch/x86_64/mm/ioremap.c
--- a/arch/x86_64/mm/ioremap.c	2005-03-01 23:39:16 -08:00
+++ b/arch/x86_64/mm/ioremap.c	2005-03-01 23:39:16 -08:00
@@ -16,7 +16,7 @@
 #include <asm/fixmap.h>
 #include <asm/cacheflush.h>
 #include <asm/tlbflush.h>
-
+#include <asm/proto.h>
 
 static inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned long size,
 	unsigned long phys_addr, unsigned long flags)
@@ -49,10 +49,10 @@
 {
 	unsigned long end;
 
-	address &= ~PGDIR_MASK;
+	address &= ~PUD_MASK;
 	end = address + size;
-	if (end > PGDIR_SIZE)
-		end = PGDIR_SIZE;
+	if (end > PUD_SIZE)
+		end = PUD_SIZE;
 	phys_addr -= address;
 	if (address >= end)
 		BUG();
@@ -67,31 +67,54 @@
 	return 0;
 }
 
+static inline int remap_area_pud(pud_t * pud, unsigned long address, unsigned long size,
+	unsigned long phys_addr, unsigned long flags)
+{
+	unsigned long end;
+
+	address &= ~PGDIR_MASK;
+	end = address + size;
+	if (end > PGDIR_SIZE)
+		end = PGDIR_SIZE;
+	phys_addr -= address;
+	if (address >= end)
+		BUG();
+	do {
+		pmd_t * pmd = pmd_alloc(&init_mm, pud, address);
+		if (!pmd)
+			return -ENOMEM;
+		remap_area_pmd(pmd, address, end - address, address + phys_addr, flags);
+		address = (address + PUD_SIZE) & PUD_MASK;
+		pud++;
+	} while (address && (address < end));
+	return 0;
+}
+
 static int remap_area_pages(unsigned long address, unsigned long phys_addr,
 				 unsigned long size, unsigned long flags)
 {
 	int error;
-	pgd_t * dir;
+	pgd_t *pgd;
 	unsigned long end = address + size;
 
 	phys_addr -= address;
-	dir = pgd_offset_k(address);
+	pgd = pgd_offset_k(address);
 	flush_cache_all();
 	if (address >= end)
 		BUG();
 	spin_lock(&init_mm.page_table_lock);
 	do {
-		pmd_t *pmd;
-		pmd = pmd_alloc(&init_mm, dir, address);
+		pud_t *pud;
+		pud = pud_alloc(&init_mm, pgd, address);
 		error = -ENOMEM;
-		if (!pmd)
+		if (!pud)
 			break;
-		if (remap_area_pmd(pmd, address, end - address,
+		if (remap_area_pud(pud, address, end - address,
 					 phys_addr + address, flags))
 			break;
 		error = 0;
 		address = (address + PGDIR_SIZE) & PGDIR_MASK;
-		dir++;
+		pgd++;
 	} while (address && (address < end));
 	spin_unlock(&init_mm.page_table_lock);
 	flush_tlb_all();
@@ -99,7 +122,31 @@
 }
 
 /*
- * Generic mapping function (not visible outside):
+ * Fix up the linear direct mapping of the kernel to avoid cache attribute
+ * conflicts.
+ */
+static int
+ioremap_change_attr(unsigned long phys_addr, unsigned long size,
+					unsigned long flags)
+{
+	int err = 0;
+	if (flags && phys_addr + size - 1 < (end_pfn_map << PAGE_SHIFT)) {
+		unsigned long npages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
+		unsigned long vaddr = (unsigned long) __va(phys_addr);
+
+		/*
+ 		 * Must use a address here and not struct page because the phys addr
+		 * can be a in hole between nodes and not have an memmap entry.
+		 */
+		err = change_page_attr_addr(vaddr,npages,__pgprot(__PAGE_KERNEL|flags));
+		if (!err)
+			global_flush_tlb();
+	}
+	return err;
+}
+
+/*
+ * Generic mapping function
  */
 
 /*
@@ -128,11 +175,11 @@
 	if (phys_addr >= 0xA0000 && last_addr < 0x100000)
 		return (__force void __iomem *)phys_to_virt(phys_addr);
 
+#ifndef CONFIG_DISCONTIGMEM
 	/*
 	 * Don't allow anybody to remap normal RAM that we're using..
 	 */
-	if (phys_addr < virt_to_phys(high_memory)) {
-#ifndef CONFIG_DISCONTIGMEM
+	if (last_addr < virt_to_phys(high_memory)) {
 		char *t_addr, *t_end;
  		struct page *page;
 
@@ -142,8 +189,8 @@
 		for(page = virt_to_page(t_addr); page <= virt_to_page(t_end); page++)
 			if(!PageReserved(page))
 				return NULL;
-#endif
 	}
+#endif
 
 	/*
 	 * Mappings have to be page-aligned
@@ -155,12 +202,17 @@
 	/*
 	 * Ok, go for it..
 	 */
-	area = get_vm_area(size, VM_IOREMAP);
+	area = get_vm_area(size, VM_IOREMAP | (flags << 20));
 	if (!area)
 		return NULL;
 	area->phys_addr = phys_addr;
 	addr = area->addr;
 	if (remap_area_pages((unsigned long) addr, phys_addr, size, flags)) {
+		remove_vm_area((void *)(PAGE_MASK & (unsigned long) addr));
+		return NULL;
+	}
+	if (ioremap_change_attr(phys_addr, size, flags) < 0) {
+		area->flags &= 0xffffff;
 		vunmap(addr);
 		return NULL;
 	}
@@ -191,43 +243,35 @@
 
 void __iomem *ioremap_nocache (unsigned long phys_addr, unsigned long size)
 {
-	void __iomem *p = __ioremap(phys_addr, size, _PAGE_PCD);
-	if (!p) 
-		return p; 
-
-	if (phys_addr + size < virt_to_phys(high_memory)) { 
-		struct page *ppage = virt_to_page(__va(phys_addr));		
-		unsigned long npages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
-
-		BUG_ON(phys_addr+size > (unsigned long)high_memory);
-		BUG_ON(phys_addr + size < phys_addr);
-
-		if (change_page_attr(ppage, npages, PAGE_KERNEL_NOCACHE) < 0) { 
-			iounmap(p); 
-			p = NULL;
-		}
-		global_flush_tlb();
-	} 
-
-	return p;					
+	return __ioremap(phys_addr, size, _PAGE_PCD);
 }
 
 void iounmap(volatile void __iomem *addr)
 {
-	struct vm_struct *p;
+	struct vm_struct *p, **pprev;
+
 	if (addr <= high_memory) 
 		return; 
-	p = remove_vm_area((void *)(PAGE_MASK & (unsigned long) addr)); 
+
+	write_lock(&vmlist_lock);
+	for (p = vmlist, pprev = &vmlist; p != NULL; pprev = &p->next, p = *pprev)
+		if (p->addr == (void *)(PAGE_MASK & (unsigned long)addr))
+			break;
 	if (!p) { 
 		printk("__iounmap: bad address %p\n", addr);
-		return;
-	} 
-
-	if (p->flags && p->phys_addr < virt_to_phys(high_memory)) { 
+		goto out_unlock;
+	}
+	*pprev = p->next;
+	unmap_vm_area(p);
+	if ((p->flags >> 20) &&
+		p->phys_addr + p->size - 1 < virt_to_phys(high_memory)) {
+		/* p->size includes the guard page, but cpa doesn't like that */
 		change_page_attr(virt_to_page(__va(p->phys_addr)),
-				 p->size >> PAGE_SHIFT,
+				 (p->size - PAGE_SIZE) >> PAGE_SHIFT,
 				 PAGE_KERNEL); 				 
 		global_flush_tlb();
 	} 
+out_unlock:
+	write_unlock(&vmlist_lock);
 	kfree(p); 
 }
diff -Nru a/arch/x86_64/mm/k8topology.c b/arch/x86_64/mm/k8topology.c
--- a/arch/x86_64/mm/k8topology.c	2005-03-01 23:39:17 -08:00
+++ b/arch/x86_64/mm/k8topology.c	2005-03-01 23:39:17 -08:00
@@ -2,9 +2,7 @@
  * AMD K8 NUMA support.
  * Discover the memory map and associated nodes.
  * 
- * Doesn't use the ACPI SRAT table because it has a questionable license.
- * Instead the northbridge registers are read directly. 
- * XXX in 2.5 we could use the generic SRAT code
+ * This version reads it directly from the K8 northbridge.
  * 
  * Copyright 2002,2003 Andi Kleen, SuSE Labs.
  */
@@ -45,10 +43,14 @@
 int __init k8_scan_nodes(unsigned long start, unsigned long end)
 { 
 	unsigned long prevbase;
-	struct node nodes[MAXNODE];
+	struct node nodes[8];
 	int nodeid, i, nb; 
 	int found = 0;
 	u32 reg;
+	unsigned numnodes;
+	nodemask_t nodes_parsed;
+
+	nodes_clear(nodes_parsed);
 
 	nb = find_northbridge(); 
 	if (nb < 0) 
@@ -57,9 +59,9 @@
 	printk(KERN_INFO "Scanning NUMA topology in Northbridge %d\n", nb); 
 
 	reg = read_pci_config(0, nb, 0, 0x60); 
-	numnodes =  ((reg >> 4) & 7) + 1; 
+	numnodes = ((reg >> 4) & 0xF) + 1;
 
-	printk(KERN_INFO "Number of nodes %d (%x)\n", numnodes, reg);
+	printk(KERN_INFO "Number of nodes %d\n", numnodes);
 
 	memset(&nodes,0,sizeof(nodes)); 
 	prevbase = 0;
@@ -71,11 +73,11 @@
 
 		nodeid = limit & 7; 
 		if ((base & 3) == 0) { 
-			if (i < numnodes) 
+			if (i < numnodes)
 				printk("Skipping disabled node %d\n", i); 
 			continue;
 		} 
-		if (nodeid >= numnodes) { 
+		if (nodeid >= numnodes) {
 			printk("Ignoring excess node %d (%lx:%lx)\n", nodeid,
 			       base, limit); 
 			continue;
@@ -91,7 +93,7 @@
 			       nodeid, (base>>8)&3, (limit>>8) & 3); 
 			return -1; 
 		}	
-		if (node_online(nodeid)) { 
+		if (node_isset(nodeid, nodes_parsed)) { 
 			printk(KERN_INFO "Node %d already present. Skipping\n", 
 			       nodeid);
 			continue;
@@ -139,24 +141,26 @@
 		nodes[nodeid].end = limit;
 
 		prevbase = base;
+
+		node_set(nodeid, nodes_parsed);
 	} 
 
 	if (!found)
 		return -1; 
 
-	memnode_shift = compute_hash_shift(nodes);
+	memnode_shift = compute_hash_shift(nodes, numnodes);
 	if (memnode_shift < 0) { 
 		printk(KERN_ERR "No NUMA node hash function found. Contact maintainer\n"); 
 		return -1; 
 	} 
 	printk(KERN_INFO "Using node hash shift of %d\n", memnode_shift); 
 
-	for (i = 0; i < MAXNODE; i++) { 
+	for (i = 0; i < 8; i++) {
 		if (nodes[i].start != nodes[i].end) { 
 			/* assume 1:1 NODE:CPU */
 			cpu_to_node[i] = i; 
-		setup_node_bootmem(i, nodes[i].start, nodes[i].end); 
-	} 
+			setup_node_bootmem(i, nodes[i].start, nodes[i].end); 
+		} 
 	}
 
 	numa_init_array();
diff -Nru a/arch/x86_64/mm/numa.c b/arch/x86_64/mm/numa.c
--- a/arch/x86_64/mm/numa.c	2005-03-01 23:39:09 -08:00
+++ b/arch/x86_64/mm/numa.c	2005-03-01 23:39:09 -08:00
@@ -16,25 +16,24 @@
 #include <asm/proto.h>
 #include <asm/dma.h>
 #include <asm/numa.h>
+#include <asm/acpi.h>
 
 #ifndef Dprintk
 #define Dprintk(x...)
 #endif
 
-struct pglist_data *node_data[MAXNODE];
+struct pglist_data *node_data[MAX_NUMNODES];
 bootmem_data_t plat_node_bdata[MAX_NUMNODES];
 
 int memnode_shift;
 u8  memnodemap[NODEMAPSIZE];
 
-unsigned char cpu_to_node[NR_CPUS];  
-cpumask_t     node_to_cpumask[MAXNODE]; 
+unsigned char cpu_to_node[NR_CPUS] = { [0 ... NR_CPUS-1] = NUMA_NO_NODE };
+cpumask_t     node_to_cpumask[MAX_NUMNODES];
 
-static int numa_off __initdata; 
+int numa_off __initdata;
 
-unsigned long nodes_present; 
-
-int __init compute_hash_shift(struct node *nodes)
+int __init compute_hash_shift(struct node *nodes, int numnodes)
 {
 	int i; 
 	int shift = 24;
@@ -43,7 +42,7 @@
 	/* When in doubt use brute force. */
 	while (shift < 48) { 
 		memset(memnodemap,0xff,sizeof(*memnodemap) * NODEMAPSIZE); 
-		for (i = 0; i < numnodes; i++) { 
+		for (i = 0; i < numnodes; i++) {
 			if (nodes[i].start == nodes[i].end) 
 				continue;
 			for (addr = nodes[i].start; 
@@ -109,8 +108,6 @@
 
 	reserve_bootmem_node(NODE_DATA(nodeid), nodedata_phys, pgdat_size); 
 	reserve_bootmem_node(NODE_DATA(nodeid), bootmap_start, bootmap_pages<<PAGE_SHIFT);
-	if (nodeid + 1 > numnodes)
-		numnodes = nodeid + 1;
 	node_set_online(nodeid);
 } 
 
@@ -150,13 +147,12 @@
 	   CPUs, as the number of CPUs is not known yet. 
 	   We round robin the existing nodes. */
 	rr = 0;
-	for (i = 0; i < MAXNODE; i++) {
-		if (node_online(i))
+	for (i = 0; i < NR_CPUS; i++) {
+		if (cpu_to_node[i] != NUMA_NO_NODE)
 			continue;
 		rr = next_node(rr, node_online_map);
 		if (rr == MAX_NUMNODES)
 			rr = first_node(node_online_map);
-		node_data[i] = node_data[rr];
 		cpu_to_node[i] = rr;
 		rr++; 
 	}
@@ -171,7 +167,7 @@
 static int numa_emulation(unsigned long start_pfn, unsigned long end_pfn)
 {
  	int i;
- 	struct node nodes[MAXNODE];
+ 	struct node nodes[MAX_NUMNODES];
  	unsigned long sz = ((end_pfn - start_pfn)<<PAGE_SHIFT) / numa_fake;
 
  	/* Kludge needed for the hash function */
@@ -196,15 +192,15 @@
  		       i,
  		       nodes[i].start, nodes[i].end,
  		       (nodes[i].end - nodes[i].start) >> 20);
+		node_set_online(i);
  	}
- 	numnodes = numa_fake;
- 	memnode_shift = compute_hash_shift(nodes);
+ 	memnode_shift = compute_hash_shift(nodes, numa_fake);
  	if (memnode_shift < 0) {
  		memnode_shift = 0;
  		printk(KERN_ERR "No NUMA hash function found. Emulation disabled.\n");
  		return -1;
  	}
- 	for (i = 0; i < numa_fake; i++)
+ 	for_each_online_node(i)
  		setup_node_bootmem(i, nodes[i].start, nodes[i].end);
  	numa_init_array();
  	return 0;
@@ -220,6 +216,12 @@
  		return;
 #endif
 
+#ifdef CONFIG_ACPI_NUMA
+	if (!numa_off && !acpi_scan_nodes(start_pfn << PAGE_SHIFT,
+					  end_pfn << PAGE_SHIFT))
+ 		return;
+#endif
+
 #ifdef CONFIG_K8_NUMA
 	if (!numa_off && !k8_scan_nodes(start_pfn<<PAGE_SHIFT, end_pfn<<PAGE_SHIFT))
 		return;
@@ -233,11 +235,12 @@
 		/* setup dummy node covering all memory */ 
 	memnode_shift = 63; 
 	memnodemap[0] = 0;
-	numnodes = 1;
+	nodes_clear(node_online_map);
+	node_set_online(0);
 	for (i = 0; i < NR_CPUS; i++)
 		cpu_to_node[i] = 0;
 	node_to_cpumask[0] = cpumask_of_cpu(0);
-	setup_node_bootmem(0, start_pfn<<PAGE_SHIFT, end_pfn<<PAGE_SHIFT);
+	setup_node_bootmem(0, start_pfn << PAGE_SHIFT, end_pfn << PAGE_SHIFT);
 }
 
 __init void numa_add_cpu(int cpu)
@@ -251,7 +254,7 @@
 { 
 	int i;
 	unsigned long pages = 0;
-	for_all_nodes(i) {
+	for_each_online_node(i) {
 		pages += free_all_bootmem_node(NODE_DATA(i));
 	}
 	return pages;
@@ -260,7 +263,7 @@
 void __init paging_init(void)
 { 
 	int i;
-	for_all_nodes(i) { 
+	for_each_online_node(i) {
 		setup_node_zones(i); 
 	}
 } 
@@ -268,7 +271,7 @@
 /* [numa=off] */
 __init int numa_setup(char *opt) 
 { 
-	if (!strcmp(opt,"off"))
+	if (!strncmp(opt,"off",3))
 		numa_off = 1;
 #ifdef CONFIG_NUMA_EMU
 	if(!strncmp(opt, "fake=", 5)) {
@@ -276,6 +279,10 @@
 		if (numa_fake >= MAX_NUMNODES)
 			numa_fake = MAX_NUMNODES;
 	}
+#endif
+#ifdef CONFIG_ACPI_NUMA
+ 	if (!strncmp(opt,"noacpi",6))
+ 		acpi_numa = -1;
 #endif
 	return 1;
 } 
diff -Nru a/arch/x86_64/mm/pageattr.c b/arch/x86_64/mm/pageattr.c
--- a/arch/x86_64/mm/pageattr.c	2005-03-01 23:38:57 -08:00
+++ b/arch/x86_64/mm/pageattr.c	2005-03-01 23:38:57 -08:00
@@ -16,12 +16,16 @@
 
 static inline pte_t *lookup_address(unsigned long address) 
 { 
-	pgd_t *pgd = pgd_offset_k(address); 
+	pgd_t *pgd = pgd_offset_k(address);
+	pud_t *pud;
 	pmd_t *pmd;
 	pte_t *pte;
-	if (!pgd || !pgd_present(*pgd))
+	if (pgd_none(*pgd))
+		return NULL;
+	pud = pud_offset(pgd, address);
+	if (!pud_present(*pud))
 		return NULL; 
-	pmd = pmd_offset(pgd, address); 	       
+	pmd = pmd_offset(pud, address);
 	if (!pmd_present(*pmd))
 		return NULL; 
 	if (pmd_large(*pmd))
@@ -61,7 +65,10 @@
 			asm volatile("clflush (%0)" :: "r" (address + i)); 
 	} else
 		asm volatile("wbinvd":::"memory"); 
-	__flush_tlb_one(address);
+	if (address)
+		__flush_tlb_one(address);
+	else
+		__flush_tlb_all();
 }
 
 
@@ -98,54 +105,65 @@
  */
 static void revert_page(unsigned long address, pgprot_t ref_prot)
 {
-       pgd_t *pgd;
-       pmd_t *pmd; 
-       pte_t large_pte; 
-       
-       pgd = pgd_offset_k(address); 
-       pmd = pmd_offset(pgd, address);
-       BUG_ON(pmd_val(*pmd) & _PAGE_PSE); 
-       pgprot_val(ref_prot) |= _PAGE_PSE;
-       large_pte = mk_pte_phys(__pa(address) & LARGE_PAGE_MASK, ref_prot);
-       set_pte((pte_t *)pmd, large_pte);
+	pgd_t *pgd;
+	pud_t *pud;
+	pmd_t *pmd;
+	pte_t large_pte;
+
+	pgd = pgd_offset_k(address);
+	BUG_ON(pgd_none(*pgd));
+	pud = pud_offset(pgd,address);
+	BUG_ON(pud_none(*pud));
+	pmd = pmd_offset(pud, address);
+	BUG_ON(pmd_val(*pmd) & _PAGE_PSE);
+	pgprot_val(ref_prot) |= _PAGE_PSE;
+	large_pte = mk_pte_phys(__pa(address) & LARGE_PAGE_MASK, ref_prot);
+	set_pte((pte_t *)pmd, large_pte);
 }      
 
 static int
-__change_page_attr(unsigned long address, struct page *page, pgprot_t prot, 
-		   pgprot_t ref_prot)
+__change_page_attr(unsigned long address, unsigned long pfn, pgprot_t prot,
+				   pgprot_t ref_prot)
 { 
 	pte_t *kpte; 
 	struct page *kpte_page;
 	unsigned kpte_flags;
-
 	kpte = lookup_address(address);
 	if (!kpte) return 0;
 	kpte_page = virt_to_page(((unsigned long)kpte) & PAGE_MASK);
 	kpte_flags = pte_val(*kpte); 
 	if (pgprot_val(prot) != pgprot_val(ref_prot)) { 
 		if ((kpte_flags & _PAGE_PSE) == 0) { 
-			pte_t old = *kpte;
-			pte_t standard = mk_pte(page, ref_prot); 
-
-			set_pte(kpte, mk_pte(page, prot)); 
-			if (pte_same(old,standard))
-				get_page(kpte_page);
+			set_pte(kpte, pfn_pte(pfn, prot));
 		} else {
+ 			/*
+ 			 * split_large_page will take the reference for this change_page_attr
+ 			 * on the split page.
+ 			 */
 			struct page *split = split_large_page(address, prot, ref_prot); 
 			if (!split)
 				return -ENOMEM;
-			get_page(kpte_page);
 			set_pte(kpte,mk_pte(split, ref_prot));
+			kpte_page = split;
 		}	
+		get_page(kpte_page);
 	} else if ((kpte_flags & _PAGE_PSE) == 0) { 
-		set_pte(kpte, mk_pte(page, ref_prot));
+		set_pte(kpte, pfn_pte(pfn, ref_prot));
 		__put_page(kpte_page);
-	}
+	} else
+		BUG();
 
-	if (page_count(kpte_page) == 1) {
+	/* on x86-64 the direct mapping set at boot is not using 4k pages */
+ 	BUG_ON(PageReserved(kpte_page));
+
+	switch (page_count(kpte_page)) {
+ 	case 1:
 		save_page(address, kpte_page); 		     
 		revert_page(address, ref_prot);
-	} 
+		break;
+ 	case 0:
+ 		BUG(); /* memleak and failed 2M page regeneration */
+ 	}
 	return 0;
 } 
 
@@ -162,31 +180,39 @@
  * 
  * Caller must call global_flush_tlb() after this.
  */
-int change_page_attr(struct page *page, int numpages, pgprot_t prot)
+int change_page_attr_addr(unsigned long address, int numpages, pgprot_t prot)
 {
 	int err = 0; 
 	int i; 
 
 	down_write(&init_mm.mmap_sem);
-	for (i = 0; i < numpages; !err && i++, page++) { 
-		unsigned long address = (unsigned long)page_address(page); 
-		err = __change_page_attr(address, page, prot, PAGE_KERNEL); 
+	for (i = 0; i < numpages; i++, address += PAGE_SIZE) {
+		unsigned long pfn = __pa(address) >> PAGE_SHIFT;
+
+		err = __change_page_attr(address, pfn, prot, PAGE_KERNEL);
 		if (err) 
 			break; 
 		/* Handle kernel mapping too which aliases part of the
 		 * lowmem */
-		/* Disabled right now. Fixme */ 
-		if (0 && page_to_phys(page) < KERNEL_TEXT_SIZE) {		
+		if (__pa(address) < KERNEL_TEXT_SIZE) {
 			unsigned long addr2;
-			addr2 = __START_KERNEL_map + page_to_phys(page);
-			err = __change_page_attr(addr2, page, prot, 
-						 PAGE_KERNEL_EXEC);
+			pgprot_t prot2 = prot;
+			addr2 = __START_KERNEL_map + __pa(address);
+ 			pgprot_val(prot2) &= ~_PAGE_NX;
+			err = __change_page_attr(addr2, pfn, prot2, PAGE_KERNEL_EXEC);
 		} 
 	} 	
 	up_write(&init_mm.mmap_sem); 
 	return err;
 }
 
+/* Don't call this for MMIO areas that may not have a mem_map entry */
+int change_page_attr(struct page *page, int numpages, pgprot_t prot)
+{
+	unsigned long addr = (unsigned long)page_address(page);
+	return change_page_attr_addr(addr, numpages, prot);
+}
+
 void global_flush_tlb(void)
 { 
 	struct deferred_page *df, *next_df;
@@ -194,6 +220,8 @@
 	down_read(&init_mm.mmap_sem);
 	df = xchg(&df_list, NULL);
 	up_read(&init_mm.mmap_sem);
+	if (!df)
+		return;
 	flush_map((df && !df->next) ? df->address : 0);
 	for (; df; df = next_df) { 
 		next_df = df->next;
diff -Nru a/arch/x86_64/mm/srat.c b/arch/x86_64/mm/srat.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/x86_64/mm/srat.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,217 @@
+/*
+ * ACPI 3.0 based NUMA setup
+ * Copyright 2004 Andi Kleen, SuSE Labs.
+ *
+ * Reads the ACPI SRAT table to figure out what memory belongs to which CPUs.
+ *
+ * Called from acpi_numa_init while reading the SRAT and SLIT tables.
+ * Assumes all memory regions belonging to a single proximity domain
+ * are in one chunk. Holes between them will be included in the node.
+ */
+
+#include <linux/kernel.h>
+#include <linux/acpi.h>
+#include <linux/mmzone.h>
+#include <linux/bitmap.h>
+#include <linux/module.h>
+#include <linux/topology.h>
+#include <asm/proto.h>
+#include <asm/numa.h>
+
+static struct acpi_table_slit *acpi_slit;
+
+static nodemask_t nodes_parsed __initdata;
+static nodemask_t nodes_found __initdata;
+static struct node nodes[MAX_NUMNODES] __initdata;
+static __u8  pxm2node[256] = { [0 ... 255] = 0xff };
+
+static __init int setup_node(int pxm)
+{
+	unsigned node = pxm2node[pxm];
+	if (node == 0xff) {
+		if (nodes_weight(nodes_found) >= MAX_NUMNODES)
+			return -1;
+		node = first_unset_node(nodes_found); 
+		node_set(node, nodes_found);
+		pxm2node[pxm] = node;
+	}
+	return pxm2node[pxm];
+}
+
+static __init int conflicting_nodes(unsigned long start, unsigned long end)
+{
+	int i;
+	for_each_online_node(i) {
+		struct node *nd = &nodes[i];
+		if (nd->start == nd->end)
+			continue;
+		if (nd->end > start && nd->start < end)
+			return 1;
+		if (nd->end == end && nd->start == start)
+			return 1;
+	}
+	return -1;
+}
+
+static __init void cutoff_node(int i, unsigned long start, unsigned long end)
+{
+	struct node *nd = &nodes[i];
+	if (nd->start < start) {
+		nd->start = start;
+		if (nd->end < nd->start)
+			nd->start = nd->end;
+	}
+	if (nd->end > end) {
+		if (!(end & 0xfff))
+			end--;
+		nd->end = end;
+		if (nd->start > nd->end)
+			nd->start = nd->end;
+	}
+}
+
+static __init void bad_srat(void)
+{
+	printk(KERN_ERR "SRAT: SRAT not used.\n");
+	acpi_numa = -1;
+}
+
+static __init inline int srat_disabled(void)
+{
+	return numa_off || acpi_numa < 0;
+}
+
+/* Callback for SLIT parsing */
+void __init acpi_numa_slit_init(struct acpi_table_slit *slit)
+{
+	acpi_slit = slit;
+}
+
+/* Callback for Proximity Domain -> LAPIC mapping */
+void __init
+acpi_numa_processor_affinity_init(struct acpi_table_processor_affinity *pa)
+{
+	int pxm, node;
+	if (srat_disabled() || pa->flags.enabled == 0)
+		return;
+	pxm = pa->proximity_domain;
+	node = setup_node(pxm);
+	if (node < 0) {
+		printk(KERN_ERR "SRAT: Too many proximity domains %x\n", pxm);
+		bad_srat();
+		return;
+	}
+	if (pa->apic_id >= NR_CPUS) {
+		printk(KERN_ERR "SRAT: lapic %u too large.\n",
+		       pa->apic_id);
+		bad_srat();
+		return;
+	}
+	cpu_to_node[pa->apic_id] = node;
+	acpi_numa = 1;
+	printk(KERN_INFO "SRAT: PXM %u -> APIC %u -> Node %u\n",
+	       pxm, pa->apic_id, node);
+}
+
+/* Callback for parsing of the Proximity Domain <-> Memory Area mappings */
+void __init
+acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma)
+{
+	struct node *nd;
+	unsigned long start, end;
+	int node, pxm;
+	int i;
+
+	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) {
+		printk(KERN_ERR "SRAT: Too many proximity domains.\n");
+		bad_srat();
+		return;
+	}
+	start = ma->base_addr_lo | ((u64)ma->base_addr_hi << 32);
+	end = start + (ma->length_lo | ((u64)ma->length_hi << 32));
+	i = conflicting_nodes(start, end);
+	if (i >= 0) {
+		printk(KERN_ERR
+		       "SRAT: pxm %d overlap %lx-%lx with node %d(%Lx-%Lx)\n",
+		       pxm, start, end, i, nodes[i].start, nodes[i].end);
+		bad_srat();
+		return;
+	}
+	nd = &nodes[node];
+	if (!node_test_and_set(node, nodes_parsed)) {
+		nd->start = start;
+		nd->end = end;
+	} else {
+		if (start < nd->start)
+			nd->start = start;
+		if (nd->end < end)
+			nd->end = end;
+	}
+	if (!(nd->end & 0xfff))
+		nd->end--;
+	printk(KERN_INFO "SRAT: Node %u PXM %u %Lx-%Lx\n", node, pxm,
+	       nd->start, nd->end);
+}
+
+void __init acpi_numa_arch_fixup(void) {}
+
+/* Use the information discovered above to actually set up the nodes. */
+int __init acpi_scan_nodes(unsigned long start, unsigned long end)
+{
+	int i;
+	if (acpi_numa <= 0)
+		return -1;
+	memnode_shift = compute_hash_shift(nodes, nodes_weight(nodes_parsed));
+	if (memnode_shift < 0) {
+		printk(KERN_ERR
+		     "SRAT: No NUMA node hash function found. Contact maintainer\n");
+		bad_srat();
+		return -1;
+	}
+	for (i = 0; i < MAX_NUMNODES; i++) {
+		if (!node_isset(i, nodes_parsed))
+			continue;
+		cutoff_node(i, start, end);
+		if (nodes[i].start == nodes[i].end) { 
+			node_clear(i, nodes_parsed);
+			continue;
+		}
+		setup_node_bootmem(i, nodes[i].start, nodes[i].end);
+	}
+	for (i = 0; i < NR_CPUS; i++) { 
+		if (cpu_to_node[i] == NUMA_NO_NODE)
+			continue;
+		if (!node_isset(cpu_to_node[i], nodes_parsed))
+			cpu_to_node[i] = NUMA_NO_NODE; 
+	}
+	numa_init_array();
+	return 0;
+}
+
+int node_to_pxm(int n)
+{
+       int i;
+       if (pxm2node[n] == n)
+               return n;
+       for (i = 0; i < 256; i++)
+               if (pxm2node[i] == n)
+                       return i;
+       return 0;
+}
+
+int __node_distance(int a, int b)
+{
+	int index;
+
+	if (!acpi_slit)
+		return a == b ? 10 : 20;
+	index = acpi_slit->localities * node_to_pxm(a);
+	return acpi_slit->entry[index + node_to_pxm(b)];
+}
+
+EXPORT_SYMBOL(__node_distance);
diff -Nru a/arch/x86_64/oprofile/Makefile b/arch/x86_64/oprofile/Makefile
--- a/arch/x86_64/oprofile/Makefile	2005-03-01 23:38:53 -08:00
+++ b/arch/x86_64/oprofile/Makefile	2005-03-01 23:38:53 -08:00
@@ -11,7 +11,7 @@
 	oprofilefs.o oprofile_stats.o \
 	timer_int.o )
 
-OPROFILE-y := init.o
+OPROFILE-y := init.o backtrace.o
 OPROFILE-$(CONFIG_X86_LOCAL_APIC) += nmi_int.o op_model_athlon.o op_model_p4.o \
 				     op_model_ppro.o
 OPROFILE-$(CONFIG_X86_IO_APIC)    += nmi_timer_int.o 
diff -Nru a/crypto/Kconfig b/crypto/Kconfig
--- a/crypto/Kconfig	2005-03-01 23:39:16 -08:00
+++ b/crypto/Kconfig	2005-03-01 23:39:16 -08:00
@@ -77,7 +77,7 @@
 	  Whirlpool will be part of the ISO/IEC 10118-3:2003(E) standard
 
 	  See also:
-	  http://planeta.terra.com.br/informatica/paulobarreto/WhirlpoolPage.html
+	  <http://planeta.terra.com.br/informatica/paulobarreto/WhirlpoolPage.html>
 
 config CRYPTO_DES
 	tristate "DES and Triple DES EDE cipher algorithms"
@@ -102,7 +102,7 @@
 	  designed for use on "large microprocessors".
 	  
 	  See also:
-	  http://www.schneier.com/blowfish.html
+	  <http://www.schneier.com/blowfish.html>
 
 config CRYPTO_TWOFISH
 	tristate "Twofish cipher algorithm"
@@ -116,7 +116,7 @@
 	  bits.
 	  
 	  See also:
-	  http://www.schneier.com/twofish.html
+	  <http://www.schneier.com/twofish.html>
 
 config CRYPTO_SERPENT
 	tristate "Serpent cipher algorithm"
@@ -129,7 +129,7 @@
 	  variant of Serpent for compatibility with old kerneli code.
 
 	  See also:
-	  http://www.cl.cam.ac.uk/~rja14/serpent.html
+	  <http://www.cl.cam.ac.uk/~rja14/serpent.html>
 
 config CRYPTO_AES
 	tristate "AES cipher algorithms"
@@ -149,7 +149,7 @@
 
 	  The AES specifies three key sizes: 128, 192 and 256 bits	  
 
-	  See http://csrc.nist.gov/CryptoToolkit/aes/ for more information.
+	  See <http://csrc.nist.gov/CryptoToolkit/aes/> for more information.
 
 config CRYPTO_AES_586
 	tristate "AES cipher algorithms (i586)"
@@ -169,7 +169,7 @@
 
 	  The AES specifies three key sizes: 128, 192 and 256 bits	  
 
-	  See http://csrc.nist.gov/encryption/aes/ for more information.
+	  See <http://csrc.nist.gov/encryption/aes/> for more information.
 
 config CRYPTO_CAST5
 	tristate "CAST5 (CAST-128) cipher algorithm"
@@ -221,7 +221,7 @@
 	  on 32-bit processors.  Khazad uses an 128 bit key size.
 
 	  See also:
-	  http://planeta.terra.com.br/informatica/paulobarreto/KhazadPage.html
+	  <http://planeta.terra.com.br/informatica/paulobarreto/KhazadPage.html>
 
 config CRYPTO_ANUBIS
 	tristate "Anubis cipher algorithm"
@@ -234,8 +234,8 @@
 	  in the NESSIE competition.
 	  
 	  See also:
-	  https://www.cosic.esat.kuleuven.ac.be/nessie/reports/
-	  http://planeta.terra.com.br/informatica/paulobarreto/AnubisPage.html
+	  <https://www.cosic.esat.kuleuven.ac.be/nessie/reports/>
+	  <http://planeta.terra.com.br/informatica/paulobarreto/AnubisPage.html>
 
 
 config CRYPTO_DEFLATE
@@ -274,5 +274,6 @@
 	help
 	  Quick & dirty crypto test module.
 
+source "drivers/crypto/Kconfig"
 endmenu
 
diff -Nru a/crypto/sha512.c b/crypto/sha512.c
--- a/crypto/sha512.c	2005-03-01 23:39:16 -08:00
+++ b/crypto/sha512.c	2005-03-01 23:39:16 -08:00
@@ -48,7 +48,7 @@
         return (x >> y) | (x << (64 - y));
 }
 
-const u64 sha512_K[80] = {
+static const u64 sha512_K[80] = {
         0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL,
         0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
         0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL,
diff -Nru a/crypto/tcrypt.c b/crypto/tcrypt.c
--- a/crypto/tcrypt.c	2005-03-01 23:39:09 -08:00
+++ b/crypto/tcrypt.c	2005-03-01 23:39:09 -08:00
@@ -255,7 +255,7 @@
 
 #endif	/* CONFIG_CRYPTO_HMAC */
 
-void
+static void
 test_cipher(char * algo, int mode, int enc, struct cipher_testvec * template, unsigned int tcount)
 {
 	unsigned int ret, i, j, k, temp;
diff -Nru a/crypto/tcrypt.h b/crypto/tcrypt.h
--- a/crypto/tcrypt.h	2005-03-01 23:39:16 -08:00
+++ b/crypto/tcrypt.h	2005-03-01 23:39:16 -08:00
@@ -63,7 +63,7 @@
  */
 #define MD4_TEST_VECTORS	7
 
-struct hash_testvec md4_tv_template [] = {
+static struct hash_testvec md4_tv_template [] = {
 	{
 		.plaintext = "",
 		.digest	= { 0x31, 0xd6, 0xcf, 0xe0, 0xd1, 0x6a, 0xe9, 0x31,
@@ -109,7 +109,7 @@
  */
 #define MD5_TEST_VECTORS	7
 
-struct hash_testvec md5_tv_template[] = {
+static struct hash_testvec md5_tv_template[] = {
 	{
 		.digest	= { 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04,
 			    0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e },
@@ -154,7 +154,7 @@
  */
 #define SHA1_TEST_VECTORS	2
 
-struct hash_testvec sha1_tv_template[] = {
+static struct hash_testvec sha1_tv_template[] = {
 	{ 
 		.plaintext = "abc",
 		.psize	= 3,
@@ -175,7 +175,7 @@
  */
 #define SHA256_TEST_VECTORS	2
 
-struct hash_testvec sha256_tv_template[] = {	
+static struct hash_testvec sha256_tv_template[] = {	
 	{ 
 		.plaintext = "abc",
 		.psize	= 3,
@@ -200,7 +200,7 @@
  */
 #define SHA384_TEST_VECTORS	4
 
-struct hash_testvec sha384_tv_template[] = {
+static struct hash_testvec sha384_tv_template[] = {
 	{ 
 		.plaintext= "abc",
 		.psize	= 3,
@@ -249,7 +249,7 @@
  */
 #define SHA512_TEST_VECTORS	4
 
-struct hash_testvec sha512_tv_template[] = {
+static struct hash_testvec sha512_tv_template[] = {
 	{ 
 		.plaintext = "abc",
 		.psize	= 3,
@@ -309,7 +309,7 @@
  */
 #define WP512_TEST_VECTORS	8
 
-struct hash_testvec wp512_tv_template[] = {
+static struct hash_testvec wp512_tv_template[] = {
 	{ 
 		.plaintext = "",
 		.psize	= 0,
@@ -407,7 +407,7 @@
 
 #define WP384_TEST_VECTORS	8
 
-struct hash_testvec wp384_tv_template[] = {
+static struct hash_testvec wp384_tv_template[] = {
 	{ 
 		.plaintext = "",
 		.psize	= 0,
@@ -489,7 +489,7 @@
 
 #define WP256_TEST_VECTORS	8
 
-struct hash_testvec wp256_tv_template[] = {
+static struct hash_testvec wp256_tv_template[] = {
 	{ 
 		.plaintext = "",
 		.psize	= 0,
@@ -561,7 +561,7 @@
  */
 #define HMAC_MD5_TEST_VECTORS	7
 
-struct hmac_testvec hmac_md5_tv_template[] =
+static struct hmac_testvec hmac_md5_tv_template[] =
 {	
 	{
 		.key	= { [0 ... 15] =  0x0b },
@@ -625,7 +625,7 @@
  */
 #define HMAC_SHA1_TEST_VECTORS	7
 
-struct hmac_testvec hmac_sha1_tv_template[] = {	
+static struct hmac_testvec hmac_sha1_tv_template[] = {	
 	{
 		.key	= { [0 ... 19] = 0x0b },
 		.ksize	= 20,
@@ -690,7 +690,7 @@
  */
 #define HMAC_SHA256_TEST_VECTORS	10
 
-struct hmac_testvec hmac_sha256_tv_template[] = {
+static struct hmac_testvec hmac_sha256_tv_template[] = {
 	{
 		.key	= { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
 			    0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
@@ -813,7 +813,7 @@
 #define DES3_EDE_ENC_TEST_VECTORS	3
 #define DES3_EDE_DEC_TEST_VECTORS	3
 
-struct cipher_testvec des_enc_tv_template[] = {
+static struct cipher_testvec des_enc_tv_template[] = {
 	{ /* From Applied Cryptography */
 		.key	= { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
 		.klen	= 8,
@@ -917,7 +917,7 @@
 	},
 };
 
-struct cipher_testvec des_dec_tv_template[] = {
+static struct cipher_testvec des_dec_tv_template[] = {
 	{ /* From Applied Cryptography */
 		.key	= { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
 		.klen	= 8,
@@ -957,7 +957,7 @@
 	},
 };
 
-struct cipher_testvec des_cbc_enc_tv_template[] = {
+static struct cipher_testvec des_cbc_enc_tv_template[] = {
 	{ /* From OpenSSL */
 		.key	= { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef},
 		.klen	= 8,
@@ -1012,7 +1012,7 @@
 	},
 };
 
-struct cipher_testvec des_cbc_dec_tv_template[] = {
+static struct cipher_testvec des_cbc_dec_tv_template[] = {
 	{ /* FIPS Pub 81 */
 		.key	= { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
 		.klen	= 8,
@@ -1053,7 +1053,7 @@
 /*
  * We really need some more test vectors, especially for DES3 CBC.
  */
-struct cipher_testvec des3_ede_enc_tv_template[] = {
+static struct cipher_testvec des3_ede_enc_tv_template[] = {
 	{ /* These are from openssl */
 		.key	= { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
 			    0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
@@ -1084,7 +1084,7 @@
 	},
 };
 
-struct cipher_testvec des3_ede_dec_tv_template[] = {
+static struct cipher_testvec des3_ede_dec_tv_template[] = {
 	{ /* These are from openssl */
 		.key	= { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
 			    0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
@@ -1123,7 +1123,7 @@
 #define BF_CBC_ENC_TEST_VECTORS	1
 #define BF_CBC_DEC_TEST_VECTORS	1
 
-struct cipher_testvec bf_enc_tv_template[] = {
+static struct cipher_testvec bf_enc_tv_template[] = {
 	{ /* DES test vectors from OpenSSL */
 		.key	= { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
 		.klen	= 8,
@@ -1178,7 +1178,7 @@
 	},
 };
 
-struct cipher_testvec bf_dec_tv_template[] = {
+static struct cipher_testvec bf_dec_tv_template[] = {
 	{ /* DES test vectors from OpenSSL */
 		.key	= { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
 		.klen	= 8,
@@ -1233,7 +1233,7 @@
 	},
 };
 
-struct cipher_testvec bf_cbc_enc_tv_template[] = {
+static struct cipher_testvec bf_cbc_enc_tv_template[] = {
 	{ /* From OpenSSL */
 		.key	= { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
 			    0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87 },
@@ -1252,7 +1252,7 @@
 	},
 };
 
-struct cipher_testvec bf_cbc_dec_tv_template[] = {
+static struct cipher_testvec bf_cbc_dec_tv_template[] = {
 	{ /* From OpenSSL */
 		.key	= { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
 			    0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87 },
@@ -1279,7 +1279,7 @@
 #define TF_CBC_ENC_TEST_VECTORS		4
 #define TF_CBC_DEC_TEST_VECTORS		4
 
-struct cipher_testvec tf_enc_tv_template[] = {
+static struct cipher_testvec tf_enc_tv_template[] = {
 	{
 		.key	= { [0 ... 15] = 0x00 },
 		.klen	= 16,
@@ -1312,7 +1312,7 @@
 	},
 };
 
-struct cipher_testvec tf_dec_tv_template[] = {
+static struct cipher_testvec tf_dec_tv_template[] = {
 	{
 		.key	= { [0 ... 15] = 0x00 },
 		.klen	= 16,
@@ -1345,7 +1345,7 @@
 	},
 };
 
-struct cipher_testvec tf_cbc_enc_tv_template[] = {
+static struct cipher_testvec tf_cbc_enc_tv_template[] = {
 	{ /* Generated with Nettle */
 		.key	= { [0 ... 15] = 0x00 },
 		.klen	= 16,
@@ -1391,7 +1391,7 @@
 	},
 };
 
-struct cipher_testvec tf_cbc_dec_tv_template[] = {
+static struct cipher_testvec tf_cbc_dec_tv_template[] = {
 	{ /* Reverse of the first four above */
 		.key	= { [0 ... 15] = 0x00 },
 		.klen	= 16,
@@ -1447,7 +1447,7 @@
 #define TNEPRES_ENC_TEST_VECTORS	4
 #define TNEPRES_DEC_TEST_VECTORS	4
 
-struct cipher_testvec serpent_enc_tv_template[] = 
+static struct cipher_testvec serpent_enc_tv_template[] = 
 {
 	{
 		.input	= { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
@@ -1489,7 +1489,7 @@
 	},
 };
 
-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,
@@ -1540,7 +1540,7 @@
 };
 
 
-struct cipher_testvec serpent_dec_tv_template[] = 
+static struct cipher_testvec serpent_dec_tv_template[] = 
 {
 	{
 		.input	= { 0x12, 0x07, 0xfc, 0xce, 0x9b, 0xd0, 0xd6, 0x47,
@@ -1582,7 +1582,7 @@
 	},
 };
 
-struct cipher_testvec tnepres_dec_tv_template[] =
+static struct cipher_testvec tnepres_dec_tv_template[] =
 {
 	{
 		.input	= { 0x41, 0xcc, 0x6b, 0x31, 0x59, 0x31, 0x45, 0x97,
@@ -1629,7 +1629,7 @@
 #define CAST6_ENC_TEST_VECTORS	3
 #define CAST6_DEC_TEST_VECTORS  3
 
-struct cipher_testvec cast6_enc_tv_template[] = 
+static struct cipher_testvec cast6_enc_tv_template[] = 
 {
 	{
 		.key	= { 0x23, 0x42, 0xbb, 0x9e, 0xfa, 0x38, 0x54, 0x2c, 
@@ -1664,7 +1664,7 @@
 	},
 };
 
-struct cipher_testvec cast6_dec_tv_template[] = 
+static struct cipher_testvec cast6_dec_tv_template[] = 
 {
 	{
 		.key	= { 0x23, 0x42, 0xbb, 0x9e, 0xfa, 0x38, 0x54, 0x2c, 
@@ -1706,7 +1706,7 @@
 #define AES_ENC_TEST_VECTORS 3
 #define AES_DEC_TEST_VECTORS 3
 
-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, 
 			    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
@@ -1743,7 +1743,7 @@
 	},
 };
 
-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, 
 			    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
@@ -1784,7 +1784,7 @@
 #define CAST5_ENC_TEST_VECTORS	3
 #define CAST5_DEC_TEST_VECTORS	3
 
-struct cipher_testvec cast5_enc_tv_template[] =
+static struct cipher_testvec cast5_enc_tv_template[] =
 {
 	{
 		.key	= { 0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78,
@@ -1812,7 +1812,7 @@
 	},
 };
 
-struct cipher_testvec cast5_dec_tv_template[] =
+static struct cipher_testvec cast5_dec_tv_template[] =
 {
 	{
 		.key	= { 0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78,
@@ -1846,7 +1846,7 @@
 #define ARC4_ENC_TEST_VECTORS	7
 #define ARC4_DEC_TEST_VECTORS	7
 
-struct cipher_testvec arc4_enc_tv_template[] =
+static struct cipher_testvec arc4_enc_tv_template[] =
 {
 	{
 		.key	= { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
@@ -1913,7 +1913,7 @@
 	},
 };
 
-struct cipher_testvec arc4_dec_tv_template[] =
+static struct cipher_testvec arc4_dec_tv_template[] =
 {
 	{
 		.key	= { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
@@ -1986,7 +1986,7 @@
 #define TEA_ENC_TEST_VECTORS	4
 #define TEA_DEC_TEST_VECTORS	4
 
-struct cipher_testvec tea_enc_tv_template[] =
+static struct cipher_testvec tea_enc_tv_template[] =
 {
 	{
 		.key    = { [0 ... 15] = 0x00 },
@@ -2030,7 +2030,7 @@
 	}
 };
 
-struct cipher_testvec tea_dec_tv_template[] =
+static struct cipher_testvec tea_dec_tv_template[] =
 {
 	{
 		.key    = { [0 ... 15] = 0x00 },
@@ -2080,7 +2080,7 @@
 #define XTEA_ENC_TEST_VECTORS	4
 #define XTEA_DEC_TEST_VECTORS	4
 
-struct cipher_testvec xtea_enc_tv_template[] =
+static struct cipher_testvec xtea_enc_tv_template[] =
 {
 	{
 		.key    = { [0 ... 15] = 0x00 },
@@ -2124,7 +2124,7 @@
 	}
 };
 
-struct cipher_testvec xtea_dec_tv_template[] =
+static struct cipher_testvec xtea_dec_tv_template[] =
 {
 	{
 		.key    = { [0 ... 15] = 0x00 },
@@ -2174,7 +2174,7 @@
 #define KHAZAD_ENC_TEST_VECTORS 5
 #define KHAZAD_DEC_TEST_VECTORS 5
 
-struct cipher_testvec khazad_enc_tv_template[] = { 
+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 },
@@ -2220,7 +2220,7 @@
 	},
 };
 
-struct cipher_testvec khazad_dec_tv_template[] = { 
+static struct cipher_testvec khazad_dec_tv_template[] = { 
 	{
 		.key	= { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
 			    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
@@ -2275,7 +2275,7 @@
 #define ANUBIS_CBC_ENC_TEST_VECTORS		2
 #define ANUBIS_CBC_DEC_TEST_VECTORS		2
 
-struct cipher_testvec anubis_enc_tv_template[] = {
+static struct cipher_testvec anubis_enc_tv_template[] = {
 	{
 		.key	= { 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
 			    0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe },
@@ -2338,7 +2338,7 @@
 	},
 };
 
-struct cipher_testvec anubis_dec_tv_template[] = {
+static struct cipher_testvec anubis_dec_tv_template[] = {
 	{
 		.key	= { 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
 			    0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe },
@@ -2401,7 +2401,7 @@
 	},
 };
 
-struct cipher_testvec anubis_cbc_enc_tv_template[] = {
+static struct cipher_testvec anubis_cbc_enc_tv_template[] = {
 	{
 		.key	= { 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
 			    0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe },
@@ -2436,7 +2436,7 @@
 	},
 };
 
-struct cipher_testvec anubis_cbc_dec_tv_template[] = {
+static struct cipher_testvec anubis_cbc_dec_tv_template[] = {
 	{
 		.key	= { 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
 			    0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe },
@@ -2489,7 +2489,7 @@
 #define DEFLATE_COMP_TEST_VECTORS 2
 #define DEFLATE_DECOMP_TEST_VECTORS 2
 
-struct comp_testvec deflate_comp_tv_template[] = {
+static struct comp_testvec deflate_comp_tv_template[] = {
 	{
 		.inlen	= 70,
 		.outlen	= 38,
@@ -2525,7 +2525,7 @@
 	},
 };
 
-struct comp_testvec deflate_decomp_tv_template[] = {
+static struct comp_testvec deflate_decomp_tv_template[] = {
 	{
 		.inlen	= 122,
 		.outlen	= 191,
@@ -2566,7 +2566,7 @@
  */
 #define MICHAEL_MIC_TEST_VECTORS 6
 
-struct hash_testvec michael_mic_tv_template[] =
+static struct hash_testvec michael_mic_tv_template[] =
 {
 	{
 		.key = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
diff -Nru a/drivers/Kconfig b/drivers/Kconfig
--- a/drivers/Kconfig	2005-03-01 23:39:16 -08:00
+++ b/drivers/Kconfig	2005-03-01 23:39:16 -08:00
@@ -56,4 +56,6 @@
 
 source "drivers/mmc/Kconfig"
 
+source "drivers/infiniband/Kconfig"
+
 endmenu
diff -Nru a/drivers/Makefile b/drivers/Makefile
--- a/drivers/Makefile	2005-03-01 23:39:18 -08:00
+++ b/drivers/Makefile	2005-03-01 23:39:18 -08:00
@@ -42,6 +42,7 @@
 obj-$(CONFIG_SBUS)		+= sbus/
 obj-$(CONFIG_ZORRO)		+= zorro/
 obj-$(CONFIG_MAC)		+= macintosh/
+obj-$(CONFIG_ATA_OVER_ETH)	+= block/aoe/
 obj-$(CONFIG_PARIDE) 		+= block/paride/
 obj-$(CONFIG_TC)		+= tc/
 obj-$(CONFIG_USB)		+= usb/
@@ -59,4 +60,6 @@
 obj-$(CONFIG_EISA)		+= eisa/
 obj-$(CONFIG_CPU_FREQ)		+= cpufreq/
 obj-$(CONFIG_MMC)		+= mmc/
+obj-$(CONFIG_INFINIBAND)	+= infiniband/
 obj-y				+= firmware/
+obj-$(CONFIG_CRYPTO)		+= crypto/
diff -Nru a/drivers/acorn/block/fd1772.c b/drivers/acorn/block/fd1772.c
--- a/drivers/acorn/block/fd1772.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/acorn/block/fd1772.c	2005-03-01 23:38:55 -08:00
@@ -1522,7 +1522,7 @@
 
 int fd1772_init(void)
 {
-	static spinlock_t lock = SPIN_LOCK_UNLOCKED;
+	static DEFINE_SPINLOCK(lock);
 	int i, err = -ENOMEM;
 
 	if (!machine_is_archimedes())
diff -Nru a/drivers/acorn/block/mfmhd.c b/drivers/acorn/block/mfmhd.c
--- a/drivers/acorn/block/mfmhd.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/acorn/block/mfmhd.c	2005-03-01 23:38:53 -08:00
@@ -124,7 +124,7 @@
 
 static void (*do_mfm)(void) = NULL;
 static struct request_queue *mfm_queue;
-static spinlock_t mfm_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(mfm_lock);
 
 #define MAJOR_NR	MFM_ACORN_MAJOR
 #define QUEUE (mfm_queue)
diff -Nru a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
--- a/drivers/acpi/Kconfig	2005-03-01 23:39:17 -08:00
+++ b/drivers/acpi/Kconfig	2005-03-01 23:39:17 -08:00
@@ -20,7 +20,7 @@
 	  kernel by about 70K.
 
 	  Linux ACPI provides a robust functional replacement for several 
-	  legacy configuration and power management intefaces, including 
+	  legacy configuration and power management interfaces, including
 	  the Plug-and-Play BIOS specification (PnP BIOS), the 
 	  MultiProcessor Specification (MPS), and the Advanced Power 
 	  Management (APM) specification.  If both ACPI and APM support 
@@ -144,6 +144,15 @@
 	  ACPI C2 and C3 processor states to save power, on systems that
 	  support it.
 
+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---
+	 Select this option if your platform support physical CPU hotplug.
+
 config ACPI_THERMAL
 	tristate "Thermal Zone"
 	depends on ACPI_PROCESSOR
@@ -158,7 +167,7 @@
 	bool "NUMA support"
 	depends on ACPI_INTERPRETER
 	depends on NUMA
-	depends on IA64
+	depends on (IA64 || X86_64)
 	default y if IA64_GENERIC || IA64_SGI_SN2
 
 config ACPI_ASUS
@@ -200,8 +209,8 @@
 	  This is a Linux ACPI driver for the IBM ThinkPad laptops. It adds
 	  support for Fn-Fx key combinations, Bluetooth control, video
 	  output switching, ThinkLight control, UltraBay eject and more.
-	  For more information about this driver see Documentation/ibm-acpi.txt
-	  and http://ibm-acpi.sf.net/ .
+	  For more information about this driver see <file:Documentation/ibm-acpi.txt>
+	  and <http://ibm-acpi.sf.net/> .
 
 	  If you have an IBM ThinkPad laptop, say Y or M here.
 
@@ -250,6 +259,7 @@
 
 config ACPI_BLACKLIST_YEAR
 	int "Disable ACPI for systems before Jan 1st this year"
+	depends on ACPI_INTERPRETER
 	default 0
 	help
 	  enter a 4-digit year, eg. 2001 to disable ACPI by default
@@ -325,5 +335,12 @@
 	  kernel logs, and/or you are using this on a notebook which
 	  does not yet have an HPET, you should say "Y" here.
 
-endmenu
+config ACPI_CONTAINER
+	tristate "ACPI0004,PNP0A05 and PNP0A06 Container Driver (EXPERIMENTAL)"
+	depends on ACPI && 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
 
+endmenu
diff -Nru a/drivers/acpi/Makefile b/drivers/acpi/Makefile
--- a/drivers/acpi/Makefile	2005-03-01 23:39:16 -08:00
+++ b/drivers/acpi/Makefile	2005-03-01 23:39:16 -08:00
@@ -29,6 +29,12 @@
 #
 # ACPI Bus and Device Drivers
 #
+processor-objs	+= processor_core.o processor_throttling.o \
+				processor_idle.o processor_thermal.o
+ifdef CONFIG_CPU_FREQ
+processor-objs	+= processor_perflib.o			
+endif
+
 obj-$(CONFIG_ACPI_BUS)		+= sleep/
 obj-$(CONFIG_ACPI_BUS)		+= bus.o
 obj-$(CONFIG_ACPI_AC) 		+= ac.o
@@ -40,6 +46,7 @@
 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
+obj-$(CONFIG_ACPI_CONTAINER)	+= container.o
 obj-$(CONFIG_ACPI_THERMAL)	+= thermal.o
 obj-$(CONFIG_ACPI_SYSTEM)	+= system.o event.o
 obj-$(CONFIG_ACPI_DEBUG)	+= debug.o
diff -Nru a/drivers/acpi/asus_acpi.c b/drivers/acpi/asus_acpi.c
--- a/drivers/acpi/asus_acpi.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/acpi/asus_acpi.c	2005-03-01 23:38:54 -08:00
@@ -78,9 +78,9 @@
 
 static uid_t asus_uid;
 static gid_t asus_gid;
-MODULE_PARM(asus_uid, "i");
+module_param(asus_uid, uint, 0);
 MODULE_PARM_DESC(uid, "UID for entries in /proc/acpi/asus.\n");
-MODULE_PARM(asus_gid, "i");
+module_param(asus_gid, uint, 0);
 MODULE_PARM_DESC(gid, "GID for entries in /proc/acpi/asus.\n");
 
 
@@ -866,7 +866,7 @@
 
 	acpi_device_dir(device) = asus_proc_dir;
 	if (!acpi_device_dir(device))
-		return(-ENODEV);
+		return -ENODEV;
 
 	proc = create_proc_entry(PROC_INFO, mode, acpi_device_dir(device));
 	if (proc) {
@@ -1098,16 +1098,16 @@
 
 	result = acpi_bus_get_status(hotk->device);
 	if (result)
-		return(result);
+		return result;
 
 	if (hotk->device->status.present) {
 		result = asus_hotk_get_info();
 	} else {
 		printk(KERN_ERR "  Hotkey device not present, aborting\n");
-		return(-EINVAL);
+		return -EINVAL;
 	}
 
-	return(result);
+	return result;
 }
 
 
@@ -1117,7 +1117,7 @@
 	int result;
 
 	if (!device)
-		return(-EINVAL);
+		return -EINVAL;
 
 	printk(KERN_NOTICE "Asus Laptop ACPI Extras version %s\n",
 	       ASUS_ACPI_VERSION);
@@ -1125,7 +1125,7 @@
 	hotk =
 	    (struct asus_hotk *) kmalloc(sizeof(struct asus_hotk), GFP_KERNEL);
 	if (!hotk)
-		return(-ENOMEM);
+		return -ENOMEM;
 	memset(hotk, 0, sizeof(struct asus_hotk));
 
 	hotk->handle = device->handle;
@@ -1173,7 +1173,7 @@
 		kfree(hotk);
 	}
 
-	return(result);
+	return result;
 }
 
 
@@ -1182,7 +1182,7 @@
 	acpi_status status = 0;
 
 	if (!device || !acpi_driver_data(device))
-		return(-EINVAL);
+		return -EINVAL;
 
 	status = acpi_remove_notify_handler(hotk->handle, ACPI_SYSTEM_NOTIFY,
 					    asus_hotk_notify);
@@ -1193,7 +1193,7 @@
 
 	kfree(hotk);
 
-	return(0);
+	return 0;
 }
 
 
diff -Nru a/drivers/acpi/bus.c b/drivers/acpi/bus.c
--- a/drivers/acpi/bus.c	2005-03-01 23:38:59 -08:00
+++ b/drivers/acpi/bus.c	2005-03-01 23:38:59 -08:00
@@ -57,10 +57,6 @@
                                 Device Management
    -------------------------------------------------------------------------- */
 
-extern void acpi_bus_data_handler (
-	acpi_handle		handle,
-	u32			function,
-	void			*context);
 int
 acpi_bus_get_device (
 	acpi_handle		handle,
@@ -77,7 +73,7 @@
 
 	status = acpi_get_data(handle, acpi_bus_data_handler, (void**) device);
 	if (ACPI_FAILURE(status) || !*device) {
-		ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Error getting context for object [%p]\n",
+		ACPI_DEBUG_PRINT((ACPI_DB_WARN, "No context for object [%p]\n",
 			handle));
 		return_VALUE(-ENODEV);
 	}
@@ -285,7 +281,7 @@
                                 Event Management
    -------------------------------------------------------------------------- */
 
-static spinlock_t		acpi_bus_event_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(acpi_bus_event_lock);
 
 LIST_HEAD(acpi_bus_event_list);
 DECLARE_WAIT_QUEUE_HEAD(acpi_bus_event_queue);
diff -Nru a/drivers/acpi/container.c b/drivers/acpi/container.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/acpi/container.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,298 @@
+/*
+ * acpi_container.c  - ACPI Generic Container Driver
+ * ($Revision: )
+ *
+ * Copyright (C) 2004 Anil S Keshavamurthy (anil.s.keshavamurthy@intel.com)
+ * Copyright (C) 2004 Keiichiro Tokunaga (tokunaga.keiich@jp.fujitsu.com)
+ * Copyright (C) 2004 Motoyuki Ito (motoyuki@soft.fujitsu.com)
+ * Copyright (C) 2004 Intel Corp.
+ * Copyright (C) 2004 FUJITSU LIMITED
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or (at
+ *  your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ *  You 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/acpi.h>
+#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
+#include <acpi/container.h>
+
+#define ACPI_CONTAINER_DRIVER_NAME	"ACPI container driver"
+#define ACPI_CONTAINER_DEVICE_NAME	"ACPI container device"
+#define ACPI_CONTAINER_CLASS		"container"
+
+#define INSTALL_NOTIFY_HANDLER		1
+#define UNINSTALL_NOTIFY_HANDLER	2
+
+#define ACPI_CONTAINER_COMPONENT	0x01000000
+#define _COMPONENT			ACPI_CONTAINER_COMPONENT
+ACPI_MODULE_NAME			("acpi_container")
+
+MODULE_AUTHOR("Anil S Keshavamurthy");
+MODULE_DESCRIPTION(ACPI_CONTAINER_DRIVER_NAME);
+MODULE_LICENSE("GPL");
+
+#define ACPI_STA_PRESENT		(0x00000001)
+
+static int acpi_container_add(struct acpi_device *device);
+static int acpi_container_remove(struct acpi_device *device, int type);
+
+static struct acpi_driver acpi_container_driver = {
+	.name =		ACPI_CONTAINER_DRIVER_NAME,
+	.class =	ACPI_CONTAINER_CLASS,
+	.ids =		"ACPI0004,PNP0A05,PNP0A06",
+	.ops =		{
+				.add =		acpi_container_add,
+				.remove =	acpi_container_remove,
+			},
+};
+
+
+/*******************************************************************/
+
+static int
+is_device_present(acpi_handle handle)
+{
+	acpi_handle		temp;
+	acpi_status		status;
+	unsigned long	sta;
+
+	ACPI_FUNCTION_TRACE("is_device_present");
+
+	status = acpi_get_handle(handle, "_STA", &temp);
+	if (ACPI_FAILURE(status))
+		return_VALUE(1); /* _STA not found, assmue device present */
+
+	status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
+	if (ACPI_FAILURE(status))
+		return_VALUE(0); /* Firmware error */
+
+	return_VALUE((sta & ACPI_STA_PRESENT) == ACPI_STA_PRESENT);
+}
+
+/*******************************************************************/
+static int
+acpi_container_add(struct acpi_device *device)
+{
+	struct acpi_container *container;
+
+	ACPI_FUNCTION_TRACE("acpi_container_add");
+
+	if (!device) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "device is NULL\n"));
+		return_VALUE(-EINVAL);
+	}
+
+	container = kmalloc(sizeof(struct acpi_container), GFP_KERNEL);
+	if(!container)
+		return_VALUE(-ENOMEM);
+	
+	memset(container, 0, sizeof(struct acpi_container));
+	container->handle = device->handle;
+	strcpy(acpi_device_name(device), ACPI_CONTAINER_DEVICE_NAME);
+	strcpy(acpi_device_class(device), ACPI_CONTAINER_CLASS);
+	acpi_driver_data(device) = container;
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device <%s> bid <%s>\n",	\
+		acpi_device_name(device), acpi_device_bid(device)));
+
+
+	return_VALUE(0);
+}
+
+static int
+acpi_container_remove(struct acpi_device *device, int type)
+{
+	acpi_status		status = AE_OK;
+	struct acpi_container	*pc = NULL;
+	pc = (struct acpi_container*) acpi_driver_data(device);
+
+	if (pc)
+		kfree(pc);
+
+	return status;
+}
+
+
+static int
+container_device_add(struct acpi_device **device, acpi_handle handle)
+{
+	acpi_handle phandle;
+	struct acpi_device *pdev;
+	int result;
+
+	ACPI_FUNCTION_TRACE("container_device_add");
+
+	if (acpi_get_parent(handle, &phandle)) {
+		return_VALUE(-ENODEV);
+	}
+
+	if (acpi_bus_get_device(phandle, &pdev)) {
+		return_VALUE(-ENODEV);
+	}
+
+	if (acpi_bus_add(device, pdev, handle, ACPI_BUS_TYPE_DEVICE)) {
+		return_VALUE(-ENODEV);
+	}
+
+	result = acpi_bus_scan(*device);
+
+	return_VALUE(result);
+}
+
+static void
+container_notify_cb(acpi_handle handle, u32 type, void *context)
+{
+	struct acpi_device		*device = NULL;
+	int result;
+	int present;
+	acpi_status status;
+
+	ACPI_FUNCTION_TRACE("container_notify_cb");
+
+	present = is_device_present(handle);
+	
+	switch (type) {
+	case ACPI_NOTIFY_BUS_CHECK:
+		/* Fall through */
+	case ACPI_NOTIFY_DEVICE_CHECK:
+		printk("Container driver received %s event\n",
+			(type == ACPI_NOTIFY_BUS_CHECK)?
+			"ACPI_NOTIFY_BUS_CHECK":"ACPI_NOTIFY_DEVICE_CHECK");
+		if (present) {
+			status = acpi_bus_get_device(handle, &device);
+			if (ACPI_FAILURE(status) || !device) {
+				result = container_device_add(&device, handle);
+				if (!result)
+					kobject_hotplug(&device->kobj, KOBJ_ONLINE);
+			} else {
+				/* device exist and this is a remove request */
+				kobject_hotplug(&device->kobj, KOBJ_OFFLINE);
+			}
+		}
+		break;
+	case ACPI_NOTIFY_EJECT_REQUEST:
+		if (!acpi_bus_get_device(handle, &device) && device) {
+			kobject_hotplug(&device->kobj, KOBJ_OFFLINE);
+		}
+		break;
+	default:
+		break;
+	}
+	return_VOID;
+}
+
+static acpi_status
+container_walk_namespace_cb(acpi_handle handle,
+	u32 lvl,
+	void *context,
+	void **rv)
+{
+	char 				*hid = NULL;
+	struct acpi_buffer 		buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+	struct acpi_device_info 	*info;
+	acpi_status 			status;
+	int 				*action = context;
+
+	ACPI_FUNCTION_TRACE("container_walk_namespace_cb");
+
+	status = acpi_get_object_info(handle, &buffer);
+	if (ACPI_FAILURE(status) || !buffer.pointer) {
+		return_ACPI_STATUS(AE_OK);
+	}
+
+	info = buffer.pointer;
+	if (info->valid & ACPI_VALID_HID)
+		hid = info->hardware_id.value;
+
+	if (hid == NULL) {
+		goto end;
+	}
+
+	if (strcmp(hid, "ACPI0004") && strcmp(hid, "PNP0A05") &&
+			strcmp(hid, "PNP0A06")) {
+		goto end;
+	}
+
+	switch(*action) {
+	case INSTALL_NOTIFY_HANDLER:
+		acpi_install_notify_handler(handle,
+			ACPI_SYSTEM_NOTIFY,
+			container_notify_cb,
+			NULL);
+		break;
+	case UNINSTALL_NOTIFY_HANDLER:
+		acpi_remove_notify_handler(handle,
+			ACPI_SYSTEM_NOTIFY,
+			container_notify_cb);
+		break;
+	default:
+		break;
+	}
+
+end:
+	acpi_os_free(buffer.pointer);
+
+	return_ACPI_STATUS(AE_OK);
+}
+
+
+int __init
+acpi_container_init(void)
+{
+	int	result = 0;
+	int	action = INSTALL_NOTIFY_HANDLER;
+
+	result = acpi_bus_register_driver(&acpi_container_driver);
+	if (result < 0) {
+		return(result);
+	}
+
+	/* register notify handler to every container device */
+	acpi_walk_namespace(ACPI_TYPE_DEVICE,
+				     ACPI_ROOT_OBJECT,
+				     ACPI_UINT32_MAX,
+				     container_walk_namespace_cb,
+				     &action, NULL);
+
+	return(0);
+}
+
+void __exit
+acpi_container_exit(void)
+{
+	int			action = UNINSTALL_NOTIFY_HANDLER;
+
+	ACPI_FUNCTION_TRACE("acpi_container_exit");
+
+	acpi_walk_namespace(ACPI_TYPE_DEVICE,
+				     ACPI_ROOT_OBJECT,
+				     ACPI_UINT32_MAX,
+				     container_walk_namespace_cb,
+				     &action, NULL);
+
+	acpi_bus_unregister_driver(&acpi_container_driver);
+
+	return_VOID;
+}
+
+module_init(acpi_container_init);
+module_exit(acpi_container_exit);
diff -Nru a/drivers/acpi/debug.c b/drivers/acpi/debug.c
--- a/drivers/acpi/debug.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/acpi/debug.c	2005-03-01 23:39:08 -08:00
@@ -4,9 +4,12 @@
 
 #include <linux/proc_fs.h>
 #include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
 #include <linux/moduleparam.h>
 #include <asm/uaccess.h>
 #include <acpi/acpi_drivers.h>
+#include <acpi/acglobal.h>
 
 #define _COMPONENT		ACPI_SYSTEM_COMPONENT
 ACPI_MODULE_NAME		("debug")
@@ -87,7 +90,6 @@
 	ACPI_DEBUG_INIT(ACPI_LV_FULL_TABLES),
 	ACPI_DEBUG_INIT(ACPI_LV_EVENTS),             
 };
-#define NUM_OF(v)	( sizeof(v)/sizeof(v[0]) )
 
 static int
 acpi_system_read_debug (
@@ -100,7 +102,7 @@
 {
 	char			*p = page;
 	int 			size = 0;
-	int			i;
+	unsigned int		i;
 
 	if (off != 0)
 		goto end;
@@ -109,7 +111,7 @@
 
 	switch ((unsigned long) data) {
 	case 0:
-		for (i = 0; i < NUM_OF(acpi_debug_layers); i++) {
+		for (i = 0; i < ARRAY_SIZE(acpi_debug_layers); i++) {
 			p += sprintf(p, "%-25s\t0x%08lX [%c]\n",
 				acpi_debug_layers[i].name,
 				acpi_debug_layers[i].value,
@@ -126,7 +128,7 @@
 			acpi_dbg_layer);
 		break;
 	case 1:
-		for (i = 0; i < NUM_OF(acpi_debug_levels); i++) {
+		for (i = 0; i < ARRAY_SIZE(acpi_debug_levels); i++) {
 			p += sprintf(p, "%-25s\t0x%08lX [%c]\n",
 				acpi_debug_levels[i].name,
 				acpi_debug_levels[i].value,
diff -Nru a/drivers/acpi/dispatcher/dsfield.c b/drivers/acpi/dispatcher/dsfield.c
--- a/drivers/acpi/dispatcher/dsfield.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/acpi/dispatcher/dsfield.c	2005-03-01 23:39:07 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/dispatcher/dsinit.c b/drivers/acpi/dispatcher/dsinit.c
--- a/drivers/acpi/dispatcher/dsinit.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/acpi/dispatcher/dsinit.c	2005-03-01 23:39:16 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/dispatcher/dsmethod.c b/drivers/acpi/dispatcher/dsmethod.c
--- a/drivers/acpi/dispatcher/dsmethod.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/acpi/dispatcher/dsmethod.c	2005-03-01 23:38:57 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/dispatcher/dsmthdat.c b/drivers/acpi/dispatcher/dsmthdat.c
--- a/drivers/acpi/dispatcher/dsmthdat.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/acpi/dispatcher/dsmthdat.c	2005-03-01 23:39:18 -08:00
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/dispatcher/dsobject.c b/drivers/acpi/dispatcher/dsobject.c
--- a/drivers/acpi/dispatcher/dsobject.c	2005-03-01 23:38:51 -08:00
+++ b/drivers/acpi/dispatcher/dsobject.c	2005-03-01 23:38:51 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -516,7 +516,7 @@
 
 			case AML_REVISION_OP:
 
-				obj_desc->integer.value = ACPI_CA_SUPPORT_LEVEL;
+				obj_desc->integer.value = ACPI_CA_VERSION;
 				break;
 
 			default:
diff -Nru a/drivers/acpi/dispatcher/dsopcode.c b/drivers/acpi/dispatcher/dsopcode.c
--- a/drivers/acpi/dispatcher/dsopcode.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/acpi/dispatcher/dsopcode.c	2005-03-01 23:39:09 -08:00
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -762,9 +762,8 @@
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Get the operands and complete the following data objec types:
- *              Buffer
- *              Package
+ * DESCRIPTION: Get the operands and complete the following data object types:
+ *              Buffer, Package.
  *
  ****************************************************************************/
 
diff -Nru a/drivers/acpi/dispatcher/dsutils.c b/drivers/acpi/dispatcher/dsutils.c
--- a/drivers/acpi/dispatcher/dsutils.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/acpi/dispatcher/dsutils.c	2005-03-01 23:38:57 -08:00
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -88,11 +88,13 @@
 	}
 
 	/*
-	 * If there is no parent, we are executing at the method level.
-	 * An executing method typically has no parent, since each method
-	 * is parsed separately.
+	 * If there is no parent, or the parent is a scope_op, we are executing
+	 * at the method level. An executing method typically has no parent,
+	 * since each method is parsed separately.  A method invoked externally
+	 * via execute_control_method has a scope_op as the parent.
 	 */
-	if (!op->common.parent) {
+	if ((!op->common.parent) ||
+		(op->common.parent->common.aml_opcode == AML_SCOPE_OP)) {
 		/*
 		 * If this is the last statement in the method, we know it is not a
 		 * Return() operator (would not come here.) The following code is the
diff -Nru a/drivers/acpi/dispatcher/dswexec.c b/drivers/acpi/dispatcher/dswexec.c
--- a/drivers/acpi/dispatcher/dswexec.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/acpi/dispatcher/dswexec.c	2005-03-01 23:39:17 -08:00
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -399,16 +399,24 @@
 			goto cleanup;
 		}
 
-		/* Resolve all operands */
+		/*
+		 * All opcodes require operand resolution, with the only exceptions
+		 * being the object_type and size_of operators.
+		 */
+		if (!(walk_state->op_info->flags & AML_NO_OPERAND_RESOLVE)) {
+			/* Resolve all operands */
 
-		status = acpi_ex_resolve_operands (walk_state->opcode,
-				  &(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");
+			status = acpi_ex_resolve_operands (walk_state->opcode,
+					  &(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");
+			}
+		}
 
+		if (ACPI_SUCCESS (status)) {
 			/*
 			 * Dispatch the request to the appropriate interpreter handler
 			 * routine.  There is one routine per opcode "type" based upon the
@@ -568,6 +576,13 @@
 
 				status = acpi_ds_eval_data_object_operands (walk_state, op, NULL);
 				break;
+			}
+
+			/* Done with this result state (Now that operand stack is built) */
+
+			status = acpi_ds_result_stack_pop (walk_state);
+			if (ACPI_FAILURE (status)) {
+				goto cleanup;
 			}
 
 			/*
diff -Nru a/drivers/acpi/dispatcher/dswload.c b/drivers/acpi/dispatcher/dswload.c
--- a/drivers/acpi/dispatcher/dswload.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/acpi/dispatcher/dswload.c	2005-03-01 23:38:52 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/dispatcher/dswscope.c b/drivers/acpi/dispatcher/dswscope.c
--- a/drivers/acpi/dispatcher/dswscope.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/acpi/dispatcher/dswscope.c	2005-03-01 23:39:17 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/dispatcher/dswstate.c b/drivers/acpi/dispatcher/dswstate.c
--- a/drivers/acpi/dispatcher/dswstate.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/acpi/dispatcher/dswstate.c	2005-03-01 23:39:09 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -1071,6 +1071,7 @@
 }
 
 
+#ifdef ACPI_ENABLE_OBJECT_CACHE
 /******************************************************************************
  *
  * FUNCTION:    acpi_ds_delete_walk_state_cache
@@ -1094,5 +1095,6 @@
 	acpi_ut_delete_generic_cache (ACPI_MEM_LIST_WALK);
 	return_VOID;
 }
+#endif
 
 
diff -Nru a/drivers/acpi/ec.c b/drivers/acpi/ec.c
--- a/drivers/acpi/ec.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/acpi/ec.c	2005-03-01 23:38:58 -08:00
@@ -442,6 +442,8 @@
 	int			result = 0;
 	struct acpi_ec		*ec = NULL;
 	u32			temp = 0;
+	acpi_integer		f_v = 0;
+	int 			i = 0;
 
 	ACPI_FUNCTION_TRACE("acpi_ec_space_handler");
 
@@ -456,6 +458,7 @@
 
 	ec = (struct acpi_ec *) handler_context;
 
+next_byte:
 	switch (function) {
 	case ACPI_READ:
 		result = acpi_ec_read(ec, (u8) address, &temp);
@@ -466,9 +469,29 @@
 		break;
 	default:
 		result = -EINVAL;
+		goto out;
 		break;
 	}
 
+	bit_width -= 8;
+	if(bit_width){
+
+		if(function == ACPI_READ)
+			f_v |= (acpi_integer) (*value) << 8*i;
+		if(function == ACPI_WRITE)
+			(*value) >>=8; 
+		i++;
+		goto next_byte;
+	}
+
+
+	if(function == ACPI_READ){
+		f_v |= (acpi_integer) (*value) << 8*i;
+		*value = f_v;
+	}
+
+		
+out:
 	switch (result) {
 	case -EINVAL:
 		return_VALUE(AE_BAD_PARAMETER);
@@ -482,6 +505,7 @@
 	default:
 		return_VALUE(AE_OK);
 	}
+	
 
 }
 
@@ -599,7 +623,7 @@
 
 	ec->handle = device->handle;
 	ec->uid = -1;
-	ec->lock = SPIN_LOCK_UNLOCKED;
+	spin_lock_init(&ec->lock);
 	strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME);
 	strcpy(acpi_device_class(device), ACPI_EC_CLASS);
 	acpi_driver_data(device) = ec;
@@ -787,9 +811,81 @@
 	return_VALUE(0);
 }
 
+static acpi_status __init
+acpi_fake_ecdt_callback (
+	acpi_handle	handle,
+	u32		Level,
+	void		*context,
+	void		**retval)
+{
+	acpi_status	status;
 
-int __init
-acpi_ec_ecdt_probe (void)
+	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->uid = -1;
+	acpi_evaluate_integer(handle, "_UID", NULL, &ec_ecdt->uid);
+
+	status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec_ecdt->gpe_bit);
+	if (ACPI_FAILURE(status))
+		return status;
+	spin_lock_init(&ec_ecdt->lock);
+	ec_ecdt->global_lock = TRUE;
+	ec_ecdt->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);
+
+	return AE_CTRL_TERMINATE;
+}
+
+/*
+ * Some BIOS (such as some from Gateway laptops) access EC region very early
+ * such as in BAT0._INI or EC._INI before an EC device is found and
+ * do not provide an ECDT. According to ACPI spec, ECDT isn't mandatorily
+ * required, but if EC regison is accessed early, it is required.
+ * The routine tries to workaround the BIOS bug by pre-scan EC device
+ * It assumes that _CRS, _HID, _GPE, _UID methods of EC don't touch any
+ * op region (since _REG isn't invoked yet). The assumption is true for
+ * all systems found.
+ */
+static int __init
+acpi_ec_fake_ecdt(void)
+{
+	acpi_status	status;
+	int		ret = 0;
+
+	printk(KERN_INFO PREFIX "Try to make an fake ECDT\n");
+
+	ec_ecdt = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL);
+	if (!ec_ecdt) {
+		ret = -ENOMEM;
+		goto error;
+	}
+	memset(ec_ecdt, 0, sizeof(struct acpi_ec));
+
+	status = acpi_get_devices (ACPI_EC_HID,
+				acpi_fake_ecdt_callback,
+				NULL,
+				NULL);
+	if (ACPI_FAILURE(status)) {
+		kfree(ec_ecdt);
+		ec_ecdt = NULL;
+		ret = -ENODEV;
+		goto error;
+	}
+	return 0;
+error:
+	printk(KERN_ERR PREFIX "Can't make an fake ECDT\n");
+	return ret;
+}
+
+static int __init
+acpi_ec_get_real_ecdt(void)
 {
 	acpi_status		status;
 	struct acpi_table_ecdt 	*ecdt_ptr;
@@ -797,11 +893,11 @@
 	status = acpi_get_firmware_table("ECDT", 1, ACPI_LOGICAL_ADDRESSING, 
 		(struct acpi_table_header **) &ecdt_ptr);
 	if (ACPI_FAILURE(status))
-		return 0;
+		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(struct acpi_ec), GFP_KERNEL);
@@ -813,7 +909,7 @@
 	ec_ecdt->status_addr = ecdt_ptr->ec_control;
 	ec_ecdt->data_addr = ecdt_ptr->ec_data;
 	ec_ecdt->gpe_bit = ecdt_ptr->gpe_bit;
-	ec_ecdt->lock = SPIN_LOCK_UNLOCKED;
+	spin_lock_init(&ec_ecdt->lock);
 	/* use the GL just to be safe */
 	ec_ecdt->global_lock = TRUE;
 	ec_ecdt->uid = ecdt_ptr->uid;
@@ -823,6 +919,31 @@
 		goto error;
 	}
 
+	return 0;
+error:
+	printk(KERN_ERR PREFIX "Could not use ECDT\n");
+	kfree(ec_ecdt);
+	ec_ecdt = NULL;
+
+	return -ENODEV;
+}
+
+static int __initdata acpi_fake_ecdt_enabled;
+int __init
+acpi_ec_ecdt_probe (void)
+{
+	acpi_status		status;
+	int			ret;
+
+	ret = acpi_ec_get_real_ecdt();
+	/* Try to make a fake ECDT */
+	if (ret && acpi_fake_ecdt_enabled) {
+		ret = acpi_ec_fake_ecdt();
+	}
+
+	if (ret)
+		return 0;
+
 	/*
 	 * Install GPE handler
 	 */
@@ -895,3 +1016,9 @@
 }
 #endif /* 0 */
 
+static int __init acpi_fake_ecdt_setup(char *str)
+{
+	acpi_fake_ecdt_enabled = 1;
+	return 0;
+}
+__setup("acpi_fake_ecdt", acpi_fake_ecdt_setup);
diff -Nru a/drivers/acpi/event.c b/drivers/acpi/event.c
--- a/drivers/acpi/event.c	2005-03-01 23:38:44 -08:00
+++ b/drivers/acpi/event.c	2005-03-01 23:38:44 -08:00
@@ -16,7 +16,7 @@
 ACPI_MODULE_NAME		("event")
 
 /* Global vars for handling event proc entry */
-static spinlock_t		acpi_system_event_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(acpi_system_event_lock);
 int				event_is_open = 0;
 extern struct list_head		acpi_bus_event_list;
 extern wait_queue_head_t	acpi_bus_event_queue;
diff -Nru a/drivers/acpi/events/evevent.c b/drivers/acpi/events/evevent.c
--- a/drivers/acpi/events/evevent.c	2005-03-01 23:39:19 -08:00
+++ b/drivers/acpi/events/evevent.c	2005-03-01 23:39:19 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/events/evgpe.c b/drivers/acpi/events/evgpe.c
--- a/drivers/acpi/events/evgpe.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/acpi/events/evgpe.c	2005-03-01 23:39:18 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -605,8 +605,8 @@
 	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: Unable to clear GPE[%2X]\n",
-				gpe_number));
+			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);
 		}
 	}
@@ -643,8 +643,8 @@
 			status = acpi_hw_clear_gpe (gpe_event_info);
 			if (ACPI_FAILURE (status)) {
 				ACPI_REPORT_ERROR ((
-					"acpi_ev_gpe_dispatch: Unable to clear GPE[%2X]\n",
-					gpe_number));
+					"acpi_ev_gpe_dispatch: %s, Unable to clear GPE[%2X]\n",
+					acpi_format_exception (status), gpe_number));
 				return_VALUE (ACPI_INTERRUPT_NOT_HANDLED);
 			}
 		}
@@ -659,8 +659,8 @@
 		status = acpi_ev_disable_gpe (gpe_event_info);
 		if (ACPI_FAILURE (status)) {
 			ACPI_REPORT_ERROR ((
-				"acpi_ev_gpe_dispatch: Unable to disable GPE[%2X]\n",
-				gpe_number));
+				"acpi_ev_gpe_dispatch: %s, Unable to disable GPE[%2X]\n",
+				acpi_format_exception (status), gpe_number));
 			return_VALUE (ACPI_INTERRUPT_NOT_HANDLED);
 		}
 
@@ -668,12 +668,12 @@
 		 * Execute the method associated with the GPE
 		 * NOTE: Level-triggered GPEs are cleared after the method completes.
 		 */
-		if (ACPI_FAILURE (acpi_os_queue_for_execution (OSD_PRIORITY_GPE,
-				 acpi_ev_asynch_execute_gpe_method,
-				 gpe_event_info))) {
+		status = acpi_os_queue_for_execution (OSD_PRIORITY_GPE,
+				 acpi_ev_asynch_execute_gpe_method, gpe_event_info);
+		if (ACPI_FAILURE (status)) {
 			ACPI_REPORT_ERROR ((
-				"acpi_ev_gpe_dispatch: Unable to queue handler for GPE[%2X], event is disabled\n",
-				gpe_number));
+				"acpi_ev_gpe_dispatch: %s, Unable to queue handler for GPE[%2X] - event disabled\n",
+				acpi_format_exception (status), gpe_number));
 		}
 		break;
 
@@ -692,8 +692,8 @@
 		status = acpi_ev_disable_gpe (gpe_event_info);
 		if (ACPI_FAILURE (status)) {
 			ACPI_REPORT_ERROR ((
-				"acpi_ev_gpe_dispatch: Unable to disable GPE[%2X]\n",
-				gpe_number));
+				"acpi_ev_gpe_dispatch: %s, Unable to disable GPE[%2X]\n",
+				acpi_format_exception (status), gpe_number));
 			return_VALUE (ACPI_INTERRUPT_NOT_HANDLED);
 		}
 		break;
diff -Nru a/drivers/acpi/events/evgpeblk.c b/drivers/acpi/events/evgpeblk.c
--- a/drivers/acpi/events/evgpeblk.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/acpi/events/evgpeblk.c	2005-03-01 23:38:57 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -925,7 +925,7 @@
 
 	/*
 	 * Runtime option: Should Wake GPEs be enabled at runtime?  The default
-	 * is No,they should only be enabled just as the machine goes to sleep.
+	 * is No, they should only be enabled just as the machine goes to sleep.
 	 */
 	if (acpi_gbl_leave_wake_gpes_disabled) {
 		/*
diff -Nru a/drivers/acpi/events/evmisc.c b/drivers/acpi/events/evmisc.c
--- a/drivers/acpi/events/evmisc.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/acpi/events/evmisc.c	2005-03-01 23:38:58 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/events/evregion.c b/drivers/acpi/events/evregion.c
--- a/drivers/acpi/events/evregion.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/acpi/events/evregion.c	2005-03-01 23:39:07 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/events/evrgnini.c b/drivers/acpi/events/evrgnini.c
--- a/drivers/acpi/events/evrgnini.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/acpi/events/evrgnini.c	2005-03-01 23:38:52 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/events/evsci.c b/drivers/acpi/events/evsci.c
--- a/drivers/acpi/events/evsci.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/acpi/events/evsci.c	2005-03-01 23:39:07 -08:00
@@ -6,7 +6,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/events/evxface.c b/drivers/acpi/events/evxface.c
--- a/drivers/acpi/events/evxface.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/acpi/events/evxface.c	2005-03-01 23:38:58 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/events/evxfevnt.c b/drivers/acpi/events/evxfevnt.c
--- a/drivers/acpi/events/evxfevnt.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/acpi/events/evxfevnt.c	2005-03-01 23:38:54 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -435,7 +435,7 @@
  * DESCRIPTION: Clear an ACPI event (fixed)
  *
  ******************************************************************************/
-#ifdef ACPI_FUTURE_USAGE
+
 acpi_status
 acpi_clear_event (
 	u32                             event)
@@ -462,7 +462,6 @@
 	return_ACPI_STATUS (status);
 }
 EXPORT_SYMBOL(acpi_clear_event);
-#endif  /*  ACPI_FUTURE_USAGE  */
 
 
 /*******************************************************************************
diff -Nru a/drivers/acpi/events/evxfregn.c b/drivers/acpi/events/evxfregn.c
--- a/drivers/acpi/events/evxfregn.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/acpi/events/evxfregn.c	2005-03-01 23:38:53 -08:00
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/executer/exconfig.c b/drivers/acpi/executer/exconfig.c
--- a/drivers/acpi/executer/exconfig.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/acpi/executer/exconfig.c	2005-03-01 23:38:58 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -95,7 +95,7 @@
 
 	ACPI_MEMSET (&table_info, 0, sizeof (struct acpi_table_desc));
 
-	table_info.type        = 5;
+	table_info.type        = ACPI_TABLE_SSDT;
 	table_info.pointer     = table;
 	table_info.length      = (acpi_size) table->length;
 	table_info.allocation  = ACPI_MEM_ALLOCATED;
diff -Nru a/drivers/acpi/executer/exconvrt.c b/drivers/acpi/executer/exconvrt.c
--- a/drivers/acpi/executer/exconvrt.c	2005-03-01 23:38:51 -08:00
+++ b/drivers/acpi/executer/exconvrt.c	2005-03-01 23:38:51 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -115,12 +115,6 @@
 	 */
 	result = 0;
 
-	/* Transfer no more than an integer's worth of data */
-
-	if (count > acpi_gbl_integer_byte_width) {
-		count = acpi_gbl_integer_byte_width;
-	}
-
 	/*
 	 * String conversion is different than Buffer conversion
 	 */
@@ -142,6 +136,18 @@
 
 	case ACPI_TYPE_BUFFER:
 
+		/* Check for zero-length buffer */
+
+		if (!count) {
+			return_ACPI_STATUS (AE_AML_BUFFER_LIMIT);
+		}
+
+		/* Transfer no more than an integer's worth of data */
+
+		if (count > acpi_gbl_integer_byte_width) {
+			count = acpi_gbl_integer_byte_width;
+		}
+
 		/*
 		 * Convert buffer to an integer - we simply grab enough raw data
 		 * from the buffer to fill an integer
@@ -173,6 +179,7 @@
 	/* Save the Result */
 
 	return_desc->integer.value = result;
+	acpi_ex_truncate_for32bit_table (return_desc);
 	*result_desc = return_desc;
 	return_ACPI_STATUS (AE_OK);
 }
@@ -238,8 +245,13 @@
 		/*
 		 * Create a new Buffer object
 		 * Size will be the string length
+		 *
+		 * NOTE: Add one to the string length to include the null terminator.
+		 * The ACPI spec is unclear on this subject, but there is existing
+		 * 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);
+		return_desc = acpi_ut_create_buffer_object ((acpi_size) obj_desc->string.length + 1);
 		if (!return_desc) {
 			return_ACPI_STATUS (AE_NO_MEMORY);
 		}
@@ -398,9 +410,9 @@
 {
 	union acpi_operand_object       *return_desc;
 	u8                              *new_buf;
+	u32                             i;
 	u32                             string_length = 0;
 	u16                             base = 16;
-	u32                             i;
 	u8                              separator = ',';
 
 
@@ -460,6 +472,8 @@
 
 	case ACPI_TYPE_BUFFER:
 
+		/* Setup string length, base, and separator */
+
 		switch (type) {
 		case ACPI_EXPLICIT_CONVERT_DECIMAL: /* Used by to_decimal_string operator */
 			/*
@@ -467,9 +481,23 @@
 			 * decimal values separated by commas."
 			 */
 			base = 10;
-			string_length = obj_desc->buffer.length; /* 4 chars for each decimal */
 
-			/*lint -fallthrough */
+			/*
+			 * Calculate the final string length.  Individual string values
+			 * are variable length (include separator for each)
+			 */
+			for (i = 0; i < obj_desc->buffer.length; i++) {
+				if (obj_desc->buffer.pointer[i] >= 100) {
+					string_length += 4;
+				}
+				else if (obj_desc->buffer.pointer[i] >= 10) {
+					string_length += 3;
+				}
+				else {
+					string_length += 2;
+				}
+			}
+			break;
 
 		case ACPI_IMPLICIT_CONVERT_HEX:
 			/*
@@ -477,55 +505,56 @@
 			 *"The entire contents of the buffer are converted to a string of
 			 * two-character hexadecimal numbers, each separated by a space."
 			 */
-			if (type == ACPI_IMPLICIT_CONVERT_HEX) {
-				separator = ' ';
-			}
-
-			/*lint -fallthrough */
+			separator = ' ';
+			string_length = (obj_desc->buffer.length * 3);
+			break;
 
 		case ACPI_EXPLICIT_CONVERT_HEX:     /* Used by to_hex_string operator */
 			/*
 			 * From ACPI: "If Data is a buffer, it is converted to a string of
 			 * hexadecimal values separated by commas."
 			 */
-			string_length += (obj_desc->buffer.length * 3);
-			if (string_length > ACPI_MAX_STRING_CONVERSION) /* ACPI limit */ {
-				return_ACPI_STATUS (AE_AML_STRING_LIMIT);
-			}
-
-			/* Create a new string object and string buffer */
-
-			return_desc = acpi_ut_create_string_object ((acpi_size) string_length -1);
-			if (!return_desc) {
-				return_ACPI_STATUS (AE_NO_MEMORY);
-			}
+			string_length = (obj_desc->buffer.length * 3);
+			break;
 
-			new_buf = return_desc->buffer.pointer;
+		default:
+			return_ACPI_STATUS (AE_BAD_PARAMETER);
+		}
 
-			/*
-			 * Convert buffer bytes to hex or decimal values
-			 * (separated by commas)
-			 */
-			for (i = 0; i < obj_desc->buffer.length; i++) {
-				new_buf += acpi_ex_convert_to_ascii (
-						 (acpi_integer) obj_desc->buffer.pointer[i], base,
-						 new_buf, 1);
-				*new_buf++ = separator; /* each separated by a comma or space */
-			}
+		/*
+		 * Perform the conversion.
+		 * (-1 because of extra separator included in string_length from above)
+		 */
+		string_length--;
+		if (string_length > ACPI_MAX_STRING_CONVERSION) /* ACPI limit */ {
+			return_ACPI_STATUS (AE_AML_STRING_LIMIT);
+		}
 
-			/* Null terminate the string (overwrites final comma from above) */
+		/*
+		 * 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);
+		}
 
-			new_buf--;
-			*new_buf = 0;
+		new_buf = return_desc->buffer.pointer;
 
-			/* Recalculate length */
+		/*
+		 * Convert buffer bytes to hex or decimal values
+		 * (separated by commas or spaces)
+		 */
+		for (i = 0; i < obj_desc->buffer.length; i++) {
+			new_buf += acpi_ex_convert_to_ascii (
+					 (acpi_integer) obj_desc->buffer.pointer[i], base,
+					 new_buf, 1);
+			*new_buf++ = separator; /* each separated by a comma or space */
+		}
 
-			return_desc->string.length = ACPI_STRLEN (return_desc->string.pointer);
-			break;
+		/* Null terminate the string (overwrites final comma/space from above) */
 
-		default:
-			return_ACPI_STATUS (AE_BAD_PARAMETER);
-		}
+		new_buf--;
+		*new_buf = 0;
 		break;
 
 	default:
diff -Nru a/drivers/acpi/executer/excreate.c b/drivers/acpi/executer/excreate.c
--- a/drivers/acpi/executer/excreate.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/acpi/executer/excreate.c	2005-03-01 23:39:16 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/executer/exdump.c b/drivers/acpi/executer/exdump.c
--- a/drivers/acpi/executer/exdump.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/acpi/executer/exdump.c	2005-03-01 23:38:52 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -110,10 +110,12 @@
 	/* obj_desc is a valid object */
 
 	if (depth > 0) {
-		ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC, "%*s[%u] ", depth, " ", depth));
+		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%*s[%u] %p ",
+			depth, " ", depth, obj_desc));
+	}
+	else {
+		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%p ", obj_desc));
 	}
-	ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC, "%p ", obj_desc));
-
 
 	switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
 	case ACPI_TYPE_LOCAL_REFERENCE:
@@ -712,9 +714,6 @@
 		acpi_ex_out_integer ("bit_length",  obj_desc->common_field.bit_length);
 		acpi_ex_out_integer ("fld_bit_offset", obj_desc->common_field.start_field_bit_offset);
 		acpi_ex_out_integer ("base_byte_offset", obj_desc->common_field.base_byte_offset);
-		acpi_ex_out_integer ("datum_valid_bits", obj_desc->common_field.datum_valid_bits);
-		acpi_ex_out_integer ("end_fld_valid_bits",obj_desc->common_field.end_field_valid_bits);
-		acpi_ex_out_integer ("end_buf_valid_bits",obj_desc->common_field.end_buffer_valid_bits);
 		acpi_ex_out_pointer ("parent_node", obj_desc->common_field.node);
 
 		switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
diff -Nru a/drivers/acpi/executer/exfield.c b/drivers/acpi/executer/exfield.c
--- a/drivers/acpi/executer/exfield.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/acpi/executer/exfield.c	2005-03-01 23:38:52 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/executer/exfldio.c b/drivers/acpi/executer/exfldio.c
--- a/drivers/acpi/executer/exfldio.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/acpi/executer/exfldio.c	2005-03-01 23:38:54 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -612,210 +612,6 @@
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_ex_get_buffer_datum
- *
- * PARAMETERS:  Datum               - Where the Datum is returned
- *              Buffer              - Raw field buffer
- *              buffer_length       - Entire length (used for big-endian only)
- *              byte_granularity    - 1/2/4/8 Granularity of the field
- *                                    (aka Datum Size)
- *              buffer_offset       - Datum offset into the buffer
- *
- * RETURN:      none
- *
- * DESCRIPTION: Get a datum from the buffer according to the buffer field
- *              byte granularity
- *
- ******************************************************************************/
-
-void
-acpi_ex_get_buffer_datum (
-	acpi_integer                    *datum,
-	void                            *buffer,
-	u32                             buffer_length,
-	u32                             byte_granularity,
-	u32                             buffer_offset)
-{
-	u32                             index;
-
-
-	ACPI_FUNCTION_TRACE_U32 ("ex_get_buffer_datum", byte_granularity);
-
-
-	/* Get proper index into buffer (handles big/little endian) */
-
-	index = ACPI_BUFFER_INDEX (buffer_length, buffer_offset, byte_granularity);
-
-	/* Move the requested number of bytes */
-
-	switch (byte_granularity) {
-	case ACPI_FIELD_BYTE_GRANULARITY:
-
-		*datum = ((u8 *) buffer) [index];
-		break;
-
-	case ACPI_FIELD_WORD_GRANULARITY:
-
-		ACPI_MOVE_16_TO_64 (datum, &(((u16 *) buffer) [index]));
-		break;
-
-	case ACPI_FIELD_DWORD_GRANULARITY:
-
-		ACPI_MOVE_32_TO_64 (datum, &(((u32 *) buffer) [index]));
-		break;
-
-	case ACPI_FIELD_QWORD_GRANULARITY:
-
-		ACPI_MOVE_64_TO_64 (datum, &(((u64 *) buffer) [index]));
-		break;
-
-	default:
-		/* Should not get here */
-		break;
-	}
-
-	return_VOID;
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ex_set_buffer_datum
- *
- * PARAMETERS:  merged_datum        - Value to store
- *              Buffer              - Receiving buffer
- *              buffer_length       - Entire length (used for big-endian only)
- *              byte_granularity    - 1/2/4/8 Granularity of the field
- *                                    (aka Datum Size)
- *              buffer_offset       - Datum offset into the buffer
- *
- * RETURN:      none
- *
- * DESCRIPTION: Store the merged datum to the buffer according to the
- *              byte granularity
- *
- ******************************************************************************/
-
-void
-acpi_ex_set_buffer_datum (
-	acpi_integer                    merged_datum,
-	void                            *buffer,
-	u32                             buffer_length,
-	u32                             byte_granularity,
-	u32                             buffer_offset)
-{
-	u32                             index;
-
-
-	ACPI_FUNCTION_TRACE_U32 ("ex_set_buffer_datum", byte_granularity);
-
-
-	/* Get proper index into buffer (handles big/little endian) */
-
-	index = ACPI_BUFFER_INDEX (buffer_length, buffer_offset, byte_granularity);
-
-	/* Move the requested number of bytes */
-
-	switch (byte_granularity) {
-	case ACPI_FIELD_BYTE_GRANULARITY:
-
-		((u8 *) buffer) [index] = (u8) merged_datum;
-		break;
-
-	case ACPI_FIELD_WORD_GRANULARITY:
-
-		ACPI_MOVE_64_TO_16 (&(((u16 *) buffer)[index]), &merged_datum);
-		break;
-
-	case ACPI_FIELD_DWORD_GRANULARITY:
-
-		ACPI_MOVE_64_TO_32 (&(((u32 *) buffer)[index]), &merged_datum);
-		break;
-
-	case ACPI_FIELD_QWORD_GRANULARITY:
-
-		ACPI_MOVE_64_TO_64 (&(((u64 *) buffer)[index]), &merged_datum);
-		break;
-
-	default:
-		/* Should not get here */
-		break;
-	}
-
-	return_VOID;
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ex_common_buffer_setup
- *
- * PARAMETERS:  obj_desc            - Field object
- *              buffer_length       - Length of caller's buffer
- *              datum_count         - Where the datum_count is returned
- *
- * RETURN:      Status, datum_count
- *
- * DESCRIPTION: Common code to validate the incoming buffer size and compute
- *              the number of field "datums" that must be read or written.
- *              A "datum" is the smallest unit that can be read or written
- *              to the field, it is either 1,2,4, or 8 bytes.
- *
- ******************************************************************************/
-
-acpi_status
-acpi_ex_common_buffer_setup (
-	union acpi_operand_object       *obj_desc,
-	u32                             buffer_length,
-	u32                             *datum_count)
-{
-	u32                             byte_field_length;
-	u32                             actual_byte_field_length;
-
-
-	ACPI_FUNCTION_TRACE ("ex_common_buffer_setup");
-
-
-	/*
-	 * Incoming buffer must be at least as long as the field, we do not
-	 * allow "partial" field reads/writes.  We do not care if the buffer is
-	 * larger than the field, this typically happens when an integer is
-	 * read/written to a field that is actually smaller than an integer.
-	 */
-	byte_field_length = ACPI_ROUND_BITS_UP_TO_BYTES (
-			 obj_desc->common_field.bit_length);
-	if (byte_field_length > buffer_length) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
-			"Field size %X (bytes) is too large for buffer (%X)\n",
-			byte_field_length, buffer_length));
-
-		return_ACPI_STATUS (AE_BUFFER_OVERFLOW);
-	}
-
-	/*
-	 * Create "actual" field byte count (minimum number of bytes that
-	 * must be read), then convert to datum count (minimum number
-	 * of datum-sized units that must be read)
-	 */
-	actual_byte_field_length = ACPI_ROUND_BITS_UP_TO_BYTES (
-			  obj_desc->common_field.start_field_bit_offset +
-			  obj_desc->common_field.bit_length);
-
-
-	*datum_count = ACPI_ROUND_UP_TO (actual_byte_field_length,
-			   obj_desc->common_field.access_byte_width);
-
-	ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
-		"buffer_bytes %X, actual_bytes %X, Datums %X, byte_gran %X\n",
-		byte_field_length, actual_byte_field_length,
-		*datum_count, obj_desc->common_field.access_byte_width));
-
-	return_ACPI_STATUS (AE_OK);
-}
-
-
-/*******************************************************************************
- *
  * FUNCTION:    acpi_ex_extract_from_field
  *
  * PARAMETERS:  obj_desc            - Field to be read
@@ -835,128 +631,92 @@
 	u32                             buffer_length)
 {
 	acpi_status                     status;
-	u32                             field_datum_byte_offset;
-	u32                             buffer_datum_offset;
-	acpi_integer                    previous_raw_datum = 0;
-	acpi_integer                    this_raw_datum = 0;
-	acpi_integer                    merged_datum = 0;
+	acpi_integer                    raw_datum;
+	acpi_integer                    merged_datum;
+	u32                             field_offset = 0;
+	u32                             buffer_offset = 0;
+	u32                             buffer_tail_bits;
 	u32                             datum_count;
+	u32                             field_datum_count;
 	u32                             i;
 
 
 	ACPI_FUNCTION_TRACE ("ex_extract_from_field");
 
 
-	/* Validate buffer, compute number of datums */
+	/* Validate target buffer and clear it */
 
-	status = acpi_ex_common_buffer_setup (obj_desc, buffer_length, &datum_count);
-	if (ACPI_FAILURE (status)) {
-		return_ACPI_STATUS (status);
-	}
+	if (buffer_length < ACPI_ROUND_BITS_UP_TO_BYTES (
+			 obj_desc->common_field.bit_length)) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Field size %X (bits) is too large for buffer (%X)\n",
+			obj_desc->common_field.bit_length, buffer_length));
 
-	/*
-	 * Clear the caller's buffer (the whole buffer length as given)
-	 * This is very important, especially in the cases where the buffer
-	 * is longer than the size of the field.
-	 */
+		return_ACPI_STATUS (AE_BUFFER_OVERFLOW);
+	}
 	ACPI_MEMSET (buffer, 0, buffer_length);
 
-	field_datum_byte_offset = 0;
-	buffer_datum_offset= 0;
-
-	/* Read the entire field */
-
-	for (i = 0; i < datum_count; i++) {
-		status = acpi_ex_field_datum_io (obj_desc, field_datum_byte_offset,
-				  &this_raw_datum, ACPI_READ);
-		if (ACPI_FAILURE (status)) {
-			return_ACPI_STATUS (status);
-		}
-
-		/* We might actually be done if the request fits in one datum */
+	/* Compute the number of datums (access width data items) */
 
-		if ((datum_count == 1) &&
-			(obj_desc->common_field.flags & AOPOBJ_SINGLE_DATUM)) {
-			/* 1) Shift the valid data bits down to start at bit 0 */
+	datum_count = ACPI_ROUND_UP_TO (
+			   obj_desc->common_field.bit_length,
+			   obj_desc->common_field.access_bit_width);
+	field_datum_count = ACPI_ROUND_UP_TO (
+			   obj_desc->common_field.bit_length +
+			   obj_desc->common_field.start_field_bit_offset,
+			   obj_desc->common_field.access_bit_width);
 
-			merged_datum = (this_raw_datum >> obj_desc->common_field.start_field_bit_offset);
+	/* Priming read from the field */
 
-			/* 2) Mask off any upper unused bits (bits not part of the field) */
-
-			if (obj_desc->common_field.end_buffer_valid_bits) {
-				merged_datum &= ACPI_MASK_BITS_ABOVE (obj_desc->common_field.end_buffer_valid_bits);
-			}
+	status = acpi_ex_field_datum_io (obj_desc, field_offset, &raw_datum, ACPI_READ);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+	merged_datum = raw_datum >> obj_desc->common_field.start_field_bit_offset;
 
-			/* Store the datum to the caller buffer */
+	/* Read the rest of the field */
 
-			acpi_ex_set_buffer_datum (merged_datum, buffer, buffer_length,
-					obj_desc->common_field.access_byte_width, buffer_datum_offset);
+	for (i = 1; i < field_datum_count; i++) {
+		/* Get next input datum from the field */
 
-			return_ACPI_STATUS (AE_OK);
+		field_offset += obj_desc->common_field.access_byte_width;
+		status = acpi_ex_field_datum_io (obj_desc, field_offset,
+				  &raw_datum, ACPI_READ);
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
 		}
 
-		/* Special handling for the last datum to ignore extra bits */
-
-		if ((i >= (datum_count -1))          &&
-			(obj_desc->common_field.end_field_valid_bits)) {
-			/*
-			 * This is the last iteration of the loop.  We need to clear
-			 * any unused bits (bits that are not part of this field) before
-			 * we store the final merged datum into the caller buffer.
-			 */
-			this_raw_datum &=
-				ACPI_MASK_BITS_ABOVE (obj_desc->common_field.end_field_valid_bits);
-		}
+		/* Merge with previous datum if necessary */
 
-		/*
-		 * Create the (possibly) merged datum to be stored to the caller buffer
-		 */
-		if (obj_desc->common_field.start_field_bit_offset == 0) {
-			/* Field is not skewed and we can just copy the datum */
+		merged_datum |= raw_datum <<
+			(obj_desc->common_field.access_bit_width - obj_desc->common_field.start_field_bit_offset);
 
-			acpi_ex_set_buffer_datum (this_raw_datum, buffer, buffer_length,
-					obj_desc->common_field.access_byte_width, buffer_datum_offset);
-			buffer_datum_offset++;
+		if (i == datum_count) {
+			break;
 		}
-		else {
-			/* Not aligned -- on the first iteration, just save the datum */
-
-			if (i != 0) {
-				/*
-				 * Put together the appropriate bits of the two raw data to make a
-				 * single complete field datum
-				 *
-				 * 1) Normalize the first datum down to bit 0
-				 */
-				merged_datum = (previous_raw_datum >> obj_desc->common_field.start_field_bit_offset);
 
-				/* 2) Insert the second datum "above" the first datum */
+		/* Write merged datum to target buffer */
 
-				merged_datum |= (this_raw_datum << obj_desc->common_field.datum_valid_bits);
+		ACPI_MEMCPY (((char *) buffer) + buffer_offset, &merged_datum,
+			ACPI_MIN(obj_desc->common_field.access_byte_width,
+					 buffer_length - buffer_offset));
 
-				acpi_ex_set_buffer_datum (merged_datum, buffer, buffer_length,
-						obj_desc->common_field.access_byte_width, buffer_datum_offset);
-				buffer_datum_offset++;
-			}
+		buffer_offset += obj_desc->common_field.access_byte_width;
+		merged_datum = raw_datum >> obj_desc->common_field.start_field_bit_offset;
+	}
 
-			/*
-			 * Save the raw datum that was just acquired since it may contain bits
-			 * of the *next* field datum
-			 */
-			previous_raw_datum = this_raw_datum;
-		}
+	/* Mask off any extra bits in the last datum */
 
-		field_datum_byte_offset += obj_desc->common_field.access_byte_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);
 	}
 
-	/* For non-aligned case, there is one last datum to insert */
-
-	if (obj_desc->common_field.start_field_bit_offset != 0) {
-		merged_datum = (this_raw_datum >> obj_desc->common_field.start_field_bit_offset);
+	/* Write the last datum to the buffer */
 
-		acpi_ex_set_buffer_datum (merged_datum, buffer, buffer_length,
-				obj_desc->common_field.access_byte_width, buffer_datum_offset);
-	}
+	ACPI_MEMCPY (((char *) buffer) + buffer_offset, &merged_datum,
+		ACPI_MIN(obj_desc->common_field.access_byte_width,
+				 buffer_length - buffer_offset));
 
 	return_ACPI_STATUS (AE_OK);
 }
@@ -983,169 +743,91 @@
 	u32                             buffer_length)
 {
 	acpi_status                     status;
-	u32                             field_datum_byte_offset;
-	u32                             datum_offset;
 	acpi_integer                    mask;
 	acpi_integer                    merged_datum;
-	acpi_integer                    previous_raw_datum;
-	acpi_integer                    this_raw_datum;
+	acpi_integer                    raw_datum = 0;
+	u32                             field_offset = 0;
+	u32                             buffer_offset = 0;
+	u32                             buffer_tail_bits;
 	u32                             datum_count;
+	u32                             field_datum_count;
+	u32                             i;
 
 
 	ACPI_FUNCTION_TRACE ("ex_insert_into_field");
 
 
-	/* Validate buffer, compute number of datums */
+	/* Validate input buffer */
 
-	status = acpi_ex_common_buffer_setup (obj_desc, buffer_length, &datum_count);
-	if (ACPI_FAILURE (status)) {
-		return_ACPI_STATUS (status);
-	}
-
-	/*
-	 * Break the request into up to three parts (similar to an I/O request):
-	 * 1) non-aligned part at start
-	 * 2) aligned part in middle
-	 * 3) non-aligned part at the end
-	 */
-	field_datum_byte_offset = 0;
-	datum_offset= 0;
-
-	/* Get a single datum from the caller's buffer */
-
-	acpi_ex_get_buffer_datum (&previous_raw_datum, buffer, buffer_length,
-			obj_desc->common_field.access_byte_width, datum_offset);
-
-	/*
-	 * Part1:
-	 * Write a partial field datum if field does not begin on a datum boundary
-	 * Note: The code in this section also handles the aligned case
-	 *
-	 * Construct Mask with 1 bits where the field is, 0 bits elsewhere
-	 * (Only the bottom 5 bits of bit_length are valid for a shift operation)
-	 *
-	 * Mask off bits that are "below" the field (if any)
-	 */
-	mask = ACPI_MASK_BITS_BELOW (obj_desc->common_field.start_field_bit_offset);
-
-	/* If the field fits in one datum, may need to mask upper bits */
-
-	if ((obj_desc->common_field.flags & AOPOBJ_SINGLE_DATUM) &&
-		 obj_desc->common_field.end_field_valid_bits) {
-		/* There are bits above the field, mask them off also */
+	if (buffer_length < ACPI_ROUND_BITS_UP_TO_BYTES (
+			 obj_desc->common_field.bit_length)) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Field size %X (bits) is too large for buffer (%X)\n",
+			obj_desc->common_field.bit_length, buffer_length));
 
-		mask &= ACPI_MASK_BITS_ABOVE (obj_desc->common_field.end_field_valid_bits);
+		return_ACPI_STATUS (AE_BUFFER_OVERFLOW);
 	}
 
-	/* Shift and mask the value into the field position */
+	/* Compute the number of datums (access width data items) */
 
-	merged_datum = (previous_raw_datum << obj_desc->common_field.start_field_bit_offset);
-	merged_datum &= mask;
-
-	/* Apply the update rule (if necessary) and write the datum to the field */
+	mask = ACPI_MASK_BITS_BELOW (obj_desc->common_field.start_field_bit_offset);
+	datum_count = ACPI_ROUND_UP_TO (obj_desc->common_field.bit_length,
+			  obj_desc->common_field.access_bit_width);
+	field_datum_count = ACPI_ROUND_UP_TO (obj_desc->common_field.bit_length +
+			   obj_desc->common_field.start_field_bit_offset,
+			   obj_desc->common_field.access_bit_width);
 
-	status = acpi_ex_write_with_update_rule (obj_desc, mask, merged_datum,
-			   field_datum_byte_offset);
-	if (ACPI_FAILURE (status)) {
-		return_ACPI_STATUS (status);
-	}
+	/* Get initial Datum from the input buffer */
 
-	/* We just wrote the first datum */
+	ACPI_MEMCPY (&raw_datum, buffer,
+		ACPI_MIN(obj_desc->common_field.access_byte_width,
+				 buffer_length - buffer_offset));
 
-	datum_offset++;
+	merged_datum = raw_datum << obj_desc->common_field.start_field_bit_offset;
 
-	/* If the entire field fits within one datum, we are done. */
+	/* Write the entire field */
 
-	if ((datum_count == 1) &&
-	   (obj_desc->common_field.flags & AOPOBJ_SINGLE_DATUM)) {
-		return_ACPI_STATUS (AE_OK);
-	}
+	for (i = 1; i < field_datum_count; i++) {
+		/* Write merged datum to the target field */
 
-	/*
-	 * Part2:
-	 * Write the aligned data.
-	 *
-	 * We don't need to worry about the update rule for these data, because
-	 * all of the bits in each datum are part of the field.
-	 *
-	 * The last datum must be special cased because it might contain bits
-	 * that are not part of the field -- therefore the "update rule" must be
-	 * applied in Part3 below.
-	 */
-	while (datum_offset < datum_count) {
-		field_datum_byte_offset += obj_desc->common_field.access_byte_width;
+		merged_datum &= mask;
+		status = acpi_ex_write_with_update_rule (obj_desc, mask, merged_datum, field_offset);
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
 
-		/*
-		 * Get the next raw buffer datum.  It may contain bits of the previous
-		 * field datum
-		 */
-		acpi_ex_get_buffer_datum (&this_raw_datum, buffer, buffer_length,
-				obj_desc->common_field.access_byte_width, datum_offset);
+		/* Start new output datum by merging with previous input datum */
 
-		/* Create the field datum based on the field alignment */
+		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);
+		mask = ACPI_INTEGER_MAX;
 
-		if (obj_desc->common_field.start_field_bit_offset != 0) {
-			/*
-			 * Put together appropriate bits of the two raw buffer data to make
-			 * a single complete field datum
-			 */
-			merged_datum =
-				(previous_raw_datum >> obj_desc->common_field.datum_valid_bits) |
-				(this_raw_datum << obj_desc->common_field.start_field_bit_offset);
+		if (i == datum_count) {
+			break;
 		}
-		else {
-			/* Field began aligned on datum boundary */
 
-			merged_datum = this_raw_datum;
-		}
+		/* Get the next input datum from the buffer */
 
-		/*
-		 * Special handling for the last datum if the field does NOT end on
-		 * a datum boundary.  Update Rule must be applied to the bits outside
-		 * the field.
-		 */
-		datum_offset++;
-		if ((datum_offset == datum_count) &&
-			(obj_desc->common_field.end_field_valid_bits)) {
-			/*
-			 * If there are dangling non-aligned bits, perform one more merged write
-			 * Else - field is aligned at the end, no need for any more writes
-			 */
-
-			/*
-			 * Part3:
-			 * This is the last datum and the field does not end on a datum boundary.
-			 * Build the partial datum and write with the update rule.
-			 *
-			 * Mask off the unused bits above (after) the end-of-field
-			 */
-			mask = ACPI_MASK_BITS_ABOVE (obj_desc->common_field.end_field_valid_bits);
-			merged_datum &= mask;
+		buffer_offset += obj_desc->common_field.access_byte_width;
+		ACPI_MEMCPY (&raw_datum, ((char *) buffer) + buffer_offset,
+			ACPI_MIN(obj_desc->common_field.access_byte_width,
+					 buffer_length - buffer_offset));
+		merged_datum |= raw_datum << obj_desc->common_field.start_field_bit_offset;
+	}
 
-			/* Write the last datum with the update rule */
+	/* Mask off any extra bits in the last datum */
 
-			status = acpi_ex_write_with_update_rule (obj_desc, mask, merged_datum,
-					   field_datum_byte_offset);
-			if (ACPI_FAILURE (status)) {
-				return_ACPI_STATUS (status);
-			}
-		}
-		else {
-			/* Normal (aligned) case -- write the completed 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;
+	if (buffer_tail_bits) {
+		mask &= ACPI_MASK_BITS_ABOVE (buffer_tail_bits);
+	}
 
-			status = acpi_ex_field_datum_io (obj_desc, field_datum_byte_offset,
-					  &merged_datum, ACPI_WRITE);
-			if (ACPI_FAILURE (status)) {
-				return_ACPI_STATUS (status);
-			}
-		}
+	/* Write the last datum to the field */
 
-		/*
-		 * Save the most recent datum since it may contain bits of the *next*
-		 * field datum.  Update current byte offset.
-		 */
-		previous_raw_datum = this_raw_datum;
-	}
+	merged_datum &= mask;
+	status = acpi_ex_write_with_update_rule (obj_desc, mask, merged_datum, field_offset);
 
 	return_ACPI_STATUS (status);
 }
diff -Nru a/drivers/acpi/executer/exmisc.c b/drivers/acpi/executer/exmisc.c
--- a/drivers/acpi/executer/exmisc.c	2005-03-01 23:39:19 -08:00
+++ b/drivers/acpi/executer/exmisc.c	2005-03-01 23:39:19 -08:00
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -389,7 +389,7 @@
 	if (local_operand1 != operand1) {
 		acpi_ut_remove_reference (local_operand1);
 	}
-	return_ACPI_STATUS (AE_OK);
+	return_ACPI_STATUS (status);
 }
 
 
diff -Nru a/drivers/acpi/executer/exmutex.c b/drivers/acpi/executer/exmutex.c
--- a/drivers/acpi/executer/exmutex.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/acpi/executer/exmutex.c	2005-03-01 23:39:09 -08:00
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/executer/exnames.c b/drivers/acpi/executer/exnames.c
--- a/drivers/acpi/executer/exnames.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/acpi/executer/exnames.c	2005-03-01 23:38:54 -08:00
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/executer/exoparg1.c b/drivers/acpi/executer/exoparg1.c
--- a/drivers/acpi/executer/exoparg1.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/acpi/executer/exoparg1.c	2005-03-01 23:39:16 -08:00
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -507,6 +507,10 @@
 
 		status = acpi_ex_convert_to_string (operand[0], &return_desc,
 				 ACPI_EXPLICIT_CONVERT_DECIMAL);
+		if (return_desc == operand[0]) {
+			/* No conversion performed, add ref to handle return value */
+			acpi_ut_add_reference (return_desc);
+		}
 		break;
 
 
@@ -514,12 +518,20 @@
 
 		status = acpi_ex_convert_to_string (operand[0], &return_desc,
 				 ACPI_EXPLICIT_CONVERT_HEX);
+		if (return_desc == operand[0]) {
+			/* No conversion performed, add ref to handle return value */
+			acpi_ut_add_reference (return_desc);
+		}
 		break;
 
 
 	case AML_TO_BUFFER_OP:          /* to_buffer (Data, Result) */
 
 		status = acpi_ex_convert_to_buffer (operand[0], &return_desc);
+		if (return_desc == operand[0]) {
+			/* No conversion performed, add ref to handle return value */
+			acpi_ut_add_reference (return_desc);
+		}
 		break;
 
 
@@ -527,6 +539,10 @@
 
 		status = acpi_ex_convert_to_integer (operand[0], &return_desc,
 				 ACPI_ANY_BASE);
+		if (return_desc == operand[0]) {
+			/* No conversion performed, add ref to handle return value */
+			acpi_ut_add_reference (return_desc);
+		}
 		break;
 
 
@@ -551,10 +567,12 @@
 		goto cleanup;
 	}
 
-	/*
-	 * Store the return value computed above into the target object
-	 */
-	status = acpi_ex_store (return_desc, operand[1], walk_state);
+	if (ACPI_SUCCESS (status)) {
+		/*
+		 * Store the return value computed above into the target object
+		 */
+		status = acpi_ex_store (return_desc, operand[1], walk_state);
+	}
 
 
 cleanup:
diff -Nru a/drivers/acpi/executer/exoparg2.c b/drivers/acpi/executer/exoparg2.c
--- a/drivers/acpi/executer/exoparg2.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/acpi/executer/exoparg2.c	2005-03-01 23:38:57 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -410,7 +410,7 @@
 		index = (u32) operand[1]->integer.value;
 
 		/*
-		 * At this point, the Source operand is either a Package or a Buffer
+		 * 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 */
@@ -428,7 +428,7 @@
 			return_desc->reference.where     = &operand[0]->package.elements [index];
 		}
 		else {
-			/* Object to be indexed is a Buffer */
+			/* Object to be indexed is a Buffer/String */
 
 			if (index >= operand[0]->buffer.length) {
 				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
diff -Nru a/drivers/acpi/executer/exoparg3.c b/drivers/acpi/executer/exoparg3.c
--- a/drivers/acpi/executer/exoparg3.c	2005-03-01 23:38:44 -08:00
+++ b/drivers/acpi/executer/exoparg3.c	2005-03-01 23:38:44 -08:00
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -218,6 +218,10 @@
 			return_desc->string.pointer = buffer;
 			return_desc->string.length = (u32) length;
 		}
+
+		/* Mark buffer initialized */
+
+		return_desc->buffer.flags |= AOPOBJ_DATA_VALID;
 		break;
 
 
diff -Nru a/drivers/acpi/executer/exoparg6.c b/drivers/acpi/executer/exoparg6.c
--- a/drivers/acpi/executer/exoparg6.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/acpi/executer/exoparg6.c	2005-03-01 23:39:08 -08:00
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -81,75 +81,119 @@
  * FUNCTION:    acpi_ex_do_match
  *
  * PARAMETERS:  match_op        - The AML match operand
- *              package_value   - Value from the target package
- *              match_value     - Value to be matched
+ *              package_obj     - Object from the target package
+ *              match_obj       - Object to be matched
  *
  * RETURN:      TRUE if the match is successful, FALSE otherwise
  *
- * DESCRIPTION: Implements the low-level match for the ASL Match operator
+ * DESCRIPTION: Implements the low-level match for the ASL Match operator.
+ *              Package elements will be implicitly converted to the type of
+ *              the match object (Integer/Buffer/String).
  *
  ******************************************************************************/
 
 u8
 acpi_ex_do_match (
 	u32                             match_op,
-	acpi_integer                    package_value,
-	acpi_integer                    match_value)
+	union acpi_operand_object       *package_obj,
+	union acpi_operand_object       *match_obj)
 {
+	u8                              logical_result = TRUE;
+	acpi_status                     status;
 
+
+	/*
+	 * Note: Since the package_obj/match_obj ordering is opposite to that of
+	 * the standard logical operators, we have to reverse them when we call
+	 * do_logical_op in order to make the implicit conversion rules work
+	 * correctly. However, this means we have to flip the entire equation
+	 * also. A bit ugly perhaps, but overall, better than fussing the
+	 * parameters around at runtime, over and over again.
+	 *
+	 * Below, P[i] refers to the package element, M refers to the Match object.
+	 */
 	switch (match_op) {
-	case MATCH_MTR:   /* always true */
+	case MATCH_MTR:
 
-		break;
+		/* Always true */
 
+		break;
 
-	case MATCH_MEQ:   /* true if equal   */
+	case MATCH_MEQ:
 
-		if (package_value != match_value) {
+		/*
+		 * True if equal: (P[i] == M)
+		 * Change to:     (M == P[i])
+		 */
+		status = acpi_ex_do_logical_op (AML_LEQUAL_OP, match_obj, package_obj,
+				 &logical_result);
+		if (ACPI_FAILURE (status)) {
 			return (FALSE);
 		}
 		break;
 
+	case MATCH_MLE:
 
-	case MATCH_MLE:   /* true if less than or equal  */
-
-		if (package_value > match_value) {
+		/*
+		 * True if less than or equal: (P[i] <= M) (P[i] not_greater than M)
+		 * Change to:                  (M >= P[i]) (M not_less than P[i])
+		 */
+		status = acpi_ex_do_logical_op (AML_LLESS_OP, match_obj, package_obj,
+				 &logical_result);
+		if (ACPI_FAILURE (status)) {
 			return (FALSE);
 		}
+		logical_result = (u8) !logical_result;
 		break;
 
+	case MATCH_MLT:
 
-	case MATCH_MLT:   /* true if less than   */
-
-		if (package_value >= match_value) {
+		/*
+		 * True if less than: (P[i] < M)
+		 * Change to:         (M > P[i])
+		 */
+		status = acpi_ex_do_logical_op (AML_LGREATER_OP, match_obj, package_obj,
+				 &logical_result);
+		if (ACPI_FAILURE (status)) {
 			return (FALSE);
 		}
 		break;
 
+	case MATCH_MGE:
 
-	case MATCH_MGE:   /* true if greater than or equal   */
-
-		if (package_value < match_value) {
+		/*
+		 * True if greater than or equal: (P[i] >= M) (P[i] not_less than M)
+		 * Change to:                     (M <= P[i]) (M not_greater than P[i])
+		 */
+		status = acpi_ex_do_logical_op (AML_LGREATER_OP, match_obj, package_obj,
+				 &logical_result);
+		if (ACPI_FAILURE (status)) {
 			return (FALSE);
 		}
+		logical_result = (u8)!logical_result;
 		break;
 
+	case MATCH_MGT:
 
-	case MATCH_MGT:   /* true if greater than    */
-
-		if (package_value <= match_value) {
+		/*
+		 * True if greater than: (P[i] > M)
+		 * Change to:            (M < P[i])
+		 */
+		status = acpi_ex_do_logical_op (AML_LLESS_OP, match_obj, package_obj,
+				 &logical_result);
+		if (ACPI_FAILURE (status)) {
 			return (FALSE);
 		}
 		break;
 
+	default:
 
-	default:    /* undefined   */
+		/* Undefined */
 
 		return (FALSE);
 	}
 
-
-	return TRUE;
+	return logical_result;
 }
 
 
@@ -182,19 +226,21 @@
 	switch (walk_state->opcode) {
 	case AML_MATCH_OP:
 		/*
-		 * Match (search_package[0], match_op1[1], match_object1[2],
-		 *                          match_op2[3], match_object2[4], start_index[5])
+		 * Match (search_pkg[0], match_op1[1], match_obj1[2],
+		 *                      match_op2[3], match_obj2[4], start_index[5])
 		 */
 
-		/* Validate match comparison sub-opcodes */
+		/* Validate both Match Term Operators (MTR, MEQ, etc.) */
 
 		if ((operand[1]->integer.value > MAX_MATCH_OPERATOR) ||
 			(operand[3]->integer.value > MAX_MATCH_OPERATOR)) {
-			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "operation encoding out of range\n"));
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Match operator out of range\n"));
 			status = AE_AML_OPERAND_VALUE;
 			goto cleanup;
 		}
 
+		/* 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"));
@@ -202,6 +248,8 @@
 			goto cleanup;
 		}
 
+		/* Create an integer for the return value */
+
 		return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
 		if (!return_desc) {
 			status = AE_NO_MEMORY;
@@ -214,37 +262,39 @@
 		return_desc->integer.value = ACPI_INTEGER_MAX;
 
 		/*
-		 * Examine each element until a match is found.  Within the loop,
+		 * Examine each element until a match is found. Both match conditions
+		 * must be satisfied for a match to occur. Within the loop,
 		 * "continue" signifies that the current element does not match
 		 * and the next should be examined.
 		 *
 		 * Upon finding a match, the loop will terminate via "break" at
-		 * the bottom.  If it terminates "normally", match_value will be -1
-		 * (its initial value) indicating that no match was found.  When
-		 * returned as a Number, this will produce the Ones value as specified.
+		 * the bottom.  If it terminates "normally", match_value will be
+		 * ACPI_INTEGER_MAX (Ones) (its initial value) indicating that no
+		 * match was found.
 		 */
 		for ( ; index < operand[0]->package.count; index++) {
+			/* Get the current package element */
+
 			this_element = operand[0]->package.elements[index];
 
-			/*
-			 * Treat any NULL or non-numeric elements as non-matching.
-			 */
-			if (!this_element ||
-				ACPI_GET_OBJECT_TYPE (this_element) != ACPI_TYPE_INTEGER) {
+			/* Treat any uninitialized (NULL) elements as non-matching */
+
+			if (!this_element) {
 				continue;
 			}
 
 			/*
-			 * "continue" (proceed to next iteration of enclosing
-			 * "for" loop) signifies a non-match.
+			 * Both match conditions must be satisfied. Execution of a continue
+			 * (proceed to next iteration of enclosing for loop) signifies a
+			 * non-match.
 			 */
 			if (!acpi_ex_do_match ((u32) operand[1]->integer.value,
-					   this_element->integer.value, operand[2]->integer.value)) {
+					   this_element, operand[2])) {
 				continue;
 			}
 
 			if (!acpi_ex_do_match ((u32) operand[3]->integer.value,
-					   this_element->integer.value, operand[4]->integer.value)) {
+					   this_element, operand[4])) {
 				continue;
 			}
 
@@ -253,7 +303,6 @@
 			return_desc->integer.value = index;
 			break;
 		}
-
 		break;
 
 
diff -Nru a/drivers/acpi/executer/exprep.c b/drivers/acpi/executer/exprep.c
--- a/drivers/acpi/executer/exprep.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/acpi/executer/exprep.c	2005-03-01 23:38:53 -08:00
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -339,6 +339,8 @@
 	obj_desc->common_field.access_byte_width = (u8)
 			ACPI_DIV_8 (access_bit_width); /* 1, 2, 4,  8 */
 
+	obj_desc->common_field.access_bit_width = (u8) access_bit_width;
+
 	/*
 	 * base_byte_offset is the address of the start of the field within the
 	 * region.  It is the byte address of the first *datum* (field-width data
@@ -360,28 +362,6 @@
 	 */
 	obj_desc->common_field.start_field_bit_offset = (u8)
 		(field_bit_position - ACPI_MUL_8 (obj_desc->common_field.base_byte_offset));
-
-	/*
-	 * Valid bits -- the number of bits that compose a partial datum,
-	 * 1) At the end of the field within the region (arbitrary starting bit
-	 *    offset)
-	 * 2) At the end of a buffer used to contain the field (starting offset
-	 *    always zero)
-	 */
-	obj_desc->common_field.end_field_valid_bits = (u8)
-		((obj_desc->common_field.start_field_bit_offset + field_bit_length) %
-				  access_bit_width);
-	/* start_buffer_bit_offset always = 0 */
-
-	obj_desc->common_field.end_buffer_valid_bits = (u8)
-		(field_bit_length % access_bit_width);
-
-	/*
-	 * datum_valid_bits is the number of valid field bits in the first
-	 * field datum.
-	 */
-	obj_desc->common_field.datum_valid_bits  = (u8)
-		(access_bit_width - obj_desc->common_field.start_field_bit_offset);
 
 	/*
 	 * Does the entire field fit within a single field access element? (datum)
diff -Nru a/drivers/acpi/executer/exregion.c b/drivers/acpi/executer/exregion.c
--- a/drivers/acpi/executer/exregion.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/acpi/executer/exregion.c	2005-03-01 23:38:52 -08:00
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/executer/exresnte.c b/drivers/acpi/executer/exresnte.c
--- a/drivers/acpi/executer/exresnte.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/acpi/executer/exresnte.c	2005-03-01 23:38:53 -08:00
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/executer/exresolv.c b/drivers/acpi/executer/exresolv.c
--- a/drivers/acpi/executer/exresolv.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/acpi/executer/exresolv.c	2005-03-01 23:38:55 -08:00
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/executer/exresop.c b/drivers/acpi/executer/exresop.c
--- a/drivers/acpi/executer/exresop.c	2005-03-01 23:39:10 -08:00
+++ b/drivers/acpi/executer/exresop.c	2005-03-01 23:39:10 -08:00
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -312,7 +312,7 @@
 			goto next_operand;
 
 
-		case ARGI_ANYTYPE:
+		case ARGI_DATAREFOBJ:  /* Store operator only */
 
 			/*
 			 * We don't want to resolve index_op reference objects during
@@ -577,6 +577,45 @@
 			default:
 				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
 					"Needed [Region/region_field], found [%s] %p\n",
+					acpi_ut_get_object_type_name (obj_desc), obj_desc));
+
+				return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+			}
+			goto next_operand;
+
+
+		case ARGI_DATAREFOBJ:
+
+			/* Used by the Store() operator only */
+
+			switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
+			case ACPI_TYPE_INTEGER:
+			case ACPI_TYPE_PACKAGE:
+			case ACPI_TYPE_STRING:
+			case ACPI_TYPE_BUFFER:
+			case ACPI_TYPE_BUFFER_FIELD:
+			case ACPI_TYPE_LOCAL_REFERENCE:
+			case ACPI_TYPE_LOCAL_REGION_FIELD:
+			case ACPI_TYPE_LOCAL_BANK_FIELD:
+			case ACPI_TYPE_LOCAL_INDEX_FIELD:
+			case ACPI_TYPE_DDB_HANDLE:
+
+				/* Valid operand */
+				break;
+
+			default:
+
+				if (acpi_gbl_enable_interpreter_slack) {
+					/*
+					 * Enable original behavior of Store(), allowing any and all
+					 * objects as the source operand.  The ACPI spec does not
+					 * allow this, however.
+					 */
+					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));
 
 				return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
diff -Nru a/drivers/acpi/executer/exstore.c b/drivers/acpi/executer/exstore.c
--- a/drivers/acpi/executer/exstore.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/acpi/executer/exstore.c	2005-03-01 23:38:56 -08:00
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -295,56 +295,45 @@
 	switch (index_desc->reference.target_type) {
 	case ACPI_TYPE_PACKAGE:
 		/*
-		 * Storing to a package element is not simple.  The source must be
-		 * evaluated and converted to the type of the destination and then the
-		 * source is copied into the destination - we can't just point to the
-		 * source object.
-		 */
-		/*
+		 * Storing to a package element. Copy the object and replace
+		 * any existing object with the new object. No implicit
+		 * conversion is performed.
+		 *
 		 * The object at *(index_desc->Reference.Where) is the
 		 * element within the package that is to be modified.
 		 * The parent package object is at index_desc->Reference.Object
 		 */
 		obj_desc = *(index_desc->reference.where);
 
-		/* Do the conversion/store */
-
-		status = acpi_ex_store_object_to_object (source_desc, obj_desc, &new_desc,
-				  walk_state);
+		status = acpi_ut_copy_iobject_to_iobject (source_desc, &new_desc, walk_state);
 		if (ACPI_FAILURE (status)) {
-			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
-				"Could not store object to indexed package element\n"));
 			return_ACPI_STATUS (status);
 		}
 
-		/*
-		 * If a new object was created, we must install it as the new
-		 * package element
-		 */
-		if (new_desc != obj_desc) {
-			acpi_ut_remove_reference (obj_desc);
-			*(index_desc->reference.where) = new_desc;
-
-			/* If same as the original source, add a reference */
+		if (obj_desc) {
+			/* Decrement reference count by the ref count of the parent package */
 
-			if (new_desc == source_desc) {
-				acpi_ut_add_reference (new_desc);
+			for (i = 0; i < ((union acpi_operand_object *) index_desc->reference.object)->common.reference_count; i++) {
+				acpi_ut_remove_reference (obj_desc);
 			}
+		}
 
-			/* Increment reference count by the ref count of the parent package -1 */
+		*(index_desc->reference.where) = new_desc;
 
-			for (i = 1; i < ((union acpi_operand_object *) index_desc->reference.object)->common.reference_count; i++) {
-				acpi_ut_add_reference (new_desc);
-			}
+		/* Increment reference 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++) {
+			acpi_ut_add_reference (new_desc);
 		}
+
 		break;
 
 
 	case ACPI_TYPE_BUFFER_FIELD:
 
 		/*
-		 * Store into a Buffer (not actually a real buffer_field) at a
-		 * location defined by an Index.
+		 * Store into a Buffer or String (not actually a real buffer_field)
+		 * at a location defined by an Index.
 		 *
 		 * The first 8-bit element of the source object is written to the
 		 * 8-bit Buffer location defined by the Index destination object,
@@ -352,10 +341,13 @@
 		 */
 
 		/*
-		 * Make sure the target is a Buffer
+		 * Make sure the target is a Buffer or String. An error should
+		 * not happen here, since the reference_object was constructed
+		 * by the INDEX_OP code.
 		 */
 		obj_desc = index_desc->reference.object;
-		if (ACPI_GET_OBJECT_TYPE (obj_desc) != ACPI_TYPE_BUFFER) {
+		if ((ACPI_GET_OBJECT_TYPE (obj_desc) != ACPI_TYPE_BUFFER) &&
+			(ACPI_GET_OBJECT_TYPE (obj_desc) != ACPI_TYPE_STRING)) {
 			return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
 		}
 
@@ -372,13 +364,11 @@
 			break;
 
 		case ACPI_TYPE_BUFFER:
-
-			value = source_desc->buffer.pointer[0];
-			break;
-
 		case ACPI_TYPE_STRING:
 
-			value = (u8) source_desc->string.pointer[0];
+			/* Note: Takes advantage of common string/buffer fields */
+
+			value = source_desc->buffer.pointer[0];
 			break;
 
 		default:
diff -Nru a/drivers/acpi/executer/exstoren.c b/drivers/acpi/executer/exstoren.c
--- a/drivers/acpi/executer/exstoren.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/acpi/executer/exstoren.c	2005-03-01 23:38:52 -08:00
@@ -7,7 +7,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -206,6 +206,7 @@
 {
 	union acpi_operand_object       *actual_src_desc;
 	acpi_status                     status = AE_OK;
+	acpi_object_type                original_src_type;
 
 
 	ACPI_FUNCTION_TRACE_PTR ("ex_store_object_to_object", source_desc);
@@ -222,7 +223,8 @@
 		return_ACPI_STATUS (status);
 	}
 
-	if (ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_GET_OBJECT_TYPE (dest_desc)) {
+	original_src_type = ACPI_GET_OBJECT_TYPE (source_desc);
+	if (original_src_type != ACPI_GET_OBJECT_TYPE (dest_desc)) {
 		/*
 		 * The source type does not match the type of the destination.
 		 * Perform the "implicit conversion" of the source to the current type
@@ -232,15 +234,15 @@
 		 * Otherwise, actual_src_desc is a temporary object to hold the
 		 * converted object.
 		 */
-		status = acpi_ex_convert_to_target_type (ACPI_GET_OBJECT_TYPE (dest_desc), source_desc,
-				  &actual_src_desc, walk_state);
+		status = acpi_ex_convert_to_target_type (ACPI_GET_OBJECT_TYPE (dest_desc),
+				  source_desc, &actual_src_desc, walk_state);
 		if (ACPI_FAILURE (status)) {
 			return_ACPI_STATUS (status);
 		}
 
 		if (source_desc == actual_src_desc) {
 			/*
-			 * No conversion was performed.  Return the source_desc as the
+			 * No conversion was performed. Return the source_desc as the
 			 * new object.
 			 */
 			*new_desc = source_desc;
@@ -269,12 +271,18 @@
 
 	case ACPI_TYPE_BUFFER:
 
-		status = acpi_ex_store_buffer_to_buffer (actual_src_desc, dest_desc);
+		/*
+		 * Note: There is different store behavior depending on the original
+		 * source type
+		 */
+		status = acpi_ex_store_buffer_to_buffer (original_src_type, actual_src_desc,
+				 dest_desc);
 		break;
 
 	case ACPI_TYPE_PACKAGE:
 
-		status = acpi_ut_copy_iobject_to_iobject (actual_src_desc, &dest_desc, walk_state);
+		status = acpi_ut_copy_iobject_to_iobject (actual_src_desc, &dest_desc,
+				 walk_state);
 		break;
 
 	default:
diff -Nru a/drivers/acpi/executer/exstorob.c b/drivers/acpi/executer/exstorob.c
--- a/drivers/acpi/executer/exstorob.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/acpi/executer/exstorob.c	2005-03-01 23:39:16 -08:00
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -66,6 +66,7 @@
 
 acpi_status
 acpi_ex_store_buffer_to_buffer (
+	acpi_object_type                original_src_type,
 	union acpi_operand_object       *source_desc,
 	union acpi_operand_object       *target_desc)
 {
@@ -93,34 +94,42 @@
 			return_ACPI_STATUS (AE_NO_MEMORY);
 		}
 
-		target_desc->common.flags &= ~AOPOBJ_STATIC_POINTER;
 		target_desc->buffer.length = length;
 	}
 
-	/*
-	 * Buffer is a static allocation,
-	 * only place what will fit in the buffer.
-	 */
+	/* Copy source buffer to target buffer */
+
 	if (length <= target_desc->buffer.length) {
 		/* Clear existing buffer and copy in the new one */
 
 		ACPI_MEMSET (target_desc->buffer.pointer, 0, target_desc->buffer.length);
 		ACPI_MEMCPY (target_desc->buffer.pointer, buffer, length);
-	}
-	else {
+
 		/*
-		 * Truncate the source, copy only what will fit
+		 * If the original source was a string, we must truncate the buffer,
+		 * according to the ACPI spec.  Integer-to-Buffer and Buffer-to-Buffer
+		 * copy must not truncate the original buffer.
 		 */
+		if (original_src_type == ACPI_TYPE_STRING) {
+			/* Set the new length of the target */
+
+			target_desc->buffer.length = length;
+		}
+	}
+	else {
+		/* Truncate the source, copy only what will fit */
+
 		ACPI_MEMCPY (target_desc->buffer.pointer, buffer, target_desc->buffer.length);
 
 		ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
-			"Truncating src buffer from %X to %X\n",
+			"Truncating source buffer from %X to %X\n",
 			length, target_desc->buffer.length));
 	}
 
 	/* Copy flags */
 
 	target_desc->buffer.flags = source_desc->buffer.flags;
+	target_desc->common.flags &= ~AOPOBJ_STATIC_POINTER;
 	return_ACPI_STATUS (AE_OK);
 }
 
diff -Nru a/drivers/acpi/executer/exsystem.c b/drivers/acpi/executer/exsystem.c
--- a/drivers/acpi/executer/exsystem.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/acpi/executer/exsystem.c	2005-03-01 23:39:07 -08:00
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/executer/exutils.c b/drivers/acpi/executer/exutils.c
--- a/drivers/acpi/executer/exutils.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/acpi/executer/exutils.c	2005-03-01 23:39:18 -08:00
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/hardware/hwacpi.c b/drivers/acpi/hardware/hwacpi.c
--- a/drivers/acpi/hardware/hwacpi.c	2005-03-01 23:38:44 -08:00
+++ b/drivers/acpi/hardware/hwacpi.c	2005-03-01 23:38:44 -08:00
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/hardware/hwgpe.c b/drivers/acpi/hardware/hwgpe.c
--- a/drivers/acpi/hardware/hwgpe.c	2005-03-01 23:38:51 -08:00
+++ b/drivers/acpi/hardware/hwgpe.c	2005-03-01 23:38:51 -08:00
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/hardware/hwregs.c b/drivers/acpi/hardware/hwregs.c
--- a/drivers/acpi/hardware/hwregs.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/acpi/hardware/hwregs.c	2005-03-01 23:39:09 -08:00
@@ -7,7 +7,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/hardware/hwsleep.c b/drivers/acpi/hardware/hwsleep.c
--- a/drivers/acpi/hardware/hwsleep.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/acpi/hardware/hwsleep.c	2005-03-01 23:38:52 -08:00
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -282,15 +282,6 @@
 		return_ACPI_STATUS (status);
 	}
 
-	if (sleep_state != ACPI_STATE_S5) {
-		/* Disable BM arbitration */
-
-		status = acpi_set_register (ACPI_BITREG_ARB_DISABLE, 1, ACPI_MTX_DO_NOT_LOCK);
-		if (ACPI_FAILURE (status)) {
-			return_ACPI_STATUS (status);
-		}
-	}
-
 	/*
 	 * 1) Disable/Clear all GPEs
 	 * 2) Enable all wakeup GPEs
@@ -580,13 +571,6 @@
 			1, ACPI_MTX_DO_NOT_LOCK);
 	(void) acpi_set_register(acpi_gbl_fixed_event_info[ACPI_EVENT_POWER_BUTTON].status_register_id,
 			1, ACPI_MTX_DO_NOT_LOCK);
-
-	/* Enable BM arbitration */
-
-	status = acpi_set_register (ACPI_BITREG_ARB_DISABLE, 0, ACPI_MTX_LOCK);
-	if (ACPI_FAILURE (status)) {
-		return_ACPI_STATUS (status);
-	}
 
 	arg.integer.value = ACPI_SST_WORKING;
 	status = acpi_evaluate_object (NULL, METHOD_NAME__SST, &arg_list, NULL);
diff -Nru a/drivers/acpi/hardware/hwtimer.c b/drivers/acpi/hardware/hwtimer.c
--- a/drivers/acpi/hardware/hwtimer.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/acpi/hardware/hwtimer.c	2005-03-01 23:38:52 -08:00
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c
--- a/drivers/acpi/ibm_acpi.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/acpi/ibm_acpi.c	2005-03-01 23:39:09 -08:00
@@ -1168,7 +1168,7 @@
 #define IBM_PARAM(feature) \
 	module_param_call(feature, set_ibm_param, NULL, NULL, 0)
 
-static void __exit acpi_ibm_exit(void)
+static void acpi_ibm_exit(void)
 {
 	int i;
 
diff -Nru a/drivers/acpi/namespace/nsaccess.c b/drivers/acpi/namespace/nsaccess.c
--- a/drivers/acpi/namespace/nsaccess.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/acpi/namespace/nsaccess.c	2005-03-01 23:39:16 -08:00
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -155,8 +155,7 @@
 			 */
 			switch (init_val->type) {
 			case ACPI_TYPE_METHOD:
-				obj_desc->method.param_count = (u8) ACPI_STRTOUL
-						  (val, NULL, 10);
+				obj_desc->method.param_count = (u8) ACPI_TO_INTEGER (val);
 				obj_desc->common.flags |= AOPOBJ_DATA_VALID;
 
 #if defined (_ACPI_ASL_COMPILER) || defined (_ACPI_DUMP_App)
@@ -176,8 +175,7 @@
 
 			case ACPI_TYPE_INTEGER:
 
-				obj_desc->integer.value =
-						(acpi_integer) ACPI_STRTOUL (val, NULL, 10);
+				obj_desc->integer.value = ACPI_TO_INTEGER (val);
 				break;
 
 
@@ -195,8 +193,7 @@
 			case ACPI_TYPE_MUTEX:
 
 				obj_desc->mutex.node = new_node;
-				obj_desc->mutex.sync_level = (u8) ACPI_STRTOUL
-						  (val, NULL, 10);
+				obj_desc->mutex.sync_level = (u8) (ACPI_TO_INTEGER (val) - 1);
 
 				if (ACPI_STRCMP (init_val->name, "_GL_") == 0) {
 					/*
diff -Nru a/drivers/acpi/namespace/nsalloc.c b/drivers/acpi/namespace/nsalloc.c
--- a/drivers/acpi/namespace/nsalloc.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/acpi/namespace/nsalloc.c	2005-03-01 23:38:57 -08:00
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/namespace/nsdump.c b/drivers/acpi/namespace/nsdump.c
--- a/drivers/acpi/namespace/nsdump.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/acpi/namespace/nsdump.c	2005-03-01 23:39:16 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/namespace/nsdumpdv.c b/drivers/acpi/namespace/nsdumpdv.c
--- a/drivers/acpi/namespace/nsdumpdv.c	2005-03-01 23:38:44 -08:00
+++ b/drivers/acpi/namespace/nsdumpdv.c	2005-03-01 23:38:44 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/namespace/nseval.c b/drivers/acpi/namespace/nseval.c
--- a/drivers/acpi/namespace/nseval.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/acpi/namespace/nseval.c	2005-03-01 23:38:56 -08:00
@@ -6,7 +6,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/namespace/nsinit.c b/drivers/acpi/namespace/nsinit.c
--- a/drivers/acpi/namespace/nsinit.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/acpi/namespace/nsinit.c	2005-03-01 23:38:55 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -420,6 +420,12 @@
 		status = AE_OK;
 	}
 	else {
+		/* Delete any return object (especially if implicit_return is enabled) */
+
+		if (pinfo.return_object) {
+			acpi_ut_remove_reference (pinfo.return_object);
+		}
+
 		/* Count of successful INIs */
 
 		info->num_INI++;
diff -Nru a/drivers/acpi/namespace/nsload.c b/drivers/acpi/namespace/nsload.c
--- a/drivers/acpi/namespace/nsload.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/acpi/namespace/nsload.c	2005-03-01 23:39:16 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/namespace/nsnames.c b/drivers/acpi/namespace/nsnames.c
--- a/drivers/acpi/namespace/nsnames.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/acpi/namespace/nsnames.c	2005-03-01 23:39:18 -08:00
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/namespace/nsobject.c b/drivers/acpi/namespace/nsobject.c
--- a/drivers/acpi/namespace/nsobject.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/acpi/namespace/nsobject.c	2005-03-01 23:38:55 -08:00
@@ -6,7 +6,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/namespace/nsparse.c b/drivers/acpi/namespace/nsparse.c
--- a/drivers/acpi/namespace/nsparse.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/acpi/namespace/nsparse.c	2005-03-01 23:38:52 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/namespace/nssearch.c b/drivers/acpi/namespace/nssearch.c
--- a/drivers/acpi/namespace/nssearch.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/acpi/namespace/nssearch.c	2005-03-01 23:39:16 -08:00
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/namespace/nsutils.c b/drivers/acpi/namespace/nsutils.c
--- a/drivers/acpi/namespace/nsutils.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/acpi/namespace/nsutils.c	2005-03-01 23:38:57 -08:00
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/namespace/nswalk.c b/drivers/acpi/namespace/nswalk.c
--- a/drivers/acpi/namespace/nswalk.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/acpi/namespace/nswalk.c	2005-03-01 23:39:17 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/namespace/nsxfeval.c b/drivers/acpi/namespace/nsxfeval.c
--- a/drivers/acpi/namespace/nsxfeval.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/acpi/namespace/nsxfeval.c	2005-03-01 23:39:17 -08:00
@@ -6,7 +6,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/namespace/nsxfname.c b/drivers/acpi/namespace/nsxfname.c
--- a/drivers/acpi/namespace/nsxfname.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/acpi/namespace/nsxfname.c	2005-03-01 23:39:18 -08:00
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -237,7 +237,7 @@
 {
 	acpi_status                     status;
 	struct acpi_namespace_node      *node;
-	struct acpi_device_info         info;
+	struct acpi_device_info         *info;
 	struct acpi_device_info         *return_info;
 	struct acpi_compatible_id_list *cid_list = NULL;
 	acpi_size                       size;
@@ -254,55 +254,59 @@
 		return (status);
 	}
 
+	info = ACPI_MEM_CALLOCATE (sizeof (struct acpi_device_info));
+	if (!info) {
+		return (AE_NO_MEMORY);
+	}
+
 	status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
 	if (ACPI_FAILURE (status)) {
-		return (status);
+		goto cleanup;
 	}
 
 	node = acpi_ns_map_handle_to_node (handle);
 	if (!node) {
 		(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
-		return (AE_BAD_PARAMETER);
+		goto cleanup;
 	}
 
 	/* Init return structure */
 
 	size = sizeof (struct acpi_device_info);
-	ACPI_MEMSET (&info, 0, size);
 
-	info.type  = node->type;
-	info.name  = node->name.integer;
-	info.valid = 0;
+	info->type  = node->type;
+	info->name  = node->name.integer;
+	info->valid = 0;
 
 	status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
 	if (ACPI_FAILURE (status)) {
-		return (status);
+		goto cleanup;
 	}
 
 	/* If not a device, we are all done */
 
-	if (info.type == ACPI_TYPE_DEVICE) {
+	if (info->type == ACPI_TYPE_DEVICE) {
 		/*
 		 * Get extra info for ACPI Devices objects only:
 		 * Run the Device _HID, _UID, _CID, _STA, _ADR and _sx_d methods.
 		 *
 		 * Note: none of these methods are required, so they may or may
-		 * not be present for this device.  The Info.Valid bitfield is used
+		 * not be present for this device.  The Info->Valid bitfield is used
 		 * to indicate which methods were found and ran successfully.
 		 */
 
 		/* Execute the Device._HID method */
 
-		status = acpi_ut_execute_HID (node, &info.hardware_id);
+		status = acpi_ut_execute_HID (node, &info->hardware_id);
 		if (ACPI_SUCCESS (status)) {
-			info.valid |= ACPI_VALID_HID;
+			info->valid |= ACPI_VALID_HID;
 		}
 
 		/* Execute the Device._UID method */
 
-		status = acpi_ut_execute_UID (node, &info.unique_id);
+		status = acpi_ut_execute_UID (node, &info->unique_id);
 		if (ACPI_SUCCESS (status)) {
-			info.valid |= ACPI_VALID_UID;
+			info->valid |= ACPI_VALID_UID;
 		}
 
 		/* Execute the Device._CID method */
@@ -311,32 +315,30 @@
 		if (ACPI_SUCCESS (status)) {
 			size += ((acpi_size) cid_list->count - 1) *
 					 sizeof (struct acpi_compatible_id);
-			info.valid |= ACPI_VALID_CID;
+			info->valid |= ACPI_VALID_CID;
 		}
 
 		/* Execute the Device._STA method */
 
-		status = acpi_ut_execute_STA (node, &info.current_status);
+		status = acpi_ut_execute_STA (node, &info->current_status);
 		if (ACPI_SUCCESS (status)) {
-			info.valid |= ACPI_VALID_STA;
+			info->valid |= ACPI_VALID_STA;
 		}
 
 		/* Execute the Device._ADR method */
 
 		status = acpi_ut_evaluate_numeric_object (METHOD_NAME__ADR, node,
-				  &info.address);
+				  &info->address);
 		if (ACPI_SUCCESS (status)) {
-			info.valid |= ACPI_VALID_ADR;
+			info->valid |= ACPI_VALID_ADR;
 		}
 
 		/* Execute the Device._sx_d methods */
 
-		status = acpi_ut_execute_sxds (node, info.highest_dstates);
+		status = acpi_ut_execute_sxds (node, info->highest_dstates);
 		if (ACPI_SUCCESS (status)) {
-			info.valid |= ACPI_VALID_SXDS;
+			info->valid |= ACPI_VALID_SXDS;
 		}
-
-		status = AE_OK;
 	}
 
 	/* Validate/Allocate/Clear caller buffer */
@@ -349,7 +351,7 @@
 	/* Populate the return buffer */
 
 	return_info = buffer->pointer;
-	ACPI_MEMCPY (return_info, &info, sizeof (struct acpi_device_info));
+	ACPI_MEMCPY (return_info, info, sizeof (struct acpi_device_info));
 
 	if (cid_list) {
 		ACPI_MEMCPY (&return_info->compatibility_id, cid_list, cid_list->size);
@@ -357,6 +359,7 @@
 
 
 cleanup:
+	ACPI_MEM_FREE (info);
 	if (cid_list) {
 		ACPI_MEM_FREE (cid_list);
 	}
diff -Nru a/drivers/acpi/namespace/nsxfobj.c b/drivers/acpi/namespace/nsxfobj.c
--- a/drivers/acpi/namespace/nsxfobj.c	2005-03-01 23:38:43 -08:00
+++ b/drivers/acpi/namespace/nsxfobj.c	2005-03-01 23:38:43 -08:00
@@ -6,7 +6,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/numa.c b/drivers/acpi/numa.c
--- a/drivers/acpi/numa.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/acpi/numa.c	2005-03-01 23:39:18 -08:00
@@ -22,7 +22,7 @@
  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  *
  */
-
+#include <linux/module.h>
 #include <linux/config.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
@@ -184,18 +184,30 @@
 		result = acpi_table_parse_srat(ACPI_SRAT_MEMORY_AFFINITY,
 					       acpi_parse_memory_affinity,
 					       NR_NODE_MEMBLKS);	// IA64 specific
-	} else {
-		/* FIXME */
-		printk("Warning: acpi_table_parse(ACPI_SRAT) returned %d!\n",result);
 	}
 
 	/* SLIT: System Locality Information Table */
 	result = acpi_table_parse(ACPI_SLIT, acpi_parse_slit);
-	if (result < 1) {
-		/* FIXME */
-		printk("Warning: acpi_table_parse(ACPI_SLIT) returned %d!\n",result);
-	}
 
 	acpi_numa_arch_fixup();
 	return 0;
 }
+
+int
+acpi_get_pxm(acpi_handle h)
+{
+	unsigned long pxm;
+	acpi_status status;
+	acpi_handle handle;
+	acpi_handle phandle = h;
+
+	do {
+		handle = phandle;
+		status = acpi_evaluate_integer(handle, "_PXM", NULL, &pxm);
+		if (ACPI_SUCCESS(status))
+			return (int)pxm;
+		status = acpi_get_parent(handle, &phandle);
+	} while(ACPI_SUCCESS(status));
+	return -1;
+}
+EXPORT_SYMBOL(acpi_get_pxm);
diff -Nru a/drivers/acpi/osl.c b/drivers/acpi/osl.c
--- a/drivers/acpi/osl.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/acpi/osl.c	2005-03-01 23:39:09 -08:00
@@ -40,6 +40,7 @@
 #include <acpi/acpi.h>
 #include <asm/io.h>
 #include <acpi/acpi_bus.h>
+#include <acpi/processor.h>
 #include <asm/uaccess.h>
 
 #include <linux/efi.h>
@@ -356,7 +357,7 @@
 	if (!t)
 		printk(KERN_ERR PREFIX "acpi_os_get_timer() TBD\n");
 
-	return(++t);
+	return ++t;
 }
 
 acpi_status
@@ -635,7 +636,7 @@
 	acpi_integer		value,
 	u32			width)
 {
-	return (AE_SUPPORT);
+	return AE_SUPPORT;
 }
 
 acpi_status
@@ -645,7 +646,7 @@
 	void			*value,
 	u32			width)
 {
-	return (AE_SUPPORT);
+	return AE_SUPPORT;
 }
 
 void
@@ -1155,7 +1156,7 @@
  * max_cstate is defined in the base kernel so modules can
  * change it w/o depending on the state of the processor module.
  */
-unsigned int max_cstate = ACPI_C_STATES_MAX;
+unsigned int max_cstate = ACPI_PROCESSOR_MAX_POWER;
 
 
 EXPORT_SYMBOL(max_cstate);
diff -Nru a/drivers/acpi/parser/psargs.c b/drivers/acpi/parser/psargs.c
--- a/drivers/acpi/parser/psargs.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/acpi/parser/psargs.c	2005-03-01 23:38:54 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/parser/psopcode.c b/drivers/acpi/parser/psopcode.c
--- a/drivers/acpi/parser/psopcode.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/acpi/parser/psopcode.c	2005-03-01 23:38:53 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -289,7 +289,7 @@
 #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_INTEGER,      ARGI_INTEGER,   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)
@@ -318,11 +318,11 @@
 #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_REFERENCE) /* Force delay of operand resolution */
+#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_ANYTYPE,    ARGI_TARGETREF)
+#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
@@ -333,7 +333,7 @@
 #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_REFERENCE) /* Force delay of operand resolution */
+#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)
@@ -521,14 +521,14 @@
 /* 2D */ ACPI_OP ("FindSetRightBit",    ARGP_FIND_SET_RIGHT_BIT_OP,ARGI_FIND_SET_RIGHT_BIT_OP, ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_1A_1T_1R,   AML_FLAGS_EXEC_1A_1T_1R | AML_CONSTANT),
 /* 2E */ ACPI_OP ("DerefOf",            ARGP_DEREF_OF_OP,          ARGI_DEREF_OF_OP,           ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_1A_0T_1R,   AML_FLAGS_EXEC_1A_0T_1R),
 /* 2F */ ACPI_OP ("Notify",             ARGP_NOTIFY_OP,            ARGI_NOTIFY_OP,             ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_2A_0T_0R,   AML_FLAGS_EXEC_2A_0T_0R),
-/* 30 */ ACPI_OP ("SizeOf",             ARGP_SIZE_OF_OP,           ARGI_SIZE_OF_OP,            ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_1A_0T_1R,   AML_FLAGS_EXEC_1A_0T_1R),
+/* 30 */ ACPI_OP ("SizeOf",             ARGP_SIZE_OF_OP,           ARGI_SIZE_OF_OP,            ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_1A_0T_1R,   AML_FLAGS_EXEC_1A_0T_1R | AML_NO_OPERAND_RESOLVE),
 /* 31 */ ACPI_OP ("Index",              ARGP_INDEX_OP,             ARGI_INDEX_OP,              ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_2A_1T_1R,   AML_FLAGS_EXEC_2A_1T_1R | AML_CONSTANT),
 /* 32 */ ACPI_OP ("Match",              ARGP_MATCH_OP,             ARGI_MATCH_OP,              ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_6A_0T_1R,   AML_FLAGS_EXEC_6A_0T_1R | AML_CONSTANT),
 /* 33 */ ACPI_OP ("CreateDWordField",   ARGP_CREATE_DWORD_FIELD_OP,ARGI_CREATE_DWORD_FIELD_OP, ACPI_TYPE_BUFFER_FIELD,      AML_CLASS_CREATE,          AML_TYPE_CREATE_FIELD,    AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE | AML_DEFER | AML_CREATE),
 /* 34 */ ACPI_OP ("CreateWordField",    ARGP_CREATE_WORD_FIELD_OP, ARGI_CREATE_WORD_FIELD_OP,  ACPI_TYPE_BUFFER_FIELD,      AML_CLASS_CREATE,          AML_TYPE_CREATE_FIELD,    AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE | AML_DEFER | AML_CREATE),
 /* 35 */ ACPI_OP ("CreateByteField",    ARGP_CREATE_BYTE_FIELD_OP, ARGI_CREATE_BYTE_FIELD_OP,  ACPI_TYPE_BUFFER_FIELD,      AML_CLASS_CREATE,          AML_TYPE_CREATE_FIELD,    AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE | AML_DEFER | AML_CREATE),
 /* 36 */ ACPI_OP ("CreateBitField",     ARGP_CREATE_BIT_FIELD_OP,  ARGI_CREATE_BIT_FIELD_OP,   ACPI_TYPE_BUFFER_FIELD,      AML_CLASS_CREATE,          AML_TYPE_CREATE_FIELD,    AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE | AML_DEFER | AML_CREATE),
-/* 37 */ ACPI_OP ("ObjectType",         ARGP_TYPE_OP,              ARGI_TYPE_OP,               ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_1A_0T_1R,   AML_FLAGS_EXEC_1A_0T_1R),
+/* 37 */ ACPI_OP ("ObjectType",         ARGP_TYPE_OP,              ARGI_TYPE_OP,               ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_1A_0T_1R,   AML_FLAGS_EXEC_1A_0T_1R | AML_NO_OPERAND_RESOLVE),
 /* 38 */ ACPI_OP ("LAnd",               ARGP_LAND_OP,              ARGI_LAND_OP,               ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_2A_0T_1R,   AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL_NUMERIC | AML_CONSTANT),
 /* 39 */ ACPI_OP ("LOr",                ARGP_LOR_OP,               ARGI_LOR_OP,                ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_2A_0T_1R,   AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL_NUMERIC | AML_CONSTANT),
 /* 3A */ ACPI_OP ("LNot",               ARGP_LNOT_OP,              ARGI_LNOT_OP,               ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_1A_0T_1R,   AML_FLAGS_EXEC_1A_0T_1R | AML_CONSTANT),
diff -Nru a/drivers/acpi/parser/psparse.c b/drivers/acpi/parser/psparse.c
--- a/drivers/acpi/parser/psparse.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/acpi/parser/psparse.c	2005-03-01 23:38:53 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/parser/psscope.c b/drivers/acpi/parser/psscope.c
--- a/drivers/acpi/parser/psscope.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/acpi/parser/psscope.c	2005-03-01 23:38:52 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/parser/pstree.c b/drivers/acpi/parser/pstree.c
--- a/drivers/acpi/parser/pstree.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/acpi/parser/pstree.c	2005-03-01 23:38:54 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/parser/psutils.c b/drivers/acpi/parser/psutils.c
--- a/drivers/acpi/parser/psutils.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/acpi/parser/psutils.c	2005-03-01 23:38:58 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -208,6 +208,7 @@
 }
 
 
+#ifdef ACPI_ENABLE_OBJECT_CACHE
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ps_delete_parse_cache
@@ -231,6 +232,7 @@
 	acpi_ut_delete_generic_cache (ACPI_MEM_LIST_PSNODE_EXT);
 	return_VOID;
 }
+#endif
 
 
 /*******************************************************************************
diff -Nru a/drivers/acpi/parser/pswalk.c b/drivers/acpi/parser/pswalk.c
--- a/drivers/acpi/parser/pswalk.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/acpi/parser/pswalk.c	2005-03-01 23:39:08 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/parser/psxface.c b/drivers/acpi/parser/psxface.c
--- a/drivers/acpi/parser/psxface.c	2005-03-01 23:39:19 -08:00
+++ b/drivers/acpi/parser/psxface.c	2005-03-01 23:39:19 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/pci_bind.c b/drivers/acpi/pci_bind.c
--- a/drivers/acpi/pci_bind.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/acpi/pci_bind.c	2005-03-01 23:39:09 -08:00
@@ -126,8 +126,8 @@
 	acpi_status		status = AE_OK;
 	struct acpi_pci_data	*data = NULL;
 	struct acpi_pci_data	*pdata = NULL;
-	char			pathname[ACPI_PATHNAME_MAX] = {0};
-	struct acpi_buffer	buffer = {ACPI_PATHNAME_MAX, pathname};
+	char			*pathname = NULL;
+	struct acpi_buffer	buffer = {0, NULL};
 	acpi_handle		handle = NULL;
 
 	ACPI_FUNCTION_TRACE("acpi_pci_bind");
@@ -135,9 +135,18 @@
 	if (!device || !device->parent)
 		return_VALUE(-EINVAL);
 
+	pathname = kmalloc(ACPI_PATHNAME_MAX, GFP_KERNEL);
+	if(!pathname)
+		return_VALUE(-ENOMEM);
+	memset(pathname, 0, ACPI_PATHNAME_MAX);
+	buffer.length = ACPI_PATHNAME_MAX;
+	buffer.pointer = pathname;
+
 	data = kmalloc(sizeof(struct acpi_pci_data), GFP_KERNEL);
-	if (!data)
+	if (!data){
+		kfree (pathname);
 		return_VALUE(-ENOMEM);
+	}
 	memset(data, 0, sizeof(struct acpi_pci_data));
 
 	acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer);
@@ -216,6 +225,7 @@
 			data->id.device, data->id.function));
 		data->bus = data->dev->subordinate;
 		device->ops.bind = acpi_pci_bind;
+		device->ops.unbind = acpi_pci_unbind;
 	}
 
 	/*
@@ -253,12 +263,64 @@
 	}
 
 end:
+	kfree(pathname);
 	if (result)
 		kfree(data);
 
 	return_VALUE(result);
 }
 
+int acpi_pci_unbind(
+	struct acpi_device      *device)
+{
+	int                     result = 0;
+	acpi_status             status = AE_OK;
+	struct acpi_pci_data    *data = NULL;
+	char                    *pathname = NULL;
+	struct acpi_buffer      buffer = {0, NULL};
+
+	ACPI_FUNCTION_TRACE("acpi_pci_unbind");
+
+	if (!device || !device->parent)
+		return_VALUE(-EINVAL);
+
+	pathname = (char *) kmalloc(ACPI_PATHNAME_MAX, GFP_KERNEL);
+	if(!pathname)
+		return_VALUE(-ENOMEM);
+	memset(pathname, 0, ACPI_PATHNAME_MAX);
+
+	buffer.length = ACPI_PATHNAME_MAX;
+	buffer.pointer = pathname;
+	acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer);
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Unbinding PCI device [%s]...\n",
+		pathname));
+	kfree(pathname);
+
+	status = acpi_get_data(device->handle, acpi_pci_data_handler, (void**)&data);
+	if (ACPI_FAILURE(status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Unable to get data from device %s\n",
+			acpi_device_bid(device)));
+		result = -ENODEV;
+		goto end;
+	}
+
+	status = acpi_detach_data(device->handle, acpi_pci_data_handler);
+	if (ACPI_FAILURE(status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Unable to detach data from device %s\n",
+			acpi_device_bid(device)));
+		result = -ENODEV;
+		goto end;
+	}
+	if (data->dev->subordinate) {
+		acpi_pci_irq_del_prt(data->id.segment, data->bus->number);
+	}
+	kfree(data);
+
+end:
+	return_VALUE(result);
+}
 
 int 
 acpi_pci_bind_root (
@@ -269,22 +331,35 @@
 	int			result = 0;
 	acpi_status		status = AE_OK;
 	struct acpi_pci_data	*data = NULL;
-	char			pathname[ACPI_PATHNAME_MAX] = {0};
-	struct acpi_buffer	buffer = {ACPI_PATHNAME_MAX, pathname};
+	char			*pathname = NULL;
+	struct acpi_buffer	buffer = {0, NULL};
 
 	ACPI_FUNCTION_TRACE("acpi_pci_bind_root");
 
-	if (!device || !id || !bus)
+	pathname = (char *)kmalloc(ACPI_PATHNAME_MAX, GFP_KERNEL);
+	if(!pathname)
+		return_VALUE(-ENOMEM);
+	memset(pathname, 0, ACPI_PATHNAME_MAX);
+
+	buffer.length = ACPI_PATHNAME_MAX;
+	buffer.pointer = pathname;
+
+	if (!device || !id || !bus){
+		kfree(pathname);
 		return_VALUE(-EINVAL);
+	}
 
 	data = kmalloc(sizeof(struct acpi_pci_data), GFP_KERNEL);
-	if (!data)
+	if (!data){
+		kfree(pathname);
 		return_VALUE(-ENOMEM);
+	}
 	memset(data, 0, sizeof(struct acpi_pci_data));
 
 	data->id = *id;
 	data->bus = bus;
 	device->ops.bind = acpi_pci_bind;
+	device->ops.unbind = acpi_pci_unbind;
 
 	acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer);
 
@@ -301,6 +376,7 @@
 	}
 
 end:
+	kfree(pathname);
 	if (result != 0)
 		kfree(data);
 
diff -Nru a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c
--- a/drivers/acpi/pci_irq.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/acpi/pci_irq.c	2005-03-01 23:38:56 -08:00
@@ -43,7 +43,7 @@
 ACPI_MODULE_NAME		("pci_irq")
 
 struct acpi_prt_list		acpi_prt;
-
+DEFINE_SPINLOCK(acpi_prt_lock);
 
 /* --------------------------------------------------------------------------
                          PCI IRQ Routing Table (PRT) Support
@@ -68,18 +68,20 @@
 	 * Parse through all PRT entries looking for a match on the specified
 	 * PCI device's segment, bus, device, and pin (don't care about func).
 	 *
-	 * TBD: Acquire/release lock
 	 */
+	spin_lock(&acpi_prt_lock);
 	list_for_each(node, &acpi_prt.entries) {
 		entry = list_entry(node, struct acpi_prt_entry, node);
 		if ((segment == entry->id.segment) 
 			&& (bus == entry->id.bus) 
 			&& (device == entry->id.device)
 			&& (pin == entry->pin)) {
+			spin_unlock(&acpi_prt_lock);
 			return_PTR(entry);
 		}
 	}
 
+	spin_unlock(&acpi_prt_lock);
 	return_PTR(NULL);
 }
 
@@ -141,14 +143,29 @@
 		entry->id.segment, entry->id.bus, entry->id.device, 
 		('A' + entry->pin), prt->source, entry->link.index));
 
-	/* TBD: Acquire/release lock */
+	spin_lock(&acpi_prt_lock);
 	list_add_tail(&entry->node, &acpi_prt.entries);
 	acpi_prt.count++;
+	spin_unlock(&acpi_prt_lock);
 
 	return_VALUE(0);
 }
 
 
+static void
+acpi_pci_irq_del_entry (
+	int				segment,
+	int				bus,
+	struct acpi_prt_entry		*entry)
+{
+	if (segment == entry->id.segment && bus == entry->id.bus){
+		acpi_prt.count--;
+		list_del(&entry->node);
+		kfree(entry);
+	}
+}
+
+
 int
 acpi_pci_irq_add_prt (
 	acpi_handle		handle,
@@ -156,7 +173,7 @@
 	int			bus)
 {
 	acpi_status			status = AE_OK;
-	char				pathname[ACPI_PATHNAME_MAX] = {0};
+	char				*pathname = NULL;
 	struct acpi_buffer		buffer = {0, NULL};
 	struct acpi_pci_routing_table	*prt = NULL;
 	struct acpi_pci_routing_table	*entry = NULL;
@@ -164,6 +181,11 @@
 
 	ACPI_FUNCTION_TRACE("acpi_pci_irq_add_prt");
 
+	pathname = (char *) kmalloc(ACPI_PATHNAME_MAX, GFP_KERNEL);
+	if(!pathname)
+		return_VALUE(-ENOMEM);
+	memset(pathname, 0, ACPI_PATHNAME_MAX);
+
 	if (first_time) {
 		acpi_prt.count = 0;
 		INIT_LIST_HEAD(&acpi_prt.entries);
@@ -175,7 +197,7 @@
 	 *       (either a PCI root bridge or PCI-PCI bridge).
 	 */
 
-	buffer.length = sizeof(pathname);
+	buffer.length = ACPI_PATHNAME_MAX;
 	buffer.pointer = pathname;
 	acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
 
@@ -188,6 +210,7 @@
 
 	buffer.length = 0;
 	buffer.pointer = NULL;
+	kfree(pathname);
 	status = acpi_get_irq_routing_table(handle, &buffer);
 	if (status != AE_BUFFER_OVERFLOW) {
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PRT [%s]\n",
@@ -196,8 +219,9 @@
 	}
 
 	prt = kmalloc(buffer.length, GFP_KERNEL);
-	if (!prt)
+	if (!prt){
 		return_VALUE(-ENOMEM);
+	}
 	memset(prt, 0, buffer.length);
 	buffer.pointer = prt;
 
@@ -222,7 +246,26 @@
 	return_VALUE(0);
 }
 
+void
+acpi_pci_irq_del_prt (int segment, int bus)
+{
+	struct list_head        *node = NULL, *n = NULL;
+	struct acpi_prt_entry   *entry = NULL;
+
+	if (!acpi_prt.count)    {
+		return;
+	}
 
+	printk(KERN_DEBUG "ACPI: Delete PCI Interrupt Routing Table for %x:%x\n",
+		segment, bus);
+	spin_lock(&acpi_prt_lock);
+	list_for_each_safe(node, n, &acpi_prt.entries) {
+		entry = list_entry(node, struct acpi_prt_entry, node);
+
+		acpi_pci_irq_del_entry(segment, bus, entry);
+	}
+	spin_unlock(&acpi_prt_lock);
+}
 /* --------------------------------------------------------------------------
                           PCI Interrupt Routing Support
    -------------------------------------------------------------------------- */
@@ -345,6 +388,7 @@
 	u8			pin = 0;
 	int			edge_level = ACPI_LEVEL_SENSITIVE;
 	int			active_high_low = ACPI_ACTIVE_LOW;
+	extern int		via_interrupt_line_quirk;
 
 	ACPI_FUNCTION_TRACE("acpi_pci_irq_enable");
 
@@ -394,6 +438,9 @@
 		}
  	}
 
+	if (via_interrupt_line_quirk)
+		pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq & 15);
+
 	dev->irq = acpi_register_gsi(irq, edge_level, active_high_low);
 
 	printk(KERN_INFO PREFIX "PCI interrupt %s[%c] -> GSI %u "
@@ -407,3 +454,55 @@
 }
 EXPORT_SYMBOL(acpi_pci_irq_enable);
 
+
+#ifdef CONFIG_ACPI_DEALLOCATE_IRQ
+void
+acpi_pci_irq_disable (
+	struct pci_dev		*dev)
+{
+	int			gsi = 0;
+	u8			pin = 0;
+	int			edge_level = ACPI_LEVEL_SENSITIVE;
+	int			active_high_low = ACPI_ACTIVE_LOW;
+
+	ACPI_FUNCTION_TRACE("acpi_pci_irq_disable");
+
+	if (!dev)
+		return_VOID;
+
+	pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
+	if (!pin)
+		return_VOID;
+	pin--;
+
+	if (!dev->bus)
+		return_VOID;
+
+	/*
+	 * 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);
+	/*
+	 * 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);
+	if (gsi < 0)
+		return_VOID;
+
+	/*
+	 * TBD: It might be worth clearing dev->irq by magic constant
+	 * (e.g. PCI_UNDEFINED_IRQ).
+	 */
+
+	printk(KERN_INFO PREFIX "PCI interrupt for device %s disabled\n",
+	       pci_name(dev));
+
+	acpi_unregister_gsi(gsi);
+
+	return_VOID;
+}
+#endif /* CONFIG_ACPI_DEALLOCATE_IRQ */
diff -Nru a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c
--- a/drivers/acpi/pci_link.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/acpi/pci_link.c	2005-03-01 23:38:52 -08:00
@@ -307,50 +307,57 @@
 	struct {
 		struct acpi_resource	res;
 		struct acpi_resource	end;
-	}                       resource;
-	struct acpi_buffer	buffer = {sizeof(resource)+1, &resource};
+	}    *resource;
+	struct acpi_buffer	buffer = {0, NULL};
 
 	ACPI_FUNCTION_TRACE("acpi_pci_link_set");
 
 	if (!link || !irq)
 		return_VALUE(-EINVAL);
 
-	memset(&resource, 0, sizeof(resource));
+	resource = kmalloc( sizeof(*resource)+1, GFP_KERNEL);
+	if(!resource)
+		return_VALUE(-ENOMEM);
+
+	memset(resource, 0, sizeof(*resource)+1);
+	buffer.length = sizeof(*resource) +1;
+	buffer.pointer = resource;
 
 	switch(link->irq.resource_type) {
 	case ACPI_RSTYPE_IRQ:
-		resource.res.id = ACPI_RSTYPE_IRQ;
-		resource.res.length = sizeof(struct acpi_resource);
-		resource.res.data.irq.edge_level = link->irq.edge_level;
-		resource.res.data.irq.active_high_low = link->irq.active_high_low;
+		resource->res.id = ACPI_RSTYPE_IRQ;
+		resource->res.length = sizeof(struct acpi_resource);
+		resource->res.data.irq.edge_level = link->irq.edge_level;
+		resource->res.data.irq.active_high_low = link->irq.active_high_low;
 		if (link->irq.edge_level == ACPI_EDGE_SENSITIVE)
-			resource.res.data.irq.shared_exclusive = ACPI_EXCLUSIVE;
+			resource->res.data.irq.shared_exclusive = ACPI_EXCLUSIVE;
 		else
-			resource.res.data.irq.shared_exclusive = ACPI_SHARED;
-		resource.res.data.irq.number_of_interrupts = 1;
-		resource.res.data.irq.interrupts[0] = irq;
+			resource->res.data.irq.shared_exclusive = ACPI_SHARED;
+		resource->res.data.irq.number_of_interrupts = 1;
+		resource->res.data.irq.interrupts[0] = irq;
 		break;
 	   
 	case ACPI_RSTYPE_EXT_IRQ:
-		resource.res.id = ACPI_RSTYPE_EXT_IRQ;
-		resource.res.length = sizeof(struct acpi_resource);
-		resource.res.data.extended_irq.producer_consumer = ACPI_CONSUMER;
-		resource.res.data.extended_irq.edge_level = link->irq.edge_level;
-		resource.res.data.extended_irq.active_high_low = link->irq.active_high_low;
+		resource->res.id = ACPI_RSTYPE_EXT_IRQ;
+		resource->res.length = sizeof(struct acpi_resource);
+		resource->res.data.extended_irq.producer_consumer = ACPI_CONSUMER;
+		resource->res.data.extended_irq.edge_level = link->irq.edge_level;
+		resource->res.data.extended_irq.active_high_low = link->irq.active_high_low;
 		if (link->irq.edge_level == ACPI_EDGE_SENSITIVE)
-			resource.res.data.irq.shared_exclusive = ACPI_EXCLUSIVE;
+			resource->res.data.irq.shared_exclusive = ACPI_EXCLUSIVE;
 		else
-			resource.res.data.irq.shared_exclusive = ACPI_SHARED;
-		resource.res.data.extended_irq.number_of_interrupts = 1;
-		resource.res.data.extended_irq.interrupts[0] = irq;
+			resource->res.data.irq.shared_exclusive = ACPI_SHARED;
+		resource->res.data.extended_irq.number_of_interrupts = 1;
+		resource->res.data.extended_irq.interrupts[0] = irq;
 		/* ignore resource_source, it's optional */
 		break;
 	default:
 		printk("ACPI BUG: resource_type %d\n", link->irq.resource_type);
-		return_VALUE(-EINVAL);
+		result = -EINVAL;
+		goto end;
 
 	}
-	resource.end.id = ACPI_RSTYPE_END_TAG;
+	resource->end.id = ACPI_RSTYPE_END_TAG;
 
 	/* Attempt to set the resource */
 	status = acpi_set_current_resources(link->handle, &buffer);
@@ -358,14 +365,15 @@
 	/* check for total failure */
 	if (ACPI_FAILURE(status)) {
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _SRS\n"));
-		return_VALUE(-ENODEV);
+		result = -ENODEV;
+		goto end;
 	}
 
 	/* Query _STA, set device->status */
 	result = acpi_bus_get_status(link->device);
 	if (result) {
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unable to read status\n"));
-		return_VALUE(result);
+		goto end;
 	}
 	if (!link->device->status.enabled) {
 		printk(KERN_WARNING PREFIX
@@ -377,7 +385,7 @@
 	/* Query _CRS, set link->irq.active */
 	result = acpi_pci_link_get_current(link);
 	if (result) {
-		return_VALUE(result);
+		goto end;
 	}
 
 	/*
@@ -399,7 +407,9 @@
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Set IRQ %d\n", link->irq.active));
 	
-	return_VALUE(0);
+end:
+	kfree(resource);
+	return_VALUE(result);
 }
 
 
@@ -810,7 +820,7 @@
  */
 static int __init acpi_irq_isa(char *str)
 {
-	return(acpi_irq_penalty_update(str, 1));
+	return acpi_irq_penalty_update(str, 1);
 }
 __setup("acpi_irq_isa=", acpi_irq_isa);
 
@@ -821,7 +831,7 @@
  */
 static int __init acpi_irq_pci(char *str)
 {
-	return(acpi_irq_penalty_update(str, 0));
+	return acpi_irq_penalty_update(str, 0);
 }
 __setup("acpi_irq_pci=", acpi_irq_pci);
 
diff -Nru a/drivers/acpi/processor.c b/drivers/acpi/processor.c
--- a/drivers/acpi/processor.c	2005-03-01 23:39:07 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,2644 +0,0 @@
-/*
- * acpi_processor.c - ACPI Processor Driver ($Revision: 71 $)
- *
- *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
- *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
- *  Copyright (C) 2004       Dominik Brodowski <linux@brodo.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.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *  TBD:
- *	1. Make # power states dynamic.
- *	2. Support duty_cycle values that span bit 4.
- *	3. Optimize by having scheduler determine business instead of
- *	   having us try to calculate it here.
- *	4. Need C1 timing -- must modify kernel (IRQ handler) to get this.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/pm.h>
-#include <linux/cpufreq.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#include <linux/dmi.h>
-#include <linux/moduleparam.h>
-
-#include <asm/io.h>
-#include <asm/system.h>
-#include <asm/delay.h>
-#include <asm/uaccess.h>
-#include <asm/processor.h>
-#include <asm/smp.h>
-#include <asm/acpi.h>
-
-#include <acpi/acpi_bus.h>
-#include <acpi/acpi_drivers.h>
-#include <acpi/processor.h>
-
-
-#define ACPI_PROCESSOR_COMPONENT	0x01000000
-#define ACPI_PROCESSOR_CLASS		"processor"
-#define ACPI_PROCESSOR_DRIVER_NAME	"ACPI Processor Driver"
-#define ACPI_PROCESSOR_DEVICE_NAME	"Processor"
-#define ACPI_PROCESSOR_FILE_INFO	"info"
-#define ACPI_PROCESSOR_FILE_POWER	"power"
-#define ACPI_PROCESSOR_FILE_THROTTLING	"throttling"
-#define ACPI_PROCESSOR_FILE_LIMIT	"limit"
-#define ACPI_PROCESSOR_FILE_PERFORMANCE	"performance"
-#define ACPI_PROCESSOR_NOTIFY_PERFORMANCE 0x80
-#define ACPI_PROCESSOR_NOTIFY_POWER	0x81
-
-#define US_TO_PM_TIMER_TICKS(t)		((t * (PM_TIMER_FREQUENCY/1000)) / 1000)
-#define C2_OVERHEAD			4	/* 1us (3.579 ticks per us) */
-#define C3_OVERHEAD			4	/* 1us (3.579 ticks per us) */
-
-
-#define ACPI_PROCESSOR_LIMIT_USER	0
-#define ACPI_PROCESSOR_LIMIT_THERMAL	1
-
-#define _COMPONENT		ACPI_PROCESSOR_COMPONENT
-ACPI_MODULE_NAME		("acpi_processor")
-
-MODULE_AUTHOR("Paul Diefenbaugh");
-MODULE_DESCRIPTION(ACPI_PROCESSOR_DRIVER_NAME);
-MODULE_LICENSE("GPL");
-
-
-static int acpi_processor_add (struct acpi_device *device);
-static int acpi_processor_remove (struct acpi_device *device, int type);
-static int acpi_processor_info_open_fs(struct inode *inode, struct file *file);
-static int acpi_processor_throttling_open_fs(struct inode *inode, struct file *file);
-static int acpi_processor_power_open_fs(struct inode *inode, struct file *file);
-static int acpi_processor_limit_open_fs(struct inode *inode, struct file *file);
-static int acpi_processor_get_limit_info(struct acpi_processor *pr);
-
-static struct acpi_driver acpi_processor_driver = {
-	.name =		ACPI_PROCESSOR_DRIVER_NAME,
-	.class =	ACPI_PROCESSOR_CLASS,
-	.ids =		ACPI_PROCESSOR_HID,
-	.ops =		{
-				.add =		acpi_processor_add,
-				.remove =	acpi_processor_remove,
-			},
-};
-
-
-struct acpi_processor_errata {
-	u8			smp;
-	struct {
-		u8			throttle:1;
-		u8			fdma:1;
-		u8			reserved:6;
-		u32			bmisx;
-	}			piix4;
-};
-
-static struct file_operations acpi_processor_info_fops = {
-	.open 		= acpi_processor_info_open_fs,
-	.read		= seq_read,
-	.llseek		= seq_lseek,
-	.release	= single_release,
-};
-
-static struct file_operations acpi_processor_power_fops = {
-	.open 		= acpi_processor_power_open_fs,
-	.read		= seq_read,
-	.llseek		= seq_lseek,
-	.release	= single_release,
-};
-
-static struct file_operations acpi_processor_throttling_fops = {
-	.open 		= acpi_processor_throttling_open_fs,
-	.read		= seq_read,
-	.llseek		= seq_lseek,
-	.release	= single_release,
-};
-
-static struct file_operations acpi_processor_limit_fops = {
-	.open 		= acpi_processor_limit_open_fs,
-	.read		= seq_read,
-	.llseek		= seq_lseek,
-	.release	= single_release,
-};
-
-static struct acpi_processor	*processors[NR_CPUS];
-static struct acpi_processor_errata errata;
-static void (*pm_idle_save)(void);
-
-
-/* --------------------------------------------------------------------------
-                                Errata Handling
-   -------------------------------------------------------------------------- */
-
-int
-acpi_processor_errata_piix4 (
-	struct pci_dev		*dev)
-{
-	u8			rev = 0;
-	u8			value1 = 0;
-	u8			value2 = 0;
-
-	ACPI_FUNCTION_TRACE("acpi_processor_errata_piix4");
-
-	if (!dev)
-		return_VALUE(-EINVAL);
-
-	/*
-	 * Note that 'dev' references the PIIX4 ACPI Controller.
-	 */
-
-	pci_read_config_byte(dev, PCI_REVISION_ID, &rev);
-
-	switch (rev) {
-	case 0:
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4 A-step\n"));
-		break;
-	case 1:
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4 B-step\n"));
-		break;
-	case 2:
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4E\n"));
-		break;
-	case 3:
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4M\n"));
-		break;
-	default:
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found unknown PIIX4\n"));
-		break;
-	}
-
-	switch (rev) {
-
-	case 0:		/* PIIX4 A-step */
-	case 1:		/* PIIX4 B-step */
-		/*
-		 * See specification changes #13 ("Manual Throttle Duty Cycle")
-		 * and #14 ("Enabling and Disabling Manual Throttle"), plus
-		 * erratum #5 ("STPCLK# Deassertion Time") from the January 
-		 * 2002 PIIX4 specification update.  Applies to only older 
-		 * PIIX4 models.
-		 */
-		errata.piix4.throttle = 1;
-
-	case 2:		/* PIIX4E */
-	case 3:		/* PIIX4M */
-		/*
-		 * See erratum #18 ("C3 Power State/BMIDE and Type-F DMA 
-		 * Livelock") from the January 2002 PIIX4 specification update.
-		 * Applies to all PIIX4 models.
-		 */
-
-		/* 
-		 * BM-IDE
-		 * ------
-		 * Find the PIIX4 IDE Controller and get the Bus Master IDE 
-		 * Status register address.  We'll use this later to read 
-		 * each IDE controller's DMA status to make sure we catch all
-		 * DMA activity.
-		 */
-		dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
-		           PCI_DEVICE_ID_INTEL_82371AB, 
-                           PCI_ANY_ID, PCI_ANY_ID, NULL);
-		if (dev) {
-			errata.piix4.bmisx = pci_resource_start(dev, 4);
-			pci_dev_put(dev);
-		}
-
-		/* 
-		 * Type-F DMA
-		 * ----------
-		 * Find the PIIX4 ISA Controller and read the Motherboard
-		 * DMA controller's status to see if Type-F (Fast) DMA mode
-		 * is enabled (bit 7) on either channel.  Note that we'll 
-		 * disable C3 support if this is enabled, as some legacy 
-		 * devices won't operate well if fast DMA is disabled.
-		 */
-		dev = pci_get_subsys(PCI_VENDOR_ID_INTEL, 
-			PCI_DEVICE_ID_INTEL_82371AB_0, 
-			PCI_ANY_ID, PCI_ANY_ID, NULL);
-		if (dev) {
-			pci_read_config_byte(dev, 0x76, &value1);
-			pci_read_config_byte(dev, 0x77, &value2);
-			if ((value1 & 0x80) || (value2 & 0x80))
-				errata.piix4.fdma = 1;
-			pci_dev_put(dev);
-		}
-
-		break;
-	}
-
-	if (errata.piix4.bmisx)
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
-			"Bus master activity detection (BM-IDE) erratum enabled\n"));
-	if (errata.piix4.fdma)
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
-			"Type-F DMA livelock erratum (C3 disabled)\n"));
-
-	return_VALUE(0);
-}
-
-
-int
-acpi_processor_errata (
-	struct acpi_processor	*pr)
-{
-	int			result = 0;
-	struct pci_dev		*dev = NULL;
-
-	ACPI_FUNCTION_TRACE("acpi_processor_errata");
-
-	if (!pr)
-		return_VALUE(-EINVAL);
-
-	/*
-	 * PIIX4
-	 */
-	dev = pci_get_subsys(PCI_VENDOR_ID_INTEL, 
-		PCI_DEVICE_ID_INTEL_82371AB_3, PCI_ANY_ID, PCI_ANY_ID, NULL);
-	if (dev) {
-		result = acpi_processor_errata_piix4(dev);
-		pci_dev_put(dev);
-	}
-
-	return_VALUE(result);
-}
-
-
-/* --------------------------------------------------------------------------
-                                Power Management
-   -------------------------------------------------------------------------- */
-
-static inline u32
-ticks_elapsed (
-	u32			t1,
-	u32			t2)
-{
-	if (t2 >= t1)
-		return (t2 - t1);
-	else if (!acpi_fadt.tmr_val_ext)
-		return (((0x00FFFFFF - t1) + t2) & 0x00FFFFFF);
-	else
-		return ((0xFFFFFFFF - t1) + t2);
-}
-
-
-static void
-acpi_processor_power_activate (
-	struct acpi_processor	*pr,
-	int			state)
-{
-	if (!pr)
-		return;
-
-	pr->power.states[pr->power.state].promotion.count = 0;
-	pr->power.states[pr->power.state].demotion.count = 0;
-
-	/* Cleanup from old state. */
-	switch (pr->power.state) {
-	case ACPI_STATE_C3:
-		/* Disable bus master reload */
-		acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0, ACPI_MTX_DO_NOT_LOCK);
-		break;
-	}
-
-	/* Prepare to use new state. */
-	switch (state) {
-	case ACPI_STATE_C3:
-		/* Enable bus master reload */
-		acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1, ACPI_MTX_DO_NOT_LOCK);
-		break;
-	}
-
-	pr->power.state = state;
-
-	return;
-}
-
-
-static void
-acpi_processor_idle (void)
-{
-	struct acpi_processor	*pr = NULL;
-	struct acpi_processor_cx *cx = NULL;
-	unsigned int			next_state = 0;
-	unsigned int		sleep_ticks = 0;
-	u32			t1, t2 = 0;
-
-	pr = processors[smp_processor_id()];
-	if (!pr)
-		return;
-
-	/*
-	 * Interrupts must be disabled during bus mastering calculations and
-	 * for C2/C3 transitions.
-	 */
-	local_irq_disable();
-
-	/*
-	 * Check whether we truly need to go idle, or should
-	 * reschedule:
-	 */
-	if (unlikely(need_resched())) {
-		local_irq_enable();
-		return;
-	}
-
-	cx = &(pr->power.states[pr->power.state]);
-
-	/*
-	 * Check BM Activity
-	 * -----------------
-	 * Check for bus mastering activity (if required), record, and check
-	 * for demotion.
-	 */
-	if (pr->flags.bm_check) {
-		u32		bm_status = 0;
-
-		pr->power.bm_activity <<= 1;
-
-		acpi_get_register(ACPI_BITREG_BUS_MASTER_STATUS, 
-			&bm_status, ACPI_MTX_DO_NOT_LOCK);
-		if (bm_status) {
-			pr->power.bm_activity++;
-			acpi_set_register(ACPI_BITREG_BUS_MASTER_STATUS,
-				1, ACPI_MTX_DO_NOT_LOCK);
-		}
-		/*
-		 * PIIX4 Erratum #18: Note that BM_STS doesn't always reflect
-		 * the true state of bus mastering activity; forcing us to 
-		 * manually check the BMIDEA bit of each IDE channel.
-		 */
-		else if (errata.piix4.bmisx) {
-			if ((inb_p(errata.piix4.bmisx + 0x02) & 0x01) 
-				|| (inb_p(errata.piix4.bmisx + 0x0A) & 0x01))
-				pr->power.bm_activity++;
-		}
-		/*
-		 * Apply bus mastering demotion policy.  Automatically demote
-		 * to avoid a faulty transition.  Note that the processor 
-		 * won't enter a low-power state during this call (to this 
-		 * funciton) but should upon the next.
-		 *
-		 * TBD: A better policy might be to fallback to the demotion 
-		 *      state (use it for this quantum only) istead of 
-		 *      demoting -- and rely on duration as our sole demotion
-		 *      qualification.  This may, however, introduce DMA 
-		 *      issues (e.g. floppy DMA transfer overrun/underrun).
-		 */
-		if (pr->power.bm_activity & cx->demotion.threshold.bm) {
-			local_irq_enable();
-			next_state = cx->demotion.state;
-			goto end;
-		}
-	}
-
-	cx->usage++;
-
-	/*
-	 * Sleep:
-	 * ------
-	 * Invoke the current Cx state to put the processor to sleep.
-	 */
-	switch (pr->power.state) {
-
-	case ACPI_STATE_C1:
-		/*
-		 * Invoke C1.
-		 * Use the appropriate idle routine, the one that would
-		 * be used without acpi C-states.
-		 */
-		if (pm_idle_save)
-			pm_idle_save();
-		else
-			safe_halt();
-		/*
-                 * TBD: Can't get time duration while in C1, as resumes
-		 *      go to an ISR rather than here.  Need to instrument
-		 *      base interrupt handler.
-		 */
-		sleep_ticks = 0xFFFFFFFF;
-		break;
-
-	case ACPI_STATE_C2:
-		/* Get start time (ticks) */
-		t1 = inl(acpi_fadt.xpm_tmr_blk.address);
-		/* Invoke C2 */
-		inb(pr->power.states[ACPI_STATE_C2].address);
-		/* Dummy op - must do something useless after P_LVL2 read */
-		t2 = inl(acpi_fadt.xpm_tmr_blk.address);
-		/* Get end time (ticks) */
-		t2 = inl(acpi_fadt.xpm_tmr_blk.address);
-		/* Re-enable interrupts */
-		local_irq_enable();
-		/* Compute time (ticks) that we were actually asleep */
-		sleep_ticks = ticks_elapsed(t1, t2) - cx->latency_ticks - C2_OVERHEAD;
-		break;
-
-	case ACPI_STATE_C3:
-		/* Disable bus master arbitration */
-		acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1, ACPI_MTX_DO_NOT_LOCK);
-		/* Get start time (ticks) */
-		t1 = inl(acpi_fadt.xpm_tmr_blk.address);
-		/* Invoke C3 */
-		inb(pr->power.states[ACPI_STATE_C3].address);
-		/* Dummy op - must do something useless after P_LVL3 read */
-		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);
-		/* Re-enable interrupts */
-		local_irq_enable();
-		/* Compute time (ticks) that we were actually asleep */
-		sleep_ticks = ticks_elapsed(t1, t2) - cx->latency_ticks - C3_OVERHEAD;
-		break;
-
-	default:
-		local_irq_enable();
-		return;
-	}
-
-	next_state = pr->power.state;
-
-	/*
-	 * Promotion?
-	 * ----------
-	 * Track the number of longs (time asleep is greater than threshold)
-	 * and promote when the count threshold is reached.  Note that bus
-	 * mastering activity may prevent promotions.
-	 * Do not promote above max_cstate.
-	 */
-	if (cx->promotion.state && (cx->promotion.state <= max_cstate)) {
-		if (sleep_ticks > cx->promotion.threshold.ticks) {
-			cx->promotion.count++;
- 			cx->demotion.count = 0;
-			if (cx->promotion.count >= cx->promotion.threshold.count) {
-				if (pr->flags.bm_check) {
-					if (!(pr->power.bm_activity & cx->promotion.threshold.bm)) {
-						next_state = cx->promotion.state;
-						goto end;
-					}
-				}
-				else {
-					next_state = cx->promotion.state;
-					goto end;
-				}
-			}
-		}
-	}
-
-	/*
-	 * Demotion?
-	 * ---------
-	 * Track the number of shorts (time asleep is less than time threshold)
-	 * and demote when the usage threshold is reached.
-	 */
-	if (cx->demotion.state) {
-		if (sleep_ticks < cx->demotion.threshold.ticks) {
-			cx->demotion.count++;
-			cx->promotion.count = 0;
-			if (cx->demotion.count >= cx->demotion.threshold.count) {
-				next_state = cx->demotion.state;
-				goto end;
-			}
-		}
-	}
-
-end:
-	/*
-	 * Demote if current state exceeds max_cstate
-	 */
-	if (pr->power.state > max_cstate) {
-		next_state = max_cstate;
-	}
-
-	/*
-	 * New Cx State?
-	 * -------------
-	 * If we're going to start using a new Cx state we must clean up
-	 * from the previous and prepare to use the new.
-	 */
-	if (next_state != pr->power.state)
-		acpi_processor_power_activate(pr, next_state);
-
-	return;
-}
-
-
-static int
-acpi_processor_set_power_policy (
-	struct acpi_processor	*pr)
-{
-	ACPI_FUNCTION_TRACE("acpi_processor_set_power_policy");
-
-	/*
-	 * This function sets the default Cx state policy (OS idle handler).
-	 * Our scheme is to promote quickly to C2 but more conservatively
-	 * to C3.  We're favoring C2  for its characteristics of low latency
-	 * (quick response), good power savings, and ability to allow bus
-	 * mastering activity.  Note that the Cx state policy is completely
-	 * customizable and can be altered dynamically.
-	 */
-
-	if (!pr)
-		return_VALUE(-EINVAL);
-
-	/*
-	 * C0/C1
-	 * -----
-	 */
-	pr->power.state = ACPI_STATE_C1;
-	pr->power.default_state = ACPI_STATE_C1;
-
-	/*
-	 * C1/C2
-	 * -----
-	 * Set the default C1 promotion and C2 demotion policies, where we
-	 * promote from C1 to C2 after several (10) successive C1 transitions,
-	 * as we cannot (currently) measure the time spent in C1. Demote from
-	 * C2 to C1 anytime we experience a 'short' (time spent in C2 is less
-	 * than the C2 transtion latency).  Note the simplifying assumption 
-	 * that the 'cost' of a transition is amortized when we sleep for at
-	 * least as long as the transition's latency (thus the total transition
-	 * time is two times the latency).
-	 *
-	 * TBD: Measure C1 sleep times by instrumenting the core IRQ handler.
-	 * TBD: Demote to default C-State after long periods of activity.
-	 * TBD: Investigate policy's use of CPU utilization -vs- sleep duration.
-	 */
-	if (pr->power.states[ACPI_STATE_C2].valid) {
-		pr->power.states[ACPI_STATE_C1].promotion.threshold.count = 10;
-		pr->power.states[ACPI_STATE_C1].promotion.threshold.ticks =
-			pr->power.states[ACPI_STATE_C2].latency_ticks;
-		pr->power.states[ACPI_STATE_C1].promotion.state = ACPI_STATE_C2;
-
-		pr->power.states[ACPI_STATE_C2].demotion.threshold.count = 1;
-		pr->power.states[ACPI_STATE_C2].demotion.threshold.ticks =
-			pr->power.states[ACPI_STATE_C2].latency_ticks;
-		pr->power.states[ACPI_STATE_C2].demotion.state = ACPI_STATE_C1;
-	}
-
-	/*
-	 * C2/C3
-	 * -----
-	 * Set default C2 promotion and C3 demotion policies, where we promote
-	 * from C2 to C3 after several (4) cycles of no bus mastering activity
-	 * while maintaining sleep time criteria.  Demote immediately on a
-	 * short or whenever bus mastering activity occurs.
-	 */
-	if ((pr->power.states[ACPI_STATE_C2].valid) &&
-		(pr->power.states[ACPI_STATE_C3].valid)) {
-		pr->power.states[ACPI_STATE_C2].promotion.threshold.count = 4;
-		pr->power.states[ACPI_STATE_C2].promotion.threshold.ticks =
-			pr->power.states[ACPI_STATE_C3].latency_ticks;
-		pr->power.states[ACPI_STATE_C2].promotion.threshold.bm = 0x0F;
-		pr->power.states[ACPI_STATE_C2].promotion.state = ACPI_STATE_C3;
-
-		pr->power.states[ACPI_STATE_C3].demotion.threshold.count = 1;
-		pr->power.states[ACPI_STATE_C3].demotion.threshold.ticks =
-			pr->power.states[ACPI_STATE_C3].latency_ticks;
-		pr->power.states[ACPI_STATE_C3].demotion.threshold.bm = 0x0F;
-		pr->power.states[ACPI_STATE_C3].demotion.state = ACPI_STATE_C2;
-	}
-
-	return_VALUE(0);
-}
-
-
-int
-acpi_processor_get_power_info (
-	struct acpi_processor	*pr)
-{
-	int			result = 0;
-
-	ACPI_FUNCTION_TRACE("acpi_processor_get_power_info");
-
-	if (!pr)
-		return_VALUE(-EINVAL);
-
-	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-		"lvl2[0x%08x] lvl3[0x%08x]\n",
-		pr->power.states[ACPI_STATE_C2].address,
-		pr->power.states[ACPI_STATE_C3].address));
-
-	/* TBD: Support ACPI 2.0 objects */
-
-	/*
-	 * C0
-	 * --
-	 * This state exists only as filler in our array.
-	 */
-	pr->power.states[ACPI_STATE_C0].valid = 1;
-
-	/*
-	 * C1
-	 * --
-	 * ACPI requires C1 support for all processors.
-	 *
-	 * TBD: What about PROC_C1?
-	 */
-	pr->power.states[ACPI_STATE_C1].valid = 1;
-
-	/*
-	 * C2
-	 * --
-	 * We're (currently) only supporting C2 on UP systems.
-	 *
-	 * TBD: Support for C2 on MP (P_LVL2_UP).
-	 */
-	if (pr->power.states[ACPI_STATE_C2].address) {
-
-		pr->power.states[ACPI_STATE_C2].latency = acpi_fadt.plvl2_lat;
-
-		/*
-		 * C2 latency must be less than or equal to 100 microseconds.
-		 */
-		if (acpi_fadt.plvl2_lat > ACPI_PROCESSOR_MAX_C2_LATENCY)
-			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-				"C2 latency too large [%d]\n",
-				acpi_fadt.plvl2_lat));
-		/*
-		 * Only support C2 on UP systems (see TBD above).
-		 */
-		else if (errata.smp)
-			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-				"C2 not supported in SMP mode\n"));
-		/*
-		 * Otherwise we've met all of our C2 requirements.
-		 * Normalize the C2 latency to expidite policy.
-		 */
-		else {
-			pr->power.states[ACPI_STATE_C2].valid = 1;
-			pr->power.states[ACPI_STATE_C2].latency_ticks = 
-				US_TO_PM_TIMER_TICKS(acpi_fadt.plvl2_lat);
-		}
-	}
-
-	/*
-	 * C3
-	 * --
-	 * TBD: Investigate use of WBINVD on UP/SMP system in absence of
-	 *	bm_control.
-	 */
-	if (pr->power.states[ACPI_STATE_C3].address) {
-
-		pr->power.states[ACPI_STATE_C3].latency = acpi_fadt.plvl3_lat;
-
-		/*
-		 * C3 latency must be less than or equal to 1000 microseconds.
-		 */
-		if (acpi_fadt.plvl3_lat > ACPI_PROCESSOR_MAX_C3_LATENCY)
-			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-				"C3 latency too large [%d]\n", 
-				acpi_fadt.plvl3_lat));
-		/*
-		 * Only support C3 when bus mastering arbitration control
-		 * is present (able to disable bus mastering to maintain
-		 * cache coherency while in C3).
-		 */
-		else if (!pr->flags.bm_control)
-			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-				"C3 support requires bus mastering control\n"));
-		/*
-		 * Only support C3 on UP systems, as bm_control is only viable
-		 * on a UP system and flushing caches (e.g. WBINVD) is simply 
-		 * too costly (at this time).
-		 */
-		else if (errata.smp)
-			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-				"C3 not supported in SMP mode\n"));
-		/*
-		 * PIIX4 Erratum #18: We don't support C3 when Type-F (fast) 
-		 * DMA transfers are used by any ISA device to avoid livelock.
-		 * Note that we could disable Type-F DMA (as recommended by
-		 * the erratum), but this is known to disrupt certain ISA 
-		 * devices thus we take the conservative approach.
-		 */
-		else if (errata.piix4.fdma) {
-			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-				"C3 not supported on PIIX4 with Type-F DMA\n"));
-		}
-		/*
-		 * Otherwise we've met all of our C3 requirements.  
-		 * Normalize the C2 latency to expidite policy.  Enable
-		 * checking of bus mastering status (bm_check) so we can 
-		 * use this in our C3 policy.
-		 */
-		else {
-			pr->power.states[ACPI_STATE_C3].valid = 1;
-			pr->power.states[ACPI_STATE_C3].latency_ticks = 
-				US_TO_PM_TIMER_TICKS(acpi_fadt.plvl3_lat);
-			pr->flags.bm_check = 1;
-		}
-	}
-
-	/*
-	 * Set Default Policy
-	 * ------------------
-	 * Now that we know which state are supported, set the default
-	 * policy.  Note that this policy can be changed dynamically
-	 * (e.g. encourage deeper sleeps to conserve battery life when
-	 * not on AC).
-	 */
-	result = acpi_processor_set_power_policy(pr);
-	if (result)
-		return_VALUE(result);
-
-	/*
-	 * If this processor supports C2 or C3 we denote it as being 'power
-	 * manageable'.  Note that there's really no policy involved for
-	 * when only C1 is supported.
-	 */
-	if (pr->power.states[ACPI_STATE_C2].valid 
-		|| pr->power.states[ACPI_STATE_C3].valid)
-		pr->flags.power = 1;
-
-	return_VALUE(0);
-}
-
-
-/* --------------------------------------------------------------------------
-                              Performance Management
-   -------------------------------------------------------------------------- */
-#ifdef CONFIG_CPU_FREQ
-
-static DECLARE_MUTEX(performance_sem);
-
-/*
- * _PPC support is implemented as a CPUfreq policy notifier: 
- * This means each time a CPUfreq driver registered also with
- * the ACPI core is asked to change the speed policy, the maximum
- * value is adjusted so that it is within the platform limit.
- * 
- * Also, when a new platform limit value is detected, the CPUfreq
- * policy is adjusted accordingly.
- */
-
-#define PPC_REGISTERED   1
-#define PPC_IN_USE       2
-
-static int acpi_processor_ppc_status = 0;
-
-static int acpi_processor_ppc_notifier(struct notifier_block *nb, 
-	unsigned long event,
-	void *data)
-{
-	struct cpufreq_policy *policy = data;
-	struct acpi_processor *pr;
-	unsigned int ppc = 0;
-
-	down(&performance_sem);
-
-	if (event != CPUFREQ_INCOMPATIBLE)
-		goto out;
-
-	pr = processors[policy->cpu];
-	if (!pr || !pr->performance)
-		goto out;
-
-	ppc = (unsigned int) pr->performance_platform_limit;
-	if (!ppc)
-		goto out;
-
-	if (ppc > pr->performance->state_count)
-		goto out;
-
-	cpufreq_verify_within_limits(policy, 0, 
-		pr->performance->states[ppc].core_frequency * 1000);
-
- out:
-	up(&performance_sem);
-
-	return 0;
-}
-
-
-static struct notifier_block acpi_ppc_notifier_block = {
-	.notifier_call = acpi_processor_ppc_notifier,
-};
-
-
-static int
-acpi_processor_get_platform_limit (
-	struct acpi_processor*	pr)
-{
-	acpi_status		status = 0;
-	unsigned long		ppc = 0;
-
-	ACPI_FUNCTION_TRACE("acpi_processor_get_platform_limit");
-
-	if (!pr)
-		return_VALUE(-EINVAL);
-
-	/*
-	 * _PPC indicates the maximum state currently supported by the platform
-	 * (e.g. 0 = states 0..n; 1 = states 1..n; etc.
-	 */
-	status = acpi_evaluate_integer(pr->handle, "_PPC", NULL, &ppc);
-
-	if (status != AE_NOT_FOUND)
-		acpi_processor_ppc_status |= PPC_IN_USE;
-
-	if(ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PPC\n"));
-		return_VALUE(-ENODEV);
-	}
-
-	pr->performance_platform_limit = (int) ppc;
-	
-	return_VALUE(0);
-}
-
-
-static int acpi_processor_ppc_has_changed(
-	struct acpi_processor *pr)
-{
-	int ret = acpi_processor_get_platform_limit(pr);
-	if (ret < 0)
-		return (ret);
-	else
-		return cpufreq_update_policy(pr->id);
-}
-
-
-static void acpi_processor_ppc_init(void) {
-	if (!cpufreq_register_notifier(&acpi_ppc_notifier_block, CPUFREQ_POLICY_NOTIFIER))
-		acpi_processor_ppc_status |= PPC_REGISTERED;
-	else
-		printk(KERN_DEBUG "Warning: Processor Platform Limit not supported.\n");
-}
-
-
-static void acpi_processor_ppc_exit(void) {
-	if (acpi_processor_ppc_status & PPC_REGISTERED)
-		cpufreq_unregister_notifier(&acpi_ppc_notifier_block, CPUFREQ_POLICY_NOTIFIER);
-
-	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 (
-	struct acpi_processor *pr)
-{
-	int			result = 0;
-	acpi_status		status = 0;
-	struct acpi_buffer	buffer = {ACPI_ALLOCATE_BUFFER, NULL};
-	union acpi_object	*pct = NULL;
-	union acpi_object	obj = {0};
-
-	ACPI_FUNCTION_TRACE("acpi_processor_get_performance_control");
-
-	status = acpi_evaluate_object(pr->handle, "_PCT", NULL, &buffer);
-	if(ACPI_FAILURE(status)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PCT\n"));
-		return_VALUE(-ENODEV);
-	}
-
-	pct = (union acpi_object *) buffer.pointer;
-	if (!pct || (pct->type != ACPI_TYPE_PACKAGE) 
-		|| (pct->package.count != 2)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PCT data\n"));
-		result = -EFAULT;
-		goto end;
-	}
-
-	/*
-	 * control_register
-	 */
-
-	obj = pct->package.elements[0];
-
-	if ((obj.type != ACPI_TYPE_BUFFER) 
-		|| (obj.buffer.length < sizeof(struct acpi_pct_register)) 
-		|| (obj.buffer.pointer == NULL)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 
-			"Invalid _PCT data (control_register)\n"));
-		result = -EFAULT;
-		goto end;
-	}
-	memcpy(&pr->performance->control_register, obj.buffer.pointer, sizeof(struct acpi_pct_register));
-
-
-	/*
-	 * status_register
-	 */
-
-	obj = pct->package.elements[1];
-
-	if ((obj.type != ACPI_TYPE_BUFFER) 
-		|| (obj.buffer.length < sizeof(struct acpi_pct_register)) 
-		|| (obj.buffer.pointer == NULL)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 
-			"Invalid _PCT data (status_register)\n"));
-		result = -EFAULT;
-		goto end;
-	}
-
-	memcpy(&pr->performance->status_register, obj.buffer.pointer, sizeof(struct acpi_pct_register));
-
-end:
-	acpi_os_free(buffer.pointer);
-
-	return_VALUE(result);
-}
-
-
-static int 
-acpi_processor_get_performance_states (
-	struct acpi_processor	*pr)
-{
-	int			result = 0;
-	acpi_status		status = AE_OK;
-	struct acpi_buffer	buffer = {ACPI_ALLOCATE_BUFFER, NULL};
-	struct acpi_buffer	format = {sizeof("NNNNNN"), "NNNNNN"};
-	struct acpi_buffer	state = {0, NULL};
-	union acpi_object 	*pss = NULL;
-	unsigned int		i;
-
-	ACPI_FUNCTION_TRACE("acpi_processor_get_performance_states");
-
-	status = acpi_evaluate_object(pr->handle, "_PSS", NULL, &buffer);
-	if(ACPI_FAILURE(status)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PSS\n"));
-		return_VALUE(-ENODEV);
-	}
-
-	pss = (union acpi_object *) buffer.pointer;
-	if (!pss || (pss->type != ACPI_TYPE_PACKAGE)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSS data\n"));
-		result = -EFAULT;
-		goto end;
-	}
-
-	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d performance states\n", 
-		pss->package.count));
-
-	pr->performance->state_count = pss->package.count;
-	pr->performance->states = kmalloc(sizeof(struct acpi_processor_px) * pss->package.count, GFP_KERNEL);
-	if (!pr->performance->states) {
-		result = -ENOMEM;
-		goto end;
-	}
-
-	for (i = 0; i < pr->performance->state_count; i++) {
-
-		struct acpi_processor_px *px = &(pr->performance->states[i]);
-
-		state.length = sizeof(struct acpi_processor_px);
-		state.pointer = px;
-
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Extracting state %d\n", i));
-
-		status = acpi_extract_package(&(pss->package.elements[i]), 
-			&format, &state);
-		if (ACPI_FAILURE(status)) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSS data\n"));
-			result = -EFAULT;
-			kfree(pr->performance->states);
-			goto end;
-		}
-
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
-			"State [%d]: core_frequency[%d] power[%d] transition_latency[%d] bus_master_latency[%d] control[0x%x] status[0x%x]\n",
-			i, 
-			(u32) px->core_frequency, 
-			(u32) px->power, 
-			(u32) px->transition_latency, 
-			(u32) px->bus_master_latency,
-			(u32) px->control, 
-			(u32) px->status));
-
-		if (!px->core_frequency) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSS data: freq is zero\n"));
-			result = -EFAULT;
-			kfree(pr->performance->states);
-			goto end;
-		}
-	}
-
-end:
-	acpi_os_free(buffer.pointer);
-
-	return_VALUE(result);
-}
-
-
-static int
-acpi_processor_get_performance_info (
-	struct acpi_processor	*pr)
-{
-	int			result = 0;
-	acpi_status		status = AE_OK;
-	acpi_handle		handle = NULL;
-
-	ACPI_FUNCTION_TRACE("acpi_processor_get_performance_info");
-
-	if (!pr || !pr->performance || !pr->handle)
-		return_VALUE(-EINVAL);
-
-	acpi_processor_set_pdc(pr);
-
-	status = acpi_get_handle(pr->handle, "_PCT", &handle);
-	if (ACPI_FAILURE(status)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
-			"ACPI-based processor performance control unavailable\n"));
-		return_VALUE(-ENODEV);
-	}
-
-	result = acpi_processor_get_performance_control(pr);
-	if (result)
-		return_VALUE(result);
-
-	result = acpi_processor_get_performance_states(pr);
-	if (result)
-		return_VALUE(result);
-
-	result = acpi_processor_get_platform_limit(pr);
-	if (result)
-		return_VALUE(result);
-
-	return_VALUE(0);
-}
-
-
-int acpi_processor_notify_smm(struct module *calling_module) {
-	acpi_status		status;
-	static int		is_done = 0;
-
-	ACPI_FUNCTION_TRACE("acpi_processor_notify_smm");
-
-	if (!(acpi_processor_ppc_status & PPC_REGISTERED))
-		return_VALUE(-EBUSY);
-
-	if (!try_module_get(calling_module))
-		return_VALUE(-EINVAL);
-
-	/* is_done is set to negative if an error occured,
-	 * and to postitive if _no_ error occured, but SMM
-	 * was already notified. This avoids double notification
-	 * which might lead to unexpected results...
-	 */
-	if (is_done > 0) {
-		module_put(calling_module);
-		return_VALUE(0);
-	}
-	else if (is_done < 0) {
-		module_put(calling_module);
-		return_VALUE(is_done);
-	}
-
-	is_done = -EIO;
-
-	/* Can't write pstate_cnt to smi_cmd if either value is zero */
-	if ((!acpi_fadt.smi_cmd) ||
-	    (!acpi_fadt.pstate_cnt)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-			"No SMI port or pstate_cnt\n"));
-		module_put(calling_module);
-		return_VALUE(0);
-	}
-
-	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Writing pstate_cnt [0x%x] to smi_cmd [0x%x]\n", acpi_fadt.pstate_cnt, acpi_fadt.smi_cmd));
-
-	/* FADT v1 doesn't support pstate_cnt, many BIOS vendors use
-	 * it anyway, so we need to support it... */
-	if (acpi_fadt_is_v1) {
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Using v1.0 FADT reserved value for pstate_cnt\n"));
-	}
-
-	status = acpi_os_write_port (acpi_fadt.smi_cmd,
-				     (u32) acpi_fadt.pstate_cnt, 8);
-	if (ACPI_FAILURE (status)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Failed to write pstate_cnt [0x%x] to "
-				  "smi_cmd [0x%x]\n", acpi_fadt.pstate_cnt, acpi_fadt.smi_cmd));
-		module_put(calling_module);
-		return_VALUE(status);
-	}
-
-	/* Success. If there's no _PPC, we need to fear nothing, so
-	 * we can allow the cpufreq driver to be rmmod'ed. */
-	is_done = 1;
-
-	if (!(acpi_processor_ppc_status & PPC_IN_USE))
-		module_put(calling_module);
-
-	return_VALUE(0);
-}
-EXPORT_SYMBOL(acpi_processor_notify_smm);
-
-
-#ifdef CONFIG_X86_ACPI_CPUFREQ_PROC_INTF
-/* /proc/acpi/processor/../performance interface (DEPRECATED) */
-
-static int acpi_processor_perf_open_fs(struct inode *inode, struct file *file);
-static struct file_operations acpi_processor_perf_fops = {
-	.open 		= acpi_processor_perf_open_fs,
-	.read		= seq_read,
-	.llseek		= seq_lseek,
-	.release	= single_release,
-};
-
-static int acpi_processor_perf_seq_show(struct seq_file *seq, void *offset)
-{
-	struct acpi_processor	*pr = (struct acpi_processor *)seq->private;
-	unsigned int		i;
-
-	ACPI_FUNCTION_TRACE("acpi_processor_perf_seq_show");
-
-	if (!pr)
-		goto end;
-
-	if (!pr->performance) {
-		seq_puts(seq, "<not supported>\n");
-		goto end;
-	}
-
-	seq_printf(seq, "state count:             %d\n"
-			"active state:            P%d\n",
-			pr->performance->state_count,
-			pr->performance->state);
-
-	seq_puts(seq, "states:\n");
-	for (i = 0; i < pr->performance->state_count; i++)
-		seq_printf(seq, "   %cP%d:                  %d MHz, %d mW, %d uS\n",
-			(i == pr->performance->state?'*':' '), i,
-			(u32) pr->performance->states[i].core_frequency,
-			(u32) pr->performance->states[i].power,
-			(u32) pr->performance->states[i].transition_latency);
-
-end:
-	return_VALUE(0);
-}
-
-static int acpi_processor_perf_open_fs(struct inode *inode, struct file *file)
-{
-	return single_open(file, acpi_processor_perf_seq_show,
-						PDE(inode)->data);
-}
-
-static ssize_t
-acpi_processor_write_performance (
-        struct file		*file,
-        const char		__user *buffer,
-        size_t			count,
-        loff_t			*data)
-{
-	int			result = 0;
-	struct seq_file		*m = (struct seq_file *) file->private_data;
-	struct acpi_processor	*pr = (struct acpi_processor *) m->private;
-	struct acpi_processor_performance *perf;
-	char			state_string[12] = {'\0'};
-	unsigned int            new_state = 0;
-	struct cpufreq_policy   policy;
-
-	ACPI_FUNCTION_TRACE("acpi_processor_write_performance");
-
-	if (!pr || (count > sizeof(state_string) - 1))
-		return_VALUE(-EINVAL);
-
-	perf = pr->performance;
-	if (!perf)
-		return_VALUE(-EINVAL);
-	
-	if (copy_from_user(state_string, buffer, count))
-		return_VALUE(-EFAULT);
-	
-	state_string[count] = '\0';
-	new_state = simple_strtoul(state_string, NULL, 0);
-
-	if (new_state >= perf->state_count)
-		return_VALUE(-EINVAL);
-
-	cpufreq_get_policy(&policy, pr->id);
-
-	policy.cpu = pr->id;
-	policy.min = perf->states[new_state].core_frequency * 1000;
-	policy.max = perf->states[new_state].core_frequency * 1000;
-
-	result = cpufreq_set_policy(&policy);
-	if (result)
-		return_VALUE(result);
-
-	return_VALUE(count);
-}
-
-static void
-acpi_cpufreq_add_file (
-	struct acpi_processor *pr)
-{
-	struct proc_dir_entry	*entry = NULL;
-	struct acpi_device	*device = NULL;
-
-	ACPI_FUNCTION_TRACE("acpi_cpufreq_addfile");
-
-	if (acpi_bus_get_device(pr->handle, &device))
-		return_VOID;
-
-	/* add file 'performance' [R/W] */
-	entry = create_proc_entry(ACPI_PROCESSOR_FILE_PERFORMANCE,
-		  S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device));
-	if (!entry)
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-			"Unable to create '%s' fs entry\n",
-			ACPI_PROCESSOR_FILE_PERFORMANCE));
-	else {
-		entry->proc_fops = &acpi_processor_perf_fops;
-		entry->proc_fops->write = acpi_processor_write_performance;
-		entry->data = acpi_driver_data(device);
-		entry->owner = THIS_MODULE;
-	}
-	return_VOID;
-}
-
-static void
-acpi_cpufreq_remove_file (
-	struct acpi_processor *pr)
-{
-	struct acpi_device	*device = NULL;
-
-	ACPI_FUNCTION_TRACE("acpi_cpufreq_addfile");
-
-	if (acpi_bus_get_device(pr->handle, &device))
-		return_VOID;
-
-	/* remove file 'performance' */
-	remove_proc_entry(ACPI_PROCESSOR_FILE_PERFORMANCE,
-		  acpi_device_dir(device));
-
-	return_VOID;
-}
-
-#else
-static void acpi_cpufreq_add_file (struct acpi_processor *pr) { return; }
-static void acpi_cpufreq_remove_file (struct acpi_processor *pr) { return; }
-#endif /* CONFIG_X86_ACPI_CPUFREQ_PROC_INTF */
-
-
-int 
-acpi_processor_register_performance (
-	struct acpi_processor_performance * performance,
-	unsigned int cpu)
-{
-	struct acpi_processor *pr;
-
-	ACPI_FUNCTION_TRACE("acpi_processor_register_performance");
-
-	if (!(acpi_processor_ppc_status & PPC_REGISTERED))
-		return_VALUE(-EINVAL);
-
-	down(&performance_sem);
-
-	pr = processors[cpu];
-	if (!pr) {
-		up(&performance_sem);
-		return_VALUE(-ENODEV);
-	}
-
-	if (pr->performance) {
-		up(&performance_sem);
-		return_VALUE(-EBUSY);
-	}
-
-	pr->performance = performance;
-
-	if (acpi_processor_get_performance_info(pr)) {
-		pr->performance = NULL;
-		up(&performance_sem);
-		return_VALUE(-EIO);
-	}
-
-	acpi_cpufreq_add_file(pr);
-
-	up(&performance_sem);
-	return_VALUE(0);
-}
-EXPORT_SYMBOL(acpi_processor_register_performance);
-
-
-void 
-acpi_processor_unregister_performance (
-	struct acpi_processor_performance * performance,
-	unsigned int cpu)
-{
-	struct acpi_processor *pr;
-
-	ACPI_FUNCTION_TRACE("acpi_processor_unregister_performance");
-
-	down(&performance_sem);
-
-	pr = processors[cpu];
-	if (!pr) {
-		up(&performance_sem);
-		return_VOID;
-	}
-
-	kfree(pr->performance->states);
-	pr->performance = NULL;
-
-	acpi_cpufreq_remove_file(pr);
-
-	up(&performance_sem);
-
-	return_VOID;
-}
-EXPORT_SYMBOL(acpi_processor_unregister_performance);
-
-
-/* for the rest of it, check arch/i386/kernel/cpu/cpufreq/acpi.c */
-
-#else  /* !CONFIG_CPU_FREQ */
-
-static void acpi_processor_ppc_init(void) { return; }
-static void acpi_processor_ppc_exit(void) { return; }
-
-static int acpi_processor_ppc_has_changed(struct acpi_processor *pr) {
-	static unsigned int printout = 1;
-	if (printout) {
-		printk(KERN_WARNING "Warning: Processor Platform Limit event detected, but not handled.\n");
-		printk(KERN_WARNING "Consider compiling CPUfreq support into your kernel.\n");
-		printout = 0;
-	}
-	return 0;
-}
-
-#endif /* CONFIG_CPU_FREQ */
-
-/* --------------------------------------------------------------------------
-                              Throttling Control
-   -------------------------------------------------------------------------- */
-
-static int
-acpi_processor_get_throttling (
-	struct acpi_processor	*pr)
-{
-	int			state = 0;
-	u32			value = 0;
-	u32			duty_mask = 0;
-	u32			duty_value = 0;
-
-	ACPI_FUNCTION_TRACE("acpi_processor_get_throttling");
-
-	if (!pr)
-		return_VALUE(-EINVAL);
-
-	if (!pr->flags.throttling)
-		return_VALUE(-ENODEV);
-
-	pr->throttling.state = 0;
-
-	local_irq_disable();
-
-	duty_mask = pr->throttling.state_count - 1;
-
-	duty_mask <<= pr->throttling.duty_offset;
-
-	value = inl(pr->throttling.address);
-
-	/*
-	 * Compute the current throttling state when throttling is enabled
-	 * (bit 4 is on).
-	 */
-	if (value & 0x10) {
-		duty_value = value & duty_mask;
-		duty_value >>= pr->throttling.duty_offset;
-
-		if (duty_value)
-			state = pr->throttling.state_count-duty_value;
-	}
-
-	pr->throttling.state = state;
-
-	local_irq_enable();
-
-	ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
-		"Throttling state is T%d (%d%% throttling applied)\n",
-		state, pr->throttling.states[state].performance));
-
-	return_VALUE(0);
-}
-
-
-static int
-acpi_processor_set_throttling (
-	struct acpi_processor	*pr,
-	int			state)
-{
-	u32                     value = 0;
-	u32                     duty_mask = 0;
-	u32                     duty_value = 0;
-
-	ACPI_FUNCTION_TRACE("acpi_processor_set_throttling");
-
-	if (!pr)
-		return_VALUE(-EINVAL);
-
-	if ((state < 0) || (state > (pr->throttling.state_count - 1)))
-		return_VALUE(-EINVAL);
-
-	if (!pr->flags.throttling)
-		return_VALUE(-ENODEV);
-
-	if (state == pr->throttling.state)
-		return_VALUE(0);
-
-	local_irq_disable();
-
-	/*
-	 * Calculate the duty_value and duty_mask.
-	 */
-	if (state) {
-		duty_value = pr->throttling.state_count - state;
-
-		duty_value <<= pr->throttling.duty_offset;
-
-		/* Used to clear all duty_value bits */
-		duty_mask = pr->throttling.state_count - 1;
-
-		duty_mask <<= acpi_fadt.duty_offset;
-		duty_mask = ~duty_mask;
-	}
-
-	/*
-	 * Disable throttling by writing a 0 to bit 4.  Note that we must
-	 * turn it off before you can change the duty_value.
-	 */
-	value = inl(pr->throttling.address);
-	if (value & 0x10) {
-		value &= 0xFFFFFFEF;
-		outl(value, pr->throttling.address);
-	}
-
-	/*
-	 * Write the new duty_value and then enable throttling.  Note
-	 * that a state value of 0 leaves throttling disabled.
-	 */
-	if (state) {
-		value &= duty_mask;
-		value |= duty_value;
-		outl(value, pr->throttling.address);
-
-		value |= 0x00000010;
-		outl(value, pr->throttling.address);
-	}
-
-	pr->throttling.state = state;
-
-	local_irq_enable();
-
-	ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
-		"Throttling state set to T%d (%d%%)\n", state, 
-		(pr->throttling.states[state].performance?pr->throttling.states[state].performance/10:0)));
-
-	return_VALUE(0);
-}
-
-
-static int
-acpi_processor_get_throttling_info (
-	struct acpi_processor	*pr)
-{
-	int			result = 0;
-	int			step = 0;
-	int			i = 0;
-
-	ACPI_FUNCTION_TRACE("acpi_processor_get_throttling_info");
-
-	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-		"pblk_address[0x%08x] duty_offset[%d] duty_width[%d]\n",
-		pr->throttling.address,
-		pr->throttling.duty_offset,
-		pr->throttling.duty_width));
-
-	if (!pr)
-		return_VALUE(-EINVAL);
-
-	/* TBD: Support ACPI 2.0 objects */
-
-	if (!pr->throttling.address) {
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No throttling register\n"));
-		return_VALUE(0);
-	}
-	else if (!pr->throttling.duty_width) {
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No throttling states\n"));
-		return_VALUE(0);
-	}
-	/* TBD: Support duty_cycle values that span bit 4. */
-	else if ((pr->throttling.duty_offset
-		+ pr->throttling.duty_width) > 4) {
-		ACPI_DEBUG_PRINT((ACPI_DB_WARN, "duty_cycle spans bit 4\n"));
-		return_VALUE(0);
-	}
-
-	/*
-	 * PIIX4 Errata: We don't support throttling on the original PIIX4.
-	 * This shouldn't be an issue as few (if any) mobile systems ever
-	 * used this part.
-	 */
-	if (errata.piix4.throttle) {
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
-			"Throttling not supported on PIIX4 A- or B-step\n"));
-		return_VALUE(0);
-	}
-
-	pr->throttling.state_count = 1 << acpi_fadt.duty_width;
-
-	/*
-	 * Compute state values. Note that throttling displays a linear power/
-	 * performance relationship (at 50% performance the CPU will consume
-	 * 50% power).  Values are in 1/10th of a percent to preserve accuracy.
-	 */
-
-	step = (1000 / pr->throttling.state_count);
-
-	for (i=0; i<pr->throttling.state_count; i++) {
-		pr->throttling.states[i].performance = step * i;
-		pr->throttling.states[i].power = step * i;
-	}
-
-	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d throttling states\n", 
-		pr->throttling.state_count));
-
-	pr->flags.throttling = 1;
-
-	/*
-	 * Disable throttling (if enabled).  We'll let subsequent policy (e.g. 
-	 * thermal) decide to lower performance if it so chooses, but for now 
-	 * we'll crank up the speed.
-	 */
-
-	result = acpi_processor_get_throttling(pr);
-	if (result)
-		goto end;
-
-	if (pr->throttling.state) {
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Disabling throttling (was T%d)\n", 
-			pr->throttling.state));
-		result = acpi_processor_set_throttling(pr, 0);
-		if (result)
-			goto end;
-	}
-
-end:
-	if (result)
-		pr->flags.throttling = 0;
-
-	return_VALUE(result);
-}
-
-
-/* --------------------------------------------------------------------------
-                                 Limit Interface
-   -------------------------------------------------------------------------- */
-
-static int
-acpi_processor_apply_limit (
-	struct acpi_processor* 	pr)
-{
-	int			result = 0;
-	u16			px = 0;
-	u16			tx = 0;
-
-	ACPI_FUNCTION_TRACE("acpi_processor_apply_limit");
-
-	if (!pr)
-		return_VALUE(-EINVAL);
-
-	if (!pr->flags.limit)
-		return_VALUE(-ENODEV);
-
-	if (pr->flags.throttling) {
-		if (pr->limit.user.tx > tx)
-			tx = pr->limit.user.tx;
-		if (pr->limit.thermal.tx > tx)
-			tx = pr->limit.thermal.tx;
-
-		result = acpi_processor_set_throttling(pr, tx);
-		if (result)
-			goto end;
-	}
-
-	pr->limit.state.px = px;
-	pr->limit.state.tx = tx;
-
-	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Processor [%d] limit set to (P%d:T%d)\n",
-		pr->id,
-		pr->limit.state.px,
-		pr->limit.state.tx));
-
-end:
-	if (result)
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unable to set limit\n"));
-
-	return_VALUE(result);
-}
-
-
-#ifdef CONFIG_CPU_FREQ
-
-/* If a passive cooling situation is detected, primarily CPUfreq is used, as it
- * offers (in most cases) voltage scaling in addition to frequency scaling, and
- * thus a cubic (instead of linear) reduction of energy. Also, we allow for
- * _any_ cpufreq driver and not only the acpi-cpufreq driver.
- */
-
-static unsigned int cpufreq_thermal_reduction_pctg[NR_CPUS];
-static unsigned int acpi_thermal_cpufreq_is_init = 0;
-
-
-static int cpu_has_cpufreq(unsigned int cpu)
-{
-	struct cpufreq_policy policy;
-	if (!acpi_thermal_cpufreq_is_init)
-		return -ENODEV;
-	if (!cpufreq_get_policy(&policy, cpu))
-		return -ENODEV;
-	return 0;
-}
-
-
-static int acpi_thermal_cpufreq_increase(unsigned int cpu)
-{
-	if (!cpu_has_cpufreq(cpu))
-		return -ENODEV;
-
-	if (cpufreq_thermal_reduction_pctg[cpu] < 60) {
-		cpufreq_thermal_reduction_pctg[cpu] += 20;
-		cpufreq_update_policy(cpu);
-		return 0;
-	}
-
-	return -ERANGE;
-}
-
-
-static int acpi_thermal_cpufreq_decrease(unsigned int cpu)
-{
-	if (!cpu_has_cpufreq(cpu))
-		return -ENODEV;
-
-	if (cpufreq_thermal_reduction_pctg[cpu] >= 20) {
-		cpufreq_thermal_reduction_pctg[cpu] -= 20;
-		cpufreq_update_policy(cpu);
-		return 0;
-	}
-
-	return -ERANGE;
-}
-
-
-static int acpi_thermal_cpufreq_notifier(
-	struct notifier_block *nb,
-	unsigned long event,
-	void *data)
-{
-	struct cpufreq_policy *policy = data;
-	unsigned long max_freq = 0;
-
-	if (event != CPUFREQ_ADJUST)
-		goto out;
-
-	max_freq = (policy->cpuinfo.max_freq * (100 - cpufreq_thermal_reduction_pctg[policy->cpu])) / 100;
-
-	cpufreq_verify_within_limits(policy, 0, max_freq);
-
- out:
-	return 0;
-}
-
-
-static struct notifier_block acpi_thermal_cpufreq_notifier_block = {
-	.notifier_call = acpi_thermal_cpufreq_notifier,
-};
-
-
-static void acpi_thermal_cpufreq_init(void) {
-	int i;
-
-	for (i=0; i<NR_CPUS; i++)
-		cpufreq_thermal_reduction_pctg[i] = 0;
-
-	i = cpufreq_register_notifier(&acpi_thermal_cpufreq_notifier_block, CPUFREQ_POLICY_NOTIFIER);
-	if (!i)
-		acpi_thermal_cpufreq_is_init = 1;
-}
-
-static void acpi_thermal_cpufreq_exit(void) {
-	if (acpi_thermal_cpufreq_is_init)
-		cpufreq_unregister_notifier(&acpi_thermal_cpufreq_notifier_block, CPUFREQ_POLICY_NOTIFIER);
-
-	acpi_thermal_cpufreq_is_init = 0;
-}
-
-#else /* ! CONFIG_CPU_FREQ */
-
-static void acpi_thermal_cpufreq_init(void) { return; }
-static void acpi_thermal_cpufreq_exit(void) { return; }
-static int acpi_thermal_cpufreq_increase(unsigned int cpu) { return -ENODEV; }
-static int acpi_thermal_cpufreq_decrease(unsigned int cpu) { return -ENODEV; }
-
-
-#endif
-
-
-int
-acpi_processor_set_thermal_limit (
-	acpi_handle		handle,
-	int			type)
-{
-	int			result = 0;
-	struct acpi_processor	*pr = NULL;
-	struct acpi_device	*device = NULL;
-	int			tx = 0;
-
-	ACPI_FUNCTION_TRACE("acpi_processor_set_thermal_limit");
-
-	if ((type < ACPI_PROCESSOR_LIMIT_NONE) 
-		|| (type > ACPI_PROCESSOR_LIMIT_DECREMENT))
-		return_VALUE(-EINVAL);
-
-	result = acpi_bus_get_device(handle, &device);
-	if (result)
-		return_VALUE(result);
-
-	pr = (struct acpi_processor *) acpi_driver_data(device);
-	if (!pr)
-		return_VALUE(-ENODEV);
-
-	/* Thermal limits are always relative to the current Px/Tx state. */
-	if (pr->flags.throttling)
-		pr->limit.thermal.tx = pr->throttling.state;
-
-	/*
-	 * Our default policy is to only use throttling at the lowest
-	 * performance state.
-	 */
-
-	tx = pr->limit.thermal.tx;
-
-	switch (type) {
-
-	case ACPI_PROCESSOR_LIMIT_NONE:
-		do {
-			result = acpi_thermal_cpufreq_decrease(pr->id);
-		} while (!result);
-		tx = 0;
-		break;
-
-	case ACPI_PROCESSOR_LIMIT_INCREMENT:
-		/* if going up: P-states first, T-states later */
-
-		result = acpi_thermal_cpufreq_increase(pr->id);
-		if (!result)
-			goto end;
-		else if (result == -ERANGE)
-			ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
-					"At maximum performance state\n"));
-
-		if (pr->flags.throttling) {
-			if (tx == (pr->throttling.state_count - 1))
-				ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
-					"At maximum throttling state\n"));
-			else
-				tx++;
-		}
-		break;
-
-	case ACPI_PROCESSOR_LIMIT_DECREMENT:
-		/* if going down: T-states first, P-states later */
-
-		if (pr->flags.throttling) {
-			if (tx == 0)
-				ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
-					"At minimum throttling state\n"));
-			else {
-				tx--;
-				goto end;
-			}
-		}
-
-		result = acpi_thermal_cpufreq_decrease(pr->id);
-		if (result == -ERANGE)
-			ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
-					"At minimum performance state\n"));
-
-		break;
-	}
-
-end:
-	if (pr->flags.throttling) {
-		pr->limit.thermal.px = 0;
-		pr->limit.thermal.tx = tx;
-
-		result = acpi_processor_apply_limit(pr);
-		if (result)
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 
-					  "Unable to set thermal limit\n"));
-
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Thermal limit now (P%d:T%d)\n",
-				  pr->limit.thermal.px,
-				  pr->limit.thermal.tx));
-	} else
-		result = 0;
-
-	return_VALUE(result);
-}
-
-
-static int
-acpi_processor_get_limit_info (
-	struct acpi_processor	*pr)
-{
-	ACPI_FUNCTION_TRACE("acpi_processor_get_limit_info");
-
-	if (!pr)
-		return_VALUE(-EINVAL);
-
-	if (pr->flags.throttling)
-		pr->flags.limit = 1;
-
-	return_VALUE(0);
-}
-
-
-/* --------------------------------------------------------------------------
-                              FS Interface (/proc)
-   -------------------------------------------------------------------------- */
-
-struct proc_dir_entry		*acpi_processor_dir = NULL;
-
-static int acpi_processor_info_seq_show(struct seq_file *seq, void *offset)
-{
-	struct acpi_processor	*pr = (struct acpi_processor *)seq->private;
-
-	ACPI_FUNCTION_TRACE("acpi_processor_info_seq_show");
-
-	if (!pr)
-		goto end;
-
-	seq_printf(seq, "processor id:            %d\n"
-			"acpi id:                 %d\n"
-			"bus mastering control:   %s\n"
-			"power management:        %s\n"
-			"throttling control:      %s\n"
-			"limit interface:         %s\n",
-			pr->id,
-			pr->acpi_id,
-			pr->flags.bm_control ? "yes" : "no",
-			pr->flags.power ? "yes" : "no",
-			pr->flags.throttling ? "yes" : "no",
-			pr->flags.limit ? "yes" : "no");
-
-end:
-	return_VALUE(0);
-}
-
-static int acpi_processor_info_open_fs(struct inode *inode, struct file *file)
-{
-	return single_open(file, acpi_processor_info_seq_show,
-						PDE(inode)->data);
-}
-
-static int acpi_processor_power_seq_show(struct seq_file *seq, void *offset)
-{
-	struct acpi_processor	*pr = (struct acpi_processor *)seq->private;
-	unsigned int		i;
-
-	ACPI_FUNCTION_TRACE("acpi_processor_power_seq_show");
-
-	if (!pr)
-		goto end;
-
-	seq_printf(seq, "active state:            C%d\n"
-			"default state:           C%d\n"
-			"max_cstate:              C%d\n"
-			"bus master activity:     %08x\n",
-			pr->power.state,
-			pr->power.default_state,
-			max_cstate,
-			pr->power.bm_activity);
-
-	seq_puts(seq, "states:\n");
-
-	for (i = 1; i < ACPI_C_STATE_COUNT; i++) {
-		seq_printf(seq, "   %cC%d:                  ", 
-			(i == pr->power.state?'*':' '), i);
-
-		if (!pr->power.states[i].valid) {
-			seq_puts(seq, "<not supported>\n");
-			continue;
-		}
-
-		if (pr->power.states[i].promotion.state)
-			seq_printf(seq, "promotion[C%d] ",
-				pr->power.states[i].promotion.state);
-		else
-			seq_puts(seq, "promotion[--] ");
-
-		if (pr->power.states[i].demotion.state)
-			seq_printf(seq, "demotion[C%d] ",
-				pr->power.states[i].demotion.state);
-		else
-			seq_puts(seq, "demotion[--] ");
-
-		seq_printf(seq, "latency[%03d] usage[%08d]\n",
-			pr->power.states[i].latency,
-			pr->power.states[i].usage);
-	}
-
-end:
-	return_VALUE(0);
-}
-
-static int acpi_processor_power_open_fs(struct inode *inode, struct file *file)
-{
-	return single_open(file, acpi_processor_power_seq_show,
-						PDE(inode)->data);
-}
-
-static int acpi_processor_throttling_seq_show(struct seq_file *seq, void *offset)
-{
-	struct acpi_processor	*pr = (struct acpi_processor *)seq->private;
-	int			i = 0;
-	int                     result = 0;
-
-	ACPI_FUNCTION_TRACE("acpi_processor_throttling_seq_show");
-
-	if (!pr)
-		goto end;
-
-	if (!(pr->throttling.state_count > 0)) {
-		seq_puts(seq, "<not supported>\n");
-		goto end;
-	}
-
-	result = acpi_processor_get_throttling(pr);
-
-	if (result) {
-		seq_puts(seq, "Could not determine current throttling state.\n");
-		goto end;
-	}
-
-	seq_printf(seq, "state count:             %d\n"
-			"active state:            T%d\n",
-			pr->throttling.state_count,
-			pr->throttling.state);
-
-	seq_puts(seq, "states:\n");
-	for (i = 0; i < pr->throttling.state_count; i++)
-		seq_printf(seq, "   %cT%d:                  %02d%%\n",
-			(i == pr->throttling.state?'*':' '), i,
-			(pr->throttling.states[i].performance?pr->throttling.states[i].performance/10:0));
-
-end:
-	return_VALUE(0);
-}
-
-static int acpi_processor_throttling_open_fs(struct inode *inode, struct file *file)
-{
-	return single_open(file, acpi_processor_throttling_seq_show,
-						PDE(inode)->data);
-}
-
-static ssize_t
-acpi_processor_write_throttling (
-        struct file		*file,
-        const char		__user *buffer,
-        size_t			count,
-        loff_t			*data)
-{
-	int			result = 0;
-        struct seq_file 	*m = (struct seq_file *)file->private_data;
-	struct acpi_processor	*pr = (struct acpi_processor *)m->private;
-	char			state_string[12] = {'\0'};
-
-	ACPI_FUNCTION_TRACE("acpi_processor_write_throttling");
-
-	if (!pr || (count > sizeof(state_string) - 1))
-		return_VALUE(-EINVAL);
-	
-	if (copy_from_user(state_string, buffer, count))
-		return_VALUE(-EFAULT);
-	
-	state_string[count] = '\0';
-	
-	result = acpi_processor_set_throttling(pr, 
-		simple_strtoul(state_string, NULL, 0));
-	if (result)
-		return_VALUE(result);
-
-	return_VALUE(count);
-}
-
-static int acpi_processor_limit_seq_show(struct seq_file *seq, void *offset)
-{
-	struct acpi_processor	*pr = (struct acpi_processor *)seq->private;
-
-	ACPI_FUNCTION_TRACE("acpi_processor_limit_seq_show");
-
-	if (!pr)
-		goto end;
-
-	if (!pr->flags.limit) {
-		seq_puts(seq, "<not supported>\n");
-		goto end;
-	}
-
-	seq_printf(seq, "active limit:            P%d:T%d\n"
-			"user limit:              P%d:T%d\n"
-			"thermal limit:           P%d:T%d\n",
-			pr->limit.state.px, pr->limit.state.tx,
-			pr->limit.user.px, pr->limit.user.tx,
-			pr->limit.thermal.px, pr->limit.thermal.tx);
-
-end:
-	return_VALUE(0);
-}
-
-static int acpi_processor_limit_open_fs(struct inode *inode, struct file *file)
-{
-	return single_open(file, acpi_processor_limit_seq_show,
-						PDE(inode)->data);
-}
-
-static ssize_t
-acpi_processor_write_limit (
-	struct file		*file,
-	const char		__user *buffer,
-	size_t			count,
-	loff_t			*data)
-{
-	int			result = 0;
-        struct seq_file 	*m = (struct seq_file *)file->private_data;
-	struct acpi_processor	*pr = (struct acpi_processor *)m->private;
-	char			limit_string[25] = {'\0'};
-	int			px = 0;
-	int			tx = 0;
-
-	ACPI_FUNCTION_TRACE("acpi_processor_write_limit");
-
-	if (!pr || (count > sizeof(limit_string) - 1)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid argument\n"));
-		return_VALUE(-EINVAL);
-	}
-	
-	if (copy_from_user(limit_string, buffer, count)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid data\n"));
-		return_VALUE(-EFAULT);
-	}
-	
-	limit_string[count] = '\0';
-
-	if (sscanf(limit_string, "%d:%d", &px, &tx) != 2) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid data format\n"));
-		return_VALUE(-EINVAL);
-	}
-
-	if (pr->flags.throttling) {
-		if ((tx < 0) || (tx > (pr->throttling.state_count - 1))) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid tx\n"));
-			return_VALUE(-EINVAL);
-		}
-		pr->limit.user.tx = tx;
-	}
-
-	result = acpi_processor_apply_limit(pr);
-
-	return_VALUE(count);
-}
-
-
-static int
-acpi_processor_add_fs (
-	struct acpi_device	*device)
-{
-	struct proc_dir_entry	*entry = NULL;
-
-	ACPI_FUNCTION_TRACE("acpi_processor_add_fs");
-
-	if (!acpi_device_dir(device)) {
-		acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
-			acpi_processor_dir);
-		if (!acpi_device_dir(device))
-			return_VALUE(-ENODEV);
-	}
-	acpi_device_dir(device)->owner = THIS_MODULE;
-
-	/* 'info' [R] */
-	entry = create_proc_entry(ACPI_PROCESSOR_FILE_INFO,
-		S_IRUGO, acpi_device_dir(device));
-	if (!entry)
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-			"Unable to create '%s' fs entry\n",
-			ACPI_PROCESSOR_FILE_INFO));
-	else {
-		entry->proc_fops = &acpi_processor_info_fops;
-		entry->data = acpi_driver_data(device);
-		entry->owner = THIS_MODULE;
-	}
-
-	/* 'power' [R] */
-	entry = create_proc_entry(ACPI_PROCESSOR_FILE_POWER,
-		S_IRUGO, acpi_device_dir(device));
-	if (!entry)
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-			"Unable to create '%s' fs entry\n",
-			ACPI_PROCESSOR_FILE_POWER));
-	else {
-		entry->proc_fops = &acpi_processor_power_fops;
-		entry->data = acpi_driver_data(device);
-		entry->owner = THIS_MODULE;
-	}
-
-	/* 'throttling' [R/W] */
-	entry = create_proc_entry(ACPI_PROCESSOR_FILE_THROTTLING,
-		S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device));
-	if (!entry)
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-			"Unable to create '%s' fs entry\n",
-			ACPI_PROCESSOR_FILE_THROTTLING));
-	else {
-		entry->proc_fops = &acpi_processor_throttling_fops;
-		entry->proc_fops->write = acpi_processor_write_throttling;
-		entry->data = acpi_driver_data(device);
-		entry->owner = THIS_MODULE;
-	}
-
-	/* 'limit' [R/W] */
-	entry = create_proc_entry(ACPI_PROCESSOR_FILE_LIMIT,
-		S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device));
-	if (!entry)
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-			"Unable to create '%s' fs entry\n",
-			ACPI_PROCESSOR_FILE_LIMIT));
-	else {
-		entry->proc_fops = &acpi_processor_limit_fops;
-		entry->proc_fops->write = acpi_processor_write_limit;
-		entry->data = acpi_driver_data(device);
-		entry->owner = THIS_MODULE;
-	}
-
-	return_VALUE(0);
-}
-
-
-static int
-acpi_processor_remove_fs (
-	struct acpi_device	*device)
-{
-	ACPI_FUNCTION_TRACE("acpi_processor_remove_fs");
-
-	if (acpi_device_dir(device)) {
-		remove_proc_entry(ACPI_PROCESSOR_FILE_INFO,acpi_device_dir(device));
-		remove_proc_entry(ACPI_PROCESSOR_FILE_POWER,acpi_device_dir(device));
-		remove_proc_entry(ACPI_PROCESSOR_FILE_THROTTLING,
-			acpi_device_dir(device));
-		remove_proc_entry(ACPI_PROCESSOR_FILE_LIMIT,acpi_device_dir(device));
-		remove_proc_entry(acpi_device_bid(device), acpi_processor_dir);
-		acpi_device_dir(device) = NULL;
-	}
-
-	return_VALUE(0);
-}
-
-/* Use the acpiid in MADT to map cpus in case of SMP */
-#ifndef CONFIG_SMP
-#define convert_acpiid_to_cpu(acpi_id) (0xff)
-#else
-
-#ifdef CONFIG_IA64
-#define arch_acpiid_to_apicid 	ia64_acpiid_to_sapicid
-#define arch_cpu_to_apicid 	ia64_cpu_to_sapicid
-#define ARCH_BAD_APICID		(0xffff)
-#else
-#define arch_acpiid_to_apicid 	x86_acpiid_to_apicid
-#define arch_cpu_to_apicid 	x86_cpu_to_apicid
-#define ARCH_BAD_APICID		(0xff)
-#endif
-
-static u8 convert_acpiid_to_cpu(u8 acpi_id)
-{
-	u16 apic_id;
-	int i;
-	
-	apic_id = arch_acpiid_to_apicid[acpi_id];
-	if (apic_id == ARCH_BAD_APICID)
-		return -1;
-
-	for (i = 0; i < NR_CPUS; i++) {
-		if (arch_cpu_to_apicid[i] == apic_id)
-			return i;
-	}
-	return -1;
-}
-#endif
-
-/* --------------------------------------------------------------------------
-                                 Driver Interface
-   -------------------------------------------------------------------------- */
-
-static int
-acpi_processor_get_info (
-	struct acpi_processor	*pr)
-{
-	acpi_status		status = 0;
-	union acpi_object	object = {0};
-	struct acpi_buffer	buffer = {sizeof(union acpi_object), &object};
-	u8			cpu_index;
-	static int		cpu0_initialized;
-
-	ACPI_FUNCTION_TRACE("acpi_processor_get_info");
-
-	if (!pr)
-		return_VALUE(-EINVAL);
-
-	if (num_online_cpus() > 1)
-		errata.smp = TRUE;
-
-	acpi_processor_errata(pr);
-
-	/*
-	 * Check to see if we have bus mastering arbitration control.  This
-	 * is required for proper C3 usage (to maintain cache coherency).
-	 */
-	if (acpi_fadt.V1_pm2_cnt_blk && acpi_fadt.pm2_cnt_len) {
-		pr->flags.bm_control = 1;
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-			"Bus mastering arbitration control present\n"));
-	}
-	else
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-			"No bus mastering arbitration control\n"));
-
-	/*
-	 * Evalute the processor object.  Note that it is common on SMP to
-	 * have the first (boot) processor with a valid PBLK address while
-	 * all others have a NULL address.
-	 */
-	status = acpi_evaluate_object(pr->handle, NULL, NULL, &buffer);
-	if (ACPI_FAILURE(status)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-			"Error evaluating processor object\n"));
-		return_VALUE(-ENODEV);
-	}
-
-	/*
-	 * TBD: Synch processor ID (via LAPIC/LSAPIC structures) on SMP.
-	 *	>>> 'acpi_get_processor_id(acpi_id, &id)' in arch/xxx/acpi.c
-	 */
-	pr->acpi_id = object.processor.proc_id;
-
-	cpu_index = convert_acpiid_to_cpu(pr->acpi_id);
-
-	if ( !cpu0_initialized && (cpu_index == 0xff)) {
-		/* Handle UP system running SMP kernel, with no LAPIC in MADT */
-		cpu_index = 0;
-	} else if (cpu_index > num_online_cpus()) {
-		/*
-		 *  Extra Processor objects may be enumerated on MP systems with
-		 *  less than the max # of CPUs. They should be ignored.
-		 */
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-			"Error getting cpuindex for acpiid 0x%x\n",
-			pr->acpi_id));
-		return_VALUE(-ENODEV);
-	}
-	cpu0_initialized = 1;
-
-	pr->id = cpu_index;
-
-	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Processor [%d:%d]\n", pr->id, 
-		pr->acpi_id));
-
-	if (!object.processor.pblk_address)
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No PBLK (NULL address)\n"));
-	else if (object.processor.pblk_length != 6)
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid PBLK length [%d]\n",
-			object.processor.pblk_length));
-	else {
-		pr->throttling.address = object.processor.pblk_address;
-		pr->throttling.duty_offset = acpi_fadt.duty_offset;
-		pr->throttling.duty_width = acpi_fadt.duty_width;
-		pr->power.states[ACPI_STATE_C2].address =
-			object.processor.pblk_address + 4;
-		pr->power.states[ACPI_STATE_C3].address =
-			object.processor.pblk_address + 5;
-
-		/*
-		 * We don't care about error returns - we just try to mark
-		 * these reserved so that nobody else is confused into thinking
-		 * that this region might be unused..
-		 *
-		 * (In particular, allocating the IO range for Cardbus)
-		 */
-		request_region(pr->throttling.address, 6, "ACPI CPU throttle");
-	}
-
-	acpi_processor_get_power_info(pr);
-#ifdef CONFIG_CPU_FREQ
-	acpi_processor_ppc_has_changed(pr);
-#endif
-	acpi_processor_get_throttling_info(pr);
-	acpi_processor_get_limit_info(pr);
-
-	return_VALUE(0);
-}
-
-
-static void
-acpi_processor_notify (
-	acpi_handle		handle,
-	u32			event,
-	void			*data)
-{
-	struct acpi_processor	*pr = (struct acpi_processor *) data;
-	struct acpi_device	*device = NULL;
-
-	ACPI_FUNCTION_TRACE("acpi_processor_notify");
-
-	if (!pr)
-		return_VOID;
-
-	if (acpi_bus_get_device(pr->handle, &device))
-		return_VOID;
-
-	switch (event) {
-	case ACPI_PROCESSOR_NOTIFY_PERFORMANCE:
-		acpi_processor_ppc_has_changed(pr);
-		acpi_bus_generate_event(device, event, 
-			pr->performance_platform_limit);
-		break;
-	case ACPI_PROCESSOR_NOTIFY_POWER:
-		/* TBD */
-		acpi_bus_generate_event(device, event, 0);
-		break;
-	default:
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-			"Unsupported event [0x%x]\n", event));
-		break;
-	}
-
-	return_VOID;
-}
-
-
-static int
-acpi_processor_add (
-	struct acpi_device	*device)
-{
-	int			result = 0;
-	acpi_status		status = AE_OK;
-	struct acpi_processor	*pr = NULL;
-	u32			i = 0;
-
-	ACPI_FUNCTION_TRACE("acpi_processor_add");
-
-	if (!device)
-		return_VALUE(-EINVAL);
-
-	pr = kmalloc(sizeof(struct acpi_processor), GFP_KERNEL);
-	if (!pr)
-		return_VALUE(-ENOMEM);
-	memset(pr, 0, sizeof(struct acpi_processor));
-
-	pr->handle = device->handle;
-	strcpy(acpi_device_name(device), ACPI_PROCESSOR_DEVICE_NAME);
-	strcpy(acpi_device_class(device), ACPI_PROCESSOR_CLASS);
-	acpi_driver_data(device) = pr;
-
-	result = acpi_processor_get_info(pr);
-	if (result)
-		goto end;
-
-	result = acpi_processor_add_fs(device);
-	if (result)
-		goto end;
-
-	status = acpi_install_notify_handler(pr->handle, ACPI_DEVICE_NOTIFY, 
-		acpi_processor_notify, pr);
-	if (ACPI_FAILURE(status)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 
-			"Error installing notify handler\n"));
-		result = -ENODEV;
-		goto end;
-	}
-
-	processors[pr->id] = pr;
-
-	/*
-	 * Install the idle handler if processor power management is supported.
-	 * Note that we use previously set idle handler will be used on 
-	 * platforms that only support C1.
-	 */
-	if ((pr->flags.power) && (!boot_option_idle_override)) {
-		printk(KERN_INFO PREFIX "%s [%s] (supports",
-			acpi_device_name(device), acpi_device_bid(device));
-		for (i = 1; i < ACPI_C_STATE_COUNT; i++)
-			if (pr->power.states[i].valid)
-				printk(" C%d", i);
-		printk(")\n");
-		if (pr->id == 0) {
-			pm_idle_save = pm_idle;
-			pm_idle = acpi_processor_idle;
-		}
-	}
-	
-	if (pr->flags.throttling) {
-		printk(KERN_INFO PREFIX "%s [%s] (supports",
-			acpi_device_name(device), acpi_device_bid(device));
-		printk(" %d throttling states", pr->throttling.state_count);
-		printk(")\n");
-	}
-
-end:
-	if (result) {
-		acpi_processor_remove_fs(device);
-		kfree(pr);
-	}
-
-	return_VALUE(result);
-}
-
-
-static int
-acpi_processor_remove (
-	struct acpi_device	*device,
-	int			type)
-{
-	acpi_status		status = AE_OK;
-	struct acpi_processor	*pr = NULL;
-
-	ACPI_FUNCTION_TRACE("acpi_processor_remove");
-
-	if (!device || !acpi_driver_data(device))
-		return_VALUE(-EINVAL);
-
-	pr = (struct acpi_processor *) acpi_driver_data(device);
-
-	/* Unregister the idle handler when processor #0 is removed. */
-	if (pr->id == 0) {
-		pm_idle = pm_idle_save;
-		/*
-		 * We are about to unload the current idle thread pm callback
-		 * (pm_idle), Wait for all processors to update cached/local
-		 * copies of pm_idle before proceeding.
-		 */
-		synchronize_kernel();
-	}
-
-	status = acpi_remove_notify_handler(pr->handle, ACPI_DEVICE_NOTIFY, 
-		acpi_processor_notify);
-	if (ACPI_FAILURE(status)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 
-			"Error removing notify handler\n"));
-	}
-
-	acpi_processor_remove_fs(device);
-
-	processors[pr->id] = NULL;
-
-	kfree(pr);
-
-	return_VALUE(0);
-}
-
-/*
- * IBM ThinkPad R40e crashes mysteriously when going into C2 or C3. 
- * For now disable this. Probably a bug somewhere else.
- *
- * To skip this limit, boot/load with a large max_cstate limit.
- */
-static int no_c2c3(struct dmi_system_id *id)
-{
-	if (max_cstate > ACPI_C_STATES_MAX)
-		return 0;
-
-	printk(KERN_NOTICE PREFIX "%s detected - C2,C3 disabled."
-		" Override with \"processor.max_cstate=9\"\n", id->ident);
-
-	max_cstate = 1;
-
-	return 0;
-}
-
-static struct dmi_system_id __initdata processor_dmi_table[] = { 
-	{ no_c2c3, "IBM ThinkPad R40e", {
-	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
-	  DMI_MATCH(DMI_BIOS_VERSION,"1SET60WW") }},
-	{ no_c2c3, "Medion 41700", {
-	  DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
-	  DMI_MATCH(DMI_BIOS_VERSION,"R01-A1J") }},
-	{},
-};
-
-/* We keep the driver loaded even when ACPI is not running. 
-   This is needed for the powernow-k8 driver, that works even without
-   ACPI, but needs symbols from this driver */
-
-static int __init
-acpi_processor_init (void)
-{
-	int			result = 0;
-
-	ACPI_FUNCTION_TRACE("acpi_processor_init");
-
-	memset(&processors, 0, sizeof(processors));
-	memset(&errata, 0, sizeof(errata));
-
-	acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir);
-	if (!acpi_processor_dir)
-		return_VALUE(0);
-	acpi_processor_dir->owner = THIS_MODULE;
-
-	result = acpi_bus_register_driver(&acpi_processor_driver);
-	if (result < 0) {
-		remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir);
-		return_VALUE(0);
-	}
-
-	acpi_thermal_cpufreq_init();
-
-	acpi_processor_ppc_init();
-
-	dmi_check_system(processor_dmi_table); 
-
-	if (max_cstate < ACPI_C_STATES_MAX)
-		printk(KERN_NOTICE "ACPI: processor limited to max C-state %d\n", max_cstate);
-
-	return_VALUE(0);
-}
-
-
-static void __exit
-acpi_processor_exit (void)
-{
-	ACPI_FUNCTION_TRACE("acpi_processor_exit");
-
-	acpi_processor_ppc_exit();
-
-	acpi_thermal_cpufreq_exit();
-
-	acpi_bus_unregister_driver(&acpi_processor_driver);
-
-	remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir);
-
-	return_VOID;
-}
-
-
-module_init(acpi_processor_init);
-module_exit(acpi_processor_exit);
-module_param_named(max_cstate, max_cstate, uint, 0);
-
-EXPORT_SYMBOL(acpi_processor_set_thermal_limit);
diff -Nru a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/acpi/processor_core.c	2005-03-01 23:39:07 -08:00
@@ -0,0 +1,989 @@
+/*
+ * acpi_processor.c - ACPI Processor Driver ($Revision: 71 $)
+ *
+ *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
+ *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
+ *  Copyright (C) 2004       Dominik Brodowski <linux@brodo.de>
+ *  Copyright (C) 2004  Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
+ *  			- Added processor hotplug 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.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *  TBD:
+ *	1. Make # power states dynamic.
+ *	2. Support duty_cycle values that span bit 4.
+ *	3. Optimize by having scheduler determine business instead of
+ *	   having us try to calculate it here.
+ *	4. Need C1 timing -- must modify kernel (IRQ handler) to get this.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/pm.h>
+#include <linux/cpufreq.h>
+#include <linux/cpu.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <linux/dmi.h>
+#include <linux/moduleparam.h>
+
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/cpu.h>
+#include <asm/delay.h>
+#include <asm/uaccess.h>
+#include <asm/processor.h>
+#include <asm/smp.h>
+#include <asm/acpi.h>
+
+#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
+#include <acpi/processor.h>
+
+
+#define ACPI_PROCESSOR_COMPONENT	0x01000000
+#define ACPI_PROCESSOR_CLASS		"processor"
+#define ACPI_PROCESSOR_DRIVER_NAME	"ACPI Processor Driver"
+#define ACPI_PROCESSOR_DEVICE_NAME	"Processor"
+#define ACPI_PROCESSOR_FILE_INFO	"info"
+#define ACPI_PROCESSOR_FILE_THROTTLING	"throttling"
+#define ACPI_PROCESSOR_FILE_LIMIT	"limit"
+#define ACPI_PROCESSOR_NOTIFY_PERFORMANCE 0x80
+#define ACPI_PROCESSOR_NOTIFY_POWER	0x81
+
+#define ACPI_PROCESSOR_LIMIT_USER	0
+#define ACPI_PROCESSOR_LIMIT_THERMAL	1
+
+#define ACPI_STA_PRESENT 0x00000001
+
+#define _COMPONENT		ACPI_PROCESSOR_COMPONENT
+ACPI_MODULE_NAME		("acpi_processor")
+
+MODULE_AUTHOR("Paul Diefenbaugh");
+MODULE_DESCRIPTION(ACPI_PROCESSOR_DRIVER_NAME);
+MODULE_LICENSE("GPL");
+
+
+static int acpi_processor_add (struct acpi_device *device);
+static int acpi_processor_start (struct acpi_device *device);
+static int acpi_processor_remove (struct acpi_device *device, int type);
+static int acpi_processor_info_open_fs(struct inode *inode, struct file *file);
+static void acpi_processor_notify ( acpi_handle	handle, u32 event, void *data);
+static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu);
+static int acpi_processor_handle_eject(struct acpi_processor *pr);
+
+static struct acpi_driver acpi_processor_driver = {
+	.name =		ACPI_PROCESSOR_DRIVER_NAME,
+	.class =	ACPI_PROCESSOR_CLASS,
+	.ids =		ACPI_PROCESSOR_HID,
+	.ops =		{
+				.add =		acpi_processor_add,
+				.remove =	acpi_processor_remove,
+				.start	= 	acpi_processor_start,
+			},
+};
+
+#define INSTALL_NOTIFY_HANDLER		1
+#define UNINSTALL_NOTIFY_HANDLER	2
+
+
+struct file_operations acpi_processor_info_fops = {
+	.open 		= acpi_processor_info_open_fs,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+
+struct acpi_processor	*processors[NR_CPUS];
+struct acpi_processor_errata errata;
+
+
+/* --------------------------------------------------------------------------
+                                Errata Handling
+   -------------------------------------------------------------------------- */
+
+int
+acpi_processor_errata_piix4 (
+	struct pci_dev		*dev)
+{
+	u8			rev = 0;
+	u8			value1 = 0;
+	u8			value2 = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_errata_piix4");
+
+	if (!dev)
+		return_VALUE(-EINVAL);
+
+	/*
+	 * Note that 'dev' references the PIIX4 ACPI Controller.
+	 */
+
+	pci_read_config_byte(dev, PCI_REVISION_ID, &rev);
+
+	switch (rev) {
+	case 0:
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4 A-step\n"));
+		break;
+	case 1:
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4 B-step\n"));
+		break;
+	case 2:
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4E\n"));
+		break;
+	case 3:
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4M\n"));
+		break;
+	default:
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found unknown PIIX4\n"));
+		break;
+	}
+
+	switch (rev) {
+
+	case 0:		/* PIIX4 A-step */
+	case 1:		/* PIIX4 B-step */
+		/*
+		 * See specification changes #13 ("Manual Throttle Duty Cycle")
+		 * and #14 ("Enabling and Disabling Manual Throttle"), plus
+		 * erratum #5 ("STPCLK# Deassertion Time") from the January
+		 * 2002 PIIX4 specification update.  Applies to only older
+		 * PIIX4 models.
+		 */
+		errata.piix4.throttle = 1;
+
+	case 2:		/* PIIX4E */
+	case 3:		/* PIIX4M */
+		/*
+		 * See erratum #18 ("C3 Power State/BMIDE and Type-F DMA
+		 * Livelock") from the January 2002 PIIX4 specification update.
+		 * Applies to all PIIX4 models.
+		 */
+
+		/*
+		 * BM-IDE
+		 * ------
+		 * Find the PIIX4 IDE Controller and get the Bus Master IDE
+		 * Status register address.  We'll use this later to read
+		 * each IDE controller's DMA status to make sure we catch all
+		 * DMA activity.
+		 */
+		dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
+		           PCI_DEVICE_ID_INTEL_82371AB,
+                           PCI_ANY_ID, PCI_ANY_ID, NULL);
+		if (dev) {
+			errata.piix4.bmisx = pci_resource_start(dev, 4);
+			pci_dev_put(dev);
+		}
+
+		/*
+		 * Type-F DMA
+		 * ----------
+		 * Find the PIIX4 ISA Controller and read the Motherboard
+		 * DMA controller's status to see if Type-F (Fast) DMA mode
+		 * is enabled (bit 7) on either channel.  Note that we'll
+		 * disable C3 support if this is enabled, as some legacy
+		 * devices won't operate well if fast DMA is disabled.
+		 */
+		dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
+			PCI_DEVICE_ID_INTEL_82371AB_0,
+			PCI_ANY_ID, PCI_ANY_ID, NULL);
+		if (dev) {
+			pci_read_config_byte(dev, 0x76, &value1);
+			pci_read_config_byte(dev, 0x77, &value2);
+			if ((value1 & 0x80) || (value2 & 0x80))
+				errata.piix4.fdma = 1;
+			pci_dev_put(dev);
+		}
+
+		break;
+	}
+
+	if (errata.piix4.bmisx)
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+			"Bus master activity detection (BM-IDE) erratum enabled\n"));
+	if (errata.piix4.fdma)
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+			"Type-F DMA livelock erratum (C3 disabled)\n"));
+
+	return_VALUE(0);
+}
+
+
+int
+acpi_processor_errata (
+	struct acpi_processor	*pr)
+{
+	int			result = 0;
+	struct pci_dev		*dev = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_errata");
+
+	if (!pr)
+		return_VALUE(-EINVAL);
+
+	/*
+	 * PIIX4
+	 */
+	dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
+		PCI_DEVICE_ID_INTEL_82371AB_3, PCI_ANY_ID, PCI_ANY_ID, NULL);
+	if (dev) {
+		result = acpi_processor_errata_piix4(dev);
+		pci_dev_put(dev);
+	}
+
+	return_VALUE(result);
+}
+
+
+/* --------------------------------------------------------------------------
+                              FS Interface (/proc)
+   -------------------------------------------------------------------------- */
+
+struct proc_dir_entry		*acpi_processor_dir = NULL;
+
+static int acpi_processor_info_seq_show(struct seq_file *seq, void *offset)
+{
+	struct acpi_processor	*pr = (struct acpi_processor *)seq->private;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_info_seq_show");
+
+	if (!pr)
+		goto end;
+
+	seq_printf(seq, "processor id:            %d\n"
+			"acpi id:                 %d\n"
+			"bus mastering control:   %s\n"
+			"power management:        %s\n"
+			"throttling control:      %s\n"
+			"limit interface:         %s\n",
+			pr->id,
+			pr->acpi_id,
+			pr->flags.bm_control ? "yes" : "no",
+			pr->flags.power ? "yes" : "no",
+			pr->flags.throttling ? "yes" : "no",
+			pr->flags.limit ? "yes" : "no");
+
+end:
+	return_VALUE(0);
+}
+
+static int acpi_processor_info_open_fs(struct inode *inode, struct file *file)
+{
+	return single_open(file, acpi_processor_info_seq_show,
+						PDE(inode)->data);
+}
+
+
+static int
+acpi_processor_add_fs (
+	struct acpi_device	*device)
+{
+	struct proc_dir_entry	*entry = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_add_fs");
+
+	if (!acpi_device_dir(device)) {
+		acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
+			acpi_processor_dir);
+		if (!acpi_device_dir(device))
+			return_VALUE(-ENODEV);
+	}
+	acpi_device_dir(device)->owner = THIS_MODULE;
+
+	/* 'info' [R] */
+	entry = create_proc_entry(ACPI_PROCESSOR_FILE_INFO,
+		S_IRUGO, acpi_device_dir(device));
+	if (!entry)
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Unable to create '%s' fs entry\n",
+			ACPI_PROCESSOR_FILE_INFO));
+	else {
+		entry->proc_fops = &acpi_processor_info_fops;
+		entry->data = acpi_driver_data(device);
+		entry->owner = THIS_MODULE;
+	}
+
+	/* 'throttling' [R/W] */
+	entry = create_proc_entry(ACPI_PROCESSOR_FILE_THROTTLING,
+		S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device));
+	if (!entry)
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Unable to create '%s' fs entry\n",
+			ACPI_PROCESSOR_FILE_THROTTLING));
+	else {
+		entry->proc_fops = &acpi_processor_throttling_fops;
+		entry->proc_fops->write = acpi_processor_write_throttling;
+		entry->data = acpi_driver_data(device);
+		entry->owner = THIS_MODULE;
+	}
+
+	/* 'limit' [R/W] */
+	entry = create_proc_entry(ACPI_PROCESSOR_FILE_LIMIT,
+		S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device));
+	if (!entry)
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Unable to create '%s' fs entry\n",
+			ACPI_PROCESSOR_FILE_LIMIT));
+	else {
+		entry->proc_fops = &acpi_processor_limit_fops;
+		entry->proc_fops->write = acpi_processor_write_limit;
+		entry->data = acpi_driver_data(device);
+		entry->owner = THIS_MODULE;
+	}
+
+	return_VALUE(0);
+}
+
+
+static int
+acpi_processor_remove_fs (
+	struct acpi_device	*device)
+{
+	ACPI_FUNCTION_TRACE("acpi_processor_remove_fs");
+
+	if (acpi_device_dir(device)) {
+		remove_proc_entry(ACPI_PROCESSOR_FILE_INFO,acpi_device_dir(device));
+		remove_proc_entry(ACPI_PROCESSOR_FILE_THROTTLING,
+			acpi_device_dir(device));
+		remove_proc_entry(ACPI_PROCESSOR_FILE_LIMIT,acpi_device_dir(device));
+		remove_proc_entry(acpi_device_bid(device), acpi_processor_dir);
+		acpi_device_dir(device) = NULL;
+	}
+
+	return_VALUE(0);
+}
+
+/* Use the acpiid in MADT to map cpus in case of SMP */
+#ifndef CONFIG_SMP
+#define convert_acpiid_to_cpu(acpi_id) (0xff)
+#else
+
+#ifdef CONFIG_IA64
+#define arch_acpiid_to_apicid 	ia64_acpiid_to_sapicid
+#define arch_cpu_to_apicid 	ia64_cpu_to_sapicid
+#define ARCH_BAD_APICID		(0xffff)
+#else
+#define arch_acpiid_to_apicid 	x86_acpiid_to_apicid
+#define arch_cpu_to_apicid 	x86_cpu_to_apicid
+#define ARCH_BAD_APICID		(0xff)
+#endif
+
+static u8 convert_acpiid_to_cpu(u8 acpi_id)
+{
+	u16 apic_id;
+	int i;
+
+	apic_id = arch_acpiid_to_apicid[acpi_id];
+	if (apic_id == ARCH_BAD_APICID)
+		return -1;
+
+	for (i = 0; i < NR_CPUS; i++) {
+		if (arch_cpu_to_apicid[i] == apic_id)
+			return i;
+	}
+	return -1;
+}
+#endif
+
+/* --------------------------------------------------------------------------
+                                 Driver Interface
+   -------------------------------------------------------------------------- */
+
+static int
+acpi_processor_get_info (
+	struct acpi_processor	*pr)
+{
+	acpi_status		status = 0;
+	union acpi_object	object = {0};
+	struct acpi_buffer	buffer = {sizeof(union acpi_object), &object};
+	u8			cpu_index;
+	static int		cpu0_initialized;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_get_info");
+
+	if (!pr)
+		return_VALUE(-EINVAL);
+
+	if (num_online_cpus() > 1)
+		errata.smp = TRUE;
+
+	acpi_processor_errata(pr);
+
+	/*
+	 * Check to see if we have bus mastering arbitration control.  This
+	 * is required for proper C3 usage (to maintain cache coherency).
+	 */
+	if (acpi_fadt.V1_pm2_cnt_blk && acpi_fadt.pm2_cnt_len) {
+		pr->flags.bm_control = 1;
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+			"Bus mastering arbitration control present\n"));
+	}
+	else
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+			"No bus mastering arbitration control\n"));
+
+	/*
+	 * Evalute the processor object.  Note that it is common on SMP to
+	 * have the first (boot) processor with a valid PBLK address while
+	 * all others have a NULL address.
+	 */
+	status = acpi_evaluate_object(pr->handle, NULL, NULL, &buffer);
+	if (ACPI_FAILURE(status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Error evaluating processor object\n"));
+		return_VALUE(-ENODEV);
+	}
+
+	/*
+	 * TBD: Synch processor ID (via LAPIC/LSAPIC structures) on SMP.
+	 *	>>> 'acpi_get_processor_id(acpi_id, &id)' in arch/xxx/acpi.c
+	 */
+	pr->acpi_id = object.processor.proc_id;
+
+	cpu_index = convert_acpiid_to_cpu(pr->acpi_id);
+
+  	/* Handle UP system running SMP kernel, with no LAPIC in MADT */
+  	if ( !cpu0_initialized && (cpu_index == 0xff) &&
+  		       	(num_online_cpus() == 1)) {
+   		cpu_index = 0;
+   	}
+
+   	cpu0_initialized = 1;
+
+   	pr->id = cpu_index;
+
+  	/*
+  	 *  Extra Processor objects may be enumerated on MP systems with
+  	 *  less than the max # of CPUs. They should be ignored _iff
+  	 *  they are physically not present.
+  	 */
+   	if (cpu_index >=  NR_CPUS) {
+   		if (ACPI_FAILURE(acpi_processor_hotadd_init(pr->handle, &pr->id))) {
+   			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+   				"Error getting cpuindex for acpiid 0x%x\n",
+   				pr->acpi_id));
+   			return_VALUE(-ENODEV);
+   		}
+    	}
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Processor [%d:%d]\n", pr->id,
+		pr->acpi_id));
+
+	if (!object.processor.pblk_address)
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No PBLK (NULL address)\n"));
+	else if (object.processor.pblk_length != 6)
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid PBLK length [%d]\n",
+			object.processor.pblk_length));
+	else {
+		pr->throttling.address = object.processor.pblk_address;
+		pr->throttling.duty_offset = acpi_fadt.duty_offset;
+		pr->throttling.duty_width = acpi_fadt.duty_width;
+
+		pr->pblk = object.processor.pblk_address;
+
+		/*
+		 * We don't care about error returns - we just try to mark
+		 * these reserved so that nobody else is confused into thinking
+		 * that this region might be unused..
+		 *
+		 * (In particular, allocating the IO range for Cardbus)
+		 */
+		request_region(pr->throttling.address, 6, "ACPI CPU throttle");
+	}
+
+#ifdef CONFIG_CPU_FREQ
+	acpi_processor_ppc_has_changed(pr);
+#endif
+	acpi_processor_get_throttling_info(pr);
+	acpi_processor_get_limit_info(pr);
+
+	return_VALUE(0);
+}
+
+static int
+acpi_processor_start(
+	struct acpi_device	*device)
+{
+	int			result = 0;
+	acpi_status		status = AE_OK;
+	struct acpi_processor	*pr;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_start");
+
+	pr = acpi_driver_data(device);
+
+	result = acpi_processor_get_info(pr);
+	if (result) {
+		/* Processor is physically not present */
+		return_VALUE(0);
+	}
+
+	BUG_ON((pr->id >= NR_CPUS) || (pr->id < 0));
+
+	processors[pr->id] = pr;
+
+	result = acpi_processor_add_fs(device);
+	if (result)
+		goto end;
+
+	status = acpi_install_notify_handler(pr->handle, ACPI_DEVICE_NOTIFY,
+		acpi_processor_notify, pr);
+	if (ACPI_FAILURE(status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Error installing device notify handler\n"));
+	}
+
+	acpi_processor_power_init(pr, device);
+
+	if (pr->flags.throttling) {
+		printk(KERN_INFO PREFIX "%s [%s] (supports",
+			acpi_device_name(device), acpi_device_bid(device));
+		printk(" %d throttling states", pr->throttling.state_count);
+		printk(")\n");
+	}
+
+end:
+
+	return_VALUE(result);
+}
+
+
+
+static void
+acpi_processor_notify (
+	acpi_handle		handle,
+	u32			event,
+	void			*data)
+{
+	struct acpi_processor	*pr = (struct acpi_processor *) data;
+	struct acpi_device	*device = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_notify");
+
+	if (!pr)
+		return_VOID;
+
+	if (acpi_bus_get_device(pr->handle, &device))
+		return_VOID;
+
+	switch (event) {
+	case ACPI_PROCESSOR_NOTIFY_PERFORMANCE:
+		acpi_processor_ppc_has_changed(pr);
+		acpi_bus_generate_event(device, event,
+			pr->performance_platform_limit);
+		break;
+	case ACPI_PROCESSOR_NOTIFY_POWER:
+		acpi_processor_cst_has_changed(pr);
+		acpi_bus_generate_event(device, event, 0);
+		break;
+	default:
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+			"Unsupported event [0x%x]\n", event));
+		break;
+	}
+
+	return_VOID;
+}
+
+
+static int
+acpi_processor_add (
+	struct acpi_device	*device)
+{
+	struct acpi_processor	*pr = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_add");
+
+	if (!device)
+		return_VALUE(-EINVAL);
+
+	pr = kmalloc(sizeof(struct acpi_processor), GFP_KERNEL);
+	if (!pr)
+		return_VALUE(-ENOMEM);
+	memset(pr, 0, sizeof(struct acpi_processor));
+
+	pr->handle = device->handle;
+	strcpy(acpi_device_name(device), ACPI_PROCESSOR_DEVICE_NAME);
+	strcpy(acpi_device_class(device), ACPI_PROCESSOR_CLASS);
+	acpi_driver_data(device) = pr;
+
+	return_VALUE(0);
+}
+
+
+static int
+acpi_processor_remove (
+	struct acpi_device	*device,
+	int			type)
+{
+	acpi_status		status = AE_OK;
+	struct acpi_processor	*pr = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_remove");
+
+	if (!device || !acpi_driver_data(device))
+		return_VALUE(-EINVAL);
+
+	pr = (struct acpi_processor *) acpi_driver_data(device);
+
+	if (pr->id >= NR_CPUS) {
+		kfree(pr);
+		return_VALUE(0);
+	}
+
+	if (type == ACPI_BUS_REMOVAL_EJECT) {
+		if (acpi_processor_handle_eject(pr))
+			return_VALUE(-EINVAL);
+	}
+
+	acpi_processor_power_exit(pr, device);
+
+	status = acpi_remove_notify_handler(pr->handle, ACPI_DEVICE_NOTIFY,
+		acpi_processor_notify);
+	if (ACPI_FAILURE(status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Error removing notify handler\n"));
+	}
+
+	acpi_processor_remove_fs(device);
+
+	processors[pr->id] = NULL;
+
+	kfree(pr);
+
+	return_VALUE(0);
+}
+
+#ifdef CONFIG_ACPI_HOTPLUG_CPU
+/****************************************************************************
+ * 	Acpi processor hotplug support 				       	    *
+ ****************************************************************************/
+
+static int is_processor_present(acpi_handle handle);
+
+static int
+is_processor_present(
+	acpi_handle handle)
+{
+	acpi_status 		status;
+	unsigned long		sta = 0;
+
+	ACPI_FUNCTION_TRACE("is_processor_present");
+
+	status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
+	if (ACPI_FAILURE(status) || !(sta & ACPI_STA_PRESENT)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Processor Device is not present\n"));
+		return_VALUE(0);
+	}
+	return_VALUE(1);
+}
+
+
+static
+int acpi_processor_device_add(
+	acpi_handle	handle,
+	struct acpi_device **device)
+{
+	acpi_handle		phandle;
+	struct acpi_device 	*pdev;
+	struct acpi_processor	*pr;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_device_add");
+
+	if (acpi_get_parent(handle, &phandle)) {
+		return_VALUE(-ENODEV);
+	}
+
+	if (acpi_bus_get_device(phandle, &pdev)) {
+		return_VALUE(-ENODEV);
+	}
+
+	if (acpi_bus_add(device, pdev, handle, ACPI_BUS_TYPE_PROCESSOR)) {
+		return_VALUE(-ENODEV);
+	}
+
+	acpi_bus_scan(*device);
+
+	pr = acpi_driver_data(*device);
+	if (!pr)
+		return_VALUE(-ENODEV);
+
+	if ((pr->id >=0) && (pr->id < NR_CPUS)) {
+		kobject_hotplug(&(*device)->kobj, KOBJ_ONLINE);
+	}
+	return_VALUE(0);
+}
+
+
+static void
+acpi_processor_hotplug_notify (
+	acpi_handle		handle,
+	u32			event,
+	void			*data)
+{
+	struct acpi_processor	*pr;
+	struct acpi_device	*device = NULL;
+	int result;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_hotplug_notify");
+
+	switch (event) {
+	case ACPI_NOTIFY_BUS_CHECK:
+	case ACPI_NOTIFY_DEVICE_CHECK:
+		printk("Processor driver received %s event\n",
+			(event==ACPI_NOTIFY_BUS_CHECK)?
+			"ACPI_NOTIFY_BUS_CHECK":"ACPI_NOTIFY_DEVICE_CHECK");
+
+		if (!is_processor_present(handle))
+			break;
+
+		if (acpi_bus_get_device(handle, &device)) {
+			result = acpi_processor_device_add(handle, &device);
+			if (result)
+				ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+					"Unable to add the device\n"));
+			break;
+		}
+
+		pr = acpi_driver_data(device);
+		if (!pr) {
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				"Driver data is NULL\n"));
+			break;
+		}
+
+		if (pr->id >= 0 && (pr->id < NR_CPUS)) {
+			kobject_hotplug(&device->kobj, KOBJ_OFFLINE);
+			break;
+		}
+
+		result = acpi_processor_start(device);
+		if ((!result) && ((pr->id >=0) && (pr->id < NR_CPUS))) {
+			kobject_hotplug(&device->kobj, KOBJ_ONLINE);
+		} else {
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				"Device [%s] failed to start\n",
+				acpi_device_bid(device)));
+		}
+	break;
+	case ACPI_NOTIFY_EJECT_REQUEST:
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,"received ACPI_NOTIFY_EJECT_REQUEST\n"));
+
+		if (acpi_bus_get_device(handle, &device)) {
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,"Device don't exist, dropping EJECT\n"));
+			break;
+		}
+		pr = acpi_driver_data(device);
+		if (!pr) {
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,"Driver data is NULL, dropping EJECT\n"));
+			return_VOID;
+		}
+
+		if ((pr->id < NR_CPUS) && (cpu_present(pr->id)))
+			kobject_hotplug(&device->kobj, KOBJ_OFFLINE);
+		break;
+	default:
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+			"Unsupported event [0x%x]\n", event));
+		break;
+	}
+
+	return_VOID;
+}
+
+static acpi_status
+processor_walk_namespace_cb(acpi_handle handle,
+	u32 lvl,
+	void *context,
+	void **rv)
+{
+	acpi_status 			status;
+	int *action = context;
+	acpi_object_type	type = 0;
+
+	status = acpi_get_type(handle, &type);
+	if (ACPI_FAILURE(status))
+		return(AE_OK);
+
+	if (type != ACPI_TYPE_PROCESSOR)
+		return(AE_OK);
+
+	switch(*action) {
+	case INSTALL_NOTIFY_HANDLER:
+		acpi_install_notify_handler(handle,
+			ACPI_SYSTEM_NOTIFY,
+			acpi_processor_hotplug_notify,
+			NULL);
+		break;
+	case UNINSTALL_NOTIFY_HANDLER:
+		acpi_remove_notify_handler(handle,
+			ACPI_SYSTEM_NOTIFY,
+			acpi_processor_hotplug_notify);
+		break;
+	default:
+		break;
+	}
+
+	return(AE_OK);
+}
+
+
+static acpi_status
+acpi_processor_hotadd_init(
+	acpi_handle		handle,
+	int			*p_cpu)
+{
+	ACPI_FUNCTION_TRACE("acpi_processor_hotadd_init");
+
+	if (!is_processor_present(handle)) {
+		return_VALUE(AE_ERROR);
+	}
+
+	if (acpi_map_lsapic(handle, p_cpu))
+		return_VALUE(AE_ERROR);
+
+	if (arch_register_cpu(*p_cpu)) {
+		acpi_unmap_lsapic(*p_cpu);
+		return_VALUE(AE_ERROR);
+	}
+
+	return_VALUE(AE_OK);
+}
+
+
+static int
+acpi_processor_handle_eject(struct acpi_processor *pr)
+{
+	if (cpu_online(pr->id)) {
+		return(-EINVAL);
+	}
+	arch_unregister_cpu(pr->id);
+	acpi_unmap_lsapic(pr->id);
+	return(0);
+}
+#else
+static acpi_status
+acpi_processor_hotadd_init(
+	acpi_handle		handle,
+	int			*p_cpu)
+{
+	return AE_ERROR;
+}
+static int
+acpi_processor_handle_eject(struct acpi_processor *pr)
+{
+	return(-EINVAL);
+}
+#endif
+
+
+static
+void acpi_processor_install_hotplug_notify(void)
+{
+#ifdef CONFIG_ACPI_HOTPLUG_CPU
+	int action = INSTALL_NOTIFY_HANDLER;
+	acpi_walk_namespace(ACPI_TYPE_PROCESSOR,
+				     ACPI_ROOT_OBJECT,
+				     ACPI_UINT32_MAX,
+				     processor_walk_namespace_cb,
+				     &action, NULL);
+#endif
+}
+
+
+static
+void acpi_processor_uninstall_hotplug_notify(void)
+{
+#ifdef CONFIG_ACPI_HOTPLUG_CPU
+	int action = UNINSTALL_NOTIFY_HANDLER;
+	acpi_walk_namespace(ACPI_TYPE_PROCESSOR,
+				     ACPI_ROOT_OBJECT,
+				     ACPI_UINT32_MAX,
+				     processor_walk_namespace_cb,
+				     &action, NULL);
+#endif
+}
+
+/*
+ * We keep the driver loaded even when ACPI is not running.
+ * This is needed for the powernow-k8 driver, that works even without
+ * ACPI, but needs symbols from this driver
+ */
+
+static int __init
+acpi_processor_init (void)
+{
+	int			result = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_init");
+
+	memset(&processors, 0, sizeof(processors));
+	memset(&errata, 0, sizeof(errata));
+
+	acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir);
+	if (!acpi_processor_dir)
+		return_VALUE(0);
+	acpi_processor_dir->owner = THIS_MODULE;
+
+	result = acpi_bus_register_driver(&acpi_processor_driver);
+	if (result < 0) {
+		remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir);
+		return_VALUE(0);
+	}
+
+	acpi_processor_install_hotplug_notify();
+
+	acpi_thermal_cpufreq_init();
+
+	acpi_processor_ppc_init();
+
+	return_VALUE(0);
+}
+
+
+static void __exit
+acpi_processor_exit (void)
+{
+	ACPI_FUNCTION_TRACE("acpi_processor_exit");
+
+	acpi_processor_ppc_exit();
+
+	acpi_thermal_cpufreq_exit();
+
+	acpi_processor_uninstall_hotplug_notify();
+
+	acpi_bus_unregister_driver(&acpi_processor_driver);
+
+	remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir);
+
+	return_VOID;
+}
+
+
+module_init(acpi_processor_init);
+module_exit(acpi_processor_exit);
+
+EXPORT_SYMBOL(acpi_processor_set_thermal_limit);
+
+MODULE_ALIAS("processor");
diff -Nru a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/acpi/processor_idle.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,1017 @@
+/*
+ * processor_idle - idle state submodule to the ACPI processor driver
+ *
+ *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
+ *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
+ *  Copyright (C) 2004       Dominik Brodowski <linux@brodo.de>
+ *  Copyright (C) 2004  Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
+ *  			- Added processor hotplug 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/module.h>
+#include <linux/init.h>
+#include <linux/cpufreq.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <linux/acpi.h>
+#include <linux/dmi.h>
+#include <linux/moduleparam.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+
+#include <acpi/acpi_bus.h>
+#include <acpi/processor.h>
+
+#define ACPI_PROCESSOR_COMPONENT        0x01000000
+#define ACPI_PROCESSOR_CLASS            "processor"
+#define ACPI_PROCESSOR_DRIVER_NAME      "ACPI Processor Driver"
+#define _COMPONENT              ACPI_PROCESSOR_COMPONENT
+ACPI_MODULE_NAME                ("acpi_processor")
+
+#define ACPI_PROCESSOR_FILE_POWER	"power"
+
+#define US_TO_PM_TIMER_TICKS(t)		((t * (PM_TIMER_FREQUENCY/1000)) / 1000)
+#define C2_OVERHEAD			4	/* 1us (3.579 ticks per us) */
+#define C3_OVERHEAD			4	/* 1us (3.579 ticks per us) */
+
+static void (*pm_idle_save)(void);
+module_param(max_cstate, uint, 0644);
+
+static unsigned int nocst = 0;
+module_param(nocst, uint, 0000);
+
+/*
+ * bm_history -- bit-mask with a bit per jiffy of bus-master activity
+ * 1000 HZ: 0xFFFFFFFF: 32 jiffies = 32ms
+ * 800 HZ: 0xFFFFFFFF: 32 jiffies = 40ms
+ * 100 HZ: 0x0000000F: 4 jiffies = 40ms
+ * reduce history for more aggressive entry into C3
+ */
+static unsigned int bm_history = (HZ >= 800 ? 0xFFFFFFFF : ((1U << (HZ / 25)) - 1));
+module_param(bm_history, uint, 0644);
+/* --------------------------------------------------------------------------
+                                Power Management
+   -------------------------------------------------------------------------- */
+
+/*
+ * IBM ThinkPad R40e crashes mysteriously when going into C2 or C3.
+ * For now disable this. Probably a bug somewhere else.
+ *
+ * To skip this limit, boot/load with a large max_cstate limit.
+ */
+static int no_c2c3(struct dmi_system_id *id)
+{
+	if (max_cstate > ACPI_PROCESSOR_MAX_POWER)
+		return 0;
+
+	printk(KERN_NOTICE PREFIX "%s detected - C2,C3 disabled."
+		" Override with \"processor.max_cstate=%d\"\n", id->ident,
+	       ACPI_PROCESSOR_MAX_POWER + 1);
+
+	max_cstate = 1;
+
+	return 0;
+}
+
+
+
+
+static struct dmi_system_id __initdata processor_power_dmi_table[] = {
+	{ no_c2c3, "IBM ThinkPad R40e", {
+	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
+	  DMI_MATCH(DMI_BIOS_VERSION,"1SET60WW") }},
+	{ no_c2c3, "Medion 41700", {
+	  DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
+	  DMI_MATCH(DMI_BIOS_VERSION,"R01-A1J") }},
+	{},
+};
+
+
+static inline u32
+ticks_elapsed (
+	u32			t1,
+	u32			t2)
+{
+	if (t2 >= t1)
+		return (t2 - t1);
+	else if (!acpi_fadt.tmr_val_ext)
+		return (((0x00FFFFFF - t1) + t2) & 0x00FFFFFF);
+	else
+		return ((0xFFFFFFFF - t1) + t2);
+}
+
+
+static void
+acpi_processor_power_activate (
+	struct acpi_processor	*pr,
+	struct acpi_processor_cx  *new)
+{
+	struct acpi_processor_cx  *old;
+
+	if (!pr || !new)
+		return;
+
+	old = pr->power.state;
+
+	if (old)
+		old->promotion.count = 0;
+ 	new->demotion.count = 0;
+
+	/* Cleanup from old state. */
+	if (old) {
+		switch (old->type) {
+		case ACPI_STATE_C3:
+			/* Disable bus master reload */
+			if (new->type != ACPI_STATE_C3)
+				acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0, ACPI_MTX_DO_NOT_LOCK);
+			break;
+		}
+	}
+
+	/* Prepare to use new state. */
+	switch (new->type) {
+	case ACPI_STATE_C3:
+		/* Enable bus master reload */
+		if (old->type != ACPI_STATE_C3)
+			acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1, ACPI_MTX_DO_NOT_LOCK);
+		break;
+	}
+
+	pr->power.state = new;
+
+	return;
+}
+
+
+static void acpi_processor_idle (void)
+{
+	struct acpi_processor	*pr = NULL;
+	struct acpi_processor_cx *cx = NULL;
+	struct acpi_processor_cx *next_state = NULL;
+	int			sleep_ticks = 0;
+	u32			t1, t2 = 0;
+
+	pr = processors[_smp_processor_id()];
+	if (!pr)
+		return;
+
+	/*
+	 * Interrupts must be disabled during bus mastering calculations and
+	 * for C2/C3 transitions.
+	 */
+	local_irq_disable();
+
+	/*
+	 * Check whether we truly need to go idle, or should
+	 * reschedule:
+	 */
+	if (unlikely(need_resched())) {
+		local_irq_enable();
+		return;
+	}
+
+	cx = pr->power.state;
+	if (!cx)
+		goto easy_out;
+
+	/*
+	 * Check BM Activity
+	 * -----------------
+	 * Check for bus mastering activity (if required), record, and check
+	 * for demotion.
+	 */
+	if (pr->flags.bm_check) {
+		u32		bm_status = 0;
+		unsigned long	diff = jiffies - pr->power.bm_check_timestamp;
+
+		if (diff > 32)
+			diff = 32;
+
+		while (diff) {
+			/* if we didn't get called, assume there was busmaster activity */
+			diff--;
+			if (diff)
+				pr->power.bm_activity |= 0x1;
+			pr->power.bm_activity <<= 1;
+		}
+
+		acpi_get_register(ACPI_BITREG_BUS_MASTER_STATUS,
+			&bm_status, ACPI_MTX_DO_NOT_LOCK);
+		if (bm_status) {
+			pr->power.bm_activity++;
+			acpi_set_register(ACPI_BITREG_BUS_MASTER_STATUS,
+				1, ACPI_MTX_DO_NOT_LOCK);
+		}
+		/*
+		 * PIIX4 Erratum #18: Note that BM_STS doesn't always reflect
+		 * the true state of bus mastering activity; forcing us to
+		 * manually check the BMIDEA bit of each IDE channel.
+		 */
+		else if (errata.piix4.bmisx) {
+			if ((inb_p(errata.piix4.bmisx + 0x02) & 0x01)
+				|| (inb_p(errata.piix4.bmisx + 0x0A) & 0x01))
+				pr->power.bm_activity++;
+		}
+
+		pr->power.bm_check_timestamp = jiffies;
+
+		/*
+		 * Apply bus mastering demotion policy.  Automatically demote
+		 * to avoid a faulty transition.  Note that the processor
+		 * won't enter a low-power state during this call (to this
+		 * funciton) but should upon the next.
+		 *
+		 * TBD: A better policy might be to fallback to the demotion
+		 *      state (use it for this quantum only) istead of
+		 *      demoting -- and rely on duration as our sole demotion
+		 *      qualification.  This may, however, introduce DMA
+		 *      issues (e.g. floppy DMA transfer overrun/underrun).
+		 */
+		if (pr->power.bm_activity & cx->demotion.threshold.bm) {
+			local_irq_enable();
+			next_state = cx->demotion.state;
+			goto end;
+		}
+	}
+
+	cx->usage++;
+
+	/*
+	 * Sleep:
+	 * ------
+	 * Invoke the current Cx state to put the processor to sleep.
+	 */
+	switch (cx->type) {
+
+	case ACPI_STATE_C1:
+		/*
+		 * Invoke C1.
+		 * Use the appropriate idle routine, the one that would
+		 * be used without acpi C-states.
+		 */
+		if (pm_idle_save)
+			pm_idle_save();
+		else
+			safe_halt();
+		/*
+                 * TBD: Can't get time duration while in C1, as resumes
+		 *      go to an ISR rather than here.  Need to instrument
+		 *      base interrupt handler.
+		 */
+		sleep_ticks = 0xFFFFFFFF;
+		break;
+
+	case ACPI_STATE_C2:
+		/* Get start time (ticks) */
+		t1 = inl(acpi_fadt.xpm_tmr_blk.address);
+		/* Invoke C2 */
+		inb(cx->address);
+		/* Dummy op - must do something useless after P_LVL2 read */
+		t2 = inl(acpi_fadt.xpm_tmr_blk.address);
+		/* Get end time (ticks) */
+		t2 = inl(acpi_fadt.xpm_tmr_blk.address);
+		/* Re-enable interrupts */
+		local_irq_enable();
+		/* Compute time (ticks) that we were actually asleep */
+		sleep_ticks = ticks_elapsed(t1, t2) - cx->latency_ticks - C2_OVERHEAD;
+		break;
+
+	case ACPI_STATE_C3:
+		/* Disable bus master arbitration */
+		acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1, ACPI_MTX_DO_NOT_LOCK);
+		/* Get start time (ticks) */
+		t1 = inl(acpi_fadt.xpm_tmr_blk.address);
+		/* Invoke C3 */
+		inb(cx->address);
+		/* Dummy op - must do something useless after P_LVL3 read */
+		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);
+		/* Re-enable interrupts */
+		local_irq_enable();
+		/* Compute time (ticks) that we were actually asleep */
+		sleep_ticks = ticks_elapsed(t1, t2) - cx->latency_ticks - C3_OVERHEAD;
+		break;
+
+	default:
+		local_irq_enable();
+		return;
+	}
+
+	next_state = pr->power.state;
+
+	/*
+	 * Promotion?
+	 * ----------
+	 * Track the number of longs (time asleep is greater than threshold)
+	 * and promote when the count threshold is reached.  Note that bus
+	 * mastering activity may prevent promotions.
+	 * Do not promote above max_cstate.
+	 */
+	if (cx->promotion.state &&
+	    ((cx->promotion.state - pr->power.states) <= max_cstate)) {
+		if (sleep_ticks > cx->promotion.threshold.ticks) {
+			cx->promotion.count++;
+ 			cx->demotion.count = 0;
+			if (cx->promotion.count >= cx->promotion.threshold.count) {
+				if (pr->flags.bm_check) {
+					if (!(pr->power.bm_activity & cx->promotion.threshold.bm)) {
+						next_state = cx->promotion.state;
+						goto end;
+					}
+				}
+				else {
+					next_state = cx->promotion.state;
+					goto end;
+				}
+			}
+		}
+	}
+
+	/*
+	 * Demotion?
+	 * ---------
+	 * Track the number of shorts (time asleep is less than time threshold)
+	 * and demote when the usage threshold is reached.
+	 */
+	if (cx->demotion.state) {
+		if (sleep_ticks < cx->demotion.threshold.ticks) {
+			cx->demotion.count++;
+			cx->promotion.count = 0;
+			if (cx->demotion.count >= cx->demotion.threshold.count) {
+				next_state = cx->demotion.state;
+				goto end;
+			}
+		}
+	}
+
+end:
+	/*
+	 * Demote if current state exceeds max_cstate
+	 */
+	if ((pr->power.state - pr->power.states) > max_cstate) {
+		if (cx->demotion.state)
+			next_state = cx->demotion.state;
+	}
+
+	/*
+	 * New Cx State?
+	 * -------------
+	 * If we're going to start using a new Cx state we must clean up
+	 * from the previous and prepare to use the new.
+	 */
+	if (next_state != pr->power.state)
+		acpi_processor_power_activate(pr, next_state);
+
+	return;
+
+ easy_out:
+	/* do C1 instead of busy loop */
+	if (pm_idle_save)
+		pm_idle_save();
+	else
+		safe_halt();
+	return;
+}
+
+
+static int
+acpi_processor_set_power_policy (
+	struct acpi_processor	*pr)
+{
+	unsigned int i;
+	unsigned int state_is_set = 0;
+	struct acpi_processor_cx *lower = NULL;
+	struct acpi_processor_cx *higher = NULL;
+	struct acpi_processor_cx *cx;
+
+ 	ACPI_FUNCTION_TRACE("acpi_processor_set_power_policy");
+
+	if (!pr)
+		return_VALUE(-EINVAL);
+
+	/*
+	 * This function sets the default Cx state policy (OS idle handler).
+	 * Our scheme is to promote quickly to C2 but more conservatively
+	 * to C3.  We're favoring C2  for its characteristics of low latency
+	 * (quick response), good power savings, and ability to allow bus
+	 * mastering activity.  Note that the Cx state policy is completely
+	 * customizable and can be altered dynamically.
+	 */
+
+	/* startup state */
+	for (i=1; i < ACPI_PROCESSOR_MAX_POWER; i++) {
+		cx = &pr->power.states[i];
+		if (!cx->valid)
+			continue;
+
+		if (!state_is_set)
+			pr->power.state = cx;
+		state_is_set++;
+		break;
+ 	}
+
+	if (!state_is_set)
+		return_VALUE(-ENODEV);
+
+	/* demotion */
+	for (i=1; i < ACPI_PROCESSOR_MAX_POWER; i++) {
+		cx = &pr->power.states[i];
+		if (!cx->valid)
+			continue;
+
+		if (lower) {
+			cx->demotion.state = lower;
+			cx->demotion.threshold.ticks = cx->latency_ticks;
+			cx->demotion.threshold.count = 1;
+			if (cx->type == ACPI_STATE_C3)
+				cx->demotion.threshold.bm = bm_history;
+		}
+
+		lower = cx;
+	}
+
+	/* promotion */
+	for (i = (ACPI_PROCESSOR_MAX_POWER - 1); i > 0; i--) {
+		cx = &pr->power.states[i];
+		if (!cx->valid)
+			continue;
+
+		if (higher) {
+			cx->promotion.state  = higher;
+			cx->promotion.threshold.ticks = cx->latency_ticks;
+			if (cx->type >= ACPI_STATE_C2)
+				cx->promotion.threshold.count = 4;
+			else
+				cx->promotion.threshold.count = 10;
+			if (higher->type == ACPI_STATE_C3)
+				cx->promotion.threshold.bm = bm_history;
+		}
+
+		higher = cx;
+	}
+
+ 	return_VALUE(0);
+}
+
+
+static int acpi_processor_get_power_info_fadt (struct acpi_processor *pr)
+{
+	int i;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_get_power_info_fadt");
+
+	if (!pr)
+		return_VALUE(-EINVAL);
+
+	if (!pr->pblk)
+		return_VALUE(-ENODEV);
+
+	for (i = 0; i < ACPI_PROCESSOR_MAX_POWER; i++)
+		memset(pr->power.states, 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;
+
+	/* determine C2 and C3 address from pblk */
+	pr->power.states[ACPI_STATE_C2].address = pr->pblk + 4;
+	pr->power.states[ACPI_STATE_C3].address = pr->pblk + 5;
+
+	/* determine latencies from FADT */
+	pr->power.states[ACPI_STATE_C2].latency = acpi_fadt.plvl2_lat;
+	pr->power.states[ACPI_STATE_C3].latency = acpi_fadt.plvl3_lat;
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+			  "lvl2[0x%08x] lvl3[0x%08x]\n",
+			  pr->power.states[ACPI_STATE_C2].address,
+			  pr->power.states[ACPI_STATE_C3].address));
+
+	return_VALUE(0);
+}
+
+
+static int acpi_processor_get_power_info_cst (struct acpi_processor *pr)
+{
+	acpi_status		status = 0;
+	acpi_integer		count;
+	int			i;
+	struct acpi_buffer	buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+	union acpi_object	*cst;
+
+	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));
+
+	status = acpi_evaluate_object(pr->handle, "_CST", NULL, &buffer);
+	if (ACPI_FAILURE(status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No _CST, giving up\n"));
+		return_VALUE(-ENODEV);
+ 	}
+
+	cst = (union acpi_object *) buffer.pointer;
+
+	/* There must be at least 2 elements */
+	if (!cst || (cst->type != ACPI_TYPE_PACKAGE) || cst->package.count < 2) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "not enough elements in _CST\n"));
+		status = -EFAULT;
+		goto end;
+	}
+
+	count = cst->package.elements[0].integer.value;
+
+	/* Validate number of power states. */
+	if (count < 1 || count != cst->package.count - 1) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "count given by _CST is not valid\n"));
+		status = -EFAULT;
+		goto end;
+	}
+
+	/* We support up to ACPI_PROCESSOR_MAX_POWER. */
+	if (count > ACPI_PROCESSOR_MAX_POWER) {
+		printk(KERN_WARNING "Limiting number of power states to max (%d)\n", ACPI_PROCESSOR_MAX_POWER);
+		printk(KERN_WARNING "Please increase ACPI_PROCESSOR_MAX_POWER if needed.\n");
+		count = ACPI_PROCESSOR_MAX_POWER;
+	}
+
+	/* Tell driver that at least _CST is supported. */
+	pr->flags.has_cst = 1;
+
+	for (i = 1; i <= count; i++) {
+		union acpi_object *element;
+		union acpi_object *obj;
+		struct acpi_power_register *reg;
+		struct acpi_processor_cx cx;
+
+		memset(&cx, 0, sizeof(cx));
+
+		element = (union acpi_object *) &(cst->package.elements[i]);
+		if (element->type != ACPI_TYPE_PACKAGE)
+			continue;
+
+		if (element->package.count != 4)
+			continue;
+
+		obj = (union acpi_object *) &(element->package.elements[0]);
+
+		if (obj->type != ACPI_TYPE_BUFFER)
+			continue;
+
+		reg = (struct acpi_power_register *) obj->buffer.pointer;
+
+		if (reg->space_id != ACPI_ADR_SPACE_SYSTEM_IO &&
+			(reg->space_id != ACPI_ADR_SPACE_FIXED_HARDWARE))
+			continue;
+
+		cx.address = (reg->space_id == ACPI_ADR_SPACE_FIXED_HARDWARE) ?
+			0 : reg->address;
+
+		/* There should be an easy way to extract an integer... */
+		obj = (union acpi_object *) &(element->package.elements[1]);
+		if (obj->type != ACPI_TYPE_INTEGER)
+			continue;
+
+		cx.type = obj->integer.value;
+
+		if ((cx.type != ACPI_STATE_C1) &&
+		    (reg->space_id != ACPI_ADR_SPACE_SYSTEM_IO))
+			continue;
+
+		if ((cx.type < ACPI_STATE_C1) ||
+		    (cx.type > ACPI_STATE_C3))
+			continue;
+
+		obj = (union acpi_object *) &(element->package.elements[2]);
+		if (obj->type != ACPI_TYPE_INTEGER)
+			continue;
+
+		cx.latency = obj->integer.value;
+
+		obj = (union acpi_object *) &(element->package.elements[3]);
+		if (obj->type != ACPI_TYPE_INTEGER)
+			continue;
+
+		cx.power = obj->integer.value;
+
+		(pr->power.count)++;
+		memcpy(&(pr->power.states[pr->power.count]), &cx, sizeof(cx));
+	}
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d power states\n", pr->power.count));
+
+	/* Validate number of power states discovered */
+	if (pr->power.count < 2)
+		status = -ENODEV;
+
+end:
+	acpi_os_free(buffer.pointer);
+
+	return_VALUE(status);
+}
+
+
+static void acpi_processor_power_verify_c2(struct acpi_processor_cx *cx)
+{
+	ACPI_FUNCTION_TRACE("acpi_processor_get_power_verify_c2");
+
+	if (!cx->address)
+		return_VOID;
+
+	/*
+	 * C2 latency must be less than or equal to 100
+	 * microseconds.
+	 */
+	else if (cx->latency > ACPI_PROCESSOR_MAX_C2_LATENCY) {
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+				  "latency too large [%d]\n",
+				  cx->latency));
+		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
+	 */
+	cx->valid = 1;
+	cx->latency_ticks = US_TO_PM_TIMER_TICKS(cx->latency);
+
+	return_VOID;
+}
+
+
+static void acpi_processor_power_verify_c3(
+	struct acpi_processor *pr,
+	struct acpi_processor_cx *cx)
+{
+	ACPI_FUNCTION_TRACE("acpi_processor_get_power_verify_c3");
+
+	if (!cx->address)
+		return_VOID;
+
+	/*
+	 * C3 latency must be less than or equal to 1000
+	 * microseconds.
+	 */
+	else if (cx->latency > ACPI_PROCESSOR_MAX_C3_LATENCY) {
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+				  "latency too large [%d]\n",
+				  cx->latency));
+		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.
+	 * Note that we could disable Type-F DMA (as recommended by
+	 * the erratum), but this is known to disrupt certain ISA
+	 * devices thus we take the conservative approach.
+	 */
+	else if (errata.piix4.fdma) {
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+			"C3 not supported on PIIX4 with Type-F DMA\n"));
+		return_VOID;
+	}
+
+	/*
+	 * Otherwise we've met all of our C3 requirements.
+	 * Normalize the C3 latency to expidite policy.  Enable
+	 * checking of bus mastering status (bm_check) so we can
+	 * use this in our C3 policy
+	 */
+	cx->valid = 1;
+	cx->latency_ticks = US_TO_PM_TIMER_TICKS(cx->latency);
+	pr->flags.bm_check = 1;
+
+	return_VOID;
+}
+
+
+static int acpi_processor_power_verify(struct acpi_processor *pr)
+{
+	unsigned int i;
+	unsigned int working = 0;
+
+	for (i=1; i < ACPI_PROCESSOR_MAX_POWER; i++) {
+		struct acpi_processor_cx *cx = &pr->power.states[i];
+
+		switch (cx->type) {
+		case ACPI_STATE_C1:
+			cx->valid = 1;
+			break;
+
+		case ACPI_STATE_C2:
+			acpi_processor_power_verify_c2(cx);
+			break;
+
+		case ACPI_STATE_C3:
+			acpi_processor_power_verify_c3(pr, cx);
+			break;
+		}
+
+		if (cx->valid)
+			working++;
+	}
+
+	return (working);
+}
+
+static int acpi_processor_get_power_info (
+	struct acpi_processor	*pr)
+{
+	unsigned int i;
+	int result;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_get_power_info");
+
+	/* NOTE: the idle thread may not be running while calling
+	 * this function */
+
+	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);
+	}
+
+	/*
+	 * Set Default Policy
+	 * ------------------
+	 * Now that we know which states are supported, set the default
+	 * policy.  Note that this policy can be changed dynamically
+	 * (e.g. encourage deeper sleeps to conserve battery life when
+	 * not on AC).
+	 */
+	result = acpi_processor_set_power_policy(pr);
+	if (result)
+		return_VALUE(result);
+
+	/*
+	 * if one state of type C2 or C3 is available, mark this
+	 * CPU as being "idle manageable"
+	 */
+	for (i = 1; i < ACPI_PROCESSOR_MAX_POWER; i++) {
+		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);
+}
+
+int acpi_processor_cst_has_changed (struct acpi_processor *pr)
+{
+ 	int			result = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_cst_has_changed");
+
+	if (!pr)
+ 		return_VALUE(-EINVAL);
+
+	if (errata.smp || nocst) {
+		return_VALUE(-ENODEV);
+	}
+
+	if (!pr->flags.power_setup_done)
+		return_VALUE(-ENODEV);
+
+	/* Fall back to the default idle loop */
+	pm_idle = pm_idle_save;
+	synchronize_kernel();
+
+	pr->flags.power = 0;
+	result = acpi_processor_get_power_info(pr);
+	if ((pr->flags.power == 1) && (pr->flags.power_setup_done))
+		pm_idle = acpi_processor_idle;
+
+	return_VALUE(result);
+}
+
+/* proc interface */
+
+static int acpi_processor_power_seq_show(struct seq_file *seq, void *offset)
+{
+	struct acpi_processor	*pr = (struct acpi_processor *)seq->private;
+	unsigned int		i;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_power_seq_show");
+
+	if (!pr)
+		goto end;
+
+	seq_printf(seq, "active state:            C%zd\n"
+			"max_cstate:              C%d\n"
+			"bus master activity:     %08x\n",
+			pr->power.state ? pr->power.state - pr->power.states : 0,
+			max_cstate,
+			(unsigned)pr->power.bm_activity);
+
+	seq_puts(seq, "states:\n");
+
+	for (i = 1; i <= pr->power.count; i++) {
+		seq_printf(seq, "   %cC%d:                  ",
+			(&pr->power.states[i] == pr->power.state?'*':' '), i);
+
+		if (!pr->power.states[i].valid) {
+			seq_puts(seq, "<not supported>\n");
+			continue;
+		}
+
+		switch (pr->power.states[i].type) {
+		case ACPI_STATE_C1:
+			seq_printf(seq, "type[C1] ");
+			break;
+		case ACPI_STATE_C2:
+			seq_printf(seq, "type[C2] ");
+			break;
+		case ACPI_STATE_C3:
+			seq_printf(seq, "type[C3] ");
+			break;
+		default:
+			seq_printf(seq, "type[--] ");
+			break;
+		}
+
+		if (pr->power.states[i].promotion.state)
+			seq_printf(seq, "promotion[C%zd] ",
+				(pr->power.states[i].promotion.state -
+				 pr->power.states));
+		else
+			seq_puts(seq, "promotion[--] ");
+
+		if (pr->power.states[i].demotion.state)
+			seq_printf(seq, "demotion[C%zd] ",
+				(pr->power.states[i].demotion.state -
+				 pr->power.states));
+		else
+			seq_puts(seq, "demotion[--] ");
+
+		seq_printf(seq, "latency[%03d] usage[%08d]\n",
+			pr->power.states[i].latency,
+			pr->power.states[i].usage);
+	}
+
+end:
+	return_VALUE(0);
+}
+
+static int acpi_processor_power_open_fs(struct inode *inode, struct file *file)
+{
+	return single_open(file, acpi_processor_power_seq_show,
+						PDE(inode)->data);
+}
+
+static struct file_operations acpi_processor_power_fops = {
+	.open 		= acpi_processor_power_open_fs,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+
+int acpi_processor_power_init(struct acpi_processor *pr, struct acpi_device *device)
+{
+	acpi_status		status = 0;
+	static int		first_run = 0;
+	struct proc_dir_entry	*entry = NULL;
+	unsigned int i;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_power_init");
+
+	if (!first_run) {
+		dmi_check_system(processor_power_dmi_table);
+		if (max_cstate < ACPI_C_STATES_MAX)
+			printk(KERN_NOTICE "ACPI: processor limited to max C-state %d\n", max_cstate);
+		first_run++;
+	}
+
+	if (!errata.smp && (pr->id == 0) && 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,
+					  "Notifying BIOS of _CST ability failed\n"));
+		}
+	}
+
+	acpi_processor_get_power_info(pr);
+
+	/*
+	 * Install the idle handler if processor power management is supported.
+	 * Note that we use previously set idle handler will be used on
+	 * platforms that only support C1.
+	 */
+	if ((pr->flags.power) && (!boot_option_idle_override)) {
+		printk(KERN_INFO PREFIX "CPU%d (power states:", pr->id);
+		for (i = 1; i <= pr->power.count; i++)
+			if (pr->power.states[i].valid)
+				printk(" C%d[C%d]", i, pr->power.states[i].type);
+		printk(")\n");
+
+		if (pr->id == 0) {
+			pm_idle_save = pm_idle;
+			pm_idle = acpi_processor_idle;
+		}
+	}
+
+	/* 'power' [R] */
+	entry = create_proc_entry(ACPI_PROCESSOR_FILE_POWER,
+		S_IRUGO, acpi_device_dir(device));
+	if (!entry)
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Unable to create '%s' fs entry\n",
+			ACPI_PROCESSOR_FILE_POWER));
+	else {
+		entry->proc_fops = &acpi_processor_power_fops;
+		entry->data = acpi_driver_data(device);
+		entry->owner = THIS_MODULE;
+	}
+
+	pr->flags.power_setup_done = 1;
+
+	return_VALUE(0);
+}
+
+int acpi_processor_power_exit(struct acpi_processor *pr, struct acpi_device *device)
+{
+	ACPI_FUNCTION_TRACE("acpi_processor_power_exit");
+
+	pr->flags.power_setup_done = 0;
+
+	if (acpi_device_dir(device))
+		remove_proc_entry(ACPI_PROCESSOR_FILE_POWER,acpi_device_dir(device));
+
+	/* Unregister the idle handler when processor #0 is removed. */
+	if (pr->id == 0) {
+		pm_idle = pm_idle_save;
+
+		/*
+		 * We are about to unload the current idle thread pm callback
+		 * (pm_idle), Wait for all processors to update cached/local
+		 * copies of pm_idle before proceeding.
+		 */
+		cpu_idle_wait();
+	}
+
+	return_VALUE(0);
+}
diff -Nru a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/acpi/processor_perflib.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,666 @@
+/*
+ * processor_perflib.c - ACPI Processor P-States Library ($Revision: 71 $)
+ *
+ *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
+ *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
+ *  Copyright (C) 2004       Dominik Brodowski <linux@brodo.de>
+ *  Copyright (C) 2004  Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
+ *  			- Added processor hotplug 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/module.h>
+#include <linux/init.h>
+#include <linux/cpufreq.h>
+
+#ifdef CONFIG_X86_ACPI_CPUFREQ_PROC_INTF
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+
+#include <asm/uaccess.h>
+#endif
+
+#include <acpi/acpi_bus.h>
+#include <acpi/processor.h>
+
+
+#define ACPI_PROCESSOR_COMPONENT	0x01000000
+#define ACPI_PROCESSOR_CLASS		"processor"
+#define ACPI_PROCESSOR_DRIVER_NAME	"ACPI Processor Driver"
+#define ACPI_PROCESSOR_FILE_PERFORMANCE	"performance"
+#define _COMPONENT		ACPI_PROCESSOR_COMPONENT
+ACPI_MODULE_NAME		("acpi_processor")
+
+
+static DECLARE_MUTEX(performance_sem);
+
+/*
+ * _PPC support is implemented as a CPUfreq policy notifier:
+ * This means each time a CPUfreq driver registered also with
+ * the ACPI core is asked to change the speed policy, the maximum
+ * value is adjusted so that it is within the platform limit.
+ *
+ * Also, when a new platform limit value is detected, the CPUfreq
+ * policy is adjusted accordingly.
+ */
+
+#define PPC_REGISTERED   1
+#define PPC_IN_USE       2
+
+static int acpi_processor_ppc_status = 0;
+
+static int acpi_processor_ppc_notifier(struct notifier_block *nb,
+	unsigned long event,
+	void *data)
+{
+	struct cpufreq_policy *policy = data;
+	struct acpi_processor *pr;
+	unsigned int ppc = 0;
+
+	down(&performance_sem);
+
+	if (event != CPUFREQ_INCOMPATIBLE)
+		goto out;
+
+	pr = processors[policy->cpu];
+	if (!pr || !pr->performance)
+		goto out;
+
+	ppc = (unsigned int) pr->performance_platform_limit;
+	if (!ppc)
+		goto out;
+
+	if (ppc > pr->performance->state_count)
+		goto out;
+
+	cpufreq_verify_within_limits(policy, 0,
+		pr->performance->states[ppc].core_frequency * 1000);
+
+ out:
+	up(&performance_sem);
+
+	return 0;
+}
+
+
+static struct notifier_block acpi_ppc_notifier_block = {
+	.notifier_call = acpi_processor_ppc_notifier,
+};
+
+
+static int
+acpi_processor_get_platform_limit (
+	struct acpi_processor*	pr)
+{
+	acpi_status		status = 0;
+	unsigned long		ppc = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_get_platform_limit");
+
+	if (!pr)
+		return_VALUE(-EINVAL);
+
+	/*
+	 * _PPC indicates the maximum state currently supported by the platform
+	 * (e.g. 0 = states 0..n; 1 = states 1..n; etc.
+	 */
+	status = acpi_evaluate_integer(pr->handle, "_PPC", NULL, &ppc);
+
+	if (status != AE_NOT_FOUND)
+		acpi_processor_ppc_status |= PPC_IN_USE;
+
+	if(ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PPC\n"));
+		return_VALUE(-ENODEV);
+	}
+
+	pr->performance_platform_limit = (int) ppc;
+
+	return_VALUE(0);
+}
+
+
+int acpi_processor_ppc_has_changed(
+	struct acpi_processor *pr)
+{
+	int ret = acpi_processor_get_platform_limit(pr);
+	if (ret < 0)
+		return (ret);
+	else
+		return cpufreq_update_policy(pr->id);
+}
+
+
+void acpi_processor_ppc_init(void) {
+	if (!cpufreq_register_notifier(&acpi_ppc_notifier_block, CPUFREQ_POLICY_NOTIFIER))
+		acpi_processor_ppc_status |= PPC_REGISTERED;
+	else
+		printk(KERN_DEBUG "Warning: Processor Platform Limit not supported.\n");
+}
+
+
+void acpi_processor_ppc_exit(void) {
+	if (acpi_processor_ppc_status & PPC_REGISTERED)
+		cpufreq_unregister_notifier(&acpi_ppc_notifier_block, CPUFREQ_POLICY_NOTIFIER);
+
+	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 (
+	struct acpi_processor *pr)
+{
+	int			result = 0;
+	acpi_status		status = 0;
+	struct acpi_buffer	buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+	union acpi_object	*pct = NULL;
+	union acpi_object	obj = {0};
+
+	ACPI_FUNCTION_TRACE("acpi_processor_get_performance_control");
+
+	status = acpi_evaluate_object(pr->handle, "_PCT", NULL, &buffer);
+	if(ACPI_FAILURE(status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PCT\n"));
+		return_VALUE(-ENODEV);
+	}
+
+	pct = (union acpi_object *) buffer.pointer;
+	if (!pct || (pct->type != ACPI_TYPE_PACKAGE)
+		|| (pct->package.count != 2)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PCT data\n"));
+		result = -EFAULT;
+		goto end;
+	}
+
+	/*
+	 * control_register
+	 */
+
+	obj = pct->package.elements[0];
+
+	if ((obj.type != ACPI_TYPE_BUFFER)
+		|| (obj.buffer.length < sizeof(struct acpi_pct_register))
+		|| (obj.buffer.pointer == NULL)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Invalid _PCT data (control_register)\n"));
+		result = -EFAULT;
+		goto end;
+	}
+	memcpy(&pr->performance->control_register, obj.buffer.pointer, sizeof(struct acpi_pct_register));
+
+
+	/*
+	 * status_register
+	 */
+
+	obj = pct->package.elements[1];
+
+	if ((obj.type != ACPI_TYPE_BUFFER)
+		|| (obj.buffer.length < sizeof(struct acpi_pct_register))
+		|| (obj.buffer.pointer == NULL)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Invalid _PCT data (status_register)\n"));
+		result = -EFAULT;
+		goto end;
+	}
+
+	memcpy(&pr->performance->status_register, obj.buffer.pointer, sizeof(struct acpi_pct_register));
+
+end:
+	acpi_os_free(buffer.pointer);
+
+	return_VALUE(result);
+}
+
+
+static int
+acpi_processor_get_performance_states (
+	struct acpi_processor	*pr)
+{
+	int			result = 0;
+	acpi_status		status = AE_OK;
+	struct acpi_buffer	buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+	struct acpi_buffer	format = {sizeof("NNNNNN"), "NNNNNN"};
+	struct acpi_buffer	state = {0, NULL};
+	union acpi_object 	*pss = NULL;
+	int			i;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_get_performance_states");
+
+	status = acpi_evaluate_object(pr->handle, "_PSS", NULL, &buffer);
+	if(ACPI_FAILURE(status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PSS\n"));
+		return_VALUE(-ENODEV);
+	}
+
+	pss = (union acpi_object *) buffer.pointer;
+	if (!pss || (pss->type != ACPI_TYPE_PACKAGE)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSS data\n"));
+		result = -EFAULT;
+		goto end;
+	}
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d performance states\n",
+		pss->package.count));
+
+	pr->performance->state_count = pss->package.count;
+	pr->performance->states = kmalloc(sizeof(struct acpi_processor_px) * pss->package.count, GFP_KERNEL);
+	if (!pr->performance->states) {
+		result = -ENOMEM;
+		goto end;
+	}
+
+	for (i = 0; i < pr->performance->state_count; i++) {
+
+		struct acpi_processor_px *px = &(pr->performance->states[i]);
+
+		state.length = sizeof(struct acpi_processor_px);
+		state.pointer = px;
+
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Extracting state %d\n", i));
+
+		status = acpi_extract_package(&(pss->package.elements[i]),
+			&format, &state);
+		if (ACPI_FAILURE(status)) {
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSS data\n"));
+			result = -EFAULT;
+			kfree(pr->performance->states);
+			goto end;
+		}
+
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+			"State [%d]: core_frequency[%d] power[%d] transition_latency[%d] bus_master_latency[%d] control[0x%x] status[0x%x]\n",
+			i,
+			(u32) px->core_frequency,
+			(u32) px->power,
+			(u32) px->transition_latency,
+			(u32) px->bus_master_latency,
+			(u32) px->control,
+			(u32) px->status));
+
+		if (!px->core_frequency) {
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSS data: freq is zero\n"));
+			result = -EFAULT;
+			kfree(pr->performance->states);
+			goto end;
+		}
+	}
+
+end:
+	acpi_os_free(buffer.pointer);
+
+	return_VALUE(result);
+}
+
+
+static int
+acpi_processor_get_performance_info (
+	struct acpi_processor	*pr)
+{
+	int			result = 0;
+	acpi_status		status = AE_OK;
+	acpi_handle		handle = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_get_performance_info");
+
+	if (!pr || !pr->performance || !pr->handle)
+		return_VALUE(-EINVAL);
+
+	acpi_processor_set_pdc(pr);
+
+	status = acpi_get_handle(pr->handle, "_PCT", &handle);
+	if (ACPI_FAILURE(status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+			"ACPI-based processor performance control unavailable\n"));
+		return_VALUE(-ENODEV);
+	}
+
+	result = acpi_processor_get_performance_control(pr);
+	if (result)
+		return_VALUE(result);
+
+	result = acpi_processor_get_performance_states(pr);
+	if (result)
+		return_VALUE(result);
+
+	result = acpi_processor_get_platform_limit(pr);
+	if (result)
+		return_VALUE(result);
+
+	return_VALUE(0);
+}
+
+
+int acpi_processor_notify_smm(struct module *calling_module) {
+	acpi_status		status;
+	static int		is_done = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_notify_smm");
+
+	if (!(acpi_processor_ppc_status & PPC_REGISTERED))
+		return_VALUE(-EBUSY);
+
+	if (!try_module_get(calling_module))
+		return_VALUE(-EINVAL);
+
+	/* is_done is set to negative if an error occured,
+	 * and to postitive if _no_ error occured, but SMM
+	 * was already notified. This avoids double notification
+	 * which might lead to unexpected results...
+	 */
+	if (is_done > 0) {
+		module_put(calling_module);
+		return_VALUE(0);
+	}
+	else if (is_done < 0) {
+		module_put(calling_module);
+		return_VALUE(is_done);
+	}
+
+	is_done = -EIO;
+
+	/* Can't write pstate_cnt to smi_cmd if either value is zero */
+	if ((!acpi_fadt.smi_cmd) ||
+	    (!acpi_fadt.pstate_cnt)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+			"No SMI port or pstate_cnt\n"));
+		module_put(calling_module);
+		return_VALUE(0);
+	}
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Writing pstate_cnt [0x%x] to smi_cmd [0x%x]\n", acpi_fadt.pstate_cnt, acpi_fadt.smi_cmd));
+
+	/* FADT v1 doesn't support pstate_cnt, many BIOS vendors use
+	 * it anyway, so we need to support it... */
+	if (acpi_fadt_is_v1) {
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Using v1.0 FADT reserved value for pstate_cnt\n"));
+	}
+
+	status = acpi_os_write_port (acpi_fadt.smi_cmd,
+				     (u32) acpi_fadt.pstate_cnt, 8);
+	if (ACPI_FAILURE (status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "Failed to write pstate_cnt [0x%x] to "
+				  "smi_cmd [0x%x]\n", acpi_fadt.pstate_cnt, acpi_fadt.smi_cmd));
+		module_put(calling_module);
+		return_VALUE(status);
+	}
+
+	/* Success. If there's no _PPC, we need to fear nothing, so
+	 * we can allow the cpufreq driver to be rmmod'ed. */
+	is_done = 1;
+
+	if (!(acpi_processor_ppc_status & PPC_IN_USE))
+		module_put(calling_module);
+
+	return_VALUE(0);
+}
+EXPORT_SYMBOL(acpi_processor_notify_smm);
+
+
+#ifdef CONFIG_X86_ACPI_CPUFREQ_PROC_INTF
+/* /proc/acpi/processor/../performance interface (DEPRECATED) */
+
+static int acpi_processor_perf_open_fs(struct inode *inode, struct file *file);
+static struct file_operations acpi_processor_perf_fops = {
+	.open 		= acpi_processor_perf_open_fs,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int acpi_processor_perf_seq_show(struct seq_file *seq, void *offset)
+{
+	struct acpi_processor	*pr = (struct acpi_processor *)seq->private;
+	int			i;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_perf_seq_show");
+
+	if (!pr)
+		goto end;
+
+	if (!pr->performance) {
+		seq_puts(seq, "<not supported>\n");
+		goto end;
+	}
+
+	seq_printf(seq, "state count:             %d\n"
+			"active state:            P%d\n",
+			pr->performance->state_count,
+			pr->performance->state);
+
+	seq_puts(seq, "states:\n");
+	for (i = 0; i < pr->performance->state_count; i++)
+		seq_printf(seq, "   %cP%d:                  %d MHz, %d mW, %d uS\n",
+			(i == pr->performance->state?'*':' '), i,
+			(u32) pr->performance->states[i].core_frequency,
+			(u32) pr->performance->states[i].power,
+			(u32) pr->performance->states[i].transition_latency);
+
+end:
+	return_VALUE(0);
+}
+
+static int acpi_processor_perf_open_fs(struct inode *inode, struct file *file)
+{
+	return single_open(file, acpi_processor_perf_seq_show,
+						PDE(inode)->data);
+}
+
+static ssize_t
+acpi_processor_write_performance (
+        struct file		*file,
+        const char		__user *buffer,
+        size_t			count,
+        loff_t			*data)
+{
+	int			result = 0;
+	struct seq_file		*m = (struct seq_file *) file->private_data;
+	struct acpi_processor	*pr = (struct acpi_processor *) m->private;
+	struct acpi_processor_performance *perf;
+	char			state_string[12] = {'\0'};
+	unsigned int            new_state = 0;
+	struct cpufreq_policy   policy;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_write_performance");
+
+	if (!pr || (count > sizeof(state_string) - 1))
+		return_VALUE(-EINVAL);
+
+	perf = pr->performance;
+	if (!perf)
+		return_VALUE(-EINVAL);
+
+	if (copy_from_user(state_string, buffer, count))
+		return_VALUE(-EFAULT);
+
+	state_string[count] = '\0';
+	new_state = simple_strtoul(state_string, NULL, 0);
+
+	if (new_state >= perf->state_count)
+		return_VALUE(-EINVAL);
+
+	cpufreq_get_policy(&policy, pr->id);
+
+	policy.cpu = pr->id;
+	policy.min = perf->states[new_state].core_frequency * 1000;
+	policy.max = perf->states[new_state].core_frequency * 1000;
+
+	result = cpufreq_set_policy(&policy);
+	if (result)
+		return_VALUE(result);
+
+	return_VALUE(count);
+}
+
+static void
+acpi_cpufreq_add_file (
+	struct acpi_processor *pr)
+{
+	struct proc_dir_entry	*entry = NULL;
+	struct acpi_device	*device = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_cpufreq_addfile");
+
+	if (acpi_bus_get_device(pr->handle, &device))
+		return_VOID;
+
+	/* add file 'performance' [R/W] */
+	entry = create_proc_entry(ACPI_PROCESSOR_FILE_PERFORMANCE,
+		  S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device));
+	if (!entry)
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Unable to create '%s' fs entry\n",
+			ACPI_PROCESSOR_FILE_PERFORMANCE));
+	else {
+		entry->proc_fops = &acpi_processor_perf_fops;
+		entry->proc_fops->write = acpi_processor_write_performance;
+		entry->data = acpi_driver_data(device);
+		entry->owner = THIS_MODULE;
+	}
+	return_VOID;
+}
+
+static void
+acpi_cpufreq_remove_file (
+	struct acpi_processor *pr)
+{
+	struct acpi_device	*device = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_cpufreq_addfile");
+
+	if (acpi_bus_get_device(pr->handle, &device))
+		return_VOID;
+
+	/* remove file 'performance' */
+	remove_proc_entry(ACPI_PROCESSOR_FILE_PERFORMANCE,
+		  acpi_device_dir(device));
+
+	return_VOID;
+}
+
+#else
+static void acpi_cpufreq_add_file (struct acpi_processor *pr) { return; }
+static void acpi_cpufreq_remove_file (struct acpi_processor *pr) { return; }
+#endif /* CONFIG_X86_ACPI_CPUFREQ_PROC_INTF */
+
+
+int
+acpi_processor_register_performance (
+	struct acpi_processor_performance * performance,
+	unsigned int cpu)
+{
+	struct acpi_processor *pr;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_register_performance");
+
+	if (!(acpi_processor_ppc_status & PPC_REGISTERED))
+		return_VALUE(-EINVAL);
+
+	down(&performance_sem);
+
+	pr = processors[cpu];
+	if (!pr) {
+		up(&performance_sem);
+		return_VALUE(-ENODEV);
+	}
+
+	if (pr->performance) {
+		up(&performance_sem);
+		return_VALUE(-EBUSY);
+	}
+
+	pr->performance = performance;
+
+	if (acpi_processor_get_performance_info(pr)) {
+		pr->performance = NULL;
+		up(&performance_sem);
+		return_VALUE(-EIO);
+	}
+
+	acpi_cpufreq_add_file(pr);
+
+	up(&performance_sem);
+	return_VALUE(0);
+}
+EXPORT_SYMBOL(acpi_processor_register_performance);
+
+
+void
+acpi_processor_unregister_performance (
+	struct acpi_processor_performance * performance,
+	unsigned int cpu)
+{
+	struct acpi_processor *pr;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_unregister_performance");
+
+	down(&performance_sem);
+
+	pr = processors[cpu];
+	if (!pr) {
+		up(&performance_sem);
+		return_VOID;
+	}
+
+	kfree(pr->performance->states);
+	pr->performance = NULL;
+
+	acpi_cpufreq_remove_file(pr);
+
+	up(&performance_sem);
+
+	return_VOID;
+}
+EXPORT_SYMBOL(acpi_processor_unregister_performance);
diff -Nru a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/acpi/processor_thermal.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,406 @@
+/*
+ * processor_thermal.c - Passive cooling submodule of the ACPI processor driver
+ *
+ *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
+ *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
+ *  Copyright (C) 2004       Dominik Brodowski <linux@brodo.de>
+ *  Copyright (C) 2004  Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
+ *  			- Added processor hotplug 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/module.h>
+#include <linux/init.h>
+#include <linux/cpufreq.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+
+#include <asm/uaccess.h>
+
+#include <acpi/acpi_bus.h>
+#include <acpi/processor.h>
+#include <acpi/acpi_drivers.h>
+
+#define ACPI_PROCESSOR_COMPONENT        0x01000000
+#define ACPI_PROCESSOR_CLASS            "processor"
+#define ACPI_PROCESSOR_DRIVER_NAME      "ACPI Processor Driver"
+#define _COMPONENT              ACPI_PROCESSOR_COMPONENT
+ACPI_MODULE_NAME                ("acpi_processor")
+
+
+/* --------------------------------------------------------------------------
+                                 Limit Interface
+   -------------------------------------------------------------------------- */
+
+static int
+acpi_processor_apply_limit (
+	struct acpi_processor* 	pr)
+{
+	int			result = 0;
+	u16			px = 0;
+	u16			tx = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_apply_limit");
+
+	if (!pr)
+		return_VALUE(-EINVAL);
+
+	if (!pr->flags.limit)
+		return_VALUE(-ENODEV);
+
+	if (pr->flags.throttling) {
+		if (pr->limit.user.tx > tx)
+			tx = pr->limit.user.tx;
+		if (pr->limit.thermal.tx > tx)
+			tx = pr->limit.thermal.tx;
+
+		result = acpi_processor_set_throttling(pr, tx);
+		if (result)
+			goto end;
+	}
+
+	pr->limit.state.px = px;
+	pr->limit.state.tx = tx;
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Processor [%d] limit set to (P%d:T%d)\n",
+		pr->id,
+		pr->limit.state.px,
+		pr->limit.state.tx));
+
+end:
+	if (result)
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unable to set limit\n"));
+
+	return_VALUE(result);
+}
+
+
+#ifdef CONFIG_CPU_FREQ
+
+/* If a passive cooling situation is detected, primarily CPUfreq is used, as it
+ * offers (in most cases) voltage scaling in addition to frequency scaling, and
+ * thus a cubic (instead of linear) reduction of energy. Also, we allow for
+ * _any_ cpufreq driver and not only the acpi-cpufreq driver.
+ */
+
+static unsigned int cpufreq_thermal_reduction_pctg[NR_CPUS];
+static unsigned int acpi_thermal_cpufreq_is_init = 0;
+
+
+static int cpu_has_cpufreq(unsigned int cpu)
+{
+	struct cpufreq_policy policy;
+	if (!acpi_thermal_cpufreq_is_init)
+		return -ENODEV;
+	if (!cpufreq_get_policy(&policy, cpu))
+		return -ENODEV;
+	return 0;
+}
+
+
+static int acpi_thermal_cpufreq_increase(unsigned int cpu)
+{
+	if (!cpu_has_cpufreq(cpu))
+		return -ENODEV;
+
+	if (cpufreq_thermal_reduction_pctg[cpu] < 60) {
+		cpufreq_thermal_reduction_pctg[cpu] += 20;
+		cpufreq_update_policy(cpu);
+		return 0;
+	}
+
+	return -ERANGE;
+}
+
+
+static int acpi_thermal_cpufreq_decrease(unsigned int cpu)
+{
+	if (!cpu_has_cpufreq(cpu))
+		return -ENODEV;
+
+	if (cpufreq_thermal_reduction_pctg[cpu] >= 20) {
+		cpufreq_thermal_reduction_pctg[cpu] -= 20;
+		cpufreq_update_policy(cpu);
+		return 0;
+	}
+
+	return -ERANGE;
+}
+
+
+static int acpi_thermal_cpufreq_notifier(
+	struct notifier_block *nb,
+	unsigned long event,
+	void *data)
+{
+	struct cpufreq_policy *policy = data;
+	unsigned long max_freq = 0;
+
+	if (event != CPUFREQ_ADJUST)
+		goto out;
+
+	max_freq = (policy->cpuinfo.max_freq * (100 - cpufreq_thermal_reduction_pctg[policy->cpu])) / 100;
+
+	cpufreq_verify_within_limits(policy, 0, max_freq);
+
+ out:
+	return 0;
+}
+
+
+static struct notifier_block acpi_thermal_cpufreq_notifier_block = {
+	.notifier_call = acpi_thermal_cpufreq_notifier,
+};
+
+
+void acpi_thermal_cpufreq_init(void) {
+	int i;
+
+	for (i=0; i<NR_CPUS; i++)
+		cpufreq_thermal_reduction_pctg[i] = 0;
+
+	i = cpufreq_register_notifier(&acpi_thermal_cpufreq_notifier_block, CPUFREQ_POLICY_NOTIFIER);
+	if (!i)
+		acpi_thermal_cpufreq_is_init = 1;
+}
+
+void acpi_thermal_cpufreq_exit(void) {
+	if (acpi_thermal_cpufreq_is_init)
+		cpufreq_unregister_notifier(&acpi_thermal_cpufreq_notifier_block, CPUFREQ_POLICY_NOTIFIER);
+
+	acpi_thermal_cpufreq_is_init = 0;
+}
+
+#else /* ! CONFIG_CPU_FREQ */
+
+static int acpi_thermal_cpufreq_increase(unsigned int cpu) { return -ENODEV; }
+static int acpi_thermal_cpufreq_decrease(unsigned int cpu) { return -ENODEV; }
+
+
+#endif
+
+
+int
+acpi_processor_set_thermal_limit (
+	acpi_handle		handle,
+	int			type)
+{
+	int			result = 0;
+	struct acpi_processor	*pr = NULL;
+	struct acpi_device	*device = NULL;
+	int			tx = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_set_thermal_limit");
+
+	if ((type < ACPI_PROCESSOR_LIMIT_NONE)
+		|| (type > ACPI_PROCESSOR_LIMIT_DECREMENT))
+		return_VALUE(-EINVAL);
+
+	result = acpi_bus_get_device(handle, &device);
+	if (result)
+		return_VALUE(result);
+
+	pr = (struct acpi_processor *) acpi_driver_data(device);
+	if (!pr)
+		return_VALUE(-ENODEV);
+
+	/* Thermal limits are always relative to the current Px/Tx state. */
+	if (pr->flags.throttling)
+		pr->limit.thermal.tx = pr->throttling.state;
+
+	/*
+	 * Our default policy is to only use throttling at the lowest
+	 * performance state.
+	 */
+
+	tx = pr->limit.thermal.tx;
+
+	switch (type) {
+
+	case ACPI_PROCESSOR_LIMIT_NONE:
+		do {
+			result = acpi_thermal_cpufreq_decrease(pr->id);
+		} while (!result);
+		tx = 0;
+		break;
+
+	case ACPI_PROCESSOR_LIMIT_INCREMENT:
+		/* if going up: P-states first, T-states later */
+
+		result = acpi_thermal_cpufreq_increase(pr->id);
+		if (!result)
+			goto end;
+		else if (result == -ERANGE)
+			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+					"At maximum performance state\n"));
+
+		if (pr->flags.throttling) {
+			if (tx == (pr->throttling.state_count - 1))
+				ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+					"At maximum throttling state\n"));
+			else
+				tx++;
+		}
+		break;
+
+	case ACPI_PROCESSOR_LIMIT_DECREMENT:
+		/* if going down: T-states first, P-states later */
+
+		if (pr->flags.throttling) {
+			if (tx == 0)
+				ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+					"At minimum throttling state\n"));
+			else {
+				tx--;
+				goto end;
+			}
+		}
+
+		result = acpi_thermal_cpufreq_decrease(pr->id);
+		if (result == -ERANGE)
+			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+					"At minimum performance state\n"));
+
+		break;
+	}
+
+end:
+	if (pr->flags.throttling) {
+		pr->limit.thermal.px = 0;
+		pr->limit.thermal.tx = tx;
+
+		result = acpi_processor_apply_limit(pr);
+		if (result)
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+					  "Unable to set thermal limit\n"));
+
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Thermal limit now (P%d:T%d)\n",
+				  pr->limit.thermal.px,
+				  pr->limit.thermal.tx));
+	} else
+		result = 0;
+
+	return_VALUE(result);
+}
+
+
+int
+acpi_processor_get_limit_info (
+	struct acpi_processor	*pr)
+{
+	ACPI_FUNCTION_TRACE("acpi_processor_get_limit_info");
+
+	if (!pr)
+		return_VALUE(-EINVAL);
+
+	if (pr->flags.throttling)
+		pr->flags.limit = 1;
+
+	return_VALUE(0);
+}
+
+
+/* /proc interface */
+
+static int acpi_processor_limit_seq_show(struct seq_file *seq, void *offset)
+{
+	struct acpi_processor	*pr = (struct acpi_processor *)seq->private;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_limit_seq_show");
+
+	if (!pr)
+		goto end;
+
+	if (!pr->flags.limit) {
+		seq_puts(seq, "<not supported>\n");
+		goto end;
+	}
+
+	seq_printf(seq, "active limit:            P%d:T%d\n"
+			"user limit:              P%d:T%d\n"
+			"thermal limit:           P%d:T%d\n",
+			pr->limit.state.px, pr->limit.state.tx,
+			pr->limit.user.px, pr->limit.user.tx,
+			pr->limit.thermal.px, pr->limit.thermal.tx);
+
+end:
+	return_VALUE(0);
+}
+
+int acpi_processor_limit_open_fs(struct inode *inode, struct file *file)
+{
+	return single_open(file, acpi_processor_limit_seq_show,
+						PDE(inode)->data);
+}
+
+ssize_t acpi_processor_write_limit (
+	struct file		*file,
+	const char		__user *buffer,
+	size_t			count,
+	loff_t			*data)
+{
+	int			result = 0;
+        struct seq_file 	*m = (struct seq_file *)file->private_data;
+	struct acpi_processor	*pr = (struct acpi_processor *)m->private;
+	char			limit_string[25] = {'\0'};
+	int			px = 0;
+	int			tx = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_write_limit");
+
+	if (!pr || (count > sizeof(limit_string) - 1)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid argument\n"));
+		return_VALUE(-EINVAL);
+	}
+
+	if (copy_from_user(limit_string, buffer, count)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid data\n"));
+		return_VALUE(-EFAULT);
+	}
+
+	limit_string[count] = '\0';
+
+	if (sscanf(limit_string, "%d:%d", &px, &tx) != 2) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid data format\n"));
+		return_VALUE(-EINVAL);
+	}
+
+	if (pr->flags.throttling) {
+		if ((tx < 0) || (tx > (pr->throttling.state_count - 1))) {
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid tx\n"));
+			return_VALUE(-EINVAL);
+		}
+		pr->limit.user.tx = tx;
+	}
+
+	result = acpi_processor_apply_limit(pr);
+
+	return_VALUE(count);
+}
+
+
+struct file_operations acpi_processor_limit_fops = {
+	.open 		= acpi_processor_limit_open_fs,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
diff -Nru a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/acpi/processor_throttling.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,351 @@
+/*
+ * processor_throttling.c - Throttling submodule of the ACPI processor driver
+ *
+ *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
+ *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
+ *  Copyright (C) 2004       Dominik Brodowski <linux@brodo.de>
+ *  Copyright (C) 2004  Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
+ *  			- Added processor hotplug 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/module.h>
+#include <linux/init.h>
+#include <linux/cpufreq.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+
+#include <acpi/acpi_bus.h>
+#include <acpi/processor.h>
+
+#define ACPI_PROCESSOR_COMPONENT        0x01000000
+#define ACPI_PROCESSOR_CLASS            "processor"
+#define ACPI_PROCESSOR_DRIVER_NAME      "ACPI Processor Driver"
+#define _COMPONENT              ACPI_PROCESSOR_COMPONENT
+ACPI_MODULE_NAME                ("acpi_processor")
+
+
+/* --------------------------------------------------------------------------
+                              Throttling Control
+   -------------------------------------------------------------------------- */
+
+static int
+acpi_processor_get_throttling (
+	struct acpi_processor	*pr)
+{
+	int			state = 0;
+	u32			value = 0;
+	u32			duty_mask = 0;
+	u32			duty_value = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_get_throttling");
+
+	if (!pr)
+		return_VALUE(-EINVAL);
+
+	if (!pr->flags.throttling)
+		return_VALUE(-ENODEV);
+
+	pr->throttling.state = 0;
+
+	duty_mask = pr->throttling.state_count - 1;
+
+	duty_mask <<= pr->throttling.duty_offset;
+
+	local_irq_disable();
+
+	value = inl(pr->throttling.address);
+
+	/*
+	 * Compute the current throttling state when throttling is enabled
+	 * (bit 4 is on).
+	 */
+	if (value & 0x10) {
+		duty_value = value & duty_mask;
+		duty_value >>= pr->throttling.duty_offset;
+
+		if (duty_value)
+			state = pr->throttling.state_count-duty_value;
+	}
+
+	pr->throttling.state = state;
+
+	local_irq_enable();
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+		"Throttling state is T%d (%d%% throttling applied)\n",
+		state, pr->throttling.states[state].performance));
+
+	return_VALUE(0);
+}
+
+
+int acpi_processor_set_throttling (
+	struct acpi_processor	*pr,
+	int			state)
+{
+	u32                     value = 0;
+	u32                     duty_mask = 0;
+	u32                     duty_value = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_set_throttling");
+
+	if (!pr)
+		return_VALUE(-EINVAL);
+
+	if ((state < 0) || (state > (pr->throttling.state_count - 1)))
+		return_VALUE(-EINVAL);
+
+	if (!pr->flags.throttling)
+		return_VALUE(-ENODEV);
+
+	if (state == pr->throttling.state)
+		return_VALUE(0);
+
+	/*
+	 * Calculate the duty_value and duty_mask.
+	 */
+	if (state) {
+		duty_value = pr->throttling.state_count - state;
+
+		duty_value <<= pr->throttling.duty_offset;
+
+		/* Used to clear all duty_value bits */
+		duty_mask = pr->throttling.state_count - 1;
+
+		duty_mask <<= acpi_fadt.duty_offset;
+		duty_mask = ~duty_mask;
+	}
+
+	local_irq_disable();
+
+	/*
+	 * Disable throttling by writing a 0 to bit 4.  Note that we must
+	 * turn it off before you can change the duty_value.
+	 */
+	value = inl(pr->throttling.address);
+	if (value & 0x10) {
+		value &= 0xFFFFFFEF;
+		outl(value, pr->throttling.address);
+	}
+
+	/*
+	 * Write the new duty_value and then enable throttling.  Note
+	 * that a state value of 0 leaves throttling disabled.
+	 */
+	if (state) {
+		value &= duty_mask;
+		value |= duty_value;
+		outl(value, pr->throttling.address);
+
+		value |= 0x00000010;
+		outl(value, pr->throttling.address);
+	}
+
+	pr->throttling.state = state;
+
+	local_irq_enable();
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+		"Throttling state set to T%d (%d%%)\n", state,
+		(pr->throttling.states[state].performance?pr->throttling.states[state].performance/10:0)));
+
+	return_VALUE(0);
+}
+
+
+int
+acpi_processor_get_throttling_info (
+	struct acpi_processor	*pr)
+{
+	int			result = 0;
+	int			step = 0;
+	int			i = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_get_throttling_info");
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+		"pblk_address[0x%08x] duty_offset[%d] duty_width[%d]\n",
+		pr->throttling.address,
+		pr->throttling.duty_offset,
+		pr->throttling.duty_width));
+
+	if (!pr)
+		return_VALUE(-EINVAL);
+
+	/* TBD: Support ACPI 2.0 objects */
+
+	if (!pr->throttling.address) {
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No throttling register\n"));
+		return_VALUE(0);
+	}
+	else if (!pr->throttling.duty_width) {
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No throttling states\n"));
+		return_VALUE(0);
+	}
+	/* TBD: Support duty_cycle values that span bit 4. */
+	else if ((pr->throttling.duty_offset
+		+ pr->throttling.duty_width) > 4) {
+		ACPI_DEBUG_PRINT((ACPI_DB_WARN, "duty_cycle spans bit 4\n"));
+		return_VALUE(0);
+	}
+
+	/*
+	 * PIIX4 Errata: We don't support throttling on the original PIIX4.
+	 * This shouldn't be an issue as few (if any) mobile systems ever
+	 * used this part.
+	 */
+	if (errata.piix4.throttle) {
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+			"Throttling not supported on PIIX4 A- or B-step\n"));
+		return_VALUE(0);
+	}
+
+	pr->throttling.state_count = 1 << acpi_fadt.duty_width;
+
+	/*
+	 * Compute state values. Note that throttling displays a linear power/
+	 * performance relationship (at 50% performance the CPU will consume
+	 * 50% power).  Values are in 1/10th of a percent to preserve accuracy.
+	 */
+
+	step = (1000 / pr->throttling.state_count);
+
+	for (i=0; i<pr->throttling.state_count; i++) {
+		pr->throttling.states[i].performance = step * i;
+		pr->throttling.states[i].power = step * i;
+	}
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d throttling states\n",
+		pr->throttling.state_count));
+
+	pr->flags.throttling = 1;
+
+	/*
+	 * Disable throttling (if enabled).  We'll let subsequent policy (e.g.
+	 * thermal) decide to lower performance if it so chooses, but for now
+	 * we'll crank up the speed.
+	 */
+
+	result = acpi_processor_get_throttling(pr);
+	if (result)
+		goto end;
+
+	if (pr->throttling.state) {
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Disabling throttling (was T%d)\n",
+			pr->throttling.state));
+		result = acpi_processor_set_throttling(pr, 0);
+		if (result)
+			goto end;
+	}
+
+end:
+	if (result)
+		pr->flags.throttling = 0;
+
+	return_VALUE(result);
+}
+
+
+/* proc interface */
+
+static int acpi_processor_throttling_seq_show(struct seq_file *seq, void *offset)
+{
+	struct acpi_processor	*pr = (struct acpi_processor *)seq->private;
+	int			i = 0;
+	int                     result = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_throttling_seq_show");
+
+	if (!pr)
+		goto end;
+
+	if (!(pr->throttling.state_count > 0)) {
+		seq_puts(seq, "<not supported>\n");
+		goto end;
+	}
+
+	result = acpi_processor_get_throttling(pr);
+
+	if (result) {
+		seq_puts(seq, "Could not determine current throttling state.\n");
+		goto end;
+	}
+
+	seq_printf(seq, "state count:             %d\n"
+			"active state:            T%d\n",
+			pr->throttling.state_count,
+			pr->throttling.state);
+
+	seq_puts(seq, "states:\n");
+	for (i = 0; i < pr->throttling.state_count; i++)
+		seq_printf(seq, "   %cT%d:                  %02d%%\n",
+			(i == pr->throttling.state?'*':' '), i,
+			(pr->throttling.states[i].performance?pr->throttling.states[i].performance/10:0));
+
+end:
+	return_VALUE(0);
+}
+
+int acpi_processor_throttling_open_fs(struct inode *inode, struct file *file)
+{
+	return single_open(file, acpi_processor_throttling_seq_show,
+						PDE(inode)->data);
+}
+
+ssize_t acpi_processor_write_throttling (
+        struct file		*file,
+        const char		__user *buffer,
+        size_t			count,
+        loff_t			*data)
+{
+	int			result = 0;
+        struct seq_file 	*m = (struct seq_file *)file->private_data;
+	struct acpi_processor	*pr = (struct acpi_processor *)m->private;
+	char			state_string[12] = {'\0'};
+
+	ACPI_FUNCTION_TRACE("acpi_processor_write_throttling");
+
+	if (!pr || (count > sizeof(state_string) - 1))
+		return_VALUE(-EINVAL);
+
+	if (copy_from_user(state_string, buffer, count))
+		return_VALUE(-EFAULT);
+
+	state_string[count] = '\0';
+
+	result = acpi_processor_set_throttling(pr,
+		simple_strtoul(state_string, NULL, 0));
+	if (result)
+		return_VALUE(result);
+
+	return_VALUE(count);
+}
+
+struct file_operations acpi_processor_throttling_fops = {
+	.open 		= acpi_processor_throttling_open_fs,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
diff -Nru a/drivers/acpi/resources/rsaddr.c b/drivers/acpi/resources/rsaddr.c
--- a/drivers/acpi/resources/rsaddr.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/acpi/resources/rsaddr.c	2005-03-01 23:38:58 -08:00
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/resources/rscalc.c b/drivers/acpi/resources/rscalc.c
--- a/drivers/acpi/resources/rscalc.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/acpi/resources/rscalc.c	2005-03-01 23:38:58 -08:00
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/resources/rscreate.c b/drivers/acpi/resources/rscreate.c
--- a/drivers/acpi/resources/rscreate.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/acpi/resources/rscreate.c	2005-03-01 23:38:55 -08:00
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/resources/rsdump.c b/drivers/acpi/resources/rsdump.c
--- a/drivers/acpi/resources/rsdump.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/acpi/resources/rsdump.c	2005-03-01 23:38:58 -08:00
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/resources/rsio.c b/drivers/acpi/resources/rsio.c
--- a/drivers/acpi/resources/rsio.c	2005-03-01 23:38:44 -08:00
+++ b/drivers/acpi/resources/rsio.c	2005-03-01 23:38:44 -08:00
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/resources/rsirq.c b/drivers/acpi/resources/rsirq.c
--- a/drivers/acpi/resources/rsirq.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/acpi/resources/rsirq.c	2005-03-01 23:39:17 -08:00
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/resources/rslist.c b/drivers/acpi/resources/rslist.c
--- a/drivers/acpi/resources/rslist.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/acpi/resources/rslist.c	2005-03-01 23:39:17 -08:00
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/resources/rsmemory.c b/drivers/acpi/resources/rsmemory.c
--- a/drivers/acpi/resources/rsmemory.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/acpi/resources/rsmemory.c	2005-03-01 23:39:09 -08:00
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/resources/rsmisc.c b/drivers/acpi/resources/rsmisc.c
--- a/drivers/acpi/resources/rsmisc.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/acpi/resources/rsmisc.c	2005-03-01 23:38:54 -08:00
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/resources/rsutils.c b/drivers/acpi/resources/rsutils.c
--- a/drivers/acpi/resources/rsutils.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/acpi/resources/rsutils.c	2005-03-01 23:38:52 -08:00
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -339,6 +339,13 @@
 	 * Execute the method, no return value
 	 */
 	status = acpi_ns_evaluate_relative ("_SRS", &info);
+	if (ACPI_SUCCESS (status)) {
+		/* Delete any return object (especially if implicit_return is enabled) */
+
+		if (info.return_object) {
+			acpi_ut_remove_reference (info.return_object);
+		}
+	}
 
 	/*
 	 * Clean up and return the status from acpi_ns_evaluate_relative
diff -Nru a/drivers/acpi/resources/rsxface.c b/drivers/acpi/resources/rsxface.c
--- a/drivers/acpi/resources/rsxface.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/acpi/resources/rsxface.c	2005-03-01 23:39:07 -08:00
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/scan.c b/drivers/acpi/scan.c
--- a/drivers/acpi/scan.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/acpi/scan.c	2005-03-01 23:38:56 -08:00
@@ -2,9 +2,9 @@
  * scan.c - support for transforming the ACPI namespace into individual objects
  */
 
+#include <linux/module.h>
 #include <linux/init.h>
 #include <linux/acpi.h>
-#include <linux/module.h>
 
 #include <acpi/acpi_drivers.h>
 #include <acpi/acinterp.h>	/* for acpi_ex_eisa_id_to_string() */
@@ -24,7 +24,7 @@
 #define ACPI_BUS_DEVICE_NAME		"System Bus"
 
 static LIST_HEAD(acpi_device_list);
-spinlock_t acpi_device_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(acpi_device_lock);
 LIST_HEAD(acpi_wakeup_device_list);
 
 static void acpi_device_release(struct kobject * kobj)
@@ -35,7 +35,49 @@
 	kfree(dev);
 }
 
+struct acpi_device_attribute {
+	struct attribute attr;
+	ssize_t (*show)(struct acpi_device *, char *);
+	ssize_t (*store)(struct acpi_device *, const char *, size_t);
+};
+
+typedef void acpi_device_sysfs_files(struct kobject *,
+				const struct attribute *);
+
+static void setup_sys_fs_device_files(struct acpi_device *dev,
+		acpi_device_sysfs_files *func);
+
+#define create_sysfs_device_files(dev)	\
+	setup_sys_fs_device_files(dev, (acpi_device_sysfs_files *)&sysfs_create_file)
+#define remove_sysfs_device_files(dev)	\
+	setup_sys_fs_device_files(dev, (acpi_device_sysfs_files *)&sysfs_remove_file)
+
+
+#define to_acpi_device(n) container_of(n, struct acpi_device, kobj)
+#define to_handle_attr(n) container_of(n, struct acpi_device_attribute, attr);
+
+static ssize_t acpi_device_attr_show(struct kobject *kobj,
+		struct attribute *attr, char *buf)
+{
+	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;
+}
+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;
+}
+
+static struct sysfs_ops acpi_device_sysfs_ops = {
+	.show	= acpi_device_attr_show,
+	.store	= acpi_device_attr_store,
+};
+
 static struct kobj_type ktype_acpi_ns = {
+	.sysfs_ops	= &acpi_device_sysfs_ops,
 	.release	= acpi_device_release,
 };
 
@@ -58,6 +100,7 @@
 	INIT_LIST_HEAD(&device->children);
 	INIT_LIST_HEAD(&device->node);
 	INIT_LIST_HEAD(&device->g_list);
+	INIT_LIST_HEAD(&device->wakeup_list);
 
 	spin_lock(&acpi_device_lock);
 	if (device->parent) {
@@ -65,15 +108,17 @@
 		list_add_tail(&device->g_list,&device->parent->g_list);
 	} else
 		list_add_tail(&device->g_list,&acpi_device_list);
+	if (device->wakeup.flags.valid)
+		list_add_tail(&device->wakeup_list,&acpi_wakeup_device_list);
 	spin_unlock(&acpi_device_lock);
 
-	kobject_init(&device->kobj);
 	strlcpy(device->kobj.name,device->pnp.bus_id,KOBJ_NAME_LEN);
 	if (parent)
 		device->kobj.parent = &parent->kobj;
 	device->kobj.ktype = &ktype_acpi_ns;
 	device->kobj.kset = &acpi_namespace_kset;
-	kobject_add(&device->kobj);
+	kobject_register(&device->kobj);
+	create_sysfs_device_files(device);
 }
 
 static int
@@ -81,6 +126,19 @@
 	struct acpi_device	*device, 
 	int			type)
 {
+	spin_lock(&acpi_device_lock);
+	if (device->parent) {
+		list_del(&device->node);
+		list_del(&device->g_list);
+	} else
+		list_del(&device->g_list);
+
+	list_del(&device->wakeup_list);
+
+	spin_unlock(&acpi_device_lock);
+
+	acpi_detach_data(device->handle, acpi_bus_data_handler);
+	remove_sysfs_device_files(device);
 	kobject_unregister(&device->kobj);
 	return 0;
 }
@@ -272,12 +330,6 @@
 	if (!acpi_match_ids(device, "PNP0C0D,PNP0C0C,PNP0C0E"))
 		device->wakeup.flags.run_wake = 1;
 
-	/* TBD: lock */
-	INIT_LIST_HEAD(&device->wakeup_list);
-	spin_lock(&acpi_device_lock);
-	list_add_tail(&device->wakeup_list, &acpi_wakeup_device_list);
-	spin_unlock(&acpi_device_lock);
-
 end:
 	if (ACPI_FAILURE(status))
 		device->flags.wake_capable = 0;
@@ -285,6 +337,114 @@
 }
 
 /* --------------------------------------------------------------------------
+		ACPI hotplug sysfs device file support
+   -------------------------------------------------------------------------- */
+static ssize_t acpi_eject_store(struct acpi_device *device, 
+		const char *buf, size_t count);
+
+#define ACPI_DEVICE_ATTR(_name,_mode,_show,_store) \
+static struct acpi_device_attribute acpi_device_attr_##_name = \
+		__ATTR(_name, _mode, _show, _store)
+
+ACPI_DEVICE_ATTR(eject, 0200, NULL, acpi_eject_store);
+
+/**
+ * setup_sys_fs_device_files - sets up the device files under device namespace
+ * @@dev:	acpi_device object
+ * @@func:	function pointer to create or destroy the device file
+ */
+static void
+setup_sys_fs_device_files (
+	struct acpi_device *dev,
+	acpi_device_sysfs_files *func)
+{
+	if (dev->flags.ejectable == 1)
+		(*(func))(&dev->kobj,&acpi_device_attr_eject.attr);
+}
+
+static int
+acpi_eject_operation(acpi_handle handle, int lockable)
+{
+	struct acpi_object_list arg_list;
+	union acpi_object arg;
+	acpi_status status = AE_OK;
+
+	/*
+	 * TBD: evaluate _PS3?
+	 */
+
+	if (lockable) {
+		arg_list.count = 1;
+		arg_list.pointer = &arg;
+		arg.type = ACPI_TYPE_INTEGER;
+		arg.integer.value = 0;
+		acpi_evaluate_object(handle, "_LCK", &arg_list, NULL);
+	}
+
+	arg_list.count = 1;
+	arg_list.pointer = &arg;
+	arg.type = ACPI_TYPE_INTEGER;
+	arg.integer.value = 1;
+
+	/*
+	 * TBD: _EJD support.
+	 */
+
+	status = acpi_evaluate_object(handle, "_EJ0", &arg_list, NULL);
+	if (ACPI_FAILURE(status)) {
+		return(-ENODEV);
+	}
+
+	return(0);
+}
+
+
+static ssize_t
+acpi_eject_store(struct acpi_device *device, const char *buf, size_t count)
+{
+	int	result;
+	int	ret = count;
+	int	islockable;
+	acpi_status	status;
+	acpi_handle	handle;
+	acpi_object_type	type = 0;
+
+	if ((!count) || (buf[0] != '1')) {
+		return -EINVAL;
+	}
+
+#ifndef FORCE_EJECT
+	if (device->driver == NULL) {
+		ret = -ENODEV;
+		goto err;
+	}
+#endif
+	status = acpi_get_type(device->handle, &type);
+	if (ACPI_FAILURE(status) || (!device->flags.ejectable) ) {
+		ret = -ENODEV;
+		goto err;
+	}
+
+	islockable = device->flags.lockable;
+	handle = device->handle;
+
+	if (type == ACPI_TYPE_PROCESSOR)
+		result = acpi_bus_trim(device, 0);
+	else
+		result = acpi_bus_trim(device, 1);
+
+	if (!result)
+		result = acpi_eject_operation(handle, islockable);
+
+	if (result) {
+		ret = -EBUSY;
+	}
+err:
+	return ret;
+}
+
+
+/* --------------------------------------------------------------------------
                               Performance Management
    -------------------------------------------------------------------------- */
 
@@ -727,7 +887,7 @@
 #ifdef CONFIG_ACPI_DEBUG_OUTPUT
 	char		*type_string = NULL;
 	char		name[80] = {'?','\0'};
-	acpi_buffer	buffer = {sizeof(name), name};
+	struct acpi_buffer	buffer = {sizeof(name), name};
 
 	switch (type) {
 	case ACPI_BUS_TYPE_DEVICE:
@@ -764,7 +924,55 @@
 #endif /*CONFIG_ACPI_DEBUG_OUTPUT*/
 }
 
-int 
+
+int
+acpi_bus_remove (
+	struct acpi_device *dev,
+	int rmdevice)
+{
+	int 			result = 0;
+	struct acpi_driver	*driver;
+	
+	ACPI_FUNCTION_TRACE("acpi_bus_remove");
+
+	if (!dev)
+		return_VALUE(-EINVAL);
+
+	driver = dev->driver;
+
+	if ((driver) && (driver->ops.remove)) {
+
+		if (driver->ops.stop) {
+			result = driver->ops.stop(dev, ACPI_BUS_REMOVAL_EJECT);
+			if (result)
+				return_VALUE(result);
+		}
+
+		result = dev->driver->ops.remove(dev, ACPI_BUS_REMOVAL_EJECT);
+		if (result) {
+			return_VALUE(result);
+		}
+
+		atomic_dec(&dev->driver->references);
+		dev->driver = NULL;
+		acpi_driver_data(dev) = NULL;
+	}
+
+	if (!rmdevice)
+		return_VALUE(0);
+
+	if (dev->flags.bus_address) {
+		if ((dev->parent) && (dev->parent->ops.unbind))
+			dev->parent->ops.unbind(dev);
+	}
+	
+	acpi_device_unregister(dev, ACPI_BUS_REMOVAL_EJECT);
+
+	return_VALUE(0);
+}
+
+
+int
 acpi_bus_add (
 	struct acpi_device	**child,
 	struct acpi_device	*parent,
@@ -911,7 +1119,7 @@
 EXPORT_SYMBOL(acpi_bus_add);
 
 
-static int acpi_bus_scan (struct acpi_device	*start)
+int acpi_bus_scan (struct acpi_device	*start)
 {
 	acpi_status		status = AE_OK;
 	struct acpi_device	*parent = NULL;
@@ -1014,6 +1222,62 @@
 }
 EXPORT_SYMBOL(acpi_bus_scan);
 
+
+int
+acpi_bus_trim(struct acpi_device	*start,
+		int rmdevice)
+{
+	acpi_status		status;
+	struct acpi_device	*parent, *child;
+	acpi_handle		phandle, chandle;
+	acpi_object_type	type;
+	u32			level = 1;
+	int			err = 0;
+
+	parent  = start;
+	phandle = start->handle;
+	child = chandle = NULL;
+
+	while ((level > 0) && parent && (!err)) {
+		status = acpi_get_next_object(ACPI_TYPE_ANY, phandle,
+			chandle, &chandle);
+
+		/*
+		 * If this scope is exhausted then move our way back up.
+		 */
+		if (ACPI_FAILURE(status)) {
+			level--;
+			chandle = phandle;
+			acpi_get_parent(phandle, &phandle);
+			child = parent;
+			parent = parent->parent;
+
+			if (level == 0)
+				err = acpi_bus_remove(child, rmdevice);
+			else
+				err = acpi_bus_remove(child, 1);
+
+			continue;
+		}
+
+		status = acpi_get_type(chandle, &type);
+		if (ACPI_FAILURE(status)) {
+			continue;
+		}
+		/*
+		 * If there is a device corresponding to chandle then
+		 * parse it (depth-first).
+		 */
+		if (acpi_bus_get_device(chandle, &child) == 0) {
+			level++;
+			phandle = chandle;
+			chandle = NULL;
+			parent = child;
+		}
+		continue;
+	}
+	return err;
+}
 
 static int
 acpi_bus_scan_fixed (
diff -Nru a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c
--- a/drivers/acpi/sleep/main.c	2005-03-01 23:38:44 -08:00
+++ b/drivers/acpi/sleep/main.c	2005-03-01 23:38:44 -08:00
@@ -159,7 +159,7 @@
 
 int acpi_suspend(u32 acpi_state)
 {
-	u32 states[] = {
+	suspend_state_t states[] = {
 		[1]	= PM_SUSPEND_STANDBY,
 		[3]	= PM_SUSPEND_MEM,
 		[4]	= PM_SUSPEND_DISK,
diff -Nru a/drivers/acpi/sleep/proc.c b/drivers/acpi/sleep/proc.c
--- a/drivers/acpi/sleep/proc.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/acpi/sleep/proc.c	2005-03-01 23:39:07 -08:00
@@ -83,6 +83,7 @@
 {
 	u32			sec, min, hr;
 	u32			day, mo, yr;
+	unsigned char		rtc_control = 0;
 
 	ACPI_FUNCTION_TRACE("acpi_system_alarm_seq_show");
 
@@ -91,10 +92,12 @@
 	sec = CMOS_READ(RTC_SECONDS_ALARM);
 	min = CMOS_READ(RTC_MINUTES_ALARM);
 	hr = CMOS_READ(RTC_HOURS_ALARM);
+	rtc_control = CMOS_READ(RTC_CONTROL);
 
-#if 0	/* If we ever get an FACP with proper values... */
+	/* If we ever get an FACP with proper values... */
 	if (acpi_gbl_FADT->day_alrm)
-		day = CMOS_READ(acpi_gbl_FADT->day_alrm);
+		/* ACPI spec: only low 6 its should be cared */
+		day = CMOS_READ(acpi_gbl_FADT->day_alrm) & 0x3F;
 	else
 		day =  CMOS_READ(RTC_DAY_OF_MONTH);
 	if (acpi_gbl_FADT->mon_alrm)
@@ -105,24 +108,20 @@
 		yr = CMOS_READ(acpi_gbl_FADT->century) * 100 + CMOS_READ(RTC_YEAR);
 	else
 		yr = CMOS_READ(RTC_YEAR);
-#else
-	day = CMOS_READ(RTC_DAY_OF_MONTH);
-	mo = CMOS_READ(RTC_MONTH);
-	yr = CMOS_READ(RTC_YEAR);
-#endif
 
 	spin_unlock(&rtc_lock);
 
-	BCD_TO_BIN(sec);
-	BCD_TO_BIN(min);
-	BCD_TO_BIN(hr);
-	BCD_TO_BIN(day);
-	BCD_TO_BIN(mo);
-	BCD_TO_BIN(yr);
+	if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
+		BCD_TO_BIN(sec);
+		BCD_TO_BIN(min);
+		BCD_TO_BIN(hr);
+		BCD_TO_BIN(day);
+		BCD_TO_BIN(mo);
+		BCD_TO_BIN(yr);
+	}
 
-#if 0
 	/* we're trusting the FADT (see above)*/
-#else
+	if (!acpi_gbl_FADT->century)
 	/* If we're not trusting the FADT, we should at least make it
 	 * right for _this_ century... ehm, what is _this_ century?
 	 *
@@ -141,8 +140,7 @@
 	 *        s/2000/2100
 	 *
 	 */
-	yr += 2000;
-#endif
+		yr += 2000;
 
 	seq_printf(seq,"%4.4u-", yr);
 	(mo > 12)  ? seq_puts(seq, "**-")  : seq_printf(seq, "%2.2u-", mo);
@@ -316,6 +314,13 @@
 	}
 
 	spin_lock_irq(&rtc_lock);
+	/*
+	 * Disable alarm interrupt before setting alarm timer or else
+	 * when ACPI_EVENT_RTC is enabled, a spurious ACPI interrupt occurs
+	 */
+	rtc_control &= ~RTC_AIE;
+	CMOS_WRITE(rtc_control, RTC_CONTROL);
+	CMOS_READ(RTC_INTR_FLAGS);
 
 	/* write the fields the rtc knows about */
 	CMOS_WRITE(hr, RTC_HOURS_ALARM);
@@ -327,24 +332,21 @@
 	 * offsets into the CMOS RAM here -- which for some reason are pointing
 	 * to the RTC area of memory.
 	 */
-#if 0
 	if (acpi_gbl_FADT->day_alrm)
 		CMOS_WRITE(day, acpi_gbl_FADT->day_alrm);
 	if (acpi_gbl_FADT->mon_alrm)
 		CMOS_WRITE(mo, acpi_gbl_FADT->mon_alrm);
 	if (acpi_gbl_FADT->century)
 		CMOS_WRITE(yr/100, acpi_gbl_FADT->century);
-#endif
 	/* enable the rtc alarm interrupt */
-	if (!(rtc_control & RTC_AIE)) {
-		rtc_control |= RTC_AIE;
-		CMOS_WRITE(rtc_control,RTC_CONTROL);
-		CMOS_READ(RTC_INTR_FLAGS);
-	}
+	rtc_control |= RTC_AIE;
+	CMOS_WRITE(rtc_control, RTC_CONTROL);
+	CMOS_READ(RTC_INTR_FLAGS);
 
 	spin_unlock_irq(&rtc_lock);
 
-	acpi_set_register(ACPI_BITREG_RT_CLOCK_ENABLE, 1, ACPI_MTX_LOCK);
+	acpi_clear_event(ACPI_EVENT_RTC);
+	acpi_enable_event(ACPI_EVENT_RTC, 0);
 
 	*ppos += count;
 
@@ -395,6 +397,7 @@
 	char		strbuf[5];
 	char		str[5] = "";
 	int 		len = count;
+	struct acpi_device *found_dev = NULL;
 
 	if (len > 4) len = 4;
 
@@ -411,9 +414,25 @@
 
 		if (!strncmp(dev->pnp.bus_id, str, 4)) {
 			dev->wakeup.state.enabled = dev->wakeup.state.enabled ? 0:1;
+			found_dev = dev;
 			break;
 		}
 	}
+	if (found_dev) {
+		list_for_each_safe(node, next, &acpi_wakeup_device_list) {
+			struct acpi_device * dev = container_of(node,
+				struct acpi_device, wakeup_list);
+
+			if ((dev != found_dev) &&
+				(dev->wakeup.gpe_number == found_dev->wakeup.gpe_number) &&
+				(dev->wakeup.gpe_device == found_dev->wakeup.gpe_device)) {
+				printk(KERN_WARNING "ACPI: '%s' and '%s' have the same GPE, "
+					"can't disable/enable one seperately\n",
+					dev->pnp.bus_id, found_dev->pnp.bus_id);
+				dev->wakeup.state.enabled = found_dev->wakeup.state.enabled;
+			}
+		}
+	}
 	spin_unlock(&acpi_device_lock);
 	return count;
 }
@@ -449,6 +468,14 @@
 };
 
 
+static u32 rtc_handler(void * context)
+{
+	acpi_clear_event(ACPI_EVENT_RTC);
+	acpi_disable_event(ACPI_EVENT_RTC, 0);
+
+	return ACPI_INTERRUPT_HANDLED;
+}
+
 static int acpi_sleep_proc_init(void)
 {
 	struct proc_dir_entry	*entry = NULL;
@@ -474,6 +501,7 @@
 	if (entry)
 		entry->proc_fops = &acpi_system_wakeup_device_fops;
 
+	acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, NULL);
 	return 0;
 }
 
diff -Nru a/drivers/acpi/tables/tbconvrt.c b/drivers/acpi/tables/tbconvrt.c
--- a/drivers/acpi/tables/tbconvrt.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/acpi/tables/tbconvrt.c	2005-03-01 23:38:56 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -190,7 +190,7 @@
 	new_gas_struct->address_space_id = ACPI_ADR_SPACE_SYSTEM_IO;
 	new_gas_struct->register_bit_width = register_bit_width;
 	new_gas_struct->register_bit_offset = 0;
-	new_gas_struct->reserved        = 0;
+	new_gas_struct->access_width    = 0;
 }
 
 
@@ -269,8 +269,8 @@
 		 * that immediately follows.
 		 */
 		ACPI_MEMCPY (&local_fadt->reset_register,
-			&((struct fadt_descriptor_rev2_minus *) original_fadt)->reset_register,
-			sizeof (struct acpi_generic_address) + 1);
+			&(ACPI_CAST_PTR (struct fadt_descriptor_rev2_minus, original_fadt))->reset_register,
+  			sizeof (struct acpi_generic_address) + 1);
 	}
 	else {
 		/*
@@ -510,7 +510,7 @@
  *
  * FUNCTION:    acpi_tb_convert_table_facs
  *
- * PARAMETERS:  table_info      - Info for currently installad FACS
+ * PARAMETERS:  table_info      - Info for currently installed FACS
  *
  * RETURN:      Status
  *
diff -Nru a/drivers/acpi/tables/tbget.c b/drivers/acpi/tables/tbget.c
--- a/drivers/acpi/tables/tbget.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/acpi/tables/tbget.c	2005-03-01 23:39:07 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/tables/tbgetall.c b/drivers/acpi/tables/tbgetall.c
--- a/drivers/acpi/tables/tbgetall.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/acpi/tables/tbgetall.c	2005-03-01 23:39:08 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/tables/tbinstal.c b/drivers/acpi/tables/tbinstal.c
--- a/drivers/acpi/tables/tbinstal.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/acpi/tables/tbinstal.c	2005-03-01 23:38:53 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/tables/tbrsdt.c b/drivers/acpi/tables/tbrsdt.c
--- a/drivers/acpi/tables/tbrsdt.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/acpi/tables/tbrsdt.c	2005-03-01 23:39:07 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -277,6 +277,7 @@
 
 	acpi_tb_get_rsdt_address (&address);
 
+	table_info.type = ACPI_TABLE_XSDT;
 	status = acpi_tb_get_table (&address, &table_info);
 	if (ACPI_FAILURE (status)) {
 		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not get the RSDT/XSDT, %s\n",
diff -Nru a/drivers/acpi/tables/tbutils.c b/drivers/acpi/tables/tbutils.c
--- a/drivers/acpi/tables/tbutils.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/acpi/tables/tbutils.c	2005-03-01 23:39:09 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/tables/tbxface.c b/drivers/acpi/tables/tbxface.c
--- a/drivers/acpi/tables/tbxface.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/acpi/tables/tbxface.c	2005-03-01 23:39:16 -08:00
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/tables/tbxfroot.c b/drivers/acpi/tables/tbxfroot.c
--- a/drivers/acpi/tables/tbxfroot.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/acpi/tables/tbxfroot.c	2005-03-01 23:39:08 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -114,8 +114,10 @@
 
 	/* Check oem_id and oem_table_id */
 
-	if ((oem_id[0]     && ACPI_STRCMP (oem_id, table->oem_id)) ||
-		(oem_table_id[0] && ACPI_STRCMP (oem_table_id, table->oem_table_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)))) {
 		return_ACPI_STATUS (AE_AML_NAME_NOT_FOUND);
 	}
 
@@ -358,7 +360,8 @@
 
 	status = acpi_tb_find_rsdp (&table_info, flags);
 	if (ACPI_FAILURE (status)) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "RSDP structure not found, %s Flags=%X\n",
+		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);
 	}
@@ -387,35 +390,58 @@
 	u8                              *start_address,
 	u32                             length)
 {
-	u32                             offset;
 	u8                              *mem_rover;
+	u8                              *end_address;
+	u8                              checksum;
 
 
 	ACPI_FUNCTION_TRACE ("tb_scan_memory_for_rsdp");
 
 
-	/* Search from given start addr for the requested length  */
+	end_address = start_address + length;
 
-	for (offset = 0, mem_rover = start_address;
-		 offset < length;
-		 offset += ACPI_RSDP_SCAN_STEP, mem_rover += ACPI_RSDP_SCAN_STEP) {
+	/* Search from given start address for the requested length */
 
+	for (mem_rover = start_address; mem_rover < end_address;
+		 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 &&
-			acpi_tb_checksum (mem_rover, ACPI_RSDP_CHECKSUM_LENGTH) == 0) {
-			/* If so, we have found the RSDP */
+		if (ACPI_STRNCMP ((char *) mem_rover, RSDP_SIG, sizeof (RSDP_SIG)-1) != 0) {
+			/* No signature match, keep looking */
+
+			continue;
+		}
+
+		/* Signature matches, check the appropriate checksum */
+
+		if ((ACPI_CAST_PTR (struct rsdp_descriptor, mem_rover))->revision < 2) {
+			/* ACPI version 1.0 */
+
+			checksum = acpi_tb_checksum (mem_rover, ACPI_RSDP_CHECKSUM_LENGTH);
+		}
+		else {
+			/* Post ACPI 1.0, use extended_checksum */
+
+			checksum = acpi_tb_checksum (mem_rover, ACPI_RSDP_XCHECKSUM_LENGTH);
+		}
+
+		if (checksum == 0) {
+			/* Checksum valid, we have found a valid RSDP */
 
 			ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
-				"RSDP located at physical address %p\n",mem_rover));
+				"RSDP located at physical address %p\n", mem_rover));
 			return_PTR (mem_rover);
 		}
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+			"Found an RSDP at physical address %p, but it has a bad checksum\n",
+			mem_rover));
 	}
 
 	/* Searched entire block, no RSDP was found */
 
-	ACPI_DEBUG_PRINT ((ACPI_DB_INFO,"Searched entire block, no RSDP was found.\n"));
+	ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+		"Searched entire block, no valid RSDP was found.\n"));
 	return_PTR (NULL);
 }
 
@@ -467,7 +493,8 @@
 				  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_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);
 		}
@@ -486,7 +513,8 @@
 					  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",
+				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);
 			}
@@ -511,7 +539,8 @@
 				  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_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);
 		}
diff -Nru a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
--- a/drivers/acpi/thermal.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/acpi/thermal.c	2005-03-01 23:39:09 -08:00
@@ -64,6 +64,7 @@
 #define ACPI_THERMAL_PATH_POWEROFF	"/sbin/poweroff"
 
 #define ACPI_THERMAL_MAX_ACTIVE	10
+#define ACPI_THERMAL_MAX_LIMIT_STR_LEN 65
 
 #define KELVIN_TO_CELSIUS(t)    (long)(((long)t-2732>=0) ? ((long)t-2732+5)/10 : ((long)t-2732-5)/10)
 #define CELSIUS_TO_KELVIN(t)	((t+273)*10)
@@ -899,21 +900,33 @@
 	struct seq_file		*m = (struct seq_file *)file->private_data;
 	struct acpi_thermal	*tz = (struct acpi_thermal *)m->private;
 
-	char			limit_string[65] = {'\0'};
+	char			*limit_string; 
 	int			num, critical, hot, passive;
-	int			active[ACPI_THERMAL_MAX_ACTIVE];
+	int			*active; 
 	int			i = 0;
 
 	ACPI_FUNCTION_TRACE("acpi_thermal_write_trip_points");
 
-	if (!tz || (count > sizeof(limit_string) - 1)) {
+	limit_string = kmalloc(ACPI_THERMAL_MAX_LIMIT_STR_LEN, GFP_KERNEL);
+	if(!limit_string)
+		return_VALUE(-ENOMEM);
+
+	memset(limit_string, 0, ACPI_THERMAL_MAX_LIMIT_STR_LEN);
+
+	active = kmalloc(ACPI_THERMAL_MAX_ACTIVE *sizeof(int), GFP_KERNEL);
+	if(!active)
+		return_VALUE(-ENOMEM);
+
+	if (!tz || (count > ACPI_THERMAL_MAX_LIMIT_STR_LEN - 1)) {
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid argument\n"));
-		return_VALUE(-EINVAL);
+		count = -EINVAL;
+		goto end;
 	}
 	
 	if (copy_from_user(limit_string, buffer, count)) {
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid data\n"));
-		return_VALUE(-EFAULT);
+		count = -EFAULT;
+		goto end;
 	}
 	
 	limit_string[count] = '\0';
@@ -924,7 +937,8 @@
 				&active[5], &active[6], &active[7], &active[8], &active[9]);
 	if(!(num >=5 && num < (ACPI_THERMAL_MAX_ACTIVE + 3))) {
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid data format\n"));
-		return_VALUE(-EINVAL);
+		count = -EINVAL;
+		goto end;
 	}
 
 	tz->trips.critical.temperature = CELSIUS_TO_KELVIN(critical);
@@ -936,6 +950,9 @@
 		tz->trips.active[i].temperature = CELSIUS_TO_KELVIN(active[i]);
 	}
 	
+end:
+	kfree(active);
+	kfree(limit_string);
 	return_VALUE(count);
 }
 
diff -Nru a/drivers/acpi/toshiba_acpi.c b/drivers/acpi/toshiba_acpi.c
--- a/drivers/acpi/toshiba_acpi.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/acpi/toshiba_acpi.c	2005-03-01 23:38:52 -08:00
@@ -508,7 +508,7 @@
 			proc->write_proc = (write_proc_t*)dispatch_write;
 	}
 
-	return(AE_OK);
+	return AE_OK;
 }
 
 static acpi_status __exit
@@ -518,7 +518,7 @@
 
 	for (item = proc_items; item->name; ++item)
 		remove_proc_entry(item->name, toshiba_proc_dir);
-	return(AE_OK);
+	return AE_OK;
 }
 
 static int __init
diff -Nru a/drivers/acpi/utilities/utalloc.c b/drivers/acpi/utilities/utalloc.c
--- a/drivers/acpi/utilities/utalloc.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/acpi/utilities/utalloc.c	2005-03-01 23:38:52 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -73,9 +73,12 @@
 	ACPI_FUNCTION_ENTRY ();
 
 
+	cache_info = &acpi_gbl_memory_lists[list_id];
+
+#ifdef ACPI_ENABLE_OBJECT_CACHE
+
 	/* If walk cache is full, just free this wallkstate object */
 
-	cache_info = &acpi_gbl_memory_lists[list_id];
 	if (cache_info->cache_depth >= cache_info->max_cache_depth) {
 		ACPI_MEM_FREE (object);
 		ACPI_MEM_TRACKING (cache_info->total_freed++);
@@ -101,6 +104,14 @@
 
 		(void) acpi_ut_release_mutex (ACPI_MTX_CACHES);
 	}
+
+#else
+
+	/* Object cache is disabled; just free the object */
+
+	ACPI_MEM_FREE (object);
+	ACPI_MEM_TRACKING (cache_info->total_freed++);
+#endif
 }
 
 
@@ -130,6 +141,9 @@
 
 
 	cache_info = &acpi_gbl_memory_lists[list_id];
+
+#ifdef ACPI_ENABLE_OBJECT_CACHE
+
 	if (ACPI_FAILURE (acpi_ut_acquire_mutex (ACPI_MTX_CACHES))) {
 		return (NULL);
 	}
@@ -174,10 +188,19 @@
 		ACPI_MEM_TRACKING (cache_info->total_allocated++);
 	}
 
+#else
+
+	/* Object cache is disabled; just allocate the object */
+
+	object = ACPI_MEM_CALLOCATE (cache_info->object_size);
+	ACPI_MEM_TRACKING (cache_info->total_allocated++);
+#endif
+
 	return (object);
 }
 
 
+#ifdef ACPI_ENABLE_OBJECT_CACHE
 /******************************************************************************
  *
  * FUNCTION:    acpi_ut_delete_generic_cache
@@ -212,6 +235,7 @@
 		cache_info->cache_depth--;
 	}
 }
+#endif
 
 
 /*******************************************************************************
diff -Nru a/drivers/acpi/utilities/utcopy.c b/drivers/acpi/utilities/utcopy.c
--- a/drivers/acpi/utilities/utcopy.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/acpi/utilities/utcopy.c	2005-03-01 23:38:56 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/utilities/utdebug.c b/drivers/acpi/utilities/utdebug.c
--- a/drivers/acpi/utilities/utdebug.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/acpi/utilities/utdebug.c	2005-03-01 23:39:07 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/utilities/utdelete.c b/drivers/acpi/utilities/utdelete.c
--- a/drivers/acpi/utilities/utdelete.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/acpi/utilities/utdelete.c	2005-03-01 23:39:18 -08:00
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/utilities/uteval.c b/drivers/acpi/utilities/uteval.c
--- a/drivers/acpi/utilities/uteval.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/acpi/utilities/uteval.c	2005-03-01 23:38:52 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -198,6 +198,17 @@
 		break;
 	}
 
+	if ((acpi_gbl_enable_interpreter_slack) &&
+		(!expected_return_btypes)) {
+		/*
+		 * We received a return object, but one was not expected.  This can
+		 * happen frequently if the "implicit return" feature is enabled.
+		 * Just delete the return object and return AE_OK.
+		 */
+		acpi_ut_remove_reference (info.return_object);
+		return_ACPI_STATUS (AE_OK);
+	}
+
 	/* Is the return object one of the expected types? */
 
 	if (!(expected_return_btypes & return_btype)) {
@@ -205,8 +216,9 @@
 			prefix_node, path, AE_TYPE);
 
 		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
-			"Type returned from %s was incorrect: %X\n",
-			path, ACPI_GET_OBJECT_TYPE (info.return_object)));
+			"Type returned from %s was incorrect: %s, expected Btypes: %X\n",
+			path, acpi_ut_get_object_type_name (info.return_object),
+			expected_return_btypes));
 
 		/* On error exit, we must delete the return object */
 
diff -Nru a/drivers/acpi/utilities/utglobal.c b/drivers/acpi/utilities/utglobal.c
--- a/drivers/acpi/utilities/utglobal.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/acpi/utilities/utglobal.c	2005-03-01 23:38:52 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -219,6 +219,8 @@
  * NOTES:
  * 1) _SB_ is defined to be a device to allow \_SB_._INI to be run
  *    during the initialization sequence.
+ * 2) _TZ_ is defined to be a thermal zone in order to allow ASL code to
+ *    perform a Notify() operation on it.
  */
 const struct acpi_predefined_names      acpi_gbl_pre_defined_names[] =
 { {"_GPE",    ACPI_TYPE_LOCAL_SCOPE,      NULL},
@@ -226,12 +228,12 @@
 	{"_SB_",    ACPI_TYPE_DEVICE,           NULL},
 	{"_SI_",    ACPI_TYPE_LOCAL_SCOPE,      NULL},
 	{"_TZ_",    ACPI_TYPE_THERMAL,          NULL},
-	{"_REV",    ACPI_TYPE_INTEGER,          "2"},
+	{"_REV",    ACPI_TYPE_INTEGER,          (char *) ACPI_CA_SUPPORT_LEVEL},
 	{"_OS_",    ACPI_TYPE_STRING,           ACPI_OS_NAME},
-	{"_GL_",    ACPI_TYPE_MUTEX,            "0"},
+	{"_GL_",    ACPI_TYPE_MUTEX,            (char *) 1},
 
 #if !defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY)
-	{"_OSI",    ACPI_TYPE_METHOD,           "1"},
+	{"_OSI",    ACPI_TYPE_METHOD,           (char *) 1},
 #endif
 	{NULL,      ACPI_TYPE_ANY,              NULL}              /* Table terminator */
 };
diff -Nru a/drivers/acpi/utilities/utinit.c b/drivers/acpi/utilities/utinit.c
--- a/drivers/acpi/utilities/utinit.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/acpi/utilities/utinit.c	2005-03-01 23:38:58 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/utilities/utmath.c b/drivers/acpi/utilities/utmath.c
--- a/drivers/acpi/utilities/utmath.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/acpi/utilities/utmath.c	2005-03-01 23:39:16 -08:00
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c
--- a/drivers/acpi/utilities/utmisc.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/acpi/utilities/utmisc.c	2005-03-01 23:38:52 -08:00
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -422,6 +422,12 @@
 		string++;
 	}
 
+	/* Any string left? */
+
+	if (!(*string)) {
+		goto error_exit;
+	}
+
 	/* Main loop: convert the string to a 64-bit integer */
 
 	while (*string) {
@@ -672,7 +678,6 @@
 	acpi_mutex_handle               mutex_id)
 {
 	acpi_status                     status;
-	u32                             i;
 	u32                             this_thread_id;
 
 
@@ -685,30 +690,37 @@
 
 	this_thread_id = acpi_os_get_thread_id ();
 
-	/*
-	 * Deadlock prevention.  Check if this thread owns any mutexes of value
-	 * greater than or equal to this one.  If so, the thread has violated
-	 * the mutex ordering rule.  This indicates a coding error somewhere in
-	 * the ACPI subsystem code.
-	 */
-	for (i = mutex_id; i < MAX_MUTEX; i++) {
-		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));
+#ifdef ACPI_MUTEX_DEBUG
+	{
+		u32                             i;
+		/*
+		 * Mutex debug code, for internal debugging only.
+		 *
+		 * Deadlock prevention.  Check if this thread owns any mutexes of value
+		 * greater than or equal to this one.  If so, the thread has violated
+		 * the mutex ordering rule.  This indicates a coding error somewhere in
+		 * the ACPI subsystem code.
+		 */
+		for (i = mutex_id; i < MAX_MUTEX; i++) {
+			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));
 
-				return (AE_ALREADY_ACQUIRED);
-			}
+					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)));
+				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)));
 
-			return (AE_ACQUIRE_DEADLOCK);
+				return (AE_ACQUIRE_DEADLOCK);
+			}
 		}
 	}
+#endif
 
 	ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX,
 			 "Thread %X attempting to acquire Mutex [%s]\n",
@@ -872,7 +884,7 @@
  * DESCRIPTION: Create a new state and push it
  *
  ******************************************************************************/
-
+#ifdef ACPI_FUTURE_USAGE
 acpi_status
 acpi_ut_create_pkg_state_and_push (
 	void                            *internal_object,
@@ -894,7 +906,7 @@
 	acpi_ut_push_generic_state (state_list, state);
 	return (AE_OK);
 }
-
+#endif  /*  ACPI_FUTURE_USAGE  */
 
 /*******************************************************************************
  *
@@ -1187,6 +1199,7 @@
 }
 
 
+#ifdef ACPI_ENABLE_OBJECT_CACHE
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ut_delete_generic_state_cache
@@ -1210,6 +1223,7 @@
 	acpi_ut_delete_generic_cache (ACPI_MEM_LIST_STATE);
 	return_VOID;
 }
+#endif
 
 
 /*******************************************************************************
diff -Nru a/drivers/acpi/utilities/utobject.c b/drivers/acpi/utilities/utobject.c
--- a/drivers/acpi/utilities/utobject.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/acpi/utilities/utobject.c	2005-03-01 23:39:07 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -368,6 +368,7 @@
 }
 
 
+#ifdef ACPI_ENABLE_OBJECT_CACHE
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ut_delete_object_cache
@@ -391,6 +392,7 @@
 	acpi_ut_delete_generic_cache (ACPI_MEM_LIST_OPERAND);
 	return_VOID;
 }
+#endif
 
 
 /*******************************************************************************
diff -Nru a/drivers/acpi/utilities/utxface.c b/drivers/acpi/utilities/utxface.c
--- a/drivers/acpi/utilities/utxface.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/acpi/utilities/utxface.c	2005-03-01 23:38:52 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -514,10 +514,12 @@
 	ACPI_FUNCTION_TRACE ("acpi_purge_cached_objects");
 
 
+#ifdef ACPI_ENABLE_OBJECT_CACHE
 	acpi_ut_delete_generic_state_cache ();
 	acpi_ut_delete_object_cache ();
 	acpi_ds_delete_walk_state_cache ();
 	acpi_ps_delete_parse_cache ();
+#endif
 
 	return_ACPI_STATUS (AE_OK);
 }
diff -Nru a/drivers/acpi/utils.c b/drivers/acpi/utils.c
--- a/drivers/acpi/utils.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/acpi/utils.c	2005-03-01 23:39:17 -08:00
@@ -244,26 +244,34 @@
 	unsigned long		*data)
 {
 	acpi_status             status = AE_OK;
-	union acpi_object	element;
-	struct acpi_buffer	buffer = {sizeof(union acpi_object), &element};
+	union acpi_object	*element;
+	struct acpi_buffer	buffer = {0,NULL};
 
 	ACPI_FUNCTION_TRACE("acpi_evaluate_integer");
 
 	if (!data)
 		return_ACPI_STATUS(AE_BAD_PARAMETER);
 
+	element = kmalloc(sizeof(union acpi_object), GFP_KERNEL);
+	if(!element)
+		return_ACPI_STATUS(AE_NO_MEMORY);
+
+	memset(element, 0, sizeof(union acpi_object));
+	buffer.length = sizeof(union acpi_object);
+	buffer.pointer = element;
 	status = acpi_evaluate_object(handle, pathname, arguments, &buffer);
 	if (ACPI_FAILURE(status)) {
 		acpi_util_eval_error(handle, pathname, status);
 		return_ACPI_STATUS(status);
 	}
 
-	if (element.type != ACPI_TYPE_INTEGER) {
+	if (element->type != ACPI_TYPE_INTEGER) {
 		acpi_util_eval_error(handle, pathname, AE_BAD_DATA);
 		return_ACPI_STATUS(AE_BAD_DATA);
 	}
 
-	*data = element.integer.value;
+	*data = element->integer.value;
+	kfree(element);
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Return value [%lu]\n", *data));
 
diff -Nru a/drivers/acpi/video.c b/drivers/acpi/video.c
--- a/drivers/acpi/video.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/acpi/video.c	2005-03-01 23:39:18 -08:00
@@ -242,6 +242,13 @@
 	.release	= single_release,
 };
 
+static char	device_decode[][30] = {
+	"motherboard VGA device",
+	"PCI VGA device",
+	"AGP VGA device",
+	"UNKNOWN",
+};
+
 static void acpi_video_device_notify ( acpi_handle handle, u32 event, void *data);
 static void acpi_video_device_rebind( struct acpi_video_bus *video);
 static void acpi_video_device_bind( struct acpi_video_bus *video, struct acpi_video_device *device);
@@ -1117,12 +1124,6 @@
 	struct acpi_video_bus	*video = (struct acpi_video_bus *) seq->private;
 	int			status;
 	unsigned long		id;
-	char			device_decode[][30] = {
-					"motherboard VGA device",
-					"PCI VGA device",
-					"AGP VGA device",
-					"UNKNOWN",
-	};
 
 	ACPI_FUNCTION_TRACE("acpi_video_bus_POST_seq_show");
 
@@ -1523,7 +1524,7 @@
 		dod->package.count));
 
 	active_device_list= kmalloc(
- 		dod->package.count*sizeof(struct acpi_video_enumerated_device),
+ 		(1+dod->package.count)*sizeof(struct acpi_video_enumerated_device),
 	       	GFP_KERNEL);
 
 	if (!active_device_list) {
diff -Nru a/drivers/atm/ambassador.c b/drivers/atm/ambassador.c
--- a/drivers/atm/ambassador.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/atm/ambassador.c	2005-03-01 23:38:52 -08:00
@@ -574,7 +574,6 @@
   amb_cq * cq = &dev->cq;
   volatile amb_cq_ptrs * ptrs = &cq->ptrs;
   command * my_slot;
-  unsigned long timeout;
   
   PRINTD (DBG_FLOW|DBG_CMD, "command_do %p", dev);
   
@@ -599,20 +598,14 @@
     // mail the command
     wr_mem (dev, offsetof(amb_mem, mb.adapter.cmd_address), virt_to_bus (ptrs->in));
     
-    // prepare to wait for cq->pending milliseconds
-    // effectively one centisecond on i386
-    timeout = (cq->pending*HZ+999)/1000;
-    
     if (cq->pending > cq->high)
       cq->high = cq->pending;
     spin_unlock (&cq->lock);
     
-    while (timeout) {
-      // go to sleep
-      // PRINTD (DBG_CMD, "wait: sleeping %lu for command", timeout);
-      set_current_state(TASK_UNINTERRUPTIBLE);
-      timeout = schedule_timeout (timeout);
-    }
+    // these comments were in a while-loop before, msleep removes the loop
+    // go to sleep
+    // PRINTD (DBG_CMD, "wait: sleeping %lu for command", timeout);
+    msleep(cq->pending);
     
     // wait for my slot to be reached (all waiters are here or above, until...)
     while (ptrs->out != my_slot) {
@@ -1692,7 +1685,7 @@
 };
 
 
-unsigned int command_successes [] = {
+static unsigned int command_successes [] = {
 	[host_memory_test]     = COMMAND_PASSED_TEST,
 	[read_adapter_memory]  = COMMAND_READ_DATA_OK,
 	[write_adapter_memory] = COMMAND_WRITE_DATA_OK,
@@ -1799,12 +1792,11 @@
   // dump_loader_block (lb);
   wr_mem (dev, offsetof(amb_mem, doorbell), virt_to_bus (lb) & ~onegigmask);
   
-  timeout = command_timeouts[cmd] * HZ/100;
+  timeout = command_timeouts[cmd] * 10;
   
   while (!lb->result || lb->result == cpu_to_be32 (COMMAND_IN_PROGRESS))
     if (timeout) {
-      set_current_state(TASK_UNINTERRUPTIBLE);
-      timeout = schedule_timeout (timeout);
+      timeout = msleep_interruptible(timeout);
     } else {
       PRINTD (DBG_LOAD|DBG_ERR, "command %d timed out", cmd);
       dump_registers (dev);
@@ -1814,10 +1806,10 @@
   
   if (cmd == adapter_start) {
     // wait for start command to acknowledge...
-    timeout = HZ/10;
+    timeout = 100;
     while (rd_plain (dev, offsetof(amb_mem, doorbell)))
       if (timeout) {
-	timeout = schedule_timeout (timeout);
+	timeout = msleep_interruptible(timeout);
       } else {
 	PRINTD (DBG_LOAD|DBG_ERR, "start command did not clear doorbell, res=%08x",
 		be32_to_cpu (lb->result));
@@ -1932,17 +1924,12 @@
   if (diags) { 
     unsigned long timeout;
     // 4.2 second wait
-    timeout = HZ*42/10;
-    while (timeout) {
-      set_current_state(TASK_UNINTERRUPTIBLE);
-      timeout = schedule_timeout (timeout);
-    }
+    msleep(4200);
     // half second time-out
-    timeout = HZ/2;
+    timeout = 500;
     while (!rd_plain (dev, offsetof(amb_mem, mb.loader.ready)))
       if (timeout) {
-        set_current_state(TASK_UNINTERRUPTIBLE);
-	timeout = schedule_timeout (timeout);
+	timeout = msleep_interruptible(timeout);
       } else {
 	PRINTD (DBG_LOAD|DBG_ERR, "reset timed out");
 	return -ETIMEDOUT;
@@ -2056,14 +2043,12 @@
   wr_mem (dev, offsetof(amb_mem, doorbell), virt_to_bus (&a));
   
   // 2.2 second wait (must not touch doorbell during 2 second DMA test)
-  timeout = HZ*22/10;
-  while (timeout)
-    timeout = schedule_timeout (timeout);
+  msleep(2200);
   // give the adapter another half second?
-  timeout = HZ/2;
+  timeout = 500;
   while (rd_plain (dev, offsetof(amb_mem, doorbell)))
     if (timeout) {
-      timeout = schedule_timeout (timeout);
+      timeout = msleep_interruptible(timeout);
     } else {
       PRINTD (DBG_INIT|DBG_ERR, "adapter init timed out");
       return -ETIMEDOUT;
@@ -2088,7 +2073,7 @@
 }
   
 // swap bits within byte to get Ethernet ordering
-u8 bit_swap (u8 byte)
+static u8 bit_swap (u8 byte)
 {
     const u8 swap[] = {
       0x0, 0x8, 0x4, 0xc,
@@ -2228,17 +2213,12 @@
 	spin_lock_init (&dev->rxq[pool].lock);
 }
 
-static int setup_pci_dev(struct pci_dev *pci_dev)
+static void setup_pci_dev(struct pci_dev *pci_dev)
 {
 	unsigned char lat;
-	int ret;
       
 	// enable bus master accesses
 	pci_set_master(pci_dev);
-      
-	ret = pci_enable_device(pci_dev);
-	if (ret < 0)
-		goto out;
 
 	// frobnicate latency (upwards, usually)
 	pci_read_config_byte (pci_dev, PCI_LATENCY_TIMER, &lat);
@@ -2251,22 +2231,27 @@
 			lat, pci_lat);
 		pci_write_config_byte(pci_dev, PCI_LATENCY_TIMER, pci_lat);
 	}
-out:
-	return ret;
 }
 
 static int __devinit amb_probe(struct pci_dev *pci_dev, const struct pci_device_id *pci_ent)
 {
 	amb_dev * dev;
 	int err;
+	unsigned int irq;
+      
+	err = pci_enable_device(pci_dev);
+	if (err < 0) {
+		PRINTK (KERN_ERR, "skipped broken (PLX rev 2) card");
+		goto out;
+	}
 
 	// read resources from PCI configuration space
-	unsigned int irq = pci_dev->irq;
+	irq = pci_dev->irq;
 
 	if (pci_dev->device == PCI_DEVICE_ID_MADGE_AMBASSADOR_BAD) {
 		PRINTK (KERN_ERR, "skipped broken (PLX rev 2) card");
 		err = -EINVAL;
-		goto out;
+		goto out_disable;
 	}
 
 	PRINTD (DBG_INFO, "found Madge ATM adapter (amb) at"
@@ -2277,7 +2262,7 @@
 	err = pci_request_region(pci_dev, 1, DEV_LABEL);
 	if (err < 0) {
 		PRINTK (KERN_ERR, "IO range already in use!");
-		goto out;
+		goto out_disable;
 	}
 
 	dev = kmalloc (sizeof(amb_dev), GFP_KERNEL);
@@ -2295,15 +2280,13 @@
 		goto out_free;
 	}
 
-	err = setup_pci_dev(pci_dev);
-	if (err < 0)
-		goto out_reset;
+	setup_pci_dev(pci_dev);
 
 	// grab (but share) IRQ and install handler
 	err = request_irq(irq, interrupt_handler, SA_SHIRQ, DEV_LABEL, dev);
 	if (err < 0) {
 		PRINTK (KERN_ERR, "request IRQ failed!");
-		goto out_disable;
+		goto out_reset;
 	}
 
 	dev->atm_dev = atm_dev_register (DEV_LABEL, &amb_ops, -1, NULL);
@@ -2337,14 +2320,14 @@
 
 out_free_irq:
 	free_irq(irq, dev);
-out_disable:
-	pci_disable_device(pci_dev);
 out_reset:
 	amb_reset(dev, 0);
 out_free:
 	kfree(dev);
 out_release:
 	pci_release_region(pci_dev, 1);
+out_disable:
+	pci_disable_device(pci_dev);
 	goto out;
 }
 
diff -Nru a/drivers/atm/atmtcp.c b/drivers/atm/atmtcp.c
--- a/drivers/atm/atmtcp.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/atm/atmtcp.c	2005-03-01 23:39:07 -08:00
@@ -396,7 +396,7 @@
 }
 
 
-int atmtcp_attach(struct atm_vcc *vcc,int itf)
+static int atmtcp_attach(struct atm_vcc *vcc,int itf)
 {
 	struct atm_dev *dev;
 
@@ -427,13 +427,13 @@
 }
 
 
-int atmtcp_create_persistent(int itf)
+static int atmtcp_create_persistent(int itf)
 {
 	return atmtcp_create(itf,1,NULL);
 }
 
 
-int atmtcp_remove_persistent(int itf)
+static int atmtcp_remove_persistent(int itf)
 {
 	struct atm_dev *dev;
 	struct atmtcp_dev_data *dev_data;
diff -Nru a/drivers/atm/firestream.c b/drivers/atm/firestream.c
--- a/drivers/atm/firestream.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/atm/firestream.c	2005-03-01 23:38:52 -08:00
@@ -82,14 +82,14 @@
  * would be interpreted. -- REW */
 
 #define NP FS_NR_FREE_POOLS
-int rx_buf_sizes[NP]  = {128,  256,  512, 1024, 2048, 4096, 16384, 65520};
+static int rx_buf_sizes[NP]  = {128,  256,  512, 1024, 2048, 4096, 16384, 65520};
 /* log2:                 7     8     9    10    11    12    14     16 */
 
 #if 0
-int rx_pool_sizes[NP] = {1024, 1024, 512, 256,  128,  64,   32,    32};
+static int rx_pool_sizes[NP] = {1024, 1024, 512, 256,  128,  64,   32,    32};
 #else
 /* debug */
-int rx_pool_sizes[NP] = {128,  128,  128, 64,   64,   64,   32,    32};
+static int rx_pool_sizes[NP] = {128,  128,  128, 64,   64,   64,   32,    32};
 #endif
 /* log2:                 10    10    9    8     7     6     5      5  */
 /* sumlog2:              17    18    18   18    18    18    19     21 */
@@ -250,7 +250,7 @@
 };
 
 
-struct reginit_item PHY_NTC_INIT[] __devinitdata = {
+static struct reginit_item PHY_NTC_INIT[] __devinitdata = {
 	{ PHY_CLEARALL, 0x40 }, 
 	{ 0x12,  0x0001 },
 	{ 0x13,  0x7605 },
@@ -334,7 +334,7 @@
 #define func_exit()  fs_dprintk (FS_DEBUG_FLOW, "fs: exit  %s\n", __FUNCTION__)
 
 
-struct fs_dev *fs_boards = NULL;
+static struct fs_dev *fs_boards = NULL;
 
 #ifdef DEBUG
 
@@ -1921,7 +1921,7 @@
 	return -ENODEV;
 }
 
-void __devexit firestream_remove_one (struct pci_dev *pdev)
+static void __devexit firestream_remove_one (struct pci_dev *pdev)
 {
 	int i;
 	struct fs_dev *dev, *nxtdev;
diff -Nru a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c
--- a/drivers/atm/fore200e.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/atm/fore200e.c	2005-03-01 23:39:17 -08:00
@@ -39,6 +39,7 @@
 #include <linux/sonet.h>
 #include <linux/atm_suni.h>
 #include <linux/dma-mapping.h>
+#include <linux/delay.h>
 #include <asm/io.h>
 #include <asm/string.h>
 #include <asm/page.h>
@@ -1779,7 +1780,7 @@
 
 	    /* retry once again? */
 	    if (--retry > 0) {
-		schedule();
+		udelay(50);
 		goto retry_here;
 	    }
 
diff -Nru a/drivers/atm/he.c b/drivers/atm/he.c
--- a/drivers/atm/he.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/atm/he.c	2005-03-01 23:38:53 -08:00
@@ -86,44 +86,19 @@
 #undef USE_RBPL_POOL			/* if memory is tight try this */
 #define USE_TPD_POOL
 /* #undef CONFIG_ATM_HE_USE_SUNI */
-
-/* compatibility */
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,69)
-typedef void irqreturn_t;
-#define IRQ_NONE
-#define IRQ_HANDLED
-#define IRQ_RETVAL(x)
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,9)
-#define __devexit_p(func)		func
-#endif
-
-#ifndef MODULE_LICENSE
-#define MODULE_LICENSE(x)
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,3)
-#define pci_set_drvdata(pci_dev, data)	(pci_dev)->driver_data = (data)
-#define pci_get_drvdata(pci_dev)	(pci_dev)->driver_data
-#endif
+/* #undef HE_DEBUG */
 
 #include "he.h"
-
 #include "suni.h"
-
 #include <linux/atm_he.h>
 
 #define hprintk(fmt,args...)	printk(KERN_ERR DEV_LABEL "%d: " fmt, he_dev->number , ##args)
 
-#undef DEBUG
-#ifdef DEBUG
+#ifdef HE_DEBUG
 #define HPRINTK(fmt,args...)	printk(KERN_DEBUG DEV_LABEL "%d: " fmt, he_dev->number , ##args)
-#else
+#else /* !HE_DEBUG */
 #define HPRINTK(fmt,args...)	do { } while (0)
-#endif /* DEBUG */
-
+#endif /* HE_DEBUG */
 
 /* version definition */
 
@@ -147,14 +122,56 @@
 
 /* globals */
 
-struct he_dev *he_devs = NULL;
-static int disable64 = 0;
+static struct he_dev *he_devs;
+static int disable64;
 static short nvpibits = -1;
 static short nvcibits = -1;
 static short rx_skb_reserve = 16;
 static int irq_coalesce = 1;
 static int sdh = 0;
 
+/* Read from EEPROM = 0000 0011b */
+static unsigned int readtab[] = {
+	CS_HIGH | CLK_HIGH,
+	CS_LOW | CLK_LOW,
+	CLK_HIGH,               /* 0 */
+	CLK_LOW,
+	CLK_HIGH,               /* 0 */
+	CLK_LOW,
+	CLK_HIGH,               /* 0 */
+	CLK_LOW,
+	CLK_HIGH,               /* 0 */
+	CLK_LOW,
+	CLK_HIGH,               /* 0 */
+	CLK_LOW,
+	CLK_HIGH,               /* 0 */
+	CLK_LOW | SI_HIGH,
+	CLK_HIGH | SI_HIGH,     /* 1 */
+	CLK_LOW | SI_HIGH,
+	CLK_HIGH | SI_HIGH      /* 1 */
+};     
+ 
+/* Clock to read from/write to the EEPROM */
+static unsigned int clocktab[] = {
+	CLK_LOW,
+	CLK_HIGH,
+	CLK_LOW,
+	CLK_HIGH,
+	CLK_LOW,
+	CLK_HIGH,
+	CLK_LOW,
+	CLK_HIGH,
+	CLK_LOW,
+	CLK_HIGH,
+	CLK_LOW,
+	CLK_HIGH,
+	CLK_LOW,
+	CLK_HIGH,
+	CLK_LOW,
+	CLK_HIGH,
+	CLK_LOW
+};     
+
 static struct atmdev_ops he_ops =
 {
 	.open =		he_open,
@@ -2558,8 +2575,8 @@
 			udelay(250);
 		}
 
-		add_wait_queue(&he_vcc->rx_waitq, &wait);
 		set_current_state(TASK_UNINTERRUPTIBLE);
+		add_wait_queue(&he_vcc->rx_waitq, &wait);
 
 		he_writel_rsr0(he_dev, RSR0_CLOSE_CONN, cid);
 		(void) he_readl_rsr0(he_dev, cid);		/* flush posted writes */
@@ -2633,8 +2650,8 @@
 		tpd->vcc = vcc;
 		wmb();
 
-		add_wait_queue(&he_vcc->tx_waitq, &wait);
 		set_current_state(TASK_UNINTERRUPTIBLE);
+		add_wait_queue(&he_vcc->tx_waitq, &wait);
 		__enqueue_tpd(he_dev, tpd, cid);
 		spin_unlock_irqrestore(&he_dev->global_lock, flags);
 
diff -Nru a/drivers/atm/he.h b/drivers/atm/he.h
--- a/drivers/atm/he.h	2005-03-01 23:39:18 -08:00
+++ b/drivers/atm/he.h	2005-03-01 23:39:18 -08:00
@@ -892,47 +892,4 @@
 #define SI_HIGH		ID_DIN /* HOST_CNTL_ID_PROM_DATA_IN */
 #define EEPROM_DELAY	400 /* microseconds */
 
-/* Read from EEPROM = 0000 0011b */
-unsigned int readtab[] = {
-	CS_HIGH | CLK_HIGH,
-	CS_LOW | CLK_LOW,
-	CLK_HIGH,               /* 0 */
-	CLK_LOW,
-	CLK_HIGH,               /* 0 */
-	CLK_LOW,
-	CLK_HIGH,               /* 0 */
-	CLK_LOW,
-	CLK_HIGH,               /* 0 */
-	CLK_LOW,
-	CLK_HIGH,               /* 0 */
-	CLK_LOW,
-	CLK_HIGH,               /* 0 */
-	CLK_LOW | SI_HIGH,
-	CLK_HIGH | SI_HIGH,     /* 1 */
-	CLK_LOW | SI_HIGH,
-	CLK_HIGH | SI_HIGH      /* 1 */
-};     
- 
-/* Clock to read from/write to the EEPROM */
-unsigned int clocktab[] = {
-	CLK_LOW,
-	CLK_HIGH,
-	CLK_LOW,
-	CLK_HIGH,
-	CLK_LOW,
-	CLK_HIGH,
-	CLK_LOW,
-	CLK_HIGH,
-	CLK_LOW,
-	CLK_HIGH,
-	CLK_LOW,
-	CLK_HIGH,
-	CLK_LOW,
-	CLK_HIGH,
-	CLK_LOW,
-	CLK_HIGH,
-	CLK_LOW
-};     
-
-
 #endif /* _HE_H_ */
diff -Nru a/drivers/atm/horizon.c b/drivers/atm/horizon.c
--- a/drivers/atm/horizon.c	2005-03-01 23:38:44 -08:00
+++ b/drivers/atm/horizon.c	2005-03-01 23:38:44 -08:00
@@ -39,6 +39,7 @@
 #include <linux/uio.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
+#include <linux/wait.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
@@ -1089,13 +1090,11 @@
 /********** (queue to) become the next TX thread **********/
 
 static inline int tx_hold (hrz_dev * dev) {
-  while (test_and_set_bit (tx_busy, &dev->flags)) {
-    PRINTD (DBG_TX, "sleeping at tx lock %p %lu", dev, dev->flags);
-    interruptible_sleep_on (&dev->tx_queue);
-    PRINTD (DBG_TX, "woken at tx lock %p %lu", dev, dev->flags);
-    if (signal_pending (current))
-      return -1;
-  }
+  PRINTD (DBG_TX, "sleeping at tx lock %p %lu", dev, dev->flags);
+  wait_event_interruptible(dev->tx_queue, (!test_and_set_bit(tx_busy, &dev->flags)));
+  PRINTD (DBG_TX, "woken at tx lock %p %lu", dev, dev->flags);
+  if (signal_pending (current))
+    return -1;
   PRINTD (DBG_TX, "set tx_busy for dev %p", dev);
   return 0;
 }
@@ -2706,18 +2705,18 @@
 	// adapter slot free, read resources from PCI configuration space
 	u32 iobase = pci_resource_start (pci_dev, 0);
 	u32 * membase = bus_to_virt (pci_resource_start (pci_dev, 1));
-	u8 irq = pci_dev->irq;
+	unsigned int irq;
 	unsigned char lat;
 
 	PRINTD (DBG_FLOW, "hrz_probe");
 
-	/* XXX DEV_LABEL is a guess */
-	if (!request_region(iobase, HRZ_IO_EXTENT, DEV_LABEL))
+	if (pci_enable_device(pci_dev))
 		return -EINVAL;
 
-	if (pci_enable_device(pci_dev)) {
-		err = -EINVAL;
-		goto out_release;
+	/* XXX DEV_LABEL is a guess */
+	if (!request_region(iobase, HRZ_IO_EXTENT, DEV_LABEL)) {
+		return -EINVAL;
+		goto out_disable;
 	}
 
 	dev = kmalloc(sizeof(hrz_dev), GFP_KERNEL);
@@ -2725,7 +2724,7 @@
 		// perhaps we should be nice: deregister all adapters and abort?
 		PRINTD(DBG_ERR, "out of memory");
 		err = -ENOMEM;
-		goto out_disable;
+		goto out_release;
 	}
 
 	memset(dev, 0, sizeof(hrz_dev));
@@ -2733,6 +2732,7 @@
 	pci_set_drvdata(pci_dev, dev);
 
 	// grab IRQ and install handler - move this someplace more sensible
+	irq = pci_dev->irq;
 	if (request_irq(irq,
 			interrupt_handler,
 			SA_SHIRQ, /* irqflags guess */
@@ -2846,10 +2846,10 @@
 	free_irq(dev->irq, dev);
 out_free:
 	kfree(dev);
-out_disable:
-	pci_disable_device(pci_dev);
 out_release:
 	release_region(iobase, HRZ_IO_EXTENT);
+out_disable:
+	pci_disable_device(pci_dev);
 	goto out;
 }
 
diff -Nru a/drivers/atm/idt77105.c b/drivers/atm/idt77105.c
--- a/drivers/atm/idt77105.c	2005-03-01 23:38:59 -08:00
+++ b/drivers/atm/idt77105.c	2005-03-01 23:38:59 -08:00
@@ -39,7 +39,7 @@
         unsigned char old_mcr;          /* storage of MCR reg while signal lost */
 };
 
-static spinlock_t idt77105_priv_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(idt77105_priv_lock);
 
 #define PRIV(dev) ((struct idt77105_priv *) dev->phy_data)
 
@@ -323,7 +323,7 @@
 }
 
 
-int idt77105_stop(struct atm_dev *dev)
+static int idt77105_stop(struct atm_dev *dev)
 {
 	struct idt77105_priv *walk, *prev;
 
diff -Nru a/drivers/atm/idt77105.h b/drivers/atm/idt77105.h
--- a/drivers/atm/idt77105.h	2005-03-01 23:38:56 -08:00
+++ b/drivers/atm/idt77105.h	2005-03-01 23:38:56 -08:00
@@ -77,7 +77,6 @@
 
 #ifdef __KERNEL__
 int idt77105_init(struct atm_dev *dev) __init;
-int idt77105_stop(struct atm_dev *dev);
 #endif
 
 /*
diff -Nru a/drivers/atm/idt77252.c b/drivers/atm/idt77252.c
--- a/drivers/atm/idt77252.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/atm/idt77252.c	2005-03-01 23:38:57 -08:00
@@ -3136,14 +3136,11 @@
 		}
 	}
 
-	if (card->soft_tst)
-		vfree(card->soft_tst);
+	vfree(card->soft_tst);
 
-	if (card->scd2vc)
-		vfree(card->scd2vc);
+	vfree(card->scd2vc);
 
-	if (card->vcs)
-		vfree(card->vcs);
+	vfree(card->vcs);
 
 	if (card->raw_cell_hnd) {
 		pci_free_consistent(card->pcidev, 2 * sizeof(u32),
diff -Nru a/drivers/atm/idt77252.h b/drivers/atm/idt77252.h
--- a/drivers/atm/idt77252.h	2005-03-01 23:39:08 -08:00
+++ b/drivers/atm/idt77252.h	2005-03-01 23:39:08 -08:00
@@ -275,7 +275,7 @@
 	struct rsq_entry	*next;
 	struct rsq_entry	*last;
 	dma_addr_t		paddr;
-} rsq_info;
+};
 
 
 /*****************************************************************************/
diff -Nru a/drivers/atm/iphase.c b/drivers/atm/iphase.c
--- a/drivers/atm/iphase.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/atm/iphase.c	2005-03-01 23:39:16 -08:00
@@ -53,6 +53,7 @@
 #include <linux/delay.h>  
 #include <linux/uio.h>  
 #include <linux/init.h>  
+#include <linux/wait.h>
 #include <asm/system.h>  
 #include <asm/io.h>  
 #include <asm/atomic.h>  
@@ -72,13 +73,13 @@
 #define PRIV(dev) ((struct suni_priv *) dev->phy_data)
 
 static unsigned char ia_phy_get(struct atm_dev *dev, unsigned long addr);
+static void desc_dbg(IADEV *iadev);
 
 static IADEV *ia_dev[8];
 static struct atm_dev *_ia_dev[8];
 static int iadev_count;
 static void ia_led_timer(unsigned long arg);
 static struct timer_list ia_timer = TIMER_INITIALIZER(ia_led_timer, 0, 0);
-struct atm_vcc *vcc_close_que[100];
 static int IA_TX_BUF = DFL_TX_BUFFERS, IA_TX_BUF_SZ = DFL_TX_BUF_SZ;
 static int IA_RX_BUF = DFL_RX_BUFFERS, IA_RX_BUF_SZ = DFL_RX_BUF_SZ;
 static uint IADebugFlag = /* IF_IADBG_ERR | IF_IADBG_CBR| IF_IADBG_INIT_ADAPTER
@@ -147,7 +148,6 @@
   u_short 		desc1;
   u_short		tcq_wr;
   struct ia_vcc         *iavcc_r = NULL; 
-  extern void desc_dbg(IADEV *iadev);
 
   tcq_wr = readl(dev->seg_reg+TCQ_WR_PTR) & 0xffff;
   while (dev->host_tcq_wr != tcq_wr) {
@@ -187,7 +187,6 @@
   unsigned long delta;
   static unsigned long timer = 0;
   int ltimeout;
-  extern void desc_dbg(IADEV *iadev);
 
   ia_hack_tcq (dev);
   if(((jiffies - timer)>50)||((dev->ffL.tcq_rd==dev->host_tcq_wr))){      
@@ -644,7 +643,7 @@
    return 0;
 }
 
-void ia_tx_poll (IADEV *iadev) {
+static void ia_tx_poll (IADEV *iadev) {
    struct atm_vcc *vcc = NULL;
    struct sk_buff *skb = NULL, *skb1 = NULL;
    struct ia_vcc *iavcc;
@@ -861,7 +860,7 @@
   return;
 }
 
-void ia_mb25_init (IADEV *iadev)
+static void ia_mb25_init (IADEV *iadev)
 {
    volatile ia_mb25_t  *mb25 = (ia_mb25_t*)iadev->phy;
 #if 0
@@ -876,7 +875,7 @@
    return;
 }                   
 
-void ia_suni_pm7345_init (IADEV *iadev)
+static void ia_suni_pm7345_init (IADEV *iadev)
 {
    volatile suni_pm7345_t *suni_pm7345 = (suni_pm7345_t *)iadev->phy;
    if (iadev->phy_type & FE_DS3_PHY)
@@ -959,9 +958,8 @@
 
 /***************************** IA_LIB END *****************************/
     
-/* pwang_test debug utility */
-int tcnter = 0, rcnter = 0;
-void xdump( u_char*  cp, int  length, char*  prefix )
+static int tcnter = 0;
+static void xdump( u_char*  cp, int  length, char*  prefix )
 {
     int col, count;
     u_char prntBuf[120];
@@ -1008,7 +1006,7 @@
   
 /*-- some utilities and memory allocation stuff will come here -------------*/  
   
-void desc_dbg(IADEV *iadev) {
+static void desc_dbg(IADEV *iadev) {
 
   u_short tcq_wr_ptr, tcq_st_ptr, tcq_ed_ptr;
   u32 i;
@@ -2589,14 +2587,14 @@
 }  
   
 static void ia_close(struct atm_vcc *vcc)  
-{  
+{
+	DEFINE_WAIT(wait);
         u16 *vc_table;
         IADEV *iadev;
         struct ia_vcc *ia_vcc;
         struct sk_buff *skb = NULL;
         struct sk_buff_head tmp_tx_backlog, tmp_vcc_backlog;
         unsigned long closetime, flags;
-        int ctimeout;
 
         iadev = INPH_IA_DEV(vcc->dev);
         ia_vcc = INPH_IA_VCC(vcc);
@@ -2609,7 +2607,9 @@
         skb_queue_head_init (&tmp_vcc_backlog); 
         if (vcc->qos.txtp.traffic_class != ATM_NONE) {
            iadev->close_pending++;
-           sleep_on_timeout(&iadev->timeout_wait, 50);
+	   prepare_to_wait(&iadev->timeout_wait, &wait, TASK_UNINTERRUPTIBLE);
+	   schedule_timeout(50);
+	   finish_wait(&iadev->timeout_wait, &wait);
            spin_lock_irqsave(&iadev->tx_lock, flags); 
            while((skb = skb_dequeue(&iadev->tx_backlog))) {
               if (ATM_SKB(skb)->vcc == vcc){ 
@@ -2622,17 +2622,12 @@
            while((skb = skb_dequeue(&tmp_tx_backlog))) 
              skb_queue_tail(&iadev->tx_backlog, skb);
            IF_EVENT(printk("IA TX Done decs_cnt = %d\n", ia_vcc->vc_desc_cnt);) 
-           closetime = jiffies;
-           ctimeout = 300000 / ia_vcc->pcr;
-           if (ctimeout == 0)
-              ctimeout = 1;
-           while (ia_vcc->vc_desc_cnt > 0){
-              if ((jiffies - closetime) >= ctimeout) 
-                 break;
-              spin_unlock_irqrestore(&iadev->tx_lock, flags);
-              sleep_on(&iadev->close_wait);
-              spin_lock_irqsave(&iadev->tx_lock, flags);
-           }    
+           closetime = 300000 / ia_vcc->pcr;
+           if (closetime == 0)
+              closetime = 1;
+           spin_unlock_irqrestore(&iadev->tx_lock, flags);
+           wait_event_timeout(iadev->close_wait, (ia_vcc->vc_desc_cnt <= 0), closetime);
+           spin_lock_irqsave(&iadev->tx_lock, flags);
            iadev->close_pending--;
            iadev->testTable[vcc->vci]->lastTime = 0;
            iadev->testTable[vcc->vci]->fract = 0; 
diff -Nru a/drivers/atm/iphase.h b/drivers/atm/iphase.h
--- a/drivers/atm/iphase.h	2005-03-01 23:38:53 -08:00
+++ b/drivers/atm/iphase.h	2005-03-01 23:38:53 -08:00
@@ -1126,8 +1126,6 @@
 #define FE_DS3_PHY      0x0080          /* DS3 */
 #define FE_E3_PHY       0x0090          /* E3 */
 		     
-extern void ia_mb25_init (IADEV *);
-
 /*********************** SUNI_PM7345 PHY DEFINE HERE *********************/
 typedef struct _suni_pm7345_t
 {
@@ -1325,8 +1323,6 @@
 #define SUNI_DS3_COCAI  0x04            /* Corr. HCS errors detected    */
 #define SUNI_DS3_FOVRI  0x02            /* FIFO overrun                 */
 #define SUNI_DS3_FUDRI  0x01            /* FIFO underrun                */
-
-extern void ia_suni_pm7345_init (IADEV *iadev);
 
 ///////////////////SUNI_PM7345 PHY DEFINE END /////////////////////////////
 
diff -Nru a/drivers/atm/nicstar.c b/drivers/atm/nicstar.c
--- a/drivers/atm/nicstar.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/atm/nicstar.c	2005-03-01 23:38:53 -08:00
@@ -54,7 +54,6 @@
 #include <asm/uaccess.h>
 #include <asm/atomic.h>
 #include "nicstar.h"
-#include "nicstarmac.h"
 #ifdef CONFIG_ATM_NICSTAR_USE_SUNI
 #include "suni.h"
 #endif /* CONFIG_ATM_NICSTAR_USE_SUNI */
diff -Nru a/drivers/atm/nicstarmac.c b/drivers/atm/nicstarmac.c
--- a/drivers/atm/nicstarmac.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/atm/nicstarmac.c	2005-03-01 23:39:17 -08:00
@@ -7,6 +7,8 @@
  * Read this ForeRunner's MAC address from eprom/eeprom
  */
 
+typedef void __iomem *virt_addr_t;
+
 #define CYCLE_DELAY 5
 
 /* This was the original definition
@@ -35,6 +37,7 @@
 #define SI_LOW		0x0000		/* Serial input data low */
 
 /* Read Status Register = 0000 0101b */
+#if 0
 static u_int32_t rdsrtab[] =
 {
     CS_HIGH | CLK_HIGH, 
@@ -55,6 +58,7 @@
     CLK_LOW | SI_HIGH, 
     CLK_HIGH | SI_HIGH   /* 1 */
 };
+#endif  /*  0  */
 
 
 /* Read from EEPROM = 0000 0011b */
@@ -117,7 +121,7 @@
  * eeprom, then pull the result from bit 16 of the NicSTaR's General Purpose 
  * register.  
  */
-
+#if 0
 u_int32_t
 nicstar_read_eprom_status( virt_addr_t base )
 {
@@ -153,6 +157,7 @@
    osp_MicroDelay( CYCLE_DELAY );
    return rbyte;
 }
+#endif  /*  0  */
 
 
 /*
@@ -210,7 +215,7 @@
 }
 
 
-void
+static void
 nicstar_init_eprom( virt_addr_t base )
 {
     u_int32_t val;
@@ -243,7 +248,7 @@
  * above.
  */ 
 
-void
+static void
 nicstar_read_eprom(
     virt_addr_t	base,
     u_int8_t	prom_offset,
diff -Nru a/drivers/atm/nicstarmac.h b/drivers/atm/nicstarmac.h
--- a/drivers/atm/nicstarmac.h	2005-03-01 23:38:52 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,14 +0,0 @@
-/******************************************************************************
- *
- * nicstarmac.h
- *
- * Header file for nicstarmac.c
- *
- ******************************************************************************/
-
-
-typedef void __iomem *virt_addr_t;
-
-u_int32_t nicstar_read_eprom_status( virt_addr_t base );
-void nicstar_init_eprom( virt_addr_t base );
-void nicstar_read_eprom( virt_addr_t, u_int8_t, u_int8_t *, u_int32_t);
diff -Nru a/drivers/atm/suni.c b/drivers/atm/suni.c
--- a/drivers/atm/suni.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/atm/suni.c	2005-03-01 23:39:09 -08:00
@@ -48,7 +48,7 @@
 
 static struct timer_list poll_timer;
 static struct suni_priv *sunis = NULL;
-static spinlock_t sunis_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(sunis_lock);
 
 
 #define ADD_LIMITED(s,v) \
diff -Nru a/drivers/atm/zatm.c b/drivers/atm/zatm.c
--- a/drivers/atm/zatm.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/atm/zatm.c	2005-03-01 23:38:53 -08:00
@@ -22,6 +22,7 @@
 #include <linux/atm_zatm.h>
 #include <linux/capability.h>
 #include <linux/bitops.h>
+#include <linux/wait.h>
 #include <asm/byteorder.h>
 #include <asm/system.h>
 #include <asm/string.h>
@@ -867,31 +868,21 @@
 	struct zatm_vcc *zatm_vcc;
 	unsigned long flags;
 	int chan;
-struct sk_buff *skb;
-int once = 1;
 
 	zatm_vcc = ZATM_VCC(vcc);
 	zatm_dev = ZATM_DEV(vcc->dev);
 	chan = zatm_vcc->tx_chan;
 	if (!chan) return;
 	DPRINTK("close_tx\n");
-	while (skb_peek(&zatm_vcc->backlog)) {
-if (once) {
-printk("waiting for backlog to drain ...\n");
-event_dump();
-once = 0;
-}
-		sleep_on(&zatm_vcc->tx_wait);
-	}
-once = 1;
-	while ((skb = skb_peek(&zatm_vcc->tx_queue))) {
-if (once) {
-printk("waiting for TX queue to drain ... %p\n",skb);
-event_dump();
-once = 0;
-}
-		DPRINTK("waiting for TX queue to drain ... %p\n",skb);
-		sleep_on(&zatm_vcc->tx_wait);
+	if (skb_peek(&zatm_vcc->backlog)) {
+		printk("waiting for backlog to drain ...\n");
+		event_dump();
+		wait_event(zatm_vcc->tx_wait, !skb_peek(&zatm_vcc->backlog));
+	}
+	if (skb_peek(&zatm_vcc->tx_queue)) {
+		printk("waiting for TX queue to drain ...\n");
+		event_dump();
+		wait_event(zatm_vcc->tx_wait, !skb_peek(&zatm_vcc->tx_queue));
 	}
 	spin_lock_irqsave(&zatm_dev->lock, flags);
 #if 0
@@ -1605,7 +1596,7 @@
 		goto out_disable;
 
 	zatm_dev->pci_dev = pci_dev;
-	dev = (struct atm_dev *)zatm_dev;
+	dev->dev_data = zatm_dev;
 	zatm_dev->copper = (int)ent->driver_data;
 	if ((ret = zatm_init(dev)) || (ret = zatm_start(dev)))
 		goto out_release;
diff -Nru a/drivers/base/Kconfig b/drivers/base/Kconfig
--- a/drivers/base/Kconfig	2005-03-01 23:38:53 -08:00
+++ b/drivers/base/Kconfig	2005-03-01 23:38:53 -08:00
@@ -20,7 +20,7 @@
 
 config FW_LOADER
 	tristate "Hotplug firmware loading support"
-	depends on HOTPLUG
+	select HOTPLUG
 	---help---
 	  This option is provided for the case where no in-kernel-tree modules
 	  require hotplug firmware loading support, but a module built outside
diff -Nru a/drivers/base/Makefile b/drivers/base/Makefile
--- a/drivers/base/Makefile	2005-03-01 23:39:09 -08:00
+++ b/drivers/base/Makefile	2005-03-01 23:39:09 -08:00
@@ -2,7 +2,8 @@
 
 obj-y			:= core.o sys.o interface.o bus.o \
 			   driver.o class.o class_simple.o platform.o \
-			   cpu.o firmware.o init.o map.o dmapool.o
+			   cpu.o firmware.o init.o map.o dmapool.o \
+			   attribute_container.o transport_class.o
 obj-y			+= power/
 obj-$(CONFIG_FW_LOADER)	+= firmware_class.o
 obj-$(CONFIG_NUMA)	+= node.o
diff -Nru a/drivers/base/attribute_container.c b/drivers/base/attribute_container.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/base/attribute_container.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,376 @@
+/*
+ * attribute_container.c - implementation of a simple container for classes
+ *
+ * Copyright (c) 2005 - James Bottomley <James.Bottomley@steeleye.com>
+ *
+ * This file is licensed under GPLv2
+ *
+ * The basic idea here is to enable a device to be attached to an
+ * aritrary numer of classes without having to allocate storage for them.
+ * Instead, the contained classes select the devices they need to attach
+ * to via a matching function.
+ */
+
+#include <linux/attribute_container.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/list.h>
+#include <linux/module.h>
+
+/* This is a private structure used to tie the classdev and the
+ * container .. it should never be visible outside this file */
+struct internal_container {
+	struct list_head node;
+	struct attribute_container *cont;
+	struct class_device classdev;
+};
+
+/**
+ * attribute_container_classdev_to_container - given a classdev, return the container
+ *
+ * @classdev: the class device created by attribute_container_add_device.
+ *
+ * Returns the container associated with this classdev.
+ */
+struct attribute_container *
+attribute_container_classdev_to_container(struct class_device *classdev)
+{
+	struct internal_container *ic =
+		container_of(classdev, struct internal_container, classdev);
+	return ic->cont;
+}
+EXPORT_SYMBOL_GPL(attribute_container_classdev_to_container);
+
+static struct list_head attribute_container_list;
+
+static DECLARE_MUTEX(attribute_container_mutex);
+
+/**
+ * attribute_container_register - register an attribute container
+ *
+ * @cont: The container to register.  This must be allocated by the
+ *        callee and should also be zeroed by it.
+ */
+int
+attribute_container_register(struct attribute_container *cont)
+{
+	INIT_LIST_HEAD(&cont->node);
+	INIT_LIST_HEAD(&cont->containers);
+		
+	down(&attribute_container_mutex);
+	list_add_tail(&cont->node, &attribute_container_list);
+	up(&attribute_container_mutex);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(attribute_container_register);
+
+/**
+ * attribute_container_unregister - remove a container registration
+ *
+ * @cont: previously registered container to remove
+ */
+int
+attribute_container_unregister(struct attribute_container *cont)
+{
+	int retval = -EBUSY;
+	down(&attribute_container_mutex);
+	if (!list_empty(&cont->containers))
+		goto out;
+	retval = 0;
+	list_del(&cont->node);
+ out:
+	up(&attribute_container_mutex);
+	return retval;
+		
+}
+EXPORT_SYMBOL_GPL(attribute_container_unregister);
+
+/* private function used as class release */
+static void attribute_container_release(struct class_device *classdev)
+{
+	struct internal_container *ic 
+		= container_of(classdev, struct internal_container, classdev);
+	struct device *dev = classdev->dev;
+
+	kfree(ic);
+	put_device(dev);
+}
+
+/**
+ * attribute_container_add_device - see if any container is interested in dev
+ *
+ * @dev: device to add attributes to
+ * @fn:	 function to trigger addition of class device.
+ *
+ * This function allocates storage for the class device(s) to be
+ * attached to dev (one for each matching attribute_container).  If no
+ * fn is provided, the code will simply register the class device via
+ * class_device_add.  If a function is provided, it is expected to add
+ * the class device at the appropriate time.  One of the things that
+ * might be necessary is to allocate and initialise the classdev and
+ * then add it a later time.  To do this, call this routine for
+ * allocation and initialisation and then use
+ * attribute_container_device_trigger() to call class_device_add() on
+ * it.  Note: after this, the class device contains a reference to dev
+ * which is not relinquished until the release of the classdev.
+ */
+void
+attribute_container_add_device(struct device *dev,
+			       int (*fn)(struct attribute_container *,
+					 struct device *,
+					 struct class_device *))
+{
+	struct attribute_container *cont;
+
+	down(&attribute_container_mutex);
+	list_for_each_entry(cont, &attribute_container_list, node) {
+		struct internal_container *ic;
+
+		if (attribute_container_no_classdevs(cont))
+			continue;
+
+		if (!cont->match(cont, dev))
+			continue;
+		ic = kmalloc(sizeof(struct internal_container), GFP_KERNEL);
+		if (!ic) {
+			dev_printk(KERN_ERR, dev, "failed to allocate class container\n");
+			continue;
+		}
+		memset(ic, 0, sizeof(struct internal_container));
+		INIT_LIST_HEAD(&ic->node);
+		ic->cont = cont;
+		class_device_initialize(&ic->classdev);
+		ic->classdev.dev = get_device(dev);
+		ic->classdev.class = cont->class;
+		cont->class->release = attribute_container_release;
+		strcpy(ic->classdev.class_id, dev->bus_id);
+		if (fn)
+			fn(cont, dev, &ic->classdev);
+		else
+			attribute_container_add_class_device(&ic->classdev);
+		list_add_tail(&ic->node, &cont->containers);
+	}
+	up(&attribute_container_mutex);
+}
+
+/**
+ * attribute_container_remove_device - make device eligible for removal.
+ *
+ * @dev:  The generic device
+ * @fn:	  A function to call to remove the device
+ *
+ * This routine triggers device removal.  If fn is NULL, then it is
+ * simply done via class_device_unregister (note that if something
+ * still has a reference to the classdev, then the memory occupied
+ * will not be freed until the classdev is released).  If you want a
+ * two phase release: remove from visibility and then delete the
+ * device, then you should use this routine with a fn that calls
+ * class_device_del() and then use
+ * attribute_container_device_trigger() to do the final put on the
+ * classdev.
+ */
+void
+attribute_container_remove_device(struct device *dev,
+				  void (*fn)(struct attribute_container *,
+					     struct device *,
+					     struct class_device *))
+{
+	struct attribute_container *cont;
+
+	down(&attribute_container_mutex);
+	list_for_each_entry(cont, &attribute_container_list, node) {
+		struct internal_container *ic, *tmp;
+
+		if (attribute_container_no_classdevs(cont))
+			continue;
+
+		if (!cont->match(cont, dev))
+			continue;
+		list_for_each_entry_safe(ic, tmp, &cont->containers, node) {
+			if (dev != ic->classdev.dev)
+				continue;
+			list_del(&ic->node);
+			if (fn)
+				fn(cont, dev, &ic->classdev);
+			else {
+				attribute_container_remove_attrs(&ic->classdev);
+				class_device_unregister(&ic->classdev);
+			}
+		}
+	}
+	up(&attribute_container_mutex);
+}
+EXPORT_SYMBOL_GPL(attribute_container_remove_device);
+
+/**
+ * attribute_container_device_trigger - execute a trigger for each matching classdev
+ *
+ * @dev:  The generic device to run the trigger for
+ * @fn	  the function to execute for each classdev.
+ *
+ * This funcion is for executing a trigger when you need to know both
+ * the container and the classdev.  If you only care about the
+ * container, then use attribute_container_trigger() instead.
+ */
+void
+attribute_container_device_trigger(struct device *dev, 
+				   int (*fn)(struct attribute_container *,
+					     struct device *,
+					     struct class_device *))
+{
+	struct attribute_container *cont;
+
+	down(&attribute_container_mutex);
+	list_for_each_entry(cont, &attribute_container_list, node) {
+		struct internal_container *ic, *tmp;
+
+		if (!cont->match(cont, dev))
+			continue;
+
+		list_for_each_entry_safe(ic, tmp, &cont->containers, node) {
+			if (dev == ic->classdev.dev)
+				fn(cont, dev, &ic->classdev);
+		}
+	}
+	up(&attribute_container_mutex);
+}
+EXPORT_SYMBOL_GPL(attribute_container_device_trigger);
+
+/**
+ * attribute_container_trigger - trigger a function for each matching container
+ *
+ * @dev:  The generic device to activate the trigger for
+ * @fn:	  the function to trigger
+ *
+ * This routine triggers a function that only needs to know the
+ * matching containers (not the classdev) associated with a device.
+ * It is more lightweight than attribute_container_device_trigger, so
+ * should be used in preference unless the triggering function
+ * actually needs to know the classdev.
+ */
+void
+attribute_container_trigger(struct device *dev,
+			    int (*fn)(struct attribute_container *,
+				      struct device *))
+{
+	struct attribute_container *cont;
+
+	down(&attribute_container_mutex);
+	list_for_each_entry(cont, &attribute_container_list, node) {
+		if (cont->match(cont, dev))
+			fn(cont, dev);
+	}
+	up(&attribute_container_mutex);
+}
+EXPORT_SYMBOL_GPL(attribute_container_trigger);
+
+/**
+ * attribute_container_add_attrs - add attributes
+ *
+ * @classdev: The class device
+ *
+ * This simply creates all the class device sysfs files from the
+ * attributes listed in the container
+ */
+int
+attribute_container_add_attrs(struct class_device *classdev)
+{
+	struct attribute_container *cont =
+		attribute_container_classdev_to_container(classdev);
+	struct class_device_attribute **attrs =	cont->attrs;
+	int i, error;
+
+	if (!attrs)
+		return 0;
+
+	for (i = 0; attrs[i]; i++) {
+		error = class_device_create_file(classdev, attrs[i]);
+		if (error)
+			return error;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(attribute_container_add_attrs);
+
+/**
+ * attribute_container_add_class_device - same function as class_device_add
+ *
+ * @classdev:	the class device to add
+ *
+ * This performs essentially the same function as class_device_add except for
+ * attribute containers, namely add the classdev to the system and then
+ * create the attribute files
+ */
+int
+attribute_container_add_class_device(struct class_device *classdev)
+{
+	int error = class_device_add(classdev);
+	if (error)
+		return error;
+	return attribute_container_add_attrs(classdev);
+}
+EXPORT_SYMBOL_GPL(attribute_container_add_class_device);
+
+/**
+ * attribute_container_add_class_device_adapter - simple adapter for triggers
+ *
+ * This function is identical to attribute_container_add_class_device except
+ * that it is designed to be called from the triggers
+ */
+int
+attribute_container_add_class_device_adapter(struct attribute_container *cont,
+					     struct device *dev,
+					     struct class_device *classdev)
+{
+	return attribute_container_add_class_device(classdev);
+}
+EXPORT_SYMBOL_GPL(attribute_container_add_class_device_adapter);
+
+/**
+ * attribute_container_remove_attrs - remove any attribute files
+ *
+ * @classdev: The class device to remove the files from
+ *
+ */
+void
+attribute_container_remove_attrs(struct class_device *classdev)
+{
+	struct attribute_container *cont =
+		attribute_container_classdev_to_container(classdev);
+	struct class_device_attribute **attrs =	cont->attrs;
+	int i;
+
+	if (!attrs)
+		return;
+
+	for (i = 0; attrs[i]; i++)
+		class_device_remove_file(classdev, attrs[i]);
+}
+EXPORT_SYMBOL_GPL(attribute_container_remove_attrs);
+
+/**
+ * attribute_container_class_device_del - equivalent of class_device_del
+ *
+ * @classdev: the class device
+ *
+ * This function simply removes all the attribute files and then calls
+ * class_device_del.
+ */
+void
+attribute_container_class_device_del(struct class_device *classdev)
+{
+	attribute_container_remove_attrs(classdev);
+	class_device_del(classdev);
+}
+EXPORT_SYMBOL_GPL(attribute_container_class_device_del);
+
+int __init
+attribute_container_init(void)
+{
+	INIT_LIST_HEAD(&attribute_container_list);
+	return 0;
+}
diff -Nru a/drivers/base/bus.c b/drivers/base/bus.c
--- a/drivers/base/bus.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/base/bus.c	2005-03-01 23:38:54 -08:00
@@ -326,7 +326,7 @@
 			if (!error)
 				/* success, driver matched */
 				return 1;
-			if (error != -ENODEV)
+			if (error != -ENODEV && error != -ENXIO)
 				/* driver matched but the probe failed */
 				printk(KERN_WARNING
 				    "%s: probe of %s failed with error %d\n",
diff -Nru a/drivers/base/class.c b/drivers/base/class.c
--- a/drivers/base/class.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/base/class.c	2005-03-01 23:39:17 -08:00
@@ -179,6 +179,22 @@
 		sysfs_remove_file(&class_dev->kobj, &attr->attr);
 }
 
+int class_device_create_bin_file(struct class_device *class_dev,
+				 struct bin_attribute *attr)
+{
+	int error = -EINVAL;
+	if (class_dev)
+		error = sysfs_create_bin_file(&class_dev->kobj, attr);
+	return error;
+}
+
+void class_device_remove_bin_file(struct class_device *class_dev,
+				  struct bin_attribute *attr)
+{
+	if (class_dev)
+		sysfs_remove_bin_file(&class_dev->kobj, attr);
+}
+
 static int class_device_dev_link(struct class_device * class_dev)
 {
 	if (class_dev->dev)
@@ -576,6 +592,8 @@
 EXPORT_SYMBOL_GPL(class_device_put);
 EXPORT_SYMBOL_GPL(class_device_create_file);
 EXPORT_SYMBOL_GPL(class_device_remove_file);
+EXPORT_SYMBOL_GPL(class_device_create_bin_file);
+EXPORT_SYMBOL_GPL(class_device_remove_bin_file);
 
 EXPORT_SYMBOL_GPL(class_interface_register);
 EXPORT_SYMBOL_GPL(class_interface_unregister);
diff -Nru a/drivers/base/class_simple.c b/drivers/base/class_simple.c
--- a/drivers/base/class_simple.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/base/class_simple.c	2005-03-01 23:38:56 -08:00
@@ -27,7 +27,7 @@
 #define to_simple_dev(d) container_of(d, struct simple_dev, class_dev)
 
 static LIST_HEAD(simple_dev_list);
-static spinlock_t simple_dev_list_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(simple_dev_list_lock);
 
 static void release_simple_dev(struct class_device *class_dev)
 {
diff -Nru a/drivers/base/cpu.c b/drivers/base/cpu.c
--- a/drivers/base/cpu.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/base/cpu.c	2005-03-01 23:38:54 -08:00
@@ -48,10 +48,22 @@
 }
 static SYSDEV_ATTR(online, 0600, show_online, store_online);
 
-static void __init register_cpu_control(struct cpu *cpu)
+static void __devinit register_cpu_control(struct cpu *cpu)
 {
 	sysdev_create_file(&cpu->sysdev, &attr_online);
 }
+void unregister_cpu(struct cpu *cpu, struct node *root)
+{
+
+	if (root)
+		sysfs_remove_link(&root->sysdev.kobj,
+				  kobject_name(&cpu->sysdev.kobj));
+	sysdev_remove_file(&cpu->sysdev, &attr_online);
+
+	sysdev_unregister(&cpu->sysdev);
+
+	return;
+}
 #else /* ... !CONFIG_HOTPLUG_CPU */
 static inline void register_cpu_control(struct cpu *cpu)
 {
@@ -66,7 +78,7 @@
  *
  * Initialize and register the CPU device.
  */
-int __init register_cpu(struct cpu *cpu, int num, struct node *root)
+int __devinit register_cpu(struct cpu *cpu, int num, struct node *root)
 {
 	int error;
 
diff -Nru a/drivers/base/init.c b/drivers/base/init.c
--- a/drivers/base/init.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/base/init.c	2005-03-01 23:38:52 -08:00
@@ -17,7 +17,7 @@
 extern int platform_bus_init(void);
 extern int system_bus_init(void);
 extern int cpu_dev_init(void);
-
+extern int attribute_container_init(void);
 /**
  *	driver_init - initialize driver model.
  *
@@ -39,4 +39,5 @@
 	platform_bus_init();
 	system_bus_init();
 	cpu_dev_init();
+	attribute_container_init();
 }
diff -Nru a/drivers/base/node.c b/drivers/base/node.c
--- a/drivers/base/node.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/base/node.c	2005-03-01 23:38:53 -08:00
@@ -10,6 +10,7 @@
 #include <linux/hugetlb.h>
 #include <linux/cpumask.h>
 #include <linux/topology.h>
+#include <linux/nodemask.h>
 
 static struct sysdev_class node_class = {
 	set_kset_name("node"),
@@ -23,7 +24,7 @@
 	int len;
 
 	/* 2004/06/03: buf currently PAGE_SIZE, need > 1 char per 4 bits. */
-	BUILD_BUG_ON(NR_CPUS/4 > PAGE_SIZE/2);
+	BUILD_BUG_ON(MAX_NUMNODES/4 > PAGE_SIZE/2);
 
 	len = cpumask_scnprintf(buf, PAGE_SIZE-1, mask);
 	len += sprintf(buf + len, "\n");
@@ -111,6 +112,24 @@
 }
 static SYSDEV_ATTR(numastat, S_IRUGO, node_read_numastat, NULL);
 
+static ssize_t node_read_distance(struct sys_device * dev, char * buf)
+{
+	int nid = dev->id;
+	int len = 0;
+	int i;
+
+	/* buf currently PAGE_SIZE, need ~4 chars per node */
+	BUILD_BUG_ON(MAX_NUMNODES*4 > PAGE_SIZE/2);
+
+	for_each_online_node(i)
+		len += sprintf(buf + len, "%s%d", i ? " " : "", node_distance(nid, i));
+
+	len += sprintf(buf + len, "\n");
+	return len;
+}
+static SYSDEV_ATTR(distance, S_IRUGO, node_read_distance, NULL);
+
+
 /*
  * register_node - Setup a driverfs device for a node.
  * @num - Node number to use when creating the device.
@@ -129,6 +148,7 @@
 		sysdev_create_file(&node->sysdev, &attr_cpumap);
 		sysdev_create_file(&node->sysdev, &attr_meminfo);
 		sysdev_create_file(&node->sysdev, &attr_numastat);
+		sysdev_create_file(&node->sysdev, &attr_distance);
 	}
 	return error;
 }
diff -Nru a/drivers/base/platform.c b/drivers/base/platform.c
--- a/drivers/base/platform.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/base/platform.c	2005-03-01 23:38:52 -08:00
@@ -58,6 +58,41 @@
 }
 
 /**
+ *	platform_get_resource_byname - get a resource for a device by name
+ *	@dev: platform device
+ *	@type: resource type
+ *	@name: resource name
+ */
+struct resource *
+platform_get_resource_byname(struct platform_device *dev, unsigned int type,
+		      char *name)
+{
+	int i;
+
+	for (i = 0; i < dev->num_resources; i++) {
+		struct resource *r = &dev->resource[i];
+
+		if ((r->flags & (IORESOURCE_IO|IORESOURCE_MEM|
+				 IORESOURCE_IRQ|IORESOURCE_DMA)) == type)
+			if (!strcmp(r->name, name))
+				return r;
+	}
+	return NULL;
+}
+
+/**
+ *	platform_get_irq - get an IRQ for a device
+ *	@dev: platform device
+ *	@name: IRQ name
+ */
+int platform_get_irq_byname(struct platform_device *dev, char *name)
+{
+	struct resource *r = platform_get_resource_byname(dev, IORESOURCE_IRQ, name);
+
+	return r ? r->start : 0;
+}
+
+/**
  *	platform_add_devices - add a numbers of platform devices
  *	@devs: array of platform devices to add
  *	@num: number of platform devices in array
@@ -103,13 +138,16 @@
 	for (i = 0; i < pdev->num_resources; i++) {
 		struct resource *p, *r = &pdev->resource[i];
 
-		r->name = pdev->dev.bus_id;
+		if (r->name == NULL)
+			r->name = pdev->dev.bus_id;
 
-		p = NULL;
-		if (r->flags & IORESOURCE_MEM)
-			p = &iomem_resource;
-		else if (r->flags & IORESOURCE_IO)
-			p = &ioport_resource;
+		p = r->parent;
+		if (!p) {
+			if (r->flags & IORESOURCE_MEM)
+				p = &iomem_resource;
+			else if (r->flags & IORESOURCE_IO)
+				p = &ioport_resource;
+		}
 
 		if (p && request_resource(p, r)) {
 			printk(KERN_ERR
@@ -238,7 +276,7 @@
 	return (strncmp(pdev->name, drv->name, BUS_ID_SIZE) == 0);
 }
 
-static int platform_suspend(struct device * dev, u32 state)
+static int platform_suspend(struct device * dev, pm_message_t state)
 {
 	int ret = 0;
 
@@ -308,3 +346,5 @@
 EXPORT_SYMBOL_GPL(platform_device_unregister);
 EXPORT_SYMBOL_GPL(platform_get_irq);
 EXPORT_SYMBOL_GPL(platform_get_resource);
+EXPORT_SYMBOL_GPL(platform_get_irq_byname);
+EXPORT_SYMBOL_GPL(platform_get_resource_byname);
diff -Nru a/drivers/base/power/power.h b/drivers/base/power/power.h
--- a/drivers/base/power/power.h	2005-03-01 23:39:18 -08:00
+++ b/drivers/base/power/power.h	2005-03-01 23:39:18 -08:00
@@ -71,14 +71,14 @@
 /*
  * suspend.c
  */
-extern int suspend_device(struct device *, u32);
+extern int suspend_device(struct device *, pm_message_t);
 
 
 /*
  * runtime.c
  */
 
-extern int dpm_runtime_suspend(struct device *, u32);
+extern int dpm_runtime_suspend(struct device *, pm_message_t);
 extern void dpm_runtime_resume(struct device *);
 
 #else /* CONFIG_PM */
@@ -93,7 +93,7 @@
 
 }
 
-static inline int dpm_runtime_suspend(struct device * dev, u32 state)
+static inline int dpm_runtime_suspend(struct device * dev, pm_message_t state)
 {
 	return 0;
 }
diff -Nru a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
--- a/drivers/base/power/runtime.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/base/power/runtime.c	2005-03-01 23:39:08 -08:00
@@ -44,7 +44,7 @@
  *	@state:	State to enter.
  */
 
-int dpm_runtime_suspend(struct device * dev, u32 state)
+int dpm_runtime_suspend(struct device * dev, pm_message_t state)
 {
 	int error = 0;
 
@@ -73,7 +73,7 @@
  *	always be able to tell, but we need accurate information to
  *	work reliably.
  */
-void dpm_set_power_state(struct device * dev, u32 state)
+void dpm_set_power_state(struct device * dev, pm_message_t state)
 {
 	down(&dpm_sem);
 	dev->power.power_state = state;
diff -Nru a/drivers/base/power/suspend.c b/drivers/base/power/suspend.c
--- a/drivers/base/power/suspend.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/base/power/suspend.c	2005-03-01 23:39:09 -08:00
@@ -11,7 +11,7 @@
 #include <linux/device.h>
 #include "power.h"
 
-extern int sysdev_suspend(u32 state);
+extern int sysdev_suspend(pm_message_t state);
 
 /*
  * The entries in the dpm_active list are in a depth first order, simply
@@ -35,7 +35,7 @@
  *	@state:	Power state device is entering.
  */
 
-int suspend_device(struct device * dev, u32 state)
+int suspend_device(struct device * dev, pm_message_t state)
 {
 	int error = 0;
 
@@ -65,7 +65,7 @@
  *
  */
 
-int device_suspend(u32 state)
+int device_suspend(pm_message_t state)
 {
 	int error = 0;
 
@@ -118,7 +118,7 @@
  *	done, power down system devices.
  */
 
-int device_power_down(u32 state)
+int device_power_down(pm_message_t state)
 {
 	int error = 0;
 	struct device * dev;
diff -Nru a/drivers/base/transport_class.c b/drivers/base/transport_class.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/base/transport_class.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,257 @@
+/*
+ * transport_class.c - implementation of generic transport classes
+ *                     using attribute_containers
+ *
+ * Copyright (c) 2005 - James Bottomley <James.Bottomley@steeleye.com>
+ *
+ * This file is licensed under GPLv2
+ *
+ * The basic idea here is to allow any "device controller" (which
+ * would most often be a Host Bus Adapter" to use the services of one
+ * or more tranport classes for performing transport specific
+ * services.  Transport specific services are things that the generic
+ * command layer doesn't want to know about (speed settings, line
+ * condidtioning, etc), but which the user might be interested in.
+ * Thus, the HBA's use the routines exported by the transport classes
+ * to perform these functions.  The transport classes export certain
+ * values to the user via sysfs using attribute containers.
+ *
+ * Note: because not every HBA will care about every transport
+ * attribute, there's a many to one relationship that goes like this:
+ *
+ * transport class<-----attribute container<----class device
+ *
+ * Usually the attribute container is per-HBA, but the design doesn't
+ * mandate that.  Although most of the services will be specific to
+ * the actual external storage connection used by the HBA, the generic
+ * transport class is framed entirely in terms of generic devices to
+ * allow it to be used by any physical HBA in the system.
+ */
+#include <linux/attribute_container.h>
+#include <linux/transport_class.h>
+
+/**
+ * transport_class_register - register an initial transport class
+ *
+ * @tclass:	a pointer to the transport class structure to be initialised
+ *
+ * The transport class contains an embedded class which is used to
+ * identify it.  The caller should initialise this structure with
+ * zeros and then generic class must have been initialised with the
+ * actual transport class unique name.  There's a macro
+ * DECLARE_TRANSPORT_CLASS() to do this (declared classes still must
+ * be registered).
+ *
+ * Returns 0 on success or error on failure.
+ */
+int transport_class_register(struct transport_class *tclass)
+{
+	return class_register(&tclass->class);
+}
+EXPORT_SYMBOL_GPL(transport_class_register);
+
+/**
+ * transport_class_unregister - unregister a previously registered class
+ *
+ * @tclass: The transport class to unregister
+ *
+ * Must be called prior to deallocating the memory for the transport
+ * class.
+ */
+void transport_class_unregister(struct transport_class *tclass)
+{
+	class_unregister(&tclass->class);
+}
+EXPORT_SYMBOL_GPL(transport_class_unregister);
+
+static int anon_transport_dummy_function(struct device *dev)
+{
+	/* do nothing */
+	return 0;
+}
+
+/**
+ * anon_transport_class_register - register an anonymous class
+ *
+ * @atc: The anon transport class to register
+ *
+ * The anonymous transport class contains both a transport class and a
+ * container.  The idea of an anonymous class is that it never
+ * actually has any device attributes associated with it (and thus
+ * saves on container storage).  So it can only be used for triggering
+ * events.  Use prezero and then use DECLARE_ANON_TRANSPORT_CLASS() to
+ * initialise the anon transport class storage.
+ */
+int anon_transport_class_register(struct anon_transport_class *atc)
+{
+	int error;
+	atc->container.class = &atc->tclass.class;
+	attribute_container_set_no_classdevs(&atc->container);
+	error = attribute_container_register(&atc->container);
+	if (error)
+		return error;
+	atc->tclass.setup = anon_transport_dummy_function;
+	atc->tclass.remove = anon_transport_dummy_function;
+	return 0;
+}
+EXPORT_SYMBOL_GPL(anon_transport_class_register);
+
+/**
+ * anon_transport_class_unregister - unregister an anon class
+ *
+ * @atc: Pointer to the anon transport class to unregister
+ *
+ * Must be called prior to deallocating the memory for the anon
+ * transport class.
+ */
+void anon_transport_class_unregister(struct anon_transport_class *atc)
+{
+	attribute_container_unregister(&atc->container);
+}
+EXPORT_SYMBOL_GPL(anon_transport_class_unregister);
+
+static int transport_setup_classdev(struct attribute_container *cont,
+				    struct device *dev,
+				    struct class_device *classdev)
+{
+	struct transport_class *tclass = class_to_transport_class(cont->class);
+
+	if (tclass->setup)
+		tclass->setup(dev);
+
+	return 0;
+}
+
+/**
+ * transport_setup_device - declare a new dev for transport class association
+ *			    but don't make it visible yet.
+ *
+ * @dev: the generic device representing the entity being added
+ *
+ * Usually, dev represents some component in the HBA system (either
+ * the HBA itself or a device remote across the HBA bus).  This
+ * routine is simply a trigger point to see if any set of transport
+ * classes wishes to associate with the added device.  This allocates
+ * storage for the class device and initialises it, but does not yet
+ * add it to the system or add attributes to it (you do this with
+ * transport_add_device).  If you have no need for a separate setup
+ * and add operations, use transport_register_device (see
+ * transport_class.h).
+ */
+
+void transport_setup_device(struct device *dev)
+{
+	attribute_container_add_device(dev, transport_setup_classdev);
+}
+EXPORT_SYMBOL_GPL(transport_setup_device);
+
+
+/**
+ * transport_add_device - declare a new dev for transport class association
+ *
+ * @dev: the generic device representing the entity being added
+ *
+ * Usually, dev represents some component in the HBA system (either
+ * the HBA itself or a device remote across the HBA bus).  This
+ * routine is simply a trigger point used to add the device to the
+ * system and register attributes for it.
+ */
+
+void transport_add_device(struct device *dev)
+{
+	attribute_container_device_trigger(dev,
+			   attribute_container_add_class_device_adapter);
+}
+EXPORT_SYMBOL_GPL(transport_add_device);
+
+static int transport_configure(struct attribute_container *cont,
+			       struct device *dev)
+{
+	struct transport_class *tclass = class_to_transport_class(cont->class);
+
+	if (tclass->configure)
+		tclass->configure(dev);
+
+	return 0;
+}
+
+/**
+ * transport_configure_device - configure an already set up device
+ *
+ * @dev: generic device representing device to be configured
+ *
+ * The idea of configure is simply to provide a point within the setup
+ * process to allow the transport class to extract information from a
+ * device after it has been setup.  This is used in SCSI because we
+ * have to have a setup device to begin using the HBA, but after we
+ * send the initial inquiry, we use configure to extract the device
+ * parameters.  The device need not have been added to be configured.
+ */
+void transport_configure_device(struct device *dev)
+{
+	attribute_container_trigger(dev, transport_configure);
+}
+EXPORT_SYMBOL_GPL(transport_configure_device);
+
+static int transport_remove_classdev(struct attribute_container *cont,
+				     struct device *dev,
+				     struct class_device *classdev)
+{
+	struct transport_class *tclass = class_to_transport_class(cont->class);
+
+	if (tclass->remove)
+		tclass->remove(dev);
+
+	if (tclass->remove != anon_transport_dummy_function)
+		attribute_container_class_device_del(classdev);
+
+	return 0;
+}
+
+
+/**
+ * transport_remove_device - remove the visibility of a device
+ *
+ * @dev: generic device to remove
+ *
+ * This call removes the visibility of the device (to the user from
+ * sysfs), but does not destroy it.  To eliminate a device entirely
+ * you must also call transport_destroy_device.  If you don't need to
+ * do remove and destroy as separate operations, use
+ * transport_unregister_device() (see transport_class.h) which will
+ * perform both calls for you.
+ */
+void transport_remove_device(struct device *dev)
+{
+	attribute_container_device_trigger(dev, transport_remove_classdev);
+}
+EXPORT_SYMBOL_GPL(transport_remove_device);
+
+static void transport_destroy_classdev(struct attribute_container *cont,
+				      struct device *dev,
+				      struct class_device *classdev)
+{
+	struct transport_class *tclass = class_to_transport_class(cont->class);
+
+	if (tclass->remove != anon_transport_dummy_function)
+		class_device_put(classdev);
+}
+
+
+/**
+ * transport_destroy_device - destroy a removed device
+ *
+ * @dev: device to eliminate from the transport class.
+ *
+ * This call triggers the elimination of storage associated with the
+ * transport classdev.  Note: all it really does is relinquish a
+ * reference to the classdev.  The memory will not be freed until the
+ * last reference goes to zero.  Note also that the classdev retains a
+ * reference count on dev, so dev too will remain for as long as the
+ * transport class device remains around.
+ */
+void transport_destroy_device(struct device *dev)
+{
+	attribute_container_remove_device(dev, transport_destroy_classdev);
+}
+EXPORT_SYMBOL_GPL(transport_destroy_device);
diff -Nru a/drivers/block/DAC960.c b/drivers/block/DAC960.c
--- a/drivers/block/DAC960.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/block/DAC960.c	2005-03-01 23:39:08 -08:00
@@ -2738,7 +2738,7 @@
   }
   init_waitqueue_head(&Controller->CommandWaitQueue);
   init_waitqueue_head(&Controller->HealthStatusWaitQueue);
-  Controller->queue_lock = SPIN_LOCK_UNLOCKED; 
+  spin_lock_init(&Controller->queue_lock);
   DAC960_AnnounceDriver(Controller);
   /*
     Map the Controller Register Window.
diff -Nru a/drivers/block/Kconfig b/drivers/block/Kconfig
--- a/drivers/block/Kconfig	2005-03-01 23:38:53 -08:00
+++ b/drivers/block/Kconfig	2005-03-01 23:38:53 -08:00
@@ -6,7 +6,7 @@
 
 config BLK_DEV_FD
 	tristate "Normal floppy disk support"
-	depends on (!ARCH_S390 && !M68K && !IA64) || Q40 || (SUN3X && BROKEN)
+	depends on (!ARCH_S390 && !M68K && !IA64 && !USERMODE) || Q40 || (SUN3X && BROKEN)
 	---help---
 	  If you want to use the floppy disk drive(s) of your PC under Linux,
 	  say Y. Information about this driver, especially important for IBM
@@ -170,7 +170,7 @@
 	help
 	  When enabled (Y), this option allows SCSI tape drives and SCSI medium
 	  changers (tape robots) to be accessed via a Compaq 5xxx array 
-	  controller.  (See Documentation/cciss.txt for more details.)
+	  controller.  (See <file:Documentation/cciss.txt> for more details.)
 
 	  "SCSI support" and "SCSI tape support" must also be enabled for this 
 	  option to work.
@@ -196,7 +196,7 @@
 	---help---
 	  Saying Y here will include support for the MM5415 family of
 	  battery backed (Non-volatile) RAM cards.
-	  http://www.umem.com/
+	  <http://www.umem.com/>
 
 	  The cards appear as block devices that can be partitioned into
 	  as many as 15 partitions.
@@ -208,6 +208,56 @@
 	  one is chosen dynamically.  Use "devfs" or look in /proc/devices
 	  for the device number
 
+config BLK_DEV_UBD
+	bool "Virtual block device"
+	depends on USERMODE
+	---help---
+          The User-Mode Linux port includes a driver called UBD which will let
+          you access arbitrary files on the host computer as block devices.
+          Unless you know that you do not need such virtual block devices say
+          Y here.
+
+config BLK_DEV_UBD_SYNC
+	bool "Always do synchronous disk IO for UBD"
+	depends on BLK_DEV_UBD
+	---help---
+	  Writes to the virtual block device are not immediately written to the
+	  host's disk; this may cause problems if, for example, the User-Mode
+	  Linux 'Virtual Machine' uses a journalling filesystem and the host
+	  computer crashes.
+
+          Synchronous operation (i.e. always writing data to the host's disk
+          immediately) is configurable on a per-UBD basis by using a special
+          kernel command line option.  Alternatively, you can say Y here to
+          turn on synchronous operation by default for all block devices.
+
+          If you're running a journalling file system (like reiserfs, for
+          example) in your virtual machine, you will want to say Y here.  If
+          you care for the safety of the data in your virtual machine, Y is a
+          wise choice too.  In all other cases (for example, if you're just
+          playing around with User-Mode Linux) you can choose N.
+
+config BLK_DEV_COW_COMMON
+	bool
+	default BLK_DEV_UBD
+
+config MMAPPER
+	tristate "Example IO memory driver (BROKEN)"
+	depends on USERMODE && BROKEN
+	---help---
+          The User-Mode Linux port can provide support for IO Memory
+          emulation with this option.  This allows a host file to be
+          specified as an I/O region on the kernel command line. That file
+          will be mapped into UML's kernel address space where a driver can
+          locate it and do whatever it wants with the memory, including
+          providing an interface to it for UML processes to use.
+
+          For more information, see
+          <http://user-mode-linux.sourceforge.net/iomem.html>.
+
+          If you'd like to be able to provide a simulated IO port space for
+          User-Mode Linux processes, say Y.  If unsure, say N.
+
 config BLK_DEV_LOOP
 	tristate "Loopback device support"
 	---help---
@@ -359,34 +409,53 @@
 	  for details.
 
 config INITRAMFS_SOURCE
-	string "Source directory of cpio_list"
+	string "Initramfs source file(s)"
 	default ""
 	help
-	  This can be set to either a directory containing files, etc to be
-	  included in the initramfs archive, or a file containing newline
-	  separated entries.
-
-	  If it is a file, it should be in the following format:
-	    # a comment
-	    file <name> <location> <mode> <uid> <gid>
-	    dir <name> <mode> <uid> <gid>
-	    nod <name> <mode> <uid> <gid> <dev_type> <maj> <min>
-
-	  Where:
-	    <name>      name of the file/dir/nod in the archive
-	    <location>  location of the file in the current filesystem
-	    <mode>      mode/permissions of the file
-	    <uid>       user id (0=root)
-	    <gid>       group id (0=root)
-	    <dev_type>  device type (b=block, c=character)
-	    <maj>       major number of nod
-	    <min>       minor number of nod
+	  This can be either a single cpio archive with a .cpio suffix or a
+	  space-separated list of directories and files for building the
+	  initramfs image.  A cpio archive should contain a filesystem archive
+	  to be used as an initramfs image.  Directories should contain a
+	  filesystem layout to be included in the initramfs image.  Files
+	  should contain entries according to the format described by the
+	  "usr/gen_init_cpio" program in the kernel tree.
+
+	  When multiple directories and files are specified then the
+	  initramfs image will be the aggregate of all of them.
+
+	  See <file:Documentation/early-userspace/README for more details.
 
 	  If you are not sure, leave it blank.
 
+config INITRAMFS_ROOT_UID
+	int "User ID to map to 0 (user root)"
+	depends on INITRAMFS_SOURCE!=""
+	default "0"
+	help
+	  This setting is only meaningful if the INITRAMFS_SOURCE is
+	  contains a directory.  Setting this user ID (UID) to something
+	  other than "0" will cause all files owned by that UID to be
+	  owned by user root in the initial ramdisk image.
+
+	  If you are not sure, leave it set to "0".
+
+config INITRAMFS_ROOT_GID
+	int "Group ID to map to 0 (group root)"
+	depends on INITRAMFS_SOURCE!=""
+	default "0"
+	help
+	  This setting is only meaningful if the INITRAMFS_SOURCE is
+	  contains a directory.  Setting this group ID (GID) to something
+	  other than "0" will cause all files owned by that GID to be
+	  owned by group root in the initial ramdisk image.
+
+	  If you are not sure, leave it set to "0".
+
+#XXX - it makes sense to enable this only for 32-bit subarch's, not for x86_64
+#for instance.
 config LBD
 	bool "Support for Large Block Devices"
-	depends on X86 || MIPS32 || PPC32 || ARCH_S390_31 || SUPERH
+	depends on X86 || MIPS32 || PPC32 || ARCH_S390_31 || SUPERH || USERMODE
 	help
 	  Say Y here if you want to attach large (bigger than 2TB) discs to
 	  your machine, or if you want to have a raid or loopback device
@@ -394,6 +463,7 @@
 
 config CDROM_PKTCDVD
 	tristate "Packet writing on CD/DVD media"
+	depends on !USERMODE
 	help
 	  If you have a CDROM drive that supports packet writing, say Y to
 	  include preliminary support. It should work with any MMC/Mt Fuji
@@ -428,5 +498,12 @@
 source "drivers/s390/block/Kconfig"
 
 source "drivers/block/Kconfig.iosched"
+
+config ATA_OVER_ETH
+	tristate "ATA over Ethernet support"
+	depends on NET
+	help
+	This driver provides Support for ATA over Ethernet block
+	devices like the Coraid EtherDrive (R) Storage Blade.
 
 endmenu
diff -Nru a/drivers/block/acsi.c b/drivers/block/acsi.c
--- a/drivers/block/acsi.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/block/acsi.c	2005-03-01 23:39:17 -08:00
@@ -250,7 +250,7 @@
 static int				CurrentNSect;
 static char				*CurrentBuffer;
 
-static spinlock_t			acsi_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(acsi_lock);
 
 
 #define SET_TIMER()	mod_timer(&acsi_timer, jiffies + ACSI_TIMEOUT)
diff -Nru a/drivers/block/amiflop.c b/drivers/block/amiflop.c
--- a/drivers/block/amiflop.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/block/amiflop.c	2005-03-01 23:38:57 -08:00
@@ -163,7 +163,7 @@
 static int writefromint;
 static char *raw_buf;
 
-static spinlock_t amiflop_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(amiflop_lock);
 
 #define RAW_BUF_SIZE 30000  /* size of raw disk data */
 
diff -Nru a/drivers/block/aoe/Makefile b/drivers/block/aoe/Makefile
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/block/aoe/Makefile	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,6 @@
+#
+# Makefile for ATA over Ethernet
+#
+
+obj-$(CONFIG_ATA_OVER_ETH)	+= aoe.o
+aoe-objs := aoeblk.o aoechr.o aoecmd.o aoedev.o aoemain.o aoenet.o
diff -Nru a/drivers/block/aoe/aoe.h b/drivers/block/aoe/aoe.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/block/aoe/aoe.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,166 @@
+/* Copyright (c) 2004 Coraid, Inc.  See COPYING for GPL terms. */
+#define VERSION "5"
+#define AOE_MAJOR 152
+#define DEVICE_NAME "aoe"
+#ifndef AOE_PARTITIONS
+#define AOE_PARTITIONS 16
+#endif
+#define SYSMINOR(aoemajor, aoeminor) ((aoemajor) * 10 + (aoeminor))
+#define AOEMAJOR(sysminor) ((sysminor) / 10)
+#define AOEMINOR(sysminor) ((sysminor) % 10)
+#define WHITESPACE " \t\v\f\n"
+
+enum {
+	AOECMD_ATA,
+	AOECMD_CFG,
+
+	AOEFL_RSP = (1<<3),
+	AOEFL_ERR = (1<<2),
+
+	AOEAFL_EXT = (1<<6),
+	AOEAFL_DEV = (1<<4),
+	AOEAFL_ASYNC = (1<<1),
+	AOEAFL_WRITE = (1<<0),
+
+	AOECCMD_READ = 0,
+	AOECCMD_TEST,
+	AOECCMD_PTEST,
+	AOECCMD_SET,
+	AOECCMD_FSET,
+
+	AOE_HVER = 0x10,
+};
+
+struct aoe_hdr {
+	unsigned char dst[6];
+	unsigned char src[6];
+	unsigned char type[2];
+	unsigned char verfl;
+	unsigned char err;
+	unsigned char major[2];
+	unsigned char minor;
+	unsigned char cmd;
+	unsigned char tag[4];
+};
+
+struct aoe_atahdr {
+	unsigned char aflags;
+	unsigned char errfeat;
+	unsigned char scnt;
+	unsigned char cmdstat;
+	unsigned char lba0;
+	unsigned char lba1;
+	unsigned char lba2;
+	unsigned char lba3;
+	unsigned char lba4;
+	unsigned char lba5;
+	unsigned char res[2];
+};
+
+struct aoe_cfghdr {
+	unsigned char bufcnt[2];
+	unsigned char fwver[2];
+	unsigned char res;
+	unsigned char aoeccmd;
+	unsigned char cslen[2];
+};
+
+enum {
+	DEVFL_UP = 1,	/* device is installed in system and ready for AoE->ATA commands */
+	DEVFL_TKILL = (1<<1),	/* flag for timer to know when to kill self */
+	DEVFL_EXT = (1<<2),	/* device accepts lba48 commands */
+	DEVFL_CLOSEWAIT = (1<<3), /* device is waiting for all closes to revalidate */
+	DEVFL_WC_UPDATE = (1<<4), /* this device needs to update write cache status */
+	DEVFL_WORKON = (1<<4),
+
+	BUFFL_FAIL = 1,
+};
+
+enum {
+	MAXATADATA = 1024,
+	NPERSHELF = 10,
+	FREETAG = -1,
+	MIN_BUFS = 8,
+};
+
+struct buf {
+	struct list_head bufs;
+	ulong flags;
+	ulong nframesout;
+	char *bufaddr;
+	ulong resid;
+	ulong bv_resid;
+	sector_t sector;
+	struct bio *bio;
+	struct bio_vec *bv;
+};
+
+struct frame {
+	int tag;
+	ulong waited;
+	struct buf *buf;
+	char *bufaddr;
+	int writedatalen;
+	int ndata;
+
+	/* largest possible */
+	unsigned char data[sizeof(struct aoe_hdr) + sizeof(struct aoe_atahdr)];
+};
+
+struct aoedev {
+	struct aoedev *next;
+	unsigned char addr[6];	/* remote mac addr */
+	ushort flags;
+	ulong sysminor;
+	ulong aoemajor;
+	ulong aoeminor;
+	ulong nopen;		/* (bd_openers isn't available without sleeping) */
+	ulong rttavg;		/* round trip average of requests/responses */
+	u16 fw_ver;		/* version of blade's firmware */
+	struct work_struct work;/* disk create work struct */
+	struct gendisk *gd;
+	request_queue_t blkq;
+	struct hd_geometry geo; 
+	sector_t ssize;
+	struct timer_list timer;
+	spinlock_t lock;
+	struct net_device *ifp;	/* interface ed is attached to */
+	struct sk_buff *skblist;/* packets needing to be sent */
+	mempool_t *bufpool;	/* for deadlock-free Buf allocation */
+	struct list_head bufq;	/* queue of bios to work on */
+	struct buf *inprocess;	/* the one we're currently working on */
+	ulong lasttag;		/* last tag sent */
+	ulong nframes;		/* number of frames below */
+	struct frame *frames;
+};
+
+
+int aoeblk_init(void);
+void aoeblk_exit(void);
+void aoeblk_gdalloc(void *);
+void aoedisk_rm_sysfs(struct aoedev *d);
+
+int aoechr_init(void);
+void aoechr_exit(void);
+void aoechr_error(char *);
+void aoechr_hdump(char *, int len);
+
+void aoecmd_work(struct aoedev *d);
+void aoecmd_cfg(ushort, unsigned char);
+void aoecmd_ata_rsp(struct sk_buff *);
+void aoecmd_cfg_rsp(struct sk_buff *);
+
+int aoedev_init(void);
+void aoedev_exit(void);
+struct aoedev *aoedev_bymac(unsigned char *);
+void aoedev_downdev(struct aoedev *d);
+struct aoedev *aoedev_set(ulong, unsigned char *, struct net_device *, ulong);
+int aoedev_busy(void);
+
+int aoenet_init(void);
+void aoenet_exit(void);
+void aoenet_xmit(struct sk_buff *);
+int is_aoe_netif(struct net_device *ifp);
+int set_aoe_iflist(const char __user *str, size_t size);
+
+u64 mac_addr(char addr[6]);
diff -Nru a/drivers/block/aoe/aoeblk.c b/drivers/block/aoe/aoeblk.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/block/aoe/aoeblk.c	2005-03-01 23:39:26 -08:00
@@ -0,0 +1,265 @@
+/* Copyright (c) 2004 Coraid, Inc.  See COPYING for GPL terms. */
+/*
+ * aoeblk.c
+ * block device routines
+ */
+
+#include <linux/hdreg.h>
+#include <linux/blkdev.h>
+#include <linux/fs.h>
+#include <linux/ioctl.h>
+#include <linux/genhd.h>
+#include <linux/netdevice.h>
+#include "aoe.h"
+
+static kmem_cache_t *buf_pool_cache;
+
+/* add attributes for our block devices in sysfs */
+static ssize_t aoedisk_show_state(struct gendisk * disk, char *page)
+{
+	struct aoedev *d = disk->private_data;
+
+	return snprintf(page, PAGE_SIZE,
+			"%s%s\n",
+			(d->flags & DEVFL_UP) ? "up" : "down",
+			(d->flags & DEVFL_CLOSEWAIT) ? ",closewait" : "");
+}
+static ssize_t aoedisk_show_mac(struct gendisk * disk, char *page)
+{
+	struct aoedev *d = disk->private_data;
+
+	return snprintf(page, PAGE_SIZE, "%012llx\n", mac_addr(d->addr));
+}
+static ssize_t aoedisk_show_netif(struct gendisk * disk, char *page)
+{
+	struct aoedev *d = disk->private_data;
+
+	return snprintf(page, PAGE_SIZE, "%s\n", d->ifp->name);
+}
+
+static struct disk_attribute disk_attr_state = {
+	.attr = {.name = "state", .mode = S_IRUGO },
+	.show = aoedisk_show_state
+};
+static struct disk_attribute disk_attr_mac = {
+	.attr = {.name = "mac", .mode = S_IRUGO },
+	.show = aoedisk_show_mac
+};
+static struct disk_attribute disk_attr_netif = {
+	.attr = {.name = "netif", .mode = S_IRUGO },
+	.show = aoedisk_show_netif
+};
+
+static void
+aoedisk_add_sysfs(struct aoedev *d)
+{
+	sysfs_create_file(&d->gd->kobj, &disk_attr_state.attr);
+	sysfs_create_file(&d->gd->kobj, &disk_attr_mac.attr);
+	sysfs_create_file(&d->gd->kobj, &disk_attr_netif.attr);
+}
+void
+aoedisk_rm_sysfs(struct aoedev *d)
+{
+	sysfs_remove_link(&d->gd->kobj, "state");
+	sysfs_remove_link(&d->gd->kobj, "mac");
+	sysfs_remove_link(&d->gd->kobj, "netif");
+}
+
+static int
+aoeblk_open(struct inode *inode, struct file *filp)
+{
+	struct aoedev *d;
+	ulong flags;
+
+	d = inode->i_bdev->bd_disk->private_data;
+
+	spin_lock_irqsave(&d->lock, flags);
+	if (d->flags & DEVFL_UP) {
+		d->nopen++;
+		spin_unlock_irqrestore(&d->lock, flags);
+		return 0;
+	}
+	spin_unlock_irqrestore(&d->lock, flags);
+	return -ENODEV;
+}
+
+static int
+aoeblk_release(struct inode *inode, struct file *filp)
+{
+	struct aoedev *d;
+	ulong flags;
+
+	d = inode->i_bdev->bd_disk->private_data;
+
+	spin_lock_irqsave(&d->lock, flags);
+
+	if (--d->nopen == 0 && (d->flags & DEVFL_CLOSEWAIT)) {
+		d->flags &= ~DEVFL_CLOSEWAIT;
+		spin_unlock_irqrestore(&d->lock, flags);
+		aoecmd_cfg(d->aoemajor, d->aoeminor);
+		return 0;
+	}
+	spin_unlock_irqrestore(&d->lock, flags);
+
+	return 0;
+}
+
+static int
+aoeblk_make_request(request_queue_t *q, struct bio *bio)
+{
+	struct aoedev *d;
+	struct buf *buf;
+	struct sk_buff *sl;
+	ulong flags;
+
+	blk_queue_bounce(q, &bio);
+
+	d = bio->bi_bdev->bd_disk->private_data;
+	buf = mempool_alloc(d->bufpool, GFP_NOIO);
+	if (buf == NULL) {
+		printk(KERN_INFO "aoe: aoeblk_make_request: buf allocation "
+			"failure\n");
+		bio_endio(bio, bio->bi_size, -ENOMEM);
+		return 0;
+	}
+	memset(buf, 0, sizeof(*buf));
+	INIT_LIST_HEAD(&buf->bufs);
+	buf->bio = bio;
+	buf->resid = bio->bi_size;
+	buf->sector = bio->bi_sector;
+	buf->bv = buf->bio->bi_io_vec;
+	buf->bv_resid = buf->bv->bv_len;
+	buf->bufaddr = page_address(buf->bv->bv_page) + buf->bv->bv_offset;
+
+	spin_lock_irqsave(&d->lock, flags);
+
+	if ((d->flags & DEVFL_UP) == 0) {
+		printk(KERN_INFO "aoe: aoeblk_make_request: device %ld.%ld is not up\n",
+			d->aoemajor, d->aoeminor);
+		spin_unlock_irqrestore(&d->lock, flags);
+		mempool_free(buf, d->bufpool);
+		bio_endio(bio, bio->bi_size, -ENXIO);
+		return 0;
+	}
+
+	list_add_tail(&buf->bufs, &d->bufq);
+	aoecmd_work(d);
+
+	sl = d->skblist;
+	d->skblist = NULL;
+
+	spin_unlock_irqrestore(&d->lock, flags);
+
+	aoenet_xmit(sl);
+	return 0;
+}
+
+/* This ioctl implementation expects userland to have the device node
+ * permissions set so that only priviledged users can open an aoe
+ * block device directly.
+ */
+static int
+aoeblk_ioctl(struct inode *inode, struct file *filp, uint cmd, ulong arg)
+{
+	struct aoedev *d;
+
+	if (!arg)
+		return -EINVAL;
+
+	d = inode->i_bdev->bd_disk->private_data;
+	if ((d->flags & DEVFL_UP) == 0) {
+		printk(KERN_ERR "aoe: aoeblk_ioctl: disk not up\n");
+		return -ENODEV;
+	}
+
+	if (cmd == HDIO_GETGEO) {
+		d->geo.start = get_start_sect(inode->i_bdev);
+		if (!copy_to_user((void __user *) arg, &d->geo, sizeof d->geo))
+			return 0;
+		return -EFAULT;
+	}
+	printk(KERN_INFO "aoe: aoeblk_ioctl: unknown ioctl %d\n", cmd);
+	return -EINVAL;
+}
+
+static struct block_device_operations aoe_bdops = {
+	.open = aoeblk_open,
+	.release = aoeblk_release,
+	.ioctl = aoeblk_ioctl,
+	.owner = THIS_MODULE,
+};
+
+/* alloc_disk and add_disk can sleep */
+void
+aoeblk_gdalloc(void *vp)
+{
+	struct aoedev *d = vp;
+	struct gendisk *gd;
+	ulong flags;
+
+	gd = alloc_disk(AOE_PARTITIONS);
+	if (gd == NULL) {
+		printk(KERN_ERR "aoe: aoeblk_gdalloc: cannot allocate disk "
+			"structure for %ld.%ld\n", d->aoemajor, d->aoeminor);
+		spin_lock_irqsave(&d->lock, flags);
+		d->flags &= ~DEVFL_WORKON;
+		spin_unlock_irqrestore(&d->lock, flags);
+		return;
+	}
+
+	d->bufpool = mempool_create(MIN_BUFS,
+				    mempool_alloc_slab, mempool_free_slab,
+				    buf_pool_cache);
+	if (d->bufpool == NULL) {
+		printk(KERN_ERR "aoe: aoeblk_gdalloc: cannot allocate bufpool "
+			"for %ld.%ld\n", d->aoemajor, d->aoeminor);
+		put_disk(gd);
+		spin_lock_irqsave(&d->lock, flags);
+		d->flags &= ~DEVFL_WORKON;
+		spin_unlock_irqrestore(&d->lock, flags);
+		return;
+	}
+
+	spin_lock_irqsave(&d->lock, flags);
+	blk_queue_make_request(&d->blkq, aoeblk_make_request);
+	gd->major = AOE_MAJOR;
+	gd->first_minor = d->sysminor * AOE_PARTITIONS;
+	gd->fops = &aoe_bdops;
+	gd->private_data = d;
+	gd->capacity = d->ssize;
+	snprintf(gd->disk_name, sizeof gd->disk_name, "etherd/e%ld.%ld",
+		d->aoemajor, d->aoeminor);
+
+	gd->queue = &d->blkq;
+	d->gd = gd;
+	d->flags &= ~DEVFL_WORKON;
+	d->flags |= DEVFL_UP;
+
+	spin_unlock_irqrestore(&d->lock, flags);
+
+	add_disk(gd);
+	aoedisk_add_sysfs(d);
+	
+	printk(KERN_INFO "aoe: %012llx e%lu.%lu v%04x has %llu "
+		"sectors\n", mac_addr(d->addr), d->aoemajor, d->aoeminor,
+		d->fw_ver, (long long)d->ssize);
+}
+
+void
+aoeblk_exit(void)
+{
+	kmem_cache_destroy(buf_pool_cache);
+}
+
+int __init
+aoeblk_init(void)
+{
+	buf_pool_cache = kmem_cache_create("aoe_bufs", 
+					   sizeof(struct buf),
+					   0, 0, NULL, NULL);
+	if (buf_pool_cache == NULL)
+		return -ENOMEM;
+
+	return 0;
+}
+
diff -Nru a/drivers/block/aoe/aoechr.c b/drivers/block/aoe/aoechr.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/block/aoe/aoechr.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,279 @@
+/* Copyright (c) 2004 Coraid, Inc.  See COPYING for GPL terms. */
+/*
+ * aoechr.c
+ * AoE character device driver
+ */
+
+#include <linux/hdreg.h>
+#include <linux/blkdev.h>
+#include "aoe.h"
+
+enum {
+	//MINOR_STAT = 1, (moved to sysfs)
+	MINOR_ERR = 2,
+	MINOR_DISCOVER,
+	MINOR_INTERFACES,
+	MSGSZ = 2048,
+	NARGS = 10,
+	NMSG = 100,		/* message backlog to retain */
+};
+
+struct aoe_chardev {
+	ulong minor;
+	char name[32];
+};
+
+enum { EMFL_VALID = 1 };
+
+struct ErrMsg {
+	short flags;
+	short len;
+	char *msg;
+};
+
+static struct ErrMsg emsgs[NMSG];
+static int emsgs_head_idx, emsgs_tail_idx;
+static struct semaphore emsgs_sema;
+static spinlock_t emsgs_lock;
+static int nblocked_emsgs_readers;
+static struct class_simple *aoe_class;
+static struct aoe_chardev chardevs[] = {
+	{ MINOR_ERR, "err" },
+	{ MINOR_DISCOVER, "discover" },
+	{ MINOR_INTERFACES, "interfaces" },
+};
+
+static int
+discover(void)
+{
+	aoecmd_cfg(0xffff, 0xff);
+	return 0;
+}
+
+static int
+interfaces(const char __user *str, size_t size)
+{
+	if (set_aoe_iflist(str, size)) {
+		printk(KERN_CRIT
+		       "%s: could not set interface list: %s\n",
+		       __FUNCTION__, "too many interfaces");
+		return -EINVAL;
+	}
+	return 0;
+}
+
+void
+aoechr_error(char *msg)
+{
+	struct ErrMsg *em;
+	char *mp;
+	ulong flags, n;
+
+	n = strlen(msg);
+
+	spin_lock_irqsave(&emsgs_lock, flags);
+
+	em = emsgs + emsgs_tail_idx;
+	if ((em->flags & EMFL_VALID)) {
+bail:		spin_unlock_irqrestore(&emsgs_lock, flags);
+		return;
+	}
+
+	mp = kmalloc(n, GFP_ATOMIC);
+	if (mp == NULL) {
+		printk(KERN_CRIT "aoe: aoechr_error: allocation failure, len=%ld\n", n);
+		goto bail;
+	}
+
+	memcpy(mp, msg, n);
+	em->msg = mp;
+	em->flags |= EMFL_VALID;
+	em->len = n;
+
+	emsgs_tail_idx++;
+	emsgs_tail_idx %= ARRAY_SIZE(emsgs);
+
+	spin_unlock_irqrestore(&emsgs_lock, flags);
+
+	if (nblocked_emsgs_readers)
+		up(&emsgs_sema);
+}
+
+#define PERLINE 16
+void
+aoechr_hdump(char *buf, int n)
+{
+	int bufsiz;
+	char *fbuf;
+	int linelen;
+	char *p, *e, *fp;
+
+	bufsiz = n * 3;			/* 2 hex digits and a space */
+	bufsiz += n / PERLINE + 1;	/* the newline characters */
+	bufsiz += 1;			/* the final '\0' */
+
+	fbuf = kmalloc(bufsiz, GFP_ATOMIC);
+	if (!fbuf) {
+		printk(KERN_INFO
+		       "%s: cannot allocate memory\n",
+		       __FUNCTION__);
+		return;
+	}
+	
+	for (p = buf; n <= 0;) {
+		linelen = n > PERLINE ? PERLINE : n;
+		n -= linelen;
+
+		fp = fbuf;
+		for (e=p+linelen; p<e; p++)
+			fp += sprintf(fp, "%2.2X ", *p & 255);
+		sprintf(fp, "\n");
+		aoechr_error(fbuf);
+	}
+
+	kfree(fbuf);
+}
+
+static ssize_t
+aoechr_write(struct file *filp, const char __user *buf, size_t cnt, loff_t *offp)
+{
+	int ret = -EINVAL;
+
+	switch ((unsigned long) filp->private_data) {
+	default:
+		printk(KERN_INFO "aoe: aoechr_write: can't write to that file.\n");
+		break;
+	case MINOR_DISCOVER:
+		ret = discover();
+		break;
+	case MINOR_INTERFACES:
+		ret = interfaces(buf, cnt);
+		break;
+	}
+	if (ret == 0)
+		ret = cnt;
+	return ret;
+}
+
+static int
+aoechr_open(struct inode *inode, struct file *filp)
+{
+	int n, i;
+
+	n = MINOR(inode->i_rdev);
+	filp->private_data = (void *) (unsigned long) n;
+
+	for (i = 0; i < ARRAY_SIZE(chardevs); ++i)
+		if (chardevs[i].minor == n)
+			return 0;
+	return -EINVAL;
+}
+
+static int
+aoechr_rel(struct inode *inode, struct file *filp)
+{
+	return 0;
+}
+
+static ssize_t
+aoechr_read(struct file *filp, char __user *buf, size_t cnt, loff_t *off)
+{
+	int n;
+	char *mp;
+	struct ErrMsg *em;
+	ssize_t len;
+	ulong flags;
+
+	n = (int) filp->private_data;
+	switch (n) {
+	case MINOR_ERR:
+		spin_lock_irqsave(&emsgs_lock, flags);
+loop:
+		em = emsgs + emsgs_head_idx;
+		if ((em->flags & EMFL_VALID) == 0) {
+			if (filp->f_flags & O_NDELAY) {
+				spin_unlock_irqrestore(&emsgs_lock, flags);
+				return -EAGAIN;
+			}
+			nblocked_emsgs_readers++;
+
+			spin_unlock_irqrestore(&emsgs_lock, flags);
+
+			n = down_interruptible(&emsgs_sema);
+
+			spin_lock_irqsave(&emsgs_lock, flags);
+
+			nblocked_emsgs_readers--;
+
+			if (n) {
+				spin_unlock_irqrestore(&emsgs_lock, flags);
+				return -ERESTARTSYS;
+			}
+			goto loop;
+		}
+		if (em->len > cnt) {
+			spin_unlock_irqrestore(&emsgs_lock, flags);
+			return -EAGAIN;
+		}
+		mp = em->msg;
+		len = em->len;
+		em->msg = NULL;
+		em->flags &= ~EMFL_VALID;
+
+		emsgs_head_idx++;
+		emsgs_head_idx %= ARRAY_SIZE(emsgs);
+
+		spin_unlock_irqrestore(&emsgs_lock, flags);
+
+		n = copy_to_user(buf, mp, len);
+		kfree(mp);
+		return n == 0 ? len : -EFAULT;
+	default:
+		return -EFAULT;
+	}
+}
+
+struct file_operations aoe_fops = {
+	.write = aoechr_write,
+	.read = aoechr_read,
+	.open = aoechr_open,
+	.release = aoechr_rel,
+	.owner = THIS_MODULE,
+};
+
+int __init
+aoechr_init(void)
+{
+	int n, i;
+
+	n = register_chrdev(AOE_MAJOR, "aoechr", &aoe_fops);
+	if (n < 0) { 
+		printk(KERN_ERR "aoe: aoechr_init: can't register char device\n");
+		return n;
+	}
+	sema_init(&emsgs_sema, 0);
+	spin_lock_init(&emsgs_lock);
+	aoe_class = class_simple_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,
+					MKDEV(AOE_MAJOR, chardevs[i].minor),
+					NULL, chardevs[i].name);
+
+	return 0;
+}
+
+void
+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);
+	unregister_chrdev(AOE_MAJOR, "aoechr");
+}
+
diff -Nru a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/block/aoe/aoecmd.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,627 @@
+/* Copyright (c) 2004 Coraid, Inc.  See COPYING for GPL terms. */
+/*
+ * aoecmd.c
+ * Filesystem request handling methods
+ */
+
+#include <linux/hdreg.h>
+#include <linux/blkdev.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include "aoe.h"
+
+#define TIMERTICK (HZ / 10)
+#define MINTIMER (2 * TIMERTICK)
+#define MAXTIMER (HZ << 1)
+#define MAXWAIT (60 * 3)	/* After MAXWAIT seconds, give up and fail dev */
+
+static struct sk_buff *
+new_skb(struct net_device *if_dev, ulong len)
+{
+	struct sk_buff *skb;
+
+	skb = alloc_skb(len, GFP_ATOMIC);
+	if (skb) {
+		skb->nh.raw = skb->mac.raw = skb->data;
+		skb->dev = if_dev;
+		skb->protocol = __constant_htons(ETH_P_AOE);
+		skb->priority = 0;
+		skb_put(skb, len);
+		skb->next = skb->prev = NULL;
+
+		/* tell the network layer not to perform IP checksums
+		 * or to get the NIC to do it
+		 */
+		skb->ip_summed = CHECKSUM_NONE;
+	}
+	return skb;
+}
+
+static struct sk_buff *
+skb_prepare(struct aoedev *d, struct frame *f)
+{
+	struct sk_buff *skb;
+	char *p;
+
+	skb = new_skb(d->ifp, f->ndata + f->writedatalen);
+	if (!skb) {
+		printk(KERN_INFO "aoe: skb_prepare: failure to allocate skb\n");
+		return NULL;
+	}
+
+	p = skb->mac.raw;
+	memcpy(p, f->data, f->ndata);
+
+	if (f->writedatalen) {
+		p += sizeof(struct aoe_hdr) + sizeof(struct aoe_atahdr);
+		memcpy(p, f->bufaddr, f->writedatalen);
+	}
+
+	return skb;
+}
+
+static struct frame *
+getframe(struct aoedev *d, int tag)
+{
+	struct frame *f, *e;
+
+	f = d->frames;
+	e = f + d->nframes;
+	for (; f<e; f++)
+		if (f->tag == tag)
+			return f;
+	return NULL;
+}
+
+/*
+ * Leave the top bit clear so we have tagspace for userland.
+ * The bottom 16 bits are the xmit tick for rexmit/rttavg processing.
+ * This driver reserves tag -1 to mean "unused frame."
+ */
+static int
+newtag(struct aoedev *d)
+{
+	register ulong n;
+
+	n = jiffies & 0xffff;
+	return n |= (++d->lasttag & 0x7fff) << 16;
+}
+
+static int
+aoehdr_atainit(struct aoedev *d, struct aoe_hdr *h)
+{
+	u16 type = __constant_cpu_to_be16(ETH_P_AOE);
+	u16 aoemajor = __cpu_to_be16(d->aoemajor);
+	u32 host_tag = newtag(d);
+	u32 tag = __cpu_to_be32(host_tag);
+
+	memcpy(h->src, d->ifp->dev_addr, sizeof h->src);
+	memcpy(h->dst, d->addr, sizeof h->dst);
+	memcpy(h->type, &type, sizeof type);
+	h->verfl = AOE_HVER;
+	memcpy(h->major, &aoemajor, sizeof aoemajor);
+	h->minor = d->aoeminor;
+	h->cmd = AOECMD_ATA;
+	memcpy(h->tag, &tag, sizeof tag);
+
+	return host_tag;
+}
+
+static void
+aoecmd_ata_rw(struct aoedev *d, struct frame *f)
+{
+	struct aoe_hdr *h;
+	struct aoe_atahdr *ah;
+	struct buf *buf;
+	struct sk_buff *skb;
+	ulong bcnt;
+	register sector_t sector;
+	char writebit, extbit;
+
+	writebit = 0x10;
+	extbit = 0x4;
+
+	buf = d->inprocess;
+
+	sector = buf->sector;
+	bcnt = buf->bv_resid;
+	if (bcnt > MAXATADATA)
+		bcnt = MAXATADATA;
+
+	/* initialize the headers & frame */
+	h = (struct aoe_hdr *) f->data;
+	ah = (struct aoe_atahdr *) (h+1);
+	f->ndata = sizeof *h + sizeof *ah;
+	memset(h, 0, f->ndata);
+	f->tag = aoehdr_atainit(d, h);
+	f->waited = 0;
+	f->buf = buf;
+	f->bufaddr = buf->bufaddr;
+
+	/* set up ata header */
+	ah->scnt = bcnt >> 9;
+	ah->lba0 = sector;
+	ah->lba1 = sector >>= 8;
+	ah->lba2 = sector >>= 8;
+	ah->lba3 = sector >>= 8;
+	if (d->flags & DEVFL_EXT) {
+		ah->aflags |= AOEAFL_EXT;
+		ah->lba4 = sector >>= 8;
+		ah->lba5 = sector >>= 8;
+	} else {
+		extbit = 0;
+		ah->lba3 &= 0x0f;
+		ah->lba3 |= 0xe0;	/* LBA bit + obsolete 0xa0 */
+	}
+
+	if (bio_data_dir(buf->bio) == WRITE) {
+		ah->aflags |= AOEAFL_WRITE;
+		f->writedatalen = bcnt;
+	} else {
+		writebit = 0;
+		f->writedatalen = 0;
+	}
+
+	ah->cmdstat = WIN_READ | writebit | extbit;
+
+	/* mark all tracking fields and load out */
+	buf->nframesout += 1;
+	buf->bufaddr += bcnt;
+	buf->bv_resid -= bcnt;
+/* printk(KERN_INFO "aoe: bv_resid=%ld\n", buf->bv_resid); */
+	buf->resid -= bcnt;
+	buf->sector += bcnt >> 9;
+	if (buf->resid == 0) {
+		d->inprocess = NULL;
+	} else if (buf->bv_resid == 0) {
+		buf->bv++;
+		buf->bv_resid = buf->bv->bv_len;
+		buf->bufaddr = page_address(buf->bv->bv_page) + buf->bv->bv_offset;
+	}
+
+	skb = skb_prepare(d, f);
+	if (skb) {
+		skb->next = d->skblist;
+		d->skblist = skb;
+	}
+}
+
+/* enters with d->lock held */
+void
+aoecmd_work(struct aoedev *d)
+{
+	struct frame *f;
+	struct buf *buf;
+loop:
+	f = getframe(d, FREETAG);
+	if (f == NULL)
+		return;
+	if (d->inprocess == NULL) {
+		if (list_empty(&d->bufq))
+			return;
+		buf = container_of(d->bufq.next, struct buf, bufs);
+		list_del(d->bufq.next);
+/*printk(KERN_INFO "aoecmd_work: bi_size=%ld\n", buf->bio->bi_size); */
+		d->inprocess = buf;
+	}
+	aoecmd_ata_rw(d, f);
+	goto loop;
+}
+
+static void
+rexmit(struct aoedev *d, struct frame *f)
+{
+	struct sk_buff *skb;
+	struct aoe_hdr *h;
+	char buf[128];
+	u32 n;
+	u32 net_tag;
+
+	n = newtag(d);
+
+	snprintf(buf, sizeof buf,
+		"%15s e%ld.%ld oldtag=%08x@%08lx newtag=%08x\n",
+		"retransmit",
+		d->aoemajor, d->aoeminor, f->tag, jiffies, n);
+	aoechr_error(buf);
+
+	h = (struct aoe_hdr *) f->data;
+	f->tag = n;
+	net_tag = __cpu_to_be32(n);
+	memcpy(h->tag, &net_tag, sizeof net_tag);
+
+	skb = skb_prepare(d, f);
+	if (skb) {
+		skb->next = d->skblist;
+		d->skblist = skb;
+	}
+}
+
+static int
+tsince(int tag)
+{
+	int n;
+
+	n = jiffies & 0xffff;
+	n -= tag & 0xffff;
+	if (n < 0)
+		n += 1<<16;
+	return n;
+}
+
+static void
+rexmit_timer(ulong vp)
+{
+	struct aoedev *d;
+	struct frame *f, *e;
+	struct sk_buff *sl;
+	register long timeout;
+	ulong flags, n;
+
+	d = (struct aoedev *) vp;
+	sl = NULL;
+
+	/* timeout is always ~150% of the moving average */
+	timeout = d->rttavg;
+	timeout += timeout >> 1;
+
+	spin_lock_irqsave(&d->lock, flags);
+
+	if (d->flags & DEVFL_TKILL) {
+tdie:		spin_unlock_irqrestore(&d->lock, flags);
+		return;
+	}
+	f = d->frames;
+	e = f + d->nframes;
+	for (; f<e; f++) {
+		if (f->tag != FREETAG && tsince(f->tag) >= timeout) {
+			n = f->waited += timeout;
+			n /= HZ;
+			if (n > MAXWAIT) { /* waited too long.  device failure. */
+				aoedev_downdev(d);
+				goto tdie;
+			}
+			rexmit(d, f);
+		}
+	}
+
+	sl = d->skblist;
+	d->skblist = NULL;
+	if (sl) {
+		n = d->rttavg <<= 1;
+		if (n > MAXTIMER)
+			d->rttavg = MAXTIMER;
+	}
+
+	d->timer.expires = jiffies + TIMERTICK;
+	add_timer(&d->timer);
+
+	spin_unlock_irqrestore(&d->lock, flags);
+
+	aoenet_xmit(sl);
+}
+
+static void
+ataid_complete(struct aoedev *d, unsigned char *id)
+{
+	u64 ssize;
+	u16 n;
+
+	/* word 83: command set supported */
+	n = __le16_to_cpu(*((u16 *) &id[83<<1]));
+
+	/* word 86: command set/feature enabled */
+	n |= __le16_to_cpu(*((u16 *) &id[86<<1]));
+
+	if (n & (1<<10)) {	/* bit 10: LBA 48 */
+		d->flags |= DEVFL_EXT;
+
+		/* word 100: number lba48 sectors */
+		ssize = __le64_to_cpu(*((u64 *) &id[100<<1]));
+
+		/* set as in ide-disk.c:init_idedisk_capacity */
+		d->geo.cylinders = ssize;
+		d->geo.cylinders /= (255 * 63);
+		d->geo.heads = 255;
+		d->geo.sectors = 63;
+	} else {
+		d->flags &= ~DEVFL_EXT;
+
+		/* number lba28 sectors */
+		ssize = __le32_to_cpu(*((u32 *) &id[60<<1]));
+
+		/* NOTE: obsolete in ATA 6 */
+		d->geo.cylinders = __le16_to_cpu(*((u16 *) &id[54<<1]));
+		d->geo.heads = __le16_to_cpu(*((u16 *) &id[55<<1]));
+		d->geo.sectors = __le16_to_cpu(*((u16 *) &id[56<<1]));
+	}
+	d->ssize = ssize;
+	d->geo.start = 0;
+	if (d->gd != NULL) {
+		d->gd->capacity = ssize;
+		d->flags |= DEVFL_UP;
+		return;
+	}
+	if (d->flags & DEVFL_WORKON) {
+		printk(KERN_INFO "aoe: ataid_complete: can't schedule work, it's already on!  "
+			"(This really shouldn't happen).\n");
+		return;
+	}
+	INIT_WORK(&d->work, aoeblk_gdalloc, d);
+	schedule_work(&d->work);
+	d->flags |= DEVFL_WORKON;
+}
+
+static void
+calc_rttavg(struct aoedev *d, int rtt)
+{
+	register long n;
+
+	n = rtt;
+	if (n < MINTIMER)
+		n = MINTIMER;
+	else if (n > MAXTIMER)
+		n = MAXTIMER;
+
+	/* g == .25; cf. Congestion Avoidance and Control, Jacobson & Karels; 1988 */
+	n -= d->rttavg;
+	d->rttavg += n >> 2;
+}
+
+void
+aoecmd_ata_rsp(struct sk_buff *skb)
+{
+	struct aoedev *d;
+	struct aoe_hdr *hin;
+	struct aoe_atahdr *ahin, *ahout;
+	struct frame *f;
+	struct buf *buf;
+	struct sk_buff *sl;
+	register long n;
+	ulong flags;
+	char ebuf[128];
+	
+	hin = (struct aoe_hdr *) skb->mac.raw;
+	d = aoedev_bymac(hin->src);
+	if (d == NULL) {
+		snprintf(ebuf, sizeof ebuf, "aoecmd_ata_rsp: ata response "
+			"for unknown device %d.%d\n",
+			 __be16_to_cpu(*((u16 *) hin->major)),
+			hin->minor);
+		aoechr_error(ebuf);
+		return;
+	}
+
+	spin_lock_irqsave(&d->lock, flags);
+
+	f = getframe(d, __be32_to_cpu(*((u32 *) hin->tag)));
+	if (f == NULL) {
+		spin_unlock_irqrestore(&d->lock, flags);
+		snprintf(ebuf, sizeof ebuf,
+			"%15s e%d.%d    tag=%08x@%08lx\n",
+			"unexpected rsp",
+			__be16_to_cpu(*((u16 *) hin->major)),
+			hin->minor,
+			__be32_to_cpu(*((u32 *) hin->tag)),
+			jiffies);
+		aoechr_error(ebuf);
+		return;
+	}
+
+	calc_rttavg(d, tsince(f->tag));
+
+	ahin = (struct aoe_atahdr *) (hin+1);
+	ahout = (struct aoe_atahdr *) (f->data + sizeof(struct aoe_hdr));
+	buf = f->buf;
+
+	if (ahin->cmdstat & 0xa9) {	/* these bits cleared on success */
+		printk(KERN_CRIT "aoe: aoecmd_ata_rsp: ata error cmd=%2.2Xh "
+			"stat=%2.2Xh\n", ahout->cmdstat, ahin->cmdstat);
+		if (buf)
+			buf->flags |= BUFFL_FAIL;
+	} else {
+		switch (ahout->cmdstat) {
+		case WIN_READ:
+		case WIN_READ_EXT:
+			n = ahout->scnt << 9;
+			if (skb->len - sizeof *hin - sizeof *ahin < n) {
+				printk(KERN_CRIT "aoe: aoecmd_ata_rsp: runt "
+					"ata data size in read.  skb->len=%d\n",
+					skb->len);
+				/* fail frame f?  just returning will rexmit. */
+				spin_unlock_irqrestore(&d->lock, flags);
+				return;
+			}
+			memcpy(f->bufaddr, ahin+1, n);
+		case WIN_WRITE:
+		case WIN_WRITE_EXT:
+			break;
+		case WIN_IDENTIFY:
+			if (skb->len - sizeof *hin - sizeof *ahin < 512) {
+				printk(KERN_INFO "aoe: aoecmd_ata_rsp: runt data size "
+					"in ataid.  skb->len=%d\n", skb->len);
+				spin_unlock_irqrestore(&d->lock, flags);
+				return;
+			}
+			ataid_complete(d, (char *) (ahin+1));
+			/* d->flags |= DEVFL_WC_UPDATE; */
+			break;
+		default:
+			printk(KERN_INFO "aoe: aoecmd_ata_rsp: unrecognized "
+			       "outbound ata command %2.2Xh for %d.%d\n", 
+			       ahout->cmdstat,
+			       __be16_to_cpu(*((u16 *) hin->major)),
+			       hin->minor);
+		}
+	}
+
+	if (buf) {
+		buf->nframesout -= 1;
+		if (buf->nframesout == 0 && buf->resid == 0) {
+			n = !(buf->flags & BUFFL_FAIL);
+			bio_endio(buf->bio, buf->bio->bi_size, 0);
+			mempool_free(buf, d->bufpool);
+		}
+	}
+
+	f->buf = NULL;
+	f->tag = FREETAG;
+
+	aoecmd_work(d);
+
+	sl = d->skblist;
+	d->skblist = NULL;
+
+	spin_unlock_irqrestore(&d->lock, flags);
+
+	aoenet_xmit(sl);
+}
+
+void
+aoecmd_cfg(ushort aoemajor, unsigned char aoeminor)
+{
+	struct aoe_hdr *h;
+	struct aoe_cfghdr *ch;
+	struct sk_buff *skb, *sl;
+	struct net_device *ifp;
+	u16 aoe_type = __constant_cpu_to_be16(ETH_P_AOE);
+	u16 net_aoemajor = __cpu_to_be16(aoemajor);
+
+	sl = NULL;
+
+	read_lock(&dev_base_lock);
+	for (ifp = dev_base; ifp; dev_put(ifp), ifp = ifp->next) {
+		dev_hold(ifp);
+		if (!is_aoe_netif(ifp))
+			continue;
+
+		skb = new_skb(ifp, sizeof *h + sizeof *ch);
+		if (skb == NULL) {
+			printk(KERN_INFO "aoe: aoecmd_cfg: skb alloc failure\n");
+			continue;
+		}
+		h = (struct aoe_hdr *) skb->mac.raw;
+		memset(h, 0, sizeof *h + sizeof *ch);
+
+		memset(h->dst, 0xff, sizeof h->dst);
+		memcpy(h->src, ifp->dev_addr, sizeof h->src);
+		memcpy(h->type, &aoe_type, sizeof aoe_type);
+		h->verfl = AOE_HVER;
+		memcpy(h->major, &net_aoemajor, sizeof net_aoemajor);
+		h->minor = aoeminor;
+		h->cmd = AOECMD_CFG;
+
+		skb->next = sl;
+		sl = skb;
+	}
+	read_unlock(&dev_base_lock);
+
+	aoenet_xmit(sl);
+}
+ 
+/*
+ * Since we only call this in one place (and it only prepares one frame)
+ * we just return the skb.  Usually we'd chain it up to the d->skblist.
+ */
+static struct sk_buff *
+aoecmd_ata_id(struct aoedev *d)
+{
+	struct aoe_hdr *h;
+	struct aoe_atahdr *ah;
+	struct frame *f;
+	struct sk_buff *skb;
+
+	f = getframe(d, FREETAG);
+	if (f == NULL) {
+		printk(KERN_CRIT "aoe: aoecmd_ata_id: can't get a frame.  "
+			"This shouldn't happen.\n");
+		return NULL;
+	}
+
+	/* initialize the headers & frame */
+	h = (struct aoe_hdr *) f->data;
+	ah = (struct aoe_atahdr *) (h+1);
+	f->ndata = sizeof *h + sizeof *ah;
+	memset(h, 0, f->ndata);
+	f->tag = aoehdr_atainit(d, h);
+	f->waited = 0;
+	f->writedatalen = 0;
+
+	/* this message initializes the device, so we reset the rttavg */
+	d->rttavg = MAXTIMER;
+
+	/* set up ata header */
+	ah->scnt = 1;
+	ah->cmdstat = WIN_IDENTIFY;
+	ah->lba3 = 0xa0;
+
+	skb = skb_prepare(d, f);
+
+	/* we now want to start the rexmit tracking */
+	d->flags &= ~DEVFL_TKILL;
+	d->timer.data = (ulong) d;
+	d->timer.function = rexmit_timer;
+	d->timer.expires = jiffies + TIMERTICK;
+	add_timer(&d->timer);
+
+	return skb;
+}
+ 
+void
+aoecmd_cfg_rsp(struct sk_buff *skb)
+{
+	struct aoedev *d;
+	struct aoe_hdr *h;
+	struct aoe_cfghdr *ch;
+	ulong flags, bufcnt, sysminor, aoemajor;
+	struct sk_buff *sl;
+	enum { MAXFRAMES = 8, MAXSYSMINOR = 255 };
+
+	h = (struct aoe_hdr *) skb->mac.raw;
+	ch = (struct aoe_cfghdr *) (h+1);
+
+	/*
+	 * Enough people have their dip switches set backwards to
+	 * warrant a loud message for this special case.
+	 */
+	aoemajor = __be16_to_cpu(*((u16 *) h->major));
+	if (aoemajor == 0xfff) {
+		printk(KERN_CRIT "aoe: aoecmd_cfg_rsp: Warning: shelf "
+			"address is all ones.  Check shelf dip switches\n");
+		return;
+	}
+
+	sysminor = SYSMINOR(aoemajor, h->minor);
+	if (sysminor > MAXSYSMINOR) {
+		printk(KERN_INFO "aoe: aoecmd_cfg_rsp: sysminor %ld too "
+			"large\n", sysminor);
+		return;
+	}
+
+	bufcnt = __be16_to_cpu(*((u16 *) ch->bufcnt));
+	if (bufcnt > MAXFRAMES)	/* keep it reasonable */
+		bufcnt = MAXFRAMES;
+
+	d = aoedev_set(sysminor, h->src, skb->dev, bufcnt);
+	if (d == NULL) {
+		printk(KERN_INFO "aoe: aoecmd_cfg_rsp: device set failure\n");
+		return;
+	}
+
+	spin_lock_irqsave(&d->lock, flags);
+
+	if (d->flags & (DEVFL_UP | DEVFL_CLOSEWAIT)) {
+		spin_unlock_irqrestore(&d->lock, flags);
+		return;
+	}
+
+	d->fw_ver = __be16_to_cpu(*((u16 *) ch->fwver));
+
+	/* we get here only if the device is new */
+	sl = aoecmd_ata_id(d);
+
+	spin_unlock_irqrestore(&d->lock, flags);
+
+	aoenet_xmit(sl);
+}
+
diff -Nru a/drivers/block/aoe/aoedev.c b/drivers/block/aoe/aoedev.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/block/aoe/aoedev.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,180 @@
+/* Copyright (c) 2004 Coraid, Inc.  See COPYING for GPL terms. */
+/*
+ * aoedev.c
+ * AoE device utility functions; maintains device list.
+ */
+
+#include <linux/hdreg.h>
+#include <linux/blkdev.h>
+#include <linux/netdevice.h>
+#include "aoe.h"
+
+static struct aoedev *devlist;
+static spinlock_t devlist_lock;
+
+struct aoedev *
+aoedev_bymac(unsigned char *macaddr)
+{
+	struct aoedev *d;
+	ulong flags;
+
+	spin_lock_irqsave(&devlist_lock, flags);
+
+	for (d=devlist; d; d=d->next)
+		if (!memcmp(d->addr, macaddr, 6))
+			break;
+
+	spin_unlock_irqrestore(&devlist_lock, flags);
+	return d;
+}
+
+/* called with devlist lock held */
+static struct aoedev *
+aoedev_newdev(ulong nframes)
+{
+	struct aoedev *d;
+	struct frame *f, *e;
+
+	d = kcalloc(1, sizeof *d, GFP_ATOMIC);
+	if (d == NULL)
+		return NULL;
+	f = kcalloc(nframes, sizeof *f, GFP_ATOMIC);
+	if (f == NULL) {
+		kfree(d);
+		return NULL;
+	}
+
+	d->nframes = nframes;
+	d->frames = f;
+	e = f + nframes;
+	for (; f<e; f++)
+		f->tag = FREETAG;
+
+	spin_lock_init(&d->lock);
+	init_timer(&d->timer);
+	d->bufpool = NULL;	/* defer to aoeblk_gdalloc */
+	INIT_LIST_HEAD(&d->bufq);
+	d->next = devlist;
+	devlist = d;
+
+	return d;
+}
+
+void
+aoedev_downdev(struct aoedev *d)
+{
+	struct frame *f, *e;
+	struct buf *buf;
+	struct bio *bio;
+
+	d->flags |= DEVFL_TKILL;
+	del_timer(&d->timer);
+
+	f = d->frames;
+	e = f + d->nframes;
+	for (; f<e; f->tag = FREETAG, f->buf = NULL, f++) {
+		if (f->tag == FREETAG || f->buf == NULL)
+			continue;
+		buf = f->buf;
+		bio = buf->bio;
+		if (--buf->nframesout == 0) {
+			mempool_free(buf, d->bufpool);
+			bio_endio(bio, bio->bi_size, -EIO);
+		}
+	}
+	d->inprocess = NULL;
+
+	while (!list_empty(&d->bufq)) {
+		buf = container_of(d->bufq.next, struct buf, bufs);
+		list_del(d->bufq.next);
+		bio = buf->bio;
+		mempool_free(buf, d->bufpool);
+		bio_endio(bio, bio->bi_size, -EIO);
+	}
+
+	if (d->nopen)
+		d->flags |= DEVFL_CLOSEWAIT;
+	if (d->gd)
+		d->gd->capacity = 0;
+
+	d->flags &= ~DEVFL_UP;
+}
+
+struct aoedev *
+aoedev_set(ulong sysminor, unsigned char *addr, struct net_device *ifp, ulong bufcnt)
+{
+	struct aoedev *d;
+	ulong flags;
+
+	spin_lock_irqsave(&devlist_lock, flags);
+
+	for (d=devlist; d; d=d->next)
+		if (d->sysminor == sysminor
+		|| memcmp(d->addr, addr, sizeof d->addr) == 0)
+			break;
+
+	if (d == NULL && (d = aoedev_newdev(bufcnt)) == NULL) {
+		spin_unlock_irqrestore(&devlist_lock, flags);
+		printk(KERN_INFO "aoe: aoedev_set: aoedev_newdev failure.\n");
+		return NULL;
+	}
+
+	spin_unlock_irqrestore(&devlist_lock, flags);
+	spin_lock_irqsave(&d->lock, flags);
+
+	d->ifp = ifp;
+
+	if (d->sysminor != sysminor
+	|| memcmp(d->addr, addr, sizeof d->addr)
+	|| (d->flags & DEVFL_UP) == 0) {
+		aoedev_downdev(d); /* flushes outstanding frames */
+		memcpy(d->addr, addr, sizeof d->addr);
+		d->sysminor = sysminor;
+		d->aoemajor = AOEMAJOR(sysminor);
+		d->aoeminor = AOEMINOR(sysminor);
+	}
+
+	spin_unlock_irqrestore(&d->lock, flags);
+	return d;
+}
+
+static void
+aoedev_freedev(struct aoedev *d)
+{
+	if (d->gd) {
+		aoedisk_rm_sysfs(d);
+		del_gendisk(d->gd);
+		put_disk(d->gd);
+	}
+	kfree(d->frames);
+	mempool_destroy(d->bufpool);
+	kfree(d);
+}
+
+void
+aoedev_exit(void)
+{
+	struct aoedev *d;
+	ulong flags;
+
+	flush_scheduled_work();
+
+	while ((d = devlist)) {
+		devlist = d->next;
+
+		spin_lock_irqsave(&d->lock, flags);
+		aoedev_downdev(d);
+		spin_unlock_irqrestore(&d->lock, flags);
+
+		del_timer_sync(&d->timer);
+		aoedev_freedev(d);
+	}
+}
+
+int __init
+aoedev_init(void)
+{
+	spin_lock_init(&devlist_lock);
+	return 0;
+}
+
diff -Nru a/drivers/block/aoe/aoemain.c b/drivers/block/aoe/aoemain.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/block/aoe/aoemain.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,112 @@
+/* Copyright (c) 2004 Coraid, Inc.  See COPYING for GPL terms. */
+/*
+ * aoemain.c
+ * Module initialization routines, discover timer
+ */
+
+#include <linux/hdreg.h>
+#include <linux/blkdev.h>
+#include <linux/module.h>
+#include "aoe.h"
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Sam Hopkins <sah@coraid.com>");
+MODULE_DESCRIPTION("AoE block/char driver for 2.6.[0-9]+");
+MODULE_VERSION(VERSION);
+
+enum { TINIT, TRUN, TKILL };
+
+static void
+discover_timer(ulong vp)
+{
+	static struct timer_list t;
+	static volatile ulong die;
+	static spinlock_t lock;
+	ulong flags;
+	enum { DTIMERTICK = HZ * 60 }; /* one minute */
+
+	switch (vp) {
+	case TINIT:
+		init_timer(&t);
+		spin_lock_init(&lock);
+		t.data = TRUN;
+		t.function = discover_timer;
+		die = 0;
+	case TRUN:
+		spin_lock_irqsave(&lock, flags);
+		if (!die) {
+			t.expires = jiffies + DTIMERTICK;
+			add_timer(&t);
+		}
+		spin_unlock_irqrestore(&lock, flags);
+
+		aoecmd_cfg(0xffff, 0xff);
+		return;
+	case TKILL:
+		spin_lock_irqsave(&lock, flags);
+		die = 1;
+		spin_unlock_irqrestore(&lock, flags);
+
+		del_timer_sync(&t);
+	default:
+		return;
+	}
+}
+
+static void
+aoe_exit(void)
+{
+	discover_timer(TKILL);
+
+	aoenet_exit();
+	unregister_blkdev(AOE_MAJOR, DEVICE_NAME);
+	aoechr_exit();
+	aoedev_exit();
+	aoeblk_exit();		/* free cache after de-allocating bufs */
+}
+
+static int __init
+aoe_init(void)
+{
+	int ret;
+
+	ret = aoedev_init();
+	if (ret)
+		return ret;
+	ret = aoechr_init();
+	if (ret)
+		goto chr_fail;
+	ret = aoeblk_init();
+	if (ret)
+		goto blk_fail;
+	ret = aoenet_init();
+	if (ret)
+		goto net_fail;
+	ret = register_blkdev(AOE_MAJOR, DEVICE_NAME);
+	if (ret < 0) {
+		printk(KERN_ERR "aoe: aoeblk_init: can't register major\n");
+		goto blkreg_fail;
+	}
+
+	printk(KERN_INFO
+	       "aoe: aoe_init: AoE v2.6-%s initialised.\n",
+	       VERSION);
+	discover_timer(TINIT);
+	return 0;
+
+ blkreg_fail:
+	aoenet_exit();
+ net_fail:
+	aoeblk_exit();
+ blk_fail:
+	aoechr_exit();
+ chr_fail:
+	aoedev_exit();
+	
+	printk(KERN_INFO "aoe: aoe_init: initialisation failure.\n");
+	return ret;
+}
+
+module_init(aoe_init);
+module_exit(aoe_exit);
+
diff -Nru a/drivers/block/aoe/aoenet.c b/drivers/block/aoe/aoenet.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/block/aoe/aoenet.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,172 @@
+/* Copyright (c) 2004 Coraid, Inc.  See COPYING for GPL terms. */
+/*
+ * aoenet.c
+ * Ethernet portion of AoE driver
+ */
+
+#include <linux/hdreg.h>
+#include <linux/blkdev.h>
+#include <linux/netdevice.h>
+#include "aoe.h"
+
+#define NECODES 5
+
+static char *aoe_errlist[] =
+{
+	"no such error",
+	"unrecognized command code",
+	"bad argument parameter",
+	"device unavailable",
+	"config string present",
+	"unsupported version"
+};
+
+enum {
+	IFLISTSZ = 1024,
+};
+
+static char aoe_iflist[IFLISTSZ];
+
+int
+is_aoe_netif(struct net_device *ifp)
+{
+	register char *p, *q;
+	register int len;
+
+	if (aoe_iflist[0] == '\0')
+		return 1;
+
+	for (p = aoe_iflist; *p; p = q + strspn(q, WHITESPACE)) {
+		q = p + strcspn(p, WHITESPACE);
+		if (q != p)
+			len = q - p;
+		else
+			len = strlen(p); /* last token in aoe_iflist */
+
+		if (strlen(ifp->name) == len && !strncmp(ifp->name, p, len))
+			return 1;
+		if (q == p)
+			break;
+	}
+
+	return 0;
+}
+
+int
+set_aoe_iflist(const char __user *user_str, size_t size)
+{
+	if (size >= IFLISTSZ)
+		return -EINVAL;
+
+	if (copy_from_user(aoe_iflist, user_str, size)) {
+		printk(KERN_INFO "aoe: %s: copy from user failed\n", __FUNCTION__);
+		return -EFAULT;
+	}
+	aoe_iflist[size] = 0x00;
+	return 0;
+}
+
+u64
+mac_addr(char addr[6])
+{
+	u64 n = 0;
+	char *p = (char *) &n;
+
+	memcpy(p + 2, addr, 6);	/* (sizeof addr != 6) */
+
+	return __be64_to_cpu(n);
+}
+
+static struct sk_buff *
+skb_check(struct sk_buff *skb)
+{
+	if (skb_is_nonlinear(skb))
+	if ((skb = skb_share_check(skb, GFP_ATOMIC)))
+	if (skb_linearize(skb, GFP_ATOMIC) < 0) {
+		dev_kfree_skb(skb);
+		return NULL;
+	}
+	return skb;
+}
+
+void
+aoenet_xmit(struct sk_buff *sl)
+{
+	struct sk_buff *skb;
+
+	while ((skb = sl)) {
+		sl = sl->next;
+		skb->next = skb->prev = NULL;
+		dev_queue_xmit(skb);
+	}
+}
+
+/* 
+ * (1) len doesn't include the header by default.  I want this. 
+ */
+static int
+aoenet_rcv(struct sk_buff *skb, struct net_device *ifp, struct packet_type *pt)
+{
+	struct aoe_hdr *h;
+	ulong n;
+
+	skb = skb_check(skb);
+	if (!skb)
+		return 0;
+
+	if (!is_aoe_netif(ifp))
+		goto exit;
+
+	//skb->len += ETH_HLEN;	/* (1) */
+	skb_push(skb, ETH_HLEN);	/* (1) */
+
+	h = (struct aoe_hdr *) skb->mac.raw;
+	n = __be32_to_cpu(*((u32 *) h->tag));
+	if ((h->verfl & AOEFL_RSP) == 0 || (n & 1<<31))
+		goto exit;
+
+	if (h->verfl & AOEFL_ERR) {
+		n = h->err;
+		if (n > NECODES)
+			n = 0;
+		if (net_ratelimit())
+			printk(KERN_ERR "aoe: aoenet_rcv: error packet from %d.%d; "
+			       "ecode=%d '%s'\n",
+			       __be16_to_cpu(*((u16 *) h->major)), h->minor, 
+			       h->err, aoe_errlist[n]);
+		goto exit;
+	}
+
+	switch (h->cmd) {
+	case AOECMD_ATA:
+		aoecmd_ata_rsp(skb);
+		break;
+	case AOECMD_CFG:
+		aoecmd_cfg_rsp(skb);
+		break;
+	default:
+		printk(KERN_INFO "aoe: aoenet_rcv: unknown cmd %d\n", h->cmd);
+	}
+exit:
+	dev_kfree_skb(skb);
+	return 0;
+}
+
+static struct packet_type aoe_pt = {
+	.type = __constant_htons(ETH_P_AOE),
+	.func = aoenet_rcv,
+};
+
+int __init
+aoenet_init(void)
+{
+	dev_add_pack(&aoe_pt);
+	return 0;
+}
+
+void
+aoenet_exit(void)
+{
+	dev_remove_pack(&aoe_pt);
+}
+
diff -Nru a/drivers/block/ataflop.c b/drivers/block/ataflop.c
--- a/drivers/block/ataflop.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/block/ataflop.c	2005-03-01 23:38:53 -08:00
@@ -140,7 +140,7 @@
 
 static int DriveType = TYPE_HD;
 
-static spinlock_t ataflop_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(ataflop_lock);
 
 /* Array for translating minors into disk formats */
 static struct {
diff -Nru a/drivers/block/cciss.c b/drivers/block/cciss.c
--- a/drivers/block/cciss.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/block/cciss.c	2005-03-01 23:39:17 -08:00
@@ -16,7 +16,7 @@
  *    along with this program; if not, write to the Free Software
  *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- *    Questions/Comments/Bugfixes to Cciss-discuss@lists.sourceforge.net
+ *    Questions/Comments/Bugfixes to iss_storagedev@hp.com
  *
  */
 
@@ -46,14 +46,14 @@
 #include <linux/completion.h>
 
 #define CCISS_DRIVER_VERSION(maj,min,submin) ((maj<<16)|(min<<8)|(submin))
-#define DRIVER_NAME "HP CISS Driver (v 2.6.2)"
-#define DRIVER_VERSION CCISS_DRIVER_VERSION(2,6,2)
+#define DRIVER_NAME "HP CISS Driver (v 2.6.4)"
+#define DRIVER_VERSION CCISS_DRIVER_VERSION(2,6,4)
 
 /* Embedded module documentation macros - see modules.h */
 MODULE_AUTHOR("Hewlett-Packard Company");
-MODULE_DESCRIPTION("Driver for HP Controller SA5xxx SA6xxx version 2.6.2");
+MODULE_DESCRIPTION("Driver for HP Controller SA5xxx SA6xxx version 2.6.4");
 MODULE_SUPPORTED_DEVICE("HP SA5i SA5i+ SA532 SA5300 SA5312 SA641 SA642 SA6400"
-			" SA6i V100");
+			" SA6i P600");
 MODULE_LICENSE("GPL");
 
 #include "cciss_cmd.h"
@@ -80,10 +80,8 @@
 		0x0E11, 0x409D, 0, 0, 0},
 	{ PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISSC,
 		0x0E11, 0x4091, 0, 0, 0},
-	{ PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISSC,
-		0x0E11, 0x409E, 0, 0, 0},
-	{ PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISS,
-		0x103C, 0x3211, 0, 0, 0},
+	{ PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSA,
+		0x103C, 0x3225, 0, 0, 0},
 	{0,}
 };
 MODULE_DEVICE_TABLE(pci, cciss_pci_device_id);
@@ -104,8 +102,7 @@
 	{ 0x409C0E11, "Smart Array 6400", &SA5_access},
 	{ 0x409D0E11, "Smart Array 6400 EM", &SA5_access},
 	{ 0x40910E11, "Smart Array 6i", &SA5_access},
-	{ 0x409E0E11, "Smart Array 6422", &SA5_access},
-	{ 0x3211103C, "Smart Array V100", &SA5_access},
+	{ 0x3225103C, "Smart Array P600", &SA5_access},
 };
 
 /* How long to wait (in millesconds) for board to go into simple mode */
@@ -149,11 +146,18 @@
 static void cciss_procinit(int i) {}
 #endif /* CONFIG_PROC_FS */
 
+#ifdef CONFIG_COMPAT
+static long cciss_compat_ioctl(struct file *f, unsigned cmd, unsigned long arg);
+#endif
+
 static struct block_device_operations cciss_fops  = {
 	.owner		= THIS_MODULE,
 	.open		= cciss_open, 
 	.release       	= cciss_release,
         .ioctl		= cciss_ioctl,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl   = cciss_compat_ioctl,
+#endif
 	.revalidate_disk= cciss_revalidate,
 };
 
@@ -480,80 +484,50 @@
 }
 
 #ifdef CONFIG_COMPAT
-/* for AMD 64 bit kernel compatibility with 32-bit userland ioctls */
-extern long sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg);
-extern int
-register_ioctl32_conversion(unsigned int cmd, int (*handler)(unsigned int,
-      unsigned int, unsigned long, struct file *));
-extern int unregister_ioctl32_conversion(unsigned int cmd);
-
-static int cciss_ioctl32_passthru(unsigned int fd, unsigned cmd, unsigned long arg, struct file *file);
-static int cciss_ioctl32_big_passthru(unsigned int fd, unsigned cmd, unsigned long arg,
-	struct file *file);
-
-typedef int (*handler_type) (unsigned int, unsigned int, unsigned long, struct file *);
-
-static struct ioctl32_map {
-	unsigned int cmd;
-	handler_type handler;
-	int registered;
-} cciss_ioctl32_map[] = {
-	{ CCISS_GETPCIINFO,	(handler_type) sys_ioctl, 0 },
-	{ CCISS_GETINTINFO,	(handler_type) sys_ioctl, 0 },
-	{ CCISS_SETINTINFO,	(handler_type) sys_ioctl, 0 },
-	{ CCISS_GETNODENAME,	(handler_type) sys_ioctl, 0 },
-	{ CCISS_SETNODENAME,	(handler_type) sys_ioctl, 0 },
-	{ CCISS_GETHEARTBEAT,	(handler_type) sys_ioctl, 0 },
-	{ CCISS_GETBUSTYPES,	(handler_type) sys_ioctl, 0 },
-	{ CCISS_GETFIRMVER,	(handler_type) sys_ioctl, 0 },
-	{ CCISS_GETDRIVVER,	(handler_type) sys_ioctl, 0 },
-	{ CCISS_REVALIDVOLS,	(handler_type) sys_ioctl, 0 },
-	{ CCISS_PASSTHRU32,	cciss_ioctl32_passthru, 0 },
-	{ CCISS_DEREGDISK,	(handler_type) sys_ioctl, 0 },
-	{ CCISS_REGNEWDISK,	(handler_type) sys_ioctl, 0 },
-	{ CCISS_REGNEWD,	(handler_type) sys_ioctl, 0 },
-	{ CCISS_RESCANDISK,	(handler_type) sys_ioctl, 0 },
-	{ CCISS_GETLUNINFO,	(handler_type) sys_ioctl, 0 },
-	{ CCISS_BIG_PASSTHRU32,	cciss_ioctl32_big_passthru, 0 },
-};
-#define NCCISS_IOCTL32_ENTRIES (sizeof(cciss_ioctl32_map) / sizeof(cciss_ioctl32_map[0]))
-static void register_cciss_ioctl32(void)
-{
-	int i, rc;
 
-	for (i=0; i < NCCISS_IOCTL32_ENTRIES; i++) {
-		rc = register_ioctl32_conversion(
-			cciss_ioctl32_map[i].cmd,
-			cciss_ioctl32_map[i].handler);
-		if (rc != 0) {
-			printk(KERN_WARNING "cciss: failed to register "
-				"32 bit compatible ioctl 0x%08x\n",
-				cciss_ioctl32_map[i].cmd);
-			cciss_ioctl32_map[i].registered = 0;
-		} else
-			cciss_ioctl32_map[i].registered = 1;
-	}
+static int do_ioctl(struct file *f, unsigned cmd, unsigned long arg)
+{
+	int ret;
+	lock_kernel();
+	ret = cciss_ioctl(f->f_dentry->d_inode, f, cmd, arg);
+	unlock_kernel();
+	return ret;
 }
-static void unregister_cciss_ioctl32(void)
+
+static int cciss_ioctl32_passthru(struct file *f, unsigned cmd, unsigned long arg);
+static int cciss_ioctl32_big_passthru(struct file *f, unsigned cmd, unsigned long arg);
+
+static long cciss_compat_ioctl(struct file *f, unsigned cmd, unsigned long arg)
 {
-	int i, rc;
+	switch (cmd) {
+	case CCISS_GETPCIINFO:
+	case CCISS_GETINTINFO:
+	case CCISS_SETINTINFO:
+	case CCISS_GETNODENAME:
+	case CCISS_SETNODENAME:
+	case CCISS_GETHEARTBEAT:
+	case CCISS_GETBUSTYPES:
+	case CCISS_GETFIRMVER:
+	case CCISS_GETDRIVVER:
+	case CCISS_REVALIDVOLS:
+	case CCISS_DEREGDISK:
+	case CCISS_REGNEWDISK:
+	case CCISS_REGNEWD:
+	case CCISS_RESCANDISK:
+	case CCISS_GETLUNINFO:
+		return do_ioctl(f, cmd, arg);
+
+	case CCISS_PASSTHRU32:
+		return cciss_ioctl32_passthru(f, cmd, arg);
+	case CCISS_BIG_PASSTHRU32:
+		return cciss_ioctl32_big_passthru(f, cmd, arg);
 
-	for (i=0; i < NCCISS_IOCTL32_ENTRIES; i++) {
-		if (!cciss_ioctl32_map[i].registered)
-			continue;
-		rc = unregister_ioctl32_conversion(
-			cciss_ioctl32_map[i].cmd);
-		if (rc == 0) {
-			cciss_ioctl32_map[i].registered = 0;
-			continue;
-		}
-		printk(KERN_WARNING "cciss: failed to unregister "
-			"32 bit compatible ioctl 0x%08x\n",
-			cciss_ioctl32_map[i].cmd);
+	default:
+		return -ENOIOCTLCMD;
 	}
 }
-int cciss_ioctl32_passthru(unsigned int fd, unsigned cmd, unsigned long arg,
-	struct file *file)
+
+static int cciss_ioctl32_passthru(struct file *f, unsigned cmd, unsigned long arg)
 {
 	IOCTL32_Command_struct __user *arg32 =
 		(IOCTL32_Command_struct __user *) arg;
@@ -574,7 +548,7 @@
 	if (err)
 		return -EFAULT;
 
-	err = sys_ioctl(fd, CCISS_PASSTHRU, (unsigned long) p);
+	err = do_ioctl(f, CCISS_PASSTHRU, (unsigned long) p);
 	if (err)
 		return err;
 	err |= copy_in_user(&arg32->error_info, &p->error_info, sizeof(arg32->error_info));
@@ -583,8 +557,7 @@
 	return err;
 }
 
-int cciss_ioctl32_big_passthru(unsigned int fd, unsigned cmd, unsigned long arg,
-	struct file *file)
+static int cciss_ioctl32_big_passthru(struct file *file, unsigned cmd, unsigned long arg)
 {
 	BIG_IOCTL32_Command_struct __user *arg32 =
 		(BIG_IOCTL32_Command_struct __user *) arg;
@@ -606,7 +579,7 @@
 	if (err)
 		 return -EFAULT;
 
-	err = sys_ioctl(fd, CCISS_BIG_PASSTHRU, (unsigned long) p);
+	err = do_ioctl(file, CCISS_BIG_PASSTHRU, (unsigned long) p);
 	if (err)
 		return err;
 	err |= copy_in_user(&arg32->error_info, &p->error_info, sizeof(arg32->error_info));
@@ -614,9 +587,6 @@
 		return -EFAULT;
 	return err;
 }
-#else
-static inline void register_cciss_ioctl32(void) {}
-static inline void unregister_cciss_ioctl32(void) {}
 #endif
 /*
  * ioctl 
@@ -2918,7 +2888,6 @@
 
 static int __init init_cciss_module(void)
 {
-	register_cciss_ioctl32();
 	return ( cciss_init());
 }
 
@@ -2926,7 +2895,6 @@
 {
 	int i;
 
-	unregister_cciss_ioctl32();
 	pci_unregister_driver(&cciss_pci_driver);
 	/* double check that all controller entrys have been removed */
 	for (i=0; i< MAX_CTLR; i++) 
diff -Nru a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c
--- a/drivers/block/cciss_scsi.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/block/cciss_scsi.c	2005-03-01 23:38:53 -08:00
@@ -16,7 +16,7 @@
  *    along with this program; if not, write to the Free Software
  *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- *    Questions/Comments/Bugfixes to arrays@compaq.com
+ *    Questions/Comments/Bugfixes to iss_storagedev@hp.com
  *    
  *    Author: Stephen M. Cameron
  */
@@ -534,7 +534,7 @@
 	if (shba == NULL)
 		return;
 	shba->scsi_host = NULL;
-	shba->lock = SPIN_LOCK_UNLOCKED;
+	spin_lock_init(&shba->lock);
 	shba->registered = 0;
 	if (scsi_cmd_stack_setup(cntl_num, shba) != 0) {
 		kfree(shba);
@@ -691,14 +691,13 @@
 cciss_scsi_detect(int ctlr)
 {
 	struct Scsi_Host *sh;
+	int error;
 
 	sh = scsi_host_alloc(&cciss_driver_template, sizeof(struct ctlr_info *));
 	if (sh == NULL)
-		return 0;
-
+		goto fail;
 	sh->io_port = 0;	// good enough?  FIXME, 
 	sh->n_io_port = 0;	// I don't think we use these two...
-
 	sh->this_id = SELF_SCSI_ID;  
 
 	((struct cciss_scsi_adapter_data_t *) 
@@ -706,10 +705,16 @@
 	sh->hostdata[0] = (unsigned long) hba[ctlr];
 	sh->irq = hba[ctlr]->intr;
 	sh->unique_id = sh->irq;
-	scsi_add_host(sh, &hba[ctlr]->pdev->dev); /* XXX handle failure */
+	error = scsi_add_host(sh, &hba[ctlr]->pdev->dev);
+	if (error)
+		goto fail_host_put;
 	scsi_scan_host(sh);
-
 	return 1;
+
+ fail_host_put:
+	scsi_host_put(sh);
+ fail:
+	return 0;
 }
 
 static void __exit cleanup_cciss_module(void);
diff -Nru a/drivers/block/cciss_scsi.h b/drivers/block/cciss_scsi.h
--- a/drivers/block/cciss_scsi.h	2005-03-01 23:38:57 -08:00
+++ b/drivers/block/cciss_scsi.h	2005-03-01 23:38:57 -08:00
@@ -16,7 +16,7 @@
  *    along with this program; if not, write to the Free Software
  *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- *    Questions/Comments/Bugfixes to arrays@compaq.com
+ *    Questions/Comments/Bugfixes to iss_storagedev@hp.com
  *
  */
 #ifdef CONFIG_CISS_SCSI_TAPE
diff -Nru a/drivers/block/cfq-iosched.c b/drivers/block/cfq-iosched.c
--- a/drivers/block/cfq-iosched.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/block/cfq-iosched.c	2005-03-01 23:39:07 -08:00
@@ -622,8 +622,10 @@
 			cfq_sort_rr_list(cfqq, 0);
 		}
 
-		crq->accounted = 0;
-		cfqq->cfqd->rq_in_driver--;
+		if (crq->accounted) {
+			crq->accounted = 0;
+			cfqq->cfqd->rq_in_driver--;
+		}
 	}
 	list_add(&rq->queuelist, &q->queue_head);
 }
@@ -1283,19 +1285,19 @@
 static void cfq_completed_request(request_queue_t *q, struct request *rq)
 {
 	struct cfq_rq *crq = RQ_DATA(rq);
+	struct cfq_queue *cfqq;
 
 	if (unlikely(!blk_fs_request(rq)))
 		return;
 
-	if (crq->in_flight) {
-		struct cfq_queue *cfqq = crq->cfq_queue;
+	cfqq = crq->cfq_queue;
 
+	if (crq->in_flight) {
 		WARN_ON(!cfqq->in_flight);
 		cfqq->in_flight--;
-
-		cfq_account_completion(cfqq, crq);
 	}
 
+	cfq_account_completion(cfqq, crq);
 }
 
 static struct request *
@@ -1817,7 +1819,7 @@
 	.elevator_owner =	THIS_MODULE,
 };
 
-int cfq_init(void)
+static int __init cfq_init(void)
 {
 	int ret;
 
diff -Nru a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c
--- a/drivers/block/cpqarray.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/block/cpqarray.c	2005-03-01 23:38:52 -08:00
@@ -16,7 +16,7 @@
  *    along with this program; if not, write to the Free Software
  *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- *    Questions/Comments/Bugfixes to Cpqarray-discuss@lists.sourceforge.net
+ *    Questions/Comments/Bugfixes to iss_storagedev@hp.com
  *
  */
 #include <linux/config.h>	/* CONFIG_PROC_FS */
@@ -310,7 +310,7 @@
 }
 #endif /* CONFIG_PROC_FS */
 
-MODULE_PARM(eisa, "1-8i");
+module_param_array(eisa, int, NULL, 0);
 
 /* This is a bit of a hack,
  * necessary to support both eisa and pci
diff -Nru a/drivers/block/cpqarray.h b/drivers/block/cpqarray.h
--- a/drivers/block/cpqarray.h	2005-03-01 23:39:07 -08:00
+++ b/drivers/block/cpqarray.h	2005-03-01 23:39:07 -08:00
@@ -16,7 +16,7 @@
  *    along with this program; if not, write to the Free Software
  *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- *    Questions/Comments/Bugfixes to arrays@compaq.com
+ *    Questions/Comments/Bugfixes to iss_storagedev@hp.com
  *
  *    If you want to make changes, improve or add functionality to this
  *    driver, you'll probably need the Compaq Array Controller Interface
diff -Nru a/drivers/block/deadline-iosched.c b/drivers/block/deadline-iosched.c
--- a/drivers/block/deadline-iosched.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/block/deadline-iosched.c	2005-03-01 23:39:09 -08:00
@@ -791,24 +791,24 @@
 };
 
 static ssize_t
-deadline_var_show(unsigned int var, char *page)
+deadline_var_show(int var, char *page)
 {
 	return sprintf(page, "%d\n", var);
 }
 
 static ssize_t
-deadline_var_store(unsigned int *var, const char *page, size_t count)
+deadline_var_store(int *var, const char *page, size_t count)
 {
 	char *p = (char *) page;
 
-	*var = simple_strtoul(p, &p, 10);
+	*var = simple_strtol(p, &p, 10);
 	return count;
 }
 
 #define SHOW_FUNCTION(__FUNC, __VAR, __CONV)				\
 static ssize_t __FUNC(struct deadline_data *dd, char *page)		\
 {									\
-	unsigned int __data = __VAR;					\
+	int __data = __VAR;					\
 	if (__CONV)							\
 		__data = jiffies_to_msecs(__data);			\
 	return deadline_var_show(__data, (page));			\
@@ -823,7 +823,7 @@
 #define STORE_FUNCTION(__FUNC, __PTR, MIN, MAX, __CONV)			\
 static ssize_t __FUNC(struct deadline_data *dd, const char *page, size_t count)	\
 {									\
-	unsigned int __data;						\
+	int __data;							\
 	int ret = deadline_var_store(&__data, (page), count);		\
 	if (__data < (MIN))						\
 		__data = (MIN);						\
diff -Nru a/drivers/block/elevator.c b/drivers/block/elevator.c
--- a/drivers/block/elevator.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/block/elevator.c	2005-03-01 23:39:09 -08:00
@@ -37,7 +37,7 @@
 
 #include <asm/uaccess.h>
 
-static spinlock_t elv_list_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(elv_list_lock);
 static LIST_HEAD(elv_list);
 
 /*
@@ -170,8 +170,6 @@
 #else
 #error "You must build at least 1 IO scheduler into the kernel"
 #endif
-	printk(KERN_INFO "elevator: using %s as default io scheduler\n",
-							chosen_elevator);
 }
 
 static int __init elevator_setup(char *str)
@@ -515,7 +513,10 @@
 	list_add_tail(&e->list, &elv_list);
 	spin_unlock_irq(&elv_list_lock);
 
-	printk(KERN_INFO "io scheduler %s registered\n", e->elevator_name);
+	printk(KERN_INFO "io scheduler %s registered", e->elevator_name);
+	if (!strcmp(e->elevator_name, chosen_elevator))
+		printk(" (default)");
+	printk("\n");
 	return 0;
 }
 EXPORT_SYMBOL_GPL(elv_register);
diff -Nru a/drivers/block/floppy.c b/drivers/block/floppy.c
--- a/drivers/block/floppy.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/block/floppy.c	2005-03-01 23:38:53 -08:00
@@ -155,7 +155,6 @@
 #include <linux/kernel.h>
 #include <linux/timer.h>
 #include <linux/workqueue.h>
-#include <linux/version.h>
 #define FDPATCHES
 #include <linux/fdreg.h>
 
@@ -217,7 +216,7 @@
  * record each buffers capabilities
  */
 
-static spinlock_t floppy_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(floppy_lock);
 static struct completion device_release;
 
 static unsigned short virtual_dma_port = 0x3f0;
@@ -1073,7 +1072,7 @@
 	return 0;
 }
 
-static spinlock_t floppy_hlt_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(floppy_hlt_lock);
 static int hlt_disabled;
 static void floppy_disable_hlt(void)
 {
@@ -3319,11 +3318,6 @@
 	return 0;
 }
 
-static inline void clear_write_error(int drive)
-{
-	CLEARSTRUCT(UDRWE);
-}
-
 static inline int set_geometry(unsigned int cmd, struct floppy_struct *g,
 			       int drive, int type, struct block_device *bdev)
 {
@@ -4421,7 +4415,7 @@
 	return err;
 }
 
-static spinlock_t floppy_usage_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(floppy_usage_lock);
 
 static int floppy_grab_irq_and_dma(void)
 {
@@ -4596,8 +4590,6 @@
 
 int init_module(void)
 {
-	printk(KERN_INFO "inserting floppy driver for " UTS_RELEASE "\n");
-
 	if (floppy)
 		parse_floppy_cfg_string(floppy);
 	return floppy_init();
diff -Nru a/drivers/block/genhd.c b/drivers/block/genhd.c
--- a/drivers/block/genhd.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/block/genhd.c	2005-03-01 23:38:57 -08:00
@@ -19,10 +19,11 @@
 
 static struct subsystem block_subsys;
 
+static DECLARE_MUTEX(block_subsys_sem);
+
 /*
  * Can be deleted altogether. Later.
  *
- * Modified under both block_subsys.rwsem and major_names_lock.
  */
 static struct blk_major_name {
 	struct blk_major_name *next;
@@ -30,14 +31,13 @@
 	char name[16];
 } *major_names[MAX_PROBE_HASH];
 
-static spinlock_t major_names_lock = SPIN_LOCK_UNLOCKED;
-
 /* index in the above - for now: assume no multimajor ranges */
 static inline int major_to_index(int major)
 {
 	return major % MAX_PROBE_HASH;
 }
 
+#ifdef CONFIG_PROC_FS
 /* get block device names in somewhat random order */
 int get_blkdev_list(char *p)
 {
@@ -46,24 +46,24 @@
 
 	len = sprintf(p, "\nBlock devices:\n");
 
-	down_read(&block_subsys.rwsem);
+	down(&block_subsys_sem);
 	for (i = 0; i < ARRAY_SIZE(major_names); i++) {
 		for (n = major_names[i]; n; n = n->next)
 			len += sprintf(p+len, "%3d %s\n",
 				       n->major, n->name);
 	}
-	up_read(&block_subsys.rwsem);
+	up(&block_subsys_sem);
 
 	return len;
 }
+#endif
 
 int register_blkdev(unsigned int major, const char *name)
 {
 	struct blk_major_name **n, *p;
 	int index, ret = 0;
-	unsigned long flags;
 
-	down_write(&block_subsys.rwsem);
+	down(&block_subsys_sem);
 
 	/* temporary */
 	if (major == 0) {
@@ -93,7 +93,6 @@
 	p->next = NULL;
 	index = major_to_index(major);
 
-	spin_lock_irqsave(&major_names_lock, flags);
 	for (n = &major_names[index]; *n; n = &(*n)->next) {
 		if ((*n)->major == major)
 			break;
@@ -102,7 +101,6 @@
 		*n = p;
 	else
 		ret = -EBUSY;
-	spin_unlock_irqrestore(&major_names_lock, flags);
 
 	if (ret < 0) {
 		printk("register_blkdev: cannot get major %d for %s\n",
@@ -110,7 +108,7 @@
 		kfree(p);
 	}
 out:
-	up_write(&block_subsys.rwsem);
+	up(&block_subsys_sem);
 	return ret;
 }
 
@@ -122,11 +120,9 @@
 	struct blk_major_name **n;
 	struct blk_major_name *p = NULL;
 	int index = major_to_index(major);
-	unsigned long flags;
 	int ret = 0;
 
-	down_write(&block_subsys.rwsem);
-	spin_lock_irqsave(&major_names_lock, flags);
+	down(&block_subsys_sem);
 	for (n = &major_names[index]; *n; n = &(*n)->next)
 		if ((*n)->major == major)
 			break;
@@ -136,8 +132,7 @@
 		p = *n;
 		*n = p->next;
 	}
-	spin_unlock_irqrestore(&major_names_lock, flags);
-	up_write(&block_subsys.rwsem);
+	up(&block_subsys_sem);
 	kfree(p);
 
 	return ret;
@@ -231,7 +226,7 @@
 	struct list_head *p;
 	loff_t l = *pos;
 
-	down_read(&block_subsys.rwsem);
+	down(&block_subsys_sem);
 	list_for_each(p, &block_subsys.kset.list)
 		if (!l--)
 			return list_entry(p, struct gendisk, kobj.entry);
@@ -248,7 +243,7 @@
 
 static void part_stop(struct seq_file *part, void *v)
 {
-	up_read(&block_subsys.rwsem);
+	up(&block_subsys_sem);
 }
 
 static int show_partition(struct seq_file *part, void *v)
@@ -305,7 +300,7 @@
 	return NULL;
 }
 
-int __init device_init(void)
+static int __init genhd_device_init(void)
 {
 	bdev_map = kobj_map_init(base_probe, &block_subsys);
 	blk_dev_init();
@@ -313,19 +308,13 @@
 	return 0;
 }
 
-subsys_initcall(device_init);
+subsys_initcall(genhd_device_init);
 
 
 
 /*
  * kobject & sysfs bindings for block devices
  */
-
-struct disk_attribute {
-	struct attribute attr;
-	ssize_t (*show)(struct gendisk *, char *);
-};
-
 static ssize_t disk_attr_show(struct kobject *kobj, struct attribute *attr,
 			      char *page)
 {
@@ -506,7 +495,7 @@
 	loff_t k = *pos;
 	struct list_head *p;
 
-	down_read(&block_subsys.rwsem);
+	down(&block_subsys_sem);
 	list_for_each(p, &block_subsys.kset.list)
 		if (!k--)
 			return list_entry(p, struct gendisk, kobj.entry);
@@ -523,7 +512,7 @@
 
 static void diskstats_stop(struct seq_file *part, void *v)
 {
-	up_read(&block_subsys.rwsem);
+	up(&block_subsys_sem);
 }
 
 static int diskstats_show(struct seq_file *s, void *v)
@@ -671,9 +660,10 @@
 {
 	int res = 0;
 	struct block_device *bdev = bdget_disk(disk, index);
-	if (bdev)
+	if (bdev) {
 		res = __invalidate_device(bdev, 1);
-	bdput(bdev);
+		bdput(bdev);
+	}
 	return res;
 }
 
diff -Nru a/drivers/block/ida_cmd.h b/drivers/block/ida_cmd.h
--- a/drivers/block/ida_cmd.h	2005-03-01 23:38:54 -08:00
+++ b/drivers/block/ida_cmd.h	2005-03-01 23:38:54 -08:00
@@ -16,7 +16,7 @@
  *    along with this program; if not, write to the Free Software
  *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- *    Questions/Comments/Bugfixes to arrays@compaq.com
+ *    Questions/Comments/Bugfixes to iss_storagedev@hp.com
  *
  */
 #ifndef ARRAYCMD_H
diff -Nru a/drivers/block/ida_ioctl.h b/drivers/block/ida_ioctl.h
--- a/drivers/block/ida_ioctl.h	2005-03-01 23:38:57 -08:00
+++ b/drivers/block/ida_ioctl.h	2005-03-01 23:38:57 -08:00
@@ -16,7 +16,7 @@
  *    along with this program; if not, write to the Free Software
  *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- *    Questions/Comments/Bugfixes to arrays@compaq.com
+ *    Questions/Comments/Bugfixes to iss_storagedev@hp.com
  *
  */
 #ifndef IDA_IOCTL_H
diff -Nru a/drivers/block/ioctl.c b/drivers/block/ioctl.c
--- a/drivers/block/ioctl.c	2005-03-01 23:38:51 -08:00
+++ b/drivers/block/ioctl.c	2005-03-01 23:38:51 -08:00
@@ -3,6 +3,7 @@
 #include <linux/blkpg.h>
 #include <linux/backing-dev.h>
 #include <linux/buffer_head.h>
+#include <linux/smp_lock.h>
 #include <asm/uaccess.h>
 
 static int blkpg_ioctl(struct block_device *bdev, struct blkpg_ioctl_arg __user *arg)
@@ -219,4 +220,20 @@
 			return disk->fops->ioctl(inode, file, cmd, arg);
 	}
 	return -ENOTTY;
+}
+
+/* Most of the generic ioctls are handled in the normal fallback path.
+   This assumes the blkdev's low level compat_ioctl always returns
+   ENOIOCTLCMD for unknown ioctls. */
+long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
+{
+	struct block_device *bdev = file->f_dentry->d_inode->i_bdev;
+	struct gendisk *disk = bdev->bd_disk;
+	int ret = -ENOIOCTLCMD;
+	if (disk->fops->compat_ioctl) {
+		lock_kernel();
+		ret = disk->fops->compat_ioctl(file, cmd, arg);
+		unlock_kernel();
+	}
+	return ret;
 }
diff -Nru a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c
--- a/drivers/block/ll_rw_blk.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/block/ll_rw_blk.c	2005-03-01 23:38:52 -08:00
@@ -1438,6 +1438,7 @@
 	struct request_list *rl = &q->rq;
 
 	rl->count[READ] = rl->count[WRITE] = 0;
+	rl->starved[READ] = rl->starved[WRITE] = 0;
 	init_waitqueue_head(&rl->wait[READ]);
 	init_waitqueue_head(&rl->wait[WRITE]);
 	init_waitqueue_head(&rl->drain);
@@ -1618,6 +1619,22 @@
 	ioc->last_waited = jiffies;
 }
 
+static void __freed_request(request_queue_t *q, int rw)
+{
+	struct request_list *rl = &q->rq;
+
+	if (rl->count[rw] < queue_congestion_off_threshold(q))
+		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]);
+
+		blk_clear_queue_full(q, rw);
+	}
+}
+
 /*
  * A request has just been released.  Account for it, update the full and
  * congestion status, wake up any waiters.   Called under q->queue_lock.
@@ -1627,17 +1644,17 @@
 	struct request_list *rl = &q->rq;
 
 	rl->count[rw]--;
-	if (rl->count[rw] < queue_congestion_off_threshold(q))
-		clear_queue_congested(q, rw);
-	if (rl->count[rw]+1 <= q->nr_requests) {
+
+	__freed_request(q, rw);
+
+	if (unlikely(rl->starved[rw ^ 1]))
+		__freed_request(q, rw ^ 1);
+
+	if (!rl->count[READ] && !rl->count[WRITE]) {
 		smp_mb();
-		if (waitqueue_active(&rl->wait[rw]))
-			wake_up(&rl->wait[rw]);
-		blk_clear_queue_full(q, rw);
+		if (unlikely(waitqueue_active(&rl->drain)))
+			wake_up(&rl->drain);
 	}
-	if (unlikely(waitqueue_active(&rl->drain)) &&
-	    !rl->count[READ] && !rl->count[WRITE])
-		wake_up(&rl->drain);
 }
 
 #define blkdev_free_rq(list) list_entry((list)->next, struct request, queuelist)
@@ -1669,8 +1686,7 @@
 
 	switch (elv_may_queue(q, rw)) {
 		case ELV_MQUEUE_NO:
-			spin_unlock_irq(q->queue_lock);
-			goto out;
+			goto rq_starved;
 		case ELV_MQUEUE_MAY:
 			break;
 		case ELV_MQUEUE_MUST:
@@ -1688,6 +1704,7 @@
 
 get_rq:
 	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);
@@ -1703,6 +1720,18 @@
 		 */
 		spin_lock_irq(q->queue_lock);
 		freed_request(q, rw);
+
+		/*
+		 * in the very unlikely event that allocation failed and no
+		 * requests for this direction was pending, mark us starved
+		 * so that freeing of a request in the other direction will
+		 * notice us. another possible fix would be to split the
+		 * rq mempool into READ and WRITE
+		 */
+rq_starved:
+		if (unlikely(rl->count[rw] == 0))
+			rl->starved[rw] = 1;
+
 		spin_unlock_irq(q->queue_lock);
 		goto out;
 	}
diff -Nru a/drivers/block/loop.c b/drivers/block/loop.c
--- a/drivers/block/loop.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/block/loop.c	2005-03-01 23:38:58 -08:00
@@ -622,10 +622,17 @@
 	return error;
 }
 
+static inline int is_loop_device(struct file *file)
+{
+	struct inode *i = file->f_mapping->host;
+
+	return i && S_ISBLK(i->i_mode) && MAJOR(i->i_rdev) == LOOP_MAJOR;
+}
+
 static int loop_set_fd(struct loop_device *lo, struct file *lo_file,
 		       struct block_device *bdev, unsigned int arg)
 {
-	struct file	*file;
+	struct file	*file, *f;
 	struct inode	*inode;
 	struct address_space *mapping;
 	unsigned lo_blocksize;
@@ -636,14 +643,30 @@
 	/* This is safe, since we have a reference from open(). */
 	__module_get(THIS_MODULE);
 
-	error = -EBUSY;
-	if (lo->lo_state != Lo_unbound)
-		goto out;
-
 	error = -EBADF;
 	file = fget(arg);
 	if (!file)
 		goto out;
+
+	error = -EBUSY;
+	if (lo->lo_state != Lo_unbound)
+		goto out_putf;
+
+	/* Avoid recursion */
+	f = file;
+	while (is_loop_device(f)) {
+		struct loop_device *l;
+
+		if (f->f_mapping->host->i_rdev == lo_file->f_mapping->host->i_rdev)
+			goto out_putf;
+
+		l = f->f_mapping->host->i_bdev->bd_disk->private_data;
+		if (l->lo_state == Lo_unbound) {
+			error = -EINVAL;
+			goto out_putf;
+		}
+		f = l->lo_backing_file;
+	}
 
 	mapping = file->f_mapping;
 	inode = mapping->host;
diff -Nru a/drivers/block/nbd.c b/drivers/block/nbd.c
--- a/drivers/block/nbd.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/block/nbd.c	2005-03-01 23:38:53 -08:00
@@ -92,7 +92,7 @@
  *    a single lock.
  * Thanks go to Jens Axboe and Al Viro for their LKML emails explaining this!
  */
-static spinlock_t nbd_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(nbd_lock);
 
 #ifndef NDEBUG
 static const char *ioctl_cmd_to_ascii(int cmd)
@@ -726,6 +726,6 @@
 MODULE_LICENSE("GPL");
 
 #ifndef NDEBUG
-MODULE_PARM(debugflags, "i");
+module_param(debugflags, int, 0644);
 MODULE_PARM_DESC(debugflags, "flags for controlling debug output");
 #endif
diff -Nru a/drivers/block/noop-iosched.c b/drivers/block/noop-iosched.c
--- a/drivers/block/noop-iosched.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/block/noop-iosched.c	2005-03-01 23:39:07 -08:00
@@ -1,24 +1,17 @@
 /*
  * elevator noop
  */
-#include <linux/kernel.h>
-#include <linux/fs.h>
 #include <linux/blkdev.h>
 #include <linux/elevator.h>
 #include <linux/bio.h>
-#include <linux/config.h>
 #include <linux/module.h>
-#include <linux/slab.h>
 #include <linux/init.h>
-#include <linux/compiler.h>
-
-#include <asm/uaccess.h>
 
 /*
  * See if we can find a request that this buffer can be coalesced with.
  */
-int elevator_noop_merge(request_queue_t *q, struct request **req,
-			struct bio *bio)
+static int elevator_noop_merge(request_queue_t *q, struct request **req,
+			       struct bio *bio)
 {
 	struct list_head *entry = &q->queue_head;
 	struct request *__rq;
@@ -50,21 +43,19 @@
 	return ELEVATOR_NO_MERGE;
 }
 
-void elevator_noop_merge_requests(request_queue_t *q, struct request *req,
-				  struct request *next)
+static void elevator_noop_merge_requests(request_queue_t *q, struct request *req,
+					 struct request *next)
 {
 	list_del_init(&next->queuelist);
 }
 
-void elevator_noop_add_request(request_queue_t *q, struct request *rq,
-			       int where)
+static void elevator_noop_add_request(request_queue_t *q, struct request *rq,
+				      int where)
 {
-	struct list_head *insert = q->queue_head.prev;
-
 	if (where == ELEVATOR_INSERT_FRONT)
-		insert = &q->queue_head;
-
-	list_add_tail(&rq->queuelist, &q->queue_head);
+		list_add(&rq->queuelist, &q->queue_head);
+	else
+		list_add_tail(&rq->queuelist, &q->queue_head);
 
 	/*
 	 * new merges must not precede this barrier
@@ -75,7 +66,7 @@
 		q->last_merge = rq;
 }
 
-struct request *elevator_noop_next_request(request_queue_t *q)
+static struct request *elevator_noop_next_request(request_queue_t *q)
 {
 	if (!list_empty(&q->queue_head))
 		return list_entry_rq(q->queue_head.next);
@@ -94,12 +85,12 @@
 	.elevator_owner = THIS_MODULE,
 };
 
-int noop_init(void)
+static int __init noop_init(void)
 {
 	return elv_register(&elevator_noop);
 }
 
-void noop_exit(void)
+static void __exit noop_exit(void)
 {
 	elv_unregister(&elevator_noop);
 }
diff -Nru a/drivers/block/paride/Kconfig b/drivers/block/paride/Kconfig
--- a/drivers/block/paride/Kconfig	2005-03-01 23:38:44 -08:00
+++ b/drivers/block/paride/Kconfig	2005-03-01 23:38:44 -08:00
@@ -119,7 +119,7 @@
 	  before 1999 were Series 5) Series 5 drives will NOT always have the
 	  Series noted on the bottom of the drive. Series 6 drivers will.
 
-	  In other words, if your BACKPACK drive dosen't say "Series 6" on the
+	  In other words, if your BACKPACK drive doesn't say "Series 6" on the
 	  bottom, enable this option.
 
 	  If you chose to build PARIDE support into your kernel, you may
diff -Nru a/drivers/block/paride/bpck6.c b/drivers/block/paride/bpck6.c
--- a/drivers/block/paride/bpck6.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/block/paride/bpck6.c	2005-03-01 23:39:18 -08:00
@@ -277,6 +277,6 @@
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Micro Solutions Inc.");
 MODULE_DESCRIPTION("BACKPACK Protocol module, compatible with PARIDE");
-MODULE_PARM(verbose,"i");
+module_param(verbose, bool, 0644);
 module_init(bpck6_init)
 module_exit(bpck6_exit)
diff -Nru a/drivers/block/paride/paride.c b/drivers/block/paride/paride.c
--- a/drivers/block/paride/paride.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/block/paride/paride.c	2005-03-01 23:38:52 -08:00
@@ -46,7 +46,7 @@
 
 static struct pi_protocol *protocols[MAX_PROTOS];
 
-static spinlock_t pi_spinlock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(pi_spinlock);
 
 void pi_write_regr(PIA * pi, int cont, int regr, int val)
 {
diff -Nru a/drivers/block/paride/pcd.c b/drivers/block/paride/pcd.c
--- a/drivers/block/paride/pcd.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/block/paride/pcd.c	2005-03-01 23:39:17 -08:00
@@ -162,14 +162,14 @@
 
 #endif
 
-MODULE_PARM(verbose, "i");
-MODULE_PARM(major, "i");
-MODULE_PARM(name, "s");
-MODULE_PARM(nice, "i");
-MODULE_PARM(drive0, "1-6i");
-MODULE_PARM(drive1, "1-6i");
-MODULE_PARM(drive2, "1-6i");
-MODULE_PARM(drive3, "1-6i");
+module_param(verbose, bool, 0644);
+module_param(major, int, 0);
+module_param(name, charp, 0);
+module_param(nice, int, 0);
+module_param_array(drive0, int, NULL, 0);
+module_param_array(drive1, int, NULL, 0);
+module_param_array(drive2, int, NULL, 0);
+module_param_array(drive3, int, NULL, 0);
 
 #include "paride.h"
 #include "pseudo.h"
diff -Nru a/drivers/block/paride/pd.c b/drivers/block/paride/pd.c
--- a/drivers/block/paride/pd.c	2005-03-01 23:39:19 -08:00
+++ b/drivers/block/paride/pd.c	2005-03-01 23:39:19 -08:00
@@ -155,7 +155,7 @@
 #include <linux/sched.h>
 #include <linux/workqueue.h>
 
-static spinlock_t pd_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(pd_lock);
 
 #ifndef MODULE
 
@@ -178,15 +178,15 @@
 
 #endif
 
-MODULE_PARM(verbose, "i");
-MODULE_PARM(major, "i");
-MODULE_PARM(name, "s");
-MODULE_PARM(cluster, "i");
-MODULE_PARM(nice, "i");
-MODULE_PARM(drive0, "1-8i");
-MODULE_PARM(drive1, "1-8i");
-MODULE_PARM(drive2, "1-8i");
-MODULE_PARM(drive3, "1-8i");
+module_param(verbose, bool, 0);
+module_param(major, int, 0);
+module_param(name, charp, 0);
+module_param(cluster, int, 0);
+module_param(nice, int, 0);
+module_param_array(drive0, int, NULL, 0);
+module_param_array(drive1, int, NULL, 0);
+module_param_array(drive2, int, NULL, 0);
+module_param_array(drive3, int, NULL, 0);
 
 #include "paride.h"
 
diff -Nru a/drivers/block/paride/pf.c b/drivers/block/paride/pf.c
--- a/drivers/block/paride/pf.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/block/paride/pf.c	2005-03-01 23:39:07 -08:00
@@ -177,15 +177,15 @@
 
 #endif
 
-MODULE_PARM(verbose, "i");
-MODULE_PARM(major, "i");
-MODULE_PARM(name, "s");
-MODULE_PARM(cluster, "i");
-MODULE_PARM(nice, "i");
-MODULE_PARM(drive0, "1-7i");
-MODULE_PARM(drive1, "1-7i");
-MODULE_PARM(drive2, "1-7i");
-MODULE_PARM(drive3, "1-7i");
+module_param(verbose, bool, 0644);
+module_param(major, int, 0);
+module_param(name, charp, 0);
+module_param(cluster, int, 0);
+module_param(nice, int, 0);
+module_param_array(drive0, int, NULL, 0);
+module_param_array(drive1, int, NULL, 0);
+module_param_array(drive2, int, NULL, 0);
+module_param_array(drive3, int, NULL, 0);
 
 #include "paride.h"
 #include "pseudo.h"
diff -Nru a/drivers/block/paride/pg.c b/drivers/block/paride/pg.c
--- a/drivers/block/paride/pg.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/block/paride/pg.c	2005-03-01 23:39:09 -08:00
@@ -184,13 +184,13 @@
 
 #endif
 
-MODULE_PARM(verbose, "i");
-MODULE_PARM(major, "i");
-MODULE_PARM(name, "s");
-MODULE_PARM(drive0, "1-6i");
-MODULE_PARM(drive1, "1-6i");
-MODULE_PARM(drive2, "1-6i");
-MODULE_PARM(drive3, "1-6i");
+module_param(verbose, bool, 0644);
+module_param(major, int, 0);
+module_param(name, charp, 0);
+module_param_array(drive0, int, NULL, 0);
+module_param_array(drive1, int, NULL, 0);
+module_param_array(drive2, int, NULL, 0);
+module_param_array(drive3, int, NULL, 0);
 
 #include "paride.h"
 
diff -Nru a/drivers/block/paride/pseudo.h b/drivers/block/paride/pseudo.h
--- a/drivers/block/paride/pseudo.h	2005-03-01 23:38:54 -08:00
+++ b/drivers/block/paride/pseudo.h	2005-03-01 23:38:54 -08:00
@@ -43,7 +43,7 @@
 static int ps_tq_active = 0;
 static int ps_nice = 0;
 
-static spinlock_t ps_spinlock __attribute__((unused)) = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(ps_spinlock __attribute__((unused)));
 
 static DECLARE_WORK(ps_tq, ps_tq_int, NULL);
 
diff -Nru a/drivers/block/paride/pt.c b/drivers/block/paride/pt.c
--- a/drivers/block/paride/pt.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/block/paride/pt.c	2005-03-01 23:38:54 -08:00
@@ -169,13 +169,13 @@
 
 #endif
 
-MODULE_PARM(verbose, "i");
-MODULE_PARM(major, "i");
-MODULE_PARM(name, "s");
-MODULE_PARM(drive0, "1-6i");
-MODULE_PARM(drive1, "1-6i");
-MODULE_PARM(drive2, "1-6i");
-MODULE_PARM(drive3, "1-6i");
+module_param(verbose, bool, 0);
+module_param(major, int, 0);
+module_param(name, charp, 0);
+module_param_array(drive0, int, NULL, 0);
+module_param_array(drive1, int, NULL, 0);
+module_param_array(drive2, int, NULL, 0);
+module_param_array(drive3, int, NULL, 0);
 
 #include "paride.h"
 
diff -Nru a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
--- a/drivers/block/pktcdvd.c	2005-03-01 23:38:44 -08:00
+++ b/drivers/block/pktcdvd.c	2005-03-01 23:38:44 -08:00
@@ -135,12 +135,10 @@
 		goto no_bio;
 
 	for (i = 0; i < PAGES_PER_PACKET; i++) {
-		pkt->pages[i] = alloc_page(GFP_KERNEL);
+		pkt->pages[i] = alloc_page(GFP_KERNEL|__GFP_ZERO);
 		if (!pkt->pages[i])
 			goto no_page;
 	}
-	for (i = 0; i < PAGES_PER_PACKET; i++)
-		clear_page(page_address(pkt->pages[i]));
 
 	spin_lock_init(&pkt->lock);
 
@@ -607,8 +605,7 @@
 /*
  * Copy CD_FRAMESIZE bytes from src_bio into a destination page
  */
-static void pkt_copy_bio_data(struct bio *src_bio, int seg, int offs,
-			      struct page *dst_page, int dst_offs)
+static void pkt_copy_bio_data(struct bio *src_bio, int seg, int offs, struct page *dst_page, int dst_offs)
 {
 	unsigned int copy_size = CD_FRAMESIZE;
 
@@ -1301,8 +1298,7 @@
 	printk("Mode-%c disc\n", pd->settings.block_mode == 8 ? '1' : '2');
 }
 
-static int pkt_mode_sense(struct pktcdvd_device *pd, struct packet_command *cgc,
-			  int page_code, int page_control)
+static int pkt_mode_sense(struct pktcdvd_device *pd, struct packet_command *cgc, int page_code, int page_control)
 {
 	memset(cgc->cmd, 0, sizeof(cgc->cmd));
 
@@ -2627,7 +2623,7 @@
 	.fops  		= &pkt_ctl_fops
 };
 
-int pkt_init(void)
+static int pkt_init(void)
 {
 	int ret;
 
@@ -2663,7 +2659,7 @@
 	return ret;
 }
 
-void pkt_exit(void)
+static void pkt_exit(void)
 {
 	remove_proc_entry("pktcdvd", proc_root_driver);
 	misc_deregister(&pkt_misc);
diff -Nru a/drivers/block/ps2esdi.c b/drivers/block/ps2esdi.c
--- a/drivers/block/ps2esdi.c	2005-03-01 23:38:44 -08:00
+++ b/drivers/block/ps2esdi.c	2005-03-01 23:38:44 -08:00
@@ -108,7 +108,7 @@
 struct ps2esdi_i_struct {
 	unsigned int head, sect, cyl, wpcom, lzone, ctl;
 };
-static spinlock_t ps2esdi_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(ps2esdi_lock);
 static struct request_queue *ps2esdi_queue;
 static struct request *current_req;
 
@@ -177,10 +177,10 @@
 static int head[MAX_HD] = {-1, -1};
 static int sect[MAX_HD] = {-1, -1};
 
-MODULE_PARM(tp720esdi, "i");
-MODULE_PARM(cyl, "i");
-MODULE_PARM(head, "i");
-MODULE_PARM(sect, "i");
+module_param(tp720esdi, bool, 0);
+module_param_array(cyl, int, NULL, 0);
+module_param_array(head, int, NULL, 0);
+module_param_array(sect, int, NULL, 0);
 MODULE_LICENSE("GPL");
 
 int init_module(void) {
diff -Nru a/drivers/block/scsi_ioctl.c b/drivers/block/scsi_ioctl.c
--- a/drivers/block/scsi_ioctl.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/block/scsi_ioctl.c	2005-03-01 23:39:17 -08:00
@@ -199,7 +199,7 @@
 			return 0;
 	}
 
-	if (!(type & CMD_WARNED)) {
+	if (!type) {
 		cmd_type[cmd[0]] = CMD_WARNED;
 		printk(KERN_WARNING "scsi: unknown opcode 0x%02x\n", cmd[0]);
 	}
@@ -339,7 +339,8 @@
 			 struct gendisk *bd_disk, Scsi_Ioctl_Command __user *sic)
 {
 	struct request *rq;
-	int err, in_len, out_len, bytes, opcode, cmdlen;
+	int err;
+	unsigned int in_len, out_len, bytes, opcode, cmdlen;
 	char *buffer = NULL, sense[SCSI_SENSE_BUFFERSIZE];
 
 	/*
@@ -356,7 +357,7 @@
 
 	bytes = max(in_len, out_len);
 	if (bytes) {
-		buffer = kmalloc(bytes, q->bounce_gfp | GFP_USER);
+		buffer = kmalloc(bytes, q->bounce_gfp | GFP_USER| __GFP_NOWARN);
 		if (!buffer)
 			return -ENOMEM;
 
diff -Nru a/drivers/block/smart1,2.h b/drivers/block/smart1,2.h
--- a/drivers/block/smart1,2.h	2005-03-01 23:38:59 -08:00
+++ b/drivers/block/smart1,2.h	2005-03-01 23:38:59 -08:00
@@ -16,7 +16,7 @@
  *    along with this program; if not, write to the Free Software
  *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- *    Questions/Comments/Bugfixes to arrays@compaq.com
+ *    Questions/Comments/Bugfixes to iss_storagedev@hp.com
  *
  *    If you want to make changes, improve or add functionality to this
  *    driver, you'll probably need the Compaq Array Controller Interface
diff -Nru a/drivers/block/swim3.c b/drivers/block/swim3.c
--- a/drivers/block/swim3.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/block/swim3.c	2005-03-01 23:38:55 -08:00
@@ -206,7 +206,7 @@
 
 static struct floppy_state floppy_states[MAX_FLOPPIES];
 static int floppy_count = 0;
-static spinlock_t swim3_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(swim3_lock);
 
 static unsigned short write_preamble[] = {
 	0x4e4e, 0x4e4e, 0x4e4e, 0x4e4e, 0x4e4e,	/* gap field */
diff -Nru a/drivers/block/swim_iop.c b/drivers/block/swim_iop.c
--- a/drivers/block/swim_iop.c	2005-03-01 23:38:44 -08:00
+++ b/drivers/block/swim_iop.c	2005-03-01 23:38:44 -08:00
@@ -76,7 +76,7 @@
 static int floppy_count;
 
 static struct floppy_state floppy_states[MAX_FLOPPIES];
-static spinlock_t swim_iop_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(swim_iop_lock);
 
 #define CURRENT elv_next_request(swim_queue)
 
diff -Nru a/drivers/block/sx8.c b/drivers/block/sx8.c
--- a/drivers/block/sx8.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/block/sx8.c	2005-03-01 23:39:18 -08:00
@@ -1503,7 +1503,8 @@
 		}
 
 		port->disk = disk;
-		sprintf(disk->disk_name, DRV_NAME "%u_%u", host->id, i);
+		sprintf(disk->disk_name, DRV_NAME "/%u",
+			(unsigned int) (host->id * CARM_MAX_PORTS) + i);
 		sprintf(disk->devfs_name, DRV_NAME "/%u_%u", host->id, i);
 		disk->major = host->major;
 		disk->first_minor = i * CARM_MINORS_PER_MAJOR;
diff -Nru a/drivers/block/ub.c b/drivers/block/ub.c
--- a/drivers/block/ub.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/block/ub.c	2005-03-01 23:39:17 -08:00
@@ -108,7 +108,8 @@
  */
 #define UB_URB_TIMEOUT	(HZ*2)
 #define UB_DATA_TIMEOUT	(HZ*5)	/* ZIP does spin-ups in the data phase */
-#define UB_CTRL_TIMEOUT	(HZ/2) /* 500ms ought to be enough to clear a stall */
+#define UB_STAT_TIMEOUT	(HZ*5)	/* Same spinups and eject for a dataless cmd. */
+#define UB_CTRL_TIMEOUT	(HZ/2)	/* 500ms ought to be enough to clear a stall */
 
 /*
  * An instance of a SCSI command in transit.
@@ -299,6 +300,11 @@
 
 /*
  */
+static int ub_bd_rq_fn_1(struct ub_dev *sc, struct request *rq);
+static int ub_cmd_build_block(struct ub_dev *sc, struct ub_scsi_cmd *cmd,
+    struct request *rq);
+static int ub_cmd_build_packet(struct ub_dev *sc, struct ub_scsi_cmd *cmd,
+    struct request *rq);
 static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd);
 static void ub_end_rq(struct request *rq, int uptodate);
 static int ub_submit_scsi(struct ub_dev *sc, struct ub_scsi_cmd *cmd);
@@ -307,6 +313,7 @@
 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 void ub_state_stat(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,
@@ -334,7 +341,7 @@
  */
 #define UB_MAX_HOSTS  26
 static char ub_hostv[UB_MAX_HOSTS];
-static spinlock_t ub_lock = SPIN_LOCK_UNLOCKED;	/* Locks globals and ->openc */
+static DEFINE_SPINLOCK(ub_lock);	/* Locks globals and ->openc */
 
 /*
  * The SCSI command tracing procedures.
@@ -589,40 +596,73 @@
  * The request function is our main entry point
  */
 
-static inline int ub_bd_rq_fn_1(request_queue_t *q)
+static void ub_bd_rq_fn(request_queue_t *q)
 {
-#if 0
-	int writing = 0, pci_dir, i, n_elem;
-	u32 tmp;
-	unsigned int msg_size;
-#endif
 	struct ub_dev *sc = q->queuedata;
 	struct request *rq;
-#if 0 /* We use rq->buffer for now */
-	struct scatterlist *sg;
-	int n_elem;
-#endif
+
+	while ((rq = elv_next_request(q)) != NULL) {
+		if (ub_bd_rq_fn_1(sc, rq) != 0) {
+			blk_stop_queue(q);
+			break;
+		}
+	}
+}
+
+static int ub_bd_rq_fn_1(struct ub_dev *sc, struct request *rq)
+{
 	struct ub_scsi_cmd *cmd;
-	int ub_dir;
-	unsigned int block, nblks;
 	int rc;
 
-	if ((rq = elv_next_request(q)) == NULL)
-		return 1;
-
 	if (atomic_read(&sc->poison) || sc->changed) {
 		blkdev_dequeue_request(rq);
 		ub_end_rq(rq, 0);
 		return 0;
 	}
 
-	if ((cmd = ub_get_cmd(sc)) == NULL) {
-		blk_stop_queue(q);
-		return 1;
-	}
+	if ((cmd = ub_get_cmd(sc)) == NULL)
+		return -1;
+	memset(cmd, 0, sizeof(struct ub_scsi_cmd));
 
 	blkdev_dequeue_request(rq);
 
+	if (blk_pc_request(rq)) {
+		rc = ub_cmd_build_packet(sc, cmd, rq);
+	} else {
+		rc = ub_cmd_build_block(sc, cmd, rq);
+	}
+	if (rc != 0) {
+		ub_put_cmd(sc, cmd);
+		ub_end_rq(rq, 0);
+		blk_start_queue(sc->disk->queue);
+		return 0;
+	}
+
+	cmd->state = UB_CMDST_INIT;
+	cmd->done = ub_rw_cmd_done;
+	cmd->back = rq;
+
+	cmd->tag = sc->tagcnt++;
+	if ((rc = ub_submit_scsi(sc, cmd)) != 0) {
+		ub_put_cmd(sc, cmd);
+		ub_end_rq(rq, 0);
+		blk_start_queue(sc->disk->queue);
+		return 0;
+	}
+
+	return 0;
+}
+
+static int ub_cmd_build_block(struct ub_dev *sc, struct ub_scsi_cmd *cmd,
+    struct request *rq)
+{
+	int ub_dir;
+#if 0 /* We use rq->buffer for now */
+	struct scatterlist *sg;
+	int n_elem;
+#endif
+	unsigned int block, nblks;
+
 	if (rq_data_dir(rq) == WRITE)
 		ub_dir = UB_DIR_WRITE;
 	else
@@ -650,6 +690,7 @@
 		return 0;
 	}
 #endif
+
 	/*
 	 * XXX Unfortunately, this check does not work. It is quite possible
 	 * to get bogus non-null rq->buffer if you allow sg by mistake.
@@ -661,13 +702,12 @@
 		 */
 		static int do_print = 1;
 		if (do_print) {
-			printk(KERN_WARNING "%s: unmapped request\n", sc->name);
+			printk(KERN_WARNING "%s: unmapped block request"
+			    " flags 0x%lx sectors %lu\n",
+			    sc->name, rq->flags, rq->nr_sectors);
 			do_print = 0;
 		}
-		ub_put_cmd(sc, cmd);
-		ub_end_rq(rq, 0);
-		blk_start_queue(q);
-		return 0;
+		return -1;
 	}
 
 	/*
@@ -679,7 +719,6 @@
 	block = rq->sector >> sc->capacity.bshift;
 	nblks = rq->nr_sectors >> sc->capacity.bshift;
 
-	memset(cmd, 0, sizeof(struct ub_scsi_cmd));
 	cmd->cdb[0] = (ub_dir == UB_DIR_READ)? READ_10: WRITE_10;
 	/* 10-byte uses 4 bytes of LBA: 2147483648KB, 2097152MB, 2048GB */
 	cmd->cdb[2] = block >> 24;
@@ -689,27 +728,44 @@
 	cmd->cdb[7] = nblks >> 8;
 	cmd->cdb[8] = nblks;
 	cmd->cdb_len = 10;
+
 	cmd->dir = ub_dir;
-	cmd->state = UB_CMDST_INIT;
 	cmd->data = rq->buffer;
 	cmd->len = rq->nr_sectors * 512;
-	cmd->done = ub_rw_cmd_done;
-	cmd->back = rq;
-
-	cmd->tag = sc->tagcnt++;
-	if ((rc = ub_submit_scsi(sc, cmd)) != 0) {
-		ub_put_cmd(sc, cmd);
-		ub_end_rq(rq, 0);
-		blk_start_queue(q);
-		return 0;
-	}
 
 	return 0;
 }
 
-static void ub_bd_rq_fn(request_queue_t *q)
+static int ub_cmd_build_packet(struct ub_dev *sc, struct ub_scsi_cmd *cmd,
+    struct request *rq)
 {
-	do { } while (ub_bd_rq_fn_1(q) == 0);
+
+	if (rq->data_len != 0 && rq->data == NULL) {
+		static int do_print = 1;
+		if (do_print) {
+			printk(KERN_WARNING "%s: unmapped packet request"
+			    " flags 0x%lx length %d\n",
+			    sc->name, rq->flags, rq->data_len);
+			do_print = 0;
+		}
+		return -1;
+	}
+
+	memcpy(&cmd->cdb, rq->cmd, rq->cmd_len);
+	cmd->cdb_len = rq->cmd_len;
+
+	if (rq->data_len == 0) {
+		cmd->dir = UB_DIR_NONE;
+	} else {
+		if (rq_data_dir(rq) == WRITE)
+			cmd->dir = UB_DIR_WRITE;
+		else
+			cmd->dir = UB_DIR_READ;
+	}
+	cmd->data = rq->data;
+	cmd->len = rq->data_len;
+
+	return 0;
 }
 
 static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
@@ -719,6 +775,12 @@
 	request_queue_t *q = disk->queue;
 	int uptodate;
 
+	if (blk_pc_request(rq)) {
+		/* UB_SENSE_SIZE is smaller than SCSI_SENSE_BUFFERSIZE */
+		memcpy(rq->sense, sc->top_sense, UB_SENSE_SIZE);
+		rq->sense_len = UB_SENSE_SIZE;
+	}
+
 	if (cmd->error == 0)
 		uptodate = 1;
 	else
@@ -777,6 +839,17 @@
 
 	bcb = &sc->work_bcb;
 
+	/*
+	 * ``If the allocation length is eighteen or greater, and a device
+	 * server returns less than eithteen bytes of data, the application
+	 * client should assume that the bytes not transferred would have been
+	 * zeroes had the device server returned those bytes.''
+	 *
+	 * We zero sense for all commands so that when a packet request
+	 * fails it does not return a stale sense.
+	 */
+	memset(&sc->top_sense, 0, UB_SENSE_SIZE);
+
 	/* set up the command wrapper */
 	bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
 	bcb->Tag = cmd->tag;		/* Endianness is not important */
@@ -894,7 +967,7 @@
 		if (urb->status == -EPIPE) {
 			/*
 			 * STALL while clearning STALL.
-			 * A STALL is illegal on a control pipe!
+			 * The control pipe clears itself - nothing to do.
 			 * XXX Might try to reset the device here and retry.
 			 */
 			printk(KERN_NOTICE "%s: "
@@ -917,7 +990,7 @@
 		if (urb->status == -EPIPE) {
 			/*
 			 * STALL while clearning STALL.
-			 * A STALL is illegal on a control pipe!
+			 * The control pipe clears itself - nothing to do.
 			 * XXX Might try to reset the device here and retry.
 			 */
 			printk(KERN_NOTICE "%s: "
@@ -941,7 +1014,8 @@
 			rc = ub_submit_clear_stall(sc, cmd, sc->last_pipe);
 			if (rc != 0) {
 				printk(KERN_NOTICE "%s: "
-				    "unable to submit clear for device %u (%d)\n",
+				    "unable to submit clear for device %u"
+				    " (code %d)\n",
 				    sc->name, sc->dev->devnum, rc);
 				/*
 				 * This is typically ENOMEM or some other such shit.
@@ -1001,7 +1075,8 @@
 			rc = ub_submit_clear_stall(sc, cmd, sc->last_pipe);
 			if (rc != 0) {
 				printk(KERN_NOTICE "%s: "
-				    "unable to submit clear for device %u (%d)\n",
+				    "unable to submit clear for device %u"
+				    " (code %d)\n",
 				    sc->name, sc->dev->devnum, rc);
 				/*
 				 * This is typically ENOMEM or some other such shit.
@@ -1033,7 +1108,8 @@
 			rc = ub_submit_clear_stall(sc, cmd, sc->last_pipe);
 			if (rc != 0) {
 				printk(KERN_NOTICE "%s: "
-				    "unable to submit clear for device %u (%d)\n",
+				    "unable to submit clear for device %u"
+				    " (code %d)\n",
 				    sc->name, sc->dev->devnum, rc);
 				/*
 				 * This is typically ENOMEM or some other such shit.
@@ -1061,33 +1137,7 @@
 				    sc->name, sc->dev->devnum);
 				goto Bad_End;
 			}
-
-			/*
-			 * ub_state_stat only not dropping the count...
-			 */
-			UB_INIT_COMPLETION(sc->work_done);
-
-			sc->last_pipe = sc->recv_bulk_pipe;
-			usb_fill_bulk_urb(&sc->work_urb, sc->dev,
-			    sc->recv_bulk_pipe, &sc->work_bcs,
-			    US_BULK_CS_WRAP_LEN, ub_urb_complete, sc);
-			sc->work_urb.transfer_flags = URB_ASYNC_UNLINK;
-			sc->work_urb.actual_length = 0;
-			sc->work_urb.error_count = 0;
-			sc->work_urb.status = 0;
-
-			rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC);
-			if (rc != 0) {
-				/* XXX Clear stalls */
-				printk("%s: CSW #%d submit failed (%d)\n",
-				   sc->name, cmd->tag, rc); /* P3 */
-				ub_complete(&sc->work_done);
-				ub_state_done(sc, cmd, rc);
-				return;
-			}
-
-			sc->work_timer.expires = jiffies + UB_URB_TIMEOUT;
-			add_timer(&sc->work_timer);
+			__ub_state_stat(sc, cmd);
 			return;
 		}
 
@@ -1108,17 +1158,31 @@
 			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)) {
-			/* XXX Rate-limit, even for P3 tagged */
-			/* P3 */ printk("ub: signature 0x%x\n", bcs->Signature);
 			/* Windows ignores signatures, so do we. */
 		}
+#endif
 
 		if (bcs->Tag != cmd->tag) {
-			/* P3 */ printk("%s: tag orig 0x%x reply 0x%x\n",
-			    sc->name, cmd->tag, bcs->Tag);
-			goto Bad_End;
+			/*
+			 * This usually happens when we disagree with the
+			 * device's microcode about something. For instance,
+			 * a few of them throw this after timeouts. They buffer
+			 * 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 "
+				    "on device %u\n",
+				    sc->name, cmd->tag, bcs->Tag,
+				    sc->dev->devnum);
+				goto Bad_End;
+			}
+			__ub_state_stat(sc, cmd);
+			return;
 		}
 
 		switch (bcs->Status) {
@@ -1174,9 +1238,9 @@
 
 /*
  * Factorization helper for the command state machine:
- * Submit a CSW read and go to STAT state.
+ * Submit a CSW read.
  */
-static void 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)
 {
 	int rc;
 
@@ -1192,14 +1256,23 @@
 
 	if ((rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC)) != 0) {
 		/* XXX Clear stalls */
-		printk("ub: CSW #%d submit failed (%d)\n", cmd->tag, rc); /* P3 */
+		printk("%s: CSW #%d submit failed (%d)\n", sc->name, cmd->tag, rc); /* P3 */
 		ub_complete(&sc->work_done);
 		ub_state_done(sc, cmd, rc);
 		return;
 	}
 
-	sc->work_timer.expires = jiffies + UB_URB_TIMEOUT;
+	sc->work_timer.expires = jiffies + UB_STAT_TIMEOUT;
 	add_timer(&sc->work_timer);
+}
+
+/*
+ * Factorization helper for the command state machine:
+ * Submit a CSW read and go to STAT state.
+ */
+static void ub_state_stat(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
+{
+	__ub_state_stat(sc, cmd);
 
 	cmd->stat_count = 0;
 	cmd->state = UB_CMDST_STAT;
@@ -1220,14 +1293,6 @@
 		goto error;
 	}
 
-	/*
-	 * ``If the allocation length is eighteen or greater, and a device
-	 * server returns less than eithteen bytes of data, the application
-	 * client should assume that the bytes not transferred would have been
-	 * zeroes had the device server returned those bytes.''
-	 */
-	memset(&sc->top_sense, 0, UB_SENSE_SIZE);
-
 	scmd = &sc->top_rqs_cmd;
 	scmd->cdb[0] = REQUEST_SENSE;
 	scmd->cdb[4] = UB_SENSE_SIZE;
@@ -1493,30 +1558,10 @@
 static int ub_bd_ioctl(struct inode *inode, struct file *filp,
     unsigned int cmd, unsigned long arg)
 {
-// void __user *usermem = (void *) arg;
-// struct carm_port *port = ino->i_bdev->bd_disk->private_data;
-// struct hd_geometry geom;
-
-#if 0
-	switch (cmd) {
-	case HDIO_GETGEO:
-		if (usermem == NULL)		// XXX Bizzare. Why?
-			return -EINVAL;
-
-		geom.heads = (u8) port->dev_geom_head;
-		geom.sectors = (u8) port->dev_geom_sect;
-		geom.cylinders = port->dev_geom_cyl;
-		geom.start = get_start_sect(ino->i_bdev);
-
-		if (copy_to_user(usermem, &geom, sizeof(geom)))
-			return -EFAULT;
-		return 0;
-
-	default: ;
-	}
-#endif
+	struct gendisk *disk = inode->i_bdev->bd_disk;
+	void __user *usermem = (void __user *) arg;
 
-	return -ENOTTY;
+	return scsi_cmd_ioctl(filp, disk, cmd, usermem);
 }
 
 /*
diff -Nru a/drivers/block/viodasd.c b/drivers/block/viodasd.c
--- a/drivers/block/viodasd.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/block/viodasd.c	2005-03-01 23:38:53 -08:00
@@ -72,7 +72,7 @@
 	MAX_DISK_NAME = sizeof(((struct gendisk *)0)->disk_name)
 };
 
-static spinlock_t	viodasd_spinlock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(viodasd_spinlock);
 
 #define VIOMAXREQ		16
 #define VIOMAXBLOCKDMA		12
diff -Nru a/drivers/block/xd.c b/drivers/block/xd.c
--- a/drivers/block/xd.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/block/xd.c	2005-03-01 23:39:09 -08:00
@@ -123,7 +123,7 @@
 	0xE0000
 };
 
-static spinlock_t xd_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(xd_lock);
 
 static struct gendisk *xd_gendisk[2];
 
@@ -1054,9 +1054,9 @@
 
 #ifdef MODULE
 
-MODULE_PARM(xd, "1-4i");
-MODULE_PARM(xd_geo, "3-6i");
-MODULE_PARM(nodma, "i");
+module_param_array(xd, int, NULL, 0);
+module_param_array(xd_geo, int, NULL, 0);
+module_param(nodma, bool, 0);
 
 MODULE_LICENSE("GPL");
 
diff -Nru a/drivers/block/z2ram.c b/drivers/block/z2ram.c
--- a/drivers/block/z2ram.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/block/z2ram.c	2005-03-01 23:39:07 -08:00
@@ -65,7 +65,7 @@
 static int list_count       = 0;
 static int current_device   = -1;
 
-static spinlock_t z2ram_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(z2ram_lock);
 
 static struct block_device_operations z2_fops;
 static struct gendisk *z2ram_gendisk;
diff -Nru a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig
--- a/drivers/bluetooth/Kconfig	2005-03-01 23:38:56 -08:00
+++ b/drivers/bluetooth/Kconfig	2005-03-01 23:38:56 -08:00
@@ -75,6 +75,17 @@
 	  Say Y here to compile support for HCI BCM203x devices into the
 	  kernel or say M to compile it as module (bcm203x).
 
+config BT_HCIBPA10X
+	tristate "HCI BPA10x USB driver"
+	depends on USB
+	help
+	  Bluetooth HCI BPA10x USB driver.
+	  This driver provides support for the Digianswer BPA 100/105 Bluetooth
+	  sniffer devices.
+
+	  Say Y here to compile support for HCI BPA10x devices into the
+	  kernel or say M to compile it as module (bpa10x).
+
 config BT_HCIBFUSB
 	tristate "HCI BlueFRITZ! USB driver"
 	depends on USB
diff -Nru a/drivers/bluetooth/Makefile b/drivers/bluetooth/Makefile
--- a/drivers/bluetooth/Makefile	2005-03-01 23:39:17 -08:00
+++ b/drivers/bluetooth/Makefile	2005-03-01 23:39:17 -08:00
@@ -6,6 +6,7 @@
 obj-$(CONFIG_BT_HCIVHCI)	+= hci_vhci.o
 obj-$(CONFIG_BT_HCIUART)	+= hci_uart.o
 obj-$(CONFIG_BT_HCIBCM203X)	+= bcm203x.o
+obj-$(CONFIG_BT_HCIBPA10X)	+= bpa10x.o
 obj-$(CONFIG_BT_HCIBFUSB)	+= bfusb.o
 obj-$(CONFIG_BT_HCIDTL1)	+= dtl1_cs.o
 obj-$(CONFIG_BT_HCIBT3C)	+= bt3c_cs.o
diff -Nru a/drivers/bluetooth/bcm203x.c b/drivers/bluetooth/bcm203x.c
--- a/drivers/bluetooth/bcm203x.c	2005-03-01 23:38:51 -08:00
+++ b/drivers/bluetooth/bcm203x.c	2005-03-01 23:38:51 -08:00
@@ -46,6 +46,8 @@
 
 #define VERSION "1.0"
 
+static int ignore = 0;
+
 static struct usb_device_id bcm203x_table[] = {
 	/* Broadcom Blutonium (BCM2033) */
 	{ USB_DEVICE(0x0a5c, 0x2033) },
@@ -55,7 +57,6 @@
 
 MODULE_DEVICE_TABLE(usb, bcm203x_table);
 
-
 #define BCM203X_ERROR		0
 #define BCM203X_RESET		1
 #define BCM203X_LOAD_MINIDRV	2
@@ -175,7 +176,7 @@
 
 	BT_DBG("intf %p id %p", intf, id);
 
-	if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
+	if (ignore || (intf->cur_altsetting->desc.bInterfaceNumber != 0))
 		return -ENODEV;
 
 	data = kmalloc(sizeof(*data), GFP_KERNEL);
@@ -303,6 +304,9 @@
 
 module_init(bcm203x_init);
 module_exit(bcm203x_exit);
+
+module_param(ignore, bool, 0644);
+MODULE_PARM_DESC(ignore, "Ignore devices from the matching table");
 
 MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
 MODULE_DESCRIPTION("Broadcom Blutonium firmware driver ver " VERSION);
diff -Nru a/drivers/bluetooth/bfusb.c b/drivers/bluetooth/bfusb.c
--- a/drivers/bluetooth/bfusb.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/bluetooth/bfusb.c	2005-03-01 23:39:08 -08:00
@@ -47,6 +47,8 @@
 
 #define VERSION "1.1"
 
+static int ignore = 0;
+
 static struct usb_driver bfusb_driver;
 
 static struct usb_device_id bfusb_table[] = {
@@ -655,6 +657,9 @@
 
 	BT_DBG("intf %p id %p", intf, id);
 
+	if (ignore)
+		return -ENODEV;
+
 	/* Check number of endpoints */
 	if (intf->cur_altsetting->desc.bNumEndpoints < 2)
 		return -EIO;
@@ -678,7 +683,7 @@
 	bfusb->udev = udev;
 	bfusb->bulk_in_ep    = bulk_in_ep->desc.bEndpointAddress;
 	bfusb->bulk_out_ep   = bulk_out_ep->desc.bEndpointAddress;
-	bfusb->bulk_pkt_size = bulk_out_ep->desc.wMaxPacketSize;
+	bfusb->bulk_pkt_size = le16_to_cpu(bulk_out_ep->desc.wMaxPacketSize);
 
 	rwlock_init(&bfusb->lock);
 
@@ -791,6 +796,9 @@
 
 module_init(bfusb_init);
 module_exit(bfusb_exit);
+
+module_param(ignore, bool, 0644);
+MODULE_PARM_DESC(ignore, "Ignore devices from the matching table");
 
 MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
 MODULE_DESCRIPTION("BlueFRITZ! USB driver ver " VERSION);
diff -Nru a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c
--- a/drivers/bluetooth/bluecard_cs.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/bluetooth/bluecard_cs.c	2005-03-01 23:38:57 -08:00
@@ -55,13 +55,6 @@
 /* ======================== Module parameters ======================== */
 
 
-/* Bit map of interrupts to choose from */
-static unsigned int irq_mask = 0x86bc;
-static int irq_list[4] = { -1 };
-
-module_param(irq_mask, uint, 0);
-module_param_array(irq_list, int, NULL, 0);
-
 MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
 MODULE_DESCRIPTION("Bluetooth driver for the Anycom BlueCard (LSE039/LSE041)");
 MODULE_LICENSE("GPL");
@@ -871,7 +864,7 @@
 	bluecard_info_t *info;
 	client_reg_t client_reg;
 	dev_link_t *link;
-	int i, ret;
+	int ret;
 
 	/* Create new info device */
 	info = kmalloc(sizeof(*info), GFP_KERNEL);
@@ -885,13 +878,7 @@
 	link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
 	link->io.NumPorts1 = 8;
 	link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
-	link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
-
-	if (irq_list[0] == -1)
-		link->irq.IRQInfo2 = irq_mask;
-	else
-		for (i = 0; i < 4; i++)
-			link->irq.IRQInfo2 |= 1 << irq_list[i];
+	link->irq.IRQInfo1 = IRQ_LEVEL_ID;
 
 	link->irq.Handler = bluecard_interrupt;
 	link->irq.Instance = info;
@@ -904,7 +891,6 @@
 	link->next = dev_list;
 	dev_list = link;
 	client_reg.dev_info = &dev_info;
-	client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
 	client_reg.EventMask =
 		CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
 		CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
@@ -1117,10 +1103,7 @@
 static void __exit exit_bluecard_cs(void)
 {
 	pcmcia_unregister_driver(&bluecard_driver);
-
-	/* XXX: this really needs to move into generic code.. */
-	while (dev_list != NULL)
-		bluecard_detach(dev_list);
+	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_bluecard_cs);
diff -Nru a/drivers/bluetooth/bpa10x.c b/drivers/bluetooth/bpa10x.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/bluetooth/bpa10x.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,657 @@
+/*
+ *
+ *  Digianswer Bluetooth USB driver
+ *
+ *  Copyright (C) 2004-2005  Marcel Holtmann <marcel@holtmann.org>
+ *
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+
+#include <linux/usb.h>
+
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
+
+#ifndef CONFIG_BT_HCIBPA10X_DEBUG
+#undef  BT_DBG
+#define BT_DBG(D...)
+#endif
+
+#define VERSION "0.8"
+
+static int ignore = 0;
+
+static struct usb_device_id bpa10x_table[] = {
+	/* Tektronix BPA 100/105 (Digianswer) */
+	{ USB_DEVICE(0x08fd, 0x0002) },
+
+	{ }	/* Terminating entry */
+};
+
+MODULE_DEVICE_TABLE(usb, bpa10x_table);
+
+#define BPA10X_CMD_EP		0x00
+#define BPA10X_EVT_EP		0x81
+#define BPA10X_TX_EP		0x02
+#define BPA10X_RX_EP		0x82
+
+#define BPA10X_CMD_BUF_SIZE	252
+#define BPA10X_EVT_BUF_SIZE	16
+#define BPA10X_TX_BUF_SIZE	384
+#define BPA10X_RX_BUF_SIZE	384
+
+struct bpa10x_data {
+	struct hci_dev		*hdev;
+	struct usb_device	*udev;
+
+	rwlock_t		lock;
+
+	struct sk_buff_head	cmd_queue;
+	struct urb		*cmd_urb;
+	struct urb		*evt_urb;
+	struct sk_buff		*evt_skb;
+	unsigned int		evt_len;
+
+	struct sk_buff_head	tx_queue;
+	struct urb		*tx_urb;
+	struct urb		*rx_urb;
+};
+
+#define HCI_VENDOR_HDR_SIZE	5
+
+struct hci_vendor_hdr {
+	__u8	type;
+	__u16	snum;
+	__u16	dlen;
+} __attribute__ ((packed));
+
+static void bpa10x_recv_bulk(struct bpa10x_data *data, unsigned char *buf, int count)
+{
+	struct hci_acl_hdr *ah;
+	struct hci_sco_hdr *sh;
+	struct hci_vendor_hdr *vh;
+	struct sk_buff *skb;
+	int len;
+
+	while (count) {
+		switch (*buf++) {
+		case HCI_ACLDATA_PKT:
+			ah = (struct hci_acl_hdr *) buf;
+			len = HCI_ACL_HDR_SIZE + __le16_to_cpu(ah->dlen);
+			skb = bt_skb_alloc(len, GFP_ATOMIC);
+			if (skb) {
+				memcpy(skb_put(skb, len), buf, len);
+				skb->dev = (void *) data->hdev;
+				skb->pkt_type = HCI_ACLDATA_PKT;
+				hci_recv_frame(skb);
+			}
+			break;
+
+		case HCI_SCODATA_PKT:
+			sh = (struct hci_sco_hdr *) buf;
+			len = HCI_SCO_HDR_SIZE + sh->dlen;
+			skb = bt_skb_alloc(len, GFP_ATOMIC);
+			if (skb) {
+				memcpy(skb_put(skb, len), buf, len);
+				skb->dev = (void *) data->hdev;
+				skb->pkt_type = HCI_SCODATA_PKT;
+				hci_recv_frame(skb);
+			}
+			break;
+
+		case HCI_VENDOR_PKT:
+			vh = (struct hci_vendor_hdr *) buf;
+			len = HCI_VENDOR_HDR_SIZE + __le16_to_cpu(vh->dlen);
+			skb = bt_skb_alloc(len, GFP_ATOMIC);
+			if (skb) {
+				memcpy(skb_put(skb, len), buf, len);
+				skb->dev = (void *) data->hdev;
+				skb->pkt_type = HCI_VENDOR_PKT;
+				hci_recv_frame(skb);
+			}
+			break;
+
+		default:
+			len = count - 1;
+			break;
+		}
+
+		buf   += len;
+		count -= (len + 1);
+	}
+}
+
+static int bpa10x_recv_event(struct bpa10x_data *data, unsigned char *buf, int size)
+{
+	BT_DBG("data %p buf %p size %d", data, buf, size);
+
+	if (data->evt_skb) {
+		struct sk_buff *skb = data->evt_skb;
+
+		memcpy(skb_put(skb, size), buf, size);
+
+		if (skb->len == data->evt_len) {
+			data->evt_skb = NULL;
+			data->evt_len = 0;
+			hci_recv_frame(skb);
+		}
+	} else {
+		struct sk_buff *skb;
+		struct hci_event_hdr *hdr;
+		unsigned char pkt_type;
+		int pkt_len = 0;
+
+		if (size < HCI_EVENT_HDR_SIZE + 1) {
+			BT_ERR("%s event packet block with size %d is too short",
+							data->hdev->name, size);
+			return -EILSEQ;
+		}
+
+		pkt_type = *buf++;
+		size--;
+
+		if (pkt_type != HCI_EVENT_PKT) {
+			BT_ERR("%s unexpected event packet start byte 0x%02x",
+							data->hdev->name, pkt_type);
+			return -EPROTO;
+		}
+
+		hdr = (struct hci_event_hdr *) buf;
+		pkt_len = HCI_EVENT_HDR_SIZE + hdr->plen;
+
+		skb = bt_skb_alloc(pkt_len, GFP_ATOMIC);
+		if (!skb) {
+			BT_ERR("%s no memory for new event packet",
+							data->hdev->name);
+			return -ENOMEM;
+		}
+
+		skb->dev = (void *) data->hdev;
+		skb->pkt_type = pkt_type;
+
+		memcpy(skb_put(skb, size), buf, size);
+
+		if (pkt_len == size) {
+			hci_recv_frame(skb);
+		} else {
+			data->evt_skb = skb;
+			data->evt_len = pkt_len;
+		}
+	}
+
+	return 0;
+}
+
+static void bpa10x_wakeup(struct bpa10x_data *data)
+{
+	struct urb *urb;
+	struct sk_buff *skb;
+	int err;
+
+	BT_DBG("data %p", data);
+
+	urb = data->cmd_urb;
+	if (urb->status == -EINPROGRESS)
+		skb = NULL;
+	else
+		skb = skb_dequeue(&data->cmd_queue);
+
+	if (skb) {
+		struct usb_ctrlrequest *cr;
+
+		if (skb->len > BPA10X_CMD_BUF_SIZE) {
+			BT_ERR("%s command packet with size %d is too big",
+							data->hdev->name, skb->len);
+			kfree_skb(skb);
+			return;
+		}
+
+		cr = (struct usb_ctrlrequest *) urb->setup_packet;
+		cr->wLength = __cpu_to_le16(skb->len);
+
+		memcpy(urb->transfer_buffer, skb->data, skb->len);
+		urb->transfer_buffer_length = skb->len;
+
+		err = usb_submit_urb(urb, GFP_ATOMIC);
+		if (err < 0 && err != -ENODEV) {
+			BT_ERR("%s submit failed for command urb %p with error %d",
+							data->hdev->name, urb, err);
+			skb_queue_head(&data->cmd_queue, skb);
+		} else
+			kfree_skb(skb);
+	}
+
+	urb = data->tx_urb;
+	if (urb->status == -EINPROGRESS)
+		skb = NULL;
+	else
+		skb = skb_dequeue(&data->tx_queue);
+
+	if (skb) {
+		memcpy(urb->transfer_buffer, skb->data, skb->len);
+		urb->transfer_buffer_length = skb->len;
+
+		err = usb_submit_urb(urb, GFP_ATOMIC);
+		if (err < 0 && err != -ENODEV) {
+			BT_ERR("%s submit failed for command urb %p with error %d",
+							data->hdev->name, urb, err);
+			skb_queue_head(&data->tx_queue, skb);
+		} else
+			kfree_skb(skb);
+	}
+}
+
+static void bpa10x_complete(struct urb *urb, struct pt_regs *regs)
+{
+	struct bpa10x_data *data = urb->context;
+	unsigned char *buf = urb->transfer_buffer;
+	int err, count = urb->actual_length;
+
+	BT_DBG("data %p urb %p buf %p count %d", data, urb, buf, count);
+
+	read_lock(&data->lock);
+
+	if (!test_bit(HCI_RUNNING, &data->hdev->flags))
+		goto unlock;
+
+	if (urb->status < 0 || !count)
+		goto resubmit;
+
+	if (usb_pipein(urb->pipe)) {
+		data->hdev->stat.byte_rx += count;
+
+		if (usb_pipetype(urb->pipe) == PIPE_INTERRUPT)
+			bpa10x_recv_event(data, buf, count);
+
+		if (usb_pipetype(urb->pipe) == PIPE_BULK)
+			bpa10x_recv_bulk(data, buf, count);
+	} else {
+		data->hdev->stat.byte_tx += count;
+
+		bpa10x_wakeup(data);
+	}
+
+resubmit:
+	if (usb_pipein(urb->pipe)) {
+		err = usb_submit_urb(urb, GFP_ATOMIC);
+		if (err < 0 && err != -ENODEV) {
+			BT_ERR("%s urb %p type %d resubmit status %d",
+				data->hdev->name, urb, usb_pipetype(urb->pipe), err);
+		}
+	}
+
+unlock:
+	read_unlock(&data->lock);
+}
+
+static inline struct urb *bpa10x_alloc_urb(struct usb_device *udev, unsigned int pipe, size_t size, int flags, void *data)
+{
+	struct urb *urb;
+	struct usb_ctrlrequest *cr;
+	unsigned char *buf;
+
+	BT_DBG("udev %p data %p", udev, data);
+
+	urb = usb_alloc_urb(0, flags);
+	if (!urb)
+		return NULL;
+
+	buf = kmalloc(size, flags);
+	if (!buf) {
+		usb_free_urb(urb);
+		return NULL;
+	}
+
+	switch (usb_pipetype(pipe)) {
+	case PIPE_CONTROL:
+		cr = kmalloc(sizeof(*cr), flags);
+		if (!cr) {
+			kfree(buf);
+			usb_free_urb(urb);
+			return NULL;
+		}
+
+		cr->bRequestType = USB_TYPE_VENDOR;
+		cr->bRequest     = 0;
+		cr->wIndex       = 0;
+		cr->wValue       = 0;
+		cr->wLength      = __cpu_to_le16(0);
+
+		usb_fill_control_urb(urb, udev, pipe, (void *) cr, buf, 0, bpa10x_complete, data);
+		break;
+
+	case PIPE_INTERRUPT:
+		usb_fill_int_urb(urb, udev, pipe, buf, size, bpa10x_complete, data, 1);
+		break;
+
+	case PIPE_BULK:
+		usb_fill_bulk_urb(urb, udev, pipe, buf, size, bpa10x_complete, data);
+		break;
+
+	default:
+		kfree(buf);
+		usb_free_urb(urb);
+		return NULL;
+	}
+
+	return urb;
+}
+
+static inline void bpa10x_free_urb(struct urb *urb)
+{
+	BT_DBG("urb %p", urb);
+
+	if (!urb)
+		return;
+
+	if (urb->setup_packet)
+		kfree(urb->setup_packet);
+
+	if (urb->transfer_buffer)
+		kfree(urb->transfer_buffer);
+
+	usb_free_urb(urb);
+}
+
+static int bpa10x_open(struct hci_dev *hdev)
+{
+	struct bpa10x_data *data = hdev->driver_data;
+	struct usb_device *udev = data->udev;
+	unsigned long flags;
+	int err;
+
+	BT_DBG("hdev %p data %p", hdev, data);
+
+	if (test_and_set_bit(HCI_RUNNING, &hdev->flags))
+		return 0;
+
+	data->cmd_urb = bpa10x_alloc_urb(udev, usb_sndctrlpipe(udev, BPA10X_CMD_EP),
+					BPA10X_CMD_BUF_SIZE, GFP_KERNEL, data);
+	if (!data->cmd_urb) {
+		err = -ENOMEM;
+		goto done;
+	}
+
+	data->evt_urb = bpa10x_alloc_urb(udev, usb_rcvintpipe(udev, BPA10X_EVT_EP),
+					BPA10X_EVT_BUF_SIZE, GFP_KERNEL, data);
+	if (!data->evt_urb) {
+		bpa10x_free_urb(data->cmd_urb);
+		err = -ENOMEM;
+		goto done;
+	}
+
+	data->rx_urb = bpa10x_alloc_urb(udev, usb_rcvbulkpipe(udev, BPA10X_RX_EP),
+					BPA10X_RX_BUF_SIZE, GFP_KERNEL, data);
+	if (!data->rx_urb) {
+		bpa10x_free_urb(data->evt_urb);
+		bpa10x_free_urb(data->cmd_urb);
+		err = -ENOMEM;
+		goto done;
+	}
+
+	data->tx_urb = bpa10x_alloc_urb(udev, usb_sndbulkpipe(udev, BPA10X_TX_EP),
+					BPA10X_TX_BUF_SIZE, GFP_KERNEL, data);
+	if (!data->rx_urb) {
+		bpa10x_free_urb(data->rx_urb);
+		bpa10x_free_urb(data->evt_urb);
+		bpa10x_free_urb(data->cmd_urb);
+		err = -ENOMEM;
+		goto done;
+	}
+
+	write_lock_irqsave(&data->lock, flags);
+
+	err = usb_submit_urb(data->evt_urb, GFP_ATOMIC);
+	if (err < 0) {
+		BT_ERR("%s submit failed for event urb %p with error %d",
+					data->hdev->name, data->evt_urb, err);
+	} else {
+		err = usb_submit_urb(data->rx_urb, GFP_ATOMIC);
+		if (err < 0) {
+			BT_ERR("%s submit failed for rx urb %p with error %d",
+					data->hdev->name, data->evt_urb, err);
+			usb_kill_urb(data->evt_urb);
+		}
+	}
+
+	write_unlock_irqrestore(&data->lock, flags);
+
+done:
+	if (err < 0)
+		clear_bit(HCI_RUNNING, &hdev->flags);
+
+	return err;
+}
+
+static int bpa10x_close(struct hci_dev *hdev)
+{
+	struct bpa10x_data *data = hdev->driver_data;
+	unsigned long flags;
+
+	BT_DBG("hdev %p data %p", hdev, data);
+
+	if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
+		return 0;
+
+	write_lock_irqsave(&data->lock, flags);
+
+	skb_queue_purge(&data->cmd_queue);
+	usb_kill_urb(data->cmd_urb);
+	usb_kill_urb(data->evt_urb);
+	usb_kill_urb(data->rx_urb);
+	usb_kill_urb(data->tx_urb);
+
+	write_unlock_irqrestore(&data->lock, flags);
+
+	bpa10x_free_urb(data->cmd_urb);
+	bpa10x_free_urb(data->evt_urb);
+	bpa10x_free_urb(data->rx_urb);
+	bpa10x_free_urb(data->tx_urb);
+
+	return 0;
+}
+
+static int bpa10x_flush(struct hci_dev *hdev)
+{
+	struct bpa10x_data *data = hdev->driver_data;
+
+	BT_DBG("hdev %p data %p", hdev, data);
+
+	skb_queue_purge(&data->cmd_queue);
+
+	return 0;
+}
+
+static int bpa10x_send_frame(struct sk_buff *skb)
+{
+	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
+	struct bpa10x_data *data;
+
+	BT_DBG("hdev %p skb %p type %d len %d", hdev, skb, skb->pkt_type, skb->len);
+
+	if (!hdev) {
+		BT_ERR("Frame for unknown HCI device");
+		return -ENODEV;
+	}
+
+	if (!test_bit(HCI_RUNNING, &hdev->flags))
+		return -EBUSY;
+
+	data = hdev->driver_data;
+
+	/* Prepend skb with frame type */
+	memcpy(skb_push(skb, 1), &(skb->pkt_type), 1);
+
+	switch (skb->pkt_type) {
+	case HCI_COMMAND_PKT:
+		hdev->stat.cmd_tx++;
+		skb_queue_tail(&data->cmd_queue, skb);
+		break;
+
+	case HCI_ACLDATA_PKT:
+		hdev->stat.acl_tx++;
+		skb_queue_tail(&data->tx_queue, skb);
+		break;
+
+	case HCI_SCODATA_PKT:
+		hdev->stat.sco_tx++;
+		skb_queue_tail(&data->tx_queue, skb);
+		break;
+	};
+
+	read_lock(&data->lock);
+
+	bpa10x_wakeup(data);
+
+	read_unlock(&data->lock);
+
+	return 0;
+}
+
+static void bpa10x_destruct(struct hci_dev *hdev)
+{
+	struct bpa10x_data *data = hdev->driver_data;
+
+	BT_DBG("hdev %p data %p", hdev, data);
+
+	kfree(data);
+}
+
+static int bpa10x_probe(struct usb_interface *intf, const struct usb_device_id *id)
+{
+	struct usb_device *udev = interface_to_usbdev(intf);
+	struct hci_dev *hdev;
+	struct bpa10x_data *data;
+	int err;
+
+	BT_DBG("intf %p id %p", intf, id);
+
+	if (ignore)
+		return -ENODEV;
+
+	data = kmalloc(sizeof(*data), GFP_KERNEL);
+	if (!data) {
+		BT_ERR("Can't allocate data structure");
+		return -ENOMEM;
+	}
+
+	memset(data, 0, sizeof(*data));
+
+	data->udev = udev;
+
+	rwlock_init(&data->lock);
+
+	skb_queue_head_init(&data->cmd_queue);
+	skb_queue_head_init(&data->tx_queue);
+
+	hdev = hci_alloc_dev();
+	if (!hdev) {
+		BT_ERR("Can't allocate HCI device");
+		kfree(data);
+		return -ENOMEM;
+	}
+
+	data->hdev = hdev;
+
+	hdev->type = HCI_USB;
+	hdev->driver_data = data;
+	SET_HCIDEV_DEV(hdev, &intf->dev);
+
+	hdev->open	= bpa10x_open;
+	hdev->close	= bpa10x_close;
+	hdev->flush	= bpa10x_flush;
+	hdev->send	= bpa10x_send_frame;
+	hdev->destruct	= bpa10x_destruct;
+
+	hdev->owner = THIS_MODULE;
+
+	err = hci_register_dev(hdev);
+	if (err < 0) {
+		BT_ERR("Can't register HCI device");
+		kfree(data);
+		hci_free_dev(hdev);
+		return err;
+	}
+
+	usb_set_intfdata(intf, data);
+
+	return 0;
+}
+
+static void bpa10x_disconnect(struct usb_interface *intf)
+{
+	struct bpa10x_data *data = usb_get_intfdata(intf);
+	struct hci_dev *hdev = data->hdev;
+
+	BT_DBG("intf %p", intf);
+
+	if (!hdev)
+		return;
+
+	usb_set_intfdata(intf, NULL);
+
+	if (hci_unregister_dev(hdev) < 0)
+		BT_ERR("Can't unregister HCI device %s", hdev->name);
+
+	hci_free_dev(hdev);
+}
+
+static struct usb_driver bpa10x_driver = {
+	.owner		= THIS_MODULE,
+	.name		= "bpa10x",
+	.probe		= bpa10x_probe,
+	.disconnect	= bpa10x_disconnect,
+	.id_table	= bpa10x_table,
+};
+
+static int __init bpa10x_init(void)
+{
+	int err;
+
+	BT_INFO("Digianswer Bluetooth USB driver ver %s", VERSION);
+
+	err = usb_register(&bpa10x_driver);
+	if (err < 0)
+		BT_ERR("Failed to register USB driver");
+
+	return err;
+}
+
+static void __exit bpa10x_exit(void)
+{
+	usb_deregister(&bpa10x_driver);
+}
+
+module_init(bpa10x_init);
+module_exit(bpa10x_exit);
+
+module_param(ignore, bool, 0644);
+MODULE_PARM_DESC(ignore, "Ignore devices from the matching table");
+
+MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
+MODULE_DESCRIPTION("Digianswer Bluetooth USB driver ver " VERSION);
+MODULE_VERSION(VERSION);
+MODULE_LICENSE("GPL");
diff -Nru a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c
--- a/drivers/bluetooth/bt3c_cs.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/bluetooth/bt3c_cs.c	2005-03-01 23:39:17 -08:00
@@ -63,13 +63,6 @@
 /* ======================== Module parameters ======================== */
 
 
-/* Bit map of interrupts to choose from */
-static unsigned int irq_mask = 0xffff;
-static int irq_list[4] = { -1 };
-
-module_param(irq_mask, uint, 0);
-module_param_array(irq_list, int, NULL, 0);
-
 MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>, Jose Orlando Pereira <jop@di.uminho.pt>");
 MODULE_DESCRIPTION("Bluetooth driver for the 3Com Bluetooth PCMCIA card");
 MODULE_LICENSE("GPL");
@@ -676,7 +669,7 @@
 	bt3c_info_t *info;
 	client_reg_t client_reg;
 	dev_link_t *link;
-	int i, ret;
+	int ret;
 
 	/* Create new info device */
 	info = kmalloc(sizeof(*info), GFP_KERNEL);
@@ -690,13 +683,7 @@
 	link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
 	link->io.NumPorts1 = 8;
 	link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
-	link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
-
-	if (irq_list[0] == -1)
-		link->irq.IRQInfo2 = irq_mask;
-	else
-		for (i = 0; i < 4; i++)
-			link->irq.IRQInfo2 |= 1 << irq_list[i];
+	link->irq.IRQInfo1 = IRQ_LEVEL_ID;
 
 	link->irq.Handler = bt3c_interrupt;
 	link->irq.Instance = info;
@@ -709,7 +696,6 @@
 	link->next = dev_list;
 	dev_list = link;
 	client_reg.dev_info = &dev_info;
-	client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
 	client_reg.EventMask =
 	    CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
 	    CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
@@ -785,7 +771,7 @@
 
 static void bt3c_config(dev_link_t *link)
 {
-	static ioaddr_t base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
+	static kio_addr_t base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
 	client_handle_t handle = link->handle;
 	bt3c_info_t *info = link->priv;
 	tuple_t tuple;
@@ -967,10 +953,7 @@
 static void __exit exit_bt3c_cs(void)
 {
 	pcmcia_unregister_driver(&bt3c_driver);
-
-	/* XXX: this really needs to move into generic code.. */
-	while (dev_list != NULL)
-		bt3c_detach(dev_list);
+	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_bt3c_cs);
diff -Nru a/drivers/bluetooth/btuart_cs.c b/drivers/bluetooth/btuart_cs.c
--- a/drivers/bluetooth/btuart_cs.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/bluetooth/btuart_cs.c	2005-03-01 23:39:17 -08:00
@@ -59,13 +59,6 @@
 /* ======================== Module parameters ======================== */
 
 
-/* Bit map of interrupts to choose from */
-static unsigned int irq_mask = 0xffff;
-static int irq_list[4] = { -1 };
-
-module_param(irq_mask, uint, 0);
-module_param_array(irq_list, int, NULL, 0);
-
 MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
 MODULE_DESCRIPTION("Bluetooth driver for Bluetooth PCMCIA cards with HCI UART interface");
 MODULE_LICENSE("GPL");
@@ -595,7 +588,7 @@
 	btuart_info_t *info;
 	client_reg_t client_reg;
 	dev_link_t *link;
-	int i, ret;
+	int ret;
 
 	/* Create new info device */
 	info = kmalloc(sizeof(*info), GFP_KERNEL);
@@ -609,13 +602,7 @@
 	link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
 	link->io.NumPorts1 = 8;
 	link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
-	link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
-
-	if (irq_list[0] == -1)
-		link->irq.IRQInfo2 = irq_mask;
-	else
-		for (i = 0; i < 4; i++)
-			link->irq.IRQInfo2 |= 1 << irq_list[i];
+	link->irq.IRQInfo1 = IRQ_LEVEL_ID;
 
 	link->irq.Handler = btuart_interrupt;
 	link->irq.Instance = info;
@@ -628,7 +615,6 @@
 	link->next = dev_list;
 	dev_list = link;
 	client_reg.dev_info = &dev_info;
-	client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
 	client_reg.EventMask =
 		CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
 		CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
@@ -704,7 +690,7 @@
 
 static void btuart_config(dev_link_t *link)
 {
-	static ioaddr_t base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
+	static kio_addr_t base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
 	client_handle_t handle = link->handle;
 	btuart_info_t *info = link->priv;
 	tuple_t tuple;
@@ -887,10 +873,7 @@
 static void __exit exit_btuart_cs(void)
 {
 	pcmcia_unregister_driver(&btuart_driver);
-
-	/* XXX: this really needs to move into generic code.. */
-	while (dev_list != NULL)
-		btuart_detach(dev_list);
+	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_btuart_cs);
diff -Nru a/drivers/bluetooth/dtl1_cs.c b/drivers/bluetooth/dtl1_cs.c
--- a/drivers/bluetooth/dtl1_cs.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/bluetooth/dtl1_cs.c	2005-03-01 23:38:56 -08:00
@@ -59,13 +59,6 @@
 /* ======================== Module parameters ======================== */
 
 
-/* Bit map of interrupts to choose from */
-static unsigned int irq_mask = 0xffff;
-static int irq_list[4] = { -1 };
-
-module_param(irq_mask, uint, 0);
-module_param_array(irq_list, int, NULL, 0);
-
 MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
 MODULE_DESCRIPTION("Bluetooth driver for Nokia Connectivity Card DTL-1");
 MODULE_LICENSE("GPL");
@@ -574,7 +567,7 @@
 	dtl1_info_t *info;
 	client_reg_t client_reg;
 	dev_link_t *link;
-	int i, ret;
+	int ret;
 
 	/* Create new info device */
 	info = kmalloc(sizeof(*info), GFP_KERNEL);
@@ -588,13 +581,7 @@
 	link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
 	link->io.NumPorts1 = 8;
 	link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
-	link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
-
-	if (irq_list[0] == -1)
-		link->irq.IRQInfo2 = irq_mask;
-	else
-		for (i = 0; i < 4; i++)
-			link->irq.IRQInfo2 |= 1 << irq_list[i];
+	link->irq.IRQInfo1 = IRQ_LEVEL_ID;
 
 	link->irq.Handler = dtl1_interrupt;
 	link->irq.Instance = info;
@@ -607,7 +594,6 @@
 	link->next = dev_list;
 	dev_list = link;
 	client_reg.dev_info = &dev_info;
-	client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
 	client_reg.EventMask =
 		CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
 		CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
@@ -839,10 +825,7 @@
 static void __exit exit_dtl1_cs(void)
 {
 	pcmcia_unregister_driver(&dtl1_driver);
-
-	/* XXX: this really needs to move into generic code.. */
-	while (dev_list != NULL)
-		dtl1_detach(dev_list);
+	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_dtl1_cs);
diff -Nru a/drivers/bluetooth/hci_bcsp.c b/drivers/bluetooth/hci_bcsp.c
--- a/drivers/bluetooth/hci_bcsp.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/bluetooth/hci_bcsp.c	2005-03-01 23:39:09 -08:00
@@ -265,7 +265,7 @@
 /* This is a rewrite of pkt_avail in ABCSP */
 static struct sk_buff *bcsp_dequeue(struct hci_uart *hu)
 {
-	struct bcsp_struct *bcsp = (struct bcsp_struct *) hu->priv;
+	struct bcsp_struct *bcsp = hu->priv;
 	unsigned long flags;
 	struct sk_buff *skb;
 	
@@ -629,7 +629,7 @@
 static void bcsp_timed_event(unsigned long arg)
 {
 	struct hci_uart *hu = (struct hci_uart *) arg;
-	struct bcsp_struct *bcsp = (struct bcsp_struct *) hu->priv;
+	struct bcsp_struct *bcsp = hu->priv;
 	struct sk_buff *skb;
 	unsigned long flags;
 
diff -Nru a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
--- a/drivers/bluetooth/hci_ldisc.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/bluetooth/hci_ldisc.c	2005-03-01 23:39:08 -08:00
@@ -51,6 +51,7 @@
 
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
+
 #include "hci_uart.h"
 
 #ifndef CONFIG_BT_HCIUART_DEBUG
@@ -60,6 +61,8 @@
 #define BT_DMP( A... )
 #endif
 
+static int reset = 0;
+
 static struct hci_uart_proto *hup[HCI_UART_MAX_PROTO];
 
 int hci_uart_register_proto(struct hci_uart_proto *p)
@@ -412,7 +415,10 @@
 	hdev->destruct = hci_uart_destruct;
 
 	hdev->owner = THIS_MODULE;
-	
+
+	if (reset)
+		set_bit(HCI_QUIRK_RESET_ON_INIT, &hdev->quirks);
+
 	if (hci_register_dev(hdev) < 0) {
 		BT_ERR("Can't register HCI device");
 		hci_free_dev(hdev);
@@ -577,7 +583,10 @@
 module_init(hci_uart_init);
 module_exit(hci_uart_exit);
 
-MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
+module_param(reset, bool, 0644);
+MODULE_PARM_DESC(reset, "Send HCI reset command on initialization");
+
+MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>, Marcel Holtmann <marcel@holtmann.org>");
 MODULE_DESCRIPTION("Bluetooth HCI UART driver ver " VERSION);
 MODULE_VERSION(VERSION);
 MODULE_LICENSE("GPL");
diff -Nru a/drivers/bluetooth/hci_usb.c b/drivers/bluetooth/hci_usb.c
--- a/drivers/bluetooth/hci_usb.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/bluetooth/hci_usb.c	2005-03-01 23:39:16 -08:00
@@ -66,11 +66,14 @@
 #define URB_ZERO_PACKET 0
 #endif
 
+static int ignore = 0;
+static int reset = 0;
+
 #ifdef CONFIG_BT_HCIUSB_SCO
 static int isoc = 2;
 #endif
 
-#define VERSION "2.7"
+#define VERSION "2.8"
 
 static struct usb_driver hci_usb_driver; 
 
@@ -101,21 +104,24 @@
 	{ USB_DEVICE(0x0a5c, 0x2033), .driver_info = HCI_IGNORE },
 
 	/* Broadcom BCM2035 */
-	{ USB_DEVICE(0x0a5c, 0x2009), .driver_info = HCI_RESET | HCI_BROKEN_ISOC },
 	{ USB_DEVICE(0x0a5c, 0x200a), .driver_info = HCI_RESET | HCI_BROKEN_ISOC },
+	{ USB_DEVICE(0x0a5c, 0x2009), .driver_info = HCI_BCM92035 },
 
 	/* Microsoft Wireless Transceiver for Bluetooth 2.0 */
-	{ USB_DEVICE(0x045e, 0x009c), .driver_info = HCI_RESET | HCI_BROKEN_ISOC },
+	{ USB_DEVICE(0x045e, 0x009c), .driver_info = HCI_RESET },
 
 	/* ISSC Bluetooth Adapter v3.1 */
 	{ USB_DEVICE(0x1131, 0x1001), .driver_info = HCI_RESET },
 
+	/* RTX Telecom based adapter with buggy SCO support */
+	{ USB_DEVICE(0x0400, 0x0807), .driver_info = HCI_BROKEN_ISOC },
+
 	/* Digianswer devices */
 	{ USB_DEVICE(0x08fd, 0x0001), .driver_info = HCI_DIGIANSWER },
 	{ USB_DEVICE(0x08fd, 0x0002), .driver_info = HCI_IGNORE },
 
-	/* RTX Telecom based adapter with buggy SCO support */
-	{ USB_DEVICE(0x0400, 0x0807), .driver_info = HCI_BROKEN_ISOC },
+	/* CSR BlueCore Bluetooth Sniffer */
+	{ USB_DEVICE(0x0a12, 0x0002), .driver_info = HCI_SNIFFER },
 
 	{ }	/* Terminating entry */
 };
@@ -193,7 +199,7 @@
 
 	BT_DBG("%s", husb->hdev->name);
 
-	size = husb->intr_in_ep->desc.wMaxPacketSize;
+	size = le16_to_cpu(husb->intr_in_ep->desc.wMaxPacketSize);
 
 	buf = kmalloc(size, GFP_ATOMIC);
 	if (!buf)
@@ -268,7 +274,7 @@
 	int err, mtu, size;
 	void *buf;
 
-	mtu  = husb->isoc_in_ep->desc.wMaxPacketSize;
+	mtu  = le16_to_cpu(husb->isoc_in_ep->desc.wMaxPacketSize);
 	size = mtu * HCI_MAX_ISOC_FRAMES;
 
 	buf = kmalloc(size, GFP_ATOMIC);
@@ -525,7 +531,7 @@
 	urb->transfer_buffer = skb->data;
 	urb->transfer_buffer_length = skb->len;
 
-	__fill_isoc_desc(urb, skb->len, husb->isoc_out_ep->desc.wMaxPacketSize);
+	__fill_isoc_desc(urb, skb->len, le16_to_cpu(husb->isoc_out_ep->desc.wMaxPacketSize));
 
 	_urb->priv = skb;
 	return __tx_submit(husb, _urb);
@@ -827,7 +833,7 @@
 			id = match;
 	}
 
-	if (id->driver_info & HCI_IGNORE)
+	if (ignore || id->driver_info & HCI_IGNORE)
 		return -ENODEV;
 
 	if (intf->cur_altsetting->desc.bInterfaceNumber > 0)
@@ -897,10 +903,10 @@
 
 				switch (ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
 				case USB_ENDPOINT_XFER_ISOC:
-					if (ep->desc.wMaxPacketSize < size ||
+					if (le16_to_cpu(ep->desc.wMaxPacketSize) < size ||
 							uif->desc.bAlternateSetting != isoc)
 						break;
-					size = ep->desc.wMaxPacketSize;
+					size = le16_to_cpu(ep->desc.wMaxPacketSize);
 
 					isoc_alts = uif->desc.bAlternateSetting;
 
@@ -963,9 +969,25 @@
 
 	hdev->owner = THIS_MODULE;
 
-	if (id->driver_info & HCI_RESET)
+	if (reset || id->driver_info & HCI_RESET)
 		set_bit(HCI_QUIRK_RESET_ON_INIT, &hdev->quirks);
 
+	if (id->driver_info & HCI_SNIFFER) {
+		if (le16_to_cpu(udev->descriptor.bcdDevice) > 0x997)
+			set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);
+	}
+
+	if (id->driver_info & HCI_BCM92035) {
+		unsigned char cmd[] = { 0x3b, 0xfc, 0x01, 0x00 };
+		struct sk_buff *skb;
+
+		skb = bt_skb_alloc(sizeof(cmd), GFP_KERNEL);
+		if (skb) {
+			memcpy(skb_put(skb, sizeof(cmd)), cmd, sizeof(cmd));
+			skb_queue_tail(&hdev->driver_init, skb);
+		}
+	}
+
 	if (hci_register_dev(hdev) < 0) {
 		BT_ERR("Can't register HCI device");
 		hci_free_dev(hdev);
@@ -1035,6 +1057,12 @@
 
 module_init(hci_usb_init);
 module_exit(hci_usb_exit);
+
+module_param(ignore, bool, 0644);
+MODULE_PARM_DESC(ignore, "Ignore devices from the matching table");
+
+module_param(reset, bool, 0644);
+MODULE_PARM_DESC(reset, "Send HCI reset command on initialization");
 
 #ifdef CONFIG_BT_HCIUSB_SCO
 module_param(isoc, int, 0644);
diff -Nru a/drivers/bluetooth/hci_usb.h b/drivers/bluetooth/hci_usb.h
--- a/drivers/bluetooth/hci_usb.h	2005-03-01 23:39:09 -08:00
+++ b/drivers/bluetooth/hci_usb.h	2005-03-01 23:39:09 -08:00
@@ -31,7 +31,9 @@
 #define HCI_IGNORE		0x01
 #define HCI_RESET		0x02
 #define HCI_DIGIANSWER		0x04
-#define HCI_BROKEN_ISOC		0x08
+#define HCI_SNIFFER		0x08
+#define HCI_BROKEN_ISOC		0x10
+#define HCI_BCM92035		0x20
 
 #define HCI_MAX_IFACE_NUM	3
 
diff -Nru a/drivers/cdrom/Kconfig b/drivers/cdrom/Kconfig
--- a/drivers/cdrom/Kconfig	2005-03-01 23:39:09 -08:00
+++ b/drivers/cdrom/Kconfig	2005-03-01 23:39:09 -08:00
@@ -18,7 +18,7 @@
 	  have, say Y and find out whether you have one of the following
 	  drives.
 
-	  For each of these drivers, a file Documentation/cdrom/{driver_name}
+	  For each of these drivers, a <file:Documentation/cdrom/{driver_name}>
 	  exists. Especially in cases where you do not know exactly which kind
 	  of drive you have you should read there. Most of these drivers use a
 	  file drivers/cdrom/{driver_name}.h where you can define your
@@ -105,7 +105,7 @@
 
 config MCD
 	tristate "Mitsumi (standard) [no XA/Multisession] CDROM support"
-	depends on CD_NO_IDESCSI
+	depends on CD_NO_IDESCSI && BROKEN
 	---help---
 	  This is the older of the two drivers for the older Mitsumi models
 	  LU-005, FX-001 and FX-001D. This is not the right driver for the
diff -Nru a/drivers/cdrom/aztcd.c b/drivers/cdrom/aztcd.c
--- a/drivers/cdrom/aztcd.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/cdrom/aztcd.c	2005-03-01 23:39:16 -08:00
@@ -165,7 +165,6 @@
 			 Torben Mathiasen <tmm@image.dk>
 */
 
-#include <linux/version.h>
 #include <linux/blkdev.h>
 #include "aztcd.h"
 
@@ -288,7 +287,7 @@
 
 static int azt_port = AZT_BASE_ADDR;
 
-MODULE_PARM(azt_port, "i");
+module_param(azt_port, int, 0);
 
 static int azt_port_auto[16] = AZT_BASE_AUTO;
 
@@ -312,7 +311,7 @@
 static unsigned long aztTimeOutCount;
 static int aztCmd = 0;
 
-static spinlock_t aztSpin = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(aztSpin);
 
 /*###########################################################################
    Function Prototypes
@@ -1708,8 +1707,8 @@
 	printk(KERN_INFO "aztcd: (C) 1994-98 W.Zimmermann\n");
 	if (azt_port == -1) {
 		printk
-		    ("aztcd: KernelVersion=%s DriverVersion=%s For IDE/ATAPI-drives use ide-cd.c\n",
-		     UTS_RELEASE, AZT_VERSION);
+		    ("aztcd: DriverVersion=%s For IDE/ATAPI-drives use ide-cd.c\n",
+		     AZT_VERSION);
 	} else
 		printk
 		    ("aztcd: DriverVersion=%s BaseAddress=0x%x  For IDE/ATAPI-drives use ide-cd.c\n",
diff -Nru a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c
--- a/drivers/cdrom/cdrom.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/cdrom/cdrom.c	2005-03-01 23:38:53 -08:00
@@ -303,7 +303,7 @@
 module_param(check_media_type, bool, 0);
 module_param(mrw_format_restart, bool, 0);
 
-static spinlock_t cdrom_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(cdrom_lock);
 
 static const char *mrw_format_status[] = {
 	"not mrw",
@@ -505,7 +505,7 @@
  * the first prototypes used 0x2c as the page code for the mrw mode page,
  * subsequently this was changed to 0x03. probe the one used by this drive
  */
-int cdrom_mrw_probe_pc(struct cdrom_device_info *cdi)
+static int cdrom_mrw_probe_pc(struct cdrom_device_info *cdi)
 {
 	struct packet_command cgc;
 	char buffer[16];
@@ -526,7 +526,7 @@
 	return 1;
 }
 
-int cdrom_is_mrw(struct cdrom_device_info *cdi, int *write)
+static int cdrom_is_mrw(struct cdrom_device_info *cdi, int *write)
 {
 	struct packet_command cgc;
 	struct mrw_feature_desc *mfd;
@@ -680,7 +680,7 @@
 	return 0;
 }
 
-int cdrom_get_random_writable(struct cdrom_device_info *cdi,
+static int cdrom_get_random_writable(struct cdrom_device_info *cdi,
 			      struct rwrt_feature_desc *rfd)
 {
 	struct packet_command cgc;
@@ -701,7 +701,7 @@
 	return 0;
 }
 
-int cdrom_has_defect_mgt(struct cdrom_device_info *cdi)
+static int cdrom_has_defect_mgt(struct cdrom_device_info *cdi)
 {
 	struct packet_command cgc;
 	char buffer[16];
@@ -726,7 +726,7 @@
 }
 
 
-int cdrom_is_random_writable(struct cdrom_device_info *cdi, int *write)
+static int cdrom_is_random_writable(struct cdrom_device_info *cdi, int *write)
 {
 	struct rwrt_feature_desc rfd;
 	int ret;
@@ -1076,6 +1076,8 @@
 			}
 			cdinfo(CD_OPEN, "the tray is now closed.\n"); 
 		}
+		/* the door should be closed now, check for the disc */
+		ret = cdo->drive_status(cdi, CDSL_CURRENT);
 		if (ret!=CDS_DISC_OK) {
 			ret = -ENOMEDIUM;
 			goto clean_up_and_return;
@@ -3074,14 +3076,12 @@
 EXPORT_SYMBOL(cdrom_mode_sense);
 EXPORT_SYMBOL(init_cdrom_command);
 EXPORT_SYMBOL(cdrom_get_media_event);
-EXPORT_SYMBOL(cdrom_is_mrw);
-EXPORT_SYMBOL(cdrom_is_random_writable);
 
 #ifdef CONFIG_SYSCTL
 
 #define CDROM_STR_SIZE 1000
 
-struct cdrom_sysctl_settings {
+static struct cdrom_sysctl_settings {
 	char	info[CDROM_STR_SIZE];	/* general info */
 	int	autoclose;		/* close tray upon mount, etc */
 	int	autoeject;		/* eject on umount */
@@ -3090,7 +3090,7 @@
 	int	check;			/* check media type */
 } cdrom_sysctl_settings;
 
-int cdrom_sysctl_info(ctl_table *ctl, int write, struct file * filp,
+static int cdrom_sysctl_info(ctl_table *ctl, int write, struct file * filp,
                            void __user *buffer, size_t *lenp, loff_t *ppos)
 {
         int pos;
@@ -3193,7 +3193,7 @@
    procfs/sysctl yet. When they are, this will naturally disappear. For now
    just update all drives. Later this will become the template on which
    new registered drives will be based. */
-void cdrom_update_settings(void)
+static void cdrom_update_settings(void)
 {
 	struct cdrom_device_info *cdi;
 
@@ -3271,7 +3271,7 @@
 }
 
 /* Place files in /proc/sys/dev/cdrom */
-ctl_table cdrom_table[] = {
+static ctl_table cdrom_table[] = {
 	{
 		.ctl_name	= DEV_CDROM_INFO,
 		.procname	= "info",
@@ -3323,7 +3323,7 @@
 	{ .ctl_name = 0 }
 };
 
-ctl_table cdrom_cdrom_table[] = {
+static ctl_table cdrom_cdrom_table[] = {
 	{
 		.ctl_name	= DEV_CDROM,
 		.procname	= "cdrom",
@@ -3335,7 +3335,7 @@
 };
 
 /* Make sure that /proc/sys/dev is there */
-ctl_table cdrom_root_table[] = {
+static ctl_table cdrom_root_table[] = {
 	{
 		.ctl_name	= CTL_DEV,
 		.procname	= "dev",
diff -Nru a/drivers/cdrom/cdu31a.c b/drivers/cdrom/cdu31a.c
--- a/drivers/cdrom/cdu31a.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/cdrom/cdu31a.c	2005-03-01 23:39:07 -08:00
@@ -236,7 +236,7 @@
 static volatile unsigned short sony_cd_fifost_reg;
 
 static struct request_queue *cdu31a_queue;
-static spinlock_t cdu31a_lock = SPIN_LOCK_UNLOCKED; /* queue lock */
+static DEFINE_SPINLOCK(cdu31a_lock); /* queue lock */
 
 static int sony_spun_up = 0;	/* Has the drive been spun up? */
 
diff -Nru a/drivers/cdrom/cm206.c b/drivers/cdrom/cm206.c
--- a/drivers/cdrom/cm206.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/cdrom/cm206.c	2005-03-01 23:39:16 -08:00
@@ -302,7 +302,7 @@
 
 static struct cm206_struct *cd;	/* the main memory structure */
 static struct request_queue *cm206_queue;
-static spinlock_t cm206_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(cm206_lock);
 
 /* First, we define some polling functions. These are actually
    only being used in the initialization. */
diff -Nru a/drivers/cdrom/gscd.c b/drivers/cdrom/gscd.c
--- a/drivers/cdrom/gscd.c	2005-03-01 23:38:51 -08:00
+++ b/drivers/cdrom/gscd.c	2005-03-01 23:38:51 -08:00
@@ -70,7 +70,6 @@
 
 #define MAJOR_NR GOLDSTAR_CDROM_MAJOR
 #include <linux/blkdev.h>
-#define gscd_port gscd		/* for compatible parameter passing with "insmod" */
 #include "gscd.h"
 
 static int gscdPresent = 0;
@@ -78,7 +77,7 @@
 static unsigned char gscd_buf[2048];	/* buffer for block size conversion */
 static int gscd_bn = -1;
 static short gscd_port = GSCD_BASE_ADDR;
-MODULE_PARM(gscd, "h");
+module_param_named(gscd, gscd_port, short, 0);
 
 /* Kommt spaeter vielleicht noch mal dran ...
  *    static DECLARE_WAIT_QUEUE_HEAD(gscd_waitq);
@@ -148,7 +147,7 @@
 static int AudioEnd_f;
 
 static struct timer_list gscd_timer = TIMER_INITIALIZER(NULL, 0, 0);
-static spinlock_t gscd_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(gscd_lock);
 static struct request_queue *gscd_queue;
 
 static struct block_device_operations gscd_fops = {
diff -Nru a/drivers/cdrom/isp16.c b/drivers/cdrom/isp16.c
--- a/drivers/cdrom/isp16.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/cdrom/isp16.c	2005-03-01 23:39:16 -08:00
@@ -72,14 +72,10 @@
 static int isp16_cdrom_dma = ISP16_CDROM_DMA;
 static char *isp16_cdrom_type = ISP16_CDROM_TYPE;
 
-MODULE_PARM(isp16_cdrom_base, "i");
-MODULE_PARM(isp16_cdrom_irq, "i");
-MODULE_PARM(isp16_cdrom_dma, "i");
-MODULE_PARM(isp16_cdrom_type, "s");
-
-#ifdef MODULE
-void isp16_exit(void);
-#endif
+module_param(isp16_cdrom_base, int, 0);
+module_param(isp16_cdrom_irq, int, 0);
+module_param(isp16_cdrom_dma, int, 0);
+module_param(isp16_cdrom_type, charp, 0);
 
 #define ISP16_IN(p) (outb(isp16_ctrl,ISP16_CTRL_PORT), inb(p))
 #define ISP16_OUT(p,b) (outb(isp16_ctrl,ISP16_CTRL_PORT), outb(b,p))
@@ -112,7 +108,7 @@
  *  ISP16 initialisation.
  *
  */
-int __init isp16_init(void)
+static int __init isp16_init(void)
 {
 	u_char expected_drive;
 
@@ -366,15 +362,13 @@
 	return 0;
 }
 
-void __exit isp16_exit(void)
+static void __exit isp16_exit(void)
 {
 	release_region(ISP16_IO_BASE, ISP16_IO_SIZE);
 	printk(KERN_INFO "ISP16: module released.\n");
 }
 
-#ifdef MODULE
 module_init(isp16_init);
-#endif
 module_exit(isp16_exit);
 
 MODULE_LICENSE("GPL");
diff -Nru a/drivers/cdrom/isp16.h b/drivers/cdrom/isp16.h
--- a/drivers/cdrom/isp16.h	2005-03-01 23:38:55 -08:00
+++ b/drivers/cdrom/isp16.h	2005-03-01 23:38:55 -08:00
@@ -70,5 +70,3 @@
 
 #define ISP16_IO_BASE 0xF8D
 #define ISP16_IO_SIZE 5  /* ports used from 0xF8D up to 0xF91 */
-
-int isp16_init(void);
diff -Nru a/drivers/cdrom/mcd.c b/drivers/cdrom/mcd.c
--- a/drivers/cdrom/mcd.c	2005-03-01 23:39:06 -08:00
+++ b/drivers/cdrom/mcd.c	2005-03-01 23:39:06 -08:00
@@ -103,7 +103,6 @@
 #include <asm/uaccess.h>
 #include <linux/blkdev.h>
 
-#define mcd_port mcd		/* for compatible parameter passing with "insmod" */
 #include "mcd.h"
 
 /* I added A flag to drop to 1x speed if too many errors 0 = 1X ; 1 = 2X */
@@ -157,7 +156,6 @@
 
 static short mcd_port = CONFIG_MCD_BASE;	/* used as "mcd" by "insmod" */
 static int mcd_irq = CONFIG_MCD_IRQ;	/* must directly follow mcd_port */
-MODULE_PARM(mcd, "1-2i");
 
 static int McdTimeout, McdTries;
 static DECLARE_WAIT_QUEUE_HEAD(mcd_waitq);
@@ -189,7 +187,7 @@
 static void mcd_release(struct cdrom_device_info *cdi);
 static int mcd_media_changed(struct cdrom_device_info *cdi, int disc_nr);
 static int mcd_tray_move(struct cdrom_device_info *cdi, int position);
-static spinlock_t mcd_spinlock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(mcd_spinlock);
 static int mcd_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
 		    void *arg);
 static int mcd_drive_status(struct cdrom_device_info *cdi, int slot_nr);
@@ -246,7 +244,6 @@
 
 static struct gendisk *mcd_gendisk;
 
-#ifndef MODULE
 static int __init mcd_setup(char *str)
 {
 	int ints[9];
@@ -265,7 +262,14 @@
 
 __setup("mcd=", mcd_setup);
 
-#endif				/* MODULE */
+#ifdef MODULE
+static int __init param_set_mcd(const char *val, struct kernel_param *kp)
+{
+	mcd_setup(val);
+	return 0;
+}
+module_param_call(mcd, param_set_mcd, NULL, NULL, 0);
+#endif
 
 static int mcd_media_changed(struct cdrom_device_info *cdi, int disc_nr)
 {
diff -Nru a/drivers/cdrom/mcdx.c b/drivers/cdrom/mcdx.c
--- a/drivers/cdrom/mcdx.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/cdrom/mcdx.c	2005-03-01 23:38:57 -08:00
@@ -56,7 +56,6 @@
     = "$Id: mcdx.c,v 1.21 1997/01/26 07:12:59 davem Exp $";
 #endif
 
-#include <linux/version.h>
 #include <linux/module.h>
 
 #include <linux/errno.h>
@@ -77,8 +76,6 @@
 #include <linux/blkdev.h>
 #include <linux/devfs_fs_kernel.h>
 
-/* for compatible parameter passing with "insmod" */
-#define	mcdx_drive_map mcdx
 #include "mcdx.h"
 
 #ifndef HZ
@@ -307,9 +304,16 @@
 
 static int mcdx_drive_map[][2] = MCDX_DRIVEMAP;
 static struct s_drive_stuff *mcdx_stuffp[MCDX_NDRIVES];
-static spinlock_t mcdx_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(mcdx_lock);
 static struct request_queue *mcdx_queue;
-MODULE_PARM(mcdx, "1-4i");
+
+/* You can only set the first two pairs, from old MODULE_PARM code.  */
+static int mcdx_set(const char *val, struct kernel_param *kp)
+{
+	get_options((char *)val, 4, (int *)mcdx_drive_map);
+	return 0;
+}
+module_param_call(mcdx, mcdx_set, NULL, NULL, 0);
 
 static struct cdrom_device_ops mcdx_dops = {
 	.open		= mcdx_open,
@@ -1260,11 +1264,7 @@
 int __init mcdx_init(void)
 {
 	int drive;
-#ifdef MODULE
-	xwarn("Version 2.14(hs) for " UTS_RELEASE "\n");
-#else
 	xwarn("Version 2.14(hs) \n");
-#endif
 
 	xwarn("$Id: mcdx.c,v 1.21 1997/01/26 07:12:59 davem Exp $\n");
 
diff -Nru a/drivers/cdrom/optcd.c b/drivers/cdrom/optcd.c
--- a/drivers/cdrom/optcd.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/cdrom/optcd.c	2005-03-01 23:38:54 -08:00
@@ -116,7 +116,7 @@
 
 #define optcd_port optcd			/* Needed for the modutils. */
 static short optcd_port = OPTCD_PORTBASE;	/* I/O base of drive. */
-MODULE_PARM(optcd_port, "h");
+module_param(optcd_port, short, 0);
 /* Drive registers, read */
 #define DATA_PORT	optcd_port	/* Read data/status */
 #define STATUS_PORT	optcd_port+1	/* Indicate data/status availability */
@@ -265,7 +265,7 @@
 static DECLARE_WAIT_QUEUE_HEAD(waitq);
 static void sleep_timer(unsigned long data);
 static struct timer_list delay_timer = TIMER_INITIALIZER(sleep_timer, 0, 0);
-static spinlock_t optcd_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(optcd_lock);
 static struct request_queue *opt_queue;
 
 /* Timer routine: wake up when desired flag goes low,
diff -Nru a/drivers/cdrom/sbpcd.c b/drivers/cdrom/sbpcd.c
--- a/drivers/cdrom/sbpcd.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/cdrom/sbpcd.c	2005-03-01 23:38:53 -08:00
@@ -461,7 +461,7 @@
 /*
  * Protects access to global structures etc.
  */
-static spinlock_t sbpcd_lock __cacheline_aligned = SPIN_LOCK_UNLOCKED;
+static  __cacheline_aligned DEFINE_SPINLOCK(sbpcd_lock);
 static struct request_queue *sbpcd_queue;
 
 MODULE_PARM(sbpcd, "2i");
diff -Nru a/drivers/cdrom/sjcd.c b/drivers/cdrom/sjcd.c
--- a/drivers/cdrom/sjcd.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/cdrom/sjcd.c	2005-03-01 23:39:07 -08:00
@@ -107,7 +107,7 @@
 static volatile unsigned char sjcd_completion_error = 0;
 static unsigned short sjcd_command_is_in_progress = 0;
 static unsigned short sjcd_error_reported = 0;
-static spinlock_t sjcd_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(sjcd_lock);
 
 static int sjcd_open_count;
 
@@ -116,7 +116,7 @@
 
 static int sjcd_base = SJCD_BASE_ADDR;
 
-MODULE_PARM(sjcd_base, "i");
+module_param(sjcd_base, int, 0);
 
 static DECLARE_WAIT_QUEUE_HEAD(sjcd_waitq);
 
diff -Nru a/drivers/cdrom/sonycd535.c b/drivers/cdrom/sonycd535.c
--- a/drivers/cdrom/sonycd535.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/cdrom/sonycd535.c	2005-03-01 23:39:18 -08:00
@@ -210,7 +210,7 @@
 /* The base I/O address of the Sony Interface.  This is a variable (not a
    #define) so it can be easily changed via some future ioctl() */
 static unsigned int sony535_cd_base_io = CDU535_ADDRESS;
-MODULE_PARM(sony535_cd_base_io, "i");
+module_param(sony535_cd_base_io, int, 0);
 
 /*
  * The following are I/O addresses of the various registers for the drive.  The
@@ -222,7 +222,7 @@
 static unsigned short read_status_reg;
 static unsigned short data_reg;
 
-static spinlock_t sonycd535_lock = SPIN_LOCK_UNLOCKED; /* queue lock */
+static DEFINE_SPINLOCK(sonycd535_lock); /* queue lock */
 static struct request_queue *sonycd535_queue;
 
 static int initialized;			/* Has the drive been initialized? */
diff -Nru a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c
--- a/drivers/cdrom/viocd.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/cdrom/viocd.c	2005-03-01 23:39:17 -08:00
@@ -765,8 +765,6 @@
 	vio_setHandler(viomajorsubtype_cdio, vio_handle_cd_event);
 
 	get_viocd_info();
-	if (viocd_numdev == 0)
-		goto out_undo_vio;
 
 	spin_lock_init(&viocd_reqlock);
 
@@ -786,7 +784,6 @@
 	dma_free_coherent(iSeries_vio_dev,
 			sizeof(*viocd_unitinfo) * VIOCD_MAX_CD,
 			viocd_unitinfo, unitinfo_dmaaddr);
-out_undo_vio:
 	vio_clearHandler(viomajorsubtype_cdio);
 	viopath_close(viopath_hostLp, viomajorsubtype_cdio, MAX_CD_REQ + 2);
 out_unregister:
diff -Nru a/drivers/char/Kconfig b/drivers/char/Kconfig
--- a/drivers/char/Kconfig	2005-03-01 23:38:51 -08:00
+++ b/drivers/char/Kconfig	2005-03-01 23:38:51 -08:00
@@ -203,7 +203,7 @@
 
 config ISI
 	tristate "Multi-Tech multiport card support (EXPERIMENTAL)"
-	depends on SERIAL_NONSTANDARD && PCI && EXPERIMENTAL && BROKEN_ON_SMP && m
+	depends on SERIAL_NONSTANDARD
 	help
 	  This is a driver for the Multi-Tech cards which provide several
 	  serial ports.  The driver is experimental and can currently only be
@@ -347,22 +347,6 @@
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called istallion.
-
-config SERIAL_TX3912
-	bool "TX3912/PR31700 serial port support"
-	depends on SERIAL_NONSTANDARD && MIPS && BROKEN_ON_SMP
-	help
-	  The TX3912 is a Toshiba RISC processor based o the MIPS 3900 core;
-	  see <http://www.toshiba.com/taec/components/Generic/risc/tx3912.htm>.
-	  Say Y here to enable kernel support for the on-board serial port.
-
-config SERIAL_TX3912_CONSOLE
-	bool "Console on TX3912/PR31700 serial port"
-	depends on SERIAL_TX3912
-	help
-	  The TX3912 is a Toshiba RISC processor based o the MIPS 3900 core;
-	  see <http://www.toshiba.com/taec/components/Generic/risc/tx3912.htm>.
-	  Say Y here to direct console I/O to the on-board serial port.
 
 config AU1000_UART
 	bool "Enable Au1000 UART Support"
diff -Nru a/drivers/char/Makefile b/drivers/char/Makefile
--- a/drivers/char/Makefile	2005-03-01 23:39:16 -08:00
+++ b/drivers/char/Makefile	2005-03-01 23:39:16 -08:00
@@ -20,7 +20,6 @@
 obj-$(CONFIG_MVME147_SCC)	+= generic_serial.o vme_scc.o
 obj-$(CONFIG_MVME162_SCC)	+= generic_serial.o vme_scc.o
 obj-$(CONFIG_BVME6000_SCC)	+= generic_serial.o vme_scc.o
-obj-$(CONFIG_SERIAL_TX3912)	+= generic_serial.o serial_tx3912.o
 obj-$(CONFIG_ROCKETPORT)	+= rocket.o
 obj-$(CONFIG_SERIAL167)		+= serial167.o
 obj-$(CONFIG_CYCLADES)		+= cyclades.o
diff -Nru a/drivers/char/README.cycladesZ b/drivers/char/README.cycladesZ
--- a/drivers/char/README.cycladesZ	2005-03-01 23:38:58 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,8 +0,0 @@
-
-The Cyclades-Z must have firmware loaded onto the card before it will
-operate.  This operation should be performed during system startup,
-
-The firmware, loader program and the latest device driver code are
-available from Cyclades at
-    ftp://ftp.cyclades.com/pub/cyclades/cyclades-z/linux/
-
diff -Nru a/drivers/char/agp/Kconfig b/drivers/char/agp/Kconfig
--- a/drivers/char/agp/Kconfig	2005-03-01 23:38:58 -08:00
+++ b/drivers/char/agp/Kconfig	2005-03-01 23:38:58 -08:00
@@ -1,5 +1,6 @@
 config AGP
-	tristate "/dev/agpgart (AGP Support)" if !GART_IOMMU && !M68K && !ARM
+	tristate "/dev/agpgart (AGP Support)" if !GART_IOMMU
+	depends on ALPHA || IA64 || PPC32 || X86
 	default y if GART_IOMMU
 	---help---
 	  AGP (Accelerated Graphics Port) is a bus system mainly used to
@@ -144,7 +145,7 @@
 
 config AGP_HP_ZX1
 	tristate "HP ZX1 chipset AGP support"
-	depends on AGP && (IA64_HP_ZX1 || IA64_GENERIC)
+	depends on AGP && (IA64_HP_ZX1 || IA64_HP_ZX1_SWIOTLB || IA64_GENERIC)
 	help
 	  This option gives you AGP GART support for the HP ZX1 chipset
 	  for IA64 processors.
diff -Nru a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h
--- a/drivers/char/agp/agp.h	2005-03-01 23:38:56 -08:00
+++ b/drivers/char/agp/agp.h	2005-03-01 23:38:56 -08:00
@@ -141,16 +141,6 @@
 	char minor_version;
 };
 
-#define OUTREG64(mmap, addr, val)	__raw_writeq((val), (mmap)+(addr))
-#define OUTREG32(mmap, addr, val)	__raw_writel((val), (mmap)+(addr))
-#define OUTREG16(mmap, addr, val)	__raw_writew((val), (mmap)+(addr))
-#define OUTREG8(mmap, addr, val)	__raw_writeb((val), (mmap)+(addr))
-
-#define INREG64(mmap, addr)		__raw_readq((mmap)+(addr))
-#define INREG32(mmap, addr)		__raw_readl((mmap)+(addr))
-#define INREG16(mmap, addr)		__raw_readw((mmap)+(addr))
-#define INREG8(mmap, addr)		__raw_readb((mmap)+(addr))
-
 #define KB(x)	((x) * 1024)
 #define MB(x)	(KB (KB (x)))
 #define GB(x)	(MB (KB (x)))
diff -Nru a/drivers/char/agp/ali-agp.c b/drivers/char/agp/ali-agp.c
--- a/drivers/char/agp/ali-agp.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/char/agp/ali-agp.c	2005-03-01 23:39:07 -08:00
@@ -277,6 +277,15 @@
 		.device_id	= PCI_DEVICE_ID_AL_M1671,
 		.chipset_name	= "M1671",
 	},
+	{
+		.device_id	= PCI_DEVICE_ID_AL_M1681,
+		.chipset_name	= "M1681",
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_AL_M1683,
+		.chipset_name	= "M1683",
+	},
+
 	{ }, /* dummy final entry, always present */
 };
 
@@ -387,6 +396,8 @@
 
 static int __init agp_ali_init(void)
 {
+	if (agp_off)
+		return -EINVAL;
 	return pci_module_init(&agp_ali_pci_driver);
 }
 
diff -Nru a/drivers/char/agp/alpha-agp.c b/drivers/char/agp/alpha-agp.c
--- a/drivers/char/agp/alpha-agp.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/char/agp/alpha-agp.c	2005-03-01 23:39:07 -08:00
@@ -195,6 +195,8 @@
 
 static int __init agp_alpha_core_init(void)
 {
+	if (agp_off)
+		return -EINVAL;
 	if (alpha_mv.agp_info)
 		return alpha_core_agp_setup();
 	return -ENODEV;
diff -Nru a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c
--- a/drivers/char/agp/amd-k7-agp.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/char/agp/amd-k7-agp.c	2005-03-01 23:39:18 -08:00
@@ -53,8 +53,10 @@
 	}
 	global_cache_flush();
 
-	for (i = 0; i < PAGE_SIZE / sizeof(unsigned long); i++)
+	for (i = 0; i < PAGE_SIZE / sizeof(unsigned long); i++) {
 		writel(agp_bridge->scratch_page, page_map->remapped+i);
+		readl(page_map->remapped+i);	/* PCI Posting. */
+	}
 
 	return 0;
 }
@@ -167,6 +169,7 @@
 	for (i = 0; i < value->num_entries / 1024; i++, addr += 0x00400000) {
 		writel(virt_to_phys(amd_irongate_private.gatt_pages[i]->real) | 1,
 			page_dir.remapped+GET_PAGE_DIR_OFF(addr));
+		readl(page_dir.remapped+GET_PAGE_DIR_OFF(addr));	/* PCI Posting. */
 	}
 
 	return 0;
@@ -220,8 +223,8 @@
 	amd_irongate_private.registers = (volatile u8 __iomem *) ioremap(temp, 4096);
 
 	/* Write out the address of the gatt table */
-	OUTREG32(amd_irongate_private.registers, AMD_ATTBASE,
-		 agp_bridge->gatt_bus_addr);
+	writel(agp_bridge->gatt_bus_addr, amd_irongate_private.registers+AMD_ATTBASE);
+	readl(amd_irongate_private.registers+AMD_ATTBASE);	/* PCI Posting. */
 
 	/* Write the Sync register */
 	pci_write_config_byte(agp_bridge->dev, AMD_MODECNTL, 0x80);
@@ -230,19 +233,19 @@
 	pci_write_config_byte(agp_bridge->dev, AMD_MODECNTL2, 0x00);
 
 	/* Write the enable register */
-	enable_reg = INREG16(amd_irongate_private.registers, AMD_GARTENABLE);
+	enable_reg = readw(amd_irongate_private.registers+AMD_GARTENABLE);
 	enable_reg = (enable_reg | 0x0004);
-	OUTREG16(amd_irongate_private.registers, AMD_GARTENABLE, enable_reg);
+	writew(enable_reg, amd_irongate_private.registers+AMD_GARTENABLE);
+	readw(amd_irongate_private.registers+AMD_GARTENABLE);	/* PCI Posting. */
 
 	/* Write out the size register */
 	pci_read_config_dword(agp_bridge->dev, AMD_APSIZE, &temp);
-	temp = (((temp & ~(0x0000000e)) | current_size->size_value)
-		| 0x00000001);
+	temp = (((temp & ~(0x0000000e)) | current_size->size_value) | 1);
 	pci_write_config_dword(agp_bridge->dev, AMD_APSIZE, temp);
 
 	/* Flush the tlb */
-	OUTREG32(amd_irongate_private.registers, AMD_TLBFLUSH, 0x00000001);
-
+	writel(1, amd_irongate_private.registers+AMD_TLBFLUSH);
+	readl(amd_irongate_private.registers+AMD_TLBFLUSH);	/* PCI Posting.*/
 	return 0;
 }
 
@@ -254,9 +257,10 @@
 
 	previous_size = A_SIZE_LVL2(agp_bridge->previous_size);
 
-	enable_reg = INREG16(amd_irongate_private.registers, AMD_GARTENABLE);
+	enable_reg = readw(amd_irongate_private.registers+AMD_GARTENABLE);
 	enable_reg = (enable_reg & ~(0x0004));
-	OUTREG16(amd_irongate_private.registers, AMD_GARTENABLE, enable_reg);
+	writew(enable_reg, amd_irongate_private.registers+AMD_GARTENABLE);
+	readw(amd_irongate_private.registers+AMD_GARTENABLE);	/* PCI Posting. */
 
 	/* Write back the previous size and disable gart translation */
 	pci_read_config_dword(agp_bridge->dev, AMD_APSIZE, &temp);
@@ -275,7 +279,8 @@
 
 static void amd_irongate_tlbflush(struct agp_memory *temp)
 {
-	OUTREG32(amd_irongate_private.registers, AMD_TLBFLUSH, 0x00000001);
+	writel(1, amd_irongate_private.registers+AMD_TLBFLUSH);
+	readl(amd_irongate_private.registers+AMD_TLBFLUSH);	/* PCI Posting. */
 }
 
 static int amd_insert_memory(struct agp_memory *mem, off_t pg_start, int type)
@@ -310,6 +315,7 @@
 		addr = (j * PAGE_SIZE) + agp_bridge->gart_bus_addr;
 		cur_gatt = GET_GATT(addr);
 		writel(agp_generic_mask_memory(mem->memory[i], mem->type), cur_gatt+GET_GATT_OFF(addr));
+		readl(cur_gatt+GET_GATT_OFF(addr));	/* PCI Posting. */
 	}
 	amd_irongate_tlbflush(mem);
 	return 0;
@@ -328,6 +334,7 @@
 		addr = (i * PAGE_SIZE) + agp_bridge->gart_bus_addr;
 		cur_gatt = GET_GATT(addr);
 		writel(agp_bridge->scratch_page, cur_gatt+GET_GATT_OFF(addr));
+		readl(cur_gatt+GET_GATT_OFF(addr));	/* PCI Posting. */
 	}
 
 	amd_irongate_tlbflush(mem);
@@ -471,6 +478,8 @@
 
 static int __init agp_amdk7_init(void)
 {
+	if (agp_off)
+		return -EINVAL;
 	return pci_module_init(&agp_amdk7_pci_driver);
 }
 
diff -Nru a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c
--- a/drivers/char/agp/amd64-agp.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/char/agp/amd64-agp.c	2005-03-01 23:39:07 -08:00
@@ -46,6 +46,11 @@
 #define NVIDIA_X86_64_1_APBASE2		0xd8
 #define NVIDIA_X86_64_1_APLIMIT2	0xdc
 
+/* ULi K8 registers */
+#define ULI_X86_64_BASE_ADDR		0x10
+#define ULI_X86_64_HTT_FEA_REG		0x50
+#define ULI_X86_64_ENU_SCR_REG		0x54
+
 static int nr_garts;
 static struct pci_dev * hammers[MAX_HAMMER_GARTS];
 
@@ -109,6 +114,7 @@
 		pte |= GPTE_VALID | GPTE_COHERENT;
 
 		writel(pte, agp_bridge->gatt_table+j);
+		readl(agp_bridge->gatt_table+j);	/* PCI Posting. */
 	}
 	amd64_tlbflush(mem);
 	return 0;
@@ -355,7 +361,7 @@
 	int i = 0;
 
 	/* cache pci_devs of northbridges. */
-	while ((loop_dev = pci_find_device(PCI_VENDOR_ID_AMD, 0x1103, loop_dev))
+	while ((loop_dev = pci_get_device(PCI_VENDOR_ID_AMD, 0x1103, loop_dev))
 			!= NULL) {
 		if (i == MAX_HAMMER_GARTS) {
 			printk(KERN_ERR PFX "Too many northbridges for AGP\n");
@@ -405,6 +411,61 @@
 	}
 }
 
+
+static struct aper_size_info_32 uli_sizes[7] =
+{
+	{256, 65536, 6, 10},
+	{128, 32768, 5, 9},
+	{64, 16384, 4, 8},
+	{32, 8192, 3, 7},
+	{16, 4096, 2, 6},
+	{8, 2048, 1, 4},
+	{4, 1024, 0, 3}
+};
+static int __devinit uli_agp_init(struct pci_dev *pdev)
+{
+	u32 httfea,baseaddr,enuscr;
+	struct pci_dev *dev1;
+	int i;
+	unsigned size = amd64_fetch_size();
+	printk(KERN_INFO "Setting up ULi AGP. \n");
+	dev1 = pci_find_slot ((unsigned int)pdev->bus->number,PCI_DEVFN(0,0));
+	if (dev1 == NULL) {
+		printk(KERN_INFO PFX "Detected a ULi chipset, "
+			"but could not fine the secondary device.\n");
+		return -ENODEV;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(uli_sizes); i++)
+		if (uli_sizes[i].size == size)
+			break;
+
+	if (i == ARRAY_SIZE(uli_sizes)) {
+		printk(KERN_INFO PFX "No ULi size found for %d\n", size);
+		return -ENODEV;
+	}
+
+	/* shadow x86-64 registers into ULi registers */
+	pci_read_config_dword (hammers[0], AMD64_GARTAPERTUREBASE, &httfea);
+
+	/* if x86-64 aperture base is beyond 4G, exit here */
+	if ((httfea & 0x7fff) >> (32 - 25))
+		return -ENODEV;
+
+	httfea = (httfea& 0x7fff) << 25;
+
+	pci_read_config_dword(pdev, ULI_X86_64_BASE_ADDR, &baseaddr);
+	baseaddr&= ~PCI_BASE_ADDRESS_MEM_MASK;
+	baseaddr|= httfea;
+	pci_write_config_dword(pdev, ULI_X86_64_BASE_ADDR, baseaddr);
+
+	enuscr= httfea+ (size * 1024 * 1024) - 1;
+	pci_write_config_dword(dev1, ULI_X86_64_HTT_FEA_REG, httfea);
+	pci_write_config_dword(dev1, ULI_X86_64_ENU_SCR_REG, enuscr);
+	return 0;
+}
+
+
 static struct aper_size_info_32 nforce3_sizes[5] =
 {
 	{512,  131072, 7, 0x00000000 },
@@ -513,6 +574,14 @@
 		}
 	}
 
+	if (pdev->vendor == PCI_VENDOR_ID_AL) {
+		int ret = uli_agp_init(pdev);
+		if (ret) {
+			agp_put_bridge(bridge);
+			return ret;
+		}
+	}
+
 	pci_set_drvdata(pdev, bridge);
 	return agp_add_bridge(bridge);
 }
@@ -536,6 +605,15 @@
 	.subvendor	= PCI_ANY_ID,
 	.subdevice	= PCI_ANY_ID,
 	},
+	/* ULi M1689 */
+	{
+	.class		= (PCI_CLASS_BRIDGE_HOST << 8),
+	.class_mask	= ~0,
+	.vendor		= PCI_VENDOR_ID_AL,
+	.device		= PCI_DEVICE_ID_AL_M1689,
+	.subvendor	= PCI_ANY_ID,
+	.subdevice	= PCI_ANY_ID,
+	},
 	/* VIA K8T800Pro */
 	{
 	.class		= (PCI_CLASS_BRIDGE_HOST << 8),
@@ -581,7 +659,6 @@
 	.subvendor	= PCI_ANY_ID,
 	.subdevice	= PCI_ANY_ID,
 	},
-
 	/* NForce3 */
 	{
 	.class		= (PCI_CLASS_BRIDGE_HOST << 8),
@@ -625,6 +702,11 @@
 int __init agp_amd64_init(void)
 {
 	int err = 0;
+	static struct pci_device_id amd64nb[] = {
+		{ PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x1103) },
+		{ },
+	};
+
 	if (agp_off)
 		return -EINVAL;
 	if (pci_module_init(&agp_amd64_pci_driver) > 0) {
@@ -640,13 +722,13 @@
 		}
 
 		/* First check that we have at least one AMD64 NB */
-		if (!pci_find_device(PCI_VENDOR_ID_AMD, 0x1103, NULL))
+		if (!pci_dev_present(amd64nb))
 			return -ENODEV;
 
 		/* Look for any AGP bridge */
 		dev = NULL;
 		err = -ENODEV;
-		while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev))) {
+		for_each_pci_dev(dev) {
 			if (!pci_find_capability(dev, PCI_CAP_ID_AGP))
 				continue;
 			/* Only one bridge supported right now */
@@ -674,5 +756,5 @@
 #endif
 
 MODULE_AUTHOR("Dave Jones <davej@codemonkey.org.uk>, Andi Kleen");
-MODULE_PARM(agp_try_unsupported, "1i");
+module_param(agp_try_unsupported, bool, 0);
 MODULE_LICENSE("GPL");
diff -Nru a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c
--- a/drivers/char/agp/ati-agp.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/char/agp/ati-agp.c	2005-03-01 23:39:08 -08:00
@@ -61,9 +61,6 @@
 
 	SetPageReserved(virt_to_page(page_map->real));
 	err = map_page_into_agp(virt_to_page(page_map->real));
-
-	/* CACHE_FLUSH(); */
-	global_cache_flush();
 	page_map->remapped = ioremap_nocache(virt_to_phys(page_map->real),
 					    PAGE_SIZE);
 	if (page_map->remapped == NULL || err) {
@@ -75,8 +72,10 @@
 	/*CACHE_FLUSH();*/
 	global_cache_flush();
 
-	for(i = 0; i < PAGE_SIZE / sizeof(unsigned long); i++)
+	for(i = 0; i < PAGE_SIZE / sizeof(unsigned long); i++) {
 		writel(agp_bridge->scratch_page, page_map->remapped+i);
+		readl(page_map->remapped+i);	/* PCI Posting. */
+	}
 
 	return 0;
 }
@@ -186,7 +185,8 @@
 
 static void ati_tlbflush(struct agp_memory * mem)
 {
-	OUTREG32(ati_generic_private.registers, ATI_GART_CACHE_CNTRL, 1);
+	writel(1, ati_generic_private.registers+ATI_GART_CACHE_CNTRL);
+	readl(ati_generic_private.registers+ATI_GART_CACHE_CNTRL);	/* PCI Posting. */
 }
 
 static void ati_cleanup(void)
@@ -230,15 +230,16 @@
 	agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
 	printk(KERN_INFO PFX "IGP320 gart_bus_addr: %x\n", agp_bridge.gart_bus_addr);
         */
-	OUTREG32(ati_generic_private.registers, ATI_GART_FEATURE_ID, 0x60000);
+	writel(0x60000, ati_generic_private.registers+ATI_GART_FEATURE_ID);
+	readl(ati_generic_private.registers+ATI_GART_FEATURE_ID);	/* PCI Posting.*/
 
 	/* SIGNALED_SYSTEM_ERROR @ NB_STATUS */
 	pci_read_config_dword(agp_bridge->dev, 4, &temp);
 	pci_write_config_dword(agp_bridge->dev, 4, temp | (1<<14));
 
 	/* Write out the address of the gatt table */
-	OUTREG32(ati_generic_private.registers, ATI_GART_BASE,
-		 agp_bridge->gatt_bus_addr);
+	writel(agp_bridge->gatt_bus_addr, ati_generic_private.registers+ATI_GART_BASE);
+	readl(ati_generic_private.registers+ATI_GART_BASE);	/* PCI Posting. */
 
 	return 0;
 }
@@ -291,6 +292,7 @@
 		addr = (j * PAGE_SIZE) + agp_bridge->gart_bus_addr;
 		cur_gatt = GET_GATT(addr);
 		writel(agp_bridge->driver->mask_memory(mem->memory[i], mem->type), cur_gatt+GET_GATT_OFF(addr));
+		readl(cur_gatt+GET_GATT_OFF(addr));	/* PCI Posting. */
 	}
 	agp_bridge->driver->tlb_flush(mem);
 	return 0;
@@ -310,6 +312,7 @@
 		addr = (i * PAGE_SIZE) + agp_bridge->gart_bus_addr;
 		cur_gatt = GET_GATT(addr);
 		writel(agp_bridge->scratch_page, cur_gatt+GET_GATT_OFF(addr));
+		readl(cur_gatt+GET_GATT_OFF(addr)); /* PCI Posting. */
 	}
 
 	agp_bridge->driver->tlb_flush(mem);
@@ -371,6 +374,7 @@
 	for(i = 0; i < value->num_entries / 1024; i++, addr += 0x00400000) {
 		writel(virt_to_bus(ati_generic_private.gatt_pages[i]->real) | 1,
 			page_dir.remapped+GET_PAGE_DIR_OFF(addr));
+		readl(page_dir.remapped+GET_PAGE_DIR_OFF(addr));	/* PCI Posting. */
 	}
 
 	return 0;
@@ -525,6 +529,8 @@
 
 static int __init agp_ati_init(void)
 {
+	if (agp_off)
+		return -EINVAL;
 	return pci_module_init(&agp_ati_pci_driver);
 }
 
diff -Nru a/drivers/char/agp/backend.c b/drivers/char/agp/backend.c
--- a/drivers/char/agp/backend.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/char/agp/backend.c	2005-03-01 23:39:08 -08:00
@@ -214,17 +214,6 @@
 				phys_to_virt(bridge->scratch_page_real));
 }
 
-static const drm_agp_t drm_agp = {
-	&agp_free_memory,
-	&agp_allocate_memory,
-	&agp_bind_memory,
-	&agp_unbind_memory,
-	&agp_enable,
-	&agp_backend_acquire,
-	&agp_backend_release,
-	&agp_copy_info
-};
-
 /* XXX Kludge alert: agpgart isn't ready for multiple bridges yet */
 struct agp_bridge_data *agp_alloc_bridge(void)
 {
@@ -277,9 +266,6 @@
 		goto frontend_err;
 	}
 
-	/* FIXME: What to do with this? */
-	inter_module_register("drm_agp", THIS_MODULE, &drm_agp);
-
 	agp_count++;
 	return 0;
 
@@ -298,7 +284,6 @@
 	bridge->type = NOT_SUPPORTED;
 	agp_frontend_cleanup();
 	agp_backend_cleanup(bridge);
-	inter_module_unregister("drm_agp");
 	agp_count--;
 	module_put(bridge->driver->owner);
 }
diff -Nru a/drivers/char/agp/efficeon-agp.c b/drivers/char/agp/efficeon-agp.c
--- a/drivers/char/agp/efficeon-agp.c	2005-03-01 23:38:44 -08:00
+++ b/drivers/char/agp/efficeon-agp.c	2005-03-01 23:38:44 -08:00
@@ -375,7 +375,7 @@
 	if (!r->start && r->end) {
 		if(pci_assign_resource(pdev, 0)) {
 			printk(KERN_ERR PFX "could not assign resource 0\n");
-			return (-ENODEV);
+			return -ENODEV;
 		}
 	}
 
@@ -386,7 +386,7 @@
 	*/
 	if (pci_enable_device(pdev)) {
 		printk(KERN_ERR PFX "Unable to Enable PCI device\n");
-		return (-ENODEV);
+		return -ENODEV;
 	}
 
 	/* Fill in the mode register */
@@ -440,6 +440,9 @@
 static int __init agp_efficeon_init(void)
 {
 	static int agp_initialised=0;
+
+	if (agp_off)
+		return -EINVAL;
 
 	if (agp_initialised == 1)
 		return 0;
diff -Nru a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c
--- a/drivers/char/agp/generic.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/char/agp/generic.c	2005-03-01 23:38:55 -08:00
@@ -35,7 +35,10 @@
 #include <linux/pm.h>
 #include <linux/agp_backend.h>
 #include <linux/vmalloc.h>
+#include <linux/mm.h>
 #include <asm/io.h>
+#include <asm/cacheflush.h>
+#include <asm/pgtable.h>
 #include "agp.h"
 
 __u32 *agp_gatt_table;
@@ -47,6 +50,26 @@
  */
 EXPORT_SYMBOL_GPL(agp_memory_reserved);
 
+#if defined(CONFIG_X86)
+int map_page_into_agp(struct page *page)
+{
+	int i;
+	i = change_page_attr(page, 1, PAGE_KERNEL_NOCACHE);
+	global_flush_tlb();
+	return i;
+}
+EXPORT_SYMBOL_GPL(map_page_into_agp);
+
+int unmap_page_from_agp(struct page *page)
+{
+	int i;
+	i = change_page_attr(page, 1, PAGE_KERNEL);
+	global_flush_tlb();
+	return i;
+}
+EXPORT_SYMBOL_GPL(unmap_page_from_agp);
+#endif
+
 /*
  * Generic routines for handling agp_memory structures -
  * They use the basic page allocation routines to do the brunt of the work.
@@ -181,8 +204,7 @@
 			agp_free_memory(new);
 			return NULL;
 		}
-		new->memory[i] =
-			agp_bridge->driver->mask_memory(virt_to_phys(addr), type);
+		new->memory[i] = virt_to_phys(addr);
 		new->page_count++;
 	}
 
@@ -507,7 +529,7 @@
 	u32 tmp;
 	u32 agp3;
 
-	while ((device = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, device)) != NULL) {
+	for_each_pci_dev(device) {
 		cap_ptr = pci_find_capability(device, PCI_CAP_ID_AGP);
 		if (!cap_ptr)
 			continue;
@@ -551,7 +573,7 @@
 	if (agp_v3)
 		mode *= 4;
 
-	while ((device = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, device)) != NULL) {
+	for_each_pci_dev(device) {
 		u8 agp = pci_find_capability(device, PCI_CAP_ID_AGP);
 		if (!agp)
 			continue;
@@ -737,8 +759,10 @@
 	agp_bridge->gatt_bus_addr = virt_to_phys(agp_bridge->gatt_table_real);
 
 	/* AK: bogus, should encode addresses > 4GB */
-	for (i = 0; i < num_entries; i++)
+	for (i = 0; i < num_entries; i++) {
 		writel(agp_bridge->scratch_page, agp_bridge->gatt_table+i);
+		readl(agp_bridge->gatt_table+i);	/* PCI Posting. */
+	}
 
 	return 0;
 }
@@ -854,8 +878,10 @@
 		mem->is_flushed = TRUE;
 	}
 
-	for (i = 0, j = pg_start; i < mem->page_count; i++, j++)
+	for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
 		writel(agp_bridge->driver->mask_memory(mem->memory[i], mem->type), agp_bridge->gatt_table+j);
+		readl(agp_bridge->gatt_table+j);	/* PCI Posting. */
+	}
 
 	agp_bridge->driver->tlb_flush(mem);
 	return 0;
@@ -873,9 +899,12 @@
 	}
 
 	/* AK: bogus, should encode addresses > 4GB */
-	for (i = pg_start; i < (mem->page_count + pg_start); i++)
+	for (i = pg_start; i < (mem->page_count + pg_start); i++) {
 		writel(agp_bridge->scratch_page, agp_bridge->gatt_table+i);
+		readl(agp_bridge->gatt_table+i);	/* PCI Posting. */
+	}
 
+	global_cache_flush();
 	agp_bridge->driver->tlb_flush(mem);
 	return 0;
 }
@@ -958,21 +987,15 @@
 EXPORT_SYMBOL(agp_enable);
 
 
-#ifdef CONFIG_SMP
 static void ipi_handler(void *null)
 {
 	flush_agp_cache();
 }
-#endif
 
 void global_cache_flush(void)
 {
-#ifdef CONFIG_SMP
 	if (on_each_cpu(ipi_handler, NULL, 1, 1) != 0)
 		panic(PFX "timed out waiting for the other CPUs!\n");
-#else
-	flush_agp_cache();
-#endif
 }
 EXPORT_SYMBOL(global_cache_flush);
 
diff -Nru a/drivers/char/agp/hp-agp.c b/drivers/char/agp/hp-agp.c
--- a/drivers/char/agp/hp-agp.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/char/agp/hp-agp.c	2005-03-01 23:39:09 -08:00
@@ -88,7 +88,7 @@
 	 * 	- IOVA space is 1Gb in size
 	 * 	- first 512Mb is IOMMU, second 512Mb is GART
 	 */
-	hp->io_tlb_ps = INREG64(hp->ioc_regs, HP_ZX1_TCNFG);
+	hp->io_tlb_ps = readq(hp->ioc_regs+HP_ZX1_TCNFG);
 	switch (hp->io_tlb_ps) {
 		case 0: hp->io_tlb_shift = 12; break;
 		case 1: hp->io_tlb_shift = 13; break;
@@ -104,13 +104,13 @@
 	hp->io_page_size = 1 << hp->io_tlb_shift;
 	hp->io_pages_per_kpage = PAGE_SIZE / hp->io_page_size;
 
-	hp->iova_base = INREG64(hp->ioc_regs, HP_ZX1_IBASE) & ~0x1;
+	hp->iova_base = readq(hp->ioc_regs+HP_ZX1_IBASE) & ~0x1;
 	hp->gart_base = hp->iova_base + HP_ZX1_IOVA_SIZE - HP_ZX1_GART_SIZE;
 
 	hp->gart_size = HP_ZX1_GART_SIZE;
 	hp->gatt_entries = hp->gart_size / hp->io_page_size;
 
-	hp->io_pdir = phys_to_virt(INREG64(hp->ioc_regs, HP_ZX1_PDIR_BASE));
+	hp->io_pdir = phys_to_virt(readq(hp->ioc_regs+HP_ZX1_PDIR_BASE));
 	hp->gatt = &hp->io_pdir[HP_ZX1_IOVA_TO_PDIR(hp->gart_base)];
 
 	if (hp->gatt[0] != HP_ZX1_SBA_IOMMU_COOKIE) {
@@ -174,7 +174,7 @@
 	 * If the IOTLB is currently disabled, we can take it over.
 	 * Otherwise, we have to share with sba_iommu.
 	 */
-	hp->io_pdir_owner = (INREG64(hp->ioc_regs, HP_ZX1_IBASE) & 0x1) == 0;
+	hp->io_pdir_owner = (readq(hp->ioc_regs+HP_ZX1_IBASE) & 0x1) == 0;
 
 	if (hp->io_pdir_owner)
 		return hp_zx1_ioc_owner();
@@ -189,18 +189,18 @@
 	u8 pos, id;
 	int ttl = 48;
 
-	status = INREG16(hpa, PCI_STATUS);
+	status = readw(hpa+PCI_STATUS);
 	if (!(status & PCI_STATUS_CAP_LIST))
 		return 0;
-	pos = INREG8(hpa, PCI_CAPABILITY_LIST);
+	pos = readb(hpa+PCI_CAPABILITY_LIST);
 	while (ttl-- && pos >= 0x40) {
 		pos &= ~3;
-		id = INREG8(hpa, pos + PCI_CAP_LIST_ID);
+		id = readb(hpa+pos+PCI_CAP_LIST_ID);
 		if (id == 0xff)
 			break;
 		if (id == cap)
 			return pos;
-		pos = INREG8(hpa, pos + PCI_CAP_LIST_NEXT);
+		pos = readb(hpa+pos+PCI_CAP_LIST_NEXT);
 	}
 	return 0;
 }
@@ -217,7 +217,7 @@
 
 	hp->lba_cap_offset = hp_zx1_lba_find_capability(hp->lba_regs, PCI_CAP_ID_AGP);
 
-	cap = INREG32(hp->lba_regs, hp->lba_cap_offset) & 0xff;
+	cap = readl(hp->lba_regs+hp->lba_cap_offset) & 0xff;
 	if (cap != PCI_CAP_ID_AGP) {
 		printk(KERN_ERR PFX "Invalid capability ID 0x%02x at 0x%x\n",
 		       cap, hp->lba_cap_offset);
@@ -245,15 +245,19 @@
 
 	agp_bridge->gart_bus_addr = hp->gart_base;
 	agp_bridge->capndx = hp->lba_cap_offset;
-	agp_bridge->mode = INREG32(hp->lba_regs, hp->lba_cap_offset + PCI_AGP_STATUS);
+	agp_bridge->mode = readl(hp->lba_regs+hp->lba_cap_offset+PCI_AGP_STATUS);
 
 	if (hp->io_pdir_owner) {
-		OUTREG64(hp->ioc_regs, HP_ZX1_PDIR_BASE, virt_to_phys(hp->io_pdir));
-		OUTREG64(hp->ioc_regs, HP_ZX1_TCNFG, hp->io_tlb_ps);
-		OUTREG64(hp->ioc_regs, HP_ZX1_IMASK, ~(HP_ZX1_IOVA_SIZE - 1));
-		OUTREG64(hp->ioc_regs, HP_ZX1_IBASE, hp->iova_base | 0x1);
-		OUTREG64(hp->ioc_regs, HP_ZX1_PCOM, hp->iova_base | log2(HP_ZX1_IOVA_SIZE));
-		INREG64(hp->ioc_regs, HP_ZX1_PCOM);
+		writel(virt_to_phys(hp->io_pdir), hp->ioc_regs+HP_ZX1_PDIR_BASE);
+		readl(hp->ioc_regs+HP_ZX1_PDIR_BASE);
+		writel(hp->io_tlb_ps, hp->ioc_regs+HP_ZX1_TCNFG);
+		readl(hp->ioc_regs+HP_ZX1_TCNFG);
+		writel(~(HP_ZX1_IOVA_SIZE-1), hp->ioc_regs+HP_ZX1_IMASK);
+		readl(hp->ioc_regs+HP_ZX1_IMASK);
+		writel(hp->iova_base|1, hp->ioc_regs+HP_ZX1_IBASE);
+		readl(hp->ioc_regs+HP_ZX1_IBASE);
+		writel(hp->iova_base|log2(HP_ZX1_IOVA_SIZE), hp->ioc_regs+HP_ZX1_PCOM);
+		readl(hp->ioc_regs+HP_ZX1_PCOM);
 	}
 
 	return 0;
@@ -265,8 +269,10 @@
 	struct _hp_private *hp = &hp_private;
 
 	if (hp->ioc_regs) {
-		if (hp->io_pdir_owner)
-			OUTREG64(hp->ioc_regs, HP_ZX1_IBASE, 0);
+		if (hp->io_pdir_owner) {
+			writeq(0, hp->ioc_regs+HP_ZX1_IBASE);
+			readq(hp->ioc_regs+HP_ZX1_IBASE);
+		}
 		iounmap(hp->ioc_regs);
 	}
 	if (hp->lba_regs)
@@ -278,8 +284,8 @@
 {
 	struct _hp_private *hp = &hp_private;
 
-	OUTREG64(hp->ioc_regs, HP_ZX1_PCOM, hp->gart_base | log2(hp->gart_size));
-	INREG64(hp->ioc_regs, HP_ZX1_PCOM);
+	writeq(hp->gart_base | log2(hp->gart_size), hp->ioc_regs+HP_ZX1_PCOM);
+	readq(hp->ioc_regs+HP_ZX1_PCOM);
 }
 
 static int
@@ -401,12 +407,11 @@
 	struct _hp_private *hp = &hp_private;
 	u32 command;
 
-	command = INREG32(hp->lba_regs, hp->lba_cap_offset + PCI_AGP_STATUS);
-
+	command = readl(hp->lba_regs+hp->lba_cap_offset+PCI_AGP_STATUS);
 	command = agp_collect_device_status(mode, command);
 	command |= 0x00000100;
 
-	OUTREG32(hp->lba_regs, hp->lba_cap_offset + PCI_AGP_COMMAND, command);
+	writel(command, hp->lba_regs+hp->lba_cap_offset+PCI_AGP_COMMAND);
 
 	agp_device_command(command, (mode & AGP8X_MODE) != 0);
 }
@@ -519,6 +524,8 @@
 static int __init
 agp_hp_init (void)
 {
+	if (agp_off)
+		return -EINVAL;
 
 	acpi_get_devices("HWP0003", zx1_gart_probe, "HWP0003", NULL);
 	if (hp_zx1_gart_found)
diff -Nru a/drivers/char/agp/i460-agp.c b/drivers/char/agp/i460-agp.c
--- a/drivers/char/agp/i460-agp.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/char/agp/i460-agp.c	2005-03-01 23:38:58 -08:00
@@ -532,8 +532,8 @@
 static unsigned long i460_mask_memory (unsigned long addr, int type)
 {
 	/* Make sure the returned address is a valid GATT entry */
-	return (agp_bridge->driver->masks[0].mask
-		| (((addr & ~((1 << I460_IO_PAGE_SHIFT) - 1)) & 0xffffff000) >> 12));
+	return agp_bridge->driver->masks[0].mask
+		| (((addr & ~((1 << I460_IO_PAGE_SHIFT) - 1)) & 0xffffff000) >> 12);
 }
 
 struct agp_bridge_driver intel_i460_driver = {
@@ -585,6 +585,8 @@
 	bridge->dev = pdev;
 	bridge->capndx = cap_ptr;
 
+	printk(KERN_INFO PFX "Detected Intel 460GX chipset\n");
+
 	pci_set_drvdata(pdev, bridge);
 	return agp_add_bridge(bridge);
 }
@@ -620,6 +622,8 @@
 
 static int __init agp_intel_i460_init(void)
 {
+	if (agp_off)
+		return -EINVAL;
 	return pci_module_init(&agp_intel_i460_pci_driver);
 }
 
diff -Nru a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
--- a/drivers/char/agp/intel-agp.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/char/agp/intel-agp.c	2005-03-01 23:38:57 -08:00
@@ -6,7 +6,7 @@
  * Intel(R) 855GM/852GM and 865G support added by David Dawes
  * <dawes@tungstengraphics.com>.
  *
- * Intel(R) 915G support added by Alan Hourihane
+ * Intel(R) 915G/915GM support added by Alan Hourihane
  * <alanh@tungstengraphics.com>.
  */
 
@@ -117,7 +117,7 @@
 		return -ENOMEM;
 	}
 
-	if ((INREG32(intel_i810_private.registers, I810_DRAM_CTL)
+	if ((readl(intel_i810_private.registers+I810_DRAM_CTL)
 		& I810_DRAM_ROW_0) == I810_DRAM_ROW_0_SDRAM) {
 		/* This will need to be dynamically assigned */
 		printk(KERN_INFO PFX "detected 4MB dedicated video ram.\n");
@@ -125,23 +125,23 @@
 	}
 	pci_read_config_dword(intel_i810_private.i810_dev, I810_GMADDR, &temp);
 	agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
-	OUTREG32(intel_i810_private.registers, I810_PGETBL_CTL,
-		 agp_bridge->gatt_bus_addr | I810_PGETBL_ENABLED);
-	global_cache_flush();
+	writel(agp_bridge->gatt_bus_addr | I810_PGETBL_ENABLED, intel_i810_private.registers+I810_PGETBL_CTL);
+	readl(intel_i810_private.registers+I810_PGETBL_CTL);	/* PCI Posting. */
 
 	if (agp_bridge->driver->needs_scratch_page) {
 		for (i = 0; i < current_size->num_entries; i++) {
-			OUTREG32(intel_i810_private.registers,
-				 I810_PTE_BASE + (i * 4),
-				 agp_bridge->scratch_page);
+			writel(agp_bridge->scratch_page, intel_i810_private.registers+I810_PTE_BASE+(i*4));
+			readl(intel_i810_private.registers+I810_PTE_BASE+(i*4));	/* PCI posting. */
 		}
 	}
+	global_cache_flush();
 	return 0;
 }
 
 static void intel_i810_cleanup(void)
 {
-	OUTREG32(intel_i810_private.registers, I810_PGETBL_CTL, 0);
+	writel(0, intel_i810_private.registers+I810_PGETBL_CTL);
+	readl(intel_i810_private.registers);	/* PCI Posting. */
 	iounmap(intel_i810_private.registers);
 }
 
@@ -161,13 +161,15 @@
 	struct page * page;
 
 	page = alloc_pages(GFP_KERNEL, 2);
-	if (page == NULL) {
+	if (page == NULL)
 		return NULL;
-	}
+
 	if (change_page_attr(page, 4, PAGE_KERNEL_NOCACHE) < 0) {
+		global_flush_tlb();
 		__free_page(page);
 		return NULL;
 	}
+	global_flush_tlb();
 	get_page(page);
 	SetPageLocked(page);
 	atomic_inc(&agp_bridge->current_memory_agp);
@@ -183,6 +185,7 @@
 
 	page = virt_to_page(addr);
 	change_page_attr(page, 4, PAGE_KERNEL);
+	global_flush_tlb();
 	put_page(page);
 	unlock_page(page);
 	free_pages((unsigned long)addr, 2);
@@ -211,10 +214,8 @@
 			/* special insert */
 			global_cache_flush();
 			for (i = pg_start; i < (pg_start + mem->page_count); i++) {
-				OUTREG32(intel_i810_private.registers,
-					 I810_PTE_BASE + (i * 4),
-					 (i * 4096) | I810_PTE_LOCAL |
-					 I810_PTE_VALID);
+				writel((i*4096)|I810_PTE_LOCAL|I810_PTE_VALID, intel_i810_private.registers+I810_PTE_BASE+(i*4));
+				readl(intel_i810_private.registers+I810_PTE_BASE+(i*4));	/* PCI Posting. */
 			}
 			global_cache_flush();
 			agp_bridge->driver->tlb_flush(mem);
@@ -228,9 +229,9 @@
 insert:
 	global_cache_flush();
 	for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
-		OUTREG32(intel_i810_private.registers,
-			I810_PTE_BASE + (j * 4),
-			agp_bridge->driver->mask_memory(mem->memory[i], mem->type));
+		writel(agp_bridge->driver->mask_memory(mem->memory[i], mem->type),
+				intel_i810_private.registers+I810_PTE_BASE+(j*4));
+		readl(intel_i810_private.registers+I810_PTE_BASE+(j*4));	/* PCI Posting. */
 	}
 	global_cache_flush();
 
@@ -244,9 +245,8 @@
 	int i;
 
 	for (i = pg_start; i < (mem->page_count + pg_start); i++) {
-		OUTREG32(intel_i810_private.registers,
-			 I810_PTE_BASE + (i * 4),
-			 agp_bridge->scratch_page);
+		writel(agp_bridge->scratch_page, intel_i810_private.registers+I810_PTE_BASE+(i*4));
+		readl(intel_i810_private.registers+I810_PTE_BASE+(i*4));	/* PCI Posting. */
 	}
 
 	global_cache_flush();
@@ -318,7 +318,7 @@
 		return new;
 	}
 	if (type == AGP_PHYS_MEMORY)
-		return(alloc_agpphysmem_i8xx(pg_count, type));
+		return alloc_agpphysmem_i8xx(pg_count, type);
 
 	return NULL;
 }
@@ -387,8 +387,7 @@
 			gtt_entries = MB(8) - KB(size);
 			break;
 		case I830_GMCH_GMS_LOCAL:
-			rdct = INREG8(intel_i830_private.registers,
-				      I830_RDRAM_CHANNEL_TYPE);
+			rdct = readb(intel_i830_private.registers+I830_RDRAM_CHANNEL_TYPE);
 			gtt_entries = (I830_RDRAM_ND(rdct) + 1) *
 					MB(ddt[I830_RDRAM_DDT(rdct)]);
 			local = 1;
@@ -416,14 +415,16 @@
 			break;
 		case I915_GMCH_GMS_STOLEN_48M:
 			/* Check it's really I915G */
-			if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915G_HB)
+			if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915G_HB ||
+			    agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB)
 				gtt_entries = MB(48) - KB(size);
 			else
 				gtt_entries = 0;
 			break;
 		case I915_GMCH_GMS_STOLEN_64M:
 			/* Check it's really I915G */
-			if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915G_HB)
+			if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915G_HB ||
+			    agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB)
 				gtt_entries = MB(64) - KB(size);
 			else
 				gtt_entries = 0;
@@ -463,10 +464,10 @@
 
 	intel_i830_private.registers = ioremap(temp,128 * 4096);
 	if (!intel_i830_private.registers)
-		return (-ENOMEM);
+		return -ENOMEM;
 
-	temp = INREG32(intel_i830_private.registers,I810_PGETBL_CTL) & 0xfffff000;
-	global_cache_flush();
+	temp = readl(intel_i830_private.registers+I810_PGETBL_CTL) & 0xfffff000;
+	global_cache_flush();	/* FIXME: ?? */
 
 	/* we have to call this as early as possible after the MMIO base address is known */
 	intel_i830_init_gtt_entries();
@@ -475,7 +476,7 @@
 
 	agp_bridge->gatt_bus_addr = temp;
 
-	return(0);
+	return 0;
 }
 
 /* Return the gatt table to a sane state. Use the top of stolen
@@ -483,7 +484,7 @@
  */
 static int intel_i830_free_gatt_table(void)
 {
-	return(0);
+	return 0;
 }
 
 static int intel_i830_fetch_size(void)
@@ -498,7 +499,7 @@
 		/* 855GM/852GM/865G has 128MB aperture size */
 		agp_bridge->previous_size = agp_bridge->current_size = (void *) values;
 		agp_bridge->aperture_size_idx = 0;
-		return(values[0].size);
+		return values[0].size;
 	}
 
 	pci_read_config_word(agp_bridge->dev,I830_GMCH_CTRL,&gmch_ctrl);
@@ -506,14 +507,14 @@
 	if ((gmch_ctrl & I830_GMCH_MEM_MASK) == I830_GMCH_MEM_128M) {
 		agp_bridge->previous_size = agp_bridge->current_size = (void *) values;
 		agp_bridge->aperture_size_idx = 0;
-		return(values[0].size);
+		return values[0].size;
 	} else {
 		agp_bridge->previous_size = agp_bridge->current_size = (void *) (values + 1);
 		agp_bridge->aperture_size_idx = 1;
-		return(values[1].size);
+		return values[1].size;
 	}
 
-	return(0);
+	return 0;
 }
 
 static int intel_i830_configure(void)
@@ -532,14 +533,18 @@
 	gmch_ctrl |= I830_GMCH_ENABLED;
 	pci_write_config_word(agp_bridge->dev,I830_GMCH_CTRL,gmch_ctrl);
 
-	OUTREG32(intel_i830_private.registers,I810_PGETBL_CTL,agp_bridge->gatt_bus_addr | I810_PGETBL_ENABLED);
-	global_cache_flush();
+	writel(agp_bridge->gatt_bus_addr|I810_PGETBL_ENABLED, intel_i830_private.registers+I810_PGETBL_CTL);
+	readl(intel_i830_private.registers+I810_PGETBL_CTL);	/* PCI Posting. */
 
-	if (agp_bridge->driver->needs_scratch_page)
-		for (i = intel_i830_private.gtt_entries; i < current_size->num_entries; i++)
-			OUTREG32(intel_i830_private.registers,I810_PTE_BASE + (i * 4),agp_bridge->scratch_page);
+	if (agp_bridge->driver->needs_scratch_page) {
+		for (i = intel_i830_private.gtt_entries; i < current_size->num_entries; i++) {
+			writel(agp_bridge->scratch_page, intel_i830_private.registers+I810_PTE_BASE+(i*4));
+			readl(intel_i830_private.registers+I810_PTE_BASE+(i*4));	/* PCI Posting. */
+		}
+	}
 
-	return (0);
+	global_cache_flush();
+	return 0;
 }
 
 static void intel_i830_cleanup(void)
@@ -547,8 +552,7 @@
 	iounmap(intel_i830_private.registers);
 }
 
-static int intel_i830_insert_entries(struct agp_memory *mem,off_t pg_start,
-				int type)
+static int intel_i830_insert_entries(struct agp_memory *mem,off_t pg_start, int type)
 {
 	int i,j,num_entries;
 	void *temp;
@@ -561,11 +565,11 @@
 				pg_start,intel_i830_private.gtt_entries);
 
 		printk (KERN_INFO PFX "Trying to insert into local/stolen memory\n");
-		return (-EINVAL);
+		return -EINVAL;
 	}
 
 	if ((pg_start + mem->page_count) > num_entries)
-		return (-EINVAL);
+		return -EINVAL;
 
 	/* The i830 can't check the GTT for entries since its read only,
 	 * depend on the caller to make the correct offset decisions.
@@ -573,19 +577,19 @@
 
 	if ((type != 0 && type != AGP_PHYS_MEMORY) ||
 		(mem->type != 0 && mem->type != AGP_PHYS_MEMORY))
-		return (-EINVAL);
+		return -EINVAL;
 
-	global_cache_flush();
+	global_cache_flush();	/* FIXME: Necessary ?*/
 
-	for (i = 0, j = pg_start; i < mem->page_count; i++, j++)
-		OUTREG32(intel_i830_private.registers,I810_PTE_BASE + (j * 4),
-			agp_bridge->driver->mask_memory(mem->memory[i], mem->type));
+	for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
+		writel(agp_bridge->driver->mask_memory(mem->memory[i], mem->type),
+				intel_i830_private.registers+I810_PTE_BASE+(j*4));
+		readl(intel_i830_private.registers+I810_PTE_BASE+(j*4));	/* PCI Posting. */
+	}
 
 	global_cache_flush();
-
 	agp_bridge->driver->tlb_flush(mem);
-
-	return(0);
+	return 0;
 }
 
 static int intel_i830_remove_entries(struct agp_memory *mem,off_t pg_start,
@@ -597,26 +601,26 @@
 
 	if (pg_start < intel_i830_private.gtt_entries) {
 		printk (KERN_INFO PFX "Trying to disable local/stolen memory\n");
-		return (-EINVAL);
+		return -EINVAL;
 	}
 
-	for (i = pg_start; i < (mem->page_count + pg_start); i++)
-		OUTREG32(intel_i830_private.registers,I810_PTE_BASE + (i * 4),agp_bridge->scratch_page);
+	for (i = pg_start; i < (mem->page_count + pg_start); i++) {
+		writel(agp_bridge->scratch_page, intel_i830_private.registers+I810_PTE_BASE+(i*4));
+		readl(intel_i830_private.registers+I810_PTE_BASE+(i*4));	/* PCI Posting. */
+	}
 
 	global_cache_flush();
-
 	agp_bridge->driver->tlb_flush(mem);
-
-	return (0);
+	return 0;
 }
 
 static struct agp_memory *intel_i830_alloc_by_type(size_t pg_count,int type)
 {
 	if (type == AGP_PHYS_MEMORY)
-		return(alloc_agpphysmem_i8xx(pg_count, type));
+		return alloc_agpphysmem_i8xx(pg_count, type);
 
 	/* always return NULL for other allocation types for now */
-	return(NULL);
+	return NULL;
 }
 
 static int intel_i915_configure(void)
@@ -636,15 +640,18 @@
 	gmch_ctrl |= I830_GMCH_ENABLED;
 	pci_write_config_word(agp_bridge->dev,I830_GMCH_CTRL,gmch_ctrl);
 
-	OUTREG32(intel_i830_private.registers,I810_PGETBL_CTL,agp_bridge->gatt_bus_addr | I810_PGETBL_ENABLED);
-	global_cache_flush();
+	writel(agp_bridge->gatt_bus_addr|I810_PGETBL_ENABLED, intel_i830_private.registers+I810_PGETBL_CTL);
+	readl(intel_i830_private.registers+I810_PGETBL_CTL);	/* PCI Posting. */
 
 	if (agp_bridge->driver->needs_scratch_page) {
-		for (i = intel_i830_private.gtt_entries; i < current_size->num_entries; i++)
-			OUTREG32(intel_i830_private.gtt, i, agp_bridge->scratch_page);
+		for (i = intel_i830_private.gtt_entries; i < current_size->num_entries; i++) {
+			writel(agp_bridge->scratch_page, intel_i830_private.gtt+i);
+			readl(intel_i830_private.gtt+i);	/* PCI Posting. */
+		}
 	}
 
-	return (0);
+	global_cache_flush();
+	return 0;
 }
 
 static void intel_i915_cleanup(void)
@@ -667,11 +674,11 @@
 				pg_start,intel_i830_private.gtt_entries);
 
 		printk (KERN_INFO PFX "Trying to insert into local/stolen memory\n");
-		return (-EINVAL);
+		return -EINVAL;
 	}
 
 	if ((pg_start + mem->page_count) > num_entries)
-		return (-EINVAL);
+		return -EINVAL;
 
 	/* The i830 can't check the GTT for entries since its read only,
 	 * depend on the caller to make the correct offset decisions.
@@ -679,18 +686,18 @@
 
 	if ((type != 0 && type != AGP_PHYS_MEMORY) ||
 		(mem->type != 0 && mem->type != AGP_PHYS_MEMORY))
-		return (-EINVAL);
+		return -EINVAL;
 
 	global_cache_flush();
 
-	for (i = 0, j = pg_start; i < mem->page_count; i++, j++)
-		OUTREG32(intel_i830_private.gtt, j, agp_bridge->driver->mask_memory(mem->memory[i], mem->type));
+	for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
+		writel(agp_bridge->driver->mask_memory(mem->memory[i], mem->type), intel_i830_private.gtt+j);
+		readl(intel_i830_private.gtt+j);	/* PCI Posting. */
+	}
 
 	global_cache_flush();
-
 	agp_bridge->driver->tlb_flush(mem);
-
-	return(0);
+	return 0;
 }
 
 static int intel_i915_remove_entries(struct agp_memory *mem,off_t pg_start,
@@ -702,17 +709,17 @@
 
 	if (pg_start < intel_i830_private.gtt_entries) {
 		printk (KERN_INFO PFX "Trying to disable local/stolen memory\n");
-		return (-EINVAL);
+		return -EINVAL;
 	}
 
-	for (i = pg_start; i < (mem->page_count + pg_start); i++)
-		OUTREG32(intel_i830_private.gtt, i, agp_bridge->scratch_page);
+	for (i = pg_start; i < (mem->page_count + pg_start); i++) {
+		writel(agp_bridge->scratch_page, intel_i830_private.gtt+i);
+		readl(intel_i830_private.gtt+i);
+	}
 
 	global_cache_flush();
-
 	agp_bridge->driver->tlb_flush(mem);
-
-	return (0);
+	return 0;
 }
 
 static int intel_i915_fetch_size(void)
@@ -730,7 +737,7 @@
 	else
 		offset = 2;	/* 256MB aperture */
 	agp_bridge->previous_size = agp_bridge->current_size = (void *)(values + offset);
-	return(values[offset].size);
+	return values[offset].size;
 }
 
 /* The intel i915 automatically initializes the agp aperture during POST.
@@ -753,16 +760,16 @@
 
 	intel_i830_private.gtt = ioremap(temp2, 256 * 1024);
 	if (!intel_i830_private.gtt)
-		return (-ENOMEM);
+		return -ENOMEM;
 
 	temp &= 0xfff80000;
 
 	intel_i830_private.registers = ioremap(temp,128 * 4096);
 	if (!intel_i830_private.registers)
-		return (-ENOMEM);
+		return -ENOMEM;
 
-	temp = INREG32(intel_i830_private.registers,I810_PGETBL_CTL) & 0xfffff000;
-	global_cache_flush();
+	temp = readl(intel_i830_private.registers+I810_PGETBL_CTL) & 0xfffff000;
+	global_cache_flush();	/* FIXME: ? */
 
 	/* we have to call this as early as possible after the MMIO base address is known */
 	intel_i830_init_gtt_entries();
@@ -771,7 +778,7 @@
 
 	agp_bridge->gatt_bus_addr = temp;
 
-	return(0);
+	return 0;
 }
 
 static int intel_fetch_size(void)
@@ -1493,7 +1500,7 @@
 {
 	struct pci_dev *i810_dev;
 
-	i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL, device, NULL);
+	i810_dev = pci_get_device(PCI_VENDOR_ID_INTEL, device, NULL);
 	if (!i810_dev)
 		return 0;
 	intel_i810_private.i810_dev = i810_dev;
@@ -1504,9 +1511,9 @@
 {
 	struct pci_dev *i830_dev;
 
-	i830_dev = pci_find_device(PCI_VENDOR_ID_INTEL, device, NULL);
+	i830_dev = pci_get_device(PCI_VENDOR_ID_INTEL, device, NULL);
 	if (i830_dev && PCI_FUNC(i830_dev->devfn) != 0) {
-		i830_dev = pci_find_device(PCI_VENDOR_ID_INTEL,
+		i830_dev = pci_get_device(PCI_VENDOR_ID_INTEL,
 				device, i830_dev);
 	}
 
@@ -1643,6 +1650,14 @@
 		}
 		name = "915G";
 		break;
+	case PCI_DEVICE_ID_INTEL_82915GM_HB:
+		if (find_i830(PCI_DEVICE_ID_INTEL_82915GM_IG)) {
+			bridge->driver = &intel_915_driver;
+		} else {
+			bridge->driver = &intel_845_driver;
+		}
+		name = "915GM";
+		break;
 	case PCI_DEVICE_ID_INTEL_7505_0:
 		bridge->driver = &intel_7505_driver;
 		name = "E7505";
@@ -1716,6 +1731,12 @@
 	struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
 
 	agp_remove_bridge(bridge);
+
+	if (intel_i810_private.i810_dev)
+		pci_dev_put(intel_i810_private.i810_dev);
+	if (intel_i830_private.i830_dev)
+		pci_dev_put(intel_i830_private.i830_dev);
+
 	agp_put_bridge(bridge);
 }
 
@@ -1727,12 +1748,16 @@
 
 	if (bridge->driver == &intel_generic_driver)
 		intel_configure();
+	else if (bridge->driver == &intel_850_driver)
+		intel_850_configure();
 	else if (bridge->driver == &intel_845_driver)
 		intel_845_configure();
 	else if (bridge->driver == &intel_830mp_driver)
 		intel_830mp_configure();
 	else if (bridge->driver == &intel_915_driver)
 		intel_i915_configure();
+	else if (bridge->driver == &intel_830_driver)
+		intel_i830_configure();
 
 	return 0;
 }
@@ -1769,6 +1794,7 @@
 	ID(PCI_DEVICE_ID_INTEL_7505_0),
 	ID(PCI_DEVICE_ID_INTEL_7205_0),
 	ID(PCI_DEVICE_ID_INTEL_82915G_HB),
+	ID(PCI_DEVICE_ID_INTEL_82915GM_HB),
 	{ }
 };
 
diff -Nru a/drivers/char/agp/intel-mch-agp.c b/drivers/char/agp/intel-mch-agp.c
--- a/drivers/char/agp/intel-mch-agp.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/char/agp/intel-mch-agp.c	2005-03-01 23:38:52 -08:00
@@ -51,7 +51,7 @@
 	if (new == NULL)
 		return NULL;
 
-	new->memory[0] = agp_bridge->driver->mask_memory(virt_to_phys(addr), type);
+	new->memory[0] = virt_to_phys(addr);
 	new->page_count = 1;
 	new->num_scratch_pages = 1;
 	new->type = AGP_PHYS_MEMORY;
@@ -111,8 +111,7 @@
 			gtt_entries = MB(8) - KB(132);
 			break;
 		case I830_GMCH_GMS_LOCAL:
-			rdct = INREG8(intel_i830_private.registers,
-				      I830_RDRAM_CHANNEL_TYPE);
+			rdct = readb(intel_i830_private.registers+I830_RDRAM_CHANNEL_TYPE);
 			gtt_entries = (I830_RDRAM_ND(rdct) + 1) *
 					MB(ddt[I830_RDRAM_DDT(rdct)]);
 			local = 1;
@@ -174,10 +173,10 @@
 
 	intel_i830_private.registers = (volatile u8 __iomem*) ioremap(temp,128 * 4096);
 	if (!intel_i830_private.registers)
-		return (-ENOMEM);
+		return -ENOMEM;
 
-	temp = INREG32(intel_i830_private.registers,I810_PGETBL_CTL) & 0xfffff000;
-	global_cache_flush();
+	temp = readl(intel_i830_private.registers+I810_PGETBL_CTL) & 0xfffff000;
+	global_cache_flush();	/* FIXME: ?? */
 
 	/* we have to call this as early as possible after the MMIO base address is known */
 	intel_i830_init_gtt_entries();
@@ -186,7 +185,7 @@
 
 	agp_bridge->gatt_bus_addr = temp;
 
-	return(0);
+	return 0;
 }
 
 /* Return the gatt table to a sane state. Use the top of stolen
@@ -194,7 +193,7 @@
  */
 static int intel_i830_free_gatt_table(void)
 {
-	return(0);
+	return 0;
 }
 
 static int intel_i830_fetch_size(void)
@@ -209,7 +208,7 @@
 		/* 855GM/852GM/865G has 128MB aperture size */
 		agp_bridge->previous_size = agp_bridge->current_size = (void *) values;
 		agp_bridge->aperture_size_idx = 0;
-		return(values[0].size);
+		return values[0].size;
 	}
 
 	pci_read_config_word(agp_bridge->dev,I830_GMCH_CTRL,&gmch_ctrl);
@@ -217,14 +216,14 @@
 	if ((gmch_ctrl & I830_GMCH_MEM_MASK) == I830_GMCH_MEM_128M) {
 		agp_bridge->previous_size = agp_bridge->current_size = (void *) values;
 		agp_bridge->aperture_size_idx = 0;
-		return(values[0].size);
+		return values[0].size;
 	} else {
 		agp_bridge->previous_size = agp_bridge->current_size = (void *) values;
 		agp_bridge->aperture_size_idx = 1;
-		return(values[1].size);
+		return values[1].size;
 	}
 
-	return(0);
+	return 0;
 }
 
 static int intel_i830_configure(void)
@@ -243,14 +242,17 @@
 	gmch_ctrl |= I830_GMCH_ENABLED;
 	pci_write_config_word(agp_bridge->dev,I830_GMCH_CTRL,gmch_ctrl);
 
-	OUTREG32(intel_i830_private.registers,I810_PGETBL_CTL,agp_bridge->gatt_bus_addr | I810_PGETBL_ENABLED);
-	global_cache_flush();
-
-	if (agp_bridge->driver->needs_scratch_page)
-		for (i = intel_i830_private.gtt_entries; i < current_size->num_entries; i++)
-			OUTREG32(intel_i830_private.registers,I810_PTE_BASE + (i * 4),agp_bridge->scratch_page);
+	writel(agp_bridge->gatt_bus_addr|I810_PGETBL_ENABLED, intel_i830_private.registers+I810_PGETBL_CTL);
+	readl(intel_i830_private.registers+I810_PGETBL_CTL);	/* PCI Posting. */
 
-	return (0);
+	if (agp_bridge->driver->needs_scratch_page) {
+		for (i = intel_i830_private.gtt_entries; i < current_size->num_entries; i++) {
+			writel(agp_bridge->scratch_page, intel_i830_private.registers+I810_PTE_BASE+(i*4));
+			readl(intel_i830_private.registers+I810_PTE_BASE+(i*4));	/* PCI Posting. */
+		}
+	}
+	global_cache_flush();
+	return 0;
 }
 
 static void intel_i830_cleanup(void)
@@ -272,11 +274,11 @@
 				pg_start,intel_i830_private.gtt_entries);
 
 		printk (KERN_INFO PFX "Trying to insert into local/stolen memory\n");
-		return (-EINVAL);
+		return -EINVAL;
 	}
 
 	if ((pg_start + mem->page_count) > num_entries)
-		return (-EINVAL);
+		return -EINVAL;
 
 	/* The i830 can't check the GTT for entries since its read only,
 	 * depend on the caller to make the correct offset decisions.
@@ -284,19 +286,21 @@
 
 	if ((type != 0 && type != AGP_PHYS_MEMORY) ||
 		(mem->type != 0 && mem->type != AGP_PHYS_MEMORY))
-		return (-EINVAL);
+		return -EINVAL;
 
-	global_cache_flush();
+	global_cache_flush();	/* FIXME: ?? */
 
-	for (i = 0, j = pg_start; i < mem->page_count; i++, j++)
-		OUTREG32(intel_i830_private.registers,I810_PTE_BASE + (j * 4),
-			agp_bridge->driver->mask_memory(mem->memory[i], mem->type));
+	for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
+		writel(agp_bridge->driver->mask_memory(mem->memory[i], mem->type),
+				intel_i830_private.registers+I810_PTE_BASE+(j*4));
+		readl(intel_i830_private.registers+I810_PTE_BASE+(j*4));	/* PCI Posting. */
+	}
 
 	global_cache_flush();
 
 	agp_bridge->driver->tlb_flush(mem);
 
-	return(0);
+	return 0;
 }
 
 static int intel_i830_remove_entries(struct agp_memory *mem,off_t pg_start,
@@ -308,26 +312,26 @@
 
 	if (pg_start < intel_i830_private.gtt_entries) {
 		printk (KERN_INFO PFX "Trying to disable local/stolen memory\n");
-		return (-EINVAL);
+		return -EINVAL;
 	}
 
-	for (i = pg_start; i < (mem->page_count + pg_start); i++)
-		OUTREG32(intel_i830_private.registers,I810_PTE_BASE + (i * 4),agp_bridge->scratch_page);
+	for (i = pg_start; i < (mem->page_count + pg_start); i++) {
+		writel(agp_bridge->scratch_page, intel_i830_private.registers+I810_PTE_BASE+(i*4));
+		readl(intel_i830_private.registers+I810_PTE_BASE+(i*4));	/* PCI Posting. */
+	}
 
 	global_cache_flush();
-
 	agp_bridge->driver->tlb_flush(mem);
-
-	return (0);
+	return 0;
 }
 
 static struct agp_memory *intel_i830_alloc_by_type(size_t pg_count,int type)
 {
 	if (type == AGP_PHYS_MEMORY)
-		return(alloc_agpphysmem_i8xx(pg_count, type));
+		return alloc_agpphysmem_i8xx(pg_count, type);
 
 	/* always return NULL for other allocation types for now */
-	return(NULL);
+	return NULL;
 }
 
 static int intel_8xx_fetch_size(void)
@@ -470,9 +474,9 @@
 {
 	struct pci_dev *i830_dev;
 
-	i830_dev = pci_find_device(PCI_VENDOR_ID_INTEL, device, NULL);
+	i830_dev = pci_get_device(PCI_VENDOR_ID_INTEL, device, NULL);
 	if (i830_dev && PCI_FUNC(i830_dev->devfn) != 0) {
-		i830_dev = pci_find_device(PCI_VENDOR_ID_INTEL,
+		i830_dev = pci_get_device(PCI_VENDOR_ID_INTEL,
 				device, i830_dev);
 	}
 
@@ -536,7 +540,7 @@
 	if (!r->start && r->end) {
 		if(pci_assign_resource(pdev, 0)) {
 			printk(KERN_ERR PFX "could not assign resource 0\n");
-			return (-ENODEV);
+			return -ENODEV;
 		}
 	}
 
@@ -547,7 +551,7 @@
 	*/
 	if (pci_enable_device(pdev)) {
 		printk(KERN_ERR PFX "Unable to Enable PCI device\n");
-		return (-ENODEV);
+		return -ENODEV;
 	}
 
 	/* Fill in the mode register */
@@ -566,13 +570,15 @@
 	struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
 
 	agp_remove_bridge(bridge);
+	if (intel_i830_private.i830_dev)
+		pci_dev_put(intel_i830_private.i830_dev);
 	agp_put_bridge(bridge);
 }
 
 static int agp_intelmch_resume(struct pci_dev *pdev)
 {
 	struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
-	
+
 	pci_restore_state(pdev);
 
 	if (bridge->driver == &intel_845_driver)
diff -Nru a/drivers/char/agp/isoch.c b/drivers/char/agp/isoch.c
--- a/drivers/char/agp/isoch.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/char/agp/isoch.c	2005-03-01 23:39:16 -08:00
@@ -347,7 +347,7 @@
 	INIT_LIST_HEAD(head);
 
 	/* Find all AGP devices, and add them to dev_list. */
-	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
+	for_each_pci_dev(dev) {
 		mcapndx = pci_find_capability(dev, PCI_CAP_ID_AGP);
 		if (mcapndx == 0)
 			continue;
diff -Nru a/drivers/char/agp/nvidia-agp.c b/drivers/char/agp/nvidia-agp.c
--- a/drivers/char/agp/nvidia-agp.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/char/agp/nvidia-agp.c	2005-03-01 23:38:53 -08:00
@@ -214,9 +214,11 @@
 		global_cache_flush();
 		mem->is_flushed = TRUE;
 	}
-	for (i = 0, j = pg_start; i < mem->page_count; i++, j++)
+	for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
 		writel(agp_bridge->driver->mask_memory(mem->memory[i], mem->type),
 			agp_bridge->gatt_table+nvidia_private.pg_offset+j);
+		readl(agp_bridge->gatt_table+nvidia_private.pg_offset+j);	/* PCI Posting. */
+	}
 	agp_bridge->driver->tlb_flush(mem);
 	return 0;
 }
@@ -403,6 +405,8 @@
 
 static int __init agp_nvidia_init(void)
 {
+	if (agp_off)
+		return -EINVAL;
 	return pci_module_init(&agp_nvidia_pci_driver);
 }
 
diff -Nru a/drivers/char/agp/sis-agp.c b/drivers/char/agp/sis-agp.c
--- a/drivers/char/agp/sis-agp.c	2005-03-01 23:38:51 -08:00
+++ b/drivers/char/agp/sis-agp.c	2005-03-01 23:38:51 -08:00
@@ -340,6 +340,8 @@
 
 static int __init agp_sis_init(void)
 {
+	if (agp_off)
+		return -EINVAL;
 	return pci_module_init(&agp_sis_pci_driver);
 }
 
@@ -351,8 +353,8 @@
 module_init(agp_sis_init);
 module_exit(agp_sis_cleanup);
 
-MODULE_PARM(agp_sis_force_delay,"i");
+module_param(agp_sis_force_delay, bool, 0);
 MODULE_PARM_DESC(agp_sis_force_delay,"forces sis delay hack");
-MODULE_PARM(agp_sis_agp_spec,"i");
+module_param(agp_sis_agp_spec, int, 0);
 MODULE_PARM_DESC(agp_sis_agp_spec,"0=force sis init, 1=force generic agp3 init, default: autodetect");
 MODULE_LICENSE("GPL and additional rights");
diff -Nru a/drivers/char/agp/sworks-agp.c b/drivers/char/agp/sworks-agp.c
--- a/drivers/char/agp/sworks-agp.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/char/agp/sworks-agp.c	2005-03-01 23:39:18 -08:00
@@ -242,12 +242,12 @@
  */
 static void serverworks_tlbflush(struct agp_memory *temp)
 {
-	OUTREG8(serverworks_private.registers, SVWRKS_POSTFLUSH, 1);
-	while(INREG8(serverworks_private.registers, SVWRKS_POSTFLUSH) == 1)
+	writeb(1, serverworks_private.registers+SVWRKS_POSTFLUSH);
+	while (readb(serverworks_private.registers+SVWRKS_POSTFLUSH) == 1)
 		cpu_relax();
 
-	OUTREG32(serverworks_private.registers, SVWRKS_DIRFLUSH, 1);
-	while(INREG32(serverworks_private.registers, SVWRKS_DIRFLUSH) == 1)
+	writel(1, serverworks_private.registers+SVWRKS_DIRFLUSH);
+	while(readl(serverworks_private.registers+SVWRKS_DIRFLUSH) == 1)
 		cpu_relax();
 }
 
@@ -269,21 +269,21 @@
 		return -ENOMEM;
 	}
 
-	OUTREG8(serverworks_private.registers, SVWRKS_GART_CACHE, 0x0a);
+	writeb(0xA, serverworks_private.registers+SVWRKS_GART_CACHE);
+	readb(serverworks_private.registers+SVWRKS_GART_CACHE);	/* PCI Posting. */
 
-	OUTREG32(serverworks_private.registers, SVWRKS_GATTBASE, 
-		 agp_bridge->gatt_bus_addr);
+	writel(agp_bridge->gatt_bus_addr, serverworks_private.registers+SVWRKS_GATTBASE);
+	readl(serverworks_private.registers+SVWRKS_GATTBASE);	/* PCI Posting. */
 
-	cap_reg = INREG16(serverworks_private.registers, SVWRKS_COMMAND);
+	cap_reg = readw(serverworks_private.registers+SVWRKS_COMMAND);
 	cap_reg &= ~0x0007;
 	cap_reg |= 0x4;
-	OUTREG16(serverworks_private.registers, SVWRKS_COMMAND, cap_reg);
+	writew(cap_reg, serverworks_private.registers+SVWRKS_COMMAND);
+	readw(serverworks_private.registers+SVWRKS_COMMAND);
 
-	pci_read_config_byte(serverworks_private.svrwrks_dev,
-			     SVWRKS_AGP_ENABLE, &enable_reg);
+	pci_read_config_byte(serverworks_private.svrwrks_dev,SVWRKS_AGP_ENABLE, &enable_reg);
 	enable_reg |= 0x1; /* Agp Enable bit */
-	pci_write_config_byte(serverworks_private.svrwrks_dev,
-			      SVWRKS_AGP_ENABLE, enable_reg);
+	pci_write_config_byte(serverworks_private.svrwrks_dev,SVWRKS_AGP_ENABLE, enable_reg);
 	serverworks_tlbflush(NULL);
 
 	agp_bridge->capndx = pci_find_capability(serverworks_private.svrwrks_dev, PCI_CAP_ID_AGP);
@@ -539,6 +539,8 @@
 
 static int __init agp_serverworks_init(void)
 {
+	if (agp_off)
+		return -EINVAL;
 	return pci_module_init(&agp_serverworks_pci_driver);
 }
 
diff -Nru a/drivers/char/agp/uninorth-agp.c b/drivers/char/agp/uninorth-agp.c
--- a/drivers/char/agp/uninorth-agp.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/char/agp/uninorth-agp.c	2005-03-01 23:38:57 -08:00
@@ -373,6 +373,8 @@
 
 static int __init agp_uninorth_init(void)
 {
+	if (agp_off)
+		return -EINVAL;
 	return pci_module_init(&agp_uninorth_pci_driver);
 }
 
diff -Nru a/drivers/char/agp/via-agp.c b/drivers/char/agp/via-agp.c
--- a/drivers/char/agp/via-agp.c	2005-03-01 23:39:19 -08:00
+++ b/drivers/char/agp/via-agp.c	2005-03-01 23:39:19 -08:00
@@ -523,6 +523,8 @@
 
 static int __init agp_via_init(void)
 {
+	if (agp_off)
+		return -EINVAL;
 	return pci_module_init(&agp_via_pci_driver);
 }
 
diff -Nru a/drivers/char/applicom.c b/drivers/char/applicom.c
--- a/drivers/char/applicom.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/char/applicom.c	2005-03-01 23:39:16 -08:00
@@ -1,6 +1,6 @@
 /* Derived from Applicom driver ac.c for SCO Unix                            */
 /* Ported by David Woodhouse, Axiom (Cambridge) Ltd.                         */
-/* dwmw2@redhat.com  30/8/98                                                 */
+/* dwmw2@infradead.org 30/8/98                                               */
 /* $Id: ac.c,v 1.30 2000/03/22 16:03:57 dwmw2 Exp $			     */
 /* This module is for Linux 2.1 and 2.2 series kernels.                      */
 /*****************************************************************************/
@@ -79,10 +79,6 @@
 MODULE_AUTHOR("David Woodhouse & Applicom International");
 MODULE_DESCRIPTION("Driver for Applicom Profibus card");
 MODULE_LICENSE("GPL");
-MODULE_PARM(irq, "i");
-MODULE_PARM_DESC(irq, "IRQ of the Applicom board");
-MODULE_PARM(mem, "i");
-MODULE_PARM_DESC(mem, "Shared Memory Address of Applicom board");
 
 MODULE_SUPPORTED_DEVICE("ac");
 
@@ -97,6 +93,11 @@
 
 static unsigned int irq = 0;	/* interrupt number IRQ       */
 static unsigned long mem = 0;	/* physical segment of board  */
+
+module_param(irq, uint, 0);
+MODULE_PARM_DESC(irq, "IRQ of the Applicom board");
+module_param(mem, ulong, 0);
+MODULE_PARM_DESC(mem, "Shared Memory Address of Applicom board");
 
 static unsigned int numboards;	/* number of installed boards */
 static volatile unsigned char Dummy;
diff -Nru a/drivers/char/consolemap.c b/drivers/char/consolemap.c
--- a/drivers/char/consolemap.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/char/consolemap.c	2005-03-01 23:39:08 -08:00
@@ -74,8 +74,8 @@
     0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
     0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x00a0,
     0x25c6, 0x2592, 0x2409, 0x240c, 0x240d, 0x240a, 0x00b0, 0x00b1,
-    0x2591, 0x240b, 0x2518, 0x2510, 0x250c, 0x2514, 0x253c, 0xf800,
-    0xf801, 0x2500, 0xf803, 0xf804, 0x251c, 0x2524, 0x2534, 0x252c,
+    0x2591, 0x240b, 0x2518, 0x2510, 0x250c, 0x2514, 0x253c, 0x23ba,
+    0x23bb, 0x2500, 0x23bc, 0x23bd, 0x251c, 0x2524, 0x2534, 0x252c,
     0x2502, 0x2264, 0x2265, 0x03c0, 0x2260, 0x00a3, 0x00b7, 0x007f,
     0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
     0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
diff -Nru a/drivers/char/cp437.uni b/drivers/char/cp437.uni
--- a/drivers/char/cp437.uni	2005-03-01 23:39:09 -08:00
+++ b/drivers/char/cp437.uni	2005-03-01 23:39:09 -08:00
@@ -111,7 +111,7 @@
 0x5c	U+005c
 0x5d	U+005d
 0x5e	U+005e
-0x5f	U+005f U+f804
+0x5f	U+005f U+23bd U+f804
 0x60	U+0060
 0x61	U+0061 U+00e3
 0x62	U+0062
diff -Nru a/drivers/char/cyclades.c b/drivers/char/cyclades.c
--- a/drivers/char/cyclades.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/char/cyclades.c	2005-03-01 23:38:53 -08:00
@@ -758,7 +758,6 @@
  * allocated when the first cy_open occurs.
  */
 static unsigned char *tmp_buf;
-DECLARE_MUTEX(tmp_buf_sem);
 
 /*
  * This is used to look up the divisor speeds and the timeouts
@@ -5537,25 +5536,5 @@
 
 module_init(cy_init);
 module_exit(cy_cleanup_module);
-
-#ifndef MODULE
-/* called by linux/init/main.c to parse command line options */
-void
-cy_setup(char *str, int *ints)
-{
-#ifdef CONFIG_ISA
-  int i, j;
-
-    for (i = 0 ; i < NR_ISA_ADDRS ; i++) {
-        if (cy_isa_addresses[i] == 0) break;
-    }
-    for (j = 1; j <= ints[0]; j++){
-        if ( i < NR_ISA_ADDRS ){
-            cy_isa_addresses[i++] = ints[j];
-        }
-    }
-#endif /* CONFIG_ISA */
-} /* cy_setup */
-#endif /* MODULE */
 
 MODULE_LICENSE("GPL");
diff -Nru a/drivers/char/drm/Kconfig b/drivers/char/drm/Kconfig
--- a/drivers/char/drm/Kconfig	2005-03-01 23:39:09 -08:00
+++ b/drivers/char/drm/Kconfig	2005-03-01 23:39:09 -08:00
@@ -5,7 +5,8 @@
 # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
 #
 config DRM
-	bool "Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)"
+	tristate "Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)"
+	depends on AGP || AGP=n
 	help
 	  Kernel-level support for the Direct Rendering Infrastructure (DRI)
 	  introduced in XFree86 4.0. If you say Y here, you need to select
@@ -81,7 +82,7 @@
 
 config DRM_MGA
 	tristate "Matrox g200/g400"
-	depends on DRM && AGP && (!X86_64 || BROKEN) 
+	depends on DRM && AGP
 	help
 	  Choose this option if you have a Matrox G200, G400 or G450 graphics
 	  card.  If M is selected, the module will be called mga.  AGP
diff -Nru a/drivers/char/drm/Makefile b/drivers/char/drm/Makefile
--- a/drivers/char/drm/Makefile	2005-03-01 23:39:16 -08:00
+++ b/drivers/char/drm/Makefile	2005-03-01 23:39:16 -08:00
@@ -2,6 +2,12 @@
 # Makefile for the drm device driver.  This driver provides support for the
 # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
 
+drm-objs    :=	drm_auth.o drm_bufs.o drm_context.o drm_dma.o drm_drawable.o \
+		drm_drv.o drm_fops.o drm_init.o drm_ioctl.o drm_irq.o \
+		drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \
+		drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \
+		drm_sysfs.o
+
 gamma-objs  := gamma_drv.o gamma_dma.o
 tdfx-objs   := tdfx_drv.o
 r128-objs   := r128_drv.o r128_cce.o r128_state.o r128_irq.o
@@ -13,6 +19,7 @@
 ffb-objs    := ffb_drv.o ffb_context.o
 sis-objs    := sis_drv.o sis_ds.o sis_mm.o
 
+obj-$(CONFIG_DRM)	+= drm.o
 obj-$(CONFIG_DRM_GAMMA) += gamma.o
 obj-$(CONFIG_DRM_TDFX)	+= tdfx.o
 obj-$(CONFIG_DRM_R128)	+= r128.o
diff -Nru a/drivers/char/drm/ati_pcigart.c b/drivers/char/drm/ati_pcigart.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/char/drm/ati_pcigart.c	2005-03-01 23:39:10 -08:00
@@ -0,0 +1,208 @@
+/**
+ * \file ati_pcigart.h 
+ * ATI PCI GART support
+ *
+ * \author Gareth Hughes <gareth@valinux.com>
+ */
+
+/*
+ * Created: Wed Dec 13 21:52:19 2000 by gareth@valinux.com
+ *
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include "drmP.h"
+
+#if PAGE_SIZE == 65536
+# define ATI_PCIGART_TABLE_ORDER	0
+# define ATI_PCIGART_TABLE_PAGES	(1 << 0)
+#elif PAGE_SIZE == 16384
+# define ATI_PCIGART_TABLE_ORDER	1
+# define ATI_PCIGART_TABLE_PAGES	(1 << 1)
+#elif PAGE_SIZE == 8192
+# define ATI_PCIGART_TABLE_ORDER 	2
+# define ATI_PCIGART_TABLE_PAGES 	(1 << 2)
+#elif PAGE_SIZE == 4096
+# define ATI_PCIGART_TABLE_ORDER 	3
+# define ATI_PCIGART_TABLE_PAGES 	(1 << 3)
+#else
+# error - PAGE_SIZE not 64K, 16K, 8K or 4K
+#endif
+
+# 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 )
+{
+	unsigned long address;
+	struct page *page;
+	int i;
+	DRM_DEBUG( "%s\n", __FUNCTION__ );
+
+	address = __get_free_pages( GFP_KERNEL, ATI_PCIGART_TABLE_ORDER );
+	if ( address == 0UL ) {
+		return 0;
+	}
+
+	page = virt_to_page( address );
+
+	for ( i = 0 ; i < ATI_PCIGART_TABLE_PAGES ; i++, page++ ) {
+		get_page(page);
+		SetPageReserved( page );
+	}
+
+	DRM_DEBUG( "%s: returning 0x%08lx\n", __FUNCTION__, address );
+	return address;
+}
+
+static void drm_ati_free_pcigart_table( unsigned long address )
+{
+	struct page *page;
+	int i;
+	DRM_DEBUG( "%s\n", __FUNCTION__ );
+
+	page = virt_to_page( address );
+
+	for ( i = 0 ; i < ATI_PCIGART_TABLE_PAGES ; i++, page++ ) {
+		__put_page(page);
+		ClearPageReserved( page );
+	}
+
+	free_pages( address, ATI_PCIGART_TABLE_ORDER );
+}
+
+int drm_ati_pcigart_cleanup( drm_device_t *dev,
+			      unsigned long addr,
+			      dma_addr_t bus_addr)
+{
+	drm_sg_mem_t *entry = dev->sg;
+	unsigned long pages;
+	int i;
+
+	/* we need to support large memory configurations */
+	if ( !entry ) {
+		DRM_ERROR( "no scatter/gather memory!\n" );
+		return 0;
+	}
+
+	if ( bus_addr ) {
+		pci_unmap_single(dev->pdev, bus_addr,
+				 ATI_PCIGART_TABLE_PAGES * PAGE_SIZE,
+				 PCI_DMA_TODEVICE);
+
+		pages = ( entry->pages <= ATI_MAX_PCIGART_PAGES )
+		        ? entry->pages : ATI_MAX_PCIGART_PAGES;
+
+		for ( i = 0 ; i < pages ; i++ ) {
+			if ( !entry->busaddr[i] ) break;
+			pci_unmap_single(dev->pdev, entry->busaddr[i],
+					 PAGE_SIZE, PCI_DMA_TODEVICE);
+		}
+	}
+
+	if ( addr ) {
+		drm_ati_free_pcigart_table( addr );
+	}
+
+	return 1;
+}
+EXPORT_SYMBOL(drm_ati_pcigart_cleanup);
+
+int drm_ati_pcigart_init( drm_device_t *dev,
+			   unsigned long *addr,
+			   dma_addr_t *bus_addr)
+{
+	drm_sg_mem_t *entry = dev->sg;
+	unsigned long address = 0;
+	unsigned long pages;
+	u32 *pci_gart, page_base, bus_address = 0;
+	int i, j, ret = 0;
+
+	if ( !entry ) {
+		DRM_ERROR( "no scatter/gather memory!\n" );
+		goto done;
+	}
+
+	address = drm_ati_alloc_pcigart_table();
+	if ( !address ) {
+		DRM_ERROR( "cannot allocate PCI GART page!\n" );
+		goto done;
+	}
+
+	if ( !dev->pdev ) {
+		DRM_ERROR( "PCI device unknown!\n" );
+		goto done;
+	}
+
+	bus_address = pci_map_single(dev->pdev, (void *)address,
+				  ATI_PCIGART_TABLE_PAGES * PAGE_SIZE,
+				  PCI_DMA_TODEVICE);
+	if (bus_address == 0) {
+		DRM_ERROR( "unable to map PCIGART pages!\n" );
+		drm_ati_free_pcigart_table( address );
+		address = 0;
+		goto done;
+	}
+
+	pci_gart = (u32 *)address;
+
+	pages = ( entry->pages <= ATI_MAX_PCIGART_PAGES )
+		? entry->pages : ATI_MAX_PCIGART_PAGES;
+
+	memset( pci_gart, 0, ATI_MAX_PCIGART_PAGES * sizeof(u32) );
+
+	for ( i = 0 ; i < pages ; i++ ) {
+		/* we need to support large memory configurations */
+		entry->busaddr[i] = pci_map_single(dev->pdev,
+					   page_address( entry->pagelist[i] ),
+					   PAGE_SIZE,
+					   PCI_DMA_TODEVICE);
+		if (entry->busaddr[i] == 0) {
+			DRM_ERROR( "unable to map PCIGART pages!\n" );
+			drm_ati_pcigart_cleanup( dev, address, bus_address );
+			address = 0;
+			bus_address = 0;
+			goto done;
+		}
+		page_base = (u32) entry->busaddr[i];
+
+		for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) {
+			*pci_gart++ = cpu_to_le32( page_base );
+			page_base += ATI_PCIGART_PAGE_SIZE;
+		}
+	}
+
+	ret = 1;
+
+#if defined(__i386__) || defined(__x86_64__)
+	wbinvd();
+#else
+	mb();
+#endif
+
+done:
+	*addr = address;
+	*bus_addr = bus_address;
+	return ret;
+}
+EXPORT_SYMBOL(drm_ati_pcigart_init);
diff -Nru a/drivers/char/drm/ati_pcigart.h b/drivers/char/drm/ati_pcigart.h
--- a/drivers/char/drm/ati_pcigart.h	2005-03-01 23:39:10 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,206 +0,0 @@
-/**
- * \file ati_pcigart.h 
- * ATI PCI GART support
- *
- * \author Gareth Hughes <gareth@valinux.com>
- */
-
-/*
- * Created: Wed Dec 13 21:52:19 2000 by gareth@valinux.com
- *
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#include "drmP.h"
-
-#if PAGE_SIZE == 65536
-# define ATI_PCIGART_TABLE_ORDER	0
-# define ATI_PCIGART_TABLE_PAGES	(1 << 0)
-#elif PAGE_SIZE == 16384
-# define ATI_PCIGART_TABLE_ORDER	1
-# define ATI_PCIGART_TABLE_PAGES	(1 << 1)
-#elif PAGE_SIZE == 8192
-# define ATI_PCIGART_TABLE_ORDER 	2
-# define ATI_PCIGART_TABLE_PAGES 	(1 << 2)
-#elif PAGE_SIZE == 4096
-# define ATI_PCIGART_TABLE_ORDER 	3
-# define ATI_PCIGART_TABLE_PAGES 	(1 << 3)
-#else
-# error - PAGE_SIZE not 64K, 16K, 8K or 4K
-#endif
-
-# define ATI_MAX_PCIGART_PAGES		8192	/**< 32 MB aperture, 4K pages */
-# define ATI_PCIGART_PAGE_SIZE		4096	/**< PCI GART page size */
-
-static unsigned long DRM(ati_alloc_pcigart_table)( void )
-{
-	unsigned long address;
-	struct page *page;
-	int i;
-	DRM_DEBUG( "%s\n", __FUNCTION__ );
-
-	address = __get_free_pages( GFP_KERNEL, ATI_PCIGART_TABLE_ORDER );
-	if ( address == 0UL ) {
-		return 0;
-	}
-
-	page = virt_to_page( address );
-
-	for ( i = 0 ; i < ATI_PCIGART_TABLE_PAGES ; i++, page++ ) {
-		get_page(page);
-		SetPageReserved( page );
-	}
-
-	DRM_DEBUG( "%s: returning 0x%08lx\n", __FUNCTION__, address );
-	return address;
-}
-
-static void DRM(ati_free_pcigart_table)( unsigned long address )
-{
-	struct page *page;
-	int i;
-	DRM_DEBUG( "%s\n", __FUNCTION__ );
-
-	page = virt_to_page( address );
-
-	for ( i = 0 ; i < ATI_PCIGART_TABLE_PAGES ; i++, page++ ) {
-		__put_page(page);
-		ClearPageReserved( page );
-	}
-
-	free_pages( address, ATI_PCIGART_TABLE_ORDER );
-}
-
-int DRM(ati_pcigart_init)( drm_device_t *dev,
-			   unsigned long *addr,
-			   dma_addr_t *bus_addr)
-{
-	drm_sg_mem_t *entry = dev->sg;
-	unsigned long address = 0;
-	unsigned long pages;
-	u32 *pci_gart, page_base, bus_address = 0;
-	int i, j, ret = 0;
-
-	if ( !entry ) {
-		DRM_ERROR( "no scatter/gather memory!\n" );
-		goto done;
-	}
-
-	address = DRM(ati_alloc_pcigart_table)();
-	if ( !address ) {
-		DRM_ERROR( "cannot allocate PCI GART page!\n" );
-		goto done;
-	}
-
-	if ( !dev->pdev ) {
-		DRM_ERROR( "PCI device unknown!\n" );
-		goto done;
-	}
-
-	bus_address = pci_map_single(dev->pdev, (void *)address,
-				  ATI_PCIGART_TABLE_PAGES * PAGE_SIZE,
-				  PCI_DMA_TODEVICE);
-	if (bus_address == 0) {
-		DRM_ERROR( "unable to map PCIGART pages!\n" );
-		DRM(ati_free_pcigart_table)( address );
-		address = 0;
-		goto done;
-	}
-
-	pci_gart = (u32 *)address;
-
-	pages = ( entry->pages <= ATI_MAX_PCIGART_PAGES )
-		? entry->pages : ATI_MAX_PCIGART_PAGES;
-
-	memset( pci_gart, 0, ATI_MAX_PCIGART_PAGES * sizeof(u32) );
-
-	for ( i = 0 ; i < pages ; i++ ) {
-		/* we need to support large memory configurations */
-		entry->busaddr[i] = pci_map_single(dev->pdev,
-					   page_address( entry->pagelist[i] ),
-					   PAGE_SIZE,
-					   PCI_DMA_TODEVICE);
-		if (entry->busaddr[i] == 0) {
-			DRM_ERROR( "unable to map PCIGART pages!\n" );
-			DRM(ati_pcigart_cleanup)( dev, address, bus_address );
-			address = 0;
-			bus_address = 0;
-			goto done;
-		}
-		page_base = (u32) entry->busaddr[i];
-
-		for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) {
-			*pci_gart++ = cpu_to_le32( page_base );
-			page_base += ATI_PCIGART_PAGE_SIZE;
-		}
-	}
-
-	ret = 1;
-
-#if defined(__i386__) || defined(__x86_64__)
-	asm volatile ( "wbinvd" ::: "memory" );
-#else
-	mb();
-#endif
-
-done:
-	*addr = address;
-	*bus_addr = bus_address;
-	return ret;
-}
-
-int DRM(ati_pcigart_cleanup)( drm_device_t *dev,
-			      unsigned long addr,
-			      dma_addr_t bus_addr)
-{
-	drm_sg_mem_t *entry = dev->sg;
-	unsigned long pages;
-	int i;
-
-	/* we need to support large memory configurations */
-	if ( !entry ) {
-		DRM_ERROR( "no scatter/gather memory!\n" );
-		return 0;
-	}
-
-	if ( bus_addr ) {
-		pci_unmap_single(dev->pdev, bus_addr,
-				 ATI_PCIGART_TABLE_PAGES * PAGE_SIZE,
-				 PCI_DMA_TODEVICE);
-
-		pages = ( entry->pages <= ATI_MAX_PCIGART_PAGES )
-		        ? entry->pages : ATI_MAX_PCIGART_PAGES;
-
-		for ( i = 0 ; i < pages ; i++ ) {
-			if ( !entry->busaddr[i] ) break;
-			pci_unmap_single(dev->pdev, entry->busaddr[i],
-					 PAGE_SIZE, PCI_DMA_TODEVICE);
-		}
-	}
-
-	if ( addr ) {
-		DRM(ati_free_pcigart_table)( addr );
-	}
-
-	return 1;
-}
diff -Nru a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h
--- a/drivers/char/drm/drmP.h	2005-03-01 23:39:08 -08:00
+++ b/drivers/char/drm/drmP.h	2005-03-01 23:39:08 -08:00
@@ -34,6 +34,8 @@
 #ifndef _DRM_P_H_
 #define _DRM_P_H_
 
+/* If you want the memory alloc debug functionality, change define below */
+/* #define DEBUG_MEMORY */
 
 #ifdef __KERNEL__
 #ifdef __alpha__
@@ -55,6 +57,7 @@
 #include <linux/jiffies.h>
 #include <linux/smp_lock.h>	/* For (un)lock_kernel */
 #include <linux/mm.h>
+#include <linux/cdev.h>
 #if defined(__alpha__) || defined(__powerpc__)
 #include <asm/pgtable.h> /* For pte_wrprotect */
 #endif
@@ -215,7 +218,8 @@
  */
 #define DRM_MEM_ERROR(area, fmt, arg...) \
 	printk(KERN_ERR "[" DRM_NAME ":%s:%s] *ERROR* " fmt , __FUNCTION__, \
-	       DRM(mem_stats)[area].name , ##arg)
+	       drm_mem_stats[area].name , ##arg)
+
 #define DRM_INFO(fmt, arg...)  printk(KERN_INFO "[" DRM_NAME "] " fmt , ##arg)
 
 /**
@@ -227,7 +231,7 @@
 #if DRM_DEBUG_CODE
 #define DRM_DEBUG(fmt, arg...)						\
 	do {								\
-		if ( DRM(flags) & DRM_FLAG_DEBUG )			\
+		if ( drm_debug )			\
 			printk(KERN_DEBUG				\
 			       "[" DRM_NAME ":%s] " fmt ,	\
 			       __FUNCTION__ , ##arg);			\
@@ -290,6 +294,18 @@
 } while (0)
 
 /**
+ * Copy and IOCTL return string to user space
+ */
+#define DRM_COPY( name, value )						\
+	len = strlen( value );						\
+	if ( len > name##_len ) len = name##_len;			\
+	name##_len = strlen( value );					\
+	if ( len && name ) {						\
+		if ( copy_to_user( name, value, len ) )			\
+			return -EFAULT;					\
+	}
+	
+/**
  * Ioctl function type.
  *
  * \param inode device inode.
@@ -475,7 +491,7 @@
 /**
  * AGP data.
  *
- * \sa DRM(agp_init)() and drm_device::agp.
+ * \sa drm_agp_init() and drm_device::agp.
  */
 typedef struct drm_agp_head {
 	DRM_AGP_KERN       agp_info;	/**< AGP device information */
@@ -533,19 +549,21 @@
 } drm_vbl_sig_t;
 
 
-/** 
- * DRM device functions structure
+/**
+ * DRM driver structure. This structure represent the common code for
+ * a family of cards. There will one drm_device for each card present
+ * in this family
  */
 struct drm_device;
 
-struct drm_driver_fn {
-	int (*preinit)(struct drm_device *);
-	int (*postinit)(struct drm_device *);
+struct drm_driver {
+	int (*preinit)(struct drm_device *, unsigned long flags);
 	void (*prerelease)(struct drm_device *, struct file *filp);
 	void (*pretakedown)(struct drm_device *);
 	int (*postcleanup)(struct drm_device *);
 	int (*presetup)(struct drm_device *);
 	int (*postsetup)(struct drm_device *);
+ 	int (*dma_ioctl)( DRM_IOCTL_ARGS );
 	int (*open_helper)(struct drm_device *, drm_file_t *);
 	void (*free_filp_priv)(struct drm_device *, drm_file_t *);
 	void (*release)(struct drm_device *, struct file *filp);
@@ -557,20 +575,27 @@
 	void (*kernel_context_switch_unlock)(struct drm_device *dev, drm_lock_t *lock);
 	int (*vblank_wait)(struct drm_device *dev, unsigned int *sequence);
 	/* these have to be filled in */
+ 	int (*postinit)(struct drm_device *, unsigned long flags);
 	irqreturn_t (*irq_handler)( DRM_IRQ_ARGS );
  	void (*irq_preinstall)(struct drm_device *dev);
  	void (*irq_postinstall)(struct drm_device *dev);
  	void (*irq_uninstall)(struct drm_device *dev);
-	void (*reclaim_buffers)(struct file *filp);
+	void (*reclaim_buffers)(struct drm_device *dev, struct file *filp);
 	unsigned long (*get_map_ofs)(drm_map_t *map);
 	unsigned long (*get_reg_ofs)(struct drm_device *dev);
 	void (*set_version)(struct drm_device *dev, drm_set_version_t *sv);
+ 	int (*version)(drm_version_t *version);
+	u32 driver_features;
+	int dev_priv_size;
+	drm_ioctl_desc_t *ioctls;
+	int num_ioctls;
+	struct file_operations fops;
+	struct pci_driver pci_driver;
 };
 /**
  * DRM device structure.
  */
 typedef struct drm_device {
-	const char	  *name;	/**< Simple driver name */
 	char		  *unique;	/**< Unique identifier: e.g., busid */
 	int		  unique_len;	/**< Length of unique field */
 	dev_t		  device;	/**< Device number for mknod */
@@ -693,15 +718,22 @@
 	drm_sigdata_t     sigdata; /**< For block_all_signals */
 	sigset_t          sigmask;
 
-	struct            drm_driver_fn fn_tbl;
+	struct            drm_driver *driver;
 	drm_local_map_t   *agp_buffer_map;
-	int               dev_priv_size;
-	u32               driver_features;
 } drm_device_t;
 
+typedef struct drm_minor {
+	enum {
+		DRM_MINOR_FREE = 0,
+		DRM_MINOR_PRIMARY,
+	} type;
+	drm_device_t *dev;
+	struct proc_dir_entry  *dev_root; /**< proc directory entry */
+} drm_minor_t;
+
 static __inline__ int drm_core_check_feature(struct drm_device *dev, int feature)
 {
-	return ((dev->driver_features & feature) ? 1 : 0);
+	return ((dev->driver->driver_features & feature) ? 1 : 0);
 }
 
 #if __OS_HAS_AGP
@@ -722,250 +754,273 @@
 #define drm_core_has_MTRR(dev) (0)
 #endif
 
-extern void DRM(driver_register_fns)(struct drm_device *dev);
-
 /******************************************************************/
 /** \name Internal function definitions */
 /*@{*/
 
 				/* Misc. support (drm_init.h) */
-extern int	     DRM(flags);
-extern void	     DRM(parse_options)( char *s );
-extern int           DRM(cpu_valid)( void );
+extern int	     drm_flags;
+extern void	     drm_parse_options( char *s );
+extern int           drm_cpu_valid( void );
 
 				/* Driver support (drm_drv.h) */
-extern int           DRM(version)(struct inode *inode, struct file *filp,
+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(open)(struct inode *inode, struct file *filp);
-extern int           DRM(release)(struct inode *inode, struct file *filp);
-extern int           DRM(ioctl)(struct inode *inode, struct file *filp,
+extern int           drm_ioctl(struct inode *inode, struct file *filp,
 				unsigned int cmd, unsigned long arg);
-extern int           DRM(lock)(struct inode *inode, struct file *filp,
-			       unsigned int cmd, unsigned long arg);
-extern int           DRM(unlock)(struct inode *inode, 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_helper)(struct inode *inode, struct file *filp,
+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_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,
+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);
+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) */
-extern void	     DRM(mem_init)(void);
-extern int	     DRM(mem_info)(char *buf, char **start, off_t offset,
+#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(alloc)(size_t size, int area);
-extern void	     *DRM(calloc)(size_t nmemb, size_t size, int area);
-extern void	     *DRM(realloc)(void *oldpt, size_t oldsize, size_t size,
+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 void	     DRM(free)(void *pt, size_t size, int area);
-extern unsigned long DRM(alloc_pages)(int order, int area);
-extern void	     DRM(free_pages)(unsigned long address, int order,
+extern unsigned long drm_alloc_pages(int order, int area);
+extern void	     drm_free_pages(unsigned long address, int order,
 				     int area);
-extern void	     *DRM(ioremap)(unsigned long offset, unsigned long size, drm_device_t *dev);
-extern void	     *DRM(ioremap_nocache)(unsigned long offset, unsigned long size,
+extern void	     *drm_ioremap(unsigned long offset, unsigned long size, drm_device_t *dev);
+extern void	     *drm_ioremap_nocache(unsigned long offset, unsigned long size,
 					   drm_device_t *dev);
-extern void	     DRM(ioremapfree)(void *pt, unsigned long size, drm_device_t *dev);
+extern void	     drm_ioremapfree(void *pt, unsigned long size, drm_device_t *dev);
 
-extern DRM_AGP_MEM   *DRM(alloc_agp)(int pages, u32 type);
-extern int           DRM(free_agp)(DRM_AGP_MEM *handle, int pages);
-extern int           DRM(bind_agp)(DRM_AGP_MEM *handle, unsigned int start);
-extern int           DRM(unbind_agp)(DRM_AGP_MEM *handle);
+extern DRM_AGP_MEM   *drm_alloc_agp(int pages, u32 type);
+extern int           drm_free_agp(DRM_AGP_MEM *handle, int pages);
+extern int           drm_bind_agp(DRM_AGP_MEM *handle, unsigned int start);
+extern int           drm_unbind_agp(DRM_AGP_MEM *handle);
 
 				/* Misc. IOCTL support (drm_ioctl.h) */
-extern int	     DRM(irq_by_busid)(struct inode *inode, struct file *filp,
+extern int	     drm_irq_by_busid(struct inode *inode, struct file *filp,
 				       unsigned int cmd, unsigned long arg);
-extern int	     DRM(getunique)(struct inode *inode, struct file *filp,
+extern int	     drm_getunique(struct inode *inode, struct file *filp,
 				    unsigned int cmd, unsigned long arg);
-extern int	     DRM(setunique)(struct inode *inode, struct file *filp,
+extern int	     drm_setunique(struct inode *inode, struct file *filp,
 				    unsigned int cmd, unsigned long arg);
-extern int	     DRM(getmap)(struct inode *inode, struct file *filp,
+extern int	     drm_getmap(struct inode *inode, struct file *filp,
 				 unsigned int cmd, unsigned long arg);
-extern int	     DRM(getclient)(struct inode *inode, struct file *filp,
+extern int	     drm_getclient(struct inode *inode, struct file *filp,
 				    unsigned int cmd, unsigned long arg);
-extern int	     DRM(getstats)(struct inode *inode, struct file *filp,
+extern int	     drm_getstats(struct inode *inode, struct file *filp,
 				   unsigned int cmd, unsigned long arg);
-extern int	     DRM(setversion)(struct inode *inode, struct file *filp,
+extern int	     drm_setversion(struct inode *inode, struct file *filp,
 				     unsigned int cmd, unsigned long arg);
 
 				/* Context IOCTL support (drm_context.h) */
-extern int	     DRM(resctx)( struct inode *inode, struct file *filp,
+extern int	     drm_resctx( struct inode *inode, struct file *filp,
 				  unsigned int cmd, unsigned long arg );
-extern int	     DRM(addctx)( struct inode *inode, struct file *filp,
+extern int	     drm_addctx( struct inode *inode, struct file *filp,
 				  unsigned int cmd, unsigned long arg );
-extern int	     DRM(modctx)( struct inode *inode, struct file *filp,
+extern int	     drm_modctx( struct inode *inode, struct file *filp,
 				  unsigned int cmd, unsigned long arg );
-extern int	     DRM(getctx)( struct inode *inode, struct file *filp,
+extern int	     drm_getctx( struct inode *inode, struct file *filp,
 				  unsigned int cmd, unsigned long arg );
-extern int	     DRM(switchctx)( struct inode *inode, struct file *filp,
+extern int	     drm_switchctx( struct inode *inode, struct file *filp,
 				     unsigned int cmd, unsigned long arg );
-extern int	     DRM(newctx)( struct inode *inode, struct file *filp,
+extern int	     drm_newctx( struct inode *inode, struct file *filp,
 				  unsigned int cmd, unsigned long arg );
-extern int	     DRM(rmctx)( struct inode *inode, struct file *filp,
+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_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 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 );
 
-extern int	     DRM(setsareactx)( struct inode *inode, struct file *filp,
+extern int	     drm_setsareactx( struct inode *inode, struct file *filp,
 				       unsigned int cmd, unsigned long arg );
-extern int	     DRM(getsareactx)( struct inode *inode, struct file *filp,
+extern int	     drm_getsareactx( struct inode *inode, struct file *filp,
 				       unsigned int cmd, unsigned long arg );
 
 				/* Drawable IOCTL support (drm_drawable.h) */
-extern int	     DRM(adddraw)(struct inode *inode, struct file *filp,
+extern int	     drm_adddraw(struct inode *inode, struct file *filp,
 				  unsigned int cmd, unsigned long arg);
-extern int	     DRM(rmdraw)(struct inode *inode, struct file *filp,
+extern int	     drm_rmdraw(struct inode *inode, struct file *filp,
 				 unsigned int cmd, unsigned long arg);
 
 
 				/* Authentication IOCTL support (drm_auth.h) */
-extern int	     DRM(add_magic)(drm_device_t *dev, drm_file_t *priv,
+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,
+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,
+extern int	     drm_authmagic(struct inode *inode, struct file *filp,
 				    unsigned int cmd, unsigned long arg);
 
                                 /* Placeholder for ioctls past */
-extern int	     DRM(noop)(struct inode *inode, struct file *filp,
+extern int	     drm_noop(struct inode *inode, struct file *filp,
 				  unsigned int cmd, unsigned long arg);
 
 				/* Locking IOCTL support (drm_lock.h) */
-extern int	     DRM(lock_take)(__volatile__ unsigned int *lock,
+extern int           drm_lock(struct inode *inode, struct file *filp,
+			       unsigned int cmd, unsigned long arg);
+extern int           drm_unlock(struct inode *inode, struct file *filp,
+				 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,
+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,
+extern int	     drm_lock_free(drm_device_t *dev,
 				    __volatile__ unsigned int *lock,
 				    unsigned int context);
-extern int           DRM(notifier)(void *priv);
+extern int           drm_notifier(void *priv);
 
 				/* Buffer management support (drm_bufs.h) */
-extern int	     DRM(order)( unsigned long size );
-extern int	     DRM(addmap)( struct inode *inode, struct file *filp,
+extern int	     drm_order( unsigned long size );
+extern int	     drm_addmap( struct inode *inode, struct file *filp,
 				  unsigned int cmd, unsigned long arg );
-extern int	     DRM(rmmap)( struct inode *inode, struct file *filp,
+extern int	     drm_rmmap( struct inode *inode, struct file *filp,
 				 unsigned int cmd, unsigned long arg );
-extern int	     DRM(addbufs)( struct inode *inode, struct file *filp,
+extern int	     drm_addbufs( struct inode *inode, struct file *filp,
 				   unsigned int cmd, unsigned long arg );
-extern int	     DRM(infobufs)( struct inode *inode, struct file *filp,
+extern int	     drm_infobufs( struct inode *inode, struct file *filp,
 				    unsigned int cmd, unsigned long arg );
-extern int	     DRM(markbufs)( struct inode *inode, struct file *filp,
+extern int	     drm_markbufs( struct inode *inode, struct file *filp,
 				    unsigned int cmd, unsigned long arg );
-extern int	     DRM(freebufs)( struct inode *inode, struct file *filp,
+extern int	     drm_freebufs( struct inode *inode, struct file *filp,
 				    unsigned int cmd, unsigned long arg );
-extern int	     DRM(mapbufs)( struct inode *inode, struct file *filp,
+extern int	     drm_mapbufs( struct inode *inode, struct file *filp,
 				   unsigned int cmd, unsigned long arg );
 
 				/* DMA support (drm_dma.h) */
-extern int	     DRM(dma_setup)(drm_device_t *dev);
-extern void	     DRM(dma_takedown)(drm_device_t *dev);
-extern void	     DRM(free_buffer)(drm_device_t *dev, drm_buf_t *buf);
-extern void	     DRM(reclaim_buffers)( struct file *filp );
+extern int	     drm_dma_setup(drm_device_t *dev);
+extern void	     drm_dma_takedown(drm_device_t *dev);
+extern void	     drm_free_buffer(drm_device_t *dev, drm_buf_t *buf);
+extern void	     drm_core_reclaim_buffers(drm_device_t *dev, struct file *filp);
 
 				/* IRQ support (drm_irq.h) */
-extern int           DRM(control)( struct inode *inode, struct file *filp,
+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 );
-extern void          DRM(driver_irq_postinstall)( drm_device_t *dev );
-extern void          DRM(driver_irq_uninstall)( drm_device_t *dev );
+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 );
+extern void          drm_driver_irq_postinstall( drm_device_t *dev );
+extern void          drm_driver_irq_uninstall( drm_device_t *dev );
 
-extern int           DRM(wait_vblank)(struct inode *inode, struct file *filp,
+extern int           drm_wait_vblank(struct inode *inode, struct file *filp,
 				      unsigned int cmd, unsigned long arg);
-extern int           DRM(vblank_wait)(drm_device_t *dev, unsigned int *vbl_seq);
-extern void          DRM(vbl_send_signals)( drm_device_t *dev );
+extern int           drm_vblank_wait(drm_device_t *dev, unsigned int *vbl_seq);
+extern void          drm_vbl_send_signals( drm_device_t *dev );
 
 				/* AGP/GART support (drm_agpsupport.h) */
-extern drm_agp_head_t *DRM(agp_init)(void);
-extern void           DRM(agp_uninit)(void);
-extern int            DRM(agp_acquire)(struct inode *inode, struct file *filp,
+extern drm_agp_head_t *drm_agp_init(void);
+extern int            drm_agp_acquire(struct inode *inode, struct file *filp,
 				       unsigned int cmd, unsigned long arg);
-extern void           DRM(agp_do_release)(void);
-extern int            DRM(agp_release)(struct inode *inode, struct file *filp,
+extern void           drm_agp_do_release(void);
+extern int            drm_agp_release(struct inode *inode, struct file *filp,
 				       unsigned int cmd, unsigned long arg);
-extern int            DRM(agp_enable)(struct inode *inode, struct file *filp,
+extern int            drm_agp_enable(struct inode *inode, struct file *filp,
 				      unsigned int cmd, unsigned long arg);
-extern int            DRM(agp_info)(struct inode *inode, struct file *filp,
+extern int            drm_agp_info(struct inode *inode, struct file *filp,
 				    unsigned int cmd, unsigned long arg);
-extern int            DRM(agp_alloc)(struct inode *inode, struct file *filp,
+extern int            drm_agp_alloc(struct inode *inode, struct file *filp,
 				     unsigned int cmd, unsigned long arg);
-extern int            DRM(agp_free)(struct inode *inode, struct file *filp,
+extern int            drm_agp_free(struct inode *inode, struct file *filp,
 				    unsigned int cmd, unsigned long arg);
-extern int            DRM(agp_unbind)(struct inode *inode, struct file *filp,
+extern int            drm_agp_unbind(struct inode *inode, struct file *filp,
 				      unsigned int cmd, unsigned long arg);
-extern int            DRM(agp_bind)(struct inode *inode, struct file *filp,
+extern int            drm_agp_bind(struct inode *inode, struct file *filp,
 				    unsigned int cmd, unsigned long arg);
-extern DRM_AGP_MEM    *DRM(agp_allocate_memory)(size_t pages, u32 type);
-extern int            DRM(agp_free_memory)(DRM_AGP_MEM *handle);
-extern int            DRM(agp_bind_memory)(DRM_AGP_MEM *handle, off_t start);
-extern int            DRM(agp_unbind_memory)(DRM_AGP_MEM *handle);
+extern DRM_AGP_MEM    *drm_agp_allocate_memory(size_t pages, u32 type);
+extern int            drm_agp_free_memory(DRM_AGP_MEM *handle);
+extern int            drm_agp_bind_memory(DRM_AGP_MEM *handle, off_t start);
+extern int            drm_agp_unbind_memory(DRM_AGP_MEM *handle);
 
 				/* Stub support (drm_stub.h) */
-int                   DRM(stub_register)(const char *name,
-					 struct file_operations *fops,
-					 drm_device_t *dev);
-int                   DRM(stub_unregister)(int minor);
+extern int            drm_probe(struct pci_dev *pdev, const struct pci_device_id *ent, struct drm_driver *driver);
+
+extern int 	      drm_put_minor(drm_device_t *dev);
+extern unsigned int   drm_debug;
+extern unsigned int   drm_cards_limit;
+extern drm_minor_t    *drm_minors;
+extern struct drm_sysfs_class *drm_class;
+extern struct proc_dir_entry *drm_proc_root;
 
 				/* Proc support (drm_proc.h) */
-extern struct proc_dir_entry *DRM(proc_init)(drm_device_t *dev,
+extern int            drm_proc_init(drm_device_t *dev,
 					     int minor,
 					     struct proc_dir_entry *root,
 					     struct proc_dir_entry **dev_root);
-extern int            DRM(proc_cleanup)(int minor,
+extern int            drm_proc_cleanup(int minor,
 					struct proc_dir_entry *root,
 					struct proc_dir_entry *dev_root);
 
 				/* Scatter Gather Support (drm_scatter.h) */
-extern void           DRM(sg_cleanup)(drm_sg_mem_t *entry);
-extern int            DRM(sg_alloc)(struct inode *inode, struct file *filp,
+extern void           drm_sg_cleanup(drm_sg_mem_t *entry);
+extern int            drm_sg_alloc(struct inode *inode, struct file *filp,
 				    unsigned int cmd, unsigned long arg);
-extern int            DRM(sg_free)(struct inode *inode, struct file *filp,
+extern int            drm_sg_free(struct inode *inode, struct file *filp,
 				   unsigned int cmd, unsigned long arg);
 
                                /* ATI PCIGART support (ati_pcigart.h) */
-extern int            DRM(ati_pcigart_init)(drm_device_t *dev,
+extern int            drm_ati_pcigart_init(drm_device_t *dev,
 					    unsigned long *addr,
 					    dma_addr_t *bus_addr);
-extern int            DRM(ati_pcigart_cleanup)(drm_device_t *dev,
+extern int            drm_ati_pcigart_cleanup(drm_device_t *dev,
 					       unsigned long addr,
 					       dma_addr_t bus_addr);
 
+extern void *drm_pci_alloc(drm_device_t * dev, size_t size,
+			   size_t align, dma_addr_t maxaddr,
+			   dma_addr_t * busaddr);
+
+extern void drm_pci_free(drm_device_t * dev, size_t size,
+			 void *vaddr, dma_addr_t busaddr);
+
+			       /* sysfs support (drm_sysfs.c) */
+struct drm_sysfs_class;
+extern struct drm_sysfs_class *drm_sysfs_create(struct module *owner,
+						char *name);
+extern void drm_sysfs_destroy(struct drm_sysfs_class *cs);
+extern struct class_device *drm_sysfs_device_add(struct drm_sysfs_class *cs,
+						 dev_t dev,
+						 struct device *device,
+						 const char *fmt, ...);
+extern void drm_sysfs_device_remove(dev_t dev);
+
 
 /* Inline replacements for DRM_IOREMAP macros */
 static __inline__ void drm_core_ioremap(struct drm_map *map, struct drm_device *dev)
 {
-	map->handle = DRM(ioremap)( map->offset, map->size, dev );
+	map->handle = drm_ioremap( map->offset, map->size, dev );
 }
 
 static __inline__ void drm_core_ioremap_nocache(struct drm_map *map, struct drm_device *dev)
 {
-	map->handle = DRM(ioremap_nocache)(map->offset, map->size, dev);
+	map->handle = drm_ioremap_nocache(map->offset, map->size, dev);
 }
 
 static __inline__ void drm_core_ioremapfree(struct drm_map *map, struct drm_device *dev)
 {
 	if ( map->handle && map->size )
-		DRM(ioremapfree)( map->handle, map->size, dev );
+		drm_ioremapfree( map->handle, map->size, dev );
 }
 
 static __inline__ struct drm_map *drm_core_findmap(struct drm_device *dev, unsigned long offset)
@@ -984,10 +1039,28 @@
 static __inline__ void drm_core_dropmap(struct drm_map *map)
 {
 }
+
+#ifndef DEBUG_MEMORY
+/** Wrapper around kmalloc() */
+static __inline__ void *drm_alloc(size_t size, int area)
+{
+	return kmalloc(size, GFP_KERNEL);
+}
+
+/** Wrapper around kfree() */
+static __inline__ void drm_free(void *pt, size_t size, int area)
+{
+	kfree(pt);
+}
+#else
+extern void *drm_alloc(size_t size, int area);
+extern void drm_free(void *pt, size_t size, int area);
+#endif
+
 /*@}*/
 
-extern unsigned long DRM(core_get_map_ofs)(drm_map_t *map);
-extern unsigned long DRM(core_get_reg_ofs)(struct drm_device *dev);
+extern unsigned long drm_core_get_map_ofs(drm_map_t *map);
+extern unsigned long drm_core_get_reg_ofs(struct drm_device *dev);
 
 #endif /* __KERNEL__ */
 #endif
diff -Nru a/drivers/char/drm/drm_agpsupport.c b/drivers/char/drm/drm_agpsupport.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/char/drm/drm_agpsupport.c	2005-03-01 23:38:44 -08:00
@@ -0,0 +1,439 @@
+/**
+ * \file drm_agpsupport.h 
+ * DRM support for AGP/GART backend
+ *    
+ * \author Rickard E. (Rik) Faith <faith@valinux.com>
+ * \author Gareth Hughes <gareth@valinux.com>
+ */
+
+/*
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "drmP.h"
+#include <linux/module.h>
+
+#if __OS_HAS_AGP
+
+/**
+ * AGP information ioctl.
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg pointer to a (output) drm_agp_info structure.
+ * \return zero on success or a negative number on failure.
+ *
+ * Verifies the AGP device has been initialized and acquired and fills in the
+ * drm_agp_info structure with the information in drm_agp_head::agp_info.
+ */
+int drm_agp_info(struct inode *inode, struct file *filp,
+		  unsigned int cmd, unsigned long arg)
+{
+	drm_file_t	 *priv	 = filp->private_data;
+	drm_device_t	 *dev	 = priv->dev;
+	DRM_AGP_KERN     *kern;
+	drm_agp_info_t   info;
+
+	if (!dev->agp || !dev->agp->acquired)
+		return -EINVAL;
+
+	kern                   = &dev->agp->agp_info;
+	info.agp_version_major = kern->version.major;
+	info.agp_version_minor = kern->version.minor;
+	info.mode              = kern->mode;
+	info.aperture_base     = kern->aper_base;
+	info.aperture_size     = kern->aper_size * 1024 * 1024;
+	info.memory_allowed    = kern->max_memory << PAGE_SHIFT;
+	info.memory_used       = kern->current_memory << PAGE_SHIFT;
+	info.id_vendor         = kern->device->vendor;
+	info.id_device         = kern->device->device;
+
+	if (copy_to_user((drm_agp_info_t __user *)arg, &info, sizeof(info)))
+		return -EFAULT;
+	return 0;
+}
+
+/**
+ * Acquire the AGP device (ioctl).
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument.
+ * \return zero on success or a negative number on failure. 
+ *
+ * Verifies the AGP device hasn't been acquired before and calls
+ * agp_acquire().
+ */
+int drm_agp_acquire(struct inode *inode, struct file *filp,
+		     unsigned int cmd, unsigned long arg)
+{
+	drm_file_t	 *priv	 = filp->private_data;
+	drm_device_t	 *dev	 = priv->dev;
+	int              retcode;
+
+	if (!dev->agp)
+		return -ENODEV;
+	if (dev->agp->acquired)
+		return -EBUSY;
+	if ((retcode = agp_backend_acquire()))
+		return retcode;
+	dev->agp->acquired = 1;
+	return 0;
+}
+
+/**
+ * Release the AGP device (ioctl).
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument.
+ * \return zero on success or a negative number on failure.
+ *
+ * Verifies the AGP device has been acquired and calls agp_backend_release().
+ */
+int drm_agp_release(struct inode *inode, struct file *filp,
+		     unsigned int cmd, unsigned long arg)
+{
+	drm_file_t	 *priv	 = filp->private_data;
+	drm_device_t	 *dev	 = priv->dev;
+
+	if (!dev->agp || !dev->agp->acquired)
+		return -EINVAL;
+	agp_backend_release();
+	dev->agp->acquired = 0;
+	return 0;
+
+}
+
+/**
+ * Release the AGP device.
+ *
+ * Calls agp_backend_release().
+ */
+void drm_agp_do_release(void)
+{
+  agp_backend_release();
+}
+
+/**
+ * Enable the AGP bus.
+ * 
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg pointer to a drm_agp_mode structure.
+ * \return zero on success or a negative number on failure.
+ *
+ * Verifies the AGP device has been acquired but not enabled, and calls
+ * agp_enable().
+ */
+int drm_agp_enable(struct inode *inode, struct file *filp,
+		    unsigned int cmd, unsigned long arg)
+{
+	drm_file_t	 *priv	 = filp->private_data;
+	drm_device_t	 *dev	 = priv->dev;
+	drm_agp_mode_t   mode;
+
+	if (!dev->agp || !dev->agp->acquired)
+		return -EINVAL;
+
+	if (copy_from_user(&mode, (drm_agp_mode_t __user *)arg, sizeof(mode)))
+		return -EFAULT;
+
+	dev->agp->mode    = mode.mode;
+	agp_enable(mode.mode);
+	dev->agp->base    = dev->agp->agp_info.aper_base;
+	dev->agp->enabled = 1;
+	return 0;
+}
+
+/**
+ * Allocate AGP memory.
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg pointer to a drm_agp_buffer structure.
+ * \return zero on success or a negative number on failure.
+ * 
+ * Verifies the AGP device is present and has been acquired, allocates the
+ * memory via alloc_agp() and creates a drm_agp_mem entry for it.
+ */
+int drm_agp_alloc(struct inode *inode, struct file *filp,
+		   unsigned int cmd, unsigned long arg)
+{
+	drm_file_t	 *priv	 = filp->private_data;
+	drm_device_t	 *dev	 = priv->dev;
+	drm_agp_buffer_t request;
+	drm_agp_mem_t    *entry;
+	DRM_AGP_MEM      *memory;
+	unsigned long    pages;
+	u32 		 type;
+	drm_agp_buffer_t __user *argp = (void __user *)arg;
+
+	if (!dev->agp || !dev->agp->acquired)
+		return -EINVAL;
+	if (copy_from_user(&request, argp, sizeof(request)))
+		return -EFAULT;
+	if (!(entry = drm_alloc(sizeof(*entry), DRM_MEM_AGPLISTS)))
+		return -ENOMEM;
+
+   	memset(entry, 0, sizeof(*entry));
+
+	pages = (request.size + PAGE_SIZE - 1) / PAGE_SIZE;
+	type = (u32) request.type;
+
+	if (!(memory = drm_alloc_agp(pages, type))) {
+		drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
+		return -ENOMEM;
+	}
+
+	entry->handle    = (unsigned long)memory->key + 1;
+	entry->memory    = memory;
+	entry->bound     = 0;
+	entry->pages     = pages;
+	entry->prev      = NULL;
+	entry->next      = dev->agp->memory;
+	if (dev->agp->memory)
+		dev->agp->memory->prev = entry;
+	dev->agp->memory = entry;
+
+	request.handle   = entry->handle;
+	request.physical = memory->physical;
+
+	if (copy_to_user(argp, &request, sizeof(request))) {
+		dev->agp->memory       = entry->next;
+		dev->agp->memory->prev = NULL;
+		drm_free_agp(memory, pages);
+		drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
+		return -EFAULT;
+	}
+	return 0;
+}
+
+/**
+ * Search for the AGP memory entry associated with a handle.
+ *
+ * \param dev DRM device structure.
+ * \param handle AGP memory handle.
+ * \return pointer to the drm_agp_mem structure associated with \p handle.
+ * 
+ * Walks through drm_agp_head::memory until finding a matching handle.
+ */
+static drm_agp_mem_t *drm_agp_lookup_entry(drm_device_t *dev,
+					    unsigned long handle)
+{
+	drm_agp_mem_t *entry;
+
+	for (entry = dev->agp->memory; entry; entry = entry->next) {
+		if (entry->handle == handle)
+			return entry;
+	}
+	return NULL;
+}
+
+/**
+ * Unbind AGP memory from the GATT (ioctl).
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg pointer to a drm_agp_binding structure.
+ * \return zero on success or a negative number on failure.
+ *
+ * Verifies the AGP device is present and acquired, looks-up the AGP memory
+ * entry and passes it to the unbind_agp() function.
+ */
+int drm_agp_unbind(struct inode *inode, struct file *filp,
+		    unsigned int cmd, unsigned long arg)
+{
+	drm_file_t	  *priv	 = filp->private_data;
+	drm_device_t	  *dev	 = priv->dev;
+	drm_agp_binding_t request;
+	drm_agp_mem_t     *entry;
+	int ret;
+
+	if (!dev->agp || !dev->agp->acquired)
+		return -EINVAL;
+	if (copy_from_user(&request, (drm_agp_binding_t __user *)arg, sizeof(request)))
+		return -EFAULT;
+	if (!(entry = drm_agp_lookup_entry(dev, request.handle)))
+		return -EINVAL;
+	if (!entry->bound)
+		return -EINVAL;
+	ret = drm_unbind_agp(entry->memory);
+	if (ret == 0)
+	    entry->bound = 0;
+	return ret;
+}
+
+/**
+ * Bind AGP memory into the GATT (ioctl)
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg pointer to a drm_agp_binding structure.
+ * \return zero on success or a negative number on failure.
+ *
+ * Verifies the AGP device is present and has been acquired and that no memory
+ * is currently bound into the GATT. Looks-up the AGP memory entry and passes
+ * it to bind_agp() function.
+ */
+int drm_agp_bind(struct inode *inode, struct file *filp,
+		  unsigned int cmd, unsigned long arg)
+{
+	drm_file_t	  *priv	 = filp->private_data;
+	drm_device_t	  *dev	 = priv->dev;
+	drm_agp_binding_t request;
+	drm_agp_mem_t     *entry;
+	int               retcode;
+	int               page;
+
+	if (!dev->agp || !dev->agp->acquired)
+		return -EINVAL;
+	if (copy_from_user(&request, (drm_agp_binding_t __user *)arg, sizeof(request)))
+		return -EFAULT;
+	if (!(entry = drm_agp_lookup_entry(dev, request.handle)))
+		return -EINVAL;
+	if (entry->bound)
+		return -EINVAL;
+	page = (request.offset + PAGE_SIZE - 1) / PAGE_SIZE;
+	if ((retcode = drm_bind_agp(entry->memory, page)))
+		return retcode;
+	entry->bound = dev->agp->base + (page << PAGE_SHIFT);
+	DRM_DEBUG("base = 0x%lx entry->bound = 0x%lx\n",
+		  dev->agp->base, entry->bound);
+	return 0;
+}
+
+/**
+ * Free AGP memory (ioctl).
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg pointer to a drm_agp_buffer structure.
+ * \return zero on success or a negative number on failure.
+ *
+ * Verifies the AGP device is present and has been acquired and looks up the
+ * AGP memory entry. If the memory it's currently bound, unbind it via
+ * unbind_agp(). Frees it via free_agp() as well as the entry itself
+ * and unlinks from the doubly linked list it's inserted in.
+ */
+int drm_agp_free(struct inode *inode, struct file *filp,
+		  unsigned int cmd, unsigned long arg)
+{
+	drm_file_t	 *priv	 = filp->private_data;
+	drm_device_t	 *dev	 = priv->dev;
+	drm_agp_buffer_t request;
+	drm_agp_mem_t    *entry;
+
+	if (!dev->agp || !dev->agp->acquired)
+		return -EINVAL;
+	if (copy_from_user(&request, (drm_agp_buffer_t __user *)arg, sizeof(request)))
+		return -EFAULT;
+	if (!(entry = drm_agp_lookup_entry(dev, request.handle)))
+		return -EINVAL;
+	if (entry->bound)
+		drm_unbind_agp(entry->memory);
+
+	if (entry->prev)
+		entry->prev->next = entry->next;
+	else
+		dev->agp->memory = entry->next;
+
+	if (entry->next)
+		entry->next->prev = entry->prev;
+
+	drm_free_agp(entry->memory, entry->pages);
+	drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
+	return 0;
+}
+
+/**
+ * Initialize the AGP resources.
+ *
+ * \return pointer to a drm_agp_head structure.
+ *
+ */
+drm_agp_head_t *drm_agp_init(void)
+{
+	drm_agp_head_t *head         = NULL;
+
+	if (!(head = drm_alloc(sizeof(*head), DRM_MEM_AGPLISTS)))
+		return NULL;
+	memset((void *)head, 0, sizeof(*head));
+	agp_copy_info(&head->agp_info);
+	if (head->agp_info.chipset == NOT_SUPPORTED) {
+		drm_free(head, sizeof(*head), DRM_MEM_AGPLISTS);
+		return NULL;
+	}
+	head->memory = NULL;
+#if LINUX_VERSION_CODE <= 0x020408
+	head->cant_use_aperture = 0;
+	head->page_mask = ~(0xfff);
+#else
+	head->cant_use_aperture = head->agp_info.cant_use_aperture;
+	head->page_mask = head->agp_info.page_mask;
+#endif
+
+	return head;
+}
+
+/** Calls agp_allocate_memory() */
+DRM_AGP_MEM *drm_agp_allocate_memory(size_t pages, u32 type)
+{
+	return agp_allocate_memory(pages, type);
+}
+
+/** Calls agp_free_memory() */
+int drm_agp_free_memory(DRM_AGP_MEM *handle)
+{
+	if (!handle)
+		return 0;
+	agp_free_memory(handle);
+	return 1;
+}
+
+/** Calls agp_bind_memory() */
+int drm_agp_bind_memory(DRM_AGP_MEM *handle, off_t start)
+{
+	if (!handle)
+		return -EINVAL;
+	return agp_bind_memory(handle, start);
+}
+
+/** Calls agp_unbind_memory() */
+int drm_agp_unbind_memory(DRM_AGP_MEM *handle)
+{
+	if (!handle)
+		return -EINVAL;
+	return agp_unbind_memory(handle);
+}
+
+#endif /* __OS_HAS_AGP */
diff -Nru a/drivers/char/drm/drm_agpsupport.h b/drivers/char/drm/drm_agpsupport.h
--- a/drivers/char/drm/drm_agpsupport.h	2005-03-01 23:38:44 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,468 +0,0 @@
-/**
- * \file drm_agpsupport.h 
- * DRM support for AGP/GART backend
- *    
- * \author Rickard E. (Rik) Faith <faith@valinux.com>
- * \author Gareth Hughes <gareth@valinux.com>
- */
-
-/*
- * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include "drmP.h"
-#include <linux/module.h>
-
-#if __OS_HAS_AGP
-
-#define DRM_AGP_GET (drm_agp_t *)inter_module_get("drm_agp")
-#define DRM_AGP_PUT inter_module_put("drm_agp")
-
-/**
- * Pointer to the drm_agp_t structure made available by the agpgart module.
- */
-static const drm_agp_t *drm_agp = NULL;
-
-/**
- * AGP information ioctl.
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg pointer to a (output) drm_agp_info structure.
- * \return zero on success or a negative number on failure.
- *
- * Verifies the AGP device has been initialized and acquired and fills in the
- * drm_agp_info structure with the information in drm_agp_head::agp_info.
- */
-int DRM(agp_info)(struct inode *inode, struct file *filp,
-		  unsigned int cmd, unsigned long arg)
-{
-	drm_file_t	 *priv	 = filp->private_data;
-	drm_device_t	 *dev	 = priv->dev;
-	DRM_AGP_KERN     *kern;
-	drm_agp_info_t   info;
-
-	if (!dev->agp || !dev->agp->acquired || !drm_agp->copy_info)
-		return -EINVAL;
-
-	kern                   = &dev->agp->agp_info;
-	info.agp_version_major = kern->version.major;
-	info.agp_version_minor = kern->version.minor;
-	info.mode              = kern->mode;
-	info.aperture_base     = kern->aper_base;
-	info.aperture_size     = kern->aper_size * 1024 * 1024;
-	info.memory_allowed    = kern->max_memory << PAGE_SHIFT;
-	info.memory_used       = kern->current_memory << PAGE_SHIFT;
-	info.id_vendor         = kern->device->vendor;
-	info.id_device         = kern->device->device;
-
-	if (copy_to_user((drm_agp_info_t __user *)arg, &info, sizeof(info)))
-		return -EFAULT;
-	return 0;
-}
-
-/**
- * Acquire the AGP device (ioctl).
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg user argument.
- * \return zero on success or a negative number on failure. 
- *
- * Verifies the AGP device hasn't been acquired before and calls
- * drm_agp->acquire().
- */
-int DRM(agp_acquire)(struct inode *inode, struct file *filp,
-		     unsigned int cmd, unsigned long arg)
-{
-	drm_file_t	 *priv	 = filp->private_data;
-	drm_device_t	 *dev	 = priv->dev;
-	int              retcode;
-
-	if (!dev->agp)
-		return -ENODEV;
-	if (dev->agp->acquired)
-		return -EBUSY;
-	if (!drm_agp->acquire)
-		return -EINVAL;
-	if ((retcode = drm_agp->acquire()))
-		return retcode;
-	dev->agp->acquired = 1;
-	return 0;
-}
-
-/**
- * Release the AGP device (ioctl).
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg user argument.
- * \return zero on success or a negative number on failure.
- *
- * Verifies the AGP device has been acquired and calls drm_agp->release().
- */
-int DRM(agp_release)(struct inode *inode, struct file *filp,
-		     unsigned int cmd, unsigned long arg)
-{
-	drm_file_t	 *priv	 = filp->private_data;
-	drm_device_t	 *dev	 = priv->dev;
-
-	if (!dev->agp || !dev->agp->acquired || !drm_agp->release)
-		return -EINVAL;
-	drm_agp->release();
-	dev->agp->acquired = 0;
-	return 0;
-
-}
-
-/**
- * Release the AGP device.
- *
- * Calls drm_agp->release().
- */
-void DRM(agp_do_release)(void)
-{
-	if (drm_agp->release)
-		drm_agp->release();
-}
-
-/**
- * Enable the AGP bus.
- * 
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg pointer to a drm_agp_mode structure.
- * \return zero on success or a negative number on failure.
- *
- * Verifies the AGP device has been acquired but not enabled, and calls
- * drm_agp->enable().
- */
-int DRM(agp_enable)(struct inode *inode, struct file *filp,
-		    unsigned int cmd, unsigned long arg)
-{
-	drm_file_t	 *priv	 = filp->private_data;
-	drm_device_t	 *dev	 = priv->dev;
-	drm_agp_mode_t   mode;
-
-	if (!dev->agp || !dev->agp->acquired || !drm_agp->enable)
-		return -EINVAL;
-
-	if (copy_from_user(&mode, (drm_agp_mode_t __user *)arg, sizeof(mode)))
-		return -EFAULT;
-
-	dev->agp->mode    = mode.mode;
-	drm_agp->enable(mode.mode);
-	dev->agp->base    = dev->agp->agp_info.aper_base;
-	dev->agp->enabled = 1;
-	return 0;
-}
-
-/**
- * Allocate AGP memory.
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg pointer to a drm_agp_buffer structure.
- * \return zero on success or a negative number on failure.
- * 
- * Verifies the AGP device is present and has been acquired, allocates the
- * memory via alloc_agp() and creates a drm_agp_mem entry for it.
- */
-int DRM(agp_alloc)(struct inode *inode, struct file *filp,
-		   unsigned int cmd, unsigned long arg)
-{
-	drm_file_t	 *priv	 = filp->private_data;
-	drm_device_t	 *dev	 = priv->dev;
-	drm_agp_buffer_t request;
-	drm_agp_mem_t    *entry;
-	DRM_AGP_MEM      *memory;
-	unsigned long    pages;
-	u32 		 type;
-	drm_agp_buffer_t __user *argp = (void __user *)arg;
-
-	if (!dev->agp || !dev->agp->acquired)
-		return -EINVAL;
-	if (copy_from_user(&request, argp, sizeof(request)))
-		return -EFAULT;
-	if (!(entry = DRM(alloc)(sizeof(*entry), DRM_MEM_AGPLISTS)))
-		return -ENOMEM;
-
-   	memset(entry, 0, sizeof(*entry));
-
-	pages = (request.size + PAGE_SIZE - 1) / PAGE_SIZE;
-	type = (u32) request.type;
-
-	if (!(memory = DRM(alloc_agp)(pages, type))) {
-		DRM(free)(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
-		return -ENOMEM;
-	}
-
-	entry->handle    = (unsigned long)memory->key + 1;
-	entry->memory    = memory;
-	entry->bound     = 0;
-	entry->pages     = pages;
-	entry->prev      = NULL;
-	entry->next      = dev->agp->memory;
-	if (dev->agp->memory)
-		dev->agp->memory->prev = entry;
-	dev->agp->memory = entry;
-
-	request.handle   = entry->handle;
-	request.physical = memory->physical;
-
-	if (copy_to_user(argp, &request, sizeof(request))) {
-		dev->agp->memory       = entry->next;
-		dev->agp->memory->prev = NULL;
-		DRM(free_agp)(memory, pages);
-		DRM(free)(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
-		return -EFAULT;
-	}
-	return 0;
-}
-
-/**
- * Search for the AGP memory entry associated with a handle.
- *
- * \param dev DRM device structure.
- * \param handle AGP memory handle.
- * \return pointer to the drm_agp_mem structure associated with \p handle.
- * 
- * Walks through drm_agp_head::memory until finding a matching handle.
- */
-static drm_agp_mem_t *DRM(agp_lookup_entry)(drm_device_t *dev,
-					    unsigned long handle)
-{
-	drm_agp_mem_t *entry;
-
-	for (entry = dev->agp->memory; entry; entry = entry->next) {
-		if (entry->handle == handle)
-			return entry;
-	}
-	return NULL;
-}
-
-/**
- * Unbind AGP memory from the GATT (ioctl).
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg pointer to a drm_agp_binding structure.
- * \return zero on success or a negative number on failure.
- *
- * Verifies the AGP device is present and acquired, looks-up the AGP memory
- * entry and passes it to the unbind_agp() function.
- */
-int DRM(agp_unbind)(struct inode *inode, struct file *filp,
-		    unsigned int cmd, unsigned long arg)
-{
-	drm_file_t	  *priv	 = filp->private_data;
-	drm_device_t	  *dev	 = priv->dev;
-	drm_agp_binding_t request;
-	drm_agp_mem_t     *entry;
-	int ret;
-
-	if (!dev->agp || !dev->agp->acquired)
-		return -EINVAL;
-	if (copy_from_user(&request, (drm_agp_binding_t __user *)arg, sizeof(request)))
-		return -EFAULT;
-	if (!(entry = DRM(agp_lookup_entry)(dev, request.handle)))
-		return -EINVAL;
-	if (!entry->bound)
-		return -EINVAL;
-	ret = DRM(unbind_agp)(entry->memory);
-	if (ret == 0)
-	    entry->bound = 0;
-	return ret;
-}
-
-/**
- * Bind AGP memory into the GATT (ioctl)
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg pointer to a drm_agp_binding structure.
- * \return zero on success or a negative number on failure.
- *
- * Verifies the AGP device is present and has been acquired and that no memory
- * is currently bound into the GATT. Looks-up the AGP memory entry and passes
- * it to bind_agp() function.
- */
-int DRM(agp_bind)(struct inode *inode, struct file *filp,
-		  unsigned int cmd, unsigned long arg)
-{
-	drm_file_t	  *priv	 = filp->private_data;
-	drm_device_t	  *dev	 = priv->dev;
-	drm_agp_binding_t request;
-	drm_agp_mem_t     *entry;
-	int               retcode;
-	int               page;
-
-	if (!dev->agp || !dev->agp->acquired || !drm_agp->bind_memory)
-		return -EINVAL;
-	if (copy_from_user(&request, (drm_agp_binding_t __user *)arg, sizeof(request)))
-		return -EFAULT;
-	if (!(entry = DRM(agp_lookup_entry)(dev, request.handle)))
-		return -EINVAL;
-	if (entry->bound)
-		return -EINVAL;
-	page = (request.offset + PAGE_SIZE - 1) / PAGE_SIZE;
-	if ((retcode = DRM(bind_agp)(entry->memory, page)))
-		return retcode;
-	entry->bound = dev->agp->base + (page << PAGE_SHIFT);
-	DRM_DEBUG("base = 0x%lx entry->bound = 0x%lx\n",
-		  dev->agp->base, entry->bound);
-	return 0;
-}
-
-/**
- * Free AGP memory (ioctl).
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg pointer to a drm_agp_buffer structure.
- * \return zero on success or a negative number on failure.
- *
- * Verifies the AGP device is present and has been acquired and looks up the
- * AGP memory entry. If the memory it's currently bound, unbind it via
- * unbind_agp(). Frees it via free_agp() as well as the entry itself
- * and unlinks from the doubly linked list it's inserted in.
- */
-int DRM(agp_free)(struct inode *inode, struct file *filp,
-		  unsigned int cmd, unsigned long arg)
-{
-	drm_file_t	 *priv	 = filp->private_data;
-	drm_device_t	 *dev	 = priv->dev;
-	drm_agp_buffer_t request;
-	drm_agp_mem_t    *entry;
-
-	if (!dev->agp || !dev->agp->acquired)
-		return -EINVAL;
-	if (copy_from_user(&request, (drm_agp_buffer_t __user *)arg, sizeof(request)))
-		return -EFAULT;
-	if (!(entry = DRM(agp_lookup_entry)(dev, request.handle)))
-		return -EINVAL;
-	if (entry->bound)
-		DRM(unbind_agp)(entry->memory);
-
-	if (entry->prev)
-		entry->prev->next = entry->next;
-	else
-		dev->agp->memory = entry->next;
-
-	if (entry->next)
-		entry->next->prev = entry->prev;
-
-	DRM(free_agp)(entry->memory, entry->pages);
-	DRM(free)(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
-	return 0;
-}
-
-/**
- * Initialize the AGP resources.
- *
- * \return pointer to a drm_agp_head structure.
- *
- * Gets the drm_agp_t structure which is made available by the agpgart module
- * via the inter_module_* functions. Creates and initializes a drm_agp_head
- * structure.
- */
-drm_agp_head_t *DRM(agp_init)(void)
-{
-	drm_agp_head_t *head         = NULL;
-
-	drm_agp = DRM_AGP_GET;
-	if (drm_agp) {
-		if (!(head = DRM(alloc)(sizeof(*head), DRM_MEM_AGPLISTS)))
-			return NULL;
-		memset((void *)head, 0, sizeof(*head));
-		drm_agp->copy_info(&head->agp_info);
-		if (head->agp_info.chipset == NOT_SUPPORTED) {
-			DRM(free)(head, sizeof(*head), DRM_MEM_AGPLISTS);
-			return NULL;
-		}
-		head->memory = NULL;
-#if LINUX_VERSION_CODE <= 0x020408
-		head->cant_use_aperture = 0;
-		head->page_mask = ~(0xfff);
-#else
-		head->cant_use_aperture = head->agp_info.cant_use_aperture;
-		head->page_mask = head->agp_info.page_mask;
-#endif
-	}
-	return head;
-}
-
-/**
- * Free the AGP resources.
- *
- * Releases the pointer in ::drm_agp.
- */
-void DRM(agp_uninit)(void)
-{
-	DRM_AGP_PUT;
-	drm_agp = NULL;
-}
-
-/** Calls drm_agp->allocate_memory() */
-DRM_AGP_MEM *DRM(agp_allocate_memory)(size_t pages, u32 type)
-{
-	if (!drm_agp->allocate_memory)
-		return NULL;
-	return drm_agp->allocate_memory(pages, type);
-}
-
-/** Calls drm_agp->free_memory() */
-int DRM(agp_free_memory)(DRM_AGP_MEM *handle)
-{
-	if (!handle || !drm_agp->free_memory)
-		return 0;
-	drm_agp->free_memory(handle);
-	return 1;
-}
-
-/** Calls drm_agp->bind_memory() */
-int DRM(agp_bind_memory)(DRM_AGP_MEM *handle, off_t start)
-{
-	if (!handle || !drm_agp->bind_memory)
-		return -EINVAL;
-	return drm_agp->bind_memory(handle, start);
-}
-
-/** Calls drm_agp->unbind_memory() */
-int DRM(agp_unbind_memory)(DRM_AGP_MEM *handle)
-{
-	if (!handle || !drm_agp->unbind_memory)
-		return -EINVAL;
-	return drm_agp->unbind_memory(handle);
-}
-
-#endif /* __OS_HAS_AGP */
diff -Nru a/drivers/char/drm/drm_auth.c b/drivers/char/drm/drm_auth.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/char/drm/drm_auth.c	2005-03-01 23:39:10 -08:00
@@ -0,0 +1,230 @@
+/**
+ * \file drm_auth.h 
+ * IOCTLs for authentication
+ *
+ * \author Rickard E. (Rik) Faith <faith@valinux.com>
+ * \author Gareth Hughes <gareth@valinux.com>
+ */
+
+/*
+ * Created: Tue Feb  2 08:37:54 1999 by faith@valinux.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "drmP.h"
+
+/**
+ * Generate a hash key from a magic.
+ *
+ * \param magic magic.
+ * \return hash key.
+ *
+ * The key is the modulus of the hash table size, #DRM_HASH_SIZE, which must be
+ * a power of 2.
+ */
+static int drm_hash_magic(drm_magic_t magic)
+{
+	return magic & (DRM_HASH_SIZE-1);
+}
+
+/**
+ * Find the file with the given magic number.
+ *
+ * \param dev DRM device.
+ * \param magic magic number.
+ *
+ * Searches in drm_device::magiclist within all files with the same hash key
+ * the one with matching magic number, while holding the drm_device::struct_sem
+ * lock.
+ */
+static drm_file_t *drm_find_file(drm_device_t *dev, drm_magic_t magic)
+{
+	drm_file_t	  *retval = NULL;
+	drm_magic_entry_t *pt;
+	int		  hash	  = drm_hash_magic(magic);
+
+	down(&dev->struct_sem);
+	for (pt = dev->magiclist[hash].head; pt; pt = pt->next) {
+		if (pt->magic == magic) {
+			retval = pt->priv;
+			break;
+		}
+	}
+	up(&dev->struct_sem);
+	return retval;
+}
+
+/**
+ * Adds a magic number.
+ * 
+ * \param dev DRM device.
+ * \param priv file private data.
+ * \param magic magic number.
+ *
+ * Creates a drm_magic_entry structure and appends to the linked list
+ * 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)
+{
+	int		  hash;
+	drm_magic_entry_t *entry;
+
+	DRM_DEBUG("%d\n", magic);
+
+	hash	     = drm_hash_magic(magic);
+	entry	     = drm_alloc(sizeof(*entry), DRM_MEM_MAGIC);
+	if (!entry) return -ENOMEM;
+	memset(entry, 0, sizeof(*entry));
+	entry->magic = magic;
+	entry->priv  = priv;
+	entry->next  = NULL;
+
+	down(&dev->struct_sem);
+	if (dev->magiclist[hash].tail) {
+		dev->magiclist[hash].tail->next = entry;
+		dev->magiclist[hash].tail	= entry;
+	} else {
+		dev->magiclist[hash].head	= entry;
+		dev->magiclist[hash].tail	= entry;
+	}
+	up(&dev->struct_sem);
+
+	return 0;
+}
+
+/**
+ * Remove a magic number.
+ * 
+ * \param dev DRM device.
+ * \param magic magic number.
+ *
+ * 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)
+{
+	drm_magic_entry_t *prev = NULL;
+	drm_magic_entry_t *pt;
+	int		  hash;
+
+
+	DRM_DEBUG("%d\n", magic);
+	hash = drm_hash_magic(magic);
+
+	down(&dev->struct_sem);
+	for (pt = dev->magiclist[hash].head; pt; prev = pt, pt = pt->next) {
+		if (pt->magic == magic) {
+			if (dev->magiclist[hash].head == pt) {
+				dev->magiclist[hash].head = pt->next;
+			}
+			if (dev->magiclist[hash].tail == pt) {
+				dev->magiclist[hash].tail = prev;
+			}
+			if (prev) {
+				prev->next = pt->next;
+			}
+			up(&dev->struct_sem);
+			return 0;
+		}
+	}
+	up(&dev->struct_sem);
+
+	drm_free(pt, sizeof(*pt), DRM_MEM_MAGIC);
+
+	return -EINVAL;
+}
+
+/**
+ * Get a unique magic number (ioctl).
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg pointer to a resulting drm_auth structure.
+ * \return zero on success, or a negative number on failure.
+ *
+ * If there is a magic number in drm_file::magic then use it, otherwise
+ * searches an unique non-zero magic number and add it associating it with \p
+ * filp.
+ */
+int drm_getmagic(struct inode *inode, struct file *filp,
+		  unsigned int cmd, unsigned long arg)
+{
+	static drm_magic_t sequence = 0;
+	static DEFINE_SPINLOCK(lock);
+	drm_file_t	   *priv    = filp->private_data;
+	drm_device_t	   *dev	    = priv->dev;
+	drm_auth_t	   auth;
+
+				/* Find unique magic */
+	if (priv->magic) {
+		auth.magic = priv->magic;
+	} else {
+		do {
+			spin_lock(&lock);
+			if (!sequence) ++sequence; /* reserve 0 */
+			auth.magic = sequence++;
+			spin_unlock(&lock);
+		} while (drm_find_file(dev, auth.magic));
+		priv->magic = auth.magic;
+		drm_add_magic(dev, priv, auth.magic);
+	}
+
+	DRM_DEBUG("%u\n", auth.magic);
+	if (copy_to_user((drm_auth_t __user *)arg, &auth, sizeof(auth)))
+		return -EFAULT;
+	return 0;
+}
+
+/**
+ * Authenticate with a magic.
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg pointer to a drm_auth structure.
+ * \return zero if authentication successed, or a negative number otherwise.
+ *
+ * Checks if \p filp is associated with the magic number passed in \arg.
+ */
+int drm_authmagic(struct inode *inode, struct file *filp,
+		   unsigned int cmd, unsigned long arg)
+{
+	drm_file_t	   *priv    = filp->private_data;
+	drm_device_t	   *dev	    = priv->dev;
+	drm_auth_t	   auth;
+	drm_file_t	   *file;
+
+	if (copy_from_user(&auth, (drm_auth_t __user *)arg, sizeof(auth)))
+		return -EFAULT;
+	DRM_DEBUG("%u\n", auth.magic);
+	if ((file = drm_find_file(dev, auth.magic))) {
+		file->authenticated = 1;
+		drm_remove_magic(dev, auth.magic);
+		return 0;
+	}
+	return -EINVAL;
+}
diff -Nru a/drivers/char/drm/drm_auth.h b/drivers/char/drm/drm_auth.h
--- a/drivers/char/drm/drm_auth.h	2005-03-01 23:39:10 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,230 +0,0 @@
-/**
- * \file drm_auth.h 
- * IOCTLs for authentication
- *
- * \author Rickard E. (Rik) Faith <faith@valinux.com>
- * \author Gareth Hughes <gareth@valinux.com>
- */
-
-/*
- * Created: Tue Feb  2 08:37:54 1999 by faith@valinux.com
- *
- * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include "drmP.h"
-
-/**
- * Generate a hash key from a magic.
- *
- * \param magic magic.
- * \return hash key.
- *
- * The key is the modulus of the hash table size, #DRM_HASH_SIZE, which must be
- * a power of 2.
- */
-static int DRM(hash_magic)(drm_magic_t magic)
-{
-	return magic & (DRM_HASH_SIZE-1);
-}
-
-/**
- * Find the file with the given magic number.
- *
- * \param dev DRM device.
- * \param magic magic number.
- *
- * Searches in drm_device::magiclist within all files with the same hash key
- * the one with matching magic number, while holding the drm_device::struct_sem
- * lock.
- */
-static drm_file_t *DRM(find_file)(drm_device_t *dev, drm_magic_t magic)
-{
-	drm_file_t	  *retval = NULL;
-	drm_magic_entry_t *pt;
-	int		  hash	  = DRM(hash_magic)(magic);
-
-	down(&dev->struct_sem);
-	for (pt = dev->magiclist[hash].head; pt; pt = pt->next) {
-		if (pt->magic == magic) {
-			retval = pt->priv;
-			break;
-		}
-	}
-	up(&dev->struct_sem);
-	return retval;
-}
-
-/**
- * Adds a magic number.
- * 
- * \param dev DRM device.
- * \param priv file private data.
- * \param magic magic number.
- *
- * Creates a drm_magic_entry structure and appends to the linked list
- * 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)
-{
-	int		  hash;
-	drm_magic_entry_t *entry;
-
-	DRM_DEBUG("%d\n", magic);
-
-	hash	     = DRM(hash_magic)(magic);
-	entry	     = DRM(alloc)(sizeof(*entry), DRM_MEM_MAGIC);
-	if (!entry) return -ENOMEM;
-	memset(entry, 0, sizeof(*entry));
-	entry->magic = magic;
-	entry->priv  = priv;
-	entry->next  = NULL;
-
-	down(&dev->struct_sem);
-	if (dev->magiclist[hash].tail) {
-		dev->magiclist[hash].tail->next = entry;
-		dev->magiclist[hash].tail	= entry;
-	} else {
-		dev->magiclist[hash].head	= entry;
-		dev->magiclist[hash].tail	= entry;
-	}
-	up(&dev->struct_sem);
-
-	return 0;
-}
-
-/**
- * Remove a magic number.
- * 
- * \param dev DRM device.
- * \param magic magic number.
- *
- * 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)
-{
-	drm_magic_entry_t *prev = NULL;
-	drm_magic_entry_t *pt;
-	int		  hash;
-
-
-	DRM_DEBUG("%d\n", magic);
-	hash = DRM(hash_magic)(magic);
-
-	down(&dev->struct_sem);
-	for (pt = dev->magiclist[hash].head; pt; prev = pt, pt = pt->next) {
-		if (pt->magic == magic) {
-			if (dev->magiclist[hash].head == pt) {
-				dev->magiclist[hash].head = pt->next;
-			}
-			if (dev->magiclist[hash].tail == pt) {
-				dev->magiclist[hash].tail = prev;
-			}
-			if (prev) {
-				prev->next = pt->next;
-			}
-			up(&dev->struct_sem);
-			return 0;
-		}
-	}
-	up(&dev->struct_sem);
-
-	DRM(free)(pt, sizeof(*pt), DRM_MEM_MAGIC);
-
-	return -EINVAL;
-}
-
-/**
- * Get a unique magic number (ioctl).
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg pointer to a resulting drm_auth structure.
- * \return zero on success, or a negative number on failure.
- *
- * If there is a magic number in drm_file::magic then use it, otherwise
- * searches an unique non-zero magic number and add it associating it with \p
- * filp.
- */
-int DRM(getmagic)(struct inode *inode, struct file *filp,
-		  unsigned int cmd, unsigned long arg)
-{
-	static drm_magic_t sequence = 0;
-	static spinlock_t  lock	    = SPIN_LOCK_UNLOCKED;
-	drm_file_t	   *priv    = filp->private_data;
-	drm_device_t	   *dev	    = priv->dev;
-	drm_auth_t	   auth;
-
-				/* Find unique magic */
-	if (priv->magic) {
-		auth.magic = priv->magic;
-	} else {
-		do {
-			spin_lock(&lock);
-			if (!sequence) ++sequence; /* reserve 0 */
-			auth.magic = sequence++;
-			spin_unlock(&lock);
-		} while (DRM(find_file)(dev, auth.magic));
-		priv->magic = auth.magic;
-		DRM(add_magic)(dev, priv, auth.magic);
-	}
-
-	DRM_DEBUG("%u\n", auth.magic);
-	if (copy_to_user((drm_auth_t __user *)arg, &auth, sizeof(auth)))
-		return -EFAULT;
-	return 0;
-}
-
-/**
- * Authenticate with a magic.
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg pointer to a drm_auth structure.
- * \return zero if authentication successed, or a negative number otherwise.
- *
- * Checks if \p filp is associated with the magic number passed in \arg.
- */
-int DRM(authmagic)(struct inode *inode, struct file *filp,
-		   unsigned int cmd, unsigned long arg)
-{
-	drm_file_t	   *priv    = filp->private_data;
-	drm_device_t	   *dev	    = priv->dev;
-	drm_auth_t	   auth;
-	drm_file_t	   *file;
-
-	if (copy_from_user(&auth, (drm_auth_t __user *)arg, sizeof(auth)))
-		return -EFAULT;
-	DRM_DEBUG("%u\n", auth.magic);
-	if ((file = DRM(find_file)(dev, auth.magic))) {
-		file->authenticated = 1;
-		DRM(remove_magic)(dev, auth.magic);
-		return 0;
-	}
-	return -EINVAL;
-}
diff -Nru a/drivers/char/drm/drm_bufs.c b/drivers/char/drm/drm_bufs.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/char/drm/drm_bufs.c	2005-03-01 23:38:53 -08:00
@@ -0,0 +1,1270 @@
+/**
+ * \file drm_bufs.h 
+ * Generic buffer template
+ * 
+ * \author Rickard E. (Rik) Faith <faith@valinux.com>
+ * \author Gareth Hughes <gareth@valinux.com>
+ */
+
+/*
+ * Created: Thu Nov 23 03:10:50 2000 by gareth@valinux.com
+ *
+ * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <linux/vmalloc.h>
+#include "drmP.h"
+
+/**
+ * Compute size order.  Returns the exponent of the smaller power of two which
+ * is greater or equal to given number.
+ * 
+ * \param size size.
+ * \return order.
+ *
+ * \todo Can be made faster.
+ */
+int drm_order( unsigned long size )
+{
+	int order;
+	unsigned long tmp;
+
+	for (order = 0, tmp = size >> 1; tmp; tmp >>= 1, order++)
+		;
+
+	if (size & (size - 1))
+		++order;
+
+	return order;
+}
+EXPORT_SYMBOL(drm_order);
+
+/**
+ * Ioctl to specify a range of memory that is available for mapping by a non-root process.
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg pointer to a drm_map structure.
+ * \return zero on success or a negative value on error.
+ *
+ * Adjusts the memory offset to its absolute value according to the mapping
+ * type.  Adds the map to the map list drm_device::maplist. Adds MTRR's where
+ * applicable and if supported by the kernel.
+ */
+int drm_addmap( struct inode *inode, struct file *filp,
+		 unsigned int cmd, unsigned long arg )
+{
+	drm_file_t *priv = filp->private_data;
+	drm_device_t *dev = priv->dev;
+	drm_map_t *map;
+	drm_map_t __user *argp = (void __user *)arg;
+	drm_map_list_t *list;
+
+	if ( !(filp->f_mode & 3) ) return -EACCES; /* Require read/write */
+
+	map = drm_alloc( sizeof(*map), DRM_MEM_MAPS );
+	if ( !map )
+		return -ENOMEM;
+
+	if ( copy_from_user( map, argp, sizeof(*map) ) ) {
+		drm_free( map, sizeof(*map), DRM_MEM_MAPS );
+		return -EFAULT;
+	}
+
+	/* Only allow shared memory to be removable since we only keep enough
+	 * book keeping information about shared memory to allow for removal
+	 * when processes fork.
+	 */
+	if ( (map->flags & _DRM_REMOVABLE) && map->type != _DRM_SHM ) {
+		drm_free( map, sizeof(*map), DRM_MEM_MAPS );
+		return -EINVAL;
+	}
+	DRM_DEBUG( "offset = 0x%08lx, size = 0x%08lx, type = %d\n",
+		   map->offset, map->size, map->type );
+	if ( (map->offset & (~PAGE_MASK)) || (map->size & (~PAGE_MASK)) ) {
+		drm_free( map, sizeof(*map), DRM_MEM_MAPS );
+		return -EINVAL;
+	}
+	map->mtrr   = -1;
+	map->handle = NULL;
+
+	switch ( map->type ) {
+	case _DRM_REGISTERS:
+	case _DRM_FRAME_BUFFER:
+#if !defined(__sparc__) && !defined(__alpha__) && !defined(__ia64__)
+		if ( map->offset + map->size < map->offset ||
+		     map->offset < virt_to_phys(high_memory) ) {
+			drm_free( map, sizeof(*map), DRM_MEM_MAPS );
+			return -EINVAL;
+		}
+#endif
+#ifdef __alpha__
+		map->offset += dev->hose->mem_space->start;
+#endif
+		if (drm_core_has_MTRR(dev)) {
+			if ( map->type == _DRM_FRAME_BUFFER ||
+			     (map->flags & _DRM_WRITE_COMBINING) ) {
+				map->mtrr = mtrr_add( map->offset, map->size,
+						      MTRR_TYPE_WRCOMB, 1 );
+			}
+		}
+		if (map->type == _DRM_REGISTERS)
+			map->handle = drm_ioremap( map->offset, map->size,
+						    dev );
+		break;
+
+	case _DRM_SHM:
+		map->handle = vmalloc_32(map->size);
+		DRM_DEBUG( "%lu %d %p\n",
+			   map->size, drm_order( map->size ), map->handle );
+		if ( !map->handle ) {
+			drm_free( map, sizeof(*map), DRM_MEM_MAPS );
+			return -ENOMEM;
+		}
+		map->offset = (unsigned long)map->handle;
+		if ( map->flags & _DRM_CONTAINS_LOCK ) {
+			/* Prevent a 2nd X Server from creating a 2nd lock */
+			if (dev->lock.hw_lock != NULL) {
+				vfree( map->handle );
+				drm_free( map, sizeof(*map), DRM_MEM_MAPS );
+				return -EBUSY;
+			}
+			dev->sigdata.lock =
+			dev->lock.hw_lock = map->handle; /* Pointer to lock */
+		}
+		break;
+	case _DRM_AGP:
+		if (drm_core_has_AGP(dev)) {
+#ifdef __alpha__
+			map->offset += dev->hose->mem_space->start;
+#endif
+			map->offset += dev->agp->base;
+			map->mtrr   = dev->agp->agp_mtrr; /* for getmap */
+		}
+		break;
+	case _DRM_SCATTER_GATHER:
+		if (!dev->sg) {
+			drm_free(map, sizeof(*map), DRM_MEM_MAPS);
+			return -EINVAL;
+		}
+		map->offset += dev->sg->handle;
+		break;
+
+	default:
+		drm_free( map, sizeof(*map), DRM_MEM_MAPS );
+		return -EINVAL;
+	}
+
+	list = drm_alloc(sizeof(*list), DRM_MEM_MAPS);
+	if(!list) {
+		drm_free(map, sizeof(*map), DRM_MEM_MAPS);
+		return -EINVAL;
+	}
+	memset(list, 0, sizeof(*list));
+	list->map = map;
+
+	down(&dev->struct_sem);
+	list_add(&list->head, &dev->maplist->head);
+ 	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;
+	}
+	return 0;
+}
+
+
+/**
+ * Remove a map private from list and deallocate resources if the mapping
+ * isn't in use.
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg pointer to a drm_map_t structure.
+ * \return zero on success or a negative value on error.
+ *
+ * Searches the map on drm_device::maplist, removes it from the list, see if
+ * its being used, and free any associate resource (such as MTRR's) if it's not
+ * being on use.
+ *
+ * \sa addmap().
+ */
+int drm_rmmap(struct inode *inode, struct file *filp,
+	       unsigned int cmd, unsigned long arg)
+{
+	drm_file_t	*priv	= filp->private_data;
+	drm_device_t	*dev	= priv->dev;
+	struct list_head *list;
+	drm_map_list_t *r_list = NULL;
+	drm_vma_entry_t *pt, *prev;
+	drm_map_t *map;
+	drm_map_t request;
+	int found_maps = 0;
+
+	if (copy_from_user(&request, (drm_map_t __user *)arg,
+			   sizeof(request))) {
+		return -EFAULT;
+	}
+
+	down(&dev->struct_sem);
+	list = &dev->maplist->head;
+	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 &&
+		   r_list->map->flags & _DRM_REMOVABLE) break;
+	}
+
+	/* List has wrapped around to the head pointer, or its empty we didn't
+	 * find anything.
+	 */
+	if(list == (&dev->maplist->head)) {
+		up(&dev->struct_sem);
+		return -EINVAL;
+	}
+	map = r_list->map;
+	list_del(list);
+	drm_free(list, sizeof(*list), DRM_MEM_MAPS);
+
+	for (pt = dev->vmalist, prev = NULL; pt; prev = pt, pt = pt->next) {
+		if (pt->vma->vm_private_data == map) found_maps++;
+	}
+
+	if(!found_maps) {
+		switch (map->type) {
+		case _DRM_REGISTERS:
+		case _DRM_FRAME_BUFFER:
+		  if (drm_core_has_MTRR(dev)) {
+				if (map->mtrr >= 0) {
+					int retcode;
+					retcode = mtrr_del(map->mtrr,
+							   map->offset,
+							   map->size);
+					DRM_DEBUG("mtrr_del = %d\n", retcode);
+				}
+			}
+			drm_ioremapfree(map->handle, map->size, dev);
+			break;
+		case _DRM_SHM:
+			vfree(map->handle);
+			break;
+		case _DRM_AGP:
+		case _DRM_SCATTER_GATHER:
+			break;
+		}
+		drm_free(map, sizeof(*map), DRM_MEM_MAPS);
+	}
+	up(&dev->struct_sem);
+	return 0;
+}
+
+/**
+ * Cleanup after an error on one of the addbufs() functions.
+ *
+ * \param entry buffer entry where the error occurred.
+ *
+ * Frees any pages and buffers associated with the given entry.
+ */
+static void drm_cleanup_buf_error(drm_device_t *dev, drm_buf_entry_t *entry)
+{
+	int i;
+
+	if (entry->seg_count) {
+		for (i = 0; i < entry->seg_count; i++) {
+			if (entry->seglist[i]) {
+				drm_free_pages(entry->seglist[i],
+					        entry->page_order,
+					        DRM_MEM_DMA);
+			}
+		}
+		drm_free(entry->seglist,
+			  entry->seg_count *
+			  sizeof(*entry->seglist),
+			  DRM_MEM_SEGS);
+
+		entry->seg_count = 0;
+	}
+
+   	if (entry->buf_count) {
+	   	for (i = 0; i < entry->buf_count; i++) {
+			if (entry->buflist[i].dev_private) {
+				drm_free(entry->buflist[i].dev_private,
+					  entry->buflist[i].dev_priv_size,
+					  DRM_MEM_BUFS);
+			}
+		}
+		drm_free(entry->buflist,
+			  entry->buf_count *
+			  sizeof(*entry->buflist),
+			  DRM_MEM_BUFS);
+
+		entry->buf_count = 0;
+	}
+}
+
+#if __OS_HAS_AGP
+/**
+ * Add AGP buffers for DMA transfers (ioctl).
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg pointer to a drm_buf_desc_t request.
+ * \return zero on success or a negative number on failure.
+ * 
+ * After some sanity checks creates a drm_buf structure for each buffer and
+ * 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 )
+{
+	drm_file_t *priv = filp->private_data;
+	drm_device_t *dev = priv->dev;
+	drm_device_dma_t *dma = dev->dma;
+	drm_buf_desc_t request;
+	drm_buf_entry_t *entry;
+	drm_buf_t *buf;
+	unsigned long offset;
+	unsigned long agp_offset;
+	int count;
+	int order;
+	int size;
+	int alignment;
+	int page_order;
+	int total;
+	int byte_count;
+	int i;
+	drm_buf_t **temp_buflist;
+	drm_buf_desc_t __user *argp = (void __user *)arg;
+
+	if ( !dma ) return -EINVAL;
+
+	if ( copy_from_user( &request, argp,
+			     sizeof(request) ) )
+		return -EFAULT;
+
+	count = request.count;
+	order = drm_order( request.size );
+	size = 1 << order;
+
+	alignment  = (request.flags & _DRM_PAGE_ALIGN)
+		? PAGE_ALIGN(size) : size;
+	page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0;
+	total = PAGE_SIZE << page_order;
+
+	byte_count = 0;
+	agp_offset = dev->agp->base + request.agp_start;
+
+	DRM_DEBUG( "count:      %d\n",  count );
+	DRM_DEBUG( "order:      %d\n",  order );
+	DRM_DEBUG( "size:       %d\n",  size );
+	DRM_DEBUG( "agp_offset: %lu\n", agp_offset );
+	DRM_DEBUG( "alignment:  %d\n",  alignment );
+	DRM_DEBUG( "page_order: %d\n",  page_order );
+	DRM_DEBUG( "total:      %d\n",  total );
+
+	if ( order < DRM_MIN_ORDER || order > DRM_MAX_ORDER ) return -EINVAL;
+	if ( dev->queue_count ) return -EBUSY; /* Not while in use */
+
+	spin_lock( &dev->count_lock );
+	if ( dev->buf_use ) {
+		spin_unlock( &dev->count_lock );
+		return -EBUSY;
+	}
+	atomic_inc( &dev->buf_alloc );
+	spin_unlock( &dev->count_lock );
+
+	down( &dev->struct_sem );
+	entry = &dma->bufs[order];
+	if ( entry->buf_count ) {
+		up( &dev->struct_sem );
+		atomic_dec( &dev->buf_alloc );
+		return -ENOMEM; /* May only call once for each order */
+	}
+
+	if (count < 0 || count > 4096) {
+		up( &dev->struct_sem );
+		atomic_dec( &dev->buf_alloc );
+		return -EINVAL;
+	}
+
+	entry->buflist = drm_alloc( count * sizeof(*entry->buflist),
+				    DRM_MEM_BUFS );
+	if ( !entry->buflist ) {
+		up( &dev->struct_sem );
+		atomic_dec( &dev->buf_alloc );
+		return -ENOMEM;
+	}
+	memset( entry->buflist, 0, count * sizeof(*entry->buflist) );
+
+	entry->buf_size = size;
+	entry->page_order = page_order;
+
+	offset = 0;
+
+	while ( entry->buf_count < count ) {
+		buf          = &entry->buflist[entry->buf_count];
+		buf->idx     = dma->buf_count + entry->buf_count;
+		buf->total   = alignment;
+		buf->order   = order;
+		buf->used    = 0;
+
+		buf->offset  = (dma->byte_count + offset);
+		buf->bus_address = agp_offset + offset;
+		buf->address = (void *)(agp_offset + offset);
+		buf->next    = NULL;
+		buf->waiting = 0;
+		buf->pending = 0;
+		init_waitqueue_head( &buf->dma_wait );
+		buf->filp    = NULL;
+
+		buf->dev_priv_size = dev->driver->dev_priv_size;
+		buf->dev_private = drm_alloc( buf->dev_priv_size,
+					       DRM_MEM_BUFS );
+		if(!buf->dev_private) {
+			/* Set count correctly so we free the proper amount. */
+			entry->buf_count = count;
+			drm_cleanup_buf_error(dev,entry);
+			up( &dev->struct_sem );
+			atomic_dec( &dev->buf_alloc );
+			return -ENOMEM;
+		}
+		memset( buf->dev_private, 0, buf->dev_priv_size );
+
+		DRM_DEBUG( "buffer %d @ %p\n",
+			   entry->buf_count, buf->address );
+
+		offset += alignment;
+		entry->buf_count++;
+		byte_count += PAGE_SIZE << page_order;
+	}
+
+	DRM_DEBUG( "byte_count: %d\n", byte_count );
+
+	temp_buflist = drm_realloc( dma->buflist,
+				     dma->buf_count * sizeof(*dma->buflist),
+				     (dma->buf_count + entry->buf_count)
+				     * sizeof(*dma->buflist),
+				     DRM_MEM_BUFS );
+	if(!temp_buflist) {
+		/* Free the entry because it isn't valid */
+		drm_cleanup_buf_error(dev,entry);
+		up( &dev->struct_sem );
+		atomic_dec( &dev->buf_alloc );
+		return -ENOMEM;
+	}
+	dma->buflist = temp_buflist;
+
+	for ( i = 0 ; i < entry->buf_count ; i++ ) {
+		dma->buflist[i + dma->buf_count] = &entry->buflist[i];
+	}
+
+	dma->buf_count += entry->buf_count;
+	dma->byte_count += byte_count;
+
+	DRM_DEBUG( "dma->buf_count : %d\n", dma->buf_count );
+	DRM_DEBUG( "entry->buf_count : %d\n", entry->buf_count );
+
+	up( &dev->struct_sem );
+
+	request.count = entry->buf_count;
+	request.size = size;
+
+	if ( copy_to_user( argp, &request, sizeof(request) ) )
+		return -EFAULT;
+
+	dma->flags = _DRM_DMA_USE_AGP;
+
+	atomic_dec( &dev->buf_alloc );
+	return 0;
+}
+#endif /* __OS_HAS_AGP */
+
+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->dev;
+	drm_device_dma_t *dma = dev->dma;
+	drm_buf_desc_t request;
+	int count;
+	int order;
+	int size;
+	int total;
+	int page_order;
+	drm_buf_entry_t *entry;
+	unsigned long page;
+	drm_buf_t *buf;
+	int alignment;
+	unsigned long offset;
+	int i;
+	int byte_count;
+	int page_count;
+	unsigned long *temp_pagelist;
+	drm_buf_t **temp_buflist;
+	drm_buf_desc_t __user *argp = (void __user *)arg;
+
+	if (!drm_core_check_feature(dev, DRIVER_PCI_DMA)) return -EINVAL;
+	if ( !dma ) return -EINVAL;
+
+	if ( copy_from_user( &request, argp, sizeof(request) ) )
+		return -EFAULT;
+
+	count = request.count;
+	order = drm_order( request.size );
+	size = 1 << order;
+
+	DRM_DEBUG( "count=%d, size=%d (%d), order=%d, queue_count=%d\n",
+		   request.count, request.size, size,
+		   order, dev->queue_count );
+
+	if ( order < DRM_MIN_ORDER || order > DRM_MAX_ORDER ) return -EINVAL;
+	if ( dev->queue_count ) return -EBUSY; /* Not while in use */
+
+	alignment = (request.flags & _DRM_PAGE_ALIGN)
+		? PAGE_ALIGN(size) : size;
+	page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0;
+	total = PAGE_SIZE << page_order;
+
+	spin_lock( &dev->count_lock );
+	if ( dev->buf_use ) {
+		spin_unlock( &dev->count_lock );
+		return -EBUSY;
+	}
+	atomic_inc( &dev->buf_alloc );
+	spin_unlock( &dev->count_lock );
+
+	down( &dev->struct_sem );
+	entry = &dma->bufs[order];
+	if ( entry->buf_count ) {
+		up( &dev->struct_sem );
+		atomic_dec( &dev->buf_alloc );
+		return -ENOMEM;	/* May only call once for each order */
+	}
+
+	if (count < 0 || count > 4096) {
+		up( &dev->struct_sem );
+		atomic_dec( &dev->buf_alloc );
+		return -EINVAL;
+	}
+
+	entry->buflist = drm_alloc( count * sizeof(*entry->buflist),
+				    DRM_MEM_BUFS );
+	if ( !entry->buflist ) {
+		up( &dev->struct_sem );
+		atomic_dec( &dev->buf_alloc );
+		return -ENOMEM;
+	}
+	memset( entry->buflist, 0, count * sizeof(*entry->buflist) );
+
+	entry->seglist = drm_alloc( count * sizeof(*entry->seglist),
+				    DRM_MEM_SEGS );
+	if ( !entry->seglist ) {
+		drm_free( entry->buflist,
+			  count * sizeof(*entry->buflist),
+			  DRM_MEM_BUFS );
+		up( &dev->struct_sem );
+		atomic_dec( &dev->buf_alloc );
+		return -ENOMEM;
+	}
+	memset( entry->seglist, 0, count * sizeof(*entry->seglist) );
+
+	/* Keep the original pagelist until we know all the allocations
+	 * have succeeded
+	 */
+	temp_pagelist = drm_alloc( (dma->page_count + (count << page_order))
+				    * sizeof(*dma->pagelist),
+				    DRM_MEM_PAGES );
+	if (!temp_pagelist) {
+		drm_free( entry->buflist,
+			   count * sizeof(*entry->buflist),
+			   DRM_MEM_BUFS );
+		drm_free( entry->seglist,
+			   count * sizeof(*entry->seglist),
+			   DRM_MEM_SEGS );
+		up( &dev->struct_sem );
+		atomic_dec( &dev->buf_alloc );
+		return -ENOMEM;
+	}
+	memcpy(temp_pagelist,
+	       dma->pagelist,
+	       dma->page_count * sizeof(*dma->pagelist));
+	DRM_DEBUG( "pagelist: %d entries\n",
+		   dma->page_count + (count << page_order) );
+
+	entry->buf_size	= size;
+	entry->page_order = page_order;
+	byte_count = 0;
+	page_count = 0;
+
+	while ( entry->buf_count < count ) {
+		page = drm_alloc_pages( page_order, DRM_MEM_DMA );
+		if ( !page ) {
+			/* Set count correctly so we free the proper amount. */
+			entry->buf_count = count;
+			entry->seg_count = count;
+			drm_cleanup_buf_error(dev, entry);
+			drm_free( temp_pagelist,
+				   (dma->page_count + (count << page_order))
+				   * sizeof(*dma->pagelist),
+				   DRM_MEM_PAGES );
+			up( &dev->struct_sem );
+			atomic_dec( &dev->buf_alloc );
+			return -ENOMEM;
+		}
+		entry->seglist[entry->seg_count++] = page;
+		for ( i = 0 ; i < (1 << page_order) ; i++ ) {
+			DRM_DEBUG( "page %d @ 0x%08lx\n",
+				   dma->page_count + page_count,
+				   page + PAGE_SIZE * i );
+			temp_pagelist[dma->page_count + page_count++]
+				= page + PAGE_SIZE * i;
+		}
+		for ( offset = 0 ;
+		      offset + size <= total && entry->buf_count < count ;
+		      offset += alignment, ++entry->buf_count ) {
+			buf	     = &entry->buflist[entry->buf_count];
+			buf->idx     = dma->buf_count + entry->buf_count;
+			buf->total   = alignment;
+			buf->order   = order;
+			buf->used    = 0;
+			buf->offset  = (dma->byte_count + byte_count + offset);
+			buf->address = (void *)(page + offset);
+			buf->next    = NULL;
+			buf->waiting = 0;
+			buf->pending = 0;
+			init_waitqueue_head( &buf->dma_wait );
+			buf->filp    = NULL;
+
+			buf->dev_priv_size = dev->driver->dev_priv_size;
+			buf->dev_private = drm_alloc( buf->dev_priv_size,
+						       DRM_MEM_BUFS );
+			if(!buf->dev_private) {
+				/* Set count correctly so we free the proper amount. */
+				entry->buf_count = count;
+				entry->seg_count = count;
+				drm_cleanup_buf_error(dev,entry);
+				drm_free( temp_pagelist,
+					   (dma->page_count + (count << page_order))
+					   * sizeof(*dma->pagelist),
+					   DRM_MEM_PAGES );
+				up( &dev->struct_sem );
+				atomic_dec( &dev->buf_alloc );
+				return -ENOMEM;
+			}
+			memset( buf->dev_private, 0, buf->dev_priv_size );
+
+			DRM_DEBUG( "buffer %d @ %p\n",
+				   entry->buf_count, buf->address );
+		}
+		byte_count += PAGE_SIZE << page_order;
+	}
+
+	temp_buflist = drm_realloc( dma->buflist,
+				     dma->buf_count * sizeof(*dma->buflist),
+				     (dma->buf_count + entry->buf_count)
+				     * sizeof(*dma->buflist),
+				     DRM_MEM_BUFS );
+	if (!temp_buflist) {
+		/* Free the entry because it isn't valid */
+		drm_cleanup_buf_error(dev,entry);
+		drm_free( temp_pagelist,
+			   (dma->page_count + (count << page_order))
+			   * sizeof(*dma->pagelist),
+			   DRM_MEM_PAGES );
+		up( &dev->struct_sem );
+		atomic_dec( &dev->buf_alloc );
+		return -ENOMEM;
+	}
+	dma->buflist = temp_buflist;
+
+	for ( i = 0 ; i < entry->buf_count ; i++ ) {
+		dma->buflist[i + dma->buf_count] = &entry->buflist[i];
+	}
+
+	/* No allocations failed, so now we can replace the orginal pagelist
+	 * with the new one.
+	 */
+	if (dma->page_count) {
+		drm_free(dma->pagelist,
+			  dma->page_count * sizeof(*dma->pagelist),
+			  DRM_MEM_PAGES);
+	}
+	dma->pagelist = temp_pagelist;
+
+	dma->buf_count += entry->buf_count;
+	dma->seg_count += entry->seg_count;
+	dma->page_count += entry->seg_count << page_order;
+	dma->byte_count += PAGE_SIZE * (entry->seg_count << page_order);
+
+	up( &dev->struct_sem );
+
+	request.count = entry->buf_count;
+	request.size = size;
+
+	if ( copy_to_user( argp, &request, sizeof(request) ) )
+		return -EFAULT;
+
+	atomic_dec( &dev->buf_alloc );
+	return 0;
+
+}
+
+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->dev;
+	drm_device_dma_t *dma = dev->dma;
+	drm_buf_desc_t __user *argp = (void __user *)arg;
+	drm_buf_desc_t request;
+	drm_buf_entry_t *entry;
+	drm_buf_t *buf;
+	unsigned long offset;
+	unsigned long agp_offset;
+	int count;
+	int order;
+	int size;
+	int alignment;
+	int page_order;
+	int total;
+	int byte_count;
+	int i;
+	drm_buf_t **temp_buflist;
+
+	if (!drm_core_check_feature(dev, DRIVER_SG)) return -EINVAL;
+	
+	if ( !dma ) return -EINVAL;
+
+	if ( copy_from_user( &request, argp, sizeof(request) ) )
+		return -EFAULT;
+
+	count = request.count;
+	order = drm_order( request.size );
+	size = 1 << order;
+
+	alignment  = (request.flags & _DRM_PAGE_ALIGN)
+			? PAGE_ALIGN(size) : size;
+	page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0;
+	total = PAGE_SIZE << page_order;
+
+	byte_count = 0;
+	agp_offset = request.agp_start;
+
+	DRM_DEBUG( "count:      %d\n",  count );
+	DRM_DEBUG( "order:      %d\n",  order );
+	DRM_DEBUG( "size:       %d\n",  size );
+	DRM_DEBUG( "agp_offset: %lu\n", agp_offset );
+	DRM_DEBUG( "alignment:  %d\n",  alignment );
+	DRM_DEBUG( "page_order: %d\n",  page_order );
+	DRM_DEBUG( "total:      %d\n",  total );
+
+	if ( order < DRM_MIN_ORDER || order > DRM_MAX_ORDER ) return -EINVAL;
+	if ( dev->queue_count ) return -EBUSY; /* Not while in use */
+
+	spin_lock( &dev->count_lock );
+	if ( dev->buf_use ) {
+		spin_unlock( &dev->count_lock );
+		return -EBUSY;
+	}
+	atomic_inc( &dev->buf_alloc );
+	spin_unlock( &dev->count_lock );
+
+	down( &dev->struct_sem );
+	entry = &dma->bufs[order];
+	if ( entry->buf_count ) {
+		up( &dev->struct_sem );
+		atomic_dec( &dev->buf_alloc );
+		return -ENOMEM; /* May only call once for each order */
+	}
+
+	if (count < 0 || count > 4096) {
+		up( &dev->struct_sem );
+		atomic_dec( &dev->buf_alloc );
+		return -EINVAL;
+	}
+
+	entry->buflist = drm_alloc( count * sizeof(*entry->buflist),
+				     DRM_MEM_BUFS );
+	if ( !entry->buflist ) {
+		up( &dev->struct_sem );
+		atomic_dec( &dev->buf_alloc );
+		return -ENOMEM;
+	}
+	memset( entry->buflist, 0, count * sizeof(*entry->buflist) );
+
+	entry->buf_size = size;
+	entry->page_order = page_order;
+
+	offset = 0;
+
+	while ( entry->buf_count < count ) {
+		buf          = &entry->buflist[entry->buf_count];
+		buf->idx     = dma->buf_count + entry->buf_count;
+		buf->total   = alignment;
+		buf->order   = order;
+		buf->used    = 0;
+
+		buf->offset  = (dma->byte_count + offset);
+		buf->bus_address = agp_offset + offset;
+		buf->address = (void *)(agp_offset + offset + dev->sg->handle);
+		buf->next    = NULL;
+		buf->waiting = 0;
+		buf->pending = 0;
+		init_waitqueue_head( &buf->dma_wait );
+		buf->filp    = NULL;
+
+		buf->dev_priv_size = dev->driver->dev_priv_size;
+		buf->dev_private = drm_alloc( buf->dev_priv_size,
+					       DRM_MEM_BUFS );
+		if(!buf->dev_private) {
+			/* Set count correctly so we free the proper amount. */
+			entry->buf_count = count;
+			drm_cleanup_buf_error(dev,entry);
+			up( &dev->struct_sem );
+			atomic_dec( &dev->buf_alloc );
+			return -ENOMEM;
+		}
+
+		memset( buf->dev_private, 0, buf->dev_priv_size );
+
+		DRM_DEBUG( "buffer %d @ %p\n",
+			   entry->buf_count, buf->address );
+
+		offset += alignment;
+		entry->buf_count++;
+		byte_count += PAGE_SIZE << page_order;
+	}
+
+	DRM_DEBUG( "byte_count: %d\n", byte_count );
+
+	temp_buflist = drm_realloc( dma->buflist,
+				     dma->buf_count * sizeof(*dma->buflist),
+				     (dma->buf_count + entry->buf_count)
+				     * sizeof(*dma->buflist),
+				     DRM_MEM_BUFS );
+	if(!temp_buflist) {
+		/* Free the entry because it isn't valid */
+		drm_cleanup_buf_error(dev,entry);
+		up( &dev->struct_sem );
+		atomic_dec( &dev->buf_alloc );
+		return -ENOMEM;
+	}
+	dma->buflist = temp_buflist;
+
+	for ( i = 0 ; i < entry->buf_count ; i++ ) {
+		dma->buflist[i + dma->buf_count] = &entry->buflist[i];
+	}
+
+	dma->buf_count += entry->buf_count;
+	dma->byte_count += byte_count;
+
+	DRM_DEBUG( "dma->buf_count : %d\n", dma->buf_count );
+	DRM_DEBUG( "entry->buf_count : %d\n", entry->buf_count );
+
+	up( &dev->struct_sem );
+
+	request.count = entry->buf_count;
+	request.size = size;
+
+	if ( copy_to_user( argp, &request, sizeof(request) ) )
+		return -EFAULT;
+
+	dma->flags = _DRM_DMA_USE_SG;
+
+	atomic_dec( &dev->buf_alloc );
+	return 0;
+}
+
+/**
+ * Add buffers for DMA transfers (ioctl).
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg pointer to a drm_buf_desc_t request.
+ * \return zero on success or a negative number on failure.
+ *
+ * According with the memory type specified in drm_buf_desc::flags and the
+ * build options, it dispatches the call either to addbufs_agp(),
+ * addbufs_sg() or addbufs_pci() for AGP, scatter-gather or consistent
+ * PCI memory respectively.
+ */
+int drm_addbufs( struct inode *inode, struct file *filp,
+		  unsigned int cmd, unsigned long arg )
+{
+	drm_buf_desc_t request;
+	drm_file_t *priv = filp->private_data;
+	drm_device_t *dev = priv->dev;
+	
+	if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA))
+		return -EINVAL;
+
+	if ( copy_from_user( &request, (drm_buf_desc_t __user *)arg,
+			     sizeof(request) ) )
+		return -EFAULT;
+
+#if __OS_HAS_AGP
+	if ( request.flags & _DRM_AGP_BUFFER )
+		return drm_addbufs_agp( inode, filp, cmd, arg );
+	else
+#endif
+	if ( request.flags & _DRM_SG_BUFFER )
+		return drm_addbufs_sg( inode, filp, cmd, arg );
+	else
+		return drm_addbufs_pci( inode, filp, cmd, arg );
+}
+
+
+/**
+ * Get information about the buffer mappings.
+ *
+ * This was originally mean for debugging purposes, or by a sophisticated
+ * client library to determine how best to use the available buffers (e.g.,
+ * large buffers can be used for image transfer).
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg pointer to a drm_buf_info structure.
+ * \return zero on success or a negative number on failure.
+ *
+ * Increments drm_device::buf_use while holding the drm_device::count_lock
+ * lock, preventing of allocating more buffers after this call. Information
+ * about each requested buffer is then copied into user space.
+ */
+int drm_infobufs( struct inode *inode, struct file *filp,
+		   unsigned int cmd, unsigned long arg )
+{
+	drm_file_t *priv = filp->private_data;
+	drm_device_t *dev = priv->dev;
+	drm_device_dma_t *dma = dev->dma;
+	drm_buf_info_t request;
+	drm_buf_info_t __user *argp = (void __user *)arg;
+	int i;
+	int count;
+
+	if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA))
+		return -EINVAL;
+
+	if ( !dma ) return -EINVAL;
+
+	spin_lock( &dev->count_lock );
+	if ( atomic_read( &dev->buf_alloc ) ) {
+		spin_unlock( &dev->count_lock );
+		return -EBUSY;
+	}
+	++dev->buf_use;		/* Can't allocate more after this call */
+	spin_unlock( &dev->count_lock );
+
+	if ( copy_from_user( &request, argp, sizeof(request) ) )
+		return -EFAULT;
+
+	for ( i = 0, count = 0 ; i < DRM_MAX_ORDER + 1 ; i++ ) {
+		if ( dma->bufs[i].buf_count ) ++count;
+	}
+
+	DRM_DEBUG( "count = %d\n", count );
+
+	if ( request.count >= count ) {
+		for ( i = 0, count = 0 ; i < DRM_MAX_ORDER + 1 ; i++ ) {
+			if ( dma->bufs[i].buf_count ) {
+				drm_buf_desc_t __user *to = &request.list[count];
+				drm_buf_entry_t *from = &dma->bufs[i];
+				drm_freelist_t *list = &dma->bufs[i].freelist;
+				if ( copy_to_user( &to->count,
+						   &from->buf_count,
+						   sizeof(from->buf_count) ) ||
+				     copy_to_user( &to->size,
+						   &from->buf_size,
+						   sizeof(from->buf_size) ) ||
+				     copy_to_user( &to->low_mark,
+						   &list->low_mark,
+						   sizeof(list->low_mark) ) ||
+				     copy_to_user( &to->high_mark,
+						   &list->high_mark,
+						   sizeof(list->high_mark) ) )
+					return -EFAULT;
+
+				DRM_DEBUG( "%d %d %d %d %d\n",
+					   i,
+					   dma->bufs[i].buf_count,
+					   dma->bufs[i].buf_size,
+					   dma->bufs[i].freelist.low_mark,
+					   dma->bufs[i].freelist.high_mark );
+				++count;
+			}
+		}
+	}
+	request.count = count;
+
+	if ( copy_to_user( argp, &request, sizeof(request) ) )
+		return -EFAULT;
+
+	return 0;
+}
+
+/**
+ * Specifies a low and high water mark for buffer allocation
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg a pointer to a drm_buf_desc structure.
+ * \return zero on success or a negative number on failure.
+ *
+ * Verifies that the size order is bounded between the admissible orders and
+ * updates the respective drm_device_dma::bufs entry low and high water mark.
+ *
+ * \note This ioctl is deprecated and mostly never used.
+ */
+int drm_markbufs( struct inode *inode, struct file *filp,
+		   unsigned int cmd, unsigned long arg )
+{
+	drm_file_t *priv = filp->private_data;
+	drm_device_t *dev = priv->dev;
+	drm_device_dma_t *dma = dev->dma;
+	drm_buf_desc_t request;
+	int order;
+	drm_buf_entry_t *entry;
+
+	if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA))
+		return -EINVAL;
+
+	if ( !dma ) return -EINVAL;
+
+	if ( copy_from_user( &request,
+			     (drm_buf_desc_t __user *)arg,
+			     sizeof(request) ) )
+		return -EFAULT;
+
+	DRM_DEBUG( "%d, %d, %d\n",
+		   request.size, request.low_mark, request.high_mark );
+	order = drm_order( request.size );
+	if ( order < DRM_MIN_ORDER || order > DRM_MAX_ORDER ) return -EINVAL;
+	entry = &dma->bufs[order];
+
+	if ( request.low_mark < 0 || request.low_mark > entry->buf_count )
+		return -EINVAL;
+	if ( request.high_mark < 0 || request.high_mark > entry->buf_count )
+		return -EINVAL;
+
+	entry->freelist.low_mark  = request.low_mark;
+	entry->freelist.high_mark = request.high_mark;
+
+	return 0;
+}
+
+/**
+ * Unreserve the buffers in list, previously reserved using drmDMA. 
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg pointer to a drm_buf_free structure.
+ * \return zero on success or a negative number on failure.
+ * 
+ * Calls free_buffer() for each used buffer.
+ * This function is primarily used for debugging.
+ */
+int drm_freebufs( struct inode *inode, struct file *filp,
+		   unsigned int cmd, unsigned long arg )
+{
+	drm_file_t *priv = filp->private_data;
+	drm_device_t *dev = priv->dev;
+	drm_device_dma_t *dma = dev->dma;
+	drm_buf_free_t request;
+	int i;
+	int idx;
+	drm_buf_t *buf;
+
+	if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA))
+		return -EINVAL;
+
+	if ( !dma ) return -EINVAL;
+
+	if ( copy_from_user( &request,
+			     (drm_buf_free_t __user *)arg,
+			     sizeof(request) ) )
+		return -EFAULT;
+
+	DRM_DEBUG( "%d\n", request.count );
+	for ( i = 0 ; i < request.count ; i++ ) {
+		if ( copy_from_user( &idx,
+				     &request.list[i],
+				     sizeof(idx) ) )
+			return -EFAULT;
+		if ( idx < 0 || idx >= dma->buf_count ) {
+			DRM_ERROR( "Index %d (of %d max)\n",
+				   idx, dma->buf_count - 1 );
+			return -EINVAL;
+		}
+		buf = dma->buflist[idx];
+		if ( buf->filp != filp ) {
+			DRM_ERROR( "Process %d freeing buffer not owned\n",
+				   current->pid );
+			return -EINVAL;
+		}
+		drm_free_buffer( dev, buf );
+	}
+
+	return 0;
+}
+
+/**
+ * Maps all of the DMA buffers into client-virtual space (ioctl).
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg pointer to a drm_buf_map structure.
+ * \return zero on success or a negative number on failure.
+ *
+ * Maps the AGP or SG buffer region with do_mmap(), and copies information
+ * about each buffer into user space. The PCI buffers are already mapped on the
+ * addbufs_pci() call.
+ */
+int drm_mapbufs( struct inode *inode, struct file *filp,
+		  unsigned int cmd, unsigned long arg )
+{
+	drm_file_t *priv = filp->private_data;
+	drm_device_t *dev = priv->dev;
+	drm_device_dma_t *dma = dev->dma;
+	drm_buf_map_t __user *argp = (void __user *)arg;
+	int retcode = 0;
+	const int zero = 0;
+	unsigned long virtual;
+	unsigned long address;
+	drm_buf_map_t request;
+	int i;
+
+	if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA))
+		return -EINVAL;
+
+	if ( !dma ) return -EINVAL;
+
+	spin_lock( &dev->count_lock );
+	if ( atomic_read( &dev->buf_alloc ) ) {
+		spin_unlock( &dev->count_lock );
+		return -EBUSY;
+	}
+	dev->buf_use++;		/* Can't allocate more after this call */
+	spin_unlock( &dev->count_lock );
+
+	if ( copy_from_user( &request, argp, sizeof(request) ) )
+		return -EFAULT;
+
+	if ( request.count >= dma->buf_count ) {
+		if ((drm_core_has_AGP(dev) && (dma->flags & _DRM_DMA_USE_AGP)) ||
+		    (drm_core_check_feature(dev, DRIVER_SG) && (dma->flags & _DRM_DMA_USE_SG)) ) {
+			drm_map_t *map = dev->agp_buffer_map;
+
+			if ( !map ) {
+				retcode = -EINVAL;
+				goto done;
+			}
+
+#if LINUX_VERSION_CODE <= 0x020402
+			down( &current->mm->mmap_sem );
+#else
+			down_write( &current->mm->mmap_sem );
+#endif
+			virtual = do_mmap( filp, 0, map->size,
+					   PROT_READ | PROT_WRITE,
+					   MAP_SHARED,
+					   (unsigned long)map->offset );
+#if LINUX_VERSION_CODE <= 0x020402
+			up( &current->mm->mmap_sem );
+#else
+			up_write( &current->mm->mmap_sem );
+#endif
+		} else {
+#if LINUX_VERSION_CODE <= 0x020402
+			down( &current->mm->mmap_sem );
+#else
+			down_write( &current->mm->mmap_sem );
+#endif
+			virtual = do_mmap( filp, 0, dma->byte_count,
+					   PROT_READ | PROT_WRITE,
+					   MAP_SHARED, 0 );
+#if LINUX_VERSION_CODE <= 0x020402
+			up( &current->mm->mmap_sem );
+#else
+			up_write( &current->mm->mmap_sem );
+#endif
+		}
+		if ( virtual > -1024UL ) {
+			/* Real error */
+			retcode = (signed long)virtual;
+			goto done;
+		}
+		request.virtual = (void __user *)virtual;
+
+		for ( i = 0 ; i < dma->buf_count ; i++ ) {
+			if ( copy_to_user( &request.list[i].idx,
+					   &dma->buflist[i]->idx,
+					   sizeof(request.list[0].idx) ) ) {
+				retcode = -EFAULT;
+				goto done;
+			}
+			if ( copy_to_user( &request.list[i].total,
+					   &dma->buflist[i]->total,
+					   sizeof(request.list[0].total) ) ) {
+				retcode = -EFAULT;
+				goto done;
+			}
+			if ( copy_to_user( &request.list[i].used,
+					   &zero,
+					   sizeof(zero) ) ) {
+				retcode = -EFAULT;
+				goto done;
+			}
+			address = virtual + dma->buflist[i]->offset; /* *** */
+			if ( copy_to_user( &request.list[i].address,
+					   &address,
+					   sizeof(address) ) ) {
+				retcode = -EFAULT;
+				goto done;
+			}
+		}
+	}
+ done:
+	request.count = dma->buf_count;
+	DRM_DEBUG( "%d buffers, retcode = %d\n", request.count, retcode );
+
+	if ( copy_to_user( argp, &request, sizeof(request) ) )
+		return -EFAULT;
+
+	return retcode;
+}
+
diff -Nru a/drivers/char/drm/drm_bufs.h b/drivers/char/drm/drm_bufs.h
--- a/drivers/char/drm/drm_bufs.h	2005-03-01 23:38:53 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,1269 +0,0 @@
-/**
- * \file drm_bufs.h 
- * Generic buffer template
- * 
- * \author Rickard E. (Rik) Faith <faith@valinux.com>
- * \author Gareth Hughes <gareth@valinux.com>
- */
-
-/*
- * Created: Thu Nov 23 03:10:50 2000 by gareth@valinux.com
- *
- * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include <linux/vmalloc.h>
-#include "drmP.h"
-
-/**
- * Compute size order.  Returns the exponent of the smaller power of two which
- * is greater or equal to given number.
- * 
- * \param size size.
- * \return order.
- *
- * \todo Can be made faster.
- */
-int DRM(order)( unsigned long size )
-{
-	int order;
-	unsigned long tmp;
-
-	for (order = 0, tmp = size >> 1; tmp; tmp >>= 1, order++)
-		;
-
-	if (size & (size - 1))
-		++order;
-
-	return order;
-}
-
-/**
- * Ioctl to specify a range of memory that is available for mapping by a non-root process.
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg pointer to a drm_map structure.
- * \return zero on success or a negative value on error.
- *
- * Adjusts the memory offset to its absolute value according to the mapping
- * type.  Adds the map to the map list drm_device::maplist. Adds MTRR's where
- * applicable and if supported by the kernel.
- */
-int DRM(addmap)( struct inode *inode, struct file *filp,
-		 unsigned int cmd, unsigned long arg )
-{
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
-	drm_map_t *map;
-	drm_map_t __user *argp = (void __user *)arg;
-	drm_map_list_t *list;
-
-	if ( !(filp->f_mode & 3) ) return -EACCES; /* Require read/write */
-
-	map = DRM(alloc)( sizeof(*map), DRM_MEM_MAPS );
-	if ( !map )
-		return -ENOMEM;
-
-	if ( copy_from_user( map, argp, sizeof(*map) ) ) {
-		DRM(free)( map, sizeof(*map), DRM_MEM_MAPS );
-		return -EFAULT;
-	}
-
-	/* Only allow shared memory to be removable since we only keep enough
-	 * book keeping information about shared memory to allow for removal
-	 * when processes fork.
-	 */
-	if ( (map->flags & _DRM_REMOVABLE) && map->type != _DRM_SHM ) {
-		DRM(free)( map, sizeof(*map), DRM_MEM_MAPS );
-		return -EINVAL;
-	}
-	DRM_DEBUG( "offset = 0x%08lx, size = 0x%08lx, type = %d\n",
-		   map->offset, map->size, map->type );
-	if ( (map->offset & (~PAGE_MASK)) || (map->size & (~PAGE_MASK)) ) {
-		DRM(free)( map, sizeof(*map), DRM_MEM_MAPS );
-		return -EINVAL;
-	}
-	map->mtrr   = -1;
-	map->handle = NULL;
-
-	switch ( map->type ) {
-	case _DRM_REGISTERS:
-	case _DRM_FRAME_BUFFER:
-#if !defined(__sparc__) && !defined(__alpha__) && !defined(__ia64__)
-		if ( map->offset + map->size < map->offset ||
-		     map->offset < virt_to_phys(high_memory) ) {
-			DRM(free)( map, sizeof(*map), DRM_MEM_MAPS );
-			return -EINVAL;
-		}
-#endif
-#ifdef __alpha__
-		map->offset += dev->hose->mem_space->start;
-#endif
-		if (drm_core_has_MTRR(dev)) {
-			if ( map->type == _DRM_FRAME_BUFFER ||
-			     (map->flags & _DRM_WRITE_COMBINING) ) {
-				map->mtrr = mtrr_add( map->offset, map->size,
-						      MTRR_TYPE_WRCOMB, 1 );
-			}
-		}
-		if (map->type == _DRM_REGISTERS)
-			map->handle = DRM(ioremap)( map->offset, map->size,
-						    dev );
-		break;
-
-	case _DRM_SHM:
-		map->handle = vmalloc_32(map->size);
-		DRM_DEBUG( "%lu %d %p\n",
-			   map->size, DRM(order)( map->size ), map->handle );
-		if ( !map->handle ) {
-			DRM(free)( map, sizeof(*map), DRM_MEM_MAPS );
-			return -ENOMEM;
-		}
-		map->offset = (unsigned long)map->handle;
-		if ( map->flags & _DRM_CONTAINS_LOCK ) {
-			/* Prevent a 2nd X Server from creating a 2nd lock */
-			if (dev->lock.hw_lock != NULL) {
-				vfree( map->handle );
-				DRM(free)( map, sizeof(*map), DRM_MEM_MAPS );
-				return -EBUSY;
-			}
-			dev->sigdata.lock =
-			dev->lock.hw_lock = map->handle; /* Pointer to lock */
-		}
-		break;
-	case _DRM_AGP:
-		if (drm_core_has_AGP(dev)) {
-#ifdef __alpha__
-			map->offset += dev->hose->mem_space->start;
-#endif
-			map->offset += dev->agp->base;
-			map->mtrr   = dev->agp->agp_mtrr; /* for getmap */
-		}
-		break;
-	case _DRM_SCATTER_GATHER:
-		if (!dev->sg) {
-			DRM(free)(map, sizeof(*map), DRM_MEM_MAPS);
-			return -EINVAL;
-		}
-		map->offset += dev->sg->handle;
-		break;
-
-	default:
-		DRM(free)( map, sizeof(*map), DRM_MEM_MAPS );
-		return -EINVAL;
-	}
-
-	list = DRM(alloc)(sizeof(*list), DRM_MEM_MAPS);
-	if(!list) {
-		DRM(free)(map, sizeof(*map), DRM_MEM_MAPS);
-		return -EINVAL;
-	}
-	memset(list, 0, sizeof(*list));
-	list->map = map;
-
-	down(&dev->struct_sem);
-	list_add(&list->head, &dev->maplist->head);
- 	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;
-	}
-	return 0;
-}
-
-
-/**
- * Remove a map private from list and deallocate resources if the mapping
- * isn't in use.
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg pointer to a drm_map_t structure.
- * \return zero on success or a negative value on error.
- *
- * Searches the map on drm_device::maplist, removes it from the list, see if
- * its being used, and free any associate resource (such as MTRR's) if it's not
- * being on use.
- *
- * \sa addmap().
- */
-int DRM(rmmap)(struct inode *inode, struct file *filp,
-	       unsigned int cmd, unsigned long arg)
-{
-	drm_file_t	*priv	= filp->private_data;
-	drm_device_t	*dev	= priv->dev;
-	struct list_head *list;
-	drm_map_list_t *r_list = NULL;
-	drm_vma_entry_t *pt, *prev;
-	drm_map_t *map;
-	drm_map_t request;
-	int found_maps = 0;
-
-	if (copy_from_user(&request, (drm_map_t __user *)arg,
-			   sizeof(request))) {
-		return -EFAULT;
-	}
-
-	down(&dev->struct_sem);
-	list = &dev->maplist->head;
-	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 &&
-		   r_list->map->flags & _DRM_REMOVABLE) break;
-	}
-
-	/* List has wrapped around to the head pointer, or its empty we didn't
-	 * find anything.
-	 */
-	if(list == (&dev->maplist->head)) {
-		up(&dev->struct_sem);
-		return -EINVAL;
-	}
-	map = r_list->map;
-	list_del(list);
-	DRM(free)(list, sizeof(*list), DRM_MEM_MAPS);
-
-	for (pt = dev->vmalist, prev = NULL; pt; prev = pt, pt = pt->next) {
-		if (pt->vma->vm_private_data == map) found_maps++;
-	}
-
-	if(!found_maps) {
-		switch (map->type) {
-		case _DRM_REGISTERS:
-		case _DRM_FRAME_BUFFER:
-		  if (drm_core_has_MTRR(dev)) {
-				if (map->mtrr >= 0) {
-					int retcode;
-					retcode = mtrr_del(map->mtrr,
-							   map->offset,
-							   map->size);
-					DRM_DEBUG("mtrr_del = %d\n", retcode);
-				}
-			}
-			DRM(ioremapfree)(map->handle, map->size, dev);
-			break;
-		case _DRM_SHM:
-			vfree(map->handle);
-			break;
-		case _DRM_AGP:
-		case _DRM_SCATTER_GATHER:
-			break;
-		}
-		DRM(free)(map, sizeof(*map), DRM_MEM_MAPS);
-	}
-	up(&dev->struct_sem);
-	return 0;
-}
-
-/**
- * Cleanup after an error on one of the addbufs() functions.
- *
- * \param entry buffer entry where the error occurred.
- *
- * Frees any pages and buffers associated with the given entry.
- */
-static void DRM(cleanup_buf_error)(drm_buf_entry_t *entry)
-{
-	int i;
-
-	if (entry->seg_count) {
-		for (i = 0; i < entry->seg_count; i++) {
-			if (entry->seglist[i]) {
-				DRM(free_pages)(entry->seglist[i],
-					        entry->page_order,
-					        DRM_MEM_DMA);
-			}
-		}
-		DRM(free)(entry->seglist,
-			  entry->seg_count *
-			  sizeof(*entry->seglist),
-			  DRM_MEM_SEGS);
-
-		entry->seg_count = 0;
-	}
-
-   	if (entry->buf_count) {
-	   	for (i = 0; i < entry->buf_count; i++) {
-			if (entry->buflist[i].dev_private) {
-				DRM(free)(entry->buflist[i].dev_private,
-					  entry->buflist[i].dev_priv_size,
-					  DRM_MEM_BUFS);
-			}
-		}
-		DRM(free)(entry->buflist,
-			  entry->buf_count *
-			  sizeof(*entry->buflist),
-			  DRM_MEM_BUFS);
-
-		entry->buf_count = 0;
-	}
-}
-
-#if __OS_HAS_AGP
-/**
- * Add AGP buffers for DMA transfers (ioctl).
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg pointer to a drm_buf_desc_t request.
- * \return zero on success or a negative number on failure.
- * 
- * After some sanity checks creates a drm_buf structure for each buffer and
- * 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 )
-{
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
-	drm_device_dma_t *dma = dev->dma;
-	drm_buf_desc_t request;
-	drm_buf_entry_t *entry;
-	drm_buf_t *buf;
-	unsigned long offset;
-	unsigned long agp_offset;
-	int count;
-	int order;
-	int size;
-	int alignment;
-	int page_order;
-	int total;
-	int byte_count;
-	int i;
-	drm_buf_t **temp_buflist;
-	drm_buf_desc_t __user *argp = (void __user *)arg;
-
-	if ( !dma ) return -EINVAL;
-
-	if ( copy_from_user( &request, argp,
-			     sizeof(request) ) )
-		return -EFAULT;
-
-	count = request.count;
-	order = DRM(order)( request.size );
-	size = 1 << order;
-
-	alignment  = (request.flags & _DRM_PAGE_ALIGN)
-		? PAGE_ALIGN(size) : size;
-	page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0;
-	total = PAGE_SIZE << page_order;
-
-	byte_count = 0;
-	agp_offset = dev->agp->base + request.agp_start;
-
-	DRM_DEBUG( "count:      %d\n",  count );
-	DRM_DEBUG( "order:      %d\n",  order );
-	DRM_DEBUG( "size:       %d\n",  size );
-	DRM_DEBUG( "agp_offset: %lu\n", agp_offset );
-	DRM_DEBUG( "alignment:  %d\n",  alignment );
-	DRM_DEBUG( "page_order: %d\n",  page_order );
-	DRM_DEBUG( "total:      %d\n",  total );
-
-	if ( order < DRM_MIN_ORDER || order > DRM_MAX_ORDER ) return -EINVAL;
-	if ( dev->queue_count ) return -EBUSY; /* Not while in use */
-
-	spin_lock( &dev->count_lock );
-	if ( dev->buf_use ) {
-		spin_unlock( &dev->count_lock );
-		return -EBUSY;
-	}
-	atomic_inc( &dev->buf_alloc );
-	spin_unlock( &dev->count_lock );
-
-	down( &dev->struct_sem );
-	entry = &dma->bufs[order];
-	if ( entry->buf_count ) {
-		up( &dev->struct_sem );
-		atomic_dec( &dev->buf_alloc );
-		return -ENOMEM; /* May only call once for each order */
-	}
-
-	if (count < 0 || count > 4096) {
-		up( &dev->struct_sem );
-		atomic_dec( &dev->buf_alloc );
-		return -EINVAL;
-	}
-
-	entry->buflist = DRM(alloc)( count * sizeof(*entry->buflist),
-				    DRM_MEM_BUFS );
-	if ( !entry->buflist ) {
-		up( &dev->struct_sem );
-		atomic_dec( &dev->buf_alloc );
-		return -ENOMEM;
-	}
-	memset( entry->buflist, 0, count * sizeof(*entry->buflist) );
-
-	entry->buf_size = size;
-	entry->page_order = page_order;
-
-	offset = 0;
-
-	while ( entry->buf_count < count ) {
-		buf          = &entry->buflist[entry->buf_count];
-		buf->idx     = dma->buf_count + entry->buf_count;
-		buf->total   = alignment;
-		buf->order   = order;
-		buf->used    = 0;
-
-		buf->offset  = (dma->byte_count + offset);
-		buf->bus_address = agp_offset + offset;
-		buf->address = (void *)(agp_offset + offset);
-		buf->next    = NULL;
-		buf->waiting = 0;
-		buf->pending = 0;
-		init_waitqueue_head( &buf->dma_wait );
-		buf->filp    = NULL;
-
-		buf->dev_priv_size = dev->dev_priv_size;
-		buf->dev_private = DRM(alloc)( buf->dev_priv_size,
-					       DRM_MEM_BUFS );
-		if(!buf->dev_private) {
-			/* Set count correctly so we free the proper amount. */
-			entry->buf_count = count;
-			DRM(cleanup_buf_error)(entry);
-			up( &dev->struct_sem );
-			atomic_dec( &dev->buf_alloc );
-			return -ENOMEM;
-		}
-		memset( buf->dev_private, 0, buf->dev_priv_size );
-
-		DRM_DEBUG( "buffer %d @ %p\n",
-			   entry->buf_count, buf->address );
-
-		offset += alignment;
-		entry->buf_count++;
-		byte_count += PAGE_SIZE << page_order;
-	}
-
-	DRM_DEBUG( "byte_count: %d\n", byte_count );
-
-	temp_buflist = DRM(realloc)( dma->buflist,
-				     dma->buf_count * sizeof(*dma->buflist),
-				     (dma->buf_count + entry->buf_count)
-				     * sizeof(*dma->buflist),
-				     DRM_MEM_BUFS );
-	if(!temp_buflist) {
-		/* Free the entry because it isn't valid */
-		DRM(cleanup_buf_error)(entry);
-		up( &dev->struct_sem );
-		atomic_dec( &dev->buf_alloc );
-		return -ENOMEM;
-	}
-	dma->buflist = temp_buflist;
-
-	for ( i = 0 ; i < entry->buf_count ; i++ ) {
-		dma->buflist[i + dma->buf_count] = &entry->buflist[i];
-	}
-
-	dma->buf_count += entry->buf_count;
-	dma->byte_count += byte_count;
-
-	DRM_DEBUG( "dma->buf_count : %d\n", dma->buf_count );
-	DRM_DEBUG( "entry->buf_count : %d\n", entry->buf_count );
-
-	up( &dev->struct_sem );
-
-	request.count = entry->buf_count;
-	request.size = size;
-
-	if ( copy_to_user( argp, &request, sizeof(request) ) )
-		return -EFAULT;
-
-	dma->flags = _DRM_DMA_USE_AGP;
-
-	atomic_dec( &dev->buf_alloc );
-	return 0;
-}
-#endif /* __OS_HAS_AGP */
-
-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->dev;
-	drm_device_dma_t *dma = dev->dma;
-	drm_buf_desc_t request;
-	int count;
-	int order;
-	int size;
-	int total;
-	int page_order;
-	drm_buf_entry_t *entry;
-	unsigned long page;
-	drm_buf_t *buf;
-	int alignment;
-	unsigned long offset;
-	int i;
-	int byte_count;
-	int page_count;
-	unsigned long *temp_pagelist;
-	drm_buf_t **temp_buflist;
-	drm_buf_desc_t __user *argp = (void __user *)arg;
-
-	if (!drm_core_check_feature(dev, DRIVER_PCI_DMA)) return -EINVAL;
-	if ( !dma ) return -EINVAL;
-
-	if ( copy_from_user( &request, argp, sizeof(request) ) )
-		return -EFAULT;
-
-	count = request.count;
-	order = DRM(order)( request.size );
-	size = 1 << order;
-
-	DRM_DEBUG( "count=%d, size=%d (%d), order=%d, queue_count=%d\n",
-		   request.count, request.size, size,
-		   order, dev->queue_count );
-
-	if ( order < DRM_MIN_ORDER || order > DRM_MAX_ORDER ) return -EINVAL;
-	if ( dev->queue_count ) return -EBUSY; /* Not while in use */
-
-	alignment = (request.flags & _DRM_PAGE_ALIGN)
-		? PAGE_ALIGN(size) : size;
-	page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0;
-	total = PAGE_SIZE << page_order;
-
-	spin_lock( &dev->count_lock );
-	if ( dev->buf_use ) {
-		spin_unlock( &dev->count_lock );
-		return -EBUSY;
-	}
-	atomic_inc( &dev->buf_alloc );
-	spin_unlock( &dev->count_lock );
-
-	down( &dev->struct_sem );
-	entry = &dma->bufs[order];
-	if ( entry->buf_count ) {
-		up( &dev->struct_sem );
-		atomic_dec( &dev->buf_alloc );
-		return -ENOMEM;	/* May only call once for each order */
-	}
-
-	if (count < 0 || count > 4096) {
-		up( &dev->struct_sem );
-		atomic_dec( &dev->buf_alloc );
-		return -EINVAL;
-	}
-
-	entry->buflist = DRM(alloc)( count * sizeof(*entry->buflist),
-				    DRM_MEM_BUFS );
-	if ( !entry->buflist ) {
-		up( &dev->struct_sem );
-		atomic_dec( &dev->buf_alloc );
-		return -ENOMEM;
-	}
-	memset( entry->buflist, 0, count * sizeof(*entry->buflist) );
-
-	entry->seglist = DRM(alloc)( count * sizeof(*entry->seglist),
-				    DRM_MEM_SEGS );
-	if ( !entry->seglist ) {
-		DRM(free)( entry->buflist,
-			  count * sizeof(*entry->buflist),
-			  DRM_MEM_BUFS );
-		up( &dev->struct_sem );
-		atomic_dec( &dev->buf_alloc );
-		return -ENOMEM;
-	}
-	memset( entry->seglist, 0, count * sizeof(*entry->seglist) );
-
-	/* Keep the original pagelist until we know all the allocations
-	 * have succeeded
-	 */
-	temp_pagelist = DRM(alloc)( (dma->page_count + (count << page_order))
-				    * sizeof(*dma->pagelist),
-				    DRM_MEM_PAGES );
-	if (!temp_pagelist) {
-		DRM(free)( entry->buflist,
-			   count * sizeof(*entry->buflist),
-			   DRM_MEM_BUFS );
-		DRM(free)( entry->seglist,
-			   count * sizeof(*entry->seglist),
-			   DRM_MEM_SEGS );
-		up( &dev->struct_sem );
-		atomic_dec( &dev->buf_alloc );
-		return -ENOMEM;
-	}
-	memcpy(temp_pagelist,
-	       dma->pagelist,
-	       dma->page_count * sizeof(*dma->pagelist));
-	DRM_DEBUG( "pagelist: %d entries\n",
-		   dma->page_count + (count << page_order) );
-
-	entry->buf_size	= size;
-	entry->page_order = page_order;
-	byte_count = 0;
-	page_count = 0;
-
-	while ( entry->buf_count < count ) {
-		page = DRM(alloc_pages)( page_order, DRM_MEM_DMA );
-		if ( !page ) {
-			/* Set count correctly so we free the proper amount. */
-			entry->buf_count = count;
-			entry->seg_count = count;
-			DRM(cleanup_buf_error)(entry);
-			DRM(free)( temp_pagelist,
-				   (dma->page_count + (count << page_order))
-				   * sizeof(*dma->pagelist),
-				   DRM_MEM_PAGES );
-			up( &dev->struct_sem );
-			atomic_dec( &dev->buf_alloc );
-			return -ENOMEM;
-		}
-		entry->seglist[entry->seg_count++] = page;
-		for ( i = 0 ; i < (1 << page_order) ; i++ ) {
-			DRM_DEBUG( "page %d @ 0x%08lx\n",
-				   dma->page_count + page_count,
-				   page + PAGE_SIZE * i );
-			temp_pagelist[dma->page_count + page_count++]
-				= page + PAGE_SIZE * i;
-		}
-		for ( offset = 0 ;
-		      offset + size <= total && entry->buf_count < count ;
-		      offset += alignment, ++entry->buf_count ) {
-			buf	     = &entry->buflist[entry->buf_count];
-			buf->idx     = dma->buf_count + entry->buf_count;
-			buf->total   = alignment;
-			buf->order   = order;
-			buf->used    = 0;
-			buf->offset  = (dma->byte_count + byte_count + offset);
-			buf->address = (void *)(page + offset);
-			buf->next    = NULL;
-			buf->waiting = 0;
-			buf->pending = 0;
-			init_waitqueue_head( &buf->dma_wait );
-			buf->filp    = NULL;
-
-			buf->dev_priv_size = dev->dev_priv_size;
-			buf->dev_private = DRM(alloc)( dev->dev_priv_size,
-						       DRM_MEM_BUFS );
-			if(!buf->dev_private) {
-				/* Set count correctly so we free the proper amount. */
-				entry->buf_count = count;
-				entry->seg_count = count;
-				DRM(cleanup_buf_error)(entry);
-				DRM(free)( temp_pagelist,
-					   (dma->page_count + (count << page_order))
-					   * sizeof(*dma->pagelist),
-					   DRM_MEM_PAGES );
-				up( &dev->struct_sem );
-				atomic_dec( &dev->buf_alloc );
-				return -ENOMEM;
-			}
-			memset( buf->dev_private, 0, buf->dev_priv_size );
-
-			DRM_DEBUG( "buffer %d @ %p\n",
-				   entry->buf_count, buf->address );
-		}
-		byte_count += PAGE_SIZE << page_order;
-	}
-
-	temp_buflist = DRM(realloc)( dma->buflist,
-				     dma->buf_count * sizeof(*dma->buflist),
-				     (dma->buf_count + entry->buf_count)
-				     * sizeof(*dma->buflist),
-				     DRM_MEM_BUFS );
-	if (!temp_buflist) {
-		/* Free the entry because it isn't valid */
-		DRM(cleanup_buf_error)(entry);
-		DRM(free)( temp_pagelist,
-			   (dma->page_count + (count << page_order))
-			   * sizeof(*dma->pagelist),
-			   DRM_MEM_PAGES );
-		up( &dev->struct_sem );
-		atomic_dec( &dev->buf_alloc );
-		return -ENOMEM;
-	}
-	dma->buflist = temp_buflist;
-
-	for ( i = 0 ; i < entry->buf_count ; i++ ) {
-		dma->buflist[i + dma->buf_count] = &entry->buflist[i];
-	}
-
-	/* No allocations failed, so now we can replace the orginal pagelist
-	 * with the new one.
-	 */
-	if (dma->page_count) {
-		DRM(free)(dma->pagelist,
-			  dma->page_count * sizeof(*dma->pagelist),
-			  DRM_MEM_PAGES);
-	}
-	dma->pagelist = temp_pagelist;
-
-	dma->buf_count += entry->buf_count;
-	dma->seg_count += entry->seg_count;
-	dma->page_count += entry->seg_count << page_order;
-	dma->byte_count += PAGE_SIZE * (entry->seg_count << page_order);
-
-	up( &dev->struct_sem );
-
-	request.count = entry->buf_count;
-	request.size = size;
-
-	if ( copy_to_user( argp, &request, sizeof(request) ) )
-		return -EFAULT;
-
-	atomic_dec( &dev->buf_alloc );
-	return 0;
-
-}
-
-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->dev;
-	drm_device_dma_t *dma = dev->dma;
-	drm_buf_desc_t __user *argp = (void __user *)arg;
-	drm_buf_desc_t request;
-	drm_buf_entry_t *entry;
-	drm_buf_t *buf;
-	unsigned long offset;
-	unsigned long agp_offset;
-	int count;
-	int order;
-	int size;
-	int alignment;
-	int page_order;
-	int total;
-	int byte_count;
-	int i;
-	drm_buf_t **temp_buflist;
-
-	if (!drm_core_check_feature(dev, DRIVER_SG)) return -EINVAL;
-	
-	if ( !dma ) return -EINVAL;
-
-	if ( copy_from_user( &request, argp, sizeof(request) ) )
-		return -EFAULT;
-
-	count = request.count;
-	order = DRM(order)( request.size );
-	size = 1 << order;
-
-	alignment  = (request.flags & _DRM_PAGE_ALIGN)
-			? PAGE_ALIGN(size) : size;
-	page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0;
-	total = PAGE_SIZE << page_order;
-
-	byte_count = 0;
-	agp_offset = request.agp_start;
-
-	DRM_DEBUG( "count:      %d\n",  count );
-	DRM_DEBUG( "order:      %d\n",  order );
-	DRM_DEBUG( "size:       %d\n",  size );
-	DRM_DEBUG( "agp_offset: %lu\n", agp_offset );
-	DRM_DEBUG( "alignment:  %d\n",  alignment );
-	DRM_DEBUG( "page_order: %d\n",  page_order );
-	DRM_DEBUG( "total:      %d\n",  total );
-
-	if ( order < DRM_MIN_ORDER || order > DRM_MAX_ORDER ) return -EINVAL;
-	if ( dev->queue_count ) return -EBUSY; /* Not while in use */
-
-	spin_lock( &dev->count_lock );
-	if ( dev->buf_use ) {
-		spin_unlock( &dev->count_lock );
-		return -EBUSY;
-	}
-	atomic_inc( &dev->buf_alloc );
-	spin_unlock( &dev->count_lock );
-
-	down( &dev->struct_sem );
-	entry = &dma->bufs[order];
-	if ( entry->buf_count ) {
-		up( &dev->struct_sem );
-		atomic_dec( &dev->buf_alloc );
-		return -ENOMEM; /* May only call once for each order */
-	}
-
-	if (count < 0 || count > 4096) {
-		up( &dev->struct_sem );
-		atomic_dec( &dev->buf_alloc );
-		return -EINVAL;
-	}
-
-	entry->buflist = DRM(alloc)( count * sizeof(*entry->buflist),
-				     DRM_MEM_BUFS );
-	if ( !entry->buflist ) {
-		up( &dev->struct_sem );
-		atomic_dec( &dev->buf_alloc );
-		return -ENOMEM;
-	}
-	memset( entry->buflist, 0, count * sizeof(*entry->buflist) );
-
-	entry->buf_size = size;
-	entry->page_order = page_order;
-
-	offset = 0;
-
-	while ( entry->buf_count < count ) {
-		buf          = &entry->buflist[entry->buf_count];
-		buf->idx     = dma->buf_count + entry->buf_count;
-		buf->total   = alignment;
-		buf->order   = order;
-		buf->used    = 0;
-
-		buf->offset  = (dma->byte_count + offset);
-		buf->bus_address = agp_offset + offset;
-		buf->address = (void *)(agp_offset + offset + dev->sg->handle);
-		buf->next    = NULL;
-		buf->waiting = 0;
-		buf->pending = 0;
-		init_waitqueue_head( &buf->dma_wait );
-		buf->filp    = NULL;
-
-		buf->dev_priv_size = dev->dev_priv_size;
-		buf->dev_private = DRM(alloc)( dev->dev_priv_size,
-					       DRM_MEM_BUFS );
-		if(!buf->dev_private) {
-			/* Set count correctly so we free the proper amount. */
-			entry->buf_count = count;
-			DRM(cleanup_buf_error)(entry);
-			up( &dev->struct_sem );
-			atomic_dec( &dev->buf_alloc );
-			return -ENOMEM;
-		}
-
-		memset( buf->dev_private, 0, buf->dev_priv_size );
-
-		DRM_DEBUG( "buffer %d @ %p\n",
-			   entry->buf_count, buf->address );
-
-		offset += alignment;
-		entry->buf_count++;
-		byte_count += PAGE_SIZE << page_order;
-	}
-
-	DRM_DEBUG( "byte_count: %d\n", byte_count );
-
-	temp_buflist = DRM(realloc)( dma->buflist,
-				     dma->buf_count * sizeof(*dma->buflist),
-				     (dma->buf_count + entry->buf_count)
-				     * sizeof(*dma->buflist),
-				     DRM_MEM_BUFS );
-	if(!temp_buflist) {
-		/* Free the entry because it isn't valid */
-		DRM(cleanup_buf_error)(entry);
-		up( &dev->struct_sem );
-		atomic_dec( &dev->buf_alloc );
-		return -ENOMEM;
-	}
-	dma->buflist = temp_buflist;
-
-	for ( i = 0 ; i < entry->buf_count ; i++ ) {
-		dma->buflist[i + dma->buf_count] = &entry->buflist[i];
-	}
-
-	dma->buf_count += entry->buf_count;
-	dma->byte_count += byte_count;
-
-	DRM_DEBUG( "dma->buf_count : %d\n", dma->buf_count );
-	DRM_DEBUG( "entry->buf_count : %d\n", entry->buf_count );
-
-	up( &dev->struct_sem );
-
-	request.count = entry->buf_count;
-	request.size = size;
-
-	if ( copy_to_user( argp, &request, sizeof(request) ) )
-		return -EFAULT;
-
-	dma->flags = _DRM_DMA_USE_SG;
-
-	atomic_dec( &dev->buf_alloc );
-	return 0;
-}
-
-/**
- * Add buffers for DMA transfers (ioctl).
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg pointer to a drm_buf_desc_t request.
- * \return zero on success or a negative number on failure.
- *
- * According with the memory type specified in drm_buf_desc::flags and the
- * build options, it dispatches the call either to addbufs_agp(),
- * addbufs_sg() or addbufs_pci() for AGP, scatter-gather or consistent
- * PCI memory respectively.
- */
-int DRM(addbufs)( struct inode *inode, struct file *filp,
-		  unsigned int cmd, unsigned long arg )
-{
-	drm_buf_desc_t request;
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
-	
-	if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA))
-		return -EINVAL;
-
-	if ( copy_from_user( &request, (drm_buf_desc_t __user *)arg,
-			     sizeof(request) ) )
-		return -EFAULT;
-
-#if __OS_HAS_AGP
-	if ( request.flags & _DRM_AGP_BUFFER )
-		return DRM(addbufs_agp)( inode, filp, cmd, arg );
-	else
-#endif
-	if ( request.flags & _DRM_SG_BUFFER )
-		return DRM(addbufs_sg)( inode, filp, cmd, arg );
-	else
-		return DRM(addbufs_pci)( inode, filp, cmd, arg );
-}
-
-
-/**
- * Get information about the buffer mappings.
- *
- * This was originally mean for debugging purposes, or by a sophisticated
- * client library to determine how best to use the available buffers (e.g.,
- * large buffers can be used for image transfer).
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg pointer to a drm_buf_info structure.
- * \return zero on success or a negative number on failure.
- *
- * Increments drm_device::buf_use while holding the drm_device::count_lock
- * lock, preventing of allocating more buffers after this call. Information
- * about each requested buffer is then copied into user space.
- */
-int DRM(infobufs)( struct inode *inode, struct file *filp,
-		   unsigned int cmd, unsigned long arg )
-{
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
-	drm_device_dma_t *dma = dev->dma;
-	drm_buf_info_t request;
-	drm_buf_info_t __user *argp = (void __user *)arg;
-	int i;
-	int count;
-
-	if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA))
-		return -EINVAL;
-
-	if ( !dma ) return -EINVAL;
-
-	spin_lock( &dev->count_lock );
-	if ( atomic_read( &dev->buf_alloc ) ) {
-		spin_unlock( &dev->count_lock );
-		return -EBUSY;
-	}
-	++dev->buf_use;		/* Can't allocate more after this call */
-	spin_unlock( &dev->count_lock );
-
-	if ( copy_from_user( &request, argp, sizeof(request) ) )
-		return -EFAULT;
-
-	for ( i = 0, count = 0 ; i < DRM_MAX_ORDER + 1 ; i++ ) {
-		if ( dma->bufs[i].buf_count ) ++count;
-	}
-
-	DRM_DEBUG( "count = %d\n", count );
-
-	if ( request.count >= count ) {
-		for ( i = 0, count = 0 ; i < DRM_MAX_ORDER + 1 ; i++ ) {
-			if ( dma->bufs[i].buf_count ) {
-				drm_buf_desc_t __user *to = &request.list[count];
-				drm_buf_entry_t *from = &dma->bufs[i];
-				drm_freelist_t *list = &dma->bufs[i].freelist;
-				if ( copy_to_user( &to->count,
-						   &from->buf_count,
-						   sizeof(from->buf_count) ) ||
-				     copy_to_user( &to->size,
-						   &from->buf_size,
-						   sizeof(from->buf_size) ) ||
-				     copy_to_user( &to->low_mark,
-						   &list->low_mark,
-						   sizeof(list->low_mark) ) ||
-				     copy_to_user( &to->high_mark,
-						   &list->high_mark,
-						   sizeof(list->high_mark) ) )
-					return -EFAULT;
-
-				DRM_DEBUG( "%d %d %d %d %d\n",
-					   i,
-					   dma->bufs[i].buf_count,
-					   dma->bufs[i].buf_size,
-					   dma->bufs[i].freelist.low_mark,
-					   dma->bufs[i].freelist.high_mark );
-				++count;
-			}
-		}
-	}
-	request.count = count;
-
-	if ( copy_to_user( argp, &request, sizeof(request) ) )
-		return -EFAULT;
-
-	return 0;
-}
-
-/**
- * Specifies a low and high water mark for buffer allocation
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg a pointer to a drm_buf_desc structure.
- * \return zero on success or a negative number on failure.
- *
- * Verifies that the size order is bounded between the admissible orders and
- * updates the respective drm_device_dma::bufs entry low and high water mark.
- *
- * \note This ioctl is deprecated and mostly never used.
- */
-int DRM(markbufs)( struct inode *inode, struct file *filp,
-		   unsigned int cmd, unsigned long arg )
-{
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
-	drm_device_dma_t *dma = dev->dma;
-	drm_buf_desc_t request;
-	int order;
-	drm_buf_entry_t *entry;
-
-	if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA))
-		return -EINVAL;
-
-	if ( !dma ) return -EINVAL;
-
-	if ( copy_from_user( &request,
-			     (drm_buf_desc_t __user *)arg,
-			     sizeof(request) ) )
-		return -EFAULT;
-
-	DRM_DEBUG( "%d, %d, %d\n",
-		   request.size, request.low_mark, request.high_mark );
-	order = DRM(order)( request.size );
-	if ( order < DRM_MIN_ORDER || order > DRM_MAX_ORDER ) return -EINVAL;
-	entry = &dma->bufs[order];
-
-	if ( request.low_mark < 0 || request.low_mark > entry->buf_count )
-		return -EINVAL;
-	if ( request.high_mark < 0 || request.high_mark > entry->buf_count )
-		return -EINVAL;
-
-	entry->freelist.low_mark  = request.low_mark;
-	entry->freelist.high_mark = request.high_mark;
-
-	return 0;
-}
-
-/**
- * Unreserve the buffers in list, previously reserved using drmDMA. 
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg pointer to a drm_buf_free structure.
- * \return zero on success or a negative number on failure.
- * 
- * Calls free_buffer() for each used buffer.
- * This function is primarily used for debugging.
- */
-int DRM(freebufs)( struct inode *inode, struct file *filp,
-		   unsigned int cmd, unsigned long arg )
-{
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
-	drm_device_dma_t *dma = dev->dma;
-	drm_buf_free_t request;
-	int i;
-	int idx;
-	drm_buf_t *buf;
-
-	if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA))
-		return -EINVAL;
-
-	if ( !dma ) return -EINVAL;
-
-	if ( copy_from_user( &request,
-			     (drm_buf_free_t __user *)arg,
-			     sizeof(request) ) )
-		return -EFAULT;
-
-	DRM_DEBUG( "%d\n", request.count );
-	for ( i = 0 ; i < request.count ; i++ ) {
-		if ( copy_from_user( &idx,
-				     &request.list[i],
-				     sizeof(idx) ) )
-			return -EFAULT;
-		if ( idx < 0 || idx >= dma->buf_count ) {
-			DRM_ERROR( "Index %d (of %d max)\n",
-				   idx, dma->buf_count - 1 );
-			return -EINVAL;
-		}
-		buf = dma->buflist[idx];
-		if ( buf->filp != filp ) {
-			DRM_ERROR( "Process %d freeing buffer not owned\n",
-				   current->pid );
-			return -EINVAL;
-		}
-		DRM(free_buffer)( dev, buf );
-	}
-
-	return 0;
-}
-
-/**
- * Maps all of the DMA buffers into client-virtual space (ioctl).
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg pointer to a drm_buf_map structure.
- * \return zero on success or a negative number on failure.
- *
- * Maps the AGP or SG buffer region with do_mmap(), and copies information
- * about each buffer into user space. The PCI buffers are already mapped on the
- * addbufs_pci() call.
- */
-int DRM(mapbufs)( struct inode *inode, struct file *filp,
-		  unsigned int cmd, unsigned long arg )
-{
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
-	drm_device_dma_t *dma = dev->dma;
-	drm_buf_map_t __user *argp = (void __user *)arg;
-	int retcode = 0;
-	const int zero = 0;
-	unsigned long virtual;
-	unsigned long address;
-	drm_buf_map_t request;
-	int i;
-
-	if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA))
-		return -EINVAL;
-
-	if ( !dma ) return -EINVAL;
-
-	spin_lock( &dev->count_lock );
-	if ( atomic_read( &dev->buf_alloc ) ) {
-		spin_unlock( &dev->count_lock );
-		return -EBUSY;
-	}
-	dev->buf_use++;		/* Can't allocate more after this call */
-	spin_unlock( &dev->count_lock );
-
-	if ( copy_from_user( &request, argp, sizeof(request) ) )
-		return -EFAULT;
-
-	if ( request.count >= dma->buf_count ) {
-		if ((drm_core_has_AGP(dev) && (dma->flags & _DRM_DMA_USE_AGP)) ||
-		    (drm_core_check_feature(dev, DRIVER_SG) && (dma->flags & _DRM_DMA_USE_SG)) ) {
-			drm_map_t *map = dev->agp_buffer_map;
-
-			if ( !map ) {
-				retcode = -EINVAL;
-				goto done;
-			}
-
-#if LINUX_VERSION_CODE <= 0x020402
-			down( &current->mm->mmap_sem );
-#else
-			down_write( &current->mm->mmap_sem );
-#endif
-			virtual = do_mmap( filp, 0, map->size,
-					   PROT_READ | PROT_WRITE,
-					   MAP_SHARED,
-					   (unsigned long)map->offset );
-#if LINUX_VERSION_CODE <= 0x020402
-			up( &current->mm->mmap_sem );
-#else
-			up_write( &current->mm->mmap_sem );
-#endif
-		} else {
-#if LINUX_VERSION_CODE <= 0x020402
-			down( &current->mm->mmap_sem );
-#else
-			down_write( &current->mm->mmap_sem );
-#endif
-			virtual = do_mmap( filp, 0, dma->byte_count,
-					   PROT_READ | PROT_WRITE,
-					   MAP_SHARED, 0 );
-#if LINUX_VERSION_CODE <= 0x020402
-			up( &current->mm->mmap_sem );
-#else
-			up_write( &current->mm->mmap_sem );
-#endif
-		}
-		if ( virtual > -1024UL ) {
-			/* Real error */
-			retcode = (signed long)virtual;
-			goto done;
-		}
-		request.virtual = (void __user *)virtual;
-
-		for ( i = 0 ; i < dma->buf_count ; i++ ) {
-			if ( copy_to_user( &request.list[i].idx,
-					   &dma->buflist[i]->idx,
-					   sizeof(request.list[0].idx) ) ) {
-				retcode = -EFAULT;
-				goto done;
-			}
-			if ( copy_to_user( &request.list[i].total,
-					   &dma->buflist[i]->total,
-					   sizeof(request.list[0].total) ) ) {
-				retcode = -EFAULT;
-				goto done;
-			}
-			if ( copy_to_user( &request.list[i].used,
-					   &zero,
-					   sizeof(zero) ) ) {
-				retcode = -EFAULT;
-				goto done;
-			}
-			address = virtual + dma->buflist[i]->offset; /* *** */
-			if ( copy_to_user( &request.list[i].address,
-					   &address,
-					   sizeof(address) ) ) {
-				retcode = -EFAULT;
-				goto done;
-			}
-		}
-	}
- done:
-	request.count = dma->buf_count;
-	DRM_DEBUG( "%d buffers, retcode = %d\n", request.count, retcode );
-
-	if ( copy_to_user( argp, &request, sizeof(request) ) )
-		return -EFAULT;
-
-	return retcode;
-}
-
diff -Nru a/drivers/char/drm/drm_context.c b/drivers/char/drm/drm_context.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/char/drm/drm_context.c	2005-03-01 23:38:44 -08:00
@@ -0,0 +1,578 @@
+/**
+ * \file drm_context.h 
+ * IOCTLs for generic contexts
+ * 
+ * \author Rickard E. (Rik) Faith <faith@valinux.com>
+ * \author Gareth Hughes <gareth@valinux.com>
+ */
+
+/*
+ * Created: Fri Nov 24 18:31:37 2000 by gareth@valinux.com
+ *
+ * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * ChangeLog:
+ *  2001-11-16	Torsten Duwe <duwe@caldera.de>
+ *		added context constructor/destructor hooks,
+ *		needed by SiS driver's memory management.
+ */
+
+#include "drmP.h"
+
+/******************************************************************/
+/** \name Context bitmap support */
+/*@{*/
+
+/**
+ * Free a handle from the context bitmap.
+ *
+ * \param dev DRM device.
+ * \param ctx_handle context handle.
+ *
+ * Clears the bit specified by \p ctx_handle in drm_device::ctx_bitmap and the entry
+ * in drm_device::context_sareas, while holding the drm_device::struct_sem
+ * lock.
+ */
+void drm_ctxbitmap_free( drm_device_t *dev, int ctx_handle )
+{
+	if ( ctx_handle < 0 ) goto failed;
+	if ( !dev->ctx_bitmap ) goto failed;
+
+	if ( ctx_handle < DRM_MAX_CTXBITMAP ) {
+		down(&dev->struct_sem);
+		clear_bit( ctx_handle, dev->ctx_bitmap );
+		dev->context_sareas[ctx_handle] = NULL;
+		up(&dev->struct_sem);
+		return;
+	}
+failed:
+       	DRM_ERROR( "Attempt to free invalid context handle: %d\n",
+		   ctx_handle );
+       	return;
+}
+
+/** 
+ * Context bitmap allocation.
+ *
+ * \param dev DRM device.
+ * \return (non-negative) context handle on success or a negative number on failure.
+ *
+ * Find the first zero bit in drm_device::ctx_bitmap and (re)allocates
+ * 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 )
+{
+	int bit;
+
+	if(!dev->ctx_bitmap) return -1;
+
+	down(&dev->struct_sem);
+	bit = find_first_zero_bit( dev->ctx_bitmap, DRM_MAX_CTXBITMAP );
+	if ( bit < DRM_MAX_CTXBITMAP ) {
+		set_bit( bit, dev->ctx_bitmap );
+	   	DRM_DEBUG( "drm_ctxbitmap_next bit : %d\n", bit );
+		if((bit+1) > dev->max_context) {
+			dev->max_context = (bit+1);
+			if(dev->context_sareas) {
+				drm_map_t **ctx_sareas;
+
+				ctx_sareas = drm_realloc(dev->context_sareas,
+						(dev->max_context - 1) * 
+						sizeof(*dev->context_sareas),
+						dev->max_context * 
+						sizeof(*dev->context_sareas),
+						DRM_MEM_MAPS);
+				if(!ctx_sareas) {
+					clear_bit(bit, dev->ctx_bitmap);
+					up(&dev->struct_sem);
+					return -1;
+				}
+				dev->context_sareas = ctx_sareas;
+				dev->context_sareas[bit] = NULL;
+			} else {
+				/* max_context == 1 at this point */
+				dev->context_sareas = drm_alloc(
+						dev->max_context * 
+						sizeof(*dev->context_sareas),
+						DRM_MEM_MAPS);
+				if(!dev->context_sareas) {
+					clear_bit(bit, dev->ctx_bitmap);
+					up(&dev->struct_sem);
+					return -1;
+				}
+				dev->context_sareas[bit] = NULL;
+			}
+		}
+		up(&dev->struct_sem);
+		return bit;
+	}
+	up(&dev->struct_sem);
+	return -1;
+}
+
+/**
+ * Context bitmap initialization.
+ *
+ * \param dev DRM device.
+ *
+ * Allocates and initialize drm_device::ctx_bitmap and drm_device::context_sareas, while holding
+ * the drm_device::struct_sem lock.
+ */
+int drm_ctxbitmap_init( drm_device_t *dev )
+{
+	int i;
+   	int temp;
+
+	down(&dev->struct_sem);
+	dev->ctx_bitmap = (unsigned long *) drm_alloc( PAGE_SIZE,
+							DRM_MEM_CTXBITMAP );
+	if ( dev->ctx_bitmap == NULL ) {
+		up(&dev->struct_sem);
+		return -ENOMEM;
+	}
+	memset( (void *)dev->ctx_bitmap, 0, PAGE_SIZE );
+	dev->context_sareas = NULL;
+	dev->max_context = -1;
+	up(&dev->struct_sem);
+
+	for ( i = 0 ; i < DRM_RESERVED_CONTEXTS ; i++ ) {
+		temp = drm_ctxbitmap_next( dev );
+	   	DRM_DEBUG( "drm_ctxbitmap_init : %d\n", temp );
+	}
+
+	return 0;
+}
+
+/**
+ * Context bitmap cleanup.
+ *
+ * \param dev DRM device.
+ *
+ * Frees drm_device::ctx_bitmap and drm_device::context_sareas, while holding
+ * the drm_device::struct_sem lock.
+ */
+void drm_ctxbitmap_cleanup( drm_device_t *dev )
+{
+	down(&dev->struct_sem);
+	if( dev->context_sareas ) drm_free( dev->context_sareas,
+					     sizeof(*dev->context_sareas) * 
+					     dev->max_context,
+					     DRM_MEM_MAPS );
+	drm_free( (void *)dev->ctx_bitmap, PAGE_SIZE, DRM_MEM_CTXBITMAP );
+	up(&dev->struct_sem);
+}
+
+/*@}*/
+
+/******************************************************************/
+/** \name Per Context SAREA Support */
+/*@{*/
+
+/**
+ * Get per-context SAREA.
+ * 
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument pointing to a drm_ctx_priv_map structure.
+ * \return zero on success or a negative number on failure.
+ *
+ * Gets the map from drm_device::context_sareas with the handle specified and
+ * returns its handle.
+ */
+int drm_getsareactx(struct inode *inode, struct file *filp,
+		     unsigned int cmd, unsigned long arg)
+{
+	drm_file_t	*priv	= filp->private_data;
+	drm_device_t	*dev	= priv->dev;
+	drm_ctx_priv_map_t __user *argp = (void __user *)arg;
+	drm_ctx_priv_map_t request;
+	drm_map_t *map;
+
+	if (copy_from_user(&request, argp, sizeof(request)))
+		return -EFAULT;
+
+	down(&dev->struct_sem);
+	if (dev->max_context < 0 || request.ctx_id >= (unsigned) dev->max_context) {
+		up(&dev->struct_sem);
+		return -EINVAL;
+	}
+
+	map = dev->context_sareas[request.ctx_id];
+	up(&dev->struct_sem);
+
+	request.handle = map->handle;
+	if (copy_to_user(argp, &request, sizeof(request)))
+		return -EFAULT;
+	return 0;
+}
+
+/**
+ * Set per-context SAREA.
+ * 
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument pointing to a drm_ctx_priv_map structure.
+ * \return zero on success or a negative number on failure.
+ *
+ * Searches the mapping specified in \p arg and update the entry in
+ * drm_device::context_sareas with it.
+ */
+int drm_setsareactx(struct inode *inode, struct file *filp,
+		     unsigned int cmd, unsigned long arg)
+{
+	drm_file_t	*priv	= filp->private_data;
+	drm_device_t	*dev	= priv->dev;
+	drm_ctx_priv_map_t request;
+	drm_map_t *map = NULL;
+	drm_map_list_t *r_list = NULL;
+	struct list_head *list;
+
+	if (copy_from_user(&request,
+			   (drm_ctx_priv_map_t __user *)arg,
+			   sizeof(request)))
+		return -EFAULT;
+
+	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)
+			goto found;
+	}
+bad:
+	up(&dev->struct_sem);
+	return -EINVAL;
+
+found:
+	map = r_list->map;
+	if (!map) goto bad;
+	if (dev->max_context < 0)
+		goto bad;
+	if (request.ctx_id >= (unsigned) dev->max_context)
+		goto bad;
+	dev->context_sareas[request.ctx_id] = map;
+	up(&dev->struct_sem);
+	return 0;
+}
+
+/*@}*/
+
+/******************************************************************/
+/** \name The actual DRM context handling routines */
+/*@{*/
+
+/**
+ * Switch context.
+ *
+ * \param dev DRM device.
+ * \param old old context handle.
+ * \param new new context handle.
+ * \return zero on success or a negative number on failure.
+ *
+ * Attempt to set drm_device::context_flag.
+ */
+int drm_context_switch( drm_device_t *dev, int old, int new )
+{
+        if ( test_and_set_bit( 0, &dev->context_flag ) ) {
+                DRM_ERROR( "Reentering -- FIXME\n" );
+                return -EBUSY;
+        }
+
+
+        DRM_DEBUG( "Context switch from %d to %d\n", old, new );
+
+        if ( new == dev->last_context ) {
+                clear_bit( 0, &dev->context_flag );
+                return 0;
+        }
+
+        return 0;
+}
+
+/**
+ * Complete context switch.
+ *
+ * \param dev DRM device.
+ * \param new new context handle.
+ * \return zero on success or a negative number on failure.
+ *
+ * Updates drm_device::last_context and drm_device::last_switch. Verifies the
+ * 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 )
+{
+        dev->last_context = new;  /* PRE/POST: This is the _only_ writer. */
+        dev->last_switch  = jiffies;
+
+        if ( !_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) ) {
+                DRM_ERROR( "Lock isn't held after context switch\n" );
+        }
+
+				/* If a context switch is ever initiated
+                                   when the kernel holds the lock, release
+                                   that lock here. */
+        clear_bit( 0, &dev->context_flag );
+        wake_up( &dev->context_wait );
+
+        return 0;
+}
+
+/**
+ * Reserve contexts.
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument pointing to a drm_ctx_res structure.
+ * \return zero on success or a negative number on failure.
+ */
+int drm_resctx( struct inode *inode, struct file *filp,
+		 unsigned int cmd, unsigned long arg )
+{
+	drm_ctx_res_t res;
+	drm_ctx_t __user *argp = (void __user *)arg;
+	drm_ctx_t ctx;
+	int i;
+
+	if ( copy_from_user( &res, argp, sizeof(res) ) )
+		return -EFAULT;
+
+	if ( res.count >= DRM_RESERVED_CONTEXTS ) {
+		memset( &ctx, 0, sizeof(ctx) );
+		for ( i = 0 ; i < DRM_RESERVED_CONTEXTS ; i++ ) {
+			ctx.handle = i;
+			if ( copy_to_user( &res.contexts[i],
+					   &i, sizeof(i) ) )
+				return -EFAULT;
+		}
+	}
+	res.count = DRM_RESERVED_CONTEXTS;
+
+	if ( copy_to_user( argp, &res, sizeof(res) ) )
+		return -EFAULT;
+	return 0;
+}
+
+/**
+ * Add context.
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument pointing to a drm_ctx structure.
+ * \return zero on success or a negative number on failure.
+ *
+ * Get a new handle for the context and copy to userspace.
+ */
+int drm_addctx( struct inode *inode, struct file *filp,
+		 unsigned int cmd, unsigned long arg )
+{
+	drm_file_t *priv = filp->private_data;
+	drm_device_t *dev = priv->dev;
+	drm_ctx_list_t * ctx_entry;
+	drm_ctx_t __user *argp = (void __user *)arg;
+	drm_ctx_t ctx;
+
+	if ( copy_from_user( &ctx, argp, sizeof(ctx) ) )
+		return -EFAULT;
+
+	ctx.handle = drm_ctxbitmap_next( dev );
+	if ( ctx.handle == DRM_KERNEL_CONTEXT ) {
+				/* Skip kernel's context and get a new one. */
+		ctx.handle = drm_ctxbitmap_next( dev );
+	}
+	DRM_DEBUG( "%d\n", ctx.handle );
+	if ( ctx.handle == -1 ) {
+		DRM_DEBUG( "Not enough free contexts.\n" );
+				/* Should this return -EBUSY instead? */
+		return -ENOMEM;
+	}
+
+	if ( ctx.handle != DRM_KERNEL_CONTEXT )
+	{
+		if (dev->driver->context_ctor)
+			dev->driver->context_ctor(dev, ctx.handle);
+	}
+
+	ctx_entry = drm_alloc( sizeof(*ctx_entry), DRM_MEM_CTXLIST );
+	if ( !ctx_entry ) {
+		DRM_DEBUG("out of memory\n");
+		return -ENOMEM;
+	}
+
+	INIT_LIST_HEAD( &ctx_entry->head );
+	ctx_entry->handle = ctx.handle;
+	ctx_entry->tag = priv;
+
+	down( &dev->ctxlist_sem );
+	list_add( &ctx_entry->head, &dev->ctxlist->head );
+	++dev->ctx_count;
+	up( &dev->ctxlist_sem );
+
+	if ( copy_to_user( argp, &ctx, sizeof(ctx) ) )
+		return -EFAULT;
+	return 0;
+}
+
+int drm_modctx( struct inode *inode, struct file *filp,
+		 unsigned int cmd, unsigned long arg )
+{
+	/* This does nothing */
+	return 0;
+}
+
+/**
+ * Get context.
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument pointing to a drm_ctx structure.
+ * \return zero on success or a negative number on failure.
+ */
+int drm_getctx( struct inode *inode, struct file *filp,
+		 unsigned int cmd, unsigned long arg )
+{
+	drm_ctx_t __user *argp = (void __user *)arg;
+	drm_ctx_t ctx;
+
+	if ( copy_from_user( &ctx, argp, sizeof(ctx) ) )
+		return -EFAULT;
+
+	/* This is 0, because we don't handle any context flags */
+	ctx.flags = 0;
+
+	if ( copy_to_user( argp, &ctx, sizeof(ctx) ) )
+		return -EFAULT;
+	return 0;
+}
+
+/**
+ * Switch context.
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument pointing to a drm_ctx structure.
+ * \return zero on success or a negative number on failure.
+ *
+ * Calls context_switch().
+ */
+int drm_switchctx( struct inode *inode, struct file *filp,
+		    unsigned int cmd, unsigned long arg )
+{
+	drm_file_t *priv = filp->private_data;
+	drm_device_t *dev = priv->dev;
+	drm_ctx_t ctx;
+
+	if ( copy_from_user( &ctx, (drm_ctx_t __user *)arg, sizeof(ctx) ) )
+		return -EFAULT;
+
+	DRM_DEBUG( "%d\n", ctx.handle );
+	return drm_context_switch( dev, dev->last_context, ctx.handle );
+}
+
+/**
+ * New context.
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument pointing to a drm_ctx structure.
+ * \return zero on success or a negative number on failure.
+ *
+ * Calls context_switch_complete().
+ */
+int drm_newctx( struct inode *inode, struct file *filp,
+		 unsigned int cmd, unsigned long arg )
+{
+	drm_file_t *priv = filp->private_data;
+	drm_device_t *dev = priv->dev;
+	drm_ctx_t ctx;
+
+	if ( copy_from_user( &ctx, (drm_ctx_t __user *)arg, sizeof(ctx) ) )
+		return -EFAULT;
+
+	DRM_DEBUG( "%d\n", ctx.handle );
+	drm_context_switch_complete( dev, ctx.handle );
+
+	return 0;
+}
+
+/**
+ * Remove context.
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument pointing to a drm_ctx structure.
+ * \return zero on success or a negative number on failure.
+ *
+ * If not the special kernel context, calls ctxbitmap_free() to free the specified context.
+ */
+int drm_rmctx( struct inode *inode, struct file *filp,
+		unsigned int cmd, unsigned long arg )
+{
+	drm_file_t *priv = filp->private_data;
+	drm_device_t *dev = priv->dev;
+	drm_ctx_t ctx;
+
+	if ( copy_from_user( &ctx, (drm_ctx_t __user *)arg, sizeof(ctx) ) )
+		return -EFAULT;
+
+	DRM_DEBUG( "%d\n", ctx.handle );
+	if ( ctx.handle == DRM_KERNEL_CONTEXT + 1 ) {
+		priv->remove_auth_on_close = 1;
+	}
+	if ( ctx.handle != DRM_KERNEL_CONTEXT ) {
+		if (dev->driver->context_dtor)
+			dev->driver->context_dtor(dev, ctx.handle);
+		drm_ctxbitmap_free( dev, ctx.handle );
+	}
+
+	down( &dev->ctxlist_sem );
+	if ( !list_empty( &dev->ctxlist->head ) ) {
+		drm_ctx_list_t *pos, *n;
+
+		list_for_each_entry_safe( pos, n, &dev->ctxlist->head, head ) {
+			if ( pos->handle == ctx.handle ) {
+				list_del( &pos->head );
+				drm_free( pos, sizeof(*pos), DRM_MEM_CTXLIST );
+				--dev->ctx_count;
+			}
+		}
+	}
+	up( &dev->ctxlist_sem );
+
+	return 0;
+}
+
+/*@}*/
+
diff -Nru a/drivers/char/drm/drm_context.h b/drivers/char/drm/drm_context.h
--- a/drivers/char/drm/drm_context.h	2005-03-01 23:38:44 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,578 +0,0 @@
-/**
- * \file drm_context.h 
- * IOCTLs for generic contexts
- * 
- * \author Rickard E. (Rik) Faith <faith@valinux.com>
- * \author Gareth Hughes <gareth@valinux.com>
- */
-
-/*
- * Created: Fri Nov 24 18:31:37 2000 by gareth@valinux.com
- *
- * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/*
- * ChangeLog:
- *  2001-11-16	Torsten Duwe <duwe@caldera.de>
- *		added context constructor/destructor hooks,
- *		needed by SiS driver's memory management.
- */
-
-#include "drmP.h"
-
-/******************************************************************/
-/** \name Context bitmap support */
-/*@{*/
-
-/**
- * Free a handle from the context bitmap.
- *
- * \param dev DRM device.
- * \param ctx_handle context handle.
- *
- * Clears the bit specified by \p ctx_handle in drm_device::ctx_bitmap and the entry
- * in drm_device::context_sareas, while holding the drm_device::struct_sem
- * lock.
- */
-void DRM(ctxbitmap_free)( drm_device_t *dev, int ctx_handle )
-{
-	if ( ctx_handle < 0 ) goto failed;
-	if ( !dev->ctx_bitmap ) goto failed;
-
-	if ( ctx_handle < DRM_MAX_CTXBITMAP ) {
-		down(&dev->struct_sem);
-		clear_bit( ctx_handle, dev->ctx_bitmap );
-		dev->context_sareas[ctx_handle] = NULL;
-		up(&dev->struct_sem);
-		return;
-	}
-failed:
-       	DRM_ERROR( "Attempt to free invalid context handle: %d\n",
-		   ctx_handle );
-       	return;
-}
-
-/** 
- * Context bitmap allocation.
- *
- * \param dev DRM device.
- * \return (non-negative) context handle on success or a negative number on failure.
- *
- * Find the first zero bit in drm_device::ctx_bitmap and (re)allocates
- * 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 )
-{
-	int bit;
-
-	if(!dev->ctx_bitmap) return -1;
-
-	down(&dev->struct_sem);
-	bit = find_first_zero_bit( dev->ctx_bitmap, DRM_MAX_CTXBITMAP );
-	if ( bit < DRM_MAX_CTXBITMAP ) {
-		set_bit( bit, dev->ctx_bitmap );
-	   	DRM_DEBUG( "drm_ctxbitmap_next bit : %d\n", bit );
-		if((bit+1) > dev->max_context) {
-			dev->max_context = (bit+1);
-			if(dev->context_sareas) {
-				drm_map_t **ctx_sareas;
-
-				ctx_sareas = DRM(realloc)(dev->context_sareas,
-						(dev->max_context - 1) * 
-						sizeof(*dev->context_sareas),
-						dev->max_context * 
-						sizeof(*dev->context_sareas),
-						DRM_MEM_MAPS);
-				if(!ctx_sareas) {
-					clear_bit(bit, dev->ctx_bitmap);
-					up(&dev->struct_sem);
-					return -1;
-				}
-				dev->context_sareas = ctx_sareas;
-				dev->context_sareas[bit] = NULL;
-			} else {
-				/* max_context == 1 at this point */
-				dev->context_sareas = DRM(alloc)(
-						dev->max_context * 
-						sizeof(*dev->context_sareas),
-						DRM_MEM_MAPS);
-				if(!dev->context_sareas) {
-					clear_bit(bit, dev->ctx_bitmap);
-					up(&dev->struct_sem);
-					return -1;
-				}
-				dev->context_sareas[bit] = NULL;
-			}
-		}
-		up(&dev->struct_sem);
-		return bit;
-	}
-	up(&dev->struct_sem);
-	return -1;
-}
-
-/**
- * Context bitmap initialization.
- *
- * \param dev DRM device.
- *
- * Allocates and initialize drm_device::ctx_bitmap and drm_device::context_sareas, while holding
- * the drm_device::struct_sem lock.
- */
-int DRM(ctxbitmap_init)( drm_device_t *dev )
-{
-	int i;
-   	int temp;
-
-	down(&dev->struct_sem);
-	dev->ctx_bitmap = (unsigned long *) DRM(alloc)( PAGE_SIZE,
-							DRM_MEM_CTXBITMAP );
-	if ( dev->ctx_bitmap == NULL ) {
-		up(&dev->struct_sem);
-		return -ENOMEM;
-	}
-	memset( (void *)dev->ctx_bitmap, 0, PAGE_SIZE );
-	dev->context_sareas = NULL;
-	dev->max_context = -1;
-	up(&dev->struct_sem);
-
-	for ( i = 0 ; i < DRM_RESERVED_CONTEXTS ; i++ ) {
-		temp = DRM(ctxbitmap_next)( dev );
-	   	DRM_DEBUG( "drm_ctxbitmap_init : %d\n", temp );
-	}
-
-	return 0;
-}
-
-/**
- * Context bitmap cleanup.
- *
- * \param dev DRM device.
- *
- * Frees drm_device::ctx_bitmap and drm_device::context_sareas, while holding
- * the drm_device::struct_sem lock.
- */
-void DRM(ctxbitmap_cleanup)( drm_device_t *dev )
-{
-	down(&dev->struct_sem);
-	if( dev->context_sareas ) DRM(free)( dev->context_sareas,
-					     sizeof(*dev->context_sareas) * 
-					     dev->max_context,
-					     DRM_MEM_MAPS );
-	DRM(free)( (void *)dev->ctx_bitmap, PAGE_SIZE, DRM_MEM_CTXBITMAP );
-	up(&dev->struct_sem);
-}
-
-/*@}*/
-
-/******************************************************************/
-/** \name Per Context SAREA Support */
-/*@{*/
-
-/**
- * Get per-context SAREA.
- * 
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg user argument pointing to a drm_ctx_priv_map structure.
- * \return zero on success or a negative number on failure.
- *
- * Gets the map from drm_device::context_sareas with the handle specified and
- * returns its handle.
- */
-int DRM(getsareactx)(struct inode *inode, struct file *filp,
-		     unsigned int cmd, unsigned long arg)
-{
-	drm_file_t	*priv	= filp->private_data;
-	drm_device_t	*dev	= priv->dev;
-	drm_ctx_priv_map_t __user *argp = (void __user *)arg;
-	drm_ctx_priv_map_t request;
-	drm_map_t *map;
-
-	if (copy_from_user(&request, argp, sizeof(request)))
-		return -EFAULT;
-
-	down(&dev->struct_sem);
-	if (dev->max_context < 0 || request.ctx_id >= (unsigned) dev->max_context) {
-		up(&dev->struct_sem);
-		return -EINVAL;
-	}
-
-	map = dev->context_sareas[request.ctx_id];
-	up(&dev->struct_sem);
-
-	request.handle = map->handle;
-	if (copy_to_user(argp, &request, sizeof(request)))
-		return -EFAULT;
-	return 0;
-}
-
-/**
- * Set per-context SAREA.
- * 
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg user argument pointing to a drm_ctx_priv_map structure.
- * \return zero on success or a negative number on failure.
- *
- * Searches the mapping specified in \p arg and update the entry in
- * drm_device::context_sareas with it.
- */
-int DRM(setsareactx)(struct inode *inode, struct file *filp,
-		     unsigned int cmd, unsigned long arg)
-{
-	drm_file_t	*priv	= filp->private_data;
-	drm_device_t	*dev	= priv->dev;
-	drm_ctx_priv_map_t request;
-	drm_map_t *map = NULL;
-	drm_map_list_t *r_list = NULL;
-	struct list_head *list;
-
-	if (copy_from_user(&request,
-			   (drm_ctx_priv_map_t __user *)arg,
-			   sizeof(request)))
-		return -EFAULT;
-
-	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)
-			goto found;
-	}
-bad:
-	up(&dev->struct_sem);
-	return -EINVAL;
-
-found:
-	map = r_list->map;
-	if (!map) goto bad;
-	if (dev->max_context < 0)
-		goto bad;
-	if (request.ctx_id >= (unsigned) dev->max_context)
-		goto bad;
-	dev->context_sareas[request.ctx_id] = map;
-	up(&dev->struct_sem);
-	return 0;
-}
-
-/*@}*/
-
-/******************************************************************/
-/** \name The actual DRM context handling routines */
-/*@{*/
-
-/**
- * Switch context.
- *
- * \param dev DRM device.
- * \param old old context handle.
- * \param new new context handle.
- * \return zero on success or a negative number on failure.
- *
- * Attempt to set drm_device::context_flag.
- */
-int DRM(context_switch)( drm_device_t *dev, int old, int new )
-{
-        if ( test_and_set_bit( 0, &dev->context_flag ) ) {
-                DRM_ERROR( "Reentering -- FIXME\n" );
-                return -EBUSY;
-        }
-
-
-        DRM_DEBUG( "Context switch from %d to %d\n", old, new );
-
-        if ( new == dev->last_context ) {
-                clear_bit( 0, &dev->context_flag );
-                return 0;
-        }
-
-        return 0;
-}
-
-/**
- * Complete context switch.
- *
- * \param dev DRM device.
- * \param new new context handle.
- * \return zero on success or a negative number on failure.
- *
- * Updates drm_device::last_context and drm_device::last_switch. Verifies the
- * 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 )
-{
-        dev->last_context = new;  /* PRE/POST: This is the _only_ writer. */
-        dev->last_switch  = jiffies;
-
-        if ( !_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) ) {
-                DRM_ERROR( "Lock isn't held after context switch\n" );
-        }
-
-				/* If a context switch is ever initiated
-                                   when the kernel holds the lock, release
-                                   that lock here. */
-        clear_bit( 0, &dev->context_flag );
-        wake_up( &dev->context_wait );
-
-        return 0;
-}
-
-/**
- * Reserve contexts.
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg user argument pointing to a drm_ctx_res structure.
- * \return zero on success or a negative number on failure.
- */
-int DRM(resctx)( struct inode *inode, struct file *filp,
-		 unsigned int cmd, unsigned long arg )
-{
-	drm_ctx_res_t res;
-	drm_ctx_t __user *argp = (void __user *)arg;
-	drm_ctx_t ctx;
-	int i;
-
-	if ( copy_from_user( &res, argp, sizeof(res) ) )
-		return -EFAULT;
-
-	if ( res.count >= DRM_RESERVED_CONTEXTS ) {
-		memset( &ctx, 0, sizeof(ctx) );
-		for ( i = 0 ; i < DRM_RESERVED_CONTEXTS ; i++ ) {
-			ctx.handle = i;
-			if ( copy_to_user( &res.contexts[i],
-					   &i, sizeof(i) ) )
-				return -EFAULT;
-		}
-	}
-	res.count = DRM_RESERVED_CONTEXTS;
-
-	if ( copy_to_user( argp, &res, sizeof(res) ) )
-		return -EFAULT;
-	return 0;
-}
-
-/**
- * Add context.
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg user argument pointing to a drm_ctx structure.
- * \return zero on success or a negative number on failure.
- *
- * Get a new handle for the context and copy to userspace.
- */
-int DRM(addctx)( struct inode *inode, struct file *filp,
-		 unsigned int cmd, unsigned long arg )
-{
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
-	drm_ctx_list_t * ctx_entry;
-	drm_ctx_t __user *argp = (void __user *)arg;
-	drm_ctx_t ctx;
-
-	if ( copy_from_user( &ctx, argp, sizeof(ctx) ) )
-		return -EFAULT;
-
-	ctx.handle = DRM(ctxbitmap_next)( dev );
-	if ( ctx.handle == DRM_KERNEL_CONTEXT ) {
-				/* Skip kernel's context and get a new one. */
-		ctx.handle = DRM(ctxbitmap_next)( dev );
-	}
-	DRM_DEBUG( "%d\n", ctx.handle );
-	if ( ctx.handle == -1 ) {
-		DRM_DEBUG( "Not enough free contexts.\n" );
-				/* Should this return -EBUSY instead? */
-		return -ENOMEM;
-	}
-
-	if ( ctx.handle != DRM_KERNEL_CONTEXT )
-	{
-		if (dev->fn_tbl.context_ctor)
-			dev->fn_tbl.context_ctor(dev, ctx.handle);
-	}
-
-	ctx_entry = DRM(alloc)( sizeof(*ctx_entry), DRM_MEM_CTXLIST );
-	if ( !ctx_entry ) {
-		DRM_DEBUG("out of memory\n");
-		return -ENOMEM;
-	}
-
-	INIT_LIST_HEAD( &ctx_entry->head );
-	ctx_entry->handle = ctx.handle;
-	ctx_entry->tag = priv;
-
-	down( &dev->ctxlist_sem );
-	list_add( &ctx_entry->head, &dev->ctxlist->head );
-	++dev->ctx_count;
-	up( &dev->ctxlist_sem );
-
-	if ( copy_to_user( argp, &ctx, sizeof(ctx) ) )
-		return -EFAULT;
-	return 0;
-}
-
-int DRM(modctx)( struct inode *inode, struct file *filp,
-		 unsigned int cmd, unsigned long arg )
-{
-	/* This does nothing */
-	return 0;
-}
-
-/**
- * Get context.
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg user argument pointing to a drm_ctx structure.
- * \return zero on success or a negative number on failure.
- */
-int DRM(getctx)( struct inode *inode, struct file *filp,
-		 unsigned int cmd, unsigned long arg )
-{
-	drm_ctx_t __user *argp = (void __user *)arg;
-	drm_ctx_t ctx;
-
-	if ( copy_from_user( &ctx, argp, sizeof(ctx) ) )
-		return -EFAULT;
-
-	/* This is 0, because we don't handle any context flags */
-	ctx.flags = 0;
-
-	if ( copy_to_user( argp, &ctx, sizeof(ctx) ) )
-		return -EFAULT;
-	return 0;
-}
-
-/**
- * Switch context.
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg user argument pointing to a drm_ctx structure.
- * \return zero on success or a negative number on failure.
- *
- * Calls context_switch().
- */
-int DRM(switchctx)( struct inode *inode, struct file *filp,
-		    unsigned int cmd, unsigned long arg )
-{
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
-	drm_ctx_t ctx;
-
-	if ( copy_from_user( &ctx, (drm_ctx_t __user *)arg, sizeof(ctx) ) )
-		return -EFAULT;
-
-	DRM_DEBUG( "%d\n", ctx.handle );
-	return DRM(context_switch)( dev, dev->last_context, ctx.handle );
-}
-
-/**
- * New context.
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg user argument pointing to a drm_ctx structure.
- * \return zero on success or a negative number on failure.
- *
- * Calls context_switch_complete().
- */
-int DRM(newctx)( struct inode *inode, struct file *filp,
-		 unsigned int cmd, unsigned long arg )
-{
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
-	drm_ctx_t ctx;
-
-	if ( copy_from_user( &ctx, (drm_ctx_t __user *)arg, sizeof(ctx) ) )
-		return -EFAULT;
-
-	DRM_DEBUG( "%d\n", ctx.handle );
-	DRM(context_switch_complete)( dev, ctx.handle );
-
-	return 0;
-}
-
-/**
- * Remove context.
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg user argument pointing to a drm_ctx structure.
- * \return zero on success or a negative number on failure.
- *
- * If not the special kernel context, calls ctxbitmap_free() to free the specified context.
- */
-int DRM(rmctx)( struct inode *inode, struct file *filp,
-		unsigned int cmd, unsigned long arg )
-{
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
-	drm_ctx_t ctx;
-
-	if ( copy_from_user( &ctx, (drm_ctx_t __user *)arg, sizeof(ctx) ) )
-		return -EFAULT;
-
-	DRM_DEBUG( "%d\n", ctx.handle );
-	if ( ctx.handle == DRM_KERNEL_CONTEXT + 1 ) {
-		priv->remove_auth_on_close = 1;
-	}
-	if ( ctx.handle != DRM_KERNEL_CONTEXT ) {
-		if (dev->fn_tbl.context_dtor)
-			dev->fn_tbl.context_dtor(dev, ctx.handle);
-		DRM(ctxbitmap_free)( dev, ctx.handle );
-	}
-
-	down( &dev->ctxlist_sem );
-	if ( !list_empty( &dev->ctxlist->head ) ) {
-		drm_ctx_list_t *pos, *n;
-
-		list_for_each_entry_safe( pos, n, &dev->ctxlist->head, head ) {
-			if ( pos->handle == ctx.handle ) {
-				list_del( &pos->head );
-				DRM(free)( pos, sizeof(*pos), DRM_MEM_CTXLIST );
-				--dev->ctx_count;
-			}
-		}
-	}
-	up( &dev->ctxlist_sem );
-
-	return 0;
-}
-
-/*@}*/
-
diff -Nru a/drivers/char/drm/drm_core.h b/drivers/char/drm/drm_core.h
--- a/drivers/char/drm/drm_core.h	2005-03-01 23:38:55 -08:00
+++ b/drivers/char/drm/drm_core.h	2005-03-01 23:38:55 -08:00
@@ -20,21 +20,15 @@
  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  * DEALINGS IN THE SOFTWARE.
  */
+#define DRIVER_AUTHOR		"Gareth Hughes, Leif Delgass, JosÃ© Fonseca, Jon Smirl"
 
-#include "drm_auth.h"
-#include "drm_agpsupport.h"
-#include "drm_bufs.h"
-#include "drm_context.h"
-#include "drm_dma.h"
-#include "drm_irq.h"
-#include "drm_drawable.h"
-#include "drm_drv.h"
-#include "drm_fops.h"
-#include "drm_init.h"
-#include "drm_ioctl.h"
-#include "drm_lock.h"
-#include "drm_memory.h"
-#include "drm_proc.h"
-#include "drm_vm.h"
-#include "drm_stub.h"
-#include "drm_scatter.h"
+#define DRIVER_NAME		"drm"
+#define DRIVER_DESC		"DRM shared core routines"
+#define DRIVER_DATE		"20040925"
+
+#define DRM_IF_MAJOR	1
+#define DRM_IF_MINOR	2
+
+#define DRIVER_MAJOR	1
+#define DRIVER_MINOR	0
+#define DRIVER_PATCHLEVEL 0
diff -Nru a/drivers/char/drm/drm_dma.c b/drivers/char/drm/drm_dma.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/char/drm/drm_dma.c	2005-03-01 23:39:07 -08:00
@@ -0,0 +1,180 @@
+/**
+ * \file drm_dma.h 
+ * DMA IOCTL and function support
+ *
+ * \author Rickard E. (Rik) Faith <faith@valinux.com>
+ * \author Gareth Hughes <gareth@valinux.com>
+ */
+
+/*
+ * Created: Fri Mar 19 14:30:16 1999 by faith@valinux.com
+ *
+ * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "drmP.h"
+
+/**
+ * Initialize the DMA data.
+ * 
+ * \param dev DRM device.
+ * \return zero on success or a negative value on failure.
+ *
+ * Allocate and initialize a drm_device_dma structure.
+ */
+int drm_dma_setup( drm_device_t *dev )
+{
+	int i;
+
+	dev->dma = drm_alloc( sizeof(*dev->dma), DRM_MEM_DRIVER );
+	if ( !dev->dma )
+		return -ENOMEM;
+
+	memset( dev->dma, 0, sizeof(*dev->dma) );
+
+	for ( i = 0 ; i <= DRM_MAX_ORDER ; i++ )
+		memset(&dev->dma->bufs[i], 0, sizeof(dev->dma->bufs[0]));
+
+	return 0;
+}
+
+/**
+ * Cleanup the DMA resources.
+ *
+ * \param dev DRM device.
+ *
+ * Free all pages associated with DMA buffers, the buffers and pages lists, and
+ * finally the the drm_device::dma structure itself.
+ */
+void drm_dma_takedown(drm_device_t *dev)
+{
+	drm_device_dma_t  *dma = dev->dma;
+	int		  i, j;
+
+	if (!dma) return;
+
+				/* Clear dma buffers */
+	for (i = 0; i <= DRM_MAX_ORDER; i++) {
+		if (dma->bufs[i].seg_count) {
+			DRM_DEBUG("order %d: buf_count = %d,"
+				  " seg_count = %d\n",
+				  i,
+				  dma->bufs[i].buf_count,
+				  dma->bufs[i].seg_count);
+			for (j = 0; j < dma->bufs[i].seg_count; j++) {
+				if (dma->bufs[i].seglist[j]) {
+					drm_free_pages(dma->bufs[i].seglist[j],
+							dma->bufs[i].page_order,
+							DRM_MEM_DMA);
+				}
+			}
+			drm_free(dma->bufs[i].seglist,
+				  dma->bufs[i].seg_count
+				  * sizeof(*dma->bufs[0].seglist),
+				  DRM_MEM_SEGS);
+		}
+	   	if (dma->bufs[i].buf_count) {
+		   	for (j = 0; j < dma->bufs[i].buf_count; j++) {
+				if (dma->bufs[i].buflist[j].dev_private) {
+					drm_free(dma->bufs[i].buflist[j].dev_private,
+						  dma->bufs[i].buflist[j].dev_priv_size,
+						  DRM_MEM_BUFS);
+				}
+			}
+		   	drm_free(dma->bufs[i].buflist,
+				  dma->bufs[i].buf_count *
+				  sizeof(*dma->bufs[0].buflist),
+				  DRM_MEM_BUFS);
+		}
+	}
+
+	if (dma->buflist) {
+		drm_free(dma->buflist,
+			  dma->buf_count * sizeof(*dma->buflist),
+			  DRM_MEM_BUFS);
+	}
+
+	if (dma->pagelist) {
+		drm_free(dma->pagelist,
+			  dma->page_count * sizeof(*dma->pagelist),
+			  DRM_MEM_PAGES);
+	}
+	drm_free(dev->dma, sizeof(*dev->dma), DRM_MEM_DRIVER);
+	dev->dma = NULL;
+}
+
+
+/**
+ * Free a buffer.
+ *
+ * \param dev DRM device.
+ * \param buf buffer to free.
+ * 
+ * Resets the fields of \p buf.
+ */
+void drm_free_buffer(drm_device_t *dev, drm_buf_t *buf)
+{
+	if (!buf) return;
+
+	buf->waiting  = 0;
+	buf->pending  = 0;
+	buf->filp     = NULL;
+	buf->used     = 0;
+
+	if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE) && waitqueue_active(&buf->dma_wait)) {
+		wake_up_interruptible(&buf->dma_wait);
+	}
+}
+
+/**
+ * Reclaim the buffers.
+ *
+ * \param filp file pointer.
+ *
+ * Frees each buffer associated with \p filp not already on the hardware.
+ */
+void drm_core_reclaim_buffers(drm_device_t *dev, struct file *filp)
+{
+	drm_device_dma_t *dma = dev->dma;
+	int		 i;
+
+	if (!dma) return;
+	for (i = 0; i < dma->buf_count; i++) {
+		if (dma->buflist[i]->filp == filp) {
+			switch (dma->buflist[i]->list) {
+			case DRM_LIST_NONE:
+				drm_free_buffer(dev, dma->buflist[i]);
+				break;
+			case DRM_LIST_WAIT:
+				dma->buflist[i]->list = DRM_LIST_RECLAIM;
+				break;
+			default:
+				/* Buffer already on hardware. */
+				break;
+			}
+		}
+	}
+}
+EXPORT_SYMBOL(drm_core_reclaim_buffers);
+
diff -Nru a/drivers/char/drm/drm_dma.h b/drivers/char/drm/drm_dma.h
--- a/drivers/char/drm/drm_dma.h	2005-03-01 23:39:07 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,181 +0,0 @@
-/**
- * \file drm_dma.h 
- * DMA IOCTL and function support
- *
- * \author Rickard E. (Rik) Faith <faith@valinux.com>
- * \author Gareth Hughes <gareth@valinux.com>
- */
-
-/*
- * Created: Fri Mar 19 14:30:16 1999 by faith@valinux.com
- *
- * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include "drmP.h"
-
-/**
- * Initialize the DMA data.
- * 
- * \param dev DRM device.
- * \return zero on success or a negative value on failure.
- *
- * Allocate and initialize a drm_device_dma structure.
- */
-int DRM(dma_setup)( drm_device_t *dev )
-{
-	int i;
-
-	dev->dma = DRM(alloc)( sizeof(*dev->dma), DRM_MEM_DRIVER );
-	if ( !dev->dma )
-		return -ENOMEM;
-
-	memset( dev->dma, 0, sizeof(*dev->dma) );
-
-	for ( i = 0 ; i <= DRM_MAX_ORDER ; i++ )
-		memset(&dev->dma->bufs[i], 0, sizeof(dev->dma->bufs[0]));
-
-	return 0;
-}
-
-/**
- * Cleanup the DMA resources.
- *
- * \param dev DRM device.
- *
- * Free all pages associated with DMA buffers, the buffers and pages lists, and
- * finally the the drm_device::dma structure itself.
- */
-void DRM(dma_takedown)(drm_device_t *dev)
-{
-	drm_device_dma_t  *dma = dev->dma;
-	int		  i, j;
-
-	if (!dma) return;
-
-				/* Clear dma buffers */
-	for (i = 0; i <= DRM_MAX_ORDER; i++) {
-		if (dma->bufs[i].seg_count) {
-			DRM_DEBUG("order %d: buf_count = %d,"
-				  " seg_count = %d\n",
-				  i,
-				  dma->bufs[i].buf_count,
-				  dma->bufs[i].seg_count);
-			for (j = 0; j < dma->bufs[i].seg_count; j++) {
-				if (dma->bufs[i].seglist[j]) {
-					DRM(free_pages)(dma->bufs[i].seglist[j],
-							dma->bufs[i].page_order,
-							DRM_MEM_DMA);
-				}
-			}
-			DRM(free)(dma->bufs[i].seglist,
-				  dma->bufs[i].seg_count
-				  * sizeof(*dma->bufs[0].seglist),
-				  DRM_MEM_SEGS);
-		}
-	   	if (dma->bufs[i].buf_count) {
-		   	for (j = 0; j < dma->bufs[i].buf_count; j++) {
-				if (dma->bufs[i].buflist[j].dev_private) {
-					DRM(free)(dma->bufs[i].buflist[j].dev_private,
-						  dma->bufs[i].buflist[j].dev_priv_size,
-						  DRM_MEM_BUFS);
-				}
-			}
-		   	DRM(free)(dma->bufs[i].buflist,
-				  dma->bufs[i].buf_count *
-				  sizeof(*dma->bufs[0].buflist),
-				  DRM_MEM_BUFS);
-		}
-	}
-
-	if (dma->buflist) {
-		DRM(free)(dma->buflist,
-			  dma->buf_count * sizeof(*dma->buflist),
-			  DRM_MEM_BUFS);
-	}
-
-	if (dma->pagelist) {
-		DRM(free)(dma->pagelist,
-			  dma->page_count * sizeof(*dma->pagelist),
-			  DRM_MEM_PAGES);
-	}
-	DRM(free)(dev->dma, sizeof(*dev->dma), DRM_MEM_DRIVER);
-	dev->dma = NULL;
-}
-
-
-/**
- * Free a buffer.
- *
- * \param dev DRM device.
- * \param buf buffer to free.
- * 
- * Resets the fields of \p buf.
- */
-void DRM(free_buffer)(drm_device_t *dev, drm_buf_t *buf)
-{
-	if (!buf) return;
-
-	buf->waiting  = 0;
-	buf->pending  = 0;
-	buf->filp     = NULL;
-	buf->used     = 0;
-
-	if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE) && waitqueue_active(&buf->dma_wait)) {
-		wake_up_interruptible(&buf->dma_wait);
-	}
-}
-
-/**
- * Reclaim the buffers.
- *
- * \param filp file pointer.
- *
- * Frees each buffer associated with \p filp not already on the hardware.
- */
-void DRM(core_reclaim_buffers)( struct file *filp )
-{
-	drm_file_t    *priv   = filp->private_data;
-	drm_device_t  *dev    = priv->dev;
-	drm_device_dma_t *dma = dev->dma;
-	int		 i;
-
-	if (!dma) return;
-	for (i = 0; i < dma->buf_count; i++) {
-		if (dma->buflist[i]->filp == filp) {
-			switch (dma->buflist[i]->list) {
-			case DRM_LIST_NONE:
-				DRM(free_buffer)(dev, dma->buflist[i]);
-				break;
-			case DRM_LIST_WAIT:
-				dma->buflist[i]->list = DRM_LIST_RECLAIM;
-				break;
-			default:
-				/* Buffer already on hardware. */
-				break;
-			}
-		}
-	}
-}
-
diff -Nru a/drivers/char/drm/drm_drawable.c b/drivers/char/drm/drm_drawable.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/char/drm/drm_drawable.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,56 @@
+/**
+ * \file drm_drawable.h 
+ * IOCTLs for drawables
+ *
+ * \author Rickard E. (Rik) Faith <faith@valinux.com>
+ * \author Gareth Hughes <gareth@valinux.com>
+ */
+
+/*
+ * Created: Tue Feb  2 08:37:54 1999 by faith@valinux.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "drmP.h"
+
+/** No-op. */
+int drm_adddraw(struct inode *inode, struct file *filp,
+		 unsigned int cmd, unsigned long arg)
+{
+	drm_draw_t draw;
+
+	draw.handle = 0;	/* NOOP */
+	DRM_DEBUG("%d\n", draw.handle);
+	if (copy_to_user((drm_draw_t __user *)arg, &draw, sizeof(draw)))
+		return -EFAULT;
+	return 0;
+}
+
+/** No-op. */
+int drm_rmdraw(struct inode *inode, struct file *filp,
+		unsigned int cmd, unsigned long arg)
+{
+	return 0;		/* NOOP */
+}
diff -Nru a/drivers/char/drm/drm_drawable.h b/drivers/char/drm/drm_drawable.h
--- a/drivers/char/drm/drm_drawable.h	2005-03-01 23:39:19 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,56 +0,0 @@
-/**
- * \file drm_drawable.h 
- * IOCTLs for drawables
- *
- * \author Rickard E. (Rik) Faith <faith@valinux.com>
- * \author Gareth Hughes <gareth@valinux.com>
- */
-
-/*
- * Created: Tue Feb  2 08:37:54 1999 by faith@valinux.com
- *
- * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include "drmP.h"
-
-/** No-op. */
-int DRM(adddraw)(struct inode *inode, struct file *filp,
-		 unsigned int cmd, unsigned long arg)
-{
-	drm_draw_t draw;
-
-	draw.handle = 0;	/* NOOP */
-	DRM_DEBUG("%d\n", draw.handle);
-	if (copy_to_user((drm_draw_t __user *)arg, &draw, sizeof(draw)))
-		return -EFAULT;
-	return 0;
-}
-
-/** No-op. */
-int DRM(rmdraw)(struct inode *inode, struct file *filp,
-		unsigned int cmd, unsigned long arg)
-{
-	return 0;		/* NOOP */
-}
diff -Nru a/drivers/char/drm/drm_drv.c b/drivers/char/drm/drm_drv.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/char/drm/drm_drv.c	2005-03-01 23:39:09 -08:00
@@ -0,0 +1,545 @@
+/**
+ * \file drm_drv.h 
+ * Generic driver template
+ *
+ * \author Rickard E. (Rik) Faith <faith@valinux.com>
+ * \author Gareth Hughes <gareth@valinux.com>
+ *
+ * To use this template, you must at least define the following (samples
+ * given for the MGA driver):
+ *
+ * \code
+ * #define DRIVER_AUTHOR	"VA Linux Systems, Inc."
+ *
+ * #define DRIVER_NAME		"mga"
+ * #define DRIVER_DESC		"Matrox G200/G400"
+ * #define DRIVER_DATE		"20001127"
+ *
+ * #define DRIVER_MAJOR		2
+ * #define DRIVER_MINOR		0
+ * #define DRIVER_PATCHLEVEL	2
+ *
+ * #define DRIVER_IOCTL_COUNT	DRM_ARRAY_SIZE( mga_ioctls )
+ *
+ * #define drm_x		mga_##x
+ * \endcode
+ */
+
+/*
+ * Created: Thu Nov 23 03:10:50 2000 by gareth@valinux.com
+ *
+ * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "drmP.h"
+#include "drm_core.h"
+
+/** Ioctl table */
+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 },
+	[DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)]     = { drm_irq_by_busid, 0, 1 },
+	[DRM_IOCTL_NR(DRM_IOCTL_GET_MAP)]       = { drm_getmap,      0, 0 },
+	[DRM_IOCTL_NR(DRM_IOCTL_GET_CLIENT)]    = { drm_getclient,   0, 0 },
+	[DRM_IOCTL_NR(DRM_IOCTL_GET_STATS)]     = { drm_getstats,    0, 0 },
+	[DRM_IOCTL_NR(DRM_IOCTL_SET_VERSION)]   = { drm_setversion,  0, 1 },
+
+	[DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)]    = { drm_setunique,   1, 1 },
+	[DRM_IOCTL_NR(DRM_IOCTL_BLOCK)]         = { drm_noop,        1, 1 },
+	[DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)]       = { drm_noop,        1, 1 },
+	[DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)]    = { drm_authmagic,   1, 1 },
+
+	[DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)]       = { drm_addmap,      1, 1 },
+	[DRM_IOCTL_NR(DRM_IOCTL_RM_MAP)]        = { drm_rmmap,       1, 0 },
+
+	[DRM_IOCTL_NR(DRM_IOCTL_SET_SAREA_CTX)] = { drm_setsareactx, 1, 1 },
+	[DRM_IOCTL_NR(DRM_IOCTL_GET_SAREA_CTX)] = { drm_getsareactx, 1, 0 },
+
+	[DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)]       = { drm_addctx,      1, 1 },
+	[DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)]        = { drm_rmctx,       1, 1 },
+	[DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)]       = { drm_modctx,      1, 1 },
+	[DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)]       = { drm_getctx,      1, 0 },
+	[DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)]    = { drm_switchctx,   1, 1 },
+	[DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)]       = { drm_newctx,      1, 1 },
+	[DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)]       = { drm_resctx,      1, 0 },
+
+	[DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)]      = { drm_adddraw,     1, 1 },
+	[DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)]       = { drm_rmdraw,      1, 1 },
+
+	[DRM_IOCTL_NR(DRM_IOCTL_LOCK)]	        = { drm_lock,        1, 0 },
+	[DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)]        = { drm_unlock,      1, 0 },
+
+	[DRM_IOCTL_NR(DRM_IOCTL_FINISH)]        = { drm_noop,      1, 0 },
+
+	[DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)]      = { drm_addbufs,     1, 1 },
+	[DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS)]     = { drm_markbufs,    1, 1 },
+	[DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)]     = { drm_infobufs,    1, 0 },
+	[DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)]      = { drm_mapbufs,     1, 0 },
+	[DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)]     = { drm_freebufs,    1, 0 },
+	/* The DRM_IOCTL_DMA ioctl should be defined by the driver. */
+
+	[DRM_IOCTL_NR(DRM_IOCTL_CONTROL)]       = { drm_control,     1, 1 },
+
+#if __OS_HAS_AGP
+	[DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)]   = { drm_agp_acquire, 1, 1 },
+	[DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)]   = { drm_agp_release, 1, 1 },
+	[DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)]    = { drm_agp_enable,  1, 1 },
+	[DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)]      = { drm_agp_info,    1, 0 },
+	[DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)]     = { drm_agp_alloc,   1, 1 },
+	[DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)]      = { drm_agp_free,    1, 1 },
+	[DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)]      = { drm_agp_bind,    1, 1 },
+	[DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)]    = { drm_agp_unbind,  1, 1 },
+#endif
+
+	[DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC)]      = { drm_sg_alloc,    1, 1 },
+	[DRM_IOCTL_NR(DRM_IOCTL_SG_FREE)]       = { drm_sg_free,     1, 1 },
+
+	[DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK)]   = { drm_wait_vblank, 0, 0 },
+};
+
+#define DRIVER_IOCTL_COUNT	DRM_ARRAY_SIZE( drm_ioctls )
+
+/**
+ * Take down the DRM device.
+ *
+ * \param dev DRM device structure.
+ *
+ * Frees every resource in \p dev.
+ *
+ * \sa drm_device and setup().
+ */
+int drm_takedown( drm_device_t *dev )
+{
+	drm_magic_entry_t *pt, *next;
+	drm_map_t *map;
+	drm_map_list_t *r_list;
+	struct list_head *list, *list_next;
+	drm_vma_entry_t *vma, *vma_next;
+	int i;
+
+	DRM_DEBUG( "\n" );
+
+	if (dev->driver->pretakedown)
+	  dev->driver->pretakedown(dev);
+
+	if ( dev->irq_enabled ) drm_irq_uninstall( dev );
+
+	down( &dev->struct_sem );
+	del_timer( &dev->timer );
+
+	if ( dev->devname ) {
+		drm_free( dev->devname, strlen( dev->devname ) + 1,
+			   DRM_MEM_DRIVER );
+		dev->devname = NULL;
+	}
+
+	if ( dev->unique ) {
+		drm_free( dev->unique, strlen( dev->unique ) + 1,
+			   DRM_MEM_DRIVER );
+		dev->unique = NULL;
+		dev->unique_len = 0;
+	}
+				/* Clear pid list */
+	for ( i = 0 ; i < DRM_HASH_SIZE ; i++ ) {
+		for ( pt = dev->magiclist[i].head ; pt ; pt = next ) {
+			next = pt->next;
+			drm_free( pt, sizeof(*pt), DRM_MEM_MAGIC );
+		}
+		dev->magiclist[i].head = dev->magiclist[i].tail = NULL;
+	}
+
+				/* Clear AGP information */
+	if (drm_core_has_AGP(dev) && dev->agp) {
+		drm_agp_mem_t *entry;
+		drm_agp_mem_t *nexte;
+
+				/* Remove AGP resources, but leave dev->agp
+                                   intact until drv_cleanup is called. */
+		for ( entry = dev->agp->memory ; entry ; entry = nexte ) {
+			nexte = entry->next;
+			if ( entry->bound ) drm_unbind_agp( entry->memory );
+			drm_free_agp( entry->memory, entry->pages );
+			drm_free( entry, sizeof(*entry), DRM_MEM_AGPLISTS );
+		}
+		dev->agp->memory = NULL;
+
+		if ( dev->agp->acquired ) drm_agp_do_release();
+
+		dev->agp->acquired = 0;
+		dev->agp->enabled  = 0;
+	}
+
+				/* Clear vma list (only built for debugging) */
+	if ( dev->vmalist ) {
+		for ( vma = dev->vmalist ; vma ; vma = vma_next ) {
+			vma_next = vma->next;
+			drm_free( vma, sizeof(*vma), DRM_MEM_VMAS );
+		}
+		dev->vmalist = NULL;
+	}
+
+	if( dev->maplist ) {
+		list_for_each_safe( list, list_next, &dev->maplist->head ) {
+			r_list = (drm_map_list_t *)list;
+
+			if ( ( map = r_list->map ) ) {
+				switch ( map->type ) {
+				case _DRM_REGISTERS:
+				case _DRM_FRAME_BUFFER:
+					if (drm_core_has_MTRR(dev)) {
+						if ( map->mtrr >= 0 ) {
+							int retcode;
+							retcode = mtrr_del( map->mtrr,
+									    map->offset,
+									    map->size );
+							DRM_DEBUG( "mtrr_del=%d\n", retcode );
+						}
+					}
+					drm_ioremapfree( map->handle, map->size, dev );
+					break;
+				case _DRM_SHM:
+					vfree(map->handle);
+					break;
+
+				case _DRM_AGP:
+					/* Do nothing here, because this is all
+					 * handled in the AGP/GART driver.
+					 */
+					break;
+				case _DRM_SCATTER_GATHER:
+					/* Handle it */
+					if (drm_core_check_feature(dev, DRIVER_SG) && dev->sg) {
+						drm_sg_cleanup(dev->sg);
+						dev->sg = NULL;
+					}
+					break;
+				}
+				drm_free(map, sizeof(*map), DRM_MEM_MAPS);
+			}
+			list_del( list );
+			drm_free(r_list, sizeof(*r_list), DRM_MEM_MAPS);
+ 		}
+		drm_free(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS);
+		dev->maplist = NULL;
+ 	}
+
+	if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE) && dev->queuelist ) {
+		for ( i = 0 ; i < dev->queue_count ; i++ ) {
+			if ( dev->queuelist[i] ) {
+				drm_free( dev->queuelist[i],
+					  sizeof(*dev->queuelist[0]),
+					  DRM_MEM_QUEUES );
+				dev->queuelist[i] = NULL;
+			}
+		}
+		drm_free( dev->queuelist,
+			  dev->queue_slots * sizeof(*dev->queuelist),
+			  DRM_MEM_QUEUES );
+		dev->queuelist = NULL;
+	}
+	dev->queue_count = 0;
+
+	if (drm_core_check_feature(dev, DRIVER_HAVE_DMA))
+		drm_dma_takedown( dev );
+
+	if ( dev->lock.hw_lock ) {
+		dev->sigdata.lock = dev->lock.hw_lock = NULL; /* SHM removed */
+		dev->lock.filp = NULL;
+		wake_up_interruptible( &dev->lock.lock_queue );
+	}
+	up( &dev->struct_sem );
+
+	return 0;
+}
+
+
+
+/**
+ * Module initialization. Called via init_module at module load time, or via
+ * linux/init/main.c (this is not currently supported).
+ *
+ * \return zero on success or a negative number on failure.
+ *
+ * Initializes an array of drm_device structures, and attempts to
+ * initialize all available devices, using consecutive minors, registering the
+ * stubs and initializing the AGP device.
+ * 
+ * Expands the \c DRIVER_PREINIT and \c DRIVER_POST_INIT macros before and
+ * after the initialization for driver customization.
+ */
+int drm_init( struct drm_driver *driver )
+{
+	struct pci_dev *pdev = NULL;
+	struct pci_device_id *pid;
+	int i;
+
+	DRM_DEBUG( "\n" );
+
+	drm_mem_init();
+
+	for (i=0; driver->pci_driver.id_table[i].vendor != 0; i++) {
+		pid = (struct pci_device_id *)&driver->pci_driver.id_table[i];
+		
+		pdev=NULL;
+		/* pass back in pdev to account for multiple identical cards */		
+		while ((pdev = pci_get_subsys(pid->vendor, pid->device, pid->subvendor, pid->subdevice, pdev)) != NULL) {
+			/* stealth mode requires a manual probe */
+			pci_dev_get(pdev);
+			drm_probe(pdev, pid, driver);
+		}
+	}
+	return 0;
+}
+EXPORT_SYMBOL(drm_init);
+
+/**
+ * Called via cleanup_module() at module unload time.
+ *
+ * Cleans up all DRM device, calling takedown().
+ * 
+ * \sa drm_init().
+ */
+static void drm_cleanup( drm_device_t *dev )
+{
+	DRM_DEBUG( "\n" );
+
+	if (!dev) {
+		DRM_ERROR("cleanup called no dev\n");
+		return;
+	}
+
+	drm_takedown( dev );	
+
+	drm_ctxbitmap_cleanup( dev );
+	
+	if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) &&
+	    dev->agp && dev->agp->agp_mtrr >= 0) {
+		int retval;
+		retval = mtrr_del( dev->agp->agp_mtrr,
+				   dev->agp->agp_info.aper_base,
+				   dev->agp->agp_info.aper_size*1024*1024 );
+		DRM_DEBUG( "mtrr_del=%d\n", retval );
+	}
+	
+	if (drm_core_has_AGP(dev) && dev->agp ) {
+		drm_free( dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS );
+		dev->agp = NULL;
+	}
+
+	if (dev->driver->postcleanup)
+		dev->driver->postcleanup(dev);
+	
+	if ( drm_put_minor(dev) )
+		DRM_ERROR( "Cannot unload module\n" );
+}
+
+void drm_exit (struct drm_driver *driver)
+{
+	int i;
+	drm_device_t *dev = NULL;
+	drm_minor_t *minor;
+	
+	DRM_DEBUG( "\n" );
+
+	for (i = 0; i < drm_cards_limit; i++) {
+		minor = &drm_minors[i];
+		if (!minor->dev)
+			continue;
+		if (minor->dev->driver!=driver)
+			continue;
+
+		dev = minor->dev;
+		
+	}
+	if (dev) {
+		/* release the pci driver */
+		if (dev->pdev)
+			pci_dev_put(dev->pdev);
+		drm_cleanup(dev);
+	}
+	
+	DRM_INFO( "Module unloaded\n" );
+}
+EXPORT_SYMBOL(drm_exit);
+
+/** File operations structure */
+static struct file_operations drm_stub_fops = {
+	.owner = THIS_MODULE,
+	.open  = drm_stub_open
+};
+
+static int __init drm_core_init(void)
+{
+	int ret = -ENOMEM;
+	
+	drm_cards_limit = (drm_cards_limit < DRM_MAX_MINOR + 1 ? drm_cards_limit : DRM_MAX_MINOR + 1);
+	drm_minors = drm_calloc(drm_cards_limit,
+				sizeof(*drm_minors), DRM_MEM_STUB);
+	if(!drm_minors) 
+		goto err_p1;
+	
+	if (register_chrdev(DRM_MAJOR, "drm", &drm_stub_fops))
+		goto err_p1;
+	
+	drm_class = drm_sysfs_create(THIS_MODULE, "drm");
+	if (IS_ERR(drm_class)) {
+		printk (KERN_ERR "DRM: Error creating drm class.\n");
+		ret = PTR_ERR(drm_class);
+		goto err_p2;
+	}
+
+	drm_proc_root = create_proc_entry("dri", S_IFDIR, NULL);
+	if (!drm_proc_root) {
+		DRM_ERROR("Cannot create /proc/dri\n");
+		ret = -1;
+		goto err_p3;
+	}
+		
+	DRM_INFO( "Initialized %s %d.%d.%d %s\n",
+		DRIVER_NAME,
+		DRIVER_MAJOR,
+		DRIVER_MINOR,
+		DRIVER_PATCHLEVEL,
+		DRIVER_DATE
+		);
+	return 0;
+err_p3:
+	drm_sysfs_destroy(drm_class);
+err_p2:
+	unregister_chrdev(DRM_MAJOR, "drm");
+	drm_free(drm_minors, sizeof(*drm_minors) * drm_cards_limit, DRM_MEM_STUB);
+err_p1:	
+	return ret;
+}
+
+static void __exit drm_core_exit (void)
+{
+	remove_proc_entry("dri", NULL);
+	drm_sysfs_destroy(drm_class);
+
+	unregister_chrdev(DRM_MAJOR, "drm");
+
+	drm_free(drm_minors, sizeof(*drm_minors) *
+				drm_cards_limit, DRM_MEM_STUB);
+}
+
+
+module_init( drm_core_init );
+module_exit( drm_core_exit );
+
+
+/**
+ * Get version information
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument, pointing to a drm_version structure.
+ * \return zero on success or negative number on failure.
+ *
+ * Fills in the version information in \p arg.
+ */
+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->dev;
+	drm_version_t __user *argp = (void __user *)arg;
+	drm_version_t version;
+	int ret;
+
+	if ( copy_from_user( &version, argp, sizeof(version) ) )
+		return -EFAULT;
+
+	/* version is a required function to return the personality module version */
+	if ((ret = dev->driver->version(&version)))
+		return ret;
+		
+	if ( copy_to_user( argp, &version, sizeof(version) ) )
+		return -EFAULT;
+	return 0;
+}
+
+
+
+/** 
+ * Called whenever a process performs an ioctl on /dev/drm.
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument.
+ * \return zero on success or negative number on failure.
+ *
+ * Looks up the ioctl function in the ::ioctls table, checking for root
+ * previleges if so required, and dispatches to the respective function.
+ */
+int drm_ioctl( struct inode *inode, struct file *filp,
+		unsigned int cmd, unsigned long arg )
+{
+	drm_file_t *priv = filp->private_data;
+	drm_device_t *dev = priv->dev;
+	drm_ioctl_desc_t *ioctl;
+	drm_ioctl_t *func;
+	unsigned int nr = DRM_IOCTL_NR(cmd);
+	int retcode = -EINVAL;
+
+	atomic_inc( &dev->ioctl_count );
+	atomic_inc( &dev->counts[_DRM_STAT_IOCTLS] );
+	++priv->ioctl_count;
+
+	DRM_DEBUG( "pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%lx, auth=%d\n",
+		   current->pid, cmd, nr, (long)old_encode_dev(dev->device), 
+		   priv->authenticated );
+	
+	if (nr < DRIVER_IOCTL_COUNT)
+		ioctl = &drm_ioctls[nr];
+	else if ((nr >= DRM_COMMAND_BASE) && (nr < DRM_COMMAND_BASE + dev->driver->num_ioctls))
+		ioctl = &dev->driver->ioctls[nr - DRM_COMMAND_BASE];
+	else
+		goto err_i1;
+	
+	func = ioctl->func;
+	/* is there a local override? */
+	if ((nr == DRM_IOCTL_NR(DRM_IOCTL_DMA)) && dev->driver->dma_ioctl)
+		func = dev->driver->dma_ioctl;
+	
+	if ( !func ) {
+		DRM_DEBUG( "no function\n" );
+		retcode = -EINVAL;
+	} else if ( ( ioctl->root_only && !capable( CAP_SYS_ADMIN ) )||
+		    ( ioctl->auth_needed && !priv->authenticated ) ) {
+		retcode = -EACCES;
+	} else {
+		retcode = func( inode, filp, cmd, arg );
+	}
+	
+err_i1:
+	atomic_dec( &dev->ioctl_count );
+	if (retcode) DRM_DEBUG( "ret = %x\n", retcode);
+	return retcode;
+}
+EXPORT_SYMBOL(drm_ioctl);
+
diff -Nru a/drivers/char/drm/drm_drv.h b/drivers/char/drm/drm_drv.h
--- a/drivers/char/drm/drm_drv.h	2005-03-01 23:39:09 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,1060 +0,0 @@
-/**
- * \file drm_drv.h 
- * Generic driver template
- *
- * \author Rickard E. (Rik) Faith <faith@valinux.com>
- * \author Gareth Hughes <gareth@valinux.com>
- *
- * To use this template, you must at least define the following (samples
- * given for the MGA driver):
- *
- * \code
- * #define DRIVER_AUTHOR	"VA Linux Systems, Inc."
- *
- * #define DRIVER_NAME		"mga"
- * #define DRIVER_DESC		"Matrox G200/G400"
- * #define DRIVER_DATE		"20001127"
- *
- * #define DRIVER_MAJOR		2
- * #define DRIVER_MINOR		0
- * #define DRIVER_PATCHLEVEL	2
- *
- * #define DRIVER_IOCTL_COUNT	DRM_ARRAY_SIZE( mga_ioctls )
- *
- * #define DRM(x)		mga_##x
- * \endcode
- */
-
-/*
- * Created: Thu Nov 23 03:10:50 2000 by gareth@valinux.com
- *
- * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef DRIVER_IOCTLS
-#define DRIVER_IOCTLS
-#endif
-
-#ifndef MODULE
-/** Use an additional macro to avoid preprocessor troubles */
-#define DRM_OPTIONS_FUNC DRM(options)
-/**
- * Called by the kernel to parse command-line options passed via the
- * boot-loader (e.g., LILO).  It calls the insmod option routine,
- * parse_options().
- */
-static int __init DRM(options)( char *str )
-{
-	DRM(parse_options)( str );
-	return 1;
-}
-
-__setup( DRIVER_NAME "=", DRM_OPTIONS_FUNC );
-#undef DRM_OPTIONS_FUNC
-#endif
-
-#define MAX_DEVICES 4
-static drm_device_t	DRM(device)[MAX_DEVICES];
-static int		DRM(numdevs) = 0;
-
-struct file_operations	DRM(fops) = {
-	.owner   = THIS_MODULE,
-	.open	 = DRM(open),
-	.flush	 = DRM(flush),
-	.release = DRM(release),
-	.ioctl	 = DRM(ioctl),
-	.mmap	 = DRM(mmap),
-	.fasync  = DRM(fasync),
-	.poll	 = DRM(poll),
-	.read	 = DRM(read),
-};
-
-/** Ioctl table */
-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 },
-	[DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)]     = { DRM(irq_by_busid), 0, 1 },
-	[DRM_IOCTL_NR(DRM_IOCTL_GET_MAP)]       = { DRM(getmap),      0, 0 },
-	[DRM_IOCTL_NR(DRM_IOCTL_GET_CLIENT)]    = { DRM(getclient),   0, 0 },
-	[DRM_IOCTL_NR(DRM_IOCTL_GET_STATS)]     = { DRM(getstats),    0, 0 },
-	[DRM_IOCTL_NR(DRM_IOCTL_SET_VERSION)]   = { DRM(setversion),  0, 1 },
-
-	[DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)]    = { DRM(setunique),   1, 1 },
-	[DRM_IOCTL_NR(DRM_IOCTL_BLOCK)]         = { DRM(noop),        1, 1 },
-	[DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)]       = { DRM(noop),        1, 1 },
-	[DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)]    = { DRM(authmagic),   1, 1 },
-
-	[DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)]       = { DRM(addmap),      1, 1 },
-	[DRM_IOCTL_NR(DRM_IOCTL_RM_MAP)]        = { DRM(rmmap),       1, 0 },
-
-	[DRM_IOCTL_NR(DRM_IOCTL_SET_SAREA_CTX)] = { DRM(setsareactx), 1, 1 },
-	[DRM_IOCTL_NR(DRM_IOCTL_GET_SAREA_CTX)] = { DRM(getsareactx), 1, 0 },
-
-	[DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)]       = { DRM(addctx),      1, 1 },
-	[DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)]        = { DRM(rmctx),       1, 1 },
-	[DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)]       = { DRM(modctx),      1, 1 },
-	[DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)]       = { DRM(getctx),      1, 0 },
-	[DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)]    = { DRM(switchctx),   1, 1 },
-	[DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)]       = { DRM(newctx),      1, 1 },
-	[DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)]       = { DRM(resctx),      1, 0 },
-
-	[DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)]      = { DRM(adddraw),     1, 1 },
-	[DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)]       = { DRM(rmdraw),      1, 1 },
-
-	[DRM_IOCTL_NR(DRM_IOCTL_LOCK)]	        = { DRM(lock),        1, 0 },
-	[DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)]        = { DRM(unlock),      1, 0 },
-
-	[DRM_IOCTL_NR(DRM_IOCTL_FINISH)]        = { DRM(noop),      1, 0 },
-
-	[DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)]      = { DRM(addbufs),     1, 1 },
-	[DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS)]     = { DRM(markbufs),    1, 1 },
-	[DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)]     = { DRM(infobufs),    1, 0 },
-	[DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)]      = { DRM(mapbufs),     1, 0 },
-	[DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)]     = { DRM(freebufs),    1, 0 },
-	/* The DRM_IOCTL_DMA ioctl should be defined by the driver. */
-
-	[DRM_IOCTL_NR(DRM_IOCTL_CONTROL)]       = { DRM(control),     1, 1 },
-
-#if __OS_HAS_AGP
-	[DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)]   = { DRM(agp_acquire), 1, 1 },
-	[DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)]   = { DRM(agp_release), 1, 1 },
-	[DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)]    = { DRM(agp_enable),  1, 1 },
-	[DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)]      = { DRM(agp_info),    1, 0 },
-	[DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)]     = { DRM(agp_alloc),   1, 1 },
-	[DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)]      = { DRM(agp_free),    1, 1 },
-	[DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)]      = { DRM(agp_bind),    1, 1 },
-	[DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)]    = { DRM(agp_unbind),  1, 1 },
-#endif
-
-	[DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC)]      = { DRM(sg_alloc),    1, 1 },
-	[DRM_IOCTL_NR(DRM_IOCTL_SG_FREE)]       = { DRM(sg_free),     1, 1 },
-
-	[DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK)]   = { DRM(wait_vblank), 0, 0 },
-
-	DRIVER_IOCTLS
-};
-
-#define DRIVER_IOCTL_COUNT	DRM_ARRAY_SIZE( DRM(ioctls) )
-
-#ifdef MODULE
-static char *drm_opts = NULL;
-#endif
-
-MODULE_AUTHOR( DRIVER_AUTHOR );
-MODULE_DESCRIPTION( DRIVER_DESC );
-MODULE_PARM( drm_opts, "s" );
-MODULE_LICENSE("GPL and additional rights");
-
-static int DRM(setup)( drm_device_t *dev )
-{
-	int i;
-	int ret;
-
-	if (dev->fn_tbl.presetup)
-	{
-		ret=dev->fn_tbl.presetup(dev);
-		if (ret!=0) 
-			return ret;
-	}
-
-	atomic_set( &dev->ioctl_count, 0 );
-	atomic_set( &dev->vma_count, 0 );
-	dev->buf_use = 0;
-	atomic_set( &dev->buf_alloc, 0 );
-
-	if (drm_core_check_feature(dev, DRIVER_HAVE_DMA))
-	{
-		i = DRM(dma_setup)( dev );
-		if ( i < 0 )
-			return i;
-	}
-
-	for ( i = 0 ; i < DRM_ARRAY_SIZE(dev->counts) ; i++ )
-		atomic_set( &dev->counts[i], 0 );
-
-	for ( i = 0 ; i < DRM_HASH_SIZE ; i++ ) {
-		dev->magiclist[i].head = NULL;
-		dev->magiclist[i].tail = NULL;
-	}
-
-	dev->maplist = DRM(alloc)(sizeof(*dev->maplist),
-				  DRM_MEM_MAPS);
-	if(dev->maplist == NULL) return -ENOMEM;
-	memset(dev->maplist, 0, sizeof(*dev->maplist));
-	INIT_LIST_HEAD(&dev->maplist->head);
-
-	dev->ctxlist = DRM(alloc)(sizeof(*dev->ctxlist),
-				  DRM_MEM_CTXLIST);
-	if(dev->ctxlist == NULL) return -ENOMEM;
-	memset(dev->ctxlist, 0, sizeof(*dev->ctxlist));
-	INIT_LIST_HEAD(&dev->ctxlist->head);
-
-	dev->vmalist = NULL;
-	dev->sigdata.lock = dev->lock.hw_lock = NULL;
-	init_waitqueue_head( &dev->lock.lock_queue );
-	dev->queue_count = 0;
-	dev->queue_reserved = 0;
-	dev->queue_slots = 0;
-	dev->queuelist = NULL;
-	dev->irq_enabled = 0;
-	dev->context_flag = 0;
-	dev->interrupt_flag = 0;
-	dev->dma_flag = 0;
-	dev->last_context = 0;
-	dev->last_switch = 0;
-	dev->last_checked = 0;
-	init_waitqueue_head( &dev->context_wait );
-	dev->if_version = 0;
-
-	dev->ctx_start = 0;
-	dev->lck_start = 0;
-
-	dev->buf_rp = dev->buf;
-	dev->buf_wp = dev->buf;
-	dev->buf_end = dev->buf + DRM_BSZ;
-	dev->buf_async = NULL;
-	init_waitqueue_head( &dev->buf_readers );
-	init_waitqueue_head( &dev->buf_writers );
-
-	DRM_DEBUG( "\n" );
-
-	/*
-	 * The kernel's context could be created here, but is now created
-	 * in drm_dma_enqueue.	This is more resource-efficient for
-	 * hardware that does not do DMA, but may mean that
-	 * drm_select_queue fails between the time the interrupt is
-	 * initialized and the time the queues are initialized.
-	 */
-	if (dev->fn_tbl.postsetup)
-		dev->fn_tbl.postsetup(dev);
-
-	return 0;
-}
-
-
-/**
- * Take down the DRM device.
- *
- * \param dev DRM device structure.
- *
- * Frees every resource in \p dev.
- *
- * \sa drm_device and setup().
- */
-static int DRM(takedown)( drm_device_t *dev )
-{
-	drm_magic_entry_t *pt, *next;
-	drm_map_t *map;
-	drm_map_list_t *r_list;
-	struct list_head *list, *list_next;
-	drm_vma_entry_t *vma, *vma_next;
-	int i;
-
-	DRM_DEBUG( "\n" );
-
-	if (dev->fn_tbl.pretakedown)
-	  dev->fn_tbl.pretakedown(dev);
-
-	if ( dev->irq_enabled ) DRM(irq_uninstall)( dev );
-
-	down( &dev->struct_sem );
-	del_timer( &dev->timer );
-
-	if ( dev->devname ) {
-		DRM(free)( dev->devname, strlen( dev->devname ) + 1,
-			   DRM_MEM_DRIVER );
-		dev->devname = NULL;
-	}
-
-	if ( dev->unique ) {
-		DRM(free)( dev->unique, strlen( dev->unique ) + 1,
-			   DRM_MEM_DRIVER );
-		dev->unique = NULL;
-		dev->unique_len = 0;
-	}
-				/* Clear pid list */
-	for ( i = 0 ; i < DRM_HASH_SIZE ; i++ ) {
-		for ( pt = dev->magiclist[i].head ; pt ; pt = next ) {
-			next = pt->next;
-			DRM(free)( pt, sizeof(*pt), DRM_MEM_MAGIC );
-		}
-		dev->magiclist[i].head = dev->magiclist[i].tail = NULL;
-	}
-
-				/* Clear AGP information */
-	if (drm_core_has_AGP(dev) && dev->agp) {
-		drm_agp_mem_t *entry;
-		drm_agp_mem_t *nexte;
-
-				/* Remove AGP resources, but leave dev->agp
-                                   intact until drv_cleanup is called. */
-		for ( entry = dev->agp->memory ; entry ; entry = nexte ) {
-			nexte = entry->next;
-			if ( entry->bound ) DRM(unbind_agp)( entry->memory );
-			DRM(free_agp)( entry->memory, entry->pages );
-			DRM(free)( entry, sizeof(*entry), DRM_MEM_AGPLISTS );
-		}
-		dev->agp->memory = NULL;
-
-		if ( dev->agp->acquired ) DRM(agp_do_release)();
-
-		dev->agp->acquired = 0;
-		dev->agp->enabled  = 0;
-	}
-
-				/* Clear vma list (only built for debugging) */
-	if ( dev->vmalist ) {
-		for ( vma = dev->vmalist ; vma ; vma = vma_next ) {
-			vma_next = vma->next;
-			DRM(free)( vma, sizeof(*vma), DRM_MEM_VMAS );
-		}
-		dev->vmalist = NULL;
-	}
-
-	if( dev->maplist ) {
-		list_for_each_safe( list, list_next, &dev->maplist->head ) {
-			r_list = (drm_map_list_t *)list;
-
-			if ( ( map = r_list->map ) ) {
-				switch ( map->type ) {
-				case _DRM_REGISTERS:
-				case _DRM_FRAME_BUFFER:
-					if (drm_core_has_MTRR(dev)) {
-						if ( map->mtrr >= 0 ) {
-							int retcode;
-							retcode = mtrr_del( map->mtrr,
-									    map->offset,
-									    map->size );
-							DRM_DEBUG( "mtrr_del=%d\n", retcode );
-						}
-					}
-					DRM(ioremapfree)( map->handle, map->size, dev );
-					break;
-				case _DRM_SHM:
-					vfree(map->handle);
-					break;
-
-				case _DRM_AGP:
-					/* Do nothing here, because this is all
-					 * handled in the AGP/GART driver.
-					 */
-					break;
-				case _DRM_SCATTER_GATHER:
-					/* Handle it */
-					if (drm_core_check_feature(dev, DRIVER_SG) && dev->sg) {
-						DRM(sg_cleanup)(dev->sg);
-						dev->sg = NULL;
-					}
-					break;
-				}
-				DRM(free)(map, sizeof(*map), DRM_MEM_MAPS);
-			}
-			list_del( list );
-			DRM(free)(r_list, sizeof(*r_list), DRM_MEM_MAPS);
- 		}
-		DRM(free)(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS);
-		dev->maplist = NULL;
- 	}
-
-	if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE) && dev->queuelist ) {
-		for ( i = 0 ; i < dev->queue_count ; i++ ) {
-			if ( dev->queuelist[i] ) {
-				DRM(free)( dev->queuelist[i],
-					  sizeof(*dev->queuelist[0]),
-					  DRM_MEM_QUEUES );
-				dev->queuelist[i] = NULL;
-			}
-		}
-		DRM(free)( dev->queuelist,
-			  dev->queue_slots * sizeof(*dev->queuelist),
-			  DRM_MEM_QUEUES );
-		dev->queuelist = NULL;
-	}
-	dev->queue_count = 0;
-
-	if (drm_core_check_feature(dev, DRIVER_HAVE_DMA))
-		DRM(dma_takedown)( dev );
-
-	if ( dev->lock.hw_lock ) {
-		dev->sigdata.lock = dev->lock.hw_lock = NULL; /* SHM removed */
-		dev->lock.filp = NULL;
-		wake_up_interruptible( &dev->lock.lock_queue );
-	}
-	up( &dev->struct_sem );
-
-	return 0;
-}
-
-static void DRM(init_fn_table)(struct drm_device *dev)
-{
-	dev->fn_tbl.reclaim_buffers = DRM(core_reclaim_buffers);
-	dev->fn_tbl.get_map_ofs = DRM(core_get_map_ofs);
-	dev->fn_tbl.get_reg_ofs = DRM(core_get_reg_ofs);
-}
-
-#include "drm_pciids.h"
-
-static struct pci_device_id DRM(pciidlist)[] = {
-	DRM(PCI_IDS)
-};
-
-static int DRM(probe)(struct pci_dev *pdev)
-{
-	drm_device_t *dev;
-	int retcode;
-	int i;
-	int is_compat = 0;
-
-	DRM_DEBUG( "\n" );
-
-	for (i = 0; DRM(pciidlist)[i].vendor != 0; i++) {
-		if ((DRM(pciidlist)[i].vendor == pdev->vendor) &&
-		    (DRM(pciidlist)[i].device == pdev->device)) {
-			is_compat = 1;
-		}
-	}
-	if (is_compat == 0)
-		return -ENODEV;
-
-	if (DRM(numdevs) >= MAX_DEVICES)
-		return -ENODEV;
-
-	if ((retcode=pci_enable_device(pdev)))
-		return retcode;
-
-	dev = &(DRM(device)[DRM(numdevs)]);
-
-	memset( (void *)dev, 0, sizeof(*dev) );
-	dev->count_lock = SPIN_LOCK_UNLOCKED;
-	init_timer( &dev->timer );
-	sema_init( &dev->struct_sem, 1 );
-	sema_init( &dev->ctxlist_sem, 1 );
-
-	if ((dev->minor = DRM(stub_register)(DRIVER_NAME, &DRM(fops),dev)) < 0)
-		return -EPERM;
-	dev->device = MKDEV(DRM_MAJOR, dev->minor );
-	dev->name   = DRIVER_NAME;
-
-	dev->pdev   = pdev;
-#ifdef __alpha__
-	dev->hose   = pdev->sysdata;
-	dev->pci_domain = dev->hose->bus->number;
-#else
-	dev->pci_domain = 0;
-#endif
-	dev->pci_bus = pdev->bus->number;
-	dev->pci_slot = PCI_SLOT(pdev->devfn);
-	dev->pci_func = PCI_FUNC(pdev->devfn);
-	dev->irq = pdev->irq;
-
-	/* dev_priv_size can be changed by a driver in driver_register_fns */
-	dev->dev_priv_size = sizeof(u32);
-
-	/* the DRM has 6 basic counters - drivers add theirs in register_fns */
-	dev->counters = 6;
-	dev->types[0]  = _DRM_STAT_LOCK;
-	dev->types[1]  = _DRM_STAT_OPENS;
-	dev->types[2]  = _DRM_STAT_CLOSES;
-	dev->types[3]  = _DRM_STAT_IOCTLS;
-	dev->types[4]  = _DRM_STAT_LOCKS;
-	dev->types[5]  = _DRM_STAT_UNLOCKS;
-
-	DRM(init_fn_table)(dev);
-
-	DRM(driver_register_fns)(dev);
-
-	if (dev->fn_tbl.preinit)
-	  dev->fn_tbl.preinit(dev);
-
-	if (drm_core_has_AGP(dev))
-	{
-		dev->agp = DRM(agp_init)();
-		if (drm_core_check_feature(dev, DRIVER_REQUIRE_AGP) && (dev->agp == NULL)) {
-			DRM_ERROR( "Cannot initialize the agpgart module.\n" );
-			DRM(stub_unregister)(dev->minor);
-			DRM(takedown)( dev );
-			return -EINVAL;
-		}
-		if (drm_core_has_MTRR(dev)) {
-			if (dev->agp)
-				dev->agp->agp_mtrr = mtrr_add( dev->agp->agp_info.aper_base,
-							       dev->agp->agp_info.aper_size*1024*1024,
-							       MTRR_TYPE_WRCOMB,
-							       1 );
-		}
-	}
-
-	retcode = DRM(ctxbitmap_init)( dev );
-	if( retcode ) {
-		DRM_ERROR( "Cannot allocate memory for context bitmap.\n" );
-		DRM(stub_unregister)(dev->minor);
-		DRM(takedown)( dev );
-		return retcode;
-	}
-
-	DRM(numdevs)++; /* no errors, mark it reserved */
-	
-	DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d: %s\n",
-		DRIVER_NAME,
-		DRIVER_MAJOR,
-		DRIVER_MINOR,
-		DRIVER_PATCHLEVEL,
-		DRIVER_DATE,
-		dev->minor,
-		pci_pretty_name(pdev));
-
-	if (dev->fn_tbl.postinit)
-	  dev->fn_tbl.postinit(dev);
-
-	return 0;
-}
-
-/**
- * Module initialization. Called via init_module at module load time, or via
- * linux/init/main.c (this is not currently supported).
- *
- * \return zero on success or a negative number on failure.
- *
- * Initializes an array of drm_device structures, and attempts to
- * initialize all available devices, using consecutive minors, registering the
- * stubs and initializing the AGP device.
- * 
- * Expands the \c DRIVER_PREINIT and \c DRIVER_POST_INIT macros before and
- * after the initialization for driver customization.
- */
-static int __init drm_init( void )
-{
-	struct pci_dev *pdev = NULL;
-
-	DRM_DEBUG( "\n" );
-
-#ifdef MODULE
-	DRM(parse_options)( drm_opts );
-#endif
-
-	DRM(mem_init)();
-
-	for_each_pci_dev(pdev) 
-		DRM(probe)(pdev);
-	return 0;
-}
-
-/**
- * Called via cleanup_module() at module unload time.
- *
- * Cleans up all DRM device, calling takedown().
- * 
- * \sa drm_init().
- */
-static void __exit drm_cleanup( void )
-{
-	drm_device_t *dev;
-	int i;
-
-	DRM_DEBUG( "\n" );
-
-	for (i = DRM(numdevs) - 1; i >= 0; i--) {
-		dev = &(DRM(device)[i]);
-		if ( DRM(stub_unregister)(dev->minor) ) {
-			DRM_ERROR( "Cannot unload module\n" );
-		} else {
-			DRM_DEBUG("minor %d unregistered\n", dev->minor);
-			if (i == 0) {
-				DRM_INFO( "Module unloaded\n" );
-			}
-		}
-
-		DRM(ctxbitmap_cleanup)( dev );
-
-		if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) &&
-		    dev->agp && dev->agp->agp_mtrr >= 0) {
-			int retval;
-			retval = mtrr_del( dev->agp->agp_mtrr,
-				   dev->agp->agp_info.aper_base,
-				   dev->agp->agp_info.aper_size*1024*1024 );
-			DRM_DEBUG( "mtrr_del=%d\n", retval );
-		}
-
-		DRM(takedown)( dev );
-
-		if (drm_core_has_AGP(dev) && dev->agp ) {
-			DRM(agp_uninit)();
-			DRM(free)( dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS );
-			dev->agp = NULL;
-		}
-
-		if (dev->fn_tbl.postcleanup)
-		  dev->fn_tbl.postcleanup(dev);
-
-	}
-	DRM(numdevs) = 0;
-}
-
-module_init( drm_init );
-module_exit( drm_cleanup );
-
-
-/**
- * Get version information
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg user argument, pointing to a drm_version structure.
- * \return zero on success or negative number on failure.
- *
- * Fills in the version information in \p arg.
- */
-int DRM(version)( struct inode *inode, struct file *filp,
-		  unsigned int cmd, unsigned long arg )
-{
-	drm_version_t __user *argp = (void __user *)arg;
-	drm_version_t version;
-	int len;
-
-	if ( copy_from_user( &version, argp, sizeof(version) ) )
-		return -EFAULT;
-
-#define DRM_COPY( name, value )						\
-	len = strlen( value );						\
-	if ( len > name##_len ) len = name##_len;			\
-	name##_len = strlen( value );					\
-	if ( len && name ) {						\
-		if ( copy_to_user( name, value, len ) )			\
-			return -EFAULT;					\
-	}
-
-	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 );
-
-	if ( copy_to_user( argp, &version, sizeof(version) ) )
-		return -EFAULT;
-	return 0;
-}
-
-/**
- * Open file.
- * 
- * \param inode device inode
- * \param filp file pointer.
- * \return zero on success or a negative number on failure.
- *
- * Searches the DRM device with the same minor number, calls open_helper(), and
- * increments the device open count. If the open count was previous at zero,
- * i.e., it's the first that the device is open, then calls setup().
- */
-int DRM(open)( struct inode *inode, struct file *filp )
-{
-	drm_device_t *dev = NULL;
-	int retcode = 0;
-	int i;
-
-	for (i = 0; i < DRM(numdevs); i++) {
-		if (iminor(inode) == DRM(device)[i].minor) {
-			dev = &(DRM(device)[i]);
-			break;
-		}
-	}
-	if (!dev) {
-		return -ENODEV;
-	}
-
-	retcode = DRM(open_helper)( inode, filp, dev );
-	if ( !retcode ) {
-		atomic_inc( &dev->counts[_DRM_STAT_OPENS] );
-		spin_lock( &dev->count_lock );
-		if ( !dev->open_count++ ) {
-			spin_unlock( &dev->count_lock );
-			return DRM(setup)( dev );
-		}
-		spin_unlock( &dev->count_lock );
-	}
-
-	return retcode;
-}
-
-/**
- * Release file.
- *
- * \param inode device inode
- * \param filp file pointer.
- * \return zero on success or a negative number on failure.
- *
- * If the hardware lock is held then free it, and take it again for the kernel
- * context since it's necessary to reclaim buffers. Unlink the file private
- * data from its list and free it. Decreases the open count and if it reaches
- * zero calls takedown().
- */
-int DRM(release)( struct inode *inode, struct file *filp )
-{
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev;
-	int retcode = 0;
-
-	lock_kernel();
-	dev = priv->dev;
-
-	DRM_DEBUG( "open_count = %d\n", dev->open_count );
-
-	if (dev->fn_tbl.prerelease)
-		dev->fn_tbl.prerelease(dev, filp);
-
-	/* ========================================================
-	 * Begin inline drm_release
-	 */
-
-	DRM_DEBUG( "pid = %d, device = 0x%lx, open_count = %d\n",
-		   current->pid, (long)old_encode_dev(dev->device), dev->open_count );
-
-	if ( priv->lock_count && dev->lock.hw_lock &&
-	     _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) &&
-	     dev->lock.filp == filp ) {
-		DRM_DEBUG( "File %p released, freeing lock for context %d\n",
-			filp,
-			_DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock) );
-		
-		if (dev->fn_tbl.release)
-			dev->fn_tbl.release(dev, filp);
-
-		DRM(lock_free)( dev, &dev->lock.hw_lock->lock,
-				_DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock) );
-
-				/* FIXME: may require heavy-handed reset of
-                                   hardware at this point, possibly
-                                   processed via a callback to the X
-                                   server. */
-	}
-	else if ( dev->fn_tbl.release && priv->lock_count && dev->lock.hw_lock ) {
-		/* The lock is required to reclaim buffers */
-		DECLARE_WAITQUEUE( entry, current );
-
-		add_wait_queue( &dev->lock.lock_queue, &entry );
-		for (;;) {
-			__set_current_state(TASK_INTERRUPTIBLE);
-			if ( !dev->lock.hw_lock ) {
-				/* Device has been unregistered */
-				retcode = -EINTR;
-				break;
-			}
-			if ( DRM(lock_take)( &dev->lock.hw_lock->lock,
-					     DRM_KERNEL_CONTEXT ) ) {
-				dev->lock.filp	    = filp;
-				dev->lock.lock_time = jiffies;
-                                atomic_inc( &dev->counts[_DRM_STAT_LOCKS] );
-				break;	/* Got lock */
-			}
-				/* Contention */
-			schedule();
-			if ( signal_pending( current ) ) {
-				retcode = -ERESTARTSYS;
-				break;
-			}
-		}
-		__set_current_state(TASK_RUNNING);
-		remove_wait_queue( &dev->lock.lock_queue, &entry );
-		if( !retcode ) {
-			if (dev->fn_tbl.release)
-				dev->fn_tbl.release(dev, filp);
-			DRM(lock_free)( dev, &dev->lock.hw_lock->lock,
-					DRM_KERNEL_CONTEXT );
-		}
-	}
-	
-	if (drm_core_check_feature(dev, DRIVER_HAVE_DMA))
-	{
-		dev->fn_tbl.reclaim_buffers(filp);
-	}
-
-	DRM(fasync)( -1, filp, 0 );
-
-	down( &dev->ctxlist_sem );
-	if ( !list_empty( &dev->ctxlist->head ) ) {
-		drm_ctx_list_t *pos, *n;
-
-		list_for_each_entry_safe( pos, n, &dev->ctxlist->head, head ) {
-			if ( pos->tag == priv &&
-			     pos->handle != DRM_KERNEL_CONTEXT ) {
-				if (dev->fn_tbl.context_dtor)
-					dev->fn_tbl.context_dtor(dev, pos->handle);
-
-				DRM(ctxbitmap_free)( dev, pos->handle );
-
-				list_del( &pos->head );
-				DRM(free)( pos, sizeof(*pos), DRM_MEM_CTXLIST );
-				--dev->ctx_count;
-			}
-		}
-	}
-	up( &dev->ctxlist_sem );
-
-	down( &dev->struct_sem );
-	if ( priv->remove_auth_on_close == 1 ) {
-		drm_file_t *temp = dev->file_first;
-		while ( temp ) {
-			temp->authenticated = 0;
-			temp = temp->next;
-		}
-	}
-	if ( priv->prev ) {
-		priv->prev->next = priv->next;
-	} else {
-		dev->file_first	 = priv->next;
-	}
-	if ( priv->next ) {
-		priv->next->prev = priv->prev;
-	} else {
-		dev->file_last	 = priv->prev;
-	}
-	up( &dev->struct_sem );
-	
-	if (dev->fn_tbl.free_filp_priv)
-		dev->fn_tbl.free_filp_priv(dev, priv);
-
-	DRM(free)( priv, sizeof(*priv), DRM_MEM_FILES );
-
-	/* ========================================================
-	 * End inline drm_release
-	 */
-
-	atomic_inc( &dev->counts[_DRM_STAT_CLOSES] );
-	spin_lock( &dev->count_lock );
-	if ( !--dev->open_count ) {
-		if ( atomic_read( &dev->ioctl_count ) || dev->blocked ) {
-			DRM_ERROR( "Device busy: %d %d\n",
-				   atomic_read( &dev->ioctl_count ),
-				   dev->blocked );
-			spin_unlock( &dev->count_lock );
-			unlock_kernel();
-			return -EBUSY;
-		}
-		spin_unlock( &dev->count_lock );
-		unlock_kernel();
-		return DRM(takedown)( dev );
-	}
-	spin_unlock( &dev->count_lock );
-
-	unlock_kernel();
-
-	return retcode;
-}
-
-/** 
- * Called whenever a process performs an ioctl on /dev/drm.
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg user argument.
- * \return zero on success or negative number on failure.
- *
- * Looks up the ioctl function in the ::ioctls table, checking for root
- * previleges if so required, and dispatches to the respective function.
- */
-int DRM(ioctl)( struct inode *inode, struct file *filp,
-		unsigned int cmd, unsigned long arg )
-{
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
-	drm_ioctl_desc_t *ioctl;
-	drm_ioctl_t *func;
-	int nr = DRM_IOCTL_NR(cmd);
-	int retcode = 0;
-
-	atomic_inc( &dev->ioctl_count );
-	atomic_inc( &dev->counts[_DRM_STAT_IOCTLS] );
-	++priv->ioctl_count;
-
-	DRM_DEBUG( "pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%lx, auth=%d\n",
-		   current->pid, cmd, nr, (long)old_encode_dev(dev->device), 
-		   priv->authenticated );
-
-	if ( nr >= DRIVER_IOCTL_COUNT ) {
-		retcode = -EINVAL;
-	} else {
-		ioctl = &DRM(ioctls)[nr];
-		func = ioctl->func;
-
-		if ( !func ) {
-			DRM_DEBUG( "no function\n" );
-			retcode = -EINVAL;
-		} else if ( ( ioctl->root_only && !capable( CAP_SYS_ADMIN ) )||
-			    ( ioctl->auth_needed && !priv->authenticated ) ) {
-			retcode = -EACCES;
-		} else {
-			retcode = func( inode, filp, cmd, arg );
-		}
-	}
-
-	atomic_dec( &dev->ioctl_count );
-	return retcode;
-}
-
-/** 
- * Lock ioctl.
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg user argument, pointing to a drm_lock structure.
- * \return zero on success or negative number on failure.
- *
- * Add the current task to the lock wait queue, and attempt to take to lock.
- */
-int DRM(lock)( struct inode *inode, struct file *filp,
-	       unsigned int cmd, unsigned long arg )
-{
-        drm_file_t *priv = filp->private_data;
-        drm_device_t *dev = priv->dev;
-        DECLARE_WAITQUEUE( entry, current );
-        drm_lock_t lock;
-        int ret = 0;
-
-	++priv->lock_count;
-
-        if ( copy_from_user( &lock, (drm_lock_t __user *)arg, sizeof(lock) ) )
-		return -EFAULT;
-
-        if ( lock.context == DRM_KERNEL_CONTEXT ) {
-                DRM_ERROR( "Process %d using kernel context %d\n",
-			   current->pid, lock.context );
-                return -EINVAL;
-        }
-
-        DRM_DEBUG( "%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n",
-		   lock.context, current->pid,
-		   dev->lock.hw_lock->lock, lock.flags );
-
-	if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE))
-		if ( lock.context < 0 )
-			return -EINVAL;
-
-	add_wait_queue( &dev->lock.lock_queue, &entry );
-	for (;;) {
-		__set_current_state(TASK_INTERRUPTIBLE);
-		if ( !dev->lock.hw_lock ) {
-			/* Device has been unregistered */
-			ret = -EINTR;
-			break;
-		}
-		if ( DRM(lock_take)( &dev->lock.hw_lock->lock,
-				     lock.context ) ) {
-			dev->lock.filp      = filp;
-			dev->lock.lock_time = jiffies;
-			atomic_inc( &dev->counts[_DRM_STAT_LOCKS] );
-			break;  /* Got lock */
-		}
-		
-		/* Contention */
-		schedule();
-		if ( signal_pending( current ) ) {
-			ret = -ERESTARTSYS;
-			break;
-		}
-	}
-	__set_current_state(TASK_RUNNING);
-	remove_wait_queue( &dev->lock.lock_queue, &entry );
-
-	sigemptyset( &dev->sigmask );
-	sigaddset( &dev->sigmask, SIGSTOP );
-	sigaddset( &dev->sigmask, SIGTSTP );
-	sigaddset( &dev->sigmask, SIGTTIN );
-	sigaddset( &dev->sigmask, SIGTTOU );
-	dev->sigdata.context = lock.context;
-	dev->sigdata.lock    = dev->lock.hw_lock;
-	block_all_signals( DRM(notifier),
-			   &dev->sigdata, &dev->sigmask );
-	
-	if (dev->fn_tbl.dma_ready && (lock.flags & _DRM_LOCK_READY))
-		dev->fn_tbl.dma_ready(dev);
-	
-	if ( dev->fn_tbl.dma_quiescent && (lock.flags & _DRM_LOCK_QUIESCENT ))
-		return dev->fn_tbl.dma_quiescent(dev);
-	
-	/* dev->fn_tbl.kernel_context_switch isn't used by any of the x86 
-	 *  drivers but is used by the Sparc driver.
-	 */
-	
-	if (dev->fn_tbl.kernel_context_switch && 
-	    dev->last_context != lock.context) {
-	  dev->fn_tbl.kernel_context_switch(dev, dev->last_context, 
-					    lock.context);
-	}
-        DRM_DEBUG( "%d %s\n", lock.context, ret ? "interrupted" : "has lock" );
-
-        return ret;
-}
-
-/** 
- * Unlock ioctl.
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg user argument, pointing to a drm_lock structure.
- * \return zero on success or negative number on failure.
- *
- * Transfer and free the lock.
- */
-int DRM(unlock)( struct inode *inode, struct file *filp,
-		 unsigned int cmd, unsigned long arg )
-{
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
-	drm_lock_t lock;
-
-	if ( copy_from_user( &lock, (drm_lock_t __user *)arg, sizeof(lock) ) )
-		return -EFAULT;
-
-	if ( lock.context == DRM_KERNEL_CONTEXT ) {
-		DRM_ERROR( "Process %d using kernel context %d\n",
-			   current->pid, lock.context );
-		return -EINVAL;
-	}
-
-	atomic_inc( &dev->counts[_DRM_STAT_UNLOCKS] );
-
-	/* kernel_context_switch isn't used by any of the x86 drm
-	 * modules but is required by the Sparc driver.
-	 */
-	if (dev->fn_tbl.kernel_context_switch_unlock)
-		dev->fn_tbl.kernel_context_switch_unlock(dev, &lock);
-	else {
-		DRM(lock_transfer)( dev, &dev->lock.hw_lock->lock, 
-				    DRM_KERNEL_CONTEXT );
-		
-		if ( DRM(lock_free)( dev, &dev->lock.hw_lock->lock,
-				     DRM_KERNEL_CONTEXT ) ) {
-			DRM_ERROR( "\n" );
-		}
-	}
-
-	unblock_all_signals();
-	return 0;
-}
diff -Nru a/drivers/char/drm/drm_fops.c b/drivers/char/drm/drm_fops.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/char/drm/drm_fops.c	2005-03-01 23:38:58 -08:00
@@ -0,0 +1,449 @@
+/**
+ * \file drm_fops.h 
+ * File operations for DRM
+ * 
+ * \author Rickard E. (Rik) Faith <faith@valinux.com>
+ * \author Daryll Strauss <daryll@valinux.com>
+ * \author Gareth Hughes <gareth@valinux.com>
+ */
+
+/*
+ * Created: Mon Jan  4 08:58:31 1999 by faith@valinux.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "drmP.h"
+#include <linux/poll.h>
+
+static int drm_setup( drm_device_t *dev )
+{
+	int i;
+	int ret;
+
+	if (dev->driver->presetup)
+	{
+		ret=dev->driver->presetup(dev);
+		if (ret!=0) 
+			return ret;
+	}
+
+	atomic_set( &dev->ioctl_count, 0 );
+	atomic_set( &dev->vma_count, 0 );
+	dev->buf_use = 0;
+	atomic_set( &dev->buf_alloc, 0 );
+
+	if (drm_core_check_feature(dev, DRIVER_HAVE_DMA))
+	{
+		i = drm_dma_setup( dev );
+		if ( i < 0 )
+			return i;
+	}
+
+	for ( i = 0 ; i < DRM_ARRAY_SIZE(dev->counts) ; i++ )
+		atomic_set( &dev->counts[i], 0 );
+
+	for ( i = 0 ; i < DRM_HASH_SIZE ; i++ ) {
+		dev->magiclist[i].head = NULL;
+		dev->magiclist[i].tail = NULL;
+	}
+
+	dev->maplist = drm_alloc(sizeof(*dev->maplist),
+				  DRM_MEM_MAPS);
+	if(dev->maplist == NULL) return -ENOMEM;
+	memset(dev->maplist, 0, sizeof(*dev->maplist));
+	INIT_LIST_HEAD(&dev->maplist->head);
+
+	dev->ctxlist = drm_alloc(sizeof(*dev->ctxlist),
+				  DRM_MEM_CTXLIST);
+	if(dev->ctxlist == NULL) return -ENOMEM;
+	memset(dev->ctxlist, 0, sizeof(*dev->ctxlist));
+	INIT_LIST_HEAD(&dev->ctxlist->head);
+
+	dev->vmalist = NULL;
+	dev->sigdata.lock = dev->lock.hw_lock = NULL;
+	init_waitqueue_head( &dev->lock.lock_queue );
+	dev->queue_count = 0;
+	dev->queue_reserved = 0;
+	dev->queue_slots = 0;
+	dev->queuelist = NULL;
+	dev->irq_enabled = 0;
+	dev->context_flag = 0;
+	dev->interrupt_flag = 0;
+	dev->dma_flag = 0;
+	dev->last_context = 0;
+	dev->last_switch = 0;
+	dev->last_checked = 0;
+	init_waitqueue_head( &dev->context_wait );
+	dev->if_version = 0;
+
+	dev->ctx_start = 0;
+	dev->lck_start = 0;
+
+	dev->buf_rp = dev->buf;
+	dev->buf_wp = dev->buf;
+	dev->buf_end = dev->buf + DRM_BSZ;
+	dev->buf_async = NULL;
+	init_waitqueue_head( &dev->buf_readers );
+	init_waitqueue_head( &dev->buf_writers );
+
+	DRM_DEBUG( "\n" );
+
+	/*
+	 * The kernel's context could be created here, but is now created
+	 * in drm_dma_enqueue.	This is more resource-efficient for
+	 * hardware that does not do DMA, but may mean that
+	 * drm_select_queue fails between the time the interrupt is
+	 * initialized and the time the queues are initialized.
+	 */
+	if (dev->driver->postsetup)
+		dev->driver->postsetup(dev);
+
+	return 0;
+}
+
+/**
+ * Open file.
+ * 
+ * \param inode device inode
+ * \param filp file pointer.
+ * \return zero on success or a negative number on failure.
+ *
+ * Searches the DRM device with the same minor number, calls open_helper(), and
+ * increments the device open count. If the open count was previous at zero,
+ * i.e., it's the first that the device is open, then calls setup().
+ */
+int drm_open( struct inode *inode, struct file *filp )
+{
+	drm_device_t *dev = NULL;
+	int minor = iminor(inode);
+	int retcode = 0;
+
+	if (!((minor >= 0) && (minor < drm_cards_limit)))
+		return -ENODEV;
+		
+	dev = drm_minors[minor].dev;
+	if (!dev)
+		return -ENODEV;
+	
+	retcode = drm_open_helper( inode, filp, dev );
+	if ( !retcode ) {
+		atomic_inc( &dev->counts[_DRM_STAT_OPENS] );
+		spin_lock( &dev->count_lock );
+		if ( !dev->open_count++ ) {
+			spin_unlock( &dev->count_lock );
+			return drm_setup( dev );
+		}
+		spin_unlock( &dev->count_lock );
+	}
+
+	return retcode;
+}
+EXPORT_SYMBOL(drm_open);
+
+/**
+ * Release file.
+ *
+ * \param inode device inode
+ * \param filp file pointer.
+ * \return zero on success or a negative number on failure.
+ *
+ * If the hardware lock is held then free it, and take it again for the kernel
+ * context since it's necessary to reclaim buffers. Unlink the file private
+ * data from its list and free it. Decreases the open count and if it reaches
+ * zero calls takedown().
+ */
+int drm_release( struct inode *inode, struct file *filp )
+{
+	drm_file_t *priv = filp->private_data;
+	drm_device_t *dev;
+	int retcode = 0;
+
+	lock_kernel();
+	dev = priv->dev;
+
+	DRM_DEBUG( "open_count = %d\n", dev->open_count );
+
+	if (dev->driver->prerelease)
+		dev->driver->prerelease(dev, filp);
+
+	/* ========================================================
+	 * Begin inline drm_release
+	 */
+
+	DRM_DEBUG( "pid = %d, device = 0x%lx, open_count = %d\n",
+		   current->pid, (long)old_encode_dev(dev->device), dev->open_count );
+
+	if ( priv->lock_count && dev->lock.hw_lock &&
+	     _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) &&
+	     dev->lock.filp == filp ) {
+		DRM_DEBUG( "File %p released, freeing lock for context %d\n",
+			filp,
+			_DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock) );
+		
+		if (dev->driver->release)
+			dev->driver->release(dev, filp);
+
+		drm_lock_free( dev, &dev->lock.hw_lock->lock,
+				_DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock) );
+
+				/* FIXME: may require heavy-handed reset of
+                                   hardware at this point, possibly
+                                   processed via a callback to the X
+                                   server. */
+	}
+	else if ( dev->driver->release && priv->lock_count && dev->lock.hw_lock ) {
+		/* The lock is required to reclaim buffers */
+		DECLARE_WAITQUEUE( entry, current );
+
+		add_wait_queue( &dev->lock.lock_queue, &entry );
+		for (;;) {
+			__set_current_state(TASK_INTERRUPTIBLE);
+			if ( !dev->lock.hw_lock ) {
+				/* Device has been unregistered */
+				retcode = -EINTR;
+				break;
+			}
+			if ( drm_lock_take( &dev->lock.hw_lock->lock,
+					     DRM_KERNEL_CONTEXT ) ) {
+				dev->lock.filp	    = filp;
+				dev->lock.lock_time = jiffies;
+                                atomic_inc( &dev->counts[_DRM_STAT_LOCKS] );
+				break;	/* Got lock */
+			}
+				/* Contention */
+			schedule();
+			if ( signal_pending( current ) ) {
+				retcode = -ERESTARTSYS;
+				break;
+			}
+		}
+		__set_current_state(TASK_RUNNING);
+		remove_wait_queue( &dev->lock.lock_queue, &entry );
+		if( !retcode ) {
+			if (dev->driver->release)
+				dev->driver->release(dev, filp);
+			drm_lock_free( dev, &dev->lock.hw_lock->lock,
+					DRM_KERNEL_CONTEXT );
+		}
+	}
+	
+	if (drm_core_check_feature(dev, DRIVER_HAVE_DMA))
+	{
+		dev->driver->reclaim_buffers(dev, filp);
+	}
+
+	drm_fasync( -1, filp, 0 );
+
+	down( &dev->ctxlist_sem );
+	if ( !list_empty( &dev->ctxlist->head ) ) {
+		drm_ctx_list_t *pos, *n;
+
+		list_for_each_entry_safe( pos, n, &dev->ctxlist->head, head ) {
+			if ( pos->tag == priv &&
+			     pos->handle != DRM_KERNEL_CONTEXT ) {
+				if (dev->driver->context_dtor)
+					dev->driver->context_dtor(dev, pos->handle);
+
+				drm_ctxbitmap_free( dev, pos->handle );
+
+				list_del( &pos->head );
+				drm_free( pos, sizeof(*pos), DRM_MEM_CTXLIST );
+				--dev->ctx_count;
+			}
+		}
+	}
+	up( &dev->ctxlist_sem );
+
+	down( &dev->struct_sem );
+	if ( priv->remove_auth_on_close == 1 ) {
+		drm_file_t *temp = dev->file_first;
+		while ( temp ) {
+			temp->authenticated = 0;
+			temp = temp->next;
+		}
+	}
+	if ( priv->prev ) {
+		priv->prev->next = priv->next;
+	} else {
+		dev->file_first	 = priv->next;
+	}
+	if ( priv->next ) {
+		priv->next->prev = priv->prev;
+	} else {
+		dev->file_last	 = priv->prev;
+	}
+	up( &dev->struct_sem );
+	
+	if (dev->driver->free_filp_priv)
+		dev->driver->free_filp_priv(dev, priv);
+
+	drm_free( priv, sizeof(*priv), DRM_MEM_FILES );
+
+	/* ========================================================
+	 * End inline drm_release
+	 */
+
+	atomic_inc( &dev->counts[_DRM_STAT_CLOSES] );
+	spin_lock( &dev->count_lock );
+	if ( !--dev->open_count ) {
+		if ( atomic_read( &dev->ioctl_count ) || dev->blocked ) {
+			DRM_ERROR( "Device busy: %d %d\n",
+				   atomic_read( &dev->ioctl_count ),
+				   dev->blocked );
+			spin_unlock( &dev->count_lock );
+			unlock_kernel();
+			return -EBUSY;
+		}
+		spin_unlock( &dev->count_lock );
+		unlock_kernel();
+		return drm_takedown( dev );
+	}
+	spin_unlock( &dev->count_lock );
+
+	unlock_kernel();
+
+	return retcode;
+}
+EXPORT_SYMBOL(drm_release);
+
+/**
+ * Called whenever a process opens /dev/drm. 
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param dev device.
+ * \return zero on success or a negative number on failure.
+ * 
+ * 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)
+{
+	int	     minor = iminor(inode);
+	drm_file_t   *priv;
+	int ret;
+
+	if (filp->f_flags & O_EXCL)   return -EBUSY; /* No exclusive opens */
+	if (!drm_cpu_valid())        return -EINVAL;
+
+	DRM_DEBUG("pid = %d, minor = %d\n", current->pid, minor);
+
+	priv		    = drm_alloc(sizeof(*priv), DRM_MEM_FILES);
+	if(!priv) return -ENOMEM;
+
+	memset(priv, 0, sizeof(*priv));
+	filp->private_data  = priv;
+	priv->uid	    = current->euid;
+	priv->pid	    = current->pid;
+	priv->minor	    = minor;
+	priv->dev	    = dev;
+	priv->ioctl_count   = 0;
+	priv->authenticated = capable(CAP_SYS_ADMIN);
+	priv->lock_count    = 0;
+
+	if (dev->driver->open_helper) {
+		ret=dev->driver->open_helper(dev, priv);
+		if (ret < 0)
+			goto out_free;
+	}
+
+	down(&dev->struct_sem);
+	if (!dev->file_last) {
+		priv->next	= NULL;
+		priv->prev	= NULL;
+		dev->file_first = priv;
+		dev->file_last	= priv;
+	} else {
+		priv->next	     = NULL;
+		priv->prev	     = dev->file_last;
+		dev->file_last->next = priv;
+		dev->file_last	     = priv;
+	}
+	up(&dev->struct_sem);
+
+#ifdef __alpha__
+	/*
+	 * Default the hose
+	 */
+	if (!dev->hose) {
+		struct pci_dev *pci_dev;
+		pci_dev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, NULL);
+		if (pci_dev) {
+			dev->hose = pci_dev->sysdata;
+			pci_dev_put(pci_dev);
+		}
+		if (!dev->hose) {
+			struct pci_bus *b = pci_bus_b(pci_root_buses.next);
+			if (b) dev->hose = b->sysdata;
+		}
+	}
+#endif
+
+	return 0;
+out_free:
+	drm_free(priv, sizeof(*priv), DRM_MEM_FILES);
+	filp->private_data=NULL;
+	return ret;
+}
+
+/** No-op. */
+int drm_flush(struct file *filp)
+{
+	drm_file_t    *priv   = filp->private_data;
+	drm_device_t  *dev    = priv->dev;
+
+	DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n",
+		  current->pid, (long)old_encode_dev(dev->device), dev->open_count);
+	return 0;
+}
+EXPORT_SYMBOL(drm_flush);
+
+/** No-op. */
+int drm_fasync(int fd, struct file *filp, int on)
+{
+	drm_file_t    *priv   = filp->private_data;
+	drm_device_t  *dev    = priv->dev;
+	int	      retcode;
+
+	DRM_DEBUG("fd = %d, device = 0x%lx\n", fd, (long)old_encode_dev(dev->device));
+	retcode = fasync_helper(fd, filp, on, &dev->buf_async);
+	if (retcode < 0) return retcode;
+	return 0;
+}
+EXPORT_SYMBOL(drm_fasync);
+
+/** No-op. */
+unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait)
+{
+	return 0;
+}
+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 -Nru a/drivers/char/drm/drm_fops.h b/drivers/char/drm/drm_fops.h
--- a/drivers/char/drm/drm_fops.h	2005-03-01 23:38:58 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,156 +0,0 @@
-/**
- * \file drm_fops.h 
- * File operations for DRM
- * 
- * \author Rickard E. (Rik) Faith <faith@valinux.com>
- * \author Daryll Strauss <daryll@valinux.com>
- * \author Gareth Hughes <gareth@valinux.com>
- */
-
-/*
- * Created: Mon Jan  4 08:58:31 1999 by faith@valinux.com
- *
- * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include "drmP.h"
-#include <linux/poll.h>
-
-
-/**
- * Called whenever a process opens /dev/drm. 
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param dev device.
- * \return zero on success or a negative number on failure.
- * 
- * 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)
-{
-	int	     minor = iminor(inode);
-	drm_file_t   *priv;
-	int ret;
-
-	if (filp->f_flags & O_EXCL)   return -EBUSY; /* No exclusive opens */
-	if (!DRM(cpu_valid)())        return -EINVAL;
-
-	DRM_DEBUG("pid = %d, minor = %d\n", current->pid, minor);
-
-	priv		    = DRM(alloc)(sizeof(*priv), DRM_MEM_FILES);
-	if(!priv) return -ENOMEM;
-
-	memset(priv, 0, sizeof(*priv));
-	filp->private_data  = priv;
-	priv->uid	    = current->euid;
-	priv->pid	    = current->pid;
-	priv->minor	    = minor;
-	priv->dev	    = dev;
-	priv->ioctl_count   = 0;
-	priv->authenticated = capable(CAP_SYS_ADMIN);
-	priv->lock_count    = 0;
-
-	if (dev->fn_tbl.open_helper) {
-		ret=dev->fn_tbl.open_helper(dev, priv);
-		if (ret < 0)
-			goto out_free;
-	}
-
-	down(&dev->struct_sem);
-	if (!dev->file_last) {
-		priv->next	= NULL;
-		priv->prev	= NULL;
-		dev->file_first = priv;
-		dev->file_last	= priv;
-	} else {
-		priv->next	     = NULL;
-		priv->prev	     = dev->file_last;
-		dev->file_last->next = priv;
-		dev->file_last	     = priv;
-	}
-	up(&dev->struct_sem);
-
-#ifdef __alpha__
-	/*
-	 * Default the hose
-	 */
-	if (!dev->hose) {
-		struct pci_dev *pci_dev;
-		pci_dev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, NULL);
-		if (pci_dev) {
-			dev->hose = pci_dev->sysdata;
-			pci_dev_put(pci_dev);
-		}
-		if (!dev->hose) {
-			struct pci_bus *b = pci_bus_b(pci_root_buses.next);
-			if (b) dev->hose = b->sysdata;
-		}
-	}
-#endif
-
-	return 0;
-out_free:
-	DRM(free)(priv, sizeof(*priv), DRM_MEM_FILES);
-	filp->private_data=NULL;
-	return ret;
-}
-
-/** No-op. */
-int DRM(flush)(struct file *filp)
-{
-	drm_file_t    *priv   = filp->private_data;
-	drm_device_t  *dev    = priv->dev;
-
-	DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n",
-		  current->pid, (long)old_encode_dev(dev->device), dev->open_count);
-	return 0;
-}
-
-/** No-op. */
-int DRM(fasync)(int fd, struct file *filp, int on)
-{
-	drm_file_t    *priv   = filp->private_data;
-	drm_device_t  *dev    = priv->dev;
-	int	      retcode;
-
-	DRM_DEBUG("fd = %d, device = 0x%lx\n", fd, (long)old_encode_dev(dev->device));
-	retcode = fasync_helper(fd, filp, on, &dev->buf_async);
-	if (retcode < 0) return retcode;
-	return 0;
-}
-
-/** No-op. */
-unsigned int DRM(poll)(struct file *filp, struct poll_table_struct *wait)
-{
-	return 0;
-}
-
-
-/** No-op. */
-ssize_t DRM(read)(struct file *filp, char __user *buf, size_t count, loff_t *off)
-{
-	return 0;
-}
diff -Nru a/drivers/char/drm/drm_init.c b/drivers/char/drm/drm_init.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/char/drm/drm_init.c	2005-03-01 23:39:09 -08:00
@@ -0,0 +1,52 @@
+/**
+ * \file drm_init.h 
+ * Setup/Cleanup for DRM
+ *
+ * \author Rickard E. (Rik) Faith <faith@valinux.com>
+ * \author Gareth Hughes <gareth@valinux.com>
+ */
+
+/*
+ * Created: Mon Jan  4 08:58:31 1999 by faith@valinux.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "drmP.h"
+
+/**
+ * Check whether DRI will run on this CPU.
+ *
+ * \return non-zero if the DRI will run on this CPU, or zero otherwise.
+ */
+int drm_cpu_valid(void)
+{
+#if defined(__i386__)
+	if (boot_cpu_data.x86 == 3) return 0; /* No cmpxchg on a 386 */
+#endif
+#if defined(__sparc__) && !defined(__sparc_v9__)
+	return 0; /* No cmpxchg before v9 sparc. */
+#endif
+	return 1;
+}
diff -Nru a/drivers/char/drm/drm_init.h b/drivers/char/drm/drm_init.h
--- a/drivers/char/drm/drm_init.h	2005-03-01 23:39:09 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,128 +0,0 @@
-/**
- * \file drm_init.h 
- * Setup/Cleanup for DRM
- *
- * \author Rickard E. (Rik) Faith <faith@valinux.com>
- * \author Gareth Hughes <gareth@valinux.com>
- */
-
-/*
- * Created: Mon Jan  4 08:58:31 1999 by faith@valinux.com
- *
- * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include "drmP.h"
-
-/** Debug flags.  Set by parse_option(). */
-#if 0
-int DRM(flags) = DRM_FLAG_DEBUG;
-#else
-int DRM(flags) = 0;
-#endif
-
-/**
- * Parse a single option.
- *
- * \param s option string.
- *
- * \sa See parse_options() for details.
- */
-static void DRM(parse_option)(char *s)
-{
-	char *c, *r;
-
-	DRM_DEBUG("\"%s\"\n", s);
-	if (!s || !*s) return;
-	for (c = s; *c && *c != ':'; c++); /* find : or \0 */
-	if (*c) r = c + 1; else r = NULL;  /* remember remainder */
-	*c = '\0';			   /* terminate */
-	if (!strcmp(s, "debug")) {
-		DRM(flags) |= DRM_FLAG_DEBUG;
-		DRM_INFO("Debug messages ON\n");
-		return;
-	}
-	DRM_ERROR("\"%s\" is not a valid option\n", s);
-	return;
-}
-
-/**
- * Parse the insmod "drm_opts=" options, or the command-line
- * options passed to the kernel via LILO.  
- *
- * \param s contains option_list without the 'drm_opts=' part.
- *
- * The grammar of the format is as
- * follows:
- *
- * \code
- * drm		::= 'drm_opts=' option_list
- * option_list	::= option [ ';' option_list ]
- * option	::= 'device:' major
- *		|   'debug'
- *		|   'noctx'
- * major	::= INTEGER
- * \endcode
- *
- * - device=major,minor specifies the device number used for /dev/drm
- *   - if major == 0 then the misc device is used
- *   - if major == 0 and minor == 0 then dynamic misc allocation is used
- * - debug=on specifies that debugging messages will be printk'd
- * - debug=trace specifies that each function call will be logged via printk
- * - debug=off turns off all debugging options
- *
- * \todo Actually only the \e presence of the 'debug' option is currently
- * checked.
- */
-
-void DRM(parse_options)(char *s)
-{
-	char *h, *t, *n;
-
-	DRM_DEBUG("\"%s\"\n", s ?: "");
-	if (!s || !*s) return;
-
-	for (h = t = n = s; h && *h; h = n) {
-		for (; *t && *t != ';'; t++);	       /* find ; or \0 */
-		if (*t) n = t + 1; else n = NULL;      /* remember next */
-		*t = '\0';			       /* terminate */
-		DRM(parse_option)(h);		       /* parse */
-	}
-}
-
-/**
- * Check whether DRI will run on this CPU.
- *
- * \return non-zero if the DRI will run on this CPU, or zero otherwise.
- */
-int DRM(cpu_valid)(void)
-{
-#if defined(__i386__)
-	if (boot_cpu_data.x86 == 3) return 0; /* No cmpxchg on a 386 */
-#endif
-#if defined(__sparc__) && !defined(__sparc_v9__)
-	return 0; /* No cmpxchg before v9 sparc. */
-#endif
-	return 1;
-}
diff -Nru a/drivers/char/drm/drm_ioctl.c b/drivers/char/drm/drm_ioctl.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/char/drm/drm_ioctl.c	2005-03-01 23:38:53 -08:00
@@ -0,0 +1,368 @@
+/**
+ * \file drm_ioctl.h 
+ * IOCTL processing for DRM
+ *
+ * \author Rickard E. (Rik) Faith <faith@valinux.com>
+ * \author Gareth Hughes <gareth@valinux.com>
+ */
+
+/*
+ * Created: Fri Jan  8 09:01:26 1999 by faith@valinux.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "drmP.h"
+#include "drm_core.h"
+
+#include "linux/pci.h"
+
+/**
+ * Get the bus id.
+ * 
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument, pointing to a drm_unique structure.
+ * \return zero on success or a negative number on failure.
+ *
+ * Copies the bus id from drm_device::unique into user space.
+ */
+int drm_getunique(struct inode *inode, struct file *filp,
+		   unsigned int cmd, unsigned long arg)
+{
+	drm_file_t	 *priv	 = filp->private_data;
+	drm_device_t	 *dev	 = priv->dev;
+	drm_unique_t	 __user *argp = (void __user *)arg;
+	drm_unique_t	 u;
+
+	if (copy_from_user(&u, argp, sizeof(u)))
+		return -EFAULT;
+	if (u.unique_len >= dev->unique_len) {
+		if (copy_to_user(u.unique, dev->unique, dev->unique_len))
+			return -EFAULT;
+	}
+	u.unique_len = dev->unique_len;
+	if (copy_to_user(argp, &u, sizeof(u)))
+		return -EFAULT;
+	return 0;
+}
+
+/**
+ * Set the bus id.
+ * 
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument, pointing to a drm_unique structure.
+ * \return zero on success or a negative number on failure.
+ *
+ * Copies the bus id from userspace into drm_device::unique, and verifies that
+ * it matches the device this DRM is attached to (EINVAL otherwise).  Deprecated
+ * in interface version 1.1 and will return EBUSY when setversion has requested
+ * version 1.1 or greater.
+ */
+int drm_setunique(struct inode *inode, struct file *filp,
+		   unsigned int cmd, unsigned long arg)
+{
+	drm_file_t	 *priv	 = filp->private_data;
+	drm_device_t	 *dev	 = priv->dev;
+	drm_unique_t	 u;
+	int		 domain, bus, slot, func, ret;
+
+	if (dev->unique_len || dev->unique) return -EBUSY;
+
+	if (copy_from_user(&u, (drm_unique_t __user *)arg, sizeof(u)))
+		return -EFAULT;
+
+	if (!u.unique_len || u.unique_len > 1024) return -EINVAL;
+
+	dev->unique_len = u.unique_len;
+	dev->unique	= drm_alloc(u.unique_len + 1, DRM_MEM_DRIVER);
+	if(!dev->unique) return -ENOMEM;
+	if (copy_from_user(dev->unique, u.unique, dev->unique_len))
+		return -EFAULT;
+
+	dev->unique[dev->unique_len] = '\0';
+
+	dev->devname = drm_alloc(strlen(dev->driver->pci_driver.name) + strlen(dev->unique) + 2,
+				  DRM_MEM_DRIVER);
+	if (!dev->devname)
+		return -ENOMEM;
+
+	sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name, dev->unique);
+
+	/* Return error if the busid submitted doesn't match the device's actual
+	 * busid.
+	 */
+	ret = sscanf(dev->unique, "PCI:%d:%d:%d", &bus, &slot, &func);
+	if (ret != 3)
+		return DRM_ERR(EINVAL);
+	domain = bus >> 8;
+	bus &= 0xff;
+	
+	if ((domain != dev->pci_domain) ||
+	    (bus != dev->pci_bus) ||
+	    (slot != dev->pci_slot) ||
+	    (func != dev->pci_func))
+		return -EINVAL;
+
+	return 0;
+}
+
+static int
+drm_set_busid(drm_device_t *dev)
+{
+	if (dev->unique != NULL)
+		return EBUSY;
+
+	dev->unique_len = 20;
+	dev->unique = drm_alloc(dev->unique_len + 1, DRM_MEM_DRIVER);
+	if (dev->unique == NULL)
+		return ENOMEM;
+
+	snprintf(dev->unique, dev->unique_len, "pci:%04x:%02x:%02x.%d",
+		dev->pci_domain, dev->pci_bus, dev->pci_slot, dev->pci_func);
+
+	dev->devname = drm_alloc(strlen(dev->driver->pci_driver.name) + dev->unique_len + 2,
+				DRM_MEM_DRIVER);
+	if (dev->devname == NULL)
+		return ENOMEM;
+
+	sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name, dev->unique);
+
+	return 0;
+}
+
+
+/**
+ * Get a mapping information.
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument, pointing to a drm_map structure.
+ * 
+ * \return zero on success or a negative number on failure.
+ *
+ * Searches for the mapping with the specified offset and copies its information
+ * into userspace
+ */
+int drm_getmap( struct inode *inode, struct file *filp,
+		 unsigned int cmd, unsigned long arg )
+{
+	drm_file_t   *priv = filp->private_data;
+	drm_device_t *dev  = priv->dev;
+	drm_map_t    __user *argp = (void __user *)arg;
+	drm_map_t    map;
+	drm_map_list_t *r_list = NULL;
+	struct list_head *list;
+	int          idx;
+	int	     i;
+
+	if (copy_from_user(&map, argp, sizeof(map)))
+		return -EFAULT;
+	idx = map.offset;
+
+	down(&dev->struct_sem);
+	if (idx < 0) {
+		up(&dev->struct_sem);
+		return -EINVAL;
+	}
+
+	i = 0;
+	list_for_each(list, &dev->maplist->head) {
+		if(i == idx) {
+			r_list = list_entry(list, drm_map_list_t, head);
+			break;
+		}
+		i++;
+	}
+	if(!r_list || !r_list->map) {
+		up(&dev->struct_sem);
+		return -EINVAL;
+	}
+
+	map.offset = r_list->map->offset;
+	map.size   = r_list->map->size;
+	map.type   = r_list->map->type;
+	map.flags  = r_list->map->flags;
+	map.handle = r_list->map->handle;
+	map.mtrr   = r_list->map->mtrr;
+	up(&dev->struct_sem);
+
+	if (copy_to_user(argp, &map, sizeof(map))) return -EFAULT;
+	return 0;
+}
+
+/**
+ * Get client information.
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument, pointing to a drm_client structure.
+ * 
+ * \return zero on success or a negative number on failure.
+ *
+ * Searches for the client with the specified index and copies its information
+ * into userspace
+ */
+int drm_getclient( struct inode *inode, struct file *filp,
+		    unsigned int cmd, unsigned long arg )
+{
+	drm_file_t   *priv = filp->private_data;
+	drm_device_t *dev  = priv->dev;
+	drm_client_t __user *argp = (void __user *)arg;
+	drm_client_t client;
+	drm_file_t   *pt;
+	int          idx;
+	int          i;
+
+	if (copy_from_user(&client, argp, sizeof(client)))
+		return -EFAULT;
+	idx = client.idx;
+	down(&dev->struct_sem);
+	for (i = 0, pt = dev->file_first; i < idx && pt; i++, pt = pt->next)
+		;
+
+	if (!pt) {
+		up(&dev->struct_sem);
+		return -EINVAL;
+	}
+	client.auth  = pt->authenticated;
+	client.pid   = pt->pid;
+	client.uid   = pt->uid;
+	client.magic = pt->magic;
+	client.iocs  = pt->ioctl_count;
+	up(&dev->struct_sem);
+
+	if (copy_to_user((drm_client_t __user *)arg, &client, sizeof(client)))
+		return -EFAULT;
+	return 0;
+}
+
+/** 
+ * Get statistics information. 
+ * 
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument, pointing to a drm_stats structure.
+ * 
+ * \return zero on success or a negative number on failure.
+ */
+int drm_getstats( struct inode *inode, struct file *filp,
+		   unsigned int cmd, unsigned long arg )
+{
+	drm_file_t   *priv = filp->private_data;
+	drm_device_t *dev  = priv->dev;
+	drm_stats_t  stats;
+	int          i;
+
+	memset(&stats, 0, sizeof(stats));
+	
+	down(&dev->struct_sem);
+
+	for (i = 0; i < dev->counters; i++) {
+		if (dev->types[i] == _DRM_STAT_LOCK)
+			stats.data[i].value
+				= (dev->lock.hw_lock
+				   ? dev->lock.hw_lock->lock : 0);
+		else 
+			stats.data[i].value = atomic_read(&dev->counts[i]);
+		stats.data[i].type  = dev->types[i];
+	}
+	
+	stats.count = dev->counters;
+
+	up(&dev->struct_sem);
+
+	if (copy_to_user((drm_stats_t __user *)arg, &stats, sizeof(stats)))
+		return -EFAULT;
+	return 0;
+}
+
+/**
+ * Setversion ioctl.
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument, pointing to a drm_lock structure.
+ * \return zero on success or negative number on failure.
+ *
+ * Sets the requested interface version
+ */
+int drm_setversion(DRM_IOCTL_ARGS)
+{
+	DRM_DEVICE;
+	drm_set_version_t sv;
+	drm_set_version_t retv;
+	int if_version;
+	drm_set_version_t __user *argp = (void __user *)data;
+	drm_version_t version;
+
+	DRM_COPY_FROM_USER_IOCTL(sv, argp, sizeof(sv));
+
+	dev->driver->version(&version);
+	retv.drm_di_major = DRM_IF_MAJOR;
+	retv.drm_di_minor = DRM_IF_MINOR;
+	retv.drm_dd_major = version.version_major;
+	retv.drm_dd_minor = version.version_minor;
+
+	DRM_COPY_TO_USER_IOCTL(argp, retv, sizeof(sv));
+
+	if (sv.drm_di_major != -1) {
+		if (sv.drm_di_major != DRM_IF_MAJOR ||
+		    sv.drm_di_minor < 0 || sv.drm_di_minor > DRM_IF_MINOR)
+			return EINVAL;
+		if_version = DRM_IF_VERSION(sv.drm_di_major, sv.drm_dd_minor);
+		dev->if_version = DRM_MAX(if_version, dev->if_version);
+		if (sv.drm_di_minor >= 1) {
+			/*
+			 * Version 1.1 includes tying of DRM to specific device
+			 */
+			drm_set_busid(dev);
+		}
+	}
+
+	if (sv.drm_dd_major != -1) {
+		if (sv.drm_dd_major != version.version_major ||
+		    sv.drm_dd_minor < 0 || sv.drm_dd_minor > version.version_minor)
+			return EINVAL;
+
+		if (dev->driver->set_version)
+			dev->driver->set_version(dev, &sv);
+	}
+	return 0;
+}
+
+/** No-op ioctl. */
+int drm_noop(struct inode *inode, struct file *filp, unsigned int cmd,
+	       unsigned long arg)
+{
+	DRM_DEBUG("\n");
+	return 0;
+}
diff -Nru a/drivers/char/drm/drm_ioctl.h b/drivers/char/drm/drm_ioctl.h
--- a/drivers/char/drm/drm_ioctl.h	2005-03-01 23:38:53 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,349 +0,0 @@
-/**
- * \file drm_ioctl.h 
- * IOCTL processing for DRM
- *
- * \author Rickard E. (Rik) Faith <faith@valinux.com>
- * \author Gareth Hughes <gareth@valinux.com>
- */
-
-/*
- * Created: Fri Jan  8 09:01:26 1999 by faith@valinux.com
- *
- * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include "drmP.h"
-
-#include "linux/pci.h"
-
-/**
- * Get the bus id.
- * 
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg user argument, pointing to a drm_unique structure.
- * \return zero on success or a negative number on failure.
- *
- * Copies the bus id from drm_device::unique into user space.
- */
-int DRM(getunique)(struct inode *inode, struct file *filp,
-		   unsigned int cmd, unsigned long arg)
-{
-	drm_file_t	 *priv	 = filp->private_data;
-	drm_device_t	 *dev	 = priv->dev;
-	drm_unique_t	 __user *argp = (void __user *)arg;
-	drm_unique_t	 u;
-
-	if (copy_from_user(&u, argp, sizeof(u)))
-		return -EFAULT;
-	if (u.unique_len >= dev->unique_len) {
-		if (copy_to_user(u.unique, dev->unique, dev->unique_len))
-			return -EFAULT;
-	}
-	u.unique_len = dev->unique_len;
-	if (copy_to_user(argp, &u, sizeof(u)))
-		return -EFAULT;
-	return 0;
-}
-
-/**
- * Set the bus id.
- * 
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg user argument, pointing to a drm_unique structure.
- * \return zero on success or a negative number on failure.
- *
- * Copies the bus id from userspace into drm_device::unique, and verifies that
- * it matches the device this DRM is attached to (EINVAL otherwise).  Deprecated
- * in interface version 1.1 and will return EBUSY when setversion has requested
- * version 1.1 or greater.
- */
-int DRM(setunique)(struct inode *inode, struct file *filp,
-		   unsigned int cmd, unsigned long arg)
-{
-	drm_file_t	 *priv	 = filp->private_data;
-	drm_device_t	 *dev	 = priv->dev;
-	drm_unique_t	 u;
-	int		 domain, bus, slot, func, ret;
-
-	if (dev->unique_len || dev->unique) return -EBUSY;
-
-	if (copy_from_user(&u, (drm_unique_t __user *)arg, sizeof(u)))
-		return -EFAULT;
-
-	if (!u.unique_len || u.unique_len > 1024) return -EINVAL;
-
-	dev->unique_len = u.unique_len;
-	dev->unique	= DRM(alloc)(u.unique_len + 1, DRM_MEM_DRIVER);
-	if(!dev->unique) return -ENOMEM;
-	if (copy_from_user(dev->unique, u.unique, dev->unique_len))
-		return -EFAULT;
-
-	dev->unique[dev->unique_len] = '\0';
-
-	dev->devname = DRM(alloc)(strlen(dev->name) + strlen(dev->unique) + 2,
-				  DRM_MEM_DRIVER);
-	if (!dev->devname)
-		return -ENOMEM;
-
-	sprintf(dev->devname, "%s@%s", dev->name, dev->unique);
-
-	/* Return error if the busid submitted doesn't match the device's actual
-	 * busid.
-	 */
-	ret = sscanf(dev->unique, "PCI:%d:%d:%d", &bus, &slot, &func);
-	if (ret != 3)
-		return DRM_ERR(EINVAL);
-	domain = bus >> 8;
-	bus &= 0xff;
-	
-	if ((domain != dev->pci_domain) ||
-	    (bus != dev->pci_bus) ||
-	    (slot != dev->pci_slot) ||
-	    (func != dev->pci_func))
-		return -EINVAL;
-
-	return 0;
-}
-
-static int
-DRM(set_busid)(drm_device_t *dev)
-{
-	if (dev->unique != NULL)
-		return EBUSY;
-
-	dev->unique_len = 20;
-	dev->unique = DRM(alloc)(dev->unique_len + 1, DRM_MEM_DRIVER);
-	if (dev->unique == NULL)
-		return ENOMEM;
-
-	snprintf(dev->unique, dev->unique_len, "pci:%04x:%02x:%02x.%d",
-		dev->pci_domain, dev->pci_bus, dev->pci_slot, dev->pci_func);
-
-	dev->devname = DRM(alloc)(strlen(dev->name) + dev->unique_len + 2,
-				DRM_MEM_DRIVER);
-	if (dev->devname == NULL)
-		return ENOMEM;
-
-	sprintf(dev->devname, "%s@%s", dev->name, dev->unique);
-
-	return 0;
-}
-
-
-/**
- * Get a mapping information.
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg user argument, pointing to a drm_map structure.
- * 
- * \return zero on success or a negative number on failure.
- *
- * Searches for the mapping with the specified offset and copies its information
- * into userspace
- */
-int DRM(getmap)( struct inode *inode, struct file *filp,
-		 unsigned int cmd, unsigned long arg )
-{
-	drm_file_t   *priv = filp->private_data;
-	drm_device_t *dev  = priv->dev;
-	drm_map_t    __user *argp = (void __user *)arg;
-	drm_map_t    map;
-	drm_map_list_t *r_list = NULL;
-	struct list_head *list;
-	int          idx;
-	int	     i;
-
-	if (copy_from_user(&map, argp, sizeof(map)))
-		return -EFAULT;
-	idx = map.offset;
-
-	down(&dev->struct_sem);
-	if (idx < 0) {
-		up(&dev->struct_sem);
-		return -EINVAL;
-	}
-
-	i = 0;
-	list_for_each(list, &dev->maplist->head) {
-		if(i == idx) {
-			r_list = list_entry(list, drm_map_list_t, head);
-			break;
-		}
-		i++;
-	}
-	if(!r_list || !r_list->map) {
-		up(&dev->struct_sem);
-		return -EINVAL;
-	}
-
-	map.offset = r_list->map->offset;
-	map.size   = r_list->map->size;
-	map.type   = r_list->map->type;
-	map.flags  = r_list->map->flags;
-	map.handle = r_list->map->handle;
-	map.mtrr   = r_list->map->mtrr;
-	up(&dev->struct_sem);
-
-	if (copy_to_user(argp, &map, sizeof(map))) return -EFAULT;
-	return 0;
-}
-
-/**
- * Get client information.
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg user argument, pointing to a drm_client structure.
- * 
- * \return zero on success or a negative number on failure.
- *
- * Searches for the client with the specified index and copies its information
- * into userspace
- */
-int DRM(getclient)( struct inode *inode, struct file *filp,
-		    unsigned int cmd, unsigned long arg )
-{
-	drm_file_t   *priv = filp->private_data;
-	drm_device_t *dev  = priv->dev;
-	drm_client_t __user *argp = (void __user *)arg;
-	drm_client_t client;
-	drm_file_t   *pt;
-	int          idx;
-	int          i;
-
-	if (copy_from_user(&client, argp, sizeof(client)))
-		return -EFAULT;
-	idx = client.idx;
-	down(&dev->struct_sem);
-	for (i = 0, pt = dev->file_first; i < idx && pt; i++, pt = pt->next)
-		;
-
-	if (!pt) {
-		up(&dev->struct_sem);
-		return -EINVAL;
-	}
-	client.auth  = pt->authenticated;
-	client.pid   = pt->pid;
-	client.uid   = pt->uid;
-	client.magic = pt->magic;
-	client.iocs  = pt->ioctl_count;
-	up(&dev->struct_sem);
-
-	if (copy_to_user((drm_client_t __user *)arg, &client, sizeof(client)))
-		return -EFAULT;
-	return 0;
-}
-
-/** 
- * Get statistics information. 
- * 
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg user argument, pointing to a drm_stats structure.
- * 
- * \return zero on success or a negative number on failure.
- */
-int DRM(getstats)( struct inode *inode, struct file *filp,
-		   unsigned int cmd, unsigned long arg )
-{
-	drm_file_t   *priv = filp->private_data;
-	drm_device_t *dev  = priv->dev;
-	drm_stats_t  stats;
-	int          i;
-
-	memset(&stats, 0, sizeof(stats));
-	
-	down(&dev->struct_sem);
-
-	for (i = 0; i < dev->counters; i++) {
-		if (dev->types[i] == _DRM_STAT_LOCK)
-			stats.data[i].value
-				= (dev->lock.hw_lock
-				   ? dev->lock.hw_lock->lock : 0);
-		else 
-			stats.data[i].value = atomic_read(&dev->counts[i]);
-		stats.data[i].type  = dev->types[i];
-	}
-	
-	stats.count = dev->counters;
-
-	up(&dev->struct_sem);
-
-	if (copy_to_user((drm_stats_t __user *)arg, &stats, sizeof(stats)))
-		return -EFAULT;
-	return 0;
-}
-
-#define DRM_IF_MAJOR	1
-#define DRM_IF_MINOR	2
-
-int DRM(setversion)(DRM_IOCTL_ARGS)
-{
-	DRM_DEVICE;
-	drm_set_version_t sv;
-	drm_set_version_t retv;
-	int if_version;
-	drm_set_version_t __user *argp = (void __user *)data;
-
-	DRM_COPY_FROM_USER_IOCTL(sv, argp, sizeof(sv));
-
-	retv.drm_di_major = DRM_IF_MAJOR;
-	retv.drm_di_minor = DRM_IF_MINOR;
-	retv.drm_dd_major = DRIVER_MAJOR;
-	retv.drm_dd_minor = DRIVER_MINOR;
-
-	DRM_COPY_TO_USER_IOCTL(argp, retv, sizeof(sv));
-
-	if (sv.drm_di_major != -1) {
-		if (sv.drm_di_major != DRM_IF_MAJOR ||
-		    sv.drm_di_minor < 0 || sv.drm_di_minor > DRM_IF_MINOR)
-			return EINVAL;
-		if_version = DRM_IF_VERSION(sv.drm_di_major, sv.drm_dd_minor);
-		dev->if_version = DRM_MAX(if_version, dev->if_version);
-		if (sv.drm_di_minor >= 1) {
-			/*
-			 * Version 1.1 includes tying of DRM to specific device
-			 */
-			DRM(set_busid)(dev);
-		}
-	}
-
-	if (sv.drm_dd_major != -1) {
-		if (sv.drm_dd_major != DRIVER_MAJOR ||
-		    sv.drm_dd_minor < 0 || sv.drm_dd_minor > DRIVER_MINOR)
-			return EINVAL;
-
-		if (dev->fn_tbl.set_version)
-			dev->fn_tbl.set_version(dev, &sv);
-	}
-	return 0;
-}
diff -Nru a/drivers/char/drm/drm_irq.c b/drivers/char/drm/drm_irq.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/char/drm/drm_irq.c	2005-03-01 23:39:07 -08:00
@@ -0,0 +1,370 @@
+/**
+ * \file drm_irq.h 
+ * IRQ support
+ *
+ * \author Rickard E. (Rik) Faith <faith@valinux.com>
+ * \author Gareth Hughes <gareth@valinux.com>
+ */
+
+/*
+ * Created: Fri Mar 19 14:30:16 1999 by faith@valinux.com
+ *
+ * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "drmP.h"
+
+#include <linux/interrupt.h>	/* For task queue support */
+
+/**
+ * Get interrupt from bus id.
+ * 
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument, pointing to a drm_irq_busid structure.
+ * \return zero on success or a negative number on failure.
+ * 
+ * Finds the PCI device with the specified bus id and gets its IRQ number.
+ * This IOCTL is deprecated, and will now return EINVAL for any busid not equal
+ * to that of the device that this DRM instance attached to.
+ */
+int drm_irq_by_busid(struct inode *inode, struct file *filp,
+		   unsigned int cmd, unsigned long arg)
+{
+	drm_file_t *priv = filp->private_data;
+	drm_device_t *dev = priv->dev;
+	drm_irq_busid_t __user *argp = (void __user *)arg;
+	drm_irq_busid_t p;
+
+	if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
+		return -EINVAL;
+
+	if (copy_from_user(&p, argp, sizeof(p)))
+		return -EFAULT;
+
+	if ((p.busnum >> 8) != dev->pci_domain ||
+	    (p.busnum & 0xff) != dev->pci_bus ||
+	    p.devnum != dev->pci_slot ||
+	    p.funcnum != dev->pci_func)
+		return -EINVAL;
+
+	p.irq = dev->irq;
+
+	DRM_DEBUG("%d:%d:%d => IRQ %d\n",
+		  p.busnum, p.devnum, p.funcnum, p.irq);
+	if (copy_to_user(argp, &p, sizeof(p)))
+		return -EFAULT;
+	return 0;
+}
+
+/**
+ * Install IRQ handler.
+ *
+ * \param dev DRM device.
+ * \param irq IRQ number.
+ *
+ * Initializes the IRQ related data, and setups drm_device::vbl_queue. Installs the handler, calling the driver
+ * \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 )
+{
+	int ret;
+	unsigned long sh_flags=0;
+
+	if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
+		return -EINVAL;
+
+	if ( dev->irq == 0 )
+		return -EINVAL;
+
+	down( &dev->struct_sem );
+
+	/* Driver must have been initialized */
+	if ( !dev->dev_private ) {
+		up( &dev->struct_sem );
+		return -EINVAL;
+	}
+
+	if ( dev->irq_enabled ) {
+		up( &dev->struct_sem );
+		return -EBUSY;
+	}
+	dev->irq_enabled = 1;
+	up( &dev->struct_sem );
+
+	DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, dev->irq );
+
+	if (drm_core_check_feature(dev, DRIVER_IRQ_VBL)) {
+		init_waitqueue_head(&dev->vbl_queue);
+		
+		spin_lock_init( &dev->vbl_lock );
+		
+		INIT_LIST_HEAD( &dev->vbl_sigs.head );
+		
+		dev->vbl_pending = 0;
+	}
+
+				/* Before installing handler */
+	dev->driver->irq_preinstall(dev);
+
+				/* Install handler */
+	if (drm_core_check_feature(dev, DRIVER_IRQ_SHARED))
+		sh_flags = SA_SHIRQ;
+	
+	ret = request_irq( dev->irq, dev->driver->irq_handler,
+			   sh_flags, dev->devname, dev );
+	if ( ret < 0 ) {
+		down( &dev->struct_sem );
+		dev->irq_enabled = 0;
+		up( &dev->struct_sem );
+		return ret;
+	}
+
+				/* After installing handler */
+	dev->driver->irq_postinstall(dev);
+
+	return 0;
+}
+
+/**
+ * Uninstall the IRQ handler.
+ *
+ * \param dev DRM device.
+ *
+ * Calls the driver's \c drm_driver_irq_uninstall() function, and stops the irq.
+ */
+int drm_irq_uninstall( drm_device_t *dev )
+{
+	int irq_enabled;
+
+	if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
+		return -EINVAL;
+
+	down( &dev->struct_sem );
+	irq_enabled = dev->irq_enabled;
+	dev->irq_enabled = 0;
+	up( &dev->struct_sem );
+
+	if ( !irq_enabled )
+		return -EINVAL;
+
+	DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, dev->irq );
+
+	dev->driver->irq_uninstall(dev);
+
+	free_irq( dev->irq, dev );
+
+	return 0;
+}
+EXPORT_SYMBOL(drm_irq_uninstall);
+
+/**
+ * IRQ control ioctl.
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument, pointing to a drm_control structure.
+ * \return zero on success or a negative number on failure.
+ *
+ * Calls irq_install() or irq_uninstall() according to \p arg.
+ */
+int drm_control( struct inode *inode, struct file *filp,
+		  unsigned int cmd, unsigned long arg )
+{
+	drm_file_t *priv = filp->private_data;
+	drm_device_t *dev = priv->dev;
+	drm_control_t ctl;
+	
+	/* if we haven't irq we fallback for compatibility reasons - this used to be a separate function in drm_dma.h */
+
+	if ( copy_from_user( &ctl, (drm_control_t __user *)arg, sizeof(ctl) ) )
+		return -EFAULT;
+
+	switch ( ctl.func ) {
+	case DRM_INST_HANDLER:
+		if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
+			return 0;
+		if (dev->if_version < DRM_IF_VERSION(1, 2) &&
+		    ctl.irq != dev->irq)
+			return -EINVAL;
+		return drm_irq_install( dev );
+	case DRM_UNINST_HANDLER:
+		if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
+			return 0;
+		return drm_irq_uninstall( dev );
+	default:
+		return -EINVAL;
+	}
+}
+
+/**
+ * Wait for VBLANK.
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param data user argument, pointing to a drm_wait_vblank structure.
+ * \return zero on success or a negative number on failure.
+ *
+ * Verifies the IRQ is installed. 
+ *
+ * If a signal is requested checks if this task has already scheduled the same signal
+ * for the same vblank sequence number - nothing to be done in
+ * that case. If the number of tasks waiting for the interrupt exceeds 100 the
+ * function fails. Otherwise adds a new entry to drm_device::vbl_sigs for this
+ * task.
+ *
+ * If a signal is not requested, then calls vblank_wait().
+ */
+int drm_wait_vblank( DRM_IOCTL_ARGS )
+{
+	drm_file_t *priv = filp->private_data;
+	drm_device_t *dev = priv->dev;
+	drm_wait_vblank_t __user *argp = (void __user *)data;
+	drm_wait_vblank_t vblwait;
+	struct timeval now;
+	int ret = 0;
+	unsigned int flags;
+
+	if (!drm_core_check_feature(dev, DRIVER_IRQ_VBL))
+		return -EINVAL;
+
+	if (!dev->irq)
+		return -EINVAL;
+
+	DRM_COPY_FROM_USER_IOCTL( vblwait, argp, sizeof(vblwait) );
+
+	switch ( vblwait.request.type & ~_DRM_VBLANK_FLAGS_MASK ) {
+	case _DRM_VBLANK_RELATIVE:
+		vblwait.request.sequence += atomic_read( &dev->vbl_received );
+		vblwait.request.type &= ~_DRM_VBLANK_RELATIVE;
+	case _DRM_VBLANK_ABSOLUTE:
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	flags = vblwait.request.type & _DRM_VBLANK_FLAGS_MASK;
+	
+	if ( flags & _DRM_VBLANK_SIGNAL ) {
+		unsigned long irqflags;
+		drm_vbl_sig_t *vbl_sig;
+		
+		vblwait.reply.sequence = atomic_read( &dev->vbl_received );
+
+		spin_lock_irqsave( &dev->vbl_lock, irqflags );
+
+		/* Check if this task has already scheduled the same signal
+		 * for the same vblank sequence number; nothing to be done in
+		 * that case
+		 */
+		list_for_each_entry( vbl_sig, &dev->vbl_sigs.head, head ) {
+			if (vbl_sig->sequence == vblwait.request.sequence
+			    && vbl_sig->info.si_signo == vblwait.request.signal
+			    && vbl_sig->task == current)
+			{
+				spin_unlock_irqrestore( &dev->vbl_lock, irqflags );
+				goto done;
+			}
+		}
+
+		if ( dev->vbl_pending >= 100 ) {
+			spin_unlock_irqrestore( &dev->vbl_lock, irqflags );
+			return -EBUSY;
+		}
+
+		dev->vbl_pending++;
+
+		spin_unlock_irqrestore( &dev->vbl_lock, irqflags );
+
+		if ( !( vbl_sig = drm_alloc( sizeof( drm_vbl_sig_t ), DRM_MEM_DRIVER ) ) ) {
+			return -ENOMEM;
+		}
+
+		memset( (void *)vbl_sig, 0, sizeof(*vbl_sig) );
+
+		vbl_sig->sequence = vblwait.request.sequence;
+		vbl_sig->info.si_signo = vblwait.request.signal;
+		vbl_sig->task = current;
+
+		spin_lock_irqsave( &dev->vbl_lock, irqflags );
+
+		list_add_tail( (struct list_head *) vbl_sig, &dev->vbl_sigs.head );
+
+		spin_unlock_irqrestore( &dev->vbl_lock, irqflags );
+	} else {
+		if (dev->driver->vblank_wait)
+			ret = dev->driver->vblank_wait( dev, &vblwait.request.sequence );
+
+		do_gettimeofday( &now );
+		vblwait.reply.tval_sec = now.tv_sec;
+		vblwait.reply.tval_usec = now.tv_usec;
+	}
+
+done:
+	DRM_COPY_TO_USER_IOCTL( argp, vblwait, sizeof(vblwait) );
+
+	return ret;
+}
+
+/**
+ * Send the VBLANK signals.
+ *
+ * \param dev DRM device.
+ *
+ * Sends a signal for each task in drm_device::vbl_sigs and empties the list.
+ *
+ * If a signal is not requested, then calls vblank_wait().
+ */
+void drm_vbl_send_signals( drm_device_t *dev )
+{
+	struct list_head *list, *tmp;
+	drm_vbl_sig_t *vbl_sig;
+	unsigned int vbl_seq = atomic_read( &dev->vbl_received );
+	unsigned long flags;
+
+	spin_lock_irqsave( &dev->vbl_lock, flags );
+
+	list_for_each_safe( list, tmp, &dev->vbl_sigs.head ) {
+		vbl_sig = list_entry( list, drm_vbl_sig_t, head );
+		if ( ( vbl_seq - vbl_sig->sequence ) <= (1<<23) ) {
+			vbl_sig->info.si_code = vbl_seq;
+			send_sig_info( vbl_sig->info.si_signo, &vbl_sig->info, vbl_sig->task );
+
+			list_del( list );
+
+			drm_free( vbl_sig, sizeof(*vbl_sig), DRM_MEM_DRIVER );
+
+			dev->vbl_pending--;
+		}
+	}
+
+	spin_unlock_irqrestore( &dev->vbl_lock, flags );
+}
+EXPORT_SYMBOL(drm_vbl_send_signals);
+
+
diff -Nru a/drivers/char/drm/drm_irq.h b/drivers/char/drm/drm_irq.h
--- a/drivers/char/drm/drm_irq.h	2005-03-01 23:39:07 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,368 +0,0 @@
-/**
- * \file drm_irq.h 
- * IRQ support
- *
- * \author Rickard E. (Rik) Faith <faith@valinux.com>
- * \author Gareth Hughes <gareth@valinux.com>
- */
-
-/*
- * Created: Fri Mar 19 14:30:16 1999 by faith@valinux.com
- *
- * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include "drmP.h"
-
-#include <linux/interrupt.h>	/* For task queue support */
-
-/**
- * Get interrupt from bus id.
- * 
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg user argument, pointing to a drm_irq_busid structure.
- * \return zero on success or a negative number on failure.
- * 
- * Finds the PCI device with the specified bus id and gets its IRQ number.
- * This IOCTL is deprecated, and will now return EINVAL for any busid not equal
- * to that of the device that this DRM instance attached to.
- */
-int DRM(irq_by_busid)(struct inode *inode, struct file *filp,
-		   unsigned int cmd, unsigned long arg)
-{
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
-	drm_irq_busid_t __user *argp = (void __user *)arg;
-	drm_irq_busid_t p;
-
-	if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
-		return -EINVAL;
-
-	if (copy_from_user(&p, argp, sizeof(p)))
-		return -EFAULT;
-
-	if ((p.busnum >> 8) != dev->pci_domain ||
-	    (p.busnum & 0xff) != dev->pci_bus ||
-	    p.devnum != dev->pci_slot ||
-	    p.funcnum != dev->pci_func)
-		return -EINVAL;
-
-	p.irq = dev->irq;
-
-	DRM_DEBUG("%d:%d:%d => IRQ %d\n",
-		  p.busnum, p.devnum, p.funcnum, p.irq);
-	if (copy_to_user(argp, &p, sizeof(p)))
-		return -EFAULT;
-	return 0;
-}
-
-/**
- * Install IRQ handler.
- *
- * \param dev DRM device.
- * \param irq IRQ number.
- *
- * Initializes the IRQ related data, and setups drm_device::vbl_queue. Installs the handler, calling the driver
- * \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 )
-{
-	int ret;
-	unsigned long sh_flags=0;
-
-	if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
-		return -EINVAL;
-
-	if ( dev->irq == 0 )
-		return -EINVAL;
-
-	down( &dev->struct_sem );
-
-	/* Driver must have been initialized */
-	if ( !dev->dev_private ) {
-		up( &dev->struct_sem );
-		return -EINVAL;
-	}
-
-	if ( dev->irq_enabled ) {
-		up( &dev->struct_sem );
-		return -EBUSY;
-	}
-	dev->irq_enabled = 1;
-	up( &dev->struct_sem );
-
-	DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, dev->irq );
-
-	if (drm_core_check_feature(dev, DRIVER_IRQ_VBL)) {
-		init_waitqueue_head(&dev->vbl_queue);
-		
-		spin_lock_init( &dev->vbl_lock );
-		
-		INIT_LIST_HEAD( &dev->vbl_sigs.head );
-		
-		dev->vbl_pending = 0;
-	}
-
-				/* Before installing handler */
-	dev->fn_tbl.irq_preinstall(dev);
-
-				/* Install handler */
-	if (drm_core_check_feature(dev, DRIVER_IRQ_SHARED))
-		sh_flags = SA_SHIRQ;
-	
-	ret = request_irq( dev->irq, dev->fn_tbl.irq_handler,
-			   sh_flags, dev->devname, dev );
-	if ( ret < 0 ) {
-		down( &dev->struct_sem );
-		dev->irq_enabled = 0;
-		up( &dev->struct_sem );
-		return ret;
-	}
-
-				/* After installing handler */
-	dev->fn_tbl.irq_postinstall(dev);
-
-	return 0;
-}
-
-/**
- * Uninstall the IRQ handler.
- *
- * \param dev DRM device.
- *
- * Calls the driver's \c DRM(driver_irq_uninstall)() function, and stops the irq.
- */
-int DRM(irq_uninstall)( drm_device_t *dev )
-{
-	int irq_enabled;
-
-	if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
-		return -EINVAL;
-
-	down( &dev->struct_sem );
-	irq_enabled = dev->irq_enabled;
-	dev->irq_enabled = 0;
-	up( &dev->struct_sem );
-
-	if ( !irq_enabled )
-		return -EINVAL;
-
-	DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, dev->irq );
-
-	dev->fn_tbl.irq_uninstall(dev);
-
-	free_irq( dev->irq, dev );
-
-	return 0;
-}
-
-/**
- * IRQ control ioctl.
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg user argument, pointing to a drm_control structure.
- * \return zero on success or a negative number on failure.
- *
- * Calls irq_install() or irq_uninstall() according to \p arg.
- */
-int DRM(control)( struct inode *inode, struct file *filp,
-		  unsigned int cmd, unsigned long arg )
-{
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
-	drm_control_t ctl;
-	
-	/* if we haven't irq we fallback for compatibility reasons - this used to be a separate function in drm_dma.h */
-
-	if ( copy_from_user( &ctl, (drm_control_t __user *)arg, sizeof(ctl) ) )
-		return -EFAULT;
-
-	switch ( ctl.func ) {
-	case DRM_INST_HANDLER:
-		if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
-			return 0;
-		if (dev->if_version < DRM_IF_VERSION(1, 2) &&
-		    ctl.irq != dev->irq)
-			return -EINVAL;
-		return DRM(irq_install)( dev );
-	case DRM_UNINST_HANDLER:
-		if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
-			return 0;
-		return DRM(irq_uninstall)( dev );
-	default:
-		return -EINVAL;
-	}
-}
-
-/**
- * Wait for VBLANK.
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param data user argument, pointing to a drm_wait_vblank structure.
- * \return zero on success or a negative number on failure.
- *
- * Verifies the IRQ is installed. 
- *
- * If a signal is requested checks if this task has already scheduled the same signal
- * for the same vblank sequence number - nothing to be done in
- * that case. If the number of tasks waiting for the interrupt exceeds 100 the
- * function fails. Otherwise adds a new entry to drm_device::vbl_sigs for this
- * task.
- *
- * If a signal is not requested, then calls vblank_wait().
- */
-int DRM(wait_vblank)( DRM_IOCTL_ARGS )
-{
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
-	drm_wait_vblank_t __user *argp = (void __user *)data;
-	drm_wait_vblank_t vblwait;
-	struct timeval now;
-	int ret = 0;
-	unsigned int flags;
-
-	if (!drm_core_check_feature(dev, DRIVER_IRQ_VBL))
-		return -EINVAL;
-
-	if (!dev->irq)
-		return -EINVAL;
-
-	DRM_COPY_FROM_USER_IOCTL( vblwait, argp, sizeof(vblwait) );
-
-	switch ( vblwait.request.type & ~_DRM_VBLANK_FLAGS_MASK ) {
-	case _DRM_VBLANK_RELATIVE:
-		vblwait.request.sequence += atomic_read( &dev->vbl_received );
-		vblwait.request.type &= ~_DRM_VBLANK_RELATIVE;
-	case _DRM_VBLANK_ABSOLUTE:
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	flags = vblwait.request.type & _DRM_VBLANK_FLAGS_MASK;
-	
-	if ( flags & _DRM_VBLANK_SIGNAL ) {
-		unsigned long irqflags;
-		drm_vbl_sig_t *vbl_sig;
-		
-		vblwait.reply.sequence = atomic_read( &dev->vbl_received );
-
-		spin_lock_irqsave( &dev->vbl_lock, irqflags );
-
-		/* Check if this task has already scheduled the same signal
-		 * for the same vblank sequence number; nothing to be done in
-		 * that case
-		 */
-		list_for_each_entry( vbl_sig, &dev->vbl_sigs.head, head ) {
-			if (vbl_sig->sequence == vblwait.request.sequence
-			    && vbl_sig->info.si_signo == vblwait.request.signal
-			    && vbl_sig->task == current)
-			{
-				spin_unlock_irqrestore( &dev->vbl_lock, irqflags );
-				goto done;
-			}
-		}
-
-		if ( dev->vbl_pending >= 100 ) {
-			spin_unlock_irqrestore( &dev->vbl_lock, irqflags );
-			return -EBUSY;
-		}
-
-		dev->vbl_pending++;
-
-		spin_unlock_irqrestore( &dev->vbl_lock, irqflags );
-
-		if ( !( vbl_sig = DRM_MALLOC( sizeof( drm_vbl_sig_t ) ) ) ) {
-			return -ENOMEM;
-		}
-
-		memset( (void *)vbl_sig, 0, sizeof(*vbl_sig) );
-
-		vbl_sig->sequence = vblwait.request.sequence;
-		vbl_sig->info.si_signo = vblwait.request.signal;
-		vbl_sig->task = current;
-
-		spin_lock_irqsave( &dev->vbl_lock, irqflags );
-
-		list_add_tail( (struct list_head *) vbl_sig, &dev->vbl_sigs.head );
-
-		spin_unlock_irqrestore( &dev->vbl_lock, irqflags );
-	} else {
-		if (dev->fn_tbl.vblank_wait)
-			ret = dev->fn_tbl.vblank_wait( dev, &vblwait.request.sequence );
-
-		do_gettimeofday( &now );
-		vblwait.reply.tval_sec = now.tv_sec;
-		vblwait.reply.tval_usec = now.tv_usec;
-	}
-
-done:
-	DRM_COPY_TO_USER_IOCTL( argp, vblwait, sizeof(vblwait) );
-
-	return ret;
-}
-
-/**
- * Send the VBLANK signals.
- *
- * \param dev DRM device.
- *
- * Sends a signal for each task in drm_device::vbl_sigs and empties the list.
- *
- * If a signal is not requested, then calls vblank_wait().
- */
-void DRM(vbl_send_signals)( drm_device_t *dev )
-{
-	struct list_head *list, *tmp;
-	drm_vbl_sig_t *vbl_sig;
-	unsigned int vbl_seq = atomic_read( &dev->vbl_received );
-	unsigned long flags;
-
-	spin_lock_irqsave( &dev->vbl_lock, flags );
-
-	list_for_each_safe( list, tmp, &dev->vbl_sigs.head ) {
-		vbl_sig = list_entry( list, drm_vbl_sig_t, head );
-		if ( ( vbl_seq - vbl_sig->sequence ) <= (1<<23) ) {
-			vbl_sig->info.si_code = vbl_seq;
-			send_sig_info( vbl_sig->info.si_signo, &vbl_sig->info, vbl_sig->task );
-
-			list_del( list );
-
-			DRM_FREE( vbl_sig, sizeof(*vbl_sig) );
-
-			dev->vbl_pending--;
-		}
-	}
-
-	spin_unlock_irqrestore( &dev->vbl_lock, flags );
-}
-
-
diff -Nru a/drivers/char/drm/drm_lock.c b/drivers/char/drm/drm_lock.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/char/drm/drm_lock.c	2005-03-01 23:39:07 -08:00
@@ -0,0 +1,303 @@
+/**
+ * \file drm_lock.h 
+ * IOCTLs for locking
+ * 
+ * \author Rickard E. (Rik) Faith <faith@valinux.com>
+ * \author Gareth Hughes <gareth@valinux.com>
+ */
+
+/*
+ * Created: Tue Feb  2 08:37:54 1999 by faith@valinux.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "drmP.h"
+
+/** 
+ * Lock ioctl.
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument, pointing to a drm_lock structure.
+ * \return zero on success or negative number on failure.
+ *
+ * Add the current task to the lock wait queue, and attempt to take to lock.
+ */
+int drm_lock( struct inode *inode, struct file *filp,
+	       unsigned int cmd, unsigned long arg )
+{
+        drm_file_t *priv = filp->private_data;
+        drm_device_t *dev = priv->dev;
+        DECLARE_WAITQUEUE( entry, current );
+        drm_lock_t lock;
+        int ret = 0;
+
+	++priv->lock_count;
+
+        if ( copy_from_user( &lock, (drm_lock_t __user *)arg, sizeof(lock) ) )
+		return -EFAULT;
+
+        if ( lock.context == DRM_KERNEL_CONTEXT ) {
+                DRM_ERROR( "Process %d using kernel context %d\n",
+			   current->pid, lock.context );
+                return -EINVAL;
+        }
+
+        DRM_DEBUG( "%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n",
+		   lock.context, current->pid,
+		   dev->lock.hw_lock->lock, lock.flags );
+
+	if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE))
+		if ( lock.context < 0 )
+			return -EINVAL;
+
+	add_wait_queue( &dev->lock.lock_queue, &entry );
+	for (;;) {
+		__set_current_state(TASK_INTERRUPTIBLE);
+		if ( !dev->lock.hw_lock ) {
+			/* Device has been unregistered */
+			ret = -EINTR;
+			break;
+		}
+		if ( drm_lock_take( &dev->lock.hw_lock->lock,
+				     lock.context ) ) {
+			dev->lock.filp      = filp;
+			dev->lock.lock_time = jiffies;
+			atomic_inc( &dev->counts[_DRM_STAT_LOCKS] );
+			break;  /* Got lock */
+		}
+		
+		/* Contention */
+		schedule();
+		if ( signal_pending( current ) ) {
+			ret = -ERESTARTSYS;
+			break;
+		}
+	}
+	__set_current_state(TASK_RUNNING);
+	remove_wait_queue( &dev->lock.lock_queue, &entry );
+
+	sigemptyset( &dev->sigmask );
+	sigaddset( &dev->sigmask, SIGSTOP );
+	sigaddset( &dev->sigmask, SIGTSTP );
+	sigaddset( &dev->sigmask, SIGTTIN );
+	sigaddset( &dev->sigmask, SIGTTOU );
+	dev->sigdata.context = lock.context;
+	dev->sigdata.lock    = dev->lock.hw_lock;
+	block_all_signals( drm_notifier,
+			   &dev->sigdata, &dev->sigmask );
+	
+	if (dev->driver->dma_ready && (lock.flags & _DRM_LOCK_READY))
+		dev->driver->dma_ready(dev);
+	
+	if ( dev->driver->dma_quiescent && (lock.flags & _DRM_LOCK_QUIESCENT ))
+		return dev->driver->dma_quiescent(dev);
+	
+	/* dev->driver->kernel_context_switch isn't used by any of the x86 
+	 *  drivers but is used by the Sparc driver.
+	 */
+	
+	if (dev->driver->kernel_context_switch && 
+	    dev->last_context != lock.context) {
+	  dev->driver->kernel_context_switch(dev, dev->last_context, 
+					    lock.context);
+	}
+        DRM_DEBUG( "%d %s\n", lock.context, ret ? "interrupted" : "has lock" );
+
+        return ret;
+}
+
+/** 
+ * Unlock ioctl.
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument, pointing to a drm_lock structure.
+ * \return zero on success or negative number on failure.
+ *
+ * Transfer and free the lock.
+ */
+int drm_unlock( struct inode *inode, struct file *filp,
+		 unsigned int cmd, unsigned long arg )
+{
+	drm_file_t *priv = filp->private_data;
+	drm_device_t *dev = priv->dev;
+	drm_lock_t lock;
+
+	if ( copy_from_user( &lock, (drm_lock_t __user *)arg, sizeof(lock) ) )
+		return -EFAULT;
+
+	if ( lock.context == DRM_KERNEL_CONTEXT ) {
+		DRM_ERROR( "Process %d using kernel context %d\n",
+			   current->pid, lock.context );
+		return -EINVAL;
+	}
+
+	atomic_inc( &dev->counts[_DRM_STAT_UNLOCKS] );
+
+	/* kernel_context_switch isn't used by any of the x86 drm
+	 * modules but is required by the Sparc driver.
+	 */
+	if (dev->driver->kernel_context_switch_unlock)
+		dev->driver->kernel_context_switch_unlock(dev, &lock);
+	else {
+		drm_lock_transfer( dev, &dev->lock.hw_lock->lock, 
+				    DRM_KERNEL_CONTEXT );
+		
+		if ( drm_lock_free( dev, &dev->lock.hw_lock->lock,
+				     DRM_KERNEL_CONTEXT ) ) {
+			DRM_ERROR( "\n" );
+		}
+	}
+
+	unblock_all_signals();
+	return 0;
+}
+
+/**
+ * Take the heavyweight lock.
+ *
+ * \param lock lock pointer.
+ * \param context locking context.
+ * \return one if the lock is held, or zero otherwise.
+ *
+ * Attempt to mark the lock as held by the given context, via the \p cmpxchg instruction.
+ */
+int drm_lock_take(__volatile__ unsigned int *lock, unsigned int context)
+{
+	unsigned int old, new, prev;
+
+	do {
+		old = *lock;
+		if (old & _DRM_LOCK_HELD) new = old | _DRM_LOCK_CONT;
+		else			  new = context | _DRM_LOCK_HELD;
+		prev = cmpxchg(lock, old, new);
+	} while (prev != old);
+	if (_DRM_LOCKING_CONTEXT(old) == context) {
+		if (old & _DRM_LOCK_HELD) {
+			if (context != DRM_KERNEL_CONTEXT) {
+				DRM_ERROR("%d holds heavyweight lock\n",
+					  context);
+			}
+			return 0;
+		}
+	}
+	if (new == (context | _DRM_LOCK_HELD)) {
+				/* Have lock */
+		return 1;
+	}
+	return 0;
+}
+
+/**
+ * This takes a lock forcibly and hands it to context.	Should ONLY be used
+ * inside *_unlock to give lock to kernel before calling *_dma_schedule. 
+ * 
+ * \param dev DRM device.
+ * \param lock lock pointer.
+ * \param context locking context.
+ * \return always one.
+ *
+ * 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)
+{
+	unsigned int old, new, prev;
+
+	dev->lock.filp = NULL;
+	do {
+		old  = *lock;
+		new  = context | _DRM_LOCK_HELD;
+		prev = cmpxchg(lock, old, new);
+	} while (prev != old);
+	return 1;
+}
+
+/**
+ * Free lock.
+ * 
+ * \param dev DRM device.
+ * \param lock lock.
+ * \param context context.
+ * 
+ * Resets the lock file pointer.
+ * Marks the lock as not held, via the \p cmpxchg instruction. Wakes any task
+ * waiting on the lock queue.
+ */
+int drm_lock_free(drm_device_t *dev,
+		   __volatile__ unsigned int *lock, unsigned int context)
+{
+	unsigned int old, new, prev;
+
+	dev->lock.filp = NULL;
+	do {
+		old  = *lock;
+		new  = 0;
+		prev = cmpxchg(lock, old, new);
+	} while (prev != old);
+	if (_DRM_LOCK_IS_HELD(old) && _DRM_LOCKING_CONTEXT(old) != context) {
+		DRM_ERROR("%d freed heavyweight lock held by %d\n",
+			  context,
+			  _DRM_LOCKING_CONTEXT(old));
+		return 1;
+	}
+	wake_up_interruptible(&dev->lock.lock_queue);
+	return 0;
+}
+
+/**
+ * If we get here, it means that the process has called DRM_IOCTL_LOCK
+ * without calling DRM_IOCTL_UNLOCK.
+ *
+ * If the lock is not held, then let the signal proceed as usual.  If the lock
+ * is held, then set the contended flag and keep the signal blocked.
+ *
+ * \param priv pointer to a drm_sigdata structure.
+ * \return one if the signal should be delivered normally, or zero if the
+ * signal should be blocked.
+ */
+int drm_notifier(void *priv)
+{
+	drm_sigdata_t *s = (drm_sigdata_t *)priv;
+	unsigned int  old, new, prev;
+
+
+				/* Allow signal delivery if lock isn't held */
+	if (!s->lock || !_DRM_LOCK_IS_HELD(s->lock->lock)
+	    || _DRM_LOCKING_CONTEXT(s->lock->lock) != s->context) return 1;
+
+				/* Otherwise, set flag to force call to
+                                   drmUnlock */
+	do {
+		old  = s->lock->lock;
+		new  = old | _DRM_LOCK_CONT;
+		prev = cmpxchg(&s->lock->lock, old, new);
+	} while (prev != old);
+	return 0;
+}
diff -Nru a/drivers/char/drm/drm_lock.h b/drivers/char/drm/drm_lock.h
--- a/drivers/char/drm/drm_lock.h	2005-03-01 23:39:07 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,168 +0,0 @@
-/**
- * \file drm_lock.h 
- * IOCTLs for locking
- * 
- * \author Rickard E. (Rik) Faith <faith@valinux.com>
- * \author Gareth Hughes <gareth@valinux.com>
- */
-
-/*
- * Created: Tue Feb  2 08:37:54 1999 by faith@valinux.com
- *
- * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include "drmP.h"
-
-/** No-op ioctl. */
-int DRM(noop)(struct inode *inode, struct file *filp, unsigned int cmd,
-	       unsigned long arg)
-{
-	DRM_DEBUG("\n");
-	return 0;
-}
-
-/**
- * Take the heavyweight lock.
- *
- * \param lock lock pointer.
- * \param context locking context.
- * \return one if the lock is held, or zero otherwise.
- *
- * Attempt to mark the lock as held by the given context, via the \p cmpxchg instruction.
- */
-int DRM(lock_take)(__volatile__ unsigned int *lock, unsigned int context)
-{
-	unsigned int old, new, prev;
-
-	do {
-		old = *lock;
-		if (old & _DRM_LOCK_HELD) new = old | _DRM_LOCK_CONT;
-		else			  new = context | _DRM_LOCK_HELD;
-		prev = cmpxchg(lock, old, new);
-	} while (prev != old);
-	if (_DRM_LOCKING_CONTEXT(old) == context) {
-		if (old & _DRM_LOCK_HELD) {
-			if (context != DRM_KERNEL_CONTEXT) {
-				DRM_ERROR("%d holds heavyweight lock\n",
-					  context);
-			}
-			return 0;
-		}
-	}
-	if (new == (context | _DRM_LOCK_HELD)) {
-				/* Have lock */
-		return 1;
-	}
-	return 0;
-}
-
-/**
- * This takes a lock forcibly and hands it to context.	Should ONLY be used
- * inside *_unlock to give lock to kernel before calling *_dma_schedule. 
- * 
- * \param dev DRM device.
- * \param lock lock pointer.
- * \param context locking context.
- * \return always one.
- *
- * 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)
-{
-	unsigned int old, new, prev;
-
-	dev->lock.filp = NULL;
-	do {
-		old  = *lock;
-		new  = context | _DRM_LOCK_HELD;
-		prev = cmpxchg(lock, old, new);
-	} while (prev != old);
-	return 1;
-}
-
-/**
- * Free lock.
- * 
- * \param dev DRM device.
- * \param lock lock.
- * \param context context.
- * 
- * Resets the lock file pointer.
- * Marks the lock as not held, via the \p cmpxchg instruction. Wakes any task
- * waiting on the lock queue.
- */
-int DRM(lock_free)(drm_device_t *dev,
-		   __volatile__ unsigned int *lock, unsigned int context)
-{
-	unsigned int old, new, prev;
-
-	dev->lock.filp = NULL;
-	do {
-		old  = *lock;
-		new  = 0;
-		prev = cmpxchg(lock, old, new);
-	} while (prev != old);
-	if (_DRM_LOCK_IS_HELD(old) && _DRM_LOCKING_CONTEXT(old) != context) {
-		DRM_ERROR("%d freed heavyweight lock held by %d\n",
-			  context,
-			  _DRM_LOCKING_CONTEXT(old));
-		return 1;
-	}
-	wake_up_interruptible(&dev->lock.lock_queue);
-	return 0;
-}
-
-/**
- * If we get here, it means that the process has called DRM_IOCTL_LOCK
- * without calling DRM_IOCTL_UNLOCK.
- *
- * If the lock is not held, then let the signal proceed as usual.  If the lock
- * is held, then set the contended flag and keep the signal blocked.
- *
- * \param priv pointer to a drm_sigdata structure.
- * \return one if the signal should be delivered normally, or zero if the
- * signal should be blocked.
- */
-int DRM(notifier)(void *priv)
-{
-	drm_sigdata_t *s = (drm_sigdata_t *)priv;
-	unsigned int  old, new, prev;
-
-
-				/* Allow signal delivery if lock isn't held */
-	if (!s->lock || !_DRM_LOCK_IS_HELD(s->lock->lock)
-	    || _DRM_LOCKING_CONTEXT(s->lock->lock) != s->context) return 1;
-
-				/* Otherwise, set flag to force call to
-                                   drmUnlock */
-	do {
-		old  = s->lock->lock;
-		new  = old | _DRM_LOCK_CONT;
-		prev = cmpxchg(&s->lock->lock, old, new);
-	} while (prev != old);
-	return 0;
-}
diff -Nru a/drivers/char/drm/drm_memory.c b/drivers/char/drm/drm_memory.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/char/drm/drm_memory.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,181 @@
+/** 
+ * \file drm_memory.h 
+ * Memory management wrappers for DRM
+ *
+ * \author Rickard E. (Rik) Faith <faith@valinux.com>
+ * \author Gareth Hughes <gareth@valinux.com>
+ */
+
+/* 
+ * Created: Thu Feb  4 14:00:34 1999 by faith@valinux.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <linux/config.h>
+#include <linux/highmem.h>
+#include "drmP.h"
+
+#ifdef DEBUG_MEMORY
+#include "drm_memory_debug.h"
+#else
+
+/** No-op. */
+void drm_mem_init(void)
+{
+}
+
+/**
+ * Called when "/proc/dri/%dev%/mem" is read.
+ * 
+ * \param buf output buffer.
+ * \param start start of output data.
+ * \param offset requested start offset.
+ * \param len requested number of bytes.
+ * \param eof whether there is no more data to return.
+ * \param data private data.
+ * \return number of written bytes.
+ *
+ * No-op. 
+ */
+int drm_mem_info(char *buf, char **start, off_t offset,
+		  int len, int *eof, void *data)
+{
+	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)
+{
+	void *pt;
+
+	if (!(pt = kmalloc(size, GFP_KERNEL))) return NULL;
+	if (oldpt && oldsize) {
+		memcpy(pt, oldpt, oldsize);
+		kfree(oldpt);
+	}
+	return pt;
+}
+
+/**
+ * Allocate pages.
+ *
+ * \param order size order.
+ * \param area memory area. (Not used.)
+ * \return page address on success, or zero on failure.
+ *
+ * Allocate and reserve free pages.
+ */
+unsigned long drm_alloc_pages(int order, int area)
+{
+	unsigned long address;
+	unsigned long bytes	  = PAGE_SIZE << order;
+	unsigned long addr;
+	unsigned int  sz;
+
+	address = __get_free_pages(GFP_KERNEL, order);
+	if (!address) 
+		return 0;
+
+				/* Zero */
+	memset((void *)address, 0, bytes);
+
+				/* Reserve */
+	for (addr = address, sz = bytes;
+	     sz > 0;
+	     addr += PAGE_SIZE, sz -= PAGE_SIZE) {
+		SetPageReserved(virt_to_page(addr));
+	}
+
+	return address;
+}
+
+/**
+ * Free pages.
+ * 
+ * \param address address of the pages to free.
+ * \param order size order.
+ * \param area memory area. (Not used.)
+ *
+ * Unreserve and free pages allocated by alloc_pages().
+ */
+void drm_free_pages(unsigned long address, int order, int area)
+{
+	unsigned long bytes = PAGE_SIZE << order;
+	unsigned long addr;
+	unsigned int  sz;
+
+	if (!address) 
+		return;
+
+	/* Unreserve */
+	for (addr = address, sz = bytes;
+	     sz > 0;
+	     addr += PAGE_SIZE, sz -= PAGE_SIZE) {
+		ClearPageReserved(virt_to_page(addr));
+	}
+
+	free_pages(address, order);
+}
+
+
+#if __OS_HAS_AGP
+/** Wrapper around agp_allocate_memory() */
+DRM_AGP_MEM *drm_alloc_agp(int pages, u32 type)
+{
+	return drm_agp_allocate_memory(pages, type);
+}
+
+/** Wrapper around agp_free_memory() */
+int drm_free_agp(DRM_AGP_MEM *handle, int pages)
+{
+	return drm_agp_free_memory(handle) ? 0 : -EINVAL;
+}
+
+/** Wrapper around agp_bind_memory() */
+int drm_bind_agp(DRM_AGP_MEM *handle, unsigned int start)
+{
+	return drm_agp_bind_memory(handle, start);
+}
+
+/** Wrapper around agp_unbind_memory() */
+int drm_unbind_agp(DRM_AGP_MEM *handle)
+{
+	return drm_agp_unbind_memory(handle);
+}
+#endif /* agp */
+#endif /* debug_memory */
diff -Nru a/drivers/char/drm/drm_memory.h b/drivers/char/drm/drm_memory.h
--- a/drivers/char/drm/drm_memory.h	2005-03-01 23:38:53 -08:00
+++ b/drivers/char/drm/drm_memory.h	2005-03-01 23:38:53 -08:00
@@ -35,14 +35,13 @@
 
 #include <linux/config.h>
 #include <linux/highmem.h>
+#include <linux/vmalloc.h>
 #include "drmP.h"
 
 /**
  * Cut down version of drm_memory_debug.h, which used to be called
- * drm_memory.h.  If you want the debug functionality, change 0 to 1
- * below.
+ * drm_memory.h.  
  */
-#define DEBUG_MEMORY 0
 
 #if __OS_HAS_AGP
 
@@ -58,8 +57,6 @@
 # endif
 #endif
 
-#include <asm/tlbflush.h>
-
 /*
  * Find the drm_map that covers the range [offset, offset+size).
  */
@@ -125,7 +122,8 @@
 drm_follow_page (void *vaddr)
 {
 	pgd_t *pgd = pgd_offset_k((unsigned long) vaddr);
-	pmd_t *pmd = pmd_offset(pgd, (unsigned long) vaddr);
+	pud_t *pud = pud_offset(pgd, (unsigned long) vaddr);
+	pmd_t *pmd = pmd_offset(pud, (unsigned long) vaddr);
 	pte_t *ptep = pte_offset_kernel(pmd, (unsigned long) vaddr);
 	return pte_pfn(*ptep) << PAGE_SHIFT;
 }
@@ -197,173 +195,3 @@
 }
 
 
-#if DEBUG_MEMORY
-#include "drm_memory_debug.h"
-#else
-
-/** No-op. */
-void DRM(mem_init)(void)
-{
-}
-
-/**
- * Called when "/proc/dri/%dev%/mem" is read.
- * 
- * \param buf output buffer.
- * \param start start of output data.
- * \param offset requested start offset.
- * \param len requested number of bytes.
- * \param eof whether there is no more data to return.
- * \param data private data.
- * \return number of written bytes.
- *
- * No-op. 
- */
-int DRM(mem_info)(char *buf, char **start, off_t offset,
-		  int len, int *eof, void *data)
-{
-	return 0;
-}
-
-/** Wrapper around kmalloc() */
-void *DRM(alloc)(size_t size, int area)
-{
-	return kmalloc(size, GFP_KERNEL);
-}
-
-/** Wrapper around kmalloc() */
-void *DRM(calloc)(size_t size, size_t nmemb, int area)
-{
-	void *addr;
-
-	addr = kmalloc(size * nmemb, GFP_KERNEL);
-	if (addr != NULL)
-		memset((void *)addr, 0, size * nmemb);
-
-	return addr;
-}
-
-/** Wrapper around kmalloc() and kfree() */
-void *DRM(realloc)(void *oldpt, size_t oldsize, size_t size, int area)
-{
-	void *pt;
-
-	if (!(pt = kmalloc(size, GFP_KERNEL))) return NULL;
-	if (oldpt && oldsize) {
-		memcpy(pt, oldpt, oldsize);
-		kfree(oldpt);
-	}
-	return pt;
-}
-
-/** Wrapper around kfree() */
-void DRM(free)(void *pt, size_t size, int area)
-{
-	kfree(pt);
-}
-
-/**
- * Allocate pages.
- *
- * \param order size order.
- * \param area memory area. (Not used.)
- * \return page address on success, or zero on failure.
- *
- * Allocate and reserve free pages.
- */
-unsigned long DRM(alloc_pages)(int order, int area)
-{
-	unsigned long address;
-	unsigned long bytes	  = PAGE_SIZE << order;
-	unsigned long addr;
-	unsigned int  sz;
-
-	address = __get_free_pages(GFP_KERNEL, order);
-	if (!address) 
-		return 0;
-
-				/* Zero */
-	memset((void *)address, 0, bytes);
-
-				/* Reserve */
-	for (addr = address, sz = bytes;
-	     sz > 0;
-	     addr += PAGE_SIZE, sz -= PAGE_SIZE) {
-		SetPageReserved(virt_to_page(addr));
-	}
-
-	return address;
-}
-
-/**
- * Free pages.
- * 
- * \param address address of the pages to free.
- * \param order size order.
- * \param area memory area. (Not used.)
- *
- * Unreserve and free pages allocated by alloc_pages().
- */
-void DRM(free_pages)(unsigned long address, int order, int area)
-{
-	unsigned long bytes = PAGE_SIZE << order;
-	unsigned long addr;
-	unsigned int  sz;
-
-	if (!address) 
-		return;
-
-	/* Unreserve */
-	for (addr = address, sz = bytes;
-	     sz > 0;
-	     addr += PAGE_SIZE, sz -= PAGE_SIZE) {
-		ClearPageReserved(virt_to_page(addr));
-	}
-
-	free_pages(address, order);
-}
-
-/** Wrapper around drm_ioremap() */
-void *DRM(ioremap)(unsigned long offset, unsigned long size, drm_device_t *dev)
-{
-	return drm_ioremap(offset, size, dev);
-}
-
-/** Wrapper around drm_ioremap_nocache() */
-void *DRM(ioremap_nocache)(unsigned long offset, unsigned long size, drm_device_t *dev)
-{
-	return drm_ioremap_nocache(offset, size, dev);
-}
-
-/** Wrapper around drm_iounmap() */
-void DRM(ioremapfree)(void *pt, unsigned long size, drm_device_t *dev)
-{
-	drm_ioremapfree(pt, size, dev);
-}
-
-#if __OS_HAS_AGP
-/** Wrapper around agp_allocate_memory() */
-DRM_AGP_MEM *DRM(alloc_agp)(int pages, u32 type)
-{
-	return DRM(agp_allocate_memory)(pages, type);
-}
-
-/** Wrapper around agp_free_memory() */
-int DRM(free_agp)(DRM_AGP_MEM *handle, int pages)
-{
-	return DRM(agp_free_memory)(handle) ? 0 : -EINVAL;
-}
-
-/** Wrapper around agp_bind_memory() */
-int DRM(bind_agp)(DRM_AGP_MEM *handle, unsigned int start)
-{
-	return DRM(agp_bind_memory)(handle, start);
-}
-
-/** Wrapper around agp_unbind_memory() */
-int DRM(unbind_agp)(DRM_AGP_MEM *handle)
-{
-	return DRM(agp_unbind_memory)(handle);
-}
-#endif /* agp */
-#endif /* debug_memory */
diff -Nru a/drivers/char/drm/drm_memory_debug.h b/drivers/char/drm/drm_memory_debug.h
--- a/drivers/char/drm/drm_memory_debug.h	2005-03-01 23:38:53 -08:00
+++ b/drivers/char/drm/drm_memory_debug.h	2005-03-01 23:38:53 -08:00
@@ -43,7 +43,7 @@
 	unsigned long	  bytes_freed;
 } drm_mem_stats_t;
 
-static spinlock_t	  DRM(mem_lock)	     = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(DRM(mem_lock));
 static unsigned long	  DRM(ram_available) = 0; /* In pages */
 static unsigned long	  DRM(ram_used)      = 0;
 static drm_mem_stats_t	  DRM(mem_stats)[]   = {
@@ -167,7 +167,7 @@
 	return pt;
 }
 
-void *DRM(calloc)(size_t size, size_t nmemb, int area)
+void *DRM(calloc)(size_t nmemb, size_t size, int area)
 {
 	void *addr;
 
diff -Nru a/drivers/char/drm/drm_os_linux.h b/drivers/char/drm/drm_os_linux.h
--- a/drivers/char/drm/drm_os_linux.h	2005-03-01 23:39:16 -08:00
+++ b/drivers/char/drm/drm_os_linux.h	2005-03-01 23:39:16 -08:00
@@ -96,14 +96,6 @@
 	__copy_to_user(arg1, arg2, arg3)
 #define DRM_GET_USER_UNCHECKED(val, uaddr)		\
 	__get_user(val, uaddr)
-#define DRM_PUT_USER_UNCHECKED(uaddr, val)		\
-	__put_user(val, uaddr)
-
-
-/** 'malloc' without the overhead of DRM(alloc)() */
-#define DRM_MALLOC(x) kmalloc(x, GFP_KERNEL)
-/** 'free' without the overhead of DRM(free)() */
-#define DRM_FREE(x,size) kfree(x)
 
 #define DRM_GET_PRIV_WITH_RETURN(_priv, _filp) _priv = _filp->private_data
 
diff -Nru a/drivers/char/drm/drm_pci.c b/drivers/char/drm/drm_pci.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/char/drm/drm_pci.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,140 @@
+/* drm_pci.h -- PCI DMA memory management wrappers for DRM -*- linux-c -*- */
+/**
+ * \file drm_pci.c
+ * \brief Functions and ioctls to manage PCI memory
+ *
+ * \warning These interfaces aren't stable yet.
+ *
+ * \todo Implement the remaining ioctl's for the PCI pools.
+ * \todo The wrappers here are so thin that they would be better off inlined..
+ *
+ * \author Jose Fonseca <jrfonseca@tungstengraphics.com>
+ * \author Leif Delgass <ldelgass@retinalburn.net>
+ */
+
+/*
+ * Copyright 2003 Josï¿½Fonseca.
+ * Copyright 2003 Leif Delgass.
+ * 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
+ * AUTHORS 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/pci.h>
+#include "drmP.h"
+
+/**********************************************************************/
+/** \name PCI memory */
+/*@{*/
+
+/**
+ * \brief Allocate a PCI consistent memory block, for DMA.
+ */
+void *drm_pci_alloc(drm_device_t * dev, size_t size, size_t align,
+		    dma_addr_t maxaddr, dma_addr_t * busaddr)
+{
+	void *address;
+#if DRM_DEBUG_MEMORY
+	int area = DRM_MEM_DMA;
+
+	spin_lock(&drm_mem_lock);
+	if ((drm_ram_used >> PAGE_SHIFT)
+	    > (DRM_RAM_PERCENT * drm_ram_available) / 100) {
+		spin_unlock(&drm_mem_lock);
+		return 0;
+	}
+	spin_unlock(&drm_mem_lock);
+#endif
+
+	/* pci_alloc_consistent only guarantees alignment to the smallest
+	 * PAGE_SIZE order which is greater than or equal to the requested size.
+	 * Return NULL here for now to make sure nobody tries for larger alignment
+	 */
+	if (align > size)
+		return NULL;
+
+	if (pci_set_dma_mask(dev->pdev, maxaddr) != 0) {
+		DRM_ERROR("Setting pci dma mask failed\n");
+		return NULL;
+	}
+
+	address = pci_alloc_consistent(dev->pdev, size, busaddr);
+
+#if DRM_DEBUG_MEMORY
+	if (address == NULL) {
+		spin_lock(&drm_mem_lock);
+		++drm_mem_stats[area].fail_count;
+		spin_unlock(&drm_mem_lock);
+		return NULL;
+	}
+
+	spin_lock(&drm_mem_lock);
+	++drm_mem_stats[area].succeed_count;
+	drm_mem_stats[area].bytes_allocated += size;
+	drm_ram_used += size;
+	spin_unlock(&drm_mem_lock);
+#else
+	if (address == NULL)
+		return NULL;
+#endif
+
+	memset(address, 0, size);
+
+	return address;
+}
+EXPORT_SYMBOL(drm_pci_alloc);
+
+/**
+ * \brief Free a PCI consistent memory block.
+ */
+void
+drm_pci_free(drm_device_t * dev, size_t size, void *vaddr, dma_addr_t busaddr)
+{
+#if DRM_DEBUG_MEMORY
+	int area = DRM_MEM_DMA;
+	int alloc_count;
+	int free_count;
+#endif
+
+	if (!vaddr) {
+#if DRM_DEBUG_MEMORY
+		DRM_MEM_ERROR(area, "Attempt to free address 0\n");
+#endif
+	} else {
+		pci_free_consistent(dev->pdev, size, vaddr, busaddr);
+	}
+
+#if DRM_DEBUG_MEMORY
+	spin_lock(&drm_mem_lock);
+	free_count = ++drm_mem_stats[area].free_count;
+	alloc_count = drm_mem_stats[area].succeed_count;
+	drm_mem_stats[area].bytes_freed += size;
+	drm_ram_used -= size;
+	spin_unlock(&drm_mem_lock);
+	if (free_count > alloc_count) {
+		DRM_MEM_ERROR(area,
+			      "Excess frees: %d frees, %d allocs\n",
+			      free_count, alloc_count);
+	}
+#endif
+
+}
+EXPORT_SYMBOL(drm_pci_free);
+
+/*@}*/
diff -Nru a/drivers/char/drm/drm_pciids.h b/drivers/char/drm/drm_pciids.h
--- a/drivers/char/drm/drm_pciids.h	2005-03-01 23:38:56 -08:00
+++ b/drivers/char/drm/drm_pciids.h	2005-03-01 23:38:56 -08:00
@@ -3,64 +3,75 @@
    Please contact dri-devel@lists.sf.net to add new cards to this list
 */
 #define radeon_PCI_IDS \
-	{0x1002, 0x4136, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
-	{0x1002, 0x4137, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
-	{0x1002, 0x4237, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
-	{0x1002, 0x4242, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
-	{0x1002, 0x4242, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
-	{0x1002, 0x4336, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
-	{0x1002, 0x4337, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
-	{0x1002, 0x4437, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
-	{0x1002, 0x4964, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
-	{0x1002, 0x4965, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
-	{0x1002, 0x4966, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
-	{0x1002, 0x4967, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
-	{0x1002, 0x4C57, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
-	{0x1002, 0x4C58, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
-	{0x1002, 0x4C59, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
-	{0x1002, 0x4C5A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
-	{0x1002, 0x4C64, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
-	{0x1002, 0x4C65, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
-	{0x1002, 0x4C66, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
-	{0x1002, 0x4C67, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
-	{0x1002, 0x5144, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
-	{0x1002, 0x5145, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
-	{0x1002, 0x5146, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
-	{0x1002, 0x5147, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
-	{0x1002, 0x5148, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
-	{0x1002, 0x5149, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
-	{0x1002, 0x514A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
-	{0x1002, 0x514B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
-	{0x1002, 0x514C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
-	{0x1002, 0x514D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
-	{0x1002, 0x514E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
-	{0x1002, 0x514F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
-	{0x1002, 0x5157, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
-	{0x1002, 0x5158, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
-	{0x1002, 0x5159, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
-	{0x1002, 0x515A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
-	{0x1002, 0x5168, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
-	{0x1002, 0x5169, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
-	{0x1002, 0x516A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
-	{0x1002, 0x516B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
-	{0x1002, 0x516C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
-	{0x1002, 0x5834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
-	{0x1002, 0x5835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
-	{0x1002, 0x5836, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
-	{0x1002, 0x5837, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
-	{0x1002, 0x5960, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
-	{0x1002, 0x5961, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
-	{0x1002, 0x5962, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
-	{0x1002, 0x5963, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
-	{0x1002, 0x5964, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
-	{0x1002, 0x5968, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
-	{0x1002, 0x5969, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
-	{0x1002, 0x596A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
-	{0x1002, 0x596B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
-	{0x1002, 0x5c61, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
-	{0x1002, 0x5c62, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
-	{0x1002, 0x5c63, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
-	{0x1002, 0x5c64, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
+	{0x1002, 0x4136, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS100|CHIP_IS_IGP}, \
+	{0x1002, 0x4137, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|CHIP_IS_IGP}, \
+	{0x1002, 0x4144, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \
+	{0x1002, 0x4145, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \
+	{0x1002, 0x4146, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \
+	{0x1002, 0x4147, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \
+	{0x1002, 0x4150, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \
+	{0x1002, 0x4151, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \
+	{0x1002, 0x4152, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \
+	{0x1002, 0x4153, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \
+	{0x1002, 0x4154, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \
+	{0x1002, 0x4156, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \
+	{0x1002, 0x4237, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS250|CHIP_IS_IGP}, \
+	{0x1002, 0x4242, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
+	{0x1002, 0x4243, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
+	{0x1002, 0x4336, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS100|CHIP_IS_IGP|CHIP_IS_MOBILITY}, \
+	{0x1002, 0x4337, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|CHIP_IS_IGP|CHIP_IS_MOBILITY}, \
+	{0x1002, 0x4437, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS250|CHIP_IS_IGP|CHIP_IS_MOBILITY}, \
+	{0x1002, 0x4964, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R250}, \
+	{0x1002, 0x4965, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R250}, \
+	{0x1002, 0x4966, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R250}, \
+	{0x1002, 0x4967, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R250}, \
+	{0x1002, 0x4C57, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV200|CHIP_IS_MOBILITY}, \
+	{0x1002, 0x4C58, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV200|CHIP_IS_MOBILITY}, \
+	{0x1002, 0x4C59, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100|CHIP_IS_MOBILITY}, \
+	{0x1002, 0x4C5A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100|CHIP_IS_MOBILITY}, \
+	{0x1002, 0x4C64, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R250|CHIP_IS_MOBILITY}, \
+	{0x1002, 0x4C65, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R250|CHIP_IS_MOBILITY}, \
+	{0x1002, 0x4C66, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R250|CHIP_IS_MOBILITY}, \
+	{0x1002, 0x4C67, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R250|CHIP_IS_MOBILITY}, \
+	{0x1002, 0x4E50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \
+	{0x1002, 0x5144, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \
+	{0x1002, 0x5145, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \
+	{0x1002, 0x5146, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \
+	{0x1002, 0x5147, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \
+	{0x1002, 0x5148, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
+	{0x1002, 0x5149, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
+	{0x1002, 0x514A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
+	{0x1002, 0x514B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
+	{0x1002, 0x514C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
+	{0x1002, 0x514D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
+	{0x1002, 0x514E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
+	{0x1002, 0x514F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
+	{0x1002, 0x5157, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV200}, \
+	{0x1002, 0x5158, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV200}, \
+	{0x1002, 0x5159, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \
+	{0x1002, 0x515A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \
+	{0x1002, 0x5168, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
+	{0x1002, 0x5169, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
+	{0x1002, 0x516A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
+	{0x1002, 0x516B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
+	{0x1002, 0x516C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
+	{0x1002, 0x5834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP}, \
+	{0x1002, 0x5835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP|CHIP_IS_MOBILITY}, \
+	{0x1002, 0x5836, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP}, \
+	{0x1002, 0x5837, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP}, \
+	{0x1002, 0x5960, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
+	{0x1002, 0x5961, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
+	{0x1002, 0x5962, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
+	{0x1002, 0x5963, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
+	{0x1002, 0x5964, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
+	{0x1002, 0x5968, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
+	{0x1002, 0x5969, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
+	{0x1002, 0x596A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
+	{0x1002, 0x596B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
+	{0x1002, 0x5c61, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|CHIP_IS_MOBILITY}, \
+	{0x1002, 0x5c62, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
+	{0x1002, 0x5c63, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|CHIP_IS_MOBILITY}, \
+	{0x1002, 0x5c64, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
 	{0, 0, 0}
 
 #define r128_PCI_IDS \
@@ -207,5 +218,6 @@
 	{0x8086, 0x3582, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
 	{0x8086, 0x2572, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
 	{0x8086, 0x2582, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
+	{0x8086, 0x2982, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
 	{0, 0, 0}
 
diff -Nru a/drivers/char/drm/drm_proc.c b/drivers/char/drm/drm_proc.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/char/drm/drm_proc.c	2005-03-01 23:38:52 -08:00
@@ -0,0 +1,539 @@
+/**
+ * \file drm_proc.h 
+ * /proc support for DRM
+ *
+ * \author Rickard E. (Rik) Faith <faith@valinux.com>
+ * \author Gareth Hughes <gareth@valinux.com>
+ *
+ * \par Acknowledgements:
+ *    Matthew J Sottek <matthew.j.sottek@intel.com> sent in a patch to fix
+ *    the problem with the proc files not outputting all their information.
+ */
+
+/*
+ * Created: Mon Jan 11 09:48:47 1999 by faith@valinux.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "drmP.h"
+
+static int	   drm_name_info(char *buf, char **start, off_t offset,
+				  int request, int *eof, void *data);
+static int	   drm_vm_info(char *buf, char **start, off_t offset,
+				int request, int *eof, void *data);
+static int	   drm_clients_info(char *buf, char **start, off_t offset,
+				     int request, int *eof, void *data);
+static int	   drm_queues_info(char *buf, char **start, off_t offset,
+				    int request, int *eof, void *data);
+static int	   drm_bufs_info(char *buf, char **start, off_t offset,
+				  int request, int *eof, void *data);
+#if DRM_DEBUG_CODE
+static int	   drm_vma_info(char *buf, char **start, off_t offset,
+				 int request, int *eof, void *data);
+#endif
+
+/**
+ * Proc file list.
+ */
+struct drm_proc_list {
+	const char *name;	/**< file name */
+	int	   (*f)(char *, char **, off_t, int, int *, void *);	/**< proc callback*/
+} drm_proc_list[] = {
+	{ "name",    drm_name_info    },
+	{ "mem",     drm_mem_info     },
+	{ "vm",	     drm_vm_info      },
+	{ "clients", drm_clients_info },
+	{ "queues",  drm_queues_info  },
+	{ "bufs",    drm_bufs_info    },
+#if DRM_DEBUG_CODE
+	{ "vma",     drm_vma_info     },
+#endif
+};
+#define DRM_PROC_ENTRIES (sizeof(drm_proc_list)/sizeof(drm_proc_list[0]))
+
+/**
+ * Initialize the DRI proc filesystem for a device.
+ *
+ * \param dev DRM device.
+ * \param minor device minor number.
+ * \param root DRI proc dir entry.
+ * \param dev_root resulting DRI device proc dir entry.
+ * \return root entry pointer on success, or NULL on failure.
+ * 
+ * Create the DRI proc root entry "/proc/dri", the device proc root entry
+ * "/proc/dri/%minor%/", and each entry in proc_list as
+ * "/proc/dri/%minor%/%name%".
+ */
+int drm_proc_init(drm_device_t *dev, int minor,
+		    struct proc_dir_entry *root,
+		    struct proc_dir_entry **dev_root)
+{
+	struct proc_dir_entry *ent;
+	int		      i, j;
+	char                  name[64];
+
+	sprintf(name, "%d", minor);
+	*dev_root = create_proc_entry(name, S_IFDIR, root);
+	if (!*dev_root) {
+		DRM_ERROR("Cannot create /proc/dri/%s\n", name);
+		return -1;
+	}
+
+	for (i = 0; i < DRM_PROC_ENTRIES; i++) {
+		ent = create_proc_entry(drm_proc_list[i].name,
+					S_IFREG|S_IRUGO, *dev_root);
+		if (!ent) {
+			DRM_ERROR("Cannot create /proc/dri/%s/%s\n",
+				  name, drm_proc_list[i].name);
+			for (j = 0; j < i; j++)
+				remove_proc_entry(drm_proc_list[i].name,
+						  *dev_root);
+			remove_proc_entry(name, root);
+			return -1;
+		}
+		ent->read_proc = drm_proc_list[i].f;
+		ent->data      = dev;
+	}
+
+	return 0;
+}
+
+
+/**
+ * Cleanup the proc filesystem resources.
+ *
+ * \param minor device minor number.
+ * \param root DRI proc dir entry.
+ * \param dev_root DRI device proc dir entry.
+ * \return always zero.
+ *
+ * Remove all proc entries created by proc_init().
+ */
+int drm_proc_cleanup(int minor, struct proc_dir_entry *root,
+		      struct proc_dir_entry *dev_root)
+{
+	int  i;
+	char name[64];
+
+	if (!root || !dev_root) return 0;
+
+	for (i = 0; i < DRM_PROC_ENTRIES; i++)
+		remove_proc_entry(drm_proc_list[i].name, dev_root);
+	sprintf(name, "%d", minor);
+	remove_proc_entry(name, root);
+
+	return 0;
+}
+
+/**
+ * Called when "/proc/dri/.../name" is read.
+ * 
+ * \param buf output buffer.
+ * \param start start of output data.
+ * \param offset requested start offset.
+ * \param request requested number of bytes.
+ * \param eof whether there is no more data to return.
+ * \param data private data.
+ * \return number of written bytes.
+ * 
+ * Prints the device name together with the bus id if available.
+ */
+static int drm_name_info(char *buf, char **start, off_t offset, int request,
+			  int *eof, void *data)
+{
+	drm_device_t *dev = (drm_device_t *)data;
+	int          len  = 0;
+
+	if (offset > DRM_PROC_LIMIT) {
+		*eof = 1;
+		return 0;
+	}
+
+	*start = &buf[offset];
+	*eof   = 0;
+
+	if (dev->unique) {
+		DRM_PROC_PRINT("%s 0x%lx %s\n",
+			       dev->driver->pci_driver.name, (long)old_encode_dev(dev->device), dev->unique);
+	} else {
+		DRM_PROC_PRINT("%s 0x%lx\n", dev->driver->pci_driver.name, (long)old_encode_dev(dev->device));
+	}
+
+	if (len > request + offset) return request;
+	*eof = 1;
+	return len - offset;
+}
+
+/**
+ * Called when "/proc/dri/.../vm" is read.
+ * 
+ * \param buf output buffer.
+ * \param start start of output data.
+ * \param offset requested start offset.
+ * \param request requested number of bytes.
+ * \param eof whether there is no more data to return.
+ * \param data private data.
+ * \return number of written bytes.
+ * 
+ * Prints information about all mappings in drm_device::maplist.
+ */
+static int drm__vm_info(char *buf, char **start, off_t offset, int request,
+			 int *eof, void *data)
+{
+	drm_device_t *dev = (drm_device_t *)data;
+	int          len  = 0;
+	drm_map_t    *map;
+	drm_map_list_t *r_list;
+	struct list_head *list;
+
+				/* Hardcoded from _DRM_FRAME_BUFFER,
+                                   _DRM_REGISTERS, _DRM_SHM, _DRM_AGP, and
+                                   _DRM_SCATTER_GATHER. */
+	const char   *types[] = { "FB", "REG", "SHM", "AGP", "SG" };
+	const char   *type;
+	int	     i;
+
+	if (offset > DRM_PROC_LIMIT) {
+		*eof = 1;
+		return 0;
+	}
+
+	*start = &buf[offset];
+	*eof   = 0;
+
+	DRM_PROC_PRINT("slot	 offset	      size type flags	 "
+		       "address mtrr\n\n");
+	i = 0;
+	if (dev->maplist != NULL) list_for_each(list, &dev->maplist->head) {
+		r_list = list_entry(list, drm_map_list_t, head);
+		map = r_list->map;
+		if(!map) continue;
+		if (map->type < 0 || map->type > 4) type = "??";
+		else				    type = types[map->type];
+		DRM_PROC_PRINT("%4d 0x%08lx 0x%08lx %4.4s  0x%02x 0x%08lx ",
+			       i,
+			       map->offset,
+			       map->size,
+			       type,
+			       map->flags,
+			       (unsigned long)map->handle);
+		if (map->mtrr < 0) {
+			DRM_PROC_PRINT("none\n");
+		} else {
+			DRM_PROC_PRINT("%4d\n", map->mtrr);
+		}
+		i++;
+	}
+
+	if (len > request + offset) return request;
+	*eof = 1;
+	return len - offset;
+}
+
+/**
+ * Simply calls _vm_info() while holding the drm_device::struct_sem lock.
+ */
+static int drm_vm_info(char *buf, char **start, off_t offset, int request,
+			int *eof, void *data)
+{
+	drm_device_t *dev = (drm_device_t *)data;
+	int	     ret;
+
+	down(&dev->struct_sem);
+	ret = drm__vm_info(buf, start, offset, request, eof, data);
+	up(&dev->struct_sem);
+	return ret;
+}
+
+/**
+ * Called when "/proc/dri/.../queues" is read.
+ * 
+ * \param buf output buffer.
+ * \param start start of output data.
+ * \param offset requested start offset.
+ * \param request requested number of bytes.
+ * \param eof whether there is no more data to return.
+ * \param data private data.
+ * \return number of written bytes.
+ */
+static int drm__queues_info(char *buf, char **start, off_t offset,
+			     int request, int *eof, void *data)
+{
+	drm_device_t *dev = (drm_device_t *)data;
+	int          len  = 0;
+	int	     i;
+	drm_queue_t  *q;
+
+	if (offset > DRM_PROC_LIMIT) {
+		*eof = 1;
+		return 0;
+	}
+
+	*start = &buf[offset];
+	*eof   = 0;
+
+	DRM_PROC_PRINT("  ctx/flags   use   fin"
+		       "   blk/rw/rwf  wait    flushed	   queued"
+		       "      locks\n\n");
+	for (i = 0; i < dev->queue_count; i++) {
+		q = dev->queuelist[i];
+		atomic_inc(&q->use_count);
+		DRM_PROC_PRINT_RET(atomic_dec(&q->use_count),
+				   "%5d/0x%03x %5d %5d"
+				   " %5d/%c%c/%c%c%c %5Zd\n",
+				   i,
+				   q->flags,
+				   atomic_read(&q->use_count),
+				   atomic_read(&q->finalization),
+				   atomic_read(&q->block_count),
+				   atomic_read(&q->block_read) ? 'r' : '-',
+				   atomic_read(&q->block_write) ? 'w' : '-',
+				   waitqueue_active(&q->read_queue) ? 'r':'-',
+				   waitqueue_active(&q->write_queue) ? 'w':'-',
+				   waitqueue_active(&q->flush_queue) ? 'f':'-',
+				   DRM_BUFCOUNT(&q->waitlist));
+		atomic_dec(&q->use_count);
+	}
+
+	if (len > request + offset) return request;
+	*eof = 1;
+	return len - offset;
+}
+
+/**
+ * Simply calls _queues_info() while holding the drm_device::struct_sem lock.
+ */
+static int drm_queues_info(char *buf, char **start, off_t offset, int request,
+			    int *eof, void *data)
+{
+	drm_device_t *dev = (drm_device_t *)data;
+	int	     ret;
+
+	down(&dev->struct_sem);
+	ret = drm__queues_info(buf, start, offset, request, eof, data);
+	up(&dev->struct_sem);
+	return ret;
+}
+
+/**
+ * Called when "/proc/dri/.../bufs" is read.
+ * 
+ * \param buf output buffer.
+ * \param start start of output data.
+ * \param offset requested start offset.
+ * \param request requested number of bytes.
+ * \param eof whether there is no more data to return.
+ * \param data private data.
+ * \return number of written bytes.
+ */
+static int drm__bufs_info(char *buf, char **start, off_t offset, int request,
+			   int *eof, void *data)
+{
+	drm_device_t	 *dev = (drm_device_t *)data;
+	int              len  = 0;
+	drm_device_dma_t *dma = dev->dma;
+	int		 i;
+
+	if (!dma || offset > DRM_PROC_LIMIT) {
+		*eof = 1;
+		return 0;
+	}
+
+	*start = &buf[offset];
+	*eof   = 0;
+
+	DRM_PROC_PRINT(" o     size count  free	 segs pages    kB\n\n");
+	for (i = 0; i <= DRM_MAX_ORDER; i++) {
+		if (dma->bufs[i].buf_count)
+			DRM_PROC_PRINT("%2d %8d %5d %5d %5d %5d %5ld\n",
+				       i,
+				       dma->bufs[i].buf_size,
+				       dma->bufs[i].buf_count,
+				       atomic_read(&dma->bufs[i]
+						   .freelist.count),
+				       dma->bufs[i].seg_count,
+				       dma->bufs[i].seg_count
+				       *(1 << dma->bufs[i].page_order),
+				       (dma->bufs[i].seg_count
+					* (1 << dma->bufs[i].page_order))
+				       * PAGE_SIZE / 1024);
+	}
+	DRM_PROC_PRINT("\n");
+	for (i = 0; i < dma->buf_count; i++) {
+		if (i && !(i%32)) DRM_PROC_PRINT("\n");
+		DRM_PROC_PRINT(" %d", dma->buflist[i]->list);
+	}
+	DRM_PROC_PRINT("\n");
+
+	if (len > request + offset) return request;
+	*eof = 1;
+	return len - offset;
+}
+
+/**
+ * Simply calls _bufs_info() while holding the drm_device::struct_sem lock.
+ */
+static int drm_bufs_info(char *buf, char **start, off_t offset, int request,
+			  int *eof, void *data)
+{
+	drm_device_t *dev = (drm_device_t *)data;
+	int	     ret;
+
+	down(&dev->struct_sem);
+	ret = drm__bufs_info(buf, start, offset, request, eof, data);
+	up(&dev->struct_sem);
+	return ret;
+}
+
+/**
+ * Called when "/proc/dri/.../clients" is read.
+ * 
+ * \param buf output buffer.
+ * \param start start of output data.
+ * \param offset requested start offset.
+ * \param request requested number of bytes.
+ * \param eof whether there is no more data to return.
+ * \param data private data.
+ * \return number of written bytes.
+ */
+static int drm__clients_info(char *buf, char **start, off_t offset,
+			      int request, int *eof, void *data)
+{
+	drm_device_t *dev = (drm_device_t *)data;
+	int          len  = 0;
+	drm_file_t   *priv;
+
+	if (offset > DRM_PROC_LIMIT) {
+		*eof = 1;
+		return 0;
+	}
+
+	*start = &buf[offset];
+	*eof   = 0;
+
+	DRM_PROC_PRINT("a dev	pid    uid	magic	  ioctls\n\n");
+	for (priv = dev->file_first; priv; priv = priv->next) {
+		DRM_PROC_PRINT("%c %3d %5d %5d %10u %10lu\n",
+			       priv->authenticated ? 'y' : 'n',
+			       priv->minor,
+			       priv->pid,
+			       priv->uid,
+			       priv->magic,
+			       priv->ioctl_count);
+	}
+
+	if (len > request + offset) return request;
+	*eof = 1;
+	return len - offset;
+}
+
+/**
+ * Simply calls _clients_info() while holding the drm_device::struct_sem lock.
+ */
+static int drm_clients_info(char *buf, char **start, off_t offset,
+			     int request, int *eof, void *data)
+{
+	drm_device_t *dev = (drm_device_t *)data;
+	int	     ret;
+
+	down(&dev->struct_sem);
+	ret = drm__clients_info(buf, start, offset, request, eof, data);
+	up(&dev->struct_sem);
+	return ret;
+}
+
+#if DRM_DEBUG_CODE
+
+static int drm__vma_info(char *buf, char **start, off_t offset, int request,
+			  int *eof, void *data)
+{
+	drm_device_t	      *dev = (drm_device_t *)data;
+	int                   len  = 0;
+	drm_vma_entry_t	      *pt;
+	struct vm_area_struct *vma;
+#if defined(__i386__)
+	unsigned int	      pgprot;
+#endif
+
+	if (offset > DRM_PROC_LIMIT) {
+		*eof = 1;
+		return 0;
+	}
+
+	*start = &buf[offset];
+	*eof   = 0;
+
+	DRM_PROC_PRINT("vma use count: %d, high_memory = %p, 0x%08lx\n",
+		       atomic_read(&dev->vma_count),
+		       high_memory, virt_to_phys(high_memory));
+	for (pt = dev->vmalist; pt; pt = pt->next) {
+		if (!(vma = pt->vma)) continue;
+		DRM_PROC_PRINT("\n%5d 0x%08lx-0x%08lx %c%c%c%c%c%c 0x%08lx",
+			       pt->pid,
+			       vma->vm_start,
+			       vma->vm_end,
+			       vma->vm_flags & VM_READ	   ? 'r' : '-',
+			       vma->vm_flags & VM_WRITE	   ? 'w' : '-',
+			       vma->vm_flags & VM_EXEC	   ? 'x' : '-',
+			       vma->vm_flags & VM_MAYSHARE ? 's' : 'p',
+			       vma->vm_flags & VM_LOCKED   ? 'l' : '-',
+			       vma->vm_flags & VM_IO	   ? 'i' : '-',
+			       VM_OFFSET(vma));
+
+#if defined(__i386__)
+		pgprot = pgprot_val(vma->vm_page_prot);
+		DRM_PROC_PRINT(" %c%c%c%c%c%c%c%c%c",
+			       pgprot & _PAGE_PRESENT  ? 'p' : '-',
+			       pgprot & _PAGE_RW       ? 'w' : 'r',
+			       pgprot & _PAGE_USER     ? 'u' : 's',
+			       pgprot & _PAGE_PWT      ? 't' : 'b',
+			       pgprot & _PAGE_PCD      ? 'u' : 'c',
+			       pgprot & _PAGE_ACCESSED ? 'a' : '-',
+			       pgprot & _PAGE_DIRTY    ? 'd' : '-',
+			       pgprot & _PAGE_PSE      ? 'm' : 'k',
+			       pgprot & _PAGE_GLOBAL   ? 'g' : 'l' );
+#endif
+		DRM_PROC_PRINT("\n");
+	}
+
+	if (len > request + offset) return request;
+	*eof = 1;
+	return len - offset;
+}
+
+static int drm_vma_info(char *buf, char **start, off_t offset, int request,
+			 int *eof, void *data)
+{
+	drm_device_t *dev = (drm_device_t *)data;
+	int	     ret;
+
+	down(&dev->struct_sem);
+	ret = drm__vma_info(buf, start, offset, request, eof, data);
+	up(&dev->struct_sem);
+	return ret;
+}
+#endif
+
+
diff -Nru a/drivers/char/drm/drm_proc.h b/drivers/char/drm/drm_proc.h
--- a/drivers/char/drm/drm_proc.h	2005-03-01 23:38:52 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,547 +0,0 @@
-/**
- * \file drm_proc.h 
- * /proc support for DRM
- *
- * \author Rickard E. (Rik) Faith <faith@valinux.com>
- * \author Gareth Hughes <gareth@valinux.com>
- *
- * \par Acknowledgements:
- *    Matthew J Sottek <matthew.j.sottek@intel.com> sent in a patch to fix
- *    the problem with the proc files not outputting all their information.
- */
-
-/*
- * Created: Mon Jan 11 09:48:47 1999 by faith@valinux.com
- *
- * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include "drmP.h"
-
-static int	   DRM(name_info)(char *buf, char **start, off_t offset,
-				  int request, int *eof, void *data);
-static int	   DRM(vm_info)(char *buf, char **start, off_t offset,
-				int request, int *eof, void *data);
-static int	   DRM(clients_info)(char *buf, char **start, off_t offset,
-				     int request, int *eof, void *data);
-static int	   DRM(queues_info)(char *buf, char **start, off_t offset,
-				    int request, int *eof, void *data);
-static int	   DRM(bufs_info)(char *buf, char **start, off_t offset,
-				  int request, int *eof, void *data);
-#if DRM_DEBUG_CODE
-static int	   DRM(vma_info)(char *buf, char **start, off_t offset,
-				 int request, int *eof, void *data);
-#endif
-
-/**
- * Proc file list.
- */
-struct drm_proc_list {
-	const char *name;	/**< file name */
-	int	   (*f)(char *, char **, off_t, int, int *, void *);	/**< proc callback*/
-} DRM(proc_list)[] = {
-	{ "name",    DRM(name_info)    },
-	{ "mem",     DRM(mem_info)     },
-	{ "vm",	     DRM(vm_info)      },
-	{ "clients", DRM(clients_info) },
-	{ "queues",  DRM(queues_info)  },
-	{ "bufs",    DRM(bufs_info)    },
-#if DRM_DEBUG_CODE
-	{ "vma",     DRM(vma_info)     },
-#endif
-};
-#define DRM_PROC_ENTRIES (sizeof(DRM(proc_list))/sizeof(DRM(proc_list)[0]))
-
-/**
- * Initialize the DRI proc filesystem for a device.
- *
- * \param dev DRM device.
- * \param minor device minor number.
- * \param root DRI proc dir entry.
- * \param dev_root resulting DRI device proc dir entry.
- * \return root entry pointer on success, or NULL on failure.
- * 
- * Create the DRI proc root entry "/proc/dri", the device proc root entry
- * "/proc/dri/%minor%/", and each entry in proc_list as
- * "/proc/dri/%minor%/%name%".
- */
-struct proc_dir_entry *DRM(proc_init)(drm_device_t *dev, int minor,
-				      struct proc_dir_entry *root,
-				      struct proc_dir_entry **dev_root)
-{
-	struct proc_dir_entry *ent;
-	int		      i, j;
-	char                  name[64];
-
-	if (!minor) root = create_proc_entry("dri", S_IFDIR, NULL);
-	if (!root) {
-		DRM_ERROR("Cannot create /proc/dri\n");
-		return NULL;
-	}
-
-	sprintf(name, "%d", minor);
-	*dev_root = create_proc_entry(name, S_IFDIR, root);
-	if (!*dev_root) {
-		DRM_ERROR("Cannot create /proc/dri/%s\n", name);
-		return NULL;
-	}
-
-	for (i = 0; i < DRM_PROC_ENTRIES; i++) {
-		ent = create_proc_entry(DRM(proc_list)[i].name,
-					S_IFREG|S_IRUGO, *dev_root);
-		if (!ent) {
-			DRM_ERROR("Cannot create /proc/dri/%s/%s\n",
-				  name, DRM(proc_list)[i].name);
-			for (j = 0; j < i; j++)
-				remove_proc_entry(DRM(proc_list)[i].name,
-						  *dev_root);
-			remove_proc_entry(name, root);
-			if (!minor) remove_proc_entry("dri", NULL);
-			return NULL;
-		}
-		ent->read_proc = DRM(proc_list)[i].f;
-		ent->data      = dev;
-	}
-
-	return root;
-}
-
-
-/**
- * Cleanup the proc filesystem resources.
- *
- * \param minor device minor number.
- * \param root DRI proc dir entry.
- * \param dev_root DRI device proc dir entry.
- * \return always zero.
- *
- * Remove all proc entries created by proc_init().
- */
-int DRM(proc_cleanup)(int minor, struct proc_dir_entry *root,
-		      struct proc_dir_entry *dev_root)
-{
-	int  i;
-	char name[64];
-
-	if (!root || !dev_root) return 0;
-
-	for (i = 0; i < DRM_PROC_ENTRIES; i++)
-		remove_proc_entry(DRM(proc_list)[i].name, dev_root);
-	sprintf(name, "%d", minor);
-	remove_proc_entry(name, root);
-	if (!minor) remove_proc_entry("dri", NULL);
-
-	return 0;
-}
-
-/**
- * Called when "/proc/dri/.../name" is read.
- * 
- * \param buf output buffer.
- * \param start start of output data.
- * \param offset requested start offset.
- * \param request requested number of bytes.
- * \param eof whether there is no more data to return.
- * \param data private data.
- * \return number of written bytes.
- * 
- * Prints the device name together with the bus id if available.
- */
-static int DRM(name_info)(char *buf, char **start, off_t offset, int request,
-			  int *eof, void *data)
-{
-	drm_device_t *dev = (drm_device_t *)data;
-	int          len  = 0;
-
-	if (offset > DRM_PROC_LIMIT) {
-		*eof = 1;
-		return 0;
-	}
-
-	*start = &buf[offset];
-	*eof   = 0;
-
-	if (dev->unique) {
-		DRM_PROC_PRINT("%s 0x%lx %s\n",
-			       dev->name, (long)old_encode_dev(dev->device), dev->unique);
-	} else {
-		DRM_PROC_PRINT("%s 0x%lx\n", dev->name, (long)old_encode_dev(dev->device));
-	}
-
-	if (len > request + offset) return request;
-	*eof = 1;
-	return len - offset;
-}
-
-/**
- * Called when "/proc/dri/.../vm" is read.
- * 
- * \param buf output buffer.
- * \param start start of output data.
- * \param offset requested start offset.
- * \param request requested number of bytes.
- * \param eof whether there is no more data to return.
- * \param data private data.
- * \return number of written bytes.
- * 
- * Prints information about all mappings in drm_device::maplist.
- */
-static int DRM(_vm_info)(char *buf, char **start, off_t offset, int request,
-			 int *eof, void *data)
-{
-	drm_device_t *dev = (drm_device_t *)data;
-	int          len  = 0;
-	drm_map_t    *map;
-	drm_map_list_t *r_list;
-	struct list_head *list;
-
-				/* Hardcoded from _DRM_FRAME_BUFFER,
-                                   _DRM_REGISTERS, _DRM_SHM, _DRM_AGP, and
-                                   _DRM_SCATTER_GATHER. */
-	const char   *types[] = { "FB", "REG", "SHM", "AGP", "SG" };
-	const char   *type;
-	int	     i;
-
-	if (offset > DRM_PROC_LIMIT) {
-		*eof = 1;
-		return 0;
-	}
-
-	*start = &buf[offset];
-	*eof   = 0;
-
-	DRM_PROC_PRINT("slot	 offset	      size type flags	 "
-		       "address mtrr\n\n");
-	i = 0;
-	if (dev->maplist != NULL) list_for_each(list, &dev->maplist->head) {
-		r_list = list_entry(list, drm_map_list_t, head);
-		map = r_list->map;
-		if(!map) continue;
-		if (map->type < 0 || map->type > 4) type = "??";
-		else				    type = types[map->type];
-		DRM_PROC_PRINT("%4d 0x%08lx 0x%08lx %4.4s  0x%02x 0x%08lx ",
-			       i,
-			       map->offset,
-			       map->size,
-			       type,
-			       map->flags,
-			       (unsigned long)map->handle);
-		if (map->mtrr < 0) {
-			DRM_PROC_PRINT("none\n");
-		} else {
-			DRM_PROC_PRINT("%4d\n", map->mtrr);
-		}
-		i++;
-	}
-
-	if (len > request + offset) return request;
-	*eof = 1;
-	return len - offset;
-}
-
-/**
- * Simply calls _vm_info() while holding the drm_device::struct_sem lock.
- */
-static int DRM(vm_info)(char *buf, char **start, off_t offset, int request,
-			int *eof, void *data)
-{
-	drm_device_t *dev = (drm_device_t *)data;
-	int	     ret;
-
-	down(&dev->struct_sem);
-	ret = DRM(_vm_info)(buf, start, offset, request, eof, data);
-	up(&dev->struct_sem);
-	return ret;
-}
-
-/**
- * Called when "/proc/dri/.../queues" is read.
- * 
- * \param buf output buffer.
- * \param start start of output data.
- * \param offset requested start offset.
- * \param request requested number of bytes.
- * \param eof whether there is no more data to return.
- * \param data private data.
- * \return number of written bytes.
- */
-static int DRM(_queues_info)(char *buf, char **start, off_t offset,
-			     int request, int *eof, void *data)
-{
-	drm_device_t *dev = (drm_device_t *)data;
-	int          len  = 0;
-	int	     i;
-	drm_queue_t  *q;
-
-	if (offset > DRM_PROC_LIMIT) {
-		*eof = 1;
-		return 0;
-	}
-
-	*start = &buf[offset];
-	*eof   = 0;
-
-	DRM_PROC_PRINT("  ctx/flags   use   fin"
-		       "   blk/rw/rwf  wait    flushed	   queued"
-		       "      locks\n\n");
-	for (i = 0; i < dev->queue_count; i++) {
-		q = dev->queuelist[i];
-		atomic_inc(&q->use_count);
-		DRM_PROC_PRINT_RET(atomic_dec(&q->use_count),
-				   "%5d/0x%03x %5d %5d"
-				   " %5d/%c%c/%c%c%c %5Zd\n",
-				   i,
-				   q->flags,
-				   atomic_read(&q->use_count),
-				   atomic_read(&q->finalization),
-				   atomic_read(&q->block_count),
-				   atomic_read(&q->block_read) ? 'r' : '-',
-				   atomic_read(&q->block_write) ? 'w' : '-',
-				   waitqueue_active(&q->read_queue) ? 'r':'-',
-				   waitqueue_active(&q->write_queue) ? 'w':'-',
-				   waitqueue_active(&q->flush_queue) ? 'f':'-',
-				   DRM_BUFCOUNT(&q->waitlist));
-		atomic_dec(&q->use_count);
-	}
-
-	if (len > request + offset) return request;
-	*eof = 1;
-	return len - offset;
-}
-
-/**
- * Simply calls _queues_info() while holding the drm_device::struct_sem lock.
- */
-static int DRM(queues_info)(char *buf, char **start, off_t offset, int request,
-			    int *eof, void *data)
-{
-	drm_device_t *dev = (drm_device_t *)data;
-	int	     ret;
-
-	down(&dev->struct_sem);
-	ret = DRM(_queues_info)(buf, start, offset, request, eof, data);
-	up(&dev->struct_sem);
-	return ret;
-}
-
-/**
- * Called when "/proc/dri/.../bufs" is read.
- * 
- * \param buf output buffer.
- * \param start start of output data.
- * \param offset requested start offset.
- * \param request requested number of bytes.
- * \param eof whether there is no more data to return.
- * \param data private data.
- * \return number of written bytes.
- */
-static int DRM(_bufs_info)(char *buf, char **start, off_t offset, int request,
-			   int *eof, void *data)
-{
-	drm_device_t	 *dev = (drm_device_t *)data;
-	int              len  = 0;
-	drm_device_dma_t *dma = dev->dma;
-	int		 i;
-
-	if (!dma || offset > DRM_PROC_LIMIT) {
-		*eof = 1;
-		return 0;
-	}
-
-	*start = &buf[offset];
-	*eof   = 0;
-
-	DRM_PROC_PRINT(" o     size count  free	 segs pages    kB\n\n");
-	for (i = 0; i <= DRM_MAX_ORDER; i++) {
-		if (dma->bufs[i].buf_count)
-			DRM_PROC_PRINT("%2d %8d %5d %5d %5d %5d %5ld\n",
-				       i,
-				       dma->bufs[i].buf_size,
-				       dma->bufs[i].buf_count,
-				       atomic_read(&dma->bufs[i]
-						   .freelist.count),
-				       dma->bufs[i].seg_count,
-				       dma->bufs[i].seg_count
-				       *(1 << dma->bufs[i].page_order),
-				       (dma->bufs[i].seg_count
-					* (1 << dma->bufs[i].page_order))
-				       * PAGE_SIZE / 1024);
-	}
-	DRM_PROC_PRINT("\n");
-	for (i = 0; i < dma->buf_count; i++) {
-		if (i && !(i%32)) DRM_PROC_PRINT("\n");
-		DRM_PROC_PRINT(" %d", dma->buflist[i]->list);
-	}
-	DRM_PROC_PRINT("\n");
-
-	if (len > request + offset) return request;
-	*eof = 1;
-	return len - offset;
-}
-
-/**
- * Simply calls _bufs_info() while holding the drm_device::struct_sem lock.
- */
-static int DRM(bufs_info)(char *buf, char **start, off_t offset, int request,
-			  int *eof, void *data)
-{
-	drm_device_t *dev = (drm_device_t *)data;
-	int	     ret;
-
-	down(&dev->struct_sem);
-	ret = DRM(_bufs_info)(buf, start, offset, request, eof, data);
-	up(&dev->struct_sem);
-	return ret;
-}
-
-/**
- * Called when "/proc/dri/.../clients" is read.
- * 
- * \param buf output buffer.
- * \param start start of output data.
- * \param offset requested start offset.
- * \param request requested number of bytes.
- * \param eof whether there is no more data to return.
- * \param data private data.
- * \return number of written bytes.
- */
-static int DRM(_clients_info)(char *buf, char **start, off_t offset,
-			      int request, int *eof, void *data)
-{
-	drm_device_t *dev = (drm_device_t *)data;
-	int          len  = 0;
-	drm_file_t   *priv;
-
-	if (offset > DRM_PROC_LIMIT) {
-		*eof = 1;
-		return 0;
-	}
-
-	*start = &buf[offset];
-	*eof   = 0;
-
-	DRM_PROC_PRINT("a dev	pid    uid	magic	  ioctls\n\n");
-	for (priv = dev->file_first; priv; priv = priv->next) {
-		DRM_PROC_PRINT("%c %3d %5d %5d %10u %10lu\n",
-			       priv->authenticated ? 'y' : 'n',
-			       priv->minor,
-			       priv->pid,
-			       priv->uid,
-			       priv->magic,
-			       priv->ioctl_count);
-	}
-
-	if (len > request + offset) return request;
-	*eof = 1;
-	return len - offset;
-}
-
-/**
- * Simply calls _clients_info() while holding the drm_device::struct_sem lock.
- */
-static int DRM(clients_info)(char *buf, char **start, off_t offset,
-			     int request, int *eof, void *data)
-{
-	drm_device_t *dev = (drm_device_t *)data;
-	int	     ret;
-
-	down(&dev->struct_sem);
-	ret = DRM(_clients_info)(buf, start, offset, request, eof, data);
-	up(&dev->struct_sem);
-	return ret;
-}
-
-#if DRM_DEBUG_CODE
-
-static int DRM(_vma_info)(char *buf, char **start, off_t offset, int request,
-			  int *eof, void *data)
-{
-	drm_device_t	      *dev = (drm_device_t *)data;
-	int                   len  = 0;
-	drm_vma_entry_t	      *pt;
-	struct vm_area_struct *vma;
-#if defined(__i386__)
-	unsigned int	      pgprot;
-#endif
-
-	if (offset > DRM_PROC_LIMIT) {
-		*eof = 1;
-		return 0;
-	}
-
-	*start = &buf[offset];
-	*eof   = 0;
-
-	DRM_PROC_PRINT("vma use count: %d, high_memory = %p, 0x%08lx\n",
-		       atomic_read(&dev->vma_count),
-		       high_memory, virt_to_phys(high_memory));
-	for (pt = dev->vmalist; pt; pt = pt->next) {
-		if (!(vma = pt->vma)) continue;
-		DRM_PROC_PRINT("\n%5d 0x%08lx-0x%08lx %c%c%c%c%c%c 0x%08lx",
-			       pt->pid,
-			       vma->vm_start,
-			       vma->vm_end,
-			       vma->vm_flags & VM_READ	   ? 'r' : '-',
-			       vma->vm_flags & VM_WRITE	   ? 'w' : '-',
-			       vma->vm_flags & VM_EXEC	   ? 'x' : '-',
-			       vma->vm_flags & VM_MAYSHARE ? 's' : 'p',
-			       vma->vm_flags & VM_LOCKED   ? 'l' : '-',
-			       vma->vm_flags & VM_IO	   ? 'i' : '-',
-			       VM_OFFSET(vma));
-
-#if defined(__i386__)
-		pgprot = pgprot_val(vma->vm_page_prot);
-		DRM_PROC_PRINT(" %c%c%c%c%c%c%c%c%c",
-			       pgprot & _PAGE_PRESENT  ? 'p' : '-',
-			       pgprot & _PAGE_RW       ? 'w' : 'r',
-			       pgprot & _PAGE_USER     ? 'u' : 's',
-			       pgprot & _PAGE_PWT      ? 't' : 'b',
-			       pgprot & _PAGE_PCD      ? 'u' : 'c',
-			       pgprot & _PAGE_ACCESSED ? 'a' : '-',
-			       pgprot & _PAGE_DIRTY    ? 'd' : '-',
-			       pgprot & _PAGE_PSE      ? 'm' : 'k',
-			       pgprot & _PAGE_GLOBAL   ? 'g' : 'l' );
-#endif
-		DRM_PROC_PRINT("\n");
-	}
-
-	if (len > request + offset) return request;
-	*eof = 1;
-	return len - offset;
-}
-
-static int DRM(vma_info)(char *buf, char **start, off_t offset, int request,
-			 int *eof, void *data)
-{
-	drm_device_t *dev = (drm_device_t *)data;
-	int	     ret;
-
-	down(&dev->struct_sem);
-	ret = DRM(_vma_info)(buf, start, offset, request, eof, data);
-	up(&dev->struct_sem);
-	return ret;
-}
-#endif
-
-
diff -Nru a/drivers/char/drm/drm_scatter.c b/drivers/char/drm/drm_scatter.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/char/drm/drm_scatter.c	2005-03-01 23:39:06 -08:00
@@ -0,0 +1,231 @@
+/**
+ * \file drm_scatter.h 
+ * IOCTLs to manage scatter/gather memory
+ *
+ * \author Gareth Hughes <gareth@valinux.com>
+ */
+
+/*
+ * Created: Mon Dec 18 23:20:54 2000 by gareth@valinux.com
+ *
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include <linux/config.h>
+#include <linux/vmalloc.h>
+#include "drmP.h"
+
+#define DEBUG_SCATTER 0
+
+void drm_sg_cleanup( drm_sg_mem_t *entry )
+{
+	struct page *page;
+	int i;
+
+	for ( i = 0 ; i < entry->pages ; i++ ) {
+		page = entry->pagelist[i];
+		if ( page )
+			ClearPageReserved( page );
+	}
+
+	vfree( entry->virtual );
+
+	drm_free( entry->busaddr,
+		   entry->pages * sizeof(*entry->busaddr),
+		   DRM_MEM_PAGES );
+	drm_free( entry->pagelist,
+		   entry->pages * sizeof(*entry->pagelist),
+		   DRM_MEM_PAGES );
+	drm_free( entry,
+		   sizeof(*entry),
+		   DRM_MEM_SGLISTS );
+}
+
+int drm_sg_alloc( struct inode *inode, struct file *filp,
+		   unsigned int cmd, unsigned long arg )
+{
+	drm_file_t *priv = filp->private_data;
+	drm_device_t *dev = priv->dev;
+	drm_scatter_gather_t __user *argp = (void __user *)arg;
+	drm_scatter_gather_t request;
+	drm_sg_mem_t *entry;
+	unsigned long pages, i, j;
+
+	DRM_DEBUG( "%s\n", __FUNCTION__ );
+
+	if (!drm_core_check_feature(dev, DRIVER_SG))
+		return -EINVAL;
+
+	if ( dev->sg )
+		return -EINVAL;
+
+	if ( copy_from_user( &request, argp, sizeof(request) ) )
+		return -EFAULT;
+
+	entry = drm_alloc( sizeof(*entry), DRM_MEM_SGLISTS );
+	if ( !entry )
+		return -ENOMEM;
+
+   	memset( entry, 0, sizeof(*entry) );
+
+	pages = (request.size + PAGE_SIZE - 1) / PAGE_SIZE;
+	DRM_DEBUG( "sg size=%ld pages=%ld\n", request.size, pages );
+
+	entry->pages = pages;
+	entry->pagelist = drm_alloc( pages * sizeof(*entry->pagelist),
+				     DRM_MEM_PAGES );
+	if ( !entry->pagelist ) {
+		drm_free( entry, sizeof(*entry), DRM_MEM_SGLISTS );
+		return -ENOMEM;
+	}
+
+	memset(entry->pagelist, 0, pages * sizeof(*entry->pagelist));
+
+	entry->busaddr = drm_alloc( pages * sizeof(*entry->busaddr),
+				     DRM_MEM_PAGES );
+	if ( !entry->busaddr ) {
+		drm_free( entry->pagelist,
+			   entry->pages * sizeof(*entry->pagelist),
+			   DRM_MEM_PAGES );
+		drm_free( entry,
+			   sizeof(*entry),
+			   DRM_MEM_SGLISTS );
+		return -ENOMEM;
+	}
+	memset( (void *)entry->busaddr, 0, pages * sizeof(*entry->busaddr) );
+
+	entry->virtual = vmalloc_32( pages << PAGE_SHIFT );
+	if ( !entry->virtual ) {
+		drm_free( entry->busaddr,
+			   entry->pages * sizeof(*entry->busaddr),
+			   DRM_MEM_PAGES );
+		drm_free( entry->pagelist,
+			   entry->pages * sizeof(*entry->pagelist),
+			   DRM_MEM_PAGES );
+		drm_free( entry,
+			   sizeof(*entry),
+			   DRM_MEM_SGLISTS );
+		return -ENOMEM;
+	}
+
+	/* This also forces the mapping of COW pages, so our page list
+	 * will be valid.  Please don't remove it...
+	 */
+	memset( entry->virtual, 0, pages << PAGE_SHIFT );
+
+	entry->handle = (unsigned long)entry->virtual;
+
+	DRM_DEBUG( "sg alloc handle  = %08lx\n", entry->handle );
+	DRM_DEBUG( "sg alloc virtual = %p\n", entry->virtual );
+
+	for ( i = entry->handle, j = 0 ; j < pages ; i += PAGE_SIZE, j++ ) {
+		entry->pagelist[j] = vmalloc_to_page((void *)i);
+		if (!entry->pagelist[j])
+			goto failed;
+		SetPageReserved(entry->pagelist[j]);
+	}
+
+	request.handle = entry->handle;
+
+	if ( copy_to_user( argp, &request, sizeof(request) ) ) {
+		drm_sg_cleanup( entry );
+		return -EFAULT;
+	}
+
+	dev->sg = entry;
+
+#if DEBUG_SCATTER
+	/* Verify that each page points to its virtual address, and vice
+	 * versa.
+	 */
+	{
+	int error = 0;
+
+	for ( i = 0 ; i < pages ; i++ ) {
+		unsigned long *tmp;
+
+		tmp = page_address( entry->pagelist[i] );
+		for ( j = 0 ;
+		      j < PAGE_SIZE / sizeof(unsigned long) ;
+		      j++, tmp++ ) {
+			*tmp = 0xcafebabe;
+		}
+		tmp = (unsigned long *)((u8 *)entry->virtual +
+					(PAGE_SIZE * i));
+		for( j = 0 ;
+		     j < PAGE_SIZE / sizeof(unsigned long) ;
+		     j++, tmp++ ) {
+			if ( *tmp != 0xcafebabe && error == 0 ) {
+				error = 1;
+				DRM_ERROR( "Scatter allocation error, "
+					   "pagelist does not match "
+					   "virtual mapping\n" );
+			}
+		}
+		tmp = page_address( entry->pagelist[i] );
+		for(j = 0 ;
+		    j < PAGE_SIZE / sizeof(unsigned long) ;
+		    j++, tmp++) {
+			*tmp = 0;
+		}
+	}
+	if (error == 0)
+		DRM_ERROR( "Scatter allocation matches pagelist\n" );
+	}
+#endif
+
+	return 0;
+
+ failed:
+	drm_sg_cleanup( entry );
+	return -ENOMEM;
+}
+
+int drm_sg_free( struct inode *inode, struct file *filp,
+		 unsigned int cmd, unsigned long arg )
+{
+	drm_file_t *priv = filp->private_data;
+	drm_device_t *dev = priv->dev;
+	drm_scatter_gather_t request;
+	drm_sg_mem_t *entry;
+
+	if (!drm_core_check_feature(dev, DRIVER_SG))
+		return -EINVAL;
+
+	if ( copy_from_user( &request,
+			     (drm_scatter_gather_t __user *)arg,
+			     sizeof(request) ) )
+		return -EFAULT;
+
+	entry = dev->sg;
+	dev->sg = NULL;
+
+	if ( !entry || entry->handle != request.handle )
+		return -EINVAL;
+
+	DRM_DEBUG( "sg free virtual  = %p\n", entry->virtual );
+
+	drm_sg_cleanup( entry );
+
+	return 0;
+}
diff -Nru a/drivers/char/drm/drm_scatter.h b/drivers/char/drm/drm_scatter.h
--- a/drivers/char/drm/drm_scatter.h	2005-03-01 23:39:06 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,231 +0,0 @@
-/**
- * \file drm_scatter.h 
- * IOCTLs to manage scatter/gather memory
- *
- * \author Gareth Hughes <gareth@valinux.com>
- */
-
-/*
- * Created: Mon Dec 18 23:20:54 2000 by gareth@valinux.com
- *
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#include <linux/config.h>
-#include <linux/vmalloc.h>
-#include "drmP.h"
-
-#define DEBUG_SCATTER 0
-
-void DRM(sg_cleanup)( drm_sg_mem_t *entry )
-{
-	struct page *page;
-	int i;
-
-	for ( i = 0 ; i < entry->pages ; i++ ) {
-		page = entry->pagelist[i];
-		if ( page )
-			ClearPageReserved( page );
-	}
-
-	vfree( entry->virtual );
-
-	DRM(free)( entry->busaddr,
-		   entry->pages * sizeof(*entry->busaddr),
-		   DRM_MEM_PAGES );
-	DRM(free)( entry->pagelist,
-		   entry->pages * sizeof(*entry->pagelist),
-		   DRM_MEM_PAGES );
-	DRM(free)( entry,
-		   sizeof(*entry),
-		   DRM_MEM_SGLISTS );
-}
-
-int DRM(sg_alloc)( struct inode *inode, struct file *filp,
-		   unsigned int cmd, unsigned long arg )
-{
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
-	drm_scatter_gather_t __user *argp = (void __user *)arg;
-	drm_scatter_gather_t request;
-	drm_sg_mem_t *entry;
-	unsigned long pages, i, j;
-
-	DRM_DEBUG( "%s\n", __FUNCTION__ );
-
-	if (!drm_core_check_feature(dev, DRIVER_SG))
-		return -EINVAL;
-
-	if ( dev->sg )
-		return -EINVAL;
-
-	if ( copy_from_user( &request, argp, sizeof(request) ) )
-		return -EFAULT;
-
-	entry = DRM(alloc)( sizeof(*entry), DRM_MEM_SGLISTS );
-	if ( !entry )
-		return -ENOMEM;
-
-   	memset( entry, 0, sizeof(*entry) );
-
-	pages = (request.size + PAGE_SIZE - 1) / PAGE_SIZE;
-	DRM_DEBUG( "sg size=%ld pages=%ld\n", request.size, pages );
-
-	entry->pages = pages;
-	entry->pagelist = DRM(alloc)( pages * sizeof(*entry->pagelist),
-				     DRM_MEM_PAGES );
-	if ( !entry->pagelist ) {
-		DRM(free)( entry, sizeof(*entry), DRM_MEM_SGLISTS );
-		return -ENOMEM;
-	}
-
-	memset(entry->pagelist, 0, pages * sizeof(*entry->pagelist));
-
-	entry->busaddr = DRM(alloc)( pages * sizeof(*entry->busaddr),
-				     DRM_MEM_PAGES );
-	if ( !entry->busaddr ) {
-		DRM(free)( entry->pagelist,
-			   entry->pages * sizeof(*entry->pagelist),
-			   DRM_MEM_PAGES );
-		DRM(free)( entry,
-			   sizeof(*entry),
-			   DRM_MEM_SGLISTS );
-		return -ENOMEM;
-	}
-	memset( (void *)entry->busaddr, 0, pages * sizeof(*entry->busaddr) );
-
-	entry->virtual = vmalloc_32( pages << PAGE_SHIFT );
-	if ( !entry->virtual ) {
-		DRM(free)( entry->busaddr,
-			   entry->pages * sizeof(*entry->busaddr),
-			   DRM_MEM_PAGES );
-		DRM(free)( entry->pagelist,
-			   entry->pages * sizeof(*entry->pagelist),
-			   DRM_MEM_PAGES );
-		DRM(free)( entry,
-			   sizeof(*entry),
-			   DRM_MEM_SGLISTS );
-		return -ENOMEM;
-	}
-
-	/* This also forces the mapping of COW pages, so our page list
-	 * will be valid.  Please don't remove it...
-	 */
-	memset( entry->virtual, 0, pages << PAGE_SHIFT );
-
-	entry->handle = (unsigned long)entry->virtual;
-
-	DRM_DEBUG( "sg alloc handle  = %08lx\n", entry->handle );
-	DRM_DEBUG( "sg alloc virtual = %p\n", entry->virtual );
-
-	for ( i = entry->handle, j = 0 ; j < pages ; i += PAGE_SIZE, j++ ) {
-		entry->pagelist[j] = vmalloc_to_page((void *)i);
-		if (!entry->pagelist[j])
-			goto failed;
-		SetPageReserved(entry->pagelist[j]);
-	}
-
-	request.handle = entry->handle;
-
-	if ( copy_to_user( argp, &request, sizeof(request) ) ) {
-		DRM(sg_cleanup)( entry );
-		return -EFAULT;
-	}
-
-	dev->sg = entry;
-
-#if DEBUG_SCATTER
-	/* Verify that each page points to its virtual address, and vice
-	 * versa.
-	 */
-	{
-	int error = 0;
-
-	for ( i = 0 ; i < pages ; i++ ) {
-		unsigned long *tmp;
-
-		tmp = page_address( entry->pagelist[i] );
-		for ( j = 0 ;
-		      j < PAGE_SIZE / sizeof(unsigned long) ;
-		      j++, tmp++ ) {
-			*tmp = 0xcafebabe;
-		}
-		tmp = (unsigned long *)((u8 *)entry->virtual +
-					(PAGE_SIZE * i));
-		for( j = 0 ;
-		     j < PAGE_SIZE / sizeof(unsigned long) ;
-		     j++, tmp++ ) {
-			if ( *tmp != 0xcafebabe && error == 0 ) {
-				error = 1;
-				DRM_ERROR( "Scatter allocation error, "
-					   "pagelist does not match "
-					   "virtual mapping\n" );
-			}
-		}
-		tmp = page_address( entry->pagelist[i] );
-		for(j = 0 ;
-		    j < PAGE_SIZE / sizeof(unsigned long) ;
-		    j++, tmp++) {
-			*tmp = 0;
-		}
-	}
-	if (error == 0)
-		DRM_ERROR( "Scatter allocation matches pagelist\n" );
-	}
-#endif
-
-	return 0;
-
- failed:
-	DRM(sg_cleanup)( entry );
-	return -ENOMEM;
-}
-
-int DRM(sg_free)( struct inode *inode, struct file *filp,
-		 unsigned int cmd, unsigned long arg )
-{
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
-	drm_scatter_gather_t request;
-	drm_sg_mem_t *entry;
-
-	if (!drm_core_check_feature(dev, DRIVER_SG))
-		return -EINVAL;
-
-	if ( copy_from_user( &request,
-			     (drm_scatter_gather_t __user *)arg,
-			     sizeof(request) ) )
-		return -EFAULT;
-
-	entry = dev->sg;
-	dev->sg = NULL;
-
-	if ( !entry || entry->handle != request.handle )
-		return -EINVAL;
-
-	DRM_DEBUG( "sg free virtual  = %p\n", entry->virtual );
-
-	DRM(sg_cleanup)( entry );
-
-	return 0;
-}
diff -Nru a/drivers/char/drm/drm_stub.c b/drivers/char/drm/drm_stub.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/char/drm/drm_stub.c	2005-03-01 23:39:09 -08:00
@@ -0,0 +1,259 @@
+/**
+ * \file drm_stub.h
+ * Stub support
+ *
+ * \author Rickard E. (Rik) Faith <faith@valinux.com>
+ */
+
+/*
+ * Created: Fri Jan 19 10:48:35 2001 by faith@acm.org
+ *
+ * Copyright 2001 VA Linux Systems, Inc., Sunnyvale, California.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include "drmP.h"
+#include "drm_core.h"
+
+unsigned int drm_cards_limit = 16;	/* Enough for one machine */
+unsigned int drm_debug = 0;		/* 1 to enable debug output */
+EXPORT_SYMBOL(drm_debug);
+
+MODULE_AUTHOR( DRIVER_AUTHOR );
+MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_LICENSE("GPL and additional rights");
+MODULE_PARM_DESC(drm_cards_limit, "Maximum number of graphics cards");
+MODULE_PARM_DESC(drm_debug, "Enable debug output");
+
+module_param_named(cards_limit, drm_cards_limit, int, 0444);
+module_param_named(debug, drm_debug, int, 0666);
+
+drm_minor_t *drm_minors;
+struct drm_sysfs_class *drm_class;
+struct proc_dir_entry *drm_proc_root;
+
+static int drm_fill_in_dev(drm_device_t *dev, struct pci_dev *pdev, const struct pci_device_id *ent, struct drm_driver *driver)
+{
+	int retcode;
+
+	spin_lock_init(&dev->count_lock);
+	init_timer( &dev->timer );
+	sema_init( &dev->struct_sem, 1 );
+	sema_init( &dev->ctxlist_sem, 1 );
+
+	dev->pdev   = pdev;
+
+#ifdef __alpha__
+	dev->hose   = pdev->sysdata;
+	dev->pci_domain = dev->hose->bus->number;
+#else
+	dev->pci_domain = 0;
+#endif
+	dev->pci_bus = pdev->bus->number;
+	dev->pci_slot = PCI_SLOT(pdev->devfn);
+	dev->pci_func = PCI_FUNC(pdev->devfn);
+	dev->irq = pdev->irq;
+
+	/* the DRM has 6 basic counters */
+	dev->counters = 6;
+	dev->types[0]  = _DRM_STAT_LOCK;
+	dev->types[1]  = _DRM_STAT_OPENS;
+	dev->types[2]  = _DRM_STAT_CLOSES;
+	dev->types[3]  = _DRM_STAT_IOCTLS;
+	dev->types[4]  = _DRM_STAT_LOCKS;
+	dev->types[5]  = _DRM_STAT_UNLOCKS;
+
+	dev->driver = driver;
+	
+	if (dev->driver->preinit)
+		if ((retcode = dev->driver->preinit(dev, ent->driver_data)))
+			goto error_out_unreg;
+
+	if (drm_core_has_AGP(dev)) {
+		dev->agp = drm_agp_init();
+		if (drm_core_check_feature(dev, DRIVER_REQUIRE_AGP) && (dev->agp == NULL)) {
+			DRM_ERROR( "Cannot initialize the agpgart module.\n" );
+			retcode = -EINVAL;
+			goto error_out_unreg;
+		}
+		if (drm_core_has_MTRR(dev)) {
+			if (dev->agp)
+				dev->agp->agp_mtrr = mtrr_add( dev->agp->agp_info.aper_base,
+							       dev->agp->agp_info.aper_size*1024*1024,
+							       MTRR_TYPE_WRCOMB,
+							       1 );
+		}
+	}
+
+	retcode = drm_ctxbitmap_init( dev );
+	if( retcode ) {
+		DRM_ERROR( "Cannot allocate memory for context bitmap.\n" );
+		goto error_out_unreg;
+	}
+
+	dev->device = MKDEV(DRM_MAJOR, dev->minor );
+
+	/* postinit is a required function to display the signon banner */
+	if ((retcode = dev->driver->postinit(dev, ent->driver_data)))
+		goto error_out_unreg;
+
+	return 0;
+	
+error_out_unreg:
+	drm_takedown(dev);
+	return retcode;
+}
+
+/**
+ * File \c open operation.
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ *
+ * Puts the dev->fops corresponding to the device minor number into
+ * \p filp, call the \c open method, and restore the file operations.
+ */
+int drm_stub_open(struct inode *inode, struct file *filp)
+{
+	drm_device_t *dev = NULL;
+	int minor = iminor(inode);
+	int err = -ENODEV;
+	struct file_operations *old_fops;
+	
+	DRM_DEBUG("\n");
+
+	if (!((minor >= 0) && (minor < drm_cards_limit)))
+		return -ENODEV;
+
+	dev = drm_minors[minor].dev;
+	if (!dev)
+		return -ENODEV;
+
+	old_fops = filp->f_op;
+	filp->f_op = fops_get(&dev->driver->fops);
+	if (filp->f_op->open && (err = filp->f_op->open(inode, filp))) {
+		fops_put(filp->f_op);
+		filp->f_op = fops_get(old_fops);
+	}
+	fops_put(old_fops);
+
+	return err;
+}
+
+/**
+ * Get a device minor number.
+ *
+ * \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_probe(struct pci_dev *pdev, const struct pci_device_id *ent, struct drm_driver *driver)
+{
+	struct class_device *dev_class;
+	drm_device_t *dev;
+	int ret;
+	int minor;
+	drm_minor_t *minors = &drm_minors[0];
+
+	DRM_DEBUG("\n");
+
+	for (minor = 0; minor < drm_cards_limit; minor++, minors++) {
+		if (minors->type == DRM_MINOR_FREE) {
+
+			DRM_DEBUG("assigning minor %d\n", minor);
+			dev = drm_calloc(1, sizeof(*dev), DRM_MEM_STUB);
+			if (!dev)
+				return -ENOMEM;
+
+			*minors = (drm_minor_t){.dev = dev, .type=DRM_MINOR_PRIMARY};
+			dev->minor = minor;
+
+			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_proc_init(dev, minor, drm_proc_root, &minors->dev_root))) {
+				printk (KERN_ERR "DRM: Failed to initialize /proc/dri.\n");
+				goto err_g1;
+			}
+
+			
+			dev_class = drm_sysfs_device_add(drm_class,
+							 MKDEV(DRM_MAJOR,
+							       minor),
+							 &pdev->dev,
+							 "card%d", minor);
+			if (IS_ERR(dev_class)) {
+				printk(KERN_ERR "DRM: Error sysfs_device_add.\n");
+				ret = PTR_ERR(dev_class);
+				goto err_g2;
+			}
+			
+			DRM_DEBUG("new minor assigned %d\n", minor);
+			return 0;
+		}
+	}
+	DRM_ERROR("out of minors\n");
+	return -ENOMEM;
+err_g2:
+	drm_proc_cleanup(minor, drm_proc_root, minors->dev_root);
+err_g1:
+	*minors = (drm_minor_t){.dev = NULL, .type = DRM_MINOR_FREE};
+	drm_free(dev, sizeof(*dev), DRM_MEM_STUB);
+	return ret;
+}
+EXPORT_SYMBOL(drm_probe);
+		
+
+/**
+ * Put a device minor number.
+ *
+ * \param minor minor number.
+ * \return always zero.
+ *
+ * Cleans up the proc resources. If a minor is zero then release the foreign
+ * "drm" data, otherwise unregisters the "drm" data, frees the stub list and
+ * unregisters the character device. 
+ */
+int drm_put_minor(drm_device_t *dev)
+{
+	drm_minor_t *minors = &drm_minors[dev->minor];
+	
+	DRM_DEBUG("release minor %d\n", dev->minor);
+	
+	drm_proc_cleanup(dev->minor, drm_proc_root, minors->dev_root);
+	drm_sysfs_device_remove(MKDEV(DRM_MAJOR, dev->minor));
+	
+	*minors = (drm_minor_t){.dev = NULL, .type = DRM_MINOR_FREE};
+	drm_free(dev, sizeof(*dev), DRM_MEM_STUB);
+	
+	return 0;
+}
+
diff -Nru a/drivers/char/drm/drm_stub.h b/drivers/char/drm/drm_stub.h
--- a/drivers/char/drm/drm_stub.h	2005-03-01 23:39:09 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,236 +0,0 @@
-/**
- * \file drm_stub.h
- * Stub support
- *
- * \author Rickard E. (Rik) Faith <faith@valinux.com>
- */
-
-/*
- * Created: Fri Jan 19 10:48:35 2001 by faith@acm.org
- *
- * Copyright 2001 VA Linux Systems, Inc., Sunnyvale, California.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#include "drmP.h"
-
-#define DRM_STUB_MAXCARDS 16	/* Enough for one machine */
-
-static struct class_simple *drm_class;
-
-/** Stub list. One for each minor. */
-static struct drm_stub_list {
-	const char             *name;
-	struct file_operations *fops;	/**< file operations */
-	struct proc_dir_entry  *dev_root;	/**< proc directory entry */
-} *DRM(stub_list);
-
-static struct proc_dir_entry *DRM(stub_root);
-
-/** Stub information */
-static struct drm_stub_info {
-	int (*info_register)(const char *name, struct file_operations *fops,
-			     drm_device_t *dev);
-	int (*info_unregister)(int minor);
-} DRM(stub_info);
-
-/**
- * File \c open operation.
- *
- * \param inode device inode.
- * \param filp file pointer.
- *
- * Puts the drm_stub_list::fops corresponding to the device minor number into
- * \p filp, call the \c open method, and restore the file operations.
- */
-static int DRM(stub_open)(struct inode *inode, struct file *filp)
-{
-	int                    minor = iminor(inode);
-	int                    err   = -ENODEV;
-	struct file_operations *old_fops;
-
-	if (!DRM(stub_list) || !DRM(stub_list)[minor].fops) return -ENODEV;
-	old_fops   = filp->f_op;
-	filp->f_op = fops_get(DRM(stub_list)[minor].fops);
-	if (filp->f_op->open && (err = filp->f_op->open(inode, filp))) {
-		fops_put(filp->f_op);
-		filp->f_op = fops_get(old_fops);
-	}
-	fops_put(old_fops);
-
-	return err;
-}
-
-/** File operations structure */
-static struct file_operations DRM(stub_fops) = {
-	.owner = THIS_MODULE,
-	.open  = DRM(stub_open)
-};
-
-/**
- * Get a device minor number.
- *
- * \param name driver name.
- * \param fops file operations.
- * \param dev DRM device.
- * \return minor number on success, or a negative number on failure.
- *
- * Allocate and initialize ::stub_list if one doesn't exist already.  Search an
- * empty entry and initialize it to the given parameters, and create the proc
- * init entry via proc_init().
- */
-static int DRM(stub_getminor)(const char *name, struct file_operations *fops,
-			      drm_device_t *dev)
-{
-	int i;
-
-	if (!DRM(stub_list)) {
-		DRM(stub_list) = DRM(alloc)(sizeof(*DRM(stub_list))
-					    * DRM_STUB_MAXCARDS, DRM_MEM_STUB);
-		if(!DRM(stub_list)) return -1;
-		for (i = 0; i < DRM_STUB_MAXCARDS; i++) {
-			DRM(stub_list)[i].name = NULL;
-			DRM(stub_list)[i].fops = NULL;
-		}
-	}
-	for (i = 0; i < DRM_STUB_MAXCARDS; i++) {
-		if (!DRM(stub_list)[i].fops) {
-			DRM(stub_list)[i].name = name;
-			DRM(stub_list)[i].fops = fops;
-			DRM(stub_root) = DRM(proc_init)(dev, i, DRM(stub_root),
-							&DRM(stub_list)[i]
-							.dev_root);
-			class_simple_device_add(drm_class, MKDEV(DRM_MAJOR, i), NULL, name);
-			return i;
-		}
-	}
-	return -1;
-}
-
-/**
- * Put a device minor number.
- *
- * \param minor minor number.
- * \return always zero.
- *
- * Cleans up the proc resources. If a minor is zero then release the foreign
- * "drm" data, otherwise unregisters the "drm" data, frees the stub list and
- * unregisters the character device. 
- */
-static int DRM(stub_putminor)(int minor)
-{
-	if (minor < 0 || minor >= DRM_STUB_MAXCARDS) return -1;
-	DRM(stub_list)[minor].name = NULL;
-	DRM(stub_list)[minor].fops = NULL;
-	DRM(proc_cleanup)(minor, DRM(stub_root),
-			  DRM(stub_list)[minor].dev_root);
-	if (minor) {
-		class_simple_device_remove(MKDEV(DRM_MAJOR, minor));
-		inter_module_put("drm");
-	} else {
-		inter_module_unregister("drm");
-		DRM(free)(DRM(stub_list),
-			  sizeof(*DRM(stub_list)) * DRM_STUB_MAXCARDS,
-			  DRM_MEM_STUB);
-		unregister_chrdev(DRM_MAJOR, "drm");
-		class_simple_device_remove(MKDEV(DRM_MAJOR, minor));
-		class_simple_destroy(drm_class);
-	}
-	return 0;
-}
-
-/**
- * Register.
- *
- * \param name driver name.
- * \param fops file operations
- * \param dev DRM device.
- * \return zero on success or a negative number on failure.
- *
- * Attempt to register the char device and get the foreign "drm" data. If
- * successful then another module already registered so gets the stub info,
- * otherwise use this module stub info and make it available for other modules.
- *
- * Finally calls stub_info::info_register.
- */
-int DRM(stub_register)(const char *name, struct file_operations *fops,
-		       drm_device_t *dev)
-{
-	struct drm_stub_info *i = NULL;
-	int ret1;
-	int ret2;
-
-	DRM_DEBUG("\n");
-	ret1 = register_chrdev(DRM_MAJOR, "drm", &DRM(stub_fops));
-	if (!ret1) {
-		drm_class = class_simple_create(THIS_MODULE, "drm");
-		if (IS_ERR(drm_class)) {
-			printk (KERN_ERR "Error creating drm class.\n");
-			unregister_chrdev(DRM_MAJOR, "drm");
-			return PTR_ERR(drm_class);
-		}
-	}
-	else if (ret1 == -EBUSY)
-		i = (struct drm_stub_info *)inter_module_get("drm");
-	else
-		return -1;
-
-	if (i) {
-				/* Already registered */
-		DRM(stub_info).info_register   = i->info_register;
-		DRM(stub_info).info_unregister = i->info_unregister;
-		DRM_DEBUG("already registered\n");
-	} else if (DRM(stub_info).info_register != DRM(stub_getminor)) {
-		DRM(stub_info).info_register   = DRM(stub_getminor);
-		DRM(stub_info).info_unregister = DRM(stub_putminor);
-		DRM_DEBUG("calling inter_module_register\n");
-		inter_module_register("drm", THIS_MODULE, &DRM(stub_info));
-	}
-	if (DRM(stub_info).info_register) {
-		ret2 = DRM(stub_info).info_register(name, fops, dev);
-		if (ret2) {
-			if (!ret1) {
-				unregister_chrdev(DRM_MAJOR, "drm");
-				class_simple_destroy(drm_class);
-			}
-			if (!i)
-				inter_module_unregister("drm");
-		}
-		return ret2;
-	}
-	return -1;
-}
-
-/**
- * Unregister.
- *
- * \param minor
- *
- * Calls drm_stub_info::unregister.
- */
-int DRM(stub_unregister)(int minor)
-{
-	DRM_DEBUG("%d\n", minor);
-	if (DRM(stub_info).info_unregister)
-		return DRM(stub_info).info_unregister(minor);
-	return -1;
-}
diff -Nru a/drivers/char/drm/drm_sysfs.c b/drivers/char/drm/drm_sysfs.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/char/drm/drm_sysfs.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,208 @@
+/*
+ * drm_sysfs.c - Modifications to drm_sysfs_class.c to support
+ *               extra sysfs attribute from DRM. Normal drm_sysfs_class
+ *               does not allow adding attributes.
+ *
+ * Copyright (c) 2004 Jon Smirl <jonsmirl@gmail.com>
+ * 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/kdev_t.h>
+#include <linux/err.h>
+
+#include "drm_core.h"
+
+struct drm_sysfs_class {
+	struct class_device_attribute attr;
+	struct class class;
+};
+#define to_drm_sysfs_class(d) container_of(d, struct drm_sysfs_class, class)
+
+struct simple_dev {
+	struct list_head node;
+	dev_t dev;
+	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 ssize_t show_dev(struct class_device *class_dev, char *buf)
+{
+	struct simple_dev *s_dev = to_simple_dev(class_dev);
+	return print_dev_t(buf, s_dev->dev);
+}
+
+static void drm_sysfs_class_release(struct class *class)
+{
+	struct drm_sysfs_class *cs = to_drm_sysfs_class(class);
+	kfree(cs);
+}
+
+/* Display the version of drm_core. This doesn't work right in current design */
+static ssize_t version_show(struct class *dev, char *buf)
+{
+	return sprintf(buf, "%s %d.%d.%d %s\n", DRIVER_NAME, DRIVER_MAJOR,
+		       DRIVER_MINOR, DRIVER_PATCHLEVEL, DRIVER_DATE);
+}
+
+static CLASS_ATTR(version, S_IRUGO, version_show, NULL);
+
+/**
+ * drm_sysfs_create - create a struct drm_sysfs_class structure
+ * @owner: pointer to the module that is to "own" this struct drm_sysfs_class
+ * @name: pointer to a string for the name of this class.
+ *
+ * This is used to create a struct drm_sysfs_class pointer that can then be used
+ * in calls to drm_sysfs_device_add().
+ *
+ * Note, the pointer created here is to be destroyed when finished by making a
+ * call to drm_sysfs_destroy().
+ */
+struct drm_sysfs_class *drm_sysfs_create(struct module *owner, char *name)
+{
+	struct drm_sysfs_class *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 = drm_sysfs_class_release;
+	cs->class.release = release_simple_dev;
+
+	cs->attr.attr.name = "dev";
+	cs->attr.attr.mode = S_IRUGO;
+	cs->attr.attr.owner = owner;
+	cs->attr.show = show_dev;
+	cs->attr.store = NULL;
+
+	retval = class_register(&cs->class);
+	if (retval)
+		goto error;
+	class_create_file(&cs->class, &class_attr_version);
+
+	return cs;
+
+      error:
+	kfree(cs);
+	return ERR_PTR(retval);
+}
+
+/**
+ * drm_sysfs_destroy - destroys a struct drm_sysfs_class structure
+ * @cs: pointer to the struct drm_sysfs_class that is to be destroyed
+ *
+ * Note, the pointer to be destroyed must have been created with a call to
+ * drm_sysfs_create().
+ */
+void drm_sysfs_destroy(struct drm_sysfs_class *cs)
+{
+	if ((cs == NULL) || (IS_ERR(cs)))
+		return;
+
+	class_unregister(&cs->class);
+}
+
+/**
+ * drm_sysfs_device_add - adds a class device to sysfs for a character driver
+ * @cs: pointer to the struct drm_sysfs_class 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
+ *
+ * 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 drm_sysfs_class passed to this function must have previously been
+ * created with a call to drm_sysfs_create().
+ */
+struct class_device *drm_sysfs_device_add(struct drm_sysfs_class *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->dev = 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;
+
+	class_device_create_file(&s_dev->class_dev, &cs->attr);
+
+	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);
+}
+
+/**
+ * drm_sysfs_device_remove - removes a class device that was created with drm_sysfs_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 drm_sysfs_device_add()
+ */
+void drm_sysfs_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->dev == 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);
+	}
+}
diff -Nru a/drivers/char/drm/drm_vm.c b/drivers/char/drm/drm_vm.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/char/drm/drm_vm.c	2005-03-01 23:39:17 -08:00
@@ -0,0 +1,678 @@
+/**
+ * \file drm_vm.h
+ * Memory mapping for DRM
+ * 
+ * \author Rickard E. (Rik) Faith <faith@valinux.com>
+ * \author Gareth Hughes <gareth@valinux.com>
+ */
+
+/*
+ * Created: Mon Jan  4 08:58:31 1999 by faith@valinux.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "drmP.h"
+#if defined(__ia64__)
+#include <linux/efi.h>
+#endif
+
+
+/**
+ * \c nopage method for AGP virtual memory.
+ *
+ * \param vma virtual memory area.
+ * \param address access address.
+ * \return pointer to the page structure.
+ * 
+ * Find the right map and if it's AGP memory find the real physical page to
+ * map, get the page, increment the use count and return it.
+ */
+#if __OS_HAS_AGP
+static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma,
+						 unsigned long address)
+{
+	drm_file_t *priv  = vma->vm_file->private_data;
+	drm_device_t *dev = priv->dev;
+	drm_map_t *map    = NULL;
+	drm_map_list_t  *r_list;
+	struct list_head *list;
+
+	/*
+         * Find the right map
+         */
+	if (!drm_core_has_AGP(dev))
+		goto vm_nopage_error;
+
+	if(!dev->agp || !dev->agp->cant_use_aperture) goto vm_nopage_error;
+
+	list_for_each(list, &dev->maplist->head) {
+		r_list = list_entry(list, drm_map_list_t, head);
+		map = r_list->map;
+		if (!map) continue;
+		if (map->offset == VM_OFFSET(vma)) break;
+	}
+
+	if (map && map->type == _DRM_AGP) {
+		unsigned long offset = address - vma->vm_start;
+		unsigned long baddr = VM_OFFSET(vma) + offset;
+		struct drm_agp_mem *agpmem;
+		struct page *page;
+
+#ifdef __alpha__
+		/*
+                 * Adjust to a bus-relative address
+                 */
+		baddr -= dev->hose->mem_space->start;
+#endif
+
+		/*
+                 * It's AGP memory - find the real physical page to map
+                 */
+		for(agpmem = dev->agp->memory; agpmem; agpmem = agpmem->next) {
+			if (agpmem->bound <= baddr &&
+			    agpmem->bound + agpmem->pages * PAGE_SIZE > baddr) 
+				break;
+		}
+
+		if (!agpmem) goto vm_nopage_error;
+
+		/*
+                 * Get the page, inc the use count, and return it
+                 */
+		offset = (baddr - agpmem->bound) >> PAGE_SHIFT;
+		page = virt_to_page(__va(agpmem->memory->memory[offset]));
+		get_page(page);
+
+		DRM_DEBUG("baddr = 0x%lx page = 0x%p, offset = 0x%lx, count=%d\n",
+			  baddr, __va(agpmem->memory->memory[offset]), offset,
+			  page_count(page));
+
+		return page;
+        }
+vm_nopage_error:
+	return NOPAGE_SIGBUS;		/* Disallow mremap */
+}
+#else /* __OS_HAS_AGP */
+static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma,
+						 unsigned long address)
+{
+	return NOPAGE_SIGBUS;
+}
+#endif /* __OS_HAS_AGP */
+
+/**
+ * \c nopage method for shared virtual memory.
+ *
+ * \param vma virtual memory area.
+ * \param address access address.
+ * \return pointer to the page structure.
+ * 
+ * Get the the mapping, find the real physical page to map, get the page, and
+ * return it.
+ */
+static __inline__ struct page *drm_do_vm_shm_nopage(struct vm_area_struct *vma,
+						     unsigned long address)
+{
+	drm_map_t	 *map	 = (drm_map_t *)vma->vm_private_data;
+	unsigned long	 offset;
+	unsigned long	 i;
+	struct page	 *page;
+
+	if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */
+	if (!map)    		   return NOPAGE_OOM;  /* Nothing allocated */
+
+	offset	 = address - vma->vm_start;
+	i = (unsigned long)map->handle + offset;
+	page = vmalloc_to_page((void *)i);
+	if (!page)
+		return NOPAGE_OOM;
+	get_page(page);
+
+	DRM_DEBUG("shm_nopage 0x%lx\n", address);
+	return page;
+}
+
+
+/**
+ * \c close method for shared virtual memory.
+ * 
+ * \param vma virtual memory area.
+ * 
+ * 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)
+{
+	drm_file_t	*priv	= vma->vm_file->private_data;
+	drm_device_t	*dev	= priv->dev;
+	drm_vma_entry_t *pt, *prev, *next;
+	drm_map_t *map;
+	drm_map_list_t *r_list;
+	struct list_head *list;
+	int found_maps = 0;
+
+	DRM_DEBUG("0x%08lx,0x%08lx\n",
+		  vma->vm_start, vma->vm_end - vma->vm_start);
+	atomic_dec(&dev->vma_count);
+
+	map = vma->vm_private_data;
+
+	down(&dev->struct_sem);
+	for (pt = dev->vmalist, prev = NULL; pt; pt = next) {
+		next = pt->next;
+		if (pt->vma->vm_private_data == map) found_maps++;
+		if (pt->vma == vma) {
+			if (prev) {
+				prev->next = pt->next;
+			} else {
+				dev->vmalist = pt->next;
+			}
+			drm_free(pt, sizeof(*pt), DRM_MEM_VMAS);
+		} else {
+			prev = pt;
+		}
+	}
+	/* We were the only map that was found */
+	if(found_maps == 1 &&
+	   map->flags & _DRM_REMOVABLE) {
+		/* Check to see if we are in the maplist, if we are not, then
+		 * we delete this mappings information.
+		 */
+		found_maps = 0;
+		list = &dev->maplist->head;
+		list_for_each(list, &dev->maplist->head) {
+			r_list = list_entry(list, drm_map_list_t, head);
+			if (r_list->map == map) found_maps++;
+		}
+
+		if(!found_maps) {
+			switch (map->type) {
+			case _DRM_REGISTERS:
+			case _DRM_FRAME_BUFFER:
+				if (drm_core_has_MTRR(dev) && map->mtrr >= 0) {
+					int retcode;
+					retcode = mtrr_del(map->mtrr,
+							   map->offset,
+							   map->size);
+					DRM_DEBUG("mtrr_del = %d\n", retcode);
+				}
+				drm_ioremapfree(map->handle, map->size, dev);
+				break;
+			case _DRM_SHM:
+				vfree(map->handle);
+				break;
+			case _DRM_AGP:
+			case _DRM_SCATTER_GATHER:
+				break;
+			}
+			drm_free(map, sizeof(*map), DRM_MEM_MAPS);
+		}
+	}
+	up(&dev->struct_sem);
+}
+
+/**
+ * \c nopage method for DMA virtual memory.
+ *
+ * \param vma virtual memory area.
+ * \param address access address.
+ * \return pointer to the page structure.
+ * 
+ * Determine the page number from the page offset and get it from drm_device_dma::pagelist.
+ */
+static __inline__ struct page *drm_do_vm_dma_nopage(struct vm_area_struct *vma,
+						     unsigned long address)
+{
+	drm_file_t	 *priv	 = vma->vm_file->private_data;
+	drm_device_t	 *dev	 = priv->dev;
+	drm_device_dma_t *dma	 = dev->dma;
+	unsigned long	 offset;
+	unsigned long	 page_nr;
+	struct page	 *page;
+
+	if (!dma)		   return NOPAGE_SIGBUS; /* Error */
+	if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */
+	if (!dma->pagelist)	   return NOPAGE_OOM ; /* Nothing allocated */
+
+	offset	 = address - vma->vm_start; /* vm_[pg]off[set] should be 0 */
+	page_nr  = offset >> PAGE_SHIFT;
+	page = virt_to_page((dma->pagelist[page_nr] + 
+			     (offset & (~PAGE_MASK))));
+
+	get_page(page);
+
+	DRM_DEBUG("dma_nopage 0x%lx (page %lu)\n", address, page_nr);
+	return page;
+}
+
+/**
+ * \c nopage method for scatter-gather virtual memory.
+ *
+ * \param vma virtual memory area.
+ * \param address access address.
+ * \return pointer to the page structure.
+ * 
+ * Determine the map offset from the page offset and get it from drm_sg_mem::pagelist.
+ */
+static __inline__ struct page *drm_do_vm_sg_nopage(struct vm_area_struct *vma,
+						    unsigned long address)
+{
+	drm_map_t        *map    = (drm_map_t *)vma->vm_private_data;
+	drm_file_t *priv = vma->vm_file->private_data;
+	drm_device_t *dev = priv->dev;
+	drm_sg_mem_t *entry = dev->sg;
+	unsigned long offset;
+	unsigned long map_offset;
+	unsigned long page_offset;
+	struct page *page;
+
+	if (!entry)                return NOPAGE_SIGBUS; /* Error */
+	if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */
+	if (!entry->pagelist)      return NOPAGE_OOM ;  /* Nothing allocated */
+
+
+	offset = address - vma->vm_start;
+	map_offset = map->offset - dev->sg->handle;
+	page_offset = (offset >> PAGE_SHIFT) + (map_offset >> PAGE_SHIFT);
+	page = entry->pagelist[page_offset];
+	get_page(page);
+
+	return page;
+}
+
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
+
+static struct page *drm_vm_nopage(struct vm_area_struct *vma,
+				   unsigned long address,
+				   int *type) {
+	if (type) *type = VM_FAULT_MINOR;
+	return drm_do_vm_nopage(vma, address);
+}
+
+static struct page *drm_vm_shm_nopage(struct vm_area_struct *vma,
+				       unsigned long address,
+				       int *type) {
+	if (type) *type = VM_FAULT_MINOR;
+	return drm_do_vm_shm_nopage(vma, address);
+}
+
+static struct page *drm_vm_dma_nopage(struct vm_area_struct *vma,
+				       unsigned long address,
+				       int *type) {
+	if (type) *type = VM_FAULT_MINOR;
+	return drm_do_vm_dma_nopage(vma, address);
+}
+
+static struct page *drm_vm_sg_nopage(struct vm_area_struct *vma,
+				      unsigned long address,
+				      int *type) {
+	if (type) *type = VM_FAULT_MINOR;
+	return drm_do_vm_sg_nopage(vma, address);
+}
+
+#else	/* LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,0) */
+
+static struct page *drm_vm_nopage(struct vm_area_struct *vma,
+				   unsigned long address,
+				   int unused) {
+	return drm_do_vm_nopage(vma, address);
+}
+
+static struct page *drm_vm_shm_nopage(struct vm_area_struct *vma,
+				       unsigned long address,
+				       int unused) {
+	return drm_do_vm_shm_nopage(vma, address);
+}
+
+static struct page *drm_vm_dma_nopage(struct vm_area_struct *vma,
+				       unsigned long address,
+				       int unused) {
+	return drm_do_vm_dma_nopage(vma, address);
+}
+
+static struct page *drm_vm_sg_nopage(struct vm_area_struct *vma,
+				      unsigned long address,
+				      int unused) {
+	return drm_do_vm_sg_nopage(vma, address);
+}
+
+#endif
+
+
+/** AGP virtual memory operations */
+static struct vm_operations_struct   drm_vm_ops = {
+	.nopage = drm_vm_nopage,
+	.open	= drm_vm_open,
+	.close	= drm_vm_close,
+};
+
+/** Shared virtual memory operations */
+static struct vm_operations_struct   drm_vm_shm_ops = {
+	.nopage = drm_vm_shm_nopage,
+	.open	= drm_vm_open,
+	.close	= drm_vm_shm_close,
+};
+
+/** DMA virtual memory operations */
+static struct vm_operations_struct   drm_vm_dma_ops = {
+	.nopage = drm_vm_dma_nopage,
+	.open	= drm_vm_open,
+	.close	= drm_vm_close,
+};
+
+/** Scatter-gather virtual memory operations */
+static struct vm_operations_struct   drm_vm_sg_ops = {
+	.nopage = drm_vm_sg_nopage,
+	.open   = drm_vm_open,
+	.close  = drm_vm_close,
+};
+
+
+/**
+ * \c open method for shared virtual memory.
+ * 
+ * \param vma virtual memory area.
+ * 
+ * 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)
+{
+	drm_file_t	*priv	= vma->vm_file->private_data;
+	drm_device_t	*dev	= priv->dev;
+	drm_vma_entry_t *vma_entry;
+
+	DRM_DEBUG("0x%08lx,0x%08lx\n",
+		  vma->vm_start, vma->vm_end - vma->vm_start);
+	atomic_inc(&dev->vma_count);
+
+	vma_entry = drm_alloc(sizeof(*vma_entry), DRM_MEM_VMAS);
+	if (vma_entry) {
+		down(&dev->struct_sem);
+		vma_entry->vma	= vma;
+		vma_entry->next = dev->vmalist;
+		vma_entry->pid	= current->pid;
+		dev->vmalist	= vma_entry;
+		up(&dev->struct_sem);
+	}
+}
+
+/**
+ * \c close method for all virtual memory types.
+ * 
+ * \param vma virtual memory area.
+ * 
+ * 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)
+{
+	drm_file_t	*priv	= vma->vm_file->private_data;
+	drm_device_t	*dev	= priv->dev;
+	drm_vma_entry_t *pt, *prev;
+
+	DRM_DEBUG("0x%08lx,0x%08lx\n",
+		  vma->vm_start, vma->vm_end - vma->vm_start);
+	atomic_dec(&dev->vma_count);
+
+	down(&dev->struct_sem);
+	for (pt = dev->vmalist, prev = NULL; pt; prev = pt, pt = pt->next) {
+		if (pt->vma == vma) {
+			if (prev) {
+				prev->next = pt->next;
+			} else {
+				dev->vmalist = pt->next;
+			}
+			drm_free(pt, sizeof(*pt), DRM_MEM_VMAS);
+			break;
+		}
+	}
+	up(&dev->struct_sem);
+}
+
+/**
+ * mmap DMA memory.
+ *
+ * \param filp file pointer.
+ * \param vma virtual memory area.
+ * \return zero on success or a negative number on failure.
+ * 
+ * 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)
+{
+	drm_file_t	 *priv	 = filp->private_data;
+	drm_device_t	 *dev;
+	drm_device_dma_t *dma;
+	unsigned long	 length	 = vma->vm_end - vma->vm_start;
+
+	lock_kernel();
+	dev	 = priv->dev;
+	dma	 = dev->dma;
+	DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n",
+		  vma->vm_start, vma->vm_end, VM_OFFSET(vma));
+
+				/* Length must match exact page count */
+	if (!dma || (length >> PAGE_SHIFT) != dma->page_count) {
+		unlock_kernel();
+		return -EINVAL;
+	}
+	unlock_kernel();
+
+	vma->vm_ops   = &drm_vm_dma_ops;
+
+#if LINUX_VERSION_CODE <= 0x02040e /* KERNEL_VERSION(2,4,14) */
+	vma->vm_flags |= VM_LOCKED | VM_SHM; /* Don't swap */
+#else
+	vma->vm_flags |= VM_RESERVED; /* Don't swap */
+#endif
+
+	vma->vm_file  =	 filp;	/* Needed for drm_vm_open() */
+	drm_vm_open(vma);
+	return 0;
+}
+
+unsigned long drm_core_get_map_ofs(drm_map_t *map)
+{
+	return map->offset;
+}
+EXPORT_SYMBOL(drm_core_get_map_ofs);
+
+unsigned long drm_core_get_reg_ofs(struct drm_device *dev)
+{
+#ifdef __alpha__
+	return dev->hose->dense_mem_base - dev->hose->mem_space->start;
+#else
+	return 0;
+#endif
+}
+EXPORT_SYMBOL(drm_core_get_reg_ofs);
+
+/**
+ * mmap DMA memory.
+ *
+ * \param filp file pointer.
+ * \param vma virtual memory area.
+ * \return zero on success or a negative number on failure.
+ * 
+ * If the virtual memory area has no offset associated with it then it's a DMA
+ * area, so calls mmap_dma(). Otherwise searches the map in drm_device::maplist,
+ * checks that the restricted flag is not set, sets the virtual memory operations
+ * according to the mapping type and remaps the pages. Finally sets the file
+ * pointer and calls vm_open().
+ */
+int drm_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+	drm_file_t	*priv	= filp->private_data;
+	drm_device_t	*dev	= priv->dev;
+	drm_map_t	*map	= NULL;
+	drm_map_list_t  *r_list;
+	unsigned long   offset  = 0;
+	struct list_head *list;
+
+	DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n",
+		  vma->vm_start, vma->vm_end, VM_OFFSET(vma));
+
+	if ( !priv->authenticated ) return -EACCES;
+
+	/* We check for "dma". On Apple's UniNorth, it's valid to have
+	 * the AGP mapped at physical address 0
+	 * --BenH.
+	 */
+	if (!VM_OFFSET(vma)
+#if __OS_HAS_AGP
+	    && (!dev->agp || dev->agp->agp_info.device->vendor != PCI_VENDOR_ID_APPLE)
+#endif
+	    )
+		return drm_mmap_dma(filp, vma);
+
+				/* A sequential search of a linked list is
+				   fine here because: 1) there will only be
+				   about 5-10 entries in the list and, 2) a
+				   DRI client only has to do this mapping
+				   once, so it doesn't have to be optimized
+				   for performance, even if the list was a
+				   bit longer. */
+	list_for_each(list, &dev->maplist->head) {
+		unsigned long off;
+
+		r_list = list_entry(list, drm_map_list_t, head);
+		map = r_list->map;
+		if (!map) continue;
+		off = dev->driver->get_map_ofs(map);
+		if (off == VM_OFFSET(vma)) break;
+	}
+
+	if (!map || ((map->flags&_DRM_RESTRICTED) && !capable(CAP_SYS_ADMIN)))
+		return -EPERM;
+
+				/* Check for valid size. */
+	if (map->size != vma->vm_end - vma->vm_start) return -EINVAL;
+
+	if (!capable(CAP_SYS_ADMIN) && (map->flags & _DRM_READ_ONLY)) {
+		vma->vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
+#if defined(__i386__) || defined(__x86_64__)
+		pgprot_val(vma->vm_page_prot) &= ~_PAGE_RW;
+#else
+				/* Ye gads this is ugly.  With more thought
+                                   we could move this up higher and use
+                                   `protection_map' instead.  */
+		vma->vm_page_prot = __pgprot(pte_val(pte_wrprotect(
+			__pte(pgprot_val(vma->vm_page_prot)))));
+#endif
+	}
+
+	switch (map->type) {
+        case _DRM_AGP:
+	  if (drm_core_has_AGP(dev) && dev->agp->cant_use_aperture) {
+                /*
+                 * On some platforms we can't talk to bus dma address from the CPU, so for
+                 * memory of type DRM_AGP, we'll deal with sorting out the real physical
+                 * pages and mappings in nopage()
+                 */
+#if defined(__powerpc__)
+		pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE;
+#endif
+                vma->vm_ops = &drm_vm_ops;
+                break;
+	  }
+                /* fall through to _DRM_FRAME_BUFFER... */        
+	case _DRM_FRAME_BUFFER:
+	case _DRM_REGISTERS:
+		if (VM_OFFSET(vma) >= __pa(high_memory)) {
+#if defined(__i386__) || defined(__x86_64__)
+			if (boot_cpu_data.x86 > 3 && map->type != _DRM_AGP) {
+				pgprot_val(vma->vm_page_prot) |= _PAGE_PCD;
+				pgprot_val(vma->vm_page_prot) &= ~_PAGE_PWT;
+			}
+#elif defined(__powerpc__)
+			pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE | _PAGE_GUARDED;
+#endif
+			vma->vm_flags |= VM_IO;	/* not in core dump */
+		}
+#if defined(__ia64__)
+		if (efi_range_is_wc(vma->vm_start, vma->vm_end -
+				    vma->vm_start))
+			vma->vm_page_prot =
+				pgprot_writecombine(vma->vm_page_prot);
+		else
+			vma->vm_page_prot =
+				pgprot_noncached(vma->vm_page_prot);
+#endif
+		offset = dev->driver->get_reg_ofs(dev);
+#ifdef __sparc__
+		if (io_remap_page_range(DRM_RPR_ARG(vma) vma->vm_start,
+					VM_OFFSET(vma) + offset,
+					vma->vm_end - vma->vm_start,
+					vma->vm_page_prot, 0))
+#else
+		if (remap_pfn_range(DRM_RPR_ARG(vma) vma->vm_start,
+				     (VM_OFFSET(vma) + offset) >> PAGE_SHIFT,
+				     vma->vm_end - vma->vm_start,
+				     vma->vm_page_prot))
+#endif
+				return -EAGAIN;
+		DRM_DEBUG("   Type = %d; start = 0x%lx, end = 0x%lx,"
+			  " offset = 0x%lx\n",
+			  map->type,
+			  vma->vm_start, vma->vm_end, VM_OFFSET(vma) + offset);
+		vma->vm_ops = &drm_vm_ops;
+		break;
+	case _DRM_SHM:
+		vma->vm_ops = &drm_vm_shm_ops;
+		vma->vm_private_data = (void *)map;
+				/* Don't let this area swap.  Change when
+				   DRM_KERNEL advisory is supported. */
+#if LINUX_VERSION_CODE <= 0x02040e /* KERNEL_VERSION(2,4,14) */
+		vma->vm_flags |= VM_LOCKED;
+#else
+		vma->vm_flags |= VM_RESERVED;
+#endif
+		break;
+	case _DRM_SCATTER_GATHER:
+		vma->vm_ops = &drm_vm_sg_ops;
+		vma->vm_private_data = (void *)map;
+#if LINUX_VERSION_CODE <= 0x02040e /* KERNEL_VERSION(2,4,14) */
+		vma->vm_flags |= VM_LOCKED;
+#else
+		vma->vm_flags |= VM_RESERVED;
+#endif
+                break;
+	default:
+		return -EINVAL;	/* This should never happen. */
+	}
+#if LINUX_VERSION_CODE <= 0x02040e /* KERNEL_VERSION(2,4,14) */
+	vma->vm_flags |= VM_LOCKED | VM_SHM; /* Don't swap */
+#else
+	vma->vm_flags |= VM_RESERVED; /* Don't swap */
+#endif
+
+	vma->vm_file  =	 filp;	/* Needed for drm_vm_open() */
+	drm_vm_open(vma);
+	return 0;
+}
+EXPORT_SYMBOL(drm_mmap);
diff -Nru a/drivers/char/drm/drm_vm.h b/drivers/char/drm/drm_vm.h
--- a/drivers/char/drm/drm_vm.h	2005-03-01 23:39:17 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,667 +0,0 @@
-/**
- * \file drm_vm.h
- * Memory mapping for DRM
- * 
- * \author Rickard E. (Rik) Faith <faith@valinux.com>
- * \author Gareth Hughes <gareth@valinux.com>
- */
-
-/*
- * Created: Mon Jan  4 08:58:31 1999 by faith@valinux.com
- *
- * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include "drmP.h"
-
-
-/**
- * \c nopage method for AGP virtual memory.
- *
- * \param vma virtual memory area.
- * \param address access address.
- * \return pointer to the page structure.
- * 
- * Find the right map and if it's AGP memory find the real physical page to
- * map, get the page, increment the use count and return it.
- */
-#if __OS_HAS_AGP
-static __inline__ struct page *DRM(do_vm_nopage)(struct vm_area_struct *vma,
-						 unsigned long address)
-{
-	drm_file_t *priv  = vma->vm_file->private_data;
-	drm_device_t *dev = priv->dev;
-	drm_map_t *map    = NULL;
-	drm_map_list_t  *r_list;
-	struct list_head *list;
-
-	/*
-         * Find the right map
-         */
-	if (!drm_core_has_AGP(dev))
-		goto vm_nopage_error;
-
-	if(!dev->agp || !dev->agp->cant_use_aperture) goto vm_nopage_error;
-
-	list_for_each(list, &dev->maplist->head) {
-		r_list = list_entry(list, drm_map_list_t, head);
-		map = r_list->map;
-		if (!map) continue;
-		if (map->offset == VM_OFFSET(vma)) break;
-	}
-
-	if (map && map->type == _DRM_AGP) {
-		unsigned long offset = address - vma->vm_start;
-		unsigned long baddr = VM_OFFSET(vma) + offset;
-		struct drm_agp_mem *agpmem;
-		struct page *page;
-
-#ifdef __alpha__
-		/*
-                 * Adjust to a bus-relative address
-                 */
-		baddr -= dev->hose->mem_space->start;
-#endif
-
-		/*
-                 * It's AGP memory - find the real physical page to map
-                 */
-		for(agpmem = dev->agp->memory; agpmem; agpmem = agpmem->next) {
-			if (agpmem->bound <= baddr &&
-			    agpmem->bound + agpmem->pages * PAGE_SIZE > baddr) 
-				break;
-		}
-
-		if (!agpmem) goto vm_nopage_error;
-
-		/*
-                 * Get the page, inc the use count, and return it
-                 */
-		offset = (baddr - agpmem->bound) >> PAGE_SHIFT;
-		page = virt_to_page(__va(agpmem->memory->memory[offset]));
-		get_page(page);
-
-		DRM_DEBUG("baddr = 0x%lx page = 0x%p, offset = 0x%lx, count=%d\n",
-			  baddr, __va(agpmem->memory->memory[offset]), offset,
-			  page_count(page));
-
-		return page;
-        }
-vm_nopage_error:
-	return NOPAGE_SIGBUS;		/* Disallow mremap */
-}
-#else /* __OS_HAS_AGP */
-static __inline__ struct page *DRM(do_vm_nopage)(struct vm_area_struct *vma,
-						 unsigned long address)
-{
-	return NOPAGE_SIGBUS;
-}
-#endif /* __OS_HAS_AGP */
-
-/**
- * \c nopage method for shared virtual memory.
- *
- * \param vma virtual memory area.
- * \param address access address.
- * \return pointer to the page structure.
- * 
- * Get the the mapping, find the real physical page to map, get the page, and
- * return it.
- */
-static __inline__ struct page *DRM(do_vm_shm_nopage)(struct vm_area_struct *vma,
-						     unsigned long address)
-{
-	drm_map_t	 *map	 = (drm_map_t *)vma->vm_private_data;
-	unsigned long	 offset;
-	unsigned long	 i;
-	struct page	 *page;
-
-	if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */
-	if (!map)    		   return NOPAGE_OOM;  /* Nothing allocated */
-
-	offset	 = address - vma->vm_start;
-	i = (unsigned long)map->handle + offset;
-	page = vmalloc_to_page((void *)i);
-	if (!page)
-		return NOPAGE_OOM;
-	get_page(page);
-
-	DRM_DEBUG("shm_nopage 0x%lx\n", address);
-	return page;
-}
-
-
-/**
- * \c close method for shared virtual memory.
- * 
- * \param vma virtual memory area.
- * 
- * 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)
-{
-	drm_file_t	*priv	= vma->vm_file->private_data;
-	drm_device_t	*dev	= priv->dev;
-	drm_vma_entry_t *pt, *prev, *next;
-	drm_map_t *map;
-	drm_map_list_t *r_list;
-	struct list_head *list;
-	int found_maps = 0;
-
-	DRM_DEBUG("0x%08lx,0x%08lx\n",
-		  vma->vm_start, vma->vm_end - vma->vm_start);
-	atomic_dec(&dev->vma_count);
-
-	map = vma->vm_private_data;
-
-	down(&dev->struct_sem);
-	for (pt = dev->vmalist, prev = NULL; pt; pt = next) {
-		next = pt->next;
-		if (pt->vma->vm_private_data == map) found_maps++;
-		if (pt->vma == vma) {
-			if (prev) {
-				prev->next = pt->next;
-			} else {
-				dev->vmalist = pt->next;
-			}
-			DRM(free)(pt, sizeof(*pt), DRM_MEM_VMAS);
-		} else {
-			prev = pt;
-		}
-	}
-	/* We were the only map that was found */
-	if(found_maps == 1 &&
-	   map->flags & _DRM_REMOVABLE) {
-		/* Check to see if we are in the maplist, if we are not, then
-		 * we delete this mappings information.
-		 */
-		found_maps = 0;
-		list = &dev->maplist->head;
-		list_for_each(list, &dev->maplist->head) {
-			r_list = list_entry(list, drm_map_list_t, head);
-			if (r_list->map == map) found_maps++;
-		}
-
-		if(!found_maps) {
-			switch (map->type) {
-			case _DRM_REGISTERS:
-			case _DRM_FRAME_BUFFER:
-				if (drm_core_has_MTRR(dev) && map->mtrr >= 0) {
-					int retcode;
-					retcode = mtrr_del(map->mtrr,
-							   map->offset,
-							   map->size);
-					DRM_DEBUG("mtrr_del = %d\n", retcode);
-				}
-				DRM(ioremapfree)(map->handle, map->size, dev);
-				break;
-			case _DRM_SHM:
-				vfree(map->handle);
-				break;
-			case _DRM_AGP:
-			case _DRM_SCATTER_GATHER:
-				break;
-			}
-			DRM(free)(map, sizeof(*map), DRM_MEM_MAPS);
-		}
-	}
-	up(&dev->struct_sem);
-}
-
-/**
- * \c nopage method for DMA virtual memory.
- *
- * \param vma virtual memory area.
- * \param address access address.
- * \return pointer to the page structure.
- * 
- * Determine the page number from the page offset and get it from drm_device_dma::pagelist.
- */
-static __inline__ struct page *DRM(do_vm_dma_nopage)(struct vm_area_struct *vma,
-						     unsigned long address)
-{
-	drm_file_t	 *priv	 = vma->vm_file->private_data;
-	drm_device_t	 *dev	 = priv->dev;
-	drm_device_dma_t *dma	 = dev->dma;
-	unsigned long	 offset;
-	unsigned long	 page_nr;
-	struct page	 *page;
-
-	if (!dma)		   return NOPAGE_SIGBUS; /* Error */
-	if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */
-	if (!dma->pagelist)	   return NOPAGE_OOM ; /* Nothing allocated */
-
-	offset	 = address - vma->vm_start; /* vm_[pg]off[set] should be 0 */
-	page_nr  = offset >> PAGE_SHIFT;
-	page = virt_to_page((dma->pagelist[page_nr] + 
-			     (offset & (~PAGE_MASK))));
-
-	get_page(page);
-
-	DRM_DEBUG("dma_nopage 0x%lx (page %lu)\n", address, page_nr);
-	return page;
-}
-
-/**
- * \c nopage method for scatter-gather virtual memory.
- *
- * \param vma virtual memory area.
- * \param address access address.
- * \return pointer to the page structure.
- * 
- * Determine the map offset from the page offset and get it from drm_sg_mem::pagelist.
- */
-static __inline__ struct page *DRM(do_vm_sg_nopage)(struct vm_area_struct *vma,
-						    unsigned long address)
-{
-	drm_map_t        *map    = (drm_map_t *)vma->vm_private_data;
-	drm_file_t *priv = vma->vm_file->private_data;
-	drm_device_t *dev = priv->dev;
-	drm_sg_mem_t *entry = dev->sg;
-	unsigned long offset;
-	unsigned long map_offset;
-	unsigned long page_offset;
-	struct page *page;
-
-	if (!entry)                return NOPAGE_SIGBUS; /* Error */
-	if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */
-	if (!entry->pagelist)      return NOPAGE_OOM ;  /* Nothing allocated */
-
-
-	offset = address - vma->vm_start;
-	map_offset = map->offset - dev->sg->handle;
-	page_offset = (offset >> PAGE_SHIFT) + (map_offset >> PAGE_SHIFT);
-	page = entry->pagelist[page_offset];
-	get_page(page);
-
-	return page;
-}
-
-
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
-
-static struct page *DRM(vm_nopage)(struct vm_area_struct *vma,
-				   unsigned long address,
-				   int *type) {
-	if (type) *type = VM_FAULT_MINOR;
-	return DRM(do_vm_nopage)(vma, address);
-}
-
-static struct page *DRM(vm_shm_nopage)(struct vm_area_struct *vma,
-				       unsigned long address,
-				       int *type) {
-	if (type) *type = VM_FAULT_MINOR;
-	return DRM(do_vm_shm_nopage)(vma, address);
-}
-
-static struct page *DRM(vm_dma_nopage)(struct vm_area_struct *vma,
-				       unsigned long address,
-				       int *type) {
-	if (type) *type = VM_FAULT_MINOR;
-	return DRM(do_vm_dma_nopage)(vma, address);
-}
-
-static struct page *DRM(vm_sg_nopage)(struct vm_area_struct *vma,
-				      unsigned long address,
-				      int *type) {
-	if (type) *type = VM_FAULT_MINOR;
-	return DRM(do_vm_sg_nopage)(vma, address);
-}
-
-#else	/* LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,0) */
-
-static struct page *DRM(vm_nopage)(struct vm_area_struct *vma,
-				   unsigned long address,
-				   int unused) {
-	return DRM(do_vm_nopage)(vma, address);
-}
-
-static struct page *DRM(vm_shm_nopage)(struct vm_area_struct *vma,
-				       unsigned long address,
-				       int unused) {
-	return DRM(do_vm_shm_nopage)(vma, address);
-}
-
-static struct page *DRM(vm_dma_nopage)(struct vm_area_struct *vma,
-				       unsigned long address,
-				       int unused) {
-	return DRM(do_vm_dma_nopage)(vma, address);
-}
-
-static struct page *DRM(vm_sg_nopage)(struct vm_area_struct *vma,
-				      unsigned long address,
-				      int unused) {
-	return DRM(do_vm_sg_nopage)(vma, address);
-}
-
-#endif
-
-
-/** AGP virtual memory operations */
-static struct vm_operations_struct   DRM(vm_ops) = {
-	.nopage = DRM(vm_nopage),
-	.open	= DRM(vm_open),
-	.close	= DRM(vm_close),
-};
-
-/** Shared virtual memory operations */
-static struct vm_operations_struct   DRM(vm_shm_ops) = {
-	.nopage = DRM(vm_shm_nopage),
-	.open	= DRM(vm_open),
-	.close	= DRM(vm_shm_close),
-};
-
-/** DMA virtual memory operations */
-static struct vm_operations_struct   DRM(vm_dma_ops) = {
-	.nopage = DRM(vm_dma_nopage),
-	.open	= DRM(vm_open),
-	.close	= DRM(vm_close),
-};
-
-/** Scatter-gather virtual memory operations */
-static struct vm_operations_struct   DRM(vm_sg_ops) = {
-	.nopage = DRM(vm_sg_nopage),
-	.open   = DRM(vm_open),
-	.close  = DRM(vm_close),
-};
-
-
-/**
- * \c open method for shared virtual memory.
- * 
- * \param vma virtual memory area.
- * 
- * 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)
-{
-	drm_file_t	*priv	= vma->vm_file->private_data;
-	drm_device_t	*dev	= priv->dev;
-	drm_vma_entry_t *vma_entry;
-
-	DRM_DEBUG("0x%08lx,0x%08lx\n",
-		  vma->vm_start, vma->vm_end - vma->vm_start);
-	atomic_inc(&dev->vma_count);
-
-	vma_entry = DRM(alloc)(sizeof(*vma_entry), DRM_MEM_VMAS);
-	if (vma_entry) {
-		down(&dev->struct_sem);
-		vma_entry->vma	= vma;
-		vma_entry->next = dev->vmalist;
-		vma_entry->pid	= current->pid;
-		dev->vmalist	= vma_entry;
-		up(&dev->struct_sem);
-	}
-}
-
-/**
- * \c close method for all virtual memory types.
- * 
- * \param vma virtual memory area.
- * 
- * 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)
-{
-	drm_file_t	*priv	= vma->vm_file->private_data;
-	drm_device_t	*dev	= priv->dev;
-	drm_vma_entry_t *pt, *prev;
-
-	DRM_DEBUG("0x%08lx,0x%08lx\n",
-		  vma->vm_start, vma->vm_end - vma->vm_start);
-	atomic_dec(&dev->vma_count);
-
-	down(&dev->struct_sem);
-	for (pt = dev->vmalist, prev = NULL; pt; prev = pt, pt = pt->next) {
-		if (pt->vma == vma) {
-			if (prev) {
-				prev->next = pt->next;
-			} else {
-				dev->vmalist = pt->next;
-			}
-			DRM(free)(pt, sizeof(*pt), DRM_MEM_VMAS);
-			break;
-		}
-	}
-	up(&dev->struct_sem);
-}
-
-/**
- * mmap DMA memory.
- *
- * \param filp file pointer.
- * \param vma virtual memory area.
- * \return zero on success or a negative number on failure.
- * 
- * 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)
-{
-	drm_file_t	 *priv	 = filp->private_data;
-	drm_device_t	 *dev;
-	drm_device_dma_t *dma;
-	unsigned long	 length	 = vma->vm_end - vma->vm_start;
-
-	lock_kernel();
-	dev	 = priv->dev;
-	dma	 = dev->dma;
-	DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n",
-		  vma->vm_start, vma->vm_end, VM_OFFSET(vma));
-
-				/* Length must match exact page count */
-	if (!dma || (length >> PAGE_SHIFT) != dma->page_count) {
-		unlock_kernel();
-		return -EINVAL;
-	}
-	unlock_kernel();
-
-	vma->vm_ops   = &DRM(vm_dma_ops);
-
-#if LINUX_VERSION_CODE <= 0x02040e /* KERNEL_VERSION(2,4,14) */
-	vma->vm_flags |= VM_LOCKED | VM_SHM; /* Don't swap */
-#else
-	vma->vm_flags |= VM_RESERVED; /* Don't swap */
-#endif
-
-	vma->vm_file  =	 filp;	/* Needed for drm_vm_open() */
-	DRM(vm_open)(vma);
-	return 0;
-}
-
-unsigned long DRM(core_get_map_ofs)(drm_map_t *map)
-{
-	return map->offset;
-}
-
-unsigned long DRM(core_get_reg_ofs)(struct drm_device *dev)
-{
-#ifdef __alpha__
-	return dev->hose->dense_mem_base - dev->hose->mem_space->start;
-#else
-	return 0;
-#endif
-}
-
-/**
- * mmap DMA memory.
- *
- * \param filp file pointer.
- * \param vma virtual memory area.
- * \return zero on success or a negative number on failure.
- * 
- * If the virtual memory area has no offset associated with it then it's a DMA
- * area, so calls mmap_dma(). Otherwise searches the map in drm_device::maplist,
- * checks that the restricted flag is not set, sets the virtual memory operations
- * according to the mapping type and remaps the pages. Finally sets the file
- * pointer and calls vm_open().
- */
-int DRM(mmap)(struct file *filp, struct vm_area_struct *vma)
-{
-	drm_file_t	*priv	= filp->private_data;
-	drm_device_t	*dev	= priv->dev;
-	drm_map_t	*map	= NULL;
-	drm_map_list_t  *r_list;
-	unsigned long   offset  = 0;
-	struct list_head *list;
-
-	DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n",
-		  vma->vm_start, vma->vm_end, VM_OFFSET(vma));
-
-	if ( !priv->authenticated ) return -EACCES;
-
-	/* We check for "dma". On Apple's UniNorth, it's valid to have
-	 * the AGP mapped at physical address 0
-	 * --BenH.
-	 */
-	if (!VM_OFFSET(vma)
-#if __OS_HAS_AGP
-	    && (!dev->agp || dev->agp->agp_info.device->vendor != PCI_VENDOR_ID_APPLE)
-#endif
-	    )
-		return DRM(mmap_dma)(filp, vma);
-
-				/* A sequential search of a linked list is
-				   fine here because: 1) there will only be
-				   about 5-10 entries in the list and, 2) a
-				   DRI client only has to do this mapping
-				   once, so it doesn't have to be optimized
-				   for performance, even if the list was a
-				   bit longer. */
-	list_for_each(list, &dev->maplist->head) {
-		unsigned long off;
-
-		r_list = list_entry(list, drm_map_list_t, head);
-		map = r_list->map;
-		if (!map) continue;
-		off = dev->fn_tbl.get_map_ofs(map);
-		if (off == VM_OFFSET(vma)) break;
-	}
-
-	if (!map || ((map->flags&_DRM_RESTRICTED) && !capable(CAP_SYS_ADMIN)))
-		return -EPERM;
-
-				/* Check for valid size. */
-	if (map->size != vma->vm_end - vma->vm_start) return -EINVAL;
-
-	if (!capable(CAP_SYS_ADMIN) && (map->flags & _DRM_READ_ONLY)) {
-		vma->vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
-#if defined(__i386__) || defined(__x86_64__)
-		pgprot_val(vma->vm_page_prot) &= ~_PAGE_RW;
-#else
-				/* Ye gads this is ugly.  With more thought
-                                   we could move this up higher and use
-                                   `protection_map' instead.  */
-		vma->vm_page_prot = __pgprot(pte_val(pte_wrprotect(
-			__pte(pgprot_val(vma->vm_page_prot)))));
-#endif
-	}
-
-	switch (map->type) {
-        case _DRM_AGP:
-	  if (drm_core_has_AGP(dev) && dev->agp->cant_use_aperture) {
-                /*
-                 * On some platforms we can't talk to bus dma address from the CPU, so for
-                 * memory of type DRM_AGP, we'll deal with sorting out the real physical
-                 * pages and mappings in nopage()
-                 */
-#if defined(__powerpc__)
-		pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE;
-#endif
-                vma->vm_ops = &DRM(vm_ops);
-                break;
-	  }
-                /* fall through to _DRM_FRAME_BUFFER... */        
-	case _DRM_FRAME_BUFFER:
-	case _DRM_REGISTERS:
-		if (VM_OFFSET(vma) >= __pa(high_memory)) {
-#if defined(__i386__) || defined(__x86_64__)
-			if (boot_cpu_data.x86 > 3 && map->type != _DRM_AGP) {
-				pgprot_val(vma->vm_page_prot) |= _PAGE_PCD;
-				pgprot_val(vma->vm_page_prot) &= ~_PAGE_PWT;
-			}
-#elif defined(__powerpc__)
-			pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE | _PAGE_GUARDED;
-#endif
-			vma->vm_flags |= VM_IO;	/* not in core dump */
-		}
-#if defined(__ia64__)
-		if (map->type != _DRM_AGP)
-			vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
-#endif
-		offset = dev->fn_tbl.get_reg_ofs(dev);
-#ifdef __sparc__
-		if (io_remap_page_range(DRM_RPR_ARG(vma) vma->vm_start,
-					VM_OFFSET(vma) + offset,
-					vma->vm_end - vma->vm_start,
-					vma->vm_page_prot, 0))
-#else
-		if (remap_pfn_range(DRM_RPR_ARG(vma) vma->vm_start,
-				     (VM_OFFSET(vma) + offset) >> PAGE_SHIFT,
-				     vma->vm_end - vma->vm_start,
-				     vma->vm_page_prot))
-#endif
-				return -EAGAIN;
-		DRM_DEBUG("   Type = %d; start = 0x%lx, end = 0x%lx,"
-			  " offset = 0x%lx\n",
-			  map->type,
-			  vma->vm_start, vma->vm_end, VM_OFFSET(vma) + offset);
-		vma->vm_ops = &DRM(vm_ops);
-		break;
-	case _DRM_SHM:
-		vma->vm_ops = &DRM(vm_shm_ops);
-		vma->vm_private_data = (void *)map;
-				/* Don't let this area swap.  Change when
-				   DRM_KERNEL advisory is supported. */
-#if LINUX_VERSION_CODE <= 0x02040e /* KERNEL_VERSION(2,4,14) */
-		vma->vm_flags |= VM_LOCKED;
-#else
-		vma->vm_flags |= VM_RESERVED;
-#endif
-		break;
-	case _DRM_SCATTER_GATHER:
-		vma->vm_ops = &DRM(vm_sg_ops);
-		vma->vm_private_data = (void *)map;
-#if LINUX_VERSION_CODE <= 0x02040e /* KERNEL_VERSION(2,4,14) */
-		vma->vm_flags |= VM_LOCKED;
-#else
-		vma->vm_flags |= VM_RESERVED;
-#endif
-                break;
-	default:
-		return -EINVAL;	/* This should never happen. */
-	}
-#if LINUX_VERSION_CODE <= 0x02040e /* KERNEL_VERSION(2,4,14) */
-	vma->vm_flags |= VM_LOCKED | VM_SHM; /* Don't swap */
-#else
-	vma->vm_flags |= VM_RESERVED; /* Don't swap */
-#endif
-
-	vma->vm_file  =	 filp;	/* Needed for drm_vm_open() */
-	DRM(vm_open)(vma);
-	return 0;
-}
diff -Nru a/drivers/char/drm/ffb.h b/drivers/char/drm/ffb.h
--- a/drivers/char/drm/ffb.h	2005-03-01 23:38:58 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,12 +0,0 @@
-/* ffb.h -- ffb DRM template customization -*- linux-c -*-
- */
-
-#ifndef __FFB_H__
-#define __FFB_H__
-
-/* This remains constant for all DRM template files.
- */
-#define DRM(x) ffb_##x
-
-#endif
-
diff -Nru a/drivers/char/drm/ffb_drv.c b/drivers/char/drm/ffb_drv.c
--- a/drivers/char/drm/ffb_drv.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/char/drm/ffb_drv.c	2005-03-01 23:39:18 -08:00
@@ -210,32 +210,17 @@
 	return addr;
 }
 
-#include "drm_core.h"
-
-/* This functions must be here since it references DRM(numdevs)
- * which drm_drv.h declares.
- */
 static int ffb_presetup(drm_device_t *dev)
 {
 	ffb_dev_priv_t	*ffb_priv;
-	drm_device_t *temp_dev;
 	int ret = 0;
-	int i;
+	int i = 0;
 
 	/* Check for the case where no device was found. */
 	if (ffb_position == NULL)
 		return -ENODEV;
 
-	/* Find our instance number by finding our device in dev structure */
-	for (i = 0; i < DRM(numdevs); i++) {
-		temp_dev = &(DRM(device)[i]);
-		if(temp_dev == dev)
-			break;
-	}
-
-	if (i == DRM(numdevs))
-		return -ENODEV;
-
+	/* code used to use numdevs no numdevs anymore */
 	ffb_priv = kmalloc(sizeof(ffb_dev_priv_t), GFP_KERNEL);
 	if (!ffb_priv)
 		return -ENOMEM;
@@ -307,16 +292,74 @@
        return 0;
 }
 
-void ffb_driver_register_fns(drm_device_t *dev)
+static int postinit( struct drm_device *dev, unsigned long flags ) 
 {
-	ffb_set_context_ioctls();
-	DRM(fops).get_unmapped_area = ffb_get_unmapped_area;
-	dev->fn_tbl.release = ffb_driver_release;
-	dev->fn_tbl.presetup = ffb_presetup;
-	dev->fn_tbl.pretakedown = ffb_driver_pretakedown;
-	dev->fn_tbl.postcleanup = ffb_driver_postcleanup;
-	dev->fn_tbl.kernel_context_switch = ffb_context_switch;
-	dev->fn_tbl.kernel_context_switch_unlock = ffb_driver_kernel_context_switch_unlock;
-	dev->fn_tbl.get_map_ofs = ffb_driver_get_map_ofs;
-	dev->fn_tbl.get_reg_ofs = ffb_driver_get_reg_ofs;
+	DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d\n",
+		DRIVER_NAME,
+		DRIVER_MAJOR,
+		DRIVER_MINOR,
+		DRIVER_PATCHLEVEL,
+		DRIVER_DATE,
+		dev->minor
+		);
+	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 drm_ioctl_desc_t ioctls[] = {
+	
+};
+
+static struct drm_driver driver = {
+	.driver_features = 0,
+	.dev_priv_size = sizeof(u32),
+	.release = ffb_driver_release,
+	.presetup = ffb_presetup,
+	.pretakedown = ffb_driver_pretakedown,
+	.postcleanup = ffb_driver_postcleanup,
+	.kernel_context_switch = ffb_driver_context_switch,
+	.kernel_context_switch_unlock = ffb_driver_kernel_context_switch_unlock,
+	.get_map_ofs = ffb_driver_get_map_ofs,
+	.get_reg_ofs = ffb_driver_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,
+	},
+};
+
+static int __init ffb_init(void)
+{
+	return -ENODEV;
+}
+
+static void __exit ffb_exit(void)
+{
+}
+
+module_init(ffb_init);
+module_exit(ffb_exit);
+
+MODULE_AUTHOR( DRIVER_AUTHOR );
+MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_LICENSE("GPL and additional rights");
diff -Nru a/drivers/char/drm/ffb_drv.h b/drivers/char/drm/ffb_drv.h
--- a/drivers/char/drm/ffb_drv.h	2005-03-01 23:38:53 -08:00
+++ b/drivers/char/drm/ffb_drv.h	2005-03-01 23:38:53 -08:00
@@ -275,7 +275,6 @@
 	struct ffb_hw_context	*hw_state[FFB_MAX_CTXS];
 } ffb_dev_priv_t;
 
-extern struct file_operations DRM(fops);
 extern unsigned long ffb_get_unmapped_area(struct file *filp,
 					   unsigned long hint,
 					   unsigned long len,
@@ -284,3 +283,4 @@
 extern void ffb_set_context_ioctls(void);
 extern drm_ioctl_desc_t DRM(ioctls)[];
 
+extern int ffb_driver_context_switch(drm_device_t *dev, int old, int new);
diff -Nru a/drivers/char/drm/gamma.h b/drivers/char/drm/gamma.h
--- a/drivers/char/drm/gamma.h	2005-03-01 23:38:44 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,77 +0,0 @@
-/* gamma.c -- 3dlabs GMX 2000 driver -*- linux-c -*-
- * Created: Mon Jan  4 08:58:31 1999 by gareth@valinux.com
- *
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- *    Gareth Hughes <gareth@valinux.com>
- */
-
-#ifndef __GAMMA_H__
-#define __GAMMA_H__
-
-/* This remains constant for all DRM template files.
- */
-#define DRM(x) gamma_##x
-
-/* General customization:
- */
-#define DRIVER_AUTHOR		"VA Linux Systems Inc."
-
-#define DRIVER_NAME		"gamma"
-#define DRIVER_DESC		"3DLabs gamma"
-#define DRIVER_DATE		"20010624"
-
-#define DRIVER_MAJOR		2
-#define DRIVER_MINOR		0
-#define DRIVER_PATCHLEVEL	0
-
-#define DRIVER_IOCTLS							  \
-	[DRM_IOCTL_NR(DRM_IOCTL_DMA)]	     = { gamma_dma,	  1, 0 }, \
-	[DRM_IOCTL_NR(DRM_IOCTL_GAMMA_INIT)] = { gamma_dma_init,  1, 1 }, \
-	[DRM_IOCTL_NR(DRM_IOCTL_GAMMA_COPY)] = { gamma_dma_copy,  1, 1 }
-
-#define IOCTL_TABLE_NAME	DRM(ioctls)
-#define IOCTL_FUNC_NAME 	DRM(ioctl)
-
-#define __HAVE_COUNTERS		5
-#define __HAVE_COUNTER6		_DRM_STAT_IRQ
-#define __HAVE_COUNTER7		_DRM_STAT_DMA
-#define __HAVE_COUNTER8		_DRM_STAT_PRIMARY
-#define __HAVE_COUNTER9		_DRM_STAT_SPECIAL
-#define __HAVE_COUNTER10	_DRM_STAT_MISSED
-
-/* Driver customization:
- */
-#define DRIVER_PRETAKEDOWN() do {					\
-	gamma_do_cleanup_dma( dev );					\
-} while (0)
-
-/* DMA customization:
- */
-#define __HAVE_MULTIPLE_DMA_QUEUES	1
-#define __HAVE_DMA_WAITQUEUE		1
-
-/* removed from DRM HAVE_DMA_FREELIST & HAVE_DMA_SCHEDULE */
-
-#endif /* __GAMMA_H__ */
diff -Nru a/drivers/char/drm/gamma_dma.c b/drivers/char/drm/gamma_dma.c
--- a/drivers/char/drm/gamma_dma.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/char/drm/gamma_dma.c	2005-03-01 23:39:16 -08:00
@@ -937,10 +937,10 @@
 	dev->driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ;
 	DRM(fops).read = gamma_fops_read;
 	DRM(fops).poll = gamma_fops_poll;
-	dev->fn_tbl.preinit = gamma_driver_preinit;
-	dev->fn_tbl.pretakedown = gamma_driver_pretakedown;
-	dev->fn_tbl.dma_ready = gamma_driver_dma_ready;
-	dev->fn_tbl.dma_quiescent = gamma_driver_dma_quiescent;
-	dev->fn_tbl.dma_flush_block_and_flush = gamma_flush_block_and_flush;
-	dev->fn_tbl.dma_flush_unblock = gamma_flush_unblock;
+	dev->driver.preinit = gamma_driver_preinit;
+	dev->driver.pretakedown = gamma_driver_pretakedown;
+	dev->driver.dma_ready = gamma_driver_dma_ready;
+	dev->driver.dma_quiescent = gamma_driver_dma_quiescent;
+	dev->driver.dma_flush_block_and_flush = gamma_flush_block_and_flush;
+	dev->driver.dma_flush_unblock = gamma_flush_unblock;
 }
diff -Nru a/drivers/char/drm/gamma_lists.h b/drivers/char/drm/gamma_lists.h
--- a/drivers/char/drm/gamma_lists.h	2005-03-01 23:38:54 -08:00
+++ b/drivers/char/drm/gamma_lists.h	2005-03-01 23:38:54 -08:00
@@ -45,8 +45,8 @@
 	bl->rp	       = bl->bufs;
 	bl->wp	       = bl->bufs;
 	bl->end	       = &bl->bufs[bl->count+1];
-	bl->write_lock = SPIN_LOCK_UNLOCKED;
-	bl->read_lock  = SPIN_LOCK_UNLOCKED;
+	spin_lock_init(&bl->write_lock);
+	spin_lock_init(&bl->read_lock);
 	return 0;
 }
 
@@ -110,7 +110,7 @@
 	bl->low_mark  = 0;
 	bl->high_mark = 0;
 	atomic_set(&bl->wfh,   0);
-	bl->lock      = SPIN_LOCK_UNLOCKED;
+	spin_lock_init(&bl->lock);
 	++bl->initialized;
 	return 0;
 }
diff -Nru a/drivers/char/drm/i810.h b/drivers/char/drm/i810.h
--- a/drivers/char/drm/i810.h	2005-03-01 23:38:55 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,77 +0,0 @@
-/* i810.h -- Intel i810/i815 DRM template customization -*- linux-c -*-
- * Created: Thu Feb 15 00:01:12 2001 by gareth@valinux.com
- *
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- *    Gareth Hughes <gareth@valinux.com>
- */
-
-#ifndef __I810_H__
-#define __I810_H__
-
-/* This remains constant for all DRM template files.
- */
-#define DRM(x) i810_##x
-
-/* General customization:
- */
-
-#define DRIVER_AUTHOR		"VA Linux Systems Inc."
-
-#define DRIVER_NAME		"i810"
-#define DRIVER_DESC		"Intel i810"
-#define DRIVER_DATE		"20030605"
-
-/* Interface history
- *
- * 1.1   - XFree86 4.1
- * 1.2   - XvMC interfaces
- *       - XFree86 4.2
- * 1.2.1 - Disable copying code (leave stub ioctls for backwards compatibility)
- *       - Remove requirement for interrupt (leave stubs again)
- * 1.3   - Add page flipping.
- * 1.4   - fix DRM interface
- */
-#define DRIVER_MAJOR		1
-#define DRIVER_MINOR		4
-#define DRIVER_PATCHLEVEL	0
-
-#define DRIVER_IOCTLS							    \
-	[DRM_IOCTL_NR(DRM_IOCTL_I810_INIT)]   = { i810_dma_init,    1, 1 }, \
-   	[DRM_IOCTL_NR(DRM_IOCTL_I810_VERTEX)] = { i810_dma_vertex,  1, 0 }, \
-   	[DRM_IOCTL_NR(DRM_IOCTL_I810_CLEAR)]  = { i810_clear_bufs,  1, 0 }, \
-      	[DRM_IOCTL_NR(DRM_IOCTL_I810_FLUSH)]  = { i810_flush_ioctl, 1, 0 }, \
-   	[DRM_IOCTL_NR(DRM_IOCTL_I810_GETAGE)] = { i810_getage,      1, 0 }, \
-	[DRM_IOCTL_NR(DRM_IOCTL_I810_GETBUF)] = { i810_getbuf,      1, 0 }, \
-   	[DRM_IOCTL_NR(DRM_IOCTL_I810_SWAP)]   = { i810_swap_bufs,   1, 0 }, \
-   	[DRM_IOCTL_NR(DRM_IOCTL_I810_COPY)]   = { i810_copybuf,     1, 0 }, \
-   	[DRM_IOCTL_NR(DRM_IOCTL_I810_DOCOPY)] = { i810_docopy,      1, 0 }, \
-	[DRM_IOCTL_NR(DRM_IOCTL_I810_OV0INFO)] = { i810_ov0_info,   1, 0 }, \
-	[DRM_IOCTL_NR(DRM_IOCTL_I810_FSTATUS)] = { i810_fstatus,    1, 0 }, \
-	[DRM_IOCTL_NR(DRM_IOCTL_I810_OV0FLIP)] = { i810_ov0_flip,   1, 0 }, \
-	[DRM_IOCTL_NR(DRM_IOCTL_I810_MC)]      = { i810_dma_mc,     1, 1 }, \
-	[DRM_IOCTL_NR(DRM_IOCTL_I810_RSTATUS)] = { i810_rstatus,    1, 0 }, \
-	[DRM_IOCTL_NR(DRM_IOCTL_I810_FLIP)] =    { i810_flip_bufs,  1, 0 }
-
-#endif
diff -Nru a/drivers/char/drm/i810_dma.c b/drivers/char/drm/i810_dma.c
--- a/drivers/char/drm/i810_dma.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/char/drm/i810_dma.c	2005-03-01 23:38:55 -08:00
@@ -30,7 +30,6 @@
  *
  */
 
-#include "i810.h"
 #include "drmP.h"
 #include "drm.h"
 #include "i810_drm.h"
@@ -51,23 +50,25 @@
 #define up_write up
 #endif
 
-static inline void i810_print_status_page(drm_device_t *dev)
-{
-   	drm_device_dma_t *dma = dev->dma;
-      	drm_i810_private_t *dev_priv = dev->dev_private;
-	u32 *temp = dev_priv->hw_status_page;
-   	int i;
+drm_ioctl_desc_t i810_ioctls[] = {
+	[DRM_IOCTL_NR(DRM_I810_INIT)]    = { i810_dma_init,    1, 1 },
+	[DRM_IOCTL_NR(DRM_I810_VERTEX)]  = { i810_dma_vertex,  1, 0 },
+	[DRM_IOCTL_NR(DRM_I810_CLEAR)]   = { i810_clear_bufs,  1, 0 },
+	[DRM_IOCTL_NR(DRM_I810_FLUSH)]   = { i810_flush_ioctl, 1, 0 },
+	[DRM_IOCTL_NR(DRM_I810_GETAGE)]  = { i810_getage,      1, 0 },
+	[DRM_IOCTL_NR(DRM_I810_GETBUF)]  = { i810_getbuf,      1, 0 },
+	[DRM_IOCTL_NR(DRM_I810_SWAP)]    = { i810_swap_bufs,   1, 0 },
+	[DRM_IOCTL_NR(DRM_I810_COPY)]    = { i810_copybuf,     1, 0 },
+	[DRM_IOCTL_NR(DRM_I810_DOCOPY)]  = { i810_docopy,      1, 0 },
+	[DRM_IOCTL_NR(DRM_I810_OV0INFO)] = { i810_ov0_info,    1, 0 },
+	[DRM_IOCTL_NR(DRM_I810_FSTATUS)] = { i810_fstatus,     1, 0 },
+	[DRM_IOCTL_NR(DRM_I810_OV0FLIP)] = { i810_ov0_flip,    1, 0 },
+	[DRM_IOCTL_NR(DRM_I810_MC)]      = { i810_dma_mc,      1, 1 },
+	[DRM_IOCTL_NR(DRM_I810_RSTATUS)] = { i810_rstatus,     1, 0 },
+	[DRM_IOCTL_NR(DRM_I810_FLIP)]    = { i810_flip_bufs,   1, 0 }
+};
 
-   	DRM_DEBUG(  "hw_status: Interrupt Status : %x\n", temp[0]);
-   	DRM_DEBUG(  "hw_status: LpRing Head ptr : %x\n", temp[1]);
-   	DRM_DEBUG(  "hw_status: IRing Head ptr : %x\n", temp[2]);
-      	DRM_DEBUG(  "hw_status: Reserved : %x\n", temp[3]);
-	DRM_DEBUG(  "hw_status: Last Render: %x\n", temp[4]);
-   	DRM_DEBUG(  "hw_status: Driver Counter : %d\n", temp[5]);
-   	for(i = 6; i < dma->buf_count + 6; i++) {
-	   	DRM_DEBUG( "buffer status idx : %d used: %d\n", i - 6, temp[i]);
-	}
-}
+int i810_max_ioctl = DRM_ARRAY_SIZE(i810_ioctls);
 
 static drm_buf_t *i810_freelist_get(drm_device_t *dev)
 {
@@ -110,12 +111,12 @@
 }
 
 static struct file_operations i810_buffer_fops = {
-	.open	 = DRM(open),
-	.flush	 = DRM(flush),
-	.release = DRM(release),
-	.ioctl	 = DRM(ioctl),
+	.open	 = drm_open,
+	.flush	 = drm_flush,
+	.release = drm_release,
+	.ioctl	 = drm_ioctl,
 	.mmap	 = i810_mmap_buffers,
-	.fasync  = DRM(fasync),
+	.fasync  = drm_fasync,
 };
 
 int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma)
@@ -237,7 +238,7 @@
 	 * is freed, it's too late.
 	 */
 	if (drm_core_check_feature(dev, DRIVER_HAVE_IRQ) && dev->irq_enabled)
-		DRM(irq_uninstall)(dev);
+		drm_irq_uninstall(dev);
 
 	if (dev->dev_private) {
 		int i;
@@ -245,7 +246,7 @@
 	     		(drm_i810_private_t *) dev->dev_private;
 
 		if (dev_priv->ring.virtual_start) {
-		   	DRM(ioremapfree)((void *) dev_priv->ring.virtual_start,
+		   	drm_ioremapfree((void *) dev_priv->ring.virtual_start,
 					 dev_priv->ring.Size, dev);
 		}
 	   	if (dev_priv->hw_status_page) {
@@ -255,7 +256,7 @@
 		   	/* Need to rewrite hardware status page */
 		   	I810_WRITE(0x02080, 0x1ffff000);
 		}
-	   	DRM(free)(dev->dev_private, sizeof(drm_i810_private_t),
+	   	drm_free(dev->dev_private, sizeof(drm_i810_private_t),
 			 DRM_MEM_DRIVER);
 	   	dev->dev_private = NULL;
 
@@ -263,7 +264,7 @@
 			drm_buf_t *buf = dma->buflist[ i ];
 			drm_i810_buf_priv_t *buf_priv = buf->dev_private;
 			if ( buf_priv->kernel_virtual && buf->total )
-				DRM(ioremapfree)(buf_priv->kernel_virtual, buf->total, dev);
+				drm_ioremapfree(buf_priv->kernel_virtual, buf->total, dev);
 		}
 	}
    	return 0;
@@ -334,7 +335,7 @@
 
 	   	*buf_priv->in_use = I810_BUF_FREE;
 
-		buf_priv->kernel_virtual = DRM(ioremap)(buf->bus_address,
+		buf_priv->kernel_virtual = drm_ioremap(buf->bus_address,
 							buf->total, dev);
 	}
 	return 0;
@@ -386,7 +387,7 @@
    	dev_priv->ring.End = init->ring_end;
    	dev_priv->ring.Size = init->ring_size;
 
-   	dev_priv->ring.virtual_start = DRM(ioremap)(dev->agp->base +
+   	dev_priv->ring.virtual_start = drm_ioremap(dev->agp->base +
 						    init->ring_start,
 						    init->ring_size, dev);
 
@@ -510,7 +511,7 @@
 			if (retcode)
 				return retcode;
 
-	   		dev_priv = DRM(alloc)(sizeof(drm_i810_private_t),
+	   		dev_priv = drm_alloc(sizeof(drm_i810_private_t),
 					     DRM_MEM_DRIVER);
 	   		if (dev_priv == NULL)
 				return -ENOMEM;
@@ -524,7 +525,7 @@
 					  sizeof(drm_i810_init_t))) {
 				return -EFAULT;
 			}
-	   		dev_priv = DRM(alloc)(sizeof(drm_i810_private_t),
+	   		dev_priv = drm_alloc(sizeof(drm_i810_private_t),
 					     DRM_MEM_DRIVER);
 			if (dev_priv == NULL) 
 				return -ENOMEM;
@@ -995,10 +996,8 @@
 }
 
 /* Must be called with the lock held */
-void i810_reclaim_buffers(struct file *filp)
+void i810_reclaim_buffers(drm_device_t *dev, struct file *filp)
 {
-	drm_file_t    *priv   = filp->private_data;
-	drm_device_t  *dev    = priv->dev;
 	drm_device_dma_t *dma = dev->dma;
 	int		 i;
 
@@ -1030,10 +1029,7 @@
    	drm_file_t	  *priv	  = filp->private_data;
    	drm_device_t	  *dev	  = priv->dev;
 
-	if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
-		DRM_ERROR("i810_flush_ioctl called without lock held\n");
-		return -EINVAL;
-	}
+	LOCK_TEST_WITH_RETURN(dev, filp);
 
    	i810_flush_queue(dev);
    	return 0;
@@ -1055,10 +1051,7 @@
 	if (copy_from_user(&vertex, (drm_i810_vertex_t __user *)arg, sizeof(vertex)))
 		return -EFAULT;
 
-	if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
-		DRM_ERROR("i810_dma_vertex called without lock held\n");
-		return -EINVAL;
-	}
+	LOCK_TEST_WITH_RETURN(dev, filp);
 
 	DRM_DEBUG("i810 dma vertex, idx %d used %d discard %d\n",
 		  vertex.idx, vertex.used, vertex.discard);
@@ -1090,10 +1083,7 @@
    	if (copy_from_user(&clear, (drm_i810_clear_t __user *)arg, sizeof(clear)))
 		return -EFAULT;
 
-	if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
-		DRM_ERROR("i810_clear_bufs called without lock held\n");
-		return -EINVAL;
-	}
+	LOCK_TEST_WITH_RETURN(dev, filp);
 
  	/* GH: Someone's doing nasty things... */
  	if (!dev->dev_private) {
@@ -1114,10 +1104,7 @@
 
 	DRM_DEBUG("i810_swap_bufs\n");
 
-	if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
-		DRM_ERROR("i810_swap_buf called without lock held\n");
-		return -EINVAL;
-	}
+	LOCK_TEST_WITH_RETURN(dev, filp);
 
 	i810_dma_dispatch_swap( dev );
    	return 0;
@@ -1152,10 +1139,7 @@
    	if (copy_from_user(&d, (drm_i810_dma_t __user *)arg, sizeof(d)))
 		return -EFAULT;
 
-	if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
-		DRM_ERROR("i810_dma called without lock held\n");
-		return -EINVAL;
-	}
+	LOCK_TEST_WITH_RETURN(dev, filp);
 
 	d.granted = 0;
 
@@ -1265,11 +1249,7 @@
 	if (copy_from_user(&mc, (drm_i810_mc_t __user *)arg, sizeof(mc)))
 		return -EFAULT;
 
-
-	if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
-		DRM_ERROR("i810_dma_mc called without lock held\n");
-		return -EINVAL;
-	}
+	LOCK_TEST_WITH_RETURN(dev, filp);
 
 	if (mc.idx >= dma->buf_count || mc.idx < 0)
 		return -EINVAL;
@@ -1317,10 +1297,8 @@
 	drm_device_t *dev = priv->dev;
 	drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
 
-	if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
-		DRM_ERROR("i810_fstatus called without lock held\n");
-		return -EINVAL;
-	}
+	LOCK_TEST_WITH_RETURN(dev, filp);
+
 	return I810_READ(0x30008);
 }
 
@@ -1331,10 +1309,7 @@
 	drm_device_t *dev = priv->dev;
 	drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
 
-	if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
-		DRM_ERROR("i810_ov0_flip called without lock held\n");
-		return -EINVAL;
-	}
+	LOCK_TEST_WITH_RETURN(dev, filp);
 
 	//Tell the overlay to update
 	I810_WRITE(0x30000,dev_priv->overlay_physical | 0x80000000);
@@ -1376,10 +1351,7 @@
 
 	DRM_DEBUG("%s\n", __FUNCTION__);
 
-	if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
-		DRM_ERROR("i810_flip_buf called without lock held\n");
-		return -EINVAL;
-	}
+	LOCK_TEST_WITH_RETURN(dev, filp);
 
 	if (!dev_priv->page_flipping) 
 		i810_do_init_pageflip( dev );
@@ -1388,35 +1360,20 @@
    	return 0;
 }
 
-static void i810_driver_pretakedown(drm_device_t *dev)
+void i810_driver_pretakedown(drm_device_t *dev)
 {
 	i810_dma_cleanup( dev );
 }
 
-static void i810_driver_release(drm_device_t *dev, struct file *filp)
+void i810_driver_release(drm_device_t *dev, struct file *filp)
 {
-	i810_reclaim_buffers(filp);
+	i810_reclaim_buffers(dev, filp);
 }
 
-static int i810_driver_dma_quiescent(drm_device_t *dev)
+int i810_driver_dma_quiescent(drm_device_t *dev)
 {
 	i810_dma_quiescent( dev );
 	return 0;
 }
 
-void i810_driver_register_fns(drm_device_t *dev)
-{
-	dev->driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_DMA | DRIVER_DMA_QUEUE;
-	dev->dev_priv_size = sizeof(drm_i810_buf_priv_t);
-	dev->fn_tbl.pretakedown = i810_driver_pretakedown;
-	dev->fn_tbl.release = i810_driver_release;
-	dev->fn_tbl.dma_quiescent = i810_driver_dma_quiescent;
-	dev->fn_tbl.reclaim_buffers = i810_reclaim_buffers;
-
-	dev->counters += 4;
-	dev->types[6] = _DRM_STAT_IRQ;
-	dev->types[7] = _DRM_STAT_PRIMARY;
-	dev->types[8] = _DRM_STAT_SECONDARY;
-	dev->types[9] = _DRM_STAT_DMA;
-}
 
diff -Nru a/drivers/char/drm/i810_drm.h b/drivers/char/drm/i810_drm.h
--- a/drivers/char/drm/i810_drm.h	2005-03-01 23:39:18 -08:00
+++ b/drivers/char/drm/i810_drm.h	2005-03-01 23:39:18 -08:00
@@ -199,21 +199,37 @@
 /* i810 specific ioctls
  * The device specific ioctl range is 0x40 to 0x79.
  */
-#define DRM_IOCTL_I810_INIT		DRM_IOW( 0x40, drm_i810_init_t)
-#define DRM_IOCTL_I810_VERTEX		DRM_IOW( 0x41, drm_i810_vertex_t)
-#define DRM_IOCTL_I810_CLEAR		DRM_IOW( 0x42, drm_i810_clear_t)
-#define DRM_IOCTL_I810_FLUSH		DRM_IO(  0x43)
-#define DRM_IOCTL_I810_GETAGE		DRM_IO(  0x44)
-#define DRM_IOCTL_I810_GETBUF		DRM_IOWR(0x45, drm_i810_dma_t)
-#define DRM_IOCTL_I810_SWAP		DRM_IO(  0x46)
-#define DRM_IOCTL_I810_COPY		DRM_IOW( 0x47, drm_i810_copy_t)
-#define DRM_IOCTL_I810_DOCOPY		DRM_IO(  0x48)
-#define DRM_IOCTL_I810_OV0INFO		DRM_IOR( 0x49, drm_i810_overlay_t)
-#define DRM_IOCTL_I810_FSTATUS		DRM_IO ( 0x4a)
-#define DRM_IOCTL_I810_OV0FLIP		DRM_IO ( 0x4b)
-#define DRM_IOCTL_I810_MC		DRM_IOW( 0x4c, drm_i810_mc_t)
-#define DRM_IOCTL_I810_RSTATUS		DRM_IO ( 0x4d )
-#define DRM_IOCTL_I810_FLIP             DRM_IO ( 0x4e )
+#define DRM_I810_INIT		0x00
+#define DRM_I810_VERTEX		0x01
+#define DRM_I810_CLEAR		0x02
+#define DRM_I810_FLUSH		0x03
+#define DRM_I810_GETAGE		0x04
+#define DRM_I810_GETBUF		0x05
+#define DRM_I810_SWAP		0x06
+#define DRM_I810_COPY		0x07
+#define DRM_I810_DOCOPY		0x08
+#define DRM_I810_OV0INFO	0x09
+#define DRM_I810_FSTATUS	0x0a
+#define DRM_I810_OV0FLIP	0x0b
+#define DRM_I810_MC		0x0c
+#define DRM_I810_RSTATUS	0x0d
+#define DRM_I810_FLIP		0x0e
+
+#define DRM_IOCTL_I810_INIT		DRM_IOW( DRM_COMMAND_BASE + DRM_I810_INIT, drm_i810_init_t)
+#define DRM_IOCTL_I810_VERTEX		DRM_IOW( DRM_COMMAND_BASE + DRM_I810_VERTEX, drm_i810_vertex_t)
+#define DRM_IOCTL_I810_CLEAR		DRM_IOW( DRM_COMMAND_BASE + DRM_I810_CLEAR, drm_i810_clear_t)
+#define DRM_IOCTL_I810_FLUSH		DRM_IO(  DRM_COMMAND_BASE + DRM_I810_FLUSH)
+#define DRM_IOCTL_I810_GETAGE		DRM_IO(  DRM_COMMAND_BASE + DRM_I810_GETAGE)
+#define DRM_IOCTL_I810_GETBUF		DRM_IOWR(DRM_COMMAND_BASE + DRM_I810_GETBUF, drm_i810_dma_t)
+#define DRM_IOCTL_I810_SWAP		DRM_IO(  DRM_COMMAND_BASE + DRM_I810_SWAP)
+#define DRM_IOCTL_I810_COPY		DRM_IOW( DRM_COMMAND_BASE + DRM_I810_COPY, drm_i810_copy_t)
+#define DRM_IOCTL_I810_DOCOPY		DRM_IO(  DRM_COMMAND_BASE + DRM_I810_DOCOPY)
+#define DRM_IOCTL_I810_OV0INFO		DRM_IOR( DRM_COMMAND_BASE + DRM_I810_OV0INFO, drm_i810_overlay_t)
+#define DRM_IOCTL_I810_FSTATUS		DRM_IO ( DRM_COMMAND_BASE + DRM_I810_FSTATUS)
+#define DRM_IOCTL_I810_OV0FLIP		DRM_IO ( DRM_COMMAND_BASE + DRM_I810_OV0FLIP)
+#define DRM_IOCTL_I810_MC		DRM_IOW( DRM_COMMAND_BASE + DRM_I810_MC, drm_i810_mc_t)
+#define DRM_IOCTL_I810_RSTATUS		DRM_IO ( DRM_COMMAND_BASE + DRM_I810_RSTATUS)
+#define DRM_IOCTL_I810_FLIP             DRM_IO ( DRM_COMMAND_BASE + DRM_I810_FLIP)
 
 typedef struct _drm_i810_clear {
 	int clear_color;
diff -Nru a/drivers/char/drm/i810_drv.c b/drivers/char/drm/i810_drv.c
--- a/drivers/char/drm/i810_drv.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/char/drm/i810_drv.c	2005-03-01 23:39:17 -08:00
@@ -31,10 +31,95 @@
  */
 
 #include <linux/config.h>
-#include "i810.h"
 #include "drmP.h"
 #include "drm.h"
 #include "i810_drm.h"
 #include "i810_drv.h"
 
-#include "drm_core.h"
+#include "drm_pciids.h"
+
+static int postinit( struct drm_device *dev, unsigned long flags )
+{
+	/* i810 has 4 more counters */
+	dev->counters += 4;
+	dev->types[6] = _DRM_STAT_IRQ;
+	dev->types[7] = _DRM_STAT_PRIMARY;
+	dev->types[8] = _DRM_STAT_SECONDARY;
+	dev->types[9] = _DRM_STAT_DMA;
+	
+	DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d: %s\n",
+		DRIVER_NAME,
+		DRIVER_MAJOR,
+		DRIVER_MINOR,
+		DRIVER_PATCHLEVEL,
+		DRIVER_DATE,
+		dev->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[] = {
+	i810_PCI_IDS
+};
+
+extern drm_ioctl_desc_t i810_ioctls[];
+extern int i810_max_ioctl;
+
+static struct drm_driver driver = {
+	.driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_DMA | DRIVER_DMA_QUEUE,
+	.dev_priv_size = sizeof(drm_i810_buf_priv_t),
+	.pretakedown = i810_driver_pretakedown,
+	.release = i810_driver_release,
+	.dma_quiescent = i810_driver_dma_quiescent,
+	.reclaim_buffers = i810_reclaim_buffers,
+	.get_map_ofs = drm_core_get_map_ofs,
+	.get_reg_ofs = drm_core_get_reg_ofs,
+	.postinit = postinit,
+	.version = version,
+	.ioctls = i810_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 i810_init(void)
+{
+	driver.num_ioctls = i810_max_ioctl;
+	return drm_init(&driver);
+}
+
+static void __exit i810_exit(void)
+{
+	drm_exit(&driver);
+}
+
+module_init(i810_init);
+module_exit(i810_exit);
+
+MODULE_AUTHOR( DRIVER_AUTHOR );
+MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_LICENSE("GPL and additional rights");
diff -Nru a/drivers/char/drm/i810_drv.h b/drivers/char/drm/i810_drv.h
--- a/drivers/char/drm/i810_drv.h	2005-03-01 23:39:16 -08:00
+++ b/drivers/char/drm/i810_drv.h	2005-03-01 23:39:16 -08:00
@@ -32,6 +32,29 @@
 #ifndef _I810_DRV_H_
 #define _I810_DRV_H_
 
+/* General customization:
+ */
+
+#define DRIVER_AUTHOR		"VA Linux Systems Inc."
+
+#define DRIVER_NAME		"i810"
+#define DRIVER_DESC		"Intel i810"
+#define DRIVER_DATE		"20030605"
+
+/* Interface history
+ *
+ * 1.1   - XFree86 4.1
+ * 1.2   - XvMC interfaces
+ *       - XFree86 4.2
+ * 1.2.1 - Disable copying code (leave stub ioctls for backwards compatibility)
+ *       - Remove requirement for interrupt (leave stubs again)
+ * 1.3   - Add page flipping.
+ * 1.4   - fix DRM interface
+ */
+#define DRIVER_MAJOR		1
+#define DRIVER_MINOR		4
+#define DRIVER_PATCHLEVEL	0
+
 typedef struct drm_i810_buf_priv {
    	u32 *in_use;
    	int my_use_idx;
@@ -99,7 +122,7 @@
 extern int  i810_dma_cleanup(drm_device_t *dev);
 extern int  i810_flush_ioctl(struct inode *inode, struct file *filp,
 			     unsigned int cmd, unsigned long arg);
-extern void i810_reclaim_buffers(struct file *filp);
+extern void i810_reclaim_buffers(drm_device_t *dev, struct file *filp);
 extern int  i810_getage(struct inode *inode, struct file *filp,
 			unsigned int cmd, unsigned long arg);
 extern int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma);
@@ -127,17 +150,21 @@
 
 extern void i810_dma_quiescent(drm_device_t *dev);
 
-int i810_dma_vertex(struct inode *inode, struct file *filp,
+extern int i810_dma_vertex(struct inode *inode, struct file *filp,
 		    unsigned int cmd, unsigned long arg);
 
-int i810_swap_bufs(struct inode *inode, struct file *filp,
+extern int i810_swap_bufs(struct inode *inode, struct file *filp,
 		   unsigned int cmd, unsigned long arg);
 
-int i810_clear_bufs(struct inode *inode, struct file *filp,
+extern int i810_clear_bufs(struct inode *inode, struct file *filp,
 		    unsigned int cmd, unsigned long arg);
 
-int i810_flip_bufs(struct inode *inode, struct file *filp,
+extern int i810_flip_bufs(struct inode *inode, struct file *filp,
 		   unsigned int cmd, unsigned long arg);
+
+extern int i810_driver_dma_quiescent(drm_device_t *dev);
+extern void i810_driver_release(drm_device_t *dev, struct file *filp);
+extern void i810_driver_pretakedown(drm_device_t *dev);
 
 #define I810_BASE(reg)		((unsigned long) \
 				dev_priv->mmio_map->handle)
diff -Nru a/drivers/char/drm/i830.h b/drivers/char/drm/i830.h
--- a/drivers/char/drm/i830.h	2005-03-01 23:38:54 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,83 +0,0 @@
-/* i830.h -- Intel I830 DRM template customization -*- linux-c -*-
- * Created: Thu Feb 15 00:01:12 2001 by gareth@valinux.com
- *
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- *    Gareth Hughes <gareth@valinux.com>
- */
-
-#ifndef __I830_H__
-#define __I830_H__
-
-/* This remains constant for all DRM template files.
- */
-#define DRM(x) i830_##x
-
-/* General customization:
- */
-
-#define DRIVER_AUTHOR		"VA Linux Systems Inc."
-
-#define DRIVER_NAME		"i830"
-#define DRIVER_DESC		"Intel 830M"
-#define DRIVER_DATE		"20021108"
-
-/* Interface history:
- *
- * 1.1: Original.
- * 1.2: ?
- * 1.3: New irq emit/wait ioctls.
- *      New pageflip ioctl.
- *      New getparam ioctl.
- *      State for texunits 3&4 in sarea.
- *      New (alternative) layout for texture state.
- */
-#define DRIVER_MAJOR		1
-#define DRIVER_MINOR		3
-#define DRIVER_PATCHLEVEL	2
-
-#define DRIVER_IOCTLS							    \
-	[DRM_IOCTL_NR(DRM_IOCTL_I830_INIT)]   = { i830_dma_init,    1, 1 }, \
-	[DRM_IOCTL_NR(DRM_IOCTL_I830_VERTEX)] = { i830_dma_vertex,  1, 0 }, \
-	[DRM_IOCTL_NR(DRM_IOCTL_I830_CLEAR)]  = { i830_clear_bufs,  1, 0 }, \
-	[DRM_IOCTL_NR(DRM_IOCTL_I830_FLUSH)]  = { i830_flush_ioctl, 1, 0 }, \
-	[DRM_IOCTL_NR(DRM_IOCTL_I830_GETAGE)] = { i830_getage,      1, 0 }, \
-	[DRM_IOCTL_NR(DRM_IOCTL_I830_GETBUF)] = { i830_getbuf,      1, 0 }, \
-	[DRM_IOCTL_NR(DRM_IOCTL_I830_SWAP)]   = { i830_swap_bufs,   1, 0 }, \
-	[DRM_IOCTL_NR(DRM_IOCTL_I830_COPY)]   = { i830_copybuf,     1, 0 }, \
-	[DRM_IOCTL_NR(DRM_IOCTL_I830_DOCOPY)] = { i830_docopy,      1, 0 }, \
-	[DRM_IOCTL_NR(DRM_IOCTL_I830_FLIP)]   = { i830_flip_bufs,   1, 0 }, \
-	[DRM_IOCTL_NR(DRM_IOCTL_I830_IRQ_EMIT)] = { i830_irq_emit,  1, 0 }, \
-	[DRM_IOCTL_NR(DRM_IOCTL_I830_IRQ_WAIT)] = { i830_irq_wait,  1, 0 }, \
-	[DRM_IOCTL_NR(DRM_IOCTL_I830_GETPARAM)] = { i830_getparam,  1, 0 }, \
-	[DRM_IOCTL_NR(DRM_IOCTL_I830_SETPARAM)] = { i830_setparam,  1, 0 } 
-
-/* Driver will work either way: IRQ's save cpu time when waiting for
- * the card, but are subject to subtle interactions between bios,
- * hardware and the driver.
- */
-/* XXX: Add vblank support? */
-#define USE_IRQS 0
-
-#endif
diff -Nru a/drivers/char/drm/i830_dma.c b/drivers/char/drm/i830_dma.c
--- a/drivers/char/drm/i830_dma.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/char/drm/i830_dma.c	2005-03-01 23:38:52 -08:00
@@ -31,7 +31,6 @@
  *
  */
 
-#include "i830.h"
 #include "drmP.h"
 #include "drm.h"
 #include "i830_drm.h"
@@ -53,6 +52,25 @@
 #define up_write up
 #endif
 
+drm_ioctl_desc_t i830_ioctls[] = {
+	[DRM_IOCTL_NR(DRM_I830_INIT)]     = { i830_dma_init,    1, 1 },
+	[DRM_IOCTL_NR(DRM_I830_VERTEX)]   = { i830_dma_vertex,  1, 0 },
+	[DRM_IOCTL_NR(DRM_I830_CLEAR)]    = { i830_clear_bufs,  1, 0 },
+	[DRM_IOCTL_NR(DRM_I830_FLUSH)]    = { i830_flush_ioctl, 1, 0 },
+	[DRM_IOCTL_NR(DRM_I830_GETAGE)]   = { i830_getage,      1, 0 },
+	[DRM_IOCTL_NR(DRM_I830_GETBUF)]   = { i830_getbuf,      1, 0 },
+	[DRM_IOCTL_NR(DRM_I830_SWAP)]     = { i830_swap_bufs,   1, 0 },
+	[DRM_IOCTL_NR(DRM_I830_COPY)]     = { i830_copybuf,     1, 0 },
+	[DRM_IOCTL_NR(DRM_I830_DOCOPY)]   = { i830_docopy,      1, 0 },
+	[DRM_IOCTL_NR(DRM_I830_FLIP)]     = { i830_flip_bufs,   1, 0 },
+	[DRM_IOCTL_NR(DRM_I830_IRQ_EMIT)] = { i830_irq_emit,    1, 0 },
+	[DRM_IOCTL_NR(DRM_I830_IRQ_WAIT)] = { i830_irq_wait,    1, 0 },
+	[DRM_IOCTL_NR(DRM_I830_GETPARAM)] = { i830_getparam,    1, 0 },
+	[DRM_IOCTL_NR(DRM_I830_SETPARAM)] = { i830_setparam,    1, 0 } 
+};
+
+int i830_max_ioctl = DRM_ARRAY_SIZE(i830_ioctls);
+
 static inline void i830_print_status_page(drm_device_t *dev)
 {
    	drm_device_dma_t *dma = dev->dma;
@@ -111,12 +129,12 @@
 }
 
 static struct file_operations i830_buffer_fops = {
-	.open	 = DRM(open),
-	.flush	 = DRM(flush),
-	.release = DRM(release),
-	.ioctl	 = DRM(ioctl),
+	.open	 = drm_open,
+	.flush	 = drm_flush,
+	.release = drm_release,
+	.ioctl	 = drm_ioctl,
 	.mmap	 = i830_mmap_buffers,
-	.fasync  = DRM(fasync),
+	.fasync  = drm_fasync,
 };
 
 int i830_mmap_buffers(struct file *filp, struct vm_area_struct *vma)
@@ -237,7 +255,7 @@
 	 * may not have been called from userspace and after dev_private
 	 * is freed, it's too late.
 	 */
-	if ( dev->irq_enabled ) DRM(irq_uninstall)(dev);
+	if ( dev->irq_enabled ) drm_irq_uninstall(dev);
 
 	if (dev->dev_private) {
 		int i;
@@ -245,7 +263,7 @@
 	     		(drm_i830_private_t *) dev->dev_private;
 	   
 	   	if (dev_priv->ring.virtual_start) {
-		   	DRM(ioremapfree)((void *) dev_priv->ring.virtual_start,
+		   	drm_ioremapfree((void *) dev_priv->ring.virtual_start,
 					 dev_priv->ring.Size, dev);
 		}
 	   	if (dev_priv->hw_status_page) {
@@ -256,7 +274,7 @@
 		   	I830_WRITE(0x02080, 0x1ffff000);
 		}
 
-	   	DRM(free)(dev->dev_private, sizeof(drm_i830_private_t), 
+	   	drm_free(dev->dev_private, sizeof(drm_i830_private_t), 
 			 DRM_MEM_DRIVER);
 	   	dev->dev_private = NULL;
 
@@ -264,7 +282,7 @@
 			drm_buf_t *buf = dma->buflist[ i ];
 			drm_i830_buf_priv_t *buf_priv = buf->dev_private;
 			if ( buf_priv->kernel_virtual && buf->total )
-				DRM(ioremapfree)(buf_priv->kernel_virtual, buf->total, dev);
+				drm_ioremapfree(buf_priv->kernel_virtual, buf->total, dev);
 		}
 	}
    	return 0;
@@ -339,7 +357,7 @@
 
 	   	*buf_priv->in_use = I830_BUF_FREE;
 
-		buf_priv->kernel_virtual = DRM(ioremap)(buf->bus_address, 
+		buf_priv->kernel_virtual = drm_ioremap(buf->bus_address, 
 							buf->total, dev);
 	}
 	return 0;
@@ -392,7 +410,7 @@
    	dev_priv->ring.End = init->ring_end;
    	dev_priv->ring.Size = init->ring_size;
 
-   	dev_priv->ring.virtual_start = DRM(ioremap)(dev->agp->base + 
+   	dev_priv->ring.virtual_start = drm_ioremap(dev->agp->base + 
 						    init->ring_start, 
 						    init->ring_size, dev);
 
@@ -475,7 +493,7 @@
 	
    	switch(init.func) {
 	 	case I830_INIT_DMA:
-			dev_priv = DRM(alloc)(sizeof(drm_i830_private_t), 
+			dev_priv = drm_alloc(sizeof(drm_i830_private_t), 
 					      DRM_MEM_DRIVER);
 	   		if(dev_priv == NULL) return -ENOMEM;
 	   		retcode = i830_dma_initialize(dev, dev_priv, &init);
@@ -1284,10 +1302,8 @@
 }
 
 /* Must be called with the lock held */
-void i830_reclaim_buffers( struct file *filp )
+void i830_reclaim_buffers(drm_device_t *dev, struct file *filp)
 {
-	drm_file_t    *priv   = filp->private_data;
-	drm_device_t  *dev    = priv->dev;
 	drm_device_dma_t *dma = dev->dma;
 	int		 i;
 
@@ -1319,10 +1335,7 @@
    	drm_file_t	  *priv	  = filp->private_data;
    	drm_device_t	  *dev	  = priv->dev;
 
-   	if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
-		DRM_ERROR("i830_flush_ioctl called without lock held\n");
-		return -EINVAL;
-	}
+	LOCK_TEST_WITH_RETURN(dev, filp);
 
    	i830_flush_queue(dev);
    	return 0;
@@ -1343,10 +1356,7 @@
 	if (copy_from_user(&vertex, (drm_i830_vertex_t __user *)arg, sizeof(vertex)))
 		return -EFAULT;
 
-   	if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
-		DRM_ERROR("i830_dma_vertex called without lock held\n");
-		return -EINVAL;
-	}
+	LOCK_TEST_WITH_RETURN(dev, filp);
 
 	DRM_DEBUG("i830 dma vertex, idx %d used %d discard %d\n",
 		  vertex.idx, vertex.used, vertex.discard);
@@ -1373,10 +1383,7 @@
    	if (copy_from_user(&clear, (drm_i830_clear_t __user *)arg, sizeof(clear)))
 		return -EFAULT;
    
-   	if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
-		DRM_ERROR("i830_clear_bufs called without lock held\n");
-		return -EINVAL;
-	}
+	LOCK_TEST_WITH_RETURN(dev, filp);
 
 	/* GH: Someone's doing nasty things... */
 	if (!dev->dev_private) {
@@ -1398,10 +1405,7 @@
    
 	DRM_DEBUG("i830_swap_bufs\n");
 
-   	if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
-		DRM_ERROR("i830_swap_buf called without lock held\n");
-		return -EINVAL;
-	}
+	LOCK_TEST_WITH_RETURN(dev, filp);
 
 	i830_dma_dispatch_swap( dev );
    	return 0;
@@ -1442,10 +1446,7 @@
 
 	DRM_DEBUG("%s\n", __FUNCTION__);
 
-   	if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
-		DRM_ERROR("i830_flip_buf called without lock held\n");
-		return -EINVAL;
-	}
+	LOCK_TEST_WITH_RETURN(dev, filp);
 
 	if (!dev_priv->page_flipping) 
 		i830_do_init_pageflip( dev );
@@ -1484,10 +1485,7 @@
    	if (copy_from_user(&d, (drm_i830_dma_t __user *)arg, sizeof(d)))
 		return -EFAULT;
    
-	if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
-		DRM_ERROR("i830_dma called without lock held\n");
-		return -EINVAL;
-	}
+	LOCK_TEST_WITH_RETURN(dev, filp);
 	
 	d.granted = 0;
 
@@ -1582,43 +1580,19 @@
 }
 
 
-static void i830_driver_pretakedown(drm_device_t *dev)
+void i830_driver_pretakedown(drm_device_t *dev)
 {
 	i830_dma_cleanup( dev );
 }
 
-static void i830_driver_release(drm_device_t *dev, struct file *filp)
+void i830_driver_release(drm_device_t *dev, struct file *filp)
 {
-	i830_reclaim_buffers(filp);
+	i830_reclaim_buffers(dev, filp);
 }
 
-static int i830_driver_dma_quiescent(drm_device_t *dev)
+int i830_driver_dma_quiescent(drm_device_t *dev)
 {
 	i830_dma_quiescent( dev );
 	return 0;
-}
-
-void i830_driver_register_fns(drm_device_t *dev)
-{
-	dev->driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_DMA | DRIVER_DMA_QUEUE;
-#if USE_IRQS
-	dev->driver_features |= DRIVER_HAVE_IRQ | DRIVER_SHARED_IRQ;
-#endif
-	dev->dev_priv_size = sizeof(drm_i830_buf_priv_t);
-	dev->fn_tbl.pretakedown = i830_driver_pretakedown;
-	dev->fn_tbl.release = i830_driver_release;
-	dev->fn_tbl.dma_quiescent = i830_driver_dma_quiescent;
-	dev->fn_tbl.reclaim_buffers = i830_reclaim_buffers;
-#if USE_IRQS
-	dev->fn_tbl.irq_preinstall = i830_driver_irq_preinstall;
-	dev->fn_tbl.irq_postinstall = i830_driver_irq_postinstall;
-	dev->fn_tbl.irq_uninstall = i830_driver_irq_uninstall;
-	dev->fn_tbl.irq_handler = i830_driver_irq_handler;
-#endif
-	dev->counters += 4;
-	dev->types[6] = _DRM_STAT_IRQ;
-	dev->types[7] = _DRM_STAT_PRIMARY;
-	dev->types[8] = _DRM_STAT_SECONDARY;
-	dev->types[9] = _DRM_STAT_DMA;
 }
 
diff -Nru a/drivers/char/drm/i830_drm.h b/drivers/char/drm/i830_drm.h
--- a/drivers/char/drm/i830_drm.h	2005-03-01 23:38:55 -08:00
+++ b/drivers/char/drm/i830_drm.h	2005-03-01 23:38:55 -08:00
@@ -251,20 +251,35 @@
 /* I830 specific ioctls
  * The device specific ioctl range is 0x40 to 0x79.
  */
-#define DRM_IOCTL_I830_INIT		DRM_IOW( 0x40, drm_i830_init_t)
-#define DRM_IOCTL_I830_VERTEX		DRM_IOW( 0x41, drm_i830_vertex_t)
-#define DRM_IOCTL_I830_CLEAR		DRM_IOW( 0x42, drm_i830_clear_t)
-#define DRM_IOCTL_I830_FLUSH		DRM_IO ( 0x43)
-#define DRM_IOCTL_I830_GETAGE		DRM_IO ( 0x44)
-#define DRM_IOCTL_I830_GETBUF		DRM_IOWR(0x45, drm_i830_dma_t)
-#define DRM_IOCTL_I830_SWAP		DRM_IO ( 0x46)
-#define DRM_IOCTL_I830_COPY		DRM_IOW( 0x47, drm_i830_copy_t)
-#define DRM_IOCTL_I830_DOCOPY		DRM_IO ( 0x48)
-#define DRM_IOCTL_I830_FLIP		DRM_IO ( 0x49)
-#define DRM_IOCTL_I830_IRQ_EMIT         DRM_IOWR(0x4a, drm_i830_irq_emit_t)
-#define DRM_IOCTL_I830_IRQ_WAIT         DRM_IOW( 0x4b, drm_i830_irq_wait_t)
-#define DRM_IOCTL_I830_GETPARAM         DRM_IOWR(0x4c, drm_i830_getparam_t)
-#define DRM_IOCTL_I830_SETPARAM         DRM_IOWR(0x4d, drm_i830_setparam_t)
+#define DRM_I830_INIT	0x00
+#define DRM_I830_VERTEX	0x01
+#define DRM_I830_CLEAR	0x02
+#define DRM_I830_FLUSH	0x03
+#define DRM_I830_GETAGE	0x04
+#define DRM_I830_GETBUF	0x05
+#define DRM_I830_SWAP	0x06
+#define DRM_I830_COPY	0x07
+#define DRM_I830_DOCOPY	0x08
+#define DRM_I830_FLIP	0x09
+#define DRM_I830_IRQ_EMIT	0x0a
+#define DRM_I830_IRQ_WAIT	0x0b
+#define DRM_I830_GETPARAM	0x0c
+#define DRM_I830_SETPARAM	0x0d
+
+#define DRM_IOCTL_I830_INIT		DRM_IOW( DRM_COMMAND_BASE + DRM_IOCTL_I830_INIT, drm_i830_init_t)
+#define DRM_IOCTL_I830_VERTEX		DRM_IOW( DRM_COMMAND_BASE + DRM_IOCTL_I830_VERTEX, drm_i830_vertex_t)
+#define DRM_IOCTL_I830_CLEAR		DRM_IOW( DRM_COMMAND_BASE + DRM_IOCTL_I830_CLEAR, drm_i830_clear_t)
+#define DRM_IOCTL_I830_FLUSH		DRM_IO ( DRM_COMMAND_BASE + DRM_IOCTL_I830_FLUSH)
+#define DRM_IOCTL_I830_GETAGE		DRM_IO ( DRM_COMMAND_BASE + DRM_IOCTL_I830_GETAGE)
+#define DRM_IOCTL_I830_GETBUF		DRM_IOWR(DRM_COMMAND_BASE + DRM_IOCTL_I830_GETBUF, drm_i830_dma_t)
+#define DRM_IOCTL_I830_SWAP		DRM_IO ( DRM_COMMAND_BASE + DRM_IOCTL_I830_SWAP)
+#define DRM_IOCTL_I830_COPY		DRM_IOW( DRM_COMMAND_BASE + DRM_IOCTL_I830_COPY, drm_i830_copy_t)
+#define DRM_IOCTL_I830_DOCOPY		DRM_IO ( DRM_COMMAND_BASE + DRM_IOCTL_I830_DOCOPY)
+#define DRM_IOCTL_I830_FLIP		DRM_IO ( DRM_COMMAND_BASE + DRM_IOCTL_I830_FLIP)
+#define DRM_IOCTL_I830_IRQ_EMIT         DRM_IOWR(DRM_COMMAND_BASE + DRM_IOCTL_I830_IRQ_EMIT, drm_i830_irq_emit_t)
+#define DRM_IOCTL_I830_IRQ_WAIT         DRM_IOW( DRM_COMMAND_BASE + DRM_IOCTL_I830_IRQ_WAIT, drm_i830_irq_wait_t)
+#define DRM_IOCTL_I830_GETPARAM         DRM_IOWR(DRM_COMMAND_BASE + DRM_IOCTL_I830_GETPARAM, drm_i830_getparam_t)
+#define DRM_IOCTL_I830_SETPARAM         DRM_IOWR(DRM_COMMAND_BASE + DRM_IOCTL_I830_SETPARAM, drm_i830_setparam_t)
 
 typedef struct _drm_i830_clear {
 	int clear_color;
diff -Nru a/drivers/char/drm/i830_drv.c b/drivers/char/drm/i830_drv.c
--- a/drivers/char/drm/i830_drv.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/char/drm/i830_drv.c	2005-03-01 23:38:54 -08:00
@@ -33,10 +33,104 @@
  */
 
 #include <linux/config.h>
-#include "i830.h"
 #include "drmP.h"
 #include "drm.h"
 #include "i830_drm.h"
 #include "i830_drv.h"
 
-#include "drm_core.h"
+#include "drm_pciids.h"
+
+int postinit( struct drm_device *dev, unsigned long flags )
+{
+	dev->counters += 4;
+	dev->types[6] = _DRM_STAT_IRQ;
+	dev->types[7] = _DRM_STAT_PRIMARY;
+	dev->types[8] = _DRM_STAT_SECONDARY;
+	dev->types[9] = _DRM_STAT_DMA;
+	
+	DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d: %s\n",
+		DRIVER_NAME,
+		DRIVER_MAJOR,
+		DRIVER_MINOR,
+		DRIVER_PATCHLEVEL,
+		DRIVER_DATE,
+		dev->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[] = {
+	i830_PCI_IDS
+};
+
+extern drm_ioctl_desc_t i830_ioctls[];
+extern int i830_max_ioctl;
+
+static struct drm_driver driver = {
+	.driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_DMA | DRIVER_DMA_QUEUE,
+#if USE_IRQS
+	.driver_features |= DRIVER_HAVE_IRQ | DRIVER_SHARED_IRQ,
+#endif
+	.dev_priv_size = sizeof(drm_i830_buf_priv_t),
+	.pretakedown = i830_driver_pretakedown,
+	.release = i830_driver_release,
+	.dma_quiescent = i830_driver_dma_quiescent,
+	.reclaim_buffers = i830_reclaim_buffers,
+	.get_map_ofs = drm_core_get_map_ofs,
+	.get_reg_ofs = drm_core_get_reg_ofs,
+#if USE_IRQS
+	.irq_preinstall = i830_driver_irq_preinstall,
+	.irq_postinstall = i830_driver_irq_postinstall,
+	.irq_uninstall = i830_driver_irq_uninstall,
+	.irq_handler = i830_driver_irq_handler,
+#endif
+	.postinit = postinit,
+	.version = version,
+	.ioctls = i830_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 i830_init(void)
+{
+	driver.num_ioctls = i830_max_ioctl;
+	return drm_init(&driver);
+}
+
+static void __exit i830_exit(void)
+{
+	drm_exit(&driver);
+}
+
+module_init(i830_init);
+module_exit(i830_exit);
+
+MODULE_AUTHOR( DRIVER_AUTHOR );
+MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_LICENSE("GPL and additional rights");
diff -Nru a/drivers/char/drm/i830_drv.h b/drivers/char/drm/i830_drv.h
--- a/drivers/char/drm/i830_drv.h	2005-03-01 23:39:07 -08:00
+++ b/drivers/char/drm/i830_drv.h	2005-03-01 23:39:07 -08:00
@@ -32,6 +32,36 @@
 #ifndef _I830_DRV_H_
 #define _I830_DRV_H_
 
+/* General customization:
+ */
+
+#define DRIVER_AUTHOR		"VA Linux Systems Inc."
+
+#define DRIVER_NAME		"i830"
+#define DRIVER_DESC		"Intel 830M"
+#define DRIVER_DATE		"20021108"
+
+/* Interface history:
+ *
+ * 1.1: Original.
+ * 1.2: ?
+ * 1.3: New irq emit/wait ioctls.
+ *      New pageflip ioctl.
+ *      New getparam ioctl.
+ *      State for texunits 3&4 in sarea.
+ *      New (alternative) layout for texture state.
+ */
+#define DRIVER_MAJOR		1
+#define DRIVER_MINOR		3
+#define DRIVER_PATCHLEVEL	2
+
+/* Driver will work either way: IRQ's save cpu time when waiting for
+ * the card, but are subject to subtle interactions between bios,
+ * hardware and the driver.
+ */
+/* XXX: Add vblank support? */
+#define USE_IRQS 0
+
 typedef struct drm_i830_buf_priv {
    	u32 *in_use;
    	int my_use_idx;
@@ -99,7 +129,7 @@
 extern int  i830_dma_cleanup(drm_device_t *dev);
 extern int  i830_flush_ioctl(struct inode *inode, struct file *filp,
 			     unsigned int cmd, unsigned long arg);
-extern void i830_reclaim_buffers(struct file *filp);
+extern void i830_reclaim_buffers(drm_device_t *dev, struct file *filp);
 extern int  i830_getage(struct inode *inode, struct file *filp, unsigned int cmd,
 			unsigned long arg);
 extern int i830_mmap_buffers(struct file *filp, struct vm_area_struct *vma);
@@ -140,6 +170,9 @@
 extern void i830_driver_irq_preinstall( drm_device_t *dev );
 extern void i830_driver_irq_postinstall( drm_device_t *dev );
 extern void i830_driver_irq_uninstall( drm_device_t *dev );
+extern void i830_driver_pretakedown(drm_device_t *dev);
+extern void i830_driver_release(drm_device_t *dev, struct file *filp);
+extern int i830_driver_dma_quiescent(drm_device_t *dev);
 
 #define I830_BASE(reg)		((unsigned long) \
 				dev_priv->mmio_map->handle)
diff -Nru a/drivers/char/drm/i830_irq.c b/drivers/char/drm/i830_irq.c
--- a/drivers/char/drm/i830_irq.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/char/drm/i830_irq.c	2005-03-01 23:39:08 -08:00
@@ -26,7 +26,6 @@
  *
  */
 
-#include "i830.h"
 #include "drmP.h"
 #include "drm.h"
 #include "i830_drm.h"
@@ -129,10 +128,7 @@
 	drm_i830_irq_emit_t emit;
 	int result;
 
-   	if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
-		DRM_ERROR("i830_irq_emit called without lock held\n");
-		return -EINVAL;
-	}
+	LOCK_TEST_WITH_RETURN(dev, filp);
 
 	if ( !dev_priv ) {
 		DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
diff -Nru a/drivers/char/drm/i915.h b/drivers/char/drm/i915.h
--- a/drivers/char/drm/i915.h	2005-03-01 23:38:44 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,53 +0,0 @@
-/* i915.h -- Intel I915 DRM template customization -*- linux-c -*-
- */
-/**************************************************************************
- * 
- * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- * 
- **************************************************************************/
-
-#ifndef __I915_H__
-#define __I915_H__
-
-/* This remains constant for all DRM template files.
- */
-#define DRM(x) i915_##x
-
-/* General customization:
- */
-
-#define DRIVER_AUTHOR		"Tungsten Graphics, Inc."
-
-#define DRIVER_NAME		"i915"
-#define DRIVER_DESC		"Intel Graphics"
-#define DRIVER_DATE		"20040405"
-
-/* Interface history:
- *
- * 1.1: Original.
- */
-#define DRIVER_MAJOR		1
-#define DRIVER_MINOR		1
-#define DRIVER_PATCHLEVEL	0
-
-#define DRIVER_IOCTLS							    \
-	[DRM_IOCTL_NR(DRM_IOCTL_I915_INIT)]   = { i915_dma_init,    1, 1 }, \
-	[DRM_IOCTL_NR(DRM_IOCTL_I915_FLUSH)]  = { i915_flush_ioctl, 1, 0 }, \
-	[DRM_IOCTL_NR(DRM_IOCTL_I915_FLIP)]   = { i915_flip_bufs,   1, 0 }, \
-	[DRM_IOCTL_NR(DRM_IOCTL_I915_BATCHBUFFER)] = { i915_batchbuffer, 1, 0 }, \
-	[DRM_IOCTL_NR(DRM_IOCTL_I915_IRQ_EMIT)] = { i915_irq_emit,  1, 0 }, \
-	[DRM_IOCTL_NR(DRM_IOCTL_I915_IRQ_WAIT)] = { i915_irq_wait,  1, 0 }, \
-	[DRM_IOCTL_NR(DRM_IOCTL_I915_GETPARAM)] = { i915_getparam,  1, 0 }, \
-	[DRM_IOCTL_NR(DRM_IOCTL_I915_SETPARAM)] = { i915_setparam,  1, 1 }, \
-        [DRM_IOCTL_NR(DRM_IOCTL_I915_ALLOC)]   = { i915_mem_alloc,  1, 0 }, \
-        [DRM_IOCTL_NR(DRM_IOCTL_I915_FREE)]    = { i915_mem_free,    1, 0 }, \
-        [DRM_IOCTL_NR(DRM_IOCTL_I915_INIT_HEAP)] = { i915_mem_init_heap, 1, 1 }, \
-	[DRM_IOCTL_NR(DRM_IOCTL_I915_CMDBUFFER)] = { i915_cmdbuffer, 1, 0 }
-
-/* We use our own dma mechanisms, not the drm template code.  However,
- * the shared IRQ code is useful to us:
- */
-#define __HAVE_PM		1
-
-#endif
diff -Nru a/drivers/char/drm/i915_dma.c b/drivers/char/drm/i915_dma.c
--- a/drivers/char/drm/i915_dma.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/char/drm/i915_dma.c	2005-03-01 23:38:55 -08:00
@@ -7,29 +7,27 @@
  * 
  **************************************************************************/
 
-#include "i915.h"
 #include "drmP.h"
 #include "drm.h"
 #include "i915_drm.h"
 #include "i915_drv.h"
 
-static inline void i915_print_status_page(drm_device_t * dev)
-{
-	drm_i915_private_t *dev_priv = dev->dev_private;
-	u32 *temp = dev_priv->hw_status_page;
+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}
+};
 
-	if (!temp) {
-		DRM_DEBUG("no status page\n");
-		return;
-	}
-
-	DRM_DEBUG("hw_status: Interrupt Status : %x\n", temp[0]);
-	DRM_DEBUG("hw_status: LpRing Head ptr : %x\n", temp[1]);
-	DRM_DEBUG("hw_status: IRing Head ptr : %x\n", temp[2]);
-	DRM_DEBUG("hw_status: Reserved : %x\n", temp[3]);
-	DRM_DEBUG("hw_status: Driver Counter : %d\n", temp[5]);
-
-}
+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
@@ -84,7 +82,7 @@
 	 * is freed, it's too late.
 	 */
 	if (dev->irq)
-		DRM(irq_uninstall) (dev);
+		drm_irq_uninstall (dev);
 
 	if (dev->dev_private) {
 		drm_i915_private_t *dev_priv =
@@ -95,14 +93,13 @@
 		}
 
 		if (dev_priv->hw_status_page) {
-			pci_free_consistent(dev->pdev, PAGE_SIZE,
-					    dev_priv->hw_status_page,
-					    dev_priv->dma_status_page);
+			drm_pci_free(dev, PAGE_SIZE, dev_priv->hw_status_page,
+				     dev_priv->dma_status_page);
 			/* Need to rewrite hardware status page */
 			I915_WRITE(0x02080, 0x1ffff000);
 		}
 
-		DRM(free) (dev->dev_private, sizeof(drm_i915_private_t),
+		drm_free (dev->dev_private, sizeof(drm_i915_private_t),
 			   DRM_MEM_DRIVER);
 
 		dev->dev_private = NULL;
@@ -174,9 +171,9 @@
 	dev_priv->allow_batchbuffer = 1;
 
 	/* Program Hardware Status Page */
-	dev_priv->hw_status_page =
-	    pci_alloc_consistent(dev->pdev, PAGE_SIZE,
-				 &dev_priv->dma_status_page);
+	dev_priv->hw_status_page = drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE,
+						 0xffffffff, 
+						 &dev_priv->dma_status_page);
 
 	if (!dev_priv->hw_status_page) {
 		dev->dev_private = (void *)dev_priv;
@@ -242,7 +239,7 @@
 
 	switch (init.func) {
 	case I915_INIT_DMA:
-		dev_priv = DRM(alloc) (sizeof(drm_i915_private_t),
+		dev_priv = drm_alloc (sizeof(drm_i915_private_t),
 				       DRM_MEM_DRIVER);
 		if (dev_priv == NULL)
 			return DRM_ERR(ENOMEM);
@@ -545,10 +542,7 @@
 {
 	DRM_DEVICE;
 
-	if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
-		DRM_ERROR("i915_flush_ioctl called without lock held\n");
-		return DRM_ERR(EINVAL);
-	}
+	LOCK_TEST_WITH_RETURN(dev, filp);
 
 	return i915_quiescent(dev);
 }
@@ -574,10 +568,7 @@
 	DRM_DEBUG("i915 batchbuffer, start %x used %d cliprects %d\n",
 		  batch.start, batch.used, batch.num_cliprects);
 
-	if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
-		DRM_ERROR("i915_batchbuffer called without lock held\n");
-		return DRM_ERR(EINVAL);
-	}
+	LOCK_TEST_WITH_RETURN(dev, filp);
 
 	if (batch.num_cliprects && DRM_VERIFYAREA_READ(batch.cliprects,
 						       batch.num_cliprects *
@@ -606,10 +597,7 @@
 	DRM_DEBUG("i915 cmdbuffer, buf %p sz %d cliprects %d\n",
 		  cmdbuf.buf, cmdbuf.sz, cmdbuf.num_cliprects);
 
-	if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
-		DRM_ERROR("i915_cmdbuffer called without lock held\n");
-		return DRM_ERR(EINVAL);
-	}
+	LOCK_TEST_WITH_RETURN(dev, filp);
 
 	if (cmdbuf.num_cliprects &&
 	    DRM_VERIFYAREA_READ(cmdbuf.cliprects,
@@ -645,10 +633,8 @@
 	DRM_DEVICE;
 
 	DRM_DEBUG("%s\n", __FUNCTION__);
-	if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
-		DRM_ERROR("i915_flip_buf called without lock held\n");
-		return DRM_ERR(EINVAL);
-	}
+
+	LOCK_TEST_WITH_RETURN(dev, filp);
 
 	return i915_dispatch_flip(dev);
 }
@@ -720,7 +706,7 @@
 	return 0;
 }
 
-static void i915_driver_pretakedown(drm_device_t *dev)
+void i915_driver_pretakedown(drm_device_t *dev)
 {
 	if ( dev->dev_private ) {
 		drm_i915_private_t *dev_priv = dev->dev_private;
@@ -729,7 +715,7 @@
 	i915_dma_cleanup( dev );
 }
 
-static void i915_driver_prerelease(drm_device_t *dev, DRMFILE filp)
+void i915_driver_prerelease(drm_device_t *dev, DRMFILE filp)
 {
 	if ( dev->dev_private ) {
 		drm_i915_private_t *dev_priv = dev->dev_private;
@@ -737,19 +723,3 @@
 	}
 }
 
-void i915_driver_register_fns(drm_device_t *dev)
-{
-	dev->driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED;
-	dev->fn_tbl.pretakedown = i915_driver_pretakedown;
-	dev->fn_tbl.prerelease = i915_driver_prerelease;
-	dev->fn_tbl.irq_preinstall = i915_driver_irq_preinstall;
-	dev->fn_tbl.irq_postinstall = i915_driver_irq_postinstall;
-	dev->fn_tbl.irq_uninstall = i915_driver_irq_uninstall;
-	dev->fn_tbl.irq_handler = i915_driver_irq_handler;
-	
-	dev->counters += 4;
-	dev->types[6] = _DRM_STAT_IRQ;
-	dev->types[7] = _DRM_STAT_PRIMARY;
-	dev->types[8] = _DRM_STAT_SECONDARY;
-	dev->types[9] = _DRM_STAT_DMA;
-}
diff -Nru a/drivers/char/drm/i915_drm.h b/drivers/char/drm/i915_drm.h
--- a/drivers/char/drm/i915_drm.h	2005-03-01 23:39:18 -08:00
+++ b/drivers/char/drm/i915_drm.h	2005-03-01 23:39:18 -08:00
@@ -61,18 +61,31 @@
 /* I915 specific ioctls
  * The device specific ioctl range is 0x40 to 0x79.
  */
-#define DRM_IOCTL_I915_INIT		DRM_IOW( 0x40, drm_i915_init_t)
-#define DRM_IOCTL_I915_FLUSH		DRM_IO ( 0x41)
-#define DRM_IOCTL_I915_FLIP		DRM_IO ( 0x42)
-#define DRM_IOCTL_I915_BATCHBUFFER	DRM_IOW( 0x43, drm_i915_batchbuffer_t)
-#define DRM_IOCTL_I915_IRQ_EMIT         DRM_IOWR(0x44, drm_i915_irq_emit_t)
-#define DRM_IOCTL_I915_IRQ_WAIT         DRM_IOW( 0x45, drm_i915_irq_wait_t)
-#define DRM_IOCTL_I915_GETPARAM         DRM_IOWR(0x46, drm_i915_getparam_t)
-#define DRM_IOCTL_I915_SETPARAM         DRM_IOW( 0x47, drm_i915_setparam_t)
-#define DRM_IOCTL_I915_ALLOC            DRM_IOWR(0x48, drm_i915_mem_alloc_t)
-#define DRM_IOCTL_I915_FREE             DRM_IOW( 0x49, drm_i915_mem_free_t)
-#define DRM_IOCTL_I915_INIT_HEAP        DRM_IOW( 0x4a, drm_i915_mem_init_heap_t)
-#define DRM_IOCTL_I915_CMDBUFFER	DRM_IOW( 0x4b, drm_i915_cmdbuffer_t)
+#define DRM_I915_INIT		0x00
+#define DRM_I915_FLUSH		0x01
+#define DRM_I915_FLIP		0x02
+#define DRM_I915_BATCHBUFFER	0x03
+#define DRM_I915_IRQ_EMIT	0x04
+#define DRM_I915_IRQ_WAIT	0x05
+#define DRM_I915_GETPARAM	0x06
+#define DRM_I915_SETPARAM	0x07
+#define DRM_I915_ALLOC		0x08
+#define DRM_I915_FREE		0x09
+#define DRM_I915_INIT_HEAP	0x0a
+#define DRM_I915_CMDBUFFER	0x0b
+
+#define DRM_IOCTL_I915_INIT		DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t)
+#define DRM_IOCTL_I915_FLUSH		DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH)
+#define DRM_IOCTL_I915_FLIP		DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLIP)
+#define DRM_IOCTL_I915_BATCHBUFFER	DRM_IOW( DRM_COMMAND_BASE + DRM_I915_BATCHBUFFER, drm_i915_batchbuffer_t)
+#define DRM_IOCTL_I915_IRQ_EMIT         DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_IRQ_EMIT, drm_i915_irq_emit_t)
+#define DRM_IOCTL_I915_IRQ_WAIT         DRM_IOW( DRM_COMMAND_BASE + DRM_I915_IRQ_WAIT, drm_i915_irq_wait_t)
+#define DRM_IOCTL_I915_GETPARAM         DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GETPARAM, drm_i915_getparam_t)
+#define DRM_IOCTL_I915_SETPARAM         DRM_IOW( DRM_COMMAND_BASE + DRM_I915_SETPARAM, drm_i915_setparam_t)
+#define DRM_IOCTL_I915_ALLOC            DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_ALLOC, drm_i915_mem_alloc_t)
+#define DRM_IOCTL_I915_FREE             DRM_IOW( DRM_COMMAND_BASE + DRM_I915_FREE, drm_i915_mem_free_t)
+#define DRM_IOCTL_I915_INIT_HEAP        DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT_HEAP, drm_i915_mem_init_heap_t)
+#define DRM_IOCTL_I915_CMDBUFFER	DRM_IOW( DRM_COMMAND_BASE + DRM_I915_CMDBUFFER, drm_i915_cmdbuffer_t)
 
 /* Allow drivers to submit batchbuffers directly to hardware, relying
  * on the security mechanisms provided by hardware.
diff -Nru a/drivers/char/drm/i915_drv.c b/drivers/char/drm/i915_drv.c
--- a/drivers/char/drm/i915_drv.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/char/drm/i915_drv.c	2005-03-01 23:38:56 -08:00
@@ -8,10 +8,97 @@
  * 
  **************************************************************************/
 
-#include "i915.h"
 #include "drmP.h"
 #include "drm.h"
 #include "i915_drm.h"
 #include "i915_drv.h"
 
-#include "drm_core.h"
+#include "drm_pciids.h"
+
+int postinit( struct drm_device *dev, unsigned long flags )
+{
+	dev->counters += 4;
+	dev->types[6] = _DRM_STAT_IRQ;
+	dev->types[7] = _DRM_STAT_PRIMARY;
+	dev->types[8] = _DRM_STAT_SECONDARY;
+	dev->types[9] = _DRM_STAT_DMA;
+	
+	DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d: %s\n",
+		DRIVER_NAME,
+		DRIVER_MAJOR,
+		DRIVER_MINOR,
+		DRIVER_PATCHLEVEL,
+		DRIVER_DATE,
+		dev->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[] = {
+	i915_PCI_IDS
+};
+
+extern drm_ioctl_desc_t i915_ioctls[];
+extern int i915_max_ioctl;
+
+static struct drm_driver driver = {
+	.driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR |
+				DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED,
+	.pretakedown = i915_driver_pretakedown,
+	.prerelease = i915_driver_prerelease,
+	.irq_preinstall = i915_driver_irq_preinstall,
+	.irq_postinstall = i915_driver_irq_postinstall,
+	.irq_uninstall = i915_driver_irq_uninstall,
+	.irq_handler = i915_driver_irq_handler,
+	.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 = i915_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 i915_init(void)
+{
+	driver.num_ioctls = i915_max_ioctl;
+	return drm_init(&driver);
+}
+
+static void __exit i915_exit(void)
+{
+	drm_exit(&driver);
+}
+
+module_init(i915_init);
+module_exit(i915_exit);
+
+MODULE_AUTHOR( DRIVER_AUTHOR );
+MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_LICENSE("GPL and additional rights");
diff -Nru a/drivers/char/drm/i915_drv.h b/drivers/char/drm/i915_drv.h
--- a/drivers/char/drm/i915_drv.h	2005-03-01 23:39:16 -08:00
+++ b/drivers/char/drm/i915_drv.h	2005-03-01 23:39:16 -08:00
@@ -10,6 +10,28 @@
 #ifndef _I915_DRV_H_
 #define _I915_DRV_H_
 
+/* General customization:
+ */
+
+#define DRIVER_AUTHOR		"Tungsten Graphics, Inc."
+
+#define DRIVER_NAME		"i915"
+#define DRIVER_DESC		"Intel Graphics"
+#define DRIVER_DATE		"20040405"
+
+/* Interface history:
+ *
+ * 1.1: Original.
+ */
+#define DRIVER_MAJOR		1
+#define DRIVER_MINOR		1
+#define DRIVER_PATCHLEVEL	0
+
+/* We use our own dma mechanisms, not the drm template code.  However,
+ * the shared IRQ code is useful to us:
+ */
+#define __HAVE_PM		1
+
 typedef struct _drm_i915_ring_buffer {
 	int tail_mask;
 	unsigned long Start;
@@ -66,6 +88,8 @@
 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);
 
 /* i915_irq.c */
 extern int i915_irq_emit(DRM_IOCTL_ARGS);
diff -Nru a/drivers/char/drm/i915_irq.c b/drivers/char/drm/i915_irq.c
--- a/drivers/char/drm/i915_irq.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/char/drm/i915_irq.c	2005-03-01 23:38:55 -08:00
@@ -7,7 +7,6 @@
  * 
  **************************************************************************/
 
-#include "i915.h"
 #include "drmP.h"
 #include "drm.h"
 #include "i915_drm.h"
@@ -92,10 +91,7 @@
 	drm_i915_irq_emit_t emit;
 	int result;
 
-	if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
-		DRM_ERROR("i915_irq_emit called without lock held\n");
-		return DRM_ERR(EINVAL);
-	}
+	LOCK_TEST_WITH_RETURN(dev, filp);
 
 	if (!dev_priv) {
 		DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
diff -Nru a/drivers/char/drm/i915_mem.c b/drivers/char/drm/i915_mem.c
--- a/drivers/char/drm/i915_mem.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/char/drm/i915_mem.c	2005-03-01 23:38:58 -08:00
@@ -7,7 +7,6 @@
  * 
  **************************************************************************/
 
-#include "i915.h"
 #include "drmP.h"
 #include "drm.h"
 #include "i915_drm.h"
@@ -75,7 +74,7 @@
 {
 	/* Maybe cut off the start of an existing block */
 	if (start > p->start) {
-		struct mem_block *newblock = DRM_MALLOC(sizeof(*newblock));
+		struct mem_block *newblock = drm_alloc(sizeof(*newblock), DRM_MEM_BUFLISTS);
 		if (!newblock)
 			goto out;
 		newblock->start = start;
@@ -91,7 +90,7 @@
 
 	/* Maybe cut off the end of an existing block */
 	if (size < p->size) {
-		struct mem_block *newblock = DRM_MALLOC(sizeof(*newblock));
+		struct mem_block *newblock = drm_alloc(sizeof(*newblock), DRM_MEM_BUFLISTS);
 		if (!newblock)
 			goto out;
 		newblock->start = start + size;
@@ -148,7 +147,7 @@
 		p->size += q->size;
 		p->next = q->next;
 		p->next->prev = p;
-		DRM_FREE(q, sizeof(*q));
+		drm_free(q, sizeof(*q), DRM_MEM_BUFLISTS);
 	}
 
 	if (p->prev->filp == NULL) {
@@ -156,7 +155,7 @@
 		q->size += p->size;
 		q->next = p->next;
 		q->next->prev = q;
-		DRM_FREE(p, sizeof(*q));
+		drm_free(p, sizeof(*q), DRM_MEM_BUFLISTS);
 	}
 }
 
@@ -164,14 +163,14 @@
  */
 static int init_heap(struct mem_block **heap, int start, int size)
 {
-	struct mem_block *blocks = DRM_MALLOC(sizeof(*blocks));
+	struct mem_block *blocks = drm_alloc(sizeof(*blocks), DRM_MEM_BUFLISTS);
 
 	if (!blocks)
 		return -ENOMEM;
 
-	*heap = DRM_MALLOC(sizeof(**heap));
+	*heap = drm_alloc(sizeof(**heap), DRM_MEM_BUFLISTS);
 	if (!*heap) {
-		DRM_FREE(blocks, sizeof(*blocks));
+		drm_free(blocks, sizeof(*blocks), DRM_MEM_BUFLISTS);
 		return -ENOMEM;
 	}
 
@@ -211,7 +210,7 @@
 			p->size += q->size;
 			p->next = q->next;
 			p->next->prev = p;
-			DRM_FREE(q, sizeof(*q));
+			drm_free(q, sizeof(*q), DRM_MEM_BUFLISTS);
 		}
 	}
 }
@@ -228,10 +227,10 @@
 	for (p = (*heap)->next; p != *heap;) {
 		struct mem_block *q = p;
 		p = p->next;
-		DRM_FREE(q, sizeof(*q));
+		drm_free(q, sizeof(*q), DRM_MEM_BUFLISTS);
 	}
 
-	DRM_FREE(*heap, sizeof(**heap));
+	drm_free(*heap, sizeof(**heap), DRM_MEM_BUFLISTS);
 	*heap = NULL;
 }
 
diff -Nru a/drivers/char/drm/mga.h b/drivers/char/drm/mga.h
--- a/drivers/char/drm/mga.h	2005-03-01 23:39:18 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,63 +0,0 @@
-/* mga.h -- Matrox G200/G400 DRM template customization -*- linux-c -*-
- * Created: Thu Jan 11 21:29:32 2001 by gareth@valinux.com
- *
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- *    Gareth Hughes <gareth@valinux.com>
- */
-
-#ifndef __MGA_H__
-#define __MGA_H__
-
-/* This remains constant for all DRM template files.
- */
-#define DRM(x) mga_##x
-
-/* General customization:
- */
-
-#define DRIVER_AUTHOR		"Gareth Hughes, VA Linux Systems Inc."
-
-#define DRIVER_NAME		"mga"
-#define DRIVER_DESC		"Matrox G200/G400"
-#define DRIVER_DATE		"20021029"
-
-#define DRIVER_MAJOR		3
-#define DRIVER_MINOR		1
-#define DRIVER_PATCHLEVEL	0
-
-#define DRIVER_IOCTLS							   \
-	[DRM_IOCTL_NR(DRM_IOCTL_DMA)]	      = { mga_dma_buffers, 1, 0 }, \
-	[DRM_IOCTL_NR(DRM_IOCTL_MGA_INIT)]    = { mga_dma_init,    1, 1 }, \
-	[DRM_IOCTL_NR(DRM_IOCTL_MGA_FLUSH)]   = { mga_dma_flush,   1, 0 }, \
-	[DRM_IOCTL_NR(DRM_IOCTL_MGA_RESET)]   = { mga_dma_reset,   1, 0 }, \
-	[DRM_IOCTL_NR(DRM_IOCTL_MGA_SWAP)]    = { mga_dma_swap,    1, 0 }, \
-	[DRM_IOCTL_NR(DRM_IOCTL_MGA_CLEAR)]   = { mga_dma_clear,   1, 0 }, \
-	[DRM_IOCTL_NR(DRM_IOCTL_MGA_VERTEX)]  = { mga_dma_vertex,  1, 0 }, \
-	[DRM_IOCTL_NR(DRM_IOCTL_MGA_INDICES)] = { mga_dma_indices, 1, 0 }, \
-	[DRM_IOCTL_NR(DRM_IOCTL_MGA_ILOAD)]   = { mga_dma_iload,   1, 0 }, \
-	[DRM_IOCTL_NR(DRM_IOCTL_MGA_BLIT)]    = { mga_dma_blit,    1, 0 }, \
-	[DRM_IOCTL_NR(DRM_IOCTL_MGA_GETPARAM)]= { mga_getparam,    1, 0 },
-
-#endif
diff -Nru a/drivers/char/drm/mga_dma.c b/drivers/char/drm/mga_dma.c
--- a/drivers/char/drm/mga_dma.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/char/drm/mga_dma.c	2005-03-01 23:39:09 -08:00
@@ -33,7 +33,6 @@
  *    Gareth Hughes <gareth@valinux.com>
  */
 
-#include "mga.h"
 #include "drmP.h"
 #include "drm.h"
 #include "mga_drm.h"
@@ -308,7 +307,7 @@
 	int i;
 	DRM_DEBUG( "count=%d\n", dma->buf_count );
 
-	dev_priv->head = DRM(alloc)( sizeof(drm_mga_freelist_t),
+	dev_priv->head = drm_alloc( sizeof(drm_mga_freelist_t),
 				     DRM_MEM_DRIVER );
 	if ( dev_priv->head == NULL )
 		return DRM_ERR(ENOMEM);
@@ -320,7 +319,7 @@
 		buf = dma->buflist[i];
 	        buf_priv = buf->dev_private;
 
-		entry = DRM(alloc)( sizeof(drm_mga_freelist_t),
+		entry = drm_alloc( sizeof(drm_mga_freelist_t),
 				    DRM_MEM_DRIVER );
 		if ( entry == NULL )
 			return DRM_ERR(ENOMEM);
@@ -357,7 +356,7 @@
 	entry = dev_priv->head;
 	while ( entry ) {
 		next = entry->next;
-		DRM(free)( entry, sizeof(drm_mga_freelist_t), DRM_MEM_DRIVER );
+		drm_free( entry, sizeof(drm_mga_freelist_t), DRM_MEM_DRIVER );
 		entry = next;
 	}
 
@@ -458,7 +457,7 @@
 	int ret;
 	DRM_DEBUG( "\n" );
 
-	dev_priv = DRM(alloc)( sizeof(drm_mga_private_t), DRM_MEM_DRIVER );
+	dev_priv = drm_alloc( sizeof(drm_mga_private_t), DRM_MEM_DRIVER );
 	if ( !dev_priv )
 		return DRM_ERR(ENOMEM);
 
@@ -634,7 +633,7 @@
 	 * may not have been called from userspace and after dev_private
 	 * is freed, it's too late.
 	 */
-	if ( dev->irq_enabled ) DRM(irq_uninstall)(dev);
+	if ( dev->irq_enabled ) drm_irq_uninstall(dev);
 
 	if ( dev->dev_private ) {
 		drm_mga_private_t *dev_priv = dev->dev_private;
@@ -650,7 +649,7 @@
 			mga_freelist_cleanup( dev );
 		}
 
-		DRM(free)( dev->dev_private, sizeof(drm_mga_private_t),
+		drm_free( dev->dev_private, sizeof(drm_mga_private_t),
 			   DRM_MEM_DRIVER );
 		dev->dev_private = NULL;
 	}
@@ -798,30 +797,13 @@
 	return ret;
 }
 
-static void mga_driver_pretakedown(drm_device_t *dev)
+void mga_driver_pretakedown(drm_device_t *dev)
 {
 	mga_do_cleanup_dma( dev );
 }
 
-static int mga_driver_dma_quiescent(drm_device_t *dev)
+int mga_driver_dma_quiescent(drm_device_t *dev)
 {
 	drm_mga_private_t *dev_priv = dev->dev_private;
 	return mga_do_wait_for_idle( dev_priv );
-}
-
-void mga_driver_register_fns(drm_device_t *dev)
-{
-	dev->driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL;
-	dev->fn_tbl.pretakedown = mga_driver_pretakedown;
-	dev->fn_tbl.dma_quiescent = mga_driver_dma_quiescent;
-	dev->fn_tbl.vblank_wait = mga_driver_vblank_wait;
-	dev->fn_tbl.irq_preinstall = mga_driver_irq_preinstall;
-	dev->fn_tbl.irq_postinstall = mga_driver_irq_postinstall;
-	dev->fn_tbl.irq_uninstall = mga_driver_irq_uninstall;
-	dev->fn_tbl.irq_handler = mga_driver_irq_handler;
-	
-	dev->counters += 3;
-	dev->types[6] = _DRM_STAT_IRQ;
-	dev->types[7] = _DRM_STAT_PRIMARY;
-	dev->types[8] = _DRM_STAT_SECONDARY;
 }
diff -Nru a/drivers/char/drm/mga_drv.c b/drivers/char/drm/mga_drv.c
--- a/drivers/char/drm/mga_drv.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/char/drm/mga_drv.c	2005-03-01 23:38:56 -08:00
@@ -30,9 +30,98 @@
  */
 
 #include <linux/config.h>
-#include "mga.h"
 #include "drmP.h"
 #include "drm.h"
 #include "mga_drm.h"
 #include "mga_drv.h"
-#include "drm_core.h"
+
+  
+#include "drm_pciids.h"
+
+static int postinit( struct drm_device *dev, unsigned long flags )
+{
+	dev->counters += 3;
+	dev->types[6] = _DRM_STAT_IRQ;
+	dev->types[7] = _DRM_STAT_PRIMARY;
+	dev->types[8] = _DRM_STAT_SECONDARY;
+
+	DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d: %s\n",
+		DRIVER_NAME,
+		DRIVER_MAJOR,
+		DRIVER_MINOR,
+		DRIVER_PATCHLEVEL,
+		DRIVER_DATE,
+		dev->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[] = {
+	mga_PCI_IDS
+};
+
+extern drm_ioctl_desc_t mga_ioctls[];
+extern int mga_max_ioctl;
+
+static struct drm_driver driver = {
+	.driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL,
+	.pretakedown = mga_driver_pretakedown,
+	.dma_quiescent = mga_driver_dma_quiescent,
+	.vblank_wait = mga_driver_vblank_wait,
+	.irq_preinstall = mga_driver_irq_preinstall,
+	.irq_postinstall = mga_driver_irq_postinstall,
+	.irq_uninstall = mga_driver_irq_uninstall,
+	.irq_handler = mga_driver_irq_handler,
+	.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 = mga_ioctls,
+	.dma_ioctl = mga_dma_buffers,
+	.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 mga_init(void)
+{
+	driver.num_ioctls = mga_max_ioctl;
+	return drm_init(&driver);
+}
+
+static void __exit mga_exit(void)
+{
+	drm_exit(&driver);
+}
+
+module_init(mga_init);
+module_exit(mga_exit);
+
+MODULE_AUTHOR( DRIVER_AUTHOR );
+MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_LICENSE("GPL and additional rights");
diff -Nru a/drivers/char/drm/mga_drv.h b/drivers/char/drm/mga_drv.h
--- a/drivers/char/drm/mga_drv.h	2005-03-01 23:39:10 -08:00
+++ b/drivers/char/drm/mga_drv.h	2005-03-01 23:39:10 -08:00
@@ -31,6 +31,19 @@
 #ifndef __MGA_DRV_H__
 #define __MGA_DRV_H__
 
+/* General customization:
+ */
+
+#define DRIVER_AUTHOR		"Gareth Hughes, VA Linux Systems Inc."
+
+#define DRIVER_NAME		"mga"
+#define DRIVER_DESC		"Matrox G200/G400"
+#define DRIVER_DATE		"20021029"
+
+#define DRIVER_MAJOR		3
+#define DRIVER_MINOR		1
+#define DRIVER_PATCHLEVEL	0
+
 typedef struct drm_mga_primary_buffer {
 	u8 *start;
 	u8 *end;
@@ -104,6 +117,8 @@
 extern int mga_dma_flush( DRM_IOCTL_ARGS );
 extern int mga_dma_reset( DRM_IOCTL_ARGS );
 extern int mga_dma_buffers( DRM_IOCTL_ARGS );
+extern void mga_driver_pretakedown(drm_device_t *dev);
+extern int mga_driver_dma_quiescent(drm_device_t *dev);
 
 extern int mga_do_wait_for_idle( drm_mga_private_t *dev_priv );
 extern int mga_do_dma_idle( drm_mga_private_t *dev_priv );
diff -Nru a/drivers/char/drm/mga_irq.c b/drivers/char/drm/mga_irq.c
--- a/drivers/char/drm/mga_irq.c	2005-03-01 23:38:44 -08:00
+++ b/drivers/char/drm/mga_irq.c	2005-03-01 23:38:44 -08:00
@@ -30,7 +30,6 @@
  *    Eric Anholt <anholt@FreeBSD.org>
  */
 
-#include "mga.h"
 #include "drmP.h"
 #include "drm.h"
 #include "mga_drm.h"
@@ -50,7 +49,7 @@
 		MGA_WRITE( MGA_ICLEAR, MGA_VLINEICLR );
 		atomic_inc(&dev->vbl_received);
 		DRM_WAKEUP(&dev->vbl_queue);
-		DRM(vbl_send_signals)( dev );
+		drm_vbl_send_signals( dev );
 		return IRQ_HANDLED;
 	}
 	return IRQ_NONE;
diff -Nru a/drivers/char/drm/mga_state.c b/drivers/char/drm/mga_state.c
--- a/drivers/char/drm/mga_state.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/char/drm/mga_state.c	2005-03-01 23:38:55 -08:00
@@ -32,12 +32,25 @@
  *    Gareth Hughes <gareth@valinux.com>
  */
 
-#include "mga.h"
 #include "drmP.h"
 #include "drm.h"
 #include "mga_drm.h"
 #include "mga_drv.h"
 
+drm_ioctl_desc_t mga_ioctls[] = {
+	[DRM_IOCTL_NR(DRM_MGA_INIT)]    = { mga_dma_init,    1, 1 },
+	[DRM_IOCTL_NR(DRM_MGA_FLUSH)]   = { mga_dma_flush,   1, 0 },
+	[DRM_IOCTL_NR(DRM_MGA_RESET)]   = { mga_dma_reset,   1, 0 },
+	[DRM_IOCTL_NR(DRM_MGA_SWAP)]    = { mga_dma_swap,    1, 0 },
+	[DRM_IOCTL_NR(DRM_MGA_CLEAR)]   = { mga_dma_clear,   1, 0 },
+	[DRM_IOCTL_NR(DRM_MGA_VERTEX)]  = { mga_dma_vertex,  1, 0 },
+	[DRM_IOCTL_NR(DRM_MGA_INDICES)] = { mga_dma_indices, 1, 0 },
+	[DRM_IOCTL_NR(DRM_MGA_ILOAD)]   = { mga_dma_iload,   1, 0 },
+	[DRM_IOCTL_NR(DRM_MGA_BLIT)]    = { mga_dma_blit,    1, 0 },
+	[DRM_IOCTL_NR(DRM_MGA_GETPARAM)]= { mga_getparam,    1, 0 },
+};
+
+int mga_max_ioctl = DRM_ARRAY_SIZE(mga_ioctls);
 
 /* ================================================================
  * DMA hardware state programming functions
diff -Nru a/drivers/char/drm/mga_warp.c b/drivers/char/drm/mga_warp.c
--- a/drivers/char/drm/mga_warp.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/char/drm/mga_warp.c	2005-03-01 23:38:56 -08:00
@@ -27,7 +27,6 @@
  *    Gareth Hughes <gareth@valinux.com>
  */
 
-#include "mga.h"
 #include "drmP.h"
 #include "drm.h"
 #include "mga_drm.h"
diff -Nru a/drivers/char/drm/r128.h b/drivers/char/drm/r128.h
--- a/drivers/char/drm/r128.h	2005-03-01 23:38:55 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,75 +0,0 @@
-/* r128.h -- ATI Rage 128 DRM template customization -*- linux-c -*-
- * Created: Wed Feb 14 16:07:10 2001 by gareth@valinux.com
- *
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- *    Gareth Hughes <gareth@valinux.com>
- */
-
-#ifndef __R128_H__
-#define __R128_H__
-
-/* This remains constant for all DRM template files.
- */
-#define DRM(x) r128_##x
-
-/* General customization:
- */
-#define DRIVER_AUTHOR		"Gareth Hughes, VA Linux Systems Inc."
-
-#define DRIVER_NAME		"r128"
-#define DRIVER_DESC		"ATI Rage 128"
-#define DRIVER_DATE		"20030725"
-
-#define DRIVER_MAJOR		2
-#define DRIVER_MINOR		5
-#define DRIVER_PATCHLEVEL	0
-
-/* Interface history:
- *
- * ??  - ??
- * 2.4 - Add support for ycbcr textures (no new ioctls)
- * 2.5 - Add FLIP ioctl, disable FULLSCREEN.
- */
-#define DRIVER_IOCTLS							    \
-   [DRM_IOCTL_NR(DRM_IOCTL_DMA)]             = { r128_cce_buffers,  1, 0 }, \
-   [DRM_IOCTL_NR(DRM_IOCTL_R128_INIT)]       = { r128_cce_init,     1, 1 }, \
-   [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_START)]  = { r128_cce_start,    1, 1 }, \
-   [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_STOP)]   = { r128_cce_stop,     1, 1 }, \
-   [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_RESET)]  = { r128_cce_reset,    1, 1 }, \
-   [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_IDLE)]   = { r128_cce_idle,     1, 0 }, \
-   [DRM_IOCTL_NR(DRM_IOCTL_R128_RESET)]      = { r128_engine_reset, 1, 0 }, \
-   [DRM_IOCTL_NR(DRM_IOCTL_R128_FULLSCREEN)] = { r128_fullscreen,   1, 0 }, \
-   [DRM_IOCTL_NR(DRM_IOCTL_R128_SWAP)]       = { r128_cce_swap,     1, 0 }, \
-   [DRM_IOCTL_NR(DRM_IOCTL_R128_FLIP)]       = { r128_cce_flip,     1, 0 }, \
-   [DRM_IOCTL_NR(DRM_IOCTL_R128_CLEAR)]      = { r128_cce_clear,    1, 0 }, \
-   [DRM_IOCTL_NR(DRM_IOCTL_R128_VERTEX)]     = { r128_cce_vertex,   1, 0 }, \
-   [DRM_IOCTL_NR(DRM_IOCTL_R128_INDICES)]    = { r128_cce_indices,  1, 0 }, \
-   [DRM_IOCTL_NR(DRM_IOCTL_R128_BLIT)]       = { r128_cce_blit,     1, 0 }, \
-   [DRM_IOCTL_NR(DRM_IOCTL_R128_DEPTH)]      = { r128_cce_depth,    1, 0 }, \
-   [DRM_IOCTL_NR(DRM_IOCTL_R128_STIPPLE)]    = { r128_cce_stipple,  1, 0 }, \
-   [DRM_IOCTL_NR(DRM_IOCTL_R128_INDIRECT)]   = { r128_cce_indirect, 1, 1 }, \
-   [DRM_IOCTL_NR(DRM_IOCTL_R128_GETPARAM)]   = { r128_getparam, 1, 0 },
-
-#endif
diff -Nru a/drivers/char/drm/r128_cce.c b/drivers/char/drm/r128_cce.c
--- a/drivers/char/drm/r128_cce.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/char/drm/r128_cce.c	2005-03-01 23:38:53 -08:00
@@ -28,7 +28,6 @@
  *    Gareth Hughes <gareth@valinux.com>
  */
 
-#include "r128.h"
 #include "drmP.h"
 #include "drm.h"
 #include "r128_drm.h"
@@ -355,7 +354,7 @@
 
 	DRM_DEBUG( "\n" );
 
-	dev_priv = DRM(alloc)( sizeof(drm_r128_private_t), DRM_MEM_DRIVER );
+	dev_priv = drm_alloc( sizeof(drm_r128_private_t), DRM_MEM_DRIVER );
 	if ( dev_priv == NULL )
 		return DRM_ERR(ENOMEM);
 
@@ -544,7 +543,7 @@
 	dev_priv->ring.end = ((u32 *)dev_priv->cce_ring->handle
 			      + init->ring_size / sizeof(u32));
 	dev_priv->ring.size = init->ring_size;
-	dev_priv->ring.size_l2qw = DRM(order)( init->ring_size / 8 );
+	dev_priv->ring.size_l2qw = drm_order( init->ring_size / 8 );
 
 	dev_priv->ring.tail_mask =
 		(dev_priv->ring.size / sizeof(u32)) - 1;
@@ -561,7 +560,7 @@
 #if __OS_HAS_AGP
 	if ( dev_priv->is_pci ) {
 #endif
-		if (!DRM(ati_pcigart_init)( dev, &dev_priv->phys_pci_gart,
+		if (!drm_ati_pcigart_init( dev, &dev_priv->phys_pci_gart,
      					    &dev_priv->bus_pci_gart) ) {
 			DRM_ERROR( "failed to init PCI GART!\n" );
 			dev->dev_private = (void *)dev_priv;
@@ -590,7 +589,7 @@
 	 * may not have been called from userspace and after dev_private
 	 * is freed, it's too late.
 	 */
-	if ( dev->irq_enabled ) DRM(irq_uninstall)(dev);
+	if ( dev->irq_enabled ) drm_irq_uninstall(dev);
 
 	if ( dev->dev_private ) {
 		drm_r128_private_t *dev_priv = dev->dev_private;
@@ -606,13 +605,13 @@
 		} else
 #endif
 		{
-			if (!DRM(ati_pcigart_cleanup)( dev,
+			if (!drm_ati_pcigart_cleanup( dev,
 						dev_priv->phys_pci_gart,
 						dev_priv->bus_pci_gart ))
 				DRM_ERROR( "failed to cleanup PCI GART!\n" );
 		}
 
-		DRM(free)( dev->dev_private, sizeof(drm_r128_private_t),
+		drm_free( dev->dev_private, sizeof(drm_r128_private_t),
 			   DRM_MEM_DRIVER );
 		dev->dev_private = NULL;
 	}
@@ -771,7 +770,7 @@
 	drm_r128_freelist_t *entry;
 	int i;
 
-	dev_priv->head = DRM(alloc)( sizeof(drm_r128_freelist_t),
+	dev_priv->head = drm_alloc( sizeof(drm_r128_freelist_t),
 				     DRM_MEM_DRIVER );
 	if ( dev_priv->head == NULL )
 		return DRM_ERR(ENOMEM);
@@ -783,7 +782,7 @@
 		buf = dma->buflist[i];
 		buf_priv = buf->dev_private;
 
-		entry = DRM(alloc)( sizeof(drm_r128_freelist_t),
+		entry = drm_alloc( sizeof(drm_r128_freelist_t),
 				    DRM_MEM_DRIVER );
 		if ( !entry ) return DRM_ERR(ENOMEM);
 
diff -Nru a/drivers/char/drm/r128_drv.c b/drivers/char/drm/r128_drv.c
--- a/drivers/char/drm/r128_drv.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/char/drm/r128_drv.c	2005-03-01 23:38:54 -08:00
@@ -30,11 +30,93 @@
  */
 
 #include <linux/config.h>
-#include "r128.h"
 #include "drmP.h"
 #include "drm.h"
 #include "r128_drm.h"
 #include "r128_drv.h"
-#include "ati_pcigart.h"
 
-#include "drm_core.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->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[] = {
+	r128_PCI_IDS
+};
+
+extern drm_ioctl_desc_t r128_ioctls[];
+extern int r128_max_ioctl;
+
+static struct drm_driver driver = {
+	.driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL,
+	.dev_priv_size = sizeof(drm_r128_buf_priv_t),
+	.prerelease = r128_driver_prerelease,
+	.pretakedown = r128_driver_pretakedown,
+	.vblank_wait = r128_driver_vblank_wait,
+	.irq_preinstall = r128_driver_irq_preinstall,
+	.irq_postinstall = r128_driver_irq_postinstall,
+	.irq_uninstall = r128_driver_irq_uninstall,
+	.irq_handler = r128_driver_irq_handler,
+	.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 = r128_ioctls,
+	.dma_ioctl = r128_cce_buffers,
+	.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 r128_init(void)
+{
+	driver.num_ioctls = r128_max_ioctl;
+	return drm_init(&driver);
+}
+
+static void __exit r128_exit(void)
+{
+	drm_exit(&driver);
+}
+
+module_init(r128_init);
+module_exit(r128_exit);
+
+MODULE_AUTHOR( DRIVER_AUTHOR );
+MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_LICENSE("GPL and additional rights");
diff -Nru a/drivers/char/drm/r128_drv.h b/drivers/char/drm/r128_drv.h
--- a/drivers/char/drm/r128_drv.h	2005-03-01 23:39:18 -08:00
+++ b/drivers/char/drm/r128_drv.h	2005-03-01 23:39:18 -08:00
@@ -28,12 +28,31 @@
  *    Rickard E. (Rik) Faith <faith@valinux.com>
  *    Kevin E. Martin <martin@valinux.com>
  *    Gareth Hughes <gareth@valinux.com>
- *    Michel Dänzer <daenzerm@student.ethz.ch>
+ *    Michel Dï¿½zer <daenzerm@student.ethz.ch>
  */
 
 #ifndef __R128_DRV_H__
 #define __R128_DRV_H__
 
+/* General customization:
+ */
+#define DRIVER_AUTHOR		"Gareth Hughes, VA Linux Systems Inc."
+
+#define DRIVER_NAME		"r128"
+#define DRIVER_DESC		"ATI Rage 128"
+#define DRIVER_DATE		"20030725"
+
+/* Interface history:
+ *
+ * ??  - ??
+ * 2.4 - Add support for ycbcr textures (no new ioctls)
+ * 2.5 - Add FLIP ioctl, disable FULLSCREEN.
+ */
+#define DRIVER_MAJOR		2
+#define DRIVER_MINOR		5
+#define DRIVER_PATCHLEVEL	0
+
+
 #define GET_RING_HEAD(dev_priv)		R128_READ( R128_PM4_BUFFER_DL_RPTR )
 
 typedef struct drm_r128_freelist {
@@ -148,6 +167,8 @@
 extern void r128_driver_irq_preinstall( drm_device_t *dev );
 extern void r128_driver_irq_postinstall( drm_device_t *dev );
 extern void r128_driver_irq_uninstall( drm_device_t *dev );
+extern void r128_driver_pretakedown(drm_device_t *dev);
+extern void r128_driver_prerelease(drm_device_t *dev, DRMFILE filp);
 
 /* Register definitions, register access macros and drmAddMap constants
  * for Rage 128 kernel driver.
diff -Nru a/drivers/char/drm/r128_irq.c b/drivers/char/drm/r128_irq.c
--- a/drivers/char/drm/r128_irq.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/char/drm/r128_irq.c	2005-03-01 23:39:18 -08:00
@@ -30,7 +30,6 @@
  *    Eric Anholt <anholt@FreeBSD.org>
  */
 
-#include "r128.h"
 #include "drmP.h"
 #include "drm.h"
 #include "r128_drm.h"
@@ -50,7 +49,7 @@
 		R128_WRITE( R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK );
 		atomic_inc(&dev->vbl_received);
 		DRM_WAKEUP(&dev->vbl_queue);
-		DRM(vbl_send_signals)( dev );
+		drm_vbl_send_signals( dev );
 		return IRQ_HANDLED;
 	}
 	return IRQ_NONE;
diff -Nru a/drivers/char/drm/r128_state.c b/drivers/char/drm/r128_state.c
--- a/drivers/char/drm/r128_state.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/char/drm/r128_state.c	2005-03-01 23:38:53 -08:00
@@ -27,12 +27,32 @@
  *    Gareth Hughes <gareth@valinux.com>
  */
 
-#include "r128.h"
 #include "drmP.h"
 #include "drm.h"
 #include "r128_drm.h"
 #include "r128_drv.h"
 
+drm_ioctl_desc_t r128_ioctls[] = {
+	[DRM_IOCTL_NR(DRM_R128_INIT)]       = { r128_cce_init,     1, 1 },
+	[DRM_IOCTL_NR(DRM_R128_CCE_START)]  = { r128_cce_start,    1, 1 },
+	[DRM_IOCTL_NR(DRM_R128_CCE_STOP)]   = { r128_cce_stop,     1, 1 },
+	[DRM_IOCTL_NR(DRM_R128_CCE_RESET)]  = { r128_cce_reset,    1, 1 },
+	[DRM_IOCTL_NR(DRM_R128_CCE_IDLE)]   = { r128_cce_idle,     1, 0 },
+	[DRM_IOCTL_NR(DRM_R128_RESET)]      = { r128_engine_reset, 1, 0 },
+	[DRM_IOCTL_NR(DRM_R128_FULLSCREEN)] = { r128_fullscreen,   1, 0 },
+	[DRM_IOCTL_NR(DRM_R128_SWAP)]       = { r128_cce_swap,     1, 0 },
+	[DRM_IOCTL_NR(DRM_R128_FLIP)]       = { r128_cce_flip,     1, 0 },
+	[DRM_IOCTL_NR(DRM_R128_CLEAR)]      = { r128_cce_clear,    1, 0 },
+	[DRM_IOCTL_NR(DRM_R128_VERTEX)]     = { r128_cce_vertex,   1, 0 },
+	[DRM_IOCTL_NR(DRM_R128_INDICES)]    = { r128_cce_indices,  1, 0 },
+	[DRM_IOCTL_NR(DRM_R128_BLIT)]       = { r128_cce_blit,     1, 0 },
+	[DRM_IOCTL_NR(DRM_R128_DEPTH)]      = { r128_cce_depth,    1, 0 },
+	[DRM_IOCTL_NR(DRM_R128_STIPPLE)]    = { r128_cce_stipple,  1, 0 },
+	[DRM_IOCTL_NR(DRM_R128_INDIRECT)]   = { r128_cce_indirect, 1, 1 },
+	[DRM_IOCTL_NR(DRM_R128_GETPARAM)]   = { r128_getparam, 1, 0 },
+};
+
+int r128_max_ioctl = DRM_ARRAY_SIZE(r128_ioctls);
 
 /* ================================================================
  * CCE hardware state programming functions
@@ -926,24 +946,24 @@
 	}
 
 	buffer_size = depth->n * sizeof(u32);
-	buffer = DRM_MALLOC( buffer_size );
+	buffer = drm_alloc( buffer_size, DRM_MEM_BUFS );
 	if ( buffer == NULL )
 		return DRM_ERR(ENOMEM);
 	if ( DRM_COPY_FROM_USER( buffer, depth->buffer, buffer_size ) ) {
-		DRM_FREE( buffer, buffer_size);
+		drm_free( buffer, buffer_size, DRM_MEM_BUFS);
 		return DRM_ERR(EFAULT);
 	}
 
 	mask_size = depth->n * sizeof(u8);
 	if ( depth->mask ) {
-		mask = DRM_MALLOC( mask_size );
+		mask = drm_alloc( mask_size, DRM_MEM_BUFS );
 		if ( mask == NULL ) {
-			DRM_FREE( buffer, buffer_size );
+			drm_free( buffer, buffer_size, DRM_MEM_BUFS );
 			return DRM_ERR(ENOMEM);
 		}
 		if ( DRM_COPY_FROM_USER( mask, depth->mask, mask_size ) ) {
-			DRM_FREE( buffer, buffer_size );
-			DRM_FREE( mask, mask_size );
+			drm_free( buffer, buffer_size, DRM_MEM_BUFS );
+			drm_free( mask, mask_size, DRM_MEM_BUFS );
 			return DRM_ERR(EFAULT);
 		}
 
@@ -970,7 +990,7 @@
 			}
 		}
 
-		DRM_FREE( mask, mask_size );
+		drm_free( mask, mask_size, DRM_MEM_BUFS );
 	} else {
 		for ( i = 0 ; i < count ; i++, x++ ) {
 			BEGIN_RING( 6 );
@@ -994,7 +1014,7 @@
 		}
 	}
 
-	DRM_FREE( buffer, buffer_size );
+	drm_free( buffer, buffer_size, DRM_MEM_BUFS );
 
 	return 0;
 }
@@ -1016,54 +1036,54 @@
 
 	xbuf_size = count * sizeof(*x);
 	ybuf_size = count * sizeof(*y);
-	x = DRM_MALLOC( xbuf_size );
+	x = drm_alloc( xbuf_size, DRM_MEM_BUFS );
 	if ( x == NULL ) {
 		return DRM_ERR(ENOMEM);
 	}
-	y = DRM_MALLOC( ybuf_size );
+	y = drm_alloc( ybuf_size, DRM_MEM_BUFS );
 	if ( y == NULL ) {
-		DRM_FREE( x, xbuf_size );
+		drm_free( x, xbuf_size, DRM_MEM_BUFS );
 		return DRM_ERR(ENOMEM);
 	}
 	if ( DRM_COPY_FROM_USER( x, depth->x, xbuf_size ) ) {
-		DRM_FREE( x, xbuf_size );
-		DRM_FREE( y, ybuf_size );
+		drm_free( x, xbuf_size, DRM_MEM_BUFS );
+		drm_free( y, ybuf_size, DRM_MEM_BUFS );
 		return DRM_ERR(EFAULT);
 	}
 	if ( DRM_COPY_FROM_USER( y, depth->y, xbuf_size ) ) {
-		DRM_FREE( x, xbuf_size );
-		DRM_FREE( y, ybuf_size );
+		drm_free( x, xbuf_size, DRM_MEM_BUFS );
+		drm_free( y, ybuf_size, DRM_MEM_BUFS );
 		return DRM_ERR(EFAULT);
 	}
 
 	buffer_size = depth->n * sizeof(u32);
-	buffer = DRM_MALLOC( buffer_size );
+	buffer = drm_alloc( buffer_size, DRM_MEM_BUFS );
 	if ( buffer == NULL ) {
-		DRM_FREE( x, xbuf_size );
-		DRM_FREE( y, ybuf_size );
+		drm_free( x, xbuf_size, DRM_MEM_BUFS );
+		drm_free( y, ybuf_size, DRM_MEM_BUFS );
 		return DRM_ERR(ENOMEM);
 	}
 	if ( DRM_COPY_FROM_USER( buffer, depth->buffer, buffer_size ) ) {
-		DRM_FREE( x, xbuf_size );
-		DRM_FREE( y, ybuf_size );
-		DRM_FREE( buffer, buffer_size );
+		drm_free( x, xbuf_size, DRM_MEM_BUFS );
+		drm_free( y, ybuf_size, DRM_MEM_BUFS );
+		drm_free( buffer, buffer_size, DRM_MEM_BUFS );
 		return DRM_ERR(EFAULT);
 	}
 
 	if ( depth->mask ) {
 		mask_size = depth->n * sizeof(u8);
-		mask = DRM_MALLOC( mask_size );
+		mask = drm_alloc( mask_size, DRM_MEM_BUFS );
 		if ( mask == NULL ) {
-			DRM_FREE( x, xbuf_size );
-			DRM_FREE( y, ybuf_size );
-			DRM_FREE( buffer, buffer_size );
+			drm_free( x, xbuf_size, DRM_MEM_BUFS );
+			drm_free( y, ybuf_size, DRM_MEM_BUFS );
+			drm_free( buffer, buffer_size, DRM_MEM_BUFS );
 			return DRM_ERR(ENOMEM);
 		}
 		if ( DRM_COPY_FROM_USER( mask, depth->mask, mask_size ) ) {
-			DRM_FREE( x, xbuf_size );
-			DRM_FREE( y, ybuf_size );
-			DRM_FREE( buffer, buffer_size );
-			DRM_FREE( mask, mask_size );
+			drm_free( x, xbuf_size, DRM_MEM_BUFS  );
+			drm_free( y, ybuf_size, DRM_MEM_BUFS  );
+			drm_free( buffer, buffer_size, DRM_MEM_BUFS  );
+			drm_free( mask, mask_size, DRM_MEM_BUFS  );
 			return DRM_ERR(EFAULT);
 		}
 
@@ -1090,7 +1110,7 @@
 			}
 		}
 
-		DRM_FREE( mask, mask_size );
+		drm_free( mask, mask_size, DRM_MEM_BUFS );
 	} else {
 		for ( i = 0 ; i < count ; i++ ) {
 			BEGIN_RING( 6 );
@@ -1114,9 +1134,9 @@
 		}
 	}
 
-	DRM_FREE( x, xbuf_size );
-	DRM_FREE( y, ybuf_size );
-	DRM_FREE( buffer, buffer_size );
+	drm_free( x, xbuf_size, DRM_MEM_BUFS );
+	drm_free( y, ybuf_size, DRM_MEM_BUFS );
+	drm_free( buffer, buffer_size, DRM_MEM_BUFS );
 
 	return 0;
 }
@@ -1184,23 +1204,23 @@
 
 	xbuf_size = count * sizeof(*x);
 	ybuf_size = count * sizeof(*y);
-	x = DRM_MALLOC( xbuf_size );
+	x = drm_alloc( xbuf_size, DRM_MEM_BUFS );
 	if ( x == NULL ) {
 		return DRM_ERR(ENOMEM);
 	}
-	y = DRM_MALLOC( ybuf_size );
+	y = drm_alloc( ybuf_size, DRM_MEM_BUFS );
 	if ( y == NULL ) {
-		DRM_FREE( x, xbuf_size );
+		drm_free( x, xbuf_size, DRM_MEM_BUFS );
 		return DRM_ERR(ENOMEM);
 	}
 	if ( DRM_COPY_FROM_USER( x, depth->x, xbuf_size ) ) {
-		DRM_FREE( x, xbuf_size );
-		DRM_FREE( y, ybuf_size );
+		drm_free( x, xbuf_size, DRM_MEM_BUFS );
+		drm_free( y, ybuf_size, DRM_MEM_BUFS );
 		return DRM_ERR(EFAULT);
 	}
 	if ( DRM_COPY_FROM_USER( y, depth->y, ybuf_size ) ) {
-		DRM_FREE( x, xbuf_size );
-		DRM_FREE( y, ybuf_size );
+		drm_free( x, xbuf_size, DRM_MEM_BUFS );
+		drm_free( y, ybuf_size, DRM_MEM_BUFS );
 		return DRM_ERR(EFAULT);
 	}
 
@@ -1228,8 +1248,8 @@
 		ADVANCE_RING();
 	}
 
-	DRM_FREE( x, xbuf_size );
-	DRM_FREE( y, ybuf_size );
+	drm_free( x, xbuf_size, DRM_MEM_BUFS );
+	drm_free( y, ybuf_size, DRM_MEM_BUFS );
 
 	return 0;
 }
@@ -1695,7 +1715,7 @@
 	return 0;
 }
 
-static void r128_driver_prerelease(drm_device_t *dev, DRMFILE filp)
+void r128_driver_prerelease(drm_device_t *dev, DRMFILE filp)
 {
 	if ( dev->dev_private ) {
 		drm_r128_private_t *dev_priv = dev->dev_private;
@@ -1705,20 +1725,8 @@
 	}			
 }
 
-static void r128_driver_pretakedown(drm_device_t *dev)
+void r128_driver_pretakedown(drm_device_t *dev)
 {
 	r128_do_cleanup_cce( dev );
 }
 
-void r128_driver_register_fns(drm_device_t *dev)
-{
-	dev->driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL;
-	dev->dev_priv_size = sizeof(drm_r128_buf_priv_t);
-	dev->fn_tbl.prerelease = r128_driver_prerelease;
-	dev->fn_tbl.pretakedown = r128_driver_pretakedown;
-	dev->fn_tbl.vblank_wait = r128_driver_vblank_wait;
-	dev->fn_tbl.irq_preinstall = r128_driver_irq_preinstall;
-	dev->fn_tbl.irq_postinstall = r128_driver_irq_postinstall;
-	dev->fn_tbl.irq_uninstall = r128_driver_irq_uninstall;
-	dev->fn_tbl.irq_handler = r128_driver_irq_handler;
-}
diff -Nru a/drivers/char/drm/radeon.h b/drivers/char/drm/radeon.h
--- a/drivers/char/drm/radeon.h	2005-03-01 23:39:10 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,112 +0,0 @@
-/* radeon.h -- ATI Radeon DRM template customization -*- linux-c -*-
- * Created: Wed Feb 14 17:07:34 2001 by gareth@valinux.com
- *
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- *    Gareth Hughes <gareth@valinux.com>
- *    Keith Whitwell <keith@tungstengraphics.com>
- */
-
-#ifndef __RADEON_H__
-#define __RADEON_H__
-
-/* This remains constant for all DRM template files.
- */
-#define DRM(x) radeon_##x
-
-/* General customization:
- */
-
-#define DRIVER_AUTHOR		"Gareth Hughes, Keith Whitwell, others."
-
-#define DRIVER_NAME		"radeon"
-#define DRIVER_DESC		"ATI Radeon"
-#define DRIVER_DATE		"20020828"
-
-#define DRIVER_MAJOR		1
-#define DRIVER_MINOR		11
-#define DRIVER_PATCHLEVEL	0
-
-/* Interface history:
- *
- * 1.1 - ??
- * 1.2 - Add vertex2 ioctl (keith)
- *     - Add stencil capability to clear ioctl (gareth, keith)
- *     - Increase MAX_TEXTURE_LEVELS (brian)
- * 1.3 - Add cmdbuf ioctl (keith)
- *     - Add support for new radeon packets (keith)
- *     - Add getparam ioctl (keith)
- *     - Add flip-buffers ioctl, deprecate fullscreen foo (keith).
- * 1.4 - Add scratch registers to get_param ioctl.
- * 1.5 - Add r200 packets to cmdbuf ioctl
- *     - Add r200 function to init ioctl
- *     - Add 'scalar2' instruction to cmdbuf
- * 1.6 - Add static GART memory manager
- *       Add irq handler (won't be turned on unless X server knows to)
- *       Add irq ioctls and irq_active getparam.
- *       Add wait command for cmdbuf ioctl
- *       Add GART offset query for getparam
- * 1.7 - Add support for cube map registers: R200_PP_CUBIC_FACES_[0..5]
- *       and R200_PP_CUBIC_OFFSET_F1_[0..5].
- *       Added packets R200_EMIT_PP_CUBIC_FACES_[0..5] and
- *       R200_EMIT_PP_CUBIC_OFFSETS_[0..5].  (brian)
- * 1.8 - Remove need to call cleanup ioctls on last client exit (keith)
- *       Add 'GET' queries for starting additional clients on different VT's.
- * 1.9 - Add DRM_IOCTL_RADEON_CP_RESUME ioctl.
- *       Add texture rectangle support for r100.
- * 1.10- Add SETPARAM ioctl; first parameter to set is FB_LOCATION, which
- *       clients use to tell the DRM where they think the framebuffer is 
- *       located in the card's address space
- * 1.11- Add packet R200_EMIT_RB3D_BLENDCOLOR to support GL_EXT_blend_color
- *       and GL_EXT_blend_[func|equation]_separate on r200
- */
-#define DRIVER_IOCTLS							     \
- [DRM_IOCTL_NR(DRM_IOCTL_DMA)]               = { radeon_cp_buffers,  1, 0 }, \
- [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_INIT)]    = { radeon_cp_init,     1, 1 }, \
- [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_START)]   = { radeon_cp_start,    1, 1 }, \
- [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_STOP)]    = { radeon_cp_stop,     1, 1 }, \
- [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_RESET)]   = { radeon_cp_reset,    1, 1 }, \
- [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_IDLE)]    = { radeon_cp_idle,     1, 0 }, \
- [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_RESUME)]  = { radeon_cp_resume,   1, 0 }, \
- [DRM_IOCTL_NR(DRM_IOCTL_RADEON_RESET)]    = { radeon_engine_reset,  1, 0 }, \
- [DRM_IOCTL_NR(DRM_IOCTL_RADEON_FULLSCREEN)] = { radeon_fullscreen,  1, 0 }, \
- [DRM_IOCTL_NR(DRM_IOCTL_RADEON_SWAP)]       = { radeon_cp_swap,     1, 0 }, \
- [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CLEAR)]      = { radeon_cp_clear,    1, 0 }, \
- [DRM_IOCTL_NR(DRM_IOCTL_RADEON_VERTEX)]     = { radeon_cp_vertex,   1, 0 }, \
- [DRM_IOCTL_NR(DRM_IOCTL_RADEON_INDICES)]    = { radeon_cp_indices,  1, 0 }, \
- [DRM_IOCTL_NR(DRM_IOCTL_RADEON_TEXTURE)]    = { radeon_cp_texture,  1, 0 }, \
- [DRM_IOCTL_NR(DRM_IOCTL_RADEON_STIPPLE)]    = { radeon_cp_stipple,  1, 0 }, \
- [DRM_IOCTL_NR(DRM_IOCTL_RADEON_INDIRECT)]   = { radeon_cp_indirect, 1, 1 }, \
- [DRM_IOCTL_NR(DRM_IOCTL_RADEON_VERTEX2)]    = { radeon_cp_vertex2,  1, 0 }, \
- [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CMDBUF)]     = { radeon_cp_cmdbuf,   1, 0 }, \
- [DRM_IOCTL_NR(DRM_IOCTL_RADEON_GETPARAM)]   = { radeon_cp_getparam, 1, 0 }, \
- [DRM_IOCTL_NR(DRM_IOCTL_RADEON_FLIP)]       = { radeon_cp_flip,     1, 0 }, \
- [DRM_IOCTL_NR(DRM_IOCTL_RADEON_ALLOC)]      = { radeon_mem_alloc,   1, 0 }, \
- [DRM_IOCTL_NR(DRM_IOCTL_RADEON_FREE)]       = { radeon_mem_free,    1, 0 }, \
- [DRM_IOCTL_NR(DRM_IOCTL_RADEON_INIT_HEAP)]  = { radeon_mem_init_heap, 1, 1 }, \
- [DRM_IOCTL_NR(DRM_IOCTL_RADEON_IRQ_EMIT)]   = { radeon_irq_emit,    1, 0 }, \
- [DRM_IOCTL_NR(DRM_IOCTL_RADEON_IRQ_WAIT)]   = { radeon_irq_wait,    1, 0 }, \
- [DRM_IOCTL_NR(DRM_IOCTL_RADEON_SETPARAM)]   = { radeon_cp_setparam, 1, 0 }, \
-
-#endif
diff -Nru a/drivers/char/drm/radeon_cp.c b/drivers/char/drm/radeon_cp.c
--- a/drivers/char/drm/radeon_cp.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/char/drm/radeon_cp.c	2005-03-01 23:38:53 -08:00
@@ -28,7 +28,6 @@
  *    Gareth Hughes <gareth@valinux.com>
  */
 
-#include "radeon.h"
 #include "drmP.h"
 #include "drm.h"
 #include "radeon_drm.h"
@@ -557,6 +556,264 @@
 	{ 0000000000, 0000000000 },
 };
 
+static u32 R300_cp_microcode[][2] = {
+	{ 0x4200e000, 0000000000 },
+	{ 0x4000e000, 0000000000 },
+	{ 0x000000af, 0x00000008 },
+	{ 0x000000b3, 0x00000008 },
+	{ 0x6c5a504f, 0000000000 },
+	{ 0x4f4f497a, 0000000000 },
+	{ 0x5a578288, 0000000000 },
+	{ 0x4f91906a, 0000000000 },
+	{ 0x4f4f4f4f, 0000000000 },
+	{ 0x4fe24f44, 0000000000 },
+	{ 0x4f9c9c9c, 0000000000 },
+	{ 0xdc4f4fde, 0000000000 },
+	{ 0xa1cd4f4f, 0000000000 },
+	{ 0xd29d9d9d, 0000000000 },
+	{ 0x4f0f9fd7, 0000000000 },
+	{ 0x000ca000, 0x00000004 },
+	{ 0x000d0012, 0x00000038 },
+	{ 0x0000e8b4, 0x00000004 },
+	{ 0x000d0014, 0x00000038 },
+	{ 0x0000e8b6, 0x00000004 },
+	{ 0x000d0016, 0x00000038 },
+	{ 0x0000e854, 0x00000004 },
+	{ 0x000d0018, 0x00000038 },
+	{ 0x0000e855, 0x00000004 },
+	{ 0x000d001a, 0x00000038 },
+	{ 0x0000e856, 0x00000004 },
+	{ 0x000d001c, 0x00000038 },
+	{ 0x0000e857, 0x00000004 },
+	{ 0x000d001e, 0x00000038 },
+	{ 0x0000e824, 0x00000004 },
+	{ 0x000d0020, 0x00000038 },
+	{ 0x0000e825, 0x00000004 },
+	{ 0x000d0022, 0x00000038 },
+	{ 0x0000e830, 0x00000004 },
+	{ 0x000d0024, 0x00000038 },
+	{ 0x0000f0c0, 0x00000004 },
+	{ 0x000d0026, 0x00000038 },
+	{ 0x0000f0c1, 0x00000004 },
+	{ 0x000d0028, 0x00000038 },
+	{ 0x0000f041, 0x00000004 },
+	{ 0x000d002a, 0x00000038 },
+	{ 0x0000f184, 0x00000004 },
+	{ 0x000d002c, 0x00000038 },
+	{ 0x0000f185, 0x00000004 },
+	{ 0x000d002e, 0x00000038 },
+	{ 0x0000f186, 0x00000004 },
+	{ 0x000d0030, 0x00000038 },
+	{ 0x0000f187, 0x00000004 },
+	{ 0x000d0032, 0x00000038 },
+	{ 0x0000f180, 0x00000004 },
+	{ 0x000d0034, 0x00000038 },
+	{ 0x0000f393, 0x00000004 },
+	{ 0x000d0036, 0x00000038 },
+	{ 0x0000f38a, 0x00000004 },
+	{ 0x000d0038, 0x00000038 },
+	{ 0x0000f38e, 0x00000004 },
+	{ 0x0000e821, 0x00000004 },
+	{ 0x0140a000, 0x00000004 },
+	{ 0x00000043, 0x00000018 },
+	{ 0x00cce800, 0x00000004 },
+	{ 0x001b0001, 0x00000004 },
+	{ 0x08004800, 0x00000004 },
+	{ 0x001b0001, 0x00000004 },
+	{ 0x08004800, 0x00000004 },
+	{ 0x001b0001, 0x00000004 },
+	{ 0x08004800, 0x00000004 },
+	{ 0x0000003a, 0x00000008 },
+	{ 0x0000a000, 0000000000 },
+	{ 0x02c0a000, 0x00000004 },
+	{ 0x000ca000, 0x00000004 },
+	{ 0x00130000, 0x00000004 },
+	{ 0x000c2000, 0x00000004 },
+	{ 0xc980c045, 0x00000008 },
+	{ 0x2000451d, 0x00000004 },
+	{ 0x0000e580, 0x00000004 },
+	{ 0x000ce581, 0x00000004 },
+	{ 0x08004580, 0x00000004 },
+	{ 0x000ce581, 0x00000004 },
+	{ 0x0000004c, 0x00000008 },
+	{ 0x0000a000, 0000000000 },
+	{ 0x000c2000, 0x00000004 },
+	{ 0x0000e50e, 0x00000004 },
+	{ 0x00032000, 0x00000004 },
+	{ 0x00022056, 0x00000028 },
+	{ 0x00000056, 0x00000024 },
+	{ 0x0800450f, 0x00000004 },
+	{ 0x0000a050, 0x00000008 },
+	{ 0x0000e565, 0x00000004 },
+	{ 0x0000e566, 0x00000004 },
+	{ 0x00000057, 0x00000008 },
+	{ 0x03cca5b4, 0x00000004 },
+	{ 0x05432000, 0x00000004 },
+	{ 0x00022000, 0x00000004 },
+	{ 0x4ccce063, 0x00000030 },
+	{ 0x08274565, 0x00000004 },
+	{ 0x00000063, 0x00000030 },
+	{ 0x08004564, 0x00000004 },
+	{ 0x0000e566, 0x00000004 },
+	{ 0x0000005a, 0x00000008 },
+	{ 0x00802066, 0x00000010 },
+	{ 0x00202000, 0x00000004 },
+	{ 0x001b00ff, 0x00000004 },
+	{ 0x01000069, 0x00000010 },
+	{ 0x001f2000, 0x00000004 },
+	{ 0x001c00ff, 0x00000004 },
+	{ 0000000000, 0x0000000c },
+	{ 0x00000085, 0x00000030 },
+	{ 0x0000005a, 0x00000008 },
+	{ 0x0000e576, 0x00000004 },
+	{ 0x000ca000, 0x00000004 },
+	{ 0x00012000, 0x00000004 },
+	{ 0x00082000, 0x00000004 },
+	{ 0x1800650e, 0x00000004 },
+	{ 0x00092000, 0x00000004 },
+	{ 0x000a2000, 0x00000004 },
+	{ 0x000f0000, 0x00000004 },
+	{ 0x00400000, 0x00000004 },
+	{ 0x00000079, 0x00000018 },
+	{ 0x0000e563, 0x00000004 },
+	{ 0x00c0e5f9, 0x000000c2 },
+	{ 0x0000006e, 0x00000008 },
+	{ 0x0000a06e, 0x00000008 },
+	{ 0x0000e576, 0x00000004 },
+	{ 0x0000e577, 0x00000004 },
+	{ 0x0000e50e, 0x00000004 },
+	{ 0x0000e50f, 0x00000004 },
+	{ 0x0140a000, 0x00000004 },
+	{ 0x0000007c, 0x00000018 },
+	{ 0x00c0e5f9, 0x000000c2 },
+	{ 0x0000007c, 0x00000008 },
+	{ 0x0014e50e, 0x00000004 },
+	{ 0x0040e50f, 0x00000004 },
+	{ 0x00c0007f, 0x00000008 },
+	{ 0x0000e570, 0x00000004 },
+	{ 0x0000e571, 0x00000004 },
+	{ 0x0000e572, 0x0000000c },
+	{ 0x0000a000, 0x00000004 },
+	{ 0x0140a000, 0x00000004 },
+	{ 0x0000e568, 0x00000004 },
+	{ 0x000c2000, 0x00000004 },
+	{ 0x00000089, 0x00000018 },
+	{ 0x000b0000, 0x00000004 },
+	{ 0x18c0e562, 0x00000004 },
+	{ 0x0000008b, 0x00000008 },
+	{ 0x00c0008a, 0x00000008 },
+	{ 0x000700e4, 0x00000004 },
+	{ 0x00000097, 0x00000038 },
+	{ 0x000ca099, 0x00000030 },
+	{ 0x080045bb, 0x00000004 },
+	{ 0x000c209a, 0x00000030 },
+	{ 0x0800e5bc, 0000000000 },
+	{ 0x0000e5bb, 0x00000004 },
+	{ 0x0000e5bc, 0000000000 },
+	{ 0x00120000, 0x0000000c },
+	{ 0x00120000, 0x00000004 },
+	{ 0x001b0002, 0x0000000c },
+	{ 0x0000a000, 0x00000004 },
+	{ 0x0000e821, 0x00000004 },
+	{ 0x0000e800, 0000000000 },
+	{ 0x0000e821, 0x00000004 },
+	{ 0x0000e82e, 0000000000 },
+	{ 0x02cca000, 0x00000004 },
+	{ 0x00140000, 0x00000004 },
+	{ 0x000ce1cc, 0x00000004 },
+	{ 0x050de1cd, 0x00000004 },
+	{ 0x000000a7, 0x00000020 },
+	{ 0x4200e000, 0000000000 },
+	{ 0x000000ae, 0x00000038 },
+	{ 0x000ca000, 0x00000004 },
+	{ 0x00140000, 0x00000004 },
+	{ 0x000c2000, 0x00000004 },
+	{ 0x00160000, 0x00000004 },
+	{ 0x700ce000, 0x00000004 },
+	{ 0x001400aa, 0x00000008 },
+	{ 0x4000e000, 0000000000 },
+	{ 0x02400000, 0x00000004 },
+	{ 0x400ee000, 0x00000004 },
+	{ 0x02400000, 0x00000004 },
+	{ 0x4000e000, 0000000000 },
+	{ 0x000c2000, 0x00000004 },
+	{ 0x0240e51b, 0x00000004 },
+	{ 0x0080e50a, 0x00000005 },
+	{ 0x0080e50b, 0x00000005 },
+	{ 0x00220000, 0x00000004 },
+	{ 0x000700e4, 0x00000004 },
+	{ 0x000000c1, 0x00000038 },
+	{ 0x000c209a, 0x00000030 },
+	{ 0x0880e5bd, 0x00000005 },
+	{ 0x000c2099, 0x00000030 },
+	{ 0x0800e5bb, 0x00000005 },
+	{ 0x000c209a, 0x00000030 },
+	{ 0x0880e5bc, 0x00000005 },
+	{ 0x000000c4, 0x00000008 },
+	{ 0x0080e5bd, 0x00000005 },
+	{ 0x0000e5bb, 0x00000005 },
+	{ 0x0080e5bc, 0x00000005 },
+	{ 0x00210000, 0x00000004 },
+	{ 0x02800000, 0x00000004 },
+	{ 0x00c000c8, 0x00000018 },
+	{ 0x4180e000, 0x00000040 },
+	{ 0x000000ca, 0x00000024 },
+	{ 0x01000000, 0x0000000c },
+	{ 0x0100e51d, 0x0000000c },
+	{ 0x000045bb, 0x00000004 },
+	{ 0x000080c4, 0x00000008 },
+	{ 0x0000f3ce, 0x00000004 },
+	{ 0x0140a000, 0x00000004 },
+	{ 0x00cc2000, 0x00000004 },
+	{ 0x08c053cf, 0x00000040 },
+	{ 0x00008000, 0000000000 },
+	{ 0x0000f3d2, 0x00000004 },
+	{ 0x0140a000, 0x00000004 },
+	{ 0x00cc2000, 0x00000004 },
+	{ 0x08c053d3, 0x00000040 },
+	{ 0x00008000, 0000000000 },
+	{ 0x0000f39d, 0x00000004 },
+	{ 0x0140a000, 0x00000004 },
+	{ 0x00cc2000, 0x00000004 },
+	{ 0x08c0539e, 0x00000040 },
+	{ 0x00008000, 0000000000 },
+	{ 0x03c00830, 0x00000004 },
+	{ 0x4200e000, 0000000000 },
+	{ 0x0000a000, 0x00000004 },
+	{ 0x200045e0, 0x00000004 },
+	{ 0x0000e5e1, 0000000000 },
+	{ 0x00000001, 0000000000 },
+	{ 0x000700e1, 0x00000004 },
+	{ 0x0800e394, 0000000000 },
+	{ 0000000000, 0000000000 },
+	{ 0000000000, 0000000000 },
+	{ 0000000000, 0000000000 },
+	{ 0000000000, 0000000000 },
+	{ 0000000000, 0000000000 },
+	{ 0000000000, 0000000000 },
+	{ 0000000000, 0000000000 },
+	{ 0000000000, 0000000000 },
+	{ 0000000000, 0000000000 },
+	{ 0000000000, 0000000000 },
+	{ 0000000000, 0000000000 },
+	{ 0000000000, 0000000000 },
+	{ 0000000000, 0000000000 },
+	{ 0000000000, 0000000000 },
+	{ 0000000000, 0000000000 },
+	{ 0000000000, 0000000000 },
+	{ 0000000000, 0000000000 },
+	{ 0000000000, 0000000000 },
+	{ 0000000000, 0000000000 },
+	{ 0000000000, 0000000000 },
+	{ 0000000000, 0000000000 },
+	{ 0000000000, 0000000000 },
+	{ 0000000000, 0000000000 },
+	{ 0000000000, 0000000000 },
+	{ 0000000000, 0000000000 },
+	{ 0000000000, 0000000000 },
+	{ 0000000000, 0000000000 },
+	{ 0000000000, 0000000000 },
+};
 
 int RADEON_READ_PLL(drm_device_t *dev, int addr)
 {
@@ -681,8 +938,7 @@
 
 	RADEON_WRITE( RADEON_CP_ME_RAM_ADDR, 0 );
 
-	if (dev_priv->is_r200)
-	{
+	if (dev_priv->microcode_version==UCODE_R200) {
 		DRM_INFO("Loading R200 Microcode\n");
 		for ( i = 0 ; i < 256 ; i++ ) 
 		{
@@ -691,9 +947,16 @@
 			RADEON_WRITE( RADEON_CP_ME_RAM_DATAL,
 				      R200_cp_microcode[i][0] );
 		}
-	}
-	else
-	{
+	} else if (dev_priv->microcode_version==UCODE_R300) {
+		DRM_INFO("Loading R300 Microcode\n");
+		for ( i = 0 ; i < 256 ; i++ ) 
+		{
+			RADEON_WRITE( RADEON_CP_ME_RAM_DATAH,
+				      R300_cp_microcode[i][1] );
+			RADEON_WRITE( RADEON_CP_ME_RAM_DATAL,
+				      R300_cp_microcode[i][0] );
+		}
+	} else {
 		for ( i = 0 ; i < 256 ; i++ ) {
 			RADEON_WRITE( RADEON_CP_ME_RAM_DATAH,
 				      radeon_cp_microcode[i][1] );
@@ -1003,15 +1266,9 @@
 
 static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
 {
-	drm_radeon_private_t *dev_priv;
+	drm_radeon_private_t *dev_priv = dev->dev_private;;
 	DRM_DEBUG( "\n" );
 
-	dev_priv = DRM(alloc)( sizeof(drm_radeon_private_t), DRM_MEM_DRIVER );
-	if ( dev_priv == NULL )
-		return DRM_ERR(ENOMEM);
-
-	memset( dev_priv, 0, sizeof(drm_radeon_private_t) );
-
 	dev_priv->is_pci = init->is_pci;
 
 	if ( dev_priv->is_pci && !dev->sg ) {
@@ -1030,7 +1287,17 @@
 		return DRM_ERR(EINVAL);
 	}
 
-	dev_priv->is_r200 = (init->func == RADEON_INIT_R200_CP);
+	switch(init->func) {
+	case RADEON_INIT_R200_CP:
+		dev_priv->microcode_version=UCODE_R200;
+		break;
+	case RADEON_INIT_R300_CP:
+		dev_priv->microcode_version=UCODE_R300;
+		break;
+	default:
+		dev_priv->microcode_version=UCODE_R100;
+	}
+	
 	dev_priv->do_boxes = 0;
 	dev_priv->cp_mode = init->cp_mode;
 
@@ -1079,7 +1346,7 @@
 	 */
 	dev_priv->depth_clear.rb3d_cntl = (RADEON_PLANE_MASK_ENABLE |
 					   (dev_priv->color_fmt << 10) |
-					   (1<<15));
+					   (dev_priv->microcode_version == UCODE_R100 ? RADEON_ZBLOCK16 : 0));
 
 	dev_priv->depth_clear.rb3d_zstencilcntl = 
 		(dev_priv->depth_fmt |
@@ -1233,7 +1500,7 @@
 	dev_priv->ring.end = ((u32 *)dev_priv->cp_ring->handle
 			      + init->ring_size / sizeof(u32));
 	dev_priv->ring.size = init->ring_size;
-	dev_priv->ring.size_l2qw = DRM(order)( init->ring_size / 8 );
+	dev_priv->ring.size_l2qw = drm_order( init->ring_size / 8 );
 
 	dev_priv->ring.tail_mask =
 		(dev_priv->ring.size / sizeof(u32)) - 1;
@@ -1247,7 +1514,7 @@
 	} else
 #endif
 	{
-		if (!DRM(ati_pcigart_init)( dev, &dev_priv->phys_pci_gart,
+		if (!drm_ati_pcigart_init( dev, &dev_priv->phys_pci_gart,
 					    &dev_priv->bus_pci_gart)) {
 			DRM_ERROR( "failed to init PCI GART!\n" );
 			dev->dev_private = (void *)dev_priv;
@@ -1273,38 +1540,37 @@
 
 int radeon_do_cleanup_cp( drm_device_t *dev )
 {
+	drm_radeon_private_t *dev_priv = dev->dev_private;
 	DRM_DEBUG( "\n" );
 
 	/* Make sure interrupts are disabled here because the uninstall ioctl
 	 * may not have been called from userspace and after dev_private
 	 * is freed, it's too late.
 	 */
-	if ( dev->irq_enabled ) DRM(irq_uninstall)(dev);
-
-	if ( dev->dev_private ) {
-		drm_radeon_private_t *dev_priv = dev->dev_private;
+	if ( dev->irq_enabled ) drm_irq_uninstall(dev);
 
 #if __OS_HAS_AGP
-		if ( !dev_priv->is_pci ) {
-			if ( dev_priv->cp_ring != NULL )
-				drm_core_ioremapfree( dev_priv->cp_ring, dev );
-			if ( dev_priv->ring_rptr != NULL )
-				drm_core_ioremapfree( dev_priv->ring_rptr, dev );
-			if ( dev->agp_buffer_map != NULL )
-				drm_core_ioremapfree( dev->agp_buffer_map, dev );
-		} else
-#endif
+	if ( !dev_priv->is_pci ) {
+		if ( dev_priv->cp_ring != NULL )
+			drm_core_ioremapfree( dev_priv->cp_ring, dev );
+		if ( dev_priv->ring_rptr != NULL )
+			drm_core_ioremapfree( dev_priv->ring_rptr, dev );
+		if ( dev->agp_buffer_map != NULL )
 		{
-			if (!DRM(ati_pcigart_cleanup)( dev,
-						dev_priv->phys_pci_gart,
-						dev_priv->bus_pci_gart ))
-				DRM_ERROR( "failed to cleanup PCI GART!\n" );
+			drm_core_ioremapfree( dev->agp_buffer_map, dev );
+			dev->agp_buffer_map = NULL;
 		}
-
-		DRM(free)( dev->dev_private, sizeof(drm_radeon_private_t),
-			   DRM_MEM_DRIVER );
-		dev->dev_private = NULL;
+	} else
+#endif
+	{
+		if (!drm_ati_pcigart_cleanup( dev,
+					      dev_priv->phys_pci_gart,
+					      dev_priv->bus_pci_gart ))
+			DRM_ERROR( "failed to cleanup PCI GART!\n" );
 	}
+	
+	/* only clear to the start of flags */
+	memset(dev_priv, 0, offsetof(drm_radeon_private_t, flags));
 
 	return 0;
 }
@@ -1361,6 +1627,7 @@
 	switch ( init.func ) {
 	case RADEON_INIT_CP:
 	case RADEON_INIT_R200_CP:
+	case RADEON_INIT_R300_CP:
 		return radeon_do_init_cp( dev, &init );
 	case RADEON_CLEANUP_CP:
 		return radeon_do_cleanup_cp( dev );
@@ -1441,7 +1708,7 @@
 void radeon_do_release( drm_device_t *dev )
 {
 	drm_radeon_private_t *dev_priv = dev->dev_private;
-	int ret;
+	int i, ret;
 
 	if (dev_priv) {
 		if (dev_priv->cp_running) {
@@ -1459,7 +1726,16 @@
 		}
 
 		/* Disable *all* interrupts */
-		RADEON_WRITE( RADEON_GEN_INT_CNTL, 0 );
+		if (dev_priv->mmio)	/* remove this after permanent addmaps */
+			RADEON_WRITE( RADEON_GEN_INT_CNTL, 0 );
+
+		if (dev_priv->mmio) {/* remove all surfaces */
+			for (i = 0; i < RADEON_MAX_SURFACES; i++) {
+				RADEON_WRITE(RADEON_SURFACE0_INFO + 16*i, 0);
+				RADEON_WRITE(RADEON_SURFACE0_LOWER_BOUND + 16*i, 0);
+				RADEON_WRITE(RADEON_SURFACE0_UPPER_BOUND + 16*i, 0);
+			}
+		}
 
 		/* Free memory heap structures */
 		radeon_mem_takedown( &(dev_priv->gart_heap) );
@@ -1742,4 +2018,43 @@
 	DRM_COPY_TO_USER_IOCTL( argp, d, sizeof(d) );
 
 	return ret;
+}
+
+int radeon_driver_preinit(struct drm_device *dev, unsigned long flags)
+{
+	drm_radeon_private_t *dev_priv;
+	int ret = 0;
+
+	dev_priv = drm_alloc(sizeof(drm_radeon_private_t), DRM_MEM_DRIVER);
+	if (dev_priv == NULL)
+		return DRM_ERR(ENOMEM);
+
+	memset(dev_priv, 0, sizeof(drm_radeon_private_t));
+	dev->dev_private = (void *)dev_priv;
+	dev_priv->flags = flags;
+
+	switch (flags & CHIP_FAMILY_MASK) {
+	case CHIP_R100:
+	case CHIP_RV200:
+	case CHIP_R200:
+	case CHIP_R300:
+		dev_priv->flags |= CHIP_HAS_HIERZ;
+		break;
+	default:
+	/* all other chips have no hierarchical z buffer */
+		break;
+	}
+	return ret;
+}
+
+int radeon_driver_postcleanup(struct drm_device *dev)
+{
+	drm_radeon_private_t *dev_priv = dev->dev_private;
+
+	DRM_DEBUG("\n");
+
+	drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER);
+
+	dev->dev_private = NULL;
+	return 0;
 }
diff -Nru a/drivers/char/drm/radeon_drm.h b/drivers/char/drm/radeon_drm.h
--- a/drivers/char/drm/radeon_drm.h	2005-03-01 23:39:07 -08:00
+++ b/drivers/char/drm/radeon_drm.h	2005-03-01 23:39:07 -08:00
@@ -145,7 +145,8 @@
 #define RADEON_EMIT_PP_TEX_SIZE_1                   74
 #define RADEON_EMIT_PP_TEX_SIZE_2                   75
 #define R200_EMIT_RB3D_BLENDCOLOR                   76
-#define RADEON_MAX_STATE_PACKETS                    77
+#define R200_EMIT_TCL_POINT_SPRITE_CNTL             77
+#define RADEON_MAX_STATE_PACKETS                    78
 
 
 /* Commands understood by cmd_buffer ioctl.  More can be added but
@@ -192,7 +193,10 @@
 #define RADEON_FRONT			0x1
 #define RADEON_BACK			0x2
 #define RADEON_DEPTH			0x4
-#define RADEON_STENCIL                  0x8
+#define RADEON_STENCIL			0x8
+#define RADEON_CLEAR_FASTZ		0x80000000
+#define RADEON_USE_HIERZ		0x40000000
+#define RADEON_USE_COMP_ZBUF		0x20000000
 
 /* Primitive types
  */
@@ -227,6 +231,8 @@
 #define RADEON_MAX_TEXTURE_LEVELS	12
 #define RADEON_MAX_TEXTURE_UNITS	3
 
+#define RADEON_MAX_SURFACES		8
+
 /* Blits have strict offset rules.  All blit offset must be aligned on
  * a 1K-byte boundary.
  */
@@ -361,6 +367,7 @@
         int pfState;                /* number of 3d windows (0,1,2ormore) */
         int pfCurrentPage;	    /* which buffer is being displayed? */
 	int crtc2_base;		    /* CRTC2 frame offset */
+	int tiling_enabled;	/* set by drm, read by 2d + 3d clients */
 } drm_radeon_sarea_t;
 
 
@@ -399,6 +406,8 @@
 #define DRM_RADEON_IRQ_WAIT   0x17
 #define DRM_RADEON_CP_RESUME  0x18
 #define DRM_RADEON_SETPARAM   0x19
+#define DRM_RADEON_SURF_ALLOC 0x1a
+#define DRM_RADEON_SURF_FREE  0x1b
 
 #define DRM_IOCTL_RADEON_CP_INIT    DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_CP_INIT, drm_radeon_init_t)
 #define DRM_IOCTL_RADEON_CP_START   DRM_IO(  DRM_COMMAND_BASE + DRM_RADEON_CP_START)
@@ -425,12 +434,15 @@
 #define DRM_IOCTL_RADEON_IRQ_WAIT   DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_IRQ_WAIT, drm_radeon_irq_wait_t)
 #define DRM_IOCTL_RADEON_CP_RESUME  DRM_IO(  DRM_COMMAND_BASE + DRM_RADEON_CP_RESUME)
 #define DRM_IOCTL_RADEON_SETPARAM   DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_SETPARAM, drm_radeon_setparam_t)
+#define DRM_IOCTL_RADEON_SURF_ALLOC DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_SURF_ALLOC, drm_radeon_surface_alloc_t)
+#define DRM_IOCTL_RADEON_SURF_FREE  DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_SURF_FREE, drm_radeon_surface_free_t)
 
 typedef struct drm_radeon_init {
 	enum {
 		RADEON_INIT_CP    = 0x01,
 		RADEON_CLEANUP_CP = 0x02,
-		RADEON_INIT_R200_CP = 0x03
+		RADEON_INIT_R200_CP = 0x03,
+		RADEON_INIT_R300_CP = 0x04
 	} func;
 	unsigned long sarea_priv_offset;
 	int is_pci;
@@ -623,7 +635,19 @@
 	int64_t      value;
 } drm_radeon_setparam_t;
 
-#define RADEON_SETPARAM_FB_LOCATION    1 /* determined framebuffer location */
+#define RADEON_SETPARAM_FB_LOCATION    1	/* determined framebuffer location */
+#define RADEON_SETPARAM_SWITCH_TILING  2	/* enable/disable color tiling */
+
+/* 1.14: Clients can allocate/free a surface
+ */
+typedef struct drm_radeon_surface_alloc {
+	unsigned int address;
+	unsigned int size;
+	unsigned int flags;
+} drm_radeon_surface_alloc_t;
 
+typedef struct drm_radeon_surface_free {
+	unsigned int address;
+} drm_radeon_surface_free_t;
 
 #endif
diff -Nru a/drivers/char/drm/radeon_drv.c b/drivers/char/drm/radeon_drv.c
--- a/drivers/char/drm/radeon_drv.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/char/drm/radeon_drv.c	2005-03-01 23:39:08 -08:00
@@ -31,11 +31,97 @@
 
 
 #include <linux/config.h>
-#include "radeon.h"
 #include "drmP.h"
 #include "drm.h"
 #include "radeon_drm.h"
 #include "radeon_drv.h"
-#include "ati_pcigart.h"
 
-#include "drm_core.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->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[] = {
+	radeon_PCI_IDS
+};
+
+extern drm_ioctl_desc_t radeon_ioctls[];
+extern int radeon_max_ioctl;
+
+static struct drm_driver driver = {
+	.driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL,
+	.dev_priv_size = sizeof(drm_radeon_buf_priv_t),
+	.preinit = radeon_driver_preinit,
+	.postcleanup = radeon_driver_postcleanup,
+	.prerelease = radeon_driver_prerelease,
+	.pretakedown = radeon_driver_pretakedown,
+	.open_helper = radeon_driver_open_helper,
+	.vblank_wait = radeon_driver_vblank_wait,
+	.irq_preinstall = radeon_driver_irq_preinstall,
+	.irq_postinstall = radeon_driver_irq_postinstall,
+	.irq_uninstall = radeon_driver_irq_uninstall,
+	.irq_handler = radeon_driver_irq_handler,
+	.free_filp_priv = radeon_driver_free_filp_priv,
+	.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 = radeon_ioctls,
+	.dma_ioctl = radeon_cp_buffers,
+	.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 radeon_init(void)
+{
+	driver.num_ioctls = radeon_max_ioctl;
+	return drm_init(&driver);
+}
+
+static void __exit radeon_exit(void)
+{
+	drm_exit(&driver);
+}
+
+module_init(radeon_init);
+module_exit(radeon_exit);
+
+MODULE_AUTHOR( DRIVER_AUTHOR );
+MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_LICENSE("GPL and additional rights");
diff -Nru a/drivers/char/drm/radeon_drv.h b/drivers/char/drm/radeon_drv.h
--- a/drivers/char/drm/radeon_drv.h	2005-03-01 23:38:57 -08:00
+++ b/drivers/char/drm/radeon_drv.h	2005-03-01 23:38:57 -08:00
@@ -31,9 +31,100 @@
 #ifndef __RADEON_DRV_H__
 #define __RADEON_DRV_H__
 
+/* General customization:
+ */
+
+#define DRIVER_AUTHOR		"Gareth Hughes, Keith Whitwell, others."
+
+#define DRIVER_NAME		"radeon"
+#define DRIVER_DESC		"ATI Radeon"
+#define DRIVER_DATE		"20050125"
+
+/* Interface history:
+ *
+ * 1.1 - ??
+ * 1.2 - Add vertex2 ioctl (keith)
+ *     - Add stencil capability to clear ioctl (gareth, keith)
+ *     - Increase MAX_TEXTURE_LEVELS (brian)
+ * 1.3 - Add cmdbuf ioctl (keith)
+ *     - Add support for new radeon packets (keith)
+ *     - Add getparam ioctl (keith)
+ *     - Add flip-buffers ioctl, deprecate fullscreen foo (keith).
+ * 1.4 - Add scratch registers to get_param ioctl.
+ * 1.5 - Add r200 packets to cmdbuf ioctl
+ *     - Add r200 function to init ioctl
+ *     - Add 'scalar2' instruction to cmdbuf
+ * 1.6 - Add static GART memory manager
+ *       Add irq handler (won't be turned on unless X server knows to)
+ *       Add irq ioctls and irq_active getparam.
+ *       Add wait command for cmdbuf ioctl
+ *       Add GART offset query for getparam
+ * 1.7 - Add support for cube map registers: R200_PP_CUBIC_FACES_[0..5]
+ *       and R200_PP_CUBIC_OFFSET_F1_[0..5].
+ *       Added packets R200_EMIT_PP_CUBIC_FACES_[0..5] and
+ *       R200_EMIT_PP_CUBIC_OFFSETS_[0..5].  (brian)
+ * 1.8 - Remove need to call cleanup ioctls on last client exit (keith)
+ *       Add 'GET' queries for starting additional clients on different VT's.
+ * 1.9 - Add DRM_IOCTL_RADEON_CP_RESUME ioctl.
+ *       Add texture rectangle support for r100.
+ * 1.10- Add SETPARAM ioctl; first parameter to set is FB_LOCATION, which
+ *       clients use to tell the DRM where they think the framebuffer is 
+ *       located in the card's address space
+ * 1.11- Add packet R200_EMIT_RB3D_BLENDCOLOR to support GL_EXT_blend_color
+ *       and GL_EXT_blend_[func|equation]_separate on r200
+ * 1.12- Add R300 CP microcode support - this just loads the CP on r300
+ *       (No 3D support yet - just microcode loading)
+ * 1.13- Add packet R200_EMIT_TCL_POINT_SPRITE_CNTL for ARB_point_parameters
+ *     - Add hyperz support, add hyperz flags to clear ioctl.
+ * 1.14- Add support for color tiling
+ *     - Add R100/R200 surface allocation/free support
+ */
+#define DRIVER_MAJOR		1
+#define DRIVER_MINOR		14
+#define DRIVER_PATCHLEVEL	0
+
 #define GET_RING_HEAD(dev_priv)		DRM_READ32(  (dev_priv)->ring_rptr, 0 )
 #define SET_RING_HEAD(dev_priv,val)	DRM_WRITE32( (dev_priv)->ring_rptr, 0, (val) )
 
+/*
+ * Radeon chip families
+ */
+enum radeon_family {
+	CHIP_R100,
+	CHIP_RS100,
+	CHIP_RV100,
+	CHIP_R200,
+	CHIP_RV200,
+	CHIP_RS200,
+	CHIP_R250,
+	CHIP_RS250,
+	CHIP_RV250,
+	CHIP_RV280,
+	CHIP_R300,
+	CHIP_RS300,
+	CHIP_RV350,
+	CHIP_LAST,
+};
+
+enum radeon_cp_microcode_version {
+	UCODE_R100,
+	UCODE_R200,
+	UCODE_R300,
+};
+
+/*
+ * Chip flags
+ */
+enum radeon_chip_flags {
+	CHIP_FAMILY_MASK = 0x0000ffffUL,
+	CHIP_FLAGS_MASK = 0xffff0000UL,
+	CHIP_IS_MOBILITY = 0x00010000UL,
+	CHIP_IS_IGP = 0x00020000UL,
+	CHIP_SINGLE_CRTC = 0x00040000UL,
+	CHIP_IS_AGP = 0x00080000UL,
+	CHIP_HAS_HIERZ = 0x00100000UL, 
+};
+
 typedef struct drm_radeon_freelist {
    	unsigned int age;
    	drm_buf_t *buf;
@@ -72,6 +163,21 @@
 	DRMFILE filp;		/* 0: free, -1: heap, other: real files */
 };
 
+struct radeon_surface {
+	int refcount;
+	u32 lower;
+	u32 upper;
+	u32 flags;
+};
+
+struct radeon_virt_surface {
+	int surface_index;
+	u32 lower;
+	u32 upper;
+	u32 flags;
+	DRMFILE filp;
+};
+
 typedef struct drm_radeon_private {
 	drm_radeon_ring_buffer_t ring;
 	drm_radeon_sarea_t *sarea_priv;
@@ -93,7 +199,7 @@
 
 	int usec_timeout;
 
-	int is_r200;
+	int microcode_version;
 
 	int is_pci;
 	unsigned long phys_pci_gart;
@@ -150,6 +256,11 @@
    	wait_queue_head_t swi_queue;
    	atomic_t swi_emitted;
 
+	struct radeon_surface surfaces[RADEON_MAX_SURFACES];
+	struct radeon_virt_surface virt_surfaces[2*RADEON_MAX_SURFACES];
+
+	/* starting from here on, data is preserved accross an open */
+	uint32_t flags;		/* see radeon_chip_flags */
 } drm_radeon_private_t;
 
 typedef struct drm_radeon_buf_priv {
@@ -176,6 +287,9 @@
 extern int radeon_do_cleanup_cp( drm_device_t *dev );
 extern int radeon_do_cleanup_pageflip( drm_device_t *dev );
 
+extern int radeon_driver_preinit(struct drm_device *dev, unsigned long flags);
+extern int radeon_driver_postcleanup(struct drm_device *dev);
+
 				/* radeon_state.c */
 extern int radeon_cp_clear( DRM_IOCTL_ARGS );
 extern int radeon_cp_swap( DRM_IOCTL_ARGS );
@@ -195,6 +309,8 @@
 extern int radeon_mem_init_heap( DRM_IOCTL_ARGS );
 extern void radeon_mem_takedown( struct mem_block **heap );
 extern void radeon_mem_release( DRMFILE filp, struct mem_block *heap );
+extern int radeon_surface_alloc(DRM_IOCTL_ARGS);
+extern int radeon_surface_free(DRM_IOCTL_ARGS);
 
 				/* radeon_irq.c */
 extern int radeon_irq_emit( DRM_IOCTL_ARGS );
@@ -210,6 +326,14 @@
 extern void radeon_driver_irq_preinstall( drm_device_t *dev );
 extern void radeon_driver_irq_postinstall( drm_device_t *dev );
 extern void radeon_driver_irq_uninstall( drm_device_t *dev );
+extern void radeon_driver_prerelease(drm_device_t *dev, DRMFILE filp);
+extern void radeon_driver_pretakedown(drm_device_t *dev);
+extern int radeon_driver_open_helper(drm_device_t *dev, drm_file_t *filp_priv);
+extern void radeon_driver_free_filp_priv(drm_device_t *dev, drm_file_t *filp_priv);
+
+extern int radeon_preinit( struct drm_device *dev, unsigned long flags );
+extern int radeon_postinit( struct drm_device *dev, unsigned long flags );
+extern int radeon_postcleanup( struct drm_device *dev );
 
 /* Flags for stats.boxes
  */
@@ -361,7 +485,9 @@
 #	define RADEON_ROP_ENABLE		(1 << 6)
 #	define RADEON_STENCIL_ENABLE		(1 << 7)
 #	define RADEON_Z_ENABLE			(1 << 8)
+#	define RADEON_ZBLOCK16			(1 << 15)
 #define RADEON_RB3D_DEPTHOFFSET		0x1c24
+#define RADEON_RB3D_DEPTHCLEARVALUE	0x3230
 #define RADEON_RB3D_DEPTHPITCH		0x1c28
 #define RADEON_RB3D_PLANEMASK		0x1d84
 #define RADEON_RB3D_STENCILREFMASK	0x1d7c
@@ -374,11 +500,15 @@
 #define RADEON_RB3D_ZSTENCILCNTL	0x1c2c
 #	define RADEON_Z_TEST_MASK		(7 << 4)
 #	define RADEON_Z_TEST_ALWAYS		(7 << 4)
+#	define RADEON_Z_HIERARCHY_ENABLE	(1 << 8)
 #	define RADEON_STENCIL_TEST_ALWAYS	(7 << 12)
 #	define RADEON_STENCIL_S_FAIL_REPLACE	(2 << 16)
 #	define RADEON_STENCIL_ZPASS_REPLACE	(2 << 20)
 #	define RADEON_STENCIL_ZFAIL_REPLACE	(2 << 24)
+#	define RADEON_Z_COMPRESSION_ENABLE	(1 << 28)
+#	define RADEON_FORCE_Z_DIRTY		(1 << 29)
 #	define RADEON_Z_WRITE_ENABLE		(1 << 30)
+#	define RADEON_Z_DECOMPRESSION_ENABLE	(1 << 31)
 #define RADEON_RBBM_SOFT_RESET		0x00f0
 #	define RADEON_SOFT_RESET_CP		(1 <<  0)
 #	define RADEON_SOFT_RESET_HI		(1 <<  1)
@@ -457,6 +587,7 @@
 #	define RADEON_SURF_TILE_MODE_16BIT_Z	(3 << 16)
 #define RADEON_SURFACE0_LOWER_BOUND	0x0b04
 #define RADEON_SURFACE0_UPPER_BOUND	0x0b08
+#	define RADEON_SURF_ADDRESS_FIXED_MASK	(0x3ff << 0)
 #define RADEON_SURFACE1_INFO		0x0b1c
 #define RADEON_SURFACE1_LOWER_BOUND	0x0b14
 #define RADEON_SURFACE1_UPPER_BOUND	0x0b18
@@ -486,7 +617,7 @@
 #	define RADEON_WAIT_3D_IDLECLEAN		(1 << 17)
 #	define RADEON_WAIT_HOST_IDLECLEAN	(1 << 18)
 
-#define RADEON_RB3D_ZMASKOFFSET		0x1c34
+#define RADEON_RB3D_ZMASKOFFSET		0x3234
 #define RADEON_RB3D_ZSTENCILCNTL	0x1c2c
 #	define RADEON_DEPTH_FORMAT_16BIT_INT_Z	(0 << 0)
 #	define RADEON_DEPTH_FORMAT_24BIT_INT_Z	(2 << 0)
@@ -541,6 +672,8 @@
 #	define RADEON_3D_DRAW_IMMD		0x00002900
 #	define RADEON_3D_DRAW_INDX		0x00002A00
 #	define RADEON_3D_LOAD_VBPNTR		0x00002F00
+#	define RADEON_3D_CLEAR_ZMASK		0x00003200
+#	define RADEON_3D_CLEAR_HIZ		0x00003700
 #	define RADEON_CNTL_HOSTDATA_BLT		0x00009400
 #	define RADEON_CNTL_PAINT_MULTI		0x00009A00
 #	define RADEON_CNTL_BITBLT_MULTI		0x00009B00
@@ -699,6 +832,8 @@
 
 #define R200_RB3D_BLENDCOLOR              0x3218
 
+#define R200_SE_TCL_POINT_SPRITE_CNTL     0x22c4
+
 /* Constants */
 #define RADEON_MAX_USEC_TIMEOUT		100000	/* 100 ms */
 
@@ -892,25 +1027,27 @@
 } while (0)
 
 
-#define OUT_RING_USER_TABLE( tab, sz ) do {			\
+#define OUT_RING_TABLE( tab, sz ) do {					\
 	int _size = (sz);					\
-	int __user *_tab = (tab);					\
+	int *_tab = (int *)(tab);				\
 								\
 	if (write + _size > mask) {				\
-		int i = (mask+1) - write;			\
-		if (DRM_COPY_FROM_USER_UNCHECKED( (int *)(ring+write),	\
-				      _tab, i*4 ))		\
-			return DRM_ERR(EFAULT);		\
+		int _i = (mask+1) - write;			\
+		_size -= _i;					\
+		while (_i > 0 ) {				\
+			*(int *)(ring + write) = *_tab++;	\
+			write++;				\
+			_i--;					\
+		}						\
 		write = 0;					\
-		_size -= i;					\
-		_tab += i;					\
+		_tab += _i;					\
 	}							\
 								\
-	if (_size && DRM_COPY_FROM_USER_UNCHECKED( (int *)(ring+write),	\
-			               _tab, _size*4 ))		\
-		return DRM_ERR(EFAULT);			\
-								\
-	write += _size;						\
+	while (_size > 0) {					\
+		*(ring + write) = *_tab++;			\
+		write++;					\
+		_size--;					\
+	}							\
 	write &= mask;						\
 } while (0)
 
diff -Nru a/drivers/char/drm/radeon_irq.c b/drivers/char/drm/radeon_irq.c
--- a/drivers/char/drm/radeon_irq.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/char/drm/radeon_irq.c	2005-03-01 23:39:16 -08:00
@@ -27,10 +27,9 @@
  *
  * Authors:
  *    Keith Whitwell <keith@tungstengraphics.com>
- *    Michel Dänzer <michel@daenzer.net>
+ *    Michel Dï¿½zer <michel@daenzer.net>
  */
 
-#include "radeon.h"
 #include "drmP.h"
 #include "drm.h"
 #include "radeon_drm.h"
@@ -78,7 +77,7 @@
 	if (stat & RADEON_CRTC_VBLANK_STAT) {
 		atomic_inc(&dev->vbl_received);
 		DRM_WAKEUP(&dev->vbl_queue);
-		DRM(vbl_send_signals)( dev );
+		drm_vbl_send_signals( dev );
 	}
 
 	/* Acknowledge interrupts we handle */
@@ -223,7 +222,7 @@
 
 /* drm_dma.h hooks
 */
-void DRM(driver_irq_preinstall)( drm_device_t *dev ) {
+void radeon_driver_irq_preinstall( drm_device_t *dev ) {
 	drm_radeon_private_t *dev_priv =
 		(drm_radeon_private_t *)dev->dev_private;
 
@@ -234,7 +233,7 @@
 	radeon_acknowledge_irqs( dev_priv );
 }
 
-void DRM(driver_irq_postinstall)( drm_device_t *dev ) {
+void radeon_driver_irq_postinstall( drm_device_t *dev ) {
 	drm_radeon_private_t *dev_priv =
 		(drm_radeon_private_t *)dev->dev_private;
 
@@ -247,7 +246,7 @@
 		      RADEON_SW_INT_ENABLE );
 }
 
-void DRM(driver_irq_uninstall)( drm_device_t *dev ) {
+void radeon_driver_irq_uninstall( drm_device_t *dev ) {
 	drm_radeon_private_t *dev_priv =
 		(drm_radeon_private_t *)dev->dev_private;
 	if (!dev_priv)
diff -Nru a/drivers/char/drm/radeon_mem.c b/drivers/char/drm/radeon_mem.c
--- a/drivers/char/drm/radeon_mem.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/char/drm/radeon_mem.c	2005-03-01 23:39:09 -08:00
@@ -29,7 +29,6 @@
  *    Keith Whitwell <keith@tungstengraphics.com>
  */
 
-#include "radeon.h"
 #include "drmP.h"
 #include "drm.h"
 #include "radeon_drm.h"
@@ -44,7 +43,7 @@
 {
 	/* Maybe cut off the start of an existing block */
 	if (start > p->start) {
-		struct mem_block *newblock = DRM_MALLOC(sizeof(*newblock));
+		struct mem_block *newblock = drm_alloc(sizeof(*newblock), DRM_MEM_BUFS );
 		if (!newblock) 
 			goto out;
 		newblock->start = start;
@@ -60,7 +59,7 @@
    
 	/* Maybe cut off the end of an existing block */
 	if (size < p->size) {
-		struct mem_block *newblock = DRM_MALLOC(sizeof(*newblock));
+		struct mem_block *newblock = drm_alloc(sizeof(*newblock), DRM_MEM_BUFS );
 		if (!newblock)
 			goto out;
 		newblock->start = start + size;
@@ -118,7 +117,7 @@
 		p->size += q->size;
 		p->next = q->next;
 		p->next->prev = p;
-		DRM_FREE(q, sizeof(*q));
+		drm_free(q, sizeof(*q), DRM_MEM_BUFS );
 	}
 
 	if (p->prev->filp == 0) {
@@ -126,7 +125,7 @@
 		q->size += p->size;
 		q->next = p->next;
 		q->next->prev = q;
-		DRM_FREE(p, sizeof(*q));
+		drm_free(p, sizeof(*q), DRM_MEM_BUFS );
 	}
 }
 
@@ -134,14 +133,14 @@
  */
 static int init_heap(struct mem_block **heap, int start, int size)
 {
-	struct mem_block *blocks = DRM_MALLOC(sizeof(*blocks));
+	struct mem_block *blocks = drm_alloc(sizeof(*blocks), DRM_MEM_BUFS );
 
 	if (!blocks) 
 		return DRM_ERR(ENOMEM);
 	
-	*heap = DRM_MALLOC(sizeof(**heap));
+	*heap = drm_alloc(sizeof(**heap), DRM_MEM_BUFS );
 	if (!*heap) {
-		DRM_FREE( blocks, sizeof(*blocks) );
+		drm_free( blocks, sizeof(*blocks), DRM_MEM_BUFS );
 		return DRM_ERR(ENOMEM);
 	}
 
@@ -180,7 +179,7 @@
 			p->size += q->size;
 			p->next = q->next;
 			p->next->prev = p;
-			DRM_FREE(q, sizeof(*q));
+			drm_free(q, sizeof(*q),DRM_MEM_DRIVER);
 		}
 	}
 }
@@ -197,10 +196,10 @@
 	for (p = (*heap)->next ; p != *heap ; ) {
 		struct mem_block *q = p;
 		p = p->next;
-		DRM_FREE(q, sizeof(*q));
+		drm_free(q, sizeof(*q),DRM_MEM_DRIVER);
 	}
 
-	DRM_FREE( *heap, sizeof(**heap) );
+	drm_free( *heap, sizeof(**heap),DRM_MEM_DRIVER );
 	*heap = NULL;
 }
 
diff -Nru a/drivers/char/drm/radeon_state.c b/drivers/char/drm/radeon_state.c
--- a/drivers/char/drm/radeon_state.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/char/drm/radeon_state.c	2005-03-01 23:39:09 -08:00
@@ -27,13 +27,43 @@
  *    Kevin E. Martin <martin@valinux.com>
  */
 
-#include "radeon.h"
 #include "drmP.h"
 #include "drm.h"
 #include "drm_sarea.h"
 #include "radeon_drm.h"
 #include "radeon_drv.h"
 
+drm_ioctl_desc_t radeon_ioctls[] = {
+	[DRM_IOCTL_NR(DRM_RADEON_CP_INIT)]    = { radeon_cp_init,      1, 1 },
+	[DRM_IOCTL_NR(DRM_RADEON_CP_START)]   = { radeon_cp_start,     1, 1 },
+	[DRM_IOCTL_NR(DRM_RADEON_CP_STOP)]    = { radeon_cp_stop,      1, 1 },
+	[DRM_IOCTL_NR(DRM_RADEON_CP_RESET)]   = { radeon_cp_reset,     1, 1 },
+	[DRM_IOCTL_NR(DRM_RADEON_CP_IDLE)]    = { radeon_cp_idle,      1, 0 },
+	[DRM_IOCTL_NR(DRM_RADEON_CP_RESUME)]  = { radeon_cp_resume,    1, 0 },
+	[DRM_IOCTL_NR(DRM_RADEON_RESET)]      = { radeon_engine_reset, 1, 0 },
+	[DRM_IOCTL_NR(DRM_RADEON_FULLSCREEN)] = { radeon_fullscreen,   1, 0 },
+	[DRM_IOCTL_NR(DRM_RADEON_SWAP)]       = { radeon_cp_swap,      1, 0 },
+	[DRM_IOCTL_NR(DRM_RADEON_CLEAR)]      = { radeon_cp_clear,     1, 0 },
+	[DRM_IOCTL_NR(DRM_RADEON_VERTEX)]     = { radeon_cp_vertex,    1, 0 },
+	[DRM_IOCTL_NR(DRM_RADEON_INDICES)]    = { radeon_cp_indices,   1, 0 },
+	[DRM_IOCTL_NR(DRM_RADEON_TEXTURE)]    = { radeon_cp_texture,   1, 0 },
+	[DRM_IOCTL_NR(DRM_RADEON_STIPPLE)]    = { radeon_cp_stipple,   1, 0 },
+	[DRM_IOCTL_NR(DRM_RADEON_INDIRECT)]   = { radeon_cp_indirect,  1, 1 },
+	[DRM_IOCTL_NR(DRM_RADEON_VERTEX2)]    = { radeon_cp_vertex2,   1, 0 },
+	[DRM_IOCTL_NR(DRM_RADEON_CMDBUF)]     = { radeon_cp_cmdbuf,    1, 0 },
+	[DRM_IOCTL_NR(DRM_RADEON_GETPARAM)]   = { radeon_cp_getparam,  1, 0 },
+	[DRM_IOCTL_NR(DRM_RADEON_FLIP)]       = { radeon_cp_flip,      1, 0 },
+	[DRM_IOCTL_NR(DRM_RADEON_ALLOC)]      = { radeon_mem_alloc,    1, 0 },
+	[DRM_IOCTL_NR(DRM_RADEON_FREE)]       = { radeon_mem_free,     1, 0 },
+	[DRM_IOCTL_NR(DRM_RADEON_INIT_HEAP)]  = { radeon_mem_init_heap,1, 1 },
+	[DRM_IOCTL_NR(DRM_RADEON_IRQ_EMIT)]   = { radeon_irq_emit,     1, 0 },
+	[DRM_IOCTL_NR(DRM_RADEON_IRQ_WAIT)]   = { radeon_irq_wait,     1, 0 },
+	[DRM_IOCTL_NR(DRM_RADEON_SETPARAM)]   = { radeon_cp_setparam,  1, 0 },
+	[DRM_IOCTL_NR(DRM_RADEON_SURF_ALLOC)] = { radeon_surface_alloc,1, 0 },
+	[DRM_IOCTL_NR(DRM_RADEON_SURF_FREE)]  = { radeon_surface_free, 1, 0 }
+};
+
+int radeon_max_ioctl = DRM_ARRAY_SIZE(radeon_ioctls);
 
 /* ================================================================
  * Helper functions for client state checking and fixup
@@ -63,21 +93,6 @@
 	return 0;
 }
 
-static __inline__ int radeon_check_and_fixup_offset_user( drm_radeon_private_t *dev_priv,
-							  drm_file_t *filp_priv,
-							  u32 __user *offset ) {
-	u32 off;
-
-	DRM_GET_USER_UNCHECKED( off, offset );
-
-	if ( radeon_check_and_fixup_offset( dev_priv, filp_priv, &off ) )
-		return DRM_ERR( EINVAL );
-
-	DRM_PUT_USER_UNCHECKED( offset, off );
-
-	return 0;
-}
-
 static __inline__ int radeon_check_and_fixup_packets( drm_radeon_private_t *dev_priv,
 						      drm_file_t *filp_priv,
 						      int id,
@@ -85,18 +100,18 @@
 	switch ( id ) {
 
 	case RADEON_EMIT_PP_MISC:
-		if ( radeon_check_and_fixup_offset_user( dev_priv, filp_priv,
-							 &data[( RADEON_RB3D_DEPTHOFFSET
-								 - RADEON_PP_MISC ) / 4] ) ) {
+		if ( radeon_check_and_fixup_offset( dev_priv, filp_priv,
+						    &data[( RADEON_RB3D_DEPTHOFFSET
+							    - RADEON_PP_MISC ) / 4] ) ) {
 			DRM_ERROR( "Invalid depth buffer offset\n" );
 			return DRM_ERR( EINVAL );
 		}
 		break;
 
 	case RADEON_EMIT_PP_CNTL:
-		if ( radeon_check_and_fixup_offset_user( dev_priv, filp_priv,
-							 &data[( RADEON_RB3D_COLOROFFSET
-								 - RADEON_PP_CNTL ) / 4] ) ) {
+		if ( radeon_check_and_fixup_offset( dev_priv, filp_priv,
+						    &data[( RADEON_RB3D_COLOROFFSET
+							    - RADEON_PP_CNTL ) / 4] ) ) {
 			DRM_ERROR( "Invalid colour buffer offset\n" );
 			return DRM_ERR( EINVAL );
 		}
@@ -108,8 +123,8 @@
 	case R200_EMIT_PP_TXOFFSET_3:
 	case R200_EMIT_PP_TXOFFSET_4:
 	case R200_EMIT_PP_TXOFFSET_5:
-		if ( radeon_check_and_fixup_offset_user( dev_priv, filp_priv,
-							 &data[0] ) ) {
+		if ( radeon_check_and_fixup_offset( dev_priv, filp_priv,
+						    &data[0] ) ) {
 			DRM_ERROR( "Invalid R200 texture offset\n" );
 			return DRM_ERR( EINVAL );
 		}
@@ -118,9 +133,9 @@
 	case RADEON_EMIT_PP_TXFILTER_0:
 	case RADEON_EMIT_PP_TXFILTER_1:
 	case RADEON_EMIT_PP_TXFILTER_2:
-		if ( radeon_check_and_fixup_offset_user( dev_priv, filp_priv,
-							 &data[( RADEON_PP_TXOFFSET_0
-								 - RADEON_PP_TXFILTER_0 ) / 4] ) ) {
+		if ( radeon_check_and_fixup_offset( dev_priv, filp_priv,
+						    &data[( RADEON_PP_TXOFFSET_0
+							    - RADEON_PP_TXFILTER_0 ) / 4] ) ) {
 			DRM_ERROR( "Invalid R100 texture offset\n" );
 			return DRM_ERR( EINVAL );
 		}
@@ -134,9 +149,8 @@
 	case R200_EMIT_PP_CUBIC_OFFSETS_5: {
 		int i;
 		for ( i = 0; i < 5; i++ ) {
-			if ( radeon_check_and_fixup_offset_user( dev_priv,
-								 filp_priv,
-								 &data[i] ) ) {
+			if ( radeon_check_and_fixup_offset( dev_priv, filp_priv,
+							    &data[i] ) ) {
 				DRM_ERROR( "Invalid R200 cubic texture offset\n" );
 				return DRM_ERR( EINVAL );
 			}
@@ -204,6 +218,7 @@
 	case RADEON_EMIT_PP_TEX_SIZE_1:
 	case RADEON_EMIT_PP_TEX_SIZE_2:
 	case R200_EMIT_RB3D_BLENDCOLOR:
+	case R200_EMIT_TCL_POINT_SPRITE_CNTL:
 		/* These packets don't contain memory offsets */
 		break;
 
@@ -219,17 +234,11 @@
 						      drm_file_t *filp_priv,
 						      drm_radeon_cmd_buffer_t *cmdbuf,
 						      unsigned int *cmdsz ) {
-	u32 tmp[4];
-	u32 __user *cmd = (u32 __user *)cmdbuf->buf;
-
-	if ( DRM_COPY_FROM_USER_UNCHECKED( tmp, cmd, sizeof( tmp ) ) ) {
-		DRM_ERROR( "Failed to copy data from user space\n" );
-		return DRM_ERR( EFAULT );
-	}
+	u32 *cmd = (u32 *) cmdbuf->buf;
 
-	*cmdsz = 2 + ( ( tmp[0] & RADEON_CP_PACKET_COUNT_MASK ) >> 16 );
+	*cmdsz = 2 + ( ( cmd[0] & RADEON_CP_PACKET_COUNT_MASK ) >> 16 );
 
-	if ( ( tmp[0] & 0xc0000000 ) != RADEON_CP_PACKET3 ) {
+	if ( ( cmd[0] & 0xc0000000 ) != RADEON_CP_PACKET3 ) {
 		DRM_ERROR( "Not a type 3 packet\n" );
 		return DRM_ERR( EINVAL );
 	}
@@ -240,32 +249,27 @@
 	}
 
 	/* Check client state and fix it up if necessary */
-	if ( tmp[0] & 0x8000 ) { /* MSB of opcode: next DWORD GUI_CNTL */
+	if ( cmd[0] & 0x8000 ) { /* MSB of opcode: next DWORD GUI_CNTL */
 		u32 offset;
 
-		if ( tmp[1] & ( RADEON_GMC_SRC_PITCH_OFFSET_CNTL
+		if ( cmd[1] & ( RADEON_GMC_SRC_PITCH_OFFSET_CNTL
 			      | RADEON_GMC_DST_PITCH_OFFSET_CNTL ) ) {
-			offset = tmp[2] << 10;
+			offset = cmd[2] << 10;
 			if ( radeon_check_and_fixup_offset( dev_priv, filp_priv, &offset ) ) {
 				DRM_ERROR( "Invalid first packet offset\n" );
 				return DRM_ERR( EINVAL );
 			}
-			tmp[2] = ( tmp[2] & 0xffc00000 ) | offset >> 10;
+			cmd[2] = ( cmd[2] & 0xffc00000 ) | offset >> 10;
 		}
 
-		if ( ( tmp[1] & RADEON_GMC_SRC_PITCH_OFFSET_CNTL ) &&
-		     ( tmp[1] & RADEON_GMC_DST_PITCH_OFFSET_CNTL ) ) {
-			offset = tmp[3] << 10;
+		if ( ( cmd[1] & RADEON_GMC_SRC_PITCH_OFFSET_CNTL ) &&
+		     ( cmd[1] & RADEON_GMC_DST_PITCH_OFFSET_CNTL ) ) {
+			offset = cmd[3] << 10;
 			if ( radeon_check_and_fixup_offset( dev_priv, filp_priv, &offset ) ) {
 				DRM_ERROR( "Invalid second packet offset\n" );
 				return DRM_ERR( EINVAL );
 			}
-			tmp[3] = ( tmp[3] & 0xffc00000 ) | offset >> 10;
-		}
-
-		if ( DRM_COPY_TO_USER_UNCHECKED( cmd, tmp, sizeof( tmp ) ) ) {
-			DRM_ERROR( "Failed to copy data to user space\n" );
-			return DRM_ERR( EFAULT );
+			cmd[3] = ( cmd[3] & 0xffc00000 ) | offset >> 10;
 		}
 	}
 
@@ -568,6 +572,7 @@
 	{ RADEON_PP_TEX_SIZE_1, 2, "RADEON_PP_TEX_SIZE_1" },
 	{ RADEON_PP_TEX_SIZE_2, 2, "RADEON_PP_TEX_SIZE_2" },
 	{ R200_RB3D_BLENDCOLOR, 3, "R200_RB3D_BLENDCOLOR" },
+	{ R200_SE_TCL_POINT_SPRITE_CNTL, 1, "R200_SE_TCL_POINT_SPRITE_CNTL" },
 };
 
 
@@ -778,13 +783,160 @@
 			}
 		}
 	}
+	
+	/* hyper z clear */
+	/* no docs available, based on reverse engeneering by Stephane Marchesin */
+	if ((flags & (RADEON_DEPTH | RADEON_STENCIL)) && (flags & RADEON_CLEAR_FASTZ)) {
+
+		int i;
+		int depthpixperline = dev_priv->depth_fmt==RADEON_DEPTH_FORMAT_16BIT_INT_Z? 
+			(dev_priv->depth_pitch / 2): (dev_priv->depth_pitch / 4);
+		
+		u32 clearmask;
+
+		u32 tempRB3D_DEPTHCLEARVALUE = clear->clear_depth |
+			((clear->depth_mask & 0xff) << 24);
+	
+		
+		/* Make sure we restore the 3D state next time.
+		 * we haven't touched any "normal" state - still need this?
+		 */
+		dev_priv->sarea_priv->ctx_owner = 0;
+
+		if ((dev_priv->flags & CHIP_HAS_HIERZ) && (flags & RADEON_USE_HIERZ)) {
+		/* FIXME : reverse engineer that for Rx00 cards */
+		/* FIXME : the mask supposedly contains low-res z values. So can't set
+		   just to the max (0xff? or actually 0x3fff?), need to take z clear
+		   value into account? */
+		/* pattern seems to work for r100, though get slight
+		   rendering errors with glxgears. If hierz is not enabled for r100,
+		   only 4 bits which indicate clear (15,16,31,32, all zero) matter, the
+		   other ones are ignored, and the same clear mask can be used. That's
+		   very different behaviour than R200 which needs different clear mask
+		   and different number of tiles to clear if hierz is enabled or not !?!
+		*/
+			clearmask = (0xff<<22)|(0xff<<6)| 0x003f003f;
+		}
+		else {
+		/* clear mask : chooses the clearing pattern.
+		   rv250: could be used to clear only parts of macrotiles
+		   (but that would get really complicated...)?
+		   bit 0 and 1 (either or both of them ?!?!) are used to
+		   not clear tile (or maybe one of the bits indicates if the tile is
+		   compressed or not), bit 2 and 3 to not clear tile 1,...,.
+		   Pattern is as follows:
+		        | 0,1 | 4,5 | 8,9 |12,13|16,17|20,21|24,25|28,29|
+		   bits -------------------------------------------------
+		        | 2,3 | 6,7 |10,11|14,15|18,19|22,23|26,27|30,31|
+		   rv100: clearmask covers 2x8 4x1 tiles, but one clear still
+		   covers 256 pixels ?!?
+		*/
+			clearmask = 0x0;
+		}
+
+		BEGIN_RING( 8 );
+		RADEON_WAIT_UNTIL_2D_IDLE();
+		OUT_RING_REG( RADEON_RB3D_DEPTHCLEARVALUE,
+			tempRB3D_DEPTHCLEARVALUE);
+		/* what offset is this exactly ? */
+		OUT_RING_REG( RADEON_RB3D_ZMASKOFFSET, 0 );
+		/* need ctlstat, otherwise get some strange black flickering */
+		OUT_RING_REG( RADEON_RB3D_ZCACHE_CTLSTAT, RADEON_RB3D_ZC_FLUSH_ALL );
+		ADVANCE_RING();
+
+		for (i = 0; i < nbox; i++) {
+			int tileoffset, nrtilesx, nrtilesy, j;
+			/* it looks like r200 needs rv-style clears, at least if hierz is not enabled? */
+			if ((dev_priv->flags&CHIP_HAS_HIERZ) && !(dev_priv->microcode_version==UCODE_R200)) {
+				/* FIXME : figure this out for r200 (when hierz is enabled). Or
+				   maybe r200 actually doesn't need to put the low-res z value into
+				   the tile cache like r100, but just needs to clear the hi-level z-buffer?
+				   Works for R100, both with hierz and without.
+				   R100 seems to operate on 2x1 8x8 tiles, but...
+				   odd: offset/nrtiles need to be 64 pix (4 block) aligned? Potentially
+				   problematic with resolutions which are not 64 pix aligned? */
+				tileoffset = ((pbox[i].y1 >> 3) * depthpixperline + pbox[i].x1) >> 6;
+				nrtilesx = ((pbox[i].x2 & ~63) - (pbox[i].x1 & ~63)) >> 4;
+				nrtilesy = (pbox[i].y2 >> 3) - (pbox[i].y1 >> 3);
+				for (j = 0; j <= nrtilesy; j++) {
+					BEGIN_RING( 4 );
+					OUT_RING( CP_PACKET3( RADEON_3D_CLEAR_ZMASK, 2 ) );
+					/* first tile */
+					OUT_RING( tileoffset * 8 );
+					/* the number of tiles to clear */
+					OUT_RING( nrtilesx + 4 );
+					/* clear mask : chooses the clearing pattern. */
+					OUT_RING( clearmask );
+					ADVANCE_RING();
+					tileoffset += depthpixperline >> 6;
+				}
+			}
+			else if (dev_priv->microcode_version==UCODE_R200) {
+				/* works for rv250. */
+				/* find first macro tile (8x2 4x4 z-pixels on rv250) */
+				tileoffset = ((pbox[i].y1 >> 3) * depthpixperline + pbox[i].x1) >> 5;
+				nrtilesx = (pbox[i].x2 >> 5) - (pbox[i].x1 >> 5);
+				nrtilesy = (pbox[i].y2 >> 3) - (pbox[i].y1 >> 3);
+				for (j = 0; j <= nrtilesy; j++) {
+					BEGIN_RING( 4 );
+					OUT_RING( CP_PACKET3( RADEON_3D_CLEAR_ZMASK, 2 ) );
+					/* first tile */
+					/* judging by the first tile offset needed, could possibly
+					   directly address/clear 4x4 tiles instead of 8x2 * 4x4
+					   macro tiles, though would still need clear mask for
+					   right/bottom if truely 4x4 granularity is desired ? */
+					OUT_RING( tileoffset * 16 );
+					/* the number of tiles to clear */
+					OUT_RING( nrtilesx + 1 );
+					/* clear mask : chooses the clearing pattern. */
+					OUT_RING( clearmask );
+					ADVANCE_RING();
+					tileoffset += depthpixperline >> 5;
+				}
+			}
+			else { /* rv 100 */
+				/* rv100 might not need 64 pix alignment, who knows */
+				/* offsets are, hmm, weird */
+				tileoffset = ((pbox[i].y1 >> 4) * depthpixperline + pbox[i].x1) >> 6;
+				nrtilesx = ((pbox[i].x2 & ~63) - (pbox[i].x1 & ~63)) >> 4;
+				nrtilesy = (pbox[i].y2 >> 4) - (pbox[i].y1 >> 4);
+				for (j = 0; j <= nrtilesy; j++) {
+					BEGIN_RING( 4 );
+					OUT_RING( CP_PACKET3( RADEON_3D_CLEAR_ZMASK, 2 ) );
+					OUT_RING( tileoffset * 128 );
+					/* the number of tiles to clear */
+					OUT_RING( nrtilesx + 4 );
+					/* clear mask : chooses the clearing pattern. */
+					OUT_RING( clearmask );
+					ADVANCE_RING();
+					tileoffset += depthpixperline >> 6;
+				}
+			}
+		}
+
+		/* TODO don't always clear all hi-level z tiles */
+		if ((dev_priv->flags & CHIP_HAS_HIERZ) && (dev_priv->microcode_version==UCODE_R200)
+			&& (flags & RADEON_USE_HIERZ))
+		/* r100 and cards without hierarchical z-buffer have no high-level z-buffer */
+		/* FIXME : the mask supposedly contains low-res z values. So can't set
+		   just to the max (0xff? or actually 0x3fff?), need to take z clear
+		   value into account? */
+		{
+			BEGIN_RING( 4 );
+			OUT_RING( CP_PACKET3( RADEON_3D_CLEAR_HIZ, 2 ) );
+			OUT_RING( 0x0 ); /* First tile */
+			OUT_RING( 0x3cc0 );
+			OUT_RING( (0xff<<22)|(0xff<<6)| 0x003f003f);
+			ADVANCE_RING();
+		}
+	}
 
 	/* We have to clear the depth and/or stencil buffers by
 	 * rendering a quad into just those buffers.  Thus, we have to
 	 * make sure the 3D engine is configured correctly.
 	 */
-	if ( dev_priv->is_r200 &&
-	     (flags & (RADEON_DEPTH | RADEON_STENCIL)) ) {
+	if ((dev_priv->microcode_version == UCODE_R200) &&
+	    (flags & (RADEON_DEPTH | RADEON_STENCIL))) {
 
 		int tempPP_CNTL;
 		int tempRE_CNTL;
@@ -803,7 +955,6 @@
 		tempRE_CNTL = 0;
 
 		tempRB3D_CNTL = depth_clear->rb3d_cntl;
-		tempRB3D_CNTL &= ~(1<<15); /* unset radeon magic flag */
 
 		tempRB3D_ZSTENCILCNTL = depth_clear->rb3d_zstencilcntl;
 		tempRB3D_STENCILREFMASK = 0x0;
@@ -854,6 +1005,14 @@
 			tempRB3D_STENCILREFMASK = 0x00000000;
 		}
 
+		if (flags & RADEON_USE_COMP_ZBUF) {
+			tempRB3D_ZSTENCILCNTL |= RADEON_Z_COMPRESSION_ENABLE |
+				RADEON_Z_DECOMPRESSION_ENABLE;
+		}
+		if (flags & RADEON_USE_HIERZ) {
+			tempRB3D_ZSTENCILCNTL |= RADEON_Z_HIERARCHY_ENABLE;
+		}
+
 		BEGIN_RING( 26 );
 		RADEON_WAIT_UNTIL_2D_IDLE();
 
@@ -908,6 +1067,8 @@
 	} 
 	else if ( (flags & (RADEON_DEPTH | RADEON_STENCIL)) ) {
 
+		int tempRB3D_ZSTENCILCNTL = depth_clear->rb3d_zstencilcntl;
+
 		rb3d_cntl = depth_clear->rb3d_cntl;
 
 		if ( flags & RADEON_DEPTH ) {
@@ -924,6 +1085,14 @@
 			rb3d_stencilrefmask = 0x00000000;
 		}
 
+		if (flags & RADEON_USE_COMP_ZBUF) {
+			tempRB3D_ZSTENCILCNTL |= RADEON_Z_COMPRESSION_ENABLE |
+				RADEON_Z_DECOMPRESSION_ENABLE;
+		}
+		if (flags & RADEON_USE_HIERZ) {
+			tempRB3D_ZSTENCILCNTL |= RADEON_Z_HIERARCHY_ENABLE;
+		}
+
 		BEGIN_RING( 13 );
 		RADEON_WAIT_UNTIL_2D_IDLE();
 
@@ -931,8 +1100,7 @@
 		OUT_RING( 0x00000000 );
 		OUT_RING( rb3d_cntl );
 		
-		OUT_RING_REG( RADEON_RB3D_ZSTENCILCNTL,
-			      depth_clear->rb3d_zstencilcntl );
+		OUT_RING_REG( RADEON_RB3D_ZSTENCILCNTL, tempRB3D_ZSTENCILCNTL );
 		OUT_RING_REG( RADEON_RB3D_STENCILREFMASK,
 			      rb3d_stencilrefmask );
 		OUT_RING_REG( RADEON_RB3D_PLANEMASK,
@@ -1440,7 +1608,8 @@
 		}
 		if ( !buf ) {
 			DRM_DEBUG("radeon_cp_dispatch_texture: EAGAIN\n");
-			DRM_COPY_TO_USER( tex->image, image, sizeof(*image) );
+			if (DRM_COPY_TO_USER( tex->image, image, sizeof(*image) ))
+				return DRM_ERR(EFAULT);
 			return DRM_ERR(EAGAIN);
 		}
 
@@ -1537,10 +1706,203 @@
 	ADVANCE_RING();
 }
 
+static void radeon_apply_surface_regs(int surf_index, drm_radeon_private_t *dev_priv)
+{
+	if (!dev_priv->mmio)
+		return;
+
+	radeon_do_cp_idle(dev_priv);
+
+	RADEON_WRITE(RADEON_SURFACE0_INFO + 16*surf_index,
+		dev_priv->surfaces[surf_index].flags);
+	RADEON_WRITE(RADEON_SURFACE0_LOWER_BOUND + 16*surf_index,
+		dev_priv->surfaces[surf_index].lower);
+	RADEON_WRITE(RADEON_SURFACE0_UPPER_BOUND + 16*surf_index,
+		dev_priv->surfaces[surf_index].upper);
+}
+
+
+/* Allocates a virtual surface
+ * doesn't always allocate a real surface, will stretch an existing 
+ * surface when possible.
+ *
+ * Note that refcount can be at most 2, since during a free refcount=3
+ * might mean we have to allocate a new surface which might not always
+ * be available.
+ * For example : we allocate three contigous surfaces ABC. If B is 
+ * freed, we suddenly need two surfaces to store A and C, which might
+ * not always be available.
+ */
+static int alloc_surface(drm_radeon_surface_alloc_t* new, drm_radeon_private_t *dev_priv, DRMFILE filp)
+{
+	struct radeon_virt_surface *s;
+	int i;
+	int virt_surface_index;
+	uint32_t new_upper, new_lower;
+
+	new_lower = new->address;
+	new_upper = new_lower + new->size - 1;
+
+	/* sanity check */
+	if ((new_lower >= new_upper) || (new->flags == 0) || (new->size == 0) ||
+		((new_upper & RADEON_SURF_ADDRESS_FIXED_MASK) != RADEON_SURF_ADDRESS_FIXED_MASK) ||
+		((new_lower & RADEON_SURF_ADDRESS_FIXED_MASK) != 0))
+		return -1;
+
+	/* make sure there is no overlap with existing surfaces */
+	for (i = 0; i < RADEON_MAX_SURFACES; i++) {
+		if ((dev_priv->surfaces[i].refcount != 0) &&
+		(( (new_lower >= dev_priv->surfaces[i].lower) &&
+			(new_lower < dev_priv->surfaces[i].upper) ) ||
+		 ( (new_lower < dev_priv->surfaces[i].lower) &&
+			(new_upper > dev_priv->surfaces[i].lower) )) ){
+		return -1;}
+	}
+
+	/* find a virtual surface */
+	for (i = 0; i < 2*RADEON_MAX_SURFACES; i++)
+		if (dev_priv->virt_surfaces[i].filp == 0)
+			break;
+	if (i == 2*RADEON_MAX_SURFACES) {
+		return -1;}
+	virt_surface_index = i;
+
+	/* try to reuse an existing surface */
+	for (i = 0; i < RADEON_MAX_SURFACES; i++) {
+		/* extend before */
+		if ((dev_priv->surfaces[i].refcount == 1) &&
+		  (new->flags == dev_priv->surfaces[i].flags) &&
+		  (new_upper + 1 == dev_priv->surfaces[i].lower)) {
+			s = &(dev_priv->virt_surfaces[virt_surface_index]);
+			s->surface_index = i;
+			s->lower = new_lower;
+			s->upper = new_upper;
+			s->flags = new->flags;
+			s->filp = filp;
+			dev_priv->surfaces[i].refcount++;
+			dev_priv->surfaces[i].lower = s->lower;
+			radeon_apply_surface_regs(s->surface_index, dev_priv);
+			return virt_surface_index;
+		}
+
+		/* extend after */
+		if ((dev_priv->surfaces[i].refcount == 1) &&
+		  (new->flags == dev_priv->surfaces[i].flags) &&
+		  (new_lower == dev_priv->surfaces[i].upper + 1)) {
+			s = &(dev_priv->virt_surfaces[virt_surface_index]);
+			s->surface_index = i;
+			s->lower = new_lower;
+			s->upper = new_upper;
+			s->flags = new->flags;
+			s->filp = filp;
+			dev_priv->surfaces[i].refcount++;
+			dev_priv->surfaces[i].upper = s->upper;
+			radeon_apply_surface_regs(s->surface_index, dev_priv);
+			return virt_surface_index;
+		}
+	}
+
+	/* okay, we need a new one */
+	for (i = 0; i < RADEON_MAX_SURFACES; i++) {
+		if (dev_priv->surfaces[i].refcount == 0) {
+			s = &(dev_priv->virt_surfaces[virt_surface_index]);
+			s->surface_index = i;
+			s->lower = new_lower;
+			s->upper = new_upper;
+			s->flags = new->flags;
+			s->filp = filp;
+			dev_priv->surfaces[i].refcount = 1;
+			dev_priv->surfaces[i].lower = s->lower;
+			dev_priv->surfaces[i].upper = s->upper;
+			dev_priv->surfaces[i].flags = s->flags;
+			radeon_apply_surface_regs(s->surface_index, dev_priv);
+			return virt_surface_index;
+		}
+	}
+
+	/* we didn't find anything */
+	return -1;
+}
+
+static int free_surface(DRMFILE filp, drm_radeon_private_t *dev_priv, int lower)
+{
+	struct radeon_virt_surface *s;
+	int i;
+	/* find the virtual surface */
+	for(i = 0; i < 2*RADEON_MAX_SURFACES; i++) {
+		s = &(dev_priv->virt_surfaces[i]);
+		if (s->filp) {
+			if ((lower == s->lower) && (filp == s->filp)) {
+				if (dev_priv->surfaces[s->surface_index].lower == s->lower)
+					dev_priv->surfaces[s->surface_index].lower = s->upper;
+
+				if (dev_priv->surfaces[s->surface_index].upper == s->upper)
+					dev_priv->surfaces[s->surface_index].upper = s->lower;
+
+				dev_priv->surfaces[s->surface_index].refcount--;
+				if (dev_priv->surfaces[s->surface_index].refcount == 0)
+					dev_priv->surfaces[s->surface_index].flags = 0;
+				s->filp = 0;
+				radeon_apply_surface_regs(s->surface_index, dev_priv);
+				return 0;
+			}
+		}
+	}
+	return 1;
+}
+
+static void radeon_surfaces_release(DRMFILE filp, drm_radeon_private_t *dev_priv)
+{
+	int i;
+	for( i = 0; i < 2*RADEON_MAX_SURFACES; i++)
+	{
+		if (dev_priv->virt_surfaces[i].filp == filp)
+			free_surface(filp, dev_priv, dev_priv->virt_surfaces[i].lower);
+	}
+}
 
 /* ================================================================
  * IOCTL functions
  */
+int radeon_surface_alloc(DRM_IOCTL_ARGS)
+{
+	DRM_DEVICE;
+	drm_radeon_private_t *dev_priv = dev->dev_private;
+	drm_radeon_surface_alloc_t alloc;
+
+	if (!dev_priv) {
+		DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
+		return DRM_ERR(EINVAL);
+	}
+
+	DRM_COPY_FROM_USER_IOCTL(alloc, (drm_radeon_surface_alloc_t __user *)data,
+				  sizeof(alloc));
+
+	if (alloc_surface(&alloc, dev_priv, filp) == -1)
+		return DRM_ERR(EINVAL);
+	else
+		return 0;
+}
+
+int radeon_surface_free(DRM_IOCTL_ARGS)
+{
+	DRM_DEVICE;
+	drm_radeon_private_t *dev_priv = dev->dev_private;
+	drm_radeon_surface_free_t memfree;
+
+	if (!dev_priv) {
+		DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
+		return DRM_ERR(EINVAL);
+	}
+
+	DRM_COPY_FROM_USER_IOCTL(memfree, (drm_radeon_mem_free_t __user *)data,
+				  sizeof(memfree) );
+
+	if (free_surface(filp, dev_priv, memfree.address))
+		return DRM_ERR(EINVAL);
+	else
+		return 0;
+}
 
 int radeon_cp_clear( DRM_IOCTL_ARGS )
 {
@@ -1596,7 +1958,7 @@
 	return 0;
 }
 
-/* Called whenever a client dies, from DRM(release).
+/* Called whenever a client dies, from drm_release.
  * NOTE:  Lock isn't necessarily held when this is called!
  */
 int radeon_do_cleanup_pageflip( drm_device_t *dev )
@@ -2084,7 +2446,7 @@
 {
 	int id = (int)header.packet.packet_id;
 	int sz, reg;
-	int __user *data = (int __user *)cmdbuf->buf;
+	int *data = (int *)cmdbuf->buf;
 	RING_LOCALS;
    
 	if (id >= RADEON_MAX_STATE_PACKETS)
@@ -2105,7 +2467,7 @@
 
 	BEGIN_RING(sz+1);
 	OUT_RING( CP_PACKET0( reg, (sz-1) ) );
-	OUT_RING_USER_TABLE( data, sz );
+	OUT_RING_TABLE( data, sz );
 	ADVANCE_RING();
 
 	cmdbuf->buf += sz * sizeof(int);
@@ -2119,7 +2481,6 @@
 	drm_radeon_cmd_buffer_t *cmdbuf )
 {
 	int sz = header.scalars.count;
-	int __user *data = (int __user *)cmdbuf->buf;
 	int start = header.scalars.offset;
 	int stride = header.scalars.stride;
 	RING_LOCALS;
@@ -2128,7 +2489,7 @@
 	OUT_RING( CP_PACKET0( RADEON_SE_TCL_SCALAR_INDX_REG, 0 ) );
 	OUT_RING( start | (stride << RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT));
 	OUT_RING( CP_PACKET0_TABLE( RADEON_SE_TCL_SCALAR_DATA_REG, sz-1 ) );
-	OUT_RING_USER_TABLE( data, sz );
+	OUT_RING_TABLE( cmdbuf->buf, sz );
 	ADVANCE_RING();
 	cmdbuf->buf += sz * sizeof(int);
 	cmdbuf->bufsz -= sz * sizeof(int);
@@ -2143,7 +2504,6 @@
 	drm_radeon_cmd_buffer_t *cmdbuf )
 {
 	int sz = header.scalars.count;
-	int __user *data = (int __user *)cmdbuf->buf;
 	int start = ((unsigned int)header.scalars.offset) + 0x100;
 	int stride = header.scalars.stride;
 	RING_LOCALS;
@@ -2152,7 +2512,7 @@
 	OUT_RING( CP_PACKET0( RADEON_SE_TCL_SCALAR_INDX_REG, 0 ) );
 	OUT_RING( start | (stride << RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT));
 	OUT_RING( CP_PACKET0_TABLE( RADEON_SE_TCL_SCALAR_DATA_REG, sz-1 ) );
-	OUT_RING_USER_TABLE( data, sz );
+	OUT_RING_TABLE( cmdbuf->buf, sz );
 	ADVANCE_RING();
 	cmdbuf->buf += sz * sizeof(int);
 	cmdbuf->bufsz -= sz * sizeof(int);
@@ -2165,7 +2525,6 @@
 	drm_radeon_cmd_buffer_t *cmdbuf )
 {
 	int sz = header.vectors.count;
-	int __user *data = (int __user *)cmdbuf->buf;
 	int start = header.vectors.offset;
 	int stride = header.vectors.stride;
 	RING_LOCALS;
@@ -2174,7 +2533,7 @@
 	OUT_RING( CP_PACKET0( RADEON_SE_TCL_VECTOR_INDX_REG, 0 ) );
 	OUT_RING( start | (stride << RADEON_VEC_INDX_OCTWORD_STRIDE_SHIFT));
 	OUT_RING( CP_PACKET0_TABLE( RADEON_SE_TCL_VECTOR_DATA_REG, (sz-1) ) );
-	OUT_RING_USER_TABLE( data, sz );
+	OUT_RING_TABLE( cmdbuf->buf, sz );
 	ADVANCE_RING();
 
 	cmdbuf->buf += sz * sizeof(int);
@@ -2189,7 +2548,6 @@
 {
 	drm_radeon_private_t *dev_priv = dev->dev_private;
 	unsigned int cmdsz;
-	int __user *cmd = (int __user *)cmdbuf->buf;
 	int ret;
 	RING_LOCALS;
 
@@ -2202,7 +2560,7 @@
 	}
 
 	BEGIN_RING( cmdsz );
-	OUT_RING_USER_TABLE( cmd, cmdsz );
+	OUT_RING_TABLE( cmdbuf->buf, cmdsz );
 	ADVANCE_RING();
 
 	cmdbuf->buf += cmdsz * 4;
@@ -2219,7 +2577,6 @@
 	drm_radeon_private_t *dev_priv = dev->dev_private;
 	drm_clip_rect_t box;
 	unsigned int cmdsz;
-	int __user *cmd = (int __user *)cmdbuf->buf;
 	int ret;
 	drm_clip_rect_t __user *boxes = cmdbuf->boxes;
 	int i = 0;
@@ -2238,7 +2595,7 @@
 
 	do {
 		if ( i < cmdbuf->nbox ) {
-			if (DRM_COPY_FROM_USER_UNCHECKED( &box, &boxes[i], sizeof(box) ))
+			if (DRM_COPY_FROM_USER( &box, &boxes[i], sizeof(box) ))
 				return DRM_ERR(EFAULT);
 			/* FIXME The second and subsequent times round
 			 * this loop, send a WAIT_UNTIL_3D_IDLE before
@@ -2261,7 +2618,7 @@
 		}
 		
 		BEGIN_RING( cmdsz );
-		OUT_RING_USER_TABLE( cmd, cmdsz );
+		OUT_RING_TABLE( cmdbuf->buf, cmdsz );
 		ADVANCE_RING();
 
 	} while ( ++i < cmdbuf->nbox );
@@ -2314,7 +2671,8 @@
 	int idx;
 	drm_radeon_cmd_buffer_t cmdbuf;
 	drm_radeon_cmd_header_t header;
-	int orig_nbox;
+	int orig_nbox, orig_bufsz;
+	char *kbuf=NULL;
 
 	LOCK_TEST_WITH_RETURN( dev, filp );
 
@@ -2331,24 +2689,29 @@
 	RING_SPACE_TEST_WITH_RETURN( dev_priv );
 	VB_AGE_TEST_WITH_RETURN( dev_priv );
 
+	if (cmdbuf.bufsz > 64*1024 || cmdbuf.bufsz<0) {
+		return DRM_ERR(EINVAL);
+	}
 
-	if (DRM_VERIFYAREA_READ( cmdbuf.buf, cmdbuf.bufsz ))
-		return DRM_ERR(EFAULT);
-
-	if (cmdbuf.nbox &&
-	    DRM_VERIFYAREA_READ(cmdbuf.boxes, 
-			 cmdbuf.nbox * sizeof(drm_clip_rect_t)))
-		return DRM_ERR(EFAULT);
+	/* Allocate an in-kernel area and copy in the cmdbuf.  Do this to avoid
+	 * races between checking values and using those values in other code,
+	 * and simply to avoid a lot of function calls to copy in data.
+	 */
+	orig_bufsz = cmdbuf.bufsz;
+	if (orig_bufsz != 0) {
+		kbuf = drm_alloc(cmdbuf.bufsz, DRM_MEM_DRIVER);
+		if (kbuf == NULL)
+			return DRM_ERR(ENOMEM);
+		if (DRM_COPY_FROM_USER(kbuf, cmdbuf.buf, cmdbuf.bufsz))
+			return DRM_ERR(EFAULT);
+		cmdbuf.buf = kbuf;
+	}
 
 	orig_nbox = cmdbuf.nbox;
 
 	while ( cmdbuf.bufsz >= sizeof(header) ) {
-		
-		if (DRM_GET_USER_UNCHECKED( header.i, (int __user *)cmdbuf.buf )) {
-			DRM_ERROR("__get_user %p\n", cmdbuf.buf);
-			return DRM_ERR(EFAULT);
-		}
 
+		header.i = *(int *)cmdbuf.buf;
 		cmdbuf.buf += sizeof(header);
 		cmdbuf.bufsz -= sizeof(header);
 
@@ -2357,7 +2720,7 @@
 			DRM_DEBUG("RADEON_CMD_PACKET\n");
 			if (radeon_emit_packets( dev_priv, filp_priv, header, &cmdbuf )) {
 				DRM_ERROR("radeon_emit_packets failed\n");
-				return DRM_ERR(EINVAL);
+				goto err;
 			}
 			break;
 
@@ -2365,7 +2728,7 @@
 			DRM_DEBUG("RADEON_CMD_SCALARS\n");
 			if (radeon_emit_scalars( dev_priv, header, &cmdbuf )) {
 				DRM_ERROR("radeon_emit_scalars failed\n");
-				return DRM_ERR(EINVAL);
+				goto err;
 			}
 			break;
 
@@ -2373,7 +2736,7 @@
 			DRM_DEBUG("RADEON_CMD_VECTORS\n");
 			if (radeon_emit_vectors( dev_priv, header, &cmdbuf )) {
 				DRM_ERROR("radeon_emit_vectors failed\n");
-				return DRM_ERR(EINVAL);
+				goto err;
 			}
 			break;
 
@@ -2383,14 +2746,14 @@
 			if ( idx < 0 || idx >= dma->buf_count ) {
 				DRM_ERROR( "buffer index %d (of %d max)\n",
 					   idx, dma->buf_count - 1 );
-				return DRM_ERR(EINVAL);
+				goto err;
 			}
 
 			buf = dma->buflist[idx];
 			if ( buf->filp != filp || buf->pending ) {
 				DRM_ERROR( "bad buffer %p %p %d\n",
 					   buf->filp, filp, buf->pending);
-				return DRM_ERR(EINVAL);
+				goto err;
 			}
 
 			radeon_cp_discard_buffer( dev, buf );
@@ -2400,7 +2763,7 @@
 			DRM_DEBUG("RADEON_CMD_PACKET3\n");
 			if (radeon_emit_packet3( dev, filp_priv, &cmdbuf )) {
 				DRM_ERROR("radeon_emit_packet3 failed\n");
-				return DRM_ERR(EINVAL);
+				goto err;
 			}
 			break;
 
@@ -2408,7 +2771,7 @@
 			DRM_DEBUG("RADEON_CMD_PACKET3_CLIP\n");
 			if (radeon_emit_packet3_cliprect( dev, filp_priv, &cmdbuf, orig_nbox )) {
 				DRM_ERROR("radeon_emit_packet3_clip failed\n");
-				return DRM_ERR(EINVAL);
+				goto err;
 			}
 			break;
 
@@ -2416,7 +2779,7 @@
 			DRM_DEBUG("RADEON_CMD_SCALARS2\n");
 			if (radeon_emit_scalars2( dev_priv, header, &cmdbuf )) {
 				DRM_ERROR("radeon_emit_scalars2 failed\n");
-				return DRM_ERR(EINVAL);
+				goto err;
 			}
 			break;
 
@@ -2424,21 +2787,28 @@
 			DRM_DEBUG("RADEON_CMD_WAIT\n");
 			if (radeon_emit_wait( dev, header.wait.flags )) {
 				DRM_ERROR("radeon_emit_wait failed\n");
-				return DRM_ERR(EINVAL);
+				goto err;
 			}
 			break;
 		default:
 			DRM_ERROR("bad cmd_type %d at %p\n", 
 				  header.header.cmd_type,
 				  cmdbuf.buf - sizeof(header));
-			return DRM_ERR(EINVAL);
+			goto err;
 		}
 	}
 
+	if (orig_bufsz != 0)
+		drm_free(kbuf, orig_bufsz, DRM_MEM_DRIVER);
 
 	DRM_DEBUG("DONE\n");
 	COMMIT_RING();
 	return 0;
+
+err:
+	if (orig_bufsz != 0)
+		drm_free(kbuf, orig_bufsz, DRM_MEM_DRIVER);
+	return DRM_ERR(EINVAL);
 }
 
 
@@ -2539,6 +2909,20 @@
 		radeon_priv = filp_priv->driver_priv;
 		radeon_priv->radeon_fb_delta = dev_priv->fb_location - sp.value;
 		break;
+	case RADEON_SETPARAM_SWITCH_TILING:
+		if (sp.value == 0) {
+			DRM_DEBUG( "color tiling disabled\n" );
+			dev_priv->front_pitch_offset &= ~RADEON_DST_TILE_MACRO;
+			dev_priv->back_pitch_offset &= ~RADEON_DST_TILE_MACRO;
+			dev_priv->sarea_priv->tiling_enabled = 0;
+		}
+		else if (sp.value == 1) {
+			DRM_DEBUG( "color tiling enabled\n" );
+			dev_priv->front_pitch_offset |= RADEON_DST_TILE_MACRO;
+			dev_priv->back_pitch_offset |= RADEON_DST_TILE_MACRO;
+			dev_priv->sarea_priv->tiling_enabled = 1;
+		}
+		break;	
 	default:
 		DRM_DEBUG( "Invalid parameter %d\n", sp.param );
 		return DRM_ERR( EINVAL );
@@ -2553,7 +2937,7 @@
  *
  * DRM infrastructure takes care of reclaiming dma buffers.
  */
-static void radeon_driver_prerelease(drm_device_t *dev, DRMFILE filp)
+void radeon_driver_prerelease(drm_device_t *dev, DRMFILE filp)
 {
 	if ( dev->dev_private ) {				
 		drm_radeon_private_t *dev_priv = dev->dev_private; 
@@ -2562,20 +2946,21 @@
 		}						
 		radeon_mem_release( filp, dev_priv->gart_heap ); 
 		radeon_mem_release( filp, dev_priv->fb_heap );	
+		radeon_surfaces_release(filp, dev_priv);
 	}				
 }
 
-static void radeon_driver_pretakedown(drm_device_t *dev)
+void radeon_driver_pretakedown(drm_device_t *dev)
 {
 	radeon_do_release(dev);
 }
 
-static int radeon_driver_open_helper(drm_device_t *dev, drm_file_t *filp_priv)
+int radeon_driver_open_helper(drm_device_t *dev, drm_file_t *filp_priv)
 {
 	drm_radeon_private_t *dev_priv = dev->dev_private;
 	struct drm_radeon_driver_file_fields *radeon_priv;
 	
-	radeon_priv = (struct drm_radeon_driver_file_fields *)DRM(alloc)(sizeof(*radeon_priv), DRM_MEM_FILES);
+	radeon_priv = (struct drm_radeon_driver_file_fields *)drm_alloc(sizeof(*radeon_priv), DRM_MEM_FILES);
 	
 	if (!radeon_priv)
 		return -ENOMEM;
@@ -2589,24 +2974,9 @@
 }
 
 
-static void radeon_driver_free_filp_priv(drm_device_t *dev, drm_file_t *filp_priv)
+void radeon_driver_free_filp_priv(drm_device_t *dev, drm_file_t *filp_priv)
 {
 	 struct drm_radeon_driver_file_fields *radeon_priv = filp_priv->driver_priv;
 	 
-	 DRM(free)(radeon_priv, sizeof(*radeon_priv), DRM_MEM_FILES);
-}
-
-void radeon_driver_register_fns(struct drm_device *dev)
-{	
-	dev->driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL;
-	dev->dev_priv_size = sizeof(drm_radeon_buf_priv_t);
-	dev->fn_tbl.prerelease = radeon_driver_prerelease;
-	dev->fn_tbl.pretakedown = radeon_driver_pretakedown;
-	dev->fn_tbl.open_helper = radeon_driver_open_helper;
-	dev->fn_tbl.free_filp_priv = radeon_driver_free_filp_priv;
-	dev->fn_tbl.vblank_wait = radeon_driver_vblank_wait;
- 	dev->fn_tbl.irq_preinstall = radeon_driver_irq_preinstall;
- 	dev->fn_tbl.irq_postinstall = radeon_driver_irq_postinstall;
- 	dev->fn_tbl.irq_uninstall = radeon_driver_irq_uninstall;
- 	dev->fn_tbl.irq_handler = radeon_driver_irq_handler;
+	 drm_free(radeon_priv, sizeof(*radeon_priv), DRM_MEM_FILES);
 }
diff -Nru a/drivers/char/drm/sis.h b/drivers/char/drm/sis.h
--- a/drivers/char/drm/sis.h	2005-03-01 23:39:17 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,61 +0,0 @@
-/* sis_drv.h -- Private header for sis driver -*- linux-c -*-
- *
- * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * All rights reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- * 
- */
-/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/sis.h,v 1.3 2002/10/30 12:52:38 alanh Exp $ */
-
-#ifndef __SIS_H__
-#define __SIS_H__
-
-/* This remains constant for all DRM template files.
- * Name it sisdrv_##x as there's a conflict with sis_free/malloc in the kernel
- * that's used for fb devices 
- */
-#ifdef __linux__
-#define DRM(x) sisdrv_##x
-#else
-#define DRM(x) sis_##x
-#endif
-
-/* General customization:
- */
-
-#define DRIVER_AUTHOR		"SIS"
-#define DRIVER_NAME		"sis"
-#define DRIVER_DESC		"SIS 300/630/540"
-#define DRIVER_DATE		"20030826"
-#define DRIVER_MAJOR		1
-#define DRIVER_MINOR		1
-#define DRIVER_PATCHLEVEL	0
-
-#define DRIVER_IOCTLS \
-	[DRM_IOCTL_NR(DRM_IOCTL_SIS_FB_ALLOC)]  = { sis_fb_alloc,	1, 0 }, \
-	[DRM_IOCTL_NR(DRM_IOCTL_SIS_FB_FREE)]   = { sis_fb_free,	1, 0 }, \
-	[DRM_IOCTL_NR(DRM_IOCTL_SIS_AGP_INIT)]  = { sis_ioctl_agp_init,	1, 1 }, \
-	[DRM_IOCTL_NR(DRM_IOCTL_SIS_AGP_ALLOC)] = { sis_ioctl_agp_alloc, 1, 0 }, \
-	[DRM_IOCTL_NR(DRM_IOCTL_SIS_AGP_FREE)]	= { sis_ioctl_agp_free,	1, 0 }, \
-	[DRM_IOCTL_NR(DRM_IOCTL_SIS_FB_INIT)]	= { sis_fb_init,	1, 1 }
-
-#endif
diff -Nru a/drivers/char/drm/sis_drm.h b/drivers/char/drm/sis_drm.h
--- a/drivers/char/drm/sis_drm.h	2005-03-01 23:39:18 -08:00
+++ b/drivers/char/drm/sis_drm.h	2005-03-01 23:39:18 -08:00
@@ -3,12 +3,21 @@
 #define __SIS_DRM_H__
 
 /* SiS specific ioctls */
-#define DRM_IOCTL_SIS_FB_ALLOC		DRM_IOWR(0x44, drm_sis_mem_t)
-#define DRM_IOCTL_SIS_FB_FREE		DRM_IOW( 0x45, drm_sis_mem_t)
-#define DRM_IOCTL_SIS_AGP_INIT		DRM_IOWR(0x53, drm_sis_agp_t)
-#define DRM_IOCTL_SIS_AGP_ALLOC		DRM_IOWR(0x54, drm_sis_mem_t)
-#define DRM_IOCTL_SIS_AGP_FREE		DRM_IOW( 0x55, drm_sis_mem_t)
-#define DRM_IOCTL_SIS_FB_INIT		DRM_IOW( 0x56, drm_sis_fb_t)
+#define NOT_USED_0_3
+#define DRM_SIS_FB_ALLOC	0x04
+#define DRM_SIS_FB_FREE	        0x05
+#define NOT_USED_6_12
+#define DRM_SIS_AGP_INIT	0x13
+#define DRM_SIS_AGP_ALLOC	0x14
+#define DRM_SIS_AGP_FREE	0x15
+#define DRM_SIS_FB_INIT	        0x16
+
+#define DRM_IOCTL_SIS_FB_ALLOC		DRM_IOWR(DRM_COMMAND_BASE + DRM_SIS_FB_ALLOC, drm_sis_mem_t)
+#define DRM_IOCTL_SIS_FB_FREE		DRM_IOW( DRM_COMMAND_BASE + DRM_SIS_FB_FREE, drm_sis_mem_t)
+#define DRM_IOCTL_SIS_AGP_INIT		DRM_IOWR(DRM_COMMAND_BASE + DRM_SIS_AGP_INIT, drm_sis_agp_t)
+#define DRM_IOCTL_SIS_AGP_ALLOC		DRM_IOWR(DRM_COMMAND_BASE + DRM_SIS_AGP_ALLOC, drm_sis_mem_t)
+#define DRM_IOCTL_SIS_AGP_FREE		DRM_IOW( DRM_COMMAND_BASE + DRM_SIS_AGP_FREE, drm_sis_mem_t)
+#define DRM_IOCTL_SIS_FB_INIT		DRM_IOW( DRM_COMMAND_BASE + DRM_SIS_FB_INIT, drm_sis_fb_t)
 /*
 #define DRM_IOCTL_SIS_FLIP		DRM_IOW( 0x48, drm_sis_flip_t)
 #define DRM_IOCTL_SIS_FLIP_INIT		DRM_IO(  0x49)
diff -Nru a/drivers/char/drm/sis_drv.c b/drivers/char/drm/sis_drv.c
--- a/drivers/char/drm/sis_drv.c	2005-03-01 23:38:44 -08:00
+++ b/drivers/char/drm/sis_drv.c	2005-03-01 23:38:44 -08:00
@@ -26,9 +26,85 @@
  */
 
 #include <linux/config.h>
-#include "sis.h"
 #include "drmP.h"
 #include "sis_drm.h"
 #include "sis_drv.h"
 
-#include "drm_core.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->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[] = {
+	sisdrv_PCI_IDS
+};
+
+extern drm_ioctl_desc_t sis_ioctls[];
+extern int sis_max_ioctl;
+
+static struct drm_driver driver = {
+	.driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR,
+	.context_ctor = sis_init_context,
+	.context_dtor = sis_final_context,
+	.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 = sis_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 sis_init(void)
+{
+	driver.num_ioctls = sis_max_ioctl;
+	return drm_init(&driver);
+}
+
+static void __exit sis_exit(void)
+{
+	drm_exit(&driver);
+}
+
+module_init(sis_init);
+module_exit(sis_exit);
+
+MODULE_AUTHOR( DRIVER_AUTHOR );
+MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_LICENSE("GPL and additional rights");
diff -Nru a/drivers/char/drm/sis_drv.h b/drivers/char/drm/sis_drv.h
--- a/drivers/char/drm/sis_drv.h	2005-03-01 23:38:53 -08:00
+++ b/drivers/char/drm/sis_drv.h	2005-03-01 23:38:53 -08:00
@@ -28,6 +28,17 @@
 #ifndef _SIS_DRV_H_
 #define _SIS_DRV_H_
 
+/* General customization:
+ */
+
+#define DRIVER_AUTHOR		"SIS"
+#define DRIVER_NAME		"sis"
+#define DRIVER_DESC		"SIS 300/630/540"
+#define DRIVER_DATE		"20030826"
+#define DRIVER_MAJOR		1
+#define DRIVER_MINOR		1
+#define DRIVER_PATCHLEVEL	0
+
 #include "sis_ds.h"
 
 typedef struct drm_sis_private {
@@ -41,5 +52,8 @@
 extern int sis_ioctl_agp_alloc( DRM_IOCTL_ARGS );
 extern int sis_ioctl_agp_free( DRM_IOCTL_ARGS );
 extern int sis_fb_init( DRM_IOCTL_ARGS );
+
+extern int sis_init_context(drm_device_t *dev, int context);
+extern int sis_final_context(drm_device_t *dev, int context);
 
 #endif
diff -Nru a/drivers/char/drm/sis_ds.c b/drivers/char/drm/sis_ds.c
--- a/drivers/char/drm/sis_ds.c	2005-03-01 23:39:10 -08:00
+++ b/drivers/char/drm/sis_ds.c	2005-03-01 23:39:10 -08:00
@@ -28,7 +28,6 @@
  * 
  */
 
-#include "sis.h"
 #include "drmP.h"
 #include "drm.h"
 #include "sis_ds.h"
@@ -42,7 +41,7 @@
 	int i;
 	set_t *set;
 
-	set = (set_t *)DRM(alloc)(sizeof(set_t), DRM_MEM_DRIVER);
+	set = (set_t *)drm_alloc(sizeof(set_t), DRM_MEM_DRIVER);
 	if (set != NULL) {
 		for (i = 0; i < SET_SIZE; i++) {
 			set->list[i].free_next = i + 1;    
@@ -128,14 +127,14 @@
 
 int setDestroy(set_t *set)
 {
-	DRM(free)(set, sizeof(set_t), DRM_MEM_DRIVER);
+	drm_free(set, sizeof(set_t), DRM_MEM_DRIVER);
 
 	return 1;
 }
 
 /*
  * GLX Hardware Device Driver common code
- * Copyright (C) 1999 Keith Whitwell
+ * Copyright (C) 1999 Wittawat Yamwong
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -150,7 +149,7 @@
  * 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
- * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, 
+ * WITTAWAT YAMWONG, OR ANY OTHER CONTRIBUTORS 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.
@@ -167,7 +166,7 @@
 	if (size <= 0)
 		return NULL;
 
-	blocks = (TMemBlock *)DRM(calloc)(1, sizeof(TMemBlock), DRM_MEM_DRIVER);
+	blocks = (TMemBlock *)drm_calloc(1, sizeof(TMemBlock), DRM_MEM_DRIVER);
 	if (blocks != NULL) {
 		blocks->ofs = ofs;
 		blocks->size = size;
@@ -202,7 +201,7 @@
 		       int size )
 {
 	PMemBlock blocks;
-	blocks = (TMemBlock *)DRM(calloc)(2, sizeof(TMemBlock), DRM_MEM_DRIVER);
+	blocks = (TMemBlock *)drm_calloc(2, sizeof(TMemBlock), DRM_MEM_DRIVER);
 	if (blocks != NULL) {
 		blocks[0].size = size;
 		blocks[0].free = 1;
@@ -229,7 +228,7 @@
 
 	/* break left */
 	if (startofs > p->ofs) {
-		newblock = (TMemBlock*) DRM(calloc)(1, sizeof(TMemBlock),
+		newblock = (TMemBlock*) drm_calloc(1, sizeof(TMemBlock),
 		    DRM_MEM_DRIVER);
 		newblock->ofs = startofs;
 		newblock->size = p->size - (startofs - p->ofs);
@@ -242,7 +241,7 @@
 
 	/* break right */
 	if (size < p->size) {
-		newblock = (TMemBlock*) DRM(calloc)(1, sizeof(TMemBlock),
+		newblock = (TMemBlock*) drm_calloc(1, sizeof(TMemBlock),
 		    DRM_MEM_DRIVER);
 		newblock->ofs = startofs + size;
 		newblock->size = p->size - size;
@@ -295,7 +294,7 @@
 		TMemBlock *q = p->next;
 		p->size += q->size;
 		p->next = q->next;
-		DRM(free)(q, sizeof(TMemBlock), DRM_MEM_DRIVER);
+		drm_free(q, sizeof(TMemBlock), DRM_MEM_DRIVER);
 		return 1;
 	}
 	return 0;
@@ -380,7 +379,7 @@
 	p = (TMemBlock *)heap;
 	while (p != NULL) {
 		q = p->next;
-		DRM(free)(p, sizeof(TMemBlock), DRM_MEM_DRIVER);
+		drm_free(p, sizeof(TMemBlock), DRM_MEM_DRIVER);
 		p = q;
 	}
 }
diff -Nru a/drivers/char/drm/sis_ds.h b/drivers/char/drm/sis_ds.h
--- a/drivers/char/drm/sis_ds.h	2005-03-01 23:38:57 -08:00
+++ b/drivers/char/drm/sis_ds.h	2005-03-01 23:38:57 -08:00
@@ -58,7 +58,7 @@
 
 /*
  * GLX Hardware Device Driver common code
- * Copyright (C) 1999 Keith Whitwell
+ * Copyright (C) 1999 Wittawat Yamwong
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -73,7 +73,7 @@
  * 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
- * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, 
+ * WITTAWAT YAMWONG, OR ANY OTHER CONTRIBUTORS 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.
@@ -85,8 +85,8 @@
 	struct mem_block_t *heap;
 	int ofs,size;
 	int align;
-	int free:1;
-	int reserved:1;
+	unsigned int free:1;
+	unsigned int reserved:1;
 };
 typedef struct mem_block_t TMemBlock;
 typedef struct mem_block_t *PMemBlock;
diff -Nru a/drivers/char/drm/sis_mm.c b/drivers/char/drm/sis_mm.c
--- a/drivers/char/drm/sis_mm.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/char/drm/sis_mm.c	2005-03-01 23:39:07 -08:00
@@ -28,7 +28,6 @@
  * 
  */
 
-#include "sis.h"
 #include "drmP.h"
 #include "sis_drm.h"
 #include "sis_drv.h"
@@ -37,6 +36,17 @@
 #include <video/sisfb.h>
 #endif
 
+drm_ioctl_desc_t sis_ioctls[] = {
+	[DRM_IOCTL_NR(DRM_SIS_FB_ALLOC)]  = { sis_fb_alloc,        1, 0 },
+	[DRM_IOCTL_NR(DRM_SIS_FB_FREE)]   = { sis_fb_free,         1, 0 },
+	[DRM_IOCTL_NR(DRM_SIS_AGP_INIT)]  = { sis_ioctl_agp_init,  1, 1 },
+	[DRM_IOCTL_NR(DRM_SIS_AGP_ALLOC)] = { sis_ioctl_agp_alloc, 1, 0 },
+	[DRM_IOCTL_NR(DRM_SIS_AGP_FREE)]  = { sis_ioctl_agp_free,  1, 0 },
+	[DRM_IOCTL_NR(DRM_SIS_FB_INIT)]   = { sis_fb_init,         1, 1 }
+};
+
+int sis_max_ioctl = DRM_ARRAY_SIZE(sis_ioctls);
+
 #define MAX_CONTEXT 100
 #define VIDEO_TYPE 0 
 #define AGP_TYPE 1
@@ -159,7 +169,7 @@
 	DRM_COPY_FROM_USER_IOCTL(fb, (drm_sis_fb_t __user *)data, sizeof(fb));
 
 	if (dev_priv == NULL) {
-		dev->dev_private = DRM(calloc)(1, sizeof(drm_sis_private_t),
+		dev->dev_private = drm_calloc(1, sizeof(drm_sis_private_t),
 		    DRM_MEM_DRIVER);
 		dev_priv = dev->dev_private;
 		if (dev_priv == NULL)
@@ -247,7 +257,7 @@
 	drm_sis_agp_t agp;
 
 	if (dev_priv == NULL) {
-		dev->dev_private = DRM(calloc)(1, sizeof(drm_sis_private_t),
+		dev->dev_private = drm_calloc(1, sizeof(drm_sis_private_t),
 		    DRM_MEM_DRIVER);
 		dev_priv = dev->dev_private;
 		if (dev_priv == NULL)
@@ -403,11 +413,4 @@
         }
 	
 	return 1;
-}
-
-void DRM(driver_register_fns)(drm_device_t *dev)
-{
-	dev->driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR;
-	dev->fn_tbl.context_ctor = sis_init_context;
-	dev->fn_tbl.context_dtor = sis_final_context;
 }
diff -Nru a/drivers/char/drm/tdfx.h b/drivers/char/drm/tdfx.h
--- a/drivers/char/drm/tdfx.h	2005-03-01 23:38:57 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,50 +0,0 @@
-/* tdfx.h -- 3dfx DRM template customization -*- linux-c -*-
- * Created: Wed Feb 14 12:32:32 2001 by gareth@valinux.com
- *
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- *    Gareth Hughes <gareth@valinux.com>
- */
-
-#ifndef __TDFX_H__
-#define __TDFX_H__
-
-/* This remains constant for all DRM template files.
- */
-#define DRM(x) tdfx_##x
-
-/* General customization:
- */
-
-#define DRIVER_AUTHOR		"VA Linux Systems Inc."
-
-#define DRIVER_NAME		"tdfx"
-#define DRIVER_DESC		"3dfx Banshee/Voodoo3+"
-#define DRIVER_DATE		"20010216"
-
-#define DRIVER_MAJOR		1
-#define DRIVER_MINOR		0
-#define DRIVER_PATCHLEVEL	0
-
-#endif
diff -Nru a/drivers/char/drm/tdfx_drv.c b/drivers/char/drm/tdfx_drv.c
--- a/drivers/char/drm/tdfx_drv.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/char/drm/tdfx_drv.c	2005-03-01 23:38:57 -08:00
@@ -31,13 +31,77 @@
  */
 
 #include <linux/config.h>
-#include "tdfx.h"
 #include "drmP.h"
+#include "tdfx_drv.h"
 
-#include "drm_core.h"
+#include "drm_pciids.h"
 
-void DRM(driver_register_fns)(drm_device_t *dev)
+static int postinit( struct drm_device *dev, unsigned long flags )
 {
-	dev->driver_features = DRIVER_USE_MTRR;
+	DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d: %s\n",
+		DRIVER_NAME,
+		DRIVER_MAJOR,
+		DRIVER_MINOR,
+		DRIVER_PATCHLEVEL,
+		DRIVER_DATE,
+		dev->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[] = {
+	tdfx_PCI_IDS
+};
+
+static struct drm_driver driver = {
+	.driver_features = DRIVER_USE_MTRR,
+	.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,
+	.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 tdfx_init(void)
+{
+	return drm_init(&driver);
+}
+
+static void __exit tdfx_exit(void)
+{
+	drm_exit(&driver);
+}
+
+module_init(tdfx_init);
+module_exit(tdfx_exit);
+
+MODULE_AUTHOR( DRIVER_AUTHOR );
+MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_LICENSE("GPL and additional rights");
diff -Nru a/drivers/char/drm/tdfx_drv.h b/drivers/char/drm/tdfx_drv.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/char/drm/tdfx_drv.h	2005-03-01 23:38:57 -08:00
@@ -0,0 +1,50 @@
+/* tdfx.h -- 3dfx DRM template customization -*- linux-c -*-
+ * Created: Wed Feb 14 12:32:32 2001 by gareth@valinux.com
+ *
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Gareth Hughes <gareth@valinux.com>
+ */
+
+#ifndef __TDFX_H__
+#define __TDFX_H__
+
+/* This remains constant for all DRM template files.
+ */
+#define DRM(x) tdfx_##x
+
+/* General customization:
+ */
+
+#define DRIVER_AUTHOR		"VA Linux Systems Inc."
+
+#define DRIVER_NAME		"tdfx"
+#define DRIVER_DESC		"3dfx Banshee/Voodoo3+"
+#define DRIVER_DATE		"20010216"
+
+#define DRIVER_MAJOR		1
+#define DRIVER_MINOR		0
+#define DRIVER_PATCHLEVEL	0
+
+#endif
diff -Nru a/drivers/char/ds1286.c b/drivers/char/ds1286.c
--- a/drivers/char/ds1286.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/char/ds1286.c	2005-03-01 23:38:56 -08:00
@@ -68,7 +68,7 @@
 
 static inline unsigned char ds1286_is_updating(void);
 
-static spinlock_t ds1286_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(ds1286_lock);
 
 static int ds1286_read_proc(char *page, char **start, off_t off,
                             int count, int *eof, void *data);
diff -Nru a/drivers/char/ec3104_keyb.c b/drivers/char/ec3104_keyb.c
--- a/drivers/char/ec3104_keyb.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/char/ec3104_keyb.c	2005-03-01 23:38:56 -08:00
@@ -92,7 +92,7 @@
 static void __aux_write_ack(int val);
 #endif
 
-static spinlock_t kbd_controller_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(kbd_controller_lock);
 static unsigned char handle_kbd_event(void);
 
 /* used only by send_data - set by keyboard_interrupt */
diff -Nru a/drivers/char/efirtc.c b/drivers/char/efirtc.c
--- a/drivers/char/efirtc.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/char/efirtc.c	2005-03-01 23:39:08 -08:00
@@ -48,7 +48,7 @@
  */
 #define EFI_RTC_EPOCH		1998
 
-static spinlock_t efi_rtc_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(efi_rtc_lock);
 
 static int efi_rtc_ioctl(struct inode *inode, struct file *file,
 		     unsigned int cmd, unsigned long arg);
diff -Nru a/drivers/char/esp.c b/drivers/char/esp.c
--- a/drivers/char/esp.c	2005-03-01 23:38:44 -08:00
+++ b/drivers/char/esp.c	2005-03-01 23:38:44 -08:00
@@ -2401,7 +2401,7 @@
 /*
  * The serial driver boot-time initialization code!
  */
-int __init espserial_init(void)
+static int __init espserial_init(void)
 {
 	int i, offset;
 	struct esp_struct * info;
diff -Nru a/drivers/char/ftape/compressor/zftape-compress.c b/drivers/char/ftape/compressor/zftape-compress.c
--- a/drivers/char/ftape/compressor/zftape-compress.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/char/ftape/compressor/zftape-compress.c	2005-03-01 23:39:09 -08:00
@@ -27,11 +27,6 @@
  *     changed * appropriately. See below.
  */
 
- char zftc_src[] ="$Source: /homes/cvs/ftape-stacked/ftape/compressor/zftape-compress.c,v $";
- char zftc_rev[] = "$Revision: 1.1.6.1 $";
- char zftc_dat[] = "$Date: 1997/11/16 15:15:56 $";
-
-#include <linux/version.h>
 #include <linux/errno.h>
 #include <linux/mm.h>
 #include <linux/module.h>
@@ -1177,12 +1172,11 @@
         if (TRACE_LEVEL >= ft_t_info) {
 		printk(
 KERN_INFO "(c) 1997 Claus-Justus Heine (claus@momo.math.rwth-aachen.de)\n"
-KERN_INFO "Compressor for zftape (lzrw3 algorithm)\n"
-KERN_INFO "Compiled for kernel version %s\n", UTS_RELEASE);
+KERN_INFO "Compressor for zftape (lzrw3 algorithm)\n");
         }
 #else /* !MODULE */
 	/* print a short no-nonsense boot message */
-	printk("zftape compressor v1.00a 970514 for Linux " UTS_RELEASE "\n");
+	printk("zftape compressor v1.00a 970514\n");
 	printk("For use with " FTAPE_VERSION "\n");
 #endif /* MODULE */
 	TRACE(ft_t_info, "zft_compressor_init @ 0x%p", zft_compressor_init);
diff -Nru a/drivers/char/ftape/lowlevel/fc-10.c b/drivers/char/ftape/lowlevel/fc-10.c
--- a/drivers/char/ftape/lowlevel/fc-10.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/char/ftape/lowlevel/fc-10.c	2005-03-01 23:38:52 -08:00
@@ -56,13 +56,13 @@
 #include "../lowlevel/fdc-io.h"
 #include "../lowlevel/fc-10.h"
 
-__u16 inbs_magic[] = {
+static __u16 inbs_magic[] = {
 	0x3, 0x3, 0x0, 0x4, 0x7, 0x2, 0x5, 0x3, 0x1, 0x4,
 	0x3, 0x5, 0x2, 0x0, 0x3, 0x7, 0x4, 0x2,
 	0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7
 };
 
-__u16 fc10_ports[] = {
+static __u16 fc10_ports[] = {
 	0x180, 0x210, 0x2A0, 0x300, 0x330, 0x340, 0x370
 };
 
diff -Nru a/drivers/char/ftape/lowlevel/fdc-io.c b/drivers/char/ftape/lowlevel/fdc-io.c
--- a/drivers/char/ftape/lowlevel/fdc-io.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/char/ftape/lowlevel/fdc-io.c	2005-03-01 23:39:18 -08:00
@@ -50,7 +50,7 @@
 
 /*      Global vars.
  */
-int ftape_motor;
+static int ftape_motor;
 volatile int ftape_current_cylinder = -1;
 volatile fdc_mode_enum fdc_mode = fdc_idle;
 fdc_config_info fdc;
@@ -86,6 +86,8 @@
 
 static char ftape_id[] = "ftape";  /* used by request irq and free irq */
 
+static int fdc_set_seek_rate(int seek_rate);
+
 void fdc_catch_stray_interrupts(int count)
 {
 	unsigned long flags;
@@ -103,7 +105,7 @@
  *  If usecs == 0 then just test status, else wait at least for usecs.
  *  Returns -ETIME on timeout. Function must be calibrated first !
  */
-int fdc_wait(unsigned int usecs, __u8 mask, __u8 state)
+static int fdc_wait(unsigned int usecs, __u8 mask, __u8 state)
 {
 	int count_1 = (fdc_calibr_count * usecs +
                        fdc_calibr_count - 1) / fdc_calibr_time;
@@ -129,18 +131,12 @@
 	fdc_wait(usecs, 0, 1);	/* will always timeout ! */
 }
 
-int fdc_ready_out_wait(unsigned int usecs)
+static int fdc_ready_out_wait(unsigned int usecs)
 {
 	fdc_usec_wait(FT_RQM_DELAY);	/* wait for valid RQM status */
 	return fdc_wait(usecs, FDC_DATA_OUT_READY, FDC_DATA_OUT_READY);
 }
 
-int fdc_ready_in_wait(unsigned int usecs)
-{
-	fdc_usec_wait(FT_RQM_DELAY);	/* wait for valid RQM status */
-	return fdc_wait(usecs, FDC_DATA_OUT_READY, FDC_DATA_IN_READY);
-}
-
 void fdc_wait_calibrate(void)
 {
 	ftape_calibrate("fdc_wait",
@@ -341,7 +337,7 @@
 /*      Handle command and result phases for
  *      commands without data phase.
  */
-int fdc_issue_command(const __u8 * out_data, int out_count,
+static int fdc_issue_command(const __u8 * out_data, int out_count,
 		      __u8 * in_data, int in_count)
 {
 	TRACE_FUN(ft_t_any);
@@ -497,7 +493,7 @@
 
 /*  Reprogram the 82078 registers to use Data Rate Table 1 on all drives.
  */
-void fdc_set_drive_specs(void)
+static void fdc_set_drive_specs(void)
 {
 	__u8 cmd[] = { FDC_DRIVE_SPEC, 0x00, 0x00, 0x00, 0x00, 0xc0};
 	int result;
@@ -705,7 +701,7 @@
 
 /*      Specify FDC seek-rate (milliseconds)
  */
-int fdc_set_seek_rate(int seek_rate)
+static int fdc_set_seek_rate(int seek_rate)
 {
 	/* set step rate, dma mode, and minimal head load and unload times
 	 */
@@ -803,49 +799,6 @@
 	TRACE_EXIT 0;
 }
 
-/*      Recalibrate and wait until home.
- */
-int fdc_recalibrate(void)
-{
-	__u8 out[2];
-	int st0;
-	int pcn;
-	int retry;
-	int old_seek_rate = fdc_seek_rate;
-	TRACE_FUN(ft_t_any);
-
-	TRACE_CATCH(fdc_set_seek_rate(6),);
-	out[0] = FDC_RECAL;
-	out[1] = ft_drive_sel;
-	ft_seek_completed = 0;
-	TRACE_CATCH(fdc_command(out, 2),);
-	/*    Handle interrupts until ft_seek_completed or timeout.
-	 */
-	for (retry = 0;; ++retry) {
-		TRACE_CATCH(fdc_interrupt_wait(2 * FT_SECOND),);
-		if (ft_seek_completed) {
-			TRACE_CATCH(fdc_sense_interrupt_status(&st0, &pcn),);
-			if ((st0 & ST0_SEEK_END) == 0) {
-				if (retry < 1) {
-					continue; /* some drives/fdc's
-						   * give an extra interrupt
-						   */
-				} else {
-					TRACE_ABORT(-EIO, ft_t_err,
-				    "no seek-end after seek completion !??");
-				}
-			}
-			break;
-		}
-	}
-	ftape_current_cylinder = pcn;
-	if (pcn != 0) {
-		TRACE(ft_t_err, "failed: resulting track = %d", pcn);
-	}
-	TRACE_CATCH(fdc_set_seek_rate(old_seek_rate),);
-	TRACE_EXIT 0;
-}
-
 static int perpend_mode; /* set if fdc is in perpendicular mode */
 
 static int perpend_off(void)
@@ -1079,7 +1032,7 @@
  */
 static __u8 fdc_save_state[2];
 
-int fdc_probe(void)
+static int fdc_probe(void)
 {
 	__u8 cmd[1];
 	__u8 stat[16]; /* must be able to hold dumpregs & save results */
@@ -1308,7 +1261,7 @@
 	TRACE_EXIT IRQ_RETVAL(handled);
 }
 
-int fdc_grab_irq_and_dma(void)
+static int fdc_grab_irq_and_dma(void)
 {
 	TRACE_FUN(ft_t_any);
 
diff -Nru a/drivers/char/ftape/lowlevel/fdc-io.h b/drivers/char/ftape/lowlevel/fdc-io.h
--- a/drivers/char/ftape/lowlevel/fdc-io.h	2005-03-01 23:39:09 -08:00
+++ b/drivers/char/ftape/lowlevel/fdc-io.h	2005-03-01 23:39:09 -08:00
@@ -210,7 +210,6 @@
 extern volatile fdc_mode_enum fdc_mode;
 extern int fdc_setup_error;	/* outdated ??? */
 extern wait_queue_head_t ftape_wait_intr;
-extern int ftape_motor;		/* fdc motor line state */
 extern volatile int ftape_current_cylinder; /* track nr FDC thinks we're on */
 extern volatile __u8 fdc_head;	/* FDC head */
 extern volatile __u8 fdc_cyl;	/* FDC track */
@@ -231,15 +230,11 @@
 extern int fdc_ready_wait(unsigned int timeout);
 extern int fdc_command(const __u8 * cmd_data, int cmd_len);
 extern int fdc_result(__u8 * res_data, int res_len);
-extern int fdc_issue_command(const __u8 * out_data, int out_count,
-			     __u8 * in_data, int in_count);
 extern int fdc_interrupt_wait(unsigned int time);
-extern int fdc_set_seek_rate(int seek_rate);
 extern int fdc_seek(int track);
 extern int fdc_sense_drive_status(int *st3);
 extern void fdc_motor(int motor);
 extern void fdc_reset(void);
-extern int fdc_recalibrate(void);
 extern void fdc_disable(void);
 extern int fdc_fifo_threshold(__u8 threshold,
 			      int *fifo_state, int *lock_state, int *fifo_thr);
diff -Nru a/drivers/char/ftape/lowlevel/ftape-bsm.c b/drivers/char/ftape/lowlevel/ftape-bsm.c
--- a/drivers/char/ftape/lowlevel/ftape-bsm.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/char/ftape/lowlevel/ftape-bsm.c	2005-03-01 23:38:54 -08:00
@@ -47,6 +47,10 @@
 } mode_type;
 
 #if 0
+static void ftape_put_bad_sector_entry(int segment_id, SectorMap new_map);
+#endif
+
+#if 0
 /*  fix_tape converts a normal QIC-80 tape into a 'wide' tape.
  *  For testing purposes only !
  */
@@ -375,7 +379,8 @@
 	}
 }
 
-void ftape_put_bad_sector_entry(int segment_id, SectorMap new_map)
+#if 0
+static void ftape_put_bad_sector_entry(int segment_id, SectorMap new_map)
 {
 	SectorCount *ptr = (SectorCount *)bad_sector_map;
 	int count;
@@ -438,6 +443,7 @@
 	}
 	TRACE_EXIT;
 }
+#endif  /*  0  */
 
 SectorMap ftape_get_bad_sector_entry(int segment_id)
 {
diff -Nru a/drivers/char/ftape/lowlevel/ftape-bsm.h b/drivers/char/ftape/lowlevel/ftape-bsm.h
--- a/drivers/char/ftape/lowlevel/ftape-bsm.h	2005-03-01 23:38:43 -08:00
+++ b/drivers/char/ftape/lowlevel/ftape-bsm.h	2005-03-01 23:38:43 -08:00
@@ -60,7 +60,6 @@
 extern void update_bad_sector_map(__u8 * buffer);
 extern void ftape_extract_bad_sector_map(__u8 * buffer);
 extern SectorMap ftape_get_bad_sector_entry(int segment_id);
-extern void      ftape_put_bad_sector_entry(int segment_id, SectorMap mask);
 extern __u8 *ftape_find_end_of_bsm_list(__u8 * address);
 extern void ftape_init_bsm(void);
 
diff -Nru a/drivers/char/ftape/lowlevel/ftape-ctl.c b/drivers/char/ftape/lowlevel/ftape-ctl.c
--- a/drivers/char/ftape/lowlevel/ftape-ctl.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/char/ftape/lowlevel/ftape-ctl.c	2005-03-01 23:39:17 -08:00
@@ -113,11 +113,6 @@
 #endif
 }
 
-void ftape_set_status(const ftape_info *status)
-{
-	ftape_status = *status;
-}
-
 static int ftape_not_operational(int status)
 {
 	/* return true if status indicates tape can not be used.
@@ -210,7 +205,7 @@
 	return i;
 }
 
-void ftape_detach_drive(void)
+static void ftape_detach_drive(void)
 {
 	TRACE_FUN(ft_t_any);
 
@@ -241,7 +236,7 @@
 		ft_history.rewinds = 0;
 }
 
-int ftape_activate_drive(vendor_struct * drive_type)
+static int ftape_activate_drive(vendor_struct * drive_type)
 {
 	int result = 0;
 	TRACE_FUN(ft_t_flow);
@@ -301,7 +296,7 @@
 	TRACE_EXIT result;
 }
 
-int ftape_get_drive_status(void)
+static int ftape_get_drive_status(void)
 {
 	int result;
 	int status;
@@ -374,7 +369,7 @@
 	TRACE_EXIT 0;
 }
 
-void ftape_log_vendor_id(void)
+static void ftape_log_vendor_id(void)
 {
 	int vendor_index;
 	TRACE_FUN(ft_t_flow);
@@ -580,7 +575,7 @@
 	TRACE_EXIT 0;
 }
 
-int ftape_init_drive(void)
+static int ftape_init_drive(void)
 {
 	int status;
 	qic_model model;
diff -Nru a/drivers/char/ftape/lowlevel/ftape-ctl.h b/drivers/char/ftape/lowlevel/ftape-ctl.h
--- a/drivers/char/ftape/lowlevel/ftape-ctl.h	2005-03-01 23:38:43 -08:00
+++ b/drivers/char/ftape/lowlevel/ftape-ctl.h	2005-03-01 23:38:43 -08:00
@@ -158,6 +158,5 @@
 				 unsigned int data_rate,
 				 unsigned int tape_len);
 extern int  ftape_calibrate_data_rate(unsigned int qic_std);
-extern int  ftape_init_drive(void);
 extern const ftape_info *ftape_get_status(void);
 #endif
diff -Nru a/drivers/char/ftape/lowlevel/ftape-init.c b/drivers/char/ftape/lowlevel/ftape-init.c
--- a/drivers/char/ftape/lowlevel/ftape-init.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/char/ftape/lowlevel/ftape-init.c	2005-03-01 23:39:09 -08:00
@@ -23,7 +23,6 @@
 
 #include <linux/config.h>
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/errno.h>
 #include <linux/fs.h>
 #include <linux/kernel.h>
@@ -48,12 +47,6 @@
 #include "../lowlevel/ftape-proc.h"
 #include "../lowlevel/ftape-tracing.h"
 
-/*      Global vars.
- */
-char ft_src[] __initdata = "$Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-init.c,v $";
-char ft_rev[] __initdata = "$Revision: 1.8 $";
-char ft_dat[] __initdata = "$Date: 1997/11/06 00:38:08 $";
-
 
 #if defined(MODULE) && !defined(CONFIG_FT_NO_TRACE_AT_ALL)
 static int ft_tracing = -1;
@@ -79,12 +72,11 @@
 KERN_INFO "(c) 1993-1996 Bas Laarhoven (bas@vimec.nl)\n"
 KERN_INFO "(c) 1995-1996 Kai Harrekilde-Petersen (khp@dolphinics.no)\n"
 KERN_INFO "(c) 1996-1997 Claus-Justus Heine (claus@momo.math.rwth-aachen.de)\n"
-KERN_INFO "QIC-117 driver for QIC-40/80/3010/3020 floppy tape drives\n"
-KERN_INFO "Compiled for Linux version %s\n", UTS_RELEASE);
+KERN_INFO "QIC-117 driver for QIC-40/80/3010/3020 floppy tape drives\n");
         }
 #else /* !MODULE */
 	/* print a short no-nonsense boot message */
-	printk(KERN_INFO FTAPE_VERSION " for Linux " UTS_RELEASE "\n");
+	printk(KERN_INFO FTAPE_VERSION "\n");
 #endif /* MODULE */
 	TRACE(ft_t_info, "installing QIC-117 floppy tape hardware drive ... ");
 	TRACE(ft_t_info, "ftape_init @ 0x%p", ftape_init);
diff -Nru a/drivers/char/ftape/lowlevel/ftape-io.c b/drivers/char/ftape/lowlevel/ftape-io.c
--- a/drivers/char/ftape/lowlevel/ftape-io.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/char/ftape/lowlevel/ftape-io.c	2005-03-01 23:38:55 -08:00
@@ -350,7 +350,7 @@
 	return result;
 }
 
-int ftape_parameter_wait(unsigned int parm, unsigned int timeout, int *status)
+static int ftape_parameter_wait(unsigned int parm, unsigned int timeout, int *status)
 {
 	int result;
 
@@ -503,16 +503,6 @@
 	TRACE_EXIT 0;
 }
 
-int ftape_in_error_state(int status)
-{
-	TRACE_FUN(ft_t_any);
-
-	if ((status & QIC_STATUS_READY) && (status & QIC_STATUS_ERROR)) {
-		TRACE_ABORT(1, ft_t_warn, "warning: error status set!");
-	}
-	TRACE_EXIT 0;
-}
-
 int ftape_report_configuration(qic_model *model,
 			       unsigned int *rate,
 			       int *qic_std,
@@ -617,7 +607,7 @@
 	TRACE_EXIT (result < 0) ? -EIO : 0;
 }
 
-int ftape_report_rom_version(int *version)
+static int ftape_report_rom_version(int *version)
 {
 
 	if (ftape_report_operation(version, QIC_REPORT_ROM_VERSION, 8) < 0) {
@@ -625,16 +615,6 @@
 	} else {
 		return 0;
 	}
-}
-
-int ftape_report_signature(int *signature)
-{
-	int result;
-
-	result = ftape_command(28);
-	result = ftape_report_operation(signature, 9, 8);
-	result = ftape_command(30);
-	return (result < 0) ? -EIO : 0;
 }
 
 void ftape_report_vendor_id(unsigned int *id)
diff -Nru a/drivers/char/ftape/lowlevel/ftape-io.h b/drivers/char/ftape/lowlevel/ftape-io.h
--- a/drivers/char/ftape/lowlevel/ftape-io.h	2005-03-01 23:38:57 -08:00
+++ b/drivers/char/ftape/lowlevel/ftape-io.h	2005-03-01 23:38:57 -08:00
@@ -65,9 +65,6 @@
 			       unsigned int timeout,
 			       int *status);
 extern int  ftape_parameter(unsigned int parameter);
-extern int  ftape_parameter_wait(unsigned int parameter,
-				 unsigned int timeout,
-				 int *status);
 extern int ftape_report_operation(int *status,
 				  qic117_cmd_t  command,
 				  int result_length);
@@ -80,7 +77,6 @@
 extern int ftape_report_status(int *status);
 extern int ftape_ready_wait(unsigned int timeout, int *status);
 extern int ftape_seek_head_to_track(unsigned int track);
-extern int ftape_in_error_state(int status);
 extern int ftape_set_data_rate(unsigned int new_rate, unsigned int qic_std);
 extern int ftape_report_error(unsigned int *error,
 			      qic117_cmd_t *command,
diff -Nru a/drivers/char/ftape/lowlevel/ftape-proc.c b/drivers/char/ftape/lowlevel/ftape-proc.c
--- a/drivers/char/ftape/lowlevel/ftape-proc.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/char/ftape/lowlevel/ftape-proc.c	2005-03-01 23:39:16 -08:00
@@ -174,8 +174,8 @@
 	return len;
 }
 
-int ftape_read_proc(char *page, char **start, off_t off,
-		    int count, int *eof, void *data)
+static int ftape_read_proc(char *page, char **start, off_t off,
+			   int count, int *eof, void *data)
 {
 	char *ptr = page;
 	size_t len;
diff -Nru a/drivers/char/ftape/lowlevel/ftape-rw.c b/drivers/char/ftape/lowlevel/ftape-rw.c
--- a/drivers/char/ftape/lowlevel/ftape-rw.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/char/ftape/lowlevel/ftape-rw.c	2005-03-01 23:38:56 -08:00
@@ -301,7 +301,7 @@
 
 /*      Read Id of first sector passing tape head.
  */
-int ftape_read_id(void)
+static int ftape_read_id(void)
 {
 	int status;
 	__u8 out[2];
diff -Nru a/drivers/char/ftape/lowlevel/ftape-rw.h b/drivers/char/ftape/lowlevel/ftape-rw.h
--- a/drivers/char/ftape/lowlevel/ftape-rw.h	2005-03-01 23:39:16 -08:00
+++ b/drivers/char/ftape/lowlevel/ftape-rw.h	2005-03-01 23:39:16 -08:00
@@ -101,7 +101,6 @@
 extern buffer_struct *ftape_get_buffer  (ft_buffer_queue_t pos);
 extern int            ftape_buffer_id   (ft_buffer_queue_t pos);
 extern void           ftape_reset_buffer(void);
-extern int  ftape_read_id(void);
 extern void ftape_tape_parameters(__u8 drive_configuration);
 extern int  ftape_wait_segment(buffer_state_enum state);
 extern int  ftape_dumb_stop(void);
diff -Nru a/drivers/char/ftape/zftape/zftape-buffers.c b/drivers/char/ftape/zftape/zftape-buffers.c
--- a/drivers/char/ftape/zftape/zftape-buffers.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/char/ftape/zftape/zftape-buffers.c	2005-03-01 23:39:18 -08:00
@@ -87,13 +87,6 @@
 	TRACE_ABORT(0, ft_t_noise,
 		    "allocated buffer @ %p, %d bytes", *(void **)new, size);
 }
-int zft_vcalloc_always(void *new, size_t size)
-{
-	TRACE_FUN(ft_t_flow);
-
-	zft_vfree(new, size);
-	TRACE_EXIT zft_vcalloc_once(new, size);
-}
 int zft_vmalloc_always(void *new, size_t size)
 {
 	TRACE_FUN(ft_t_flow);
diff -Nru a/drivers/char/ftape/zftape/zftape-buffers.h b/drivers/char/ftape/zftape/zftape-buffers.h
--- a/drivers/char/ftape/zftape/zftape-buffers.h	2005-03-01 23:39:18 -08:00
+++ b/drivers/char/ftape/zftape/zftape-buffers.h	2005-03-01 23:39:18 -08:00
@@ -37,7 +37,6 @@
 extern int   zft_vmalloc_once(void *new, size_t size);
 extern int   zft_vcalloc_once(void *new, size_t size);
 extern int   zft_vmalloc_always(void *new, size_t size);
-extern int   zft_vcalloc_always(void *new, size_t size);
 extern void  zft_vfree(void *old, size_t size);
 extern void *zft_kmalloc(size_t size);
 extern void  zft_kfree(void *old, size_t size);
diff -Nru a/drivers/char/ftape/zftape/zftape-init.c b/drivers/char/ftape/zftape/zftape-init.c
--- a/drivers/char/ftape/zftape/zftape-init.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/char/ftape/zftape/zftape-init.c	2005-03-01 23:38:55 -08:00
@@ -23,7 +23,6 @@
 #include <linux/config.h>
 #include <linux/module.h>
 #include <linux/errno.h>
-#include <linux/version.h>
 #include <linux/fs.h>
 #include <linux/kernel.h>
 #include <linux/signal.h>
@@ -46,10 +45,6 @@
 #include "../zftape/zftape-ctl.h"
 #include "../zftape/zftape-buffers.h"
 
-char zft_src[] __initdata = "$Source: /homes/cvs/ftape-stacked/ftape/zftape/zftape-init.c,v $";
-char zft_rev[] __initdata = "$Revision: 1.8 $";
-char zft_dat[] __initdata = "$Date: 1997/11/06 00:48:56 $";
-
 MODULE_AUTHOR("(c) 1996, 1997 Claus-Justus Heine "
 	      "(claus@momo.math.rwth-aachen.de)");
 MODULE_DESCRIPTION(ZFTAPE_VERSION " - "
@@ -278,15 +273,6 @@
 	}
 }
 
-struct zft_cmpr_ops *zft_cmpr_unregister(void)
-{
-	struct zft_cmpr_ops *old_ops = zft_cmpr_ops;
-	TRACE_FUN(ft_t_flow);
-
-	zft_cmpr_ops = NULL;
-	TRACE_EXIT old_ops;
-}
-
 /*  lock the zft-compressor() module.
  */
 int zft_cmpr_lock(int try_to_load)
@@ -332,13 +318,11 @@
 KERN_INFO
 "Support for QIC-113 compatible volume table, dynamic memory allocation\n"
 KERN_INFO
-"and builtin compression (lzrw3 algorithm).\n"
-KERN_INFO
-"Compiled for Linux version %s\n", UTS_RELEASE);
+"and builtin compression (lzrw3 algorithm).\n");
         }
 #else /* !MODULE */
 	/* print a short no-nonsense boot message */
-	printk(KERN_INFO ZFTAPE_VERSION " for Linux " UTS_RELEASE "\n");
+	printk(KERN_INFO ZFTAPE_VERSION "\n");
 #endif /* MODULE */
 	TRACE(ft_t_info, "zft_init @ 0x%p", zft_init);
 	TRACE(ft_t_info,
diff -Nru a/drivers/char/ftape/zftape/zftape-init.h b/drivers/char/ftape/zftape/zftape-init.h
--- a/drivers/char/ftape/zftape/zftape-init.h	2005-03-01 23:38:57 -08:00
+++ b/drivers/char/ftape/zftape/zftape-init.h	2005-03-01 23:38:57 -08:00
@@ -70,7 +70,6 @@
 /* zftape-init.c defined global functions.
  */
 extern int                  zft_cmpr_register(struct zft_cmpr_ops *new_ops);
-extern struct zft_cmpr_ops *zft_cmpr_unregister(void);
 extern int                  zft_cmpr_lock(int try_to_load);
 
 #endif
diff -Nru a/drivers/char/ftape/zftape/zftape-rw.c b/drivers/char/ftape/zftape/zftape-rw.c
--- a/drivers/char/ftape/zftape/zftape-rw.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/char/ftape/zftape/zftape-rw.c	2005-03-01 23:38:58 -08:00
@@ -45,7 +45,6 @@
 int zft_deblock_segment = -1;
 zft_status_enum zft_io_state = zft_idle;
 int zft_header_changed;
-int zft_bad_sector_map_changed;
 int zft_qic113; /* conform to old specs. and old zftape */
 int zft_use_compression;
 zft_position zft_pos = {
diff -Nru a/drivers/char/ftape/zftape/zftape-rw.h b/drivers/char/ftape/zftape/zftape-rw.h
--- a/drivers/char/ftape/zftape/zftape-rw.h	2005-03-01 23:38:58 -08:00
+++ b/drivers/char/ftape/zftape/zftape-rw.h	2005-03-01 23:38:58 -08:00
@@ -79,7 +79,6 @@
 extern int zft_deblock_segment;
 extern zft_status_enum zft_io_state;
 extern int zft_header_changed;
-extern int zft_bad_sector_map_changed;
 extern int zft_qic113; /* conform to old specs. and old zftape */
 extern int zft_use_compression;
 extern unsigned int zft_blk_sz;
diff -Nru a/drivers/char/ftape/zftape/zftape-vtbl.c b/drivers/char/ftape/zftape/zftape-vtbl.c
--- a/drivers/char/ftape/zftape/zftape-vtbl.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/char/ftape/zftape/zftape-vtbl.c	2005-03-01 23:38:56 -08:00
@@ -62,7 +62,7 @@
 static zft_volinfo  eot_vtbl;
 static zft_volinfo *cur_vtbl;
 
-inline void zft_new_vtbl_entry(void)
+static inline void zft_new_vtbl_entry(void)
 {
 	struct list_head *tmp = &zft_last_vtbl->node;
 	zft_volinfo *new = zft_kmalloc(sizeof(zft_volinfo));
@@ -248,7 +248,7 @@
  * that buffer already contains the old volume-table, so that vtbl
  * entries without the zft_volume flag set can savely be ignored.
  */
-void zft_create_volume_headers(__u8 *buffer)
+static void zft_create_volume_headers(__u8 *buffer)
 {   
 	__u8 *entry;
 	struct list_head *tmp;
diff -Nru a/drivers/char/ftape/zftape/zftape-vtbl.h b/drivers/char/ftape/zftape/zftape-vtbl.h
--- a/drivers/char/ftape/zftape/zftape-vtbl.h	2005-03-01 23:38:55 -08:00
+++ b/drivers/char/ftape/zftape/zftape-vtbl.h	2005-03-01 23:38:55 -08:00
@@ -152,7 +152,6 @@
 /* exported functions */
 extern void  zft_init_vtbl             (void);
 extern void  zft_free_vtbl             (void);
-extern void  zft_new_vtbl_entry        (void);
 extern int   zft_extract_volume_headers(__u8 *buffer);
 extern int   zft_update_volume_table   (unsigned int segment);
 extern int   zft_open_volume           (zft_position *pos,
diff -Nru a/drivers/char/ftape/zftape/zftape_syms.c b/drivers/char/ftape/zftape/zftape_syms.c
--- a/drivers/char/ftape/zftape/zftape_syms.c	2005-03-01 23:38:51 -08:00
+++ b/drivers/char/ftape/zftape/zftape_syms.c	2005-03-01 23:38:51 -08:00
@@ -35,7 +35,6 @@
 
 /* zftape-init.c */
 EXPORT_SYMBOL(zft_cmpr_register);
-EXPORT_SYMBOL(zft_cmpr_unregister);
 /* zftape-read.c */
 EXPORT_SYMBOL(zft_fetch_segment_fraction);
 /* zftape-buffers.c */
diff -Nru a/drivers/char/generic_serial.c b/drivers/char/generic_serial.c
--- a/drivers/char/generic_serial.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/char/generic_serial.c	2005-03-01 23:38:57 -08:00
@@ -279,7 +279,7 @@
 }
 
 
-int gs_real_chars_in_buffer(struct tty_struct *tty)
+static int gs_real_chars_in_buffer(struct tty_struct *tty)
 {
 	struct gs_port *port;
 	func_enter ();
@@ -457,7 +457,7 @@
 }
 
 
-void gs_shutdown_port (struct gs_port *port)
+static void gs_shutdown_port (struct gs_port *port)
 {
 	unsigned long flags;
 
@@ -511,27 +511,6 @@
 }
 
 
-void gs_do_softint(void *private_)
-{
-	struct gs_port *port = private_;
-	struct tty_struct *tty;
-
-	func_enter ();
-
-	if (!port) return;
-
-	tty = port->tty;
-
-	if (!tty) return;
-
-	if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &port->event)) {
-		tty_wakeup(tty);
-		wake_up_interruptible(&tty->write_wait);
-	}
-	func_exit ();
-}
-
-
 int gs_block_til_ready(void *port_, struct file * filp)
 {
 	struct gs_port *port = port_;
@@ -996,7 +975,6 @@
 EXPORT_SYMBOL(gs_stop);
 EXPORT_SYMBOL(gs_start);
 EXPORT_SYMBOL(gs_hangup);
-EXPORT_SYMBOL(gs_do_softint);
 EXPORT_SYMBOL(gs_block_til_ready);
 EXPORT_SYMBOL(gs_close);
 EXPORT_SYMBOL(gs_set_termios);
diff -Nru a/drivers/char/genrtc.c b/drivers/char/genrtc.c
--- a/drivers/char/genrtc.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/char/genrtc.c	2005-03-01 23:39:16 -08:00
@@ -83,7 +83,7 @@
 static int irq_active;
 
 #ifdef CONFIG_GEN_RTC_X
-struct work_struct genrtc_task;
+static struct work_struct genrtc_task;
 static struct timer_list timer_task;
 
 static unsigned int oldsecs;
@@ -95,7 +95,7 @@
 static volatile int stask_active;              /* schedule_work */
 static volatile int ttask_active;              /* timer_task */
 static int stop_rtc_timers;                    /* don't requeue tasks */
-static spinlock_t gen_rtc_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(gen_rtc_lock);
 
 static void gen_rtc_interrupt(unsigned long arg);
 
diff -Nru a/drivers/char/hpet.c b/drivers/char/hpet.c
--- a/drivers/char/hpet.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/char/hpet.c	2005-03-01 23:38:58 -08:00
@@ -52,9 +52,9 @@
 static u32 hpet_ntimer, hpet_nhpet, hpet_max_freq = HPET_USER_FREQ;
 
 /* A lock for concurrent access by app and isr hpet activity. */
-static spinlock_t hpet_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(hpet_lock);
 /* A lock for concurrent intermodule access to hpet and isr hpet activity. */
-static spinlock_t hpet_task_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(hpet_task_lock);
 
 #define	HPET_DEV_NAME	(7)
 
diff -Nru a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c
--- a/drivers/char/hvc_console.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/char/hvc_console.c	2005-03-01 23:39:09 -08:00
@@ -94,7 +94,7 @@
  * Protect the list of hvc_struct instances from inserts and removals during
  * list traversal.
  */
-static spinlock_t hvc_structs_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(hvc_structs_lock);
 
 /*
  * Initial console vtermnos for console API usage prior to full console
@@ -629,7 +629,7 @@
 	kobject_init(&hp->kobj);
 	hp->kobj.ktype = &hvc_kobj_type;
 
-	hp->lock = SPIN_LOCK_UNLOCKED;
+	spin_lock_init(&hp->lock);
 	spin_lock(&hvc_structs_lock);
 	hp->index = ++hvc_count;
 	list_add_tail(&(hp->next), &hvc_structs);
diff -Nru a/drivers/char/hvcs.c b/drivers/char/hvcs.c
--- a/drivers/char/hvcs.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/char/hvcs.c	2005-03-01 23:39:18 -08:00
@@ -257,7 +257,7 @@
 static unsigned long *hvcs_pi_buff;
 
 /* Only allow one hvcs_struct to use the hvcs_pi_buff at a time. */
-static spinlock_t hvcs_pi_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(hvcs_pi_lock);
 
 /* One vty-server per hvcs_struct */
 struct hvcs_struct {
@@ -308,7 +308,7 @@
 #define from_kobj(kobj) container_of(kobj, struct hvcs_struct, kobj)
 
 static struct list_head hvcs_structs = LIST_HEAD_INIT(hvcs_structs);
-static spinlock_t hvcs_structs_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(hvcs_structs_lock);
 
 static void hvcs_unthrottle(struct tty_struct *tty);
 static void hvcs_throttle(struct tty_struct *tty);
@@ -631,7 +631,7 @@
 	/* hvcsd->tty is zeroed out with the memset */
 	memset(hvcsd, 0x00, sizeof(*hvcsd));
 
-	hvcsd->lock = SPIN_LOCK_UNLOCKED;
+	spin_lock_init(&hvcsd->lock);
 	/* Automatically incs the refcount the first time */
 	kobject_init(&hvcsd->kobj);
 	/* Set up the callback for terminating the hvcs_struct's life */
@@ -1363,6 +1363,7 @@
 
 	hvcs_tty_driver->driver_name = hvcs_driver_name;
 	hvcs_tty_driver->name = hvcs_device_node;
+	hvcs_tty_driver->devfs_name = hvcs_device_node;
 
 	/*
 	 * We'll let the system assign us a major number, indicated by leaving
diff -Nru a/drivers/char/hvsi.c b/drivers/char/hvsi.c
--- a/drivers/char/hvsi.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/char/hvsi.c	2005-03-01 23:39:07 -08:00
@@ -1331,7 +1331,7 @@
 		INIT_WORK(&hp->handshaker, hvsi_handshaker, hp);
 		init_waitqueue_head(&hp->emptyq);
 		init_waitqueue_head(&hp->stateq);
-		hp->lock = SPIN_LOCK_UNLOCKED;
+		spin_lock_init(&hp->lock);
 		hp->index = hvsi_count;
 		hp->inbuf_end = hp->inbuf;
 		hp->state = HVSI_CLOSED;
diff -Nru a/drivers/char/hw_random.c b/drivers/char/hw_random.c
--- a/drivers/char/hw_random.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/char/hw_random.c	2005-03-01 23:38:55 -08:00
@@ -56,31 +56,27 @@
 /*
  * debugging macros
  */
-#undef RNG_DEBUG /* define to enable copious debugging info */
 
-#ifdef RNG_DEBUG
-/* note: prints function name for you */
-#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
-#else
-#define DPRINTK(fmt, args...)
-#endif
+/* pr_debug() collapses to a no-op if DEBUG is not defined */
+#define DPRINTK(fmt, args...) pr_debug(PFX "%s: " fmt, __FUNCTION__ , ## args)
+
 
-#define RNG_NDEBUG        /* define to disable lightweight runtime checks */
+#undef RNG_NDEBUG        /* define to enable lightweight runtime checks */
 #ifdef RNG_NDEBUG
-#define assert(expr)
+#define assert(expr)							\
+		if(!(expr)) {						\
+		printk(KERN_DEBUG PFX "Assertion failed! %s,%s,%s,"	\
+		"line=%d\n", #expr, __FILE__, __FUNCTION__, __LINE__);	\
+		}
 #else
-#define assert(expr) \
-        if(!(expr)) {                                   \
-        printk( "Assertion failed! %s,%s,%s,line=%d\n", \
-        #expr,__FILE__,__FUNCTION__,__LINE__);          \
-        }
+#define assert(expr)
 #endif
 
 #define RNG_MISCDEV_MINOR		183 /* official */
 
 static int rng_dev_open (struct inode *inode, struct file *filp);
 static ssize_t rng_dev_read (struct file *filp, char __user *buf, size_t size,
-			     loff_t * offp);
+				loff_t * offp);
 
 static int __init intel_init (struct pci_dev *dev);
 static void intel_cleanup(void);
@@ -322,7 +318,8 @@
 	rnen |= (1 << 7);	/* PMIO enable */
 	pci_write_config_byte(dev, 0x41, rnen);
 
-	printk(KERN_INFO PFX "AMD768 system management I/O registers at 0x%X.\n", pmbase);
+	pr_info( PFX "AMD768 system management I/O registers at 0x%X.\n",
+			pmbase);
 
 	amd_dev = dev;
 
@@ -369,7 +366,7 @@
 	VIA_RNG_CHUNK_1_MASK	= 0xFF,
 };
 
-u32 via_rng_datum;
+static u32 via_rng_datum;
 
 /*
  * Investigate using the 'rep' prefix to obtain 32 bits of random data
@@ -483,9 +480,9 @@
 
 
 static ssize_t rng_dev_read (struct file *filp, char __user *buf, size_t size,
-			     loff_t * offp)
+				loff_t * offp)
 {
-	static spinlock_t rng_lock = SPIN_LOCK_UNLOCKED;
+	static DEFINE_SPINLOCK(rng_lock);
 	unsigned int have_data;
 	u32 data = 0;
 	ssize_t ret = 0;
@@ -606,7 +603,7 @@
 	if (rc)
 		return rc;
 
-	printk (KERN_INFO RNG_DRIVER_NAME " loaded\n");
+	pr_info( RNG_DRIVER_NAME " loaded\n");
 
 	DPRINTK ("EXIT, returning 0\n");
 	return 0;
diff -Nru a/drivers/char/i8k.c b/drivers/char/i8k.c
--- a/drivers/char/i8k.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/char/i8k.c	2005-03-01 23:38:53 -08:00
@@ -621,32 +621,35 @@
 
 static int __init dmi_iterate(void (*decode)(DMIHeader *))
 {
-    unsigned char buf[20];
-    long fp = 0x000e0000L;
-    fp -= 16;
+	unsigned char buf[20];
+	void __iomem *p = ioremap(0xe0000, 0x20000), *q;
 
-    while (fp < 0x000fffffL) {
-	fp += 16;
-	isa_memcpy_fromio(buf, fp, 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];
+	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]);
+			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) {
-		return 0;
-	    }
+			if (dmi_table(base, len, num, decode)==0) {
+				iounmap(p);
+				return 0;
+			}
+		}
 	}
-    }
-    return -1;
+	iounmap(p);
+	return -1;
 }
 /* end of DMI code */
 
diff -Nru a/drivers/char/ip2/Makefile b/drivers/char/ip2/Makefile
--- a/drivers/char/ip2/Makefile	2005-03-01 23:39:17 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,12 +0,0 @@
-
-all:	ip2mkdev ip2trace ip2stat
-
-ip2mkdev: ip2mkdev.c
-	cc -o ip2mkdev ip2mkdev.c
-
-ip2trace: ip2trace.c
-	cc -o ip2trace ip2trace.c
-
-ip2stat: ip2stat.c
-	cc -o ip2stat ip2stat.c
-
diff -Nru a/drivers/char/ip2/fip_firm.h b/drivers/char/ip2/fip_firm.h
--- a/drivers/char/ip2/fip_firm.h	2005-03-01 23:38:58 -08:00
+++ b/drivers/char/ip2/fip_firm.h	2005-03-01 23:38:58 -08:00
@@ -1,7 +1,7 @@
 /* fip_firm.h - Intelliport II loadware */
 /* -31232 bytes read from ff.lod */
 
-unsigned char fip_firm[] __initdata = {
+static unsigned char fip_firm[] __initdata = {
 0x3C,0x42,0x37,0x18,0x02,0x01,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
 0x57,0x65,0x64,0x20,0x44,0x65,0x63,0x20,0x30,0x31,0x20,0x31,0x32,0x3A,0x32,0x34,
 0x3A,0x33,0x30,0x20,0x31,0x39,0x39,0x39,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
diff -Nru a/drivers/char/ip2/i2cmd.c b/drivers/char/ip2/i2cmd.c
--- a/drivers/char/ip2/i2cmd.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/char/ip2/i2cmd.c	2005-03-01 23:38:55 -08:00
@@ -88,7 +88,7 @@
 //static UCHAR ct37[]={ 5, BYP|VIP, 0x25,0,0,0,0             }; // FLOW PACKET
 
 // Back to normal
-static UCHAR ct38[] = {11, BTH|VAR, 0x26,0,0,0,0,0,0,0,0,0,0 }; // DEF KEY SEQ
+//static UCHAR ct38[] = {11, BTH|VAR, 0x26,0,0,0,0,0,0,0,0,0,0 }; // DEF KEY SEQ
 //static UCHAR ct39[]={ 3, BTH|END, 0x27,0,0                 }; // OPOSTON
 //static UCHAR ct40[]={ 1, BTH|END, 0x28                     }; // OPOSTOFF
 static UCHAR ct41[] = { 1, BYP,     0x29                     }; // RESUME
@@ -103,7 +103,7 @@
 //static UCHAR ct50[]={ 1, BTH,     0x32                     }; // DTRFLOWENAB
 //static UCHAR ct51[]={ 1, BTH,     0x33                     }; // DTRFLOWDSAB
 //static UCHAR ct52[]={ 1, BTH,     0x34                     }; // BAUDTABRESET
-static UCHAR ct53[] = { 3, BTH,     0x35,0,0                 }; // BAUDREMAP
+//static UCHAR ct53[] = { 3, BTH,     0x35,0,0                 }; // BAUDREMAP
 static UCHAR ct54[] = { 3, BTH,     0x36,0,0                 }; // CUSTOMBAUD1
 static UCHAR ct55[] = { 3, BTH,     0x37,0,0                 }; // CUSTOMBAUD2
 static UCHAR ct56[] = { 2, BTH|END, 0x38,0                   }; // PAUSE
@@ -152,40 +152,6 @@
 //********
 
 //******************************************************************************
-// Function:   i2cmdSetSeq(type, size, string)
-// Parameters: type   - sequence number
-//             size   - length of sequence
-//             string - substitution string
-//
-// Returns:    Pointer to command structure
-//
-// Description:
-//
-// This routine sets the parameters of command 38 Define Hot Key sequence (alias
-// "special receive sequence"). Returns a pointer to the structure. Endeavours
-// to be bullet-proof in that the sequence number is forced in range, and any
-// out-of-range sizes are forced to zero.
-//******************************************************************************
-cmdSyntaxPtr
-i2cmdSetSeq(unsigned char type, unsigned char size, unsigned char *string)
-{
-	cmdSyntaxPtr pCM = (cmdSyntaxPtr) ct38;
-	unsigned char *pc;
-
-	pCM->cmd[1] = ((type > 0xf) ? 0xf : type);   // Sequence number
-	size = ((size > 0x8) ? 0 : size);            // size
-	pCM->cmd[2] = size;
-	pCM->length = 3 + size;                      // UPDATES THE LENGTH!
-
-	pc = &(pCM->cmd[3]);
-
-	while(size--) {
-		*pc++ = *string++;
-	}
-	return pCM;
-}
-
-//******************************************************************************
 // Function:   i2cmdUnixFlags(iflag, cflag, lflag)
 // Parameters: Unix tty flags
 //
@@ -207,27 +173,6 @@
 	pCM->cmd[4] = (unsigned char) (cflag >> 8);
 	pCM->cmd[5] = (unsigned char)  lflag;
 	pCM->cmd[6] = (unsigned char) (lflag >> 8);
-	return pCM;
-}
-
-//******************************************************************************
-// Function:   i2cmdBaudRemap(dest,src)
-// Parameters: ?
-//
-// Returns:    Pointer to command structure
-//
-// Description:
-//
-// This routine sets the parameters of command 53 and returns a pointer to the
-// appropriate structure.
-//******************************************************************************
-cmdSyntaxPtr
-i2cmdBaudRemap(unsigned char dest, unsigned char src)
-{
-	cmdSyntaxPtr pCM = (cmdSyntaxPtr) ct53;
-
-	pCM->cmd[1] = dest;
-	pCM->cmd[2] = src;
 	return pCM;
 }
 
diff -Nru a/drivers/char/ip2/i2cmd.h b/drivers/char/ip2/i2cmd.h
--- a/drivers/char/ip2/i2cmd.h	2005-03-01 23:38:52 -08:00
+++ b/drivers/char/ip2/i2cmd.h	2005-03-01 23:38:52 -08:00
@@ -71,9 +71,7 @@
 // there is more than one parameter to assign, we must use a function rather
 // than a macro (used usually).
 //
-extern cmdSyntaxPtr i2cmdSetSeq(UCHAR seqno, UCHAR size, UCHAR *string);
 extern cmdSyntaxPtr i2cmdUnixFlags(USHORT iflag,USHORT cflag,USHORT lflag);
-extern cmdSyntaxPtr i2cmdBaudRemap(UCHAR dest, UCHAR src);
 extern cmdSyntaxPtr i2cmdBaudDef(int which, USHORT rate);
 
 // Declarations for the global arrays used to bear the commands and their
@@ -397,14 +395,6 @@
 // library code in response to data movement and shouldn't ever be sent by the
 // user code. See i2pack.h and the body of i2lib.c for details.
 
-// COMMAND 38: Define the hot-key sequence
-// seqno:  sequence number 0-15
-// size:   number of characters in sequence (1-8)
-// string: pointer to the characters
-// (if size == 0, "undefines" this sequence
-//
-#define CMD_SET_SEQ(seqno,size,string) i2cmdSetSeq(seqno,size,string)
-
 // Enable on-board post-processing, using options given in oflag argument.
 // Formerly, this command was automatically preceded by a CMD_OPOST_OFF command
 // because the loadware does not permit sending back-to-back CMD_OPOST_ON
@@ -457,13 +447,6 @@
 #define CMD_DTRFL_ENAB  (cmdSyntaxPtr)(ct50) // Enable  DTR flow control
 #define CMD_DTRFL_DSAB  (cmdSyntaxPtr)(ct51) // Disable DTR flow control
 #define CMD_BAUD_RESET  (cmdSyntaxPtr)(ct52) // Reset baudrate table
-
-// COMMAND 53: Remap baud rate table
-// dest = index of table entry to be changed
-// src  = index value to substitute.
-// at default mapping table is f(x) = x
-//
-#define CMD_BAUD_REMAP(dest,src) i2cmdBaudRemap(dest,src)
 
 // COMMAND 54: Define custom rate #1
 // rate = (short) 1/10 of the desired baud rate
diff -Nru a/drivers/char/ip2/i2lib.c b/drivers/char/ip2/i2lib.c
--- a/drivers/char/ip2/i2lib.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/char/ip2/i2lib.c	2005-03-01 23:39:17 -08:00
@@ -141,7 +141,7 @@
 //* Code *
 //********
 
-inline int
+static inline int
 i2Validate ( i2ChanStrPtr pCh )
 {
 	//ip2trace(pCh->port_index, ITRC_VERIFY,ITRC_ENTER,2,pCh->validity,
diff -Nru a/drivers/char/ip2/ip2mkdev.c b/drivers/char/ip2/ip2mkdev.c
--- a/drivers/char/ip2/ip2mkdev.c	2005-03-01 23:38:57 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,123 +0,0 @@
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <linux/major.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <stdio.h>
-
-#include "ip2.h"
-#include "i2ellis.h"
-
-char nm[256];
-i2eBordStr Board[2];
-
-static void ex_details(i2eBordStrPtr);
-
-int main (int argc, char *argv[])
-{
-	int board, box, port;
-	int fd;
-	int dev;
-	i2eBordStrPtr pB  = Board;
-
-	// Remove all IP2 devices
-
-	for ( board = 0; board < 4; ++board )
-	{
-		sprintf ( nm, "/dev/ip2ipl%d", board );
-		unlink ( nm );
-		sprintf ( nm, "/dev/ip2stat%d", board );
-		unlink ( nm );
-	}
-
-	for ( port = 0; port < 256; ++port  )
-	{
-		sprintf ( nm, "/dev/ttyF%d", port );
-		unlink ( nm );
-		sprintf ( nm, "/dev/cuf%d", port );
-		unlink ( nm );
-	}
-
-	// Now create management devices, and use the status device to determine how
-	// port devices need to exist, and then create them.
-
-	for ( board = 0; board < 4; ++board )
-	{
-		printf("Board %d: ", board );
-
-		sprintf ( nm, "/dev/ip2ipl%d", board );
-		mknod ( nm, S_IFCHR|0666, (IP2_IPL_MAJOR << 8) | board * 4 );
-		sprintf ( nm, "/dev/ip2stat%d", board );
-		mknod ( nm, S_IFCHR|0666, (IP2_IPL_MAJOR << 8) | board * 4 + 1 );
-
-		fd = open ( nm, O_RDONLY );
-		if ( !fd )
-		{
-			printf ( "Unable to open status device %s\n", nm );
-			exit ( 1 );
-		}
-		if ( ioctl ( fd,  65, Board ) < 0 )
-		{
-			printf ( "not present\n" );
-			close ( fd );
-			unlink ( nm );
-			sprintf ( nm, "/dev/ip2ipl%d", board );
-			unlink ( nm );
-		}
-		else
-		{
-			switch( pB->i2ePom.e.porID & ~POR_ID_RESERVED ) 
-			{
-			case POR_ID_FIIEX: ex_details ( pB );       break;
-			case POR_ID_II_4:  printf ( "ISA-4" );      break;
-			case POR_ID_II_8:  printf ( "ISA-8 std" );  break;
-			case POR_ID_II_8R: printf ( "ISA-8 RJ11" ); break;
-		
-			default:
-				printf ( "Unknown board type, ID = %x", pB->i2ePom.e.porID );
-			}
-
-			for ( box = 0; box < ABS_MAX_BOXES; ++box )
-			{
-				for ( port = 0; port < ABS_BIGGEST_BOX; ++port )
-				{
-					if ( pB->i2eChannelMap[box] & ( 1 << port ) )
-					{
-						dev = port 
-							 + box * ABS_BIGGEST_BOX 
-							 + board * ABS_BIGGEST_BOX * ABS_MAX_BOXES;
-	
-						sprintf ( nm, "/dev/ttyF%d", dev );
-						mknod ( nm, S_IFCHR|0666, (IP2_TTY_MAJOR << 8) | dev );
-						sprintf ( nm, "/dev/cuf%d", dev );
-						mknod ( nm, S_IFCHR|0666, (IP2_CALLOUT_MAJOR << 8) | dev );
-
-						printf(".");
-					}
-				}
-			}
-			printf("\n");
-		}
-	}
-}
-
-static void ex_details ( i2eBordStrPtr pB )
-{
-	int            box;
-	int            i;
-	int            ports = 0;
-	int            boxes = 0;
-
-	for( box = 0; box < ABS_MAX_BOXES; ++box )
-	{
-		if( pB->i2eChannelMap[box] != 0 ) ++boxes;
-		for( i = 0; i < ABS_BIGGEST_BOX; ++i ) 
-		{
-			if( pB->i2eChannelMap[box] & 1<< i ) ++ports;
-		}
-	}
-
-	printf("EX bx=%d pt=%d %d bit", boxes, ports, pB->i2eDataWidth16 ? 16 : 8 );
-}
-
-
diff -Nru a/drivers/char/ip2/ip2stat.c b/drivers/char/ip2/ip2stat.c
--- a/drivers/char/ip2/ip2stat.c	2005-03-01 23:38:55 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,115 +0,0 @@
-/*******************************************************************************
-*
-*   (c) 1998 by Computone Corporation
-*
-********************************************************************************
-*
-*
-*   PACKAGE:     Linux tty Device Driver for IntelliPort family of multiport
-*                serial I/O controllers.
-*
-*   DESCRIPTION: Status display utility
-*
-*******************************************************************************/
-
-#include <sys/time.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <signal.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <ctype.h>
-#include <linux/timer.h>
-#include <linux/termios.h>
-
-#include "i2ellis.h"
-#include "i2lib.h"
-
-i2eBordStr Board[2];
-i2ChanStr  Port[2];
-
-struct driver_stats
-{
-	ULONG ref_count;
-	ULONG irq_counter;
-	ULONG bh_counter;
-} Driver;
-
-char	devname[20];
-
-int main (int argc, char *argv[])
-{
-   int   fd;
-   int   dev, i;
-	i2eBordStrPtr pB  = Board;
-	i2ChanStrPtr  pCh = Port;
-
-	if ( argc != 2 ) 
-	{
-		printf ( "Usage: %s <port>\n", argv[0] );
-		exit(1);
-	}
-	i = sscanf ( argv[1], "/dev/ttyF%d", &dev );
-
-	if ( i != 1 ) exit(1);
-
-	//printf("%s: board %d, port %d\n", argv[1], dev / 64, dev % 64 );
-
-	sprintf ( devname, "/dev/ip2stat%d", dev / 64 );
-	if( 0 > ( fd = open ( devname, O_RDONLY ) ) ) {
-		// Conventional name failed - try devfs name
-		sprintf ( devname, "/dev/ip2/stat%d", dev / 64 );
-		if( 0 > ( fd = open ( devname, O_RDONLY ) ) ) {
-			// Where is our board???
-			printf( "Unable to open board %d to retrieve stats\n",
-				dev / 64 );
-			exit( 255 );
-		}
-	}
-
-	ioctl ( fd,  64, &Driver );
-	ioctl ( fd,  65, Board );
-	ioctl ( fd,  dev % 64, Port );
-
-	printf ( "Driver statistics:-\n" );
-	printf ( " Reference Count:  %d\n", Driver.ref_count );
-	printf ( " Interrupts to date:   %ld\n", Driver.irq_counter );
-	printf ( " Bottom half to date:  %ld\n", Driver.bh_counter );
-
-	printf ( "Board statistics(%d):-\n",dev/64 );
-	printf ( "FIFO: remains = %d%s\n", pB->i2eFifoRemains, 
-				pB->i2eWaitingForEmptyFifo ? ", busy" : "" );
-	printf ( "Mail: out mail = %02x\n", pB->i2eOutMailWaiting ); 
-	printf ( "  Input interrupts : %d\n", pB->i2eFifoInInts );
-	printf ( "  Output interrupts: %d\n", pB->i2eFifoOutInts );
-	printf ( "  Flow queued      : %ld\n", pB->debugFlowQueued );
-	printf ( "  Bypass queued    : %ld\n", pB->debugBypassQueued );
-	printf ( "  Inline queued    : %ld\n", pB->debugInlineQueued );
-	printf ( "  Data queued      : %ld\n", pB->debugDataQueued );
-	printf ( "  Flow packets     : %ld\n", pB->debugFlowCount );
-	printf ( "  Bypass packets   : %ld\n", pB->debugBypassCount );
-	printf ( "  Inline packets   : %ld\n", pB->debugInlineCount );
-	printf ( "  Mail status      : %x\n",  pB->i2eStatus );
-	printf ( "  Output mail      : %x\n",  pB->i2eOutMailWaiting );
-	printf ( "  Fatal flag       : %d\n",  pB->i2eFatal );
-
-	printf ( "Channel statistics(%s:%d):-\n",argv[1],dev%64 );
-	printf ( "ibuf: stuff = %d strip = %d\n", pCh->Ibuf_stuff, pCh->Ibuf_strip );
-	printf ( "obuf: stuff = %d strip = %d\n", pCh->Obuf_stuff, pCh->Obuf_strip );
-	printf ( "pbuf: stuff = %d\n", pCh->Pbuf_stuff );
-	printf ( "cbuf: stuff = %d strip = %d\n", pCh->Cbuf_stuff, pCh->Cbuf_strip );
-	printf ( "infl: count = %d room = %d\n", pCh->infl.asof, pCh->infl.room );
-	printf ( "outfl: count = %d room = %d\n", pCh->outfl.asof, pCh->outfl.room );
-	printf ( "throttled = %d ",pCh->throttled);
-	printf ( "bookmarks = %d ",pCh->bookMarks);
-	printf ( "flush_flags = %x\n",pCh->flush_flags);
-	printf ( "needs: ");
-	if (pCh->channelNeeds & NEED_FLOW)   printf("FLOW ");
-	if (pCh->channelNeeds & NEED_INLINE) printf("INLINE ");
-	if (pCh->channelNeeds & NEED_BYPASS) printf("BYPASS ");
-	if (pCh->channelNeeds & NEED_CREDIT) printf("CREDIT ");
-	printf ( "\n");
-	printf ( "dss: in = %x, out = %x\n",pCh->dataSetIn,pCh->dataSetOut);
-	
-}
diff -Nru a/drivers/char/ip2/ip2trace.c b/drivers/char/ip2/ip2trace.c
--- a/drivers/char/ip2/ip2trace.c	2005-03-01 23:39:07 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,279 +0,0 @@
-/*******************************************************************************
-*
-*   (c) 1998 by Computone Corporation
-*
-********************************************************************************
-*
-*
-*   PACKAGE:     Linux tty Device Driver for IntelliPort family of multiport
-*                serial I/O controllers.
-*
-*   DESCRIPTION: Interpretive trace dump utility
-*
-*******************************************************************************/
-
-#include <sys/time.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <signal.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <ctype.h>
-#include "ip2trace.h"
-
-unsigned long namebuf[100];
-
-struct { 
-	int wrap,
-	size,
-	o_strip,
-	o_stuff,
-	strip,
-	stuff;
-	unsigned long buf[1000];
-} tbuf;
-
-struct sigaction act;
-
-typedef enum { kChar, kInt, kAddr, kHex } eFormat;
-
-int active = 1;
-void quit() { active = 0; }
-
-int main (int argc, char *argv[])
-{
-   int   fd = open ( "/dev/ip2trace", O_RDONLY );
-   int   cnt, i;
-	unsigned long ts, td;
-   struct timeval timeout;
-   union ip2breadcrumb bc;
-	eFormat fmt = kHex;
-
-   if ( fd < 0 )
-   {
-      printf ( "Can't open device /dev/ip2trace\n" );
-      exit ( 1 );
-   }
-
-   act.sa_handler = quit;
-   /*act.sa_mask = 0;*/
-	sigemptyset(&act.sa_mask);
-   act.sa_flags = 0;
-   act.sa_restorer = NULL;
-
-   sigaction ( SIGTERM, &act, NULL );
-
-	ioctl ( fd,  1, namebuf );
-
-	printf ( "iiSendPendingMail %p\n",        namebuf[0] );
-	printf ( "i2InitChannels %p\n",           namebuf[1] );
-	printf ( "i2QueueNeeds %p\n",             namebuf[2] );
-	printf ( "i2QueueCommands %p\n",          namebuf[3] );
-	printf ( "i2GetStatus %p\n",              namebuf[4] );
-	printf ( "i2Input %p\n",                  namebuf[5] );
-	printf ( "i2InputFlush %p\n",             namebuf[6] );
-	printf ( "i2Output %p\n",                 namebuf[7] );
-	printf ( "i2FlushOutput %p\n",            namebuf[8] );
-	printf ( "i2DrainWakeup %p\n",            namebuf[9] );
-	printf ( "i2DrainOutput %p\n",            namebuf[10] );
-	printf ( "i2OutputFree %p\n",             namebuf[11] );
-	printf ( "i2StripFifo %p\n",              namebuf[12] );
-	printf ( "i2StuffFifoBypass %p\n",        namebuf[13] );
-	printf ( "i2StuffFifoFlow %p\n",          namebuf[14] );
-	printf ( "i2StuffFifoInline %p\n",        namebuf[15] );
-	printf ( "i2ServiceBoard %p\n",           namebuf[16] );
-	printf ( "serviceOutgoingFifo %p\n",      namebuf[17] );
-	printf ( "ip2_init %p\n",                 namebuf[18] ); 
-	printf ( "ip2_init_board %p\n",           namebuf[19] ); 
-	printf ( "find_eisa_board %p\n",          namebuf[20] );  
-	printf ( "set_irq %p\n",                  namebuf[21] );  
-	printf ( "ex_details %p\n",               namebuf[22] );  
-	printf ( "ip2_interrupt %p\n",            namebuf[23] );  
-	printf ( "ip2_poll %p\n",                 namebuf[24] );  
-	printf ( "service_all_boards %p\n",        namebuf[25] );  
-	printf ( "do_input %p\n",                 namebuf[27] );  
-	printf ( "do_status %p\n",                namebuf[26] );  
-	printf ( "open_sanity_check %p\n",        namebuf[27] );  
-	printf ( "open_block_til_ready %p\n",     namebuf[28] );   
-	printf ( "ip2_open %p\n",                 namebuf[29] );  
-	printf ( "ip2_close %p\n",                namebuf[30] );  
-	printf ( "ip2_hangup %p\n",               namebuf[31] );  
-	printf ( "ip2_write %p\n",                namebuf[32] );  
-	printf ( "ip2_putchar %p\n",              namebuf[33] );  
-	printf ( "ip2_flush_chars %p\n",          namebuf[34] );  
-	printf ( "ip2_write_room %p\n",           namebuf[35] );  
-	printf ( "ip2_chars_in_buf %p\n",         namebuf[36] );  
-	printf ( "ip2_flush_buffer %p\n",         namebuf[37] );  
-	//printf ( "ip2_wait_until_sent %p\n",      namebuf[38] );  
-	printf ( "ip2_throttle %p\n",             namebuf[39] );  
-	printf ( "ip2_unthrottle %p\n",           namebuf[40] );  
-	printf ( "ip2_ioctl %p\n",                namebuf[41] );  
-	printf ( "get_modem_info %p\n",           namebuf[42] );  
-	printf ( "set_modem_info %p\n",           namebuf[43] );  
-	printf ( "get_serial_info %p\n",          namebuf[44] );  
-	printf ( "set_serial_info %p\n",          namebuf[45] );  
-	printf ( "ip2_set_termios %p\n",          namebuf[46] );  
-	printf ( "ip2_set_line_discipline %p\n",  namebuf[47] );  
-	printf ( "set_line_characteristics %p\n", namebuf[48] );  
-
-	printf("\n-------------------------\n");
-	printf("Start of trace\n");
-
-   while ( active ) {
-      cnt = read ( fd, &tbuf, sizeof tbuf );
-
-      if ( cnt ) {
-         if ( tbuf.wrap ) {
-            printf ( "\nTrace buffer: wrap=%d, strip=%d, stuff=%d\n",
-                     tbuf.wrap, tbuf.strip, tbuf.stuff );
-         }
-         for ( i = 0, bc.value = 0; i < cnt; ++i ) {
-				if ( !bc.hdr.codes ) {
-					td = tbuf.buf[i] - ts;
-					ts = tbuf.buf[i++];
-					bc.value = tbuf.buf[i];
-	
-					printf ( "\n(%d) Port %3d ", ts, bc.hdr.port );
-
-					fmt = kHex;
-
-					switch ( bc.hdr.cat )
-					{
-					case ITRC_INIT:
-						printf ( "Init       %d: ", bc.hdr.label );
-						break;
-
-					case ITRC_OPEN:
-						printf ( "Open       %d: ", bc.hdr.label );
-						break;
-
-					case ITRC_CLOSE:
-						printf ( "Close      %d: ", bc.hdr.label );
-						break;
-
-					case ITRC_DRAIN:
-						printf ( "Drain      %d: ", bc.hdr.label );
-						fmt = kInt;
-						break;
-
-					case ITRC_IOCTL:
-						printf ( "Ioctl      %d: ", bc.hdr.label );
-						break;
-
-					case ITRC_FLUSH:
-						printf ( "Flush      %d: ", bc.hdr.label );
-						break;
-
-					case ITRC_STATUS:
-						printf ( "GetS       %d: ", bc.hdr.label );
-						break;
-
-					case ITRC_HANGUP:
-						printf ( "Hangup     %d: ", bc.hdr.label );
-						break;
-
-					case ITRC_INTR:
-						printf ( "*Intr      %d: ", bc.hdr.label );
-						break;
-
-					case ITRC_SFLOW:
-						printf ( "SFlow      %d: ", bc.hdr.label );
-						fmt = kInt;
-						break;
-
-					case ITRC_SBCMD:
-						printf ( "Bypass CMD %d: ", bc.hdr.label );
-						fmt = kInt;
-						break;
-
-					case ITRC_SICMD:
-						printf ( "Inline CMD %d: ", bc.hdr.label );
-						fmt = kInt;
-						break;
-
-					case ITRC_MODEM:
-						printf ( "Modem      %d: ", bc.hdr.label );
-						break;
-
-					case ITRC_INPUT:
-						printf ( "Input      %d: ", bc.hdr.label );
-						break;
-
-					case ITRC_OUTPUT:
-						printf ( "Output     %d: ", bc.hdr.label );
-						fmt = kInt;
-						break;
-
-					case ITRC_PUTC:
-						printf ( "Put char   %d: ", bc.hdr.label );
-						fmt = kChar;
-						break;
-
-					case ITRC_QUEUE:
-						printf ( "Queue CMD  %d: ", bc.hdr.label );
-						fmt = kInt;
-						break;
-
-					case ITRC_STFLW:
-						printf ( "Stat Flow  %d: ", bc.hdr.label );
-						fmt = kInt;
-						break;
-
-					case ITRC_SFIFO:
-						printf ( "SFifo      %d: ", bc.hdr.label );
-						break;
-
-					case ITRC_VERIFY:
-						printf ( "Verfy      %d: ", bc.hdr.label );
-						fmt = kHex;
-						break;
-
-					case ITRC_WRITE:
-						printf ( "Write      %d: ", bc.hdr.label );
-						fmt = kChar;
-						break;
-
-					case ITRC_ERROR:
-						printf ( "ERROR      %d: ", bc.hdr.label );
-						fmt = kInt;
-						break;
-
-					default:
-						printf ( "%08x          ", tbuf.buf[i] );
-						break;
-					}
-				}
-				else 
-				{
-               --bc.hdr.codes;
-					switch ( fmt )
-					{
-					case kChar:
-						printf ( "%c (0x%02x) ", 
-							isprint ( tbuf.buf[i] ) ? tbuf.buf[i] : '.', tbuf.buf[i] );
-						break;
-					case kInt:
-						printf ( "%d ", tbuf.buf[i] );
-						break;
-
-					case kAddr:
-					case kHex:
-						printf ( "0x%x ", tbuf.buf[i] );
-						break;
-					}
-				}
-         }
-      }
-      fflush ( stdout );
-      timeout.tv_sec = 0;
-      timeout.tv_usec = 250;
-      select ( 0, NULL, NULL, NULL, &timeout );
-
-   }
-	printf("\n-------------------------\n");
-	printf("End of trace\n");
-
-   close ( fd );
-}
-
diff -Nru a/drivers/char/ip2main.c b/drivers/char/ip2main.c
--- a/drivers/char/ip2main.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/char/ip2main.c	2005-03-01 23:39:18 -08:00
@@ -138,7 +138,7 @@
 #include <linux/proc_fs.h>
 
 static int ip2_read_procmem(char *, char **, off_t, int);
-int ip2_read_proc(char *, char **, off_t, int, int *, void * );
+static int ip2_read_proc(char *, char **, off_t, int, int *, void * );
 
 /********************/
 /* Type Definitions */
@@ -202,7 +202,6 @@
 static void ip2_wait_until_sent(PTTY,int);
 
 static void set_params (i2ChanStrPtr, struct termios *);
-static int set_modem_info(i2ChanStrPtr, unsigned int, unsigned int *);
 static int get_serial_info(i2ChanStrPtr, struct serial_struct __user *);
 static int set_serial_info(i2ChanStrPtr, struct serial_struct __user *);
 
@@ -3097,7 +3096,7 @@
  * different sources including ip2mkdev.c and a couple of other drivers.
  * The bugs are all mine.  :-)	=mhw=
  */
-int ip2_read_proc(char *page, char **start, off_t off,
+static int ip2_read_proc(char *page, char **start, off_t off,
 				int count, int *eof, void *data)
 {
 	int	i, j, box;
diff -Nru a/drivers/char/ipmi/Kconfig b/drivers/char/ipmi/Kconfig
--- a/drivers/char/ipmi/Kconfig	2005-03-01 23:39:08 -08:00
+++ b/drivers/char/ipmi/Kconfig	2005-03-01 23:39:08 -08:00
@@ -12,7 +12,7 @@
          IPMI is a standard for managing sensors (temperature,
          voltage, etc.) in a system.
 
-         See Documentation/IPMI.txt for more details on the driver.
+         See <file:Documentation/IPMI.txt> for more details on the driver.
 
 	 If unsure, say N.
 
diff -Nru a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
--- a/drivers/char/ipmi/ipmi_msghandler.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/char/ipmi/ipmi_msghandler.c	2005-03-01 23:38:58 -08:00
@@ -49,7 +49,7 @@
 #define PFX "IPMI message handler: "
 #define IPMI_MSGHANDLER_VERSION "v33"
 
-struct ipmi_recv_msg *ipmi_alloc_recv_msg(void);
+static struct ipmi_recv_msg *ipmi_alloc_recv_msg(void);
 static int ipmi_init_msghandler(void);
 
 static int initialized = 0;
@@ -294,44 +294,6 @@
 	unsigned int events;
 };
 
-int
-ipmi_register_all_cmd_rcvr(ipmi_user_t user)
-{
-	unsigned long flags;
-	int           rv = -EBUSY;
-
-	write_lock_irqsave(&(user->intf->users_lock), flags);
-	write_lock(&(user->intf->cmd_rcvr_lock));
-	if ((user->intf->all_cmd_rcvr == NULL)
-	    && (list_empty(&(user->intf->cmd_rcvrs))))
-	{
-		user->intf->all_cmd_rcvr = user;
-		rv = 0;
-	}
-	write_unlock(&(user->intf->cmd_rcvr_lock));
-	write_unlock_irqrestore(&(user->intf->users_lock), flags);
-	return rv;
-}
-
-int
-ipmi_unregister_all_cmd_rcvr(ipmi_user_t user)
-{
-	unsigned long flags;
-	int           rv = -EINVAL;
-
-	write_lock_irqsave(&(user->intf->users_lock), flags);
-	write_lock(&(user->intf->cmd_rcvr_lock));
-	if (user->intf->all_cmd_rcvr == user)
-	{
-		user->intf->all_cmd_rcvr = NULL;
-		rv = 0;
-	}
-	write_unlock(&(user->intf->cmd_rcvr_lock));
-	write_unlock_irqrestore(&(user->intf->users_lock), flags);
-	return rv;
-}
-
-
 #define MAX_IPMI_INTERFACES 4
 static ipmi_smi_t ipmi_interfaces[MAX_IPMI_INTERFACES];
 
@@ -342,7 +304,7 @@
 
 /* Directly protects the ipmi_interfaces data structure.  This is
    claimed in the timer interrupt. */
-static spinlock_t interfaces_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(interfaces_lock);
 
 /* List of watchers that want to know when smi's are added and
    deleted. */
@@ -389,7 +351,7 @@
 	up_read(&smi_watchers_sem);
 }
 
-int
+static int
 ipmi_addr_equal(struct ipmi_addr *addr1, struct ipmi_addr *addr2)
 {
 	if (addr1->addr_type != addr2->addr_type)
@@ -481,6 +443,9 @@
 		return sizeof(struct ipmi_ipmb_addr);
 	}
 
+	if (addr_type == IPMI_LAN_ADDR_TYPE)
+		return sizeof(struct ipmi_lan_addr);
+
 	return 0;
 }
 
@@ -1360,26 +1325,6 @@
 	return rv;
 }
 
-int ipmi_request(ipmi_user_t      user,
-		 struct ipmi_addr *addr,
-		 long             msgid,
-		 struct kernel_ipmi_msg  *msg,
-		 void             *user_msg_data,
-		 int              priority)
-{
-	return i_ipmi_request(user,
-			      user->intf,
-			      addr,
-			      msgid,
-			      msg,
-			      user_msg_data,
-			      NULL, NULL,
-			      priority,
-			      user->intf->my_address,
-			      user->intf->my_lun,
-			      -1, 0);
-}
-
 int ipmi_request_settime(ipmi_user_t      user,
 			 struct ipmi_addr *addr,
 			 long             msgid,
@@ -1426,28 +1371,6 @@
 			      -1, 0);
 }
 
-int ipmi_request_with_source(ipmi_user_t      user,
-			     struct ipmi_addr *addr,
-			     long             msgid,
-			     struct kernel_ipmi_msg  *msg,
-			     void             *user_msg_data,
-			     int              priority,
-			     unsigned char    source_address,
-			     unsigned char    source_lun)
-{
-	return i_ipmi_request(user,
-			      user->intf,
-			      addr,
-			      msgid,
-			      msg,
-			      user_msg_data,
-			      NULL, NULL,
-			      priority,
-			      source_address,
-			      source_lun,
-			      -1, 0);
-}
-
 static int ipmb_file_read_proc(char *page, char **start, off_t off,
 			       int count, int *eof, void *data)
 {
@@ -1702,14 +1625,6 @@
 	return;
 }
 
-void ipmi_poll_interface(ipmi_user_t user)
-{
-	ipmi_smi_t intf = user->intf;
-
-	if (intf->handlers->poll)
-		intf->handlers->poll(intf->send_info);
-}
-
 int ipmi_register_smi(struct ipmi_smi_handlers *handlers,
 		      void		       *send_info,
 		      unsigned char            version_major,
@@ -2389,12 +2304,17 @@
 
 	if (!found) {
 		/* Special handling for NULL users. */
-		if (!recv_msg->user && intf->null_user_handler)
+		if (!recv_msg->user && intf->null_user_handler){
 			intf->null_user_handler(intf, msg);
-		/* The user for the message went away, so give up. */
-		spin_lock_irqsave(&intf->counter_lock, flags);
-		intf->unhandled_local_responses++;
-		spin_unlock_irqrestore(&intf->counter_lock, flags);
+			spin_lock_irqsave(&intf->counter_lock, flags);
+			intf->handled_local_responses++;
+			spin_unlock_irqrestore(&intf->counter_lock, flags);
+		}else{
+			/* The user for the message went away, so give up. */
+			spin_lock_irqsave(&intf->counter_lock, flags);
+			intf->unhandled_local_responses++;
+			spin_unlock_irqrestore(&intf->counter_lock, flags);
+		}
 		ipmi_free_recv_msg(recv_msg);
 	} else {
 		struct ipmi_system_interface_addr *smi_addr;
@@ -3126,9 +3046,9 @@
 }
 
 static struct notifier_block panic_block = {
-	panic_event,
-	NULL,
-	200   /* priority: INT_MAX >= x >= 0 */
+	.notifier_call	= panic_event,
+	.next		= NULL,
+	.priority	= 200	/* priority: INT_MAX >= x >= 0 */
 };
 
 static int ipmi_init_msghandler(void)
@@ -3211,15 +3131,11 @@
 module_init(ipmi_init_msghandler_mod);
 MODULE_LICENSE("GPL");
 
-EXPORT_SYMBOL(ipmi_alloc_recv_msg);
 EXPORT_SYMBOL(ipmi_create_user);
 EXPORT_SYMBOL(ipmi_destroy_user);
 EXPORT_SYMBOL(ipmi_get_version);
-EXPORT_SYMBOL(ipmi_request);
 EXPORT_SYMBOL(ipmi_request_settime);
 EXPORT_SYMBOL(ipmi_request_supply_msgs);
-EXPORT_SYMBOL(ipmi_request_with_source);
-EXPORT_SYMBOL(ipmi_poll_interface);
 EXPORT_SYMBOL(ipmi_register_smi);
 EXPORT_SYMBOL(ipmi_unregister_smi);
 EXPORT_SYMBOL(ipmi_register_for_cmd);
@@ -3227,12 +3143,9 @@
 EXPORT_SYMBOL(ipmi_smi_msg_received);
 EXPORT_SYMBOL(ipmi_smi_watchdog_pretimeout);
 EXPORT_SYMBOL(ipmi_alloc_smi_msg);
-EXPORT_SYMBOL(ipmi_register_all_cmd_rcvr);
-EXPORT_SYMBOL(ipmi_unregister_all_cmd_rcvr);
 EXPORT_SYMBOL(ipmi_addr_length);
 EXPORT_SYMBOL(ipmi_validate_addr);
 EXPORT_SYMBOL(ipmi_set_gets_events);
-EXPORT_SYMBOL(ipmi_addr_equal);
 EXPORT_SYMBOL(ipmi_smi_watcher_register);
 EXPORT_SYMBOL(ipmi_smi_watcher_unregister);
 EXPORT_SYMBOL(ipmi_set_my_address);
diff -Nru a/drivers/char/ipmi/ipmi_poweroff.c b/drivers/char/ipmi/ipmi_poweroff.c
--- a/drivers/char/ipmi/ipmi_poweroff.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/char/ipmi/ipmi_poweroff.c	2005-03-01 23:38:58 -08:00
@@ -45,9 +45,9 @@
 extern void (*pm_power_off)(void);
 
 /* Stuff from the get device id command. */
-unsigned int mfg_id;
-unsigned int prod_id;
-unsigned char capabilities;
+static unsigned int mfg_id;
+static unsigned int prod_id;
+static unsigned char capabilities;
 
 /* We use our own messages for this operation, we don't let the system
    allocate them, since we may be in a panic situation.  The whole
@@ -381,11 +381,17 @@
 };
 
 static struct poweroff_function poweroff_functions[] = {
-	{ "ATCA",    ipmi_atca_detect, ipmi_poweroff_atca },
-	{ "CPI1",    ipmi_cpi1_detect, ipmi_poweroff_cpi1 },
+	{ .platform_type	= "ATCA",
+	  .detect		= ipmi_atca_detect,
+	  .poweroff_func	= ipmi_poweroff_atca },
+	{ .platform_type	= "CPI1",
+	  .detect		= ipmi_cpi1_detect,
+	  .poweroff_func	= ipmi_poweroff_cpi1 },
 	/* Chassis should generally be last, other things should override
 	   it. */
-	{ "chassis", ipmi_chassis_detect, ipmi_poweroff_chassis },
+	{ .platform_type	= "chassis",
+	  .detect		= ipmi_chassis_detect,
+	  .poweroff_func	= ipmi_poweroff_chassis },
 };
 #define NUM_PO_FUNCS (sizeof(poweroff_functions) \
 		      / sizeof(struct poweroff_function))
diff -Nru a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
--- a/drivers/char/ipmi/ipmi_si_intf.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/char/ipmi/ipmi_si_intf.c	2005-03-01 23:38:52 -08:00
@@ -959,7 +959,7 @@
 #define IPMI_MEM_ADDR_SPACE 1
 #define IPMI_IO_ADDR_SPACE  2
 
-#if defined(CONFIG_ACPI_INTERPETER) || defined(CONFIG_X86) || defined(CONFIG_PCI)
+#if defined(CONFIG_ACPI_INTERPRETER) || defined(CONFIG_X86) || defined(CONFIG_PCI)
 static int is_new_interface(int intf, u8 addr_space, unsigned long base_addr)
 {
 	int i;
@@ -1299,7 +1299,7 @@
 	memset(info, 0, sizeof(*info));
 
 	info->io_setup = mem_setup;
-	info->io.info = (void *) addrs[intf_num];
+	info->io.info = &addrs[intf_num];
 	info->io.addr = NULL;
 	info->io.regspacing = regspacings[intf_num];
 	if (!info->io.regspacing)
@@ -1331,7 +1331,7 @@
 static int acpi_failure = 0;
 
 /* For GPE-type interrupts. */
-u32 ipmi_acpi_gpe(void *context)
+static u32 ipmi_acpi_gpe(void *context)
 {
 	struct smi_info *smi_info = context;
 	unsigned long   flags;
@@ -1564,47 +1564,54 @@
 	u8		*data = (u8 *)dm;
 	unsigned long  	base_addr;
 	u8		reg_spacing;
+	u8              len = dm->length;
 
-	ipmi_data->type = data[0x04];
+	ipmi_data->type = data[4];
 
-	memcpy(&base_addr,&data[0x08],sizeof(unsigned long));
-	if (base_addr & 1) {
-		/* I/O */
-		base_addr &= 0xFFFE;
+	memcpy(&base_addr, data+8, sizeof(unsigned long));
+	if (len >= 0x11) {
+		if (base_addr & 1) {
+			/* I/O */
+			base_addr &= 0xFFFE;
+			ipmi_data->addr_space = IPMI_IO_ADDR_SPACE;
+		}
+		else {
+			/* Memory */
+			ipmi_data->addr_space = IPMI_MEM_ADDR_SPACE;
+		}
+		/* If bit 4 of byte 0x10 is set, then the lsb for the address
+		   is odd. */
+		ipmi_data->base_addr = base_addr | ((data[0x10] & 0x10) >> 4);
+
+		ipmi_data->irq = data[0x11];
+
+		/* The top two bits of byte 0x10 hold the register spacing. */
+		reg_spacing = (data[0x10] & 0xC0) >> 6;
+		switch(reg_spacing){
+		case 0x00: /* Byte boundaries */
+		    ipmi_data->offset = 1;
+		    break;
+		case 0x01: /* 32-bit boundaries */
+		    ipmi_data->offset = 4;
+		    break;
+		case 0x02: /* 16-byte boundaries */
+		    ipmi_data->offset = 16;
+		    break;
+		default:
+		    /* Some other interface, just ignore it. */
+		    return -EIO;
+		}
+	} else {
+		/* Old DMI spec. */
+		ipmi_data->base_addr = base_addr;
 		ipmi_data->addr_space = IPMI_IO_ADDR_SPACE;
-	}
-	else {
-		/* Memory */
-		ipmi_data->addr_space = IPMI_MEM_ADDR_SPACE;
-	}
-
-	/* The top two bits of byte 0x10 hold the register spacing. */
-	reg_spacing = (data[0x10] & 0xC0) >> 6;
-	switch(reg_spacing){
-	case 0x00: /* Byte boundaries */
 		ipmi_data->offset = 1;
-		break;
-	case 0x01: /* 32-bit boundaries */
-		ipmi_data->offset = 4;
-		break;
-	case 0x02: /* 16-bit boundaries */
-		ipmi_data->offset = 2;
-	default:
-		printk("ipmi_si: Unknown SMBIOS IPMI Base Addr"
-		       " Modifier: 0x%x\n", reg_spacing);
-		return -EIO;
 	}
 
-	/* If bit 4 of byte 0x10 is set, then the lsb for the address
-	   is odd. */
-	ipmi_data->base_addr = base_addr | ((data[0x10] & 0x10) >> 4);
-
-	ipmi_data->irq = data[0x11];
-
 	if (is_new_interface(-1, ipmi_data->addr_space,ipmi_data->base_addr))
-	    return 0;
+		return 0;
 
-	memset(ipmi_data,0,sizeof(dmi_ipmi_data_t));
+	memset(ipmi_data, 0, sizeof(dmi_ipmi_data_t));
 
 	return -1;
 }
@@ -2253,7 +2260,7 @@
 }
 module_init(init_ipmi_si);
 
-void __exit cleanup_one_si(struct smi_info *to_clean)
+static void __exit cleanup_one_si(struct smi_info *to_clean)
 {
 	int           rv;
 	unsigned long flags;
diff -Nru a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c
--- a/drivers/char/ipmi/ipmi_watchdog.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/char/ipmi/ipmi_watchdog.c	2005-03-01 23:39:17 -08:00
@@ -157,7 +157,7 @@
 static unsigned char preop_val = WDOG_PREOP_NONE;
 
 static char preop[16] = "preop_none";
-static spinlock_t ipmi_read_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(ipmi_read_lock);
 static char data_to_read = 0;
 static DECLARE_WAIT_QUEUE_HEAD(read_q);
 static struct fasync_struct *fasync_q = NULL;
@@ -366,20 +366,6 @@
 	}
 }
 
-/* Do a delayed shutdown, with the delay in milliseconds.  If power_off is
-   false, do a reset.  If power_off is true, do a power down.  This is
-   primarily for the IMB code's shutdown. */
-void ipmi_delayed_shutdown(long delay, int power_off)
-{
-	ipmi_ignore_heartbeat = 1;
-	if (power_off) 
-		ipmi_watchdog_state = WDOG_TIMEOUT_POWER_DOWN;
-	else
-		ipmi_watchdog_state = WDOG_TIMEOUT_RESET;
-	timeout = delay;
-	ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY);
-}
-
 /* We use a semaphore to make sure that only one thing can send a
    heartbeat at one time, because we only have one copy of the data.
    The semaphore is claimed when the set_timeout is sent and freed
@@ -518,9 +504,9 @@
 
 static struct watchdog_info ident=
 {
-	0, /* WDIOF_SETTIMEOUT, */
-	1,
-	"IPMI"
+	.options	= 0,	/* WDIOF_SETTIMEOUT, */
+	.firmware_version = 1,
+	.identity	= "IPMI"
 };
 
 static int ipmi_ioctl(struct inode *inode, struct file *file,
@@ -748,9 +734,9 @@
 };
 
 static struct miscdevice ipmi_wdog_miscdev = {
-	WATCHDOG_MINOR,
-	"watchdog",
-	&ipmi_wdog_fops
+	.minor		= WATCHDOG_MINOR,
+	.name		= "watchdog",
+	.fops		= &ipmi_wdog_fops
 };
 
 static DECLARE_RWSEM(register_sem);
@@ -885,13 +871,11 @@
 }
 
 static struct notifier_block wdog_reboot_notifier = {
-	wdog_reboot_handler,
-	NULL,
-	0
+	.notifier_call	= wdog_reboot_handler,
+	.next		= NULL,
+	.priority	= 0
 };
 
-extern int panic_timeout; /* Why isn't this defined anywhere? */
-
 static int wdog_panic_handler(struct notifier_block *this,
 			      unsigned long         event,
 			      void                  *unused)
@@ -915,9 +899,9 @@
 }
 
 static struct notifier_block wdog_panic_notifier = {
-	wdog_panic_handler,
-	NULL,
-	150   /* priority: INT_MAX >= x >= 0 */
+	.notifier_call	= wdog_panic_handler,
+	.next		= NULL,
+	.priority	= 150	/* priority: INT_MAX >= x >= 0 */
 };
 
 
@@ -1054,10 +1038,6 @@
 	/* Make sure no one can call us any more. */
 	misc_deregister(&ipmi_wdog_miscdev);
 
-	/*  Disable the timer. */
-	ipmi_watchdog_state = WDOG_TIMEOUT_NONE;
-	ipmi_set_timeout(IPMI_SET_TIMEOUT_NO_HB);
-
 	/* Wait to make sure the message makes it out.  The lower layer has
 	   pointers to our buffers, we want to make sure they are done before
 	   we release our memory. */
@@ -1084,8 +1064,5 @@
 	ipmi_unregister_watchdog();
 }
 module_exit(ipmi_wdog_exit);
-
-EXPORT_SYMBOL(ipmi_delayed_shutdown);
-
 module_init(ipmi_wdog_init);
 MODULE_LICENSE("GPL");
diff -Nru a/drivers/char/isicom.c b/drivers/char/isicom.c
--- a/drivers/char/isicom.c	2005-03-01 23:38:51 -08:00
+++ b/drivers/char/isicom.c	2005-03-01 23:38:51 -08:00
@@ -16,10 +16,81 @@
  *
  *	10/6/99 sameer			Merged the ISA and PCI drivers to
  *					a new unified driver.
+ *
+ *	3/9/99	sameer			Added support for ISI4616 cards.
+ *
+ *	16/9/99	sameer			We do not force RTS low anymore.
+ *					This is to prevent the firmware 
+ *					from getting confused.
+ *
+ *	26/10/99 sameer			Cosmetic changes:The driver now
+ *					dumps the Port Count information
+ *					along with I/O address and IRQ.
+ *
+ *	13/12/99 sameer			Fixed the problem with IRQ sharing.
+ *
+ *	10/5/00  sameer			Fixed isicom_shutdown_board()
+ *					to not lower DTR on all the ports
+ *					when the last port on the card is 
+ *					closed.
+ *
+ *	10/5/00  sameer			Signal mask setup command added
+ *					to  isicom_setup_port and 
+ *					isicom_shutdown_port.
+ *
+ *	24/5/00  sameer			The driver is now SMP aware.
+ *					
+ *	
+ *	27/11/00 Vinayak P Risbud	Fixed the Driver Crash Problem
+ *	
+ *	
+ *	03/01/01  anil .s		Added support for resetting the
+ *					internal modems on ISI cards.
+ *
+ *	08/02/01  anil .s		Upgraded the driver for kernel
+ *					2.4.x
+ *
+ *      11/04/01  Kevin			Fixed firmware load problem with
+ *					ISIHP-4X card
+ *	
+ *	30/04/01  anil .s		Fixed the remote login through
+ *					ISI port problem. Now the link
+ *					does not go down before password
+ *					prompt.
+ *
+ *	03/05/01  anil .s		Fixed the problem with IRQ sharing
+ *					among ISI-PCI cards.
+ *
+ *	03/05/01  anil .s		Added support to display the version
+ *					info during insmod as well as module 
+ *					listing by lsmod.
+ *	
+ *	10/05/01  anil .s		Done the modifications to the source
+ *					file and Install script so that the
+ *					same installation can be used for
+ *					2.2.x and 2.4.x kernel.
+ *
+ *	06/06/01  anil .s		Now we drop both dtr and rts during
+ *					shutdown_port as well as raise them
+ *					during isicom_config_port.
+ *  	
  *	09/06/01 acme@conectiva.com.br	use capable, not suser, do
  *					restore_flags on failure in
  *					isicom_send_break, verify put_user
  *					result
+ *
+ *  	11/02/03  ranjeeth		Added support for 230 Kbps and 460 Kbps
+ *  					Baud index extended to 21
+ *  	
+ *  	20/03/03  ranjeeth		Made to work for Linux Advanced server.
+ *  					Taken care of license warning.	
+ *      
+ *	10/12/03  Ravindra		Made to work for Fedora Core 1 of 
+ *					Red Hat Distribution
+ *
+ *	06/01/05  Alan Cox 		Merged the ISI and base kernel strands
+ *					into a single 2.6 driver
+ *
  *	***********************************************************
  *
  *	To use this driver you also need the support package. You 
@@ -35,6 +106,10 @@
  *
  *	Omit those entries for boards you don't have installed.
  *
+ *	TODO
+ *		Hotplug
+ *		Merge testing
+ *		64-bit verification
  */
 
 #include <linux/module.h>
@@ -74,7 +149,6 @@
 MODULE_DEVICE_TABLE(pci, isicom_pci_tbl);
 
 static int prev_card = 3;	/*	start servicing isi_card[0]	*/
-static struct isi_board * irq_to_board[16];
 static struct tty_driver *isicom_normal;
 
 static struct isi_board isi_card[BOARD_COUNT];
@@ -101,9 +175,205 @@
 	18, 19
 };
 
+struct	isi_board {
+	unsigned short		base;
+	unsigned char		irq;
+	unsigned char		port_count;
+	unsigned short		status;
+	unsigned short		port_status; /* each bit represents a single port */
+	unsigned short		shift_count;
+	struct isi_port		* ports;
+	signed char		count;
+	unsigned char		isa;
+	spinlock_t		card_lock; /* Card wide lock 11/5/00 -sameer */
+	unsigned long		flags;
+};
+
+struct	isi_port {
+	unsigned short		magic;
+	unsigned int		flags;
+	int			count;
+	int			blocked_open;
+	int			close_delay;
+	unsigned short		channel;
+	unsigned short		status;
+	unsigned short		closing_wait;
+	struct isi_board	* card;
+	struct tty_struct 	* tty;
+	wait_queue_head_t	close_wait;
+	wait_queue_head_t	open_wait;
+	struct work_struct	hangup_tq;
+	struct work_struct	bh_tqueue;
+	unsigned char		* xmit_buf;
+	int			xmit_head;
+	int			xmit_tail;
+	int			xmit_cnt;
+};
+
+/*
+ *	Locking functions for card level locking. We need to own both
+ *	the kernel lock for the card and have the card in a position that
+ *	it wants to talk.
+ */
+ 
+static int lock_card(struct isi_board *card)
+{
+	char		retries;
+	unsigned short base = card->base;
+
+	for (retries = 0; retries < 100; retries++) {
+		spin_lock_irqsave(&card->card_lock, card->flags);
+		if (inw(base + 0xe) & 0x1) {
+			return 1; 
+		} else {
+			spin_unlock_irqrestore(&card->card_lock, card->flags);
+			udelay(1000);   /* 1ms */
+		}
+	}
+	printk(KERN_WARNING "ISICOM: Failed to lock Card (0x%x)\n", card->base);
+	return 0;	/* Failed to aquire the card! */
+}
+
+static int lock_card_at_interrupt(struct isi_board *card)
+{
+	unsigned char		retries;
+	unsigned short 		base = card->base;
+
+	for (retries = 0; retries < 200; retries++) {
+		spin_lock_irqsave(&card->card_lock, card->flags);
+
+		if (inw(base + 0xe) & 0x1)
+			return 1; 
+		else
+			spin_unlock_irqrestore(&card->card_lock, card->flags);
+	}
+	/* Failing in interrupt is an acceptable event */
+	return 0;	/* Failed to aquire the card! */
+}
+
+static void unlock_card(struct isi_board *card)
+{
+	spin_unlock_irqrestore(&card->card_lock, card->flags);
+}
+
+/*
+ *  ISI Card specific ops ...
+ */
+ 
+static void raise_dtr(struct isi_port * port)
+{
+	struct isi_board * card = port->card;
+	unsigned short base = card->base;
+	unsigned char channel = port->channel;
+
+	if (!lock_card(card))
+		return;
+
+	outw(0x8000 | (channel << card->shift_count) | 0x02 , base);
+	outw(0x0504, base);
+	InterruptTheCard(base);
+	port->status |= ISI_DTR;
+	unlock_card(card);
+}
+
+static inline void drop_dtr(struct isi_port * port)
+{	
+	struct isi_board * card = port->card;
+	unsigned short base = card->base;
+	unsigned char channel = port->channel;
+
+	if (!lock_card(card))
+		return;
+
+	outw(0x8000 | (channel << card->shift_count) | 0x02 , base);
+	outw(0x0404, base);
+	InterruptTheCard(base);	
+	port->status &= ~ISI_DTR;
+	unlock_card(card);
+}
+
+static inline void raise_rts(struct isi_port * port)
+{
+	struct isi_board * card = port->card;
+	unsigned short base = card->base;
+	unsigned char channel = port->channel;
+
+	if (!lock_card(card))
+		return;
+
+	outw(0x8000 | (channel << card->shift_count) | 0x02 , base);
+	outw(0x0a04, base);
+	InterruptTheCard(base);	
+	port->status |= ISI_RTS;
+	unlock_card(card);
+}
+static inline void drop_rts(struct isi_port * port)
+{
+	struct isi_board * card = port->card;
+	unsigned short base = card->base;
+	unsigned char channel = port->channel;
+
+	if (!lock_card(card))
+		return;
+
+	outw(0x8000 | (channel << card->shift_count) | 0x02 , base);
+	outw(0x0804, base);
+	InterruptTheCard(base);	
+	port->status &= ~ISI_RTS;
+	unlock_card(card);
+}
+
+static inline void raise_dtr_rts(struct isi_port * port)
+{
+	struct isi_board * card = port->card;
+	unsigned short base = card->base;
+	unsigned char channel = port->channel;
+
+	if (!lock_card(card))
+		return;
+
+	outw(0x8000 | (channel << card->shift_count) | 0x02 , base);
+	outw(0x0f04, base);
+	InterruptTheCard(base);
+	port->status |= (ISI_DTR | ISI_RTS);
+	unlock_card(card);
+}
+
+static void drop_dtr_rts(struct isi_port * port)
+{
+	struct isi_board * card = port->card;
+	unsigned short base = card->base;
+	unsigned char channel = port->channel;
+
+	if (!lock_card(card))
+		return;
+
+	outw(0x8000 | (channel << card->shift_count) | 0x02 , base);
+	outw(0x0c04, base);
+	InterruptTheCard(base);	
+	port->status &= ~(ISI_RTS | ISI_DTR);
+	unlock_card(card);
+}
+
+static inline void kill_queue(struct isi_port * port, short queue)
+{
+	struct isi_board * card = port->card;
+	unsigned short base = card->base;
+	unsigned char channel = port->channel;
+
+	if (!lock_card(card))
+		return;
+
+	outw(0x8000 | (channel << card->shift_count) | 0x02 , base);
+	outw((queue << 8) | 0x06, base);
+	InterruptTheCard(base);	
+	unlock_card(card);
+}
+
+
 /* 
- *  Firmware loader driver specific routines
- *
+ *  Firmware loader driver specific routines. This needs to mostly die
+ *  and be replaced with request_firmware.
  */
 
 static struct file_operations ISILoad_fops = {
@@ -354,15 +624,19 @@
 	return 0;
 }
 			
-/*	Transmitter	*/
+/*
+ *	Transmitter. 
+ *
+ *	We shovel data into the card buffers on a regular basis. The card
+ *	will do the rest of the work for us.
+ */
 
 static void isicom_tx(unsigned long _data)
 {
 	short count = (BOARD_COUNT-1), card, base;
-	short txcount, wait, wrd, residue, word_count, cnt;
+	short txcount, wrd, residue, word_count, cnt;
 	struct isi_port * port;
 	struct tty_struct * tty;
-	unsigned long flags;
 	
 #ifdef ISICOM_DEBUG
 	++tx_count;
@@ -384,33 +658,29 @@
 	port = isi_card[card].ports;
 	base = isi_card[card].base;
 	for (;count > 0;count--, port++) {
+		if (!lock_card_at_interrupt(&isi_card[card]))
+			continue;
 		/* port not active or tx disabled to force flow control */
-		if (!(port->status & ISI_TXOK))
+		if (!(port->flags & ASYNC_INITIALIZED) ||
+		 	!(port->status & ISI_TXOK))
+			unlock_card(&isi_card[card]);
 			continue;
 		
 		tty = port->tty;
-		save_flags(flags); cli();
-		txcount = min_t(short, TX_SIZE, port->xmit_cnt);
-		if ((txcount <= 0) || tty->stopped || tty->hw_stopped) {
-			restore_flags(flags);
+		
+		
+		if(tty == NULL) {
+			unlock_card(&isi_card[card]);
 			continue;
 		}
-		wait = 200;	
-		while(((inw(base+0x0e) & 0x01) == 0) && (wait-- > 0));
-		if (wait <= 0) {
-			restore_flags(flags);
-#ifdef ISICOM_DEBUG
-			printk(KERN_DEBUG "ISICOM: isicom_tx:Card(0x%x) found busy.\n",
-				card);
-#endif
+		
+		txcount = min_t(short, TX_SIZE, port->xmit_cnt);
+		if (txcount <= 0 || tty->stopped || tty->hw_stopped) {
+			unlock_card(&isi_card[card]);
 			continue;
 		}
 		if (!(inw(base + 0x02) & (1 << port->channel))) {
-			restore_flags(flags);
-#ifdef ISICOM_DEBUG					
-			printk(KERN_DEBUG "ISICOM: isicom_tx: cannot tx to 0x%x:%d.\n",
-					base, port->channel + 1);
-#endif					
+			unlock_card(&isi_card[card]);
 			continue;		
 		}
 #ifdef ISICOM_DEBUG
@@ -459,10 +729,10 @@
 			port->status &= ~ISI_TXOK;
 		if (port->xmit_cnt <= WAKEUP_CHARS)
 			schedule_work(&port->bh_tqueue);
-		restore_flags(flags);
+		unlock_card(&isi_card[card]);
 	}	
 
-		/*	schedule another tx for hopefully in about 10ms	*/	
+	/*	schedule another tx for hopefully in about 10ms	*/	
 sched_again:	
 	if (!re_schedule)	
 		return;
@@ -490,7 +760,10 @@
 	wake_up_interruptible(&tty->write_wait);
 } 		
  		
-/* main interrupt handler routine */ 		
+/*
+ *	Main interrupt handler routine 
+ */
+ 
 static irqreturn_t isicom_interrupt(int irq, void *dev_id,
 					struct pt_regs *regs)
 {
@@ -501,31 +774,19 @@
 	unsigned char channel;
 	short byte_count;
 	
-	/*
-	 *      find the source of interrupt
-	 */
-	 
-	for(count = 0; count < BOARD_COUNT; count++) { 
-		card = &isi_card[count];
-		if (card->base != 0) {
-			if (((card->isa == YES) && (card->irq == irq)) || 
-				((card->isa == NO) && (card->irq == irq) && (inw(card->base+0x0e) & 0x02)))
-				break;
-		}
-		card = NULL;
-	}
+	card = (struct isi_board *) dev_id;
 
-	if (!card || !(card->status & FIRMWARE_LOADED)) {
-/*		printk(KERN_DEBUG "ISICOM: interrupt: not handling irq%d!.\n", irq);*/
+	if (!card || !(card->status & FIRMWARE_LOADED))
 		return IRQ_NONE;
-	}
 	
 	base = card->base;
+	spin_lock(&card->card_lock);
+	
 	if (card->isa == NO) {
-	/*
-	 *      disable any interrupts from the PCI card and lower the
-	 *      interrupt line
-	 */
+		/*
+		 *      disable any interrupts from the PCI card and lower the
+		 *      interrupt line
+		 */
 		outw(0x8000, base+0x04);
 		ClearInterrupt(base);
 	}
@@ -534,16 +795,15 @@
 	header = inw(base);
 	channel = (header & 0x7800) >> card->shift_count;
 	byte_count = header & 0xff;
-#ifdef ISICOM_DEBUG	
-	printk(KERN_DEBUG "ISICOM:Intr:(0x%x:%d).\n", base, channel+1);
-#endif	
-	if ((channel+1) > card->port_count) {
+
+	if (channel + 1 > card->port_count) {
 		printk(KERN_WARNING "ISICOM: isicom_interrupt(0x%x): %d(channel) > port_count.\n",
 				base, channel+1);
 		if (card->isa)
 			ClearInterrupt(base);
 		else
 			outw(0x0000, base+0x04); /* enable interrupts */		
+		spin_unlock(&card->card_lock);
 		return IRQ_HANDLED;			
 	}
 	port = card->ports + channel;
@@ -556,6 +816,21 @@
 	}	
 		
 	tty = port->tty;
+	if (tty == NULL) {
+		word_count = byte_count >> 1;
+		while(byte_count > 1) {
+			inw(base);
+			byte_count -= 2;
+		}
+		if (byte_count & 0x01)
+			inw(base);
+		if (card->isa == YES)
+			ClearInterrupt(base);
+		else
+			outw(0x0000, base+0x04); /* enable interrupts */
+		spin_unlock(&card->card_lock);
+		return IRQ_HANDLED;
+	}
 	
 	if (header & 0x8000) {		/* Status Packet */
 		header = inw(base);
@@ -631,7 +906,6 @@
 				if (tty->flip.count >= TTY_FLIPBUF_SIZE)
 					break;
 				*tty->flip.flag_buf_ptr++ = TTY_BREAK;
-				/* dunno if this is right */	
 				*tty->flip.char_buf_ptr++ = 0;
 				tty->flip.count++;
 				if (port->flags & ASYNC_SAK)
@@ -683,13 +957,12 @@
 	return IRQ_HANDLED;
 } 
 
- /* called with interrupts disabled */ 
 static void isicom_config_port(struct isi_port * port)
 {
 	struct isi_board * card = port->card;
 	struct tty_struct * tty;
 	unsigned long baud;
-	unsigned short channel_setup, wait, base = card->base;
+	unsigned short channel_setup, base = card->base;
 	unsigned short channel = port->channel, shift_count = card->shift_count;
 	unsigned char flow_ctrl;
 	
@@ -729,40 +1002,36 @@
 	else  
 		raise_dtr(port);
 		
-	wait = 100;	
-	while (((inw(base + 0x0e) & 0x0001) == 0) && (wait-- > 0));	
-	if (!wait) {
-		printk(KERN_WARNING "ISICOM: Card found busy in isicom_config_port at channel setup.\n");
-		return;
-	}			 
-	outw(0x8000 | (channel << shift_count) |0x03, base);
-	outw(linuxb_to_isib[baud] << 8 | 0x03, base);
-	channel_setup = 0;
-	switch(C_CSIZE(tty)) {
-		case CS5:
-			channel_setup |= ISICOM_CS5;
-			break;
-		case CS6:
-			channel_setup |= ISICOM_CS6;
-			break;
-		case CS7:
-			channel_setup |= ISICOM_CS7;
-			break;
-		case CS8:
-			channel_setup |= ISICOM_CS8;
-			break;
-	}
-		
-	if (C_CSTOPB(tty))
-		channel_setup |= ISICOM_2SB;
-	
-	if (C_PARENB(tty))
-		channel_setup |= ISICOM_EVPAR;
-	if (C_PARODD(tty))
-		channel_setup |= ISICOM_ODPAR;	
-	outw(channel_setup, base);	
-	InterruptTheCard(base);
-	
+	if (lock_card(card)) {
+		outw(0x8000 | (channel << shift_count) |0x03, base);
+		outw(linuxb_to_isib[baud] << 8 | 0x03, base);
+		channel_setup = 0;
+		switch(C_CSIZE(tty)) {
+			case CS5:
+				channel_setup |= ISICOM_CS5;
+				break;
+			case CS6:
+				channel_setup |= ISICOM_CS6;
+				break;
+			case CS7:
+				channel_setup |= ISICOM_CS7;
+				break;
+			case CS8:
+				channel_setup |= ISICOM_CS8;
+				break;
+		}
+			
+		if (C_CSTOPB(tty))
+			channel_setup |= ISICOM_2SB;
+		if (C_PARENB(tty)) {
+			channel_setup |= ISICOM_EVPAR;
+			if (C_PARODD(tty))
+				channel_setup |= ISICOM_ODPAR;	
+		}
+		outw(channel_setup, base);	
+		InterruptTheCard(base);
+		unlock_card(card);	
+	}	
 	if (C_CLOCAL(tty))
 		port->flags &= ~ASYNC_CHECK_CD;
 	else
@@ -780,23 +1049,19 @@
 	if (I_IXOFF(tty))
 		flow_ctrl |= ISICOM_INITIATE_XONXOFF;	
 		
-	wait = 100;	
-	while (((inw(base + 0x0e) & 0x0001) == 0) && (wait-- > 0));	
-	if (!wait) {
-		printk(KERN_WARNING "ISICOM: Card found busy in isicom_config_port at flow setup.\n");
-		return;
-	}			 
-	outw(0x8000 | (channel << shift_count) |0x04, base);
-	outw(flow_ctrl << 8 | 0x05, base);
-	outw((STOP_CHAR(tty)) << 8 | (START_CHAR(tty)), base);
-	InterruptTheCard(base);
+	if (lock_card(card)) {
+		outw(0x8000 | (channel << shift_count) |0x04, base);
+		outw(flow_ctrl << 8 | 0x05, base);
+		outw((STOP_CHAR(tty)) << 8 | (START_CHAR(tty)), base);
+		InterruptTheCard(base);
+		unlock_card(card);
+	}
 	
 	/*	rx enabled -> enable port for rx on the card	*/
 	if (C_CREAD(tty)) {
 		card->port_status |= (1 << channel);
 		outw(card->port_status, base + 0x02);
 	}
-		
 }
  
 /* open et all */ 
@@ -807,22 +1072,16 @@
 	struct isi_port * port;
 	unsigned long flags;
 	
-	if (bp->status & BOARD_ACTIVE) 
+	spin_lock_irqsave(&bp->card_lock, flags);
+	if (bp->status & BOARD_ACTIVE) {
+		spin_unlock_irqrestore(&bp->card_lock, flags);
 		return;
-	port = bp->ports;
-#ifdef ISICOM_DEBUG	
-	printk(KERN_DEBUG "ISICOM: setup_board: drop_dtr_rts start, port_count %d...\n", bp->port_count);
-#endif
-	for(channel = 0; channel < bp->port_count; channel++, port++) {
-		save_flags(flags); cli();
-		drop_dtr_rts(port);
-		restore_flags(flags);
 	}
-#ifdef ISICOM_DEBUG		
-	printk(KERN_DEBUG "ISICOM: setup_board: drop_dtr_rts stop...\n");	
-#endif	
-	
+	port = bp->ports;
 	bp->status |= BOARD_ACTIVE;
+	spin_unlock_irqrestore(&bp->card_lock, flags);
+	for(channel = 0; channel < bp->port_count; channel++, port++)
+		drop_dtr_rts(port);
 	return;
 }
  
@@ -831,8 +1090,9 @@
 	struct isi_board * card = port->card;
 	unsigned long flags;
 	
-	if (port->flags & ASYNC_INITIALIZED)
+	if (port->flags & ASYNC_INITIALIZED) {
 		return 0;
+	}
 	if (!port->xmit_buf) {
 		unsigned long page;
 		
@@ -845,7 +1105,8 @@
 		}
 		port->xmit_buf = (unsigned char *) page;	
 	}	
-	save_flags(flags); cli();
+
+	spin_lock_irqsave(&card->card_lock, flags);
 	if (port->tty)
 		clear_bit(TTY_IO_ERROR, &port->tty->flags);
 	if (port->count == 1)
@@ -858,15 +1119,16 @@
 	
 	isicom_config_port(port);
 	port->flags |= ASYNC_INITIALIZED;
-	
-	restore_flags(flags);
+	spin_unlock_irqrestore(&card->card_lock, flags);
 	
 	return 0;		
 } 
  
 static int block_til_ready(struct tty_struct * tty, struct file * filp, struct isi_port * port) 
 {
+	struct isi_board * card = port->card;
 	int do_clocal = 0, retval;
+	unsigned long flags;
 	DECLARE_WAITQUEUE(wait, current);
 
 	/* block if port is in the process of being closed */
@@ -894,49 +1156,34 @@
 	
 	if (C_CLOCAL(tty))
 		do_clocal = 1;
-#ifdef ISICOM_DEBUG	
-	if (do_clocal)
-		printk(KERN_DEBUG "ISICOM: block_til_ready: CLOCAL set.\n");
-#endif 		
 	
 	/* block waiting for DCD to be asserted, and while 
 						callout dev is busy */
 	retval = 0;
 	add_wait_queue(&port->open_wait, &wait);
-	cli();
-		if (!tty_hung_up_p(filp))
-			port->count--;
-	sti();
+
+	spin_lock_irqsave(&card->card_lock, flags);
+	if (!tty_hung_up_p(filp))
+		port->count--;
 	port->blocked_open++;
-#ifdef ISICOM_DEBUG	
-	printk(KERN_DEBUG "ISICOM: block_til_ready: waiting for DCD...\n");
-#endif	
+	spin_unlock_irqrestore(&card->card_lock, flags);
+	
 	while (1) {
-		cli();
 		raise_dtr_rts(port);
-		sti();
+
 		set_current_state(TASK_INTERRUPTIBLE);
 		if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)) { 	
 			if (port->flags & ASYNC_HUP_NOTIFY)
 				retval = -EAGAIN;
 			else
 				retval = -ERESTARTSYS;
-#ifdef ISICOM_DEBUG				
-			printk(KERN_DEBUG "ISICOM: block_til_ready: tty_hung_up_p || not init.\n"); 
-#endif			
 			break;
 		}	
 		if (!(port->flags & ASYNC_CLOSING) &&
 		    (do_clocal || (port->status & ISI_DCD))) {
-#ifdef ISICOM_DEBUG		    
-		 	printk(KERN_DEBUG "ISICOM: block_til_ready: do_clocal || DCD.\n");   
-#endif		 	
 			break;
 		}	
 		if (signal_pending(current)) {
-#ifdef ISICOM_DEBUG		
-			printk(KERN_DEBUG "ISICOM: block_til_ready: sig blocked.\n");
-#endif			
 			retval = -ERESTARTSYS;
 			break;
 		}
@@ -944,9 +1191,11 @@
 	}
 	set_current_state(TASK_RUNNING);
 	remove_wait_queue(&port->open_wait, &wait);
+	spin_lock_irqsave(&card->card_lock, flags);
 	if (!tty_hung_up_p(filp))
 		port->count++;
 	port->blocked_open--;
+	spin_unlock_irqrestore(&card->card_lock, flags);
 	if (retval)
 		return retval;
 	port->flags |= ASYNC_NORMAL_ACTIVE;
@@ -960,62 +1209,33 @@
 	unsigned int line, board;
 	int error;
 
-#ifdef ISICOM_DEBUG	
-	printk(KERN_DEBUG "ISICOM: open start!!!.\n");
-#endif	
 	line = tty->index;
-	
-#ifdef ISICOM_DEBUG	
-	printk(KERN_DEBUG "line = %d.\n", line);
-#endif	
-	
-	if ((line < 0) || (line > (PORT_COUNT-1)))
+	if (line < 0 || line > PORT_COUNT-1)
 		return -ENODEV;
 	board = BOARD(line);
-	
-#ifdef ISICOM_DEBUG	
-	printk(KERN_DEBUG "board = %d.\n", board);
-#endif	
-	
 	card = &isi_card[board];
-	if (!(card->status & FIRMWARE_LOADED)) {
-#ifdef ISICOM_DEBUG	
-		printk(KERN_DEBUG"ISICOM: Firmware not loaded to card%d.\n", board);
-#endif		
+	
+	if (!(card->status & FIRMWARE_LOADED))
 		return -ENODEV;
-	}
 	
 	/*  open on a port greater than the port count for the card !!! */
-	if (line > ((board * 16) + card->port_count - 1)) {
-		printk(KERN_ERR "ISICOM: Open on a port which exceeds the port_count of the card!\n");
+	if (line > ((board * 16) + card->port_count - 1))
 		return -ENODEV;
-	}	
+
 	port = &isi_ports[line];	
 	if (isicom_paranoia_check(port, tty->name, "isicom_open"))
 		return -ENODEV;
 		
-#ifdef ISICOM_DEBUG		
-	printk(KERN_DEBUG "ISICOM: isicom_setup_board ...\n");		
-#endif	
 	isicom_setup_board(card);		
 	
 	port->count++;
 	tty->driver_data = port;
 	port->tty = tty;
-#ifdef ISICOM_DEBUG	
-	printk(KERN_DEBUG "ISICOM: isicom_setup_port ...\n");
-#endif	
 	if ((error = isicom_setup_port(port))!=0)
 		return error;
-#ifdef ISICOM_DEBUG		
-	printk(KERN_DEBUG "ISICOM: block_til_ready ...\n");	
-#endif	
 	if ((error = block_til_ready(tty, filp, port))!=0)
 		return error;
 
-#ifdef ISICOM_DEBUG	
-	printk(KERN_DEBUG "ISICOM: open end!!!.\n");
-#endif	
 	return 0;      		
 }
  
@@ -1023,38 +1243,50 @@
 
 static inline void isicom_shutdown_board(struct isi_board * bp)
 {
-	int channel;
-	struct isi_port * port;
-	
-	if (!(bp->status & BOARD_ACTIVE))
-		return;
-	bp->status &= ~BOARD_ACTIVE;
-	port = bp->ports;
-	for(channel = 0; channel < bp->port_count; channel++, port++) {
-		drop_dtr_rts(port);
-	}	
+	unsigned long flags;
+
+	spin_lock_irqsave(&bp->card_lock, flags);
+	if (bp->status & BOARD_ACTIVE) {
+		bp->status &= ~BOARD_ACTIVE;
+	}
+	spin_unlock_irqrestore(&bp->card_lock, flags);
 }
 
 static void isicom_shutdown_port(struct isi_port * port)
 {
 	struct isi_board * card = port->card;
 	struct tty_struct * tty;	
+	unsigned long flags;
 	
-	if (!(port->flags & ASYNC_INITIALIZED))
+	tty = port->tty;
+
+	spin_lock_irqsave(&card->card_lock, flags);	
+	if (!(port->flags & ASYNC_INITIALIZED)) {
+		spin_unlock_irqrestore(&card->card_lock, flags);
 		return;
+	}
 	if (port->xmit_buf) {
 		free_page((unsigned long) port->xmit_buf);
 		port->xmit_buf = NULL;
 	}	
-	if (!(tty = port->tty) || C_HUPCL(tty)) 
+	port->flags &= ~ASYNC_INITIALIZED;
+	/* 3rd October 2000 : Vinayak P Risbud */
+	port->tty = 0;
+	spin_unlock_irqrestore(&card->card_lock, flags);
+	
+	/*Fix done by Anil .S on 30-04-2001
+	remote login through isi port has dtr toggle problem
+	due to which the carrier drops before the password prompt
+	appears on the remote end. Now we drop the dtr only if the 
+	HUPCL(Hangup on close) flag is set for the tty*/
+	
+	if (C_HUPCL(tty)) 
 		/* drop dtr on this port */
 		drop_dtr(port);
 		
 	/* any other port uninits  */ 
-	
 	if (tty)
 		set_bit(TTY_IO_ERROR, &tty->flags);
-	port->flags &= ~ASYNC_INITIALIZED;
 	
 	if (--card->count < 0) {
 		printk(KERN_DEBUG "ISICOM: isicom_shutdown_port: bad board(0x%x) count %d.\n",
@@ -1063,8 +1295,10 @@
 	}
 	
 	/* last port was closed , shutdown that boad too */
-	if (!card->count)
-		isicom_shutdown_board(card);
+	if(C_HUPCL(tty)) {
+		if (!card->count)
+			isicom_shutdown_board(card);
+	}
 }
 
 static void isicom_close(struct tty_struct * tty, struct file * filp)
@@ -1082,13 +1316,13 @@
 	printk(KERN_DEBUG "ISICOM: Close start!!!.\n");
 #endif	
 	
-	save_flags(flags); cli();
+	spin_lock_irqsave(&card->card_lock, flags);
 	if (tty_hung_up_p(filp)) {
-		restore_flags(flags);
+		spin_unlock_irqrestore(&card->card_lock, flags);
 		return;
 	}
 	
-	if ((tty->count == 1) && (port->count != 1)) {
+	if (tty->count == 1 && port->count != 1) {
 		printk(KERN_WARNING "ISICOM:(0x%x) isicom_close: bad port count"
 			"tty->count = 1	port count = %d.\n",
 			card->base, port->count);
@@ -1102,41 +1336,46 @@
 	}
 	
 	if (port->count) {
-		restore_flags(flags);
+		spin_unlock_irqrestore(&card->card_lock, flags);
 		return;
 	} 	
 	port->flags |= ASYNC_CLOSING;
 	tty->closing = 1;
+	spin_unlock_irqrestore(&card->card_lock, flags);
+	
 	if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
 		tty_wait_until_sent(tty, port->closing_wait);
 	/* indicate to the card that no more data can be received 
 	   on this port */
+	spin_lock_irqsave(&card->card_lock, flags);
 	if (port->flags & ASYNC_INITIALIZED) {   
 		card->port_status &= ~(1 << port->channel);
 		outw(card->port_status, card->base + 0x02);
 	}	
 	isicom_shutdown_port(port);
+	spin_unlock_irqrestore(&card->card_lock, flags);
+	
 	if (tty->driver->flush_buffer)
 		tty->driver->flush_buffer(tty);
-		
 	tty_ldisc_flush(tty);
+
+	spin_lock_irqsave(&card->card_lock, flags);
 	tty->closing = 0;
-	port->tty = NULL;
+
 	if (port->blocked_open) {
+		spin_unlock_irqrestore(&card->card_lock, flags);
 		if (port->close_delay) {
 #ifdef ISICOM_DEBUG			
 			printk(KERN_DEBUG "ISICOM: scheduling until time out.\n");
 #endif			
 			msleep_interruptible(jiffies_to_msecs(port->close_delay));
 		}
+		spin_lock_irqsave(&card->card_lock, flags);
 		wake_up_interruptible(&port->open_wait);
 	}	
 	port->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
 	wake_up_interruptible(&port->close_wait);
-	restore_flags(flags);
-#ifdef ISICOM_DEBUG	
-	printk(KERN_DEBUG "ISICOM: Close end!!!.\n");
-#endif	
+	spin_unlock_irqrestore(&card->card_lock, flags);
 }
 
 /* write et all */
@@ -1144,21 +1383,19 @@
 			const unsigned char * buf, int count)
 {
 	struct isi_port * port = (struct isi_port *) tty->driver_data;
+	struct isi_board * card = port->card;
 	unsigned long flags;
 	int cnt, total = 0;
-#ifdef ISICOM_DEBUG
-	printk(KERN_DEBUG "ISICOM: isicom_write for port%d: %d bytes.\n",
-			port->channel+1, count);
-#endif	  	
+
 	if (isicom_paranoia_check(port, tty->name, "isicom_write"))
 		return 0;
 	
 	if (!tty || !port->xmit_buf || !tmp_buf)
 		return 0;
 		
-	save_flags(flags);
+	spin_lock_irqsave(&card->card_lock, flags);
+	
 	while(1) {	
-		cli();
 		cnt = min_t(int, count, min(SERIAL_XMIT_SIZE - port->xmit_cnt - 1,
 					    SERIAL_XMIT_SIZE - port->xmit_head));
 		if (cnt <= 0) 
@@ -1167,17 +1404,13 @@
 		memcpy(port->xmit_buf + port->xmit_head, buf, cnt);
 		port->xmit_head = (port->xmit_head + cnt) & (SERIAL_XMIT_SIZE - 1);
 		port->xmit_cnt += cnt;
-		restore_flags(flags);
 		buf += cnt;
 		count -= cnt;
 		total += cnt;
 	}		
 	if (port->xmit_cnt && !tty->stopped && !tty->hw_stopped)
 		port->status |= ISI_TXOK;
-	restore_flags(flags);
-#ifdef ISICOM_DEBUG
-	printk(KERN_DEBUG "ISICOM: isicom_write %d bytes written.\n", total);
-#endif		
+	spin_unlock_irqrestore(&card->card_lock, flags);
 	return total;	
 }
 
@@ -1185,6 +1418,7 @@
 static void isicom_put_char(struct tty_struct * tty, unsigned char ch)
 {
 	struct isi_port * port = (struct isi_port *) tty->driver_data;
+	struct isi_board * card = port->card;
 	unsigned long flags;
 	
 	if (isicom_paranoia_check(port, tty->name, "isicom_put_char"))
@@ -1192,21 +1426,17 @@
 	
 	if (!tty || !port->xmit_buf)
 		return;
-#ifdef ISICOM_DEBUG
-	printk(KERN_DEBUG "ISICOM: put_char, port %d, char %c.\n", port->channel+1, ch);
-#endif			
-		
-	save_flags(flags); cli();
-	
-	if (port->xmit_cnt >= (SERIAL_XMIT_SIZE - 1)) {
-		restore_flags(flags);
+
+	spin_lock_irqsave(&card->card_lock, flags);
+	if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) {
+		spin_unlock_irqrestore(&card->card_lock, flags);
 		return;
 	}
 	
 	port->xmit_buf[port->xmit_head++] = ch;
 	port->xmit_head &= (SERIAL_XMIT_SIZE - 1);
 	port->xmit_cnt++;
-	restore_flags(flags);
+	spin_unlock_irqrestore(&card->card_lock, flags);
 }
 
 /* flush_chars et all */
@@ -1217,8 +1447,7 @@
 	if (isicom_paranoia_check(port, tty->name, "isicom_flush_chars"))
 		return;
 	
-	if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
-	    !port->xmit_buf)
+	if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || !port->xmit_buf)
 		return;
 		
 	/* this tells the transmitter to consider this port for
@@ -1231,6 +1460,7 @@
 {
 	struct isi_port * port = (struct isi_port *) tty->driver_data;
 	int free;
+
 	if (isicom_paranoia_check(port, tty->name, "isicom_write_room"))
 		return 0;
 	
@@ -1253,21 +1483,17 @@
 static inline void isicom_send_break(struct isi_port * port, unsigned long length)
 {
 	struct isi_board * card = port->card;
-	short wait = 10;
 	unsigned short base = card->base;	
-	unsigned long flags;
 	
-	save_flags(flags); cli();
-	while (((inw(base + 0x0e) & 0x0001) == 0) && (wait-- > 0));	
-	if (!wait) {
-		printk(KERN_DEBUG "ISICOM: Card found busy in isicom_send_break.\n");
-		goto out;
-	}	
+	if(!lock_card(card))
+		return;
+		
 	outw(0x8000 | ((port->channel) << (card->shift_count)) | 0x3, base);
 	outw((length & 0xff) << 8 | 0x00, base);
 	outw((length & 0xff00), base);
 	InterruptTheCard(base);
-out:	restore_flags(flags);
+
+	unlock_card(card);
 }
 
 static int isicom_tiocmget(struct tty_struct *tty, struct file *file)
@@ -1291,12 +1517,10 @@
 			   unsigned int set, unsigned int clear)
 {
 	struct isi_port * port = (struct isi_port *) tty->driver_data;
-	unsigned long flags;
 	
 	if (isicom_paranoia_check(port, tty->name, "isicom_ioctl"))
 		return -ENODEV;
 	
-	save_flags(flags); cli();
 	if (set & TIOCM_RTS)
 		raise_rts(port);
 	if (set & TIOCM_DTR)
@@ -1307,7 +1531,6 @@
 	if (clear & TIOCM_DTR)
 		drop_dtr(port);
 
-	restore_flags(flags);
 	return 0;
 }			
 
@@ -1315,7 +1538,6 @@
 					struct serial_struct __user *info)
 {
 	struct serial_struct newinfo;
-	unsigned long flags;
 	int reconfig_port;
 
 	if(copy_from_user(&newinfo, info, sizeof(newinfo)))
@@ -1340,9 +1562,7 @@
 				(newinfo.flags & ASYNC_FLAGS));
 	}
 	if (reconfig_port) {
-		save_flags(flags); cli();
 		isicom_config_port(port);
-		restore_flags(flags);
 	}
 	return 0;		 
 }		
@@ -1421,7 +1641,6 @@
 static void isicom_set_termios(struct tty_struct * tty, struct termios * old_termios)
 {
 	struct isi_port * port = (struct isi_port *) tty->driver_data;
-	unsigned long flags;
 	
 	if (isicom_paranoia_check(port, tty->name, "isicom_set_termios"))
 		return;
@@ -1430,9 +1649,7 @@
 	    tty->termios->c_iflag == old_termios->c_iflag)
 		return;
 		
-	save_flags(flags); cli();
 	isicom_config_port(port);
-	restore_flags(flags);
 	
 	if ((old_termios->c_cflag & CRTSCTS) &&
 	    !(tty->termios->c_cflag & CRTSCTS)) {	
@@ -1446,16 +1663,13 @@
 {
 	struct isi_port * port = (struct isi_port *) tty->driver_data;
 	struct isi_board * card = port->card;
-	unsigned long flags;
 	
 	if (isicom_paranoia_check(port, tty->name, "isicom_throttle"))
 		return;
 	
 	/* tell the card that this port cannot handle any more data for now */
-	save_flags(flags); cli();
 	card->port_status &= ~(1 << port->channel);
 	outw(card->port_status, card->base + 0x02);
-	restore_flags(flags);
 }
 
 /* unthrottle et all */
@@ -1463,16 +1677,13 @@
 {
 	struct isi_port * port = (struct isi_port *) tty->driver_data;
 	struct isi_board * card = port->card;
-	unsigned long flags;
 	
 	if (isicom_paranoia_check(port, tty->name, "isicom_unthrottle"))
 		return;
 	
 	/* tell the card that this port is ready to accept more data */
-	save_flags(flags); cli();
 	card->port_status |= (1 << port->channel);
 	outw(card->port_status, card->base + 0x02);
-	restore_flags(flags);
 }
 
 /* stop et all */
@@ -1509,7 +1720,7 @@
 	
 	tty = port->tty;
 	if (tty)
-		tty_hangup(tty);	/* FIXME: module removal race here - AKPM */
+		tty_hangup(tty);
 }
 
 static void isicom_hangup(struct tty_struct * tty)
@@ -1530,21 +1741,22 @@
 static void isicom_flush_buffer(struct tty_struct * tty)
 {
 	struct isi_port * port = (struct isi_port *) tty->driver_data;
+	struct isi_board * card = port->card;
 	unsigned long flags;
 	
 	if (isicom_paranoia_check(port, tty->name, "isicom_flush_buffer"))
 		return;
 	
-	save_flags(flags); cli();
+	spin_lock_irqsave(&card->card_lock, flags);
 	port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
-	restore_flags(flags);
+	spin_unlock_irqrestore(&card->card_lock, flags);
 	
 	wake_up_interruptible(&tty->write_wait);
 	tty_wakeup(tty);
 }
 
 
-static int register_ioregion(void)
+static int __init register_ioregion(void)
 {
 	int count, done=0;
 	for (count=0; count < BOARD_COUNT; count++ ) {
@@ -1559,7 +1771,7 @@
 	return done;
 }
 
-static void unregister_ioregion(void)
+static void __exit unregister_ioregion(void)
 {
 	int count;
 	for (count=0; count < BOARD_COUNT; count++ ) 
@@ -1591,7 +1803,7 @@
 	.tiocmset	= isicom_tiocmset,
 };
 
-static int register_drivers(void)
+static int __init register_drivers(void)
 {
 	int error;
 
@@ -1622,7 +1834,7 @@
 	return 0;
 }
 
-static void unregister_drivers(void)
+static void __exit unregister_drivers(void)
 {
 	int error = tty_unregister_driver(isicom_normal);
 	if (error)
@@ -1630,78 +1842,48 @@
 	put_tty_driver(isicom_normal);
 }
 
-static int register_isr(void)
+static int __init register_isr(void)
 {
-	int count, done=0, card;
-	int flag;
-	unsigned char request;
+	int count, done=0;
+	unsigned long irqflags;
+
 	for (count=0; count < BOARD_COUNT; count++ ) {
 		if (isi_card[count].base) {
-		/*
-		 * verify if the required irq has already been requested for
-		 * another ISI Card, if so we already have it, else request it
-		 */
-			request = YES;
-			for(card = 0; card < count; card++)
-			if ((isi_card[card].base) && (isi_card[card].irq == isi_card[count].irq)) {
-				request = NO;
-				if ((isi_card[count].isa == NO) && (isi_card[card].isa == NO))
-					break;
-				/*
-				 * ISA cards cannot share interrupts with other
-				 * PCI or ISA devices hence disable this card.
-				 */
+			irqflags = (isi_card[count].isa == YES) ? 
+					SA_INTERRUPT : 
+					(SA_INTERRUPT | SA_SHIRQ);
+
+			if (request_irq(isi_card[count].irq, 
+					isicom_interrupt, 
+					irqflags, 
+					ISICOM_NAME, &isi_card[count])) {
+
+				printk(KERN_WARNING "ISICOM: Could not"
+					" install handler at Irq %d."
+					" Card%d will be disabled.\n",
+					isi_card[count].irq, count+1);
+
 				release_region(isi_card[count].base,16);
-				isi_card[count].base = 0;
-				break;
-			}
-			flag=0;
-			if(isi_card[count].isa == NO)
-				flag |= SA_SHIRQ;
-				
-			if (request == YES) { 
-				if (request_irq(isi_card[count].irq, isicom_interrupt, SA_INTERRUPT|flag, ISICOM_NAME, NULL)) {
-					printk(KERN_WARNING "ISICOM: Could not install handler at Irq %d. Card%d will be disabled.\n",
-						isi_card[count].irq, count+1);
-					release_region(isi_card[count].base,16);
-					isi_card[count].base=0;
-				}
-				else {
-					printk(KERN_INFO "ISICOM: Card%d at 0x%x using irq %d.\n", 
-					count+1, isi_card[count].base, isi_card[count].irq); 
-					
-					irq_to_board[isi_card[count].irq]=&isi_card[count];
-					done++;
-				}
+				isi_card[count].base=0;
 			}
+			else
+				done++;
 		}	
 	}
 	return done;
 }
 
-static void unregister_isr(void)
+static void __exit unregister_isr(void)
 {
-	int count, card;
-	unsigned char freeirq;
+	int count;
+
 	for (count=0; count < BOARD_COUNT; count++ ) {
-		if (isi_card[count].base) {
-			freeirq = YES;
-			for(card = 0; card < count; card++)
-				if ((isi_card[card].base) && (isi_card[card].irq == isi_card[count].irq)) {
-					freeirq = NO;
-					break;
-				}
-			if (freeirq == YES) {
-				free_irq(isi_card[count].irq, NULL);
-#ifdef ISICOM_DEBUG			
-				printk(KERN_DEBUG "ISICOM: Irq %d released for Card%d.\n",isi_card[count].irq, count+1);
-#endif	
-			}		
-		}
+		if (isi_card[count].base)
+			free_irq(isi_card[count].irq, &isi_card[count]);
 	}
 }
 
-static int isicom_init(void)
+static int __init isicom_init(void)
 {
 	int card, channel, base;
 	struct isi_port * port;
@@ -1744,11 +1926,12 @@
 	for (card = 0; card < BOARD_COUNT; card++) {
 		port = &isi_ports[card * 16];
 		isi_card[card].ports = port;
+		spin_lock_init(&isi_card[card].card_lock);
 		base = isi_card[card].base;
 		for (channel = 0; channel < 16; channel++, port++) {
 			port->magic = ISICOM_MAGIC;
 			port->card = &isi_card[card];
-			port->channel = channel;		
+			port->channel = channel;
 		 	port->close_delay = 50 * HZ/100;
 		 	port->closing_wait = 3000 * HZ/100;
 		 	INIT_WORK(&port->hangup_tq, do_isicom_hangup, port);
@@ -1778,7 +1961,7 @@
 module_param_array(irq, int, NULL, 0);
 MODULE_PARM_DESC(irq, "Interrupts for the cards");
 
-int init_module(void)
+static int __devinit isicom_setup(void)
 {
 	struct pci_dev *dev = NULL;
 	int retval, card, idx, count;
@@ -1878,38 +2061,19 @@
 	return 0;
 }
 
-void cleanup_module(void)
+static void __exit isicom_exit(void)
 {
 	re_schedule = 0;
+	/* FIXME */
 	msleep(1000);
-
-#ifdef ISICOM_DEBUG	
-	printk("ISICOM: isicom_tx tx_count = %ld.\n", tx_count);
-#endif	
-
-#ifdef ISICOM_DEBUG
-	printk("ISICOM: uregistering isr ...\n");
-#endif	
 	unregister_isr();
-
-#ifdef ISICOM_DEBUG	
-	printk("ISICOM: unregistering drivers ...\n");
-#endif
 	unregister_drivers();
-	
-#ifdef ISICOM_DEBUG	
-	printk("ISICOM: unregistering ioregion ...\n");
-#endif	
 	unregister_ioregion();	
-	
-#ifdef ISICOM_DEBUG	
-	printk("ISICOM: freeing tmp_buf ...\n");
-#endif	
-	free_page((unsigned long)tmp_buf);
-	
-#ifdef ISICOM_DEBUG		
-	printk("ISICOM: unregistering firmware loader ...\n");	
-#endif
+	if(tmp_buf)
+		free_page((unsigned long)tmp_buf);
 	if (misc_deregister(&isiloader_device))
 		printk(KERN_ERR "ISICOM: Unable to unregister Firmware Loader driver\n");
 }
+
+module_init(isicom_setup);
+module_exit(isicom_exit);
diff -Nru a/drivers/char/ite_gpio.c b/drivers/char/ite_gpio.c
--- a/drivers/char/ite_gpio.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/char/ite_gpio.c	2005-03-01 23:39:07 -08:00
@@ -30,9 +30,7 @@
  *  with this program; if not, write  to the Free Software Foundation, Inc.,
  *  675 Mass Ave, Cambridge, MA 02139, USA.
  */
-
 #include <linux/module.h>
-#include <linux/config.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/miscdevice.h>
@@ -238,10 +236,6 @@
 
 static int ite_gpio_open(struct inode *inode, struct file *file)
 {
-	unsigned int minor = iminor(inode); 
-	if (minor != GPIO_MINOR)
-		return -ENODEV;
-
 	return 0;
 }
 
@@ -255,7 +249,6 @@
 static int ite_gpio_ioctl(struct inode *inode, struct file *file,
 	unsigned int cmd, unsigned long arg)
 {
-
 	static struct ite_gpio_ioctl_data ioctl_data;
 
 	if (copy_from_user(&ioctl_data, (struct ite_gpio_ioctl_data *)arg,
@@ -314,10 +307,12 @@
 			return -ENOIOCTLCMD;
 
 	}
+
 	return 0;
 }
 
-static void ite_gpio_irq_handler(int this_irq, void *dev_id, struct pt_regs *regs)
+static void ite_gpio_irq_handler(int this_irq, void *dev_id,
+	struct pt_regs *regs)
 {
 	int i,line;
 
@@ -362,18 +357,15 @@
 	}
 }
 
-static struct file_operations ite_gpio_fops =
-{
+static struct file_operations ite_gpio_fops = {
 	.owner		= THIS_MODULE,
 	.ioctl		= ite_gpio_ioctl,
 	.open		= ite_gpio_open,
 	.release	= ite_gpio_release,
 };
 
-/* GPIO_MINOR in include/linux/miscdevice.h */
-static struct miscdevice ite_gpio_miscdev =
-{
-	GPIO_MINOR,
+static struct miscdevice ite_gpio_miscdev = {
+	MISC_DYNAMIC_MINOR,
 	"ite_gpio",
 	&ite_gpio_fops
 };
@@ -416,7 +408,7 @@
 	return 0;
 }	
 
-void __exit ite_gpio_exit(void)
+static void __exit ite_gpio_exit(void)
 {
 	misc_deregister(&ite_gpio_miscdev);
 }
diff -Nru a/drivers/char/keyboard.c b/drivers/char/keyboard.c
--- a/drivers/char/keyboard.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/char/keyboard.c	2005-03-01 23:39:18 -08:00
@@ -31,7 +31,6 @@
 #include <linux/tty_flip.h>
 #include <linux/mm.h>
 #include <linux/string.h>
-#include <linux/random.h>
 #include <linux/init.h>
 #include <linux/slab.h>
 
@@ -199,6 +198,8 @@
 
 	if (scancode < 0 || scancode >= dev->keycodemax)
 		return -EINVAL;
+	if (keycode < 0 || keycode > KEY_MAX)
+		return -EINVAL;
 
 	oldkey = SET_INPUT_KEYCODE(dev, scancode, keycode);
 
@@ -330,7 +331,7 @@
  * in utf-8 already. UTF-8 is defined for words of up to 31 bits,
  * but we need only 16 bits here
  */
-void to_utf8(struct vc_data *vc, ushort c) 
+static void to_utf8(struct vc_data *vc, ushort c)
 {
 	if (c < 0x80)
 		/*  0******* */
@@ -392,7 +393,7 @@
  * Otherwise, conclude that DIACR was not combining after all,
  * queue it and return CH.
  */
-unsigned char handle_diacr(struct vc_data *vc, unsigned char ch)
+static unsigned char handle_diacr(struct vc_data *vc, unsigned char ch)
 {
 	int d = diacr;
 	int i;
@@ -853,18 +854,6 @@
 	set_leds();
 }
 
-void register_leds(struct kbd_struct *kbd, unsigned int led,
-		   unsigned int *addr, unsigned int mask)
-{
-	if (led < 3) {
-		ledptrs[led].addr = addr;
-		ledptrs[led].mask = mask;
-		ledptrs[led].valid = 1;
-		kbd->ledmode = LED_SHOW_MEM;
-	} else
-		kbd->ledmode = LED_SHOW_FLAGS;
-}
-
 static inline unsigned char getleds(void)
 {
 	struct kbd_struct *kbd = kbd_table + fg_console;
@@ -925,7 +914,7 @@
 /*
  * This allows a newly plugged keyboard to pick the LED state.
  */
-void kbd_refresh_leds(struct input_handle *handle)
+static void kbd_refresh_leds(struct input_handle *handle)
 {
 	unsigned char leds = ledstate;
 
@@ -939,7 +928,10 @@
 	tasklet_enable(&keyboard_tasklet);
 }
 
-#if defined(CONFIG_X86) || defined(CONFIG_IA64) || defined(CONFIG_ALPHA) || defined(CONFIG_MIPS) || defined(CONFIG_PPC) || defined(CONFIG_SPARC32) || defined(CONFIG_SPARC64) || defined(CONFIG_PARISC) || defined(CONFIG_SUPERH)
+#if defined(CONFIG_X86) || defined(CONFIG_IA64) || defined(CONFIG_ALPHA) ||\
+    defined(CONFIG_MIPS) || defined(CONFIG_PPC) || defined(CONFIG_SPARC32) ||\
+    defined(CONFIG_SPARC64) || defined(CONFIG_PARISC) || defined(CONFIG_SUPERH) ||\
+    (defined(CONFIG_ARM) && defined(CONFIG_KEYBOARD_ATKBD) && !defined(CONFIG_RPC))
 
 #define HW_RAW(dev) (test_bit(EV_MSC, dev->evbit) && test_bit(MSC_RAW, dev->mscbit) &&\
 			((dev)->id.bustype == BUS_I8042) && ((dev)->id.vendor == 0x0001) && ((dev)->id.product == 0x0001))
@@ -1024,7 +1016,7 @@
 }
 #endif
 
-void kbd_rawcode(unsigned char data)
+static void kbd_rawcode(unsigned char data)
 {
 	struct vc_data *vc = vc_cons[fg_console].d;
 	kbd = kbd_table + fg_console;
@@ -1039,9 +1031,6 @@
 	unsigned char type, raw_mode;
 	struct tty_struct *tty;
 	int shift_final;
-
-	if (down != 2)
-		add_keyboard_randomness((keycode << 1) ^ down);
 
 	tty = vc->vc_tty;
 
diff -Nru a/drivers/char/lcd.c b/drivers/char/lcd.c
--- a/drivers/char/lcd.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/char/lcd.c	2005-03-01 23:38:56 -08:00
@@ -33,11 +33,14 @@
 
 #include "lcd.h"
 
+static DEFINE_SPINLOCK(lcd_lock);
+
 static int lcd_ioctl(struct inode *inode, struct file *file,
 		     unsigned int cmd, unsigned long arg);
 
-static int lcd_present = 1;
+static unsigned int lcd_present = 1;
 
+/* used in arch/mips/cobalt/reset.c */
 int led_state = 0;
 
 #if defined(CONFIG_TULIP) && 0
@@ -63,7 +66,6 @@
 {
 	struct lcd_display button_display;
 	unsigned long address, a;
-	int index;
 
 	switch (cmd) {
 	case LCD_On:
@@ -220,6 +222,7 @@
 
 	case LCD_Write:{
 			struct lcd_display display;
+			unsigned int index;
 
 
 			if (copy_from_user
@@ -316,7 +319,7 @@
 //  set only bit led_display.leds
 
 	case LED_Bit_Set:{
-			int i;
+			unsigned int i;
 			int bit = 1;
 			struct lcd_display led_display;
 
@@ -338,7 +341,7 @@
 //  clear only bit led_display.leds
 
 	case LED_Bit_Clear:{
-			int i;
+			unsigned int i;
 			int bit = 1;
 			struct lcd_display led_display;
 
@@ -413,6 +416,10 @@
 
 			int ctr = 0;
 
+			if ( !capable(CAP_SYS_ADMIN) ) return -EPERM;
+
+			pr_info(LCD "Erasing Flash\n");
+
 			// Chip Erase Sequence
 			WRITE_FLASH(kFlash_Addr1, kFlash_Data1);
 			WRITE_FLASH(kFlash_Addr2, kFlash_Data2);
@@ -421,21 +428,15 @@
 			WRITE_FLASH(kFlash_Addr2, kFlash_Data2);
 			WRITE_FLASH(kFlash_Addr1, kFlash_Erase6);
 
-			printk("Erasing Flash.\n");
-
 			while ((!dqpoll(0x00000000, 0xFF))
 			       && (!timeout(0x00000000))) {
 				ctr++;
 			}
 
-			printk("\n");
-			printk("\n");
-			printk("\n");
-
 			if (READ_FLASH(0x07FFF0) == 0xFF) {
-				printk("Erase Successful\r\n");
+				pr_info(LCD "Erase Successful\n");
 			} else if (timeout) {
-				printk("Erase Timed Out\r\n");
+				pr_info(LCD "Erase Timed Out\n");
 			}
 
 			break;
@@ -447,31 +448,35 @@
 
 			volatile unsigned long burn_addr;
 			unsigned long flags;
-			int i;
+			unsigned int i, index;
 			unsigned char *rom;
 
 
 			struct lcd_display display;
 
+			if ( !capable(CAP_SYS_ADMIN) ) return -EPERM;
+
 			if (copy_from_user
 			    (&display, (struct lcd_display *) arg,
 			     sizeof(struct lcd_display)))
 				return -EFAULT;
 			rom = (unsigned char *) kmalloc((128), GFP_ATOMIC);
 			if (rom == NULL) {
-				printk("broken\n");
-				return 1;
+				printk(KERN_ERR LCD "kmalloc() failed in %s\n",
+						__FUNCTION__);
+				return -ENOMEM;
 			}
 
-			printk("Churning and Burning -");
-			save_flags(flags);
+			pr_info(LCD "Starting Flash burn\n");
 			for (i = 0; i < FLASH_SIZE; i = i + 128) {
 
 				if (copy_from_user
-				    (rom, display.RomImage + i, 128))
+				    (rom, display.RomImage + i, 128)) {
+					kfree(rom);
 					return -EFAULT;
+				}
 				burn_addr = kFlashBase + i;
-				cli();
+				spin_lock_irqsave(&lcd_lock, flags);
 				for (index = 0; index < (128); index++) {
 
 					WRITE_FLASH(kFlash_Addr1,
@@ -480,32 +485,30 @@
 						    kFlash_Data2);
 					WRITE_FLASH(kFlash_Addr1,
 						    kFlash_Prog);
-					*((volatile unsigned char *)
-					  burn_addr) =
-		 (volatile unsigned char) rom[index];
-
-					while ((!dqpoll
-						(burn_addr,
-						 (volatile unsigned char)
-						 rom[index]))
-					       && (!timeout(burn_addr))) {
-					}
+					*((volatile unsigned char *)burn_addr) =
+					  (volatile unsigned char) rom[index];
+
+					while ((!dqpoll (burn_addr,
+						(volatile unsigned char)
+						rom[index])) &&
+						(!timeout(burn_addr))) { }
 					burn_addr++;
 				}
-				restore_flags(flags);
-				if (*
-				    ((volatile unsigned char *) (burn_addr
-								 - 1)) ==
-				    (volatile unsigned char) rom[index -
-								 1]) {
+				spin_unlock_irqrestore(&lcd_lock, flags);
+				if (* ((volatile unsigned char *)
+					(burn_addr - 1)) ==
+					(volatile unsigned char)
+					rom[index - 1]) {
 				} else if (timeout) {
-					printk("Program timed out\r\n");
+					pr_info(LCD "Flash burn timed out\n");
 				}
 
 
 			}
 			kfree(rom);
 
+			pr_info(LCD "Flash successfully burned\n");
+
 			break;
 		}
 
@@ -515,7 +518,7 @@
 
 			unsigned char *user_bytes;
 			volatile unsigned long read_addr;
-			int i;
+			unsigned int i;
 
 			user_bytes =
 			    &(((struct lcd_display *) arg)->RomImage[0]);
@@ -524,7 +527,7 @@
 			    (VERIFY_WRITE, user_bytes, FLASH_SIZE))
 				return -EFAULT;
 
-			printk("Reading Flash");
+			pr_info(LCD "Reading Flash");
 			for (i = 0; i < FLASH_SIZE; i++) {
 				unsigned char tmp_byte;
 				read_addr = kFlashBase + i;
@@ -540,8 +543,7 @@
 		}
 
 	default:
-		return 0;
-		break;
+		return -EINVAL;
 
 	}
 
@@ -613,7 +615,7 @@
 {
 	unsigned long data;
 
-	printk("%s\n", LCD_DRIVER);
+	pr_info("%s\n", LCD_DRIVER);
 	misc_register(&lcd_dev);
 
 	/* Check region? Naaah! Just snarf it up. */
@@ -623,7 +625,7 @@
 	data = LCDReadData;
 	if ((data & 0x000000FF) == (0x00)) {
 		lcd_present = 0;
-		printk("LCD Not Present\n");
+		pr_info(LCD "LCD Not Present\n");
 	} else {
 		lcd_present = 1;
 		WRITE_GAL(kGal_DevBank2PReg, kGal_DevBank2Cfg);
diff -Nru a/drivers/char/lcd.h b/drivers/char/lcd.h
--- a/drivers/char/lcd.h	2005-03-01 23:38:57 -08:00
+++ b/drivers/char/lcd.h	2005-03-01 23:38:57 -08:00
@@ -37,6 +37,8 @@
 
 #define LCD_DRIVER	"Cobalt LCD Driver v2.10"
 
+#define LCD		"lcd: "
+
 #define kLCD_IR		0x0F000000
 #define kLCD_DR		0x0F000010
 #define kGPI		0x0D000000
diff -Nru a/drivers/char/lp.c b/drivers/char/lp.c
--- a/drivers/char/lp.c	2005-03-01 23:38:44 -08:00
+++ b/drivers/char/lp.c	2005-03-01 23:38:44 -08:00
@@ -142,7 +142,7 @@
 /* ROUND_UP macro from fs/select.c */
 #define ROUND_UP(x,y) (((x)+(y)-1)/(y))
 
-struct lp_struct lp_table[LP_NO];
+static struct lp_struct lp_table[LP_NO];
 
 static unsigned int lp_count = 0;
 static struct class_simple *lp_class;
@@ -867,7 +867,7 @@
 	.detach = lp_detach,
 };
 
-int __init lp_init (void)
+static int __init lp_init (void)
 {
 	int i, err = 0;
 
diff -Nru a/drivers/char/misc.c b/drivers/char/misc.c
--- a/drivers/char/misc.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/char/misc.c	2005-03-01 23:39:16 -08:00
@@ -207,10 +207,9 @@
 int misc_register(struct miscdevice * misc)
 {
 	struct miscdevice *c;
-	struct class_device *class;
 	dev_t dev;
 	int err;
-	
+
 	down(&misc_sem);
 	list_for_each_entry(c, &misc_list, list) {
 		if (c->minor == misc->minor) {
@@ -224,8 +223,7 @@
 		while (--i >= 0)
 			if ( (misc_minors[i>>3] & (1 << (i&7))) == 0)
 				break;
-		if (i<0)
-		{
+		if (i<0) {
 			up(&misc_sem);
 			return -EBUSY;
 		}
@@ -240,10 +238,10 @@
 	}
 	dev = MKDEV(MISC_MAJOR, misc->minor);
 
-	class = class_simple_device_add(misc_class, dev,
-					misc->dev, misc->name);
-	if (IS_ERR(class)) {
-		err = PTR_ERR(class);
+	misc->class = class_simple_device_add(misc_class, dev,
+					      misc->dev, misc->name);
+	if (IS_ERR(misc->class)) {
+		err = PTR_ERR(misc->class);
 		goto out;
 	}
 
diff -Nru a/drivers/char/mmtimer.c b/drivers/char/mmtimer.c
--- a/drivers/char/mmtimer.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/char/mmtimer.c	2005-03-01 23:39:07 -08:00
@@ -36,9 +36,7 @@
 #include <asm/sn/intr.h>
 #include <asm/sn/shub_mmr.h>
 #include <asm/sn/nodepda.h>
-
-/* This is ugly and jbarnes has promised me to fix this later */
-#include "../../arch/ia64/sn/include/shubio.h"
+#include <asm/sn/shubio.h>
 
 MODULE_AUTHOR("Jesse Barnes <jbarnes@sgi.com>");
 MODULE_DESCRIPTION("SGI Altix RTC Timer");
diff -Nru a/drivers/char/mwave/3780i.c b/drivers/char/mwave/3780i.c
--- a/drivers/char/mwave/3780i.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/char/mwave/3780i.c	2005-03-01 23:39:16 -08:00
@@ -61,7 +61,7 @@
 #include "mwavedd.h"
 #include "3780i.h"
 
-static spinlock_t dsp_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(dsp_lock);
 static unsigned long flags;
 
 
diff -Nru a/drivers/char/mwave/mwavedd.c b/drivers/char/mwave/mwavedd.c
--- a/drivers/char/mwave/mwavedd.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/char/mwave/mwavedd.c	2005-03-01 23:38:54 -08:00
@@ -76,11 +76,11 @@
 int mwave_3780i_io = 0;
 int mwave_uart_irq = 0;
 int mwave_uart_io = 0;
-MODULE_PARM(mwave_debug, "i");
-MODULE_PARM(mwave_3780i_irq, "i");
-MODULE_PARM(mwave_3780i_io, "i");
-MODULE_PARM(mwave_uart_irq, "i");
-MODULE_PARM(mwave_uart_io, "i");
+module_param(mwave_debug, int, 0);
+module_param(mwave_3780i_irq, int, 0);
+module_param(mwave_3780i_io, int, 0);
+module_param(mwave_uart_irq, int, 0);
+module_param(mwave_uart_io, int, 0);
 
 static int mwave_open(struct inode *inode, struct file *file);
 static int mwave_close(struct inode *inode, struct file *file);
diff -Nru a/drivers/char/mxser.c b/drivers/char/mxser.c
--- a/drivers/char/mxser.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/char/mxser.c	2005-03-01 23:39:07 -08:00
@@ -401,7 +401,7 @@
 static void mxser_flush_chars(struct tty_struct *);
 static void mxser_put_char(struct tty_struct *, unsigned char);
 static int mxser_ioctl(struct tty_struct *, struct file *, uint, ulong);
-static int mxser_ioctl_special(unsigned int, unsigned long);
+static int mxser_ioctl_special(unsigned int, void __user *);
 static void mxser_throttle(struct tty_struct *);
 static void mxser_unthrottle(struct tty_struct *);
 static void mxser_set_termios(struct tty_struct *, struct termios *);
@@ -417,9 +417,9 @@
 static int mxser_startup(struct mxser_struct *);
 static void mxser_shutdown(struct mxser_struct *);
 static int mxser_change_speed(struct mxser_struct *, struct termios *old_termios);
-static int mxser_get_serial_info(struct mxser_struct *, struct serial_struct *);
-static int mxser_set_serial_info(struct mxser_struct *, struct serial_struct *);
-static int mxser_get_lsr_info(struct mxser_struct *, unsigned int *);
+static int mxser_get_serial_info(struct mxser_struct *, struct serial_struct __user *);
+static int mxser_set_serial_info(struct mxser_struct *, struct serial_struct __user *);
+static int mxser_get_lsr_info(struct mxser_struct *, unsigned int __user *);
 static void mxser_send_break(struct mxser_struct *, int);
 static int mxser_tiocmget(struct tty_struct *, struct file *);
 static int mxser_tiocmset(struct tty_struct *, struct file *, unsigned int, unsigned int);
@@ -556,7 +556,7 @@
 	info = &mxvar_table[n];
 	/*if (verbose) */  {
 		printk(KERN_DEBUG "        ttyM%d - ttyM%d ", n, n + hwconf->ports - 1);
-		printk(KERN_DEBUG " max. baud rate = %d bps.\n", hwconf->MaxCanSetBaudRate[0]);
+		printk(" max. baud rate = %d bps.\n", hwconf->MaxCanSetBaudRate[0]);
 	}
 
 	for (i = 0; i < hwconf->ports; i++, n++, info++) {
@@ -609,18 +609,12 @@
 	n = board * MXSER_PORTS_PER_BOARD;
 	info = &mxvar_table[n];
 
-	spin_lock_irqsave(&info->slock, flags);
 	retval = request_irq(hwconf->irq, mxser_interrupt, IRQ_T(info), "mxser", info);
 	if (retval) {
-		spin_unlock_irqrestore(&info->slock, flags);
 		printk(KERN_ERR "Board %d: %s", board, mxser_brdname[hwconf->board_type - 1]);
 		printk("  Request irq fail,IRQ (%d) may be conflit with another device.\n", info->irq);
 		return retval;
 	}
-
-	spin_unlock_irqrestore(&info->slock, flags);
-
-
 	return 0;
 }
 
@@ -834,6 +828,7 @@
 	}
 
 	/* start finding PCI board here */
+#ifdef CONFIG_PCI
 	n = (sizeof(mxser_pcibrds) / sizeof(mxser_pcibrds[0])) - 1;
 	index = 0;
 	b = 0;
@@ -875,6 +870,7 @@
 			m++;
 		}
 	}
+#endif
 
 	ret1 = 0;
 	if (!(ret1 = tty_register_driver(mxvar_sdriver))) {
@@ -968,7 +964,7 @@
 			*tty->termios = info->normal_termios;
 		else
 			*tty->termios = info->callout_termios;
-		mxser_change_speed(info, 0);
+		mxser_change_speed(info, NULL);
 	}
 
 	info->session = current->signal->session;
@@ -1084,7 +1080,7 @@
 		
 	tty->closing = 0;
 	info->event = 0;
-	info->tty = 0;
+	info->tty = NULL;
 	if (info->blocked_open) {
 		if (info->close_delay) {
 			set_current_state(TASK_INTERRUPTIBLE);
@@ -1223,12 +1219,13 @@
 	struct mxser_struct *info = (struct mxser_struct *) tty->driver_data;
 	int retval;
 	struct async_icount cprev, cnow;	/* kernel counter temps */
-	struct serial_icounter_struct *p_cuser;	/* user space */
+	struct serial_icounter_struct __user *p_cuser;
 	unsigned long templ;
 	unsigned long flags;
+	void __user *argp = (void __user *)arg;
 
 	if (tty->index == MXSER_PORTS)
-		return (mxser_ioctl_special(cmd, arg));
+		return (mxser_ioctl_special(cmd, argp));
 
 	// following add by Victor Yu. 01-05-2004
 	if (cmd == MOXA_SET_OP_MODE || cmd == MOXA_GET_OP_MODE) {
@@ -1239,7 +1236,7 @@
 
 		p = info->port % 4;
 		if (cmd == MOXA_SET_OP_MODE) {
-			if (get_user(opmode, (int *) arg))
+			if (get_user(opmode, (int __user *) argp))
 				return -EFAULT;
 			if (opmode != RS232_MODE && opmode != RS485_2WIRE_MODE && opmode != RS422_MODE && opmode != RS485_4WIRE_MODE)
 				return -EFAULT;
@@ -1253,7 +1250,7 @@
 			shiftbit = p * 2;
 			opmode = inb(info->opmode_ioaddr) >> shiftbit;
 			opmode &= OP_MODE_MASK;
-			if (copy_to_user((int *) arg, &opmode, sizeof(int)))
+			if (copy_to_user(argp, &opmode, sizeof(int)))
 				return -EFAULT;
 		}
 		return 0;
@@ -1281,19 +1278,19 @@
 		mxser_send_break(info, arg ? arg * (HZ / 10) : HZ / 4);
 		return (0);
 	case TIOCGSOFTCAR:
-		return put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long *) arg);
+		return put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long __user *) argp);
 	case TIOCSSOFTCAR:
-		if (get_user(templ, (unsigned long *) arg))
+		if (get_user(templ, (unsigned long __user *) argp))
 			return -EFAULT;
 		arg = templ;
 		tty->termios->c_cflag = ((tty->termios->c_cflag & ~CLOCAL) | (arg ? CLOCAL : 0));
 		return (0);
 	case TIOCGSERIAL:
-		return (mxser_get_serial_info(info, (struct serial_struct *) arg));
+		return mxser_get_serial_info(info, argp);
 	case TIOCSSERIAL:
-		return (mxser_set_serial_info(info, (struct serial_struct *) arg));
+		return mxser_set_serial_info(info, argp);
 	case TIOCSERGETLSR:	/* Get line status register */
-		return (mxser_get_lsr_info(info, (unsigned int *) arg));
+		return mxser_get_lsr_info(info, argp);
 		/*
 		 * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change
 		 * - mask passed in arg for lines of interest
@@ -1340,7 +1337,7 @@
 		spin_lock_irqsave(&info->slock, flags);
 		cnow = info->icount;
 		spin_unlock_irqrestore(&info->slock, flags);
-		p_cuser = (struct serial_icounter_struct *) arg;
+		p_cuser = argp;
 		/* modified by casper 1/11/2000 */
 		if (put_user(cnow.frame, &p_cuser->frame))
 			return -EFAULT;
@@ -1364,7 +1361,7 @@
 /* */
 		return 0;
 	case MOXA_HighSpeedOn:
-		return put_user(info->baud_base != 115200 ? 1 : 0, (int *) arg);
+		return put_user(info->baud_base != 115200 ? 1 : 0, (int __user *) argp);
 
 	case MOXA_SDS_RSTICOUNTER:{
 			info->mon_data.rxcnt = 0;
@@ -1374,13 +1371,13 @@
 // (above) added by James.
 	case MOXA_ASPP_SETBAUD:{
 			long baud;
-			if (get_user(baud, (long *) arg))
+			if (get_user(baud, (long __user *) argp))
 				return -EFAULT;
 			mxser_set_baud(info, baud);
 			return 0;
 		}
 	case MOXA_ASPP_GETBAUD:
-		if (copy_to_user((long *) arg, &info->realbaud, sizeof(long)))
+		if (copy_to_user(argp, &info->realbaud, sizeof(long)))
 			return -EFAULT;
 
 		return 0;
@@ -1394,7 +1391,7 @@
 
 			len += (lsr ? 0 : 1);
 
-			if (copy_to_user((int *) arg, &len, sizeof(int)))
+			if (copy_to_user(argp, &len, sizeof(int)))
 				return -EFAULT;
 
 			return 0;
@@ -1423,7 +1420,7 @@
 				info->mon_data.hold_reason &= ~NPPI_NOTIFY_CTSHOLD;
 
 
-			if (copy_to_user((struct mxser_mon *) arg, &(info->mon_data), sizeof(struct mxser_mon)))
+			if (copy_to_user(argp, &info->mon_data, sizeof(struct mxser_mon)))
 				return -EFAULT;
 
 			return 0;
@@ -1431,7 +1428,7 @@
 		}
 
 	case MOXA_ASPP_LSTATUS:{
-			if (copy_to_user((struct mxser_mon *) arg, &(info->err_shadow), sizeof(unsigned char)))
+			if (copy_to_user(argp, &info->err_shadow, sizeof(unsigned char)))
 				return -EFAULT;
 
 			info->err_shadow = 0;
@@ -1440,10 +1437,10 @@
 		}
 	case MOXA_SET_BAUD_METHOD:{
 			int method;
-			if (get_user(method, (int *) arg))
+			if (get_user(method, (int __user *) argp))
 				return -EFAULT;
 			mxser_set_baud_method[info->port] = method;
-			if (copy_to_user((int *) arg, &method, sizeof(int)))
+			if (copy_to_user(argp, &method, sizeof(int)))
 				return -EFAULT;
 
 			return 0;
@@ -1454,22 +1451,26 @@
 	return 0;
 }
 
-static int mxser_ioctl_special(unsigned int cmd, unsigned long arg)
+#ifndef CMSPAR
+#define	CMSPAR 010000000000
+#endif
+
+static int mxser_ioctl_special(unsigned int cmd, void __user *argp)
 {
 	int i, result, status;
 
 	switch (cmd) {
 	case MOXA_GET_CONF:
-		if (copy_to_user((struct mxser_hwconf *) arg, mxsercfg, sizeof(struct mxser_hwconf) * 4))
+		if (copy_to_user(argp, mxsercfg, sizeof(struct mxser_hwconf) * 4))
 			return -EFAULT;
 		return 0;
 	case MOXA_GET_MAJOR:
-		if (copy_to_user((int *) arg, &ttymajor, sizeof(int)))
+		if (copy_to_user(argp, &ttymajor, sizeof(int)))
 			return -EFAULT;
 		return 0;
 
 	case MOXA_GET_CUMAJOR:
-		if (copy_to_user((int *) arg, &calloutmajor, sizeof(int)))
+		if (copy_to_user(argp, &calloutmajor, sizeof(int)))
 			return -EFAULT;
 		return 0;
 
@@ -1479,9 +1480,9 @@
 			if (mxvar_table[i].base)
 				result |= (1 << i);
 		}
-		return put_user(result, (unsigned long *) arg);
+		return put_user(result, (unsigned long __user *) argp);
 	case MOXA_GETDATACOUNT:
-		if (copy_to_user((struct mxser_log *) arg, &mxvar_log, sizeof(mxvar_log)))
+		if (copy_to_user(argp, &mxvar_log, sizeof(mxvar_log)))
 			return -EFAULT;
 		return (0);
 	case MOXA_GETMSTATUS:
@@ -1516,7 +1517,7 @@
 			else
 				GMStatus[i].cts = 0;
 		}
-		if (copy_to_user((struct mxser_mstatus *) arg, GMStatus, sizeof(struct mxser_mstatus) * MXSER_PORTS))
+		if (copy_to_user(argp, GMStatus, sizeof(struct mxser_mstatus) * MXSER_PORTS))
 			return -EFAULT;
 		return 0;
 	case MOXA_ASPP_MON_EXT:{
@@ -1584,7 +1585,7 @@
 				mon_data_ext.iftype[i] = opmode;
 
 			}
-			if (copy_to_user((struct mxser_mon_ext *) arg, &mon_data_ext, sizeof(struct mxser_mon_ext)))
+			if (copy_to_user(argp, &mon_data_ext, sizeof(struct mxser_mon_ext)))
 				return -EFAULT;
 
 			return 0;
@@ -1829,7 +1830,7 @@
 	info->event = 0;
 	info->count = 0;
 	info->flags &= ~ASYNC_NORMAL_ACTIVE;
-	info->tty = 0;
+	info->tty = NULL;
 	wake_up_interruptible(&info->open_wait);
 }
 
@@ -1866,7 +1867,7 @@
 	int pass_counter = 0;
 	int handled = IRQ_NONE;
 
-	port = 0;
+	port = NULL;
 	//spin_lock(&gm_lock);
 
 	for (i = 0; i < MXSER_BOARDS; i++) {
@@ -2137,10 +2138,9 @@
 	mxvar_log.rxcnt[info->port] += cnt;
 	info->mon_data.rxcnt += cnt;
 	info->mon_data.up_rxcnt += cnt;
-
-	tty->ldisc.receive_buf(tty, tty->flip.char_buf, tty->flip.flag_buf, count);
 	spin_unlock_irqrestore(&info->slock, flags);
-
+	
+	tty_flip_buffer_push(tty);
 }
 
 static void mxser_transmit_chars(struct mxser_struct *info)
@@ -2412,7 +2412,7 @@
 	 * and set the speed of the serial port
 	 */
 	spin_unlock_irqrestore(&info->slock, flags);
-	mxser_change_speed(info, 0);
+	mxser_change_speed(info, NULL);
 
 	info->flags |= ASYNC_INITIALIZED;
 	return (0);
@@ -2442,7 +2442,7 @@
 	 */
 	if (info->xmit_buf) {
 		free_page((unsigned long) info->xmit_buf);
-		info->xmit_buf = 0;
+		info->xmit_buf = NULL;
 	}
 
 	info->IER = 0;
@@ -2591,9 +2591,6 @@
 		cval |= 0x04;
 	if (cflag & PARENB)
 		cval |= UART_LCR_PARITY;
-#ifndef CMSPAR
-#define	CMSPAR 010000000000
-#endif
 	if (!(cflag & PARODD)) {
 		cval |= UART_LCR_EPAR;
 	}
@@ -2807,7 +2804,7 @@
  * friends of mxser_ioctl()
  * ------------------------------------------------------------
  */
-static int mxser_get_serial_info(struct mxser_struct *info, struct serial_struct *retinfo)
+static int mxser_get_serial_info(struct mxser_struct *info, struct serial_struct __user *retinfo)
 {
 	struct serial_struct tmp;
 
@@ -2829,7 +2826,7 @@
 	return (0);
 }
 
-static int mxser_set_serial_info(struct mxser_struct *info, struct serial_struct *new_info)
+static int mxser_set_serial_info(struct mxser_struct *info, struct serial_struct __user *new_info)
 {
 	struct serial_struct new_serial;
 	unsigned int flags;
@@ -2869,7 +2866,7 @@
 	/* */
 	if (info->flags & ASYNC_INITIALIZED) {
 		if (flags != (info->flags & ASYNC_SPD_MASK)) {
-			mxser_change_speed(info, 0);
+			mxser_change_speed(info, NULL);
 		}
 	} else {
 		retval = mxser_startup(info);
@@ -2887,7 +2884,7 @@
  *	    transmit holding register is empty.  This functionality
  *	    allows an RS485 driver to be written in user space.
  */
-static int mxser_get_lsr_info(struct mxser_struct *info, unsigned int *value)
+static int mxser_get_lsr_info(struct mxser_struct *info, unsigned int __user *value)
 {
 	unsigned char status;
 	unsigned int result;
diff -Nru a/drivers/char/n_hdlc.c b/drivers/char/n_hdlc.c
--- a/drivers/char/n_hdlc.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/char/n_hdlc.c	2005-03-01 23:38:54 -08:00
@@ -177,7 +177,7 @@
 static int debuglevel;
 
 /* max frame size for memory allocations */
-static ssize_t maxframe = 4096;
+static int maxframe = 4096;
 
 /* TTY callbacks */
 
@@ -672,7 +672,7 @@
 		if (debuglevel & DEBUG_LEVEL_INFO)
 			printk (KERN_WARNING
 				"n_hdlc_tty_write: truncating user packet "
-				"from %lu to %Zd\n", (unsigned long) count,
+				"from %lu to %d\n", (unsigned long) count,
 				maxframe );
 		count = maxframe;
 	}
@@ -975,6 +975,6 @@
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Paul Fulghum paulkf@microgate.com");
-MODULE_PARM(debuglevel, "i");
-MODULE_PARM(maxframe, "i");
+module_param(debuglevel, int, 0);
+module_param(maxframe, int, 0);
 MODULE_ALIAS_LDISC(N_HDLC);
diff -Nru a/drivers/char/n_tty.c b/drivers/char/n_tty.c
--- a/drivers/char/n_tty.c	2005-03-01 23:38:51 -08:00
+++ b/drivers/char/n_tty.c	2005-03-01 23:38:51 -08:00
@@ -152,7 +152,7 @@
  *	lock_kernel() still.
  */
  
-void n_tty_flush_buffer(struct tty_struct * tty)
+static void n_tty_flush_buffer(struct tty_struct * tty)
 {
 	/* clear everything and unthrottle the driver */
 	reset_buffer_flags(tty);
@@ -174,7 +174,7 @@
  *	at this instant in time. 
  */
  
-ssize_t n_tty_chars_in_buffer(struct tty_struct *tty)
+static ssize_t n_tty_chars_in_buffer(struct tty_struct *tty)
 {
 	unsigned long flags;
 	ssize_t n = 0;
@@ -317,8 +317,6 @@
 		return 0;
 	if (nr > space)
 		nr = space;
-	if (nr > sizeof(buf))
-	    nr = sizeof(buf);
 
 	for (i = 0, cp = buf; i < nr; i++, cp++) {
 		switch (*cp) {
@@ -1143,13 +1141,13 @@
 
 {
 	int retval;
-	ssize_t n;
+	size_t n;
 	unsigned long flags;
 
 	retval = 0;
 	spin_lock_irqsave(&tty->read_lock, flags);
 	n = min(tty->read_cnt, N_TTY_BUF_SIZE - tty->read_tail);
-	n = min((ssize_t)*nr, n);
+	n = min(*nr, n);
 	spin_unlock_irqrestore(&tty->read_lock, flags);
 	if (n) {
 		mb();
diff -Nru a/drivers/char/nvram.c b/drivers/char/nvram.c
--- a/drivers/char/nvram.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/char/nvram.c	2005-03-01 23:38:55 -08:00
@@ -133,7 +133,7 @@
 #include <asm/uaccess.h>
 #include <asm/system.h>
 
-static spinlock_t nvram_state_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(nvram_state_lock);
 static int nvram_open_cnt;	/* #times opened */
 static int nvram_open_mode;	/* special open modes */
 #define NVRAM_WRITE		1 /* opened for writing (exclusive) */
diff -Nru a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
--- a/drivers/char/pcmcia/synclink_cs.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/char/pcmcia/synclink_cs.c	2005-03-01 23:38:55 -08:00
@@ -464,21 +464,11 @@
 static int maxframe[MAX_DEVICE_COUNT] = {0,};
 static int dosyncppp[MAX_DEVICE_COUNT] = {1,1,1,1};
 
-/* The old way: bit map of interrupts to choose from */
-/* This means pick from 15, 14, 12, 11, 10, 9, 7, 5, 4, and 3 */
-static u_int irq_mask = 0xdeb8;
-
-/* Newer, simpler way of listing specific interrupts */
-static int irq_list[4] = { -1 };
-
-MODULE_PARM(irq_mask, "i");
-MODULE_PARM(irq_list, "1-4i");
-
-MODULE_PARM(break_on_load,"i");
-MODULE_PARM(ttymajor,"i");
-MODULE_PARM(debug_level,"i");
-MODULE_PARM(maxframe,"1-" __MODULE_STRING(MAX_DEVICE_COUNT) "i");
-MODULE_PARM(dosyncppp,"1-" __MODULE_STRING(MAX_DEVICE_COUNT) "i");
+module_param(break_on_load, bool, 0);
+module_param(ttymajor, int, 0);
+module_param(debug_level, int, 0);
+module_param_array(maxframe, int, NULL, 0);
+module_param_array(dosyncppp, int, NULL, 0);
 
 MODULE_LICENSE("GPL");
 
@@ -555,7 +545,7 @@
     MGSLPC_INFO *info;
     dev_link_t *link;
     client_reg_t client_reg;
-    int ret, i;
+    int ret;
     
     if (debug_level >= DEBUG_LEVEL_INFO)
 	    printk("mgslpc_attach\n");
@@ -592,11 +582,6 @@
     /* Interrupt setup */
     link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
     link->irq.IRQInfo1   = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
-    if (irq_list[0] == -1)
-	    link->irq.IRQInfo2 = irq_mask;
-    else
-	    for (i = 0; i < 4; i++)
-		    link->irq.IRQInfo2 |= 1 << irq_list[i];
     link->irq.Handler = NULL;
     
     link->conf.Attributes = 0;
@@ -608,7 +593,6 @@
     dev_list = link;
 
     client_reg.dev_info = &dev_info;
-    client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
     client_reg.EventMask =
 	    CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
 	    CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
@@ -923,7 +907,7 @@
 /* Return next bottom half action to perform.
  * or 0 if nothing to do.
  */
-int bh_action(MGSLPC_INFO *info)
+static int bh_action(MGSLPC_INFO *info)
 {
 	unsigned long flags;
 	int rc = 0;
@@ -1017,7 +1001,7 @@
 }
 
 /* eom: non-zero = end of frame */ 
-void rx_ready_hdlc(MGSLPC_INFO *info, int eom) 
+static void rx_ready_hdlc(MGSLPC_INFO *info, int eom)
 {
 	unsigned char data[2];
 	unsigned char fifo_count, read_count, i;
@@ -1079,7 +1063,7 @@
 	issue_command(info, CHA, CMD_RXFIFO);
 }
 
-void rx_ready_async(MGSLPC_INFO *info, int tcd) 
+static void rx_ready_async(MGSLPC_INFO *info, int tcd)
 {
 	unsigned char data, status;
 	int fifo_count;
@@ -1153,7 +1137,7 @@
 }
 
 
-void tx_done(MGSLPC_INFO *info) 
+static void tx_done(MGSLPC_INFO *info)
 {
 	if (!info->tx_active)
 		return;
@@ -1190,7 +1174,7 @@
 	}
 }
 
-void tx_ready(MGSLPC_INFO *info) 
+static void tx_ready(MGSLPC_INFO *info)
 {
 	unsigned char fifo_count = 32;
 	int c;
@@ -1239,7 +1223,7 @@
 	}
 }
 
-void cts_change(MGSLPC_INFO *info) 
+static void cts_change(MGSLPC_INFO *info)
 {
 	get_signals(info);
 	if ((info->cts_chkcount)++ >= IO_PIN_SHUTDOWN_LIMIT)
@@ -1276,7 +1260,7 @@
 	info->pending_bh |= BH_STATUS;
 }
 
-void dcd_change(MGSLPC_INFO *info) 
+static void dcd_change(MGSLPC_INFO *info)
 {
 	get_signals(info);
 	if ((info->dcd_chkcount)++ >= IO_PIN_SHUTDOWN_LIMIT)
@@ -1310,7 +1294,7 @@
 	info->pending_bh |= BH_STATUS;
 }
 
-void dsr_change(MGSLPC_INFO *info) 
+static void dsr_change(MGSLPC_INFO *info)
 {
 	get_signals(info);
 	if ((info->dsr_chkcount)++ >= IO_PIN_SHUTDOWN_LIMIT)
@@ -1325,7 +1309,7 @@
 	info->pending_bh |= BH_STATUS;
 }
 
-void ri_change(MGSLPC_INFO *info) 
+static void ri_change(MGSLPC_INFO *info)
 {
 	get_signals(info);
 	if ((info->ri_chkcount)++ >= IO_PIN_SHUTDOWN_LIMIT)
@@ -2955,7 +2939,7 @@
 
 /* Called to print information about devices
  */
-int mgslpc_read_proc(char *page, char **start, off_t off, int count,
+static int mgslpc_read_proc(char *page, char **start, off_t off, int count,
 		 int *eof, void *data)
 {
 	int len = 0, l;
@@ -3147,13 +3131,7 @@
 	}
 
 	pcmcia_unregister_driver(&mgslpc_driver);
-
-	/* XXX: this really needs to move into generic code.. */
-	while (dev_list != NULL) {
-		if (dev_list->state & DEV_CONFIG)
-			mgslpc_release((u_long)dev_list);
-		mgslpc_detach(dev_list);
-	}
+	BUG_ON(dev_list != NULL);
 }
 
 static int __init synclink_cs_init(void)
@@ -3218,7 +3196,7 @@
 module_init(synclink_cs_init);
 module_exit(synclink_cs_exit);
 
-void mgslpc_set_rate(MGSLPC_INFO *info, unsigned char channel, unsigned int rate) 
+static void mgslpc_set_rate(MGSLPC_INFO *info, unsigned char channel, unsigned int rate)
 {
 	unsigned int M, N;
 	unsigned char val;
@@ -3254,7 +3232,7 @@
 
 /* Enabled the AUX clock output at the specified frequency.
  */
-void enable_auxclk(MGSLPC_INFO *info)
+static void enable_auxclk(MGSLPC_INFO *info)
 {
 	unsigned char val;
 	
diff -Nru a/drivers/char/pty.c b/drivers/char/pty.c
--- a/drivers/char/pty.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/char/pty.c	2005-03-01 23:38:54 -08:00
@@ -35,7 +35,7 @@
 /* These are global because they are accessed in tty_io.c */
 #ifdef CONFIG_UNIX98_PTYS
 struct tty_driver *ptm_driver;
-struct tty_driver *pts_driver;
+static struct tty_driver *pts_driver;
 #endif
 
 static void pty_close(struct tty_struct * tty, struct file * filp)
@@ -149,13 +149,15 @@
 static int pty_chars_in_buffer(struct tty_struct *tty)
 {
 	struct tty_struct *to = tty->link;
+	ssize_t (*chars_in_buffer)(struct tty_struct *);
 	int count;
 
-	if (!to || !to->ldisc.chars_in_buffer)
+	/* We should get the line discipline lock for "tty->link" */
+	if (!to || !(chars_in_buffer = to->ldisc.chars_in_buffer))
 		return 0;
 
 	/* The ldisc must report 0 if no characters available to be read */
-	count = to->ldisc.chars_in_buffer(to);
+	count = chars_in_buffer(to);
 
 	if (tty->driver->subtype == PTY_TYPE_SLAVE) return count;
 
diff -Nru a/drivers/char/qtronix.c b/drivers/char/qtronix.c
--- a/drivers/char/qtronix.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/char/qtronix.c	2005-03-01 23:39:18 -08:00
@@ -69,7 +69,6 @@
 #include <linux/init.h>
 #include <linux/kbd_ll.h>
 #include <linux/delay.h>
-#include <linux/random.h>
 #include <linux/poll.h>
 #include <linux/miscdevice.h>
 #include <linux/slab.h>
@@ -350,7 +349,7 @@
 }
 
 
-spinlock_t kbd_controller_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(kbd_controller_lock);
 static unsigned char handle_kbd_event(void);
 
 
@@ -442,7 +441,6 @@
 		return;
 	}
 
-	add_mouse_randomness(scancode);
 	if (aux_count) {
 		int head = queue->head;
 
@@ -537,7 +535,8 @@
 		i--;
 	}
 	if (count-i) {
-		file->f_dentry->d_inode->i_atime = CURRENT_TIME;
+		struct inode *inode = file->f_dentry->d_inode;
+		inode->i_atime = current_fs_time(inode->i_sb);
 		return count-i;
 	}
 	if (signal_pending(current))
diff -Nru a/drivers/char/random.c b/drivers/char/random.c
--- a/drivers/char/random.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/char/random.c	2005-03-01 23:38:52 -08:00
@@ -2,7 +2,7 @@
  * random.c -- A strong random number generator
  *
  * Version 1.89, last modified 19-Sep-99
- * 
+ *
  * Copyright Theodore Ts'o, 1994, 1995, 1996, 1997, 1998, 1999.  All
  * rights reserved.
  *
@@ -18,13 +18,13 @@
  * 3. The name of the author may not be used to endorse or promote
  *    products derived from this software without specific prior
  *    written permission.
- * 
+ *
  * ALTERNATIVELY, this product may be distributed under the terms of
  * the GNU General Public License, in which case the provisions of the GPL are
  * required INSTEAD OF the above restrictions.  (This clause is
  * necessary due to a potential bad interaction between the GPL and
  * the restrictions contained in a BSD-style copyright.)
- * 
+ *
  * 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, ALL OF
@@ -40,8 +40,8 @@
  */
 
 /*
- * (now, with legal B.S. out of the way.....) 
- * 
+ * (now, with legal B.S. out of the way.....)
+ *
  * This routine gathers environmental noise from device drivers, etc.,
  * and returns good random numbers, suitable for cryptographic use.
  * Besides the obvious cryptographic uses, these numbers are also good
@@ -51,7 +51,7 @@
  *
  * Theory of operation
  * ===================
- * 
+ *
  * Computers are very predictable devices.  Hence it is extremely hard
  * to produce truly random numbers on a computer --- as opposed to
  * pseudo-random numbers, which can easily generated by using a
@@ -62,7 +62,7 @@
  * must be hard for outside attackers to observe, and use that to
  * generate random numbers.  In a Unix environment, this is best done
  * from inside the kernel.
- * 
+ *
  * Sources of randomness from the environment include inter-keyboard
  * timings, inter-interrupt timings from some interrupts, and other
  * events which are both (a) non-deterministic and (b) hard for an
@@ -74,7 +74,7 @@
  * As random bytes are mixed into the entropy pool, the routines keep
  * an *estimate* of how many bits of randomness have been stored into
  * the random number generator's internal state.
- * 
+ *
  * When random bytes are desired, they are obtained by taking the SHA
  * hash of the contents of the "entropy pool".  The SHA hash avoids
  * exposing the internal state of the entropy pool.  It is believed to
@@ -86,7 +86,7 @@
  * reason, the routine decreases its internal estimate of how many
  * bits of "true randomness" are contained in the entropy pool as it
  * outputs random numbers.
- * 
+ *
  * If this estimate goes to zero, the routine can still generate
  * random numbers; however, an attacker may (at least in theory) be
  * able to infer the future output of the generator from prior
@@ -94,10 +94,10 @@
  * not believed to be feasible, but there is a remote possibility.
  * Nonetheless, these numbers should be useful for the vast majority
  * of purposes.
- * 
+ *
  * Exported interfaces ---- output
  * ===============================
- * 
+ *
  * There are three exported interfaces; the first is one designed to
  * be used from within the kernel:
  *
@@ -105,14 +105,14 @@
  *
  * This interface will return the requested number of random bytes,
  * and place it in the requested buffer.
- * 
+ *
  * The two other interfaces are two character devices /dev/random and
  * /dev/urandom.  /dev/random is suitable for use when very high
  * quality randomness is desired (for example, for key generation or
  * one-time pads), as it will only return a maximum of the number of
  * bits of randomness (as estimated by the random number generator)
  * contained in the entropy pool.
- * 
+ *
  * The /dev/urandom device does not have this limit, and will return
  * as many bytes as are requested.  As more and more random bytes are
  * requested without giving time for the entropy pool to recharge,
@@ -121,19 +121,16 @@
  *
  * Exported interfaces ---- input
  * ==============================
- * 
+ *
  * The current exported interfaces for gathering environmental noise
  * from the devices are:
- * 
- * 	void add_keyboard_randomness(unsigned char scancode);
- * 	void add_mouse_randomness(__u32 mouse_data);
+ *
+ * 	void add_input_randomness(unsigned int type, unsigned int code,
+ *                                unsigned int value);
  * 	void add_interrupt_randomness(int irq);
- * 
- * add_keyboard_randomness() uses the inter-keypress timing, as well as the
- * scancode as random inputs into the "entropy pool".
- * 
- * add_mouse_randomness() uses the mouse interrupt timing, as well as
- * the reported position of the mouse from the hardware.
+ *
+ * add_input_randomness() uses the input layer interrupt timing, as well as
+ * the event type information from the hardware.
  *
  * add_interrupt_randomness() uses the inter-interrupt timing as random
  * inputs to the entropy pool.  Note that not all interrupts are good
@@ -142,14 +139,14 @@
  * regular, and hence predictable to an attacker.  Disk interrupts are
  * a better measure, since the timing of the disk interrupts are more
  * unpredictable.
- * 
+ *
  * All of these routines try to estimate how many bits of randomness a
  * particular randomness source.  They do this by keeping track of the
  * first and second order deltas of the event timings.
  *
  * Ensuring unpredictability at system startup
  * ============================================
- * 
+ *
  * When any operating system starts up, it will go through a sequence
  * of actions that are fairly predictable by an adversary, especially
  * if the start-up does not involve interaction with a human operator.
@@ -158,7 +155,7 @@
  * counteract this effect, it helps to carry information in the
  * entropy pool across shut-downs and start-ups.  To do this, put the
  * following lines an appropriate script which is run during the boot
- * sequence: 
+ * sequence:
  *
  *	echo "Initializing random number generator..."
  *	random_seed=/var/run/random-seed
@@ -170,9 +167,7 @@
  *		touch $random_seed
  *	fi
  *	chmod 600 $random_seed
- *	poolfile=/proc/sys/kernel/random/poolsize
- *	[ -r $poolfile ] && bytes=`cat $poolfile` || bytes=512
- *	dd if=/dev/urandom of=$random_seed count=1 bs=$bytes
+ *	dd if=/dev/urandom of=$random_seed count=1 bs=512
  *
  * and the following lines in an appropriate script which is run as
  * the system is shutdown:
@@ -183,15 +178,13 @@
  *	random_seed=/var/run/random-seed
  *	touch $random_seed
  *	chmod 600 $random_seed
- *	poolfile=/proc/sys/kernel/random/poolsize
- *	[ -r $poolfile ] && bytes=`cat $poolfile` || bytes=512
- *	dd if=/dev/urandom of=$random_seed count=1 bs=$bytes
+ *	dd if=/dev/urandom of=$random_seed count=1 bs=512
  *
  * For example, on most modern systems using the System V init
  * scripts, such code fragments would be found in
  * /etc/rc.d/init.d/random.  On older Linux systems, the correct script
  * location might be in /etc/rcb.d/rc.local or /etc/rc.d/rc.0.
- * 
+ *
  * Effectively, these commands cause the contents of the entropy pool
  * to be saved at shut-down time and reloaded into the entropy pool at
  * start-up.  (The 'dd' in the addition to the bootup script is to
@@ -211,7 +204,7 @@
  *
  * 	mknod /dev/random c 1 8
  * 	mknod /dev/urandom c 1 9
- * 
+ *
  * Acknowledgements:
  * =================
  *
@@ -221,17 +214,17 @@
  * number generator, which speed up the mixing function of the entropy
  * pool, taken from PGPfone.  Dale Worley has also contributed many
  * useful ideas and suggestions to improve this driver.
- * 
+ *
  * Any flaws in the design are solely my responsibility, and should
  * not be attributed to the Phil, Colin, or any of authors of PGP.
- * 
+ *
  * The code for SHA transform was taken from Peter Gutmann's
  * implementation, which has been placed in the public domain.
  * The code for MD5 transform was taken from Colin Plumb's
  * implementation, which has been placed in the public domain.
  * The MD5 cryptographic checksum was devised by Ronald Rivest, and is
  * documented in RFC 1321, "The MD5 Message Digest Algorithm".
- * 
+ *
  * Further background information on this topic may be obtained from
  * RFC 1750, "Randomness Recommendations for Security", by Donald
  * Eastlake, Steve Crocker, and Jeff Schiller.
@@ -299,8 +292,8 @@
  * get the twisting happening as fast as possible.
  */
 static struct poolinfo {
-	int	poolwords;
-	int	tap1, tap2, tap3, tap4, tap5;
+	int poolwords;
+	int tap1, tap2, tap3, tap4, tap5;
 } poolinfo_table[] = {
 	/* x^2048 + x^1638 + x^1231 + x^819 + x^411 + x + 1  -- 115 */
 	{ 2048,	1638,	1231,	819,	411,	1 },
@@ -353,12 +346,12 @@
  * II.  ACM Transactions on Mdeling and Computer Simulation 4:254-266)
  *
  * Thanks to Colin Plumb for suggesting this.
- * 
+ *
  * We have not analyzed the resultant polynomial to prove it primitive;
  * in fact it almost certainly isn't.  Nonetheless, the irreducible factors
  * of a random large-degree polynomial over GF(2) are more than large enough
  * that periodicity is not a concern.
- * 
+ *
  * The input hash is much less sensitive than the output hash.  All
  * that we want of it is that it be a good non-cryptographic hash;
  * i.e. it not produce collisions when fed "random" data of the sort
@@ -390,7 +383,7 @@
  * Linux 2.2 compatibility
  */
 #ifndef DECLARE_WAITQUEUE
-#define DECLARE_WAITQUEUE(WAIT, PTR)	struct wait_queue WAIT = { PTR, NULL }
+#define DECLARE_WAITQUEUE(WAIT, PTR) struct wait_queue WAIT = { PTR, NULL }
 #endif
 #ifndef DECLARE_WAIT_QUEUE_HEAD
 #define DECLARE_WAIT_QUEUE_HEAD(WAIT) struct wait_queue *WAIT
@@ -416,7 +409,7 @@
  *
  * Utility functions, with some ASM defined functions for speed
  * purposes
- * 
+ *
  *****************************************************************/
 
 /*
@@ -428,7 +421,6 @@
 static inline __u32 rotate_left(int i, __u32 word)
 {
 	return (word << i) | (word >> (32 - i));
-	
 }
 #else
 static inline __u32 rotate_left(int i, __u32 word)
@@ -442,9 +434,9 @@
 
 /*
  * More asm magic....
- * 
+ *
  * For entropy estimation, we need to do an integral base 2
- * logarithm.  
+ * logarithm.
  *
  * Note the "12bits" suffix - this is used for numbers between
  * 0 and 4095 only.  This allows a few shortcuts.
@@ -453,7 +445,7 @@
 static inline __u32 int_ln_12bits(__u32 word)
 {
 	__u32 nbits = 0;
-	
+
 	while (word >>= 1)
 		nbits++;
 	return nbits;
@@ -478,7 +470,15 @@
 #endif
 
 #if 0
-#define DEBUG_ENT(fmt, arg...) printk(KERN_DEBUG "random: " fmt, ## arg)
+static int debug = 0;
+module_param(debug, bool, 0644);
+#define DEBUG_ENT(fmt, arg...) do { if (debug) \
+	printk(KERN_DEBUG "random %04d %04d %04d: " \
+	fmt,\
+	random_state->entropy_count,\
+	sec_random_state->entropy_count,\
+	urandom_state->entropy_count,\
+	## arg); } while (0)
 #else
 #define DEBUG_ENT(fmt, arg...) do {} while (0)
 #endif
@@ -487,20 +487,20 @@
  *
  * OS independent entropy store.   Here are the functions which handle
  * storing entropy in an entropy pool.
- * 
+ *
  **********************************************************************/
 
 struct entropy_store {
 	/* mostly-read data: */
 	struct poolinfo poolinfo;
-	__u32		*pool;
-	const char	*name;
+	__u32 *pool;
+	const char *name;
 
 	/* read-write data: */
 	spinlock_t lock ____cacheline_aligned_in_smp;
-	unsigned	add_ptr;
-	int		entropy_count;
-	int		input_rotate;
+	unsigned add_ptr;
+	int entropy_count;
+	int input_rotate;
 };
 
 /*
@@ -512,9 +512,9 @@
 static int create_entropy_store(int size, const char *name,
 				struct entropy_store **ret_bucket)
 {
-	struct	entropy_store	*r;
-	struct	poolinfo	*p;
-	int	poolwords;
+	struct entropy_store *r;
+	struct poolinfo *p;
+	int poolwords;
 
 	poolwords = (size + 3) / 4; /* Convert bytes->words */
 	/* The pool size must be a multiple of 16 32-bit words */
@@ -540,7 +540,7 @@
 		return -ENOMEM;
 	}
 	memset(r->pool, 0, POOLBYTES);
-	r->lock = SPIN_LOCK_UNLOCKED;
+	spin_lock_init(&r->lock);
 	r->name = name;
 	*ret_bucket = r;
 	return 0;
@@ -554,19 +554,12 @@
 	r->input_rotate = 0;
 	memset(r->pool, 0, r->poolinfo.POOLBYTES);
 }
-#ifdef CONFIG_SYSCTL
-static void free_entropy_store(struct entropy_store *r)
-{
-	if (r->pool)
-		kfree(r->pool);
-	kfree(r);
-}
-#endif
+
 /*
  * This function adds a byte into the entropy "pool".  It does not
  * update the entropy estimate.  The caller should call
  * credit_entropy_store if this is appropriate.
- * 
+ *
  * The pool is stirred with a primitive polynomial of the appropriate
  * degree, and then twisted.  We twist by three bits at a time because
  * it's cheap to do so and helps slightly in the expected case where
@@ -576,7 +569,7 @@
 				int nwords, __u32 out[16])
 {
 	static __u32 const twist_table[8] = {
-		         0, 0x3b6e20c8, 0x76dc4190, 0x4db26158,
+		0x00000000, 0x3b6e20c8, 0x76dc4190, 0x4db26158,
 		0xedb88320, 0xd6d6a3e8, 0x9b64c2b0, 0xa00ae278 };
 	unsigned long i, add_ptr, tap1, tap2, tap3, tap4, tap5;
 	int new_rotate, input_rotate;
@@ -642,7 +635,6 @@
 	__add_entropy_words(r, in, nwords, NULL);
 }
 
-
 /*
  * Credit (or debit) the entropy store with n bits of entropy
  */
@@ -661,8 +653,8 @@
 	} else {
 		r->entropy_count += nbits;
 		if (nbits)
-			DEBUG_ENT("Added %d entropy credits to %s, now %d\n",
-				  nbits, r->name, r->entropy_count);
+			DEBUG_ENT("added %d entropy credits to %s\n",
+				  nbits, r->name);
 	}
 
 	spin_unlock_irqrestore(&r->lock, flags);
@@ -682,10 +674,10 @@
 };
 
 static struct sample *batch_entropy_pool, *batch_entropy_copy;
-static int	batch_head, batch_tail;
-static spinlock_t batch_lock = SPIN_LOCK_UNLOCKED;
+static int batch_head, batch_tail;
+static DEFINE_SPINLOCK(batch_lock);
 
-static int	batch_max;
+static int batch_max;
 static void batch_entropy_process(void *private_);
 static DECLARE_WORK(batch_work, batch_entropy_process, NULL);
 
@@ -726,19 +718,14 @@
 	batch_entropy_pool[batch_head].data[1] = b;
 	batch_entropy_pool[batch_head].credit = num;
 
-	if (((batch_head - batch_tail) & (batch_max-1)) >= (batch_max / 2)) {
-		/*
-		 * Schedule it for the next timer tick:
-		 */
+	if (((batch_head - batch_tail) & (batch_max - 1)) >= (batch_max / 2))
 		schedule_delayed_work(&batch_work, 1);
-	}
 
-	new = (batch_head+1) & (batch_max-1);
-	if (new == batch_tail) {
+	new = (batch_head + 1) & (batch_max - 1);
+	if (new == batch_tail)
 		DEBUG_ENT("batch entropy buffer full\n");
-	} else {
+	else
 		batch_head = new;
-	}
 
 	spin_unlock_irqrestore(&batch_lock, flags);
 }
@@ -762,7 +749,7 @@
 	spin_lock_irq(&batch_lock);
 
 	memcpy(batch_entropy_copy, batch_entropy_pool,
-	       batch_max*sizeof(struct sample));
+	       batch_max * sizeof(struct sample));
 
 	head = batch_head;
 	tail = batch_tail;
@@ -773,13 +760,13 @@
 	p = r;
 	while (head != tail) {
 		if (r->entropy_count >= max_entropy) {
-			r = (r == sec_random_state) ?	random_state :
-							sec_random_state;
+			r = (r == sec_random_state) ? random_state :
+				sec_random_state;
 			max_entropy = r->poolinfo.POOLBITS;
 		}
 		add_entropy_words(r, batch_entropy_copy[tail].data, 2);
 		credit_entropy_store(r, batch_entropy_copy[tail].credit);
-		tail = (tail+1) & (batch_max-1);
+		tail = (tail + 1) & (batch_max - 1);
 	}
 	if (p->entropy_count >= random_read_wakeup_thresh)
 		wake_up_interruptible(&random_read_wait);
@@ -793,13 +780,12 @@
 
 /* There is one of these per entropy source */
 struct timer_rand_state {
-	cycles_t	last_time;
-	long		last_delta,last_delta2;
-	unsigned	dont_count_entropy:1;
+	cycles_t last_time;
+	long last_delta,last_delta2;
+	unsigned dont_count_entropy:1;
 };
 
-static struct timer_rand_state keyboard_timer_state;
-static struct timer_rand_state mouse_timer_state;
+static struct timer_rand_state input_timer_state;
 static struct timer_rand_state extract_timer_state;
 static struct timer_rand_state *irq_timer_state[NR_IRQS];
 
@@ -815,31 +801,23 @@
  */
 static void add_timer_randomness(struct timer_rand_state *state, unsigned num)
 {
-	cycles_t	time;
-	long		delta, delta2, delta3;
-	int		entropy = 0;
+	cycles_t data;
+	long delta, delta2, delta3, time;
+	int entropy = 0;
 
 	preempt_disable();
 	/* if over the trickle threshold, use only 1 in 4096 samples */
-	if ( random_state->entropy_count > trickle_thresh &&
-	     (__get_cpu_var(trickle_count)++ & 0xfff))
+	if (random_state->entropy_count > trickle_thresh &&
+	    (__get_cpu_var(trickle_count)++ & 0xfff))
 		goto out;
 
 	/*
-	 * Use get_cycles() if implemented, otherwise fall back to
-	 * jiffies.
-	 */
-	time = get_cycles();
-	if (time)
-		num ^= (u32)((time >> 31) >> 1);
-	else
-		time = jiffies;
-
-	/*
 	 * Calculate number of bits of randomness we probably added.
 	 * We take into account the first, second and third-order deltas
 	 * in order to make our estimate.
 	 */
+	time = jiffies;
+
 	if (!state->dont_count_entropy) {
 		delta = time - state->last_time;
 		state->last_time = time;
@@ -871,34 +849,44 @@
 
 		entropy = int_ln_12bits(delta);
 	}
-	batch_entropy_store(num, time, entropy);
+
+	/*
+	 * Use get_cycles() if implemented, otherwise fall back to
+	 * jiffies.
+	 */
+	data = get_cycles();
+	if (data)
+		num ^= (u32)((data >> 31) >> 1);
+	else
+		data = time;
+
+	batch_entropy_store(num, data, entropy);
 out:
 	preempt_enable();
 }
 
-void add_keyboard_randomness(unsigned char scancode)
+extern void add_input_randomness(unsigned int type, unsigned int code,
+				 unsigned int value)
 {
-	static unsigned char last_scancode;
-	/* ignore autorepeat (multiple key down w/o key up) */
-	if (scancode != last_scancode) {
-		last_scancode = scancode;
-		add_timer_randomness(&keyboard_timer_state, scancode);
-	}
-}
+	static unsigned char last_value;
 
-void add_mouse_randomness(__u32 mouse_data)
-{
-	add_timer_randomness(&mouse_timer_state, mouse_data);
-}
+	/* ignore autorepeat and the like */
+	if (value == last_value)
+		return;
 
-EXPORT_SYMBOL(add_mouse_randomness);
+	DEBUG_ENT("input event\n");
+	last_value = value;
+	add_timer_randomness(&input_timer_state,
+			     (type << 4) ^ code ^ (code >> 4) ^ value);
+}
 
 void add_interrupt_randomness(int irq)
 {
 	if (irq >= NR_IRQS || irq_timer_state[irq] == 0)
 		return;
 
-	add_timer_randomness(irq_timer_state[irq], 0x100+irq);
+	DEBUG_ENT("irq event %d\n", irq);
+	add_timer_randomness(irq_timer_state[irq], 0x100 + irq);
 }
 
 void add_disk_randomness(struct gendisk *disk)
@@ -906,7 +894,10 @@
 	if (!disk || !disk->random)
 		return;
 	/* first major is 1, so we get >= 0x200 here */
-	add_timer_randomness(disk->random, 0x100+MKDEV(disk->major, disk->first_minor));
+	DEBUG_ENT("disk event %d:%d\n", disk->major, disk->first_minor);
+
+	add_timer_randomness(disk->random,
+			     0x100 + MKDEV(disk->major, disk->first_minor));
 }
 
 EXPORT_SYMBOL(add_disk_randomness);
@@ -921,7 +912,7 @@
  * This chunk of code defines a function
  * void HASH_TRANSFORM(__u32 digest[HASH_BUFFER_SIZE + HASH_EXTRA_SIZE],
  * 		__u32 const data[16])
- * 
+ *
  * The function hashes the input data to produce a digest in the first
  * HASH_BUFFER_SIZE words of the digest[] array, and uses HASH_EXTRA_SIZE
  * more words for internal purposes.  (This buffer is exported so the
@@ -936,7 +927,7 @@
  * 3) 0x98badcfe
  * 4) 0x10325476
  * 5) 0xc3d2e1f0 (SHA only)
- * 
+ *
  * For /dev/random purposes, the length of the data being hashed is
  * fixed in length, so appending a bit count in the usual way is not
  * cryptographically necessary.
@@ -958,9 +949,9 @@
 
 /* The SHA f()-functions.  */
 
-#define f1(x,y,z)   ( z ^ (x & (y^z)) )		/* Rounds  0-19: x ? y : z */
+#define f1(x,y,z)   (z ^ (x & (y ^ z)))		/* Rounds  0-19: x ? y : z */
 #define f2(x,y,z)   (x ^ y ^ z)			/* Rounds 20-39: XOR */
-#define f3(x,y,z)   ( (x & y) + (z & (x ^ y)) )	/* Rounds 40-59: majority */
+#define f3(x,y,z)   ((x & y) + (z & (x ^ y)))	/* Rounds 40-59: majority */
 #define f4(x,y,z)   (x ^ y ^ z)			/* Rounds 60-79: XOR */
 
 /* The SHA Mysterious Constants */
@@ -970,199 +961,198 @@
 #define K3  0x8F1BBCDCL			/* Rounds 40-59: sqrt(5) * 2^30 */
 #define K4  0xCA62C1D6L			/* Rounds 60-79: sqrt(10) * 2^30 */
 
-#define ROTL(n,X)  ( ( ( X ) << n ) | ( ( X ) >> ( 32 - n ) ) )
+#define ROTL(n,X)  (((X) << n ) | ((X) >> (32 - n)))
 
 #define subRound(a, b, c, d, e, f, k, data) \
-    ( e += ROTL( 5, a ) + f( b, c, d ) + k + data, b = ROTL( 30, b ) )
-
+    (e += ROTL(5, a) + f(b, c, d) + k + data, b = ROTL(30, b))
 
 static void SHATransform(__u32 digest[85], __u32 const data[16])
 {
-    __u32 A, B, C, D, E;     /* Local vars */
-    __u32 TEMP;
-    int	i;
+	__u32 A, B, C, D, E;     /* Local vars */
+	__u32 TEMP;
+	int i;
 #define W (digest + HASH_BUFFER_SIZE)	/* Expanded data array */
 
-    /*
-     * Do the preliminary expansion of 16 to 80 words.  Doing it
-     * out-of-line line this is faster than doing it in-line on
-     * register-starved machines like the x86, and not really any
-     * slower on real processors.
-     */
-    memcpy(W, data, 16*sizeof(__u32));
-    for (i = 0; i < 64; i++) {
-	    TEMP = W[i] ^ W[i+2] ^ W[i+8] ^ W[i+13];
-	    W[i+16] = ROTL(1, TEMP);
-    }
-
-    /* Set up first buffer and local data buffer */
-    A = digest[ 0 ];
-    B = digest[ 1 ];
-    C = digest[ 2 ];
-    D = digest[ 3 ];
-    E = digest[ 4 ];
+	/*
+	 * Do the preliminary expansion of 16 to 80 words.  Doing it
+	 * out-of-line line this is faster than doing it in-line on
+	 * register-starved machines like the x86, and not really any
+	 * slower on real processors.
+	 */
+	memcpy(W, data, 16*sizeof(__u32));
+	for (i = 0; i < 64; i++) {
+		TEMP = W[i] ^ W[i+2] ^ W[i+8] ^ W[i+13];
+		W[i+16] = ROTL(1, TEMP);
+	}
+
+	/* Set up first buffer and local data buffer */
+	A = digest[ 0 ];
+	B = digest[ 1 ];
+	C = digest[ 2 ];
+	D = digest[ 3 ];
+	E = digest[ 4 ];
 
-    /* Heavy mangling, in 4 sub-rounds of 20 iterations each. */
+	/* Heavy mangling, in 4 sub-rounds of 20 iterations each. */
 #if SHA_CODE_SIZE == 0
-    /*
-     * Approximately 50% of the speed of the largest version, but
-     * takes up 1/16 the space.  Saves about 6k on an i386 kernel.
-     */
-    for (i = 0; i < 80; i++) {
-	if (i < 40) {
-	    if (i < 20)
-		TEMP = f1(B, C, D) + K1;
-	    else
-		TEMP = f2(B, C, D) + K2;
-	} else {
-	    if (i < 60)
-		TEMP = f3(B, C, D) + K3;
-	    else
-		TEMP = f4(B, C, D) + K4;
-	}
-	TEMP += ROTL(5, A) + E + W[i];
-	E = D; D = C; C = ROTL(30, B); B = A; A = TEMP;
-    }
+	/*
+	 * Approximately 50% of the speed of the largest version, but
+	 * takes up 1/16 the space.  Saves about 6k on an i386 kernel.
+	 */
+	for (i = 0; i < 80; i++) {
+		if (i < 40) {
+			if (i < 20)
+				TEMP = f1(B, C, D) + K1;
+			else
+				TEMP = f2(B, C, D) + K2;
+		} else {
+			if (i < 60)
+				TEMP = f3(B, C, D) + K3;
+			else
+				TEMP = f4(B, C, D) + K4;
+		}
+		TEMP += ROTL(5, A) + E + W[i];
+		E = D; D = C; C = ROTL(30, B); B = A; A = TEMP;
+	}
 #elif SHA_CODE_SIZE == 1
-    for (i = 0; i < 20; i++) {
-	TEMP = f1(B, C, D) + K1 + ROTL(5, A) + E + W[i];
-	E = D; D = C; C = ROTL(30, B); B = A; A = TEMP;
-    }
-    for (; i < 40; i++) {
-	TEMP = f2(B, C, D) + K2 + ROTL(5, A) + E + W[i];
-	E = D; D = C; C = ROTL(30, B); B = A; A = TEMP;
-    }
-    for (; i < 60; i++) {
-	TEMP = f3(B, C, D) + K3 + ROTL(5, A) + E + W[i];
-	E = D; D = C; C = ROTL(30, B); B = A; A = TEMP;
-    }
-    for (; i < 80; i++) {
-	TEMP = f4(B, C, D) + K4 + ROTL(5, A) + E + W[i];
-	E = D; D = C; C = ROTL(30, B); B = A; A = TEMP;
-    }
+	for (i = 0; i < 20; i++) {
+		TEMP = f1(B, C, D) + K1 + ROTL(5, A) + E + W[i];
+		E = D; D = C; C = ROTL(30, B); B = A; A = TEMP;
+	}
+	for (; i < 40; i++) {
+		TEMP = f2(B, C, D) + K2 + ROTL(5, A) + E + W[i];
+		E = D; D = C; C = ROTL(30, B); B = A; A = TEMP;
+	}
+	for (; i < 60; i++) {
+		TEMP = f3(B, C, D) + K3 + ROTL(5, A) + E + W[i];
+		E = D; D = C; C = ROTL(30, B); B = A; A = TEMP;
+	}
+	for (; i < 80; i++) {
+		TEMP = f4(B, C, D) + K4 + ROTL(5, A) + E + W[i];
+		E = D; D = C; C = ROTL(30, B); B = A; A = TEMP;
+	}
 #elif SHA_CODE_SIZE == 2
-    for (i = 0; i < 20; i += 5) {
-	subRound( A, B, C, D, E, f1, K1, W[ i   ] );
-	subRound( E, A, B, C, D, f1, K1, W[ i+1 ] );
-	subRound( D, E, A, B, C, f1, K1, W[ i+2 ] );
-	subRound( C, D, E, A, B, f1, K1, W[ i+3 ] );
-	subRound( B, C, D, E, A, f1, K1, W[ i+4 ] );
-    }
-    for (; i < 40; i += 5) {
-	subRound( A, B, C, D, E, f2, K2, W[ i   ] );
-	subRound( E, A, B, C, D, f2, K2, W[ i+1 ] );
-	subRound( D, E, A, B, C, f2, K2, W[ i+2 ] );
-	subRound( C, D, E, A, B, f2, K2, W[ i+3 ] );
-	subRound( B, C, D, E, A, f2, K2, W[ i+4 ] );
-    }
-    for (; i < 60; i += 5) {
-	subRound( A, B, C, D, E, f3, K3, W[ i   ] );
-	subRound( E, A, B, C, D, f3, K3, W[ i+1 ] );
-	subRound( D, E, A, B, C, f3, K3, W[ i+2 ] );
-	subRound( C, D, E, A, B, f3, K3, W[ i+3 ] );
-	subRound( B, C, D, E, A, f3, K3, W[ i+4 ] );
-    }
-    for (; i < 80; i += 5) {
-	subRound( A, B, C, D, E, f4, K4, W[ i   ] );
-	subRound( E, A, B, C, D, f4, K4, W[ i+1 ] );
-	subRound( D, E, A, B, C, f4, K4, W[ i+2 ] );
-	subRound( C, D, E, A, B, f4, K4, W[ i+3 ] );
-	subRound( B, C, D, E, A, f4, K4, W[ i+4 ] );
-    }
+	for (i = 0; i < 20; i += 5) {
+		subRound(A, B, C, D, E, f1, K1, W[i  ]);
+		subRound(E, A, B, C, D, f1, K1, W[i+1]);
+		subRound(D, E, A, B, C, f1, K1, W[i+2]);
+		subRound(C, D, E, A, B, f1, K1, W[i+3]);
+		subRound(B, C, D, E, A, f1, K1, W[i+4]);
+	}
+	for (; i < 40; i += 5) {
+		subRound(A, B, C, D, E, f2, K2, W[i  ]);
+		subRound(E, A, B, C, D, f2, K2, W[i+1]);
+		subRound(D, E, A, B, C, f2, K2, W[i+2]);
+		subRound(C, D, E, A, B, f2, K2, W[i+3]);
+		subRound(B, C, D, E, A, f2, K2, W[i+4]);
+	}
+	for (; i < 60; i += 5) {
+		subRound(A, B, C, D, E, f3, K3, W[i  ]);
+		subRound(E, A, B, C, D, f3, K3, W[i+1]);
+		subRound(D, E, A, B, C, f3, K3, W[i+2]);
+		subRound(C, D, E, A, B, f3, K3, W[i+3]);
+		subRound(B, C, D, E, A, f3, K3, W[i+4]);
+	}
+	for (; i < 80; i += 5) {
+		subRound(A, B, C, D, E, f4, K4, W[i  ]);
+		subRound(E, A, B, C, D, f4, K4, W[i+1]);
+		subRound(D, E, A, B, C, f4, K4, W[i+2]);
+		subRound(C, D, E, A, B, f4, K4, W[i+3]);
+		subRound(B, C, D, E, A, f4, K4, W[i+4]);
+	}
 #elif SHA_CODE_SIZE == 3 /* Really large version */
-    subRound( A, B, C, D, E, f1, K1, W[  0 ] );
-    subRound( E, A, B, C, D, f1, K1, W[  1 ] );
-    subRound( D, E, A, B, C, f1, K1, W[  2 ] );
-    subRound( C, D, E, A, B, f1, K1, W[  3 ] );
-    subRound( B, C, D, E, A, f1, K1, W[  4 ] );
-    subRound( A, B, C, D, E, f1, K1, W[  5 ] );
-    subRound( E, A, B, C, D, f1, K1, W[  6 ] );
-    subRound( D, E, A, B, C, f1, K1, W[  7 ] );
-    subRound( C, D, E, A, B, f1, K1, W[  8 ] );
-    subRound( B, C, D, E, A, f1, K1, W[  9 ] );
-    subRound( A, B, C, D, E, f1, K1, W[ 10 ] );
-    subRound( E, A, B, C, D, f1, K1, W[ 11 ] );
-    subRound( D, E, A, B, C, f1, K1, W[ 12 ] );
-    subRound( C, D, E, A, B, f1, K1, W[ 13 ] );
-    subRound( B, C, D, E, A, f1, K1, W[ 14 ] );
-    subRound( A, B, C, D, E, f1, K1, W[ 15 ] );
-    subRound( E, A, B, C, D, f1, K1, W[ 16 ] );
-    subRound( D, E, A, B, C, f1, K1, W[ 17 ] );
-    subRound( C, D, E, A, B, f1, K1, W[ 18 ] );
-    subRound( B, C, D, E, A, f1, K1, W[ 19 ] );
-
-    subRound( A, B, C, D, E, f2, K2, W[ 20 ] );
-    subRound( E, A, B, C, D, f2, K2, W[ 21 ] );
-    subRound( D, E, A, B, C, f2, K2, W[ 22 ] );
-    subRound( C, D, E, A, B, f2, K2, W[ 23 ] );
-    subRound( B, C, D, E, A, f2, K2, W[ 24 ] );
-    subRound( A, B, C, D, E, f2, K2, W[ 25 ] );
-    subRound( E, A, B, C, D, f2, K2, W[ 26 ] );
-    subRound( D, E, A, B, C, f2, K2, W[ 27 ] );
-    subRound( C, D, E, A, B, f2, K2, W[ 28 ] );
-    subRound( B, C, D, E, A, f2, K2, W[ 29 ] );
-    subRound( A, B, C, D, E, f2, K2, W[ 30 ] );
-    subRound( E, A, B, C, D, f2, K2, W[ 31 ] );
-    subRound( D, E, A, B, C, f2, K2, W[ 32 ] );
-    subRound( C, D, E, A, B, f2, K2, W[ 33 ] );
-    subRound( B, C, D, E, A, f2, K2, W[ 34 ] );
-    subRound( A, B, C, D, E, f2, K2, W[ 35 ] );
-    subRound( E, A, B, C, D, f2, K2, W[ 36 ] );
-    subRound( D, E, A, B, C, f2, K2, W[ 37 ] );
-    subRound( C, D, E, A, B, f2, K2, W[ 38 ] );
-    subRound( B, C, D, E, A, f2, K2, W[ 39 ] );
-    
-    subRound( A, B, C, D, E, f3, K3, W[ 40 ] );
-    subRound( E, A, B, C, D, f3, K3, W[ 41 ] );
-    subRound( D, E, A, B, C, f3, K3, W[ 42 ] );
-    subRound( C, D, E, A, B, f3, K3, W[ 43 ] );
-    subRound( B, C, D, E, A, f3, K3, W[ 44 ] );
-    subRound( A, B, C, D, E, f3, K3, W[ 45 ] );
-    subRound( E, A, B, C, D, f3, K3, W[ 46 ] );
-    subRound( D, E, A, B, C, f3, K3, W[ 47 ] );
-    subRound( C, D, E, A, B, f3, K3, W[ 48 ] );
-    subRound( B, C, D, E, A, f3, K3, W[ 49 ] );
-    subRound( A, B, C, D, E, f3, K3, W[ 50 ] );
-    subRound( E, A, B, C, D, f3, K3, W[ 51 ] );
-    subRound( D, E, A, B, C, f3, K3, W[ 52 ] );
-    subRound( C, D, E, A, B, f3, K3, W[ 53 ] );
-    subRound( B, C, D, E, A, f3, K3, W[ 54 ] );
-    subRound( A, B, C, D, E, f3, K3, W[ 55 ] );
-    subRound( E, A, B, C, D, f3, K3, W[ 56 ] );
-    subRound( D, E, A, B, C, f3, K3, W[ 57 ] );
-    subRound( C, D, E, A, B, f3, K3, W[ 58 ] );
-    subRound( B, C, D, E, A, f3, K3, W[ 59 ] );
-
-    subRound( A, B, C, D, E, f4, K4, W[ 60 ] );
-    subRound( E, A, B, C, D, f4, K4, W[ 61 ] );
-    subRound( D, E, A, B, C, f4, K4, W[ 62 ] );
-    subRound( C, D, E, A, B, f4, K4, W[ 63 ] );
-    subRound( B, C, D, E, A, f4, K4, W[ 64 ] );
-    subRound( A, B, C, D, E, f4, K4, W[ 65 ] );
-    subRound( E, A, B, C, D, f4, K4, W[ 66 ] );
-    subRound( D, E, A, B, C, f4, K4, W[ 67 ] );
-    subRound( C, D, E, A, B, f4, K4, W[ 68 ] );
-    subRound( B, C, D, E, A, f4, K4, W[ 69 ] );
-    subRound( A, B, C, D, E, f4, K4, W[ 70 ] );
-    subRound( E, A, B, C, D, f4, K4, W[ 71 ] );
-    subRound( D, E, A, B, C, f4, K4, W[ 72 ] );
-    subRound( C, D, E, A, B, f4, K4, W[ 73 ] );
-    subRound( B, C, D, E, A, f4, K4, W[ 74 ] );
-    subRound( A, B, C, D, E, f4, K4, W[ 75 ] );
-    subRound( E, A, B, C, D, f4, K4, W[ 76 ] );
-    subRound( D, E, A, B, C, f4, K4, W[ 77 ] );
-    subRound( C, D, E, A, B, f4, K4, W[ 78 ] );
-    subRound( B, C, D, E, A, f4, K4, W[ 79 ] );
+	subRound(A, B, C, D, E, f1, K1, W[ 0]);
+	subRound(E, A, B, C, D, f1, K1, W[ 1]);
+	subRound(D, E, A, B, C, f1, K1, W[ 2]);
+	subRound(C, D, E, A, B, f1, K1, W[ 3]);
+	subRound(B, C, D, E, A, f1, K1, W[ 4]);
+	subRound(A, B, C, D, E, f1, K1, W[ 5]);
+	subRound(E, A, B, C, D, f1, K1, W[ 6]);
+	subRound(D, E, A, B, C, f1, K1, W[ 7]);
+	subRound(C, D, E, A, B, f1, K1, W[ 8]);
+	subRound(B, C, D, E, A, f1, K1, W[ 9]);
+	subRound(A, B, C, D, E, f1, K1, W[10]);
+	subRound(E, A, B, C, D, f1, K1, W[11]);
+	subRound(D, E, A, B, C, f1, K1, W[12]);
+	subRound(C, D, E, A, B, f1, K1, W[13]);
+	subRound(B, C, D, E, A, f1, K1, W[14]);
+	subRound(A, B, C, D, E, f1, K1, W[15]);
+	subRound(E, A, B, C, D, f1, K1, W[16]);
+	subRound(D, E, A, B, C, f1, K1, W[17]);
+	subRound(C, D, E, A, B, f1, K1, W[18]);
+	subRound(B, C, D, E, A, f1, K1, W[19]);
+
+	subRound(A, B, C, D, E, f2, K2, W[20]);
+	subRound(E, A, B, C, D, f2, K2, W[21]);
+	subRound(D, E, A, B, C, f2, K2, W[22]);
+	subRound(C, D, E, A, B, f2, K2, W[23]);
+	subRound(B, C, D, E, A, f2, K2, W[24]);
+	subRound(A, B, C, D, E, f2, K2, W[25]);
+	subRound(E, A, B, C, D, f2, K2, W[26]);
+	subRound(D, E, A, B, C, f2, K2, W[27]);
+	subRound(C, D, E, A, B, f2, K2, W[28]);
+	subRound(B, C, D, E, A, f2, K2, W[29]);
+	subRound(A, B, C, D, E, f2, K2, W[30]);
+	subRound(E, A, B, C, D, f2, K2, W[31]);
+	subRound(D, E, A, B, C, f2, K2, W[32]);
+	subRound(C, D, E, A, B, f2, K2, W[33]);
+	subRound(B, C, D, E, A, f2, K2, W[34]);
+	subRound(A, B, C, D, E, f2, K2, W[35]);
+	subRound(E, A, B, C, D, f2, K2, W[36]);
+	subRound(D, E, A, B, C, f2, K2, W[37]);
+	subRound(C, D, E, A, B, f2, K2, W[38]);
+	subRound(B, C, D, E, A, f2, K2, W[39]);
+
+	subRound(A, B, C, D, E, f3, K3, W[40]);
+	subRound(E, A, B, C, D, f3, K3, W[41]);
+	subRound(D, E, A, B, C, f3, K3, W[42]);
+	subRound(C, D, E, A, B, f3, K3, W[43]);
+	subRound(B, C, D, E, A, f3, K3, W[44]);
+	subRound(A, B, C, D, E, f3, K3, W[45]);
+	subRound(E, A, B, C, D, f3, K3, W[46]);
+	subRound(D, E, A, B, C, f3, K3, W[47]);
+	subRound(C, D, E, A, B, f3, K3, W[48]);
+	subRound(B, C, D, E, A, f3, K3, W[49]);
+	subRound(A, B, C, D, E, f3, K3, W[50]);
+	subRound(E, A, B, C, D, f3, K3, W[51]);
+	subRound(D, E, A, B, C, f3, K3, W[52]);
+	subRound(C, D, E, A, B, f3, K3, W[53]);
+	subRound(B, C, D, E, A, f3, K3, W[54]);
+	subRound(A, B, C, D, E, f3, K3, W[55]);
+	subRound(E, A, B, C, D, f3, K3, W[56]);
+	subRound(D, E, A, B, C, f3, K3, W[57]);
+	subRound(C, D, E, A, B, f3, K3, W[58]);
+	subRound(B, C, D, E, A, f3, K3, W[59]);
+
+	subRound(A, B, C, D, E, f4, K4, W[60]);
+	subRound(E, A, B, C, D, f4, K4, W[61]);
+	subRound(D, E, A, B, C, f4, K4, W[62]);
+	subRound(C, D, E, A, B, f4, K4, W[63]);
+	subRound(B, C, D, E, A, f4, K4, W[64]);
+	subRound(A, B, C, D, E, f4, K4, W[65]);
+	subRound(E, A, B, C, D, f4, K4, W[66]);
+	subRound(D, E, A, B, C, f4, K4, W[67]);
+	subRound(C, D, E, A, B, f4, K4, W[68]);
+	subRound(B, C, D, E, A, f4, K4, W[69]);
+	subRound(A, B, C, D, E, f4, K4, W[70]);
+	subRound(E, A, B, C, D, f4, K4, W[71]);
+	subRound(D, E, A, B, C, f4, K4, W[72]);
+	subRound(C, D, E, A, B, f4, K4, W[73]);
+	subRound(B, C, D, E, A, f4, K4, W[74]);
+	subRound(A, B, C, D, E, f4, K4, W[75]);
+	subRound(E, A, B, C, D, f4, K4, W[76]);
+	subRound(D, E, A, B, C, f4, K4, W[77]);
+	subRound(C, D, E, A, B, f4, K4, W[78]);
+	subRound(B, C, D, E, A, f4, K4, W[79]);
 #else
 #error Illegal SHA_CODE_SIZE
 #endif
 
-    /* Build message digest */
-    digest[ 0 ] += A;
-    digest[ 1 ] += B;
-    digest[ 2 ] += C;
-    digest[ 3 ] += D;
-    digest[ 4 ] += E;
+	/* Build message digest */
+	digest[0] += A;
+	digest[1] += B;
+	digest[2] += C;
+	digest[3] += D;
+	digest[4] += E;
 
 	/* W is wiped by the caller */
 #undef W
@@ -1173,18 +1163,18 @@
 #undef f2
 #undef f3
 #undef f4
-#undef K1	
+#undef K1
 #undef K2
-#undef K3	
-#undef K4	
+#undef K3
+#undef K4
 #undef subRound
-	
+
 #else /* !USE_SHA - Use MD5 */
 
 #define HASH_BUFFER_SIZE 4
 #define HASH_EXTRA_SIZE 0
 #define HASH_TRANSFORM MD5Transform
-	
+
 /*
  * MD5 transform algorithm, taken from code written by Colin Plumb,
  * and put into the public domain
@@ -1200,7 +1190,7 @@
 
 /* This is the central step in the MD5 algorithm. */
 #define MD5STEP(f, w, x, y, z, data, s) \
-	( w += f(x, y, z) + data,  w = w<<s | w>>(32-s),  w += x )
+	(w += f(x, y, z) + data,  w = w << s | w >> (32 - s),  w += x )
 
 /*
  * The core of the MD5 algorithm, this alters an existing MD5 hash to
@@ -1326,15 +1316,13 @@
 		int bytes = max_t(int, random_read_wakeup_thresh / 8,
 				min_t(int, nbytes, TMP_BUF_SIZE));
 
-		DEBUG_ENT("%04d %04d : going to reseed %s with %d bits "
+		DEBUG_ENT("going to reseed %s with %d bits "
 			  "(%d of %d requested)\n",
-			  random_state->entropy_count,
-			  sec_random_state->entropy_count,
 			  r->name, bytes * 8, nbytes * 8, r->entropy_count);
 
 		bytes=extract_entropy(random_state, tmp, bytes,
 				      EXTRACT_ENTROPY_LIMIT);
-		add_entropy_words(r, tmp, bytes);
+		add_entropy_words(r, tmp, (bytes + 3) / 4);
 		credit_entropy_store(r, bytes*8);
 	}
 }
@@ -1360,7 +1348,6 @@
 	__u32 x;
 	unsigned long cpuflags;
 
-
 	/* Redundant, but just in case... */
 	if (r->entropy_count > r->poolinfo.POOLBITS)
 		r->entropy_count = r->poolinfo.POOLBITS;
@@ -1371,9 +1358,7 @@
 	/* Hold lock while accounting */
 	spin_lock_irqsave(&r->lock, cpuflags);
 
-	DEBUG_ENT("%04d %04d : trying to extract %d bits from %s\n",
-		  random_state->entropy_count,
-		  sec_random_state->entropy_count,
+	DEBUG_ENT("trying to extract %d bits from %s\n",
 		  nbytes * 8, r->name);
 
 	if (flags & EXTRACT_ENTROPY_LIMIT && nbytes >= r->entropy_count / 8)
@@ -1387,7 +1372,7 @@
 	if (r->entropy_count < random_write_wakeup_thresh)
 		wake_up_interruptible(&random_write_wait);
 
-	DEBUG_ENT("Debiting %d entropy credits from %s%s\n",
+	DEBUG_ENT("debiting %d entropy credits from %s%s\n",
 		  nbytes * 8, r->name,
 		  flags & EXTRACT_ENTROPY_LIMIT ? "" : " (unlimited)");
 
@@ -1405,15 +1390,7 @@
 				break;
 			}
 
-			DEBUG_ENT("%04d %04d : extract feeling sleepy (%d bytes left)\n",
-				  random_state->entropy_count,
-				  sec_random_state->entropy_count, nbytes);
-
 			schedule();
-
-			DEBUG_ENT("%04d %04d : extract woke up\n",
-				  random_state->entropy_count,
-				  sec_random_state->entropy_count);
 		}
 
 		/* Hash the pool to get the output */
@@ -1456,7 +1433,7 @@
 		x ^= (x >> 16);		/* Fold it in half */
 		((__u16 *)tmp)[HASH_BUFFER_SIZE-1] = (__u16)x;
 #endif
-		
+
 		/* Copy data to destination buffer */
 		i = min(nbytes, HASH_BUFFER_SIZE*sizeof(__u32)/2);
 		if (flags & EXTRACT_ENTROPY_USER) {
@@ -1467,6 +1444,7 @@
 			}
 		} else
 			memcpy(buf, (__u8 const *)tmp, i);
+
 		nbytes -= i;
 		buf += i;
 		ret += i;
@@ -1474,7 +1452,7 @@
 
 	/* Wipe data just returned from memory */
 	memset(tmp, 0, sizeof(tmp));
-	
+
 	return ret;
 }
 
@@ -1517,10 +1495,10 @@
  */
 static void init_std_data(struct entropy_store *r)
 {
-	struct timeval 	tv;
-	__u32		words[2];
-	char 		*p;
-	int		i;
+	struct timeval tv;
+	__u32 words[2];
+	char *p;
+	int i;
 
 	do_gettimeofday(&tv);
 	words[0] = tv.tv_sec;
@@ -1564,8 +1542,7 @@
 #endif
 	for (i = 0; i < NR_IRQS; i++)
 		irq_timer_state[i] = NULL;
-	memset(&keyboard_timer_state, 0, sizeof(struct timer_rand_state));
-	memset(&mouse_timer_state, 0, sizeof(struct timer_rand_state));
+	memset(&input_timer_state, 0, sizeof(struct timer_rand_state));
 	memset(&extract_timer_state, 0, sizeof(struct timer_rand_state));
 	extract_timer_state.dont_count_entropy = 1;
 	return 0;
@@ -1577,7 +1554,7 @@
 void rand_initialize_irq(int irq)
 {
 	struct timer_rand_state *state;
-	
+
 	if (irq >= NR_IRQS || irq_timer_state[irq])
 		return;
 
@@ -1591,11 +1568,11 @@
 		irq_timer_state[irq] = state;
 	}
 }
- 
+
 void rand_initialize_disk(struct gendisk *disk)
 {
 	struct timer_rand_state *state;
-	
+
 	/*
 	 * If kmalloc returns null, we just won't use that entropy
 	 * source.
@@ -1611,8 +1588,8 @@
 random_read(struct file * file, char __user * buf, size_t nbytes, loff_t *ppos)
 {
 	DECLARE_WAITQUEUE(wait, current);
-	ssize_t			n, retval = 0, count = 0;
-	
+	ssize_t n, retval = 0, count = 0;
+
 	if (nbytes == 0)
 		return 0;
 
@@ -1621,20 +1598,14 @@
 		if (n > SEC_XFER_SIZE)
 			n = SEC_XFER_SIZE;
 
-		DEBUG_ENT("%04d %04d : reading %d bits, p: %d s: %d\n",
-			  random_state->entropy_count,
-			  sec_random_state->entropy_count,
-			  n*8, random_state->entropy_count,
-			  sec_random_state->entropy_count);
+		DEBUG_ENT("reading %d bits\n", n*8);
 
 		n = extract_entropy(sec_random_state, buf, n,
 				    EXTRACT_ENTROPY_USER |
 				    EXTRACT_ENTROPY_LIMIT |
 				    EXTRACT_ENTROPY_SECONDARY);
 
-		DEBUG_ENT("%04d %04d : read got %d bits (%d still needed)\n",
-			  random_state->entropy_count,
-			  sec_random_state->entropy_count,
+		DEBUG_ENT("read got %d bits (%d still needed)\n",
 			  n*8, (nbytes-n)*8);
 
 		if (n == 0) {
@@ -1647,10 +1618,6 @@
 				break;
 			}
 
-			DEBUG_ENT("%04d %04d : sleeping?\n",
-				  random_state->entropy_count,
-				  sec_random_state->entropy_count);
-
 			set_current_state(TASK_INTERRUPTIBLE);
 			add_wait_queue(&random_read_wait, &wait);
 
@@ -1660,10 +1627,6 @@
 			set_current_state(TASK_RUNNING);
 			remove_wait_queue(&random_read_wait, &wait);
 
-			DEBUG_ENT("%04d %04d : waking up\n",
-				  random_state->entropy_count,
-				  sec_random_state->entropy_count);
-
 			continue;
 		}
 
@@ -1683,7 +1646,7 @@
 	 */
 	if (count)
 		file_accessed(file);
-	
+
 	return (count ? count : retval);
 }
 
@@ -1721,11 +1684,11 @@
 random_write(struct file * file, const char __user * buffer,
 	     size_t count, loff_t *ppos)
 {
-	int		ret = 0;
-	size_t		bytes;
-	__u32 		buf[16];
-	const char 	__user *p = buffer;
-	size_t		c = count;
+	int ret = 0;
+	size_t bytes;
+	__u32 buf[16];
+	const char __user *p = buffer;
+	size_t c = count;
 
 	while (c > 0) {
 		bytes = min(c, sizeof(buf));
@@ -1743,8 +1706,9 @@
 	if (p == buffer) {
 		return (ssize_t)ret;
 	} else {
-		file->f_dentry->d_inode->i_mtime = CURRENT_TIME;
-		mark_inode_dirty(file->f_dentry->d_inode);
+		struct inode *inode = file->f_dentry->d_inode;
+	        inode->i_mtime = current_fs_time(inode->i_sb);
+		mark_inode_dirty(inode);
 		return (ssize_t)(p - buffer);
 	}
 }
@@ -1756,7 +1720,7 @@
 	int size, ent_count;
 	int __user *p = (int __user *)arg;
 	int retval;
-	
+
 	switch (cmd) {
 	case RNDGETENTCNT:
 		ent_count = random_state->entropy_count;
@@ -1815,22 +1779,22 @@
 }
 
 struct file_operations random_fops = {
-	.read		= random_read,
-	.write		= random_write,
-	.poll		= random_poll,
-	.ioctl		= random_ioctl,
+	.read  = random_read,
+	.write = random_write,
+	.poll  = random_poll,
+	.ioctl = random_ioctl,
 };
 
 struct file_operations urandom_fops = {
-	.read		= urandom_read,
-	.write		= random_write,
-	.ioctl		= random_ioctl,
+	.read  = urandom_read,
+	.write = random_write,
+	.ioctl = random_ioctl,
 };
 
 /***************************************************************
  * Random UUID interface
- * 
- * Used here for a Boot ID, but can be useful for other kernel 
+ *
+ * Used here for a Boot ID, but can be useful for other kernel
  * drivers.
  ***************************************************************/
 
@@ -1858,91 +1822,24 @@
 
 #include <linux/sysctl.h>
 
-static int sysctl_poolsize;
 static int min_read_thresh, max_read_thresh;
 static int min_write_thresh, max_write_thresh;
 static char sysctl_bootid[16];
 
 /*
- * This function handles a request from the user to change the pool size 
- * of the primary entropy store.
- */
-static int change_poolsize(int poolsize)
-{
-	struct entropy_store	*new_store, *old_store;
-	int			ret;
-	
-	if ((ret = create_entropy_store(poolsize, random_state->name,
-					&new_store)))
-		return ret;
-
-	add_entropy_words(new_store, random_state->pool,
-			  random_state->poolinfo.poolwords);
-	credit_entropy_store(new_store, random_state->entropy_count);
-
-	sysctl_init_random(new_store);
-	old_store = random_state;
-	random_state = batch_work.data = new_store;
-	free_entropy_store(old_store);
-	return 0;
-}
-
-static int proc_do_poolsize(ctl_table *table, int write, struct file *filp,
-			    void __user *buffer, size_t *lenp, loff_t *ppos)
-{
-	int	ret;
-
-	sysctl_poolsize = random_state->poolinfo.POOLBYTES;
-
-	ret = proc_dointvec(table, write, filp, buffer, lenp, ppos);
-	if (ret || !write ||
-	    (sysctl_poolsize == random_state->poolinfo.POOLBYTES))
-		return ret;
-
-	return change_poolsize(sysctl_poolsize);
-}
-
-static int poolsize_strategy(ctl_table *table, int __user *name, int nlen,
-			     void __user *oldval, size_t __user *oldlenp,
-			     void __user *newval, size_t newlen, void **context)
-{
-	int	len;
-	
-	sysctl_poolsize = random_state->poolinfo.POOLBYTES;
-
-	/*
-	 * We only handle the write case, since the read case gets
-	 * handled by the default handler (and we don't care if the
-	 * write case happens twice; it's harmless).
-	 */
-	if (newval && newlen) {
-		len = newlen;
-		if (len > table->maxlen)
-			len = table->maxlen;
-		if (copy_from_user(table->data, newval, len))
-			return -EFAULT;
-	}
-
-	if (sysctl_poolsize != random_state->poolinfo.POOLBYTES)
-		return change_poolsize(sysctl_poolsize);
-
-	return 0;
-}
-
-/*
  * These functions is used to return both the bootid UUID, and random
  * UUID.  The difference is in whether table->data is NULL; if it is,
  * then a new UUID is generated and returned to the user.
- * 
+ *
  * If the user accesses this via the proc interface, it will be returned
- * as an ASCII string in the standard UUID format.  If accesses via the 
+ * as an ASCII string in the standard UUID format.  If accesses via the
  * sysctl system call, it is returned as 16 bytes of binary data.
  */
 static int proc_do_uuid(ctl_table *table, int write, struct file *filp,
 			void __user *buffer, size_t *lenp, loff_t *ppos)
 {
-	ctl_table	fake_table;
-	unsigned char	buf[64], tmp_uuid[16], *uuid;
+	ctl_table fake_table;
+	unsigned char buf[64], tmp_uuid[16], *uuid;
 
 	uuid = table->data;
 	if (!uuid) {
@@ -1968,8 +1865,8 @@
 			 void __user *oldval, size_t __user *oldlenp,
 			 void __user *newval, size_t newlen, void **context)
 {
-	unsigned char	tmp_uuid[16], *uuid;
-	unsigned int	len;
+	unsigned char tmp_uuid[16], *uuid;
+	unsigned int len;
 
 	if (!oldval || !oldlenp)
 		return 1;
@@ -1994,15 +1891,15 @@
 	return 1;
 }
 
+static int sysctl_poolsize = DEFAULT_POOL_SIZE;
 ctl_table random_table[] = {
 	{
-		.ctl_name	= RANDOM_POOLSIZE,
+		.ctl_name 	= RANDOM_POOLSIZE,
 		.procname	= "poolsize",
 		.data		= &sysctl_poolsize,
 		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= &proc_do_poolsize,
-		.strategy	= &poolsize_strategy,
+		.mode		= 0444,
+		.proc_handler	= &proc_dointvec,
 	},
 	{
 		.ctl_name	= RANDOM_ENTROPY_COUNT,
@@ -2094,7 +1991,7 @@
  * Rotation is separate from addition to prevent recomputation
  */
 #define ROUND(f, a, b, c, d, x, s)	\
-	(a += f(b, c, d) + x, a = (a << s) | (a >> (32-s)))
+	(a += f(b, c, d) + x, a = (a << s) | (a >> (32 - s)))
 #define K1 0
 #define K2 013240474631UL
 #define K3 015666365641UL
@@ -2104,7 +2001,7 @@
  */
 static __u32 halfMD4Transform (__u32 const buf[4], __u32 const in[8])
 {
-	__u32	a = buf[0], b = buf[1], c = buf[2], d = buf[3];
+	__u32 a = buf[0], b = buf[1], c = buf[2], d = buf[3];
 
 	/* Round 1 */
 	ROUND(F, a, b, c, d, in[0] + K1,  3);
@@ -2144,7 +2041,7 @@
 
 static __u32 twothirdsMD4Transform (__u32 const buf[4], __u32 const in[12])
 {
-	__u32	a = buf[0], b = buf[1], c = buf[2], d = buf[3];
+	__u32 a = buf[0], b = buf[1], c = buf[2], d = buf[3];
 
 	/* Round 1 */
 	ROUND(F, a, b, c, d, in[ 0] + K1,  3);
@@ -2188,7 +2085,7 @@
 	ROUND(H, c, d, a, b, in[ 4] + K3, 11);
 	ROUND(H, b, c, d, a, in[ 8] + K3, 15);
 
-	return buf[1] + b;	/* "most hashed" word */
+	return buf[1] + b; /* "most hashed" word */
 	/* Alternative: return sum of all words? */
 }
 #endif
@@ -2202,7 +2099,7 @@
 #undef K3
 
 /* This should not be decreased so low that ISNs wrap too fast. */
-#define REKEY_INTERVAL	(300*HZ)
+#define REKEY_INTERVAL (300 * HZ)
 /*
  * Bit layout of the tcp sequence numbers (before adding current time):
  * bit 24-31: increased after every key exchange
@@ -2220,16 +2117,16 @@
  *
  * SMP cleanup and lock avoidance with poor man's RCU.
  * 			Manfred Spraul <manfred@colorfullife.com>
- * 		
+ *
  */
-#define COUNT_BITS	8
-#define COUNT_MASK	( (1<<COUNT_BITS)-1)
-#define HASH_BITS	24
-#define HASH_MASK	( (1<<HASH_BITS)-1 )
+#define COUNT_BITS 8
+#define COUNT_MASK ((1 << COUNT_BITS) - 1)
+#define HASH_BITS 24
+#define HASH_MASK ((1 << HASH_BITS) - 1)
 
 static struct keydata {
-	__u32	count;		// already shifted to the final position
-	__u32	secret[12];
+	__u32 count; /* already shifted to the final position */
+	__u32 secret[12];
 } ____cacheline_aligned ip_keydata[2];
 
 static unsigned int ip_cnt;
@@ -2252,10 +2149,10 @@
  */
 static void rekey_seq_generator(void *private_)
 {
-	struct keydata *keyptr = &ip_keydata[1^(ip_cnt&1)];
+	struct keydata *keyptr = &ip_keydata[1 ^ (ip_cnt & 1)];
 
 	get_random_bytes(keyptr->secret, sizeof(keyptr->secret));
-	keyptr->count = (ip_cnt&COUNT_MASK)<<HASH_BITS;
+	keyptr->count = (ip_cnt & COUNT_MASK) << HASH_BITS;
 	smp_wmb();
 	ip_cnt++;
 	schedule_delayed_work(&rekey_work, REKEY_INTERVAL);
@@ -2263,7 +2160,7 @@
 
 static inline struct keydata *get_keyptr(void)
 {
-	struct keydata *keyptr = &ip_keydata[ip_cnt&1];
+	struct keydata *keyptr = &ip_keydata[ip_cnt & 1];
 
 	smp_rmb();
 
@@ -2281,25 +2178,24 @@
 __u32 secure_tcpv6_sequence_number(__u32 *saddr, __u32 *daddr,
 				   __u16 sport, __u16 dport)
 {
-	struct timeval 	tv;
-	__u32		seq;
-	__u32		hash[12];
+	struct timeval tv;
+	__u32 seq;
+	__u32 hash[12];
 	struct keydata *keyptr = get_keyptr();
 
 	/* The procedure is the same as for IPv4, but addresses are longer.
 	 * Thus we must use twothirdsMD4Transform.
 	 */
 
-
 	memcpy(hash, saddr, 16);
 	hash[4]=(sport << 16) + dport;
-	memcpy(&hash[5],keyptr->secret,sizeof(__u32)*7);
+	memcpy(&hash[5],keyptr->secret,sizeof(__u32) * 7);
 
 	seq = twothirdsMD4Transform(daddr, hash) & HASH_MASK;
 	seq += keyptr->count;
 
 	do_gettimeofday(&tv);
-	seq += tv.tv_usec + tv.tv_sec*1000000;
+	seq += tv.tv_usec + tv.tv_sec * 1000000;
 
 	return seq;
 }
@@ -2309,15 +2205,15 @@
 __u32 secure_tcp_sequence_number(__u32 saddr, __u32 daddr,
 				 __u16 sport, __u16 dport)
 {
-	struct timeval 	tv;
-	__u32		seq;
-	__u32	hash[4];
+	struct timeval tv;
+	__u32 seq;
+	__u32 hash[4];
 	struct keydata *keyptr = get_keyptr();
 
 	/*
 	 *  Pick a unique starting offset for each TCP connection endpoints
 	 *  (saddr, daddr, sport, dport).
-	 *  Note that the words are placed into the starting vector, which is 
+	 *  Note that the words are placed into the starting vector, which is
 	 *  then mixed with a partial MD4 over random data.
 	 */
 	hash[0]=saddr;
@@ -2336,7 +2232,7 @@
 	 *	(Networks are faster now - should this be increased?)
 	 */
 	do_gettimeofday(&tv);
-	seq += tv.tv_usec + tv.tv_sec*1000000;
+	seq += tv.tv_usec + tv.tv_sec * 1000000;
 #if 0
 	printk("init_seq(%lx, %lx, %d, %d) = %d\n",
 	       saddr, daddr, sport, dport, seq);
@@ -2369,6 +2265,24 @@
 	return halfMD4Transform(hash, keyptr->secret);
 }
 
+/* Generate secure starting point for ephemeral TCP port search */
+u32 secure_tcp_port_ephemeral(__u32 saddr, __u32 daddr, __u16 dport)
+{
+	struct keydata *keyptr = get_keyptr();
+	u32 hash[4];
+
+	/*
+	 *  Pick a unique starting offset for each ephemeral port search
+	 *  (saddr, daddr, dport) and 48bits of random data.
+	 */
+	hash[0] = saddr;
+	hash[1] = daddr;
+	hash[2] = dport ^ keyptr->secret[10];
+	hash[3] = keyptr->secret[11];
+
+	return halfMD4Transform(hash, keyptr->secret);
+}
+
 #ifdef CONFIG_SYN_COOKIES
 /*
  * Secure SYN cookie computation. This is the algorithm worked out by
@@ -2381,14 +2295,14 @@
 #define COOKIEBITS 24	/* Upper bits store count */
 #define COOKIEMASK (((__u32)1 << COOKIEBITS) - 1)
 
-static int	syncookie_init;
-static __u32	syncookie_secret[2][16-3+HASH_BUFFER_SIZE];
+static int syncookie_init;
+static __u32 syncookie_secret[2][16-3+HASH_BUFFER_SIZE];
 
 __u32 secure_tcp_syn_cookie(__u32 saddr, __u32 daddr, __u16 sport,
 		__u16 dport, __u32 sseq, __u32 count, __u32 data)
 {
-	__u32 	tmp[16 + HASH_BUFFER_SIZE + HASH_EXTRA_SIZE];
-	__u32	seq;
+	__u32 tmp[16 + HASH_BUFFER_SIZE + HASH_EXTRA_SIZE];
+	__u32 seq;
 
 	/*
 	 * Pick two random secrets the first time we need a cookie.
@@ -2409,19 +2323,19 @@
 	 * MSS into the second hash value.
 	 */
 
-	memcpy(tmp+3, syncookie_secret[0], sizeof(syncookie_secret[0]));
+	memcpy(tmp + 3, syncookie_secret[0], sizeof(syncookie_secret[0]));
 	tmp[0]=saddr;
 	tmp[1]=daddr;
 	tmp[2]=(sport << 16) + dport;
 	HASH_TRANSFORM(tmp+16, tmp);
 	seq = tmp[17] + sseq + (count << COOKIEBITS);
 
-	memcpy(tmp+3, syncookie_secret[1], sizeof(syncookie_secret[1]));
+	memcpy(tmp + 3, syncookie_secret[1], sizeof(syncookie_secret[1]));
 	tmp[0]=saddr;
 	tmp[1]=daddr;
 	tmp[2]=(sport << 16) + dport;
 	tmp[3] = count;	/* minute counter */
-	HASH_TRANSFORM(tmp+16, tmp);
+	HASH_TRANSFORM(tmp + 16, tmp);
 
 	/* Add in the second hash and the data */
 	return seq + ((tmp[17] + data) & COOKIEMASK);
@@ -2439,18 +2353,18 @@
 __u32 check_tcp_syn_cookie(__u32 cookie, __u32 saddr, __u32 daddr, __u16 sport,
 		__u16 dport, __u32 sseq, __u32 count, __u32 maxdiff)
 {
-	__u32 	tmp[16 + HASH_BUFFER_SIZE + HASH_EXTRA_SIZE];
-	__u32	diff;
+	__u32 tmp[16 + HASH_BUFFER_SIZE + HASH_EXTRA_SIZE];
+	__u32 diff;
 
 	if (syncookie_init == 0)
-		return (__u32)-1;	/* Well, duh! */
+		return (__u32)-1; /* Well, duh! */
 
 	/* Strip away the layers from the cookie */
-	memcpy(tmp+3, syncookie_secret[0], sizeof(syncookie_secret[0]));
+	memcpy(tmp + 3, syncookie_secret[0], sizeof(syncookie_secret[0]));
 	tmp[0]=saddr;
 	tmp[1]=daddr;
 	tmp[2]=(sport << 16) + dport;
-	HASH_TRANSFORM(tmp+16, tmp);
+	HASH_TRANSFORM(tmp + 16, tmp);
 	cookie -= tmp[17] + sseq;
 	/* Cookie is now reduced to (count * 2^24) ^ (hash % 2^24) */
 
@@ -2463,7 +2377,7 @@
 	tmp[1] = daddr;
 	tmp[2] = (sport << 16) + dport;
 	tmp[3] = count - diff;	/* minute counter */
-	HASH_TRANSFORM(tmp+16, tmp);
+	HASH_TRANSFORM(tmp + 16, tmp);
 
 	return (cookie - tmp[17]) & COOKIEMASK;	/* Leaving the data behind */
 }
diff -Nru a/drivers/char/rio/cdproto.h b/drivers/char/rio/cdproto.h
--- a/drivers/char/rio/cdproto.h	2005-03-01 23:38:56 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,55 +0,0 @@
-/* 
- *
- *  (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-#ifndef _cirrusprots_h
-#define _cirrusprots_h
-
-#ifdef RTA
-extern void cd1400_reset ( int uart) ;
-extern void cd1400_init ( int uart ) ;
-extern void ccr_wait ( int priority, int port) ;
-extern void cd1400_txstart( int port) ;
-extern void cd1400_rxstart ( int port) ;
-extern void command_acknowledge ( PHB *port_header ) ;
-extern int close_port ( ushort port, PHB *port_header, ushort preemptive, int pseudo) ;
-extern void command_preemptive ( PKT *packet) ;
-extern void rup_service ( void ) ;
-extern ushort GetModemLines(struct PHB *, register short *);
-extern void cd1400_intr (Process *cirrus_p, ushort *RtaType) ;
-extern void cd1400_mdint ( short port) ;
-extern void cd1400_rxint ( short port) ;
-extern void cd1400_rxexcept ( short port) ;
-extern void cd1400_txdata ( short port, PHB *port_header, PKT *packet) ;
-extern void cd1400_fast_clock(void);
-extern void cd1400_map_baud ( ushort host_rate, ushort *prescaler, ushort *divisor) ;
-extern void cd1400_modem ( ushort port, ushort way) ;
-extern void cd1400_txcommand ( short port, PHB *port_header, PKT *packet) ;
-extern void cd1400_txint ( int port) ;
-void Rprintf( char *RIOPrBuf, char *Str, ... );
-#if defined(DCIRRUS)
-void debug_packet(PKT *pkt, int option, char *string, int channel);
-#endif	/* defined(DCIRRUS) */
-#endif
-
-#ifdef HOST
-extern void wflush (PHB *);
-extern void command_preemptive (PKT *);
-#endif
-
-#endif /* _cirrusprots_h */
diff -Nru a/drivers/char/rio/func.h b/drivers/char/rio/func.h
--- a/drivers/char/rio/func.h	2005-03-01 23:38:57 -08:00
+++ b/drivers/char/rio/func.h	2005-03-01 23:38:57 -08:00
@@ -47,7 +47,6 @@
 int RIOBootCodeUNKNOWN(struct rio_info *, struct DownLoad *);
 void msec_timeout(struct Host *);
 int RIOBootRup(struct rio_info *, uint, struct Host *, struct PKT *);
-int RIOBootComplete(struct rio_info *, struct Host *, uint, struct PktCmd *);
 int RIOBootOk(struct rio_info *,struct Host *, ulong);
 int RIORtaBound(struct rio_info *, uint); 
 void FillSlot(int, int, uint, struct Host *);
@@ -61,15 +60,10 @@
 int RIOKillNeighbour(struct rio_info *, caddr_t);
 int RIOSuspendBootRta(struct Host *, int, int);
 int RIOFoadWakeup(struct rio_info *);
-int RIOCommandRup(struct rio_info *, uint, struct Host *, struct PKT *);
 struct CmdBlk * RIOGetCmdBlk(void);
 void RIOFreeCmdBlk(struct CmdBlk *);
 int RIOQueueCmdBlk(struct Host *, uint, struct CmdBlk *);
 void RIOPollHostCommands(struct rio_info *, struct Host *);
-int RIOStrlen(register char *);
-int RIOStrCmp(register char *, register char *);
-int RIOStrnCmp(register char *, register char *, int);
-void  RIOStrNCpy(char *, char *, int);
 int RIOWFlushMark(int, struct CmdBlk *);
 int RIORFlushEnable(int, struct CmdBlk *);
 int RIOUnUse(int, struct CmdBlk *);
@@ -77,7 +71,6 @@
 
 /* rioctrl.c */
 int copyin(int, caddr_t, int);
-int copyout(caddr_t, int, int);
 int riocontrol(struct rio_info *, dev_t,int,caddr_t,int); 
 int RIOPreemptiveCmd(struct rio_info *,struct Port *,uchar);
 
@@ -89,24 +82,17 @@
 caddr_t RIOCheckForATCard(int);
 int RIOAssignAT(struct rio_info *, int, caddr_t, int);
 int RIOBoardTest(paddr_t, caddr_t, uchar, int);
-int RIOScrub(int, BYTE *, int);
-void RIOAllocateInterrupts(struct rio_info *);
-void RIOStopInterrupts(struct rio_info *, int, int);
 void RIOAllocDataStructs(struct rio_info *);
 void RIOSetupDataStructs(struct rio_info *);
 int RIODefaultName(struct rio_info *, struct Host *, uint);
-int RIOReport(struct rio_info *);
 struct rioVersion * RIOVersid(void);
 int RIOMapin(paddr_t, int, caddr_t *);
 void RIOMapout(paddr_t, long, caddr_t);
 void RIOHostReset(uint, volatile struct DpRam *, uint);
 
 /* riointr.c */
-void riopoll(struct rio_info *);
-void riointr(struct rio_info *);
 void RIOTxEnable(char *);
 void RIOServiceHost(struct rio_info *, struct Host *, int);
-void RIOReceive(struct rio_info *, struct Port *);
 int riotproc(struct rio_info *, register struct ttystatics *, int, int);
 
 /* rioparam.c */
@@ -123,22 +109,15 @@
 /* rioroute.c */
 int RIORouteRup(struct rio_info *, uint, struct Host *, struct PKT *);
 void RIOFixPhbs(struct rio_info *, struct Host *, uint); 
-int RIOCheckIsolated(struct rio_info *, struct Host *, uint);
-int RIOIsolate(struct rio_info *, struct Host *, uint);
-int RIOCheck(struct Host *, uint);
 uint GetUnitType(uint);
 int RIOSetChange(struct rio_info *);
-void RIOConCon(struct rio_info *, struct Host *, uint, uint, uint, uint, int);
 int RIOFindFreeID(struct rio_info *, struct Host *, uint *, uint *);
-int RIOFreeDisconnected(struct rio_info *, struct Host *, int );
-int RIORemoveFromSavedTable(struct rio_info *, struct Map *);
 
 
 /* riotty.c */
 
 int riotopen(struct tty_struct * tty, struct file * filp);
 int riotclose(void  *ptr);
-int RIOCookMode(struct ttystatics *);
 int riotioctl(struct rio_info *, struct tty_struct *, register int, register caddr_t); 
 void ttyseth(struct Port *, struct ttystatics *, struct old_sgttyb *sg);
 
diff -Nru a/drivers/char/rio/rio_linux.c b/drivers/char/rio/rio_linux.c
--- a/drivers/char/rio/rio_linux.c	2005-03-01 23:38:59 -08:00
+++ b/drivers/char/rio/rio_linux.c	2005-03-01 23:38:59 -08:00
@@ -32,11 +32,6 @@
  *
  * */
 
-
-#define RCS_ID "$Id: rio.c,v 1.1 1999/07/11 10:13:54 wolff Exp wolff $"
-#define RCS_REV "$Revision: 1.1 $"
-
-
 #include <linux/module.h>
 #include <linux/config.h> 
 #include <linux/kdev_t.h>
@@ -198,7 +193,7 @@
 		         unsigned int cmd, unsigned long arg);
 static int rio_init_drivers(void);
 
-void my_hd (void *addr, int len);
+static void my_hd (void *addr, int len);
 
 static struct tty_driver *rio_driver, *rio_driver2;
 
@@ -206,11 +201,6 @@
 sources use all over the place. */
 struct rio_info *p;
 
-/* struct rio_board boards[RIO_HOSTS]; */
-struct rio_port *rio_ports;
-
-int rio_initialized;
-int rio_nports;
 int rio_debug;
 
 
@@ -218,12 +208,12 @@
     - Set rio_poll to 1 to poll every timer tick (10ms on Intel). 
       This is used when the card cannot use an interrupt for some reason.
 */
-int rio_poll = 1;
+static int rio_poll = 1;
 
 
 /* These are the only open spaces in my computer. Yours may have more
    or less.... */
-int rio_probe_addrs[]= {0xc0000, 0xd0000, 0xe0000};
+static int rio_probe_addrs[]= {0xc0000, 0xd0000, 0xe0000};
 
 #define NR_RIO_ADDRS (sizeof(rio_probe_addrs)/sizeof (int))
 
@@ -264,7 +254,7 @@
 	.ioctl		= rio_fw_ioctl,
 };
 
-struct miscdevice rio_fw_device = {
+static struct miscdevice rio_fw_device = {
 	RIOCTL_MISC_MINOR, "rioctl", &rio_fw_fops
 };
 
@@ -302,7 +292,7 @@
 
 
 #ifdef DEBUG
-void my_hd (void *ad, int len)
+static void my_hd (void *ad, int len)
 {
   int i, j, ch;
   unsigned char *addr = ad;
@@ -387,7 +377,7 @@
 }
 
 
-void rio_reset_interrupt (struct Host *HostP)
+static void rio_reset_interrupt (struct Host *HostP)
 {
   func_enter();
 
@@ -824,7 +814,7 @@
  * ********************************************************************** */
 
 
-struct vpd_prom *get_VPD_PROM (struct Host *hp)
+static struct vpd_prom *get_VPD_PROM (struct Host *hp)
 {
   static struct vpd_prom vpdp;
   char *p;
@@ -979,7 +969,7 @@
     port->gs.close_delay = HZ/2;
     port->gs.closing_wait = 30 * HZ;
     port->gs.rd = &rio_real_driver;
-    port->portSem = SPIN_LOCK_UNLOCKED;
+    spin_lock_init(&port->portSem);
     /*
      * Initializing wait queue
      */
@@ -1045,7 +1035,7 @@
    EEprom.  As the bit is read/write for the CPU, we can fix it here,
    if we detect that it isn't set correctly. -- REW */
 
-void fix_rio_pci (struct pci_dev *pdev)
+static void fix_rio_pci (struct pci_dev *pdev)
 {
   unsigned int hwbase;
   unsigned long rebase;
@@ -1141,7 +1131,7 @@
       hp->Type  = RIO_PCI;
       hp->Copy  = rio_pcicopy; 
       hp->Mode  = RIO_PCI_BOOT_FROM_RAM;
-      hp->HostLock = SPIN_LOCK_UNLOCKED;
+      spin_lock_init(&hp->HostLock);
       rio_reset_interrupt (hp);
       rio_start_card_running (hp);
 
@@ -1199,7 +1189,7 @@
       hp->Type  = RIO_PCI;
       hp->Copy  = rio_pcicopy;
       hp->Mode  = RIO_PCI_BOOT_FROM_RAM;
-      hp->HostLock = SPIN_LOCK_UNLOCKED;
+      spin_lock_init(&hp->HostLock);
 
       rio_dprintk (RIO_DEBUG_PROBE, "Ivec: %x\n", hp->Ivec);
       rio_dprintk (RIO_DEBUG_PROBE, "Mode: %x\n", hp->Mode);
@@ -1249,7 +1239,7 @@
                              * Moreover, the ISA card will work with the 
                              * special PCI copy anyway. -- REW */
     hp->Mode = 0;
-    hp->HostLock = SPIN_LOCK_UNLOCKED;
+    spin_lock_init(&hp->HostLock);
 
     vpdp = get_VPD_PROM (hp);
     rio_dprintk (RIO_DEBUG_PROBE, "Got VPD ROM\n");
diff -Nru a/drivers/char/rio/rioboot.c b/drivers/char/rio/rioboot.c
--- a/drivers/char/rio/rioboot.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/char/rio/rioboot.c	2005-03-01 23:38:54 -08:00
@@ -80,6 +80,8 @@
 #include "cmdblk.h"
 #include "route.h"
 
+static int RIOBootComplete( struct rio_info *p, struct Host *HostP, uint Rup, struct PktCmd *PktCmdP );
+
 static uchar
 RIOAtVec2Ctrl[] =
 {
@@ -580,14 +582,14 @@
 			HostP->UnixRups[RupN].RupP		= &HostP->RupP[RupN];
 			HostP->UnixRups[RupN].Id		  = RupN+1;
 			HostP->UnixRups[RupN].BaseSysPort = NO_PORT;
-			HostP->UnixRups[RupN].RupLock = SPIN_LOCK_UNLOCKED;
+			spin_lock_init(&HostP->UnixRups[RupN].RupLock);
 		}
 
 		for ( RupN = 0; RupN<LINKS_PER_UNIT; RupN++ ) {
 			HostP->UnixRups[RupN+MAX_RUP].RupP	= &HostP->LinkStrP[RupN].rup;
 			HostP->UnixRups[RupN+MAX_RUP].Id  = 0;
 			HostP->UnixRups[RupN+MAX_RUP].BaseSysPort = NO_PORT;
-			HostP->UnixRups[RupN+MAX_RUP].RupLock = SPIN_LOCK_UNLOCKED;
+			spin_lock_init(&HostP->UnixRups[RupN+MAX_RUP].RupLock);
 		}
 
 		/*
@@ -802,7 +804,7 @@
 ** If booted by an RTA, HostP->Mapping[Rup].RtaUniqueNum is the booting RTA.
 ** RtaUniq is the booted RTA.
 */
-int RIOBootComplete( struct rio_info *p, struct Host *HostP, uint Rup, struct PktCmd *PktCmdP )
+static int RIOBootComplete( struct rio_info *p, struct Host *HostP, uint Rup, struct PktCmd *PktCmdP )
 {
 	struct Map	*MapP = NULL;
 	struct Map	*MapP2 = NULL;
diff -Nru a/drivers/char/rio/riocmd.c b/drivers/char/rio/riocmd.c
--- a/drivers/char/rio/riocmd.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/char/rio/riocmd.c	2005-03-01 23:38:54 -08:00
@@ -397,7 +397,7 @@
 /*
 ** Incoming command on the COMMAND_RUP to be processed.
 */
-int
+static int
 RIOCommandRup(p, Rup, HostP, PacketP)
 struct rio_info *	p;
 uint Rup;
@@ -915,62 +915,6 @@
 		}
 		spin_unlock_irqrestore(&UnixRupP->RupLock, flags);
 	} while ( Rup );
-}
-
-
-/*
-** Return the length of the named string
-*/
-int
-RIOStrlen(Str)
-register char *Str;
-{
-	register int len = 0;
-
-	while ( *Str++ )
-		len++;
-	return len;
-}
-
-/*
-** compares s1 to s2 and return 0 if they match.
-*/
-int
-RIOStrCmp(s1, s2)
-register char *s1;
-register char *s2;
-{
-	while ( *s1 && *s2 && *s1==*s2 )
-		s1++, s2++;
-	return *s1-*s2;
-}
-
-/*
-** compares s1 to s2 for upto n bytes and return 0 if they match.
-*/
-int
-RIOStrnCmp(s1, s2, n)
-register char *s1;
-register char *s2;
-int n;
-{
-	while ( n && *s1 && *s2 && *s1==*s2 )
-		n--, s1++, s2++;
-	return n ? *s1!=*s2 : 0;
-}
-
-/*
-** copy up to 'len' bytes from 'from' to 'to'.
-*/
-void
-RIOStrNCpy(to, from, len)
-char *to;
-char *from;
-int len; 
-{
-	while ( len-- && (*to++ = *from++) )
-		;
-	to[-1]='\0';
 }
 
 int
diff -Nru a/drivers/char/rio/rioctrl.c b/drivers/char/rio/rioctrl.c
--- a/drivers/char/rio/rioctrl.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/char/rio/rioctrl.c	2005-03-01 23:38:56 -08:00
@@ -130,7 +130,6 @@
 
 #define drv_makedev(maj, min) ((((uint) maj & 0xff) << 8) | ((uint) min & 0xff))
 
-#ifdef linux
 int copyin (int arg, caddr_t dp, int siz)
 {
   int rv;
@@ -141,8 +140,7 @@
   else return rv;
 }
 
-
-int copyout (caddr_t dp, int arg, int siz)
+static int copyout (caddr_t dp, int arg, int siz)
 {
   int rv;
 
@@ -152,35 +150,6 @@
   else return rv;
 }
 
-#else
-
-int
-copyin(arg, dp, siz)
-int arg;
-caddr_t dp;
-int siz; 
-{
-	if (rbounds ((unsigned long) arg) >= siz) {
-		bcopy ( arg, dp, siz );
-		return OK;
-	} else
-		return ( COPYFAIL );
-}
-
-int
-copyout (dp, arg, siz)
-caddr_t dp;
-int arg;
-int siz;
-{
-	if (wbounds ((unsigned long) arg) >=  siz ) {
-		bcopy ( dp, arg, siz );
-		return OK;
-	} else
-		return ( COPYFAIL );
-}
-#endif
-
 int
 riocontrol(p, dev, cmd, arg, su)
 struct rio_info	* p;
@@ -1203,7 +1172,7 @@
 					p->RIOPortp[loop]->TtyP = &p->channel[loop];
 #endif
 					
-					p->RIOPortp[loop]->portSem = SPIN_LOCK_UNLOCKED;
+					spin_lock_init(&p->RIOPortp[loop]->portSem);
 					p->RIOPortp[loop]->InUse = NOT_INUSE;
 				}
 
diff -Nru a/drivers/char/rio/rioinit.c b/drivers/char/rio/rioinit.c
--- a/drivers/char/rio/rioinit.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/char/rio/rioinit.c	2005-03-01 23:38:54 -08:00
@@ -84,9 +84,15 @@
 #undef bcopy
 #define bcopy rio_pcicopy
 
-int
-RIOPCIinit(struct rio_info *p, int Mode);
+int RIOPCIinit(struct rio_info *p, int Mode);
+
+#if 0
+static void RIOAllocateInterrupts(struct rio_info *);
+static int RIOReport(struct rio_info *);
+static void RIOStopInterrupts(struct rio_info *, int, int);
+#endif
 
+static int RIOScrub(int, BYTE *, int);
 
 #if 0
 extern int	rio_intr();
@@ -1116,7 +1122,7 @@
 ** Call with op not zero, and the RAM will be read and compated with val[op-1]
 ** to check that the data from the previous phase was retained.
 */
-int
+static int
 RIOScrub(op, ram, size)
 int		op;
 BYTE *	ram;
@@ -1262,7 +1268,8 @@
 ** and force into polled mode if told to. Patch up the
 ** interrupt vector & salute The Queen when you've done.
 */
-void
+#if 0
+static void
 RIOAllocateInterrupts(p)
 struct rio_info *	p;
 {
@@ -1301,7 +1308,7 @@
 ** new-fangled interrupt thingies. Set everything up to just
 ** poll.
 */
-void
+static void
 RIOStopInterrupts(p, Reason, Host)
 struct rio_info *	p;
 int	Reason;
@@ -1360,7 +1367,6 @@
 	}
 }
 
-#if 0
 /*
 ** This function is called at init time to setup the data structures.
 */
@@ -1444,7 +1450,7 @@
 				}
 				RIODefaultName(p, HostP, rup);
 			}
-			HostP->UnixRups[rup].RupLock = SPIN_LOCK_UNLOCKED;
+			spin_lock_init(&HostP->UnixRups[rup].RupLock);
 		}
 	}
 }
@@ -1476,7 +1482,8 @@
 #define RIO_RELEASE	"Linux"
 #define RELEASE_ID	"1.0"
 
-int
+#if 0
+static int
 RIOReport(p)
 struct rio_info *	p;
 {
@@ -1500,41 +1507,7 @@
 	}
 	return 0;
 }
-
-/*
-** This function returns release/version information as used by ioctl() calls
-** It returns a MAX_VERSION_LEN byte string, null terminated.
-*/
-char *
-OLD_RIOVersid( void )
-{
-	static char	Info[MAX_VERSION_LEN];
-	char *	RIORelease = RIO_RELEASE;
-	char *	cp;
-	int		ct = 0;
-
-	for ( ct=0; RIORelease[ct] && ct<MAX_VERSION_LEN; ct++ )
-		Info[ct] = RIORelease[ct];
-	if ( ct>=MAX_VERSION_LEN ) {
-		Info[MAX_VERSION_LEN-1] = '\0';
-		return Info;
-	}
-	Info[ct++]=' ';
-	if ( ct>=MAX_VERSION_LEN ) {
-		Info[MAX_VERSION_LEN-1] = '\0';
-		return Info;
-	}
-
-	cp="";	/* Fill the RCS Id here */
-
-	while ( *cp && ct<MAX_VERSION_LEN )
-		Info[ct++] = *cp++;
-	if ( ct<MAX_VERSION_LEN-1 )
-		Info[ct] = '\0';
-	Info[MAX_VERSION_LEN-1] = '\0';
-	return Info;
-}
-
+#endif
 
 static struct rioVersion	stVersion;
 
diff -Nru a/drivers/char/rio/riointr.c b/drivers/char/rio/riointr.c
--- a/drivers/char/rio/riointr.c	2005-03-01 23:38:43 -08:00
+++ b/drivers/char/rio/riointr.c	2005-03-01 23:38:43 -08:00
@@ -84,83 +84,10 @@
 #include "rioioctl.h"
 
 
+static void RIOReceive(struct rio_info *, struct Port *);
 
 
-/*
-** riopoll is called every clock tick. Once the /dev/rio device has been
-** opened, and polldistributed( ) has been called, this routine is called
-** every clock tick *by every cpu*. The 'interesting' piece of code that
-** manipulates 'RIONumCpus' and 'RIOCpuCountdown' is used to fair-share
-** the work between the CPUs. If there are 'N' cpus, then each poll time
-** we increment a counter, modulo 'N-1'. When this counter is 0, we call
-** the interrupt handler. This has the effect that polls are serviced
-** by processor 'N', 'N-1', 'N-2', ... '0', round and round. Neat.
-*/
-void
-riopoll(p)
-struct rio_info *	p;
-{
-	int   host;
-
-	/*
-	** Here's the deal. We try to fair share as much as possible amongst
-	** all the processors that are available. Since each processor 
-	** should generate HZ ticks per second and since we only need HZ ticks
-	** in total for proper operation we simply attempt to cycle round each
-	** processor in turn, using RIOCpuCountdown to decide whether to call
-	** the interrupt routine. ( In fact the count zeroes when it reaches
-	** one less than the total number of processors - so e.g. on a two
-	** processor system RIOService will get called 2*HZ times per second. )
-	** this_cpu (cur_cpu()) tells us the number of the current processor
-	** as follows:
-	**
-	**		0 - default CPU
-	**		1 - first extra CPU
-	**		2 - second extra CPU
-	**		etc.
-	*/
-
-	/*
-	** okay, we've got a cpu that hasn't had a go recently 
-	** - lets check to see what needs doing.
-	*/
-	for ( host=0; host<p->RIONumHosts; host++ ) {
-		struct Host *HostP = &p->RIOHosts[host];
-
-		rio_spin_lock( &HostP->HostLock );
-
-		if ( ( (HostP->Flags & RUN_STATE) != RC_RUNNING ) ||
-		     HostP->InIntr ) {
-			rio_spin_unlock (&HostP->HostLock); 
-			continue;
-		}
-
-		if ( RWORD( HostP->ParmMapP->rup_intr ) ||
-			 RWORD( HostP->ParmMapP->rx_intr  ) ||
-			 RWORD( HostP->ParmMapP->tx_intr  ) ) {
-			HostP->InIntr = 1;
-
-#ifdef FUTURE_RELEASE
-			if( HostP->Type == RIO_EISA )
-				INBZ( HostP->Slot, EISA_INTERRUPT_RESET );
-			else
-#endif
-				WBYTE( HostP->ResetInt , 0xff );
-
-			rio_spin_lock(&HostP->HostLock); 
-
-			p->_RIO_Polled++;
-			RIOServiceHost(p, HostP, 'p' );
-			rio_spin_lock( &HostP->HostLock); 
-			HostP->InIntr = 0;
-			rio_spin_unlock (&HostP->HostLock);
-		}
-	}
-	rio_spin_unlock (&p->RIOIntrSem); 
-}
-
-
-char *firstchars (char *p, int nch)
+static char *firstchars (char *p, int nch)
 {
   static char buf[2][128];
   static int t=0;
@@ -258,93 +185,6 @@
 
 
 /*
-** When a real-life interrupt comes in here, we try to find out
-** which host card it belongs to, and then service only that host
-** Notice the cunning way that, once we've found a candidate, we
-** continue just in case we are sharing interrupts.
-*/
-void
-riointr(p)
-struct rio_info *	p;
-{
-	int host;
-
-	for ( host=0; host<p->RIONumHosts; host++ ) {
-		struct Host *HostP = &p->RIOHosts[host];
-
-		rio_dprintk (RIO_DEBUG_INTR,  "riointr() doing host %d type %d\n", host, HostP->Type);
-
-		switch( HostP->Type ) {
-			case RIO_AT:
-			case RIO_MCA:
-			case RIO_PCI:
-			  	rio_spin_lock(&HostP->HostLock);
-				WBYTE(HostP->ResetInt , 0xff);
-				if ( !HostP->InIntr ) {
-					HostP->InIntr = 1;
-					rio_spin_unlock (&HostP->HostLock);
-					p->_RIO_Interrupted++;
-					RIOServiceHost(p, HostP, 'i');
-					rio_spin_lock(&HostP->HostLock);
-					HostP->InIntr = 0;
-				}
-				rio_spin_unlock(&HostP->HostLock); 
-				break;
-#ifdef FUTURE_RELEASE
-		case RIO_EISA:
-			if ( ivec == HostP->Ivec )
-			{
-				OldSpl = LOCKB( &HostP->HostLock );
-				INBZ( HostP->Slot, EISA_INTERRUPT_RESET );
-				if ( !HostP->InIntr )
-				{
-					HostP->InIntr = 1;
-					UNLOCKB( &HostP->HostLock, OldSpl );
-					if ( this_cpu < RIO_CPU_LIMIT )
-					{
-						int intrSpl = LOCKB( &RIOIntrLock );
-						UNLOCKB( &RIOIntrLock, intrSpl );
-					}
-						p->_RIO_Interrupted++;
-					RIOServiceHost( HostP, 'i' );
-					OldSpl = LOCKB( &HostP->HostLock );
-					HostP->InIntr = 0;
-				}
-				UNLOCKB( &HostP->HostLock, OldSpl );
-				done++;
-			}
-			break;
-#endif
-		}
-
-		HostP->IntSrvDone++;
-	}
-
-#ifdef FUTURE_RELEASE
-	if ( !done )
-	{
-		cmn_err( CE_WARN, "RIO: Interrupt received with vector 0x%x\n", ivec );
-		cmn_err( CE_CONT, "	 Valid vectors are:\n");
-		for ( host=0; host<RIONumHosts; host++ )
-		{
-			switch( RIOHosts[host].Type )
-			{
-				case RIO_AT:
-				case RIO_MCA:
-				case RIO_EISA:
-						cmn_err( CE_CONT, "0x%x ", RIOHosts[host].Ivec );
-						break;
-				case RIO_PCI:
-						cmn_err( CE_CONT, "0x%x ", get_intr_arg( RIOHosts[host].PciDevInfo.busnum, IDIST_PCI_IRQ( RIOHosts[host].PciDevInfo.slotnum, RIOHosts[host].PciDevInfo.funcnum ) ));
-						break;
-			}
-		}
-		cmn_err( CE_CONT, "\n" );
-	}
-#endif
-}
-
-/*
 ** RIO Host Service routine. Does all the work traditionally associated with an
 ** interrupt.
 */
@@ -710,7 +550,7 @@
 ** NB: Called with the tty locked. The spl from the lockb( ) is passed.
 ** we return the ttySpl level that we re-locked at.
 */
-void
+static void
 RIOReceive(p, PortP)
 struct rio_info *	p;
 struct Port *		PortP;
diff -Nru a/drivers/char/rio/rioroute.c b/drivers/char/rio/rioroute.c
--- a/drivers/char/rio/rioroute.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/char/rio/rioroute.c	2005-03-01 23:38:58 -08:00
@@ -83,6 +83,12 @@
 #include "list.h"
 #include "sam.h"
 
+static int RIOCheckIsolated(struct rio_info *, struct Host *, uint);
+static int RIOIsolate(struct rio_info *, struct Host *, uint);
+static int RIOCheck(struct Host *, uint);
+static void RIOConCon(struct rio_info *, struct Host *, uint, uint, uint, uint, int);
+
+
 /*
 ** Incoming on the ROUTE_RUP
 ** I wrote this while I was tired. Forgive me.
@@ -717,7 +723,7 @@
 ** the world about it. This is done to ensure that the configurator
 ** only gets up-to-date information about what is going on.
 */
-int
+static int
 RIOCheckIsolated(p, HostP, UnitId)
 struct rio_info *	p;
 struct Host *HostP;
@@ -747,7 +753,7 @@
 ** all the units attached to it. This will mean that the entire
 ** subnet will re-introduce itself.
 */
-int
+static int
 RIOIsolate(p, HostP, UnitId)
 struct rio_info *	p;
 struct Host *		HostP;
@@ -782,7 +788,7 @@
 	return 1;
 }
 
-int
+static int
 RIOCheck(HostP, UnitId)
 struct Host *HostP;
 uint UnitId;
@@ -883,7 +889,7 @@
 	return(0);
 }
 
-void
+static void
 RIOConCon(p, HostP, FromId, FromLink, ToId, ToLink, Change)
 struct rio_info *	p;
 struct Host *HostP;
@@ -966,7 +972,7 @@
 ** Delete and RTA entry from the saved table given to us
 ** by the configuration program.
 */
-int
+static int
 RIORemoveFromSavedTable(struct rio_info *p, struct Map *pMap)
 {
     int		entry;
@@ -993,7 +999,7 @@
 ** Scan the unit links to and return zero if the unit is completely
 ** disconnected.
 */
-int
+static int
 RIOFreeDisconnected(struct rio_info *p, struct Host *HostP, int unit)
 {
     int		link;
diff -Nru a/drivers/char/rio/riotable.c b/drivers/char/rio/riotable.c
--- a/drivers/char/rio/riotable.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/char/rio/riotable.c	2005-03-01 23:39:16 -08:00
@@ -37,6 +37,7 @@
 #include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/interrupt.h>
+#include <linux/string.h>
 
 #include <asm/io.h>
 #include <asm/system.h>
@@ -276,7 +277,7 @@
 						return -ENXIO;
 					}
 					rio_dprintk (RIO_DEBUG_TABLE, "RIONewTable: entering(9)\n"); 
-					if (RIOStrCmp(MapP->Name,
+					if (strcmp(MapP->Name,
 							p->RIOConnectTable[SubEnt].Name)==0 && !(MapP->Flags & RTA16_SECOND_SLOT)) { /* (9) */
 						rio_dprintk (RIO_DEBUG_TABLE, "RTA name %s used twice\n", MapP->Name);
 						p->RIOError.Error = NAME_USED_TWICE;
@@ -405,7 +406,7 @@
 			for ( Host2=0; Host2<p->RIONumHosts; Host2++ ) {
 				if (Host2 == Host)
 					continue;
-				if (RIOStrCmp(p->RIOHosts[Host].Name, p->RIOHosts[Host2].Name)
+				if (strcmp(p->RIOHosts[Host].Name, p->RIOHosts[Host2].Name)
 									 == 0) {
 					NameIsUnique = 0;
 					Host1++;
@@ -938,20 +939,6 @@
 		PortP->Lock			= 0;
 		PortP->Store		= 0;
 		PortP->FirstOpen	= 1;
-
-		/*
-		** handle the xprint issues
-		*/
-#ifdef XPRINT_SUPPORT
-		PortP->Xprint.XpActive	= 0;
-		PortP->Xprint.XttyP = &riox_tty[SysPort];
-		/*				TO				FROM			MAXLEN */
-		RIOStrNCpy( PortP->Xprint.XpOn,	RIOConf.XpOn,	MAX_XP_CTRL_LEN );
-		RIOStrNCpy( PortP->Xprint.XpOff, RIOConf.XpOff, MAX_XP_CTRL_LEN );
-		PortP->Xprint.XpCps = RIOConf.XpCps;
-		PortP->Xprint.XpLen = RIOStrlen(PortP->Xprint.XpOn)+
-									RIOStrlen(PortP->Xprint.XpOff);
-#endif
 
 		/*
 		** Buffers 'n things
diff -Nru a/drivers/char/rio/riotty.c b/drivers/char/rio/riotty.c
--- a/drivers/char/rio/riotty.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/char/rio/riotty.c	2005-03-01 23:38:55 -08:00
@@ -40,6 +40,7 @@
 #include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/tty.h>
+#include <linux/string.h>
 #include <asm/io.h>
 #include <asm/system.h>
 #include <asm/string.h>
@@ -97,6 +98,9 @@
 int RIOShortCommand(struct rio_info *p, struct Port *PortP, 
 			   int command, int len, int arg);
 
+#if 0
+static int RIOCookMode(struct ttystatics *);
+#endif
 
 extern int	conv_vb[];	/* now defined in ttymgr.c */
 extern int	conv_bv[];	/* now defined in ttymgr.c */
@@ -726,7 +730,8 @@
 ** COOK_WELL if the line discipline must be used to do the processing
 ** COOK_MEDIUM if the card can do all the processing necessary.
 */
-int
+#if 0
+static int
 RIOCookMode(struct ttystatics *tp)
 {
 	/*
@@ -757,7 +762,7 @@
 	*/
 	return COOK_MEDIUM;
 }
-
+#endif
 
 static void
 RIOClearUp(PortP)
@@ -1011,8 +1016,8 @@
 				pseterr(EFAULT);
 			}
 			PortP->Xprint.XpOn[MAX_XP_CTRL_LEN-1] = '\0';
-			PortP->Xprint.XpLen = RIOStrlen(PortP->Xprint.XpOn)+
-												RIOStrlen(PortP->Xprint.XpOff);
+			PortP->Xprint.XpLen = strlen(PortP->Xprint.XpOn)+
+												strlen(PortP->Xprint.XpOff);
 			rio_spin_unlock_irqrestore(&PortP->portSem, flags);
 			return 0;
 
@@ -1026,8 +1031,8 @@
 				pseterr(EFAULT);
 			}
 			PortP->Xprint.XpOff[MAX_XP_CTRL_LEN-1] = '\0';
-			PortP->Xprint.XpLen = RIOStrlen(PortP->Xprint.XpOn)+
-										RIOStrlen(PortP->Xprint.XpOff);
+			PortP->Xprint.XpLen = strlen(PortP->Xprint.XpOn)+
+										strlen(PortP->Xprint.XpOff);
 			rio_spin_unlock_irqrestore(&PortP->portSem, flags);
 			return 0;
 
diff -Nru a/drivers/char/rsf16fmi.h b/drivers/char/rsf16fmi.h
--- a/drivers/char/rsf16fmi.h	2005-03-01 23:39:08 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,13 +0,0 @@
-/* SF16FMI FMRadio include file.
- * (c) 1998 Petr Vandrovec
- *
- * Not in include/linux/ because there's no need for anyone
- * to know about these details, I reckon.
- */
-
-#ifndef __RSF16FMI_H
-#define __RSF16FMI_H
-
-int radiosf16fmi_init(void);
-
-#endif /* __RSF16FMI_H */
diff -Nru a/drivers/char/rtc.c b/drivers/char/rtc.c
--- a/drivers/char/rtc.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/char/rtc.c	2005-03-01 23:39:18 -08:00
@@ -177,7 +177,7 @@
 /*
  * rtc_task_lock nests inside rtc_lock.
  */
-static spinlock_t rtc_task_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(rtc_task_lock);
 static rtc_task_t *rtc_callback = NULL;
 #endif
 
@@ -878,7 +878,7 @@
 	&rtc_fops
 };
 
-#ifdef RTC_IRQ
+#if defined(RTC_IRQ) && !defined(__sparc__)
 static irqreturn_t (*rtc_int_handler_ptr)(int irq, void *dev_id, struct pt_regs *regs);
 #endif
 
diff -Nru a/drivers/char/s3c2410-rtc.c b/drivers/char/s3c2410-rtc.c
--- a/drivers/char/s3c2410-rtc.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/char/s3c2410-rtc.c	2005-03-01 23:38:57 -08:00
@@ -48,7 +48,7 @@
 static int s3c2410_rtc_tickno  = NO_IRQ;
 static int s3c2410_rtc_freq    = 1;
 
-static spinlock_t s3c2410_rtc_pie_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(s3c2410_rtc_pie_lock);
 
 /* IRQ Handlers */
 
diff -Nru a/drivers/char/scx200_gpio.c b/drivers/char/scx200_gpio.c
--- a/drivers/char/scx200_gpio.c	2005-03-01 23:38:51 -08:00
+++ b/drivers/char/scx200_gpio.c	2005-03-01 23:38:51 -08:00
@@ -23,7 +23,7 @@
 MODULE_LICENSE("GPL");
 
 static int major = 0;		/* default to dynamic major */
-MODULE_PARM(major, "i");
+module_param(major, int, 0);
 MODULE_PARM_DESC(major, "Major device number");
 
 static ssize_t scx200_gpio_write(struct file *file, const char __user *data, 
diff -Nru a/drivers/char/selection.c b/drivers/char/selection.c
--- a/drivers/char/selection.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/char/selection.c	2005-03-01 23:39:16 -08:00
@@ -33,7 +33,7 @@
 
 /* Variables for selection control. */
 /* Use a dynamic buffer, instead of static (Dec 1994) */
-       int sel_cons;		/* must not be disallocated */
+struct vc_data *sel_cons;		/* must not be disallocated */
 static volatile int sel_start = -1; 	/* cleared by clear_selection */
 static int sel_end;
 static int sel_buffer_lth;
@@ -44,20 +44,22 @@
 
 /* set reverse video on characters s-e of console with selection. */
 inline static void
-highlight(const int s, const int e) {
+highlight(const int s, const int e)
+{
 	invert_screen(sel_cons, s, e-s+2, 1);
 }
 
 /* use complementary color to show the pointer */
 inline static void
-highlight_pointer(const int where) {
+highlight_pointer(const int where)
+{
 	complement_pos(sel_cons, where);
 }
 
 static unsigned char
 sel_pos(int n)
 {
-	return inverse_translate(vc_cons[sel_cons].d, screen_glyph(sel_cons, n));
+	return inverse_translate(sel_cons, screen_glyph(sel_cons, n));
 }
 
 /* remove the current selection highlight, if any,
@@ -111,10 +113,10 @@
 /* set the current selection. Invoked by ioctl() or by kernel code. */
 int set_selection(const struct tiocl_selection __user *sel, struct tty_struct *tty)
 {
+	struct vc_data *vc = vc_cons[fg_console].d;
 	int sel_mode, new_sel_start, new_sel_end, spc;
 	char *bp, *obp;
 	int i, ps, pe;
-	unsigned int currcons = fg_console;
 
 	poke_blanked_console();
 
@@ -128,12 +130,12 @@
 	  __get_user(ye, &sel->ye);
 	  __get_user(sel_mode, &sel->sel_mode);
 	  xs--; ys--; xe--; ye--;
-	  xs = limit(xs, video_num_columns - 1);
-	  ys = limit(ys, video_num_lines - 1);
-	  xe = limit(xe, video_num_columns - 1);
-	  ye = limit(ye, video_num_lines - 1);
-	  ps = ys * video_size_row + (xs << 1);
-	  pe = ye * video_size_row + (xe << 1);
+	  xs = limit(xs, vc->vc_cols - 1);
+	  ys = limit(ys, vc->vc_rows - 1);
+	  xe = limit(xe, vc->vc_cols - 1);
+	  ye = limit(ye, vc->vc_rows - 1);
+	  ps = ys * vc->vc_size_row + (xs << 1);
+	  pe = ye * vc->vc_size_row + (xe << 1);
 
 	  if (sel_mode == TIOCL_SELCLEAR) {
 	      /* useful for screendump without selection highlights */
@@ -154,9 +156,9 @@
 		pe = tmp;
 	}
 
-	if (sel_cons != fg_console) {
+	if (sel_cons != vc_cons[fg_console].d) {
 		clear_selection();
-		sel_cons = fg_console;
+		sel_cons = vc_cons[fg_console].d;
 	}
 
 	switch (sel_mode)
@@ -173,7 +175,7 @@
 				    (!spc && !inword(sel_pos(ps))))
 					break;
 				new_sel_start = ps;
-				if (!(ps % video_size_row))
+				if (!(ps % vc->vc_size_row))
 					break;
 			}
 			spc = isspace(sel_pos(pe));
@@ -183,14 +185,14 @@
 				    (!spc && !inword(sel_pos(pe))))
 					break;
 				new_sel_end = pe;
-				if (!((pe + 2) % video_size_row))
+				if (!((pe + 2) % vc->vc_size_row))
 					break;
 			}
 			break;
 		case TIOCL_SELLINE:	/* line-by-line selection */
-			new_sel_start = ps - ps % video_size_row;
-			new_sel_end = pe + video_size_row
-				    - pe % video_size_row - 2;
+			new_sel_start = ps - ps % vc->vc_size_row;
+			new_sel_end = pe + vc->vc_size_row
+				    - pe % vc->vc_size_row - 2;
 			break;
 		case TIOCL_SELPOINTER:
 			highlight_pointer(pe);
@@ -204,11 +206,11 @@
 
 	/* select to end of line if on trailing space */
 	if (new_sel_end > new_sel_start &&
-		!atedge(new_sel_end, video_size_row) &&
+		!atedge(new_sel_end, vc->vc_size_row) &&
 		isspace(sel_pos(new_sel_end))) {
 		for (pe = new_sel_end + 2; ; pe += 2)
 			if (!isspace(sel_pos(pe)) ||
-			    atedge(pe, video_size_row))
+			    atedge(pe, vc->vc_size_row))
 				break;
 		if (isspace(sel_pos(pe)))
 			new_sel_end = pe;
@@ -255,7 +257,7 @@
 		*bp = sel_pos(i);
 		if (!isspace(*bp++))
 			obp = bp;
-		if (! ((i + 2) % video_size_row)) {
+		if (! ((i + 2) % vc->vc_size_row)) {
 			/* strip trailing blanks from line and add newline,
 			   unless non-space at end of line. */
 			if (obp != bp) {
diff -Nru a/drivers/char/serial_tx3912.c b/drivers/char/serial_tx3912.c
--- a/drivers/char/serial_tx3912.c	2005-03-01 23:38:57 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,981 +0,0 @@
-/*
- *  drivers/char/serial_tx3912.c
- *
- *  Copyright (C) 1999 Harald Koerfgen
- *  Copyright (C) 2000 Jim Pick <jim@jimpick.com>
- *  Copyright (C) 2001 Steven J. Hill (sjhill@realitydiluted.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.
- *  
- *  Serial driver for TMPR3912/05 and PR31700 processors
- */
-#include <linux/init.h>
-#include <linux/config.h>
-#include <linux/tty.h>
-#include <linux/major.h>
-#include <linux/ptrace.h>
-#include <linux/console.h>
-#include <linux/fs.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <asm/delay.h>
-#include <asm/wbflush.h>
-#include <asm/tx3912.h>
-#include "serial_tx3912.h"
-
-/*
- * Forward declarations for serial routines
- */
-static void rs_disable_tx_interrupts (void * ptr);
-static void rs_enable_tx_interrupts (void * ptr); 
-static void rs_disable_rx_interrupts (void * ptr); 
-static void rs_enable_rx_interrupts (void * ptr); 
-static int rs_get_CD (void * ptr); 
-static void rs_shutdown_port (void * ptr); 
-static int rs_set_real_termios (void *ptr);
-static int rs_chars_in_buffer (void * ptr); 
-
-/*
- * Used by generic serial driver to access hardware
- */
-static struct real_driver rs_real_driver = { 
-	.disable_tx_interrupts = rs_disable_tx_interrupts, 
-	.enable_tx_interrupts  = rs_enable_tx_interrupts, 
-	.disable_rx_interrupts = rs_disable_rx_interrupts, 
-	.enable_rx_interrupts  = rs_enable_rx_interrupts, 
-	.get_CD                = rs_get_CD, 
-	.shutdown_port         = rs_shutdown_port,  
-	.set_real_termios      = rs_set_real_termios,  
-	.chars_in_buffer       = rs_chars_in_buffer, 
-}; 
-
-/*
- * Structures and such for TTY sessions and usage counts
- */
-static struct tty_driver *rs_driver;
-struct rs_port *rs_ports;
-int rs_initialized = 0;
-
-/*
- * ----------------------------------------------------------------------
- *
- * 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.
- *
- * Note: rs_interrupt() is a "fast" interrupt, which means that it
- * runs with interrupts turned off.  People who may want to modify
- * rs_interrupt() should try to keep the interrupt handler as fast as
- * possible.  After you are done making modifications, it is not a bad
- * idea to do:
- * 
- * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c
- *
- * and look at the resulting assemble code in serial.s.
- *
- * 				- Ted Ts'o (tytso@mit.edu), 7-Mar-93
- * -----------------------------------------------------------------------
- */
-static inline void receive_char_pio(struct rs_port *port)
-{
-	struct tty_struct *tty = port->gs.tty;
-	unsigned char ch;
-	int counter = 2048;
-
-	/* While there are characters, get them ... */
-	while (counter>0) {
-		if (!(inl(port->base + TX3912_UART_CTRL1) & UART_RX_HOLD_FULL))
-			break;
-		ch = inb(port->base + TX3912_UART_DATA);
-		if (tty->flip.count < TTY_FLIPBUF_SIZE) {
-			*tty->flip.char_buf_ptr++ = ch;
-			*tty->flip.flag_buf_ptr++ = 0;
-			tty->flip.count++;
-		}
-		udelay(1); /* Allow things to happen - it take a while */
-		counter--;
-	}
-	if (!counter)
-		printk( "Ugh, looped in receive_char_pio!\n" );
-
-	tty_flip_buffer_push(tty);
-
-#if 0
-	/* Now handle error conditions */
-	if (*status & (INTTYPE(UART_RXOVERRUN_INT) |
-			INTTYPE(UART_FRAMEERR_INT) |
-			INTTYPE(UART_PARITYERR_INT) |
-			INTTYPE(UART_BREAK_INT))) {
-
-		/*
-		 * Now check to see if character should be
-		 * ignored, and mask off conditions which
-		 * should be ignored.
-	       	 */
-		if (*status & port->ignore_status_mask) {
-			goto ignore_char;
-		}
-		*status &= port->read_status_mask;
-		
-		if (*status & INTTYPE(UART_BREAK_INT)) {
-			rs_dprintk(TX3912_UART_DEBUG_INTERRUPTS, "handling break....");
-			*tty->flip.flag_buf_ptr = TTY_BREAK;
-		}
-		else if (*status & INTTYPE(UART_PARITYERR_INT)) {
-			*tty->flip.flag_buf_ptr = TTY_PARITY;
-		}
-		else if (*status & INTTYPE(UART_FRAMEERR_INT)) {
-			*tty->flip.flag_buf_ptr = TTY_FRAME;
-		}
-		if (*status & INTTYPE(UART_RXOVERRUN_INT)) {
-			/*
-			 * Overrun is special, since it's
-			 * reported immediately, and doesn't
-			 * affect the current character
-			 */
-			if (tty->flip.count < TTY_FLIPBUF_SIZE) {
-				tty->flip.count++;
-				tty->flip.flag_buf_ptr++;
-				tty->flip.char_buf_ptr++;
-				*tty->flip.flag_buf_ptr = TTY_OVERRUN;
-			}
-		}
-	}
-
-	tty->flip.flag_buf_ptr++;
-	tty->flip.char_buf_ptr++;
-	tty->flip.count++;
-
-ignore_char:
-	tty_flip_buffer_push(tty);
-#endif
-}
-
-static inline void transmit_char_pio(struct rs_port *port)
-{
-	/* While I'm able to transmit ... */
-	for (;;) {
-		if (!(inl(port->base + TX3912_UART_CTRL1) & UART_TX_EMPTY))
-			break;
-		else if (port->x_char) {
-			outb(port->x_char, port->base + TX3912_UART_DATA);
-			port->icount.tx++;
-			port->x_char = 0;
-		}
-		else if (port->gs.xmit_cnt <= 0 || port->gs.tty->stopped ||
-		    port->gs.tty->hw_stopped) {
-			break;
-		}
-		else {
-			outb(port->gs.xmit_buf[port->gs.xmit_tail++],
-				port->base + TX3912_UART_DATA);
-			port->icount.tx++;
-			port->gs.xmit_tail &= SERIAL_XMIT_SIZE-1;
-			if (--port->gs.xmit_cnt <= 0) {
-				break;
-			}
-		}
-		udelay(10); /* Allow things to happen - it take a while */
-	}
-
-	if (port->gs.xmit_cnt <= 0 || port->gs.tty->stopped ||
-	     port->gs.tty->hw_stopped) {
-		rs_disable_tx_interrupts(port);
-	}
-	
-        if (port->gs.xmit_cnt <= port->gs.wakeup_chars) {
-        	tty_wakeup(port->gs.tty);
-                rs_dprintk (TX3912_UART_DEBUG_TRANSMIT, "Waking up.... ldisc (%d)....\n",
-                            port->gs.wakeup_chars); 
-       	}	
-}
-
-
-
-static inline void check_modem_status(struct rs_port *port)
-{
-        /* We don't have a carrier detect line - but just respond
-           like we had one anyways so that open() becomes unblocked */
-	wake_up_interruptible(&port->gs.open_wait);
-}
-
-int count = 0;
-
-/*
- * This is the serial driver's interrupt routine (inlined, because
- * there are two different versions of this, one for each serial port,
- * differing only by the bits used in interrupt status 2 register)
- */
-
-static inline void rs_rx_interrupt(int irq, void *dev_id,
-				  struct pt_regs * regs, int intshift)
-{
-	struct rs_port * port;
-	unsigned long int2status;
-	unsigned long flags;
-	unsigned long ints;
-
-	save_and_cli(flags);
-
-	port = (struct rs_port *)dev_id;
-	rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS, "rs_interrupt (port %p, shift %d)...", port, intshift);
-
-	/* Get the interrrupts we have enabled */
-	int2status = IntStatus2 & IntEnable2;
-
-	/* Get interrupts in easy to use form */
-	ints = int2status >> intshift;
-
-	/* Clear any interrupts we might be about to handle */
-	IntClear2 = int2status & (
-		(INTTYPE(UART_RXOVERRUN_INT) |
-		 INTTYPE(UART_FRAMEERR_INT) |
-		 INTTYPE(UART_BREAK_INT) |
-		 INTTYPE(UART_PARITYERR_INT) |
-		 INTTYPE(UART_RX_INT)) << intshift);
-
-	if (!port || !port->gs.tty) {
-		restore_flags(flags);
-		return;
-	}
-
-	/* RX Receiver Holding Register Overrun */
-	if (ints & INTTYPE(UART_RXOVERRUN_INT)) {
-		rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS, "overrun");
-		port->icount.overrun++;
-	}
-
-	/* RX Frame Error */
-	if (ints & INTTYPE(UART_FRAMEERR_INT)) {
-		rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS, "frame error");
-		port->icount.frame++;
-	}
-
-	/* Break signal received */
-	if (ints & INTTYPE(UART_BREAK_INT)) {
-		rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS, "break");
-		port->icount.brk++;
-      	}
-
-	/* RX Parity Error */
-	if (ints & INTTYPE(UART_PARITYERR_INT)) {
-		rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS, "parity error");
-		port->icount.parity++;
-	}
-
-	/* Receive byte (non-DMA) */
-	if (ints & INTTYPE(UART_RX_INT)) {
-		receive_char_pio(port);
-	}
-
-	restore_flags(flags);
-
-	rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS, "end.\n");
-}
-
-static inline void rs_tx_interrupt(int irq, void *dev_id,
-				  struct pt_regs * regs, int intshift)
-{
-	struct rs_port * port;
-	unsigned long int2status;
-	unsigned long flags;
-	unsigned long ints;
-
-	save_and_cli(flags);
-
-	port = (struct rs_port *)dev_id;
-	rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS, "rs_interrupt (port %p, shift %d)...", port, intshift);
-
-	/* Get the interrrupts we have enabled */
-	int2status = IntStatus2 & IntEnable2;
-
-	if (!port || !port->gs.tty) {
-		restore_flags(flags);
-		return;
-	}
-
-	/* Get interrupts in easy to use form */
-	ints = int2status >> intshift;
-
-	/* Clear any interrupts we might be about to handle */
-	IntClear2 = int2status & (
-		(INTTYPE(UART_TX_INT) |
-		 INTTYPE(UART_EMPTY_INT) |
-		 INTTYPE(UART_TXOVERRUN_INT)) << intshift);
-
-	/* TX holding register empty, so transmit byte (non-DMA) */
-	if (ints & (INTTYPE(UART_TX_INT) | INTTYPE(UART_EMPTY_INT))) {
-		transmit_char_pio(port);
-	}
-
-	/* TX Transmit Holding Register Overrun (shouldn't happen) */
-	if (ints & INTTYPE(UART_TXOVERRUN_INT)) {
-		printk ( "rs: TX overrun\n");
-	}
-
-	/*
-	check_modem_status();
-	*/
-
-	restore_flags(flags);
-
-	rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS, "end.\n");
-}
-
-static void rs_rx_interrupt_uarta(int irq, void *dev_id,
-					 struct pt_regs * regs)
-{
-	rs_rx_interrupt(irq, dev_id, regs, UARTA_SHIFT);
-}
-
-static void rs_tx_interrupt_uarta(int irq, void *dev_id,
-					 struct pt_regs * regs)
-{
-	rs_tx_interrupt(irq, dev_id, regs, UARTA_SHIFT);
-}
-
-/*
- ***********************************************************************
- *                Here are the routines that actually                  *
- *              interface with the generic_serial driver               *
- ***********************************************************************
- */
-static void rs_disable_tx_interrupts (void * ptr) 
-{
-	struct rs_port *port = ptr; 
-	unsigned long flags;
-
-	save_and_cli(flags);
-        port->gs.flags &= ~GS_TX_INTEN;
-
-	IntEnable2 &= ~((INTTYPE(UART_TX_INT) |
-			INTTYPE(UART_EMPTY_INT) |
-			INTTYPE(UART_TXOVERRUN_INT)) << port->intshift);
-
-	IntClear2 = (INTTYPE(UART_TX_INT) |
-			INTTYPE(UART_EMPTY_INT) |
-			INTTYPE(UART_TXOVERRUN_INT)) << port->intshift;
-
-	restore_flags(flags);
-}
-
-static void rs_enable_tx_interrupts (void * ptr) 
-{
-	struct rs_port *port = ptr; 
-	unsigned long flags;
-
-	save_and_cli(flags);
-
-	IntClear2 = (INTTYPE(UART_TX_INT) |
-			INTTYPE(UART_EMPTY_INT) |
-			INTTYPE(UART_TXOVERRUN_INT)) << port->intshift;
-
-	IntEnable2 |= (INTTYPE(UART_TX_INT) |
-			INTTYPE(UART_EMPTY_INT) |
-			INTTYPE(UART_TXOVERRUN_INT)) << port->intshift;
-
-	/* Send a char to start TX interrupts happening */
-	transmit_char_pio(port);
-
-	restore_flags(flags);
-}
-
-static void rs_disable_rx_interrupts (void * ptr) 
-{
-	struct rs_port *port = ptr;
-	unsigned long flags;
-
-	save_and_cli(flags);
-
-	IntEnable2 &= ~((INTTYPE(UART_RX_INT) |
-			 INTTYPE(UART_RXOVERRUN_INT) |
-			 INTTYPE(UART_FRAMEERR_INT) |
-			 INTTYPE(UART_BREAK_INT) |
-			 INTTYPE(UART_PARITYERR_INT)) << port->intshift);
-
-	IntClear2 = (INTTYPE(UART_RX_INT) |
-			 INTTYPE(UART_RXOVERRUN_INT) |
-			 INTTYPE(UART_FRAMEERR_INT) |
-			 INTTYPE(UART_BREAK_INT) |
-			 INTTYPE(UART_PARITYERR_INT)) << port->intshift;
-
-	restore_flags(flags);
-}
-
-static void rs_enable_rx_interrupts (void * ptr) 
-{
-	struct rs_port *port = ptr;
-	unsigned long flags;
-
-	save_and_cli(flags);
-
-	IntEnable2 |= (INTTYPE(UART_RX_INT) |
-			 INTTYPE(UART_RXOVERRUN_INT) |
-			 INTTYPE(UART_FRAMEERR_INT) |
-			 INTTYPE(UART_BREAK_INT) |
-			 INTTYPE(UART_PARITYERR_INT)) << port->intshift;
-
-	/* Empty the input buffer - apparently this is *vital* */
-	while (inl(port->base + TX3912_UART_CTRL1) & UART_RX_HOLD_FULL) { 
-		inb(port->base + TX3912_UART_DATA);
-	}
-
-	IntClear2 = (INTTYPE(UART_RX_INT) |
-			 INTTYPE(UART_RXOVERRUN_INT) |
-			 INTTYPE(UART_FRAMEERR_INT) |
-			 INTTYPE(UART_BREAK_INT) |
-			 INTTYPE(UART_PARITYERR_INT)) << port->intshift;
-
-	restore_flags(flags);
-}
-
-
-static int rs_get_CD (void * ptr) 
-{
-	/* No Carried Detect in Hardware - just return true */
-	func_exit();
-	return (1);
-}
-
-static void rs_shutdown_port (void * ptr) 
-{
-	struct rs_port *port = ptr; 
-
-	func_enter();
-
-	port->gs.flags &= ~GS_ACTIVE;
-
-	func_exit();
-}
-
-static int rs_set_real_termios (void *ptr)
-{
-	struct rs_port *port = ptr;
-	int t;
-
-	switch (port->gs.baud) {
-		/* Save some typing work... */
-#define e(x) case x:t= TX3912_UART_CTRL2_B ## x ; break
-		e(300);e(600);e(1200);e(2400);e(4800);e(9600);
-		e(19200);e(38400);e(57600);e(76800);e(115200);e(230400);
-	case 0      :t = -1;
-		break;
-	default:
-		/* Can I return "invalid"? */
-		t = TX3912_UART_CTRL2_B9600;
-		printk (KERN_INFO "rs: unsupported baud rate: %d.\n", port->gs.baud);
-		break;
-	}
-#undef e
-	if (t >= 0) {
-		/* Jim: Set Hardware Baud rate - there is some good
-		   code in drivers/char/serial.c */
-
-	  	/* Program hardware for parity, data bits, stop bits (note: these are hardcoded to 8N1 */
-		UartA_Ctrl1 &= 0xf000000f;
-		UartA_Ctrl1 &= ~(UART_DIS_TXD | SER_SEVEN_BIT | SER_EVEN_PARITY | SER_TWO_STOP);
-
-#define CFLAG port->gs.tty->termios->c_cflag
-		if (C_PARENB(port->gs.tty)) {
-			if (!C_PARODD(port->gs.tty))
-				UartA_Ctrl1 |= SER_EVEN_PARITY;
-			else
-				UartA_Ctrl1 |= SER_ODD_PARITY;
-		}
-		if ((CFLAG & CSIZE)==CS6)
-			printk(KERN_ERR "6 bits not supported\n");
-		if ((CFLAG & CSIZE)==CS5)
-			printk(KERN_ERR "5 bits not supported\n");
-		if ((CFLAG & CSIZE)==CS7)
-			UartA_Ctrl1 |= SER_SEVEN_BIT;
-		if (C_CSTOPB(port->gs.tty))
-			UartA_Ctrl1 |= SER_TWO_STOP;
-
-		outl(t, port->base + TX3912_UART_CTRL2);
-		outl(0, port->base + TX3912_UART_DMA_CTRL1);
-		outl(0, port->base + TX3912_UART_DMA_CTRL2);
-        	UartA_Ctrl1 |= TX3912_UART_CTRL1_UARTON;
-
-        /* wait until UARTA is stable */
-        while (~UartA_Ctrl1 & TX3912_UART_CTRL1_UARTON);
-	}
-
-	func_exit ();
-        return 0;
-}
-
-static int rs_chars_in_buffer (void * ptr) 
-{
-	struct rs_port *port = ptr;
-	int scratch;
-
-	scratch = inl(port->base + TX3912_UART_CTRL1);
-
-	return ((scratch & UART_TX_EMPTY) ? 0 : 1);
-}
-
-/* ********************************************************************** *
- *                Here are the routines that actually                     *
- *               interface with the rest of the system                    *
- * ********************************************************************** */
-static int rs_open  (struct tty_struct * tty, struct file * filp)
-{
-	struct rs_port *port;
-	int retval, line;
-
-	func_enter();
-
-	if (!rs_initialized) {
-		return -EIO;
-	}
-
-	line = tty->index;
-	rs_dprintk (TX3912_UART_DEBUG_OPEN, "%d: opening line %d. tty=%p ctty=%p)\n", 
-	            (int) current->pid, line, tty, current->tty);
-
-	if ((line < 0) || (line >= TX3912_UART_NPORTS))
-		return -ENODEV;
-
-	/* Pre-initialized already */
-	port = & rs_ports[line];
-
-	rs_dprintk (TX3912_UART_DEBUG_OPEN, "port = %p\n", port);
-
-	tty->driver_data = port;
-	port->gs.tty = tty;
-	port->gs.count++;
-
-	rs_dprintk (TX3912_UART_DEBUG_OPEN, "starting port\n");
-
-	/*
-	 * Start up serial port
-	 */
-	retval = gs_init_port(&port->gs);
-	rs_dprintk (TX3912_UART_DEBUG_OPEN, "done gs_init\n");
-	if (retval) {
-		port->gs.count--;
-		return retval;
-	}
-
-	port->gs.flags |= GS_ACTIVE;
-
-	rs_dprintk (TX3912_UART_DEBUG_OPEN, "before inc_use_count (count=%d.\n", 
-	            port->gs.count);
-	rs_dprintk (TX3912_UART_DEBUG_OPEN, "after inc_use_count\n");
-
-	/* Jim: Initialize port hardware here */
-
-	/* Enable high-priority interrupts for UARTA */
-	IntEnable6 |= INT6_UARTARXINT; 
-	rs_enable_rx_interrupts(&rs_ports[0]); 
-
-	retval = gs_block_til_ready(&port->gs, filp);
-	rs_dprintk (TX3912_UART_DEBUG_OPEN, "Block til ready returned %d. Count=%d\n", 
-	            retval, port->gs.count);
-
-	if (retval) {
-		port->gs.count--;
-		return retval;
-	}
-	/* tty->low_latency = 1; */
-
-	func_exit();
-
-	/* Jim */
-/*	cli(); */
-
-	return 0;
-
-}
-
-
-static int rs_ioctl (struct tty_struct * tty, struct file * filp, 
-                     unsigned int cmd, unsigned long arg)
-{
-	int rc;
-	struct rs_port *port = tty->driver_data;
-	int ival;
-
-	rc = 0;
-	switch (cmd) {
-	case TIOCGSOFTCAR:
-		rc = put_user(((tty->termios->c_cflag & CLOCAL) ? 1 : 0),
-		              (unsigned int *) arg);
-		break;
-	case TIOCSSOFTCAR:
-		if ((rc = get_user(ival, (unsigned int *) arg)) == 0) {
-			tty->termios->c_cflag =
-				(tty->termios->c_cflag & ~CLOCAL) |
-				(ival ? CLOCAL : 0);
-		}
-		break;
-	case TIOCGSERIAL:
-		if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
-		                      sizeof(struct serial_struct))) == 0)
-			rc = gs_getserial(&port->gs, (struct serial_struct *) arg);
-		break;
-	case TIOCSSERIAL:
-		if ((rc = verify_area(VERIFY_READ, (void *) arg,
-		                      sizeof(struct serial_struct))) == 0)
-			rc = gs_setserial(&port->gs, (struct serial_struct *) arg);
-		break;
-	default:
-		rc = -ENOIOCTLCMD;
-		break;
-	}
-
-	/* func_exit(); */
-	return rc;
-}
-
-
-/*
- * This function is used to send a high-priority XON/XOFF character to
- * the device
- */
-static void rs_send_xchar(struct tty_struct * tty, char ch)
-{
-	struct rs_port *port = (struct rs_port *)tty->driver_data;
-	func_enter ();
-	
-	port->x_char = ch;
-	if (ch) {
-		/* Make sure transmit interrupts are on */
-		rs_enable_tx_interrupts(tty);
-	}
-
-	func_exit();
-}
-
-
-/*
- * ------------------------------------------------------------
- * 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)
-{
-#ifdef TX3912_UART_DEBUG_THROTTLE
-	char	buf[64];
-	
-	printk("throttle %s: %d....\n", tty_name(tty, buf),
-	       tty->ldisc.chars_in_buffer(tty));
-#endif
-
-	func_enter ();
-	
-	if (I_IXOFF(tty))
-		rs_send_xchar(tty, STOP_CHAR(tty));
-
-	func_exit ();
-}
-
-static void rs_unthrottle(struct tty_struct * tty)
-{
-	struct rs_port *port = (struct rs_port *)tty->driver_data;
-#ifdef TX3912_UART_DEBUG_THROTTLE
-	char	buf[64];
-	
-	printk("unthrottle %s: %d....\n", tty_name(tty, buf),
-	       tty->ldisc.chars_in_buffer(tty));
-#endif
-
-	func_enter();
-	
-	if (I_IXOFF(tty)) {
-		if (port->x_char)
-			port->x_char = 0;
-		else
-			rs_send_xchar(tty, START_CHAR(tty));
-	}
-
-	func_exit();
-}
-
-
-
-
-
-/* ********************************************************************** *
- *                    Here are the initialization routines.               *
- * ********************************************************************** */
-
-void * ckmalloc (int size)
-{
-        void *p;
-
-        p = kmalloc(size, GFP_KERNEL);
-        if (p) 
-                memset(p, 0, size);
-        return p;
-}
-
-
-
-static int rs_init_portstructs(void)
-{
-	struct rs_port *port;
-	int i;
-
-	/* Debugging */
-	func_enter();
-
-	rs_ports          = ckmalloc(TX3912_UART_NPORTS * sizeof (struct rs_port));
-	if (!rs_ports)
-		return -ENOMEM;
-
-	port = rs_ports;
-	for (i=0; i < TX3912_UART_NPORTS;i++) {
-		rs_dprintk (TX3912_UART_DEBUG_INIT, "initing port %d\n", i);
-		port->gs.magic = SERIAL_MAGIC;
-		port->gs.close_delay = HZ/2;
-		port->gs.closing_wait = 30 * HZ;
-		port->gs.rd = &rs_real_driver;
-#ifdef NEW_WRITE_LOCKING
-		port->gs.port_write_sem = MUTEX;
-#endif
-#ifdef DECLARE_WAITQUEUE
-		init_waitqueue_head(&port->gs.open_wait);
-		init_waitqueue_head(&port->gs.close_wait);
-#endif
-		port->base = (i == 0) ? TX3912_UARTA_BASE : TX3912_UARTB_BASE;
-		port->intshift = (i == 0) ? UARTA_SHIFT : UARTB_SHIFT;
-		rs_dprintk (TX3912_UART_DEBUG_INIT, "base 0x%08lx intshift %d\n",
-			    port->base, port->intshift);
-		port++;
-	}
-
-	func_exit();
-	return 0;
-}
-
-static struct tty_operations rs_ops = {
-	.open	= rs_open,
-	.close = gs_close,
-	.write = gs_write,
-	.put_char = gs_put_char, 
-	.flush_chars = gs_flush_chars,
-	.write_room = gs_write_room,
-	.chars_in_buffer = gs_chars_in_buffer,
-	.flush_buffer = gs_flush_buffer,
-	.ioctl = rs_ioctl,
-	.throttle = rs_throttle,
-	.unthrottle = rs_unthrottle,
-	.set_termios = gs_set_termios,
-	.stop = gs_stop,
-	.start = gs_start,
-	.hangup = gs_hangup,
-};
-
-static int rs_init_drivers(void)
-{
-	int error;
-
-	func_enter();
-
-	rs_driver = alloc_tty_driver(TX3912_UART_NPORTS);
-	if (!rs_driver)
-		return -ENOMEM;
-	rs_driver->owner = THIS_MODULE;
-	rs_driver->driver_name = "serial";
-	rs_driver->name = "ttyS";
-	rs_driver->major = TTY_MAJOR;
-	rs_driver->minor_start = 64;
-	rs_driver->type = TTY_DRIVER_TYPE_SERIAL;
-	rs_driver->subtype = SERIAL_TYPE_NORMAL;
-	rs_driver->init_termios = tty_std_termios;
-	rs_driver->init_termios.c_cflag =
-		B115200 | CS8 | CREAD | HUPCL | CLOCAL;
-	tty_set_operations(rs_driver, &rs_ops);
-	if ((error = tty_register_driver(rs_driver))) {
-		printk(KERN_ERR "Couldn't register serial driver, error = %d\n",
-		       error);
-		put_tty_driver(rs_driver);
-		return 1;
-	}
-	return 0;
-}
-
-
-static void __init tx3912_rs_init(void)
-{
-	int rc;
-
-
-	func_enter();
-	rs_dprintk (TX3912_UART_DEBUG_INIT, "Initing serial module... (rs_debug=%d)\n", rs_debug);
-
-	rc = rs_init_portstructs ();
-	rs_init_drivers ();
-	if (request_irq(2, rs_tx_interrupt_uarta, SA_SHIRQ | SA_INTERRUPT,
-			"serial", &rs_ports[0])) {
-		printk(KERN_ERR "rs: Cannot allocate irq for UARTA.\n");
-		rc = 0;
-	}
-	if (request_irq(3, rs_rx_interrupt_uarta, SA_SHIRQ | SA_INTERRUPT,
-			"serial", &rs_ports[0])) {
-		printk(KERN_ERR "rs: Cannot allocate irq for UARTA.\n");
-		rc = 0;
-	}
-
-	IntEnable6 |= INT6_UARTARXINT; 
-	rs_enable_rx_interrupts(&rs_ports[0]); 
-
-#ifndef CONFIG_SERIAL_TX3912_CONSOLE
-{
-	unsigned int scratch = 0;
-
-	/* Setup master clock for UART */
-	scratch = inl(TX3912_CLK_CTRL_BASE);
-	scratch &= ~TX3912_CLK_CTRL_SIBMCLKDIV_MASK;
-	scratch |= ((0x2 << TX3912_CLK_CTRL_SIBMCLKDIV_SHIFT) &
-				TX3912_CLK_CTRL_SIBMCLKDIV_MASK)
-			| TX3912_CLK_CTRL_SIBMCLKDIR
-			| TX3912_CLK_CTRL_ENSIBMCLK
-			| TX3912_CLK_CTRL_CSERSEL;
-	outl(scratch, TX3912_CLK_CTRL_BASE);
-
-	/* Configure UARTA clock */
-	scratch = inl(TX3912_CLK_CTRL_BASE);
-	scratch |= ((0x3 << TX3912_CLK_CTRL_CSERDIV_SHIFT) &
-				TX3912_CLK_CTRL_CSERDIV_MASK)
-			| TX3912_CLK_CTRL_ENCSERCLK
-			| TX3912_CLK_CTRL_ENUARTACLK;
-	outl(scratch, TX3912_CLK_CTRL_BASE);
-		
-	/* Setup UARTA for 115200,8N1 */
-	outl(0, TX3912_UARTA_BASE + TX3912_UART_CTRL1);
-	outl(TX3912_UART_CTRL2_B115200, TX3912_UARTA_BASE + TX3912_UART_CTRL2);
-	outl(0, TX3912_UARTA_BASE + TX3912_UART_DMA_CTRL1);
-	outl(0, TX3912_UARTA_BASE + TX3912_UART_DMA_CTRL2);
-
-	/* Enable UARTA */
-	outl(TX3912_UART_CTRL1_ENUART, TX3912_UARTA_BASE + TX3912_UART_CTRL1);
-	while (~inl(TX3912_UARTA_BASE + TX3912_UART_CTRL1) &
-		TX3912_UART_CTRL1_UARTON);
-}
-#endif
-
-	/* Note: I didn't do anything to enable the second UART */
-	if (rc >= 0) 
-		rs_initialized++;
-
-	func_exit();
-}
-module_init(tx3912_rs_init);
-
-/*
- * Begin serial console routines
- */
-#ifdef CONFIG_SERIAL_TX3912_CONSOLE
-
-void serial_outc(unsigned char c)
-{
-	int i;
-	unsigned long int2;
-	#define BUSY_WAIT 10000
-
-	/*
-	 * Turn UARTA interrupts off
-	 */
-	int2 = IntEnable2;
-	IntEnable2 &=
-		~(INT2_UARTATXINT | INT2_UARTATXOVERRUN | INT2_UARTAEMPTY);
-
-	/*
-	 * The UART_TX_EMPTY bit in UartA_Ctrl1 seems
-	 * not to be very reliable :-(
-	 *
-	 * Wait for the Tx register to become empty
-	 */
-	for (i = 0; !(IntStatus2 & INT2_UARTATXINT) && (i < BUSY_WAIT); i++);
-
-	IntClear2 = INT2_UARTATXINT | INT2_UARTATXOVERRUN | INT2_UARTAEMPTY;
-	UartA_Data = c;
-	for (i = 0; !(IntStatus2 & INT2_UARTATXINT) && (i < BUSY_WAIT); i++);
-	IntClear2 = INT2_UARTATXINT | INT2_UARTATXOVERRUN | INT2_UARTAEMPTY;
-
-	IntEnable2 = int2;
-}
-
-static void serial_console_write(struct console *co, const char *s,
-		unsigned count)
-{
-    	unsigned int i;
-
-	for (i = 0; i < count; i++) {
-		if (*s == '\n')
-			serial_outc('\r');
-		serial_outc(*s++);
-    	}
-}
-
-static struct tty_driver *serial_console_device(struct console *c, int *index)
-{
-	*index = c->index;
-	return rs_driver;
-}
-
-static __init int serial_console_setup(struct console *co, char *options)
-{
-	unsigned int scratch = 0;
-
-	/* Setup master clock for UART */
-	scratch = inl(TX3912_CLK_CTRL_BASE);
-	scratch &= ~TX3912_CLK_CTRL_SIBMCLKDIV_MASK;
-	scratch |= ((0x2 << TX3912_CLK_CTRL_SIBMCLKDIV_SHIFT) &
-				TX3912_CLK_CTRL_SIBMCLKDIV_MASK)
-			| TX3912_CLK_CTRL_SIBMCLKDIR
-			| TX3912_CLK_CTRL_ENSIBMCLK
-			| TX3912_CLK_CTRL_CSERSEL;
-	outl(scratch, TX3912_CLK_CTRL_BASE);
-
-	/* Configure UARTA clock */
-	scratch = inl(TX3912_CLK_CTRL_BASE);
-	scratch |= ((0x3 << TX3912_CLK_CTRL_CSERDIV_SHIFT) &
-				TX3912_CLK_CTRL_CSERDIV_MASK)
-			| TX3912_CLK_CTRL_ENCSERCLK
-			| TX3912_CLK_CTRL_ENUARTACLK;
-	outl(scratch, TX3912_CLK_CTRL_BASE);
-		
-	/* Setup UARTA for 115200,8N1 */
-	outl(0, TX3912_UARTA_BASE + TX3912_UART_CTRL1);
-	outl(TX3912_UART_CTRL2_B115200, TX3912_UARTA_BASE + TX3912_UART_CTRL2);
-	outl(0, TX3912_UARTA_BASE + TX3912_UART_DMA_CTRL1);
-	outl(0, TX3912_UARTA_BASE + TX3912_UART_DMA_CTRL2);
-
-	/* Enable UARTA */
-	outl(TX3912_UART_CTRL1_ENUART, TX3912_UARTA_BASE + TX3912_UART_CTRL1);
-	while (~inl(TX3912_UARTA_BASE + TX3912_UART_CTRL1) &
-		TX3912_UART_CTRL1_UARTON);
-
-	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
-};
-
-static int __init tx3912_console_init(void)
-{
-	register_console(&sercons);
-	return 0;
-}
-console_initcall(tx3912_console_init);
-
-#endif
diff -Nru a/drivers/char/serial_tx3912.h b/drivers/char/serial_tx3912.h
--- a/drivers/char/serial_tx3912.h	2005-03-01 23:39:08 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,92 +0,0 @@
-/*
- *  drivers/char/serial_tx3912.h
- *
- *  Copyright (C) 1999 Harald Koerfgen
- *  Copyright (C) 2000 Jim Pick <jim@jimpick.com>
- *  Copyright (C) 2001 Steven J. Hill (sjhill@realitydiluted.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.
- *
- *  Serial driver for TMPR3912/05 and PR31700 processors
- */
-#include <linux/serialP.h>
-#include <linux/generic_serial.h>
-
-/* UART Interrupt (Interrupt 2) bits (UARTA,UARTB) */
-#define UART_RX_INT         9  /* receiver holding register full  (31, 21) */
-#define UART_RXOVERRUN_INT  8  /* receiver overrun error          (30, 20) */
-#define UART_FRAMEERR_INT   7  /* receiver frame error            (29, 19) */
-#define UART_BREAK_INT      6  /* received break signal           (28, 18) */
-#define UART_PARITYERR_INT  5  /* receiver parity error           (27, 17) */
-#define UART_TX_INT         4  /* transmit holding register empty (26, 16) */
-#define UART_TXOVERRUN_INT  3  /* transmit overrun error          (25, 15) */
-#define UART_EMPTY_INT      2  /* both trans/recv regs empty      (24, 14) */
-#define UART_DMAFULL_INT    1  /* DMA at end of buffer            (23, 13) */
-#define UART_DMAHALF_INT    0  /* DMA halfway through buffer      (22, 12) */
-
-#define UARTA_SHIFT        22
-#define UARTB_SHIFT        12
-
-#define INTTYPE(interrupttype)            (1 << interrupttype)
-
-/* 
- * This driver can spew a whole lot of debugging output at you. If you
- * need maximum performance, you should disable the DEBUG define.
- */
-#undef TX3912_UART_DEBUG
-
-#ifdef TX3912_UART_DEBUG
-#define TX3912_UART_DEBUG_OPEN		0x00000001
-#define TX3912_UART_DEBUG_SETTING	0x00000002
-#define TX3912_UART_DEBUG_FLOW		0x00000004
-#define TX3912_UART_DEBUG_MODEMSIGNALS	0x00000008
-#define TX3912_UART_DEBUG_TERMIOS	0x00000010
-#define TX3912_UART_DEBUG_TRANSMIT	0x00000020
-#define TX3912_UART_DEBUG_RECEIVE	0x00000040
-#define TX3912_UART_DEBUG_INTERRUPTS	0x00000080
-#define TX3912_UART_DEBUG_PROBE		0x00000100
-#define TX3912_UART_DEBUG_INIT		0x00000200
-#define TX3912_UART_DEBUG_CLEANUP	0x00000400
-#define TX3912_UART_DEBUG_CLOSE		0x00000800
-#define TX3912_UART_DEBUG_FIRMWARE	0x00001000
-#define TX3912_UART_DEBUG_MEMTEST	0x00002000
-#define TX3912_UART_DEBUG_THROTTLE	0x00004000
-#define TX3912_UART_DEBUG_ALL		0xffffffff
-
-int rs_debug = TX3912_UART_DEBUG_ALL & ~TX3912_UART_DEBUG_TRANSMIT;
-
-#define rs_dprintk(f, str...) if (rs_debug & f) printk (str)
-#define func_enter() rs_dprintk (TX3912_UART_DEBUG_FLOW,	\
-				"rs: enter %s\n", __FUNCTION__)
-#define func_exit() rs_dprintk (TX3912_UART_DEBUG_FLOW,	\
-				"rs: exit %s\n", __FUNCTION__)
-
-#else
-#define rs_dprintk(f, str...)
-#define func_enter()
-#define func_exit()
-
-#endif	/* TX3912_UART_DEBUG */
-
-/*
- * Number of serial ports
- */
-#define TX3912_UART_NPORTS  2
-
-/*
- * Hardware specific serial port structure
- */
-struct rs_port { 	
-	struct gs_port		gs;		/* Must be first field! */
-
-	unsigned long		base;
-	int			intshift;	/* Register shift */
-	struct wait_queue	*shutdown_wait; 
-	int			stat_flags;
-        struct async_icount	icount;		/* Counters for 4 input IRQs */
-	int			read_status_mask;
-	int			ignore_status_mask;
-	int			x_char;		/* XON/XOFF character */
-}; 
diff -Nru a/drivers/char/sonypi.c b/drivers/char/sonypi.c
--- a/drivers/char/sonypi.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/char/sonypi.c	2005-03-01 23:39:08 -08:00
@@ -1,7 +1,9 @@
 /*
  * Sony Programmable I/O Control Device driver for VAIO
  *
- * Copyright (C) 2001-2004 Stelian Pop <stelian@popies.net>
+ * Copyright (C) 2001-2005 Stelian Pop <stelian@popies.net>
+ *
+ * Copyright (C) 2005 Narayanan R S <nars@kadamba.org>
  *
  * Copyright (C) 2001-2002 Alcôve <www.alcove.com>
  *
@@ -45,14 +47,16 @@
 #include <linux/acpi.h>
 #include <linux/dmi.h>
 #include <linux/err.h>
+#include <linux/kfifo.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
 #include <asm/system.h>
 
-#include "sonypi.h"
 #include <linux/sonypi.h>
 
+#define SONYPI_DRIVER_VERSION	 "1.26"
+
 MODULE_AUTHOR("Stelian Pop <stelian@popies.net>");
 MODULE_DESCRIPTION("Sony Programmable I/O Control Device driver");
 MODULE_LICENSE("GPL");
@@ -92,7 +96,390 @@
 MODULE_PARM_DESC(useinput,
 		 "set this if you would like sonypi to feed events to the input subsystem");
 
-static struct sonypi_device sonypi_device;
+#define SONYPI_DEVICE_MODEL_TYPE1	1
+#define SONYPI_DEVICE_MODEL_TYPE2	2
+
+/* type1 models use those */
+#define SONYPI_IRQ_PORT			0x8034
+#define SONYPI_IRQ_SHIFT		22
+#define SONYPI_BASE			0x50
+#define SONYPI_G10A			(SONYPI_BASE+0x14)
+#define SONYPI_TYPE1_REGION_SIZE	0x08
+#define SONYPI_TYPE1_EVTYPE_OFFSET	0x04
+
+/* type2 series specifics */
+#define SONYPI_SIRQ			0x9b
+#define SONYPI_SLOB			0x9c
+#define SONYPI_SHIB			0x9d
+#define SONYPI_TYPE2_REGION_SIZE	0x20
+#define SONYPI_TYPE2_EVTYPE_OFFSET	0x12
+
+/* battery / brightness addresses */
+#define SONYPI_BAT_FLAGS	0x81
+#define SONYPI_LCD_LIGHT	0x96
+#define SONYPI_BAT1_PCTRM	0xa0
+#define SONYPI_BAT1_LEFT	0xa2
+#define SONYPI_BAT1_MAXRT	0xa4
+#define SONYPI_BAT2_PCTRM	0xa8
+#define SONYPI_BAT2_LEFT	0xaa
+#define SONYPI_BAT2_MAXRT	0xac
+#define SONYPI_BAT1_MAXTK	0xb0
+#define SONYPI_BAT1_FULL	0xb2
+#define SONYPI_BAT2_MAXTK	0xb8
+#define SONYPI_BAT2_FULL	0xba
+
+/* FAN0 information (reverse engineered from ACPI tables) */
+#define SONYPI_FAN0_STATUS	0x93
+#define SONYPI_TEMP_STATUS	0xC1
+
+/* ioports used for brightness and type2 events */
+#define SONYPI_DATA_IOPORT	0x62
+#define SONYPI_CST_IOPORT	0x66
+
+/* The set of possible ioports */
+struct sonypi_ioport_list {
+	u16	port1;
+	u16	port2;
+};
+
+static struct sonypi_ioport_list sonypi_type1_ioport_list[] = {
+	{ 0x10c0, 0x10c4 },	/* looks like the default on C1Vx */
+	{ 0x1080, 0x1084 },
+	{ 0x1090, 0x1094 },
+	{ 0x10a0, 0x10a4 },
+	{ 0x10b0, 0x10b4 },
+	{ 0x0, 0x0 }
+};
+
+static struct sonypi_ioport_list sonypi_type2_ioport_list[] = {
+	{ 0x1080, 0x1084 },
+	{ 0x10a0, 0x10a4 },
+	{ 0x10c0, 0x10c4 },
+	{ 0x10e0, 0x10e4 },
+	{ 0x0, 0x0 }
+};
+
+/* The set of possible interrupts */
+struct sonypi_irq_list {
+	u16	irq;
+	u16	bits;
+};
+
+static struct sonypi_irq_list sonypi_type1_irq_list[] = {
+	{ 11, 0x2 },	/* IRQ 11, GO22=0,GO23=1 in AML */
+	{ 10, 0x1 },	/* IRQ 10, GO22=1,GO23=0 in AML */
+	{  5, 0x0 },	/* IRQ  5, GO22=0,GO23=0 in AML */
+	{  0, 0x3 }	/* no IRQ, GO22=1,GO23=1 in AML */
+};
+
+static struct sonypi_irq_list sonypi_type2_irq_list[] = {
+	{ 11, 0x80 },	/* IRQ 11, 0x80 in SIRQ in AML */
+	{ 10, 0x40 },	/* IRQ 10, 0x40 in SIRQ in AML */
+	{  9, 0x20 },	/* IRQ  9, 0x20 in SIRQ in AML */
+	{  6, 0x10 },	/* IRQ  6, 0x10 in SIRQ in AML */
+	{  0, 0x00 }	/* no IRQ, 0x00 in SIRQ in AML */
+};
+
+#define SONYPI_CAMERA_BRIGHTNESS		0
+#define SONYPI_CAMERA_CONTRAST			1
+#define SONYPI_CAMERA_HUE			2
+#define SONYPI_CAMERA_COLOR			3
+#define SONYPI_CAMERA_SHARPNESS			4
+
+#define SONYPI_CAMERA_PICTURE			5
+#define SONYPI_CAMERA_EXPOSURE_MASK		0xC
+#define SONYPI_CAMERA_WHITE_BALANCE_MASK	0x3
+#define SONYPI_CAMERA_PICTURE_MODE_MASK		0x30
+#define SONYPI_CAMERA_MUTE_MASK			0x40
+
+/* the rest don't need a loop until not 0xff */
+#define SONYPI_CAMERA_AGC			6
+#define SONYPI_CAMERA_AGC_MASK			0x30
+#define SONYPI_CAMERA_SHUTTER_MASK 		0x7
+
+#define SONYPI_CAMERA_SHUTDOWN_REQUEST		7
+#define SONYPI_CAMERA_CONTROL			0x10
+
+#define SONYPI_CAMERA_STATUS 			7
+#define SONYPI_CAMERA_STATUS_READY 		0x2
+#define SONYPI_CAMERA_STATUS_POSITION		0x4
+
+#define SONYPI_DIRECTION_BACKWARDS 		0x4
+
+#define SONYPI_CAMERA_REVISION 			8
+#define SONYPI_CAMERA_ROMVERSION 		9
+
+/* Event masks */
+#define SONYPI_JOGGER_MASK			0x00000001
+#define SONYPI_CAPTURE_MASK			0x00000002
+#define SONYPI_FNKEY_MASK			0x00000004
+#define SONYPI_BLUETOOTH_MASK			0x00000008
+#define SONYPI_PKEY_MASK			0x00000010
+#define SONYPI_BACK_MASK			0x00000020
+#define SONYPI_HELP_MASK			0x00000040
+#define SONYPI_LID_MASK				0x00000080
+#define SONYPI_ZOOM_MASK			0x00000100
+#define SONYPI_THUMBPHRASE_MASK			0x00000200
+#define SONYPI_MEYE_MASK			0x00000400
+#define SONYPI_MEMORYSTICK_MASK			0x00000800
+#define SONYPI_BATTERY_MASK			0x00001000
+
+struct sonypi_event {
+	u8	data;
+	u8	event;
+};
+
+/* The set of possible button release events */
+static struct sonypi_event sonypi_releaseev[] = {
+	{ 0x00, SONYPI_EVENT_ANYBUTTON_RELEASED },
+	{ 0, 0 }
+};
+
+/* The set of possible jogger events  */
+static struct sonypi_event sonypi_joggerev[] = {
+	{ 0x1f, SONYPI_EVENT_JOGDIAL_UP },
+	{ 0x01, SONYPI_EVENT_JOGDIAL_DOWN },
+	{ 0x5f, SONYPI_EVENT_JOGDIAL_UP_PRESSED },
+	{ 0x41, SONYPI_EVENT_JOGDIAL_DOWN_PRESSED },
+	{ 0x1e, SONYPI_EVENT_JOGDIAL_FAST_UP },
+	{ 0x02, SONYPI_EVENT_JOGDIAL_FAST_DOWN },
+	{ 0x5e, SONYPI_EVENT_JOGDIAL_FAST_UP_PRESSED },
+	{ 0x42, SONYPI_EVENT_JOGDIAL_FAST_DOWN_PRESSED },
+	{ 0x1d, SONYPI_EVENT_JOGDIAL_VFAST_UP },
+	{ 0x03, SONYPI_EVENT_JOGDIAL_VFAST_DOWN },
+	{ 0x5d, SONYPI_EVENT_JOGDIAL_VFAST_UP_PRESSED },
+	{ 0x43, SONYPI_EVENT_JOGDIAL_VFAST_DOWN_PRESSED },
+	{ 0x40, SONYPI_EVENT_JOGDIAL_PRESSED },
+	{ 0, 0 }
+};
+
+/* The set of possible capture button events */
+static struct sonypi_event sonypi_captureev[] = {
+	{ 0x05, SONYPI_EVENT_CAPTURE_PARTIALPRESSED },
+	{ 0x07, SONYPI_EVENT_CAPTURE_PRESSED },
+	{ 0x01, SONYPI_EVENT_CAPTURE_PARTIALRELEASED },
+	{ 0, 0 }
+};
+
+/* The set of possible fnkeys events */
+static struct sonypi_event sonypi_fnkeyev[] = {
+	{ 0x10, SONYPI_EVENT_FNKEY_ESC },
+	{ 0x11, SONYPI_EVENT_FNKEY_F1 },
+	{ 0x12, SONYPI_EVENT_FNKEY_F2 },
+	{ 0x13, SONYPI_EVENT_FNKEY_F3 },
+	{ 0x14, SONYPI_EVENT_FNKEY_F4 },
+	{ 0x15, SONYPI_EVENT_FNKEY_F5 },
+	{ 0x16, SONYPI_EVENT_FNKEY_F6 },
+	{ 0x17, SONYPI_EVENT_FNKEY_F7 },
+	{ 0x18, SONYPI_EVENT_FNKEY_F8 },
+	{ 0x19, SONYPI_EVENT_FNKEY_F9 },
+	{ 0x1a, SONYPI_EVENT_FNKEY_F10 },
+	{ 0x1b, SONYPI_EVENT_FNKEY_F11 },
+	{ 0x1c, SONYPI_EVENT_FNKEY_F12 },
+	{ 0x1f, SONYPI_EVENT_FNKEY_RELEASED },
+	{ 0x21, SONYPI_EVENT_FNKEY_1 },
+	{ 0x22, SONYPI_EVENT_FNKEY_2 },
+	{ 0x31, SONYPI_EVENT_FNKEY_D },
+	{ 0x32, SONYPI_EVENT_FNKEY_E },
+	{ 0x33, SONYPI_EVENT_FNKEY_F },
+	{ 0x34, SONYPI_EVENT_FNKEY_S },
+	{ 0x35, SONYPI_EVENT_FNKEY_B },
+	{ 0x36, SONYPI_EVENT_FNKEY_ONLY },
+	{ 0, 0 }
+};
+
+/* The set of possible program key events */
+static struct sonypi_event sonypi_pkeyev[] = {
+	{ 0x01, SONYPI_EVENT_PKEY_P1 },
+	{ 0x02, SONYPI_EVENT_PKEY_P2 },
+	{ 0x04, SONYPI_EVENT_PKEY_P3 },
+	{ 0x5c, SONYPI_EVENT_PKEY_P1 },
+	{ 0, 0 }
+};
+
+/* The set of possible bluetooth events */
+static struct sonypi_event sonypi_blueev[] = {
+	{ 0x55, SONYPI_EVENT_BLUETOOTH_PRESSED },
+	{ 0x59, SONYPI_EVENT_BLUETOOTH_ON },
+	{ 0x5a, SONYPI_EVENT_BLUETOOTH_OFF },
+	{ 0, 0 }
+};
+
+/* The set of possible back button events */
+static struct sonypi_event sonypi_backev[] = {
+	{ 0x20, SONYPI_EVENT_BACK_PRESSED },
+	{ 0, 0 }
+};
+
+/* The set of possible help button events */
+static struct sonypi_event sonypi_helpev[] = {
+	{ 0x3b, SONYPI_EVENT_HELP_PRESSED },
+	{ 0, 0 }
+};
+
+
+/* The set of possible lid events */
+static struct sonypi_event sonypi_lidev[] = {
+	{ 0x51, SONYPI_EVENT_LID_CLOSED },
+	{ 0x50, SONYPI_EVENT_LID_OPENED },
+	{ 0, 0 }
+};
+
+/* The set of possible zoom events */
+static struct sonypi_event sonypi_zoomev[] = {
+	{ 0x39, SONYPI_EVENT_ZOOM_PRESSED },
+	{ 0, 0 }
+};
+
+/* The set of possible thumbphrase events */
+static struct sonypi_event sonypi_thumbphraseev[] = {
+	{ 0x3a, SONYPI_EVENT_THUMBPHRASE_PRESSED },
+	{ 0, 0 }
+};
+
+/* The set of possible motioneye camera events */
+static struct sonypi_event sonypi_meyeev[] = {
+	{ 0x00, SONYPI_EVENT_MEYE_FACE },
+	{ 0x01, SONYPI_EVENT_MEYE_OPPOSITE },
+	{ 0, 0 }
+};
+
+/* The set of possible memorystick events */
+static struct sonypi_event sonypi_memorystickev[] = {
+	{ 0x53, SONYPI_EVENT_MEMORYSTICK_INSERT },
+	{ 0x54, SONYPI_EVENT_MEMORYSTICK_EJECT },
+	{ 0, 0 }
+};
+
+/* The set of possible battery events */
+static struct sonypi_event sonypi_batteryev[] = {
+	{ 0x20, SONYPI_EVENT_BATTERY_INSERT },
+	{ 0x30, SONYPI_EVENT_BATTERY_REMOVE },
+	{ 0, 0 }
+};
+
+static struct sonypi_eventtypes {
+	int			model;
+	u8			data;
+	unsigned long		mask;
+	struct sonypi_event *	events;
+} sonypi_eventtypes[] = {
+	{ SONYPI_DEVICE_MODEL_TYPE1, 0, 0xffffffff, sonypi_releaseev },
+	{ SONYPI_DEVICE_MODEL_TYPE1, 0x70, SONYPI_MEYE_MASK, sonypi_meyeev },
+	{ SONYPI_DEVICE_MODEL_TYPE1, 0x30, SONYPI_LID_MASK, sonypi_lidev },
+	{ SONYPI_DEVICE_MODEL_TYPE1, 0x60, SONYPI_CAPTURE_MASK, sonypi_captureev },
+	{ SONYPI_DEVICE_MODEL_TYPE1, 0x10, SONYPI_JOGGER_MASK, sonypi_joggerev },
+	{ SONYPI_DEVICE_MODEL_TYPE1, 0x20, SONYPI_FNKEY_MASK, sonypi_fnkeyev },
+	{ SONYPI_DEVICE_MODEL_TYPE1, 0x30, SONYPI_BLUETOOTH_MASK, sonypi_blueev },
+	{ SONYPI_DEVICE_MODEL_TYPE1, 0x40, SONYPI_PKEY_MASK, sonypi_pkeyev },
+	{ SONYPI_DEVICE_MODEL_TYPE1, 0x30, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev },
+	{ SONYPI_DEVICE_MODEL_TYPE1, 0x40, SONYPI_BATTERY_MASK, sonypi_batteryev },
+
+	{ SONYPI_DEVICE_MODEL_TYPE2, 0, 0xffffffff, sonypi_releaseev },
+	{ SONYPI_DEVICE_MODEL_TYPE2, 0x38, SONYPI_LID_MASK, sonypi_lidev },
+	{ SONYPI_DEVICE_MODEL_TYPE2, 0x11, SONYPI_JOGGER_MASK, sonypi_joggerev },
+	{ SONYPI_DEVICE_MODEL_TYPE2, 0x61, SONYPI_CAPTURE_MASK, sonypi_captureev },
+	{ SONYPI_DEVICE_MODEL_TYPE2, 0x21, SONYPI_FNKEY_MASK, sonypi_fnkeyev },
+	{ SONYPI_DEVICE_MODEL_TYPE2, 0x31, SONYPI_BLUETOOTH_MASK, sonypi_blueev },
+	{ SONYPI_DEVICE_MODEL_TYPE2, 0x08, SONYPI_PKEY_MASK, sonypi_pkeyev },
+	{ SONYPI_DEVICE_MODEL_TYPE2, 0x11, SONYPI_BACK_MASK, sonypi_backev },
+	{ SONYPI_DEVICE_MODEL_TYPE2, 0x08, SONYPI_HELP_MASK, sonypi_helpev },
+	{ SONYPI_DEVICE_MODEL_TYPE2, 0x21, SONYPI_HELP_MASK, sonypi_helpev },
+	{ SONYPI_DEVICE_MODEL_TYPE2, 0x21, SONYPI_ZOOM_MASK, sonypi_zoomev },
+	{ SONYPI_DEVICE_MODEL_TYPE2, 0x20, SONYPI_THUMBPHRASE_MASK, sonypi_thumbphraseev },
+	{ SONYPI_DEVICE_MODEL_TYPE2, 0x31, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev },
+	{ SONYPI_DEVICE_MODEL_TYPE2, 0x41, SONYPI_BATTERY_MASK, sonypi_batteryev },
+	{ SONYPI_DEVICE_MODEL_TYPE2, 0x31, SONYPI_PKEY_MASK, sonypi_pkeyev },
+
+	{ 0 }
+};
+
+#define SONYPI_BUF_SIZE	128
+
+/* The name of the devices for the input device drivers */
+#define SONYPI_JOG_INPUTNAME	"Sony Vaio Jogdial"
+#define SONYPI_KEY_INPUTNAME	"Sony Vaio Keys"
+
+/* Correspondance table between sonypi events and input layer events */
+static struct {
+	int sonypiev;
+	int inputev;
+} sonypi_inputkeys[] = {
+	{ SONYPI_EVENT_CAPTURE_PRESSED,	 	KEY_CAMERA },
+	{ SONYPI_EVENT_FNKEY_ONLY, 		KEY_FN },
+	{ SONYPI_EVENT_FNKEY_ESC, 		KEY_FN_ESC },
+	{ SONYPI_EVENT_FNKEY_F1, 		KEY_FN_F1 },
+	{ SONYPI_EVENT_FNKEY_F2, 		KEY_FN_F2 },
+	{ SONYPI_EVENT_FNKEY_F3, 		KEY_FN_F3 },
+	{ SONYPI_EVENT_FNKEY_F4, 		KEY_FN_F4 },
+	{ SONYPI_EVENT_FNKEY_F5, 		KEY_FN_F5 },
+	{ SONYPI_EVENT_FNKEY_F6, 		KEY_FN_F6 },
+	{ SONYPI_EVENT_FNKEY_F7, 		KEY_FN_F7 },
+	{ SONYPI_EVENT_FNKEY_F8, 		KEY_FN_F8 },
+	{ SONYPI_EVENT_FNKEY_F9,		KEY_FN_F9 },
+	{ SONYPI_EVENT_FNKEY_F10,		KEY_FN_F10 },
+	{ SONYPI_EVENT_FNKEY_F11, 		KEY_FN_F11 },
+	{ SONYPI_EVENT_FNKEY_F12,		KEY_FN_F12 },
+	{ SONYPI_EVENT_FNKEY_1, 		KEY_FN_1 },
+	{ SONYPI_EVENT_FNKEY_2, 		KEY_FN_2 },
+	{ SONYPI_EVENT_FNKEY_D,			KEY_FN_D },
+	{ SONYPI_EVENT_FNKEY_E,			KEY_FN_E },
+	{ SONYPI_EVENT_FNKEY_F,			KEY_FN_F },
+	{ SONYPI_EVENT_FNKEY_S,			KEY_FN_S },
+	{ SONYPI_EVENT_FNKEY_B,			KEY_FN_B },
+	{ SONYPI_EVENT_BLUETOOTH_PRESSED, 	KEY_BLUE },
+	{ SONYPI_EVENT_BLUETOOTH_ON, 		KEY_BLUE },
+	{ SONYPI_EVENT_PKEY_P1, 		KEY_PROG1 },
+	{ SONYPI_EVENT_PKEY_P2, 		KEY_PROG2 },
+	{ SONYPI_EVENT_PKEY_P3, 		KEY_PROG3 },
+	{ SONYPI_EVENT_BACK_PRESSED, 		KEY_BACK },
+	{ SONYPI_EVENT_HELP_PRESSED, 		KEY_HELP },
+	{ SONYPI_EVENT_ZOOM_PRESSED, 		KEY_ZOOM },
+	{ SONYPI_EVENT_THUMBPHRASE_PRESSED, 	BTN_THUMB },
+	{ 0, 0 },
+};
+
+static struct sonypi_device {
+	struct pci_dev *dev;
+	struct platform_device *pdev;
+	u16 irq;
+	u16 bits;
+	u16 ioport1;
+	u16 ioport2;
+	u16 region_size;
+	u16 evtype_offset;
+	int camera_power;
+	int bluetooth_power;
+	struct semaphore lock;
+	struct kfifo *fifo;
+	spinlock_t fifo_lock;
+	wait_queue_head_t fifo_proc_list;
+	struct fasync_struct *fifo_async;
+	int open_count;
+	int model;
+	struct input_dev input_jog_dev;
+	struct input_dev input_key_dev;
+	struct work_struct input_work;
+	struct kfifo *input_fifo;
+	spinlock_t input_fifo_lock;
+} sonypi_device;
+
+#define ITERATIONS_LONG		10000
+#define ITERATIONS_SHORT	10
+
+#define wait_on_command(quiet, command, iterations) { \
+	unsigned int n = iterations; \
+	while (--n && (command)) \
+		udelay(1); \
+	if (!n && (verbose || !quiet)) \
+		printk(KERN_WARNING "sonypi command failed at %s : %s (line %d)\n", __FILE__, __FUNCTION__, __LINE__); \
+}
+
+#ifdef CONFIG_ACPI
+#define SONYPI_ACPI_ACTIVE (!acpi_disabled)
+#else
+#define SONYPI_ACPI_ACTIVE 0
+#endif				/* CONFIG_ACPI */
 
 static int sonypi_ec_write(u8 addr, u8 value)
 {
@@ -286,17 +673,14 @@
 
 	for (j = 5; j > 0; j--) {
 
-		while (sonypi_call2(0x91, 0x1)) {
-			set_current_state(TASK_UNINTERRUPTIBLE);
-			schedule_timeout(1);
-		}
+		while (sonypi_call2(0x91, 0x1))
+			msleep(10);
 		sonypi_call1(0x93);
 
 		for (i = 400; i > 0; i--) {
 			if (sonypi_camera_ready())
 				break;
-			set_current_state(TASK_UNINTERRUPTIBLE);
-			schedule_timeout(1);
+			msleep(10);
 		}
 		if (i)
 			break;
@@ -536,8 +920,10 @@
 		ret++;
 	}
 
-	if (ret > 0)
-		file->f_dentry->d_inode->i_atime = CURRENT_TIME;
+	if (ret > 0) {
+		struct inode *inode = file->f_dentry->d_inode;
+		inode->i_atime = current_fs_time(inode->i_sb);
+	}
 
 	return ret;
 }
@@ -629,6 +1015,32 @@
 		}
 		sonypi_setbluetoothpower(val8);
 		break;
+	/* FAN Controls */
+	case SONYPI_IOCGFAN:
+		if (sonypi_ec_read(SONYPI_FAN0_STATUS, &val8)) {
+			ret = -EIO;
+			break;
+		}
+		if (copy_to_user((u8 *)arg, &val8, sizeof(val8)))
+			ret = -EFAULT;
+		break;
+	case SONYPI_IOCSFAN:
+		if (copy_from_user(&val8, (u8 *)arg, sizeof(val8))) {
+			ret = -EFAULT;
+			break;
+		}
+		if (sonypi_ec_write(SONYPI_FAN0_STATUS, val8))
+			ret = -EIO;
+		break;
+	/* GET Temperature (useful under APM) */
+	case SONYPI_IOCGTEMP:
+		if (sonypi_ec_read(SONYPI_TEMP_STATUS, &val8)) {
+			ret = -EIO;
+			break;
+		}
+		if (copy_to_user((u8 *)arg, &val8, sizeof(val8)))
+			ret = -EFAULT;
+		break;
 	default:
 		ret = -EINVAL;
 	}
@@ -646,8 +1058,8 @@
 	.ioctl		= sonypi_misc_ioctl,
 };
 
-struct miscdevice sonypi_misc_device = {
-	.minor		= -1,
+static struct miscdevice sonypi_misc_device = {
+	.minor		= MISC_DYNAMIC_MINOR,
 	.name		= "sonypi",
 	.fops		= &sonypi_misc_fops,
 };
@@ -737,7 +1149,7 @@
 	sonypi_device.model = pcidev ?
 		SONYPI_DEVICE_MODEL_TYPE1 : SONYPI_DEVICE_MODEL_TYPE2;
 
-	sonypi_device.fifo_lock = SPIN_LOCK_UNLOCKED;
+	spin_lock_init(&sonypi_device.fifo_lock);
 	sonypi_device.fifo = kfifo_alloc(SONYPI_BUF_SIZE, GFP_KERNEL,
 					 &sonypi_device.fifo_lock);
 	if (IS_ERR(sonypi_device.fifo)) {
@@ -756,7 +1168,8 @@
 		goto out_pcienable;
 	}
 
-	sonypi_misc_device.minor = (minor == -1) ? MISC_DYNAMIC_MINOR : minor;
+	if (minor != -1)
+		sonypi_misc_device.minor = minor;
 	if ((ret = misc_register(&sonypi_misc_device))) {
 		printk(KERN_ERR "sonypi: misc_register failed\n");
 		goto out_miscreg;
@@ -850,7 +1263,7 @@
 		printk(KERN_INFO "%s input method installed.\n",
 		       sonypi_device.input_key_dev.name);
 
-		sonypi_device.input_fifo_lock = SPIN_LOCK_UNLOCKED;
+		spin_lock_init(&sonypi_device.input_fifo_lock);
 		sonypi_device.input_fifo =
 			kfifo_alloc(SONYPI_BUF_SIZE, GFP_KERNEL,
 				    &sonypi_device.input_fifo_lock);
diff -Nru a/drivers/char/sonypi.h b/drivers/char/sonypi.h
--- a/drivers/char/sonypi.h	2005-03-01 23:38:58 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,431 +0,0 @@
-/*
- * Sony Programmable I/O Control Device driver for VAIO
- *
- * Copyright (C) 2001-2004 Stelian Pop <stelian@popies.net>
- *
- * Copyright (C) 2001-2002 Alcôve <www.alcove.com>
- *
- * Copyright (C) 2001 Michael Ashley <m.ashley@unsw.edu.au>
- *
- * Copyright (C) 2001 Junichi Morita <jun1m@mars.dti.ne.jp>
- *
- * Copyright (C) 2000 Takaya Kinjo <t-kinjo@tc4.so-net.ne.jp>
- *
- * Copyright (C) 2000 Andrew Tridgell <tridge@valinux.com>
- *
- * Earlier work by Werner Almesberger, Paul `Rusty' Russell and Paul Mackerras.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You 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 _SONYPI_PRIV_H_
-#define _SONYPI_PRIV_H_
-
-#ifdef __KERNEL__
-
-#define SONYPI_DRIVER_VERSION	 "1.25"
-
-#define SONYPI_DEVICE_MODEL_TYPE1	1
-#define SONYPI_DEVICE_MODEL_TYPE2	2
-
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/input.h>
-#include <linux/acpi.h>
-#include <linux/kfifo.h>
-#include <linux/sonypi.h>
-
-/* type1 models use those */
-#define SONYPI_IRQ_PORT			0x8034
-#define SONYPI_IRQ_SHIFT		22
-#define SONYPI_BASE			0x50
-#define SONYPI_G10A			(SONYPI_BASE+0x14)
-#define SONYPI_TYPE1_REGION_SIZE	0x08
-#define SONYPI_TYPE1_EVTYPE_OFFSET	0x04
-
-/* type2 series specifics */
-#define SONYPI_SIRQ			0x9b
-#define SONYPI_SLOB			0x9c
-#define SONYPI_SHIB			0x9d
-#define SONYPI_TYPE2_REGION_SIZE	0x20
-#define SONYPI_TYPE2_EVTYPE_OFFSET	0x12
-
-/* battery / brightness addresses */
-#define SONYPI_BAT_FLAGS	0x81
-#define SONYPI_LCD_LIGHT	0x96
-#define SONYPI_BAT1_PCTRM	0xa0
-#define SONYPI_BAT1_LEFT	0xa2
-#define SONYPI_BAT1_MAXRT	0xa4
-#define SONYPI_BAT2_PCTRM	0xa8
-#define SONYPI_BAT2_LEFT	0xaa
-#define SONYPI_BAT2_MAXRT	0xac
-#define SONYPI_BAT1_MAXTK	0xb0
-#define SONYPI_BAT1_FULL	0xb2
-#define SONYPI_BAT2_MAXTK	0xb8
-#define SONYPI_BAT2_FULL	0xba
-
-/* ioports used for brightness and type2 events */
-#define SONYPI_DATA_IOPORT	0x62
-#define SONYPI_CST_IOPORT	0x66
-
-/* The set of possible ioports */
-struct sonypi_ioport_list {
-	u16	port1;
-	u16	port2;
-};
-
-static struct sonypi_ioport_list sonypi_type1_ioport_list[] = {
-	{ 0x10c0, 0x10c4 },	/* looks like the default on C1Vx */
-	{ 0x1080, 0x1084 },
-	{ 0x1090, 0x1094 },
-	{ 0x10a0, 0x10a4 },
-	{ 0x10b0, 0x10b4 },
-	{ 0x0, 0x0 }
-};
-
-static struct sonypi_ioport_list sonypi_type2_ioport_list[] = {
-	{ 0x1080, 0x1084 },
-	{ 0x10a0, 0x10a4 },
-	{ 0x10c0, 0x10c4 },
-	{ 0x10e0, 0x10e4 },
-	{ 0x0, 0x0 }
-};
-
-/* The set of possible interrupts */
-struct sonypi_irq_list {
-	u16	irq;
-	u16	bits;
-};
-
-static struct sonypi_irq_list sonypi_type1_irq_list[] = {
-	{ 11, 0x2 },	/* IRQ 11, GO22=0,GO23=1 in AML */
-	{ 10, 0x1 },	/* IRQ 10, GO22=1,GO23=0 in AML */
-	{  5, 0x0 },	/* IRQ  5, GO22=0,GO23=0 in AML */
-	{  0, 0x3 }	/* no IRQ, GO22=1,GO23=1 in AML */
-};
-
-static struct sonypi_irq_list sonypi_type2_irq_list[] = {
-	{ 11, 0x80 },	/* IRQ 11, 0x80 in SIRQ in AML */
-	{ 10, 0x40 },	/* IRQ 10, 0x40 in SIRQ in AML */
-	{  9, 0x20 },	/* IRQ  9, 0x20 in SIRQ in AML */
-	{  6, 0x10 },	/* IRQ  6, 0x10 in SIRQ in AML */
-	{  0, 0x00 }	/* no IRQ, 0x00 in SIRQ in AML */
-};
-
-#define SONYPI_CAMERA_BRIGHTNESS		0
-#define SONYPI_CAMERA_CONTRAST			1
-#define SONYPI_CAMERA_HUE			2
-#define SONYPI_CAMERA_COLOR			3
-#define SONYPI_CAMERA_SHARPNESS			4
-
-#define SONYPI_CAMERA_PICTURE			5
-#define SONYPI_CAMERA_EXPOSURE_MASK		0xC
-#define SONYPI_CAMERA_WHITE_BALANCE_MASK	0x3
-#define SONYPI_CAMERA_PICTURE_MODE_MASK		0x30
-#define SONYPI_CAMERA_MUTE_MASK			0x40
-
-/* the rest don't need a loop until not 0xff */
-#define SONYPI_CAMERA_AGC			6
-#define SONYPI_CAMERA_AGC_MASK			0x30
-#define SONYPI_CAMERA_SHUTTER_MASK 		0x7
-
-#define SONYPI_CAMERA_SHUTDOWN_REQUEST		7
-#define SONYPI_CAMERA_CONTROL			0x10
-
-#define SONYPI_CAMERA_STATUS 			7
-#define SONYPI_CAMERA_STATUS_READY 		0x2
-#define SONYPI_CAMERA_STATUS_POSITION		0x4
-
-#define SONYPI_DIRECTION_BACKWARDS 		0x4
-
-#define SONYPI_CAMERA_REVISION 			8
-#define SONYPI_CAMERA_ROMVERSION 		9
-
-/* Event masks */
-#define SONYPI_JOGGER_MASK			0x00000001
-#define SONYPI_CAPTURE_MASK			0x00000002
-#define SONYPI_FNKEY_MASK			0x00000004
-#define SONYPI_BLUETOOTH_MASK			0x00000008
-#define SONYPI_PKEY_MASK			0x00000010
-#define SONYPI_BACK_MASK			0x00000020
-#define SONYPI_HELP_MASK			0x00000040
-#define SONYPI_LID_MASK				0x00000080
-#define SONYPI_ZOOM_MASK			0x00000100
-#define SONYPI_THUMBPHRASE_MASK			0x00000200
-#define SONYPI_MEYE_MASK			0x00000400
-#define SONYPI_MEMORYSTICK_MASK			0x00000800
-#define SONYPI_BATTERY_MASK			0x00001000
-
-struct sonypi_event {
-	u8	data;
-	u8	event;
-};
-
-/* The set of possible button release events */
-static struct sonypi_event sonypi_releaseev[] = {
-	{ 0x00, SONYPI_EVENT_ANYBUTTON_RELEASED },
-	{ 0, 0 }
-};
-
-/* The set of possible jogger events  */
-static struct sonypi_event sonypi_joggerev[] = {
-	{ 0x1f, SONYPI_EVENT_JOGDIAL_UP },
-	{ 0x01, SONYPI_EVENT_JOGDIAL_DOWN },
-	{ 0x5f, SONYPI_EVENT_JOGDIAL_UP_PRESSED },
-	{ 0x41, SONYPI_EVENT_JOGDIAL_DOWN_PRESSED },
-	{ 0x1e, SONYPI_EVENT_JOGDIAL_FAST_UP },
-	{ 0x02, SONYPI_EVENT_JOGDIAL_FAST_DOWN },
-	{ 0x5e, SONYPI_EVENT_JOGDIAL_FAST_UP_PRESSED },
-	{ 0x42, SONYPI_EVENT_JOGDIAL_FAST_DOWN_PRESSED },
-	{ 0x1d, SONYPI_EVENT_JOGDIAL_VFAST_UP },
-	{ 0x03, SONYPI_EVENT_JOGDIAL_VFAST_DOWN },
-	{ 0x5d, SONYPI_EVENT_JOGDIAL_VFAST_UP_PRESSED },
-	{ 0x43, SONYPI_EVENT_JOGDIAL_VFAST_DOWN_PRESSED },
-	{ 0x40, SONYPI_EVENT_JOGDIAL_PRESSED },
-	{ 0, 0 }
-};
-
-/* The set of possible capture button events */
-static struct sonypi_event sonypi_captureev[] = {
-	{ 0x05, SONYPI_EVENT_CAPTURE_PARTIALPRESSED },
-	{ 0x07, SONYPI_EVENT_CAPTURE_PRESSED },
-	{ 0x01, SONYPI_EVENT_CAPTURE_PARTIALRELEASED },
-	{ 0, 0 }
-};
-
-/* The set of possible fnkeys events */
-static struct sonypi_event sonypi_fnkeyev[] = {
-	{ 0x10, SONYPI_EVENT_FNKEY_ESC },
-	{ 0x11, SONYPI_EVENT_FNKEY_F1 },
-	{ 0x12, SONYPI_EVENT_FNKEY_F2 },
-	{ 0x13, SONYPI_EVENT_FNKEY_F3 },
-	{ 0x14, SONYPI_EVENT_FNKEY_F4 },
-	{ 0x15, SONYPI_EVENT_FNKEY_F5 },
-	{ 0x16, SONYPI_EVENT_FNKEY_F6 },
-	{ 0x17, SONYPI_EVENT_FNKEY_F7 },
-	{ 0x18, SONYPI_EVENT_FNKEY_F8 },
-	{ 0x19, SONYPI_EVENT_FNKEY_F9 },
-	{ 0x1a, SONYPI_EVENT_FNKEY_F10 },
-	{ 0x1b, SONYPI_EVENT_FNKEY_F11 },
-	{ 0x1c, SONYPI_EVENT_FNKEY_F12 },
-	{ 0x1f, SONYPI_EVENT_FNKEY_RELEASED },
-	{ 0x21, SONYPI_EVENT_FNKEY_1 },
-	{ 0x22, SONYPI_EVENT_FNKEY_2 },
-	{ 0x31, SONYPI_EVENT_FNKEY_D },
-	{ 0x32, SONYPI_EVENT_FNKEY_E },
-	{ 0x33, SONYPI_EVENT_FNKEY_F },
-	{ 0x34, SONYPI_EVENT_FNKEY_S },
-	{ 0x35, SONYPI_EVENT_FNKEY_B },
-	{ 0x36, SONYPI_EVENT_FNKEY_ONLY },
-	{ 0, 0 }
-};
-
-/* The set of possible program key events */
-static struct sonypi_event sonypi_pkeyev[] = {
-	{ 0x01, SONYPI_EVENT_PKEY_P1 },
-	{ 0x02, SONYPI_EVENT_PKEY_P2 },
-	{ 0x04, SONYPI_EVENT_PKEY_P3 },
-	{ 0x5c, SONYPI_EVENT_PKEY_P1 },
-	{ 0, 0 }
-};
-
-/* The set of possible bluetooth events */
-static struct sonypi_event sonypi_blueev[] = {
-	{ 0x55, SONYPI_EVENT_BLUETOOTH_PRESSED },
-	{ 0x59, SONYPI_EVENT_BLUETOOTH_ON },
-	{ 0x5a, SONYPI_EVENT_BLUETOOTH_OFF },
-	{ 0, 0 }
-};
-
-/* The set of possible back button events */
-static struct sonypi_event sonypi_backev[] = {
-	{ 0x20, SONYPI_EVENT_BACK_PRESSED },
-	{ 0, 0 }
-};
-
-/* The set of possible help button events */
-static struct sonypi_event sonypi_helpev[] = {
-	{ 0x3b, SONYPI_EVENT_HELP_PRESSED },
-	{ 0, 0 }
-};
-
-
-/* The set of possible lid events */
-static struct sonypi_event sonypi_lidev[] = {
-	{ 0x51, SONYPI_EVENT_LID_CLOSED },
-	{ 0x50, SONYPI_EVENT_LID_OPENED },
-	{ 0, 0 }
-};
-
-/* The set of possible zoom events */
-static struct sonypi_event sonypi_zoomev[] = {
-	{ 0x39, SONYPI_EVENT_ZOOM_PRESSED },
-	{ 0, 0 }
-};
-
-/* The set of possible thumbphrase events */
-static struct sonypi_event sonypi_thumbphraseev[] = {
-	{ 0x3a, SONYPI_EVENT_THUMBPHRASE_PRESSED },
-	{ 0, 0 }
-};
-
-/* The set of possible motioneye camera events */
-static struct sonypi_event sonypi_meyeev[] = {
-	{ 0x00, SONYPI_EVENT_MEYE_FACE },
-	{ 0x01, SONYPI_EVENT_MEYE_OPPOSITE },
-	{ 0, 0 }
-};
-
-/* The set of possible memorystick events */
-static struct sonypi_event sonypi_memorystickev[] = {
-	{ 0x53, SONYPI_EVENT_MEMORYSTICK_INSERT },
-	{ 0x54, SONYPI_EVENT_MEMORYSTICK_EJECT },
-	{ 0, 0 }
-};
-
-/* The set of possible battery events */
-static struct sonypi_event sonypi_batteryev[] = {
-	{ 0x20, SONYPI_EVENT_BATTERY_INSERT },
-	{ 0x30, SONYPI_EVENT_BATTERY_REMOVE },
-	{ 0, 0 }
-};
-
-struct sonypi_eventtypes {
-	int			model;
-	u8			data;
-	unsigned long		mask;
-	struct sonypi_event *	events;
-} sonypi_eventtypes[] = {
-	{ SONYPI_DEVICE_MODEL_TYPE1, 0, 0xffffffff, sonypi_releaseev },
-	{ SONYPI_DEVICE_MODEL_TYPE1, 0x70, SONYPI_MEYE_MASK, sonypi_meyeev },
-	{ SONYPI_DEVICE_MODEL_TYPE1, 0x30, SONYPI_LID_MASK, sonypi_lidev },
-	{ SONYPI_DEVICE_MODEL_TYPE1, 0x60, SONYPI_CAPTURE_MASK, sonypi_captureev },
-	{ SONYPI_DEVICE_MODEL_TYPE1, 0x10, SONYPI_JOGGER_MASK, sonypi_joggerev },
-	{ SONYPI_DEVICE_MODEL_TYPE1, 0x20, SONYPI_FNKEY_MASK, sonypi_fnkeyev },
-	{ SONYPI_DEVICE_MODEL_TYPE1, 0x30, SONYPI_BLUETOOTH_MASK, sonypi_blueev },
-	{ SONYPI_DEVICE_MODEL_TYPE1, 0x40, SONYPI_PKEY_MASK, sonypi_pkeyev },
-	{ SONYPI_DEVICE_MODEL_TYPE1, 0x30, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev },
-	{ SONYPI_DEVICE_MODEL_TYPE1, 0x40, SONYPI_BATTERY_MASK, sonypi_batteryev },
-
-	{ SONYPI_DEVICE_MODEL_TYPE2, 0, 0xffffffff, sonypi_releaseev },
-	{ SONYPI_DEVICE_MODEL_TYPE2, 0x38, SONYPI_LID_MASK, sonypi_lidev },
-	{ SONYPI_DEVICE_MODEL_TYPE2, 0x11, SONYPI_JOGGER_MASK, sonypi_joggerev },
-	{ SONYPI_DEVICE_MODEL_TYPE2, 0x61, SONYPI_CAPTURE_MASK, sonypi_captureev },
-	{ SONYPI_DEVICE_MODEL_TYPE2, 0x21, SONYPI_FNKEY_MASK, sonypi_fnkeyev },
-	{ SONYPI_DEVICE_MODEL_TYPE2, 0x31, SONYPI_BLUETOOTH_MASK, sonypi_blueev },
-	{ SONYPI_DEVICE_MODEL_TYPE2, 0x08, SONYPI_PKEY_MASK, sonypi_pkeyev },
-	{ SONYPI_DEVICE_MODEL_TYPE2, 0x11, SONYPI_BACK_MASK, sonypi_backev },
-	{ SONYPI_DEVICE_MODEL_TYPE2, 0x08, SONYPI_HELP_MASK, sonypi_helpev },
-	{ SONYPI_DEVICE_MODEL_TYPE2, 0x21, SONYPI_ZOOM_MASK, sonypi_zoomev },
-	{ SONYPI_DEVICE_MODEL_TYPE2, 0x20, SONYPI_THUMBPHRASE_MASK, sonypi_thumbphraseev },
-	{ SONYPI_DEVICE_MODEL_TYPE2, 0x31, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev },
-	{ SONYPI_DEVICE_MODEL_TYPE2, 0x41, SONYPI_BATTERY_MASK, sonypi_batteryev },
-	{ SONYPI_DEVICE_MODEL_TYPE2, 0x31, SONYPI_PKEY_MASK, sonypi_pkeyev },
-
-	{ 0 }
-};
-
-#define SONYPI_BUF_SIZE	128
-
-/* The name of the devices for the input device drivers */
-#define SONYPI_JOG_INPUTNAME	"Sony Vaio Jogdial"
-#define SONYPI_KEY_INPUTNAME	"Sony Vaio Keys"
-
-/* Correspondance table between sonypi events and input layer events */
-struct {
-	int sonypiev;
-	int inputev;
-} sonypi_inputkeys[] = {
-	{ SONYPI_EVENT_CAPTURE_PRESSED,	 	KEY_CAMERA },
-	{ SONYPI_EVENT_FNKEY_ONLY, 		KEY_FN },
-	{ SONYPI_EVENT_FNKEY_ESC, 		KEY_FN_ESC },
-	{ SONYPI_EVENT_FNKEY_F1, 		KEY_FN_F1 },
-	{ SONYPI_EVENT_FNKEY_F2, 		KEY_FN_F2 },
-	{ SONYPI_EVENT_FNKEY_F3, 		KEY_FN_F3 },
-	{ SONYPI_EVENT_FNKEY_F4, 		KEY_FN_F4 },
-	{ SONYPI_EVENT_FNKEY_F5, 		KEY_FN_F5 },
-	{ SONYPI_EVENT_FNKEY_F6, 		KEY_FN_F6 },
-	{ SONYPI_EVENT_FNKEY_F7, 		KEY_FN_F7 },
-	{ SONYPI_EVENT_FNKEY_F8, 		KEY_FN_F8 },
-	{ SONYPI_EVENT_FNKEY_F9,		KEY_FN_F9 },
-	{ SONYPI_EVENT_FNKEY_F10,		KEY_FN_F10 },
-	{ SONYPI_EVENT_FNKEY_F11, 		KEY_FN_F11 },
-	{ SONYPI_EVENT_FNKEY_F12,		KEY_FN_F12 },
-	{ SONYPI_EVENT_FNKEY_1, 		KEY_FN_1 },
-	{ SONYPI_EVENT_FNKEY_2, 		KEY_FN_2 },
-	{ SONYPI_EVENT_FNKEY_D,			KEY_FN_D },
-	{ SONYPI_EVENT_FNKEY_E,			KEY_FN_E },
-	{ SONYPI_EVENT_FNKEY_F,			KEY_FN_F },
-	{ SONYPI_EVENT_FNKEY_S,			KEY_FN_S },
-	{ SONYPI_EVENT_FNKEY_B,			KEY_FN_B },
-	{ SONYPI_EVENT_BLUETOOTH_PRESSED, 	KEY_BLUE },
-	{ SONYPI_EVENT_BLUETOOTH_ON, 		KEY_BLUE },
-	{ SONYPI_EVENT_PKEY_P1, 		KEY_PROG1 },
-	{ SONYPI_EVENT_PKEY_P2, 		KEY_PROG2 },
-	{ SONYPI_EVENT_PKEY_P3, 		KEY_PROG3 },
-	{ SONYPI_EVENT_BACK_PRESSED, 		KEY_BACK },
-	{ SONYPI_EVENT_HELP_PRESSED, 		KEY_HELP },
-	{ SONYPI_EVENT_ZOOM_PRESSED, 		KEY_ZOOM },
-	{ SONYPI_EVENT_THUMBPHRASE_PRESSED, 	BTN_THUMB },
-	{ 0, 0 },
-};
-
-struct sonypi_device {
-	struct pci_dev *dev;
-	struct platform_device *pdev;
-	u16 irq;
-	u16 bits;
-	u16 ioport1;
-	u16 ioport2;
-	u16 region_size;
-	u16 evtype_offset;
-	int camera_power;
-	int bluetooth_power;
-	struct semaphore lock;
-	struct kfifo *fifo;
-	spinlock_t fifo_lock;
-	wait_queue_head_t fifo_proc_list;
-	struct fasync_struct *fifo_async;
-	int open_count;
-	int model;
-	struct input_dev input_jog_dev;
-	struct input_dev input_key_dev;
-	struct work_struct input_work;
-	struct kfifo *input_fifo;
-	spinlock_t input_fifo_lock;
-};
-
-#define ITERATIONS_LONG		10000
-#define ITERATIONS_SHORT	10
-
-#define wait_on_command(quiet, command, iterations) { \
-	unsigned int n = iterations; \
-	while (--n && (command)) \
-		udelay(1); \
-	if (!n && (verbose || !quiet)) \
-		printk(KERN_WARNING "sonypi command failed at %s : %s (line %d)\n", __FILE__, __FUNCTION__, __LINE__); \
-}
-
-#ifdef CONFIG_ACPI
-#define SONYPI_ACPI_ACTIVE (!acpi_disabled)
-#else
-#define SONYPI_ACPI_ACTIVE 0
-#endif				/* CONFIG_ACPI */
-
-#endif				/* __KERNEL__ */
-
-#endif				/* _SONYPI_PRIV_H_ */
diff -Nru a/drivers/char/synclink.c b/drivers/char/synclink.c
--- a/drivers/char/synclink.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/char/synclink.c	2005-03-01 23:38:55 -08:00
@@ -53,7 +53,6 @@
  * OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#define VERSION(ver,rel,seq) (((ver)<<16) | ((rel)<<8) | (seq))
 #if defined(__i386__)
 #  define BREAKPOINT() asm("   int $3");
 #else
@@ -118,7 +117,7 @@
 
 #define RCLRVALUE 0xffff
 
-MGSL_PARAMS default_params = {
+static MGSL_PARAMS default_params = {
 	MGSL_MODE_HDLC,			/* unsigned long mode */
 	0,				/* unsigned char loopback; */
 	HDLC_FLAG_UNDERRUN_ABORT15,	/* unsigned short flags; */
@@ -679,13 +678,13 @@
 #define usc_EnableReceiver(a,b) \
 	usc_OutReg( (a), RMR, (u16)((usc_InReg((a),RMR) & 0xfffc) | (b)) )
 
-u16  usc_InDmaReg( struct mgsl_struct *info, u16 Port );
-void usc_OutDmaReg( struct mgsl_struct *info, u16 Port, u16 Value );
-void usc_DmaCmd( struct mgsl_struct *info, u16 Cmd );
-
-u16  usc_InReg( struct mgsl_struct *info, u16 Port );
-void usc_OutReg( struct mgsl_struct *info, u16 Port, u16 Value );
-void usc_RTCmd( struct mgsl_struct *info, u16 Cmd );
+static u16  usc_InDmaReg( struct mgsl_struct *info, u16 Port );
+static void usc_OutDmaReg( struct mgsl_struct *info, u16 Port, u16 Value );
+static void usc_DmaCmd( struct mgsl_struct *info, u16 Cmd );
+
+static u16  usc_InReg( struct mgsl_struct *info, u16 Port );
+static void usc_OutReg( struct mgsl_struct *info, u16 Port, u16 Value );
+static void usc_RTCmd( struct mgsl_struct *info, u16 Cmd );
 void usc_RCmd( struct mgsl_struct *info, u16 Cmd );
 void usc_TCmd( struct mgsl_struct *info, u16 Cmd );
 
@@ -694,40 +693,39 @@
 
 #define usc_SetTransmitSyncChars(a,s0,s1) usc_OutReg((a), TSR, (u16)(((u16)s0<<8)|(u16)s1))
 
-void usc_process_rxoverrun_sync( struct mgsl_struct *info );
-void usc_start_receiver( struct mgsl_struct *info );
-void usc_stop_receiver( struct mgsl_struct *info );
+static void usc_process_rxoverrun_sync( struct mgsl_struct *info );
+static void usc_start_receiver( struct mgsl_struct *info );
+static void usc_stop_receiver( struct mgsl_struct *info );
 
-void usc_start_transmitter( struct mgsl_struct *info );
-void usc_stop_transmitter( struct mgsl_struct *info );
-void usc_set_txidle( struct mgsl_struct *info );
-void usc_load_txfifo( struct mgsl_struct *info );
+static void usc_start_transmitter( struct mgsl_struct *info );
+static void usc_stop_transmitter( struct mgsl_struct *info );
+static void usc_set_txidle( struct mgsl_struct *info );
+static void usc_load_txfifo( struct mgsl_struct *info );
 
-void usc_enable_aux_clock( struct mgsl_struct *info, u32 DataRate );
-void usc_enable_loopback( struct mgsl_struct *info, int enable );
+static void usc_enable_aux_clock( struct mgsl_struct *info, u32 DataRate );
+static void usc_enable_loopback( struct mgsl_struct *info, int enable );
 
-void usc_get_serial_signals( struct mgsl_struct *info );
-void usc_set_serial_signals( struct mgsl_struct *info );
+static void usc_get_serial_signals( struct mgsl_struct *info );
+static void usc_set_serial_signals( struct mgsl_struct *info );
 
-void usc_reset( struct mgsl_struct *info );
+static void usc_reset( struct mgsl_struct *info );
 
-void usc_set_sync_mode( struct mgsl_struct *info );
-void usc_set_sdlc_mode( struct mgsl_struct *info );
-void usc_set_async_mode( struct mgsl_struct *info );
-void usc_enable_async_clock( struct mgsl_struct *info, u32 DataRate );
+static void usc_set_sync_mode( struct mgsl_struct *info );
+static void usc_set_sdlc_mode( struct mgsl_struct *info );
+static void usc_set_async_mode( struct mgsl_struct *info );
+static void usc_enable_async_clock( struct mgsl_struct *info, u32 DataRate );
 
-void usc_loopback_frame( struct mgsl_struct *info );
+static void usc_loopback_frame( struct mgsl_struct *info );
 
-void mgsl_tx_timeout(unsigned long context);
+static void mgsl_tx_timeout(unsigned long context);
 
 
-void usc_loopmode_cancel_transmit( struct mgsl_struct * info );
-void usc_loopmode_insert_request( struct mgsl_struct * info );
-int usc_loopmode_active( struct mgsl_struct * info);
-void usc_loopmode_send_done( struct mgsl_struct * info );
-int usc_loopmode_send_active( struct mgsl_struct * info );
+static void usc_loopmode_cancel_transmit( struct mgsl_struct * info );
+static void usc_loopmode_insert_request( struct mgsl_struct * info );
+static int usc_loopmode_active( struct mgsl_struct * info);
+static void usc_loopmode_send_done( struct mgsl_struct * info );
 
-int mgsl_ioctl_common(struct mgsl_struct *info, unsigned int cmd, unsigned long arg);
+static int mgsl_ioctl_common(struct mgsl_struct *info, unsigned int cmd, unsigned long arg);
 
 #ifdef CONFIG_HDLC
 #define dev_to_port(D) (dev_to_hdlc(D)->priv)
@@ -753,77 +751,77 @@
 ((Nrdd)   << 11) + \
 ((Nrad)   <<  6) )
 
-void mgsl_trace_block(struct mgsl_struct *info,const char* data, int count, int xmit);
+static void mgsl_trace_block(struct mgsl_struct *info,const char* data, int count, int xmit);
 
 /*
  * Adapter diagnostic routines
  */
-BOOLEAN mgsl_register_test( struct mgsl_struct *info );
-BOOLEAN mgsl_irq_test( struct mgsl_struct *info );
-BOOLEAN mgsl_dma_test( struct mgsl_struct *info );
-BOOLEAN mgsl_memory_test( struct mgsl_struct *info );
-int mgsl_adapter_test( struct mgsl_struct *info );
+static BOOLEAN mgsl_register_test( struct mgsl_struct *info );
+static BOOLEAN mgsl_irq_test( struct mgsl_struct *info );
+static BOOLEAN mgsl_dma_test( struct mgsl_struct *info );
+static BOOLEAN mgsl_memory_test( struct mgsl_struct *info );
+static int mgsl_adapter_test( struct mgsl_struct *info );
 
 /*
  * device and resource management routines
  */
-int mgsl_claim_resources(struct mgsl_struct *info);
-void mgsl_release_resources(struct mgsl_struct *info);
-void mgsl_add_device(struct mgsl_struct *info);
-struct mgsl_struct* mgsl_allocate_device(void);
+static int mgsl_claim_resources(struct mgsl_struct *info);
+static void mgsl_release_resources(struct mgsl_struct *info);
+static void mgsl_add_device(struct mgsl_struct *info);
+static struct mgsl_struct* mgsl_allocate_device(void);
 
 /*
  * DMA buffer manupulation functions.
  */
-void mgsl_free_rx_frame_buffers( struct mgsl_struct *info, unsigned int StartIndex, unsigned int EndIndex );
-int  mgsl_get_rx_frame( struct mgsl_struct *info );
-int  mgsl_get_raw_rx_frame( struct mgsl_struct *info );
-void mgsl_reset_rx_dma_buffers( struct mgsl_struct *info );
-void mgsl_reset_tx_dma_buffers( struct mgsl_struct *info );
-int num_free_tx_dma_buffers(struct mgsl_struct *info);
-void mgsl_load_tx_dma_buffer( struct mgsl_struct *info, const char *Buffer, unsigned int BufferSize);
-void mgsl_load_pci_memory(char* TargetPtr, const char* SourcePtr, unsigned short count);
+static void mgsl_free_rx_frame_buffers( struct mgsl_struct *info, unsigned int StartIndex, unsigned int EndIndex );
+static int  mgsl_get_rx_frame( struct mgsl_struct *info );
+static int  mgsl_get_raw_rx_frame( struct mgsl_struct *info );
+static void mgsl_reset_rx_dma_buffers( struct mgsl_struct *info );
+static void mgsl_reset_tx_dma_buffers( struct mgsl_struct *info );
+static int num_free_tx_dma_buffers(struct mgsl_struct *info);
+static void mgsl_load_tx_dma_buffer( struct mgsl_struct *info, const char *Buffer, unsigned int BufferSize);
+static void mgsl_load_pci_memory(char* TargetPtr, const char* SourcePtr, unsigned short count);
 
 /*
  * DMA and Shared Memory buffer allocation and formatting
  */
-int  mgsl_allocate_dma_buffers(struct mgsl_struct *info);
-void mgsl_free_dma_buffers(struct mgsl_struct *info);
-int  mgsl_alloc_frame_memory(struct mgsl_struct *info, DMABUFFERENTRY *BufferList,int Buffercount);
-void mgsl_free_frame_memory(struct mgsl_struct *info, DMABUFFERENTRY *BufferList,int Buffercount);
-int  mgsl_alloc_buffer_list_memory(struct mgsl_struct *info);
-void mgsl_free_buffer_list_memory(struct mgsl_struct *info);
-int mgsl_alloc_intermediate_rxbuffer_memory(struct mgsl_struct *info);
-void mgsl_free_intermediate_rxbuffer_memory(struct mgsl_struct *info);
-int mgsl_alloc_intermediate_txbuffer_memory(struct mgsl_struct *info);
-void mgsl_free_intermediate_txbuffer_memory(struct mgsl_struct *info);
-int load_next_tx_holding_buffer(struct mgsl_struct *info);
-int save_tx_buffer_request(struct mgsl_struct *info,const char *Buffer, unsigned int BufferSize);
+static int  mgsl_allocate_dma_buffers(struct mgsl_struct *info);
+static void mgsl_free_dma_buffers(struct mgsl_struct *info);
+static int  mgsl_alloc_frame_memory(struct mgsl_struct *info, DMABUFFERENTRY *BufferList,int Buffercount);
+static void mgsl_free_frame_memory(struct mgsl_struct *info, DMABUFFERENTRY *BufferList,int Buffercount);
+static int  mgsl_alloc_buffer_list_memory(struct mgsl_struct *info);
+static void mgsl_free_buffer_list_memory(struct mgsl_struct *info);
+static int mgsl_alloc_intermediate_rxbuffer_memory(struct mgsl_struct *info);
+static void mgsl_free_intermediate_rxbuffer_memory(struct mgsl_struct *info);
+static int mgsl_alloc_intermediate_txbuffer_memory(struct mgsl_struct *info);
+static void mgsl_free_intermediate_txbuffer_memory(struct mgsl_struct *info);
+static int load_next_tx_holding_buffer(struct mgsl_struct *info);
+static int save_tx_buffer_request(struct mgsl_struct *info,const char *Buffer, unsigned int BufferSize);
 
 /*
  * Bottom half interrupt handlers
  */
-void mgsl_bh_handler(void* Context);
-void mgsl_bh_receive(struct mgsl_struct *info);
-void mgsl_bh_transmit(struct mgsl_struct *info);
-void mgsl_bh_status(struct mgsl_struct *info);
+static void mgsl_bh_handler(void* Context);
+static void mgsl_bh_receive(struct mgsl_struct *info);
+static void mgsl_bh_transmit(struct mgsl_struct *info);
+static void mgsl_bh_status(struct mgsl_struct *info);
 
 /*
  * Interrupt handler routines and dispatch table.
  */
-void mgsl_isr_null( struct mgsl_struct *info );
-void mgsl_isr_transmit_data( struct mgsl_struct *info );
-void mgsl_isr_receive_data( struct mgsl_struct *info );
-void mgsl_isr_receive_status( struct mgsl_struct *info );
-void mgsl_isr_transmit_status( struct mgsl_struct *info );
-void mgsl_isr_io_pin( struct mgsl_struct *info );
-void mgsl_isr_misc( struct mgsl_struct *info );
-void mgsl_isr_receive_dma( struct mgsl_struct *info );
-void mgsl_isr_transmit_dma( struct mgsl_struct *info );
+static void mgsl_isr_null( struct mgsl_struct *info );
+static void mgsl_isr_transmit_data( struct mgsl_struct *info );
+static void mgsl_isr_receive_data( struct mgsl_struct *info );
+static void mgsl_isr_receive_status( struct mgsl_struct *info );
+static void mgsl_isr_transmit_status( struct mgsl_struct *info );
+static void mgsl_isr_io_pin( struct mgsl_struct *info );
+static void mgsl_isr_misc( struct mgsl_struct *info );
+static void mgsl_isr_receive_dma( struct mgsl_struct *info );
+static void mgsl_isr_transmit_dma( struct mgsl_struct *info );
 
 typedef void (*isr_dispatch_func)(struct mgsl_struct *);
 
-isr_dispatch_func UscIsrTable[7] =
+static isr_dispatch_func UscIsrTable[7] =
 {
 	mgsl_isr_null,
 	mgsl_isr_misc,
@@ -858,7 +856,7 @@
 /*
  * Global linked list of SyncLink devices
  */
-struct mgsl_struct *mgsl_device_list;
+static struct mgsl_struct *mgsl_device_list;
 static int mgsl_device_count;
 
 /*
@@ -886,16 +884,16 @@
 static int txdmabufs[MAX_TOTAL_DEVICES];
 static int txholdbufs[MAX_TOTAL_DEVICES];
 	
-MODULE_PARM(break_on_load,"i");
-MODULE_PARM(ttymajor,"i");
-MODULE_PARM(io,"1-" __MODULE_STRING(MAX_ISA_DEVICES) "i");
-MODULE_PARM(irq,"1-" __MODULE_STRING(MAX_ISA_DEVICES) "i");
-MODULE_PARM(dma,"1-" __MODULE_STRING(MAX_ISA_DEVICES) "i");
-MODULE_PARM(debug_level,"i");
-MODULE_PARM(maxframe,"1-" __MODULE_STRING(MAX_TOTAL_DEVICES) "i");
-MODULE_PARM(dosyncppp,"1-" __MODULE_STRING(MAX_TOTAL_DEVICES) "i");
-MODULE_PARM(txdmabufs,"1-" __MODULE_STRING(MAX_TOTAL_DEVICES) "i");
-MODULE_PARM(txholdbufs,"1-" __MODULE_STRING(MAX_TOTAL_DEVICES) "i");
+module_param(break_on_load, bool, 0);
+module_param(ttymajor, int, 0);
+module_param_array(io, int, NULL, 0);
+module_param_array(irq, int, NULL, 0);
+module_param_array(dma, int, NULL, 0);
+module_param(debug_level, int, 0);
+module_param_array(maxframe, int, NULL, 0);
+module_param_array(dosyncppp, int, NULL, 0);
+module_param_array(txdmabufs, int, NULL, 0);
+module_param_array(txholdbufs, int, NULL, 0);
 
 static char *driver_name = "SyncLink serial driver";
 static char *driver_version = "$Revision: 4.28 $";
@@ -935,7 +933,7 @@
  * (gdb) to get the .text address for the add-symbol-file command.
  * This allows remote debugging of dynamically loadable modules.
  */
-void* mgsl_get_text_ptr(void)
+static void* mgsl_get_text_ptr(void)
 {
 	return mgsl_get_text_ptr;
 }
@@ -1052,7 +1050,7 @@
 /* mgsl_bh_action()	Return next bottom half action to perform.
  * Return Value:	BH action code or 0 if nothing to do.
  */
-int mgsl_bh_action(struct mgsl_struct *info)
+static int mgsl_bh_action(struct mgsl_struct *info)
 {
 	unsigned long flags;
 	int rc = 0;
@@ -1084,7 +1082,7 @@
 /*
  * 	Perform bottom half processing of work items queued by ISR.
  */
-void mgsl_bh_handler(void* Context)
+static void mgsl_bh_handler(void* Context)
 {
 	struct mgsl_struct *info = (struct mgsl_struct*)Context;
 	int action;
@@ -1128,7 +1126,7 @@
 			__FILE__,__LINE__,info->device_name);
 }
 
-void mgsl_bh_receive(struct mgsl_struct *info)
+static void mgsl_bh_receive(struct mgsl_struct *info)
 {
 	int (*get_rx_frame)(struct mgsl_struct *info) =
 		(info->params.mode == MGSL_MODE_HDLC ? mgsl_get_rx_frame : mgsl_get_raw_rx_frame);
@@ -1149,7 +1147,7 @@
 	} while(get_rx_frame(info));
 }
 
-void mgsl_bh_transmit(struct mgsl_struct *info)
+static void mgsl_bh_transmit(struct mgsl_struct *info)
 {
 	struct tty_struct *tty = info->tty;
 	unsigned long flags;
@@ -1172,7 +1170,7 @@
 	spin_unlock_irqrestore(&info->irq_spinlock,flags);
 }
 
-void mgsl_bh_status(struct mgsl_struct *info)
+static void mgsl_bh_status(struct mgsl_struct *info)
 {
 	if ( debug_level >= DEBUG_LEVEL_BH )
 		printk( "%s(%d):mgsl_bh_status() entry on %s\n",
@@ -1193,7 +1191,7 @@
  * Arguments:		info	pointer to device instance data
  * Return Value:	None
  */
-void mgsl_isr_receive_status( struct mgsl_struct *info )
+static void mgsl_isr_receive_status( struct mgsl_struct *info )
 {
 	u16 status = usc_InReg( info, RCSR );
 
@@ -1245,7 +1243,7 @@
  * Arguments:		info	       pointer to device instance data
  * Return Value:	None
  */
-void mgsl_isr_transmit_status( struct mgsl_struct *info )
+static void mgsl_isr_transmit_status( struct mgsl_struct *info )
 {
 	u16 status = usc_InReg( info, TCSR );
 
@@ -1312,7 +1310,7 @@
  * Arguments:		info	       pointer to device instance data
  * Return Value:	None
  */
-void mgsl_isr_io_pin( struct mgsl_struct *info )
+static void mgsl_isr_io_pin( struct mgsl_struct *info )
 {
  	struct	mgsl_icount *icount;
 	u16 status = usc_InReg( info, MISR );
@@ -1430,7 +1428,7 @@
  * Arguments:		info	pointer to device instance data
  * Return Value:	None
  */
-void mgsl_isr_transmit_data( struct mgsl_struct *info )
+static void mgsl_isr_transmit_data( struct mgsl_struct *info )
 {
 	if ( debug_level >= DEBUG_LEVEL_ISR )	
 		printk("%s(%d):mgsl_isr_transmit_data xmit_cnt=%d\n",
@@ -1462,7 +1460,7 @@
  * Arguments:		info		pointer to device instance data
  * Return Value:	None
  */
-void mgsl_isr_receive_data( struct mgsl_struct *info )
+static void mgsl_isr_receive_data( struct mgsl_struct *info )
 {
 	int Fifocount;
 	u16 status;
@@ -1574,7 +1572,7 @@
  * Arguments:		info		pointer to device extension (instance data)
  * Return Value:	None
  */
-void mgsl_isr_misc( struct mgsl_struct *info )
+static void mgsl_isr_misc( struct mgsl_struct *info )
 {
 	u16 status = usc_InReg( info, MISR );
 
@@ -1610,7 +1608,7 @@
  * Arguments:		info		pointer to device extension (instance data)
  * Return Value:	None
  */
-void mgsl_isr_null( struct mgsl_struct *info )
+static void mgsl_isr_null( struct mgsl_struct *info )
 {
 
 }	/* end of mgsl_isr_null() */
@@ -1634,7 +1632,7 @@
  * Arguments:		info		pointer to device instance data
  * Return Value:	None
  */
-void mgsl_isr_receive_dma( struct mgsl_struct *info )
+static void mgsl_isr_receive_dma( struct mgsl_struct *info )
 {
 	u16 status;
 	
@@ -1678,7 +1676,7 @@
  * Arguments:		info		pointer to device instance data
  * Return Value:	None
  */
-void mgsl_isr_transmit_dma( struct mgsl_struct *info )
+static void mgsl_isr_transmit_dma( struct mgsl_struct *info )
 {
 	u16 status;
 
@@ -2990,7 +2988,7 @@
 	return mgsl_ioctl_common(info, cmd, arg);
 }
 
-int mgsl_ioctl_common(struct mgsl_struct *info, unsigned int cmd, unsigned long arg)
+static int mgsl_ioctl_common(struct mgsl_struct *info, unsigned int cmd, unsigned long arg)
 {
 	int error;
 	struct mgsl_icount cnow;	/* kernel counter temps */
@@ -3649,7 +3647,7 @@
  * 	
  * Return Value:
  */
-int mgsl_read_proc(char *page, char **start, off_t off, int count,
+static int mgsl_read_proc(char *page, char **start, off_t off, int count,
 		 int *eof, void *data)
 {
 	int len = 0, l;
@@ -3688,7 +3686,7 @@
  * Arguments:		info	pointer to device instance data
  * Return Value:	0 if success, otherwise error
  */
-int mgsl_allocate_dma_buffers(struct mgsl_struct *info)
+static int mgsl_allocate_dma_buffers(struct mgsl_struct *info)
 {
 	unsigned short BuffersPerFrame;
 
@@ -3795,7 +3793,7 @@
  * Arguments:		info	pointer to device instance data
  * Return Value:	0 if success, otherwise error
  */
-int mgsl_alloc_buffer_list_memory( struct mgsl_struct *info )
+static int mgsl_alloc_buffer_list_memory( struct mgsl_struct *info )
 {
 	unsigned int i;
 
@@ -3880,7 +3878,7 @@
  * 	the buffer list contains the information necessary to free
  * 	the individual buffers!
  */
-void mgsl_free_buffer_list_memory( struct mgsl_struct *info )
+static void mgsl_free_buffer_list_memory( struct mgsl_struct *info )
 {
 	if ( info->buffer_list && info->bus_type != MGSL_BUS_TYPE_PCI )
 		kfree(info->buffer_list);
@@ -3907,7 +3905,7 @@
  * 
  * Return Value:	0 if success, otherwise -ENOMEM
  */
-int mgsl_alloc_frame_memory(struct mgsl_struct *info,DMABUFFERENTRY *BufferList,int Buffercount)
+static int mgsl_alloc_frame_memory(struct mgsl_struct *info,DMABUFFERENTRY *BufferList,int Buffercount)
 {
 	int i;
 	unsigned long phys_addr;
@@ -3949,7 +3947,7 @@
  * 
  * Return Value:	None
  */
-void mgsl_free_frame_memory(struct mgsl_struct *info, DMABUFFERENTRY *BufferList, int Buffercount)
+static void mgsl_free_frame_memory(struct mgsl_struct *info, DMABUFFERENTRY *BufferList, int Buffercount)
 {
 	int i;
 
@@ -3972,7 +3970,7 @@
  * Arguments:		info	pointer to device instance data
  * Return Value:	None
  */
-void mgsl_free_dma_buffers( struct mgsl_struct *info )
+static void mgsl_free_dma_buffers( struct mgsl_struct *info )
 {
 	mgsl_free_frame_memory( info, info->rx_buffer_list, info->rx_buffer_count );
 	mgsl_free_frame_memory( info, info->tx_buffer_list, info->tx_buffer_count );
@@ -3993,7 +3991,7 @@
  * 
  * Return Value:	0 if success, otherwise -ENOMEM
  */
-int mgsl_alloc_intermediate_rxbuffer_memory(struct mgsl_struct *info)
+static int mgsl_alloc_intermediate_rxbuffer_memory(struct mgsl_struct *info)
 {
 	info->intermediate_rxbuffer = kmalloc(info->max_frame_size, GFP_KERNEL | GFP_DMA);
 	if ( info->intermediate_rxbuffer == NULL )
@@ -4013,7 +4011,7 @@
  * 
  * Return Value:	None
  */
-void mgsl_free_intermediate_rxbuffer_memory(struct mgsl_struct *info)
+static void mgsl_free_intermediate_rxbuffer_memory(struct mgsl_struct *info)
 {
 	if ( info->intermediate_rxbuffer )
 		kfree(info->intermediate_rxbuffer);
@@ -4035,7 +4033,7 @@
  *
  * Return Value:	0 if success, otherwise -ENOMEM
  */
-int mgsl_alloc_intermediate_txbuffer_memory(struct mgsl_struct *info)
+static int mgsl_alloc_intermediate_txbuffer_memory(struct mgsl_struct *info)
 {
 	int i;
 
@@ -4066,7 +4064,7 @@
  *
  * Return Value:	None
  */
-void mgsl_free_intermediate_txbuffer_memory(struct mgsl_struct *info)
+static void mgsl_free_intermediate_txbuffer_memory(struct mgsl_struct *info)
 {
 	int i;
 
@@ -4098,7 +4096,7 @@
  * 			into adapter's tx dma buffer,
  * 			0 otherwise
  */
-int load_next_tx_holding_buffer(struct mgsl_struct *info)
+static int load_next_tx_holding_buffer(struct mgsl_struct *info)
 {
 	int ret = 0;
 
@@ -4144,7 +4142,7 @@
  *
  * Return Value:	1 if able to store, 0 otherwise
  */
-int save_tx_buffer_request(struct mgsl_struct *info,const char *Buffer, unsigned int BufferSize)
+static int save_tx_buffer_request(struct mgsl_struct *info,const char *Buffer, unsigned int BufferSize)
 {
 	struct tx_holding_buffer *ptx;
 
@@ -4163,7 +4161,7 @@
 	return 1;
 }
 
-int mgsl_claim_resources(struct mgsl_struct *info)
+static int mgsl_claim_resources(struct mgsl_struct *info)
 {
 	if (request_region(info->io_base,info->io_addr_size,"synclink") == NULL) {
 		printk( "%s(%d):I/O address conflict on device %s Addr=%08X\n",
@@ -4243,7 +4241,7 @@
 
 }	/* end of mgsl_claim_resources() */
 
-void mgsl_release_resources(struct mgsl_struct *info)
+static void mgsl_release_resources(struct mgsl_struct *info)
 {
 	if ( debug_level >= DEBUG_LEVEL_INFO )
 		printk( "%s(%d):mgsl_release_resources(%s) entry\n",
@@ -4297,7 +4295,7 @@
  * Arguments:		info	pointer to device instance data
  * Return Value:	None
  */
-void mgsl_add_device( struct mgsl_struct *info )
+static void mgsl_add_device( struct mgsl_struct *info )
 {
 	info->next_device = NULL;
 	info->line = mgsl_device_count;
@@ -4363,7 +4361,7 @@
  * Arguments:		none
  * Return Value:	pointer to mgsl_struct if success, otherwise NULL
  */
-struct mgsl_struct* mgsl_allocate_device(void)
+static struct mgsl_struct* mgsl_allocate_device(void)
 {
 	struct mgsl_struct *info;
 	
@@ -4582,7 +4580,7 @@
  *
  *    None
  */
-void usc_RTCmd( struct mgsl_struct *info, u16 Cmd )
+static void usc_RTCmd( struct mgsl_struct *info, u16 Cmd )
 {
 	/* output command to CCAR in bits <15..11> */
 	/* preserve bits <10..7>, bits <6..0> must be zero */
@@ -4609,7 +4607,7 @@
  *
  *       None
  */
-void usc_DmaCmd( struct mgsl_struct *info, u16 Cmd )
+static void usc_DmaCmd( struct mgsl_struct *info, u16 Cmd )
 {
 	/* write command mask to DCAR */
 	outw( Cmd + info->mbre_bit, info->io_base );
@@ -4636,7 +4634,7 @@
  *    None
  *
  */
-void usc_OutDmaReg( struct mgsl_struct *info, u16 RegAddr, u16 RegValue )
+static void usc_OutDmaReg( struct mgsl_struct *info, u16 RegAddr, u16 RegValue )
 {
 	/* Note: The DCAR is located at the adapter base address */
 	/* Note: must preserve state of BIT8 in DCAR */
@@ -4665,7 +4663,7 @@
  *    The 16-bit value read from register
  *
  */
-u16 usc_InDmaReg( struct mgsl_struct *info, u16 RegAddr )
+static u16 usc_InDmaReg( struct mgsl_struct *info, u16 RegAddr )
 {
 	/* Note: The DCAR is located at the adapter base address */
 	/* Note: must preserve state of BIT8 in DCAR */
@@ -4692,7 +4690,7 @@
  *    None
  *
  */
-void usc_OutReg( struct mgsl_struct *info, u16 RegAddr, u16 RegValue )
+static void usc_OutReg( struct mgsl_struct *info, u16 RegAddr, u16 RegValue )
 {
 	outw( RegAddr + info->loopback_bits, info->io_base + CCAR );
 	outw( RegValue, info->io_base + CCAR );
@@ -4717,7 +4715,7 @@
  *
  *    16-bit value read from register
  */
-u16 usc_InReg( struct mgsl_struct *info, u16 RegAddr )
+static u16 usc_InReg( struct mgsl_struct *info, u16 RegAddr )
 {
 	outw( RegAddr + info->loopback_bits, info->io_base + CCAR );
 	return inw( info->io_base + CCAR );
@@ -4731,7 +4729,7 @@
  * Arguments:		info    pointer to device instance data
  * Return Value: 	NONE
  */
-void usc_set_sdlc_mode( struct mgsl_struct *info )
+static void usc_set_sdlc_mode( struct mgsl_struct *info )
 {
 	u16 RegValue;
 	int PreSL1660;
@@ -5311,7 +5309,7 @@
  *			enable	1 = enable loopback, 0 = disable
  * Return Value:	None
  */
-void usc_enable_loopback(struct mgsl_struct *info, int enable)
+static void usc_enable_loopback(struct mgsl_struct *info, int enable)
 {
 	if (enable) {
 		/* blank external TXD output */
@@ -5375,7 +5373,7 @@
  *
  * Return Value:	None
  */
-void usc_enable_aux_clock( struct mgsl_struct *info, u32 data_rate )
+static void usc_enable_aux_clock( struct mgsl_struct *info, u32 data_rate )
 {
 	u32 XtalSpeed;
 	u16 Tc;
@@ -5432,7 +5430,7 @@
  *
  * Return Value: None
  */
-void usc_process_rxoverrun_sync( struct mgsl_struct *info )
+static void usc_process_rxoverrun_sync( struct mgsl_struct *info )
 {
 	int start_index;
 	int end_index;
@@ -5571,7 +5569,7 @@
  * Arguments:		info	pointer to device instance data
  * Return Value:	None
  */
-void usc_stop_receiver( struct mgsl_struct *info )
+static void usc_stop_receiver( struct mgsl_struct *info )
 {
 	if (debug_level >= DEBUG_LEVEL_ISR)
 		printk("%s(%d):usc_stop_receiver(%s)\n",
@@ -5604,7 +5602,7 @@
  * Arguments:		info	pointer to device instance data
  * Return Value:	None
  */
-void usc_start_receiver( struct mgsl_struct *info )
+static void usc_start_receiver( struct mgsl_struct *info )
 {
 	u32 phys_addr;
 	
@@ -5668,7 +5666,7 @@
  * Arguments:		info	pointer to device instance data
  * Return Value:	None
  */
-void usc_start_transmitter( struct mgsl_struct *info )
+static void usc_start_transmitter( struct mgsl_struct *info )
 {
 	u32 phys_addr;
 	unsigned int FrameSize;
@@ -5774,7 +5772,7 @@
  * Arguments:		info	pointer to device isntance data
  * Return Value:	None
  */
-void usc_stop_transmitter( struct mgsl_struct *info )
+static void usc_stop_transmitter( struct mgsl_struct *info )
 {
 	if (debug_level >= DEBUG_LEVEL_ISR)
 		printk("%s(%d):usc_stop_transmitter(%s)\n",
@@ -5803,7 +5801,7 @@
  * Arguments:		info	pointer to device extension (instance data)
  * Return Value:	None
  */
-void usc_load_txfifo( struct mgsl_struct *info )
+static void usc_load_txfifo( struct mgsl_struct *info )
 {
 	int Fifocount;
 	u8 TwoBytes[2];
@@ -5860,7 +5858,7 @@
  * Arguments:		info	pointer to device instance data
  * Return Value:	None
  */
-void usc_reset( struct mgsl_struct *info )
+static void usc_reset( struct mgsl_struct *info )
 {
 	if ( info->bus_type == MGSL_BUS_TYPE_PCI ) {
 		int i;
@@ -5974,7 +5972,7 @@
  * Arguments:		info		pointer to device instance data
  * Return Value:	None
  */
-void usc_set_async_mode( struct mgsl_struct *info )
+static void usc_set_async_mode( struct mgsl_struct *info )
 {
 	u16 RegValue;
 
@@ -6167,7 +6165,7 @@
  * Arguments:		info		pointer to device instance data
  * Return Value:	None
  */
-void usc_loopback_frame( struct mgsl_struct *info )
+static void usc_loopback_frame( struct mgsl_struct *info )
 {
 	int i;
 	unsigned long oldmode = info->params.mode;
@@ -6235,7 +6233,7 @@
  * Arguments:		info	pointer to adapter info structure
  * Return Value:	None
  */
-void usc_set_sync_mode( struct mgsl_struct *info )
+static void usc_set_sync_mode( struct mgsl_struct *info )
 {
 	usc_loopback_frame( info );
 	usc_set_sdlc_mode( info );
@@ -6258,7 +6256,7 @@
  * Arguments:		info	pointer to device instance data
  * Return Value:	None
  */
-void usc_set_txidle( struct mgsl_struct *info )
+static void usc_set_txidle( struct mgsl_struct *info )
 {
 	u16 usc_idle_mode = IDLEMODE_FLAGS;
 
@@ -6321,7 +6319,7 @@
  * Arguments:		info	pointer to device instance data
  * Return Value:	None
  */
-void usc_get_serial_signals( struct mgsl_struct *info )
+static void usc_get_serial_signals( struct mgsl_struct *info )
 {
 	u16 status;
 
@@ -6357,7 +6355,7 @@
  * Arguments:		info	pointer to device instance data
  * Return Value:	None
  */
-void usc_set_serial_signals( struct mgsl_struct *info )
+static void usc_set_serial_signals( struct mgsl_struct *info )
 {
 	u16 Control;
 	unsigned char V24Out = info->serial_signals;
@@ -6389,7 +6387,7 @@
  *					0 disables the AUX clock.
  * Return Value:	None
  */
-void usc_enable_async_clock( struct mgsl_struct *info, u32 data_rate )
+static void usc_enable_async_clock( struct mgsl_struct *info, u32 data_rate )
 {
 	if ( data_rate )	{
 		/*
@@ -6499,7 +6497,7 @@
  * Arguments:		info	pointer to device instance data
  * Return Value:	None
  */
-void mgsl_reset_tx_dma_buffers( struct mgsl_struct *info )
+static void mgsl_reset_tx_dma_buffers( struct mgsl_struct *info )
 {
 	unsigned int i;
 
@@ -6525,7 +6523,7 @@
  * Arguments:		info	pointer to device instance data
  * Return Value:	number of free tx dma buffers
  */
-int num_free_tx_dma_buffers(struct mgsl_struct *info)
+static int num_free_tx_dma_buffers(struct mgsl_struct *info)
 {
 	return info->tx_buffer_count - info->tx_dma_buffers_used;
 }
@@ -6540,7 +6538,7 @@
  * Arguments:		info	pointer to device instance data
  * Return Value:	None
  */
-void mgsl_reset_rx_dma_buffers( struct mgsl_struct *info )
+static void mgsl_reset_rx_dma_buffers( struct mgsl_struct *info )
 {
 	unsigned int i;
 
@@ -6568,7 +6566,7 @@
  * 
  * Return Value:	None
  */
-void mgsl_free_rx_frame_buffers( struct mgsl_struct *info, unsigned int StartIndex, unsigned int EndIndex )
+static void mgsl_free_rx_frame_buffers( struct mgsl_struct *info, unsigned int StartIndex, unsigned int EndIndex )
 {
 	int Done = 0;
 	DMABUFFERENTRY *pBufEntry;
@@ -6611,7 +6609,7 @@
  * Arguments:	 	info	pointer to device extension
  * Return Value:	1 if frame returned, otherwise 0
  */
-int mgsl_get_rx_frame(struct mgsl_struct *info)
+static int mgsl_get_rx_frame(struct mgsl_struct *info)
 {
 	unsigned int StartIndex, EndIndex;	/* index of 1st and last buffers of Rx frame */
 	unsigned short status;
@@ -6810,7 +6808,7 @@
  * Arguments:	 	info	pointer to device extension
  * Return Value:	1 if frame returned, otherwise 0
  */
-int mgsl_get_raw_rx_frame(struct mgsl_struct *info)
+static int mgsl_get_raw_rx_frame(struct mgsl_struct *info)
 {
 	unsigned int CurrentIndex, NextIndex;
 	unsigned short status;
@@ -6975,8 +6973,8 @@
  * 
  * Return Value: 	None
  */
-void mgsl_load_tx_dma_buffer(struct mgsl_struct *info, const char *Buffer,
-	 unsigned int BufferSize)
+static void mgsl_load_tx_dma_buffer(struct mgsl_struct *info,
+		const char *Buffer, unsigned int BufferSize)
 {
 	unsigned short Copycount;
 	unsigned int i = 0;
@@ -7052,7 +7050,7 @@
  * Arguments:		info	pointer to device instance data
  * Return Value:		TRUE if test passed, otherwise FALSE
  */
-BOOLEAN mgsl_register_test( struct mgsl_struct *info )
+static BOOLEAN mgsl_register_test( struct mgsl_struct *info )
 {
 	static unsigned short BitPatterns[] =
 		{ 0x0000, 0xffff, 0xaaaa, 0x5555, 0x1234, 0x6969, 0x9696, 0x0f0f };
@@ -7108,7 +7106,7 @@
  * Arguments:		info	pointer to device instance data
  * Return Value:	TRUE if test passed, otherwise FALSE
  */
-BOOLEAN mgsl_irq_test( struct mgsl_struct *info )
+static BOOLEAN mgsl_irq_test( struct mgsl_struct *info )
 {
 	unsigned long EndTime;
 	unsigned long flags;
@@ -7163,7 +7161,7 @@
  * Arguments:		info	pointer to device instance data
  * Return Value:	TRUE if test passed, otherwise FALSE
  */
-BOOLEAN mgsl_dma_test( struct mgsl_struct *info )
+static BOOLEAN mgsl_dma_test( struct mgsl_struct *info )
 {
 	unsigned short FifoLevel;
 	unsigned long phys_addr;
@@ -7455,7 +7453,7 @@
  * Arguments:		info	pointer to device instance data
  * Return Value:	0 if success, otherwise -ENODEV
  */
-int mgsl_adapter_test( struct mgsl_struct *info )
+static int mgsl_adapter_test( struct mgsl_struct *info )
 {
 	if ( debug_level >= DEBUG_LEVEL_INFO )
 		printk( "%s(%d):Testing device %s\n",
@@ -7497,7 +7495,7 @@
  * Arguments:		info	pointer to device instance data
  * Return Value:	TRUE if test passed, otherwise FALSE
  */
-BOOLEAN mgsl_memory_test( struct mgsl_struct *info )
+static BOOLEAN mgsl_memory_test( struct mgsl_struct *info )
 {
 	static unsigned long BitPatterns[] = { 0x0, 0x55555555, 0xaaaaaaaa,
 											0x66666666, 0x99999999, 0xffffffff, 0x12345678 };
@@ -7578,7 +7576,7 @@
  *
  * Return Value:	None
  */
-void mgsl_load_pci_memory( char* TargetPtr, const char* SourcePtr, 
+static void mgsl_load_pci_memory( char* TargetPtr, const char* SourcePtr,
 	unsigned short count )
 {
 	/* 16 32-bit writes @ 60ns each = 960ns max latency on local bus */
@@ -7600,7 +7598,7 @@
 
 }	/* End Of mgsl_load_pci_memory() */
 
-void mgsl_trace_block(struct mgsl_struct *info,const char* data, int count, int xmit)
+static void mgsl_trace_block(struct mgsl_struct *info,const char* data, int count, int xmit)
 {
 	int i;
 	int linecount;
@@ -7640,7 +7638,7 @@
  * Arguments:	context		pointer to device instance data
  * Return Value:	None
  */
-void mgsl_tx_timeout(unsigned long context)
+static void mgsl_tx_timeout(unsigned long context)
 {
 	struct mgsl_struct *info = (struct mgsl_struct*)context;
 	unsigned long flags;
@@ -7694,7 +7692,7 @@
 /* release the line by echoing RxD to TxD
  * upon completion of a transmit frame
  */
-void usc_loopmode_send_done( struct mgsl_struct * info )
+static void usc_loopmode_send_done( struct mgsl_struct * info )
 {
  	info->loopmode_send_done_requested = FALSE;
  	/* clear CMR:13 to 0 to start echoing RxData to TxData */
@@ -7704,7 +7702,7 @@
 
 /* abort a transmit in progress while in HDLC LoopMode
  */
-void usc_loopmode_cancel_transmit( struct mgsl_struct * info )
+static void usc_loopmode_cancel_transmit( struct mgsl_struct * info )
 {
  	/* reset tx dma channel and purge TxFifo */
  	usc_RTCmd( info, RTCmd_PurgeTxFifo );
@@ -7716,7 +7714,7 @@
  * is an Insert Into Loop action. Upon receipt of a GoAhead sequence (RxAbort)
  * we must clear CMR:13 to begin repeating TxData to RxData
  */
-void usc_loopmode_insert_request( struct mgsl_struct * info )
+static void usc_loopmode_insert_request( struct mgsl_struct * info )
 {
  	info->loopmode_insert_requested = TRUE;
  
@@ -7733,17 +7731,10 @@
 
 /* return 1 if station is inserted into the loop, otherwise 0
  */
-int usc_loopmode_active( struct mgsl_struct * info)
+static int usc_loopmode_active( struct mgsl_struct * info)
 {
  	return usc_InReg( info, CCSR ) & BIT7 ? 1 : 0 ;
 }
-
-/* return 1 if USC is in loop send mode, otherwise 0
- */
-int usc_loopmode_send_active( struct mgsl_struct * info )
-{
-	return usc_InReg( info, CCSR ) & BIT6 ? 1 : 0 ;
-}			  
 
 #ifdef CONFIG_HDLC
 
diff -Nru a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c
--- a/drivers/char/synclinkmp.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/char/synclinkmp.c	2005-03-01 23:38:53 -08:00
@@ -480,11 +480,11 @@
 static int maxframe[MAX_DEVICES] = {0,};
 static int dosyncppp[MAX_DEVICES] = {0,};
 
-MODULE_PARM(break_on_load,"i");
-MODULE_PARM(ttymajor,"i");
-MODULE_PARM(debug_level,"i");
-MODULE_PARM(maxframe,"1-" __MODULE_STRING(MAX_DEVICES) "i");
-MODULE_PARM(dosyncppp,"1-" __MODULE_STRING(MAX_DEVICES) "i");
+module_param(break_on_load, bool, 0);
+module_param(ttymajor, int, 0);
+module_param(debug_level, int, 0);
+module_param_array(maxframe, int, NULL, 0);
+module_param_array(dosyncppp, int, NULL, 0);
 
 static char *driver_name = "SyncLink MultiPort driver";
 static char *driver_version = "$Revision: 4.29 $";
diff -Nru a/drivers/char/sysrq.c b/drivers/char/sysrq.c
--- a/drivers/char/sysrq.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/char/sysrq.c	2005-03-01 23:39:09 -08:00
@@ -98,6 +98,7 @@
 static void sysrq_handle_reboot(int key, struct pt_regs *pt_regs,
 				struct tty_struct *tty) 
 {
+	local_irq_enable();
 	machine_restart(NULL);
 }
 
@@ -228,7 +229,7 @@
 };
 
 /* Key Operations table and lock */
-static spinlock_t sysrq_key_table_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(sysrq_key_table_lock);
 #define SYSRQ_KEY_TABLE_LENGTH 36
 static struct sysrq_key_op *sysrq_key_table[SYSRQ_KEY_TABLE_LENGTH] = {
 /* 0 */	&sysrq_loglevel_op,
diff -Nru a/drivers/char/tipar.c b/drivers/char/tipar.c
--- a/drivers/char/tipar.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/char/tipar.c	2005-03-01 23:39:08 -08:00
@@ -40,10 +40,10 @@
  * the minor number.
  *
  */
-
+#undef DEBUG				/* change to #define to get debugging
+					 * output - for pr_debug() */
 #include <linux/config.h>
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
@@ -57,7 +57,7 @@
 #include <asm/io.h>
 #include <linux/bitops.h>
 #include <linux/devfs_fs_kernel.h>	/* DevFs support */
-#include <linux/parport.h>	/* Our code depend on parport */
+#include <linux/parport.h>		/* Our code depend on parport */
 #include <linux/device.h>
 
 /*
@@ -74,9 +74,6 @@
 #define DRIVER_LICENSE "GPL"
 
 #define VERSION(ver,rel,seq) (((ver)<<16) | ((rel)<<8) | (seq))
-#if LINUX_VERSION_CODE < VERSION(2,5,0)
-# define need_resched() (current->need_resched)
-#endif
 
 /* ----- global variables --------------------------------------------- */
 
@@ -143,7 +140,7 @@
 static int
 put_ti_parallel(int minor, unsigned char data)
 {
-	int bit;
+	unsigned int bit;
 	unsigned long max;
 
 	for (bit = 0; bit < 8; bit++) {
@@ -187,7 +184,7 @@
 static int
 get_ti_parallel(int minor)
 {
-	int bit;
+	unsigned int bit;
 	unsigned char v, data = 0;
 	unsigned long max;
 
@@ -234,7 +231,8 @@
 		outbyte(3, minor);
 		outbyte(i, minor);
 		udelay(delay);
-		/*printk(KERN_DEBUG "Probing -> %i: 0x%02x 0x%02x\n", i, data & 0x30, seq[i]); */
+		pr_debug("tipar: Probing -> %i: 0x%02x 0x%02x\n", i,
+			data & 0x30, seq[i]);
 		if ((inbyte(minor) & 0x30) != seq[i]) {
 			outbyte(3, minor);
 			return -1;
@@ -279,7 +277,8 @@
 }
 
 static ssize_t
-tipar_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos)
+tipar_write (struct file *file, const char __user *buf, size_t count,
+		loff_t * ppos)
 {
 	unsigned int minor = iminor(file->f_dentry->d_inode) - TIPAR_MINOR;
 	ssize_t n;
@@ -405,7 +404,8 @@
 		if (ints[1] != 0)
                         timeout = ints[1];
                 else
-                        printk("tipar: wrong timeout value (0), using default value instead.");
+                        printk(KERN_WARNING "tipar: bad timeout value (0), "
+				"using default value instead");
 		if (ints[0] > 1) {
 			delay = ints[2];
 		}
@@ -436,8 +436,8 @@
 		goto out;
 	}
 
-	class_simple_device_add(tipar_class, MKDEV(TIPAR_MAJOR, TIPAR_MINOR + nr),
-			NULL, "par%d", nr);
+	class_simple_device_add(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),
 			S_IFCHR | S_IRUGO | S_IWUGO,
@@ -446,14 +446,13 @@
 		goto out_class;
 
 	/* Display informations */
-	printk(KERN_INFO "tipar%d: using %s (%s).\n", nr, port->name,
-	       (port->irq ==
+	pr_info("tipar%d: using %s (%s)\n", nr, port->name, (port->irq ==
 		PARPORT_IRQ_NONE) ? "polling" : "interrupt-driven");
 
 	if (probe_ti_parallel(nr) != -1)
-		printk("tipar%d: link cable found !\n", nr);
+		pr_info("tipar%d: link cable found\n", nr);
 	else
-		printk("tipar%d: link cable not found.\n", nr);
+		pr_info("tipar%d: link cable not found\n", nr);
 
 	err = 0;
 	goto out;
@@ -469,7 +468,7 @@
 tipar_attach(struct parport *port)
 {
 	if (tp_count == PP_NO) {
-		printk("tipar: ignoring parallel port (max. %d)\n", PP_NO);
+		pr_info("tipar: ignoring parallel port (max. %d)\n", PP_NO);
 		return;
 	}
 
@@ -489,16 +488,16 @@
 	.detach = tipar_detach,
 };
 
-int __init
+static int __init
 tipar_init_module(void)
 {
 	int err = 0;
 
-	printk("tipar: parallel link cable driver, version %s\n",
-	       DRIVER_VERSION);
+	pr_info("tipar: parallel link cable driver, version %s\n",
+		DRIVER_VERSION);
 
 	if (register_chrdev(TIPAR_MAJOR, "tipar", &tipar_fops)) {
-		printk("tipar: unable to get major %d\n", TIPAR_MAJOR);
+		printk(KERN_ERR "tipar: unable to get major %d\n", TIPAR_MAJOR);
 		err = -EIO;
 		goto out;
 	}
@@ -512,7 +511,7 @@
 		goto out_chrdev;
 	}
 	if (parport_register_driver(&tipar_driver)) {
-		printk("tipar: unable to register with parport\n");
+		printk(KERN_ERR "tipar: unable to register with parport\n");
 		err = -EIO;
 		goto out;
 	}
@@ -526,7 +525,7 @@
 	return err;	
 }
 
-void __exit
+static void __exit
 tipar_cleanup_module(void)
 {
 	unsigned int i;
@@ -546,7 +545,7 @@
 	class_simple_destroy(tipar_class);
 	devfs_remove("ticables/par");
 
-	printk("tipar: module unloaded !\n");
+	pr_info("tipar: module unloaded\n");
 }
 
 /* --------------------------------------------------------------------- */
@@ -559,7 +558,7 @@
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE(DRIVER_LICENSE);
 
-MODULE_PARM(timeout, "i");
+module_param(timeout, int, 0);
 MODULE_PARM_DESC(timeout, "Timeout (default=1.5 seconds)");
-MODULE_PARM(delay, "i");
+module_param(delay, int, 0);
 MODULE_PARM_DESC(delay, "Inter-bit delay (default=10 microseconds)");
diff -Nru a/drivers/char/toshiba.c b/drivers/char/toshiba.c
--- a/drivers/char/toshiba.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/char/toshiba.c	2005-03-01 23:39:16 -08:00
@@ -81,7 +81,7 @@
 
 static int tosh_fn = 0;
 
-MODULE_PARM(tosh_fn, "i");
+module_param(tosh_fn, int, 0);
 
 
 static int tosh_ioctl(struct inode *, struct file *, unsigned int,
@@ -407,7 +407,7 @@
  *   laptop, otherwise zero and determines the Machine ID, BIOS version and
  *   date, and SCI version.
  */
-int tosh_probe(void)
+static int tosh_probe(void)
 {
 	int i,major,minor,day,year,month,flag;
 	unsigned char signature[7] = { 0x54,0x4f,0x53,0x48,0x49,0x42,0x41 };
diff -Nru a/drivers/char/tty_io.c b/drivers/char/tty_io.c
--- a/drivers/char/tty_io.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/char/tty_io.c	2005-03-01 23:38:58 -08:00
@@ -249,7 +249,7 @@
  *	callers who will do ldisc lookups and cannot sleep.
  */
  
-static spinlock_t tty_ldisc_lock = SPIN_LOCK_UNLOCKED;
+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	*/
 
@@ -327,7 +327,7 @@
 	
 EXPORT_SYMBOL_GPL(tty_ldisc_put);
 
-void tty_ldisc_assign(struct tty_struct *tty, struct tty_ldisc *ld)
+static void tty_ldisc_assign(struct tty_struct *tty, struct tty_ldisc *ld)
 {
 	tty->ldisc = *ld;
 	tty->ldisc.refcount = 0;
@@ -583,7 +583,7 @@
 /*
  * This routine returns a tty driver structure, given a device number
  */
-struct tty_driver *get_tty_driver(dev_t device, int *index)
+static struct tty_driver *get_tty_driver(dev_t device, int *index)
 {
 	struct tty_driver *p;
 
@@ -690,7 +690,7 @@
 	.release	= tty_release,
 };
 
-static spinlock_t redirect_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(redirect_lock);
 static struct file *redirect;
 
 /**
@@ -744,7 +744,7 @@
  * but doesn't hold any locks, so we need to make sure we have the appropriate
  * locks for what we're doing..
  */
-void do_tty_hangup(void *data)
+static void do_tty_hangup(void *data)
 {
 	struct tty_struct *tty = (struct tty_struct *) data;
 	struct file * cons_filp = NULL;
@@ -918,9 +918,11 @@
 
 	lock_kernel();
 
+	down(&tty_sem);
 	tty = current->signal->tty;
 	if (tty) {
 		tty_pgrp = tty->pgrp;
+		up(&tty_sem);
 		if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY)
 			tty_vhangup(tty);
 	} else {
@@ -928,6 +930,7 @@
 			kill_pg(current->signal->tty_old_pgrp, SIGHUP, on_exit);
 			kill_pg(current->signal->tty_old_pgrp, SIGCONT, on_exit);
 		}
+		up(&tty_sem);
 		unlock_kernel();	
 		return;
 	}
@@ -937,15 +940,19 @@
 			kill_pg(tty_pgrp, SIGCONT, on_exit);
 	}
 
+	/* Must lock changes to tty_old_pgrp */
+	down(&tty_sem);
 	current->signal->tty_old_pgrp = 0;
 	tty->session = 0;
 	tty->pgrp = -1;
 
+	/* Now clear signal->tty under the lock */
 	read_lock(&tasklist_lock);
 	do_each_task_pid(current->signal->session, PIDTYPE_SID, p) {
 		p->signal->tty = NULL;
 	} while_each_task_pid(current->signal->session, PIDTYPE_SID, p);
 	read_unlock(&tasklist_lock);
+	up(&tty_sem);
 	unlock_kernel();
 }
 
@@ -1011,7 +1018,7 @@
 	tty_ldisc_deref(ld);
 	unlock_kernel();
 	if (i > 0)
-		inode->i_atime = CURRENT_TIME;
+		inode->i_atime = current_fs_time(inode->i_sb);
 	return i;
 }
 
@@ -1040,8 +1047,13 @@
 	 *
 	 * But if TTY_NO_WRITE_SPLIT is set, we should use a
 	 * big chunk-size..
+	 *
+	 * The default chunk-size is 2kB, because the NTTY
+	 * layer has problems with bigger chunks. It will
+	 * claim to be able to handle more characters than
+	 * it actually does.
 	 */
-	chunk = 4096;
+	chunk = 2048;
 	if (test_bit(TTY_NO_WRITE_SPLIT, &tty->flags))
 		chunk = 65536;
 	if (count < chunk)
@@ -1088,7 +1100,8 @@
 		cond_resched();
 	}
 	if (written) {
-		file->f_dentry->d_inode->i_mtime = CURRENT_TIME;
+		struct inode *inode = file->f_dentry->d_inode;
+		inode->i_mtime = current_fs_time(inode->i_sb);
 		ret = written;
 	}
 	up(&tty->atomic_write);
@@ -1171,12 +1184,6 @@
 	struct termios *ltp, **ltp_loc, *o_ltp, **o_ltp_loc;
 	int retval=0;
 
-	/* 
-	 * Check whether we need to acquire the tty semaphore to avoid
-	 * race conditions.  For now, play it safe.
-	 */
-	down(&tty_sem);
-
 	/* check whether we're reopening an existing tty */
 	if (driver->flags & TTY_DRIVER_DEVPTS_MEM) {
 		tty = devpts_get_tty(idx);
@@ -1365,7 +1372,6 @@
 	
 	/* All paths come through here to release the semaphore */
 end_init:
-	up(&tty_sem);
 	return retval;
 
 	/* Release locally allocated memory ... nothing placed in slots */
@@ -1561,9 +1567,14 @@
 	 * each iteration we avoid any problems.
 	 */
 	while (1) {
+		/* Guard against races with tty->count changes elsewhere and
+		   opens on /dev/tty */
+		   
+		down(&tty_sem);
 		tty_closing = tty->count <= 1;
 		o_tty_closing = o_tty &&
 			(o_tty->count <= (pty_master ? 1 : 0));
+		up(&tty_sem);
 		do_sleep = 0;
 
 		if (tty_closing) {
@@ -1599,6 +1610,8 @@
 	 * both sides, and we've completed the last operation that could 
 	 * block, so it's safe to proceed with closing.
 	 */
+	 
+	down(&tty_sem);
 	if (pty_master) {
 		if (--o_tty->count < 0) {
 			printk(KERN_WARNING "release_dev: bad pty slave count "
@@ -1612,7 +1625,8 @@
 		       tty->count, tty_name(tty, buf));
 		tty->count = 0;
 	}
-
+	up(&tty_sem);
+	
 	/*
 	 * We've decremented tty->count, so we need to remove this file
 	 * descriptor off the tty->tty_files list; this serves two
@@ -1759,10 +1773,14 @@
 	noctty = filp->f_flags & O_NOCTTY;
 	index  = -1;
 	retval = 0;
+	
+	down(&tty_sem);
 
 	if (device == MKDEV(TTYAUX_MAJOR,0)) {
-		if (!current->signal->tty)
+		if (!current->signal->tty) {
+			up(&tty_sem);
 			return -ENXIO;
+		}
 		driver = current->signal->tty->driver;
 		index = current->signal->tty->index;
 		filp->f_flags |= O_NONBLOCK; /* Don't let /dev/tty block */
@@ -1787,14 +1805,18 @@
 			noctty = 1;
 			goto got_driver;
 		}
+		up(&tty_sem);
 		return -ENODEV;
 	}
 
 	driver = get_tty_driver(device, &index);
-	if (!driver)
+	if (!driver) {
+		up(&tty_sem);
 		return -ENODEV;
+	}
 got_driver:
 	retval = init_dev(driver, index, &tty);
+	up(&tty_sem);
 	if (retval)
 		return retval;
 
@@ -1880,7 +1902,10 @@
 	}
 	up(&allocated_ptys_lock);
 
+	down(&tty_sem);
 	retval = init_dev(ptm_driver, index, &tty);
+	up(&tty_sem);
+	
 	if (retval)
 		goto out;
 
@@ -2504,28 +2529,6 @@
 }
 
 /*
- *	Call the ldisc flush directly from a driver. This function may
- *	return an error and need retrying by the user.
- */
-
-int tty_push_data(struct tty_struct *tty, unsigned char *cp, unsigned char *fp, int count)
-{
-	int ret = 0;
-	struct tty_ldisc *disc;
-	
-	disc = tty_ldisc_ref(tty);
-	if(test_bit(TTY_DONT_FLIP, &tty->flags))
-		ret = -EAGAIN;
-	else if(disc == NULL)
-		ret = -EIO;
-	else
-		disc->receive_buf(tty, cp, fp, count);
-	tty_ldisc_deref(disc);
-	return ret;
-	
-}
-
-/*
  * Routine which returns the baud rate of the tty
  *
  * Note that the baud_table needs to be kept in sync with the
@@ -2903,8 +2906,8 @@
 	   So I haven't moved it. dwmw2 */
         rs_360_init();
 #endif
-	call = &__con_initcall_start;
-	while (call < &__con_initcall_end) {
+	call = __con_initcall_start;
+	while (call < __con_initcall_end) {
 		(*call)();
 		call++;
 	}
diff -Nru a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c
--- a/drivers/char/tty_ioctl.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/char/tty_ioctl.c	2005-03-01 23:39:18 -08:00
@@ -372,7 +372,7 @@
 /*
  * Send a high priority character to the tty.
  */
-void send_prio_char(struct tty_struct *tty, char ch)
+static void send_prio_char(struct tty_struct *tty, char ch)
 {
 	int	was_stopped = tty->stopped;
 
diff -Nru a/drivers/char/vc_screen.c b/drivers/char/vc_screen.c
--- a/drivers/char/vc_screen.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/char/vc_screen.c	2005-03-01 23:38:54 -08:00
@@ -59,7 +59,7 @@
 	if (!vc_cons_allocated(currcons))
 		return -ENXIO;
 
-	size = video_num_lines * video_num_columns;
+	size = vc_cons[currcons].d->vc_rows * vc_cons[currcons].d->vc_cols;
 
 	if (minor & 128)
 		size = 2*size + HEADER_SIZE;
@@ -99,6 +99,7 @@
 {
 	struct inode *inode = file->f_dentry->d_inode;
 	unsigned int currcons = iminor(inode);
+	struct vc_data *vc;
 	long pos;
 	long viewed, attr, read;
 	int col, maxcol;
@@ -126,6 +127,7 @@
 	ret = -ENXIO;
 	if (!vc_cons_allocated(currcons))
 		goto unlock_out;
+	vc = vc_cons[currcons].d;
 
 	ret = -EINVAL;
 	if (pos < 0)
@@ -159,15 +161,15 @@
 
 		con_buf_start = con_buf0 = con_buf;
 		orig_count = this_round;
-		maxcol = video_num_columns;
+		maxcol = vc->vc_cols;
 		if (!attr) {
-			org = screen_pos(currcons, p, viewed);
+			org = screen_pos(vc, p, viewed);
 			col = p % maxcol;
 			p += maxcol - col;
 			while (this_round-- > 0) {
-				*con_buf0++ = (vcs_scr_readw(currcons, org++) & 0xff);
+				*con_buf0++ = (vcs_scr_readw(vc, org++) & 0xff);
 				if (++col == maxcol) {
-					org = screen_pos(currcons, p, viewed);
+					org = screen_pos(vc, p, viewed);
 					col = 0;
 					p += maxcol;
 				}
@@ -176,9 +178,9 @@
 			if (p < HEADER_SIZE) {
 				size_t tmp_count;
 
-				con_buf0[0] = (char) video_num_lines;
-				con_buf0[1] = (char) video_num_columns;
-				getconsxy(currcons, con_buf0 + 2);
+				con_buf0[0] = (char)vc->vc_rows;
+				con_buf0[1] = (char)vc->vc_cols;
+				getconsxy(vc, con_buf0 + 2);
 
 				con_buf_start += p;
 				this_round += p;
@@ -214,7 +216,7 @@
 				p /= 2;
 				col = p % maxcol;
 
-				org = screen_pos(currcons, p, viewed);
+				org = screen_pos(vc, p, viewed);
 				p += maxcol - col;
 
 				/* Buffer has even length, so we can always copy
@@ -224,10 +226,10 @@
 				this_round = (this_round + 1) >> 1;
 
 				while (this_round) {
-					*tmp_buf++ = vcs_scr_readw(currcons, org++);
+					*tmp_buf++ = vcs_scr_readw(vc, org++);
 					this_round --;
 					if (++col == maxcol) {
-						org = screen_pos(currcons, p, viewed);
+						org = screen_pos(vc, p, viewed);
 						col = 0;
 						p += maxcol;
 					}
@@ -270,6 +272,7 @@
 {
 	struct inode *inode = file->f_dentry->d_inode;
 	unsigned int currcons = iminor(inode);
+	struct vc_data *vc;
 	long pos;
 	long viewed, attr, size, written;
 	char *con_buf0;
@@ -299,6 +302,7 @@
 	ret = -ENXIO;
 	if (!vc_cons_allocated(currcons))
 		goto unlock_out;
+	vc = vc_cons[currcons].d;
 
 	size = vcs_size(inode);
 	ret = -EINVAL;
@@ -351,10 +355,10 @@
 
 		con_buf0 = con_buf;
 		orig_count = this_round;
-		maxcol = video_num_columns;
+		maxcol = vc->vc_cols;
 		p = pos;
 		if (!attr) {
-			org0 = org = screen_pos(currcons, p, viewed);
+			org0 = org = screen_pos(vc, p, viewed);
 			col = p % maxcol;
 			p += maxcol - col;
 
@@ -362,11 +366,11 @@
 				unsigned char c = *con_buf0++;
 
 				this_round--;
-				vcs_scr_writew(currcons,
-					       (vcs_scr_readw(currcons, org) & 0xff00) | c, org);
+				vcs_scr_writew(vc,
+					       (vcs_scr_readw(vc, org) & 0xff00) | c, org);
 				org++;
 				if (++col == maxcol) {
-					org = screen_pos(currcons, p, viewed);
+					org = screen_pos(vc, p, viewed);
 					col = 0;
 					p += maxcol;
 				}
@@ -375,34 +379,34 @@
 			if (p < HEADER_SIZE) {
 				char header[HEADER_SIZE];
 
-				getconsxy(currcons, header + 2);
+				getconsxy(vc, header + 2);
 				while (p < HEADER_SIZE && this_round > 0) {
 					this_round--;
 					header[p++] = *con_buf0++;
 				}
 				if (!viewed)
-					putconsxy(currcons, header + 2);
+					putconsxy(vc, header + 2);
 			}
 			p -= HEADER_SIZE;
 			col = (p/2) % maxcol;
 			if (this_round > 0) {
-				org0 = org = screen_pos(currcons, p/2, viewed);
+				org0 = org = screen_pos(vc, p/2, viewed);
 				if ((p & 1) && this_round > 0) {
 					char c;
 
 					this_round--;
 					c = *con_buf0++;
 #ifdef __BIG_ENDIAN
-					vcs_scr_writew(currcons, c |
-					     (vcs_scr_readw(currcons, org) & 0xff00), org);
+					vcs_scr_writew(vc, c |
+					     (vcs_scr_readw(vc, org) & 0xff00), org);
 #else
-					vcs_scr_writew(currcons, (c << 8) |
-					     (vcs_scr_readw(currcons, org) & 0xff), org);
+					vcs_scr_writew(vc, (c << 8) |
+					     (vcs_scr_readw(vc, org) & 0xff), org);
 #endif
 					org++;
 					p++;
 					if (++col == maxcol) {
-						org = screen_pos(currcons, p/2, viewed);
+						org = screen_pos(vc, p/2, viewed);
 						col = 0;
 					}
 				}
@@ -413,11 +417,11 @@
 				unsigned short w;
 
 				w = get_unaligned(((const unsigned short *)con_buf0));
-				vcs_scr_writew(currcons, w, org++);
+				vcs_scr_writew(vc, w, org++);
 				con_buf0 += 2;
 				this_round -= 2;
 				if (++col == maxcol) {
-					org = screen_pos(currcons, p, viewed);
+					org = screen_pos(vc, p, viewed);
 					col = 0;
 					p += maxcol;
 				}
@@ -427,9 +431,9 @@
 
 				c = *con_buf0++;
 #ifdef __BIG_ENDIAN
-				vcs_scr_writew(currcons, (vcs_scr_readw(currcons, org) & 0xff) | (c << 8), org);
+				vcs_scr_writew(vc, (vcs_scr_readw(vc, org) & 0xff) | (c << 8), org);
 #else
-				vcs_scr_writew(currcons, (vcs_scr_readw(currcons, org) & 0xff00) | c, org);
+				vcs_scr_writew(vc, (vcs_scr_readw(vc, org) & 0xff00) | c, org);
 #endif
 			}
 		}
diff -Nru a/drivers/char/viocons.c b/drivers/char/viocons.c
--- a/drivers/char/viocons.c	2005-03-01 23:38:43 -08:00
+++ b/drivers/char/viocons.c	2005-03-01 23:38:43 -08:00
@@ -61,8 +61,8 @@
 #define VIOCONS_KERN_WARN	KERN_WARNING "viocons: "
 #define VIOCONS_KERN_INFO	KERN_INFO "viocons: "
 
-static spinlock_t consolelock = SPIN_LOCK_UNLOCKED;
-static spinlock_t consoleloglock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(consolelock);
+static DEFINE_SPINLOCK(consoleloglock);
 
 #ifdef CONFIG_MAGIC_SYSRQ
 static int vio_sysrq_pressed;
diff -Nru a/drivers/char/vt.c b/drivers/char/vt.c
--- a/drivers/char/vt.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/char/vt.c	2005-03-01 23:39:09 -08:00
@@ -40,15 +40,6 @@
  *     - Arno Griffioen <arno@usn.nl>
  *     - David Carter <carter@cs.bris.ac.uk>
  * 
- *   Note that the abstract console driver allows all consoles to be of
- *   potentially different sizes, so the following variables depend on the
- *   current console (currcons):
- *
- *     - video_num_columns
- *     - video_num_lines
- *     - video_size_row
- *     - can_do_color
- *
  *   The abstract console driver provides a generic interface for a text
  *   console. It supports VGA text mode, frame buffer based graphical consoles
  *   and special graphics processors that are only accessible through some
@@ -146,13 +137,13 @@
 static int con_open(struct tty_struct *, struct file *);
 static void vc_init(unsigned int console, unsigned int rows,
 		    unsigned int cols, int do_clear);
-static void gotoxy(int currcons, int new_x, int new_y);
+static void gotoxy(struct vc_data *vc, int new_x, int new_y);
 static void save_cur(int currcons);
 static void reset_terminal(int currcons, int do_clear);
 static void con_flush_chars(struct tty_struct *tty);
 static void set_vesa_blanking(char __user *p);
-static void set_cursor(int currcons);
-static void hide_cursor(int currcons);
+static void set_cursor(struct vc_data *vc);
+static void hide_cursor(struct vc_data *vc);
 static void console_callback(void *ignored);
 static void blank_screen_t(unsigned long dummy);
 
@@ -223,28 +214,32 @@
  *	Low-Level Functions
  */
 
-#define IS_FG (currcons == fg_console)
+#define IS_FG			(currcons == fg_console)
+#define IS_FG_VC(vc)		(vc == vc_cons[fg_console].d)
+
 #define IS_VISIBLE CON_IS_VISIBLE(vc_cons[currcons].d)
 
 #ifdef VT_BUF_VRAM_ONLY
-#define DO_UPDATE 0
+#define DO_UPDATE		0
+#define DO_UPDATE_VC(vc)	0
 #else
-#define DO_UPDATE IS_VISIBLE
+#define DO_UPDATE 		IS_VISIBLE
+#define DO_UPDATE_VC(vc)	CON_IS_VISIBLE(vc)
 #endif
 
 static int pm_con_request(struct pm_dev *dev, pm_request_t rqst, void *data);
 static struct pm_dev *pm_con;
 
-static inline unsigned short *screenpos(int currcons, int offset, int viewed)
+static inline unsigned short *screenpos(struct vc_data *vc, int offset, int viewed)
 {
 	unsigned short *p;
 	
 	if (!viewed)
-		p = (unsigned short *)(origin + offset);
-	else if (!sw->con_screen_pos)
-		p = (unsigned short *)(visible_origin + offset);
+		p = (unsigned short *)(vc->vc_origin + offset);
+	else if (!vc->vc_sw->con_screen_pos)
+		p = (unsigned short *)(vc->vc_visible_origin + offset);
 	else
-		p = sw->con_screen_pos(vc_cons[currcons].d, offset);
+		p = vc->vc_sw->con_screen_pos(vc, offset);
 	return p;
 }
 
@@ -265,14 +260,15 @@
 
 	if (t+nr >= b)
 		nr = b - t - 1;
-	if (b > video_num_lines || t >= b || nr < 1)
+	if (b > vc_cons[currcons].d->vc_rows || t >= b || nr < 1)
 		return;
 	if (IS_VISIBLE && sw->con_scroll(vc_cons[currcons].d, t, b, SM_UP, nr))
 		return;
-	d = (unsigned short *) (origin+video_size_row*t);
-	s = (unsigned short *) (origin+video_size_row*(t+nr));
-	scr_memmovew(d, s, (b-t-nr) * video_size_row);
-	scr_memsetw(d + (b-t-nr) * video_num_columns, video_erase_char, video_size_row*nr);
+	d = (unsigned short *) (origin+vc_cons[currcons].d->vc_size_row*t);
+	s = (unsigned short *) (origin+vc_cons[currcons].d->vc_size_row*(t+nr));
+	scr_memmovew(d, s, (b-t-nr) * vc_cons[currcons].d->vc_size_row);
+	scr_memsetw(d + (b-t-nr) * vc_cons[currcons].d->vc_cols, video_erase_char,
+			vc_cons[currcons].d->vc_size_row * nr);
 }
 
 static void
@@ -283,40 +279,40 @@
 
 	if (t+nr >= b)
 		nr = b - t - 1;
-	if (b > video_num_lines || t >= b || nr < 1)
+	if (b > vc_cons[currcons].d->vc_rows || t >= b || nr < 1)
 		return;
 	if (IS_VISIBLE && sw->con_scroll(vc_cons[currcons].d, t, b, SM_DOWN, nr))
 		return;
-	s = (unsigned short *) (origin+video_size_row*t);
-	step = video_num_columns * nr;
-	scr_memmovew(s + step, s, (b-t-nr)*video_size_row);
+	s = (unsigned short *) (origin+vc_cons[currcons].d->vc_size_row*t);
+	step = vc_cons[currcons].d->vc_cols * nr;
+	scr_memmovew(s + step, s, (b-t-nr)*vc_cons[currcons].d->vc_size_row);
 	scr_memsetw(s, video_erase_char, 2*step);
 }
 
-static void do_update_region(int currcons, unsigned long start, int count)
+static void do_update_region(struct vc_data *vc, unsigned long start, int count)
 {
 #ifndef VT_BUF_VRAM_ONLY
 	unsigned int xx, yy, offset;
 	u16 *p;
 
 	p = (u16 *) start;
-	if (!sw->con_getxy) {
-		offset = (start - origin) / 2;
-		xx = offset % video_num_columns;
-		yy = offset / video_num_columns;
+	if (!vc->vc_sw->con_getxy) {
+		offset = (start - vc->vc_origin) / 2;
+		xx = offset % vc->vc_cols;
+		yy = offset / vc->vc_cols;
 	} else {
 		int nxx, nyy;
-		start = sw->con_getxy(vc_cons[currcons].d, start, &nxx, &nyy);
+		start = vc->vc_sw->con_getxy(vc, start, &nxx, &nyy);
 		xx = nxx; yy = nyy;
 	}
 	for(;;) {
 		u16 attrib = scr_readw(p) & 0xff00;
 		int startx = xx;
 		u16 *q = p;
-		while (xx < video_num_columns && count) {
+		while (xx < vc->vc_cols && count) {
 			if (attrib != (scr_readw(p) & 0xff00)) {
 				if (p > q)
-					sw->con_putcs(vc_cons[currcons].d, q, p-q, yy, startx);
+					vc->vc_sw->con_putcs(vc, q, p-q, yy, startx);
 				startx = xx;
 				q = p;
 				attrib = scr_readw(p) & 0xff00;
@@ -326,14 +322,14 @@
 			count--;
 		}
 		if (p > q)
-			sw->con_putcs(vc_cons[currcons].d, q, p-q, yy, startx);
+			vc->vc_sw->con_putcs(vc, q, p-q, yy, startx);
 		if (!count)
 			break;
 		xx = 0;
 		yy++;
-		if (sw->con_getxy) {
+		if (vc->vc_sw->con_getxy) {
 			p = (u16 *)start;
-			start = sw->con_getxy(vc_cons[currcons].d, start, NULL, NULL);
+			start = vc->vc_sw->con_getxy(vc, start, NULL, NULL);
 		}
 	}
 #endif
@@ -344,9 +340,9 @@
 	WARN_CONSOLE_UNLOCKED();
 
 	if (DO_UPDATE) {
-		hide_cursor(currcons);
-		do_update_region(currcons, start, count);
-		set_cursor(currcons);
+		hide_cursor(vc_cons[currcons].d);
+		do_update_region(vc_cons[currcons].d, start, count);
+		set_cursor(vc_cons[currcons].d);
 	}
 }
 
@@ -370,7 +366,7 @@
  */
 	{
 	u8 a = color;
-	if (!can_do_color)
+	if (!vc_cons[currcons].d->vc_can_do_color)
 		return _intensity |
 		       (_underline ? 4 : 0) |
 		       (_reverse ? 8 : 0) |
@@ -401,31 +397,30 @@
 }
 
 /* Note: inverting the screen twice should revert to the original state */
-
-void invert_screen(int currcons, int offset, int count, int viewed)
+void invert_screen(struct vc_data *vc, int offset, int count, int viewed)
 {
 	unsigned short *p;
 
 	WARN_CONSOLE_UNLOCKED();
 
 	count /= 2;
-	p = screenpos(currcons, offset, viewed);
-	if (sw->con_invert_region)
-		sw->con_invert_region(vc_cons[currcons].d, p, count);
+	p = screenpos(vc, offset, viewed);
+	if (vc->vc_sw->con_invert_region)
+		vc->vc_sw->con_invert_region(vc, p, count);
 #ifndef VT_BUF_VRAM_ONLY
 	else {
 		u16 *q = p;
 		int cnt = count;
 		u16 a;
 
-		if (!can_do_color) {
+		if (!vc->vc_can_do_color) {
 			while (cnt--) {
 			    a = scr_readw(q);
 			    a ^= 0x0800;
 			    scr_writew(a, q);
 			    q++;
 			}
-		} else if (hi_font_mask == 0x100) {
+		} else if (vc->vc_hi_font_mask == 0x100) {
 			while (cnt--) {
 				a = scr_readw(q);
 				a = ((a) & 0x11ff) | (((a) & 0xe000) >> 4) | (((a) & 0x0e00) << 4);
@@ -442,12 +437,12 @@
 		}
 	}
 #endif
-	if (DO_UPDATE)
-		do_update_region(currcons, (unsigned long) p, count);
+	if (DO_UPDATE_VC(vc))
+		do_update_region(vc, (unsigned long) p, count);
 }
 
 /* used by selection: complement pointer position */
-void complement_pos(int currcons, int offset)
+void complement_pos(struct vc_data *vc, int offset)
 {
 	static unsigned short *p;
 	static unsigned short old;
@@ -457,21 +452,21 @@
 
 	if (p) {
 		scr_writew(old, p);
-		if (DO_UPDATE)
-			sw->con_putc(vc_cons[currcons].d, old, oldy, oldx);
+		if (DO_UPDATE_VC(vc))
+			vc->vc_sw->con_putc(vc, old, oldy, oldx);
 	}
 	if (offset == -1)
 		p = NULL;
 	else {
 		unsigned short new;
-		p = screenpos(currcons, offset, 1);
+		p = screenpos(vc, offset, 1);
 		old = scr_readw(p);
-		new = old ^ complement_mask;
+		new = old ^ vc->vc_complement_mask;
 		scr_writew(new, p);
-		if (DO_UPDATE) {
-			oldx = (offset >> 1) % video_num_columns;
-			oldy = (offset >> 1) / video_num_columns;
-			sw->con_putc(vc_cons[currcons].d, new, oldy, oldx);
+		if (DO_UPDATE_VC(vc)) {
+			oldx = (offset >> 1) % vc->vc_cols;
+			oldy = (offset >> 1) / vc->vc_cols;
+			vc->vc_sw->con_putc(vc, new, oldy, oldx);
 		}
 	}
 }
@@ -480,7 +475,7 @@
 {
 	unsigned short *p, *q = (unsigned short *) pos;
 
-	p = q + video_num_columns - nr - x;
+	p = q + vc_cons[currcons].d->vc_cols - nr - x;
 	while (--p >= q)
 		scr_writew(scr_readw(p), p + nr);
 	scr_memsetw(q, video_erase_char, nr*2);
@@ -488,7 +483,7 @@
 	if (DO_UPDATE) {
 		unsigned short oldattr = attr;
 		sw->con_bmove(vc_cons[currcons].d,y,x,y,x+nr,1,
-			      video_num_columns-x-nr);
+			      vc_cons[currcons].d->vc_cols-x-nr);
 		attr = video_erase_char >> 8;
 		while (nr--)
 			sw->con_putc(vc_cons[currcons].d,
@@ -502,7 +497,7 @@
 	unsigned int i = x;
 	unsigned short *p = (unsigned short *) pos;
 
-	while (++i <= video_num_columns - nr) {
+	while (++i <= vc_cons[currcons].d->vc_cols - nr) {
 		scr_writew(scr_readw(p+nr), p);
 		p++;
 	}
@@ -511,22 +506,22 @@
 	if (DO_UPDATE) {
 		unsigned short oldattr = attr;
 		sw->con_bmove(vc_cons[currcons].d, y, x+nr, y, x, 1,
-			      video_num_columns-x-nr);
+			      vc_cons[currcons].d->vc_cols-x-nr);
 		attr = video_erase_char >> 8;
 		while (nr--)
 			sw->con_putc(vc_cons[currcons].d,
 				     video_erase_char, y,
-				     video_num_columns-1-nr);
+				     vc_cons[currcons].d->vc_cols-1-nr);
 		attr = oldattr;
 	}
 }
 
 static int softcursor_original;
 
-static void add_softcursor(int currcons)
+static void add_softcursor(struct vc_data *vc)
 {
-	int i = scr_readw((u16 *) pos);
-	u32 type = cursor_type;
+	int i = scr_readw((u16 *) vc->vc_pos);
+	u32 type = vc->vc_cursor_type;
 
 	if (! (type & 0x10)) return;
 	if (softcursor_original != -1) return;
@@ -535,41 +530,43 @@
 	i ^= ((type) & 0xff00 );
 	if ((type & 0x20) && ((softcursor_original & 0x7000) == (i & 0x7000))) i ^= 0x7000;
 	if ((type & 0x40) && ((i & 0x700) == ((i & 0x7000) >> 4))) i ^= 0x0700;
-	scr_writew(i, (u16 *) pos);
-	if (DO_UPDATE)
-		sw->con_putc(vc_cons[currcons].d, i, y, x);
+	scr_writew(i, (u16 *) vc->vc_pos);
+	if (DO_UPDATE_VC(vc))
+		vc->vc_sw->con_putc(vc, i, vc->vc_y, vc->vc_x);
 }
 
-static void hide_softcursor(int currcons)
+static void hide_softcursor(struct vc_data *vc)
 {
 	if (softcursor_original != -1) {
-		scr_writew(softcursor_original,(u16 *) pos);
-		if (DO_UPDATE)
-			sw->con_putc(vc_cons[currcons].d, softcursor_original, y, x);
+		scr_writew(softcursor_original, (u16 *)vc->vc_pos);
+		if (DO_UPDATE_VC(vc))
+			vc->vc_sw->con_putc(vc, softcursor_original,
+					vc->vc_y, vc->vc_x);
 		softcursor_original = -1;
 	}
 }
 
-static void hide_cursor(int currcons)
+static void hide_cursor(struct vc_data *vc)
 {
-	if (currcons == sel_cons)
+	if (vc == sel_cons)
 		clear_selection();
-	sw->con_cursor(vc_cons[currcons].d,CM_ERASE);
-	hide_softcursor(currcons);
+	vc->vc_sw->con_cursor(vc, CM_ERASE);
+	hide_softcursor(vc);
 }
 
-static void set_cursor(int currcons)
+static void set_cursor(struct vc_data *vc)
 {
-    if (!IS_FG || console_blanked || vcmode == KD_GRAPHICS)
-	return;
-    if (deccm) {
-	if (currcons == sel_cons)
-		clear_selection();
-	add_softcursor(currcons);
-	if ((cursor_type & 0x0f) != 1)
-	    sw->con_cursor(vc_cons[currcons].d,CM_DRAW);
-    } else
-	hide_cursor(currcons);
+	if (!IS_FG_VC(vc) || console_blanked ||
+	    vc->vc_vt->vc_mode == KD_GRAPHICS)
+		return;
+	if (vc->vc_deccm) {
+		if (vc == sel_cons)
+			clear_selection();
+		add_softcursor(vc);
+		if ((vc->vc_cursor_type & 0x0f) != 1)
+			vc->vc_sw->con_cursor(vc, CM_DRAW);
+	} else
+		hide_cursor(vc);
 }
 
 static void set_origin(int currcons)
@@ -582,7 +579,7 @@
 		origin = (unsigned long) screenbuf;
 	visible_origin = origin;
 	scr_end = origin + screenbuf_size;
-	pos = origin + video_size_row*y + 2*x;
+	pos = origin + vc_cons[currcons].d->vc_size_row*y + 2*x;
 }
 
 static inline void save_screen(int currcons)
@@ -623,7 +620,7 @@
 
 	if (is_switch) {
 		currcons = fg_console;
-		hide_cursor(currcons);
+		hide_cursor(vc_cons[currcons].d);
 		if (fg_console != new_console) {
 			struct vc_data **display = vc_cons[new_console].d->vc_display_fg;
 			old_console = (*display) ? (*display)->vc_num : fg_console;
@@ -640,7 +637,7 @@
 		}
 	} else {
 		currcons = new_console;
-		hide_cursor(currcons);
+		hide_cursor(vc_cons[currcons].d);
 	}
 
 	if (redraw) {
@@ -661,9 +658,9 @@
 			clear_buffer_attributes(currcons);
 		}
 		if (update && vcmode != KD_GRAPHICS)
-			do_update_region(currcons, origin, screenbuf_size/2);
+			do_update_region(vc_cons[currcons].d, origin, screenbuf_size/2);
 	}
-	set_cursor(currcons);
+	set_cursor(vc_cons[currcons].d);
 	if (is_switch) {
 		set_leds();
 		compute_shiftstate();
@@ -696,13 +693,14 @@
     vc_cons[currcons].d->vc_uni_pagedir = 0;
     hi_font_mask = 0;
     complement_mask = 0;
-    can_do_color = 0;
+    vc_cons[currcons].d->vc_can_do_color = 0;
     sw->con_init(vc_cons[currcons].d, init);
     if (!complement_mask)
-        complement_mask = can_do_color ? 0x7700 : 0x0800;
+        complement_mask =
+		vc_cons[currcons].d->vc_can_do_color ? 0x7700 : 0x0800;
     s_complement_mask = complement_mask;
-    video_size_row = video_num_columns<<1;
-    screenbuf_size = video_num_lines*video_size_row;
+    vc_cons[currcons].d->vc_size_row = vc_cons[currcons].d->vc_cols<<1;
+    screenbuf_size = vc_cons[currcons].d->vc_rows * vc_cons[currcons].d->vc_size_row;
 }
 
 int vc_allocate(unsigned int currcons)	/* return 0 on success */
@@ -730,6 +728,7 @@
 	    memset((void *)p, 0, structsize);
 	    vc_cons[currcons].d = (struct vc_data *)p;
 	    vt_cons[currcons] = (struct vt_struct *)(p+sizeof(struct vc_data));
+	    vc_cons[currcons].d->vc_vt = vt_cons[currcons];
 	    visual_init(currcons, 1);
 	    if (!*vc_cons[currcons].d->vc_uni_pagedir_loc)
 		con_set_default_unimap(currcons);
@@ -742,7 +741,7 @@
 	    }
 	    screenbuf = (unsigned short *) q;
 	    kmalloced = 1;
-	    vc_init(currcons, video_num_lines, video_num_columns, 1);
+	    vc_init(currcons, vc_cons[currcons].d->vc_rows, vc_cons[currcons].d->vc_cols, 1);
 
 	    if (!pm_con) {
 		    pm_con = pm_register(PM_SYS_DEV,
@@ -785,21 +784,21 @@
 	if (cols > VC_RESIZE_MAXCOL || lines > VC_RESIZE_MAXROW)
 		return -EINVAL;
 
-	new_cols = (cols ? cols : video_num_columns);
-	new_rows = (lines ? lines : video_num_lines);
+	new_cols = (cols ? cols : vc_cons[currcons].d->vc_cols);
+	new_rows = (lines ? lines : vc_cons[currcons].d->vc_rows);
 	new_row_size = new_cols << 1;
 	new_screen_size = new_row_size * new_rows;
 
-	if (new_cols == video_num_columns && new_rows == video_num_lines)
+	if (new_cols == vc_cons[currcons].d->vc_cols && new_rows == vc_cons[currcons].d->vc_rows)
 		return 0;
 
 	newscreen = (unsigned short *) kmalloc(new_screen_size, GFP_USER);
 	if (!newscreen)
 		return -ENOMEM;
 
-	old_rows = video_num_lines;
-	old_cols = video_num_columns;
-	old_row_size = video_size_row;
+	old_rows = vc_cons[currcons].d->vc_rows;
+	old_cols = vc_cons[currcons].d->vc_cols;
+	old_row_size = vc_cons[currcons].d->vc_size_row;
 	old_screen_size = screenbuf_size;
 
 	err = resize_screen(currcons, new_cols, new_rows);
@@ -808,9 +807,9 @@
 		return err;
 	}
 
-	video_num_lines = new_rows;
-	video_num_columns = new_cols;
-	video_size_row = new_row_size;
+	vc_cons[currcons].d->vc_rows = new_rows;
+	vc_cons[currcons].d->vc_cols = new_cols;
+	vc_cons[currcons].d->vc_size_row = new_row_size;
 	screenbuf_size = new_screen_size;
 
 	rlth = min(old_row_size, new_row_size);
@@ -841,16 +840,16 @@
 
 	/* do part of a reset_terminal() */
 	top = 0;
-	bottom = video_num_lines;
-	gotoxy(currcons, x, y);
+	bottom = vc_cons[currcons].d->vc_rows;
+	gotoxy(vc_cons[currcons].d, x, y);
 	save_cur(currcons);
 
 	if (vc_cons[currcons].d->vc_tty) {
 		struct winsize ws, *cws = &vc_cons[currcons].d->vc_tty->winsize;
 
 		memset(&ws, 0, sizeof(ws));
-		ws.ws_row = video_num_lines;
-		ws.ws_col = video_num_columns;
+		ws.ws_row = vc_cons[currcons].d->vc_rows;
+		ws.ws_col = vc_cons[currcons].d->vc_cols;
 		ws.ws_ypixel = video_scan_lines;
 		if ((ws.ws_row != cws->ws_row || ws.ws_col != cws->ws_col) &&
 		    vc_cons[currcons].d->vc_tty->pgrp > 0)
@@ -913,38 +912,40 @@
  * might also be negative. If the given position is out of
  * bounds, the cursor is placed at the nearest margin.
  */
-static void gotoxy(int currcons, int new_x, int new_y)
+static void gotoxy(struct vc_data *vc, int new_x, int new_y)
 {
 	int min_y, max_y;
 
 	if (new_x < 0)
-		x = 0;
-	else
-		if (new_x >= video_num_columns)
-			x = video_num_columns - 1;
+		vc->vc_x = 0;
+	else {
+		if (new_x >= vc->vc_cols)
+			vc->vc_x = vc->vc_cols - 1;
 		else
-			x = new_x;
- 	if (decom) {
-		min_y = top;
-		max_y = bottom;
+			vc->vc_x = new_x;
+	}
+
+ 	if (vc->vc_decom) {
+		min_y = vc->vc_top;
+		max_y = vc->vc_bottom;
 	} else {
 		min_y = 0;
-		max_y = video_num_lines;
+		max_y = vc->vc_rows;
 	}
 	if (new_y < min_y)
-		y = min_y;
+		vc->vc_y = min_y;
 	else if (new_y >= max_y)
-		y = max_y - 1;
+		vc->vc_y = max_y - 1;
 	else
-		y = new_y;
-	pos = origin + y*video_size_row + (x<<1);
-	need_wrap = 0;
+		vc->vc_y = new_y;
+	vc->vc_pos = vc->vc_origin + vc->vc_y * vc->vc_size_row + (vc->vc_x<<1);
+	vc->vc_need_wrap = 0;
 }
 
 /* for absolute user moves, when decom is set */
 static void gotoxay(int currcons, int new_x, int new_y)
 {
-	gotoxy(currcons, new_x, decom ? (top+new_y) : new_y);
+	gotoxy(vc_cons[currcons].d, new_x, decom ? (top+new_y) : new_y);
 }
 
 void scrollback(int lines)
@@ -952,7 +953,7 @@
 	int currcons = fg_console;
 
 	if (!lines)
-		lines = video_num_lines/2;
+		lines = vc_cons[currcons].d->vc_rows/2;
 	scrolldelta(-lines);
 }
 
@@ -961,7 +962,7 @@
 	int currcons = fg_console;
 
 	if (!lines)
-		lines = video_num_lines/2;
+		lines = vc_cons[currcons].d->vc_rows/2;
 	scrolldelta(lines);
 }
 
@@ -972,9 +973,9 @@
 	 */
     	if (y+1 == bottom)
 		scrup(currcons,top,bottom,1);
-	else if (y < video_num_lines-1) {
+	else if (y < vc_cons[currcons].d->vc_rows-1) {
 	    	y++;
-		pos += video_size_row;
+		pos += vc_cons[currcons].d->vc_size_row;
 	}
 	need_wrap = 0;
 }
@@ -988,7 +989,7 @@
 		scrdown(currcons,top,bottom,1);
 	else if (y > 0) {
 		y--;
-		pos -= video_size_row;
+		pos -= vc_cons[currcons].d->vc_size_row;
 	}
 	need_wrap = 0;
 }
@@ -1025,10 +1026,10 @@
 			if (DO_UPDATE) {
 				/* do in two stages */
 				sw->con_clear(vc_cons[currcons].d, y, x, 1,
-					      video_num_columns-x);
+					      vc_cons[currcons].d->vc_cols-x);
 				sw->con_clear(vc_cons[currcons].d, y+1, 0,
-					      video_num_lines-y-1,
-					      video_num_columns);
+					      vc_cons[currcons].d->vc_rows-y-1,
+					      vc_cons[currcons].d->vc_cols);
 			}
 			break;
 		case 1:	/* erase from start to cursor */
@@ -1037,18 +1038,18 @@
 			if (DO_UPDATE) {
 				/* do in two stages */
 				sw->con_clear(vc_cons[currcons].d, 0, 0, y,
-					      video_num_columns);
+					      vc_cons[currcons].d->vc_cols);
 				sw->con_clear(vc_cons[currcons].d, y, 0, 1,
 					      x + 1);
 			}
 			break;
 		case 2: /* erase whole display */
-			count = video_num_columns * video_num_lines;
+			count = vc_cons[currcons].d->vc_cols * vc_cons[currcons].d->vc_rows;
 			start = (unsigned short *) origin;
 			if (DO_UPDATE)
 				sw->con_clear(vc_cons[currcons].d, 0, 0,
-					      video_num_lines,
-					      video_num_columns);
+					      vc_cons[currcons].d->vc_rows,
+					      vc_cons[currcons].d->vc_cols);
 			break;
 		default:
 			return;
@@ -1064,11 +1065,11 @@
 
 	switch (vpar) {
 		case 0:	/* erase from cursor to end of line */
-			count = video_num_columns-x;
+			count = vc_cons[currcons].d->vc_cols-x;
 			start = (unsigned short *) pos;
 			if (DO_UPDATE)
 				sw->con_clear(vc_cons[currcons].d, y, x, 1,
-					      video_num_columns-x);
+					      vc_cons[currcons].d->vc_cols-x);
 			break;
 		case 1:	/* erase from start of line to cursor */
 			start = (unsigned short *) (pos - (x<<1));
@@ -1079,10 +1080,10 @@
 			break;
 		case 2: /* erase whole line */
 			start = (unsigned short *) (pos - (x<<1));
-			count = video_num_columns;
+			count = vc_cons[currcons].d->vc_cols;
 			if (DO_UPDATE)
 				sw->con_clear(vc_cons[currcons].d, y, 0, 1,
-					      video_num_columns);
+					      vc_cons[currcons].d->vc_cols);
 			break;
 		default:
 			return;
@@ -1097,7 +1098,7 @@
 
 	if (!vpar)
 		vpar++;
-	count = (vpar > video_num_columns-x) ? (video_num_columns-x) : vpar;
+	count = (vpar > vc_cons[currcons].d->vc_cols-x) ? (vc_cons[currcons].d->vc_cols-x) : vpar;
 
 	scr_memsetw((unsigned short *) pos, video_erase_char, 2 * count);
 	if (DO_UPDATE)
@@ -1270,7 +1271,7 @@
 			case 3:	/* 80/132 mode switch unimplemented */
 				deccolm = on_off;
 #if 0
-				(void) vc_resize(deccolm ? 132 : 80, video_num_lines);
+				(void) vc_resize(deccolm ? 132 : 80, vc_cons[currcons].d->vc_rows);
 				/* this alone does not suffice; some user mode
 				   utility has to change the hardware regs */
 #endif
@@ -1278,7 +1279,7 @@
 			case 5:			/* Inverted screen on/off */
 				if (decscnm != on_off) {
 					decscnm = on_off;
-					invert_screen(currcons, 0, screenbuf_size, 0);
+					invert_screen(vc_cons[currcons].d, 0, screenbuf_size, 0);
 					update_attr(currcons);
 				}
 				break;
@@ -1325,14 +1326,16 @@
 {
 	switch(par[0]) {
 		case 1:	/* set color for underline mode */
-			if (can_do_color && par[1] < 16) {
+			if (vc_cons[currcons].d->vc_can_do_color &&
+					par[1] < 16) {
 				ulcolor = color_table[par[1]];
 				if (underline)
 					update_attr(currcons);
 			}
 			break;
 		case 2:	/* set color for half intensity mode */
-			if (can_do_color && par[1] < 16) {
+			if (vc_cons[currcons].d->vc_can_do_color &&
+					par[1] < 16) {
 				halfcolor = color_table[par[1]];
 				if (intensity == 0)
 					update_attr(currcons);
@@ -1381,8 +1384,8 @@
 /* console_sem is held */
 static void csi_at(int currcons, unsigned int nr)
 {
-	if (nr > video_num_columns - x)
-		nr = video_num_columns - x;
+	if (nr > vc_cons[currcons].d->vc_cols - x)
+		nr = vc_cons[currcons].d->vc_cols - x;
 	else if (!nr)
 		nr = 1;
 	insert_char(currcons, nr);
@@ -1391,8 +1394,8 @@
 /* console_sem is held */
 static void csi_L(int currcons, unsigned int nr)
 {
-	if (nr > video_num_lines - y)
-		nr = video_num_lines - y;
+	if (nr > vc_cons[currcons].d->vc_rows - y)
+		nr = vc_cons[currcons].d->vc_rows - y;
 	else if (!nr)
 		nr = 1;
 	scrdown(currcons,y,bottom,nr);
@@ -1402,8 +1405,8 @@
 /* console_sem is held */
 static void csi_P(int currcons, unsigned int nr)
 {
-	if (nr > video_num_columns - x)
-		nr = video_num_columns - x;
+	if (nr > vc_cons[currcons].d->vc_cols - x)
+		nr = vc_cons[currcons].d->vc_cols - x;
 	else if (!nr)
 		nr = 1;
 	delete_char(currcons, nr);
@@ -1412,8 +1415,8 @@
 /* console_sem is held */
 static void csi_M(int currcons, unsigned int nr)
 {
-	if (nr > video_num_lines - y)
-		nr = video_num_lines - y;
+	if (nr > vc_cons[currcons].d->vc_rows - y)
+		nr = vc_cons[currcons].d->vc_rows - y;
 	else if (!nr)
 		nr=1;
 	scrup(currcons,y,bottom,nr);
@@ -1438,7 +1441,7 @@
 /* console_sem is held */
 static void restore_cur(int currcons)
 {
-	gotoxy(currcons,saved_x,saved_y);
+	gotoxy(vc_cons[currcons].d,saved_x,saved_y);
 	intensity	= s_intensity;
 	underline	= s_underline;
 	blink		= s_blink;
@@ -1460,7 +1463,7 @@
 static void reset_terminal(int currcons, int do_clear)
 {
 	top		= 0;
-	bottom		= video_num_lines;
+	bottom		= vc_cons[currcons].d->vc_rows;
 	vc_state	= ESnormal;
 	ques		= 0;
 	translate	= set_translate(LAT1_MAP,currcons);
@@ -1507,7 +1510,7 @@
 	bell_pitch = DEFAULT_BELL_PITCH;
 	bell_duration = DEFAULT_BELL_DURATION;
 
-	gotoxy(currcons,0,0);
+	gotoxy(vc_cons[currcons].d, 0, 0);
 	save_cur(currcons);
 	if (do_clear)
 	    csi_J(currcons,2);
@@ -1532,7 +1535,7 @@
 		return;
 	case 9:
 		pos -= (x << 1);
-		while (x < video_num_columns - 1) {
+		while (x < vc_cons[currcons].d->vc_cols - 1) {
 			x++;
 			if (tab_stop[x >> 5] & (1 << (x & 31)))
 				break;
@@ -1719,31 +1722,31 @@
 		switch(c) {
 		case 'G': case '`':
 			if (par[0]) par[0]--;
-			gotoxy(currcons,par[0],y);
+			gotoxy(vc_cons[currcons].d, par[0], y);
 			return;
 		case 'A':
 			if (!par[0]) par[0]++;
-			gotoxy(currcons,x,y-par[0]);
+			gotoxy(vc_cons[currcons].d, x, y-par[0]);
 			return;
 		case 'B': case 'e':
 			if (!par[0]) par[0]++;
-			gotoxy(currcons,x,y+par[0]);
+			gotoxy(vc_cons[currcons].d, x, y+par[0]);
 			return;
 		case 'C': case 'a':
 			if (!par[0]) par[0]++;
-			gotoxy(currcons,x+par[0],y);
+			gotoxy(vc_cons[currcons].d, x+par[0], y);
 			return;
 		case 'D':
 			if (!par[0]) par[0]++;
-			gotoxy(currcons,x-par[0],y);
+			gotoxy(vc_cons[currcons].d, x-par[0], y);
 			return;
 		case 'E':
 			if (!par[0]) par[0]++;
-			gotoxy(currcons,0,y+par[0]);
+			gotoxy(vc_cons[currcons].d, 0, y+par[0]);
 			return;
 		case 'F':
 			if (!par[0]) par[0]++;
-			gotoxy(currcons,0,y-par[0]);
+			gotoxy(vc_cons[currcons].d, 0, y-par[0]);
 			return;
 		case 'd':
 			if (par[0]) par[0]--;
@@ -1797,10 +1800,10 @@
 			if (!par[0])
 				par[0]++;
 			if (!par[1])
-				par[1] = video_num_lines;
+				par[1] = vc_cons[currcons].d->vc_rows;
 			/* Minimum allowed region is 2 lines */
 			if (par[0] < par[1] &&
-			    par[1] <= video_num_lines) {
+			    par[1] <= vc_cons[currcons].d->vc_rows) {
 				top=par[0]-1;
 				bottom=par[1];
 				gotoxay(currcons,0,0);
@@ -1847,7 +1850,7 @@
 			csi_J(currcons, 2);
 			video_erase_char =
 				(video_erase_char & 0xff00) | ' ';
-			do_update_region(currcons, origin, screenbuf_size/2);
+			do_update_region(vc_cons[currcons].d, origin, screenbuf_size/2);
 		}
 		return;
 	case ESsetG0:
@@ -1963,7 +1966,7 @@
 
 	/* undraw cursor first */
 	if (IS_FG)
-		hide_cursor(currcons);
+		hide_cursor(vc_cons[currcons].d);
 
 	while (!tty->stopped && count) {
 		int orig = *buf;
@@ -2065,7 +2068,7 @@
 				draw_x = x;
 				draw_from = pos;
 			}
-			if (x == video_num_columns - 1) {
+			if (x == vc_cons[currcons].d->vc_cols - 1) {
 				need_wrap = decawm;
 				draw_to = pos+2;
 			} else {
@@ -2102,7 +2105,7 @@
 	if (want_console >= 0) {
 		if (want_console != fg_console &&
 		    vc_cons_allocated(want_console)) {
-			hide_cursor(fg_console);
+			hide_cursor(vc_cons[fg_console].d);
 			change_console(want_console);
 			/* we only changed when the console had already
 			   been allocated - a new console is not created
@@ -2176,7 +2179,7 @@
 
 	/* undraw cursor first */
 	if (IS_FG)
-		hide_cursor(currcons);
+		hide_cursor(vc_cons[currcons].d);
 
 	start = (ushort *)pos;
 
@@ -2209,7 +2212,7 @@
 		}
 		scr_writew((attr << 8) + c, (unsigned short *) pos);
 		cnt++;
-		if (myx == video_num_columns - 1) {
+		if (myx == vc_cons[currcons].d->vc_cols - 1) {
 			need_wrap = 1;
 			continue;
 		}
@@ -2220,12 +2223,12 @@
 		if (IS_VISIBLE)
 			sw->con_putcs(vc_cons[currcons].d, start, cnt, y, x);
 		x += cnt;
-		if (x == video_num_columns) {
+		if (x == vc_cons[currcons].d->vc_cols) {
 			x--;
 			need_wrap = 1;
 		}
 	}
-	set_cursor(currcons);
+	set_cursor(vc_cons[currcons].d);
 
 	if (!oops_in_progress)
 		poke_blanked_console();
@@ -2438,7 +2441,7 @@
 	acquire_console_sem();
 	vt = tty->driver_data;
 	if (vt)
-		set_cursor(vt->vc_num);
+		set_cursor(vc_cons[vt->vc_num].d);
 	release_console_sem();
 }
 
@@ -2459,8 +2462,8 @@
 			vc_cons[currcons].d->vc_tty = tty;
 
 			if (!tty->winsize.ws_row && !tty->winsize.ws_col) {
-				tty->winsize.ws_row = video_num_lines;
-				tty->winsize.ws_col = video_num_columns;
+				tty->winsize.ws_row = vc_cons[currcons].d->vc_rows;
+				tty->winsize.ws_col = vc_cons[currcons].d->vc_cols;
 			}
 			release_console_sem();
 			vcs_make_devfs(tty);
@@ -2507,10 +2510,10 @@
 {
 	int j, k ;
 
-	video_num_columns = cols;
-	video_num_lines = rows;
-	video_size_row = cols<<1;
-	screenbuf_size = video_num_lines * video_size_row;
+	vc_cons[currcons].d->vc_cols = cols;
+	vc_cons[currcons].d->vc_rows = rows;
+	vc_cons[currcons].d->vc_size_row = cols<<1;
+	screenbuf_size = vc_cons[currcons].d->vc_rows * vc_cons[currcons].d->vc_size_row;
 
 	set_origin(currcons);
 	pos = origin;
@@ -2563,22 +2566,23 @@
 				alloc_bootmem(sizeof(struct vc_data));
 		vt_cons[currcons] = (struct vt_struct *)
 				alloc_bootmem(sizeof(struct vt_struct));
+		vc_cons[currcons].d->vc_vt = vt_cons[currcons];
 		visual_init(currcons, 1);
 		screenbuf = (unsigned short *) alloc_bootmem(screenbuf_size);
 		kmalloced = 0;
-		vc_init(currcons, video_num_lines, video_num_columns, 
+		vc_init(currcons, vc_cons[currcons].d->vc_rows, vc_cons[currcons].d->vc_cols,
 			currcons || !sw->con_save_screen);
 	}
 	currcons = fg_console = 0;
 	master_display_fg = vc_cons[currcons].d;
 	set_origin(currcons);
 	save_screen(currcons);
-	gotoxy(currcons,x,y);
+	gotoxy(vc_cons[currcons].d, x, y);
 	csi_J(currcons, 0);
 	update_screen(fg_console);
 	printk("Console: %s %s %dx%d",
-		can_do_color ? "colour" : "mono",
-		display_desc, video_num_columns, video_num_lines);
+		vc_cons[currcons].d->vc_can_do_color ? "colour" : "mono",
+		display_desc, vc_cons[currcons].d->vc_cols, vc_cons[currcons].d->vc_rows);
 	printable = 1;
 	printk("\n");
 
@@ -2690,7 +2694,7 @@
 		origin = (unsigned long) screenbuf;
 		visible_origin = origin;
 		scr_end = origin + screenbuf_size;
-		pos = origin + video_size_row*y + 2*x;
+		pos = origin + vc_cons[currcons].d->vc_size_row*y + 2*x;
 		visual_init(i, 0);
 		update_attr(i);
 
@@ -2788,7 +2792,7 @@
 
 	/* entering graphics mode? */
 	if (entering_gfx) {
-		hide_cursor(currcons);
+		hide_cursor(vc_cons[currcons].d);
 		save_screen(currcons);
 		sw->con_blank(vc_cons[currcons].d, -1, 1);
 		console_blanked = fg_console + 1;
@@ -2802,7 +2806,7 @@
 		return;
 	}
 
-	hide_cursor(currcons);
+	hide_cursor(vc_cons[currcons].d);
 	del_timer_sync(&console_timer);
 	blank_timer_expired = 0;
 
@@ -2824,7 +2828,7 @@
     	if (vesa_blank_mode)
 		sw->con_blank(vc_cons[currcons].d, vesa_blank_mode + 1, 0);
 }
-
+EXPORT_SYMBOL(do_blank_screen);
 
 /*
  * Called by timer as well as from vt_console_driver
@@ -2859,8 +2863,9 @@
 	if (console_blank_hook)
 		console_blank_hook(0);
 	set_palette(currcons);
-	set_cursor(fg_console);
+	set_cursor(vc_cons[fg_console].d);
 }
+EXPORT_SYMBOL(do_unblank_screen);
 
 /*
  * This is called by the outside world to cause a forced unblank, mostly for
@@ -3184,47 +3189,47 @@
  */
 
 /* used by selection */
-u16 screen_glyph(int currcons, int offset)
+u16 screen_glyph(struct vc_data *vc, int offset)
 {
-	u16 w = scr_readw(screenpos(currcons, offset, 1));
+	u16 w = scr_readw(screenpos(vc, offset, 1));
 	u16 c = w & 0xff;
 
-	if (w & hi_font_mask)
+	if (w & vc->vc_hi_font_mask)
 		c |= 0x100;
 	return c;
 }
 
 /* used by vcs - note the word offset */
-unsigned short *screen_pos(int currcons, int w_offset, int viewed)
+unsigned short *screen_pos(struct vc_data *vc, int w_offset, int viewed)
 {
-	return screenpos(currcons, 2 * w_offset, viewed);
+	return screenpos(vc, 2 * w_offset, viewed);
 }
 
-void getconsxy(int currcons, unsigned char *p)
+void getconsxy(struct vc_data *vc, unsigned char *p)
 {
-	p[0] = x;
-	p[1] = y;
+	p[0] = vc->vc_x;
+	p[1] = vc->vc_y;
 }
 
-void putconsxy(int currcons, unsigned char *p)
+void putconsxy(struct vc_data *vc, unsigned char *p)
 {
-	gotoxy(currcons, p[0], p[1]);
-	set_cursor(currcons);
+	gotoxy(vc, p[0], p[1]);
+	set_cursor(vc);
 }
 
-u16 vcs_scr_readw(int currcons, const u16 *org)
+u16 vcs_scr_readw(struct vc_data *vc, const u16 *org)
 {
-	if ((unsigned long)org == pos && softcursor_original != -1)
+	if ((unsigned long)org == vc->vc_pos && softcursor_original != -1)
 		return softcursor_original;
 	return scr_readw(org);
 }
 
-void vcs_scr_writew(int currcons, u16 val, u16 *org)
+void vcs_scr_writew(struct vc_data *vc, u16 val, u16 *org)
 {
 	scr_writew(val, org);
-	if ((unsigned long)org == pos) {
+	if ((unsigned long)org == vc->vc_pos) {
 		softcursor_original = -1;
-		add_softcursor(currcons);
+		add_softcursor(vc);
 	}
 }
 
diff -Nru a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c
--- a/drivers/char/vt_ioctl.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/char/vt_ioctl.c	2005-03-01 23:39:08 -08:00
@@ -37,7 +37,7 @@
 extern struct tty_driver *console_driver;
 
 #define VT_IS_IN_USE(i)	(console_driver->ttys[i] && console_driver->ttys[i]->count)
-#define VT_BUSY(i)	(VT_IS_IN_USE(i) || i == fg_console || i == sel_cons)
+#define VT_BUSY(i)	(VT_IS_IN_USE(i) || i == fg_console || vc_cons[i].d == sel_cons)
 
 /*
  * Console (vt and kd) routines, as defined by USL SVR4 manual, and by
diff -Nru a/drivers/char/watchdog/Kconfig b/drivers/char/watchdog/Kconfig
--- a/drivers/char/watchdog/Kconfig	2005-03-01 23:39:07 -08:00
+++ b/drivers/char/watchdog/Kconfig	2005-03-01 23:39:07 -08:00
@@ -93,6 +93,11 @@
 	  be built as a module by choosing M. The module will
 	  be called ixp4xx_wdt.
 
+	  Note: The internal IXP4xx watchdog does a soft CPU reset
+	  which doesn't reset any peripherals. There are circumstances
+	  where the watchdog will fail to reset the board correctly
+	  (e.g., if the boot ROM is in an unreadable state).
+
 	  Say N if you are unsure.
 
 config IXP2000_WATCHDOG
diff -Nru a/drivers/char/watchdog/alim7101_wdt.c b/drivers/char/watchdog/alim7101_wdt.c
--- a/drivers/char/watchdog/alim7101_wdt.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/char/watchdog/alim7101_wdt.c	2005-03-01 23:39:08 -08:00
@@ -12,6 +12,11 @@
  *  because this particular WDT has a very short timeout (1.6
  *  seconds) and it would be insane to count on any userspace
  *  daemon always getting scheduled within that time frame.
+ *
+ *  Additions:
+ *   Aug 23, 2004 - Added use_gpio module parameter for use on revision a1d PMUs
+ *                  found on very old cobalt hardware.
+ *                  -- Mike Waychison <michael.waychison@sun.com>
  */
 
 #include <linux/module.h>
@@ -38,6 +43,8 @@
 #define WDT_DISABLE 0x8C
 
 #define ALI_7101_WDT    0x92
+#define ALI_7101_GPIO   0x7D
+#define ALI_7101_GPIO_O 0x7E
 #define ALI_WDT_ARM     0x01
 
 /*
@@ -57,6 +64,10 @@
 module_param(timeout, int, 0);
 MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (1<=timeout<=3600, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ")");
 
+static int use_gpio = 0; /* Use the pic (for a1d revision alim7101) */
+module_param(use_gpio, int, 0);
+MODULE_PARM_DESC(use_gpio, "Use the gpio watchdog.  (required by old cobalt boards)");
+
 static void wdt_timer_ping(unsigned long);
 static struct timer_list timer;
 static unsigned long next_heartbeat;
@@ -90,6 +101,13 @@
 		pci_read_config_byte(alim7101_pmu, 0x92, &tmp);
 		pci_write_config_byte(alim7101_pmu, ALI_7101_WDT, (tmp & ~ALI_WDT_ARM));
 		pci_write_config_byte(alim7101_pmu, ALI_7101_WDT, (tmp | ALI_WDT_ARM));
+		if (use_gpio) {
+			pci_read_config_byte(alim7101_pmu, ALI_7101_GPIO_O, &tmp);
+			pci_write_config_byte(alim7101_pmu, ALI_7101_GPIO_O, tmp
+					| 0x20);
+			pci_write_config_byte(alim7101_pmu, ALI_7101_GPIO_O, tmp
+					& ~0x20);
+		}
 	} else {
 		printk(KERN_WARNING PFX "Heartbeat lost! Will not ping the watchdog\n");
 	}
@@ -106,11 +124,21 @@
 {
 	char	tmp;
 
-	pci_read_config_byte(alim7101_pmu, 0x92, &tmp);
-	if (writeval == WDT_ENABLE)
+	pci_read_config_byte(alim7101_pmu, ALI_7101_WDT, &tmp);
+	if (writeval == WDT_ENABLE) {
 		pci_write_config_byte(alim7101_pmu, ALI_7101_WDT, (tmp | ALI_WDT_ARM));
-	else
+		if (use_gpio) {
+			pci_read_config_byte(alim7101_pmu, ALI_7101_GPIO_O, &tmp);
+			pci_write_config_byte(alim7101_pmu, ALI_7101_GPIO_O, tmp & ~0x20);
+		}
+
+	} else {
 		pci_write_config_byte(alim7101_pmu, ALI_7101_WDT, (tmp & ~ALI_WDT_ARM));
+		if (use_gpio) {
+			pci_read_config_byte(alim7101_pmu, ALI_7101_GPIO_O, &tmp);
+			pci_write_config_byte(alim7101_pmu, ALI_7101_GPIO_O, tmp | 0x20);
+		}
+	}
 }
 
 static void wdt_startup(void)
@@ -334,7 +362,13 @@
 		return -EBUSY;
 	}
 	pci_read_config_byte(ali1543_south, 0x5e, &tmp);
-	if ((tmp & 0x1e) != 0x12) {
+	if ((tmp & 0x1e) == 0x00) {
+		if (!use_gpio) {
+			printk(KERN_INFO PFX "Detected old alim7101 revision 'a1d'.  If this is a cobalt board, set the 'use_gpio' module parameter.\n");
+			return -EBUSY;
+		} 
+		nowayout = 1;
+	} else if ((tmp & 0x1e) != 0x12 && (tmp & 0x1e) != 0x00) {
 		printk(KERN_INFO PFX "ALi 1543 South-Bridge does not have the correct revision number (???1001?) - WDT not set\n");
 		return -EBUSY;
 	}
@@ -362,6 +396,10 @@
 		printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n",
 			rc);
 		goto err_out_miscdev;
+	}
+
+	if (nowayout) {
+		__module_get(THIS_MODULE);
 	}
 
 	printk(KERN_INFO PFX "WDT driver for ALi M7101 initialised. timeout=%d sec (nowayout=%d)\n",
diff -Nru a/drivers/char/watchdog/i8xx_tco.c b/drivers/char/watchdog/i8xx_tco.c
--- a/drivers/char/watchdog/i8xx_tco.c	2005-03-01 23:38:51 -08:00
+++ b/drivers/char/watchdog/i8xx_tco.c	2005-03-01 23:38:51 -08:00
@@ -1,5 +1,5 @@
 /*
- *	i8xx_tco 0.06:	TCO timer driver for i8xx chipsets
+ *	i8xx_tco 0.07:	TCO timer driver for i8xx chipsets
  *
  *	(c) Copyright 2000 kernel concepts <nils@kernelconcepts.de>, All Rights Reserved.
  *				http://www.kernelconcepts.de
@@ -22,11 +22,22 @@
  *
  *	The TCO timer is implemented in the following I/O controller hubs:
  *	(See the intel documentation on http://developer.intel.com.)
- *	82801AA & 82801AB  chip : document number 290655-003, 290677-004,
- *	82801BA & 82801BAM chip : document number 290687-002, 298242-005,
- *	82801CA & 82801CAM chip : document number 290716-001, 290718-001,
- *	82801DB & 82801E   chip : document number 290744-001, 273599-001,
- *	82801EB & 82801ER  chip : document number 252516-001
+ *	82801AA  (ICH)    : document number 290655-003, 290677-014,
+ *	82801AB  (ICHO)   : document number 290655-003, 290677-014,
+ *	82801BA  (ICH2)   : document number 290687-002, 298242-027,
+ *	82801BAM (ICH2-M) : document number 290687-002, 298242-027,
+ *	82801CA  (ICH3-S) : document number 290733-003, 290739-013,
+ *	82801CAM (ICH3-M) : document number 290716-001, 290718-007,
+ *	82801DB  (ICH4)   : document number 290744-001, 290745-020,
+ *	82801DBM (ICH4-M) : document number 252337-001, 252663-005,
+ *	82801E   (C-ICH)  : document number 273599-001, 273645-002,
+ *	82801EB  (ICH5)   : document number 252516-001, 252517-003,
+ *	82801ER  (ICH5R)  : document number 252516-001, 252517-003,
+ *	82801FB  (ICH6)   : document number 301473-002, 301474-007,
+ *	82801FR  (ICH6R)  : document number 301473-002, 301474-007,
+ *	82801FBM (ICH6-M) : document number 301473-002, 301474-007,
+ *	82801FW  (ICH6W)  : document number 301473-001, 301474-007,
+ *	82801FRW (ICH6RW) : document number 301473-001, 301474-007
  *
  *  20000710 Nils Faerber
  *	Initial Version 0.01
@@ -49,6 +60,9 @@
  *  20030921 Wim Van Sebroeck <wim@iguana.be>
  *	0.06 change i810_margin to heartbeat, use module_param,
  *	     added notify system support, renamed module to i8xx_tco.
+ *  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.
  */
 
 /*
@@ -73,7 +87,7 @@
 #include "i8xx_tco.h"
 
 /* Module and version information */
-#define TCO_VERSION "0.06"
+#define TCO_VERSION "0.07"
 #define TCO_MODULE_NAME "i8xx TCO timer"
 #define TCO_DRIVER_NAME   TCO_MODULE_NAME ", v" TCO_VERSION
 #define PFX TCO_MODULE_NAME ": "
@@ -360,8 +374,14 @@
 	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0,	PCI_ANY_ID, PCI_ANY_ID, },
 	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12,	PCI_ANY_ID, PCI_ANY_ID, },
 	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0,	PCI_ANY_ID, PCI_ANY_ID, },
+	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12,	PCI_ANY_ID, PCI_ANY_ID, },
 	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801E_0,	PCI_ANY_ID, PCI_ANY_ID, },
 	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0,	PCI_ANY_ID, PCI_ANY_ID, },
+	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_0,	PCI_ANY_ID, PCI_ANY_ID, },
+	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1,	PCI_ANY_ID, PCI_ANY_ID, },
+	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_2,	PCI_ANY_ID, PCI_ANY_ID, },
+	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0,	PCI_ANY_ID, PCI_ANY_ID, },
+	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_1,	PCI_ANY_ID, PCI_ANY_ID, },
 	{ 0, },			/* End of list */
 };
 MODULE_DEVICE_TABLE (pci, i8xx_tco_pci_tbl);
diff -Nru a/drivers/char/watchdog/machzwd.c b/drivers/char/watchdog/machzwd.c
--- a/drivers/char/watchdog/machzwd.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/char/watchdog/machzwd.c	2005-03-01 23:38:53 -08:00
@@ -88,12 +88,6 @@
 	return inw(DATA_W);
 }
 
-static unsigned short zf_readb(unsigned char port)
-{
-	outb(port, INDEX);
-	return inb(DATA_B);
-}
-
 
 MODULE_AUTHOR("Fernando Fuganti <fuganti@conectiva.com.br>");
 MODULE_DESCRIPTION("MachZ ZF-Logic Watchdog driver");
@@ -155,13 +149,6 @@
 #endif
 
 
-/* STATUS register functions */
-
-static inline unsigned char zf_get_status(void)
-{
-	return zf_readb(STATUS);
-}
-
 static inline void zf_set_status(unsigned char new)
 {
 	zf_writeb(STATUS, new);
@@ -182,22 +169,6 @@
 
 
 /* WD#? counter functions */
-/*
- *	Just get current counter value
- */
-
-static inline unsigned short zf_get_timer(unsigned char n)
-{
-	switch(n){
-		case WD1:
-			return zf_readw(COUNTER_1);
-		case WD2:
-			return zf_readb(COUNTER_2);
-		default:
-			return 0;
-	}
-}
-
 /*
  *	Just set counter value
  */
diff -Nru a/drivers/char/watchdog/pcwd_usb.c b/drivers/char/watchdog/pcwd_usb.c
--- a/drivers/char/watchdog/pcwd_usb.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/char/watchdog/pcwd_usb.c	2005-03-01 23:38:54 -08:00
@@ -571,12 +571,6 @@
 	char fw_ver_str[20];
 	unsigned char option_switches, dummy;
 
-	/* See if the device offered us matches what we can accept */
-	if ((udev->descriptor.idVendor != USB_PCWD_VENDOR_ID) ||
-	    (udev->descriptor.idProduct != USB_PCWD_PRODUCT_ID)) {
-		return -ENODEV;
-	}
-
 	cards_found++;
 	if (cards_found > 1) {
 		printk(KERN_ERR PFX "This driver only supports 1 device\n");
@@ -621,7 +615,7 @@
 	usb_pcwd->udev = udev;
 	usb_pcwd->interface = interface;
 	usb_pcwd->interface_number = iface_desc->desc.bInterfaceNumber;
-	usb_pcwd->intr_size = (endpoint->wMaxPacketSize > 8 ? endpoint->wMaxPacketSize : 8);
+	usb_pcwd->intr_size = (le16_to_cpu(endpoint->wMaxPacketSize) > 8 ? le16_to_cpu(endpoint->wMaxPacketSize) : 8);
 
 	/* set up the memory buffer's */
 	if (!(usb_pcwd->intr_buffer = usb_buffer_alloc(udev, usb_pcwd->intr_size, SLAB_ATOMIC, &usb_pcwd->intr_dma))) {
diff -Nru a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig
--- a/drivers/cpufreq/Kconfig	2005-03-01 23:39:10 -08:00
+++ b/drivers/cpufreq/Kconfig	2005-03-01 23:39:10 -08:00
@@ -27,17 +27,21 @@
 	       2 to activate CPUfreq drivers debugging, and
 	       4 to activate CPUfreq governor debugging
 
-config CPU_FREQ_PROC_INTF
-	tristate "/proc/cpufreq interface (deprecated)"
-	depends on CPU_FREQ && PROC_FS
-	help
-	  This enables the /proc/cpufreq interface for controlling
-	  CPUFreq. Please note that it is recommended to use the sysfs
-	  interface instead (which is built automatically). 
-	  
-	  For details, take a look at <file:Documentation/cpu-freq/>.
-	  
-	  If in doubt, say N.
+config CPU_FREQ_STAT
+       tristate "CPU frequency translation statistics"
+       depends on CPU_FREQ && CPU_FREQ_TABLE
+       default y
+       help
+         This driver exports CPU frequency statistics information through sysfs
+         file system
+
+config CPU_FREQ_STAT_DETAILS
+       bool "CPU frequency translation statistics details"
+       depends on CPU_FREQ && CPU_FREQ_STAT
+       default n
+       help
+         This will show detail CPU frequency translation table in sysfs file
+         system
 
 choice
 	prompt "Default CPUFreq governor"
@@ -97,21 +101,6 @@
 	  For details, take a look at <file:Documentation/cpu-freq/>.
 
 	  If in doubt, say Y.
-
-config CPU_FREQ_24_API
-	bool "/proc/sys/cpu/ interface (2.4. / OLD)"
-	depends on CPU_FREQ_GOV_USERSPACE
-	depends on SYSCTL
-	help
-	  This enables the /proc/sys/cpu/ sysctl interface for controlling
-	  the CPUFreq,"userspace" governor. This is the same interface
-	  as known from the 2.4.-kernel patches for CPUFreq, and offers
-	  the same functionality as long as "userspace" is the
-	  selected governor for the specified CPU.
-	
-	  For details, take a look at <file:Documentation/cpu-freq/>.
-
-	  If in doubt, say N.
 
 config CPU_FREQ_GOV_ONDEMAND
 	tristate "'ondemand' cpufreq policy governor"
diff -Nru a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
--- a/drivers/cpufreq/Makefile	2005-03-01 23:39:18 -08:00
+++ b/drivers/cpufreq/Makefile	2005-03-01 23:39:18 -08:00
@@ -1,5 +1,7 @@
 # CPUfreq core
 obj-$(CONFIG_CPU_FREQ)			+= cpufreq.o
+# CPUfreq stats
+obj-$(CONFIG_CPU_FREQ_STAT)             += cpufreq_stats.o
 
 # CPUfreq governors 
 obj-$(CONFIG_CPU_FREQ_GOV_PERFORMANCE)	+= cpufreq_performance.o
@@ -9,5 +11,4 @@
 
 # CPUfreq cross-arch helpers
 obj-$(CONFIG_CPU_FREQ_TABLE)		+= freq_table.o
-obj-$(CONFIG_CPU_FREQ_PROC_INTF)	+= proc_intf.o
 
diff -Nru a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
--- a/drivers/cpufreq/cpufreq.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/cpufreq/cpufreq.c	2005-03-01 23:38:53 -08:00
@@ -33,7 +33,7 @@
  */
 static struct cpufreq_driver   	*cpufreq_driver;
 static struct cpufreq_policy	*cpufreq_cpu_data[NR_CPUS];
-static spinlock_t		cpufreq_driver_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(cpufreq_driver_lock);
 
 
 /* we keep a copy of all ->add'ed CPU's struct sys_device here;
@@ -63,7 +63,7 @@
 static LIST_HEAD(cpufreq_governor_list);
 static DECLARE_MUTEX		(cpufreq_governor_sem);
 
-static struct cpufreq_policy * cpufreq_cpu_get(unsigned int cpu)
+struct cpufreq_policy * cpufreq_cpu_get(unsigned int cpu)
 {
 	struct cpufreq_policy *data;
 	unsigned long flags;
@@ -102,12 +102,14 @@
  err_out:
 	return NULL;
 }
+EXPORT_SYMBOL_GPL(cpufreq_cpu_get);
 
-static void cpufreq_cpu_put(struct cpufreq_policy *data)
+void cpufreq_cpu_put(struct cpufreq_policy *data)
 {
 	kobject_put(&data->kobj);
 	module_put(cpufreq_driver->owner);
 }
+EXPORT_SYMBOL_GPL(cpufreq_cpu_put);
 
 
 /*********************************************************************
@@ -128,7 +130,7 @@
  * is set, and disabled upon cpufreq driver removal
  */
 static unsigned int disable_ratelimit = 1;
-static spinlock_t disable_ratelimit_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(disable_ratelimit_lock);
 
 static inline void cpufreq_debug_enable_ratelimit(void)
 {
@@ -285,7 +287,7 @@
 /**
  * cpufreq_parse_governor - parse a governor string
  */
-int cpufreq_parse_governor (char *str_governor, unsigned int *policy,
+static int cpufreq_parse_governor (char *str_governor, unsigned int *policy,
 				struct cpufreq_governor **governor)
 {
 	if (!cpufreq_driver)
@@ -763,8 +765,11 @@
 	spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
 #endif
 
+	down(&data->lock);
 	if (cpufreq_driver->target)
 		__cpufreq_governor(data, CPUFREQ_GOV_STOP);
+	cpufreq_driver->target = NULL;
+	up(&data->lock);
 
 	kobject_unregister(&data->kobj);
 
@@ -893,6 +898,16 @@
 		return 0;
 	}
 
+	if (cpufreq_driver->resume) {
+		ret = cpufreq_driver->resume(cpu_policy);
+		if (ret) {
+			printk(KERN_ERR "cpufreq: resume failed in ->resume "
+					"step on CPU %u\n", cpu_policy->cpu);
+			cpufreq_cpu_put(cpu_policy);
+			return ret;
+		}
+	}
+
 	if (!(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) {
 		unsigned int cur_freq = 0;
 
@@ -1018,7 +1033,7 @@
 	lock_cpu_hotplug();
 	dprintk("target for CPU %u: %u kHz, relation %u\n", policy->cpu,
 		target_freq, relation);
-	if (cpu_online(policy->cpu))
+	if (cpu_online(policy->cpu) && cpufreq_driver->target)
 		retval = cpufreq_driver->target(policy, target_freq, relation);
 	unlock_cpu_hotplug();
 	return retval;
diff -Nru a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
--- a/drivers/cpufreq/cpufreq_ondemand.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/cpufreq/cpufreq_ondemand.c	2005-03-01 23:39:16 -08:00
@@ -229,10 +229,14 @@
 	static int down_skip[NR_CPUS];
 	struct cpu_dbs_info_s *this_dbs_info;
 
+	struct cpufreq_policy *policy;
+	unsigned int j;
+
 	this_dbs_info = &per_cpu(cpu_dbs_info, cpu);
 	if (!this_dbs_info->enable)
 		return;
 
+	policy = this_dbs_info->cur_policy;
 	/* 
 	 * The default safe range is 20% to 80% 
 	 * Every sampling_rate, we check
@@ -246,12 +250,33 @@
 	 * Frequency reduction happens at minimum steps of 
 	 * 5% of max_frequency 
 	 */
+
 	/* Check for frequency increase */
 	total_idle_ticks = kstat_cpu(cpu).cpustat.idle +
 		kstat_cpu(cpu).cpustat.iowait;
 	idle_ticks = total_idle_ticks -
 		this_dbs_info->prev_cpu_idle_up;
 	this_dbs_info->prev_cpu_idle_up = total_idle_ticks;
+	
+
+	for_each_cpu_mask(j, policy->cpus) {
+		unsigned int tmp_idle_ticks;
+		struct cpu_dbs_info_s *j_dbs_info;
+
+		if (j == cpu)
+			continue;
+
+		j_dbs_info = &per_cpu(cpu_dbs_info, j);
+		/* Check for frequency increase */
+		total_idle_ticks = kstat_cpu(j).cpustat.idle +
+			kstat_cpu(j).cpustat.iowait;
+		tmp_idle_ticks = total_idle_ticks -
+			j_dbs_info->prev_cpu_idle_up;
+		j_dbs_info->prev_cpu_idle_up = total_idle_ticks;
+
+		if (tmp_idle_ticks < idle_ticks)
+			idle_ticks = tmp_idle_ticks;
+	}
 
 	/* Scale idle ticks by 100 and compare with up and down ticks */
 	idle_ticks *= 100;
@@ -259,8 +284,7 @@
 			sampling_rate_in_HZ(dbs_tuners_ins.sampling_rate);
 
 	if (idle_ticks < up_idle_ticks) {
-		__cpufreq_driver_target(this_dbs_info->cur_policy,
-			this_dbs_info->cur_policy->max, 
+		__cpufreq_driver_target(policy, policy->max, 
 			CPUFREQ_RELATION_H);
 		down_skip[cpu] = 0;
 		this_dbs_info->prev_cpu_idle_down = total_idle_ticks;
@@ -272,12 +296,34 @@
 	if (down_skip[cpu] < dbs_tuners_ins.sampling_down_factor)
 		return;
 
+	total_idle_ticks = kstat_cpu(cpu).cpustat.idle +
+		kstat_cpu(cpu).cpustat.iowait;
 	idle_ticks = total_idle_ticks -
 		this_dbs_info->prev_cpu_idle_down;
+	this_dbs_info->prev_cpu_idle_down = total_idle_ticks;
+
+	for_each_cpu_mask(j, policy->cpus) {
+		unsigned int tmp_idle_ticks;
+		struct cpu_dbs_info_s *j_dbs_info;
+
+		if (j == cpu)
+			continue;
+
+		j_dbs_info = &per_cpu(cpu_dbs_info, j);
+		/* Check for frequency increase */
+		total_idle_ticks = kstat_cpu(j).cpustat.idle +
+			kstat_cpu(j).cpustat.iowait;
+		tmp_idle_ticks = total_idle_ticks -
+			j_dbs_info->prev_cpu_idle_down;
+		j_dbs_info->prev_cpu_idle_down = total_idle_ticks;
+
+		if (tmp_idle_ticks < idle_ticks)
+			idle_ticks = tmp_idle_ticks;
+	}
+
 	/* Scale idle ticks by 100 and compare with up and down ticks */
 	idle_ticks *= 100;
 	down_skip[cpu] = 0;
-	this_dbs_info->prev_cpu_idle_down = total_idle_ticks;
 
 	freq_down_sampling_rate = dbs_tuners_ins.sampling_rate *
 		dbs_tuners_ins.sampling_down_factor;
@@ -285,14 +331,14 @@
 			sampling_rate_in_HZ(freq_down_sampling_rate);
 
 	if (idle_ticks > down_idle_ticks ) {
-		freq_down_step = (5 * this_dbs_info->cur_policy->max) / 100;
+		freq_down_step = (5 * policy->max) / 100;
 
 		/* max freq cannot be less than 100. But who knows.... */
 		if (unlikely(freq_down_step == 0))
 			freq_down_step = 5;
 
-		__cpufreq_driver_target(this_dbs_info->cur_policy,
-			this_dbs_info->cur_policy->cur - freq_down_step, 
+		__cpufreq_driver_target(policy,
+			policy->cur - freq_down_step, 
 			CPUFREQ_RELATION_H);
 		return;
 	}
@@ -313,7 +359,8 @@
 static inline void dbs_timer_init(void)
 {
 	INIT_WORK(&dbs_work, do_dbs_timer, NULL);
-	schedule_work(&dbs_work);
+	schedule_delayed_work(&dbs_work,
+			sampling_rate_in_HZ(dbs_tuners_ins.sampling_rate));
 	return;
 }
 
@@ -328,6 +375,7 @@
 {
 	unsigned int cpu = policy->cpu;
 	struct cpu_dbs_info_s *this_dbs_info;
+	unsigned int j;
 
 	this_dbs_info = &per_cpu(cpu_dbs_info, cpu);
 
@@ -344,14 +392,18 @@
 			break;
 		 
 		down(&dbs_sem);
-		this_dbs_info->cur_policy = policy;
+		for_each_cpu_mask(j, policy->cpus) {
+			struct cpu_dbs_info_s *j_dbs_info;
+			j_dbs_info = &per_cpu(cpu_dbs_info, j);
+			j_dbs_info->cur_policy = policy;
 		
-		this_dbs_info->prev_cpu_idle_up = 
-				kstat_cpu(cpu).cpustat.idle +
-				kstat_cpu(cpu).cpustat.iowait;
-		this_dbs_info->prev_cpu_idle_down = 
-				kstat_cpu(cpu).cpustat.idle +
-				kstat_cpu(cpu).cpustat.iowait;
+			j_dbs_info->prev_cpu_idle_up = 
+				kstat_cpu(j).cpustat.idle +
+				kstat_cpu(j).cpustat.iowait;
+			j_dbs_info->prev_cpu_idle_down = 
+				kstat_cpu(j).cpustat.idle +
+				kstat_cpu(j).cpustat.iowait;
+		}
 		this_dbs_info->enable = 1;
 		sysfs_create_group(&policy->kobj, &dbs_attr_group);
 		dbs_enable++;
diff -Nru a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/cpufreq/cpufreq_stats.c	2005-03-01 23:39:26 -08:00
@@ -0,0 +1,334 @@
+/*
+ *  drivers/cpufreq/cpufreq_stats.c
+ *
+ *  Copyright (C) 2003-2004 Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>.
+ *  	      (C) 2004 Zou Nan hai <nanhai.zou@intel.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/kernel.h>
+#include <linux/sysdev.h>
+#include <linux/cpu.h>
+#include <linux/sysfs.h>
+#include <linux/cpufreq.h>
+#include <linux/jiffies.h>
+#include <linux/percpu.h>
+#include <linux/kobject.h>
+#include <linux/spinlock.h>
+
+static spinlock_t cpufreq_stats_lock;
+
+#define CPUFREQ_STATDEVICE_ATTR(_name,_mode,_show) \
+static struct freq_attr _attr_##_name = {\
+	.attr = {.name = __stringify(_name), .owner = THIS_MODULE, \
+		.mode = _mode, }, \
+	.show = _show,\
+};
+
+static unsigned long
+delta_time(unsigned long old, unsigned long new)
+{
+	return (old > new) ? (old - new): (new + ~old + 1);
+}
+
+struct cpufreq_stats {
+	unsigned int cpu;
+	unsigned int total_trans;
+	unsigned long long last_time;
+	unsigned int max_state;
+	unsigned int state_num;
+	unsigned int last_index;
+	unsigned long long *time_in_state;
+	unsigned int *freq_table;
+#ifdef CONFIG_CPU_FREQ_STAT_DETAILS
+	unsigned int *trans_table;
+#endif
+};
+
+static struct cpufreq_stats *cpufreq_stats_table[NR_CPUS];
+
+struct cpufreq_stats_attribute {
+	struct attribute attr;
+	ssize_t(*show) (struct cpufreq_stats *, char *);
+};
+
+static int
+cpufreq_stats_update (unsigned int cpu)
+{
+	struct cpufreq_stats *stat;
+	spin_lock(&cpufreq_stats_lock);
+	stat = cpufreq_stats_table[cpu];
+	if (stat->time_in_state)
+		stat->time_in_state[stat->last_index] +=
+			delta_time(stat->last_time, jiffies);
+	stat->last_time = jiffies;
+	spin_unlock(&cpufreq_stats_lock);
+	return 0;
+}
+
+static ssize_t
+show_total_trans(struct cpufreq_policy *policy, char *buf)
+{
+	struct cpufreq_stats *stat = cpufreq_stats_table[policy->cpu];
+	if(!stat)
+		return 0;
+	return sprintf(buf, "%d\n",
+			cpufreq_stats_table[stat->cpu]->total_trans);
+}
+
+static ssize_t
+show_time_in_state(struct cpufreq_policy *policy, char *buf)
+{
+	ssize_t len = 0;
+	int i;
+	struct cpufreq_stats *stat = cpufreq_stats_table[policy->cpu];
+	if(!stat)
+		return 0;
+	cpufreq_stats_update(stat->cpu);
+	for (i = 0; i < stat->state_num; i++) {
+		len += sprintf(buf + len, "%u %llu\n",
+			stat->freq_table[i], stat->time_in_state[i]);
+	}
+	return len;
+}
+
+#ifdef CONFIG_CPU_FREQ_STAT_DETAILS
+static ssize_t
+show_trans_table(struct cpufreq_policy *policy, char *buf)
+{
+	ssize_t len = 0;
+	int i, j;
+
+	struct cpufreq_stats *stat = cpufreq_stats_table[policy->cpu];
+	if(!stat)
+		return 0;
+	cpufreq_stats_update(stat->cpu);
+	for (i = 0; i < stat->state_num; i++) {
+		if (len >= PAGE_SIZE)
+			break;
+		len += snprintf(buf + len, PAGE_SIZE - len, "%9u:\t",
+				stat->freq_table[i]);
+
+		for (j = 0; j < stat->state_num; j++)   {
+			if (len >= PAGE_SIZE)
+				break;
+			len += snprintf(buf + len, PAGE_SIZE - len, "%u\t",
+					stat->trans_table[i*stat->max_state+j]);
+		}
+		len += snprintf(buf + len, PAGE_SIZE - len, "\n");
+	}
+	return len;
+}
+CPUFREQ_STATDEVICE_ATTR(trans_table,0444,show_trans_table);
+#endif
+
+CPUFREQ_STATDEVICE_ATTR(total_trans,0444,show_total_trans);
+CPUFREQ_STATDEVICE_ATTR(time_in_state,0444,show_time_in_state);
+
+static struct attribute *default_attrs[] = {
+	&_attr_total_trans.attr,
+	&_attr_time_in_state.attr,
+#ifdef CONFIG_CPU_FREQ_STAT_DETAILS
+	&_attr_trans_table.attr,
+#endif
+	NULL
+};
+static struct attribute_group stats_attr_group = {
+	.attrs = default_attrs,
+	.name = "stats"
+};
+
+static int
+freq_table_get_index(struct cpufreq_stats *stat, unsigned int freq)
+{
+	int index;
+	for (index = 0; index < stat->max_state; index++)
+		if (stat->freq_table[index] == freq)
+			return index;
+	return -1;
+}
+
+static void
+cpufreq_stats_free_table (unsigned int cpu)
+{
+	struct cpufreq_stats *stat = cpufreq_stats_table[cpu];
+	struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
+	if (policy && policy->cpu == cpu)	
+		sysfs_remove_group(&policy->kobj, &stats_attr_group);
+	if (stat) {
+		kfree(stat->time_in_state);
+		kfree(stat);
+	}
+	cpufreq_stats_table[cpu] = NULL;
+	if (policy)
+		cpufreq_cpu_put(policy);
+}
+
+static int
+cpufreq_stats_create_table (struct cpufreq_policy *policy,
+		struct cpufreq_frequency_table *table)
+{
+	unsigned int i, j, count = 0, ret = 0;
+	struct cpufreq_stats *stat;
+	struct cpufreq_policy *data;
+	unsigned int alloc_size;
+	unsigned int cpu = policy->cpu;
+	if (cpufreq_stats_table[cpu])
+		return -EBUSY;
+	if ((stat = kmalloc(sizeof(struct cpufreq_stats), GFP_KERNEL)) == NULL)
+		return -ENOMEM;
+	memset(stat, 0, sizeof (struct cpufreq_stats));
+
+	data = cpufreq_cpu_get(cpu);
+	if ((ret = sysfs_create_group(&data->kobj, &stats_attr_group)))
+		goto error_out;
+
+	stat->cpu = cpu;
+	cpufreq_stats_table[cpu] = stat;
+
+	for (i=0; table[i].frequency != CPUFREQ_TABLE_END; i++) {
+		unsigned int freq = table[i].frequency;
+		if (freq == CPUFREQ_ENTRY_INVALID)
+			continue;
+		count++;
+	}
+
+	alloc_size = count * sizeof(int) + count * sizeof(long long);
+
+#ifdef CONFIG_CPU_FREQ_STAT_DETAILS
+	alloc_size += count * count * sizeof(int);
+#endif
+	stat->max_state = count;
+	stat->time_in_state = kmalloc(alloc_size, GFP_KERNEL);
+	if (!stat->time_in_state) {
+		ret = -ENOMEM;
+		goto error_out;
+	}
+	memset(stat->time_in_state, 0, alloc_size);
+	stat->freq_table = (unsigned int *)(stat->time_in_state + count);
+
+#ifdef CONFIG_CPU_FREQ_STAT_DETAILS
+	stat->trans_table = stat->freq_table + count;
+#endif
+	j = 0;
+	for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) {
+		unsigned int freq = table[i].frequency;
+		if (freq == CPUFREQ_ENTRY_INVALID)
+			continue;
+		if (freq_table_get_index(stat, freq) == -1)
+			stat->freq_table[j++] = freq;
+	}
+	stat->state_num = j;
+	spin_lock(&cpufreq_stats_lock);
+	stat->last_time = jiffies;
+	stat->last_index = freq_table_get_index(stat, policy->cur);
+	spin_unlock(&cpufreq_stats_lock);
+	cpufreq_cpu_put(data);
+	return 0;
+error_out:
+	cpufreq_cpu_put(data);
+	kfree(stat);
+	cpufreq_stats_table[cpu] = NULL;
+	return ret;
+}
+
+static int
+cpufreq_stat_notifier_policy (struct notifier_block *nb, unsigned long val,
+		void *data)
+{
+	int ret;
+	struct cpufreq_policy *policy = data;
+	struct cpufreq_frequency_table *table;
+	unsigned int cpu = policy->cpu;
+	if (val != CPUFREQ_NOTIFY)
+		return 0;
+	table = cpufreq_frequency_get_table(cpu);
+	if (!table)
+		return 0;
+	if ((ret = cpufreq_stats_create_table(policy, table)))
+		return ret;
+	return 0;
+}
+
+static int
+cpufreq_stat_notifier_trans (struct notifier_block *nb, unsigned long val,
+		void *data)
+{
+	struct cpufreq_freqs *freq = data;
+	struct cpufreq_stats *stat;
+	int old_index, new_index;
+
+	if (val != CPUFREQ_POSTCHANGE)
+		return 0;
+
+	stat = cpufreq_stats_table[freq->cpu];
+	if (!stat)
+		return 0;
+	old_index = freq_table_get_index(stat, freq->old);
+	new_index = freq_table_get_index(stat, freq->new);
+
+	cpufreq_stats_update(freq->cpu);
+	if (old_index == new_index)
+		return 0;
+
+	spin_lock(&cpufreq_stats_lock);
+	stat->last_index = new_index;
+#ifdef CONFIG_CPU_FREQ_STAT_DETAILS
+	stat->trans_table[old_index * stat->max_state + new_index]++;
+#endif
+	stat->total_trans++;
+	spin_unlock(&cpufreq_stats_lock);
+	return 0;
+}
+
+static struct notifier_block notifier_policy_block = {
+	.notifier_call = cpufreq_stat_notifier_policy
+};
+
+static struct notifier_block notifier_trans_block = {
+	.notifier_call = cpufreq_stat_notifier_trans
+};
+
+static int
+__init cpufreq_stats_init(void)
+{
+	int ret;
+	unsigned int cpu;
+	spin_lock_init(&cpufreq_stats_lock);
+	if ((ret = cpufreq_register_notifier(&notifier_policy_block,
+				CPUFREQ_POLICY_NOTIFIER)))
+		return ret;
+
+	if ((ret = cpufreq_register_notifier(&notifier_trans_block,
+				CPUFREQ_TRANSITION_NOTIFIER))) {
+		cpufreq_unregister_notifier(&notifier_policy_block,
+				CPUFREQ_POLICY_NOTIFIER);
+		return ret;
+	}
+
+	for_each_cpu(cpu)
+		cpufreq_update_policy(cpu);
+	return 0;
+}
+static void
+__exit cpufreq_stats_exit(void)
+{
+	unsigned int cpu;
+	cpufreq_unregister_notifier(&notifier_policy_block,
+			CPUFREQ_POLICY_NOTIFIER);
+	cpufreq_unregister_notifier(&notifier_trans_block,
+			CPUFREQ_TRANSITION_NOTIFIER);
+	for_each_cpu(cpu)
+		cpufreq_stats_free_table(cpu);
+}
+
+MODULE_AUTHOR ("Zou Nan hai <nanhai.zou@intel.com>");
+MODULE_DESCRIPTION ("'cpufreq_stats' - A driver to export cpufreq stats through sysfs filesystem");
+MODULE_LICENSE ("GPL");
+
+module_init(cpufreq_stats_init);
+module_exit(cpufreq_stats_exit);
diff -Nru a/drivers/cpufreq/cpufreq_userspace.c b/drivers/cpufreq/cpufreq_userspace.c
--- a/drivers/cpufreq/cpufreq_userspace.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/cpufreq/cpufreq_userspace.c	2005-03-01 23:38:52 -08:00
@@ -17,51 +17,13 @@
 #include <linux/init.h>
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
-#include <linux/ctype.h>
 #include <linux/cpufreq.h>
-#include <linux/sysctl.h>
 #include <linux/types.h>
 #include <linux/fs.h>
 #include <linux/sysfs.h>
 
 #include <asm/uaccess.h>
 
-#define CTL_CPU_VARS_SPEED_MAX(cpunr) { \
-                .ctl_name	= CPU_NR_FREQ_MAX, \
-                .data		= &cpu_max_freq[cpunr], \
-                .procname	= "speed-max", \
-                .maxlen		= sizeof(cpu_max_freq[cpunr]),\
-                .mode		= 0444, \
-                .proc_handler	= proc_dointvec, }
-
-#define CTL_CPU_VARS_SPEED_MIN(cpunr) { \
-                .ctl_name	= CPU_NR_FREQ_MIN, \
-                .data		= &cpu_min_freq[cpunr], \
-                .procname	= "speed-min", \
-                .maxlen		= sizeof(cpu_min_freq[cpunr]),\
-                .mode		= 0444, \
-                .proc_handler	= proc_dointvec, }
-
-#define CTL_CPU_VARS_SPEED(cpunr) { \
-                .ctl_name	= CPU_NR_FREQ, \
-                .procname	= "speed", \
-                .mode		= 0644, \
-                .proc_handler	= cpufreq_procctl, \
-                .strategy	= cpufreq_sysctl, \
-                .extra1		= (void*) (cpunr), }
-
-#define CTL_TABLE_CPU_VARS(cpunr) static ctl_table ctl_cpu_vars_##cpunr[] = {\
-                CTL_CPU_VARS_SPEED_MAX(cpunr), \
-                CTL_CPU_VARS_SPEED_MIN(cpunr), \
-                CTL_CPU_VARS_SPEED(cpunr),  \
-                { .ctl_name = 0, }, }
-
-/* the ctl_table entry for each CPU */
-#define CPU_ENUM(s) { \
-                .ctl_name	= (CPU_NR + s), \
-                .procname	= #s, \
-                .mode		= 0555, \
-                .child		= ctl_cpu_vars_##s }
 
 /**
  * A few values needed by the userspace governor
@@ -96,17 +58,17 @@
 
 
 /** 
- * _cpufreq_set - set the CPU frequency
+ * cpufreq_set - set the CPU frequency
  * @freq: target frequency in kHz
  * @cpu: CPU for which the frequency is to be set
  *
  * Sets the CPU frequency to freq.
  */
-static int _cpufreq_set(unsigned int freq, unsigned int cpu)
+static int cpufreq_set(unsigned int freq, unsigned int cpu)
 {
 	int ret = -EINVAL;
 
-	dprintk("_cpufreq_set for cpu %u, freq %u kHz\n", cpu, freq);
+	dprintk("cpufreq_set for cpu %u, freq %u kHz\n", cpu, freq);
 
 	down(&userspace_sem);
 	if (!cpu_is_managed[cpu])
@@ -135,358 +97,6 @@
 }
 
 
-#ifdef CONFIG_CPU_FREQ_24_API
-
-#warning The /proc/sys/cpu/ and sysctl interface to cpufreq will be removed from the 2.6. kernel series soon after 2005-01-01
-
-static unsigned int warning_print = 0;
-
-int __deprecated cpufreq_set(unsigned int freq, unsigned int cpu)
-{
-	return _cpufreq_set(freq, cpu);
-}
-EXPORT_SYMBOL_GPL(cpufreq_set);
-
-
-/** 
- * cpufreq_setmax - set the CPU to the maximum frequency
- * @cpu - affected cpu;
- *
- * Sets the CPU frequency to the maximum frequency supported by
- * this CPU.
- */
-int __deprecated cpufreq_setmax(unsigned int cpu)
-{
-	if (!cpu_is_managed[cpu] || !cpu_online(cpu))
-		return -EINVAL;
-	return _cpufreq_set(cpu_max_freq[cpu], cpu);
-}
-EXPORT_SYMBOL_GPL(cpufreq_setmax);
-
-/*********************** cpufreq_sysctl interface ********************/
-static int
-cpufreq_procctl(ctl_table *ctl, int write, struct file *filp,
-		void __user *buffer, size_t *lenp, loff_t *ppos)
-{
-	char buf[16], *p;
-	int cpu = (long) ctl->extra1;
-	unsigned int len, left = *lenp;
-
-	if (!left || (*ppos && !write) || !cpu_online(cpu)) {
-		*lenp = 0;
-		return 0;
-	}
-
-	if (!warning_print) {
-		warning_print++;
-		printk(KERN_INFO "Access to /proc/sys/cpu/ is deprecated and "
-			"will be removed from (new) 2.6. kernels soon "
-			"after 2005-01-01\n");
-	}
-
-	if (write) {
-		unsigned int freq;
-
-		len = left;
-		if (left > sizeof(buf))
-			left = sizeof(buf);
-		if (copy_from_user(buf, buffer, left))
-			return -EFAULT;
-		buf[sizeof(buf) - 1] = '\0';
-
-		freq = simple_strtoul(buf, &p, 0);
-		_cpufreq_set(freq, cpu);
-	} else {
-		len = sprintf(buf, "%d\n", cpufreq_get(cpu));
-		if (len > left)
-			len = left;
-		if (copy_to_user(buffer, buf, len))
-			return -EFAULT;
-	}
-
-	*lenp = len;
-	*ppos += len;
-	return 0;
-}
-
-static int
-cpufreq_sysctl(ctl_table *table, int __user *name, int nlen,
-	       void __user *oldval, size_t __user *oldlenp,
-	       void __user *newval, size_t newlen, void **context)
-{
-	int cpu = (long) table->extra1;
-
-	if (!cpu_online(cpu))
-		return -EINVAL;
-
-	if (!warning_print) {
-		warning_print++;
-		printk(KERN_INFO "Access to /proc/sys/cpu/ is deprecated and "
-			"will be removed from (new) 2.6. kernels soon "
-			"after 2005-01-01\n");
-	}
-
-	if (oldval && oldlenp) {
-		size_t oldlen;
-
-		if (get_user(oldlen, oldlenp))
-			return -EFAULT;
-
-		if (oldlen != sizeof(unsigned int))
-			return -EINVAL;
-
-		if (put_user(cpufreq_get(cpu), (unsigned int __user *)oldval) ||
-		    put_user(sizeof(unsigned int), oldlenp))
-			return -EFAULT;
-	}
-	if (newval && newlen) {
-		unsigned int freq;
-
-		if (newlen != sizeof(unsigned int))
-			return -EINVAL;
-
-		if (get_user(freq, (unsigned int __user *)newval))
-			return -EFAULT;
-
-		_cpufreq_set(freq, cpu);
-	}
-	return 1;
-}
-
-/* ctl_table ctl_cpu_vars_{0,1,...,(NR_CPUS-1)} */
-/* due to NR_CPUS tweaking, a lot of if/endifs are required, sorry */
-        CTL_TABLE_CPU_VARS(0);
-#if NR_CPUS > 1
-	CTL_TABLE_CPU_VARS(1);
-#endif
-#if NR_CPUS > 2
-	CTL_TABLE_CPU_VARS(2);
-#endif
-#if NR_CPUS > 3
-	CTL_TABLE_CPU_VARS(3);
-#endif
-#if NR_CPUS > 4
-	CTL_TABLE_CPU_VARS(4);
-#endif
-#if NR_CPUS > 5
-	CTL_TABLE_CPU_VARS(5);
-#endif
-#if NR_CPUS > 6
-	CTL_TABLE_CPU_VARS(6);
-#endif
-#if NR_CPUS > 7
-	CTL_TABLE_CPU_VARS(7);
-#endif
-#if NR_CPUS > 8
-	CTL_TABLE_CPU_VARS(8);
-#endif
-#if NR_CPUS > 9
-	CTL_TABLE_CPU_VARS(9);
-#endif
-#if NR_CPUS > 10
-	CTL_TABLE_CPU_VARS(10);
-#endif
-#if NR_CPUS > 11
-	CTL_TABLE_CPU_VARS(11);
-#endif
-#if NR_CPUS > 12
-	CTL_TABLE_CPU_VARS(12);
-#endif
-#if NR_CPUS > 13
-	CTL_TABLE_CPU_VARS(13);
-#endif
-#if NR_CPUS > 14
-	CTL_TABLE_CPU_VARS(14);
-#endif
-#if NR_CPUS > 15
-	CTL_TABLE_CPU_VARS(15);
-#endif
-#if NR_CPUS > 16
-	CTL_TABLE_CPU_VARS(16);
-#endif
-#if NR_CPUS > 17
-	CTL_TABLE_CPU_VARS(17);
-#endif
-#if NR_CPUS > 18
-	CTL_TABLE_CPU_VARS(18);
-#endif
-#if NR_CPUS > 19
-	CTL_TABLE_CPU_VARS(19);
-#endif
-#if NR_CPUS > 20
-	CTL_TABLE_CPU_VARS(20);
-#endif
-#if NR_CPUS > 21
-	CTL_TABLE_CPU_VARS(21);
-#endif
-#if NR_CPUS > 22
-	CTL_TABLE_CPU_VARS(22);
-#endif
-#if NR_CPUS > 23
-	CTL_TABLE_CPU_VARS(23);
-#endif
-#if NR_CPUS > 24
-	CTL_TABLE_CPU_VARS(24);
-#endif
-#if NR_CPUS > 25
-	CTL_TABLE_CPU_VARS(25);
-#endif
-#if NR_CPUS > 26
-	CTL_TABLE_CPU_VARS(26);
-#endif
-#if NR_CPUS > 27
-	CTL_TABLE_CPU_VARS(27);
-#endif
-#if NR_CPUS > 28
-	CTL_TABLE_CPU_VARS(28);
-#endif
-#if NR_CPUS > 29
-	CTL_TABLE_CPU_VARS(29);
-#endif
-#if NR_CPUS > 30
-	CTL_TABLE_CPU_VARS(30);
-#endif
-#if NR_CPUS > 31
-	CTL_TABLE_CPU_VARS(31);
-#endif
-#if NR_CPUS > 32
-#error please extend CPU enumeration
-#endif
-
-/* due to NR_CPUS tweaking, a lot of if/endifs are required, sorry */
-static ctl_table ctl_cpu_table[NR_CPUS + 1] = {
-	CPU_ENUM(0),
-#if NR_CPUS > 1
-	CPU_ENUM(1),
-#endif
-#if NR_CPUS > 2
-	CPU_ENUM(2),
-#endif
-#if NR_CPUS > 3
-	CPU_ENUM(3),
-#endif
-#if NR_CPUS > 4
-	CPU_ENUM(4),
-#endif
-#if NR_CPUS > 5
-	CPU_ENUM(5),
-#endif
-#if NR_CPUS > 6
-	CPU_ENUM(6),
-#endif
-#if NR_CPUS > 7
-	CPU_ENUM(7),
-#endif
-#if NR_CPUS > 8
-	CPU_ENUM(8),
-#endif
-#if NR_CPUS > 9
-	CPU_ENUM(9),
-#endif
-#if NR_CPUS > 10
-	CPU_ENUM(10),
-#endif
-#if NR_CPUS > 11
-	CPU_ENUM(11),
-#endif
-#if NR_CPUS > 12
-	CPU_ENUM(12),
-#endif
-#if NR_CPUS > 13
-	CPU_ENUM(13),
-#endif
-#if NR_CPUS > 14
-	CPU_ENUM(14),
-#endif
-#if NR_CPUS > 15
-	CPU_ENUM(15),
-#endif
-#if NR_CPUS > 16
-	CPU_ENUM(16),
-#endif
-#if NR_CPUS > 17
-	CPU_ENUM(17),
-#endif
-#if NR_CPUS > 18
-	CPU_ENUM(18),
-#endif
-#if NR_CPUS > 19
-	CPU_ENUM(19),
-#endif
-#if NR_CPUS > 20
-	CPU_ENUM(20),
-#endif
-#if NR_CPUS > 21
-	CPU_ENUM(21),
-#endif
-#if NR_CPUS > 22
-	CPU_ENUM(22),
-#endif
-#if NR_CPUS > 23
-	CPU_ENUM(23),
-#endif
-#if NR_CPUS > 24
-	CPU_ENUM(24),
-#endif
-#if NR_CPUS > 25
-	CPU_ENUM(25),
-#endif
-#if NR_CPUS > 26
-	CPU_ENUM(26),
-#endif
-#if NR_CPUS > 27
-	CPU_ENUM(27),
-#endif
-#if NR_CPUS > 28
-	CPU_ENUM(28),
-#endif
-#if NR_CPUS > 29
-	CPU_ENUM(29),
-#endif
-#if NR_CPUS > 30
-	CPU_ENUM(30),
-#endif
-#if NR_CPUS > 31
-	CPU_ENUM(31),
-#endif
-#if NR_CPUS > 32
-#error please extend CPU enumeration
-#endif
-	{
-		.ctl_name	= 0,
-	}
-};
-
-static ctl_table ctl_cpu[2] = {
-	{
-		.ctl_name	= CTL_CPU,
-		.procname	= "cpu",
-		.mode		= 0555,
-		.child		= ctl_cpu_table,
-	},
-	{
-		.ctl_name	= 0,
-	}
-};
-
-static struct ctl_table_header *cpufreq_sysctl_table;
-
-static inline void cpufreq_sysctl_init(void)
-{
-	cpufreq_sysctl_table = register_sysctl_table(ctl_cpu, 0);
-}
-
-static inline void cpufreq_sysctl_exit(void)
-{
-	unregister_sysctl_table(cpufreq_sysctl_table);
-}
-
-#else
-#define cpufreq_sysctl_init() do {} while(0)
-#define cpufreq_sysctl_exit() do {} while(0)
-#endif /* CONFIG_CPU_FREQ_24API */
-
-
 /************************** sysfs interface ************************/
 static ssize_t show_speed (struct cpufreq_policy *policy, char *buf)
 {
@@ -503,7 +113,7 @@
 	if (ret != 1)
 		return -EINVAL;
 
-	_cpufreq_set(freq, policy->cpu);
+	cpufreq_set(freq, policy->cpu);
 
 	return count;
 }
@@ -577,7 +187,6 @@
 
 static int __init cpufreq_gov_userspace_init(void)
 {
-	cpufreq_sysctl_init();
 	cpufreq_register_notifier(&userspace_cpufreq_notifier_block, CPUFREQ_TRANSITION_NOTIFIER);
 	return cpufreq_register_governor(&cpufreq_gov_userspace);
 }
@@ -587,7 +196,6 @@
 {
 	cpufreq_unregister_governor(&cpufreq_gov_userspace);
         cpufreq_unregister_notifier(&userspace_cpufreq_notifier_block, CPUFREQ_TRANSITION_NOTIFIER);
-	cpufreq_sysctl_exit();
 }
 
 
diff -Nru a/drivers/cpufreq/freq_table.c b/drivers/cpufreq/freq_table.c
--- a/drivers/cpufreq/freq_table.c	2005-03-01 23:39:10 -08:00
+++ b/drivers/cpufreq/freq_table.c	2005-03-01 23:39:10 -08:00
@@ -214,6 +214,11 @@
 }
 EXPORT_SYMBOL_GPL(cpufreq_frequency_table_put_attr);
 
+struct cpufreq_frequency_table *cpufreq_frequency_get_table(unsigned int cpu)
+{
+	return show_table[cpu];
+}
+EXPORT_SYMBOL_GPL(cpufreq_frequency_get_table);
 
 MODULE_AUTHOR ("Dominik Brodowski <linux@brodo.de>");
 MODULE_DESCRIPTION ("CPUfreq frequency table helpers");
diff -Nru a/drivers/cpufreq/proc_intf.c b/drivers/cpufreq/proc_intf.c
--- a/drivers/cpufreq/proc_intf.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/cpufreq/proc_intf.c	2005-03-01 23:38:53 -08:00
@@ -1,263 +0,0 @@
-/*
- * linux/drivers/cpufreq/proc_intf.c
- *
- * Copyright (C) 2002 - 2003 Dominik Brodowski
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/cpufreq.h>
-#include <linux/ctype.h>
-#include <linux/proc_fs.h>
-#include <asm/uaccess.h>
-
-#warning This module will be removed from the 2.6. kernel series soon after 2005-01-01
-
-#define CPUFREQ_ALL_CPUS		((NR_CPUS))
-
-static unsigned int warning_print = 0;
-
-/**
- * cpufreq_parse_policy - parse a policy string
- * @input_string: the string to parse.
- * @policy: the policy written inside input_string
- *
- * This function parses a "policy string" - something the user echo'es into
- * /proc/cpufreq or gives as boot parameter - into a struct cpufreq_policy.
- * If there are invalid/missing entries, they are replaced with current
- * cpufreq policy.
- */
-static int cpufreq_parse_policy(char input_string[42], struct cpufreq_policy *policy)
-{
-	unsigned int            min = 0;
-	unsigned int            max = 0;
-	unsigned int            cpu = 0;
-	char			str_governor[16];
-	struct cpufreq_policy   current_policy;
-	unsigned int            result = -EFAULT;
-
-	if (!policy)
-		return -EINVAL;
-
-	policy->min = 0;
-	policy->max = 0;
-	policy->policy = 0;
-	policy->cpu = CPUFREQ_ALL_CPUS;
-
-	if (sscanf(input_string, "%d:%d:%d:%15s", &cpu, &min, &max, str_governor) == 4) 
-	{
-		policy->min = min;
-		policy->max = max;
-		policy->cpu = cpu;
-		result = 0;
-		goto scan_policy;
-	}
-	if (sscanf(input_string, "%d%%%d%%%d%%%15s", &cpu, &min, &max, str_governor) == 4)
-	{
-		if (!cpufreq_get_policy(&current_policy, cpu)) {
-			policy->min = (min * current_policy.cpuinfo.max_freq) / 100;
-			policy->max = (max * current_policy.cpuinfo.max_freq) / 100;
-			policy->cpu = cpu;
-			result = 0;
-			goto scan_policy;
-		}
-	}
-
-	if (sscanf(input_string, "%d:%d:%15s", &min, &max, str_governor) == 3) 
-	{
-		policy->min = min;
-		policy->max = max;
-		result = 0;
-		goto scan_policy;
-	}
-
-	if (sscanf(input_string, "%d%%%d%%%15s", &min, &max, str_governor) == 3)
-	{
-		if (!cpufreq_get_policy(&current_policy, cpu)) {
-			policy->min = (min * current_policy.cpuinfo.max_freq) / 100;
-			policy->max = (max * current_policy.cpuinfo.max_freq) / 100;
-			result = 0;
-			goto scan_policy;
-		}
-	}
-
-	return -EINVAL;
-
-scan_policy:
-	result = cpufreq_parse_governor(str_governor, &policy->policy, &policy->governor);
-
-	return result;
-}
-
-/**
- * cpufreq_proc_read - read /proc/cpufreq
- *
- * This function prints out the current cpufreq policy.
- */
-static int cpufreq_proc_read (
-	char			*page,
-	char			**start,
-	off_t			off,
-	int 			count,
-	int 			*eof,
-	void			*data)
-{
-	char			*p = page;
-	int			len = 0;
-	struct cpufreq_policy   policy;
-	unsigned int            min_pctg = 0;
-	unsigned int            max_pctg = 0;
-	unsigned int            i = 0;
-
-	if (off != 0)
-		goto end;
-
-	if (!warning_print) {
-		warning_print++;
-		printk(KERN_INFO "Access to /proc/cpufreq is deprecated and "
-			"will be removed from (new) 2.6. kernels soon "
-			"after 2005-01-01\n");
-	}
-
-	p += sprintf(p, "          minimum CPU frequency  -  maximum CPU frequency  -  policy\n");
-	for (i=0;i<NR_CPUS;i++) {
-		if (!cpu_online(i))
-			continue;
-
-		if (cpufreq_get_policy(&policy, i))
-			continue;
-
-		if (!policy.cpuinfo.max_freq)
-			continue;
-
-		min_pctg = (policy.min * 100) / policy.cpuinfo.max_freq;
-		max_pctg = (policy.max * 100) / policy.cpuinfo.max_freq;
-
-		p += sprintf(p, "CPU%3d    %9d kHz (%3d %%)  -  %9d kHz (%3d %%)  -  ",
-			     i , policy.min, min_pctg, policy.max, max_pctg);
-		if (policy.policy) {
-			switch (policy.policy) {
-				case CPUFREQ_POLICY_POWERSAVE:
-				p += sprintf(p, "powersave\n");
-				break;	
-			case CPUFREQ_POLICY_PERFORMANCE:
-				p += sprintf(p, "performance\n");
-				break;
-			default:
-				p += sprintf(p, "INVALID\n");
-				break;
-			} 
-		} else
-			p += scnprintf(p, CPUFREQ_NAME_LEN, "%s\n", policy.governor->name);
-	}
-end:
-	len = (p - page);
-	if (len <= off+count) 
-		*eof = 1;
-	*start = page + off;
-	len -= off;
-	if (len>count) 
-		len = count;
-	if (len<0) 
-		len = 0;
-
-	return len;
-}
-
-
-/**
- * cpufreq_proc_write - handles writing into /proc/cpufreq
- *
- * This function calls the parsing script and then sets the policy
- * accordingly.
- */
-static int cpufreq_proc_write (
-        struct file		*file,
-        const char		__user *buffer,
-        unsigned long		count,
-        void			*data)
-{
-	int                     result = 0;
-	char			proc_string[42] = {'\0'};
-	struct cpufreq_policy   policy;
-	unsigned int            i = 0;
-
-
-	if ((count > sizeof(proc_string) - 1))
-		return -EINVAL;
-	
-	if (copy_from_user(proc_string, buffer, count))
-		return -EFAULT;
-
-	if (!warning_print) {
-		warning_print++;
-		printk(KERN_INFO "Access to /proc/cpufreq is deprecated and "
-			"will be removed from (new) 2.6. kernels soon "
-			"after 2005-01-01\n");
-	}
-	
-	proc_string[count] = '\0';
-
-	result = cpufreq_parse_policy(proc_string, &policy);
-	if (result)
-		return -EFAULT;
-
-	if (policy.cpu == CPUFREQ_ALL_CPUS)
-	{
-		for (i=0; i<NR_CPUS; i++) 
-		{
-			policy.cpu = i;
-			if (cpu_online(i))
-				cpufreq_set_policy(&policy);
-		}
-	} 
-	else
-		cpufreq_set_policy(&policy);
-
-	return count;
-}
-
-
-/**
- * cpufreq_proc_init - add "cpufreq" to the /proc root directory
- *
- * This function adds "cpufreq" to the /proc root directory.
- */
-static int __init cpufreq_proc_init (void)
-{
-	struct proc_dir_entry *entry = NULL;
-
-	/* are these acceptable values? */
-	entry = create_proc_entry("cpufreq", S_IFREG|S_IRUGO|S_IWUSR, 
-				  &proc_root);
-
-	if (!entry) {
-		printk(KERN_ERR "unable to create /proc/cpufreq entry\n");
-		return -EIO;
-	} else {
-		entry->read_proc = cpufreq_proc_read;
-		entry->write_proc = cpufreq_proc_write;
-	}
-
-	return 0;
-}
-
-
-/**
- * cpufreq_proc_exit - removes "cpufreq" from the /proc root directory.
- *
- * This function removes "cpufreq" from the /proc root directory.
- */
-static void __exit cpufreq_proc_exit (void)
-{
-	remove_proc_entry("cpufreq", &proc_root);
-	return;
-}
-
-MODULE_AUTHOR ("Dominik Brodowski <linux@brodo.de>");
-MODULE_DESCRIPTION ("CPUfreq /proc/cpufreq interface");
-MODULE_LICENSE ("GPL");
-
-module_init(cpufreq_proc_init);
-module_exit(cpufreq_proc_exit);
diff -Nru a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/crypto/Kconfig	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,23 @@
+menu "Hardware crypto devices"
+
+config CRYPTO_DEV_PADLOCK
+	tristate "Support for VIA PadLock ACE"
+	depends on CRYPTO && X86 && !X86_64
+	help
+	  Some VIA processors come with an integrated crypto engine
+	  (so called VIA PadLock ACE, Advanced Cryptography Engine)
+	  that provides instructions for very fast {en,de}cryption 
+	  with some algorithms.
+	  
+	  The instructions are used only when the CPU supports them.
+	  Otherwise software encryption is used. If you are unsure,
+	  say Y.
+
+config CRYPTO_DEV_PADLOCK_AES
+	bool "Support for AES in VIA PadLock"
+	depends on CRYPTO_DEV_PADLOCK
+	default y
+	help
+	  Use VIA PadLock for AES algorithm.
+
+endmenu
diff -Nru a/drivers/crypto/Makefile b/drivers/crypto/Makefile
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/crypto/Makefile	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,7 @@
+
+obj-$(CONFIG_CRYPTO_DEV_PADLOCK) += padlock.o
+
+padlock-objs-$(CONFIG_CRYPTO_DEV_PADLOCK_AES) += padlock-aes.o
+
+padlock-objs := padlock-generic.o $(padlock-objs-y)
+
diff -Nru a/drivers/crypto/padlock-aes.c b/drivers/crypto/padlock-aes.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/crypto/padlock-aes.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,468 @@
+/* 
+ * Cryptographic API.
+ *
+ * Support for VIA PadLock hardware crypto engine.
+ *
+ * Copyright (c) 2004  Michal Ludvig <michal@logix.cz>
+ *
+ * Key expansion routine taken from crypto/aes.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.
+ *
+ * ---------------------------------------------------------------------------
+ * 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.
+ * ---------------------------------------------------------------------------
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/crypto.h>
+#include <linux/interrupt.h>
+#include <asm/byteorder.h>
+#include "padlock.h"
+
+#define AES_MIN_KEY_SIZE	16	/* in uint8_t units */
+#define AES_MAX_KEY_SIZE	32	/* ditto */
+#define AES_BLOCK_SIZE		16	/* ditto */
+#define AES_EXTENDED_KEY_SIZE	64	/* in uint32_t units */
+#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;
+	uint32_t *D;
+	int key_length;
+};
+
+/* ====== Key management routines ====== */
+
+static inline uint32_t
+generic_rotr32 (const uint32_t x, const unsigned bits)
+{
+	const unsigned n = bits % 32;
+	return (x >> n) | (x << (32 - n));
+}
+
+static inline uint32_t
+generic_rotl32 (const uint32_t x, const unsigned bits)
+{
+	const unsigned n = bits % 32;
+	return (x << n) | (x >> (32 - n));
+}
+
+#define rotl generic_rotl32
+#define rotr generic_rotr32
+
+/*
+ * #define byte(x, nr) ((unsigned char)((x) >> (nr*8))) 
+ */
+static inline uint8_t
+byte(const uint32_t x, const unsigned n)
+{
+	return x >> (n << 3);
+}
+
+#define uint32_t_in(x) le32_to_cpu(*(const uint32_t *)(x))
+#define uint32_t_out(to, from) (*(uint32_t *)(to) = cpu_to_le32(from))
+
+#define E_KEY ctx->E
+#define D_KEY ctx->D
+
+static uint8_t pow_tab[256];
+static uint8_t log_tab[256];
+static uint8_t sbx_tab[256];
+static uint8_t isb_tab[256];
+static uint32_t rco_tab[10];
+static uint32_t ft_tab[4][256];
+static uint32_t it_tab[4][256];
+
+static uint32_t fl_tab[4][256];
+static uint32_t il_tab[4][256];
+
+static inline uint8_t
+f_mult (uint8_t a, uint8_t b)
+{
+	uint8_t 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 f_rn(bo, bi, n, k)					\
+    bo[n] =  ft_tab[0][byte(bi[n],0)] ^				\
+             ft_tab[1][byte(bi[(n + 1) & 3],1)] ^		\
+             ft_tab[2][byte(bi[(n + 2) & 3],2)] ^		\
+             ft_tab[3][byte(bi[(n + 3) & 3],3)] ^ *(k + n)
+
+#define i_rn(bo, bi, n, k)					\
+    bo[n] =  it_tab[0][byte(bi[n],0)] ^				\
+             it_tab[1][byte(bi[(n + 3) & 3],1)] ^		\
+             it_tab[2][byte(bi[(n + 2) & 3],2)] ^		\
+             it_tab[3][byte(bi[(n + 1) & 3],3)] ^ *(k + n)
+
+#define ls_box(x)				\
+    ( fl_tab[0][byte(x, 0)] ^			\
+      fl_tab[1][byte(x, 1)] ^			\
+      fl_tab[2][byte(x, 2)] ^			\
+      fl_tab[3][byte(x, 3)] )
+
+#define f_rl(bo, bi, n, k)					\
+    bo[n] =  fl_tab[0][byte(bi[n],0)] ^				\
+             fl_tab[1][byte(bi[(n + 1) & 3],1)] ^		\
+             fl_tab[2][byte(bi[(n + 2) & 3],2)] ^		\
+             fl_tab[3][byte(bi[(n + 3) & 3],3)] ^ *(k + n)
+
+#define i_rl(bo, bi, n, k)					\
+    bo[n] =  il_tab[0][byte(bi[n],0)] ^				\
+             il_tab[1][byte(bi[(n + 3) & 3],1)] ^		\
+             il_tab[2][byte(bi[(n + 2) & 3],2)] ^		\
+             il_tab[3][byte(bi[(n + 1) & 3],3)] ^ *(k + n)
+
+static void
+gen_tabs (void)
+{
+	uint32_t i, t;
+	uint8_t p, q;
+
+	/* log and power tables for GF(2**8) finite field with
+	   0x011b as modular polynomial - the simplest prmitive
+	   root is 0x03, used here to generate the tables */
+
+	for (i = 0, p = 1; i < 256; ++i) {
+		pow_tab[i] = (uint8_t) p;
+		log_tab[p] = (uint8_t) 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] = (uint8_t) i;
+	}
+
+	for (i = 0; i < 256; ++i) {
+		p = sbx_tab[i];
+
+		t = p;
+		fl_tab[0][i] = t;
+		fl_tab[1][i] = rotl (t, 8);
+		fl_tab[2][i] = rotl (t, 16);
+		fl_tab[3][i] = rotl (t, 24);
+
+		t = ((uint32_t) ff_mult (2, p)) |
+		    ((uint32_t) p << 8) |
+		    ((uint32_t) p << 16) | ((uint32_t) ff_mult (3, p) << 24);
+
+		ft_tab[0][i] = t;
+		ft_tab[1][i] = rotl (t, 8);
+		ft_tab[2][i] = rotl (t, 16);
+		ft_tab[3][i] = rotl (t, 24);
+
+		p = isb_tab[i];
+
+		t = p;
+		il_tab[0][i] = t;
+		il_tab[1][i] = rotl (t, 8);
+		il_tab[2][i] = rotl (t, 16);
+		il_tab[3][i] = rotl (t, 24);
+
+		t = ((uint32_t) ff_mult (14, p)) |
+		    ((uint32_t) ff_mult (9, p) << 8) |
+		    ((uint32_t) ff_mult (13, p) << 16) |
+		    ((uint32_t) ff_mult (11, p) << 24);
+
+		it_tab[0][i] = t;
+		it_tab[1][i] = rotl (t, 8);
+		it_tab[2][i] = rotl (t, 16);
+		it_tab[3][i] = rotl (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) ^= rotr(u ^ t,  8) ^ \
+          rotr(v ^ t, 16) ^ \
+          rotr(t,24)
+
+/* initialise the key schedule from the user supplied key */
+
+#define loop4(i)                                    \
+{   t = rotr(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 = rotr(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 = rotr(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;   \
+}
+
+/* Tells whether the ACE is capable to generate
+   the extended key for a given key_len. */
+static inline int
+aes_hw_extkey_available(uint8_t key_len)
+{
+	/* TODO: We should check the actual CPU model/stepping
+	         as it's possible that the capability will be
+	         added in the next CPU revisions. */
+	if (key_len == 16)
+		return 1;
+	return 0;
+}
+
+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;
+	uint32_t i, t, u, v, w;
+	uint32_t P[AES_EXTENDED_KEY_SIZE];
+	uint32_t rounds;
+
+	if (key_len != 16 && key_len != 24 && key_len != 32) {
+		*flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
+		return -EINVAL;
+	}
+
+	ctx->key_length = key_len;
+
+	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]));
+
+	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);
+
+	/* Don't generate extended keys if the hardware can do it. */
+	if (aes_hw_extkey_available(key_len))
+		return 0;
+
+	switch (key_len) {
+	case 16:
+		t = E_KEY[3];
+		for (i = 0; i < 10; ++i)
+			loop4 (i);
+		break;
+
+	case 24:
+		E_KEY[4] = uint32_t_in (in_key + 16);
+		t = E_KEY[5] = uint32_t_in (in_key + 20);
+		for (i = 0; i < 8; ++i)
+			loop6 (i);
+		break;
+
+	case 32:
+		E_KEY[4] = uint32_t_in (in_key + 16);
+		E_KEY[5] = uint32_t_in (in_key + 20);
+		E_KEY[6] = uint32_t_in (in_key + 24);
+		t = E_KEY[7] = uint32_t_in (in_key + 28);
+		for (i = 0; i < 7; ++i)
+			loop8 (i);
+		break;
+	}
+
+	D_KEY[0] = E_KEY[0];
+	D_KEY[1] = E_KEY[1];
+	D_KEY[2] = E_KEY[2];
+	D_KEY[3] = E_KEY[3];
+
+	for (i = 4; i < key_len + 24; ++i) {
+		imix_col (D_KEY[i], E_KEY[i]);
+	}
+
+	/* PadLock needs a different format of the decryption key. */
+	rounds = 10 + (key_len - 16) / 4;
+
+	for (i = 0; i < rounds; i++) {
+		P[((i + 1) * 4) + 0] = D_KEY[((rounds - i - 1) * 4) + 0];
+		P[((i + 1) * 4) + 1] = D_KEY[((rounds - i - 1) * 4) + 1];
+		P[((i + 1) * 4) + 2] = D_KEY[((rounds - i - 1) * 4) + 2];
+		P[((i + 1) * 4) + 3] = D_KEY[((rounds - i - 1) * 4) + 3];
+	}
+
+	P[0] = E_KEY[(rounds * 4) + 0];
+	P[1] = E_KEY[(rounds * 4) + 1];
+	P[2] = E_KEY[(rounds * 4) + 2];
+	P[3] = E_KEY[(rounds * 4) + 3];
+
+	memcpy(D_KEY, P, AES_EXTENDED_KEY_SIZE_B);
+
+	return 0;
+}
+
+/* ====== 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)
+{
+	asm volatile ("pushfl; popfl");		/* enforce key reload. */
+	asm volatile (".byte 0xf3,0x0f,0xa7,0xc8"	/* rep xcryptecb */
+		      : "+S"(input), "+D"(output)
+		      : "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)
+{
+	/* 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);
+}
+
+static void
+aes_encrypt(void *ctx_arg, uint8_t *out, const uint8_t *in)
+{
+	aes_padlock(ctx_arg, out, in, CRYPTO_DIR_ENCRYPT);
+}
+
+static void
+aes_decrypt(void *ctx_arg, uint8_t *out, const uint8_t *in)
+{
+	aes_padlock(ctx_arg, out, in, CRYPTO_DIR_DECRYPT);
+}
+
+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
+		}
+	}
+};
+
+int __init padlock_init_aes(void)
+{
+	printk(KERN_NOTICE PFX "Using VIA PadLock ACE for AES algorithm.\n");
+
+	gen_tabs();
+	return crypto_register_alg(&aes_alg);
+}
+
+void __exit padlock_fini_aes(void)
+{
+	crypto_unregister_alg(&aes_alg);
+}
diff -Nru a/drivers/crypto/padlock-generic.c b/drivers/crypto/padlock-generic.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/crypto/padlock-generic.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,63 @@
+/* 
+ * Cryptographic API.
+ *
+ * Support for VIA PadLock hardware crypto engine.
+ *
+ * Copyright (c) 2004  Michal Ludvig <michal@logix.cz>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the 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/init.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/crypto.h>
+#include <asm/byteorder.h>
+#include "padlock.h"
+
+static int __init
+padlock_init(void)
+{
+	int ret = -ENOSYS;
+	
+	if (!cpu_has_xcrypt) {
+		printk(KERN_ERR PFX "VIA PadLock not detected.\n");
+		return -ENODEV;
+	}
+
+	if (!cpu_has_xcrypt_enabled) {
+		printk(KERN_ERR PFX "VIA PadLock detected, but not enabled. Hmm, strange...\n");
+		return -ENODEV;
+	}
+
+#ifdef CONFIG_CRYPTO_DEV_PADLOCK_AES
+	if ((ret = padlock_init_aes())) {
+		printk(KERN_ERR PFX "VIA PadLock AES initialization failed.\n");
+		return ret;
+	}
+#endif
+
+	if (ret == -ENOSYS)
+		printk(KERN_ERR PFX "Hmm, VIA PadLock was compiled without any algorithm.\n");
+
+	return ret;
+}
+
+static void __exit
+padlock_fini(void)
+{
+#ifdef CONFIG_CRYPTO_DEV_PADLOCK_AES
+	padlock_fini_aes();
+#endif
+}
+
+module_init(padlock_init);
+module_exit(padlock_fini);
+
+MODULE_DESCRIPTION("VIA PadLock crypto engine support.");
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_AUTHOR("Michal Ludvig");
diff -Nru a/drivers/crypto/padlock.h b/drivers/crypto/padlock.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/crypto/padlock.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,36 @@
+/*
+ * Driver for VIA PadLock
+ *
+ * Copyright (c) 2004 Michal Ludvig <michal@logix.cz>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the 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 _CRYPTO_PADLOCK_H
+#define _CRYPTO_PADLOCK_H
+
+/* 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;
+};
+
+#define PFX	"padlock: "
+
+#ifdef CONFIG_CRYPTO_DEV_PADLOCK_AES
+int padlock_init_aes(void);
+void padlock_fini_aes(void);
+#endif
+
+#endif	/* _CRYPTO_PADLOCK_H */
diff -Nru a/drivers/eisa/Makefile b/drivers/eisa/Makefile
--- a/drivers/eisa/Makefile	2005-03-01 23:38:57 -08:00
+++ b/drivers/eisa/Makefile	2005-03-01 23:38:57 -08:00
@@ -1,8 +1,5 @@
 # Makefile for the Linux device tree
 
-# Being anal sometimes saves a crash/reboot cycle... ;-)
-EXTRA_CFLAGS    := -Werror
-
 obj-$(CONFIG_EISA)	        += eisa-bus.o
 obj-${CONFIG_EISA_PCI_EISA}     += pci_eisa.o
 
diff -Nru a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
--- a/drivers/firmware/Kconfig	2005-03-01 23:38:43 -08:00
+++ b/drivers/firmware/Kconfig	2005-03-01 23:38:43 -08:00
@@ -30,10 +30,10 @@
 	  Note that using this driver in concert with efibootmgr requires
 	  at least test release version 0.5.0-test3 or later, which is
 	  available from Matt Domsch's website located at:
-	  http://linux.dell.com/efibootmgr/testing/efibootmgr-0.5.0-test3.tar.gz
+	  <http://linux.dell.com/efibootmgr/testing/efibootmgr-0.5.0-test3.tar.gz>
 
 	  Subsequent efibootmgr releases may be found at:
-	  http://linux.dell.com/efibootmgr
+	  <http://linux.dell.com/efibootmgr>
 
 config EFI_PCDP
 	bool "Console device selection via EFI PCDP or HCDP table"
diff -Nru a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c
--- a/drivers/firmware/efivars.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/firmware/efivars.c	2005-03-01 23:39:09 -08:00
@@ -97,7 +97,7 @@
  * efi.get_next_variable() is only called from efivars_init(),
  * which is protected by the BKL, so that path is safe.
  */
-static spinlock_t efivars_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(efivars_lock);
 static LIST_HEAD(efivar_list);
 
 /*
diff -Nru a/drivers/firmware/pcdp.c b/drivers/firmware/pcdp.c
--- a/drivers/firmware/pcdp.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/firmware/pcdp.c	2005-03-01 23:38:54 -08:00
@@ -98,44 +98,3 @@
 
 	return -ENODEV;
 }
-
-#ifdef CONFIG_IA64_EARLY_PRINTK_UART
-unsigned long
-hcdp_early_uart (void)
-{
-	efi_system_table_t *systab;
-	efi_config_table_t *config_tables;
-	unsigned long addr = 0;
-	struct pcdp *pcdp = 0;
-	struct pcdp_uart *uart;
-	int i;
-
-	systab = (efi_system_table_t *) ia64_boot_param->efi_systab;
-	if (!systab)
-		return 0;
-	systab = __va(systab);
-
-	config_tables = (efi_config_table_t *) systab->tables;
-	if (!config_tables)
-		return 0;
-	config_tables = __va(config_tables);
-
-	for (i = 0; i < systab->nr_tables; i++) {
-		if (efi_guidcmp(config_tables[i].guid, HCDP_TABLE_GUID) == 0) {
-			pcdp = (struct pcdp *) config_tables[i].table;
-			break;
-		}
-	}
-	if (!pcdp)
-		return 0;
-	pcdp = __va(pcdp);
-
-	for (i = 0, uart = pcdp->uart; i < pcdp->num_uarts; i++, uart++) {
-		if (uart->type == PCDP_CONSOLE_UART) {
-			addr = uart->addr.address;
-			break;
-		}
-	}
-	return addr;
-}
-#endif /* CONFIG_IA64_EARLY_PRINTK_UART */
diff -Nru a/drivers/i2c/algos/Kconfig b/drivers/i2c/algos/Kconfig
--- a/drivers/i2c/algos/Kconfig	2005-03-01 23:39:19 -08:00
+++ b/drivers/i2c/algos/Kconfig	2005-03-01 23:39:19 -08:00
@@ -53,5 +53,18 @@
 	tristate "MPC8xx CPM I2C interface"
 	depends on 8xx && I2C
 
+config I2C_ALGO_SIBYTE
+	tristate "SiByte SMBus interface"
+	depends on SIBYTE_SB1xxx_SOC && I2C
+	help
+	  Supports the SiByte SOC on-chip I2C interfaces (2 channels).
+
+config I2C_ALGO_SGI
+	tristate "I2C SGI interfaces"
+	depends on I2C && (SGI_IP22 || SGI_IP32 || X86_VISWS)
+	help
+	  Supports the SGI interfaces like the ones found on SGI Indy VINO
+	  or SGI O2 MACE.
+
 endmenu
 
diff -Nru a/drivers/i2c/algos/Makefile b/drivers/i2c/algos/Makefile
--- a/drivers/i2c/algos/Makefile	2005-03-01 23:39:08 -08:00
+++ b/drivers/i2c/algos/Makefile	2005-03-01 23:39:08 -08:00
@@ -6,6 +6,8 @@
 obj-$(CONFIG_I2C_ALGOPCF)	+= i2c-algo-pcf.o
 obj-$(CONFIG_I2C_ALGOPCA)	+= i2c-algo-pca.o
 obj-$(CONFIG_I2C_ALGOITE)	+= i2c-algo-ite.o
+obj-$(CONFIG_I2C_ALGO_SIBYTE)	+= i2c-algo-sibyte.o
+obj-$(CONFIG_I2C_ALGO_SGI)	+= i2c-algo-sgi.o
 
 ifeq ($(CONFIG_I2C_DEBUG_ALGO),y)
 EXTRA_CFLAGS += -DDEBUG
diff -Nru a/drivers/i2c/algos/i2c-algo-bit.c b/drivers/i2c/algos/i2c-algo-bit.c
--- a/drivers/i2c/algos/i2c-algo-bit.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/i2c/algos/i2c-algo-bit.c	2005-03-01 23:38:57 -08:00
@@ -511,8 +511,8 @@
 
 static u32 bit_func(struct i2c_adapter *adap)
 {
-	return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR | 
-	       I2C_FUNC_PROTOCOL_MANGLING;
+	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | 
+	       I2C_FUNC_10BIT_ADDR | I2C_FUNC_PROTOCOL_MANGLING;
 }
 
 
diff -Nru a/drivers/i2c/algos/i2c-algo-pca.c b/drivers/i2c/algos/i2c-algo-pca.c
--- a/drivers/i2c/algos/i2c-algo-pca.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/i2c/algos/i2c-algo-pca.c	2005-03-01 23:39:07 -08:00
@@ -189,7 +189,7 @@
 
 	state = pca_status(adap);
 	if ( state != 0xF8 ) {
-		printk(KERN_ERR DRIVER ": bus is not idle. status is %#04x\n", state );
+		dev_dbg(&i2c_adap->dev, "bus is not idle. status is %#04x\n", state );
 		/* FIXME: what to do. Force stop ? */
 		return -EREMOTEIO;
 	}
@@ -328,7 +328,7 @@
 
 static u32 pca_func(struct i2c_adapter *adap)
 {
-        return I2C_FUNC_SMBUS_EMUL;
+        return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
 }
 
 static int pca_init(struct i2c_algo_pca_data *adap)
diff -Nru a/drivers/i2c/algos/i2c-algo-pcf.c b/drivers/i2c/algos/i2c-algo-pcf.c
--- a/drivers/i2c/algos/i2c-algo-pcf.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/i2c/algos/i2c-algo-pcf.c	2005-03-01 23:39:08 -08:00
@@ -414,8 +414,8 @@
 
 static u32 pcf_func(struct i2c_adapter *adap)
 {
-	return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR | 
-	       I2C_FUNC_PROTOCOL_MANGLING; 
+	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | 
+	       I2C_FUNC_10BIT_ADDR | I2C_FUNC_PROTOCOL_MANGLING; 
 }
 
 /* -----exported algorithm data: -------------------------------------	*/
diff -Nru a/drivers/i2c/algos/i2c-algo-sgi.c b/drivers/i2c/algos/i2c-algo-sgi.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/i2c/algos/i2c-algo-sgi.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,189 @@
+/*
+ * i2c-algo-sgi.c: i2c driver algorithms for SGI adapters.
+ * 
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * Copyright (C) 2003 Ladislav Michl <ladis@linux-mips.org>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+
+#include <linux/i2c.h>
+#include <linux/i2c-algo-sgi.h>
+
+
+#define SGI_I2C_FORCE_IDLE	(0 << 0)
+#define SGI_I2C_NOT_IDLE	(1 << 0)
+#define SGI_I2C_WRITE		(0 << 1)
+#define SGI_I2C_READ		(1 << 1)
+#define SGI_I2C_RELEASE_BUS	(0 << 2)
+#define SGI_I2C_HOLD_BUS	(1 << 2)
+#define SGI_I2C_XFER_DONE	(0 << 4)
+#define SGI_I2C_XFER_BUSY	(1 << 4)
+#define SGI_I2C_ACK		(0 << 5)
+#define SGI_I2C_NACK		(1 << 5)
+#define SGI_I2C_BUS_OK		(0 << 7)
+#define SGI_I2C_BUS_ERR		(1 << 7)
+
+#define get_control()		adap->getctrl(adap->data)
+#define set_control(val)	adap->setctrl(adap->data, val)
+#define read_data()		adap->rdata(adap->data)
+#define write_data(val)		adap->wdata(adap->data, val)
+
+
+static int wait_xfer_done(struct i2c_algo_sgi_data *adap)
+{
+	int i;
+
+	for (i = 0; i < adap->xfer_timeout; i++) {
+		if ((get_control() & SGI_I2C_XFER_BUSY) == 0)
+			return 0;
+		udelay(1);
+	}
+
+	return -ETIMEDOUT;
+}
+
+static int wait_ack(struct i2c_algo_sgi_data *adap)
+{
+	int i;
+
+	if (wait_xfer_done(adap))
+		return -ETIMEDOUT;
+	for (i = 0; i < adap->ack_timeout; i++) {
+		if ((get_control() & SGI_I2C_NACK) == 0)
+			return 0;
+		udelay(1);
+	}
+
+	return -ETIMEDOUT;
+}
+
+static int force_idle(struct i2c_algo_sgi_data *adap)
+{
+	int i;
+
+	set_control(SGI_I2C_FORCE_IDLE);
+	for (i = 0; i < adap->xfer_timeout; i++) {
+		if ((get_control() & SGI_I2C_NOT_IDLE) == 0)
+			goto out;
+		udelay(1);
+	}
+	return -ETIMEDOUT;
+out:
+	if (get_control() & SGI_I2C_BUS_ERR)
+		return -EIO;
+	return 0;
+}
+
+static int do_address(struct i2c_algo_sgi_data *adap, unsigned int addr,
+		      int rd)
+{
+	if (rd)
+		set_control(SGI_I2C_NOT_IDLE);
+	/* Check if bus is idle, eventually force it to do so */
+	if (get_control() & SGI_I2C_NOT_IDLE)
+		if (force_idle(adap))
+	                return -EIO;
+	/* Write out the i2c chip address and specify operation */
+	set_control(SGI_I2C_HOLD_BUS | SGI_I2C_WRITE | SGI_I2C_NOT_IDLE);
+	if (rd)
+		addr |= 1;
+	write_data(addr);
+	if (wait_ack(adap))
+		return -EIO;
+	return 0;
+}
+
+static int i2c_read(struct i2c_algo_sgi_data *adap, unsigned char *buf,
+		    unsigned int len)
+{
+	int i;
+
+	set_control(SGI_I2C_HOLD_BUS | SGI_I2C_READ | SGI_I2C_NOT_IDLE);
+	for (i = 0; i < len; i++) {
+		if (wait_xfer_done(adap))
+			return -EIO;
+		buf[i] = read_data();
+	}
+	set_control(SGI_I2C_RELEASE_BUS | SGI_I2C_FORCE_IDLE);
+
+	return 0;
+
+}
+
+static int i2c_write(struct i2c_algo_sgi_data *adap, unsigned char *buf,
+		     unsigned int len)
+{
+	int i;
+
+	/* We are already in write state */
+	for (i = 0; i < len; i++) {
+		write_data(buf[i]);
+		if (wait_ack(adap))
+			return -EIO;
+	}
+	return 0;
+}
+
+static int sgi_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[],
+		    int num)
+{
+	struct i2c_algo_sgi_data *adap = i2c_adap->algo_data;
+	struct i2c_msg *p;
+	int i, err = 0;
+
+	for (i = 0; !err && i < num; i++) {
+		p = &msgs[i];
+		err = do_address(adap, p->addr, p->flags & I2C_M_RD);
+		if (err || !p->len)
+			continue;
+		if (p->flags & I2C_M_RD)
+			err = i2c_read(adap, p->buf, p->len);
+		else
+			err = i2c_write(adap, p->buf, p->len);
+	}
+
+	return err;
+}
+
+static u32 sgi_func(struct i2c_adapter *adap)
+{
+	return I2C_FUNC_SMBUS_EMUL;
+}
+
+static struct i2c_algorithm sgi_algo = {
+	.name		= "SGI algorithm",
+	.id		= I2C_ALGO_SGI,
+	.master_xfer	= sgi_xfer,
+	.functionality	= sgi_func,
+};
+
+/* 
+ * registering functions to load algorithms at runtime 
+ */
+int i2c_sgi_add_bus(struct i2c_adapter *adap)
+{
+	adap->id |= sgi_algo.id;
+	adap->algo = &sgi_algo;
+
+	return i2c_add_adapter(adap);
+}
+
+
+int i2c_sgi_del_bus(struct i2c_adapter *adap)
+{
+	return i2c_del_adapter(adap);
+}
+
+EXPORT_SYMBOL(i2c_sgi_add_bus);
+EXPORT_SYMBOL(i2c_sgi_del_bus);
+
+MODULE_AUTHOR("Ladislav Michl <ladis@linux-mips.org>");
+MODULE_DESCRIPTION("I2C-Bus SGI algorithm");
+MODULE_LICENSE("GPL");
diff -Nru a/drivers/i2c/algos/i2c-algo-sibyte.c b/drivers/i2c/algos/i2c-algo-sibyte.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/i2c/algos/i2c-algo-sibyte.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,225 @@
+/* ------------------------------------------------------------------------- */
+/* i2c-algo-sibyte.c i2c driver algorithms for bit-shift adapters		     */
+/* ------------------------------------------------------------------------- */
+/*   Copyright (C) 2001,2002,2003 Broadcom Corporation
+     Copyright (C) 1995-2000 Simon G. Vogl
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You 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.		     */
+/* ------------------------------------------------------------------------- */
+
+/* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and even
+   Frodo Looijaard <frodol@dds.nl>.  */
+
+/* Ported for SiByte SOCs by Broadcom Corporation.  */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/sibyte/sb1250_regs.h>
+#include <asm/sibyte/sb1250_smbus.h>
+
+#include <linux/i2c.h>
+#include <linux/i2c-algo-sibyte.h>
+
+/* ----- global defines ----------------------------------------------- */
+#define SMB_CSR(a,r) ((long)(a->reg_base + r))
+
+/* ----- global variables ---------------------------------------------	*/
+
+/* module parameters:
+ */
+static int bit_scan=0;	/* have a look at what's hanging 'round		*/
+
+
+static int smbus_xfer(struct i2c_adapter *i2c_adap, u16 addr, 
+                      unsigned short flags, char read_write,
+                      u8 command, int size, union i2c_smbus_data * data)
+{
+	struct i2c_algo_sibyte_data *adap = i2c_adap->algo_data;
+        int data_bytes = 0;
+        int error;
+
+        while (csr_in32(SMB_CSR(adap, R_SMB_STATUS)) & M_SMB_BUSY)
+                ;
+
+        switch (size) {
+        case I2C_SMBUS_QUICK:
+                csr_out32((V_SMB_ADDR(addr) | (read_write == I2C_SMBUS_READ ? M_SMB_QDATA : 0) |
+			   V_SMB_TT_QUICKCMD), SMB_CSR(adap, R_SMB_START));
+                break;
+        case I2C_SMBUS_BYTE:
+                if (read_write == I2C_SMBUS_READ) {
+                        csr_out32((V_SMB_ADDR(addr) | V_SMB_TT_RD1BYTE),
+				  SMB_CSR(adap, R_SMB_START));
+                        data_bytes = 1;
+                } else {
+                        csr_out32(V_SMB_CMD(command), SMB_CSR(adap, R_SMB_CMD));
+                        csr_out32((V_SMB_ADDR(addr) | V_SMB_TT_WR1BYTE),
+				  SMB_CSR(adap, R_SMB_START));
+                }
+                break;
+        case I2C_SMBUS_BYTE_DATA:
+                csr_out32(V_SMB_CMD(command), SMB_CSR(adap, R_SMB_CMD));
+                if (read_write == I2C_SMBUS_READ) {
+                        csr_out32((V_SMB_ADDR(addr) | V_SMB_TT_CMD_RD1BYTE),
+				  SMB_CSR(adap, R_SMB_START));
+                        data_bytes = 1;
+                } else {
+                        csr_out32(V_SMB_LB(data->byte), SMB_CSR(adap, R_SMB_DATA));
+                        csr_out32((V_SMB_ADDR(addr) | V_SMB_TT_WR2BYTE),
+				  SMB_CSR(adap, R_SMB_START));
+                }
+                break;
+        case I2C_SMBUS_WORD_DATA:
+                csr_out32(V_SMB_CMD(command), SMB_CSR(adap, R_SMB_CMD));
+                if (read_write == I2C_SMBUS_READ) {
+                        csr_out32((V_SMB_ADDR(addr) | V_SMB_TT_CMD_RD2BYTE),
+				  SMB_CSR(adap, R_SMB_START));
+                        data_bytes = 2;
+                } else {
+                        csr_out32(V_SMB_LB(data->word & 0xff), SMB_CSR(adap, R_SMB_DATA));
+                        csr_out32(V_SMB_MB(data->word >> 8), SMB_CSR(adap, R_SMB_DATA));
+                        csr_out32((V_SMB_ADDR(addr) | V_SMB_TT_WR2BYTE),
+				  SMB_CSR(adap, R_SMB_START));
+                }
+                break;
+        default:
+                return -1;      /* XXXKW better error code? */
+        }
+
+        while (csr_in32(SMB_CSR(adap, R_SMB_STATUS)) & M_SMB_BUSY)
+                ;
+
+        error = csr_in32(SMB_CSR(adap, R_SMB_STATUS));
+        if (error & M_SMB_ERROR) {
+                /* Clear error bit by writing a 1 */
+                csr_out32(M_SMB_ERROR, SMB_CSR(adap, R_SMB_STATUS));
+                return -1;      /* XXXKW better error code? */
+        }
+
+        if (data_bytes == 1)
+                data->byte = csr_in32(SMB_CSR(adap, R_SMB_DATA)) & 0xff;
+        if (data_bytes == 2)
+                data->word = csr_in32(SMB_CSR(adap, R_SMB_DATA)) & 0xffff;
+
+        return 0;
+}
+
+static int algo_control(struct i2c_adapter *adapter, 
+	unsigned int cmd, unsigned long arg)
+{
+	return 0;
+}
+
+static u32 bit_func(struct i2c_adapter *adap)
+{
+	return (I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
+                I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA);
+}
+
+
+/* -----exported algorithm data: -------------------------------------	*/
+
+static struct i2c_algorithm i2c_sibyte_algo = {
+	"SiByte algorithm",
+	I2C_ALGO_SIBYTE,
+	NULL,                           /* master_xfer          */
+	smbus_xfer,                   	/* smbus_xfer           */
+	NULL,				/* slave_xmit		*/
+	NULL,				/* slave_recv		*/
+	algo_control,			/* ioctl		*/
+	bit_func,			/* functionality	*/
+};
+
+/* 
+ * registering functions to load algorithms at runtime 
+ */
+int i2c_sibyte_add_bus(struct i2c_adapter *i2c_adap, int speed)
+{
+	int i;
+	struct i2c_algo_sibyte_data *adap = i2c_adap->algo_data;
+
+	/* register new adapter to i2c module... */
+
+	i2c_adap->id |= i2c_sibyte_algo.id;
+	i2c_adap->algo = &i2c_sibyte_algo;
+        
+        /* Set the frequency to 100 kHz */
+        csr_out32(speed, SMB_CSR(adap,R_SMB_FREQ));
+        csr_out32(0, SMB_CSR(adap,R_SMB_CONTROL));
+
+	/* scan bus */
+	if (bit_scan) {
+                union i2c_smbus_data data;
+                int rc;
+		printk(KERN_INFO " i2c-algo-sibyte.o: scanning bus %s.\n",
+		       i2c_adap->name);
+		for (i = 0x00; i < 0x7f; i++) {
+                        /* XXXKW is this a realistic probe? */
+                        rc = smbus_xfer(i2c_adap, i, 0, I2C_SMBUS_READ, 0,
+                                        I2C_SMBUS_BYTE_DATA, &data);
+			if (!rc) {
+				printk("(%02x)",i); 
+			} else 
+				printk("."); 
+		}
+		printk("\n");
+	}
+
+	i2c_add_adapter(i2c_adap);
+
+	return 0;
+}
+
+
+int i2c_sibyte_del_bus(struct i2c_adapter *adap)
+{
+	int res;
+
+	if ((res = i2c_del_adapter(adap)) < 0)
+		return res;
+
+	return 0;
+}
+
+int __init i2c_algo_sibyte_init (void)
+{
+	printk("i2c-algo-sibyte.o: i2c SiByte algorithm module\n");
+	return 0;
+}
+
+
+EXPORT_SYMBOL(i2c_sibyte_add_bus);
+EXPORT_SYMBOL(i2c_sibyte_del_bus);
+
+#ifdef MODULE
+MODULE_AUTHOR("Kip Walker, Broadcom Corp.");
+MODULE_DESCRIPTION("SiByte I2C-Bus algorithm");
+MODULE_PARM(bit_scan, "i");
+MODULE_PARM_DESC(bit_scan, "Scan for active chips on the bus");
+MODULE_LICENSE("GPL");
+
+int init_module(void) 
+{
+	return i2c_algo_sibyte_init();
+}
+
+void cleanup_module(void) 
+{
+}
+#endif
diff -Nru a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
--- a/drivers/i2c/busses/Kconfig	2005-03-01 23:39:09 -08:00
+++ b/drivers/i2c/busses/Kconfig	2005-03-01 23:39:09 -08:00
@@ -74,6 +74,16 @@
 	  This driver can also be built as a module.  If so, the module
 	  will be called i2c-amd8111.
 
+config I2C_AU1550
+	tristate "Au1550 SMBus interface"
+	depends on I2C && SOC_AU1550
+	help
+	  If you say yes to this option, support will be included for the
+	  Au1550 SMBus interface.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called i2c-au1550.
+
 config I2C_ELEKTOR
 	tristate "Elektor ISA card"
 	depends on I2C && ISA && BROKEN_ON_SMP
@@ -112,6 +122,7 @@
 	    82801EB
 	    6300ESB
 	    ICH6
+	    ICH7
 
 	  This driver can also be built as a module.  If so, the module
 	  will be called i2c-i801.
@@ -143,8 +154,14 @@
 	  will be called i2c-ibm_iic.
 
 config I2C_IOP3XX
-	tristate "Intel XScale IOP3xx on-chip I2C interface"
-	depends on ARCH_IOP3XX && I2C
+	tristate "Intel IOP3xx and IXP4xx on-chip I2C interface"
+	depends on (ARCH_IOP3XX || ARCH_IXP4XX) && I2C
+	help
+	  Say Y here if you want to use the IIC bus controller on
+	  the Intel IOP3xx I/O Processors or IXP4xx Network Processors.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called i2c-iop3xx.
 
 config I2C_ISA
 	tristate "ISA Bus support"
@@ -202,7 +219,7 @@
 
 config I2C_MPC
 	tristate "MPC107/824x/85xx/52xx"
-	depends on I2C && FSL_OCP
+	depends on I2C && PPC
 	help
 	  If you say yes to this option, support will be included for the
 	  built-in I2C interface on the MPC107/Tsi107/MPC8240/MPC8245 and
@@ -323,6 +340,12 @@
 	  This driver can also be built as a module.  If so, the module
 	  will be called i2c-savage4.
 
+config I2C_SIBYTE
+	tristate "SiByte SMBus interface"
+	depends on SIBYTE_SB1xxx_SOC && I2C
+	help
+	  Supports the SiByte SOC on-chip I2C interfaces (2 channels).
+
 config SCx200_I2C
 	tristate "NatSemi SCx200 I2C using GPIO pins"
 	depends on SCx200_GPIO && I2C
@@ -408,7 +431,7 @@
 	  especially for certain kinds of sensor chips.
 
 	  If you do build this module, be sure to read the notes and warnings
-	  in Documentation/i2c/i2c-stub.
+	  in <file:Documentation/i2c/i2c-stub>.
 
 	  If you don't know what to do here, definitely say N.
 
@@ -417,7 +440,6 @@
 	depends on I2C && PCI && EXPERIMENTAL
 	select I2C_ALGOBIT
 	help
-
 	  If you say yes to this option, support will be included for the VIA
           82C586B I2C interface
 
@@ -428,7 +450,6 @@
 	tristate "VIA 82C596/82C686/823x"
 	depends on I2C && PCI && EXPERIMENTAL
 	help
-
 	  If you say yes to this option, support will be included for the VIA
 	  82C596/82C686/823x I2C interfaces.  Specifically, the following 
 	  chipsets are supported:
@@ -448,7 +469,6 @@
 	depends on I2C && PCI && EXPERIMENTAL
 	select I2C_ALGOBIT
 	help
-
 	  If you say yes to this option, support will be included for the
 	  Voodoo 3 I2C interface.
 
diff -Nru a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
--- a/drivers/i2c/busses/Makefile	2005-03-01 23:38:52 -08:00
+++ b/drivers/i2c/busses/Makefile	2005-03-01 23:38:52 -08:00
@@ -8,6 +8,7 @@
 obj-$(CONFIG_I2C_AMD756)	+= i2c-amd756.o
 obj-$(CONFIG_I2C_AMD756_S4882)	+= i2c-amd756-s4882.o
 obj-$(CONFIG_I2C_AMD8111)	+= i2c-amd8111.o
+obj-$(CONFIG_I2C_AU1550)	+= i2c-au1550.o
 obj-$(CONFIG_I2C_ELEKTOR)	+= i2c-elektor.o
 obj-$(CONFIG_I2C_HYDRA)		+= i2c-hydra.o
 obj-$(CONFIG_I2C_I801)		+= i2c-i801.o
@@ -29,6 +30,7 @@
 obj-$(CONFIG_I2C_RPXLITE)	+= i2c-rpx.o
 obj-$(CONFIG_I2C_S3C2410)	+= i2c-s3c2410.o
 obj-$(CONFIG_I2C_SAVAGE4)	+= i2c-savage4.o
+obj-$(CONFIG_I2C_SIBYTE)	+= i2c-sibyte.o
 obj-$(CONFIG_I2C_SIS5595)	+= i2c-sis5595.o
 obj-$(CONFIG_I2C_SIS630)	+= i2c-sis630.o
 obj-$(CONFIG_I2C_SIS96X)	+= i2c-sis96x.o
diff -Nru a/drivers/i2c/busses/i2c-ali1535.c b/drivers/i2c/busses/i2c-ali1535.c
--- a/drivers/i2c/busses/i2c-ali1535.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/i2c/busses/i2c-ali1535.c	2005-03-01 23:39:09 -08:00
@@ -487,12 +487,7 @@
 };
 
 static struct pci_device_id ali1535_ids[] = {
-	{
-		.vendor =	PCI_VENDOR_ID_AL,
-		.device =	PCI_DEVICE_ID_AL_M7101,
-		.subvendor =	PCI_ANY_ID,
-		.subdevice =	PCI_ANY_ID,
-	},
+	{ PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101) },
 	{ },
 };
 
diff -Nru a/drivers/i2c/busses/i2c-ali1563.c b/drivers/i2c/busses/i2c-ali1563.c
--- a/drivers/i2c/busses/i2c-ali1563.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/i2c/busses/i2c-ali1563.c	2005-03-01 23:39:07 -08:00
@@ -306,7 +306,7 @@
 	pci_write_config_word(dev,ALI1563_SMBBA,ctrl);
 }
 
-static int __init ali1563_setup(struct pci_dev * dev)
+static int __devinit ali1563_setup(struct pci_dev * dev)
 {
 	u16 ctrl;
 
@@ -362,7 +362,7 @@
 	.algo	= &ali1563_algorithm,
 };
 
-static int __init ali1563_probe(struct pci_dev * dev,
+static int __devinit ali1563_probe(struct pci_dev * dev,
 				const struct pci_device_id * id_table)
 {
 	int error;
@@ -378,19 +378,14 @@
 	return error;
 }
 
-static void __exit ali1563_remove(struct pci_dev * dev)
+static void __devexit ali1563_remove(struct pci_dev * dev)
 {
 	i2c_del_adapter(&ali1563_adapter);
 	ali1563_shutdown(dev);
 }
 
 static struct pci_device_id __devinitdata ali1563_id_table[] = {
-	{
-		.vendor		= PCI_VENDOR_ID_AL,
-		.device		= PCI_DEVICE_ID_AL_M1563,
-		.subvendor	= PCI_ANY_ID,
-		.subdevice	= PCI_ANY_ID,
-	},
+	{ PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1563) },
 	{},
 };
 
@@ -400,7 +395,7 @@
  	.name		= "ali1563_i2c",
 	.id_table	= ali1563_id_table,
  	.probe		= ali1563_probe,
-	.remove		= ali1563_remove,
+	.remove		= __devexit_p(ali1563_remove),
 };
 
 static int __init ali1563_init(void)
diff -Nru a/drivers/i2c/busses/i2c-ali15x3.c b/drivers/i2c/busses/i2c-ali15x3.c
--- a/drivers/i2c/busses/i2c-ali15x3.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/i2c/busses/i2c-ali15x3.c	2005-03-01 23:38:57 -08:00
@@ -477,12 +477,7 @@
 };
 
 static struct pci_device_id ali15x3_ids[] = {
-	{
-	.vendor =	PCI_VENDOR_ID_AL,
-	.device =	PCI_DEVICE_ID_AL_M7101,
-	.subvendor =	PCI_ANY_ID,
-	.subdevice =	PCI_ANY_ID,
-	},
+	{ PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101) },
 	{ 0, }
 };
 
diff -Nru a/drivers/i2c/busses/i2c-amd756.c b/drivers/i2c/busses/i2c-amd756.c
--- a/drivers/i2c/busses/i2c-amd756.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/i2c/busses/i2c-amd756.c	2005-03-01 23:39:09 -08:00
@@ -316,11 +316,16 @@
 };
 
 static struct pci_device_id amd756_ids[] = {
-	{PCI_VENDOR_ID_AMD, 0x740B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AMD756 },
-	{PCI_VENDOR_ID_AMD, 0x7413, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AMD766 },
-	{PCI_VENDOR_ID_AMD, 0x7443, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AMD768 },
-	{PCI_VENDOR_ID_AMD, 0x746B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AMD8111 },
-	{PCI_VENDOR_ID_NVIDIA, 0x01B4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NFORCE },
+	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_740B),
+	  .driver_data = AMD756 },
+	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7413),
+	  .driver_data = AMD766 },
+	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_OPUS_7443),
+	  .driver_data = AMD768 },
+	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_SMBUS),
+	  .driver_data = AMD8111 },
+	{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_SMBUS),
+	  .driver_data = NFORCE },
 	{ 0, }
 };
 
diff -Nru a/drivers/i2c/busses/i2c-amd8111.c b/drivers/i2c/busses/i2c-amd8111.c
--- a/drivers/i2c/busses/i2c-amd8111.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/i2c/busses/i2c-amd8111.c	2005-03-01 23:39:09 -08:00
@@ -332,7 +332,7 @@
 
 
 static struct pci_device_id amd8111_ids[] = {
-	{ 0x1022, 0x746a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_SMBUS2) },
 	{ 0, }
 };
 
diff -Nru a/drivers/i2c/busses/i2c-au1550.c b/drivers/i2c/busses/i2c-au1550.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/i2c/busses/i2c-au1550.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,435 @@
+/*
+ * i2c-au1550.c: SMBus (i2c) adapter for Alchemy PSC interface
+ * Copyright (C) 2004 Embedded Edge, LLC <dan@embeddededge.com>
+ *
+ * 2.6 port by Matt Porter <mporter@kernel.crashing.org>
+ *
+ * The documentation describes this as an SMBus controller, but it doesn't
+ * understand any of the SMBus protocol in hardware.  It's really an I2C
+ * controller that could emulate most of the SMBus in software.
+ *
+ * This is just a skeleton adapter to use with the Au1550 PSC
+ * algorithm.  It was developed for the Pb1550, but will work with
+ * any Au1550 board that has a similar PSC configuration.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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/delay.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/i2c.h>
+
+#include <asm/mach-au1x00/au1000.h>
+#include <asm/mach-pb1x00/pb1550.h>
+#include <asm/mach-au1x00/au1xxx_psc.h>
+
+#include "i2c-au1550.h"
+
+static int
+wait_xfer_done(struct i2c_au1550_data *adap)
+{
+	u32	stat;
+	int	i;
+	volatile psc_smb_t	*sp;
+
+	sp = (volatile psc_smb_t *)(adap->psc_base);
+
+	/* Wait for Tx FIFO Underflow.
+	*/
+	for (i = 0; i < adap->xfer_timeout; i++) {
+		stat = sp->psc_smbevnt;
+		au_sync();
+		if ((stat & PSC_SMBEVNT_TU) != 0) {
+			/* Clear it.  */
+			sp->psc_smbevnt = PSC_SMBEVNT_TU;
+			au_sync();
+			return 0;
+		}
+		udelay(1);
+	}
+
+	return -ETIMEDOUT;
+}
+
+static int
+wait_ack(struct i2c_au1550_data *adap)
+{
+	u32	stat;
+	volatile psc_smb_t	*sp;
+
+	if (wait_xfer_done(adap))
+		return -ETIMEDOUT;
+
+	sp = (volatile psc_smb_t *)(adap->psc_base);
+
+	stat = sp->psc_smbevnt;
+	au_sync();
+
+	if ((stat & (PSC_SMBEVNT_DN | PSC_SMBEVNT_AN | PSC_SMBEVNT_AL)) != 0)
+		return -ETIMEDOUT;
+
+	return 0;
+}
+
+static int
+wait_master_done(struct i2c_au1550_data *adap)
+{
+	u32	stat;
+	int	i;
+	volatile psc_smb_t	*sp;
+
+	sp = (volatile psc_smb_t *)(adap->psc_base);
+
+	/* Wait for Master Done.
+	*/
+	for (i = 0; i < adap->xfer_timeout; i++) {
+		stat = sp->psc_smbevnt;
+		au_sync();
+		if ((stat & PSC_SMBEVNT_MD) != 0)
+			return 0;
+		udelay(1);
+	}
+
+	return -ETIMEDOUT;
+}
+
+static int
+do_address(struct i2c_au1550_data *adap, unsigned int addr, int rd)
+{
+	volatile psc_smb_t	*sp;
+	u32			stat;
+
+	sp = (volatile psc_smb_t *)(adap->psc_base);
+
+	/* Reset the FIFOs, clear events.
+	*/
+	sp->psc_smbpcr = PSC_SMBPCR_DC;
+	sp->psc_smbevnt = PSC_SMBEVNT_ALLCLR;
+	au_sync();
+	do {
+		stat = sp->psc_smbpcr;
+		au_sync();
+	} while ((stat & PSC_SMBPCR_DC) != 0);
+
+	/* Write out the i2c chip address and specify operation
+	*/
+	addr <<= 1;
+	if (rd)
+		addr |= 1;
+
+	/* Put byte into fifo, start up master.
+	*/
+	sp->psc_smbtxrx = addr;
+	au_sync();
+	sp->psc_smbpcr = PSC_SMBPCR_MS;
+	au_sync();
+	if (wait_ack(adap))
+		return -EIO;
+	return 0;
+}
+
+static u32
+wait_for_rx_byte(struct i2c_au1550_data *adap, u32 *ret_data)
+{
+	int	j;
+	u32	data, stat;
+	volatile psc_smb_t	*sp;
+
+	if (wait_xfer_done(adap))
+		return -EIO;
+
+	sp = (volatile psc_smb_t *)(adap->psc_base);
+
+	j =  adap->xfer_timeout * 100;
+	do {
+		j--;
+		if (j <= 0)
+			return -EIO;
+
+		stat = sp->psc_smbstat;
+		au_sync();
+		if ((stat & PSC_SMBSTAT_RE) == 0)
+			j = 0;
+		else
+			udelay(1);
+	} while (j > 0);
+	data = sp->psc_smbtxrx;
+	au_sync();
+	*ret_data = data;
+
+	return 0;
+}
+
+static int
+i2c_read(struct i2c_au1550_data *adap, unsigned char *buf,
+		    unsigned int len)
+{
+	int	i;
+	u32	data;
+	volatile psc_smb_t	*sp;
+
+	if (len == 0)
+		return 0;
+
+	/* A read is performed by stuffing the transmit fifo with
+	 * zero bytes for timing, waiting for bytes to appear in the
+	 * receive fifo, then reading the bytes.
+	 */
+
+	sp = (volatile psc_smb_t *)(adap->psc_base);
+
+	i = 0;
+	while (i < (len-1)) {
+		sp->psc_smbtxrx = 0;
+		au_sync();
+		if (wait_for_rx_byte(adap, &data))
+			return -EIO;
+
+		buf[i] = data;
+		i++;
+	}
+
+	/* The last byte has to indicate transfer done.
+	*/
+	sp->psc_smbtxrx = PSC_SMBTXRX_STP;
+	au_sync();
+	if (wait_master_done(adap))
+		return -EIO;
+
+	data = sp->psc_smbtxrx;
+	au_sync();
+	buf[i] = data;
+	return 0;
+}
+
+static int
+i2c_write(struct i2c_au1550_data *adap, unsigned char *buf,
+		     unsigned int len)
+{
+	int	i;
+	u32	data;
+	volatile psc_smb_t	*sp;
+
+	if (len == 0)
+		return 0;
+
+	sp = (volatile psc_smb_t *)(adap->psc_base);
+
+	i = 0;
+	while (i < (len-1)) {
+		data = buf[i];
+		sp->psc_smbtxrx = data;
+		au_sync();
+		if (wait_ack(adap))
+			return -EIO;
+		i++;
+	}
+
+	/* The last byte has to indicate transfer done.
+	*/
+	data = buf[i];
+	data |= PSC_SMBTXRX_STP;
+	sp->psc_smbtxrx = data;
+	au_sync();
+	if (wait_master_done(adap))
+		return -EIO;
+	return 0;
+}
+
+static int
+au1550_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num)
+{
+	struct i2c_au1550_data *adap = i2c_adap->algo_data;
+	struct i2c_msg *p;
+	int i, err = 0;
+
+	for (i = 0; !err && i < num; i++) {
+		p = &msgs[i];
+		err = do_address(adap, p->addr, p->flags & I2C_M_RD);
+		if (err || !p->len)
+			continue;
+		if (p->flags & I2C_M_RD)
+			err = i2c_read(adap, p->buf, p->len);
+		else
+			err = i2c_write(adap, p->buf, p->len);
+	}
+
+	/* Return the number of messages processed, or the error code.
+	*/
+	if (err == 0)
+		err = num;
+	return err;
+}
+
+static u32
+au1550_func(struct i2c_adapter *adap)
+{
+	return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm au1550_algo = {
+	.name		= "Au1550 algorithm",
+	.id		= I2C_ALGO_AU1550,
+	.master_xfer	= au1550_xfer,
+	.functionality	= au1550_func,
+};
+
+/*
+ * registering functions to load algorithms at runtime
+ * Prior to calling us, the 50MHz clock frequency and routing
+ * must have been set up for the PSC indicated by the adapter.
+ */
+int
+i2c_au1550_add_bus(struct i2c_adapter *i2c_adap)
+{
+	struct i2c_au1550_data *adap = i2c_adap->algo_data;
+	volatile psc_smb_t	*sp;
+	u32	stat;
+
+	i2c_adap->algo = &au1550_algo;
+
+	/* Now, set up the PSC for SMBus PIO mode.
+	*/
+	sp = (volatile psc_smb_t *)(adap->psc_base);
+	sp->psc_ctrl = PSC_CTRL_DISABLE;
+	au_sync();
+	sp->psc_sel = PSC_SEL_PS_SMBUSMODE;
+	sp->psc_smbcfg = 0;
+	au_sync();
+	sp->psc_ctrl = PSC_CTRL_ENABLE;
+	au_sync();
+	do {
+		stat = sp->psc_smbstat;
+		au_sync();
+	} while ((stat & PSC_SMBSTAT_SR) == 0);
+
+	sp->psc_smbcfg = (PSC_SMBCFG_RT_FIFO8 | PSC_SMBCFG_TT_FIFO8 |
+				PSC_SMBCFG_DD_DISABLE);
+
+	/* Divide by 8 to get a 6.25 MHz clock.  The later protocol
+	 * timings are based on this clock.
+	 */
+	sp->psc_smbcfg |= PSC_SMBCFG_SET_DIV(PSC_SMBCFG_DIV8);
+	sp->psc_smbmsk = PSC_SMBMSK_ALLMASK;
+	au_sync();
+
+	/* Set the protocol timer values.  See Table 71 in the
+	 * Au1550 Data Book for standard timing values.
+	 */
+	sp->psc_smbtmr = PSC_SMBTMR_SET_TH(0) | PSC_SMBTMR_SET_PS(15) | \
+		PSC_SMBTMR_SET_PU(15) | PSC_SMBTMR_SET_SH(15) | \
+		PSC_SMBTMR_SET_SU(15) | PSC_SMBTMR_SET_CL(15) | \
+		PSC_SMBTMR_SET_CH(15);
+	au_sync();
+
+	sp->psc_smbcfg |= PSC_SMBCFG_DE_ENABLE;
+	do {
+		stat = sp->psc_smbstat;
+		au_sync();
+	} while ((stat & PSC_SMBSTAT_DR) == 0);
+
+	return i2c_add_adapter(i2c_adap);
+}
+
+
+int
+i2c_au1550_del_bus(struct i2c_adapter *adap)
+{
+	return i2c_del_adapter(adap);
+}
+
+static int
+pb1550_reg(struct i2c_client *client)
+{
+	return 0;
+}
+
+static int
+pb1550_unreg(struct i2c_client *client)
+{
+	return 0;
+}
+
+static struct i2c_au1550_data pb1550_i2c_info = {
+	SMBUS_PSC_BASE, 200, 200
+};
+
+static struct i2c_adapter pb1550_board_adapter = {
+	name:              "pb1550 adapter",
+	id:                I2C_HW_AU1550_PSC,
+	algo:              NULL,
+	algo_data:         &pb1550_i2c_info,
+	client_register:   pb1550_reg,
+	client_unregister: pb1550_unreg,
+};
+
+/* BIG hack to support the control interface on the Wolfson WM8731
+ * audio codec on the Pb1550 board.  We get an address and two data
+ * bytes to write, create an i2c message, and send it across the
+ * i2c transfer function.  We do this here because we have access to
+ * the i2c adapter structure.
+ */
+static struct i2c_msg wm_i2c_msg;  /* We don't want this stuff on the stack */
+static	u8 i2cbuf[2];
+
+int
+pb1550_wm_codec_write(u8 addr, u8 reg, u8 val)
+{
+	wm_i2c_msg.addr = addr;
+	wm_i2c_msg.flags = 0;
+	wm_i2c_msg.buf = i2cbuf;
+	wm_i2c_msg.len = 2;
+	i2cbuf[0] = reg;
+	i2cbuf[1] = val;
+
+	return pb1550_board_adapter.algo->master_xfer(&pb1550_board_adapter, &wm_i2c_msg, 1);
+}
+
+static int __init
+i2c_au1550_init(void)
+{
+	printk(KERN_INFO "Au1550 I2C: ");
+
+	/* This is where we would set up a 50MHz clock source
+	 * and routing.  On the Pb1550, the SMBus is PSC2, which
+	 * uses a shared clock with USB.  This has been already
+	 * configured by Yamon as a 48MHz clock, close enough
+	 * for our work.
+	 */
+        if (i2c_au1550_add_bus(&pb1550_board_adapter) < 0) {
+		printk("failed to initialize.\n");
+                return -ENODEV;
+	}
+
+	printk("initialized.\n");
+	return 0;
+}
+
+static void __exit
+i2c_au1550_exit(void)
+{
+	i2c_au1550_del_bus(&pb1550_board_adapter);
+}
+
+MODULE_AUTHOR("Dan Malek, Embedded Edge, LLC.");
+MODULE_DESCRIPTION("SMBus adapter Alchemy pb1550");
+MODULE_LICENSE("GPL");
+
+module_init (i2c_au1550_init);
+module_exit (i2c_au1550_exit);
diff -Nru a/drivers/i2c/busses/i2c-au1550.h b/drivers/i2c/busses/i2c-au1550.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/i2c/busses/i2c-au1550.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2004 Embedded Edge, LLC <dan@embeddededge.com>
+ * 2.6 port by Matt Porter <mporter@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.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef I2C_AU1550_H
+#define I2C_AU1550_H
+
+struct i2c_au1550_data {
+	u32	psc_base;
+	int	xfer_timeout;
+	int	ack_timeout;
+};
+
+int i2c_au1550_add_bus(struct i2c_adapter *);
+int i2c_au1550_del_bus(struct i2c_adapter *);
+
+#endif /* I2C_AU1550_H */
diff -Nru a/drivers/i2c/busses/i2c-hydra.c b/drivers/i2c/busses/i2c-hydra.c
--- a/drivers/i2c/busses/i2c-hydra.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/i2c/busses/i2c-hydra.c	2005-03-01 23:38:55 -08:00
@@ -111,12 +111,7 @@
 };
 
 static struct pci_device_id hydra_ids[] = {
-	{
-		.vendor		= PCI_VENDOR_ID_APPLE,
-		.device		= PCI_DEVICE_ID_APPLE_HYDRA,
-		.subvendor	= PCI_ANY_ID,
-		.subdevice	= PCI_ANY_ID,
-	},
+	{ PCI_DEVICE(PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_HYDRA) },
 	{ 0, }
 };
 
diff -Nru a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
--- a/drivers/i2c/busses/i2c-i801.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/i2c/busses/i2c-i801.c	2005-03-01 23:38:57 -08:00
@@ -30,6 +30,7 @@
     82801EB		24D3   (HW PEC supported, 32 byte buffer not supported)
     6300ESB		25A4
     ICH6		266A
+    ICH7		27DA
     This driver supports several versions of Intel's I/O Controller Hubs (ICH).
     For SMBus support, they are similar to the PIIX4 and are part
     of Intel's '810' and other chipsets.
@@ -548,54 +549,15 @@
 };
 
 static struct pci_device_id i801_ids[] = {
-	{
-		.vendor =	PCI_VENDOR_ID_INTEL,
-		.device =	PCI_DEVICE_ID_INTEL_82801AA_3,
-		.subvendor =	PCI_ANY_ID,
-		.subdevice =	PCI_ANY_ID,
-	},
-	{
-		.vendor =	PCI_VENDOR_ID_INTEL,
-		.device =	PCI_DEVICE_ID_INTEL_82801AB_3,
-		.subvendor =	PCI_ANY_ID,
-		.subdevice =	PCI_ANY_ID,
-	},
-	{
-		.vendor =	PCI_VENDOR_ID_INTEL,
-		.device =	PCI_DEVICE_ID_INTEL_82801BA_2,
-		.subvendor =	PCI_ANY_ID,
-		.subdevice =	PCI_ANY_ID,
-	},
-	{
-		.vendor =	PCI_VENDOR_ID_INTEL,
-		.device =	PCI_DEVICE_ID_INTEL_82801CA_3,
-		.subvendor =	PCI_ANY_ID,
-		.subdevice =	PCI_ANY_ID,
-	},
-	{
-		.vendor =	PCI_VENDOR_ID_INTEL,
-		.device =	PCI_DEVICE_ID_INTEL_82801DB_3,
-		.subvendor =	PCI_ANY_ID,
-		.subdevice =	PCI_ANY_ID,
-	},
-	{
-		.vendor =	PCI_VENDOR_ID_INTEL,
-		.device =	PCI_DEVICE_ID_INTEL_82801EB_3,
-		.subvendor =	PCI_ANY_ID,
-		.subdevice =	PCI_ANY_ID,
-	},
-	{
-		.vendor =	PCI_VENDOR_ID_INTEL,
-		.device =	PCI_DEVICE_ID_INTEL_ESB_4,
-		.subvendor =	PCI_ANY_ID,
-		.subdevice = 	PCI_ANY_ID,
-	},
-	{
-		.vendor =	PCI_VENDOR_ID_INTEL,
-		.device =	PCI_DEVICE_ID_INTEL_ICH6_16,
-		.subvendor =	PCI_ANY_ID,
-		.subdevice =	PCI_ANY_ID,
-	},
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_3) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_3) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_2) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_3) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_3) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_3) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_4) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_16) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_17) },
 	{ 0, }
 };
 
diff -Nru a/drivers/i2c/busses/i2c-iop3xx.c b/drivers/i2c/busses/i2c-iop3xx.c
--- a/drivers/i2c/busses/i2c-iop3xx.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/i2c/busses/i2c-iop3xx.c	2005-03-01 23:38:58 -08:00
@@ -1,35 +1,30 @@
 /* ------------------------------------------------------------------------- */
-/* i2c-iop3xx.c i2c driver algorithms for Intel XScale IOP3xx                */
+/* i2c-iop3xx.c i2c driver algorithms for Intel XScale IOP3xx & IXP46x       */
 /* ------------------------------------------------------------------------- */
-/*   Copyright (C) 2003 Peter Milne, D-TACQ Solutions Ltd
- *                      <Peter dot Milne at D hyphen TACQ dot 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 program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You 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.                */
-/* ------------------------------------------------------------------------- */
-/*
-   With acknowledgements to i2c-algo-ibm_ocp.c by 
-   Ian DaSilva, MontaVista Software, Inc. idasilva@mvista.com
-
-   And i2c-algo-pcf.c, which was created by Simon G. Vogl and Hans Berglund:
-
-     Copyright (C) 1995-1997 Simon G. Vogl, 1998-2000 Hans Berglund
-   
-   And which acknowledged Kyösti Mälkki <kmalkki@cc.hut.fi>,
-   Frodo Looijaard <frodol@dds.nl>, Martin Bailey<mbailey@littlefeet-inc.com>
-
-  ---------------------------------------------------------------------------*/
+/* Copyright (C) 2003 Peter Milne, D-TACQ Solutions Ltd
+ *                    <Peter dot Milne at D hyphen TACQ dot com>
+ *
+ * With acknowledgements to i2c-algo-ibm_ocp.c by 
+ * Ian DaSilva, MontaVista Software, Inc. idasilva@mvista.com
+ *
+ * And i2c-algo-pcf.c, which was created by Simon G. Vogl and Hans Berglund:
+ *
+ * Copyright (C) 1995-1997 Simon G. Vogl, 1998-2000 Hans Berglund
+ *  
+ * And which acknowledged Kyösti Mälkki <kmalkki@cc.hut.fi>,
+ * Frodo Looijaard <frodol@dds.nl>, Martin Bailey<mbailey@littlefeet-inc.com>
+ *
+ * Major cleanup by Deepak Saxena <dsaxena@plexity.net>, 01/2005:
+ *
+ * - Use driver model to pass per-chip info instead of hardcoding and #ifdefs
+ * - Use ioremap/__raw_readl/__raw_writel instead of direct dereference
+ * - Make it work with IXP46x chips
+ * - Cleanup function names, coding style, etc
+ *
+ * This program is free software; 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.
+ */
 
 #include <linux/config.h>
 #include <linux/interrupt.h>
@@ -40,24 +35,18 @@
 #include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/sched.h>
+#include <linux/device.h>
 #include <linux/i2c.h>
 
+#include <asm/io.h>
 
-#include <asm/arch-iop3xx/iop321.h>
-#include <asm/arch-iop3xx/iop321-irqs.h>
 #include "i2c-iop3xx.h"
 
+/* global unit counter */
+static int i2c_id = 0;
 
-/* ----- global defines ----------------------------------------------- */
-#define PASSERT(x) do { if (!(x) ) \
-		printk(KERN_CRIT "PASSERT %s in %s:%d\n", #x, __FILE__, __LINE__ );\
-	} while (0)
-
-
-/* ----- global variables ---------------------------------------------	*/
-
-
-static inline unsigned char iic_cook_addr(struct i2c_msg *msg) 
+static inline unsigned char 
+iic_cook_addr(struct i2c_msg *msg) 
 {
 	unsigned char addr;
 
@@ -66,103 +55,110 @@
 	if (msg->flags & I2C_M_RD)
 		addr |= 1;
 
-	/* PGM: what is M_REV_DIR_ADDR - do we need it ?? */
+	/*
+	 * Read or Write?
+	 */
 	if (msg->flags & I2C_M_REV_DIR_ADDR)
 		addr ^= 1;
 
 	return addr;   
 }
 
-
-static inline void iop3xx_adap_reset(struct i2c_algo_iop3xx_data *iop3xx_adap)
+static void 
+iop3xx_i2c_reset(struct i2c_algo_iop3xx_data *iop3xx_adap)
 {
 	/* Follows devman 9.3 */
-	*iop3xx_adap->biu->CR = IOP321_ICR_UNIT_RESET;
-	*iop3xx_adap->biu->SR = IOP321_ISR_CLEARBITS;
-	*iop3xx_adap->biu->CR = 0;
+	__raw_writel(IOP3XX_ICR_UNIT_RESET, iop3xx_adap->ioaddr + CR_OFFSET);
+	__raw_writel(IOP3XX_ISR_CLEARBITS, iop3xx_adap->ioaddr + SR_OFFSET);
+	__raw_writel(0, iop3xx_adap->ioaddr + CR_OFFSET);
 } 
 
-static inline void iop3xx_adap_set_slave_addr(struct i2c_algo_iop3xx_data *iop3xx_adap)
+static void 
+iop3xx_i2c_set_slave_addr(struct i2c_algo_iop3xx_data *iop3xx_adap)
 {
-	*iop3xx_adap->biu->SAR = MYSAR;
+	__raw_writel(MYSAR, iop3xx_adap->ioaddr + SAR_OFFSET);
 }
 
-static inline void iop3xx_adap_enable(struct i2c_algo_iop3xx_data *iop3xx_adap)
+static void 
+iop3xx_i2c_enable(struct i2c_algo_iop3xx_data *iop3xx_adap)
 {
-	u32 cr = IOP321_ICR_GCD|IOP321_ICR_SCLEN|IOP321_ICR_UE;
+	u32 cr = IOP3XX_ICR_GCD | IOP3XX_ICR_SCLEN | IOP3XX_ICR_UE;
 
+	/* 
+	 * Everytime unit enable is asserted, GPOD needs to be cleared
+	 * on IOP321 to avoid data corruption on the bus.
+	 */
+#ifdef CONFIG_ARCH_IOP321
+#define IOP321_GPOD_I2C0    0x00c0  /* clear these bits to enable ch0 */
+#define IOP321_GPOD_I2C1    0x0030  /* clear these bits to enable ch1 */
+
+	*IOP321_GPOD &= (iop3xx_adap->id == 0) ? ~IOP321_GPOD_I2C0 : 
+		~IOP321_GPOD_I2C1;
+#endif
 	/* NB SR bits not same position as CR IE bits :-( */
-	iop3xx_adap->biu->SR_enabled = 
-		IOP321_ISR_ALD | IOP321_ISR_BERRD |
-		IOP321_ISR_RXFULL | IOP321_ISR_TXEMPTY;
+	iop3xx_adap->SR_enabled = 
+		IOP3XX_ISR_ALD | IOP3XX_ISR_BERRD |
+		IOP3XX_ISR_RXFULL | IOP3XX_ISR_TXEMPTY;
 
-	cr |= IOP321_ICR_ALDIE | IOP321_ICR_BERRIE |
-		IOP321_ICR_RXFULLIE | IOP321_ICR_TXEMPTYIE;
+	cr |= IOP3XX_ICR_ALD_IE | IOP3XX_ICR_BERR_IE |
+		IOP3XX_ICR_RXFULL_IE | IOP3XX_ICR_TXEMPTY_IE;
 
-	*iop3xx_adap->biu->CR = cr;
+	__raw_writel(cr, iop3xx_adap->ioaddr + CR_OFFSET);
 }
 
-static void iop3xx_adap_transaction_cleanup(struct i2c_algo_iop3xx_data *iop3xx_adap)
+static void 
+iop3xx_i2c_transaction_cleanup(struct i2c_algo_iop3xx_data *iop3xx_adap)
 {
-	unsigned cr = *iop3xx_adap->biu->CR;
+	unsigned long cr = __raw_readl(iop3xx_adap->ioaddr + CR_OFFSET);
 	
-	cr &= ~(IOP321_ICR_MSTART | IOP321_ICR_TBYTE | 
-		IOP321_ICR_MSTOP | IOP321_ICR_SCLEN);
-	*iop3xx_adap->biu->CR = cr;
-}
+	cr &= ~(IOP3XX_ICR_MSTART | IOP3XX_ICR_TBYTE | 
+		IOP3XX_ICR_MSTOP | IOP3XX_ICR_SCLEN);
 
-static void iop3xx_adap_final_cleanup(struct i2c_algo_iop3xx_data *iop3xx_adap)
-{
-	unsigned cr = *iop3xx_adap->biu->CR;
-	
-	cr &= ~(IOP321_ICR_ALDIE | IOP321_ICR_BERRIE |
-		IOP321_ICR_RXFULLIE | IOP321_ICR_TXEMPTYIE);
-	iop3xx_adap->biu->SR_enabled = 0;
-	*iop3xx_adap->biu->CR = cr;
+	__raw_writel(cr, iop3xx_adap->ioaddr + CR_OFFSET);
 }
 
 /* 
  * NB: the handler has to clear the source of the interrupt! 
  * Then it passes the SR flags of interest to BH via adap data
  */
-static irqreturn_t iop3xx_i2c_handler(int this_irq, 
-				void *dev_id, 
-				struct pt_regs *regs) 
+static irqreturn_t 
+iop3xx_i2c_irq_handler(int this_irq, void *dev_id, struct pt_regs *regs) 
 {
 	struct i2c_algo_iop3xx_data *iop3xx_adap = dev_id;
+	u32 sr = __raw_readl(iop3xx_adap->ioaddr + SR_OFFSET);
 
-	u32 sr = *iop3xx_adap->biu->SR;
-
-	if ((sr &= iop3xx_adap->biu->SR_enabled)) {
-		*iop3xx_adap->biu->SR = sr;
-		iop3xx_adap->biu->SR_received |= sr;
+	if ((sr &= iop3xx_adap->SR_enabled)) {
+		__raw_writel(sr, iop3xx_adap->ioaddr + SR_OFFSET);
+		iop3xx_adap->SR_received |= sr;
 		wake_up_interruptible(&iop3xx_adap->waitq);
 	}
 	return IRQ_HANDLED;
 }
 
 /* check all error conditions, clear them , report most important */
-static int iop3xx_adap_error(u32 sr)
+static int 
+iop3xx_i2c_error(u32 sr)
 {
 	int rc = 0;
 
-	if ((sr&IOP321_ISR_BERRD)) {
+	if ((sr & IOP3XX_ISR_BERRD)) {
 		if ( !rc ) rc = -I2C_ERR_BERR;
 	}
-	if ((sr&IOP321_ISR_ALD)) {
+	if ((sr & IOP3XX_ISR_ALD)) {
 		if ( !rc ) rc = -I2C_ERR_ALD;		
 	}
 	return rc;	
 }
 
-static inline u32 get_srstat(struct i2c_algo_iop3xx_data *iop3xx_adap)
+static inline u32 
+iop3xx_i2c_get_srstat(struct i2c_algo_iop3xx_data *iop3xx_adap)
 {
 	unsigned long flags;
 	u32 sr;
 
 	spin_lock_irqsave(&iop3xx_adap->lock, flags);
-	sr = iop3xx_adap->biu->SR_received;
-	iop3xx_adap->biu->SR_received = 0;
+	sr = iop3xx_adap->SR_received;
+	iop3xx_adap->SR_received = 0;
 	spin_unlock_irqrestore(&iop3xx_adap->lock, flags);
 
 	return sr;
@@ -175,9 +171,10 @@
 typedef int (* compare_func)(unsigned test, unsigned mask);
 /* returns 1 on correct comparison */
 
-static int iop3xx_adap_wait_event(struct i2c_algo_iop3xx_data *iop3xx_adap, 
-				  unsigned flags, unsigned* status,
-				  compare_func compare)
+static int 
+iop3xx_i2c_wait_event(struct i2c_algo_iop3xx_data *iop3xx_adap, 
+			  unsigned flags, unsigned* status,
+			  compare_func compare)
 {
 	unsigned sr = 0;
 	int interrupted;
@@ -187,13 +184,13 @@
 	do {
 		interrupted = wait_event_interruptible_timeout (
 			iop3xx_adap->waitq,
-			(done = compare( sr = get_srstat(iop3xx_adap),flags )),
-			iop3xx_adap->timeout
+			(done = compare( sr = iop3xx_i2c_get_srstat(iop3xx_adap)					,flags )),
+			1 * HZ;
 			);
-		if ((rc = iop3xx_adap_error(sr)) < 0) {
+		if ((rc = iop3xx_i2c_error(sr)) < 0) {
 			*status = sr;
 			return rc;
-		}else if (!interrupted) {
+		} else if (!interrupted) {
 			*status = sr;
 			return -ETIMEDOUT;
 		}
@@ -207,141 +204,131 @@
 /*
  * Concrete compare_funcs 
  */
-static int all_bits_clear(unsigned test, unsigned mask)
+static int 
+all_bits_clear(unsigned test, unsigned mask)
 {
 	return (test & mask) == 0;
 }
-static int any_bits_set(unsigned test, unsigned mask)
+
+static int 
+any_bits_set(unsigned test, unsigned mask)
 {
 	return (test & mask) != 0;
 }
 
-static int iop3xx_adap_wait_tx_done(struct i2c_algo_iop3xx_data *iop3xx_adap, int *status)
+static int 
+iop3xx_i2c_wait_tx_done(struct i2c_algo_iop3xx_data *iop3xx_adap, int *status)
 {
-	return iop3xx_adap_wait_event( 
+	return iop3xx_i2c_wait_event( 
 		iop3xx_adap, 
-	        IOP321_ISR_TXEMPTY|IOP321_ISR_ALD|IOP321_ISR_BERRD,
+	        IOP3XX_ISR_TXEMPTY | IOP3XX_ISR_ALD | IOP3XX_ISR_BERRD,
 		status, any_bits_set);
 }
 
-static int iop3xx_adap_wait_rx_done(struct i2c_algo_iop3xx_data *iop3xx_adap, int *status)
+static int 
+iop3xx_i2c_wait_rx_done(struct i2c_algo_iop3xx_data *iop3xx_adap, int *status)
 {
-	return iop3xx_adap_wait_event( 
+	return iop3xx_i2c_wait_event( 
 		iop3xx_adap, 
-		IOP321_ISR_RXFULL|IOP321_ISR_ALD|IOP321_ISR_BERRD,
+		IOP3XX_ISR_RXFULL | IOP3XX_ISR_ALD | IOP3XX_ISR_BERRD,
 		status,	any_bits_set);
 }
 
-static int iop3xx_adap_wait_idle(struct i2c_algo_iop3xx_data *iop3xx_adap, int *status)
-{
-	return iop3xx_adap_wait_event( 
-		iop3xx_adap, IOP321_ISR_UNITBUSY, status, all_bits_clear);
-}
-
-/*
- * Description: This performs the IOP3xx initialization sequence
- * Valid for IOP321. Maybe valid for IOP310?.
- */
-static int iop3xx_adap_init (struct i2c_algo_iop3xx_data *iop3xx_adap)
+static int 
+iop3xx_i2c_wait_idle(struct i2c_algo_iop3xx_data *iop3xx_adap, int *status)
 {
-	*IOP321_GPOD &= ~(iop3xx_adap->channel==0 ?
-			  IOP321_GPOD_I2C0:
-			  IOP321_GPOD_I2C1);
-
-	iop3xx_adap_reset(iop3xx_adap);
-	iop3xx_adap_set_slave_addr(iop3xx_adap);
-	iop3xx_adap_enable(iop3xx_adap);
-	
-        return 0;
+	return iop3xx_i2c_wait_event( 
+		iop3xx_adap, IOP3XX_ISR_UNITBUSY, status, all_bits_clear);
 }
 
-static int iop3xx_adap_send_target_slave_addr(struct i2c_algo_iop3xx_data *iop3xx_adap,
-					      struct i2c_msg* msg)
+static int 
+iop3xx_i2c_send_target_addr(struct i2c_algo_iop3xx_data *iop3xx_adap, 
+				struct i2c_msg* msg)
 {
-	unsigned cr = *iop3xx_adap->biu->CR;
+	unsigned long cr = __raw_readl(iop3xx_adap->ioaddr + CR_OFFSET);
 	int status;
 	int rc;
 
-	*iop3xx_adap->biu->DBR = iic_cook_addr(msg);
+	__raw_writel(iic_cook_addr(msg), iop3xx_adap->ioaddr + DBR_OFFSET);
 	
-	cr &= ~(IOP321_ICR_MSTOP | IOP321_ICR_NACK);
-	cr |= IOP321_ICR_MSTART | IOP321_ICR_TBYTE;
+	cr &= ~(IOP3XX_ICR_MSTOP | IOP3XX_ICR_NACK);
+	cr |= IOP3XX_ICR_MSTART | IOP3XX_ICR_TBYTE;
+
+	__raw_writel(cr, iop3xx_adap->ioaddr + CR_OFFSET);
+	rc = iop3xx_i2c_wait_tx_done(iop3xx_adap, &status);
 
-	*iop3xx_adap->biu->CR = cr;
-	rc = iop3xx_adap_wait_tx_done(iop3xx_adap, &status);
-	/* this assert fires every time, contrary to IOP manual	
-	PASSERT((status&IOP321_ISR_UNITBUSY)!=0);
-	*/
-	PASSERT((status&IOP321_ISR_RXREAD)==0);
-	     
 	return rc;
 }
 
-static int iop3xx_adap_write_byte(struct i2c_algo_iop3xx_data *iop3xx_adap, char byte, int stop)
+static int 
+iop3xx_i2c_write_byte(struct i2c_algo_iop3xx_data *iop3xx_adap, char byte, 
+				int stop)
 {
-	unsigned cr = *iop3xx_adap->biu->CR;
+	unsigned long cr = __raw_readl(iop3xx_adap->ioaddr + CR_OFFSET);
 	int status;
 	int rc = 0;
 
-	*iop3xx_adap->biu->DBR = byte;
-	cr &= ~IOP321_ICR_MSTART;
+	__raw_writel(byte, iop3xx_adap->ioaddr + DBR_OFFSET);
+	cr &= ~IOP3XX_ICR_MSTART;
 	if (stop) {
-		cr |= IOP321_ICR_MSTOP;
+		cr |= IOP3XX_ICR_MSTOP;
 	} else {
-		cr &= ~IOP321_ICR_MSTOP;
+		cr &= ~IOP3XX_ICR_MSTOP;
 	}
-	*iop3xx_adap->biu->CR = cr |= IOP321_ICR_TBYTE;
-	rc = iop3xx_adap_wait_tx_done(iop3xx_adap, &status);
+	cr |= IOP3XX_ICR_TBYTE;
+	__raw_writel(cr, iop3xx_adap->ioaddr + CR_OFFSET);
+	rc = iop3xx_i2c_wait_tx_done(iop3xx_adap, &status);
 
 	return rc;
 } 
 
-static int iop3xx_adap_read_byte(struct i2c_algo_iop3xx_data *iop3xx_adap,
-				 char* byte, int stop)
+static int 
+iop3xx_i2c_read_byte(struct i2c_algo_iop3xx_data *iop3xx_adap, char* byte, 
+				int stop)
 {
-	unsigned cr = *iop3xx_adap->biu->CR;
+	unsigned long cr = __raw_readl(iop3xx_adap->ioaddr + CR_OFFSET);
 	int status;
 	int rc = 0;
 
-	cr &= ~IOP321_ICR_MSTART;
+	cr &= ~IOP3XX_ICR_MSTART;
 
 	if (stop) {
-		cr |= IOP321_ICR_MSTOP|IOP321_ICR_NACK;
+		cr |= IOP3XX_ICR_MSTOP | IOP3XX_ICR_NACK;
 	} else {
-		cr &= ~(IOP321_ICR_MSTOP|IOP321_ICR_NACK);
+		cr &= ~(IOP3XX_ICR_MSTOP | IOP3XX_ICR_NACK);
 	}
-	*iop3xx_adap->biu->CR = cr |= IOP321_ICR_TBYTE;
+	cr |= IOP3XX_ICR_TBYTE;
+	__raw_writel(cr, iop3xx_adap->ioaddr + CR_OFFSET);
 
-	rc = iop3xx_adap_wait_rx_done(iop3xx_adap, &status);
+	rc = iop3xx_i2c_wait_rx_done(iop3xx_adap, &status);
 
-	*byte = *iop3xx_adap->biu->DBR;
+	*byte = __raw_readl(iop3xx_adap->ioaddr + DBR_OFFSET);
 
 	return rc;
 }
 
-static int iop3xx_i2c_writebytes(struct i2c_adapter *i2c_adap, 
-				 const char *buf, int count)
+static int 
+iop3xx_i2c_writebytes(struct i2c_adapter *i2c_adap, const char *buf, int count)
 {
 	struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data;
 	int ii;
 	int rc = 0;
 
-	for (ii = 0; rc == 0 && ii != count; ++ii) {
-		rc = iop3xx_adap_write_byte(iop3xx_adap, buf[ii], ii==count-1);
-	}
+	for (ii = 0; rc == 0 && ii != count; ++ii) 
+		rc = iop3xx_i2c_write_byte(iop3xx_adap, buf[ii], ii==count-1);
 	return rc;
 }
 
-static int iop3xx_i2c_readbytes(struct i2c_adapter *i2c_adap, 
-				char *buf, int count)
+static int 
+iop3xx_i2c_readbytes(struct i2c_adapter *i2c_adap, char *buf, int count)
 {
 	struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data;
 	int ii;
 	int rc = 0;
 
-	for (ii = 0; rc == 0 && ii != count; ++ii) {
-		rc = iop3xx_adap_read_byte(iop3xx_adap, &buf[ii], ii==count-1);
-	}
+	for (ii = 0; rc == 0 && ii != count; ++ii)
+		rc = iop3xx_i2c_read_byte(iop3xx_adap, &buf[ii], ii==count-1);
+	
 	return rc;
 }
 
@@ -352,12 +339,13 @@
  * Each transfer (i.e. a read or a write) is separated by a repeated start
  * condition.
  */
-static int iop3xx_handle_msg(struct i2c_adapter *i2c_adap, struct i2c_msg* pmsg) 
+static int 
+iop3xx_i2c_handle_msg(struct i2c_adapter *i2c_adap, struct i2c_msg* pmsg) 
 {
 	struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data;
 	int rc;
 
-	rc = iop3xx_adap_send_target_slave_addr(iop3xx_adap, pmsg);
+	rc = iop3xx_i2c_send_target_addr(iop3xx_adap, pmsg);
 	if (rc < 0) {
 		return rc;
 	}
@@ -372,22 +360,24 @@
 /*
  * master_xfer() - main read/write entry
  */
-static int iop3xx_master_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num)
+static int 
+iop3xx_i2c_master_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], 
+				int num)
 {
 	struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data;
 	int im = 0;
 	int ret = 0;
 	int status;
 
-	iop3xx_adap_wait_idle(iop3xx_adap, &status);
-	iop3xx_adap_reset(iop3xx_adap);
-	iop3xx_adap_enable(iop3xx_adap);
+	iop3xx_i2c_wait_idle(iop3xx_adap, &status);
+	iop3xx_i2c_reset(iop3xx_adap);
+	iop3xx_i2c_enable(iop3xx_adap);
 
 	for (im = 0; ret == 0 && im != num; im++) {
-		ret = iop3xx_handle_msg(i2c_adap, &msgs[im]);
+		ret = iop3xx_i2c_handle_msg(i2c_adap, &msgs[im]);
 	}
 
-	iop3xx_adap_transaction_cleanup(iop3xx_adap);
+	iop3xx_i2c_transaction_cleanup(iop3xx_adap);
 	
 	if(ret)
 		return ret;
@@ -395,136 +385,165 @@
 	return im;   
 }
 
-static int algo_control(struct i2c_adapter *adapter, unsigned int cmd,
+static int 
+iop3xx_i2c_algo_control(struct i2c_adapter *adapter, unsigned int cmd,
 			unsigned long arg)
 {
 	return 0;
 }
 
-static u32 iic_func(struct i2c_adapter *adap)
+static u32 
+iop3xx_i2c_func(struct i2c_adapter *adap)
 {
 	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
 }
 
-
-/* -----exported algorithm data: -------------------------------------	*/
-
-static struct i2c_algorithm iic_algo = {
+static struct i2c_algorithm iop3xx_i2c_algo = {
 	.name		= "IOP3xx I2C algorithm",
-	.id		= I2C_ALGO_OCP_IOP3XX,
-	.master_xfer	= iop3xx_master_xfer,
-	.algo_control	= algo_control,
-	.functionality	= iic_func,
+	.id		= I2C_ALGO_IOP3XX,
+	.master_xfer	= iop3xx_i2c_master_xfer,
+	.algo_control	= iop3xx_i2c_algo_control,
+	.functionality	= iop3xx_i2c_func,
 };
 
-/* 
- * registering functions to load algorithms at runtime 
- */
-static int i2c_iop3xx_add_bus(struct i2c_adapter *iic_adap)
+static int 
+iop3xx_i2c_remove(struct device *device)
+{
+	struct platform_device *pdev = to_platform_device(device);
+	struct i2c_adapter *padapter = dev_get_drvdata(&pdev->dev);
+	struct i2c_algo_iop3xx_data *adapter_data = 
+		(struct i2c_algo_iop3xx_data *)padapter->algo_data;
+	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	unsigned long cr = __raw_readl(adapter_data->ioaddr + CR_OFFSET);
+
+	/*
+	 * Disable the actual HW unit
+	 */
+	cr &= ~(IOP3XX_ICR_ALD_IE | IOP3XX_ICR_BERR_IE |
+		IOP3XX_ICR_RXFULL_IE | IOP3XX_ICR_TXEMPTY_IE);
+	__raw_writel(cr, adapter_data->ioaddr + CR_OFFSET);
+
+	iounmap((void __iomem*)adapter_data->ioaddr);
+	release_mem_region(res->start, IOP3XX_I2C_IO_SIZE);
+	kfree(adapter_data);
+	kfree(padapter);
+
+	dev_set_drvdata(&pdev->dev, NULL);
+
+	return 0;
+}
+
+static int 
+iop3xx_i2c_probe(struct device *dev)
 {
-	struct i2c_algo_iop3xx_data *iop3xx_adap = iic_adap->algo_data;
+	struct platform_device *pdev = to_platform_device(dev);
+	struct resource *res;
+	int ret;
+	struct i2c_adapter *new_adapter;
+	struct i2c_algo_iop3xx_data *adapter_data;
 
-	if (!request_region( REGION_START(iop3xx_adap), 
-			      REGION_LENGTH(iop3xx_adap),
-			      iic_adap->name)) {
-		return -ENODEV;
+	new_adapter = kmalloc(sizeof(struct i2c_adapter), GFP_KERNEL);
+	if (!new_adapter) {
+		ret = -ENOMEM;
+		goto out;
 	}
+	memset((void*)new_adapter, 0, sizeof(*new_adapter));
 
-	init_waitqueue_head(&iop3xx_adap->waitq);
-	spin_lock_init(&iop3xx_adap->lock);
+	adapter_data = kmalloc(sizeof(struct i2c_algo_iop3xx_data), GFP_KERNEL);
+	if (!adapter_data) {
+		ret = -ENOMEM;
+		goto free_adapter;
+	}
+	memset((void*)adapter_data, 0, sizeof(*adapter_data));
 
-	if (request_irq( 
-		     iop3xx_adap->biu->irq,
-		     iop3xx_i2c_handler,
-		     /* SA_SAMPLE_RANDOM */ 0,
-		     iic_adap->name,
-		     iop3xx_adap)) {
-		return -ENODEV;
-	}			  
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		ret = -ENODEV;
+		goto free_both;
+	}
 
-	/* register new iic_adapter to i2c module... */
-	iic_adap->id |= iic_algo.id;
-	iic_adap->algo = &iic_algo;
+	if (!request_mem_region(res->start, IOP3XX_I2C_IO_SIZE, pdev->name)) {
+		ret = -EBUSY;
+		goto free_both;
+	}
 
-	iic_adap->timeout = 100;	/* default values, should */
-	iic_adap->retries = 3;		/* be replaced by defines */
+	/* set the adapter enumeration # */
+	adapter_data->id = i2c_id++;
 
-	iop3xx_adap_init(iic_adap->algo_data);
-	i2c_add_adapter(iic_adap);
-	return 0;
-}
+	adapter_data->ioaddr = (u32)ioremap(res->start, IOP3XX_I2C_IO_SIZE);
+	if (!adapter_data->ioaddr) {
+		ret = -ENOMEM;
+		goto release_region;
+	}
 
-static int i2c_iop3xx_del_bus(struct i2c_adapter *iic_adap)
-{
-	struct i2c_algo_iop3xx_data *iop3xx_adap = iic_adap->algo_data;
+	res = request_irq(platform_get_irq(pdev, 0), iop3xx_i2c_irq_handler, 0, 
+				pdev->name, adapter_data);
+	if (res) {
+		ret = -EIO;
+		goto unmap;
+	}
 
-	iop3xx_adap_final_cleanup(iop3xx_adap);
-	free_irq(iop3xx_adap->biu->irq, iop3xx_adap);
+	memcpy(new_adapter->name, pdev->name, strlen(pdev->name));
+	new_adapter->id = I2C_HW_IOP3XX;
+	new_adapter->owner = THIS_MODULE;
+	new_adapter->dev.parent = &pdev->dev;
 
-	release_region(REGION_START(iop3xx_adap), REGION_LENGTH(iop3xx_adap));
+	/*
+	 * Default values...should these come in from board code?
+	 */
+	new_adapter->timeout = 100;	
+	new_adapter->retries = 3;
+	new_adapter->algo = &iop3xx_i2c_algo;
 
-	return i2c_del_adapter(iic_adap);
-}
+	init_waitqueue_head(&adapter_data->waitq);
+	spin_lock_init(&adapter_data->lock);
 
-#ifdef CONFIG_ARCH_IOP321
+	iop3xx_i2c_reset(adapter_data);
+	iop3xx_i2c_set_slave_addr(adapter_data);
+	iop3xx_i2c_enable(adapter_data);
 
-static struct iop3xx_biu biu0 = {
-	.CR	= IOP321_ICR0,
-	.SR	= IOP321_ISR0,
-	.SAR	= IOP321_ISAR0,
-	.DBR	= IOP321_IDBR0,
-	.BMR	= IOP321_IBMR0,
-	.irq	= IRQ_IOP321_I2C_0,
-};
+	dev_set_drvdata(&pdev->dev, new_adapter);
+	new_adapter->algo_data = adapter_data;
 
-static struct iop3xx_biu biu1 = {
-	.CR	= IOP321_ICR1,
-	.SR	= IOP321_ISR1,
-	.SAR	= IOP321_ISAR1,
-	.DBR	= IOP321_IDBR1,
-	.BMR	= IOP321_IBMR1,
-	.irq	= IRQ_IOP321_I2C_1,
-};
+	i2c_add_adapter(new_adapter);
 
-#define ADAPTER_NAME_ROOT "IOP321 i2c biu adapter "
-#else
-#error Please define the BIU struct iop3xx_biu for your processor arch
-#endif
+	return 0;
 
-static struct i2c_algo_iop3xx_data algo_iop3xx_data0 = {
-	.channel		= 0,
-	.biu			= &biu0,
-	.timeout		= 1*HZ,
-};
-static struct i2c_algo_iop3xx_data algo_iop3xx_data1 = {
-	.channel		= 1,
-	.biu			= &biu1,
-	.timeout		= 1*HZ,
-};
+unmap:
+	iounmap((void __iomem*)adapter_data->ioaddr);
 
-static struct i2c_adapter iop3xx_ops0 = {
-	.owner			= THIS_MODULE,
-	.name			= ADAPTER_NAME_ROOT "0",
-	.id			= I2C_HW_IOP321,
-	.algo_data		= &algo_iop3xx_data0,
-};
-static struct i2c_adapter iop3xx_ops1 = {
-	.owner			= THIS_MODULE,
-	.name			= ADAPTER_NAME_ROOT "1",
-	.id			= I2C_HW_IOP321,
-	.algo_data		= &algo_iop3xx_data1,
+release_region:
+	release_mem_region(res->start, IOP3XX_I2C_IO_SIZE);
+
+free_both:
+	kfree(adapter_data);
+
+free_adapter:
+	kfree(new_adapter);
+
+out:
+	return ret;
+}
+
+
+static struct device_driver iop3xx_i2c_driver = {
+	.name		= "IOP3xx-I2C",
+	.bus		= &platform_bus_type,
+	.probe		= iop3xx_i2c_probe,
+	.remove		= iop3xx_i2c_remove
 };
 
-static int __init i2c_iop3xx_init (void)
+static int __init 
+i2c_iop3xx_init (void)
 {
-	return i2c_iop3xx_add_bus(&iop3xx_ops0) ||
-		i2c_iop3xx_add_bus(&iop3xx_ops1);
+	return driver_register(&iop3xx_i2c_driver);
 }
 
-static void __exit i2c_iop3xx_exit (void)
+static void __exit 
+i2c_iop3xx_exit (void)
 {
-	i2c_iop3xx_del_bus(&iop3xx_ops0);
-	i2c_iop3xx_del_bus(&iop3xx_ops1);
+	driver_unregister(&iop3xx_i2c_driver);
+	return;
 }
 
 module_init (i2c_iop3xx_init);
diff -Nru a/drivers/i2c/busses/i2c-iop3xx.h b/drivers/i2c/busses/i2c-iop3xx.h
--- a/drivers/i2c/busses/i2c-iop3xx.h	2005-03-01 23:38:44 -08:00
+++ b/drivers/i2c/busses/i2c-iop3xx.h	2005-03-01 23:38:44 -08:00
@@ -25,20 +25,20 @@
 /*
  * iop321 hardware bit definitions
  */
-#define IOP321_ICR_FAST_MODE	0x8000	/* 1=400kBps, 0=100kBps */
-#define IOP321_ICR_UNIT_RESET	0x4000	/* 1=RESET */
-#define IOP321_ICR_SADIE	0x2000	/* 1=Slave Detect Interrupt Enable */
-#define IOP321_ICR_ALDIE	0x1000	/* 1=Arb Loss Detect Interrupt Enable */
-#define IOP321_ICR_SSDIE	0x0800	/* 1=Slave STOP Detect Interrupt Enable */
-#define IOP321_ICR_BERRIE	0x0400	/* 1=Bus Error Interrupt Enable */
-#define IOP321_ICR_RXFULLIE	0x0200	/* 1=Receive Full Interrupt Enable */
-#define IOP321_ICR_TXEMPTYIE	0x0100	/* 1=Transmit Empty Interrupt Enable */
-#define IOP321_ICR_GCD		0x0080	/* 1=General Call Disable */
+#define IOP3XX_ICR_FAST_MODE	0x8000	/* 1=400kBps, 0=100kBps */
+#define IOP3XX_ICR_UNIT_RESET	0x4000	/* 1=RESET */
+#define IOP3XX_ICR_SAD_IE	0x2000	/* 1=Slave Detect Interrupt Enable */
+#define IOP3XX_ICR_ALD_IE	0x1000	/* 1=Arb Loss Detect Interrupt Enable */
+#define IOP3XX_ICR_SSD_IE	0x0800	/* 1=Slave STOP Detect Interrupt Enable */
+#define IOP3XX_ICR_BERR_IE	0x0400	/* 1=Bus Error Interrupt Enable */
+#define IOP3XX_ICR_RXFULL_IE	0x0200	/* 1=Receive Full Interrupt Enable */
+#define IOP3XX_ICR_TXEMPTY_IE	0x0100	/* 1=Transmit Empty Interrupt Enable */
+#define IOP3XX_ICR_GCD		0x0080	/* 1=General Call Disable */
 /*
- * IOP321_ICR_GCD: 1 disables response as slave. "This bit must be set
+ * IOP3XX_ICR_GCD: 1 disables response as slave. "This bit must be set
  * when sending a master mode general call message from the I2C unit"
  */
-#define IOP321_ICR_UE		0x0040	/* 1=Unit Enable */
+#define IOP3XX_ICR_UE		0x0040	/* 1=Unit Enable */
 /*
  * "NOTE: To avoid I2C bus integrity problems, 
  * the user needs to ensure that the GPIO Output Data Register - 
@@ -47,38 +47,38 @@
  * The user prepares to enable I2C port 0 and 
  * I2C port 1 by clearing GPOD bits 7:6 and GPOD bits 5:4, respectively.
  */
-#define IOP321_ICR_SCLEN	0x0020	/* 1=SCL enable for master mode */
-#define IOP321_ICR_MABORT	0x0010	/* 1=Send a STOP with no data 
+#define IOP3XX_ICR_SCLEN	0x0020	/* 1=SCL enable for master mode */
+#define IOP3XX_ICR_MABORT	0x0010	/* 1=Send a STOP with no data 
 					 * NB TBYTE must be clear */
-#define IOP321_ICR_TBYTE	0x0008	/* 1=Send/Receive a byte. i2c clears */
-#define IOP321_ICR_NACK		0x0004	/* 1=reply with NACK */
-#define IOP321_ICR_MSTOP	0x0002	/* 1=send a STOP after next data byte */
-#define IOP321_ICR_MSTART	0x0001	/* 1=initiate a START */
-
-
-#define IOP321_ISR_BERRD	0x0400	/* 1=BUS ERROR Detected */
-#define IOP321_ISR_SAD		0x0200	/* 1=Slave ADdress Detected */
-#define IOP321_ISR_GCAD		0x0100	/* 1=General Call Address Detected */
-#define IOP321_ISR_RXFULL	0x0080	/* 1=Receive Full */
-#define IOP321_ISR_TXEMPTY	0x0040	/* 1=Transmit Empty */
-#define IOP321_ISR_ALD		0x0020	/* 1=Arbitration Loss Detected */
-#define IOP321_ISR_SSD		0x0010	/* 1=Slave STOP Detected */
-#define IOP321_ISR_BBUSY	0x0008	/* 1=Bus BUSY */
-#define IOP321_ISR_UNITBUSY	0x0004	/* 1=Unit Busy */
-#define IOP321_ISR_NACK		0x0002	/* 1=Unit Rx or Tx a NACK */
-#define IOP321_ISR_RXREAD	0x0001	/* 1=READ 0=WRITE (R/W bit of slave addr */
-
-#define IOP321_ISR_CLEARBITS	0x07f0
-
-#define IOP321_ISAR_SAMASK	0x007f
+#define IOP3XX_ICR_TBYTE	0x0008	/* 1=Send/Receive a byte. i2c clears */
+#define IOP3XX_ICR_NACK		0x0004	/* 1=reply with NACK */
+#define IOP3XX_ICR_MSTOP	0x0002	/* 1=send a STOP after next data byte */
+#define IOP3XX_ICR_MSTART	0x0001	/* 1=initiate a START */
+
+
+#define IOP3XX_ISR_BERRD	0x0400	/* 1=BUS ERROR Detected */
+#define IOP3XX_ISR_SAD		0x0200	/* 1=Slave ADdress Detected */
+#define IOP3XX_ISR_GCAD		0x0100	/* 1=General Call Address Detected */
+#define IOP3XX_ISR_RXFULL	0x0080	/* 1=Receive Full */
+#define IOP3XX_ISR_TXEMPTY	0x0040	/* 1=Transmit Empty */
+#define IOP3XX_ISR_ALD		0x0020	/* 1=Arbitration Loss Detected */
+#define IOP3XX_ISR_SSD		0x0010	/* 1=Slave STOP Detected */
+#define IOP3XX_ISR_BBUSY	0x0008	/* 1=Bus BUSY */
+#define IOP3XX_ISR_UNITBUSY	0x0004	/* 1=Unit Busy */
+#define IOP3XX_ISR_NACK		0x0002	/* 1=Unit Rx or Tx a NACK */
+#define IOP3XX_ISR_RXREAD	0x0001	/* 1=READ 0=WRITE (R/W bit of slave addr */
+
+#define IOP3XX_ISR_CLEARBITS	0x07f0
+
+#define IOP3XX_ISAR_SAMASK	0x007f
 
-#define IOP321_IDBR_MASK	0x00ff
+#define IOP3XX_IDBR_MASK	0x00ff
 
-#define IOP321_IBMR_SCL		0x0002
-#define IOP321_IBMR_SDA		0x0001
+#define IOP3XX_IBMR_SCL		0x0002
+#define IOP3XX_IBMR_SDA		0x0001
 
-#define IOP321_GPOD_I2C0	0x00c0	/* clear these bits to enable ch0 */
-#define IOP321_GPOD_I2C1	0x0030	/* clear these bits to enable ch1 */
+#define IOP3XX_GPOD_I2C0	0x00c0	/* clear these bits to enable ch0 */
+#define IOP3XX_GPOD_I2C1	0x0030	/* clear these bits to enable ch1 */
 
 #define MYSAR			0x02	/* SWAG a suitable slave address */
 
@@ -87,32 +87,21 @@
 #define I2C_ERR_ALD		(I2C_ERR+1)
 
 
-struct iop3xx_biu {                /* Bus Interface Unit - the hardware */
-/* physical hardware defs - regs*/
-	u32 *CR;
-	u32 *SR;
-	u32 *SAR;
-	u32 *DBR;
-	u32 *BMR;
-/* irq bit vector */
-	u32 irq;
-/* stored flags */
-	u32 SR_enabled, SR_received;
-};
+#define	CR_OFFSET		0
+#define	SR_OFFSET		0x4
+#define	SAR_OFFSET		0x8
+#define	DBR_OFFSET		0xc
+#define	CCR_OFFSET		0x10
+#define	BMR_OFFSET		0x14
 
-struct i2c_algo_iop3xx_data {
-	int channel;
+#define	IOP3XX_I2C_IO_SIZE	0x18
 
+struct i2c_algo_iop3xx_data {
+	u32 ioaddr;
 	wait_queue_head_t waitq;
 	spinlock_t lock;
-	int timeout;
-	struct iop3xx_biu* biu;
+	u32 SR_enabled, SR_received;
+	int id;
 };
-
-#define REGION_START(adap)	((u32)((adap)->biu->CR))
-#define REGION_END(adap)	((u32)((adap)->biu->BMR+1))
-#define REGION_LENGTH(adap)	(REGION_END(adap)-REGION_START(adap))
-
-#define IRQ_STATUS_MASK(adap)	(1<<adap->biu->irq)
 
 #endif /* I2C_IOP3XX_H */
diff -Nru a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c
--- a/drivers/i2c/busses/i2c-mpc.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/i2c/busses/i2c-mpc.c	2005-03-01 23:38:56 -08:00
@@ -1,12 +1,12 @@
 /*
  * (C) Copyright 2003-2004
  * Humboldt Solutions Ltd, adrian@humboldt.co.uk.
- 
+
  * This is a combined i2c adapter and algorithm driver for the
  * MPC107/Tsi107 PowerPC northbridge and processors that include
- * the same I2C unit (8240, 8245, 85xx). 
+ * the same I2C unit (8240, 8245, 85xx).
  *
- * Release 0.6
+ * Release 0.8
  *
  * This file is licensed under the terms of the GNU General Public
  * License version 2. This program is licensed "as is" without any
@@ -20,7 +20,13 @@
 #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>
@@ -50,10 +56,11 @@
 
 struct mpc_i2c {
 	char *base;
-	struct ocp_def *ocpdef;
 	u32 interrupt;
 	wait_queue_head_t queue;
 	struct i2c_adapter adap;
+	int irq;
+	u32 flags;
 };
 
 static __inline__ void writeccr(struct mpc_i2c *i2c, u32 x)
@@ -75,12 +82,12 @@
 
 static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing)
 {
-	DECLARE_WAITQUEUE(wait, current);
 	unsigned long orig_jiffies = jiffies;
 	u32 x;
 	int result = 0;
 
-	if (i2c->ocpdef->irq == OCP_IRQ_NA) {
+	if (i2c->irq == 0)
+	{
 		while (!(readb(i2c->base + MPC_I2C_SR) & CSR_MIF)) {
 			schedule();
 			if (time_after(jiffies, orig_jiffies + timeout)) {
@@ -92,28 +99,22 @@
 		x = readb(i2c->base + MPC_I2C_SR);
 		writeb(0, i2c->base + MPC_I2C_SR);
 	} else {
-		set_current_state(TASK_INTERRUPTIBLE);
-		add_wait_queue(&i2c->queue, &wait);
-		while (!(i2c->interrupt & CSR_MIF)) {
-			if (signal_pending(current)) {
-				pr_debug("I2C: Interrupted\n");
-				result = -EINTR;
-				break;
-			}
-			if (time_after(jiffies, orig_jiffies + timeout)) {
-				pr_debug("I2C: timeout\n");
-				result = -EIO;
-				break;
-			}
-			msleep_interruptible(jiffies_to_msecs(timeout));
+		/* Interrupt mode */
+		result = wait_event_interruptible_timeout(i2c->queue,
+			(i2c->interrupt & CSR_MIF), timeout * HZ);
+
+		if (unlikely(result < 0))
+			pr_debug("I2C: wait interrupted\n");
+		else if (unlikely(!(i2c->interrupt & CSR_MIF))) {
+			pr_debug("I2C: wait timeout\n");
+			result = -ETIMEDOUT;
 		}
-		set_current_state(TASK_RUNNING);
-		remove_wait_queue(&i2c->queue, &wait);
+
 		x = i2c->interrupt;
 		i2c->interrupt = 0;
 	}
 
-	if (result < -0)
+	if (result < 0)
 		return result;
 
 	if (!(x & CSR_MCF)) {
@@ -137,12 +138,11 @@
 
 static void mpc_i2c_setclock(struct mpc_i2c *i2c)
 {
-	struct ocp_fs_i2c_data *i2c_data = i2c->ocpdef->additions;
 	/* Set clock and filters */
-	if (i2c_data && (i2c_data->flags & FS_I2C_SEPARATE_DFSRR)) {
+	if (i2c->flags & FSL_I2C_DEV_SEPARATE_DFSRR) {
 		writeb(0x31, i2c->base + MPC_I2C_FDR);
 		writeb(0x10, i2c->base + MPC_I2C_DFSRR);
-	} else if (i2c_data && (i2c_data->flags & FS_I2C_CLOCK_5200))
+	} else if (i2c->flags & FSL_I2C_DEV_CLOCK_5200)
 		writeb(0x3f, i2c->base + MPC_I2C_FDR);
 	else
 		writel(0x1031, i2c->base + MPC_I2C_FDR);
@@ -165,7 +165,7 @@
 		     const u8 * data, int length, int restart)
 {
 	int i;
-	unsigned timeout = HZ;
+	unsigned timeout = i2c->adap.timeout;
 	u32 flags = restart ? CCR_RSTA : 0;
 
 	/* Start with MEN */
@@ -193,7 +193,7 @@
 static int mpc_read(struct mpc_i2c *i2c, int target,
 		    u8 * data, int length, int restart)
 {
-	unsigned timeout = HZ;
+	unsigned timeout = i2c->adap.timeout;
 	int i;
 	u32 flags = restart ? CCR_RSTA : 0;
 
@@ -294,6 +294,7 @@
 	.retries = 1
 };
 
+#ifdef CONFIG_FSL_OCP
 static int __devinit mpc_i2c_probe(struct ocp_device *ocp)
 {
 	int result = 0;
@@ -302,7 +303,10 @@
 	if (!(i2c = kmalloc(sizeof(*i2c), GFP_KERNEL))) {
 		return -ENOMEM;
 	}
-	i2c->ocpdef = ocp->def;
+	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")) {
@@ -318,16 +322,20 @@
 		goto fail_map;
 	}
 
-	if (ocp->def->irq != OCP_IRQ_NA)
+	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;
@@ -354,9 +362,9 @@
 	i2c_del_adapter(&i2c->adap);
 
 	if (ocp->def->irq != OCP_IRQ_NA)
-		free_irq(i2c->ocpdef->irq, i2c);
+		free_irq(i2c->irq, i2c);
 	iounmap(i2c->base);
-	release_mem_region(i2c->ocpdef->paddr, MPC_I2C_REGION);
+	release_mem_region(ocp->def->paddr, MPC_I2C_REGION);
 	kfree(i2c);
 }
 
@@ -386,6 +394,101 @@
 
 module_init(iic_init);
 module_exit(iic_exit);
+#else
+static int fsl_i2c_probe(struct device *device)
+{
+	int result = 0;
+	struct mpc_i2c *i2c;
+	struct platform_device *pdev = to_platform_device(device);
+	struct fsl_i2c_platform_data *pdata;
+	struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+	pdata = (struct fsl_i2c_platform_data *) pdev->dev.platform_data;
+
+	if (!(i2c = kmalloc(sizeof(*i2c), GFP_KERNEL))) {
+		return -ENOMEM;
+	}
+	memset(i2c, 0, sizeof(*i2c));
+
+	i2c->irq = platform_get_irq(pdev, 0);
+	i2c->flags = pdata->device_flags;
+	init_waitqueue_head(&i2c->queue);
+
+	i2c->base = ioremap((phys_addr_t)r->start, MPC_I2C_REGION);
+
+	if (!i2c->base) {
+		printk(KERN_ERR "i2c-mpc - failed to map controller\n");
+		result = -ENOMEM;
+		goto fail_map;
+	}
+
+	if (i2c->irq != 0)
+		if ((result = request_irq(i2c->irq, mpc_i2c_isr,
+					  0, "fsl-i2c", i2c)) < 0) {
+			printk(KERN_ERR
+			       "i2c-mpc - failed to attach interrupt\n");
+			goto fail_irq;
+		}
+
+	i2c->adap = mpc_ops;
+	i2c_set_adapdata(&i2c->adap, i2c);
+	i2c->adap.dev.parent = &pdev->dev;
+	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);
+	dev_set_drvdata(device, i2c);
+	return result;
+
+      fail_add:
+	if (i2c->irq != 0)
+		free_irq(i2c->irq, 0);
+      fail_irq:
+	iounmap(i2c->base);
+      fail_map:
+	kfree(i2c);
+	return result;
+};
+
+static int fsl_i2c_remove(struct device *device)
+{
+	struct mpc_i2c *i2c = dev_get_drvdata(device);
+
+	dev_set_drvdata(device, NULL);
+	i2c_del_adapter(&i2c->adap);
+
+	if (i2c->irq != 0)
+		free_irq(i2c->irq, i2c);
+
+	iounmap(i2c->base);
+	kfree(i2c);
+	return 0;
+};
+
+/* Structure for a device driver */
+static struct device_driver fsl_i2c_driver = {
+	.name = "fsl-i2c",
+	.bus = &platform_bus_type,
+	.probe = fsl_i2c_probe,
+	.remove = fsl_i2c_remove,
+};
+
+static int __init fsl_i2c_init(void)
+{
+	return driver_register(&fsl_i2c_driver);
+}
+
+static void __exit fsl_i2c_exit(void)
+{
+	driver_unregister(&fsl_i2c_driver);
+}
+
+module_init(fsl_i2c_init);
+module_exit(fsl_i2c_exit);
+
+#endif /* CONFIG_FSL_OCP */
 
 MODULE_AUTHOR("Adrian Cox <adrian@humboldt.co.uk>");
 MODULE_DESCRIPTION
diff -Nru a/drivers/i2c/busses/i2c-nforce2.c b/drivers/i2c/busses/i2c-nforce2.c
--- a/drivers/i2c/busses/i2c-nforce2.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/i2c/busses/i2c-nforce2.c	2005-03-01 23:38:53 -08:00
@@ -28,6 +28,7 @@
     nForce2 MCP			0064
     nForce2 Ultra 400 MCP	0084
     nForce3 Pro150 MCP		00D4
+    nForce3 250Gb MCP		00E4
 
     This driver supports the 2 SMBuses that are included in the MCP2 of the
     nForce2 chipset.
@@ -290,12 +291,10 @@
 
 
 static struct pci_device_id nforce2_ids[] = {
-	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2_SMBUS,
-	       	PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
-	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2S_SMBUS,
-	       	PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
-	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3_SMBUS,
-	       	PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+	{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2_SMBUS) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2S_SMBUS) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3_SMBUS) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_SMBUS) },
 	{ 0 }
 };
 
diff -Nru a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
--- a/drivers/i2c/busses/i2c-piix4.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/i2c/busses/i2c-piix4.c	2005-03-01 23:38:54 -08:00
@@ -414,48 +414,18 @@
 };
 
 static struct pci_device_id piix4_ids[] = {
-	{
-		.vendor =	PCI_VENDOR_ID_INTEL,
-		.device =	PCI_DEVICE_ID_INTEL_82371AB_3,
-		.subvendor =	PCI_ANY_ID,
-		.subdevice =	PCI_ANY_ID,
-		.driver_data =	3
-	},
-	{
-		.vendor =	PCI_VENDOR_ID_SERVERWORKS,
-		.device =	PCI_DEVICE_ID_SERVERWORKS_OSB4,
-		.subvendor =	PCI_ANY_ID,
-		.subdevice =	PCI_ANY_ID,
-		.driver_data =	0,
-	},
-	{
-		.vendor =	PCI_VENDOR_ID_SERVERWORKS,
-		.device =	PCI_DEVICE_ID_SERVERWORKS_CSB5,
-		.subvendor =	PCI_ANY_ID,
-		.subdevice =	PCI_ANY_ID,
-		.driver_data =	0,
-	},
-	{
-		.vendor =	PCI_VENDOR_ID_SERVERWORKS,
-		.device =	PCI_DEVICE_ID_SERVERWORKS_CSB6,
-		.subvendor =	PCI_ANY_ID,
-		.subdevice =	PCI_ANY_ID,
-		.driver_data =	0,
-	},
-	{
-		.vendor =	PCI_VENDOR_ID_INTEL,
-		.device =	PCI_DEVICE_ID_INTEL_82443MX_3,
-		.subvendor =	PCI_ANY_ID,
-		.subdevice =	PCI_ANY_ID,
-		.driver_data =	3,
-	},
-	{
-		.vendor =	PCI_VENDOR_ID_EFAR,
-		.device =	PCI_DEVICE_ID_EFAR_SLC90E66_3,
-		.subvendor =	PCI_ANY_ID,
-		.subdevice =	PCI_ANY_ID,
-		.driver_data =	0,
-	},
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3),
+	  .driver_data = 3 },
+	{ PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4),
+	  .driver_data = 0 },
+	{ PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5),
+	  .driver_data = 0 },
+	{ PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6),
+	  .driver_data = 0 },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443MX_3),
+	  .driver_data = 3 },
+	{ PCI_DEVICE(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_3),
+	  .driver_data = 0 },
 	{ 0, }
 };
 
diff -Nru a/drivers/i2c/busses/i2c-prosavage.c b/drivers/i2c/busses/i2c-prosavage.c
--- a/drivers/i2c/busses/i2c-prosavage.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/i2c/busses/i2c-prosavage.c	2005-03-01 23:38:55 -08:00
@@ -96,13 +96,6 @@
 /* 
  * S3/VIA 8365/8375 registers
  */
-#ifndef PCI_DEVICE_ID_S3_SAVAGE4
-#define PCI_DEVICE_ID_S3_SAVAGE4	0x8a25
-#endif
-#ifndef PCI_DEVICE_ID_S3_PROSAVAGE8
-#define PCI_DEVICE_ID_S3_PROSAVAGE8	0x8d04
-#endif
-
 #define VGA_CR_IX	0x3d4
 #define VGA_CR_DATA	0x3d5
 
diff -Nru a/drivers/i2c/busses/i2c-sibyte.c b/drivers/i2c/busses/i2c-sibyte.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/i2c/busses/i2c-sibyte.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2004 Steven J. Hill
+ * Copyright (C) 2001,2002,2003 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#include <linux/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)) }
+};
+
+static struct i2c_adapter sibyte_board_adapter[2] = {
+	{
+		.owner		= THIS_MODULE,
+		.id		= I2C_HW_SIBYTE,
+		.class		= I2C_CLASS_HWMON,
+		.algo		= NULL,
+		.algo_data	= &sibyte_board_data[0],
+		.name		= "SiByte SMBus 0",
+	},
+	{
+		.owner		= THIS_MODULE,
+		.id		= I2C_HW_SIBYTE,
+		.class		= I2C_CLASS_HWMON,
+		.algo		= NULL,
+		.algo_data	= &sibyte_board_data[1],
+		.name		= "SiByte SMBus 1",
+	},
+};
+
+static int __init i2c_sibyte_init(void)
+{
+	printk("i2c-swarm.o: i2c SMBus adapter module for SiByte board\n");
+	if (i2c_sibyte_add_bus(&sibyte_board_adapter[0], K_SMB_FREQ_100KHZ) < 0)
+		return -ENODEV;
+	if (i2c_sibyte_add_bus(&sibyte_board_adapter[1], K_SMB_FREQ_400KHZ) < 0)
+		return -ENODEV;
+	return 0;
+}
+
+static void __exit i2c_sibyte_exit(void)
+{
+	i2c_sibyte_del_bus(&sibyte_board_adapter[0]);
+	i2c_sibyte_del_bus(&sibyte_board_adapter[1]);
+}
+
+module_init(i2c_sibyte_init);
+module_exit(i2c_sibyte_exit);
+
+MODULE_AUTHOR("Kip Walker <kwalker@broadcom.com>, Steven J. Hill <sjhill@realitydiluted.com>");
+MODULE_DESCRIPTION("SMBus adapter routines for SiByte boards");
+MODULE_LICENSE("GPL");
diff -Nru a/drivers/i2c/busses/i2c-sis5595.c b/drivers/i2c/busses/i2c-sis5595.c
--- a/drivers/i2c/busses/i2c-sis5595.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/i2c/busses/i2c-sis5595.c	2005-03-01 23:39:18 -08:00
@@ -181,9 +181,11 @@
 
 	if (force_addr) {
 		dev_info(&SIS5595_dev->dev, "forcing ISA address 0x%04X\n", sis5595_base);
-		if (!pci_write_config_word(SIS5595_dev, ACPI_BASE, sis5595_base))
+		if (pci_write_config_word(SIS5595_dev, ACPI_BASE, sis5595_base)
+		    != PCIBIOS_SUCCESSFUL)
 			goto error;
-		if (!pci_read_config_word(SIS5595_dev, ACPI_BASE, &a))
+		if (pci_read_config_word(SIS5595_dev, ACPI_BASE, &a)
+		    != PCIBIOS_SUCCESSFUL)
 			goto error;
 		if ((a & ~(SIS5595_EXTENT - 1)) != sis5595_base) {
 			/* doesn't work for some chips! */
@@ -192,13 +194,16 @@
 		}
 	}
 
-	if (!pci_read_config_byte(SIS5595_dev, SIS5595_ENABLE_REG, &val))
+	if (pci_read_config_byte(SIS5595_dev, SIS5595_ENABLE_REG, &val)
+	    != PCIBIOS_SUCCESSFUL)
 		goto error;
 	if ((val & 0x80) == 0) {
 		dev_info(&SIS5595_dev->dev, "enabling ACPI\n");
-		if (!pci_write_config_byte(SIS5595_dev, SIS5595_ENABLE_REG, val | 0x80))
+		if (pci_write_config_byte(SIS5595_dev, SIS5595_ENABLE_REG, val | 0x80)
+		    != PCIBIOS_SUCCESSFUL)
 			goto error;
-		if (!pci_read_config_byte(SIS5595_dev, SIS5595_ENABLE_REG, &val))
+		if (pci_read_config_byte(SIS5595_dev, SIS5595_ENABLE_REG, &val)
+		    != PCIBIOS_SUCCESSFUL)
 			goto error;
 		if ((val & 0x80) == 0) {
 			/* doesn't work for some chips? */
diff -Nru a/drivers/i2c/busses/i2c-sis96x.c b/drivers/i2c/busses/i2c-sis96x.c
--- a/drivers/i2c/busses/i2c-sis96x.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/i2c/busses/i2c-sis96x.c	2005-03-01 23:38:54 -08:00
@@ -51,9 +51,6 @@
 */
 #define SIS96x_VERSION "1.0.0"
 
-/* SiS96x SMBus PCI device ID */
-#define PCI_DEVICE_ID_SI_SMBUS 0x16
-
 /* base address register in PCI config space */
 #define SIS96x_BAR 0x04
 
@@ -267,14 +264,7 @@
 };
 
 static struct pci_device_id sis96x_ids[] = {
-
-	{
-		.vendor	=	PCI_VENDOR_ID_SI,
-		.device =	PCI_DEVICE_ID_SI_SMBUS,
-		.subvendor =	PCI_ANY_ID,
-		.subdevice =	PCI_ANY_ID,
-	},
-
+	{ PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_SMBUS) },
 	{ 0, }
 };
 
diff -Nru a/drivers/i2c/busses/i2c-stub.c b/drivers/i2c/busses/i2c-stub.c
--- a/drivers/i2c/busses/i2c-stub.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/i2c/busses/i2c-stub.c	2005-03-01 23:38:58 -08:00
@@ -28,6 +28,7 @@
 #include <linux/errno.h>
 #include <linux/i2c.h>
 
+static u8  stub_pointer;
 static u8  stub_bytes[256];
 static u16 stub_words[256];
 
@@ -44,6 +45,22 @@
 		ret = 0;
 		break;
 
+	case I2C_SMBUS_BYTE:
+		if (read_write == I2C_SMBUS_WRITE) {
+			stub_pointer = command;
+			dev_dbg(&adap->dev, "smbus byte - addr 0x%02x, "
+					"wrote 0x%02x.\n",
+					addr, command);
+		} else {
+			data->byte = stub_bytes[stub_pointer++];
+			dev_dbg(&adap->dev, "smbus byte - addr 0x%02x, "
+					"read  0x%02x.\n",
+					addr, data->byte);
+		}
+
+		ret = 0;
+		break;
+
 	case I2C_SMBUS_BYTE_DATA:
 		if (read_write == I2C_SMBUS_WRITE) {
 			stub_bytes[command] = data->byte;
@@ -56,6 +73,7 @@
 					"read  0x%02x at 0x%02x.\n",
 					addr, data->byte, command);
 		}
+		stub_pointer = command + 1;
 
 		ret = 0;
 		break;
@@ -87,8 +105,8 @@
 
 static u32 stub_func(struct i2c_adapter *adapter)
 {
-	return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE_DATA |
-		I2C_FUNC_SMBUS_WORD_DATA;
+	return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
+		I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA;
 }
 
 static struct i2c_algorithm smbus_algorithm = {
diff -Nru a/drivers/i2c/busses/i2c-viapro.c b/drivers/i2c/busses/i2c-viapro.c
--- a/drivers/i2c/busses/i2c-viapro.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/i2c/busses/i2c-viapro.c	2005-03-01 23:39:08 -08:00
@@ -45,6 +45,8 @@
 #include <linux/init.h>
 #include <asm/io.h>
 
+static struct pci_dev *vt596_pdev;
+
 #define SMBBA1	   	 0x90
 #define SMBBA2     	 0x80
 #define SMBBA3     	 0xD0
@@ -231,8 +233,8 @@
 			len = data->block[0];
 			if (len < 0)
 				len = 0;
-			if (len > 32)
-				len = 32;
+			if (len > I2C_SMBUS_BLOCK_MAX)
+				len = I2C_SMBUS_BLOCK_MAX;
 			outb_p(len, SMBHSTDAT0);
 			i = inb_p(SMBHSTCNT);	/* Reset SMBBLKDAT */
 			for (i = 1; i <= len; i++)
@@ -266,6 +268,8 @@
 		break;
 	case VT596_BLOCK_DATA:
 		data->block[0] = inb_p(SMBHSTDAT0);
+		if (data->block[0] > I2C_SMBUS_BLOCK_MAX)
+			data->block[0] = I2C_SMBUS_BLOCK_MAX;
 		i = inb_p(SMBHSTCNT);	/* Reset SMBBLKDAT */
 		for (i = 1; i <= data->block[0]; i++)
 			data->block[i] = inb_p(SMBBLKDAT);
@@ -381,76 +385,40 @@
 	snprintf(vt596_adapter.name, I2C_NAME_SIZE,
 			"SMBus Via Pro adapter at %04x", vt596_smba);
 	
-	return i2c_add_adapter(&vt596_adapter);
+	vt596_pdev = pci_dev_get(pdev);
+	if (i2c_add_adapter(&vt596_adapter)) {
+		pci_dev_put(vt596_pdev);
+		vt596_pdev = 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;
 
  release_region:
 	release_region(vt596_smba, 8);
 	return error;
 }
 
-static void __devexit vt596_remove(struct pci_dev *pdev)
-{
-	i2c_del_adapter(&vt596_adapter);
-	release_region(vt596_smba, 8);
-}
-
 static struct pci_device_id vt596_ids[] = {
-	{
-		.vendor		= PCI_VENDOR_ID_VIA,
-		.device 	= PCI_DEVICE_ID_VIA_82C596_3,
-		.subvendor	= PCI_ANY_ID,
-		.subdevice	= PCI_ANY_ID,
-		.driver_data	= SMBBA1,
-	},
-	{
-		.vendor		= PCI_VENDOR_ID_VIA,
-		.device		= PCI_DEVICE_ID_VIA_82C596B_3,
-		.subvendor	= PCI_ANY_ID,
-		.subdevice	= PCI_ANY_ID,
-		.driver_data	= SMBBA1,
-	},
-	{
-		.vendor		= PCI_VENDOR_ID_VIA,
-		.device 	= PCI_DEVICE_ID_VIA_82C686_4,
-		.subvendor	= PCI_ANY_ID,
-		.subdevice	= PCI_ANY_ID,
-		.driver_data	= SMBBA1,
-	},
-	{
-		.vendor		= PCI_VENDOR_ID_VIA,
-		.device 	= PCI_DEVICE_ID_VIA_8233_0,
-		.subvendor	= PCI_ANY_ID,
-		.subdevice	= PCI_ANY_ID,
-		.driver_data	= SMBBA3
-	},
-	{
-		.vendor		= PCI_VENDOR_ID_VIA,
-		.device 	= PCI_DEVICE_ID_VIA_8233A,
-		.subvendor	= PCI_ANY_ID,
-		.subdevice	= PCI_ANY_ID,
-		.driver_data	= SMBBA3,
-	},
-	{
-		.vendor		= PCI_VENDOR_ID_VIA,
-		.device 	= PCI_DEVICE_ID_VIA_8235,
-		.subvendor	= PCI_ANY_ID,
-		.subdevice	= PCI_ANY_ID,
-		.driver_data	= SMBBA3
-	},
-	{
-		.vendor		= PCI_VENDOR_ID_VIA,
-		.device 	= PCI_DEVICE_ID_VIA_8237,
-		.subvendor	= PCI_ANY_ID,
-		.subdevice	= PCI_ANY_ID,
-		.driver_data	= SMBBA3
-	},
-	{
-		.vendor		= PCI_VENDOR_ID_VIA,
-		.device 	= PCI_DEVICE_ID_VIA_8231_4,
-		.subvendor	= PCI_ANY_ID,
-		.subdevice	= PCI_ANY_ID,
-		.driver_data	= SMBBA1,
-	},
+	{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C596_3),
+	  .driver_data = SMBBA1 },
+	{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C596B_3),
+	  .driver_data = SMBBA1 },
+	{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4),
+	  .driver_data = SMBBA1 },
+	{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8233_0),
+	  .driver_data = SMBBA3 },
+	{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8233A),
+	  .driver_data = SMBBA3 },
+	{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235),
+	  .driver_data = SMBBA3 },
+	{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237),
+	  .driver_data = SMBBA3 },
+	{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231_4),
+	  .driver_data = SMBBA1 },
 	{ 0, }
 };
 
@@ -460,7 +428,6 @@
 	.name		= "vt596_smbus",
 	.id_table	= vt596_ids,
 	.probe		= vt596_probe,
-	.remove		= __devexit_p(vt596_remove),
 };
 
 static int __init i2c_vt596_init(void)
@@ -472,6 +439,12 @@
 static void __exit i2c_vt596_exit(void)
 {
 	pci_unregister_driver(&vt596_driver);
+	if (vt596_pdev != NULL) {
+		i2c_del_adapter(&vt596_adapter);
+		release_region(vt596_smba, 8);
+		pci_dev_put(vt596_pdev);
+		vt596_pdev = NULL;
+	}
 }
 
 MODULE_AUTHOR(
diff -Nru a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig
--- a/drivers/i2c/chips/Kconfig	2005-03-01 23:38:58 -08:00
+++ b/drivers/i2c/chips/Kconfig	2005-03-01 23:38:58 -08:00
@@ -239,6 +239,18 @@
 	  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_SMSC47M1
 	tristate "SMSC LPC47M10x and compatibles"
 	depends on I2C && EXPERIMENTAL
diff -Nru a/drivers/i2c/chips/Makefile b/drivers/i2c/chips/Makefile
--- a/drivers/i2c/chips/Makefile	2005-03-01 23:39:18 -08:00
+++ b/drivers/i2c/chips/Makefile	2005-03-01 23:39:18 -08:00
@@ -30,6 +30,7 @@
 obj-$(CONFIG_SENSORS_PCF8574)	+= pcf8574.o
 obj-$(CONFIG_SENSORS_PCF8591)	+= pcf8591.o
 obj-$(CONFIG_SENSORS_RTC8564)	+= rtc8564.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
diff -Nru a/drivers/i2c/chips/adm1026.c b/drivers/i2c/chips/adm1026.c
--- a/drivers/i2c/chips/adm1026.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/i2c/chips/adm1026.c	2005-03-01 23:38:55 -08:00
@@ -452,6 +452,14 @@
 		client->id, 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)
@@ -459,8 +467,7 @@
 	struct adm1026_data *data = i2c_get_clientdata(client);
 	int  i;
 
-	dev_dbg(&client->dev, "(%d): GPIO config is:",
-			    client->id);
+	dev_dbg(&client->dev, "(%d): GPIO config is:", client->id);
 	for (i = 0;i <= 7;++i) {
 		if (data->config2 & (1 << i)) {
 			dev_dbg(&client->dev, "\t(%d): %sGP%s%d\n", client->id,
diff -Nru a/drivers/i2c/chips/asb100.c b/drivers/i2c/chips/asb100.c
--- a/drivers/i2c/chips/asb100.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/i2c/chips/asb100.c	2005-03-01 23:38:58 -08:00
@@ -56,8 +56,7 @@
 #define ASB100_VERSION "1.0.0"
 
 /* I2C addresses to scan */
-static unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d,
-					0x2e, 0x2f, I2C_CLIENT_END };
+static unsigned short normal_i2c[] = { 0x2d, I2C_CLIENT_END };
 
 /* ISA addresses to scan (none) */
 static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
diff -Nru a/drivers/i2c/chips/ds1621.c b/drivers/i2c/chips/ds1621.c
--- a/drivers/i2c/chips/ds1621.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/i2c/chips/ds1621.c	2005-03-01 23:39:17 -08:00
@@ -42,9 +42,8 @@
 /* Many DS1621 constants specified below */
 /* Config register used for detection         */
 /*  7    6    5    4    3    2    1    0      */
-/* |Done|THF |TLF |NVB | 1  | 0  |POL |1SHOT| */
-#define DS1621_REG_CONFIG_MASK		0x0C
-#define DS1621_REG_CONFIG_VAL		0x08
+/* |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
@@ -55,6 +54,7 @@
 #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
@@ -212,9 +212,13 @@
 
 	/* 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_MASK) != DS1621_REG_CONFIG_VAL)
+		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;
diff -Nru a/drivers/i2c/chips/eeprom.c b/drivers/i2c/chips/eeprom.c
--- a/drivers/i2c/chips/eeprom.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/i2c/chips/eeprom.c	2005-03-01 23:38:55 -08:00
@@ -43,13 +43,6 @@
 /* Insmod parameters */
 SENSORS_INSMOD_1(eeprom);
 
-static int checksum = 0;
-module_param(checksum, bool, 0);
-MODULE_PARM_DESC(checksum, "Only accept eeproms whose checksum is correct");
-
-
-/* EEPROM registers */
-#define EEPROM_REG_CHECKSUM	0x3f
 
 /* Size of EEPROM in bytes */
 #define EEPROM_SIZE		256
@@ -85,8 +78,6 @@
 	.detach_client	= eeprom_detach_client,
 };
 
-static int eeprom_id;
-
 static void eeprom_update_client(struct i2c_client *client, u8 slice)
 {
 	struct eeprom_data *data = i2c_get_clientdata(client);
@@ -168,21 +159,18 @@
 /* This function is called by i2c_detect */
 int eeprom_detect(struct i2c_adapter *adapter, int address, int kind)
 {
-	int i, cs;
 	struct i2c_client *new_client;
 	struct eeprom_data *data;
 	int err = 0;
 
-	/* 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, " eeprom_detect called for an ISA bus adapter?!?\n");
-		return 0;
-	}
-#endif
-
-	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+	/* 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))
 		goto exit;
 
 	/* OK. For now, we presume we have a valid client. We now create the
@@ -205,37 +193,27 @@
 	/* prevent 24RF08 corruption */
 	i2c_smbus_write_quick(new_client, 0);
 
-	/* Now, we do the remaining detection. It is not there, unless you force
-	   the checksum to work out. */
-	if (checksum) {
-		cs = 0;
-		for (i = 0; i <= 0x3e; i++)
-			cs += i2c_smbus_read_byte_data(new_client, i);
-		cs &= 0xff;
-		if (i2c_smbus_read_byte_data (new_client, EEPROM_REG_CHECKSUM) != cs)
-			goto exit_kfree;
-	}
-
-	data->nature = UNKNOWN;
-	/* Detect the Vaio nature of EEPROMs.
-	   We use the "PCG-" prefix as the signature. */
-	if (address == 0x57) {
-		if (i2c_smbus_read_byte_data(new_client, 0x80) == 'P' && 
-		    i2c_smbus_read_byte_data(new_client, 0x81) == 'C' && 
-		    i2c_smbus_read_byte_data(new_client, 0x82) == 'G' &&
-		    i2c_smbus_read_byte_data(new_client, 0x83) == '-')
-			data->nature = VAIO;
-	}
-
 	/* Fill in the remaining client fields */
-	strncpy(new_client->name, "eeprom", I2C_NAME_SIZE);
-	new_client->id = eeprom_id++;
+	strlcpy(new_client->name, "eeprom", I2C_NAME_SIZE);
 	data->valid = 0;
 	init_MUTEX(&data->update_lock);
+	data->nature = UNKNOWN;
 
 	/* Tell the I2C layer a new client has arrived */
 	if ((err = i2c_attach_client(new_client)))
 		goto exit_kfree;
+
+	/* Detect the Vaio nature of EEPROMs.
+	   We use the "PCG-" prefix as the signature. */
+	if (address == 0x57) {
+		if (i2c_smbus_read_byte_data(new_client, 0x80) == 'P'
+		 && i2c_smbus_read_byte(new_client) == 'C'
+		 && i2c_smbus_read_byte(new_client) == 'G'
+		 && i2c_smbus_read_byte(new_client) == '-')
+			dev_info(&new_client->dev, "Vaio EEPROM detected, "
+				"enabling password protection\n");
+			data->nature = VAIO;
+	}
 
 	/* create the sysfs eeprom file */
 	sysfs_create_bin_file(&new_client->dev.kobj, &eeprom_attr);
diff -Nru a/drivers/i2c/chips/fscher.c b/drivers/i2c/chips/fscher.c
--- a/drivers/i2c/chips/fscher.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/i2c/chips/fscher.c	2005-03-01 23:38:57 -08:00
@@ -198,7 +198,7 @@
 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(fan, _pwm   , offset, reg_min) \
+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)
@@ -247,7 +247,7 @@
 #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_fan##offset##_pwm); \
+	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)
@@ -483,16 +483,17 @@
 	return sprintf(buf, "%u\n", data->fan_status[FAN_INDEX_FROM_NUM(nr)] & 0x04);
 }
 
-static ssize_t set_fan_pwm(struct i2c_client *client, struct fscher_data *data,
+static ssize_t set_pwm(struct i2c_client *client, struct fscher_data *data,
 		       const char *buf, size_t count, int nr, int reg)
 {
-	data->fan_min[FAN_INDEX_FROM_NUM(nr)] = simple_strtoul(buf, NULL, 10) & 0xff;
+	unsigned long v = simple_strtoul(buf, NULL, 10);
+	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)]);
 	return count;
 }
 
-static ssize_t show_fan_pwm (struct fscher_data *data, char *buf, int nr)
+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)]);
 }
diff -Nru a/drivers/i2c/chips/isp1301_omap.c b/drivers/i2c/chips/isp1301_omap.c
--- a/drivers/i2c/chips/isp1301_omap.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/i2c/chips/isp1301_omap.c	2005-03-01 23:39:16 -08:00
@@ -934,13 +934,14 @@
 
 static void b_peripheral(struct isp1301 *isp)
 {
-	enable_vbus_draw(isp, 8);
 	OTG_CTRL_REG = OTG_CTRL_REG & OTG_XCEIV_OUTPUTS;
 	usb_gadget_vbus_connect(isp->otg.gadget);
 
 #ifdef	CONFIG_USB_OTG
+	enable_vbus_draw(isp, 8);
 	otg_update_isp(isp);
 #else
+	enable_vbus_draw(isp, 100);
 	/* UDC driver just set OTG_BSESSVLD */
 	isp1301_set_bits(isp, ISP1301_OTG_CONTROL_1, OTG1_DP_PULLUP);
 	isp1301_clear_bits(isp, ISP1301_OTG_CONTROL_1, OTG1_DP_PULLDOWN);
@@ -950,7 +951,7 @@
 #endif
 }
 
-static int isp_update_otg(struct isp1301 *isp, u8 stat)
+static void isp_update_otg(struct isp1301 *isp, u8 stat)
 {
 	u8			isp_stat, isp_bstat;
 	enum usb_otg_state	state = isp->otg.state;
@@ -1489,11 +1490,9 @@
 	if (the_transceiver)
 		return 0;
 
-	isp = kmalloc(sizeof *isp, GFP_KERNEL);
+	isp = kcalloc(1, sizeof *isp, GFP_KERNEL);
 	if (!isp)
 		return 0;
-
-	memset(isp, 0, sizeof *isp);
 
 	INIT_WORK(&isp->work, isp1301_work, isp);
 	init_timer(&isp->timer);
diff -Nru a/drivers/i2c/chips/it87.c b/drivers/i2c/chips/it87.c
--- a/drivers/i2c/chips/it87.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/i2c/chips/it87.c	2005-03-01 23:39:08 -08:00
@@ -2,8 +2,8 @@
     it87.c - Part of lm_sensors, Linux kernel modules for hardware
              monitoring.
 
-    Supports: IT8705F  Super I/O chip w/LPC interface
-              IT8712F  Super I/O chip w/LPC interface & SMbus
+    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> 
@@ -42,10 +42,8 @@
 
 
 /* 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 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 */
@@ -56,6 +54,7 @@
 #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)
@@ -64,6 +63,16 @@
 	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)
 {
@@ -87,18 +96,14 @@
 	outb(0x02, VAL);
 }
 
-/* just IT8712F for now - this should be extended to support the other
-   chips as well */
 #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;
 
-/* Reset the registers on init if true */
-static int reset;
-
 /* Chip Type */
 
 static u16 chip_type;
@@ -128,6 +133,8 @@
 #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))
@@ -164,6 +171,9 @@
 
 #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;
@@ -200,6 +210,8 @@
 	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 */
 };
 
 
@@ -224,8 +236,6 @@
 	.detach_client	= it87_detach_client,
 };
 
-static int it87_id;
-
 static ssize_t show_in(struct device *dev, char *buf, int nr)
 {
 	struct it87_data *data = it87_update_device(dev);
@@ -440,18 +450,28 @@
 {
 	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])) );
+				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])) );
+		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]) );
+	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)
@@ -486,7 +506,7 @@
 		else
 			data->fan_div[nr] = 3;
 	}
-	val = old & 0x100;
+	val = old & 0x80;
 	val |= (data->fan_div[0] & 0x07);
 	val |= (data->fan_div[1] & 0x07) << 3;
 	if (data->fan_div[2] == 3)
@@ -499,6 +519,48 @@
 	}
 	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);
+
+	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
+		return -EINVAL;
+
+	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;
+
+	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]));
+
+	return count;
+}
 
 #define show_fan_offset(offset)						\
 static ssize_t show_fan_##offset (struct device *dev, char *buf)	\
@@ -533,6 +595,36 @@
 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)
 {
@@ -587,25 +679,33 @@
 /* SuperIO detection - will change normal_isa[0] if a chip is found */
 static int it87_find(int *address)
 {
-	u16 val;
+	int err = -ENODEV;
 
 	superio_enter();
-	chip_type = (superio_inb(DEVID) << 8) |
-	       superio_inb(DEVID + 1);
-	if (chip_type != IT8712F_DEVID) {
-		superio_exit();
-		return -ENODEV;
-	}
+	chip_type = superio_inw(DEVID);
+	if (chip_type != IT8712F_DEVID
+	 && chip_type != IT8705F_DEVID)
+	 	goto exit;
 
 	superio_select();
-	val = (superio_inb(IT87_BASE_REG) << 8) |
-	       superio_inb(IT87_BASE_REG + 1);
-	superio_exit();
-	*address = val & ~(IT87_EXTENT - 1);
+	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) {
-		return -ENODEV;
+		pr_info("it87: Base address not set, skipping\n");
+		goto exit;
 	}
-	return 0;
+
+	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 */
@@ -617,6 +717,8 @@
 	int err = 0;
 	const char *name = "";
 	int is_isa = i2c_is_isa_adapter(adapter);
+	int enable_pwm_interface;
+	int tmp;
 
 	if (!is_isa && 
 	    !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
@@ -624,7 +726,7 @@
 
 	/* Reserve the ISA region */
 	if (is_isa)
-		if (!request_region(address, IT87_EXTENT, name))
+		if (!request_region(address, IT87_EXTENT, it87_driver.name))
 			goto ERROR0;
 
 	/* Probe whether there is anything available on this address. Already
@@ -712,10 +814,7 @@
 
 	/* Fill in the remaining client fields and put it into the global list */
 	strlcpy(new_client->name, name, I2C_NAME_SIZE);
-
 	data->type = kind;
-
-	new_client->id = it87_id++;
 	data->valid = 0;
 	init_MUTEX(&data->update_lock);
 
@@ -726,6 +825,17 @@
 	/* Initialize the IT87 chip */
 	it87_init_client(new_client, data);
 
+	/* 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. */
+	enable_pwm_interface = 1;
+	tmp = it87_read_value(new_client, IT87_REG_FAN_CTL);
+	if ((tmp & 0x87) == 0) {
+		enable_pwm_interface = 0;
+		dev_info(&new_client->dev,
+			"detected broken BIOS defaults, disabling pwm interface");
+	}
+
 	/* Register sysfs hooks */
 	device_create_file(&new_client->dev, &dev_attr_in0_input);
 	device_create_file(&new_client->dev, &dev_attr_in1_input);
@@ -774,6 +884,14 @@
 	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) {
 		device_create_file_vrm(new_client);
@@ -851,12 +969,17 @@
 /* Called when we have found a new IT87. */
 static void it87_init_client(struct i2c_client *client, struct it87_data *data)
 {
-	int tmp;
+	int tmp, i;
 
-	if (reset) {
-		/* Reset all except Watchdog values and last conversion values
-		   This sets fan-divs to 2, among others */
-		it87_write_value(client, IT87_REG_CONFIG, 0x80);
+	/* 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 */
@@ -876,13 +999,31 @@
 	}
 
 	/* Check if tachometers are reset manually or by some reason */
-	tmp = it87_read_value(client, IT87_REG_FAN_MAIN_CTRL);
-	if ((tmp & 0x70) == 0) {
+	data->fan_main_ctrl = it87_read_value(client, IT87_REG_FAN_MAIN_CTRL);
+	if ((data->fan_main_ctrl & 0x70) == 0) {
 		/* Enable all fan tachometers */
-		tmp = (tmp & 0x8f) | 0x70;
-		it87_write_value(client, IT87_REG_FAN_MAIN_CTRL, tmp);
+		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)
@@ -948,6 +1089,7 @@
 			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 */
@@ -984,8 +1126,6 @@
 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(reset, bool, 0);
-MODULE_PARM_DESC(reset, "Reset the chip's registers, default no");
 MODULE_LICENSE("GPL");
 
 module_init(sm_it87_init);
diff -Nru a/drivers/i2c/chips/lm63.c b/drivers/i2c/chips/lm63.c
--- a/drivers/i2c/chips/lm63.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/i2c/chips/lm63.c	2005-03-01 23:39:18 -08:00
@@ -464,8 +464,8 @@
 		(data->config & 0x04) ? "tachometer input" :
 		"alert output");
 	dev_dbg(&client->dev, "PWM clock %s kHz, output frequency %u Hz\n",
-		(data->config_fan & 0x04) ? "1.4" : "360",
-		((data->config_fan & 0x04) ? 700 : 180000) / data->pwm1_freq);
+		(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");
diff -Nru a/drivers/i2c/chips/lm78.c b/drivers/i2c/chips/lm78.c
--- a/drivers/i2c/chips/lm78.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/i2c/chips/lm78.c	2005-03-01 23:39:09 -08:00
@@ -462,7 +462,7 @@
 
 	/* Reserve the ISA region */
 	if (is_isa)
-		if (!request_region(address, LM78_EXTENT, "lm78")) {
+		if (!request_region(address, LM78_EXTENT, lm78_driver.name)) {
 			err = -EBUSY;
 			goto ERROR0;
 		}
diff -Nru a/drivers/i2c/chips/lm85.c b/drivers/i2c/chips/lm85.c
--- a/drivers/i2c/chips/lm85.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/i2c/chips/lm85.c	2005-03-01 23:38:55 -08:00
@@ -36,7 +36,7 @@
 static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
 
 /* Insmod parameters */
-SENSORS_INSMOD_4(lm85b, lm85c, adm1027, adt7463);
+SENSORS_INSMOD_5(lm85b, lm85c, adm1027, adt7463, emc6d100);
 
 /* The LM85 registers */
 
@@ -66,11 +66,15 @@
 #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_EMC6D100_A0        0x60
+#define	LM85_VERSTEP_EMC6D100_A1        0x61
 
 #define	LM85_REG_CONFIG			0x40
 
@@ -105,6 +109,12 @@
 #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	LM85_ALARM_IN0			0x0001
 #define	LM85_ALARM_IN1			0x0002
 #define	LM85_ALARM_IN2			0x0004
@@ -135,7 +145,8 @@
 
 /* IN are scaled acording to built-in resistors */
 static int lm85_scaling[] = {  /* .001 Volts */
-		2500, 2250, 3300, 5000, 12000
+		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))
@@ -331,9 +342,9 @@
 	unsigned long last_reading;	/* In jiffies */
 	unsigned long last_config;	/* In jiffies */
 
-	u8 in[5];		/* Register value */
-	u8 in_max[5];		/* Register value */
-	u8 in_min[5];		/* Register value */
+	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 */
@@ -353,7 +364,7 @@
 	u16 tmin_ctl;		/* Register value */
 	unsigned long therm_total; /* Cummulative therm count */
 	u8 therm_limit;		/* Register value */
-	u16 alarms;		/* Register encoding, combined */
+	u32 alarms;		/* Register encoding, combined */
 	struct lm85_autofan autofan[3];
 	struct lm85_zone zone[3];
 };
@@ -1072,7 +1083,7 @@
 		    && verstep == LM85_VERSTEP_LM85B ) {
 			kind = lm85b ;
 		} else if( company == LM85_COMPANY_NATIONAL
-		    && (verstep & 0xf0) == LM85_VERSTEP_GENERIC ) {
+		    && (verstep & LM85_VERSTEP_VMASK) == LM85_VERSTEP_GENERIC ) {
 			dev_err(&adapter->dev, "Unrecognized version/stepping 0x%02x"
 				" Defaulting to LM85.\n", verstep);
 			kind = any_chip ;
@@ -1083,17 +1094,34 @@
 		    && verstep == LM85_VERSTEP_ADT7463 ) {
 			kind = adt7463 ;
 		} else if( company == LM85_COMPANY_ANALOG_DEV
-		    && (verstep & 0xf0) == LM85_VERSTEP_GENERIC ) {
+		    && (verstep & LM85_VERSTEP_VMASK) == LM85_VERSTEP_GENERIC ) {
 			dev_err(&adapter->dev, "Unrecognized version/stepping 0x%02x"
-				" Defaulting to ADM1027.\n", verstep);
-			kind = adm1027 ;
-		} else if( kind == 0 && (verstep & 0xf0) == 0x60) {
+				" 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_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 == 0 ) {  /* User used force=x,y */
+			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 );
@@ -1114,6 +1142,8 @@
 		type_name = "adm1027";
 	} else if ( kind == adt7463 ) {
 		type_name = "adt7463";
+	} else if ( kind == emc6d100){
+		type_name = "emc6d100";
 	}
 	strlcpy(new_client->name, type_name, I2C_NAME_SIZE);
 
@@ -1365,15 +1395,24 @@
 			    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;
 		}
 
-		data->alarms = lm85_read_value(client, LM85_REG_ALARM1);
-
 		data->last_reading = jiffies ;
 	};  /* last_reading */
 
@@ -1387,6 +1426,15 @@
 			    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) {
diff -Nru a/drivers/i2c/chips/lm90.c b/drivers/i2c/chips/lm90.c
--- a/drivers/i2c/chips/lm90.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/i2c/chips/lm90.c	2005-03-01 23:38:52 -08:00
@@ -35,12 +35,13 @@
  * Among others, it has a higher accuracy than the LM90, much like the
  * LM86 does.
  *
- * This driver also supports the MAX6657 and MAX6658, sensor chips made
- * by Maxim. These chips are similar to the LM86. Complete datasheet
- * can be obtained at Maxim's website at:
+ * 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 way to differenciate between both chips (but
- * no need either).
+ * 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.
  *
  * Since the LM90 was the first chipset supported by this driver, most
  * comments will refer to this chipset, but are actually general and
@@ -70,9 +71,11 @@
 
 /*
  * Addresses to scan
- * Address is fully defined internally and cannot be changed.
+ * 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).
  */
 
 static unsigned short normal_i2c[] = { 0x4c, 0x4d, I2C_CLIENT_END };
@@ -386,8 +389,17 @@
 			}
 		} else
 		if (man_id == 0x4D) { /* Maxim */
-			if (address == 0x4C
-			 && (reg_config1 & 0x1F) == 0
+			/*
+			 * 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;
 			}
diff -Nru a/drivers/i2c/chips/pc87360.c b/drivers/i2c/chips/pc87360.c
--- a/drivers/i2c/chips/pc87360.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/i2c/chips/pc87360.c	2005-03-01 23:38:54 -08:00
@@ -756,7 +756,8 @@
 
 	for (i = 0; i < 3; i++) {
 		if (((data->address[i] = extra_isa[i]))
-		 && !request_region(extra_isa[i], PC87360_EXTENT, "pc87360")) {
+		 && !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);
@@ -794,8 +795,10 @@
 
 	/* Fan clock dividers may be needed before any data is read */
 	for (i = 0; i < data->fannr; i++) {
-		data->fan_status[i] = pc87360_read_value(data, LD_FAN,
-				      NO_BANK, PC87360_REG_FAN_STATUS(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) {
@@ -897,14 +900,27 @@
 	}
 
 	if (data->fannr) {
-		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_fan1_status);
-		device_create_file(&new_client->dev, &dev_attr_fan2_status);
+		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);
@@ -912,10 +928,16 @@
 			device_create_file(&new_client->dev, &dev_attr_pwm2);
 	}
 	if (data->fannr == 3) {
-		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_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);
diff -Nru a/drivers/i2c/chips/smsc47b397.c b/drivers/i2c/chips/smsc47b397.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/i2c/chips/smsc47b397.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,353 @@
+/*
+    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/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, (unsigned long)HZ)
+		|| time_before(jiffies, data->last_updated) || !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 -Nru a/drivers/i2c/chips/smsc47m1.c b/drivers/i2c/chips/smsc47m1.c
--- a/drivers/i2c/chips/smsc47m1.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/i2c/chips/smsc47m1.c	2005-03-01 23:38:54 -08:00
@@ -400,7 +400,7 @@
 		return 0;
 	}
 
-	if (!request_region(address, SMSC_EXTENT, "smsc47m1")) {
+	if (!request_region(address, SMSC_EXTENT, smsc47m1_driver.name)) {
 		dev_err(&adapter->dev, "Region 0x%x already in use!\n", address);
 		return -EBUSY;
 	}
diff -Nru a/drivers/i2c/chips/via686a.c b/drivers/i2c/chips/via686a.c
--- a/drivers/i2c/chips/via686a.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/i2c/chips/via686a.c	2005-03-01 23:38:52 -08:00
@@ -613,7 +613,7 @@
 	}
 
 	/* Reserve the ISA region */
-	if (!request_region(address, VIA686A_EXTENT, "via686a-sensor")) {
+	if (!request_region(address, VIA686A_EXTENT, via686a_driver.name)) {
 		dev_err(&adapter->dev,"region 0x%x already in use!\n",
 		       address);
 		return -ENODEV;
@@ -786,15 +786,12 @@
 }
 
 static struct pci_device_id via686a_pci_ids[] = {
-       {
-	       .vendor 		= PCI_VENDOR_ID_VIA, 
-	       .device 		= PCI_DEVICE_ID_VIA_82C686_4, 
-	       .subvendor	= PCI_ANY_ID, 
-	       .subdevice	= PCI_ANY_ID, 
-       },
+       { 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)
 {
@@ -818,20 +815,24 @@
                return -ENODEV;
        }
        normal_isa[0] = addr;
-       s_bridge = dev;
-       return i2c_add_driver(&via686a_driver);
-}
 
-static void __devexit via686a_pci_remove(struct pci_dev *dev)
-{
-       i2c_del_driver(&via686a_driver);
+	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,
-       .remove		= __devexit_p(via686a_pci_remove),
 };
 
 static int __init sm_via686a_init(void)
@@ -841,7 +842,12 @@
 
 static void __exit sm_via686a_exit(void)
 {
-       pci_unregister_driver(&via686a_pci_driver);
+	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>, "
diff -Nru a/drivers/i2c/chips/w83627hf.c b/drivers/i2c/chips/w83627hf.c
--- a/drivers/i2c/chips/w83627hf.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/i2c/chips/w83627hf.c	2005-03-01 23:39:08 -08:00
@@ -67,9 +67,9 @@
 MODULE_PARM_DESC(init, "Set to zero to bypass chip initialization");
 
 /* modified from kernel/include/traps.c */
-#define	REG	0x2e	/* The register to read/write */
+static int REG;		/* The register to read/write */
 #define	DEV	0x07	/* Register: Logical device select */
-#define	VAL	0x2f	/* The value to read/write */
+static int VAL;		/* The value to read/write */
 
 /* logical device numbers for superio_select (below) */
 #define W83627HF_LD_FDC		0x00
@@ -90,9 +90,9 @@
 
 #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 */
-#define W83627THF_GPIO5_INVR	0xf5 /* w83627thf only */
 
 static inline void
 superio_outb(int reg, int val)
@@ -938,10 +938,13 @@
 	return i2c_detect(adapter, &addr_data, w83627hf_detect);
 }
 
-static int w83627hf_find(int *address)
+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 &&
@@ -984,7 +987,7 @@
 	if(force_addr)
 		address = force_addr & ~(WINB_EXTENT - 1);
 
-	if (!request_region(address, WINB_EXTENT, "w83627hf")) {
+	if (!request_region(address, WINB_EXTENT, w83627hf_driver.name)) {
 		err = -EBUSY;
 		goto ERROR0;
 	}
@@ -1187,16 +1190,31 @@
 
 static int w83627thf_read_gpio5(struct i2c_client *client)
 {
-	struct w83627hf_data *data = i2c_get_clientdata(client);
-	int res, inv;
+	int res = 0xff, sel;
 
-	down(&data->lock);
 	superio_enter();
 	superio_select(W83627HF_LD_GPIO5);
-	res = superio_inb(W83627THF_GPIO5_DR);
-	inv = superio_inb(W83627THF_GPIO5_INVR);
+
+	/* 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();
-	up(&data->lock);
 	return res;
 }
 
@@ -1269,7 +1287,7 @@
 		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) & 0x1f;
+		data->vid = w83627thf_read_gpio5(client) & 0x3f;
 	}
 
 	/* Read VRM & OVT Config only once */
@@ -1422,7 +1440,8 @@
 {
 	int addr;
 
-	if (w83627hf_find(&addr)) {
+	if (w83627hf_find(0x2e, &addr)
+	 && w83627hf_find(0x4e, &addr)) {
 		return -ENODEV;
 	}
 	normal_isa[0] = addr;
diff -Nru a/drivers/i2c/chips/w83781d.c b/drivers/i2c/chips/w83781d.c
--- a/drivers/i2c/chips/w83781d.c	2005-03-01 23:38:43 -08:00
+++ b/drivers/i2c/chips/w83781d.c	2005-03-01 23:38:43 -08:00
@@ -175,11 +175,6 @@
 						: (val)) / 1000, 0, 0xff))
 #define TEMP_FROM_REG(val)		(((val) & 0x80 ? (val)-0x100 : (val)) * 1000)
 
-#define AS99127_TEMP_ADD_TO_REG(val)	(SENSORS_LIMIT((((val) < 0 ? (val)+0x10000*250 \
-						: (val)) / 250) << 7, 0, 0xffff))
-#define AS99127_TEMP_ADD_FROM_REG(val)	((((val) & 0x8000 ? (val)-0x10000 : (val)) \
-						>> 7) * 250)
-
 #define ALARMS_FROM_REG(val)		(val)
 #define PWM_FROM_REG(val)		(val)
 #define PWM_TO_REG(val)			(SENSORS_LIMIT((val),0,255))
@@ -417,13 +412,8 @@
 { \
 	struct w83781d_data *data = w83781d_update_device(dev); \
 	if (nr >= 2) {	/* TEMP2 and TEMP3 */ \
-		if (data->type == as99127f) { \
-			return sprintf(buf,"%ld\n", \
-				(long)AS99127_TEMP_ADD_FROM_REG(data->reg##_add[nr-2])); \
-		} else { \
-			return sprintf(buf,"%d\n", \
-				LM75_TEMP_FROM_REG(data->reg##_add[nr-2])); \
-		} \
+		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)); \
 	} \
@@ -442,11 +432,7 @@
 	val = simple_strtol(buf, NULL, 10); \
 	 \
 	if (nr >= 2) {	/* TEMP2 and TEMP3 */ \
-		if (data->type == as99127f) \
-			data->temp_##reg##_add[nr-2] = AS99127_TEMP_ADD_TO_REG(val); \
-		else \
-			data->temp_##reg##_add[nr-2] = LM75_TEMP_TO_REG(val); \
-		 \
+		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 */ \
@@ -1065,7 +1051,8 @@
 	}
 	
 	if (is_isa)
-		if (!request_region(address, W83781D_EXTENT, "w83781d")) {
+		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);
diff -Nru a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c
--- a/drivers/i2c/i2c-dev.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/i2c/i2c-dev.c	2005-03-01 23:39:08 -08:00
@@ -53,7 +53,7 @@
 
 #define I2C_MINORS	256
 static struct i2c_dev *i2c_dev_array[I2C_MINORS];
-static spinlock_t i2c_dev_array_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(i2c_dev_array_lock);
 
 struct i2c_dev *i2c_dev_get_by_minor(unsigned index)
 {
diff -Nru a/drivers/i2c/i2c-sensor-vid.c b/drivers/i2c/i2c-sensor-vid.c
--- a/drivers/i2c/i2c-sensor-vid.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/i2c/i2c-sensor-vid.c	2005-03-01 23:39:09 -08:00
@@ -36,8 +36,7 @@
 
 static struct vrm_model vrm_models[] = {
 	{X86_VENDOR_AMD, 0x6, ANY, 90},		/* Athlon Duron etc */
-	{X86_VENDOR_AMD, 0xF, 0x4, 90},		/* Athlon 64 */
-	{X86_VENDOR_AMD, 0xF, 0x5, 24},		/* Opteron */
+	{X86_VENDOR_AMD, 0xF, ANY, 24},		/* Athlon 64, Opteron */
 	{X86_VENDOR_INTEL, 0x6, 0x9, 85},	/* 0.13um too */
 	{X86_VENDOR_INTEL, 0x6, 0xB, 85},	/* 0xB Tualatin */
 	{X86_VENDOR_INTEL, 0x6, ANY, 82},	/* any P6 */
@@ -87,7 +86,7 @@
 	return vrm_ret;
 }
 
-/* and now something completely different for Non-x86 world*/
+/* and now for something completely different for Non-x86 world*/
 #else
 int i2c_which_vrm(void)
 {
diff -Nru a/drivers/ide/Kconfig b/drivers/ide/Kconfig
--- a/drivers/ide/Kconfig	2005-03-01 23:38:57 -08:00
+++ b/drivers/ide/Kconfig	2005-03-01 23:38:57 -08:00
@@ -812,7 +812,7 @@
 
 config BLK_DEV_IDE_BAST
 	tristate "Simtec BAST / Thorcom VR1000 IDE support"
-	depends on ARM && (ARCH_BAST || MACH_VR100)
+	depends on ARM && (ARCH_BAST || MACH_VR1000)
 	help
 	  Say Y here if you want to support the onboard IDE channels on the
 	  Simtec BAST or the Thorcom VR1000
diff -Nru a/drivers/ide/arm/icside.c b/drivers/ide/arm/icside.c
--- a/drivers/ide/arm/icside.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/ide/arm/icside.c	2005-03-01 23:38:57 -08:00
@@ -397,35 +397,6 @@
 	enable_dma(hwif->hw.dma);
 }
 
-/*
- * dma_intr() is the handler for disk read/write DMA interrupts
- */
-static ide_startstop_t icside_dmaintr(ide_drive_t *drive)
-{
-	unsigned int stat;
-	int dma_stat;
-
-	dma_stat = icside_dma_end(drive);
-	stat = HWIF(drive)->INB(IDE_STATUS_REG);
-	if (OK_STAT(stat, DRIVE_READY, drive->bad_wstat | DRQ_STAT)) {
-		if (!dma_stat) {
-			struct request *rq = HWGROUP(drive)->rq;
-			int i;
-
-			for (i = rq->nr_sectors; i > 0; ) {
-				i -= rq->current_nr_sectors;
-				DRIVER(drive)->end_request(drive, 1, rq->nr_sectors);
-			}
-
-			return ide_stopped;
-		}
-		printk(KERN_ERR "%s: bad DMA status (dma_stat=%x)\n",
-		       drive->name, dma_stat);
-	}
-
-	return DRIVER(drive)->error(drive, __FUNCTION__, stat);
-}
-
 static int icside_dma_setup(ide_drive_t *drive)
 {
 	ide_hwif_t *hwif = HWIF(drive);
@@ -474,7 +445,7 @@
 static void icside_dma_exec_cmd(ide_drive_t *drive, u8 cmd)
 {
 	/* issue cmd to drive */
-	ide_execute_command(drive, cmd, icside_dmaintr, 2*WAIT_CMD, NULL);
+	ide_execute_command(drive, cmd, ide_dma_intr, 2 * WAIT_CMD, NULL);
 }
 
 static int icside_dma_test_irq(ide_drive_t *drive)
diff -Nru a/drivers/ide/cris/ide-v10.c b/drivers/ide/cris/ide-v10.c
--- a/drivers/ide/cris/ide-v10.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/ide/cris/ide-v10.c	2005-03-01 23:38:57 -08:00
@@ -753,27 +753,10 @@
  */
 static ide_startstop_t etrax_dma_intr (ide_drive_t *drive)
 {
-	int i, dma_stat;
-	byte stat;
-
 	LED_DISK_READ(0);
 	LED_DISK_WRITE(0);
 
-	dma_stat = HWIF(drive)->ide_dma_end(drive);
-	stat = HWIF(drive)->INB(IDE_STATUS_REG);		/* get drive status */
-	if (OK_STAT(stat,DRIVE_READY,drive->bad_wstat|DRQ_STAT)) {
-		if (!dma_stat) {
-			struct request *rq;
-			rq = HWGROUP(drive)->rq;
-			for (i = rq->nr_sectors; i > 0;) {
-				i -= rq->current_nr_sectors;
-				DRIVER(drive)->end_request(drive, 1, rq->nr_sectors);
-			}
-			return ide_stopped;
-		}
-		printk("%s: bad DMA status\n", drive->name);
-	}
-	return DRIVER(drive)->error(drive, "dma_intr", stat);
+	return ide_dma_intr(drive);
 }
 
 /*
diff -Nru a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
--- a/drivers/ide/ide-cd.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/ide/ide-cd.c	2005-03-01 23:38:56 -08:00
@@ -456,7 +456,7 @@
 				s = "(reserved error code)";
 		}
 
-		printk("  %s -- (asc=0x%02x, ascq=0x%02x)\n",
+		printk(KERN_ERR "  %s -- (asc=0x%02x, ascq=0x%02x)\n",
 			s, sense->asc, sense->ascq);
 
 		if (failed_command != NULL) {
@@ -478,7 +478,7 @@
 					lo = mid+1;
 			}
 
-			printk ("  The failed \"%s\" packet command was: \n  \"", s);
+			printk (KERN_ERR "  The failed \"%s\" packet command was: \n  \"", s);
 			for (i=0; i<sizeof (failed_command->cmd); i++)
 				printk ("%02x ", failed_command->cmd[i]);
 			printk ("\"\n");
@@ -491,13 +491,13 @@
 		 */
 		if (sense->sense_key == NOT_READY && (sense->sks[0] & 0x80)) {
 			int progress = (sense->sks[1] << 8 | sense->sks[2]) * 100;
-			printk("  Command is %02d%% complete\n", progress / 0xffff);
+			printk(KERN_ERR "  Command is %02d%% complete\n", progress / 0xffff);
 
 		}
 
 		if (sense->sense_key == ILLEGAL_REQUEST &&
 		    (sense->sks[0] & 0x80) != 0) {
-			printk("  Error in %s byte %d",
+			printk(KERN_ERR "  Error in %s byte %d",
 				(sense->sks[0] & 0x40) != 0 ?
 				"command packet" : "command data",
 				(sense->sks[1] << 8) + sense->sks[2]);
@@ -519,7 +519,7 @@
 						sense->asc == 0x3a)))
 		return;
 
-	printk("%s: error code: 0x%02x  sense_key: 0x%02x  asc: 0x%02x  ascq: 0x%02x\n",
+	printk(KERN_ERR "%s: error code: 0x%02x  sense_key: 0x%02x  asc: 0x%02x  ascq: 0x%02x\n",
 		drive->name,
 		sense->error_code, sense->sense_key,
 		sense->asc, sense->ascq);
@@ -559,62 +559,6 @@
 	(void) ide_do_drive_cmd(drive, rq, ide_preempt);
 }
 
-/*
- * ide_error() takes action based on the error returned by the drive.
- */
-static ide_startstop_t ide_cdrom_error (ide_drive_t *drive, const char *msg, byte stat)
-{
-	struct request *rq;
-	byte err;
-
-	err = ide_dump_atapi_status(drive, msg, stat);
-	if (drive == NULL || (rq = HWGROUP(drive)->rq) == NULL)
-		return ide_stopped;
-	/* retry only "normal" I/O: */
-	if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK | REQ_DRIVE_TASKFILE)) {
-		rq->errors = 1;
-		ide_end_drive_cmd(drive, stat, err);
-		return ide_stopped;
-	}
-
-	if (stat & BUSY_STAT || ((stat & WRERR_STAT) && !drive->nowerr)) {
-		/* other bits are useless when BUSY */
-		rq->errors |= ERROR_RESET;
-	} else {
-		/* add decoding error stuff */
-	}
-	if (HWIF(drive)->INB(IDE_STATUS_REG) & (BUSY_STAT|DRQ_STAT))
-		/* force an abort */
-		HWIF(drive)->OUTB(WIN_IDLEIMMEDIATE,IDE_COMMAND_REG);
-	if (rq->errors >= ERROR_MAX) {
-		DRIVER(drive)->end_request(drive, 0, 0);
-	} else {
-		if ((rq->errors & ERROR_RESET) == ERROR_RESET) {
-			++rq->errors;
-			return ide_do_reset(drive);
-		}
-		++rq->errors;
-	}
-	return ide_stopped;
-}
-
-static ide_startstop_t ide_cdrom_abort (ide_drive_t *drive, const char *msg)
-{
-	struct request *rq;
-
-	if (drive == NULL || (rq = HWGROUP(drive)->rq) == NULL)
-		return ide_stopped;
-	/* retry only "normal" I/O: */
-	if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK | REQ_DRIVE_TASKFILE)) {
-		rq->errors = 1;
-		ide_end_drive_cmd(drive, BUSY_STAT, 0);
-		return ide_stopped;
-	}
-	rq->errors |= ERROR_RESET;
-	DRIVER(drive)->end_request(drive, 0, 0);
-	return ide_stopped;
-}
-
 static void cdrom_end_request (ide_drive_t *drive, int uptodate)
 {
 	struct request *rq = HWGROUP(drive)->rq;
@@ -690,7 +634,7 @@
 
 		rq->flags |= REQ_FAILED;
 		cdrom_end_request(drive, 0);
-		DRIVER(drive)->error(drive, "request sense failure", stat);
+		ide_error(drive, "request sense failure", stat);
 		return 1;
 
 	} else if (rq->flags & (REQ_PC | REQ_BLOCK_PC)) {
@@ -801,7 +745,7 @@
 		} else if ((err & ~ABRT_ERR) != 0) {
 			/* Go to the default handler
 			   for other errors. */
-			DRIVER(drive)->error(drive, "cdrom_decode_status",stat);
+			ide_error(drive, "cdrom_decode_status", stat);
 			return 1;
 		} else if ((++rq->errors > ERROR_MAX)) {
 			/* We've racked up too many retries.  Abort. */
@@ -1014,7 +958,7 @@
 		return 0;
 	else if (ireason == 0) {
 		/* Whoops... The drive is expecting to receive data from us! */
-		printk("%s: read_intr: Drive wants to transfer data the "
+		printk(KERN_ERR "%s: read_intr: Drive wants to transfer data the "
 						"wrong way!\n", drive->name);
 
 		/* Throw some data at the drive so it doesn't hang
@@ -1032,7 +976,7 @@
 		return 0;
 	} else {
 		/* Drive wants a command packet, or invalid ireason... */
-		printk("%s: read_intr: bad interrupt reason %x\n", drive->name,
+		printk(KERN_ERR "%s: read_intr: bad interrupt reason %x\n", drive->name,
 								ireason);
 	}
 
@@ -1070,7 +1014,7 @@
 			ide_end_request(drive, 1, rq->nr_sectors);
 			return ide_stopped;
 		} else
-			return DRIVER(drive)->error(drive, "dma error", stat);
+			return ide_error(drive, "dma error", stat);
 	}
 
 	/* Read the interrupt reason and the transfer length. */
@@ -1085,7 +1029,7 @@
 		/* If we're not done filling the current buffer, complain.
 		   Otherwise, complete the command normally. */
 		if (rq->current_nr_sectors > 0) {
-			printk ("%s: cdrom_read_intr: data underrun (%d blocks)\n",
+			printk (KERN_ERR "%s: cdrom_read_intr: data underrun (%d blocks)\n",
 				drive->name, rq->current_nr_sectors);
 			rq->flags |= REQ_FAILED;
 			cdrom_end_request(drive, 0);
@@ -1102,12 +1046,12 @@
 	   of at least SECTOR_SIZE, as it gets hairy to keep track
 	   of the transfers otherwise. */
 	if ((len % SECTOR_SIZE) != 0) {
-		printk ("%s: cdrom_read_intr: Bad transfer size %d\n",
+		printk (KERN_ERR "%s: cdrom_read_intr: Bad transfer size %d\n",
 			drive->name, len);
 		if (CDROM_CONFIG_FLAGS(drive)->limit_nframes)
-			printk ("  This drive is not supported by this version of the driver\n");
+			printk (KERN_ERR "  This drive is not supported by this version of the driver\n");
 		else {
-			printk ("  Trying to limit transfer sizes\n");
+			printk (KERN_ERR "  Trying to limit transfer sizes\n");
 			CDROM_CONFIG_FLAGS(drive)->limit_nframes = 1;
 		}
 		cdrom_end_request(drive, 0);
@@ -1221,7 +1165,7 @@
 	   paranoid and check. */
 	if (rq->current_nr_sectors < bio_cur_sectors(rq->bio) &&
 	    (rq->sector & (sectors_per_frame - 1))) {
-		printk("%s: cdrom_read_from_buffer: buffer botch (%ld)\n",
+		printk(KERN_ERR "%s: cdrom_read_from_buffer: buffer botch (%ld)\n",
 			drive->name, (long)rq->sector);
 		cdrom_end_request(drive, 0);
 		return -1;
@@ -1256,7 +1200,7 @@
 		/* Sanity check... */
 		if (rq->current_nr_sectors != bio_cur_sectors(rq->bio) &&
 			(rq->sector & (sectors_per_frame - 1))) {
-			printk ("%s: cdrom_start_read_continuation: buffer botch (%u)\n",
+			printk(KERN_ERR "%s: cdrom_start_read_continuation: buffer botch (%u)\n",
 				drive->name, rq->current_nr_sectors);
 			cdrom_end_request(drive, 0);
 			return ide_stopped;
@@ -1481,7 +1425,7 @@
 			rq->sense_len += thislen;
 	} else {
 confused:
-		printk ("%s: cdrom_pc_intr: The drive "
+		printk (KERN_ERR "%s: cdrom_pc_intr: The drive "
 			"appears confused (ireason = 0x%02x)\n",
 			drive->name, ireason);
 		rq->flags |= REQ_FAILED;
@@ -1520,19 +1464,6 @@
 }
 
 
-/* Sleep for TIME jiffies.
-   Not to be called from an interrupt handler. */
-static
-void cdrom_sleep (int time)
-{
-	int sleep = time;
-
-	do {
-		set_current_state(TASK_INTERRUPTIBLE);
-		sleep = schedule_timeout(sleep);
-	} while (sleep);
-}
-
 static
 int cdrom_queue_packet_command(ide_drive_t *drive, struct request *rq)
 {
@@ -1567,7 +1498,7 @@
 				/* The drive is in the process of loading
 				   a disk.  Retry, but wait a little to give
 				   the drive time to complete the load. */
-				cdrom_sleep(2 * HZ);
+				ssleep(2);
 			} else {
 				/* Otherwise, don't retry. */
 				retries = 0;
@@ -1595,7 +1526,7 @@
 		return 0;
 	else if (ireason == 2) {
 		/* Whoops... The drive wants to send data. */
-		printk("%s: write_intr: wrong transfer direction!\n",
+		printk(KERN_ERR "%s: write_intr: wrong transfer direction!\n",
 							drive->name);
 
 		while (len > 0) {
@@ -1605,7 +1536,7 @@
 		}
 	} else {
 		/* Drive wants a command packet, or invalid ireason... */
-		printk("%s: write_intr: bad interrupt reason %x\n",
+		printk(KERN_ERR "%s: write_intr: bad interrupt reason %x\n",
 							drive->name, ireason);
 	}
 
@@ -1671,9 +1602,9 @@
 	 */
 	if (dma) {
 		if (dma_error) {
-			printk("ide-cd: dma error\n");
+			printk(KERN_ERR "ide-cd: dma error\n");
 			__ide_dma_off(drive);
-			return DRIVER(drive)->error(drive, "dma error", stat);
+			return ide_error(drive, "dma error", stat);
 		}
 
 		end_that_request_chunk(rq, 1, rq->data_len);
@@ -1736,7 +1667,7 @@
 		}
 
 		if (!ptr) {
-			printk("%s: confused, missing data\n", drive->name);
+			printk(KERN_ERR "%s: confused, missing data\n", drive->name);
 			break;
 		}
 
@@ -1798,7 +1729,7 @@
 	if (dma) {
 		info->dma = 0;
 		if ((dma_error = HWIF(drive)->ide_dma_end(drive))) {
-			printk("ide-cd: write dma error\n");
+			printk(KERN_ERR "ide-cd: write dma error\n");
 			__ide_dma_off(drive);
 		}
 	}
@@ -1811,7 +1742,7 @@
 	 */
 	if (dma) {
 		if (dma_error)
-			return DRIVER(drive)->error(drive, "dma error", stat);
+			return ide_error(drive, "dma error", stat);
 
 		ide_end_request(drive, 1, rq->nr_sectors);
 		return ide_stopped;
@@ -1831,7 +1762,7 @@
 		 */
 		uptodate = 1;
 		if (rq->current_nr_sectors > 0) {
-			printk("%s: write_intr: data underrun (%d blocks)\n",
+			printk(KERN_ERR "%s: write_intr: data underrun (%d blocks)\n",
 			drive->name, rq->current_nr_sectors);
 			uptodate = 0;
 		}
@@ -1852,7 +1783,7 @@
 		int this_transfer;
 
 		if (!rq->current_nr_sectors) {
-			printk("ide-cd: write_intr: oops\n");
+			printk(KERN_ERR "ide-cd: write_intr: oops\n");
 			break;
 		}
 
@@ -1998,7 +1929,7 @@
 					ide_stall_queue(drive, IDECD_SEEK_TIMER);
 					return ide_stopped;
 				}
-				printk ("%s: DSC timeout\n", drive->name);
+				printk (KERN_ERR "%s: DSC timeout\n", drive->name);
 			}
 			CDROM_CONFIG_FLAGS(drive)->seeking = 0;
 		}
@@ -2134,7 +2065,7 @@
 	if (stat != 0 &&
 	    sense->sense_key == ILLEGAL_REQUEST &&
 	    (sense->asc == 0x24 || sense->asc == 0x20)) {
-		printk ("%s: door locking not supported\n",
+		printk (KERN_ERR "%s: door locking not supported\n",
 			drive->name);
 		CDROM_CONFIG_FLAGS(drive)->no_doorlock = 1;
 		stat = 0;
@@ -2252,7 +2183,7 @@
 						    GFP_KERNEL);
 		info->toc = toc;
 		if (toc == NULL) {
-			printk ("%s: No cdrom TOC buffer!\n", drive->name);
+			printk (KERN_ERR "%s: No cdrom TOC buffer!\n", drive->name);
 			return -ENOMEM;
 		}
 	}
@@ -2744,9 +2675,9 @@
 	 */
 	if (sense.sense_key == NOT_READY) {
 		if (sense.asc == 0x3a) {
-			if (sense.ascq == 0 || sense.ascq == 1)
+			if (sense.ascq == 1)
 				return CDS_NO_DISC;
-			else if (sense.ascq == 2)
+			else if (sense.ascq == 0 || sense.ascq == 2)
 				return CDS_TRAY_OPEN;
 		}
 	}
@@ -2939,7 +2870,7 @@
 	if (drive->media == ide_optical) {
 		CDROM_CONFIG_FLAGS(drive)->mo_drive = 1;
 		CDROM_CONFIG_FLAGS(drive)->ram = 1;
-		printk("%s: ATAPI magneto-optical drive\n", drive->name);
+		printk(KERN_ERR "%s: ATAPI magneto-optical drive\n", drive->name);
 		return nslots;
 	}
 
@@ -3029,7 +2960,7 @@
 
 	/* don't print speed if the drive reported 0.
 	 */
-	printk("%s: ATAPI", drive->name);
+	printk(KERN_INFO "%s: ATAPI", drive->name);
 	if (CDROM_CONFIG_FLAGS(drive)->max_speed)
 		printk(" %dX", CDROM_CONFIG_FLAGS(drive)->max_speed);
 	printk(" %s", CDROM_CONFIG_FLAGS(drive)->dvd ? "DVD-ROM" : "CD-ROM");
@@ -3272,7 +3203,7 @@
 #endif
 
 	if (ide_cdrom_register(drive, nslots)) {
-		printk ("%s: ide_cdrom_setup failed to register device with the cdrom driver.\n", drive->name);
+		printk (KERN_ERR "%s: ide_cdrom_setup failed to register device with the cdrom driver.\n", drive->name);
 		info->devinfo.handle = NULL;
 		return 1;
 	}
@@ -3299,7 +3230,7 @@
 	struct gendisk *g = drive->disk;
 
 	if (ide_unregister_subdriver(drive)) {
-		printk("%s: %s: failed to ide_unregister_subdriver\n",
+		printk(KERN_ERR "%s: %s: failed to ide_unregister_subdriver\n",
 			__FUNCTION__, drive->name);
 		return 1;
 	}
@@ -3310,7 +3241,7 @@
 	if (info->changer_info != NULL)
 		kfree(info->changer_info);
 	if (devinfo->handle == drive && unregister_cdrom(devinfo))
-		printk("%s: ide_cdrom_cleanup failed to unregister device from the cdrom driver.\n", drive->name);
+		printk(KERN_ERR "%s: ide_cdrom_cleanup failed to unregister device from the cdrom driver.\n", drive->name);
 	kfree(info);
 	drive->driver_data = NULL;
 	blk_queue_prep_rq(drive->queue, NULL);
@@ -3369,9 +3300,6 @@
 	.supports_dsc_overlap	= 1,
 	.cleanup		= ide_cdrom_cleanup,
 	.do_request		= ide_do_rw_cdrom,
-	.sense			= ide_dump_atapi_status,
-	.error			= ide_cdrom_error,
-	.abort			= ide_cdrom_abort,
 	.capacity		= ide_cdrom_capacity,
 	.attach			= ide_cdrom_attach,
 	.drives			= LIST_HEAD_INIT(ide_cdrom_driver.drives),
@@ -3462,21 +3390,21 @@
 	/* skip drives that we were told to ignore */
 	if (ignore != NULL) {
 		if (strstr(ignore, drive->name)) {
-			printk("ide-cd: ignoring drive %s\n", drive->name);
+			printk(KERN_INFO "ide-cd: ignoring drive %s\n", drive->name);
 			goto failed;
 		}
 	}
 	if (drive->scsi) {
-		printk("ide-cd: passing drive %s to ide-scsi emulation.\n", drive->name);
+		printk(KERN_INFO "ide-cd: passing drive %s to ide-scsi emulation.\n", drive->name);
 		goto failed;
 	}
 	info = (struct cdrom_info *) kmalloc (sizeof (struct cdrom_info), GFP_KERNEL);
 	if (info == NULL) {
-		printk("%s: Can't allocate a cdrom structure\n", drive->name);
+		printk(KERN_ERR "%s: Can't allocate a cdrom structure\n", drive->name);
 		goto failed;
 	}
 	if (ide_register_subdriver(drive, &ide_cdrom_driver)) {
-		printk("%s: Failed to register the driver with ide.c\n",
+		printk(KERN_ERR "%s: Failed to register the driver with ide.c\n",
 			drive->name);
 		kfree(info);
 		goto failed;
@@ -3500,7 +3428,7 @@
 		if (info->changer_info != NULL)
 			kfree(info->changer_info);
 		if (devinfo->handle == drive && unregister_cdrom(devinfo))
-			printk ("%s: ide_cdrom_cleanup failed to unregister device from the cdrom driver.\n", drive->name);
+			printk (KERN_ERR "%s: ide_cdrom_cleanup failed to unregister device from the cdrom driver.\n", drive->name);
 		kfree(info);
 		drive->driver_data = NULL;
 		goto failed;
diff -Nru a/drivers/ide/ide-default.c b/drivers/ide/ide-default.c
--- a/drivers/ide/ide-default.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/ide/ide-default.c	2005-03-01 23:39:17 -08:00
@@ -46,6 +46,7 @@
 	.name		=	"ide-default",
 	.version	=	IDEDEFAULT_VERSION,
 	.attach		=	idedefault_attach,
+	.cleanup	=	ide_unregister_subdriver,
 	.drives		=	LIST_HEAD_INIT(idedefault_driver.drives)
 };
 
diff -Nru a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
--- a/drivers/ide/ide-disk.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/ide/ide-disk.c	2005-03-01 23:38:56 -08:00
@@ -119,9 +119,8 @@
 /*
  * __ide_do_rw_disk() issues READ and WRITE commands to a disk,
  * using LBA if supported, or CHS otherwise, to address sectors.
- * It also takes care of issuing special DRIVE_CMDs.
  */
-ide_startstop_t __ide_do_rw_disk (ide_drive_t *drive, struct request *rq, sector_t block)
+static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq, sector_t block)
 {
 	ide_hwif_t *hwif	= HWIF(drive);
 	unsigned int dma	= drive->using_dma;
@@ -132,7 +131,7 @@
 	nsectors.all		= (u16) rq->nr_sectors;
 
 	if (hwif->no_lba48_dma && lba48 && dma) {
-		if (rq->sector + rq->nr_sectors > 1ULL << 28)
+		if (block + rq->nr_sectors > 1ULL << 28)
 			dma = 0;
 	}
 
@@ -253,11 +252,9 @@
 		/* FIXME: ->OUTBSYNC ? */
 		hwif->OUTB(command, IDE_COMMAND_REG);
 
-		pre_task_out_intr(drive, rq);
-		return ide_started;
+		return pre_task_out_intr(drive, rq);
 	}
 }
-EXPORT_SYMBOL_GPL(__ide_do_rw_disk);
 
 /*
  * 268435455  == 137439 MB or 28bit limit
@@ -282,192 +279,9 @@
 		 block, rq->nr_sectors, (unsigned long)rq->buffer);
 
 	if (hwif->rw_disk)
-		return hwif->rw_disk(drive, rq, block);
-	else
-		return __ide_do_rw_disk(drive, rq, block);
-}
-
-static u8 idedisk_dump_status (ide_drive_t *drive, const char *msg, u8 stat)
-{
-	ide_hwif_t *hwif = HWIF(drive);
-	unsigned long flags;
-	u8 err = 0;
-
-	local_irq_set(flags);
-	printk("%s: %s: status=0x%02x", drive->name, msg, stat);
-	printk(" { ");
-	if (stat & BUSY_STAT)
-		printk("Busy ");
-	else {
-		if (stat & READY_STAT)	printk("DriveReady ");
-		if (stat & WRERR_STAT)	printk("DeviceFault ");
-		if (stat & SEEK_STAT)	printk("SeekComplete ");
-		if (stat & DRQ_STAT)	printk("DataRequest ");
-		if (stat & ECC_STAT)	printk("CorrectedError ");
-		if (stat & INDEX_STAT)	printk("Index ");
-		if (stat & ERR_STAT)	printk("Error ");
-	}
-	printk("}");
-	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(" { ");
-		if (err & ABRT_ERR)	printk("DriveStatusError ");
-		if (err & ICRC_ERR)
-			printk("Bad%s ", (err & ABRT_ERR) ? "CRC" : "Sector");
-		if (err & ECC_ERR)	printk("UncorrectableError ");
-		if (err & ID_ERR)	printk("SectorIdNotFound ");
-		if (err & TRK0_ERR)	printk("TrackZeroNotFound ");
-		if (err & MARK_ERR)	printk("AddrMarkNotFound ");
-		printk("}");
-		if ((err & (BBD_ERR | ABRT_ERR)) == BBD_ERR ||
-		    (err & (ECC_ERR|ID_ERR|MARK_ERR))) {
-			if (drive->addressing == 1) {
-				__u64 sectors = 0;
-				u32 low = 0, high = 0;
-				low = ide_read_24(drive);
-				hwif->OUTB(drive->ctl|0x80, IDE_CONTROL_REG);
-				high = ide_read_24(drive);
-				sectors = ((__u64)high << 24) | low;
-				printk(", LBAsect=%llu, high=%d, low=%d",
-				       (unsigned long long) sectors,
-				       high, low);
-			} else {
-				u8 cur = hwif->INB(IDE_SELECT_REG);
-				if (cur & 0x40) {	/* using LBA? */
-					printk(", LBAsect=%ld", (unsigned long)
-					 ((cur&0xf)<<24)
-					 |(hwif->INB(IDE_HCYL_REG)<<16)
-					 |(hwif->INB(IDE_LCYL_REG)<<8)
-					 | hwif->INB(IDE_SECTOR_REG));
-				} else {
-					printk(", CHS=%d/%d/%d",
-					 (hwif->INB(IDE_HCYL_REG)<<8) +
-					  hwif->INB(IDE_LCYL_REG),
-					  cur & 0xf,
-					  hwif->INB(IDE_SECTOR_REG));
-				}
-			}
-			if (HWGROUP(drive) && HWGROUP(drive)->rq)
-				printk(", sector=%llu",
-					(unsigned long long)HWGROUP(drive)->rq->sector);
-		}
-	}
-	printk("\n");
-	{
-		struct request *rq;
-		unsigned char opcode = 0;
-		int found = 0;
-
-		spin_lock(&ide_lock);
-		rq = HWGROUP(drive)->rq;
-		spin_unlock(&ide_lock);
-		if (!rq)
-			goto out;
-		if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK)) {
-			char *args = rq->buffer;
-			if (args) {
-				opcode = args[0];
-				found = 1;
-			}
-		} else if (rq->flags & REQ_DRIVE_TASKFILE) {
-			ide_task_t *args = rq->special;
-			if (args) {
-				task_struct_t *tf = (task_struct_t *) args->tfRegister;
-				opcode = tf->command;
-				found = 1;
-			}
-		}
-		printk("ide: failed opcode was: ");
-		if (!found)
-			printk("unknown\n");
-		else
-			printk("0x%02x\n", opcode);
-	}
-out:
-	local_irq_restore(flags);
-	return err;
-}
-
-static ide_startstop_t idedisk_error (ide_drive_t *drive, const char *msg, u8 stat)
-{
-	ide_hwif_t *hwif;
-	struct request *rq;
-	u8 err;
+		hwif->rw_disk(drive, rq);
 
-	err = idedisk_dump_status(drive, msg, stat);
-
-	if (drive == NULL || (rq = HWGROUP(drive)->rq) == NULL)
-		return ide_stopped;
-
-	hwif = HWIF(drive);
-	/* retry only "normal" I/O: */
-	if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK | REQ_DRIVE_TASKFILE)) {
-		rq->errors = 1;
-		ide_end_drive_cmd(drive, stat, err);
-		return ide_stopped;
-	}
-
-	if (stat & BUSY_STAT || ((stat & WRERR_STAT) && !drive->nowerr)) {
-		/* other bits are useless when BUSY */
-		rq->errors |= ERROR_RESET;
-	} else if (stat & ERR_STAT) {
-		/* err has different meaning on cdrom and tape */
-		if (err == ABRT_ERR) {
-			if (drive->select.b.lba &&
-			    /* some newer drives don't support WIN_SPECIFY */
-			    hwif->INB(IDE_COMMAND_REG) == WIN_SPECIFY)
-				return ide_stopped;
-		} else if ((err & BAD_CRC) == BAD_CRC) {
-			/* UDMA crc error, just retry the operation */
-			drive->crc_count++;
-		} else if (err & (BBD_ERR | ECC_ERR)) {
-			/* retries won't help these */
-			rq->errors = ERROR_MAX;
-		} else if (err & TRK0_ERR) {
-			/* help it find track zero */
-			rq->errors |= ERROR_RECAL;
-		}
-	}
-	if ((stat & DRQ_STAT) && rq_data_dir(rq) == READ)
-		try_to_flush_leftover_data(drive);
-	if (hwif->INB(IDE_STATUS_REG) & (BUSY_STAT|DRQ_STAT)) {
-		/* force an abort */
-		hwif->OUTB(WIN_IDLEIMMEDIATE,IDE_COMMAND_REG);
-	}
-	if (rq->errors >= ERROR_MAX || blk_noretry_request(rq))
-		DRIVER(drive)->end_request(drive, 0, 0);
-	else {
-		if ((rq->errors & ERROR_RESET) == ERROR_RESET) {
-			++rq->errors;
-			return ide_do_reset(drive);
-		}
-		if ((rq->errors & ERROR_RECAL) == ERROR_RECAL)
-			drive->special.b.recalibrate = 1;
-		++rq->errors;
-	}
-	return ide_stopped;
-}
-
-static ide_startstop_t idedisk_abort(ide_drive_t *drive, const char *msg)
-{
-	ide_hwif_t *hwif;
-	struct request *rq;
-
-	if (drive == NULL || (rq = HWGROUP(drive)->rq) == NULL)
-		return ide_stopped;
-
-	hwif = HWIF(drive);
-
-	if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK | REQ_DRIVE_TASKFILE)) {
-		rq->errors = 1;
-		ide_end_drive_cmd(drive, BUSY_STAT, 0);
-		return ide_stopped;
-	}
-
-	DRIVER(drive)->end_request(drive, 0, 0);
-	return ide_stopped;
+	return __ide_do_rw_disk(drive, rq, block);
 }
 
 /*
@@ -1358,9 +1172,6 @@
 	.supports_dsc_overlap	= 0,
 	.cleanup		= idedisk_cleanup,
 	.do_request		= ide_do_rw_disk,
-	.sense			= idedisk_dump_status,
-	.error			= idedisk_error,
-	.abort			= idedisk_abort,
 	.pre_reset		= idedisk_pre_reset,
 	.capacity		= idedisk_capacity,
 	.special		= idedisk_special,
@@ -1434,7 +1245,7 @@
 static int idedisk_revalidate_disk(struct gendisk *disk)
 {
 	ide_drive_t *drive = disk->private_data;
-	set_capacity(disk, current_capacity(drive));
+	set_capacity(disk, idedisk_capacity(drive));
 	return 0;
 }
 
@@ -1478,7 +1289,7 @@
 	strcpy(g->devfs_name, drive->devfs_name);
 	g->driverfs_dev = &drive->gendev;
 	g->flags = drive->removable ? GENHD_FL_REMOVABLE : 0;
-	set_capacity(g, current_capacity(drive));
+	set_capacity(g, idedisk_capacity(drive));
 	g->fops = &idedisk_ops;
 	add_disk(g);
 	return 0;
diff -Nru a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c
--- a/drivers/ide/ide-dma.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/ide/ide-dma.c	2005-03-01 23:38:57 -08:00
@@ -116,7 +116,6 @@
 	{ "Compaq CRD-8241B"	,	"ALL"		},
 	{ "CRD-8400B"		,	"ALL"		},
 	{ "CRD-8480B",			"ALL"		},
-	{ "CRD-8480C",			"ALL"		},
 	{ "CRD-8482B",			"ALL"		},
  	{ "CRD-84"		,	"ALL"		},
 	{ "SanDisk SDP3B"	,	"ALL"		},
@@ -159,7 +158,6 @@
 	return 0;
 }
 
-#ifdef CONFIG_BLK_DEV_IDEDMA_PCI
 /**
  *	ide_dma_intr	-	IDE DMA interrupt handler
  *	@drive: the drive the interrupt is for
@@ -184,11 +182,12 @@
 		printk(KERN_ERR "%s: dma_intr: bad DMA status (dma_stat=%x)\n", 
 		       drive->name, dma_stat);
 	}
-	return DRIVER(drive)->error(drive, "dma_intr", stat);
+	return ide_error(drive, "dma_intr", stat);
 }
 
 EXPORT_SYMBOL_GPL(ide_dma_intr);
 
+#ifdef CONFIG_BLK_DEV_IDEDMA_PCI
 /**
  *	ide_build_sglist	-	map IDE scatter gather for DMA I/O
  *	@drive: the drive to build the DMA table for
@@ -228,7 +227,9 @@
  *	the PRD table that the IDE layer wants to be fed. The code
  *	knows about the 64K wrap bug in the CS5530.
  *
- *	Returns 0 if all went okay, returns 1 otherwise.
+ *	Returns the number of built PRD entries if all went okay,
+ *	returns 0 otherwise.
+ *
  *	May also be invoked from trm290.c
  */
  
@@ -632,7 +633,7 @@
 EXPORT_SYMBOL(__ide_dma_end);
 
 /* returns 1 if dma irq issued, 0 otherwise */
-int __ide_dma_test_irq (ide_drive_t *drive)
+static int __ide_dma_test_irq(ide_drive_t *drive)
 {
 	ide_hwif_t *hwif	= HWIF(drive);
 	u8 dma_stat		= hwif->INB(hwif->dma_status);
@@ -651,8 +652,6 @@
 			drive->name, __FUNCTION__);
 	return 0;
 }
-
-EXPORT_SYMBOL(__ide_dma_test_irq);
 #endif /* CONFIG_BLK_DEV_IDEDMA_PCI */
 
 int __ide_dma_bad_drive (ide_drive_t *drive)
@@ -785,7 +784,7 @@
 /*
  * Needed for allowing full modular support of ide-driver
  */
-int ide_release_dma_engine (ide_hwif_t *hwif)
+static int ide_release_dma_engine(ide_hwif_t *hwif)
 {
 	if (hwif->dmatable_cpu) {
 		pci_free_consistent(hwif->pci_dev,
@@ -797,7 +796,7 @@
 	return 1;
 }
 
-int ide_release_iomio_dma (ide_hwif_t *hwif)
+static int ide_release_iomio_dma(ide_hwif_t *hwif)
 {
 	if ((hwif->dma_extra) && (hwif->channel == 0))
 		release_region((hwif->dma_base + 16), hwif->dma_extra);
@@ -821,7 +820,7 @@
 	return ide_release_iomio_dma(hwif);
 }
 
-int ide_allocate_dma_engine (ide_hwif_t *hwif)
+static int ide_allocate_dma_engine(ide_hwif_t *hwif)
 {
 	hwif->dmatable_cpu = pci_alloc_consistent(hwif->pci_dev,
 						  PRD_ENTRIES * PRD_BYTES,
@@ -831,14 +830,13 @@
 		return 0;
 
 	printk(KERN_ERR "%s: -- Error, unable to allocate%s DMA table(s).\n",
-		(hwif->dmatable_cpu == NULL) ? " CPU" : "",
-		hwif->cds->name);
+			hwif->cds->name, !hwif->dmatable_cpu ? " CPU" : "");
 
 	ide_release_dma_engine(hwif);
 	return 1;
 }
 
-int ide_mapped_mmio_dma (ide_hwif_t *hwif, unsigned long base, unsigned int ports)
+static int ide_mapped_mmio_dma(ide_hwif_t *hwif, unsigned long base, unsigned int ports)
 {
 	printk(KERN_INFO "    %s: MMIO-DMA ", hwif->name);
 
@@ -853,7 +851,7 @@
 	return 0;
 }
 
-int ide_iomio_dma (ide_hwif_t *hwif, unsigned long base, unsigned int ports)
+static int ide_iomio_dma(ide_hwif_t *hwif, unsigned long base, unsigned int ports)
 {
 	printk(KERN_INFO "    %s: BM-DMA at 0x%04lx-0x%04lx",
 		hwif->name, base, base + ports - 1);
@@ -882,10 +880,7 @@
 	return 0;
 }
 
-/*
- * 
- */
-int ide_dma_iobase (ide_hwif_t *hwif, unsigned long base, unsigned int ports)
+static int ide_dma_iobase(ide_hwif_t *hwif, unsigned long base, unsigned int ports)
 {
 	if (hwif->mmio == 2)
 		return ide_mapped_mmio_dma(hwif, base,ports);
diff -Nru a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
--- a/drivers/ide/ide-floppy.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/ide/ide-floppy.c	2005-03-01 23:38:57 -08:00
@@ -585,7 +585,7 @@
 			count = min(bvec->bv_len, bcount);
 
 			data = bvec_kmap_irq(bvec, &flags);
-			atapi_input_bytes(drive, data, count);
+			drive->hwif->atapi_input_bytes(drive, data, count);
 			bvec_kunmap_irq(data, &flags);
 
 			bcount -= count;
@@ -619,7 +619,7 @@
 			count = min(bvec->bv_len, bcount);
 
 			data = bvec_kmap_irq(bvec, &flags);
-			atapi_output_bytes(drive, data, count);
+			drive->hwif->atapi_output_bytes(drive, data, count);
 			bvec_kunmap_irq(data, &flags);
 
 			bcount -= count;
@@ -1640,7 +1640,7 @@
 }
 
 /*
- *	Return the current floppy capacity to ide.c.
+ *	Return the current floppy capacity.
  */
 static sector_t idefloppy_capacity (ide_drive_t *drive)
 {
@@ -2034,7 +2034,7 @@
 static int idefloppy_revalidate_disk(struct gendisk *disk)
 {
 	ide_drive_t *drive = disk->private_data;
-	set_capacity(disk, current_capacity(drive));
+	set_capacity(disk, idefloppy_capacity(drive));
 	return 0;
 }
 
diff -Nru a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
--- a/drivers/ide/ide-io.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/ide/ide-io.c	2005-03-01 23:39:09 -08:00
@@ -238,9 +238,10 @@
 		high = ide_read_24(drive);
 	} else {
 		u8 cur = HWIF(drive)->INB(IDE_SELECT_REG);
-		if (cur & 0x40)
+		if (cur & 0x40) {
+			high = cur & 0xf;
 			low = (hcyl << 16) | (lcyl << 8) | sect;
-		else {
+		} else {
 			low = hcyl * drive->head * drive->sect;
 			low += lcyl * drive->sect;
 			low += sect - 1;
@@ -437,7 +438,7 @@
  *	by read a sector's worth of data from the drive.  Of course,
  *	this may not help if the drive is *waiting* for data from *us*.
  */
-void try_to_flush_leftover_data (ide_drive_t *drive)
+static void try_to_flush_leftover_data (ide_drive_t *drive)
 {
 	int i = (drive->mult_count ? drive->mult_count : 1) * SECTOR_WORDS;
 
@@ -452,11 +453,88 @@
 	}
 }
 
-EXPORT_SYMBOL(try_to_flush_leftover_data);
+static ide_startstop_t ide_ata_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err)
+{
+	ide_hwif_t *hwif = drive->hwif;
 
-/*
- * FIXME Add an ATAPI error
- */
+	if (stat & BUSY_STAT || ((stat & WRERR_STAT) && !drive->nowerr)) {
+		/* other bits are useless when BUSY */
+		rq->errors |= ERROR_RESET;
+	} else if (stat & ERR_STAT) {
+		/* err has different meaning on cdrom and tape */
+		if (err == ABRT_ERR) {
+			if (drive->select.b.lba &&
+			    /* some newer drives don't support WIN_SPECIFY */
+			    hwif->INB(IDE_COMMAND_REG) == WIN_SPECIFY)
+				return ide_stopped;
+		} else if ((err & BAD_CRC) == BAD_CRC) {
+			/* UDMA crc error, just retry the operation */
+			drive->crc_count++;
+		} else if (err & (BBD_ERR | ECC_ERR)) {
+			/* retries won't help these */
+			rq->errors = ERROR_MAX;
+		} else if (err & TRK0_ERR) {
+			/* help it find track zero */
+			rq->errors |= ERROR_RECAL;
+		}
+	}
+
+	if ((stat & DRQ_STAT) && rq_data_dir(rq) == READ)
+		try_to_flush_leftover_data(drive);
+
+	if (hwif->INB(IDE_STATUS_REG) & (BUSY_STAT|DRQ_STAT))
+		/* force an abort */
+		hwif->OUTB(WIN_IDLEIMMEDIATE, IDE_COMMAND_REG);
+
+	if (rq->errors >= ERROR_MAX || blk_noretry_request(rq))
+		drive->driver->end_request(drive, 0, 0);
+	else {
+		if ((rq->errors & ERROR_RESET) == ERROR_RESET) {
+			++rq->errors;
+			return ide_do_reset(drive);
+		}
+		if ((rq->errors & ERROR_RECAL) == ERROR_RECAL)
+			drive->special.b.recalibrate = 1;
+		++rq->errors;
+	}
+	return ide_stopped;
+}
+
+static ide_startstop_t ide_atapi_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err)
+{
+	ide_hwif_t *hwif = drive->hwif;
+
+	if (stat & BUSY_STAT || ((stat & WRERR_STAT) && !drive->nowerr)) {
+		/* other bits are useless when BUSY */
+		rq->errors |= ERROR_RESET;
+	} else {
+		/* add decoding error stuff */
+	}
+
+	if (hwif->INB(IDE_STATUS_REG) & (BUSY_STAT|DRQ_STAT))
+		/* force an abort */
+		hwif->OUTB(WIN_IDLEIMMEDIATE, IDE_COMMAND_REG);
+
+	if (rq->errors >= ERROR_MAX) {
+		drive->driver->end_request(drive, 0, 0);
+	} else {
+		if ((rq->errors & ERROR_RESET) == ERROR_RESET) {
+			++rq->errors;
+			return ide_do_reset(drive);
+		}
+		++rq->errors;
+	}
+
+	return ide_stopped;
+}
+
+ide_startstop_t
+__ide_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err)
+{
+	if (drive->media == ide_disk)
+		return ide_ata_error(drive, rq, stat, err);
+	return ide_atapi_error(drive, rq, stat, err);
+}
 
 /**
  *	ide_error	-	handle an error on the IDE
@@ -473,73 +551,32 @@
  
 ide_startstop_t ide_error (ide_drive_t *drive, const char *msg, u8 stat)
 {
-	ide_hwif_t *hwif;
 	struct request *rq;
 	u8 err;
 
 	err = ide_dump_status(drive, msg, stat);
-	if (drive == NULL || (rq = HWGROUP(drive)->rq) == NULL)
+
+	if ((rq = HWGROUP(drive)->rq) == NULL)
 		return ide_stopped;
 
-	hwif = HWIF(drive);
 	/* retry only "normal" I/O: */
-	if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK)) {
-		rq->errors = 1;
-		ide_end_drive_cmd(drive, stat, err);
-		return ide_stopped;
-	}
-	if (rq->flags & REQ_DRIVE_TASKFILE) {
+	if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK | REQ_DRIVE_TASKFILE)) {
 		rq->errors = 1;
 		ide_end_drive_cmd(drive, stat, err);
 		return ide_stopped;
 	}
 
-	if (stat & BUSY_STAT || ((stat & WRERR_STAT) && !drive->nowerr)) {
-		 /* other bits are useless when BUSY */
+	return drive->driver->error(drive, rq, stat, err);
+}
+
+EXPORT_SYMBOL_GPL(ide_error);
+
+ide_startstop_t __ide_abort(ide_drive_t *drive, struct request *rq)
+{
+	if (drive->media != ide_disk)
 		rq->errors |= ERROR_RESET;
-	} else {
-		if (drive->media != ide_disk)
-			goto media_out;
 
-		if (stat & ERR_STAT) {
-			/* err has different meaning on cdrom and tape */
-			if (err == ABRT_ERR) {
-				if (drive->select.b.lba &&
-				    (hwif->INB(IDE_COMMAND_REG) == WIN_SPECIFY))
-					/* some newer drives don't
-					 * support WIN_SPECIFY
-					 */
-					return ide_stopped;
-			} else if ((err & BAD_CRC) == BAD_CRC) {
-				drive->crc_count++;
-				/* UDMA crc error -- just retry the operation */
-			} else if (err & (BBD_ERR | ECC_ERR)) {
-				/* retries won't help these */
-				rq->errors = ERROR_MAX;
-			} else if (err & TRK0_ERR) {
-				/* help it find track zero */
-				rq->errors |= ERROR_RECAL;
-			}
-		}
-media_out:
-		if ((stat & DRQ_STAT) && rq_data_dir(rq) != WRITE)
-			try_to_flush_leftover_data(drive);
-	}
-	if (hwif->INB(IDE_STATUS_REG) & (BUSY_STAT|DRQ_STAT)) {
-		/* force an abort */
-		hwif->OUTB(WIN_IDLEIMMEDIATE,IDE_COMMAND_REG);
-	}
-	if (rq->errors >= ERROR_MAX) {
-		DRIVER(drive)->end_request(drive, 0, 0);
-	} else {
-		if ((rq->errors & ERROR_RESET) == ERROR_RESET) {
-			++rq->errors;
-			return ide_do_reset(drive);
-		}
-		if ((rq->errors & ERROR_RECAL) == ERROR_RECAL)
-			drive->special.b.recalibrate = 1;
-		++rq->errors;
-	}
+	DRIVER(drive)->end_request(drive, 0, 0);
 	return ide_stopped;
 }
 
@@ -559,28 +596,19 @@
  
 ide_startstop_t ide_abort(ide_drive_t *drive, const char *msg)
 {
-	ide_hwif_t *hwif;
 	struct request *rq;
 
 	if (drive == NULL || (rq = HWGROUP(drive)->rq) == NULL)
 		return ide_stopped;
 
-	hwif = HWIF(drive);
 	/* retry only "normal" I/O: */
-	if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK)) {
-		rq->errors = 1;
-		ide_end_drive_cmd(drive, BUSY_STAT, 0);
-		return ide_stopped;
-	}
-	if (rq->flags & REQ_DRIVE_TASKFILE) {
+	if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK | REQ_DRIVE_TASKFILE)) {
 		rq->errors = 1;
 		ide_end_drive_cmd(drive, BUSY_STAT, 0);
 		return ide_stopped;
 	}
 
-	rq->errors |= ERROR_RESET;
-	DRIVER(drive)->end_request(drive, 0, 0);
-	return ide_stopped;
+	return drive->driver->abort(drive, rq);
 }
 
 /**
@@ -634,7 +662,7 @@
 	}
 
 	if (!OK_STAT(stat, READY_STAT, BAD_STAT) && DRIVER(drive) != NULL)
-		return DRIVER(drive)->error(drive, "drive_cmd", stat);
+		return ide_error(drive, "drive_cmd", stat);
 		/* calls ide_end_drive_cmd */
 	ide_end_drive_cmd(drive, stat, hwif->INB(IDE_ERROR_REG));
 	return ide_stopped;
@@ -825,13 +853,6 @@
 		goto kill_rq;
 	}
 
-	/*
-	 * bail early if we've sent a device to sleep, however how to wake
-	 * this needs to be a masked flag.  FIXME for proper operations.
-	 */
-	if (drive->suspend_reset)
-		goto kill_rq;
-
 	block    = rq->sector;
 	if (blk_fs_request(rq) &&
 	    (drive->media == ide_disk || drive->media == ide_floppy)) {
@@ -913,6 +934,7 @@
 	if (timeout > WAIT_WORSTCASE)
 		timeout = WAIT_WORSTCASE;
 	drive->sleep = timeout + jiffies;
+	drive->sleeping = 1;
 }
 
 EXPORT_SYMBOL(ide_stall_queue);
@@ -952,18 +974,18 @@
 	}
 
 	do {
-		if ((!drive->sleep || time_after_eq(jiffies, drive->sleep))
+		if ((!drive->sleeping || time_after_eq(jiffies, drive->sleep))
 		    && !elv_queue_empty(drive->queue)) {
 			if (!best
-			 || (drive->sleep && (!best->sleep || 0 < (signed long)(best->sleep - drive->sleep)))
-			 || (!best->sleep && 0 < (signed long)(WAKEUP(best) - WAKEUP(drive))))
+			 || (drive->sleeping && (!best->sleeping || time_before(drive->sleep, best->sleep)))
+			 || (!best->sleeping && time_before(WAKEUP(drive), WAKEUP(best))))
 			{
 				if (!blk_queue_plugged(drive->queue))
 					best = drive;
 			}
 		}
 	} while ((drive = drive->next) != hwgroup->drive);
-	if (best && best->nice1 && !best->sleep && best != hwgroup->drive && best->service_time > WAIT_MIN_SLEEP) {
+	if (best && best->nice1 && !best->sleeping && best != hwgroup->drive && best->service_time > WAIT_MIN_SLEEP) {
 		long t = (signed long)(WAKEUP(best) - jiffies);
 		if (t >= WAIT_MIN_SLEEP) {
 		/*
@@ -972,10 +994,9 @@
 		 */
 			drive = best->next;
 			do {
-				if (!drive->sleep
-				/* FIXME: use time_before */
-				 && 0 < (signed long)(WAKEUP(drive) - (jiffies - best->service_time))
-				 && 0 < (signed long)((jiffies + t) - WAKEUP(drive)))
+				if (!drive->sleeping
+				 && time_before(jiffies - best->service_time, WAKEUP(drive))
+				 && time_before(WAKEUP(drive), jiffies + t))
 				{
 					ide_stall_queue(best, min_t(long, t, 10 * WAIT_MIN_SLEEP));
 					goto repeat;
@@ -1038,14 +1059,17 @@
 		hwgroup->busy = 1;
 		drive = choose_drive(hwgroup);
 		if (drive == NULL) {
-			unsigned long sleep = 0;
+			int sleeping = 0;
+			unsigned long sleep = 0; /* shut up, gcc */
 			hwgroup->rq = NULL;
 			drive = hwgroup->drive;
 			do {
-				if (drive->sleep && (!sleep || 0 < (signed long)(sleep - drive->sleep)))
+				if (drive->sleeping && (!sleeping || time_before(drive->sleep, sleep))) {
+					sleeping = 1;
 					sleep = drive->sleep;
+				}
 			} while ((drive = drive->next) != hwgroup->drive);
-			if (sleep) {
+			if (sleeping) {
 		/*
 		 * Take a short snooze, and then wake up this hwgroup again.
 		 * This gives other hwgroups on the same a chance to
@@ -1085,7 +1109,7 @@
 		}
 		hwgroup->hwif = hwif;
 		hwgroup->drive = drive;
-		drive->sleep = 0;
+		drive->sleeping = 0;
 		drive->service_start = jiffies;
 
 		if (blk_queue_plugged(drive->queue)) {
@@ -1139,14 +1163,14 @@
 		 * happens anyway when any interrupt comes in, IDE or otherwise
 		 *  -- the kernel masks the IRQ while it is being handled.
 		 */
-		if (hwif->irq != masked_irq)
+		if (masked_irq != IDE_NO_IRQ && hwif->irq != masked_irq)
 			disable_irq_nosync(hwif->irq);
 		spin_unlock(&ide_lock);
 		local_irq_enable();
 			/* allow other IRQs while we start this request */
 		startstop = start_request(drive, rq);
 		spin_lock_irq(&ide_lock);
-		if (hwif->irq != masked_irq)
+		if (masked_irq != IDE_NO_IRQ && hwif->irq != masked_irq)
 			enable_irq(hwif->irq);
 		if (startstop == ide_stopped)
 			hwgroup->busy = 0;
@@ -1181,7 +1205,7 @@
 	if (error < 0) {
 		printk(KERN_WARNING "%s: DMA timeout error\n", drive->name);
 		(void)HWIF(drive)->ide_dma_end(drive);
-		ret = DRIVER(drive)->error(drive, "dma timeout error",
+		ret = ide_error(drive, "dma timeout error",
 						hwif->INB(IDE_STATUS_REG));
 	} else {
 		printk(KERN_WARNING "%s: DMA timeout retry\n", drive->name);
@@ -1212,7 +1236,7 @@
 	rq->sector = rq->bio->bi_sector;
 	rq->current_nr_sectors = bio_iovec(rq->bio)->bv_len >> 9;
 	rq->hard_cur_sectors = rq->current_nr_sectors;
-	rq->buffer = NULL;
+	rq->buffer = bio_data(rq->bio);
 out:
 	return ret;
 }
@@ -1291,7 +1315,7 @@
 			/* local CPU only,
 			 * as if we were handling an interrupt */
 			local_irq_disable();
-			if (hwgroup->poll_timeout != 0) {
+			if (hwgroup->polling) {
 				startstop = handler(drive);
 			} else if (drive_is_ready(drive)) {
 				if (drive->waiting_for_dma)
@@ -1304,7 +1328,7 @@
 					startstop = ide_dma_timeout_retry(drive, wait);
 				} else
 					startstop =
-					DRIVER(drive)->error(drive, "irq timeout", hwif->INB(IDE_STATUS_REG));
+					ide_error(drive, "irq timeout", hwif->INB(IDE_STATUS_REG));
 			}
 			drive->service_time = jiffies - drive->service_start;
 			spin_lock_irq(&ide_lock);
@@ -1419,8 +1443,7 @@
 		return IRQ_NONE;
 	}
 
-	if ((handler = hwgroup->handler) == NULL ||
-	    hwgroup->poll_timeout != 0) {
+	if ((handler = hwgroup->handler) == NULL || hwgroup->polling) {
 		/*
 		 * Not expecting an interrupt from this drive.
 		 * That means this could be:
diff -Nru a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c
--- a/drivers/ide/ide-iops.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/ide/ide-iops.c	2005-03-01 23:38:55 -08:00
@@ -184,16 +184,6 @@
 
 EXPORT_SYMBOL(default_hwif_mmiops);
 
-void default_hwif_transport (ide_hwif_t *hwif)
-{
-	hwif->ata_input_data		= ata_input_data;
-	hwif->ata_output_data		= ata_output_data;
-	hwif->atapi_input_bytes		= atapi_input_bytes;
-	hwif->atapi_output_bytes	= atapi_output_bytes;
-}
-
-EXPORT_SYMBOL(default_hwif_transport);
-
 u32 ide_read_24 (ide_drive_t *drive)
 {
 	u8 hcyl = HWIF(drive)->INB(IDE_HCYL_REG);
@@ -202,8 +192,6 @@
 	return (hcyl<<16)|(lcyl<<8)|sect;
 }
 
-EXPORT_SYMBOL(ide_read_24);
-
 void SELECT_DRIVE (ide_drive_t *drive)
 {
 	if (HWIF(drive)->selectproc)
@@ -240,7 +228,7 @@
  * of the sector count register location, with interrupts disabled
  * to ensure that the reads all happen together.
  */
-void ata_vlb_sync (ide_drive_t *drive, unsigned long port)
+static void ata_vlb_sync(ide_drive_t *drive, unsigned long port)
 {
 	(void) HWIF(drive)->INB(port);
 	(void) HWIF(drive)->INB(port);
@@ -250,7 +238,7 @@
 /*
  * This is used for most PIO data transfers *from* the IDE interface
  */
-void ata_input_data (ide_drive_t *drive, void *buffer, u32 wcount)
+static void ata_input_data(ide_drive_t *drive, void *buffer, u32 wcount)
 {
 	ide_hwif_t *hwif	= HWIF(drive);
 	u8 io_32bit		= drive->io_32bit;
@@ -272,7 +260,7 @@
 /*
  * This is used for most PIO data transfers *to* the IDE interface
  */
-void ata_output_data (ide_drive_t *drive, void *buffer, u32 wcount)
+static void ata_output_data(ide_drive_t *drive, void *buffer, u32 wcount)
 {
 	ide_hwif_t *hwif	= HWIF(drive);
 	u8 io_32bit		= drive->io_32bit;
@@ -299,7 +287,7 @@
  * extra byte allocated for the buffer.
  */
 
-void atapi_input_bytes (ide_drive_t *drive, void *buffer, u32 bytecount)
+static void atapi_input_bytes(ide_drive_t *drive, void *buffer, u32 bytecount)
 {
 	ide_hwif_t *hwif = HWIF(drive);
 
@@ -316,9 +304,7 @@
 		hwif->INSW(IDE_DATA_REG, ((u8 *)buffer)+(bytecount & ~0x03), 1);
 }
 
-EXPORT_SYMBOL(atapi_input_bytes);
-
-void atapi_output_bytes (ide_drive_t *drive, void *buffer, u32 bytecount)
+static void atapi_output_bytes(ide_drive_t *drive, void *buffer, u32 bytecount)
 {
 	ide_hwif_t *hwif = HWIF(drive);
 
@@ -335,7 +321,15 @@
 		hwif->OUTSW(IDE_DATA_REG, ((u8*)buffer)+(bytecount & ~0x03), 1);
 }
 
-EXPORT_SYMBOL(atapi_output_bytes);
+void default_hwif_transport(ide_hwif_t *hwif)
+{
+	hwif->ata_input_data		= ata_input_data;
+	hwif->ata_output_data		= ata_output_data;
+	hwif->atapi_input_bytes		= atapi_input_bytes;
+	hwif->atapi_output_bytes	= atapi_output_bytes;
+}
+
+EXPORT_SYMBOL(default_hwif_transport);
 
 /*
  * Beginning of Taskfile OPCODE Library and feature sets.
@@ -437,6 +431,7 @@
 #endif
 }
 
+/* FIXME: exported for use by the USB storage (isd200.c) code only */
 EXPORT_SYMBOL(ide_fix_driveid);
 
 void ide_fixstring (u8 *s, const int bytecount, const int byteswap)
@@ -576,7 +571,7 @@
 					break;
 
 				local_irq_restore(flags);
-				*startstop = DRIVER(drive)->error(drive, "status timeout", stat);
+				*startstop = ide_error(drive, "status timeout", stat);
 				return 1;
 			}
 		}
@@ -594,7 +589,7 @@
 		if (OK_STAT((stat = hwif->INB(IDE_STATUS_REG)), good, bad))
 			return 0;
 	}
-	*startstop = DRIVER(drive)->error(drive, "status error", stat);
+	*startstop = ide_error(drive, "status error", stat);
 	return 1;
 }
 
@@ -1028,14 +1023,14 @@
 			return ide_started;
 		}
 		/* end of polling */
-		hwgroup->poll_timeout = 0;
+		hwgroup->polling = 0;
 		printk("%s: ATAPI reset timed-out, status=0x%02x\n",
 				drive->name, stat);
 		/* do it the old fashioned way */
 		return do_reset1(drive, 1);
 	}
 	/* done polling */
-	hwgroup->poll_timeout = 0;
+	hwgroup->polling = 0;
 	return ide_stopped;
 }
 
@@ -1095,7 +1090,7 @@
 			printk("\n");
 		}
 	}
-	hwgroup->poll_timeout = 0;	/* done polling */
+	hwgroup->polling = 0;	/* done polling */
 	return ide_stopped;
 }
 
@@ -1112,7 +1107,7 @@
 #endif
 }
 
-void pre_reset (ide_drive_t *drive)
+static void pre_reset(ide_drive_t *drive)
 {
 	DRIVER(drive)->pre_reset(drive);
 
@@ -1170,6 +1165,7 @@
 		udelay (20);
 		hwif->OUTB(WIN_SRST, IDE_COMMAND_REG);
 		hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;
+		hwgroup->polling = 1;
 		__ide_set_handler(drive, &atapi_reset_pollfunc, HZ/20, NULL);
 		spin_unlock_irqrestore(&ide_lock, flags);
 		return ide_started;
@@ -1210,6 +1206,7 @@
 	/* more than enough time */
 	udelay(10);
 	hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;
+	hwgroup->polling = 1;
 	__ide_set_handler(drive, &reset_pollfunc, HZ/20, NULL);
 
 	/*
diff -Nru a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c
--- a/drivers/ide/ide-lib.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/ide/ide-lib.c	2005-03-01 23:39:17 -08:00
@@ -445,6 +445,114 @@
 
 EXPORT_SYMBOL_GPL(ide_set_xfer_rate);
 
+static void ide_dump_opcode(ide_drive_t *drive)
+{
+	struct request *rq;
+	u8 opcode = 0;
+	int found = 0;
+
+	spin_lock(&ide_lock);
+	rq = NULL;
+	if (HWGROUP(drive))
+		rq = HWGROUP(drive)->rq;
+	spin_unlock(&ide_lock);
+	if (!rq)
+		return;
+	if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK)) {
+		char *args = rq->buffer;
+		if (args) {
+			opcode = args[0];
+			found = 1;
+		}
+	} else if (rq->flags & REQ_DRIVE_TASKFILE) {
+		ide_task_t *args = rq->special;
+		if (args) {
+			task_struct_t *tf = (task_struct_t *) args->tfRegister;
+			opcode = tf->command;
+			found = 1;
+		}
+	}
+
+	printk("ide: failed opcode was: ");
+	if (!found)
+		printk("unknown\n");
+	else
+		printk("0x%02x\n", opcode);
+}
+
+static u8 ide_dump_ata_status(ide_drive_t *drive, const char *msg, u8 stat)
+{
+	ide_hwif_t *hwif = HWIF(drive);
+	unsigned long flags;
+	u8 err = 0;
+
+	local_irq_set(flags);
+	printk("%s: %s: status=0x%02x", drive->name, msg, stat);
+	printk(" { ");
+	if (stat & BUSY_STAT)
+		printk("Busy ");
+	else {
+		if (stat & READY_STAT)	printk("DriveReady ");
+		if (stat & WRERR_STAT)	printk("DeviceFault ");
+		if (stat & SEEK_STAT)	printk("SeekComplete ");
+		if (stat & DRQ_STAT)	printk("DataRequest ");
+		if (stat & ECC_STAT)	printk("CorrectedError ");
+		if (stat & INDEX_STAT)	printk("Index ");
+		if (stat & ERR_STAT)	printk("Error ");
+	}
+	printk("}");
+	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(" { ");
+		if (err & ABRT_ERR)	printk("DriveStatusError ");
+		if (err & ICRC_ERR)
+			printk("Bad%s ", (err & ABRT_ERR) ? "CRC" : "Sector");
+		if (err & ECC_ERR)	printk("UncorrectableError ");
+		if (err & ID_ERR)	printk("SectorIdNotFound ");
+		if (err & TRK0_ERR)	printk("TrackZeroNotFound ");
+		if (err & MARK_ERR)	printk("AddrMarkNotFound ");
+		printk("}");
+		if ((err & (BBD_ERR | ABRT_ERR)) == BBD_ERR ||
+		    (err & (ECC_ERR|ID_ERR|MARK_ERR))) {
+			if (drive->addressing == 1) {
+				__u64 sectors = 0;
+				u32 low = 0, high = 0;
+				low = ide_read_24(drive);
+				hwif->OUTB(drive->ctl|0x80, IDE_CONTROL_REG);
+				high = ide_read_24(drive);
+				sectors = ((__u64)high << 24) | low;
+				printk(", LBAsect=%llu, high=%d, low=%d",
+				       (unsigned long long) sectors,
+				       high, low);
+			} else {
+				u8 cur = hwif->INB(IDE_SELECT_REG);
+				if (cur & 0x40) {	/* using LBA? */
+					printk(", LBAsect=%ld", (unsigned long)
+					 ((cur&0xf)<<24)
+					 |(hwif->INB(IDE_HCYL_REG)<<16)
+					 |(hwif->INB(IDE_LCYL_REG)<<8)
+					 | hwif->INB(IDE_SECTOR_REG));
+				} else {
+					printk(", CHS=%d/%d/%d",
+					 (hwif->INB(IDE_HCYL_REG)<<8) +
+					  hwif->INB(IDE_LCYL_REG),
+					  cur & 0xf,
+					  hwif->INB(IDE_SECTOR_REG));
+				}
+			}
+			if (HWGROUP(drive) && HWGROUP(drive)->rq)
+				printk(", sector=%llu",
+					(unsigned long long)HWGROUP(drive)->rq->sector);
+		}
+	}
+	printk("\n");
+	ide_dump_opcode(drive);
+	local_irq_restore(flags);
+	return err;
+}
+
 /**
  *	ide_dump_atapi_status       -       print human readable atapi status
  *	@drive: drive that status applies to
@@ -453,7 +561,8 @@
  *
  *	Error reporting, in human readable form (luxurious, but a memory hog).
  */
-byte ide_dump_atapi_status (ide_drive_t *drive, const char *msg, byte stat)
+
+static u8 ide_dump_atapi_status(ide_drive_t *drive, const char *msg, u8 stat)
 {
 	unsigned long flags;
 
@@ -461,9 +570,9 @@
 	atapi_error_t error;
 
 	status.all = stat;
+	error.all = 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 (status.b.bsy)
 		printk("Busy ");
 	else {
@@ -475,21 +584,39 @@
 		if (status.b.idx)	printk("Index ");
 		if (status.b.check)	printk("Error ");
 	}
-	printk("}");
-	printk("\n");
-	if ((status.all & (status.b.bsy|status.b.check)) == status.b.check) {
+	printk("}\n");
+	if (status.b.check && !status.b.bsy) {
 		error.all = HWIF(drive)->INB(IDE_ERROR_REG);
-		printk("%s: %s: error=0x%02x", drive->name, msg, error.all);
+		printk("%s: %s: error=0x%02x { ", drive->name, msg, error.all);
 		if (error.b.ili)	printk("IllegalLengthIndication ");
 		if (error.b.eom)	printk("EndOfMedia ");
-		if (error.b.abrt)	printk("Aborted Command ");
+		if (error.b.abrt)	printk("AbortedCommand ");
 		if (error.b.mcr)	printk("MediaChangeRequested ");
-		if (error.b.sense_key)	printk("LastFailedSense 0x%02x ",
+		if (error.b.sense_key)	printk("LastFailedSense=0x%02x ",
 						error.b.sense_key);
-		printk("\n");
+		printk("}\n");
 	}
+	ide_dump_opcode(drive);
 	local_irq_restore(flags);
 	return error.all;
 }
 
-EXPORT_SYMBOL(ide_dump_atapi_status);
+/**
+ *	ide_dump_status		-	translate ATA/ATAPI error
+ *	@drive: drive the error occured on
+ *	@msg: information string
+ *	@stat: status byte
+ *
+ *	Error reporting, in human readable form (luxurious, but a memory hog).
+ *	Combines the drive name, message and status byte to provide a
+ *	user understandable explanation of the device error.
+ */
+
+u8 ide_dump_status(ide_drive_t *drive, const char *msg, u8 stat)
+{
+	if (drive->media == ide_disk)
+		return ide_dump_ata_status(drive, msg, stat);
+	return ide_dump_atapi_status(drive, msg, stat);
+}
+
+EXPORT_SYMBOL(ide_dump_status);
diff -Nru a/drivers/ide/ide-pnp.c b/drivers/ide/ide-pnp.c
--- a/drivers/ide/ide-pnp.c	2005-03-01 23:39:06 -08:00
+++ b/drivers/ide/ide-pnp.c	2005-03-01 23:39:06 -08:00
@@ -21,7 +21,7 @@
 #include <linux/ide.h>
 
 /* Add your devices here :)) */
-struct pnp_device_id idepnp_devices[] = {
+static struct pnp_device_id idepnp_devices[] = {
   	/* Generic ESDI/IDE/ATA compatible hard disk controller */
 	{.id = "PNP0600", .driver_data = 0},
 	{.id = ""}
diff -Nru a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
--- a/drivers/ide/ide-probe.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/ide/ide-probe.c	2005-03-01 23:38:58 -08:00
@@ -749,7 +749,7 @@
 	 *  
 	 *  BenH.
 	 */
-	if (wait_hwif_ready(hwif))
+	if (wait_hwif_ready(hwif) == -EBUSY)
 		printk(KERN_DEBUG "%s: Wait for ready failed before probe !\n", hwif->name);
 
 	/*
@@ -841,7 +841,11 @@
 	if (fixup)
 		fixup(hwif);
 
-	hwif_init(hwif);
+	if (!hwif_init(hwif)) {
+		printk(KERN_INFO "%s: failed to initialize IDE interface\n",
+				 hwif->name);
+		return -1;
+	}
 
 	if (hwif->present) {
 		u16 unit = 0;
@@ -1244,8 +1248,9 @@
 {
 	int old_irq, unit;
 
+	/* Return success if no device is connected */
 	if (!hwif->present)
-		return 0;
+		return 1;
 
 	if (!hwif->irq) {
 		if (!(hwif->irq = ide_default_irq(hwif->io_ports[IDE_DATA_OFFSET])))
diff -Nru a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c
--- a/drivers/ide/ide-proc.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/ide/ide-proc.c	2005-03-01 23:38:58 -08:00
@@ -492,20 +492,6 @@
 	}
 }
 
-static void destroy_proc_ide_interfaces(void)
-{
-	int	h;
-
-	for (h = 0; h < MAX_HWIFS; h++) {
-		ide_hwif_t *hwif = &ide_hwifs[h];
-#if 0
-		if (!hwif->present)
-			continue;
-#endif
-		destroy_proc_ide_interface(hwif);
-	}
-}
-
 extern struct seq_operations ide_drivers_op;
 static int ide_drivers_open(struct inode *inode, struct file *file)
 {
@@ -535,6 +521,5 @@
 void proc_ide_destroy(void)
 {
 	remove_proc_entry("ide/drivers", proc_ide_root);
-	destroy_proc_ide_interfaces();
 	remove_proc_entry("ide", NULL);
 }
diff -Nru a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
--- a/drivers/ide/ide-tape.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/ide/ide-tape.c	2005-03-01 23:38:55 -08:00
@@ -2439,7 +2439,7 @@
 			tape->dsc_polling_start = jiffies;
 			tape->dsc_polling_frequency = tape->best_dsc_rw_frequency;
 			tape->dsc_timeout = jiffies + IDETAPE_DSC_RW_TIMEOUT;
-		} else if ((signed long) (jiffies - tape->dsc_timeout) > 0) {
+		} else if (time_after(jiffies, tape->dsc_timeout)) {
 			printk(KERN_ERR "ide-tape: %s: DSC timeout\n",
 				tape->name);
 			if (rq->cmd[0] & REQ_IDETAPE_PC2) {
diff -Nru a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c
--- a/drivers/ide/ide-taskfile.c	2005-03-01 23:38:44 -08:00
+++ b/drivers/ide/ide-taskfile.c	2005-03-01 23:38:44 -08:00
@@ -199,7 +199,7 @@
 		return ide_stopped;
 
 	if (stat & (ERR_STAT|DRQ_STAT))
-		return DRIVER(drive)->error(drive, "set_geometry_intr", stat);
+		return ide_error(drive, "set_geometry_intr", stat);
 
 	if (HWGROUP(drive)->handler != NULL)
 		BUG();
@@ -218,7 +218,7 @@
 	u8 stat;
 
 	if (!OK_STAT(stat = hwif->INB(IDE_STATUS_REG), READY_STAT, BAD_STAT))
-		return DRIVER(drive)->error(drive, "recal_intr", stat);
+		return ide_error(drive, "recal_intr", stat);
 	return ide_stopped;
 }
 
@@ -235,7 +235,7 @@
 
 	local_irq_enable();
 	if (!OK_STAT(stat = hwif->INB(IDE_STATUS_REG),READY_STAT,BAD_STAT)) {
-		return DRIVER(drive)->error(drive, "task_no_data_intr", stat);
+		return ide_error(drive, "task_no_data_intr", stat);
 		/* calls ide_end_drive_cmd */
 	}
 	if (args)
@@ -363,7 +363,7 @@
 		if (sectors > 0)
 			drive->driver->end_request(drive, 1, sectors);
 	}
-	return drive->driver->error(drive, s, stat);
+	return ide_error(drive, s, stat);
 }
 
 static void task_end_request(ide_drive_t *drive, struct request *rq, u8 stat)
@@ -851,8 +851,8 @@
 		hwif->OUTB(taskfile->high_cylinder, IDE_HCYL_REG);
 
         /*
-	 * (ks) In the flagged taskfile approch, we will used all specified
-	 * registers and the register value will not be changed. Except the
+	 * (ks) In the flagged taskfile approch, we will use all specified
+	 * registers and the register value will not be changed, except the
 	 * select bit (master/slave) in the drive_head register. We must make
 	 * sure that the desired drive is selected.
 	 */
diff -Nru a/drivers/ide/ide.c b/drivers/ide/ide.c
--- a/drivers/ide/ide.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/ide/ide.c	2005-03-01 23:38:54 -08:00
@@ -175,7 +175,7 @@
 static int initializing;	/* set while initializing built-in drivers */
 
 DECLARE_MUTEX(ide_cfg_sem);
-spinlock_t ide_lock __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
+ __cacheline_aligned_in_smp DEFINE_SPINLOCK(ide_lock);
 
 #ifdef CONFIG_BLK_DEV_IDEPCI
 static int ide_scan_direction; /* THIS was formerly 2.2.x pci=reverse */
@@ -333,12 +333,16 @@
  *	Returns a guessed speed in MHz.
  */
 
-int ide_system_bus_speed (void)
+static int ide_system_bus_speed(void)
 {
+#ifdef CONFIG_PCI
 	static struct pci_device_id pci_default[] = {
 		{ PCI_DEVICE(PCI_ANY_ID, PCI_ANY_ID) },
 		{ }
 	};
+#else
+#define pci_default 0
+#endif /* CONFIG_PCI */
 
 	if (!system_bus_speed) {
 		if (idebus_parameter) {
@@ -358,137 +362,6 @@
 	return system_bus_speed;
 }
 
-/**
- *	current_capacity	-	drive capacity
- *	@drive: drive to query
- *
- *	Return the current capacity (in sectors) of a drive according to
- *	its current geometry/LBA settings. Empty removables are reported
- *	as size zero.
- */
-
-sector_t current_capacity (ide_drive_t *drive)
-{
-	if (!drive->present)
-		return 0;
-	return DRIVER(drive)->capacity(drive);
-}
-
-EXPORT_SYMBOL(current_capacity);
-
-/**
- *	ide_dump_status		-	translate ATA error
- *	@drive: drive the error occured on
- *	@msg: information string
- *	@stat: status byte
- *
- *	Error reporting, in human readable form (luxurious, but a memory hog).
- *	Combines the drive name, message and status byte to provide a
- *	user understandable explanation of the device error.
- */
-
-u8 ide_dump_status (ide_drive_t *drive, const char *msg, u8 stat)
-{
-	ide_hwif_t *hwif = HWIF(drive);
-	unsigned long flags;
-	u8 err = 0;
-
-	local_irq_set(flags);
-	printk(KERN_WARNING "%s: %s: status=0x%02x", drive->name, msg, stat);
-	printk(" { ");
-	if (stat & BUSY_STAT) {
-		printk("Busy ");
-	} else {
-		if (stat & READY_STAT)	printk("DriveReady ");
-		if (stat & WRERR_STAT)	printk("DeviceFault ");
-		if (stat & SEEK_STAT)	printk("SeekComplete ");
-		if (stat & DRQ_STAT)	printk("DataRequest ");
-		if (stat & ECC_STAT)	printk("CorrectedError ");
-		if (stat & INDEX_STAT)	printk("Index ");
-		if (stat & ERR_STAT)	printk("Error ");
-	}
-	printk("}");
-	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);
-		if (drive->media == ide_disk) {
-			printk(" { ");
-			if (err & ABRT_ERR)	printk("DriveStatusError ");
-			if (err & ICRC_ERR)	printk("Bad%s ", (err & ABRT_ERR) ? "CRC" : "Sector");
-			if (err & ECC_ERR)	printk("UncorrectableError ");
-			if (err & ID_ERR)	printk("SectorIdNotFound ");
-			if (err & TRK0_ERR)	printk("TrackZeroNotFound ");
-			if (err & MARK_ERR)	printk("AddrMarkNotFound ");
-			printk("}");
-			if ((err & (BBD_ERR | ABRT_ERR)) == BBD_ERR || (err & (ECC_ERR|ID_ERR|MARK_ERR))) {
-				if ((drive->id->command_set_2 & 0x0400) &&
-				    (drive->id->cfs_enable_2 & 0x0400) &&
-				    (drive->addressing == 1)) {
-					u64 sectors = 0;
-					u32 high = 0;
-					u32 low = ide_read_24(drive);
-					hwif->OUTB(drive->ctl|0x80, IDE_CONTROL_REG);
-					high = ide_read_24(drive);
-
-					sectors = ((u64)high << 24) | low;
-					printk(", LBAsect=%llu, high=%d, low=%d",
-					       (long long) sectors,
-					       high, low);
-				} else {
-					u8 cur = hwif->INB(IDE_SELECT_REG);
-					if (cur & 0x40) {	/* using LBA? */
-						printk(", LBAsect=%ld", (unsigned long)
-						 ((cur&0xf)<<24)
-						 |(hwif->INB(IDE_HCYL_REG)<<16)
-						 |(hwif->INB(IDE_LCYL_REG)<<8)
-						 | hwif->INB(IDE_SECTOR_REG));
-					} else {
-						printk(", CHS=%d/%d/%d",
-						 (hwif->INB(IDE_HCYL_REG)<<8) +
-						  hwif->INB(IDE_LCYL_REG),
-						  cur & 0xf,
-						  hwif->INB(IDE_SECTOR_REG));
-					}
-				}
-				if (HWGROUP(drive) && HWGROUP(drive)->rq)
-					printk(", sector=%llu", (unsigned long long)HWGROUP(drive)->rq->sector);
-			}
-		}
-		printk("\n");
-	}
-	{
-		struct request *rq;
-		int opcode = 0x100;
-
-		spin_lock(&ide_lock);
-		rq = NULL;
-		if (HWGROUP(drive))
-			rq = HWGROUP(drive)->rq;
-		spin_unlock(&ide_lock);
-		if (!rq)
-			goto out;
-		if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK)) {
-			char *args = rq->buffer;
-			if (args)
-				opcode = args[0];
-		} else if (rq->flags & REQ_DRIVE_TASKFILE) {
-			ide_task_t *args = rq->special;
-			if (args) {
-				task_struct_t *tf = (task_struct_t *) args->tfRegister;
-				opcode = tf->command;
-			}
-		}
-
-		printk("ide: failed opcode was %x\n", opcode);
-	}
-out:
-	local_irq_restore(flags);
-	return err;
-}
-
-EXPORT_SYMBOL(ide_dump_status);
-
 static int ide_open (struct inode * inode, struct file * filp)
 {
 	return -ENXIO;
@@ -499,8 +372,8 @@
  *	list of drivers.  Currently nobody takes both at once.
  */
 
-static spinlock_t drives_lock = SPIN_LOCK_UNLOCKED;
-static spinlock_t drivers_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(drives_lock);
+static DEFINE_SPINLOCK(drivers_lock);
 static LIST_HEAD(drivers);
 
 /* Iterator for the driver list. */
@@ -545,7 +418,7 @@
 #ifdef CONFIG_PROC_FS
 struct proc_dir_entry *proc_ide_root;
 
-ide_proc_entry_t generic_subdriver_entries[] = {
+static ide_proc_entry_t generic_subdriver_entries[] = {
 	{ "capacity",	S_IFREG|S_IRUGO,	proc_ide_read_capacity,	NULL },
 	{ NULL, 0, NULL, NULL }
 };
@@ -1511,7 +1384,7 @@
 	return 1;
 }
 
-static int generic_ide_suspend(struct device *dev, u32 state)
+static int generic_ide_suspend(struct device *dev, pm_message_t state)
 {
 	ide_drive_t *drive = dev->driver_data;
 	struct request rq;
@@ -1673,8 +1546,9 @@
 			 */
 
 			spin_lock_irqsave(&ide_lock, flags);
-			
-			DRIVER(drive)->abort(drive, "drive reset");
+
+			ide_abort(drive, "drive reset");
+
 			if(HWGROUP(drive)->handler)
 				BUG();
 				
@@ -1684,18 +1558,7 @@
 			HWGROUP(drive)->busy = 1;
 			spin_unlock_irqrestore(&ide_lock, flags);
 			(void) ide_do_reset(drive);
-			if (drive->suspend_reset) {
-/*
- *				APM WAKE UP todo !!
- *				int nogoodpower = 1;
- *				while(nogoodpower) {
- *					check_power1() or check_power2()
- *					nogoodpower = 0;
- *				} 
- *				HWIF(drive)->multiproc(drive);
- */
-				return ioctl_by_bdev(bdev, BLKRRPART, 0);
-			}
+
 			return 0;
 		}
 
@@ -1816,7 +1679,7 @@
  *
  * Remember to update Documentation/ide.txt if you change something here.
  */
-int __init ide_setup (char *s)
+static int __init ide_setup(char *s)
 {
 	int i, vals[3];
 	ide_hwif_t *hwif;
@@ -2159,16 +2022,6 @@
 #endif
 }
 
-/*
- *	Actually unregister the subdriver. Called with the
- *	request lock dropped.
- */
- 
-static int default_cleanup (ide_drive_t *drive)
-{
-	return ide_unregister_subdriver(drive);
-}
-
 static ide_startstop_t default_do_request (ide_drive_t *drive, struct request *rq, sector_t block)
 {
 	ide_end_request(drive, 0, 0);
@@ -2180,14 +2033,10 @@
 	return ide_end_request(drive, uptodate, nr_sects);
 }
 
-static u8 default_sense (ide_drive_t *drive, const char *msg, u8 stat)
+static ide_startstop_t
+default_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err)
 {
-	return ide_dump_status(drive, msg, stat);
-}
-
-static ide_startstop_t default_error (ide_drive_t *drive, const char *msg, u8 stat)
-{
-	return ide_error(drive, msg, stat);
+	return __ide_error(drive, rq, stat, err);
 }
 
 static void default_pre_reset (ide_drive_t *drive)
@@ -2208,17 +2057,9 @@
 	return ide_stopped;
 }
 
-static int default_attach (ide_drive_t *drive)
-{
-	printk(KERN_ERR "%s: does not support hotswap of device class !\n",
-		drive->name);
-
-	return 0;
-}
-
-static ide_startstop_t default_abort (ide_drive_t *drive, const char *msg)
+static ide_startstop_t default_abort(ide_drive_t *drive, struct request *rq)
 {
-	return ide_abort(drive, msg);
+	return __ide_abort(drive, rq);
 }
 
 static ide_startstop_t default_start_power_step(ide_drive_t *drive,
@@ -2230,16 +2071,15 @@
 
 static void setup_driver_defaults (ide_driver_t *d)
 {
-	if (d->cleanup == NULL)		d->cleanup = default_cleanup;
+	BUG_ON(d->attach == NULL || d->cleanup == NULL);
+
 	if (d->do_request == NULL)	d->do_request = default_do_request;
 	if (d->end_request == NULL)	d->end_request = default_end_request;
-	if (d->sense == NULL)		d->sense = default_sense;
 	if (d->error == NULL)		d->error = default_error;
 	if (d->abort == NULL)		d->abort = default_abort;
 	if (d->pre_reset == NULL)	d->pre_reset = default_pre_reset;
 	if (d->capacity == NULL)	d->capacity = default_capacity;
 	if (d->special == NULL)		d->special = default_special;
-	if (d->attach == NULL)		d->attach = default_attach;
 	if (d->start_power_step == NULL)
 		d->start_power_step = default_start_power_step;
 }
@@ -2268,7 +2108,6 @@
 		drive->dsc_overlap = (drive->next != drive && driver->supports_dsc_overlap);
 		drive->nice1 = 1;
 	}
-	drive->suspend_reset = 0;
 #ifdef CONFIG_PROC_FS
 	if (drive->driver != &idedefault_driver) {
 		ide_add_proc_entries(drive->proc, generic_subdriver_entries, drive);
@@ -2426,7 +2265,7 @@
 /*
  * This is gets invoked once during initialization, to set *everything* up
  */
-int __init ide_init (void)
+static int __init ide_init(void)
 {
 	printk(KERN_INFO "Uniform Multi-Platform E-IDE driver " REVISION "\n");
 	devfs_mk_dir("ide");
@@ -2473,7 +2312,7 @@
 }
 
 #ifdef MODULE
-char *options = NULL;
+static char *options = NULL;
 module_param(options, charp, 0);
 MODULE_LICENSE("GPL");
 
@@ -2501,11 +2340,8 @@
 {
 	int index;
 
-	for (index = 0; index < MAX_HWIFS; ++index) {
+	for (index = 0; index < MAX_HWIFS; ++index)
 		ide_unregister(index);
-		if (ide_hwifs[index].dma_base)
-			(void) ide_release_dma(&ide_hwifs[index]);
-	}
 
 #ifdef CONFIG_PROC_FS
 	proc_ide_destroy();
diff -Nru a/drivers/ide/legacy/hd.c b/drivers/ide/legacy/hd.c
--- a/drivers/ide/legacy/hd.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/ide/legacy/hd.c	2005-03-01 23:39:18 -08:00
@@ -94,7 +94,7 @@
 #define BBD_ERR			0x80	/* pre-EIDE meaning:  block marked bad */
 #define ICRC_ERR		0x80	/* new meaning:  CRC error during transfer */
 
-static spinlock_t hd_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(hd_lock);
 static struct request_queue *hd_queue;
 
 #define MAJOR_NR HD_MAJOR
diff -Nru a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c
--- a/drivers/ide/legacy/ide-cs.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/ide/legacy/ide-cs.c	2005-03-01 23:39:07 -08:00
@@ -62,12 +62,7 @@
 MODULE_DESCRIPTION("PCMCIA ATA/IDE card driver");
 MODULE_LICENSE("Dual MPL/GPL");
 
-#define INT_MODULE_PARM(n, v) static int n = v; MODULE_PARM(n, "i")
-
-/* Bit map of interrupts to choose from */
-INT_MODULE_PARM(irq_mask, 0xdeb8);
-static int irq_list[4] = { -1 };
-MODULE_PARM(irq_list, "1-4i");
+#define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0)
 
 #ifdef PCMCIA_DEBUG
 INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
@@ -116,7 +111,7 @@
     ide_info_t *info;
     dev_link_t *link;
     client_reg_t client_reg;
-    int i, ret;
+    int ret;
     
     DEBUG(0, "ide_attach()\n");
 
@@ -130,12 +125,7 @@
     link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
     link->io.IOAddrLines = 3;
     link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
-    link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
-    if (irq_list[0] == -1)
-	link->irq.IRQInfo2 = irq_mask;
-    else
-	for (i = 0; i < 4; i++)
-	    link->irq.IRQInfo2 |= 1 << irq_list[i];
+    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.Vcc = 50;
     link->conf.IntType = INT_MEMORY_AND_IO;
@@ -144,7 +134,6 @@
     link->next = dev_list;
     dev_list = link;
     client_reg.dev_info = &dev_info;
-    client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
     client_reg.EventMask =
 	CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
 	CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
@@ -220,7 +209,7 @@
 #define CS_CHECK(fn, ret) \
 do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
 
-void ide_config(dev_link_t *link)
+static void ide_config(dev_link_t *link)
 {
     client_handle_t handle = link->handle;
     ide_info_t *info = link->priv;
@@ -485,8 +474,7 @@
 static void __exit exit_ide_cs(void)
 {
 	pcmcia_unregister_driver(&ide_cs_driver);
-	while (dev_list != NULL)
-		ide_detach(dev_list);
+	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_ide_cs);
diff -Nru a/drivers/ide/pci/Makefile b/drivers/ide/pci/Makefile
--- a/drivers/ide/pci/Makefile	2005-03-01 23:38:53 -08:00
+++ b/drivers/ide/pci/Makefile	2005-03-01 23:38:53 -08:00
@@ -1,5 +1,4 @@
 
-obj-$(CONFIG_BLK_DEV_ADMA100)		+= adma100.o
 obj-$(CONFIG_BLK_DEV_AEC62XX)		+= aec62xx.o
 obj-$(CONFIG_BLK_DEV_ALI15X3)		+= alim15x3.o
 obj-$(CONFIG_BLK_DEV_AMD74XX)		+= amd74xx.o
diff -Nru a/drivers/ide/pci/adma100.c b/drivers/ide/pci/adma100.c
--- a/drivers/ide/pci/adma100.c	2005-03-01 23:38:55 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,30 +0,0 @@
-/*
- *  linux/drivers/ide/pci/adma100.c -- basic support for Pacific Digital ADMA-100 boards
- *
- *     Created 09 Apr 2002 by Mark Lord
- *
- *  This file 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/mm.h>
-#include <linux/blkdev.h>
-#include <linux/hdreg.h>
-#include <linux/ide.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <asm/io.h>
-
-void __init ide_init_adma100 (ide_hwif_t *hwif)
-{
-	unsigned long  phy_admctl = pci_resource_start(hwif->pci_dev, 4) + 0x80 + (hwif->channel * 0x20);
-	void *v_admctl;
-
-	hwif->autodma = 0;		// not compatible with normal IDE DMA transfers
-	hwif->dma_base = 0;		// disable DMA completely
-	hwif->io_ports[IDE_CONTROL_OFFSET] += 4;	// chip needs offset of 6 instead of 2
-	v_admctl = ioremap_nocache(phy_admctl, 1024);	// map config regs, so we can turn on drive IRQs
-	*((unsigned short *)v_admctl) &= 3;		// enable aIEN; preserve PIO mode
-	iounmap(v_admctl);				// all done; unmap config regs
-}
diff -Nru a/drivers/ide/pci/adma100.h b/drivers/ide/pci/adma100.h
--- a/drivers/ide/pci/adma100.h	2005-03-01 23:39:09 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,28 +0,0 @@
-#ifndef ADMA_100_H
-#define ADMA_100_H
-
-#include <linux/config.h>
-#include <linux/pci.h>
-#include <linux/ide.h>
-
-extern void init_setup_pdcadma(struct pci_dev *, ide_pci_device_t *);
-extern unsigned int init_chipset_pdcadma(struct pci_dev *, const char *);
-extern void init_hwif_pdcadma(ide_hwif_t *);
-extern void init_dma_pdcadma(ide_hwif_t *, unsigned long);
-
-static ide_pci_device_t pdcadma_chipsets[] __devinitdata = {
-	{
-		.vendor		= PCI_VENDOR_ID_PDC,
-		.device		= PCI_DEVICE_ID_PDC_1841,
-		.name		= "ADMA100",
-		.init_setup	= init_setup_pdcadma,
-		.init_chipset	= init_chipset_pdcadma,
-		.init_hwif	= init_hwif_pdcadma,
-		.init_dma	= init_dma_pdcadma,
-		.channels	= 2,
-		.autodma	= NODMA,
-		.bootable	= OFF_BOARD,
-	}
-}
-
-#endif /* ADMA_100_H */
diff -Nru a/drivers/ide/pci/aec62xx.c b/drivers/ide/pci/aec62xx.c
--- a/drivers/ide/pci/aec62xx.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/ide/pci/aec62xx.c	2005-03-01 23:39:09 -08:00
@@ -16,7 +16,54 @@
 
 #include <asm/io.h>
 
-#include "aec62xx.h"
+struct chipset_bus_clock_list_entry {
+	u8 xfer_speed;
+	u8 chipset_settings;
+	u8 ultra_settings;
+};
+
+static struct chipset_bus_clock_list_entry aec6xxx_33_base [] = {
+	{	XFER_UDMA_6,	0x31,	0x07	},
+	{	XFER_UDMA_5,	0x31,	0x06	},
+	{	XFER_UDMA_4,	0x31,	0x05	},
+	{	XFER_UDMA_3,	0x31,	0x04	},
+	{	XFER_UDMA_2,	0x31,	0x03	},
+	{	XFER_UDMA_1,	0x31,	0x02	},
+	{	XFER_UDMA_0,	0x31,	0x01	},
+
+	{	XFER_MW_DMA_2,	0x31,	0x00	},
+	{	XFER_MW_DMA_1,	0x31,	0x00	},
+	{	XFER_MW_DMA_0,	0x0a,	0x00	},
+	{	XFER_PIO_4,	0x31,	0x00	},
+	{	XFER_PIO_3,	0x33,	0x00	},
+	{	XFER_PIO_2,	0x08,	0x00	},
+	{	XFER_PIO_1,	0x0a,	0x00	},
+	{	XFER_PIO_0,	0x00,	0x00	},
+	{	0,		0x00,	0x00	}
+};
+
+static struct chipset_bus_clock_list_entry aec6xxx_34_base [] = {
+	{	XFER_UDMA_6,	0x41,	0x06	},
+	{	XFER_UDMA_5,	0x41,	0x05	},
+	{	XFER_UDMA_4,	0x41,	0x04	},
+	{	XFER_UDMA_3,	0x41,	0x03	},
+	{	XFER_UDMA_2,	0x41,	0x02	},
+	{	XFER_UDMA_1,	0x41,	0x01	},
+	{	XFER_UDMA_0,	0x41,	0x01	},
+
+	{	XFER_MW_DMA_2,	0x41,	0x00	},
+	{	XFER_MW_DMA_1,	0x42,	0x00	},
+	{	XFER_MW_DMA_0,	0x7a,	0x00	},
+	{	XFER_PIO_4,	0x41,	0x00	},
+	{	XFER_PIO_3,	0x43,	0x00	},
+	{	XFER_PIO_2,	0x78,	0x00	},
+	{	XFER_PIO_1,	0x7a,	0x00	},
+	{	XFER_PIO_0,	0x70,	0x00	},
+	{	0,		0x00,	0x00	}
+};
+
+#define BUSCLOCK(D)	\
+	((struct chipset_bus_clock_list_entry *) pci_get_drvdata((D)))
 
 #if 0
 		if (dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF) {
@@ -101,8 +148,7 @@
 	/* 0x40|(2*drive->dn): Active, 0x41|(2*drive->dn): Recovery */
 	pci_read_config_word(dev, 0x40|(2*drive->dn), &d_conf);
 	tmp0 = pci_bus_clock_list(speed, BUSCLOCK(dev));
-	SPLIT_BYTE(tmp0,tmp1,tmp2);
-	MAKE_WORD(d_conf,tmp1,tmp2);
+	d_conf = ((tmp0 & 0xf0) << 4) | (tmp0 & 0xf);
 	pci_write_config_word(dev, 0x40|(2*drive->dn), d_conf);
 
 	tmp1 = 0x00;
@@ -321,12 +367,12 @@
 	ide_setup_dma(hwif, dmabase, 8);
 }
 
-static void __devinit init_setup_aec62xx(struct pci_dev *dev, ide_pci_device_t *d)
+static int __devinit init_setup_aec62xx(struct pci_dev *dev, ide_pci_device_t *d)
 {
-	ide_setup_pci_device(dev, d);
+	return ide_setup_pci_device(dev, d);
 }
 
-static void __devinit init_setup_aec6x80(struct pci_dev *dev, ide_pci_device_t *d)
+static int __devinit init_setup_aec6x80(struct pci_dev *dev, ide_pci_device_t *d)
 {
 	unsigned long bar4reg = pci_resource_start(dev, 4);
 
@@ -340,9 +386,61 @@
 			strcpy(d->name, "AEC6280R");
 	}
 
-	ide_setup_pci_device(dev, d);
+	return ide_setup_pci_device(dev, d);
 }
 
+static ide_pci_device_t aec62xx_chipsets[] __devinitdata = {
+	{	/* 0 */
+		.name		= "AEC6210",
+		.init_setup	= init_setup_aec62xx,
+		.init_chipset	= init_chipset_aec62xx,
+		.init_hwif	= init_hwif_aec62xx,
+		.init_dma	= init_dma_aec62xx,
+		.channels	= 2,
+		.autodma	= AUTODMA,
+		.enablebits	= {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}},
+		.bootable	= OFF_BOARD,
+	},{	/* 1 */
+		.name		= "AEC6260",
+		.init_setup	= init_setup_aec62xx,
+		.init_chipset	= init_chipset_aec62xx,
+		.init_hwif	= init_hwif_aec62xx,
+		.init_dma	= init_dma_aec62xx,
+		.channels	= 2,
+		.autodma	= NOAUTODMA,
+		.bootable	= OFF_BOARD,
+	},{	/* 2 */
+		.name		= "AEC6260R",
+		.init_setup	= init_setup_aec62xx,
+		.init_chipset	= init_chipset_aec62xx,
+		.init_hwif	= init_hwif_aec62xx,
+		.init_dma	= init_dma_aec62xx,
+		.channels	= 2,
+		.autodma	= AUTODMA,
+		.enablebits	= {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}},
+		.bootable	= NEVER_BOARD,
+	},{	/* 3 */
+		.name		= "AEC6X80",
+		.init_setup	= init_setup_aec6x80,
+		.init_chipset	= init_chipset_aec62xx,
+		.init_hwif	= init_hwif_aec62xx,
+		.init_dma	= init_dma_aec62xx,
+		.channels	= 2,
+		.autodma	= AUTODMA,
+		.bootable	= OFF_BOARD,
+	},{	/* 4 */
+		.name		= "AEC6X80R",
+		.init_setup	= init_setup_aec6x80,
+		.init_chipset	= init_chipset_aec62xx,
+		.init_hwif	= init_hwif_aec62xx,
+		.init_dma	= init_dma_aec62xx,
+		.channels	= 2,
+		.autodma	= AUTODMA,
+		.enablebits	= {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}},
+		.bootable	= OFF_BOARD,
+	}
+};
+
 /**
  *	aec62xx_init_one	-	called when a AEC is found
  *	@dev: the aec62xx device
@@ -356,8 +454,7 @@
 {
 	ide_pci_device_t *d = &aec62xx_chipsets[id->driver_data];
 
-	d->init_setup(dev, d);
-	return 0;
+	return d->init_setup(dev, d);
 }
 
 static struct pci_device_id aec62xx_pci_tbl[] = {
diff -Nru a/drivers/ide/pci/aec62xx.h b/drivers/ide/pci/aec62xx.h
--- a/drivers/ide/pci/aec62xx.h	2005-03-01 23:38:57 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,122 +0,0 @@
-#ifndef AEC62XX_H
-#define AEC62XX_H
-
-#include <linux/config.h>
-#include <linux/pci.h>
-#include <linux/ide.h>
-
-struct chipset_bus_clock_list_entry {
-	byte		xfer_speed;
-	byte		chipset_settings;
-	byte		ultra_settings;
-};
-
-static struct chipset_bus_clock_list_entry aec6xxx_33_base [] = {
-	{	XFER_UDMA_6,	0x31,	0x07	},
-	{	XFER_UDMA_5,	0x31,	0x06	},
-	{	XFER_UDMA_4,	0x31,	0x05	},
-	{	XFER_UDMA_3,	0x31,	0x04	},
-	{	XFER_UDMA_2,	0x31,	0x03	},
-	{	XFER_UDMA_1,	0x31,	0x02	},
-	{	XFER_UDMA_0,	0x31,	0x01	},
-
-	{	XFER_MW_DMA_2,	0x31,	0x00	},
-	{	XFER_MW_DMA_1,	0x31,	0x00	},
-	{	XFER_MW_DMA_0,	0x0a,	0x00	},
-	{	XFER_PIO_4,	0x31,	0x00	},
-	{	XFER_PIO_3,	0x33,	0x00	},
-	{	XFER_PIO_2,	0x08,	0x00	},
-	{	XFER_PIO_1,	0x0a,	0x00	},
-	{	XFER_PIO_0,	0x00,	0x00	},
-	{	0,		0x00,	0x00	}
-};
-
-static struct chipset_bus_clock_list_entry aec6xxx_34_base [] = {
-	{	XFER_UDMA_6,	0x41,	0x06	},
-	{	XFER_UDMA_5,	0x41,	0x05	},
-	{	XFER_UDMA_4,	0x41,	0x04	},
-	{	XFER_UDMA_3,	0x41,	0x03	},
-	{	XFER_UDMA_2,	0x41,	0x02	},
-	{	XFER_UDMA_1,	0x41,	0x01	},
-	{	XFER_UDMA_0,	0x41,	0x01	},
-
-	{	XFER_MW_DMA_2,	0x41,	0x00	},
-	{	XFER_MW_DMA_1,	0x42,	0x00	},
-	{	XFER_MW_DMA_0,	0x7a,	0x00	},
-	{	XFER_PIO_4,	0x41,	0x00	},
-	{	XFER_PIO_3,	0x43,	0x00	},
-	{	XFER_PIO_2,	0x78,	0x00	},
-	{	XFER_PIO_1,	0x7a,	0x00	},
-	{	XFER_PIO_0,	0x70,	0x00	},
-	{	0,		0x00,	0x00	}
-};
-
-#ifndef SPLIT_BYTE
-#define SPLIT_BYTE(B,H,L)	((H)=(B>>4), (L)=(B-((B>>4)<<4)))
-#endif
-#ifndef MAKE_WORD
-#define MAKE_WORD(W,HB,LB)	((W)=((HB<<8)+LB))
-#endif
-
-#define BUSCLOCK(D)	\
-	((struct chipset_bus_clock_list_entry *) pci_get_drvdata((D)))
-
-static void init_setup_aec6x80(struct pci_dev *, ide_pci_device_t *);
-static void init_setup_aec62xx(struct pci_dev *, ide_pci_device_t *);
-static unsigned int init_chipset_aec62xx(struct pci_dev *, const char *);
-static void init_hwif_aec62xx(ide_hwif_t *);
-static void init_dma_aec62xx(ide_hwif_t *, unsigned long);
-
-static ide_pci_device_t aec62xx_chipsets[] __devinitdata = {
-	{	/* 0 */
-		.name		= "AEC6210",
-		.init_setup	= init_setup_aec62xx,
-		.init_chipset	= init_chipset_aec62xx,
-		.init_hwif	= init_hwif_aec62xx,
-		.init_dma	= init_dma_aec62xx,
-		.channels	= 2,
-		.autodma	= AUTODMA,
-		.enablebits	= {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}},
-		.bootable	= OFF_BOARD,
-	},{	/* 1 */
-		.name		= "AEC6260",
-		.init_setup	= init_setup_aec62xx,
-		.init_chipset	= init_chipset_aec62xx,
-		.init_hwif	= init_hwif_aec62xx,
-		.init_dma	= init_dma_aec62xx,
-		.channels	= 2,
-		.autodma	= NOAUTODMA,
-		.bootable	= OFF_BOARD,
-	},{	/* 2 */
-		.name		= "AEC6260R",
-		.init_setup	= init_setup_aec62xx,
-		.init_chipset	= init_chipset_aec62xx,
-		.init_hwif	= init_hwif_aec62xx,
-		.init_dma	= init_dma_aec62xx,
-		.channels	= 2,
-		.autodma	= AUTODMA,
-		.enablebits	= {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}},
-		.bootable	= NEVER_BOARD,
-	},{	/* 3 */
-		.name		= "AEC6X80",
-		.init_setup	= init_setup_aec6x80,
-		.init_chipset	= init_chipset_aec62xx,
-		.init_hwif	= init_hwif_aec62xx,
-		.init_dma	= init_dma_aec62xx,
-		.channels	= 2,
-		.autodma	= AUTODMA,
-		.bootable	= OFF_BOARD,
-	},{	/* 4 */
-		.name		= "AEC6X80R",
-		.init_setup	= init_setup_aec6x80,
-		.init_chipset	= init_chipset_aec62xx,
-		.init_hwif	= init_hwif_aec62xx,
-		.init_dma	= init_dma_aec62xx,
-		.channels	= 2,
-		.autodma	= AUTODMA,
-		.enablebits	= {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}},
-		.bootable	= OFF_BOARD,
-	}
-};
-
-#endif /* AEC62XX_H */
diff -Nru a/drivers/ide/pci/alim15x3.c b/drivers/ide/pci/alim15x3.c
--- a/drivers/ide/pci/alim15x3.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/ide/pci/alim15x3.c	2005-03-01 23:38:55 -08:00
@@ -884,8 +884,7 @@
 #if defined(CONFIG_SPARC64)
 	d->init_hwif = init_hwif_common_ali15x3;
 #endif /* CONFIG_SPARC64 */
-	ide_setup_pci_device(dev, d);
-	return 0;
+	return ide_setup_pci_device(dev, d);
 }
 
 
diff -Nru a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c
--- a/drivers/ide/pci/amd74xx.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/ide/pci/amd74xx.c	2005-03-01 23:39:17 -08:00
@@ -493,9 +493,12 @@
 {
 	amd_chipset = amd74xx_chipsets + id->driver_data;
 	amd_config = amd_ide_chips + id->driver_data;
-	if (dev->device != amd_config->id) BUG();
-	ide_setup_pci_device(dev, amd_chipset);
-	return 0;
+	if (dev->device != amd_config->id) {
+		printk(KERN_ERR "%s: assertion 0x%02x == 0x%02x failed !\n",
+		       pci_name(dev), dev->device, amd_config->id);
+		return -ENODEV;
+	}
+	return ide_setup_pci_device(dev, amd_chipset);
 }
 
 static struct pci_device_id amd74xx_pci_tbl[] = {
diff -Nru a/drivers/ide/pci/atiixp.c b/drivers/ide/pci/atiixp.c
--- a/drivers/ide/pci/atiixp.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/ide/pci/atiixp.c	2005-03-01 23:38:56 -08:00
@@ -341,13 +341,13 @@
 
 static int __devinit atiixp_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-	ide_setup_pci_device(dev, &atiixp_pci_info[id->driver_data]);
-	return 0;
+	return ide_setup_pci_device(dev, &atiixp_pci_info[id->driver_data]);
 }
 
 static struct pci_device_id atiixp_pci_tbl[] = {
-	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP2_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP200_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP300_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP400_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
 	{ 0, },
 };
 MODULE_DEVICE_TABLE(pci, atiixp_pci_tbl);
diff -Nru a/drivers/ide/pci/cmd64x.c b/drivers/ide/pci/cmd64x.c
--- a/drivers/ide/pci/cmd64x.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/ide/pci/cmd64x.c	2005-03-01 23:39:09 -08:00
@@ -25,7 +25,56 @@
 
 #include <asm/io.h>
 
-#include "cmd64x.h"
+#define DISPLAY_CMD64X_TIMINGS
+
+#define CMD_DEBUG 0
+
+#if CMD_DEBUG
+#define cmdprintk(x...)	printk(x)
+#else
+#define cmdprintk(x...)
+#endif
+
+/*
+ * CMD64x specific registers definition.
+ */
+#define CFR		0x50
+#define   CFR_INTR_CH0		0x02
+#define CNTRL		0x51
+#define	  CNTRL_DIS_RA0		0x40
+#define   CNTRL_DIS_RA1		0x80
+#define	  CNTRL_ENA_2ND		0x08
+
+#define	CMDTIM		0x52
+#define	ARTTIM0		0x53
+#define	DRWTIM0		0x54
+#define ARTTIM1 	0x55
+#define DRWTIM1		0x56
+#define ARTTIM23	0x57
+#define   ARTTIM23_DIS_RA2	0x04
+#define   ARTTIM23_DIS_RA3	0x08
+#define   ARTTIM23_INTR_CH1	0x10
+#define ARTTIM2		0x57
+#define ARTTIM3		0x57
+#define DRWTIM23	0x58
+#define DRWTIM2		0x58
+#define BRST		0x59
+#define DRWTIM3		0x5b
+
+#define BMIDECR0	0x70
+#define MRDMODE		0x71
+#define   MRDMODE_INTR_CH0	0x04
+#define   MRDMODE_INTR_CH1	0x08
+#define   MRDMODE_BLK_CH0	0x10
+#define   MRDMODE_BLK_CH1	0x20
+#define BMIDESR0	0x72
+#define UDIDETCR0	0x73
+#define DTPR0		0x74
+#define BMIDECR1	0x78
+#define BMIDECSR	0x79
+#define BMIDESR1	0x7A
+#define UDIDETCR1	0x7B
+#define DTPR1		0x7C
 
 #if defined(DISPLAY_CMD64X_TIMINGS) && defined(CONFIG_PROC_FS)
 #include <linux/stat.h>
@@ -707,10 +756,42 @@
 	hwif->drives[1].autodma = hwif->autodma;
 }
 
+static ide_pci_device_t cmd64x_chipsets[] __devinitdata = {
+	{	/* 0 */
+		.name		= "CMD643",
+		.init_chipset	= init_chipset_cmd64x,
+		.init_hwif	= init_hwif_cmd64x,
+		.channels	= 2,
+		.autodma	= AUTODMA,
+		.bootable	= ON_BOARD,
+	},{	/* 1 */
+		.name		= "CMD646",
+		.init_chipset	= init_chipset_cmd64x,
+		.init_hwif	= init_hwif_cmd64x,
+		.channels	= 2,
+		.autodma	= AUTODMA,
+		.enablebits	= {{0x00,0x00,0x00}, {0x51,0x80,0x80}},
+		.bootable	= ON_BOARD,
+	},{	/* 2 */
+		.name		= "CMD648",
+		.init_chipset	= init_chipset_cmd64x,
+		.init_hwif	= init_hwif_cmd64x,
+		.channels	= 2,
+		.autodma	= AUTODMA,
+		.bootable	= ON_BOARD,
+	},{	/* 3 */
+		.name		= "CMD649",
+		.init_chipset	= init_chipset_cmd64x,
+		.init_hwif	= init_hwif_cmd64x,
+		.channels	= 2,
+		.autodma	= AUTODMA,
+		.bootable	= ON_BOARD,
+	}
+};
+
 static int __devinit cmd64x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-	ide_setup_pci_device(dev, &cmd64x_chipsets[id->driver_data]);
-	return 0;
+	return ide_setup_pci_device(dev, &cmd64x_chipsets[id->driver_data]);
 }
 
 static struct pci_device_id cmd64x_pci_tbl[] = {
diff -Nru a/drivers/ide/pci/cmd64x.h b/drivers/ide/pci/cmd64x.h
--- a/drivers/ide/pci/cmd64x.h	2005-03-01 23:38:56 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,95 +0,0 @@
-#ifndef CMD64X_H
-#define CMD64X_H
-
-#include <linux/config.h>
-#include <linux/pci.h>
-#include <linux/ide.h>
-
-#define DISPLAY_CMD64X_TIMINGS
-
-#define CMD_DEBUG 0
-
-#if CMD_DEBUG
-#define cmdprintk(x...)	printk(x)
-#else
-#define cmdprintk(x...)
-#endif
-
-/*
- * CMD64x specific registers definition.
- */
-#define CFR		0x50
-#define   CFR_INTR_CH0		0x02
-#define CNTRL		0x51
-#define	  CNTRL_DIS_RA0		0x40
-#define   CNTRL_DIS_RA1		0x80
-#define	  CNTRL_ENA_2ND		0x08
-
-#define	CMDTIM		0x52
-#define	ARTTIM0		0x53
-#define	DRWTIM0		0x54
-#define ARTTIM1 	0x55
-#define DRWTIM1		0x56
-#define ARTTIM23	0x57
-#define   ARTTIM23_DIS_RA2	0x04
-#define   ARTTIM23_DIS_RA3	0x08
-#define   ARTTIM23_INTR_CH1	0x10
-#define ARTTIM2		0x57
-#define ARTTIM3		0x57
-#define DRWTIM23	0x58
-#define DRWTIM2		0x58
-#define BRST		0x59
-#define DRWTIM3		0x5b
-
-#define BMIDECR0	0x70
-#define MRDMODE		0x71
-#define   MRDMODE_INTR_CH0	0x04
-#define   MRDMODE_INTR_CH1	0x08
-#define   MRDMODE_BLK_CH0	0x10
-#define   MRDMODE_BLK_CH1	0x20
-#define BMIDESR0	0x72
-#define UDIDETCR0	0x73
-#define DTPR0		0x74
-#define BMIDECR1	0x78
-#define BMIDECSR	0x79
-#define BMIDESR1	0x7A
-#define UDIDETCR1	0x7B
-#define DTPR1		0x7C
-
-static unsigned int init_chipset_cmd64x(struct pci_dev *, const char *);
-static void init_hwif_cmd64x(ide_hwif_t *);
-
-static ide_pci_device_t cmd64x_chipsets[] __devinitdata = {
-	{	/* 0 */
-		.name		= "CMD643",
-		.init_chipset	= init_chipset_cmd64x,
-		.init_hwif	= init_hwif_cmd64x,
-		.channels	= 2,
-		.autodma	= AUTODMA,
-		.bootable	= ON_BOARD,
-	},{	/* 1 */
-		.name		= "CMD646",
-		.init_chipset	= init_chipset_cmd64x,
-		.init_hwif	= init_hwif_cmd64x,
-		.channels	= 2,
-		.autodma	= AUTODMA,
-		.enablebits	= {{0x00,0x00,0x00}, {0x51,0x80,0x80}},
-		.bootable	= ON_BOARD,
-	},{	/* 2 */
-		.name		= "CMD648",
-		.init_chipset	= init_chipset_cmd64x,
-		.init_hwif	= init_hwif_cmd64x,
-		.channels	= 2,
-		.autodma	= AUTODMA,
-		.bootable	= ON_BOARD,
-	},{
-		.name		= "CMD649",
-		.init_chipset	= init_chipset_cmd64x,
-		.init_hwif	= init_hwif_cmd64x,
-		.channels	= 2,
-		.autodma	= AUTODMA,
-		.bootable	= ON_BOARD,
-	}
-};
-
-#endif /* CMD64X_H */
diff -Nru a/drivers/ide/pci/cs5530.c b/drivers/ide/pci/cs5530.c
--- a/drivers/ide/pci/cs5530.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/ide/pci/cs5530.c	2005-03-01 23:38:55 -08:00
@@ -357,8 +357,7 @@
 
 static int __devinit cs5530_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-	ide_setup_pci_device(dev, &cs5530_chipset);
-	return 0;
+	return ide_setup_pci_device(dev, &cs5530_chipset);
 }
 
 static struct pci_device_id cs5530_pci_tbl[] = {
diff -Nru a/drivers/ide/pci/cy82c693.c b/drivers/ide/pci/cy82c693.c
--- a/drivers/ide/pci/cy82c693.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/ide/pci/cy82c693.c	2005-03-01 23:38:53 -08:00
@@ -54,7 +54,64 @@
 
 #include <asm/io.h>
 
-#include "cy82c693.h"
+/* the current version */
+#define CY82_VERSION	"CY82C693U driver v0.34 99-13-12 Andreas S. Krebs (akrebs@altavista.net)"
+
+/*
+ *	The following are used to debug the driver.
+ */
+#define CY82C693_DEBUG_LOGS	0
+#define CY82C693_DEBUG_INFO	0
+
+/* define CY82C693_SETDMA_CLOCK to set DMA Controller Clock Speed to ATCLK */
+#undef CY82C693_SETDMA_CLOCK
+
+/*
+ *	NOTE: the value for busmaster timeout is tricky and I got it by
+ *	trial and error!  By using a to low value will cause DMA timeouts
+ *	and drop IDE performance, and by using a to high value will cause
+ *	audio playback to scatter.
+ *	If you know a better value or how to calc it, please let me know.
+ */
+
+/* twice the value written in cy82c693ub datasheet */
+#define BUSMASTER_TIMEOUT	0x50
+/*
+ * the value above was tested on my machine and it seems to work okay
+ */
+
+/* here are the offset definitions for the registers */
+#define CY82_IDE_CMDREG		0x04
+#define CY82_IDE_ADDRSETUP	0x48
+#define CY82_IDE_MASTER_IOR	0x4C
+#define CY82_IDE_MASTER_IOW	0x4D
+#define CY82_IDE_SLAVE_IOR	0x4E
+#define CY82_IDE_SLAVE_IOW	0x4F
+#define CY82_IDE_MASTER_8BIT	0x50
+#define CY82_IDE_SLAVE_8BIT	0x51
+
+#define CY82_INDEX_PORT		0x22
+#define CY82_DATA_PORT		0x23
+
+#define CY82_INDEX_CTRLREG1	0x01
+#define CY82_INDEX_CHANNEL0	0x30
+#define CY82_INDEX_CHANNEL1	0x31
+#define CY82_INDEX_TIMEOUT	0x32
+
+/* the max PIO mode - from datasheet */
+#define CY82C693_MAX_PIO	4
+
+/* the min and max PCI bus speed in MHz - from datasheet */
+#define CY82C963_MIN_BUS_SPEED	25
+#define CY82C963_MAX_BUS_SPEED	33
+
+/* the struct for the PIO mode timings */
+typedef struct pio_clocks_s {
+	u8	address_time;	/* Address setup (clocks) */
+	u8	time_16r;	/* clocks for 16bit IOR (0xF0=Active/data, 0x0F=Recovery) */
+	u8	time_16w;	/* clocks for 16bit IOW (0xF0=Active/data, 0x0F=Recovery) */
+	u8	time_8;		/* clocks for 8bit (0xF0=Active/data, 0x0F=Recovery) */
+} pio_clocks_t;
 
 /*
  * calc clocks using bus_speed
@@ -422,19 +479,32 @@
 	}
 }
 
+static ide_pci_device_t cy82c693_chipsets[] __devinitdata = {
+	{	/* 0 */
+		.name		= "CY82C693",
+		.init_chipset	= init_chipset_cy82c693,
+		.init_iops	= init_iops_cy82c693,
+		.init_hwif	= init_hwif_cy82c693,
+		.channels	= 1,
+		.autodma	= AUTODMA,
+		.bootable	= ON_BOARD,
+	}
+};
+
 static int __devinit cy82c693_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
 	ide_pci_device_t *d = &cy82c693_chipsets[id->driver_data];
 	struct pci_dev *dev2;
+	int ret = -ENODEV;
 
 	/* CY82C693 is more than only a IDE controller.
 	   Function 1 is primary IDE channel, function 2 - secondary. */
         if ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE &&
 	    PCI_FUNC(dev->devfn) == 1) {
 		dev2 = pci_find_slot(dev->bus->number, dev->devfn + 1);
-		ide_setup_pci_devices(dev, dev2, d);
+		ret = ide_setup_pci_devices(dev, dev2, d);
 	}
-	return 0;
+	return ret;
 }
 
 static struct pci_device_id cy82c693_pci_tbl[] = {
diff -Nru a/drivers/ide/pci/cy82c693.h b/drivers/ide/pci/cy82c693.h
--- a/drivers/ide/pci/cy82c693.h	2005-03-01 23:38:54 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,83 +0,0 @@
-#ifndef CY82C693_H
-#define CY82C693_H
-
-#include <linux/config.h>
-#include <linux/pci.h>
-#include <linux/ide.h>
-
-/* the current version */
-#define CY82_VERSION	"CY82C693U driver v0.34 99-13-12 Andreas S. Krebs (akrebs@altavista.net)"
-
-/*
- *	The following are used to debug the driver.
- */
-#define	CY82C693_DEBUG_LOGS	0
-#define	CY82C693_DEBUG_INFO	0
-
-/* define CY82C693_SETDMA_CLOCK to set DMA Controller Clock Speed to ATCLK */
-#undef CY82C693_SETDMA_CLOCK
-
-/*
- *	NOTE: the value for busmaster timeout is tricky and I got it by
- *	 trial and error!  By using a to low value will cause DMA timeouts
- *	 and drop IDE performance, and by using a to high value will cause
- *	 audio playback to scatter.
- *	 If you know a better value or how to calc it, please let me know.
- */
-
-/* twice the value written in cy82c693ub datasheet */
-#define BUSMASTER_TIMEOUT	0x50
-/*
- * the value above was tested on my machine and it seems to work okay
- */
-
-/* here are the offset definitions for the registers */
-#define CY82_IDE_CMDREG		0x04
-#define CY82_IDE_ADDRSETUP	0x48
-#define CY82_IDE_MASTER_IOR	0x4C	
-#define CY82_IDE_MASTER_IOW	0x4D	
-#define CY82_IDE_SLAVE_IOR	0x4E	
-#define CY82_IDE_SLAVE_IOW	0x4F
-#define CY82_IDE_MASTER_8BIT	0x50	
-#define CY82_IDE_SLAVE_8BIT	0x51	
-
-#define CY82_INDEX_PORT		0x22
-#define CY82_DATA_PORT		0x23
-
-#define CY82_INDEX_CTRLREG1	0x01
-#define CY82_INDEX_CHANNEL0	0x30
-#define CY82_INDEX_CHANNEL1	0x31
-#define CY82_INDEX_TIMEOUT	0x32
-
-/* the max PIO mode - from datasheet */
-#define CY82C693_MAX_PIO	4
-
-/* the min and max PCI bus speed in MHz - from datasheet */
-#define CY82C963_MIN_BUS_SPEED	25
-#define CY82C963_MAX_BUS_SPEED	33
-
-/* the struct for the PIO mode timings */
-typedef struct pio_clocks_s {
-        u8	address_time;	/* Address setup (clocks) */
-	u8	time_16r;	/* clocks for 16bit IOR (0xF0=Active/data, 0x0F=Recovery) */
-	u8	time_16w;	/* clocks for 16bit IOW (0xF0=Active/data, 0x0F=Recovery) */
-	u8	time_8;		/* clocks for 8bit (0xF0=Active/data, 0x0F=Recovery) */
-} pio_clocks_t;
-
-static unsigned int init_chipset_cy82c693(struct pci_dev *, const char *);
-static void init_hwif_cy82c693(ide_hwif_t *);
-static void init_iops_cy82c693(ide_hwif_t *);
-
-static ide_pci_device_t cy82c693_chipsets[] __devinitdata = {
-	{	/* 0 */
-		.name		= "CY82C693",
-		.init_chipset	= init_chipset_cy82c693,
-		.init_iops	= init_iops_cy82c693,
-		.init_hwif	= init_hwif_cy82c693,
-		.channels	= 1,
-		.autodma	= AUTODMA,
-		.bootable	= ON_BOARD,
-	}
-};
-
-#endif /* CY82C693_H */
diff -Nru a/drivers/ide/pci/generic.c b/drivers/ide/pci/generic.c
--- a/drivers/ide/pci/generic.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/ide/pci/generic.c	2005-03-01 23:38:57 -08:00
@@ -39,13 +39,6 @@
 
 #include <asm/io.h>
 
-#include "generic.h"
-
-static unsigned int __devinit init_chipset_generic (struct pci_dev *dev, const char *name)
-{
-	return 0;
-}
-
 static void __devinit init_hwif_generic (ide_hwif_t *hwif)
 {
 	switch(hwif->pci_dev->device) {
@@ -83,6 +76,89 @@
 	return 0;
 #endif	
 
+static ide_pci_device_t generic_chipsets[] __devinitdata = {
+	{	/* 0 */
+		.name		= "NS87410",
+		.init_hwif	= init_hwif_generic,
+		.channels	= 2,
+		.autodma	= AUTODMA,
+		.enablebits	= {{0x43,0x08,0x08}, {0x47,0x08,0x08}},
+		.bootable	= ON_BOARD,
+        },{	/* 1 */
+		.name		= "SAMURAI",
+		.init_hwif	= init_hwif_generic,
+		.channels	= 2,
+		.autodma	= AUTODMA,
+		.bootable	= ON_BOARD,
+	},{	/* 2 */
+		.name		= "HT6565",
+		.init_hwif	= init_hwif_generic,
+		.channels	= 2,
+		.autodma	= AUTODMA,
+		.bootable	= ON_BOARD,
+	},{	/* 3 */
+		.name		= "UM8673F",
+		.init_hwif	= init_hwif_generic,
+		.channels	= 2,
+		.autodma	= NODMA,
+		.bootable	= ON_BOARD,
+	},{	/* 4 */
+		.name		= "UM8886A",
+		.init_hwif	= init_hwif_generic,
+		.channels	= 2,
+		.autodma	= NODMA,
+		.bootable	= ON_BOARD,
+	},{	/* 5 */
+		.name		= "UM8886BF",
+		.init_hwif	= init_hwif_generic,
+		.channels	= 2,
+		.autodma	= NODMA,
+		.bootable	= ON_BOARD,
+	},{	/* 6 */
+		.name		= "HINT_IDE",
+		.init_hwif	= init_hwif_generic,
+		.channels	= 2,
+		.autodma	= AUTODMA,
+		.bootable	= ON_BOARD,
+	},{	/* 7 */
+		.name		= "VIA_IDE",
+		.init_hwif	= init_hwif_generic,
+		.channels	= 2,
+		.autodma	= NOAUTODMA,
+		.bootable	= ON_BOARD,
+	},{	/* 8 */
+		.name		= "OPTI621V",
+		.init_hwif	= init_hwif_generic,
+		.channels	= 2,
+		.autodma	= NOAUTODMA,
+		.bootable	= ON_BOARD,
+	},{	/* 9 */
+		.name		= "VIA8237SATA",
+		.init_hwif	= init_hwif_generic,
+		.channels	= 2,
+		.autodma	= AUTODMA,
+		.bootable	= OFF_BOARD,
+	},{	/* 10 */
+		.name 		= "Piccolo0102",
+		.init_hwif	= init_hwif_generic,
+		.channels	= 2,
+		.autodma	= NOAUTODMA,
+		.bootable	= ON_BOARD,
+	},{	/* 11 */
+		.name 		= "Piccolo0103",
+		.init_hwif	= init_hwif_generic,
+		.channels	= 2,
+		.autodma	= NOAUTODMA,
+		.bootable	= ON_BOARD,
+	},{	/* 12 */
+		.name 		= "Piccolo0105",
+		.init_hwif	= init_hwif_generic,
+		.channels	= 2,
+		.autodma	= NOAUTODMA,
+		.bootable	= ON_BOARD,
+	}
+};
+
 /**
  *	generic_init_one	-	called when a PIIX is found
  *	@dev: the generic device
@@ -96,25 +172,26 @@
 {
 	ide_pci_device_t *d = &generic_chipsets[id->driver_data];
 	u16 command;
+	int ret = -ENODEV;
 
 	if (dev->vendor == PCI_VENDOR_ID_UMC &&
 	    dev->device == PCI_DEVICE_ID_UMC_UM8886A &&
 	    (!(PCI_FUNC(dev->devfn) & 1)))
-		return 1; /* UM8886A/BF pair */
+		goto out; /* UM8886A/BF pair */
 
 	if (dev->vendor == PCI_VENDOR_ID_OPTI &&
 	    dev->device == PCI_DEVICE_ID_OPTI_82C558 &&
 	    (!(PCI_FUNC(dev->devfn) & 1)))
-		return 1;
+		goto out;
 
 	pci_read_config_word(dev, PCI_COMMAND, &command);
-	if(!(command & PCI_COMMAND_IO))
-	{
+	if (!(command & PCI_COMMAND_IO)) {
 		printk(KERN_INFO "Skipping disabled %s IDE controller.\n", d->name);
-		return 1; 
+		goto out;
 	}
-	ide_setup_pci_device(dev, d);
-	return 0;
+	ret = ide_setup_pci_device(dev, d);
+out:
+	return ret;
 }
 
 static struct pci_device_id generic_pci_tbl[] = {
diff -Nru a/drivers/ide/pci/generic.h b/drivers/ide/pci/generic.h
--- a/drivers/ide/pci/generic.h	2005-03-01 23:38:53 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,120 +0,0 @@
-#ifndef IDE_GENERIC_H
-#define IDE_GENERIC_H
-
-#include <linux/config.h>
-#include <linux/pci.h>
-#include <linux/ide.h>
-
-static unsigned int init_chipset_generic(struct pci_dev *, const char *);
-static void init_hwif_generic(ide_hwif_t *);
-
-static ide_pci_device_t generic_chipsets[] __devinitdata = {
-	{	/* 0 */
-		.name		= "NS87410",
-		.init_chipset	= init_chipset_generic,
-		.init_hwif	= init_hwif_generic,
-		.channels	= 2,
-		.autodma	= AUTODMA,
-		.enablebits	= {{0x43,0x08,0x08}, {0x47,0x08,0x08}},
-		.bootable	= ON_BOARD,
-        },{	/* 1 */
-		.name		= "SAMURAI",
-		.init_chipset	= init_chipset_generic,
-		.init_hwif	= init_hwif_generic,
-		.channels	= 2,
-		.autodma	= AUTODMA,
-		.bootable	= ON_BOARD,
-	},{	/* 2 */
-		.name		= "HT6565",
-		.init_chipset	= init_chipset_generic,
-		.init_hwif	= init_hwif_generic,
-		.channels	= 2,
-		.autodma	= AUTODMA,
-		.bootable	= ON_BOARD,
-	},{	/* 3 */
-		.name		= "UM8673F",
-		.init_chipset	= init_chipset_generic,
-		.init_hwif	= init_hwif_generic,
-		.channels	= 2,
-		.autodma	= NODMA,
-		.bootable	= ON_BOARD,
-	},{	/* 4 */
-		.name		= "UM8886A",
-		.init_chipset	= init_chipset_generic,
-		.init_hwif	= init_hwif_generic,
-		.channels	= 2,
-		.autodma	= NODMA,
-		.bootable	= ON_BOARD,
-	},{	/* 5 */
-		.name		= "UM8886BF",
-		.init_chipset	= init_chipset_generic,
-		.init_hwif	= init_hwif_generic,
-		.channels	= 2,
-		.autodma	= NODMA,
-		.bootable	= ON_BOARD,
-	},{	/* 6 */
-		.name		= "HINT_IDE",
-		.init_chipset	= init_chipset_generic,
-		.init_hwif	= init_hwif_generic,
-		.channels	= 2,
-		.autodma	= AUTODMA,
-		.bootable	= ON_BOARD,
-	},{	/* 7 */
-		.name		= "VIA_IDE",
-		.init_chipset	= init_chipset_generic,
-		.init_hwif	= init_hwif_generic,
-		.channels	= 2,
-		.autodma	= NOAUTODMA,
-		.bootable	= ON_BOARD,
-	},{	/* 8 */
-		.name		= "OPTI621V",
-		.init_chipset	= init_chipset_generic,
-		.init_hwif	= init_hwif_generic,
-		.channels	= 2,
-		.autodma	= NOAUTODMA,
-		.bootable	= ON_BOARD,
-	},{	/* 9 */
-		.name		= "VIA8237SATA",
-		.init_chipset	= init_chipset_generic,
-		.init_hwif	= init_hwif_generic,
-		.channels	= 2,
-		.autodma	= AUTODMA,
-		.bootable	= OFF_BOARD,
-	},{ /* 10 */
-		.name 		= "Piccolo0102",
-		.init_chipset	= init_chipset_generic,
-		.init_hwif	= init_hwif_generic,
-		.channels	= 2,
-		.autodma	= NOAUTODMA,
-		.bootable	= ON_BOARD,
-	},{ /* 11 */
-		.name 		= "Piccolo0103",
-		.init_chipset	= init_chipset_generic,
-		.init_hwif	= init_hwif_generic,
-		.channels	= 2,
-		.autodma	= NOAUTODMA,
-		.bootable	= ON_BOARD,
-	},{ /* 12 */
-		.name 		= "Piccolo0105",
-		.init_chipset	= init_chipset_generic,
-		.init_hwif	= init_hwif_generic,
-		.channels	= 2,
-		.autodma	= NOAUTODMA,
-		.bootable	= ON_BOARD,
-	}
-};
-
-#if 0
-static ide_pci_device_t unknown_chipset[] __devinitdata = {
-	{	/* 0 */
-		.name		= "PCI_IDE",
-		.init_chipset	= init_chipset_generic,
-		.init_hwif	= init_hwif_generic,
-		.channels	= 2,
-		.autodma	= AUTODMA,
-		.bootable	= ON_BOARD,
-	}
-};
-#endif
-
-#endif /* IDE_GENERIC_H */
diff -Nru a/drivers/ide/pci/hpt34x.c b/drivers/ide/pci/hpt34x.c
--- a/drivers/ide/pci/hpt34x.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/ide/pci/hpt34x.c	2005-03-01 23:38:55 -08:00
@@ -251,8 +251,7 @@
 	d->name = chipset_names[(pcicmd & PCI_COMMAND_MEMORY) ? 1 : 0];
 	d->bootable = (pcicmd & PCI_COMMAND_MEMORY) ? OFF_BOARD : NEVER_BOARD;
 
-	ide_setup_pci_device(dev, d);
-	return 0;
+	return ide_setup_pci_device(dev, d);
 }
 
 static struct pci_device_id hpt34x_pci_tbl[] = {
diff -Nru a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c
--- a/drivers/ide/pci/hpt366.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/ide/pci/hpt366.c	2005-03-01 23:39:18 -08:00
@@ -70,8 +70,383 @@
 #include <asm/io.h>
 #include <asm/irq.h>
 
-#include "hpt366.h"
+/* various tuning parameters */
+#define HPT_RESET_STATE_ENGINE
+#undef HPT_DELAY_INTERRUPT
+#undef HPT_SERIALIZE_IO
+
+static const char *quirk_drives[] = {
+	"QUANTUM FIREBALLlct08 08",
+	"QUANTUM FIREBALLP KA6.4",
+	"QUANTUM FIREBALLP LM20.4",
+	"QUANTUM FIREBALLP LM20.5",
+	NULL
+};
+
+static const char *bad_ata100_5[] = {
+	"IBM-DTLA-307075",
+	"IBM-DTLA-307060",
+	"IBM-DTLA-307045",
+	"IBM-DTLA-307030",
+	"IBM-DTLA-307020",
+	"IBM-DTLA-307015",
+	"IBM-DTLA-305040",
+	"IBM-DTLA-305030",
+	"IBM-DTLA-305020",
+	"IC35L010AVER07-0",
+	"IC35L020AVER07-0",
+	"IC35L030AVER07-0",
+	"IC35L040AVER07-0",
+	"IC35L060AVER07-0",
+	"WDC AC310200R",
+	NULL
+};
+
+static const char *bad_ata66_4[] = {
+	"IBM-DTLA-307075",
+	"IBM-DTLA-307060",
+	"IBM-DTLA-307045",
+	"IBM-DTLA-307030",
+	"IBM-DTLA-307020",
+	"IBM-DTLA-307015",
+	"IBM-DTLA-305040",
+	"IBM-DTLA-305030",
+	"IBM-DTLA-305020",
+	"IC35L010AVER07-0",
+	"IC35L020AVER07-0",
+	"IC35L030AVER07-0",
+	"IC35L040AVER07-0",
+	"IC35L060AVER07-0",
+	"WDC AC310200R",
+	NULL
+};
+
+static const char *bad_ata66_3[] = {
+	"WDC AC310200R",
+	NULL
+};
+
+static const char *bad_ata33[] = {
+	"Maxtor 92720U8", "Maxtor 92040U6", "Maxtor 91360U4", "Maxtor 91020U3", "Maxtor 90845U3", "Maxtor 90650U2",
+	"Maxtor 91360D8", "Maxtor 91190D7", "Maxtor 91020D6", "Maxtor 90845D5", "Maxtor 90680D4", "Maxtor 90510D3", "Maxtor 90340D2",
+	"Maxtor 91152D8", "Maxtor 91008D7", "Maxtor 90845D6", "Maxtor 90840D6", "Maxtor 90720D5", "Maxtor 90648D5", "Maxtor 90576D4",
+	"Maxtor 90510D4",
+	"Maxtor 90432D3", "Maxtor 90288D2", "Maxtor 90256D2",
+	"Maxtor 91000D8", "Maxtor 90910D8", "Maxtor 90875D7", "Maxtor 90840D7", "Maxtor 90750D6", "Maxtor 90625D5", "Maxtor 90500D4",
+	"Maxtor 91728D8", "Maxtor 91512D7", "Maxtor 91303D6", "Maxtor 91080D5", "Maxtor 90845D4", "Maxtor 90680D4", "Maxtor 90648D3", "Maxtor 90432D2",
+	NULL
+};
+
+struct chipset_bus_clock_list_entry {
+	u8		xfer_speed;
+	unsigned int	chipset_settings;
+};
+
+/* key for bus clock timings
+ * bit
+ * 0:3    data_high_time. inactive time of DIOW_/DIOR_ for PIO and MW
+ *        DMA. cycles = value + 1
+ * 4:8    data_low_time. active time of DIOW_/DIOR_ for PIO and MW
+ *        DMA. cycles = value + 1
+ * 9:12   cmd_high_time. inactive time of DIOW_/DIOR_ during task file
+ *        register access.
+ * 13:17  cmd_low_time. active time of DIOW_/DIOR_ during task file
+ *        register access.
+ * 18:21  udma_cycle_time. clock freq and clock cycles for UDMA xfer.
+ *        during task file register access.
+ * 22:24  pre_high_time. time to initialize 1st cycle for PIO and MW DMA
+ *        xfer.
+ * 25:27  cmd_pre_high_time. time to initialize 1st PIO cycle for task
+ *        register access.
+ * 28     UDMA enable
+ * 29     DMA enable
+ * 30     PIO_MST enable. if set, the chip is in bus master mode during
+ *        PIO.
+ * 31     FIFO enable.
+ */
+static struct chipset_bus_clock_list_entry forty_base_hpt366[] = {
+	{	XFER_UDMA_4,	0x900fd943	},
+	{	XFER_UDMA_3,	0x900ad943	},
+	{	XFER_UDMA_2,	0x900bd943	},
+	{	XFER_UDMA_1,	0x9008d943	},
+	{	XFER_UDMA_0,	0x9008d943	},
+
+	{	XFER_MW_DMA_2,	0xa008d943	},
+	{	XFER_MW_DMA_1,	0xa010d955	},
+	{	XFER_MW_DMA_0,	0xa010d9fc	},
+
+	{	XFER_PIO_4,	0xc008d963	},
+	{	XFER_PIO_3,	0xc010d974	},
+	{	XFER_PIO_2,	0xc010d997	},
+	{	XFER_PIO_1,	0xc010d9c7	},
+	{	XFER_PIO_0,	0xc018d9d9	},
+	{	0,		0x0120d9d9	}
+};
+
+static struct chipset_bus_clock_list_entry thirty_three_base_hpt366[] = {
+	{	XFER_UDMA_4,	0x90c9a731	},
+	{	XFER_UDMA_3,	0x90cfa731	},
+	{	XFER_UDMA_2,	0x90caa731	},
+	{	XFER_UDMA_1,	0x90cba731	},
+	{	XFER_UDMA_0,	0x90c8a731	},
+
+	{	XFER_MW_DMA_2,	0xa0c8a731	},
+	{	XFER_MW_DMA_1,	0xa0c8a732	},	/* 0xa0c8a733 */
+	{	XFER_MW_DMA_0,	0xa0c8a797	},
+
+	{	XFER_PIO_4,	0xc0c8a731	},
+	{	XFER_PIO_3,	0xc0c8a742	},
+	{	XFER_PIO_2,	0xc0d0a753	},
+	{	XFER_PIO_1,	0xc0d0a7a3	},	/* 0xc0d0a793 */
+	{	XFER_PIO_0,	0xc0d0a7aa	},	/* 0xc0d0a7a7 */
+	{	0,		0x0120a7a7	}
+};
+
+static struct chipset_bus_clock_list_entry twenty_five_base_hpt366[] = {
+	{	XFER_UDMA_4,	0x90c98521	},
+	{	XFER_UDMA_3,	0x90cf8521	},
+	{	XFER_UDMA_2,	0x90cf8521	},
+	{	XFER_UDMA_1,	0x90cb8521	},
+	{	XFER_UDMA_0,	0x90cb8521	},
+
+	{	XFER_MW_DMA_2,	0xa0ca8521	},
+	{	XFER_MW_DMA_1,	0xa0ca8532	},
+	{	XFER_MW_DMA_0,	0xa0ca8575	},
+
+	{	XFER_PIO_4,	0xc0ca8521	},
+	{	XFER_PIO_3,	0xc0ca8532	},
+	{	XFER_PIO_2,	0xc0ca8542	},
+	{	XFER_PIO_1,	0xc0d08572	},
+	{	XFER_PIO_0,	0xc0d08585	},
+	{	0,		0x01208585	}
+};
+
+/* from highpoint documentation. these are old values */
+static struct chipset_bus_clock_list_entry thirty_three_base_hpt370[] = {
+/*	{	XFER_UDMA_5,	0x1A85F442,	0x16454e31	}, */
+	{	XFER_UDMA_5,	0x16454e31	},
+	{	XFER_UDMA_4,	0x16454e31	},
+	{	XFER_UDMA_3,	0x166d4e31	},
+	{	XFER_UDMA_2,	0x16494e31	},
+	{	XFER_UDMA_1,	0x164d4e31	},
+	{	XFER_UDMA_0,	0x16514e31	},
+
+	{	XFER_MW_DMA_2,	0x26514e21	},
+	{	XFER_MW_DMA_1,	0x26514e33	},
+	{	XFER_MW_DMA_0,	0x26514e97	},
+
+	{	XFER_PIO_4,	0x06514e21	},
+	{	XFER_PIO_3,	0x06514e22	},
+	{	XFER_PIO_2,	0x06514e33	},
+	{	XFER_PIO_1,	0x06914e43	},
+	{	XFER_PIO_0,	0x06914e57	},
+	{	0,		0x06514e57	}
+};
+
+static struct chipset_bus_clock_list_entry sixty_six_base_hpt370[] = {
+	{	XFER_UDMA_5,	0x14846231	},
+	{	XFER_UDMA_4,	0x14886231	},
+	{	XFER_UDMA_3,	0x148c6231	},
+	{	XFER_UDMA_2,	0x148c6231	},
+	{	XFER_UDMA_1,	0x14906231	},
+	{	XFER_UDMA_0,	0x14986231	},
+
+	{	XFER_MW_DMA_2,	0x26514e21	},
+	{	XFER_MW_DMA_1,	0x26514e33	},
+	{	XFER_MW_DMA_0,	0x26514e97	},
+
+	{	XFER_PIO_4,	0x06514e21	},
+	{	XFER_PIO_3,	0x06514e22	},
+	{	XFER_PIO_2,	0x06514e33	},
+	{	XFER_PIO_1,	0x06914e43	},
+	{	XFER_PIO_0,	0x06914e57	},
+	{	0,		0x06514e57	}
+};
+
+/* these are the current (4 sep 2001) timings from highpoint */
+static struct chipset_bus_clock_list_entry thirty_three_base_hpt370a[] = {
+	{	XFER_UDMA_5,	0x12446231	},
+	{	XFER_UDMA_4,	0x12446231	},
+	{	XFER_UDMA_3,	0x126c6231	},
+	{	XFER_UDMA_2,	0x12486231	},
+	{	XFER_UDMA_1,	0x124c6233	},
+	{	XFER_UDMA_0,	0x12506297	},
+
+	{	XFER_MW_DMA_2,	0x22406c31	},
+	{	XFER_MW_DMA_1,	0x22406c33	},
+	{	XFER_MW_DMA_0,	0x22406c97	},
+
+	{	XFER_PIO_4,	0x06414e31	},
+	{	XFER_PIO_3,	0x06414e42	},
+	{	XFER_PIO_2,	0x06414e53	},
+	{	XFER_PIO_1,	0x06814e93	},
+	{	XFER_PIO_0,	0x06814ea7	},
+	{	0,		0x06814ea7	}
+};
+
+/* 2x 33MHz timings */
+static struct chipset_bus_clock_list_entry sixty_six_base_hpt370a[] = {
+	{	XFER_UDMA_5,	0x1488e673	},
+	{	XFER_UDMA_4,	0x1488e673	},
+	{	XFER_UDMA_3,	0x1498e673	},
+	{	XFER_UDMA_2,	0x1490e673	},
+	{	XFER_UDMA_1,	0x1498e677	},
+	{	XFER_UDMA_0,	0x14a0e73f	},
+
+	{	XFER_MW_DMA_2,	0x2480fa73	},
+	{	XFER_MW_DMA_1,	0x2480fa77	}, 
+	{	XFER_MW_DMA_0,	0x2480fb3f	},
+
+	{	XFER_PIO_4,	0x0c82be73	},
+	{	XFER_PIO_3,	0x0c82be95	},
+	{	XFER_PIO_2,	0x0c82beb7	},
+	{	XFER_PIO_1,	0x0d02bf37	},
+	{	XFER_PIO_0,	0x0d02bf5f	},
+	{	0,		0x0d02bf5f	}
+};
+
+static struct chipset_bus_clock_list_entry fifty_base_hpt370a[] = {
+	{	XFER_UDMA_5,	0x12848242	},
+	{	XFER_UDMA_4,	0x12ac8242	},
+	{	XFER_UDMA_3,	0x128c8242	},
+	{	XFER_UDMA_2,	0x120c8242	},
+	{	XFER_UDMA_1,	0x12148254	},
+	{	XFER_UDMA_0,	0x121882ea	},
+
+	{	XFER_MW_DMA_2,	0x22808242	},
+	{	XFER_MW_DMA_1,	0x22808254	},
+	{	XFER_MW_DMA_0,	0x228082ea	},
+
+	{	XFER_PIO_4,	0x0a81f442	},
+	{	XFER_PIO_3,	0x0a81f443	},
+	{	XFER_PIO_2,	0x0a81f454	},
+	{	XFER_PIO_1,	0x0ac1f465	},
+	{	XFER_PIO_0,	0x0ac1f48a	},
+	{	0,		0x0ac1f48a	}
+};
+
+static struct chipset_bus_clock_list_entry thirty_three_base_hpt372[] = {
+	{	XFER_UDMA_6,	0x1c81dc62	},
+	{	XFER_UDMA_5,	0x1c6ddc62	},
+	{	XFER_UDMA_4,	0x1c8ddc62	},
+	{	XFER_UDMA_3,	0x1c8edc62	},	/* checkme */
+	{	XFER_UDMA_2,	0x1c91dc62	},
+	{	XFER_UDMA_1,	0x1c9adc62	},	/* checkme */
+	{	XFER_UDMA_0,	0x1c82dc62	},	/* checkme */
+
+	{	XFER_MW_DMA_2,	0x2c829262	},
+	{	XFER_MW_DMA_1,	0x2c829266	},	/* checkme */
+	{	XFER_MW_DMA_0,	0x2c82922e	},	/* checkme */
+
+	{	XFER_PIO_4,	0x0c829c62	},
+	{	XFER_PIO_3,	0x0c829c84	},
+	{	XFER_PIO_2,	0x0c829ca6	},
+	{	XFER_PIO_1,	0x0d029d26	},
+	{	XFER_PIO_0,	0x0d029d5e	},
+	{	0,		0x0d029d5e	}
+};
+
+static struct chipset_bus_clock_list_entry fifty_base_hpt372[] = {
+	{	XFER_UDMA_5,	0x12848242	},
+	{	XFER_UDMA_4,	0x12ac8242	},
+	{	XFER_UDMA_3,	0x128c8242	},
+	{	XFER_UDMA_2,	0x120c8242	},
+	{	XFER_UDMA_1,	0x12148254	},
+	{	XFER_UDMA_0,	0x121882ea	},
+
+	{	XFER_MW_DMA_2,	0x22808242	},
+	{	XFER_MW_DMA_1,	0x22808254	},
+	{	XFER_MW_DMA_0,	0x228082ea	},
+
+	{	XFER_PIO_4,	0x0a81f442	},
+	{	XFER_PIO_3,	0x0a81f443	},
+	{	XFER_PIO_2,	0x0a81f454	},
+	{	XFER_PIO_1,	0x0ac1f465	},
+	{	XFER_PIO_0,	0x0ac1f48a	},
+	{	0,		0x0a81f443	}
+};
+
+static struct chipset_bus_clock_list_entry sixty_six_base_hpt372[] = {
+	{	XFER_UDMA_6,	0x1c869c62	},
+	{	XFER_UDMA_5,	0x1cae9c62	},
+	{	XFER_UDMA_4,	0x1c8a9c62	},
+	{	XFER_UDMA_3,	0x1c8e9c62	},
+	{	XFER_UDMA_2,	0x1c929c62	},
+	{	XFER_UDMA_1,	0x1c9a9c62	},
+	{	XFER_UDMA_0,	0x1c829c62	},
+
+	{	XFER_MW_DMA_2,	0x2c829c62	},
+	{	XFER_MW_DMA_1,	0x2c829c66	},
+	{	XFER_MW_DMA_0,	0x2c829d2e	},
+
+	{	XFER_PIO_4,	0x0c829c62	},
+	{	XFER_PIO_3,	0x0c829c84	},
+	{	XFER_PIO_2,	0x0c829ca6	},
+	{	XFER_PIO_1,	0x0d029d26	},
+	{	XFER_PIO_0,	0x0d029d5e	},
+	{	0,		0x0d029d26	}
+};
+
+static struct chipset_bus_clock_list_entry thirty_three_base_hpt374[] = {
+	{	XFER_UDMA_6,	0x12808242	},
+	{	XFER_UDMA_5,	0x12848242	},
+	{	XFER_UDMA_4,	0x12ac8242	},
+	{	XFER_UDMA_3,	0x128c8242	},
+	{	XFER_UDMA_2,	0x120c8242	},
+	{	XFER_UDMA_1,	0x12148254	},
+	{	XFER_UDMA_0,	0x121882ea	},
+
+	{	XFER_MW_DMA_2,	0x22808242	},
+	{	XFER_MW_DMA_1,	0x22808254	},
+	{	XFER_MW_DMA_0,	0x228082ea	},
+
+	{	XFER_PIO_4,	0x0a81f442	},
+	{	XFER_PIO_3,	0x0a81f443	},
+	{	XFER_PIO_2,	0x0a81f454	},
+	{	XFER_PIO_1,	0x0ac1f465	},
+	{	XFER_PIO_0,	0x0ac1f48a	},
+	{	0,		0x06814e93	}
+};
+
+/* FIXME: 50MHz timings for HPT374 */
+
+#if 0
+static struct chipset_bus_clock_list_entry sixty_six_base_hpt374[] = {
+	{	XFER_UDMA_6,	0x12406231	},	/* checkme */
+	{	XFER_UDMA_5,	0x12446231	},	/* 0x14846231 */
+	{	XFER_UDMA_4,	0x16814ea7	},	/* 0x14886231 */
+	{	XFER_UDMA_3,	0x16814ea7	},	/* 0x148c6231 */
+	{	XFER_UDMA_2,	0x16814ea7	},	/* 0x148c6231 */
+	{	XFER_UDMA_1,	0x16814ea7	},	/* 0x14906231 */
+	{	XFER_UDMA_0,	0x16814ea7	},	/* 0x14986231 */
+	{	XFER_MW_DMA_2,	0x16814ea7	},	/* 0x26514e21 */
+	{	XFER_MW_DMA_1,	0x16814ea7	},	/* 0x26514e97 */
+	{	XFER_MW_DMA_0,	0x16814ea7	},	/* 0x26514e97 */
+	{	XFER_PIO_4,	0x06814ea7	},	/* 0x06514e21 */
+	{	XFER_PIO_3,	0x06814ea7	},	/* 0x06514e22 */
+	{	XFER_PIO_2,	0x06814ea7	},	/* 0x06514e33 */
+	{	XFER_PIO_1,	0x06814ea7	},	/* 0x06914e43 */
+	{	XFER_PIO_0,	0x06814ea7	},	/* 0x06914e57 */
+	{	0,		0x06814ea7	}
+};
+#endif
+
+#define HPT366_DEBUG_DRIVE_INFO		0
+#define HPT374_ALLOW_ATA133_6		0
+#define HPT371_ALLOW_ATA133_6		0
+#define HPT302_ALLOW_ATA133_6		0
+#define HPT372_ALLOW_ATA133_6		1
+#define HPT370_ALLOW_ATA100_5		1
+#define HPT366_ALLOW_ATA66_4		1
+#define HPT366_ALLOW_ATA66_3		1
+#define HPT366_MAX_DEVS			8
+
+#define F_LOW_PCI_33	0x23
+#define F_LOW_PCI_40	0x29
+#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;
@@ -643,32 +1018,25 @@
 }
 
 /**
- *	hpt372n_rw_disk		-	wrapper for I/O
+ *	hpt372n_rw_disk		-	prepare for I/O
  *	@drive: drive for command
  *	@rq: block request structure
- *	@block: block number
- *
- *	This is called when a disk I/O is issued to the 372N instead
- *	of the default functionality. We need it because of the clock
- *	switching
  *
+ *	This is called when a disk I/O is issued to the 372N.
+ *	We need it because of the clock switching.
  */
- 
-static ide_startstop_t hpt372n_rw_disk(ide_drive_t *drive, struct request *rq, sector_t block)
+
+static void hpt372n_rw_disk(ide_drive_t *drive, struct request *rq)
 {
+	ide_hwif_t *hwif = drive->hwif;
 	int wantclock;
-	
-	if(rq_data_dir(rq) == READ)
-		wantclock = 0x21;
-	else
-		wantclock = 0x23;
-		
-	if(HWIF(drive)->config_data != wantclock)
-	{
+
+	wantclock = rq_data_dir(rq) ? 0x23 : 0x21;
+
+	if (hwif->config_data != wantclock) {
 		hpt372n_set_clock(drive, wantclock);
-		HWIF(drive)->config_data = wantclock;
+		hwif->config_data = wantclock;
 	}
-	return __ide_do_rw_disk(drive, rq, block);
 }
 
 /*
@@ -1191,12 +1559,12 @@
 	ide_setup_dma(hwif, dmabase, 8);
 }
 
-static void __devinit init_setup_hpt374(struct pci_dev *dev, ide_pci_device_t *d)
+static int __devinit init_setup_hpt374(struct pci_dev *dev, ide_pci_device_t *d)
 {
 	struct pci_dev *findev = NULL;
 
 	if (PCI_FUNC(dev->devfn) & 1)
-		return;
+		return -ENODEV;
 
 	while ((findev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, findev)) != NULL) {
 		if ((findev->vendor == dev->vendor) &&
@@ -1209,19 +1577,18 @@
 				printk(KERN_WARNING "%s: pci-config space interrupt "
 					"fixed.\n", d->name);
 			}
-			ide_setup_pci_devices(dev, findev, d);
-			return;
+			return ide_setup_pci_devices(dev, findev, d);
 		}
 	}
-	ide_setup_pci_device(dev, d);
+	return ide_setup_pci_device(dev, d);
 }
 
-static void __devinit init_setup_hpt37x(struct pci_dev *dev, ide_pci_device_t *d)
+static int __devinit init_setup_hpt37x(struct pci_dev *dev, ide_pci_device_t *d)
 {
-	ide_setup_pci_device(dev, d);
+	return ide_setup_pci_device(dev, d);
 }
 
-static void __devinit init_setup_hpt366(struct pci_dev *dev, ide_pci_device_t *d)
+static int __devinit init_setup_hpt366(struct pci_dev *dev, ide_pci_device_t *d)
 {
 	struct pci_dev *findev = NULL;
 	u8 pin1 = 0, pin2 = 0;
@@ -1231,7 +1598,7 @@
 				 "HPT372N" };
 
 	if (PCI_FUNC(dev->devfn) & 1)
-		return;
+		return -ENODEV;
 
 	pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
 	class_rev &= 0xff;
@@ -1246,9 +1613,10 @@
 		case 6:
 		case 5:
 		case 4:
-		case 3: ide_setup_pci_device(dev, d);
-			return;
-		default:	break;
+		case 3:
+			goto init_single;
+		default:
+			break;
 	}
 
 	d->channels = 1;
@@ -1266,13 +1634,71 @@
 					"pin1=%d pin2=%d\n", d->name,
 					pin1, pin2);
 			}
-			ide_setup_pci_devices(dev, findev, d);
-			return;
+			return ide_setup_pci_devices(dev, findev, d);
 		}
 	}
-	ide_setup_pci_device(dev, d);
+init_single:
+	return ide_setup_pci_device(dev, d);
 }
 
+static ide_pci_device_t hpt366_chipsets[] __devinitdata = {
+	{	/* 0 */
+		.name		= "HPT366",
+		.init_setup	= init_setup_hpt366,
+		.init_chipset	= init_chipset_hpt366,
+		.init_hwif	= init_hwif_hpt366,
+		.init_dma	= init_dma_hpt366,
+		.channels	= 2,
+		.autodma	= AUTODMA,
+		.bootable	= OFF_BOARD,
+		.extra		= 240
+	},{	/* 1 */
+		.name		= "HPT372A",
+		.init_setup	= init_setup_hpt37x,
+		.init_chipset	= init_chipset_hpt366,
+		.init_hwif	= init_hwif_hpt366,
+		.init_dma	= init_dma_hpt366,
+		.channels	= 2,
+		.autodma	= AUTODMA,
+		.bootable	= OFF_BOARD,
+	},{	/* 2 */
+		.name		= "HPT302",
+		.init_setup	= init_setup_hpt37x,
+		.init_chipset	= init_chipset_hpt366,
+		.init_hwif	= init_hwif_hpt366,
+		.init_dma	= init_dma_hpt366,
+		.channels	= 2,
+		.autodma	= AUTODMA,
+		.bootable	= OFF_BOARD,
+	},{	/* 3 */
+		.name		= "HPT371",
+		.init_setup	= init_setup_hpt37x,
+		.init_chipset	= init_chipset_hpt366,
+		.init_hwif	= init_hwif_hpt366,
+		.init_dma	= init_dma_hpt366,
+		.channels	= 2,
+		.autodma	= AUTODMA,
+		.bootable	= OFF_BOARD,
+	},{	/* 4 */
+		.name		= "HPT374",
+		.init_setup	= init_setup_hpt374,
+		.init_chipset	= init_chipset_hpt366,
+		.init_hwif	= init_hwif_hpt366,
+		.init_dma	= init_dma_hpt366,
+		.channels	= 2,	/* 4 */
+		.autodma	= AUTODMA,
+		.bootable	= OFF_BOARD,
+	},{	/* 5 */
+		.name		= "HPT372N",
+		.init_setup	= init_setup_hpt37x,
+		.init_chipset	= init_chipset_hpt366,
+		.init_hwif	= init_hwif_hpt366,
+		.init_dma	= init_dma_hpt366,
+		.channels	= 2,	/* 4 */
+		.autodma	= AUTODMA,
+		.bootable	= OFF_BOARD,
+	}
+};
 
 /**
  *	hpt366_init_one	-	called when an HPT366 is found
@@ -1287,8 +1713,7 @@
 {
 	ide_pci_device_t *d = &hpt366_chipsets[id->driver_data];
 
-	d->init_setup(dev, d);
-	return 0;
+	return d->init_setup(dev, d);
 }
 
 static struct pci_device_id hpt366_pci_tbl[] = {
diff -Nru a/drivers/ide/pci/hpt366.h b/drivers/ide/pci/hpt366.h
--- a/drivers/ide/pci/hpt366.h	2005-03-01 23:39:08 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,483 +0,0 @@
-#ifndef HPT366_H
-#define HPT366_H
-
-#include <linux/config.h>
-#include <linux/pci.h>
-#include <linux/ide.h>
-
-/* various tuning parameters */
-#define HPT_RESET_STATE_ENGINE
-#undef HPT_DELAY_INTERRUPT
-#undef HPT_SERIALIZE_IO
-
-static const char *quirk_drives[] = {
-	"QUANTUM FIREBALLlct08 08",
-	"QUANTUM FIREBALLP KA6.4",
-	"QUANTUM FIREBALLP LM20.4",
-	"QUANTUM FIREBALLP LM20.5",
-        NULL
-};
-
-static const char *bad_ata100_5[] = {
-	"IBM-DTLA-307075",
-	"IBM-DTLA-307060",
-	"IBM-DTLA-307045",
-	"IBM-DTLA-307030",
-	"IBM-DTLA-307020",
-	"IBM-DTLA-307015",
-	"IBM-DTLA-305040",
-	"IBM-DTLA-305030",
-	"IBM-DTLA-305020",
-	"IC35L010AVER07-0",
-	"IC35L020AVER07-0",
-	"IC35L030AVER07-0",
-	"IC35L040AVER07-0",
-	"IC35L060AVER07-0",
-	"WDC AC310200R",
-	NULL
-};
-
-static const char *bad_ata66_4[] = {
-	"IBM-DTLA-307075",
-	"IBM-DTLA-307060",
-	"IBM-DTLA-307045",
-	"IBM-DTLA-307030",
-	"IBM-DTLA-307020",
-	"IBM-DTLA-307015",
-	"IBM-DTLA-305040",
-	"IBM-DTLA-305030",
-	"IBM-DTLA-305020",
-	"IC35L010AVER07-0",
-	"IC35L020AVER07-0",
-	"IC35L030AVER07-0",
-	"IC35L040AVER07-0",
-	"IC35L060AVER07-0",
-	"WDC AC310200R",
-	NULL
-};
-
-static const char *bad_ata66_3[] = {
-	"WDC AC310200R",
-	NULL
-};
-
-static const char *bad_ata33[] = {
-	"Maxtor 92720U8", "Maxtor 92040U6", "Maxtor 91360U4", "Maxtor 91020U3", "Maxtor 90845U3", "Maxtor 90650U2",
-	"Maxtor 91360D8", "Maxtor 91190D7", "Maxtor 91020D6", "Maxtor 90845D5", "Maxtor 90680D4", "Maxtor 90510D3", "Maxtor 90340D2",
-	"Maxtor 91152D8", "Maxtor 91008D7", "Maxtor 90845D6", "Maxtor 90840D6", "Maxtor 90720D5", "Maxtor 90648D5", "Maxtor 90576D4",
-	"Maxtor 90510D4",
-	"Maxtor 90432D3", "Maxtor 90288D2", "Maxtor 90256D2",
-	"Maxtor 91000D8", "Maxtor 90910D8", "Maxtor 90875D7", "Maxtor 90840D7", "Maxtor 90750D6", "Maxtor 90625D5", "Maxtor 90500D4",
-	"Maxtor 91728D8", "Maxtor 91512D7", "Maxtor 91303D6", "Maxtor 91080D5", "Maxtor 90845D4", "Maxtor 90680D4", "Maxtor 90648D3", "Maxtor 90432D2",
-	NULL
-};
-
-struct chipset_bus_clock_list_entry {
-	byte		xfer_speed;
-	unsigned int	chipset_settings;
-};
-
-/* key for bus clock timings
- * bit
- * 0:3    data_high_time. inactive time of DIOW_/DIOR_ for PIO and MW
- *        DMA. cycles = value + 1
- * 4:8    data_low_time. active time of DIOW_/DIOR_ for PIO and MW
- *        DMA. cycles = value + 1
- * 9:12   cmd_high_time. inactive time of DIOW_/DIOR_ during task file
- *        register access.
- * 13:17  cmd_low_time. active time of DIOW_/DIOR_ during task file
- *        register access.
- * 18:21  udma_cycle_time. clock freq and clock cycles for UDMA xfer.
- *        during task file register access.
- * 22:24  pre_high_time. time to initialize 1st cycle for PIO and MW DMA
- *        xfer.
- * 25:27  cmd_pre_high_time. time to initialize 1st PIO cycle for task
- *        register access.
- * 28     UDMA enable
- * 29     DMA enable
- * 30     PIO_MST enable. if set, the chip is in bus master mode during
- *        PIO.
- * 31     FIFO enable.
- */
-static struct chipset_bus_clock_list_entry forty_base_hpt366[] = {
-	{	XFER_UDMA_4,	0x900fd943	},
-	{	XFER_UDMA_3,	0x900ad943	},
-	{	XFER_UDMA_2,	0x900bd943	},
-	{	XFER_UDMA_1,	0x9008d943	},
-	{	XFER_UDMA_0,	0x9008d943	},
-
-	{	XFER_MW_DMA_2,	0xa008d943	},
-	{	XFER_MW_DMA_1,	0xa010d955	},
-	{	XFER_MW_DMA_0,	0xa010d9fc	},
-
-	{	XFER_PIO_4,	0xc008d963	},
-	{	XFER_PIO_3,	0xc010d974	},
-	{	XFER_PIO_2,	0xc010d997	},
-	{	XFER_PIO_1,	0xc010d9c7	},
-	{	XFER_PIO_0,	0xc018d9d9	},
-	{	0,		0x0120d9d9	}
-};
-
-static struct chipset_bus_clock_list_entry thirty_three_base_hpt366[] = {
-	{	XFER_UDMA_4,	0x90c9a731	},
-	{	XFER_UDMA_3,	0x90cfa731	},
-	{	XFER_UDMA_2,	0x90caa731	},
-	{	XFER_UDMA_1,	0x90cba731	},
-	{	XFER_UDMA_0,	0x90c8a731	},
-
-	{	XFER_MW_DMA_2,	0xa0c8a731	},
-	{	XFER_MW_DMA_1,	0xa0c8a732	},	/* 0xa0c8a733 */
-	{	XFER_MW_DMA_0,	0xa0c8a797	},
-
-	{	XFER_PIO_4,	0xc0c8a731	},
-	{	XFER_PIO_3,	0xc0c8a742	},
-	{	XFER_PIO_2,	0xc0d0a753	},
-	{	XFER_PIO_1,	0xc0d0a7a3	},	/* 0xc0d0a793 */
-	{	XFER_PIO_0,	0xc0d0a7aa	},	/* 0xc0d0a7a7 */
-	{	0,		0x0120a7a7	}
-};
-
-static struct chipset_bus_clock_list_entry twenty_five_base_hpt366[] = {
-
-	{	XFER_UDMA_4,	0x90c98521	},
-	{	XFER_UDMA_3,	0x90cf8521	},
-	{	XFER_UDMA_2,	0x90cf8521	},
-	{	XFER_UDMA_1,	0x90cb8521	},
-	{	XFER_UDMA_0,	0x90cb8521	},
-
-	{	XFER_MW_DMA_2,	0xa0ca8521	},
-	{	XFER_MW_DMA_1,	0xa0ca8532	},
-	{	XFER_MW_DMA_0,	0xa0ca8575	},
-
-	{	XFER_PIO_4,	0xc0ca8521	},
-	{	XFER_PIO_3,	0xc0ca8532	},
-	{	XFER_PIO_2,	0xc0ca8542	},
-	{	XFER_PIO_1,	0xc0d08572	},
-	{	XFER_PIO_0,	0xc0d08585	},
-	{	0,		0x01208585	}
-};
-
-/* from highpoint documentation. these are old values */
-static struct chipset_bus_clock_list_entry thirty_three_base_hpt370[] = {
-/*	{	XFER_UDMA_5,	0x1A85F442,	0x16454e31	}, */
-	{	XFER_UDMA_5,	0x16454e31	},
-	{	XFER_UDMA_4,	0x16454e31	},
-	{	XFER_UDMA_3,	0x166d4e31	},
-	{	XFER_UDMA_2,	0x16494e31	},
-	{	XFER_UDMA_1,	0x164d4e31	},
-	{	XFER_UDMA_0,	0x16514e31	},
-
-	{	XFER_MW_DMA_2,	0x26514e21	},
-	{	XFER_MW_DMA_1,	0x26514e33	},
-	{	XFER_MW_DMA_0,	0x26514e97	},
-
-	{	XFER_PIO_4,	0x06514e21	},
-	{	XFER_PIO_3,	0x06514e22	},
-	{	XFER_PIO_2,	0x06514e33	},
-	{	XFER_PIO_1,	0x06914e43	},
-	{	XFER_PIO_0,	0x06914e57	},
-	{	0,		0x06514e57	}
-};
-
-static struct chipset_bus_clock_list_entry sixty_six_base_hpt370[] = {
-	{       XFER_UDMA_5,    0x14846231      },
-	{       XFER_UDMA_4,    0x14886231      },
-	{       XFER_UDMA_3,    0x148c6231      },
-	{       XFER_UDMA_2,    0x148c6231      },
-	{       XFER_UDMA_1,    0x14906231      },
-	{       XFER_UDMA_0,    0x14986231      },
-	
-	{       XFER_MW_DMA_2,  0x26514e21      },
-	{       XFER_MW_DMA_1,  0x26514e33      },
-	{       XFER_MW_DMA_0,  0x26514e97      },
-	
-	{       XFER_PIO_4,     0x06514e21      },
-	{       XFER_PIO_3,     0x06514e22      },
-	{       XFER_PIO_2,     0x06514e33      },
-	{       XFER_PIO_1,     0x06914e43      },
-	{       XFER_PIO_0,     0x06914e57      },
-	{       0,              0x06514e57      }
-};
-
-/* these are the current (4 sep 2001) timings from highpoint */
-static struct chipset_bus_clock_list_entry thirty_three_base_hpt370a[] = {
-        {       XFER_UDMA_5,    0x12446231      },
-        {       XFER_UDMA_4,    0x12446231      },
-        {       XFER_UDMA_3,    0x126c6231      },
-        {       XFER_UDMA_2,    0x12486231      },
-        {       XFER_UDMA_1,    0x124c6233      },
-        {       XFER_UDMA_0,    0x12506297      },
-
-        {       XFER_MW_DMA_2,  0x22406c31      },
-        {       XFER_MW_DMA_1,  0x22406c33      },
-        {       XFER_MW_DMA_0,  0x22406c97      },
-
-        {       XFER_PIO_4,     0x06414e31      },
-        {       XFER_PIO_3,     0x06414e42      },
-        {       XFER_PIO_2,     0x06414e53      },
-        {       XFER_PIO_1,     0x06814e93      },
-        {       XFER_PIO_0,     0x06814ea7      },
-        {       0,              0x06814ea7      }
-};
-
-/* 2x 33MHz timings */
-static struct chipset_bus_clock_list_entry sixty_six_base_hpt370a[] = {
-	{       XFER_UDMA_5,    0x1488e673       },
-	{       XFER_UDMA_4,    0x1488e673       },
-	{       XFER_UDMA_3,    0x1498e673       },
-	{       XFER_UDMA_2,    0x1490e673       },
-	{       XFER_UDMA_1,    0x1498e677       },
-	{       XFER_UDMA_0,    0x14a0e73f       },
-
-	{       XFER_MW_DMA_2,  0x2480fa73       },
-	{       XFER_MW_DMA_1,  0x2480fa77       }, 
-	{       XFER_MW_DMA_0,  0x2480fb3f       },
-
-	{       XFER_PIO_4,     0x0c82be73       },
-	{       XFER_PIO_3,     0x0c82be95       },
-	{       XFER_PIO_2,     0x0c82beb7       },
-	{       XFER_PIO_1,     0x0d02bf37       },
-	{       XFER_PIO_0,     0x0d02bf5f       },
-	{       0,              0x0d02bf5f       }
-};
-
-static struct chipset_bus_clock_list_entry fifty_base_hpt370a[] = {
-	{       XFER_UDMA_5,    0x12848242      },
-	{       XFER_UDMA_4,    0x12ac8242      },
-	{       XFER_UDMA_3,    0x128c8242      },
-	{       XFER_UDMA_2,    0x120c8242      },
-	{       XFER_UDMA_1,    0x12148254      },
-	{       XFER_UDMA_0,    0x121882ea      },
-
-	{       XFER_MW_DMA_2,  0x22808242      },
-	{       XFER_MW_DMA_1,  0x22808254      },
-	{       XFER_MW_DMA_0,  0x228082ea      },
-
-	{       XFER_PIO_4,     0x0a81f442      },
-	{       XFER_PIO_3,     0x0a81f443      },
-	{       XFER_PIO_2,     0x0a81f454      },
-	{       XFER_PIO_1,     0x0ac1f465      },
-	{       XFER_PIO_0,     0x0ac1f48a      },
-	{       0,              0x0ac1f48a      }
-};
-
-static struct chipset_bus_clock_list_entry thirty_three_base_hpt372[] = {
-	{	XFER_UDMA_6,	0x1c81dc62	},
-	{	XFER_UDMA_5,	0x1c6ddc62	},
-	{	XFER_UDMA_4,	0x1c8ddc62	},
-	{	XFER_UDMA_3,	0x1c8edc62	},	/* checkme */
-	{	XFER_UDMA_2,	0x1c91dc62	},
-	{	XFER_UDMA_1,	0x1c9adc62	},	/* checkme */
-	{	XFER_UDMA_0,	0x1c82dc62	},	/* checkme */
-
-	{	XFER_MW_DMA_2,	0x2c829262	},
-	{	XFER_MW_DMA_1,	0x2c829266	},	/* checkme */
-	{	XFER_MW_DMA_0,	0x2c82922e	},	/* checkme */
-
-	{	XFER_PIO_4,	0x0c829c62	},
-	{	XFER_PIO_3,	0x0c829c84	},
-	{	XFER_PIO_2,	0x0c829ca6	},
-	{	XFER_PIO_1,	0x0d029d26	},
-	{	XFER_PIO_0,	0x0d029d5e	},
-	{	0,		0x0d029d5e	}
-};
-
-static struct chipset_bus_clock_list_entry fifty_base_hpt372[] = {
-	{	XFER_UDMA_5,	0x12848242	},
-	{	XFER_UDMA_4,	0x12ac8242	},
-	{	XFER_UDMA_3,	0x128c8242	},
-	{	XFER_UDMA_2,	0x120c8242	},
-	{	XFER_UDMA_1,	0x12148254	},
-	{	XFER_UDMA_0,	0x121882ea	},
-
-	{	XFER_MW_DMA_2,	0x22808242	},
-	{	XFER_MW_DMA_1,	0x22808254	},
-	{	XFER_MW_DMA_0,	0x228082ea	},
-
-	{	XFER_PIO_4,	0x0a81f442	},
-	{	XFER_PIO_3,	0x0a81f443	},
-	{	XFER_PIO_2,	0x0a81f454	},
-	{	XFER_PIO_1,	0x0ac1f465	},
-	{	XFER_PIO_0,	0x0ac1f48a	},
-	{	0,		0x0a81f443	}
-};
-
-static struct chipset_bus_clock_list_entry sixty_six_base_hpt372[] = {
-	{	XFER_UDMA_6,	0x1c869c62	},
-	{	XFER_UDMA_5,	0x1cae9c62	},
-	{	XFER_UDMA_4,	0x1c8a9c62	},
-	{	XFER_UDMA_3,	0x1c8e9c62	},
-	{	XFER_UDMA_2,	0x1c929c62	},
-	{	XFER_UDMA_1,	0x1c9a9c62	},
-	{	XFER_UDMA_0,	0x1c829c62	},
-
-	{	XFER_MW_DMA_2,	0x2c829c62	},
-	{	XFER_MW_DMA_1,	0x2c829c66	},
-	{	XFER_MW_DMA_0,	0x2c829d2e	},
-
-	{	XFER_PIO_4,	0x0c829c62	},
-	{	XFER_PIO_3,	0x0c829c84	},
-	{	XFER_PIO_2,	0x0c829ca6	},
-	{	XFER_PIO_1,	0x0d029d26	},
-	{	XFER_PIO_0,	0x0d029d5e	},
-	{	0,		0x0d029d26	}
-};
-
-static struct chipset_bus_clock_list_entry thirty_three_base_hpt374[] = {
-	{	XFER_UDMA_6,	0x12808242	},
-	{	XFER_UDMA_5,	0x12848242	},
-	{	XFER_UDMA_4,	0x12ac8242	},
-	{	XFER_UDMA_3,	0x128c8242	},
-	{	XFER_UDMA_2,	0x120c8242	},
-	{	XFER_UDMA_1,	0x12148254	},
-	{	XFER_UDMA_0,	0x121882ea	},
-
-	{	XFER_MW_DMA_2,	0x22808242	},
-	{	XFER_MW_DMA_1,	0x22808254	},
-	{	XFER_MW_DMA_0,	0x228082ea	},
-
-	{	XFER_PIO_4,	0x0a81f442	},
-	{	XFER_PIO_3,	0x0a81f443	},
-	{	XFER_PIO_2,	0x0a81f454	},
-	{	XFER_PIO_1,	0x0ac1f465	},
-	{	XFER_PIO_0,	0x0ac1f48a	},
-	{	0,		0x06814e93	}
-};
-
-#if 0
-static struct chipset_bus_clock_list_entry fifty_base_hpt374[] = {
-	{	XFER_UDMA_6,	},
-	{	XFER_UDMA_5,	},
-	{	XFER_UDMA_4,	},
-	{	XFER_UDMA_3,	},
-	{	XFER_UDMA_2,	},
-	{	XFER_UDMA_1,	},
-	{	XFER_UDMA_0,	},
-	{	XFER_MW_DMA_2,	},
-	{	XFER_MW_DMA_1,	},
-	{	XFER_MW_DMA_0,	},
-	{	XFER_PIO_4,	},
-	{	XFER_PIO_3,	},
-	{	XFER_PIO_2,	},
-	{	XFER_PIO_1,	},
-	{	XFER_PIO_0,	},
-	{	0,	}
-};
-#endif
-#if 0
-static struct chipset_bus_clock_list_entry sixty_six_base_hpt374[] = {
-	{	XFER_UDMA_6,	0x12406231	},	/* checkme */
-	{	XFER_UDMA_5,	0x12446231	},
-				0x14846231
-	{	XFER_UDMA_4,		0x16814ea7	},
-				0x14886231
-	{	XFER_UDMA_3,		0x16814ea7	},
-				0x148c6231
-	{	XFER_UDMA_2,		0x16814ea7	},
-				0x148c6231
-	{	XFER_UDMA_1,		0x16814ea7	},
-				0x14906231
-	{	XFER_UDMA_0,		0x16814ea7	},
-				0x14986231
-	{	XFER_MW_DMA_2,		0x16814ea7	},
-				0x26514e21
-	{	XFER_MW_DMA_1,		0x16814ea7	},
-				0x26514e97
-	{	XFER_MW_DMA_0,		0x16814ea7	},
-				0x26514e97
-	{	XFER_PIO_4,		0x06814ea7	},
-				0x06514e21
-	{	XFER_PIO_3,		0x06814ea7	},
-				0x06514e22
-	{	XFER_PIO_2,		0x06814ea7	},
-				0x06514e33
-	{	XFER_PIO_1,		0x06814ea7	},
-				0x06914e43
-	{	XFER_PIO_0,		0x06814ea7	},
-				0x06914e57
-	{	0,		0x06814ea7	}
-};
-#endif
-
-#define HPT366_DEBUG_DRIVE_INFO		0
-#define HPT374_ALLOW_ATA133_6		0
-#define HPT371_ALLOW_ATA133_6		0
-#define HPT302_ALLOW_ATA133_6		0
-#define HPT372_ALLOW_ATA133_6		1
-#define HPT370_ALLOW_ATA100_5		1
-#define HPT366_ALLOW_ATA66_4		1
-#define HPT366_ALLOW_ATA66_3		1
-#define HPT366_MAX_DEVS			8
-
-#define F_LOW_PCI_33      0x23
-#define F_LOW_PCI_40      0x29
-#define F_LOW_PCI_50      0x2d
-#define F_LOW_PCI_66      0x42
-
-static void init_setup_hpt366(struct pci_dev *, ide_pci_device_t *);
-static void init_setup_hpt37x(struct pci_dev *, ide_pci_device_t *);
-static void init_setup_hpt374(struct pci_dev *, ide_pci_device_t *);
-static unsigned int init_chipset_hpt366(struct pci_dev *, const char *);
-static void init_hwif_hpt366(ide_hwif_t *);
-static void init_dma_hpt366(ide_hwif_t *, unsigned long);
-
-static ide_pci_device_t hpt366_chipsets[] __devinitdata = {
-	{	/* 0 */
-		.name		= "HPT366",
-		.init_setup	= init_setup_hpt366,
-		.init_chipset	= init_chipset_hpt366,
-		.init_hwif	= init_hwif_hpt366,
-		.init_dma	= init_dma_hpt366,
-		.channels	= 2,
-		.autodma	= AUTODMA,
-		.bootable	= OFF_BOARD,
-		.extra		= 240
-	},{	/* 1 */
-		.name		= "HPT372A",
-		.init_setup	= init_setup_hpt37x,
-		.init_chipset	= init_chipset_hpt366,
-		.init_hwif	= init_hwif_hpt366,
-		.init_dma	= init_dma_hpt366,
-		.channels	= 2,
-		.autodma	= AUTODMA,
-		.bootable	= OFF_BOARD,
-	},{	/* 2 */
-		.name		= "HPT302",
-		.init_setup	= init_setup_hpt37x,
-		.init_chipset	= init_chipset_hpt366,
-		.init_hwif	= init_hwif_hpt366,
-		.init_dma	= init_dma_hpt366,
-		.channels	= 2,
-		.autodma	= AUTODMA,
-		.bootable	= OFF_BOARD,
-	},{	/* 3 */
-		.name		= "HPT371",
-		.init_setup	= init_setup_hpt37x,
-		.init_chipset	= init_chipset_hpt366,
-		.init_hwif	= init_hwif_hpt366,
-		.init_dma	= init_dma_hpt366,
-		.channels	= 2,
-		.autodma	= AUTODMA,
-		.bootable	= OFF_BOARD,
-	},{	/* 4 */
-		.name		= "HPT374",
-		.init_setup	= init_setup_hpt374,
-		.init_chipset	= init_chipset_hpt366,
-		.init_hwif	= init_hwif_hpt366,
-		.init_dma	= init_dma_hpt366,
-		.channels	= 2,	/* 4 */
-		.autodma	= AUTODMA,
-		.bootable	= OFF_BOARD,
-	},{	/* 5 */
-		.name		= "HPT372N",
-		.init_setup	= init_setup_hpt37x,
-		.init_chipset	= init_chipset_hpt366,
-		.init_hwif	= init_hwif_hpt366,
-		.init_dma	= init_dma_hpt366,
-		.channels	= 2,	/* 4 */
-		.autodma	= AUTODMA,
-		.bootable	= OFF_BOARD,
-	}
-};
-
-#endif /* HPT366_H */
diff -Nru a/drivers/ide/pci/it8172.c b/drivers/ide/pci/it8172.c
--- a/drivers/ide/pci/it8172.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/ide/pci/it8172.c	2005-03-01 23:39:09 -08:00
@@ -42,8 +42,6 @@
 #include <asm/io.h>
 #include <asm/it8172/it8172_int.h>
 
-#include "it8172.h"
-
 /*
  * Prototypes
  */
@@ -56,7 +54,7 @@
 {
 	ide_hwif_t *hwif	= HWIF(drive);
 	struct pci_dev *dev	= hwif->pci_dev;
-	int is_slave		= (hwif->drives[1] == drive);
+	int is_slave		= (&hwif->drives[1] == drive);
 	unsigned long flags;
 	u16 drive_enables;
 	u32 drive_timing;
@@ -94,7 +92,7 @@
 	}
 
 	pci_write_config_word(dev, 0x40, drive_enables);
-	spin_unlock_irqrestore(&ide_lock, flags)
+	spin_unlock_irqrestore(&ide_lock, flags);
 }
 
 static u8 it8172_dma_2_pio (u8 xfer_rate)
@@ -266,13 +264,24 @@
 	hwif->drives[1].autodma = hwif->autodma;
 }
 
+static ide_pci_device_t it8172_chipsets[] __devinitdata = {
+	{	/* 0 */
+		.name		= "IT8172G",
+		.init_chipset	= init_chipset_it8172,
+		.init_hwif	= init_hwif_it8172,
+		.channels	= 2,
+		.autodma	= AUTODMA,
+		.enablebits	= {{0x00,0x00,0x00}, {0x40,0x00,0x01}},
+		.bootable	= ON_BOARD,
+	}
+};
+
 static int __devinit it8172_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
         if ((!(PCI_FUNC(dev->devfn) & 1) ||
             (!((dev->class >> 8) == PCI_CLASS_STORAGE_IDE))))
-                return 1; /* IT8172 is more than only a IDE controller */
-	ide_setup_pci_device(dev, &it8172_chipsets[id->driver_data]);
-	return 0;
+		return -ENODEV; /* IT8172 is more than an IDE controller */
+	return ide_setup_pci_device(dev, &it8172_chipsets[id->driver_data]);
 }
 
 static struct pci_device_id it8172_pci_tbl[] = {
diff -Nru a/drivers/ide/pci/it8172.h b/drivers/ide/pci/it8172.h
--- a/drivers/ide/pci/it8172.h	2005-03-01 23:38:56 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,34 +0,0 @@
-#ifndef ITE8172G_H
-#define ITE8172G_H
-
-#include <linux/config.h>
-#include <linux/pci.h>
-#include <linux/ide.h>
-
-static u8 it8172_ratemask(ide_drive_t *drive);
-static u8 it8172_ratefilter(ide_drive_t *drive, u8 speed);
-static void it8172_tune_drive(ide_drive_t *drive, u8 pio);
-static u8 it8172_dma_2_pio(u8 xfer_rate);
-static int it8172_tune_chipset(ide_drive_t *drive, u8 xferspeed);
-#ifdef CONFIG_BLK_DEV_IDEDMA
-static int it8172_config_chipset_for_dma(ide_drive_t *drive);
-#endif
-
-static void init_setup_it8172(struct pci_dev *, ide_pci_device_t *);
-static unsigned int init_chipset_it8172(struct pci_dev *, const char *);
-static void init_hwif_it8172(ide_hwif_t *);
-
-static ide_pci_device_t it8172_chipsets[] __devinitdata = {
-	{	/* 0 */
-		.name		= "IT8172G",
-		.init_setup	= init_setup_it8172,
-		.init_chipset	= init_chipset_it8172,
-		.init_hwif	= init_hwif_it8172,
-		.channels	= 2,
-		.autodma	= AUTODMA,
-		.enablebits	= {{0x00,0x00,0x00}, {0x40,0x00,0x01}},
-		.bootable	= ON_BOARD,
-	}
-};
-
-#endif /* ITE8172G_H */
diff -Nru a/drivers/ide/pci/ns87415.c b/drivers/ide/pci/ns87415.c
--- a/drivers/ide/pci/ns87415.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/ide/pci/ns87415.c	2005-03-01 23:38:56 -08:00
@@ -288,8 +288,7 @@
 
 static int __devinit ns87415_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-	ide_setup_pci_device(dev, &ns87415_chipset);
-	return 0;
+	return ide_setup_pci_device(dev, &ns87415_chipset);
 }
 
 static struct pci_device_id ns87415_pci_tbl[] = {
diff -Nru a/drivers/ide/pci/opti621.c b/drivers/ide/pci/opti621.c
--- a/drivers/ide/pci/opti621.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/ide/pci/opti621.c	2005-03-01 23:38:55 -08:00
@@ -104,8 +104,6 @@
 
 #include <asm/io.h>
 
-#include "opti621.h"
-
 #define OPTI621_MAX_PIO 3
 /* In fact, I do not have any PIO 4 drive
  * (address: 25 ns, data: 70 ns, recovery: 35 ns),
@@ -348,15 +346,27 @@
 	hwif->drives[1].autodma = hwif->autodma;
 }
 
-static void __init init_setup_opti621 (struct pci_dev *dev, ide_pci_device_t *d)
-{
-	ide_setup_pci_device(dev, d);
-}
+static ide_pci_device_t opti621_chipsets[] __devinitdata = {
+	{	/* 0 */
+		.name		= "OPTI621",
+		.init_hwif	= init_hwif_opti621,
+		.channels	= 2,
+		.autodma	= AUTODMA,
+		.enablebits	= {{0x45,0x80,0x00}, {0x40,0x08,0x00}},
+		.bootable	= ON_BOARD,
+	},{	/* 1 */
+		.name		= "OPTI621X",
+		.init_hwif	= init_hwif_opti621,
+		.channels	= 2,
+		.autodma	= AUTODMA,
+		.enablebits	= {{0x45,0x80,0x00}, {0x40,0x08,0x00}},
+		.bootable	= ON_BOARD,
+	}
+};
 
 static int __devinit opti621_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-	ide_setup_pci_device(dev, &opti621_chipsets[id->driver_data]);
-	return 0;
+	return ide_setup_pci_device(dev, &opti621_chipsets[id->driver_data]);
 }
 
 static struct pci_device_id opti621_pci_tbl[] = {
diff -Nru a/drivers/ide/pci/opti621.h b/drivers/ide/pci/opti621.h
--- a/drivers/ide/pci/opti621.h	2005-03-01 23:39:10 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,31 +0,0 @@
-#ifndef OPTI621_H
-#define OPTI621_H
-
-#include <linux/config.h>
-#include <linux/pci.h>
-#include <linux/ide.h>
-
-static void init_setup_opti621(struct pci_dev *, ide_pci_device_t *);
-static void init_hwif_opti621(ide_hwif_t *);
-
-static ide_pci_device_t opti621_chipsets[] __devinitdata = {
-	{	/* 0 */
-		.name		= "OPTI621",
-		.init_setup	= init_setup_opti621,
-		.init_hwif	= init_hwif_opti621,
-		.channels	= 2,
-		.autodma	= AUTODMA,
-		.enablebits	= {{0x45,0x80,0x00}, {0x40,0x08,0x00}},
-		.bootable	= ON_BOARD,
-	},{	/* 1 */
-		.name		= "OPTI621X",
-		.init_setup	= init_setup_opti621,
-		.init_hwif	= init_hwif_opti621,
-		.channels	= 2,
-		.autodma	= AUTODMA,
-		.enablebits	= {{0x45,0x80,0x00}, {0x40,0x08,0x00}},
-		.bootable	= ON_BOARD,
-	}
-};
-
-#endif /* OPTI621_H */
diff -Nru a/drivers/ide/pci/pdc202xx_new.c b/drivers/ide/pci/pdc202xx_new.c
--- a/drivers/ide/pci/pdc202xx_new.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/ide/pci/pdc202xx_new.c	2005-03-01 23:39:08 -08:00
@@ -37,10 +37,46 @@
 #include <asm/pci-bridge.h>
 #endif
 
-#include "pdc202xx_new.h"
-
 #define PDC202_DEBUG_CABLE	0
 
+const static char *pdc_quirk_drives[] = {
+	"QUANTUM FIREBALLlct08 08",
+	"QUANTUM FIREBALLP KA6.4",
+	"QUANTUM FIREBALLP KA9.1",
+	"QUANTUM FIREBALLP LM20.4",
+	"QUANTUM FIREBALLP KX13.6",
+	"QUANTUM FIREBALLP KX20.5",
+	"QUANTUM FIREBALLP KX27.3",
+	"QUANTUM FIREBALLP LM20.5",
+	NULL
+};
+
+#define set_2regs(a, b)					\
+	do {						\
+		hwif->OUTB((a + adj), indexreg);	\
+		hwif->OUTB(b, datareg);			\
+	} while(0)
+
+#define set_ultra(a, b, c)				\
+	do {						\
+		set_2regs(0x10,(a));			\
+		set_2regs(0x11,(b));			\
+		set_2regs(0x12,(c));			\
+	} while(0)
+
+#define set_ata2(a, b)					\
+	do {						\
+		set_2regs(0x0e,(a));			\
+		set_2regs(0x0f,(b));			\
+	} while(0)
+
+#define set_pio(a, b, c)				\
+	do { 						\
+		set_2regs(0x0c,(a));			\
+		set_2regs(0x0d,(b));			\
+		set_2regs(0x13,(c));			\
+	} while(0)
+
 static u8 pdcnew_ratemask (ide_drive_t *drive)
 {
 	u8 mode;
@@ -316,21 +352,21 @@
 #endif /* PDC202_DEBUG_CABLE */
 }
 
-static void __devinit init_setup_pdcnew(struct pci_dev *dev, ide_pci_device_t *d)
+static int __devinit init_setup_pdcnew(struct pci_dev *dev, ide_pci_device_t *d)
 {
-	ide_setup_pci_device(dev, d);
+	return ide_setup_pci_device(dev, d);
 }
 
-static void __devinit init_setup_pdc20270(struct pci_dev *dev, ide_pci_device_t *d)
+static int __devinit init_setup_pdc20270(struct pci_dev *dev,
+					 ide_pci_device_t *d)
 {
 	struct pci_dev *findev = NULL;
 
 	if ((dev->bus->self &&
 	     dev->bus->self->vendor == PCI_VENDOR_ID_DEC) &&
 	    (dev->bus->self->device == PCI_DEVICE_ID_DEC_21150)) {
-		if (PCI_SLOT(dev->devfn) & 2) {
-			return;
-		}
+		if (PCI_SLOT(dev->devfn) & 2)
+			return -ENODEV;
 		d->extra = 0;
 		while ((findev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, findev)) != NULL) {
 			if ((findev->vendor == dev->vendor) &&
@@ -339,15 +375,15 @@
 				if (findev->irq != dev->irq) {
 					findev->irq = dev->irq;
 				}
-				ide_setup_pci_devices(dev, findev, d);
-				return;
+				return ide_setup_pci_devices(dev, findev, d);
 			}
 		}
 	}
-	ide_setup_pci_device(dev, d);
+	return ide_setup_pci_device(dev, d);
 }
 
-static void __devinit init_setup_pdc20276(struct pci_dev *dev, ide_pci_device_t *d)
+static int __devinit init_setup_pdc20276(struct pci_dev *dev,
+					 ide_pci_device_t *d)
 {
 	if ((dev->bus->self) &&
 	    (dev->bus->self->vendor == PCI_VENDOR_ID_INTEL) &&
@@ -355,11 +391,77 @@
 	     (dev->bus->self->device == PCI_DEVICE_ID_INTEL_I960RM))) {
 		printk(KERN_INFO "ide: Skipping Promise PDC20276 "
 			"attached to I2O RAID controller.\n");
-		return;
+		return -ENODEV;
 	}
-	ide_setup_pci_device(dev, d);
+	return ide_setup_pci_device(dev, d);
 }
 
+static ide_pci_device_t pdcnew_chipsets[] __devinitdata = {
+	{	/* 0 */
+		.name		= "PDC20268",
+		.init_setup	= init_setup_pdcnew,
+		.init_chipset	= init_chipset_pdcnew,
+		.init_hwif	= init_hwif_pdc202new,
+		.channels	= 2,
+		.autodma	= AUTODMA,
+		.bootable	= OFF_BOARD,
+	},{	/* 1 */
+		.name		= "PDC20269",
+		.init_setup	= init_setup_pdcnew,
+		.init_chipset	= init_chipset_pdcnew,
+		.init_hwif	= init_hwif_pdc202new,
+		.channels	= 2,
+		.autodma	= AUTODMA,
+		.bootable	= OFF_BOARD,
+	},{	/* 2 */
+		.name		= "PDC20270",
+		.init_setup	= init_setup_pdc20270,
+		.init_chipset	= init_chipset_pdcnew,
+		.init_hwif	= init_hwif_pdc202new,
+		.channels	= 2,
+		.autodma	= AUTODMA,
+#ifndef CONFIG_PDC202XX_FORCE
+		.enablebits	= {{0x50,0x02,0x02}, {0x50,0x04,0x04}},
+#endif
+		.bootable	= OFF_BOARD,
+	},{	/* 3 */
+		.name		= "PDC20271",
+		.init_setup	= init_setup_pdcnew,
+		.init_chipset	= init_chipset_pdcnew,
+		.init_hwif	= init_hwif_pdc202new,
+		.channels	= 2,
+		.autodma	= AUTODMA,
+		.bootable	= OFF_BOARD,
+	},{	/* 4 */
+		.name		= "PDC20275",
+		.init_setup	= init_setup_pdcnew,
+		.init_chipset	= init_chipset_pdcnew,
+		.init_hwif	= init_hwif_pdc202new,
+		.channels	= 2,
+		.autodma	= AUTODMA,
+		.bootable	= OFF_BOARD,
+	},{	/* 5 */
+		.name		= "PDC20276",
+		.init_setup	= init_setup_pdc20276,
+		.init_chipset	= init_chipset_pdcnew,
+		.init_hwif	= init_hwif_pdc202new,
+		.channels	= 2,
+		.autodma	= AUTODMA,
+#ifndef CONFIG_PDC202XX_FORCE
+		.enablebits	= {{0x50,0x02,0x02}, {0x50,0x04,0x04}},
+#endif
+		.bootable	= OFF_BOARD,
+	},{	/* 6 */
+		.name		= "PDC20277",
+		.init_setup	= init_setup_pdcnew,
+		.init_chipset	= init_chipset_pdcnew,
+		.init_hwif	= init_hwif_pdc202new,
+		.channels	= 2,
+		.autodma	= AUTODMA,
+		.bootable	= OFF_BOARD,
+	}
+};
+
 /**
  *	pdc202new_init_one	-	called when a pdc202xx is found
  *	@dev: the pdc202new device
@@ -373,8 +475,7 @@
 {
 	ide_pci_device_t *d = &pdcnew_chipsets[id->driver_data];
 
-	d->init_setup(dev, d);
-	return 0;
+	return d->init_setup(dev, d);
 }
 
 static struct pci_device_id pdc202new_pci_tbl[] = {
diff -Nru a/drivers/ide/pci/pdc202xx_new.h b/drivers/ide/pci/pdc202xx_new.h
--- a/drivers/ide/pci/pdc202xx_new.h	2005-03-01 23:38:52 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,118 +0,0 @@
-#ifndef PDC202XX_H
-#define PDC202XX_H
-
-#include <linux/config.h>
-#include <linux/pci.h>
-#include <linux/ide.h>
-
-const static char *pdc_quirk_drives[] = {
-	"QUANTUM FIREBALLlct08 08",
-	"QUANTUM FIREBALLP KA6.4",
-	"QUANTUM FIREBALLP KA9.1",
-	"QUANTUM FIREBALLP LM20.4",
-	"QUANTUM FIREBALLP KX13.6",
-	"QUANTUM FIREBALLP KX20.5",
-	"QUANTUM FIREBALLP KX27.3",
-	"QUANTUM FIREBALLP LM20.5",
-	NULL
-};
-
-#define set_2regs(a, b)					\
-	do {						\
-		hwif->OUTB((a + adj), indexreg);	\
-		hwif->OUTB(b, datareg);			\
-	} while(0)
-
-#define set_ultra(a, b, c)				\
-	do {						\
-		set_2regs(0x10,(a));			\
-		set_2regs(0x11,(b));			\
-		set_2regs(0x12,(c));			\
-	} while(0)
-
-#define set_ata2(a, b)					\
-	do {						\
-		set_2regs(0x0e,(a));			\
-		set_2regs(0x0f,(b));			\
-	} while(0)
-
-#define set_pio(a, b, c)				\
-	do { 						\
-		set_2regs(0x0c,(a));			\
-		set_2regs(0x0d,(b));			\
-		set_2regs(0x13,(c));			\
-	} while(0)
-
-static void init_setup_pdcnew(struct pci_dev *, ide_pci_device_t *);
-static void init_setup_pdc20270(struct pci_dev *, ide_pci_device_t *);
-static void init_setup_pdc20276(struct pci_dev *dev, ide_pci_device_t *d);
-static unsigned int init_chipset_pdcnew(struct pci_dev *, const char *);
-static void init_hwif_pdc202new(ide_hwif_t *);
-
-static ide_pci_device_t pdcnew_chipsets[] __devinitdata = {
-	{	/* 0 */
-		.name		= "PDC20268",
-		.init_setup	= init_setup_pdcnew,
-		.init_chipset	= init_chipset_pdcnew,
-		.init_hwif	= init_hwif_pdc202new,
-		.channels	= 2,
-		.autodma	= AUTODMA,
-		.bootable	= OFF_BOARD,
-	},{	/* 1 */
-		.name		= "PDC20269",
-		.init_setup	= init_setup_pdcnew,
-		.init_chipset	= init_chipset_pdcnew,
-		.init_hwif	= init_hwif_pdc202new,
-		.channels	= 2,
-		.autodma	= AUTODMA,
-		.bootable	= OFF_BOARD,
-	},{	/* 2 */
-		.name		= "PDC20270",
-		.init_setup	= init_setup_pdc20270,
-		.init_chipset	= init_chipset_pdcnew,
-		.init_hwif	= init_hwif_pdc202new,
-		.channels	= 2,
-		.autodma	= AUTODMA,
-#ifndef CONFIG_PDC202XX_FORCE
-		.enablebits	= {{0x50,0x02,0x02}, {0x50,0x04,0x04}},
-#endif
-		.bootable	= OFF_BOARD,
-	},{	/* 3 */
-		.name		= "PDC20271",
-		.init_setup	= init_setup_pdcnew,
-		.init_chipset	= init_chipset_pdcnew,
-		.init_hwif	= init_hwif_pdc202new,
-		.channels	= 2,
-		.autodma	= AUTODMA,
-		.bootable	= OFF_BOARD,
-	},{	/* 4 */
-		.name		= "PDC20275",
-		.init_setup	= init_setup_pdcnew,
-		.init_chipset	= init_chipset_pdcnew,
-		.init_hwif	= init_hwif_pdc202new,
-		.channels	= 2,
-		.autodma	= AUTODMA,
-		.bootable	= OFF_BOARD,
-	},{	/* 5 */
-		.name		= "PDC20276",
-		.init_setup	= init_setup_pdc20276,
-		.init_chipset	= init_chipset_pdcnew,
-		.init_hwif	= init_hwif_pdc202new,
-		.channels	= 2,
-		.autodma	= AUTODMA,
-#ifndef CONFIG_PDC202XX_FORCE
-		.enablebits	= {{0x50,0x02,0x02}, {0x50,0x04,0x04}},
-#endif
-		.bootable	= OFF_BOARD,
-	},{	/* 6 */
-		.name		= "PDC20277",
-		.init_setup	= init_setup_pdcnew,
-		.init_chipset	= init_chipset_pdcnew,
-		.init_hwif	= init_hwif_pdc202new,
-		.channels	= 2,
-		.autodma	= AUTODMA,
-		.bootable	= OFF_BOARD,
-	}
-};
-
-#endif /* PDC202XX_H */
diff -Nru a/drivers/ide/pci/pdc202xx_old.c b/drivers/ide/pci/pdc202xx_old.c
--- a/drivers/ide/pci/pdc202xx_old.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/ide/pci/pdc202xx_old.c	2005-03-01 23:39:17 -08:00
@@ -46,9 +46,60 @@
 #include <asm/io.h>
 #include <asm/irq.h>
 
-#include "pdc202xx_old.h"
+#define PDC202_DEBUG_CABLE		0
+#define PDC202XX_DEBUG_DRIVE_INFO	0
 
-#define PDC202_DEBUG_CABLE	0
+static const char *pdc_quirk_drives[] = {
+	"QUANTUM FIREBALLlct08 08",
+	"QUANTUM FIREBALLP KA6.4",
+	"QUANTUM FIREBALLP KA9.1",
+	"QUANTUM FIREBALLP LM20.4",
+	"QUANTUM FIREBALLP KX13.6",
+	"QUANTUM FIREBALLP KX20.5",
+	"QUANTUM FIREBALLP KX27.3",
+	"QUANTUM FIREBALLP LM20.5",
+	NULL
+};
+
+/* A Register */
+#define	SYNC_ERRDY_EN	0xC0
+
+#define	SYNC_IN		0x80	/* control bit, different for master vs. slave drives */
+#define	ERRDY_EN	0x40	/* control bit, different for master vs. slave drives */
+#define	IORDY_EN	0x20	/* PIO: IOREADY */
+#define	PREFETCH_EN	0x10	/* PIO: PREFETCH */
+
+#define	PA3		0x08	/* PIO"A" timing */
+#define	PA2		0x04	/* PIO"A" timing */
+#define	PA1		0x02	/* PIO"A" timing */
+#define	PA0		0x01	/* PIO"A" timing */
+
+/* B Register */
+
+#define	MB2		0x80	/* DMA"B" timing */
+#define	MB1		0x40	/* DMA"B" timing */
+#define	MB0		0x20	/* DMA"B" timing */
+
+#define	PB4		0x10	/* PIO_FORCE 1:0 */
+
+#define	PB3		0x08	/* PIO"B" timing */	/* PIO flow Control mode */
+#define	PB2		0x04	/* PIO"B" timing */	/* PIO 4 */
+#define	PB1		0x02	/* PIO"B" timing */	/* PIO 3 half */
+#define	PB0		0x01	/* PIO"B" timing */	/* PIO 3 other half */
+
+/* C Register */
+#define	IORDYp_NO_SPEED	0x4F
+#define	SPEED_DIS	0x0F
+
+#define	DMARQp		0x80
+#define	IORDYp		0x40
+#define	DMAR_EN		0x20
+#define	DMAW_EN		0x10
+
+#define	MC3		0x08	/* DMA"C" timing */
+#define	MC2		0x04	/* DMA"C" timing */
+#define	MC1		0x02	/* DMA"C" timing */
+#define	MC0		0x01	/* DMA"C" timing */
 
 #if 0
 	unsigned long bibma  = pci_resource_start(dev, 4);
@@ -69,7 +120,8 @@
 		((sc1c & 0x02) == 0x02) ? "8" :
 		((sc1c & 0x01) == 0x01) ? "6" :
 		((sc1c & 0x00) == 0x00) ? "4" : "??");
-	SPLIT_BYTE(sc1e, hi, lo);
+	hi = sc1e >> 4;
+	lo = sc1e & 0xf;
 	p += sprintf(p, "Status Polling Period                : %d\n", hi);
 	p += sprintf(p, "Interrupt Check Status Polling Delay : %d\n", lo);
 #endif
@@ -658,7 +710,8 @@
 	ide_setup_dma(hwif, dmabase, 8);
 }
 
-static void __devinit init_setup_pdc202ata4(struct pci_dev *dev, ide_pci_device_t *d)
+static int __devinit init_setup_pdc202ata4(struct pci_dev *dev,
+					   ide_pci_device_t *d)
 {
 	if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE) {
 		u8 irq = 0, irq2 = 0;
@@ -685,10 +738,11 @@
         }
 #endif
 
-	ide_setup_pci_device(dev, d);
+	return ide_setup_pci_device(dev, d);
 }
 
-static void __devinit init_setup_pdc20265(struct pci_dev *dev, ide_pci_device_t *d)
+static int __devinit init_setup_pdc20265(struct pci_dev *dev,
+					 ide_pci_device_t *d)
 {
 	if ((dev->bus->self) &&
 	    (dev->bus->self->vendor == PCI_VENDOR_ID_INTEL) &&
@@ -696,7 +750,7 @@
 	     (dev->bus->self->device == PCI_DEVICE_ID_INTEL_I960RM))) {
 		printk(KERN_INFO "ide: Skipping Promise PDC20265 "
 			"attached to I2O RAID controller.\n");
-		return;
+		return -ENODEV;
 	}
 
 #if 0
@@ -714,14 +768,86 @@
         }
 #endif
 
-	ide_setup_pci_device(dev, d);
+	return ide_setup_pci_device(dev, d);
 }
 
-static void __devinit init_setup_pdc202xx(struct pci_dev *dev, ide_pci_device_t *d)
+static int __devinit init_setup_pdc202xx(struct pci_dev *dev,
+					 ide_pci_device_t *d)
 {
-	ide_setup_pci_device(dev, d);
+	return ide_setup_pci_device(dev, d);
 }
 
+static ide_pci_device_t pdc202xx_chipsets[] __devinitdata = {
+	{	/* 0 */
+		.name		= "PDC20246",
+		.init_setup	= init_setup_pdc202ata4,
+		.init_chipset	= init_chipset_pdc202xx,
+		.init_hwif	= init_hwif_pdc202xx,
+		.init_dma	= init_dma_pdc202xx,
+		.channels	= 2,
+		.autodma	= AUTODMA,
+#ifndef CONFIG_PDC202XX_FORCE
+		.enablebits	= {{0x50,0x02,0x02}, {0x50,0x04,0x04}},
+#endif
+		.bootable	= OFF_BOARD,
+		.extra		= 16,
+	},{	/* 1 */
+		.name		= "PDC20262",
+		.init_setup	= init_setup_pdc202ata4,
+		.init_chipset	= init_chipset_pdc202xx,
+		.init_hwif	= init_hwif_pdc202xx,
+		.init_dma	= init_dma_pdc202xx,
+		.channels	= 2,
+		.autodma	= AUTODMA,
+#ifndef CONFIG_PDC202XX_FORCE
+		.enablebits	= {{0x50,0x02,0x02}, {0x50,0x04,0x04}},
+#endif
+		.bootable	= OFF_BOARD,
+		.extra		= 48,
+		.flags		= IDEPCI_FLAG_FORCE_PDC,
+	},{	/* 2 */
+		.name		= "PDC20263",
+		.init_setup	= init_setup_pdc202ata4,
+		.init_chipset	= init_chipset_pdc202xx,
+		.init_hwif	= init_hwif_pdc202xx,
+		.init_dma	= init_dma_pdc202xx,
+		.channels	= 2,
+		.autodma	= AUTODMA,
+#ifndef CONFIG_PDC202XX_FORCE
+		.enablebits	= {{0x50,0x02,0x02}, {0x50,0x04,0x04}},
+#endif
+		.bootable	= OFF_BOARD,
+		.extra		= 48,
+	},{	/* 3 */
+		.name		= "PDC20265",
+		.init_setup	= init_setup_pdc20265,
+		.init_chipset	= init_chipset_pdc202xx,
+		.init_hwif	= init_hwif_pdc202xx,
+		.init_dma	= init_dma_pdc202xx,
+		.channels	= 2,
+		.autodma	= AUTODMA,
+#ifndef CONFIG_PDC202XX_FORCE
+		.enablebits	= {{0x50,0x02,0x02}, {0x50,0x04,0x04}},
+#endif
+		.bootable	= OFF_BOARD,
+		.extra		= 48,
+		.flags		= IDEPCI_FLAG_FORCE_PDC,
+	},{	/* 4 */
+		.name		= "PDC20267",
+		.init_setup	= init_setup_pdc202xx,
+		.init_chipset	= init_chipset_pdc202xx,
+		.init_hwif	= init_hwif_pdc202xx,
+		.init_dma	= init_dma_pdc202xx,
+		.channels	= 2,
+		.autodma	= AUTODMA,
+#ifndef CONFIG_PDC202XX_FORCE
+		.enablebits	= {{0x50,0x02,0x02}, {0x50,0x04,0x04}},
+#endif
+		.bootable	= OFF_BOARD,
+		.extra		= 48,
+	}
+};
+
 /**
  *	pdc202xx_init_one	-	called when a PDC202xx is found
  *	@dev: the pdc202xx device
@@ -735,8 +861,7 @@
 {
 	ide_pci_device_t *d = &pdc202xx_chipsets[id->driver_data];
 
-	d->init_setup(dev, d);
-	return 0;
+	return d->init_setup(dev, d);
 }
 
 static struct pci_device_id pdc202xx_pci_tbl[] = {
diff -Nru a/drivers/ide/pci/pdc202xx_old.h b/drivers/ide/pci/pdc202xx_old.h
--- a/drivers/ide/pci/pdc202xx_old.h	2005-03-01 23:38:44 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,144 +0,0 @@
-#ifndef PDC202XX_H
-#define PDC202XX_H
-
-#include <linux/config.h>
-#include <linux/pci.h>
-#include <linux/ide.h>
-
-#ifndef SPLIT_BYTE
-#define SPLIT_BYTE(B,H,L)	((H)=(B>>4), (L)=(B-((B>>4)<<4)))
-#endif
-
-#define PDC202XX_DEBUG_DRIVE_INFO		0
-
-static const char *pdc_quirk_drives[] = {
-	"QUANTUM FIREBALLlct08 08",
-	"QUANTUM FIREBALLP KA6.4",
-	"QUANTUM FIREBALLP KA9.1",
-	"QUANTUM FIREBALLP LM20.4",
-	"QUANTUM FIREBALLP KX13.6",
-	"QUANTUM FIREBALLP KX20.5",
-	"QUANTUM FIREBALLP KX27.3",
-	"QUANTUM FIREBALLP LM20.5",
-	NULL
-};
-
-/* A Register */
-#define	SYNC_ERRDY_EN	0xC0
-
-#define	SYNC_IN		0x80	/* control bit, different for master vs. slave drives */
-#define	ERRDY_EN	0x40	/* control bit, different for master vs. slave drives */
-#define	IORDY_EN	0x20	/* PIO: IOREADY */
-#define	PREFETCH_EN	0x10	/* PIO: PREFETCH */
-
-#define	PA3		0x08	/* PIO"A" timing */
-#define	PA2		0x04	/* PIO"A" timing */
-#define	PA1		0x02	/* PIO"A" timing */
-#define	PA0		0x01	/* PIO"A" timing */
-
-/* B Register */
-
-#define	MB2		0x80	/* DMA"B" timing */
-#define	MB1		0x40	/* DMA"B" timing */
-#define	MB0		0x20	/* DMA"B" timing */
-
-#define	PB4		0x10	/* PIO_FORCE 1:0 */
-
-#define	PB3		0x08	/* PIO"B" timing */	/* PIO flow Control mode */
-#define	PB2		0x04	/* PIO"B" timing */	/* PIO 4 */
-#define	PB1		0x02	/* PIO"B" timing */	/* PIO 3 half */
-#define	PB0		0x01	/* PIO"B" timing */	/* PIO 3 other half */
-
-/* C Register */
-#define	IORDYp_NO_SPEED	0x4F
-#define	SPEED_DIS	0x0F
-
-#define	DMARQp		0x80
-#define	IORDYp		0x40
-#define	DMAR_EN		0x20
-#define	DMAW_EN		0x10
-
-#define	MC3		0x08	/* DMA"C" timing */
-#define	MC2		0x04	/* DMA"C" timing */
-#define	MC1		0x02	/* DMA"C" timing */
-#define	MC0		0x01	/* DMA"C" timing */
-
-static void init_setup_pdc202ata4(struct pci_dev *dev, ide_pci_device_t *d);
-static void init_setup_pdc20265(struct pci_dev *, ide_pci_device_t *);
-static void init_setup_pdc202xx(struct pci_dev *, ide_pci_device_t *);
-static unsigned int init_chipset_pdc202xx(struct pci_dev *, const char *);
-static void init_hwif_pdc202xx(ide_hwif_t *);
-static void init_dma_pdc202xx(ide_hwif_t *, unsigned long);
-
-static ide_pci_device_t pdc202xx_chipsets[] __devinitdata = {
-	{	/* 0 */
-		.name		= "PDC20246",
-		.init_setup	= init_setup_pdc202ata4,
-		.init_chipset	= init_chipset_pdc202xx,
-		.init_hwif	= init_hwif_pdc202xx,
-		.init_dma	= init_dma_pdc202xx,
-		.channels	= 2,
-		.autodma	= AUTODMA,
-#ifndef CONFIG_PDC202XX_FORCE
-		.enablebits	= {{0x50,0x02,0x02}, {0x50,0x04,0x04}},
-#endif
-		.bootable	= OFF_BOARD,
-		.extra		= 16,
-	},{	/* 1 */
-		.name		= "PDC20262",
-		.init_setup	= init_setup_pdc202ata4,
-		.init_chipset	= init_chipset_pdc202xx,
-		.init_hwif	= init_hwif_pdc202xx,
-		.init_dma	= init_dma_pdc202xx,
-		.channels	= 2,
-		.autodma	= AUTODMA,
-#ifndef CONFIG_PDC202XX_FORCE
-		.enablebits	= {{0x50,0x02,0x02}, {0x50,0x04,0x04}},
-#endif
-		.bootable	= OFF_BOARD,
-		.extra		= 48,
-		.flags		= IDEPCI_FLAG_FORCE_PDC,
-	},{	/* 2 */
-		.name		= "PDC20263",
-		.init_setup	= init_setup_pdc202ata4,
-		.init_chipset	= init_chipset_pdc202xx,
-		.init_hwif	= init_hwif_pdc202xx,
-		.init_dma	= init_dma_pdc202xx,
-		.channels	= 2,
-		.autodma	= AUTODMA,
-#ifndef CONFIG_PDC202XX_FORCE
-		.enablebits	= {{0x50,0x02,0x02}, {0x50,0x04,0x04}},
-#endif
-		.bootable	= OFF_BOARD,
-		.extra		= 48,
-	},{	/* 3 */
-		.name		= "PDC20265",
-		.init_setup	= init_setup_pdc20265,
-		.init_chipset	= init_chipset_pdc202xx,
-		.init_hwif	= init_hwif_pdc202xx,
-		.init_dma	= init_dma_pdc202xx,
-		.channels	= 2,
-		.autodma	= AUTODMA,
-#ifndef CONFIG_PDC202XX_FORCE
-		.enablebits	= {{0x50,0x02,0x02}, {0x50,0x04,0x04}},
-#endif
-		.bootable	= OFF_BOARD,
-		.extra		= 48,
-		.flags		= IDEPCI_FLAG_FORCE_PDC,
-	},{	/* 4 */
-		.name		= "PDC20267",
-		.init_setup	= init_setup_pdc202xx,
-		.init_chipset	= init_chipset_pdc202xx,
-		.init_hwif	= init_hwif_pdc202xx,
-		.init_dma	= init_dma_pdc202xx,
-		.channels	= 2,
-		.autodma	= AUTODMA,
-#ifndef CONFIG_PDC202XX_FORCE
-		.enablebits	= {{0x50,0x02,0x02}, {0x50,0x04,0x04}},
-#endif
-		.bootable	= OFF_BOARD,
-		.extra		= 48,
-	}
-};
-
-#endif /* PDC202XX_H */
diff -Nru a/drivers/ide/pci/piix.c b/drivers/ide/pci/piix.c
--- a/drivers/ide/pci/piix.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/ide/pci/piix.c	2005-03-01 23:38:52 -08:00
@@ -103,8 +103,6 @@
 
 #include <asm/io.h>
 
-#include "piix.h"
-
 static int no_piix_dma;
 
 /**
@@ -129,11 +127,13 @@
 		case PCI_DEVICE_ID_INTEL_82801CA_10:
 		case PCI_DEVICE_ID_INTEL_82801CA_11:
 		case PCI_DEVICE_ID_INTEL_82801E_11:
+		case PCI_DEVICE_ID_INTEL_82801DB_1:
 		case PCI_DEVICE_ID_INTEL_82801DB_10:
 		case PCI_DEVICE_ID_INTEL_82801DB_11:
 		case PCI_DEVICE_ID_INTEL_82801EB_11:
 		case PCI_DEVICE_ID_INTEL_ESB_2:
 		case PCI_DEVICE_ID_INTEL_ICH6_19:
+		case PCI_DEVICE_ID_INTEL_ICH7_21:
 			mode = 3;
 			break;
 		/* UDMA 66 capable */
@@ -439,12 +439,14 @@
 		case PCI_DEVICE_ID_INTEL_82801BA_9:
 		case PCI_DEVICE_ID_INTEL_82801CA_10:
 		case PCI_DEVICE_ID_INTEL_82801CA_11:
+		case PCI_DEVICE_ID_INTEL_82801DB_1:
 		case PCI_DEVICE_ID_INTEL_82801DB_10:
 		case PCI_DEVICE_ID_INTEL_82801DB_11:
 		case PCI_DEVICE_ID_INTEL_82801EB_11:
 		case PCI_DEVICE_ID_INTEL_82801E_11:
 		case PCI_DEVICE_ID_INTEL_ESB_2:
 		case PCI_DEVICE_ID_INTEL_ICH6_19:
+		case PCI_DEVICE_ID_INTEL_ICH7_21:
 		{
 			unsigned int extra = 0;
 			pci_read_config_dword(dev, 0x54, &extra);
@@ -526,19 +528,51 @@
 	hwif->drives[0].autodma = hwif->autodma;
 }
 
-/**
- *	init_setup_piix		-	callback for IDE initialize
- *	@dev: PIIX PCI device
- *	@d: IDE pci info
- *
- *	Enable the xp fixup for the PIIX controller and then perform
- *	a standard ide PCI setup
- */
-
-static void __devinit init_setup_piix(struct pci_dev *dev, ide_pci_device_t *d)
-{
-	ide_setup_pci_device(dev, d);
-}
+#define DECLARE_PIIX_DEV(name_str) \
+	{						\
+		.name		= name_str,		\
+		.init_chipset	= init_chipset_piix,	\
+		.init_hwif	= init_hwif_piix,	\
+		.channels	= 2,			\
+		.autodma	= AUTODMA,		\
+		.enablebits	= {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, \
+		.bootable	= ON_BOARD,		\
+	}
+
+static ide_pci_device_t piix_pci_info[] __devinitdata = {
+	/*  0 */ DECLARE_PIIX_DEV("PIIXa"),
+	/*  1 */ DECLARE_PIIX_DEV("PIIXb"),
+
+	{	/* 2 */
+		.name		= "MPIIX",
+		.init_hwif	= init_hwif_piix,
+		.channels	= 2,
+		.autodma	= NODMA,
+		.enablebits	= {{0x6D,0x80,0x80}, {0x6F,0x80,0x80}},
+		.bootable	= ON_BOARD,
+	},
+
+	/*  3 */ DECLARE_PIIX_DEV("PIIX3"),
+	/*  4 */ DECLARE_PIIX_DEV("PIIX4"),
+	/*  5 */ DECLARE_PIIX_DEV("ICH0"),
+	/*  6 */ DECLARE_PIIX_DEV("PIIX4"),
+	/*  7 */ DECLARE_PIIX_DEV("ICH"),
+	/*  8 */ DECLARE_PIIX_DEV("PIIX4"),
+	/*  9 */ DECLARE_PIIX_DEV("PIIX4"),
+	/* 10 */ DECLARE_PIIX_DEV("ICH2"),
+	/* 11 */ DECLARE_PIIX_DEV("ICH2M"),
+	/* 12 */ DECLARE_PIIX_DEV("ICH3M"),
+	/* 13 */ DECLARE_PIIX_DEV("ICH3"),
+	/* 14 */ DECLARE_PIIX_DEV("ICH4"),
+	/* 15 */ DECLARE_PIIX_DEV("ICH5"),
+	/* 16 */ DECLARE_PIIX_DEV("C-ICH"),
+	/* 17 */ DECLARE_PIIX_DEV("ICH4"),
+	/* 18 */ DECLARE_PIIX_DEV("ICH5-SATA"),
+	/* 19 */ DECLARE_PIIX_DEV("ICH5"),
+	/* 20 */ DECLARE_PIIX_DEV("ICH6"),
+	/* 21 */ DECLARE_PIIX_DEV("ICH7"),
+	/* 22 */ DECLARE_PIIX_DEV("ICH4"),
+};
 
 /**
  *	piix_init_one	-	called when a PIIX is found
@@ -553,8 +587,7 @@
 {
 	ide_pci_device_t *d = &piix_pci_info[id->driver_data];
 
-	d->init_setup(dev, d);
-	return 0;
+	return ide_setup_pci_device(dev, d);
 }
 
 /**
@@ -612,6 +645,8 @@
 #endif
 	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 19},
 	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_19, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 20},
+	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_21, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 21},
+	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 22},
 	{ 0, },
 };
 MODULE_DEVICE_TABLE(pci, piix_pci_tbl);
diff -Nru a/drivers/ide/pci/piix.h b/drivers/ide/pci/piix.h
--- a/drivers/ide/pci/piix.h	2005-03-01 23:38:53 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,63 +0,0 @@
-#ifndef PIIX_H
-#define PIIX_H
-
-#include <linux/config.h>
-#include <linux/pci.h>
-#include <linux/ide.h>
-
-static void init_setup_piix(struct pci_dev *, ide_pci_device_t *);
-static unsigned int __devinit init_chipset_piix(struct pci_dev *, const char *);
-static void init_hwif_piix(ide_hwif_t *);
-
-#define DECLARE_PIIX_DEV(name_str) \
-	{						\
-		.name		= name_str,		\
-		.init_setup	= init_setup_piix,	\
-		.init_chipset	= init_chipset_piix,	\
-		.init_hwif	= init_hwif_piix,	\
-		.channels	= 2,			\
-		.autodma	= AUTODMA,		\
-		.enablebits	= {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, \
-		.bootable	= ON_BOARD,		\
-	}
-
-/*
- *	Table of the various PIIX capability blocks
- *
- */
- 
-static ide_pci_device_t piix_pci_info[] __devinitdata = {
-	/*  0 */ DECLARE_PIIX_DEV("PIIXa"),
-	/*  1 */ DECLARE_PIIX_DEV("PIIXb"),
-
-	{	/* 2 */
-		.name		= "MPIIX",
-		.init_setup	= init_setup_piix,
-		.init_hwif	= init_hwif_piix,
-		.channels	= 2,
-		.autodma	= NODMA,
-		.enablebits	= {{0x6D,0x80,0x80}, {0x6F,0x80,0x80}},
-		.bootable	= ON_BOARD,
-	},
-
-	/*  3 */ DECLARE_PIIX_DEV("PIIX3"),
-	/*  4 */ DECLARE_PIIX_DEV("PIIX4"),
-	/*  5 */ DECLARE_PIIX_DEV("ICH0"),
-	/*  6 */ DECLARE_PIIX_DEV("PIIX4"),
-	/*  7 */ DECLARE_PIIX_DEV("ICH"),
-	/*  8 */ DECLARE_PIIX_DEV("PIIX4"),
-	/*  9 */ DECLARE_PIIX_DEV("PIIX4"),
-	/* 10 */ DECLARE_PIIX_DEV("ICH2"),
-	/* 11 */ DECLARE_PIIX_DEV("ICH2M"),
-	/* 12 */ DECLARE_PIIX_DEV("ICH3M"),
-	/* 13 */ DECLARE_PIIX_DEV("ICH3"),
-	/* 14 */ DECLARE_PIIX_DEV("ICH4"),
-	/* 15 */ DECLARE_PIIX_DEV("ICH5"),
-	/* 16 */ DECLARE_PIIX_DEV("C-ICH"),
-	/* 17 */ DECLARE_PIIX_DEV("ICH4"),
-	/* 18 */ DECLARE_PIIX_DEV("ICH5-SATA"),
-	/* 19 */ DECLARE_PIIX_DEV("ICH5"),
-	/* 20 */ DECLARE_PIIX_DEV("ICH6")
-};
-
-#endif /* PIIX_H */
diff -Nru a/drivers/ide/pci/rz1000.c b/drivers/ide/pci/rz1000.c
--- a/drivers/ide/pci/rz1000.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/ide/pci/rz1000.c	2005-03-01 23:38:55 -08:00
@@ -62,8 +62,7 @@
 
 static int __devinit rz1000_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-	ide_setup_pci_device(dev, &rz1000_chipset);
-	return 0;
+	return ide_setup_pci_device(dev, &rz1000_chipset);
 }
 
 static struct pci_device_id rz1000_pci_tbl[] = {
diff -Nru a/drivers/ide/pci/sc1200.c b/drivers/ide/pci/sc1200.c
--- a/drivers/ide/pci/sc1200.c	2005-03-01 23:38:59 -08:00
+++ b/drivers/ide/pci/sc1200.c	2005-03-01 23:38:59 -08:00
@@ -489,8 +489,7 @@
 
 static int __devinit sc1200_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-	ide_setup_pci_device(dev, &sc1200_chipset);
-	return 0;
+	return ide_setup_pci_device(dev, &sc1200_chipset);
 }
 
 static struct pci_device_id sc1200_pci_tbl[] = {
diff -Nru a/drivers/ide/pci/serverworks.c b/drivers/ide/pci/serverworks.c
--- a/drivers/ide/pci/serverworks.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/ide/pci/serverworks.c	2005-03-01 23:38:52 -08:00
@@ -39,7 +39,18 @@
 
 #include <asm/io.h>
 
-#include "serverworks.h"
+#define SVWKS_CSB5_REVISION_NEW	0x92 /* min PCI_REVISION_ID for UDMA5 (A2.0) */
+#define SVWKS_CSB6_REVISION	0xa0 /* min PCI_REVISION_ID for UDMA4 (A1.0) */
+
+/* Seagate Barracuda ATA IV Family drives in UDMA mode 5
+ * can overrun their FIFOs when used with the CSB5 */
+static const char *svwks_bad_ata100[] = {
+	"ST320011A",
+	"ST340016A",
+	"ST360021A",
+	"ST380021A",
+	NULL
+};
 
 static u8 svwks_revision = 0;
 static struct pci_dev *isa_dev;
@@ -359,11 +370,9 @@
 	else if ((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE) ||
 		 (dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE) ||
 		 (dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2)) {
-//		u32 pioreg = 0, dmareg = 0;
 
 		/* Third Channel Test */
 		if (!(PCI_FUNC(dev->devfn) & 1)) {
-#if 1
 			struct pci_dev * findev = NULL;
 			u32 reg4c = 0;
 			findev = pci_find_device(PCI_VENDOR_ID_SERVERWORKS,
@@ -375,19 +384,11 @@
 				reg4c |=  0x00000020;
 				pci_write_config_dword(findev, 0x4C, reg4c);
 			}
-#endif
 			outb_p(0x06, 0x0c00);
 			dev->irq = inb_p(0x0c01);
 #if 0
-			/* WE need to figure out how to get the correct one */
-			printk("%s: interrupt %d\n", name, dev->irq);
-			if (dev->irq != 0x0B)
-				dev->irq = 0x0B;
-#endif
-#if 0
 			printk("%s: device class (0x%04x)\n",
 				name, dev->class);
-#else
 			if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE) {
 				dev->class &= ~0x000F0F00;
 		//		dev->class |= ~0x00000400;
@@ -413,7 +414,8 @@
 			 * interrupt pin to be set, and it is a compatibility
 			 * mode issue.
 			 */
-			dev->irq = 0;
+			if ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE)
+				dev->irq = 0;
 		}
 //		pci_read_config_dword(dev, 0x40, &pioreg)
 //		pci_write_config_dword(dev, 0x40, 0x99999999);
@@ -566,20 +568,17 @@
 	ide_setup_dma(hwif, dmabase, 8);
 }
 
-static void __init init_setup_svwks (struct pci_dev *dev, ide_pci_device_t *d)
+static int __init init_setup_svwks (struct pci_dev *dev, ide_pci_device_t *d)
 {
-	ide_setup_pci_device(dev, d);
+	return ide_setup_pci_device(dev, d);
 }
 
-static void __init init_setup_csb6 (struct pci_dev *dev, ide_pci_device_t *d)
+static int __init init_setup_csb6 (struct pci_dev *dev, ide_pci_device_t *d)
 {
 	if (!(PCI_FUNC(dev->devfn) & 1)) {
 		d->bootable = NEVER_BOARD;
 		if (dev->resource[0].start == 0x01f1)
 			d->bootable = ON_BOARD;
-	} else {
-		if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE)
-			return;
 	}
 #if 0
 	if ((IDE_PCI_DEVID_EQ(d->devid, DEVID_CSB6) &&
@@ -591,9 +590,47 @@
 			dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2) &&
 		       (!(PCI_FUNC(dev->devfn) & 1))) ? 1 : 2;
 
-	ide_setup_pci_device(dev, d);
+	return ide_setup_pci_device(dev, d);
 }
 
+static ide_pci_device_t serverworks_chipsets[] __devinitdata = {
+	{	/* 0 */
+		.name		= "SvrWks OSB4",
+		.init_setup	= init_setup_svwks,
+		.init_chipset	= init_chipset_svwks,
+		.init_hwif	= init_hwif_svwks,
+		.channels	= 2,
+		.autodma	= AUTODMA,
+		.bootable	= ON_BOARD,
+	},{	/* 1 */
+		.name		= "SvrWks CSB5",
+		.init_setup	= init_setup_svwks,
+		.init_chipset	= init_chipset_svwks,
+		.init_hwif	= init_hwif_svwks,
+		.init_dma	= init_dma_svwks,
+		.channels	= 2,
+		.autodma	= AUTODMA,
+		.bootable	= ON_BOARD,
+	},{	/* 2 */
+		.name		= "SvrWks CSB6",
+		.init_setup	= init_setup_csb6,
+		.init_chipset	= init_chipset_svwks,
+		.init_hwif	= init_hwif_svwks,
+		.init_dma	= init_dma_svwks,
+		.channels	= 2,
+		.autodma	= AUTODMA,
+		.bootable	= ON_BOARD,
+	},{	/* 3 */
+		.name		= "SvrWks CSB6",
+		.init_setup	= init_setup_csb6,
+		.init_chipset	= init_chipset_svwks,
+		.init_hwif	= init_hwif_svwks,
+		.init_dma	= init_dma_svwks,
+		.channels	= 1,	/* 2 */
+		.autodma	= AUTODMA,
+		.bootable	= ON_BOARD,
+	}
+};
 
 /**
  *	svwks_init_one	-	called when a OSB/CSB is found
@@ -608,8 +645,7 @@
 {
 	ide_pci_device_t *d = &serverworks_chipsets[id->driver_data];
 
-	d->init_setup(dev, d);
-	return 0;
+	return d->init_setup(dev, d);
 }
 
 static struct pci_device_id svwks_pci_tbl[] = {
@@ -625,10 +661,6 @@
 	.name		= "Serverworks_IDE",
 	.id_table	= svwks_pci_tbl,
 	.probe		= svwks_init_one,
-#if 0	/* FIXME: implement */
-	.suspend	= ,
-	.resume		= ,
-#endif
 };
 
 static int svwks_ide_init(void)
diff -Nru a/drivers/ide/pci/serverworks.h b/drivers/ide/pci/serverworks.h
--- a/drivers/ide/pci/serverworks.h	2005-03-01 23:38:55 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,69 +0,0 @@
-
-#ifndef SERVERWORKS_H
-#define SERVERWORKS_H
-
-#include <linux/config.h>
-#include <linux/pci.h>
-#include <linux/ide.h>
-
-#undef SVWKS_DEBUG_DRIVE_INFO
-
-#define SVWKS_CSB5_REVISION_NEW	0x92 /* min PCI_REVISION_ID for UDMA5 (A2.0) */
-#define SVWKS_CSB6_REVISION	0xa0 /* min PCI_REVISION_ID for UDMA4 (A1.0) */
-
-/* Seagate Barracuda ATA IV Family drives in UDMA mode 5
- * can overrun their FIFOs when used with the CSB5 */
-static const char *svwks_bad_ata100[] = {
-	"ST320011A",
-	"ST340016A",
-	"ST360021A",
-	"ST380021A",
-	NULL
-};
-
-static void init_setup_svwks(struct pci_dev *, ide_pci_device_t *);
-static void init_setup_csb6(struct pci_dev *, ide_pci_device_t *);
-static unsigned int init_chipset_svwks(struct pci_dev *, const char *);
-static void init_hwif_svwks(ide_hwif_t *);
-static void init_dma_svwks(ide_hwif_t *, unsigned long);
-
-static ide_pci_device_t serverworks_chipsets[] __devinitdata = {
-	{	/* 0 */
-		.name		= "SvrWks OSB4",
-		.init_setup	= init_setup_svwks,
-		.init_chipset	= init_chipset_svwks,
-		.init_hwif	= init_hwif_svwks,
-		.channels	= 2,
-		.autodma	= AUTODMA,
-		.bootable	= ON_BOARD,
-	},{	/* 1 */
-		.name		= "SvrWks CSB5",
-		.init_setup	= init_setup_svwks,
-		.init_chipset	= init_chipset_svwks,
-		.init_hwif	= init_hwif_svwks,
-		.init_dma	= init_dma_svwks,
-		.channels	= 2,
-		.autodma	= AUTODMA,
-		.bootable	= ON_BOARD,
-	},{	/* 2 */
-		.name		= "SvrWks CSB6",
-		.init_setup	= init_setup_csb6,
-		.init_chipset	= init_chipset_svwks,
-		.init_hwif	= init_hwif_svwks,
-		.init_dma	= init_dma_svwks,
-		.channels	= 2,
-		.autodma	= AUTODMA,
-		.bootable	= ON_BOARD,
-	},{	/* 3 */
-		.name		= "SvrWks CSB6",
-		.init_setup	= init_setup_csb6,
-		.init_chipset	= init_chipset_svwks,
-		.init_hwif	= init_hwif_svwks,
-		.init_dma	= init_dma_svwks,
-		.channels	= 1,	/* 2 */
-		.autodma	= AUTODMA,
-		.bootable	= ON_BOARD,
-	}
-};
-
-#endif /* SERVERWORKS_H */
diff -Nru a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c
--- a/drivers/ide/pci/sgiioc4.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/ide/pci/sgiioc4.c	2005-03-01 23:38:57 -08:00
@@ -669,7 +669,8 @@
 		printk(KERN_INFO "%s: %s Bus-Master DMA disabled\n",
 		       hwif->name, d->name);
 
-	probe_hwif_init(hwif);
+	if (probe_hwif_init(hwif))
+		return -EIO;
 
 	/* Create /proc/ide entries */
 	create_proc_ide_interfaces(); 
@@ -681,12 +682,14 @@
 pci_init_sgiioc4(struct pci_dev *dev, ide_pci_device_t * d)
 {
 	unsigned int class_rev;
+	int ret;
 
-	if (pci_enable_device(dev)) {
+	ret = pci_enable_device(dev);
+	if (ret < 0) {
 		printk(KERN_ERR
 		       "Failed to enable device %s at slot %s\n",
 		       d->name, dev->slot_name);
-		return -ENODEV;
+		goto out;
 	}
 	pci_set_master(dev);
 
@@ -698,9 +701,12 @@
 		printk(KERN_ERR "Skipping %s IDE controller in slot %s: "
 			"firmware is obsolete - please upgrade to revision"
 			"46 or higher\n", d->name, dev->slot_name);
-		return -ENODEV;
+		ret = -EAGAIN;
+		goto out;
 	}
-	return sgiioc4_ide_setup_pci_device(dev, d);
+	ret = sgiioc4_ide_setup_pci_device(dev, d);
+out:
+	return ret;
 }
 
 static ide_pci_device_t sgiioc4_chipsets[] __devinitdata = {
diff -Nru a/drivers/ide/pci/siimage.c b/drivers/ide/pci/siimage.c
--- a/drivers/ide/pci/siimage.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/ide/pci/siimage.c	2005-03-01 23:38:55 -08:00
@@ -590,7 +590,7 @@
 		if ((hwif->INL(SATA_STATUS_REG) & 0x03) != 0x03) {
 			printk(KERN_WARNING "%s: reset phy dead, status=0x%08x\n",
 				hwif->name, hwif->INL(SATA_STATUS_REG));
-			HWGROUP(drive)->poll_timeout = 0;
+			HWGROUP(drive)->polling = 0;
 			return ide_started;
 		}
 		return 0;
@@ -1102,8 +1102,7 @@
  
 static int __devinit siimage_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-	ide_setup_pci_device(dev, &siimage_chipsets[id->driver_data]);
-	return 0;
+	return ide_setup_pci_device(dev, &siimage_chipsets[id->driver_data]);
 }
 
 static struct pci_device_id siimage_pci_tbl[] = {
diff -Nru a/drivers/ide/pci/sis5513.c b/drivers/ide/pci/sis5513.c
--- a/drivers/ide/pci/sis5513.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/ide/pci/sis5513.c	2005-03-01 23:38:57 -08:00
@@ -946,8 +946,7 @@
 
 static int __devinit sis5513_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-	ide_setup_pci_device(dev, &sis5513_chipset);
-	return 0;
+	return ide_setup_pci_device(dev, &sis5513_chipset);
 }
 
 static struct pci_device_id sis5513_pci_tbl[] = {
diff -Nru a/drivers/ide/pci/sl82c105.c b/drivers/ide/pci/sl82c105.c
--- a/drivers/ide/pci/sl82c105.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/ide/pci/sl82c105.c	2005-03-01 23:38:55 -08:00
@@ -490,8 +490,7 @@
 
 static int __devinit sl82c105_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-	ide_setup_pci_device(dev, &sl82c105_chipset);
-	return 0;
+	return ide_setup_pci_device(dev, &sl82c105_chipset);
 }
 
 static struct pci_device_id sl82c105_pci_tbl[] = {
diff -Nru a/drivers/ide/pci/slc90e66.c b/drivers/ide/pci/slc90e66.c
--- a/drivers/ide/pci/slc90e66.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/ide/pci/slc90e66.c	2005-03-01 23:39:08 -08:00
@@ -246,8 +246,7 @@
 
 static int __devinit slc90e66_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-	ide_setup_pci_device(dev, &slc90e66_chipset);
-	return 0;
+	return ide_setup_pci_device(dev, &slc90e66_chipset);
 }
 
 static struct pci_device_id slc90e66_pci_tbl[] = {
diff -Nru a/drivers/ide/pci/triflex.c b/drivers/ide/pci/triflex.c
--- a/drivers/ide/pci/triflex.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/ide/pci/triflex.c	2005-03-01 23:38:55 -08:00
@@ -158,9 +158,7 @@
 static int __devinit triflex_init_one(struct pci_dev *dev, 
 		const struct pci_device_id *id)
 {
-	ide_setup_pci_device(dev, &triflex_device);
-
-	return 0;
+	return ide_setup_pci_device(dev, &triflex_device);
 }
 
 static struct pci_device_id triflex_pci_tbl[] = {
diff -Nru a/drivers/ide/pci/trm290.c b/drivers/ide/pci/trm290.c
--- a/drivers/ide/pci/trm290.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/ide/pci/trm290.c	2005-03-01 23:38:53 -08:00
@@ -342,8 +342,7 @@
 
 static int __devinit trm290_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-	ide_setup_pci_device(dev, &trm290_chipset);
-	return 0;
+	return ide_setup_pci_device(dev, &trm290_chipset);
 }
 
 static struct pci_device_id trm290_pci_tbl[] = {
diff -Nru a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c
--- a/drivers/ide/pci/via82cxxx.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/ide/pci/via82cxxx.c	2005-03-01 23:39:18 -08:00
@@ -36,6 +36,10 @@
 #include <linux/ide.h>
 #include <asm/io.h>
 
+#ifdef CONFIG_PPC_MULTIPLATFORM
+#include <asm/processor.h>
+#endif
+
 #include "ide-timing.h"
 
 #define DISPLAY_VIA_TIMINGS
@@ -584,6 +588,13 @@
 	hwif->tuneproc = &via82cxxx_tune_drive;
 	hwif->speedproc = &via_set_drive;
 
+
+#if defined(CONFIG_PPC_MULTIPLATFORM) && defined(CONFIG_PPC32)
+	if(_machine == _MACH_chrp && _chrp_type == _CHRP_Pegasos) {
+		hwif->irq = hwif->channel ? 15 : 14;
+	}
+#endif
+
 	for (i = 0; i < 2; i++) {
 		hwif->drives[i].io_32bit = 1;
 		hwif->drives[i].unmask = (via_config->flags & VIA_NO_UNMASK) ? 0 : 1;
@@ -620,8 +631,7 @@
 
 static int __devinit via_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-	ide_setup_pci_device(dev, &via82cxxx_chipset);
-	return 0;
+	return ide_setup_pci_device(dev, &via82cxxx_chipset);
 }
 
 static struct pci_device_id via_pci_tbl[] = {
diff -Nru a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c
--- a/drivers/ide/ppc/pmac.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/ide/ppc/pmac.c	2005-03-01 23:38:52 -08:00
@@ -52,7 +52,7 @@
 
 #include "ide-timing.h"
 
-#define IDE_PMAC_DEBUG
+#undef IDE_PMAC_DEBUG
 
 #define DMA_WAIT_TIMEOUT	50
 
diff -Nru a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c
--- a/drivers/ide/setup-pci.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/ide/setup-pci.c	2005-03-01 23:38:56 -08:00
@@ -28,6 +28,7 @@
 #include <linux/mm.h>
 #include <linux/interrupt.h>
 #include <linux/ide.h>
+#include <linux/dma-mapping.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
@@ -290,14 +291,16 @@
  
 static int ide_pci_enable(struct pci_dev *dev, ide_pci_device_t *d)
 {
-	
+	int ret;
+
 	if (pci_enable_device(dev)) {
-		if (pci_enable_device_bars(dev, 1 << 4)) {
+		ret = pci_enable_device_bars(dev, 1 << 4);
+		if (ret < 0) {
 			printk(KERN_WARNING "%s: (ide_setup_pci_device:) "
 				"Could not enable device.\n", d->name);
-			return -EBUSY;
-		} else
-			printk(KERN_WARNING "%s: BIOS configuration fixed.\n", d->name);
+			goto out;
+		}
+		printk(KERN_WARNING "%s: BIOS configuration fixed.\n", d->name);
 	}
 
 	/*
@@ -305,18 +308,21 @@
 	 * dma mask field to the ide_pci_device_t if we need it (or let
 	 * lower level driver set the dma mask)
 	 */
-	if (pci_set_dma_mask(dev, 0xffffffff)) {
+	ret = pci_set_dma_mask(dev, DMA_32BIT_MASK);
+	if (ret < 0) {
 		printk(KERN_ERR "%s: can't set dma mask\n", d->name);
-		return -EBUSY;
+		goto out;
 	}
-	 
+
 	/* FIXME: Temporary - until we put in the hotplug interface logic
-	   Check that the bits we want are not in use by someone else */
-	if (pci_request_region(dev, 4, "ide_tmp"))
-		return -EBUSY;
+	   Check that the bits we want are not in use by someone else. */
+	ret = pci_request_region(dev, 4, "ide_tmp");
+	if (ret < 0)
+		goto out;
+
 	pci_release_region(dev, 4);
-	
-	return 0;	
+out:
+	return ret;
 }
 
 /**
@@ -425,7 +431,12 @@
 	if (hwif->io_ports[IDE_DATA_OFFSET] != base ||
 	    hwif->io_ports[IDE_CONTROL_OFFSET] != (ctl | 2)) {
 		memset(&hwif->hw, 0, sizeof(hwif->hw));
+#ifndef IDE_ARCH_OBSOLETE_INIT
+		ide_std_init_ports(&hwif->hw, base, (ctl | 2));
+		hwif->hw.io_ports[IDE_IRQ_OFFSET] = 0;
+#else
 		ide_init_hwif_ports(&hwif->hw, base, (ctl | 2), NULL);
+#endif
 		memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports));
 		hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET];
 	}
@@ -515,22 +526,26 @@
  
 static int ide_setup_pci_controller(struct pci_dev *dev, ide_pci_device_t *d, int noisy, int *config)
 {
+	int ret;
 	u32 class_rev;
 	u16 pcicmd;
 
 	if (noisy)
 		ide_setup_pci_noise(dev, d);
 
-	if (ide_pci_enable(dev, d))
-		return -EBUSY;
-		
-	if (pci_read_config_word(dev, PCI_COMMAND, &pcicmd)) {
+	ret = ide_pci_enable(dev, d);
+	if (ret < 0)
+		goto out;
+
+	ret = pci_read_config_word(dev, PCI_COMMAND, &pcicmd);
+	if (ret < 0) {
 		printk(KERN_ERR "%s: error accessing PCI regs\n", d->name);
-		return -EIO;
+		goto out;
 	}
 	if (!(pcicmd & PCI_COMMAND_IO)) {	/* is device disabled? */
-		if (ide_pci_configure(dev, d))
-			return -ENODEV;
+		ret = ide_pci_configure(dev, d);
+		if (ret < 0)
+			goto out;
 		*config = 1;
 		printk(KERN_INFO "%s: device enabled (Linux)\n", d->name);
 	}
@@ -539,7 +554,8 @@
 	class_rev &= 0xff;
 	if (noisy)
 		printk(KERN_INFO "%s: chipset revision %d\n", d->name, class_rev);
-	return 0;
+out:
+	return ret;
 }
 
 /**
@@ -643,14 +659,16 @@
  * we "know" about, this information is in the ide_pci_device_t struct;
  * for all other chipsets, we just assume both interfaces are enabled.
  */
-static ata_index_t do_ide_setup_pci_device (struct pci_dev *dev, ide_pci_device_t *d, u8 noisy)
+static int do_ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t *d,
+				   ata_index_t *index, u8 noisy)
 {
-	int pciirq = 0;
+	static ata_index_t ata_index = { .b = { .low = 0xff, .high = 0xff } };
 	int tried_config = 0;
-	ata_index_t index = { .b = { .low = 0xff, .high = 0xff } };
+	int pciirq, ret;
 
-	if (ide_setup_pci_controller(dev, d, noisy, &tried_config) < 0)
-		return index;
+	ret = ide_setup_pci_controller(dev, d, noisy, &tried_config);
+	if (ret < 0)
+		goto out;
 
 	/*
 	 * Can we trust the reported IRQ?
@@ -668,7 +686,10 @@
 		 * space, place chipset into init-mode, and/or preserve
 		 * an interrupt if the card is not native ide support.
 		 */
-		pciirq = (d->init_chipset) ? d->init_chipset(dev, d->name) : 0;
+		ret = d->init_chipset ? d->init_chipset(dev, d->name) : 0;
+		if (ret < 0)
+			goto out;
+		pciirq = ret;
 	} else if (tried_config) {
 		if (noisy)
 			printk(KERN_INFO "%s: will probe irqs later\n", d->name);
@@ -679,10 +700,10 @@
 				d->name, pciirq);
 		pciirq = 0;
 	} else {
-		if (d->init_chipset)
-		{
-			if(d->init_chipset(dev, d->name) < 0)
-				return index;
+		if (d->init_chipset) {
+			ret = d->init_chipset(dev, d->name);
+			if (ret < 0)
+				goto out;
 		}
 		if (noisy)
 #ifdef __sparc__
@@ -693,18 +714,23 @@
 				d->name, pciirq);
 #endif
 	}
-	
-	if(pciirq < 0)		/* Error not an IRQ */
-		return index;
 
-	ide_pci_setup_ports(dev, d, pciirq, &index);
+	/* FIXME: silent failure can happen */
 
-	return index;
+	*index = ata_index;
+	ide_pci_setup_ports(dev, d, pciirq, index);
+out:
+	return ret;
 }
 
-void ide_setup_pci_device (struct pci_dev *dev, ide_pci_device_t *d)
+int ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t *d)
 {
-	ata_index_t index_list = do_ide_setup_pci_device(dev, d, 1);
+	ata_index_t index_list;
+	int ret;
+
+	ret = do_ide_setup_pci_device(dev, d, &index_list, 1);
+	if (ret < 0)
+		goto out;
 
 	if ((index_list.b.low & 0xf0) != 0xf0)
 		probe_hwif_init_with_fixup(&ide_hwifs[index_list.b.low], d->fixup);
@@ -712,25 +738,42 @@
 		probe_hwif_init_with_fixup(&ide_hwifs[index_list.b.high], d->fixup);
 
 	create_proc_ide_interfaces();
+out:
+	return ret;
 }
 
 EXPORT_SYMBOL_GPL(ide_setup_pci_device);
 
-void ide_setup_pci_devices (struct pci_dev *dev, struct pci_dev *dev2, ide_pci_device_t *d)
+int ide_setup_pci_devices(struct pci_dev *dev1, struct pci_dev *dev2,
+			  ide_pci_device_t *d)
 {
-	ata_index_t index_list  = do_ide_setup_pci_device(dev, d, 1);
-	ata_index_t index_list2 = do_ide_setup_pci_device(dev2, d, 0);
+	struct pci_dev *pdev[] = { dev1, dev2 };
+	ata_index_t index_list[2];
+	int ret, i;
 
-	if ((index_list.b.low & 0xf0) != 0xf0)
-		probe_hwif_init(&ide_hwifs[index_list.b.low]);
-	if ((index_list.b.high & 0xf0) != 0xf0)
-		probe_hwif_init(&ide_hwifs[index_list.b.high]);
-	if ((index_list2.b.low & 0xf0) != 0xf0)
-		probe_hwif_init(&ide_hwifs[index_list2.b.low]);
-	if ((index_list2.b.high & 0xf0) != 0xf0)
-		probe_hwif_init(&ide_hwifs[index_list2.b.high]);
+	for (i = 0; i < 2; i++) {
+		ret = do_ide_setup_pci_device(pdev[i], d, index_list + i, !i);
+		/*
+		 * FIXME: Mom, mom, they stole me the helper function to undo
+		 * do_ide_setup_pci_device() on the first device!
+		 */
+		if (ret < 0)
+			goto out;
+	}
+
+	for (i = 0; i < 2; i++) {
+		u8 idx[2] = { index_list[i].b.low, index_list[i].b.high };
+		int j;
+
+		for (j = 0; j < 2; j++) {
+			if ((idx[j] & 0xf0) != 0xf0)
+				probe_hwif_init(ide_hwifs + idx[j]);
+		}
+	}
 
 	create_proc_ide_interfaces();
+out:
+	return ret;
 }
 
 EXPORT_SYMBOL_GPL(ide_setup_pci_devices);
diff -Nru a/drivers/ieee1394/amdtp.c b/drivers/ieee1394/amdtp.c
--- a/drivers/ieee1394/amdtp.c	2005-03-01 23:38:59 -08:00
+++ b/drivers/ieee1394/amdtp.c	2005-03-01 23:38:59 -08:00
@@ -1140,24 +1140,28 @@
 	return count;
 }
 
-static int amdtp_ioctl(struct inode *inode, struct file *file,
-			   unsigned int cmd, unsigned long arg)
+static long amdtp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
 	struct stream *s = file->private_data;
 	struct amdtp_ioctl cfg;
-
+	int err;
+	lock_kernel();
 	switch(cmd)
 	{
 	case AMDTP_IOC_PLUG:
 	case AMDTP_IOC_CHANNEL:
 		if (copy_from_user(&cfg, (struct amdtp_ioctl __user *) arg, sizeof cfg))
-			return -EFAULT;
+			err = -EFAULT;
 		else
-			return stream_configure(s, cmd, &cfg);
+			err = stream_configure(s, cmd, &cfg);
+		break;
 
 	default:
-		return -EINVAL;
+		err = -EINVAL;
+		break;
 	}
+	unlock_kernel();
+	return err;
 }
 
 static unsigned int amdtp_poll(struct file *file, poll_table *pt)
@@ -1203,7 +1207,8 @@
 	.owner =	THIS_MODULE,
 	.write =	amdtp_write,
 	.poll =		amdtp_poll,
-	.ioctl =	amdtp_ioctl,
+	.unlocked_ioctl = amdtp_ioctl,
+	.compat_ioctl = amdtp_ioctl, /* All amdtp ioctls are compatible */
 	.open =		amdtp_open,
 	.release =	amdtp_release
 };
@@ -1276,18 +1281,6 @@
 
 	hpsb_register_highlevel(&amdtp_highlevel);
 
-#ifdef CONFIG_COMPAT
-	{
-		int ret;
-		ret = register_ioctl32_conversion(AMDTP_IOC_CHANNEL, NULL);
-		ret |= register_ioctl32_conversion(AMDTP_IOC_PLUG, NULL);
-		ret |= register_ioctl32_conversion(AMDTP_IOC_PING, NULL);
-		ret |= register_ioctl32_conversion(AMDTP_IOC_ZAP, NULL);
-		if (ret)
-			HPSB_ERR("amdtp: Error registering ioctl32 translations");
-	}
-#endif
-
 	HPSB_INFO("Loaded AMDTP driver");
 
 	return 0;
@@ -1295,17 +1288,6 @@
 
 static void __exit amdtp_exit_module (void)
 {
-#ifdef CONFIG_COMPAT
-	int ret;
-
-	ret = unregister_ioctl32_conversion(AMDTP_IOC_CHANNEL);
-	ret |= unregister_ioctl32_conversion(AMDTP_IOC_PLUG);
-	ret |= unregister_ioctl32_conversion(AMDTP_IOC_PING);
-	ret |= unregister_ioctl32_conversion(AMDTP_IOC_ZAP);
-	if (ret)
-		HPSB_ERR("amdtp: Error unregistering ioctl32 translations");
-#endif
-
         hpsb_unregister_highlevel(&amdtp_highlevel);
 	devfs_remove("amdtp");
 	cdev_del(&amdtp_cdev);
diff -Nru a/drivers/ieee1394/csr.c b/drivers/ieee1394/csr.c
--- a/drivers/ieee1394/csr.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/ieee1394/csr.c	2005-03-01 23:38:53 -08:00
@@ -201,7 +201,7 @@
 				CSR_REGISTER_BASE + CSR_SPEED_MAP,
 				CSR_REGISTER_BASE + CSR_SPEED_MAP_END);
 
-        host->csr.lock = SPIN_LOCK_UNLOCKED;
+        spin_lock_init(&host->csr.lock);
 
         host->csr.state                 = 0;
         host->csr.node_ids              = 0;
diff -Nru a/drivers/ieee1394/dv1394.c b/drivers/ieee1394/dv1394.c
--- a/drivers/ieee1394/dv1394.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/ieee1394/dv1394.c	2005-03-01 23:39:08 -08:00
@@ -168,11 +168,16 @@
 static void it_tasklet_func(unsigned long data);
 static void ir_tasklet_func(unsigned long data);
 
+#ifdef CONFIG_COMPAT
+static long dv1394_compat_ioctl(struct file *file, unsigned int cmd,
+			       unsigned long arg);
+#endif
+
 /* GLOBAL DATA */
 
 /* list of all video_cards */
 static LIST_HEAD(dv1394_cards);
-static spinlock_t dv1394_cards_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(dv1394_cards_lock);
 
 /* translate from a struct file* to the corresponding struct video_card* */
 
@@ -1540,26 +1545,29 @@
 
 /*** DEVICE IOCTL INTERFACE ************************************************/
 
-/* I *think* the VFS serializes ioctl() for us, so we don't have to worry
-   about situations like having two threads in here at once... */
-
-static int dv1394_ioctl(struct inode *inode, struct file *file,
-			   unsigned int cmd, unsigned long arg)
+static long dv1394_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
-	struct video_card *video = file_to_video_card(file);
+	struct video_card *video;
 	unsigned long flags;
 	int ret = -EINVAL;
 	void __user *argp = (void __user *)arg;
 
 	DECLARE_WAITQUEUE(wait, current);
 
+	lock_kernel();
+	video = file_to_video_card(file);
+
 	/* serialize this to prevent multi-threaded mayhem */
 	if (file->f_flags & O_NONBLOCK) {
-		if (down_trylock(&video->sem))
+		if (down_trylock(&video->sem)) {
+			unlock_kernel();
 			return -EAGAIN;
+		}
 	} else {
-		if (down_interruptible(&video->sem))
+		if (down_interruptible(&video->sem)) {
+			unlock_kernel();
 			return -ERESTARTSYS;
+		}
 	}
 
 	switch(cmd)
@@ -1783,11 +1791,10 @@
 
  out:
 	up(&video->sem);
+	unlock_kernel();
 	return ret;
 }
 
-
-
 /*** DEVICE FILE INTERFACE CONTINUED ***************************************/
 
 static int dv1394_open(struct inode *inode, struct file *file)
@@ -2165,7 +2172,10 @@
 {
 	.owner =	THIS_MODULE,
 	.poll =         dv1394_poll,
-	.ioctl =	dv1394_ioctl,
+	.unlocked_ioctl = dv1394_ioctl,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl = dv1394_compat_ioctl,
+#endif
 	.mmap =		dv1394_mmap,
 	.open =		dv1394_open,
 	.write =        dv1394_write,
@@ -2507,8 +2517,9 @@
 	u32 dropped_frames;
 };
 
-static int handle_dv1394_init(unsigned int fd, unsigned int cmd, unsigned long arg,
-			      struct file *file)
+/* RED-PEN: this should use compat_alloc_userspace instead */
+
+static int handle_dv1394_init(struct file *file, unsigned int cmd, unsigned long arg)
 {
 	struct dv1394_init32 dv32;
 	struct dv1394_init dv;
@@ -2531,15 +2542,14 @@
 
 	old_fs = get_fs();
 	set_fs(KERNEL_DS);
-	ret = dv1394_ioctl(file->f_dentry->d_inode, file,
+	ret = dv1394_ioctl(file,
 			   DV1394_IOC_INIT, (unsigned long)&dv);
 	set_fs(old_fs);
 
 	return ret;
 }
 
-static int handle_dv1394_get_status(unsigned int fd, unsigned int cmd, unsigned long arg,
-				    struct file *file)
+static int handle_dv1394_get_status(struct file *file, unsigned int cmd, unsigned long arg)
 {
 	struct dv1394_status32 dv32;
 	struct dv1394_status dv;
@@ -2551,7 +2561,7 @@
 
 	old_fs = get_fs();
 	set_fs(KERNEL_DS);
-	ret = dv1394_ioctl(file->f_dentry->d_inode, file,
+	ret = dv1394_ioctl(file,
 			   DV1394_IOC_GET_STATUS, (unsigned long)&dv);
 	set_fs(old_fs);
 
@@ -2574,6 +2584,30 @@
 
 	return ret;
 }
+
+
+
+static long dv1394_compat_ioctl(struct file *file, unsigned int cmd,
+			       unsigned long arg)
+{
+	int err;
+	switch (cmd) {
+	case DV1394_IOC_SHUTDOWN:
+	case DV1394_IOC_SUBMIT_FRAMES:
+	case DV1394_IOC_WAIT_FRAMES:
+	case DV1394_IOC_RECEIVE_FRAMES:
+	case DV1394_IOC_START_RECEIVE:
+		return dv1394_ioctl(file, cmd, arg);
+
+	case DV1394_IOC32_INIT:
+		return handle_dv1394_init(file, cmd, arg);
+	case DV1394_IOC32_GET_STATUS:
+		return handle_dv1394_get_status(file, cmd, arg);
+	default:
+		return -ENOIOCTLCMD;
+	}
+}
+
 #endif /* CONFIG_COMPAT */
 
 
@@ -2586,20 +2620,6 @@
 
 static void __exit dv1394_exit_module(void)
 {
-#ifdef CONFIG_COMPAT
-	int ret;
-
-	ret = unregister_ioctl32_conversion(DV1394_IOC_SHUTDOWN);
-	ret |= unregister_ioctl32_conversion(DV1394_IOC_SUBMIT_FRAMES);
-	ret |= unregister_ioctl32_conversion(DV1394_IOC_WAIT_FRAMES);
-	ret |= unregister_ioctl32_conversion(DV1394_IOC_RECEIVE_FRAMES);
-	ret |= unregister_ioctl32_conversion(DV1394_IOC_START_RECEIVE);
-	ret |= unregister_ioctl32_conversion(DV1394_IOC32_INIT);
-	ret |= unregister_ioctl32_conversion(DV1394_IOC32_GET_STATUS);
-	if (ret)
-		printk(KERN_ERR "dv1394: Error unregistering ioctl32 translations\n");
-#endif
-
 	hpsb_unregister_protocol(&dv1394_driver);
 
 	hpsb_unregister_highlevel(&dv1394_highlevel);
@@ -2632,23 +2652,6 @@
 		cdev_del(&dv1394_cdev);
 		return ret;
 	}
-
-#ifdef CONFIG_COMPAT
-	{
-		/* First compatible ones */
-		ret = register_ioctl32_conversion(DV1394_IOC_SHUTDOWN, NULL);
-		ret |= register_ioctl32_conversion(DV1394_IOC_SUBMIT_FRAMES, NULL);
-		ret |= register_ioctl32_conversion(DV1394_IOC_WAIT_FRAMES, NULL);
-		ret |= register_ioctl32_conversion(DV1394_IOC_RECEIVE_FRAMES, NULL);
-		ret |= register_ioctl32_conversion(DV1394_IOC_START_RECEIVE, NULL);
-
-		/* These need to be handled by translation */
-		ret |= register_ioctl32_conversion(DV1394_IOC32_INIT, handle_dv1394_init);
-		ret |= register_ioctl32_conversion(DV1394_IOC32_GET_STATUS, handle_dv1394_get_status);
-		if (ret)
-			printk(KERN_ERR "dv1394: Error registering ioctl32 translations\n");
-	}
-#endif
 
 	return 0;
 }
diff -Nru a/drivers/ieee1394/eth1394.c b/drivers/ieee1394/eth1394.c
--- a/drivers/ieee1394/eth1394.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/ieee1394/eth1394.c	2005-03-01 23:39:07 -08:00
@@ -168,11 +168,11 @@
  * consume in the event that some partial datagrams are never completed.  This
  * should probably change to a sysctl item or the like if possible.
  */
-MODULE_PARM(max_partial_datagrams, "i");
+static int max_partial_datagrams = 25;
+module_param(max_partial_datagrams, int, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(max_partial_datagrams,
 		 "Maximum number of partially received fragmented datagrams "
 		 "(default = 25).");
-static int max_partial_datagrams = 25;
 
 
 static int ether1394_header(struct sk_buff *skb, struct net_device *dev,
diff -Nru a/drivers/ieee1394/highlevel.c b/drivers/ieee1394/highlevel.c
--- a/drivers/ieee1394/highlevel.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/ieee1394/highlevel.c	2005-03-01 23:39:09 -08:00
@@ -43,9 +43,9 @@
 static DECLARE_RWSEM(hl_drivers_sem);
 
 static LIST_HEAD(hl_irqs);
-static rwlock_t hl_irqs_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(hl_irqs_lock);
 
-static rwlock_t addr_space_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(addr_space_lock);
 
 /* addr_space list will have zero and max already included as bounds */
 static struct hpsb_address_ops dummy_ops = { NULL, NULL, NULL, NULL };
diff -Nru a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c
--- a/drivers/ieee1394/nodemgr.c	2005-03-01 23:38:59 -08:00
+++ b/drivers/ieee1394/nodemgr.c	2005-03-01 23:38:59 -08:00
@@ -19,7 +19,6 @@
 #include <linux/delay.h>
 #include <linux/pci.h>
 #include <linux/moduleparam.h>
-#include <linux/suspend.h>
 #include <asm/atomic.h>
 
 #include "ieee1394_types.h"
@@ -1480,10 +1479,8 @@
 
 		if (down_interruptible(&hi->reset_sem) ||
 		    down_interruptible(&nodemgr_serialize)) {
-			if (current->flags & PF_FREEZE) {
-				refrigerator(0);
+			if (try_to_freeze(PF_FREEZE))
 				continue;
-			}
 			printk("NodeMgr: received unexpected signal?!\n" );
 			break;
 		}
diff -Nru a/drivers/ieee1394/pcilynx.c b/drivers/ieee1394/pcilynx.c
--- a/drivers/ieee1394/pcilynx.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/ieee1394/pcilynx.c	2005-03-01 23:38:55 -08:00
@@ -1546,8 +1546,8 @@
         host->pdev = dev;
         pci_set_drvdata(dev, lynx);
 
-        lynx->lock = SPIN_LOCK_UNLOCKED;
-        lynx->phy_reg_lock = SPIN_LOCK_UNLOCKED;
+        spin_lock_init(&lynx->lock);
+        spin_lock_init(&lynx->phy_reg_lock);
 
 #ifndef CONFIG_IEEE1394_PCILYNX_LOCALRAM
         lynx->pcl_mem = pci_alloc_consistent(dev, LOCALRAM_SIZE,
@@ -1659,11 +1659,11 @@
 	tasklet_init(&lynx->iso_rcv.tq, (void (*)(unsigned long))iso_rcv_bh,
 		     (unsigned long)lynx);
 
-        lynx->iso_rcv.lock = SPIN_LOCK_UNLOCKED;
+        spin_lock_init(&lynx->iso_rcv.lock);
 
-        lynx->async.queue_lock = SPIN_LOCK_UNLOCKED;
+        spin_lock_init(&lynx->async.queue_lock);
         lynx->async.channel = CHANNEL_ASYNC_SEND;
-        lynx->iso_send.queue_lock = SPIN_LOCK_UNLOCKED;
+        spin_lock_init(&lynx->iso_send.queue_lock);
         lynx->iso_send.channel = CHANNEL_ISO_SEND;
 
         PRINT(KERN_INFO, lynx->id, "remapped memory spaces reg 0x%p, rom 0x%p, "
diff -Nru a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c
--- a/drivers/ieee1394/raw1394.c	2005-03-01 23:38:44 -08:00
+++ b/drivers/ieee1394/raw1394.c	2005-03-01 23:38:44 -08:00
@@ -71,7 +71,7 @@
 
 static LIST_HEAD(host_info_list);
 static int host_count;
-static spinlock_t host_info_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(host_info_lock);
 static atomic_t internal_generation = ATOMIC_INIT(0);
 
 static atomic_t iso_buffer_size;
diff -Nru a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c
--- a/drivers/ieee1394/sbp2.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/ieee1394/sbp2.c	2005-03-01 23:38:52 -08:00
@@ -708,7 +708,7 @@
 	INIT_LIST_HEAD(&scsi_id->sbp2_command_orb_inuse);
 	INIT_LIST_HEAD(&scsi_id->sbp2_command_orb_completed);
 	INIT_LIST_HEAD(&scsi_id->scsi_list);
-	scsi_id->sbp2_command_orb_lock = SPIN_LOCK_UNLOCKED;
+	spin_lock_init(&scsi_id->sbp2_command_orb_lock);
 	scsi_id->sbp2_device_type_and_lun = SBP2_DEVICE_TYPE_LUN_UNINITIALIZED;
 
 	ud->device.driver_data = scsi_id;
diff -Nru a/drivers/ieee1394/video1394.c b/drivers/ieee1394/video1394.c
--- a/drivers/ieee1394/video1394.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/ieee1394/video1394.c	2005-03-01 23:38:53 -08:00
@@ -699,8 +699,8 @@
 	reg_write(ohci, OHCI1394_IsoXmitIntMaskSet, 1<<d->ctx);
 }
 
-static int video1394_ioctl(struct inode *inode, struct file *file,
-			   unsigned int cmd, unsigned long arg)
+static int __video1394_ioctl(struct file *file,
+			     unsigned int cmd, unsigned long arg)
 {
 	struct file_ctx *ctx = (struct file_ctx *)file->private_data;
 	struct ti_ohci *ohci = ctx->ohci;
@@ -1152,6 +1152,15 @@
 	}
 }
 
+static long video1394_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	int err;
+	lock_kernel();
+	err = __video1394_ioctl(file, cmd, arg);
+	unlock_kernel();
+	return err;
+}
+
 /*
  *	This maps the vmalloced and reserved buffer to user space.
  *
@@ -1233,11 +1242,18 @@
 	return 0;
 }
 
+#ifdef CONFIG_COMPAT
+static long video1394_compat_ioctl(struct file *f, unsigned cmd, unsigned long arg);
+#endif
+
 static struct cdev video1394_cdev;
 static struct file_operations video1394_fops=
 {
 	.owner =	THIS_MODULE,
-	.ioctl =	video1394_ioctl,
+	.unlocked_ioctl = video1394_ioctl,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl = video1394_compat_ioctl,
+#endif
 	.mmap =		video1394_mmap,
 	.open =		video1394_open,
 	.release =	video1394_release
@@ -1333,8 +1349,7 @@
 	struct compat_timeval filltime;
 };
 
-static int video1394_wr_wait32(unsigned int fd, unsigned int cmd, unsigned long arg,
-			       struct file *file)
+static int video1394_wr_wait32(struct file *file, unsigned int cmd, unsigned long arg)
 {
         struct video1394_wait32 __user *argp = (void __user *)arg;
         struct video1394_wait32 wait32;
@@ -1342,9 +1357,6 @@
         mm_segment_t old_fs;
         int ret;
 
-	if (file->f_op->ioctl != video1394_ioctl)
-		return -EFAULT;
-
         if (copy_from_user(&wait32, argp, sizeof(wait32)))
                 return -EFAULT;
 
@@ -1356,11 +1368,11 @@
         old_fs = get_fs();
         set_fs(KERNEL_DS);
         if (cmd == VIDEO1394_IOC32_LISTEN_WAIT_BUFFER)
-		ret = video1394_ioctl(file->f_dentry->d_inode, file,
+		ret = video1394_ioctl(file,
 				      VIDEO1394_IOC_LISTEN_WAIT_BUFFER,
 				      (unsigned long) &wait);
         else
-		ret = video1394_ioctl(file->f_dentry->d_inode, file,
+		ret = video1394_ioctl(file,
 				      VIDEO1394_IOC_LISTEN_POLL_BUFFER,
 				      (unsigned long) &wait);
         set_fs(old_fs);
@@ -1378,17 +1390,13 @@
         return ret;
 }
 
-static int video1394_w_wait32(unsigned int fd, unsigned int cmd, unsigned long arg,
-			      struct file *file)
+static int video1394_w_wait32(struct file *file, unsigned int cmd, unsigned long arg)
 {
         struct video1394_wait32 wait32;
         struct video1394_wait wait;
         mm_segment_t old_fs;
         int ret;
 
-	if (file->f_op->ioctl != video1394_ioctl)
-		return -EFAULT;
-
         if (copy_from_user(&wait32, (void __user *)arg, sizeof(wait32)))
                 return -EFAULT;
 
@@ -1400,11 +1408,11 @@
         old_fs = get_fs();
         set_fs(KERNEL_DS);
         if (cmd == VIDEO1394_IOC32_LISTEN_QUEUE_BUFFER)
-		ret = video1394_ioctl(file->f_dentry->d_inode, file,
+		ret = video1394_ioctl(file,
 				      VIDEO1394_IOC_LISTEN_QUEUE_BUFFER,
 				      (unsigned long) &wait);
         else
-		ret = video1394_ioctl(file->f_dentry->d_inode, file,
+		ret = video1394_ioctl(file,
 				      VIDEO1394_IOC_TALK_WAIT_BUFFER,
 				      (unsigned long) &wait);
         set_fs(old_fs);
@@ -1412,38 +1420,42 @@
         return ret;
 }
 
-static int video1394_queue_buf32(unsigned int fd, unsigned int cmd, unsigned long arg,
-				 struct file *file)
+static int video1394_queue_buf32(struct file *file, unsigned int cmd, unsigned long arg)
 {
-	if (file->f_op->ioctl != video1394_ioctl)
-		return -EFAULT;
-
-        return -EFAULT;
+        return -EFAULT;   /* ??? was there before. */
 
-	return video1394_ioctl(file->f_dentry->d_inode, file,
+	return video1394_ioctl(file,
 				VIDEO1394_IOC_TALK_QUEUE_BUFFER, arg);
 }
 
+static long video1394_compat_ioctl(struct file *f, unsigned cmd, unsigned long arg)
+{
+	switch (cmd) {
+	case VIDEO1394_IOC_LISTEN_CHANNEL:
+	case VIDEO1394_IOC_UNLISTEN_CHANNEL:
+	case VIDEO1394_IOC_TALK_CHANNEL:
+	case VIDEO1394_IOC_UNTALK_CHANNEL:
+		return video1394_ioctl(f, cmd, arg);
+
+	case VIDEO1394_IOC32_LISTEN_QUEUE_BUFFER:
+		return video1394_w_wait32(f, cmd, arg);
+	case VIDEO1394_IOC32_LISTEN_WAIT_BUFFER:
+		return video1394_wr_wait32(f, cmd, arg);
+	case VIDEO1394_IOC_TALK_QUEUE_BUFFER:
+		return video1394_queue_buf32(f, cmd, arg);
+	case VIDEO1394_IOC32_TALK_WAIT_BUFFER:
+		return video1394_w_wait32(f, cmd, arg);
+	case VIDEO1394_IOC32_LISTEN_POLL_BUFFER:
+		return video1394_wr_wait32(f, cmd, arg);
+	default:
+		return -ENOIOCTLCMD;
+	}
+}
+
 #endif /* CONFIG_COMPAT */
 
 static void __exit video1394_exit_module (void)
 {
-#ifdef CONFIG_COMPAT
-	int ret;
-
-	ret = unregister_ioctl32_conversion(VIDEO1394_IOC_LISTEN_CHANNEL);
-	ret |= unregister_ioctl32_conversion(VIDEO1394_IOC_UNLISTEN_CHANNEL);
-	ret |= unregister_ioctl32_conversion(VIDEO1394_IOC_TALK_CHANNEL);
-	ret |= unregister_ioctl32_conversion(VIDEO1394_IOC_UNTALK_CHANNEL);
-	ret |= unregister_ioctl32_conversion(VIDEO1394_IOC32_LISTEN_QUEUE_BUFFER);
-	ret |= unregister_ioctl32_conversion(VIDEO1394_IOC32_LISTEN_WAIT_BUFFER);
-	ret |= unregister_ioctl32_conversion(VIDEO1394_IOC_TALK_QUEUE_BUFFER);
-	ret |= unregister_ioctl32_conversion(VIDEO1394_IOC32_TALK_WAIT_BUFFER);
-	ret |= unregister_ioctl32_conversion(VIDEO1394_IOC32_LISTEN_POLL_BUFFER);
-	if (ret)
-		PRINT_G(KERN_CRIT, "Error unregistering ioctl32 translations");
-#endif
-
 	hpsb_unregister_protocol(&video1394_driver);
 
 	hpsb_unregister_highlevel(&video1394_highlevel);
@@ -1479,30 +1491,6 @@
 		cdev_del(&video1394_cdev);
 		return ret;
 	}
-
-#ifdef CONFIG_COMPAT
-	{
-		/* First the compatible ones */
-		ret = register_ioctl32_conversion(VIDEO1394_IOC_LISTEN_CHANNEL, NULL);
-		ret |= register_ioctl32_conversion(VIDEO1394_IOC_UNLISTEN_CHANNEL, NULL);
-		ret |= register_ioctl32_conversion(VIDEO1394_IOC_TALK_CHANNEL, NULL);
-		ret |= register_ioctl32_conversion(VIDEO1394_IOC_UNTALK_CHANNEL, NULL);
-
-		/* These need translation */
-		ret |= register_ioctl32_conversion(VIDEO1394_IOC32_LISTEN_QUEUE_BUFFER,
-					    video1394_w_wait32);
-		ret |= register_ioctl32_conversion(VIDEO1394_IOC32_LISTEN_WAIT_BUFFER,
-					    video1394_wr_wait32);
-		ret |= register_ioctl32_conversion(VIDEO1394_IOC_TALK_QUEUE_BUFFER,
-					    video1394_queue_buf32);
-		ret |= register_ioctl32_conversion(VIDEO1394_IOC32_TALK_WAIT_BUFFER,
-					    video1394_w_wait32);
-		ret |= register_ioctl32_conversion(VIDEO1394_IOC32_LISTEN_POLL_BUFFER,
-					    video1394_wr_wait32);
-		if (ret)
-			PRINT_G(KERN_INFO, "Error registering ioctl32 translations");
-	}
-#endif
 
 	PRINT_G(KERN_INFO, "Installed " VIDEO1394_DRIVER_NAME " module");
 	return 0;
diff -Nru a/drivers/infiniband/Kconfig b/drivers/infiniband/Kconfig
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/infiniband/Kconfig	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,14 @@
+menu "InfiniBand support"
+
+config INFINIBAND
+	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.
+
+source "drivers/infiniband/hw/mthca/Kconfig"
+
+source "drivers/infiniband/ulp/ipoib/Kconfig"
+
+endmenu
diff -Nru a/drivers/infiniband/Makefile b/drivers/infiniband/Makefile
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/infiniband/Makefile	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,3 @@
+obj-$(CONFIG_INFINIBAND)		+= core/
+obj-$(CONFIG_INFINIBAND_MTHCA)		+= hw/mthca/
+obj-$(CONFIG_INFINIBAND_IPOIB)		+= ulp/ipoib/
diff -Nru a/drivers/infiniband/core/Makefile b/drivers/infiniband/core/Makefile
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/infiniband/core/Makefile	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,12 @@
+EXTRA_CFLAGS += -Idrivers/infiniband/include
+
+obj-$(CONFIG_INFINIBAND) +=	ib_core.o ib_mad.o ib_sa.o ib_umad.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_sa-y :=			sa_query.o
+
+ib_umad-y :=			user_mad.o
diff -Nru a/drivers/infiniband/core/agent.c b/drivers/infiniband/core/agent.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/infiniband/core/agent.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,399 @@
+/*
+ * Copyright (c) 2004 Mellanox Technologies Ltd.  All rights reserved.
+ * Copyright (c) 2004 Infinicon Corporation.  All rights reserved.
+ * 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 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: agent.c 1389 2004-12-27 22:56:47Z roland $
+ */
+
+#include <linux/dma-mapping.h>
+
+#include <asm/bug.h>
+
+#include <ib_smi.h>
+
+#include "smi.h"
+#include "agent_priv.h"
+#include "mad_priv.h"
+
+
+spinlock_t ib_agent_port_list_lock;
+static LIST_HEAD(ib_agent_port_list);
+
+extern kmem_cache_t *ib_mad_cache;
+
+
+/*
+ * Caller must hold ib_agent_port_list_lock
+ */
+static inline struct ib_agent_port_private *
+__ib_get_agent_port(struct ib_device *device, int port_num,
+		    struct ib_mad_agent *mad_agent)
+{
+	struct ib_agent_port_private *entry;
+
+	BUG_ON(!(!!device ^ !!mad_agent));  /* Exactly one MUST be (!NULL) */
+
+	if (device) {
+		list_for_each_entry(entry, &ib_agent_port_list, port_list) {
+			if (entry->dr_smp_agent->device == device &&
+			    entry->port_num == port_num)
+				return entry;
+		}
+	} else {
+		list_for_each_entry(entry, &ib_agent_port_list, port_list) {
+			if ((entry->dr_smp_agent == mad_agent) ||
+			    (entry->lr_smp_agent == mad_agent) ||
+			    (entry->perf_mgmt_agent == mad_agent))
+				return entry;
+		}
+	}
+	return NULL;
+}
+
+static inline struct ib_agent_port_private *
+ib_get_agent_port(struct ib_device *device, int port_num,
+		  struct ib_mad_agent *mad_agent)
+{
+	struct ib_agent_port_private *entry;
+	unsigned long flags;
+
+	spin_lock_irqsave(&ib_agent_port_list_lock, flags);
+	entry = __ib_get_agent_port(device, port_num, mad_agent);
+	spin_unlock_irqrestore(&ib_agent_port_list_lock, flags);
+
+	return entry;
+}
+
+int smi_check_local_dr_smp(struct ib_smp *smp,
+			   struct ib_device *device,
+			   int port_num)
+{
+	struct ib_agent_port_private *port_priv;
+
+	if (smp->mgmt_class != IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE)
+		return 1;
+	port_priv = ib_get_agent_port(device, port_num, NULL);
+	if (!port_priv) {
+		printk(KERN_DEBUG SPFX "smi_check_local_dr_smp %s port %d "
+		       "not open\n",
+		       device->name, port_num);
+		return 1;
+	}
+
+	return smi_check_local_smp(port_priv->dr_smp_agent, smp);
+}
+
+static int agent_mad_send(struct ib_mad_agent *mad_agent,
+			  struct ib_agent_port_private *port_priv,
+			  struct ib_mad_private *mad_priv,
+			  struct ib_grh *grh,
+			  struct ib_wc *wc)
+{
+	struct ib_agent_send_wr *agent_send_wr;
+	struct ib_sge gather_list;
+	struct ib_send_wr send_wr;
+	struct ib_send_wr *bad_send_wr;
+	struct ib_ah_attr ah_attr;
+	unsigned long flags;
+	int ret = 1;
+
+	agent_send_wr = kmalloc(sizeof(*agent_send_wr), GFP_KERNEL);
+	if (!agent_send_wr)
+		goto out;
+	agent_send_wr->mad = mad_priv;
+
+	/* PCI mapping */
+	gather_list.addr = dma_map_single(mad_agent->device->dma_device,
+					  &mad_priv->mad,
+					  sizeof(mad_priv->mad),
+					  DMA_TO_DEVICE);
+	gather_list.length = sizeof(mad_priv->mad);
+	gather_list.lkey = (*port_priv->mr).lkey;
+
+	send_wr.next = NULL;
+	send_wr.opcode = IB_WR_SEND;
+	send_wr.sg_list = &gather_list;
+	send_wr.num_sge = 1;
+	send_wr.wr.ud.remote_qpn = wc->src_qp; /* DQPN */
+	send_wr.wr.ud.timeout_ms = 0;
+	send_wr.send_flags = IB_SEND_SIGNALED | IB_SEND_SOLICITED;
+
+	ah_attr.dlid = wc->slid;
+	ah_attr.port_num = mad_agent->port_num;
+	ah_attr.src_path_bits = wc->dlid_path_bits;
+	ah_attr.sl = wc->sl;
+	ah_attr.static_rate = 0;
+	ah_attr.ah_flags = 0; /* No GRH */
+	if (mad_priv->mad.mad.mad_hdr.mgmt_class == IB_MGMT_CLASS_PERF_MGMT) {
+		if (wc->wc_flags & IB_WC_GRH) {
+			ah_attr.ah_flags = IB_AH_GRH;
+			/* 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;
+			memcpy(ah_attr.grh.dgid.raw,
+			       grh->sgid.raw,
+			       sizeof(ah_attr.grh.dgid));
+		}
+	}
+
+	agent_send_wr->ah = ib_create_ah(mad_agent->qp->pd, &ah_attr);
+	if (IS_ERR(agent_send_wr->ah)) {
+		printk(KERN_ERR SPFX "No memory for address handle\n");
+		kfree(agent_send_wr);
+		goto out;
+	}
+
+	send_wr.wr.ud.ah = agent_send_wr->ah;
+	if (mad_priv->mad.mad.mad_hdr.mgmt_class == IB_MGMT_CLASS_PERF_MGMT) {
+		send_wr.wr.ud.pkey_index = wc->pkey_index;
+		send_wr.wr.ud.remote_qkey = IB_QP1_QKEY;
+	} else { 	/* for SMPs */
+		send_wr.wr.ud.pkey_index = 0;
+		send_wr.wr.ud.remote_qkey = 0;
+	}
+	send_wr.wr.ud.mad_hdr = &mad_priv->mad.mad.mad_hdr;
+	send_wr.wr_id = (unsigned long)agent_send_wr;
+
+	pci_unmap_addr_set(agent_send_wr, mapping, gather_list.addr);
+
+	/* Send */
+	spin_lock_irqsave(&port_priv->send_list_lock, flags);
+	if (ib_post_send_mad(mad_agent, &send_wr, &bad_send_wr)) {
+		spin_unlock_irqrestore(&port_priv->send_list_lock, flags);
+		dma_unmap_single(mad_agent->device->dma_device,
+				 pci_unmap_addr(agent_send_wr, mapping),
+				 sizeof(mad_priv->mad),
+				 DMA_TO_DEVICE);
+		ib_destroy_ah(agent_send_wr->ah);
+		kfree(agent_send_wr);
+	} else {
+		list_add_tail(&agent_send_wr->send_list,
+			      &port_priv->send_posted_list);
+		spin_unlock_irqrestore(&port_priv->send_list_lock, flags);
+		ret = 0;
+	}
+
+out:
+	return ret;
+}
+
+int agent_send(struct ib_mad_private *mad,
+	       struct ib_grh *grh,
+	       struct ib_wc *wc,
+	       struct ib_device *device,
+	       int port_num)
+{
+	struct ib_agent_port_private *port_priv;
+	struct ib_mad_agent *mad_agent;
+
+	port_priv = ib_get_agent_port(device, port_num, NULL);
+	if (!port_priv) {
+		printk(KERN_DEBUG SPFX "agent_send %s port %d not open\n",
+		       device->name, port_num);
+		return 1;
+	}
+
+	/* Get mad agent based on mgmt_class in MAD */
+	switch (mad->mad.mad.mad_hdr.mgmt_class) {
+		case IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE:
+			mad_agent = port_priv->dr_smp_agent;
+			break;
+		case IB_MGMT_CLASS_SUBN_LID_ROUTED:
+			mad_agent = port_priv->lr_smp_agent;
+			break;
+		case IB_MGMT_CLASS_PERF_MGMT:
+			mad_agent = port_priv->perf_mgmt_agent;
+			break;
+		default:
+			return 1;
+	}
+
+	return agent_mad_send(mad_agent, port_priv, mad, grh, wc);
+}
+
+static void agent_send_handler(struct ib_mad_agent *mad_agent,
+			       struct ib_mad_send_wc *mad_send_wc)
+{
+	struct ib_agent_port_private	*port_priv;
+	struct ib_agent_send_wr		*agent_send_wr;
+	unsigned long			flags;
+
+	/* Find matching MAD agent */
+	port_priv = ib_get_agent_port(NULL, 0, mad_agent);
+	if (!port_priv) {
+		printk(KERN_ERR SPFX "agent_send_handler: no matching MAD "
+		       "agent %p\n", mad_agent);
+		return;
+	}
+
+	agent_send_wr = (struct ib_agent_send_wr *)(unsigned long)mad_send_wc->wr_id;
+	spin_lock_irqsave(&port_priv->send_list_lock, flags);
+	/* Remove completed send from posted send MAD list */
+	list_del(&agent_send_wr->send_list);
+	spin_unlock_irqrestore(&port_priv->send_list_lock, flags);
+
+	/* Unmap PCI */
+	dma_unmap_single(mad_agent->device->dma_device,
+			 pci_unmap_addr(agent_send_wr, mapping),
+			 sizeof(agent_send_wr->mad->mad),
+			 DMA_TO_DEVICE);
+
+	ib_destroy_ah(agent_send_wr->ah);
+
+	/* Release allocated memory */
+	kmem_cache_free(ib_mad_cache, agent_send_wr->mad);
+	kfree(agent_send_wr);
+}
+
+int ib_agent_port_open(struct ib_device *device, int port_num)
+{
+	int ret;
+	struct ib_agent_port_private *port_priv;
+	struct ib_mad_reg_req reg_req;
+	unsigned long flags;
+
+	/* First, check if port already open for SMI */
+	port_priv = ib_get_agent_port(device, port_num, NULL);
+	if (port_priv) {
+		printk(KERN_DEBUG SPFX "%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) {
+		printk(KERN_ERR SPFX "No memory for ib_agent_port_private\n");
+		ret = -ENOMEM;
+		goto error1;
+	}
+
+	memset(port_priv, 0, sizeof *port_priv);
+	port_priv->port_num = port_num;
+	spin_lock_init(&port_priv->send_list_lock);
+	INIT_LIST_HEAD(&port_priv->send_posted_list);
+
+	/* Obtain MAD agent for directed route SM class */
+	reg_req.mgmt_class = IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE;
+	reg_req.mgmt_class_version = 1;
+
+	port_priv->dr_smp_agent = ib_register_mad_agent(device, port_num,
+							IB_QPT_SMI,
+							NULL, 0,
+						       &agent_send_handler,
+							NULL, NULL);
+
+	if (IS_ERR(port_priv->dr_smp_agent)) {
+		ret = PTR_ERR(port_priv->dr_smp_agent);
+		goto error2;
+	}
+
+	/* Obtain MAD agent for LID routed SM class */
+	reg_req.mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED;
+	port_priv->lr_smp_agent = ib_register_mad_agent(device, port_num,
+							IB_QPT_SMI,
+							NULL, 0,
+						       &agent_send_handler,
+							NULL, NULL);
+	if (IS_ERR(port_priv->lr_smp_agent)) {
+		ret = PTR_ERR(port_priv->lr_smp_agent);
+		goto error3;
+	}
+
+	/* Obtain MAD agent for PerfMgmt class */
+	reg_req.mgmt_class = IB_MGMT_CLASS_PERF_MGMT;
+	port_priv->perf_mgmt_agent = ib_register_mad_agent(device, port_num,
+							   IB_QPT_GSI,
+							   NULL, 0,
+							  &agent_send_handler,
+							   NULL, NULL);
+	if (IS_ERR(port_priv->perf_mgmt_agent)) {
+		ret = PTR_ERR(port_priv->perf_mgmt_agent);
+		goto error4;
+	}
+
+	port_priv->mr = ib_get_dma_mr(port_priv->dr_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 error5;
+	}
+
+	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;
+
+error5:
+	ib_unregister_mad_agent(port_priv->perf_mgmt_agent);
+error4:
+	ib_unregister_mad_agent(port_priv->lr_smp_agent);
+error3:
+	ib_unregister_mad_agent(port_priv->dr_smp_agent);
+error2:
+	kfree(port_priv);
+error1:
+	return ret;
+}
+
+int ib_agent_port_close(struct ib_device *device, int port_num)
+{
+	struct ib_agent_port_private *port_priv;
+	unsigned long flags;
+
+	spin_lock_irqsave(&ib_agent_port_list_lock, flags);
+	port_priv = __ib_get_agent_port(device, port_num, NULL);
+	if (port_priv == NULL) {
+		spin_unlock_irqrestore(&ib_agent_port_list_lock, flags);
+		printk(KERN_ERR SPFX "Port %d not found\n", port_num);
+		return -ENODEV;
+	}
+	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->lr_smp_agent);
+	ib_unregister_mad_agent(port_priv->dr_smp_agent);
+	kfree(port_priv);
+
+	return 0;
+}
diff -Nru a/drivers/infiniband/core/agent.h b/drivers/infiniband/core/agent.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/infiniband/core/agent.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2004 Mellanox Technologies Ltd.  All rights reserved.
+ * Copyright (c) 2004 Infinicon Corporation.  All rights reserved.
+ * 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 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: agent.h 1389 2004-12-27 22:56:47Z roland $
+ */
+
+#ifndef __AGENT_H_
+#define __AGENT_H_
+
+extern spinlock_t ib_agent_port_list_lock;
+
+extern int ib_agent_port_open(struct ib_device *device,
+			      int port_num);
+
+extern int ib_agent_port_close(struct ib_device *device, int port_num);
+
+extern int agent_send(struct ib_mad_private *mad,
+		      struct ib_grh *grh,
+		      struct ib_wc *wc,
+		      struct ib_device *device,
+		      int port_num);
+
+#endif	/* __AGENT_H_ */
diff -Nru a/drivers/infiniband/core/agent_priv.h b/drivers/infiniband/core/agent_priv.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/infiniband/core/agent_priv.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2004 Mellanox Technologies Ltd.  All rights reserved.
+ * Copyright (c) 2004 Infinicon Corporation.  All rights reserved.
+ * 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 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: agent_priv.h 1389 2004-12-27 22:56:47Z roland $
+ */
+
+#ifndef __IB_AGENT_PRIV_H__
+#define __IB_AGENT_PRIV_H__
+
+#include <linux/pci.h>
+
+#define SPFX "ib_agent: "
+
+struct ib_agent_send_wr {
+	struct list_head send_list;
+	struct ib_ah *ah;
+	struct ib_mad_private *mad;
+	DECLARE_PCI_UNMAP_ADDR(mapping)
+};
+
+struct ib_agent_port_private {
+	struct list_head port_list;
+	struct list_head send_posted_list;
+	spinlock_t send_list_lock;
+	int port_num;
+	struct ib_mad_agent *dr_smp_agent;    /* DR SM class */
+	struct ib_mad_agent *lr_smp_agent;    /* LR SM class */
+	struct ib_mad_agent *perf_mgmt_agent; /* PerfMgmt class */
+	struct ib_mr *mr;
+};
+
+#endif	/* __IB_AGENT_PRIV_H__ */
diff -Nru a/drivers/infiniband/core/cache.c b/drivers/infiniband/core/cache.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/infiniband/core/cache.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,363 @@
+/*
+ * Copyright (c) 2004 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: cache.c 1349 2004-12-16 21:09:43Z roland $
+ */
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+
+#include "core_priv.h"
+
+struct ib_pkey_cache {
+	int             table_len;
+	u16             table[0];
+};
+
+struct ib_gid_cache {
+	int             table_len;
+	union ib_gid    table[0];
+};
+
+struct ib_update_work {
+	struct work_struct work;
+	struct ib_device  *device;
+	u8                 port_num;
+};
+
+static inline int start_port(struct ib_device *device)
+{
+	return device->node_type == IB_NODE_SWITCH ? 0 : 1;
+}
+
+static inline int end_port(struct ib_device *device)
+{
+	return device->node_type == IB_NODE_SWITCH ? 0 : device->phys_port_cnt;
+}
+
+int ib_get_cached_gid(struct ib_device *device,
+		      u8                port_num,
+		      int               index,
+		      union ib_gid     *gid)
+{
+	struct ib_gid_cache *cache;
+	unsigned long flags;
+	int ret = 0;
+
+	if (port_num < start_port(device) || port_num > end_port(device))
+		return -EINVAL;
+
+	read_lock_irqsave(&device->cache.lock, flags);
+
+	cache = device->cache.gid_cache[port_num - start_port(device)];
+
+	if (index < 0 || index >= cache->table_len)
+		ret = -EINVAL;
+	else
+		*gid = cache->table[index];
+
+	read_unlock_irqrestore(&device->cache.lock, flags);
+
+	return ret;
+}
+EXPORT_SYMBOL(ib_get_cached_gid);
+
+int ib_find_cached_gid(struct ib_device *device,
+		       union ib_gid	*gid,
+		       u8               *port_num,
+		       u16              *index)
+{
+	struct ib_gid_cache *cache;
+	unsigned long flags;
+	int p, i;
+	int ret = -ENOENT;
+
+	*port_num = -1;
+	if (index)
+		*index = -1;
+
+	read_lock_irqsave(&device->cache.lock, flags);
+
+	for (p = 0; p <= end_port(device) - start_port(device); ++p) {
+		cache = device->cache.gid_cache[p];
+		for (i = 0; i < cache->table_len; ++i) {
+			if (!memcmp(gid, &cache->table[i], sizeof *gid)) {
+				*port_num = p;
+				if (index)
+					*index = i;
+				ret = 0;
+				goto found;
+			}
+		}
+	}
+found:
+	read_unlock_irqrestore(&device->cache.lock, flags);
+
+	return ret;
+}
+EXPORT_SYMBOL(ib_find_cached_gid);
+
+int ib_get_cached_pkey(struct ib_device *device,
+		       u8                port_num,
+		       int               index,
+		       u16              *pkey)
+{
+	struct ib_pkey_cache *cache;
+	unsigned long flags;
+	int ret = 0;
+
+	if (port_num < start_port(device) || port_num > end_port(device))
+		return -EINVAL;
+
+	read_lock_irqsave(&device->cache.lock, flags);
+
+	cache = device->cache.pkey_cache[port_num - start_port(device)];
+
+	if (index < 0 || index >= cache->table_len)
+		ret = -EINVAL;
+	else
+		*pkey = cache->table[index];
+
+	read_unlock_irqrestore(&device->cache.lock, flags);
+
+	return ret;
+}
+EXPORT_SYMBOL(ib_get_cached_pkey);
+
+int ib_find_cached_pkey(struct ib_device *device,
+			u8                port_num,
+			u16               pkey,
+			u16              *index)
+{
+	struct ib_pkey_cache *cache;
+	unsigned long flags;
+	int i;
+	int ret = -ENOENT;
+
+	if (port_num < start_port(device) || port_num > end_port(device))
+		return -EINVAL;
+
+	read_lock_irqsave(&device->cache.lock, flags);
+
+	cache = device->cache.pkey_cache[port_num - start_port(device)];
+
+	*index = -1;
+
+	for (i = 0; i < cache->table_len; ++i)
+		if ((cache->table[i] & 0x7fff) == (pkey & 0x7fff)) {
+			*index = i;
+			ret = 0;
+			break;
+		}
+
+	read_unlock_irqrestore(&device->cache.lock, flags);
+
+	return ret;
+}
+EXPORT_SYMBOL(ib_find_cached_pkey);
+
+static void ib_cache_update(struct ib_device *device,
+			    u8                port)
+{
+	struct ib_port_attr       *tprops = NULL;
+	struct ib_pkey_cache      *pkey_cache = NULL, *old_pkey_cache;
+	struct ib_gid_cache       *gid_cache = NULL, *old_gid_cache;
+	int                        i;
+	int                        ret;
+
+	tprops = kmalloc(sizeof *tprops, GFP_KERNEL);
+	if (!tprops)
+		return;
+
+	ret = ib_query_port(device, port, tprops);
+	if (ret) {
+		printk(KERN_WARNING "ib_query_port failed (%d) for %s\n",
+		       ret, device->name);
+		goto err;
+	}
+
+	pkey_cache = kmalloc(sizeof *pkey_cache + tprops->pkey_tbl_len *
+			     sizeof *pkey_cache->table, GFP_KERNEL);
+	if (!pkey_cache)
+		goto err;
+
+	pkey_cache->table_len = tprops->pkey_tbl_len;
+
+	gid_cache = kmalloc(sizeof *gid_cache + tprops->gid_tbl_len *
+			    sizeof *gid_cache->table, GFP_KERNEL);
+	if (!gid_cache)
+		goto err;
+
+	gid_cache->table_len = tprops->gid_tbl_len;
+
+	for (i = 0; i < pkey_cache->table_len; ++i) {
+		ret = ib_query_pkey(device, port, i, pkey_cache->table + i);
+		if (ret) {
+			printk(KERN_WARNING "ib_query_pkey failed (%d) for %s (index %d)\n",
+			       ret, device->name, i);
+			goto err;
+		}
+	}
+
+	for (i = 0; i < gid_cache->table_len; ++i) {
+		ret = ib_query_gid(device, port, i, gid_cache->table + i);
+		if (ret) {
+			printk(KERN_WARNING "ib_query_gid failed (%d) for %s (index %d)\n",
+			       ret, device->name, i);
+			goto err;
+		}
+	}
+
+	write_lock_irq(&device->cache.lock);
+
+	old_pkey_cache = device->cache.pkey_cache[port - start_port(device)];
+	old_gid_cache  = device->cache.gid_cache [port - start_port(device)];
+
+	device->cache.pkey_cache[port - start_port(device)] = pkey_cache;
+	device->cache.gid_cache [port - start_port(device)] = gid_cache;
+
+	write_unlock_irq(&device->cache.lock);
+
+	kfree(old_pkey_cache);
+	kfree(old_gid_cache);
+	kfree(tprops);
+	return;
+
+err:
+	kfree(pkey_cache);
+	kfree(gid_cache);
+	kfree(tprops);
+}
+
+static void ib_cache_task(void *work_ptr)
+{
+	struct ib_update_work *work = work_ptr;
+
+	ib_cache_update(work->device, work->port_num);
+	kfree(work);
+}
+
+static void ib_cache_event(struct ib_event_handler *handler,
+			   struct ib_event *event)
+{
+	struct ib_update_work *work;
+
+	if (event->event == IB_EVENT_PORT_ERR    ||
+	    event->event == IB_EVENT_PORT_ACTIVE ||
+	    event->event == IB_EVENT_LID_CHANGE  ||
+	    event->event == IB_EVENT_PKEY_CHANGE ||
+	    event->event == IB_EVENT_SM_CHANGE) {
+		work = kmalloc(sizeof *work, GFP_ATOMIC);
+		if (work) {
+			INIT_WORK(&work->work, ib_cache_task, work);
+			work->device   = event->device;
+			work->port_num = event->element.port_num;
+			schedule_work(&work->work);
+		}
+	}
+}
+
+static void ib_cache_setup_one(struct ib_device *device)
+{
+	int p;
+
+	rwlock_init(&device->cache.lock);
+
+	device->cache.pkey_cache =
+		kmalloc(sizeof *device->cache.pkey_cache *
+			(end_port(device) - start_port(device) + 1), GFP_KERNEL);
+	device->cache.gid_cache =
+		kmalloc(sizeof *device->cache.pkey_cache *
+			(end_port(device) - start_port(device) + 1), GFP_KERNEL);
+
+	if (!device->cache.pkey_cache || !device->cache.gid_cache) {
+		printk(KERN_WARNING "Couldn't allocate cache "
+		       "for %s\n", device->name);
+		goto err;
+	}
+
+	for (p = 0; p <= end_port(device) - start_port(device); ++p) {
+		device->cache.pkey_cache[p] = NULL;
+		device->cache.gid_cache [p] = NULL;
+		ib_cache_update(device, p + start_port(device));
+	}
+
+	INIT_IB_EVENT_HANDLER(&device->cache.event_handler,
+			      device, ib_cache_event);
+	if (ib_register_event_handler(&device->cache.event_handler))
+		goto err_cache;
+
+	return;
+
+err_cache:
+	for (p = 0; p <= end_port(device) - start_port(device); ++p) {
+		kfree(device->cache.pkey_cache[p]);
+		kfree(device->cache.gid_cache[p]);
+	}
+
+err:
+	kfree(device->cache.pkey_cache);
+	kfree(device->cache.gid_cache);
+}
+
+static void ib_cache_cleanup_one(struct ib_device *device)
+{
+	int p;
+
+	ib_unregister_event_handler(&device->cache.event_handler);
+	flush_scheduled_work();
+
+	for (p = 0; p <= end_port(device) - start_port(device); ++p) {
+		kfree(device->cache.pkey_cache[p]);
+		kfree(device->cache.gid_cache[p]);
+	}
+
+	kfree(device->cache.pkey_cache);
+	kfree(device->cache.gid_cache);
+}
+
+static struct ib_client cache_client = {
+	.name   = "cache",
+	.add    = ib_cache_setup_one,
+	.remove = ib_cache_cleanup_one
+};
+
+int __init ib_cache_setup(void)
+{
+	return ib_register_client(&cache_client);
+}
+
+void __exit ib_cache_cleanup(void)
+{
+	ib_unregister_client(&cache_client);
+}
diff -Nru a/drivers/infiniband/core/core_priv.h b/drivers/infiniband/core/core_priv.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/infiniband/core/core_priv.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2004 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: core_priv.h 1349 2004-12-16 21:09:43Z roland $
+ */
+
+#ifndef _CORE_PRIV_H
+#define _CORE_PRIV_H
+
+#include <linux/list.h>
+#include <linux/spinlock.h>
+
+#include <ib_verbs.h>
+
+int  ib_device_register_sysfs(struct ib_device *device);
+void ib_device_unregister_sysfs(struct ib_device *device);
+
+int  ib_sysfs_setup(void);
+void ib_sysfs_cleanup(void);
+
+int  ib_cache_setup(void);
+void ib_cache_cleanup(void);
+
+#endif /* _CORE_PRIV_H */
diff -Nru a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/infiniband/core/device.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,614 @@
+/*
+ * Copyright (c) 2004 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: device.c 1349 2004-12-16 21:09:43Z roland $
+ */
+
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+
+#include <asm/semaphore.h>
+
+#include "core_priv.h"
+
+MODULE_AUTHOR("Roland Dreier");
+MODULE_DESCRIPTION("core kernel InfiniBand API");
+MODULE_LICENSE("Dual BSD/GPL");
+
+struct ib_client_data {
+	struct list_head  list;
+	struct ib_client *client;
+	void *            data;
+};
+
+static LIST_HEAD(device_list);
+static LIST_HEAD(client_list);
+
+/*
+ * device_sem protects access to both device_list and client_list.
+ * There's no real point to using multiple locks or something fancier
+ * like an rwsem: we always access both lists, and we're always
+ * modifying one list or the other list.  In any case this is not a
+ * hot path so there's no point in trying to optimize.
+ */
+static DECLARE_MUTEX(device_sem);
+
+static int ib_device_check_mandatory(struct ib_device *device)
+{
+#define IB_MANDATORY_FUNC(x) { offsetof(struct ib_device, x), #x }
+	static const struct {
+		size_t offset;
+		char  *name;
+	} mandatory_table[] = {
+		IB_MANDATORY_FUNC(query_device),
+		IB_MANDATORY_FUNC(query_port),
+		IB_MANDATORY_FUNC(query_pkey),
+		IB_MANDATORY_FUNC(query_gid),
+		IB_MANDATORY_FUNC(alloc_pd),
+		IB_MANDATORY_FUNC(dealloc_pd),
+		IB_MANDATORY_FUNC(create_ah),
+		IB_MANDATORY_FUNC(destroy_ah),
+		IB_MANDATORY_FUNC(create_qp),
+		IB_MANDATORY_FUNC(modify_qp),
+		IB_MANDATORY_FUNC(destroy_qp),
+		IB_MANDATORY_FUNC(post_send),
+		IB_MANDATORY_FUNC(post_recv),
+		IB_MANDATORY_FUNC(create_cq),
+		IB_MANDATORY_FUNC(destroy_cq),
+		IB_MANDATORY_FUNC(poll_cq),
+		IB_MANDATORY_FUNC(req_notify_cq),
+		IB_MANDATORY_FUNC(get_dma_mr),
+		IB_MANDATORY_FUNC(dereg_mr)
+	};
+	int i;
+
+	for (i = 0; i < sizeof mandatory_table / sizeof mandatory_table[0]; ++i) {
+		if (!*(void **) ((void *) device + mandatory_table[i].offset)) {
+			printk(KERN_WARNING "Device %s is missing mandatory function %s\n",
+			       device->name, mandatory_table[i].name);
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
+static struct ib_device *__ib_device_get_by_name(const char *name)
+{
+	struct ib_device *device;
+
+	list_for_each_entry(device, &device_list, core_list)
+		if (!strncmp(name, device->name, IB_DEVICE_NAME_MAX))
+			return device;
+
+	return NULL;
+}
+
+
+static int alloc_name(char *name)
+{
+	long *inuse;
+	char buf[IB_DEVICE_NAME_MAX];
+	struct ib_device *device;
+	int i;
+
+	inuse = (long *) get_zeroed_page(GFP_KERNEL);
+	if (!inuse)
+		return -ENOMEM;
+
+	list_for_each_entry(device, &device_list, core_list) {
+		if (!sscanf(device->name, name, &i))
+			continue;
+		if (i < 0 || i >= PAGE_SIZE * 8)
+			continue;
+		snprintf(buf, sizeof buf, name, i);
+		if (!strncmp(buf, device->name, IB_DEVICE_NAME_MAX))
+			set_bit(i, inuse);
+	}
+
+	i = find_first_zero_bit(inuse, PAGE_SIZE * 8);
+	free_page((unsigned long) inuse);
+	snprintf(buf, sizeof buf, name, i);
+
+	if (__ib_device_get_by_name(buf))
+		return -ENFILE;
+
+	strlcpy(name, buf, IB_DEVICE_NAME_MAX);
+	return 0;
+}
+
+/**
+ * ib_alloc_device - allocate an IB device struct
+ * @size:size of structure to allocate
+ *
+ * Low-level drivers should use ib_alloc_device() to allocate &struct
+ * ib_device.  @size is the size of the structure to be allocated,
+ * including any private data used by the low-level driver.
+ * ib_dealloc_device() must be used to free structures allocated with
+ * ib_alloc_device().
+ */
+struct ib_device *ib_alloc_device(size_t size)
+{
+	void *dev;
+
+	BUG_ON(size < sizeof (struct ib_device));
+
+	dev = kmalloc(size, GFP_KERNEL);
+	if (!dev)
+		return NULL;
+
+	memset(dev, 0, size);
+
+	return dev;
+}
+EXPORT_SYMBOL(ib_alloc_device);
+
+/**
+ * ib_dealloc_device - free an IB device struct
+ * @device:structure to free
+ *
+ * Free a structure allocated with ib_alloc_device().
+ */
+void ib_dealloc_device(struct ib_device *device)
+{
+	if (device->reg_state == IB_DEV_UNINITIALIZED) {
+		kfree(device);
+		return;
+	}
+
+	BUG_ON(device->reg_state != IB_DEV_UNREGISTERED);
+
+	ib_device_unregister_sysfs(device);
+}
+EXPORT_SYMBOL(ib_dealloc_device);
+
+static int add_client_context(struct ib_device *device, struct ib_client *client)
+{
+	struct ib_client_data *context;
+	unsigned long flags;
+
+	context = kmalloc(sizeof *context, GFP_KERNEL);
+	if (!context) {
+		printk(KERN_WARNING "Couldn't allocate client context for %s/%s\n",
+		       device->name, client->name);
+		return -ENOMEM;
+	}
+
+	context->client = client;
+	context->data   = NULL;
+
+	spin_lock_irqsave(&device->client_data_lock, flags);
+	list_add(&context->list, &device->client_data_list);
+	spin_unlock_irqrestore(&device->client_data_lock, flags);
+
+	return 0;
+}
+
+/**
+ * ib_register_device - Register an IB device with IB core
+ * @device:Device to register
+ *
+ * Low-level drivers use ib_register_device() to register their
+ * devices with the IB core.  All registered clients will receive a
+ * callback for each device that is added. @device must be allocated
+ * with ib_alloc_device().
+ */
+int ib_register_device(struct ib_device *device)
+{
+	int ret;
+
+	down(&device_sem);
+
+	if (strchr(device->name, '%')) {
+		ret = alloc_name(device->name);
+		if (ret)
+			goto out;
+	}
+
+	if (ib_device_check_mandatory(device)) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	INIT_LIST_HEAD(&device->event_handler_list);
+	INIT_LIST_HEAD(&device->client_data_list);
+	spin_lock_init(&device->event_handler_lock);
+	spin_lock_init(&device->client_data_lock);
+
+	ret = ib_device_register_sysfs(device);
+	if (ret) {
+		printk(KERN_WARNING "Couldn't register device %s with driver model\n",
+		       device->name);
+		goto out;
+	}
+
+	list_add_tail(&device->core_list, &device_list);
+
+	device->reg_state = IB_DEV_REGISTERED;
+
+	{
+		struct ib_client *client;
+
+		list_for_each_entry(client, &client_list, list)
+			if (client->add && !add_client_context(device, client))
+				client->add(device);
+	}
+
+ out:
+	up(&device_sem);
+	return ret;
+}
+EXPORT_SYMBOL(ib_register_device);
+
+/**
+ * ib_unregister_device - Unregister an IB device
+ * @device:Device to unregister
+ *
+ * Unregister an IB device.  All clients will receive a remove callback.
+ */
+void ib_unregister_device(struct ib_device *device)
+{
+	struct ib_client *client;
+	struct ib_client_data *context, *tmp;
+	unsigned long flags;
+
+	down(&device_sem);
+
+	list_for_each_entry_reverse(client, &client_list, list)
+		if (client->remove)
+			client->remove(device);
+
+	list_del(&device->core_list);
+
+	up(&device_sem);
+
+	spin_lock_irqsave(&device->client_data_lock, flags);
+	list_for_each_entry_safe(context, tmp, &device->client_data_list, list)
+		kfree(context);
+	spin_unlock_irqrestore(&device->client_data_lock, flags);
+
+	device->reg_state = IB_DEV_UNREGISTERED;
+}
+EXPORT_SYMBOL(ib_unregister_device);
+
+/**
+ * ib_register_client - Register an IB client
+ * @client:Client to register
+ *
+ * Upper level users of the IB drivers can use ib_register_client() to
+ * register callbacks for IB device addition and removal.  When an IB
+ * device is added, each registered client's add method will be called
+ * (in the order the clients were registered), and when a device is
+ * removed, each client's remove method will be called (in the reverse
+ * order that clients were registered).  In addition, when
+ * ib_register_client() is called, the client will receive an add
+ * callback for all devices already registered.
+ */
+int ib_register_client(struct ib_client *client)
+{
+	struct ib_device *device;
+
+	down(&device_sem);
+
+	list_add_tail(&client->list, &client_list);
+	list_for_each_entry(device, &device_list, core_list)
+		if (client->add && !add_client_context(device, client))
+			client->add(device);
+
+	up(&device_sem);
+
+	return 0;
+}
+EXPORT_SYMBOL(ib_register_client);
+
+/**
+ * ib_unregister_client - Unregister an IB client
+ * @client:Client to unregister
+ *
+ * Upper level users use ib_unregister_client() to remove their client
+ * registration.  When ib_unregister_client() is called, the client
+ * will receive a remove callback for each IB device still registered.
+ */
+void ib_unregister_client(struct ib_client *client)
+{
+	struct ib_client_data *context, *tmp;
+	struct ib_device *device;
+	unsigned long flags;
+
+	down(&device_sem);
+
+	list_for_each_entry(device, &device_list, core_list) {
+		if (client->remove)
+			client->remove(device);
+
+		spin_lock_irqsave(&device->client_data_lock, flags);
+		list_for_each_entry_safe(context, tmp, &device->client_data_list, list)
+			if (context->client == client) {
+				list_del(&context->list);
+				kfree(context);
+			}
+		spin_unlock_irqrestore(&device->client_data_lock, flags);
+	}
+	list_del(&client->list);
+
+	up(&device_sem);
+}
+EXPORT_SYMBOL(ib_unregister_client);
+
+/**
+ * ib_get_client_data - Get IB client context
+ * @device:Device to get context for
+ * @client:Client to get context for
+ *
+ * ib_get_client_data() returns client context set with
+ * ib_set_client_data().
+ */
+void *ib_get_client_data(struct ib_device *device, struct ib_client *client)
+{
+	struct ib_client_data *context;
+	void *ret = NULL;
+	unsigned long flags;
+
+	spin_lock_irqsave(&device->client_data_lock, flags);
+	list_for_each_entry(context, &device->client_data_list, list)
+		if (context->client == client) {
+			ret = context->data;
+			break;
+		}
+	spin_unlock_irqrestore(&device->client_data_lock, flags);
+
+	return ret;
+}
+EXPORT_SYMBOL(ib_get_client_data);
+
+/**
+ * ib_set_client_data - Get IB client context
+ * @device:Device to set context for
+ * @client:Client to set context for
+ * @data:Context to set
+ *
+ * ib_set_client_data() sets client context that can be retrieved with
+ * ib_get_client_data().
+ */
+void ib_set_client_data(struct ib_device *device, struct ib_client *client,
+			void *data)
+{
+	struct ib_client_data *context;
+	unsigned long flags;
+
+	spin_lock_irqsave(&device->client_data_lock, flags);
+	list_for_each_entry(context, &device->client_data_list, list)
+		if (context->client == client) {
+			context->data = data;
+			goto out;
+		}
+
+	printk(KERN_WARNING "No client context found for %s/%s\n",
+	       device->name, client->name);
+
+out:
+	spin_unlock_irqrestore(&device->client_data_lock, flags);
+}
+EXPORT_SYMBOL(ib_set_client_data);
+
+/**
+ * ib_register_event_handler - Register an IB event handler
+ * @event_handler:Handler to register
+ *
+ * ib_register_event_handler() registers an event handler that will be
+ * called back when asynchronous IB events occur (as defined in
+ * chapter 11 of the InfiniBand Architecture Specification).  This
+ * callback may occur in interrupt context.
+ */
+int ib_register_event_handler  (struct ib_event_handler *event_handler)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&event_handler->device->event_handler_lock, flags);
+	list_add_tail(&event_handler->list,
+		      &event_handler->device->event_handler_list);
+	spin_unlock_irqrestore(&event_handler->device->event_handler_lock, flags);
+
+	return 0;
+}
+EXPORT_SYMBOL(ib_register_event_handler);
+
+/**
+ * ib_unregister_event_handler - Unregister an event handler
+ * @event_handler:Handler to unregister
+ *
+ * Unregister an event handler registered with
+ * ib_register_event_handler().
+ */
+int ib_unregister_event_handler(struct ib_event_handler *event_handler)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&event_handler->device->event_handler_lock, flags);
+	list_del(&event_handler->list);
+	spin_unlock_irqrestore(&event_handler->device->event_handler_lock, flags);
+
+	return 0;
+}
+EXPORT_SYMBOL(ib_unregister_event_handler);
+
+/**
+ * ib_dispatch_event - Dispatch an asynchronous event
+ * @event:Event to dispatch
+ *
+ * Low-level drivers must call ib_dispatch_event() to dispatch the
+ * event to all registered event handlers when an asynchronous event
+ * occurs.
+ */
+void ib_dispatch_event(struct ib_event *event)
+{
+	unsigned long flags;
+	struct ib_event_handler *handler;
+
+	spin_lock_irqsave(&event->device->event_handler_lock, flags);
+
+	list_for_each_entry(handler, &event->device->event_handler_list, list)
+		handler->handler(handler, event);
+
+	spin_unlock_irqrestore(&event->device->event_handler_lock, flags);
+}
+EXPORT_SYMBOL(ib_dispatch_event);
+
+/**
+ * ib_query_device - Query IB device attributes
+ * @device:Device to query
+ * @device_attr:Device attributes
+ *
+ * ib_query_device() returns the attributes of a device through the
+ * @device_attr pointer.
+ */
+int ib_query_device(struct ib_device *device,
+		    struct ib_device_attr *device_attr)
+{
+	return device->query_device(device, device_attr);
+}
+EXPORT_SYMBOL(ib_query_device);
+
+/**
+ * ib_query_port - Query IB port attributes
+ * @device:Device to query
+ * @port_num:Port number to query
+ * @port_attr:Port attributes
+ *
+ * ib_query_port() returns the attributes of a port through the
+ * @port_attr pointer.
+ */
+int ib_query_port(struct ib_device *device,
+		  u8 port_num,
+		  struct ib_port_attr *port_attr)
+{
+	return device->query_port(device, port_num, port_attr);
+}
+EXPORT_SYMBOL(ib_query_port);
+
+/**
+ * ib_query_gid - Get GID table entry
+ * @device:Device to query
+ * @port_num:Port number to query
+ * @index:GID table index to query
+ * @gid:Returned GID
+ *
+ * ib_query_gid() fetches the specified GID table entry.
+ */
+int ib_query_gid(struct ib_device *device,
+		 u8 port_num, int index, union ib_gid *gid)
+{
+	return device->query_gid(device, port_num, index, gid);
+}
+EXPORT_SYMBOL(ib_query_gid);
+
+/**
+ * ib_query_pkey - Get P_Key table entry
+ * @device:Device to query
+ * @port_num:Port number to query
+ * @index:P_Key table index to query
+ * @pkey:Returned P_Key
+ *
+ * ib_query_pkey() fetches the specified P_Key table entry.
+ */
+int ib_query_pkey(struct ib_device *device,
+		  u8 port_num, u16 index, u16 *pkey)
+{
+	return device->query_pkey(device, port_num, index, pkey);
+}
+EXPORT_SYMBOL(ib_query_pkey);
+
+/**
+ * ib_modify_device - Change IB device attributes
+ * @device:Device to modify
+ * @device_modify_mask:Mask of attributes to change
+ * @device_modify:New attribute values
+ *
+ * ib_modify_device() changes a device's attributes as specified by
+ * the @device_modify_mask and @device_modify structure.
+ */
+int ib_modify_device(struct ib_device *device,
+		     int device_modify_mask,
+		     struct ib_device_modify *device_modify)
+{
+	return device->modify_device(device, device_modify_mask,
+				     device_modify);
+}
+EXPORT_SYMBOL(ib_modify_device);
+
+/**
+ * ib_modify_port - Modifies the attributes for the specified port.
+ * @device: The device to modify.
+ * @port_num: The number of the port to modify.
+ * @port_modify_mask: Mask used to specify which attributes of the port
+ *   to change.
+ * @port_modify: New attribute values for the port.
+ *
+ * ib_modify_port() changes a port's attributes as specified by the
+ * @port_modify_mask and @port_modify structure.
+ */
+int ib_modify_port(struct ib_device *device,
+		   u8 port_num, int port_modify_mask,
+		   struct ib_port_modify *port_modify)
+{
+	return device->modify_port(device, port_num, port_modify_mask,
+				   port_modify);
+}
+EXPORT_SYMBOL(ib_modify_port);
+
+static int __init ib_core_init(void)
+{
+	int ret;
+
+	ret = ib_sysfs_setup();
+	if (ret)
+		printk(KERN_WARNING "Couldn't create InfiniBand device class\n");
+
+	ret = ib_cache_setup();
+	if (ret) {
+		printk(KERN_WARNING "Couldn't set up InfiniBand P_Key/GID cache\n");
+		ib_sysfs_cleanup();
+	}
+
+	return ret;
+}
+
+static void __exit ib_core_cleanup(void)
+{
+	ib_cache_cleanup();
+	ib_sysfs_cleanup();
+}
+
+module_init(ib_core_init);
+module_exit(ib_core_cleanup);
diff -Nru a/drivers/infiniband/core/fmr_pool.c b/drivers/infiniband/core/fmr_pool.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/infiniband/core/fmr_pool.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,507 @@
+/*
+ * Copyright (c) 2004 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: fmr_pool.c 1349 2004-12-16 21:09:43Z roland $
+ */
+
+#include <linux/errno.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <linux/jhash.h>
+#include <linux/kthread.h>
+
+#include <ib_fmr_pool.h>
+
+#include "core_priv.h"
+
+enum {
+	IB_FMR_MAX_REMAPS = 32,
+
+	IB_FMR_HASH_BITS  = 8,
+	IB_FMR_HASH_SIZE  = 1 << IB_FMR_HASH_BITS,
+	IB_FMR_HASH_MASK  = IB_FMR_HASH_SIZE - 1
+};
+
+/*
+ * If an FMR is not in use, then the list member will point to either
+ * its pool's free_list (if the FMR can be mapped again; that is,
+ * remap_count < IB_FMR_MAX_REMAPS) or its pool's dirty_list (if the
+ * FMR needs to be unmapped before being remapped).  In either of
+ * these cases it is a bug if the ref_count is not 0.  In other words,
+ * if ref_count is > 0, then the list member must not be linked into
+ * either free_list or dirty_list.
+ *
+ * The cache_node member is used to link the FMR into a cache bucket
+ * (if caching is enabled).  This is independent of the reference
+ * count of the FMR.  When a valid FMR is released, its ref_count is
+ * decremented, and if ref_count reaches 0, the FMR is placed in
+ * either free_list or dirty_list as appropriate.  However, it is not
+ * removed from the cache and may be "revived" if a call to
+ * ib_fmr_register_physical() occurs before the FMR is remapped.  In
+ * this case we just increment the ref_count and remove the FMR from
+ * free_list/dirty_list.
+ *
+ * Before we remap an FMR from free_list, we remove it from the cache
+ * (to prevent another user from obtaining a stale FMR).  When an FMR
+ * is released, we add it to the tail of the free list, so that our
+ * cache eviction policy is "least recently used."
+ *
+ * All manipulation of ref_count, list and cache_node is protected by
+ * pool_lock to maintain consistency.
+ */
+
+struct ib_fmr_pool {
+	spinlock_t                pool_lock;
+
+	int                       pool_size;
+	int                       max_pages;
+	int                       dirty_watermark;
+	int                       dirty_len;
+	struct list_head          free_list;
+	struct list_head          dirty_list;
+	struct hlist_head        *cache_bucket;
+
+	void                     (*flush_function)(struct ib_fmr_pool *pool,
+						   void *              arg);
+	void                     *flush_arg;
+
+	struct task_struct       *thread;
+
+	atomic_t                  req_ser;
+	atomic_t                  flush_ser;
+
+	wait_queue_head_t         force_wait;
+};
+
+static inline u32 ib_fmr_hash(u64 first_page)
+{
+	return jhash_2words((u32) first_page,
+			    (u32) (first_page >> 32),
+			    0);
+}
+
+/* Caller must hold pool_lock */
+static inline struct ib_pool_fmr *ib_fmr_cache_lookup(struct ib_fmr_pool *pool,
+						      u64 *page_list,
+						      int  page_list_len,
+						      u64  io_virtual_address)
+{
+	struct hlist_head *bucket;
+	struct ib_pool_fmr *fmr;
+	struct hlist_node *pos;
+
+	if (!pool->cache_bucket)
+		return NULL;
+
+	bucket = pool->cache_bucket + ib_fmr_hash(*page_list);
+
+	hlist_for_each_entry(fmr, pos, bucket, cache_node)
+		if (io_virtual_address == fmr->io_virtual_address &&
+		    page_list_len      == fmr->page_list_len      &&
+		    !memcmp(page_list, fmr->page_list,
+			    page_list_len * sizeof *page_list))
+			return fmr;
+
+	return NULL;
+}
+
+static void ib_fmr_batch_release(struct ib_fmr_pool *pool)
+{
+	int                 ret;
+	struct ib_pool_fmr *fmr;
+	LIST_HEAD(unmap_list);
+	LIST_HEAD(fmr_list);
+
+	spin_lock_irq(&pool->pool_lock);
+
+	list_for_each_entry(fmr, &pool->dirty_list, list) {
+		hlist_del_init(&fmr->cache_node);
+		fmr->remap_count = 0;
+		list_add_tail(&fmr->fmr->list, &fmr_list);
+
+#ifdef DEBUG
+		if (fmr->ref_count !=0) {
+			printk(KERN_WARNING "Unmapping FMR 0x%08x with ref count %d",
+			       fmr, fmr->ref_count);
+		}
+#endif
+	}
+
+	list_splice(&pool->dirty_list, &unmap_list);
+	INIT_LIST_HEAD(&pool->dirty_list);
+	pool->dirty_len = 0;
+
+	spin_unlock_irq(&pool->pool_lock);
+
+	if (list_empty(&unmap_list)) {
+		return;
+	}
+
+	ret = ib_unmap_fmr(&fmr_list);
+	if (ret)
+		printk(KERN_WARNING "ib_unmap_fmr returned %d", ret);
+
+	spin_lock_irq(&pool->pool_lock);
+	list_splice(&unmap_list, &pool->free_list);
+	spin_unlock_irq(&pool->pool_lock);
+}
+
+static int ib_fmr_cleanup_thread(void *pool_ptr)
+{
+	struct ib_fmr_pool *pool = pool_ptr;
+
+	do {
+		if (pool->dirty_len >= pool->dirty_watermark ||
+		    atomic_read(&pool->flush_ser) - atomic_read(&pool->req_ser) < 0) {
+			ib_fmr_batch_release(pool);
+
+			atomic_inc(&pool->flush_ser);
+			wake_up_interruptible(&pool->force_wait);
+
+			if (pool->flush_function)
+				pool->flush_function(pool, pool->flush_arg);
+		}
+
+		set_current_state(TASK_INTERRUPTIBLE);
+		if (pool->dirty_len < pool->dirty_watermark &&
+		    atomic_read(&pool->flush_ser) - atomic_read(&pool->req_ser) >= 0 &&
+		    !kthread_should_stop())
+			schedule();
+		__set_current_state(TASK_RUNNING);
+	} while (!kthread_should_stop());
+
+	return 0;
+}
+
+/**
+ * ib_create_fmr_pool - Create an FMR pool
+ * @pd:Protection domain for FMRs
+ * @params:FMR pool parameters
+ *
+ * Create a pool of FMRs.  Return value is pointer to new pool or
+ * error code if creation failed.
+ */
+struct ib_fmr_pool *ib_create_fmr_pool(struct ib_pd             *pd,
+				       struct ib_fmr_pool_param *params)
+{
+	struct ib_device   *device;
+	struct ib_fmr_pool *pool;
+	int i;
+	int ret;
+
+	if (!params)
+		return ERR_PTR(-EINVAL);
+
+	device = pd->device;
+	if (!device->alloc_fmr    || !device->dealloc_fmr  ||
+	    !device->map_phys_fmr || !device->unmap_fmr) {
+		printk(KERN_WARNING "Device %s does not support fast memory regions",
+		       device->name);
+		return ERR_PTR(-ENOSYS);
+	}
+
+	pool = kmalloc(sizeof *pool, GFP_KERNEL);
+	if (!pool) {
+		printk(KERN_WARNING "couldn't allocate pool struct");
+		return ERR_PTR(-ENOMEM);
+	}
+
+	pool->cache_bucket   = NULL;
+
+	pool->flush_function = params->flush_function;
+	pool->flush_arg      = params->flush_arg;
+
+	INIT_LIST_HEAD(&pool->free_list);
+	INIT_LIST_HEAD(&pool->dirty_list);
+
+	if (params->cache) {
+		pool->cache_bucket =
+			kmalloc(IB_FMR_HASH_SIZE * sizeof *pool->cache_bucket,
+				GFP_KERNEL);
+		if (!pool->cache_bucket) {
+			printk(KERN_WARNING "Failed to allocate cache in pool");
+			ret = -ENOMEM;
+			goto out_free_pool;
+		}
+
+		for (i = 0; i < IB_FMR_HASH_SIZE; ++i)
+			INIT_HLIST_HEAD(pool->cache_bucket + i);
+	}
+
+	pool->pool_size       = 0;
+	pool->max_pages       = params->max_pages_per_fmr;
+	pool->dirty_watermark = params->dirty_watermark;
+	pool->dirty_len       = 0;
+	spin_lock_init(&pool->pool_lock);
+	atomic_set(&pool->req_ser,   0);
+	atomic_set(&pool->flush_ser, 0);
+	init_waitqueue_head(&pool->force_wait);
+
+	pool->thread = kthread_create(ib_fmr_cleanup_thread,
+				      pool,
+				      "ib_fmr(%s)",
+				      device->name);
+	if (IS_ERR(pool->thread)) {
+		printk(KERN_WARNING "couldn't start cleanup thread");
+		ret = PTR_ERR(pool->thread);
+		goto out_free_pool;
+	}
+
+	{
+		struct ib_pool_fmr *fmr;
+		struct ib_fmr_attr attr = {
+			.max_pages = params->max_pages_per_fmr,
+			.max_maps  = IB_FMR_MAX_REMAPS,
+			.page_size = PAGE_SHIFT
+		};
+
+		for (i = 0; i < params->pool_size; ++i) {
+			fmr = kmalloc(sizeof *fmr + params->max_pages_per_fmr * sizeof (u64),
+				      GFP_KERNEL);
+			if (!fmr) {
+				printk(KERN_WARNING "failed to allocate fmr struct "
+				       "for FMR %d", i);
+				goto out_fail;
+			}
+
+			fmr->pool             = pool;
+			fmr->remap_count      = 0;
+			fmr->ref_count        = 0;
+			INIT_HLIST_NODE(&fmr->cache_node);
+
+			fmr->fmr = ib_alloc_fmr(pd, params->access, &attr);
+			if (IS_ERR(fmr->fmr)) {
+				printk(KERN_WARNING "fmr_create failed for FMR %d", i);
+				kfree(fmr);
+				goto out_fail;
+			}
+
+			list_add_tail(&fmr->list, &pool->free_list);
+			++pool->pool_size;
+		}
+	}
+
+	return pool;
+
+ out_free_pool:
+	kfree(pool->cache_bucket);
+	kfree(pool);
+
+	return ERR_PTR(ret);
+
+ out_fail:
+	ib_destroy_fmr_pool(pool);
+
+	return ERR_PTR(-ENOMEM);
+}
+EXPORT_SYMBOL(ib_create_fmr_pool);
+
+/**
+ * ib_destroy_fmr_pool - Free FMR pool
+ * @pool:FMR pool to free
+ *
+ * Destroy an FMR pool and free all associated resources.
+ */
+int ib_destroy_fmr_pool(struct ib_fmr_pool *pool)
+{
+	struct ib_pool_fmr *fmr;
+	struct ib_pool_fmr *tmp;
+	int                 i;
+
+	kthread_stop(pool->thread);
+	ib_fmr_batch_release(pool);
+
+	i = 0;
+	list_for_each_entry_safe(fmr, tmp, &pool->free_list, list) {
+		ib_dealloc_fmr(fmr->fmr);
+		list_del(&fmr->list);
+		kfree(fmr);
+		++i;
+	}
+
+	if (i < pool->pool_size)
+		printk(KERN_WARNING "pool still has %d regions registered",
+		       pool->pool_size - i);
+
+	kfree(pool->cache_bucket);
+	kfree(pool);
+
+	return 0;
+}
+EXPORT_SYMBOL(ib_destroy_fmr_pool);
+
+/**
+ * ib_flush_fmr_pool - Invalidate all unmapped FMRs
+ * @pool:FMR pool to flush
+ *
+ * Ensure that all unmapped FMRs are fully invalidated.
+ */
+int ib_flush_fmr_pool(struct ib_fmr_pool *pool)
+{
+	int serial;
+
+	atomic_inc(&pool->req_ser);
+	/*
+	 * It's OK if someone else bumps req_ser again here -- we'll
+	 * just wait a little longer.
+	 */
+	serial = atomic_read(&pool->req_ser);
+
+	wake_up_process(pool->thread);
+
+	if (wait_event_interruptible(pool->force_wait,
+				     atomic_read(&pool->flush_ser) -
+				     atomic_read(&pool->req_ser) >= 0))
+		return -EINTR;
+
+	return 0;
+}
+EXPORT_SYMBOL(ib_flush_fmr_pool);
+
+/**
+ * ib_fmr_pool_map_phys -
+ * @pool:FMR pool to allocate FMR from
+ * @page_list:List of pages to map
+ * @list_len:Number of pages in @page_list
+ * @io_virtual_address:I/O virtual address for new FMR
+ *
+ * Map an FMR from an FMR pool.
+ */
+struct ib_pool_fmr *ib_fmr_pool_map_phys(struct ib_fmr_pool *pool_handle,
+					 u64                *page_list,
+					 int                 list_len,
+					 u64                *io_virtual_address)
+{
+	struct ib_fmr_pool *pool = pool_handle;
+	struct ib_pool_fmr *fmr;
+	unsigned long       flags;
+	int                 result;
+
+	if (list_len < 1 || list_len > pool->max_pages)
+		return ERR_PTR(-EINVAL);
+
+	spin_lock_irqsave(&pool->pool_lock, flags);
+	fmr = ib_fmr_cache_lookup(pool,
+				  page_list,
+				  list_len,
+				  *io_virtual_address);
+	if (fmr) {
+		/* found in cache */
+		++fmr->ref_count;
+		if (fmr->ref_count == 1) {
+			list_del(&fmr->list);
+		}
+
+		spin_unlock_irqrestore(&pool->pool_lock, flags);
+
+		return fmr;
+	}
+
+	if (list_empty(&pool->free_list)) {
+		spin_unlock_irqrestore(&pool->pool_lock, flags);
+		return ERR_PTR(-EAGAIN);
+	}
+
+	fmr = list_entry(pool->free_list.next, struct ib_pool_fmr, list);
+	list_del(&fmr->list);
+	hlist_del_init(&fmr->cache_node);
+	spin_unlock_irqrestore(&pool->pool_lock, flags);
+
+	result = ib_map_phys_fmr(fmr->fmr, page_list, list_len,
+				 *io_virtual_address);
+
+	if (result) {
+		spin_lock_irqsave(&pool->pool_lock, flags);
+		list_add(&fmr->list, &pool->free_list);
+		spin_unlock_irqrestore(&pool->pool_lock, flags);
+
+		printk(KERN_WARNING "fmr_map returns %d",
+		       result);
+
+		return ERR_PTR(result);
+	}
+
+	++fmr->remap_count;
+	fmr->ref_count = 1;
+
+	if (pool->cache_bucket) {
+		fmr->io_virtual_address = *io_virtual_address;
+		fmr->page_list_len      = list_len;
+		memcpy(fmr->page_list, page_list, list_len * sizeof(*page_list));
+
+		spin_lock_irqsave(&pool->pool_lock, flags);
+		hlist_add_head(&fmr->cache_node,
+			       pool->cache_bucket + ib_fmr_hash(fmr->page_list[0]));
+		spin_unlock_irqrestore(&pool->pool_lock, flags);
+	}
+
+	return fmr;
+}
+EXPORT_SYMBOL(ib_fmr_pool_map_phys);
+
+/**
+ * ib_fmr_pool_unmap - Unmap FMR
+ * @fmr:FMR to unmap
+ *
+ * Unmap an FMR.  The FMR mapping may remain valid until the FMR is
+ * reused (or until ib_flush_fmr_pool() is called).
+ */
+int ib_fmr_pool_unmap(struct ib_pool_fmr *fmr)
+{
+	struct ib_fmr_pool *pool;
+	unsigned long flags;
+
+	pool = fmr->pool;
+
+	spin_lock_irqsave(&pool->pool_lock, flags);
+
+	--fmr->ref_count;
+	if (!fmr->ref_count) {
+		if (fmr->remap_count < IB_FMR_MAX_REMAPS) {
+			list_add_tail(&fmr->list, &pool->free_list);
+		} else {
+			list_add_tail(&fmr->list, &pool->dirty_list);
+			++pool->dirty_len;
+			wake_up_process(pool->thread);
+		}
+	}
+
+#ifdef DEBUG
+	if (fmr->ref_count < 0)
+		printk(KERN_WARNING "FMR %p has ref count %d < 0",
+		       fmr, fmr->ref_count);
+#endif
+
+	spin_unlock_irqrestore(&pool->pool_lock, flags);
+
+	return 0;
+}
+EXPORT_SYMBOL(ib_fmr_pool_unmap);
diff -Nru a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/infiniband/core/mad.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,2689 @@
+/*
+ * Copyright (c) 2004, 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.c 1389 2004-12-27 22:56:47Z roland $
+ */
+
+#include <linux/dma-mapping.h>
+#include <linux/interrupt.h>
+
+#include <ib_mad.h>
+
+#include "mad_priv.h"
+#include "smi.h"
+#include "agent.h"
+
+
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_DESCRIPTION("kernel IB MAD API");
+MODULE_AUTHOR("Hal Rosenstock");
+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;
+
+/* Port list lock */
+static spinlock_t ib_mad_port_list_lock;
+
+
+/* Forward declarations */
+static int method_in_use(struct ib_mad_mgmt_method_table **method,
+			 struct ib_mad_reg_req *mad_reg_req);
+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);
+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 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);
+static int add_oui_reg_req(struct ib_mad_reg_req *mad_reg_req,
+			   struct ib_mad_agent_private *agent_priv);
+
+/*
+ * Returns a ib_mad_port_private structure or NULL for a device/port
+ * Assumes ib_mad_port_list_lock is being held
+ */
+static inline struct ib_mad_port_private *
+__ib_get_mad_port(struct ib_device *device, int port_num)
+{
+	struct ib_mad_port_private *entry;
+
+	list_for_each_entry(entry, &ib_mad_port_list, port_list) {
+		if (entry->device == device && entry->port_num == port_num)
+			return entry;
+	}
+	return NULL;
+}
+
+/*
+ * Wrapper function to return a ib_mad_port_private structure or NULL
+ * for a device/port
+ */
+static inline struct ib_mad_port_private *
+ib_get_mad_port(struct ib_device *device, int port_num)
+{
+	struct ib_mad_port_private *entry;
+	unsigned long flags;
+
+	spin_lock_irqsave(&ib_mad_port_list_lock, flags);
+	entry = __ib_get_mad_port(device, port_num);
+	spin_unlock_irqrestore(&ib_mad_port_list_lock, flags);
+
+	return entry;
+}
+
+static inline u8 convert_mgmt_class(u8 mgmt_class)
+{
+	/* Alias IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE to 0 */
+	return mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE ?
+		0 : mgmt_class;
+}
+
+static int get_spl_qp_index(enum ib_qp_type qp_type)
+{
+	switch (qp_type)
+	{
+	case IB_QPT_SMI:
+		return 0;
+	case IB_QPT_GSI:
+		return 1;
+	default:
+		return -1;
+	}
+}
+
+static int vendor_class_index(u8 mgmt_class)
+{
+	return mgmt_class - IB_MGMT_CLASS_VENDOR_RANGE2_START;
+}
+
+static int is_vendor_class(u8 mgmt_class)
+{
+	if ((mgmt_class < IB_MGMT_CLASS_VENDOR_RANGE2_START) ||
+	    (mgmt_class > IB_MGMT_CLASS_VENDOR_RANGE2_END))
+		return 0;
+	return 1;
+}
+
+static int is_vendor_oui(char *oui)
+{
+	if (oui[0] || oui[1] || oui[2])
+		return 1;
+	return 0;
+}
+
+static int is_vendor_method_in_use(
+		struct ib_mad_mgmt_vendor_class *vendor_class,
+		struct ib_mad_reg_req *mad_reg_req)
+{
+	struct ib_mad_mgmt_method_table *method;
+	int i;
+
+	for (i = 0; i < MAX_MGMT_OUI; i++) {
+		if (!memcmp(vendor_class->oui[i], mad_reg_req->oui, 3)) {
+			method = vendor_class->method_table[i];
+			if (method) {
+				if (method_in_use(&method, mad_reg_req))
+					return 1;
+				else
+					break;
+			}
+		}
+	}
+	return 0;
+}
+
+/*
+ * ib_register_mad_agent - Register to send/receive MADs
+ */
+struct ib_mad_agent *ib_register_mad_agent(struct ib_device *device,
+					   u8 port_num,
+					   enum ib_qp_type qp_type,
+					   struct ib_mad_reg_req *mad_reg_req,
+					   u8 rmpp_version,
+					   ib_mad_send_handler send_handler,
+					   ib_mad_recv_handler recv_handler,
+					   void *context)
+{
+	struct ib_mad_port_private *port_priv;
+	struct ib_mad_agent *ret = ERR_PTR(-EINVAL);
+	struct ib_mad_agent_private *mad_agent_priv;
+	struct ib_mad_reg_req *reg_req = NULL;
+	struct ib_mad_mgmt_class_table *class;
+	struct ib_mad_mgmt_vendor_class_table *vendor;
+	struct ib_mad_mgmt_vendor_class *vendor_class;
+	struct ib_mad_mgmt_method_table *method;
+	int ret2, qpn;
+	unsigned long flags;
+	u8 mgmt_class, vclass;
+
+	/* Validate parameters */
+	qpn = get_spl_qp_index(qp_type);
+	if (qpn == -1)
+		goto error1;
+
+	if (rmpp_version)
+		goto error1;	/* XXX: until RMPP implemented */
+
+	/* Validate MAD registration request if supplied */
+	if (mad_reg_req) {
+		if (mad_reg_req->mgmt_class_version >= MAX_MGMT_VERSION)
+			goto error1;
+		if (!recv_handler)
+			goto error1;
+		if (mad_reg_req->mgmt_class >= MAX_MGMT_CLASS) {
+			/*
+			 * IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE is the only
+			 * one in this range currently allowed
+			 */
+			if (mad_reg_req->mgmt_class !=
+			    IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE)
+				goto error1;
+		} else if (mad_reg_req->mgmt_class == 0) {
+			/*
+			 * Class 0 is reserved in IBA and is used for
+			 * aliasing of IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE
+			 */
+			goto error1;
+		} else if (is_vendor_class(mad_reg_req->mgmt_class)) {
+			/*
+			 * If class is in "new" vendor range,
+			 * ensure supplied OUI is not zero
+			 */
+			if (!is_vendor_oui(mad_reg_req->oui))
+				goto error1;
+		}
+		/* Make sure class supplied is consistent with QP type */
+		if (qp_type == IB_QPT_SMI) {
+			if ((mad_reg_req->mgmt_class !=
+					IB_MGMT_CLASS_SUBN_LID_ROUTED) &&
+			    (mad_reg_req->mgmt_class !=
+					IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE))
+				goto error1;
+		} else {
+			if ((mad_reg_req->mgmt_class ==
+					IB_MGMT_CLASS_SUBN_LID_ROUTED) ||
+			    (mad_reg_req->mgmt_class ==
+					IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE))
+				goto error1;
+		}
+	} else {
+		/* No registration request supplied */
+		if (!send_handler)
+			goto error1;
+	}
+
+	/* Validate device and port */
+	port_priv = ib_get_mad_port(device, port_num);
+	if (!port_priv) {
+		ret = ERR_PTR(-ENODEV);
+		goto error1;
+	}
+
+	/* Allocate structures */
+	mad_agent_priv = kmalloc(sizeof *mad_agent_priv, GFP_KERNEL);
+	if (!mad_agent_priv) {
+		ret = ERR_PTR(-ENOMEM);
+		goto error1;
+	}
+
+	if (mad_reg_req) {
+		reg_req = kmalloc(sizeof *reg_req, GFP_KERNEL);
+		if (!reg_req) {
+			ret = ERR_PTR(-ENOMEM);
+			goto error2;
+		}
+		/* 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.device = device;
+	mad_agent_priv->agent.recv_handler = recv_handler;
+	mad_agent_priv->agent.send_handler = send_handler;
+	mad_agent_priv->agent.context = context;
+	mad_agent_priv->agent.qp = port_priv->qp_info[qpn].qp;
+	mad_agent_priv->agent.port_num = port_num;
+
+	spin_lock_irqsave(&port_priv->reg_lock, flags);
+	mad_agent_priv->agent.hi_tid = ++ib_mad_client_id;
+
+	/*
+	 * Make sure MAD registration (if supplied)
+	 * is non overlapping with any existing ones
+	 */
+	if (mad_reg_req) {
+		mgmt_class = convert_mgmt_class(mad_reg_req->mgmt_class);
+		if (!is_vendor_class(mgmt_class)) {
+			class = port_priv->version[mad_reg_req->
+						   mgmt_class_version].class;
+			if (class) {
+				method = class->method_table[mgmt_class];
+				if (method) {
+					if (method_in_use(&method,
+							   mad_reg_req))
+						goto error3;
+				}
+			}
+			ret2 = add_nonoui_reg_req(mad_reg_req, mad_agent_priv,
+						  mgmt_class);
+		} else {
+			/* "New" vendor class range */
+			vendor = port_priv->version[mad_reg_req->
+						    mgmt_class_version].vendor;
+			if (vendor) {
+				vclass = vendor_class_index(mgmt_class);
+				vendor_class = vendor->vendor_class[vclass];
+				if (vendor_class) {
+					if (is_vendor_method_in_use(
+							vendor_class,
+							mad_reg_req))
+						goto error3;
+				}
+			}
+			ret2 = add_oui_reg_req(mad_reg_req, mad_agent_priv);
+		}
+		if (ret2) {
+			ret = ERR_PTR(ret2);
+			goto error3;
+		}
+	}
+
+	/* Add mad agent into port's agent list */
+	list_add_tail(&mad_agent_priv->agent_list, &port_priv->agent_list);
+	spin_unlock_irqrestore(&port_priv->reg_lock, flags);
+
+	spin_lock_init(&mad_agent_priv->lock);
+	INIT_LIST_HEAD(&mad_agent_priv->send_list);
+	INIT_LIST_HEAD(&mad_agent_priv->wait_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);
+	atomic_set(&mad_agent_priv->refcount, 1);
+	init_waitqueue_head(&mad_agent_priv->wait);
+
+	return &mad_agent_priv->agent;
+
+error3:
+	spin_unlock_irqrestore(&port_priv->reg_lock, flags);
+	kfree(reg_req);
+error2:
+	kfree(mad_agent_priv);
+error1:
+	return ret;
+}
+EXPORT_SYMBOL(ib_register_mad_agent);
+
+static inline int is_snooping_sends(int mad_snoop_flags)
+{
+	return (mad_snoop_flags &
+		(/*IB_MAD_SNOOP_POSTED_SENDS |
+		 IB_MAD_SNOOP_RMPP_SENDS |*/
+		 IB_MAD_SNOOP_SEND_COMPLETIONS /*|
+		 IB_MAD_SNOOP_RMPP_SEND_COMPLETIONS*/));
+}
+
+static inline int is_snooping_recvs(int mad_snoop_flags)
+{
+	return (mad_snoop_flags &
+		(IB_MAD_SNOOP_RECVS /*|
+		 IB_MAD_SNOOP_RMPP_RECVS*/));
+}
+
+static int register_snoop_agent(struct ib_mad_qp_info *qp_info,
+				struct ib_mad_snoop_private *mad_snoop_priv)
+{
+	struct ib_mad_snoop_private **new_snoop_table;
+	unsigned long flags;
+	int i;
+
+	spin_lock_irqsave(&qp_info->snoop_lock, flags);
+	/* Check for empty slot in array. */
+	for (i = 0; i < qp_info->snoop_table_size; i++)
+		if (!qp_info->snoop_table[i])
+			break;
+
+	if (i == qp_info->snoop_table_size) {
+		/* Grow table. */
+		new_snoop_table = kmalloc(sizeof mad_snoop_priv *
+					  qp_info->snoop_table_size + 1,
+					  GFP_ATOMIC);
+		if (!new_snoop_table) {
+			i = -ENOMEM;
+			goto out;
+		}
+		if (qp_info->snoop_table) {
+			memcpy(new_snoop_table, qp_info->snoop_table,
+			       sizeof mad_snoop_priv *
+			       qp_info->snoop_table_size);
+			kfree(qp_info->snoop_table);
+		}
+		qp_info->snoop_table = new_snoop_table;
+		qp_info->snoop_table_size++;
+	}
+	qp_info->snoop_table[i] = mad_snoop_priv;
+	atomic_inc(&qp_info->snoop_count);
+out:
+	spin_unlock_irqrestore(&qp_info->snoop_lock, flags);
+	return i;
+}
+
+struct ib_mad_agent *ib_register_mad_snoop(struct ib_device *device,
+					   u8 port_num,
+					   enum ib_qp_type qp_type,
+					   int mad_snoop_flags,
+					   ib_mad_snoop_handler snoop_handler,
+					   ib_mad_recv_handler recv_handler,
+					   void *context)
+{
+	struct ib_mad_port_private *port_priv;
+	struct ib_mad_agent *ret;
+	struct ib_mad_snoop_private *mad_snoop_priv;
+	int qpn;
+
+	/* Validate parameters */
+	if ((is_snooping_sends(mad_snoop_flags) && !snoop_handler) ||
+	    (is_snooping_recvs(mad_snoop_flags) && !recv_handler)) {
+		ret = ERR_PTR(-EINVAL);
+		goto error1;
+	}
+	qpn = get_spl_qp_index(qp_type);
+	if (qpn == -1) {
+		ret = ERR_PTR(-EINVAL);
+		goto error1;
+	}
+	port_priv = ib_get_mad_port(device, port_num);
+	if (!port_priv) {
+		ret = ERR_PTR(-ENODEV);
+		goto error1;
+	}
+	/* Allocate structures */
+	mad_snoop_priv = kmalloc(sizeof *mad_snoop_priv, GFP_KERNEL);
+	if (!mad_snoop_priv) {
+		ret = ERR_PTR(-ENOMEM);
+		goto error1;
+	}
+
+	/* Now, fill in the various structures */
+	memset(mad_snoop_priv, 0, sizeof *mad_snoop_priv);
+	mad_snoop_priv->qp_info = &port_priv->qp_info[qpn];
+	mad_snoop_priv->agent.device = device;
+	mad_snoop_priv->agent.recv_handler = recv_handler;
+	mad_snoop_priv->agent.snoop_handler = snoop_handler;
+	mad_snoop_priv->agent.context = context;
+	mad_snoop_priv->agent.qp = port_priv->qp_info[qpn].qp;
+	mad_snoop_priv->agent.port_num = port_num;
+	mad_snoop_priv->mad_snoop_flags = mad_snoop_flags;
+	init_waitqueue_head(&mad_snoop_priv->wait);
+	mad_snoop_priv->snoop_index = register_snoop_agent(
+						&port_priv->qp_info[qpn],
+						mad_snoop_priv);
+	if (mad_snoop_priv->snoop_index < 0) {
+		ret = ERR_PTR(mad_snoop_priv->snoop_index);
+		goto error2;
+	}
+
+	atomic_set(&mad_snoop_priv->refcount, 1);
+	return &mad_snoop_priv->agent;
+
+error2:
+	kfree(mad_snoop_priv);
+error1:
+	return ret;
+}
+EXPORT_SYMBOL(ib_register_mad_snoop);
+
+static void unregister_mad_agent(struct ib_mad_agent_private *mad_agent_priv)
+{
+	struct ib_mad_port_private *port_priv;
+	unsigned long flags;
+
+	/* Note that we could still be handling received MADs */
+
+	/*
+	 * Canceling all sends results in dropping received response
+	 * 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 */
+
+	atomic_dec(&mad_agent_priv->refcount);
+	wait_event(mad_agent_priv->wait,
+		   !atomic_read(&mad_agent_priv->refcount));
+
+	if (mad_agent_priv->reg_req)
+		kfree(mad_agent_priv->reg_req);
+	kfree(mad_agent_priv);
+}
+
+static void unregister_mad_snoop(struct ib_mad_snoop_private *mad_snoop_priv)
+{
+	struct ib_mad_qp_info *qp_info;
+	unsigned long flags;
+
+	qp_info = mad_snoop_priv->qp_info;
+	spin_lock_irqsave(&qp_info->snoop_lock, flags);
+	qp_info->snoop_table[mad_snoop_priv->snoop_index] = NULL;
+	atomic_dec(&qp_info->snoop_count);
+	spin_unlock_irqrestore(&qp_info->snoop_lock, flags);
+
+	atomic_dec(&mad_snoop_priv->refcount);
+	wait_event(mad_snoop_priv->wait,
+		   !atomic_read(&mad_snoop_priv->refcount));
+
+	kfree(mad_snoop_priv);
+}
+
+/*
+ * ib_unregister_mad_agent - Unregisters a client from using MAD services
+ */
+int ib_unregister_mad_agent(struct ib_mad_agent *mad_agent)
+{
+	struct ib_mad_agent_private *mad_agent_priv;
+	struct ib_mad_snoop_private *mad_snoop_priv;
+
+	/* If the TID is zero, the agent can only snoop. */
+	if (mad_agent->hi_tid) {
+		mad_agent_priv = container_of(mad_agent,
+					      struct ib_mad_agent_private,
+					      agent);
+		unregister_mad_agent(mad_agent_priv);
+	} else {
+		mad_snoop_priv = container_of(mad_agent,
+					      struct ib_mad_snoop_private,
+					      agent);
+		unregister_mad_snoop(mad_snoop_priv);
+	}
+	return 0;
+}
+EXPORT_SYMBOL(ib_unregister_mad_agent);
+
+static void dequeue_mad(struct ib_mad_list_head *mad_list)
+{
+	struct ib_mad_queue *mad_queue;
+	unsigned long flags;
+
+	BUG_ON(!mad_list->mad_queue);
+	mad_queue = mad_list->mad_queue;
+	spin_lock_irqsave(&mad_queue->lock, flags);
+	list_del(&mad_list->list);
+	mad_queue->count--;
+	spin_unlock_irqrestore(&mad_queue->lock, flags);
+}
+
+static void snoop_send(struct ib_mad_qp_info *qp_info,
+		       struct ib_send_wr *send_wr,
+		       struct ib_mad_send_wc *mad_send_wc,
+		       int mad_snoop_flags)
+{
+	struct ib_mad_snoop_private *mad_snoop_priv;
+	unsigned long flags;
+	int i;
+
+	spin_lock_irqsave(&qp_info->snoop_lock, flags);
+	for (i = 0; i < qp_info->snoop_table_size; i++) {
+		mad_snoop_priv = qp_info->snoop_table[i];
+		if (!mad_snoop_priv ||
+		    !(mad_snoop_priv->mad_snoop_flags & mad_snoop_flags))
+			continue;
+
+		atomic_inc(&mad_snoop_priv->refcount);
+		spin_unlock_irqrestore(&qp_info->snoop_lock, flags);
+		mad_snoop_priv->agent.snoop_handler(&mad_snoop_priv->agent,
+						    send_wr, mad_send_wc);
+		if (atomic_dec_and_test(&mad_snoop_priv->refcount))
+			wake_up(&mad_snoop_priv->wait);
+		spin_lock_irqsave(&qp_info->snoop_lock, flags);
+	}
+	spin_unlock_irqrestore(&qp_info->snoop_lock, flags);
+}
+
+static void snoop_recv(struct ib_mad_qp_info *qp_info,
+		       struct ib_mad_recv_wc *mad_recv_wc,
+		       int mad_snoop_flags)
+{
+	struct ib_mad_snoop_private *mad_snoop_priv;
+	unsigned long flags;
+	int i;
+
+	spin_lock_irqsave(&qp_info->snoop_lock, flags);
+	for (i = 0; i < qp_info->snoop_table_size; i++) {
+		mad_snoop_priv = qp_info->snoop_table[i];
+		if (!mad_snoop_priv ||
+		    !(mad_snoop_priv->mad_snoop_flags & mad_snoop_flags))
+			continue;
+
+		atomic_inc(&mad_snoop_priv->refcount);
+		spin_unlock_irqrestore(&qp_info->snoop_lock, flags);
+		mad_snoop_priv->agent.recv_handler(&mad_snoop_priv->agent,
+						   mad_recv_wc);
+		if (atomic_dec_and_test(&mad_snoop_priv->refcount))
+			wake_up(&mad_snoop_priv->wait);
+		spin_lock_irqsave(&qp_info->snoop_lock, flags);
+	}
+	spin_unlock_irqrestore(&qp_info->snoop_lock, flags);
+}
+
+static void build_smp_wc(u64 wr_id, u16 slid, u16 pkey_index, u8 port_num,
+			 struct ib_wc *wc)
+{
+	memset(wc, 0, sizeof *wc);
+	wc->wr_id = wr_id;
+	wc->status = IB_WC_SUCCESS;
+	wc->opcode = IB_WC_RECV;
+	wc->pkey_index = pkey_index;
+	wc->byte_len = sizeof(struct ib_mad) + sizeof(struct ib_grh);
+	wc->src_qp = IB_QP0;
+	wc->qp_num = IB_QP0;
+	wc->slid = slid;
+	wc->sl = 0;
+	wc->dlid_path_bits = 0;
+	wc->port_num = port_num;
+}
+
+/*
+ * Return 0 if SMP is to be sent
+ * Return 1 if SMP was consumed locally (whether or not solicited)
+ * Return < 0 if error
+ */
+static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv,
+				  struct ib_smp *smp,
+				  struct ib_send_wr *send_wr)
+{
+	int ret, alloc_flags, solicited;
+	unsigned long flags;
+	struct ib_mad_local_private *local;
+	struct ib_mad_private *mad_priv;
+	struct ib_mad_port_private *port_priv;
+	struct ib_mad_agent_private *recv_mad_agent = NULL;
+	struct ib_device *device = mad_agent_priv->agent.device;
+	u8 port_num = mad_agent_priv->agent.port_num;
+	struct ib_wc mad_wc;
+
+	if (!smi_handle_dr_smp_send(smp, device->node_type, port_num)) {
+		ret = -EINVAL;
+		printk(KERN_ERR PFX "Invalid directed route\n");
+		goto out;
+	}
+	/* Check to post send on QP or process locally */
+	ret = smi_check_local_dr_smp(smp, device, port_num);
+	if (!ret || !device->process_mad)
+		goto out;
+
+	if (in_atomic() || irqs_disabled())
+		alloc_flags = GFP_ATOMIC;
+	else
+		alloc_flags = GFP_KERNEL;
+	local = kmalloc(sizeof *local, alloc_flags);
+	if (!local) {
+		ret = -ENOMEM;
+		printk(KERN_ERR PFX "No memory for ib_mad_local_private\n");
+		goto out;
+	}
+	local->mad_priv = NULL;
+	local->recv_mad_agent = NULL;
+	mad_priv = kmem_cache_alloc(ib_mad_cache, alloc_flags);
+	if (!mad_priv) {
+		ret = -ENOMEM;
+		printk(KERN_ERR PFX "No memory for local response MAD\n");
+		kfree(local);
+		goto out;
+	}
+
+	build_smp_wc(send_wr->wr_id, smp->dr_slid, send_wr->wr.ud.pkey_index,
+		     send_wr->wr.ud.port_num, &mad_wc);
+
+	/* No GRH for DR SMP */
+	ret = device->process_mad(device, 0, port_num, &mad_wc, NULL,
+				  (struct ib_mad *)smp,
+				  (struct ib_mad *)&mad_priv->mad);
+	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) &&
+		    mad_agent_priv->agent.recv_handler) {
+			local->mad_priv = mad_priv;
+			local->recv_mad_agent = mad_agent_priv;
+			/*
+			 * Reference MAD agent until receive
+			 * side of local completion handled
+			 */
+			atomic_inc(&mad_agent_priv->refcount);
+		} else
+			kmem_cache_free(ib_mad_cache, mad_priv);
+		break;
+	case IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_CONSUMED:
+		kmem_cache_free(ib_mad_cache, mad_priv);
+		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);
+		}
+		if (!port_priv || !recv_mad_agent) {
+			kmem_cache_free(ib_mad_cache, mad_priv);
+			kfree(local);
+			ret = 0;
+			goto out;
+		}
+		local->mad_priv = mad_priv;
+		local->recv_mad_agent = recv_mad_agent;
+		break;
+	default:
+		kmem_cache_free(ib_mad_cache, mad_priv);
+		kfree(local);
+		ret = -EINVAL;
+		goto out;
+	}
+
+	local->send_wr = *send_wr;
+	local->send_wr.sg_list = local->sg_list;
+	memcpy(local->sg_list, send_wr->sg_list,
+	       sizeof *send_wr->sg_list * send_wr->num_sge);
+	local->send_wr.next = NULL;
+	local->tid = send_wr->wr.ud.mad_hdr->tid;
+	local->wr_id = send_wr->wr_id;
+	/* Reference MAD agent until send side of local completion handled */
+	atomic_inc(&mad_agent_priv->refcount);
+	/* Queue local completion to local list */
+	spin_lock_irqsave(&mad_agent_priv->lock, flags);
+	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);
+	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)
+{
+	struct ib_mad_qp_info *qp_info;
+	struct ib_send_wr *bad_send_wr;
+	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;
+	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,
+				   &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);
+		}
+	} 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;
+	}
+	return ret;
+}
+
+/*
+ * ib_post_send_mad - Posts MAD(s) to the send queue of the QP associated
+ *  with the registered client
+ */
+int ib_post_send_mad(struct ib_mad_agent *mad_agent,
+		     struct ib_send_wr *send_wr,
+		     struct ib_send_wr **bad_send_wr)
+{
+	int ret = -EINVAL;
+	struct ib_mad_agent_private *mad_agent_priv;
+
+	/* Validate supplied parameters */
+	if (!bad_send_wr)
+		goto error1;
+
+	if (!mad_agent || !send_wr)
+		goto error2;
+
+	if (!mad_agent->send_handler)
+		goto error2;
+
+	mad_agent_priv = container_of(mad_agent,
+				      struct ib_mad_agent_private,
+				      agent);
+
+	/* Walk list of send WRs and post each on send list */
+	while (send_wr) {
+		unsigned long			flags;
+		struct ib_send_wr		*next_send_wr;
+		struct ib_mad_send_wr_private	*mad_send_wr;
+		struct ib_smp			*smp;
+
+		/* Validate more parameters */
+		if (send_wr->num_sge > IB_MAD_SEND_REQ_MAX_SG)
+			goto error2;
+
+		if (send_wr->wr.ud.timeout_ms && !mad_agent->recv_handler)
+			goto error2;
+
+		if (!send_wr->wr.ud.mad_hdr) {
+			printk(KERN_ERR PFX "MAD header must be supplied "
+			       "in WR %p\n", send_wr);
+			goto error2;
+		}
+
+		/*
+		 * Save pointer to next work request to post in case the
+		 * current one completes, and the user modifies the work
+		 * request associated with the completion
+		 */
+		next_send_wr = (struct ib_send_wr *)send_wr->next;
+
+		smp = (struct ib_smp *)send_wr->wr.ud.mad_hdr;
+		if (smp->mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) {
+			ret = handle_outgoing_dr_smp(mad_agent_priv, smp,
+						     send_wr);
+			if (ret < 0)		/* error */
+				goto error2;
+			else if (ret == 1)	/* locally consumed */
+				goto next;
+		}
+
+		/* Allocate MAD send WR tracking structure */
+		mad_send_wr = kmalloc(sizeof *mad_send_wr,
+				      (in_atomic() || irqs_disabled()) ?
+				      GFP_ATOMIC : GFP_KERNEL);
+		if (!mad_send_wr) {
+			printk(KERN_ERR PFX "No memory for "
+			       "ib_mad_send_wr_private\n");
+			ret = -ENOMEM;
+			goto error2;
+		}
+
+		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->tid = send_wr->wr.ud.mad_hdr->tid;
+		mad_send_wr->agent = mad_agent;
+		/* 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;
+		/* 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;
+
+		/* Reference MAD agent until send completes */
+		atomic_inc(&mad_agent_priv->refcount);
+		spin_lock_irqsave(&mad_agent_priv->lock, flags);
+		list_add_tail(&mad_send_wr->agent_list,
+			      &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) {
+			/* Fail send request */
+			spin_lock_irqsave(&mad_agent_priv->lock, flags);
+			list_del(&mad_send_wr->agent_list);
+			spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
+			atomic_dec(&mad_agent_priv->refcount);
+			goto error2;
+		}
+next:
+		send_wr = next_send_wr;
+	}
+	return 0;
+
+error2:
+	*bad_send_wr = send_wr;
+error1:
+	return ret;
+}
+EXPORT_SYMBOL(ib_post_send_mad);
+
+/*
+ * ib_free_recv_mad - Returns data buffers used to receive
+ *  a MAD to the access layer
+ */
+void ib_free_recv_mad(struct ib_mad_recv_wc *mad_recv_wc)
+{
+	struct ib_mad_recv_buf *entry;
+	struct ib_mad_private_header *mad_priv_hdr;
+	struct ib_mad_private *priv;
+
+	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);
+
+	/*
+	 * 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);
+		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);
+	}
+
+	/* 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,
+					ib_mad_recv_handler recv_handler,
+					void *context)
+{
+	return ERR_PTR(-EINVAL);	/* XXX: for now */
+}
+EXPORT_SYMBOL(ib_redirect_mad_qp);
+
+int ib_process_mad_wc(struct ib_mad_agent *mad_agent,
+		      struct ib_wc *wc)
+{
+	printk(KERN_ERR PFX "ib_process_mad_wc() not implemented yet\n");
+	return 0;
+}
+EXPORT_SYMBOL(ib_process_mad_wc);
+
+static int method_in_use(struct ib_mad_mgmt_method_table **method,
+			 struct ib_mad_reg_req *mad_reg_req)
+{
+	int i;
+
+	for (i = find_first_bit(mad_reg_req->method_mask, IB_MGMT_MAX_METHODS);
+	     i < IB_MGMT_MAX_METHODS;
+	     i = find_next_bit(mad_reg_req->method_mask, IB_MGMT_MAX_METHODS,
+			       1+i)) {
+		if ((*method)->agent[i]) {
+			printk(KERN_ERR PFX "Method %d already in use\n", i);
+			return -EINVAL;
+		}
+	}
+	return 0;
+}
+
+static int allocate_method_table(struct ib_mad_mgmt_method_table **method)
+{
+	/* Allocate management method table */
+	*method = kmalloc(sizeof **method, GFP_ATOMIC);
+	if (!*method) {
+		printk(KERN_ERR PFX "No memory for "
+		       "ib_mad_mgmt_method_table\n");
+		return -ENOMEM;
+	}
+	/* Clear management method table */
+	memset(*method, 0, sizeof **method);
+
+	return 0;
+}
+
+/*
+ * Check to see if there are any methods still in use
+ */
+static int check_method_table(struct ib_mad_mgmt_method_table *method)
+{
+	int i;
+
+	for (i = 0; i < IB_MGMT_MAX_METHODS; i++)
+		if (method->agent[i])
+			return 1;
+	return 0;
+}
+
+/*
+ * Check to see if there are any method tables for this class still in use
+ */
+static int check_class_table(struct ib_mad_mgmt_class_table *class)
+{
+	int i;
+
+	for (i = 0; i < MAX_MGMT_CLASS; i++)
+		if (class->method_table[i])
+			return 1;
+	return 0;
+}
+
+static int check_vendor_class(struct ib_mad_mgmt_vendor_class *vendor_class)
+{
+	int i;
+
+	for (i = 0; i < MAX_MGMT_OUI; i++)
+		if (vendor_class->method_table[i])
+			return 1;
+	return 0;
+}
+
+static int find_vendor_oui(struct ib_mad_mgmt_vendor_class *vendor_class,
+			   char *oui)
+{
+	int i;
+
+	for (i = 0; i < MAX_MGMT_OUI; i++)
+                /* Is there matching OUI for this vendor class ? */
+                if (!memcmp(vendor_class->oui[i], oui, 3))
+			return i;
+
+	return -1;
+}
+
+static int check_vendor_table(struct ib_mad_mgmt_vendor_class_table *vendor)
+{
+	int i;
+
+	for (i = 0; i < MAX_MGMT_VENDOR_RANGE2; i++)
+		if (vendor->vendor_class[i])
+			return 1;
+
+	return 0;
+}
+
+static void remove_methods_mad_agent(struct ib_mad_mgmt_method_table *method,
+				     struct ib_mad_agent_private *agent)
+{
+	int i;
+
+	/* Remove any methods for this mad agent */
+	for (i = 0; i < IB_MGMT_MAX_METHODS; i++) {
+		if (method->agent[i] == agent) {
+			method->agent[i] = NULL;
+		}
+	}
+}
+
+static int add_nonoui_reg_req(struct ib_mad_reg_req *mad_reg_req,
+			      struct ib_mad_agent_private *agent_priv,
+			      u8 mgmt_class)
+{
+	struct ib_mad_port_private *port_priv;
+	struct ib_mad_mgmt_class_table **class;
+	struct ib_mad_mgmt_method_table **method;
+	int i, ret;
+
+	port_priv = agent_priv->qp_info->port_priv;
+	class = &port_priv->version[mad_reg_req->mgmt_class_version].class;
+	if (!*class) {
+		/* Allocate management class table for "new" class version */
+		*class = kmalloc(sizeof **class, GFP_ATOMIC);
+		if (!*class) {
+			printk(KERN_ERR PFX "No memory for "
+			       "ib_mad_mgmt_class_table\n");
+			ret = -ENOMEM;
+			goto error1;
+		}
+		/* Clear management class table */
+		memset(*class, 0, sizeof(**class));
+		/* Allocate method table for this management class */
+		method = &(*class)->method_table[mgmt_class];
+		if ((ret = allocate_method_table(method)))
+			goto error2;
+	} else {
+		method = &(*class)->method_table[mgmt_class];
+		if (!*method) {
+			/* Allocate method table for this management class */
+			if ((ret = allocate_method_table(method)))
+				goto error1;
+		}
+	}
+
+	/* Now, make sure methods are not already in use */
+	if (method_in_use(method, mad_reg_req))
+		goto error3;
+
+	/* Finally, add in methods being registered */
+	for (i = find_first_bit(mad_reg_req->method_mask,
+				IB_MGMT_MAX_METHODS);
+	     i < IB_MGMT_MAX_METHODS;
+	     i = find_next_bit(mad_reg_req->method_mask, IB_MGMT_MAX_METHODS,
+			       1+i)) {
+		(*method)->agent[i] = agent_priv;
+	}
+	return 0;
+
+error3:
+	/* Remove any methods for this mad agent */
+	remove_methods_mad_agent(*method, agent_priv);
+	/* Now, check to see if there are any methods in use */
+	if (!check_method_table(*method)) {
+		/* If not, release management method table */
+		kfree(*method);
+		*method = NULL;
+	}
+	ret = -EINVAL;
+	goto error1;
+error2:
+	kfree(*class);
+	*class = NULL;
+error1:
+	return ret;
+}
+
+static int add_oui_reg_req(struct ib_mad_reg_req *mad_reg_req,
+			   struct ib_mad_agent_private *agent_priv)
+{
+	struct ib_mad_port_private *port_priv;
+	struct ib_mad_mgmt_vendor_class_table **vendor_table;
+	struct ib_mad_mgmt_vendor_class_table *vendor = NULL;
+	struct ib_mad_mgmt_vendor_class *vendor_class = NULL;
+	struct ib_mad_mgmt_method_table **method;
+	int i, ret = -ENOMEM;
+	u8 vclass;
+
+	/* "New" vendor (with OUI) class */
+	vclass = vendor_class_index(mad_reg_req->mgmt_class);
+	port_priv = agent_priv->qp_info->port_priv;
+	vendor_table = &port_priv->version[
+				mad_reg_req->mgmt_class_version].vendor;
+	if (!*vendor_table) {
+		/* Allocate mgmt vendor class table for "new" class version */
+		vendor = kmalloc(sizeof *vendor, GFP_ATOMIC);
+		if (!vendor) {
+			printk(KERN_ERR PFX "No memory for "
+			       "ib_mad_mgmt_vendor_class_table\n");
+			goto error1;
+		}
+		/* Clear management vendor class table */
+		memset(vendor, 0, sizeof(*vendor));
+		*vendor_table = vendor;
+	}
+	if (!(*vendor_table)->vendor_class[vclass]) {
+		/* Allocate table for this management vendor class */
+		vendor_class = kmalloc(sizeof *vendor_class, GFP_ATOMIC);
+		if (!vendor_class) {
+			printk(KERN_ERR PFX "No memory for "
+			       "ib_mad_mgmt_vendor_class\n");
+			goto error2;
+		}
+		memset(vendor_class, 0, sizeof(*vendor_class));
+		(*vendor_table)->vendor_class[vclass] = vendor_class;
+	}
+	for (i = 0; i < MAX_MGMT_OUI; i++) {
+		/* Is there matching OUI for this vendor class ? */
+		if (!memcmp((*vendor_table)->vendor_class[vclass]->oui[i],
+			    mad_reg_req->oui, 3)) {
+			method = &(*vendor_table)->vendor_class[
+						vclass]->method_table[i];
+			BUG_ON(!*method);
+			goto check_in_use;
+		}
+	}
+	for (i = 0; i < MAX_MGMT_OUI; i++) {
+		/* OUI slot available ? */
+		if (!is_vendor_oui((*vendor_table)->vendor_class[
+				vclass]->oui[i])) {
+			method = &(*vendor_table)->vendor_class[
+				vclass]->method_table[i];
+			BUG_ON(*method);
+			/* Allocate method table for this OUI */
+			if ((ret = allocate_method_table(method)))
+				goto error3;
+			memcpy((*vendor_table)->vendor_class[vclass]->oui[i],
+			       mad_reg_req->oui, 3);
+			goto check_in_use;
+		}
+	}
+	printk(KERN_ERR PFX "All OUI slots in use\n");
+	goto error3;
+
+check_in_use:
+	/* Now, make sure methods are not already in use */
+	if (method_in_use(method, mad_reg_req))
+		goto error4;
+
+	/* Finally, add in methods being registered */
+	for (i = find_first_bit(mad_reg_req->method_mask,
+				IB_MGMT_MAX_METHODS);
+	     i < IB_MGMT_MAX_METHODS;
+	     i = find_next_bit(mad_reg_req->method_mask, IB_MGMT_MAX_METHODS,
+			       1+i)) {
+		(*method)->agent[i] = agent_priv;
+	}
+	return 0;
+
+error4:
+	/* Remove any methods for this mad agent */
+	remove_methods_mad_agent(*method, agent_priv);
+	/* Now, check to see if there are any methods in use */
+	if (!check_method_table(*method)) {
+		/* If not, release management method table */
+		kfree(*method);
+		*method = NULL;
+	}
+	ret = -EINVAL;
+error3:
+	if (vendor_class) {
+		(*vendor_table)->vendor_class[vclass] = NULL;
+		kfree(vendor_class);
+	}
+error2:
+	if (vendor) {
+		*vendor_table = NULL;
+		kfree(vendor);
+	}
+error1:
+	return ret;
+}
+
+static void remove_mad_reg_req(struct ib_mad_agent_private *agent_priv)
+{
+	struct ib_mad_port_private *port_priv;
+	struct ib_mad_mgmt_class_table *class;
+	struct ib_mad_mgmt_method_table *method;
+	struct ib_mad_mgmt_vendor_class_table *vendor;
+	struct ib_mad_mgmt_vendor_class *vendor_class;
+	int index;
+	u8 mgmt_class;
+
+	/*
+	 * Was MAD registration request supplied
+	 * with original registration ?
+	 */
+	if (!agent_priv->reg_req) {
+		goto out;
+	}
+
+	port_priv = agent_priv->qp_info->port_priv;
+	class = port_priv->version[
+			agent_priv->reg_req->mgmt_class_version].class;
+	if (!class)
+		goto vendor_check;
+
+	mgmt_class = convert_mgmt_class(agent_priv->reg_req->mgmt_class);
+	method = class->method_table[mgmt_class];
+	if (method) {
+		/* Remove any methods for this mad agent */
+		remove_methods_mad_agent(method, agent_priv);
+		/* Now, check to see if there are any methods still in use */
+		if (!check_method_table(method)) {
+			/* If not, release management method table */
+			 kfree(method);
+			 class->method_table[mgmt_class] = NULL;
+			 /* Any management classes left ? */
+			if (!check_class_table(class)) {
+				/* If not, release management class table */
+				kfree(class);
+				port_priv->version[
+					agent_priv->reg_req->
+					mgmt_class_version].class = NULL;
+			}
+		}
+	}
+
+vendor_check:
+	vendor = port_priv->version[
+			agent_priv->reg_req->mgmt_class_version].vendor;
+	if (!vendor)
+		goto out;
+
+	mgmt_class = vendor_class_index(agent_priv->reg_req->mgmt_class);
+	vendor_class = vendor->vendor_class[mgmt_class];
+	if (vendor_class) {
+		index = find_vendor_oui(vendor_class, agent_priv->reg_req->oui);
+		if (index == -1)
+			goto out;
+		method = vendor_class->method_table[index];
+		if (method) {
+			/* Remove any methods for this mad agent */
+			remove_methods_mad_agent(method, agent_priv);
+			/*
+			 * Now, check to see if there are
+			 * any methods still in use
+			 */
+			if (!check_method_table(method)) {
+				/* If not, release management method table */
+				kfree(method);
+				vendor_class->method_table[index] = NULL;
+				memset(vendor_class->oui[index], 0, 3);
+				/* Any OUIs left ? */
+				if (!check_vendor_class(vendor_class)) {
+					/* If not, release vendor class table */
+					kfree(vendor_class);
+					vendor->vendor_class[mgmt_class] = NULL;
+					/* Any other vendor classes left ? */
+					if (!check_vendor_table(vendor)) {
+						kfree(vendor);
+						port_priv->version[
+							agent_priv->reg_req->
+							mgmt_class_version].
+							vendor = NULL;
+					}
+				}
+			}
+		}
+	}
+
+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_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) {
+		u32 hi_tid;
+		struct ib_mad_agent_private *entry;
+
+		/*
+		 * Routing is based on high 32 bits of transaction ID
+		 * of MAD.
+		 */
+		hi_tid = be64_to_cpu(mad->mad_hdr.tid) >> 32;
+		list_for_each_entry(entry, &port_priv->agent_list,
+				    agent_list) {
+			if (entry->agent.hi_tid == hi_tid) {
+				mad_agent = entry;
+				break;
+			}
+		}
+	} else {
+		struct ib_mad_mgmt_class_table *class;
+		struct ib_mad_mgmt_method_table *method;
+		struct ib_mad_mgmt_vendor_class_table *vendor;
+		struct ib_mad_mgmt_vendor_class *vendor_class;
+		struct ib_vendor_mad *vendor_mad;
+		int index;
+
+		/*
+		 * Routing is based on version, class, and method
+		 * For "newer" vendor MADs, also based on OUI
+		 */
+		if (mad->mad_hdr.class_version >= MAX_MGMT_VERSION)
+			goto out;
+		if (!is_vendor_class(mad->mad_hdr.mgmt_class)) {
+			class = port_priv->version[
+					mad->mad_hdr.class_version].class;
+			if (!class)
+				goto out;
+			method = class->method_table[convert_mgmt_class(
+							mad->mad_hdr.mgmt_class)];
+			if (method)
+				mad_agent = method->agent[mad->mad_hdr.method &
+							  ~IB_MGMT_METHOD_RESP];
+		} else {
+			vendor = port_priv->version[
+					mad->mad_hdr.class_version].vendor;
+			if (!vendor)
+				goto out;
+			vendor_class = vendor->vendor_class[vendor_class_index(
+						mad->mad_hdr.mgmt_class)];
+			if (!vendor_class)
+				goto out;
+			/* Find matching OUI */
+			vendor_mad = (struct ib_vendor_mad *)mad;
+			index = find_vendor_oui(vendor_class, vendor_mad->oui);
+			if (index == -1)
+				goto out;
+			method = vendor_class->method_table[index];
+			if (method) {
+				mad_agent = method->agent[mad->mad_hdr.method &
+							  ~IB_MGMT_METHOD_RESP];
+			}
+		}
+	}
+
+	if (mad_agent) {
+		if (mad_agent->agent.recv_handler)
+			atomic_inc(&mad_agent->refcount);
+		else {
+			printk(KERN_NOTICE PFX "No receive handler for client "
+			       "%p on port %d\n",
+			       &mad_agent->agent, port_priv->port_num);
+			mad_agent = NULL;
+		}
+	}
+out:
+	spin_unlock_irqrestore(&port_priv->reg_lock, flags);
+
+	return mad_agent;
+}
+
+static int validate_mad(struct ib_mad *mad, u32 qp_num)
+{
+	int valid = 0;
+
+	/* Make sure MAD base version is understood */
+	if (mad->mad_hdr.base_version != IB_MGMT_BASE_VERSION) {
+		printk(KERN_ERR PFX "MAD received with unsupported base "
+		       "version %d\n", mad->mad_hdr.base_version);
+		goto out;
+	}
+
+	/* Filter SMI packets sent to other than QP0 */
+	if ((mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_LID_ROUTED) ||
+	    (mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE)) {
+		if (qp_num == 0)
+			valid = 1;
+	} else {
+		/* Filter GSI packets sent to QP0 */
+		if (qp_num != 0)
+			valid = 1;
+	}
+
+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 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 *mad_send_wr;
+
+	list_for_each_entry(mad_send_wr, &mad_agent_priv->wait_list,
+			    agent_list) {
+		if (mad_send_wr->tid == tid)
+			return mad_send_wr;
+	}
+
+	/*
+	 * It's possible to receive the response before we've
+	 * been notified that the send has completed
+	 */
+	list_for_each_entry(mad_send_wr, &mad_agent_priv->send_list,
+			    agent_list) {
+		if (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;
+		}
+	}
+	return NULL;
+}
+
+static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv,
+				 struct ib_mad_private *recv,
+				 int solicited)
+{
+	struct ib_mad_send_wr_private *mad_send_wr;
+	struct ib_mad_send_wc mad_send_wc;
+	unsigned long flags;
+
+	/* 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;
+	}
+
+	/* Complete corresponding request */
+	if (solicited) {
+		spin_lock_irqsave(&mad_agent_priv->lock, flags);
+		mad_send_wr = find_send_req(mad_agent_priv,
+					    recv->mad.mad.mad_hdr.tid);
+		if (!mad_send_wr) {
+			spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
+			ib_free_recv_mad(&recv->header.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;
+		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);
+		atomic_dec(&mad_agent_priv->refcount);
+
+		mad_send_wc.status = IB_WC_SUCCESS;
+		mad_send_wc.vendor_err = 0;
+		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);
+		if (atomic_dec_and_test(&mad_agent_priv->refcount))
+			wake_up(&mad_agent_priv->wait);
+	}
+}
+
+static void ib_mad_recv_done_handler(struct ib_mad_port_private *port_priv,
+				     struct ib_wc *wc)
+{
+	struct ib_mad_qp_info *qp_info;
+	struct ib_mad_private_header *mad_priv_hdr;
+	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)
+		printk(KERN_ERR PFX "ib_mad_recv_done_handler no memory "
+		       "for response buffer\n");
+
+	mad_list = (struct ib_mad_list_head *)(unsigned long)wc->wr_id;
+	qp_info = mad_list->mad_queue->qp_info;
+	dequeue_mad(mad_list);
+
+	mad_priv_hdr = container_of(mad_list, struct ib_mad_private_header,
+				    mad_list);
+	recv = container_of(mad_priv_hdr, struct ib_mad_private, header);
+	dma_unmap_single(port_priv->device->dma_device,
+			 pci_unmap_addr(&recv->header, mapping),
+			 sizeof(struct ib_mad_private) -
+			 sizeof(struct ib_mad_private_header),
+			 DMA_FROM_DEVICE);
+
+	/* Setup MAD receive work completion from "normal" work completion */
+	recv->header.recv_wc.wc = wc;
+	recv->header.recv_wc.mad_len = sizeof(struct ib_mad);
+	recv->header.recv_wc.recv_buf.mad = &recv->mad.mad;
+	recv->header.recv_wc.recv_buf.grh = &recv->grh;
+
+	if (atomic_read(&qp_info->snoop_count))
+		snoop_recv(qp_info, &recv->header.recv_wc, IB_MAD_SNOOP_RECVS);
+
+	/* Validate MAD */
+	if (!validate_mad(&recv->mad.mad, qp_info->qp->qp_num))
+		goto out;
+
+	if (recv->mad.mad.mad_hdr.mgmt_class ==
+	    IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) {
+		if (!smi_handle_dr_smp_recv(&recv->mad.smp,
+					    port_priv->device->node_type,
+					    port_priv->port_num,
+					    port_priv->device->phys_port_cnt))
+			goto out;
+		if (!smi_check_forward_dr_smp(&recv->mad.smp))
+			goto local;
+		if (!smi_handle_dr_smp_send(&recv->mad.smp,
+					    port_priv->device->node_type,
+					    port_priv->port_num))
+			goto out;
+		if (!smi_check_local_dr_smp(&recv->mad.smp,
+					    port_priv->device,
+					    port_priv->port_num))
+			goto out;
+	}
+
+local:
+	/* Give driver "right of first refusal" on incoming MAD */
+	if (port_priv->device->process_mad) {
+		int ret;
+
+		if (!response) {
+			printk(KERN_ERR PFX "No memory for response MAD\n");
+			/*
+			 * Is it better to assume that
+			 * it wouldn't be processed ?
+			 */
+			goto out;
+		}
+
+		ret = port_priv->device->process_mad(port_priv->device, 0,
+						     port_priv->port_num,
+						     wc, &recv->grh,
+						     &recv->mad.mad,
+						     &response->mad.mad);
+		if (ret & IB_MAD_RESULT_SUCCESS) {
+			if (ret & IB_MAD_RESULT_CONSUMED)
+				goto out;
+			if (ret & IB_MAD_RESULT_REPLY) {
+				/* Send response */
+				if (!agent_send(response, &recv->grh, wc,
+						port_priv->device,
+						port_priv->port_num))
+					response = NULL;
+				goto out;
+			}
+		}
+	}
+
+	/* 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);
+	if (mad_agent) {
+		ib_mad_complete_recv(mad_agent, recv, solicited);
+		/*
+		 * recv is freed up in error cases in ib_mad_complete_recv
+		 * or via recv_handler in ib_mad_complete_recv()
+		 */
+		recv = NULL;
+	}
+
+out:
+	/* Post another receive request for this QP */
+	if (response) {
+		ib_mad_post_receive_mads(qp_info, response);
+		if (recv)
+			kmem_cache_free(ib_mad_cache, recv);
+	} else
+		ib_mad_post_receive_mads(qp_info, recv);
+}
+
+static void adjust_timeout(struct ib_mad_agent_private *mad_agent_priv)
+{
+	struct ib_mad_send_wr_private *mad_send_wr;
+	unsigned long delay;
+
+	if (list_empty(&mad_agent_priv->wait_list)) {
+		cancel_delayed_work(&mad_agent_priv->timed_work);
+	} else {
+		mad_send_wr = list_entry(mad_agent_priv->wait_list.next,
+					 struct ib_mad_send_wr_private,
+					 agent_list);
+
+		if (time_after(mad_agent_priv->timeout,
+			       mad_send_wr->timeout)) {
+			mad_agent_priv->timeout = mad_send_wr->timeout;
+			cancel_delayed_work(&mad_agent_priv->timed_work);
+			delay = mad_send_wr->timeout - jiffies;
+			if ((long)delay <= 0)
+				delay = 1;
+			queue_delayed_work(mad_agent_priv->qp_info->
+					   port_priv->wq,
+					   &mad_agent_priv->timed_work, delay);
+		}
+	}
+}
+
+static void wait_for_response(struct ib_mad_agent_private *mad_agent_priv,
+			      struct ib_mad_send_wr_private *mad_send_wr )
+{
+	struct ib_mad_send_wr_private *temp_mad_send_wr;
+	struct list_head *list_item;
+	unsigned long delay;
+
+	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;
+	}
+	list_add(&mad_send_wr->agent_list, list_item);
+
+	/* Reschedule a work item if we have a shorter timeout */
+	if (mad_agent_priv->wait_list.next == &mad_send_wr->agent_list) {
+		cancel_delayed_work(&mad_agent_priv->timed_work);
+		queue_delayed_work(mad_agent_priv->qp_info->port_priv->wq,
+				   &mad_agent_priv->timed_work, delay);
+	}
+}
+
+/*
+ * 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)
+{
+	struct ib_mad_agent_private	*mad_agent_priv;
+	unsigned long			flags;
+
+	mad_agent_priv = container_of(mad_send_wr->agent,
+				      struct ib_mad_agent_private, agent);
+
+	spin_lock_irqsave(&mad_agent_priv->lock, flags);
+	if (mad_send_wc->status != IB_WC_SUCCESS &&
+	    mad_send_wr->status == IB_WC_SUCCESS) {
+		mad_send_wr->status = mad_send_wc->status;
+		mad_send_wr->refcount -= (mad_send_wr->timeout > 0);
+	}
+
+	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);
+		}
+		spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
+		return;
+	}
+
+	/* Remove send from MAD agent and notify client of completion */
+	list_del(&mad_send_wr->agent_list);
+	adjust_timeout(mad_agent_priv);
+	spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
+
+	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);
+
+	/* 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);
+}
+
+static void ib_mad_send_done_handler(struct ib_mad_port_private *port_priv,
+				     struct ib_wc *wc)
+{
+	struct ib_mad_send_wr_private	*mad_send_wr, *queued_send_wr;
+	struct ib_mad_list_head		*mad_list;
+	struct ib_mad_qp_info		*qp_info;
+	struct ib_mad_queue		*send_queue;
+	struct ib_send_wr		*bad_send_wr;
+	unsigned long flags;
+	int ret;
+
+	mad_list = (struct ib_mad_list_head *)(unsigned long)wc->wr_id;
+	mad_send_wr = container_of(mad_list, struct ib_mad_send_wr_private,
+				   mad_list);
+	send_queue = mad_list->mad_queue;
+	qp_info = send_queue->qp_info;
+
+retry:
+	queued_send_wr = NULL;
+	spin_lock_irqsave(&send_queue->lock, flags);
+	list_del(&mad_list->list);
+
+	/* Move queued send to the send queue */
+	if (send_queue->count-- > send_queue->max_active) {
+		mad_list = container_of(qp_info->overflow_list.next,
+					struct ib_mad_list_head, list);
+		queued_send_wr = container_of(mad_list,
+					struct ib_mad_send_wr_private,
+					mad_list);
+		list_del(&mad_list->list);
+		list_add_tail(&mad_list->list, &send_queue->list);
+	}
+	spin_unlock_irqrestore(&send_queue->lock, flags);
+
+	/* Restore client wr_id in WC and complete send */
+	wc->wr_id = mad_send_wr->wr_id;
+	if (atomic_read(&qp_info->snoop_count))
+		snoop_send(qp_info, &mad_send_wr->send_wr,
+			   (struct ib_mad_send_wc *)wc,
+			   IB_MAD_SNOOP_SEND_COMPLETIONS);
+	ib_mad_complete_send_wr(mad_send_wr, (struct ib_mad_send_wc *)wc);
+
+	if (queued_send_wr) {
+		ret = ib_post_send(qp_info->qp, &queued_send_wr->send_wr,
+				&bad_send_wr);
+		if (ret) {
+			printk(KERN_ERR PFX "ib_post_send failed: %d\n", ret);
+			mad_send_wr = queued_send_wr;
+			wc->status = IB_WC_LOC_QP_OP_ERR;
+			goto retry;
+		}
+	}
+}
+
+static void mark_sends_for_retry(struct ib_mad_qp_info *qp_info)
+{
+	struct ib_mad_send_wr_private *mad_send_wr;
+	struct ib_mad_list_head *mad_list;
+	unsigned long flags;
+
+	spin_lock_irqsave(&qp_info->send_queue.lock, flags);
+	list_for_each_entry(mad_list, &qp_info->send_queue.list, list) {
+		mad_send_wr = container_of(mad_list,
+					   struct ib_mad_send_wr_private,
+					   mad_list);
+		mad_send_wr->retry = 1;
+	}
+	spin_unlock_irqrestore(&qp_info->send_queue.lock, flags);
+}
+
+static void mad_error_handler(struct ib_mad_port_private *port_priv,
+			      struct ib_wc *wc)
+{
+	struct ib_mad_list_head *mad_list;
+	struct ib_mad_qp_info *qp_info;
+	struct ib_mad_send_wr_private *mad_send_wr;
+	int ret;
+
+	/* Determine if failure was a send or receive */
+	mad_list = (struct ib_mad_list_head *)(unsigned long)wc->wr_id;
+	qp_info = mad_list->mad_queue->qp_info;
+	if (mad_list->mad_queue == &qp_info->recv_queue)
+		/*
+		 * Receive errors indicate that the QP has entered the error
+		 * state - error handling/shutdown code will cleanup
+		 */
+		return;
+
+	/*
+	 * Send errors will transition the QP to SQE - move
+	 * QP to RTS and repost flushed work requests
+	 */
+	mad_send_wr = container_of(mad_list, struct ib_mad_send_wr_private,
+				   mad_list);
+	if (wc->status == IB_WC_WR_FLUSH_ERR) {
+		if (mad_send_wr->retry) {
+			/* Repost send */
+			struct ib_send_wr *bad_send_wr;
+
+			mad_send_wr->retry = 0;
+			ret = ib_post_send(qp_info->qp, &mad_send_wr->send_wr,
+					&bad_send_wr);
+			if (ret)
+				ib_mad_send_done_handler(port_priv, wc);
+		} else
+			ib_mad_send_done_handler(port_priv, wc);
+	} else {
+		struct ib_qp_attr *attr;
+
+		/* Transition QP to RTS and fail offending send */
+		attr = kmalloc(sizeof *attr, GFP_KERNEL);
+		if (attr) {
+			attr->qp_state = IB_QPS_RTS;
+			attr->cur_qp_state = IB_QPS_SQE;
+			ret = ib_modify_qp(qp_info->qp, attr,
+					   IB_QP_STATE | IB_QP_CUR_STATE);
+			kfree(attr);
+			if (ret)
+				printk(KERN_ERR PFX "mad_error_handler - "
+				       "ib_modify_qp to RTS : %d\n", ret);
+			else
+				mark_sends_for_retry(qp_info);
+		}
+		ib_mad_send_done_handler(port_priv, wc);
+	}
+}
+
+/*
+ * IB MAD completion callback
+ */
+static void ib_mad_completion_handler(void *data)
+{
+	struct ib_mad_port_private *port_priv;
+	struct ib_wc wc;
+
+	port_priv = (struct ib_mad_port_private *)data;
+	ib_req_notify_cq(port_priv->cq, IB_CQ_NEXT_COMP);
+
+	while (ib_poll_cq(port_priv->cq, 1, &wc) == 1) {
+		if (wc.status == IB_WC_SUCCESS) {
+			switch (wc.opcode) {
+			case IB_WC_SEND:
+				ib_mad_send_done_handler(port_priv, &wc);
+				break;
+			case IB_WC_RECV:
+				ib_mad_recv_done_handler(port_priv, &wc);
+				break;
+			default:
+				BUG_ON(1);
+				break;
+			}
+		} else
+			mad_error_handler(port_priv, &wc);
+	}
+}
+
+static void cancel_mads(struct ib_mad_agent_private *mad_agent_priv)
+{
+	unsigned long flags;
+	struct ib_mad_send_wr_private *mad_send_wr, *temp_mad_send_wr;
+	struct ib_mad_send_wc mad_send_wc;
+	struct list_head cancel_list;
+
+	INIT_LIST_HEAD(&cancel_list);
+
+	spin_lock_irqsave(&mad_agent_priv->lock, flags);
+	list_for_each_entry_safe(mad_send_wr, temp_mad_send_wr,
+				 &mad_agent_priv->send_list, agent_list) {
+		if (mad_send_wr->status == IB_WC_SUCCESS) {
+ 			mad_send_wr->status = IB_WC_WR_FLUSH_ERR;
+			mad_send_wr->refcount -= (mad_send_wr->timeout > 0);
+		}
+	}
+
+	/* Empty wait list to prevent receives from finding a request */
+	list_splice_init(&mad_agent_priv->wait_list, &cancel_list);
+	spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
+
+	/* Report all cancelled requests */
+	mad_send_wc.status = IB_WC_WR_FLUSH_ERR;
+	mad_send_wc.vendor_err = 0;
+
+	list_for_each_entry_safe(mad_send_wr, temp_mad_send_wr,
+				 &cancel_list, agent_list) {
+		mad_send_wc.wr_id = mad_send_wr->wr_id;
+		mad_agent_priv->agent.send_handler(&mad_agent_priv->agent,
+						   &mad_send_wc);
+
+		list_del(&mad_send_wr->agent_list);
+		kfree(mad_send_wr);
+		atomic_dec(&mad_agent_priv->refcount);
+	}
+}
+
+static struct ib_mad_send_wr_private*
+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;
+
+	list_for_each_entry(mad_send_wr, &mad_agent_priv->wait_list,
+			    agent_list) {
+		if (mad_send_wr->wr_id == wr_id)
+			return mad_send_wr;
+	}
+
+	list_for_each_entry(mad_send_wr, &mad_agent_priv->send_list,
+			    agent_list) {
+		if (mad_send_wr->wr_id == wr_id)
+			return mad_send_wr;
+	}
+	return NULL;
+}
+
+void ib_cancel_mad(struct ib_mad_agent *mad_agent,
+		  u64 wr_id)
+{
+	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 = 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) {
+		spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
+		goto out;
+	}
+
+	if (mad_send_wr->status == IB_WC_SUCCESS)
+		mad_send_wr->refcount -= (mad_send_wr->timeout > 0);
+
+	if (mad_send_wr->refcount != 0) {
+		mad_send_wr->status = IB_WC_WR_FLUSH_ERR;
+		spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
+		goto out;
+	}
+
+	list_del(&mad_send_wr->agent_list);
+	adjust_timeout(mad_agent_priv);
+	spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
+
+	mad_send_wc.status = IB_WC_WR_FLUSH_ERR;
+	mad_send_wc.vendor_err = 0;
+	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);
+
+out:
+	return;
+}
+EXPORT_SYMBOL(ib_cancel_mad);
+
+static void local_completions(void *data)
+{
+	struct ib_mad_agent_private *mad_agent_priv;
+	struct ib_mad_local_private *local;
+	struct ib_mad_agent_private *recv_mad_agent;
+	unsigned long flags;
+	struct ib_wc wc;
+	struct ib_mad_send_wc mad_send_wc;
+
+	mad_agent_priv = (struct ib_mad_agent_private *)data;
+
+	spin_lock_irqsave(&mad_agent_priv->lock, flags);
+	while (!list_empty(&mad_agent_priv->local_list)) {
+		local = list_entry(mad_agent_priv->local_list.next,
+				   struct ib_mad_local_private,
+				   completion_list);
+		spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
+		if (local->mad_priv) {
+			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;
+			}
+
+			/*
+			 * Defined behavior is to complete response
+			 * before request
+			 */
+			build_smp_wc(local->wr_id, IB_LID_PERMISSIVE,
+				     0 /* pkey index */,
+				     recv_mad_agent->agent.port_num, &wc);
+
+			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);
+			local->mad_priv->header.recv_wc.recv_buf.grh = NULL;
+			local->mad_priv->header.recv_wc.recv_buf.mad =
+						&local->mad_priv->mad.mad;
+			if (atomic_read(&recv_mad_agent->qp_info->snoop_count))
+				snoop_recv(recv_mad_agent->qp_info,
+					  &local->mad_priv->header.recv_wc,
+					   IB_MAD_SNOOP_RECVS);
+			recv_mad_agent->agent.recv_handler(
+						&recv_mad_agent->agent,
+						&local->mad_priv->header.recv_wc);
+			spin_lock_irqsave(&recv_mad_agent->lock, flags);
+			atomic_dec(&recv_mad_agent->refcount);
+			spin_unlock_irqrestore(&recv_mad_agent->lock, flags);
+		}
+
+local_send_completion:
+		/* Complete send */
+		mad_send_wc.status = IB_WC_SUCCESS;
+		mad_send_wc.vendor_err = 0;
+		mad_send_wc.wr_id = local->wr_id;
+		if (atomic_read(&mad_agent_priv->qp_info->snoop_count))
+			snoop_send(mad_agent_priv->qp_info, &local->send_wr,
+				  &mad_send_wc,
+				   IB_MAD_SNOOP_SEND_COMPLETIONS);
+		mad_agent_priv->agent.send_handler(&mad_agent_priv->agent,
+						   &mad_send_wc);
+
+		spin_lock_irqsave(&mad_agent_priv->lock, flags);
+		list_del(&local->completion_list);
+		atomic_dec(&mad_agent_priv->refcount);
+		kfree(local);
+	}
+	spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
+}
+
+static void timeout_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, 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);
+	while (!list_empty(&mad_agent_priv->wait_list)) {
+		mad_send_wr = list_entry(mad_agent_priv->wait_list.next,
+					 struct ib_mad_send_wr_private,
+					 agent_list);
+
+		if (time_after(mad_send_wr->timeout, jiffies)) {
+			delay = mad_send_wr->timeout - jiffies;
+			if ((long)delay <= 0)
+				delay = 1;
+			queue_delayed_work(mad_agent_priv->qp_info->
+					   port_priv->wq,
+					   &mad_agent_priv->timed_work, delay);
+			break;
+		}
+
+		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);
+		atomic_dec(&mad_agent_priv->refcount);
+		spin_lock_irqsave(&mad_agent_priv->lock, flags);
+	}
+	spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
+}
+
+static void ib_mad_thread_completion_handler(struct ib_cq *cq)
+{
+	struct ib_mad_port_private *port_priv = cq->cq_context;
+
+	queue_work(port_priv->wq, &port_priv->work);
+}
+
+/*
+ * Allocate receive MADs and post receive WRs for them
+ */
+static int ib_mad_post_receive_mads(struct ib_mad_qp_info *qp_info,
+				    struct ib_mad_private *mad)
+{
+	unsigned long flags;
+	int post, ret;
+	struct ib_mad_private *mad_priv;
+	struct ib_sge sg_list;
+	struct ib_recv_wr recv_wr, *bad_recv_wr;
+	struct ib_mad_queue *recv_queue = &qp_info->recv_queue;
+
+	/* Initialize common scatter list fields */
+	sg_list.length = sizeof *mad_priv - sizeof mad_priv->header;
+	sg_list.lkey = (*qp_info->port_priv->mr).lkey;
+
+	/* Initialize common receive WR fields */
+	recv_wr.next = NULL;
+	recv_wr.sg_list = &sg_list;
+	recv_wr.num_sge = 1;
+	recv_wr.recv_flags = IB_RECV_SIGNALED;
+
+	do {
+		/* Allocate and map receive buffer */
+		if (mad) {
+			mad_priv = mad;
+			mad = NULL;
+		} else {
+			mad_priv = kmem_cache_alloc(ib_mad_cache, GFP_KERNEL);
+			if (!mad_priv) {
+				printk(KERN_ERR PFX "No memory for receive buffer\n");
+				ret = -ENOMEM;
+				break;
+			}
+		}
+		sg_list.addr = dma_map_single(qp_info->port_priv->
+						device->dma_device,
+					&mad_priv->grh,
+					sizeof *mad_priv -
+						sizeof mad_priv->header,
+					DMA_FROM_DEVICE);
+		pci_unmap_addr_set(&mad_priv->header, mapping, sg_list.addr);
+		recv_wr.wr_id = (unsigned long)&mad_priv->header.mad_list;
+		mad_priv->header.mad_list.mad_queue = recv_queue;
+
+		/* Post receive WR */
+		spin_lock_irqsave(&recv_queue->lock, flags);
+		post = (++recv_queue->count < recv_queue->max_active);
+		list_add_tail(&mad_priv->header.mad_list.list, &recv_queue->list);
+		spin_unlock_irqrestore(&recv_queue->lock, flags);
+		ret = ib_post_recv(qp_info->qp, &recv_wr, &bad_recv_wr);
+		if (ret) {
+			spin_lock_irqsave(&recv_queue->lock, flags);
+			list_del(&mad_priv->header.mad_list.list);
+			recv_queue->count--;
+			spin_unlock_irqrestore(&recv_queue->lock, flags);
+			dma_unmap_single(qp_info->port_priv->device->dma_device,
+					 pci_unmap_addr(&mad_priv->header,
+							mapping),
+					 sizeof *mad_priv -
+					   sizeof mad_priv->header,
+					 DMA_FROM_DEVICE);
+			kmem_cache_free(ib_mad_cache, mad_priv);
+			printk(KERN_ERR PFX "ib_post_recv failed: %d\n", ret);
+			break;
+		}
+	} while (post);
+
+	return ret;
+}
+
+/*
+ * Return all the posted receive MADs
+ */
+static void cleanup_recv_queue(struct ib_mad_qp_info *qp_info)
+{
+	struct ib_mad_private_header *mad_priv_hdr;
+	struct ib_mad_private *recv;
+	struct ib_mad_list_head *mad_list;
+
+	while (!list_empty(&qp_info->recv_queue.list)) {
+
+		mad_list = list_entry(qp_info->recv_queue.list.next,
+				      struct ib_mad_list_head, list);
+		mad_priv_hdr = container_of(mad_list,
+					    struct ib_mad_private_header,
+					    mad_list);
+		recv = container_of(mad_priv_hdr, struct ib_mad_private,
+				    header);
+
+		/* Remove from posted receive MAD list */
+		list_del(&mad_list->list);
+
+		/* Undo PCI mapping */
+		dma_unmap_single(qp_info->port_priv->device->dma_device,
+				 pci_unmap_addr(&recv->header, mapping),
+				 sizeof(struct ib_mad_private) -
+				 sizeof(struct ib_mad_private_header),
+				 DMA_FROM_DEVICE);
+		kmem_cache_free(ib_mad_cache, recv);
+	}
+
+	qp_info->recv_queue.count = 0;
+}
+
+/*
+ * Start the port
+ */
+static int ib_mad_port_start(struct ib_mad_port_private *port_priv)
+{
+	int ret, i;
+	struct ib_qp_attr *attr;
+	struct ib_qp *qp;
+
+	attr = kmalloc(sizeof *attr, GFP_KERNEL);
+ 	if (!attr) {
+		printk(KERN_ERR PFX "Couldn't kmalloc ib_qp_attr\n");
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < IB_MAD_QPS_CORE; i++) {
+		qp = port_priv->qp_info[i].qp;
+		/*
+		 * PKey index for QP1 is irrelevant but
+		 * one is needed for the Reset to Init transition
+		 */
+		attr->qp_state = IB_QPS_INIT;
+		attr->pkey_index = 0;
+		attr->qkey = (qp->qp_num == 0) ? 0 : IB_QP1_QKEY;
+		ret = ib_modify_qp(qp, attr, IB_QP_STATE |
+					     IB_QP_PKEY_INDEX | IB_QP_QKEY);
+		if (ret) {
+			printk(KERN_ERR PFX "Couldn't change QP%d state to "
+			       "INIT: %d\n", i, ret);
+			goto out;
+		}
+
+		attr->qp_state = IB_QPS_RTR;
+		ret = ib_modify_qp(qp, attr, IB_QP_STATE);
+		if (ret) {
+			printk(KERN_ERR PFX "Couldn't change QP%d state to "
+			       "RTR: %d\n", i, ret);
+			goto out;
+		}
+
+		attr->qp_state = IB_QPS_RTS;
+		attr->sq_psn = IB_MAD_SEND_Q_PSN;
+		ret = ib_modify_qp(qp, attr, IB_QP_STATE | IB_QP_SQ_PSN);
+		if (ret) {
+			printk(KERN_ERR PFX "Couldn't change QP%d state to "
+			       "RTS: %d\n", i, ret);
+			goto out;
+		}
+	}
+
+	ret = ib_req_notify_cq(port_priv->cq, IB_CQ_NEXT_COMP);
+	if (ret) {
+		printk(KERN_ERR PFX "Failed to request completion "
+		       "notification: %d\n", ret);
+		goto out;
+	}
+
+	for (i = 0; i < IB_MAD_QPS_CORE; i++) {
+		ret = ib_mad_post_receive_mads(&port_priv->qp_info[i], NULL);
+		if (ret) {
+			printk(KERN_ERR PFX "Couldn't post receive WRs\n");
+			goto out;
+		}
+	}
+out:
+	kfree(attr);
+	return ret;
+}
+
+static void qp_event_handler(struct ib_event *event, void *qp_context)
+{
+	struct ib_mad_qp_info	*qp_info = qp_context;
+
+	/* It's worse than that! He's dead, Jim! */
+	printk(KERN_ERR PFX "Fatal error (%d) on MAD QP (%d)\n",
+		event->event, qp_info->qp->qp_num);
+}
+
+static void init_mad_queue(struct ib_mad_qp_info *qp_info,
+			   struct ib_mad_queue *mad_queue)
+{
+	mad_queue->qp_info = qp_info;
+	mad_queue->count = 0;
+	spin_lock_init(&mad_queue->lock);
+	INIT_LIST_HEAD(&mad_queue->list);
+}
+
+static void init_mad_qp(struct ib_mad_port_private *port_priv,
+			struct ib_mad_qp_info *qp_info)
+{
+	qp_info->port_priv = port_priv;
+	init_mad_queue(qp_info, &qp_info->send_queue);
+	init_mad_queue(qp_info, &qp_info->recv_queue);
+	INIT_LIST_HEAD(&qp_info->overflow_list);
+	spin_lock_init(&qp_info->snoop_lock);
+	qp_info->snoop_table = NULL;
+	qp_info->snoop_table_size = 0;
+	atomic_set(&qp_info->snoop_count, 0);
+}
+
+static int create_mad_qp(struct ib_mad_qp_info *qp_info,
+			 enum ib_qp_type qp_type)
+{
+	struct ib_qp_init_attr	qp_init_attr;
+	int ret;
+
+	memset(&qp_init_attr, 0, sizeof qp_init_attr);
+	qp_init_attr.send_cq = qp_info->port_priv->cq;
+	qp_init_attr.recv_cq = qp_info->port_priv->cq;
+	qp_init_attr.sq_sig_type = IB_SIGNAL_ALL_WR;
+	qp_init_attr.rq_sig_type = IB_SIGNAL_ALL_WR;
+	qp_init_attr.cap.max_send_wr = IB_MAD_QP_SEND_SIZE;
+	qp_init_attr.cap.max_recv_wr = IB_MAD_QP_RECV_SIZE;
+	qp_init_attr.cap.max_send_sge = IB_MAD_SEND_REQ_MAX_SG;
+	qp_init_attr.cap.max_recv_sge = IB_MAD_RECV_REQ_MAX_SG;
+	qp_init_attr.qp_type = qp_type;
+	qp_init_attr.port_num = qp_info->port_priv->port_num;
+	qp_init_attr.qp_context = qp_info;
+	qp_init_attr.event_handler = qp_event_handler;
+	qp_info->qp = ib_create_qp(qp_info->port_priv->pd, &qp_init_attr);
+	if (IS_ERR(qp_info->qp)) {
+		printk(KERN_ERR PFX "Couldn't create ib_mad QP%d\n",
+		       get_spl_qp_index(qp_type));
+		ret = PTR_ERR(qp_info->qp);
+		goto error;
+	}
+	/* Use minimum queue sizes unless the CQ is resized */
+	qp_info->send_queue.max_active = IB_MAD_QP_SEND_SIZE;
+	qp_info->recv_queue.max_active = IB_MAD_QP_RECV_SIZE;
+	return 0;
+
+error:
+	return ret;
+}
+
+static void destroy_mad_qp(struct ib_mad_qp_info *qp_info)
+{
+	ib_destroy_qp(qp_info->qp);
+	if (qp_info->snoop_table)
+		kfree(qp_info->snoop_table);
+}
+
+/*
+ * Open the port
+ * Create the QP, PD, MR, and CQ if needed
+ */
+static int ib_mad_port_open(struct ib_device *device,
+			    int port_num)
+{
+	int ret, cq_size;
+	struct ib_mad_port_private *port_priv;
+	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) {
+		printk(KERN_ERR PFX "No memory for ib_mad_port_private\n");
+		return -ENOMEM;
+	}
+	memset(port_priv, 0, sizeof *port_priv);
+	port_priv->device = device;
+	port_priv->port_num = port_num;
+	spin_lock_init(&port_priv->reg_lock);
+	INIT_LIST_HEAD(&port_priv->agent_list);
+	init_mad_qp(port_priv, &port_priv->qp_info[0]);
+	init_mad_qp(port_priv, &port_priv->qp_info[1]);
+
+	cq_size = (IB_MAD_QP_SEND_SIZE + IB_MAD_QP_RECV_SIZE) * 2;
+	port_priv->cq = ib_create_cq(port_priv->device,
+				     (ib_comp_handler)
+					ib_mad_thread_completion_handler,
+				     NULL, port_priv, cq_size);
+	if (IS_ERR(port_priv->cq)) {
+		printk(KERN_ERR PFX "Couldn't create ib_mad CQ\n");
+		ret = PTR_ERR(port_priv->cq);
+		goto error3;
+	}
+
+	port_priv->pd = ib_alloc_pd(device);
+	if (IS_ERR(port_priv->pd)) {
+		printk(KERN_ERR PFX "Couldn't create ib_mad PD\n");
+		ret = PTR_ERR(port_priv->pd);
+		goto error4;
+	}
+
+	port_priv->mr = ib_get_dma_mr(port_priv->pd, IB_ACCESS_LOCAL_WRITE);
+	if (IS_ERR(port_priv->mr)) {
+		printk(KERN_ERR PFX "Couldn't get ib_mad DMA MR\n");
+		ret = PTR_ERR(port_priv->mr);
+		goto error5;
+	}
+
+	ret = create_mad_qp(&port_priv->qp_info[0], IB_QPT_SMI);
+	if (ret)
+		goto error6;
+	ret = create_mad_qp(&port_priv->qp_info[1], IB_QPT_GSI);
+	if (ret)
+		goto error7;
+
+	snprintf(name, sizeof name, "ib_mad%d", port_num);
+	port_priv->wq = create_singlethread_workqueue(name);
+	if (!port_priv->wq) {
+		ret = -ENOMEM;
+		goto error8;
+	}
+	INIT_WORK(&port_priv->work, ib_mad_completion_handler, port_priv);
+
+	ret = ib_mad_port_start(port_priv);
+	if (ret) {
+		printk(KERN_ERR PFX "Couldn't start port\n");
+		goto error9;
+	}
+
+	spin_lock_irqsave(&ib_mad_port_list_lock, flags);
+	list_add_tail(&port_priv->port_list, &ib_mad_port_list);
+	spin_unlock_irqrestore(&ib_mad_port_list_lock, flags);
+	return 0;
+
+error9:
+	destroy_workqueue(port_priv->wq);
+error8:
+	destroy_mad_qp(&port_priv->qp_info[1]);
+error7:
+	destroy_mad_qp(&port_priv->qp_info[0]);
+error6:
+	ib_dereg_mr(port_priv->mr);
+error5:
+	ib_dealloc_pd(port_priv->pd);
+error4:
+	ib_destroy_cq(port_priv->cq);
+	cleanup_recv_queue(&port_priv->qp_info[1]);
+	cleanup_recv_queue(&port_priv->qp_info[0]);
+error3:
+	kfree(port_priv);
+
+	return ret;
+}
+
+/*
+ * Close the port
+ * If there are no classes using the port, free the port
+ * resources (CQ, MR, PD, QP) and remove the port's info structure
+ */
+static int ib_mad_port_close(struct ib_device *device, int port_num)
+{
+	struct ib_mad_port_private *port_priv;
+	unsigned long flags;
+
+	spin_lock_irqsave(&ib_mad_port_list_lock, flags);
+	port_priv = __ib_get_mad_port(device, port_num);
+	if (port_priv == NULL) {
+		spin_unlock_irqrestore(&ib_mad_port_list_lock, flags);
+		printk(KERN_ERR PFX "Port %d not found\n", port_num);
+		return -ENODEV;
+	}
+	list_del(&port_priv->port_list);
+	spin_unlock_irqrestore(&ib_mad_port_list_lock, flags);
+
+	/* Stop processing completions. */
+	flush_workqueue(port_priv->wq);
+	destroy_workqueue(port_priv->wq);
+	destroy_mad_qp(&port_priv->qp_info[1]);
+	destroy_mad_qp(&port_priv->qp_info[0]);
+	ib_dereg_mr(port_priv->mr);
+	ib_dealloc_pd(port_priv->pd);
+	ib_destroy_cq(port_priv->cq);
+	cleanup_recv_queue(&port_priv->qp_info[1]);
+	cleanup_recv_queue(&port_priv->qp_info[0]);
+	/* XXX: Handle deallocation of MAD registration tables */
+
+	kfree(port_priv);
+
+	return 0;
+}
+
+static void ib_mad_init_device(struct ib_device *device)
+{
+	int ret, num_ports, cur_port, i, ret2;
+
+	if (device->node_type == IB_NODE_SWITCH) {
+		num_ports = 1;
+		cur_port = 0;
+	} else {
+		num_ports = device->phys_port_cnt;
+		cur_port = 1;
+	}
+	for (i = 0; i < num_ports; i++, cur_port++) {
+		ret = ib_mad_port_open(device, cur_port);
+		if (ret) {
+			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) {
+			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;
+
+error_device_open:
+	while (i > 0) {
+		cur_port--;
+		ret2 = ib_agent_port_close(device, cur_port);
+		if (ret2) {
+			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) {
+			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;
+
+	if (device->node_type == IB_NODE_SWITCH) {
+		num_ports = 1;
+		cur_port = 0;
+	} else {
+		num_ports = device->phys_port_cnt;
+		cur_port = 1;
+	}
+	for (i = 0; i < num_ports; i++, cur_port++) {
+		ret2 = ib_agent_port_close(device, cur_port);
+		if (ret2) {
+			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) {
+			printk(KERN_ERR PFX "Couldn't close %s port %d\n",
+			       device->name, cur_port);
+			if (!ret)
+				ret = ret2;
+		}
+	}
+}
+
+static struct ib_client mad_client = {
+	.name   = "mad",
+	.add = ib_mad_init_device,
+	.remove = ib_mad_remove_device
+};
+
+static int __init ib_mad_init_module(void)
+{
+	int ret;
+
+	spin_lock_init(&ib_mad_port_list_lock);
+	spin_lock_init(&ib_agent_port_list_lock);
+
+	ib_mad_cache = kmem_cache_create("ib_mad",
+					 sizeof(struct ib_mad_private),
+					 0,
+					 SLAB_HWCACHE_ALIGN,
+					 NULL,
+					 NULL);
+	if (!ib_mad_cache) {
+		printk(KERN_ERR PFX "Couldn't create ib_mad cache\n");
+		ret = -ENOMEM;
+		goto error1;
+	}
+
+	INIT_LIST_HEAD(&ib_mad_port_list);
+
+	if (ib_register_client(&mad_client)) {
+		printk(KERN_ERR PFX "Couldn't register ib_mad client\n");
+		ret = -EINVAL;
+		goto error2;
+	}
+
+	return 0;
+
+error2:
+	kmem_cache_destroy(ib_mad_cache);
+error1:
+	return ret;
+}
+
+static void __exit ib_mad_cleanup_module(void)
+{
+	ib_unregister_client(&mad_client);
+
+	if (kmem_cache_destroy(ib_mad_cache)) {
+		printk(KERN_DEBUG PFX "Failed to destroy ib_mad cache\n");
+	}
+}
+
+module_init(ib_mad_init_module);
+module_exit(ib_mad_cleanup_module);
diff -Nru a/drivers/infiniband/core/mad_priv.h b/drivers/infiniband/core/mad_priv.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/infiniband/core/mad_priv.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2004, 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_priv.h 1389 2004-12-27 22:56:47Z roland $
+ */
+
+#ifndef __IB_MAD_PRIV_H__
+#define __IB_MAD_PRIV_H__
+
+#include <linux/pci.h>
+#include <linux/kthread.h>
+#include <linux/workqueue.h>
+#include <ib_mad.h>
+#include <ib_smi.h>
+
+
+#define PFX "ib_mad: "
+
+#define IB_MAD_QPS_CORE		2 /* Always QP0 and QP1 as a minimum */
+
+/* QP and CQ parameters */
+#define IB_MAD_QP_SEND_SIZE	128
+#define IB_MAD_QP_RECV_SIZE	512
+#define IB_MAD_SEND_REQ_MAX_SG	2
+#define IB_MAD_RECV_REQ_MAX_SG	1
+
+#define IB_MAD_SEND_Q_PSN	0
+
+/* Registration table sizes */
+#define MAX_MGMT_CLASS		80
+#define MAX_MGMT_VERSION	8
+#define MAX_MGMT_OUI		8
+#define MAX_MGMT_VENDOR_RANGE2	IB_MGMT_CLASS_VENDOR_RANGE2_END - \
+				IB_MGMT_CLASS_VENDOR_RANGE2_START + 1
+
+struct ib_mad_list_head {
+	struct list_head list;
+	struct ib_mad_queue *mad_queue;
+};
+
+struct ib_mad_private_header {
+	struct ib_mad_list_head mad_list;
+	struct ib_mad_recv_wc recv_wc;
+	DECLARE_PCI_UNMAP_ADDR(mapping)
+} __attribute__ ((packed));
+
+struct ib_mad_private {
+	struct ib_mad_private_header header;
+	struct ib_grh grh;
+	union {
+		struct ib_mad mad;
+		struct ib_rmpp_mad rmpp_mad;
+		struct ib_smp smp;
+	} mad;
+} __attribute__ ((packed));
+
+struct ib_mad_agent_private {
+	struct list_head agent_list;
+	struct ib_mad_agent agent;
+	struct ib_mad_reg_req *reg_req;
+	struct ib_mad_qp_info *qp_info;
+
+	spinlock_t lock;
+	struct list_head send_list;
+	struct list_head wait_list;
+	struct work_struct timed_work;
+	unsigned long timeout;
+	struct list_head local_list;
+	struct work_struct local_work;
+
+	atomic_t refcount;
+	wait_queue_head_t wait;
+	u8 rmpp_version;
+};
+
+struct ib_mad_snoop_private {
+	struct ib_mad_agent agent;
+	struct ib_mad_qp_info *qp_info;
+	int snoop_index;
+	int mad_snoop_flags;
+	atomic_t refcount;
+	wait_queue_head_t wait;
+};
+
+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_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 retry;
+	int refcount;
+	enum ib_wc_status status;
+};
+
+struct ib_mad_local_private {
+	struct list_head completion_list;
+	struct ib_mad_private *mad_priv;
+	struct ib_mad_agent_private *recv_mad_agent;
+	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;
+};
+
+struct ib_mad_mgmt_method_table {
+	struct ib_mad_agent_private *agent[IB_MGMT_MAX_METHODS];
+};
+
+struct ib_mad_mgmt_class_table {
+	struct ib_mad_mgmt_method_table *method_table[MAX_MGMT_CLASS];
+};
+
+struct ib_mad_mgmt_vendor_class {
+	u8	oui[MAX_MGMT_OUI][3];
+	struct ib_mad_mgmt_method_table *method_table[MAX_MGMT_OUI];
+};
+
+struct ib_mad_mgmt_vendor_class_table {
+	struct ib_mad_mgmt_vendor_class *vendor_class[MAX_MGMT_VENDOR_RANGE2];
+};
+
+struct ib_mad_mgmt_version_table {
+	struct ib_mad_mgmt_class_table *class;
+	struct ib_mad_mgmt_vendor_class_table *vendor;
+};
+
+struct ib_mad_queue {
+	spinlock_t lock;
+	struct list_head list;
+	int count;
+	int max_active;
+	struct ib_mad_qp_info *qp_info;
+};
+
+struct ib_mad_qp_info {
+	struct ib_mad_port_private *port_priv;
+	struct ib_qp *qp;
+	struct ib_mad_queue send_queue;
+	struct ib_mad_queue recv_queue;
+	struct list_head overflow_list;
+	spinlock_t snoop_lock;
+	struct ib_mad_snoop_private **snoop_table;
+	int snoop_table_size;
+	atomic_t snoop_count;
+};
+
+struct ib_mad_port_private {
+	struct list_head port_list;
+	struct ib_device *device;
+	int port_num;
+	struct ib_cq *cq;
+	struct ib_pd *pd;
+	struct ib_mr *mr;
+
+	spinlock_t reg_lock;
+	struct ib_mad_mgmt_version_table version[MAX_MGMT_VERSION];
+	struct list_head agent_list;
+	struct workqueue_struct *wq;
+	struct work_struct work;
+	struct ib_mad_qp_info qp_info[IB_MAD_QPS_CORE];
+};
+
+#endif	/* __IB_MAD_PRIV_H__ */
diff -Nru a/drivers/infiniband/core/packer.c b/drivers/infiniband/core/packer.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/infiniband/core/packer.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2004 Topspin 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 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: packer.c 1349 2004-12-16 21:09:43Z roland $
+ */
+
+#include <ib_pack.h>
+
+static u64 value_read(int offset, int size, void *structure)
+{
+	switch (size) {
+	case 1: return                *(u8  *) (structure + offset);
+	case 2: return be16_to_cpup((__be16 *) (structure + offset));
+	case 4: return be32_to_cpup((__be32 *) (structure + offset));
+	case 8: return be64_to_cpup((__be64 *) (structure + offset));
+	default:
+		printk(KERN_WARNING "Field size %d bits not handled\n", size * 8);
+		return 0;
+	}
+}
+
+/**
+ * ib_pack - Pack a structure into a buffer
+ * @desc:Array of structure field descriptions
+ * @desc_len:Number of entries in @desc
+ * @structure:Structure to pack from
+ * @buf:Buffer to pack into
+ *
+ * ib_pack() packs a list of structure fields into a buffer,
+ * controlled by the array of fields in @desc.
+ */
+void ib_pack(const struct ib_field        *desc,
+	     int                           desc_len,
+	     void                         *structure,
+	     void                         *buf)
+{
+	int i;
+
+	for (i = 0; i < desc_len; ++i) {
+		if (desc[i].size_bits <= 32) {
+			int shift;
+			u32 val;
+			__be32 mask;
+			__be32 *addr;
+
+			shift = 32 - desc[i].offset_bits - desc[i].size_bits;
+			if (desc[i].struct_size_bytes)
+				val = value_read(desc[i].struct_offset_bytes,
+						 desc[i].struct_size_bytes,
+						 structure) << shift;
+			else
+				val = 0;
+
+			mask = cpu_to_be32(((1ull << desc[i].size_bits) - 1) << shift);
+			addr = (__be32 *) buf + desc[i].offset_words;
+			*addr = (*addr & ~mask) | (cpu_to_be32(val) & mask);
+		} else if (desc[i].size_bits <= 64) {
+			int shift;
+			u64 val;
+			__be64 mask;
+			__be64 *addr;
+
+			shift = 64 - desc[i].offset_bits - desc[i].size_bits;
+			if (desc[i].struct_size_bytes)
+				val = value_read(desc[i].struct_offset_bytes,
+						 desc[i].struct_size_bytes,
+						 structure) << shift;
+			else
+				val = 0;
+
+			mask = cpu_to_be64(((1ull << desc[i].size_bits) - 1) << shift);
+			addr = (__be64 *) ((__be32 *) buf + desc[i].offset_words);
+			*addr = (*addr & ~mask) | (cpu_to_be64(val) & mask);
+		} else {
+			if (desc[i].offset_bits % 8 ||
+			    desc[i].size_bits   % 8) {
+				printk(KERN_WARNING "Structure field %s of size %d "
+				       "bits is not byte-aligned\n",
+				       desc[i].field_name, desc[i].size_bits);
+			}
+
+			if (desc[i].struct_size_bytes)
+				memcpy(buf + desc[i].offset_words * 4 +
+				       desc[i].offset_bits / 8,
+				       structure + desc[i].struct_offset_bytes,
+				       desc[i].size_bits / 8);
+			else
+				memset(buf + desc[i].offset_words * 4 +
+				       desc[i].offset_bits / 8,
+				       0,
+				       desc[i].size_bits / 8);
+		}
+	}
+}
+EXPORT_SYMBOL(ib_pack);
+
+static void value_write(int offset, int size, u64 val, void *structure)
+{
+	switch (size * 8) {
+	case 8:  *(    u8 *) (structure + offset) = val; break;
+	case 16: *(__be16 *) (structure + offset) = cpu_to_be16(val); break;
+	case 32: *(__be32 *) (structure + offset) = cpu_to_be32(val); break;
+	case 64: *(__be64 *) (structure + offset) = cpu_to_be64(val); break;
+	default:
+		printk(KERN_WARNING "Field size %d bits not handled\n", size * 8);
+	}
+}
+
+/**
+ * ib_unpack - Unpack a buffer into a structure
+ * @desc:Array of structure field descriptions
+ * @desc_len:Number of entries in @desc
+ * @buf:Buffer to unpack from
+ * @structure:Structure to unpack into
+ *
+ * ib_pack() unpacks a list of structure fields from a buffer,
+ * controlled by the array of fields in @desc.
+ */
+void ib_unpack(const struct ib_field        *desc,
+	       int                           desc_len,
+	       void                         *buf,
+	       void                         *structure)
+{
+	int i;
+
+	for (i = 0; i < desc_len; ++i) {
+		if (!desc[i].struct_size_bytes)
+			continue;
+
+		if (desc[i].size_bits <= 32) {
+			int shift;
+			u32  val;
+			u32  mask;
+			__be32 *addr;
+
+			shift = 32 - desc[i].offset_bits - desc[i].size_bits;
+			mask = ((1ull << desc[i].size_bits) - 1) << shift;
+			addr = (__be32 *) buf + desc[i].offset_words;
+			val = (be32_to_cpup(addr) & mask) >> shift;
+			value_write(desc[i].struct_offset_bytes,
+				    desc[i].struct_size_bytes,
+				    val,
+				    structure);
+		} else if (desc[i].size_bits <= 64) {
+			int shift;
+			u64  val;
+			u64  mask;
+			__be64 *addr;
+
+			shift = 64 - desc[i].offset_bits - desc[i].size_bits;
+			mask = ((1ull << desc[i].size_bits) - 1) << shift;
+			addr = (__be64 *) buf + desc[i].offset_words;
+			val = (be64_to_cpup(addr) & mask) >> shift;
+			value_write(desc[i].struct_offset_bytes,
+				    desc[i].struct_size_bytes,
+				    val,
+				    structure);
+		} else {
+			if (desc[i].offset_bits % 8 ||
+			    desc[i].size_bits   % 8) {
+				printk(KERN_WARNING "Structure field %s of size %d "
+				       "bits is not byte-aligned\n",
+				       desc[i].field_name, desc[i].size_bits);
+			}
+
+			memcpy(structure + desc[i].struct_offset_bytes,
+			       buf + desc[i].offset_words * 4 +
+			       desc[i].offset_bits / 8,
+			       desc[i].size_bits / 8);
+		}
+	}
+}
+EXPORT_SYMBOL(ib_unpack);
diff -Nru a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/infiniband/core/sa_query.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,866 @@
+/*
+ * Copyright (c) 2004 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: sa_query.c 1389 2004-12-27 22:56:47Z roland $
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/random.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <linux/pci.h>
+#include <linux/dma-mapping.h>
+#include <linux/kref.h>
+#include <linux/idr.h>
+
+#include <ib_pack.h>
+#include <ib_sa.h>
+
+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;
+};
+
+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;
+	u8                   port_num;
+};
+
+struct ib_sa_device {
+	int                     start_port, end_port;
+	struct ib_event_handler event_handler;
+	struct ib_sa_port port[0];
+};
+
+struct ib_sa_query {
+	void (*callback)(struct ib_sa_query *, int, struct ib_sa_mad *);
+	void (*release)(struct ib_sa_query *);
+	struct ib_sa_port  *port;
+	struct ib_sa_mad   *mad;
+	struct ib_sa_sm_ah *sm_ah;
+	DECLARE_PCI_UNMAP_ADDR(mapping)
+	int                 id;
+};
+
+struct ib_sa_path_query {
+	void (*callback)(int, struct ib_sa_path_rec *, void *);
+	void *context;
+	struct ib_sa_query sa_query;
+};
+
+struct ib_sa_mcmember_query {
+	void (*callback)(int, struct ib_sa_mcmember_rec *, void *);
+	void *context;
+	struct ib_sa_query sa_query;
+};
+
+static void ib_sa_add_one(struct ib_device *device);
+static void ib_sa_remove_one(struct ib_device *device);
+
+static struct ib_client sa_client = {
+	.name   = "sa",
+	.add    = ib_sa_add_one,
+	.remove = ib_sa_remove_one
+};
+
+static spinlock_t idr_lock;
+static DEFINE_IDR(query_idr);
+
+static spinlock_t tid_lock;
+static u32 tid;
+
+enum {
+	IB_SA_ATTR_CLASS_PORTINFO    = 0x01,
+	IB_SA_ATTR_NOTICE	     = 0x02,
+	IB_SA_ATTR_INFORM_INFO	     = 0x03,
+	IB_SA_ATTR_NODE_REC	     = 0x11,
+	IB_SA_ATTR_PORT_INFO_REC     = 0x12,
+	IB_SA_ATTR_SL2VL_REC	     = 0x13,
+	IB_SA_ATTR_SWITCH_REC	     = 0x14,
+	IB_SA_ATTR_LINEAR_FDB_REC    = 0x15,
+	IB_SA_ATTR_RANDOM_FDB_REC    = 0x16,
+	IB_SA_ATTR_MCAST_FDB_REC     = 0x17,
+	IB_SA_ATTR_SM_INFO_REC	     = 0x18,
+	IB_SA_ATTR_LINK_REC	     = 0x20,
+	IB_SA_ATTR_GUID_INFO_REC     = 0x30,
+	IB_SA_ATTR_SERVICE_REC	     = 0x31,
+	IB_SA_ATTR_PARTITION_REC     = 0x33,
+	IB_SA_ATTR_RANGE_REC	     = 0x34,
+	IB_SA_ATTR_PATH_REC	     = 0x35,
+	IB_SA_ATTR_VL_ARB_REC	     = 0x36,
+	IB_SA_ATTR_MC_GROUP_REC	     = 0x37,
+	IB_SA_ATTR_MC_MEMBER_REC     = 0x38,
+	IB_SA_ATTR_TRACE_REC	     = 0x39,
+	IB_SA_ATTR_MULTI_PATH_REC    = 0x3a,
+	IB_SA_ATTR_SERVICE_ASSOC_REC = 0x3b
+};
+
+#define PATH_REC_FIELD(field) \
+	.struct_offset_bytes = offsetof(struct ib_sa_path_rec, field),		\
+	.struct_size_bytes   = sizeof ((struct ib_sa_path_rec *) 0)->field,	\
+	.field_name          = "sa_path_rec:" #field
+
+static const struct ib_field path_rec_table[] = {
+	{ RESERVED,
+	  .offset_words = 0,
+	  .offset_bits  = 0,
+	  .size_bits    = 32 },
+	{ RESERVED,
+	  .offset_words = 1,
+	  .offset_bits  = 0,
+	  .size_bits    = 32 },
+	{ PATH_REC_FIELD(dgid),
+	  .offset_words = 2,
+	  .offset_bits  = 0,
+	  .size_bits    = 128 },
+	{ PATH_REC_FIELD(sgid),
+	  .offset_words = 6,
+	  .offset_bits  = 0,
+	  .size_bits    = 128 },
+	{ PATH_REC_FIELD(dlid),
+	  .offset_words = 10,
+	  .offset_bits  = 0,
+	  .size_bits    = 16 },
+	{ PATH_REC_FIELD(slid),
+	  .offset_words = 10,
+	  .offset_bits  = 16,
+	  .size_bits    = 16 },
+	{ PATH_REC_FIELD(raw_traffic),
+	  .offset_words = 11,
+	  .offset_bits  = 0,
+	  .size_bits    = 1 },
+	{ RESERVED,
+	  .offset_words = 11,
+	  .offset_bits  = 1,
+	  .size_bits    = 3 },
+	{ PATH_REC_FIELD(flow_label),
+	  .offset_words = 11,
+	  .offset_bits  = 4,
+	  .size_bits    = 20 },
+	{ PATH_REC_FIELD(hop_limit),
+	  .offset_words = 11,
+	  .offset_bits  = 24,
+	  .size_bits    = 8 },
+	{ PATH_REC_FIELD(traffic_class),
+	  .offset_words = 12,
+	  .offset_bits  = 0,
+	  .size_bits    = 8 },
+	{ PATH_REC_FIELD(reversible),
+	  .offset_words = 12,
+	  .offset_bits  = 8,
+	  .size_bits    = 1 },
+	{ PATH_REC_FIELD(numb_path),
+	  .offset_words = 12,
+	  .offset_bits  = 9,
+	  .size_bits    = 7 },
+	{ PATH_REC_FIELD(pkey),
+	  .offset_words = 12,
+	  .offset_bits  = 16,
+	  .size_bits    = 16 },
+	{ RESERVED,
+	  .offset_words = 13,
+	  .offset_bits  = 0,
+	  .size_bits    = 12 },
+	{ PATH_REC_FIELD(sl),
+	  .offset_words = 13,
+	  .offset_bits  = 12,
+	  .size_bits    = 4 },
+	{ PATH_REC_FIELD(mtu_selector),
+	  .offset_words = 13,
+	  .offset_bits  = 16,
+	  .size_bits    = 2 },
+	{ PATH_REC_FIELD(mtu),
+	  .offset_words = 13,
+	  .offset_bits  = 18,
+	  .size_bits    = 6 },
+	{ PATH_REC_FIELD(rate_selector),
+	  .offset_words = 13,
+	  .offset_bits  = 24,
+	  .size_bits    = 2 },
+	{ PATH_REC_FIELD(rate),
+	  .offset_words = 13,
+	  .offset_bits  = 26,
+	  .size_bits    = 6 },
+	{ PATH_REC_FIELD(packet_life_time_selector),
+	  .offset_words = 14,
+	  .offset_bits  = 0,
+	  .size_bits    = 2 },
+	{ PATH_REC_FIELD(packet_life_time),
+	  .offset_words = 14,
+	  .offset_bits  = 2,
+	  .size_bits    = 6 },
+	{ PATH_REC_FIELD(preference),
+	  .offset_words = 14,
+	  .offset_bits  = 8,
+	  .size_bits    = 8 },
+	{ RESERVED,
+	  .offset_words = 14,
+	  .offset_bits  = 16,
+	  .size_bits    = 48 },
+};
+
+#define MCMEMBER_REC_FIELD(field) \
+	.struct_offset_bytes = offsetof(struct ib_sa_mcmember_rec, field),	\
+	.struct_size_bytes   = sizeof ((struct ib_sa_mcmember_rec *) 0)->field,	\
+	.field_name          = "sa_mcmember_rec:" #field
+
+static const struct ib_field mcmember_rec_table[] = {
+	{ MCMEMBER_REC_FIELD(mgid),
+	  .offset_words = 0,
+	  .offset_bits  = 0,
+	  .size_bits    = 128 },
+	{ MCMEMBER_REC_FIELD(port_gid),
+	  .offset_words = 4,
+	  .offset_bits  = 0,
+	  .size_bits    = 128 },
+	{ MCMEMBER_REC_FIELD(qkey),
+	  .offset_words = 8,
+	  .offset_bits  = 0,
+	  .size_bits    = 32 },
+	{ MCMEMBER_REC_FIELD(mlid),
+	  .offset_words = 9,
+	  .offset_bits  = 0,
+	  .size_bits    = 16 },
+	{ MCMEMBER_REC_FIELD(mtu_selector),
+	  .offset_words = 9,
+	  .offset_bits  = 16,
+	  .size_bits    = 2 },
+	{ MCMEMBER_REC_FIELD(mtu),
+	  .offset_words = 9,
+	  .offset_bits  = 18,
+	  .size_bits    = 6 },
+	{ MCMEMBER_REC_FIELD(traffic_class),
+	  .offset_words = 9,
+	  .offset_bits  = 24,
+	  .size_bits    = 8 },
+	{ MCMEMBER_REC_FIELD(pkey),
+	  .offset_words = 10,
+	  .offset_bits  = 0,
+	  .size_bits    = 16 },
+	{ MCMEMBER_REC_FIELD(rate_selector),
+	  .offset_words = 10,
+	  .offset_bits  = 16,
+	  .size_bits    = 2 },
+	{ MCMEMBER_REC_FIELD(rate),
+	  .offset_words = 10,
+	  .offset_bits  = 18,
+	  .size_bits    = 6 },
+	{ MCMEMBER_REC_FIELD(packet_life_time_selector),
+	  .offset_words = 10,
+	  .offset_bits  = 24,
+	  .size_bits    = 2 },
+	{ MCMEMBER_REC_FIELD(packet_life_time),
+	  .offset_words = 10,
+	  .offset_bits  = 26,
+	  .size_bits    = 6 },
+	{ MCMEMBER_REC_FIELD(sl),
+	  .offset_words = 11,
+	  .offset_bits  = 0,
+	  .size_bits    = 4 },
+	{ MCMEMBER_REC_FIELD(flow_label),
+	  .offset_words = 11,
+	  .offset_bits  = 4,
+	  .size_bits    = 20 },
+	{ MCMEMBER_REC_FIELD(hop_limit),
+	  .offset_words = 11,
+	  .offset_bits  = 24,
+	  .size_bits    = 8 },
+	{ MCMEMBER_REC_FIELD(scope),
+	  .offset_words = 12,
+	  .offset_bits  = 0,
+	  .size_bits    = 4 },
+	{ MCMEMBER_REC_FIELD(join_state),
+	  .offset_words = 12,
+	  .offset_bits  = 4,
+	  .size_bits    = 4 },
+	{ MCMEMBER_REC_FIELD(proxy_join),
+	  .offset_words = 12,
+	  .offset_bits  = 8,
+	  .size_bits    = 1 },
+	{ RESERVED,
+	  .offset_words = 12,
+	  .offset_bits  = 9,
+	  .size_bits    = 23 },
+};
+
+static void free_sm_ah(struct kref *kref)
+{
+	struct ib_sa_sm_ah *sm_ah = container_of(kref, struct ib_sa_sm_ah, ref);
+
+	ib_destroy_ah(sm_ah->ah);
+	kfree(sm_ah);
+}
+
+static void update_sm_ah(void *port_ptr)
+{
+	struct ib_sa_port *port = port_ptr;
+	struct ib_sa_sm_ah *new_ah, *old_ah;
+	struct ib_port_attr port_attr;
+	struct ib_ah_attr   ah_attr;
+
+	if (ib_query_port(port->agent->device, port->port_num, &port_attr)) {
+		printk(KERN_WARNING "Couldn't query port\n");
+		return;
+	}
+
+	new_ah = kmalloc(sizeof *new_ah, GFP_KERNEL);
+	if (!new_ah) {
+		printk(KERN_WARNING "Couldn't allocate new SM AH\n");
+		return;
+	}
+
+	kref_init(&new_ah->ref);
+
+	memset(&ah_attr, 0, sizeof ah_attr);
+	ah_attr.dlid     = port_attr.sm_lid;
+	ah_attr.sl       = port_attr.sm_sl;
+	ah_attr.port_num = port->port_num;
+
+	new_ah->ah = ib_create_ah(port->agent->qp->pd, &ah_attr);
+	if (IS_ERR(new_ah->ah)) {
+		printk(KERN_WARNING "Couldn't create new SM AH\n");
+		kfree(new_ah);
+		return;
+	}
+
+	spin_lock_irq(&port->ah_lock);
+	old_ah = port->sm_ah;
+	port->sm_ah = new_ah;
+	spin_unlock_irq(&port->ah_lock);
+
+	if (old_ah)
+		kref_put(&old_ah->ref, free_sm_ah);
+}
+
+static void ib_sa_event(struct ib_event_handler *handler, struct ib_event *event)
+{
+	if (event->event == IB_EVENT_PORT_ERR    ||
+	    event->event == IB_EVENT_PORT_ACTIVE ||
+	    event->event == IB_EVENT_LID_CHANGE  ||
+	    event->event == IB_EVENT_PKEY_CHANGE ||
+	    event->event == IB_EVENT_SM_CHANGE) {
+		struct ib_sa_device *sa_dev =
+			ib_get_client_data(event->device, &sa_client);
+
+		schedule_work(&sa_dev->port[event->element.port_num -
+					    sa_dev->start_port].update_task);
+	}
+}
+
+/**
+ * ib_sa_cancel_query - try to cancel an SA query
+ * @id:ID of query to cancel
+ * @query:query pointer to cancel
+ *
+ * Try to cancel an SA query.  If the id and query don't match up or
+ * the query has already completed, nothing is done.  Otherwise the
+ * query is canceled and will complete with a status of -EINTR.
+ */
+void ib_sa_cancel_query(int id, struct ib_sa_query *query)
+{
+	unsigned long flags;
+	struct ib_mad_agent *agent;
+
+	spin_lock_irqsave(&idr_lock, flags);
+	if (idr_find(&query_idr, id) != query) {
+		spin_unlock_irqrestore(&idr_lock, flags);
+		return;
+	}
+	agent = query->port->agent;
+	spin_unlock_irqrestore(&idr_lock, flags);
+
+	ib_cancel_mad(agent, id);
+}
+EXPORT_SYMBOL(ib_sa_cancel_query);
+
+static void init_mad(struct ib_sa_mad *mad, struct ib_mad_agent *agent)
+{
+	unsigned long flags;
+
+	memset(mad, 0, sizeof *mad);
+
+	mad->mad_hdr.base_version  = IB_MGMT_BASE_VERSION;
+	mad->mad_hdr.mgmt_class    = IB_MGMT_CLASS_SUBN_ADM;
+	mad->mad_hdr.class_version = IB_SA_CLASS_VERSION;
+
+	spin_lock_irqsave(&tid_lock, flags);
+	mad->mad_hdr.tid           =
+		cpu_to_be64(((u64) agent->hi_tid) << 32 | tid++);
+	spin_unlock_irqrestore(&tid_lock, flags);
+}
+
+static int send_mad(struct ib_sa_query *query, int timeout_ms)
+{
+	struct ib_sa_port *port = query->port;
+	unsigned long flags;
+	int ret;
+	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,
+		.wr	     = {
+			 .ud = {
+				 .mad_hdr     = &query->mad->mad_hdr,
+				 .remote_qpn  = 1,
+				 .remote_qkey = IB_QP1_QKEY,
+				 .timeout_ms  = timeout_ms
+			 }
+		 }
+	};
+
+retry:
+	if (!idr_pre_get(&query_idr, GFP_ATOMIC))
+		return -ENOMEM;
+	spin_lock_irqsave(&idr_lock, flags);
+	ret = idr_get_new(&query_idr, query, &query->id);
+	spin_unlock_irqrestore(&idr_lock, flags);
+	if (ret == -EAGAIN)
+		goto retry;
+	if (ret)
+		return ret;
+
+	wr.wr_id = query->id;
+
+	spin_lock_irqsave(&port->ah_lock, flags);
+	kref_get(&port->sm_ah->ref);
+	query->sm_ah = port->sm_ah;
+	wr.wr.ud.ah  = port->sm_ah->ah;
+	spin_unlock_irqrestore(&port->ah_lock, flags);
+
+	gather_list.addr   = dma_map_single(port->agent->device->dma_device,
+					    query->mad,
+					    sizeof (struct ib_sa_mad),
+					    DMA_TO_DEVICE);
+	gather_list.length = sizeof (struct ib_sa_mad);
+	gather_list.lkey   = port->mr->lkey;
+	pci_unmap_addr_set(query, mapping, gather_list.addr);
+
+	ret = ib_post_send_mad(port->agent, &wr, &bad_wr);
+	if (ret) {
+		dma_unmap_single(port->agent->device->dma_device,
+				 pci_unmap_addr(query, mapping),
+				 sizeof (struct ib_sa_mad),
+				 DMA_TO_DEVICE);
+		kref_put(&query->sm_ah->ref, free_sm_ah);
+		spin_lock_irqsave(&idr_lock, flags);
+		idr_remove(&query_idr, query->id);
+		spin_unlock_irqrestore(&idr_lock, flags);
+	}
+
+	return ret;
+}
+
+static void ib_sa_path_rec_callback(struct ib_sa_query *sa_query,
+				    int status,
+				    struct ib_sa_mad *mad)
+{
+	struct ib_sa_path_query *query =
+		container_of(sa_query, struct ib_sa_path_query, sa_query);
+
+	if (mad) {
+		struct ib_sa_path_rec rec;
+
+		ib_unpack(path_rec_table, ARRAY_SIZE(path_rec_table),
+			  mad->data, &rec);
+		query->callback(status, &rec, query->context);
+	} else
+		query->callback(status, NULL, query->context);
+}
+
+static void ib_sa_path_rec_release(struct ib_sa_query *sa_query)
+{
+	kfree(sa_query->mad);
+	kfree(container_of(sa_query, struct ib_sa_path_query, sa_query));
+}
+
+/**
+ * ib_sa_path_rec_get - Start a Path get query
+ * @device:device to send query on
+ * @port_num: port number to send query on
+ * @rec:Path Record to send in query
+ * @comp_mask:component mask to send in query
+ * @timeout_ms:time to wait for response
+ * @gfp_mask:GFP mask to use for internal allocations
+ * @callback:function called when query completes, times out or is
+ * canceled
+ * @context:opaque user context passed to callback
+ * @sa_query:query context, used to cancel query
+ *
+ * Send a Path Record Get query to the SA to look up a path.  The
+ * callback function will be called when the query 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_path_rec_get() is negative, it is an
+ * error code.  Otherwise it is a query ID that can be used to cancel
+ * the query.
+ */
+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,
+		       void (*callback)(int status,
+					struct ib_sa_path_rec *resp,
+					void *context),
+		       void *context,
+		       struct ib_sa_query **sa_query)
+{
+	struct ib_sa_path_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;
+
+	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              = ib_sa_path_rec_callback;
+	query->sa_query.release               = ib_sa_path_rec_release;
+	query->sa_query.port                  = port;
+	query->sa_query.mad->mad_hdr.method   = IB_MGMT_METHOD_GET;
+	query->sa_query.mad->mad_hdr.attr_id  = cpu_to_be16(IB_SA_ATTR_PATH_REC);
+	query->sa_query.mad->sa_hdr.comp_mask = comp_mask;
+
+	ib_pack(path_rec_table, ARRAY_SIZE(path_rec_table),
+		rec, query->sa_query.mad->data);
+
+	*sa_query = &query->sa_query;
+	ret = send_mad(&query->sa_query, timeout_ms);
+	if (ret) {
+		*sa_query = NULL;
+		kfree(query->sa_query.mad);
+		kfree(query);
+	}
+
+	return ret ? ret : query->sa_query.id;
+}
+EXPORT_SYMBOL(ib_sa_path_rec_get);
+
+static void ib_sa_mcmember_rec_callback(struct ib_sa_query *sa_query,
+					int status,
+					struct ib_sa_mad *mad)
+{
+	struct ib_sa_mcmember_query *query =
+		container_of(sa_query, struct ib_sa_mcmember_query, sa_query);
+
+	if (mad) {
+		struct ib_sa_mcmember_rec rec;
+
+		ib_unpack(mcmember_rec_table, ARRAY_SIZE(mcmember_rec_table),
+			  mad->data, &rec);
+		query->callback(status, &rec, query->context);
+	} else
+		query->callback(status, NULL, query->context);
+}
+
+static void ib_sa_mcmember_rec_release(struct ib_sa_query *sa_query)
+{
+	kfree(sa_query->mad);
+	kfree(container_of(sa_query, struct ib_sa_mcmember_query, sa_query));
+}
+
+int ib_sa_mcmember_rec_query(struct ib_device *device, u8 port_num,
+			     u8 method,
+			     struct ib_sa_mcmember_rec *rec,
+			     ib_sa_comp_mask comp_mask,
+			     int timeout_ms, int gfp_mask,
+			     void (*callback)(int status,
+					      struct ib_sa_mcmember_rec *resp,
+					      void *context),
+			     void *context,
+			     struct ib_sa_query **sa_query)
+{
+	struct ib_sa_mcmember_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;
+
+	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              = ib_sa_mcmember_rec_callback;
+	query->sa_query.release               = ib_sa_mcmember_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_MC_MEMBER_REC);
+	query->sa_query.mad->sa_hdr.comp_mask = comp_mask;
+
+	ib_pack(mcmember_rec_table, ARRAY_SIZE(mcmember_rec_table),
+		rec, query->sa_query.mad->data);
+
+	*sa_query = &query->sa_query;
+	ret = send_mad(&query->sa_query, timeout_ms);
+	if (ret) {
+		*sa_query = NULL;
+		kfree(query->sa_query.mad);
+		kfree(query);
+	}
+
+	return ret ? ret : query->sa_query.id;
+}
+EXPORT_SYMBOL(ib_sa_mcmember_rec_query);
+
+static void send_handler(struct ib_mad_agent *agent,
+			 struct ib_mad_send_wc *mad_send_wc)
+{
+	struct ib_sa_query *query;
+	unsigned long flags;
+
+	spin_lock_irqsave(&idr_lock, flags);
+	query = idr_find(&query_idr, mad_send_wc->wr_id);
+	spin_unlock_irqrestore(&idr_lock, flags);
+
+	if (!query)
+		return;
+
+	switch (mad_send_wc->status) {
+	case IB_WC_SUCCESS:
+		/* No callback -- already got recv */
+		break;
+	case IB_WC_RESP_TIMEOUT_ERR:
+		query->callback(query, -ETIMEDOUT, NULL);
+		break;
+	case IB_WC_WR_FLUSH_ERR:
+		query->callback(query, -EINTR, NULL);
+		break;
+	default:
+		query->callback(query, -EIO, NULL);
+		break;
+	}
+
+	dma_unmap_single(agent->device->dma_device,
+			 pci_unmap_addr(query, mapping),
+			 sizeof (struct ib_sa_mad),
+			 DMA_TO_DEVICE);
+	kref_put(&query->sm_ah->ref, free_sm_ah);
+
+	query->release(query);
+
+	spin_lock_irqsave(&idr_lock, flags);
+	idr_remove(&query_idr, mad_send_wc->wr_id);
+	spin_unlock_irqrestore(&idr_lock, flags);
+}
+
+static void recv_handler(struct ib_mad_agent *mad_agent,
+			 struct ib_mad_recv_wc *mad_recv_wc)
+{
+	struct ib_sa_query *query;
+	unsigned long flags;
+
+	spin_lock_irqsave(&idr_lock, flags);
+	query = idr_find(&query_idr, mad_recv_wc->wc->wr_id);
+	spin_unlock_irqrestore(&idr_lock, flags);
+
+	if (query) {
+		if (mad_recv_wc->wc->status == IB_WC_SUCCESS)
+			query->callback(query,
+					mad_recv_wc->recv_buf.mad->mad_hdr.status ?
+					-EINVAL : 0,
+					(struct ib_sa_mad *) mad_recv_wc->recv_buf.mad);
+		else
+			query->callback(query, -EIO, NULL);
+	}
+
+	ib_free_recv_mad(mad_recv_wc);
+}
+
+static void ib_sa_add_one(struct ib_device *device)
+{
+	struct ib_sa_device *sa_dev;
+	int s, e, i;
+
+	if (device->node_type == IB_NODE_SWITCH)
+		s = e = 0;
+	else {
+		s = 1;
+		e = device->phys_port_cnt;
+	}
+
+	sa_dev = kmalloc(sizeof *sa_dev +
+			 (e - s + 1) * sizeof (struct ib_sa_port),
+			 GFP_KERNEL);
+	if (!sa_dev)
+		return;
+
+	sa_dev->start_port = s;
+	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);
+
+		sa_dev->port[i].agent =
+			ib_register_mad_agent(device, i + s, IB_QPT_GSI,
+					      NULL, 0, send_handler,
+					      recv_handler, sa_dev);
+		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]);
+	}
+
+	ib_set_client_data(device, &sa_client, sa_dev);
+
+	/*
+	 * We register our event handler after everything is set up,
+	 * and then update our cached info after the event handler is
+	 * registered to avoid any problems if a port changes state
+	 * during our initialization.
+	 */
+
+	INIT_IB_EVENT_HANDLER(&sa_dev->event_handler, device, ib_sa_event);
+	if (ib_register_event_handler(&sa_dev->event_handler))
+		goto err;
+
+	for (i = 0; i <= e - s; ++i)
+		update_sm_ah(&sa_dev->port[i]);
+
+	return;
+
+err:
+	while (--i >= 0) {
+		ib_dereg_mr(sa_dev->port[i].mr);
+		ib_unregister_mad_agent(sa_dev->port[i].agent);
+	}
+
+	kfree(sa_dev);
+
+	return;
+}
+
+static void ib_sa_remove_one(struct ib_device *device)
+{
+	struct ib_sa_device *sa_dev = ib_get_client_data(device, &sa_client);
+	int i;
+
+	if (!sa_dev)
+		return;
+
+	ib_unregister_event_handler(&sa_dev->event_handler);
+
+	for (i = 0; i <= sa_dev->end_port - sa_dev->start_port; ++i) {
+		ib_unregister_mad_agent(sa_dev->port[i].agent);
+		kref_put(&sa_dev->port[i].sm_ah->ref, free_sm_ah);
+	}
+
+	kfree(sa_dev);
+}
+
+static int __init ib_sa_init(void)
+{
+	int ret;
+
+	spin_lock_init(&idr_lock);
+	spin_lock_init(&tid_lock);
+
+	get_random_bytes(&tid, sizeof tid);
+
+	ret = ib_register_client(&sa_client);
+	if (ret)
+		printk(KERN_ERR "Couldn't register ib_sa client\n");
+
+	return ret;
+}
+
+static void __exit ib_sa_cleanup(void)
+{
+	ib_unregister_client(&sa_client);
+}
+
+module_init(ib_sa_init);
+module_exit(ib_sa_cleanup);
diff -Nru a/drivers/infiniband/core/smi.c b/drivers/infiniband/core/smi.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/infiniband/core/smi.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,234 @@
+/*
+ * Copyright (c) 2004 Mellanox Technologies Ltd.  All rights reserved.
+ * Copyright (c) 2004 Infinicon Corporation.  All rights reserved.
+ * 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 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: smi.c 1389 2004-12-27 22:56:47Z roland $
+ */
+
+#include <ib_smi.h>
+
+
+/*
+ * Fixup a directed route SMP for sending
+ * Return 0 if the SMP should be discarded
+ */
+int smi_handle_dr_smp_send(struct ib_smp *smp,
+			   u8 node_type,
+			   int port_num)
+{
+	u8 hop_ptr, hop_cnt;
+
+	hop_ptr = smp->hop_ptr;
+	hop_cnt = smp->hop_cnt;
+
+	/* See section 14.2.2.2, Vol 1 IB spec */
+	if (!ib_get_smp_direction(smp)) {
+		/* C14-9:1 */
+		if (hop_cnt && hop_ptr == 0) {
+			smp->hop_ptr++;
+			return (smp->initial_path[smp->hop_ptr] ==
+				port_num);
+		}
+
+		/* C14-9:2 */
+		if (hop_ptr && hop_ptr < hop_cnt) {
+			if (node_type != IB_NODE_SWITCH)
+				return 0;
+
+			/* smp->return_path set when received */
+			smp->hop_ptr++;
+			return (smp->initial_path[smp->hop_ptr] ==
+				port_num);
+		}
+
+		/* C14-9:3 -- We're at the end of the DR segment of path */
+		if (hop_ptr == hop_cnt) {
+			/* smp->return_path set when received */
+			smp->hop_ptr++;
+			return (node_type == IB_NODE_SWITCH ||
+				smp->dr_dlid == IB_LID_PERMISSIVE);
+		}
+
+		/* C14-9:4 -- hop_ptr = hop_cnt + 1 -> give to SMA/SM */
+		/* C14-9:5 -- Fail unreasonable hop pointer */
+		return (hop_ptr == hop_cnt + 1);
+
+	} else {
+		/* C14-13:1 */
+		if (hop_cnt && hop_ptr == hop_cnt + 1) {
+			smp->hop_ptr--;
+			return (smp->return_path[smp->hop_ptr] ==
+				port_num);
+		}
+
+		/* C14-13:2 */
+		if (2 <= hop_ptr && hop_ptr <= hop_cnt) {
+			if (node_type != IB_NODE_SWITCH)
+				return 0;
+
+			smp->hop_ptr--;
+			return (smp->return_path[smp->hop_ptr] ==
+				port_num);
+		}
+
+		/* C14-13:3 -- at the end of the DR segment of path */
+		if (hop_ptr == 1) {
+			smp->hop_ptr--;
+			/* C14-13:3 -- SMPs destined for SM shouldn't be here */
+			return (node_type == IB_NODE_SWITCH ||
+				smp->dr_slid == IB_LID_PERMISSIVE);
+		}
+
+		/* C14-13:4 -- hop_ptr = 0 -> should have gone to SM */
+		if (hop_ptr == 0)
+			return 1;
+
+		/* C14-13:5 -- Check for unreasonable hop pointer */
+		return 0;
+	}
+}
+
+/*
+ * Adjust information for a received SMP
+ * Return 0 if the SMP should be dropped
+ */
+int smi_handle_dr_smp_recv(struct ib_smp *smp,
+			   u8 node_type,
+			   int port_num,
+			   int phys_port_cnt)
+{
+	u8 hop_ptr, hop_cnt;
+
+	hop_ptr = smp->hop_ptr;
+	hop_cnt = smp->hop_cnt;
+
+	/* See section 14.2.2.2, Vol 1 IB spec */
+	if (!ib_get_smp_direction(smp)) {
+		/* C14-9:1 -- sender should have incremented hop_ptr */
+		if (hop_cnt && hop_ptr == 0)
+			return 0;
+
+		/* C14-9:2 -- intermediate hop */
+		if (hop_ptr && hop_ptr < hop_cnt) {
+			if (node_type != IB_NODE_SWITCH)
+				return 0;
+
+			smp->return_path[hop_ptr] = port_num;
+			/* smp->hop_ptr updated when sending */
+			return (smp->initial_path[hop_ptr+1] <= phys_port_cnt);
+		}
+
+		/* C14-9:3 -- We're at the end of the DR segment of path */
+		if (hop_ptr == hop_cnt) {
+			if (hop_cnt)
+				smp->return_path[hop_ptr] = port_num;
+			/* smp->hop_ptr updated when sending */
+
+			return (node_type == IB_NODE_SWITCH ||
+				smp->dr_dlid == IB_LID_PERMISSIVE);
+		}
+
+		/* C14-9:4 -- hop_ptr = hop_cnt + 1 -> give to SMA/SM */
+		/* C14-9:5 -- fail unreasonable hop pointer */
+		return (hop_ptr == hop_cnt + 1);
+
+	} else {
+
+		/* C14-13:1 */
+		if (hop_cnt && hop_ptr == hop_cnt + 1) {
+			smp->hop_ptr--;
+			return (smp->return_path[smp->hop_ptr] ==
+				port_num);
+		}
+
+		/* C14-13:2 */
+		if (2 <= hop_ptr && hop_ptr <= hop_cnt) {
+			if (node_type != IB_NODE_SWITCH)
+				return 0;
+
+			/* smp->hop_ptr updated when sending */
+			return (smp->return_path[hop_ptr-1] <= phys_port_cnt);
+		}
+
+		/* C14-13:3 -- We're at the end of the DR segment of path */
+		if (hop_ptr == 1) {
+			if (smp->dr_slid == IB_LID_PERMISSIVE) {
+				/* giving SMP to SM - update hop_ptr */
+				smp->hop_ptr--;
+				return 1;
+			}
+			/* smp->hop_ptr updated when sending */
+			return (node_type == IB_NODE_SWITCH);
+		}
+
+		/* C14-13:4 -- hop_ptr = 0 -> give to SM */
+		/* C14-13:5 -- Check for unreasonable hop pointer */
+		return (hop_ptr == 0);
+	}
+}
+
+/*
+ * Return 1 if the received DR SMP should be forwarded to the send queue
+ * Return 0 if the SMP should be completed up the stack
+ */
+int smi_check_forward_dr_smp(struct ib_smp *smp)
+{
+	u8 hop_ptr, hop_cnt;
+
+	hop_ptr = smp->hop_ptr;
+	hop_cnt = smp->hop_cnt;
+
+	if (!ib_get_smp_direction(smp)) {
+		/* C14-9:2 -- intermediate hop */
+		if (hop_ptr && hop_ptr < hop_cnt)
+			return 1;
+
+		/* C14-9:3 -- at the end of the DR segment of path */
+		if (hop_ptr == hop_cnt)
+			return (smp->dr_dlid == IB_LID_PERMISSIVE);
+
+		/* C14-9:4 -- hop_ptr = hop_cnt + 1 -> give to SMA/SM */
+		if (hop_ptr == hop_cnt + 1)
+			return 1;
+	} else {
+		/* C14-13:2 */
+		if (2 <= hop_ptr && hop_ptr <= hop_cnt)
+			return 1;
+
+		/* C14-13:3 -- at the end of the DR segment of path */
+		if (hop_ptr == 1)
+			return (smp->dr_slid != IB_LID_PERMISSIVE);
+	}
+	return 0;
+}
diff -Nru a/drivers/infiniband/core/smi.h b/drivers/infiniband/core/smi.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/infiniband/core/smi.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2004 Mellanox Technologies Ltd.  All rights reserved.
+ * Copyright (c) 2004 Infinicon Corporation.  All rights reserved.
+ * 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 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: smi.h 1389 2004-12-27 22:56:47Z roland $
+ */
+
+#ifndef __SMI_H_
+#define __SMI_H_
+
+int smi_handle_dr_smp_recv(struct ib_smp *smp,
+			   u8 node_type,
+			   int port_num,
+			   int phys_port_cnt);
+extern int smi_check_forward_dr_smp(struct ib_smp *smp);
+extern int smi_handle_dr_smp_send(struct ib_smp *smp,
+				  u8 node_type,
+				  int port_num);
+extern int smi_check_local_dr_smp(struct ib_smp *smp,
+				  struct ib_device *device,
+				  int port_num);
+
+/*
+ * Return 1 if the SMP should be handled by the local SMA/SM via process_mad
+ */
+static inline int smi_check_local_smp(struct ib_mad_agent *mad_agent,
+                         	      struct ib_smp *smp)
+{
+	/* C14-9:3 -- We're at the end of the DR segment of path */
+	/* C14-9:4 -- Hop Pointer = Hop Count + 1 -> give to SMA/SM */
+	return ((mad_agent->device->process_mad &&
+		!ib_get_smp_direction(smp) &&
+		(smp->hop_ptr == smp->hop_cnt + 1)));
+}
+
+#endif	/* __SMI_H_ */
diff -Nru a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/infiniband/core/sysfs.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,762 @@
+/*
+ * Copyright (c) 2004, 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: sysfs.c 1349 2004-12-16 21:09:43Z roland $
+ */
+
+#include "core_priv.h"
+
+#include <ib_mad.h>
+
+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;
+};
+
+struct port_attribute {
+	struct attribute attr;
+	ssize_t (*show)(struct ib_port *, struct port_attribute *, char *buf);
+	ssize_t (*store)(struct ib_port *, struct port_attribute *,
+			 const char *buf, size_t count);
+};
+
+#define PORT_ATTR(_name, _mode, _show, _store) \
+struct port_attribute port_attr_##_name = __ATTR(_name, _mode, _show, _store)
+
+#define PORT_ATTR_RO(_name) \
+struct port_attribute port_attr_##_name = __ATTR_RO(_name)
+
+struct port_table_attribute {
+	struct port_attribute attr;
+	int                   index;
+};
+
+static ssize_t port_attr_show(struct kobject *kobj,
+			      struct attribute *attr, char *buf)
+{
+	struct port_attribute *port_attr =
+		container_of(attr, struct port_attribute, attr);
+	struct ib_port *p = container_of(kobj, struct ib_port, kobj);
+
+	if (!port_attr->show)
+		return 0;
+
+	return port_attr->show(p, port_attr, buf);
+}
+
+static struct sysfs_ops port_sysfs_ops = {
+	.show = port_attr_show
+};
+
+static ssize_t state_show(struct ib_port *p, struct port_attribute *unused,
+			  char *buf)
+{
+	struct ib_port_attr attr;
+	ssize_t ret;
+
+	static const char *state_name[] = {
+		[IB_PORT_NOP]		= "NOP",
+		[IB_PORT_DOWN]		= "DOWN",
+		[IB_PORT_INIT]		= "INIT",
+		[IB_PORT_ARMED]		= "ARMED",
+		[IB_PORT_ACTIVE]	= "ACTIVE",
+		[IB_PORT_ACTIVE_DEFER]	= "ACTIVE_DEFER"
+	};
+
+	ret = ib_query_port(p->ibdev, p->port_num, &attr);
+	if (ret)
+		return ret;
+
+	return sprintf(buf, "%d: %s\n", attr.state,
+		       attr.state >= 0 && attr.state <= ARRAY_SIZE(state_name) ?
+		       state_name[attr.state] : "UNKNOWN");
+}
+
+static ssize_t lid_show(struct ib_port *p, struct port_attribute *unused,
+			char *buf)
+{
+	struct ib_port_attr attr;
+	ssize_t ret;
+
+	ret = ib_query_port(p->ibdev, p->port_num, &attr);
+	if (ret)
+		return ret;
+
+	return sprintf(buf, "0x%x\n", attr.lid);
+}
+
+static ssize_t lid_mask_count_show(struct ib_port *p,
+				   struct port_attribute *unused,
+				   char *buf)
+{
+	struct ib_port_attr attr;
+	ssize_t ret;
+
+	ret = ib_query_port(p->ibdev, p->port_num, &attr);
+	if (ret)
+		return ret;
+
+	return sprintf(buf, "%d\n", attr.lmc);
+}
+
+static ssize_t sm_lid_show(struct ib_port *p, struct port_attribute *unused,
+			   char *buf)
+{
+	struct ib_port_attr attr;
+	ssize_t ret;
+
+	ret = ib_query_port(p->ibdev, p->port_num, &attr);
+	if (ret)
+		return ret;
+
+	return sprintf(buf, "0x%x\n", attr.sm_lid);
+}
+
+static ssize_t sm_sl_show(struct ib_port *p, struct port_attribute *unused,
+			  char *buf)
+{
+	struct ib_port_attr attr;
+	ssize_t ret;
+
+	ret = ib_query_port(p->ibdev, p->port_num, &attr);
+	if (ret)
+		return ret;
+
+	return sprintf(buf, "%d\n", attr.sm_sl);
+}
+
+static ssize_t cap_mask_show(struct ib_port *p, struct port_attribute *unused,
+			     char *buf)
+{
+	struct ib_port_attr attr;
+	ssize_t ret;
+
+	ret = ib_query_port(p->ibdev, p->port_num, &attr);
+	if (ret)
+		return ret;
+
+	return sprintf(buf, "0x%08x\n", attr.port_cap_flags);
+}
+
+static ssize_t rate_show(struct ib_port *p, struct port_attribute *unused,
+			 char *buf)
+{
+	struct ib_port_attr attr;
+	char *speed = "";
+	int rate;
+	ssize_t ret;
+
+	ret = ib_query_port(p->ibdev, p->port_num, &attr);
+	if (ret)
+		return ret;
+
+	switch (attr.active_speed) {
+	case 2: speed = " DDR"; break;
+	case 4: speed = " QDR"; break;
+	}
+
+	rate = 25 * ib_width_enum_to_int(attr.active_width) * attr.active_speed;
+	if (rate < 0)
+		return -EINVAL;
+
+	return sprintf(buf, "%d%s Gb/sec (%dX%s)\n",
+		       rate / 10, rate % 10 ? ".5" : "",
+		       ib_width_enum_to_int(attr.active_width), speed);
+}
+
+static ssize_t phys_state_show(struct ib_port *p, struct port_attribute *unused,
+			       char *buf)
+{
+	struct ib_port_attr attr;
+
+	ssize_t ret;
+
+	ret = ib_query_port(p->ibdev, p->port_num, &attr);
+	if (ret)
+		return ret;
+
+	switch (attr.phys_state) {
+	case 1:  return sprintf(buf, "1: Sleep\n");
+	case 2:  return sprintf(buf, "2: Polling\n");
+	case 3:  return sprintf(buf, "3: Disabled\n");
+	case 4:  return sprintf(buf, "4: PortConfigurationTraining\n");
+	case 5:  return sprintf(buf, "5: LinkUp\n");
+	case 6:  return sprintf(buf, "6: LinkErrorRecovery\n");
+	case 7:  return sprintf(buf, "7: Phy Test\n");
+	default: return sprintf(buf, "%d: <unknown>\n", attr.phys_state);
+	}
+}
+
+static PORT_ATTR_RO(state);
+static PORT_ATTR_RO(lid);
+static PORT_ATTR_RO(lid_mask_count);
+static PORT_ATTR_RO(sm_lid);
+static PORT_ATTR_RO(sm_sl);
+static PORT_ATTR_RO(cap_mask);
+static PORT_ATTR_RO(rate);
+static PORT_ATTR_RO(phys_state);
+
+static struct attribute *port_default_attrs[] = {
+	&port_attr_state.attr,
+	&port_attr_lid.attr,
+	&port_attr_lid_mask_count.attr,
+	&port_attr_sm_lid.attr,
+	&port_attr_sm_sl.attr,
+	&port_attr_cap_mask.attr,
+	&port_attr_rate.attr,
+	&port_attr_phys_state.attr,
+	NULL
+};
+
+static ssize_t show_port_gid(struct ib_port *p, struct port_attribute *attr,
+			     char *buf)
+{
+	struct port_table_attribute *tab_attr =
+		container_of(attr, struct port_table_attribute, attr);
+	union ib_gid gid;
+	ssize_t ret;
+
+	ret = ib_query_gid(p->ibdev, p->port_num, tab_attr->index, &gid);
+	if (ret)
+		return ret;
+
+	return sprintf(buf, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
+		       be16_to_cpu(((u16 *) gid.raw)[0]),
+		       be16_to_cpu(((u16 *) gid.raw)[1]),
+		       be16_to_cpu(((u16 *) gid.raw)[2]),
+		       be16_to_cpu(((u16 *) gid.raw)[3]),
+		       be16_to_cpu(((u16 *) gid.raw)[4]),
+		       be16_to_cpu(((u16 *) gid.raw)[5]),
+		       be16_to_cpu(((u16 *) gid.raw)[6]),
+		       be16_to_cpu(((u16 *) gid.raw)[7]));
+}
+
+static ssize_t show_port_pkey(struct ib_port *p, struct port_attribute *attr,
+			      char *buf)
+{
+	struct port_table_attribute *tab_attr =
+		container_of(attr, struct port_table_attribute, attr);
+	u16 pkey;
+	ssize_t ret;
+
+	ret = ib_query_pkey(p->ibdev, p->port_num, tab_attr->index, &pkey);
+	if (ret)
+		return ret;
+
+	return sprintf(buf, "0x%04x\n", pkey);
+}
+
+#define PORT_PMA_ATTR(_name, _counter, _width, _offset)			\
+struct port_table_attribute port_pma_attr_##_name = {			\
+	.attr  = __ATTR(_name, S_IRUGO, show_pma_counter, NULL),	\
+	.index = (_offset) | ((_width) << 16) | ((_counter) << 24)	\
+}
+
+static ssize_t show_pma_counter(struct ib_port *p, struct port_attribute *attr,
+				char *buf)
+{
+	struct port_table_attribute *tab_attr =
+		container_of(attr, struct port_table_attribute, attr);
+	int offset = tab_attr->index & 0xffff;
+	int width  = (tab_attr->index >> 16) & 0xff;
+	struct ib_mad *in_mad  = NULL;
+	struct ib_mad *out_mad = NULL;
+	ssize_t ret;
+
+	if (!p->ibdev->process_mad)
+		return sprintf(buf, "N/A (no PMA)\n");
+
+	in_mad  = kmalloc(sizeof *in_mad, GFP_KERNEL);
+	out_mad = kmalloc(sizeof *in_mad, GFP_KERNEL);
+	if (!in_mad || !out_mad) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	memset(in_mad, 0, sizeof *in_mad);
+	in_mad->mad_hdr.base_version  = 1;
+	in_mad->mad_hdr.mgmt_class    = IB_MGMT_CLASS_PERF_MGMT;
+	in_mad->mad_hdr.class_version = 1;
+	in_mad->mad_hdr.method        = IB_MGMT_METHOD_GET;
+	in_mad->mad_hdr.attr_id       = cpu_to_be16(0x12); /* PortCounters */
+
+	in_mad->data[41] = p->port_num;	/* PortSelect field */
+
+	if ((p->ibdev->process_mad(p->ibdev, IB_MAD_IGNORE_MKEY,
+		 p->port_num, NULL, NULL, in_mad, out_mad) &
+	     (IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY)) !=
+	    (IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY)) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	switch (width) {
+	case 4:
+		ret = sprintf(buf, "%u\n", (out_mad->data[40 + offset / 8] >>
+					    (offset % 4)) & 0xf);
+		break;
+	case 8:
+		ret = sprintf(buf, "%u\n", out_mad->data[40 + offset / 8]);
+		break;
+	case 16:
+		ret = sprintf(buf, "%u\n",
+			      be16_to_cpup((u16 *)(out_mad->data + 40 + offset / 8)));
+		break;
+	case 32:
+		ret = sprintf(buf, "%u\n",
+			      be32_to_cpup((u32 *)(out_mad->data + 40 + offset / 8)));
+		break;
+	default:
+		ret = 0;
+	}
+
+out:
+	kfree(in_mad);
+	kfree(out_mad);
+
+	return ret;
+}
+
+static PORT_PMA_ATTR(symbol_error		    ,  0, 16,  32);
+static PORT_PMA_ATTR(link_error_recovery	    ,  1,  8,  48);
+static PORT_PMA_ATTR(link_downed		    ,  2,  8,  56);
+static PORT_PMA_ATTR(port_rcv_errors		    ,  3, 16,  64);
+static PORT_PMA_ATTR(port_rcv_remote_physical_errors,  4, 16,  80);
+static PORT_PMA_ATTR(port_rcv_switch_relay_errors   ,  5, 16,  96);
+static PORT_PMA_ATTR(port_xmit_discards		    ,  6, 16, 112);
+static PORT_PMA_ATTR(port_xmit_constraint_errors    ,  7,  8, 128);
+static PORT_PMA_ATTR(port_rcv_constraint_errors	    ,  8,  8, 136);
+static PORT_PMA_ATTR(local_link_integrity_errors    ,  9,  4, 152);
+static PORT_PMA_ATTR(excessive_buffer_overrun_errors, 10,  4, 156);
+static PORT_PMA_ATTR(VL15_dropped		    , 11, 16, 176);
+static PORT_PMA_ATTR(port_xmit_data		    , 12, 32, 192);
+static PORT_PMA_ATTR(port_rcv_data		    , 13, 32, 224);
+static PORT_PMA_ATTR(port_xmit_packets		    , 14, 32, 256);
+static PORT_PMA_ATTR(port_rcv_packets		    , 15, 32, 288);
+
+static struct attribute *pma_attrs[] = {
+	&port_pma_attr_symbol_error.attr.attr,
+	&port_pma_attr_link_error_recovery.attr.attr,
+	&port_pma_attr_link_downed.attr.attr,
+	&port_pma_attr_port_rcv_errors.attr.attr,
+	&port_pma_attr_port_rcv_remote_physical_errors.attr.attr,
+	&port_pma_attr_port_rcv_switch_relay_errors.attr.attr,
+	&port_pma_attr_port_xmit_discards.attr.attr,
+	&port_pma_attr_port_xmit_constraint_errors.attr.attr,
+	&port_pma_attr_port_rcv_constraint_errors.attr.attr,
+	&port_pma_attr_local_link_integrity_errors.attr.attr,
+	&port_pma_attr_excessive_buffer_overrun_errors.attr.attr,
+	&port_pma_attr_VL15_dropped.attr.attr,
+	&port_pma_attr_port_xmit_data.attr.attr,
+	&port_pma_attr_port_rcv_data.attr.attr,
+	&port_pma_attr_port_xmit_packets.attr.attr,
+	&port_pma_attr_port_rcv_packets.attr.attr,
+	NULL
+};
+
+static struct attribute_group pma_group = {
+	.name  = "counters",
+	.attrs  = pma_attrs
+};
+
+static void ib_port_release(struct kobject *kobj)
+{
+	struct ib_port *p = container_of(kobj, struct ib_port, kobj);
+	struct attribute *a;
+	int i;
+
+	for (i = 0; (a = p->gid_attr[i]); ++i) {
+		kfree(a->name);
+		kfree(a);
+	}
+
+	for (i = 0; (a = p->pkey_attr[i]); ++i) {
+		kfree(a->name);
+		kfree(a);
+	}
+
+	kfree(p->gid_attr);
+	kfree(p);
+}
+
+static struct kobj_type port_type = {
+	.release       = ib_port_release,
+	.sysfs_ops     = &port_sysfs_ops,
+	.default_attrs = port_default_attrs
+};
+
+static void ib_device_release(struct class_device *cdev)
+{
+	struct ib_device *dev = container_of(cdev, struct ib_device, class_dev);
+
+	kfree(dev);
+}
+
+static int ib_device_hotplug(struct class_device *cdev, char **envp,
+			     int num_envp, char *buf, int size)
+{
+	struct ib_device *dev = container_of(cdev, struct ib_device, class_dev);
+	int i = 0, len = 0;
+
+	if (add_hotplug_env_var(envp, num_envp, &i, buf, size, &len,
+				"NAME=%s", dev->name))
+		return -ENOMEM;
+
+	/*
+	 * It might be nice to pass the node GUID to hotplug, but
+	 * right now the only way to get it is to query the device
+	 * provider, and this can crash during device removal because
+	 * we are will be running after driver removal has started.
+	 * We could add a node_guid field to struct ib_device, or we
+	 * could just let the hotplug script read the node GUID from
+	 * sysfs when devices are added.
+	 */
+
+	envp[i] = NULL;
+	return 0;
+}
+
+static int alloc_group(struct attribute ***attr,
+		       ssize_t (*show)(struct ib_port *,
+				       struct port_attribute *, char *buf),
+		       int len)
+{
+	struct port_table_attribute ***tab_attr =
+		(struct port_table_attribute ***) attr;
+	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;
+			goto err;
+		}
+
+		if (snprintf((*tab_attr)[i]->attr.attr.name, 8, "%d", i) >= 8) {
+			ret = -ENOMEM;
+			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;
+
+err:
+	for (i = 0; i < len; ++i) {
+		if ((*tab_attr)[i])
+			kfree((*tab_attr)[i]->attr.attr.name);
+		kfree((*tab_attr)[i]);
+	}
+
+	kfree(*tab_attr);
+
+	return ret;
+}
+
+static int add_port(struct ib_device *device, int port_num)
+{
+	struct ib_port *p;
+	struct ib_port_attr attr;
+	int i;
+	int ret;
+
+	ret = ib_query_port(device, port_num, &attr);
+	if (ret)
+		return ret;
+
+	p = kmalloc(sizeof *p, GFP_KERNEL);
+	if (!p)
+		return -ENOMEM;
+	memset(p, 0, sizeof *p);
+
+	p->ibdev      = device;
+	p->port_num   = port_num;
+	p->kobj.ktype = &port_type;
+
+	p->kobj.parent = kobject_get(&device->ports_parent);
+	if (!p->kobj.parent) {
+		ret = -EBUSY;
+		goto err;
+	}
+
+	ret = kobject_set_name(&p->kobj, "%d", port_num);
+	if (ret)
+		goto err_put;
+
+	ret = kobject_register(&p->kobj);
+	if (ret)
+		goto err_put;
+
+	ret = sysfs_create_group(&p->kobj, &pma_group);
+	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;
+
+	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;
+
+	ret = sysfs_create_group(&p->kobj, &p->pkey_group);
+	if (ret)
+		goto err_free_pkey;
+
+	list_add_tail(&p->kobj.entry, &device->port_list);
+
+	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]);
+	}
+
+	kfree(p->pkey_attr);
+
+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]);
+	}
+
+	kfree(p->gid_attr);
+
+err_remove_pma:
+	sysfs_remove_group(&p->kobj, &pma_group);
+
+err_put:
+	kobject_put(&device->ports_parent);
+
+err:
+	kfree(p);
+	return ret;
+}
+
+static ssize_t show_node_type(struct class_device *cdev, char *buf)
+{
+	struct ib_device *dev = container_of(cdev, struct ib_device, class_dev);
+
+	switch (dev->node_type) {
+	case IB_NODE_CA:     return sprintf(buf, "%d: CA\n", dev->node_type);
+	case IB_NODE_SWITCH: return sprintf(buf, "%d: switch\n", dev->node_type);
+	case IB_NODE_ROUTER: return sprintf(buf, "%d: router\n", dev->node_type);
+	default:             return sprintf(buf, "%d: <unknown>\n", dev->node_type);
+	}
+}
+
+static ssize_t show_sys_image_guid(struct class_device *cdev, char *buf)
+{
+	struct ib_device *dev = container_of(cdev, struct ib_device, class_dev);
+	struct ib_device_attr attr;
+	ssize_t ret;
+
+	ret = ib_query_device(dev, &attr);
+	if (ret)
+		return ret;
+
+	return sprintf(buf, "%04x:%04x:%04x:%04x\n",
+		       be16_to_cpu(((u16 *) &attr.sys_image_guid)[0]),
+		       be16_to_cpu(((u16 *) &attr.sys_image_guid)[1]),
+		       be16_to_cpu(((u16 *) &attr.sys_image_guid)[2]),
+		       be16_to_cpu(((u16 *) &attr.sys_image_guid)[3]));
+}
+
+static ssize_t show_node_guid(struct class_device *cdev, char *buf)
+{
+	struct ib_device *dev = container_of(cdev, struct ib_device, class_dev);
+	struct ib_device_attr attr;
+	ssize_t ret;
+
+	ret = ib_query_device(dev, &attr);
+	if (ret)
+		return ret;
+
+	return sprintf(buf, "%04x:%04x:%04x:%04x\n",
+		       be16_to_cpu(((u16 *) &attr.node_guid)[0]),
+		       be16_to_cpu(((u16 *) &attr.node_guid)[1]),
+		       be16_to_cpu(((u16 *) &attr.node_guid)[2]),
+		       be16_to_cpu(((u16 *) &attr.node_guid)[3]));
+}
+
+static CLASS_DEVICE_ATTR(node_type, S_IRUGO, show_node_type, NULL);
+static CLASS_DEVICE_ATTR(sys_image_guid, S_IRUGO, show_sys_image_guid, NULL);
+static CLASS_DEVICE_ATTR(node_guid, S_IRUGO, show_node_guid, NULL);
+
+static struct class_device_attribute *ib_class_attributes[] = {
+	&class_device_attr_node_type,
+	&class_device_attr_sys_image_guid,
+	&class_device_attr_node_guid
+};
+
+static struct class ib_class = {
+	.name    = "infiniband",
+	.release = ib_device_release,
+	.hotplug = ib_device_hotplug,
+};
+
+int ib_device_register_sysfs(struct ib_device *device)
+{
+	struct class_device *class_dev = &device->class_dev;
+	int ret;
+	int i;
+
+	class_dev->class      = &ib_class;
+	class_dev->class_data = device;
+	strlcpy(class_dev->class_id, device->name, BUS_ID_SIZE);
+
+	INIT_LIST_HEAD(&device->port_list);
+
+	ret = class_device_register(class_dev);
+	if (ret)
+		goto err;
+
+	for (i = 0; i < ARRAY_SIZE(ib_class_attributes); ++i) {
+		ret = class_device_create_file(class_dev, ib_class_attributes[i]);
+		if (ret)
+			goto err_unregister;
+	}
+
+	device->ports_parent.parent = kobject_get(&class_dev->kobj);
+	if (!device->ports_parent.parent) {
+		ret = -EBUSY;
+		goto err_unregister;
+	}
+	ret = kobject_set_name(&device->ports_parent, "ports");
+	if (ret)
+		goto err_put;
+	ret = kobject_register(&device->ports_parent);
+	if (ret)
+		goto err_put;
+
+	if (device->node_type == IB_NODE_SWITCH) {
+		ret = add_port(device, 0);
+		if (ret)
+			goto err_put;
+	} else {
+		int i;
+
+		for (i = 1; i <= device->phys_port_cnt; ++i) {
+			ret = add_port(device, i);
+			if (ret)
+				goto err_put;
+		}
+	}
+
+	return 0;
+
+err_put:
+	{
+		struct kobject *p, *t;
+		struct ib_port *port;
+
+		list_for_each_entry_safe(p, t, &device->port_list, entry) {
+			list_del(&p->entry);
+			port = container_of(p, struct ib_port, kobj);
+			sysfs_remove_group(p, &pma_group);
+			sysfs_remove_group(p, &port->pkey_group);
+			sysfs_remove_group(p, &port->gid_group);
+			kobject_unregister(p);
+		}
+	}
+
+	kobject_put(&class_dev->kobj);
+
+err_unregister:
+	class_device_unregister(class_dev);
+
+err:
+	return ret;
+}
+
+void ib_device_unregister_sysfs(struct ib_device *device)
+{
+	struct kobject *p, *t;
+	struct ib_port *port;
+
+	list_for_each_entry_safe(p, t, &device->port_list, entry) {
+		list_del(&p->entry);
+		port = container_of(p, struct ib_port, kobj);
+		sysfs_remove_group(p, &pma_group);
+		sysfs_remove_group(p, &port->pkey_group);
+		sysfs_remove_group(p, &port->gid_group);
+		kobject_unregister(p);
+	}
+
+	kobject_unregister(&device->ports_parent);
+	class_device_unregister(&device->class_dev);
+}
+
+int ib_sysfs_setup(void)
+{
+	return class_register(&ib_class);
+}
+
+void ib_sysfs_cleanup(void)
+{
+	class_unregister(&ib_class);
+}
diff -Nru a/drivers/infiniband/core/ud_header.c b/drivers/infiniband/core/ud_header.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/infiniband/core/ud_header.c	2005-03-01 23:39:26 -08:00
@@ -0,0 +1,365 @@
+/*
+ * Copyright (c) 2004 Topspin 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 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: ud_header.c 1349 2004-12-16 21:09:43Z roland $
+ */
+
+#include <linux/errno.h>
+
+#include <ib_pack.h>
+
+#define STRUCT_FIELD(header, field) \
+	.struct_offset_bytes = offsetof(struct ib_unpacked_ ## header, field),      \
+	.struct_size_bytes   = sizeof ((struct ib_unpacked_ ## header *) 0)->field, \
+	.field_name          = #header ":" #field
+
+static const struct ib_field lrh_table[]  = {
+	{ STRUCT_FIELD(lrh, virtual_lane),
+	  .offset_words = 0,
+	  .offset_bits  = 0,
+	  .size_bits    = 4 },
+	{ STRUCT_FIELD(lrh, link_version),
+	  .offset_words = 0,
+	  .offset_bits  = 4,
+	  .size_bits    = 4 },
+	{ STRUCT_FIELD(lrh, service_level),
+	  .offset_words = 0,
+	  .offset_bits  = 8,
+	  .size_bits    = 4 },
+	{ RESERVED,
+	  .offset_words = 0,
+	  .offset_bits  = 12,
+	  .size_bits    = 2 },
+	{ STRUCT_FIELD(lrh, link_next_header),
+	  .offset_words = 0,
+	  .offset_bits  = 14,
+	  .size_bits    = 2 },
+	{ STRUCT_FIELD(lrh, destination_lid),
+	  .offset_words = 0,
+	  .offset_bits  = 16,
+	  .size_bits    = 16 },
+	{ RESERVED,
+	  .offset_words = 1,
+	  .offset_bits  = 0,
+	  .size_bits    = 5 },
+	{ STRUCT_FIELD(lrh, packet_length),
+	  .offset_words = 1,
+	  .offset_bits  = 5,
+	  .size_bits    = 11 },
+	{ STRUCT_FIELD(lrh, source_lid),
+	  .offset_words = 1,
+	  .offset_bits  = 16,
+	  .size_bits    = 16 }
+};
+
+static const struct ib_field grh_table[]  = {
+	{ STRUCT_FIELD(grh, ip_version),
+	  .offset_words = 0,
+	  .offset_bits  = 0,
+	  .size_bits    = 4 },
+	{ STRUCT_FIELD(grh, traffic_class),
+	  .offset_words = 0,
+	  .offset_bits  = 4,
+	  .size_bits    = 8 },
+	{ STRUCT_FIELD(grh, flow_label),
+	  .offset_words = 0,
+	  .offset_bits  = 12,
+	  .size_bits    = 20 },
+	{ STRUCT_FIELD(grh, payload_length),
+	  .offset_words = 1,
+	  .offset_bits  = 0,
+	  .size_bits    = 16 },
+	{ STRUCT_FIELD(grh, next_header),
+	  .offset_words = 1,
+	  .offset_bits  = 16,
+	  .size_bits    = 8 },
+	{ STRUCT_FIELD(grh, hop_limit),
+	  .offset_words = 1,
+	  .offset_bits  = 24,
+	  .size_bits    = 8 },
+	{ STRUCT_FIELD(grh, source_gid),
+	  .offset_words = 2,
+	  .offset_bits  = 0,
+	  .size_bits    = 128 },
+	{ STRUCT_FIELD(grh, destination_gid),
+	  .offset_words = 6,
+	  .offset_bits  = 0,
+	  .size_bits    = 128 }
+};
+
+static const struct ib_field bth_table[]  = {
+	{ STRUCT_FIELD(bth, opcode),
+	  .offset_words = 0,
+	  .offset_bits  = 0,
+	  .size_bits    = 8 },
+	{ STRUCT_FIELD(bth, solicited_event),
+	  .offset_words = 0,
+	  .offset_bits  = 8,
+	  .size_bits    = 1 },
+	{ STRUCT_FIELD(bth, mig_req),
+	  .offset_words = 0,
+	  .offset_bits  = 9,
+	  .size_bits    = 1 },
+	{ STRUCT_FIELD(bth, pad_count),
+	  .offset_words = 0,
+	  .offset_bits  = 10,
+	  .size_bits    = 2 },
+	{ STRUCT_FIELD(bth, transport_header_version),
+	  .offset_words = 0,
+	  .offset_bits  = 12,
+	  .size_bits    = 4 },
+	{ STRUCT_FIELD(bth, pkey),
+	  .offset_words = 0,
+	  .offset_bits  = 16,
+	  .size_bits    = 16 },
+	{ RESERVED,
+	  .offset_words = 1,
+	  .offset_bits  = 0,
+	  .size_bits    = 8 },
+	{ STRUCT_FIELD(bth, destination_qpn),
+	  .offset_words = 1,
+	  .offset_bits  = 8,
+	  .size_bits    = 24 },
+	{ STRUCT_FIELD(bth, ack_req),
+	  .offset_words = 2,
+	  .offset_bits  = 0,
+	  .size_bits    = 1 },
+	{ RESERVED,
+	  .offset_words = 2,
+	  .offset_bits  = 1,
+	  .size_bits    = 7 },
+	{ STRUCT_FIELD(bth, psn),
+	  .offset_words = 2,
+	  .offset_bits  = 8,
+	  .size_bits    = 24 }
+};
+
+static const struct ib_field deth_table[] = {
+	{ STRUCT_FIELD(deth, qkey),
+	  .offset_words = 0,
+	  .offset_bits  = 0,
+	  .size_bits    = 32 },
+	{ RESERVED,
+	  .offset_words = 1,
+	  .offset_bits  = 0,
+	  .size_bits    = 8 },
+	{ STRUCT_FIELD(deth, source_qpn),
+	  .offset_words = 1,
+	  .offset_bits  = 8,
+	  .size_bits    = 24 }
+};
+
+/**
+ * ib_ud_header_init - Initialize UD header structure
+ * @payload_bytes:Length of packet payload
+ * @grh_present:GRH flag (if non-zero, GRH will be included)
+ * @header:Structure to initialize
+ *
+ * ib_ud_header_init() initializes the lrh.link_version, lrh.link_next_header,
+ * lrh.packet_length, grh.ip_version, grh.payload_length,
+ * grh.next_header, bth.opcode, bth.pad_count and
+ * bth.transport_header_version fields of a &struct ib_ud_header given
+ * the payload length and whether a GRH will be included.
+ */
+void ib_ud_header_init(int     		    payload_bytes,
+		       int    		    grh_present,
+		       struct ib_ud_header *header)
+{
+	int header_len;
+
+	memset(header, 0, sizeof *header);
+
+	header_len =
+		IB_LRH_BYTES  +
+		IB_BTH_BYTES  +
+		IB_DETH_BYTES;
+	if (grh_present) {
+		header_len += IB_GRH_BYTES;
+	}
+
+	header->lrh.link_version     = 0;
+	header->lrh.link_next_header =
+		grh_present ? IB_LNH_IBA_GLOBAL : IB_LNH_IBA_LOCAL;
+	header->lrh.packet_length    = (IB_LRH_BYTES     +
+					IB_BTH_BYTES     +
+					IB_DETH_BYTES    +
+					payload_bytes    +
+					4                + /* ICRC     */
+					3) / 4;            /* round up */
+
+	header->grh_present          = grh_present;
+	if (grh_present) {
+		header->lrh.packet_length  += IB_GRH_BYTES / 4;
+
+		header->grh.ip_version      = 6;
+		header->grh.payload_length  =
+			cpu_to_be16((IB_BTH_BYTES     +
+				     IB_DETH_BYTES    +
+				     payload_bytes    +
+				     4                + /* ICRC     */
+				     3) & ~3);          /* round up */
+		header->grh.next_header     = 0x1b;
+	}
+
+	cpu_to_be16s(&header->lrh.packet_length);
+
+	if (header->immediate_present)
+		header->bth.opcode           = IB_OPCODE_UD_SEND_ONLY_WITH_IMMEDIATE;
+	else
+		header->bth.opcode           = IB_OPCODE_UD_SEND_ONLY;
+	header->bth.pad_count                = (4 - payload_bytes) & 3;
+	header->bth.transport_header_version = 0;
+}
+EXPORT_SYMBOL(ib_ud_header_init);
+
+/**
+ * ib_ud_header_pack - Pack UD header struct into wire format
+ * @header:UD header struct
+ * @buf:Buffer to pack into
+ *
+ * ib_ud_header_pack() packs the UD header structure @header into wire
+ * format in the buffer @buf.
+ */
+int ib_ud_header_pack(struct ib_ud_header *header,
+		      void                *buf)
+{
+	int len = 0;
+
+	ib_pack(lrh_table, ARRAY_SIZE(lrh_table),
+		&header->lrh, buf);
+	len += IB_LRH_BYTES;
+
+	if (header->grh_present) {
+		ib_pack(grh_table, ARRAY_SIZE(grh_table),
+			&header->grh, buf + len);
+		len += IB_GRH_BYTES;
+	}
+
+	ib_pack(bth_table, ARRAY_SIZE(bth_table),
+		&header->bth, buf + len);
+	len += IB_BTH_BYTES;
+
+	ib_pack(deth_table, ARRAY_SIZE(deth_table),
+		&header->deth, buf + len);
+	len += IB_DETH_BYTES;
+
+	if (header->immediate_present) {
+		memcpy(buf + len, &header->immediate_data, sizeof header->immediate_data);
+		len += sizeof header->immediate_data;
+	}
+
+	return len;
+}
+EXPORT_SYMBOL(ib_ud_header_pack);
+
+/**
+ * ib_ud_header_unpack - Unpack UD header struct from wire format
+ * @header:UD header struct
+ * @buf:Buffer to pack into
+ *
+ * ib_ud_header_pack() unpacks the UD header structure @header from wire
+ * format in the buffer @buf.
+ */
+int ib_ud_header_unpack(void                *buf,
+			struct ib_ud_header *header)
+{
+	ib_unpack(lrh_table, ARRAY_SIZE(lrh_table),
+		  buf, &header->lrh);
+	buf += IB_LRH_BYTES;
+
+	if (header->lrh.link_version != 0) {
+		printk(KERN_WARNING "Invalid LRH.link_version %d\n",
+		       header->lrh.link_version);
+		return -EINVAL;
+	}
+
+	switch (header->lrh.link_next_header) {
+	case IB_LNH_IBA_LOCAL:
+		header->grh_present = 0;
+		break;
+
+	case IB_LNH_IBA_GLOBAL:
+		header->grh_present = 1;
+		ib_unpack(grh_table, ARRAY_SIZE(grh_table),
+			  buf, &header->grh);
+		buf += IB_GRH_BYTES;
+
+		if (header->grh.ip_version != 6) {
+			printk(KERN_WARNING "Invalid GRH.ip_version %d\n",
+			       header->grh.ip_version);
+			return -EINVAL;
+		}
+		if (header->grh.next_header != 0x1b) {
+			printk(KERN_WARNING "Invalid GRH.next_header 0x%02x\n",
+			       header->grh.next_header);
+			return -EINVAL;
+		}
+		break;
+
+	default:
+		printk(KERN_WARNING "Invalid LRH.link_next_header %d\n",
+		       header->lrh.link_next_header);
+		return -EINVAL;
+	}
+
+	ib_unpack(bth_table, ARRAY_SIZE(bth_table),
+		  buf, &header->bth);
+	buf += IB_BTH_BYTES;
+
+	switch (header->bth.opcode) {
+	case IB_OPCODE_UD_SEND_ONLY:
+		header->immediate_present = 0;
+		break;
+	case IB_OPCODE_UD_SEND_ONLY_WITH_IMMEDIATE:
+		header->immediate_present = 1;
+		break;
+	default:
+		printk(KERN_WARNING "Invalid BTH.opcode 0x%02x\n",
+		       header->bth.opcode);
+		return -EINVAL;
+	}
+
+	if (header->bth.transport_header_version != 0) {
+		printk(KERN_WARNING "Invalid BTH.transport_header_version %d\n",
+		       header->bth.transport_header_version);
+		return -EINVAL;
+	}
+
+	ib_unpack(deth_table, ARRAY_SIZE(deth_table),
+		  buf, &header->deth);
+	buf += IB_DETH_BYTES;
+
+	if (header->immediate_present)
+		memcpy(&header->immediate_data, buf, sizeof header->immediate_data);
+
+	return 0;
+}
+EXPORT_SYMBOL(ib_ud_header_unpack);
diff -Nru a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/infiniband/core/user_mad.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,840 @@
+/*
+ * Copyright (c) 2004 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: user_mad.c 1389 2004-12-27 22:56:47Z roland $
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/fs.h>
+#include <linux/cdev.h>
+#include <linux/pci.h>
+#include <linux/dma-mapping.h>
+#include <linux/poll.h>
+#include <linux/rwsem.h>
+#include <linux/kref.h>
+
+#include <asm/uaccess.h>
+#include <asm/semaphore.h>
+
+#include <ib_mad.h>
+#include <ib_user_mad.h>
+
+MODULE_AUTHOR("Roland Dreier");
+MODULE_DESCRIPTION("InfiniBand userspace MAD packet access");
+MODULE_LICENSE("Dual BSD/GPL");
+
+enum {
+	IB_UMAD_MAX_PORTS  = 64,
+	IB_UMAD_MAX_AGENTS = 32,
+
+	IB_UMAD_MAJOR      = 231,
+	IB_UMAD_MINOR_BASE = 0
+};
+
+struct ib_umad_port {
+	int                    devnum;
+	struct cdev            dev;
+	struct class_device    class_dev;
+
+	int                    sm_devnum;
+	struct cdev            sm_dev;
+	struct class_device    sm_class_dev;
+	struct semaphore       sm_sem;
+
+	struct ib_device      *ib_dev;
+	struct ib_umad_device *umad_dev;
+	u8                     port_num;
+};
+
+struct ib_umad_device {
+	int                  start_port, end_port;
+	struct kref          ref;
+	struct ib_umad_port  port[0];
+};
+
+struct ib_umad_file {
+	struct ib_umad_port *port;
+	spinlock_t           recv_lock;
+	struct list_head     recv_list;
+	wait_queue_head_t    recv_wait;
+	struct rw_semaphore  agent_mutex;
+	struct ib_mad_agent *agent[IB_UMAD_MAX_AGENTS];
+	struct ib_mr        *mr[IB_UMAD_MAX_AGENTS];
+};
+
+struct ib_umad_packet {
+	struct ib_user_mad mad;
+	struct ib_ah      *ah;
+	struct list_head   list;
+	DECLARE_PCI_UNMAP_ADDR(mapping)
+};
+
+static const dev_t base_dev = MKDEV(IB_UMAD_MAJOR, IB_UMAD_MINOR_BASE);
+static spinlock_t map_lock;
+static DECLARE_BITMAP(dev_map, IB_UMAD_MAX_PORTS * 2);
+
+static void ib_umad_add_one(struct ib_device *device);
+static void ib_umad_remove_one(struct ib_device *device);
+
+static int queue_packet(struct ib_umad_file *file,
+			struct ib_mad_agent *agent,
+			struct ib_umad_packet *packet)
+{
+	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]) {
+			spin_lock_irq(&file->recv_lock);
+			list_add_tail(&packet->list, &file->recv_list);
+			spin_unlock_irq(&file->recv_lock);
+			wake_up_interruptible(&file->recv_wait);
+			ret = 0;
+			break;
+		}
+
+	up_read(&file->agent_mutex);
+
+	return ret;
+}
+
+static void send_handler(struct ib_mad_agent *agent,
+			 struct ib_mad_send_wc *send_wc)
+{
+	struct ib_umad_file *file = agent->context;
+	struct ib_umad_packet *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);
+
+	if (send_wc->status == IB_WC_RESP_TIMEOUT_ERR) {
+		packet->mad.status = ETIMEDOUT;
+
+		if (!queue_packet(file, agent, packet))
+			return;
+	}
+
+	kfree(packet);
+}
+
+static void recv_handler(struct ib_mad_agent *agent,
+			 struct ib_mad_recv_wc *mad_recv_wc)
+{
+	struct ib_umad_file *file = agent->context;
+	struct ib_umad_packet *packet;
+
+	if (mad_recv_wc->wc->status != IB_WC_SUCCESS)
+		goto out;
+
+	packet = kmalloc(sizeof *packet, GFP_KERNEL);
+	if (!packet)
+		goto out;
+
+	memset(packet, 0, sizeof *packet);
+
+	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) {
+		/* 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;
+	}
+
+	if (queue_packet(file, agent, packet))
+		kfree(packet);
+
+out:
+	ib_free_recv_mad(mad_recv_wc);
+}
+
+static ssize_t ib_umad_read(struct file *filp, char __user *buf,
+			    size_t count, loff_t *pos)
+{
+	struct ib_umad_file *file = filp->private_data;
+	struct ib_umad_packet *packet;
+	ssize_t ret;
+
+	if (count < sizeof (struct ib_user_mad))
+		return -EINVAL;
+
+	spin_lock_irq(&file->recv_lock);
+
+	while (list_empty(&file->recv_list)) {
+		spin_unlock_irq(&file->recv_lock);
+
+		if (filp->f_flags & O_NONBLOCK)
+			return -EAGAIN;
+
+		if (wait_event_interruptible(file->recv_wait,
+					     !list_empty(&file->recv_list)))
+			return -ERESTARTSYS;
+
+		spin_lock_irq(&file->recv_lock);
+	}
+
+	packet = list_entry(file->recv_list.next, struct ib_umad_packet, list);
+	list_del(&packet->list);
+
+	spin_unlock_irq(&file->recv_lock);
+
+	if (copy_to_user(buf, &packet->mad, sizeof packet->mad))
+		ret = -EFAULT;
+	else
+		ret = sizeof packet->mad;
+
+	kfree(packet);
+	return ret;
+}
+
+static ssize_t ib_umad_write(struct file *filp, const char __user *buf,
+			     size_t count, loff_t *pos)
+{
+	struct ib_umad_file *file = filp->private_data;
+	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,
+	};
+	u8 method;
+	u64 *tid;
+	int ret;
+
+	if (count < sizeof (struct ib_user_mad))
+		return -EINVAL;
+
+	packet = kmalloc(sizeof *packet, GFP_KERNEL);
+	if (!packet)
+		return -ENOMEM;
+
+	if (copy_from_user(&packet->mad, buf, sizeof packet->mad)) {
+		kfree(packet);
+		return -EFAULT;
+	}
+
+	if (packet->mad.id < 0 || packet->mad.id >= IB_UMAD_MAX_AGENTS) {
+		ret = -EINVAL;
+		goto err;
+	}
+
+	down_read(&file->agent_mutex);
+
+	agent = file->agent[packet->mad.id];
+	if (!agent) {
+		ret = -EINVAL;
+		goto err_up;
+	}
+
+	/*
+	 * 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;
+
+	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 = 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;
+	}
+
+	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;
+
+	wr.wr_id            = (unsigned long) packet;
+
+	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;
+	}
+
+	up_read(&file->agent_mutex);
+
+	return sizeof packet->mad;
+
+err_up:
+	up_read(&file->agent_mutex);
+
+err:
+	kfree(packet);
+	return ret;
+}
+
+static unsigned int ib_umad_poll(struct file *filp, struct poll_table_struct *wait)
+{
+	struct ib_umad_file *file = filp->private_data;
+
+	/* we will always be able to post a MAD send */
+	unsigned int mask = POLLOUT | POLLWRNORM;
+
+	poll_wait(filp, &file->recv_wait, wait);
+
+	if (!list_empty(&file->recv_list))
+		mask |= POLLIN | POLLRDNORM;
+
+	return mask;
+}
+
+static int ib_umad_reg_agent(struct ib_umad_file *file, unsigned long arg)
+{
+	struct ib_user_mad_reg_req ureq;
+	struct ib_mad_reg_req req;
+	struct ib_mad_agent *agent;
+	int agent_id;
+	int ret;
+
+	down_write(&file->agent_mutex);
+
+	if (copy_from_user(&ureq, (void __user *) arg, sizeof ureq)) {
+		ret = -EFAULT;
+		goto out;
+	}
+
+	if (ureq.qpn != 0 && ureq.qpn != 1) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	for (agent_id = 0; agent_id < IB_UMAD_MAX_AGENTS; ++agent_id)
+		if (!file->agent[agent_id])
+			goto found;
+
+	ret = -ENOMEM;
+	goto out;
+
+found:
+	req.mgmt_class         = ureq.mgmt_class;
+	req.mgmt_class_version = ureq.mgmt_class_version;
+	memcpy(req.method_mask, ureq.method_mask, sizeof req.method_mask);
+	memcpy(req.oui,         ureq.oui,         sizeof req.oui);
+
+	agent = ib_register_mad_agent(file->port->ib_dev, file->port->port_num,
+				      ureq.qpn ? IB_QPT_GSI : IB_QPT_SMI,
+				      &req, 0, send_handler, recv_handler,
+				      file);
+	if (IS_ERR(agent)) {
+		ret = PTR_ERR(agent);
+		goto out;
+	}
+
+	file->agent[agent_id] = agent;
+
+	file->mr[agent_id] = ib_get_dma_mr(agent->qp->pd, IB_ACCESS_LOCAL_WRITE);
+	if (IS_ERR(file->mr[agent_id])) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	if (put_user(agent_id,
+		     (u32 __user *) (arg + offsetof(struct ib_user_mad_reg_req, id)))) {
+		ret = -EFAULT;
+		goto err_mr;
+	}
+
+	ret = 0;
+	goto out;
+
+err_mr:
+	ib_dereg_mr(file->mr[agent_id]);
+
+err:
+	file->agent[agent_id] = NULL;
+	ib_unregister_mad_agent(agent);
+
+out:
+	up_write(&file->agent_mutex);
+	return ret;
+}
+
+static int ib_umad_unreg_agent(struct ib_umad_file *file, unsigned long arg)
+{
+	u32 id;
+	int ret = 0;
+
+	down_write(&file->agent_mutex);
+
+	if (get_user(id, (u32 __user *) arg)) {
+		ret = -EFAULT;
+		goto out;
+	}
+
+	if (id < 0 || id >= IB_UMAD_MAX_AGENTS || !file->agent[id]) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	ib_dereg_mr(file->mr[id]);
+	ib_unregister_mad_agent(file->agent[id]);
+	file->agent[id] = NULL;
+
+out:
+	up_write(&file->agent_mutex);
+	return ret;
+}
+
+static long ib_umad_ioctl(struct file *filp,
+			 unsigned int cmd, unsigned long arg)
+{
+	switch (cmd) {
+	case IB_USER_MAD_REGISTER_AGENT:
+		return ib_umad_reg_agent(filp->private_data, arg);
+	case IB_USER_MAD_UNREGISTER_AGENT:
+		return ib_umad_unreg_agent(filp->private_data, arg);
+	default:
+		return -ENOIOCTLCMD;
+	}
+}
+
+static int ib_umad_open(struct inode *inode, struct file *filp)
+{
+	struct ib_umad_port *port =
+		container_of(inode->i_cdev, struct ib_umad_port, dev);
+	struct ib_umad_file *file;
+
+	file = kmalloc(sizeof *file, GFP_KERNEL);
+	if (!file)
+		return -ENOMEM;
+
+	memset(file, 0, sizeof *file);
+
+	spin_lock_init(&file->recv_lock);
+	init_rwsem(&file->agent_mutex);
+	INIT_LIST_HEAD(&file->recv_list);
+	init_waitqueue_head(&file->recv_wait);
+
+	file->port = port;
+	filp->private_data = file;
+
+	return 0;
+}
+
+static int ib_umad_close(struct inode *inode, struct file *filp)
+{
+	struct ib_umad_file *file = filp->private_data;
+	int i;
+
+	for (i = 0; i < IB_UMAD_MAX_AGENTS; ++i)
+		if (file->agent[i]) {
+			ib_dereg_mr(file->mr[i]);
+			ib_unregister_mad_agent(file->agent[i]);
+		}
+
+	kfree(file);
+
+	return 0;
+}
+
+static struct file_operations umad_fops = {
+	.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
+};
+
+static int ib_umad_sm_open(struct inode *inode, struct file *filp)
+{
+	struct ib_umad_port *port =
+		container_of(inode->i_cdev, struct ib_umad_port, sm_dev);
+	struct ib_port_modify props = {
+		.set_port_cap_mask = IB_PORT_SM
+	};
+	int ret;
+
+	if (filp->f_flags & O_NONBLOCK) {
+		if (down_trylock(&port->sm_sem))
+			return -EAGAIN;
+	} else {
+		if (down_interruptible(&port->sm_sem))
+			return -ERESTARTSYS;
+	}
+
+	ret = ib_modify_port(port->ib_dev, port->port_num, 0, &props);
+	if (ret) {
+		up(&port->sm_sem);
+		return ret;
+	}
+
+	filp->private_data = port;
+
+	return 0;
+}
+
+static int ib_umad_sm_close(struct inode *inode, struct file *filp)
+{
+	struct ib_umad_port *port = filp->private_data;
+	struct ib_port_modify props = {
+		.clr_port_cap_mask = IB_PORT_SM
+	};
+	int ret;
+
+	ret = ib_modify_port(port->ib_dev, port->port_num, 0, &props);
+	up(&port->sm_sem);
+
+	return ret;
+}
+
+static struct file_operations umad_sm_fops = {
+	.owner 	 = THIS_MODULE,
+	.open 	 = ib_umad_sm_open,
+	.release = ib_umad_sm_close
+};
+
+static struct ib_client umad_client = {
+	.name   = "umad",
+	.add    = ib_umad_add_one,
+	.remove = ib_umad_remove_one
+};
+
+static ssize_t show_dev(struct class_device *class_dev, char *buf)
+{
+	struct ib_umad_port *port = class_get_devdata(class_dev);
+
+	if (class_dev == &port->class_dev)
+		return print_dev_t(buf, port->dev.dev);
+	else
+		return print_dev_t(buf, port->sm_dev.dev);
+}
+static CLASS_DEVICE_ATTR(dev, S_IRUGO, show_dev, NULL);
+
+static ssize_t show_ibdev(struct class_device *class_dev, char *buf)
+{
+	struct ib_umad_port *port = class_get_devdata(class_dev);
+
+	return sprintf(buf, "%s\n", port->ib_dev->name);
+}
+static CLASS_DEVICE_ATTR(ibdev, S_IRUGO, show_ibdev, NULL);
+
+static ssize_t show_port(struct class_device *class_dev, char *buf)
+{
+	struct ib_umad_port *port = class_get_devdata(class_dev);
+
+	return sprintf(buf, "%d\n", port->port_num);
+}
+static CLASS_DEVICE_ATTR(port, S_IRUGO, show_port, NULL);
+
+static void ib_umad_release_dev(struct kref *ref)
+{
+	struct ib_umad_device *dev =
+		container_of(ref, struct ib_umad_device, ref);
+
+	kfree(dev);
+}
+
+static void ib_umad_release_port(struct class_device *class_dev)
+{
+	struct ib_umad_port *port = class_get_devdata(class_dev);
+
+	if (class_dev == &port->class_dev) {
+		cdev_del(&port->dev);
+		clear_bit(port->devnum, dev_map);
+	} else {
+		cdev_del(&port->sm_dev);
+		clear_bit(port->sm_devnum, dev_map);
+	}
+
+	kref_put(&port->umad_dev->ref, ib_umad_release_dev);
+}
+
+static struct class umad_class = {
+	.name    = "infiniband_mad",
+	.release = ib_umad_release_port
+};
+
+static ssize_t show_abi_version(struct class *class, char *buf)
+{
+	return sprintf(buf, "%d\n", IB_USER_MAD_ABI_VERSION);
+}
+static CLASS_ATTR(abi_version, S_IRUGO, show_abi_version, NULL);
+
+static int ib_umad_init_port(struct ib_device *device, int port_num,
+			     struct ib_umad_port *port)
+{
+	spin_lock(&map_lock);
+	port->devnum = find_first_zero_bit(dev_map, IB_UMAD_MAX_PORTS);
+	if (port->devnum >= IB_UMAD_MAX_PORTS) {
+		spin_unlock(&map_lock);
+		return -1;
+	}
+	port->sm_devnum = find_next_zero_bit(dev_map, IB_UMAD_MAX_PORTS * 2, IB_UMAD_MAX_PORTS);
+	if (port->sm_devnum >= IB_UMAD_MAX_PORTS * 2) {
+		spin_unlock(&map_lock);
+		return -1;
+	}
+	set_bit(port->devnum, dev_map);
+	set_bit(port->sm_devnum, dev_map);
+	spin_unlock(&map_lock);
+
+	port->ib_dev   = device;
+	port->port_num = port_num;
+	init_MUTEX(&port->sm_sem);
+
+	cdev_init(&port->dev, &umad_fops);
+	port->dev.owner = THIS_MODULE;
+	kobject_set_name(&port->dev.kobj, "umad%d", port->devnum);
+	if (cdev_add(&port->dev, base_dev + port->devnum, 1))
+		return -1;
+
+	port->class_dev.class = &umad_class;
+	port->class_dev.dev   = device->dma_device;
+
+	snprintf(port->class_dev.class_id, BUS_ID_SIZE, "umad%d", port->devnum);
+
+	if (class_device_register(&port->class_dev))
+		goto err_cdev;
+
+	class_set_devdata(&port->class_dev, port);
+	kref_get(&port->umad_dev->ref);
+
+	if (class_device_create_file(&port->class_dev, &class_device_attr_dev))
+		goto err_class;
+	if (class_device_create_file(&port->class_dev, &class_device_attr_ibdev))
+		goto err_class;
+	if (class_device_create_file(&port->class_dev, &class_device_attr_port))
+		goto err_class;
+
+	cdev_init(&port->sm_dev, &umad_sm_fops);
+	port->sm_dev.owner = THIS_MODULE;
+	kobject_set_name(&port->dev.kobj, "issm%d", port->sm_devnum - IB_UMAD_MAX_PORTS);
+	if (cdev_add(&port->sm_dev, base_dev + port->sm_devnum, 1))
+		return -1;
+
+	port->sm_class_dev.class = &umad_class;
+	port->sm_class_dev.dev   = device->dma_device;
+
+	snprintf(port->sm_class_dev.class_id, BUS_ID_SIZE, "issm%d", port->sm_devnum - IB_UMAD_MAX_PORTS);
+
+	if (class_device_register(&port->sm_class_dev))
+		goto err_sm_cdev;
+
+	class_set_devdata(&port->sm_class_dev, port);
+	kref_get(&port->umad_dev->ref);
+
+	if (class_device_create_file(&port->sm_class_dev, &class_device_attr_dev))
+		goto err_sm_class;
+	if (class_device_create_file(&port->sm_class_dev, &class_device_attr_ibdev))
+		goto err_sm_class;
+	if (class_device_create_file(&port->sm_class_dev, &class_device_attr_port))
+		goto err_sm_class;
+
+	return 0;
+
+err_sm_class:
+	class_device_unregister(&port->sm_class_dev);
+
+err_sm_cdev:
+	cdev_del(&port->sm_dev);
+
+err_class:
+	class_device_unregister(&port->class_dev);
+
+err_cdev:
+	cdev_del(&port->dev);
+	clear_bit(port->devnum, dev_map);
+
+	return -1;
+}
+
+static void ib_umad_add_one(struct ib_device *device)
+{
+	struct ib_umad_device *umad_dev;
+	int s, e, i;
+
+	if (device->node_type == IB_NODE_SWITCH)
+		s = e = 0;
+	else {
+		s = 1;
+		e = device->phys_port_cnt;
+	}
+
+	umad_dev = kmalloc(sizeof *umad_dev +
+			   (e - s + 1) * sizeof (struct ib_umad_port),
+			   GFP_KERNEL);
+	if (!umad_dev)
+		return;
+
+	memset(umad_dev, 0, sizeof *umad_dev +
+	       (e - s + 1) * sizeof (struct ib_umad_port));
+
+	kref_init(&umad_dev->ref);
+
+	umad_dev->start_port = s;
+	umad_dev->end_port   = e;
+
+	for (i = s; i <= e; ++i) {
+		umad_dev->port[i - s].umad_dev = umad_dev;
+
+		if (ib_umad_init_port(device, i, &umad_dev->port[i - s]))
+			goto err;
+	}
+
+	ib_set_client_data(device, &umad_client, umad_dev);
+
+	return;
+
+err:
+	while (--i >= s) {
+		class_device_unregister(&umad_dev->port[i - s].class_dev);
+		class_device_unregister(&umad_dev->port[i - s].sm_class_dev);
+	}
+
+	kref_put(&umad_dev->ref, ib_umad_release_dev);
+}
+
+static void ib_umad_remove_one(struct ib_device *device)
+{
+	struct ib_umad_device *umad_dev = ib_get_client_data(device, &umad_client);
+	int i;
+
+	if (!umad_dev)
+		return;
+
+	for (i = 0; i <= umad_dev->end_port - umad_dev->start_port; ++i) {
+		class_device_unregister(&umad_dev->port[i].class_dev);
+		class_device_unregister(&umad_dev->port[i].sm_class_dev);
+	}
+
+	kref_put(&umad_dev->ref, ib_umad_release_dev);
+}
+
+static int __init ib_umad_init(void)
+{
+	int ret;
+
+	spin_lock_init(&map_lock);
+
+	ret = register_chrdev_region(base_dev, IB_UMAD_MAX_PORTS * 2,
+				     "infiniband_mad");
+	if (ret) {
+		printk(KERN_ERR "user_mad: couldn't register device number\n");
+		goto out;
+	}
+
+	ret = class_register(&umad_class);
+	if (ret) {
+		printk(KERN_ERR "user_mad: couldn't create class infiniband_mad\n");
+		goto out_chrdev;
+	}
+
+	ret = class_create_file(&umad_class, &class_attr_abi_version);
+	if (ret) {
+		printk(KERN_ERR "user_mad: couldn't create abi_version attribute\n");
+		goto out_class;
+	}
+
+	ret = ib_register_client(&umad_client);
+	if (ret) {
+		printk(KERN_ERR "user_mad: couldn't register ib_umad client\n");
+		goto out_class;
+	}
+
+	return 0;
+
+out_class:
+	class_unregister(&umad_class);
+
+out_chrdev:
+	unregister_chrdev_region(base_dev, IB_UMAD_MAX_PORTS * 2);
+
+out:
+	return ret;
+}
+
+static void __exit ib_umad_cleanup(void)
+{
+	ib_unregister_client(&umad_client);
+	class_unregister(&umad_class);
+	unregister_chrdev_region(base_dev, IB_UMAD_MAX_PORTS * 2);
+}
+
+module_init(ib_umad_init);
+module_exit(ib_umad_cleanup);
diff -Nru a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/infiniband/core/verbs.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,434 @@
+/*
+ * Copyright (c) 2004 Mellanox Technologies Ltd.  All rights reserved.
+ * Copyright (c) 2004 Infinicon Corporation.  All rights reserved.
+ * 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 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: verbs.c 1349 2004-12-16 21:09:43Z roland $
+ */
+
+#include <linux/errno.h>
+#include <linux/err.h>
+
+#include <ib_verbs.h>
+
+/* Protection domains */
+
+struct ib_pd *ib_alloc_pd(struct ib_device *device)
+{
+	struct ib_pd *pd;
+
+	pd = device->alloc_pd(device);
+
+	if (!IS_ERR(pd)) {
+		pd->device = device;
+		atomic_set(&pd->usecnt, 0);
+	}
+
+	return pd;
+}
+EXPORT_SYMBOL(ib_alloc_pd);
+
+int ib_dealloc_pd(struct ib_pd *pd)
+{
+	if (atomic_read(&pd->usecnt))
+		return -EBUSY;
+
+	return pd->device->dealloc_pd(pd);
+}
+EXPORT_SYMBOL(ib_dealloc_pd);
+
+/* Address handles */
+
+struct ib_ah *ib_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr)
+{
+	struct ib_ah *ah;
+
+	ah = pd->device->create_ah(pd, ah_attr);
+
+	if (!IS_ERR(ah)) {
+		ah->device = pd->device;
+		ah->pd     = pd;
+		atomic_inc(&pd->usecnt);
+	}
+
+	return ah;
+}
+EXPORT_SYMBOL(ib_create_ah);
+
+int ib_modify_ah(struct ib_ah *ah, struct ib_ah_attr *ah_attr)
+{
+	return ah->device->modify_ah ?
+		ah->device->modify_ah(ah, ah_attr) :
+		-ENOSYS;
+}
+EXPORT_SYMBOL(ib_modify_ah);
+
+int ib_query_ah(struct ib_ah *ah, struct ib_ah_attr *ah_attr)
+{
+	return ah->device->query_ah ?
+		ah->device->query_ah(ah, ah_attr) :
+		-ENOSYS;
+}
+EXPORT_SYMBOL(ib_query_ah);
+
+int ib_destroy_ah(struct ib_ah *ah)
+{
+	struct ib_pd *pd;
+	int ret;
+
+	pd = ah->pd;
+	ret = ah->device->destroy_ah(ah);
+	if (!ret)
+		atomic_dec(&pd->usecnt);
+
+	return ret;
+}
+EXPORT_SYMBOL(ib_destroy_ah);
+
+/* Queue pairs */
+
+struct ib_qp *ib_create_qp(struct ib_pd *pd,
+			   struct ib_qp_init_attr *qp_init_attr)
+{
+	struct ib_qp *qp;
+
+	qp = pd->device->create_qp(pd, qp_init_attr);
+
+	if (!IS_ERR(qp)) {
+		qp->device     	  = pd->device;
+		qp->pd         	  = pd;
+		qp->send_cq    	  = qp_init_attr->send_cq;
+		qp->recv_cq    	  = qp_init_attr->recv_cq;
+		qp->srq	       	  = qp_init_attr->srq;
+		qp->event_handler = qp_init_attr->event_handler;
+		qp->qp_context    = qp_init_attr->qp_context;
+		qp->qp_type	  = qp_init_attr->qp_type;
+		atomic_inc(&pd->usecnt);
+		atomic_inc(&qp_init_attr->send_cq->usecnt);
+		atomic_inc(&qp_init_attr->recv_cq->usecnt);
+		if (qp_init_attr->srq)
+			atomic_inc(&qp_init_attr->srq->usecnt);
+	}
+
+	return qp;
+}
+EXPORT_SYMBOL(ib_create_qp);
+
+int ib_modify_qp(struct ib_qp *qp,
+		 struct ib_qp_attr *qp_attr,
+		 int qp_attr_mask)
+{
+	return qp->device->modify_qp(qp, qp_attr, qp_attr_mask);
+}
+EXPORT_SYMBOL(ib_modify_qp);
+
+int ib_query_qp(struct ib_qp *qp,
+		struct ib_qp_attr *qp_attr,
+		int qp_attr_mask,
+		struct ib_qp_init_attr *qp_init_attr)
+{
+	return qp->device->query_qp ?
+		qp->device->query_qp(qp, qp_attr, qp_attr_mask, qp_init_attr) :
+		-ENOSYS;
+}
+EXPORT_SYMBOL(ib_query_qp);
+
+int ib_destroy_qp(struct ib_qp *qp)
+{
+	struct ib_pd *pd;
+	struct ib_cq *scq, *rcq;
+	struct ib_srq *srq;
+	int ret;
+
+	pd  = qp->pd;
+	scq = qp->send_cq;
+	rcq = qp->recv_cq;
+	srq = qp->srq;
+
+	ret = qp->device->destroy_qp(qp);
+	if (!ret) {
+		atomic_dec(&pd->usecnt);
+		atomic_dec(&scq->usecnt);
+		atomic_dec(&rcq->usecnt);
+		if (srq)
+			atomic_dec(&srq->usecnt);
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL(ib_destroy_qp);
+
+/* Completion queues */
+
+struct ib_cq *ib_create_cq(struct ib_device *device,
+			   ib_comp_handler comp_handler,
+			   void (*event_handler)(struct ib_event *, void *),
+			   void *cq_context, int cqe)
+{
+	struct ib_cq *cq;
+
+	cq = device->create_cq(device, cqe);
+
+	if (!IS_ERR(cq)) {
+		cq->device        = device;
+		cq->comp_handler  = comp_handler;
+		cq->event_handler = event_handler;
+		cq->cq_context    = cq_context;
+		atomic_set(&cq->usecnt, 0);
+	}
+
+	return cq;
+}
+EXPORT_SYMBOL(ib_create_cq);
+
+int ib_destroy_cq(struct ib_cq *cq)
+{
+	if (atomic_read(&cq->usecnt))
+		return -EBUSY;
+
+	return cq->device->destroy_cq(cq);
+}
+EXPORT_SYMBOL(ib_destroy_cq);
+
+int ib_resize_cq(struct ib_cq *cq,
+                 int           cqe)
+{
+	int ret;
+
+	if (!cq->device->resize_cq)
+		return -ENOSYS;
+
+	ret = cq->device->resize_cq(cq, &cqe);
+	if (!ret)
+		cq->cqe = cqe;
+
+	return ret;
+}
+EXPORT_SYMBOL(ib_resize_cq);
+
+/* Memory regions */
+
+struct ib_mr *ib_get_dma_mr(struct ib_pd *pd, int mr_access_flags)
+{
+	struct ib_mr *mr;
+
+	mr = pd->device->get_dma_mr(pd, mr_access_flags);
+
+	if (!IS_ERR(mr)) {
+		mr->device = pd->device;
+		mr->pd     = pd;
+		atomic_inc(&pd->usecnt);
+		atomic_set(&mr->usecnt, 0);
+	}
+
+	return mr;
+}
+EXPORT_SYMBOL(ib_get_dma_mr);
+
+struct ib_mr *ib_reg_phys_mr(struct ib_pd *pd,
+			     struct ib_phys_buf *phys_buf_array,
+			     int num_phys_buf,
+			     int mr_access_flags,
+			     u64 *iova_start)
+{
+	struct ib_mr *mr;
+
+	mr = pd->device->reg_phys_mr(pd, phys_buf_array, num_phys_buf,
+				     mr_access_flags, iova_start);
+
+	if (!IS_ERR(mr)) {
+		mr->device = pd->device;
+		mr->pd     = pd;
+		atomic_inc(&pd->usecnt);
+		atomic_set(&mr->usecnt, 0);
+	}
+
+	return mr;
+}
+EXPORT_SYMBOL(ib_reg_phys_mr);
+
+int ib_rereg_phys_mr(struct ib_mr *mr,
+		     int mr_rereg_mask,
+		     struct ib_pd *pd,
+		     struct ib_phys_buf *phys_buf_array,
+		     int num_phys_buf,
+		     int mr_access_flags,
+		     u64 *iova_start)
+{
+	struct ib_pd *old_pd;
+	int ret;
+
+	if (!mr->device->rereg_phys_mr)
+		return -ENOSYS;
+
+	if (atomic_read(&mr->usecnt))
+		return -EBUSY;
+
+	old_pd = mr->pd;
+
+	ret = mr->device->rereg_phys_mr(mr, mr_rereg_mask, pd,
+					phys_buf_array, num_phys_buf,
+					mr_access_flags, iova_start);
+
+	if (!ret && (mr_rereg_mask & IB_MR_REREG_PD)) {
+		atomic_dec(&old_pd->usecnt);
+		atomic_inc(&pd->usecnt);
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL(ib_rereg_phys_mr);
+
+int ib_query_mr(struct ib_mr *mr, struct ib_mr_attr *mr_attr)
+{
+	return mr->device->query_mr ?
+		mr->device->query_mr(mr, mr_attr) : -ENOSYS;
+}
+EXPORT_SYMBOL(ib_query_mr);
+
+int ib_dereg_mr(struct ib_mr *mr)
+{
+	struct ib_pd *pd;
+	int ret;
+
+	if (atomic_read(&mr->usecnt))
+		return -EBUSY;
+
+	pd = mr->pd;
+	ret = mr->device->dereg_mr(mr);
+	if (!ret)
+		atomic_dec(&pd->usecnt);
+
+	return ret;
+}
+EXPORT_SYMBOL(ib_dereg_mr);
+
+/* Memory windows */
+
+struct ib_mw *ib_alloc_mw(struct ib_pd *pd)
+{
+	struct ib_mw *mw;
+
+	if (!pd->device->alloc_mw)
+		return ERR_PTR(-ENOSYS);
+
+	mw = pd->device->alloc_mw(pd);
+	if (!IS_ERR(mw)) {
+		mw->device = pd->device;
+		mw->pd     = pd;
+		atomic_inc(&pd->usecnt);
+	}
+
+	return mw;
+}
+EXPORT_SYMBOL(ib_alloc_mw);
+
+int ib_dealloc_mw(struct ib_mw *mw)
+{
+	struct ib_pd *pd;
+	int ret;
+
+	pd = mw->pd;
+	ret = mw->device->dealloc_mw(mw);
+	if (!ret)
+		atomic_dec(&pd->usecnt);
+
+	return ret;
+}
+EXPORT_SYMBOL(ib_dealloc_mw);
+
+/* "Fast" memory regions */
+
+struct ib_fmr *ib_alloc_fmr(struct ib_pd *pd,
+			    int mr_access_flags,
+			    struct ib_fmr_attr *fmr_attr)
+{
+	struct ib_fmr *fmr;
+
+	if (!pd->device->alloc_fmr)
+		return ERR_PTR(-ENOSYS);
+
+	fmr = pd->device->alloc_fmr(pd, mr_access_flags, fmr_attr);
+	if (!IS_ERR(fmr)) {
+		fmr->device = pd->device;
+		fmr->pd     = pd;
+		atomic_inc(&pd->usecnt);
+	}
+
+	return fmr;
+}
+EXPORT_SYMBOL(ib_alloc_fmr);
+
+int ib_unmap_fmr(struct list_head *fmr_list)
+{
+	struct ib_fmr *fmr;
+
+	if (list_empty(fmr_list))
+		return 0;
+
+	fmr = list_entry(fmr_list->next, struct ib_fmr, list);
+	return fmr->device->unmap_fmr(fmr_list);
+}
+EXPORT_SYMBOL(ib_unmap_fmr);
+
+int ib_dealloc_fmr(struct ib_fmr *fmr)
+{
+	struct ib_pd *pd;
+	int ret;
+
+	pd = fmr->pd;
+	ret = fmr->device->dealloc_fmr(fmr);
+	if (!ret)
+		atomic_dec(&pd->usecnt);
+
+	return ret;
+}
+EXPORT_SYMBOL(ib_dealloc_fmr);
+
+/* Multicast groups */
+
+int ib_attach_mcast(struct ib_qp *qp, union ib_gid *gid, u16 lid)
+{
+	return qp->device->attach_mcast ?
+		qp->device->attach_mcast(qp, gid, lid) :
+		-ENOSYS;
+}
+EXPORT_SYMBOL(ib_attach_mcast);
+
+int ib_detach_mcast(struct ib_qp *qp, union ib_gid *gid, u16 lid)
+{
+	return qp->device->detach_mcast ?
+		qp->device->detach_mcast(qp, gid, lid) :
+		-ENOSYS;
+}
+EXPORT_SYMBOL(ib_detach_mcast);
diff -Nru a/drivers/infiniband/hw/mthca/Kconfig b/drivers/infiniband/hw/mthca/Kconfig
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/infiniband/hw/mthca/Kconfig	2005-03-01 23:39:26 -08:00
@@ -0,0 +1,16 @@
+config INFINIBAND_MTHCA
+	tristate "Mellanox HCA support"
+	depends on PCI && INFINIBAND
+	---help---
+	  This is a low-level driver for Mellanox InfiniHost host
+	  channel adapters (HCAs), including the MT23108 PCI-X HCA
+	  ("Tavor") and the MT25208 PCI Express HCA ("Arbel").
+
+config INFINIBAND_MTHCA_DEBUG
+	bool "Verbose debugging output"
+	depends on INFINIBAND_MTHCA
+	default n
+	---help---
+	  This option causes the mthca driver produce a bunch of debug
+	  messages.  Select this is you are developing the driver or
+	  trying to diagnose a problem.
diff -Nru a/drivers/infiniband/hw/mthca/Makefile b/drivers/infiniband/hw/mthca/Makefile
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/infiniband/hw/mthca/Makefile	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,12 @@
+EXTRA_CFLAGS += -Idrivers/infiniband/include
+
+ifdef CONFIG_INFINIBAND_MTHCA_DEBUG
+EXTRA_CFLAGS += -DDEBUG
+endif
+
+obj-$(CONFIG_INFINIBAND_MTHCA) += ib_mthca.o
+
+ib_mthca-y :=	mthca_main.o mthca_cmd.o mthca_profile.o mthca_reset.o \
+		mthca_allocator.o mthca_eq.o mthca_pd.o mthca_cq.o \
+		mthca_mr.o mthca_qp.o mthca_av.o mthca_mcg.o mthca_mad.o \
+		mthca_provider.o mthca_memfree.o
diff -Nru a/drivers/infiniband/hw/mthca/mthca_allocator.c b/drivers/infiniband/hw/mthca/mthca_allocator.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/infiniband/hw/mthca/mthca_allocator.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2004 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: mthca_allocator.c 1349 2004-12-16 21:09:43Z roland $
+ */
+
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/bitmap.h>
+
+#include "mthca_dev.h"
+
+/* Trivial bitmap-based allocator */
+u32 mthca_alloc(struct mthca_alloc *alloc)
+{
+	u32 obj;
+
+	spin_lock(&alloc->lock);
+	obj = find_next_zero_bit(alloc->table, alloc->max, alloc->last);
+	if (obj >= alloc->max) {
+		alloc->top = (alloc->top + alloc->max) & alloc->mask;
+		obj = find_first_zero_bit(alloc->table, alloc->max);
+	}
+
+	if (obj < alloc->max) {
+		set_bit(obj, alloc->table);
+		obj |= alloc->top;
+	} else
+		obj = -1;
+
+	spin_unlock(&alloc->lock);
+
+	return obj;
+}
+
+void mthca_free(struct mthca_alloc *alloc, u32 obj)
+{
+	obj &= alloc->max - 1;
+	spin_lock(&alloc->lock);
+	clear_bit(obj, alloc->table);
+	alloc->last = min(alloc->last, obj);
+	alloc->top = (alloc->top + alloc->max) & alloc->mask;
+	spin_unlock(&alloc->lock);
+}
+
+int mthca_alloc_init(struct mthca_alloc *alloc, u32 num, u32 mask,
+		     u32 reserved)
+{
+	int i;
+
+	/* num must be a power of 2 */
+	if (num != 1 << (ffs(num) - 1))
+		return -EINVAL;
+
+	alloc->last = 0;
+	alloc->top  = 0;
+	alloc->max  = num;
+	alloc->mask = mask;
+	spin_lock_init(&alloc->lock);
+	alloc->table = kmalloc(BITS_TO_LONGS(num) * sizeof (long),
+			       GFP_KERNEL);
+	if (!alloc->table)
+		return -ENOMEM;
+
+	bitmap_zero(alloc->table, num);
+	for (i = 0; i < reserved; ++i)
+		set_bit(i, alloc->table);
+
+	return 0;
+}
+
+void mthca_alloc_cleanup(struct mthca_alloc *alloc)
+{
+	kfree(alloc->table);
+}
+
+/*
+ * Array of pointers with lazy allocation of leaf pages.  Callers of
+ * _get, _set and _clear methods must use a lock or otherwise
+ * serialize access to the array.
+ */
+
+void *mthca_array_get(struct mthca_array *array, int index)
+{
+	int p = (index * sizeof (void *)) >> PAGE_SHIFT;
+
+	if (array->page_list[p].page) {
+		int i = index & (PAGE_SIZE / sizeof (void *) - 1);
+		return array->page_list[p].page[i];
+	} else
+		return NULL;
+}
+
+int mthca_array_set(struct mthca_array *array, int index, void *value)
+{
+	int p = (index * sizeof (void *)) >> PAGE_SHIFT;
+
+	/* Allocate with GFP_ATOMIC because we'll be called with locks held. */
+	if (!array->page_list[p].page)
+		array->page_list[p].page = (void **) get_zeroed_page(GFP_ATOMIC);
+
+	if (!array->page_list[p].page)
+		return -ENOMEM;
+
+	array->page_list[p].page[index & (PAGE_SIZE / sizeof (void *) - 1)] =
+		value;
+	++array->page_list[p].used;
+
+	return 0;
+}
+
+void mthca_array_clear(struct mthca_array *array, int index)
+{
+	int p = (index * sizeof (void *)) >> PAGE_SHIFT;
+
+	if (--array->page_list[p].used == 0) {
+		free_page((unsigned long) array->page_list[p].page);
+		array->page_list[p].page = NULL;
+	}
+
+	if (array->page_list[p].used < 0)
+		pr_debug("Array %p index %d page %d with ref count %d < 0\n",
+			 array, index, p, array->page_list[p].used);
+}
+
+int mthca_array_init(struct mthca_array *array, int nent)
+{
+	int npage = (nent * sizeof (void *) + PAGE_SIZE - 1) / PAGE_SIZE;
+	int i;
+
+	array->page_list = kmalloc(npage * sizeof *array->page_list, GFP_KERNEL);
+	if (!array->page_list)
+		return -ENOMEM;
+
+	for (i = 0; i < npage; ++i) {
+		array->page_list[i].page = NULL;
+		array->page_list[i].used = 0;
+	}
+
+	return 0;
+}
+
+void mthca_array_cleanup(struct mthca_array *array, int nent)
+{
+	int i;
+
+	for (i = 0; i < (nent * sizeof (void *) + PAGE_SIZE - 1) / PAGE_SIZE; ++i)
+		free_page((unsigned long) array->page_list[i].page);
+
+	kfree(array->page_list);
+}
diff -Nru a/drivers/infiniband/hw/mthca/mthca_av.c b/drivers/infiniband/hw/mthca/mthca_av.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/infiniband/hw/mthca/mthca_av.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,219 @@
+/*
+ * Copyright (c) 2004 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: mthca_av.c 1349 2004-12-16 21:09:43Z roland $
+ */
+
+#include <linux/init.h>
+
+#include <ib_verbs.h>
+#include <ib_cache.h>
+
+#include "mthca_dev.h"
+
+struct mthca_av {
+	u32 port_pd;
+	u8  reserved1;
+	u8  g_slid;
+	u16 dlid;
+	u8  reserved2;
+	u8  gid_index;
+	u8  msg_sr;
+	u8  hop_limit;
+	u32 sl_tclass_flowlabel;
+	u32 dgid[4];
+};
+
+int mthca_create_ah(struct mthca_dev *dev,
+		    struct mthca_pd *pd,
+		    struct ib_ah_attr *ah_attr,
+		    struct mthca_ah *ah)
+{
+	u32 index = -1;
+	struct mthca_av *av = NULL;
+
+	ah->on_hca = 0;
+
+	if (!atomic_read(&pd->sqp_count) &&
+	    !(dev->mthca_flags & MTHCA_FLAG_DDR_HIDDEN)) {
+		index = mthca_alloc(&dev->av_table.alloc);
+
+		/* fall back to allocate in host memory */
+		if (index == -1)
+			goto host_alloc;
+
+		av = kmalloc(sizeof *av, GFP_KERNEL);
+		if (!av)
+			goto host_alloc;
+
+		ah->on_hca = 1;
+		ah->avdma  = dev->av_table.ddr_av_base +
+			index * MTHCA_AV_SIZE;
+	}
+
+ host_alloc:
+	if (!ah->on_hca) {
+		ah->av = pci_pool_alloc(dev->av_table.pool,
+					SLAB_KERNEL, &ah->avdma);
+		if (!ah->av)
+			return -ENOMEM;
+
+		av = ah->av;
+	}
+
+	ah->key = pd->ntmr.ibmr.lkey;
+
+	memset(av, 0, MTHCA_AV_SIZE);
+
+	av->port_pd = cpu_to_be32(pd->pd_num | (ah_attr->port_num << 24));
+	av->g_slid  = ah_attr->src_path_bits;
+	av->dlid    = cpu_to_be16(ah_attr->dlid);
+	av->msg_sr  = (3 << 4) | /* 2K message */
+		ah_attr->static_rate;
+	av->sl_tclass_flowlabel = cpu_to_be32(ah_attr->sl << 28);
+	if (ah_attr->ah_flags & IB_AH_GRH) {
+		av->g_slid |= 0x80;
+		av->gid_index = (ah_attr->port_num - 1) * dev->limits.gid_table_len +
+			ah_attr->grh.sgid_index;
+		av->hop_limit = ah_attr->grh.hop_limit;
+		av->sl_tclass_flowlabel |=
+			cpu_to_be32((ah_attr->grh.traffic_class << 20) |
+				    ah_attr->grh.flow_label);
+		memcpy(av->dgid, ah_attr->grh.dgid.raw, 16);
+	} else {
+		/* Arbel workaround -- low byte of GID must be 2 */
+		av->dgid[3] = cpu_to_be32(2);
+	}
+
+	if (0) {
+		int j;
+
+		mthca_dbg(dev, "Created UDAV at %p/%08lx:\n",
+			  av, (unsigned long) ah->avdma);
+		for (j = 0; j < 8; ++j)
+			printk(KERN_DEBUG "  [%2x] %08x\n",
+			       j * 4, be32_to_cpu(((u32 *) av)[j]));
+	}
+
+	if (ah->on_hca) {
+		memcpy_toio(dev->av_table.av_map + index * MTHCA_AV_SIZE,
+			    av, MTHCA_AV_SIZE);
+		kfree(av);
+	}
+
+	return 0;
+}
+
+int mthca_destroy_ah(struct mthca_dev *dev, struct mthca_ah *ah)
+{
+	if (ah->on_hca)
+		mthca_free(&dev->av_table.alloc,
+ 			   (ah->avdma - dev->av_table.ddr_av_base) /
+			   MTHCA_AV_SIZE);
+	else
+		pci_pool_free(dev->av_table.pool, ah->av, ah->avdma);
+
+	return 0;
+}
+
+int mthca_read_ah(struct mthca_dev *dev, struct mthca_ah *ah,
+		  struct ib_ud_header *header)
+{
+	if (ah->on_hca)
+		return -EINVAL;
+
+	header->lrh.service_level   = be32_to_cpu(ah->av->sl_tclass_flowlabel) >> 28;
+	header->lrh.destination_lid = ah->av->dlid;
+	header->lrh.source_lid      = ah->av->g_slid & 0x7f;
+	if (ah->av->g_slid & 0x80) {
+		header->grh_present = 1;
+		header->grh.traffic_class =
+			(be32_to_cpu(ah->av->sl_tclass_flowlabel) >> 20) & 0xff;
+		header->grh.flow_label    =
+			ah->av->sl_tclass_flowlabel & cpu_to_be32(0xfffff);
+		ib_get_cached_gid(&dev->ib_dev,
+				  be32_to_cpu(ah->av->port_pd) >> 24,
+				  ah->av->gid_index,
+				  &header->grh.source_gid);
+		memcpy(header->grh.destination_gid.raw,
+		       ah->av->dgid, 16);
+	} else {
+		header->grh_present = 0;
+	}
+
+	return 0;
+}
+
+int __devinit mthca_init_av_table(struct mthca_dev *dev)
+{
+	int err;
+
+	err = mthca_alloc_init(&dev->av_table.alloc,
+			       dev->av_table.num_ddr_avs,
+			       dev->av_table.num_ddr_avs - 1,
+			       0);
+	if (err)
+		return err;
+
+	dev->av_table.pool = pci_pool_create("mthca_av", dev->pdev,
+					     MTHCA_AV_SIZE,
+					     MTHCA_AV_SIZE, 0);
+	if (!dev->av_table.pool)
+		goto out_free_alloc;
+
+	if (!(dev->mthca_flags & MTHCA_FLAG_DDR_HIDDEN)) {
+		dev->av_table.av_map = ioremap(pci_resource_start(dev->pdev, 4) +
+					       dev->av_table.ddr_av_base -
+					       dev->ddr_start,
+					       dev->av_table.num_ddr_avs *
+					       MTHCA_AV_SIZE);
+		if (!dev->av_table.av_map)
+			goto out_free_pool;
+	} else
+		dev->av_table.av_map = NULL;
+
+	return 0;
+
+ out_free_pool:
+	pci_pool_destroy(dev->av_table.pool);
+
+ out_free_alloc:
+	mthca_alloc_cleanup(&dev->av_table.alloc);
+	return -ENOMEM;
+}
+
+void __devexit mthca_cleanup_av_table(struct mthca_dev *dev)
+{
+	if (dev->av_table.av_map)
+		iounmap(dev->av_table.av_map);
+	pci_pool_destroy(dev->av_table.pool);
+	mthca_alloc_cleanup(&dev->av_table.alloc);
+}
diff -Nru a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/infiniband/hw/mthca/mthca_cmd.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,1764 @@
+/*
+ * Copyright (c) 2004, 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: mthca_cmd.c 1349 2004-12-16 21:09:43Z roland $
+ */
+
+#include <linux/sched.h>
+#include <linux/pci.h>
+#include <linux/errno.h>
+#include <asm/io.h>
+#include <ib_mad.h>
+
+#include "mthca_dev.h"
+#include "mthca_config_reg.h"
+#include "mthca_cmd.h"
+#include "mthca_memfree.h"
+
+#define CMD_POLL_TOKEN 0xffff
+
+enum {
+	HCR_IN_PARAM_OFFSET    = 0x00,
+	HCR_IN_MODIFIER_OFFSET = 0x08,
+	HCR_OUT_PARAM_OFFSET   = 0x0c,
+	HCR_TOKEN_OFFSET       = 0x14,
+	HCR_STATUS_OFFSET      = 0x18,
+
+	HCR_OPMOD_SHIFT        = 12,
+	HCA_E_BIT              = 22,
+	HCR_GO_BIT             = 23
+};
+
+enum {
+	/* initialization and general commands */
+	CMD_SYS_EN          = 0x1,
+	CMD_SYS_DIS         = 0x2,
+	CMD_MAP_FA          = 0xfff,
+	CMD_UNMAP_FA        = 0xffe,
+	CMD_RUN_FW          = 0xff6,
+	CMD_MOD_STAT_CFG    = 0x34,
+	CMD_QUERY_DEV_LIM   = 0x3,
+	CMD_QUERY_FW        = 0x4,
+	CMD_ENABLE_LAM      = 0xff8,
+	CMD_DISABLE_LAM     = 0xff7,
+	CMD_QUERY_DDR       = 0x5,
+	CMD_QUERY_ADAPTER   = 0x6,
+	CMD_INIT_HCA        = 0x7,
+	CMD_CLOSE_HCA       = 0x8,
+	CMD_INIT_IB         = 0x9,
+	CMD_CLOSE_IB        = 0xa,
+	CMD_QUERY_HCA       = 0xb,
+	CMD_SET_IB          = 0xc,
+	CMD_ACCESS_DDR      = 0x2e,
+	CMD_MAP_ICM         = 0xffa,
+	CMD_UNMAP_ICM       = 0xff9,
+	CMD_MAP_ICM_AUX     = 0xffc,
+	CMD_UNMAP_ICM_AUX   = 0xffb,
+	CMD_SET_ICM_SIZE    = 0xffd,
+
+	/* TPT commands */
+	CMD_SW2HW_MPT 	    = 0xd,
+	CMD_QUERY_MPT 	    = 0xe,
+	CMD_HW2SW_MPT 	    = 0xf,
+	CMD_READ_MTT        = 0x10,
+	CMD_WRITE_MTT       = 0x11,
+	CMD_SYNC_TPT        = 0x2f,
+
+	/* EQ commands */
+	CMD_MAP_EQ          = 0x12,
+	CMD_SW2HW_EQ 	    = 0x13,
+	CMD_HW2SW_EQ 	    = 0x14,
+	CMD_QUERY_EQ        = 0x15,
+
+	/* CQ commands */
+	CMD_SW2HW_CQ 	    = 0x16,
+	CMD_HW2SW_CQ 	    = 0x17,
+	CMD_QUERY_CQ 	    = 0x18,
+	CMD_RESIZE_CQ       = 0x2c,
+
+	/* SRQ commands */
+	CMD_SW2HW_SRQ 	    = 0x35,
+	CMD_HW2SW_SRQ 	    = 0x36,
+	CMD_QUERY_SRQ       = 0x37,
+
+	/* QP/EE commands */
+	CMD_RST2INIT_QPEE   = 0x19,
+	CMD_INIT2RTR_QPEE   = 0x1a,
+	CMD_RTR2RTS_QPEE    = 0x1b,
+	CMD_RTS2RTS_QPEE    = 0x1c,
+	CMD_SQERR2RTS_QPEE  = 0x1d,
+	CMD_2ERR_QPEE       = 0x1e,
+	CMD_RTS2SQD_QPEE    = 0x1f,
+	CMD_SQD2SQD_QPEE    = 0x38,
+	CMD_SQD2RTS_QPEE    = 0x20,
+	CMD_ERR2RST_QPEE    = 0x21,
+	CMD_QUERY_QPEE      = 0x22,
+	CMD_INIT2INIT_QPEE  = 0x2d,
+	CMD_SUSPEND_QPEE    = 0x32,
+	CMD_UNSUSPEND_QPEE  = 0x33,
+	/* special QPs and management commands */
+	CMD_CONF_SPECIAL_QP = 0x23,
+	CMD_MAD_IFC         = 0x24,
+
+	/* multicast commands */
+	CMD_READ_MGM        = 0x25,
+	CMD_WRITE_MGM       = 0x26,
+	CMD_MGID_HASH       = 0x27,
+
+	/* miscellaneous commands */
+	CMD_DIAG_RPRT       = 0x30,
+	CMD_NOP             = 0x31,
+
+	/* debug commands */
+	CMD_QUERY_DEBUG_MSG = 0x2a,
+	CMD_SET_DEBUG_MSG   = 0x2b,
+};
+
+/*
+ * According to Mellanox code, FW may be starved and never complete
+ * commands.  So we can't use strict timeouts described in PRM -- we
+ * just arbitrarily select 60 seconds for now.
+ */
+#if 0
+/*
+ * Round up and add 1 to make sure we get the full wait time (since we
+ * will be starting in the middle of a jiffy)
+ */
+enum {
+	CMD_TIME_CLASS_A = (HZ + 999) / 1000 + 1,
+	CMD_TIME_CLASS_B = (HZ +  99) /  100 + 1,
+	CMD_TIME_CLASS_C = (HZ +   9) /   10 + 1
+};
+#else
+enum {
+	CMD_TIME_CLASS_A = 60 * HZ,
+	CMD_TIME_CLASS_B = 60 * HZ,
+	CMD_TIME_CLASS_C = 60 * HZ
+};
+#endif
+
+enum {
+	GO_BIT_TIMEOUT = HZ * 10
+};
+
+struct mthca_cmd_context {
+	struct completion done;
+	struct timer_list timer;
+	int               result;
+	int               next;
+	u64               out_param;
+	u16               token;
+	u8                status;
+};
+
+static inline int go_bit(struct mthca_dev *dev)
+{
+	return readl(dev->hcr + HCR_STATUS_OFFSET) &
+		swab32(1 << HCR_GO_BIT);
+}
+
+static int mthca_cmd_post(struct mthca_dev *dev,
+			  u64 in_param,
+			  u64 out_param,
+			  u32 in_modifier,
+			  u8 op_modifier,
+			  u16 op,
+			  u16 token,
+			  int event)
+{
+	int err = 0;
+
+	if (down_interruptible(&dev->cmd.hcr_sem))
+		return -EINTR;
+
+	if (event) {
+		unsigned long end = jiffies + GO_BIT_TIMEOUT;
+
+		while (go_bit(dev) && time_before(jiffies, end)) {
+			set_current_state(TASK_RUNNING);
+			schedule();
+		}
+	}
+
+	if (go_bit(dev)) {
+		err = -EAGAIN;
+		goto out;
+	}
+
+	/*
+	 * We use writel (instead of something like memcpy_toio)
+	 * because writes of less than 32 bits to the HCR don't work
+	 * (and some architectures such as ia64 implement memcpy_toio
+	 * in terms of writeb).
+	 */
+	__raw_writel(cpu_to_be32(in_param >> 32),           dev->hcr + 0 * 4);
+	__raw_writel(cpu_to_be32(in_param & 0xfffffffful),  dev->hcr + 1 * 4);
+	__raw_writel(cpu_to_be32(in_modifier),              dev->hcr + 2 * 4);
+	__raw_writel(cpu_to_be32(out_param >> 32),          dev->hcr + 3 * 4);
+	__raw_writel(cpu_to_be32(out_param & 0xfffffffful), dev->hcr + 4 * 4);
+	__raw_writel(cpu_to_be32(token << 16),              dev->hcr + 5 * 4);
+
+	/* __raw_writel may not order writes. */
+	wmb();
+
+	__raw_writel(cpu_to_be32((1 << HCR_GO_BIT)                |
+				 (event ? (1 << HCA_E_BIT) : 0)   |
+				 (op_modifier << HCR_OPMOD_SHIFT) |
+				 op),                       dev->hcr + 6 * 4);
+
+out:
+	up(&dev->cmd.hcr_sem);
+	return err;
+}
+
+static int mthca_cmd_poll(struct mthca_dev *dev,
+			  u64 in_param,
+			  u64 *out_param,
+			  int out_is_imm,
+			  u32 in_modifier,
+			  u8 op_modifier,
+			  u16 op,
+			  unsigned long timeout,
+			  u8 *status)
+{
+	int err = 0;
+	unsigned long end;
+
+	if (down_interruptible(&dev->cmd.poll_sem))
+		return -EINTR;
+
+	err = mthca_cmd_post(dev, in_param,
+			     out_param ? *out_param : 0,
+			     in_modifier, op_modifier,
+			     op, CMD_POLL_TOKEN, 0);
+	if (err)
+		goto out;
+
+	end = timeout + jiffies;
+	while (go_bit(dev) && time_before(jiffies, end)) {
+		set_current_state(TASK_RUNNING);
+		schedule();
+	}
+
+	if (go_bit(dev)) {
+		err = -EBUSY;
+		goto out;
+	}
+
+	if (out_is_imm) {
+		memcpy_fromio(out_param, dev->hcr + HCR_OUT_PARAM_OFFSET, sizeof (u64));
+		be64_to_cpus(out_param);
+	}
+
+	*status = be32_to_cpu(__raw_readl(dev->hcr + HCR_STATUS_OFFSET)) >> 24;
+
+out:
+	up(&dev->cmd.poll_sem);
+	return err;
+}
+
+void mthca_cmd_event(struct mthca_dev *dev,
+		     u16 token,
+		     u8  status,
+		     u64 out_param)
+{
+	struct mthca_cmd_context *context =
+		&dev->cmd.context[token & dev->cmd.token_mask];
+
+	/* previously timed out command completing at long last */
+	if (token != context->token)
+		return;
+
+	context->result    = 0;
+	context->status    = status;
+	context->out_param = out_param;
+
+	context->token += dev->cmd.token_mask + 1;
+
+	complete(&context->done);
+}
+
+static void event_timeout(unsigned long context_ptr)
+{
+	struct mthca_cmd_context *context =
+		(struct mthca_cmd_context *) context_ptr;
+
+	context->result = -EBUSY;
+	complete(&context->done);
+}
+
+static int mthca_cmd_wait(struct mthca_dev *dev,
+			  u64 in_param,
+			  u64 *out_param,
+			  int out_is_imm,
+			  u32 in_modifier,
+			  u8 op_modifier,
+			  u16 op,
+			  unsigned long timeout,
+			  u8 *status)
+{
+	int err = 0;
+	struct mthca_cmd_context *context;
+
+	if (down_interruptible(&dev->cmd.event_sem))
+		return -EINTR;
+
+	spin_lock(&dev->cmd.context_lock);
+	BUG_ON(dev->cmd.free_head < 0);
+	context = &dev->cmd.context[dev->cmd.free_head];
+	dev->cmd.free_head = context->next;
+	spin_unlock(&dev->cmd.context_lock);
+
+	init_completion(&context->done);
+
+	err = mthca_cmd_post(dev, in_param,
+			     out_param ? *out_param : 0,
+			     in_modifier, op_modifier,
+			     op, context->token, 1);
+	if (err)
+		goto out;
+
+	context->timer.expires  = jiffies + timeout;
+	add_timer(&context->timer);
+
+	wait_for_completion(&context->done);
+	del_timer_sync(&context->timer);
+
+	err = context->result;
+	if (err)
+		goto out;
+
+	*status = context->status;
+	if (*status)
+		mthca_dbg(dev, "Command %02x completed with status %02x\n",
+			  op, *status);
+
+	if (out_is_imm)
+		*out_param = context->out_param;
+
+out:
+	spin_lock(&dev->cmd.context_lock);
+	context->next = dev->cmd.free_head;
+	dev->cmd.free_head = context - dev->cmd.context;
+	spin_unlock(&dev->cmd.context_lock);
+
+	up(&dev->cmd.event_sem);
+	return err;
+}
+
+/* Invoke a command with an output mailbox */
+static int mthca_cmd_box(struct mthca_dev *dev,
+			 u64 in_param,
+			 u64 out_param,
+			 u32 in_modifier,
+			 u8 op_modifier,
+			 u16 op,
+			 unsigned long timeout,
+			 u8 *status)
+{
+	if (dev->cmd.use_events)
+		return mthca_cmd_wait(dev, in_param, &out_param, 0,
+				      in_modifier, op_modifier, op,
+				      timeout, status);
+	else
+		return mthca_cmd_poll(dev, in_param, &out_param, 0,
+				      in_modifier, op_modifier, op,
+				      timeout, status);
+}
+
+/* Invoke a command with no output parameter */
+static int mthca_cmd(struct mthca_dev *dev,
+		     u64 in_param,
+		     u32 in_modifier,
+		     u8 op_modifier,
+		     u16 op,
+		     unsigned long timeout,
+		     u8 *status)
+{
+	return mthca_cmd_box(dev, in_param, 0, in_modifier,
+			     op_modifier, op, timeout, status);
+}
+
+/*
+ * Invoke a command with an immediate output parameter (and copy the
+ * output into the caller's out_param pointer after the command
+ * executes).
+ */
+static int mthca_cmd_imm(struct mthca_dev *dev,
+			 u64 in_param,
+			 u64 *out_param,
+			 u32 in_modifier,
+			 u8 op_modifier,
+			 u16 op,
+			 unsigned long timeout,
+			 u8 *status)
+{
+	if (dev->cmd.use_events)
+		return mthca_cmd_wait(dev, in_param, out_param, 1,
+				      in_modifier, op_modifier, op,
+				      timeout, status);
+	else
+		return mthca_cmd_poll(dev, in_param, out_param, 1,
+				      in_modifier, op_modifier, op,
+				      timeout, status);
+}
+
+/*
+ * Switch to using events to issue FW commands (should be called after
+ * event queue to command events has been initialized).
+ */
+int mthca_cmd_use_events(struct mthca_dev *dev)
+{
+	int i;
+
+	dev->cmd.context = kmalloc(dev->cmd.max_cmds *
+				   sizeof (struct mthca_cmd_context),
+				   GFP_KERNEL);
+	if (!dev->cmd.context)
+		return -ENOMEM;
+
+	for (i = 0; i < dev->cmd.max_cmds; ++i) {
+		dev->cmd.context[i].token = i;
+		dev->cmd.context[i].next = i + 1;
+		init_timer(&dev->cmd.context[i].timer);
+		dev->cmd.context[i].timer.data     =
+			(unsigned long) &dev->cmd.context[i];
+		dev->cmd.context[i].timer.function = event_timeout;
+	}
+
+	dev->cmd.context[dev->cmd.max_cmds - 1].next = -1;
+	dev->cmd.free_head = 0;
+
+	sema_init(&dev->cmd.event_sem, dev->cmd.max_cmds);
+	spin_lock_init(&dev->cmd.context_lock);
+
+	for (dev->cmd.token_mask = 1;
+	     dev->cmd.token_mask < dev->cmd.max_cmds;
+	     dev->cmd.token_mask <<= 1)
+		; /* nothing */
+	--dev->cmd.token_mask;
+
+	dev->cmd.use_events = 1;
+	down(&dev->cmd.poll_sem);
+
+	return 0;
+}
+
+/*
+ * Switch back to polling (used when shutting down the device)
+ */
+void mthca_cmd_use_polling(struct mthca_dev *dev)
+{
+	int i;
+
+	dev->cmd.use_events = 0;
+
+	for (i = 0; i < dev->cmd.max_cmds; ++i)
+		down(&dev->cmd.event_sem);
+
+	kfree(dev->cmd.context);
+
+	up(&dev->cmd.poll_sem);
+}
+
+int mthca_SYS_EN(struct mthca_dev *dev, u8 *status)
+{
+	u64 out;
+	int ret;
+
+	ret = mthca_cmd_imm(dev, 0, &out, 0, 0, CMD_SYS_EN, HZ, status);
+
+	if (*status == MTHCA_CMD_STAT_DDR_MEM_ERR)
+		mthca_warn(dev, "SYS_EN DDR error: syn=%x, sock=%d, "
+			   "sladdr=%d, SPD source=%s\n",
+			   (int) (out >> 6) & 0xf, (int) (out >> 4) & 3,
+			   (int) (out >> 1) & 7, (int) out & 1 ? "NVMEM" : "DIMM");
+
+	return ret;
+}
+
+int mthca_SYS_DIS(struct mthca_dev *dev, u8 *status)
+{
+	return mthca_cmd(dev, 0, 0, 0, CMD_SYS_DIS, HZ, status);
+}
+
+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_icm_iter iter;
+	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);
+
+	for (mthca_icm_first(icm, &iter);
+	     !mthca_icm_last(&iter);
+	     mthca_icm_next(&iter)) {
+		/*
+		 * We have to pass pages that are aligned to their
+		 * size, so find the least significant 1 in the
+		 * address or size and use that as our log2 size.
+		 */
+		lg = ffs(mthca_icm_addr(&iter) | mthca_icm_size(&iter)) - 1;
+		if (lg < 12) {
+			mthca_warn(dev, "Got FW area not aligned to 4K (%llx/%lx).\n",
+				   (unsigned long long) mthca_icm_addr(&iter),
+				   mthca_icm_size(&iter));
+			err = -EINVAL;
+			goto out;
+		}
+		for (i = 0; i < mthca_icm_size(&iter) / (1 << lg); ++i, ++nent) {
+			if (virt != -1) {
+				*((__be64 *) (inbox + nent * 4)) =
+					cpu_to_be64(virt);
+				virt += 1 << lg;
+			}
+
+			*((__be64 *) (inbox + nent * 4 + 2)) =
+				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,
+						CMD_TIME_CLASS_B, status);
+				if (err || *status)
+					goto out;
+				nent = 0;
+			}
+		}
+	}
+
+	if (nent)
+		err = mthca_cmd(dev, indma, nent, 0, op,
+				CMD_TIME_CLASS_B, status);
+
+	switch (op) {
+	case CMD_MAP_FA:
+		mthca_dbg(dev, "Mapped %d chunks/%d KB for FW.\n", tc, ts);
+		break;
+	case CMD_MAP_ICM_AUX:
+		mthca_dbg(dev, "Mapped %d chunks/%d KB for ICM aux.\n", tc, ts);
+		break;
+	case CMD_MAP_ICM:
+		mthca_dbg(dev, "Mapped %d chunks/%d KB at %llx for ICM.\n",
+			  tc, ts, (unsigned long long) virt - (ts << 10));
+		break;
+	}
+
+out:
+	pci_free_consistent(dev->pdev, PAGE_SIZE, inbox, indma);
+	return err;
+}
+
+int mthca_MAP_FA(struct mthca_dev *dev, struct mthca_icm *icm, u8 *status)
+{
+	return mthca_map_cmd(dev, CMD_MAP_FA, icm, -1, status);
+}
+
+int mthca_UNMAP_FA(struct mthca_dev *dev, u8 *status)
+{
+	return mthca_cmd(dev, 0, 0, 0, CMD_UNMAP_FA, CMD_TIME_CLASS_B, status);
+}
+
+int mthca_RUN_FW(struct mthca_dev *dev, u8 *status)
+{
+	return mthca_cmd(dev, 0, 0, 0, CMD_RUN_FW, CMD_TIME_CLASS_A, status);
+}
+
+int mthca_QUERY_FW(struct mthca_dev *dev, u8 *status)
+{
+	u32 *outbox;
+	dma_addr_t outdma;
+	int err = 0;
+	u8 lg;
+
+#define QUERY_FW_OUT_SIZE             0x100
+#define QUERY_FW_VER_OFFSET            0x00
+#define QUERY_FW_MAX_CMD_OFFSET        0x0f
+#define QUERY_FW_ERR_START_OFFSET      0x30
+#define QUERY_FW_ERR_SIZE_OFFSET       0x38
+
+#define QUERY_FW_START_OFFSET          0x20
+#define QUERY_FW_END_OFFSET            0x28
+
+#define QUERY_FW_SIZE_OFFSET           0x00
+#define QUERY_FW_CLR_INT_BASE_OFFSET   0x20
+#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;
+	}
+
+	err = mthca_cmd_box(dev, 0, outdma, 0, 0, CMD_QUERY_FW,
+			    CMD_TIME_CLASS_A, status);
+
+	if (err)
+		goto out;
+
+	MTHCA_GET(dev->fw_ver,   outbox, QUERY_FW_VER_OFFSET);
+	/*
+	 * FW subminor version is at more signifant bits than minor
+	 * version, so swap here.
+	 */
+	dev->fw_ver = (dev->fw_ver & 0xffff00000000ull) |
+		((dev->fw_ver & 0xffff0000ull) >> 16) |
+		((dev->fw_ver & 0x0000ffffull) << 16);
+
+	MTHCA_GET(lg, outbox, QUERY_FW_MAX_CMD_OFFSET);
+	dev->cmd.max_cmds = 1 << lg;
+
+	mthca_dbg(dev, "FW version %012llx, max commands %d\n",
+		  (unsigned long long) dev->fw_ver, dev->cmd.max_cmds);
+
+	if (dev->hca_type == ARBEL_NATIVE) {
+		MTHCA_GET(dev->fw.arbel.fw_pages,       outbox, QUERY_FW_SIZE_OFFSET);
+		MTHCA_GET(dev->fw.arbel.clr_int_base,   outbox, QUERY_FW_CLR_INT_BASE_OFFSET);
+		MTHCA_GET(dev->fw.arbel.eq_arm_base,    outbox, QUERY_FW_EQ_ARM_BASE_OFFSET);
+		MTHCA_GET(dev->fw.arbel.eq_set_ci_base, outbox, QUERY_FW_EQ_SET_CI_BASE_OFFSET);
+		mthca_dbg(dev, "FW size %d KB\n", dev->fw.arbel.fw_pages << 2);
+
+		/*
+		 * Arbel page size is always 4 KB; round up number of
+		 * system pages needed.
+		 */
+		dev->fw.arbel.fw_pages =
+			(dev->fw.arbel.fw_pages + (1 << (PAGE_SHIFT - 12)) - 1) >>
+			(PAGE_SHIFT - 12);
+
+		mthca_dbg(dev, "Clear int @ %llx, EQ arm @ %llx, EQ set CI @ %llx\n",
+			  (unsigned long long) dev->fw.arbel.clr_int_base,
+			  (unsigned long long) dev->fw.arbel.eq_arm_base,
+			  (unsigned long long) dev->fw.arbel.eq_set_ci_base);
+	} else {
+		MTHCA_GET(dev->fw.tavor.fw_start, outbox, QUERY_FW_START_OFFSET);
+		MTHCA_GET(dev->fw.tavor.fw_end,   outbox, QUERY_FW_END_OFFSET);
+
+		mthca_dbg(dev, "FW size %d KB (start %llx, end %llx)\n",
+			  (int) ((dev->fw.tavor.fw_end - dev->fw.tavor.fw_start) >> 10),
+			  (unsigned long long) dev->fw.tavor.fw_start,
+			  (unsigned long long) dev->fw.tavor.fw_end);
+	}
+
+out:
+	pci_free_consistent(dev->pdev, QUERY_FW_OUT_SIZE, outbox, outdma);
+	return err;
+}
+
+int mthca_ENABLE_LAM(struct mthca_dev *dev, u8 *status)
+{
+	u8 info;
+	u32 *outbox;
+	dma_addr_t outdma;
+	int err = 0;
+
+#define ENABLE_LAM_OUT_SIZE         0x100
+#define ENABLE_LAM_START_OFFSET     0x00
+#define ENABLE_LAM_END_OFFSET       0x08
+#define ENABLE_LAM_INFO_OFFSET      0x13
+
+#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;
+
+	err = mthca_cmd_box(dev, 0, outdma, 0, 0, CMD_ENABLE_LAM,
+			    CMD_TIME_CLASS_C, status);
+
+	if (err)
+		goto out;
+
+	if (*status == MTHCA_CMD_STAT_LAM_NOT_PRE)
+		goto out;
+
+	MTHCA_GET(dev->ddr_start, outbox, ENABLE_LAM_START_OFFSET);
+	MTHCA_GET(dev->ddr_end,   outbox, ENABLE_LAM_END_OFFSET);
+	MTHCA_GET(info,           outbox, ENABLE_LAM_INFO_OFFSET);
+
+	if (!!(info & ENABLE_LAM_INFO_HIDDEN_FLAG) !=
+	    !!(dev->mthca_flags & MTHCA_FLAG_DDR_HIDDEN)) {
+		mthca_info(dev, "FW reports that HCA-attached memory "
+			   "is %s hidden; does not match PCI config\n",
+			   (info & ENABLE_LAM_INFO_HIDDEN_FLAG) ?
+			   "" : "not");
+	}
+	if (info & ENABLE_LAM_INFO_HIDDEN_FLAG)
+		mthca_dbg(dev, "HCA-attached memory is hidden.\n");
+
+	mthca_dbg(dev, "HCA memory size %d KB (start %llx, end %llx)\n",
+		  (int) ((dev->ddr_end - dev->ddr_start) >> 10),
+		  (unsigned long long) dev->ddr_start,
+		  (unsigned long long) dev->ddr_end);
+
+out:
+	pci_free_consistent(dev->pdev, ENABLE_LAM_OUT_SIZE, outbox, outdma);
+	return err;
+}
+
+int mthca_DISABLE_LAM(struct mthca_dev *dev, u8 *status)
+{
+	return mthca_cmd(dev, 0, 0, 0, CMD_SYS_DIS, CMD_TIME_CLASS_C, status);
+}
+
+int mthca_QUERY_DDR(struct mthca_dev *dev, u8 *status)
+{
+	u8 info;
+	u32 *outbox;
+	dma_addr_t outdma;
+	int err = 0;
+
+#define QUERY_DDR_OUT_SIZE         0x100
+#define QUERY_DDR_START_OFFSET     0x00
+#define QUERY_DDR_END_OFFSET       0x08
+#define QUERY_DDR_INFO_OFFSET      0x13
+
+#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;
+
+	err = mthca_cmd_box(dev, 0, outdma, 0, 0, CMD_QUERY_DDR,
+			    CMD_TIME_CLASS_A, status);
+
+	if (err)
+		goto out;
+
+	MTHCA_GET(dev->ddr_start, outbox, QUERY_DDR_START_OFFSET);
+	MTHCA_GET(dev->ddr_end,   outbox, QUERY_DDR_END_OFFSET);
+	MTHCA_GET(info,           outbox, QUERY_DDR_INFO_OFFSET);
+
+	if (!!(info & QUERY_DDR_INFO_HIDDEN_FLAG) !=
+	    !!(dev->mthca_flags & MTHCA_FLAG_DDR_HIDDEN)) {
+		mthca_info(dev, "FW reports that HCA-attached memory "
+			   "is %s hidden; does not match PCI config\n",
+			   (info & QUERY_DDR_INFO_HIDDEN_FLAG) ?
+			   "" : "not");
+	}
+	if (info & QUERY_DDR_INFO_HIDDEN_FLAG)
+		mthca_dbg(dev, "HCA-attached memory is hidden.\n");
+
+	mthca_dbg(dev, "HCA memory size %d KB (start %llx, end %llx)\n",
+		  (int) ((dev->ddr_end - dev->ddr_start) >> 10),
+		  (unsigned long long) dev->ddr_start,
+		  (unsigned long long) dev->ddr_end);
+
+out:
+	pci_free_consistent(dev->pdev, QUERY_DDR_OUT_SIZE, outbox, outdma);
+	return err;
+}
+
+int mthca_QUERY_DEV_LIM(struct mthca_dev *dev,
+			struct mthca_dev_lim *dev_lim, u8 *status)
+{
+	u32 *outbox;
+	dma_addr_t outdma;
+	u8 field;
+	u16 size;
+	int err;
+
+#define QUERY_DEV_LIM_OUT_SIZE             0x100
+#define QUERY_DEV_LIM_MAX_SRQ_SZ_OFFSET     0x10
+#define QUERY_DEV_LIM_MAX_QP_SZ_OFFSET      0x11
+#define QUERY_DEV_LIM_RSVD_QP_OFFSET        0x12
+#define QUERY_DEV_LIM_MAX_QP_OFFSET         0x13
+#define QUERY_DEV_LIM_RSVD_SRQ_OFFSET       0x14
+#define QUERY_DEV_LIM_MAX_SRQ_OFFSET        0x15
+#define QUERY_DEV_LIM_RSVD_EEC_OFFSET       0x16
+#define QUERY_DEV_LIM_MAX_EEC_OFFSET        0x17
+#define QUERY_DEV_LIM_MAX_CQ_SZ_OFFSET      0x19
+#define QUERY_DEV_LIM_RSVD_CQ_OFFSET        0x1a
+#define QUERY_DEV_LIM_MAX_CQ_OFFSET         0x1b
+#define QUERY_DEV_LIM_MAX_MPT_OFFSET        0x1d
+#define QUERY_DEV_LIM_RSVD_EQ_OFFSET        0x1e
+#define QUERY_DEV_LIM_MAX_EQ_OFFSET         0x1f
+#define QUERY_DEV_LIM_RSVD_MTT_OFFSET       0x20
+#define QUERY_DEV_LIM_MAX_MRW_SZ_OFFSET     0x21
+#define QUERY_DEV_LIM_RSVD_MRW_OFFSET       0x22
+#define QUERY_DEV_LIM_MAX_MTT_SEG_OFFSET    0x23
+#define QUERY_DEV_LIM_MAX_AV_OFFSET         0x27
+#define QUERY_DEV_LIM_MAX_REQ_QP_OFFSET     0x29
+#define QUERY_DEV_LIM_MAX_RES_QP_OFFSET     0x2b
+#define QUERY_DEV_LIM_MAX_RDMA_OFFSET       0x2f
+#define QUERY_DEV_LIM_RSZ_SRQ_OFFSET        0x33
+#define QUERY_DEV_LIM_ACK_DELAY_OFFSET      0x35
+#define QUERY_DEV_LIM_MTU_WIDTH_OFFSET      0x36
+#define QUERY_DEV_LIM_VL_PORT_OFFSET        0x37
+#define QUERY_DEV_LIM_MAX_GID_OFFSET        0x3b
+#define QUERY_DEV_LIM_MAX_PKEY_OFFSET       0x3f
+#define QUERY_DEV_LIM_FLAGS_OFFSET          0x44
+#define QUERY_DEV_LIM_RSVD_UAR_OFFSET       0x48
+#define QUERY_DEV_LIM_UAR_SZ_OFFSET         0x49
+#define QUERY_DEV_LIM_PAGE_SZ_OFFSET        0x4b
+#define QUERY_DEV_LIM_MAX_SG_OFFSET         0x51
+#define QUERY_DEV_LIM_MAX_DESC_SZ_OFFSET    0x52
+#define QUERY_DEV_LIM_MAX_SG_RQ_OFFSET      0x55
+#define QUERY_DEV_LIM_MAX_DESC_SZ_RQ_OFFSET 0x56
+#define QUERY_DEV_LIM_MAX_QP_MCG_OFFSET     0x61
+#define QUERY_DEV_LIM_RSVD_MCG_OFFSET       0x62
+#define QUERY_DEV_LIM_MAX_MCG_OFFSET        0x63
+#define QUERY_DEV_LIM_RSVD_PD_OFFSET        0x64
+#define QUERY_DEV_LIM_MAX_PD_OFFSET         0x65
+#define QUERY_DEV_LIM_RSVD_RDD_OFFSET       0x66
+#define QUERY_DEV_LIM_MAX_RDD_OFFSET        0x67
+#define QUERY_DEV_LIM_EEC_ENTRY_SZ_OFFSET   0x80
+#define QUERY_DEV_LIM_QPC_ENTRY_SZ_OFFSET   0x82
+#define QUERY_DEV_LIM_EEEC_ENTRY_SZ_OFFSET  0x84
+#define QUERY_DEV_LIM_EQPC_ENTRY_SZ_OFFSET  0x86
+#define QUERY_DEV_LIM_EQC_ENTRY_SZ_OFFSET   0x88
+#define QUERY_DEV_LIM_CQC_ENTRY_SZ_OFFSET   0x8a
+#define QUERY_DEV_LIM_SRQ_ENTRY_SZ_OFFSET   0x8c
+#define QUERY_DEV_LIM_UAR_ENTRY_SZ_OFFSET   0x8e
+#define QUERY_DEV_LIM_MTT_ENTRY_SZ_OFFSET   0x90
+#define QUERY_DEV_LIM_MPT_ENTRY_SZ_OFFSET   0x92
+#define QUERY_DEV_LIM_PBL_SZ_OFFSET         0x96
+#define QUERY_DEV_LIM_BMME_FLAGS_OFFSET     0x97
+#define QUERY_DEV_LIM_RSVD_LKEY_OFFSET      0x98
+#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;
+
+	err = mthca_cmd_box(dev, 0, outdma, 0, 0, CMD_QUERY_DEV_LIM,
+			    CMD_TIME_CLASS_A, status);
+
+	if (err)
+		goto out;
+
+	MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_SRQ_SZ_OFFSET);
+	dev_lim->max_srq_sz = 1 << field;
+	MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_QP_SZ_OFFSET);
+	dev_lim->max_qp_sz = 1 << field;
+	MTHCA_GET(field, outbox, QUERY_DEV_LIM_RSVD_QP_OFFSET);
+	dev_lim->reserved_qps = 1 << (field & 0xf);
+	MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_QP_OFFSET);
+	dev_lim->max_qps = 1 << (field & 0x1f);
+	MTHCA_GET(field, outbox, QUERY_DEV_LIM_RSVD_SRQ_OFFSET);
+	dev_lim->reserved_srqs = 1 << (field >> 4);
+	MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_SRQ_OFFSET);
+	dev_lim->max_srqs = 1 << (field & 0x1f);
+	MTHCA_GET(field, outbox, QUERY_DEV_LIM_RSVD_EEC_OFFSET);
+	dev_lim->reserved_eecs = 1 << (field & 0xf);
+	MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_EEC_OFFSET);
+	dev_lim->max_eecs = 1 << (field & 0x1f);
+	MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_CQ_SZ_OFFSET);
+	dev_lim->max_cq_sz = 1 << field;
+	MTHCA_GET(field, outbox, QUERY_DEV_LIM_RSVD_CQ_OFFSET);
+	dev_lim->reserved_cqs = 1 << (field & 0xf);
+	MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_CQ_OFFSET);
+	dev_lim->max_cqs = 1 << (field & 0x1f);
+	MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_MPT_OFFSET);
+	dev_lim->max_mpts = 1 << (field & 0x3f);
+	MTHCA_GET(field, outbox, QUERY_DEV_LIM_RSVD_EQ_OFFSET);
+	dev_lim->reserved_eqs = 1 << (field & 0xf);
+	MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_EQ_OFFSET);
+	dev_lim->max_eqs = 1 << (field & 0x7);
+	MTHCA_GET(field, outbox, QUERY_DEV_LIM_RSVD_MTT_OFFSET);
+	dev_lim->reserved_mtts = 1 << (field >> 4);
+	MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_MRW_SZ_OFFSET);
+	dev_lim->max_mrw_sz = 1 << field;
+	MTHCA_GET(field, outbox, QUERY_DEV_LIM_RSVD_MRW_OFFSET);
+	dev_lim->reserved_mrws = 1 << (field & 0xf);
+	MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_MTT_SEG_OFFSET);
+	dev_lim->max_mtt_seg = 1 << (field & 0x3f);
+	MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_REQ_QP_OFFSET);
+	dev_lim->max_requester_per_qp = 1 << (field & 0x3f);
+	MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_RES_QP_OFFSET);
+	dev_lim->max_responder_per_qp = 1 << (field & 0x3f);
+	MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_RDMA_OFFSET);
+	dev_lim->max_rdma_global = 1 << (field & 0x3f);
+	MTHCA_GET(field, outbox, QUERY_DEV_LIM_ACK_DELAY_OFFSET);
+	dev_lim->local_ca_ack_delay = field & 0x1f;
+	MTHCA_GET(field, outbox, QUERY_DEV_LIM_MTU_WIDTH_OFFSET);
+	dev_lim->max_mtu        = field >> 4;
+	dev_lim->max_port_width = field & 0xf;
+	MTHCA_GET(field, outbox, QUERY_DEV_LIM_VL_PORT_OFFSET);
+	dev_lim->max_vl    = field >> 4;
+	dev_lim->num_ports = field & 0xf;
+	MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_GID_OFFSET);
+	dev_lim->max_gids = 1 << (field & 0xf);
+	MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_PKEY_OFFSET);
+	dev_lim->max_pkeys = 1 << (field & 0xf);
+	MTHCA_GET(dev_lim->flags, outbox, QUERY_DEV_LIM_FLAGS_OFFSET);
+	MTHCA_GET(field, outbox, QUERY_DEV_LIM_RSVD_UAR_OFFSET);
+	dev_lim->reserved_uars = field >> 4;
+	MTHCA_GET(field, outbox, QUERY_DEV_LIM_UAR_SZ_OFFSET);
+	dev_lim->uar_size = 1 << ((field & 0x3f) + 20);
+	MTHCA_GET(field, outbox, QUERY_DEV_LIM_PAGE_SZ_OFFSET);
+	dev_lim->min_page_sz = 1 << field;
+	MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_SG_OFFSET);
+	dev_lim->max_sg = field;
+
+	MTHCA_GET(size, outbox, QUERY_DEV_LIM_MAX_DESC_SZ_OFFSET);
+	dev_lim->max_desc_sz = size;
+
+	MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_QP_MCG_OFFSET);
+	dev_lim->max_qp_per_mcg = 1 << field;
+	MTHCA_GET(field, outbox, QUERY_DEV_LIM_RSVD_MCG_OFFSET);
+	dev_lim->reserved_mgms = field & 0xf;
+	MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_MCG_OFFSET);
+	dev_lim->max_mcgs = 1 << field;
+	MTHCA_GET(field, outbox, QUERY_DEV_LIM_RSVD_PD_OFFSET);
+	dev_lim->reserved_pds = field >> 4;
+	MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_PD_OFFSET);
+	dev_lim->max_pds = 1 << (field & 0x3f);
+	MTHCA_GET(field, outbox, QUERY_DEV_LIM_RSVD_RDD_OFFSET);
+	dev_lim->reserved_rdds = field >> 4;
+	MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_RDD_OFFSET);
+	dev_lim->max_rdds = 1 << (field & 0x3f);
+
+	MTHCA_GET(size, outbox, QUERY_DEV_LIM_EEC_ENTRY_SZ_OFFSET);
+	dev_lim->eec_entry_sz = size;
+	MTHCA_GET(size, outbox, QUERY_DEV_LIM_QPC_ENTRY_SZ_OFFSET);
+	dev_lim->qpc_entry_sz = size;
+	MTHCA_GET(size, outbox, QUERY_DEV_LIM_EEEC_ENTRY_SZ_OFFSET);
+	dev_lim->eeec_entry_sz = size;
+	MTHCA_GET(size, outbox, QUERY_DEV_LIM_EQPC_ENTRY_SZ_OFFSET);
+	dev_lim->eqpc_entry_sz = size;
+	MTHCA_GET(size, outbox, QUERY_DEV_LIM_EQC_ENTRY_SZ_OFFSET);
+	dev_lim->eqc_entry_sz = size;
+	MTHCA_GET(size, outbox, QUERY_DEV_LIM_CQC_ENTRY_SZ_OFFSET);
+	dev_lim->cqc_entry_sz = size;
+	MTHCA_GET(size, outbox, QUERY_DEV_LIM_SRQ_ENTRY_SZ_OFFSET);
+	dev_lim->srq_entry_sz = size;
+	MTHCA_GET(size, outbox, QUERY_DEV_LIM_UAR_ENTRY_SZ_OFFSET);
+	dev_lim->uar_scratch_entry_sz = size;
+
+	mthca_dbg(dev, "Max QPs: %d, reserved QPs: %d, entry size: %d\n",
+		  dev_lim->max_qps, dev_lim->reserved_qps, dev_lim->qpc_entry_sz);
+	mthca_dbg(dev, "Max CQs: %d, reserved CQs: %d, entry size: %d\n",
+		  dev_lim->max_cqs, dev_lim->reserved_cqs, dev_lim->cqc_entry_sz);
+	mthca_dbg(dev, "Max EQs: %d, reserved EQs: %d, entry size: %d\n",
+		  dev_lim->max_eqs, dev_lim->reserved_eqs, dev_lim->eqc_entry_sz);
+	mthca_dbg(dev, "reserved MPTs: %d, reserved MTTs: %d\n",
+		  dev_lim->reserved_mrws, dev_lim->reserved_mtts);
+	mthca_dbg(dev, "Max PDs: %d, reserved PDs: %d, reserved UARs: %d\n",
+		  dev_lim->max_pds, dev_lim->reserved_pds, dev_lim->reserved_uars);
+	mthca_dbg(dev, "Max QP/MCG: %d, reserved MGMs: %d\n",
+		  dev_lim->max_pds, dev_lim->reserved_mgms);
+
+	mthca_dbg(dev, "Flags: %08x\n", dev_lim->flags);
+
+	if (dev->hca_type == ARBEL_NATIVE) {
+		MTHCA_GET(field, outbox, QUERY_DEV_LIM_RSZ_SRQ_OFFSET);
+		dev_lim->hca.arbel.resize_srq = field & 1;
+		MTHCA_GET(size, outbox, QUERY_DEV_LIM_MTT_ENTRY_SZ_OFFSET);
+		dev_lim->mtt_seg_sz = size;
+		MTHCA_GET(size, outbox, QUERY_DEV_LIM_MPT_ENTRY_SZ_OFFSET);
+		dev_lim->mpt_entry_sz = size;
+		MTHCA_GET(field, outbox, QUERY_DEV_LIM_PBL_SZ_OFFSET);
+		dev_lim->hca.arbel.max_pbl_sz = 1 << (field & 0x3f);
+		MTHCA_GET(dev_lim->hca.arbel.bmme_flags, outbox,
+			  QUERY_DEV_LIM_BMME_FLAGS_OFFSET);
+		MTHCA_GET(dev_lim->hca.arbel.reserved_lkey, outbox,
+			  QUERY_DEV_LIM_RSVD_LKEY_OFFSET);
+		MTHCA_GET(field, outbox, QUERY_DEV_LIM_LAMR_OFFSET);
+		dev_lim->hca.arbel.lam_required = field & 1;
+		MTHCA_GET(dev_lim->hca.arbel.max_icm_sz, outbox,
+			  QUERY_DEV_LIM_MAX_ICM_SZ_OFFSET);
+
+		if (dev_lim->hca.arbel.bmme_flags & 1)
+			mthca_dbg(dev, "Base MM extensions: yes "
+				  "(flags %d, max PBL %d, rsvd L_Key %08x)\n",
+				  dev_lim->hca.arbel.bmme_flags,
+				  dev_lim->hca.arbel.max_pbl_sz,
+				  dev_lim->hca.arbel.reserved_lkey);
+		else
+			mthca_dbg(dev, "Base MM extensions: no\n");
+
+		mthca_dbg(dev, "Max ICM size %lld MB\n",
+			  (unsigned long long) dev_lim->hca.arbel.max_icm_sz >> 20);
+	} else {
+		MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_AV_OFFSET);
+		dev_lim->hca.tavor.max_avs = 1 << (field & 0x3f);
+		dev_lim->mtt_seg_sz   = MTHCA_MTT_SEG_SIZE;
+		dev_lim->mpt_entry_sz = MTHCA_MPT_ENTRY_SIZE;
+	}
+
+out:
+	pci_free_consistent(dev->pdev, QUERY_DEV_LIM_OUT_SIZE, outbox, outdma);
+	return err;
+}
+
+int mthca_QUERY_ADAPTER(struct mthca_dev *dev,
+			struct mthca_adapter *adapter, u8 *status)
+{
+	u32 *outbox;
+	dma_addr_t outdma;
+	int err;
+
+#define QUERY_ADAPTER_OUT_SIZE             0x100
+#define QUERY_ADAPTER_VENDOR_ID_OFFSET     0x00
+#define QUERY_ADAPTER_DEVICE_ID_OFFSET     0x04
+#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;
+
+	err = mthca_cmd_box(dev, 0, outdma, 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->revision_id, outbox, QUERY_ADAPTER_REVISION_ID_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);
+	return err;
+}
+
+int mthca_INIT_HCA(struct mthca_dev *dev,
+		   struct mthca_init_hca_param *param,
+		   u8 *status)
+{
+	u32 *inbox;
+	dma_addr_t indma;
+	int err;
+
+#define INIT_HCA_IN_SIZE             	 0x200
+#define INIT_HCA_FLAGS_OFFSET        	 0x014
+#define INIT_HCA_QPC_OFFSET          	 0x020
+#define  INIT_HCA_QPC_BASE_OFFSET    	 (INIT_HCA_QPC_OFFSET + 0x10)
+#define  INIT_HCA_LOG_QP_OFFSET      	 (INIT_HCA_QPC_OFFSET + 0x17)
+#define  INIT_HCA_EEC_BASE_OFFSET    	 (INIT_HCA_QPC_OFFSET + 0x20)
+#define  INIT_HCA_LOG_EEC_OFFSET     	 (INIT_HCA_QPC_OFFSET + 0x27)
+#define  INIT_HCA_SRQC_BASE_OFFSET   	 (INIT_HCA_QPC_OFFSET + 0x28)
+#define  INIT_HCA_LOG_SRQ_OFFSET     	 (INIT_HCA_QPC_OFFSET + 0x2f)
+#define  INIT_HCA_CQC_BASE_OFFSET    	 (INIT_HCA_QPC_OFFSET + 0x30)
+#define  INIT_HCA_LOG_CQ_OFFSET      	 (INIT_HCA_QPC_OFFSET + 0x37)
+#define  INIT_HCA_EQPC_BASE_OFFSET   	 (INIT_HCA_QPC_OFFSET + 0x40)
+#define  INIT_HCA_EEEC_BASE_OFFSET   	 (INIT_HCA_QPC_OFFSET + 0x50)
+#define  INIT_HCA_EQC_BASE_OFFSET    	 (INIT_HCA_QPC_OFFSET + 0x60)
+#define  INIT_HCA_LOG_EQ_OFFSET      	 (INIT_HCA_QPC_OFFSET + 0x67)
+#define  INIT_HCA_RDB_BASE_OFFSET    	 (INIT_HCA_QPC_OFFSET + 0x70)
+#define INIT_HCA_UDAV_OFFSET         	 0x0b0
+#define  INIT_HCA_UDAV_LKEY_OFFSET   	 (INIT_HCA_UDAV_OFFSET + 0x0)
+#define  INIT_HCA_UDAV_PD_OFFSET     	 (INIT_HCA_UDAV_OFFSET + 0x4)
+#define INIT_HCA_MCAST_OFFSET        	 0x0c0
+#define  INIT_HCA_MC_BASE_OFFSET         (INIT_HCA_MCAST_OFFSET + 0x00)
+#define  INIT_HCA_LOG_MC_ENTRY_SZ_OFFSET (INIT_HCA_MCAST_OFFSET + 0x12)
+#define  INIT_HCA_MC_HASH_SZ_OFFSET      (INIT_HCA_MCAST_OFFSET + 0x16)
+#define  INIT_HCA_LOG_MC_TABLE_SZ_OFFSET (INIT_HCA_MCAST_OFFSET + 0x1b)
+#define INIT_HCA_TPT_OFFSET              0x0f0
+#define  INIT_HCA_MPT_BASE_OFFSET        (INIT_HCA_TPT_OFFSET + 0x00)
+#define  INIT_HCA_MTT_SEG_SZ_OFFSET      (INIT_HCA_TPT_OFFSET + 0x09)
+#define  INIT_HCA_LOG_MPT_SZ_OFFSET      (INIT_HCA_TPT_OFFSET + 0x0b)
+#define  INIT_HCA_MTT_BASE_OFFSET        (INIT_HCA_TPT_OFFSET + 0x10)
+#define INIT_HCA_UAR_OFFSET              0x120
+#define  INIT_HCA_UAR_BASE_OFFSET        (INIT_HCA_UAR_OFFSET + 0x00)
+#define  INIT_HCA_UARC_SZ_OFFSET         (INIT_HCA_UAR_OFFSET + 0x09)
+#define  INIT_HCA_LOG_UAR_SZ_OFFSET      (INIT_HCA_UAR_OFFSET + 0x0a)
+#define  INIT_HCA_UAR_PAGE_SZ_OFFSET     (INIT_HCA_UAR_OFFSET + 0x0b)
+#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;
+
+	memset(inbox, 0, INIT_HCA_IN_SIZE);
+
+#if defined(__LITTLE_ENDIAN)
+	*(inbox + INIT_HCA_FLAGS_OFFSET / 4) &= ~cpu_to_be32(1 << 1);
+#elif defined(__BIG_ENDIAN)
+	*(inbox + INIT_HCA_FLAGS_OFFSET / 4) |= cpu_to_be32(1 << 1);
+#else
+#error Host endianness not defined
+#endif
+	/* Check port for UD address vector: */
+	*(inbox + INIT_HCA_FLAGS_OFFSET / 4) |= cpu_to_be32(1);
+
+	/* We leave wqe_quota, responder_exu, etc as 0 (default) */
+
+	/* QPC/EEC/CQC/EQC/RDB attributes */
+
+	MTHCA_PUT(inbox, param->qpc_base,     INIT_HCA_QPC_BASE_OFFSET);
+	MTHCA_PUT(inbox, param->log_num_qps,  INIT_HCA_LOG_QP_OFFSET);
+	MTHCA_PUT(inbox, param->eec_base,     INIT_HCA_EEC_BASE_OFFSET);
+	MTHCA_PUT(inbox, param->log_num_eecs, INIT_HCA_LOG_EEC_OFFSET);
+	MTHCA_PUT(inbox, param->srqc_base,    INIT_HCA_SRQC_BASE_OFFSET);
+	MTHCA_PUT(inbox, param->log_num_srqs, INIT_HCA_LOG_SRQ_OFFSET);
+	MTHCA_PUT(inbox, param->cqc_base,     INIT_HCA_CQC_BASE_OFFSET);
+	MTHCA_PUT(inbox, param->log_num_cqs,  INIT_HCA_LOG_CQ_OFFSET);
+	MTHCA_PUT(inbox, param->eqpc_base,    INIT_HCA_EQPC_BASE_OFFSET);
+	MTHCA_PUT(inbox, param->eeec_base,    INIT_HCA_EEEC_BASE_OFFSET);
+	MTHCA_PUT(inbox, param->eqc_base,     INIT_HCA_EQC_BASE_OFFSET);
+	MTHCA_PUT(inbox, param->log_num_eqs,  INIT_HCA_LOG_EQ_OFFSET);
+	MTHCA_PUT(inbox, param->rdb_base,     INIT_HCA_RDB_BASE_OFFSET);
+
+	/* UD AV attributes */
+
+	/* multicast attributes */
+
+	MTHCA_PUT(inbox, param->mc_base,         INIT_HCA_MC_BASE_OFFSET);
+	MTHCA_PUT(inbox, param->log_mc_entry_sz, INIT_HCA_LOG_MC_ENTRY_SZ_OFFSET);
+	MTHCA_PUT(inbox, param->mc_hash_sz,      INIT_HCA_MC_HASH_SZ_OFFSET);
+	MTHCA_PUT(inbox, param->log_mc_table_sz, INIT_HCA_LOG_MC_TABLE_SZ_OFFSET);
+
+	/* TPT attributes */
+
+	MTHCA_PUT(inbox, param->mpt_base,   INIT_HCA_MPT_BASE_OFFSET);
+	if (dev->hca_type != ARBEL_NATIVE)
+		MTHCA_PUT(inbox, param->mtt_seg_sz, INIT_HCA_MTT_SEG_SZ_OFFSET);
+	MTHCA_PUT(inbox, param->log_mpt_sz, INIT_HCA_LOG_MPT_SZ_OFFSET);
+	MTHCA_PUT(inbox, param->mtt_base,   INIT_HCA_MTT_BASE_OFFSET);
+
+	/* UAR attributes */
+	{
+		u8 uar_page_sz = PAGE_SHIFT - 12;
+		MTHCA_PUT(inbox, uar_page_sz, INIT_HCA_UAR_PAGE_SZ_OFFSET);
+	}
+
+	MTHCA_PUT(inbox, param->uar_scratch_base, INIT_HCA_UAR_SCATCH_BASE_OFFSET);
+
+	if (dev->hca_type == ARBEL_NATIVE) {
+		MTHCA_PUT(inbox, param->log_uarc_sz, INIT_HCA_UARC_SZ_OFFSET);
+		MTHCA_PUT(inbox, param->log_uar_sz,  INIT_HCA_LOG_UAR_SZ_OFFSET);
+		MTHCA_PUT(inbox, param->uarc_base,   INIT_HCA_UAR_CTX_BASE_OFFSET);
+	}
+
+	err = mthca_cmd(dev, indma, 0, 0, CMD_INIT_HCA,
+			HZ, status);
+
+	pci_free_consistent(dev->pdev, INIT_HCA_IN_SIZE, inbox, indma);
+	return err;
+}
+
+int mthca_INIT_IB(struct mthca_dev *dev,
+		  struct mthca_init_ib_param *param,
+		  int port, u8 *status)
+{
+	u32 *inbox;
+	dma_addr_t indma;
+	int err;
+	u32 flags;
+
+#define INIT_IB_IN_SIZE          56
+#define INIT_IB_FLAGS_OFFSET     0x00
+#define INIT_IB_FLAG_SIG         (1 << 18)
+#define INIT_IB_FLAG_NG          (1 << 17)
+#define INIT_IB_FLAG_G0          (1 << 16)
+#define INIT_IB_FLAG_1X          (1 << 8)
+#define INIT_IB_FLAG_4X          (1 << 9)
+#define INIT_IB_FLAG_12X         (1 << 11)
+#define INIT_IB_VL_SHIFT         4
+#define INIT_IB_MTU_SHIFT        12
+#define INIT_IB_MAX_GID_OFFSET   0x06
+#define INIT_IB_MAX_PKEY_OFFSET  0x0a
+#define INIT_IB_GUID0_OFFSET     0x10
+#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;
+
+	memset(inbox, 0, INIT_IB_IN_SIZE);
+
+	flags = 0;
+	flags |= param->enable_1x     ? INIT_IB_FLAG_1X  : 0;
+	flags |= param->enable_4x     ? INIT_IB_FLAG_4X  : 0;
+	flags |= param->set_guid0     ? INIT_IB_FLAG_G0  : 0;
+	flags |= param->set_node_guid ? INIT_IB_FLAG_NG  : 0;
+	flags |= param->set_si_guid   ? INIT_IB_FLAG_SIG : 0;
+	flags |= param->vl_cap << INIT_IB_VL_SHIFT;
+	flags |= param->mtu_cap << INIT_IB_MTU_SHIFT;
+	MTHCA_PUT(inbox, flags, INIT_IB_FLAGS_OFFSET);
+
+	MTHCA_PUT(inbox, param->gid_cap,   INIT_IB_MAX_GID_OFFSET);
+	MTHCA_PUT(inbox, param->pkey_cap,  INIT_IB_MAX_PKEY_OFFSET);
+	MTHCA_PUT(inbox, param->guid0,     INIT_IB_GUID0_OFFSET);
+	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,
+			CMD_TIME_CLASS_A, status);
+
+	pci_free_consistent(dev->pdev, INIT_HCA_IN_SIZE, inbox, indma);
+	return err;
+}
+
+int mthca_CLOSE_IB(struct mthca_dev *dev, int port, u8 *status)
+{
+	return mthca_cmd(dev, 0, port, 0, CMD_CLOSE_IB, HZ, status);
+}
+
+int mthca_CLOSE_HCA(struct mthca_dev *dev, int panic, u8 *status)
+{
+	return mthca_cmd(dev, 0, 0, panic, CMD_CLOSE_HCA, HZ, status);
+}
+
+int mthca_SET_IB(struct mthca_dev *dev, struct mthca_set_ib_param *param,
+		 int port, u8 *status)
+{
+	u32 *inbox;
+	dma_addr_t indma;
+	int err;
+	u32 flags = 0;
+
+#define SET_IB_IN_SIZE         0x40
+#define SET_IB_FLAGS_OFFSET    0x00
+#define SET_IB_FLAG_SIG        (1 << 18)
+#define SET_IB_FLAG_RQK        (1 <<  0)
+#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;
+
+	memset(inbox, 0, SET_IB_IN_SIZE);
+
+	flags |= param->set_si_guid     ? SET_IB_FLAG_SIG : 0;
+	flags |= param->reset_qkey_viol ? SET_IB_FLAG_RQK : 0;
+	MTHCA_PUT(inbox, flags, SET_IB_FLAGS_OFFSET);
+
+	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,
+			CMD_TIME_CLASS_B, status);
+
+	pci_free_consistent(dev->pdev, INIT_HCA_IN_SIZE, inbox, indma);
+	return err;
+}
+
+int mthca_MAP_ICM(struct mthca_dev *dev, struct mthca_icm *icm, u64 virt, u8 *status)
+{
+	return mthca_map_cmd(dev, CMD_MAP_ICM, icm, virt, status);
+}
+
+int mthca_MAP_ICM_page(struct mthca_dev *dev, u64 dma_addr, u64 virt, u8 *status)
+{
+	u64 *inbox;
+	dma_addr_t indma;
+	int err;
+
+	inbox = pci_alloc_consistent(dev->pdev, 16, &indma);
+	if (!inbox)
+		return -ENOMEM;
+
+	inbox[0] = cpu_to_be64(virt);
+	inbox[1] = cpu_to_be64(dma_addr | (PAGE_SHIFT - 12));
+
+	err = mthca_cmd(dev, indma, 1, 0, CMD_MAP_ICM, CMD_TIME_CLASS_B, status);
+
+	pci_free_consistent(dev->pdev, 16, inbox, indma);
+
+	if (!err)
+		mthca_dbg(dev, "Mapped page at %llx for ICM.\n",
+			  (unsigned long long) virt);
+
+	return err;
+}
+
+int mthca_UNMAP_ICM(struct mthca_dev *dev, u64 virt, u32 page_count, u8 *status)
+{
+	return mthca_cmd(dev, virt, page_count, 0, CMD_UNMAP_ICM, CMD_TIME_CLASS_B, status);
+}
+
+int mthca_MAP_ICM_AUX(struct mthca_dev *dev, struct mthca_icm *icm, u8 *status)
+{
+	return mthca_map_cmd(dev, CMD_MAP_ICM_AUX, icm, -1, status);
+}
+
+int mthca_UNMAP_ICM_AUX(struct mthca_dev *dev, u8 *status)
+{
+	return mthca_cmd(dev, 0, 0, 0, CMD_UNMAP_ICM_AUX, CMD_TIME_CLASS_B, status);
+}
+
+int mthca_SET_ICM_SIZE(struct mthca_dev *dev, u64 icm_size, u64 *aux_pages,
+		       u8 *status)
+{
+	int ret = mthca_cmd_imm(dev, icm_size, aux_pages, 0, 0, CMD_SET_ICM_SIZE,
+				CMD_TIME_CLASS_A, status);
+
+	if (ret || status)
+		return ret;
+
+	/*
+	 * Arbel page size is always 4 KB; round up number of system
+	 * pages needed.
+	 */
+	*aux_pages = (*aux_pages + (1 << (PAGE_SHIFT - 12)) - 1) >> (PAGE_SHIFT - 12);
+
+	return 0;
+}
+
+int mthca_SW2HW_MPT(struct mthca_dev *dev, void *mpt_entry,
+		    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;
+}
+
+int mthca_HW2SW_MPT(struct mthca_dev *dev, void *mpt_entry,
+		    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;
+}
+
+int mthca_WRITE_MTT(struct mthca_dev *dev, u64 *mtt_entry,
+		    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;
+}
+
+int mthca_MAP_EQ(struct mthca_dev *dev, u64 event_mask, int unmap,
+		 int eq_num, u8 *status)
+{
+	mthca_dbg(dev, "%s mask %016llx for eqn %d\n",
+		  unmap ? "Clearing" : "Setting",
+		  (unsigned long long) event_mask, eq_num);
+	return mthca_cmd(dev, event_mask, (unmap << 31) | eq_num,
+			 0, CMD_MAP_EQ, CMD_TIME_CLASS_B, status);
+}
+
+int mthca_SW2HW_EQ(struct mthca_dev *dev, void *eq_context,
+		   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;
+}
+
+int mthca_HW2SW_EQ(struct mthca_dev *dev, void *eq_context,
+		   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;
+}
+
+int mthca_SW2HW_CQ(struct mthca_dev *dev, void *cq_context,
+		   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,
+			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 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;
+}
+
+int mthca_MODIFY_QP(struct mthca_dev *dev, int trans, u32 num,
+		    int is_ee, void *qp_context, u32 optmask,
+		    u8 *status)
+{
+	static const u16 op[] = {
+		[MTHCA_TRANS_RST2INIT]  = CMD_RST2INIT_QPEE,
+		[MTHCA_TRANS_INIT2INIT] = CMD_INIT2INIT_QPEE,
+		[MTHCA_TRANS_INIT2RTR]  = CMD_INIT2RTR_QPEE,
+		[MTHCA_TRANS_RTR2RTS]   = CMD_RTR2RTS_QPEE,
+		[MTHCA_TRANS_RTS2RTS]   = CMD_RTS2RTS_QPEE,
+		[MTHCA_TRANS_SQERR2RTS] = CMD_SQERR2RTS_QPEE,
+		[MTHCA_TRANS_ANY2ERR]   = CMD_2ERR_QPEE,
+		[MTHCA_TRANS_RTS2SQD]   = CMD_RTS2SQD_QPEE,
+		[MTHCA_TRANS_SQD2SQD]   = CMD_SQD2SQD_QPEE,
+		[MTHCA_TRANS_SQD2RTS]   = CMD_SQD2RTS_QPEE,
+		[MTHCA_TRANS_ANY2RST]   = CMD_ERR2RST_QPEE
+	};
+	u8 op_mod = 0;
+
+	dma_addr_t indma;
+	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 */
+	} 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(" %08x\n", be32_to_cpup(qp_context));
+			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]));
+				if ((i + 1) % 8 == 0)
+					printk("\n");
+			}
+		}
+	}
+
+	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);
+
+		if (0) {
+			int i;
+			mthca_dbg(dev, "Dumping QP context:\n");
+			printk(" %08x\n", be32_to_cpup(qp_context));
+			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]));
+				if ((i + 1) % 8 == 0)
+					printk("\n");
+			}
+		}
+
+	} else
+		err = mthca_cmd(dev, indma, (!!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);
+	return err;
+}
+
+int mthca_QUERY_QP(struct mthca_dev *dev, u32 num, int is_ee,
+		   void *qp_context, 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;
+}
+
+int mthca_CONF_SPECIAL_QP(struct mthca_dev *dev, int type, u32 qpn,
+			  u8 *status)
+{
+	u8 op_mod;
+
+	switch (type) {
+	case IB_QPT_SMI:
+		op_mod = 0;
+		break;
+	case IB_QPT_GSI:
+		op_mod = 1;
+		break;
+	case IB_QPT_RAW_IPV6:
+		op_mod = 2;
+		break;
+	case IB_QPT_RAW_ETY:
+		op_mod = 3;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return mthca_cmd(dev, 0, qpn, op_mod, CMD_CONF_SPECIAL_QP,
+			 CMD_TIME_CLASS_B, 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,
+		  void *in_mad, void *response_mad, u8 *status)
+{
+	void *box;
+	dma_addr_t dma;
+	int err;
+	u32 in_modifier = port;
+	u8 op_modifier = 0;
+
+#define MAD_IFC_BOX_SIZE      0x400
+#define MAD_IFC_MY_QPN_OFFSET 0x100
+#define MAD_IFC_RQPN_OFFSET   0x104
+#define MAD_IFC_SL_OFFSET     0x108
+#define MAD_IFC_G_PATH_OFFSET 0x109
+#define MAD_IFC_RLID_OFFSET   0x10a
+#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;
+
+	memcpy(box, in_mad, 256);
+
+	/*
+	 * Key check traps can't be generated unless we have in_wc to
+	 * tell us where to send the trap.
+	 */
+	if (ignore_mkey || !in_wc)
+		op_modifier |= 0x1;
+	if (ignore_bkey || !in_wc)
+		op_modifier |= 0x2;
+
+	if (in_wc) {
+		u8 val;
+
+		memset(box + 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);
+
+		val = in_wc->sl << 4;
+		MTHCA_PUT(box, 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(box, in_wc->slid,       MAD_IFC_RLID_OFFSET);
+		MTHCA_PUT(box, in_wc->pkey_index, MAD_IFC_PKEY_OFFSET);
+
+		if (in_grh)
+			memcpy((u8 *) box + 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,
+			    CMD_MAD_IFC, CMD_TIME_CLASS_C, status);
+
+	if (!err && !*status)
+		memcpy(response_mad, box + 512, 256);
+
+	pci_free_consistent(dev->pdev, MAD_IFC_BOX_SIZE, box, dma);
+	return err;
+}
+
+int mthca_READ_MGM(struct mthca_dev *dev, int index, void *mgm,
+		   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;
+}
+
+int mthca_WRITE_MGM(struct mthca_dev *dev, int index, void *mgm,
+		    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;
+}
+
+int mthca_MGID_HASH(struct mthca_dev *dev, void *gid, 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,
+			    CMD_TIME_CLASS_A, status);
+	*hash = imm;
+
+	pci_unmap_single(dev->pdev, indma, 16, PCI_DMA_TODEVICE);
+	return err;
+}
+
+int mthca_NOP(struct mthca_dev *dev, u8 *status)
+{
+	return mthca_cmd(dev, 0, 0x1f, 0, CMD_NOP, msecs_to_jiffies(100), status);
+}
diff -Nru a/drivers/infiniband/hw/mthca/mthca_cmd.h b/drivers/infiniband/hw/mthca/mthca_cmd.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/infiniband/hw/mthca/mthca_cmd.h	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,296 @@
+/*
+ * Copyright (c) 2004, 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: mthca_cmd.h 1349 2004-12-16 21:09:43Z roland $
+ */
+
+#ifndef MTHCA_CMD_H
+#define MTHCA_CMD_H
+
+#include <ib_verbs.h>
+
+#define MTHCA_CMD_MAILBOX_ALIGN 16UL
+#define MTHCA_CMD_MAILBOX_EXTRA (MTHCA_CMD_MAILBOX_ALIGN - 1)
+
+enum {
+	/* command completed successfully: */
+	MTHCA_CMD_STAT_OK 	      = 0x00,
+	/* Internal error (such as a bus error) occurred while processing command: */
+	MTHCA_CMD_STAT_INTERNAL_ERR   = 0x01,
+	/* Operation/command not supported or opcode modifier not supported: */
+	MTHCA_CMD_STAT_BAD_OP 	      = 0x02,
+	/* Parameter not supported or parameter out of range: */
+	MTHCA_CMD_STAT_BAD_PARAM      = 0x03,
+	/* System not enabled or bad system state: */
+	MTHCA_CMD_STAT_BAD_SYS_STATE  = 0x04,
+	/* Attempt to access reserved or unallocaterd resource: */
+	MTHCA_CMD_STAT_BAD_RESOURCE   = 0x05,
+	/* Requested resource is currently executing a command, or is otherwise busy: */
+	MTHCA_CMD_STAT_RESOURCE_BUSY  = 0x06,
+	/* memory error: */
+	MTHCA_CMD_STAT_DDR_MEM_ERR    = 0x07,
+	/* Required capability exceeds device limits: */
+	MTHCA_CMD_STAT_EXCEED_LIM     = 0x08,
+	/* Resource is not in the appropriate state or ownership: */
+	MTHCA_CMD_STAT_BAD_RES_STATE  = 0x09,
+	/* Index out of range: */
+	MTHCA_CMD_STAT_BAD_INDEX      = 0x0a,
+	/* FW image corrupted: */
+	MTHCA_CMD_STAT_BAD_NVMEM      = 0x0b,
+	/* Attempt to modify a QP/EE which is not in the presumed state: */
+	MTHCA_CMD_STAT_BAD_QPEE_STATE = 0x10,
+	/* Bad segment parameters (Address/Size): */
+	MTHCA_CMD_STAT_BAD_SEG_PARAM  = 0x20,
+	/* Memory Region has Memory Windows bound to: */
+	MTHCA_CMD_STAT_REG_BOUND      = 0x21,
+	/* HCA local attached memory not present: */
+	MTHCA_CMD_STAT_LAM_NOT_PRE    = 0x22,
+        /* Bad management packet (silently discarded): */
+	MTHCA_CMD_STAT_BAD_PKT 	      = 0x30,
+        /* More outstanding CQEs in CQ than new CQ size: */
+	MTHCA_CMD_STAT_BAD_SIZE       = 0x40
+};
+
+enum {
+	MTHCA_TRANS_INVALID = 0,
+	MTHCA_TRANS_RST2INIT,
+	MTHCA_TRANS_INIT2INIT,
+	MTHCA_TRANS_INIT2RTR,
+	MTHCA_TRANS_RTR2RTS,
+	MTHCA_TRANS_RTS2RTS,
+	MTHCA_TRANS_SQERR2RTS,
+	MTHCA_TRANS_ANY2ERR,
+	MTHCA_TRANS_RTS2SQD,
+	MTHCA_TRANS_SQD2SQD,
+	MTHCA_TRANS_SQD2RTS,
+	MTHCA_TRANS_ANY2RST,
+};
+
+enum {
+	DEV_LIM_FLAG_SRQ = 1 << 6
+};
+
+struct mthca_dev_lim {
+	int max_srq_sz;
+	int max_qp_sz;
+	int reserved_qps;
+	int max_qps;
+	int reserved_srqs;
+	int max_srqs;
+	int reserved_eecs;
+	int max_eecs;
+	int max_cq_sz;
+	int reserved_cqs;
+	int max_cqs;
+	int max_mpts;
+	int reserved_eqs;
+	int max_eqs;
+	int reserved_mtts;
+	int max_mrw_sz;
+	int reserved_mrws;
+	int max_mtt_seg;
+	int max_requester_per_qp;
+	int max_responder_per_qp;
+	int max_rdma_global;
+	int local_ca_ack_delay;
+	int max_mtu;
+	int max_port_width;
+	int max_vl;
+	int num_ports;
+	int max_gids;
+	int max_pkeys;
+	u32 flags;
+	int reserved_uars;
+	int uar_size;
+	int min_page_sz;
+	int max_sg;
+	int max_desc_sz;
+	int max_qp_per_mcg;
+	int reserved_mgms;
+	int max_mcgs;
+	int reserved_pds;
+	int max_pds;
+	int reserved_rdds;
+	int max_rdds;
+	int eec_entry_sz;
+	int qpc_entry_sz;
+	int eeec_entry_sz;
+	int eqpc_entry_sz;
+	int eqc_entry_sz;
+	int cqc_entry_sz;
+	int srq_entry_sz;
+	int uar_scratch_entry_sz;
+	int mtt_seg_sz;
+	int mpt_entry_sz;
+	union {
+		struct {
+			int max_avs;
+		} tavor;
+		struct {
+			int resize_srq;
+			int max_pbl_sz;
+			u8  bmme_flags;
+			u32 reserved_lkey;
+			int lam_required;
+			u64 max_icm_sz;
+		} arbel;
+	} hca;
+};
+
+struct mthca_adapter {
+	u32 vendor_id;
+	u32 device_id;
+	u32 revision_id;
+	u8  inta_pin;
+};
+
+struct mthca_init_hca_param {
+	u64 qpc_base;
+	u64 eec_base;
+	u64 srqc_base;
+	u64 cqc_base;
+	u64 eqpc_base;
+	u64 eeec_base;
+	u64 eqc_base;
+	u64 rdb_base;
+	u64 mc_base;
+	u64 mpt_base;
+	u64 mtt_base;
+	u64 uar_scratch_base;
+	u64 uarc_base;
+	u16 log_mc_entry_sz;
+	u16 mc_hash_sz;
+	u8  log_num_qps;
+	u8  log_num_eecs;
+	u8  log_num_srqs;
+	u8  log_num_cqs;
+	u8  log_num_eqs;
+	u8  log_mc_table_sz;
+	u8  mtt_seg_sz;
+	u8  log_mpt_sz;
+	u8  log_uar_sz;
+	u8  log_uarc_sz;
+};
+
+struct mthca_init_ib_param {
+	int enable_1x;
+	int enable_4x;
+	int vl_cap;
+	int mtu_cap;
+	u16 gid_cap;
+	u16 pkey_cap;
+	int set_guid0;
+	u64 guid0;
+	int set_node_guid;
+	u64 node_guid;
+	int set_si_guid;
+	u64 si_guid;
+};
+
+struct mthca_set_ib_param {
+	int set_si_guid;
+	int reset_qkey_viol;
+	u64 si_guid;
+	u32 cap_mask;
+};
+
+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);
+
+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);
+int mthca_UNMAP_FA(struct mthca_dev *dev, u8 *status);
+int mthca_RUN_FW(struct mthca_dev *dev, u8 *status);
+int mthca_QUERY_FW(struct mthca_dev *dev, u8 *status);
+int mthca_ENABLE_LAM(struct mthca_dev *dev, u8 *status);
+int mthca_DISABLE_LAM(struct mthca_dev *dev, u8 *status);
+int mthca_QUERY_DDR(struct mthca_dev *dev, u8 *status);
+int mthca_QUERY_DEV_LIM(struct mthca_dev *dev,
+			struct mthca_dev_lim *dev_lim, u8 *status);
+int mthca_QUERY_ADAPTER(struct mthca_dev *dev,
+			struct mthca_adapter *adapter, u8 *status);
+int mthca_INIT_HCA(struct mthca_dev *dev,
+		   struct mthca_init_hca_param *param,
+		   u8 *status);
+int mthca_INIT_IB(struct mthca_dev *dev,
+		  struct mthca_init_ib_param *param,
+		  int port, u8 *status);
+int mthca_CLOSE_IB(struct mthca_dev *dev, int port, u8 *status);
+int mthca_CLOSE_HCA(struct mthca_dev *dev, int panic, u8 *status);
+int mthca_SET_IB(struct mthca_dev *dev, struct mthca_set_ib_param *param,
+		 int port, u8 *status);
+int mthca_MAP_ICM(struct mthca_dev *dev, struct mthca_icm *icm, u64 virt, u8 *status);
+int mthca_MAP_ICM_page(struct mthca_dev *dev, u64 dma_addr, u64 virt, u8 *status);
+int mthca_UNMAP_ICM(struct mthca_dev *dev, u64 virt, u32 page_count, u8 *status);
+int mthca_MAP_ICM_AUX(struct mthca_dev *dev, struct mthca_icm *icm, u8 *status);
+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 mpt_index, u8 *status);
+int mthca_HW2SW_MPT(struct mthca_dev *dev, void *mpt_entry,
+		    int mpt_index, u8 *status);
+int mthca_WRITE_MTT(struct mthca_dev *dev, u64 *mtt_entry,
+		    int num_mtt, 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 eq_num, u8 *status);
+int mthca_HW2SW_EQ(struct mthca_dev *dev, void *eq_context,
+		   int eq_num, u8 *status);
+int mthca_SW2HW_CQ(struct mthca_dev *dev, void *cq_context,
+		   int cq_num, u8 *status);
+int mthca_HW2SW_CQ(struct mthca_dev *dev, void *cq_context,
+		   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,
+		    u8 *status);
+int mthca_QUERY_QP(struct mthca_dev *dev, u32 num, int is_ee,
+		   void *qp_context, 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,
+		  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_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 -Nru a/drivers/infiniband/hw/mthca/mthca_config_reg.h b/drivers/infiniband/hw/mthca/mthca_config_reg.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/infiniband/hw/mthca/mthca_config_reg.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2004 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: mthca_config_reg.h 1349 2004-12-16 21:09:43Z roland $
+ */
+
+#ifndef MTHCA_CONFIG_REG_H
+#define MTHCA_CONFIG_REG_H
+
+#include <asm/page.h>
+
+#define MTHCA_HCR_BASE         0x80680
+#define MTHCA_HCR_SIZE         0x0001c
+#define MTHCA_ECR_BASE         0x80700
+#define MTHCA_ECR_SIZE         0x00008
+#define MTHCA_ECR_CLR_BASE     0x80708
+#define MTHCA_ECR_CLR_SIZE     0x00008
+#define MTHCA_MAP_ECR_SIZE     (MTHCA_ECR_SIZE + MTHCA_ECR_CLR_SIZE)
+#define MTHCA_CLR_INT_BASE     0xf00d8
+#define MTHCA_CLR_INT_SIZE     0x00008
+
+#endif /* MTHCA_CONFIG_REG_H */
diff -Nru a/drivers/infiniband/hw/mthca/mthca_cq.c b/drivers/infiniband/hw/mthca/mthca_cq.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/infiniband/hw/mthca/mthca_cq.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,841 @@
+/*
+ * Copyright (c) 2004, 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: mthca_cq.c 1369 2004-12-20 16:17:07Z roland $
+ */
+
+#include <linux/init.h>
+
+#include <ib_pack.h>
+
+#include "mthca_dev.h"
+#include "mthca_cmd.h"
+
+enum {
+	MTHCA_MAX_DIRECT_CQ_SIZE = 4 * PAGE_SIZE
+};
+
+enum {
+	MTHCA_CQ_ENTRY_SIZE = 0x20
+};
+
+/*
+ * Must be packed because start is 64 bits but only aligned to 32 bits.
+ */
+struct mthca_cq_context {
+	u32 flags;
+	u64 start;
+	u32 logsize_usrpage;
+	u32 error_eqn;
+	u32 comp_eqn;
+	u32 pd;
+	u32 lkey;
+	u32 last_notified_index;
+	u32 solicit_producer_index;
+	u32 consumer_index;
+	u32 producer_index;
+	u32 cqn;
+	u32 reserved[3];
+} __attribute__((packed));
+
+#define MTHCA_CQ_STATUS_OK          ( 0 << 28)
+#define MTHCA_CQ_STATUS_OVERFLOW    ( 9 << 28)
+#define MTHCA_CQ_STATUS_WRITE_FAIL  (10 << 28)
+#define MTHCA_CQ_FLAG_TR            ( 1 << 18)
+#define MTHCA_CQ_FLAG_OI            ( 1 << 17)
+#define MTHCA_CQ_STATE_DISARMED     ( 0 <<  8)
+#define MTHCA_CQ_STATE_ARMED        ( 1 <<  8)
+#define MTHCA_CQ_STATE_ARMED_SOL    ( 4 <<  8)
+#define MTHCA_EQ_STATE_FIRED        (10 <<  8)
+
+enum {
+	MTHCA_ERROR_CQE_OPCODE_MASK = 0xfe
+};
+
+enum {
+	SYNDROME_LOCAL_LENGTH_ERR 	 = 0x01,
+	SYNDROME_LOCAL_QP_OP_ERR  	 = 0x02,
+	SYNDROME_LOCAL_EEC_OP_ERR 	 = 0x03,
+	SYNDROME_LOCAL_PROT_ERR   	 = 0x04,
+	SYNDROME_WR_FLUSH_ERR     	 = 0x05,
+	SYNDROME_MW_BIND_ERR      	 = 0x06,
+	SYNDROME_BAD_RESP_ERR     	 = 0x10,
+	SYNDROME_LOCAL_ACCESS_ERR 	 = 0x11,
+	SYNDROME_REMOTE_INVAL_REQ_ERR 	 = 0x12,
+	SYNDROME_REMOTE_ACCESS_ERR 	 = 0x13,
+	SYNDROME_REMOTE_OP_ERR     	 = 0x14,
+	SYNDROME_RETRY_EXC_ERR 		 = 0x15,
+	SYNDROME_RNR_RETRY_EXC_ERR 	 = 0x16,
+	SYNDROME_LOCAL_RDD_VIOL_ERR 	 = 0x20,
+	SYNDROME_REMOTE_INVAL_RD_REQ_ERR = 0x21,
+	SYNDROME_REMOTE_ABORTED_ERR 	 = 0x22,
+	SYNDROME_INVAL_EECN_ERR 	 = 0x23,
+	SYNDROME_INVAL_EEC_STATE_ERR 	 = 0x24
+};
+
+struct mthca_cqe {
+	u32 my_qpn;
+	u32 my_ee;
+	u32 rqpn;
+	u16 sl_g_mlpath;
+	u16 rlid;
+	u32 imm_etype_pkey_eec;
+	u32 byte_cnt;
+	u32 wqe;
+	u8  opcode;
+	u8  is_send;
+	u8  reserved;
+	u8  owner;
+};
+
+struct mthca_err_cqe {
+	u32 my_qpn;
+	u32 reserved1[3];
+	u8  syndrome;
+	u8  reserved2;
+	u16 db_cnt;
+	u32 reserved3;
+	u32 wqe;
+	u8  opcode;
+	u8  reserved4[2];
+	u8  owner;
+};
+
+#define MTHCA_CQ_ENTRY_OWNER_SW      (0 << 7)
+#define MTHCA_CQ_ENTRY_OWNER_HW      (1 << 7)
+
+#define MTHCA_CQ_DB_INC_CI       (1 << 24)
+#define MTHCA_CQ_DB_REQ_NOT      (2 << 24)
+#define MTHCA_CQ_DB_REQ_NOT_SOL  (3 << 24)
+#define MTHCA_CQ_DB_SET_CI       (4 << 24)
+#define MTHCA_CQ_DB_REQ_NOT_MULT (5 << 24)
+
+static inline struct mthca_cqe *get_cqe(struct mthca_cq *cq, int entry)
+{
+	if (cq->is_direct)
+		return cq->queue.direct.buf + (entry * MTHCA_CQ_ENTRY_SIZE);
+	else
+		return cq->queue.page_list[entry * MTHCA_CQ_ENTRY_SIZE / PAGE_SIZE].buf
+			+ (entry * MTHCA_CQ_ENTRY_SIZE) % PAGE_SIZE;
+}
+
+static inline int cqe_sw(struct mthca_cq *cq, int i)
+{
+	return !(MTHCA_CQ_ENTRY_OWNER_HW &
+		 get_cqe(cq, i)->owner);
+}
+
+static inline int next_cqe_sw(struct mthca_cq *cq)
+{
+	return cqe_sw(cq, cq->cons_index);
+}
+
+static inline void set_cqe_hw(struct mthca_cq *cq, int entry)
+{
+	get_cqe(cq, entry)->owner = MTHCA_CQ_ENTRY_OWNER_HW;
+}
+
+static inline void inc_cons_index(struct mthca_dev *dev, struct mthca_cq *cq,
+				  int nent)
+{
+	u32 doorbell[2];
+
+	doorbell[0] = cpu_to_be32(MTHCA_CQ_DB_INC_CI | cq->cqn);
+	doorbell[1] = cpu_to_be32(nent - 1);
+
+	mthca_write64(doorbell,
+		      dev->kar + MTHCA_CQ_DOORBELL,
+		      MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
+}
+
+void mthca_cq_event(struct mthca_dev *dev, u32 cqn)
+{
+	struct mthca_cq *cq;
+
+	spin_lock(&dev->cq_table.lock);
+	cq = mthca_array_get(&dev->cq_table.cq, cqn & (dev->limits.num_cqs - 1));
+	if (cq)
+		atomic_inc(&cq->refcount);
+	spin_unlock(&dev->cq_table.lock);
+
+	if (!cq) {
+		mthca_warn(dev, "Completion event for bogus CQ %08x\n", cqn);
+		return;
+	}
+
+	cq->ibcq.comp_handler(&cq->ibcq, cq->ibcq.cq_context);
+
+	if (atomic_dec_and_test(&cq->refcount))
+		wake_up(&cq->wait);
+}
+
+void mthca_cq_clean(struct mthca_dev *dev, u32 cqn, u32 qpn)
+{
+	struct mthca_cq *cq;
+	struct mthca_cqe *cqe;
+	int prod_index;
+	int nfreed = 0;
+
+	spin_lock_irq(&dev->cq_table.lock);
+	cq = mthca_array_get(&dev->cq_table.cq, cqn & (dev->limits.num_cqs - 1));
+	if (cq)
+		atomic_inc(&cq->refcount);
+	spin_unlock_irq(&dev->cq_table.lock);
+
+	if (!cq)
+		return;
+
+	spin_lock_irq(&cq->lock);
+
+	/*
+	 * First we need to find the current producer index, so we
+	 * know where to start cleaning from.  It doesn't matter if HW
+	 * adds new entries after this loop -- the QP we're worried
+	 * about is already in RESET, so the new entries won't come
+	 * from our QP and therefore don't need to be checked.
+	 */
+	for (prod_index = cq->cons_index;
+	     cqe_sw(cq, prod_index & cq->ibcq.cqe);
+	     ++prod_index)
+		if (prod_index == cq->cons_index + cq->ibcq.cqe)
+			break;
+
+	if (0)
+		mthca_dbg(dev, "Cleaning QPN %06x from CQN %06x; ci %d, pi %d\n",
+			  qpn, cqn, cq->cons_index, prod_index);
+
+	/*
+	 * Now sweep backwards through the CQ, removing CQ entries
+	 * that match our QP by copying older entries on top of them.
+	 */
+	while (prod_index > cq->cons_index) {
+		cqe = get_cqe(cq, (prod_index - 1) & cq->ibcq.cqe);
+		if (cqe->my_qpn == cpu_to_be32(qpn))
+			++nfreed;
+		else if (nfreed)
+			memcpy(get_cqe(cq, (prod_index - 1 + nfreed) &
+				       cq->ibcq.cqe),
+			       cqe,
+			       MTHCA_CQ_ENTRY_SIZE);
+		--prod_index;
+	}
+
+	if (nfreed) {
+		wmb();
+		inc_cons_index(dev, cq, nfreed);
+		cq->cons_index = (cq->cons_index + nfreed) & cq->ibcq.cqe;
+	}
+
+	spin_unlock_irq(&cq->lock);
+	if (atomic_dec_and_test(&cq->refcount))
+		wake_up(&cq->wait);
+}
+
+static int handle_error_cqe(struct mthca_dev *dev, struct mthca_cq *cq,
+			    struct mthca_qp *qp, int wqe_index, int is_send,
+			    struct mthca_err_cqe *cqe,
+			    struct ib_wc *entry, int *free_cqe)
+{
+	int err;
+	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]));
+	}
+
+	/*
+	 * For completions in error, only work request ID, status (and
+	 * freed resource count for RD) have to be set.
+	 */
+	switch (cqe->syndrome) {
+	case SYNDROME_LOCAL_LENGTH_ERR:
+		entry->status = IB_WC_LOC_LEN_ERR;
+		break;
+	case SYNDROME_LOCAL_QP_OP_ERR:
+		entry->status = IB_WC_LOC_QP_OP_ERR;
+		break;
+	case SYNDROME_LOCAL_EEC_OP_ERR:
+		entry->status = IB_WC_LOC_EEC_OP_ERR;
+		break;
+	case SYNDROME_LOCAL_PROT_ERR:
+		entry->status = IB_WC_LOC_PROT_ERR;
+		break;
+	case SYNDROME_WR_FLUSH_ERR:
+		entry->status = IB_WC_WR_FLUSH_ERR;
+		break;
+	case SYNDROME_MW_BIND_ERR:
+		entry->status = IB_WC_MW_BIND_ERR;
+		break;
+	case SYNDROME_BAD_RESP_ERR:
+		entry->status = IB_WC_BAD_RESP_ERR;
+		break;
+	case SYNDROME_LOCAL_ACCESS_ERR:
+		entry->status = IB_WC_LOC_ACCESS_ERR;
+		break;
+	case SYNDROME_REMOTE_INVAL_REQ_ERR:
+		entry->status = IB_WC_REM_INV_REQ_ERR;
+		break;
+	case SYNDROME_REMOTE_ACCESS_ERR:
+		entry->status = IB_WC_REM_ACCESS_ERR;
+		break;
+	case SYNDROME_REMOTE_OP_ERR:
+		entry->status = IB_WC_REM_OP_ERR;
+		break;
+	case SYNDROME_RETRY_EXC_ERR:
+		entry->status = IB_WC_RETRY_EXC_ERR;
+		break;
+	case SYNDROME_RNR_RETRY_EXC_ERR:
+		entry->status = IB_WC_RNR_RETRY_EXC_ERR;
+		break;
+	case SYNDROME_LOCAL_RDD_VIOL_ERR:
+		entry->status = IB_WC_LOC_RDD_VIOL_ERR;
+		break;
+	case SYNDROME_REMOTE_INVAL_RD_REQ_ERR:
+		entry->status = IB_WC_REM_INV_RD_REQ_ERR;
+		break;
+	case SYNDROME_REMOTE_ABORTED_ERR:
+		entry->status = IB_WC_REM_ABORT_ERR;
+		break;
+	case SYNDROME_INVAL_EECN_ERR:
+		entry->status = IB_WC_INV_EECN_ERR;
+		break;
+	case SYNDROME_INVAL_EEC_STATE_ERR:
+		entry->status = IB_WC_INV_EEC_STATE_ERR;
+		break;
+	default:
+		entry->status = IB_WC_GENERAL_ERR;
+		break;
+	}
+
+	err = mthca_free_err_wqe(qp, is_send, wqe_index, &dbd, &new_wqe);
+	if (err)
+		return err;
+
+	/*
+	 * 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.
+	 */
+	if (!(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);
+	cqe->wqe      = new_wqe;
+	cqe->syndrome = SYNDROME_WR_FLUSH_ERR;
+
+	*free_cqe = 0;
+
+	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,
+				 int *freed,
+				 struct ib_wc *entry)
+{
+	struct mthca_wq *wq;
+	struct mthca_cqe *cqe;
+	int wqe_index;
+	int is_error = 0;
+	int is_send;
+	int free_cqe = 1;
+	int err = 0;
+
+	if (!next_cqe_sw(cq))
+		return -EAGAIN;
+
+	/*
+	 * Make sure we read CQ entry contents after we've checked the
+	 * ownership bit.
+	 */
+	rmb();
+
+	cqe = get_cqe(cq, cq->cons_index);
+
+	if (0) {
+		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);
+	}
+
+	if ((cqe->opcode & MTHCA_ERROR_CQE_OPCODE_MASK) ==
+	    MTHCA_ERROR_CQE_OPCODE_MASK) {
+		is_error = 1;
+		is_send = cqe->opcode & 1;
+	} else
+		is_send = cqe->is_send & 0x80;
+
+	if (!*cur_qp || be32_to_cpu(cqe->my_qpn) != (*cur_qp)->qpn) {
+		if (*cur_qp) {
+			if (*freed) {
+				wmb();
+				inc_cons_index(dev, cq, *freed);
+				*freed = 0;
+			}
+			spin_unlock(&(*cur_qp)->lock);
+		}
+
+		spin_lock(&dev->qp_table.lock);
+		*cur_qp = mthca_array_get(&dev->qp_table.qp,
+					  be32_to_cpu(cqe->my_qpn) &
+					  (dev->limits.num_qps - 1));
+		if (*cur_qp)
+			atomic_inc(&(*cur_qp)->refcount);
+		spin_unlock(&dev->qp_table.lock);
+
+		if (!*cur_qp) {
+			mthca_warn(dev, "CQ entry for unknown QP %06x\n",
+				   be32_to_cpu(cqe->my_qpn) & 0xffffff);
+			err = -EINVAL;
+			goto out;
+		}
+
+		spin_lock(&(*cur_qp)->lock);
+	}
+
+	entry->qp_num = (*cur_qp)->qpn;
+
+	if (is_send) {
+		wq = &(*cur_qp)->sq;
+		wqe_index = ((be32_to_cpu(cqe->wqe) - (*cur_qp)->send_wqe_offset)
+			     >> wq->wqe_shift);
+		entry->wr_id = (*cur_qp)->wrid[wqe_index +
+					       (*cur_qp)->rq.max];
+	} else {
+		wq = &(*cur_qp)->rq;
+		wqe_index = be32_to_cpu(cqe->wqe) >> wq->wqe_shift;
+		entry->wr_id = (*cur_qp)->wrid[wqe_index];
+	}
+
+	if (wq->last_comp < wqe_index)
+		wq->cur -= wqe_index - wq->last_comp;
+	else
+		wq->cur -= wq->max - wq->last_comp + wqe_index;
+
+	wq->last_comp = wqe_index;
+
+	if (0)
+		mthca_dbg(dev, "%s completion for QP %06x, index %d (nr %d)\n",
+			  is_send ? "Send" : "Receive",
+			  (*cur_qp)->qpn, wqe_index, wq->max);
+
+	if (is_error) {
+		err = handle_error_cqe(dev, cq, *cur_qp, wqe_index, is_send,
+				       (struct mthca_err_cqe *) cqe,
+				       entry, &free_cqe);
+		goto out;
+	}
+
+	if (is_send) {
+		entry->opcode = IB_WC_SEND; /* XXX */
+	} else {
+		entry->byte_len = be32_to_cpu(cqe->byte_cnt);
+		switch (cqe->opcode & 0x1f) {
+		case IB_OPCODE_SEND_LAST_WITH_IMMEDIATE:
+		case IB_OPCODE_SEND_ONLY_WITH_IMMEDIATE:
+			entry->wc_flags = IB_WC_WITH_IMM;
+			entry->imm_data = cqe->imm_etype_pkey_eec;
+			entry->opcode = IB_WC_RECV;
+			break;
+		case IB_OPCODE_RDMA_WRITE_LAST_WITH_IMMEDIATE:
+		case IB_OPCODE_RDMA_WRITE_ONLY_WITH_IMMEDIATE:
+			entry->wc_flags = IB_WC_WITH_IMM;
+			entry->imm_data = cqe->imm_etype_pkey_eec;
+			entry->opcode = IB_WC_RECV_RDMA_WITH_IMM;
+			break;
+		default:
+			entry->wc_flags = 0;
+			entry->opcode = IB_WC_RECV;
+			break;
+		}
+		entry->slid 	   = be16_to_cpu(cqe->rlid);
+		entry->sl   	   = be16_to_cpu(cqe->sl_g_mlpath) >> 12;
+		entry->src_qp 	   = be32_to_cpu(cqe->rqpn) & 0xffffff;
+		entry->dlid_path_bits = be16_to_cpu(cqe->sl_g_mlpath) & 0x7f;
+		entry->pkey_index  = be32_to_cpu(cqe->imm_etype_pkey_eec) >> 16;
+		entry->wc_flags   |= be16_to_cpu(cqe->sl_g_mlpath) & 0x80 ?
+					IB_WC_GRH : 0;
+	}
+
+	entry->status = IB_WC_SUCCESS;
+
+ out:
+	if (free_cqe) {
+		set_cqe_hw(cq, cq->cons_index);
+		++(*freed);
+		cq->cons_index = (cq->cons_index + 1) & cq->ibcq.cqe;
+	}
+
+	return err;
+}
+
+int mthca_poll_cq(struct ib_cq *ibcq, int num_entries,
+		  struct ib_wc *entry)
+{
+	struct mthca_dev *dev = to_mdev(ibcq->device);
+	struct mthca_cq *cq = to_mcq(ibcq);
+	struct mthca_qp *qp = NULL;
+	unsigned long flags;
+	int err = 0;
+	int freed = 0;
+	int npolled;
+
+	spin_lock_irqsave(&cq->lock, flags);
+
+	for (npolled = 0; npolled < num_entries; ++npolled) {
+		err = mthca_poll_one(dev, cq, &qp,
+				     &freed, entry + npolled);
+		if (err)
+			break;
+	}
+
+	if (freed) {
+		wmb();
+		inc_cons_index(dev, cq, freed);
+	}
+
+	if (qp) {
+		spin_unlock(&qp->lock);
+		if (atomic_dec_and_test(&qp->refcount))
+			wake_up(&qp->wait);
+	}
+
+
+	spin_unlock_irqrestore(&cq->lock, flags);
+
+	return err == 0 || err == -EAGAIN ? npolled : err;
+}
+
+void mthca_arm_cq(struct mthca_dev *dev, struct mthca_cq *cq,
+		  int solicited)
+{
+	u32 doorbell[2];
+
+	doorbell[0] =  cpu_to_be32((solicited ?
+				    MTHCA_CQ_DB_REQ_NOT_SOL :
+				    MTHCA_CQ_DB_REQ_NOT)      |
+				   cq->cqn);
+	doorbell[1] = 0xffffffff;
+
+	mthca_write64(doorbell,
+		      dev->kar + MTHCA_CQ_DOORBELL,
+		      MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
+}
+
+int mthca_init_cq(struct mthca_dev *dev, int nent,
+		  struct mthca_cq *cq)
+{
+	int size = nent * MTHCA_CQ_ENTRY_SIZE;
+	dma_addr_t t;
+	void *mailbox = NULL;
+	int npages, shift;
+	u64 *dma_list = NULL;
+	struct mthca_cq_context *cq_context;
+	int err = -ENOMEM;
+	u8 status;
+	int i;
+
+	might_sleep();
+
+	mailbox = kmalloc(sizeof (struct mthca_cq_context) + MTHCA_CMD_MAILBOX_EXTRA,
+			  GFP_KERNEL);
+	if (!mailbox)
+		goto err_out;
+
+	cq_context = MAILBOX_ALIGN(mailbox);
+
+	if (size <= MTHCA_MAX_DIRECT_CQ_SIZE) {
+		if (0)
+			mthca_dbg(dev, "Creating direct CQ of size %d\n", size);
+
+		cq->is_direct = 1;
+		npages        = 1;
+		shift         = get_order(size) + PAGE_SHIFT;
+
+		cq->queue.direct.buf = pci_alloc_consistent(dev->pdev,
+							    size, &t);
+		if (!cq->queue.direct.buf)
+			goto err_out;
+
+		pci_unmap_addr_set(&cq->queue.direct, mapping, t);
+
+		memset(cq->queue.direct.buf, 0, size);
+
+		while (t & ((1 << shift) - 1)) {
+			--shift;
+			npages *= 2;
+		}
+
+		dma_list = kmalloc(npages * sizeof *dma_list, GFP_KERNEL);
+		if (!dma_list)
+			goto err_out_free;
+
+		for (i = 0; i < npages; ++i)
+			dma_list[i] = t + i * (1 << shift);
+	} else {
+		cq->is_direct = 0;
+		npages        = (size + PAGE_SIZE - 1) / PAGE_SIZE;
+		shift         = PAGE_SHIFT;
+
+		if (0)
+			mthca_dbg(dev, "Creating indirect CQ with %d pages\n", npages);
+
+		dma_list = kmalloc(npages * sizeof *dma_list, GFP_KERNEL);
+		if (!dma_list)
+			goto err_out;
+
+		cq->queue.page_list = kmalloc(npages * sizeof *cq->queue.page_list,
+					      GFP_KERNEL);
+		if (!cq->queue.page_list)
+			goto err_out;
+
+		for (i = 0; i < npages; ++i)
+			cq->queue.page_list[i].buf = NULL;
+
+		for (i = 0; i < npages; ++i) {
+			cq->queue.page_list[i].buf =
+				pci_alloc_consistent(dev->pdev, PAGE_SIZE, &t);
+			if (!cq->queue.page_list[i].buf)
+				goto err_out_free;
+
+			dma_list[i] = t;
+			pci_unmap_addr_set(&cq->queue.page_list[i], mapping, t);
+
+			memset(cq->queue.page_list[i].buf, 0, PAGE_SIZE);
+		}
+	}
+
+	for (i = 0; i < nent; ++i)
+		set_cqe_hw(cq, i);
+
+	cq->cqn = mthca_alloc(&dev->cq_table.alloc);
+	if (cq->cqn == -1)
+		goto err_out_free;
+
+	err = mthca_mr_alloc_phys(dev, dev->driver_pd.pd_num,
+				  dma_list, shift, npages,
+				  0, size,
+				  MTHCA_MPT_FLAG_LOCAL_WRITE |
+				  MTHCA_MPT_FLAG_LOCAL_READ,
+				  &cq->mr);
+	if (err)
+		goto err_out_free_cq;
+
+	spin_lock_init(&cq->lock);
+	atomic_set(&cq->refcount, 1);
+	init_waitqueue_head(&cq->wait);
+
+	memset(cq_context, 0, sizeof *cq_context);
+	cq_context->flags           = cpu_to_be32(MTHCA_CQ_STATUS_OK      |
+						  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 |
+						  MTHCA_KAR_PAGE);
+	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->lkey            = cpu_to_be32(cq->mr.ibmr.lkey);
+	cq_context->cqn             = cpu_to_be32(cq->cqn);
+
+	err = mthca_SW2HW_CQ(dev, cq_context, cq->cqn, &status);
+	if (err) {
+		mthca_warn(dev, "SW2HW_CQ failed (%d)\n", err);
+		goto err_out_free_mr;
+	}
+
+	if (status) {
+		mthca_warn(dev, "SW2HW_CQ returned status 0x%02x\n",
+			   status);
+		err = -EINVAL;
+		goto err_out_free_mr;
+	}
+
+	spin_lock_irq(&dev->cq_table.lock);
+	if (mthca_array_set(&dev->cq_table.cq,
+			    cq->cqn & (dev->limits.num_cqs - 1),
+			    cq)) {
+		spin_unlock_irq(&dev->cq_table.lock);
+		goto err_out_free_mr;
+	}
+	spin_unlock_irq(&dev->cq_table.lock);
+
+	cq->cons_index = 0;
+
+	kfree(dma_list);
+	kfree(mailbox);
+
+	return 0;
+
+ err_out_free_mr:
+	mthca_free_mr(dev, &cq->mr);
+
+ err_out_free_cq:
+	mthca_free(&dev->cq_table.alloc, cq->cqn);
+
+ err_out_free:
+	if (cq->is_direct)
+		pci_free_consistent(dev->pdev, size,
+				    cq->queue.direct.buf,
+				    pci_unmap_addr(&cq->queue.direct, mapping));
+	else {
+		for (i = 0; i < npages; ++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));
+
+		kfree(cq->queue.page_list);
+	}
+
+ err_out:
+	kfree(dma_list);
+	kfree(mailbox);
+
+	return err;
+}
+
+void mthca_free_cq(struct mthca_dev *dev,
+		   struct mthca_cq *cq)
+{
+	void *mailbox;
+	int err;
+	u8 status;
+
+	might_sleep();
+
+	mailbox = kmalloc(sizeof (struct mthca_cq_context) + MTHCA_CMD_MAILBOX_EXTRA,
+			  GFP_KERNEL);
+	if (!mailbox) {
+		mthca_warn(dev, "No memory for mailbox to free CQ.\n");
+		return;
+	}
+
+	err = mthca_HW2SW_CQ(dev, MAILBOX_ALIGN(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);
+
+	if (0) {
+		u32 *ctx = MAILBOX_ALIGN(mailbox);
+		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));
+		for (j = 0; j < 16; ++j)
+			printk(KERN_ERR "[%2x] %08x\n", j * 4, be32_to_cpu(ctx[j]));
+	}
+
+	spin_lock_irq(&dev->cq_table.lock);
+	mthca_array_clear(&dev->cq_table.cq,
+			  cq->cqn & (dev->limits.num_cqs - 1));
+	spin_unlock_irq(&dev->cq_table.lock);
+
+	atomic_dec(&cq->refcount);
+	wait_event(cq->wait, !atomic_read(&cq->refcount));
+
+	mthca_free_mr(dev, &cq->mr);
+
+	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));
+	else {
+		int i;
+
+		for (i = 0;
+		     i < ((cq->ibcq.cqe + 1) * MTHCA_CQ_ENTRY_SIZE + PAGE_SIZE - 1) /
+			     PAGE_SIZE;
+		     ++i)
+			pci_free_consistent(dev->pdev, PAGE_SIZE,
+					    cq->queue.page_list[i].buf,
+					    pci_unmap_addr(&cq->queue.page_list[i],
+							   mapping));
+
+		kfree(cq->queue.page_list);
+	}
+
+	mthca_free(&dev->cq_table.alloc, cq->cqn);
+	kfree(mailbox);
+}
+
+int __devinit mthca_init_cq_table(struct mthca_dev *dev)
+{
+	int err;
+
+	spin_lock_init(&dev->cq_table.lock);
+
+	err = mthca_alloc_init(&dev->cq_table.alloc,
+			       dev->limits.num_cqs,
+			       (1 << 24) - 1,
+			       dev->limits.reserved_cqs);
+	if (err)
+		return err;
+
+	err = mthca_array_init(&dev->cq_table.cq,
+			       dev->limits.num_cqs);
+	if (err)
+		mthca_alloc_cleanup(&dev->cq_table.alloc);
+
+	return err;
+}
+
+void __devexit mthca_cleanup_cq_table(struct mthca_dev *dev)
+{
+	mthca_array_cleanup(&dev->cq_table.cq, dev->limits.num_cqs);
+	mthca_alloc_cleanup(&dev->cq_table.alloc);
+}
diff -Nru a/drivers/infiniband/hw/mthca/mthca_dev.h b/drivers/infiniband/hw/mthca/mthca_dev.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/infiniband/hw/mthca/mthca_dev.h	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,410 @@
+/*
+ * Copyright (c) 2004, 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: mthca_dev.h 1349 2004-12-16 21:09:43Z roland $
+ */
+
+#ifndef MTHCA_DEV_H
+#define MTHCA_DEV_H
+
+#include <linux/spinlock.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/dma-mapping.h>
+#include <asm/semaphore.h>
+
+#include "mthca_provider.h"
+#include "mthca_doorbell.h"
+
+#define DRV_NAME	"ib_mthca"
+#define PFX		DRV_NAME ": "
+#define DRV_VERSION	"0.06-pre"
+#define DRV_RELDATE	"November 8, 2004"
+
+/* Types of supported HCA */
+enum {
+	TAVOR,			/* MT23108                        */
+	ARBEL_COMPAT,		/* MT25208 in Tavor compat mode   */
+	ARBEL_NATIVE		/* MT25208 with extended features */
+};
+
+enum {
+	MTHCA_FLAG_DDR_HIDDEN = 1 << 1,
+	MTHCA_FLAG_SRQ        = 1 << 2,
+	MTHCA_FLAG_MSI        = 1 << 3,
+	MTHCA_FLAG_MSI_X      = 1 << 4,
+	MTHCA_FLAG_NO_LAM     = 1 << 5
+};
+
+enum {
+	MTHCA_KAR_PAGE  = 1,
+	MTHCA_MAX_PORTS = 2
+};
+
+enum {
+	MTHCA_EQ_CONTEXT_SIZE =  0x40,
+	MTHCA_CQ_CONTEXT_SIZE =  0x40,
+	MTHCA_QP_CONTEXT_SIZE = 0x200,
+	MTHCA_RDB_ENTRY_SIZE  =  0x20,
+	MTHCA_AV_SIZE         =  0x20,
+	MTHCA_MGM_ENTRY_SIZE  =  0x40,
+
+	/* Arbel FW gives us these, but we need them for Tavor */
+	MTHCA_MPT_ENTRY_SIZE  =  0x40,
+	MTHCA_MTT_SEG_SIZE    =  0x40,
+};
+
+enum {
+	MTHCA_EQ_CMD,
+	MTHCA_EQ_ASYNC,
+	MTHCA_EQ_COMP,
+	MTHCA_NUM_EQ
+};
+
+struct mthca_cmd {
+	int                       use_events;
+	struct semaphore          hcr_sem;
+	struct semaphore 	  poll_sem;
+	struct semaphore 	  event_sem;
+	int              	  max_cmds;
+	spinlock_t                context_lock;
+	int                       free_head;
+	struct mthca_cmd_context *context;
+	u16                       token_mask;
+};
+
+struct mthca_limits {
+	int      num_ports;
+	int      vl_cap;
+	int      mtu_cap;
+	int      gid_table_len;
+	int      pkey_table_len;
+	int      local_ca_ack_delay;
+	int      max_sg;
+	int      num_qps;
+	int      reserved_qps;
+	int      num_srqs;
+	int      reserved_srqs;
+	int      num_eecs;
+	int      reserved_eecs;
+	int      num_cqs;
+	int      reserved_cqs;
+	int      num_eqs;
+	int      reserved_eqs;
+	int      num_mpts;
+	int      num_mtt_segs;
+	int      mtt_seg_size;
+	int      reserved_mtts;
+	int      reserved_mrws;
+	int      reserved_uars;
+	int      num_mgms;
+	int      num_amgms;
+	int      reserved_mcgs;
+	int      num_pds;
+	int      reserved_pds;
+};
+
+struct mthca_alloc {
+	u32            last;
+	u32            top;
+	u32            max;
+	u32            mask;
+	spinlock_t     lock;
+	unsigned long *table;
+};
+
+struct mthca_array {
+	struct {
+		void    **page;
+		int       used;
+	} *page_list;
+};
+
+struct mthca_pd_table {
+	struct mthca_alloc alloc;
+};
+
+struct mthca_mr_table {
+	struct mthca_alloc      mpt_alloc;
+	int                     max_mtt_order;
+	unsigned long         **mtt_buddy;
+	u64                     mtt_base;
+	struct mthca_icm_table *mtt_table;
+	struct mthca_icm_table *mpt_table;
+};
+
+struct mthca_eq_table {
+	struct mthca_alloc alloc;
+	void __iomem      *clr_int;
+	u32                clr_mask;
+	struct mthca_eq    eq[MTHCA_NUM_EQ];
+	u64                icm_virt;
+	struct page       *icm_page;
+	dma_addr_t         icm_dma;
+	int                have_irq;
+	u8                 inta_pin;
+};
+
+struct mthca_cq_table {
+	struct mthca_alloc 	alloc;
+	spinlock_t         	lock;
+	struct mthca_array      cq;
+	struct mthca_icm_table *table;
+};
+
+struct mthca_qp_table {
+	struct mthca_alloc     	alloc;
+	u32                    	rdb_base;
+	int                    	rdb_shift;
+	int                    	sqp_start;
+	spinlock_t             	lock;
+	struct mthca_array     	qp;
+	struct mthca_icm_table *qp_table;
+	struct mthca_icm_table *eqp_table;
+};
+
+struct mthca_av_table {
+	struct pci_pool   *pool;
+	int                num_ddr_avs;
+	u64                ddr_av_base;
+	void __iomem      *av_map;
+	struct mthca_alloc alloc;
+};
+
+struct mthca_mcg_table {
+	struct semaphore   sem;
+	struct mthca_alloc alloc;
+};
+
+struct mthca_dev {
+	struct ib_device  ib_dev;
+	struct pci_dev   *pdev;
+
+	int          	 hca_type;
+	unsigned long	 mthca_flags;
+
+	u32              rev_id;
+
+	/* firmware info */
+	u64              fw_ver;
+	union {
+		struct {
+			u64 fw_start;
+			u64 fw_end;
+		}        tavor;
+		struct {
+			u64 clr_int_base;
+			u64 eq_arm_base;
+			u64 eq_set_ci_base;
+			struct mthca_icm *fw_icm;
+			struct mthca_icm *aux_icm;
+			u16 fw_pages;
+		}        arbel;
+	}                fw;
+
+	u64              ddr_start;
+	u64              ddr_end;
+
+	MTHCA_DECLARE_DOORBELL_LOCK(doorbell_lock)
+	struct semaphore cap_mask_mutex;
+
+	void __iomem    *hcr;
+	void __iomem    *ecr_base;
+	void __iomem    *clr_base;
+	void __iomem    *kar;
+
+	struct mthca_cmd    cmd;
+	struct mthca_limits limits;
+
+	struct mthca_pd_table  pd_table;
+	struct mthca_mr_table  mr_table;
+	struct mthca_eq_table  eq_table;
+	struct mthca_cq_table  cq_table;
+	struct mthca_qp_table  qp_table;
+	struct mthca_av_table  av_table;
+	struct mthca_mcg_table mcg_table;
+
+	struct mthca_pd       driver_pd;
+	struct mthca_mr       driver_mr;
+
+	struct ib_mad_agent  *send_agent[MTHCA_MAX_PORTS][2];
+	struct ib_ah         *sm_ah[MTHCA_MAX_PORTS];
+	spinlock_t            sm_lock;
+};
+
+#define mthca_dbg(mdev, format, arg...) \
+	dev_dbg(&mdev->pdev->dev, format, ## arg)
+#define mthca_err(mdev, format, arg...) \
+	dev_err(&mdev->pdev->dev, format, ## arg)
+#define mthca_info(mdev, format, arg...) \
+	dev_info(&mdev->pdev->dev, format, ## arg)
+#define mthca_warn(mdev, format, arg...) \
+	dev_warn(&mdev->pdev->dev, format, ## arg)
+
+extern void __buggy_use_of_MTHCA_GET(void);
+extern void __buggy_use_of_MTHCA_PUT(void);
+
+#define MTHCA_GET(dest, source, offset)                               \
+	do {                                                          \
+		void *__p = (char *) (source) + (offset);             \
+		switch (sizeof (dest)) {                              \
+			case 1: (dest) = *(u8 *) __p;       break;    \
+			case 2: (dest) = be16_to_cpup(__p); break;    \
+			case 4: (dest) = be32_to_cpup(__p); break;    \
+			case 8: (dest) = be64_to_cpup(__p); break;    \
+			default: __buggy_use_of_MTHCA_GET();          \
+		}                                                     \
+	} while (0)
+
+#define MTHCA_PUT(dest, source, offset)                               \
+	do {                                                          \
+		__typeof__(source) *__p =                             \
+			(__typeof__(source) *) ((char *) (dest) + (offset)); \
+		switch (sizeof(source)) {                             \
+			case 1: *__p = (source);            break;    \
+			case 2: *__p = cpu_to_be16(source); break;    \
+			case 4: *__p = cpu_to_be32(source); break;    \
+			case 8: *__p = cpu_to_be64(source); break;    \
+			default: __buggy_use_of_MTHCA_PUT();          \
+		}                                                     \
+	} while (0)
+
+int mthca_reset(struct mthca_dev *mdev);
+
+u32 mthca_alloc(struct mthca_alloc *alloc);
+void mthca_free(struct mthca_alloc *alloc, u32 obj);
+int mthca_alloc_init(struct mthca_alloc *alloc, u32 num, u32 mask,
+		     u32 reserved);
+void mthca_alloc_cleanup(struct mthca_alloc *alloc);
+void *mthca_array_get(struct mthca_array *array, int index);
+int mthca_array_set(struct mthca_array *array, int index, void *value);
+void mthca_array_clear(struct mthca_array *array, int index);
+int mthca_array_init(struct mthca_array *array, int nent);
+void mthca_array_cleanup(struct mthca_array *array, int nent);
+
+int mthca_init_pd_table(struct mthca_dev *dev);
+int mthca_init_mr_table(struct mthca_dev *dev);
+int mthca_init_eq_table(struct mthca_dev *dev);
+int mthca_init_cq_table(struct mthca_dev *dev);
+int mthca_init_qp_table(struct mthca_dev *dev);
+int mthca_init_av_table(struct mthca_dev *dev);
+int mthca_init_mcg_table(struct mthca_dev *dev);
+
+void mthca_cleanup_pd_table(struct mthca_dev *dev);
+void mthca_cleanup_mr_table(struct mthca_dev *dev);
+void mthca_cleanup_eq_table(struct mthca_dev *dev);
+void mthca_cleanup_cq_table(struct mthca_dev *dev);
+void mthca_cleanup_qp_table(struct mthca_dev *dev);
+void mthca_cleanup_av_table(struct mthca_dev *dev);
+void mthca_cleanup_mcg_table(struct mthca_dev *dev);
+
+int mthca_register_device(struct mthca_dev *dev);
+void mthca_unregister_device(struct mthca_dev *dev);
+
+int mthca_pd_alloc(struct mthca_dev *dev, struct mthca_pd *pd);
+void mthca_pd_free(struct mthca_dev *dev, struct mthca_pd *pd);
+
+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,
+			u64 *buffer_list, int buffer_size_shift,
+			int list_len, u64 iova, u64 total_size,
+			u32 access, struct mthca_mr *mr);
+void mthca_free_mr(struct mthca_dev *dev, struct mthca_mr *mr);
+
+int mthca_map_eq_icm(struct mthca_dev *dev, u64 icm_virt);
+void mthca_unmap_eq_icm(struct mthca_dev *dev);
+
+int mthca_poll_cq(struct ib_cq *ibcq, int num_entries,
+		  struct ib_wc *entry);
+void mthca_arm_cq(struct mthca_dev *dev, struct mthca_cq *cq,
+		  int solicited);
+int mthca_init_cq(struct mthca_dev *dev, int nent,
+		  struct mthca_cq *cq);
+void mthca_free_cq(struct mthca_dev *dev,
+		   struct mthca_cq *cq);
+void mthca_cq_event(struct mthca_dev *dev, u32 cqn);
+void mthca_cq_clean(struct mthca_dev *dev, u32 cqn, u32 qpn);
+
+void mthca_qp_event(struct mthca_dev *dev, u32 qpn,
+		    enum ib_event_type event_type);
+int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask);
+int mthca_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
+		    struct ib_send_wr **bad_wr);
+int mthca_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr,
+		       struct ib_recv_wr **bad_wr);
+int mthca_free_err_wqe(struct mthca_qp *qp, int is_send,
+		       int index, int *dbd, u32 *new_wqe);
+int mthca_alloc_qp(struct mthca_dev *dev,
+		   struct mthca_pd *pd,
+		   struct mthca_cq *send_cq,
+		   struct mthca_cq *recv_cq,
+		   enum ib_qp_type type,
+		   enum ib_sig_type send_policy,
+		   enum ib_sig_type recv_policy,
+		   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,
+		    enum ib_sig_type recv_policy,
+		    int qpn,
+		    int port,
+		    struct mthca_sqp *sqp);
+void mthca_free_qp(struct mthca_dev *dev, struct mthca_qp *qp);
+int mthca_create_ah(struct mthca_dev *dev,
+		    struct mthca_pd *pd,
+		    struct ib_ah_attr *ah_attr,
+		    struct mthca_ah *ah);
+int mthca_destroy_ah(struct mthca_dev *dev, struct mthca_ah *ah);
+int mthca_read_ah(struct mthca_dev *dev, struct mthca_ah *ah,
+		  struct ib_ud_header *header);
+
+int mthca_multicast_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid);
+int mthca_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid);
+
+int mthca_process_mad(struct ib_device *ibdev,
+		      int mad_flags,
+		      u8 port_num,
+		      struct ib_wc *in_wc,
+		      struct ib_grh *in_grh,
+		      struct ib_mad *in_mad,
+		      struct ib_mad *out_mad);
+int mthca_create_agents(struct mthca_dev *dev);
+void mthca_free_agents(struct mthca_dev *dev);
+
+static inline struct mthca_dev *to_mdev(struct ib_device *ibdev)
+{
+	return container_of(ibdev, struct mthca_dev, ib_dev);
+}
+
+#endif /* MTHCA_DEV_H */
diff -Nru a/drivers/infiniband/hw/mthca/mthca_doorbell.h b/drivers/infiniband/hw/mthca/mthca_doorbell.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/infiniband/hw/mthca/mthca_doorbell.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2004 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: mthca_doorbell.h 1349 2004-12-16 21:09:43Z roland $
+ */
+
+#include <linux/types.h>
+
+#define MTHCA_RD_DOORBELL      0x00
+#define MTHCA_SEND_DOORBELL    0x10
+#define MTHCA_RECEIVE_DOORBELL 0x18
+#define MTHCA_CQ_DOORBELL      0x20
+#define MTHCA_EQ_DOORBELL      0x28
+
+#if BITS_PER_LONG == 64
+/*
+ * Assume that we can just write a 64-bit doorbell atomically.  s390
+ * actually doesn't have writeq() but S/390 systems don't even have
+ * PCI so we won't worry about it.
+ */
+
+#define MTHCA_DECLARE_DOORBELL_LOCK(name)
+#define MTHCA_INIT_DOORBELL_LOCK(ptr)    do { } while (0)
+#define MTHCA_GET_DOORBELL_LOCK(ptr)      (NULL)
+
+static inline void mthca_write64(u32 val[2], void __iomem *dest,
+				 spinlock_t *doorbell_lock)
+{
+	__raw_writeq(*(u64 *) val, dest);
+}
+
+#else
+
+/*
+ * Just fall back to a spinlock to protect the doorbell if
+ * BITS_PER_LONG is 32 -- there's no portable way to do atomic 64-bit
+ * MMIO writes.
+ */
+
+#define MTHCA_DECLARE_DOORBELL_LOCK(name) spinlock_t name;
+#define MTHCA_INIT_DOORBELL_LOCK(ptr)     spin_lock_init(ptr)
+#define MTHCA_GET_DOORBELL_LOCK(ptr)      (ptr)
+
+static inline void mthca_write64(u32 val[2], void __iomem *dest,
+				 spinlock_t *doorbell_lock)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(doorbell_lock, flags);
+	__raw_writel(val[0], dest);
+	__raw_writel(val[1], dest + 4);
+	spin_unlock_irqrestore(doorbell_lock, flags);
+}
+
+#endif
diff -Nru a/drivers/infiniband/hw/mthca/mthca_eq.c b/drivers/infiniband/hw/mthca/mthca_eq.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/infiniband/hw/mthca/mthca_eq.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,744 @@
+/*
+ * Copyright (c) 2004, 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: mthca_eq.c 1382 2004-12-24 02:21:02Z roland $
+ */
+
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+
+#include "mthca_dev.h"
+#include "mthca_cmd.h"
+#include "mthca_config_reg.h"
+
+enum {
+	MTHCA_NUM_ASYNC_EQE = 0x80,
+	MTHCA_NUM_CMD_EQE   = 0x80,
+	MTHCA_EQ_ENTRY_SIZE = 0x20
+};
+
+/*
+ * Must be packed because start is 64 bits but only aligned to 32 bits.
+ */
+struct mthca_eq_context {
+	u32 flags;
+	u64 start;
+	u32 logsize_usrpage;
+	u32 pd;
+	u8  reserved1[3];
+	u8  intr;
+	u32 lost_count;
+	u32 lkey;
+	u32 reserved2[2];
+	u32 consumer_index;
+	u32 producer_index;
+	u32 reserved3[4];
+} __attribute__((packed));
+
+#define MTHCA_EQ_STATUS_OK          ( 0 << 28)
+#define MTHCA_EQ_STATUS_OVERFLOW    ( 9 << 28)
+#define MTHCA_EQ_STATUS_WRITE_FAIL  (10 << 28)
+#define MTHCA_EQ_OWNER_SW           ( 0 << 24)
+#define MTHCA_EQ_OWNER_HW           ( 1 << 24)
+#define MTHCA_EQ_FLAG_TR            ( 1 << 18)
+#define MTHCA_EQ_FLAG_OI            ( 1 << 17)
+#define MTHCA_EQ_STATE_ARMED        ( 1 <<  8)
+#define MTHCA_EQ_STATE_FIRED        ( 2 <<  8)
+#define MTHCA_EQ_STATE_ALWAYS_ARMED ( 3 <<  8)
+
+enum {
+	MTHCA_EVENT_TYPE_COMP       	    = 0x00,
+	MTHCA_EVENT_TYPE_PATH_MIG   	    = 0x01,
+	MTHCA_EVENT_TYPE_COMM_EST   	    = 0x02,
+	MTHCA_EVENT_TYPE_SQ_DRAINED 	    = 0x03,
+	MTHCA_EVENT_TYPE_SRQ_LAST_WQE       = 0x13,
+	MTHCA_EVENT_TYPE_CQ_ERROR   	    = 0x04,
+	MTHCA_EVENT_TYPE_WQ_CATAS_ERROR     = 0x05,
+	MTHCA_EVENT_TYPE_EEC_CATAS_ERROR    = 0x06,
+	MTHCA_EVENT_TYPE_PATH_MIG_FAILED    = 0x07,
+	MTHCA_EVENT_TYPE_WQ_INVAL_REQ_ERROR = 0x10,
+	MTHCA_EVENT_TYPE_WQ_ACCESS_ERROR    = 0x11,
+	MTHCA_EVENT_TYPE_SRQ_CATAS_ERROR    = 0x12,
+	MTHCA_EVENT_TYPE_LOCAL_CATAS_ERROR  = 0x08,
+	MTHCA_EVENT_TYPE_PORT_CHANGE        = 0x09,
+	MTHCA_EVENT_TYPE_EQ_OVERFLOW        = 0x0f,
+	MTHCA_EVENT_TYPE_ECC_DETECT         = 0x0e,
+	MTHCA_EVENT_TYPE_CMD                = 0x0a
+};
+
+#define MTHCA_ASYNC_EVENT_MASK ((1ULL << MTHCA_EVENT_TYPE_PATH_MIG)           | \
+				(1ULL << MTHCA_EVENT_TYPE_COMM_EST)           | \
+				(1ULL << MTHCA_EVENT_TYPE_SQ_DRAINED)         | \
+				(1ULL << MTHCA_EVENT_TYPE_CQ_ERROR)           | \
+				(1ULL << MTHCA_EVENT_TYPE_WQ_CATAS_ERROR)     | \
+				(1ULL << MTHCA_EVENT_TYPE_EEC_CATAS_ERROR)    | \
+				(1ULL << MTHCA_EVENT_TYPE_PATH_MIG_FAILED)    | \
+				(1ULL << MTHCA_EVENT_TYPE_WQ_INVAL_REQ_ERROR) | \
+				(1ULL << MTHCA_EVENT_TYPE_WQ_ACCESS_ERROR)    | \
+				(1ULL << MTHCA_EVENT_TYPE_LOCAL_CATAS_ERROR)  | \
+				(1ULL << MTHCA_EVENT_TYPE_PORT_CHANGE)        | \
+				(1ULL << MTHCA_EVENT_TYPE_ECC_DETECT))
+#define MTHCA_SRQ_EVENT_MASK    (1ULL << MTHCA_EVENT_TYPE_SRQ_CATAS_ERROR)    | \
+				(1ULL << MTHCA_EVENT_TYPE_SRQ_LAST_WQE)
+#define MTHCA_CMD_EVENT_MASK    (1ULL << MTHCA_EVENT_TYPE_CMD)
+
+#define MTHCA_EQ_DB_INC_CI     (1 << 24)
+#define MTHCA_EQ_DB_REQ_NOT    (2 << 24)
+#define MTHCA_EQ_DB_DISARM_CQ  (3 << 24)
+#define MTHCA_EQ_DB_SET_CI     (4 << 24)
+#define MTHCA_EQ_DB_ALWAYS_ARM (5 << 24)
+
+struct mthca_eqe {
+	u8 reserved1;
+	u8 type;
+	u8 reserved2;
+	u8 subtype;
+	union {
+		u32 raw[6];
+		struct {
+			u32 cqn;
+		} __attribute__((packed)) comp;
+		struct {
+			u16 reserved1;
+			u16 token;
+			u32 reserved2;
+			u8  reserved3[3];
+			u8  status;
+			u64 out_param;
+		} __attribute__((packed)) cmd;
+		struct {
+			u32 qpn;
+		} __attribute__((packed)) qp;
+		struct {
+			u32 cqn;
+			u32 reserved1;
+			u8  reserved2[3];
+			u8  syndrome;
+		} __attribute__((packed)) cq_err;
+		struct {
+			u32 reserved1[2];
+			u32 port;
+		} __attribute__((packed)) port_change;
+	} event;
+	u8 reserved3[3];
+	u8 owner;
+} __attribute__((packed));
+
+#define  MTHCA_EQ_ENTRY_OWNER_SW      (0 << 7)
+#define  MTHCA_EQ_ENTRY_OWNER_HW      (1 << 7)
+
+static inline u64 async_mask(struct mthca_dev *dev)
+{
+	return dev->mthca_flags & MTHCA_FLAG_SRQ ?
+		MTHCA_ASYNC_EVENT_MASK | MTHCA_SRQ_EVENT_MASK :
+		MTHCA_ASYNC_EVENT_MASK;
+}
+
+static inline void set_eq_ci(struct mthca_dev *dev, struct mthca_eq *eq, u32 ci)
+{
+	u32 doorbell[2];
+
+	doorbell[0] = cpu_to_be32(MTHCA_EQ_DB_SET_CI | eq->eqn);
+	doorbell[1] = cpu_to_be32(ci & (eq->nent - 1));
+
+	mthca_write64(doorbell,
+		      dev->kar + MTHCA_EQ_DOORBELL,
+		      MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
+}
+
+static inline void eq_req_not(struct mthca_dev *dev, int eqn)
+{
+	u32 doorbell[2];
+
+	doorbell[0] = cpu_to_be32(MTHCA_EQ_DB_REQ_NOT | eqn);
+	doorbell[1] = 0;
+
+	mthca_write64(doorbell,
+		      dev->kar + MTHCA_EQ_DOORBELL,
+		      MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
+}
+
+static inline void disarm_cq(struct mthca_dev *dev, int eqn, int cqn)
+{
+	u32 doorbell[2];
+
+	doorbell[0] = cpu_to_be32(MTHCA_EQ_DB_DISARM_CQ | eqn);
+	doorbell[1] = cpu_to_be32(cqn);
+
+	mthca_write64(doorbell,
+		      dev->kar + MTHCA_EQ_DOORBELL,
+		      MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
+}
+
+static inline struct mthca_eqe *get_eqe(struct mthca_eq *eq, u32 entry)
+{
+	unsigned long off = (entry & (eq->nent - 1)) * MTHCA_EQ_ENTRY_SIZE;
+	return eq->page_list[off / PAGE_SIZE].buf + off % PAGE_SIZE;
+}
+
+static inline struct mthca_eqe* next_eqe_sw(struct mthca_eq *eq)
+{
+	struct mthca_eqe* eqe;
+	eqe = get_eqe(eq, eq->cons_index);
+	return (MTHCA_EQ_ENTRY_OWNER_HW & eqe->owner) ? NULL : eqe;
+}
+
+static inline void set_eqe_hw(struct mthca_eqe *eqe)
+{
+	eqe->owner =  MTHCA_EQ_ENTRY_OWNER_HW;
+}
+
+static void port_change(struct mthca_dev *dev, int port, int active)
+{
+	struct ib_event record;
+
+	mthca_dbg(dev, "Port change to %s for port %d\n",
+		  active ? "active" : "down", port);
+
+	record.device = &dev->ib_dev;
+	record.event  = active ? IB_EVENT_PORT_ACTIVE : IB_EVENT_PORT_ERR;
+	record.element.port_num = port;
+
+	ib_dispatch_event(&record);
+}
+
+static void mthca_eq_int(struct mthca_dev *dev, struct mthca_eq *eq)
+{
+	struct mthca_eqe *eqe;
+	int disarm_cqn;
+	int  eqes_found = 0;
+
+	while ((eqe = next_eqe_sw(eq))) {
+		int set_ci = 0;
+
+		/*
+		 * Make sure we read EQ entry contents after we've
+		 * checked the ownership bit.
+		 */
+		rmb();
+
+		switch (eqe->type) {
+		case MTHCA_EVENT_TYPE_COMP:
+			disarm_cqn = be32_to_cpu(eqe->event.comp.cqn) & 0xffffff;
+			disarm_cq(dev, eq->eqn, disarm_cqn);
+			mthca_cq_event(dev, disarm_cqn);
+			break;
+
+		case MTHCA_EVENT_TYPE_PATH_MIG:
+			mthca_qp_event(dev, be32_to_cpu(eqe->event.qp.qpn) & 0xffffff,
+				       IB_EVENT_PATH_MIG);
+			break;
+
+		case MTHCA_EVENT_TYPE_COMM_EST:
+			mthca_qp_event(dev, be32_to_cpu(eqe->event.qp.qpn) & 0xffffff,
+				       IB_EVENT_COMM_EST);
+			break;
+
+		case MTHCA_EVENT_TYPE_SQ_DRAINED:
+			mthca_qp_event(dev, be32_to_cpu(eqe->event.qp.qpn) & 0xffffff,
+				       IB_EVENT_SQ_DRAINED);
+			break;
+
+		case MTHCA_EVENT_TYPE_WQ_CATAS_ERROR:
+			mthca_qp_event(dev, be32_to_cpu(eqe->event.qp.qpn) & 0xffffff,
+				       IB_EVENT_QP_FATAL);
+			break;
+
+		case MTHCA_EVENT_TYPE_PATH_MIG_FAILED:
+			mthca_qp_event(dev, be32_to_cpu(eqe->event.qp.qpn) & 0xffffff,
+				       IB_EVENT_PATH_MIG_ERR);
+			break;
+
+		case MTHCA_EVENT_TYPE_WQ_INVAL_REQ_ERROR:
+			mthca_qp_event(dev, be32_to_cpu(eqe->event.qp.qpn) & 0xffffff,
+				       IB_EVENT_QP_REQ_ERR);
+			break;
+
+		case MTHCA_EVENT_TYPE_WQ_ACCESS_ERROR:
+			mthca_qp_event(dev, be32_to_cpu(eqe->event.qp.qpn) & 0xffffff,
+				       IB_EVENT_QP_ACCESS_ERR);
+			break;
+
+		case MTHCA_EVENT_TYPE_CMD:
+			mthca_cmd_event(dev,
+					be16_to_cpu(eqe->event.cmd.token),
+					eqe->event.cmd.status,
+					be64_to_cpu(eqe->event.cmd.out_param));
+			/*
+			 * cmd_event() may add more commands.
+			 * The card will think the queue has overflowed if
+			 * we don't tell it we've been processing events.
+			 */
+			set_ci = 1;
+			break;
+
+		case MTHCA_EVENT_TYPE_PORT_CHANGE:
+			port_change(dev,
+				    (be32_to_cpu(eqe->event.port_change.port) >> 28) & 3,
+				    eqe->subtype == 0x4);
+			break;
+
+		case MTHCA_EVENT_TYPE_CQ_ERROR:
+			mthca_warn(dev, "CQ %s on CQN %08x\n",
+				   eqe->event.cq_err.syndrome == 1 ?
+				   "overrun" : "access violation",
+				   be32_to_cpu(eqe->event.cq_err.cqn));
+			break;
+
+		case MTHCA_EVENT_TYPE_EQ_OVERFLOW:
+			mthca_warn(dev, "EQ overrun on EQN %d\n", eq->eqn);
+			break;
+
+		case MTHCA_EVENT_TYPE_EEC_CATAS_ERROR:
+		case MTHCA_EVENT_TYPE_SRQ_CATAS_ERROR:
+		case MTHCA_EVENT_TYPE_LOCAL_CATAS_ERROR:
+		case MTHCA_EVENT_TYPE_ECC_DETECT:
+		default:
+			mthca_warn(dev, "Unhandled event %02x(%02x) on EQ %d\n",
+				   eqe->type, eqe->subtype, eq->eqn);
+			break;
+		};
+
+		set_eqe_hw(eqe);
+		++eq->cons_index;
+		eqes_found = 1;
+
+		if (set_ci) {
+			wmb(); /* see comment below */
+			set_eq_ci(dev, eq, eq->cons_index);
+			set_ci = 0;
+		}
+	}
+
+	/*
+	 * This barrier makes sure that all updates to
+	 * ownership bits done by set_eqe_hw() hit memory
+	 * before the consumer index is updated.  set_eq_ci()
+	 * allows the HCA to possibly write more EQ entries,
+	 * and we want to avoid the exceedingly unlikely
+	 * possibility of the HCA writing an entry and then
+	 * having set_eqe_hw() overwrite the owner field.
+	 */
+	if (likely(eqes_found)) {
+		wmb();
+		set_eq_ci(dev, eq, eq->cons_index);
+	}
+	eq_req_not(dev, eq->eqn);
+}
+
+static irqreturn_t mthca_interrupt(int irq, void *dev_ptr, struct pt_regs *regs)
+{
+	struct mthca_dev *dev = dev_ptr;
+	u32 ecr;
+	int work = 0;
+	int i;
+
+	if (dev->eq_table.clr_mask)
+		writel(dev->eq_table.clr_mask, dev->eq_table.clr_int);
+
+	if ((ecr = readl(dev->ecr_base + 4)) != 0) {
+		work = 1;
+
+		writel(ecr, dev->ecr_base +
+		       MTHCA_ECR_CLR_BASE - MTHCA_ECR_BASE + 4);
+
+		for (i = 0; i < MTHCA_NUM_EQ; ++i)
+			if (ecr & dev->eq_table.eq[i].ecr_mask)
+				mthca_eq_int(dev, &dev->eq_table.eq[i]);
+	}
+
+	return IRQ_RETVAL(work);
+}
+
+static irqreturn_t mthca_msi_x_interrupt(int irq, void *eq_ptr,
+					 struct pt_regs *regs)
+{
+	struct mthca_eq  *eq  = eq_ptr;
+	struct mthca_dev *dev = eq->dev;
+
+	mthca_eq_int(dev, eq);
+
+	/* MSI-X vectors always belong to us */
+	return IRQ_HANDLED;
+}
+
+static int __devinit mthca_create_eq(struct mthca_dev *dev,
+				     int nent,
+				     u8 intr,
+				     struct mthca_eq *eq)
+{
+	int npages = (nent * MTHCA_EQ_ENTRY_SIZE + PAGE_SIZE - 1) /
+		PAGE_SIZE;
+	u64 *dma_list = NULL;
+	dma_addr_t t;
+	void *mailbox = NULL;
+	struct mthca_eq_context *eq_context;
+	int err = -ENOMEM;
+	int i;
+	u8 status;
+
+	/* Make sure EQ size is aligned to a power of 2 size. */
+	for (i = 1; i < nent; i <<= 1)
+		; /* nothing */
+	nent = i;
+
+	eq->dev = dev;
+
+	eq->page_list = kmalloc(npages * sizeof *eq->page_list,
+				GFP_KERNEL);
+	if (!eq->page_list)
+		goto err_out;
+
+	for (i = 0; i < npages; ++i)
+		eq->page_list[i].buf = NULL;
+
+	dma_list = kmalloc(npages * sizeof *dma_list, GFP_KERNEL);
+	if (!dma_list)
+		goto err_out_free;
+
+	mailbox = kmalloc(sizeof *eq_context + MTHCA_CMD_MAILBOX_EXTRA,
+			  GFP_KERNEL);
+	if (!mailbox)
+		goto err_out_free;
+	eq_context = MAILBOX_ALIGN(mailbox);
+
+	for (i = 0; i < npages; ++i) {
+		eq->page_list[i].buf = pci_alloc_consistent(dev->pdev,
+							    PAGE_SIZE, &t);
+		if (!eq->page_list[i].buf)
+			goto err_out_free;
+
+		dma_list[i] = t;
+		pci_unmap_addr_set(&eq->page_list[i], mapping, t);
+
+		memset(eq->page_list[i].buf, 0, PAGE_SIZE);
+	}
+
+	for (i = 0; i < nent; ++i)
+		set_eqe_hw(get_eqe(eq, i));
+
+	eq->eqn = mthca_alloc(&dev->eq_table.alloc);
+	if (eq->eqn == -1)
+		goto err_out_free;
+
+	err = mthca_mr_alloc_phys(dev, dev->driver_pd.pd_num,
+				  dma_list, PAGE_SHIFT, npages,
+				  0, npages * PAGE_SIZE,
+				  MTHCA_MPT_FLAG_LOCAL_WRITE |
+				  MTHCA_MPT_FLAG_LOCAL_READ,
+				  &eq->mr);
+	if (err)
+		goto err_out_free_eq;
+
+	eq->nent = nent;
+
+	memset(eq_context, 0, sizeof *eq_context);
+	eq_context->flags           = cpu_to_be32(MTHCA_EQ_STATUS_OK   |
+						  MTHCA_EQ_OWNER_HW    |
+						  MTHCA_EQ_STATE_ARMED |
+						  MTHCA_EQ_FLAG_TR);
+	eq_context->start           = cpu_to_be64(0);
+	eq_context->logsize_usrpage = cpu_to_be32((ffs(nent) - 1) << 24 |
+						  MTHCA_KAR_PAGE);
+	eq_context->pd              = cpu_to_be32(dev->driver_pd.pd_num);
+	eq_context->intr            = intr;
+	eq_context->lkey            = cpu_to_be32(eq->mr.ibmr.lkey);
+
+	err = mthca_SW2HW_EQ(dev, eq_context, eq->eqn, &status);
+	if (err) {
+		mthca_warn(dev, "SW2HW_EQ failed (%d)\n", err);
+		goto err_out_free_mr;
+	}
+	if (status) {
+		mthca_warn(dev, "SW2HW_EQ returned status 0x%02x\n",
+			   status);
+		err = -EINVAL;
+		goto err_out_free_mr;
+	}
+
+	kfree(dma_list);
+	kfree(mailbox);
+
+	eq->ecr_mask   = swab32(1 << eq->eqn);
+	eq->cons_index = 0;
+
+	eq_req_not(dev, eq->eqn);
+
+	mthca_dbg(dev, "Allocated EQ %d with %d entries\n",
+		  eq->eqn, nent);
+
+	return err;
+
+ err_out_free_mr:
+	mthca_free_mr(dev, &eq->mr);
+
+ err_out_free_eq:
+	mthca_free(&dev->eq_table.alloc, eq->eqn);
+
+ err_out_free:
+	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));
+
+	kfree(eq->page_list);
+	kfree(dma_list);
+	kfree(mailbox);
+
+ err_out:
+	return err;
+}
+
+static void mthca_free_eq(struct mthca_dev *dev,
+			  struct mthca_eq *eq)
+{
+	void *mailbox = NULL;
+	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)
+		return;
+
+	err = mthca_HW2SW_EQ(dev, MAILBOX_ALIGN(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);
+
+	if (0) {
+		mthca_dbg(dev, "Dumping EQ context %02x:\n", eq->eqn);
+		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));
+			if ((i + 1) % 4 == 0)
+				printk("\n");
+		}
+	}
+
+
+	mthca_free_mr(dev, &eq->mr);
+	for (i = 0; i < npages; ++i)
+		pci_free_consistent(dev->pdev, PAGE_SIZE,
+				    eq->page_list[i].buf,
+				    pci_unmap_addr(&eq->page_list[i], mapping));
+
+	kfree(eq->page_list);
+	kfree(mailbox);
+}
+
+static void mthca_free_irqs(struct mthca_dev *dev)
+{
+	int i;
+
+	if (dev->eq_table.have_irq)
+		free_irq(dev->pdev->irq, dev);
+	for (i = 0; i < MTHCA_NUM_EQ; ++i)
+		if (dev->eq_table.eq[i].have_irq)
+			free_irq(dev->eq_table.eq[i].msi_x_vector,
+				 dev->eq_table.eq + i);
+}
+
+int __devinit mthca_map_eq_icm(struct mthca_dev *dev, u64 icm_virt)
+{
+	int ret;
+	u8 status;
+
+	/*
+	 * We assume that mapping one page is enough for the whole EQ
+	 * context table.  This is fine with all current HCAs, because
+	 * we only use 32 EQs and each EQ uses 32 bytes of context
+	 * memory, or 1 KB total.
+	 */
+	dev->eq_table.icm_virt = icm_virt;
+	dev->eq_table.icm_page = alloc_page(GFP_HIGHUSER);
+	if (!dev->eq_table.icm_page)
+		return -ENOMEM;
+	dev->eq_table.icm_dma  = pci_map_page(dev->pdev, dev->eq_table.icm_page, 0,
+					      PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
+	if (pci_dma_mapping_error(dev->eq_table.icm_dma)) {
+		__free_page(dev->eq_table.icm_page);
+		return -ENOMEM;
+	}
+
+	ret = mthca_MAP_ICM_page(dev, dev->eq_table.icm_dma, icm_virt, &status);
+	if (!ret && status)
+		ret = -EINVAL;
+	if (ret) {
+		pci_unmap_page(dev->pdev, dev->eq_table.icm_dma, PAGE_SIZE,
+			       PCI_DMA_BIDIRECTIONAL);
+		__free_page(dev->eq_table.icm_page);
+	}
+
+	return ret;
+}
+
+void __devexit mthca_unmap_eq_icm(struct mthca_dev *dev)
+{
+	u8 status;
+
+	mthca_UNMAP_ICM(dev, dev->eq_table.icm_virt, PAGE_SIZE / 4096, &status);
+	pci_unmap_page(dev->pdev, dev->eq_table.icm_dma, PAGE_SIZE,
+		       PCI_DMA_BIDIRECTIONAL);
+	__free_page(dev->eq_table.icm_page);
+}
+
+int __devinit mthca_init_eq_table(struct mthca_dev *dev)
+{
+	int err;
+	u8 status;
+	u8 intr;
+	int i;
+
+	err = mthca_alloc_init(&dev->eq_table.alloc,
+			       dev->limits.num_eqs,
+			       dev->limits.num_eqs - 1,
+			       dev->limits.reserved_eqs);
+	if (err)
+		return err;
+
+	if (dev->mthca_flags & MTHCA_FLAG_MSI ||
+	    dev->mthca_flags & MTHCA_FLAG_MSI_X) {
+		dev->eq_table.clr_mask = 0;
+	} else {
+		dev->eq_table.clr_mask =
+			swab32(1 << (dev->eq_table.inta_pin & 31));
+		dev->eq_table.clr_int  = dev->clr_base +
+			(dev->eq_table.inta_pin < 31 ? 4 : 0);
+	}
+
+	intr = (dev->mthca_flags & MTHCA_FLAG_MSI) ?
+		128 : dev->eq_table.inta_pin;
+
+	err = mthca_create_eq(dev, dev->limits.num_cqs,
+			      (dev->mthca_flags & MTHCA_FLAG_MSI_X) ? 128 : intr,
+			      &dev->eq_table.eq[MTHCA_EQ_COMP]);
+	if (err)
+		goto err_out_free;
+
+	err = mthca_create_eq(dev, MTHCA_NUM_ASYNC_EQE,
+			      (dev->mthca_flags & MTHCA_FLAG_MSI_X) ? 129 : intr,
+			      &dev->eq_table.eq[MTHCA_EQ_ASYNC]);
+	if (err)
+		goto err_out_comp;
+
+	err = mthca_create_eq(dev, MTHCA_NUM_CMD_EQE,
+			      (dev->mthca_flags & MTHCA_FLAG_MSI_X) ? 130 : intr,
+			      &dev->eq_table.eq[MTHCA_EQ_CMD]);
+	if (err)
+		goto err_out_async;
+
+	if (dev->mthca_flags & MTHCA_FLAG_MSI_X) {
+		static const char *eq_name[] = {
+			[MTHCA_EQ_COMP]  = DRV_NAME " (comp)",
+			[MTHCA_EQ_ASYNC] = DRV_NAME " (async)",
+			[MTHCA_EQ_CMD]   = DRV_NAME " (cmd)"
+		};
+
+		for (i = 0; i < MTHCA_NUM_EQ; ++i) {
+			err = request_irq(dev->eq_table.eq[i].msi_x_vector,
+					  mthca_msi_x_interrupt, 0,
+					  eq_name[i], dev->eq_table.eq + i);
+			if (err)
+				goto err_out_cmd;
+			dev->eq_table.eq[i].have_irq = 1;
+		}
+	} else {
+		err = request_irq(dev->pdev->irq, mthca_interrupt, SA_SHIRQ,
+				  DRV_NAME, dev);
+		if (err)
+			goto err_out_cmd;
+		dev->eq_table.have_irq = 1;
+	}
+
+	err = mthca_MAP_EQ(dev, async_mask(dev),
+			   0, dev->eq_table.eq[MTHCA_EQ_ASYNC].eqn, &status);
+	if (err)
+		mthca_warn(dev, "MAP_EQ for async EQ %d failed (%d)\n",
+			   dev->eq_table.eq[MTHCA_EQ_ASYNC].eqn, err);
+	if (status)
+		mthca_warn(dev, "MAP_EQ for async EQ %d returned status 0x%02x\n",
+			   dev->eq_table.eq[MTHCA_EQ_ASYNC].eqn, status);
+
+	err = mthca_MAP_EQ(dev, MTHCA_CMD_EVENT_MASK,
+			   0, dev->eq_table.eq[MTHCA_EQ_CMD].eqn, &status);
+	if (err)
+		mthca_warn(dev, "MAP_EQ for cmd EQ %d failed (%d)\n",
+			   dev->eq_table.eq[MTHCA_EQ_CMD].eqn, err);
+	if (status)
+		mthca_warn(dev, "MAP_EQ for cmd EQ %d returned status 0x%02x\n",
+			   dev->eq_table.eq[MTHCA_EQ_CMD].eqn, status);
+
+	return 0;
+
+err_out_cmd:
+	mthca_free_irqs(dev);
+	mthca_free_eq(dev, &dev->eq_table.eq[MTHCA_EQ_CMD]);
+
+err_out_async:
+	mthca_free_eq(dev, &dev->eq_table.eq[MTHCA_EQ_ASYNC]);
+
+err_out_comp:
+	mthca_free_eq(dev, &dev->eq_table.eq[MTHCA_EQ_COMP]);
+
+err_out_free:
+	mthca_alloc_cleanup(&dev->eq_table.alloc);
+	return err;
+}
+
+void __devexit mthca_cleanup_eq_table(struct mthca_dev *dev)
+{
+	u8 status;
+	int i;
+
+	mthca_free_irqs(dev);
+
+	mthca_MAP_EQ(dev, async_mask(dev),
+		     1, dev->eq_table.eq[MTHCA_EQ_ASYNC].eqn, &status);
+	mthca_MAP_EQ(dev, MTHCA_CMD_EVENT_MASK,
+		     1, dev->eq_table.eq[MTHCA_EQ_CMD].eqn, &status);
+
+	for (i = 0; i < MTHCA_NUM_EQ; ++i)
+		mthca_free_eq(dev, &dev->eq_table.eq[i]);
+
+	mthca_alloc_cleanup(&dev->eq_table.alloc);
+}
diff -Nru a/drivers/infiniband/hw/mthca/mthca_mad.c b/drivers/infiniband/hw/mthca/mthca_mad.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/infiniband/hw/mthca/mthca_mad.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,323 @@
+/*
+ * Copyright (c) 2004 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: mthca_mad.c 1349 2004-12-16 21:09:43Z roland $
+ */
+
+#include <ib_verbs.h>
+#include <ib_mad.h>
+#include <ib_smi.h>
+
+#include "mthca_dev.h"
+#include "mthca_cmd.h"
+
+enum {
+	MTHCA_VENDOR_CLASS1 = 0x9,
+	MTHCA_VENDOR_CLASS2 = 0xa
+};
+
+struct mthca_trap_mad {
+	struct ib_mad *mad;
+	DECLARE_PCI_UNMAP_ADDR(mapping)
+};
+
+static void update_sm_ah(struct mthca_dev *dev,
+			 u8 port_num, u16 lid, u8 sl)
+{
+	struct ib_ah *new_ah;
+	struct ib_ah_attr ah_attr;
+	unsigned long flags;
+
+	if (!dev->send_agent[port_num - 1][0])
+		return;
+
+	memset(&ah_attr, 0, sizeof ah_attr);
+	ah_attr.dlid     = lid;
+	ah_attr.sl       = sl;
+	ah_attr.port_num = port_num;
+
+	new_ah = ib_create_ah(dev->send_agent[port_num - 1][0]->qp->pd,
+			      &ah_attr);
+	if (IS_ERR(new_ah))
+		return;
+
+	spin_lock_irqsave(&dev->sm_lock, flags);
+	if (dev->sm_ah[port_num - 1])
+		ib_destroy_ah(dev->sm_ah[port_num - 1]);
+	dev->sm_ah[port_num - 1] = new_ah;
+	spin_unlock_irqrestore(&dev->sm_lock, flags);
+}
+
+/*
+ * Snoop SM MADs for port info and P_Key table sets, so we can
+ * synthesize LID change and P_Key change events.
+ */
+static void smp_snoop(struct ib_device *ibdev,
+		      u8 port_num,
+		      struct ib_mad *mad)
+{
+	struct ib_event event;
+
+	if ((mad->mad_hdr.mgmt_class  == IB_MGMT_CLASS_SUBN_LID_ROUTED ||
+	     mad->mad_hdr.mgmt_class  == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) &&
+	    mad->mad_hdr.method     == IB_MGMT_METHOD_SET) {
+		if (mad->mad_hdr.attr_id == IB_SMP_ATTR_PORT_INFO) {
+			update_sm_ah(to_mdev(ibdev), port_num,
+				     be16_to_cpup((__be16 *) (mad->data + 58)),
+				     (*(u8 *) (mad->data + 76)) & 0xf);
+
+			event.device           = ibdev;
+			event.event            = IB_EVENT_LID_CHANGE;
+			event.element.port_num = port_num;
+			ib_dispatch_event(&event);
+		}
+
+		if (mad->mad_hdr.attr_id == IB_SMP_ATTR_PKEY_TABLE) {
+			event.device           = ibdev;
+			event.event            = IB_EVENT_PKEY_CHANGE;
+			event.element.port_num = port_num;
+			ib_dispatch_event(&event);
+		}
+	}
+}
+
+static void forward_trap(struct mthca_dev *dev,
+			 u8 port_num,
+			 struct ib_mad *mad)
+{
+	int qpn = mad->mad_hdr.mgmt_class != IB_MGMT_CLASS_SUBN_LID_ROUTED;
+	struct mthca_trap_mad *tmad;
+	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,
+		.wr	     = {
+			 .ud = {
+				 .remote_qpn  = qpn,
+				 .remote_qkey = qpn ? IB_QP1_QKEY : 0,
+				 .timeout_ms  = 0
+			 }
+		 }
+	};
+	struct ib_mad_agent *agent = dev->send_agent[port_num - 1][qpn];
+	int ret;
+	unsigned long flags;
+
+	if (agent) {
+		tmad = kmalloc(sizeof *tmad, GFP_KERNEL);
+		if (!tmad)
+			return;
+
+		tmad->mad = kmalloc(sizeof *tmad->mad, GFP_KERNEL);
+		if (!tmad->mad) {
+			kfree(tmad);
+			return;
+		}
+
+		memcpy(tmad->mad, mad, sizeof *mad);
+
+		wr.wr.ud.mad_hdr = &tmad->mad->mad_hdr;
+		wr.wr_id         = (unsigned long) tmad;
+
+		gather_list.addr   = dma_map_single(agent->device->dma_device,
+						    tmad->mad,
+						    sizeof *tmad->mad,
+						    DMA_TO_DEVICE);
+		gather_list.length = sizeof *tmad->mad;
+		gather_list.lkey   = to_mpd(agent->qp->pd)->ntmr.ibmr.lkey;
+		pci_unmap_addr_set(tmad, mapping, gather_list.addr);
+
+		/*
+		 * We rely here on the fact that MLX QPs don't use the
+		 * address handle after the send is posted (this is
+		 * wrong following the IB spec strictly, but we know
+		 * it's OK for our devices).
+		 */
+		spin_lock_irqsave(&dev->sm_lock, flags);
+		wr.wr.ud.ah      = dev->sm_ah[port_num - 1];
+		if (wr.wr.ud.ah)
+			ret = ib_post_send_mad(agent, &wr, &bad_wr);
+		else
+			ret = -EINVAL;
+		spin_unlock_irqrestore(&dev->sm_lock, flags);
+
+		if (ret) {
+			dma_unmap_single(agent->device->dma_device,
+					 pci_unmap_addr(tmad, mapping),
+					 sizeof *tmad->mad,
+					 DMA_TO_DEVICE);
+			kfree(tmad->mad);
+			kfree(tmad);
+		}
+	}
+}
+
+int mthca_process_mad(struct ib_device *ibdev,
+		      int mad_flags,
+		      u8 port_num,
+		      struct ib_wc *in_wc,
+		      struct ib_grh *in_grh,
+		      struct ib_mad *in_mad,
+		      struct ib_mad *out_mad)
+{
+	int err;
+	u8 status;
+	u16 slid = in_wc ? in_wc->slid : IB_LID_PERMISSIVE;
+
+	/* Forward locally generated traps to the SM */
+	if (in_mad->mad_hdr.method == IB_MGMT_METHOD_TRAP &&
+	    slid == 0) {
+		forward_trap(to_mdev(ibdev), port_num, in_mad);
+		return IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_CONSUMED;
+	}
+
+	/*
+	 * Only handle SM gets, sets and trap represses for SM class
+	 *
+	 * Only handle PMA and Mellanox vendor-specific class gets and
+	 * sets for other classes.
+	 */
+	if (in_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_LID_ROUTED ||
+	    in_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) {
+		if (in_mad->mad_hdr.method   != IB_MGMT_METHOD_GET &&
+		    in_mad->mad_hdr.method   != IB_MGMT_METHOD_SET &&
+		    in_mad->mad_hdr.method   != IB_MGMT_METHOD_TRAP_REPRESS)
+			return IB_MAD_RESULT_SUCCESS;
+
+		/*
+		 * Don't process SMInfo queries or vendor-specific
+		 * MADs -- the SMA can't handle them.
+		 */
+		if (in_mad->mad_hdr.attr_id == IB_SMP_ATTR_SM_INFO ||
+		    ((in_mad->mad_hdr.attr_id & IB_SMP_ATTR_VENDOR_MASK) ==
+		     IB_SMP_ATTR_VENDOR_MASK))
+			return IB_MAD_RESULT_SUCCESS;
+	} else if (in_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_PERF_MGMT ||
+		   in_mad->mad_hdr.mgmt_class == MTHCA_VENDOR_CLASS1     ||
+		   in_mad->mad_hdr.mgmt_class == MTHCA_VENDOR_CLASS2) {
+		if (in_mad->mad_hdr.method  != IB_MGMT_METHOD_GET &&
+		    in_mad->mad_hdr.method  != IB_MGMT_METHOD_SET)
+			return IB_MAD_RESULT_SUCCESS;
+	} else
+		return IB_MAD_RESULT_SUCCESS;
+
+	err = mthca_MAD_IFC(to_mdev(ibdev),
+			    mad_flags & IB_MAD_IGNORE_MKEY,
+			    mad_flags & IB_MAD_IGNORE_BKEY,
+			    port_num, in_wc, in_grh, in_mad, out_mad,
+			    &status);
+	if (err) {
+		mthca_err(to_mdev(ibdev), "MAD_IFC failed\n");
+		return IB_MAD_RESULT_FAILURE;
+	}
+	if (status == MTHCA_CMD_STAT_BAD_PKT)
+		return IB_MAD_RESULT_SUCCESS;
+	if (status) {
+		mthca_err(to_mdev(ibdev), "MAD_IFC returned status %02x\n",
+			  status);
+		return IB_MAD_RESULT_FAILURE;
+	}
+
+	if (!out_mad->mad_hdr.status)
+		smp_snoop(ibdev, port_num, in_mad);
+
+	/* set return bit in status of directed route responses */
+	if (in_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE)
+		out_mad->mad_hdr.status |= cpu_to_be16(1 << 15);
+
+	if (in_mad->mad_hdr.method == IB_MGMT_METHOD_TRAP_REPRESS)
+		/* no response for trap repress */
+		return IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_CONSUMED;
+
+	return IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY;
+}
+
+static void send_handler(struct ib_mad_agent *agent,
+			 struct ib_mad_send_wc *mad_send_wc)
+{
+	struct mthca_trap_mad *tmad =
+		(void *) (unsigned long) mad_send_wc->wr_id;
+
+	dma_unmap_single(agent->device->dma_device,
+			 pci_unmap_addr(tmad, mapping),
+			 sizeof *tmad->mad,
+			 DMA_TO_DEVICE);
+	kfree(tmad->mad);
+	kfree(tmad);
+}
+
+int mthca_create_agents(struct mthca_dev *dev)
+{
+	struct ib_mad_agent *agent;
+	int p, q;
+
+	spin_lock_init(&dev->sm_lock);
+
+	for (p = 0; p < dev->limits.num_ports; ++p)
+		for (q = 0; q <= 1; ++q) {
+			agent = ib_register_mad_agent(&dev->ib_dev, p + 1,
+						      q ? IB_QPT_GSI : IB_QPT_SMI,
+						      NULL, 0, send_handler,
+						      NULL, NULL);
+			if (IS_ERR(agent))
+				goto err;
+			dev->send_agent[p][q] = agent;
+		}
+
+	return 0;
+
+err:
+	for (p = 0; p < dev->limits.num_ports; ++p)
+		for (q = 0; q <= 1; ++q)
+			if (dev->send_agent[p][q])
+				ib_unregister_mad_agent(dev->send_agent[p][q]);
+
+	return PTR_ERR(agent);
+}
+
+void mthca_free_agents(struct mthca_dev *dev)
+{
+	struct ib_mad_agent *agent;
+	int p, q;
+
+	for (p = 0; p < dev->limits.num_ports; ++p) {
+		for (q = 0; q <= 1; ++q) {
+			agent = dev->send_agent[p][q];
+			dev->send_agent[p][q] = NULL;
+			ib_unregister_mad_agent(agent);
+		}
+
+		if (dev->sm_ah[p])
+			ib_destroy_ah(dev->sm_ah[p]);
+	}
+}
diff -Nru a/drivers/infiniband/hw/mthca/mthca_main.c b/drivers/infiniband/hw/mthca/mthca_main.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/infiniband/hw/mthca/mthca_main.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,1126 @@
+/*
+ * Copyright (c) 2004, 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: mthca_main.c 1396 2004-12-28 04:10:27Z roland $
+ */
+
+#include <linux/config.h>
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+
+#include "mthca_dev.h"
+#include "mthca_config_reg.h"
+#include "mthca_cmd.h"
+#include "mthca_profile.h"
+#include "mthca_memfree.h"
+
+MODULE_AUTHOR("Roland Dreier");
+MODULE_DESCRIPTION("Mellanox InfiniBand HCA low-level driver");
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_VERSION(DRV_VERSION);
+
+#ifdef CONFIG_PCI_MSI
+
+static int msi_x = 0;
+module_param(msi_x, int, 0444);
+MODULE_PARM_DESC(msi_x, "attempt to use MSI-X if nonzero");
+
+static int msi = 0;
+module_param(msi, int, 0444);
+MODULE_PARM_DESC(msi, "attempt to use MSI if nonzero");
+
+#else /* CONFIG_PCI_MSI */
+
+#define msi_x (0)
+#define msi   (0)
+
+#endif /* CONFIG_PCI_MSI */
+
+static const char mthca_version[] __devinitdata =
+	"ib_mthca: Mellanox InfiniBand HCA driver v"
+	DRV_VERSION " (" DRV_RELDATE ")\n";
+
+static struct mthca_profile default_profile = {
+	.num_qp     = 1 << 16,
+	.rdb_per_qp = 4,
+	.num_cq     = 1 << 16,
+	.num_mcg    = 1 << 13,
+	.num_mpt    = 1 << 17,
+	.num_mtt    = 1 << 20,
+	.num_udav   = 1 << 15,	/* Tavor only */
+	.uarc_size  = 1 << 18,	/* Arbel only */
+};
+
+static int __devinit mthca_tune_pci(struct mthca_dev *mdev)
+{
+	int cap;
+	u16 val;
+
+	/* First try to max out Read Byte Count */
+	cap = pci_find_capability(mdev->pdev, PCI_CAP_ID_PCIX);
+	if (cap) {
+		if (pci_read_config_word(mdev->pdev, cap + PCI_X_CMD, &val)) {
+			mthca_err(mdev, "Couldn't read PCI-X command register, "
+				  "aborting.\n");
+			return -ENODEV;
+		}
+		val = (val & ~PCI_X_CMD_MAX_READ) | (3 << 2);
+		if (pci_write_config_word(mdev->pdev, cap + PCI_X_CMD, val)) {
+			mthca_err(mdev, "Couldn't write PCI-X command register, "
+				  "aborting.\n");
+			return -ENODEV;
+		}
+	} else if (mdev->hca_type == TAVOR)
+		mthca_info(mdev, "No PCI-X capability, not setting RBC.\n");
+
+	cap = pci_find_capability(mdev->pdev, PCI_CAP_ID_EXP);
+	if (cap) {
+		if (pci_read_config_word(mdev->pdev, cap + PCI_EXP_DEVCTL, &val)) {
+			mthca_err(mdev, "Couldn't read PCI Express device control "
+				  "register, aborting.\n");
+			return -ENODEV;
+		}
+		val = (val & ~PCI_EXP_DEVCTL_READRQ) | (5 << 12);
+		if (pci_write_config_word(mdev->pdev, cap + PCI_EXP_DEVCTL, val)) {
+			mthca_err(mdev, "Couldn't write PCI Express device control "
+				  "register, aborting.\n");
+			return -ENODEV;
+		}
+	} else if (mdev->hca_type == ARBEL_NATIVE ||
+		   mdev->hca_type == ARBEL_COMPAT)
+		mthca_info(mdev, "No PCI Express capability, "
+			   "not setting Max Read Request Size.\n");
+
+	return 0;
+}
+
+static int __devinit mthca_dev_lim(struct mthca_dev *mdev, struct mthca_dev_lim *dev_lim)
+{
+	int err;
+	u8 status;
+
+	err = mthca_QUERY_DEV_LIM(mdev, dev_lim, &status);
+	if (err) {
+		mthca_err(mdev, "QUERY_DEV_LIM command failed, aborting.\n");
+		return err;
+	}
+	if (status) {
+		mthca_err(mdev, "QUERY_DEV_LIM returned status 0x%02x, "
+			  "aborting.\n", status);
+		return -EINVAL;
+	}
+	if (dev_lim->min_page_sz > PAGE_SIZE) {
+		mthca_err(mdev, "HCA minimum page size of %d bigger than "
+			  "kernel PAGE_SIZE of %ld, aborting.\n",
+			  dev_lim->min_page_sz, PAGE_SIZE);
+		return -ENODEV;
+	}
+	if (dev_lim->num_ports > MTHCA_MAX_PORTS) {
+		mthca_err(mdev, "HCA has %d ports, but we only support %d, "
+			  "aborting.\n",
+			  dev_lim->num_ports, MTHCA_MAX_PORTS);
+		return -ENODEV;
+	}
+
+	mdev->limits.num_ports      	= dev_lim->num_ports;
+	mdev->limits.vl_cap             = dev_lim->max_vl;
+	mdev->limits.mtu_cap            = dev_lim->max_mtu;
+	mdev->limits.gid_table_len  	= dev_lim->max_gids;
+	mdev->limits.pkey_table_len 	= dev_lim->max_pkeys;
+	mdev->limits.local_ca_ack_delay = dev_lim->local_ca_ack_delay;
+	mdev->limits.max_sg             = dev_lim->max_sg;
+	mdev->limits.reserved_qps       = dev_lim->reserved_qps;
+	mdev->limits.reserved_srqs      = dev_lim->reserved_srqs;
+	mdev->limits.reserved_eecs      = dev_lim->reserved_eecs;
+	mdev->limits.reserved_cqs       = dev_lim->reserved_cqs;
+	mdev->limits.reserved_eqs       = dev_lim->reserved_eqs;
+	mdev->limits.reserved_mtts      = dev_lim->reserved_mtts;
+	mdev->limits.reserved_mrws      = dev_lim->reserved_mrws;
+	mdev->limits.reserved_uars      = dev_lim->reserved_uars;
+	mdev->limits.reserved_pds       = dev_lim->reserved_pds;
+
+	if (dev_lim->flags & DEV_LIM_FLAG_SRQ)
+		mdev->mthca_flags |= MTHCA_FLAG_SRQ;
+
+	return 0;
+}
+
+static int __devinit mthca_init_tavor(struct mthca_dev *mdev)
+{
+	u8 status;
+	int err;
+	struct mthca_dev_lim        dev_lim;
+	struct mthca_profile        profile;
+	struct mthca_init_hca_param init_hca;
+	struct mthca_adapter        adapter;
+
+	err = mthca_SYS_EN(mdev, &status);
+	if (err) {
+		mthca_err(mdev, "SYS_EN command failed, aborting.\n");
+		return err;
+	}
+	if (status) {
+		mthca_err(mdev, "SYS_EN returned status 0x%02x, "
+			  "aborting.\n", status);
+		return -EINVAL;
+	}
+
+	err = mthca_QUERY_FW(mdev, &status);
+	if (err) {
+		mthca_err(mdev, "QUERY_FW command failed, aborting.\n");
+		goto err_disable;
+	}
+	if (status) {
+		mthca_err(mdev, "QUERY_FW returned status 0x%02x, "
+			  "aborting.\n", status);
+		err = -EINVAL;
+		goto err_disable;
+	}
+	err = mthca_QUERY_DDR(mdev, &status);
+	if (err) {
+		mthca_err(mdev, "QUERY_DDR command failed, aborting.\n");
+		goto err_disable;
+	}
+	if (status) {
+		mthca_err(mdev, "QUERY_DDR returned status 0x%02x, "
+			  "aborting.\n", status);
+		err = -EINVAL;
+		goto err_disable;
+	}
+
+	err = mthca_dev_lim(mdev, &dev_lim);
+
+	profile = default_profile;
+	profile.num_uar   = dev_lim.uar_size / PAGE_SIZE;
+	profile.uarc_size = 0;
+
+	err = mthca_make_profile(mdev, &profile, &dev_lim, &init_hca);
+	if (err < 0)
+		goto err_disable;
+
+	err = mthca_INIT_HCA(mdev, &init_hca, &status);
+	if (err) {
+		mthca_err(mdev, "INIT_HCA command failed, aborting.\n");
+		goto err_disable;
+	}
+	if (status) {
+		mthca_err(mdev, "INIT_HCA returned status 0x%02x, "
+			  "aborting.\n", status);
+		err = -EINVAL;
+		goto err_disable;
+	}
+
+	err = mthca_QUERY_ADAPTER(mdev, &adapter, &status);
+	if (err) {
+		mthca_err(mdev, "QUERY_ADAPTER command failed, aborting.\n");
+		goto err_close;
+	}
+	if (status) {
+		mthca_err(mdev, "QUERY_ADAPTER returned status 0x%02x, "
+			  "aborting.\n", status);
+		err = -EINVAL;
+		goto err_close;
+	}
+
+	mdev->eq_table.inta_pin = adapter.inta_pin;
+	mdev->rev_id            = adapter.revision_id;
+
+	return 0;
+
+err_close:
+	mthca_CLOSE_HCA(mdev, 0, &status);
+
+err_disable:
+	mthca_SYS_DIS(mdev, &status);
+
+	return err;
+}
+
+static int __devinit mthca_load_fw(struct mthca_dev *mdev)
+{
+	u8 status;
+	int err;
+
+	/* FIXME: use HCA-attached memory for FW if present */
+
+	mdev->fw.arbel.fw_icm =
+		mthca_alloc_icm(mdev, mdev->fw.arbel.fw_pages,
+				GFP_HIGHUSER | __GFP_NOWARN);
+	if (!mdev->fw.arbel.fw_icm) {
+		mthca_err(mdev, "Couldn't allocate FW area, aborting.\n");
+		return -ENOMEM;
+	}
+
+	err = mthca_MAP_FA(mdev, mdev->fw.arbel.fw_icm, &status);
+	if (err) {
+		mthca_err(mdev, "MAP_FA command failed, aborting.\n");
+		goto err_free;
+	}
+	if (status) {
+		mthca_err(mdev, "MAP_FA returned status 0x%02x, aborting.\n", status);
+		err = -EINVAL;
+		goto err_free;
+	}
+	err = mthca_RUN_FW(mdev, &status);
+	if (err) {
+		mthca_err(mdev, "RUN_FW command failed, aborting.\n");
+		goto err_unmap_fa;
+	}
+	if (status) {
+		mthca_err(mdev, "RUN_FW returned status 0x%02x, aborting.\n", status);
+		err = -EINVAL;
+		goto err_unmap_fa;
+	}
+
+	return 0;
+
+err_unmap_fa:
+	mthca_UNMAP_FA(mdev, &status);
+
+err_free:
+	mthca_free_icm(mdev, mdev->fw.arbel.fw_icm);
+	return err;
+}
+
+static int __devinit mthca_init_icm(struct mthca_dev *mdev,
+				    struct mthca_dev_lim *dev_lim,
+				    struct mthca_init_hca_param *init_hca,
+				    u64 icm_size)
+{
+	u64 aux_pages;
+	u8 status;
+	int err;
+
+	err = mthca_SET_ICM_SIZE(mdev, icm_size, &aux_pages, &status);
+	if (err) {
+		mthca_err(mdev, "SET_ICM_SIZE command failed, aborting.\n");
+		return err;
+	}
+	if (status) {
+		mthca_err(mdev, "SET_ICM_SIZE returned status 0x%02x, "
+			  "aborting.\n", status);
+		return -EINVAL;
+	}
+
+	mthca_dbg(mdev, "%lld KB of HCA context requires %lld KB aux memory.\n",
+		  (unsigned long long) icm_size >> 10,
+		  (unsigned long long) aux_pages << 2);
+
+	mdev->fw.arbel.aux_icm = mthca_alloc_icm(mdev, aux_pages,
+						 GFP_HIGHUSER | __GFP_NOWARN);
+	if (!mdev->fw.arbel.aux_icm) {
+		mthca_err(mdev, "Couldn't allocate aux memory, aborting.\n");
+		return -ENOMEM;
+	}
+
+	err = mthca_MAP_ICM_AUX(mdev, mdev->fw.arbel.aux_icm, &status);
+	if (err) {
+		mthca_err(mdev, "MAP_ICM_AUX command failed, aborting.\n");
+		goto err_free_aux;
+	}
+	if (status) {
+		mthca_err(mdev, "MAP_ICM_AUX returned status 0x%02x, aborting.\n", status);
+		err = -EINVAL;
+		goto err_free_aux;
+	}
+
+	err = mthca_map_eq_icm(mdev, init_hca->eqc_base);
+	if (err) {
+		mthca_err(mdev, "Failed to map EQ context memory, aborting.\n");
+		goto err_unmap_aux;
+	}
+
+	mdev->mr_table.mtt_table = mthca_alloc_icm_table(mdev, init_hca->mtt_base,
+							 mdev->limits.num_mtt_segs *
+							 init_hca->mtt_seg_sz,
+							 mdev->limits.reserved_mtts *
+							 init_hca->mtt_seg_sz, 1);
+	if (!mdev->mr_table.mtt_table) {
+		mthca_err(mdev, "Failed to map MTT context memory, aborting.\n");
+		err = -ENOMEM;
+		goto err_unmap_eq;
+	}
+
+	mdev->mr_table.mpt_table = mthca_alloc_icm_table(mdev, init_hca->mpt_base,
+							 mdev->limits.num_mpts *
+							 dev_lim->mpt_entry_sz,
+							 mdev->limits.reserved_mrws *
+							 dev_lim->mpt_entry_sz, 1);
+	if (!mdev->mr_table.mpt_table) {
+		mthca_err(mdev, "Failed to map MPT context memory, aborting.\n");
+		err = -ENOMEM;
+		goto err_unmap_mtt;
+	}
+
+	mdev->qp_table.qp_table = mthca_alloc_icm_table(mdev, init_hca->qpc_base,
+							mdev->limits.num_qps *
+							dev_lim->qpc_entry_sz,
+							mdev->limits.reserved_qps *
+							dev_lim->qpc_entry_sz, 1);
+	if (!mdev->qp_table.qp_table) {
+		mthca_err(mdev, "Failed to map QP context memory, aborting.\n");
+		err = -ENOMEM;
+		goto err_unmap_mpt;
+	}
+
+	mdev->qp_table.eqp_table = mthca_alloc_icm_table(mdev, init_hca->eqpc_base,
+							 mdev->limits.num_qps *
+							 dev_lim->eqpc_entry_sz,
+							 mdev->limits.reserved_qps *
+							 dev_lim->eqpc_entry_sz, 1);
+	if (!mdev->qp_table.eqp_table) {
+		mthca_err(mdev, "Failed to map EQP context memory, aborting.\n");
+		err = -ENOMEM;
+		goto err_unmap_qp;
+	}
+
+	mdev->cq_table.table = mthca_alloc_icm_table(mdev, init_hca->cqc_base,
+						     mdev->limits.num_cqs *
+						     dev_lim->cqc_entry_sz,
+						     mdev->limits.reserved_cqs *
+						     dev_lim->cqc_entry_sz, 1);
+	if (!mdev->cq_table.table) {
+		mthca_err(mdev, "Failed to map CQ context memory, aborting.\n");
+		err = -ENOMEM;
+		goto err_unmap_eqp;
+	}
+
+	return 0;
+
+err_unmap_eqp:
+	mthca_free_icm_table(mdev, mdev->qp_table.eqp_table);
+
+err_unmap_qp:
+	mthca_free_icm_table(mdev, mdev->qp_table.qp_table);
+
+err_unmap_mpt:
+	mthca_free_icm_table(mdev, mdev->mr_table.mpt_table);
+
+err_unmap_mtt:
+	mthca_free_icm_table(mdev, mdev->mr_table.mtt_table);
+
+err_unmap_eq:
+	mthca_unmap_eq_icm(mdev);
+
+err_unmap_aux:
+	mthca_UNMAP_ICM_AUX(mdev, &status);
+
+err_free_aux:
+	mthca_free_icm(mdev, mdev->fw.arbel.aux_icm);
+
+	return err;
+}
+
+static int __devinit mthca_init_arbel(struct mthca_dev *mdev)
+{
+	struct mthca_dev_lim        dev_lim;
+	struct mthca_profile        profile;
+	struct mthca_init_hca_param init_hca;
+	struct mthca_adapter        adapter;
+	u64 icm_size;
+	u8 status;
+	int err;
+
+	err = mthca_QUERY_FW(mdev, &status);
+	if (err) {
+		mthca_err(mdev, "QUERY_FW command failed, aborting.\n");
+		return err;
+	}
+	if (status) {
+		mthca_err(mdev, "QUERY_FW returned status 0x%02x, "
+			  "aborting.\n", status);
+		return -EINVAL;
+	}
+
+	err = mthca_ENABLE_LAM(mdev, &status);
+	if (err) {
+		mthca_err(mdev, "ENABLE_LAM command failed, aborting.\n");
+		return err;
+	}
+	if (status == MTHCA_CMD_STAT_LAM_NOT_PRE) {
+		mthca_dbg(mdev, "No HCA-attached memory (running in MemFree mode)\n");
+		mdev->mthca_flags |= MTHCA_FLAG_NO_LAM;
+	} else if (status) {
+		mthca_err(mdev, "ENABLE_LAM returned status 0x%02x, "
+			  "aborting.\n", status);
+		return -EINVAL;
+	}
+
+	err = mthca_load_fw(mdev);
+	if (err) {
+		mthca_err(mdev, "Failed to start FW, aborting.\n");
+		goto err_disable;
+	}
+
+	err = mthca_dev_lim(mdev, &dev_lim);
+	if (err) {
+		mthca_err(mdev, "QUERY_DEV_LIM command failed, aborting.\n");
+		goto err_stop_fw;
+	}
+
+	profile = default_profile;
+	profile.num_uar  = dev_lim.uar_size / PAGE_SIZE;
+	profile.num_udav = 0;
+
+	icm_size = mthca_make_profile(mdev, &profile, &dev_lim, &init_hca);
+	if ((int) icm_size < 0) {
+		err = icm_size;
+		goto err_stop_fw;
+	}
+
+	err = mthca_init_icm(mdev, &dev_lim, &init_hca, icm_size);
+	if (err)
+		goto err_stop_fw;
+
+	err = mthca_INIT_HCA(mdev, &init_hca, &status);
+	if (err) {
+		mthca_err(mdev, "INIT_HCA command failed, aborting.\n");
+		goto err_free_icm;
+	}
+	if (status) {
+		mthca_err(mdev, "INIT_HCA returned status 0x%02x, "
+			  "aborting.\n", status);
+		err = -EINVAL;
+		goto err_free_icm;
+	}
+
+	err = mthca_QUERY_ADAPTER(mdev, &adapter, &status);
+	if (err) {
+		mthca_err(mdev, "QUERY_ADAPTER command failed, aborting.\n");
+		goto err_free_icm;
+	}
+	if (status) {
+		mthca_err(mdev, "QUERY_ADAPTER returned status 0x%02x, "
+			  "aborting.\n", status);
+		err = -EINVAL;
+		goto err_free_icm;
+	}
+
+	mdev->eq_table.inta_pin = adapter.inta_pin;
+	mdev->rev_id            = adapter.revision_id;
+
+	return 0;
+
+err_free_icm:
+	mthca_free_icm_table(mdev, mdev->cq_table.table);
+	mthca_free_icm_table(mdev, mdev->qp_table.eqp_table);
+	mthca_free_icm_table(mdev, mdev->qp_table.qp_table);
+	mthca_free_icm_table(mdev, mdev->mr_table.mpt_table);
+	mthca_free_icm_table(mdev, mdev->mr_table.mtt_table);
+	mthca_unmap_eq_icm(mdev);
+
+	mthca_UNMAP_ICM_AUX(mdev, &status);
+	mthca_free_icm(mdev, mdev->fw.arbel.aux_icm);
+
+err_stop_fw:
+	mthca_UNMAP_FA(mdev, &status);
+	mthca_free_icm(mdev, mdev->fw.arbel.fw_icm);
+
+err_disable:
+	if (!(mdev->mthca_flags & MTHCA_FLAG_NO_LAM))
+		mthca_DISABLE_LAM(mdev, &status);
+
+	return err;
+}
+
+static int __devinit mthca_init_hca(struct mthca_dev *mdev)
+{
+	if (mdev->hca_type == ARBEL_NATIVE)
+		return mthca_init_arbel(mdev);
+	else
+		return mthca_init_tavor(mdev);
+}
+
+static int __devinit mthca_setup_hca(struct mthca_dev *dev)
+{
+	int err;
+	u8 status;
+
+	MTHCA_INIT_DOORBELL_LOCK(&dev->doorbell_lock);
+
+	err = mthca_init_pd_table(dev);
+	if (err) {
+		mthca_err(dev, "Failed to initialize "
+			  "protection domain table, aborting.\n");
+		return err;
+	}
+
+	err = mthca_init_mr_table(dev);
+	if (err) {
+		mthca_err(dev, "Failed to initialize "
+			  "memory region table, aborting.\n");
+		goto err_pd_table_free;
+	}
+
+	err = mthca_pd_alloc(dev, &dev->driver_pd);
+	if (err) {
+		mthca_err(dev, "Failed to create driver PD, "
+			  "aborting.\n");
+		goto err_mr_table_free;
+	}
+
+	if (dev->hca_type == ARBEL_NATIVE) {
+		mthca_warn(dev, "Sorry, native MT25208 mode support is not done, "
+			   "aborting.\n");
+		err = -ENODEV;
+		goto err_pd_free;
+	}
+
+	err = mthca_init_eq_table(dev);
+	if (err) {
+		mthca_err(dev, "Failed to initialize "
+			  "event queue table, aborting.\n");
+		goto err_pd_free;
+	}
+
+	err = mthca_cmd_use_events(dev);
+	if (err) {
+		mthca_err(dev, "Failed to switch to event-driven "
+			  "firmware commands, aborting.\n");
+		goto err_eq_table_free;
+	}
+
+	err = mthca_NOP(dev, &status);
+	if (err || status) {
+		mthca_err(dev, "NOP command failed to generate interrupt, aborting.\n");
+		if (dev->mthca_flags & (MTHCA_FLAG_MSI | MTHCA_FLAG_MSI_X))
+			mthca_err(dev, "Try again with MSI/MSI-X disabled.\n");
+		else
+			mthca_err(dev, "BIOS or ACPI interrupt routing problem?\n");
+
+		goto err_cmd_poll;
+	} else
+		mthca_dbg(dev, "NOP command IRQ test passed\n");
+
+	err = mthca_init_cq_table(dev);
+	if (err) {
+		mthca_err(dev, "Failed to initialize "
+			  "completion queue table, aborting.\n");
+		goto err_cmd_poll;
+	}
+
+	err = mthca_init_qp_table(dev);
+	if (err) {
+		mthca_err(dev, "Failed to initialize "
+			  "queue pair table, aborting.\n");
+		goto err_cq_table_free;
+	}
+
+	err = mthca_init_av_table(dev);
+	if (err) {
+		mthca_err(dev, "Failed to initialize "
+			  "address vector table, aborting.\n");
+		goto err_qp_table_free;
+	}
+
+	err = mthca_init_mcg_table(dev);
+	if (err) {
+		mthca_err(dev, "Failed to initialize "
+			  "multicast group table, aborting.\n");
+		goto err_av_table_free;
+	}
+
+	return 0;
+
+err_av_table_free:
+	mthca_cleanup_av_table(dev);
+
+err_qp_table_free:
+	mthca_cleanup_qp_table(dev);
+
+err_cq_table_free:
+	mthca_cleanup_cq_table(dev);
+
+err_cmd_poll:
+	mthca_cmd_use_polling(dev);
+
+err_eq_table_free:
+	mthca_cleanup_eq_table(dev);
+
+err_pd_free:
+	mthca_pd_free(dev, &dev->driver_pd);
+
+err_mr_table_free:
+	mthca_cleanup_mr_table(dev);
+
+err_pd_table_free:
+	mthca_cleanup_pd_table(dev);
+	return err;
+}
+
+static int __devinit mthca_request_regions(struct pci_dev *pdev,
+					   int ddr_hidden)
+{
+	int err;
+
+	/*
+	 * We request our first BAR in two chunks, since the MSI-X
+	 * vector table is right in the middle.
+	 *
+	 * This is why we can't just use pci_request_regions() -- if
+	 * we did then setting up MSI-X would fail, since the PCI core
+	 * wants to do request_mem_region on the MSI-X vector table.
+	 */
+	if (!request_mem_region(pci_resource_start(pdev, 0) +
+				MTHCA_HCR_BASE,
+				MTHCA_HCR_SIZE,
+				DRV_NAME)) {
+		err = -EBUSY;
+		goto err_hcr_failed;
+	}
+
+	if (!request_mem_region(pci_resource_start(pdev, 0) +
+				MTHCA_ECR_BASE,
+				MTHCA_MAP_ECR_SIZE,
+				DRV_NAME)) {
+		err = -EBUSY;
+		goto err_ecr_failed;
+	}
+
+	if (!request_mem_region(pci_resource_start(pdev, 0) +
+				MTHCA_CLR_INT_BASE,
+				MTHCA_CLR_INT_SIZE,
+				DRV_NAME)) {
+		err = -EBUSY;
+		goto err_int_failed;
+	}
+
+
+	err = pci_request_region(pdev, 2, DRV_NAME);
+	if (err)
+		goto err_bar2_failed;
+
+	if (!ddr_hidden) {
+		err = pci_request_region(pdev, 4, DRV_NAME);
+		if (err)
+			goto err_bar4_failed;
+	}
+
+	return 0;
+
+err_bar4_failed:
+
+	pci_release_region(pdev, 2);
+err_bar2_failed:
+
+	release_mem_region(pci_resource_start(pdev, 0) +
+			   MTHCA_CLR_INT_BASE,
+			   MTHCA_CLR_INT_SIZE);
+err_int_failed:
+
+	release_mem_region(pci_resource_start(pdev, 0) +
+			   MTHCA_ECR_BASE,
+			   MTHCA_MAP_ECR_SIZE);
+err_ecr_failed:
+
+	release_mem_region(pci_resource_start(pdev, 0) +
+			   MTHCA_HCR_BASE,
+			   MTHCA_HCR_SIZE);
+err_hcr_failed:
+
+	return err;
+}
+
+static void mthca_release_regions(struct pci_dev *pdev,
+				  int ddr_hidden)
+{
+	if (!ddr_hidden)
+		pci_release_region(pdev, 4);
+
+	pci_release_region(pdev, 2);
+
+	release_mem_region(pci_resource_start(pdev, 0) +
+			   MTHCA_CLR_INT_BASE,
+			   MTHCA_CLR_INT_SIZE);
+
+	release_mem_region(pci_resource_start(pdev, 0) +
+			   MTHCA_ECR_BASE,
+			   MTHCA_MAP_ECR_SIZE);
+
+	release_mem_region(pci_resource_start(pdev, 0) +
+			   MTHCA_HCR_BASE,
+			   MTHCA_HCR_SIZE);
+}
+
+static int __devinit mthca_enable_msi_x(struct mthca_dev *mdev)
+{
+	struct msix_entry entries[3];
+	int err;
+
+	entries[0].entry = 0;
+	entries[1].entry = 1;
+	entries[2].entry = 2;
+
+	err = pci_enable_msix(mdev->pdev, entries, ARRAY_SIZE(entries));
+	if (err) {
+		if (err > 0)
+			mthca_info(mdev, "Only %d MSI-X vectors available, "
+				   "not using MSI-X\n", err);
+		return err;
+	}
+
+	mdev->eq_table.eq[MTHCA_EQ_COMP ].msi_x_vector = entries[0].vector;
+	mdev->eq_table.eq[MTHCA_EQ_ASYNC].msi_x_vector = entries[1].vector;
+	mdev->eq_table.eq[MTHCA_EQ_CMD  ].msi_x_vector = entries[2].vector;
+
+	return 0;
+}
+
+static void mthca_close_hca(struct mthca_dev *mdev)
+{
+	u8 status;
+
+	mthca_CLOSE_HCA(mdev, 0, &status);
+
+	if (mdev->hca_type == ARBEL_NATIVE) {
+		mthca_free_icm_table(mdev, mdev->cq_table.table);
+		mthca_free_icm_table(mdev, mdev->qp_table.eqp_table);
+		mthca_free_icm_table(mdev, mdev->qp_table.qp_table);
+		mthca_free_icm_table(mdev, mdev->mr_table.mpt_table);
+		mthca_free_icm_table(mdev, mdev->mr_table.mtt_table);
+		mthca_unmap_eq_icm(mdev);
+
+		mthca_UNMAP_ICM_AUX(mdev, &status);
+		mthca_free_icm(mdev, mdev->fw.arbel.aux_icm);
+
+		mthca_UNMAP_FA(mdev, &status);
+		mthca_free_icm(mdev, mdev->fw.arbel.fw_icm);
+
+		if (!(mdev->mthca_flags & MTHCA_FLAG_NO_LAM))
+			mthca_DISABLE_LAM(mdev, &status);
+	} else
+		mthca_SYS_DIS(mdev, &status);
+}
+
+static int __devinit mthca_init_one(struct pci_dev *pdev,
+				    const struct pci_device_id *id)
+{
+	static int mthca_version_printed = 0;
+	int ddr_hidden = 0;
+	int err;
+	unsigned long mthca_base;
+	struct mthca_dev *mdev;
+
+	if (!mthca_version_printed) {
+		printk(KERN_INFO "%s", mthca_version);
+		++mthca_version_printed;
+	}
+
+	printk(KERN_INFO PFX "Initializing %s (%s)\n",
+	       pci_pretty_name(pdev), pci_name(pdev));
+
+	err = pci_enable_device(pdev);
+	if (err) {
+		dev_err(&pdev->dev, "Cannot enable PCI device, "
+			"aborting.\n");
+		return err;
+	}
+
+	/*
+	 * Check for BARs.  We expect 0: 1MB, 2: 8MB, 4: DDR (may not
+	 * be present)
+	 */
+	if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM) ||
+	    pci_resource_len(pdev, 0) != 1 << 20) {
+		dev_err(&pdev->dev, "Missing DCS, aborting.");
+		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.");
+		err = -ENODEV;
+		goto err_disable_pdev;
+	}
+	if (!(pci_resource_flags(pdev, 4) & IORESOURCE_MEM))
+		ddr_hidden = 1;
+
+	err = mthca_request_regions(pdev, ddr_hidden);
+	if (err) {
+		dev_err(&pdev->dev, "Cannot obtain PCI resources, "
+			"aborting.\n");
+		goto err_disable_pdev;
+	}
+
+	pci_set_master(pdev);
+
+	err = pci_set_dma_mask(pdev, DMA_64BIT_MASK);
+	if (err) {
+		dev_warn(&pdev->dev, "Warning: couldn't set 64-bit PCI DMA mask.\n");
+		err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+		if (err) {
+			dev_err(&pdev->dev, "Can't set PCI DMA mask, aborting.\n");
+			goto err_free_res;
+		}
+	}
+	err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
+	if (err) {
+		dev_warn(&pdev->dev, "Warning: couldn't set 64-bit "
+			 "consistent PCI DMA mask.\n");
+		err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+		if (err) {
+			dev_err(&pdev->dev, "Can't set consistent PCI DMA mask, "
+				"aborting.\n");
+			goto err_free_res;
+		}
+	}
+
+	mdev = (struct mthca_dev *) ib_alloc_device(sizeof *mdev);
+	if (!mdev) {
+		dev_err(&pdev->dev, "Device struct alloc failed, "
+			"aborting.\n");
+		err = -ENOMEM;
+		goto err_free_res;
+	}
+
+	mdev->pdev     = pdev;
+	mdev->hca_type = id->driver_data;
+
+	if (ddr_hidden)
+		mdev->mthca_flags |= MTHCA_FLAG_DDR_HIDDEN;
+
+	/*
+	 * Now reset the HCA before we touch the PCI capabilities or
+	 * attempt a firmware command, since a boot ROM may have left
+	 * the HCA in an undefined state.
+	 */
+	err = mthca_reset(mdev);
+	if (err) {
+		mthca_err(mdev, "Failed to reset HCA, aborting.\n");
+		goto err_free_dev;
+	}
+
+	if (msi_x && !mthca_enable_msi_x(mdev))
+		mdev->mthca_flags |= MTHCA_FLAG_MSI_X;
+	if (msi && !(mdev->mthca_flags & MTHCA_FLAG_MSI_X) &&
+	    !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;
+
+	mthca_base = pci_resource_start(pdev, 0);
+	mdev->hcr = ioremap(mthca_base + MTHCA_HCR_BASE, MTHCA_HCR_SIZE);
+	if (!mdev->hcr) {
+		mthca_err(mdev, "Couldn't map command register, "
+			  "aborting.\n");
+		err = -ENOMEM;
+		goto err_free_dev;
+	}
+
+	mdev->clr_base = ioremap(mthca_base + MTHCA_CLR_INT_BASE,
+				 MTHCA_CLR_INT_SIZE);
+	if (!mdev->clr_base) {
+		mthca_err(mdev, "Couldn't map interrupt clear register, "
+			  "aborting.\n");
+		err = -ENOMEM;
+		goto err_iounmap;
+	}
+
+	mdev->ecr_base = ioremap(mthca_base + MTHCA_ECR_BASE,
+				 MTHCA_ECR_SIZE + MTHCA_ECR_CLR_SIZE);
+	if (!mdev->ecr_base) {
+		mthca_err(mdev, "Couldn't map ecr register, "
+			  "aborting.\n");
+		err = -ENOMEM;
+		goto err_iounmap_clr;
+	}
+
+	mthca_base = pci_resource_start(pdev, 2);
+	mdev->kar = ioremap(mthca_base + PAGE_SIZE * MTHCA_KAR_PAGE, PAGE_SIZE);
+	if (!mdev->kar) {
+		mthca_err(mdev, "Couldn't map kernel access region, "
+			  "aborting.\n");
+		err = -ENOMEM;
+		goto err_iounmap_ecr;
+	}
+
+	err = mthca_tune_pci(mdev);
+	if (err)
+		goto err_iounmap_kar;
+
+	err = mthca_init_hca(mdev);
+	if (err)
+		goto err_iounmap_kar;
+
+	err = mthca_setup_hca(mdev);
+	if (err)
+		goto err_close;
+
+	err = mthca_register_device(mdev);
+	if (err)
+		goto err_cleanup;
+
+	err = mthca_create_agents(mdev);
+	if (err)
+		goto err_unregister;
+
+	pci_set_drvdata(pdev, mdev);
+
+	return 0;
+
+err_unregister:
+	mthca_unregister_device(mdev);
+
+err_cleanup:
+	mthca_cleanup_mcg_table(mdev);
+	mthca_cleanup_av_table(mdev);
+	mthca_cleanup_qp_table(mdev);
+	mthca_cleanup_cq_table(mdev);
+	mthca_cmd_use_polling(mdev);
+	mthca_cleanup_eq_table(mdev);
+
+	mthca_pd_free(mdev, &mdev->driver_pd);
+
+	mthca_cleanup_mr_table(mdev);
+	mthca_cleanup_pd_table(mdev);
+
+err_close:
+	mthca_close_hca(mdev);
+
+err_iounmap_kar:
+	iounmap(mdev->kar);
+
+err_iounmap_ecr:
+	iounmap(mdev->ecr_base);
+
+err_iounmap_clr:
+	iounmap(mdev->clr_base);
+
+err_iounmap:
+	iounmap(mdev->hcr);
+
+err_free_dev:
+	if (mdev->mthca_flags & MTHCA_FLAG_MSI_X)
+		pci_disable_msix(pdev);
+	if (mdev->mthca_flags & MTHCA_FLAG_MSI)
+		pci_disable_msi(pdev);
+
+	ib_dealloc_device(&mdev->ib_dev);
+
+err_free_res:
+	mthca_release_regions(pdev, ddr_hidden);
+
+err_disable_pdev:
+	pci_disable_device(pdev);
+	pci_set_drvdata(pdev, NULL);
+	return err;
+}
+
+static void __devexit mthca_remove_one(struct pci_dev *pdev)
+{
+	struct mthca_dev *mdev = pci_get_drvdata(pdev);
+	u8 status;
+	int p;
+
+	if (mdev) {
+		mthca_free_agents(mdev);
+		mthca_unregister_device(mdev);
+
+		for (p = 1; p <= mdev->limits.num_ports; ++p)
+			mthca_CLOSE_IB(mdev, p, &status);
+
+		mthca_cleanup_mcg_table(mdev);
+		mthca_cleanup_av_table(mdev);
+		mthca_cleanup_qp_table(mdev);
+		mthca_cleanup_cq_table(mdev);
+		mthca_cmd_use_polling(mdev);
+		mthca_cleanup_eq_table(mdev);
+
+		mthca_pd_free(mdev, &mdev->driver_pd);
+
+		mthca_cleanup_mr_table(mdev);
+		mthca_cleanup_pd_table(mdev);
+
+		mthca_close_hca(mdev);
+
+		iounmap(mdev->hcr);
+		iounmap(mdev->ecr_base);
+		iounmap(mdev->clr_base);
+
+		if (mdev->mthca_flags & MTHCA_FLAG_MSI_X)
+			pci_disable_msix(pdev);
+		if (mdev->mthca_flags & MTHCA_FLAG_MSI)
+			pci_disable_msi(pdev);
+
+		ib_dealloc_device(&mdev->ib_dev);
+		mthca_release_regions(pdev, mdev->mthca_flags &
+				      MTHCA_FLAG_DDR_HIDDEN);
+		pci_disable_device(pdev);
+		pci_set_drvdata(pdev, NULL);
+	}
+}
+
+static struct pci_device_id mthca_pci_table[] = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_MELLANOX, PCI_DEVICE_ID_MELLANOX_TAVOR),
+	  .driver_data = TAVOR },
+	{ PCI_DEVICE(PCI_VENDOR_ID_TOPSPIN, PCI_DEVICE_ID_MELLANOX_TAVOR),
+	  .driver_data = TAVOR },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MELLANOX, PCI_DEVICE_ID_MELLANOX_ARBEL_COMPAT),
+	  .driver_data = ARBEL_COMPAT },
+	{ PCI_DEVICE(PCI_VENDOR_ID_TOPSPIN, PCI_DEVICE_ID_MELLANOX_ARBEL_COMPAT),
+	  .driver_data = ARBEL_COMPAT },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MELLANOX, PCI_DEVICE_ID_MELLANOX_ARBEL),
+	  .driver_data = ARBEL_NATIVE },
+	{ PCI_DEVICE(PCI_VENDOR_ID_TOPSPIN, PCI_DEVICE_ID_MELLANOX_ARBEL),
+	  .driver_data = ARBEL_NATIVE },
+	{ 0, }
+};
+
+MODULE_DEVICE_TABLE(pci, mthca_pci_table);
+
+static struct pci_driver mthca_driver = {
+	.name		= "ib_mthca",
+	.id_table	= mthca_pci_table,
+	.probe		= mthca_init_one,
+	.remove		= __devexit_p(mthca_remove_one)
+};
+
+static int __init mthca_init(void)
+{
+	int ret;
+
+	ret = pci_register_driver(&mthca_driver);
+	return ret < 0 ? ret : 0;
+}
+
+static void __exit mthca_cleanup(void)
+{
+	pci_unregister_driver(&mthca_driver);
+}
+
+module_init(mthca_init);
+module_exit(mthca_cleanup);
diff -Nru a/drivers/infiniband/hw/mthca/mthca_mcg.c b/drivers/infiniband/hw/mthca/mthca_mcg.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/infiniband/hw/mthca/mthca_mcg.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,376 @@
+/*
+ * Copyright (c) 2004 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: mthca_mcg.c 1349 2004-12-16 21:09:43Z roland $
+ */
+
+#include <linux/init.h>
+
+#include "mthca_dev.h"
+#include "mthca_cmd.h"
+
+enum {
+	MTHCA_QP_PER_MGM = 4 * (MTHCA_MGM_ENTRY_SIZE / 16 - 2)
+};
+
+struct mthca_mgm {
+	u32 next_gid_index;
+	u32 reserved[3];
+	u8  gid[16];
+	u32 qp[MTHCA_QP_PER_MGM];
+};
+
+static const u8 zero_gid[16];	/* automatically initialized to 0 */
+
+/*
+ * Caller must hold MCG table semaphore.  gid and mgm parameters must
+ * be properly aligned for command interface.
+ *
+ *  Returns 0 unless a firmware command error occurs.
+ *
+ * If GID is found in MGM or MGM is empty, *index = *hash, *prev = -1
+ * and *mgm holds MGM entry.
+ *
+ * if GID is found in AMGM, *index = index in AMGM, *prev = index of
+ * previous entry in hash chain and *mgm holds AMGM entry.
+ *
+ * If no AMGM exists for given gid, *index = -1, *prev = index of last
+ * 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,
+		    u16 *hash, int *prev, int *index)
+{
+	void *mailbox;
+	u8 *mgid;
+	int err;
+	u8 status;
+
+	mailbox = kmalloc(16 + MTHCA_CMD_MAILBOX_EXTRA, GFP_KERNEL);
+	if (!mailbox)
+		return -ENOMEM;
+	mgid = MAILBOX_ALIGN(mailbox);
+
+	memcpy(mgid, gid, 16);
+
+	err = mthca_MGID_HASH(dev, mgid, hash, &status);
+	if (err)
+		goto out;
+	if (status) {
+		mthca_err(dev, "MGID_HASH returned status %02x\n", status);
+		err = -EINVAL;
+		goto out;
+	}
+
+	if (0)
+		mthca_dbg(dev, "Hash for %04x:%04x:%04x:%04x:"
+			  "%04x:%04x:%04x:%04x is %04x\n",
+			  be16_to_cpu(((u16 *) gid)[0]), be16_to_cpu(((u16 *) gid)[1]),
+			  be16_to_cpu(((u16 *) gid)[2]), be16_to_cpu(((u16 *) gid)[3]),
+			  be16_to_cpu(((u16 *) gid)[4]), be16_to_cpu(((u16 *) gid)[5]),
+			  be16_to_cpu(((u16 *) gid)[6]), be16_to_cpu(((u16 *) gid)[7]),
+			  *hash);
+
+	*index = *hash;
+	*prev  = -1;
+
+	do {
+		err = mthca_READ_MGM(dev, *index, mgm, &status);
+		if (err)
+			goto out;
+		if (status) {
+			mthca_err(dev, "READ_MGM returned status %02x\n", status);
+			return -EINVAL;
+		}
+
+		if (!memcmp(mgm->gid, zero_gid, 16)) {
+			if (*index != *hash) {
+				mthca_err(dev, "Found zero MGID in AMGM.\n");
+				err = -EINVAL;
+			}
+			goto out;
+		}
+
+		if (!memcmp(mgm->gid, gid, 16))
+			goto out;
+
+		*prev = *index;
+		*index = be32_to_cpu(mgm->next_gid_index) >> 5;
+	} while (*index);
+
+	*index = -1;
+
+ out:
+	kfree(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_mgm *mgm;
+	u16 hash;
+	int index, prev;
+	int link = 0;
+	int i;
+	int err;
+	u8 status;
+
+	mailbox = kmalloc(sizeof *mgm + MTHCA_CMD_MAILBOX_EXTRA, GFP_KERNEL);
+	if (!mailbox)
+		return -ENOMEM;
+	mgm = MAILBOX_ALIGN(mailbox);
+
+	if (down_interruptible(&dev->mcg_table.sem))
+		return -EINTR;
+
+	err = find_mgm(dev, gid->raw, mgm, &hash, &prev, &index);
+	if (err)
+		goto out;
+
+	if (index != -1) {
+		if (!memcmp(mgm->gid, zero_gid, 16))
+			memcpy(mgm->gid, gid->raw, 16);
+	} else {
+		link = 1;
+
+		index = mthca_alloc(&dev->mcg_table.alloc);
+		if (index == -1) {
+			mthca_err(dev, "No AMGM entries left\n");
+			err = -ENOMEM;
+			goto out;
+		}
+
+		err = mthca_READ_MGM(dev, index, mgm, &status);
+		if (err)
+			goto out;
+		if (status) {
+			mthca_err(dev, "READ_MGM returned status %02x\n", status);
+			err = -EINVAL;
+			goto out;
+		}
+
+		memcpy(mgm->gid, gid->raw, 16);
+		mgm->next_gid_index = 0;
+	}
+
+	for (i = 0; i < MTHCA_QP_PER_MGM; ++i)
+		if (!(mgm->qp[i] & cpu_to_be32(1 << 31))) {
+			mgm->qp[i] = cpu_to_be32(ibqp->qp_num | (1 << 31));
+			break;
+		}
+
+	if (i == MTHCA_QP_PER_MGM) {
+		mthca_err(dev, "MGM at index %x is full.\n", index);
+		err = -ENOMEM;
+		goto out;
+	}
+
+	err = mthca_WRITE_MGM(dev, index, mgm, &status);
+	if (err)
+		goto out;
+	if (status) {
+		mthca_err(dev, "WRITE_MGM returned status %02x\n", status);
+		err = -EINVAL;
+	}
+
+	if (!link)
+		goto out;
+
+	err = mthca_READ_MGM(dev, prev, mgm, &status);
+	if (err)
+		goto out;
+	if (status) {
+		mthca_err(dev, "READ_MGM returned status %02x\n", status);
+		err = -EINVAL;
+		goto out;
+	}
+
+	mgm->next_gid_index = cpu_to_be32(index << 5);
+
+	err = mthca_WRITE_MGM(dev, prev, mgm, &status);
+	if (err)
+		goto out;
+	if (status) {
+		mthca_err(dev, "WRITE_MGM returned status %02x\n", status);
+		err = -EINVAL;
+	}
+
+ out:
+	up(&dev->mcg_table.sem);
+	kfree(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_mgm *mgm;
+	u16 hash;
+	int prev, index;
+	int i, loc;
+	int err;
+	u8 status;
+
+	mailbox = kmalloc(sizeof *mgm + MTHCA_CMD_MAILBOX_EXTRA, GFP_KERNEL);
+	if (!mailbox)
+		return -ENOMEM;
+	mgm = MAILBOX_ALIGN(mailbox);
+
+	if (down_interruptible(&dev->mcg_table.sem))
+		return -EINTR;
+
+	err = find_mgm(dev, gid->raw, mgm, &hash, &prev, &index);
+	if (err)
+		goto out;
+
+	if (index == -1) {
+		mthca_err(dev, "MGID %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x "
+			  "not found\n",
+			  be16_to_cpu(((u16 *) gid->raw)[0]),
+			  be16_to_cpu(((u16 *) gid->raw)[1]),
+			  be16_to_cpu(((u16 *) gid->raw)[2]),
+			  be16_to_cpu(((u16 *) gid->raw)[3]),
+			  be16_to_cpu(((u16 *) gid->raw)[4]),
+			  be16_to_cpu(((u16 *) gid->raw)[5]),
+			  be16_to_cpu(((u16 *) gid->raw)[6]),
+			  be16_to_cpu(((u16 *) gid->raw)[7]));
+		err = -EINVAL;
+		goto out;
+	}
+
+	for (loc = -1, i = 0; i < MTHCA_QP_PER_MGM; ++i) {
+		if (mgm->qp[i] == cpu_to_be32(ibqp->qp_num | (1 << 31)))
+			loc = i;
+		if (!(mgm->qp[i] & cpu_to_be32(1 << 31)))
+			break;
+	}
+
+	if (loc == -1) {
+		mthca_err(dev, "QP %06x not found in MGM\n", ibqp->qp_num);
+		err = -EINVAL;
+		goto out;
+	}
+
+	mgm->qp[loc]   = mgm->qp[i - 1];
+	mgm->qp[i - 1] = 0;
+
+	err = mthca_WRITE_MGM(dev, index, mgm, &status);
+	if (err)
+		goto out;
+	if (status) {
+		mthca_err(dev, "WRITE_MGM returned status %02x\n", status);
+		err = -EINVAL;
+		goto out;
+	}
+
+	if (i != 1)
+		goto out;
+
+	goto out;
+
+	if (prev == -1) {
+		/* Remove entry from MGM */
+		if (be32_to_cpu(mgm->next_gid_index) >> 5) {
+			err = mthca_READ_MGM(dev,
+					     be32_to_cpu(mgm->next_gid_index) >> 5,
+					     mgm, &status);
+			if (err)
+				goto out;
+			if (status) {
+				mthca_err(dev, "READ_MGM returned status %02x\n",
+					  status);
+				err = -EINVAL;
+				goto out;
+			}
+		} else
+			memset(mgm->gid, 0, 16);
+
+		err = mthca_WRITE_MGM(dev, index, mgm, &status);
+		if (err)
+			goto out;
+		if (status) {
+			mthca_err(dev, "WRITE_MGM returned status %02x\n", status);
+			err = -EINVAL;
+			goto out;
+		}
+	} else {
+		/* Remove entry from AMGM */
+		index = be32_to_cpu(mgm->next_gid_index) >> 5;
+		err = mthca_READ_MGM(dev, prev, mgm, &status);
+		if (err)
+			goto out;
+		if (status) {
+			mthca_err(dev, "READ_MGM returned status %02x\n", status);
+			err = -EINVAL;
+			goto out;
+		}
+
+		mgm->next_gid_index = cpu_to_be32(index << 5);
+
+		err = mthca_WRITE_MGM(dev, prev, mgm, &status);
+		if (err)
+			goto out;
+		if (status) {
+			mthca_err(dev, "WRITE_MGM returned status %02x\n", status);
+			err = -EINVAL;
+			goto out;
+		}
+	}
+
+ out:
+	up(&dev->mcg_table.sem);
+	kfree(mailbox);
+	return err;
+}
+
+int __devinit mthca_init_mcg_table(struct mthca_dev *dev)
+{
+	int err;
+
+	err = mthca_alloc_init(&dev->mcg_table.alloc,
+			       dev->limits.num_amgms,
+			       dev->limits.num_amgms - 1,
+			       0);
+	if (err)
+		return err;
+
+	init_MUTEX(&dev->mcg_table.sem);
+
+	return 0;
+}
+
+void __devexit mthca_cleanup_mcg_table(struct mthca_dev *dev)
+{
+	mthca_alloc_cleanup(&dev->mcg_table.alloc);
+}
diff -Nru a/drivers/infiniband/hw/mthca/mthca_memfree.c b/drivers/infiniband/hw/mthca/mthca_memfree.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/infiniband/hw/mthca/mthca_memfree.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,206 @@
+/*
+ * Copyright (c) 2004, 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$
+ */
+
+#include "mthca_memfree.h"
+#include "mthca_dev.h"
+#include "mthca_cmd.h"
+
+/*
+ * We allocate in as big chunks as we can, up to a maximum of 256 KB
+ * per chunk.
+ */
+enum {
+	MTHCA_ICM_ALLOC_SIZE   = 1 << 18,
+	MTHCA_TABLE_CHUNK_SIZE = 1 << 18
+};
+
+void mthca_free_icm(struct mthca_dev *dev, struct mthca_icm *icm)
+{
+	struct mthca_icm_chunk *chunk, *tmp;
+	int i;
+
+	if (!icm)
+		return;
+
+	list_for_each_entry_safe(chunk, tmp, &icm->chunk_list, list) {
+		if (chunk->nsg > 0)
+			pci_unmap_sg(dev->pdev, chunk->mem, chunk->npages,
+				     PCI_DMA_BIDIRECTIONAL);
+
+		for (i = 0; i < chunk->npages; ++i)
+			__free_pages(chunk->mem[i].page,
+				     get_order(chunk->mem[i].length));
+
+		kfree(chunk);
+	}
+
+	kfree(icm);
+}
+
+struct mthca_icm *mthca_alloc_icm(struct mthca_dev *dev, int npages,
+				  unsigned int gfp_mask)
+{
+	struct mthca_icm *icm;
+	struct mthca_icm_chunk *chunk = NULL;
+	int cur_order;
+
+	icm = kmalloc(sizeof *icm, gfp_mask & ~(__GFP_HIGHMEM | __GFP_NOWARN));
+	if (!icm)
+		return icm;
+
+	INIT_LIST_HEAD(&icm->chunk_list);
+
+	cur_order = get_order(MTHCA_ICM_ALLOC_SIZE);
+
+	while (npages > 0) {
+		if (!chunk) {
+			chunk = kmalloc(sizeof *chunk,
+					gfp_mask & ~(__GFP_HIGHMEM | __GFP_NOWARN));
+			if (!chunk)
+				goto fail;
+
+			chunk->npages = 0;
+			chunk->nsg    = 0;
+			list_add_tail(&chunk->list, &icm->chunk_list);
+		}
+
+		while (1 << cur_order > npages)
+			--cur_order;
+
+		chunk->mem[chunk->npages].page = alloc_pages(gfp_mask, cur_order);
+		if (chunk->mem[chunk->npages].page) {
+			chunk->mem[chunk->npages].length = PAGE_SIZE << cur_order;
+			chunk->mem[chunk->npages].offset = 0;
+
+			if (++chunk->npages == MTHCA_ICM_CHUNK_LEN) {
+				chunk->nsg = pci_map_sg(dev->pdev, chunk->mem,
+							chunk->npages,
+							PCI_DMA_BIDIRECTIONAL);
+
+				if (chunk->nsg <= 0)
+					goto fail;
+
+				chunk = NULL;
+			}
+
+			npages -= 1 << cur_order;
+		} else {
+			--cur_order;
+			if (cur_order < 0)
+				goto fail;
+		}
+	}
+
+	if (chunk) {
+		chunk->nsg = pci_map_sg(dev->pdev, chunk->mem,
+					chunk->npages,
+					PCI_DMA_BIDIRECTIONAL);
+
+		if (chunk->nsg <= 0)
+			goto fail;
+	}
+
+	return icm;
+
+fail:
+	mthca_free_icm(dev, icm);
+	return NULL;
+}
+
+struct mthca_icm_table *mthca_alloc_icm_table(struct mthca_dev *dev,
+					      u64 virt, unsigned size,
+					      unsigned reserved,
+					      int use_lowmem)
+{
+	struct mthca_icm_table *table;
+	int num_icm;
+	int i;
+	u8 status;
+
+	num_icm = size / MTHCA_TABLE_CHUNK_SIZE;
+
+	table = kmalloc(sizeof *table + num_icm * sizeof *table->icm, GFP_KERNEL);
+	if (!table)
+		return NULL;
+
+	table->virt    = virt;
+	table->num_icm = num_icm;
+	init_MUTEX(&table->sem);
+
+	for (i = 0; i < num_icm; ++i)
+		table->icm[i] = NULL;
+
+	for (i = 0; i < (reserved + MTHCA_TABLE_CHUNK_SIZE - 1) / MTHCA_TABLE_CHUNK_SIZE; ++i) {
+		table->icm[i] = mthca_alloc_icm(dev, MTHCA_TABLE_CHUNK_SIZE >> PAGE_SHIFT,
+						(use_lowmem ? GFP_KERNEL : GFP_HIGHUSER) |
+						__GFP_NOWARN);
+		if (!table->icm[i])
+			goto err;
+		if (mthca_MAP_ICM(dev, table->icm[i], virt + i * MTHCA_TABLE_CHUNK_SIZE,
+				  &status) || status) {
+			mthca_free_icm(dev, table->icm[i]);
+			table->icm[i] = NULL;
+			goto err;
+		}
+	}
+
+	return table;
+
+err:
+	for (i = 0; i < num_icm; ++i)
+		if (table->icm[i]) {
+			mthca_UNMAP_ICM(dev, virt + i * MTHCA_TABLE_CHUNK_SIZE,
+					MTHCA_TABLE_CHUNK_SIZE >> 12, &status);
+			mthca_free_icm(dev, table->icm[i]);
+		}
+
+	kfree(table);
+
+	return NULL;
+}
+
+void mthca_free_icm_table(struct mthca_dev *dev, struct mthca_icm_table *table)
+{
+	int i;
+	u8 status;
+
+	for (i = 0; i < table->num_icm; ++i)
+		if (table->icm[i]) {
+			mthca_UNMAP_ICM(dev, table->virt + i * MTHCA_TABLE_CHUNK_SIZE,
+					MTHCA_TABLE_CHUNK_SIZE >> 12, &status);
+			mthca_free_icm(dev, table->icm[i]);
+		}
+
+	kfree(table);
+}
diff -Nru a/drivers/infiniband/hw/mthca/mthca_memfree.h b/drivers/infiniband/hw/mthca/mthca_memfree.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/infiniband/hw/mthca/mthca_memfree.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2004, 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$
+ */
+
+#ifndef MTHCA_MEMFREE_H
+#define MTHCA_MEMFREE_H
+
+#include <linux/list.h>
+#include <linux/pci.h>
+
+#include <asm/semaphore.h>
+
+#define MTHCA_ICM_CHUNK_LEN \
+	((256 - sizeof (struct list_head) - 2 * sizeof (int)) /		\
+	 (sizeof (struct scatterlist)))
+
+struct mthca_icm_chunk {
+	struct list_head   list;
+	int                npages;
+	int                nsg;
+	struct scatterlist mem[MTHCA_ICM_CHUNK_LEN];
+};
+
+struct mthca_icm {
+	struct list_head chunk_list;
+};
+
+struct mthca_icm_table {
+	u64               virt;
+	int               num_icm;
+	struct semaphore  sem;
+	struct mthca_icm *icm[0];
+};
+
+struct mthca_icm_iter {
+	struct mthca_icm       *icm;
+	struct mthca_icm_chunk *chunk;
+	int                     page_idx;
+};
+
+struct mthca_dev;
+
+struct mthca_icm *mthca_alloc_icm(struct mthca_dev *dev, int npages,
+				  unsigned int gfp_mask);
+void mthca_free_icm(struct mthca_dev *dev, struct mthca_icm *icm);
+
+struct mthca_icm_table *mthca_alloc_icm_table(struct mthca_dev *dev,
+					      u64 virt, unsigned size,
+					      unsigned reserved,
+					      int use_lowmem);
+void mthca_free_icm_table(struct mthca_dev *dev, struct mthca_icm_table *table);
+
+static inline void mthca_icm_first(struct mthca_icm *icm,
+				   struct mthca_icm_iter *iter)
+{
+	iter->icm      = icm;
+	iter->chunk    = list_empty(&icm->chunk_list) ?
+		NULL : list_entry(icm->chunk_list.next,
+				  struct mthca_icm_chunk, list);
+	iter->page_idx = 0;
+}
+
+static inline int mthca_icm_last(struct mthca_icm_iter *iter)
+{
+	return !iter->chunk;
+}
+
+static inline void mthca_icm_next(struct mthca_icm_iter *iter)
+{
+	if (++iter->page_idx >= iter->chunk->nsg) {
+		if (iter->chunk->list.next == &iter->icm->chunk_list) {
+			iter->chunk = NULL;
+			return;
+		}
+
+		iter->chunk = list_entry(iter->chunk->list.next,
+					 struct mthca_icm_chunk, list);
+		iter->page_idx = 0;
+	}
+}
+
+static inline dma_addr_t mthca_icm_addr(struct mthca_icm_iter *iter)
+{
+	return sg_dma_address(&iter->chunk->mem[iter->page_idx]);
+}
+
+static inline unsigned long mthca_icm_size(struct mthca_icm_iter *iter)
+{
+	return sg_dma_len(&iter->chunk->mem[iter->page_idx]);
+}
+
+#endif /* MTHCA_MEMFREE_H */
diff -Nru a/drivers/infiniband/hw/mthca/mthca_mr.c b/drivers/infiniband/hw/mthca/mthca_mr.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/infiniband/hw/mthca/mthca_mr.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,396 @@
+/*
+ * Copyright (c) 2004 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: mthca_mr.c 1349 2004-12-16 21:09:43Z roland $
+ */
+
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+
+#include "mthca_dev.h"
+#include "mthca_cmd.h"
+
+/*
+ * Must be packed because mtt_seg is 64 bits but only aligned to 32 bits.
+ */
+struct mthca_mpt_entry {
+	u32 flags;
+	u32 page_size;
+	u32 key;
+	u32 pd;
+	u64 start;
+	u64 length;
+	u32 lkey;
+	u32 window_count;
+	u32 window_count_limit;
+	u64 mtt_seg;
+	u32 reserved[3];
+} __attribute__((packed));
+
+#define MTHCA_MPT_FLAG_SW_OWNS       (0xfUL << 28)
+#define MTHCA_MPT_FLAG_MIO           (1 << 17)
+#define MTHCA_MPT_FLAG_BIND_ENABLE   (1 << 15)
+#define MTHCA_MPT_FLAG_PHYSICAL      (1 <<  9)
+#define MTHCA_MPT_FLAG_REGION        (1 <<  8)
+
+#define MTHCA_MTT_FLAG_PRESENT       1
+
+/*
+ * Buddy allocator for MTT segments (currently not very efficient
+ * since it doesn't keep a free list and just searches linearly
+ * through the bitmaps)
+ */
+
+static u32 mthca_alloc_mtt(struct mthca_dev *dev, int order)
+{
+	int o;
+	int m;
+	u32 seg;
+
+	spin_lock(&dev->mr_table.mpt_alloc.lock);
+
+	for (o = order; o <= dev->mr_table.max_mtt_order; ++o) {
+		m = 1 << (dev->mr_table.max_mtt_order - o);
+		seg = find_first_bit(dev->mr_table.mtt_buddy[o], m);
+		if (seg < m)
+			goto found;
+	}
+
+	spin_unlock(&dev->mr_table.mpt_alloc.lock);
+	return -1;
+
+ found:
+	clear_bit(seg, dev->mr_table.mtt_buddy[o]);
+
+	while (o > order) {
+		--o;
+		seg <<= 1;
+		set_bit(seg ^ 1, dev->mr_table.mtt_buddy[o]);
+	}
+
+	spin_unlock(&dev->mr_table.mpt_alloc.lock);
+
+	seg <<= order;
+
+	return seg;
+}
+
+static void mthca_free_mtt(struct mthca_dev *dev, u32 seg, int order)
+{
+	seg >>= order;
+
+	spin_lock(&dev->mr_table.mpt_alloc.lock);
+
+	while (test_bit(seg ^ 1, dev->mr_table.mtt_buddy[order])) {
+		clear_bit(seg ^ 1, dev->mr_table.mtt_buddy[order]);
+		seg >>= 1;
+		++order;
+	}
+
+	set_bit(seg, dev->mr_table.mtt_buddy[order]);
+
+	spin_unlock(&dev->mr_table.mpt_alloc.lock);
+}
+
+int mthca_mr_alloc_notrans(struct mthca_dev *dev, u32 pd,
+			   u32 access, struct mthca_mr *mr)
+{
+	void *mailbox;
+	struct mthca_mpt_entry *mpt_entry;
+	int err;
+	u8 status;
+
+	might_sleep();
+
+	mr->order = -1;
+	mr->ibmr.lkey = mthca_alloc(&dev->mr_table.mpt_alloc);
+	if (mr->ibmr.lkey == -1)
+		return -ENOMEM;
+	mr->ibmr.rkey = mr->ibmr.lkey;
+
+	mailbox = kmalloc(sizeof *mpt_entry + MTHCA_CMD_MAILBOX_EXTRA,
+			  GFP_KERNEL);
+	if (!mailbox) {
+		mthca_free(&dev->mr_table.mpt_alloc, mr->ibmr.lkey);
+		return -ENOMEM;
+	}
+	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(mr->ibmr.lkey);
+	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,
+			      mr->ibmr.lkey & (dev->limits.num_mpts - 1),
+			      &status);
+	if (err)
+		mthca_warn(dev, "SW2HW_MPT failed (%d)\n", err);
+	else if (status) {
+		mthca_warn(dev, "SW2HW_MPT returned status 0x%02x\n",
+			   status);
+		err = -EINVAL;
+	}
+
+	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;
+	int err = -ENOMEM;
+	u8 status;
+	int i;
+
+	might_sleep();
+	WARN_ON(buffer_size_shift >= 32);
+
+	mr->ibmr.lkey = mthca_alloc(&dev->mr_table.mpt_alloc);
+	if (mr->ibmr.lkey == -1)
+		return -ENOMEM;
+	mr->ibmr.rkey = mr->ibmr.lkey;
+
+	for (i = dev->limits.mtt_seg_size / 8, mr->order = 0;
+	     i < list_len;
+	     i <<= 1, ++mr->order)
+		; /* nothing */
+
+	mr->first_seg = mthca_alloc_mtt(dev, mr->order);
+	if (mr->first_seg == -1)
+		goto err_out_mpt_free;
+
+	/*
+	 * 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 * dev->limits.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->flags = cpu_to_be32(MTHCA_MPT_FLAG_SW_OWNS     |
+				       MTHCA_MPT_FLAG_MIO         |
+				       MTHCA_MPT_FLAG_REGION      |
+				       access);
+
+	mpt_entry->page_size = cpu_to_be32(buffer_size_shift - 12);
+	mpt_entry->key       = cpu_to_be32(mr->ibmr.lkey);
+	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 * dev->limits.mtt_seg_size);
+
+	if (0) {
+		mthca_dbg(dev, "Dumping MPT entry %08x:\n", mr->ibmr.lkey);
+		for (i = 0; i < sizeof (struct mthca_mpt_entry) / 4; ++i) {
+			if (i % 4 == 0)
+				printk("[%02x] ", i * 4);
+			printk(" %08x", be32_to_cpu(((u32 *) mpt_entry)[i]));
+			if ((i + 1) % 4 == 0)
+				printk("\n");
+		}
+	}
+
+	err = mthca_SW2HW_MPT(dev, mpt_entry,
+			      mr->ibmr.lkey & (dev->limits.num_mpts - 1),
+			      &status);
+	if (err)
+		mthca_warn(dev, "SW2HW_MPT failed (%d)\n", err);
+	else if (status) {
+		mthca_warn(dev, "SW2HW_MPT returned status 0x%02x\n",
+			   status);
+		err = -EINVAL;
+	}
+
+	kfree(mailbox);
+	return err;
+
+ err_out_mailbox_free:
+	kfree(mailbox);
+
+ err_out_free_mtt:
+	mthca_free_mtt(dev, mr->first_seg, mr->order);
+
+ err_out_mpt_free:
+	mthca_free(&dev->mr_table.mpt_alloc, mr->ibmr.lkey);
+	return err;
+}
+
+void mthca_free_mr(struct mthca_dev *dev, struct mthca_mr *mr)
+{
+	int err;
+	u8 status;
+
+	might_sleep();
+
+	err = mthca_HW2SW_MPT(dev, NULL,
+			      mr->ibmr.lkey & (dev->limits.num_mpts - 1),
+			      &status);
+	if (err)
+		mthca_warn(dev, "HW2SW_MPT failed (%d)\n", err);
+	else if (status)
+		mthca_warn(dev, "HW2SW_MPT returned status 0x%02x\n",
+			   status);
+
+	if (mr->order >= 0)
+		mthca_free_mtt(dev, mr->first_seg, mr->order);
+
+	mthca_free(&dev->mr_table.mpt_alloc, mr->ibmr.lkey);
+}
+
+int __devinit mthca_init_mr_table(struct mthca_dev *dev)
+{
+	int err;
+	int i, s;
+
+	err = mthca_alloc_init(&dev->mr_table.mpt_alloc,
+			       dev->limits.num_mpts,
+			       ~0, dev->limits.reserved_mrws);
+	if (err)
+		return err;
+
+	err = -ENOMEM;
+
+	for (i = 1, dev->mr_table.max_mtt_order = 0;
+	     i < dev->limits.num_mtt_segs;
+	     i <<= 1, ++dev->mr_table.max_mtt_order)
+		; /* nothing */
+
+	dev->mr_table.mtt_buddy = kmalloc((dev->mr_table.max_mtt_order + 1) *
+					  sizeof (long *),
+					  GFP_KERNEL);
+	if (!dev->mr_table.mtt_buddy)
+		goto err_out;
+
+	for (i = 0; i <= dev->mr_table.max_mtt_order; ++i)
+		dev->mr_table.mtt_buddy[i] = NULL;
+
+	for (i = 0; i <= dev->mr_table.max_mtt_order; ++i) {
+		s = BITS_TO_LONGS(1 << (dev->mr_table.max_mtt_order - i));
+		dev->mr_table.mtt_buddy[i] = kmalloc(s * sizeof (long),
+						     GFP_KERNEL);
+		if (!dev->mr_table.mtt_buddy[i])
+			goto err_out_free;
+		bitmap_zero(dev->mr_table.mtt_buddy[i],
+			    1 << (dev->mr_table.max_mtt_order - i));
+	}
+
+	set_bit(0, dev->mr_table.mtt_buddy[dev->mr_table.max_mtt_order]);
+
+	for (i = 0; i < dev->mr_table.max_mtt_order; ++i)
+		if (1 << i >= dev->limits.reserved_mtts)
+			break;
+
+	if (i == dev->mr_table.max_mtt_order) {
+		mthca_err(dev, "MTT table of order %d is "
+			  "too small.\n", i);
+		goto err_out_free;
+	}
+
+	(void) mthca_alloc_mtt(dev, i);
+
+	return 0;
+
+ err_out_free:
+	for (i = 0; i <= dev->mr_table.max_mtt_order; ++i)
+		kfree(dev->mr_table.mtt_buddy[i]);
+
+ err_out:
+	mthca_alloc_cleanup(&dev->mr_table.mpt_alloc);
+
+	return err;
+}
+
+void __devexit mthca_cleanup_mr_table(struct mthca_dev *dev)
+{
+	int i;
+
+	/* XXX check if any MRs are still allocated? */
+	for (i = 0; i <= dev->mr_table.max_mtt_order; ++i)
+		kfree(dev->mr_table.mtt_buddy[i]);
+	kfree(dev->mr_table.mtt_buddy);
+	mthca_alloc_cleanup(&dev->mr_table.mpt_alloc);
+}
diff -Nru a/drivers/infiniband/hw/mthca/mthca_pd.c b/drivers/infiniband/hw/mthca/mthca_pd.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/infiniband/hw/mthca/mthca_pd.c	2005-03-01 23:39:26 -08:00
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2004 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: mthca_pd.c 1349 2004-12-16 21:09:43Z roland $
+ */
+
+#include <linux/init.h>
+#include <linux/errno.h>
+
+#include "mthca_dev.h"
+
+int mthca_pd_alloc(struct mthca_dev *dev, struct mthca_pd *pd)
+{
+	int err;
+
+	might_sleep();
+
+	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);
+
+	return err;
+}
+
+void mthca_pd_free(struct mthca_dev *dev, struct mthca_pd *pd)
+{
+	might_sleep();
+	mthca_free_mr(dev, &pd->ntmr);
+	mthca_free(&dev->pd_table.alloc, pd->pd_num);
+}
+
+int __devinit mthca_init_pd_table(struct mthca_dev *dev)
+{
+	return mthca_alloc_init(&dev->pd_table.alloc,
+				dev->limits.num_pds,
+				(1 << 24) - 1,
+				dev->limits.reserved_pds);
+}
+
+void __devexit mthca_cleanup_pd_table(struct mthca_dev *dev)
+{
+	/* XXX check if any PDs are still allocated? */
+	mthca_alloc_cleanup(&dev->pd_table.alloc);
+}
diff -Nru a/drivers/infiniband/hw/mthca/mthca_profile.c b/drivers/infiniband/hw/mthca/mthca_profile.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/infiniband/hw/mthca/mthca_profile.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,261 @@
+/*
+ * Copyright (c) 2004, 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: mthca_profile.c 1349 2004-12-16 21:09:43Z roland $
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+
+#include "mthca_profile.h"
+
+enum {
+	MTHCA_RES_QP,
+	MTHCA_RES_EEC,
+	MTHCA_RES_SRQ,
+	MTHCA_RES_CQ,
+	MTHCA_RES_EQP,
+	MTHCA_RES_EEEC,
+	MTHCA_RES_EQ,
+	MTHCA_RES_RDB,
+	MTHCA_RES_MCG,
+	MTHCA_RES_MPT,
+	MTHCA_RES_MTT,
+	MTHCA_RES_UAR,
+	MTHCA_RES_UDAV,
+	MTHCA_RES_UARC,
+	MTHCA_RES_NUM
+};
+
+enum {
+	MTHCA_NUM_EQS = 32,
+	MTHCA_NUM_PDS = 1 << 15
+};
+
+u64 mthca_make_profile(struct mthca_dev *dev,
+		       struct mthca_profile *request,
+		       struct mthca_dev_lim *dev_lim,
+		       struct mthca_init_hca_param *init_hca)
+{
+	struct mthca_resource {
+		u64 size;
+		u64 start;
+		int type;
+		int num;
+		int log_num;
+	};
+
+	u64 mem_base, mem_avail;
+	u64 total_size = 0;
+	struct mthca_resource *profile;
+	struct mthca_resource tmp;
+	int i, j;
+
+	profile = kmalloc(MTHCA_RES_NUM * sizeof *profile, GFP_KERNEL);
+	if (!profile)
+		return -ENOMEM;
+
+	memset(profile, 0, MTHCA_RES_NUM * sizeof *profile);
+
+	profile[MTHCA_RES_QP].size   = dev_lim->qpc_entry_sz;
+	profile[MTHCA_RES_EEC].size  = dev_lim->eec_entry_sz;
+	profile[MTHCA_RES_SRQ].size  = dev_lim->srq_entry_sz;
+	profile[MTHCA_RES_CQ].size   = dev_lim->cqc_entry_sz;
+	profile[MTHCA_RES_EQP].size  = dev_lim->eqpc_entry_sz;
+	profile[MTHCA_RES_EEEC].size = dev_lim->eeec_entry_sz;
+	profile[MTHCA_RES_EQ].size   = dev_lim->eqc_entry_sz;
+	profile[MTHCA_RES_RDB].size  = MTHCA_RDB_ENTRY_SIZE;
+	profile[MTHCA_RES_MCG].size  = MTHCA_MGM_ENTRY_SIZE;
+	profile[MTHCA_RES_MPT].size  = dev_lim->mpt_entry_sz;
+	profile[MTHCA_RES_MTT].size  = dev_lim->mtt_seg_sz;
+	profile[MTHCA_RES_UAR].size  = dev_lim->uar_scratch_entry_sz;
+	profile[MTHCA_RES_UDAV].size = MTHCA_AV_SIZE;
+	profile[MTHCA_RES_UARC].size = request->uarc_size;
+
+	profile[MTHCA_RES_QP].num    = request->num_qp;
+	profile[MTHCA_RES_EQP].num   = request->num_qp;
+	profile[MTHCA_RES_RDB].num   = request->num_qp * request->rdb_per_qp;
+	profile[MTHCA_RES_CQ].num    = request->num_cq;
+	profile[MTHCA_RES_EQ].num    = MTHCA_NUM_EQS;
+	profile[MTHCA_RES_MCG].num   = request->num_mcg;
+	profile[MTHCA_RES_MPT].num   = request->num_mpt;
+	profile[MTHCA_RES_MTT].num   = request->num_mtt;
+	profile[MTHCA_RES_UAR].num   = request->num_uar;
+	profile[MTHCA_RES_UARC].num  = request->num_uar;
+	profile[MTHCA_RES_UDAV].num  = request->num_udav;
+
+	for (i = 0; i < MTHCA_RES_NUM; ++i) {
+		profile[i].type     = i;
+		profile[i].log_num  = max(ffs(profile[i].num) - 1, 0);
+		profile[i].size    *= profile[i].num;
+		if (dev->hca_type == ARBEL_NATIVE)
+			profile[i].size = max(profile[i].size, (u64) PAGE_SIZE);
+	}
+
+	if (dev->hca_type == ARBEL_NATIVE) {
+		mem_base  = 0;
+		mem_avail = dev_lim->hca.arbel.max_icm_sz;
+	} else {
+		mem_base  = dev->ddr_start;
+		mem_avail = dev->fw.tavor.fw_start - dev->ddr_start;
+	}
+
+	/*
+	 * Sort the resources in decreasing order of size.  Since they
+	 * all have sizes that are powers of 2, we'll be able to keep
+	 * resources aligned to their size and pack them without gaps
+	 * using the sorted order.
+	 */
+	for (i = MTHCA_RES_NUM; i > 0; --i)
+		for (j = 1; j < i; ++j) {
+			if (profile[j].size > profile[j - 1].size) {
+				tmp            = profile[j];
+				profile[j]     = profile[j - 1];
+				profile[j - 1] = tmp;
+			}
+		}
+
+	for (i = 0; i < MTHCA_RES_NUM; ++i) {
+		if (profile[i].size) {
+			profile[i].start = mem_base + total_size;
+			total_size      += profile[i].size;
+		}
+		if (total_size > mem_avail) {
+			mthca_err(dev, "Profile requires 0x%llx bytes; "
+				  "won't in 0x%llx bytes of context memory.\n",
+				  (unsigned long long) total_size,
+				  (unsigned long long) mem_avail);
+			kfree(profile);
+			return -ENOMEM;
+		}
+
+		if (profile[i].size)
+			mthca_dbg(dev, "profile[%2d]--%2d/%2d @ 0x%16llx "
+				  "(size 0x%8llx)\n",
+				  i, profile[i].type, profile[i].log_num,
+				  (unsigned long long) profile[i].start,
+				  (unsigned long long) profile[i].size);
+	}
+
+	if (dev->hca_type == ARBEL_NATIVE)
+		mthca_dbg(dev, "HCA context memory: reserving %d KB\n",
+			  (int) (total_size >> 10));
+	else
+		mthca_dbg(dev, "HCA memory: allocated %d KB/%d KB (%d KB free)\n",
+			  (int) (total_size >> 10), (int) (mem_avail >> 10),
+			  (int) ((mem_avail - total_size) >> 10));
+
+	for (i = 0; i < MTHCA_RES_NUM; ++i) {
+		switch (profile[i].type) {
+		case MTHCA_RES_QP:
+			dev->limits.num_qps   = profile[i].num;
+			init_hca->qpc_base    = profile[i].start;
+			init_hca->log_num_qps = profile[i].log_num;
+			break;
+		case MTHCA_RES_EEC:
+			dev->limits.num_eecs   = profile[i].num;
+			init_hca->eec_base     = profile[i].start;
+			init_hca->log_num_eecs = profile[i].log_num;
+			break;
+		case MTHCA_RES_SRQ:
+			dev->limits.num_srqs   = profile[i].num;
+			init_hca->srqc_base    = profile[i].start;
+			init_hca->log_num_srqs = profile[i].log_num;
+			break;
+		case MTHCA_RES_CQ:
+			dev->limits.num_cqs   = profile[i].num;
+			init_hca->cqc_base    = profile[i].start;
+			init_hca->log_num_cqs = profile[i].log_num;
+			break;
+		case MTHCA_RES_EQP:
+			init_hca->eqpc_base = profile[i].start;
+			break;
+		case MTHCA_RES_EEEC:
+			init_hca->eeec_base = profile[i].start;
+			break;
+		case MTHCA_RES_EQ:
+			dev->limits.num_eqs   = profile[i].num;
+			init_hca->eqc_base    = profile[i].start;
+			init_hca->log_num_eqs = profile[i].log_num;
+			break;
+		case MTHCA_RES_RDB:
+			for (dev->qp_table.rdb_shift = 0;
+			     profile[MTHCA_RES_QP].num << dev->qp_table.rdb_shift <
+				     profile[i].num;
+			     ++dev->qp_table.rdb_shift)
+				; /* nothing */
+			dev->qp_table.rdb_base    = (u32) profile[i].start;
+			init_hca->rdb_base        = profile[i].start;
+			break;
+		case MTHCA_RES_MCG:
+			dev->limits.num_mgms      = profile[i].num >> 1;
+			dev->limits.num_amgms     = profile[i].num >> 1;
+			init_hca->mc_base         = profile[i].start;
+			init_hca->log_mc_entry_sz = ffs(MTHCA_MGM_ENTRY_SIZE) - 1;
+			init_hca->log_mc_table_sz = profile[i].log_num;
+			init_hca->mc_hash_sz      = 1 << (profile[i].log_num - 1);
+			break;
+		case MTHCA_RES_MPT:
+			dev->limits.num_mpts = profile[i].num;
+			init_hca->mpt_base   = profile[i].start;
+			init_hca->log_mpt_sz = profile[i].log_num;
+			break;
+		case MTHCA_RES_MTT:
+			dev->limits.num_mtt_segs = profile[i].num;
+			dev->limits.mtt_seg_size = dev_lim->mtt_seg_sz;
+			dev->mr_table.mtt_base   = profile[i].start;
+			init_hca->mtt_base       = profile[i].start;
+			init_hca->mtt_seg_sz     = ffs(dev_lim->mtt_seg_sz) - 7;
+			break;
+		case MTHCA_RES_UAR:
+			init_hca->uar_scratch_base = profile[i].start;
+			break;
+		case MTHCA_RES_UDAV:
+			dev->av_table.ddr_av_base = profile[i].start;
+			dev->av_table.num_ddr_avs = profile[i].num;
+		case MTHCA_RES_UARC:
+			init_hca->uarc_base   = profile[i].start;
+			init_hca->log_uarc_sz = ffs(request->uarc_size) - 13;
+			init_hca->log_uar_sz  = ffs(request->num_uar) - 1;
+		default:
+			break;
+		}
+	}
+
+	/*
+	 * PDs don't take any HCA memory, but we assign them as part
+	 * of the HCA profile anyway.
+	 */
+	dev->limits.num_pds = MTHCA_NUM_PDS;
+
+	kfree(profile);
+	return total_size;
+}
diff -Nru a/drivers/infiniband/hw/mthca/mthca_profile.h b/drivers/infiniband/hw/mthca/mthca_profile.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/infiniband/hw/mthca/mthca_profile.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2004, 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: mthca_profile.h 1349 2004-12-16 21:09:43Z roland $
+ */
+
+#ifndef MTHCA_PROFILE_H
+#define MTHCA_PROFILE_H
+
+#include "mthca_dev.h"
+#include "mthca_cmd.h"
+
+struct mthca_profile {
+	int num_qp;
+	int rdb_per_qp;
+	int num_cq;
+	int num_mcg;
+	int num_mpt;
+	int num_mtt;
+	int num_udav;
+	int num_uar;
+	int uarc_size;
+};
+
+u64 mthca_make_profile(struct mthca_dev *mdev,
+		       struct mthca_profile *request,
+		       struct mthca_dev_lim *dev_lim,
+		       struct mthca_init_hca_param *init_hca);
+
+#endif /* MTHCA_PROFILE_H */
diff -Nru a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/infiniband/hw/mthca/mthca_provider.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,658 @@
+/*
+ * Copyright (c) 2004, 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: mthca_provider.c 1397 2004-12-28 05:09:00Z roland $
+ */
+
+#include <ib_smi.h>
+
+#include "mthca_dev.h"
+#include "mthca_cmd.h"
+
+static int mthca_query_device(struct ib_device *ibdev,
+			      struct ib_device_attr *props)
+{
+	struct ib_smp *in_mad  = NULL;
+	struct ib_smp *out_mad = NULL;
+	int err = -ENOMEM;
+	u8 status;
+
+	in_mad  = kmalloc(sizeof *in_mad, GFP_KERNEL);
+	out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL);
+	if (!in_mad || !out_mad)
+		goto out;
+
+	props->fw_ver        = to_mdev(ibdev)->fw_ver;
+
+	memset(in_mad, 0, sizeof *in_mad);
+	in_mad->base_version       = 1;
+	in_mad->mgmt_class     	   = IB_MGMT_CLASS_SUBN_LID_ROUTED;
+	in_mad->class_version  	   = 1;
+	in_mad->method         	   = IB_MGMT_METHOD_GET;
+	in_mad->attr_id   	   = IB_SMP_ATTR_NODE_INFO;
+
+	err = mthca_MAD_IFC(to_mdev(ibdev), 1, 1,
+			    1, NULL, NULL, in_mad, out_mad,
+			    &status);
+	if (err)
+		goto out;
+	if (status) {
+		err = -EINVAL;
+		goto out;
+	}
+
+	props->vendor_id      = be32_to_cpup((u32 *) (out_mad->data + 36)) &
+		0xffffff;
+	props->vendor_part_id = be16_to_cpup((u16 *) (out_mad->data + 30));
+	props->hw_ver         = be16_to_cpup((u16 *) (out_mad->data + 32));
+	memcpy(&props->sys_image_guid, out_mad->data +  4, 8);
+	memcpy(&props->node_guid,      out_mad->data + 12, 8);
+
+	err = 0;
+ out:
+	kfree(in_mad);
+	kfree(out_mad);
+	return err;
+}
+
+static int mthca_query_port(struct ib_device *ibdev,
+			    u8 port, struct ib_port_attr *props)
+{
+	struct ib_smp *in_mad  = NULL;
+	struct ib_smp *out_mad = NULL;
+	int err = -ENOMEM;
+	u8 status;
+
+	in_mad  = kmalloc(sizeof *in_mad, GFP_KERNEL);
+	out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL);
+	if (!in_mad || !out_mad)
+		goto out;
+
+	memset(in_mad, 0, sizeof *in_mad);
+	in_mad->base_version       = 1;
+	in_mad->mgmt_class     	   = IB_MGMT_CLASS_SUBN_LID_ROUTED;
+	in_mad->class_version  	   = 1;
+	in_mad->method         	   = IB_MGMT_METHOD_GET;
+	in_mad->attr_id   	   = IB_SMP_ATTR_PORT_INFO;
+	in_mad->attr_mod           = cpu_to_be32(port);
+
+	err = mthca_MAD_IFC(to_mdev(ibdev), 1, 1,
+			    port, NULL, NULL, in_mad, out_mad,
+			    &status);
+	if (err)
+		goto out;
+	if (status) {
+		err = -EINVAL;
+		goto out;
+	}
+
+	props->lid               = be16_to_cpup((u16 *) (out_mad->data + 16));
+	props->lmc               = out_mad->data[34] & 0x7;
+	props->sm_lid            = be16_to_cpup((u16 *) (out_mad->data + 18));
+	props->sm_sl             = out_mad->data[36] & 0xf;
+	props->state             = out_mad->data[32] & 0xf;
+	props->phys_state        = out_mad->data[33] >> 4;
+	props->port_cap_flags    = be32_to_cpup((u32 *) (out_mad->data + 20));
+	props->gid_tbl_len       = to_mdev(ibdev)->limits.gid_table_len;
+	props->pkey_tbl_len      = to_mdev(ibdev)->limits.pkey_table_len;
+	props->qkey_viol_cntr    = be16_to_cpup((u16 *) (out_mad->data + 48));
+	props->active_width      = out_mad->data[31] & 0xf;
+	props->active_speed      = out_mad->data[35] >> 4;
+
+ out:
+	kfree(in_mad);
+	kfree(out_mad);
+	return err;
+}
+
+static int mthca_modify_port(struct ib_device *ibdev,
+			     u8 port, int port_modify_mask,
+			     struct ib_port_modify *props)
+{
+	struct mthca_set_ib_param set_ib;
+	struct ib_port_attr attr;
+	int err;
+	u8 status;
+
+	if (down_interruptible(&to_mdev(ibdev)->cap_mask_mutex))
+		return -ERESTARTSYS;
+
+	err = mthca_query_port(ibdev, port, &attr);
+	if (err)
+		goto out;
+
+	set_ib.set_si_guid     = 0;
+	set_ib.reset_qkey_viol = !!(port_modify_mask & IB_PORT_RESET_QKEY_CNTR);
+
+	set_ib.cap_mask = (attr.port_cap_flags | props->set_port_cap_mask) &
+		~props->clr_port_cap_mask;
+
+	err = mthca_SET_IB(to_mdev(ibdev), &set_ib, port, &status);
+	if (err)
+		goto out;
+	if (status) {
+		err = -EINVAL;
+		goto out;
+	}
+
+out:
+	up(&to_mdev(ibdev)->cap_mask_mutex);
+	return err;
+}
+
+static int mthca_query_pkey(struct ib_device *ibdev,
+			    u8 port, u16 index, u16 *pkey)
+{
+	struct ib_smp *in_mad  = NULL;
+	struct ib_smp *out_mad = NULL;
+	int err = -ENOMEM;
+	u8 status;
+
+	in_mad  = kmalloc(sizeof *in_mad, GFP_KERNEL);
+	out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL);
+	if (!in_mad || !out_mad)
+		goto out;
+
+	memset(in_mad, 0, sizeof *in_mad);
+	in_mad->base_version       = 1;
+	in_mad->mgmt_class     	   = IB_MGMT_CLASS_SUBN_LID_ROUTED;
+	in_mad->class_version  	   = 1;
+	in_mad->method         	   = IB_MGMT_METHOD_GET;
+	in_mad->attr_id   	   = IB_SMP_ATTR_PKEY_TABLE;
+	in_mad->attr_mod           = cpu_to_be32(index / 32);
+
+	err = mthca_MAD_IFC(to_mdev(ibdev), 1, 1,
+			    port, NULL, NULL, in_mad, out_mad,
+			    &status);
+	if (err)
+		goto out;
+	if (status) {
+		err = -EINVAL;
+		goto out;
+	}
+
+	*pkey = be16_to_cpu(((u16 *) out_mad->data)[index % 32]);
+
+ out:
+	kfree(in_mad);
+	kfree(out_mad);
+	return err;
+}
+
+static int mthca_query_gid(struct ib_device *ibdev, u8 port,
+			   int index, union ib_gid *gid)
+{
+	struct ib_smp *in_mad  = NULL;
+	struct ib_smp *out_mad = NULL;
+	int err = -ENOMEM;
+	u8 status;
+
+	in_mad  = kmalloc(sizeof *in_mad, GFP_KERNEL);
+	out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL);
+	if (!in_mad || !out_mad)
+		goto out;
+
+	memset(in_mad, 0, sizeof *in_mad);
+	in_mad->base_version       = 1;
+	in_mad->mgmt_class     	   = IB_MGMT_CLASS_SUBN_LID_ROUTED;
+	in_mad->class_version  	   = 1;
+	in_mad->method         	   = IB_MGMT_METHOD_GET;
+	in_mad->attr_id   	   = IB_SMP_ATTR_PORT_INFO;
+	in_mad->attr_mod           = cpu_to_be32(port);
+
+	err = mthca_MAD_IFC(to_mdev(ibdev), 1, 1,
+			    port, NULL, NULL, in_mad, out_mad,
+			    &status);
+	if (err)
+		goto out;
+	if (status) {
+		err = -EINVAL;
+		goto out;
+	}
+
+	memcpy(gid->raw, out_mad->data + 8, 8);
+
+	memset(in_mad, 0, sizeof *in_mad);
+	in_mad->base_version       = 1;
+	in_mad->mgmt_class     	   = IB_MGMT_CLASS_SUBN_LID_ROUTED;
+	in_mad->class_version  	   = 1;
+	in_mad->method         	   = IB_MGMT_METHOD_GET;
+	in_mad->attr_id   	   = IB_SMP_ATTR_GUID_INFO;
+	in_mad->attr_mod           = cpu_to_be32(index / 8);
+
+	err = mthca_MAD_IFC(to_mdev(ibdev), 1, 1,
+			    port, NULL, NULL, in_mad, out_mad,
+			    &status);
+	if (err)
+		goto out;
+	if (status) {
+		err = -EINVAL;
+		goto out;
+	}
+
+	memcpy(gid->raw + 8, out_mad->data + (index % 8) * 16, 8);
+
+ out:
+	kfree(in_mad);
+	kfree(out_mad);
+	return err;
+}
+
+static struct ib_pd *mthca_alloc_pd(struct ib_device *ibdev)
+{
+	struct mthca_pd *pd;
+	int err;
+
+	pd = kmalloc(sizeof *pd, GFP_KERNEL);
+	if (!pd)
+		return ERR_PTR(-ENOMEM);
+
+	err = mthca_pd_alloc(to_mdev(ibdev), pd);
+	if (err) {
+		kfree(pd);
+		return ERR_PTR(err);
+	}
+
+	return &pd->ibpd;
+}
+
+static int mthca_dealloc_pd(struct ib_pd *pd)
+{
+	mthca_pd_free(to_mdev(pd->device), to_mpd(pd));
+	kfree(pd);
+
+	return 0;
+}
+
+static struct ib_ah *mthca_ah_create(struct ib_pd *pd,
+				     struct ib_ah_attr *ah_attr)
+{
+	int err;
+	struct mthca_ah *ah;
+
+	ah = kmalloc(sizeof *ah, GFP_KERNEL);
+	if (!ah)
+		return ERR_PTR(-ENOMEM);
+
+	err = mthca_create_ah(to_mdev(pd->device), to_mpd(pd), ah_attr, ah);
+	if (err) {
+		kfree(ah);
+		return ERR_PTR(err);
+	}
+
+	return &ah->ibah;
+}
+
+static int mthca_ah_destroy(struct ib_ah *ah)
+{
+	mthca_destroy_ah(to_mdev(ah->device), to_mah(ah));
+	kfree(ah);
+
+	return 0;
+}
+
+static struct ib_qp *mthca_create_qp(struct ib_pd *pd,
+				     struct ib_qp_init_attr *init_attr)
+{
+	struct mthca_qp *qp;
+	int err;
+
+	switch (init_attr->qp_type) {
+	case IB_QPT_RC:
+	case IB_QPT_UC:
+	case IB_QPT_UD:
+	{
+		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;
+
+		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,
+				     init_attr->rq_sig_type, qp);
+		qp->ibqp.qp_num = qp->qpn;
+		break;
+	}
+	case IB_QPT_SMI:
+	case IB_QPT_GSI:
+	{
+		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->rq_sig_type,
+				      qp->ibqp.qp_num, init_attr->port_num,
+				      to_msqp(qp));
+		break;
+	}
+	default:
+		/* Don't support raw QPs */
+		return ERR_PTR(-ENOSYS);
+	}
+
+	if (err) {
+		kfree(qp);
+		return ERR_PTR(err);
+	}
+
+        init_attr->cap.max_inline_data = 0;
+
+	return &qp->ibqp;
+}
+
+static int mthca_destroy_qp(struct ib_qp *qp)
+{
+	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)
+{
+	struct mthca_cq *cq;
+	int nent;
+	int err;
+
+	cq = kmalloc(sizeof *cq, GFP_KERNEL);
+	if (!cq)
+		return ERR_PTR(-ENOMEM);
+
+	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);
+	} else
+		cq->ibcq.cqe = nent - 1;
+
+	return &cq->ibcq;
+}
+
+static int mthca_destroy_cq(struct ib_cq *cq)
+{
+	mthca_free_cq(to_mdev(cq->device), to_mcq(cq));
+	kfree(cq);
+
+	return 0;
+}
+
+static int mthca_req_notify_cq(struct ib_cq *cq, enum ib_cq_notify notify)
+{
+	mthca_arm_cq(to_mdev(cq->device), to_mcq(cq),
+		     notify == IB_CQ_SOLICITED);
+	return 0;
+}
+
+static inline u32 convert_access(int acc)
+{
+	return (acc & IB_ACCESS_REMOTE_ATOMIC ? MTHCA_MPT_FLAG_ATOMIC       : 0) |
+	       (acc & IB_ACCESS_REMOTE_WRITE  ? MTHCA_MPT_FLAG_REMOTE_WRITE : 0) |
+	       (acc & IB_ACCESS_REMOTE_READ   ? MTHCA_MPT_FLAG_REMOTE_READ  : 0) |
+	       (acc & IB_ACCESS_LOCAL_WRITE   ? MTHCA_MPT_FLAG_LOCAL_WRITE  : 0) |
+	       MTHCA_MPT_FLAG_LOCAL_READ;
+}
+
+static struct ib_mr *mthca_get_dma_mr(struct ib_pd *pd, int acc)
+{
+	struct mthca_mr *mr;
+	int err;
+
+	mr = kmalloc(sizeof *mr, GFP_KERNEL);
+	if (!mr)
+		return ERR_PTR(-ENOMEM);
+
+	err = mthca_mr_alloc_notrans(to_mdev(pd->device),
+				     to_mpd(pd)->pd_num,
+				     convert_access(acc), mr);
+
+	if (err) {
+		kfree(mr);
+		return ERR_PTR(err);
+	}
+
+	return &mr->ibmr;
+}
+
+static struct ib_mr *mthca_reg_phys_mr(struct ib_pd       *pd,
+				       struct ib_phys_buf *buffer_list,
+				       int                 num_phys_buf,
+				       int                 acc,
+				       u64                *iova_start)
+{
+	struct mthca_mr *mr;
+	u64 *page_list;
+	u64 total_size;
+	u64 mask;
+	int shift;
+	int npages;
+	int err;
+	int i, j, n;
+
+	/* First check that we have enough alignment */
+	if ((*iova_start & ~PAGE_MASK) != (buffer_list[0].addr & ~PAGE_MASK))
+		return ERR_PTR(-EINVAL);
+
+	if (num_phys_buf > 1 &&
+	    ((buffer_list[0].addr + buffer_list[0].size) & ~PAGE_MASK))
+		return ERR_PTR(-EINVAL);
+
+	mask = 0;
+	total_size = 0;
+	for (i = 0; i < num_phys_buf; ++i) {
+		if (buffer_list[i].addr & ~PAGE_MASK)
+			return ERR_PTR(-EINVAL);
+		if (i != 0 && i != num_phys_buf - 1 &&
+		    (buffer_list[i].size & ~PAGE_MASK))
+			return ERR_PTR(-EINVAL);
+
+		total_size += buffer_list[i].size;
+		if (i > 0)
+			mask |= buffer_list[i].addr;
+	}
+
+	/* Find largest page shift we can use to cover buffers */
+	for (shift = PAGE_SHIFT; shift < 31; ++shift)
+		if (num_phys_buf > 1) {
+			if ((1ULL << shift) & mask)
+				break;
+		} else {
+			if (1ULL << shift >=
+			    buffer_list[0].size +
+			    (buffer_list[0].addr & ((1ULL << shift) - 1)))
+				break;
+		}
+
+	buffer_list[0].size += buffer_list[0].addr & ((1ULL << shift) - 1);
+	buffer_list[0].addr &= ~0ull << shift;
+
+	mr = kmalloc(sizeof *mr, GFP_KERNEL);
+	if (!mr)
+		return ERR_PTR(-ENOMEM);
+
+	npages = 0;
+	for (i = 0; i < num_phys_buf; ++i)
+		npages += (buffer_list[i].size + (1ULL << shift) - 1) >> shift;
+
+	if (!npages)
+		return &mr->ibmr;
+
+	page_list = kmalloc(npages * sizeof *page_list, GFP_KERNEL);
+	if (!page_list) {
+		kfree(mr);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	n = 0;
+	for (i = 0; i < num_phys_buf; ++i)
+		for (j = 0;
+		     j < (buffer_list[i].size + (1ULL << shift) - 1) >> shift;
+		     ++j)
+			page_list[n++] = buffer_list[i].addr + ((u64) j << shift);
+
+	mthca_dbg(to_mdev(pd->device), "Registering memory at %llx (iova %llx) "
+		  "in PD %x; shift %d, npages %d.\n",
+		  (unsigned long long) buffer_list[0].addr,
+		  (unsigned long long) *iova_start,
+		  to_mpd(pd)->pd_num,
+		  shift, npages);
+
+	err = mthca_mr_alloc_phys(to_mdev(pd->device),
+				  to_mpd(pd)->pd_num,
+				  page_list, shift, npages,
+				  *iova_start, total_size,
+				  convert_access(acc), mr);
+
+	if (err) {
+		kfree(mr);
+		return ERR_PTR(err);
+	}
+
+	kfree(page_list);
+	return &mr->ibmr;
+}
+
+static int mthca_dereg_mr(struct ib_mr *mr)
+{
+	mthca_free_mr(to_mdev(mr->device), to_mmr(mr));
+	kfree(mr);
+	return 0;
+}
+
+static ssize_t show_rev(struct class_device *cdev, char *buf)
+{
+	struct mthca_dev *dev = container_of(cdev, struct mthca_dev, ib_dev.class_dev);
+	return sprintf(buf, "%x\n", dev->rev_id);
+}
+
+static ssize_t show_fw_ver(struct class_device *cdev, char *buf)
+{
+	struct mthca_dev *dev = container_of(cdev, struct mthca_dev, ib_dev.class_dev);
+	return sprintf(buf, "%x.%x.%x\n", (int) (dev->fw_ver >> 32),
+		       (int) (dev->fw_ver >> 16) & 0xffff,
+		       (int) dev->fw_ver & 0xffff);
+}
+
+static ssize_t show_hca(struct class_device *cdev, char *buf)
+{
+	struct mthca_dev *dev = container_of(cdev, struct mthca_dev, ib_dev.class_dev);
+	switch (dev->hca_type) {
+	case TAVOR:        return sprintf(buf, "MT23108\n");
+	case ARBEL_COMPAT: return sprintf(buf, "MT25208 (MT23108 compat mode)\n");
+	case ARBEL_NATIVE: return sprintf(buf, "MT25208\n");
+	default:           return sprintf(buf, "unknown\n");
+	}
+}
+
+static CLASS_DEVICE_ATTR(hw_rev,   S_IRUGO, show_rev,    NULL);
+static CLASS_DEVICE_ATTR(fw_ver,   S_IRUGO, show_fw_ver, NULL);
+static CLASS_DEVICE_ATTR(hca_type, S_IRUGO, show_hca,    NULL);
+
+static struct class_device_attribute *mthca_class_attributes[] = {
+	&class_device_attr_hw_rev,
+	&class_device_attr_fw_ver,
+	&class_device_attr_hca_type
+};
+
+int mthca_register_device(struct mthca_dev *dev)
+{
+	int ret;
+	int i;
+
+	strlcpy(dev->ib_dev.name, "mthca%d", IB_DEVICE_NAME_MAX);
+	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;
+	dev->ib_dev.class_dev.dev        = &dev->pdev->dev;
+	dev->ib_dev.query_device         = mthca_query_device;
+	dev->ib_dev.query_port           = mthca_query_port;
+	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_pd             = mthca_alloc_pd;
+	dev->ib_dev.dealloc_pd           = mthca_dealloc_pd;
+	dev->ib_dev.create_ah            = mthca_ah_create;
+	dev->ib_dev.destroy_ah           = mthca_ah_destroy;
+	dev->ib_dev.create_qp            = mthca_create_qp;
+	dev->ib_dev.modify_qp            = mthca_modify_qp;
+	dev->ib_dev.destroy_qp           = mthca_destroy_qp;
+	dev->ib_dev.post_send            = mthca_post_send;
+	dev->ib_dev.post_recv            = mthca_post_receive;
+	dev->ib_dev.create_cq            = mthca_create_cq;
+	dev->ib_dev.destroy_cq           = mthca_destroy_cq;
+	dev->ib_dev.poll_cq              = mthca_poll_cq;
+	dev->ib_dev.req_notify_cq        = mthca_req_notify_cq;
+	dev->ib_dev.get_dma_mr           = mthca_get_dma_mr;
+	dev->ib_dev.reg_phys_mr          = mthca_reg_phys_mr;
+	dev->ib_dev.dereg_mr             = mthca_dereg_mr;
+	dev->ib_dev.attach_mcast         = mthca_multicast_attach;
+	dev->ib_dev.detach_mcast         = mthca_multicast_detach;
+	dev->ib_dev.process_mad          = mthca_process_mad;
+
+	init_MUTEX(&dev->cap_mask_mutex);
+
+	ret = ib_register_device(&dev->ib_dev);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < ARRAY_SIZE(mthca_class_attributes); ++i) {
+		ret = class_device_create_file(&dev->ib_dev.class_dev,
+					       mthca_class_attributes[i]);
+		if (ret) {
+			ib_unregister_device(&dev->ib_dev);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+void mthca_unregister_device(struct mthca_dev *dev)
+{
+	ib_unregister_device(&dev->ib_dev);
+}
diff -Nru a/drivers/infiniband/hw/mthca/mthca_provider.h b/drivers/infiniband/hw/mthca/mthca_provider.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/infiniband/hw/mthca/mthca_provider.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,228 @@
+/*
+ * Copyright (c) 2004 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: mthca_provider.h 1349 2004-12-16 21:09:43Z roland $
+ */
+
+#ifndef MTHCA_PROVIDER_H
+#define MTHCA_PROVIDER_H
+
+#include <ib_verbs.h>
+#include <ib_pack.h>
+
+#define MTHCA_MPT_FLAG_ATOMIC        (1 << 14)
+#define MTHCA_MPT_FLAG_REMOTE_WRITE  (1 << 13)
+#define MTHCA_MPT_FLAG_REMOTE_READ   (1 << 12)
+#define MTHCA_MPT_FLAG_LOCAL_WRITE   (1 << 11)
+#define MTHCA_MPT_FLAG_LOCAL_READ    (1 << 10)
+
+struct mthca_buf_list {
+	void *buf;
+	DECLARE_PCI_UNMAP_ADDR(mapping)
+};
+
+struct mthca_mr {
+	struct ib_mr ibmr;
+	int order;
+	u32 first_seg;
+};
+
+struct mthca_pd {
+	struct ib_pd    ibpd;
+	u32             pd_num;
+	atomic_t        sqp_count;
+	struct mthca_mr ntmr;
+};
+
+struct mthca_eq {
+	struct mthca_dev      *dev;
+	int                    eqn;
+	u32                    ecr_mask;
+	u32                    cons_index;
+	u16                    msi_x_vector;
+	u16                    msi_x_entry;
+	int                    have_irq;
+	int                    nent;
+	struct mthca_buf_list *page_list;
+	struct mthca_mr        mr;
+};
+
+struct mthca_av;
+
+struct mthca_ah {
+	struct ib_ah     ibah;
+	int              on_hca;
+	u32              key;
+	struct mthca_av *av;
+	dma_addr_t       avdma;
+};
+
+/*
+ * Quick description of our CQ/QP locking scheme:
+ *
+ * We have one global lock that protects dev->cq/qp_table.  Each
+ * struct mthca_cq/qp also has its own lock.  An individual qp lock
+ * may be taken inside of an individual cq lock.  Both cqs attached to
+ * a qp may be locked, with the send cq locked first.  No other
+ * nesting should be done.
+ *
+ * Each struct mthca_cq/qp also has an atomic_t ref count.  The
+ * pointer from the cq/qp_table to the struct counts as one reference.
+ * This reference also is good for access through the consumer API, so
+ * modifying the CQ/QP etc doesn't need to take another reference.
+ * Access because of a completion being polled does need a reference.
+ *
+ * Finally, each struct mthca_cq/qp has a wait_queue_head_t for the
+ * destroy function to sleep on.
+ *
+ * This means that access from the consumer API requires nothing but
+ * taking the struct's lock.
+ *
+ * Access because of a completion event should go as follows:
+ * - lock cq/qp_table and look up struct
+ * - increment ref count in struct
+ * - drop cq/qp_table lock
+ * - lock struct, do your thing, and unlock struct
+ * - decrement ref count; if zero, wake up waiters
+ *
+ * To destroy a CQ/QP, we can do the following:
+ * - lock cq/qp_table, remove pointer, unlock cq/qp_table lock
+ * - decrement ref count
+ * - wait_event until ref count is zero
+ *
+ * It is the consumer's responsibilty to make sure that no QP
+ * operations (WQE posting or state modification) are pending when the
+ * QP is destroyed.  Also, the consumer must make sure that calls to
+ * qp_modify are serialized.
+ *
+ * Possible optimizations (wait for profile data to see if/where we
+ * have locks bouncing between CPUs):
+ * - split cq/qp table lock into n separate (cache-aligned) locks,
+ *   indexed (say) by the page in the table
+ * - split QP struct lock into three (one for common info, one for the
+ *   send queue and one for the receive queue)
+ */
+
+struct mthca_cq {
+	struct ib_cq           ibcq;
+	spinlock_t             lock;
+	atomic_t               refcount;
+	int                    cqn;
+	int                    cons_index;
+	int                    is_direct;
+	union {
+		struct mthca_buf_list direct;
+		struct mthca_buf_list *page_list;
+	}                      queue;
+	struct mthca_mr        mr;
+	wait_queue_head_t      wait;
+};
+
+struct mthca_wq {
+	int   max;
+	int   cur;
+	int   next;
+	int   last_comp;
+	void *last;
+	int   max_gs;
+	int   wqe_shift;
+	enum ib_sig_type policy;
+};
+
+struct mthca_qp {
+	struct ib_qp           ibqp;
+	spinlock_t             lock;
+	atomic_t               refcount;
+	u32                    qpn;
+	int                    is_direct;
+	u8                     transport;
+	u8                     state;
+	u8                     atomic_rd_en;
+	u8                     resp_depth;
+
+	struct mthca_mr        mr;
+
+	struct mthca_wq        rq;
+	struct mthca_wq        sq;
+	int                    send_wqe_offset;
+
+	u64                   *wrid;
+	union {
+		struct mthca_buf_list direct;
+		struct mthca_buf_list *page_list;
+	}                      queue;
+
+	wait_queue_head_t      wait;
+};
+
+struct mthca_sqp {
+	struct mthca_qp qp;
+	int             port;
+	int             pkey_index;
+	u32             qkey;
+	u32             send_psn;
+	struct ib_ud_header ud_header;
+	int             header_buf_size;
+	void           *header_buf;
+	dma_addr_t      header_dma;
+};
+
+static inline struct mthca_mr *to_mmr(struct ib_mr *ibmr)
+{
+	return container_of(ibmr, struct mthca_mr, ibmr);
+}
+
+static inline struct mthca_pd *to_mpd(struct ib_pd *ibpd)
+{
+	return container_of(ibpd, struct mthca_pd, ibpd);
+}
+
+static inline struct mthca_ah *to_mah(struct ib_ah *ibah)
+{
+	return container_of(ibah, struct mthca_ah, ibah);
+}
+
+static inline struct mthca_cq *to_mcq(struct ib_cq *ibcq)
+{
+	return container_of(ibcq, struct mthca_cq, ibcq);
+}
+
+static inline struct mthca_qp *to_mqp(struct ib_qp *ibqp)
+{
+	return container_of(ibqp, struct mthca_qp, ibqp);
+}
+
+static inline struct mthca_sqp *to_msqp(struct mthca_qp *qp)
+{
+	return container_of(qp, struct mthca_sqp, qp);
+}
+
+#endif /* MTHCA_PROVIDER_H */
diff -Nru a/drivers/infiniband/hw/mthca/mthca_qp.c b/drivers/infiniband/hw/mthca/mthca_qp.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/infiniband/hw/mthca/mthca_qp.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,1615 @@
+/*
+ * Copyright (c) 2004 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: mthca_qp.c 1355 2004-12-17 15:23:43Z roland $
+ */
+
+#include <linux/init.h>
+
+#include <ib_verbs.h>
+#include <ib_cache.h>
+#include <ib_pack.h>
+
+#include "mthca_dev.h"
+#include "mthca_cmd.h"
+
+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 */
+};
+
+enum {
+	MTHCA_QP_STATE_RST  = 0,
+	MTHCA_QP_STATE_INIT = 1,
+	MTHCA_QP_STATE_RTR  = 2,
+	MTHCA_QP_STATE_RTS  = 3,
+	MTHCA_QP_STATE_SQE  = 4,
+	MTHCA_QP_STATE_SQD  = 5,
+	MTHCA_QP_STATE_ERR  = 6,
+	MTHCA_QP_STATE_DRAINING = 7
+};
+
+enum {
+	MTHCA_QP_ST_RC 	= 0x0,
+	MTHCA_QP_ST_UC 	= 0x1,
+	MTHCA_QP_ST_RD 	= 0x2,
+	MTHCA_QP_ST_UD 	= 0x3,
+	MTHCA_QP_ST_MLX = 0x7
+};
+
+enum {
+	MTHCA_QP_PM_MIGRATED = 0x3,
+	MTHCA_QP_PM_ARMED    = 0x0,
+	MTHCA_QP_PM_REARM    = 0x1
+};
+
+enum {
+	/* qp_context flags */
+	MTHCA_QP_BIT_DE  = 1 <<  8,
+	/* params1 */
+	MTHCA_QP_BIT_SRE = 1 << 15,
+	MTHCA_QP_BIT_SWE = 1 << 14,
+	MTHCA_QP_BIT_SAE = 1 << 13,
+	MTHCA_QP_BIT_SIC = 1 <<  4,
+	MTHCA_QP_BIT_SSC = 1 <<  3,
+	/* params2 */
+	MTHCA_QP_BIT_RRE = 1 << 15,
+	MTHCA_QP_BIT_RWE = 1 << 14,
+	MTHCA_QP_BIT_RAE = 1 << 13,
+	MTHCA_QP_BIT_RIC = 1 <<  4,
+	MTHCA_QP_BIT_RSC = 1 <<  3
+};
+
+struct mthca_qp_path {
+	u32 port_pkey;
+	u8  rnr_retry;
+	u8  g_mylmc;
+	u16 rlid;
+	u8  ackto;
+	u8  mgid_index;
+	u8  static_rate;
+	u8  hop_limit;
+	u32 sl_tclass_flowlabel;
+	u8  rgid[16];
+} __attribute__((packed));
+
+struct mthca_qp_context {
+	u32 flags;
+	u32 sched_queue;
+	u32 mtu_msgmax;
+	u32 usr_page;
+	u32 local_qpn;
+	u32 remote_qpn;
+	u32 reserved1[2];
+	struct mthca_qp_path pri_path;
+	struct mthca_qp_path alt_path;
+	u32 rdd;
+	u32 pd;
+	u32 wqe_base;
+	u32 wqe_lkey;
+	u32 params1;
+	u32 reserved2;
+	u32 next_send_psn;
+	u32 cqn_snd;
+	u32 next_snd_wqe[2];
+	u32 last_acked_psn;
+	u32 ssn;
+	u32 params2;
+	u32 rnr_nextrecvpsn;
+	u32 ra_buff_indx;
+	u32 cqn_rcv;
+	u32 next_rcv_wqe[2];
+	u32 qkey;
+	u32 srqn;
+	u32 rmsn;
+	u32 reserved3[19];
+} __attribute__((packed));
+
+struct mthca_qp_param {
+	u32 opt_param_mask;
+	u32 reserved1;
+	struct mthca_qp_context context;
+	u32 reserved2[62];
+} __attribute__((packed));
+
+enum {
+	MTHCA_QP_OPTPAR_ALT_ADDR_PATH     = 1 << 0,
+	MTHCA_QP_OPTPAR_RRE               = 1 << 1,
+	MTHCA_QP_OPTPAR_RAE               = 1 << 2,
+	MTHCA_QP_OPTPAR_RWE               = 1 << 3,
+	MTHCA_QP_OPTPAR_PKEY_INDEX        = 1 << 4,
+	MTHCA_QP_OPTPAR_Q_KEY             = 1 << 5,
+	MTHCA_QP_OPTPAR_RNR_TIMEOUT       = 1 << 6,
+	MTHCA_QP_OPTPAR_PRIMARY_ADDR_PATH = 1 << 7,
+	MTHCA_QP_OPTPAR_SRA_MAX           = 1 << 8,
+	MTHCA_QP_OPTPAR_RRA_MAX           = 1 << 9,
+	MTHCA_QP_OPTPAR_PM_STATE          = 1 << 10,
+	MTHCA_QP_OPTPAR_PORT_NUM          = 1 << 11,
+	MTHCA_QP_OPTPAR_RETRY_COUNT       = 1 << 12,
+	MTHCA_QP_OPTPAR_ALT_RNR_RETRY     = 1 << 13,
+	MTHCA_QP_OPTPAR_ACK_TIMEOUT       = 1 << 14,
+	MTHCA_QP_OPTPAR_RNR_RETRY         = 1 << 15,
+	MTHCA_QP_OPTPAR_SCHED_QUEUE       = 1 << 16
+};
+
+enum {
+	MTHCA_OPCODE_NOP            = 0x00,
+	MTHCA_OPCODE_RDMA_WRITE     = 0x08,
+	MTHCA_OPCODE_RDMA_WRITE_IMM = 0x09,
+	MTHCA_OPCODE_SEND           = 0x0a,
+	MTHCA_OPCODE_SEND_IMM       = 0x0b,
+	MTHCA_OPCODE_RDMA_READ      = 0x10,
+	MTHCA_OPCODE_ATOMIC_CS      = 0x11,
+	MTHCA_OPCODE_ATOMIC_FA      = 0x12,
+	MTHCA_OPCODE_BIND_MW        = 0x18,
+	MTHCA_OPCODE_INVALID        = 0xff
+};
+
+enum {
+	MTHCA_NEXT_DBD       = 1 << 7,
+	MTHCA_NEXT_FENCE     = 1 << 6,
+	MTHCA_NEXT_CQ_UPDATE = 1 << 3,
+	MTHCA_NEXT_EVENT_GEN = 1 << 2,
+	MTHCA_NEXT_SOLICIT   = 1 << 1,
+
+	MTHCA_MLX_VL15       = 1 << 17,
+	MTHCA_MLX_SLR        = 1 << 16
+};
+
+struct mthca_next_seg {
+	u32 nda_op;		/* [31:6] next WQE [4:0] next opcode */
+	u32 ee_nds;		/* [31:8] next EE  [7] DBD [6] F [5:0] next WQE size */
+	u32 flags;		/* [3] CQ [2] Event [1] Solicit */
+	u32 imm;		/* immediate data */
+};
+
+struct mthca_ud_seg {
+	u32 reserved1;
+	u32 lkey;
+	u64 av_addr;
+	u32 reserved2[4];
+	u32 dqpn;
+	u32 qkey;
+	u32 reserved3[2];
+};
+
+struct mthca_bind_seg {
+	u32 flags;		/* [31] Atomic [30] rem write [29] rem read */
+	u32 reserved;
+	u32 new_rkey;
+	u32 lkey;
+	u64 addr;
+	u64 length;
+};
+
+struct mthca_raddr_seg {
+	u64 raddr;
+	u32 rkey;
+	u32 reserved;
+};
+
+struct mthca_atomic_seg {
+	u64 swap_add;
+	u64 compare;
+};
+
+struct mthca_data_seg {
+	u32 byte_count;
+	u32 lkey;
+	u64 addr;
+};
+
+struct mthca_mlx_seg {
+	u32 nda_op;
+	u32 nds;
+	u32 flags;		/* [17] VL15 [16] SLR [14:12] static rate
+				   [11:8] SL [3] C [2] E */
+	u16 rlid;
+	u16 vcrc;
+};
+
+static int is_sqp(struct mthca_dev *dev, struct mthca_qp *qp)
+{
+	return qp->qpn >= dev->qp_table.sqp_start &&
+		qp->qpn <= dev->qp_table.sqp_start + 3;
+}
+
+static int is_qp0(struct mthca_dev *dev, struct mthca_qp *qp)
+{
+	return qp->qpn >= dev->qp_table.sqp_start &&
+		qp->qpn <= dev->qp_table.sqp_start + 1;
+}
+
+static void *get_recv_wqe(struct mthca_qp *qp, int n)
+{
+	if (qp->is_direct)
+		return qp->queue.direct.buf + (n << qp->rq.wqe_shift);
+	else
+		return qp->queue.page_list[(n << qp->rq.wqe_shift) >> PAGE_SHIFT].buf +
+			((n << qp->rq.wqe_shift) & (PAGE_SIZE - 1));
+}
+
+static void *get_send_wqe(struct mthca_qp *qp, int n)
+{
+	if (qp->is_direct)
+		return qp->queue.direct.buf + qp->send_wqe_offset +
+			(n << qp->sq.wqe_shift);
+	else
+		return qp->queue.page_list[(qp->send_wqe_offset +
+					    (n << qp->sq.wqe_shift)) >>
+					   PAGE_SHIFT].buf +
+			((qp->send_wqe_offset + (n << qp->sq.wqe_shift)) &
+			 (PAGE_SIZE - 1));
+}
+
+void mthca_qp_event(struct mthca_dev *dev, u32 qpn,
+		    enum ib_event_type event_type)
+{
+	struct mthca_qp *qp;
+	struct ib_event event;
+
+	spin_lock(&dev->qp_table.lock);
+	qp = mthca_array_get(&dev->qp_table.qp, qpn & (dev->limits.num_qps - 1));
+	if (qp)
+		atomic_inc(&qp->refcount);
+	spin_unlock(&dev->qp_table.lock);
+
+	if (!qp) {
+		mthca_warn(dev, "Async event for bogus QP %08x\n", qpn);
+		return;
+	}
+
+	event.device      = &dev->ib_dev;
+	event.event       = event_type;
+	event.element.qp  = &qp->ibqp;
+	if (qp->ibqp.event_handler)
+		qp->ibqp.event_handler(&event, qp->ibqp.qp_context);
+
+	if (atomic_dec_and_test(&qp->refcount))
+		wake_up(&qp->wait);
+}
+
+static int to_mthca_state(enum ib_qp_state ib_state)
+{
+	switch (ib_state) {
+	case IB_QPS_RESET: return MTHCA_QP_STATE_RST;
+	case IB_QPS_INIT:  return MTHCA_QP_STATE_INIT;
+	case IB_QPS_RTR:   return MTHCA_QP_STATE_RTR;
+	case IB_QPS_RTS:   return MTHCA_QP_STATE_RTS;
+	case IB_QPS_SQD:   return MTHCA_QP_STATE_SQD;
+	case IB_QPS_SQE:   return MTHCA_QP_STATE_SQE;
+	case IB_QPS_ERR:   return MTHCA_QP_STATE_ERR;
+	default:                return -1;
+	}
+}
+
+enum { RC, UC, UD, RD, RDEE, MLX, NUM_TRANS };
+
+static int to_mthca_st(int transport)
+{
+	switch (transport) {
+	case RC:  return MTHCA_QP_ST_RC;
+	case UC:  return MTHCA_QP_ST_UC;
+	case UD:  return MTHCA_QP_ST_UD;
+	case RD:  return MTHCA_QP_ST_RD;
+	case MLX: return MTHCA_QP_ST_MLX;
+	default:  return -1;
+	}
+}
+
+static const struct {
+	int trans;
+	u32 req_param[NUM_TRANS];
+	u32 opt_param[NUM_TRANS];
+} state_table[IB_QPS_ERR + 1][IB_QPS_ERR + 1] = {
+	[IB_QPS_RESET] = {
+		[IB_QPS_RESET] = { .trans = MTHCA_TRANS_ANY2RST },
+		[IB_QPS_ERR] = { .trans = MTHCA_TRANS_ANY2ERR },
+		[IB_QPS_INIT]  = {
+			.trans = MTHCA_TRANS_RST2INIT,
+			.req_param = {
+				[UD]  = (IB_QP_PKEY_INDEX |
+					 IB_QP_PORT       |
+					 IB_QP_QKEY),
+				[RC]  = (IB_QP_PKEY_INDEX |
+					 IB_QP_PORT       |
+					 IB_QP_ACCESS_FLAGS),
+				[MLX] = (IB_QP_PKEY_INDEX |
+					 IB_QP_QKEY),
+			},
+			/* bug-for-bug compatibility with VAPI: */
+			.opt_param = {
+				[MLX] = IB_QP_PORT
+			}
+		},
+	},
+	[IB_QPS_INIT]  = {
+		[IB_QPS_RESET] = { .trans = MTHCA_TRANS_ANY2RST },
+		[IB_QPS_ERR] = { .trans = MTHCA_TRANS_ANY2ERR },
+		[IB_QPS_INIT]  = {
+			.trans = MTHCA_TRANS_INIT2INIT,
+			.opt_param = {
+				[UD]  = (IB_QP_PKEY_INDEX |
+					 IB_QP_PORT       |
+					 IB_QP_QKEY),
+				[RC]  = (IB_QP_PKEY_INDEX |
+					 IB_QP_PORT       |
+					 IB_QP_ACCESS_FLAGS),
+				[MLX] = (IB_QP_PKEY_INDEX |
+					 IB_QP_QKEY),
+			}
+		},
+		[IB_QPS_RTR]   = {
+			.trans = MTHCA_TRANS_INIT2RTR,
+			.req_param = {
+				[RC]  = (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),
+			},
+			.opt_param = {
+				[UD]  = (IB_QP_PKEY_INDEX |
+					 IB_QP_QKEY),
+				[RC]  = (IB_QP_ALT_PATH     |
+					 IB_QP_ACCESS_FLAGS |
+					 IB_QP_PKEY_INDEX),
+				[MLX] = (IB_QP_PKEY_INDEX |
+					 IB_QP_QKEY),
+			}
+		}
+	},
+	[IB_QPS_RTR]   = {
+		[IB_QPS_RESET] = { .trans = MTHCA_TRANS_ANY2RST },
+		[IB_QPS_ERR] = { .trans = MTHCA_TRANS_ANY2ERR },
+		[IB_QPS_RTS]   = {
+			.trans = MTHCA_TRANS_RTR2RTS,
+			.req_param = {
+				[UD]  = IB_QP_SQ_PSN,
+				[RC]  = (IB_QP_TIMEOUT           |
+					 IB_QP_RETRY_CNT         |
+					 IB_QP_RNR_RETRY         |
+					 IB_QP_SQ_PSN            |
+					 IB_QP_MAX_QP_RD_ATOMIC),
+				[MLX] = IB_QP_SQ_PSN,
+			},
+			.opt_param = {
+				[UD]  = (IB_QP_CUR_STATE             |
+					 IB_QP_QKEY),
+				[RC]  = (IB_QP_CUR_STATE             |
+					 IB_QP_ALT_PATH              |
+					 IB_QP_ACCESS_FLAGS          |
+					 IB_QP_PKEY_INDEX            |
+					 IB_QP_MIN_RNR_TIMER         |
+					 IB_QP_PATH_MIG_STATE),
+				[MLX] = (IB_QP_CUR_STATE             |
+					 IB_QP_QKEY),
+			}
+		}
+	},
+	[IB_QPS_RTS]   = {
+		[IB_QPS_RESET] = { .trans = MTHCA_TRANS_ANY2RST },
+		[IB_QPS_ERR] = { .trans = MTHCA_TRANS_ANY2ERR },
+		[IB_QPS_RTS]   = {
+			.trans = MTHCA_TRANS_RTS2RTS,
+			.opt_param = {
+				[UD]  = (IB_QP_CUR_STATE             |
+					 IB_QP_QKEY),
+				[RC]  = (IB_QP_ACCESS_FLAGS          |
+					 IB_QP_ALT_PATH              |
+					 IB_QP_PATH_MIG_STATE        |
+					 IB_QP_MIN_RNR_TIMER),
+				[MLX] = (IB_QP_CUR_STATE             |
+					 IB_QP_QKEY),
+			}
+		},
+		[IB_QPS_SQD]   = {
+			.trans = MTHCA_TRANS_RTS2SQD,
+		},
+	},
+	[IB_QPS_SQD]   = {
+		[IB_QPS_RESET] = { .trans = MTHCA_TRANS_ANY2RST },
+		[IB_QPS_ERR] = { .trans = MTHCA_TRANS_ANY2ERR },
+		[IB_QPS_RTS]   = {
+			.trans = MTHCA_TRANS_SQD2RTS,
+			.opt_param = {
+				[UD]  = (IB_QP_CUR_STATE             |
+					 IB_QP_QKEY),
+				[RC]  = (IB_QP_CUR_STATE             |
+					 IB_QP_ALT_PATH              |
+					 IB_QP_ACCESS_FLAGS          |
+					 IB_QP_MIN_RNR_TIMER         |
+					 IB_QP_PATH_MIG_STATE),
+				[MLX] = (IB_QP_CUR_STATE             |
+					 IB_QP_QKEY),
+			}
+		},
+		[IB_QPS_SQD]   = {
+			.trans = MTHCA_TRANS_SQD2SQD,
+			.opt_param = {
+				[UD]  = (IB_QP_PKEY_INDEX            |
+					 IB_QP_QKEY),
+				[RC]  = (IB_QP_AV                    |
+					 IB_QP_TIMEOUT               |
+					 IB_QP_RETRY_CNT             |
+					 IB_QP_RNR_RETRY             |
+					 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_MIN_RNR_TIMER         |
+					 IB_QP_PATH_MIG_STATE),
+				[MLX] = (IB_QP_PKEY_INDEX            |
+					 IB_QP_QKEY),
+			}
+		}
+	},
+	[IB_QPS_SQE]   = {
+		[IB_QPS_RESET] = { .trans = MTHCA_TRANS_ANY2RST },
+		[IB_QPS_ERR] = { .trans = MTHCA_TRANS_ANY2ERR },
+		[IB_QPS_RTS]   = {
+			.trans = MTHCA_TRANS_SQERR2RTS,
+			.opt_param = {
+				[UD]  = (IB_QP_CUR_STATE             |
+					 IB_QP_QKEY),
+				[RC]  = (IB_QP_CUR_STATE             |
+					 IB_QP_MIN_RNR_TIMER),
+				[MLX] = (IB_QP_CUR_STATE             |
+					 IB_QP_QKEY),
+			}
+		}
+	},
+	[IB_QPS_ERR] = {
+		[IB_QPS_RESET] = { .trans = MTHCA_TRANS_ANY2RST },
+		[IB_QPS_ERR] = { .trans = MTHCA_TRANS_ANY2ERR }
+	}
+};
+
+static void store_attrs(struct mthca_sqp *sqp, struct ib_qp_attr *attr,
+			int attr_mask)
+{
+	if (attr_mask & IB_QP_PKEY_INDEX)
+		sqp->pkey_index = attr->pkey_index;
+	if (attr_mask & IB_QP_QKEY)
+		sqp->qkey = attr->qkey;
+	if (attr_mask & IB_QP_SQ_PSN)
+		sqp->send_psn = attr->sq_psn;
+}
+
+static void init_port(struct mthca_dev *dev, int port)
+{
+	int err;
+	u8 status;
+	struct mthca_init_ib_param param;
+
+	memset(&param, 0, sizeof param);
+
+	param.enable_1x = 1;
+	param.enable_4x = 1;
+	param.vl_cap    = dev->limits.vl_cap;
+	param.mtu_cap   = dev->limits.mtu_cap;
+	param.gid_cap   = dev->limits.gid_table_len;
+	param.pkey_cap  = dev->limits.pkey_table_len;
+
+	err = mthca_INIT_IB(dev, &param, port, &status);
+	if (err)
+		mthca_warn(dev, "INIT_IB failed, return code %d.\n", err);
+	if (status)
+		mthca_warn(dev, "INIT_IB returned status %02x.\n", status);
+}
+
+int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask)
+{
+	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_qp_param *qp_param;
+	struct mthca_qp_context *qp_context;
+	u32 req_param, opt_param;
+	u8 status;
+	int err;
+
+	if (attr_mask & IB_QP_CUR_STATE) {
+		if (attr->cur_qp_state != IB_QPS_RTR &&
+		    attr->cur_qp_state != IB_QPS_RTS &&
+		    attr->cur_qp_state != IB_QPS_SQD &&
+		    attr->cur_qp_state != IB_QPS_SQE)
+			return -EINVAL;
+		else
+			cur_state = attr->cur_qp_state;
+	} else {
+		spin_lock_irq(&qp->lock);
+		cur_state = qp->state;
+		spin_unlock_irq(&qp->lock);
+	}
+
+	if (attr_mask & IB_QP_STATE) {
+               if (attr->qp_state < 0 || attr->qp_state > IB_QPS_ERR)
+			return -EINVAL;
+		new_state = attr->qp_state;
+	} else
+		new_state = cur_state;
+
+	if (state_table[cur_state][new_state].trans == MTHCA_TRANS_INVALID) {
+		mthca_dbg(dev, "Illegal QP transition "
+			  "%d->%d\n", cur_state, new_state);
+		return -EINVAL;
+	}
+
+	req_param = state_table[cur_state][new_state].req_param[qp->transport];
+	opt_param = state_table[cur_state][new_state].opt_param[qp->transport];
+
+	if ((req_param & attr_mask) != req_param) {
+		mthca_dbg(dev, "QP transition "
+			  "%d->%d missing req attr 0x%08x\n",
+			  cur_state, new_state,
+			  req_param & ~attr_mask);
+		return -EINVAL;
+	}
+
+	if (attr_mask & ~(req_param | opt_param | IB_QP_STATE)) {
+		mthca_dbg(dev, "QP transition (transport %d) "
+			  "%d->%d has extra attr 0x%08x\n",
+			  qp->transport,
+			  cur_state, new_state,
+			  attr_mask & ~(req_param | opt_param |
+						 IB_QP_STATE));
+		return -EINVAL;
+	}
+
+	mailbox = kmalloc(sizeof (*qp_param) + MTHCA_CMD_MAILBOX_EXTRA, GFP_KERNEL);
+	if (!mailbox)
+		return -ENOMEM;
+	qp_param = MAILBOX_ALIGN(mailbox);
+	qp_context = &qp_param->context;
+	memset(qp_param, 0, sizeof *qp_param);
+
+	qp_context->flags      = cpu_to_be32((to_mthca_state(new_state) << 28) |
+					     (to_mthca_st(qp->transport) << 16));
+	qp_context->flags     |= cpu_to_be32(MTHCA_QP_BIT_DE);
+	if (!(attr_mask & IB_QP_PATH_MIG_STATE))
+		qp_context->flags |= cpu_to_be32(MTHCA_QP_PM_MIGRATED << 11);
+	else {
+		qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_PM_STATE);
+		switch (attr->path_mig_state) {
+		case IB_MIG_MIGRATED:
+			qp_context->flags |= cpu_to_be32(MTHCA_QP_PM_MIGRATED << 11);
+			break;
+		case IB_MIG_REARM:
+			qp_context->flags |= cpu_to_be32(MTHCA_QP_PM_REARM << 11);
+			break;
+		case IB_MIG_ARMED:
+			qp_context->flags |= cpu_to_be32(MTHCA_QP_PM_ARMED << 11);
+			break;
+		}
+	}
+	/* leave sched_queue as 0 */
+	if (qp->transport == MLX || qp->transport == UD)
+		qp_context->mtu_msgmax = cpu_to_be32((IB_MTU_2048 << 29) |
+						     (11 << 24));
+	else if (attr_mask & IB_QP_PATH_MTU) {
+		qp_context->mtu_msgmax = cpu_to_be32((attr->path_mtu << 29) |
+						     (31 << 24));
+	}
+	qp_context->usr_page   = cpu_to_be32(MTHCA_KAR_PAGE);
+	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);
+	}
+
+	if (qp->transport == MLX)
+		qp_context->pri_path.port_pkey |=
+			cpu_to_be32(to_msqp(qp)->port << 24);
+	else {
+		if (attr_mask & IB_QP_PORT) {
+			qp_context->pri_path.port_pkey |=
+				cpu_to_be32(attr->port_num << 24);
+			qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_PORT_NUM);
+		}
+	}
+
+	if (attr_mask & IB_QP_PKEY_INDEX) {
+		qp_context->pri_path.port_pkey |=
+			cpu_to_be32(attr->pkey_index);
+		qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_PKEY_INDEX);
+	}
+
+	if (attr_mask & IB_QP_RNR_RETRY) {
+		qp_context->pri_path.rnr_retry = attr->rnr_retry << 5;
+		qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RNR_RETRY);
+	}
+
+	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;
+		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;
+			qp_context->pri_path.hop_limit = attr->ah_attr.grh.hop_limit;
+			qp_context->pri_path.sl_tclass_flowlabel =
+				cpu_to_be32((attr->ah_attr.sl << 28)                |
+					    (attr->ah_attr.grh.traffic_class << 20) |
+					    (attr->ah_attr.grh.flow_label));
+			memcpy(qp_context->pri_path.rgid,
+			       attr->ah_attr.grh.dgid.raw, 16);
+		} else {
+			qp_context->pri_path.sl_tclass_flowlabel =
+				cpu_to_be32(attr->ah_attr.sl << 28);
+		}
+		qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_PRIMARY_ADDR_PATH);
+	}
+
+	if (attr_mask & IB_QP_TIMEOUT) {
+		qp_context->pri_path.ackto = attr->timeout;
+		qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_ACK_TIMEOUT);
+	}
+
+	/* XXX alt_path */
+
+	/* leave rdd as 0 */
+	qp_context->pd         = cpu_to_be32(to_mpd(ibqp->pd)->pd_num);
+	/* leave wqe_base as 0 (we always create an MR based at 0 for WQs) */
+	qp_context->wqe_lkey   = cpu_to_be32(qp->mr.ibmr.lkey);
+	qp_context->params1    = cpu_to_be32((MTHCA_ACK_REQ_FREQ << 28) |
+					     (MTHCA_FLIGHT_LIMIT << 24) |
+					     MTHCA_QP_BIT_SRE           |
+					     MTHCA_QP_BIT_SWE           |
+					     MTHCA_QP_BIT_SAE);
+	if (qp->sq.policy == IB_SIGNAL_ALL_WR)
+		qp_context->params1 |= cpu_to_be32(MTHCA_QP_BIT_SSC);
+	if (attr_mask & IB_QP_RETRY_CNT) {
+		qp_context->params1 |= cpu_to_be32(attr->retry_cnt << 16);
+		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,
+						       7) << 21);
+		qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_SRA_MAX);
+	}
+
+	if (attr_mask & IB_QP_SQ_PSN)
+		qp_context->next_send_psn = cpu_to_be32(attr->sq_psn);
+	qp_context->cqn_snd = cpu_to_be32(to_mcq(ibqp->send_cq)->cqn);
+
+	if (attr_mask & IB_QP_ACCESS_FLAGS) {
+		/*
+		 * Only enable RDMA/atomics if we have responder
+		 * resources set to a non-zero value.
+		 */
+		if (qp->resp_depth) {
+			qp_context->params2 |=
+				cpu_to_be32(attr->qp_access_flags & IB_ACCESS_REMOTE_WRITE ?
+					    MTHCA_QP_BIT_RWE : 0);
+			qp_context->params2 |=
+				cpu_to_be32(attr->qp_access_flags & IB_ACCESS_REMOTE_READ ?
+					    MTHCA_QP_BIT_RRE : 0);
+			qp_context->params2 |=
+				cpu_to_be32(attr->qp_access_flags & IB_ACCESS_REMOTE_ATOMIC ?
+					    MTHCA_QP_BIT_RAE : 0);
+		}
+
+		qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RWE |
+							MTHCA_QP_OPTPAR_RRE |
+							MTHCA_QP_OPTPAR_RAE);
+
+		qp->atomic_rd_en = attr->qp_access_flags;
+	}
+
+	if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC) {
+		u8 rra_max;
+
+		if (qp->resp_depth && !attr->max_rd_atomic) {
+			/*
+			 * Lowering our responder resources to zero.
+			 * Turn off RDMA/atomics as responder.
+			 * (RWE/RRE/RAE in params2 already zero)
+			 */
+			qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RWE |
+								MTHCA_QP_OPTPAR_RRE |
+								MTHCA_QP_OPTPAR_RAE);
+		}
+
+		if (!qp->resp_depth && attr->max_rd_atomic) {
+			/*
+			 * Increasing our responder resources from
+			 * zero.  Turn on RDMA/atomics as appropriate.
+			 */
+			qp_context->params2 |=
+				cpu_to_be32(qp->atomic_rd_en & IB_ACCESS_REMOTE_WRITE ?
+					    MTHCA_QP_BIT_RWE : 0);
+			qp_context->params2 |=
+				cpu_to_be32(qp->atomic_rd_en & IB_ACCESS_REMOTE_READ ?
+					    MTHCA_QP_BIT_RRE : 0);
+			qp_context->params2 |=
+				cpu_to_be32(qp->atomic_rd_en & IB_ACCESS_REMOTE_ATOMIC ?
+					    MTHCA_QP_BIT_RAE : 0);
+
+			qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RWE |
+								MTHCA_QP_OPTPAR_RRE |
+								MTHCA_QP_OPTPAR_RAE);
+		}
+
+		for (rra_max = 0;
+		     1 << rra_max < attr->max_rd_atomic &&
+			     rra_max < dev->qp_table.rdb_shift;
+		     ++rra_max)
+			; /* nothing */
+
+		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;
+	}
+
+	if (qp->rq.policy == IB_SIGNAL_ALL_WR)
+		qp_context->params2 |= cpu_to_be32(MTHCA_QP_BIT_RSC);
+	if (attr_mask & IB_QP_MIN_RNR_TIMER) {
+		qp_context->rnr_nextrecvpsn |= cpu_to_be32(attr->min_rnr_timer << 24);
+		qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RNR_TIMEOUT);
+	}
+	if (attr_mask & IB_QP_RQ_PSN)
+		qp_context->rnr_nextrecvpsn |= cpu_to_be32(attr->rq_psn);
+
+	qp_context->ra_buff_indx = dev->qp_table.rdb_base +
+		((qp->qpn & (dev->limits.num_qps - 1)) * MTHCA_RDB_ENTRY_SIZE <<
+		 dev->qp_table.rdb_shift);
+
+	qp_context->cqn_rcv = cpu_to_be32(to_mcq(ibqp->recv_cq)->cqn);
+
+	if (attr_mask & IB_QP_QKEY) {
+		qp_context->qkey = cpu_to_be32(attr->qkey);
+		qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_Q_KEY);
+	}
+
+	err = mthca_MODIFY_QP(dev, state_table[cur_state][new_state].trans,
+			      qp->qpn, 0, qp_param, 0, &status);
+	if (status) {
+		mthca_warn(dev, "modify QP %d returned status %02x.\n",
+			   state_table[cur_state][new_state].trans, status);
+		err = -EINVAL;
+	}
+
+	if (!err)
+		qp->state = new_state;
+
+	kfree(mailbox);
+
+	if (is_sqp(dev, qp))
+		store_attrs(to_msqp(qp), attr, attr_mask);
+
+	/*
+	 * If we are moving QP0 to RTR, bring the IB link up; if we
+	 * are moving QP0 to RESET or ERROR, bring the link back down.
+	 */
+	if (is_qp0(dev, qp)) {
+		if (cur_state != IB_QPS_RTR &&
+		    new_state == IB_QPS_RTR)
+			init_port(dev, to_msqp(qp)->port);
+
+		if (cur_state != IB_QPS_RESET &&
+		    cur_state != IB_QPS_ERR &&
+		    (new_state == IB_QPS_RESET ||
+		     new_state == IB_QPS_ERR))
+			mthca_CLOSE_IB(dev, to_msqp(qp)->port, &status);
+	}
+
+	return err;
+}
+
+/*
+ * Allocate and register buffer for WQEs.  qp->rq.max, sq.max,
+ * rq.max_gs and sq.max_gs must all be assigned.
+ * mthca_alloc_wqe_buf will calculate rq.wqe_shift and
+ * sq.wqe_shift (as well as send_wqe_offset, is_direct, and
+ * queue)
+ */
+static int mthca_alloc_wqe_buf(struct mthca_dev *dev,
+			       struct mthca_pd *pd,
+			       struct mthca_qp *qp)
+{
+	int size;
+	int i;
+	int npages, shift;
+	dma_addr_t t;
+	u64 *dma_list = NULL;
+	int err = -ENOMEM;
+
+	size = sizeof (struct mthca_next_seg) +
+		qp->rq.max_gs * sizeof (struct mthca_data_seg);
+
+	for (qp->rq.wqe_shift = 6; 1 << qp->rq.wqe_shift < size;
+	     qp->rq.wqe_shift++)
+		; /* nothing */
+
+	size = sizeof (struct mthca_next_seg) +
+		qp->sq.max_gs * sizeof (struct mthca_data_seg);
+	if (qp->transport == MLX)
+		size += 2 * sizeof (struct mthca_data_seg);
+	else if (qp->transport == UD)
+		size += sizeof (struct mthca_ud_seg);
+	else /* bind seg is as big as atomic + raddr segs */
+		size += sizeof (struct mthca_bind_seg);
+
+	for (qp->sq.wqe_shift = 6; 1 << qp->sq.wqe_shift < size;
+	     qp->sq.wqe_shift++)
+		; /* nothing */
+
+	qp->send_wqe_offset = ALIGN(qp->rq.max << qp->rq.wqe_shift,
+				    1 << qp->sq.wqe_shift);
+	size = PAGE_ALIGN(qp->send_wqe_offset +
+			  (qp->sq.max << qp->sq.wqe_shift));
+
+	qp->wrid = kmalloc((qp->rq.max + qp->sq.max) * sizeof (u64),
+			   GFP_KERNEL);
+	if (!qp->wrid)
+		goto err_out;
+
+	if (size <= MTHCA_MAX_DIRECT_QP_SIZE) {
+		qp->is_direct = 1;
+		npages = 1;
+		shift = get_order(size) + PAGE_SHIFT;
+
+		if (0)
+			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);
+		if (!qp->queue.direct.buf)
+			goto err_out;
+
+		pci_unmap_addr_set(&qp->queue.direct, mapping, t);
+
+		memset(qp->queue.direct.buf, 0, size);
+
+		while (t & ((1 << shift) - 1)) {
+			--shift;
+			npages *= 2;
+		}
+
+		dma_list = kmalloc(npages * sizeof *dma_list, GFP_KERNEL);
+		if (!dma_list)
+			goto err_out_free;
+
+		for (i = 0; i < npages; ++i)
+			dma_list[i] = t + i * (1 << shift);
+	} else {
+		qp->is_direct = 0;
+		npages = size / PAGE_SIZE;
+		shift = PAGE_SHIFT;
+
+		if (0)
+			mthca_dbg(dev, "Creating indirect QP with %d pages\n", npages);
+
+		dma_list = kmalloc(npages * sizeof *dma_list, GFP_KERNEL);
+		if (!dma_list)
+			goto err_out;
+
+		qp->queue.page_list = kmalloc(npages *
+					      sizeof *qp->queue.page_list,
+					      GFP_KERNEL);
+		if (!qp->queue.page_list)
+			goto err_out;
+
+		for (i = 0; i < npages; ++i) {
+			qp->queue.page_list[i].buf =
+				pci_alloc_consistent(dev->pdev, PAGE_SIZE, &t);
+			if (!qp->queue.page_list[i].buf)
+				goto err_out_free;
+
+			memset(qp->queue.page_list[i].buf, 0, PAGE_SIZE);
+
+			pci_unmap_addr_set(&qp->queue.page_list[i], mapping, t);
+			dma_list[i] = t;
+		}
+	}
+
+	err = mthca_mr_alloc_phys(dev, pd->pd_num, dma_list, shift,
+				  npages, 0, size,
+				  MTHCA_MPT_FLAG_LOCAL_WRITE |
+				  MTHCA_MPT_FLAG_LOCAL_READ,
+				  &qp->mr);
+	if (err)
+		goto err_out_free;
+
+	kfree(dma_list);
+	return 0;
+
+ err_out_free:
+	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 < 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));
+
+		}
+
+ err_out:
+	kfree(qp->wrid);
+	kfree(dma_list);
+	return err;
+}
+
+static int mthca_alloc_qp_common(struct mthca_dev *dev,
+				 struct mthca_pd *pd,
+				 struct mthca_cq *send_cq,
+				 struct mthca_cq *recv_cq,
+				 enum ib_sig_type send_policy,
+				 enum ib_sig_type recv_policy,
+				 struct mthca_qp *qp)
+{
+	int err;
+
+	spin_lock_init(&qp->lock);
+	atomic_set(&qp->refcount, 1);
+	qp->state    	 = IB_QPS_RESET;
+	qp->atomic_rd_en = 0;
+	qp->resp_depth   = 0;
+	qp->sq.policy    = send_policy;
+	qp->rq.policy    = recv_policy;
+	qp->rq.cur       = 0;
+	qp->sq.cur       = 0;
+	qp->rq.next      = 0;
+	qp->sq.next      = 0;
+	qp->rq.last_comp = qp->rq.max - 1;
+	qp->sq.last_comp = qp->sq.max - 1;
+	qp->rq.last      = NULL;
+	qp->sq.last      = NULL;
+
+	err = mthca_alloc_wqe_buf(dev, pd, qp);
+	return err;
+}
+
+int mthca_alloc_qp(struct mthca_dev *dev,
+		   struct mthca_pd *pd,
+		   struct mthca_cq *send_cq,
+		   struct mthca_cq *recv_cq,
+		   enum ib_qp_type type,
+		   enum ib_sig_type send_policy,
+		   enum ib_sig_type recv_policy,
+		   struct mthca_qp *qp)
+{
+	int err;
+
+	switch (type) {
+	case IB_QPT_RC: qp->transport = RC; break;
+	case IB_QPT_UC: qp->transport = UC; break;
+	case IB_QPT_UD: qp->transport = UD; break;
+	default: return -EINVAL;
+	}
+
+	qp->qpn = mthca_alloc(&dev->qp_table.alloc);
+	if (qp->qpn == -1)
+		return -ENOMEM;
+
+	err = mthca_alloc_qp_common(dev, pd, send_cq, recv_cq,
+				    send_policy, recv_policy, qp);
+	if (err) {
+		mthca_free(&dev->qp_table.alloc, qp->qpn);
+		return err;
+	}
+
+	spin_lock_irq(&dev->qp_table.lock);
+	mthca_array_set(&dev->qp_table.qp,
+			qp->qpn & (dev->limits.num_qps - 1), qp);
+	spin_unlock_irq(&dev->qp_table.lock);
+
+	return 0;
+}
+
+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,
+		    enum ib_sig_type recv_policy,
+		    int qpn,
+		    int port,
+		    struct mthca_sqp *sqp)
+{
+	int err = 0;
+	u32 mqpn = qpn * 2 + dev->qp_table.sqp_start + port - 1;
+
+	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,
+					     &sqp->header_dma, GFP_KERNEL);
+	if (!sqp->header_buf)
+		return -ENOMEM;
+
+	spin_lock_irq(&dev->qp_table.lock);
+	if (mthca_array_get(&dev->qp_table.qp, mqpn))
+		err = -EBUSY;
+	else
+		mthca_array_set(&dev->qp_table.qp, mqpn, sqp);
+	spin_unlock_irq(&dev->qp_table.lock);
+
+	if (err)
+		goto err_out;
+
+	sqp->port = port;
+	sqp->qp.qpn       = mqpn;
+	sqp->qp.transport = MLX;
+
+	err = mthca_alloc_qp_common(dev, pd, send_cq, recv_cq,
+				    send_policy, recv_policy,
+				    &sqp->qp);
+	if (err)
+		goto err_out_free;
+
+	atomic_inc(&pd->sqp_count);
+
+	return 0;
+
+ err_out_free:
+	spin_lock_irq(&dev->qp_table.lock);
+	mthca_array_clear(&dev->qp_table.qp, mqpn);
+	spin_unlock_irq(&dev->qp_table.lock);
+
+ err_out:
+	dma_free_coherent(&dev->pdev->dev, sqp->header_buf_size,
+			  sqp->header_buf, sqp->header_dma);
+
+	return err;
+}
+
+void mthca_free_qp(struct mthca_dev *dev,
+		   struct mthca_qp *qp)
+{
+	u8 status;
+	int size;
+	int i;
+
+	spin_lock_irq(&dev->qp_table.lock);
+	mthca_array_clear(&dev->qp_table.qp,
+			  qp->qpn & (dev->limits.num_qps - 1));
+	spin_unlock_irq(&dev->qp_table.lock);
+
+	atomic_dec(&qp->refcount);
+	wait_event(qp->wait, !atomic_read(&qp->refcount));
+
+	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 (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));
+		}
+	}
+
+	kfree(qp->wrid);
+
+	if (is_sqp(dev, qp)) {
+		atomic_dec(&(to_mpd(qp->ibqp.pd)->sqp_count));
+		dma_free_coherent(&dev->pdev->dev,
+				  to_msqp(qp)->header_buf_size,
+				  to_msqp(qp)->header_buf,
+				  to_msqp(qp)->header_dma);
+	}
+	else
+		mthca_free(&dev->qp_table.alloc, qp->qpn);
+}
+
+/* Create UD header for an MLX send and build a data segment for it */
+static int build_mlx_header(struct mthca_dev *dev, struct mthca_sqp *sqp,
+			    int ind, struct ib_send_wr *wr,
+			    struct mthca_mlx_seg *mlx,
+			    struct mthca_data_seg *data)
+{
+	int header_size;
+	int err;
+
+	ib_ud_header_init(256, /* assume a MAD */
+			  sqp->ud_header.grh_present,
+			  &sqp->ud_header);
+
+	err = mthca_read_ah(dev, to_mah(wr->wr.ud.ah), &sqp->ud_header);
+	if (err)
+		return err;
+	mlx->flags &= ~cpu_to_be32(MTHCA_NEXT_SOLICIT | 1);
+	mlx->flags |= cpu_to_be32((!sqp->qp.ibqp.qp_num ? MTHCA_MLX_VL15 : 0) |
+				  (sqp->ud_header.lrh.destination_lid == 0xffff ?
+				   MTHCA_MLX_SLR : 0) |
+				  (sqp->ud_header.lrh.service_level << 8));
+	mlx->rlid = sqp->ud_header.lrh.destination_lid;
+	mlx->vcrc = 0;
+
+	switch (wr->opcode) {
+	case IB_WR_SEND:
+		sqp->ud_header.bth.opcode = IB_OPCODE_UD_SEND_ONLY;
+		sqp->ud_header.immediate_present = 0;
+		break;
+	case IB_WR_SEND_WITH_IMM:
+		sqp->ud_header.bth.opcode = IB_OPCODE_UD_SEND_ONLY_WITH_IMMEDIATE;
+		sqp->ud_header.immediate_present = 1;
+		sqp->ud_header.immediate_data = wr->imm_data;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	sqp->ud_header.lrh.virtual_lane    = !sqp->qp.ibqp.qp_num ? 15 : 0;
+	if (sqp->ud_header.lrh.destination_lid == 0xffff)
+		sqp->ud_header.lrh.source_lid = 0xffff;
+	sqp->ud_header.bth.solicited_event = !!(wr->send_flags & IB_SEND_SOLICITED);
+	if (!sqp->qp.ibqp.qp_num)
+		ib_get_cached_pkey(&dev->ib_dev, sqp->port,
+				   sqp->pkey_index,
+				   &sqp->ud_header.bth.pkey);
+	else
+		ib_get_cached_pkey(&dev->ib_dev, sqp->port,
+				   wr->wr.ud.pkey_index,
+				   &sqp->ud_header.bth.pkey);
+	cpu_to_be16s(&sqp->ud_header.bth.pkey);
+	sqp->ud_header.bth.destination_qpn = cpu_to_be32(wr->wr.ud.remote_qpn);
+	sqp->ud_header.bth.psn = cpu_to_be32((sqp->send_psn++) & ((1 << 24) - 1));
+	sqp->ud_header.deth.qkey = cpu_to_be32(wr->wr.ud.remote_qkey & 0x80000000 ?
+					       sqp->qkey : wr->wr.ud.remote_qkey);
+	sqp->ud_header.deth.source_qpn = cpu_to_be32(sqp->qp.ibqp.qp_num);
+
+	header_size = ib_ud_header_pack(&sqp->ud_header,
+					sqp->header_buf +
+					ind * MTHCA_UD_HEADER_SIZE);
+
+	data->byte_count = cpu_to_be32(header_size);
+	data->lkey       = cpu_to_be32(to_mpd(sqp->qp.ibqp.pd)->ntmr.ibmr.lkey);
+	data->addr       = cpu_to_be64(sqp->header_dma +
+				       ind * MTHCA_UD_HEADER_SIZE);
+
+	return 0;
+}
+
+int mthca_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
+		    struct ib_send_wr **bad_wr)
+{
+	struct mthca_dev *dev = to_mdev(ibqp->device);
+	struct mthca_qp *qp = to_mqp(ibqp);
+	void *wqe;
+	void *prev_wqe;
+	unsigned long flags;
+	int err = 0;
+	int nreq;
+	int i;
+	int size;
+	int size0 = 0;
+	u32 f0 = 0;
+	int ind;
+	u8 op0 = 0;
+
+	static const u8 opcode[] = {
+		[IB_WR_SEND]                 = MTHCA_OPCODE_SEND,
+		[IB_WR_SEND_WITH_IMM]        = MTHCA_OPCODE_SEND_IMM,
+		[IB_WR_RDMA_WRITE]           = MTHCA_OPCODE_RDMA_WRITE,
+		[IB_WR_RDMA_WRITE_WITH_IMM]  = MTHCA_OPCODE_RDMA_WRITE_IMM,
+		[IB_WR_RDMA_READ]            = MTHCA_OPCODE_RDMA_READ,
+		[IB_WR_ATOMIC_CMP_AND_SWP]   = MTHCA_OPCODE_ATOMIC_CS,
+		[IB_WR_ATOMIC_FETCH_AND_ADD] = MTHCA_OPCODE_ATOMIC_FA,
+	};
+
+	spin_lock_irqsave(&qp->lock, flags);
+
+	/* XXX check that state is OK to post send */
+
+	ind = qp->sq.next;
+
+	for (nreq = 0; wr; ++nreq, wr = wr->next) {
+		if (qp->sq.cur + nreq >= qp->sq.max) {
+			mthca_err(dev, "SQ full (%d posted, %d max, %d nreq)\n",
+				  qp->sq.cur, qp->sq.max, nreq);
+			err = -ENOMEM;
+			*bad_wr = wr;
+			goto out;
+		}
+
+		wqe = get_send_wqe(qp, ind);
+		prev_wqe = qp->sq.last;
+		qp->sq.last = wqe;
+
+		((struct mthca_next_seg *) wqe)->nda_op = 0;
+		((struct mthca_next_seg *) wqe)->ee_nds = 0;
+		((struct mthca_next_seg *) wqe)->flags =
+			((wr->send_flags & IB_SEND_SIGNALED) ?
+			 cpu_to_be32(MTHCA_NEXT_CQ_UPDATE) : 0) |
+			((wr->send_flags & IB_SEND_SOLICITED) ?
+			 cpu_to_be32(MTHCA_NEXT_SOLICIT) : 0)   |
+			cpu_to_be32(1);
+		if (wr->opcode == IB_WR_SEND_WITH_IMM ||
+		    wr->opcode == IB_WR_RDMA_WRITE_WITH_IMM)
+			((struct mthca_next_seg *) wqe)->flags = wr->imm_data;
+
+		wqe += sizeof (struct mthca_next_seg);
+		size = sizeof (struct mthca_next_seg) / 16;
+
+		switch (qp->transport) {
+		case RC:
+			switch (wr->opcode) {
+			case IB_WR_ATOMIC_CMP_AND_SWP:
+			case IB_WR_ATOMIC_FETCH_AND_ADD:
+				((struct mthca_raddr_seg *) wqe)->raddr =
+					cpu_to_be64(wr->wr.atomic.remote_addr);
+				((struct mthca_raddr_seg *) wqe)->rkey =
+					cpu_to_be32(wr->wr.atomic.rkey);
+				((struct mthca_raddr_seg *) wqe)->reserved = 0;
+
+				wqe += sizeof (struct mthca_raddr_seg);
+
+				if (wr->opcode == IB_WR_ATOMIC_CMP_AND_SWP) {
+					((struct mthca_atomic_seg *) wqe)->swap_add =
+						cpu_to_be64(wr->wr.atomic.swap);
+					((struct mthca_atomic_seg *) wqe)->compare =
+						cpu_to_be64(wr->wr.atomic.compare_add);
+				} else {
+					((struct mthca_atomic_seg *) wqe)->swap_add =
+						cpu_to_be64(wr->wr.atomic.compare_add);
+					((struct mthca_atomic_seg *) wqe)->compare = 0;
+				}
+
+				wqe += sizeof (struct mthca_atomic_seg);
+				size += sizeof (struct mthca_raddr_seg) / 16 +
+					sizeof (struct mthca_atomic_seg);
+				break;
+
+			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 =
+					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_ud_seg *) wqe)->lkey =
+				cpu_to_be32(to_mah(wr->wr.ud.ah)->key);
+			((struct mthca_ud_seg *) wqe)->av_addr =
+				cpu_to_be64(to_mah(wr->wr.ud.ah)->avdma);
+			((struct mthca_ud_seg *) wqe)->dqpn =
+				cpu_to_be32(wr->wr.ud.remote_qpn);
+			((struct mthca_ud_seg *) wqe)->qkey =
+				cpu_to_be32(wr->wr.ud.remote_qkey);
+
+			wqe += sizeof (struct mthca_ud_seg);
+			size += sizeof (struct mthca_ud_seg) / 16;
+			break;
+
+		case MLX:
+			err = build_mlx_header(dev, to_msqp(qp), ind, wr,
+					       wqe - sizeof (struct mthca_next_seg),
+					       wqe);
+			if (err) {
+				*bad_wr = wr;
+				goto out;
+			}
+			wqe += sizeof (struct mthca_data_seg);
+			size += sizeof (struct mthca_data_seg) / 16;
+			break;
+		}
+
+		if (wr->num_sge > qp->sq.max_gs) {
+			mthca_err(dev, "too many gathers\n");
+			err = -EINVAL;
+			*bad_wr = wr;
+			goto out;
+		}
+
+		for (i = 0; i < wr->num_sge; ++i) {
+			((struct mthca_data_seg *) wqe)->byte_count =
+				cpu_to_be32(wr->sg_list[i].length);
+			((struct mthca_data_seg *) wqe)->lkey =
+				cpu_to_be32(wr->sg_list[i].lkey);
+			((struct mthca_data_seg *) wqe)->addr =
+				cpu_to_be64(wr->sg_list[i].addr);
+			wqe += sizeof (struct mthca_data_seg);
+			size += sizeof (struct mthca_data_seg) / 16;
+		}
+
+		/* Add one more inline data segment for ICRC */
+		if (qp->transport == MLX) {
+			((struct mthca_data_seg *) wqe)->byte_count =
+				cpu_to_be32((1 << 31) | 4);
+			((u32 *) wqe)[1] = 0;
+			wqe += sizeof (struct mthca_data_seg);
+			size += sizeof (struct mthca_data_seg) / 16;
+		}
+
+		qp->wrid[ind + qp->rq.max] = wr->wr_id;
+
+		if (wr->opcode >= ARRAY_SIZE(opcode)) {
+			mthca_err(dev, "opcode invalid\n");
+			err = -EINVAL;
+			*bad_wr = wr;
+			goto out;
+		}
+
+		if (prev_wqe) {
+			((struct mthca_next_seg *) prev_wqe)->nda_op =
+				cpu_to_be32(((ind << qp->sq.wqe_shift) +
+					     qp->send_wqe_offset) |
+					    opcode[wr->opcode]);
+			smp_wmb();
+			((struct mthca_next_seg *) prev_wqe)->ee_nds =
+				cpu_to_be32((size0 ? 0 : MTHCA_NEXT_DBD) | size);
+		}
+
+		if (!size0) {
+			size0 = size;
+			op0   = opcode[wr->opcode];
+		}
+
+		++ind;
+		if (unlikely(ind >= qp->sq.max))
+			ind -= qp->sq.max;
+	}
+
+out:
+	if (nreq) {
+		u32 doorbell[2];
+
+		doorbell[0] = cpu_to_be32(((qp->sq.next << qp->sq.wqe_shift) +
+					   qp->send_wqe_offset) | f0 | op0);
+		doorbell[1] = cpu_to_be32((qp->qpn << 8) | size0);
+
+		wmb();
+
+		mthca_write64(doorbell,
+			      dev->kar + MTHCA_SEND_DOORBELL,
+			      MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
+	}
+
+	qp->sq.cur += nreq;
+	qp->sq.next = ind;
+
+	spin_unlock_irqrestore(&qp->lock, flags);
+	return err;
+}
+
+int mthca_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr,
+		       struct ib_recv_wr **bad_wr)
+{
+	struct mthca_dev *dev = to_mdev(ibqp->device);
+	struct mthca_qp *qp = to_mqp(ibqp);
+	unsigned long flags;
+	int err = 0;
+	int nreq;
+	int i;
+	int size;
+	int size0 = 0;
+	int ind;
+	void *wqe;
+	void *prev_wqe;
+
+	spin_lock_irqsave(&qp->lock, flags);
+
+	/* XXX check that state is OK to post receive */
+
+	ind = qp->rq.next;
+
+	for (nreq = 0; wr; ++nreq, wr = wr->next) {
+		if (qp->rq.cur + nreq >= qp->rq.max) {
+			mthca_err(dev, "RQ %06x full\n", qp->qpn);
+			err = -ENOMEM;
+			*bad_wr = wr;
+			goto out;
+		}
+
+		wqe = get_recv_wqe(qp, ind);
+		prev_wqe = qp->rq.last;
+		qp->rq.last = wqe;
+
+		((struct mthca_next_seg *) wqe)->nda_op = 0;
+		((struct mthca_next_seg *) wqe)->ee_nds =
+			cpu_to_be32(MTHCA_NEXT_DBD);
+		((struct mthca_next_seg *) wqe)->flags =
+			(wr->recv_flags & IB_RECV_SIGNALED) ?
+			cpu_to_be32(MTHCA_NEXT_CQ_UPDATE) : 0;
+
+		wqe += sizeof (struct mthca_next_seg);
+		size = sizeof (struct mthca_next_seg) / 16;
+
+		if (wr->num_sge > qp->rq.max_gs) {
+			err = -EINVAL;
+			*bad_wr = wr;
+			goto out;
+		}
+
+		for (i = 0; i < wr->num_sge; ++i) {
+			((struct mthca_data_seg *) wqe)->byte_count =
+				cpu_to_be32(wr->sg_list[i].length);
+			((struct mthca_data_seg *) wqe)->lkey =
+				cpu_to_be32(wr->sg_list[i].lkey);
+			((struct mthca_data_seg *) wqe)->addr =
+				cpu_to_be64(wr->sg_list[i].addr);
+			wqe += sizeof (struct mthca_data_seg);
+			size += sizeof (struct mthca_data_seg) / 16;
+		}
+
+		qp->wrid[ind] = wr->wr_id;
+
+		if (prev_wqe) {
+			((struct mthca_next_seg *) prev_wqe)->nda_op =
+				cpu_to_be32((ind << qp->rq.wqe_shift) | 1);
+			smp_wmb();
+			((struct mthca_next_seg *) prev_wqe)->ee_nds =
+				cpu_to_be32(MTHCA_NEXT_DBD | size);
+		}
+
+		if (!size0)
+			size0 = size;
+
+		++ind;
+		if (unlikely(ind >= qp->rq.max))
+			ind -= qp->rq.max;
+	}
+
+out:
+	if (nreq) {
+		u32 doorbell[2];
+
+		doorbell[0] = cpu_to_be32((qp->rq.next << qp->rq.wqe_shift) | size0);
+		doorbell[1] = cpu_to_be32((qp->qpn << 8) | nreq);
+
+		wmb();
+
+		mthca_write64(doorbell,
+			      dev->kar + MTHCA_RECEIVE_DOORBELL,
+			      MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
+	}
+
+	qp->rq.cur += nreq;
+	qp->rq.next = ind;
+
+	spin_unlock_irqrestore(&qp->lock, flags);
+	return err;
+}
+
+int mthca_free_err_wqe(struct mthca_qp *qp, int is_send,
+		       int index, int *dbd, u32 *new_wqe)
+{
+	struct mthca_next_seg *next;
+
+	if (is_send)
+		next = get_send_wqe(qp, index);
+	else
+		next = get_recv_wqe(qp, index);
+
+	*dbd = !!(next->ee_nds & cpu_to_be32(MTHCA_NEXT_DBD));
+	if (next->ee_nds & cpu_to_be32(0x3f))
+		*new_wqe = (next->nda_op & cpu_to_be32(~0x3f)) |
+			(next->ee_nds & cpu_to_be32(0x3f));
+	else
+		*new_wqe = 0;
+
+	return 0;
+}
+
+int __devinit mthca_init_qp_table(struct mthca_dev *dev)
+{
+	int err;
+	u8 status;
+	int i;
+
+	spin_lock_init(&dev->qp_table.lock);
+
+	/*
+	 * We reserve 2 extra QPs per port for the special QPs.  The
+	 * special QP for port 1 has to be even, so round up.
+	 */
+	dev->qp_table.sqp_start = (dev->limits.reserved_qps + 1) & ~1UL;
+	err = mthca_alloc_init(&dev->qp_table.alloc,
+			       dev->limits.num_qps,
+			       (1 << 24) - 1,
+			       dev->qp_table.sqp_start +
+			       MTHCA_MAX_PORTS * 2);
+	if (err)
+		return err;
+
+	err = mthca_array_init(&dev->qp_table.qp,
+			       dev->limits.num_qps);
+	if (err) {
+		mthca_alloc_cleanup(&dev->qp_table.alloc);
+		return err;
+	}
+
+	for (i = 0; i < 2; ++i) {
+		err = mthca_CONF_SPECIAL_QP(dev, i ? IB_QPT_GSI : IB_QPT_SMI,
+					    dev->qp_table.sqp_start + i * 2,
+					    &status);
+		if (err)
+			goto err_out;
+		if (status) {
+			mthca_warn(dev, "CONF_SPECIAL_QP returned "
+				   "status %02x, aborting.\n",
+				   status);
+			err = -EINVAL;
+			goto err_out;
+		}
+	}
+	return 0;
+
+ err_out:
+	for (i = 0; i < 2; ++i)
+		mthca_CONF_SPECIAL_QP(dev, i, 0, &status);
+
+	mthca_array_cleanup(&dev->qp_table.qp, dev->limits.num_qps);
+	mthca_alloc_cleanup(&dev->qp_table.alloc);
+
+	return err;
+}
+
+void __devexit mthca_cleanup_qp_table(struct mthca_dev *dev)
+{
+	int i;
+	u8 status;
+
+	for (i = 0; i < 2; ++i)
+		mthca_CONF_SPECIAL_QP(dev, i, 0, &status);
+
+	mthca_alloc_cleanup(&dev->qp_table.alloc);
+}
diff -Nru a/drivers/infiniband/hw/mthca/mthca_reset.c b/drivers/infiniband/hw/mthca/mthca_reset.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/infiniband/hw/mthca/mthca_reset.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,232 @@
+/*
+ * Copyright (c) 2004 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: mthca_reset.c 1349 2004-12-16 21:09:43Z roland $
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+
+#include "mthca_dev.h"
+#include "mthca_cmd.h"
+
+int mthca_reset(struct mthca_dev *mdev)
+{
+	int i;
+	int err = 0;
+	u32 *hca_header    = NULL;
+	u32 *bridge_header = NULL;
+	struct pci_dev *bridge = NULL;
+
+#define MTHCA_RESET_OFFSET 0xf0010
+#define MTHCA_RESET_VALUE  cpu_to_be32(1)
+
+	/*
+	 * Reset the chip.  This is somewhat ugly because we have to
+	 * save off the PCI header before reset and then restore it
+	 * after the chip reboots.  We skip config space offsets 22
+	 * and 23 since those have a special meaning.
+	 *
+	 * To make matters worse, for Tavor (PCI-X HCA) we have to
+	 * find the associated bridge device and save off its PCI
+	 * header as well.
+	 */
+
+	if (mdev->hca_type == TAVOR) {
+		/* Look for the bridge -- its device ID will be 2 more
+		   than HCA's device ID. */
+		while ((bridge = pci_get_device(mdev->pdev->vendor,
+						mdev->pdev->device + 2,
+						bridge)) != NULL) {
+			if (bridge->hdr_type    == PCI_HEADER_TYPE_BRIDGE &&
+			    bridge->subordinate == mdev->pdev->bus) {
+				mthca_dbg(mdev, "Found bridge: %s (%s)\n",
+					  pci_pretty_name(bridge), pci_name(bridge));
+				break;
+			}
+		}
+
+		if (!bridge) {
+			/*
+			 * Didn't find a bridge for a Tavor device --
+			 * assume we're in no-bridge mode and hope for
+			 * the best.
+			 */
+			mthca_warn(mdev, "No bridge found for %s (%s)\n",
+				  pci_pretty_name(mdev->pdev), pci_name(mdev->pdev));
+		}
+
+	}
+
+	/* For Arbel do we need to save off the full 4K PCI Express header?? */
+	hca_header = kmalloc(256, GFP_KERNEL);
+	if (!hca_header) {
+		err = -ENOMEM;
+		mthca_err(mdev, "Couldn't allocate memory to save HCA "
+			  "PCI header, aborting.\n");
+		goto out;
+	}
+
+	for (i = 0; i < 64; ++i) {
+		if (i == 22 || i == 23)
+			continue;
+		if (pci_read_config_dword(mdev->pdev, i * 4, hca_header + i)) {
+			err = -ENODEV;
+			mthca_err(mdev, "Couldn't save HCA "
+				  "PCI header, aborting.\n");
+			goto out;
+		}
+	}
+
+	if (bridge) {
+		bridge_header = kmalloc(256, GFP_KERNEL);
+		if (!bridge_header) {
+			err = -ENOMEM;
+			mthca_err(mdev, "Couldn't allocate memory to save HCA "
+				  "bridge PCI header, aborting.\n");
+			goto out;
+		}
+
+		for (i = 0; i < 64; ++i) {
+			if (i == 22 || i == 23)
+				continue;
+			if (pci_read_config_dword(bridge, i * 4, bridge_header + i)) {
+				err = -ENODEV;
+				mthca_err(mdev, "Couldn't save HCA bridge "
+					  "PCI header, aborting.\n");
+				goto out;
+			}
+		}
+	}
+
+	/* actually hit reset */
+	{
+		void __iomem *reset = ioremap(pci_resource_start(mdev->pdev, 0) +
+					      MTHCA_RESET_OFFSET, 4);
+
+		if (!reset) {
+			err = -ENOMEM;
+			mthca_err(mdev, "Couldn't map HCA reset register, "
+				  "aborting.\n");
+			goto out;
+		}
+
+		writel(MTHCA_RESET_VALUE, reset);
+		iounmap(reset);
+	}
+
+	/* Docs say to wait one second before accessing device */
+	msleep(1000);
+
+	/* Now wait for PCI device to start responding again */
+	{
+		u32 v;
+		int c = 0;
+
+		for (c = 0; c < 100; ++c) {
+			if (pci_read_config_dword(bridge ? bridge : mdev->pdev, 0, &v)) {
+				err = -ENODEV;
+				mthca_err(mdev, "Couldn't access HCA after reset, "
+					  "aborting.\n");
+				goto out;
+			}
+
+			if (v != 0xffffffff)
+				goto good;
+
+			msleep(100);
+		}
+
+		err = -ENODEV;
+		mthca_err(mdev, "PCI device did not come back after reset, "
+			  "aborting.\n");
+		goto out;
+	}
+
+good:
+	/* Now restore the PCI headers */
+	if (bridge) {
+		/*
+		 * Bridge control register is at 0x3e, so we'll
+		 * naturally restore it last in this loop.
+		 */
+		for (i = 0; i < 16; ++i) {
+			if (i * 4 == PCI_COMMAND)
+				continue;
+
+			if (pci_write_config_dword(bridge, i * 4, bridge_header[i])) {
+				err = -ENODEV;
+				mthca_err(mdev, "Couldn't restore HCA bridge reg %x, "
+					  "aborting.\n", i);
+				goto out;
+			}
+		}
+
+		if (pci_write_config_dword(bridge, PCI_COMMAND,
+					   bridge_header[PCI_COMMAND / 4])) {
+			err = -ENODEV;
+			mthca_err(mdev, "Couldn't restore HCA bridge COMMAND, "
+				  "aborting.\n");
+			goto out;
+		}
+	}
+
+	for (i = 0; i < 16; ++i) {
+		if (i * 4 == PCI_COMMAND)
+			continue;
+
+		if (pci_write_config_dword(mdev->pdev, i * 4, hca_header[i])) {
+			err = -ENODEV;
+			mthca_err(mdev, "Couldn't restore HCA reg %x, "
+				  "aborting.\n", i);
+			goto out;
+		}
+	}
+
+	if (pci_write_config_dword(mdev->pdev, PCI_COMMAND,
+				   hca_header[PCI_COMMAND / 4])) {
+		err = -ENODEV;
+		mthca_err(mdev, "Couldn't restore HCA COMMAND, "
+			  "aborting.\n");
+		goto out;
+	}
+
+out:
+	if (bridge)
+		pci_dev_put(bridge);
+	kfree(bridge_header);
+	kfree(hca_header);
+
+	return err;
+}
diff -Nru a/drivers/infiniband/include/ib_cache.h b/drivers/infiniband/include/ib_cache.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/infiniband/include/ib_cache.h	2005-03-01 23:39:26 -08:00
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2004 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_cache.h 1349 2004-12-16 21:09:43Z roland $
+ */
+
+#ifndef _IB_CACHE_H
+#define _IB_CACHE_H
+
+#include <ib_verbs.h>
+
+/**
+ * ib_get_cached_gid - Returns a cached GID table entry
+ * @device: The device to query.
+ * @port_num: The port number of the device to query.
+ * @index: The index into the cached GID table to query.
+ * @gid: The GID value found at the specified index.
+ *
+ * ib_get_cached_gid() fetches the specified GID table entry stored in
+ * the local software cache.
+ */
+int ib_get_cached_gid(struct ib_device    *device,
+		      u8                   port_num,
+		      int                  index,
+		      union ib_gid        *gid);
+
+/**
+ * ib_find_cached_gid - Returns the port number and GID table index where
+ *   a specified GID value occurs.
+ * @device: The device to query.
+ * @gid: The GID value to search for.
+ * @port_num: The port number of the device where the GID value was found.
+ * @index: The index into the cached GID table where the GID was found.  This
+ *   parameter may be NULL.
+ *
+ * ib_find_cached_gid() searches for the specified GID value in
+ * the local software cache.
+ */
+int ib_find_cached_gid(struct ib_device *device,
+		       union ib_gid	*gid,
+		       u8               *port_num,
+		       u16              *index);
+
+/**
+ * ib_get_cached_pkey - Returns a cached PKey table entry
+ * @device: The device to query.
+ * @port_num: The port number of the device to query.
+ * @index: The index into the cached PKey table to query.
+ * @pkey: The PKey value found at the specified index.
+ *
+ * ib_get_cached_pkey() fetches the specified PKey table entry stored in
+ * the local software cache.
+ */
+int ib_get_cached_pkey(struct ib_device    *device_handle,
+		       u8                   port_num,
+		       int                  index,
+		       u16                 *pkey);
+
+/**
+ * ib_find_cached_pkey - Returns the PKey table index where a specified
+ *   PKey value occurs.
+ * @device: The device to query.
+ * @port_num: The port number of the device to search for the PKey.
+ * @pkey: The PKey value to search for.
+ * @index: The index into the cached PKey table where the PKey was found.
+ *
+ * ib_find_cached_pkey() searches the specified PKey table in
+ * the local software cache.
+ */
+int ib_find_cached_pkey(struct ib_device    *device,
+			u8                   port_num,
+			u16                  pkey,
+			u16                 *index);
+
+#endif /* _IB_CACHE_H */
diff -Nru a/drivers/infiniband/include/ib_fmr_pool.h b/drivers/infiniband/include/ib_fmr_pool.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/infiniband/include/ib_fmr_pool.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2004 Topspin 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 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_fmr_pool.h 1349 2004-12-16 21:09:43Z roland $
+ */
+
+#if !defined(IB_FMR_POOL_H)
+#define IB_FMR_POOL_H
+
+#include <ib_verbs.h>
+
+struct ib_fmr_pool;
+
+/**
+ * struct ib_fmr_pool_param - Parameters for creating FMR pool
+ * @max_pages_per_fmr:Maximum number of pages per map request.
+ * @access:Access flags for FMRs in pool.
+ * @pool_size:Number of FMRs to allocate for pool.
+ * @dirty_watermark:Flush is triggered when @dirty_watermark dirty
+ *     FMRs are present.
+ * @flush_function:Callback called when unmapped FMRs are flushed and
+ *     more FMRs are possibly available for mapping
+ * @flush_arg:Context passed to user's flush function.
+ * @cache:If set, FMRs may be reused after unmapping for identical map
+ *     requests.
+ */
+struct ib_fmr_pool_param {
+	int                     max_pages_per_fmr;
+	enum ib_access_flags    access;
+	int                     pool_size;
+	int                     dirty_watermark;
+	void                  (*flush_function)(struct ib_fmr_pool *pool,
+						void *              arg);
+	void                   *flush_arg;
+	unsigned                cache:1;
+};
+
+struct ib_pool_fmr {
+	struct ib_fmr      *fmr;
+	struct ib_fmr_pool *pool;
+	struct list_head    list;
+	struct hlist_node   cache_node;
+	int                 ref_count;
+	int                 remap_count;
+	u64                 io_virtual_address;
+	int                 page_list_len;
+	u64                 page_list[0];
+};
+
+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);
+
+int ib_flush_fmr_pool(struct ib_fmr_pool *pool);
+
+struct ib_pool_fmr *ib_fmr_pool_map_phys(struct ib_fmr_pool *pool_handle,
+					 u64                *page_list,
+					 int                 list_len,
+					 u64                *io_virtual_address);
+
+int ib_fmr_pool_unmap(struct ib_pool_fmr *fmr);
+
+#endif /* IB_FMR_POOL_H */
diff -Nru a/drivers/infiniband/include/ib_mad.h b/drivers/infiniband/include/ib_mad.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/infiniband/include/ib_mad.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,404 @@
+/*
+ * Copyright (c) 2004 Mellanox Technologies Ltd.  All rights reserved.
+ * Copyright (c) 2004 Infinicon Corporation.  All rights reserved.
+ * 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 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_mad.h 1389 2004-12-27 22:56:47Z roland $
+ */
+
+#if !defined( IB_MAD_H )
+#define IB_MAD_H
+
+#include <ib_verbs.h>
+
+/* Management base version */
+#define IB_MGMT_BASE_VERSION			1
+
+/* Management classes */
+#define IB_MGMT_CLASS_SUBN_LID_ROUTED		0x01
+#define IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE	0x81
+#define IB_MGMT_CLASS_SUBN_ADM			0x03
+#define IB_MGMT_CLASS_PERF_MGMT			0x04
+#define IB_MGMT_CLASS_BM			0x05
+#define IB_MGMT_CLASS_DEVICE_MGMT		0x06
+#define IB_MGMT_CLASS_CM			0x07
+#define IB_MGMT_CLASS_SNMP			0x08
+#define IB_MGMT_CLASS_VENDOR_RANGE2_START	0x30
+#define IB_MGMT_CLASS_VENDOR_RANGE2_END		0x4F
+
+/* Management methods */
+#define IB_MGMT_METHOD_GET			0x01
+#define IB_MGMT_METHOD_SET			0x02
+#define IB_MGMT_METHOD_GET_RESP			0x81
+#define IB_MGMT_METHOD_SEND			0x03
+#define IB_MGMT_METHOD_TRAP			0x05
+#define IB_MGMT_METHOD_REPORT			0x06
+#define IB_MGMT_METHOD_REPORT_RESP		0x86
+#define IB_MGMT_METHOD_TRAP_REPRESS		0x07
+
+#define IB_MGMT_METHOD_RESP			0x80
+
+#define IB_MGMT_MAX_METHODS			128
+
+#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));
+
+struct ib_mad_hdr {
+	u8	base_version;
+	u8	mgmt_class;
+	u8	class_version;
+	u8	method;
+	u16	status;
+	u16	class_specific;
+	u64	tid;
+	u16	attr_id;
+	u16	resv;
+	u32	attr_mod;
+} __attribute__ ((packed));
+
+struct ib_rmpp_hdr {
+	u8	rmpp_version;
+	u8	rmpp_type;
+	u8	rmpp_rtime_flags;
+	u8	rmpp_status;
+	u32	seg_num;
+	u32	paylen_newwin;
+} __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];
+} __attribute__ ((packed));
+
+struct ib_vendor_mad {
+	struct ib_mad_hdr	mad_hdr;
+	struct ib_rmpp_hdr	rmpp_hdr;
+	u8			reserved;
+	u8			oui[3];
+	u8			data[216];
+} __attribute__ ((packed));
+
+struct ib_mad_agent;
+struct ib_mad_send_wc;
+struct ib_mad_recv_wc;
+
+/**
+ * ib_mad_send_handler - callback handler for a sent MAD.
+ * @mad_agent: MAD agent that sent the MAD.
+ * @mad_send_wc: Send work completion information on the sent MAD.
+ */
+typedef void (*ib_mad_send_handler)(struct ib_mad_agent *mad_agent,
+				    struct ib_mad_send_wc *mad_send_wc);
+
+/**
+ * ib_mad_snoop_handler - Callback handler for snooping sent MADs.
+ * @mad_agent: MAD agent that snooped the MAD.
+ * @send_wr: Work request information on the sent MAD.
+ * @mad_send_wc: Work completion information on the sent MAD.  Valid
+ *   only for snooping that occurs on a send completion.
+ *
+ * Clients snooping MADs should not modify data referenced by the @send_wr
+ * or @mad_send_wc.
+ */
+typedef void (*ib_mad_snoop_handler)(struct ib_mad_agent *mad_agent,
+				     struct ib_send_wr *send_wr,
+				     struct ib_mad_send_wc *mad_send_wc);
+
+/**
+ * ib_mad_recv_handler - callback handler for a received MAD.
+ * @mad_agent: MAD agent requesting the received MAD.
+ * @mad_recv_wc: Received work completion information on the received MAD.
+ *
+ * MADs received in response to a send request operation will be handed to
+ * the user after the send operation completes.  All data buffers given
+ * to registered agents through this routine are owned by the receiving
+ * client, except for snooping agents.  Clients snooping MADs should not
+ * modify the data referenced by @mad_recv_wc.
+ */
+typedef void (*ib_mad_recv_handler)(struct ib_mad_agent *mad_agent,
+				    struct ib_mad_recv_wc *mad_recv_wc);
+
+/**
+ * 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.
+ * @recv_handler: Callback handler for a received MAD.
+ * @send_handler: Callback handler for a sent MAD.
+ * @snoop_handler: Callback handler for snooped sent MADs.
+ * @context: User-specified context associated with this registration.
+ * @hi_tid: Access layer assigned transaction ID for this client.
+ *   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
+ */
+struct ib_mad_agent {
+	struct ib_device	*device;
+	struct ib_qp		*qp;
+	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;
+};
+
+/**
+ * ib_mad_send_wc - MAD send completion information.
+ * @wr_id: Work request identifier associated with the send MAD request.
+ * @status: Completion status.
+ * @vendor_err: Optional vendor error information returned with a failed
+ *   request.
+ */
+struct ib_mad_send_wc {
+	u64			wr_id;
+	enum ib_wc_status	status;
+	u32			vendor_err;
+};
+
+/**
+ * ib_mad_recv_buf - received MAD buffer information.
+ * @list: Reference to next data buffer for a received RMPP MAD.
+ * @grh: References a data buffer containing the global route header.
+ *   The data refereced by this buffer is only valid if the GRH is
+ *   valid.
+ * @mad: References the start of the received MAD.
+ */
+struct ib_mad_recv_buf {
+	struct list_head	list;
+	struct ib_grh		*grh;
+	struct ib_mad		*mad;
+};
+
+/**
+ * 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).
+ * @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
+ *   for the corresponding send request.
+ */
+struct ib_mad_recv_wc {
+	struct ib_wc		*wc;
+	struct ib_mad_recv_buf	recv_buf;
+	int			mad_len;
+};
+
+/**
+ * ib_mad_reg_req - MAD registration request
+ * @mgmt_class: Indicates which management class of MADs should be receive
+ *   by the caller.  This field is only required if the user wishes to
+ *   receive unsolicited MADs, otherwise it should be 0.
+ * @mgmt_class_version: Indicates which version of MADs for the given
+ *   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.
+ * @method_mask: The caller will receive unsolicited MADs for any method
+ *   where @method_mask = 1.
+ */
+struct ib_mad_reg_req {
+	u8	mgmt_class;
+	u8	mgmt_class_version;
+	u8	oui[3];
+	DECLARE_BITMAP(method_mask, IB_MGMT_MAX_METHODS);
+};
+
+/**
+ * ib_register_mad_agent - Register to send/receive MADs.
+ * @device: The device to register with.
+ * @port_num: The port on the specified device to use.
+ * @qp_type: Specifies which QP to access.  Must be either
+ *   IB_QPT_SMI or IB_QPT_GSI.
+ * @mad_reg_req: Specifies which unsolicited MADs should be received
+ *   by the caller.  This parameter may be NULL if the caller only
+ *   wishes to receive solicited responses.
+ * @rmpp_version: If set, indicates that the client will send
+ *   and receive MADs that contain the RMPP header for the given version.
+ *   If set to 0, indicates that RMPP is not used by this client.
+ * @send_handler: The completion callback routine invoked after a send
+ *   request has completed.
+ * @recv_handler: The completion callback routine invoked for a received
+ *   MAD.
+ * @context: User specified context associated with the registration.
+ */
+struct ib_mad_agent *ib_register_mad_agent(struct ib_device *device,
+					   u8 port_num,
+					   enum ib_qp_type qp_type,
+					   struct ib_mad_reg_req *mad_reg_req,
+					   u8 rmpp_version,
+					   ib_mad_send_handler send_handler,
+					   ib_mad_recv_handler recv_handler,
+					   void *context);
+
+enum ib_mad_snoop_flags {
+	/*IB_MAD_SNOOP_POSTED_SENDS	   = 1,*/
+	/*IB_MAD_SNOOP_RMPP_SENDS	   = (1<<1),*/
+	IB_MAD_SNOOP_SEND_COMPLETIONS	   = (1<<2),
+	/*IB_MAD_SNOOP_RMPP_SEND_COMPLETIONS = (1<<3),*/
+	IB_MAD_SNOOP_RECVS		   = (1<<4)
+	/*IB_MAD_SNOOP_RMPP_RECVS	   = (1<<5),*/
+	/*IB_MAD_SNOOP_REDIRECTED_QPS	   = (1<<6)*/
+};
+
+/**
+ * ib_register_mad_snoop - Register to snoop sent and received MADs.
+ * @device: The device to register with.
+ * @port_num: The port on the specified device to use.
+ * @qp_type: Specifies which QP traffic to snoop.  Must be either
+ *   IB_QPT_SMI or IB_QPT_GSI.
+ * @mad_snoop_flags: Specifies information where snooping occurs.
+ * @send_handler: The callback routine invoked for a snooped send.
+ * @recv_handler: The callback routine invoked for a snooped receive.
+ * @context: User specified context associated with the registration.
+ */
+struct ib_mad_agent *ib_register_mad_snoop(struct ib_device *device,
+					   u8 port_num,
+					   enum ib_qp_type qp_type,
+					   int mad_snoop_flags,
+					   ib_mad_snoop_handler snoop_handler,
+					   ib_mad_recv_handler recv_handler,
+					   void *context);
+
+/**
+ * ib_unregister_mad_agent - Unregisters a client from using MAD services.
+ * @mad_agent: Corresponding MAD registration request to deregister.
+ *
+ * After invoking this routine, MAD services are no longer usable by the
+ * client on the associated QP.
+ */
+int ib_unregister_mad_agent(struct ib_mad_agent *mad_agent);
+
+/**
+ * ib_post_send_mad - Posts MAD(s) to the send queue of the QP associated
+ *   with the registered client.
+ * @mad_agent: Specifies the associated registration to post the send to.
+ * @send_wr: Specifies the information needed to send the MAD(s).
+ * @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.
+ */
+int ib_post_send_mad(struct ib_mad_agent *mad_agent,
+		     struct ib_send_wr *send_wr,
+		     struct ib_send_wr **bad_send_wr);
+
+/**
+ * ib_coalesce_recv_mad - Coalesces received MAD data into a single buffer.
+ * @mad_recv_wc: Work completion information for a received MAD.
+ * @buf: User-provided data buffer to receive the coalesced buffers.  The
+ *   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,
+ * removing duplicated headers.
+ */
+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.
+ * @mad_recv_wc: Work completion information for a received MAD.
+ *
+ * Clients receiving MADs through their ib_mad_recv_handler must call this
+ * routine to return the work completion buffers to the access layer.
+ */
+void ib_free_recv_mad(struct ib_mad_recv_wc *mad_recv_wc);
+
+/**
+ * ib_cancel_mad - Cancels 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 cancel.
+ *
+ * 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);
+
+/**
+ * ib_redirect_mad_qp - Registers a QP for MAD services.
+ * @qp: Reference to a QP that requires MAD services.
+ * @rmpp_version: If set, indicates that the client will send
+ *   and receive MADs that contain the RMPP header for the given version.
+ *   If set to 0, indicates that RMPP is not used by this client.
+ * @send_handler: The completion callback routine invoked after a send
+ *   request has completed.
+ * @recv_handler: The completion callback routine invoked for a received
+ *   MAD.
+ * @context: User specified context associated with the registration.
+ *
+ * Use of this call allows clients to use MAD services, such as RMPP,
+ * on user-owned QPs.  After calling this routine, users may send
+ * MADs on the specified QP by calling ib_mad_post_send.
+ */
+struct ib_mad_agent *ib_redirect_mad_qp(struct ib_qp *qp,
+					u8 rmpp_version,
+					ib_mad_send_handler send_handler,
+					ib_mad_recv_handler recv_handler,
+					void *context);
+
+/**
+ * ib_process_mad_wc - Processes a work completion associated with a
+ *   MAD sent or received on a redirected QP.
+ * @mad_agent: Specifies the registered MAD service using the redirected QP.
+ * @wc: References a work completion associated with a sent or received
+ *   MAD segment.
+ *
+ * This routine is used to complete or continue processing on a MAD request.
+ * If the work completion is associated with a send operation, calling
+ * this routine is required to continue an RMPP transfer or to wait for a
+ * corresponding response, if it is a request.  If the work completion is
+ * associated with a receive operation, calling this routine is required to
+ * process an inbound or outbound RMPP transfer, or to match a response MAD
+ * with its corresponding request.
+ */
+int ib_process_mad_wc(struct ib_mad_agent *mad_agent,
+		      struct ib_wc *wc);
+
+#endif /* IB_MAD_H */
diff -Nru a/drivers/infiniband/include/ib_pack.h b/drivers/infiniband/include/ib_pack.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/infiniband/include/ib_pack.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,245 @@
+/*
+ * Copyright (c) 2004 Topspin 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 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_pack.h 1349 2004-12-16 21:09:43Z roland $
+ */
+
+#ifndef IB_PACK_H
+#define IB_PACK_H
+
+#include <ib_verbs.h>
+
+enum {
+	IB_LRH_BYTES  = 8,
+	IB_GRH_BYTES  = 40,
+	IB_BTH_BYTES  = 12,
+	IB_DETH_BYTES = 8
+};
+
+struct ib_field {
+	size_t struct_offset_bytes;
+	size_t struct_size_bytes;
+	int    offset_words;
+	int    offset_bits;
+	int    size_bits;
+	char  *field_name;
+};
+
+#define RESERVED \
+	.field_name          = "reserved"
+
+/*
+ * This macro cleans up the definitions of constants for BTH opcodes.
+ * It is used to define constants such as IB_OPCODE_UD_SEND_ONLY,
+ * which becomes IB_OPCODE_UD + IB_OPCODE_SEND_ONLY, and this gives
+ * the correct value.
+ *
+ * In short, user code should use the constants defined using the
+ * macro rather than worrying about adding together other constants.
+*/
+#define IB_OPCODE(transport, op) \
+	IB_OPCODE_ ## transport ## _ ## op = \
+		IB_OPCODE_ ## transport + IB_OPCODE_ ## op
+
+enum {
+	/* transport types -- just used to define real constants */
+	IB_OPCODE_RC                                = 0x00,
+	IB_OPCODE_UC                                = 0x20,
+	IB_OPCODE_RD                                = 0x40,
+	IB_OPCODE_UD                                = 0x60,
+
+	/* operations -- just used to define real constants */
+	IB_OPCODE_SEND_FIRST                        = 0x00,
+	IB_OPCODE_SEND_MIDDLE                       = 0x01,
+	IB_OPCODE_SEND_LAST                         = 0x02,
+	IB_OPCODE_SEND_LAST_WITH_IMMEDIATE          = 0x03,
+	IB_OPCODE_SEND_ONLY                         = 0x04,
+	IB_OPCODE_SEND_ONLY_WITH_IMMEDIATE          = 0x05,
+	IB_OPCODE_RDMA_WRITE_FIRST                  = 0x06,
+	IB_OPCODE_RDMA_WRITE_MIDDLE                 = 0x07,
+	IB_OPCODE_RDMA_WRITE_LAST                   = 0x08,
+	IB_OPCODE_RDMA_WRITE_LAST_WITH_IMMEDIATE    = 0x09,
+	IB_OPCODE_RDMA_WRITE_ONLY                   = 0x0a,
+	IB_OPCODE_RDMA_WRITE_ONLY_WITH_IMMEDIATE    = 0x0b,
+	IB_OPCODE_RDMA_READ_REQUEST                 = 0x0c,
+	IB_OPCODE_RDMA_READ_RESPONSE_FIRST          = 0x0d,
+	IB_OPCODE_RDMA_READ_RESPONSE_MIDDLE         = 0x0e,
+	IB_OPCODE_RDMA_READ_RESPONSE_LAST           = 0x0f,
+	IB_OPCODE_RDMA_READ_RESPONSE_ONLY           = 0x10,
+	IB_OPCODE_ACKNOWLEDGE                       = 0x11,
+	IB_OPCODE_ATOMIC_ACKNOWLEDGE                = 0x12,
+	IB_OPCODE_COMPARE_SWAP                      = 0x13,
+	IB_OPCODE_FETCH_ADD                         = 0x14,
+
+	/* real constants follow -- see comment about above IB_OPCODE()
+	   macro for more details */
+
+	/* RC */
+	IB_OPCODE(RC, SEND_FIRST),
+	IB_OPCODE(RC, SEND_MIDDLE),
+	IB_OPCODE(RC, SEND_LAST),
+	IB_OPCODE(RC, SEND_LAST_WITH_IMMEDIATE),
+	IB_OPCODE(RC, SEND_ONLY),
+	IB_OPCODE(RC, SEND_ONLY_WITH_IMMEDIATE),
+	IB_OPCODE(RC, RDMA_WRITE_FIRST),
+	IB_OPCODE(RC, RDMA_WRITE_MIDDLE),
+	IB_OPCODE(RC, RDMA_WRITE_LAST),
+	IB_OPCODE(RC, RDMA_WRITE_LAST_WITH_IMMEDIATE),
+	IB_OPCODE(RC, RDMA_WRITE_ONLY),
+	IB_OPCODE(RC, RDMA_WRITE_ONLY_WITH_IMMEDIATE),
+	IB_OPCODE(RC, RDMA_READ_REQUEST),
+	IB_OPCODE(RC, RDMA_READ_RESPONSE_FIRST),
+	IB_OPCODE(RC, RDMA_READ_RESPONSE_MIDDLE),
+	IB_OPCODE(RC, RDMA_READ_RESPONSE_LAST),
+	IB_OPCODE(RC, RDMA_READ_RESPONSE_ONLY),
+	IB_OPCODE(RC, ACKNOWLEDGE),
+	IB_OPCODE(RC, ATOMIC_ACKNOWLEDGE),
+	IB_OPCODE(RC, COMPARE_SWAP),
+	IB_OPCODE(RC, FETCH_ADD),
+
+	/* UC */
+	IB_OPCODE(UC, SEND_FIRST),
+	IB_OPCODE(UC, SEND_MIDDLE),
+	IB_OPCODE(UC, SEND_LAST),
+	IB_OPCODE(UC, SEND_LAST_WITH_IMMEDIATE),
+	IB_OPCODE(UC, SEND_ONLY),
+	IB_OPCODE(UC, SEND_ONLY_WITH_IMMEDIATE),
+	IB_OPCODE(UC, RDMA_WRITE_FIRST),
+	IB_OPCODE(UC, RDMA_WRITE_MIDDLE),
+	IB_OPCODE(UC, RDMA_WRITE_LAST),
+	IB_OPCODE(UC, RDMA_WRITE_LAST_WITH_IMMEDIATE),
+	IB_OPCODE(UC, RDMA_WRITE_ONLY),
+	IB_OPCODE(UC, RDMA_WRITE_ONLY_WITH_IMMEDIATE),
+
+	/* RD */
+	IB_OPCODE(RD, SEND_FIRST),
+	IB_OPCODE(RD, SEND_MIDDLE),
+	IB_OPCODE(RD, SEND_LAST),
+	IB_OPCODE(RD, SEND_LAST_WITH_IMMEDIATE),
+	IB_OPCODE(RD, SEND_ONLY),
+	IB_OPCODE(RD, SEND_ONLY_WITH_IMMEDIATE),
+	IB_OPCODE(RD, RDMA_WRITE_FIRST),
+	IB_OPCODE(RD, RDMA_WRITE_MIDDLE),
+	IB_OPCODE(RD, RDMA_WRITE_LAST),
+	IB_OPCODE(RD, RDMA_WRITE_LAST_WITH_IMMEDIATE),
+	IB_OPCODE(RD, RDMA_WRITE_ONLY),
+	IB_OPCODE(RD, RDMA_WRITE_ONLY_WITH_IMMEDIATE),
+	IB_OPCODE(RD, RDMA_READ_REQUEST),
+	IB_OPCODE(RD, RDMA_READ_RESPONSE_FIRST),
+	IB_OPCODE(RD, RDMA_READ_RESPONSE_MIDDLE),
+	IB_OPCODE(RD, RDMA_READ_RESPONSE_LAST),
+	IB_OPCODE(RD, RDMA_READ_RESPONSE_ONLY),
+	IB_OPCODE(RD, ACKNOWLEDGE),
+	IB_OPCODE(RD, ATOMIC_ACKNOWLEDGE),
+	IB_OPCODE(RD, COMPARE_SWAP),
+	IB_OPCODE(RD, FETCH_ADD),
+
+	/* UD */
+	IB_OPCODE(UD, SEND_ONLY),
+	IB_OPCODE(UD, SEND_ONLY_WITH_IMMEDIATE)
+};
+
+enum {
+	IB_LNH_RAW        = 0,
+	IB_LNH_IP         = 1,
+	IB_LNH_IBA_LOCAL  = 2,
+	IB_LNH_IBA_GLOBAL = 3
+};
+
+struct ib_unpacked_lrh {
+	u8        virtual_lane;
+	u8        link_version;
+	u8        service_level;
+	u8        link_next_header;
+	__be16    destination_lid;
+	__be16    packet_length;
+	__be16    source_lid;
+};
+
+struct ib_unpacked_grh {
+	u8    	     ip_version;
+	u8    	     traffic_class;
+	__be32 	     flow_label;
+	__be16       payload_length;
+	u8    	     next_header;
+	u8    	     hop_limit;
+	union ib_gid source_gid;
+	union ib_gid destination_gid;
+};
+
+struct ib_unpacked_bth {
+	u8           opcode;
+	u8           solicited_event;
+	u8           mig_req;
+	u8           pad_count;
+	u8           transport_header_version;
+	__be16       pkey;
+	__be32       destination_qpn;
+	u8           ack_req;
+	__be32       psn;
+};
+
+struct ib_unpacked_deth {
+	__be32       qkey;
+	__be32       source_qpn;
+};
+
+struct ib_ud_header {
+	struct ib_unpacked_lrh  lrh;
+	int                     grh_present;
+	struct ib_unpacked_grh  grh;
+	struct ib_unpacked_bth  bth;
+	struct ib_unpacked_deth deth;
+	int            		immediate_present;
+	__be32         		immediate_data;
+};
+
+void ib_pack(const struct ib_field        *desc,
+	     int                           desc_len,
+	     void                         *structure,
+	     void                         *buf);
+
+void ib_unpack(const struct ib_field        *desc,
+	       int                           desc_len,
+	       void                         *buf,
+	       void                         *structure);
+
+void ib_ud_header_init(int     		   payload_bytes,
+		       int    		   grh_present,
+		       struct ib_ud_header *header);
+
+int ib_ud_header_pack(struct ib_ud_header *header,
+		      void                *buf);
+
+int ib_ud_header_unpack(void                *buf,
+			struct ib_ud_header *header);
+
+#endif /* IB_PACK_H */
diff -Nru a/drivers/infiniband/include/ib_sa.h b/drivers/infiniband/include/ib_sa.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/infiniband/include/ib_sa.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,308 @@
+/*
+ * Copyright (c) 2004 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_sa.h 1389 2004-12-27 22:56:47Z roland $
+ */
+
+#ifndef IB_SA_H
+#define IB_SA_H
+
+#include <linux/compiler.h>
+
+#include <ib_verbs.h>
+#include <ib_mad.h>
+
+enum {
+	IB_SA_CLASS_VERSION	= 2,	/* IB spec version 1.1/1.2 */
+
+	IB_SA_METHOD_DELETE	= 0x15
+};
+
+enum ib_sa_selector {
+	IB_SA_GTE  = 0,
+	IB_SA_LTE  = 1,
+	IB_SA_EQ   = 2,
+	/*
+	 * The meaning of "best" depends on the attribute: for
+	 * example, for MTU best will return the largest available
+	 * MTU, while for packet life time, best will return the
+	 * smallest available life time.
+	 */
+	IB_SA_BEST = 3
+};
+
+enum ib_sa_rate {
+	IB_SA_RATE_2_5_GBPS = 2,
+	IB_SA_RATE_5_GBPS   = 5,
+	IB_SA_RATE_10_GBPS  = 3,
+	IB_SA_RATE_20_GBPS  = 6,
+	IB_SA_RATE_30_GBPS  = 4,
+	IB_SA_RATE_40_GBPS  = 7,
+	IB_SA_RATE_60_GBPS  = 8,
+	IB_SA_RATE_80_GBPS  = 9,
+	IB_SA_RATE_120_GBPS = 10
+};
+
+static inline int ib_sa_rate_enum_to_int(enum ib_sa_rate rate)
+{
+	switch (rate) {
+	case IB_SA_RATE_2_5_GBPS: return  1;
+	case IB_SA_RATE_5_GBPS:   return  2;
+	case IB_SA_RATE_10_GBPS:  return  4;
+	case IB_SA_RATE_20_GBPS:  return  8;
+	case IB_SA_RATE_30_GBPS:  return 12;
+	case IB_SA_RATE_40_GBPS:  return 16;
+	case IB_SA_RATE_60_GBPS:  return 24;
+	case IB_SA_RATE_80_GBPS:  return 32;
+	case IB_SA_RATE_120_GBPS: return 48;
+	default: 	          return -1;
+	}
+}
+
+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
+ * SA records in SA MADs; all packing and unpacking is handled by the
+ * SA query code.
+ *
+ * For a record with structure ib_sa_xxx_rec, the naming convention
+ * for the component mask value for field yyy is IB_SA_XXX_REC_YYY (we
+ * never use different abbreviations or otherwise change the spelling
+ * of xxx/yyy between ib_sa_xxx_rec.yyy and IB_SA_XXX_REC_YYY).
+ *
+ * Reserved rows are indicated with comments to help maintainability.
+ */
+
+/* reserved:								 0 */
+/* reserved:								 1 */
+#define IB_SA_PATH_REC_DGID				IB_SA_COMP_MASK( 2)
+#define IB_SA_PATH_REC_SGID				IB_SA_COMP_MASK( 3)
+#define IB_SA_PATH_REC_DLID				IB_SA_COMP_MASK( 4)
+#define IB_SA_PATH_REC_SLID				IB_SA_COMP_MASK( 5)
+#define IB_SA_PATH_REC_RAW_TRAFFIC			IB_SA_COMP_MASK( 6)
+/* reserved:								 7 */
+#define IB_SA_PATH_REC_FLOW_LABEL       		IB_SA_COMP_MASK( 8)
+#define IB_SA_PATH_REC_HOP_LIMIT			IB_SA_COMP_MASK( 9)
+#define IB_SA_PATH_REC_TRAFFIC_CLASS			IB_SA_COMP_MASK(10)
+#define IB_SA_PATH_REC_REVERSIBLE			IB_SA_COMP_MASK(11)
+#define IB_SA_PATH_REC_NUMB_PATH			IB_SA_COMP_MASK(12)
+#define IB_SA_PATH_REC_PKEY				IB_SA_COMP_MASK(13)
+/* reserved:								14 */
+#define IB_SA_PATH_REC_SL				IB_SA_COMP_MASK(15)
+#define IB_SA_PATH_REC_MTU_SELECTOR			IB_SA_COMP_MASK(16)
+#define IB_SA_PATH_REC_MTU				IB_SA_COMP_MASK(17)
+#define IB_SA_PATH_REC_RATE_SELECTOR			IB_SA_COMP_MASK(18)
+#define IB_SA_PATH_REC_RATE				IB_SA_COMP_MASK(19)
+#define IB_SA_PATH_REC_PACKET_LIFE_TIME_SELECTOR	IB_SA_COMP_MASK(20)
+#define IB_SA_PATH_REC_PACKET_LIFE_TIME			IB_SA_COMP_MASK(21)
+#define IB_SA_PATH_REC_PREFERENCE			IB_SA_COMP_MASK(22)
+
+struct ib_sa_path_rec {
+	/* reserved */
+	/* reserved */
+	union ib_gid dgid;
+	union ib_gid sgid;
+	u16          dlid;
+	u16          slid;
+	int          raw_traffic;
+	/* reserved */
+	u32          flow_label;
+	u8           hop_limit;
+	u8           traffic_class;
+	int          reversible;
+	u8           numb_path;
+	u16          pkey;
+	/* reserved */
+	u8           sl;
+	u8           mtu_selector;
+	enum ib_mtu  mtu;
+	u8           rate_selector;
+	u8           rate;
+	u8           packet_life_time_selector;
+	u8           packet_life_time;
+	u8           preference;
+};
+
+#define IB_SA_MCMEMBER_REC_MGID				IB_SA_COMP_MASK( 0)
+#define IB_SA_MCMEMBER_REC_PORT_GID			IB_SA_COMP_MASK( 1)
+#define IB_SA_MCMEMBER_REC_QKEY				IB_SA_COMP_MASK( 2)
+#define IB_SA_MCMEMBER_REC_MLID				IB_SA_COMP_MASK( 3)
+#define IB_SA_MCMEMBER_REC_MTU_SELECTOR			IB_SA_COMP_MASK( 4)
+#define IB_SA_MCMEMBER_REC_MTU				IB_SA_COMP_MASK( 5)
+#define IB_SA_MCMEMBER_REC_TRAFFIC_CLASS		IB_SA_COMP_MASK( 6)
+#define IB_SA_MCMEMBER_REC_PKEY				IB_SA_COMP_MASK( 7)
+#define IB_SA_MCMEMBER_REC_RATE_SELECTOR		IB_SA_COMP_MASK( 8)
+#define IB_SA_MCMEMBER_REC_RATE				IB_SA_COMP_MASK( 9)
+#define IB_SA_MCMEMBER_REC_PACKET_LIFE_TIME_SELECTOR	IB_SA_COMP_MASK(10)
+#define IB_SA_MCMEMBER_REC_PACKET_LIFE_TIME		IB_SA_COMP_MASK(11)
+#define IB_SA_MCMEMBER_REC_SL				IB_SA_COMP_MASK(12)
+#define IB_SA_MCMEMBER_REC_FLOW_LABEL			IB_SA_COMP_MASK(13)
+#define IB_SA_MCMEMBER_REC_HOP_LIMIT			IB_SA_COMP_MASK(14)
+#define IB_SA_MCMEMBER_REC_SCOPE			IB_SA_COMP_MASK(15)
+#define IB_SA_MCMEMBER_REC_JOIN_STATE			IB_SA_COMP_MASK(16)
+#define IB_SA_MCMEMBER_REC_PROXY_JOIN			IB_SA_COMP_MASK(17)
+
+struct ib_sa_mcmember_rec {
+	union ib_gid mgid;
+	union ib_gid port_gid;
+	u32          qkey;
+	u16          mlid;
+	u8           mtu_selector;
+	enum         ib_mtu mtu;
+	u8           traffic_class;
+	u16          pkey;
+	u8 	     rate_selector;
+	u8 	     rate;
+	u8 	     packet_life_time_selector;
+	u8 	     packet_life_time;
+	u8           sl;
+	u32          flow_label;
+	u8           hop_limit;
+	u8           scope;
+	u8           join_state;
+	int          proxy_join;
+};
+
+struct ib_sa_query;
+
+void ib_sa_cancel_query(int id, struct ib_sa_query *query);
+
+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,
+		       void (*callback)(int status,
+					struct ib_sa_path_rec *resp,
+					void *context),
+		       void *context,
+		       struct ib_sa_query **query);
+
+int ib_sa_mcmember_rec_query(struct ib_device *device, u8 port_num,
+			     u8 method,
+			     struct ib_sa_mcmember_rec *rec,
+			     ib_sa_comp_mask comp_mask,
+			     int timeout_ms, int gfp_mask,
+			     void (*callback)(int status,
+					      struct ib_sa_mcmember_rec *resp,
+					      void *context),
+			     void *context,
+			     struct ib_sa_query **query);
+
+/**
+ * ib_sa_mcmember_rec_set - Start an MCMember set query
+ * @device:device to send query on
+ * @port_num: port number to send query on
+ * @rec:MCMember Record to send in query
+ * @comp_mask:component mask to send in query
+ * @timeout_ms:time to wait for response
+ * @gfp_mask:GFP mask to use for internal allocations
+ * @callback:function called when query completes, times out or is
+ * canceled
+ * @context:opaque user context passed to callback
+ * @sa_query:query context, used to cancel query
+ *
+ * Send an MCMember Set query to the SA (eg to join a multicast
+ * group).  The callback function will be called when the query
+ * 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_mcmember_rec_set() is negative, it is
+ * an error code.  Otherwise it is a query ID that can be used to
+ * cancel the query.
+ */
+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,
+		       void (*callback)(int status,
+					struct ib_sa_mcmember_rec *resp,
+					void *context),
+		       void *context,
+		       struct ib_sa_query **query)
+{
+	return ib_sa_mcmember_rec_query(device, port_num,
+					IB_MGMT_METHOD_SET,
+					rec, comp_mask,
+					timeout_ms, gfp_mask, callback,
+					context, query);
+}
+
+/**
+ * ib_sa_mcmember_rec_delete - Start an MCMember delete query
+ * @device:device to send query on
+ * @port_num: port number to send query on
+ * @rec:MCMember Record to send in query
+ * @comp_mask:component mask to send in query
+ * @timeout_ms:time to wait for response
+ * @gfp_mask:GFP mask to use for internal allocations
+ * @callback:function called when query completes, times out or is
+ * canceled
+ * @context:opaque user context passed to callback
+ * @sa_query:query context, used to cancel query
+ *
+ * Send an MCMember Delete query to the SA (eg to leave a multicast
+ * group).  The callback function will be called when the query
+ * 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_mcmember_rec_delete() is negative, it
+ * is an error code.  Otherwise it is a query ID that can be used to
+ * cancel the query.
+ */
+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,
+			  void (*callback)(int status,
+					   struct ib_sa_mcmember_rec *resp,
+					   void *context),
+			  void *context,
+			  struct ib_sa_query **query)
+{
+	return ib_sa_mcmember_rec_query(device, port_num,
+					IB_SA_METHOD_DELETE,
+					rec, comp_mask,
+					timeout_ms, gfp_mask, callback,
+					context, query);
+}
+
+
+#endif /* IB_SA_H */
diff -Nru a/drivers/infiniband/include/ib_smi.h b/drivers/infiniband/include/ib_smi.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/infiniband/include/ib_smi.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2004 Mellanox Technologies Ltd.  All rights reserved.
+ * Copyright (c) 2004 Infinicon Corporation.  All rights reserved.
+ * 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 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_smi.h 1389 2004-12-27 22:56:47Z roland $
+ */
+
+#if !defined( IB_SMI_H )
+#define IB_SMI_H
+
+#include <ib_mad.h>
+
+#define IB_LID_PERMISSIVE			0xFFFF
+
+#define IB_SMP_DATA_SIZE			64
+#define IB_SMP_MAX_PATH_HOPS			64
+
+struct ib_smp {
+	u8	base_version;
+	u8	mgmt_class;
+	u8	class_version;
+	u8	method;
+	u16	status;
+	u8	hop_ptr;
+	u8	hop_cnt;
+	u64	tid;
+	u16	attr_id;
+	u16	resv;
+	u32	attr_mod;
+	u64	mkey;
+	u16	dr_slid;
+	u16	dr_dlid;
+	u8	reserved[28];
+	u8	data[IB_SMP_DATA_SIZE];
+	u8	initial_path[IB_SMP_MAX_PATH_HOPS];
+	u8	return_path[IB_SMP_MAX_PATH_HOPS];
+} __attribute__ ((packed));
+
+#define IB_SMP_DIRECTION			__constant_htons(0x8000)
+
+/* Subnet management attributes */
+#define IB_SMP_ATTR_NOTICE			__constant_htons(0x0002)
+#define IB_SMP_ATTR_NODE_DESC			__constant_htons(0x0010)
+#define IB_SMP_ATTR_NODE_INFO			__constant_htons(0x0011)
+#define IB_SMP_ATTR_SWITCH_INFO			__constant_htons(0x0012)
+#define IB_SMP_ATTR_GUID_INFO			__constant_htons(0x0014)
+#define IB_SMP_ATTR_PORT_INFO			__constant_htons(0x0015)
+#define IB_SMP_ATTR_PKEY_TABLE			__constant_htons(0x0016)
+#define IB_SMP_ATTR_SL_TO_VL_TABLE		__constant_htons(0x0017)
+#define IB_SMP_ATTR_VL_ARB_TABLE		__constant_htons(0x0018)
+#define IB_SMP_ATTR_LINEAR_FORWARD_TABLE	__constant_htons(0x0019)
+#define IB_SMP_ATTR_RANDOM_FORWARD_TABLE	__constant_htons(0x001A)
+#define IB_SMP_ATTR_MCAST_FORWARD_TABLE		__constant_htons(0x001B)
+#define IB_SMP_ATTR_SM_INFO			__constant_htons(0x0020)
+#define IB_SMP_ATTR_VENDOR_DIAG			__constant_htons(0x0030)
+#define IB_SMP_ATTR_LED_INFO			__constant_htons(0x0031)
+#define IB_SMP_ATTR_VENDOR_MASK			__constant_htons(0xFF00)
+
+static inline u8
+ib_get_smp_direction(struct ib_smp *smp)
+{
+	return ((smp->status & IB_SMP_DIRECTION) == IB_SMP_DIRECTION);
+}
+
+#endif /* IB_SMI_H */
diff -Nru a/drivers/infiniband/include/ib_user_mad.h b/drivers/infiniband/include/ib_user_mad.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/infiniband/include/ib_user_mad.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2004 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_mad.h 1389 2004-12-27 22:56:47Z roland $
+ */
+
+#ifndef IB_USER_MAD_H
+#define IB_USER_MAD_H
+
+#include <linux/types.h>
+#include <linux/ioctl.h>
+
+/*
+ * Increment this value if any changes that break userspace ABI
+ * compatibility are made.
+ */
+#define IB_USER_MAD_ABI_VERSION	2
+
+/*
+ * 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).
+ */
+
+/**
+ * ib_user_mad - MAD packet
+ * @data - Contents of MAD
+ * @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)
+ * @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
+ * @sl - Service level received with/to be sent with
+ * @path_bits - Local path bits received with/to be sent with
+ * @grh_present - If set, GRH was received/should be sent
+ * @gid_index - Local GID index to send with (unset on receive)
+ * @hop_limit - Hop limit in GRH
+ * @traffic_class - Traffic class in GRH
+ * @gid - Remote GID in GRH
+ * @flow_label - Flow label in GRH
+ *
+ * All multi-byte quantities are stored in network (big endian) byte order.
+ */
+struct ib_user_mad {
+	__u8	data[256];
+	__u32	id;
+	__u32	status;
+	__u32	timeout_ms;
+	__u32	qpn;
+	__u32   qkey;
+	__u16	lid;
+	__u8	sl;
+	__u8	path_bits;
+	__u8	grh_present;
+	__u8	gid_index;
+	__u8	hop_limit;
+	__u8	traffic_class;
+	__u8	gid[16];
+	__u32	flow_label;
+};
+
+/**
+ * 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.
+ * @method_mask - The caller will receive unsolicited MADs for any method
+ *   where @method_mask = 1.
+ * @mgmt_class - Indicates which management class of MADs should be receive
+ *   by the caller.  This field is only required if the user wishes to
+ *   receive unsolicited MADs, otherwise it should be 0.
+ * @mgmt_class_version - Indicates which version of MADs for the given
+ *   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.
+ */
+struct ib_user_mad_reg_req {
+	__u32	id;
+	__u32	method_mask[4];
+	__u8	qpn;
+	__u8	mgmt_class;
+	__u8	mgmt_class_version;
+	__u8    oui[3];
+};
+
+#define IB_IOCTL_MAGIC		0x1b
+
+#define IB_USER_MAD_REGISTER_AGENT	_IOWR(IB_IOCTL_MAGIC, 1, \
+					      struct ib_user_mad_reg_req)
+
+#define IB_USER_MAD_UNREGISTER_AGENT	_IOW(IB_IOCTL_MAGIC, 2, __u32)
+
+#endif /* IB_USER_MAD_H */
diff -Nru a/drivers/infiniband/include/ib_verbs.h b/drivers/infiniband/include/ib_verbs.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/infiniband/include/ib_verbs.h	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,1259 @@
+/*
+ * Copyright (c) 2004 Mellanox Technologies Ltd.  All rights reserved.
+ * Copyright (c) 2004 Infinicon Corporation.  All rights reserved.
+ * 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 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_verbs.h 1349 2004-12-16 21:09:43Z roland $
+ */
+
+#if !defined(IB_VERBS_H)
+#define IB_VERBS_H
+
+#include <linux/types.h>
+#include <linux/device.h>
+#include <asm/atomic.h>
+
+union ib_gid {
+	u8	raw[16];
+	struct {
+		u64	subnet_prefix;
+		u64	interface_id;
+	} global;
+};
+
+enum ib_node_type {
+	IB_NODE_CA 	= 1,
+	IB_NODE_SWITCH,
+	IB_NODE_ROUTER
+};
+
+enum ib_device_cap_flags {
+	IB_DEVICE_RESIZE_MAX_WR		= 1,
+	IB_DEVICE_BAD_PKEY_CNTR		= (1<<1),
+	IB_DEVICE_BAD_QKEY_CNTR		= (1<<2),
+	IB_DEVICE_RAW_MULTI		= (1<<3),
+	IB_DEVICE_AUTO_PATH_MIG		= (1<<4),
+	IB_DEVICE_CHANGE_PHY_PORT	= (1<<5),
+	IB_DEVICE_UD_AV_PORT_ENFORCE	= (1<<6),
+	IB_DEVICE_CURR_QP_STATE_MOD	= (1<<7),
+	IB_DEVICE_SHUTDOWN_PORT		= (1<<8),
+	IB_DEVICE_INIT_TYPE		= (1<<9),
+	IB_DEVICE_PORT_ACTIVE_EVENT	= (1<<10),
+	IB_DEVICE_SYS_IMAGE_GUID	= (1<<11),
+	IB_DEVICE_RC_RNR_NAK_GEN	= (1<<12),
+	IB_DEVICE_SRQ_RESIZE		= (1<<13),
+	IB_DEVICE_N_NOTIFY_CQ		= (1<<14),
+	IB_DEVICE_RQ_SIG_TYPE		= (1<<15)
+};
+
+enum ib_atomic_cap {
+	IB_ATOMIC_NONE,
+	IB_ATOMIC_HCA,
+	IB_ATOMIC_GLOB
+};
+
+struct ib_device_attr {
+	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;
+	int			max_qp;
+	int			max_qp_wr;
+	int			device_cap_flags;
+	int			max_sge;
+	int			max_sge_rd;
+	int			max_cq;
+	int			max_cqe;
+	int			max_mr;
+	int			max_pd;
+	int			max_qp_rd_atom;
+	int			max_ee_rd_atom;
+	int			max_res_rd_atom;
+	int			max_qp_init_rd_atom;
+	int			max_ee_init_rd_atom;
+	enum ib_atomic_cap	atomic_cap;
+	int			max_ee;
+	int			max_rdd;
+	int			max_mw;
+	int			max_raw_ipv6_qp;
+	int			max_raw_ethy_qp;
+	int			max_mcast_grp;
+	int			max_mcast_qp_attach;
+	int			max_total_mcast_qp_attach;
+	int			max_ah;
+	int			max_fmr;
+	int			max_map_per_fmr;
+	int			max_srq;
+	int			max_srq_wr;
+	int			max_srq_sge;
+	u16			max_pkeys;
+	u8			local_ca_ack_delay;
+};
+
+enum ib_mtu {
+	IB_MTU_256  = 1,
+	IB_MTU_512  = 2,
+	IB_MTU_1024 = 3,
+	IB_MTU_2048 = 4,
+	IB_MTU_4096 = 5
+};
+
+static inline int ib_mtu_enum_to_int(enum ib_mtu mtu)
+{
+	switch (mtu) {
+	case IB_MTU_256:  return  256;
+	case IB_MTU_512:  return  512;
+	case IB_MTU_1024: return 1024;
+	case IB_MTU_2048: return 2048;
+	case IB_MTU_4096: return 4096;
+	default: 	  return -1;
+	}
+}
+
+enum ib_port_state {
+	IB_PORT_NOP		= 0,
+	IB_PORT_DOWN		= 1,
+	IB_PORT_INIT		= 2,
+	IB_PORT_ARMED		= 3,
+	IB_PORT_ACTIVE		= 4,
+	IB_PORT_ACTIVE_DEFER	= 5
+};
+
+enum ib_port_cap_flags {
+	IB_PORT_SM				= 1 <<  1,
+	IB_PORT_NOTICE_SUP			= 1 <<  2,
+	IB_PORT_TRAP_SUP			= 1 <<  3,
+	IB_PORT_OPT_IPD_SUP                     = 1 <<  4,
+	IB_PORT_AUTO_MIGR_SUP			= 1 <<  5,
+	IB_PORT_SL_MAP_SUP			= 1 <<  6,
+	IB_PORT_MKEY_NVRAM			= 1 <<  7,
+	IB_PORT_PKEY_NVRAM			= 1 <<  8,
+	IB_PORT_LED_INFO_SUP			= 1 <<  9,
+	IB_PORT_SM_DISABLED			= 1 << 10,
+	IB_PORT_SYS_IMAGE_GUID_SUP		= 1 << 11,
+	IB_PORT_PKEY_SW_EXT_PORT_TRAP_SUP	= 1 << 12,
+	IB_PORT_CM_SUP				= 1 << 16,
+	IB_PORT_SNMP_TUNNEL_SUP			= 1 << 17,
+	IB_PORT_REINIT_SUP			= 1 << 18,
+	IB_PORT_DEVICE_MGMT_SUP			= 1 << 19,
+	IB_PORT_VENDOR_CLASS_SUP		= 1 << 20,
+	IB_PORT_DR_NOTICE_SUP			= 1 << 21,
+	IB_PORT_CAP_MASK_NOTICE_SUP		= 1 << 22,
+	IB_PORT_BOOT_MGMT_SUP			= 1 << 23,
+	IB_PORT_LINK_LATENCY_SUP		= 1 << 24,
+	IB_PORT_CLIENT_REG_SUP			= 1 << 25
+};
+
+enum ib_port_width {
+	IB_WIDTH_1X	= 1,
+	IB_WIDTH_4X	= 2,
+	IB_WIDTH_8X	= 4,
+	IB_WIDTH_12X	= 8
+};
+
+static inline int ib_width_enum_to_int(enum ib_port_width width)
+{
+	switch (width) {
+	case IB_WIDTH_1X:  return  1;
+	case IB_WIDTH_4X:  return  4;
+	case IB_WIDTH_8X:  return  8;
+	case IB_WIDTH_12X: return 12;
+	default: 	  return -1;
+	}
+}
+
+struct ib_port_attr {
+	enum ib_port_state	state;
+	enum ib_mtu		max_mtu;
+	enum ib_mtu		active_mtu;
+	int			gid_tbl_len;
+	u32			port_cap_flags;
+	u32			max_msg_sz;
+	u32			bad_pkey_cntr;
+	u32			qkey_viol_cntr;
+	u16			pkey_tbl_len;
+	u16			lid;
+	u16			sm_lid;
+	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;
+};
+
+enum ib_device_modify_flags {
+	IB_DEVICE_MODIFY_SYS_IMAGE_GUID	= 1
+};
+
+struct ib_device_modify {
+	u64	sys_image_guid;
+};
+
+enum ib_port_modify_flags {
+	IB_PORT_SHUTDOWN		= 1,
+	IB_PORT_INIT_TYPE		= (1<<2),
+	IB_PORT_RESET_QKEY_CNTR		= (1<<3)
+};
+
+struct ib_port_modify {
+	u32	set_port_cap_mask;
+	u32	clr_port_cap_mask;
+	u8	init_type;
+};
+
+enum ib_event_type {
+	IB_EVENT_CQ_ERR,
+	IB_EVENT_QP_FATAL,
+	IB_EVENT_QP_REQ_ERR,
+	IB_EVENT_QP_ACCESS_ERR,
+	IB_EVENT_COMM_EST,
+	IB_EVENT_SQ_DRAINED,
+	IB_EVENT_PATH_MIG,
+	IB_EVENT_PATH_MIG_ERR,
+	IB_EVENT_DEVICE_FATAL,
+	IB_EVENT_PORT_ACTIVE,
+	IB_EVENT_PORT_ERR,
+	IB_EVENT_LID_CHANGE,
+	IB_EVENT_PKEY_CHANGE,
+	IB_EVENT_SM_CHANGE
+};
+
+struct ib_event {
+	struct ib_device	*device;
+	union {
+		struct ib_cq	*cq;
+		struct ib_qp	*qp;
+		u8		port_num;
+	} element;
+	enum ib_event_type	event;
+};
+
+struct ib_event_handler {
+	struct ib_device *device;
+	void            (*handler)(struct ib_event_handler *, struct ib_event *);
+	struct list_head  list;
+};
+
+#define INIT_IB_EVENT_HANDLER(_ptr, _device, _handler)		\
+	do {							\
+		(_ptr)->device  = _device;			\
+		(_ptr)->handler = _handler;			\
+		INIT_LIST_HEAD(&(_ptr)->list);			\
+	} while (0)
+
+struct ib_global_route {
+	union ib_gid	dgid;
+	u32		flow_label;
+	u8		sgid_index;
+	u8		hop_limit;
+	u8		traffic_class;
+};
+
+enum {
+	IB_MULTICAST_QPN = 0xffffff
+};
+
+enum ib_ah_flags {
+	IB_AH_GRH	= 1
+};
+
+struct ib_ah_attr {
+	struct ib_global_route	grh;
+	u16			dlid;
+	u8			sl;
+	u8			src_path_bits;
+	u8			static_rate;
+	u8			ah_flags;
+	u8			port_num;
+};
+
+enum ib_wc_status {
+	IB_WC_SUCCESS,
+	IB_WC_LOC_LEN_ERR,
+	IB_WC_LOC_QP_OP_ERR,
+	IB_WC_LOC_EEC_OP_ERR,
+	IB_WC_LOC_PROT_ERR,
+	IB_WC_WR_FLUSH_ERR,
+	IB_WC_MW_BIND_ERR,
+	IB_WC_BAD_RESP_ERR,
+	IB_WC_LOC_ACCESS_ERR,
+	IB_WC_REM_INV_REQ_ERR,
+	IB_WC_REM_ACCESS_ERR,
+	IB_WC_REM_OP_ERR,
+	IB_WC_RETRY_EXC_ERR,
+	IB_WC_RNR_RETRY_EXC_ERR,
+	IB_WC_LOC_RDD_VIOL_ERR,
+	IB_WC_REM_INV_RD_REQ_ERR,
+	IB_WC_REM_ABORT_ERR,
+	IB_WC_INV_EECN_ERR,
+	IB_WC_INV_EEC_STATE_ERR,
+	IB_WC_FATAL_ERR,
+	IB_WC_RESP_TIMEOUT_ERR,
+	IB_WC_GENERAL_ERR
+};
+
+enum ib_wc_opcode {
+	IB_WC_SEND,
+	IB_WC_RDMA_WRITE,
+	IB_WC_RDMA_READ,
+	IB_WC_COMP_SWAP,
+	IB_WC_FETCH_ADD,
+	IB_WC_BIND_MW,
+/*
+ * Set value of IB_WC_RECV so consumers can test if a completion is a
+ * receive by testing (opcode & IB_WC_RECV).
+ */
+	IB_WC_RECV			= 1 << 7,
+	IB_WC_RECV_RDMA_WITH_IMM
+};
+
+enum ib_wc_flags {
+	IB_WC_GRH		= 1,
+	IB_WC_WITH_IMM		= (1<<1)
+};
+
+struct ib_wc {
+	u64			wr_id;
+	enum ib_wc_status	status;
+	enum ib_wc_opcode	opcode;
+	u32			vendor_err;
+	u32			byte_len;
+	__be32			imm_data;
+	u32			qp_num;
+	u32			src_qp;
+	int			wc_flags;
+	u16			pkey_index;
+	u16			slid;
+	u8			sl;
+	u8			dlid_path_bits;
+	u8			port_num;	/* valid only for DR SMPs on switches */
+};
+
+enum ib_cq_notify {
+	IB_CQ_SOLICITED,
+	IB_CQ_NEXT_COMP
+};
+
+struct ib_qp_cap {
+	u32	max_send_wr;
+	u32	max_recv_wr;
+	u32	max_send_sge;
+	u32	max_recv_sge;
+	u32	max_inline_data;
+};
+
+enum ib_sig_type {
+	IB_SIGNAL_ALL_WR,
+	IB_SIGNAL_REQ_WR
+};
+
+enum ib_qp_type {
+	/*
+	 * IB_QPT_SMI and IB_QPT_GSI have to be the first two entries
+	 * here (and in that order) since the MAD layer uses them as
+	 * indices into a 2-entry table.
+	 */
+	IB_QPT_SMI,
+	IB_QPT_GSI,
+
+	IB_QPT_RC,
+	IB_QPT_UC,
+	IB_QPT_UD,
+	IB_QPT_RAW_IPV6,
+	IB_QPT_RAW_ETY
+};
+
+struct ib_qp_init_attr {
+	void                  (*event_handler)(struct ib_event *, void *);
+	void		       *qp_context;
+	struct ib_cq	       *send_cq;
+	struct ib_cq	       *recv_cq;
+	struct ib_srq	       *srq;
+	struct ib_qp_cap	cap;
+	enum ib_sig_type	sq_sig_type;
+	enum ib_sig_type	rq_sig_type;
+	enum ib_qp_type		qp_type;
+	u8			port_num; /* special QP types only */
+};
+
+enum ib_rnr_timeout {
+	IB_RNR_TIMER_655_36 =  0,
+	IB_RNR_TIMER_000_01 =  1,
+	IB_RNR_TIMER_000_02 =  2,
+	IB_RNR_TIMER_000_03 =  3,
+	IB_RNR_TIMER_000_04 =  4,
+	IB_RNR_TIMER_000_06 =  5,
+	IB_RNR_TIMER_000_08 =  6,
+	IB_RNR_TIMER_000_12 =  7,
+	IB_RNR_TIMER_000_16 =  8,
+	IB_RNR_TIMER_000_24 =  9,
+	IB_RNR_TIMER_000_32 = 10,
+	IB_RNR_TIMER_000_48 = 11,
+	IB_RNR_TIMER_000_64 = 12,
+	IB_RNR_TIMER_000_96 = 13,
+	IB_RNR_TIMER_001_28 = 14,
+	IB_RNR_TIMER_001_92 = 15,
+	IB_RNR_TIMER_002_56 = 16,
+	IB_RNR_TIMER_003_84 = 17,
+	IB_RNR_TIMER_005_12 = 18,
+	IB_RNR_TIMER_007_68 = 19,
+	IB_RNR_TIMER_010_24 = 20,
+	IB_RNR_TIMER_015_36 = 21,
+	IB_RNR_TIMER_020_48 = 22,
+	IB_RNR_TIMER_030_72 = 23,
+	IB_RNR_TIMER_040_96 = 24,
+	IB_RNR_TIMER_061_44 = 25,
+	IB_RNR_TIMER_081_92 = 26,
+	IB_RNR_TIMER_122_88 = 27,
+	IB_RNR_TIMER_163_84 = 28,
+	IB_RNR_TIMER_245_76 = 29,
+	IB_RNR_TIMER_327_68 = 30,
+	IB_RNR_TIMER_491_52 = 31
+};
+
+enum ib_qp_attr_mask {
+	IB_QP_STATE			= 1,
+	IB_QP_CUR_STATE			= (1<<1),
+	IB_QP_EN_SQD_ASYNC_NOTIFY	= (1<<2),
+	IB_QP_ACCESS_FLAGS		= (1<<3),
+	IB_QP_PKEY_INDEX		= (1<<4),
+	IB_QP_PORT			= (1<<5),
+	IB_QP_QKEY			= (1<<6),
+	IB_QP_AV			= (1<<7),
+	IB_QP_PATH_MTU			= (1<<8),
+	IB_QP_TIMEOUT			= (1<<9),
+	IB_QP_RETRY_CNT			= (1<<10),
+	IB_QP_RNR_RETRY			= (1<<11),
+	IB_QP_RQ_PSN			= (1<<12),
+	IB_QP_MAX_QP_RD_ATOMIC		= (1<<13),
+	IB_QP_ALT_PATH			= (1<<14),
+	IB_QP_MIN_RNR_TIMER		= (1<<15),
+	IB_QP_SQ_PSN			= (1<<16),
+	IB_QP_MAX_DEST_RD_ATOMIC	= (1<<17),
+	IB_QP_PATH_MIG_STATE		= (1<<18),
+	IB_QP_CAP			= (1<<19),
+	IB_QP_DEST_QPN			= (1<<20)
+};
+
+enum ib_qp_state {
+	IB_QPS_RESET,
+	IB_QPS_INIT,
+	IB_QPS_RTR,
+	IB_QPS_RTS,
+	IB_QPS_SQD,
+	IB_QPS_SQE,
+	IB_QPS_ERR
+};
+
+enum ib_mig_state {
+	IB_MIG_MIGRATED,
+	IB_MIG_REARM,
+	IB_MIG_ARMED
+};
+
+struct ib_qp_attr {
+	enum ib_qp_state	qp_state;
+	enum ib_qp_state	cur_qp_state;
+	enum ib_mtu		path_mtu;
+	enum ib_mig_state	path_mig_state;
+	u32			qkey;
+	u32			rq_psn;
+	u32			sq_psn;
+	u32			dest_qp_num;
+	int			qp_access_flags;
+	struct ib_qp_cap	cap;
+	struct ib_ah_attr	ah_attr;
+	struct ib_ah_attr	alt_ah_attr;
+	u16			pkey_index;
+	u16			alt_pkey_index;
+	u8			en_sqd_async_notify;
+	u8			sq_draining;
+	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;
+};
+
+enum ib_wr_opcode {
+	IB_WR_RDMA_WRITE,
+	IB_WR_RDMA_WRITE_WITH_IMM,
+	IB_WR_SEND,
+	IB_WR_SEND_WITH_IMM,
+	IB_WR_RDMA_READ,
+	IB_WR_ATOMIC_CMP_AND_SWP,
+	IB_WR_ATOMIC_FETCH_AND_ADD
+};
+
+enum ib_send_flags {
+	IB_SEND_FENCE		= 1,
+	IB_SEND_SIGNALED	= (1<<1),
+	IB_SEND_SOLICITED	= (1<<2),
+	IB_SEND_INLINE		= (1<<3)
+};
+
+enum ib_recv_flags {
+	IB_RECV_SIGNALED	= 1
+};
+
+struct ib_sge {
+	u64	addr;
+	u32	length;
+	u32	lkey;
+};
+
+struct ib_send_wr {
+	struct ib_send_wr      *next;
+	u64			wr_id;
+	struct ib_sge	       *sg_list;
+	int			num_sge;
+	enum ib_wr_opcode	opcode;
+	int			send_flags;
+	u32			imm_data;
+	union {
+		struct {
+			u64	remote_addr;
+			u32	rkey;
+		} rdma;
+		struct {
+			u64	remote_addr;
+			u64	compare_add;
+			u64	swap;
+			u32	rkey;
+		} atomic;
+		struct {
+			struct ib_ah *ah;
+			struct ib_mad_hdr *mad_hdr;
+			u32	remote_qpn;
+			u32	remote_qkey;
+			int	timeout_ms; /* valid for MADs only */
+			u16	pkey_index; /* valid for GSI only */
+			u8	port_num;   /* valid for DR SMPs on switch only */
+		} ud;
+	} wr;
+};
+
+struct ib_recv_wr {
+	struct ib_recv_wr      *next;
+	u64			wr_id;
+	struct ib_sge	       *sg_list;
+	int			num_sge;
+	int			recv_flags;
+};
+
+enum ib_access_flags {
+	IB_ACCESS_LOCAL_WRITE	= 1,
+	IB_ACCESS_REMOTE_WRITE	= (1<<1),
+	IB_ACCESS_REMOTE_READ	= (1<<2),
+	IB_ACCESS_REMOTE_ATOMIC	= (1<<3),
+	IB_ACCESS_MW_BIND	= (1<<4)
+};
+
+struct ib_phys_buf {
+	u64      addr;
+	u64      size;
+};
+
+struct ib_mr_attr {
+	struct ib_pd	*pd;
+	u64		device_virt_addr;
+	u64		size;
+	int		mr_access_flags;
+	u32		lkey;
+	u32		rkey;
+};
+
+enum ib_mr_rereg_flags {
+	IB_MR_REREG_TRANS	= 1,
+	IB_MR_REREG_PD		= (1<<1),
+	IB_MR_REREG_ACCESS	= (1<<2)
+};
+
+struct ib_mw_bind {
+	struct ib_mr   *mr;
+	u64		wr_id;
+	u64		addr;
+	u32		length;
+	int		send_flags;
+	int		mw_access_flags;
+};
+
+struct ib_fmr_attr {
+	int	max_pages;
+	int	max_maps;
+	u8	page_size;
+};
+
+struct ib_pd {
+	struct ib_device *device;
+	atomic_t          usecnt; /* count all resources */
+};
+
+struct ib_ah {
+	struct ib_device	*device;
+	struct ib_pd		*pd;
+};
+
+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_srq {
+	struct ib_device	*device;
+	struct ib_pd		*pd;
+	void			*srq_context;
+	atomic_t		usecnt;
+};
+
+struct ib_qp {
+	struct ib_device       *device;
+	struct ib_pd	       *pd;
+	struct ib_cq	       *send_cq;
+	struct ib_cq	       *recv_cq;
+	struct ib_srq	       *srq;
+	void                  (*event_handler)(struct ib_event *, void *);
+	void		       *qp_context;
+	u32			qp_num;
+	enum ib_qp_type		qp_type;
+};
+
+struct ib_mr {
+	struct ib_device *device;
+	struct ib_pd     *pd;
+	u32		  lkey;
+	u32		  rkey;
+	atomic_t          usecnt; /* count number of MWs */
+};
+
+struct ib_mw {
+	struct ib_device	*device;
+	struct ib_pd		*pd;
+	u32			rkey;
+};
+
+struct ib_fmr {
+	struct ib_device	*device;
+	struct ib_pd		*pd;
+	struct list_head	list;
+	u32			lkey;
+	u32			rkey;
+};
+
+struct ib_mad;
+struct ib_grh;
+
+enum ib_process_mad_flags {
+	IB_MAD_IGNORE_MKEY	= 1,
+	IB_MAD_IGNORE_BKEY	= 2,
+	IB_MAD_IGNORE_ALL	= IB_MAD_IGNORE_MKEY | IB_MAD_IGNORE_BKEY
+};
+
+enum ib_mad_result {
+	IB_MAD_RESULT_FAILURE  = 0,      /* (!SUCCESS is the important flag) */
+	IB_MAD_RESULT_SUCCESS  = 1 << 0, /* MAD was successfully processed   */
+	IB_MAD_RESULT_REPLY    = 1 << 1, /* Reply packet needs to be sent    */
+	IB_MAD_RESULT_CONSUMED = 1 << 2  /* Packet consumed: stop processing */
+};
+
+#define IB_DEVICE_NAME_MAX 64
+
+struct ib_cache {
+	rwlock_t                lock;
+	struct ib_event_handler event_handler;
+	struct ib_pkey_cache  **pkey_cache;
+	struct ib_gid_cache   **gid_cache;
+};
+
+struct ib_device {
+	struct device                *dma_device;
+
+	char                          name[IB_DEVICE_NAME_MAX];
+
+	struct list_head              event_handler_list;
+	spinlock_t                    event_handler_lock;
+
+	struct list_head              core_list;
+	struct list_head              client_data_list;
+	spinlock_t                    client_data_lock;
+
+	struct ib_cache               cache;
+
+	u32                           flags;
+
+	int		           (*query_device)(struct ib_device *device,
+						   struct ib_device_attr *device_attr);
+	int		           (*query_port)(struct ib_device *device,
+						 u8 port_num,
+						 struct ib_port_attr *port_attr);
+	int		           (*query_gid)(struct ib_device *device,
+						u8 port_num, int index,
+						union ib_gid *gid);
+	int		           (*query_pkey)(struct ib_device *device,
+						 u8 port_num, u16 index, u16 *pkey);
+	int		           (*modify_device)(struct ib_device *device,
+						    int device_modify_mask,
+						    struct ib_device_modify *device_modify);
+	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);
+	int                        (*dealloc_pd)(struct ib_pd *pd);
+	struct ib_ah *             (*create_ah)(struct ib_pd *pd,
+						struct ib_ah_attr *ah_attr);
+	int                        (*modify_ah)(struct ib_ah *ah,
+						struct ib_ah_attr *ah_attr);
+	int                        (*query_ah)(struct ib_ah *ah,
+					       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);
+	int                        (*modify_qp)(struct ib_qp *qp,
+						struct ib_qp_attr *qp_attr,
+						int qp_attr_mask);
+	int                        (*query_qp)(struct ib_qp *qp,
+					       struct ib_qp_attr *qp_attr,
+					       int qp_attr_mask,
+					       struct ib_qp_init_attr *qp_init_attr);
+	int                        (*destroy_qp)(struct ib_qp *qp);
+	int                        (*post_send)(struct ib_qp *qp,
+						struct ib_send_wr *send_wr,
+						struct ib_send_wr **bad_send_wr);
+	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);
+	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,
+					      struct ib_wc *wc);
+	int                        (*peek_cq)(struct ib_cq *cq, int wc_cnt);
+	int                        (*req_notify_cq)(struct ib_cq *cq,
+						    enum ib_cq_notify cq_notify);
+	int                        (*req_ncomp_notif)(struct ib_cq *cq,
+						      int wc_cnt);
+	struct ib_mr *             (*get_dma_mr)(struct ib_pd *pd,
+						 int mr_access_flags);
+	struct ib_mr *             (*reg_phys_mr)(struct ib_pd *pd,
+						  struct ib_phys_buf *phys_buf_array,
+						  int num_phys_buf,
+						  int mr_access_flags,
+						  u64 *iova_start);
+	int                        (*query_mr)(struct ib_mr *mr,
+					       struct ib_mr_attr *mr_attr);
+	int                        (*dereg_mr)(struct ib_mr *mr);
+	int                        (*rereg_phys_mr)(struct ib_mr *mr,
+						    int mr_rereg_mask,
+						    struct ib_pd *pd,
+						    struct ib_phys_buf *phys_buf_array,
+						    int num_phys_buf,
+						    int mr_access_flags,
+						    u64 *iova_start);
+	struct ib_mw *             (*alloc_mw)(struct ib_pd *pd);
+	int                        (*bind_mw)(struct ib_qp *qp,
+					      struct ib_mw *mw,
+					      struct ib_mw_bind *mw_bind);
+	int                        (*dealloc_mw)(struct ib_mw *mw);
+	struct ib_fmr *	           (*alloc_fmr)(struct ib_pd *pd,
+						int mr_access_flags,
+						struct ib_fmr_attr *fmr_attr);
+	int		           (*map_phys_fmr)(struct ib_fmr *fmr,
+						   u64 *page_list, int list_len,
+						   u64 iova);
+	int		           (*unmap_fmr)(struct list_head *fmr_list);
+	int		           (*dealloc_fmr)(struct ib_fmr *fmr);
+	int                        (*attach_mcast)(struct ib_qp *qp,
+						   union ib_gid *gid,
+						   u16 lid);
+	int                        (*detach_mcast)(struct ib_qp *qp,
+						   union ib_gid *gid,
+						   u16 lid);
+	int                        (*process_mad)(struct ib_device *device,
+						  int process_mad_flags,
+						  u8 port_num,
+						  struct ib_wc *in_wc,
+						  struct ib_grh *in_grh,
+						  struct ib_mad *in_mad,
+						  struct ib_mad *out_mad);
+
+	struct class_device          class_dev;
+	struct kobject               ports_parent;
+	struct list_head             port_list;
+
+	enum {
+		IB_DEV_UNINITIALIZED,
+		IB_DEV_REGISTERED,
+		IB_DEV_UNREGISTERED
+	}                            reg_state;
+
+	u8                           node_type;
+	u8                           phys_port_cnt;
+};
+
+struct ib_client {
+	char  *name;
+	void (*add)   (struct ib_device *);
+	void (*remove)(struct ib_device *);
+
+	struct list_head list;
+};
+
+struct ib_device *ib_alloc_device(size_t size);
+void ib_dealloc_device(struct ib_device *device);
+
+int ib_register_device   (struct ib_device *device);
+void ib_unregister_device(struct ib_device *device);
+
+int ib_register_client   (struct ib_client *client);
+void ib_unregister_client(struct ib_client *client);
+
+void *ib_get_client_data(struct ib_device *device, struct ib_client *client);
+void  ib_set_client_data(struct ib_device *device, struct ib_client *client,
+			 void *data);
+
+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);
+
+int ib_query_device(struct ib_device *device,
+		    struct ib_device_attr *device_attr);
+
+int ib_query_port(struct ib_device *device,
+		  u8 port_num, struct ib_port_attr *port_attr);
+
+int ib_query_gid(struct ib_device *device,
+		 u8 port_num, int index, union ib_gid *gid);
+
+int ib_query_pkey(struct ib_device *device,
+		  u8 port_num, u16 index, u16 *pkey);
+
+int ib_modify_device(struct ib_device *device,
+		     int device_modify_mask,
+		     struct ib_device_modify *device_modify);
+
+int ib_modify_port(struct ib_device *device,
+		   u8 port_num, int port_modify_mask,
+		   struct ib_port_modify *port_modify);
+
+/**
+ * ib_alloc_pd - Allocates an unused protection domain.
+ * @device: The device on which to allocate the protection domain.
+ *
+ * A protection domain object provides an association between QPs, shared
+ * receive queues, address handles, memory regions, and memory windows.
+ */
+struct ib_pd *ib_alloc_pd(struct ib_device *device);
+
+/**
+ * ib_dealloc_pd - Deallocates a protection domain.
+ * @pd: The protection domain to deallocate.
+ */
+int ib_dealloc_pd(struct ib_pd *pd);
+
+/**
+ * ib_create_ah - Creates an address handle for the given address vector.
+ * @pd: The protection domain associated with the address handle.
+ * @ah_attr: The attributes of the address vector.
+ *
+ * The address handle is used to reference a local or global destination
+ * in all UD QP post sends.
+ */
+struct ib_ah *ib_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr);
+
+/**
+ * ib_modify_ah - Modifies the address vector associated with an address
+ *   handle.
+ * @ah: The address handle to modify.
+ * @ah_attr: The new address vector attributes to associate with the
+ *   address handle.
+ */
+int ib_modify_ah(struct ib_ah *ah, struct ib_ah_attr *ah_attr);
+
+/**
+ * ib_query_ah - Queries the address vector associated with an address
+ *   handle.
+ * @ah: The address handle to query.
+ * @ah_attr: The address vector attributes associated with the address
+ *   handle.
+ */
+int ib_query_ah(struct ib_ah *ah, struct ib_ah_attr *ah_attr);
+
+/**
+ * ib_destroy_ah - Destroys an address handle.
+ * @ah: The address handle to destroy.
+ */
+int ib_destroy_ah(struct ib_ah *ah);
+
+/**
+ * ib_create_qp - Creates a QP associated with the specified protection
+ *   domain.
+ * @pd: The protection domain associated with the QP.
+ * @qp_init_attr: A list of initial attributes required to create the QP.
+ */
+struct ib_qp *ib_create_qp(struct ib_pd *pd,
+			   struct ib_qp_init_attr *qp_init_attr);
+
+/**
+ * ib_modify_qp - Modifies the attributes for the specified QP and then
+ *   transitions the QP to the given state.
+ * @qp: The QP to modify.
+ * @qp_attr: On input, specifies the QP attributes to modify.  On output,
+ *   the current values of selected QP attributes are returned.
+ * @qp_attr_mask: A bit-mask used to specify which attributes of the QP
+ *   are being modified.
+ */
+int ib_modify_qp(struct ib_qp *qp,
+		 struct ib_qp_attr *qp_attr,
+		 int qp_attr_mask);
+
+/**
+ * ib_query_qp - Returns the attribute list and current values for the
+ *   specified QP.
+ * @qp: The QP to query.
+ * @qp_attr: The attributes of the specified QP.
+ * @qp_attr_mask: A bit-mask used to select specific attributes to query.
+ * @qp_init_attr: Additional attributes of the selected QP.
+ *
+ * The qp_attr_mask may be used to limit the query to gathering only the
+ * selected attributes.
+ */
+int ib_query_qp(struct ib_qp *qp,
+		struct ib_qp_attr *qp_attr,
+		int qp_attr_mask,
+		struct ib_qp_init_attr *qp_init_attr);
+
+/**
+ * ib_destroy_qp - Destroys the specified QP.
+ * @qp: The QP to destroy.
+ */
+int ib_destroy_qp(struct ib_qp *qp);
+
+/**
+ * ib_post_send - Posts a list of work requests to the send queue of
+ *   the specified QP.
+ * @qp: The QP to post the work request on.
+ * @send_wr: A list of work requests to post on the send queue.
+ * @bad_send_wr: On an immediate failure, this parameter will reference
+ *   the work request that failed to be posted on the QP.
+ */
+static inline int ib_post_send(struct ib_qp *qp,
+			       struct ib_send_wr *send_wr,
+			       struct ib_send_wr **bad_send_wr)
+{
+	return qp->device->post_send(qp, send_wr, bad_send_wr);
+}
+
+/**
+ * ib_post_recv - Posts a list of work requests to the receive queue of
+ *   the specified QP.
+ * @qp: The QP to post the work request on.
+ * @recv_wr: A list of work requests to post on the receive queue.
+ * @bad_recv_wr: On an immediate failure, this parameter will reference
+ *   the work request that failed to be posted on the QP.
+ */
+static inline int ib_post_recv(struct ib_qp *qp,
+			       struct ib_recv_wr *recv_wr,
+			       struct ib_recv_wr **bad_recv_wr)
+{
+	return qp->device->post_recv(qp, recv_wr, bad_recv_wr);
+}
+
+/**
+ * ib_create_cq - Creates a CQ on the specified device.
+ * @device: The device on which to create the CQ.
+ * @comp_handler: A user-specified callback that is invoked when a
+ *   completion event occurs on the CQ.
+ * @event_handler: A user-specified callback that is invoked when an
+ *   asynchronous event not associated with a completion occurs on the CQ.
+ * @cq_context: Context associated with the CQ returned to the user via
+ *   the associated completion and event handlers.
+ * @cqe: The minimum size of the CQ.
+ *
+ * Users can examine the cq structure to determine the actual CQ size.
+ */
+struct ib_cq *ib_create_cq(struct ib_device *device,
+			   ib_comp_handler comp_handler,
+			   void (*event_handler)(struct ib_event *, void *),
+			   void *cq_context, int cqe);
+
+/**
+ * ib_resize_cq - Modifies the capacity of the CQ.
+ * @cq: The CQ to resize.
+ * @cqe: The minimum size of the CQ.
+ *
+ * Users can examine the cq structure to determine the actual CQ size.
+ */
+int ib_resize_cq(struct ib_cq *cq, int cqe);
+
+/**
+ * ib_destroy_cq - Destroys the specified CQ.
+ * @cq: The CQ to destroy.
+ */
+int ib_destroy_cq(struct ib_cq *cq);
+
+/**
+ * ib_poll_cq - poll a CQ for completion(s)
+ * @cq:the CQ being polled
+ * @num_entries:maximum number of completions to return
+ * @wc:array of at least @num_entries &struct ib_wc where completions
+ *   will be returned
+ *
+ * Poll a CQ for (possibly multiple) completions.  If the return value
+ * is < 0, an error occurred.  If the return value is >= 0, it is the
+ * number of completions returned.  If the return value is
+ * non-negative and < num_entries, then the CQ was emptied.
+ */
+static inline int ib_poll_cq(struct ib_cq *cq, int num_entries,
+			     struct ib_wc *wc)
+{
+	return cq->device->poll_cq(cq, num_entries, wc);
+}
+
+/**
+ * ib_peek_cq - Returns the number of unreaped completions currently
+ *   on the specified CQ.
+ * @cq: The CQ to peek.
+ * @wc_cnt: A minimum number of unreaped completions to check for.
+ *
+ * If the number of unreaped completions is greater than or equal to wc_cnt,
+ * this function returns wc_cnt, otherwise, it returns the actual number of
+ * unreaped completions.
+ */
+int ib_peek_cq(struct ib_cq *cq, int wc_cnt);
+
+/**
+ * ib_req_notify_cq - Request completion notification on a CQ.
+ * @cq: The CQ to generate an event for.
+ * @cq_notify: If set to %IB_CQ_SOLICITED, completion notification will
+ *   occur on the next solicited event. If set to %IB_CQ_NEXT_COMP,
+ *   notification will occur on the next completion.
+ */
+static inline int ib_req_notify_cq(struct ib_cq *cq,
+				   enum ib_cq_notify cq_notify)
+{
+	return cq->device->req_notify_cq(cq, cq_notify);
+}
+
+/**
+ * ib_req_ncomp_notif - Request completion notification when there are
+ *   at least the specified number of unreaped completions on the CQ.
+ * @cq: The CQ to generate an event for.
+ * @wc_cnt: The number of unreaped completions that should be on the
+ *   CQ before an event is generated.
+ */
+static inline int ib_req_ncomp_notif(struct ib_cq *cq, int wc_cnt)
+{
+	return cq->device->req_ncomp_notif ?
+		cq->device->req_ncomp_notif(cq, wc_cnt) :
+		-ENOSYS;
+}
+
+/**
+ * ib_get_dma_mr - Returns a memory region for system memory that is
+ *   usable for DMA.
+ * @pd: The protection domain associated with the memory region.
+ * @mr_access_flags: Specifies the memory access rights.
+ */
+struct ib_mr *ib_get_dma_mr(struct ib_pd *pd, int mr_access_flags);
+
+/**
+ * ib_reg_phys_mr - Prepares a virtually addressed memory region for use
+ *   by an HCA.
+ * @pd: The protection domain associated assigned to the registered region.
+ * @phys_buf_array: Specifies a list of physical buffers to use in the
+ *   memory region.
+ * @num_phys_buf: Specifies the size of the phys_buf_array.
+ * @mr_access_flags: Specifies the memory access rights.
+ * @iova_start: The offset of the region's starting I/O virtual address.
+ */
+struct ib_mr *ib_reg_phys_mr(struct ib_pd *pd,
+			     struct ib_phys_buf *phys_buf_array,
+			     int num_phys_buf,
+			     int mr_access_flags,
+			     u64 *iova_start);
+
+/**
+ * ib_rereg_phys_mr - Modifies the attributes of an existing memory region.
+ *   Conceptually, this call performs the functions deregister memory region
+ *   followed by register physical memory region.  Where possible,
+ *   resources are reused instead of deallocated and reallocated.
+ * @mr: The memory region to modify.
+ * @mr_rereg_mask: A bit-mask used to indicate which of the following
+ *   properties of the memory region are being modified.
+ * @pd: If %IB_MR_REREG_PD is set in mr_rereg_mask, this field specifies
+ *   the new protection domain to associated with the memory region,
+ *   otherwise, this parameter is ignored.
+ * @phys_buf_array: If %IB_MR_REREG_TRANS is set in mr_rereg_mask, this
+ *   field specifies a list of physical buffers to use in the new
+ *   translation, otherwise, this parameter is ignored.
+ * @num_phys_buf: If %IB_MR_REREG_TRANS is set in mr_rereg_mask, this
+ *   field specifies the size of the phys_buf_array, otherwise, this
+ *   parameter is ignored.
+ * @mr_access_flags: If %IB_MR_REREG_ACCESS is set in mr_rereg_mask, this
+ *   field specifies the new memory access rights, otherwise, this
+ *   parameter is ignored.
+ * @iova_start: The offset of the region's starting I/O virtual address.
+ */
+int ib_rereg_phys_mr(struct ib_mr *mr,
+		     int mr_rereg_mask,
+		     struct ib_pd *pd,
+		     struct ib_phys_buf *phys_buf_array,
+		     int num_phys_buf,
+		     int mr_access_flags,
+		     u64 *iova_start);
+
+/**
+ * ib_query_mr - Retrieves information about a specific memory region.
+ * @mr: The memory region to retrieve information about.
+ * @mr_attr: The attributes of the specified memory region.
+ */
+int ib_query_mr(struct ib_mr *mr, struct ib_mr_attr *mr_attr);
+
+/**
+ * ib_dereg_mr - Deregisters a memory region and removes it from the
+ *   HCA translation table.
+ * @mr: The memory region to deregister.
+ */
+int ib_dereg_mr(struct ib_mr *mr);
+
+/**
+ * ib_alloc_mw - Allocates a memory window.
+ * @pd: The protection domain associated with the memory window.
+ */
+struct ib_mw *ib_alloc_mw(struct ib_pd *pd);
+
+/**
+ * ib_bind_mw - Posts a work request to the send queue of the specified
+ *   QP, which binds the memory window to the given address range and
+ *   remote access attributes.
+ * @qp: QP to post the bind work request on.
+ * @mw: The memory window to bind.
+ * @mw_bind: Specifies information about the memory window, including
+ *   its address range, remote access rights, and associated memory region.
+ */
+static inline int ib_bind_mw(struct ib_qp *qp,
+			     struct ib_mw *mw,
+			     struct ib_mw_bind *mw_bind)
+{
+	/* XXX reference counting in corresponding MR? */
+	return mw->device->bind_mw ?
+		mw->device->bind_mw(qp, mw, mw_bind) :
+		-ENOSYS;
+}
+
+/**
+ * ib_dealloc_mw - Deallocates a memory window.
+ * @mw: The memory window to deallocate.
+ */
+int ib_dealloc_mw(struct ib_mw *mw);
+
+/**
+ * ib_alloc_fmr - Allocates a unmapped fast memory region.
+ * @pd: The protection domain associated with the unmapped region.
+ * @mr_access_flags: Specifies the memory access rights.
+ * @fmr_attr: Attributes of the unmapped region.
+ *
+ * A fast memory region must be mapped before it can be used as part of
+ * a work request.
+ */
+struct ib_fmr *ib_alloc_fmr(struct ib_pd *pd,
+			    int mr_access_flags,
+			    struct ib_fmr_attr *fmr_attr);
+
+/**
+ * ib_map_phys_fmr - Maps a list of physical pages to a fast memory region.
+ * @fmr: The fast memory region to associate with the pages.
+ * @page_list: An array of physical pages to map to the fast memory region.
+ * @list_len: The number of pages in page_list.
+ * @iova: The I/O virtual address to use with the mapped region.
+ */
+static inline int ib_map_phys_fmr(struct ib_fmr *fmr,
+				  u64 *page_list, int list_len,
+				  u64 iova)
+{
+	return fmr->device->map_phys_fmr(fmr, page_list, list_len, iova);
+}
+
+/**
+ * ib_unmap_fmr - Removes the mapping from a list of fast memory regions.
+ * @fmr_list: A linked list of fast memory regions to unmap.
+ */
+int ib_unmap_fmr(struct list_head *fmr_list);
+
+/**
+ * ib_dealloc_fmr - Deallocates a fast memory region.
+ * @fmr: The fast memory region to deallocate.
+ */
+int ib_dealloc_fmr(struct ib_fmr *fmr);
+
+/**
+ * ib_attach_mcast - Attaches the specified QP to a multicast group.
+ * @qp: QP to attach to the multicast group.  The QP must be type
+ *   IB_QPT_UD.
+ * @gid: Multicast group GID.
+ * @lid: Multicast group LID in host byte order.
+ *
+ * In order to send and receive multicast packets, subnet
+ * administration must have created the multicast group and configured
+ * the fabric appropriately.  The port associated with the specified
+ * QP must also be a member of the multicast group.
+ */
+int ib_attach_mcast(struct ib_qp *qp, union ib_gid *gid, u16 lid);
+
+/**
+ * ib_detach_mcast - Detaches the specified QP from a multicast group.
+ * @qp: QP to detach from the multicast group.
+ * @gid: Multicast group GID.
+ * @lid: Multicast group LID in host byte order.
+ */
+int ib_detach_mcast(struct ib_qp *qp, union ib_gid *gid, u16 lid);
+
+#endif /* IB_VERBS_H */
diff -Nru a/drivers/infiniband/ulp/ipoib/Kconfig b/drivers/infiniband/ulp/ipoib/Kconfig
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/infiniband/ulp/ipoib/Kconfig	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,33 @@
+config INFINIBAND_IPOIB
+	tristate "IP-over-InfiniBand"
+	depends on INFINIBAND && NETDEVICES && INET
+	---help---
+	  Support for the IP-over-InfiniBand protocol (IPoIB). This
+	  transports IP packets over InfiniBand so you can use your IB
+	  device as a fancy NIC.
+
+	  The IPoIB protocol is defined by the IETF ipoib working
+	  group: <http://www.ietf.org/html.charters/ipoib-charter.html>.
+
+config INFINIBAND_IPOIB_DEBUG
+	bool "IP-over-InfiniBand debugging"
+	depends on INFINIBAND_IPOIB
+	---help---
+	  This option causes debugging code to be compiled into the
+	  IPoIB driver.  The output can be turned on via the
+	  debug_level and mcast_debug_level module parameters (which
+	  can also be set after the driver is loaded through sysfs).
+
+	  This option also creates an "ipoib_debugfs," which can be
+	  mounted to expose debugging information about IB multicast
+	  groups used by the IPoIB driver.
+
+config INFINIBAND_IPOIB_DEBUG_DATA
+	bool "IP-over-InfiniBand data path debugging"
+	depends on INFINIBAND_IPOIB_DEBUG
+	---help---
+	  This option compiles debugging code into the the data path
+	  of the IPoIB driver.  The output can be turned on via the
+	  data_debug_level module parameter; however, even with output
+	  turned off, this debugging code will have some performance
+	  impact.
diff -Nru a/drivers/infiniband/ulp/ipoib/Makefile b/drivers/infiniband/ulp/ipoib/Makefile
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/infiniband/ulp/ipoib/Makefile	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,11 @@
+EXTRA_CFLAGS += -Idrivers/infiniband/include
+
+obj-$(CONFIG_INFINIBAND_IPOIB)			+= ib_ipoib.o
+
+ib_ipoib-y					:= ipoib_main.o \
+						   ipoib_ib.o \
+						   ipoib_multicast.o \
+						   ipoib_verbs.o \
+						   ipoib_vlan.o
+ib_ipoib-$(CONFIG_INFINIBAND_IPOIB_DEBUG)	+= ipoib_fs.o
+
diff -Nru a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/infiniband/ulp/ipoib/ipoib.h	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,353 @@
+/*
+ * Copyright (c) 2004, 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: ipoib.h 1358 2004-12-17 22:00:11Z roland $
+ */
+
+#ifndef _IPOIB_H
+#define _IPOIB_H
+
+#include <linux/list.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/workqueue.h>
+#include <linux/pci.h>
+#include <linux/config.h>
+#include <linux/kref.h>
+#include <linux/if_infiniband.h>
+
+#include <net/neighbour.h>
+
+#include <asm/atomic.h>
+#include <asm/semaphore.h>
+
+#include <ib_verbs.h>
+#include <ib_pack.h>
+#include <ib_sa.h>
+
+/* constants */
+
+enum {
+	IPOIB_PACKET_SIZE         = 2048,
+	IPOIB_BUF_SIZE 		  = IPOIB_PACKET_SIZE + IB_GRH_BYTES,
+
+	IPOIB_ENCAP_LEN 	  = 4,
+
+	IPOIB_RX_RING_SIZE 	  = 128,
+	IPOIB_TX_RING_SIZE 	  = 64,
+
+	IPOIB_NUM_WC 		  = 4,
+
+	IPOIB_MAX_PATH_REC_QUEUE  = 3,
+	IPOIB_MAX_MCAST_QUEUE     = 3,
+
+	IPOIB_FLAG_OPER_UP 	  = 0,
+	IPOIB_FLAG_ADMIN_UP 	  = 1,
+	IPOIB_PKEY_ASSIGNED 	  = 2,
+	IPOIB_PKEY_STOP 	  = 3,
+	IPOIB_FLAG_SUBINTERFACE   = 4,
+	IPOIB_MCAST_RUN 	  = 5,
+	IPOIB_STOP_REAPER         = 6,
+
+	IPOIB_MAX_BACKOFF_SECONDS = 16,
+
+	IPOIB_MCAST_FLAG_FOUND 	  = 0,	/* used in set_multicast_list */
+	IPOIB_MCAST_FLAG_SENDONLY = 1,
+	IPOIB_MCAST_FLAG_BUSY 	  = 2,	/* joining or already joined */
+	IPOIB_MCAST_FLAG_ATTACHED = 3,
+};
+
+/* structs */
+
+struct ipoib_header {
+	u16 proto;
+	u16 reserved;
+};
+
+struct ipoib_pseudoheader {
+	u8  hwaddr[INFINIBAND_ALEN];
+};
+
+struct ipoib_mcast;
+
+struct ipoib_buf {
+	struct sk_buff *skb;
+	DECLARE_PCI_UNMAP_ADDR(mapping)
+};
+
+/*
+ * Device private locking: tx_lock protects members used in TX fast
+ * path (and we use LLTX so upper layers don't do extra locking).
+ * lock protects everything else.  lock nests inside of tx_lock (ie
+ * tx_lock must be acquired first if needed).
+ */
+struct ipoib_dev_priv {
+	spinlock_t lock;
+
+	struct net_device *dev;
+
+	unsigned long flags;
+
+	struct semaphore mcast_mutex;
+	struct semaphore vlan_mutex;
+
+	struct rb_root  path_tree;
+	struct list_head path_list;
+
+	struct ipoib_mcast *broadcast;
+	struct list_head multicast_list;
+	struct rb_root multicast_tree;
+
+	struct work_struct pkey_task;
+	struct work_struct mcast_task;
+	struct work_struct flush_task;
+	struct work_struct restart_task;
+	struct work_struct ah_reap_task;
+
+	struct ib_device *ca;
+	u8            	  port;
+	u16           	  pkey;
+	struct ib_pd  	 *pd;
+	struct ib_mr  	 *mr;
+	struct ib_cq  	 *cq;
+	struct ib_qp  	 *qp;
+	u32           	  qkey;
+
+	union ib_gid local_gid;
+	u16          local_lid;
+	u8           local_rate;
+
+	unsigned int admin_mtu;
+	unsigned int mcast_mtu;
+
+	struct ipoib_buf *rx_ring;
+
+	spinlock_t        tx_lock;
+	struct ipoib_buf *tx_ring;
+	unsigned          tx_head;
+	unsigned          tx_tail;
+	struct ib_sge     tx_sge;
+	struct ib_send_wr tx_wr;
+
+	struct ib_wc ibwc[IPOIB_NUM_WC];
+
+	struct list_head dead_ahs;
+
+	struct ib_event_handler event_handler;
+
+	struct net_device_stats stats;
+
+	struct net_device *parent;
+	struct list_head child_intfs;
+	struct list_head list;
+
+#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
+	struct list_head fs_list;
+	struct dentry *mcg_dentry;
+#endif
+};
+
+struct ipoib_ah {
+	struct net_device *dev;
+	struct ib_ah      *ah;
+	struct list_head   list;
+	struct kref        ref;
+	unsigned           last_send;
+};
+
+struct ipoib_path {
+	struct net_device    *dev;
+	struct ib_sa_path_rec pathrec;
+	struct ipoib_ah      *ah;
+	struct sk_buff_head   queue;
+
+	struct list_head      neigh_list;
+
+	int                   query_id;
+	struct ib_sa_query   *query;
+	struct completion     done;
+
+	struct rb_node        rb_node;
+	struct list_head      list;
+};
+
+struct ipoib_neigh {
+	struct ipoib_ah    *ah;
+	struct sk_buff_head queue;
+
+	struct neighbour   *neighbour;
+
+	struct list_head    list;
+};
+
+static inline struct ipoib_neigh **to_ipoib_neigh(struct neighbour *neigh)
+{
+	return (struct ipoib_neigh **) (neigh->ha + 24 -
+					(offsetof(struct neighbour, ha) & 4));
+}
+
+extern struct workqueue_struct *ipoib_workqueue;
+
+/* functions */
+
+void ipoib_ib_completion(struct ib_cq *cq, void *dev_ptr);
+
+struct ipoib_ah *ipoib_create_ah(struct net_device *dev,
+				 struct ib_pd *pd, struct ib_ah_attr *attr);
+void ipoib_free_ah(struct kref *kref);
+static inline void ipoib_put_ah(struct ipoib_ah *ah)
+{
+	kref_put(&ah->ref, ipoib_free_ah);
+}
+
+int ipoib_add_pkey_attr(struct net_device *dev);
+
+void ipoib_send(struct net_device *dev, struct sk_buff *skb,
+		struct ipoib_ah *address, u32 qpn);
+void ipoib_reap_ah(void *dev_ptr);
+
+void ipoib_flush_paths(struct net_device *dev);
+struct ipoib_dev_priv *ipoib_intf_alloc(const char *format);
+
+int ipoib_ib_dev_init(struct net_device *dev, struct ib_device *ca, int port);
+void ipoib_ib_dev_flush(void *dev);
+void ipoib_ib_dev_cleanup(struct net_device *dev);
+
+int ipoib_ib_dev_open(struct net_device *dev);
+int ipoib_ib_dev_up(struct net_device *dev);
+int ipoib_ib_dev_down(struct net_device *dev);
+int ipoib_ib_dev_stop(struct net_device *dev);
+
+int ipoib_dev_init(struct net_device *dev, struct ib_device *ca, int port);
+void ipoib_dev_cleanup(struct net_device *dev);
+
+void ipoib_mcast_join_task(void *dev_ptr);
+void ipoib_mcast_send(struct net_device *dev, union ib_gid *mgid,
+		      struct sk_buff *skb);
+
+void ipoib_mcast_restart_task(void *dev_ptr);
+int ipoib_mcast_start_thread(struct net_device *dev);
+int ipoib_mcast_stop_thread(struct net_device *dev);
+
+void ipoib_mcast_dev_down(struct net_device *dev);
+void ipoib_mcast_dev_flush(struct net_device *dev);
+
+struct ipoib_mcast_iter *ipoib_mcast_iter_init(struct net_device *dev);
+void ipoib_mcast_iter_free(struct ipoib_mcast_iter *iter);
+int ipoib_mcast_iter_next(struct ipoib_mcast_iter *iter);
+void ipoib_mcast_iter_read(struct ipoib_mcast_iter *iter,
+				  union ib_gid *gid,
+				  unsigned long *created,
+				  unsigned int *queuelen,
+				  unsigned int *complete,
+				  unsigned int *send_only);
+
+int ipoib_mcast_attach(struct net_device *dev, u16 mlid,
+		       union ib_gid *mgid);
+int ipoib_mcast_detach(struct net_device *dev, u16 mlid,
+		       union ib_gid *mgid);
+
+int ipoib_qp_create(struct net_device *dev);
+int ipoib_transport_dev_init(struct net_device *dev, struct ib_device *ca);
+void ipoib_transport_dev_cleanup(struct net_device *dev);
+
+void ipoib_event(struct ib_event_handler *handler,
+		 struct ib_event *record);
+
+int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey);
+int ipoib_vlan_delete(struct net_device *pdev, unsigned short pkey);
+
+void ipoib_pkey_poll(void *dev);
+int ipoib_pkey_dev_delay_open(struct net_device *dev);
+
+#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
+int ipoib_create_debug_file(struct net_device *dev);
+void ipoib_delete_debug_file(struct net_device *dev);
+int ipoib_register_debugfs(void);
+void ipoib_unregister_debugfs(void);
+#else
+static inline int ipoib_create_debug_file(struct net_device *dev) { return 0; }
+static inline void ipoib_delete_debug_file(struct net_device *dev) { }
+static inline int ipoib_register_debugfs(void) { return 0; }
+static inline void ipoib_unregister_debugfs(void) { }
+#endif
+
+
+#define ipoib_printk(level, priv, format, arg...)	\
+	printk(level "%s: " format, ((struct ipoib_dev_priv *) priv)->dev->name , ## arg)
+#define ipoib_warn(priv, format, arg...)		\
+	ipoib_printk(KERN_WARNING, priv, format , ## arg)
+
+
+#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
+extern int debug_level;
+
+#define ipoib_dbg(priv, format, arg...)			\
+	do {					        \
+		if (debug_level > 0)			\
+			ipoib_printk(KERN_DEBUG, priv, format , ## arg); \
+	} while (0)
+#define ipoib_dbg_mcast(priv, format, arg...)		\
+	do {					        \
+		if (mcast_debug_level > 0)		\
+			ipoib_printk(KERN_DEBUG, priv, format , ## arg); \
+	} while (0)
+#else /* CONFIG_INFINIBAND_IPOIB_DEBUG */
+#define ipoib_dbg(priv, format, arg...)			\
+	do { (void) (priv); } while (0)
+#define ipoib_dbg_mcast(priv, format, arg...)		\
+	do { (void) (priv); } while (0)
+#endif /* CONFIG_INFINIBAND_IPOIB_DEBUG */
+
+#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG_DATA
+#define ipoib_dbg_data(priv, format, arg...)		\
+	do {					        \
+		if (data_debug_level > 0)		\
+			ipoib_printk(KERN_DEBUG, priv, format , ## arg); \
+	} while (0)
+#else /* CONFIG_INFINIBAND_IPOIB_DEBUG_DATA */
+#define ipoib_dbg_data(priv, format, arg...)		\
+	do { (void) (priv); } while (0)
+#endif /* CONFIG_INFINIBAND_IPOIB_DEBUG_DATA */
+
+
+#define IPOIB_GID_FMT		"%x:%x:%x:%x:%x:%x:%x:%x"
+
+#define IPOIB_GID_ARG(gid)	be16_to_cpup((__be16 *) ((gid).raw +  0)), \
+				be16_to_cpup((__be16 *) ((gid).raw +  2)), \
+				be16_to_cpup((__be16 *) ((gid).raw +  4)), \
+				be16_to_cpup((__be16 *) ((gid).raw +  6)), \
+				be16_to_cpup((__be16 *) ((gid).raw +  8)), \
+				be16_to_cpup((__be16 *) ((gid).raw + 10)), \
+				be16_to_cpup((__be16 *) ((gid).raw + 12)), \
+				be16_to_cpup((__be16 *) ((gid).raw + 14))
+
+#endif /* _IPOIB_H */
diff -Nru a/drivers/infiniband/ulp/ipoib/ipoib_fs.c b/drivers/infiniband/ulp/ipoib/ipoib_fs.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/infiniband/ulp/ipoib/ipoib_fs.c	2005-03-01 23:39:26 -08:00
@@ -0,0 +1,287 @@
+/*
+ * Copyright (c) 2004 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: ipoib_fs.c 1389 2004-12-27 22:56:47Z roland $
+ */
+
+#include <linux/pagemap.h>
+#include <linux/seq_file.h>
+
+#include "ipoib.h"
+
+enum {
+	IPOIB_MAGIC = 0x49504942 /* "IPIB" */
+};
+
+static DECLARE_MUTEX(ipoib_fs_mutex);
+static struct dentry *ipoib_root;
+static struct super_block *ipoib_sb;
+static LIST_HEAD(ipoib_device_list);
+
+static void *ipoib_mcg_seq_start(struct seq_file *file, loff_t *pos)
+{
+	struct ipoib_mcast_iter *iter;
+	loff_t n = *pos;
+
+	iter = ipoib_mcast_iter_init(file->private);
+	if (!iter)
+		return NULL;
+
+	while (n--) {
+		if (ipoib_mcast_iter_next(iter)) {
+			ipoib_mcast_iter_free(iter);
+			return NULL;
+		}
+	}
+
+	return iter;
+}
+
+static void *ipoib_mcg_seq_next(struct seq_file *file, void *iter_ptr,
+				   loff_t *pos)
+{
+	struct ipoib_mcast_iter *iter = iter_ptr;
+
+	(*pos)++;
+
+	if (ipoib_mcast_iter_next(iter)) {
+		ipoib_mcast_iter_free(iter);
+		return NULL;
+	}
+
+	return iter;
+}
+
+static void ipoib_mcg_seq_stop(struct seq_file *file, void *iter_ptr)
+{
+	/* nothing for now */
+}
+
+static int ipoib_mcg_seq_show(struct seq_file *file, void *iter_ptr)
+{
+	struct ipoib_mcast_iter *iter = iter_ptr;
+	char gid_buf[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"];
+	union ib_gid mgid;
+	int i, n;
+	unsigned long created;
+	unsigned int queuelen, complete, send_only;
+
+	if (iter) {
+		ipoib_mcast_iter_read(iter, &mgid, &created, &queuelen,
+				      &complete, &send_only);
+
+		for (n = 0, i = 0; i < sizeof mgid / 2; ++i) {
+			n += sprintf(gid_buf + n, "%x",
+				     be16_to_cpu(((u16 *)mgid.raw)[i]));
+			if (i < sizeof mgid / 2 - 1)
+				gid_buf[n++] = ':';
+		}
+	}
+
+	seq_printf(file, "GID: %*s", -(1 + (int) sizeof gid_buf), gid_buf);
+
+	seq_printf(file,
+		   " created: %10ld queuelen: %4d complete: %d send_only: %d\n",
+		   created, queuelen, complete, send_only);
+
+	return 0;
+}
+
+static struct seq_operations ipoib_seq_ops = {
+	.start = ipoib_mcg_seq_start,
+	.next  = ipoib_mcg_seq_next,
+	.stop  = ipoib_mcg_seq_stop,
+	.show  = ipoib_mcg_seq_show,
+};
+
+static int ipoib_mcg_open(struct inode *inode, struct file *file)
+{
+	struct seq_file *seq;
+	int ret;
+
+	ret = seq_open(file, &ipoib_seq_ops);
+	if (ret)
+		return ret;
+
+	seq = file->private_data;
+	seq->private = inode->u.generic_ip;
+
+	return 0;
+}
+
+static struct file_operations ipoib_fops = {
+	.owner   = THIS_MODULE,
+	.open    = ipoib_mcg_open,
+	.read    = seq_read,
+	.llseek  = seq_lseek,
+	.release = seq_release
+};
+
+static struct inode *ipoib_get_inode(void)
+{
+	struct inode *inode = new_inode(ipoib_sb);
+
+	if (inode) {
+		inode->i_mode 	 = S_IFREG | S_IRUGO;
+		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_fop     = &ipoib_fops;
+	}
+
+	return inode;
+}
+
+static int __ipoib_create_debug_file(struct net_device *dev)
+{
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+	struct dentry *dentry;
+	struct inode *inode;
+	char name[IFNAMSIZ + sizeof "_mcg"];
+
+	snprintf(name, sizeof name, "%s_mcg", dev->name);
+
+	dentry = d_alloc_name(ipoib_root, name);
+	if (!dentry)
+		return -ENOMEM;
+
+	inode = ipoib_get_inode();
+	if (!inode) {
+		dput(dentry);
+		return -ENOMEM;
+	}
+
+	inode->u.generic_ip = dev;
+	priv->mcg_dentry = dentry;
+
+	d_add(dentry, inode);
+
+	return 0;
+}
+
+int ipoib_create_debug_file(struct net_device *dev)
+{
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+
+	down(&ipoib_fs_mutex);
+
+	list_add_tail(&priv->fs_list, &ipoib_device_list);
+
+	if (!ipoib_sb) {
+		up(&ipoib_fs_mutex);
+		return 0;
+	}
+
+	up(&ipoib_fs_mutex);
+
+	return __ipoib_create_debug_file(dev);
+}
+
+void ipoib_delete_debug_file(struct net_device *dev)
+{
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+
+	down(&ipoib_fs_mutex);
+	list_del(&priv->fs_list);
+	if (!ipoib_sb) {
+		up(&ipoib_fs_mutex);
+		return;
+	}
+	up(&ipoib_fs_mutex);
+
+	if (priv->mcg_dentry) {
+		d_drop(priv->mcg_dentry);
+		simple_unlink(ipoib_root->d_inode, priv->mcg_dentry);
+	}
+}
+
+static int ipoib_fill_super(struct super_block *sb, void *data, int silent)
+{
+	static struct tree_descr ipoib_files[] = {
+		{ "" }
+	};
+	struct ipoib_dev_priv *priv;
+	int ret;
+
+	ret = simple_fill_super(sb, IPOIB_MAGIC, ipoib_files);
+	if (ret)
+		return ret;
+
+	ipoib_root = sb->s_root;
+
+	down(&ipoib_fs_mutex);
+
+	ipoib_sb = sb;
+
+	list_for_each_entry(priv, &ipoib_device_list, fs_list) {
+		ret = __ipoib_create_debug_file(priv->dev);
+		if (ret)
+			break;
+	}
+
+	up(&ipoib_fs_mutex);
+
+	return ret;
+}
+
+static struct super_block *ipoib_get_sb(struct file_system_type *fs_type,
+	int flags, const char *dev_name, void *data)
+{
+	return get_sb_single(fs_type, flags, data, ipoib_fill_super);
+}
+
+static void ipoib_kill_sb(struct super_block *sb)
+{
+	down(&ipoib_fs_mutex);
+	ipoib_sb = NULL;
+	up(&ipoib_fs_mutex);
+
+	kill_litter_super(sb);
+}
+
+static struct file_system_type ipoib_fs_type = {
+	.owner		= THIS_MODULE,
+	.name		= "ipoib_debugfs",
+	.get_sb		= ipoib_get_sb,
+	.kill_sb	= ipoib_kill_sb,
+};
+
+int ipoib_register_debugfs(void)
+{
+	return register_filesystem(&ipoib_fs_type);
+}
+
+void ipoib_unregister_debugfs(void)
+{
+	unregister_filesystem(&ipoib_fs_type);
+}
diff -Nru a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,666 @@
+/*
+ * Copyright (c) 2004, 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: ipoib_ib.c 1386 2004-12-27 16:23:17Z roland $
+ */
+
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+
+#include <ib_cache.h>
+
+#include "ipoib.h"
+
+#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG_DATA
+int data_debug_level;
+
+module_param(data_debug_level, int, 0644);
+MODULE_PARM_DESC(data_debug_level,
+		 "Enable data path debug tracing if > 0");
+#endif
+
+#define	IPOIB_OP_RECV	(1ul << 31)
+
+static DECLARE_MUTEX(pkey_sem);
+
+struct ipoib_ah *ipoib_create_ah(struct net_device *dev,
+				 struct ib_pd *pd, struct ib_ah_attr *attr)
+{
+	struct ipoib_ah *ah;
+
+	ah = kmalloc(sizeof *ah, GFP_KERNEL);
+	if (!ah)
+		return NULL;
+
+	ah->dev       = dev;
+	ah->last_send = 0;
+	kref_init(&ah->ref);
+
+	ah->ah = ib_create_ah(pd, attr);
+	if (IS_ERR(ah->ah)) {
+		kfree(ah);
+		ah = NULL;
+	} else
+		ipoib_dbg(netdev_priv(dev), "Created ah %p\n", ah->ah);
+
+	return ah;
+}
+
+void ipoib_free_ah(struct kref *kref)
+{
+	struct ipoib_ah *ah = container_of(kref, struct ipoib_ah, ref);
+	struct ipoib_dev_priv *priv = netdev_priv(ah->dev);
+
+	unsigned long flags;
+
+	if (ah->last_send <= priv->tx_tail) {
+		ipoib_dbg(priv, "Freeing ah %p\n", ah->ah);
+		ib_destroy_ah(ah->ah);
+		kfree(ah);
+	} else {
+		spin_lock_irqsave(&priv->lock, flags);
+		list_add_tail(&ah->list, &priv->dead_ahs);
+		spin_unlock_irqrestore(&priv->lock, flags);
+	}
+}
+
+static inline int ipoib_ib_receive(struct ipoib_dev_priv *priv,
+				   unsigned int wr_id,
+				   dma_addr_t addr)
+{
+	struct ib_sge list = {
+		.addr    = addr,
+		.length  = IPOIB_BUF_SIZE,
+		.lkey    = priv->mr->lkey,
+	};
+	struct ib_recv_wr param = {
+		.wr_id 	    = wr_id | IPOIB_OP_RECV,
+		.sg_list    = &list,
+		.num_sge    = 1,
+		.recv_flags = IB_RECV_SIGNALED
+	};
+	struct ib_recv_wr *bad_wr;
+
+	return ib_post_recv(priv->qp, &param, &bad_wr);
+}
+
+static int ipoib_ib_post_receive(struct net_device *dev, int id)
+{
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+	struct sk_buff *skb;
+	dma_addr_t addr;
+	int ret;
+
+	skb = dev_alloc_skb(IPOIB_BUF_SIZE + 4);
+	if (!skb) {
+		ipoib_warn(priv, "failed to allocate receive buffer\n");
+
+		priv->rx_ring[id].skb = NULL;
+		return -ENOMEM;
+	}
+	skb_reserve(skb, 4);	/* 16 byte align IP header */
+	priv->rx_ring[id].skb = skb;
+	addr = dma_map_single(priv->ca->dma_device,
+			      skb->data, IPOIB_BUF_SIZE,
+			      DMA_FROM_DEVICE);
+	pci_unmap_addr_set(&priv->rx_ring[id], mapping, addr);
+
+	ret = ipoib_ib_receive(priv, id, addr);
+	if (ret) {
+		ipoib_warn(priv, "ipoib_ib_receive failed for buf %d (%d)\n",
+			   id, ret);
+		priv->rx_ring[id].skb = NULL;
+	}
+
+	return ret;
+}
+
+static int ipoib_ib_post_receives(struct net_device *dev)
+{
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+	int i;
+
+	for (i = 0; i < IPOIB_RX_RING_SIZE; ++i) {
+		if (ipoib_ib_post_receive(dev, i)) {
+			ipoib_warn(priv, "ipoib_ib_post_receive failed for buf %d\n", i);
+			return -EIO;
+		}
+	}
+
+	return 0;
+}
+
+static void ipoib_ib_handle_wc(struct net_device *dev,
+			       struct ib_wc *wc)
+{
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+	unsigned int wr_id = wc->wr_id;
+
+	ipoib_dbg_data(priv, "called: id %d, op %d, status: %d\n",
+		       wr_id, wc->opcode, wc->status);
+
+	if (wr_id & IPOIB_OP_RECV) {
+		wr_id &= ~IPOIB_OP_RECV;
+
+		if (wr_id < IPOIB_RX_RING_SIZE) {
+			struct sk_buff *skb = priv->rx_ring[wr_id].skb;
+
+			priv->rx_ring[wr_id].skb = NULL;
+
+			dma_unmap_single(priv->ca->dma_device,
+					 pci_unmap_addr(&priv->rx_ring[wr_id],
+							mapping),
+					 IPOIB_BUF_SIZE,
+					 DMA_FROM_DEVICE);
+
+			if (wc->status != IB_WC_SUCCESS) {
+				if (wc->status != IB_WC_WR_FLUSH_ERR)
+					ipoib_warn(priv, "failed recv event "
+						   "(status=%d, wrid=%d vend_err %x)\n",
+						   wc->status, wr_id, wc->vendor_err);
+				dev_kfree_skb_any(skb);
+				return;
+			}
+
+			ipoib_dbg_data(priv, "received %d bytes, SLID 0x%04x\n",
+				       wc->byte_len, wc->slid);
+
+			skb_put(skb, wc->byte_len);
+			skb_pull(skb, IB_GRH_BYTES);
+
+			if (wc->slid != priv->local_lid ||
+			    wc->src_qp != priv->qp->qp_num) {
+				skb->protocol = ((struct ipoib_header *) skb->data)->proto;
+
+				skb_pull(skb, IPOIB_ENCAP_LEN);
+
+				dev->last_rx = jiffies;
+				++priv->stats.rx_packets;
+				priv->stats.rx_bytes += skb->len;
+
+				skb->dev = dev;
+				/* XXX get correct PACKET_ type here */
+				skb->pkt_type = PACKET_HOST;
+				netif_rx_ni(skb);
+			} else {
+				ipoib_dbg_data(priv, "dropping loopback packet\n");
+				dev_kfree_skb_any(skb);
+			}
+
+			/* repost receive */
+			if (ipoib_ib_post_receive(dev, wr_id))
+				ipoib_warn(priv, "ipoib_ib_post_receive failed "
+					   "for buf %d\n", wr_id);
+		} else
+			ipoib_warn(priv, "completion event with wrid %d\n",
+				   wr_id);
+
+	} else {
+		struct ipoib_buf *tx_req;
+		unsigned long flags;
+
+		if (wr_id >= IPOIB_TX_RING_SIZE) {
+			ipoib_warn(priv, "completion event with wrid %d (> %d)\n",
+				   wr_id, IPOIB_TX_RING_SIZE);
+			return;
+		}
+
+		ipoib_dbg_data(priv, "send complete, wrid %d\n", wr_id);
+
+		tx_req = &priv->tx_ring[wr_id];
+
+		dma_unmap_single(priv->ca->dma_device,
+				 pci_unmap_addr(tx_req, mapping),
+				 tx_req->skb->len,
+				 DMA_TO_DEVICE);
+
+		++priv->stats.tx_packets;
+		priv->stats.tx_bytes += tx_req->skb->len;
+
+		dev_kfree_skb_any(tx_req->skb);
+
+		spin_lock_irqsave(&priv->tx_lock, flags);
+		++priv->tx_tail;
+		if (netif_queue_stopped(dev) &&
+		    priv->tx_head - priv->tx_tail <= IPOIB_TX_RING_SIZE / 2)
+			netif_wake_queue(dev);
+		spin_unlock_irqrestore(&priv->tx_lock, flags);
+
+		if (wc->status != IB_WC_SUCCESS &&
+		    wc->status != IB_WC_WR_FLUSH_ERR)
+			ipoib_warn(priv, "failed send event "
+				   "(status=%d, wrid=%d vend_err %x)\n",
+				   wc->status, wr_id, wc->vendor_err);
+	}
+}
+
+void ipoib_ib_completion(struct ib_cq *cq, void *dev_ptr)
+{
+	struct net_device *dev = (struct net_device *) dev_ptr;
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+	int n, i;
+
+	ib_req_notify_cq(cq, IB_CQ_NEXT_COMP);
+	do {
+		n = ib_poll_cq(cq, IPOIB_NUM_WC, priv->ibwc);
+		for (i = 0; i < n; ++i)
+			ipoib_ib_handle_wc(dev, priv->ibwc + i);
+	} while (n == IPOIB_NUM_WC);
+}
+
+static inline int post_send(struct ipoib_dev_priv *priv,
+			    unsigned int wr_id,
+			    struct ib_ah *address, u32 qpn,
+			    dma_addr_t addr, int len)
+{
+	struct ib_send_wr *bad_wr;
+
+	priv->tx_sge.addr             = addr;
+	priv->tx_sge.length           = len;
+
+	priv->tx_wr.wr_id 	      = wr_id;
+	priv->tx_wr.wr.ud.remote_qpn  = qpn;
+	priv->tx_wr.wr.ud.ah 	      = address;
+
+	return ib_post_send(priv->qp, &priv->tx_wr, &bad_wr);
+}
+
+void ipoib_send(struct net_device *dev, struct sk_buff *skb,
+		struct ipoib_ah *address, u32 qpn)
+{
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+	struct ipoib_buf *tx_req;
+	dma_addr_t addr;
+
+	if (skb->len > dev->mtu + INFINIBAND_ALEN) {
+		ipoib_warn(priv, "packet len %d (> %d) too long to send, dropping\n",
+			   skb->len, dev->mtu + INFINIBAND_ALEN);
+		++priv->stats.tx_dropped;
+		++priv->stats.tx_errors;
+		dev_kfree_skb_any(skb);
+		return;
+	}
+
+	ipoib_dbg_data(priv, "sending packet, length=%d address=%p qpn=0x%06x\n",
+		       skb->len, address, qpn);
+
+	/*
+	 * We put the skb into the tx_ring _before_ we call post_send()
+	 * because it's entirely possible that the completion handler will
+	 * run before we execute anything after the post_send().  That
+	 * means we have to make sure everything is properly recorded and
+	 * our state is consistent before we call post_send().
+	 */
+	tx_req = &priv->tx_ring[priv->tx_head & (IPOIB_TX_RING_SIZE - 1)];
+	tx_req->skb = skb;
+	addr = dma_map_single(priv->ca->dma_device, skb->data, skb->len,
+			      DMA_TO_DEVICE);
+	pci_unmap_addr_set(tx_req, mapping, addr);
+
+	if (unlikely(post_send(priv, priv->tx_head & (IPOIB_TX_RING_SIZE - 1),
+			       address->ah, qpn, addr, skb->len))) {
+		ipoib_warn(priv, "post_send failed\n");
+		++priv->stats.tx_errors;
+		dma_unmap_single(priv->ca->dma_device, addr, skb->len,
+				 DMA_TO_DEVICE);
+		dev_kfree_skb_any(skb);
+	} else {
+		dev->trans_start = jiffies;
+
+		address->last_send = priv->tx_head;
+		++priv->tx_head;
+
+		if (priv->tx_head - priv->tx_tail == IPOIB_TX_RING_SIZE) {
+			ipoib_dbg(priv, "TX ring full, stopping kernel net queue\n");
+			netif_stop_queue(dev);
+		}
+	}
+}
+
+static void __ipoib_reap_ah(struct net_device *dev)
+{
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+	struct ipoib_ah *ah, *tah;
+	LIST_HEAD(remove_list);
+
+	spin_lock_irq(&priv->lock);
+	list_for_each_entry_safe(ah, tah, &priv->dead_ahs, list)
+		if (ah->last_send <= priv->tx_tail) {
+			list_del(&ah->list);
+			list_add_tail(&ah->list, &remove_list);
+		}
+	spin_unlock_irq(&priv->lock);
+
+	list_for_each_entry_safe(ah, tah, &remove_list, list) {
+		ipoib_dbg(priv, "Reaping ah %p\n", ah->ah);
+		ib_destroy_ah(ah->ah);
+		kfree(ah);
+	}
+}
+
+void ipoib_reap_ah(void *dev_ptr)
+{
+	struct net_device *dev = dev_ptr;
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+
+	__ipoib_reap_ah(dev);
+
+	if (!test_bit(IPOIB_STOP_REAPER, &priv->flags))
+		queue_delayed_work(ipoib_workqueue, &priv->ah_reap_task, HZ);
+}
+
+int ipoib_ib_dev_open(struct net_device *dev)
+{
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+	int ret;
+
+	ret = ipoib_qp_create(dev);
+	if (ret) {
+		ipoib_warn(priv, "ipoib_qp_create returned %d\n", ret);
+		return -1;
+	}
+
+	ret = ipoib_ib_post_receives(dev);
+	if (ret) {
+		ipoib_warn(priv, "ipoib_ib_post_receives returned %d\n", ret);
+		return -1;
+	}
+
+	clear_bit(IPOIB_STOP_REAPER, &priv->flags);
+	queue_delayed_work(ipoib_workqueue, &priv->ah_reap_task, HZ);
+
+	return 0;
+}
+
+int ipoib_ib_dev_up(struct net_device *dev)
+{
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+
+	set_bit(IPOIB_FLAG_OPER_UP, &priv->flags);
+
+	return ipoib_mcast_start_thread(dev);
+}
+
+int ipoib_ib_dev_down(struct net_device *dev)
+{
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+
+	ipoib_dbg(priv, "downing ib_dev\n");
+
+	clear_bit(IPOIB_FLAG_OPER_UP, &priv->flags);
+	netif_carrier_off(dev);
+
+	/* Shutdown the P_Key thread if still active */
+	if (!test_bit(IPOIB_PKEY_ASSIGNED, &priv->flags)) {
+		down(&pkey_sem);
+		set_bit(IPOIB_PKEY_STOP, &priv->flags);
+		cancel_delayed_work(&priv->pkey_task);
+		up(&pkey_sem);
+		flush_workqueue(ipoib_workqueue);
+	}
+
+	ipoib_mcast_stop_thread(dev);
+
+	/*
+	 * Flush the multicast groups first so we stop any multicast joins. The
+	 * completion thread may have already died and we may deadlock waiting
+	 * for the completion thread to finish some multicast joins.
+	 */
+	ipoib_mcast_dev_flush(dev);
+
+	/* Delete broadcast and local addresses since they will be recreated */
+	ipoib_mcast_dev_down(dev);
+
+	ipoib_flush_paths(dev);
+
+	return 0;
+}
+
+static int recvs_pending(struct net_device *dev)
+{
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+	int pending = 0;
+	int i;
+
+	for (i = 0; i < IPOIB_RX_RING_SIZE; ++i)
+		if (priv->rx_ring[i].skb)
+			++pending;
+
+	return pending;
+}
+
+int ipoib_ib_dev_stop(struct net_device *dev)
+{
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+	struct ib_qp_attr qp_attr;
+	int attr_mask;
+	unsigned long begin;
+	struct ipoib_buf *tx_req;
+	int i;
+
+	/* Kill the existing QP and allocate a new one */
+	qp_attr.qp_state = IB_QPS_ERR;
+	attr_mask        = IB_QP_STATE;
+	if (ib_modify_qp(priv->qp, &qp_attr, attr_mask))
+		ipoib_warn(priv, "Failed to modify QP to ERROR state\n");
+
+	/* Wait for all sends and receives to complete */
+	begin = jiffies;
+
+	while (priv->tx_head != priv->tx_tail || recvs_pending(dev)) {
+		if (time_after(jiffies, begin + 5 * HZ)) {
+			ipoib_warn(priv, "timing out; %d sends %d receives not completed\n",
+				   priv->tx_head - priv->tx_tail, recvs_pending(dev));
+
+			/*
+			 * assume the HW is wedged and just free up
+			 * all our pending work requests.
+			 */
+			while (priv->tx_tail < priv->tx_head) {
+				tx_req = &priv->tx_ring[priv->tx_tail &
+							(IPOIB_TX_RING_SIZE - 1)];
+				dma_unmap_single(priv->ca->dma_device,
+						 pci_unmap_addr(tx_req, mapping),
+						 tx_req->skb->len,
+						 DMA_TO_DEVICE);
+				dev_kfree_skb_any(tx_req->skb);
+				++priv->tx_tail;
+			}
+
+			for (i = 0; i < IPOIB_RX_RING_SIZE; ++i)
+				if (priv->rx_ring[i].skb) {
+					dma_unmap_single(priv->ca->dma_device,
+							 pci_unmap_addr(&priv->rx_ring[i],
+									mapping),
+							 IPOIB_BUF_SIZE,
+							 DMA_FROM_DEVICE);
+					dev_kfree_skb_any(priv->rx_ring[i].skb);
+					priv->rx_ring[i].skb = NULL;
+				}
+
+			goto timeout;
+		}
+
+		msleep(1);
+	}
+
+	ipoib_dbg(priv, "All sends and receives done.\n");
+
+timeout:
+	qp_attr.qp_state = IB_QPS_RESET;
+	attr_mask        = IB_QP_STATE;
+	if (ib_modify_qp(priv->qp, &qp_attr, attr_mask))
+		ipoib_warn(priv, "Failed to modify QP to RESET state\n");
+
+	/* Wait for all AHs to be reaped */
+	set_bit(IPOIB_STOP_REAPER, &priv->flags);
+	cancel_delayed_work(&priv->ah_reap_task);
+	flush_workqueue(ipoib_workqueue);
+
+	begin = jiffies;
+
+	while (!list_empty(&priv->dead_ahs)) {
+		__ipoib_reap_ah(dev);
+
+		if (time_after(jiffies, begin + HZ)) {
+			ipoib_warn(priv, "timing out; will leak address handles\n");
+			break;
+		}
+
+		msleep(1);
+	}
+
+	return 0;
+}
+
+int ipoib_ib_dev_init(struct net_device *dev, struct ib_device *ca, int port)
+{
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+
+	priv->ca = ca;
+	priv->port = port;
+	priv->qp = NULL;
+
+	if (ipoib_transport_dev_init(dev, ca)) {
+		printk(KERN_WARNING "%s: ipoib_transport_dev_init failed\n", ca->name);
+		return -ENODEV;
+	}
+
+	if (dev->flags & IFF_UP) {
+		if (ipoib_ib_dev_open(dev)) {
+			ipoib_transport_dev_cleanup(dev);
+			return -ENODEV;
+		}
+	}
+
+	return 0;
+}
+
+void ipoib_ib_dev_flush(void *_dev)
+{
+	struct net_device *dev = (struct net_device *)_dev;
+	struct ipoib_dev_priv *priv = netdev_priv(dev), *cpriv;
+
+	if (!test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags))
+		return;
+
+	ipoib_dbg(priv, "flushing\n");
+
+	ipoib_ib_dev_down(dev);
+
+	/*
+	 * The device could have been brought down between the start and when
+	 * we get here, don't bring it back up if it's not configured up
+	 */
+	if (test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags))
+		ipoib_ib_dev_up(dev);
+
+	/* Flush any child interfaces too */
+	list_for_each_entry(cpriv, &priv->child_intfs, list)
+		ipoib_ib_dev_flush(&cpriv->dev);
+}
+
+void ipoib_ib_dev_cleanup(struct net_device *dev)
+{
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+
+	ipoib_dbg(priv, "cleaning up ib_dev\n");
+
+	ipoib_mcast_stop_thread(dev);
+
+	/* Delete the broadcast address and the local address */
+	ipoib_mcast_dev_down(dev);
+
+	ipoib_transport_dev_cleanup(dev);
+}
+
+/*
+ * Delayed P_Key Assigment Interim Support
+ *
+ * The following is initial implementation of delayed P_Key assigment
+ * mechanism. It is using the same approach implemented for the multicast
+ * group join. The single goal of this implementation is to quickly address
+ * Bug #2507. This implementation will probably be removed when the P_Key
+ * change async notification is available.
+ */
+int ipoib_open(struct net_device *dev);
+
+static void ipoib_pkey_dev_check_presence(struct net_device *dev)
+{
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+	u16 pkey_index = 0;
+
+	if (ib_find_cached_pkey(priv->ca, priv->port, priv->pkey, &pkey_index))
+		clear_bit(IPOIB_PKEY_ASSIGNED, &priv->flags);
+	else
+		set_bit(IPOIB_PKEY_ASSIGNED, &priv->flags);
+}
+
+void ipoib_pkey_poll(void *dev_ptr)
+{
+	struct net_device *dev = dev_ptr;
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+
+	ipoib_pkey_dev_check_presence(dev);
+
+	if (test_bit(IPOIB_PKEY_ASSIGNED, &priv->flags))
+		ipoib_open(dev);
+	else {
+		down(&pkey_sem);
+		if (!test_bit(IPOIB_PKEY_STOP, &priv->flags))
+			queue_delayed_work(ipoib_workqueue,
+					   &priv->pkey_task,
+					   HZ);
+		up(&pkey_sem);
+	}
+}
+
+int ipoib_pkey_dev_delay_open(struct net_device *dev)
+{
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+
+	/* Look for the interface pkey value in the IB Port P_Key table and */
+	/* set the interface pkey assigment flag                            */
+	ipoib_pkey_dev_check_presence(dev);
+
+	/* P_Key value not assigned yet - start polling */
+	if (!test_bit(IPOIB_PKEY_ASSIGNED, &priv->flags)) {
+		down(&pkey_sem);
+		clear_bit(IPOIB_PKEY_STOP, &priv->flags);
+		queue_delayed_work(ipoib_workqueue,
+				   &priv->pkey_task,
+				   HZ);
+		up(&pkey_sem);
+		return 1;
+	}
+
+	return 0;
+}
diff -Nru a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,1079 @@
+/*
+ * Copyright (c) 2004 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: ipoib_main.c 1377 2004-12-23 19:57:12Z roland $
+ */
+
+#include "ipoib.h"
+
+#include <linux/version.h>
+#include <linux/module.h>
+
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+
+#include <linux/if_arp.h>	/* For ARPHRD_xxx */
+
+#include <linux/ip.h>
+#include <linux/in.h>
+
+MODULE_AUTHOR("Roland Dreier");
+MODULE_DESCRIPTION("IP-over-InfiniBand net driver");
+MODULE_LICENSE("Dual BSD/GPL");
+
+#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
+int debug_level;
+
+module_param(debug_level, int, 0644);
+MODULE_PARM_DESC(debug_level, "Enable debug tracing if > 0");
+#endif
+
+static const u8 ipv4_bcast_addr[] = {
+	0x00, 0xff, 0xff, 0xff,
+	0xff, 0x12, 0x40, 0x1b,	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,	0xff, 0xff, 0xff, 0xff
+};
+
+struct workqueue_struct *ipoib_workqueue;
+
+static void ipoib_add_one(struct ib_device *device);
+static void ipoib_remove_one(struct ib_device *device);
+
+static struct ib_client ipoib_client = {
+	.name   = "ipoib",
+	.add    = ipoib_add_one,
+	.remove = ipoib_remove_one
+};
+
+int ipoib_open(struct net_device *dev)
+{
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+
+	ipoib_dbg(priv, "bringing up interface\n");
+
+	set_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags);
+
+	if (ipoib_pkey_dev_delay_open(dev))
+		return 0;
+
+	if (ipoib_ib_dev_open(dev))
+		return -EINVAL;
+
+	if (ipoib_ib_dev_up(dev))
+		return -EINVAL;
+
+	if (!test_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags)) {
+		struct ipoib_dev_priv *cpriv;
+
+		/* Bring up any child interfaces too */
+		down(&priv->vlan_mutex);
+		list_for_each_entry(cpriv, &priv->child_intfs, list) {
+			int flags;
+
+			flags = cpriv->dev->flags;
+			if (flags & IFF_UP)
+				continue;
+
+			dev_change_flags(cpriv->dev, flags | IFF_UP);
+		}
+		up(&priv->vlan_mutex);
+	}
+
+	netif_start_queue(dev);
+
+	return 0;
+}
+
+static int ipoib_stop(struct net_device *dev)
+{
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+
+	ipoib_dbg(priv, "stopping interface\n");
+
+	clear_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags);
+
+	netif_stop_queue(dev);
+
+	ipoib_ib_dev_down(dev);
+	ipoib_ib_dev_stop(dev);
+
+	if (!test_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags)) {
+		struct ipoib_dev_priv *cpriv;
+
+		/* Bring down any child interfaces too */
+		down(&priv->vlan_mutex);
+		list_for_each_entry(cpriv, &priv->child_intfs, list) {
+			int flags;
+
+			flags = cpriv->dev->flags;
+			if (!(flags & IFF_UP))
+				continue;
+
+			dev_change_flags(cpriv->dev, flags & ~IFF_UP);
+		}
+		up(&priv->vlan_mutex);
+	}
+
+	return 0;
+}
+
+static int ipoib_change_mtu(struct net_device *dev, int new_mtu)
+{
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+
+	if (new_mtu > IPOIB_PACKET_SIZE - IPOIB_ENCAP_LEN)
+		return -EINVAL;
+
+	priv->admin_mtu = new_mtu;
+
+	dev->mtu = min(priv->mcast_mtu, priv->admin_mtu);
+
+	return 0;
+}
+
+static struct ipoib_path *__path_find(struct net_device *dev,
+				      union ib_gid *gid)
+{
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+	struct rb_node *n = priv->path_tree.rb_node;
+	struct ipoib_path *path;
+	int ret;
+
+	while (n) {
+		path = rb_entry(n, struct ipoib_path, rb_node);
+
+		ret = memcmp(gid->raw, path->pathrec.dgid.raw,
+			     sizeof (union ib_gid));
+
+		if (ret < 0)
+			n = n->rb_left;
+		else if (ret > 0)
+			n = n->rb_right;
+		else
+			return path;
+	}
+
+	return NULL;
+}
+
+static int __path_add(struct net_device *dev, struct ipoib_path *path)
+{
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+	struct rb_node **n = &priv->path_tree.rb_node;
+	struct rb_node *pn = NULL;
+	struct ipoib_path *tpath;
+	int ret;
+
+	while (*n) {
+		pn = *n;
+		tpath = rb_entry(pn, struct ipoib_path, rb_node);
+
+		ret = memcmp(path->pathrec.dgid.raw, tpath->pathrec.dgid.raw,
+			     sizeof (union ib_gid));
+		if (ret < 0)
+			n = &pn->rb_left;
+		else if (ret > 0)
+			n = &pn->rb_right;
+		else
+			return -EEXIST;
+	}
+
+	rb_link_node(&path->rb_node, pn, n);
+	rb_insert_color(&path->rb_node, &priv->path_tree);
+
+	list_add_tail(&path->list, &priv->path_list);
+
+	return 0;
+}
+
+static void __path_free(struct net_device *dev, struct ipoib_path *path)
+{
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+	struct ipoib_neigh *neigh, *tn;
+	struct sk_buff *skb;
+
+	while ((skb = __skb_dequeue(&path->queue)))
+		dev_kfree_skb_irq(skb);
+
+	list_for_each_entry_safe(neigh, tn, &path->neigh_list, list) {
+		if (neigh->ah)
+			ipoib_put_ah(neigh->ah);
+		*to_ipoib_neigh(neigh->neighbour) = NULL;
+		neigh->neighbour->ops->destructor = NULL;
+		kfree(neigh);
+	}
+
+	if (path->ah)
+		ipoib_put_ah(path->ah);
+
+	rb_erase(&path->rb_node, &priv->path_tree);
+	list_del(&path->list);
+	kfree(path);
+}
+
+void ipoib_flush_paths(struct net_device *dev)
+{
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+	struct ipoib_path *path, *tp;
+	LIST_HEAD(remove_list);
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->lock, flags);
+	list_splice(&priv->path_list, &remove_list);
+	INIT_LIST_HEAD(&priv->path_list);
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	list_for_each_entry_safe(path, tp, &remove_list, list) {
+		if (path->query)
+			ib_sa_cancel_query(path->query_id, path->query);
+		wait_for_completion(&path->done);
+		__path_free(dev, path);
+	}
+}
+
+static void path_rec_completion(int status,
+				struct ib_sa_path_rec *pathrec,
+				void *path_ptr)
+{
+	struct ipoib_path *path = path_ptr;
+	struct net_device *dev = path->dev;
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+	struct ipoib_ah *ah = NULL;
+	struct ipoib_neigh *neigh;
+	struct sk_buff_head skqueue;
+	struct sk_buff *skb;
+	unsigned long flags;
+
+	if (pathrec)
+		ipoib_dbg(priv, "PathRec LID 0x%04x for GID " IPOIB_GID_FMT "\n",
+			  be16_to_cpu(pathrec->dlid), IPOIB_GID_ARG(pathrec->dgid));
+	else
+		ipoib_dbg(priv, "PathRec status %d for GID " IPOIB_GID_FMT "\n",
+			  status, IPOIB_GID_ARG(path->pathrec.dgid));
+
+	skb_queue_head_init(&skqueue);
+
+	if (!status) {
+		struct ib_ah_attr av = {
+			.dlid 	       = be16_to_cpu(pathrec->dlid),
+			.sl 	       = pathrec->sl,
+			.port_num      = priv->port
+		};
+
+		if (ib_sa_rate_enum_to_int(pathrec->rate) > 0)
+			av.static_rate = (2 * priv->local_rate -
+					  ib_sa_rate_enum_to_int(pathrec->rate) - 1) /
+				(priv->local_rate ? priv->local_rate : 1);
+
+		ipoib_dbg(priv, "static_rate %d for local port %dX, path %dX\n",
+			  av.static_rate, priv->local_rate,
+			  ib_sa_rate_enum_to_int(pathrec->rate));
+
+		ah = ipoib_create_ah(dev, priv->pd, &av);
+	}
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	path->ah = ah;
+
+	if (ah) {
+		path->pathrec = *pathrec;
+
+		ipoib_dbg(priv, "created address handle %p for LID 0x%04x, SL %d\n",
+			  ah, be16_to_cpu(pathrec->dlid), pathrec->sl);
+
+		while ((skb = __skb_dequeue(&path->queue)))
+			__skb_queue_tail(&skqueue, skb);
+
+		list_for_each_entry(neigh, &path->neigh_list, list) {
+			kref_get(&path->ah->ref);
+			neigh->ah = path->ah;
+
+			while ((skb = __skb_dequeue(&neigh->queue)))
+				__skb_queue_tail(&skqueue, skb);
+		}
+	} else
+		path->query = NULL;
+
+	complete(&path->done);
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	while ((skb = __skb_dequeue(&skqueue))) {
+		skb->dev = dev;
+		if (dev_queue_xmit(skb))
+			ipoib_warn(priv, "dev_queue_xmit failed "
+				   "to requeue packet\n");
+	}
+}
+
+static struct ipoib_path *path_rec_create(struct net_device *dev,
+					  union ib_gid *gid)
+{
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+	struct ipoib_path *path;
+
+	path = kmalloc(sizeof *path, GFP_ATOMIC);
+	if (!path)
+		return NULL;
+
+	path->dev = dev;
+	path->pathrec.dlid = 0;
+
+	skb_queue_head_init(&path->queue);
+
+	INIT_LIST_HEAD(&path->neigh_list);
+	path->query = NULL;
+	init_completion(&path->done);
+
+	memcpy(path->pathrec.dgid.raw, gid->raw, sizeof (union ib_gid));
+	path->pathrec.sgid      = priv->local_gid;
+	path->pathrec.pkey      = cpu_to_be16(priv->pkey);
+	path->pathrec.numb_path = 1;
+
+	__path_add(dev, path);
+
+	return path;
+}
+
+static int path_rec_start(struct net_device *dev,
+			  struct ipoib_path *path)
+{
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+
+	ipoib_dbg(priv, "Start path record lookup for " IPOIB_GID_FMT "\n",
+		  IPOIB_GID_ARG(path->pathrec.dgid));
+
+	path->query_id =
+		ib_sa_path_rec_get(priv->ca, priv->port,
+				   &path->pathrec,
+				   IB_SA_PATH_REC_DGID		|
+				   IB_SA_PATH_REC_SGID		|
+				   IB_SA_PATH_REC_NUMB_PATH	|
+				   IB_SA_PATH_REC_PKEY,
+				   1000, GFP_ATOMIC,
+				   path_rec_completion,
+				   path, &path->query);
+	if (path->query_id < 0) {
+		ipoib_warn(priv, "ib_sa_path_rec_get failed\n");
+		path->query = NULL;
+		return path->query_id;
+	}
+
+	return 0;
+}
+
+static void neigh_add_path(struct sk_buff *skb, struct net_device *dev)
+{
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+	struct ipoib_path *path;
+	struct ipoib_neigh *neigh;
+
+	neigh = kmalloc(sizeof *neigh, GFP_ATOMIC);
+	if (!neigh) {
+		++priv->stats.tx_dropped;
+		dev_kfree_skb_any(skb);
+		return;
+	}
+
+	skb_queue_head_init(&neigh->queue);
+	neigh->neighbour = skb->dst->neighbour;
+	*to_ipoib_neigh(skb->dst->neighbour) = neigh;
+
+	/*
+	 * We can only be called from ipoib_start_xmit, so we're
+	 * inside tx_lock -- no need to save/restore flags.
+	 */
+	spin_lock(&priv->lock);
+
+	path = __path_find(dev, (union ib_gid *) (skb->dst->neighbour->ha + 4));
+	if (!path) {
+		path = path_rec_create(dev,
+				       (union ib_gid *) (skb->dst->neighbour->ha + 4));
+		if (!path)
+			goto err;
+	}
+
+	list_add_tail(&neigh->list, &path->neigh_list);
+
+	if (path->pathrec.dlid) {
+		kref_get(&path->ah->ref);
+		neigh->ah = path->ah;
+
+		ipoib_send(dev, skb, path->ah,
+			   be32_to_cpup((__be32 *) skb->dst->neighbour->ha));
+	} else {
+		neigh->ah  = NULL;
+		if (skb_queue_len(&neigh->queue) < IPOIB_MAX_PATH_REC_QUEUE) {
+			__skb_queue_tail(&neigh->queue, skb);
+		} else {
+			++priv->stats.tx_dropped;
+			dev_kfree_skb_any(skb);
+		}
+
+		if (!path->query && path_rec_start(dev, path))
+			goto err;
+	}
+
+	spin_unlock(&priv->lock);
+	return;
+
+err:
+	*to_ipoib_neigh(skb->dst->neighbour) = NULL;
+	list_del(&neigh->list);
+	kfree(neigh);
+	neigh->neighbour->ops->destructor = NULL;
+
+	++priv->stats.tx_dropped;
+	dev_kfree_skb_any(skb);
+
+	spin_unlock(&priv->lock);
+}
+
+static void path_lookup(struct sk_buff *skb, struct net_device *dev)
+{
+	struct ipoib_dev_priv *priv = netdev_priv(skb->dev);
+
+	/* Look up path record for unicasts */
+	if (skb->dst->neighbour->ha[4] != 0xff) {
+		neigh_add_path(skb, dev);
+		return;
+	}
+
+	/* Add in the P_Key for multicasts */
+	skb->dst->neighbour->ha[8] = (priv->pkey >> 8) & 0xff;
+	skb->dst->neighbour->ha[9] = priv->pkey & 0xff;
+	ipoib_mcast_send(dev, (union ib_gid *) (skb->dst->neighbour->ha + 4), skb);
+}
+
+static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev,
+			     struct ipoib_pseudoheader *phdr)
+{
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+	struct ipoib_path *path;
+
+	/*
+	 * We can only be called from ipoib_start_xmit, so we're
+	 * inside tx_lock -- no need to save/restore flags.
+	 */
+	spin_lock(&priv->lock);
+
+	path = __path_find(dev, (union ib_gid *) (phdr->hwaddr + 4));
+	if (!path) {
+		path = path_rec_create(dev,
+				       (union ib_gid *) (phdr->hwaddr + 4));
+		if (path) {
+			/* put pseudoheader back on for next time */
+			skb_push(skb, sizeof *phdr);
+			__skb_queue_tail(&path->queue, skb);
+
+			if (path_rec_start(dev, path))
+				__path_free(dev, path);
+		} else {
+			++priv->stats.tx_dropped;
+			dev_kfree_skb_any(skb);
+		}
+
+		spin_unlock(&priv->lock);
+		return;
+	}
+
+	if (path->pathrec.dlid) {
+		ipoib_dbg(priv, "Send unicast ARP to %04x\n",
+			  be16_to_cpu(path->pathrec.dlid));
+
+		ipoib_send(dev, skb, path->ah,
+			   be32_to_cpup((__be32 *) phdr->hwaddr));
+	} else if ((path->query || !path_rec_start(dev, path)) &&
+		   skb_queue_len(&path->queue) < IPOIB_MAX_PATH_REC_QUEUE) {
+		/* put pseudoheader back on for next time */
+		skb_push(skb, sizeof *phdr);
+		__skb_queue_tail(&path->queue, skb);
+	} else {
+		++priv->stats.tx_dropped;
+		dev_kfree_skb_any(skb);
+	}
+
+	spin_unlock(&priv->lock);
+}
+
+static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+	struct ipoib_neigh *neigh;
+	unsigned long flags;
+
+	local_irq_save(flags);
+	if (!spin_trylock(&priv->tx_lock)) {
+		local_irq_restore(flags);
+		return NETDEV_TX_LOCKED;
+	}
+
+	/*
+	 * Check if our queue is stopped.  Since we have the LLTX bit
+	 * set, we can't rely on netif_stop_queue() preventing our
+	 * xmit function from being called with a full queue.
+	 */
+	if (unlikely(netif_queue_stopped(dev))) {
+		spin_unlock_irqrestore(&priv->tx_lock, flags);
+		return NETDEV_TX_BUSY;
+	}
+
+	if (skb->dst && skb->dst->neighbour) {
+		if (unlikely(!*to_ipoib_neigh(skb->dst->neighbour))) {
+			path_lookup(skb, dev);
+			goto out;
+		}
+
+		neigh = *to_ipoib_neigh(skb->dst->neighbour);
+
+		if (likely(neigh->ah)) {
+			ipoib_send(dev, skb, neigh->ah,
+				   be32_to_cpup((__be32 *) skb->dst->neighbour->ha));
+			goto out;
+		}
+
+		if (skb_queue_len(&neigh->queue) < IPOIB_MAX_PATH_REC_QUEUE) {
+			spin_lock(&priv->lock);
+			__skb_queue_tail(&neigh->queue, skb);
+			spin_unlock(&priv->lock);
+		} else {
+			++priv->stats.tx_dropped;
+			dev_kfree_skb_any(skb);
+		}
+	} else {
+		struct ipoib_pseudoheader *phdr =
+			(struct ipoib_pseudoheader *) skb->data;
+		skb_pull(skb, sizeof *phdr);
+
+		if (phdr->hwaddr[4] == 0xff) {
+			/* Add in the P_Key for multicast*/
+			phdr->hwaddr[8] = (priv->pkey >> 8) & 0xff;
+			phdr->hwaddr[9] = priv->pkey & 0xff;
+
+			ipoib_mcast_send(dev, (union ib_gid *) (phdr->hwaddr + 4), skb);
+		} else {
+			/* unicast GID -- should be ARP reply */
+
+			if (be16_to_cpup((u16 *) skb->data) != ETH_P_ARP) {
+				ipoib_warn(priv, "Unicast, no %s: type %04x, QPN %06x "
+					   IPOIB_GID_FMT "\n",
+					   skb->dst ? "neigh" : "dst",
+					   be16_to_cpup((u16 *) skb->data),
+					   be32_to_cpup((u32 *) phdr->hwaddr),
+					   IPOIB_GID_ARG(*(union ib_gid *) (phdr->hwaddr + 4)));
+				dev_kfree_skb_any(skb);
+				++priv->stats.tx_dropped;
+				goto out;
+			}
+
+			unicast_arp_send(skb, dev, phdr);
+		}
+	}
+
+out:
+	spin_unlock_irqrestore(&priv->tx_lock, flags);
+
+	return NETDEV_TX_OK;
+}
+
+static struct net_device_stats *ipoib_get_stats(struct net_device *dev)
+{
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+
+	return &priv->stats;
+}
+
+static void ipoib_timeout(struct net_device *dev)
+{
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+
+	ipoib_warn(priv, "transmit timeout: latency %ld\n",
+		   jiffies - dev->trans_start);
+	/* XXX reset QP, etc. */
+}
+
+static int ipoib_hard_header(struct sk_buff *skb,
+			     struct net_device *dev,
+			     unsigned short type,
+			     void *daddr, void *saddr, unsigned len)
+{
+	struct ipoib_header *header;
+
+	header = (struct ipoib_header *) skb_push(skb, sizeof *header);
+
+	header->proto = htons(type);
+	header->reserved = 0;
+
+	/*
+	 * If we don't have a neighbour structure, stuff the
+	 * destination address onto the front of the skb so we can
+	 * figure out where to send the packet later.
+	 */
+	if (!skb->dst || !skb->dst->neighbour) {
+		struct ipoib_pseudoheader *phdr =
+			(struct ipoib_pseudoheader *) skb_push(skb, sizeof *phdr);
+		memcpy(phdr->hwaddr, daddr, INFINIBAND_ALEN);
+	}
+
+	return 0;
+}
+
+static void ipoib_set_mcast_list(struct net_device *dev)
+{
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+
+	schedule_work(&priv->restart_task);
+}
+
+static void ipoib_neigh_destructor(struct neighbour *n)
+{
+	struct ipoib_neigh *neigh = *to_ipoib_neigh(n);
+	struct ipoib_dev_priv *priv = netdev_priv(n->dev);
+	unsigned long flags;
+
+	ipoib_dbg(priv,
+		  "neigh_destructor for %06x " IPOIB_GID_FMT "\n",
+		  be32_to_cpup((__be32 *) n->ha),
+		  IPOIB_GID_ARG(*((union ib_gid *) (n->ha + 4))));
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	if (neigh) {
+		if (neigh->ah)
+			ipoib_put_ah(neigh->ah);
+		list_del(&neigh->list);
+		*to_ipoib_neigh(n) = NULL;
+		kfree(neigh);
+	}
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+static int ipoib_neigh_setup(struct neighbour *neigh)
+{
+	/*
+	 * Is this kosher?  I can't find anybody in the kernel that
+	 * sets neigh->destructor, so we should be able to set it here
+	 * without trouble.
+	 */
+	neigh->ops->destructor = ipoib_neigh_destructor;
+
+	return 0;
+}
+
+static int ipoib_neigh_setup_dev(struct net_device *dev, struct neigh_parms *parms)
+{
+	parms->neigh_setup = ipoib_neigh_setup;
+
+	return 0;
+}
+
+int ipoib_dev_init(struct net_device *dev, struct ib_device *ca, int port)
+{
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+
+	/* Allocate RX/TX "rings" to hold queued skbs */
+
+	priv->rx_ring =	kmalloc(IPOIB_RX_RING_SIZE * sizeof (struct ipoib_buf),
+				GFP_KERNEL);
+	if (!priv->rx_ring) {
+		printk(KERN_WARNING "%s: failed to allocate RX ring (%d entries)\n",
+		       ca->name, IPOIB_RX_RING_SIZE);
+		goto out;
+	}
+	memset(priv->rx_ring, 0,
+	       IPOIB_RX_RING_SIZE * sizeof (struct ipoib_buf));
+
+	priv->tx_ring = kmalloc(IPOIB_TX_RING_SIZE * sizeof (struct ipoib_buf),
+				GFP_KERNEL);
+	if (!priv->tx_ring) {
+		printk(KERN_WARNING "%s: failed to allocate TX ring (%d entries)\n",
+		       ca->name, IPOIB_TX_RING_SIZE);
+		goto out_rx_ring_cleanup;
+	}
+	memset(priv->tx_ring, 0,
+	       IPOIB_TX_RING_SIZE * sizeof (struct ipoib_buf));
+
+	/* priv->tx_head & tx_tail are already 0 */
+
+	if (ipoib_ib_dev_init(dev, ca, port))
+		goto out_tx_ring_cleanup;
+
+	return 0;
+
+out_tx_ring_cleanup:
+	kfree(priv->tx_ring);
+
+out_rx_ring_cleanup:
+	kfree(priv->rx_ring);
+
+out:
+	return -ENOMEM;
+}
+
+void ipoib_dev_cleanup(struct net_device *dev)
+{
+	struct ipoib_dev_priv *priv = netdev_priv(dev), *cpriv, *tcpriv;
+
+	ipoib_delete_debug_file(dev);
+
+	/* Delete any child interfaces first */
+	list_for_each_entry_safe(cpriv, tcpriv, &priv->child_intfs, list) {
+		unregister_netdev(cpriv->dev);
+		ipoib_dev_cleanup(cpriv->dev);
+		free_netdev(cpriv->dev);
+	}
+
+	ipoib_ib_dev_cleanup(dev);
+
+	if (priv->rx_ring) {
+		kfree(priv->rx_ring);
+		priv->rx_ring = NULL;
+	}
+
+	if (priv->tx_ring) {
+		kfree(priv->tx_ring);
+		priv->tx_ring = NULL;
+	}
+}
+
+static void ipoib_setup(struct net_device *dev)
+{
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+
+	dev->open 		 = ipoib_open;
+	dev->stop 		 = ipoib_stop;
+	dev->change_mtu 	 = ipoib_change_mtu;
+	dev->hard_start_xmit 	 = ipoib_start_xmit;
+	dev->get_stats 		 = ipoib_get_stats;
+	dev->tx_timeout 	 = ipoib_timeout;
+	dev->hard_header 	 = ipoib_hard_header;
+	dev->set_multicast_list  = ipoib_set_mcast_list;
+	dev->neigh_setup         = ipoib_neigh_setup_dev;
+
+	dev->watchdog_timeo 	 = HZ;
+
+	dev->rebuild_header 	 = NULL;
+	dev->set_mac_address 	 = NULL;
+	dev->header_cache_update = NULL;
+
+	dev->flags              |= IFF_BROADCAST | IFF_MULTICAST;
+
+	/*
+	 * We add in INFINIBAND_ALEN to allow for the destination
+	 * address "pseudoheader" for skbs without neighbour struct.
+	 */
+	dev->hard_header_len 	 = IPOIB_ENCAP_LEN + INFINIBAND_ALEN;
+	dev->addr_len 		 = INFINIBAND_ALEN;
+	dev->type 		 = ARPHRD_INFINIBAND;
+	dev->tx_queue_len 	 = IPOIB_TX_RING_SIZE * 2;
+	dev->features            = NETIF_F_VLAN_CHALLENGED | NETIF_F_LLTX;
+
+	/* MTU will be reset when mcast join happens */
+	dev->mtu 		 = IPOIB_PACKET_SIZE - IPOIB_ENCAP_LEN;
+	priv->mcast_mtu 	 = priv->admin_mtu = dev->mtu;
+
+	memcpy(dev->broadcast, ipv4_bcast_addr, INFINIBAND_ALEN);
+
+	netif_carrier_off(dev);
+
+	SET_MODULE_OWNER(dev);
+
+	priv->dev = dev;
+
+	spin_lock_init(&priv->lock);
+	spin_lock_init(&priv->tx_lock);
+
+	init_MUTEX(&priv->mcast_mutex);
+	init_MUTEX(&priv->vlan_mutex);
+
+	INIT_LIST_HEAD(&priv->path_list);
+	INIT_LIST_HEAD(&priv->child_intfs);
+	INIT_LIST_HEAD(&priv->dead_ahs);
+	INIT_LIST_HEAD(&priv->multicast_list);
+
+	INIT_WORK(&priv->pkey_task,    ipoib_pkey_poll,          priv->dev);
+	INIT_WORK(&priv->mcast_task,   ipoib_mcast_join_task,    priv->dev);
+	INIT_WORK(&priv->flush_task,   ipoib_ib_dev_flush,       priv->dev);
+	INIT_WORK(&priv->restart_task, ipoib_mcast_restart_task, priv->dev);
+	INIT_WORK(&priv->ah_reap_task, ipoib_reap_ah,            priv->dev);
+}
+
+struct ipoib_dev_priv *ipoib_intf_alloc(const char *name)
+{
+	struct net_device *dev;
+
+	dev = alloc_netdev((int) sizeof (struct ipoib_dev_priv), name,
+			   ipoib_setup);
+	if (!dev)
+		return NULL;
+
+	return netdev_priv(dev);
+}
+
+static ssize_t show_pkey(struct class_device *cdev, char *buf)
+{
+	struct ipoib_dev_priv *priv =
+		netdev_priv(container_of(cdev, struct net_device, class_dev));
+
+	return sprintf(buf, "0x%04x\n", priv->pkey);
+}
+static CLASS_DEVICE_ATTR(pkey, S_IRUGO, show_pkey, NULL);
+
+static ssize_t create_child(struct class_device *cdev,
+			    const char *buf, size_t count)
+{
+	int pkey;
+	int ret;
+
+	if (sscanf(buf, "%i", &pkey) != 1)
+		return -EINVAL;
+
+	if (pkey < 0 || pkey > 0xffff)
+		return -EINVAL;
+
+	ret = ipoib_vlan_add(container_of(cdev, struct net_device, class_dev),
+			     pkey);
+
+	return ret ? ret : count;
+}
+static CLASS_DEVICE_ATTR(create_child, S_IWUGO, NULL, create_child);
+
+static ssize_t delete_child(struct class_device *cdev,
+			    const char *buf, size_t count)
+{
+	int pkey;
+	int ret;
+
+	if (sscanf(buf, "%i", &pkey) != 1)
+		return -EINVAL;
+
+	if (pkey < 0 || pkey > 0xffff)
+		return -EINVAL;
+
+	ret = ipoib_vlan_delete(container_of(cdev, struct net_device, class_dev),
+				pkey);
+
+	return ret ? ret : count;
+
+}
+static CLASS_DEVICE_ATTR(delete_child, S_IWUGO, NULL, delete_child);
+
+int ipoib_add_pkey_attr(struct net_device *dev)
+{
+	return class_device_create_file(&dev->class_dev,
+					&class_device_attr_pkey);
+}
+
+static struct net_device *ipoib_add_port(const char *format,
+					 struct ib_device *hca, u8 port)
+{
+	struct ipoib_dev_priv *priv;
+	int result = -ENOMEM;
+
+	priv = ipoib_intf_alloc(format);
+	if (!priv)
+		goto alloc_mem_failed;
+
+	SET_NETDEV_DEV(priv->dev, hca->dma_device);
+
+	result = ib_query_pkey(hca, port, 0, &priv->pkey);
+	if (result) {
+		printk(KERN_WARNING "%s: ib_query_pkey port %d failed (ret = %d)\n",
+		       hca->name, port, result);
+		goto alloc_mem_failed;
+	}
+
+	priv->dev->broadcast[8] = priv->pkey >> 8;
+	priv->dev->broadcast[9] = priv->pkey & 0xff;
+
+	result = ib_query_gid(hca, port, 0, &priv->local_gid);
+	if (result) {
+		printk(KERN_WARNING "%s: ib_query_gid port %d failed (ret = %d)\n",
+		       hca->name, port, result);
+		goto alloc_mem_failed;
+	} else
+		memcpy(priv->dev->dev_addr + 4, priv->local_gid.raw, sizeof (union ib_gid));
+
+
+	result = ipoib_dev_init(priv->dev, hca, port);
+	if (result < 0) {
+		printk(KERN_WARNING "%s: failed to initialize port %d (ret = %d)\n",
+		       hca->name, port, result);
+		goto device_init_failed;
+	}
+
+	INIT_IB_EVENT_HANDLER(&priv->event_handler,
+			      priv->ca, ipoib_event);
+	result = ib_register_event_handler(&priv->event_handler);
+	if (result < 0) {
+		printk(KERN_WARNING "%s: ib_register_event_handler failed for "
+		       "port %d (ret = %d)\n",
+		       hca->name, port, result);
+		goto event_failed;
+	}
+
+	result = register_netdev(priv->dev);
+	if (result) {
+		printk(KERN_WARNING "%s: couldn't register ipoib port %d; error %d\n",
+		       hca->name, port, result);
+		goto register_failed;
+	}
+
+	if (ipoib_create_debug_file(priv->dev))
+		goto debug_failed;
+
+	if (ipoib_add_pkey_attr(priv->dev))
+		goto sysfs_failed;
+	if (class_device_create_file(&priv->dev->class_dev,
+				     &class_device_attr_create_child))
+		goto sysfs_failed;
+	if (class_device_create_file(&priv->dev->class_dev,
+				     &class_device_attr_delete_child))
+		goto sysfs_failed;
+
+	return priv->dev;
+
+sysfs_failed:
+	ipoib_delete_debug_file(priv->dev);
+
+debug_failed:
+	unregister_netdev(priv->dev);
+
+register_failed:
+	ib_unregister_event_handler(&priv->event_handler);
+
+event_failed:
+	ipoib_dev_cleanup(priv->dev);
+
+device_init_failed:
+	free_netdev(priv->dev);
+
+alloc_mem_failed:
+	return ERR_PTR(result);
+}
+
+static void ipoib_add_one(struct ib_device *device)
+{
+	struct list_head *dev_list;
+	struct net_device *dev;
+	struct ipoib_dev_priv *priv;
+	int s, e, p;
+
+	dev_list = kmalloc(sizeof *dev_list, GFP_KERNEL);
+	if (!dev_list)
+		return;
+
+	INIT_LIST_HEAD(dev_list);
+
+	if (device->node_type == IB_NODE_SWITCH) {
+		s = 0;
+		e = 0;
+	} else {
+		s = 1;
+		e = device->phys_port_cnt;
+	}
+
+	for (p = s; p <= e; ++p) {
+		dev = ipoib_add_port("ib%d", device, p);
+		if (!IS_ERR(dev)) {
+			priv = netdev_priv(dev);
+			list_add_tail(&priv->list, dev_list);
+		}
+	}
+
+	ib_set_client_data(device, &ipoib_client, dev_list);
+}
+
+static void ipoib_remove_one(struct ib_device *device)
+{
+	struct ipoib_dev_priv *priv, *tmp;
+	struct list_head *dev_list;
+
+	dev_list = ib_get_client_data(device, &ipoib_client);
+
+	list_for_each_entry_safe(priv, tmp, dev_list, list) {
+		ib_unregister_event_handler(&priv->event_handler);
+
+		unregister_netdev(priv->dev);
+		ipoib_dev_cleanup(priv->dev);
+		free_netdev(priv->dev);
+	}
+}
+
+static int __init ipoib_init_module(void)
+{
+	int ret;
+
+	ret = ipoib_register_debugfs();
+	if (ret)
+		return ret;
+
+	/*
+	 * We create our own workqueue mainly because we want to be
+	 * able to flush it when devices are being removed.  We can't
+	 * use schedule_work()/flush_scheduled_work() because both
+	 * unregister_netdev() and linkwatch_event take the rtnl lock,
+	 * so flush_scheduled_work() can deadlock during device
+	 * removal.
+	 */
+	ipoib_workqueue = create_singlethread_workqueue("ipoib");
+	if (!ipoib_workqueue) {
+		ret = -ENOMEM;
+		goto err_fs;
+	}
+
+	ret = ib_register_client(&ipoib_client);
+	if (ret)
+		goto err_wq;
+
+	return 0;
+
+err_fs:
+	ipoib_unregister_debugfs();
+
+err_wq:
+	destroy_workqueue(ipoib_workqueue);
+
+	return ret;
+}
+
+static void __exit ipoib_cleanup_module(void)
+{
+	ipoib_unregister_debugfs();
+	ib_unregister_client(&ipoib_client);
+	destroy_workqueue(ipoib_workqueue);
+}
+
+module_init(ipoib_init_module);
+module_exit(ipoib_cleanup_module);
diff -Nru a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,985 @@
+/*
+ * Copyright (c) 2004, 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: ipoib_multicast.c 1362 2004-12-18 15:56:29Z roland $
+ */
+
+#include <linux/skbuff.h>
+#include <linux/rtnetlink.h>
+#include <linux/ip.h>
+#include <linux/in.h>
+#include <linux/igmp.h>
+#include <linux/inetdevice.h>
+#include <linux/delay.h>
+#include <linux/completion.h>
+
+#include "ipoib.h"
+
+#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
+static int mcast_debug_level;
+
+module_param(mcast_debug_level, int, 0644);
+MODULE_PARM_DESC(mcast_debug_level,
+		 "Enable multicast debug tracing if > 0");
+#endif
+
+static DECLARE_MUTEX(mcast_mutex);
+
+/* Used for all multicast joins (broadcast, IPv4 mcast and IPv6 mcast) */
+struct ipoib_mcast {
+	struct ib_sa_mcmember_rec mcmember;
+	struct ipoib_ah          *ah;
+
+	struct rb_node    rb_node;
+	struct list_head  list;
+	struct completion done;
+
+	int                 query_id;
+	struct ib_sa_query *query;
+
+	unsigned long created;
+	unsigned long backoff;
+
+	unsigned long flags;
+	unsigned char logcount;
+
+	struct list_head  neigh_list;
+
+	struct sk_buff_head pkt_queue;
+
+	struct net_device *dev;
+};
+
+struct ipoib_mcast_iter {
+	struct net_device *dev;
+	union ib_gid       mgid;
+	unsigned long      created;
+	unsigned int       queuelen;
+	unsigned int       complete;
+	unsigned int       send_only;
+};
+
+static void ipoib_mcast_free(struct ipoib_mcast *mcast)
+{
+	struct net_device *dev = mcast->dev;
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+	struct ipoib_neigh *neigh, *tmp;
+	unsigned long flags;
+
+	ipoib_dbg_mcast(netdev_priv(dev),
+			"deleting multicast group " IPOIB_GID_FMT "\n",
+			IPOIB_GID_ARG(mcast->mcmember.mgid));
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	list_for_each_entry_safe(neigh, tmp, &mcast->neigh_list, list) {
+		ipoib_put_ah(neigh->ah);
+		*to_ipoib_neigh(neigh->neighbour) = NULL;
+		neigh->neighbour->ops->destructor = NULL;
+		kfree(neigh);
+	}
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	if (mcast->ah)
+		ipoib_put_ah(mcast->ah);
+
+	while (!skb_queue_empty(&mcast->pkt_queue)) {
+		struct sk_buff *skb = skb_dequeue(&mcast->pkt_queue);
+
+		skb->dev = dev;
+		dev_kfree_skb_any(skb);
+	}
+
+	kfree(mcast);
+}
+
+static struct ipoib_mcast *ipoib_mcast_alloc(struct net_device *dev,
+					     int can_sleep)
+{
+	struct ipoib_mcast *mcast;
+
+	mcast = kmalloc(sizeof (*mcast), can_sleep ? GFP_KERNEL : GFP_ATOMIC);
+	if (!mcast)
+		return NULL;
+
+	memset(mcast, 0, sizeof (*mcast));
+
+	init_completion(&mcast->done);
+
+	mcast->dev = dev;
+	mcast->created = jiffies;
+	mcast->backoff = HZ;
+	mcast->logcount = 0;
+
+	INIT_LIST_HEAD(&mcast->list);
+	INIT_LIST_HEAD(&mcast->neigh_list);
+	skb_queue_head_init(&mcast->pkt_queue);
+
+	mcast->ah    = NULL;
+	mcast->query = NULL;
+
+	return mcast;
+}
+
+static struct ipoib_mcast *__ipoib_mcast_find(struct net_device *dev, union ib_gid *mgid)
+{
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+	struct rb_node *n = priv->multicast_tree.rb_node;
+
+	while (n) {
+		struct ipoib_mcast *mcast;
+		int ret;
+
+		mcast = rb_entry(n, struct ipoib_mcast, rb_node);
+
+		ret = memcmp(mgid->raw, mcast->mcmember.mgid.raw,
+			     sizeof (union ib_gid));
+		if (ret < 0)
+			n = n->rb_left;
+		else if (ret > 0)
+			n = n->rb_right;
+		else
+			return mcast;
+	}
+
+	return NULL;
+}
+
+static int __ipoib_mcast_add(struct net_device *dev, struct ipoib_mcast *mcast)
+{
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+	struct rb_node **n = &priv->multicast_tree.rb_node, *pn = NULL;
+
+	while (*n) {
+		struct ipoib_mcast *tmcast;
+		int ret;
+
+		pn = *n;
+		tmcast = rb_entry(pn, struct ipoib_mcast, rb_node);
+
+		ret = memcmp(mcast->mcmember.mgid.raw, tmcast->mcmember.mgid.raw,
+			     sizeof (union ib_gid));
+		if (ret < 0)
+			n = &pn->rb_left;
+		else if (ret > 0)
+			n = &pn->rb_right;
+		else
+			return -EEXIST;
+	}
+
+	rb_link_node(&mcast->rb_node, pn, n);
+	rb_insert_color(&mcast->rb_node, &priv->multicast_tree);
+
+	return 0;
+}
+
+static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast,
+				   struct ib_sa_mcmember_rec *mcmember)
+{
+	struct net_device *dev = mcast->dev;
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+	int ret;
+
+	mcast->mcmember = *mcmember;
+
+	/* Set the cached Q_Key before we attach if it's the broadcast group */
+	if (!memcmp(mcast->mcmember.mgid.raw, priv->dev->broadcast + 4,
+		    sizeof (union ib_gid))) {
+		priv->qkey = be32_to_cpu(priv->broadcast->mcmember.qkey);
+		priv->tx_wr.wr.ud.remote_qkey = priv->qkey;
+	}
+
+	if (!test_bit(IPOIB_MCAST_FLAG_SENDONLY, &mcast->flags)) {
+		if (test_and_set_bit(IPOIB_MCAST_FLAG_ATTACHED, &mcast->flags)) {
+			ipoib_warn(priv, "multicast group " IPOIB_GID_FMT
+				   " already attached\n",
+				   IPOIB_GID_ARG(mcast->mcmember.mgid));
+
+			return 0;
+		}
+
+		ret = ipoib_mcast_attach(dev, be16_to_cpu(mcast->mcmember.mlid),
+					 &mcast->mcmember.mgid);
+		if (ret < 0) {
+			ipoib_warn(priv, "couldn't attach QP to multicast group "
+				   IPOIB_GID_FMT "\n",
+				   IPOIB_GID_ARG(mcast->mcmember.mgid));
+
+			clear_bit(IPOIB_MCAST_FLAG_ATTACHED, &mcast->flags);
+			return ret;
+		}
+	}
+
+	{
+		struct ib_ah_attr av = {
+			.dlid	       = be16_to_cpu(mcast->mcmember.mlid),
+			.port_num      = priv->port,
+			.sl	       = mcast->mcmember.sl,
+			.ah_flags      = IB_AH_GRH,
+			.grh	       = {
+				.flow_label    = be32_to_cpu(mcast->mcmember.flow_label),
+				.hop_limit     = mcast->mcmember.hop_limit,
+				.sgid_index    = 0,
+				.traffic_class = mcast->mcmember.traffic_class
+			}
+		};
+
+		av.grh.dgid = mcast->mcmember.mgid;
+
+		if (ib_sa_rate_enum_to_int(mcast->mcmember.rate) > 0)
+			av.static_rate = (2 * priv->local_rate -
+					  ib_sa_rate_enum_to_int(mcast->mcmember.rate) - 1) /
+				(priv->local_rate ? priv->local_rate : 1);
+
+		ipoib_dbg_mcast(priv, "static_rate %d for local port %dX, mcmember %dX\n",
+				av.static_rate, priv->local_rate,
+				ib_sa_rate_enum_to_int(mcast->mcmember.rate));
+
+		mcast->ah = ipoib_create_ah(dev, priv->pd, &av);
+		if (!mcast->ah) {
+			ipoib_warn(priv, "ib_address_create failed\n");
+		} else {
+			ipoib_dbg_mcast(priv, "MGID " IPOIB_GID_FMT
+					" AV %p, LID 0x%04x, SL %d\n",
+					IPOIB_GID_ARG(mcast->mcmember.mgid),
+					mcast->ah->ah,
+					be16_to_cpu(mcast->mcmember.mlid),
+					mcast->mcmember.sl);
+		}
+	}
+
+	/* actually send any queued packets */
+	while (!skb_queue_empty(&mcast->pkt_queue)) {
+		struct sk_buff *skb = skb_dequeue(&mcast->pkt_queue);
+
+		skb->dev = dev;
+
+		if (!skb->dst || !skb->dst->neighbour) {
+			/* put pseudoheader back on for next time */
+			skb_push(skb, sizeof (struct ipoib_pseudoheader));
+		}
+
+		if (dev_queue_xmit(skb))
+			ipoib_warn(priv, "dev_queue_xmit failed to requeue packet\n");
+	}
+
+	return 0;
+}
+
+static void
+ipoib_mcast_sendonly_join_complete(int status,
+				   struct ib_sa_mcmember_rec *mcmember,
+				   void *mcast_ptr)
+{
+	struct ipoib_mcast *mcast = mcast_ptr;
+	struct net_device *dev = mcast->dev;
+
+	if (!status)
+		ipoib_mcast_join_finish(mcast, mcmember);
+	else {
+		if (mcast->logcount++ < 20)
+			ipoib_dbg_mcast(netdev_priv(dev), "multicast join failed for "
+					IPOIB_GID_FMT ", status %d\n",
+					IPOIB_GID_ARG(mcast->mcmember.mgid), status);
+
+		/* Flush out any queued packets */
+		while (!skb_queue_empty(&mcast->pkt_queue)) {
+			struct sk_buff *skb = skb_dequeue(&mcast->pkt_queue);
+
+			skb->dev = dev;
+
+			dev_kfree_skb_any(skb);
+		}
+
+		/* Clear the busy flag so we try again */
+		clear_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags);
+	}
+
+	complete(&mcast->done);
+}
+
+static int ipoib_mcast_sendonly_join(struct ipoib_mcast *mcast)
+{
+	struct net_device *dev = mcast->dev;
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+	struct ib_sa_mcmember_rec rec = {
+#if 0				/* Some SMs don't support send-only yet */
+		.join_state = 4
+#else
+		.join_state = 1
+#endif
+	};
+	int ret = 0;
+
+	if (!test_bit(IPOIB_FLAG_OPER_UP, &priv->flags)) {
+		ipoib_dbg_mcast(priv, "device shutting down, no multicast joins\n");
+		return -ENODEV;
+	}
+
+	if (test_and_set_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags)) {
+		ipoib_dbg_mcast(priv, "multicast entry busy, skipping\n");
+		return -EBUSY;
+	}
+
+	rec.mgid     = mcast->mcmember.mgid;
+	rec.port_gid = priv->local_gid;
+	rec.pkey     = be16_to_cpu(priv->pkey);
+
+	ret = ib_sa_mcmember_rec_set(priv->ca, priv->port, &rec,
+				     IB_SA_MCMEMBER_REC_MGID		|
+				     IB_SA_MCMEMBER_REC_PORT_GID	|
+				     IB_SA_MCMEMBER_REC_PKEY		|
+				     IB_SA_MCMEMBER_REC_JOIN_STATE,
+				     1000, GFP_ATOMIC,
+				     ipoib_mcast_sendonly_join_complete,
+				     mcast, &mcast->query);
+	if (ret < 0) {
+		ipoib_warn(priv, "ib_sa_mcmember_rec_set failed (ret = %d)\n",
+			   ret);
+	} else {
+		ipoib_dbg_mcast(priv, "no multicast record for " IPOIB_GID_FMT
+				", starting join\n",
+				IPOIB_GID_ARG(mcast->mcmember.mgid));
+
+		mcast->query_id = ret;
+	}
+
+	return ret;
+}
+
+static void ipoib_mcast_join_complete(int status,
+				      struct ib_sa_mcmember_rec *mcmember,
+				      void *mcast_ptr)
+{
+	struct ipoib_mcast *mcast = mcast_ptr;
+	struct net_device *dev = mcast->dev;
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+
+	ipoib_dbg_mcast(priv, "join completion for " IPOIB_GID_FMT
+			" (status %d)\n",
+			IPOIB_GID_ARG(mcast->mcmember.mgid), status);
+
+	if (!status && !ipoib_mcast_join_finish(mcast, mcmember)) {
+		mcast->backoff = HZ;
+		down(&mcast_mutex);
+		if (test_bit(IPOIB_MCAST_RUN, &priv->flags))
+			queue_work(ipoib_workqueue, &priv->mcast_task);
+		up(&mcast_mutex);
+		complete(&mcast->done);
+		return;
+	}
+
+	if (status == -EINTR) {
+		complete(&mcast->done);
+		return;
+	}
+
+	if (status && mcast->logcount++ < 20) {
+		if (status == -ETIMEDOUT || status == -EINTR) {
+			ipoib_dbg_mcast(priv, "multicast join failed for " IPOIB_GID_FMT
+					", status %d\n",
+					IPOIB_GID_ARG(mcast->mcmember.mgid),
+					status);
+		} else {
+			ipoib_warn(priv, "multicast join failed for "
+				   IPOIB_GID_FMT ", status %d\n",
+				   IPOIB_GID_ARG(mcast->mcmember.mgid),
+				   status);
+		}
+	}
+
+	mcast->backoff *= 2;
+	if (mcast->backoff > IPOIB_MAX_BACKOFF_SECONDS)
+		mcast->backoff = IPOIB_MAX_BACKOFF_SECONDS;
+
+	mcast->query = NULL;
+
+	down(&mcast_mutex);
+	if (test_bit(IPOIB_MCAST_RUN, &priv->flags)) {
+		if (status == -ETIMEDOUT)
+			queue_work(ipoib_workqueue, &priv->mcast_task);
+		else
+			queue_delayed_work(ipoib_workqueue, &priv->mcast_task,
+					   mcast->backoff * HZ);
+	} else
+		complete(&mcast->done);
+	up(&mcast_mutex);
+
+	return;
+}
+
+static void ipoib_mcast_join(struct net_device *dev, struct ipoib_mcast *mcast,
+			     int create)
+{
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+	struct ib_sa_mcmember_rec rec = {
+		.join_state = 1
+	};
+	ib_sa_comp_mask comp_mask;
+	int ret = 0;
+
+	ipoib_dbg_mcast(priv, "joining MGID " IPOIB_GID_FMT "\n",
+			IPOIB_GID_ARG(mcast->mcmember.mgid));
+
+	rec.mgid     = mcast->mcmember.mgid;
+	rec.port_gid = priv->local_gid;
+	rec.pkey     = be16_to_cpu(priv->pkey);
+
+	comp_mask =
+		IB_SA_MCMEMBER_REC_MGID		|
+		IB_SA_MCMEMBER_REC_PORT_GID	|
+		IB_SA_MCMEMBER_REC_PKEY		|
+		IB_SA_MCMEMBER_REC_JOIN_STATE;
+
+	if (create) {
+		comp_mask |=
+			IB_SA_MCMEMBER_REC_QKEY		|
+			IB_SA_MCMEMBER_REC_SL		|
+			IB_SA_MCMEMBER_REC_FLOW_LABEL	|
+			IB_SA_MCMEMBER_REC_TRAFFIC_CLASS;
+
+		rec.qkey	  = priv->broadcast->mcmember.qkey;
+		rec.sl		  = priv->broadcast->mcmember.sl;
+		rec.flow_label	  = priv->broadcast->mcmember.flow_label;
+		rec.traffic_class = priv->broadcast->mcmember.traffic_class;
+	}
+
+	ret = ib_sa_mcmember_rec_set(priv->ca, priv->port, &rec, comp_mask,
+				     mcast->backoff * 1000, GFP_ATOMIC,
+				     ipoib_mcast_join_complete,
+				     mcast, &mcast->query);
+
+	if (ret < 0) {
+		ipoib_warn(priv, "ib_sa_mcmember_rec_set failed, status %d\n", ret);
+
+		mcast->backoff *= 2;
+		if (mcast->backoff > IPOIB_MAX_BACKOFF_SECONDS)
+			mcast->backoff = IPOIB_MAX_BACKOFF_SECONDS;
+
+		down(&mcast_mutex);
+		if (test_bit(IPOIB_MCAST_RUN, &priv->flags))
+			queue_delayed_work(ipoib_workqueue,
+					   &priv->mcast_task,
+					   mcast->backoff);
+		up(&mcast_mutex);
+	} else
+		mcast->query_id = ret;
+}
+
+void ipoib_mcast_join_task(void *dev_ptr)
+{
+	struct net_device *dev = dev_ptr;
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+
+	if (!test_bit(IPOIB_MCAST_RUN, &priv->flags))
+		return;
+
+	if (ib_query_gid(priv->ca, priv->port, 0, &priv->local_gid))
+		ipoib_warn(priv, "ib_gid_entry_get() failed\n");
+	else
+		memcpy(priv->dev->dev_addr + 4, priv->local_gid.raw, sizeof (union ib_gid));
+
+	{
+		struct ib_port_attr attr;
+
+		if (!ib_query_port(priv->ca, priv->port, &attr)) {
+			priv->local_lid  = attr.lid;
+			priv->local_rate = attr.active_speed *
+				ib_width_enum_to_int(attr.active_width);
+		} else
+			ipoib_warn(priv, "ib_query_port failed\n");
+	}
+
+	if (!priv->broadcast) {
+		priv->broadcast = ipoib_mcast_alloc(dev, 1);
+		if (!priv->broadcast) {
+			ipoib_warn(priv, "failed to allocate broadcast group\n");
+			down(&mcast_mutex);
+			if (test_bit(IPOIB_MCAST_RUN, &priv->flags))
+				queue_delayed_work(ipoib_workqueue,
+						   &priv->mcast_task, HZ);
+			up(&mcast_mutex);
+			return;
+		}
+
+		memcpy(priv->broadcast->mcmember.mgid.raw, priv->dev->broadcast + 4,
+		       sizeof (union ib_gid));
+
+		spin_lock_irq(&priv->lock);
+		__ipoib_mcast_add(dev, priv->broadcast);
+		spin_unlock_irq(&priv->lock);
+	}
+
+	if (!test_bit(IPOIB_MCAST_FLAG_ATTACHED, &priv->broadcast->flags)) {
+		ipoib_mcast_join(dev, priv->broadcast, 0);
+		return;
+	}
+
+	while (1) {
+		struct ipoib_mcast *mcast = NULL;
+
+		spin_lock_irq(&priv->lock);
+		list_for_each_entry(mcast, &priv->multicast_list, list) {
+			if (!test_bit(IPOIB_MCAST_FLAG_SENDONLY, &mcast->flags)
+			    && !test_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags)
+			    && !test_bit(IPOIB_MCAST_FLAG_ATTACHED, &mcast->flags)) {
+				/* Found the next unjoined group */
+				break;
+			}
+		}
+		spin_unlock_irq(&priv->lock);
+
+		if (&mcast->list == &priv->multicast_list) {
+			/* All done */
+			break;
+		}
+
+		ipoib_mcast_join(dev, mcast, 1);
+		return;
+	}
+
+	priv->mcast_mtu = ib_mtu_enum_to_int(priv->broadcast->mcmember.mtu) -
+		IPOIB_ENCAP_LEN;
+	dev->mtu = min(priv->mcast_mtu, priv->admin_mtu);
+
+	ipoib_dbg_mcast(priv, "successfully joined all multicast groups\n");
+
+	clear_bit(IPOIB_MCAST_RUN, &priv->flags);
+	netif_carrier_on(dev);
+}
+
+int ipoib_mcast_start_thread(struct net_device *dev)
+{
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+
+	ipoib_dbg_mcast(priv, "starting multicast thread\n");
+
+	down(&mcast_mutex);
+	if (!test_and_set_bit(IPOIB_MCAST_RUN, &priv->flags))
+		queue_work(ipoib_workqueue, &priv->mcast_task);
+	up(&mcast_mutex);
+
+	return 0;
+}
+
+int ipoib_mcast_stop_thread(struct net_device *dev)
+{
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+	struct ipoib_mcast *mcast;
+
+	ipoib_dbg_mcast(priv, "stopping multicast thread\n");
+
+	down(&mcast_mutex);
+	clear_bit(IPOIB_MCAST_RUN, &priv->flags);
+	cancel_delayed_work(&priv->mcast_task);
+	up(&mcast_mutex);
+
+	flush_workqueue(ipoib_workqueue);
+
+	if (priv->broadcast && priv->broadcast->query) {
+		ib_sa_cancel_query(priv->broadcast->query_id, priv->broadcast->query);
+		priv->broadcast->query = NULL;
+		ipoib_dbg_mcast(priv, "waiting for bcast\n");
+		wait_for_completion(&priv->broadcast->done);
+	}
+
+	list_for_each_entry(mcast, &priv->multicast_list, list) {
+		if (mcast->query) {
+			ib_sa_cancel_query(mcast->query_id, mcast->query);
+			mcast->query = NULL;
+			ipoib_dbg_mcast(priv, "waiting for MGID " IPOIB_GID_FMT "\n",
+					IPOIB_GID_ARG(mcast->mcmember.mgid));
+			wait_for_completion(&mcast->done);
+		}
+	}
+
+	return 0;
+}
+
+static int ipoib_mcast_leave(struct net_device *dev, struct ipoib_mcast *mcast)
+{
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+	struct ib_sa_mcmember_rec rec = {
+		.join_state = 1
+	};
+	int ret = 0;
+
+	if (!test_and_clear_bit(IPOIB_MCAST_FLAG_ATTACHED, &mcast->flags))
+		return 0;
+
+	ipoib_dbg_mcast(priv, "leaving MGID " IPOIB_GID_FMT "\n",
+			IPOIB_GID_ARG(mcast->mcmember.mgid));
+
+	rec.mgid     = mcast->mcmember.mgid;
+	rec.port_gid = priv->local_gid;
+	rec.pkey     = be16_to_cpu(priv->pkey);
+
+	/* Remove ourselves from the multicast group */
+	ret = ipoib_mcast_detach(dev, be16_to_cpu(mcast->mcmember.mlid),
+				 &mcast->mcmember.mgid);
+	if (ret)
+		ipoib_warn(priv, "ipoib_mcast_detach failed (result = %d)\n", ret);
+
+	/*
+	 * Just make one shot at leaving and don't wait for a reply;
+	 * if we fail, too bad.
+	 */
+	ret = ib_sa_mcmember_rec_delete(priv->ca, priv->port, &rec,
+					IB_SA_MCMEMBER_REC_MGID		|
+					IB_SA_MCMEMBER_REC_PORT_GID	|
+					IB_SA_MCMEMBER_REC_PKEY		|
+					IB_SA_MCMEMBER_REC_JOIN_STATE,
+					0, GFP_ATOMIC, NULL,
+					mcast, &mcast->query);
+	if (ret < 0)
+		ipoib_warn(priv, "ib_sa_mcmember_rec_delete failed "
+			   "for leave (result = %d)\n", ret);
+
+	return 0;
+}
+
+void ipoib_mcast_send(struct net_device *dev, union ib_gid *mgid,
+		      struct sk_buff *skb)
+{
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+	struct ipoib_mcast *mcast;
+
+	/*
+	 * We can only be called from ipoib_start_xmit, so we're
+	 * inside tx_lock -- no need to save/restore flags.
+	 */
+	spin_lock(&priv->lock);
+
+	mcast = __ipoib_mcast_find(dev, mgid);
+	if (!mcast) {
+		/* Let's create a new send only group now */
+		ipoib_dbg_mcast(priv, "setting up send only multicast group for "
+				IPOIB_GID_FMT "\n", IPOIB_GID_ARG(*mgid));
+
+		mcast = ipoib_mcast_alloc(dev, 0);
+		if (!mcast) {
+			ipoib_warn(priv, "unable to allocate memory for "
+				   "multicast structure\n");
+			dev_kfree_skb_any(skb);
+			goto out;
+		}
+
+		set_bit(IPOIB_MCAST_FLAG_SENDONLY, &mcast->flags);
+		mcast->mcmember.mgid = *mgid;
+		__ipoib_mcast_add(dev, mcast);
+		list_add_tail(&mcast->list, &priv->multicast_list);
+	}
+
+	if (!mcast->ah) {
+		if (skb_queue_len(&mcast->pkt_queue) < IPOIB_MAX_MCAST_QUEUE)
+			skb_queue_tail(&mcast->pkt_queue, skb);
+		else
+			dev_kfree_skb_any(skb);
+
+		if (mcast->query)
+			ipoib_dbg_mcast(priv, "no address vector, "
+					"but multicast join already started\n");
+		else if (test_bit(IPOIB_MCAST_FLAG_SENDONLY, &mcast->flags))
+			ipoib_mcast_sendonly_join(mcast);
+
+		/*
+		 * If lookup completes between here and out:, don't
+		 * want to send packet twice.
+		 */
+		mcast = NULL;
+	}
+
+out:
+	if (mcast && mcast->ah) {
+		if (skb->dst            &&
+		    skb->dst->neighbour &&
+		    !*to_ipoib_neigh(skb->dst->neighbour)) {
+			struct ipoib_neigh *neigh = kmalloc(sizeof *neigh, GFP_ATOMIC);
+
+			if (neigh) {
+				kref_get(&mcast->ah->ref);
+				neigh->ah  	= mcast->ah;
+				neigh->neighbour = skb->dst->neighbour;
+				*to_ipoib_neigh(skb->dst->neighbour) = neigh;
+				list_add_tail(&neigh->list, &mcast->neigh_list);
+			}
+		}
+
+		ipoib_send(dev, skb, mcast->ah, IB_MULTICAST_QPN);
+	}
+
+	spin_unlock(&priv->lock);
+}
+
+void ipoib_mcast_dev_flush(struct net_device *dev)
+{
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+	LIST_HEAD(remove_list);
+	struct ipoib_mcast *mcast, *tmcast, *nmcast;
+	unsigned long flags;
+
+	ipoib_dbg_mcast(priv, "flushing multicast list\n");
+
+	spin_lock_irqsave(&priv->lock, flags);
+	list_for_each_entry_safe(mcast, tmcast, &priv->multicast_list, list) {
+		nmcast = ipoib_mcast_alloc(dev, 0);
+		if (nmcast) {
+			nmcast->flags =
+				mcast->flags & (1 << IPOIB_MCAST_FLAG_SENDONLY);
+
+			nmcast->mcmember.mgid = mcast->mcmember.mgid;
+
+			/* Add the new group in before the to-be-destroyed group */
+			list_add_tail(&nmcast->list, &mcast->list);
+			list_del_init(&mcast->list);
+
+			rb_replace_node(&mcast->rb_node, &nmcast->rb_node,
+					&priv->multicast_tree);
+
+			list_add_tail(&mcast->list, &remove_list);
+		} else {
+			ipoib_warn(priv, "could not reallocate multicast group "
+				   IPOIB_GID_FMT "\n",
+				   IPOIB_GID_ARG(mcast->mcmember.mgid));
+		}
+	}
+
+	if (priv->broadcast) {
+		nmcast = ipoib_mcast_alloc(dev, 0);
+		if (nmcast) {
+			nmcast->mcmember.mgid = priv->broadcast->mcmember.mgid;
+
+			rb_replace_node(&priv->broadcast->rb_node,
+					&nmcast->rb_node,
+					&priv->multicast_tree);
+
+			list_add_tail(&priv->broadcast->list, &remove_list);
+		}
+
+		priv->broadcast = nmcast;
+	}
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	list_for_each_entry(mcast, &remove_list, list) {
+		ipoib_mcast_leave(dev, mcast);
+		ipoib_mcast_free(mcast);
+	}
+}
+
+void ipoib_mcast_dev_down(struct net_device *dev)
+{
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+	unsigned long flags;
+
+	/* Delete broadcast since it will be recreated */
+	if (priv->broadcast) {
+		ipoib_dbg_mcast(priv, "deleting broadcast group\n");
+
+		spin_lock_irqsave(&priv->lock, flags);
+		rb_erase(&priv->broadcast->rb_node, &priv->multicast_tree);
+		spin_unlock_irqrestore(&priv->lock, flags);
+		ipoib_mcast_leave(dev, priv->broadcast);
+		ipoib_mcast_free(priv->broadcast);
+		priv->broadcast = NULL;
+	}
+}
+
+void ipoib_mcast_restart_task(void *dev_ptr)
+{
+	struct net_device *dev = dev_ptr;
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+	struct dev_mc_list *mclist;
+	struct ipoib_mcast *mcast, *tmcast;
+	LIST_HEAD(remove_list);
+	unsigned long flags;
+
+	ipoib_dbg_mcast(priv, "restarting multicast task\n");
+
+	ipoib_mcast_stop_thread(dev);
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	/*
+	 * Unfortunately, the networking core only gives us a list of all of
+	 * the multicast hardware addresses. We need to figure out which ones
+	 * are new and which ones have been removed
+	 */
+
+	/* Clear out the found flag */
+	list_for_each_entry(mcast, &priv->multicast_list, list)
+		clear_bit(IPOIB_MCAST_FLAG_FOUND, &mcast->flags);
+
+	/* Mark all of the entries that are found or don't exist */
+	for (mclist = dev->mc_list; mclist; mclist = mclist->next) {
+		union ib_gid mgid;
+
+		memcpy(mgid.raw, mclist->dmi_addr + 4, sizeof mgid);
+
+		/* Add in the P_Key */
+		mgid.raw[4] = (priv->pkey >> 8) & 0xff;
+		mgid.raw[5] = priv->pkey & 0xff;
+
+		mcast = __ipoib_mcast_find(dev, &mgid);
+		if (!mcast || test_bit(IPOIB_MCAST_FLAG_SENDONLY, &mcast->flags)) {
+			struct ipoib_mcast *nmcast;
+
+			/* Not found or send-only group, let's add a new entry */
+			ipoib_dbg_mcast(priv, "adding multicast entry for mgid "
+					IPOIB_GID_FMT "\n", IPOIB_GID_ARG(mgid));
+
+			nmcast = ipoib_mcast_alloc(dev, 0);
+			if (!nmcast) {
+				ipoib_warn(priv, "unable to allocate memory for multicast structure\n");
+				continue;
+			}
+
+			set_bit(IPOIB_MCAST_FLAG_FOUND, &nmcast->flags);
+
+			nmcast->mcmember.mgid = mgid;
+
+			if (mcast) {
+				/* Destroy the send only entry */
+				list_del(&mcast->list);
+				list_add_tail(&mcast->list, &remove_list);
+
+				rb_replace_node(&mcast->rb_node,
+						&nmcast->rb_node,
+						&priv->multicast_tree);
+			} else
+				__ipoib_mcast_add(dev, nmcast);
+
+			list_add_tail(&nmcast->list, &priv->multicast_list);
+		}
+
+		if (mcast)
+			set_bit(IPOIB_MCAST_FLAG_FOUND, &mcast->flags);
+	}
+
+	/* Remove all of the entries don't exist anymore */
+	list_for_each_entry_safe(mcast, tmcast, &priv->multicast_list, list) {
+		if (!test_bit(IPOIB_MCAST_FLAG_FOUND, &mcast->flags) &&
+		    !test_bit(IPOIB_MCAST_FLAG_SENDONLY, &mcast->flags)) {
+			ipoib_dbg_mcast(priv, "deleting multicast group " IPOIB_GID_FMT "\n",
+					IPOIB_GID_ARG(mcast->mcmember.mgid));
+
+			rb_erase(&mcast->rb_node, &priv->multicast_tree);
+
+			/* Move to the remove list */
+			list_del(&mcast->list);
+			list_add_tail(&mcast->list, &remove_list);
+		}
+	}
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	/* We have to cancel outside of the spinlock */
+	list_for_each_entry(mcast, &remove_list, list) {
+		ipoib_mcast_leave(mcast->dev, mcast);
+		ipoib_mcast_free(mcast);
+	}
+
+	if (test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags))
+		ipoib_mcast_start_thread(dev);
+}
+
+struct ipoib_mcast_iter *ipoib_mcast_iter_init(struct net_device *dev)
+{
+	struct ipoib_mcast_iter *iter;
+
+	iter = kmalloc(sizeof *iter, GFP_KERNEL);
+	if (!iter)
+		return NULL;
+
+	iter->dev = dev;
+	memset(iter->mgid.raw, 0, sizeof iter->mgid);
+
+	if (ipoib_mcast_iter_next(iter)) {
+		ipoib_mcast_iter_free(iter);
+		return NULL;
+	}
+
+	return iter;
+}
+
+void ipoib_mcast_iter_free(struct ipoib_mcast_iter *iter)
+{
+	kfree(iter);
+}
+
+int ipoib_mcast_iter_next(struct ipoib_mcast_iter *iter)
+{
+	struct ipoib_dev_priv *priv = netdev_priv(iter->dev);
+	struct rb_node *n;
+	struct ipoib_mcast *mcast;
+	int ret = 1;
+
+	spin_lock_irq(&priv->lock);
+
+	n = rb_first(&priv->multicast_tree);
+
+	while (n) {
+		mcast = rb_entry(n, struct ipoib_mcast, rb_node);
+
+		if (memcmp(iter->mgid.raw, mcast->mcmember.mgid.raw,
+			   sizeof (union ib_gid)) < 0) {
+			iter->mgid      = mcast->mcmember.mgid;
+			iter->created   = mcast->created;
+			iter->queuelen  = skb_queue_len(&mcast->pkt_queue);
+			iter->complete  = !!mcast->ah;
+			iter->send_only = !!(mcast->flags & (1 << IPOIB_MCAST_FLAG_SENDONLY));
+
+			ret = 0;
+
+			break;
+		}
+
+		n = rb_next(n);
+	}
+
+	spin_unlock_irq(&priv->lock);
+
+	return ret;
+}
+
+void ipoib_mcast_iter_read(struct ipoib_mcast_iter *iter,
+			   union ib_gid *mgid,
+			   unsigned long *created,
+			   unsigned int *queuelen,
+			   unsigned int *complete,
+			   unsigned int *send_only)
+{
+	*mgid      = iter->mgid;
+	*created   = iter->created;
+	*queuelen  = iter->queuelen;
+	*complete  = iter->complete;
+	*send_only = iter->send_only;
+}
diff -Nru a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,261 @@
+/*
+ * Copyright (c) 2004, 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: ipoib_verbs.c 1349 2004-12-16 21:09:43Z roland $
+ */
+
+#include <ib_cache.h>
+
+#include "ipoib.h"
+
+int ipoib_mcast_attach(struct net_device *dev, u16 mlid, union ib_gid *mgid)
+{
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+	struct ib_qp_attr *qp_attr;
+	int attr_mask;
+	int ret;
+	u16 pkey_index;
+
+	ret = -ENOMEM;
+	qp_attr = kmalloc(sizeof *qp_attr, GFP_KERNEL);
+	if (!qp_attr)
+		goto out;
+
+	if (ib_find_cached_pkey(priv->ca, priv->port, priv->pkey, &pkey_index)) {
+		clear_bit(IPOIB_PKEY_ASSIGNED, &priv->flags);
+		ret = -ENXIO;
+		goto out;
+	}
+	set_bit(IPOIB_PKEY_ASSIGNED, &priv->flags);
+
+	/* set correct QKey for QP */
+	qp_attr->qkey = priv->qkey;
+	attr_mask = IB_QP_QKEY;
+	ret = ib_modify_qp(priv->qp, qp_attr, attr_mask);
+	if (ret) {
+		ipoib_warn(priv, "failed to modify QP, ret = %d\n", ret);
+		goto out;
+	}
+
+	/* attach QP to multicast group */
+	down(&priv->mcast_mutex);
+	ret = ib_attach_mcast(priv->qp, mgid, mlid);
+	up(&priv->mcast_mutex);
+	if (ret)
+		ipoib_warn(priv, "failed to attach to multicast group, ret = %d\n", ret);
+
+out:
+	kfree(qp_attr);
+	return ret;
+}
+
+int ipoib_mcast_detach(struct net_device *dev, u16 mlid, union ib_gid *mgid)
+{
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+	int ret;
+
+	down(&priv->mcast_mutex);
+	ret = ib_detach_mcast(priv->qp, mgid, mlid);
+	up(&priv->mcast_mutex);
+	if (ret)
+		ipoib_warn(priv, "ib_detach_mcast failed (result = %d)\n", ret);
+
+	return ret;
+}
+
+int ipoib_qp_create(struct net_device *dev)
+{
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+	int ret;
+	u16 pkey_index;
+	struct ib_qp_attr qp_attr;
+	int attr_mask;
+
+	/*
+	 * Search through the port P_Key table for the requested pkey value.
+	 * The port has to be assigned to the respective IB partition in
+	 * advance.
+	 */
+	ret = ib_find_cached_pkey(priv->ca, priv->port, priv->pkey, &pkey_index);
+	if (ret) {
+		clear_bit(IPOIB_PKEY_ASSIGNED, &priv->flags);
+		return ret;
+	}
+	set_bit(IPOIB_PKEY_ASSIGNED, &priv->flags);
+
+	qp_attr.qp_state = IB_QPS_INIT;
+	qp_attr.qkey = 0;
+	qp_attr.port_num = priv->port;
+	qp_attr.pkey_index = pkey_index;
+	attr_mask =
+	    IB_QP_QKEY |
+	    IB_QP_PORT |
+	    IB_QP_PKEY_INDEX |
+	    IB_QP_STATE;
+	ret = ib_modify_qp(priv->qp, &qp_attr, attr_mask);
+	if (ret) {
+		ipoib_warn(priv, "failed to modify QP to init, ret = %d\n", ret);
+		goto out_fail;
+	}
+
+	qp_attr.qp_state = IB_QPS_RTR;
+	/* Can't set this in a INIT->RTR transition */
+	attr_mask &= ~IB_QP_PORT;
+	ret = ib_modify_qp(priv->qp, &qp_attr, attr_mask);
+	if (ret) {
+		ipoib_warn(priv, "failed to modify QP to RTR, ret = %d\n", ret);
+		goto out_fail;
+	}
+
+	qp_attr.qp_state = IB_QPS_RTS;
+	qp_attr.sq_psn = 0;
+	attr_mask |= IB_QP_SQ_PSN;
+	attr_mask &= ~IB_QP_PKEY_INDEX;
+	ret = ib_modify_qp(priv->qp, &qp_attr, attr_mask);
+	if (ret) {
+		ipoib_warn(priv, "failed to modify QP to RTS, ret = %d\n", ret);
+		goto out_fail;
+	}
+
+	return 0;
+
+out_fail:
+	ib_destroy_qp(priv->qp);
+	priv->qp = NULL;
+
+	return -EINVAL;
+}
+
+int ipoib_transport_dev_init(struct net_device *dev, struct ib_device *ca)
+{
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+	struct ib_qp_init_attr init_attr = {
+		.cap = {
+			.max_send_wr  = IPOIB_TX_RING_SIZE,
+			.max_recv_wr  = IPOIB_RX_RING_SIZE,
+			.max_send_sge = 1,
+			.max_recv_sge = 1
+		},
+		.sq_sig_type = IB_SIGNAL_ALL_WR,
+		.rq_sig_type = IB_SIGNAL_ALL_WR,
+		.qp_type     = IB_QPT_UD
+	};
+
+	priv->pd = ib_alloc_pd(priv->ca);
+	if (IS_ERR(priv->pd)) {
+		printk(KERN_WARNING "%s: failed to allocate PD\n", ca->name);
+		return -ENODEV;
+	}
+
+	priv->cq = ib_create_cq(priv->ca, ipoib_ib_completion, NULL, dev,
+				IPOIB_TX_RING_SIZE + IPOIB_RX_RING_SIZE + 1);
+	if (IS_ERR(priv->cq)) {
+		printk(KERN_WARNING "%s: failed to create CQ\n", ca->name);
+		goto out_free_pd;
+	}
+
+	if (ib_req_notify_cq(priv->cq, IB_CQ_NEXT_COMP))
+		goto out_free_cq;
+
+	priv->mr = ib_get_dma_mr(priv->pd, IB_ACCESS_LOCAL_WRITE);
+	if (IS_ERR(priv->mr)) {
+		printk(KERN_WARNING "%s: ib_get_dma_mr failed\n", ca->name);
+		goto out_free_cq;
+	}
+
+	init_attr.send_cq = priv->cq;
+	init_attr.recv_cq = priv->cq,
+
+	priv->qp = ib_create_qp(priv->pd, &init_attr);
+	if (IS_ERR(priv->qp)) {
+		printk(KERN_WARNING "%s: failed to create QP\n", ca->name);
+		goto out_free_mr;
+	}
+
+	priv->dev->dev_addr[1] = (priv->qp->qp_num >> 16) & 0xff;
+	priv->dev->dev_addr[2] = (priv->qp->qp_num >>  8) & 0xff;
+	priv->dev->dev_addr[3] = (priv->qp->qp_num      ) & 0xff;
+
+	priv->tx_sge.lkey 	= priv->mr->lkey;
+
+	priv->tx_wr.opcode 	= IB_WR_SEND;
+	priv->tx_wr.sg_list 	= &priv->tx_sge;
+	priv->tx_wr.num_sge 	= 1;
+	priv->tx_wr.send_flags 	= IB_SEND_SIGNALED;
+
+	return 0;
+
+out_free_mr:
+	ib_dereg_mr(priv->mr);
+
+out_free_cq:
+	ib_destroy_cq(priv->cq);
+
+out_free_pd:
+	ib_dealloc_pd(priv->pd);
+	return -ENODEV;
+}
+
+void ipoib_transport_dev_cleanup(struct net_device *dev)
+{
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+
+	if (priv->qp) {
+		if (ib_destroy_qp(priv->qp))
+			ipoib_warn(priv, "ib_qp_destroy failed\n");
+
+		priv->qp = NULL;
+		clear_bit(IPOIB_PKEY_ASSIGNED, &priv->flags);
+	}
+
+	if (ib_dereg_mr(priv->mr))
+		ipoib_warn(priv, "ib_dereg_mr failed\n");
+
+	if (ib_destroy_cq(priv->cq))
+		ipoib_warn(priv, "ib_cq_destroy failed\n");
+
+	if (ib_dealloc_pd(priv->pd))
+		ipoib_warn(priv, "ib_dealloc_pd failed\n");
+}
+
+void ipoib_event(struct ib_event_handler *handler,
+		 struct ib_event *record)
+{
+	struct ipoib_dev_priv *priv =
+		container_of(handler, struct ipoib_dev_priv, event_handler);
+
+	if (record->event == IB_EVENT_PORT_ACTIVE ||
+	    record->event == IB_EVENT_LID_CHANGE  ||
+	    record->event == IB_EVENT_SM_CHANGE) {
+		ipoib_dbg(priv, "Port active event\n");
+		schedule_work(&priv->flush_task);
+	}
+}
diff -Nru a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2004 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: ipoib_vlan.c 1349 2004-12-16 21:09:43Z roland $
+ */
+
+#include <linux/version.h>
+#include <linux/module.h>
+
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/seq_file.h>
+
+#include <asm/uaccess.h>
+
+#include "ipoib.h"
+
+static ssize_t show_parent(struct class_device *class_dev, char *buf)
+{
+	struct net_device *dev =
+		container_of(class_dev, struct net_device, class_dev);
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+
+	return sprintf(buf, "%s\n", priv->parent->name);
+}
+static CLASS_DEVICE_ATTR(parent, S_IRUGO, show_parent, NULL);
+
+int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey)
+{
+	struct ipoib_dev_priv *ppriv, *priv;
+	char intf_name[IFNAMSIZ];
+	int result;
+
+	if (!capable(CAP_NET_ADMIN))
+		return -EPERM;
+
+	ppriv = netdev_priv(pdev);
+
+	down(&ppriv->vlan_mutex);
+
+	/*
+	 * First ensure this isn't a duplicate. We check the parent device and
+	 * then all of the child interfaces to make sure the Pkey doesn't match.
+	 */
+	if (ppriv->pkey == pkey) {
+		result = -ENOTUNIQ;
+		goto err;
+	}
+
+	list_for_each_entry(priv, &ppriv->child_intfs, list) {
+		if (priv->pkey == pkey) {
+			result = -ENOTUNIQ;
+			goto err;
+		}
+	}
+
+	snprintf(intf_name, sizeof intf_name, "%s.%04x",
+		 ppriv->dev->name, pkey);
+	priv = ipoib_intf_alloc(intf_name);
+	if (!priv) {
+		result = -ENOMEM;
+		goto err;
+	}
+
+	set_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags);
+
+	priv->pkey = pkey;
+
+	memcpy(priv->dev->dev_addr, ppriv->dev->dev_addr, INFINIBAND_ALEN);
+	priv->dev->broadcast[8] = pkey >> 8;
+	priv->dev->broadcast[9] = pkey & 0xff;
+
+	result = ipoib_dev_init(priv->dev, ppriv->ca, ppriv->port);
+	if (result < 0) {
+		ipoib_warn(ppriv, "failed to initialize subinterface: "
+			   "device %s, port %d",
+			   ppriv->ca->name, ppriv->port);
+		goto device_init_failed;
+	}
+
+	result = register_netdev(priv->dev);
+	if (result) {
+		ipoib_warn(priv, "failed to initialize; error %i", result);
+		goto register_failed;
+	}
+
+	priv->parent = ppriv->dev;
+
+	if (ipoib_create_debug_file(priv->dev))
+		goto debug_failed;
+
+	if (ipoib_add_pkey_attr(priv->dev))
+		goto sysfs_failed;
+
+	if (class_device_create_file(&priv->dev->class_dev,
+				     &class_device_attr_parent))
+		goto sysfs_failed;
+
+	list_add_tail(&priv->list, &ppriv->child_intfs);
+
+	up(&ppriv->vlan_mutex);
+
+	return 0;
+
+sysfs_failed:
+	ipoib_delete_debug_file(priv->dev);
+
+debug_failed:
+	unregister_netdev(priv->dev);
+
+register_failed:
+	ipoib_dev_cleanup(priv->dev);
+
+device_init_failed:
+	free_netdev(priv->dev);
+
+err:
+	up(&ppriv->vlan_mutex);
+	return result;
+}
+
+int ipoib_vlan_delete(struct net_device *pdev, unsigned short pkey)
+{
+	struct ipoib_dev_priv *ppriv, *priv, *tpriv;
+	int ret = -ENOENT;
+
+	if (!capable(CAP_NET_ADMIN))
+		return -EPERM;
+
+	ppriv = netdev_priv(pdev);
+
+	down(&ppriv->vlan_mutex);
+	list_for_each_entry_safe(priv, tpriv, &ppriv->child_intfs, list) {
+		if (priv->pkey == pkey) {
+			unregister_netdev(priv->dev);
+			ipoib_dev_cleanup(priv->dev);
+
+			list_del(&priv->list);
+
+			kfree(priv);
+
+			ret = 0;
+			break;
+		}
+	}
+	up(&ppriv->vlan_mutex);
+
+	return ret;
+}
diff -Nru a/drivers/input/Kconfig b/drivers/input/Kconfig
--- a/drivers/input/Kconfig	2005-03-01 23:38:52 -08:00
+++ b/drivers/input/Kconfig	2005-03-01 23:38:52 -08:00
@@ -32,7 +32,7 @@
 	  Say Y here if you want your mouse to be accessible as char devices
 	  13:32+ - /dev/input/mouseX and 13:63 - /dev/input/mice as an
 	  emulated IntelliMouse Explorer PS/2 mouse. That way, all user space
-	  programs (includung SVGAlib, GPM and X) will be able to use your
+	  programs (including SVGAlib, GPM and X) will be able to use your
 	  mouse.
 
 	  If unsure, say Y.
diff -Nru a/drivers/input/gameport/Kconfig b/drivers/input/gameport/Kconfig
--- a/drivers/input/gameport/Kconfig	2005-03-01 23:38:51 -08:00
+++ b/drivers/input/gameport/Kconfig	2005-03-01 23:38:51 -08:00
@@ -84,7 +84,7 @@
 	tristate "ForteMedia FM801 gameport support"
 	depends on GAMEPORT
 
-config GAMEPORT_CS461x
+config GAMEPORT_CS461X
 	tristate "Crystal SoundFusion gameport support"
 	depends on GAMEPORT
 
diff -Nru a/drivers/input/gameport/cs461x.c b/drivers/input/gameport/cs461x.c
--- a/drivers/input/gameport/cs461x.c	2005-03-01 23:38:51 -08:00
+++ b/drivers/input/gameport/cs461x.c	2005-03-01 23:38:51 -08:00
@@ -118,7 +118,7 @@
 */
 
 static unsigned long ba0_addr;
-static unsigned int *ba0;
+static unsigned int __iomem *ba0;
 
 static char phys[32];
 static char name[] = "CS416x Gameport";
@@ -127,34 +127,34 @@
 static unsigned long ba1_addr;
 static union ba1_t {
         struct {
-                unsigned int *data0;
-                unsigned int *data1;
-                unsigned int *pmem;
-                unsigned int *reg;
+                unsigned int __iomem *data0;
+                unsigned int __iomem *data1;
+                unsigned int __iomem *pmem;
+                unsigned int __iomem *reg;
         } name;
-        unsigned int *idx[4];
+        unsigned int __iomem *idx[4];
 } ba1;
 
 static void cs461x_poke(unsigned long reg, unsigned int val)
 {
-        ba1.idx[(reg >> 16) & 3][(reg >> 2) & 0x3fff] = val;
+        writel(val, &ba1.idx[(reg >> 16) & 3][(reg >> 2) & 0x3fff]);
 }
 
 static unsigned int cs461x_peek(unsigned long reg)
 {
-        return ba1.idx[(reg >> 16) & 3][(reg >> 2) & 0x3fff];
+        return readl(&ba1.idx[(reg >> 16) & 3][(reg >> 2) & 0x3fff]);
 }
 
 #endif
 
 static void cs461x_pokeBA0(unsigned long reg, unsigned int val)
 {
-        ba0[reg >> 2] = val;
+        writel(val, &ba0[reg >> 2]);
 }
 
 static unsigned int cs461x_peekBA0(unsigned long reg)
 {
-        return ba0[reg >> 2];
+        return readl(&ba0[reg >> 2]);
 }
 
 static int cs461x_free(struct pci_dev *pdev)
diff -Nru a/drivers/input/input.c b/drivers/input/input.c
--- a/drivers/input/input.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/input/input.c	2005-03-01 23:38:58 -08:00
@@ -17,7 +17,6 @@
 #include <linux/module.h>
 #include <linux/random.h>
 #include <linux/major.h>
-#include <linux/pm.h>
 #include <linux/proc_fs.h>
 #include <linux/kobject_uevent.h>
 #include <linux/interrupt.h>
@@ -67,13 +66,10 @@
 {
 	struct input_handle *handle;
 
-	if (dev->pm_dev)
-		pm_access(dev->pm_dev);
-
 	if (type > EV_MAX || !test_bit(type, dev->evbit))
 		return;
 
-	add_mouse_randomness((type << 4) ^ code ^ (code >> 4) ^ value);
+	add_input_randomness(type, code, value);
 
 	switch (type) {
 
@@ -230,8 +226,6 @@
 
 int input_open_device(struct input_handle *handle)
 {
-	if (handle->dev->pm_dev)
-		pm_access(handle->dev->pm_dev);
 	handle->open++;
 	if (handle->dev->open)
 		return handle->dev->open(handle->dev);
@@ -249,8 +243,6 @@
 void input_close_device(struct input_handle *handle)
 {
 	input_release_device(handle);
-	if (handle->dev->pm_dev)
-		pm_dev_idle(handle->dev->pm_dev);
 	if (handle->dev->close)
 		handle->dev->close(handle->dev);
 	handle->open--;
@@ -467,9 +459,6 @@
 	struct list_head * node, * next;
 
 	if (!dev) return;
-
-	if (dev->pm_dev)
-		pm_unregister(dev->pm_dev);
 
 	del_timer_sync(&dev->timer);
 
diff -Nru a/drivers/input/joystick/gamecon.c b/drivers/input/joystick/gamecon.c
--- a/drivers/input/joystick/gamecon.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/input/joystick/gamecon.c	2005-03-01 23:39:17 -08:00
@@ -89,7 +89,7 @@
 static int gc_status_bit[] = { 0x40, 0x80, 0x20, 0x10, 0x08 };
 
 static char *gc_names[] = { NULL, "SNES pad", "NES pad", "NES FourPort", "Multisystem joystick",
-				"Multisystem 2-button joystick", "N64 controller", "PSX controller"
+				"Multisystem 2-button joystick", "N64 controller", "PSX controller",
 				"PSX DDR controller" };
 /*
  * N64 support.
@@ -271,7 +271,7 @@
 		udelay(gc_psx_delay);
 		read = parport_read_status(gc->pd->port) ^ 0x80;
 		for (j = 0; j < 5; j++)
-			data[j] |= (read & gc_status_bit[j] & gc->pads[GC_PSX]) ? (1 << i) : 0;
+			data[j] |= (read & gc_status_bit[j] & (gc->pads[GC_PSX] | gc->pads[GC_DDR])) ? (1 << i) : 0;
 		parport_write_data(gc->pd->port, cmd | GC_PSX_CLOCK | GC_PSX_POWER);
 		udelay(gc_psx_delay);
 	}
@@ -300,7 +300,7 @@
 	gc_psx_command(gc, 0, data2);							/* Dump status */
 
 	for (i =0; i < 5; i++)								/* Find the longest pad */
-		if((gc_status_bit[i] & gc->pads[GC_PSX]) && (GC_PSX_LEN(id[i]) > max_len))
+		if((gc_status_bit[i] & (gc->pads[GC_PSX] | gc->pads[GC_DDR])) && (GC_PSX_LEN(id[i]) > max_len))
 			max_len = GC_PSX_LEN(id[i]);
 
 	for (i = 0; i < max_len * 2; i++) {						/* Read in all the data */
diff -Nru a/drivers/input/joystick/iforce/Kconfig b/drivers/input/joystick/iforce/Kconfig
--- a/drivers/input/joystick/iforce/Kconfig	2005-03-01 23:39:18 -08:00
+++ b/drivers/input/joystick/iforce/Kconfig	2005-03-01 23:39:18 -08:00
@@ -27,5 +27,6 @@
 	  connected to your serial (COM) port.
 
 	  You will need an additional utility called inputattach, see
-	  Documentation/input/joystick.txt and ff.txt.
+	  <file:Documentation/input/joystick.txt>
+	  and <file:Documentation/input/ff.txt>.
 
diff -Nru a/drivers/input/joystick/iforce/iforce-main.c b/drivers/input/joystick/iforce/iforce-main.c
--- a/drivers/input/joystick/iforce/iforce-main.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/input/joystick/iforce/iforce-main.c	2005-03-01 23:38:56 -08:00
@@ -352,7 +352,21 @@
  * Input device fields.
  */
 
-	iforce->dev.id.bustype = BUS_USB;
+	switch (iforce->bus) {
+#ifdef CONFIG_JOYSTICK_IFORCE_USB
+	case IFORCE_USB:
+		iforce->dev.id.bustype = BUS_USB;
+		iforce->dev.dev = &iforce->usbdev->dev;
+		break;
+#endif
+#ifdef CONFIG_JOYSTICK_IFORCE_232
+	case IFORCE_232:
+		iforce->dev.id.bustype = BUS_RS232;
+		iforce->dev.dev = &iforce->serio->dev;
+		break;
+#endif
+	}
+
 	iforce->dev.private = iforce;
 	iforce->dev.name = "Unknown I-Force device";
 	iforce->dev.open = iforce_open;
diff -Nru a/drivers/input/joystick/magellan.c b/drivers/input/joystick/magellan.c
--- a/drivers/input/joystick/magellan.c	2005-03-01 23:38:51 -08:00
+++ b/drivers/input/joystick/magellan.c	2005-03-01 23:38:51 -08:00
@@ -183,6 +183,7 @@
 	magellan->dev.id.vendor = SERIO_MAGELLAN;
 	magellan->dev.id.product = 0x0001;
 	magellan->dev.id.version = 0x0100;
+	magellan->dev.dev = &serio->dev;
 
 	serio->private = magellan;
 
diff -Nru a/drivers/input/joystick/sidewinder.c b/drivers/input/joystick/sidewinder.c
--- a/drivers/input/joystick/sidewinder.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/input/joystick/sidewinder.c	2005-03-01 23:39:09 -08:00
@@ -45,7 +45,7 @@
  * as well as break everything.
  */
 
-#define SW_DEBUG
+/* #define SW_DEBUG */
 
 #define SW_START	400	/* The time we wait for the first bit [400 us] */
 #define SW_STROBE	45	/* Max time per bit [45 us] */
diff -Nru a/drivers/input/joystick/spaceball.c b/drivers/input/joystick/spaceball.c
--- a/drivers/input/joystick/spaceball.c	2005-03-01 23:38:51 -08:00
+++ b/drivers/input/joystick/spaceball.c	2005-03-01 23:38:51 -08:00
@@ -253,6 +253,7 @@
 	spaceball->dev.id.vendor = SERIO_SPACEBALL;
 	spaceball->dev.id.product = id;
 	spaceball->dev.id.version = 0x0100;
+	spaceball->dev.dev = &serio->dev;
 
 	serio->private = spaceball;
 
diff -Nru a/drivers/input/joystick/spaceorb.c b/drivers/input/joystick/spaceorb.c
--- a/drivers/input/joystick/spaceorb.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/input/joystick/spaceorb.c	2005-03-01 23:38:56 -08:00
@@ -200,6 +200,7 @@
 	spaceorb->dev.id.vendor = SERIO_SPACEORB;
 	spaceorb->dev.id.product = 0x0001;
 	spaceorb->dev.id.version = 0x0100;
+	spaceorb->dev.dev = &serio->dev;
 
 	serio->private = spaceorb;
 
diff -Nru a/drivers/input/joystick/stinger.c b/drivers/input/joystick/stinger.c
--- a/drivers/input/joystick/stinger.c	2005-03-01 23:38:44 -08:00
+++ b/drivers/input/joystick/stinger.c	2005-03-01 23:38:44 -08:00
@@ -164,6 +164,7 @@
 	stinger->dev.id.vendor = SERIO_STINGER;
 	stinger->dev.id.product = 0x0001;
 	stinger->dev.id.version = 0x0100;
+	stinger->dev.dev = &serio->dev;
 
 	for (i = 0; i < 2; i++) {
 		stinger->dev.absmax[ABS_X+i] =  64;
diff -Nru a/drivers/input/joystick/twidjoy.c b/drivers/input/joystick/twidjoy.c
--- a/drivers/input/joystick/twidjoy.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/input/joystick/twidjoy.c	2005-03-01 23:38:52 -08:00
@@ -210,6 +210,7 @@
 	twidjoy->dev.id.vendor = SERIO_TWIDJOY;
 	twidjoy->dev.id.product = 0x0001;
 	twidjoy->dev.id.version = 0x0100;
+	twidjoy->dev.dev = &serio->dev;
 
 	twidjoy->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
 
diff -Nru a/drivers/input/joystick/warrior.c b/drivers/input/joystick/warrior.c
--- a/drivers/input/joystick/warrior.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/input/joystick/warrior.c	2005-03-01 23:39:07 -08:00
@@ -168,6 +168,7 @@
 	warrior->dev.id.vendor = SERIO_WARRIOR;
 	warrior->dev.id.product = 0x0001;
 	warrior->dev.id.version = 0x0100;
+	warrior->dev.dev = &serio->dev;
 
 	for (i = 0; i < 2; i++) {
 		warrior->dev.absmax[ABS_X+i] = -64;
diff -Nru a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
--- a/drivers/input/keyboard/Kconfig	2005-03-01 23:39:16 -08:00
+++ b/drivers/input/keyboard/Kconfig	2005-03-01 23:39:16 -08:00
@@ -16,6 +16,7 @@
 	default y
 	depends on INPUT && INPUT_KEYBOARD
 	select SERIO
+	select SERIO_LIBPS2
 	select SERIO_I8042 if PC
 	select SERIO_GSCPS2 if GSC
 	help
diff -Nru a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
--- a/drivers/input/keyboard/atkbd.c	2005-03-01 23:39:19 -08:00
+++ b/drivers/input/keyboard/atkbd.c	2005-03-01 23:39:19 -08:00
@@ -26,6 +26,7 @@
 #include <linux/input.h>
 #include <linux/serio.h>
 #include <linux/workqueue.h>
+#include <linux/libps2.h>
 
 #define DRIVER_DESC	"AT and PS/2 keyboard driver"
 
@@ -170,36 +171,29 @@
 	{ ATKBD_SCR_CLICK, 0x60 },
 };
 
-#define ATKBD_FLAG_ACK		0	/* Waiting for ACK/NAK */
-#define ATKBD_FLAG_CMD		1	/* Waiting for command to finish */
-#define ATKBD_FLAG_CMD1		2	/* First byte of command response */
-#define ATKBD_FLAG_ENABLED	3	/* Waining for init to finish */
-
 /*
  * The atkbd control structure
  */
 
 struct atkbd {
 
+	struct ps2dev	ps2dev;
+
 	/* Written only during init */
 	char name[64];
 	char phys[32];
-	struct serio *serio;
 	struct input_dev dev;
 
-	unsigned char set;
 	unsigned short id;
 	unsigned char keycode[512];
+	unsigned char set;
 	unsigned char translated;
 	unsigned char extra;
 	unsigned char write;
-
-	/* Protected by FLAG_ACK */
-	unsigned char nak;
-
-	/* Protected by FLAG_CMD */
-	unsigned char cmdbuf[4];
-	unsigned char cmdcnt;
+	unsigned char softrepeat;
+	unsigned char softraw;
+	unsigned char scroll;
+	unsigned char enabled;
 
 	/* Accessed only from interrupt */
 	unsigned char emul;
@@ -208,24 +202,31 @@
 	unsigned char bat_xl;
 	unsigned int last;
 	unsigned long time;
-
-	/* Ensures that only one command is executing at a time */
-	struct semaphore cmd_sem;
-
-	/* Used to signal completion from interrupt handler */
-	wait_queue_head_t wait;
-
-	/* Flags */
-	unsigned long flags;
 };
 
-/* Work structure to schedule execution of a command */
-struct atkbd_work {
-	struct work_struct work;
-	struct atkbd *atkbd;
-	int command;
-	unsigned char param[0];
-};
+static ssize_t atkbd_attr_show_helper(struct device *dev, char *buf,
+				ssize_t (*handler)(struct atkbd *, char *));
+static ssize_t atkbd_attr_set_helper(struct device *dev, const char *buf, size_t count,
+				ssize_t (*handler)(struct atkbd *, const char *, size_t));
+#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)			\
+{										\
+	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)	\
+{										\
+	return atkbd_attr_set_helper(d, b, s, atkbd_set_##_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);
+ATKBD_DEFINE_ATTR(scroll);
+ATKBD_DEFINE_ATTR(set);
+ATKBD_DEFINE_ATTR(softrepeat);
+ATKBD_DEFINE_ATTR(softraw);
 
 
 static void atkbd_report_key(struct input_dev *dev, struct pt_regs *regs, int code, int value)
@@ -233,6 +234,7 @@
 	input_regs(dev, regs);
 	if (value == 3) {
 		input_report_key(dev, code, 1);
+		input_sync(dev);
 		input_report_key(dev, code, 0);
 	} else
 		input_event(dev, EV_KEY, code, value);
@@ -268,42 +270,15 @@
 		atkbd->resend = 0;
 #endif
 
-	if (test_bit(ATKBD_FLAG_ACK, &atkbd->flags)) {
-		switch (code) {
-			case ATKBD_RET_ACK:
-				atkbd->nak = 0;
-				if (atkbd->cmdcnt) {
-					set_bit(ATKBD_FLAG_CMD, &atkbd->flags);
-					set_bit(ATKBD_FLAG_CMD1, &atkbd->flags);
-				}
-				clear_bit(ATKBD_FLAG_ACK, &atkbd->flags);
-				wake_up_interruptible(&atkbd->wait);
-				break;
-			case ATKBD_RET_NAK:
-				atkbd->nak = 1;
-				clear_bit(ATKBD_FLAG_ACK, &atkbd->flags);
-				wake_up_interruptible(&atkbd->wait);
-				break;
-		}
-		goto out;
-	}
-
-	if (test_bit(ATKBD_FLAG_CMD, &atkbd->flags)) {
-
-		if (atkbd->cmdcnt)
-			atkbd->cmdbuf[--atkbd->cmdcnt] = code;
-
-		if (test_and_clear_bit(ATKBD_FLAG_CMD1, &atkbd->flags) && atkbd->cmdcnt)
-			wake_up_interruptible(&atkbd->wait);
+	if (unlikely(atkbd->ps2dev.flags & PS2_FLAG_ACK))
+		if  (ps2_handle_ack(&atkbd->ps2dev, data))
+			goto out;
 
-		if (!atkbd->cmdcnt) {
-			clear_bit(ATKBD_FLAG_CMD, &atkbd->flags);
-			wake_up_interruptible(&atkbd->wait);
-		}
-		goto out;
-	}
+	if (unlikely(atkbd->ps2dev.flags & PS2_FLAG_CMD))
+		if  (ps2_handle_response(&atkbd->ps2dev, data))
+			goto out;
 
-	if (!test_bit(ATKBD_FLAG_ENABLED, &atkbd->flags))
+	if (!atkbd->enabled)
 		goto out;
 
 	input_event(&atkbd->dev, EV_MSC, MSC_RAW, code);
@@ -326,8 +301,8 @@
 
 	switch (code) {
 		case ATKBD_RET_BAT:
-			clear_bit(ATKBD_FLAG_ENABLED, &atkbd->flags);
-			serio_rescan(atkbd->serio);
+			atkbd->enabled = 0;
+			serio_rescan(atkbd->ps2dev.serio);
 			goto out;
 		case ATKBD_RET_EMUL0:
 			atkbd->emul = 1;
@@ -378,6 +353,7 @@
 				       "to make it known.\n",
 				       code & 0x80 ? "e0" : "", code & 0x7f);
 			}
+			input_sync(&atkbd->dev);
 			break;
 		case ATKBD_SCR_1:
 			scroll = 1 - atkbd->release * 2;
@@ -396,7 +372,7 @@
 			break;
 		default:
 			value = atkbd->release ? 0 :
-				(1 + (!atkbd_softrepeat && test_bit(atkbd->keycode[code], atkbd->dev.key)));
+				(1 + (!atkbd->softrepeat && test_bit(atkbd->keycode[code], atkbd->dev.key)));
 
 			switch (value) { 	/* Workaround Toshiba laptop multiple keypress */
 				case 0:
@@ -427,151 +403,6 @@
 	return IRQ_HANDLED;
 }
 
-/*
- * atkbd_sendbyte() sends a byte to the keyboard, and waits for
- * acknowledge. It doesn't handle resends according to the keyboard
- * protocol specs, because if these are needed, the keyboard needs
- * replacement anyway, and they only make a mess in the protocol.
- *
- * atkbd_sendbyte() can only be called from a process context
- */
-
-static int atkbd_sendbyte(struct atkbd *atkbd, unsigned char byte)
-{
-#ifdef ATKBD_DEBUG
-	printk(KERN_DEBUG "atkbd.c: Sent: %02x\n", byte);
-#endif
-	atkbd->nak = 1;
-	set_bit(ATKBD_FLAG_ACK, &atkbd->flags);
-
-	if (serio_write(atkbd->serio, byte) == 0)
-		wait_event_interruptible_timeout(atkbd->wait,
-				!test_bit(ATKBD_FLAG_ACK, &atkbd->flags),
-				msecs_to_jiffies(200));
-
-	clear_bit(ATKBD_FLAG_ACK, &atkbd->flags);
-	return -atkbd->nak;
-}
-
-/*
- * atkbd_command() sends a command, and its parameters to the keyboard,
- * then waits for the response and puts it in the param array.
- *
- * atkbd_command() can only be called from a process context
- */
-
-static int atkbd_command(struct atkbd *atkbd, unsigned char *param, int command)
-{
-	int timeout;
-	int send = (command >> 12) & 0xf;
-	int receive = (command >> 8) & 0xf;
-	int rc = -1;
-	int i;
-
-	timeout = msecs_to_jiffies(command == ATKBD_CMD_RESET_BAT ? 4000 : 500);
-
-	down(&atkbd->cmd_sem);
-	clear_bit(ATKBD_FLAG_CMD, &atkbd->flags);
-
-	if (receive && param)
-		for (i = 0; i < receive; i++)
-			atkbd->cmdbuf[(receive - 1) - i] = param[i];
-
-	atkbd->cmdcnt = receive;
-
-	if (command & 0xff)
-		if (atkbd_sendbyte(atkbd, command & 0xff))
-			goto out;
-
-	for (i = 0; i < send; i++)
-		if (atkbd_sendbyte(atkbd, param[i]))
-			goto out;
-
-	timeout = wait_event_interruptible_timeout(atkbd->wait,
-				!test_bit(ATKBD_FLAG_CMD1, &atkbd->flags), timeout);
-
-	if (atkbd->cmdcnt && timeout > 0) {
-		if (command == ATKBD_CMD_RESET_BAT && jiffies_to_msecs(timeout) > 100)
-			timeout = msecs_to_jiffies(100);
-
-		if (command == ATKBD_CMD_GETID &&
-		    atkbd->cmdbuf[receive - 1] != 0xab && atkbd->cmdbuf[receive - 1] != 0xac) {
-			/*
-			 * Device behind the port is not a keyboard
-			 * so we don't need to wait for the 2nd byte
-			 * of ID response.
-			 */
-			clear_bit(ATKBD_FLAG_CMD, &atkbd->flags);
-			atkbd->cmdcnt = 0;
-		}
-
-		wait_event_interruptible_timeout(atkbd->wait,
-				!test_bit(ATKBD_FLAG_CMD, &atkbd->flags), timeout);
-	}
-
-	if (param)
-		for (i = 0; i < receive; i++)
-			param[i] = atkbd->cmdbuf[(receive - 1) - i];
-
-	if (atkbd->cmdcnt && (command != ATKBD_CMD_RESET_BAT || atkbd->cmdcnt != 1))
-		goto out;
-
-	rc = 0;
-
-out:
-	clear_bit(ATKBD_FLAG_CMD, &atkbd->flags);
-	clear_bit(ATKBD_FLAG_CMD1, &atkbd->flags);
-	up(&atkbd->cmd_sem);
-
-	return rc;
-}
-
-/*
- * atkbd_execute_scheduled_command() sends a command, previously scheduled by
- * atkbd_schedule_command(), to the keyboard.
- */
-
-static void atkbd_execute_scheduled_command(void *data)
-{
-	struct atkbd_work *atkbd_work = data;
-
-	atkbd_command(atkbd_work->atkbd, atkbd_work->param, atkbd_work->command);
-
-	kfree(atkbd_work);
-}
-
-/*
- * atkbd_schedule_command() allows to schedule delayed execution of a keyboard
- * command and can be used to issue a command from an interrupt or softirq
- * context.
- */
-
-static int atkbd_schedule_command(struct atkbd *atkbd, unsigned char *param, int command)
-{
-	struct atkbd_work *atkbd_work;
-	int send = (command >> 12) & 0xf;
-	int receive = (command >> 8) & 0xf;
-
-	if (!test_bit(ATKBD_FLAG_ENABLED, &atkbd->flags))
-		return -1;
-
-	if (!(atkbd_work = kmalloc(sizeof(struct atkbd_work) + max(send, receive), GFP_ATOMIC)))
-		return -1;
-
-	memset(atkbd_work, 0, sizeof(struct atkbd_work));
-	atkbd_work->atkbd = atkbd;
-	atkbd_work->command = command;
-	memcpy(atkbd_work->param, param, send);
-	INIT_WORK(&atkbd_work->work, atkbd_execute_scheduled_command, atkbd_work);
-
-	if (!schedule_work(&atkbd_work->work)) {
-		kfree(atkbd_work);
-		return -1;
-	}
-
-	return 0;
-}
-
 
 /*
  * Event callback from the input module. Events that change the state of
@@ -599,7 +430,7 @@
 			param[0] = (test_bit(LED_SCROLLL, dev->led) ? 1 : 0)
 			         | (test_bit(LED_NUML,    dev->led) ? 2 : 0)
 			         | (test_bit(LED_CAPSL,   dev->led) ? 4 : 0);
-		        atkbd_schedule_command(atkbd, param, ATKBD_CMD_SETLEDS);
+		        ps2_schedule_command(&atkbd->ps2dev, param, ATKBD_CMD_SETLEDS);
 
 			if (atkbd->extra) {
 				param[0] = 0;
@@ -608,7 +439,7 @@
 					 | (test_bit(LED_SUSPEND, dev->led) ? 0x04 : 0)
 				         | (test_bit(LED_MISC,    dev->led) ? 0x10 : 0)
 				         | (test_bit(LED_MUTE,    dev->led) ? 0x20 : 0);
-				atkbd_schedule_command(atkbd, param, ATKBD_CMD_EX_SETLEDS);
+				ps2_schedule_command(&atkbd->ps2dev, param, ATKBD_CMD_EX_SETLEDS);
 			}
 
 			return 0;
@@ -616,7 +447,7 @@
 
 		case EV_REP:
 
-			if (atkbd_softrepeat) return 0;
+			if (atkbd->softrepeat) return 0;
 
 			i = j = 0;
 			while (i < 32 && period[i] < dev->rep[REP_PERIOD]) i++;
@@ -624,7 +455,7 @@
 			dev->rep[REP_PERIOD] = period[i];
 			dev->rep[REP_DELAY] = delay[j];
 			param[0] = i | (j << 5);
-			atkbd_schedule_command(atkbd, param, ATKBD_CMD_SETREP);
+			ps2_schedule_command(&atkbd->ps2dev, param, ATKBD_CMD_SETREP);
 
 			return 0;
 	}
@@ -633,11 +464,36 @@
 }
 
 /*
+ * atkbd_enable() signals that interrupt handler is allowed to
+ * generate input events.
+ */
+
+static inline void atkbd_enable(struct atkbd *atkbd)
+{
+	serio_pause_rx(atkbd->ps2dev.serio);
+	atkbd->enabled = 1;
+	serio_continue_rx(atkbd->ps2dev.serio);
+}
+
+/*
+ * atkbd_disable() tells input handler that all incoming data except
+ * for ACKs and command response should be dropped.
+ */
+
+static inline void atkbd_disable(struct atkbd *atkbd)
+{
+	serio_pause_rx(atkbd->ps2dev.serio);
+	atkbd->enabled = 0;
+	serio_continue_rx(atkbd->ps2dev.serio);
+}
+
+/*
  * atkbd_probe() probes for an AT keyboard on a serio port.
  */
 
 static int atkbd_probe(struct atkbd *atkbd)
 {
+	struct ps2dev *ps2dev = &atkbd->ps2dev;
 	unsigned char param[2];
 
 /*
@@ -647,8 +503,8 @@
  */
 
 	if (atkbd_reset)
-		if (atkbd_command(atkbd, NULL, ATKBD_CMD_RESET_BAT))
-			printk(KERN_WARNING "atkbd.c: keyboard reset failed on %s\n", atkbd->serio->phys);
+		if (ps2_command(ps2dev, NULL, ATKBD_CMD_RESET_BAT))
+			printk(KERN_WARNING "atkbd.c: keyboard reset failed on %s\n", ps2dev->serio->phys);
 
 /*
  * Then we check the keyboard ID. We should get 0xab83 under normal conditions.
@@ -658,7 +514,7 @@
  */
 
 	param[0] = param[1] = 0xa5;	/* initialize with invalid values */
-	if (atkbd_command(atkbd, param, ATKBD_CMD_GETID)) {
+	if (ps2_command(ps2dev, param, ATKBD_CMD_GETID)) {
 
 /*
  * If the get ID command failed, we check if we can at least set the LEDs on
@@ -666,14 +522,17 @@
  * the LEDs off, which we want anyway.
  */
 		param[0] = 0;
-		if (atkbd_command(atkbd, param, ATKBD_CMD_SETLEDS))
+		if (ps2_command(ps2dev, param, ATKBD_CMD_SETLEDS))
 			return -1;
 		atkbd->id = 0xabba;
 		return 0;
 	}
 
-	if (param[0] != 0xab && param[0] != 0xac)
+	if (param[0] != 0xab && param[0] != 0xac &&	/* Regular and NCD Sun keyboards */
+	    param[0] != 0x2b && param[0] != 0x5d &&	/* Trust keyboard, raw and translated */
+	    param[0] != 0x60 && param[0] != 0x47)	/* NMB SGI keyboard, raw and translated */
 		return -1;
+
 	atkbd->id = (param[0] << 8) | param[1];
 
 	if (atkbd->id == 0xaca1 && atkbd->translated) {
@@ -686,15 +545,17 @@
 }
 
 /*
- * atkbd_set_3 checks if a keyboard has a working Set 3 support, and
+ * atkbd_select_set checks if a keyboard has a working Set 3 support, and
  * sets it into that. Unfortunately there are keyboards that can be switched
  * to Set 3, but don't work well in that (BTC Multimedia ...)
  */
 
-static int atkbd_set_3(struct atkbd *atkbd)
+static int atkbd_select_set(struct atkbd *atkbd, int target_set, int allow_extra)
 {
+	struct ps2dev *ps2dev = &atkbd->ps2dev;
 	unsigned char param[2];
 
+	atkbd->extra = 0;
 /*
  * For known special keyboards we can go ahead and set the correct set.
  * We check for NCD PS/2 Sun, NorthGate OmniKey 101 and
@@ -706,47 +567,48 @@
 
 	if (atkbd->id == 0xaca1) {
 		param[0] = 3;
-		atkbd_command(atkbd, param, ATKBD_CMD_SSCANSET);
+		ps2_command(ps2dev, param, ATKBD_CMD_SSCANSET);
 		return 3;
 	}
 
-	if (atkbd_extra) {
+	if (allow_extra) {
 		param[0] = 0x71;
-		if (!atkbd_command(atkbd, param, ATKBD_CMD_EX_ENABLE)) {
+		if (!ps2_command(ps2dev, param, ATKBD_CMD_EX_ENABLE)) {
 			atkbd->extra = 1;
 			return 2;
 		}
 	}
 
-	if (atkbd_set != 3)
+	if (target_set != 3)
 		return 2;
 
-	if (!atkbd_command(atkbd, param, ATKBD_CMD_OK_GETID)) {
+	if (!ps2_command(ps2dev, param, ATKBD_CMD_OK_GETID)) {
 		atkbd->id = param[0] << 8 | param[1];
 		return 2;
 	}
 
 	param[0] = 3;
-	if (atkbd_command(atkbd, param, ATKBD_CMD_SSCANSET))
+	if (ps2_command(ps2dev, param, ATKBD_CMD_SSCANSET))
 		return 2;
 
 	param[0] = 0;
-	if (atkbd_command(atkbd, param, ATKBD_CMD_GSCANSET))
+	if (ps2_command(ps2dev, param, ATKBD_CMD_GSCANSET))
 		return 2;
 
 	if (param[0] != 3) {
 		param[0] = 2;
-		if (atkbd_command(atkbd, param, ATKBD_CMD_SSCANSET))
+		if (ps2_command(ps2dev, param, ATKBD_CMD_SSCANSET))
 		return 2;
 	}
 
-	atkbd_command(atkbd, param, ATKBD_CMD_SETALL_MBR);
+	ps2_command(ps2dev, param, ATKBD_CMD_SETALL_MBR);
 
 	return 3;
 }
 
-static int atkbd_enable(struct atkbd *atkbd)
+static int atkbd_activate(struct atkbd *atkbd)
 {
+	struct ps2dev *ps2dev = &atkbd->ps2dev;
 	unsigned char param[1];
 
 /*
@@ -754,7 +616,7 @@
  */
 
 	param[0] = 0;
-	if (atkbd_command(atkbd, param, ATKBD_CMD_SETLEDS))
+	if (ps2_command(ps2dev, param, ATKBD_CMD_SETLEDS))
 		return -1;
 
 /*
@@ -762,16 +624,16 @@
  */
 
 	param[0] = 0;
-	if (atkbd_command(atkbd, param, ATKBD_CMD_SETREP))
+	if (ps2_command(ps2dev, param, ATKBD_CMD_SETREP))
 		return -1;
 
 /*
  * Enable the keyboard to receive keystrokes.
  */
 
-	if (atkbd_command(atkbd, NULL, ATKBD_CMD_ENABLE)) {
+	if (ps2_command(ps2dev, NULL, ATKBD_CMD_ENABLE)) {
 		printk(KERN_ERR "atkbd.c: Failed to enable keyboard on %s\n",
-			atkbd->serio->phys);
+			ps2dev->serio->phys);
 		return -1;
 	}
 
@@ -786,9 +648,10 @@
 static void atkbd_cleanup(struct serio *serio)
 {
 	struct atkbd *atkbd = serio->private;
-	atkbd_command(atkbd, NULL, ATKBD_CMD_RESET_BAT);
+	ps2_command(&atkbd->ps2dev, NULL, ATKBD_CMD_RESET_BAT);
 }
 
+
 /*
  * atkbd_disconnect() closes and frees.
  */
@@ -797,15 +660,113 @@
 {
 	struct atkbd *atkbd = serio->private;
 
-	clear_bit(ATKBD_FLAG_ENABLED, &atkbd->flags);
+	atkbd_disable(atkbd);
+
+	/* make sure we don't have a command in flight */
 	synchronize_kernel();
 	flush_scheduled_work();
 
+	device_remove_file(&serio->dev, &atkbd_attr_extra);
+	device_remove_file(&serio->dev, &atkbd_attr_scroll);
+	device_remove_file(&serio->dev, &atkbd_attr_set);
+	device_remove_file(&serio->dev, &atkbd_attr_softrepeat);
+	device_remove_file(&serio->dev, &atkbd_attr_softraw);
+
 	input_unregister_device(&atkbd->dev);
 	serio_close(serio);
 	kfree(atkbd);
 }
 
+
+/*
+ * atkbd_set_device_attrs() initializes keyboard's keycode table
+ * according to the selected scancode set
+ */
+
+static void atkbd_set_keycode_table(struct atkbd *atkbd)
+{
+	int i, j;
+
+	memset(atkbd->keycode, 0, sizeof(atkbd->keycode));
+
+	if (atkbd->translated) {
+		for (i = 0; i < 128; i++) {
+			atkbd->keycode[i] = atkbd_set2_keycode[atkbd_unxlate_table[i]];
+			atkbd->keycode[i | 0x80] = atkbd_set2_keycode[atkbd_unxlate_table[i] | 0x80];
+			if (atkbd->scroll)
+				for (j = 0; i < 5; i++) {
+					if (atkbd_unxlate_table[i] == atkbd_scroll_keys[j][1])
+						atkbd->keycode[i] = atkbd_scroll_keys[j][0];
+					if ((atkbd_unxlate_table[i] | 0x80) == atkbd_scroll_keys[j][1])
+						atkbd->keycode[i | 0x80] = atkbd_scroll_keys[j][0];
+				}
+		}
+	} else if (atkbd->set == 3) {
+		memcpy(atkbd->keycode, atkbd_set3_keycode, sizeof(atkbd->keycode));
+	} else {
+		memcpy(atkbd->keycode, atkbd_set2_keycode, sizeof(atkbd->keycode));
+
+		if (atkbd->scroll)
+			for (i = 0; i < 5; i++)
+				atkbd->keycode[atkbd_scroll_keys[i][1]] = atkbd_scroll_keys[i][0];
+	}
+}
+
+/*
+ * atkbd_set_device_attrs() sets up keyboard's input device structure
+ */
+
+static void atkbd_set_device_attrs(struct atkbd *atkbd)
+{
+	int i;
+
+	memset(&atkbd->dev, 0, sizeof(struct input_dev));
+
+	init_input_dev(&atkbd->dev);
+
+	atkbd->dev.name = atkbd->name;
+	atkbd->dev.phys = atkbd->phys;
+	atkbd->dev.id.bustype = BUS_I8042;
+	atkbd->dev.id.vendor = 0x0001;
+	atkbd->dev.id.product = atkbd->translated ? 1 : atkbd->set;
+	atkbd->dev.id.version = atkbd->id;
+	atkbd->dev.event = atkbd_event;
+	atkbd->dev.private = atkbd;
+	atkbd->dev.dev = &atkbd->ps2dev.serio->dev;
+
+	atkbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_MSC);
+
+	if (atkbd->write) {
+		atkbd->dev.evbit[0] |= BIT(EV_LED);
+		atkbd->dev.ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL);
+	}
+
+	if (atkbd->extra)
+		atkbd->dev.ledbit[0] |= BIT(LED_COMPOSE) | BIT(LED_SUSPEND) |
+					BIT(LED_SLEEP) | BIT(LED_MUTE) | BIT(LED_MISC);
+
+	if (!atkbd->softrepeat) {
+		atkbd->dev.rep[REP_DELAY] = 250;
+		atkbd->dev.rep[REP_PERIOD] = 33;
+	}
+
+	atkbd->dev.mscbit[0] = atkbd->softraw ? BIT(MSC_SCAN) : BIT(MSC_RAW) | BIT(MSC_SCAN);
+
+	if (atkbd->scroll) {
+		atkbd->dev.evbit[0] |= BIT(EV_REL);
+		atkbd->dev.relbit[0] = BIT(REL_WHEEL);
+		set_bit(BTN_MIDDLE, atkbd->dev.keybit);
+	}
+
+	atkbd->dev.keycode = atkbd->keycode;
+	atkbd->dev.keycodesize = sizeof(unsigned char);
+	atkbd->dev.keycodemax = ARRAY_SIZE(atkbd_set2_keycode);
+
+	for (i = 0; i < 512; i++)
+		if (atkbd->keycode[i] && atkbd->keycode[i] < ATKBD_SPECIAL)
+			set_bit(atkbd->keycode[i], atkbd->dev.keybit);
+}
+
 /*
  * atkbd_connect() is called when the serio module finds and interface
  * that isn't handled yet by an appropriate device driver. We check if
@@ -816,14 +777,12 @@
 static void atkbd_connect(struct serio *serio, struct serio_driver *drv)
 {
 	struct atkbd *atkbd;
-	int i;
 
 	if (!(atkbd = kmalloc(sizeof(struct atkbd), GFP_KERNEL)))
 		return;
 	memset(atkbd, 0, sizeof(struct atkbd));
 
-	init_MUTEX(&atkbd->cmd_sem);
-	init_waitqueue_head(&atkbd->wait);
+	ps2_init(&atkbd->ps2dev, serio);
 
 	switch (serio->type & SERIO_TYPE) {
 
@@ -841,31 +800,15 @@
 			return;
 	}
 
-	if (!atkbd->write)
-		atkbd_softrepeat = 1;
-	if (atkbd_softrepeat)
-		atkbd_softraw = 1;
+	atkbd->softraw = atkbd_softraw;
+	atkbd->softrepeat = atkbd_softrepeat;
+	atkbd->scroll = atkbd_scroll;
 
-	if (atkbd->write) {
-		atkbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_REP) | BIT(EV_MSC);
-		atkbd->dev.ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL);
-	} else  atkbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_MSC);
-	atkbd->dev.mscbit[0] = atkbd_softraw ? BIT(MSC_SCAN) : BIT(MSC_RAW) | BIT(MSC_SCAN);
-
-	if (!atkbd_softrepeat) {
-		atkbd->dev.rep[REP_DELAY] = 250;
-		atkbd->dev.rep[REP_PERIOD] = 33;
-	} else atkbd_softraw = 1;
-
-	atkbd->serio = serio;
-
-	init_input_dev(&atkbd->dev);
+	if (!atkbd->write)
+		atkbd->softrepeat = 1;
 
-	atkbd->dev.keycode = atkbd->keycode;
-	atkbd->dev.keycodesize = sizeof(unsigned char);
-	atkbd->dev.keycodemax = ARRAY_SIZE(atkbd_set2_keycode);
-	atkbd->dev.event = atkbd_event;
-	atkbd->dev.private = atkbd;
+	if (atkbd->softrepeat)
+		atkbd->softraw = 1;
 
 	serio->private = atkbd;
 
@@ -883,56 +826,34 @@
 			return;
 		}
 
-		atkbd->set = atkbd_set_3(atkbd);
-		atkbd_enable(atkbd);
+		atkbd->set = atkbd_select_set(atkbd, atkbd_set, atkbd_extra);
+		atkbd_activate(atkbd);
 
 	} else {
 		atkbd->set = 2;
 		atkbd->id = 0xab00;
 	}
 
-	if (atkbd->extra) {
-		atkbd->dev.ledbit[0] |= BIT(LED_COMPOSE) | BIT(LED_SUSPEND) | BIT(LED_SLEEP) | BIT(LED_MUTE) | BIT(LED_MISC);
+	if (atkbd->extra)
 		sprintf(atkbd->name, "AT Set 2 Extra keyboard");
-	} else
+	else
 		sprintf(atkbd->name, "AT %s Set %d keyboard",
 			atkbd->translated ? "Translated" : "Raw", atkbd->set);
 
 	sprintf(atkbd->phys, "%s/input0", serio->phys);
 
-	if (atkbd_scroll) {
-		for (i = 0; i < 5; i++)
-			atkbd_set2_keycode[atkbd_scroll_keys[i][1]] = atkbd_scroll_keys[i][0];
-		atkbd->dev.evbit[0] |= BIT(EV_REL);
-		atkbd->dev.relbit[0] = BIT(REL_WHEEL);
-		set_bit(BTN_MIDDLE, atkbd->dev.keybit);
-	}
-
-	if (atkbd->translated) {
-		for (i = 0; i < 128; i++) {
-			atkbd->keycode[i] = atkbd_set2_keycode[atkbd_unxlate_table[i]];
-			atkbd->keycode[i | 0x80] = atkbd_set2_keycode[atkbd_unxlate_table[i] | 0x80];
-		}
-	} else if (atkbd->set == 3) {
-		memcpy(atkbd->keycode, atkbd_set3_keycode, sizeof(atkbd->keycode));
-	} else {
-		memcpy(atkbd->keycode, atkbd_set2_keycode, sizeof(atkbd->keycode));
-	}
-
-	atkbd->dev.name = atkbd->name;
-	atkbd->dev.phys = atkbd->phys;
-	atkbd->dev.id.bustype = BUS_I8042;
-	atkbd->dev.id.vendor = 0x0001;
-	atkbd->dev.id.product = atkbd->translated ? 1 : atkbd->set;
-	atkbd->dev.id.version = atkbd->id;
-
-	for (i = 0; i < 512; i++)
-		if (atkbd->keycode[i] && atkbd->keycode[i] < ATKBD_SPECIAL)
-			set_bit(atkbd->keycode[i], atkbd->dev.keybit);
+	atkbd_set_keycode_table(atkbd);
+	atkbd_set_device_attrs(atkbd);
 
 	input_register_device(&atkbd->dev);
 
-	set_bit(ATKBD_FLAG_ENABLED, &atkbd->flags);
+	device_create_file(&serio->dev, &atkbd_attr_extra);
+	device_create_file(&serio->dev, &atkbd_attr_scroll);
+	device_create_file(&serio->dev, &atkbd_attr_set);
+	device_create_file(&serio->dev, &atkbd_attr_softrepeat);
+	device_create_file(&serio->dev, &atkbd_attr_softraw);
+
+	atkbd_enable(atkbd);
 
 	printk(KERN_INFO "input: %s on %s\n", atkbd->name, serio->phys);
 }
@@ -948,11 +869,13 @@
 	struct serio_driver *drv = serio->drv;
 	unsigned char param[1];
 
-	if (!drv) {
+	if (!atkbd || !drv) {
 		printk(KERN_DEBUG "atkbd: reconnect request, but serio is disconnected, ignoring...\n");
 		return -1;
 	}
 
+	atkbd_disable(atkbd);
+
 	if (atkbd->write) {
 		param[0] = (test_bit(LED_SCROLLL, atkbd->dev.led) ? 1 : 0)
 		         | (test_bit(LED_NUML,    atkbd->dev.led) ? 2 : 0)
@@ -960,16 +883,16 @@
 
 		if (atkbd_probe(atkbd))
 			return -1;
-		if (atkbd->set != atkbd_set_3(atkbd))
+		if (atkbd->set != atkbd_select_set(atkbd, atkbd->set, atkbd->extra))
 			return -1;
 
-		atkbd_enable(atkbd);
+		atkbd_activate(atkbd);
 
-		if (atkbd_command(atkbd, param, ATKBD_CMD_SETLEDS))
+		if (ps2_command(&atkbd->ps2dev, param, ATKBD_CMD_SETLEDS))
 			return -1;
 	}
 
-	set_bit(ATKBD_FLAG_ENABLED, &atkbd->flags);
+	atkbd_enable(atkbd);
 
 	return 0;
 }
@@ -985,6 +908,192 @@
 	.disconnect	= atkbd_disconnect,
 	.cleanup	= atkbd_cleanup,
 };
+
+static ssize_t atkbd_attr_show_helper(struct device *dev, char *buf,
+				ssize_t (*handler)(struct atkbd *, char *))
+{
+	struct serio *serio = to_serio_port(dev);
+	int retval;
+
+	retval = serio_pin_driver(serio);
+	if (retval)
+		return retval;
+
+	if (serio->drv != &atkbd_drv) {
+		retval = -ENODEV;
+		goto out;
+	}
+
+	retval = handler((struct atkbd *)serio->private, buf);
+
+out:
+	serio_unpin_driver(serio);
+	return retval;
+}
+
+static ssize_t atkbd_attr_set_helper(struct device *dev, const char *buf, size_t count,
+				ssize_t (*handler)(struct atkbd *, const char *, size_t))
+{
+	struct serio *serio = to_serio_port(dev);
+	struct atkbd *atkbd;
+	int retval;
+
+	retval = serio_pin_driver(serio);
+	if (retval)
+		return retval;
+
+	if (serio->drv != &atkbd_drv) {
+		retval = -ENODEV;
+		goto out;
+	}
+
+	atkbd = serio->private;
+	atkbd_disable(atkbd);
+	retval = handler(atkbd, buf, count);
+	atkbd_enable(atkbd);
+
+out:
+	serio_unpin_driver(serio);
+	return retval;
+}
+
+static ssize_t atkbd_show_extra(struct atkbd *atkbd, char *buf)
+{
+	return sprintf(buf, "%d\n", atkbd->extra ? 1 : 0);
+}
+
+static ssize_t atkbd_set_extra(struct atkbd *atkbd, const char *buf, size_t count)
+{
+	unsigned long value;
+	char *rest;
+
+	if (!atkbd->write)
+		return -EIO;
+
+	value = simple_strtoul(buf, &rest, 10);
+	if (*rest || value > 1)
+		return -EINVAL;
+
+	if (atkbd->extra != value) {
+		/* unregister device as it's properties will change */
+		input_unregister_device(&atkbd->dev);
+		atkbd->set = atkbd_select_set(atkbd, atkbd->set, value);
+		atkbd_activate(atkbd);
+		atkbd_set_device_attrs(atkbd);
+		input_register_device(&atkbd->dev);
+	}
+	return count;
+}
+
+static ssize_t atkbd_show_scroll(struct atkbd *atkbd, char *buf)
+{
+	return sprintf(buf, "%d\n", atkbd->scroll ? 1 : 0);
+}
+
+static ssize_t atkbd_set_scroll(struct atkbd *atkbd, const char *buf, size_t count)
+{
+	unsigned long value;
+	char *rest;
+
+	value = simple_strtoul(buf, &rest, 10);
+	if (*rest || value > 1)
+		return -EINVAL;
+
+	if (atkbd->scroll != value) {
+		/* unregister device as it's properties will change */
+		input_unregister_device(&atkbd->dev);
+		atkbd->scroll = value;
+		atkbd_set_keycode_table(atkbd);
+		atkbd_set_device_attrs(atkbd);
+		input_register_device(&atkbd->dev);
+	}
+	return count;
+}
+
+static ssize_t atkbd_show_set(struct atkbd *atkbd, char *buf)
+{
+	return sprintf(buf, "%d\n", atkbd->set);
+}
+
+static ssize_t atkbd_set_set(struct atkbd *atkbd, const char *buf, size_t count)
+{
+	unsigned long value;
+	char *rest;
+
+	if (!atkbd->write)
+		return -EIO;
+
+	value = simple_strtoul(buf, &rest, 10);
+	if (*rest || (value != 2 && value != 3))
+		return -EINVAL;
+
+	if (atkbd->set != value) {
+		/* unregister device as it's properties will change */
+		input_unregister_device(&atkbd->dev);
+		atkbd->set = atkbd_select_set(atkbd, value, atkbd->extra);
+		atkbd_activate(atkbd);
+		atkbd_set_keycode_table(atkbd);
+		atkbd_set_device_attrs(atkbd);
+		input_register_device(&atkbd->dev);
+	}
+	return count;
+}
+
+static ssize_t atkbd_show_softrepeat(struct atkbd *atkbd, char *buf)
+{
+	return sprintf(buf, "%d\n", atkbd->softrepeat ? 1 : 0);
+}
+
+static ssize_t atkbd_set_softrepeat(struct atkbd *atkbd, const char *buf, size_t count)
+{
+	unsigned long value;
+	char *rest;
+
+	if (!atkbd->write)
+		return -EIO;
+
+	value = simple_strtoul(buf, &rest, 10);
+	if (*rest || value > 1)
+		return -EINVAL;
+
+	if (atkbd->softrepeat != value) {
+		/* unregister device as it's properties will change */
+		input_unregister_device(&atkbd->dev);
+		atkbd->softrepeat = value;
+		if (atkbd->softrepeat)
+			atkbd->softraw = 1;
+		atkbd_set_device_attrs(atkbd);
+		input_register_device(&atkbd->dev);
+	}
+
+	return count;
+}
+
+
+static ssize_t atkbd_show_softraw(struct atkbd *atkbd, char *buf)
+{
+	return sprintf(buf, "%d\n", atkbd->softraw ? 1 : 0);
+}
+
+static ssize_t atkbd_set_softraw(struct atkbd *atkbd, const char *buf, size_t count)
+{
+	unsigned long value;
+	char *rest;
+
+	value = simple_strtoul(buf, &rest, 10);
+	if (*rest || value > 1)
+		return -EINVAL;
+
+	if (atkbd->softraw != value) {
+		/* unregister device as it's properties will change */
+		input_unregister_device(&atkbd->dev);
+		atkbd->softraw = value;
+		atkbd_set_device_attrs(atkbd);
+		input_register_device(&atkbd->dev);
+	}
+	return count;
+}
+
 
 int __init atkbd_init(void)
 {
diff -Nru a/drivers/input/keyboard/lkkbd.c b/drivers/input/keyboard/lkkbd.c
--- a/drivers/input/keyboard/lkkbd.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/input/keyboard/lkkbd.c	2005-03-01 23:38:53 -08:00
@@ -14,13 +14,13 @@
  * DISCLAIMER: This works for _me_. If you break anything by using the
  * information given below, I will _not_ be liable!
  *
- * RJ11 pinout:		To DB9:		Or DB25:
+ * RJ11 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 DB9 or DB25!!!
+ * 	3 - +12V (from HDD drive connector), DON'T connect to DE9 or DB25!!!
  *
- * Pin numbers for DB9 and DB25 are noted on the plug (quite small:). For
+ * Pin numbers for DE9 and DB25 are noted on the plug (quite small:). For
  * RJ11, it's like this:
  *
  *      __=__	Hold the plug in front of you, cable downwards,
@@ -685,6 +685,7 @@
 	lk->dev.id.vendor = SERIO_LKKBD;
 	lk->dev.id.product = 0;
 	lk->dev.id.version = 0x0100;
+	lk->dev.dev = &serio->dev;
 
 	input_register_device (&lk->dev);
 
diff -Nru a/drivers/input/keyboard/newtonkbd.c b/drivers/input/keyboard/newtonkbd.c
--- a/drivers/input/keyboard/newtonkbd.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/input/keyboard/newtonkbd.c	2005-03-01 23:39:18 -08:00
@@ -126,6 +126,7 @@
 	nkbd->dev.id.vendor = SERIO_NEWTON;
 	nkbd->dev.id.product = 0x0001;
 	nkbd->dev.id.version = 0x0100;
+	nkbd->dev.dev = &serio->dev;
 
 	input_register_device(&nkbd->dev);
 
diff -Nru a/drivers/input/keyboard/sunkbd.c b/drivers/input/keyboard/sunkbd.c
--- a/drivers/input/keyboard/sunkbd.c	2005-03-01 23:38:44 -08:00
+++ b/drivers/input/keyboard/sunkbd.c	2005-03-01 23:38:44 -08:00
@@ -285,6 +285,7 @@
 	sunkbd->dev.id.vendor = SERIO_SUNKBD;
 	sunkbd->dev.id.product = sunkbd->type;
 	sunkbd->dev.id.version = 0x0100;
+	sunkbd->dev.dev = &serio->dev;
 
 	input_register_device(&sunkbd->dev);
 
diff -Nru a/drivers/input/keyboard/xtkbd.c b/drivers/input/keyboard/xtkbd.c
--- a/drivers/input/keyboard/xtkbd.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/input/keyboard/xtkbd.c	2005-03-01 23:38:58 -08:00
@@ -131,6 +131,7 @@
 	xtkbd->dev.id.vendor = 0x0001;
 	xtkbd->dev.id.product = 0x0001;
 	xtkbd->dev.id.version = 0x0100;
+	xtkbd->dev.dev = &serio->dev;
 
 	input_register_device(&xtkbd->dev);
 
diff -Nru a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
--- a/drivers/input/misc/Kconfig	2005-03-01 23:38:56 -08:00
+++ b/drivers/input/misc/Kconfig	2005-03-01 23:38:56 -08:00
@@ -5,7 +5,6 @@
 	bool "Misc"
 	depends on INPUT
 	help
-
 	  Say Y here, and a list of miscellaneous input drivers will be displayed.
 	  Everything that didn't fit into the other categories is here. This option
 	  doesn't affect the kernel.
diff -Nru a/drivers/input/misc/pcspkr.c b/drivers/input/misc/pcspkr.c
--- a/drivers/input/misc/pcspkr.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/input/misc/pcspkr.c	2005-03-01 23:38:58 -08:00
@@ -27,7 +27,7 @@
 static char pcspkr_phys[] = "isa0061/input0";
 static struct input_dev pcspkr_dev;
 
-spinlock_t i8253_beep_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(i8253_beep_lock);
 
 static int pcspkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
 {
diff -Nru a/drivers/input/misc/sparcspkr.c b/drivers/input/misc/sparcspkr.c
--- a/drivers/input/misc/sparcspkr.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/input/misc/sparcspkr.c	2005-03-01 23:39:17 -08:00
@@ -27,7 +27,7 @@
 static char *sparcspkr_phys = "sparc/input0";
 static struct input_dev sparcspkr_dev;
 
-spinlock_t beep_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(beep_lock);
 
 static void __init init_sparcspkr_struct(void)
 {
diff -Nru a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig
--- a/drivers/input/mouse/Kconfig	2005-03-01 23:39:09 -08:00
+++ b/drivers/input/mouse/Kconfig	2005-03-01 23:39:09 -08:00
@@ -16,6 +16,7 @@
 	default y
 	depends on INPUT && INPUT_MOUSE
 	select SERIO
+	select SERIO_LIBPS2
 	select SERIO_I8042 if PC
 	select SERIO_GSCPS2 if GSC
 	---help---
@@ -26,9 +27,9 @@
 
 	  Synaptics TouchPad users might be interested in a specialized
 	  XFree86 driver at:
-		http://w1.894.telia.com/~u89404340/touchpad/index.html
-	  and a new verion of GPM at:
-		http://www.geocities.com/dt_or/gpm/gpm.html
+		<http://w1.894.telia.com/~u89404340/touchpad/index.html>
+	  and a new version of GPM at:
+		<http://www.geocities.com/dt_or/gpm/gpm.html>
 	  to take advantage of the advanced features of the touchpad.
 
 	  If unsure, say Y.
diff -Nru a/drivers/input/mouse/Makefile b/drivers/input/mouse/Makefile
--- a/drivers/input/mouse/Makefile	2005-03-01 23:38:53 -08:00
+++ b/drivers/input/mouse/Makefile	2005-03-01 23:38:53 -08:00
@@ -14,4 +14,4 @@
 obj-$(CONFIG_MOUSE_SERIAL)	+= sermouse.o
 obj-$(CONFIG_MOUSE_VSXXXAA)	+= vsxxxaa.o
 
-psmouse-objs  := psmouse-base.o logips2pp.o synaptics.o
+psmouse-objs  := psmouse-base.o alps.o logips2pp.o synaptics.o
diff -Nru a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/input/mouse/alps.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,424 @@
+/*
+ * 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) 2004 Dmitry Torokhov <dtor@mail.ru>
+ *
+ * ALPS detection, tap switching and status querying info is taken from
+ * tpconfig utility (by C. Scott Ananian and Bruce Kall).
+ *
+ * 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 "psmouse.h"
+#include "alps.h"
+
+#undef DEBUG
+#ifdef DEBUG
+#define dbg(format, arg...) printk(KERN_INFO "alps.c: " format "\n", ## arg)
+#else
+#define dbg(format, arg...) do {} while (0)
+#endif
+
+#define ALPS_MODEL_GLIDEPOINT	1
+#define ALPS_MODEL_DUALPOINT	2
+
+struct alps_model_info {
+	unsigned char signature[3];
+	unsigned char model;
+} alps_model_data[] = {
+/*	{ { 0x33, 0x02, 0x0a },	ALPS_MODEL_GLIDEPOINT },	*/
+	{ { 0x53, 0x02, 0x0a },	ALPS_MODEL_GLIDEPOINT },
+	{ { 0x53, 0x02, 0x14 },	ALPS_MODEL_GLIDEPOINT },
+	{ { 0x63, 0x02, 0x0a },	ALPS_MODEL_GLIDEPOINT },
+	{ { 0x63, 0x02, 0x14 },	ALPS_MODEL_GLIDEPOINT },
+	{ { 0x73, 0x02, 0x0a },	ALPS_MODEL_GLIDEPOINT },
+	{ { 0x73, 0x02, 0x14 },	ALPS_MODEL_GLIDEPOINT },
+	{ { 0x63, 0x02, 0x28 },	ALPS_MODEL_GLIDEPOINT },
+/*	{ { 0x63, 0x02, 0x3c },	ALPS_MODEL_GLIDEPOINT },	*/
+/*	{ { 0x63, 0x02, 0x50 },	ALPS_MODEL_GLIDEPOINT },	*/
+	{ { 0x63, 0x02, 0x64 },	ALPS_MODEL_GLIDEPOINT },
+	{ { 0x20, 0x02, 0x0e },	ALPS_MODEL_DUALPOINT },
+	{ { 0x22, 0x02, 0x0a },	ALPS_MODEL_DUALPOINT },
+	{ { 0x22, 0x02, 0x14 }, ALPS_MODEL_DUALPOINT },
+	{ { 0x63, 0x03, 0xc8 },	ALPS_MODEL_DUALPOINT },
+};
+
+/*
+ * ALPS abolute Mode
+ * byte 0:  1    1    1    1    1  mid0 rig0 lef0
+ * byte 1:  0   x6   x5   x4   x3   x2   x1   x0
+ * byte 2:  0   x10  x9   x8   x7  up1  fin  ges
+ * byte 3:  0   y9   y8   y7    1  mid1 rig1 lef1
+ * byte 4:  0   y6   y5   y4   y3   y2   y1   y0
+ * byte 5:  0   z6   z5   z4   z3   z2   z1   z0
+ *
+ * On a dualpoint, {mid,rig,lef}0 are the stick, 1 are the pad.
+ * We just 'or' them together for now.
+ *
+ * We used to send 'ges'tures as BTN_TOUCH but this made it impossible
+ * to disable tap events in the synaptics driver since the driver
+ * was unable to distinguish a gesture tap from an actual button click.
+ * A tap gesture now creates an emulated touch that the synaptics
+ * driver can interpret as a tap event, if MaxTapTime=0 and
+ * MaxTapMove=0 then the driver will ignore taps.
+ *
+ * The touchpad on an 'Acer Aspire' has 4 buttons:
+ *   left,right,up,down.
+ * This device always sets {mid,rig,lef}0 to 1 and
+ * reflects left,right,down,up in lef1,rig1,mid1,up1.
+ */
+
+static void alps_process_packet(struct psmouse *psmouse, struct pt_regs *regs)
+{
+	unsigned char *packet = psmouse->packet;
+	struct input_dev *dev = &psmouse->dev;
+	int x, y, z;
+	int left = 0, right = 0, middle = 0;
+
+	input_regs(dev, regs);
+
+	if ((packet[0] & 0xc8) == 0x08) {   /* 3-byte PS/2 packet */
+		x = packet[1];
+		if (packet[0] & 0x10)
+			x = x - 256;
+		y = packet[2];
+		if (packet[0] & 0x20)
+			y = y - 256;
+		left  = (packet[0]     ) & 1;
+		right = (packet[0] >> 1) & 1;
+
+		input_report_rel(dev, REL_X, x);
+		input_report_rel(dev, REL_Y, -y);
+		input_report_key(dev, BTN_A, left);
+		input_report_key(dev, BTN_B, right);
+		input_sync(dev);
+		return;
+	}
+
+	x = (packet[1] & 0x7f) | ((packet[2] & 0x78)<<(7-3));
+	y = (packet[4] & 0x7f) | ((packet[3] & 0x70)<<(7-4));
+	z = packet[5];
+
+	if (z == 127) {	/* DualPoint stick is relative, not absolute */
+		if (x > 383)
+			x = x - 768;
+		if (y > 255)
+			y = y - 512;
+		left  = packet[3] & 1;
+		right = (packet[3] >> 1) & 1;
+
+		input_report_rel(dev, REL_X, x);
+		input_report_rel(dev, REL_Y, -y);
+		input_report_key(dev, BTN_LEFT, left);
+		input_report_key(dev, BTN_RIGHT, right);
+		input_sync(dev);
+		return;
+	}
+
+	if (z > 30) input_report_key(dev, BTN_TOUCH, 1);
+	if (z < 25) input_report_key(dev, BTN_TOUCH, 0);
+
+	if (z > 0) {
+		input_report_abs(dev, ABS_X, x);
+		input_report_abs(dev, ABS_Y, y);
+	}
+	input_report_abs(dev, ABS_PRESSURE, z);
+	input_report_key(dev, BTN_TOOL_FINGER, z > 0);
+
+	left  |= (packet[2]     ) & 1;
+	left  |= (packet[3]     ) & 1;
+	right |= (packet[3] >> 1) & 1;
+	if (packet[0] == 0xff) {
+		int back    = (packet[3] >> 2) & 1;
+		int forward = (packet[2] >> 2) & 1;
+		if (back && forward) {
+			middle = 1;
+			back = 0;
+			forward = 0;
+		}
+		input_report_key(dev, BTN_BACK,    back);
+		input_report_key(dev, BTN_FORWARD, forward);
+	} else {
+		left   |= (packet[0]     ) & 1;
+		right  |= (packet[0] >> 1) & 1;
+		middle |= (packet[0] >> 2) & 1;
+		middle |= (packet[3] >> 2) & 1;
+	}
+
+	input_report_key(dev, BTN_LEFT, left);
+	input_report_key(dev, BTN_RIGHT, right);
+	input_report_key(dev, BTN_MIDDLE, middle);
+
+	input_sync(dev);
+}
+
+static psmouse_ret_t alps_process_byte(struct psmouse *psmouse, struct pt_regs *regs)
+{
+	if ((psmouse->packet[0] & 0xc8) == 0x08) { /* PS/2 packet */
+		if (psmouse->pktcnt == 3) {
+			alps_process_packet(psmouse, regs);
+			return PSMOUSE_FULL_PACKET;
+		}
+		return PSMOUSE_GOOD_DATA;
+	}
+
+	/* ALPS absolute mode packets start with 0b11111mrl */
+	if ((psmouse->packet[0] & 0xf8) != 0xf8)
+		return PSMOUSE_BAD_DATA;
+
+	/* Bytes 2 - 6 should have 0 in the highest bit */
+	if (psmouse->pktcnt >= 2 && psmouse->pktcnt <= 6 &&
+	    (psmouse->packet[psmouse->pktcnt-1] & 0x80))
+		return PSMOUSE_BAD_DATA;
+
+	if (psmouse->pktcnt == 6) {
+		alps_process_packet(psmouse, regs);
+		return PSMOUSE_FULL_PACKET;
+	}
+
+	return PSMOUSE_GOOD_DATA;
+}
+
+int alps_get_model(struct psmouse *psmouse)
+{
+	struct ps2dev *ps2dev = &psmouse->ps2dev;
+	unsigned char param[4];
+	int i;
+
+	/*
+	 * First try "E6 report".
+	 * ALPS should return 0x00,0x00,0x0a or 0x00,0x00,0x64
+	 */
+	param[0] = 0;
+	if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES) ||
+	    ps2_command(ps2dev,  NULL, PSMOUSE_CMD_SETSCALE11) ||
+	    ps2_command(ps2dev,  NULL, PSMOUSE_CMD_SETSCALE11) ||
+	    ps2_command(ps2dev,  NULL, PSMOUSE_CMD_SETSCALE11))
+		return -1;
+
+	param[0] = param[1] = param[2] = 0xff;
+	if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO))
+		return -1;
+
+	dbg("E6 report: %2.2x %2.2x %2.2x", param[0], param[1], param[2]);
+
+	if (param[0] != 0x00 || param[1] != 0x00 || (param[2] != 0x0a && param[2] != 0x64))
+		return -1;
+
+	/* Now try "E7 report". ALPS should return 0x33 in byte 1 */
+	param[0] = 0;
+	if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES) ||
+	    ps2_command(ps2dev,  NULL, PSMOUSE_CMD_SETSCALE21) ||
+	    ps2_command(ps2dev,  NULL, PSMOUSE_CMD_SETSCALE21) ||
+	    ps2_command(ps2dev,  NULL, PSMOUSE_CMD_SETSCALE21))
+		return -1;
+
+	param[0] = param[1] = param[2] = 0xff;
+	if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO))
+		return -1;
+
+	dbg("E7 report: %2.2x %2.2x %2.2x", param[0], param[1], param[2]);
+
+	for (i = 0; i < ARRAY_SIZE(alps_model_data); i++)
+		if (!memcmp(param, alps_model_data[i].signature, sizeof(alps_model_data[i].signature)))
+			return alps_model_data[i].model;
+
+	return -1;
+}
+
+/*
+ * For DualPoint devices select the device that should respond to
+ * subsequent commands. It looks like glidepad is behind stickpointer,
+ * I'd thought it would be other way around...
+ */
+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) ||
+	    ps2_command(ps2dev, NULL, cmd) ||
+	    ps2_command(ps2dev, NULL, cmd) ||
+	    ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE))
+		return -1;
+
+	/* we may get 3 more bytes, just ignore them */
+	ps2_command(ps2dev, param, 0x0300);
+
+	return 0;
+}
+
+static int alps_absolute_mode(struct psmouse *psmouse)
+{
+	struct ps2dev *ps2dev = &psmouse->ps2dev;
+
+	/* Try ALPS magic knock - 4 disable before enable */
+	if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) ||
+	    ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) ||
+	    ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) ||
+	    ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) ||
+	    ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE))
+		return -1;
+
+	/*
+	 * Switch mouse to poll (remote) mode so motion data will not
+	 * get in our way
+	 */
+	return ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETPOLL);
+}
+
+static int alps_get_status(struct psmouse *psmouse, char *param)
+{
+	struct ps2dev *ps2dev = &psmouse->ps2dev;
+
+	/* Get status: 0xF5 0xF5 0xF5 0xE9 */
+	if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) ||
+	    ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) ||
+	    ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) ||
+	    ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO))
+		return -1;
+
+	dbg("Status: %2.2x %2.2x %2.2x", param[0], param[1], param[2]);
+
+	return 0;
+}
+
+/*
+ * Turn touchpad tapping on or off. The sequences are:
+ * 0xE9 0xF5 0xF5 0xF3 0x0A to enable,
+ * 0xE9 0xF5 0xF5 0xE8 0x00 to disable.
+ * My guess that 0xE9 (GetInfo) is here as a sync point.
+ * For models that also have stickpointer (DualPoints) its tapping
+ * is controlled separately (0xE6 0xE6 0xE6 0xF3 0x14|0x0A) but
+ * we don't fiddle with it.
+ */
+static int alps_tap_mode(struct psmouse *psmouse, int enable)
+{
+	struct ps2dev *ps2dev = &psmouse->ps2dev;
+	int cmd = enable ? PSMOUSE_CMD_SETRATE : PSMOUSE_CMD_SETRES;
+	unsigned char tap_arg = enable ? 0x0A : 0x00;
+	unsigned char param[4];
+
+	if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO) ||
+	    ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) ||
+	    ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) ||
+	    ps2_command(ps2dev, &tap_arg, cmd))
+		return -1;
+
+	if (alps_get_status(psmouse, param))
+		return -1;
+
+	return 0;
+}
+
+static int alps_reconnect(struct psmouse *psmouse)
+{
+	int model;
+	unsigned char param[4];
+
+	if ((model = alps_get_model(psmouse)) < 0)
+		return -1;
+
+	if (model == ALPS_MODEL_DUALPOINT && alps_passthrough_mode(psmouse, 1))
+		return -1;
+
+	if (alps_get_status(psmouse, param))
+		return -1;
+
+	if (param[0] & 0x04)
+		alps_tap_mode(psmouse, 0);
+
+	if (alps_absolute_mode(psmouse)) {
+		printk(KERN_ERR "alps.c: Failed to enable absolute mode\n");
+		return -1;
+	}
+
+	if (model == ALPS_MODEL_DUALPOINT && alps_passthrough_mode(psmouse, 0))
+		return -1;
+
+	return 0;
+}
+
+static void alps_disconnect(struct psmouse *psmouse)
+{
+	psmouse_reset(psmouse);
+}
+
+int alps_init(struct psmouse *psmouse)
+{
+	unsigned char param[4];
+	int model;
+
+	if ((model = alps_get_model(psmouse)) < 0)
+		return -1;
+
+	printk(KERN_INFO "ALPS Touchpad (%s) detected\n",
+		model == ALPS_MODEL_GLIDEPOINT ? "Glidepoint" : "Dualpoint");
+
+	if (model == ALPS_MODEL_DUALPOINT && alps_passthrough_mode(psmouse, 1))
+		return -1;
+
+	if (alps_get_status(psmouse, param)) {
+		printk(KERN_ERR "alps.c: touchpad status report request failed\n");
+		return -1;
+	}
+
+	if (param[0] & 0x04) {
+		printk(KERN_INFO "  Disabling hardware tapping\n");
+		if (alps_tap_mode(psmouse, 0))
+			printk(KERN_WARNING "alps.c: Failed to disable hardware tapping\n");
+	}
+
+	if (alps_absolute_mode(psmouse)) {
+		printk(KERN_ERR "alps.c: Failed to enable absolute mode\n");
+		return -1;
+	}
+
+	if (model == ALPS_MODEL_DUALPOINT && alps_passthrough_mode(psmouse, 0))
+		return -1;
+
+	psmouse->dev.evbit[LONG(EV_REL)] |= BIT(EV_REL);
+	psmouse->dev.relbit[LONG(REL_X)] |= BIT(REL_X);
+	psmouse->dev.relbit[LONG(REL_Y)] |= BIT(REL_Y);
+	psmouse->dev.keybit[LONG(BTN_A)] |= BIT(BTN_A);
+	psmouse->dev.keybit[LONG(BTN_B)] |= BIT(BTN_B);
+
+	psmouse->dev.evbit[LONG(EV_ABS)] |= BIT(EV_ABS);
+	input_set_abs_params(&psmouse->dev, ABS_X, 0, 1023, 0, 0);
+	input_set_abs_params(&psmouse->dev, ABS_Y, 0, 1023, 0, 0);
+	input_set_abs_params(&psmouse->dev, ABS_PRESSURE, 0, 127, 0, 0);
+
+	psmouse->dev.keybit[LONG(BTN_TOUCH)] |= BIT(BTN_TOUCH);
+	psmouse->dev.keybit[LONG(BTN_TOOL_FINGER)] |= BIT(BTN_TOOL_FINGER);
+	psmouse->dev.keybit[LONG(BTN_FORWARD)] |= BIT(BTN_FORWARD);
+	psmouse->dev.keybit[LONG(BTN_BACK)] |= BIT(BTN_BACK);
+
+	psmouse->protocol_handler = alps_process_byte;
+	psmouse->disconnect = alps_disconnect;
+	psmouse->reconnect = alps_reconnect;
+	psmouse->pktsize = 6;
+
+	return 0;
+}
+
+int alps_detect(struct psmouse *psmouse, int set_properties)
+{
+	if (alps_get_model(psmouse) < 0)
+		return -1;
+
+	if (set_properties) {
+		psmouse->vendor = "ALPS";
+		psmouse->name = "TouchPad";
+	}
+	return 0;
+}
+
diff -Nru a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/input/mouse/alps.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,17 @@
+/*
+ * ALPS touchpad PS/2 mouse driver
+ *
+ * Copyright (c) 2003 Peter Osterlund <petero2@telia.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.
+ */
+
+#ifndef _ALPS_H
+#define _ALPS_H
+
+int alps_detect(struct psmouse *psmouse, int set_properties);
+int alps_init(struct psmouse *psmouse);
+
+#endif
diff -Nru a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c
--- a/drivers/input/mouse/logips2pp.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/input/mouse/logips2pp.c	2005-03-01 23:39:07 -08:00
@@ -11,6 +11,7 @@
 
 #include <linux/input.h>
 #include <linux/serio.h>
+#include <linux/libps2.h>
 #include "psmouse.h"
 #include "logips2pp.h"
 
@@ -37,13 +38,23 @@
  * Process a PS2++ or PS2T++ packet.
  */
 
-void ps2pp_process_packet(struct psmouse *psmouse)
+static psmouse_ret_t ps2pp_process_byte(struct psmouse *psmouse, struct pt_regs *regs)
 {
 	struct input_dev *dev = &psmouse->dev;
-        unsigned char *packet = psmouse->packet;
+	unsigned char *packet = psmouse->packet;
+
+	if (psmouse->pktcnt < 3)
+		return PSMOUSE_GOOD_DATA;
+
+/*
+ * Full packet accumulated, process it
+ */
+
+	input_regs(dev, regs);
 
 	if ((packet[0] & 0x48) == 0x48 && (packet[1] & 0x02) == 0x02) {
 
+		/* Logitech extended packet */
 		switch ((packet[1] >> 4) | (packet[0] & 0x30)) {
 
 			case 0x0d: /* Mouse extra info */
@@ -78,11 +89,20 @@
 					(packet[1] >> 4) | (packet[0] & 0x30));
 #endif
 		}
-
-		packet[0] &= 0x0f;
-		packet[1] = 0;
-		packet[2] = 0;
+	} else {
+		/* Standard PS/2 motion data */
+		input_report_rel(dev, REL_X, packet[1] ? (int) packet[1] - (int) ((packet[0] << 4) & 0x100) : 0);
+		input_report_rel(dev, REL_Y, packet[2] ? (int) ((packet[0] << 3) & 0x100) - (int) packet[2] : 0);
 	}
+
+	input_report_key(dev, BTN_LEFT,    packet[0]       & 1);
+	input_report_key(dev, BTN_MIDDLE, (packet[0] >> 2) & 1);
+	input_report_key(dev, BTN_RIGHT,  (packet[0] >> 1) & 1);
+
+	input_sync(dev);
+
+	return PSMOUSE_FULL_PACKET;
+
 }
 
 /*
@@ -97,7 +117,7 @@
 	if (psmouse_sliced_command(psmouse, command))
 		return -1;
 
-	if (psmouse_command(psmouse, param, PSMOUSE_CMD_POLL))
+	if (ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_POLL))
 		return -1;
 
 	return 0;
@@ -108,40 +128,73 @@
  * enabled if we do nothing to it. Of course I put this in because I want it
  * disabled :P
  * 1 - enabled (if previously disabled, also default)
- * 0/2 - disabled
+ * 0 - disabled
  */
 
-static void ps2pp_set_smartscroll(struct psmouse *psmouse)
+static void ps2pp_set_smartscroll(struct psmouse *psmouse, unsigned int smartscroll)
 {
+	struct ps2dev *ps2dev = &psmouse->ps2dev;
 	unsigned char param[4];
 
+	if (smartscroll > 1)
+		smartscroll = 1;
+
 	ps2pp_cmd(psmouse, param, 0x32);
 
 	param[0] = 0;
-	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
-	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
-	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
-
-	if (psmouse_smartscroll < 2) {
-		/* 0 - disabled, 1 - enabled */
-		param[0] = psmouse_smartscroll;
-		psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
-	}
+	ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
+	ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
+	ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
+
+	param[0] = smartscroll;
+	ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
 }
 
+static ssize_t psmouse_attr_show_smartscroll(struct psmouse *psmouse, char *buf)
+{
+	return sprintf(buf, "%d\n", psmouse->smartscroll ? 1 : 0);
+}
+
+static ssize_t psmouse_attr_set_smartscroll(struct psmouse *psmouse, const char *buf, size_t count)
+{
+	unsigned long value;
+	char *rest;
+
+	value = simple_strtoul(buf, &rest, 10);
+	if (*rest || value > 1)
+		return -EINVAL;
+
+	ps2pp_set_smartscroll(psmouse, value);
+	psmouse->smartscroll = value;
+	return count;
+}
+
+PSMOUSE_DEFINE_ATTR(smartscroll);
+
 /*
  * Support 800 dpi resolution _only_ if the user wants it (there are good
  * reasons to not use it even if the mouse supports it, and of course there are
  * also good reasons to use it, let the user decide).
  */
 
-void ps2pp_set_800dpi(struct psmouse *psmouse)
+static void ps2pp_set_resolution(struct psmouse *psmouse, unsigned int resolution)
 {
-	unsigned char param = 3;
-	psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11);
-	psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11);
-	psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11);
-	psmouse_command(psmouse, &param, PSMOUSE_CMD_SETRES);
+	if (resolution > 400) {
+		struct ps2dev *ps2dev = &psmouse->ps2dev;
+		unsigned char param = 3;
+
+		ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11);
+		ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11);
+		ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11);
+		ps2_command(ps2dev, &param, PSMOUSE_CMD_SETRES);
+		psmouse->resolution = 800;
+	} else
+		psmouse_set_resolution(psmouse, resolution);
+}
+
+static void ps2pp_disconnect(struct psmouse *psmouse)
+{
+	device_remove_file(&psmouse->ps2dev.serio->dev, &psmouse_attr_smartscroll);
 }
 
 static struct ps2pp_info *get_model_info(unsigned char model)
@@ -192,7 +245,8 @@
  * Set up input device's properties based on the detected mouse model.
  */
 
-static void ps2pp_set_model_properties(struct psmouse *psmouse, struct ps2pp_info *model_info)
+static void ps2pp_set_model_properties(struct psmouse *psmouse, struct ps2pp_info *model_info,
+				       int using_ps2pp)
 {
 	if (model_info->features & PS2PP_SIDE_BTN)
 		set_bit(BTN_SIDE, psmouse->dev.keybit);
@@ -226,6 +280,16 @@
 		case PS2PP_KIND_TP3:
 			psmouse->name = "TouchPad 3";
 			break;
+
+		default:
+			/*
+			 * Set name to "Mouse" only when using PS2++,
+			 * otherwise let other protocols define suitable
+			 * name
+			 */
+			if (using_ps2pp)
+				psmouse->name = "Mouse";
+			break;
 	}
 }
 
@@ -238,23 +302,27 @@
 
 int ps2pp_init(struct psmouse *psmouse, int set_properties)
 {
+	struct ps2dev *ps2dev = &psmouse->ps2dev;
 	unsigned char param[4];
-	unsigned char protocol = PSMOUSE_PS2;
 	unsigned char model, buttons;
 	struct ps2pp_info *model_info;
+	int use_ps2pp = 0;
 
 	param[0] = 0;
-	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
-	psmouse_command(psmouse,  NULL, PSMOUSE_CMD_SETSCALE11);
-	psmouse_command(psmouse,  NULL, PSMOUSE_CMD_SETSCALE11);
-	psmouse_command(psmouse,  NULL, PSMOUSE_CMD_SETSCALE11);
+	ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
+	ps2_command(ps2dev,  NULL, PSMOUSE_CMD_SETSCALE11);
+	ps2_command(ps2dev,  NULL, PSMOUSE_CMD_SETSCALE11);
+	ps2_command(ps2dev,  NULL, PSMOUSE_CMD_SETSCALE11);
 	param[1] = 0;
-	psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO);
+	ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO);
+
+	if (!param[1])
+		return -1;
+
+	model = ((param[0] >> 4) & 0x07) | ((param[0] << 3) & 0x78);
+	buttons = param[1];
 
-	if (param[1] != 0) {
-		model = ((param[0] >> 4) & 0x07) | ((param[0] << 3) & 0x78);
-		buttons = param[1];
-		model_info = get_model_info(model);
+	if ((model_info = get_model_info(model)) != NULL) {
 
 /*
  * Do Logitech PS2++ / PS2T++ magic init.
@@ -263,21 +331,21 @@
 
 			/* Unprotect RAM */
 			param[0] = 0x11; param[1] = 0x04; param[2] = 0x68;
-			psmouse_command(psmouse, param, 0x30d1);
+			ps2_command(ps2dev, param, 0x30d1);
 			/* Enable features */
 			param[0] = 0x11; param[1] = 0x05; param[2] = 0x0b;
-			psmouse_command(psmouse, param, 0x30d1);
+			ps2_command(ps2dev, param, 0x30d1);
 			/* Enable PS2++ */
 			param[0] = 0x11; param[1] = 0x09; param[2] = 0xc3;
-			psmouse_command(psmouse, param, 0x30d1);
+			ps2_command(ps2dev, param, 0x30d1);
 
 			param[0] = 0;
-			if (!psmouse_command(psmouse, param, 0x13d1) &&
+			if (!ps2_command(ps2dev, param, 0x13d1) &&
 			    param[0] == 0x06 && param[1] == 0x00 && param[2] == 0x14) {
-				protocol = PSMOUSE_PS2TPP;
+				use_ps2pp = 1;
 			}
 
-		} else if (model_info != NULL) {
+		} else {
 
 			param[0] = param[1] = param[2] = 0;
 			ps2pp_cmd(psmouse, param, 0x39); /* Magic knock */
@@ -286,25 +354,37 @@
 			if ((param[0] & 0x78) == 0x48 &&
 			    (param[1] & 0xf3) == 0xc2 &&
 			    (param[2] & 0x03) == ((param[1] >> 2) & 3)) {
-				ps2pp_set_smartscroll(psmouse);
-				protocol = PSMOUSE_PS2PP;
+				ps2pp_set_smartscroll(psmouse, psmouse->smartscroll);
+				use_ps2pp = 1;
 			}
 		}
+	}
 
-		if (set_properties) {
-			psmouse->vendor = "Logitech";
-			psmouse->model = model;
-
-			if (buttons < 3)
-				clear_bit(BTN_MIDDLE, psmouse->dev.keybit);
-			if (buttons < 2)
-				clear_bit(BTN_RIGHT, psmouse->dev.keybit);
+	if (set_properties) {
+		psmouse->vendor = "Logitech";
+		psmouse->model = model;
+
+		if (use_ps2pp) {
+			psmouse->protocol_handler = ps2pp_process_byte;
+			psmouse->pktsize = 3;
+
+			if (model_info->kind != PS2PP_KIND_TP3) {
+				psmouse->set_resolution = ps2pp_set_resolution;
+				psmouse->disconnect = ps2pp_disconnect;
 
-			if (model_info)
-				ps2pp_set_model_properties(psmouse, model_info);
+				device_create_file(&psmouse->ps2dev.serio->dev, &psmouse_attr_smartscroll);
+			}
 		}
+
+		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);
 	}
 
-	return protocol;
+	return use_ps2pp ? 0 : -1;
 }
 
diff -Nru a/drivers/input/mouse/logips2pp.h b/drivers/input/mouse/logips2pp.h
--- a/drivers/input/mouse/logips2pp.h	2005-03-01 23:39:08 -08:00
+++ b/drivers/input/mouse/logips2pp.h	2005-03-01 23:39:08 -08:00
@@ -11,8 +11,6 @@
 #ifndef _LOGIPS2PP_H
 #define _LOGIPS2PP_H
 
-void ps2pp_process_packet(struct psmouse *psmouse);
-void ps2pp_set_800dpi(struct psmouse *psmouse);
 int ps2pp_init(struct psmouse *psmouse, int set_properties);
 
 #endif
diff -Nru a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
--- a/drivers/input/mouse/psmouse-base.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/input/mouse/psmouse-base.c	2005-03-01 23:38:53 -08:00
@@ -2,6 +2,7 @@
  * PS/2 mouse driver
  *
  * Copyright (c) 1999-2002 Vojtech Pavlik
+ * Copyright (c) 2003-2004 Dmitry Torokhov
  */
 
 /*
@@ -18,9 +19,11 @@
 #include <linux/input.h>
 #include <linux/serio.h>
 #include <linux/init.h>
+#include <linux/libps2.h>
 #include "psmouse.h"
 #include "synaptics.h"
 #include "logips2pp.h"
+#include "alps.h"
 
 #define DRIVER_DESC	"PS/2 mouse driver"
 
@@ -33,15 +36,15 @@
 module_param_named(proto, psmouse_proto, charp, 0);
 MODULE_PARM_DESC(proto, "Highest protocol extension to probe (bare, imps, exps). Useful for KVM switches.");
 
-int psmouse_resolution = 200;
+static unsigned int psmouse_resolution = 200;
 module_param_named(resolution, psmouse_resolution, uint, 0);
 MODULE_PARM_DESC(resolution, "Resolution, in dpi.");
 
-unsigned int psmouse_rate = 100;
+static unsigned int psmouse_rate = 100;
 module_param_named(rate, psmouse_rate, uint, 0);
 MODULE_PARM_DESC(rate, "Report rate, in reports per second.");
 
-int psmouse_smartscroll = 1;
+static unsigned int psmouse_smartscroll = 1;
 module_param_named(smartscroll, psmouse_smartscroll, bool, 0);
 MODULE_PARM_DESC(smartscroll, "Logitech Smartscroll autorepeat, 1 = enabled (default), 0 = disabled.");
 
@@ -49,13 +52,17 @@
 module_param_named(resetafter, psmouse_resetafter, uint, 0);
 MODULE_PARM_DESC(resetafter, "Reset device after so many bad packets (0 = never).");
 
+PSMOUSE_DEFINE_ATTR(rate);
+PSMOUSE_DEFINE_ATTR(resolution);
+PSMOUSE_DEFINE_ATTR(resetafter);
+
 __obsolete_setup("psmouse_noext");
 __obsolete_setup("psmouse_resolution=");
 __obsolete_setup("psmouse_smartscroll=");
 __obsolete_setup("psmouse_resetafter=");
 __obsolete_setup("psmouse_rate=");
 
-static char *psmouse_protocols[] = { "None", "PS/2", "PS2++", "PS2T++", "GenPS/2", "ImPS/2", "ImExPS/2", "SynPS/2"};
+static char *psmouse_protocols[] = { "None", "PS/2", "PS2++", "ThinkPS/2", "GenPS/2", "ImPS/2", "ImExPS/2", "SynPS/2", "AlpsPS/2" };
 
 /*
  * psmouse_process_byte() analyzes the PS/2 data stream and reports
@@ -67,7 +74,7 @@
 	struct input_dev *dev = &psmouse->dev;
 	unsigned char *packet = psmouse->packet;
 
-	if (psmouse->pktcnt < 3 + (psmouse->type >= PSMOUSE_GENPS))
+	if (psmouse->pktcnt < psmouse->pktsize)
 		return PSMOUSE_GOOD_DATA;
 
 /*
@@ -77,13 +84,6 @@
 	input_regs(dev, regs);
 
 /*
- * The PS2++ protocol is a little bit complex
- */
-
-	if (psmouse->type == PSMOUSE_PS2PP || psmouse->type == PSMOUSE_PS2TPP)
-		ps2pp_process_packet(psmouse);
-
-/*
  * Scroll wheel on IntelliMice, scroll buttons on NetMice
  */
 
@@ -110,6 +110,15 @@
 	}
 
 /*
+ * Extra button on ThinkingMouse
+ */
+	if (psmouse->type == PSMOUSE_THINKPS) {
+		input_report_key(dev, BTN_EXTRA, (packet[0] >> 3) & 1);
+		/* Without this bit of weirdness moving up gives wildly high Y changes. */
+		packet[1] |= (packet[0] & 0x40) << 1;
+	}
+
+/*
  * Generic PS/2 Mouse
  */
 
@@ -144,63 +153,17 @@
 			printk(KERN_WARNING "psmouse.c: bad data from KBC -%s%s\n",
 				flags & SERIO_TIMEOUT ? " timeout" : "",
 				flags & SERIO_PARITY ? " bad parity" : "");
-		psmouse->nak = 1;
-		clear_bit(PSMOUSE_FLAG_ACK, &psmouse->flags);
-		clear_bit(PSMOUSE_FLAG_CMD,  &psmouse->flags);
-		wake_up_interruptible(&psmouse->wait);
+		ps2_cmd_aborted(&psmouse->ps2dev);
 		goto out;
 	}
 
-	if (test_bit(PSMOUSE_FLAG_ACK, &psmouse->flags)) {
-		switch (data) {
-			case PSMOUSE_RET_ACK:
-				psmouse->nak = 0;
-				break;
-
-			case PSMOUSE_RET_NAK:
-				psmouse->nak = 1;
-				break;
-
-			/*
-			 * Workaround for mice which don't ACK the Get ID command.
-			 * These are valid mouse IDs that we recognize.
-			 */
-			case 0x00:
-			case 0x03:
-			case 0x04:
-				if (test_bit(PSMOUSE_FLAG_WAITID, &psmouse->flags)) {
-					psmouse->nak = 0;
-					break;
-				}
-				/* Fall through */
-			default:
-				goto out;
-		}
-
-		if (!psmouse->nak && psmouse->cmdcnt) {
-			set_bit(PSMOUSE_FLAG_CMD, &psmouse->flags);
-			set_bit(PSMOUSE_FLAG_CMD1, &psmouse->flags);
-		}
-		clear_bit(PSMOUSE_FLAG_ACK, &psmouse->flags);
-		wake_up_interruptible(&psmouse->wait);
-
-		if (data == PSMOUSE_RET_ACK || data == PSMOUSE_RET_NAK)
+	if (unlikely(psmouse->ps2dev.flags & PS2_FLAG_ACK))
+		if  (ps2_handle_ack(&psmouse->ps2dev, data))
 			goto out;
-	}
 
-	if (test_bit(PSMOUSE_FLAG_CMD, &psmouse->flags)) {
-		if (psmouse->cmdcnt)
-			psmouse->cmdbuf[--psmouse->cmdcnt] = data;
-
-		if (test_and_clear_bit(PSMOUSE_FLAG_CMD1, &psmouse->flags) && psmouse->cmdcnt)
-			wake_up_interruptible(&psmouse->wait);
-
-		if (!psmouse->cmdcnt) {
-			clear_bit(PSMOUSE_FLAG_CMD, &psmouse->flags);
-			wake_up_interruptible(&psmouse->wait);
-		}
-		goto out;
-	}
+	if (unlikely(psmouse->ps2dev.flags & PS2_FLAG_CMD))
+		if  (ps2_handle_response(&psmouse->ps2dev, data))
+			goto out;
 
 	if (psmouse->state == PSMOUSE_INITIALIZING)
 		goto out;
@@ -243,10 +206,10 @@
 				psmouse->name, psmouse->phys, psmouse->pktcnt);
 			psmouse->pktcnt = 0;
 
-			if (++psmouse->out_of_sync == psmouse_resetafter) {
+			if (++psmouse->out_of_sync == psmouse->resetafter) {
 				psmouse->state = PSMOUSE_IGNORE;
 				printk(KERN_NOTICE "psmouse.c: issuing reconnect request\n");
-				serio_reconnect(psmouse->serio);
+				serio_reconnect(psmouse->ps2dev.serio);
 			}
 			break;
 
@@ -266,100 +229,6 @@
 	return IRQ_HANDLED;
 }
 
-/*
- * psmouse_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.
- *
- * psmouse_sendbyte() can only be called from a process context
- */
-
-static int psmouse_sendbyte(struct psmouse *psmouse, unsigned char byte)
-{
-	psmouse->nak = 1;
-	set_bit(PSMOUSE_FLAG_ACK, &psmouse->flags);
-
-	if (serio_write(psmouse->serio, byte) == 0)
-		wait_event_interruptible_timeout(psmouse->wait,
-				!test_bit(PSMOUSE_FLAG_ACK, &psmouse->flags),
-				msecs_to_jiffies(200));
-
-	clear_bit(PSMOUSE_FLAG_ACK, &psmouse->flags);
-	return -psmouse->nak;
-}
-
-/*
- * psmouse_command() sends a command and its parameters to the mouse,
- * then waits for the response and puts it in the param array.
- *
- * psmouse_command() can only be called from a process context
- */
-
-int psmouse_command(struct psmouse *psmouse, unsigned char *param, int command)
-{
-	int timeout;
-	int send = (command >> 12) & 0xf;
-	int receive = (command >> 8) & 0xf;
-	int rc = -1;
-	int i;
-
-	timeout = msecs_to_jiffies(command == PSMOUSE_CMD_RESET_BAT ? 4000 : 500);
-
-	clear_bit(PSMOUSE_FLAG_CMD, &psmouse->flags);
-	if (command == PSMOUSE_CMD_GETID)
-		set_bit(PSMOUSE_FLAG_WAITID, &psmouse->flags);
-
-	if (receive && param)
-		for (i = 0; i < receive; i++)
-			psmouse->cmdbuf[(receive - 1) - i] = param[i];
-
-	psmouse->cmdcnt = receive;
-
-	if (command & 0xff)
-		if (psmouse_sendbyte(psmouse, command & 0xff))
-			goto out;
-
-	for (i = 0; i < send; i++)
-		if (psmouse_sendbyte(psmouse, param[i]))
-			goto out;
-
-	timeout = wait_event_interruptible_timeout(psmouse->wait,
-				!test_bit(PSMOUSE_FLAG_CMD1, &psmouse->flags), timeout);
-
-	if (psmouse->cmdcnt && timeout > 0) {
-		if (command == PSMOUSE_CMD_RESET_BAT && jiffies_to_msecs(timeout) > 100)
-			timeout = msecs_to_jiffies(100);
-
-		if (command == PSMOUSE_CMD_GETID &&
-		    psmouse->cmdbuf[receive - 1] != 0xab && psmouse->cmdbuf[receive - 1] != 0xac) {
-			/*
-			 * Device behind the port is not a keyboard
-			 * so we don't need to wait for the 2nd byte
-			 * of ID response.
-			 */
-			clear_bit(PSMOUSE_FLAG_CMD, &psmouse->flags);
-			psmouse->cmdcnt = 0;
-		}
-
-		wait_event_interruptible_timeout(psmouse->wait,
-				!test_bit(PSMOUSE_FLAG_CMD, &psmouse->flags), timeout);
-	}
-
-	if (param)
-		for (i = 0; i < receive; i++)
-			param[i] = psmouse->cmdbuf[(receive - 1) - i];
-
-	if (psmouse->cmdcnt && (command != PSMOUSE_CMD_RESET_BAT || psmouse->cmdcnt != 1))
-		goto out;
-
-	rc = 0;
-
-out:
-	clear_bit(PSMOUSE_FLAG_CMD, &psmouse->flags);
-	clear_bit(PSMOUSE_FLAG_CMD1, &psmouse->flags);
-	clear_bit(PSMOUSE_FLAG_WAITID, &psmouse->flags);
-	return rc;
-}
 
 /*
  * psmouse_sliced_command() sends an extended PS/2 command to the mouse
@@ -372,12 +241,12 @@
 {
 	int i;
 
-	if (psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11))
+	if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSCALE11))
 		return -1;
 
 	for (i = 6; i >= 0; i -= 2) {
 		unsigned char d = (command >> i) & 3;
-		if (psmouse_command(psmouse, &d, PSMOUSE_CMD_SETRES))
+		if (ps2_command(&psmouse->ps2dev, &d, PSMOUSE_CMD_SETRES))
 			return -1;
 	}
 
@@ -392,7 +261,7 @@
 {
 	unsigned char param[2];
 
-	if (psmouse_command(psmouse, param, PSMOUSE_CMD_RESET_BAT))
+	if (ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_RESET_BAT))
 		return -1;
 
 	if (param[0] != PSMOUSE_RET_BAT && param[1] != PSMOUSE_RET_ID)
@@ -405,56 +274,138 @@
 /*
  * Genius NetMouse magic init.
  */
-static int genius_detect(struct psmouse *psmouse)
+static int genius_detect(struct psmouse *psmouse, int set_properties)
 {
+	struct ps2dev *ps2dev = &psmouse->ps2dev;
 	unsigned char param[4];
 
 	param[0] = 3;
-	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
-	psmouse_command(psmouse,  NULL, PSMOUSE_CMD_SETSCALE11);
-	psmouse_command(psmouse,  NULL, PSMOUSE_CMD_SETSCALE11);
-	psmouse_command(psmouse,  NULL, PSMOUSE_CMD_SETSCALE11);
-	psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO);
+	ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
+	ps2_command(ps2dev,  NULL, PSMOUSE_CMD_SETSCALE11);
+	ps2_command(ps2dev,  NULL, PSMOUSE_CMD_SETSCALE11);
+	ps2_command(ps2dev,  NULL, PSMOUSE_CMD_SETSCALE11);
+	ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO);
+
+	if (param[0] != 0x00 || param[1] != 0x33 || param[2] != 0x55)
+		return -1;
 
-	return param[0] == 0x00 && param[1] == 0x33 && param[2] == 0x55;
+	if (set_properties) {
+		set_bit(BTN_EXTRA, psmouse->dev.keybit);
+		set_bit(BTN_SIDE, psmouse->dev.keybit);
+		set_bit(REL_WHEEL, psmouse->dev.relbit);
+
+		psmouse->vendor = "Genius";
+		psmouse->name = "Wheel Mouse";
+		psmouse->pktsize = 4;
+	}
+
+	return 0;
 }
 
 /*
  * IntelliMouse magic init.
  */
-static int intellimouse_detect(struct psmouse *psmouse)
+static int intellimouse_detect(struct psmouse *psmouse, int set_properties)
 {
+	struct ps2dev *ps2dev = &psmouse->ps2dev;
 	unsigned char param[2];
 
 	param[0] = 200;
-	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRATE);
+	ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
 	param[0] = 100;
-	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRATE);
+	ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
 	param[0] =  80;
-	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRATE);
-	psmouse_command(psmouse, param, PSMOUSE_CMD_GETID);
+	ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
+	ps2_command(ps2dev, param, PSMOUSE_CMD_GETID);
 
-	return param[0] == 3;
+	if (param[0] != 3)
+		return -1;
+
+	if (set_properties) {
+		set_bit(REL_WHEEL, psmouse->dev.relbit);
+
+		if (!psmouse->vendor) psmouse->vendor = "Generic";
+		if (!psmouse->name) psmouse->name = "Wheel Mouse";
+		psmouse->pktsize = 4;
+	}
+
+	return 0;
 }
 
 /*
  * Try IntelliMouse/Explorer magic init.
  */
-static int im_explorer_detect(struct psmouse *psmouse)
+static int im_explorer_detect(struct psmouse *psmouse, int set_properties)
 {
+	struct ps2dev *ps2dev = &psmouse->ps2dev;
 	unsigned char param[2];
 
-	intellimouse_detect(psmouse);
+	intellimouse_detect(psmouse, 0);
 
 	param[0] = 200;
-	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRATE);
+	ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
 	param[0] = 200;
-	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRATE);
+	ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
 	param[0] =  80;
-	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRATE);
-	psmouse_command(psmouse, param, PSMOUSE_CMD_GETID);
+	ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
+	ps2_command(ps2dev, param, PSMOUSE_CMD_GETID);
 
-	return param[0] == 4;
+	if (param[0] != 4)
+		return -1;
+
+	if (set_properties) {
+		set_bit(REL_WHEEL, psmouse->dev.relbit);
+		set_bit(BTN_SIDE, psmouse->dev.keybit);
+		set_bit(BTN_EXTRA, psmouse->dev.keybit);
+
+		if (!psmouse->vendor) psmouse->vendor = "Generic";
+		if (!psmouse->name) psmouse->name = "Explorer Mouse";
+		psmouse->pktsize = 4;
+	}
+
+	return 0;
+}
+
+/*
+ * Kensington ThinkingMouse / ExpertMouse magic init.
+ */
+static int thinking_detect(struct psmouse *psmouse, int set_properties)
+{
+	struct ps2dev *ps2dev = &psmouse->ps2dev;
+	unsigned char param[2];
+	unsigned char seq[] = { 20, 60, 40, 20, 20, 60, 40, 20, 20, 0 };
+	int i;
+
+	param[0] = 10;
+	ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
+	param[0] = 0;
+	ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
+	for (i = 0; seq[i]; i++)
+		ps2_command(ps2dev, seq + i, PSMOUSE_CMD_SETRATE);
+	ps2_command(ps2dev, param, PSMOUSE_CMD_GETID);
+
+	if (param[0] != 2)
+		return -1;
+
+	if (set_properties) {
+		set_bit(BTN_EXTRA, psmouse->dev.keybit);
+
+		psmouse->vendor = "Kensington";
+		psmouse->name = "ThinkingMouse";
+	}
+
+	return 0;
+}
+
+/*
+ * Bare PS/2 protocol "detection". Always succeeds.
+ */
+static int ps2bare_detect(struct psmouse *psmouse, int set_properties)
+{
+	if (!psmouse->vendor) psmouse->vendor = "Generic";
+	if (!psmouse->name) psmouse->name = "Mouse";
+
+	return 0;
 }
 
 /*
@@ -468,16 +419,19 @@
 	int synaptics_hardware = 0;
 
 /*
+ * Try Kensington ThinkingMouse (we try first, because synaptics probe
+ * upsets the thinkingmouse).
+ */
+
+	if (max_proto > PSMOUSE_PS2 && thinking_detect(psmouse, set_properties) == 0)
+		return PSMOUSE_THINKPS;
+
+/*
  * Try Synaptics TouchPad
  */
-	if (max_proto > PSMOUSE_PS2 && synaptics_detect(psmouse)) {
+	if (max_proto > PSMOUSE_PS2 && synaptics_detect(psmouse, set_properties) == 0) {
 		synaptics_hardware = 1;
 
-		if (set_properties) {
-			psmouse->vendor = "Synaptics";
-			psmouse->name = "TouchPad";
-		}
-
 		if (max_proto > PSMOUSE_IMEX) {
 			if (!set_properties || synaptics_init(psmouse) == 0)
 				return PSMOUSE_SYNAPTICS;
@@ -494,53 +448,45 @@
 		synaptics_reset(psmouse);
 	}
 
-	if (max_proto > PSMOUSE_IMEX && genius_detect(psmouse)) {
-
-		if (set_properties) {
-			set_bit(BTN_EXTRA, psmouse->dev.keybit);
-			set_bit(BTN_SIDE, psmouse->dev.keybit);
-			set_bit(REL_WHEEL, psmouse->dev.relbit);
-			psmouse->vendor = "Genius";
-			psmouse->name = "Wheel Mouse";
+/*
+ * Try ALPS TouchPad
+ */
+	if (max_proto > PSMOUSE_IMEX) {
+		ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_RESET_DIS);
+		if (alps_detect(psmouse, set_properties) == 0) {
+			if (!set_properties || alps_init(psmouse) == 0)
+				return PSMOUSE_ALPS;
+/*
+ * Init failed, try basic relative protocols
+ */
+			max_proto = PSMOUSE_IMEX;
 		}
+	}
 
+	if (max_proto > PSMOUSE_IMEX && genius_detect(psmouse, set_properties) == 0)
 		return PSMOUSE_GENPS;
-	}
 
-	if (max_proto > PSMOUSE_IMEX) {
-		int type = ps2pp_init(psmouse, set_properties);
-		if (type > PSMOUSE_PS2)
-			return type;
-	}
+	if (max_proto > PSMOUSE_IMEX && ps2pp_init(psmouse, set_properties) == 0)
+		return PSMOUSE_PS2PP;
 
-	if (max_proto >= PSMOUSE_IMEX && im_explorer_detect(psmouse)) {
-
-		if (set_properties) {
-			set_bit(REL_WHEEL, psmouse->dev.relbit);
-			set_bit(BTN_SIDE, psmouse->dev.keybit);
-			set_bit(BTN_EXTRA, psmouse->dev.keybit);
-			if (!psmouse->name)
-				psmouse->name = "Explorer Mouse";
-		}
+/*
+ * Reset to defaults in case the device got confused by extended
+ * protocol probes.
+ */
+	ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_RESET_DIS);
 
+	if (max_proto >= PSMOUSE_IMEX && im_explorer_detect(psmouse, set_properties) == 0)
 		return PSMOUSE_IMEX;
-	}
-
-	if (max_proto >= PSMOUSE_IMPS && intellimouse_detect(psmouse)) {
-
-		if (set_properties) {
-			set_bit(REL_WHEEL, psmouse->dev.relbit);
-			if (!psmouse->name)
-				psmouse->name = "Wheel Mouse";
-		}
 
+	if (max_proto >= PSMOUSE_IMPS && intellimouse_detect(psmouse, set_properties) == 0)
 		return PSMOUSE_IMPS;
-	}
 
 /*
  * Okay, all failed, we have a standard mouse here. The number of the buttons
  * is still a question, though. We assume 3.
  */
+	ps2bare_detect(psmouse, set_properties);
+
 	if (synaptics_hardware) {
 /*
  * We detected Synaptics hardware but it did not respond to IMPS/2 probes.
@@ -549,7 +495,7 @@
  * extensions.
  */
 		psmouse_reset(psmouse);
-		psmouse_command(psmouse, NULL, PSMOUSE_CMD_RESET_DIS);
+		ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_RESET_DIS);
 	}
 
 	return PSMOUSE_PS2;
@@ -561,6 +507,7 @@
 
 static int psmouse_probe(struct psmouse *psmouse)
 {
+	struct ps2dev *ps2dev = &psmouse->ps2dev;
 	unsigned char param[2];
 
 /*
@@ -569,8 +516,7 @@
  */
 
 	param[0] = 0xa5;
-
-	if (psmouse_command(psmouse, param, PSMOUSE_CMD_GETID))
+	if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETID))
 		return -1;
 
 	if (param[0] != 0x00 && param[0] != 0x03 && param[0] != 0x04)
@@ -580,8 +526,8 @@
  * Then we reset and disable the mouse so that it doesn't generate events.
  */
 
-	if (psmouse_command(psmouse, NULL, PSMOUSE_CMD_RESET_DIS))
-		printk(KERN_WARNING "psmouse.c: Failed to reset mouse on %s\n", psmouse->serio->phys);
+	if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_RESET_DIS))
+		printk(KERN_WARNING "psmouse.c: Failed to reset mouse on %s\n", ps2dev->serio->phys);
 
 	return 0;
 }
@@ -590,38 +536,29 @@
  * Here we set the mouse resolution.
  */
 
-static void psmouse_set_resolution(struct psmouse *psmouse)
+void psmouse_set_resolution(struct psmouse *psmouse, unsigned int resolution)
 {
-	unsigned char param[1];
-
-	if (psmouse->type == PSMOUSE_PS2PP && psmouse_resolution > 400) {
-		ps2pp_set_800dpi(psmouse);
-		return;
-	}
+	unsigned char params[] = { 0, 1, 2, 2, 3 };
 
-	if (!psmouse_resolution || psmouse_resolution >= 200)
-		param[0] = 3;
-	else if (psmouse_resolution >= 100)
-		param[0] = 2;
-	else if (psmouse_resolution >= 50)
-		param[0] = 1;
-	else if (psmouse_resolution)
-		param[0] = 0;
+	if (resolution == 0 || resolution > 200)
+		resolution = 200;
 
-        psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+	ps2_command(&psmouse->ps2dev, &params[resolution / 50], PSMOUSE_CMD_SETRES);
+	psmouse->resolution = 25 << params[resolution / 50];
 }
 
 /*
  * Here we set the mouse report rate.
  */
 
-static void psmouse_set_rate(struct psmouse *psmouse)
+static void psmouse_set_rate(struct psmouse *psmouse, unsigned int rate)
 {
 	unsigned char rates[] = { 200, 100, 80, 60, 40, 20, 10, 0 };
 	int i = 0;
 
-	while (rates[i] > psmouse_rate) i++;
-	psmouse_command(psmouse, rates + i, PSMOUSE_CMD_SETRATE);
+	while (rates[i] > rate) i++;
+	ps2_command(&psmouse->ps2dev, &rates[i], PSMOUSE_CMD_SETRATE);
+	psmouse->rate = rates[i];
 }
 
 /*
@@ -630,23 +567,21 @@
 
 static void psmouse_initialize(struct psmouse *psmouse)
 {
-	unsigned char param[2];
-
 /*
- * We set the mouse report rate, resolution and scaling.
+ * We set the mouse into streaming mode.
  */
 
-	if (psmouse_max_proto != PSMOUSE_PS2) {
-		psmouse_set_rate(psmouse);
-		psmouse_set_resolution(psmouse);
-		psmouse_command(psmouse,  NULL, PSMOUSE_CMD_SETSCALE11);
-	}
+	ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSTREAM);
 
 /*
- * We set the mouse into streaming mode.
+ * We set the mouse report rate, resolution and scaling.
  */
 
-	psmouse_command(psmouse, param, PSMOUSE_CMD_SETSTREAM);
+	if (psmouse_max_proto != PSMOUSE_PS2) {
+		psmouse->set_rate(psmouse, psmouse->rate);
+		psmouse->set_resolution(psmouse, psmouse->resolution);
+		ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSCALE11);
+	}
 }
 
 /*
@@ -657,11 +592,11 @@
 
 static void psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_state)
 {
-	serio_pause_rx(psmouse->serio);
+	serio_pause_rx(psmouse->ps2dev.serio);
 	psmouse->state = new_state;
-	psmouse->pktcnt = psmouse->cmdcnt = psmouse->out_of_sync = 0;
-	psmouse->flags = 0;
-	serio_continue_rx(psmouse->serio);
+	psmouse->pktcnt = psmouse->out_of_sync = 0;
+	psmouse->ps2dev.flags = 0;
+	serio_continue_rx(psmouse->ps2dev.serio);
 }
 
 /*
@@ -670,8 +605,9 @@
 
 static void psmouse_activate(struct psmouse *psmouse)
 {
-	if (psmouse_command(psmouse, NULL, PSMOUSE_CMD_ENABLE))
-		printk(KERN_WARNING "psmouse.c: Failed to enable mouse on %s\n", psmouse->serio->phys);
+	if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_ENABLE))
+		printk(KERN_WARNING "psmouse.c: Failed to enable mouse on %s\n",
+			psmouse->ps2dev.serio->phys);
 
 	psmouse_set_state(psmouse, PSMOUSE_ACTIVATED);
 }
@@ -684,8 +620,9 @@
 
 static void psmouse_deactivate(struct psmouse *psmouse)
 {
-	if (psmouse_command(psmouse, NULL, PSMOUSE_CMD_DISABLE))
-		printk(KERN_WARNING "psmouse.c: Failed to deactivate mouse on %s\n", psmouse->serio->phys);
+	if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_DISABLE))
+		printk(KERN_WARNING "psmouse.c: Failed to deactivate mouse on %s\n",
+			psmouse->ps2dev.serio->phys);
 
 	psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);
 }
@@ -710,6 +647,10 @@
 {
 	struct psmouse *psmouse, *parent;
 
+	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->private;
 	psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);
 
@@ -755,13 +696,12 @@
 
 	memset(psmouse, 0, sizeof(struct psmouse));
 
-	init_waitqueue_head(&psmouse->wait);
-	init_input_dev(&psmouse->dev);
+	ps2_init(&psmouse->ps2dev, serio);
 	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->serio = serio;
 	psmouse->dev.private = psmouse;
+	psmouse->dev.dev = &serio->dev;
 	psmouse_set_state(psmouse, PSMOUSE_INITIALIZING);
 
 	serio->private = psmouse;
@@ -778,13 +718,16 @@
 		goto out;
 	}
 
+	psmouse->rate = psmouse_rate;
+	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);
-	if (!psmouse->vendor)
-		psmouse->vendor = "Generic";
-	if (!psmouse->name)
-		psmouse->name = "Mouse";
-	if (!psmouse->protocol_handler)
-		psmouse->protocol_handler = psmouse_process_byte;
 
 	sprintf(psmouse->devname, "%s %s %s",
 		psmouse_protocols[psmouse->type], psmouse->vendor, psmouse->name);
@@ -809,6 +752,10 @@
 	if (parent && parent->pt_activate)
 		parent->pt_activate(parent);
 
+	device_create_file(&serio->dev, &psmouse_attr_rate);
+	device_create_file(&serio->dev, &psmouse_attr_resolution);
+	device_create_file(&serio->dev, &psmouse_attr_resetafter);
+
 	if (serio->child) {
 		/*
 		 * Nothing to be done here, serio core will detect that
@@ -846,7 +793,7 @@
 	psmouse_set_state(psmouse, PSMOUSE_INITIALIZING);
 
 	if (psmouse->reconnect) {
-	       if (psmouse->reconnect(psmouse))
+		if (psmouse->reconnect(psmouse))
 			goto out;
 	} else if (psmouse_probe(psmouse) < 0 ||
 		   psmouse->type != psmouse_extensions(psmouse, psmouse_max_proto, 0))
@@ -885,6 +832,115 @@
 	.disconnect	= psmouse_disconnect,
 	.cleanup	= psmouse_cleanup,
 };
+
+ssize_t psmouse_attr_show_helper(struct device *dev, char *buf,
+				 ssize_t (*handler)(struct psmouse *, char *))
+{
+	struct serio *serio = to_serio_port(dev);
+	int retval;
+
+	retval = serio_pin_driver(serio);
+	if (retval)
+		return retval;
+
+	if (serio->drv != &psmouse_drv) {
+		retval = -ENODEV;
+		goto out;
+	}
+
+	retval = handler(serio->private, buf);
+
+out:
+	serio_unpin_driver(serio);
+	return retval;
+}
+
+ssize_t psmouse_attr_set_helper(struct device *dev, const char *buf, size_t count,
+				ssize_t (*handler)(struct psmouse *, const char *, size_t))
+{
+	struct serio *serio = to_serio_port(dev);
+	struct psmouse *psmouse = serio->private, *parent = NULL;
+	int retval;
+
+	retval = serio_pin_driver(serio);
+	if (retval)
+		return retval;
+
+	if (serio->drv != &psmouse_drv) {
+		retval = -ENODEV;
+		goto out;
+	}
+
+	if (serio->parent && (serio->type & SERIO_TYPE) == SERIO_PS_PSTHRU) {
+		parent = serio->parent->private;
+		psmouse_deactivate(parent);
+	}
+	psmouse_deactivate(psmouse);
+
+	retval = handler(psmouse, buf, count);
+
+	psmouse_activate(psmouse);
+	if (parent)
+		psmouse_activate(parent);
+
+out:
+	serio_unpin_driver(serio);
+	return retval;
+}
+
+static ssize_t psmouse_attr_show_rate(struct psmouse *psmouse, char *buf)
+{
+	return sprintf(buf, "%d\n", psmouse->rate);
+}
+
+static ssize_t psmouse_attr_set_rate(struct psmouse *psmouse, const char *buf, size_t count)
+{
+	unsigned long value;
+	char *rest;
+
+	value = simple_strtoul(buf, &rest, 10);
+	if (*rest)
+		return -EINVAL;
+
+	psmouse->set_rate(psmouse, value);
+	return count;
+}
+
+static ssize_t psmouse_attr_show_resolution(struct psmouse *psmouse, char *buf)
+{
+	return sprintf(buf, "%d\n", psmouse->resolution);
+}
+
+static ssize_t psmouse_attr_set_resolution(struct psmouse *psmouse, const char *buf, size_t count)
+{
+	unsigned long value;
+	char *rest;
+
+	value = simple_strtoul(buf, &rest, 10);
+	if (*rest)
+		return -EINVAL;
+
+	psmouse->set_resolution(psmouse, value);
+	return count;
+}
+
+static ssize_t psmouse_attr_show_resetafter(struct psmouse *psmouse, char *buf)
+{
+	return sprintf(buf, "%d\n", psmouse->resetafter);
+}
+
+static ssize_t psmouse_attr_set_resetafter(struct psmouse *psmouse, const char *buf, size_t count)
+{
+	unsigned long value;
+	char *rest;
+
+	value = simple_strtoul(buf, &rest, 10);
+	if (*rest)
+		return -EINVAL;
+
+	psmouse->resetafter = value;
+	return count;
+}
 
 static inline void psmouse_parse_proto(void)
 {
diff -Nru a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h
--- a/drivers/input/mouse/psmouse.h	2005-03-01 23:39:09 -08:00
+++ b/drivers/input/mouse/psmouse.h	2005-03-01 23:39:09 -08:00
@@ -2,9 +2,11 @@
 #define _PSMOUSE_H
 
 #define PSMOUSE_CMD_SETSCALE11	0x00e6
+#define PSMOUSE_CMD_SETSCALE21	0x00e7
 #define PSMOUSE_CMD_SETRES	0x10e8
 #define PSMOUSE_CMD_GETINFO	0x03e9
 #define PSMOUSE_CMD_SETSTREAM	0x00ea
+#define PSMOUSE_CMD_SETPOLL	0x00f0
 #define PSMOUSE_CMD_POLL	0x03eb
 #define PSMOUSE_CMD_GETID	0x02f2
 #define PSMOUSE_CMD_SETRATE	0x10f3
@@ -18,11 +20,6 @@
 #define PSMOUSE_RET_ACK		0xfa
 #define PSMOUSE_RET_NAK		0xfe
 
-#define PSMOUSE_FLAG_ACK	0	/* Waiting for ACK/NAK */
-#define PSMOUSE_FLAG_CMD	1	/* Waiting for command to finish */
-#define PSMOUSE_FLAG_CMD1	2	/* Waiting for the first byte of command response */
-#define PSMOUSE_FLAG_WAITID	3	/* Command execiting is GET ID */
-
 enum psmouse_state {
 	PSMOUSE_IGNORE,
 	PSMOUSE_INITIALIZING,
@@ -40,28 +37,29 @@
 struct psmouse {
 	void *private;
 	struct input_dev dev;
-	struct serio *serio;
+	struct ps2dev ps2dev;
 	char *vendor;
 	char *name;
-	unsigned char cmdbuf[8];
 	unsigned char packet[8];
-	unsigned char cmdcnt;
 	unsigned char pktcnt;
+	unsigned char pktsize;
 	unsigned char type;
 	unsigned char model;
 	unsigned long last;
 	unsigned long out_of_sync;
 	enum psmouse_state state;
-	unsigned char nak;
-	char error;
 	char devname[64];
 	char phys[32];
-	unsigned long flags;
 
-	/* Used to signal completion from interrupt handler */
-	wait_queue_head_t wait;
+	unsigned int rate;
+	unsigned int resolution;
+	unsigned int resetafter;
+	unsigned int smartscroll;	/* Logitech only */
 
 	psmouse_ret_t (*protocol_handler)(struct psmouse *psmouse, struct pt_regs *regs);
+	void (*set_rate)(struct psmouse *psmouse, unsigned int rate);
+	void (*set_resolution)(struct psmouse *psmouse, unsigned int resolution);
+
 	int (*reconnect)(struct psmouse *psmouse);
 	void (*disconnect)(struct psmouse *psmouse);
 
@@ -69,19 +67,40 @@
 	void (*pt_deactivate)(struct psmouse *psmouse);
 };
 
-#define PSMOUSE_PS2		1
-#define PSMOUSE_PS2PP		2
-#define PSMOUSE_PS2TPP		3
-#define PSMOUSE_GENPS		4
-#define PSMOUSE_IMPS		5
-#define PSMOUSE_IMEX		6
-#define PSMOUSE_SYNAPTICS 	7
+enum psmouse_type {
+	PSMOUSE_NONE,
+	PSMOUSE_PS2,
+	PSMOUSE_PS2PP,
+	PSMOUSE_THINKPS,
+	PSMOUSE_GENPS,
+	PSMOUSE_IMPS,
+	PSMOUSE_IMEX,
+	PSMOUSE_SYNAPTICS,
+	PSMOUSE_ALPS,
+};
 
-int psmouse_command(struct psmouse *psmouse, unsigned char *param, int command);
 int psmouse_sliced_command(struct psmouse *psmouse, unsigned char command);
 int psmouse_reset(struct psmouse *psmouse);
+void psmouse_set_resolution(struct psmouse *psmouse, unsigned int resolution);
 
-extern int psmouse_smartscroll;
-extern unsigned int psmouse_rate;
+ssize_t psmouse_attr_show_helper(struct device *dev, char *buf,
+			ssize_t (*handler)(struct psmouse *, char *));
+ssize_t psmouse_attr_set_helper(struct device *dev, const char *buf, size_t count,
+			ssize_t (*handler)(struct psmouse *, const char *, size_t));
+
+#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)		\
+{										\
+	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)\
+{										\
+	return psmouse_attr_set_helper(d, b, s, psmouse_attr_set_##_name);	\
+}										\
+static struct device_attribute psmouse_attr_##_name = 				\
+	__ATTR(_name, S_IWUSR | S_IRUGO,					\
+		psmouse_do_show_##_name, psmouse_do_set_##_name);
 
 #endif /* _PSMOUSE_H */
diff -Nru a/drivers/input/mouse/sermouse.c b/drivers/input/mouse/sermouse.c
--- a/drivers/input/mouse/sermouse.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/input/mouse/sermouse.c	2005-03-01 23:39:08 -08:00
@@ -11,18 +11,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
@@ -73,19 +73,19 @@
 
 		case 0:
 			if ((data & 0xf8) != 0x80) return;
-			input_report_key(dev, BTN_LEFT,   !(data & 4)); 
+			input_report_key(dev, BTN_LEFT,   !(data & 4));
 			input_report_key(dev, BTN_RIGHT,  !(data & 1));
 			input_report_key(dev, BTN_MIDDLE, !(data & 2));
 			break;
 
-		case 1: 
-		case 3: 
+		case 1:
+		case 3:
 			input_report_rel(dev, REL_X, data / 2);
 			input_report_rel(dev, REL_Y, -buf[1]);
 			buf[0] = data - data / 2;
 			break;
 
-		case 2: 
+		case 2:
 		case 4:
 			input_report_rel(dev, REL_X, buf[0]);
 			input_report_rel(dev, REL_Y, buf[1] - data);
@@ -145,7 +145,7 @@
 		case 3:
 
 			switch (sermouse->type) {
-			
+
 				case SERIO_MS:
 					 sermouse->type = SERIO_MP;
 
@@ -164,7 +164,7 @@
 					input_report_rel(dev, REL_WHEEL,  (data & 8) - (data & 7));
 					break;
 			}
-					
+
 			break;
 
 		case 4:
@@ -243,7 +243,7 @@
 {
 	struct sermouse *sermouse;
 	unsigned char c;
-	
+
 	if ((serio->type & SERIO_TYPE) != SERIO_RS232)
 		return;
 
@@ -280,6 +280,7 @@
 	sermouse->dev.id.vendor = sermouse->type;
 	sermouse->dev.id.product = c;
 	sermouse->dev.id.version = 0x0100;
+	sermouse->dev.dev = &serio->dev;
 
 	if (serio_open(serio, drv)) {
 		kfree(sermouse);
@@ -287,7 +288,7 @@
 	}
 
 	input_register_device(&sermouse->dev);
-	
+
 	printk(KERN_INFO "input: %s on %s\n", sermouse_protocols[sermouse->type], serio->phys);
 }
 
diff -Nru a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
--- a/drivers/input/mouse/synaptics.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/input/mouse/synaptics.c	2005-03-01 23:38:55 -08:00
@@ -26,6 +26,7 @@
 #include <linux/module.h>
 #include <linux/input.h>
 #include <linux/serio.h>
+#include <linux/libps2.h>
 #include "psmouse.h"
 #include "synaptics.h"
 
@@ -50,7 +51,7 @@
 {
 	if (psmouse_sliced_command(psmouse, c))
 		return -1;
-	if (psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO))
+	if (ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_GETINFO))
 		return -1;
 	return 0;
 }
@@ -65,7 +66,7 @@
 	if (psmouse_sliced_command(psmouse, mode))
 		return -1;
 	param[0] = SYN_PS_SET_MODE2;
-	if (psmouse_command(psmouse, param, PSMOUSE_CMD_SETRATE))
+	if (ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_SETRATE))
 		return -1;
 	return 0;
 }
@@ -192,23 +193,37 @@
 	return 0;
 }
 
-static int synaptics_set_mode(struct psmouse *psmouse, int mode)
+static int synaptics_set_absolute_mode(struct psmouse *psmouse)
 {
 	struct synaptics_data *priv = psmouse->private;
 
-	mode |= SYN_BIT_ABSOLUTE_MODE;
-	if (psmouse_rate >= 80)
-		mode |= SYN_BIT_HIGH_RATE;
+	priv->mode = SYN_BIT_ABSOLUTE_MODE;
 	if (SYN_ID_MAJOR(priv->identity) >= 4)
-		mode |= SYN_BIT_DISABLE_GESTURE;
+		priv->mode |= SYN_BIT_DISABLE_GESTURE;
 	if (SYN_CAP_EXTENDED(priv->capabilities))
-		mode |= SYN_BIT_W_MODE;
-	if (synaptics_mode_cmd(psmouse, mode))
+		priv->mode |= SYN_BIT_W_MODE;
+
+	if (synaptics_mode_cmd(psmouse, priv->mode))
 		return -1;
 
 	return 0;
 }
 
+static void synaptics_set_rate(struct psmouse *psmouse, unsigned int rate)
+{
+	struct synaptics_data *priv = psmouse->private;
+
+	if (rate >= 80) {
+		priv->mode |= SYN_BIT_HIGH_RATE;
+		psmouse->rate = 80;
+	} else {
+		priv->mode &= ~SYN_BIT_HIGH_RATE;
+		psmouse->rate = 40;
+	}
+
+	synaptics_mode_cmd(psmouse, priv->mode);
+}
+
 /*****************************************************************************
  *	Synaptics pass-through PS/2 port support
  ****************************************************************************/
@@ -219,7 +234,7 @@
 
 	if (psmouse_sliced_command(parent, c))
 		return -1;
-	if (psmouse_command(parent, &rate_param, PSMOUSE_CMD_SETRATE))
+	if (ps2_command(&parent->ps2dev, &rate_param, PSMOUSE_CMD_SETRATE))
 		return -1;
 	return 0;
 }
@@ -245,12 +260,18 @@
 
 static void synaptics_pt_activate(struct psmouse *psmouse)
 {
-	struct psmouse *child = psmouse->serio->child->private;
+	struct psmouse *child = psmouse->ps2dev.serio->child->private;
+	struct synaptics_data *priv = psmouse->private;
 
 	/* adjust the touchpad to child's choice of protocol */
-	if (child && child->type >= PSMOUSE_GENPS) {
-		if (synaptics_set_mode(psmouse, SYN_BIT_FOUR_BYTE_CLIENT))
-			printk(KERN_INFO "synaptics: failed to enable 4-byte guest protocol\n");
+	if (child) {
+		if (child->type >= PSMOUSE_GENPS)
+			priv->mode |= SYN_BIT_FOUR_BYTE_CLIENT;
+		else
+			priv->mode &= ~SYN_BIT_FOUR_BYTE_CLIENT;
+
+		if (synaptics_mode_cmd(psmouse, priv->mode))
+			printk(KERN_INFO "synaptics: failed to switch guest protocol\n");
 	}
 }
 
@@ -270,11 +291,11 @@
 	strlcpy(serio->name, "Synaptics pass-through", sizeof(serio->name));
 	strlcpy(serio->phys, "synaptics-pt/serio0", sizeof(serio->name));
 	serio->write = synaptics_pt_write;
-	serio->parent = psmouse->serio;
+	serio->parent = psmouse->ps2dev.serio;
 
 	psmouse->pt_activate = synaptics_pt_activate;
 
-	psmouse->serio->child = serio;
+	psmouse->ps2dev.serio->child = serio;
 }
 
 /*****************************************************************************
@@ -470,8 +491,8 @@
 			priv->pkt_type = synaptics_detect_pkt_type(psmouse);
 
 		if (SYN_CAP_PASS_THROUGH(priv->capabilities) && synaptics_is_pt_packet(psmouse->packet)) {
-			if (psmouse->serio->child)
-				synaptics_pass_pt_packet(psmouse->serio->child, psmouse->packet);
+			if (psmouse->ps2dev.serio->child)
+				synaptics_pass_pt_packet(psmouse->ps2dev.serio->child, psmouse->packet);
 		} else
 			synaptics_process_packet(psmouse);
 
@@ -537,7 +558,7 @@
 	struct synaptics_data *priv = psmouse->private;
 	struct synaptics_data old_priv = *priv;
 
-	if (!synaptics_detect(psmouse))
+	if (synaptics_detect(psmouse, 0))
 		return -1;
 
 	if (synaptics_query_hardware(psmouse)) {
@@ -551,7 +572,7 @@
 	    old_priv.ext_cap != priv->ext_cap)
 		return -1;
 
-	if (synaptics_set_mode(psmouse, 0)) {
+	if (synaptics_set_absolute_mode(psmouse)) {
 		printk(KERN_ERR "Unable to initialize Synaptics hardware.\n");
 		return -1;
 	}
@@ -559,19 +580,28 @@
 	return 0;
 }
 
-int synaptics_detect(struct psmouse *psmouse)
+int synaptics_detect(struct psmouse *psmouse, int set_properties)
 {
+	struct ps2dev *ps2dev = &psmouse->ps2dev;
 	unsigned char param[4];
 
 	param[0] = 0;
 
-	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
-	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
-	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
-	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
-	psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO);
+	ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
+	ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
+	ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
+	ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
+	ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO);
+
+	if (param[1] != 0x47)
+		return -1;
+
+	if (set_properties) {
+		psmouse->vendor = "Synaptics";
+		psmouse->name = "TouchPad";
+	}
 
-	return param[1] == 0x47;
+	return 0;
 }
 
 int synaptics_init(struct psmouse *psmouse)
@@ -588,7 +618,7 @@
 		goto init_fail;
 	}
 
-	if (synaptics_set_mode(psmouse, 0)) {
+	if (synaptics_set_absolute_mode(psmouse)) {
 		printk(KERN_ERR "Unable to initialize Synaptics hardware.\n");
 		goto init_fail;
 	}
@@ -602,8 +632,10 @@
 	set_input_params(&psmouse->dev, priv);
 
 	psmouse->protocol_handler = synaptics_process_byte;
+	psmouse->set_rate = synaptics_set_rate;
 	psmouse->disconnect = synaptics_disconnect;
 	psmouse->reconnect = synaptics_reconnect;
+	psmouse->pktsize = 6;
 
 	return 0;
 
diff -Nru a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h
--- a/drivers/input/mouse/synaptics.h	2005-03-01 23:38:57 -08:00
+++ b/drivers/input/mouse/synaptics.h	2005-03-01 23:38:57 -08:00
@@ -9,7 +9,7 @@
 #ifndef _SYNAPTICS_H
 #define _SYNAPTICS_H
 
-extern int synaptics_detect(struct psmouse *psmouse);
+extern int synaptics_detect(struct psmouse *psmouse, int set_properties);
 extern int synaptics_init(struct psmouse *psmouse);
 extern void synaptics_reset(struct psmouse *psmouse);
 
@@ -101,9 +101,8 @@
 	unsigned long int ext_cap; 		/* Extended Capabilities */
 	unsigned long int identity;		/* Identification */
 
-	/* Data for normal processing */
-	int old_w;				/* Previous w value */
 	unsigned char pkt_type;			/* packet type - old, new, etc */
+	unsigned char mode;			/* current mode byte */
 };
 
 #endif /* _SYNAPTICS_H */
diff -Nru a/drivers/input/mouse/vsxxxaa.c b/drivers/input/mouse/vsxxxaa.c
--- a/drivers/input/mouse/vsxxxaa.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/input/mouse/vsxxxaa.c	2005-03-01 23:39:18 -08:00
@@ -1,11 +1,14 @@
 /*
- * DEC VSXXX-AA and VSXXX-GA mouse driver.
+ * 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)
  *
  * Copyright (C) 2003-2004 by Jan-Benedict Glaw <jbglaw@lug-owl.de>
  *
- * The packet format was taken from a patch to GPM which is (C) 2001
+ * The packet format was initially taken from a patch to GPM which is (C) 2001
  * by	Karsten Merker <merker@linuxtag.org>
  * and	Maciej W. Rozycki <macro@ds2.pg.gda.pl>
+ * Later on, I had access to the device's documentation (referenced below).
  */
 
 /*
@@ -25,7 +28,7 @@
  */
 
 /*
- * Building an adaptor to DB9 / DB25 RS232
+ * Building an adaptor to DE9 / DB25 RS232
  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  *
  * DISCLAIMER: Use this description AT YOUR OWN RISK! I'll not pay for
@@ -42,8 +45,8 @@
  *  | 4 --- 3 |
  *   \  2 1  /
  *    -------
- * 
- *	DEC socket	DB9	DB25	Note
+ *
+ *	DEC socket	DE9	DB25	Note
  *	1 (GND)		5	7	-
  *	2 (RxD)		2	3	-
  *	3 (TxD)		3	2	-
@@ -82,7 +85,7 @@
 #include <linux/serio.h>
 #include <linux/init.h>
 
-#define DRIVER_DESC	"Serial DEC VSXXX-AA/GA mouse / DEC tablet driver"
+#define DRIVER_DESC "Driver for DEC VSXXX-AA and -GA mice and VSXXX-AB tablet"
 
 MODULE_AUTHOR ("Jan-Benedict Glaw <jbglaw@lug-owl.de>");
 MODULE_DESCRIPTION (DRIVER_DESC);
@@ -104,7 +107,7 @@
 #define VSXXXAA_PACKET_REL	0x80
 #define VSXXXAA_PACKET_ABS	0xc0
 #define VSXXXAA_PACKET_POR	0xa0
-#define MATCH_PACKET_TYPE(data, type)	(((data) & VSXXXAA_PACKET_MASK) == type)
+#define MATCH_PACKET_TYPE(data, type)	(((data) & VSXXXAA_PACKET_MASK) == (type))
 
 
 
@@ -150,7 +153,7 @@
 {
 	switch (mouse->type) {
 		case 0x02:
-			sprintf (mouse->name, "DEC VSXXX-AA/GA mouse");
+			sprintf (mouse->name, "DEC VSXXX-AA/-GA mouse");
 			break;
 
 		case 0x04:
@@ -158,7 +161,8 @@
 			break;
 
 		default:
-			sprintf (mouse->name, "unknown DEC pointer device");
+			sprintf (mouse->name, "unknown DEC pointer device "
+					"(type = 0x%02x)", mouse->type);
 			break;
 	}
 
@@ -336,13 +340,10 @@
 	 *
 	 * M: manufacturer location code
 	 * R: revision code
-	 * E: Error code. I'm not sure about these, but gpm's sources,
-	 *    which support this mouse, too, tell about them:
-	 *	E = [0x00 .. 0x1f]: no error, byte #3 is button state
-	 *	E = 0x3d: button error, byte #3 tells which one.
-	 *	E = <else>: other error
+	 * E: Error code. If it's in the range of 0x00..0x1f, only some
+	 *    minor problem occured. Errors >= 0x20 are considered bad
+	 *    and the device may not work properly...
 	 * D: <0010> == mouse, <0100> == tablet
-	 *
 	 */
 
 	mouse->version = buf[0] & 0x0f;
@@ -363,28 +364,32 @@
 	vsxxxaa_detection_done (mouse);
 
 	if (error <= 0x1f) {
-		/* No error. Report buttons */
+		/* No (serious) error. Report buttons */
 		input_regs (dev, regs);
 		input_report_key (dev, BTN_LEFT, left);
 		input_report_key (dev, BTN_MIDDLE, middle);
 		input_report_key (dev, BTN_RIGHT, right);
 		input_report_key (dev, BTN_TOUCH, 0);
 		input_sync (dev);
-	} else {
-		printk (KERN_ERR "Your %s on %s reports an undefined error, "
-				"please check it...\n", mouse->name,
-				mouse->phys);
+
+		if (error != 0)
+			printk (KERN_INFO "Your %s on %s reports error=0x%02x\n",
+					mouse->name, mouse->phys, error);
+
 	}
 
 	/*
 	 * If the mouse was hot-plugged, we need to force differential mode
 	 * now... However, give it a second to recover from it's reset.
 	 */
-	printk (KERN_NOTICE "%s on %s: Forceing standard packet format and "
-			"streaming mode\n", mouse->name, mouse->phys);
-	mouse->serio->write (mouse->serio, 'S');
+	printk (KERN_NOTICE "%s on %s: Forceing standard packet format, "
+			"incremental streaming mode and 72 samples/sec\n",
+			mouse->name, mouse->phys);
+	mouse->serio->write (mouse->serio, 'S');	/* Standard format */
+	mdelay (50);
+	mouse->serio->write (mouse->serio, 'R');	/* Incremental */
 	mdelay (50);
-	mouse->serio->write (mouse->serio, 'R');
+	mouse->serio->write (mouse->serio, 'L');	/* 72 samples/sec */
 }
 
 static void
@@ -519,11 +524,12 @@
 	mouse->dev.private = mouse;
 	serio->private = mouse;
 
-	sprintf (mouse->name, "DEC VSXXX-AA/GA mouse or VSXXX-AB digitizer");
+	sprintf (mouse->name, "DEC VSXXX-AA/-GA mouse or VSXXX-AB digitizer");
 	sprintf (mouse->phys, "%s/input0", serio->phys);
 	mouse->dev.name = mouse->name;
 	mouse->dev.phys = mouse->phys;
 	mouse->dev.id.bustype = BUS_RS232;
+	mouse->dev.dev = &serio->dev;
 	mouse->serio = serio;
 
 	if (serio_open (serio, drv)) {
diff -Nru a/drivers/input/mousedev.c b/drivers/input/mousedev.c
--- a/drivers/input/mousedev.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/input/mousedev.c	2005-03-01 23:39:16 -08:00
@@ -115,20 +115,26 @@
 #define fx(i)  (mousedev->old_x[(mousedev->pkt_count - (i)) & 03])
 #define fy(i)  (mousedev->old_y[(mousedev->pkt_count - (i)) & 03])
 
-static void mousedev_touchpad_event(struct mousedev *mousedev, unsigned int code, int value)
+static void mousedev_touchpad_event(struct input_dev *dev, struct mousedev *mousedev, unsigned int code, int value)
 {
+	int size;
+
 	if (mousedev->touch) {
 		switch (code) {
 			case ABS_X:
+				size = dev->absmax[ABS_X] - dev->absmin[ABS_X];
+				if (size == 0) size = xres;
 				fx(0) = value;
 				if (mousedev->pkt_count >= 2)
-					mousedev->packet.dx = ((fx(0) - fx(1)) / 2 + (fx(1) - fx(2)) / 2) / 8;
+					mousedev->packet.dx = ((fx(0) - fx(1)) / 2 + (fx(1) - fx(2)) / 2) * xres / (size * 2);
 				break;
 
 			case ABS_Y:
+				size = dev->absmax[ABS_Y] - dev->absmin[ABS_Y];
+				if (size == 0) size = yres;
 				fy(0) = value;
 				if (mousedev->pkt_count >= 2)
-					mousedev->packet.dy = -((fy(0) - fy(1)) / 2 + (fy(1) - fy(2)) / 2) / 8;
+					mousedev->packet.dy = -((fy(0) - fy(1)) / 2 + (fy(1) - fy(2)) / 2) * yres / (size * 2);
 				break;
 		}
 	}
@@ -279,7 +285,7 @@
 				return;
 
 			if (test_bit(BTN_TOOL_FINGER, handle->dev->keybit))
-				mousedev_touchpad_event(mousedev, code, value);
+				mousedev_touchpad_event(handle->dev, mousedev, code, value);
 			else
 				mousedev_abs_event(handle->dev, mousedev, code, value);
 
@@ -461,10 +467,10 @@
 	}
 
 	if (!p->dx && !p->dy && !p->dz) {
-		if (list->tail != list->head)
-			list->tail = (list->tail + 1) % PACKET_QUEUE_LEN;
 		if (list->tail == list->head)
 			list->ready = 0;
+		else
+			list->tail = (list->tail + 1) % PACKET_QUEUE_LEN;
 	}
 
 	spin_unlock_irqrestore(&list->packet_lock, flags);
diff -Nru a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig
--- a/drivers/input/serio/Kconfig	2005-03-01 23:38:58 -08:00
+++ b/drivers/input/serio/Kconfig	2005-03-01 23:38:58 -08:00
@@ -131,6 +131,16 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called maceps2.
 
+config SERIO_LIBPS2
+	tristate "PS/2 driver library" if EMBEDDED
+	depends on SERIO
+	help
+	  Say Y here if you are using a driver for device connected
+	  to a PS/2 port, such as PS/2 mouse or standard AT keyboard.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called libps2.
+
 config SERIO_RAW
 	tristate "Raw access to serio ports"
 	depends on SERIO
diff -Nru a/drivers/input/serio/Makefile b/drivers/input/serio/Makefile
--- a/drivers/input/serio/Makefile	2005-03-01 23:38:52 -08:00
+++ b/drivers/input/serio/Makefile	2005-03-01 23:38:52 -08:00
@@ -17,4 +17,5 @@
 obj-$(CONFIG_SERIO_GSCPS2)	+= gscps2.o
 obj-$(CONFIG_SERIO_PCIPS2)	+= pcips2.o
 obj-$(CONFIG_SERIO_MACEPS2)	+= maceps2.o
+obj-$(CONFIG_SERIO_LIBPS2)	+= libps2.o
 obj-$(CONFIG_SERIO_RAW)		+= serio_raw.o
diff -Nru a/drivers/input/serio/ambakmi.c b/drivers/input/serio/ambakmi.c
--- a/drivers/input/serio/ambakmi.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/input/serio/ambakmi.c	2005-03-01 23:39:07 -08:00
@@ -31,7 +31,7 @@
 struct amba_kmi_port {
 	struct serio		*io;
 	struct clk		*clk;
-	unsigned char		*base;
+	void __iomem		*base;
 	unsigned int		irq;
 	unsigned int		divisor;
 	unsigned int		open;
diff -Nru a/drivers/input/serio/gscps2.c b/drivers/input/serio/gscps2.c
--- a/drivers/input/serio/gscps2.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/input/serio/gscps2.c	2005-03-01 23:39:17 -08:00
@@ -322,19 +322,6 @@
 	gscps2_enable(ps2port, DISABLE);
 }
 
-static struct serio gscps2_serio_port =
-{
-	.name =		"GSC PS/2",
-	.idbus =	BUS_GSC,
-	.idvendor =	PCI_VENDOR_ID_HP,
-	.idproduct =	0x0001,
-	.idversion =	0x0010,
-	.type =		SERIO_8042,
-	.write =	gscps2_write,
-	.open =		gscps2_open,
-	.close =	gscps2_close,
-};
-
 /**
  * gscps2_probe() - Probes PS2 devices
  * @return: success/error report
diff -Nru a/drivers/input/serio/i8042-io.h b/drivers/input/serio/i8042-io.h
--- a/drivers/input/serio/i8042-io.h	2005-03-01 23:38:44 -08:00
+++ b/drivers/input/serio/i8042-io.h	2005-03-01 23:38:44 -08:00
@@ -3,7 +3,7 @@
 
 /*
  * 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 
+ * under the terms of the GNU General Public License version 2 as published by
  * the Free Software Foundation.
  */
 
@@ -22,9 +22,6 @@
 #ifdef __alpha__
 # define I8042_KBD_IRQ	1
 # define I8042_AUX_IRQ	(RTC_PORT(0) == 0x170 ? 9 : 12)	/* Jensen is special */
-#elif defined(__ia64__)
-# define I8042_KBD_IRQ isa_irq_to_vector(1)
-# define I8042_AUX_IRQ isa_irq_to_vector(12)
 #elif defined(__arm__)
 /* defined in include/asm-arm/arch-xxx/irqs.h */
 #include <asm/irq.h>
@@ -40,8 +37,8 @@
  * Register numbers.
  */
 
-#define I8042_COMMAND_REG	0x64	
-#define I8042_STATUS_REG	0x64	
+#define I8042_COMMAND_REG	0x64
+#define I8042_STATUS_REG	0x64
 #define I8042_DATA_REG		0x60
 
 static inline int i8042_read_data(void)
@@ -57,59 +54,25 @@
 static inline void i8042_write_data(int val)
 {
 	outb(val, I8042_DATA_REG);
-	return;
 }
 
 static inline void i8042_write_command(int val)
 {
 	outb(val, I8042_COMMAND_REG);
-	return;
 }
 
-#if defined(__i386__)
-
-#include <linux/dmi.h>
-
-static struct dmi_system_id __initdata i8042_dmi_table[] = {
-	{
-		.ident = "Compaq Proliant 8500",
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Compaq"),
-			DMI_MATCH(DMI_PRODUCT_NAME , "ProLiant"),
-			DMI_MATCH(DMI_PRODUCT_VERSION, "8500"),
-		},
-	},
-	{
-		.ident = "Compaq Proliant DL760",
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Compaq"),
-			DMI_MATCH(DMI_PRODUCT_NAME , "ProLiant"),
-			DMI_MATCH(DMI_PRODUCT_VERSION, "DL760"),
-		},
-	},
-	{ }
-};
-#endif
-
 static inline int i8042_platform_init(void)
 {
 /*
- * On ix86 platforms touching the i8042 data register region can do really
- * bad things. Because of this the region is always reserved on ix86 boxes.
+ * On some platforms touching the i8042 data register region can do really
+ * bad things. Because of this the region is always reserved on such boxes.
  */
-#if !defined(__i386__) && !defined(__sh__) && !defined(__alpha__) && !defined(__x86_64__) && !defined(__mips__) && !defined (CONFIG_PPC64)
+#if !defined(__sh__) && !defined(__alpha__) && !defined(__mips__) && !defined(CONFIG_PPC64)
 	if (!request_region(I8042_DATA_REG, 16, "i8042"))
 		return -1;
 #endif
 
-#if !defined(__i386__) && !defined(__x86_64__)
         i8042_reset = 1;
-#endif
-
-#if defined(__i386__)
-	if (dmi_check_system(i8042_dmi_table))
-		i8042_noloop = 1;
-#endif
 
 #if defined(CONFIG_PPC64)
 	if (check_legacy_ioport(I8042_DATA_REG))
@@ -122,7 +85,7 @@
 
 static inline void i8042_platform_exit(void)
 {
-#if !defined(__i386__) && !defined(__sh__) && !defined(__alpha__) && !defined(__x86_64__) && !defined(CONFIG_PPC64)
+#if !defined(__sh__) && !defined(__alpha__) && !defined(CONFIG_PPC64)
 	release_region(I8042_DATA_REG, 16);
 #endif
 }
diff -Nru a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/input/serio/i8042-x86ia64io.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,308 @@
+#ifndef _I8042_X86IA64IO_H
+#define _I8042_X86IA64IO_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.
+ */
+
+/*
+ * Names.
+ */
+
+#define I8042_KBD_PHYS_DESC "isa0060/serio0"
+#define I8042_AUX_PHYS_DESC "isa0060/serio1"
+#define I8042_MUX_PHYS_DESC "isa0060/serio%d"
+
+/*
+ * IRQs.
+ */
+
+#if defined(__ia64__)
+# define I8042_MAP_IRQ(x)	isa_irq_to_vector((x))
+#else
+# define I8042_MAP_IRQ(x)	(x)
+#endif
+
+#define I8042_KBD_IRQ	i8042_kbd_irq
+#define I8042_AUX_IRQ	i8042_aux_irq
+
+static int i8042_kbd_irq;
+static int i8042_aux_irq;
+
+/*
+ * Register numbers.
+ */
+
+#define I8042_COMMAND_REG	i8042_command_reg
+#define I8042_STATUS_REG	i8042_command_reg
+#define I8042_DATA_REG		i8042_data_reg
+
+static int i8042_command_reg = 0x64;
+static int i8042_data_reg = 0x60;
+
+
+static inline int i8042_read_data(void)
+{
+	return inb(I8042_DATA_REG);
+}
+
+static inline int i8042_read_status(void)
+{
+	return inb(I8042_STATUS_REG);
+}
+
+static inline void i8042_write_data(int val)
+{
+	outb(val, I8042_DATA_REG);
+}
+
+static inline void i8042_write_command(int val)
+{
+	outb(val, I8042_COMMAND_REG);
+}
+
+#if defined(__i386__)
+
+#include <linux/dmi.h>
+
+static struct dmi_system_id __initdata i8042_dmi_table[] = {
+	{
+		.ident = "Compaq Proliant 8500",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Compaq"),
+			DMI_MATCH(DMI_PRODUCT_NAME , "ProLiant"),
+			DMI_MATCH(DMI_PRODUCT_VERSION, "8500"),
+		},
+	},
+	{
+		.ident = "Compaq Proliant DL760",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Compaq"),
+			DMI_MATCH(DMI_PRODUCT_NAME , "ProLiant"),
+			DMI_MATCH(DMI_PRODUCT_VERSION, "DL760"),
+		},
+	},
+	{ }
+};
+#endif
+
+#ifdef CONFIG_ACPI
+#include <linux/acpi.h>
+#include <acpi/acpi_bus.h>
+
+struct i8042_acpi_resources {
+	unsigned int port1;
+	unsigned int port2;
+	unsigned int irq;
+};
+
+static int i8042_acpi_kbd_registered;
+static int i8042_acpi_aux_registered;
+
+static acpi_status i8042_acpi_parse_resource(struct acpi_resource *res, void *data)
+{
+	struct i8042_acpi_resources *i8042_res = data;
+	struct acpi_resource_io *io;
+	struct acpi_resource_fixed_io *fixed_io;
+	struct acpi_resource_irq *irq;
+	struct acpi_resource_ext_irq *ext_irq;
+
+	switch (res->id) {
+		case ACPI_RSTYPE_IO:
+			io = &res->data.io;
+			if (io->range_length) {
+				if (!i8042_res->port1)
+					i8042_res->port1 = io->min_base_address;
+				else
+					i8042_res->port2 = io->min_base_address;
+			}
+			break;
+
+		case ACPI_RSTYPE_FIXED_IO:
+			fixed_io = &res->data.fixed_io;
+			if (fixed_io->range_length) {
+				if (!i8042_res->port1)
+					i8042_res->port1 = fixed_io->base_address;
+				else
+					i8042_res->port2 = fixed_io->base_address;
+			}
+			break;
+
+		case ACPI_RSTYPE_IRQ:
+			irq = &res->data.irq;
+			if (irq->number_of_interrupts > 0)
+				i8042_res->irq =
+					acpi_register_gsi(irq->interrupts[0],
+							  irq->edge_level,
+							  irq->active_high_low);
+			break;
+
+		case ACPI_RSTYPE_EXT_IRQ:
+			ext_irq = &res->data.extended_irq;
+			if (ext_irq->number_of_interrupts > 0)
+				i8042_res->irq =
+					acpi_register_gsi(ext_irq->interrupts[0],
+							  ext_irq->edge_level,
+							  ext_irq->active_high_low);
+			break;
+	}
+	return AE_OK;
+}
+
+static int i8042_acpi_kbd_add(struct acpi_device *device)
+{
+	struct i8042_acpi_resources kbd_res;
+	acpi_status status;
+
+	memset(&kbd_res, 0, sizeof(kbd_res));
+	status = acpi_walk_resources(device->handle, METHOD_NAME__CRS,
+				     i8042_acpi_parse_resource, &kbd_res);
+	if (ACPI_FAILURE(status))
+		return -ENODEV;
+
+	if (kbd_res.port1)
+		i8042_data_reg = kbd_res.port1;
+	else
+		printk(KERN_WARNING "ACPI: [%s] has no data port; default is 0x%x\n",
+			acpi_device_bid(device), i8042_data_reg);
+
+	if (kbd_res.port2)
+		i8042_command_reg = kbd_res.port2;
+	else
+		printk(KERN_WARNING "ACPI: [%s] has no command port; default is 0x%x\n",
+			acpi_device_bid(device), i8042_command_reg);
+
+	if (kbd_res.irq)
+		i8042_kbd_irq = kbd_res.irq;
+	else
+		printk(KERN_WARNING "ACPI: [%s] has no IRQ; default is %d\n",
+			acpi_device_bid(device), i8042_kbd_irq);
+
+	strncpy(acpi_device_name(device), "PS/2 Keyboard Controller",
+		sizeof(acpi_device_name(device)));
+	printk("ACPI: %s [%s] at I/O 0x%x, 0x%x, irq %d\n",
+		acpi_device_name(device), acpi_device_bid(device),
+		i8042_data_reg, i8042_command_reg, i8042_kbd_irq);
+
+	return 0;
+}
+
+static int i8042_acpi_aux_add(struct acpi_device *device)
+{
+	struct i8042_acpi_resources aux_res;
+	acpi_status status;
+
+	memset(&aux_res, 0, sizeof(aux_res));
+	status = acpi_walk_resources(device->handle, METHOD_NAME__CRS,
+				     i8042_acpi_parse_resource, &aux_res);
+	if (ACPI_FAILURE(status))
+		return -ENODEV;
+
+	if (aux_res.irq)
+		i8042_aux_irq = aux_res.irq;
+	else
+		printk(KERN_WARNING "ACPI: [%s] has no IRQ; default is %d\n",
+			acpi_device_bid(device), i8042_aux_irq);
+
+	strncpy(acpi_device_name(device), "PS/2 Mouse Controller",
+		sizeof(acpi_device_name(device)));
+	printk("ACPI: %s [%s] at irq %d\n",
+		acpi_device_name(device), acpi_device_bid(device), i8042_aux_irq);
+
+	return 0;
+}
+
+static struct acpi_driver i8042_acpi_kbd_driver = {
+	.name		= "i8042",
+	.ids		= "PNP0303,PNP030B",
+	.ops		= {
+		.add		= i8042_acpi_kbd_add,
+	},
+};
+
+static struct acpi_driver i8042_acpi_aux_driver = {
+	.name		= "i8042",
+	.ids		= "PNP0F03,PNP0F0B,PNP0F0E,PNP0F12,PNP0F13,SYN0801",
+	.ops		= {
+		.add		= i8042_acpi_aux_add,
+	},
+};
+
+static int i8042_acpi_init(void)
+{
+	int result;
+
+	if (acpi_disabled || i8042_noacpi) {
+		printk("i8042: ACPI detection disabled\n");
+		return 0;
+	}
+
+	result = acpi_bus_register_driver(&i8042_acpi_kbd_driver);
+	if (result < 0)
+		return result;
+
+	if (result == 0) {
+		acpi_bus_unregister_driver(&i8042_acpi_kbd_driver);
+		return -ENODEV;
+	}
+	i8042_acpi_kbd_registered = 1;
+
+	result = acpi_bus_register_driver(&i8042_acpi_aux_driver);
+	if (result >= 0)
+		i8042_acpi_aux_registered = 1;
+	if (result == 0)
+		i8042_noaux = 1;
+
+	return 0;
+}
+
+static void i8042_acpi_exit(void)
+{
+	if (i8042_acpi_kbd_registered)
+		acpi_bus_unregister_driver(&i8042_acpi_kbd_driver);
+
+	if (i8042_acpi_aux_registered)
+		acpi_bus_unregister_driver(&i8042_acpi_aux_driver);
+}
+#endif
+
+static inline int i8042_platform_init(void)
+{
+/*
+ * On ix86 platforms touching the i8042 data register region can do really
+ * bad things. Because of this the region is always reserved on ix86 boxes.
+ *
+ *	if (!request_region(I8042_DATA_REG, 16, "i8042"))
+ *		return -1;
+ */
+
+	i8042_kbd_irq = I8042_MAP_IRQ(1);
+	i8042_aux_irq = I8042_MAP_IRQ(12);
+
+#ifdef CONFIG_ACPI
+	if (i8042_acpi_init())
+		return -1;
+#endif
+
+#if defined(__ia64__)
+        i8042_reset = 1;
+#endif
+
+#if defined(__i386__)
+	if (dmi_check_system(i8042_dmi_table))
+		i8042_noloop = 1;
+#endif
+
+	return 0;
+}
+
+static inline void i8042_platform_exit(void)
+{
+#ifdef CONFIG_ACPI
+	i8042_acpi_exit();
+#endif
+}
+
+#endif /* _I8042_X86IA64IO_H */
diff -Nru a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
--- a/drivers/input/serio/i8042.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/input/serio/i8042.c	2005-03-01 23:38:52 -08:00
@@ -16,10 +16,7 @@
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/config.h>
-#include <linux/reboot.h>
 #include <linux/init.h>
-#include <linux/sysdev.h>
-#include <linux/pm.h>
 #include <linux/serio.h>
 #include <linux/err.h>
 
@@ -57,6 +54,19 @@
 module_param_named(noloop, i8042_noloop, bool, 0);
 MODULE_PARM_DESC(dumbkbd, "Disable the AUX Loopback command while probing for the AUX port");
 
+#ifdef CONFIG_ACPI
+static int i8042_noacpi;
+module_param_named(noacpi, i8042_noacpi, bool, 0);
+MODULE_PARM_DESC(noacpi, "Do not use ACPI to detect controller settings");
+#endif
+
+#define DEBUG
+#ifdef DEBUG
+static int i8042_debug;
+module_param_named(debug, i8042_debug, bool, 0600);
+MODULE_PARM_DESC(debug, "Turn i8042 debugging mode on and off");
+#endif
+
 __obsolete_setup("i8042_noaux");
 __obsolete_setup("i8042_nomux");
 __obsolete_setup("i8042_unlock");
@@ -64,10 +74,9 @@
 __obsolete_setup("i8042_direct");
 __obsolete_setup("i8042_dumbkbd");
 
-#undef DEBUG
 #include "i8042.h"
 
-spinlock_t i8042_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(i8042_lock);
 
 struct i8042_values {
 	int irq;
@@ -101,7 +110,6 @@
 static unsigned char i8042_ctr;
 static unsigned char i8042_mux_open;
 static unsigned char i8042_mux_present;
-static struct pm_dev *i8042_pm_dev;
 static struct timer_list i8042_timer;
 static struct platform_device *i8042_platform_device;
 
@@ -450,12 +458,11 @@
 }
 
 /*
- * i8042_enable_mux_mode checks whether the controller has an active
- * multiplexor and puts the chip into Multiplexed (as opposed to
- * Legacy) mode.
+ * i8042_set_mux_mode checks whether the controller has an active
+ * multiplexor and puts the chip into Multiplexed (1) or Legacy (0) mode.
  */
 
-static int i8042_enable_mux_mode(struct i8042_values *values, unsigned char *mux_version)
+static int i8042_set_mux_mode(unsigned int mode, unsigned char *mux_version)
 {
 
 	unsigned char param;
@@ -474,11 +481,11 @@
 	param = 0xf0;
 	if (i8042_command(&param, I8042_CMD_AUX_LOOP) || param != 0x0f)
 		return -1;
-	param = 0x56;
-	if (i8042_command(&param, I8042_CMD_AUX_LOOP) || param != 0xa9)
+	param = mode ? 0x56 : 0xf6;
+	if (i8042_command(&param, I8042_CMD_AUX_LOOP) || param != (mode ? 0xa9 : 0x09))
 		return -1;
-	param = 0xa4;
-	if (i8042_command(&param, I8042_CMD_AUX_LOOP) || param == 0x5b)
+	param = mode ? 0xa4 : 0xa5;
+	if (i8042_command(&param, I8042_CMD_AUX_LOOP) || param == (mode ? 0x5b : 0x5a))
 		return -1;
 
 	if (mux_version)
@@ -532,11 +539,11 @@
 {
 	unsigned char mux_version;
 
-	if (i8042_enable_mux_mode(values, &mux_version))
+	if (i8042_set_mux_mode(1, &mux_version))
 		return -1;
 
-	/* Workaround for broken chips which seem to support MUX, but in reality don't. */
-	/* They all report version 10.12 */
+	/* Workaround for interference with USB Legacy emulation */
+	/* that causes a v10.12 MUX to be found. */
 	if (mux_version == 0xAC)
 		return -1;
 
@@ -766,12 +773,22 @@
  */
 void i8042_controller_reset(void)
 {
-	if (i8042_reset) {
-		unsigned char param;
+	unsigned char param;
+
+/*
+ * Reset the controller if requested.
+ */
 
+	if (i8042_reset)
 		if (i8042_command(&param, I8042_CMD_CTL_TEST))
 			printk(KERN_ERR "i8042.c: i8042 controller reset timeout.\n");
-	}
+
+/*
+ * Disable MUX mode if present.
+ */
+
+	if (i8042_mux_present)
+		i8042_set_mux_mode(0, NULL);
 
 /*
  * Restore the original control register setting.
@@ -852,10 +869,12 @@
  * Here we try to restore the original BIOS settings
  */
 
-static int i8042_controller_suspend(void)
+static int i8042_suspend(struct device *dev, u32 state, u32 level)
 {
-	del_timer_sync(&i8042_timer);
-	i8042_controller_reset();
+	if (level == SUSPEND_DISABLE) {
+		del_timer_sync(&i8042_timer);
+		i8042_controller_reset();
+	}
 
 	return 0;
 }
@@ -865,17 +884,20 @@
  * Here we try to reset everything back to a state in which suspended
  */
 
-static int i8042_controller_resume(void)
+static int i8042_resume(struct device *dev, u32 level)
 {
 	int i;
 
+	if (level != RESUME_ENABLE)
+		return 0;
+
 	if (i8042_controller_init()) {
 		printk(KERN_ERR "i8042: resume failed\n");
 		return -1;
 	}
 
 	if (i8042_mux_present)
-		if (i8042_enable_mux_mode(&i8042_aux_values, NULL) ||
+		if (i8042_set_mux_mode(1, NULL) ||
 		    i8042_enable_mux_ports(&i8042_aux_values)) {
 			printk(KERN_WARNING "i8042: failed to resume active multiplexor, mouse won't work.\n");
 		}
@@ -901,42 +923,14 @@
 	panic_blink = i8042_panic_blink;
 
 	return 0;
-}
 
+}
 
 /*
  * We need to reset the 8042 back to original mode on system shutdown,
  * because otherwise BIOSes will be confused.
  */
 
-static int i8042_notify_sys(struct notifier_block *this, unsigned long code,
-        		    void *unused)
-{
-        if (code == SYS_DOWN || code == SYS_HALT)
-        	i8042_controller_cleanup();
-        return NOTIFY_DONE;
-}
-
-static struct notifier_block i8042_notifier =
-{
-        i8042_notify_sys,
-        NULL,
-        0
-};
-
-/*
- * Suspend/resume handlers for the new PM scheme (driver model)
- */
-static int i8042_suspend(struct device *dev, u32 state, u32 level)
-{
-	return level == SUSPEND_DISABLE ? i8042_controller_suspend() : 0;
-}
-
-static int i8042_resume(struct device *dev, u32 level)
-{
-	return level == RESUME_ENABLE ? i8042_controller_resume() : 0;
-}
-
 static void i8042_shutdown(struct device *dev)
 {
 	i8042_controller_cleanup();
@@ -950,22 +944,6 @@
 	.shutdown	= i8042_shutdown,
 };
 
-/*
- * Suspend/resume handler for the old PM scheme (APM)
- */
-static int i8042_pm_callback(struct pm_dev *dev, pm_request_t request, void *dummy)
-{
-	switch (request) {
-		case PM_SUSPEND:
-			return i8042_controller_suspend();
-
-		case PM_RESUME:
-			return i8042_controller_resume();
-	}
-
-	return 0;
-}
-
 static struct serio * __init i8042_allocate_kbd_port(void)
 {
 	struct serio *serio;
@@ -1080,21 +1058,12 @@
 
 	mod_timer(&i8042_timer, jiffies + I8042_POLL_PERIOD);
 
-	i8042_pm_dev = pm_register(PM_SYS_DEV, PM_SYS_UNKNOWN, i8042_pm_callback);
-
-	register_reboot_notifier(&i8042_notifier);
-
 	return 0;
 }
 
 void __exit i8042_exit(void)
 {
 	int i;
-
-	unregister_reboot_notifier(&i8042_notifier);
-
-	if (i8042_pm_dev)
-		pm_unregister(i8042_pm_dev);
 
 	i8042_controller_cleanup();
 
diff -Nru a/drivers/input/serio/i8042.h b/drivers/input/serio/i8042.h
--- a/drivers/input/serio/i8042.h	2005-03-01 23:39:08 -08:00
+++ b/drivers/input/serio/i8042.h	2005-03-01 23:39:08 -08:00
@@ -15,7 +15,7 @@
  * Arch-dependent inline functions and defines.
  */
 
-#if defined(CONFIG_MIPS_JAZZ)
+#if defined(CONFIG_MACH_JAZZ)
 #include "i8042-jazzio.h"
 #elif defined(CONFIG_SGI_IP22)
 #include "i8042-ip22io.h"
@@ -23,6 +23,8 @@
 #include "i8042-ppcio.h"
 #elif defined(CONFIG_SPARC32) || defined(CONFIG_SPARC64)
 #include "i8042-sparcio.h"
+#elif defined(CONFIG_X86) || defined(CONFIG_IA64)
+#include "i8042-x86ia64io.h"
 #else
 #include "i8042-io.h"
 #endif
@@ -117,8 +119,12 @@
 #ifdef DEBUG
 static unsigned long i8042_start;
 #define dbg_init() do { i8042_start = jiffies; } while (0)
-#define dbg(format, arg...) printk(KERN_DEBUG __FILE__ ": " format " [%d]\n" ,\
-	 ## arg, (int) (jiffies - i8042_start))
+#define dbg(format, arg...) 							\
+	do { 									\
+		if (i8042_debug)						\
+			printk(KERN_DEBUG __FILE__ ": " format " [%d]\n" ,	\
+	 			## arg, (int) (jiffies - i8042_start));		\
+	} while (0)
 #else
 #define dbg_init() do { } while (0)
 #define dbg(format, arg...) do {} while (0)
diff -Nru a/drivers/input/serio/libps2.c b/drivers/input/serio/libps2.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/input/serio/libps2.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,305 @@
+/*
+ * PS/2 driver library
+ *
+ * Copyright (c) 1999-2002 Vojtech Pavlik
+ * Copyright (c) 2004 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/delay.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/input.h>
+#include <linux/serio.h>
+#include <linux/init.h>
+#include <linux/libps2.h>
+
+#define DRIVER_DESC	"PS/2 driver library"
+
+MODULE_AUTHOR("Dmitry Torokhov <dtor@mail.ru>");
+MODULE_DESCRIPTION("PS/2 driver library");
+MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(ps2_init);
+EXPORT_SYMBOL(ps2_sendbyte);
+EXPORT_SYMBOL(ps2_command);
+EXPORT_SYMBOL(ps2_schedule_command);
+EXPORT_SYMBOL(ps2_handle_ack);
+EXPORT_SYMBOL(ps2_handle_response);
+EXPORT_SYMBOL(ps2_cmd_aborted);
+
+/* Work structure to schedule execution of a command */
+struct ps2work {
+	struct work_struct work;
+	struct ps2dev *ps2dev;
+	int command;
+	unsigned char param[0];
+};
+
+
+/*
+ * 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() can only be called from a process context
+ */
+
+int ps2_sendbyte(struct ps2dev *ps2dev, unsigned char byte, int timeout)
+{
+	serio_pause_rx(ps2dev->serio);
+	ps2dev->nak = 1;
+	ps2dev->flags |= PS2_FLAG_ACK;
+	serio_continue_rx(ps2dev->serio);
+
+	if (serio_write(ps2dev->serio, byte) == 0)
+		wait_event_timeout(ps2dev->wait,
+				   !(ps2dev->flags & PS2_FLAG_ACK),
+				   msecs_to_jiffies(timeout));
+
+	serio_pause_rx(ps2dev->serio);
+	ps2dev->flags &= ~PS2_FLAG_ACK;
+	serio_continue_rx(ps2dev->serio);
+
+	return -ps2dev->nak;
+}
+
+/*
+ * ps2_command() sends a command and its parameters to the mouse,
+ * then waits for the response and puts it in the param array.
+ *
+ * ps2_command() can only be called from a process context
+ */
+
+int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command)
+{
+	int timeout;
+	int send = (command >> 12) & 0xf;
+	int receive = (command >> 8) & 0xf;
+	int rc = -1;
+	int i;
+
+	down(&ps2dev->cmd_sem);
+
+	serio_pause_rx(ps2dev->serio);
+	ps2dev->flags = command == PS2_CMD_GETID ? PS2_FLAG_WAITID : 0;
+	ps2dev->cmdcnt = receive;
+	if (receive && param)
+		for (i = 0; i < receive; i++)
+			ps2dev->cmdbuf[(receive - 1) - i] = param[i];
+	serio_continue_rx(ps2dev->serio);
+
+	/*
+	 * Some devices (Synaptics) peform the reset before
+	 * 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;
+
+	for (i = 0; i < send; i++)
+		if (ps2_sendbyte(ps2dev, param[i], 200))
+			goto out;
+
+	/*
+	 * The reset command takes a long time to execute.
+	 */
+	timeout = msecs_to_jiffies(command == PS2_CMD_RESET_BAT ? 4000 : 500);
+
+	timeout = wait_event_timeout(ps2dev->wait,
+				     !(ps2dev->flags & PS2_FLAG_CMD1), timeout);
+
+	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);
+		}
+
+		wait_event_timeout(ps2dev->wait,
+				   !(ps2dev->flags & PS2_FLAG_CMD), timeout);
+	}
+
+	if (param)
+		for (i = 0; i < receive; i++)
+			param[i] = ps2dev->cmdbuf[(receive - 1) - i];
+
+	if (ps2dev->cmdcnt && (command != PS2_CMD_RESET_BAT || ps2dev->cmdcnt != 1))
+		goto out;
+
+	rc = 0;
+
+out:
+	serio_pause_rx(ps2dev->serio);
+	ps2dev->flags = 0;
+	serio_continue_rx(ps2dev->serio);
+
+	up(&ps2dev->cmd_sem);
+	return rc;
+}
+
+/*
+ * ps2_execute_scheduled_command() sends a command, previously scheduled by
+ * ps2_schedule_command(), to a PS/2 device (keyboard, mouse, etc.)
+ */
+
+static void ps2_execute_scheduled_command(void *data)
+{
+	struct ps2work *ps2work = data;
+
+	ps2_command(ps2work->ps2dev, ps2work->param, ps2work->command);
+	kfree(ps2work);
+}
+
+/*
+ * ps2_schedule_command() allows to schedule delayed execution of a PS/2
+ * command and can be used to issue a command from an interrupt or softirq
+ * context.
+ */
+
+int ps2_schedule_command(struct ps2dev *ps2dev, unsigned char *param, int command)
+{
+	struct ps2work *ps2work;
+	int send = (command >> 12) & 0xf;
+	int receive = (command >> 8) & 0xf;
+
+	if (!(ps2work = kmalloc(sizeof(struct ps2work) + max(send, receive), GFP_ATOMIC)))
+		return -1;
+
+	memset(ps2work, 0, sizeof(struct ps2work));
+	ps2work->ps2dev = ps2dev;
+	ps2work->command = command;
+	memcpy(ps2work->param, param, send);
+	INIT_WORK(&ps2work->work, ps2_execute_scheduled_command, ps2work);
+
+	if (!schedule_work(&ps2work->work)) {
+		kfree(ps2work);
+		return -1;
+	}
+
+	return 0;
+}
+
+/*
+ * ps2_init() initializes ps2dev structure
+ */
+
+void ps2_init(struct ps2dev *ps2dev, struct serio *serio)
+{
+	init_MUTEX(&ps2dev->cmd_sem);
+	init_waitqueue_head(&ps2dev->wait);
+	ps2dev->serio = serio;
+}
+
+/*
+ * ps2_handle_ack() is supposed to be used in interrupt handler
+ * to properly process ACK/NAK of a command from a PS/2 device.
+ */
+
+int ps2_handle_ack(struct ps2dev *ps2dev, unsigned char data)
+{
+	switch (data) {
+		case PS2_RET_ACK:
+			ps2dev->nak = 0;
+			break;
+
+		case PS2_RET_NAK:
+			ps2dev->nak = 1;
+			break;
+
+		/*
+		 * Workaround for mice which don't ACK the Get ID command.
+		 * These are valid mouse IDs that we recognize.
+		 */
+		case 0x00:
+		case 0x03:
+		case 0x04:
+			if (ps2dev->flags & PS2_FLAG_WAITID) {
+				ps2dev->nak = 0;
+				break;
+			}
+			/* Fall through */
+		default:
+			return 0;
+	}
+
+
+	if (!ps2dev->nak && ps2dev->cmdcnt)
+		ps2dev->flags |= PS2_FLAG_CMD | PS2_FLAG_CMD1;
+
+	ps2dev->flags &= ~PS2_FLAG_ACK;
+	wake_up(&ps2dev->wait);
+
+	if (data != PS2_RET_ACK)
+		ps2_handle_response(ps2dev, data);
+
+	return 1;
+}
+
+/*
+ * ps2_handle_response() is supposed to be used in interrupt handler
+ * to properly store device's response to a command and notify process
+ * waiting for completion of the command.
+ */
+
+int ps2_handle_response(struct ps2dev *ps2dev, unsigned char data)
+{
+	if (ps2dev->cmdcnt)
+		ps2dev->cmdbuf[--ps2dev->cmdcnt] = data;
+
+	if (ps2dev->flags & PS2_FLAG_CMD1) {
+		ps2dev->flags &= ~PS2_FLAG_CMD1;
+		if (ps2dev->cmdcnt)
+			wake_up(&ps2dev->wait);
+	}
+
+	if (!ps2dev->cmdcnt) {
+		ps2dev->flags &= ~PS2_FLAG_CMD;
+		wake_up(&ps2dev->wait);
+	}
+
+	return 1;
+}
+
+void ps2_cmd_aborted(struct ps2dev *ps2dev)
+{
+	if (ps2dev->flags & PS2_FLAG_ACK)
+		ps2dev->nak = 1;
+
+	if (ps2dev->flags & (PS2_FLAG_ACK | PS2_FLAG_CMD))
+		wake_up(&ps2dev->wait);
+
+	ps2dev->flags = 0;
+}
+
diff -Nru a/drivers/input/serio/maceps2.c b/drivers/input/serio/maceps2.c
--- a/drivers/input/serio/maceps2.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/input/serio/maceps2.c	2005-03-01 23:38:55 -08:00
@@ -62,8 +62,8 @@
 	unsigned int timeout = MACE_PS2_TIMEOUT;
 
 	do {
-		if (mace_read(port->status) & PS2_STATUS_TX_EMPTY) {
-			mace_write(val, port->tx);
+		if (port->status & PS2_STATUS_TX_EMPTY) {
+			port->tx = val;
 			return 0;
 		}
 		udelay(50);
@@ -72,14 +72,15 @@
 	return -1;
 }
 
-static irqreturn_t maceps2_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t maceps2_interrupt(int irq, void *dev_id,
+				     struct pt_regs *regs)
 {
 	struct serio *dev = dev_id;
 	struct mace_ps2port *port = ((struct maceps2_data *)dev->port_data)->port;
-	unsigned int byte;
+	unsigned long byte;
 
-	if (mace_read(port->status) & PS2_STATUS_RX_FULL) {
-		byte = mace_read(port->rx);
+	if (port->status & PS2_STATUS_RX_FULL) {
+		byte = port->rx;
 		serio_interrupt(dev, byte & 0xff, 0, regs);
         }
 
@@ -90,19 +91,19 @@
 {
 	struct maceps2_data *data = (struct maceps2_data *)dev->port_data;
 
-	if (request_irq(data->irq, maceps2_interrupt, 0, "PS/2 port", dev)) {
+	if (request_irq(data->irq, maceps2_interrupt, 0, "PS2 port", dev)) {
 		printk(KERN_ERR "Could not allocate PS/2 IRQ\n");
 		return -EBUSY;
 	}
 
 	/* Reset port */
-	mace_write(PS2_CONTROL_TX_CLOCK_DISABLE | PS2_CONTROL_RESET,
-		   data->port->control);
+	data->port->control = PS2_CONTROL_TX_CLOCK_DISABLE | PS2_CONTROL_RESET;
 	udelay(100);
 
         /* Enable interrupts */
-	mace_write(PS2_CONTROL_RX_CLOCK_ENABLE | PS2_CONTROL_TX_ENABLE |
-		   PS2_CONTROL_RX_INT_ENABLE, data->port->control);
+	data->port->control = PS2_CONTROL_RX_CLOCK_ENABLE |
+			      PS2_CONTROL_TX_ENABLE |
+			      PS2_CONTROL_RX_INT_ENABLE;
 
 	return 0;
 }
@@ -111,8 +112,7 @@
 {
 	struct maceps2_data *data = (struct maceps2_data *)dev->port_data;
 
-	mace_write(PS2_CONTROL_TX_CLOCK_DISABLE | PS2_CONTROL_RESET,
-		   data->port->control);
+	data->port->control = PS2_CONTROL_TX_CLOCK_DISABLE | PS2_CONTROL_RESET;
 	udelay(100);
 	free_irq(data->irq, dev);
 }
diff -Nru a/drivers/input/serio/parkbd.c b/drivers/input/serio/parkbd.c
--- a/drivers/input/serio/parkbd.c	2005-03-01 23:38:51 -08:00
+++ b/drivers/input/serio/parkbd.c	2005-03-01 23:38:51 -08:00
@@ -37,15 +37,17 @@
 MODULE_DESCRIPTION("Parallel port to Keyboard port adapter driver");
 MODULE_LICENSE("GPL");
 
-MODULE_PARM(parkbd, "1i");
-MODULE_PARM(parkbd_mode, "1i");
+static unsigned int parkbd_pp_no;
+module_param_named(port, parkbd_pp_no, int, 0);
+MODULE_PARM_DESC(port, "Parallel port the adapter is connected to (default is 0)");
+
+static unsigned int parkbd_mode = SERIO_8042;
+module_param_named(mode, parkbd_mode, uint, 0);
+MODULE_PARM_DESC(mode, "Mode of operation: XT = 0/AT = 1 (default)");
 
 #define PARKBD_CLOCK	0x01	/* Strobe & Ack */
 #define PARKBD_DATA	0x02	/* AutoFd & Busy */
 
-static int parkbd;
-static int parkbd_mode = SERIO_8042;
-
 static int parkbd_buffer;
 static int parkbd_counter;
 static unsigned long parkbd_last;
@@ -126,12 +128,7 @@
 {
 	struct parport *pp;
 
-	if (parkbd < 0) {
-		printk(KERN_ERR "parkbd: no port specified\n");
-		return -ENODEV;
-	}
-
-	pp = parport_find_number(parkbd);
+	pp = parport_find_number(parkbd_pp_no);
 
 	if (pp == NULL) {
 		printk(KERN_ERR "parkbd: no such parport\n");
diff -Nru a/drivers/input/serio/q40kbd.c b/drivers/input/serio/q40kbd.c
--- a/drivers/input/serio/q40kbd.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/input/serio/q40kbd.c	2005-03-01 23:38:54 -08:00
@@ -48,7 +48,7 @@
 MODULE_DESCRIPTION("Q40 PS/2 keyboard controller driver");
 MODULE_LICENSE("GPL");
 
-spinlock_t q40kbd_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(q40kbd_lock);
 static struct serio *q40kbd_port;
 static struct platform_device *q40kbd_device;
 
diff -Nru a/drivers/input/serio/sa1111ps2.c b/drivers/input/serio/sa1111ps2.c
--- a/drivers/input/serio/sa1111ps2.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/input/serio/sa1111ps2.c	2005-03-01 23:39:18 -08:00
@@ -28,7 +28,7 @@
 struct ps2if {
 	struct serio		*io;
 	struct sa1111_dev	*dev;
-	unsigned long		base;
+	void __iomem		*base;
 	unsigned int		open;
 	spinlock_t		lock;
 	unsigned int		head;
@@ -272,7 +272,7 @@
 	/*
 	 * Our parent device has already mapped the region.
 	 */
-	ps2if->base = (unsigned long)dev->mapbase;
+	ps2if->base = dev->mapbase;
 
 	sa1111_enable_device(ps2if->dev);
 
diff -Nru a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
--- a/drivers/input/serio/serio.c	2005-03-01 23:38:51 -08:00
+++ b/drivers/input/serio/serio.c	2005-03-01 23:38:51 -08:00
@@ -34,7 +34,6 @@
 #include <linux/completion.h>
 #include <linux/sched.h>
 #include <linux/smp_lock.h>
-#include <linux/suspend.h>
 #include <linux/slab.h>
 
 MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
@@ -114,7 +113,7 @@
 	SERIO_UNREGISTER_PORT,
 };
 
-static spinlock_t serio_event_lock = SPIN_LOCK_UNLOCKED;	/* protects serio_event_list */
+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);
@@ -225,8 +224,7 @@
 	do {
 		serio_handle_events();
 		wait_event_interruptible(serio_wait, !list_empty(&serio_event_list));
-		if (current->flags & PF_FREEZE)
-			refrigerator(PF_FREEZE);
+		try_to_freeze(PF_FREEZE);
 	} while (!signal_pending(current));
 
 	printk(KERN_DEBUG "serio: kseriod exiting\n");
@@ -321,6 +319,7 @@
 	try_module_get(THIS_MODULE);
 
 	spin_lock_init(&serio->lock);
+	init_MUTEX(&serio->drv_sem);
 	list_add_tail(&serio->node, &serio_list);
 	snprintf(serio->dev.bus_id, sizeof(serio->dev.bus_id), "serio%d", serio_no++);
 	serio->dev.bus = &serio_bus;
@@ -590,17 +589,22 @@
 	up(&serio_sem);
 }
 
-/* called from serio_driver->connect/disconnect methods under serio_sem */
-int serio_open(struct serio *serio, struct serio_driver *drv)
+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);
+}
+
+/* called from serio_driver->connect/disconnect methods under serio_sem */
+int serio_open(struct serio *serio, struct serio_driver *drv)
+{
+	serio_set_drv(serio, drv);
 
 	if (serio->open && serio->open(serio)) {
-		serio_pause_rx(serio);
-		serio->drv = NULL;
-		serio_continue_rx(serio);
+		serio_set_drv(serio, NULL);
 		return -1;
 	}
 	return 0;
@@ -612,9 +616,7 @@
 	if (serio->close)
 		serio->close(serio);
 
-	serio_pause_rx(serio);
-	serio->drv = NULL;
-	serio_continue_rx(serio);
+	serio_set_drv(serio, NULL);
 }
 
 irqreturn_t serio_interrupt(struct serio *serio,
diff -Nru a/drivers/input/serio/serport.c b/drivers/input/serio/serport.c
--- a/drivers/input/serio/serport.c	2005-03-01 23:39:10 -08:00
+++ b/drivers/input/serio/serport.c	2005-03-01 23:39:10 -08:00
@@ -64,6 +64,9 @@
 	struct serio *serio;
 	char name[64];
 
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
 	serport = kmalloc(sizeof(struct serport), GFP_KERNEL);
 	serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
 	if (unlikely(!serport || !serio)) {
diff -Nru a/drivers/input/touchscreen/h3600_ts_input.c b/drivers/input/touchscreen/h3600_ts_input.c
--- a/drivers/input/touchscreen/h3600_ts_input.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/input/touchscreen/h3600_ts_input.c	2005-03-01 23:39:09 -08:00
@@ -100,6 +100,7 @@
  */
 struct h3600_dev {
 	struct input_dev dev;
+	struct pm_dev *pm_dev;
 	struct serio *serio;
 	unsigned char event;	/* event ID from packet */
 	unsigned char chksum;
@@ -452,8 +453,8 @@
 
 	//h3600_flite_control(1, 25);     /* default brightness */
 #ifdef CONFIG_PM
-	ts->dev.pm_dev = pm_register(PM_ILLUMINATION_DEV, PM_SYS_LIGHT,
-					h3600ts_pm_callback);
+	ts->pm_dev = pm_register(PM_ILLUMINATION_DEV, PM_SYS_LIGHT,
+				h3600ts_pm_callback);
 	printk("registered pm callback\n");
 #endif
 	input_register_device(&ts->dev);
diff -Nru a/drivers/isdn/act2000/module.c b/drivers/isdn/act2000/module.c
--- a/drivers/isdn/act2000/module.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/isdn/act2000/module.c	2005-03-01 23:39:08 -08:00
@@ -40,10 +40,10 @@
 MODULE_PARM_DESC(membase, "Base port address of first card");
 MODULE_PARM_DESC(act_irq, "IRQ of first card");
 MODULE_PARM_DESC(act_id,  "ID-String of first card");
-MODULE_PARM(act_bus,  "i");
-MODULE_PARM(act_port, "i");
-MODULE_PARM(act_irq,  "i");
-MODULE_PARM(act_id,   "s");
+module_param(act_bus,  int, 0);
+module_param(act_port, int, 0);
+module_param(act_irq, int, 0);
+module_param(act_id, charp, 0);
 
 static int act2000_addcard(int, int, int, char *);
 
diff -Nru a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c
--- a/drivers/isdn/capi/capi.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/isdn/capi/capi.c	2005-03-01 23:39:16 -08:00
@@ -143,11 +143,11 @@
 
 /* -------- global variables ---------------------------------------- */
 
-static rwlock_t capidev_list_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(capidev_list_lock);
 static LIST_HEAD(capidev_list);
 
 #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
-static rwlock_t capiminor_list_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(capiminor_list_lock);
 static LIST_HEAD(capiminor_list);
 #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
 
diff -Nru a/drivers/isdn/capi/capidrv.c b/drivers/isdn/capi/capidrv.c
--- a/drivers/isdn/capi/capidrv.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/isdn/capi/capidrv.c	2005-03-01 23:38:56 -08:00
@@ -140,7 +140,7 @@
 /* -------- data definitions ----------------------------------------- */
 
 static capidrv_data global;
-static spinlock_t global_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(global_lock);
 
 static void handle_dtrace_data(capidrv_contr *card,
 	int send, int level2, u8 *data, u16 len);
diff -Nru a/drivers/isdn/capi/capifs.c b/drivers/isdn/capi/capifs.c
--- a/drivers/isdn/capi/capifs.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/isdn/capi/capifs.c	2005-03-01 23:38:54 -08:00
@@ -93,6 +93,7 @@
 	s->s_blocksize_bits = 10;
 	s->s_magic = CAPIFS_SUPER_MAGIC;
 	s->s_op = &capifs_sops;
+	s->s_time_gran = 1;
 
 	inode = new_inode(s);
 	if (!inode)
diff -Nru a/drivers/isdn/capi/kcapi.c b/drivers/isdn/capi/kcapi.c
--- a/drivers/isdn/capi/kcapi.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/isdn/capi/kcapi.c	2005-03-01 23:39:09 -08:00
@@ -63,9 +63,9 @@
 #define NCCI2CTRL(ncci)    (((ncci) >> 24) & 0x7f)
 
 LIST_HEAD(capi_drivers);
-rwlock_t capi_drivers_list_lock = RW_LOCK_UNLOCKED;
+DEFINE_RWLOCK(capi_drivers_list_lock);
 
-static rwlock_t application_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(application_lock);
 static DECLARE_MUTEX(controller_sem);
 
 struct capi20_appl *capi_applications[CAPI_MAXAPPL];
diff -Nru a/drivers/isdn/divert/divert_procfs.c b/drivers/isdn/divert/divert_procfs.c
--- a/drivers/isdn/divert/divert_procfs.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/isdn/divert/divert_procfs.c	2005-03-01 23:39:16 -08:00
@@ -29,7 +29,7 @@
 ulong if_used = 0;		/* number of interface users */
 static struct divert_info *divert_info_head = NULL;	/* head of queue */
 static struct divert_info *divert_info_tail = NULL;	/* pointer to last entry */
-static spinlock_t divert_info_lock = SPIN_LOCK_UNLOCKED;/* lock for queue */
+static DEFINE_SPINLOCK(divert_info_lock);/* lock for queue */
 static wait_queue_head_t rd_queue;
 
 /*********************************/
diff -Nru a/drivers/isdn/divert/isdn_divert.c b/drivers/isdn/divert/isdn_divert.c
--- a/drivers/isdn/divert/isdn_divert.c	2005-03-01 23:38:59 -08:00
+++ b/drivers/isdn/divert/isdn_divert.c	2005-03-01 23:38:59 -08:00
@@ -48,7 +48,7 @@
 static struct deflect_struc *table_tail = NULL; 
 static unsigned char extern_wait_max = 4; /* maximum wait in s for external process */ 
 
-spinlock_t divert_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(divert_lock);
 
 /***************************/
 /* timer callback function */
diff -Nru a/drivers/isdn/hardware/avm/avm_cs.c b/drivers/isdn/hardware/avm/avm_cs.c
--- a/drivers/isdn/hardware/avm/avm_cs.c	2005-03-01 23:38:51 -08:00
+++ b/drivers/isdn/hardware/avm/avm_cs.c	2005-03-01 23:38:51 -08:00
@@ -43,16 +43,6 @@
 
 /*====================================================================*/
 
-/* Parameters that can be set with 'insmod' */
-
-/* This means pick from 15, 12, 11, 10, 9, 7, 5, 4, and 3 */
-static int default_irq_list[10] = { 15, 12, 11, 10, 9, 7, 5, 4, 3, -1 };
-static int irq_list[10] = { -1 };
-
-MODULE_PARM(irq_list, "1-10i");
-
-/*====================================================================*/
-
 /*
    The event() function is this driver's Card Services event handler.
    It will be called by Card Services when an appropriate card status
@@ -134,7 +124,7 @@
     client_reg_t client_reg;
     dev_link_t *link;
     local_info_t *local;
-    int ret, i;
+    int ret;
     
     /* Initialize the dev_link_t structure */
     link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
@@ -151,14 +141,7 @@
     link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
     link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
 
-    link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
-    if (irq_list[0] != -1) {
-	    for (i = 0; i < 10 && irq_list[i] > 0; i++)
-	       link->irq.IRQInfo2 |= 1 << irq_list[i];
-    } else {
-	    for (i = 0; i < 10 && default_irq_list[i] > 0; i++)
-	       link->irq.IRQInfo2 |= 1 << default_irq_list[i];
-    }
+    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
     
     /* General socket configuration */
     link->conf.Attributes = CONF_ENABLE_IRQ;
@@ -178,7 +161,6 @@
     link->next = dev_list;
     dev_list = link;
     client_reg.dev_info = &dev_info;
-    client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
     client_reg.EventMask =
 	CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
 	CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
@@ -521,13 +503,7 @@
 static void __exit avmcs_exit(void)
 {
 	pcmcia_unregister_driver(&avmcs_driver);
-
-	/* XXX: this really needs to move into generic code.. */
-	while (dev_list != NULL) {
-		if (dev_list->state & DEV_CONFIG)
-			avmcs_release(dev_list);
-		avmcs_detach(dev_list);
-	}
+	BUG_ON(dev_list != NULL);
 }
 
 module_init(avmcs_init);
diff -Nru a/drivers/isdn/hardware/avm/avmcard.h b/drivers/isdn/hardware/avm/avmcard.h
--- a/drivers/isdn/hardware/avm/avmcard.h	2005-03-01 23:39:16 -08:00
+++ b/drivers/isdn/hardware/avm/avmcard.h	2005-03-01 23:39:16 -08:00
@@ -89,7 +89,7 @@
 	char msgbuf[128];	/* capimsg msg part */
 	char databuf[2048];	/* capimsg data part */
 
-	void *mbase;
+	void __iomem *mbase;
 	volatile u32 csr;
 	avmcard_dmainfo *dma;
 
diff -Nru a/drivers/isdn/hardware/avm/b1pcmcia.c b/drivers/isdn/hardware/avm/b1pcmcia.c
--- a/drivers/isdn/hardware/avm/b1pcmcia.c	2005-03-01 23:38:43 -08:00
+++ b/drivers/isdn/hardware/avm/b1pcmcia.c	2005-03-01 23:38:43 -08:00
@@ -200,7 +200,6 @@
 {
 	char *p;
 	char rev[32];
-	int err;
 
 	if ((p = strchr(revision, ':')) != 0 && p[1]) {
 		strlcpy(rev, p + 2, 32);
diff -Nru a/drivers/isdn/hardware/eicon/capifunc.c b/drivers/isdn/hardware/eicon/capifunc.c
--- a/drivers/isdn/hardware/eicon/capifunc.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/isdn/hardware/eicon/capifunc.c	2005-03-01 23:39:09 -08:00
@@ -1,4 +1,4 @@
-/* $Id: capifunc.c,v 1.61.4.5 2004/08/27 20:10:12 armin Exp $
+/* $Id: capifunc.c,v 1.61.4.7 2005/02/11 19:40:25 armin Exp $
  *
  * ISDN interface module for Eicon active cards DIVA.
  * CAPI Interface common functions
@@ -64,7 +64,7 @@
  */
 static void no_printf(unsigned char *, ...);
 #include "debuglib.c"
-void xlog(char *x, ...)
+static void xlog(char *x, ...)
 {
 #ifndef DIVA_NO_DEBUGLIB
 	va_list ap;
@@ -157,7 +157,7 @@
 	while (num < MAX_DESCRIPTORS) {
 		a = &adapter[num];
 		if (!a->Id)
-				break;
+			break;
 		num++;
 	}
 	return(num + 1);
@@ -353,7 +353,7 @@
 	if (k == 0) {
 		if (li_config_table) {
 			list_add((struct list_head *)li_config_table, free_mem_q);
-		li_config_table = NULL;
+			li_config_table = NULL;
 		}
 	} else {
 		if (a->li_base < k) {
@@ -1212,7 +1212,7 @@
 void DIVA_EXIT_FUNCTION finit_capifunc(void)
 {
 	do_api_remove_start();
-		    divacapi_disconnect_didd();
+	divacapi_disconnect_didd();
 	divacapi_remove_cards();
 	remove_main_structs();
 	diva_os_destroy_spin_lock(&api_lock, "capifunc");
diff -Nru a/drivers/isdn/hardware/eicon/dadapter.c b/drivers/isdn/hardware/eicon/dadapter.c
--- a/drivers/isdn/hardware/eicon/dadapter.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/isdn/hardware/eicon/dadapter.c	2005-03-01 23:38:56 -08:00
@@ -106,7 +106,7 @@
   return adapter handle (> 0) on success
   return -1 adapter array overflow
   -------------------------------------------------------------------------- */
-int diva_didd_add_descriptor (DESCRIPTOR* d) {
+static int diva_didd_add_descriptor (DESCRIPTOR* d) {
  diva_os_spin_lock_magic_t      irql;
  int i;
  if (d->type == IDI_DIMAINT) {
@@ -143,7 +143,7 @@
   return adapter handle (> 0) on success
   return 0 on success
   -------------------------------------------------------------------------- */
-int diva_didd_remove_descriptor (IDI_CALL request) {
+static int diva_didd_remove_descriptor (IDI_CALL request) {
  diva_os_spin_lock_magic_t      irql;
  int i;
  if (request == MAdapter.request) {
@@ -171,7 +171,7 @@
   Read adapter array
   return 1 if not enough space to save all available adapters
    -------------------------------------------------------------------------- */
-int diva_didd_read_adapter_array (DESCRIPTOR* buffer, int length) {
+static int diva_didd_read_adapter_array (DESCRIPTOR* buffer, int length) {
  diva_os_spin_lock_magic_t      irql;
  int src, dst;
  memset (buffer, 0x00, length);
diff -Nru a/drivers/isdn/hardware/eicon/dadapter.h b/drivers/isdn/hardware/eicon/dadapter.h
--- a/drivers/isdn/hardware/eicon/dadapter.h	2005-03-01 23:39:16 -08:00
+++ b/drivers/isdn/hardware/eicon/dadapter.h	2005-03-01 23:39:16 -08:00
@@ -25,11 +25,10 @@
  */
 #ifndef __DIVA_DIDD_DADAPTER_INC__
 #define __DIVA_DIDD_DADAPTER_INC__
+ 
 void diva_didd_load_time_init (void);
 void diva_didd_load_time_finit (void);
-int diva_didd_add_descriptor (DESCRIPTOR* d);
-int diva_didd_remove_descriptor (IDI_CALL request);
-int diva_didd_read_adapter_array (DESCRIPTOR* buffer, int length);
-#define OLD_MAX_DESCRIPTORS     16
+
 #define NEW_MAX_DESCRIPTORS     64
+
 #endif
diff -Nru a/drivers/isdn/hardware/eicon/di.c b/drivers/isdn/hardware/eicon/di.c
--- a/drivers/isdn/hardware/eicon/di.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/isdn/hardware/eicon/di.c	2005-03-01 23:38:55 -08:00
@@ -42,10 +42,7 @@
 /*------------------------------------------------------------------*/
 void pr_out(ADAPTER * a);
 byte pr_dpc(ADAPTER * a);
-void scom_out(ADAPTER * a);
-byte scom_dpc(ADAPTER * a);
 static byte pr_ready(ADAPTER * a);
-static byte scom_ready(ADAPTER * a);
 static byte isdn_rc(ADAPTER *, byte, byte, byte, word, dword, dword);
 static byte isdn_ind(ADAPTER *, byte, byte, byte, PBUFFER *, byte, word);
 /* -----------------------------------------------------------------
@@ -59,11 +56,11 @@
    ----------------------------------------------------------------- */
 #if defined(XDI_USE_XLOG)
 #define XDI_A_NR(_x_) ((byte)(((ISDN_ADAPTER *)(_x_->io))->ANum))
+static void xdi_xlog (byte *msg, word code, int length);
+static byte xdi_xlog_sec = 0;
 #else
 #define XDI_A_NR(_x_) ((byte)0)
 #endif
-byte xdi_xlog_sec = 0;
-void xdi_xlog (byte *msg, word code, int length);
 static void xdi_xlog_rc_event (byte Adapter,
                                byte Id, byte Ch, byte Rc, byte cb, byte type);
 static void xdi_xlog_request (byte Adapter, byte Id,
@@ -345,192 +342,6 @@
   }
   return FALSE;
 }
-byte pr_test_int(ADAPTER * a)
-{
-  return a->ram_in(a,(void *)0x3ffc);
-}
-void pr_clear_int(ADAPTER * a)
-{
-  a->ram_out(a,(void *)0x3ffc,0);
-}
-/*------------------------------------------------------------------*/
-/* output function                                                  */
-/*------------------------------------------------------------------*/
-void scom_out(ADAPTER * a)
-{
-  byte e_no;
-  ENTITY  * this;
-  BUFFERS  * X;
-  word length;
-  word i;
-  word clength;
-  byte more;
-  byte Id;
-  dtrc(dprintf("scom_out"));
-        /* check if the adapter is ready to accept an request:      */
-  e_no = look_req(a);
-  if(!e_no)
-  {
-    dtrc(dprintf("no_req"));
-    return;
-  }
-  if(!scom_ready(a))
-  {
-    dtrc(dprintf("not_ready"));
-    return;
-  }
-  this = entity_ptr(a,e_no);
-  dtrc(dprintf("out:Req=%x,Id=%x,Ch=%x",this->Req,this->Id,this->ReqCh));
-  next_req(a);
-        /* now copy the data from the current data buffer into the  */
-        /* adapters request buffer                                  */
-  length = 0;
-  i = this->XCurrent;
-  X = PTR_X(a, this);
-  while(i<this->XNum && length<270) {
-    clength = MIN((word)(270-length),X[i].PLength-this->XOffset);
-    a->ram_out_buffer(a,
-                      &RAM->XBuffer.P[length],
-                      PTR_P(a,this,&X[i].P[this->XOffset]),
-                      clength);
-    length +=clength;
-    this->XOffset +=clength;
-    if(this->XOffset==X[i].PLength) {
-      this->XCurrent = (byte)++i;
-      this->XOffset = 0;
-    }
-  }
-  a->ram_outw(a, &RAM->XBuffer.length, length);
-  a->ram_out(a, &RAM->ReqId, this->Id);
-  a->ram_out(a, &RAM->ReqCh, this->ReqCh);
-        /* if it's a specific request (no ASSIGN) ...                */
-  if(this->Id &0x1f) {
-        /* if buffers are left in the list of data buffers do       */
-        /* chaining (LL_MDATA, N_MDATA)                             */
-    this->More++;
-    if(i<this->XNum && this->MInd) {
-      a->ram_out(a, &RAM->Req, this->MInd);
-      more = TRUE;
-    }
-    else {
-      this->More |=XMOREF;
-      a->ram_out(a, &RAM->Req, this->Req);
-      more = FALSE;
-      if (a->FlowControlIdTable[this->ReqCh] == this->Id)
-        a->FlowControlSkipTable[this->ReqCh] = TRUE;
-      /*
-         Note that remove request was sent to the card
-         */
-      if (this->Req == REMOVE) {
-        a->misc_flags_table[e_no] |= DIVA_MISC_FLAGS_REMOVE_PENDING;
-      }
-    }
-    if(more) {
-      req_queue(a,this->No);
-    }
-  }
-        /* else it's a ASSIGN                                       */
-  else {
-        /* save the request code used for buffer chaining           */
-    this->MInd = 0;
-    if (this->Id==BLLC_ID) this->MInd = LL_MDATA;
-    if (this->Id==NL_ID   ||
-        this->Id==TASK_ID ||
-        this->Id==MAN_ID
-      ) this->MInd = N_MDATA;
-        /* send the ASSIGN                                          */
-    this->More |=XMOREF;
-    a->ram_out(a, &RAM->Req, this->Req);
-        /* save the reference of the ASSIGN                         */
-    assign_queue(a, this->No, 0);
-  }
-        /* if it is a 'unreturncoded' UREMOVE request, remove the  */
-        /* Id from our table after sending the request             */
-  if(this->Req==UREMOVE && this->Id) {
-    Id = this->Id;
-    e_no = a->IdTable[Id];
-    free_entity(a, e_no);
-    for (i = 0; i < 256; i++)
-    {
-      if (a->FlowControlIdTable[i] == Id)
-        a->FlowControlIdTable[i] = 0;
-    }
-    a->IdTable[Id] = 0;
-    this->Id = 0;
-  }
-}
-static byte scom_ready(ADAPTER * a)
-{
-  if(a->ram_in(a, &RAM->Req)) {
-    if(!a->ReadyInt) {
-      a->ram_inc(a, &RAM->ReadyInt);
-      a->ReadyInt++;
-    }
-    return 0;
-  }
-  return 1;
-}
-/*------------------------------------------------------------------*/
-/* isdn interrupt handler                                           */
-/*------------------------------------------------------------------*/
-byte scom_dpc(ADAPTER * a)
-{
-  byte c;
-        /* if a return code is available ...                        */
-  if(a->ram_in(a, &RAM->Rc)) {
-        /* call return code handler, if it is not our return code   */
-        /* the handler returns 2, if it's the return code to an     */
-        /* ASSIGN the handler returns 1                             */
-    c = isdn_rc(a,
-                a->ram_in(a, &RAM->Rc),
-                a->ram_in(a, &RAM->RcId),
-                a->ram_in(a, &RAM->RcCh),
-                0,
-                /*
-                  Scom Card does not provide extended information
-                  */
-                0, 0);
-    switch(c) {
-    case 0:
-      a->ram_out(a, &RAM->Rc, 0);
-      break;
-    case 1:
-      a->ram_out(a, &RAM->Req, 0);
-      a->ram_out(a, &RAM->Rc, 0);
-      break;
-    case 2:
-      return TRUE;
-    }
-        /* call output function                                     */
-    scom_out(a);
-  }
-  else {
-        /* if an indications is available ...                       */
-    if(a->ram_in(a, &RAM->Ind)) {
-        /* call indication handler, a return value of 2 means chain */
-        /* a return value of 1 means RNR                            */
-      c = isdn_ind(a,
-                   a->ram_in(a, &RAM->Ind),
-                   a->ram_in(a, &RAM->IndId),
-                   a->ram_in(a, &RAM->IndCh),
-                   &RAM->RBuffer,
-                   a->ram_in(a, &RAM->MInd),
-                   a->ram_inw(a, &RAM->MLength));
-      switch(c) {
-      case 0:
-        a->ram_out(a, &RAM->Ind, 0);
-        break;
-      case 1:
-        dtrc(dprintf("RNR"));
-        a->ram_out(a, &RAM->RNR, TRUE);
-        break;
-      case 2:
-        return TRUE;
-      }
-    }
-  }
-  return FALSE;
-}
 byte scom_test_int(ADAPTER * a)
 {
   return a->ram_in(a,(void *)0x3fe);
@@ -539,11 +350,6 @@
 {
   a->ram_out(a,(void *)0x3fe,0);
 }
-void quadro_clear_int(ADAPTER * a)
-{
-  a->ram_out(a,(void *)0x3fe,0);
-  a->ram_out(a,(void *)0x401,0);
-}
 /*------------------------------------------------------------------*/
 /* return code handler                                              */
 /*------------------------------------------------------------------*/
@@ -914,15 +720,15 @@
   }
   return 2;
 }
+#if defined(XDI_USE_XLOG)
 /* -----------------------------------------------------------
    This function works in the same way as xlog on the
    active board
    ----------------------------------------------------------- */
-void xdi_xlog (byte *msg, word code, int length) {
-#if defined(XDI_USE_XLOG)
+static void xdi_xlog (byte *msg, word code, int length) {
   xdi_dbg_xlog ("\x00\x02", msg, code, length);
-#endif
 }
+#endif
 /* -----------------------------------------------------------
     This function writes the information about the Return Code
     processing in the trace buffer. Trace ID is 221.
diff -Nru a/drivers/isdn/hardware/eicon/di.h b/drivers/isdn/hardware/eicon/di.h
--- a/drivers/isdn/hardware/eicon/di.h	2005-03-01 23:39:08 -08:00
+++ b/drivers/isdn/hardware/eicon/di.h	2005-03-01 23:39:08 -08:00
@@ -81,13 +81,8 @@
 /*------------------------------------------------------------------*/
 void pr_out(ADAPTER * a);
 byte pr_dpc(ADAPTER * a);
-byte pr_test_int(ADAPTER * a);
-void pr_clear_int(ADAPTER * a);
-void scom_out(ADAPTER * a);
-byte scom_dpc(ADAPTER * a);
 byte scom_test_int(ADAPTER * a);
 void scom_clear_int(ADAPTER * a);
-void quadro_clear_int(ADAPTER * a);
 /*------------------------------------------------------------------*/
 /* OS specific functions used by IDI common code                    */
 /*------------------------------------------------------------------*/
diff -Nru a/drivers/isdn/hardware/eicon/diva_didd.c b/drivers/isdn/hardware/eicon/diva_didd.c
--- a/drivers/isdn/hardware/eicon/diva_didd.c	2005-03-01 23:38:59 -08:00
+++ b/drivers/isdn/hardware/eicon/diva_didd.c	2005-03-01 23:38:59 -08:00
@@ -1,4 +1,4 @@
-/* $Id: diva_didd.c,v 1.13.6.1 2004/08/28 20:03:53 armin Exp $
+/* $Id: diva_didd.c,v 1.13.6.4 2005/02/11 19:40:25 armin Exp $
  *
  * DIDD Interface module for Eicon active cards.
  * 
@@ -23,7 +23,7 @@
 #include "divasync.h"
 #include "did_vers.h"
 
-static char *main_revision = "$Revision: 1.13.6.1 $";
+static char *main_revision = "$Revision: 1.13.6.4 $";
 
 static char *DRIVERNAME =
     "Eicon DIVA - DIDD table (http://www.melware.net)";
@@ -140,7 +140,7 @@
 	return (ret);
 }
 
-void DIVA_EXIT_FUNCTION divadidd_exit(void)
+static void DIVA_EXIT_FUNCTION divadidd_exit(void)
 {
 	diddfunc_finit();
 	remove_proc();
diff -Nru a/drivers/isdn/hardware/eicon/divamnt.c b/drivers/isdn/hardware/eicon/divamnt.c
--- a/drivers/isdn/hardware/eicon/divamnt.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/isdn/hardware/eicon/divamnt.c	2005-03-01 23:38:57 -08:00
@@ -1,4 +1,4 @@
-/* $Id: divamnt.c,v 1.32.6.5 2004/08/28 20:03:53 armin Exp $
+/* $Id: divamnt.c,v 1.32.6.10 2005/02/11 19:40:25 armin Exp $
  *
  * Driver for Eicon DIVA Server ISDN cards.
  * Maint module
@@ -18,13 +18,14 @@
 #include <linux/smp_lock.h>
 #include <linux/poll.h>
 #include <linux/devfs_fs_kernel.h>
+#include <asm/uaccess.h>
 
 #include "platform.h"
 #include "di_defs.h"
 #include "divasync.h"
 #include "debug_if.h"
 
-static char *main_revision = "$Revision: 1.32.6.5 $";
+static char *main_revision = "$Revision: 1.32.6.10 $";
 
 static int major;
 
@@ -33,10 +34,10 @@
 MODULE_SUPPORTED_DEVICE("DIVA card driver");
 MODULE_LICENSE("GPL");
 
-int buffer_length = 128;
-MODULE_PARM(buffer_length, "i");
-unsigned long diva_dbg_mem = 0;
-MODULE_PARM(diva_dbg_mem, "l");
+static int buffer_length = 128;
+module_param(buffer_length, int, 0);
+static unsigned long diva_dbg_mem = 0;
+module_param(diva_dbg_mem, ulong, 0);
 
 static char *DRIVERNAME =
     "Eicon DIVA - MAINT module (http://www.melware.net)";
diff -Nru a/drivers/isdn/hardware/eicon/divasi.c b/drivers/isdn/hardware/eicon/divasi.c
--- a/drivers/isdn/hardware/eicon/divasi.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/isdn/hardware/eicon/divasi.c	2005-03-01 23:38:55 -08:00
@@ -1,4 +1,4 @@
-/* $Id: divasi.c,v 1.25 2003/09/09 06:46:29 schindler Exp $
+/* $Id: divasi.c,v 1.25.6.2 2005/01/31 12:22:20 armin Exp $
  *
  * Driver for Eicon DIVA Server ISDN cards.
  * User Mode IDI Interface 
@@ -20,6 +20,7 @@
 #include <linux/proc_fs.h>
 #include <linux/skbuff.h>
 #include <linux/devfs_fs_kernel.h>
+#include <asm/uaccess.h>
 
 #include "platform.h"
 #include "di_defs.h"
@@ -27,7 +28,7 @@
 #include "um_xdi.h"
 #include "um_idi.h"
 
-static char *main_revision = "$Revision: 1.25 $";
+static char *main_revision = "$Revision: 1.25.6.2 $";
 
 static int major;
 
diff -Nru a/drivers/isdn/hardware/eicon/divasmain.c b/drivers/isdn/hardware/eicon/divasmain.c
--- a/drivers/isdn/hardware/eicon/divasmain.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/isdn/hardware/eicon/divasmain.c	2005-03-01 23:38:52 -08:00
@@ -1,4 +1,4 @@
-/* $Id: divasmain.c,v 1.55.4.1 2004/05/21 12:15:00 armin Exp $
+/* $Id: divasmain.c,v 1.55.4.6 2005/02/09 19:28:20 armin Exp $
  *
  * Low level driver for Eicon DIVA Server ISDN cards.
  *
@@ -41,7 +41,7 @@
 #include "diva_dma.h"
 #include "diva_pci.h"
 
-static char *main_revision = "$Revision: 1.55.4.1 $";
+static char *main_revision = "$Revision: 1.55.4.6 $";
 
 static int major;
 
@@ -51,7 +51,7 @@
 MODULE_AUTHOR("Cytronics & Melware, Eicon Networks");
 MODULE_LICENSE("GPL");
 
-MODULE_PARM(dbgmask, "i");
+module_param(dbgmask, int, 0);
 MODULE_PARM_DESC(dbgmask, "initial debug mask");
 
 static char *DRIVERNAME =
@@ -823,7 +823,7 @@
 		goto out;
 	}
 
-	if ((ret = pci_module_init(&diva_pci_driver))) {
+	if ((ret = pci_register_driver(&diva_pci_driver))) {
 #ifdef MODULE
 		remove_divas_proc();
 		divas_unregister_chrdev();
diff -Nru a/drivers/isdn/hardware/eicon/divasproc.c b/drivers/isdn/hardware/eicon/divasproc.c
--- a/drivers/isdn/hardware/eicon/divasproc.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/isdn/hardware/eicon/divasproc.c	2005-03-01 23:39:08 -08:00
@@ -1,4 +1,4 @@
-/* $Id: divasproc.c,v 1.19 2004/03/21 17:26:01 armin Exp $
+/* $Id: divasproc.c,v 1.19.4.3 2005/01/31 12:22:20 armin Exp $
  *
  * Low level driver for Eicon DIVA Server ISDN cards.
  * /proc functions
@@ -16,6 +16,7 @@
 #include <linux/poll.h>
 #include <linux/proc_fs.h>
 #include <linux/list.h>
+#include <asm/uaccess.h>
 
 #include "platform.h"
 #include "debuglib.h"
diff -Nru a/drivers/isdn/hardware/eicon/io.c b/drivers/isdn/hardware/eicon/io.c
--- a/drivers/isdn/hardware/eicon/io.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/isdn/hardware/eicon/io.c	2005-03-01 23:38:54 -08:00
@@ -36,7 +36,7 @@
 extern ADAPTER * adapter[MAX_ADAPTER];
 extern PISDN_ADAPTER IoAdapters[MAX_ADAPTER];
 void request (PISDN_ADAPTER, ENTITY *);
-void pcm_req (PISDN_ADAPTER, ENTITY *);
+static void pcm_req (PISDN_ADAPTER, ENTITY *);
 /* --------------------------------------------------------------------------
   local functions
   -------------------------------------------------------------------------- */
@@ -118,7 +118,8 @@
           &IoAdapter->Name[0]))
 }
 /*****************************************************************************/
-char *(ExceptionCauseTable[]) =
+#if defined(XDI_USE_XLOG)
+static char *(ExceptionCauseTable[]) =
 {
  "Interrupt",
  "TLB mod /IBOUND",
@@ -153,6 +154,7 @@
  "Reserved 30",
  "VCED"
 } ;
+#endif
 void
 dump_trap_frame (PISDN_ADAPTER IoAdapter, byte __iomem *exceptionFrame)
 {
@@ -227,10 +229,6 @@
         if (pI->descriptor_number >= 0) {
           dword dma_magic;
           void* local_addr;
-#if 0
-          DBG_TRC(("A(%d) dma_alloc(%d)",
-                   IoAdapter->ANum, pI->descriptor_number))
-#endif
           diva_get_dma_map_entry (\
                                (struct _diva_dma_map_entry*)IoAdapter->dma_map,
                                pI->descriptor_number,
@@ -243,9 +241,6 @@
         }
       } else if ((pI->operation == IDI_SYNC_REQ_DMA_DESCRIPTOR_FREE) &&
                  (pI->descriptor_number >= 0)) {
-#if 0
-        DBG_TRC(("A(%d) dma_free(%d)", IoAdapter->ANum, pI->descriptor_number))
-#endif
         diva_free_dma_map_entry((struct _diva_dma_map_entry*)IoAdapter->dma_map,
                                 pI->descriptor_number);
         pI->descriptor_number = -1;
@@ -369,9 +364,6 @@
   }
   if ( IoAdapter )
   {
-#if 0
-   DBG_FTL(("xdi: unknown Req 0 / Rc %d !", e->Rc))
-#endif
    return ;
   }
  }
@@ -506,7 +498,7 @@
 /* --------------------------------------------------------------------------
   XLOG interface
   -------------------------------------------------------------------------- */
-void
+static void
 pcm_req (PISDN_ADAPTER IoAdapter, ENTITY *e)
 {
  diva_os_spin_lock_magic_t OldIrql ;
@@ -857,27 +849,4 @@
 {
  if ( e && e->callback )
   e->callback (e) ;
-}
-/* --------------------------------------------------------------------------
-  routines for aligned reading and writing on RISC
-  -------------------------------------------------------------------------- */
-void outp_words_from_buffer (word __iomem * adr, byte* P, dword len)
-{
-  dword i = 0;
-  word w;
-  while (i < (len & 0xfffffffe)) {
-    w = P[i++];
-    w += (P[i++])<<8;
-    outppw (adr, w);
-  }
-}
-void inp_words_to_buffer (word __iomem * adr, byte* P, dword len)
-{
-  dword i = 0;
-  word w;
-  while (i < (len & 0xfffffffe)) {
-    w = inppw (adr);
-    P[i++] = (byte)(w);
-    P[i++] = (byte)(w>>8);
-  }
 }
diff -Nru a/drivers/isdn/hardware/eicon/io.h b/drivers/isdn/hardware/eicon/io.h
--- a/drivers/isdn/hardware/eicon/io.h	2005-03-01 23:39:17 -08:00
+++ b/drivers/isdn/hardware/eicon/io.h	2005-03-01 23:39:17 -08:00
@@ -252,11 +252,6 @@
 #define PR_RAM  ((struct pr_ram *)0)
 #define RAM ((struct dual *)0)
 /* ---------------------------------------------------------------------
-  Functions for port io
-   --------------------------------------------------------------------- */
-void outp_words_from_buffer (word __iomem * adr, byte* P, dword len);
-void inp_words_to_buffer    (word __iomem * adr, byte* P, dword len);
-/* ---------------------------------------------------------------------
   platform specific conversions
    --------------------------------------------------------------------- */
 extern void * PTR_P(ADAPTER * a, ENTITY * e, void * P);
diff -Nru a/drivers/isdn/hardware/eicon/message.c b/drivers/isdn/hardware/eicon/message.c
--- a/drivers/isdn/hardware/eicon/message.c	2005-03-01 23:39:06 -08:00
+++ b/drivers/isdn/hardware/eicon/message.c	2005-03-01 23:39:06 -08:00
@@ -55,7 +55,7 @@
 /* and it is not necessary to save it separate for every adapter    */
 /* Macrose defined here have only local meaning                     */
 /*------------------------------------------------------------------*/
-dword diva_xdi_extended_features = 0;
+static dword diva_xdi_extended_features = 0;
 
 #define DIVA_CAPI_USE_CMA                 0x00000001
 #define DIVA_CAPI_XDI_PROVIDES_SDRAM_BAR  0x00000002
@@ -72,11 +72,10 @@
 /* local function prototypes                                        */
 /*------------------------------------------------------------------*/
 
-void group_optimization(DIVA_CAPI_ADAPTER   * a, PLCI   * plci);
-void set_group_ind_mask (PLCI   *plci);
-void set_group_ind_mask_bit (PLCI   *plci, word b);
-void clear_group_ind_mask_bit (PLCI   *plci, word b);
-byte test_group_ind_mask_bit (PLCI   *plci, word b);
+static void group_optimization(DIVA_CAPI_ADAPTER   * a, PLCI   * plci);
+static void set_group_ind_mask (PLCI   *plci);
+static void clear_group_ind_mask_bit (PLCI   *plci, word b);
+static byte test_group_ind_mask_bit (PLCI   *plci, word b);
 void AutomaticLaw(DIVA_CAPI_ADAPTER   *);
 word CapiRelease(word);
 word CapiRegister(word);
@@ -88,7 +87,7 @@
 word api_remove_start(void);
 void api_remove_complete(void);
 
-void plci_remove(PLCI   *);
+static void plci_remove(PLCI   *);
 static void diva_get_extended_adapter_features (DIVA_CAPI_ADAPTER  * a);
 static void diva_ask_for_xdi_sdram_bar (DIVA_CAPI_ADAPTER  *, IDI_SYNC_REQ  *);
 
@@ -100,9 +99,9 @@
 static void sig_ind(PLCI   *);
 static void SendInfo(PLCI   *, dword, byte   * *, byte);
 static void SendSetupInfo(APPL   *, PLCI   *, dword, byte   * *, byte);
-void SendSSExtInd(APPL   *, PLCI   * plci, dword Id, byte   * * parms);
+static void SendSSExtInd(APPL   *, PLCI   * plci, dword Id, byte   * * parms);
 
-void VSwitchReqInd(PLCI   *plci, dword Id, byte   **parms);
+static void VSwitchReqInd(PLCI   *plci, dword Id, byte   **parms);
 
 static void nl_ind(PLCI   *);
 
@@ -254,11 +253,11 @@
 
 
 
-byte remove_started = FALSE;
-PLCI dummy_plci;
+static byte remove_started = FALSE;
+static PLCI dummy_plci;
 
 
-struct _ftable {
+static struct _ftable {
   word command;
   byte * format;
   byte (* function)(dword, word, DIVA_CAPI_ADAPTER   *, PLCI   *, APPL   *, API_PARSE *);
@@ -291,7 +290,7 @@
   {_MANUFACTURER_I|RESPONSE,            "",             manufacturer_res}
 };
 
-byte * cip_bc[29][2] = {
+static byte * cip_bc[29][2] = {
   { "",                     ""                     }, /* 0 */
   { "\x03\x80\x90\xa3",     "\x03\x80\x90\xa2"     }, /* 1 */
   { "\x02\x88\x90",         "\x02\x88\x90"         }, /* 2 */
@@ -324,7 +323,7 @@
   { "\x02\x88\x90",         "\x02\x88\x90"         }  /* 28 */
 };
 
-byte * cip_hlc[29] = {
+static byte * cip_hlc[29] = {
   "",                           /* 0 */
   "",                           /* 1 */
   "",                           /* 2 */
@@ -716,7 +715,7 @@
 /* internal command queue                                           */
 /*------------------------------------------------------------------*/
 
-void init_internal_command_queue (PLCI   *plci)
+static void init_internal_command_queue (PLCI   *plci)
 {
   word i;
 
@@ -729,7 +728,7 @@
 }
 
 
-void start_internal_command (dword Id, PLCI   *plci, t_std_internal_command command_function)
+static void start_internal_command (dword Id, PLCI   *plci, t_std_internal_command command_function)
 {
   word i;
 
@@ -751,7 +750,7 @@
 }
 
 
-void next_internal_command (dword Id, PLCI   *plci)
+static void next_internal_command (dword Id, PLCI   *plci)
 {
   word i;
 
@@ -1048,7 +1047,7 @@
 }
 
 
-void plci_remove(PLCI   * plci)
+static void plci_remove(PLCI   * plci)
 {
 
   if(!plci) {
@@ -1094,7 +1093,7 @@
 /* Application Group function helpers                               */
 /*------------------------------------------------------------------*/
 
-void set_group_ind_mask (PLCI   *plci)
+static void set_group_ind_mask (PLCI   *plci)
 {
   word i;
 
@@ -1102,17 +1101,12 @@
     plci->group_optimization_mask_table[i] = 0xffffffffL;
 }
 
-void set_group_ind_mask_bit (PLCI   *plci, word b)
-{
-  plci->group_optimization_mask_table[b >> 5] |= (1L << (b & 0x1f));
-}
-
-void clear_group_ind_mask_bit (PLCI   *plci, word b)
+static void clear_group_ind_mask_bit (PLCI   *plci, word b)
 {
   plci->group_optimization_mask_table[b >> 5] &= ~(1L << (b & 0x1f));
 }
 
-byte test_group_ind_mask_bit (PLCI   *plci, word b)
+static byte test_group_ind_mask_bit (PLCI   *plci, word b)
 {
   return ((plci->group_optimization_mask_table[b >> 5] & (1L << (b & 0x1f))) != 0);
 }
@@ -1121,7 +1115,7 @@
 /* c_ind_mask operations for arbitrary MAX_APPL                     */
 /*------------------------------------------------------------------*/
 
-void clear_c_ind_mask (PLCI   *plci)
+static void clear_c_ind_mask (PLCI   *plci)
 {
   word i;
 
@@ -1129,7 +1123,7 @@
     plci->c_ind_mask_table[i] = 0;
 }
 
-byte c_ind_mask_empty (PLCI   *plci)
+static byte c_ind_mask_empty (PLCI   *plci)
 {
   word i;
 
@@ -1139,22 +1133,22 @@
   return (i == C_IND_MASK_DWORDS);
 }
 
-void set_c_ind_mask_bit (PLCI   *plci, word b)
+static void set_c_ind_mask_bit (PLCI   *plci, word b)
 {
   plci->c_ind_mask_table[b >> 5] |= (1L << (b & 0x1f));
 }
 
-void clear_c_ind_mask_bit (PLCI   *plci, word b)
+static void clear_c_ind_mask_bit (PLCI   *plci, word b)
 {
   plci->c_ind_mask_table[b >> 5] &= ~(1L << (b & 0x1f));
 }
 
-byte test_c_ind_mask_bit (PLCI   *plci, word b)
+static byte test_c_ind_mask_bit (PLCI   *plci, word b)
 {
   return ((plci->c_ind_mask_table[b >> 5] & (1L << (b & 0x1f))) != 0);
 }
 
-void dump_c_ind_mask (PLCI   *plci)
+static void dump_c_ind_mask (PLCI   *plci)
 {
 static char hex_digit_table[0x10] =
   {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
@@ -6426,7 +6420,7 @@
   return iesent;
 }
 
-void SendSSExtInd(APPL   * appl, PLCI   * plci, dword Id, byte   * * parms)
+static void SendSSExtInd(APPL   * appl, PLCI   * plci, dword Id, byte   * * parms)
 {
   word i;
    /* Format of multi_ssext_parms[i][]:
@@ -14720,71 +14714,6 @@
 
 /*------------------------------------------------------------------*/
 
-/* to be completed */
-void disable_adapter(byte adapter_number)
-{
-  word j, ncci;
-  DIVA_CAPI_ADAPTER   *a;
-  PLCI   *plci;
-  dword Id;
-
-  if ((adapter_number == 0) || (adapter_number > max_adapter) || !adapter[adapter_number-1].request)
-  {
-    dbug(1,dprintf("disable adapter: number %d invalid",adapter_number));
-    return;
-  }
-  dbug(1,dprintf("disable adapter number %d",adapter_number));
-    /* Capi20 starts with Nr. 1, internal field starts with 0 */
-  a = &adapter[adapter_number-1];
-  a->adapter_disabled = TRUE;
-  for(j=0;j<a->max_plci;j++)
-  {
-    if(a->plci[j].Id) /* disconnect logical links */
-    {
-      plci = &a->plci[j];
-      if(plci->channels)
-      {
-        for(ncci=1;ncci<MAX_NCCI+1 && plci->channels;ncci++)
-        {
-          if(a->ncci_plci[ncci]==plci->Id)
-          {
-            Id = (((dword)ncci)<<16)|((word)plci->Id<<8)|a->Id;
-            sendf(plci->appl,_DISCONNECT_B3_I,Id,0,"ws",0,"");
-            plci->channels--;
-          }
-        }
-      }
-
-      if(plci->State!=LISTENING) /* disconnect physical links */
-      {
-        Id = ((word)plci->Id<<8)|a->Id;
-        sendf(plci->appl, _DISCONNECT_I, Id, 0, "w", _L1_ERROR);
-        plci_remove(plci);
-        plci->Sig.Id = 0;
-        plci->NL.Id = 0;
-        plci_remove(plci);
-      }
-    }
-  }
-}
-
-void enable_adapter(byte adapter_number)
-{
-  DIVA_CAPI_ADAPTER   *a;
-
-  if ((adapter_number == 0) || (adapter_number > max_adapter) || !adapter[adapter_number-1].request)
-  {
-    dbug(1,dprintf("enable adapter: number %d invalid",adapter_number));
-    return;
-  }
-  dbug(1,dprintf("enable adapter number %d",adapter_number));
-    /* Capi20 starts with Nr. 1, internal field starts with 0 */
-  a = &adapter[adapter_number-1];
-  a->adapter_disabled = FALSE;
-  listen_check(a);
-}
-
-
 static word CPN_filter_ok(byte   *cpn,DIVA_CAPI_ADAPTER   * a,word offset)
 {
   return 1;
@@ -14800,7 +14729,7 @@
 /* function must be enabled by setting "a->group_optimization_enabled" from the   */
 /* OS specific part (per adapter).                                                */
 /**********************************************************************************/
-void group_optimization(DIVA_CAPI_ADAPTER   * a, PLCI   * plci)
+static void group_optimization(DIVA_CAPI_ADAPTER   * a, PLCI   * plci)
 {
   word i,j,k,busy,group_found;
   dword info_mask_group[MAX_CIP_TYPES];
@@ -14967,7 +14896,7 @@
 
 /* Functions for virtual Switching e.g. Transfer by join, Conference */
 
-void VSwitchReqInd(PLCI   *plci, dword Id, byte   **parms)
+static void VSwitchReqInd(PLCI   *plci, dword Id, byte   **parms)
 {
  word i;
  /* Format of vswitch_t:
diff -Nru a/drivers/isdn/hardware/eicon/mntfunc.c b/drivers/isdn/hardware/eicon/mntfunc.c
--- a/drivers/isdn/hardware/eicon/mntfunc.c	2005-03-01 23:38:51 -08:00
+++ b/drivers/isdn/hardware/eicon/mntfunc.c	2005-03-01 23:38:51 -08:00
@@ -1,4 +1,4 @@
-/* $Id: mntfunc.c,v 1.19.6.2 2004/08/28 20:03:53 armin Exp $
+/* $Id: mntfunc.c,v 1.19.6.4 2005/01/31 12:22:20 armin Exp $
  *
  * Driver for Eicon DIVA Server ISDN cards.
  * Maint module
@@ -187,7 +187,7 @@
 		if (!mask) {
 			ret = diva_set_trace_filter (1, "*");
 		} else if (mask < sizeof(data)) {
-			if (copy_from_user(data, (char __user *)buf+12, mask)) {
+			if (diva_os_copy_from_user(NULL, data, (char __user *)buf+12, mask)) {
 				ret = -EFAULT;
 			} else {
 				ret = diva_set_trace_filter ((int)mask, data);
@@ -199,7 +199,7 @@
 
 	case DITRACE_READ_SELECTIVE_TRACE_FILTER:
 		if ((ret = diva_get_trace_filter (sizeof(data), data)) > 0) {
-			if (copy_to_user (buf, data, ret))
+			if (diva_os_copy_to_user (NULL, buf, data, ret))
 				ret = -EFAULT;
 		} else {
 			ret = -ENODEV;
diff -Nru a/drivers/isdn/hardware/eicon/os_4bri.c b/drivers/isdn/hardware/eicon/os_4bri.c
--- a/drivers/isdn/hardware/eicon/os_4bri.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/isdn/hardware/eicon/os_4bri.c	2005-03-01 23:38:56 -08:00
@@ -1,4 +1,4 @@
-/* $Id: os_4bri.c,v 1.28 2004/03/21 17:26:01 armin Exp $ */
+/* $Id: os_4bri.c,v 1.28.4.4 2005/02/11 19:40:25 armin Exp $ */
 
 #include "platform.h"
 #include "debuglib.h"
@@ -17,8 +17,8 @@
 #include "mi_pc.h"
 #include "dsrv4bri.h"
 
-void *diva_xdiLoadFileFile = NULL;
-dword diva_xdiLoadFileLength = 0;
+static void *diva_xdiLoadFileFile = NULL;
+static dword diva_xdiLoadFileLength = 0;
 
 /*
 **  IMPORTS
@@ -416,8 +416,8 @@
 		if (i) {
 			Slave->serialNo = ((dword) (Slave->ControllerNumber << 24)) |
 					a->xdi_adapter.serialNo;
-		Slave->cardType = a->xdi_adapter.cardType;
-	}
+			Slave->cardType = a->xdi_adapter.cardType;
+		}
 	}
 
 	/*
diff -Nru a/drivers/isdn/hardware/eicon/platform.h b/drivers/isdn/hardware/eicon/platform.h
--- a/drivers/isdn/hardware/eicon/platform.h	2005-03-01 23:39:08 -08:00
+++ b/drivers/isdn/hardware/eicon/platform.h	2005-03-01 23:39:08 -08:00
@@ -1,4 +1,4 @@
-/* $Id: platform.h,v 1.37.4.2 2004/08/28 20:03:53 armin Exp $
+/* $Id: platform.h,v 1.37.4.6 2005/01/31 12:22:20 armin Exp $
  *
  * platform.h
  * 
@@ -195,9 +195,7 @@
 }
 static __inline__ void  diva_os_free   (unsigned long flags, void* ptr)
 {
-	if (ptr) {
-		vfree(ptr);
-	}
+	vfree(ptr);
 }
 
 /*
diff -Nru a/drivers/isdn/hardware/eicon/s_4bri.c b/drivers/isdn/hardware/eicon/s_4bri.c
--- a/drivers/isdn/hardware/eicon/s_4bri.c	2005-03-01 23:38:44 -08:00
+++ b/drivers/isdn/hardware/eicon/s_4bri.c	2005-03-01 23:38:44 -08:00
@@ -359,506 +359,9 @@
 	return (1) ;
 }
 
-#if !defined(DIVA_USER_MODE_CARD_CONFIG) /* { */
-/* --------------------------------------------------------------------------
-		Download protocol code to the adapter
-	 -------------------------------------------------------------------------- */
-
-static int qBri_protocol_load (PISDN_ADAPTER BaseIoAdapter, PISDN_ADAPTER IoAdapter) {
-	PISDN_ADAPTER HighIoAdapter;
-
-	byte *p;
-	dword  FileLength ;
-	dword *sharedRam, *File;
-	dword  Addr, ProtOffset, SharedRamOffset, i;
-	dword tasks = BaseIoAdapter->tasks ;
-	int factor = (tasks == 1) ? 1 : 2;
-
-	if (!(File = (dword *)xdiLoadArchive (IoAdapter, &FileLength, 0))) {
-		return (0) ;
-	}
-
-	IoAdapter->features = diva_get_protocol_file_features ((byte*)File,
-	                                       OFFS_PROTOCOL_ID_STRING,
-	                                       IoAdapter->ProtocolIdString,
-	                                       sizeof(IoAdapter->ProtocolIdString)) ;
-	IoAdapter->a.protocol_capabilities = IoAdapter->features ;
-
-	DBG_LOG(("Loading %s", IoAdapter->ProtocolIdString))
-
-	ProtOffset = IoAdapter->ControllerNumber * (IoAdapter->MemorySize >> factor);
-	SharedRamOffset = (IoAdapter->MemorySize >> factor) - MQ_SHARED_RAM_SIZE;
-	Addr = ((dword)(((byte *) File)[OFFS_PROTOCOL_END_ADDR]))
-	  | (((dword)(((byte *) File)[OFFS_PROTOCOL_END_ADDR + 1])) << 8)
-	  | (((dword)(((byte *) File)[OFFS_PROTOCOL_END_ADDR + 2])) << 16)
-	  | (((dword)(((byte *) File)[OFFS_PROTOCOL_END_ADDR + 3])) << 24) ;
-        if ( Addr != 0 )
-	{
-		IoAdapter->DspCodeBaseAddr = (Addr + 3) & (~3) ;
-		IoAdapter->MaxDspCodeSize = (MQ_UNCACHED_ADDR (ProtOffset + SharedRamOffset) -
-										IoAdapter->DspCodeBaseAddr) & ((IoAdapter->MemorySize >> factor) - 1);
-
-		i = 0 ;
-		while ( BaseIoAdapter->QuadroList->QuadroAdapter[i]->ControllerNumber != tasks - 1 )
-			i++ ;
-		HighIoAdapter = BaseIoAdapter->QuadroList->QuadroAdapter[i] ;
-		Addr = HighIoAdapter->DspCodeBaseAddr ;
-
-		if (tasks == 1) {
-			((byte *) File)[OFFS_DIVA_INIT_TASK_COUNT]   =(byte)1;
-			((byte *) File)[OFFS_DIVA_INIT_TASK_COUNT+1] = (byte)BaseIoAdapter->cardType;
-		}
-
-		((byte *) File)[OFFS_DSP_CODE_BASE_ADDR] = (byte) Addr ;
-		((byte *) File)[OFFS_DSP_CODE_BASE_ADDR + 1] = (byte)(Addr >> 8) ;
-		((byte *) File)[OFFS_DSP_CODE_BASE_ADDR + 2] = (byte)(Addr >> 16) ;
-		((byte *) File)[OFFS_DSP_CODE_BASE_ADDR + 3] = (byte)(Addr >> 24) ;
-		IoAdapter->InitialDspInfo = 0x80 ;
-	}
-	else
-	{
-		if ( IoAdapter->features & PROTCAP_VOIP )
-		{
-			IoAdapter->DspCodeBaseAddr = MQ_CACHED_ADDR (ProtOffset + SharedRamOffset - MQ_VOIP_MAX_DSP_CODE_SIZE) ;
-
-			IoAdapter->MaxDspCodeSize = MQ_VOIP_MAX_DSP_CODE_SIZE ;
-
-		}
-		else if ( IoAdapter->features & PROTCAP_V90D )
-		{
-			IoAdapter->DspCodeBaseAddr = MQ_CACHED_ADDR (ProtOffset + SharedRamOffset - MQ_V90D_MAX_DSP_CODE_SIZE) ;
-
-			IoAdapter->MaxDspCodeSize = (IoAdapter->ControllerNumber == tasks - 1) ? MQ_V90D_MAX_DSP_CODE_SIZE : 0 ;
-
-		}
-		else
-		{
-			IoAdapter->DspCodeBaseAddr = MQ_CACHED_ADDR (ProtOffset + SharedRamOffset - MQ_ORG_MAX_DSP_CODE_SIZE) ;
-
-			IoAdapter->MaxDspCodeSize = (IoAdapter->ControllerNumber == tasks - 1) ? MQ_ORG_MAX_DSP_CODE_SIZE : 0 ;
-
-		}
-		IoAdapter->InitialDspInfo = (MQ_CACHED_ADDR (ProtOffset + SharedRamOffset -
-															MQ_ORG_MAX_DSP_CODE_SIZE) - IoAdapter->DspCodeBaseAddr) >> 14 ;
-
-	}
-	DBG_LOG(("%d: DSP code base 0x%08lx, max size 0x%08lx (%08lx,%02x)",
-	         IoAdapter->ControllerNumber,
-	         IoAdapter->DspCodeBaseAddr, IoAdapter->MaxDspCodeSize,
-	         Addr, IoAdapter->InitialDspInfo))
-
-	if (FileLength > ((IoAdapter->DspCodeBaseAddr - MQ_CACHED_ADDR (ProtOffset)) & (IoAdapter->MemorySize - 1)) )
-	{
-		xdiFreeFile (File) ;
-		DBG_FTL(("Protocol code '%s' too long (%ld)",
-		         &IoAdapter->Protocol[0], FileLength))
-		return (0) ;
-	}
-	IoAdapter->downloadAddr = 0 ;
-	p = DIVA_OS_MEM_ATTACH_RAM(IoAdapter);
-	sharedRam = (dword *)&p[IoAdapter->downloadAddr & (IoAdapter->MemorySize - 1)];
-	memcpy (sharedRam, File, FileLength) ;
-
-	DBG_TRC(("Download addr 0x%08x len %ld - virtual 0x%08x",
-	         IoAdapter->downloadAddr, FileLength, sharedRam))
-
-	if ( memcmp (sharedRam, File, FileLength) )
-	{
-		DBG_FTL(("%s: Memory test failed!", IoAdapter->Properties.Name))
-
-		DBG_FTL(("File=0x%x, sharedRam=0x%x", File, sharedRam))
-		DBG_BLK(( (char *)File, 256))
-		DBG_BLK(( (char *)sharedRam, 256))
-		DIVA_OS_MEM_DETACH_RAM(IoAdapter, p);
-
-		xdiFreeFile (File) ;
-		return (0) ;
-	}
-	DIVA_OS_MEM_DETACH_RAM(IoAdapter, p);
-	xdiFreeFile (File) ;
-
-	return (1) ;
-}
-
-/* --------------------------------------------------------------------------
-		DSP Code download
-	 -------------------------------------------------------------------------- */
-static long qBri_download_buffer (OsFileHandle *fp, long length, void **addr) {
-	PISDN_ADAPTER BaseIoAdapter = (PISDN_ADAPTER)fp->sysLoadDesc ;
-	PISDN_ADAPTER IoAdapter;
-	word        i ;
-	dword       *sharedRam ;
-	byte *p;
-
-	i = 0 ;
-
-	do
-	{
-		IoAdapter = BaseIoAdapter->QuadroList->QuadroAdapter[i++] ;
-	} while ( (i < BaseIoAdapter->tasks)
-	       && (((dword) length) > IoAdapter->DspCodeBaseAddr +
-	                IoAdapter->MaxDspCodeSize - IoAdapter->downloadAddr) );
-
-	*addr = (void *)IoAdapter->downloadAddr ;
-	if ( ((dword) length) > IoAdapter->DspCodeBaseAddr +
-	                        IoAdapter->MaxDspCodeSize - IoAdapter->downloadAddr )
-	{
-		DBG_FTL(("%s: out of card memory during DSP download (0x%X)",
-		         IoAdapter->Properties.Name,
-		         IoAdapter->downloadAddr + length))
-		return (-1) ;
-	}
-	p = DIVA_OS_MEM_ATTACH_RAM(BaseIoAdapter);
-	sharedRam = (dword*)&p[IoAdapter->downloadAddr & (IoAdapter->MemorySize - 1)];
-
-	if ( fp->sysFileRead (fp, sharedRam, length) != length ) {
-		DIVA_OS_MEM_DETACH_RAM(BaseIoAdapter, p);
-		return (-1) ;
-	}
-	DIVA_OS_MEM_DETACH_RAM(BaseIoAdapter, p);
-
-	IoAdapter->downloadAddr += length ;
-	IoAdapter->downloadAddr  = (IoAdapter->downloadAddr + 3) & (~3) ;
-
-	return (0) ;
-}
-
-/******************************************************************************/
-
-static dword qBri_telindus_load (PISDN_ADAPTER BaseIoAdapter) {
-	PISDN_ADAPTER        IoAdapter = 0;
-	PISDN_ADAPTER        HighIoAdapter = NULL ;
-	char                *error ;
-	OsFileHandle        *fp ;
-	t_dsp_portable_desc  download_table[DSP_MAX_DOWNLOAD_COUNT] ;
-	word                 download_count, i ;
-	dword               *sharedRam ;
-	dword                FileLength ;
-	byte *p;
-
-	if ( !(fp = OsOpenFile (DSP_TELINDUS_FILE)) ) {
-		DBG_FTL(("qBri_telindus_load: %s not found!", DSP_TELINDUS_FILE))
-		return (0) ;
-	}
-
-
-	for ( i = 0 ; i < BaseIoAdapter->tasks ; ++i )
-	{
-		IoAdapter = BaseIoAdapter->QuadroList->QuadroAdapter[i] ;
-		IoAdapter->downloadAddr = IoAdapter->DspCodeBaseAddr ;
-		if ( IoAdapter->ControllerNumber == BaseIoAdapter->tasks - 1 )
-		{
-			HighIoAdapter = IoAdapter ;
-			HighIoAdapter->downloadAddr = (HighIoAdapter->downloadAddr
-			           + sizeof(dword) + sizeof(download_table) + 3) & (~3) ;
-		}
-	}
-
-
-	FileLength      = fp->sysFileSize ;
-	fp->sysLoadDesc = (void *)BaseIoAdapter ;
-	fp->sysCardLoad = qBri_download_buffer ;
-
-	download_count = DSP_MAX_DOWNLOAD_COUNT ;
-	memset (&download_table[0], '\0', sizeof(download_table)) ;
-/*
- *	set start address for download
- */
-	error = dsp_read_file (fp, (word)(IoAdapter->cardType),
-	                       &download_count, NULL, &download_table[0]) ;
-	if ( error )
-	{
-		DBG_FTL(("download file error: %s", error))
-		OsCloseFile (fp) ;
-		return (0) ;
-	}
-	OsCloseFile (fp) ;
-
-
-	/*
-	 *	store # of download files extracted from the archive and download table
-	 */
-		HighIoAdapter->downloadAddr = HighIoAdapter->DspCodeBaseAddr ;
-		p = DIVA_OS_MEM_ATTACH_RAM(BaseIoAdapter);
-		sharedRam = (dword *)&p[HighIoAdapter->downloadAddr & (IoAdapter->MemorySize - 1)];
-		WRITE_DWORD(&(sharedRam[0]), (dword)download_count);
-		memcpy (&sharedRam[1], &download_table[0], sizeof(download_table)) ;
-
-
-	/* memory check */
-	if ( memcmp (&sharedRam[1], &download_table, download_count) ) {
-		DBG_FTL(("%s: Dsp Memory test failed!", IoAdapter->Properties.Name))
-	}
-	DIVA_OS_MEM_DETACH_RAM(BaseIoAdapter, p);
-
-	return (FileLength) ;
-}
-
-/*
-	Load SDP tasks to the card
-	Return start address of image on succesful load
-	Return zero in case of problem
-
-	INPUT:
-		task			->	name of the image containing this task
-		link_addr	->	pointer to start of previous task
-	*/
-static byte* qBri_sdp_load (PISDN_ADAPTER BaseIoAdapter,
-													char* task,
-													byte*	link_addr) {
-	OsFileHandle *fp;
-	dword FileLength;
-	byte tmp[sizeof(dword)];
-	dword gp_addr;
-	dword entry_addr;
-	dword start_addr = 0;
-	dword phys_start_addr;
-	dword end_addr;
-	byte* sharedRam = 0;
-	byte *p;
-
-  if (task) {
-		if (!(fp = OsOpenFile (task))) {
-			DBG_ERR(("Can't open [%s] image", task))
-			return (0);
-		}
-		if ((FileLength = fp->sysFileSize) < DIVA_MIPS_TASK_IMAGE_ID_STRING_OFFS) {
-			OsCloseFile (fp) ;
-			DBG_ERR(("Image [%s] too short", task))
-			return (0);
-		}
-
-		fp->sysFileSeek (fp, DIVA_MIPS_TASK_IMAGE_GP_OFFS, OS_SEEK_SET);
-		if (fp->sysFileRead (fp, tmp, sizeof(dword)) != sizeof(dword)) {
-			OsCloseFile (fp) ;
-			DBG_ERR(("Can't read image [%s]", task))
-			return (0);
-		}
-		gp_addr = ((dword)tmp[0])					|
-							(((dword)tmp[1]) << 8)	|
-							(((dword)tmp[2]) << 16) |
-							(((dword)tmp[3]) << 24);
-		DBG_TRC(("Image [%s] GP = %08lx", task, gp_addr))
-
-		fp->sysFileSeek (fp, DIVA_MIPS_TASK_IMAGE_ENTRY_OFFS, OS_SEEK_SET);
-		if (fp->sysFileRead (fp, tmp, sizeof(dword)) != sizeof(dword)) {
-			OsCloseFile (fp) ;
-			DBG_ERR(("Can't read image [%s]", task))
-			return (0);
-		}
-		entry_addr = ((dword)tmp[0])					|
-									(((dword)tmp[1]) << 8)	|
-									(((dword)tmp[2]) << 16) |
-									(((dword)tmp[3]) << 24);
-		DBG_TRC(("Image [%s] entry = %08lx", task, entry_addr))
-
-		fp->sysFileSeek (fp, DIVA_MIPS_TASK_IMAGE_LOAD_ADDR_OFFS, OS_SEEK_SET);
-		if (fp->sysFileRead (fp, tmp, sizeof(dword)) != sizeof(dword)) {
-			OsCloseFile (fp) ;
-			DBG_ERR(("Can't read image [%s]", task))
-			return (0);
-		}
-		start_addr = ((dword)tmp[0])					|
-									(((dword)tmp[1]) << 8)	|
-									(((dword)tmp[2]) << 16) |
-									(((dword)tmp[3]) << 24);
-		DBG_TRC(("Image [%s] start = %08lx", task, start_addr))
-
-		fp->sysFileSeek (fp, DIVA_MIPS_TASK_IMAGE_END_ADDR_OFFS, OS_SEEK_SET);
-		if (fp->sysFileRead (fp, tmp, sizeof(dword)) != sizeof(dword)) {
-			OsCloseFile (fp) ;
-			DBG_ERR(("Can't read image [%s]", task))
-			return (0);
-		}
-		end_addr = ((dword)tmp[0])					|
-								(((dword)tmp[1]) << 8)	|
-								(((dword)tmp[2]) << 16) |
-								(((dword)tmp[3]) << 24);
-		DBG_TRC(("Image [%s] end = %08lx", task, end_addr))
-
-		phys_start_addr = start_addr & 0x1fffffff;
-
-		if ((phys_start_addr + FileLength) >= BaseIoAdapter->MemorySize) {
-			OsCloseFile (fp) ;
-			DBG_ERR(("Image [%s] too long", task))
-			return (0);
-		}
-
-		fp->sysFileSeek (fp, 0, OS_SEEK_SET);
-		p = DIVA_OS_MEM_ATTACH_RAM(BaseIoAdapter);
-		sharedRam = &p[phys_start_addr];
-		if ((dword)fp->sysFileRead (fp, sharedRam, FileLength) != FileLength) {
-			DIVA_OS_MEM_DETACH_RAM(BaseIoAdapter, p);
-			OsCloseFile (fp) ;
-			DBG_ERR(("Can't read image [%s]", task))
-			return (0);
-		}
-		DIVA_OS_MEM_DETACH_RAM(BaseIoAdapter, p);
-
-		OsCloseFile (fp) ;
-  }
-
-	p = DIVA_OS_MEM_ATTACH_RAM(BaseIoAdapter);
-	if (!link_addr) {
-		link_addr = &p[OFFS_DSP_CODE_BASE_ADDR];
-	}
-
-	DBG_TRC(("Write task [%s] link %08lx at %08lx",
-						task ? task : "none",
-						start_addr,
-						link_addr - (byte*)&BaseIoAdapter->ram[0]))
-
-	link_addr[0] = (byte)(start_addr         & 0xff);
-	link_addr[1] = (byte)((start_addr >>  8) & 0xff);
-	link_addr[2] = (byte)((start_addr >> 16) & 0xff);
-	link_addr[3] = (byte)((start_addr >> 24) & 0xff);
-
-	DIVA_OS_MEM_DETACH_RAM(BaseIoAdapter, p);
-
-	return (task ? &sharedRam[DIVA_MIPS_TASK_IMAGE_LINK_OFFS] : 0);
-}
-
-/* --------------------------------------------------------------------------
-		Load Card
-	 -------------------------------------------------------------------------- */
-static int load_qBri_hardware (PISDN_ADAPTER IoAdapter) {
-	dword         i, offset, controller ;
-	word         *signature ;
-	int           factor = (IoAdapter->tasks == 1) ? 1 : 2;
-	byte *p;
-
-	PISDN_ADAPTER Slave ;
-
-
-	if (
-
-		!IoAdapter->QuadroList
-
-	  || ( (IoAdapter->cardType != CARDTYPE_DIVASRV_Q_8M_PCI)
-	    && (IoAdapter->cardType != CARDTYPE_DIVASRV_VOICE_Q_8M_PCI)
-	    && (IoAdapter->cardType != CARDTYPE_DIVASRV_Q_8M_V2_PCI)
-     && (IoAdapter->cardType != CARDTYPE_DIVASRV_VOICE_Q_8M_V2_PCI)
-     && (IoAdapter->cardType != CARDTYPE_DIVASRV_B_2M_V2_PCI)
-     && (IoAdapter->cardType != CARDTYPE_DIVASRV_VOICE_B_2M_V2_PCI)
-     && (IoAdapter->cardType != CARDTYPE_DIVASRV_B_2F_PCI) ) )
-	{
-		return (0) ;
-	}
-
-/*
- *	Check for first instance
- */
-	if ( IoAdapter->ControllerNumber > 0 )
-		return (1) ;
-
-/*
- *	first initialize the onboard FPGA
- */
-	if ( !qBri_FPGA_download (IoAdapter) )
-		return (0) ;
-
-
-	for ( i = 0; i < IoAdapter->tasks; i++ )
-	{
-		Slave = IoAdapter->QuadroList->QuadroAdapter[i] ;
-		Slave->fpga_features = IoAdapter->fpga_features ;
-	}
-
-
-/*
- *	download protocol code for all instances
- */
-
-	controller = IoAdapter->tasks;
-	do
-	{
-		controller-- ;
-		i = 0 ;
-		while ( IoAdapter->QuadroList->QuadroAdapter[i]->ControllerNumber != controller )
-			i++ ;
-/*
- *	calculate base address for instance
- */
-		Slave          = IoAdapter->QuadroList->QuadroAdapter[i] ;
-		offset         = Slave->ControllerNumber * (IoAdapter->MemorySize >> factor) ;
-		Slave->Address = &IoAdapter->Address[offset] ;
-		Slave->ram     = &IoAdapter->ram[offset] ;
-		Slave->reset   = IoAdapter->reset ;
-		Slave->ctlReg  = IoAdapter->ctlReg ;
-		Slave->prom    = IoAdapter->prom ;
-		Slave->Config  = IoAdapter->Config ;
-		Slave->Control = IoAdapter->Control ;
-
-		if ( !qBri_protocol_load (IoAdapter, Slave) )
-			return (0) ;
-
-	} while (controller != 0) ;
-
-
-/*
- *	download only one copy of the DSP code
- */
- if (IoAdapter->cardType != CARDTYPE_DIVASRV_B_2F_PCI) {
-	if ( !qBri_telindus_load (IoAdapter) )
-		return (0) ;
- } else {
-   byte* link_addr = 0;
-   link_addr = qBri_sdp_load (IoAdapter, DIVA_BRI2F_SDP_1_NAME, link_addr);
-   link_addr = qBri_sdp_load (IoAdapter, DIVA_BRI2F_SDP_2_NAME, link_addr);
-   if (!link_addr) {
-     qBri_sdp_load (IoAdapter, 0, link_addr);
-   }
- }
-
-/*
- *	copy configuration parameters
- */
-
-	for ( i = 0 ; i < IoAdapter->tasks ; ++i )
-	{
-		Slave = IoAdapter->QuadroList->QuadroAdapter[i] ;
-		Slave->ram += (IoAdapter->MemorySize >> factor) - MQ_SHARED_RAM_SIZE ;
-		p = DIVA_OS_MEM_ATTACH_RAM(Slave);
-		DBG_TRC(("Configure instance %d shared memory @ 0x%08lx",
-		         Slave->ControllerNumber, p))
-		memset (p, '\0', 256) ;
-		DIVA_OS_MEM_DETACH_RAM(Slave, p);
-		diva_configure_protocol (Slave);
-	}
-
-/*
- *	start adapter
- */
-	start_qBri_hardware (IoAdapter) ;
-	p = DIVA_OS_MEM_ATTACH_RAM(IoAdapter);
-	signature = (word *)(&p[0x1E]) ;
-/*
- *	wait for signature in shared memory (max. 3 seconds)
- */
-	for ( i = 0 ; i < 300 ; ++i )
-	{
-		diva_os_wait (10) ;
-
-		if ( signature[0] == 0x4447 )
-		{
-			DIVA_OS_MEM_DETACH_RAM(IoAdapter, p);
-			DBG_TRC(("Protocol startup time %d.%02d seconds",
-			         (i / 100), (i % 100) ))
-
-			return (1) ;
-		}
-	}
-	DIVA_OS_MEM_DETACH_RAM(IoAdapter, p);
-	DBG_FTL(("%s: Adapter selftest failed (0x%04X)!",
-	         IoAdapter->Properties.Name, signature[0] >> 16))
-	qBri_cpu_trapped (IoAdapter) ;
-	return (FALSE) ;
-}
-#else /* } { */
 static int load_qBri_hardware (PISDN_ADAPTER IoAdapter) {
 	return (0);
 }
-#endif /* } */
 
 /* --------------------------------------------------------------------------
 		Card ISR
diff -Nru a/drivers/isdn/hardware/eicon/s_bri.c b/drivers/isdn/hardware/eicon/s_bri.c
--- a/drivers/isdn/hardware/eicon/s_bri.c	2005-03-01 23:39:10 -08:00
+++ b/drivers/isdn/hardware/eicon/s_bri.c	2005-03-01 23:39:10 -08:00
@@ -119,356 +119,9 @@
  outpp (p, 0x00) ;    /* clear int, halt cpu */
  DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
 }
-#if !defined(DIVA_USER_MODE_CARD_CONFIG) /* { */
-/* ---------------------------------------------------------------------
-  Load protocol on the card
-  --------------------------------------------------------------------- */
-static dword bri_protocol_load (PISDN_ADAPTER IoAdapter) {
- dword   FileLength ;
- word    test, *File = NULL ;
- byte*  addrHi, *addrLo, *ioaddr ;
- char   *FileName = &IoAdapter->Protocol[0] ;
- dword   Addr, i ;
- byte *Port;
- /* -------------------------------------------------------------------
-   Try to load protocol code. 'File' points to memory location
-   that does contain entire protocol code
-   ------------------------------------------------------------------- */
- if ( !(File = (word *)xdiLoadArchive (IoAdapter, &FileLength, 0)) )
-  return (0) ;
- /* -------------------------------------------------------------------
-   Get protocol features and calculate load addresses
-   ------------------------------------------------------------------- */
- IoAdapter->features = diva_get_protocol_file_features ((byte*)File,
-                     OFFS_PROTOCOL_ID_STRING,
-                     IoAdapter->ProtocolIdString,
-                     sizeof(IoAdapter->ProtocolIdString));
- IoAdapter->a.protocol_capabilities = IoAdapter->features ;
- DBG_LOG(("Loading %s", IoAdapter->ProtocolIdString))
- Addr = ((dword)(((byte *) File)[OFFS_PROTOCOL_END_ADDR]))
-   | (((dword)(((byte *) File)[OFFS_PROTOCOL_END_ADDR + 1])) << 8)
-   | (((dword)(((byte *) File)[OFFS_PROTOCOL_END_ADDR + 2])) << 16)
-   | (((dword)(((byte *) File)[OFFS_PROTOCOL_END_ADDR + 3])) << 24) ;
-        if ( Addr != 0 )
- {
-  IoAdapter->DspCodeBaseAddr = (Addr + 3) & (~3) ;
-  IoAdapter->MaxDspCodeSize = (BRI_UNCACHED_ADDR (IoAdapter->MemoryBase + IoAdapter->MemorySize -
-                                                  BRI_SHARED_RAM_SIZE)
-                            - IoAdapter->DspCodeBaseAddr) & (IoAdapter->MemorySize - 1) ;
-  Addr = IoAdapter->DspCodeBaseAddr ;
-  ((byte *) File)[OFFS_DSP_CODE_BASE_ADDR] = (byte) Addr ;
-  ((byte *) File)[OFFS_DSP_CODE_BASE_ADDR + 1] = (byte)(Addr >> 8) ;
-  ((byte *) File)[OFFS_DSP_CODE_BASE_ADDR + 2] = (byte)(Addr >> 16) ;
-  ((byte *) File)[OFFS_DSP_CODE_BASE_ADDR + 3] = (byte)(Addr >> 24) ;
-  IoAdapter->InitialDspInfo = 0x80 ;
- }
- else
- {
-  if ( IoAdapter->features & PROTCAP_V90D )
-   IoAdapter->MaxDspCodeSize = BRI_V90D_MAX_DSP_CODE_SIZE ;
-  else
-   IoAdapter->MaxDspCodeSize = BRI_ORG_MAX_DSP_CODE_SIZE ;
-  IoAdapter->DspCodeBaseAddr = BRI_CACHED_ADDR (IoAdapter->MemoryBase + IoAdapter->MemorySize -
-                                                BRI_SHARED_RAM_SIZE - IoAdapter->MaxDspCodeSize);
-  IoAdapter->InitialDspInfo = (IoAdapter->MaxDspCodeSize - BRI_ORG_MAX_DSP_CODE_SIZE) >> 14 ;
- }
- DBG_LOG(("DSP code base 0x%08lx, max size 0x%08lx (%08lx,%02x)",
-      IoAdapter->DspCodeBaseAddr, IoAdapter->MaxDspCodeSize,
-      Addr, IoAdapter->InitialDspInfo))
- if ( FileLength > ((IoAdapter->DspCodeBaseAddr -
-                     BRI_CACHED_ADDR (IoAdapter->MemoryBase)) & (IoAdapter->MemorySize - 1)) )
- {
-  xdiFreeFile (File);
-  DBG_FTL(("Protocol code '%s' too big (%ld)", FileName, FileLength))
-  return (0) ;
- }
- Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter);
- addrHi =   Port + ((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH) ;
- addrLo = Port + ADDR ;
- ioaddr = Port + DATA ;
-/*
- * set start address for download (use autoincrement mode !)
- */
- outpp  (addrHi, 0) ;
- outppw (addrLo, 0) ;
- for ( i = 0 ; i < FileLength ; i += 2 )
- {
-  if ( (i & 0x0000FFFF) == 0 )
-  {
-   outpp (addrHi, (byte)(i >> 16)) ;
-  }
-  outppw (ioaddr, File[i/2]) ;
- }
-/*
- * memory test without second load of file
- */
- outpp  (addrHi, 0) ;
- outppw (addrLo, 0) ;
- for ( i = 0 ; i < FileLength ; i += 2 )
- {
-  if ( (i & 0x0000FFFF) == 0 )
-  {
-   outpp (addrHi, (byte)(i >> 16)) ;
-  }
-  test = inppw (ioaddr) ;
-  if ( test != File[i/2] )
-  {
-   DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
-   DBG_FTL(("%s: Memory test failed! (%d - 0x%04X/0x%04X)",
-            IoAdapter->Properties.Name, i, test, File[i/2]))
-   xdiFreeFile (File);
-   return (0) ;
-  }
- }
- DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
- xdiFreeFile (File);
- return (FileLength) ;
-}
-/******************************************************************************/
-typedef struct
-{
- PISDN_ADAPTER IoAdapter ;
- byte*        AddrLo ;
- byte*        AddrHi ;
- word*       Data ;
- dword         DownloadPos ;
-} bri_download_info ;
-static long bri_download_buffer (OsFileHandle *fp, long length, void **addr) {
- int        buffer_size = 2048*sizeof(word);
- word       *buffer = (word*)diva_os_malloc (0, buffer_size);
- bri_download_info *info ;
- word       test ;
- long       i, len, page ;
- if (!buffer) {
-  DBG_ERR(("A: out of memory, s_bri at %d", __LINE__))
-  return (-1);
- }
- info = (bri_download_info *)fp->sysLoadDesc ;
- *addr = (void *)info->DownloadPos ;
- if ( ((dword) length) > info->IoAdapter->DspCodeBaseAddr +
-                         info->IoAdapter->MaxDspCodeSize - info->DownloadPos )
- {
-  DBG_FTL(("%s: out of card memory during DSP download (0x%X)",
-           info->IoAdapter->Properties.Name,
-           info->DownloadPos + length))
-  diva_os_free (0, buffer);
-  return (-1) ;
- }
- for ( len = 0 ; length > 0 ; length -= len )
- {
-  len = (length > buffer_size ? buffer_size : length) ;
-  page = ((long)(info->DownloadPos) + len) & 0xFFFF0000 ;
-  if ( page != (long)(info->DownloadPos & 0xFFFF0000) )
-  {
-   len = 0x00010000 - (((long)info->DownloadPos) & 0x0000FFFF) ;
-  }
-  if ( fp->sysFileRead (fp, &buffer[0], len) != len ) {
-   diva_os_free (0, buffer);
-   return (-1) ;
-  }
-  outpp (info->AddrHi, (byte)(info->DownloadPos >> 16)) ;
-  outppw (info->AddrLo, (word)info->DownloadPos) ;
-  outppw_buffer (info->Data, &buffer[0], (len + 1)) ;
-/*
- * memory test without second load of file
- */
-  outpp (info->AddrHi, (byte)(info->DownloadPos >> 16)) ;
-  outppw (info->AddrLo, (word)info->DownloadPos) ;
-  for ( i = 0 ; i < len ; i += 2 )
-  {
-   if ( (test = inppw (info->Data)) != buffer[i/2] )
-   {
-    DBG_FTL(("%s: Memory test failed! (0x%lX - 0x%04X/0x%04X)",
-             info->IoAdapter->Properties.Name,
-             info->DownloadPos + i, test, buffer[i/2]))
-    diva_os_free (0, buffer);
-    return (-2) ;
-   }
-  }
-  info->DownloadPos += len ;
- }
- info->DownloadPos = (info->DownloadPos + 3) & (~3) ;
- diva_os_free (0, buffer);
- return (0) ;
-}
-/******************************************************************************/
-static dword bri_telindus_load (PISDN_ADAPTER IoAdapter, char *DspTelindusFile) 
-{
- bri_download_info    *pinfo =\
-             (bri_download_info*)diva_os_malloc(0, sizeof(*pinfo));
- char                *error ;
- OsFileHandle        *fp ;
- t_dsp_portable_desc  download_table[DSP_MAX_DOWNLOAD_COUNT] ;
- word                 download_count ;
- dword                FileLength ;
- byte *Port;
- if (!pinfo) {
-  DBG_ERR (("A: out of memory s_bri at %d", __LINE__))
-  return (0);
- }
- if (!(fp = OsOpenFile (DspTelindusFile))) {
-  diva_os_free (0, pinfo);
-  return (0) ;
- }
- FileLength     = fp->sysFileSize ;
- Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter);
- pinfo->IoAdapter = IoAdapter ;
- pinfo->AddrLo    = Port + ADDR ;
- pinfo->AddrHi    = Port + (IoAdapter->Properties.Bus == BUS_PCI ? M_PCI_ADDRH : ADDRH);
- pinfo->Data = (word*)(Port + DATA) ;
- pinfo->DownloadPos = (IoAdapter->DspCodeBaseAddr +\
-           sizeof(dword) + sizeof(download_table) + 3) & (~3) ;
- fp->sysLoadDesc = (void *)pinfo;
- fp->sysCardLoad = bri_download_buffer ;
- download_count = DSP_MAX_DOWNLOAD_COUNT ;
- memset (&download_table[0], '\0', sizeof(download_table)) ;
-/*
- * set start address for download (use autoincrement mode !)
- */
- error = dsp_read_file (fp, (word)(IoAdapter->cardType),
-                        &download_count, NULL, &download_table[0]) ;
- if ( error )
- {
-  DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
-  DBG_FTL(("download file error: %s", error))
-  OsCloseFile (fp) ;
-  diva_os_free (0, pinfo);
-  return (0) ;
- }
- OsCloseFile (fp) ;
-/*
- * store # of separate download files extracted from archive
- */
- pinfo->DownloadPos = IoAdapter->DspCodeBaseAddr ;
- outpp  (pinfo->AddrHi, (byte)(pinfo->DownloadPos >> 16)) ;
- outppw (pinfo->AddrLo, (word)pinfo->DownloadPos) ;
- outppw (pinfo->Data,   (word)download_count) ;
- outppw (pinfo->Data,   (word)0) ;
-/*
- * copy download table to board
- */
- outppw_buffer (pinfo->Data, &download_table[0], sizeof(download_table)) ;
- DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
- diva_os_free (0, pinfo);
- return (FileLength) ;
-}
-/******************************************************************************/
-static int load_bri_hardware (PISDN_ADAPTER IoAdapter) {
- dword   i ;
- byte*  addrHi, *addrLo, *ioaddr, *p ;
- dword   test ;
- byte *Port;
- if ( IoAdapter->Properties.Card != CARD_MAE )
- {
-  return (FALSE) ;
- }
- reset_bri_hardware (IoAdapter) ;
- Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter);
- addrHi =   Port + ((IoAdapter->Properties.Bus==BUS_PCI) ? M_PCI_ADDRH : ADDRH);
- addrLo = Port + ADDR ;
- ioaddr = Port + DATA ;
- diva_os_wait (100);
-/*
- * recover
- */
- outpp  (addrHi, (byte) 0) ;
- outppw (addrLo, (word) 0) ;
- outppw (ioaddr, (word) 0) ;
-/*
- * clear shared memory
- */
- outpp  (addrHi, (byte)((BRI_UNCACHED_ADDR (IoAdapter->MemoryBase + \
-          IoAdapter->MemorySize - BRI_SHARED_RAM_SIZE)) >> 16)) ;
- outppw (addrLo, 0) ;
- for ( i = 0 ; i < 0x8000 ; outppw (ioaddr, 0), ++i ) ;
- DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
- diva_os_wait (100) ;
-/*
- * download protocol and dsp files
- */
- switch ( IoAdapter->protocol_id ) {
- default:
-  if ( !xdiSetProtocol (IoAdapter, IoAdapter->ProtocolSuffix) )
-   return (FALSE) ;
-  if ( !bri_protocol_load (IoAdapter) )
-   return (FALSE) ;
-  if ( !bri_telindus_load (IoAdapter, DSP_TELINDUS_FILE) )
-   return (FALSE) ;
-  break ;
- case PROTTYPE_QSIG:
- case PROTTYPE_CORNETN:
-  if ( !xdiSetProtocol (IoAdapter, IoAdapter->ProtocolSuffix) )
-   return (FALSE) ;
-  if (IoAdapter->ProtocolSuffix && *IoAdapter->ProtocolSuffix) {
-   sprintf (&IoAdapter->Protocol[0],
-        "TE_QSIG.%s", IoAdapter->ProtocolSuffix) ;
-  }
-  DBG_TRC(("xdiSetProtocol: %s firmware '%s' archive '%s'",
-     IoAdapter->Properties.Name,
-     &IoAdapter->Protocol[0], &IoAdapter->Archive[0]))
-  if ( !bri_protocol_load (IoAdapter) )
-   return (FALSE) ;
-  if ( !bri_telindus_load (IoAdapter, DSP_QSIG_TELINDUS_FILE) )
-   return (FALSE) ;
-  break ;
- }
-
- Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter);
- addrHi =   Port + ((IoAdapter->Properties.Bus==BUS_PCI) ? M_PCI_ADDRH : ADDRH);
- addrLo = Port + ADDR ;
- ioaddr = Port + DATA ;
-/*
- * clear signature
- */
- outpp  (addrHi, (byte)((BRI_UNCACHED_ADDR (IoAdapter->MemoryBase + \
-     IoAdapter->MemorySize - BRI_SHARED_RAM_SIZE)) >> 16)) ;
- outppw (addrLo, 0x1e) ;
- outpp (ioaddr, 0) ;
- outpp (ioaddr, 0) ;
-/*
- * copy parameters
- */
- diva_configure_protocol (IoAdapter);
- DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
-/*
- * start the protocol code
- */
- p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
- outpp (p, 0x08) ;
- DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
-/*
- * wait for signature (max. 3 seconds)
- */
- Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter);
- addrHi =   Port + ((IoAdapter->Properties.Bus==BUS_PCI) ? M_PCI_ADDRH : ADDRH);
- addrLo = Port + ADDR ;
- ioaddr = Port + DATA ;
- for ( i = 0 ; i < 300 ; ++i )
- {
-  diva_os_wait (10) ;
-  outpp (addrHi, (byte)((BRI_UNCACHED_ADDR (IoAdapter->MemoryBase + \
-      IoAdapter->MemorySize - BRI_SHARED_RAM_SIZE)) >> 16)) ;
-  outppw (addrLo, 0x1e) ;
-  test = (dword)inppw (ioaddr) ;
-  if ( test == 0x4447 )
-  {
-   DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
-   DBG_TRC(("Protocol startup time %d.%02d seconds",
-            (i / 100), (i % 100) ))
-   return (TRUE) ;
-  }
- }
- DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
- DBG_FTL(("%s: Adapter selftest failed (0x%04X)!",
-          IoAdapter->Properties.Name, test))
- bri_cpu_trapped (IoAdapter) ;
- return (FALSE) ;
-}
-#else /* } { */
 static int load_bri_hardware (PISDN_ADAPTER IoAdapter) {
  return (0);
 }
-#endif /* } */
 /******************************************************************************/
 static int bri_ISR (struct _ISDN_ADAPTER* IoAdapter) {
  byte __iomem *p;
diff -Nru a/drivers/isdn/hardware/eicon/s_pri.c b/drivers/isdn/hardware/eicon/s_pri.c
--- a/drivers/isdn/hardware/eicon/s_pri.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/isdn/hardware/eicon/s_pri.c	2005-03-01 23:39:18 -08:00
@@ -122,371 +122,9 @@
  WRITE_BYTE(p, _MP_RISC_RESET | _MP_LED1 | _MP_LED2);
  DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
 }
-#if !defined(DIVA_USER_MODE_CARD_CONFIG) /* { */
-/* -------------------------------------------------------------------------
-  Load protocol code to the PRI Card
-  ------------------------------------------------------------------------- */
-#define DOWNLOAD_ADDR(IoAdapter) (IoAdapter->downloadAddr & (IoAdapter->MemorySize - 1))
-static int pri_protocol_load (PISDN_ADAPTER IoAdapter) {
- dword  FileLength ;
- dword *File ;
- dword *sharedRam ;
- dword  Addr ;
- byte *p;
- if (!(File = (dword *)xdiLoadArchive (IoAdapter, &FileLength, 0))) {
-  return (0) ;
- }
- IoAdapter->features = diva_get_protocol_file_features ((byte*)File,
-                                        OFFS_PROTOCOL_ID_STRING,
-                                        IoAdapter->ProtocolIdString,
-                                        sizeof(IoAdapter->ProtocolIdString)) ;
- IoAdapter->a.protocol_capabilities = IoAdapter->features ;
- DBG_LOG(("Loading %s", IoAdapter->ProtocolIdString))
- Addr = ((dword)(((byte *) File)[OFFS_PROTOCOL_END_ADDR]))
-   | (((dword)(((byte *) File)[OFFS_PROTOCOL_END_ADDR + 1])) << 8)
-   | (((dword)(((byte *) File)[OFFS_PROTOCOL_END_ADDR + 2])) << 16)
-   | (((dword)(((byte *) File)[OFFS_PROTOCOL_END_ADDR + 3])) << 24) ;
-        if ( Addr != 0 )
- {
-  IoAdapter->DspCodeBaseAddr = (Addr + 3) & (~3) ;
-  IoAdapter->MaxDspCodeSize = (MP_UNCACHED_ADDR (IoAdapter->MemorySize)
-                            - IoAdapter->DspCodeBaseAddr) & (IoAdapter->MemorySize - 1) ;
-  Addr = IoAdapter->DspCodeBaseAddr ;
-  ((byte *) File)[OFFS_DSP_CODE_BASE_ADDR] = (byte) Addr ;
-  ((byte *) File)[OFFS_DSP_CODE_BASE_ADDR + 1] = (byte)(Addr >> 8) ;
-  ((byte *) File)[OFFS_DSP_CODE_BASE_ADDR + 2] = (byte)(Addr >> 16) ;
-  ((byte *) File)[OFFS_DSP_CODE_BASE_ADDR + 3] = (byte)(Addr >> 24) ;
-  IoAdapter->InitialDspInfo = 0x80 ;
- }
- else
- {
-  if ( IoAdapter->features & PROTCAP_VOIP )
-   IoAdapter->MaxDspCodeSize = MP_VOIP_MAX_DSP_CODE_SIZE ;
-  else if ( IoAdapter->features & PROTCAP_V90D )
-   IoAdapter->MaxDspCodeSize = MP_V90D_MAX_DSP_CODE_SIZE ;
-  else
-   IoAdapter->MaxDspCodeSize = MP_ORG_MAX_DSP_CODE_SIZE ;
-  IoAdapter->DspCodeBaseAddr = MP_CACHED_ADDR (IoAdapter->MemorySize -
-                                               IoAdapter->MaxDspCodeSize) ;
-  IoAdapter->InitialDspInfo = (IoAdapter->MaxDspCodeSize
-                            - MP_ORG_MAX_DSP_CODE_SIZE) >> 14 ;
- }
- DBG_LOG(("DSP code base 0x%08lx, max size 0x%08lx (%08lx,%02x)",
-          IoAdapter->DspCodeBaseAddr, IoAdapter->MaxDspCodeSize,
-          Addr, IoAdapter->InitialDspInfo))
- if ( FileLength > ((IoAdapter->DspCodeBaseAddr -
-                     MP_CACHED_ADDR (MP_PROTOCOL_OFFSET)) & (IoAdapter->MemorySize - 1)) )
- {
-  xdiFreeFile (File);
-  DBG_FTL(("Protocol code '%s' too long (%ld)",
-           &IoAdapter->Protocol[0], FileLength))
-  return (0) ;
- }
- IoAdapter->downloadAddr = MP_UNCACHED_ADDR (MP_PROTOCOL_OFFSET) ;
- p = DIVA_OS_MEM_ATTACH_RAM(IoAdapter);
- sharedRam = (dword *)(&p[DOWNLOAD_ADDR(IoAdapter)]);
- memcpy (sharedRam, File, FileLength) ;
- if ( memcmp (sharedRam, File, FileLength) )
- {
-  DIVA_OS_MEM_DETACH_RAM(IoAdapter, p);
-  DBG_FTL(("%s: Memory test failed!", IoAdapter->Properties.Name))
-  xdiFreeFile (File);
-  return (0) ;
- }
- DIVA_OS_MEM_DETACH_RAM(IoAdapter, p);
- xdiFreeFile (File);
- return (1) ;
-}
-/******************************************************************************/
-/*------------------------------------------------------------------
-  Dsp related definitions
-  ------------------------------------------------------------------ */
-#define DSP_SIGNATURE_PROBE_WORD 0x5a5a
-/*
-**  Checks presence of DSP on board
-*/
-static int
-dsp_check_presence (volatile byte* addr, volatile byte* data, int dsp)
-{
-  word pattern;
-  *(volatile word*)addr = 0x4000;
-  *(volatile word*)data = DSP_SIGNATURE_PROBE_WORD;
-  *(volatile word*)addr = 0x4000;
-  pattern = *(volatile word*)data;
-  if (pattern != DSP_SIGNATURE_PROBE_WORD) {
-    DBG_TRC(("W: DSP[%d] %04x(is) != %04x(should)",
-              dsp, pattern, DSP_SIGNATURE_PROBE_WORD))
-    return (-1);
-  }
-  *(volatile word*)addr = 0x4000;
-  *(volatile word*)data = ~DSP_SIGNATURE_PROBE_WORD;
-  *(volatile word*)addr = 0x4000;
-  pattern = *(volatile word*)data;
-  if (pattern != (word)~DSP_SIGNATURE_PROBE_WORD) {
-    DBG_ERR(("A: DSP[%d] %04x(is) != %04x(should)",
-              dsp, pattern, (word)~DSP_SIGNATURE_PROBE_WORD))
-    return (-2);
-  }
-  DBG_TRC (("DSP[%d] present", dsp))
-  return (0);
-}
-/*
-**  Check if DSP's are present and operating
-**  Information about detected DSP's is returned as bit mask
-**  Bit 0  - DSP1
-**  ...
-**  ...
-**  ...
-**  Bit 29 - DSP30
-*/
-static dword
-diva_pri_detect_dsps (PISDN_ADAPTER IoAdapter)
-{
-  byte* base;
-  byte* p;
-  dword ret = 0, DspCount = 0 ;
-  dword row_offset[] = {
-    0x00000000,
-    0x00000800, /* 1 - ROW 1 */
-    0x00000840, /* 2 - ROW 2 */
-    0x00001000, /* 3 - ROW 3 */
-    0x00001040, /* 4 - ROW 4 */
-    0x00000000  /* 5 - ROW 0 */
-  };
-  byte *dsp_addr_port, *dsp_data_port, row_state;
-  int dsp_row = 0, dsp_index, dsp_num;
- IoAdapter->InitialDspInfo &= 0xffff ;
- p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
-  if (!p)
-  {
-    DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
-    return (0);
-  }
-  *(volatile byte*)(p) = _MP_RISC_RESET | _MP_DSP_RESET;
-  DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
-  diva_os_wait (5) ;
-
-  base = DIVA_OS_MEM_ATTACH_CONTROL(IoAdapter);
-  
-  for (dsp_num = 0; dsp_num < 30; dsp_num++) {
-    dsp_row   = dsp_num / 7 + 1;
-    dsp_index = dsp_num % 7;
-    dsp_data_port = base;
-    dsp_addr_port = base;
-    dsp_data_port += row_offset[dsp_row];
-    dsp_addr_port += row_offset[dsp_row];
-    dsp_data_port += (dsp_index * 8);
-    dsp_addr_port += (dsp_index * 8) + 0x80;
-    if (!dsp_check_presence (dsp_addr_port, dsp_data_port, dsp_num+1)) {
-      ret |= (1 << dsp_num);
-   DspCount++ ;
-    }
-  }
-  DIVA_OS_MEM_DETACH_CONTROL(IoAdapter, base);
-
-  p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
-  *(volatile byte*)(p) = _MP_RISC_RESET | _MP_LED1 | _MP_LED2;
-  diva_os_wait (50) ;
-  /*
-    Verify modules
-  */
-  for (dsp_row = 0; dsp_row < 4; dsp_row++) {
-    row_state = (byte)((ret >> (dsp_row*7)) & 0x7F);
-    if (row_state && (row_state != 0x7F)) {
-      for (dsp_index = 0; dsp_index < 7; dsp_index++) {
-        if (!(row_state & (1 << dsp_index))) {
-          DBG_ERR (("A: MODULE[%d]-DSP[%d] failed", dsp_row+1, dsp_index+1))
-        }
-      }
-    }
-  }
-  if (!(ret & 0x10000000)) {
-    DBG_ERR (("A: ON BOARD-DSP[1] failed"))
-  }
-  if (!(ret & 0x20000000)) {
-    DBG_ERR (("A: ON BOARD-DSP[2] failed"))
-  }
-  /*
-    Print module population now
-  */
-  DBG_LOG(("+-----------------------+"))
-  DBG_LOG(("| DSP MODULE POPULATION |"))
-  DBG_LOG(("+-----------------------+"))
-  DBG_LOG(("|  1  |  2  |  3  |  4  |"))
-  DBG_LOG(("+-----------------------+"))
-  DBG_LOG(("|  %s  |  %s  |  %s  |  %s  |",
-    ((ret >> (0*7)) & 0x7F) ? "Y" : "N",
-    ((ret >> (1*7)) & 0x7F) ? "Y" : "N",
-    ((ret >> (2*7)) & 0x7F) ? "Y" : "N",
-    ((ret >> (3*7)) & 0x7F) ? "Y" : "N"))
-  DBG_LOG(("+-----------------------+"))
-  DBG_LOG(("DSP's(present-absent):%08x-%08x", ret, ~ret & 0x3fffffff))
-  *(volatile byte*)(p) = 0 ;
-  DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
-  diva_os_wait (50) ;
- IoAdapter->InitialDspInfo |= DspCount << 16 ;
-  return (ret);
-}
-/* -------------------------------------------------------------------------
-  helper used to download dsp code toi PRI Card
-  ------------------------------------------------------------------------- */
-static long pri_download_buffer (OsFileHandle *fp, long length, void **addr) {
- PISDN_ADAPTER IoAdapter = (PISDN_ADAPTER)fp->sysLoadDesc ;
- dword        *sharedRam ;
- byte *p;
- *addr = (void *)IoAdapter->downloadAddr ;
- if ( ((dword) length) > IoAdapter->DspCodeBaseAddr +
-                         IoAdapter->MaxDspCodeSize - IoAdapter->downloadAddr )
- {
-  DBG_FTL(("%s: out of card memory during DSP download (0x%X)",
-           IoAdapter->Properties.Name,
-           IoAdapter->downloadAddr + length))
-  return (-1) ;
- }
- p = DIVA_OS_MEM_ATTACH_RAM(IoAdapter);
- sharedRam = (dword *)(&p[DOWNLOAD_ADDR(IoAdapter)]);
- if ( fp->sysFileRead (fp, sharedRam, length) != length ) {
-  DIVA_OS_MEM_DETACH_RAM(IoAdapter, p);
-  return (-1) ;
- }
- IoAdapter->downloadAddr += length ;
- IoAdapter->downloadAddr  = (IoAdapter->downloadAddr + 3) & (~3) ;
- DIVA_OS_MEM_DETACH_RAM(IoAdapter, p);
- return (0) ;
-}
-/* -------------------------------------------------------------------------
-  Download DSP code to PRI Card
-  ------------------------------------------------------------------------- */
-static dword pri_telindus_load (PISDN_ADAPTER IoAdapter) {
- char                *error ;
- OsFileHandle        *fp ;
- t_dsp_portable_desc  download_table[DSP_MAX_DOWNLOAD_COUNT] ;
- word                 download_count ;
- dword               *sharedRam ;
- dword                FileLength ;
- byte *p;
- if ( !(fp = OsOpenFile (DSP_TELINDUS_FILE)) )
-  return (0) ;
- IoAdapter->downloadAddr = (IoAdapter->DspCodeBaseAddr
-                         + sizeof(dword) + sizeof(download_table) + 3) & (~3) ;
- FileLength      = fp->sysFileSize ;
- fp->sysLoadDesc = (void *)IoAdapter ;
- fp->sysCardLoad = pri_download_buffer ;
- download_count = DSP_MAX_DOWNLOAD_COUNT ;
- memset (&download_table[0], '\0', sizeof(download_table)) ;
-/*
- * set start address for download (use autoincrement mode !)
- */
- error = dsp_read_file (fp, (word)(IoAdapter->cardType),
-                        &download_count, NULL, &download_table[0]) ;
- if ( error )
- {
-  DBG_FTL(("download file error: %s", error))
-  OsCloseFile (fp) ;
-  return (0) ;
- }
- OsCloseFile (fp) ;
-/*
- * store # of separate download files extracted from archive
- */
- IoAdapter->downloadAddr = IoAdapter->DspCodeBaseAddr ;
- p = DIVA_OS_MEM_ATTACH_RAM(IoAdapter);
- sharedRam = (dword *)(&p[DOWNLOAD_ADDR(IoAdapter)]);
- WRITE_DWORD(&(sharedRam[0]), (dword)download_count);
- memcpy (&sharedRam[1], &download_table[0], sizeof(download_table)) ;
- DIVA_OS_MEM_DETACH_RAM(IoAdapter, p);
- return (FileLength) ;
-}
-/* -------------------------------------------------------------------------
-  Download PRI Card
-  ------------------------------------------------------------------------- */
-#define MIN_DSPS 0x30000000
-static int load_pri_hardware (PISDN_ADAPTER IoAdapter) {
- dword           i ;
- struct mp_load *boot = (struct mp_load *)DIVA_OS_MEM_ATTACH_RAM(IoAdapter);
- if ( IoAdapter->Properties.Card != CARD_MAEP ) {
-  DIVA_OS_MEM_DETACH_RAM(IoAdapter, boot);
-  return (0) ;
- }
- boot->err = 0 ;
-#if 0
- IoAdapter->rstFnc (IoAdapter) ;
-#else
- if ( MIN_DSPS != (MIN_DSPS & diva_pri_detect_dsps(IoAdapter)) ) { /* makes reset */
-  DIVA_OS_MEM_DETACH_RAM(IoAdapter, boot);
-  DBG_FTL(("%s: DSP error!", IoAdapter->Properties.Name))
-  return (0) ;
- }
-#endif
-/*
- * check if CPU is alive
- */
- diva_os_wait (10) ;
- i = boot->live ;
- diva_os_wait (10) ;
- if ( i == boot->live )
- {
-  DIVA_OS_MEM_DETACH_RAM(IoAdapter, boot);
-  DBG_FTL(("%s: CPU is not alive!", IoAdapter->Properties.Name))
-  return (0) ;
- }
- if ( boot->err )
- {
-  DIVA_OS_MEM_DETACH_RAM(IoAdapter, boot);
-  DBG_FTL(("%s: Board Selftest failed!", IoAdapter->Properties.Name))
-  return (0) ;
- }
-/*
- * download protocol and dsp files
- */
- if ( !xdiSetProtocol (IoAdapter, IoAdapter->ProtocolSuffix) ) {
-  DIVA_OS_MEM_DETACH_RAM(IoAdapter, boot);
-  return (0) ;
- }
- if ( !pri_protocol_load (IoAdapter) ) {
-  DIVA_OS_MEM_DETACH_RAM(IoAdapter, boot);
-  return (0) ;
- }
- if ( !pri_telindus_load (IoAdapter) ) {
-  DIVA_OS_MEM_DETACH_RAM(IoAdapter, boot);
-  return (0) ;
- }
-/*
- * copy configuration parameters
- */
- IoAdapter->ram += MP_SHARED_RAM_OFFSET ;
- memset (boot + MP_SHARED_RAM_OFFSET, '\0', 256) ;
- diva_configure_protocol (IoAdapter);
-/*
- * start adapter
- */
- boot->addr = MP_UNCACHED_ADDR (MP_PROTOCOL_OFFSET) ;
- boot->cmd  = 3 ;
-/*
- * wait for signature in shared memory (max. 3 seconds)
- */
- for ( i = 0 ; i < 300 ; ++i )
- {
-  diva_os_wait (10) ;
-  if ( (boot->signature >> 16) == 0x4447 )
-  {
-   DIVA_OS_MEM_DETACH_RAM(IoAdapter, boot);
-   DBG_TRC(("Protocol startup time %d.%02d seconds",
-            (i / 100), (i % 100) ))
-   return (1) ;
-  }
- }
- DIVA_OS_MEM_DETACH_RAM(IoAdapter, boot);
- DBG_FTL(("%s: Adapter selftest failed (0x%04X)!",
-          IoAdapter->Properties.Name, boot->signature >> 16))
- pri_cpu_trapped (IoAdapter) ;
- return (0) ;
-}
-#else /* } { */
 static int load_pri_hardware (PISDN_ADAPTER IoAdapter) {
  return (0);
 }
-#endif /* } */
 /* --------------------------------------------------------------------------
   PRI Adapter interrupt Service Routine
    -------------------------------------------------------------------------- */
diff -Nru a/drivers/isdn/hardware/eicon/xdi_vers.h b/drivers/isdn/hardware/eicon/xdi_vers.h
--- a/drivers/isdn/hardware/eicon/xdi_vers.h	2005-03-01 23:39:08 -08:00
+++ b/drivers/isdn/hardware/eicon/xdi_vers.h	2005-03-01 23:39:08 -08:00
@@ -1,26 +1,26 @@
-
-/*
- *
-  Copyright (c) Eicon Networks, 2002.
- *
-  This source file is supplied for the use with
-  Eicon Networks range of DIVA Server Adapters.
- *
-  Eicon File Revision :    2.1
- *
-  This program is free software; you can redistribute 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 OF ANY KIND WHATSOEVER INCLUDING ANY
-  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-  See the GNU General Public License for more details.
- *
-  You 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.
- *
- */
-static char diva_xdi_common_code_build[] = "102-52"; 
+
+/*
+ *
+  Copyright (c) Eicon Networks, 2002.
+ *
+  This source file is supplied for the use with
+  Eicon Networks range of DIVA Server Adapters.
+ *
+  Eicon File Revision :    2.1
+ *
+  This program is free software; you can redistribute 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 OF ANY KIND WHATSOEVER INCLUDING ANY
+  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the GNU General Public License for more details.
+ *
+  You 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.
+ *
+ */
+static char diva_xdi_common_code_build[] = "102-52"; 
diff -Nru a/drivers/isdn/hisax/avm_a1p.c b/drivers/isdn/hisax/avm_a1p.c
--- a/drivers/isdn/hisax/avm_a1p.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/isdn/hisax/avm_a1p.c	2005-03-01 23:39:18 -08:00
@@ -231,7 +231,7 @@
 	cs->irq = card->para[0];
 
 
-	outb(cs->hw.avm.cfg_reg+ASL1_OFFSET, ASL1_W_ENABLE_S0);
+	byteout(cs->hw.avm.cfg_reg+ASL1_OFFSET, ASL1_W_ENABLE_S0);
 	byteout(cs->hw.avm.cfg_reg+ASL0_OFFSET,0x00);
 	HZDELAY(HZ / 5 + 1);
 	byteout(cs->hw.avm.cfg_reg+ASL0_OFFSET,ASL0_W_RESET);
diff -Nru a/drivers/isdn/hisax/avma1_cs.c b/drivers/isdn/hisax/avma1_cs.c
--- a/drivers/isdn/hisax/avma1_cs.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/isdn/hisax/avma1_cs.c	2005-03-01 23:39:07 -08:00
@@ -41,7 +41,7 @@
 */
 #ifdef PCMCIA_DEBUG
 static int pc_debug = PCMCIA_DEBUG;
-MODULE_PARM(pc_debug, "i");
+module_param(pc_debug, int, 0);
 #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args);
 static char *version =
 "avma1_cs.c 1.00 1998/01/23 10:00:00 (Carsten Paeth)";
@@ -53,12 +53,9 @@
 
 /* Parameters that can be set with 'insmod' */
 
-static int default_irq_list[11] = { 15, 13, 12, 11, 10, 9, 7, 5, 4, 3, -1 };
-static int irq_list[11] = { -1 };
 static int isdnprot = 2;
 
-MODULE_PARM(irq_list, "1-11i");
-MODULE_PARM(isdnprot, "1-4i");
+module_param(isdnprot, int, 0);
 
 /*====================================================================*/
 
@@ -143,7 +140,7 @@
     client_reg_t client_reg;
     dev_link_t *link;
     local_info_t *local;
-    int ret, i;
+    int ret;
     
     DEBUG(0, "avma1cs_attach()\n");
 
@@ -173,15 +170,8 @@
     link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
     link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
 
-    link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
-    if (irq_list[0] != -1) {
-	    for (i = 0; i < 10 && irq_list[i] > 0; i++)
-	       link->irq.IRQInfo2 |= 1 << irq_list[i];
-    } else {
-	    for (i = 0; i < 10 && default_irq_list[i] > 0; i++)
-	       link->irq.IRQInfo2 |= 1 << default_irq_list[i];
-    }
-    
+    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+
     /* General socket configuration */
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.Vcc = 50;
@@ -193,7 +183,6 @@
     link->next = dev_list;
     dev_list = link;
     client_reg.dev_info = &dev_info;
-    client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
     client_reg.EventMask =
 	CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
 	CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
@@ -531,13 +520,7 @@
 static void __exit exit_avma1_cs(void)
 {
 	pcmcia_unregister_driver(&avma1cs_driver);
-
-	/* XXX: this really needs to move into generic code.. */
-	while (dev_list != NULL) {
-		if (dev_list->state & DEV_CONFIG)
-			avma1cs_release(dev_list);
-		avma1cs_detach(dev_list);
-	}
+	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_avma1_cs);
diff -Nru a/drivers/isdn/hisax/config.c b/drivers/isdn/hisax/config.c
--- a/drivers/isdn/hisax/config.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/isdn/hisax/config.c	2005-03-01 23:39:09 -08:00
@@ -354,20 +354,18 @@
 static int mem[HISAX_MAX_CARDS] __devinitdata = { 0, };
 static char *id = HiSaxID;
 
-#define PARM_PARA "1-" __MODULE_STRING(HISAX_MAX_CARDS) "i"
-
 MODULE_DESCRIPTION("ISDN4Linux: Driver for passive ISDN cards");
 MODULE_AUTHOR("Karsten Keil");
 MODULE_LICENSE("GPL");
-MODULE_PARM(type, PARM_PARA);
-MODULE_PARM(protocol, PARM_PARA);
-MODULE_PARM(io, PARM_PARA);
-MODULE_PARM(irq, PARM_PARA);
-MODULE_PARM(mem, PARM_PARA);
-MODULE_PARM(id, "s");
+module_param_array(type, int, NULL, 0);
+module_param_array(protocol, int, NULL, 0);
+module_param_array(io, int, NULL, 0);
+module_param_array(irq, int, NULL, 0);
+module_param_array(mem, int, NULL, 0);
+module_param(id, charp, 0);
 #ifdef IO0_IO1
-MODULE_PARM(io0, PARM_PARA);
-MODULE_PARM(io1, PARM_PARA);
+module_param_array(io0, int, NULL, 0);
+module_param_array(io1, int, NULL, 0);
 #endif
 #endif /* MODULE */
 
diff -Nru a/drivers/isdn/hisax/elsa_cs.c b/drivers/isdn/hisax/elsa_cs.c
--- a/drivers/isdn/hisax/elsa_cs.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/isdn/hisax/elsa_cs.c	2005-03-01 23:38:57 -08:00
@@ -69,7 +69,7 @@
 
 #ifdef PCMCIA_DEBUG
 static int pc_debug = PCMCIA_DEBUG;
-MODULE_PARM(pc_debug, "i");
+module_param(pc_debug, int, 0);
 #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args);
 static char *version =
 "elsa_cs.c $Revision: 1.2.2.4 $ $Date: 2004/01/25 15:07:06 $ (K.Lichtenwalder)";
@@ -81,18 +81,8 @@
 
 /* Parameters that can be set with 'insmod' */
 
-/* Bit map of interrupts to choose from, the old way */
-/* This means pick from 15, 14, 12, 11, 10, 9, 7, 5, 4, 3 */
-static u_long irq_mask = 0xdeb8;
-
-/* Newer, simpler way of listing specific interrupts */
-static int irq_list[4] = { -1 };
-
-MODULE_PARM(irq_mask, "i");
-MODULE_PARM(irq_list, "1-4i");
-
 static int protocol = 2;        /* EURO-ISDN Default */
-MODULE_PARM(protocol, "i");
+module_param(protocol, int, 0);
 
 /*====================================================================*/
 
@@ -187,7 +177,7 @@
     client_reg_t client_reg;
     dev_link_t *link;
     local_info_t *local;
-    int ret, i;
+    int ret;
 
     DEBUG(0, "elsa_cs_attach()\n");
 
@@ -200,12 +190,7 @@
 
     /* Interrupt setup */
     link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
-    link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID|IRQ_SHARE_ID;
-    if (irq_list[0] == -1)
-        link->irq.IRQInfo2 = irq_mask;
-    else
-        for (i = 0; i < 4; i++)
-            link->irq.IRQInfo2 |= 1 << irq_list[i];
+    link->irq.IRQInfo1 = IRQ_LEVEL_ID|IRQ_SHARE_ID;
     link->irq.Handler = NULL;
 
     /*
@@ -227,7 +212,6 @@
     link->next = dev_list;
     dev_list = link;
     client_reg.dev_info = &dev_info;
-    client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
     client_reg.EventMask =
         CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
         CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
@@ -541,10 +525,7 @@
 static void __exit exit_elsa_cs(void)
 {
 	pcmcia_unregister_driver(&elsa_cs_driver);
-
-	/* XXX: this really needs to move into generic code.. */
-	while (dev_list != NULL)
-		elsa_cs_detach(dev_list);
+	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_elsa_cs);
diff -Nru a/drivers/isdn/hisax/hfc_usb.c b/drivers/isdn/hisax/hfc_usb.c
--- a/drivers/isdn/hisax/hfc_usb.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/isdn/hisax/hfc_usb.c	2005-03-01 23:38:54 -08:00
@@ -1360,9 +1360,10 @@
 //	usb_show_device_descriptor(&dev->descriptor);
 //	usb_show_interface_descriptor(&iface->desc);
 	vend_idx=0xffff;
-	for(i=0;vdata[i].vendor;i++)
-	{
-		if(dev->descriptor.idVendor==vdata[i].vendor && dev->descriptor.idProduct==vdata[i].prod_id) vend_idx=i;
+	for(i=0;vdata[i].vendor;i++) {
+		if (le16_to_cpu(dev->descriptor.idVendor) == vdata[i].vendor && 
+		    le16_to_cpu(dev->descriptor.idProduct) == vdata[i].prod_id)
+			vend_idx = i;
 	}
 	
 
@@ -1491,7 +1492,7 @@
 						case USB_ENDPOINT_XFER_INT:
 							context->fifos[cidx].pipe = usb_rcvintpipe(dev, ep->desc.bEndpointAddress);
 							context->fifos[cidx].usb_transfer_mode = USB_INT;
-							packet_size = ep->desc.wMaxPacketSize; // remember max packet size
+							packet_size = le16_to_cpu(ep->desc.wMaxPacketSize); // remember max packet size
 #ifdef VERBOSE_USB_DEBUG
 							printk (KERN_INFO "HFC-USB: Interrupt-In Endpoint found %d ms(idx:%d cidx:%d)!\n",
 								ep->desc.bInterval, idx, cidx);
@@ -1503,7 +1504,7 @@
 							else
 								context->fifos[cidx].pipe = usb_sndbulkpipe(dev, ep->desc.bEndpointAddress);
 							context->fifos[cidx].usb_transfer_mode = USB_BULK;
-							packet_size = ep->desc.wMaxPacketSize; // remember max packet size
+							packet_size = le16_to_cpu(ep->desc.wMaxPacketSize); // remember max packet size
 #ifdef VERBOSE_USB_DEBUG
 							printk (KERN_INFO "HFC-USB: Bulk Endpoint found (idx:%d cidx:%d)!\n",
 								idx, cidx);
@@ -1515,7 +1516,7 @@
 							else
 								context->fifos[cidx].pipe = usb_sndisocpipe(dev, ep->desc.bEndpointAddress);
 							context->fifos[cidx].usb_transfer_mode = USB_ISOC;
-							iso_packet_size = ep->desc.wMaxPacketSize; // remember max packet size
+							iso_packet_size = le16_to_cpu(ep->desc.wMaxPacketSize); // remember max packet size
 #ifdef VERBOSE_USB_DEBUG
 							printk (KERN_INFO "HFC-USB: ISO Endpoint found (idx:%d cidx:%d)!\n",
 								idx, cidx);
@@ -1528,7 +1529,7 @@
 					if (context->fifos[cidx].pipe) {
 						context->fifos[cidx].fifonum = cidx;
 						context->fifos[cidx].hfc = context;
-						context->fifos[cidx].usb_packet_maxlen = ep->desc.wMaxPacketSize;
+						context->fifos[cidx].usb_packet_maxlen = le16_to_cpu(ep->desc.wMaxPacketSize);
 						context->fifos[cidx].intervall = ep->desc.bInterval;
 						context->fifos[cidx].skbuff = NULL;
 #ifdef VERBOSE_USB_DEBUG
diff -Nru a/drivers/isdn/hisax/hisax_fcpcipnp.c b/drivers/isdn/hisax/hisax_fcpcipnp.c
--- a/drivers/isdn/hisax/hisax_fcpcipnp.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/isdn/hisax/hisax_fcpcipnp.c	2005-03-01 23:39:08 -08:00
@@ -45,8 +45,8 @@
 #ifdef CONFIG_HISAX_DEBUG
 static int debug = 0;
 /* static int hdlcfifosize = 32; */
-MODULE_PARM(debug, "i");
-/* MODULE_PARM(hdlcfifosize, "i"); */
+module_param(debug, int, 0);
+/* module_param(hdlcfifosize, int, 0); */
 #endif
 
 MODULE_AUTHOR("Kai Germaschewski <kai.germaschewski@gmx.de>/Karsten Keil <kkeil@suse.de>");
@@ -81,7 +81,7 @@
 #endif
 
 static int protocol = 2;       /* EURO-ISDN Default */
-MODULE_PARM(protocol, "i");
+module_param(protocol, int, 0);
 MODULE_LICENSE("GPL");
 
 // ----------------------------------------------------------------------
diff -Nru a/drivers/isdn/hisax/hisax_isac.c b/drivers/isdn/hisax/hisax_isac.c
--- a/drivers/isdn/hisax/hisax_isac.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/isdn/hisax/hisax_isac.c	2005-03-01 23:38:52 -08:00
@@ -32,7 +32,7 @@
 
 #ifdef CONFIG_HISAX_DEBUG
 static int debug = 1;
-MODULE_PARM(debug, "i");
+module_param(debug, int, 0);
 
 static char *ISACVer[] = {
   "2086/2186 V1.1", 
diff -Nru a/drivers/isdn/hisax/icc.c b/drivers/isdn/hisax/icc.c
--- a/drivers/isdn/hisax/icc.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/isdn/hisax/icc.c	2005-03-01 23:39:18 -08:00
@@ -27,7 +27,7 @@
 static char *ICCVer[] __initdata =
 {"2070 A1/A3", "2070 B1", "2070 B2/B3", "2070 V2.4"};
 
-void
+void __init
 ICCVersion(struct IsdnCardState *cs, char *s)
 {
 	int val;
diff -Nru a/drivers/isdn/hisax/icc.h b/drivers/isdn/hisax/icc.h
--- a/drivers/isdn/hisax/icc.h	2005-03-01 23:39:09 -08:00
+++ b/drivers/isdn/hisax/icc.h	2005-03-01 23:39:09 -08:00
@@ -65,7 +65,7 @@
 #define ICC_IND_AIL    0xE
 #define ICC_IND_DC     0xF
 
-extern void ICCVersion(struct IsdnCardState *cs, char *s);
+extern void __init ICCVersion(struct IsdnCardState *cs, char *s);
 extern void initicc(struct IsdnCardState *cs);
 extern void icc_interrupt(struct IsdnCardState *cs, u_char val);
 extern void clear_pending_icc_ints(struct IsdnCardState *cs);
diff -Nru a/drivers/isdn/hisax/isdnhdlc.c b/drivers/isdn/hisax/isdnhdlc.c
--- a/drivers/isdn/hisax/isdnhdlc.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/isdn/hisax/isdnhdlc.c	2005-03-01 23:39:07 -08:00
@@ -308,7 +308,7 @@
 				hdlc->crc = crc_ccitt_byte(hdlc->crc, hdlc->shift_reg);
 
 				// good byte received
-				if (dsize--) {
+				if (hdlc->dstpos < dsize) {
 					dst[hdlc->dstpos++] = hdlc->shift_reg;
 				} else {
 					// frame too long
diff -Nru a/drivers/isdn/hisax/sedlbauer_cs.c b/drivers/isdn/hisax/sedlbauer_cs.c
--- a/drivers/isdn/hisax/sedlbauer_cs.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/isdn/hisax/sedlbauer_cs.c	2005-03-01 23:38:54 -08:00
@@ -69,7 +69,7 @@
 
 #ifdef PCMCIA_DEBUG
 static int pc_debug = PCMCIA_DEBUG;
-MODULE_PARM(pc_debug, "i");
+module_param(pc_debug, int, 0);
 #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args); 
 static char *version =
 "sedlbauer_cs.c 1.1a 2001/01/28 15:04:04 (M.Niemann)";
@@ -82,17 +82,8 @@
 
 /* Parameters that can be set with 'insmod' */
 
-/* The old way: bit map of interrupts to choose from */
-/* This means pick from 15, 14, 12, 11, 10, 9, 7, 5, 4, and 3 */
-static u_int irq_mask = 0xdeb8;
-/* Newer, simpler way of listing specific interrupts */
-static int irq_list[4] = { -1 };
-
-MODULE_PARM(irq_mask, "i");
-MODULE_PARM(irq_list, "1-4i");
-
 static int protocol = 2;        /* EURO-ISDN Default */
-MODULE_PARM(protocol, "i");
+module_param(protocol, int, 0);
 
 /*====================================================================*/
 
@@ -195,7 +186,7 @@
     local_info_t *local;
     dev_link_t *link;
     client_reg_t client_reg;
-    int ret, i;
+    int ret;
     
     DEBUG(0, "sedlbauer_attach()\n");
 
@@ -208,14 +199,9 @@
     
     /* Interrupt setup */
     link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
-    link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
-    if (irq_list[0] == -1)
-	link->irq.IRQInfo2 = irq_mask;
-    else
-	for (i = 0; i < 4; i++)
-	    link->irq.IRQInfo2 |= 1 << irq_list[i];
+    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
     link->irq.Handler = NULL;
-    
+
     /*
       General socket configuration defaults can go here.  In this
       client, we assume very little, and rely on the CIS for almost
@@ -240,7 +226,6 @@
     link->next = dev_list;
     dev_list = link;
     client_reg.dev_info = &dev_info;
-    client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
     client_reg.EventMask =
 	CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
 	CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
@@ -648,13 +633,7 @@
 static void __exit exit_sedlbauer_cs(void)
 {
 	pcmcia_unregister_driver(&sedlbauer_driver);
-
-	/* XXX: this really needs to move into generic code.. */
-	while (dev_list != NULL) {
-		if (dev_list->state & DEV_CONFIG)
-			sedlbauer_release(dev_list);
-		sedlbauer_detach(dev_list);
-	}
+	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_sedlbauer_cs);
diff -Nru a/drivers/isdn/hisax/st5481_b.c b/drivers/isdn/hisax/st5481_b.c
--- a/drivers/isdn/hisax/st5481_b.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/isdn/hisax/st5481_b.c	2005-03-01 23:38:56 -08:00
@@ -274,7 +274,7 @@
 	endpoint = &altsetting->endpoint[EP_B1_OUT - 1 + bcs->channel * 2];
 
 	DBG(4,"endpoint address=%02x,packet size=%d",
-	    endpoint->desc.bEndpointAddress, endpoint->desc.wMaxPacketSize);
+	    endpoint->desc.bEndpointAddress, le16_to_cpu(endpoint->desc.wMaxPacketSize));
 
 	// Allocate memory for 8000bytes/sec + extra bytes if underrun
 	return st5481_setup_isocpipes(b_out->urb, dev, 
diff -Nru a/drivers/isdn/hisax/st5481_d.c b/drivers/isdn/hisax/st5481_d.c
--- a/drivers/isdn/hisax/st5481_d.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/isdn/hisax/st5481_d.c	2005-03-01 23:38:56 -08:00
@@ -669,7 +669,7 @@
 	endpoint = &altsetting->endpoint[EP_D_OUT-1];
 
 	DBG(2,"endpoint address=%02x,packet size=%d",
-	    endpoint->desc.bEndpointAddress, endpoint->desc.wMaxPacketSize);
+	    endpoint->desc.bEndpointAddress, le16_to_cpu(endpoint->desc.wMaxPacketSize));
 
 	return st5481_setup_isocpipes(d_out->urb, dev, 
 				      usb_sndisocpipe(dev, endpoint->desc.bEndpointAddress),
diff -Nru a/drivers/isdn/hisax/st5481_init.c b/drivers/isdn/hisax/st5481_init.c
--- a/drivers/isdn/hisax/st5481_init.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/isdn/hisax/st5481_init.c	2005-03-01 23:39:16 -08:00
@@ -37,14 +37,14 @@
 MODULE_LICENSE("GPL");
 
 static int protocol = 2;       /* EURO-ISDN Default */
-MODULE_PARM(protocol, "i");
+module_param(protocol, int, 0);
 
 static int number_of_leds = 2;       /* 2 LEDs on the adpater default */
-MODULE_PARM(number_of_leds, "i");
+module_param(number_of_leds, int, 0);
 
 #ifdef CONFIG_HISAX_DEBUG
 static int debug = 0x1;
-MODULE_PARM(debug, "i");
+module_param(debug, int, 0);
 int st5481_debug;
 #endif
 
@@ -67,7 +67,8 @@
 	int retval, i;
 
 	printk(KERN_INFO "st541: found adapter VendorId %04x, ProductId %04x, LEDs %d\n",
-	     dev->descriptor.idVendor, dev->descriptor.idProduct,
+	     le16_to_cpu(dev->descriptor.idVendor),
+	     le16_to_cpu(dev->descriptor.idProduct),
 	     number_of_leds);
 
 	adapter = kmalloc(sizeof(struct st5481_adapter), GFP_KERNEL);
diff -Nru a/drivers/isdn/hisax/st5481_usb.c b/drivers/isdn/hisax/st5481_usb.c
--- a/drivers/isdn/hisax/st5481_usb.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/isdn/hisax/st5481_usb.c	2005-03-01 23:39:07 -08:00
@@ -268,8 +268,8 @@
 	}
 
 	// The descriptor is wrong for some early samples of the ST5481 chip
-	altsetting->endpoint[3].desc.wMaxPacketSize = 32;
-	altsetting->endpoint[4].desc.wMaxPacketSize = 32;
+	altsetting->endpoint[3].desc.wMaxPacketSize = __constant_cpu_to_le16(32);
+	altsetting->endpoint[4].desc.wMaxPacketSize = __constant_cpu_to_le16(32);
 
 	// Use alternative setting 3 on interface 0 to have 2B+D
 	if ((status = usb_set_interface (dev, 0, 3)) < 0) {
diff -Nru a/drivers/isdn/hisax/teles_cs.c b/drivers/isdn/hisax/teles_cs.c
--- a/drivers/isdn/hisax/teles_cs.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/isdn/hisax/teles_cs.c	2005-03-01 23:39:09 -08:00
@@ -50,7 +50,7 @@
 
 #ifdef PCMCIA_DEBUG
 static int pc_debug = PCMCIA_DEBUG;
-MODULE_PARM(pc_debug, "i");
+module_param(pc_debug, int, 0);
 #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args);
 static char *version =
 "teles_cs.c 2.10 2002/07/30 22:23:34 kkeil";
@@ -62,18 +62,8 @@
 
 /* Parameters that can be set with 'insmod' */
 
-/* Bit map of interrupts to choose from, the old way */
-/* This means pick from 15, 14, 12, 11, 10, 9, 7, 5, 4, 3 */
-static u_long irq_mask = 0xdeb8;
-
-/* Newer, simpler way of listing specific interrupts */
-static int irq_list[4] = { -1 };
-
-MODULE_PARM(irq_mask, "i");
-MODULE_PARM(irq_list, "1-4i");
-
 static int protocol = 2;        /* EURO-ISDN Default */
-MODULE_PARM(protocol, "i");
+module_param(protocol, int, 0);
 
 /*====================================================================*/
 
@@ -168,7 +158,7 @@
     client_reg_t client_reg;
     dev_link_t *link;
     local_info_t *local;
-    int ret, i;
+    int ret;
 
     DEBUG(0, "teles_attach()\n");
 
@@ -181,12 +171,7 @@
 
     /* Interrupt setup */
     link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
-    link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID|IRQ_SHARE_ID;
-    if (irq_list[0] == -1)
-        link->irq.IRQInfo2 = irq_mask;
-    else
-        for (i = 0; i < 4; i++)
-            link->irq.IRQInfo2 |= 1 << irq_list[i];
+    link->irq.IRQInfo1 = IRQ_LEVEL_ID|IRQ_SHARE_ID;
     link->irq.Handler = NULL;
 
     /*
@@ -208,7 +193,6 @@
     link->next = dev_list;
     dev_list = link;
     client_reg.dev_info = &dev_info;
-    client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
     client_reg.EventMask =
         CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
         CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
@@ -522,10 +506,7 @@
 static void __exit exit_teles_cs(void)
 {
 	pcmcia_unregister_driver(&teles_cs_driver);
-
-	/* XXX: this really needs to move into generic code.. */
-	while (dev_list != NULL)
-		teles_detach(dev_list);
+	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_teles_cs);
diff -Nru a/drivers/isdn/i4l/Kconfig b/drivers/isdn/i4l/Kconfig
--- a/drivers/isdn/i4l/Kconfig	2005-03-01 23:38:55 -08:00
+++ b/drivers/isdn/i4l/Kconfig	2005-03-01 23:38:55 -08:00
@@ -58,7 +58,7 @@
 	help
 	  If you say Y here, the modem-emulator will support a subset of the
 	  EIA Class 8 Voice commands. Using a getty with voice-support
-	  (mgetty+sendfax by gert@greenie.muc.de with an extension, available
+	  (mgetty+sendfax by <gert@greenie.muc.de> with an extension, available
 	  with the ISDN utility package for example), you will be able to use
 	  your Linux box as an ISDN-answering machine. Of course, this must be
 	  supported by the lowlevel driver also. Currently, the HiSax driver
diff -Nru a/drivers/isdn/i4l/isdn_net.h b/drivers/isdn/i4l/isdn_net.h
--- a/drivers/isdn/i4l/isdn_net.h	2005-03-01 23:39:09 -08:00
+++ b/drivers/isdn/i4l/isdn_net.h	2005-03-01 23:39:09 -08:00
@@ -78,18 +78,19 @@
 
 	spin_lock_irqsave(&nd->queue_lock, flags);
 	lp = nd->queue;         /* get lp on top of queue */
-	spin_lock_bh(&nd->queue->xmit_lock);
+	spin_lock(&nd->queue->xmit_lock);
 	while (isdn_net_lp_busy(nd->queue)) {
-		spin_unlock_bh(&nd->queue->xmit_lock);
+		spin_unlock(&nd->queue->xmit_lock);
 		nd->queue = nd->queue->next;
 		if (nd->queue == lp) { /* not found -- should never happen */
 			lp = NULL;
 			goto errout;
 		}
-		spin_lock_bh(&nd->queue->xmit_lock);
+		spin_lock(&nd->queue->xmit_lock);
 	}
 	lp = nd->queue;
 	nd->queue = nd->queue->next;
+	local_bh_disable();
 errout:
 	spin_unlock_irqrestore(&nd->queue_lock, flags);
 	return lp;
diff -Nru a/drivers/isdn/icn/icn.c b/drivers/isdn/icn/icn.c
--- a/drivers/isdn/icn/icn.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/isdn/icn/icn.c	2005-03-01 23:39:18 -08:00
@@ -21,13 +21,13 @@
 MODULE_DESCRIPTION("ISDN4Linux: Driver for ICN active ISDN card");
 MODULE_AUTHOR("Fritz Elfert");
 MODULE_LICENSE("GPL");
-MODULE_PARM(portbase, "i");
+module_param(portbase, int, 0);
 MODULE_PARM_DESC(portbase, "Port address of first card");
-MODULE_PARM(membase, "l");
+module_param(membase, ulong, 0);
 MODULE_PARM_DESC(membase, "Shared memory address of all cards");
-MODULE_PARM(icn_id, "s");
+module_param(icn_id, charp, 0);
 MODULE_PARM_DESC(icn_id, "ID-String of first card");
-MODULE_PARM(icn_id2, "s");
+module_param(icn_id2, charp, 0);
 MODULE_PARM_DESC(icn_id2, "ID-String of first card, second S0 (4B only)");
 
 /*
diff -Nru a/drivers/isdn/icn/icn.h b/drivers/isdn/icn/icn.h
--- a/drivers/isdn/icn/icn.h	2005-03-01 23:39:17 -08:00
+++ b/drivers/isdn/icn/icn.h	2005-03-01 23:39:17 -08:00
@@ -174,7 +174,7 @@
 typedef struct icn_dev {
 	spinlock_t devlock;     /* spinlock to protect this struct  */
 	unsigned long memaddr;	/* Address of memory mapped buffers */
-	icn_shmem *shmem;       /* Pointer to memory-mapped-buffers */
+	icn_shmem __iomem *shmem;       /* Pointer to memory-mapped-buffers */
 	int mvalid;             /* IO-shmem has been requested      */
 	int channel;            /* Currently mapped channel         */
 	struct icn_card *mcard; /* Currently mapped card            */
diff -Nru a/drivers/isdn/pcbit/drv.c b/drivers/isdn/pcbit/drv.c
--- a/drivers/isdn/pcbit/drv.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/isdn/pcbit/drv.c	2005-03-01 23:39:08 -08:00
@@ -96,7 +96,7 @@
 			dev_pcbit[board] = NULL;
 			return -EACCES;
 		}
-		dev->sh_mem = (unsigned char*)ioremap(dev->ph_mem, 4096);
+		dev->sh_mem = ioremap(dev->ph_mem, 4096);
 	}
 	else 
 	{
@@ -109,7 +109,7 @@
 	dev->b1 = kmalloc(sizeof(struct pcbit_chan), GFP_KERNEL);
 	if (!dev->b1) {
 		printk("pcbit_init: couldn't malloc pcbit_chan struct\n");
-		iounmap((unsigned char*)dev->sh_mem);
+		iounmap(dev->sh_mem);
 		release_mem_region(dev->ph_mem, 4096);
 		kfree(dev);
 		return -ENOMEM;
@@ -119,7 +119,7 @@
 	if (!dev->b2) {
 		printk("pcbit_init: couldn't malloc pcbit_chan struct\n");
 		kfree(dev->b1);
-		iounmap((unsigned char*)dev->sh_mem);
+		iounmap(dev->sh_mem);
 		release_mem_region(dev->ph_mem, 4096);
 		kfree(dev);
 		return -ENOMEM;
@@ -139,7 +139,7 @@
 	{
 		kfree(dev->b1);
 		kfree(dev->b2);
-		iounmap((unsigned char*)dev->sh_mem);
+		iounmap(dev->sh_mem);
 		release_mem_region(dev->ph_mem, 4096);
 		kfree(dev);
 		dev_pcbit[board] = NULL;
@@ -161,7 +161,7 @@
 		free_irq(irq, dev);
 		kfree(dev->b1);
 		kfree(dev->b2);
-		iounmap((unsigned char*)dev->sh_mem);
+		iounmap(dev->sh_mem);
 		release_mem_region(dev->ph_mem, 4096);
 		kfree(dev);
 		dev_pcbit[board] = NULL;
@@ -193,7 +193,7 @@
 		free_irq(irq, dev);
 		kfree(dev->b1);
 		kfree(dev->b2);
-		iounmap((unsigned char*)dev->sh_mem);
+		iounmap(dev->sh_mem);
 		release_mem_region(dev->ph_mem, 4096);
 		kfree(dev);
 		dev_pcbit[board] = NULL;
@@ -231,7 +231,7 @@
 			del_timer(&dev->b2->fsm_timer);
 		kfree(dev->b1);
 		kfree(dev->b2);
-		iounmap((unsigned char*)dev->sh_mem);
+		iounmap(dev->sh_mem);
 		release_mem_region(dev->ph_mem, 4096);
 		kfree(dev);
 	}
diff -Nru a/drivers/isdn/pcbit/module.c b/drivers/isdn/pcbit/module.c
--- a/drivers/isdn/pcbit/module.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/isdn/pcbit/module.c	2005-03-01 23:39:07 -08:00
@@ -22,11 +22,12 @@
 MODULE_DESCRIPTION("ISDN4Linux: Driver for PCBIT-T card");
 MODULE_AUTHOR("Pedro Roque Marques");
 MODULE_LICENSE("GPL");
-MODULE_PARM(mem, "1-" __MODULE_STRING(MAX_PCBIT_CARDS) "i");
-MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_PCBIT_CARDS) "i");
 
 static int mem[MAX_PCBIT_CARDS];
 static int irq[MAX_PCBIT_CARDS];
+
+module_param_array(mem, int, NULL, 0);
+module_param_array(irq, int, NULL, 0);
 
 static int num_boards;
 struct pcbit_dev * dev_pcbit[MAX_PCBIT_CARDS];
diff -Nru a/drivers/isdn/pcbit/pcbit.h b/drivers/isdn/pcbit/pcbit.h
--- a/drivers/isdn/pcbit/pcbit.h	2005-03-01 23:38:52 -08:00
+++ b/drivers/isdn/pcbit/pcbit.h	2005-03-01 23:38:52 -08:00
@@ -45,7 +45,7 @@
 struct pcbit_dev {
 	/* board */
 
-	volatile unsigned char* sh_mem;		/* RDP address	*/
+	volatile unsigned char __iomem *sh_mem;		/* RDP address	*/
 	unsigned long ph_mem;
 	unsigned int irq;
 	unsigned int id;
@@ -79,8 +79,8 @@
 	u_char w_busy;
 	u_char r_busy;
 
-	volatile unsigned char *readptr;
-	volatile unsigned char *writeptr;
+	volatile unsigned char __iomem *readptr;
+	volatile unsigned char __iomem *writeptr;
 
 	ushort loadptr;
 
diff -Nru a/drivers/isdn/sc/init.c b/drivers/isdn/sc/init.c
--- a/drivers/isdn/sc/init.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/isdn/sc/init.c	2005-03-01 23:39:08 -08:00
@@ -15,10 +15,6 @@
 MODULE_DESCRIPTION("ISDN4Linux: Driver for Spellcaster card");
 MODULE_AUTHOR("Spellcaster Telecommunications Inc.");
 MODULE_LICENSE("GPL");
-MODULE_PARM( io, "1-" __MODULE_STRING(MAX_CARDS) "i");
-MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_CARDS) "i");
-MODULE_PARM(ram, "1-" __MODULE_STRING(MAX_CARDS) "i");
-MODULE_PARM(do_reset, "i");
 
 board *sc_adapter[MAX_CARDS];
 int cinst;
@@ -33,6 +29,11 @@
 static unsigned char irq[] = {0,0,0,0};
 static unsigned long ram[] = {0,0,0,0};
 static int do_reset = 0;
+
+module_param_array(io, int, NULL, 0);
+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
diff -Nru a/drivers/isdn/tpam/Kconfig b/drivers/isdn/tpam/Kconfig
--- a/drivers/isdn/tpam/Kconfig	2005-03-01 23:38:51 -08:00
+++ b/drivers/isdn/tpam/Kconfig	2005-03-01 23:38:51 -08:00
@@ -11,5 +11,5 @@
 	  to be downloaded into the card using a utility which is distributed
 	  separately from the Auvertech's web site: <http://www.auvertech.fr/>.
 
-	  Please redirect all support questions to support@auvertech.fr.
+	  Please redirect all support questions to <support@auvertech.fr>.
 
diff -Nru a/drivers/isdn/tpam/tpam_main.c b/drivers/isdn/tpam/tpam_main.c
--- a/drivers/isdn/tpam/tpam_main.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/isdn/tpam/tpam_main.c	2005-03-01 23:39:08 -08:00
@@ -39,7 +39,7 @@
 MODULE_AUTHOR("Stelian Pop");
 MODULE_LICENSE("GPL");
 MODULE_PARM_DESC(id,"ID-String of the driver");
-MODULE_PARM(id,"s");
+module_param(id, charp, 0);
 
 /*
  * Finds a board by its driver ID.
@@ -105,7 +105,7 @@
 	memset((char *)card, 0, sizeof(tpam_card));
 
 	card->irq = dev->irq;
-	card->lock = SPIN_LOCK_UNLOCKED;
+	spin_lock_init(&card->lock);
 	sprintf(card->interface.id, "%s%d", id, cards_num);
 
 	/* request interrupt */
diff -Nru a/drivers/macintosh/adb.c b/drivers/macintosh/adb.c
--- a/drivers/macintosh/adb.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/macintosh/adb.c	2005-03-01 23:39:18 -08:00
@@ -120,7 +120,7 @@
  * called.
  */
 static DECLARE_MUTEX(adb_handler_sem);
-static rwlock_t adb_handler_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(adb_handler_lock);
 
 #if 0
 static void printADBreply(struct adb_request *req)
diff -Nru a/drivers/macintosh/adbhid.c b/drivers/macintosh/adbhid.c
--- a/drivers/macintosh/adbhid.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/macintosh/adbhid.c	2005-03-01 23:39:18 -08:00
@@ -569,7 +569,7 @@
 static int pending_devs[16];
 static int pending_led_start=0;
 static int pending_led_end=0;
-static spinlock_t leds_lock  = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(leds_lock);
 
 static void leds_done(struct adb_request *req)
 {
diff -Nru a/drivers/macintosh/macio-adb.c b/drivers/macintosh/macio-adb.c
--- a/drivers/macintosh/macio-adb.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/macintosh/macio-adb.c	2005-03-01 23:39:17 -08:00
@@ -59,7 +59,7 @@
 
 static volatile struct adb_regs __iomem *adb;
 static struct adb_request *current_req, *last_req;
-static spinlock_t macio_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(macio_lock);
 
 static int macio_probe(void);
 static int macio_init(void);
diff -Nru a/drivers/macintosh/via-cuda.c b/drivers/macintosh/via-cuda.c
--- a/drivers/macintosh/via-cuda.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/macintosh/via-cuda.c	2005-03-01 23:38:52 -08:00
@@ -33,7 +33,7 @@
 #include <linux/init.h>
 
 static volatile unsigned char __iomem *via;
-static spinlock_t cuda_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(cuda_lock);
 
 #ifdef CONFIG_MAC
 #define CUDA_IRQ IRQ_MAC_ADB
diff -Nru a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c
--- a/drivers/macintosh/via-pmu.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/macintosh/via-pmu.c	2005-03-01 23:39:16 -08:00
@@ -45,6 +45,7 @@
 #include <linux/device.h>
 #include <linux/suspend.h>
 #include <linux/syscalls.h>
+#include <linux/cpu.h>
 #include <asm/prom.h>
 #include <asm/machdep.h>
 #include <asm/io.h>
@@ -152,7 +153,6 @@
 #ifdef CONFIG_PMAC_PBOOK
 static int option_lid_wakeup = 1;
 static int sleep_in_progress;
-static int can_sleep;
 #endif /* CONFIG_PMAC_PBOOK */
 static unsigned long async_req_locks;
 static unsigned int pmu_irq_stats[11];
@@ -406,8 +406,6 @@
 	bright_req_2.complete = 1;
 #ifdef CONFIG_PMAC_PBOOK
 	batt_req.complete = 1;
-	if (pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,-1) >= 0)
-		can_sleep = 1;
 #endif
 
 	if (request_irq(vias->intrs[0].line, via_pmu_interrupt, 0, "VIA-PMU",
@@ -418,7 +416,7 @@
 	}
 
 	if (pmu_kind == PMU_KEYLARGO_BASED && gpio_irq != -1) {
-		if (request_irq(gpio_irq, gpio1_interrupt, 0, "GPIO1/ADB", (void *)0))
+		if (request_irq(gpio_irq, gpio1_interrupt, 0, "GPIO1 ADB", (void *)0))
 			printk(KERN_ERR "pmu: can't get irq %d (GPIO1)\n", gpio_irq);
 		gpio_irq_enabled = 1;
 	}
@@ -885,7 +883,8 @@
 	char *p = page;
 
 #ifdef CONFIG_PMAC_PBOOK
-	if (pmu_kind == PMU_KEYLARGO_BASED && can_sleep)
+	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 */
 	if (pmu_kind == PMU_KEYLARGO_BASED)
@@ -925,7 +924,8 @@
 	while(*val == ' ')
 		val++;
 #ifdef CONFIG_PMAC_PBOOK
-	if (pmu_kind == PMU_KEYLARGO_BASED && can_sleep)
+	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 */
@@ -2313,7 +2313,7 @@
 pmac_suspend_devices(void)
 {
 	int ret;
-	
+
 	pm_prepare_console();
 	
 	/* Notify old-style device drivers & userland */
@@ -2341,13 +2341,13 @@
 	/* Send suspend call to devices, hold the device core's dpm_sem */
 	ret = device_suspend(PM_SUSPEND_MEM);
 	if (ret) {
-		printk(KERN_ERR "Driver sleep failed\n");
 		broadcast_wake();
+		printk(KERN_ERR "Driver sleep failed\n");
 		return -EBUSY;
 	}
-	
+
 	preempt_disable();
-	
+
 	/* Make sure the decrementer won't interrupt us */
 	asm volatile("mtdec %0" : : "r" (0x7fffffff));
 	/* Make sure any pending DEC interrupt occurring while we did
@@ -2404,8 +2404,6 @@
 	/* Power back up system devices (including the PIC) */
 	device_power_up();
 
-	pmu_blink(1);
-
 	/* Force a poll of ADB interrupts */
 	adb_int_pending = 1;
 	via_pmu_interrupt(0, NULL, NULL);
@@ -2416,7 +2414,7 @@
 	/* Re-enable local CPU interrupts */
 	local_irq_enable();
 
-	pmu_blink(1);
+	mdelay(100);
 
 	preempt_enable();
 
@@ -2464,8 +2462,6 @@
 
 	/* For 750, save backside cache setting and disable it */
 	save_l2cr = _get_L2CR();	/* (returns -1 if not available) */
-	if (save_l2cr != 0xffffffff && (save_l2cr & L2CR_L2E) != 0)
-		_set_L2CR(save_l2cr & 0x7fffffff);
 
 	if (!__fake_sleep) {
 		/* Ask the PMU to put us to sleep */
@@ -2530,17 +2526,22 @@
 	struct adb_request req;
 	int ret;
 	
-	if (!can_sleep) {
+	if (pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,-1) < 0) {
 		printk(KERN_ERR "Sleep mode not supported on this machine\n");
 		return -ENOSYS;
 	}
-	
+
+	if (num_online_cpus() > 1 || cpu_is_offline(0))
+		return -EAGAIN;
+
 	ret = pmac_suspend_devices();
 	if (ret) {
 		printk(KERN_ERR "Sleep rejected by devices\n");
 		return ret;
 	}
-	
+
+	printk(KERN_DEBUG "HID1, before: %x\n", mfspr(SPRN_HID1));
+
 	/* Tell PMU what events will wake us up */
 	pmu_request(&req, NULL, 4, PMU_POWER_EVENTS, PMU_PWR_CLR_WAKEUP_EVENTS,
 		0xff, 0xff);
@@ -2550,16 +2551,9 @@
 		(option_lid_wakeup ? PMU_PWR_WAKEUP_LID_OPEN : 0));
 	pmu_wait_complete(&req);
 
-	/* Save & disable L2 and L3 caches*/
+	/* Save the state of the L2 and L3 caches */
 	save_l3cr = _get_L3CR();	/* (returns -1 if not available) */
 	save_l2cr = _get_L2CR();	/* (returns -1 if not available) */
-	if (save_l3cr != 0xffffffff && (save_l3cr & L3CR_L3E) != 0)
-		_set_L3CR(save_l3cr & 0x7fffffff);
-	if (save_l2cr != 0xffffffff && (save_l2cr & L2CR_L2E) != 0)
-		_set_L2CR(save_l2cr & 0x7fffffff);
-
-	/* Save the state of PCI config space for some slots */
-	//pbook_pci_save();
 
 	if (!__fake_sleep) {
 		/* Ask the PMU to put us to sleep */
@@ -2574,7 +2568,7 @@
 	 * talk to the PMU after this, so I moved it to _after_ sending the
 	 * sleep command to it. Still need to be checked.
 	 */
-	pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,1);
+	pmac_call_feature(PMAC_FTR_SLEEP_STATE, NULL, 0, 1);
 
 	/* Call low-level ASM sleep handler */
 	if (__fake_sleep)
@@ -2583,18 +2577,13 @@
 		low_sleep_handler();
 
 	/* Restore Apple core ASICs state */
-	pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,0);
+	pmac_call_feature(PMAC_FTR_SLEEP_STATE, NULL, 0, 0);
 
 	/* Restore VIA */
 	restore_via_state();
 
-	/* Restore PCI config space. This should be overridable by PCI device
-	 * drivers as some of them may need special restore code. That's yet
-	 * another issue that should be handled by the common code properly,
-	 * maybe one day ?
-	 */
-	/* Don't restore PCI for now, it crashes. Maybe unnecessary on pbook */
-	//pbook_pci_restore();
+	/* Restore video */
+	pmac_call_early_video_resume();
 
 	/* Restore L2 cache */
 	if (save_l2cr != 0xffffffff && (save_l2cr & L2CR_L2E) != 0)
@@ -2613,7 +2602,7 @@
 	pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, pmu_intr_mask);
 	pmu_wait_complete(&req);
 
-	pmu_blink(1);
+	printk(KERN_DEBUG "HID1, after: %x\n", mfspr(SPRN_HID1));
 
 	pmac_wakeup_devices();
 
@@ -2721,7 +2710,7 @@
 };
 
 static LIST_HEAD(all_pmu_pvt);
-static spinlock_t all_pvt_lock __pmacdata = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(all_pvt_lock __pmacdata);
 
 static void __pmac
 pmu_pass_intr(unsigned char *data, int len)
@@ -2909,7 +2898,10 @@
 		sleep_in_progress = 0;
 		return error;
 	case PMU_IOC_CAN_SLEEP:
-		return put_user((u32)can_sleep, argp);
+		if (pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,-1) < 0)
+			return put_user(0, argp);
+		else
+			return put_user(1, argp);
 
 #ifdef CONFIG_PMAC_BACKLIGHT
 	/* Backlight should have its own device or go via
diff -Nru a/drivers/mca/mca-bus.c b/drivers/mca/mca-bus.c
--- a/drivers/mca/mca-bus.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/mca/mca-bus.c	2005-03-01 23:38:53 -08:00
@@ -34,7 +34,7 @@
 /* Very few machines have more than one MCA bus.  However, there are
  * those that do (Voyager 35xx/5xxx), so we do it this way for future
  * expansion.  None that I know have more than 2 */
-struct mca_bus *mca_root_busses[MAX_MCA_BUSSES];
+static struct mca_bus *mca_root_busses[MAX_MCA_BUSSES];
 
 #define MCA_DEVINFO(i,s) { .pos = i, .name = s }
 
diff -Nru a/drivers/mca/mca-legacy.c b/drivers/mca/mca-legacy.c
--- a/drivers/mca/mca-legacy.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/mca/mca-legacy.c	2005-03-01 23:39:18 -08:00
@@ -283,25 +283,6 @@
 EXPORT_SYMBOL(mca_set_adapter_name);
 
 /**
- *	mca_get_adapter_name - get the adapter description
- *	@slot:	slot to query
- *
- *	Return the adapter description if set. If it has not been
- *	set or the slot is out range then return NULL.
- */
-
-char *mca_get_adapter_name(int slot)
-{
-	struct mca_device *mca_dev = mca_find_device_by_slot(slot);
-
-	if(!mca_dev)
-		return NULL;
-
-	return mca_device_get_name(mca_dev);
-}
-EXPORT_SYMBOL(mca_get_adapter_name);
-
-/**
  *	mca_is_adapter_used - check if claimed by driver
  *	@slot:	slot to check
  *
@@ -365,43 +346,3 @@
 }
 EXPORT_SYMBOL(mca_mark_as_unused);
 
-/**
- *	mca_isadapter - check if the slot holds an adapter
- *	@slot:	slot to query
- *
- *	Returns zero if the slot does not hold an adapter, non zero if
- *	it does.
- */
-
-int mca_isadapter(int slot)
-{
-	struct mca_device *mca_dev = mca_find_device_by_slot(slot);
-	enum MCA_AdapterStatus status;
-
-	if(!mca_dev)
-		return 0;
-
-	status = mca_device_status(mca_dev);
-
-	return status == MCA_ADAPTER_NORMAL
-		|| status == MCA_ADAPTER_DISABLED;
-}
-EXPORT_SYMBOL(mca_isadapter);
-
-/**
- *	mca_isenabled - check if the slot holds an enabled adapter
- *	@slot:	slot to query
- *
- *	Returns a non zero value if the slot holds an enabled adapter
- *	and zero for any other case.
- */
-
-int mca_isenabled(int slot)
-{
-	struct mca_device *mca_dev = mca_find_device_by_slot(slot);
-
-	if(!mca_dev)
-		return 0;
-
-	return mca_device_status(mca_dev) == MCA_ADAPTER_NORMAL;
-}
diff -Nru a/drivers/mca/mca-proc.c b/drivers/mca/mca-proc.c
--- a/drivers/mca/mca-proc.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/mca/mca-proc.c	2005-03-01 23:39:08 -08:00
@@ -43,8 +43,8 @@
 	return len;
 }
 
-int get_mca_info(char *page, char **start, off_t off,
-		 int count, int *eof, void *data)
+static int get_mca_info(char *page, char **start, off_t off,
+			int count, int *eof, void *data)
 {
 	int i, len = 0;
 
diff -Nru a/drivers/md/Kconfig b/drivers/md/Kconfig
--- a/drivers/md/Kconfig	2005-03-01 23:38:52 -08:00
+++ b/drivers/md/Kconfig	2005-03-01 23:38:52 -08:00
@@ -200,7 +200,7 @@
 
 	  Information on how to use dm-crypt can be found on
 
-	  http://www.saout.de/misc/dm-crypt/
+	  <http://www.saout.de/misc/dm-crypt/>
 
 	  To compile this code as a module, choose M here: the module will
 	  be called dm-crypt.
diff -Nru a/drivers/md/Makefile b/drivers/md/Makefile
--- a/drivers/md/Makefile	2005-03-01 23:38:58 -08:00
+++ b/drivers/md/Makefile	2005-03-01 23:38:58 -08:00
@@ -9,6 +9,8 @@
 raid6-objs	:= raid6main.o raid6algos.o raid6recov.o raid6tables.o \
 		   raid6int1.o raid6int2.o raid6int4.o \
 		   raid6int8.o raid6int16.o raid6int32.o \
+		   raid6altivec1.o raid6altivec2.o raid6altivec4.o \
+		   raid6altivec8.o \
 		   raid6mmx.o raid6sse1.o raid6sse2.o
 hostprogs-y	:= mktables
 
@@ -36,6 +38,10 @@
       cmd_unroll = $(PERL) $(srctree)/$(src)/unroll.pl $(UNROLL) \
                    < $< > $@ || ( rm -f $@ && exit 1 )
 
+ifeq ($(CONFIG_ALTIVEC),y)
+altivec_flags := -maltivec -mabi=altivec
+endif
+
 targets += raid6int1.c
 $(obj)/raid6int1.c:   UNROLL := 1
 $(obj)/raid6int1.c:   $(src)/raid6int.uc $(src)/unroll.pl FORCE
@@ -64,6 +70,30 @@
 targets += raid6int32.c
 $(obj)/raid6int32.c:  UNROLL := 32
 $(obj)/raid6int32.c:  $(src)/raid6int.uc $(src)/unroll.pl FORCE
+	$(call if_changed,unroll)
+
+CFLAGS_raid6altivec1.o += $(altivec_flags)
+targets += raid6altivec1.c
+$(obj)/raid6altivec1.c:   UNROLL := 1
+$(obj)/raid6altivec1.c:   $(src)/raid6altivec.uc $(src)/unroll.pl FORCE
+	$(call if_changed,unroll)
+
+CFLAGS_raid6altivec2.o += $(altivec_flags)
+targets += raid6altivec2.c
+$(obj)/raid6altivec2.c:   UNROLL := 2
+$(obj)/raid6altivec2.c:   $(src)/raid6altivec.uc $(src)/unroll.pl FORCE
+	$(call if_changed,unroll)
+
+CFLAGS_raid6altivec4.o += $(altivec_flags)
+targets += raid6altivec4.c
+$(obj)/raid6altivec4.c:   UNROLL := 4
+$(obj)/raid6altivec4.c:   $(src)/raid6altivec.uc $(src)/unroll.pl FORCE
+	$(call if_changed,unroll)
+
+CFLAGS_raid6altivec8.o += $(altivec_flags)
+targets += raid6altivec8.c
+$(obj)/raid6altivec8.c:   UNROLL := 8
+$(obj)/raid6altivec8.c:   $(src)/raid6altivec.uc $(src)/unroll.pl FORCE
 	$(call if_changed,unroll)
 
 quiet_cmd_mktable = TABLE   $@
diff -Nru a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
--- a/drivers/md/dm-crypt.c	2005-03-01 23:38:44 -08:00
+++ b/drivers/md/dm-crypt.c	2005-03-01 23:38:44 -08:00
@@ -329,7 +329,7 @@
                    struct bio *base_bio, unsigned int *bio_vec_idx)
 {
 	struct bio *bio;
-	unsigned int nr_iovecs = dm_div_up(size, PAGE_SIZE);
+	unsigned int nr_iovecs = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
 	int gfp_mask = GFP_NOIO | __GFP_HIGHMEM;
 	unsigned long flags = current->flags;
 	unsigned int i;
diff -Nru a/drivers/md/dm-io.c b/drivers/md/dm-io.c
--- a/drivers/md/dm-io.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/md/dm-io.c	2005-03-01 23:39:17 -08:00
@@ -149,22 +149,6 @@
 	return 0;
 }
 
-static inline void bs_bio_init(struct bio *bio)
-{
-	bio->bi_next = NULL;
-	bio->bi_flags = 1 << BIO_UPTODATE;
-	bio->bi_rw = 0;
-	bio->bi_vcnt = 0;
-	bio->bi_idx = 0;
-	bio->bi_phys_segments = 0;
-	bio->bi_hw_segments = 0;
-	bio->bi_size = 0;
-	bio->bi_max_vecs = 0;
-	bio->bi_end_io = NULL;
-	atomic_set(&bio->bi_cnt, 1);
-	bio->bi_private = NULL;
-}
-
 static unsigned _bio_count = 0;
 struct bio *bio_set_alloc(struct bio_set *bs, int gfp_mask, int nr_iovecs)
 {
diff -Nru a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
--- a/drivers/md/dm-ioctl.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/md/dm-ioctl.c	2005-03-01 23:38:54 -08:00
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2001, 2002 Sistina Software (UK) Limited.
- * Copyright (C) 2004 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2004 - 2005 Red Hat, Inc. All rights reserved.
  *
  * This file is released under the GPL.
  */
@@ -520,19 +520,22 @@
 	if (dm_suspended(md))
 		param->flags |= DM_SUSPEND_FLAG;
 
-	bdev = bdget_disk(disk, 0);
-	if (!bdev)
-		return -ENXIO;
-
 	param->dev = huge_encode_dev(MKDEV(disk->major, disk->first_minor));
 
-	/*
-	 * Yes, this will be out of date by the time it gets back
-	 * to userland, but it is still very useful ofr
-	 * debugging.
-	 */
-	param->open_count = bdev->bd_openers;
-	bdput(bdev);
+	if (!(param->flags & DM_SKIP_BDGET_FLAG)) {
+		bdev = bdget_disk(disk, 0);
+		if (!bdev)
+			return -ENXIO;
+
+		/*
+		 * Yes, this will be out of date by the time it gets back
+		 * to userland, but it is still very useful for
+		 * debugging.
+		 */
+		param->open_count = bdev->bd_openers;
+		bdput(bdev);
+	} else
+		param->open_count = -1;
 
 	if (disk->policy)
 		param->flags |= DM_READONLY_FLAG;
diff -Nru a/drivers/md/dm-log.c b/drivers/md/dm-log.c
--- a/drivers/md/dm-log.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/md/dm-log.c	2005-03-01 23:39:17 -08:00
@@ -13,13 +13,10 @@
 #include "dm-io.h"
 
 static LIST_HEAD(_log_types);
-static spinlock_t _lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(_lock);
 
 int dm_register_dirty_log_type(struct dirty_log_type *type)
 {
-	if (!try_module_get(type->module))
-		return -EINVAL;
-
 	spin_lock(&_lock);
 	type->use_count = 0;
 	list_add(&type->list, &_log_types);
@@ -34,10 +31,8 @@
 
 	if (type->use_count)
 		DMWARN("Attempt to unregister a log type that is still in use");
-	else {
+	else
 		list_del(&type->list);
-		module_put(type->module);
-	}
 
 	spin_unlock(&_lock);
 
@@ -51,6 +46,10 @@
 	spin_lock(&_lock);
 	list_for_each_entry (type, &_log_types, list)
 		if (!strcmp(type_name, type->name)) {
+			if (!type->use_count && !try_module_get(type->module)){
+				spin_unlock(&_lock);
+				return NULL;
+			}
 			type->use_count++;
 			spin_unlock(&_lock);
 			return type;
@@ -63,7 +62,8 @@
 static void put_type(struct dirty_log_type *type)
 {
 	spin_lock(&_lock);
-	type->use_count--;
+	if (!--type->use_count)
+		module_put(type->module);
 	spin_unlock(&_lock);
 }
 
@@ -129,7 +129,7 @@
 struct log_c {
 	struct dm_target *ti;
 	int touched;
-	sector_t region_size;
+	uint32_t region_size;
 	unsigned int region_count;
 	region_t sync_count;
 
@@ -292,7 +292,7 @@
 	enum sync sync = DEFAULTSYNC;
 
 	struct log_c *lc;
-	sector_t region_size;
+	uint32_t region_size;
 	unsigned int region_count;
 	size_t bitset_size;
 
@@ -313,12 +313,12 @@
 		}
 	}
 
-	if (sscanf(argv[0], SECTOR_FORMAT, &region_size) != 1) {
+	if (sscanf(argv[0], "%u", &region_size) != 1) {
 		DMWARN("invalid region size string");
 		return -EINVAL;
 	}
 
-	region_count = dm_div_up(ti->len, region_size);
+	region_count = dm_sector_div_up(ti->len, region_size);
 
 	lc = kmalloc(sizeof(*lc), GFP_KERNEL);
 	if (!lc) {
@@ -508,7 +508,7 @@
 	return write_header(lc);
 }
 
-static sector_t core_get_region_size(struct dirty_log *log)
+static uint32_t core_get_region_size(struct dirty_log *log)
 {
 	struct log_c *lc = (struct log_c *) log->context;
 	return lc->region_size;
@@ -616,7 +616,7 @@
 		break;
 
 	case STATUSTYPE_TABLE:
-		DMEMIT("%s %u " SECTOR_FORMAT " ", log->type->name,
+		DMEMIT("%s %u %u ", log->type->name,
 		       lc->sync == DEFAULTSYNC ? 1 : 2, lc->region_size);
 		DMEMIT_SYNC;
 	}
@@ -637,7 +637,7 @@
 
 	case STATUSTYPE_TABLE:
 		format_dev_t(buffer, lc->log_dev->bdev->bd_dev);
-		DMEMIT("%s %u %s " SECTOR_FORMAT " ", log->type->name,
+		DMEMIT("%s %u %s %u ", log->type->name,
 		       lc->sync == DEFAULTSYNC ? 2 : 3, buffer,
 		       lc->region_size);
 		DMEMIT_SYNC;
diff -Nru a/drivers/md/dm-log.h b/drivers/md/dm-log.h
--- a/drivers/md/dm-log.h	2005-03-01 23:38:54 -08:00
+++ b/drivers/md/dm-log.h	2005-03-01 23:38:54 -08:00
@@ -39,7 +39,7 @@
 	 * Retrieves the smallest size of region that the log can
 	 * deal with.
 	 */
-	sector_t (*get_region_size)(struct dirty_log *log);
+	uint32_t (*get_region_size)(struct dirty_log *log);
 
         /*
 	 * A predicate to say whether a region is clean or not.
diff -Nru a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c
--- a/drivers/md/dm-raid1.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/md/dm-raid1.c	2005-03-01 23:39:17 -08:00
@@ -67,7 +67,7 @@
 struct mirror_set;
 struct region_hash {
 	struct mirror_set *ms;
-	sector_t region_size;
+	uint32_t region_size;
 	unsigned region_shift;
 
 	/* holds persistent region state */
@@ -135,7 +135,7 @@
 #define MIN_REGIONS 64
 #define MAX_RECOVERY 1
 static int rh_init(struct region_hash *rh, struct mirror_set *ms,
-		   struct dirty_log *log, sector_t region_size,
+		   struct dirty_log *log, uint32_t region_size,
 		   region_t nr_regions)
 {
 	unsigned int nr_buckets, max_buckets;
@@ -253,9 +253,9 @@
 	else {
 		__rh_insert(rh, nreg);
 		if (nreg->state == RH_CLEAN) {
-			spin_lock_irq(&rh->region_lock);
+			spin_lock(&rh->region_lock);
 			list_add(&nreg->list, &rh->clean_regions);
-			spin_unlock_irq(&rh->region_lock);
+			spin_unlock(&rh->region_lock);
 		}
 		reg = nreg;
 	}
@@ -871,7 +871,7 @@
  * Target functions
  *---------------------------------------------------------------*/
 static struct mirror_set *alloc_context(unsigned int nr_mirrors,
-					sector_t region_size,
+					uint32_t region_size,
 					struct dm_target *ti,
 					struct dirty_log *dl)
 {
@@ -894,7 +894,7 @@
 
 	ms->ti = ti;
 	ms->nr_mirrors = nr_mirrors;
-	ms->nr_regions = dm_div_up(ti->len, region_size);
+	ms->nr_regions = dm_sector_div_up(ti->len, region_size);
 	ms->in_sync = 0;
 
 	if (rh_init(&ms->rh, ms, dl, region_size, ms->nr_regions)) {
@@ -916,7 +916,7 @@
 	kfree(ms);
 }
 
-static inline int _check_region_size(struct dm_target *ti, sector_t size)
+static inline int _check_region_size(struct dm_target *ti, uint32_t size)
 {
 	return !(size % (PAGE_SIZE >> 9) || (size & (size - 1)) ||
 		 size > ti->len);
@@ -1158,10 +1158,11 @@
 	return 0;
 }
 
-static void mirror_suspend(struct dm_target *ti)
+static void mirror_postsuspend(struct dm_target *ti)
 {
 	struct mirror_set *ms = (struct mirror_set *) ti->private;
 	struct dirty_log *log = ms->rh.log;
+
 	rh_stop_recovery(&ms->rh);
 	if (log->type->suspend && log->type->suspend(log))
 		/* FIXME: need better error handling */
@@ -1220,7 +1221,7 @@
 	.dtr	 = mirror_dtr,
 	.map	 = mirror_map,
 	.end_io	 = mirror_end_io,
-	.suspend = mirror_suspend,
+	.postsuspend = mirror_postsuspend,
 	.resume	 = mirror_resume,
 	.status	 = mirror_status,
 };
diff -Nru a/drivers/md/dm-stripe.c b/drivers/md/dm-stripe.c
--- a/drivers/md/dm-stripe.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/md/dm-stripe.c	2005-03-01 23:38:57 -08:00
@@ -21,7 +21,7 @@
 	uint32_t stripes;
 
 	/* The size of this target / num. stripes */
-	uint32_t stripe_width;
+	sector_t stripe_width;
 
 	/* stripe chunk size */
 	uint32_t chunk_shift;
@@ -173,9 +173,8 @@
 	struct stripe_c *sc = (struct stripe_c *) ti->private;
 
 	sector_t offset = bio->bi_sector - ti->begin;
-	uint32_t chunk = (uint32_t) (offset >> sc->chunk_shift);
-	uint32_t stripe = chunk % sc->stripes;	/* 32bit modulus */
-	chunk = chunk / sc->stripes;
+	sector_t chunk = offset >> sc->chunk_shift;
+	uint32_t stripe = sector_div(chunk, sc->stripes);
 
 	bio->bi_bdev = sc->stripe[stripe].dev->bdev;
 	bio->bi_sector = sc->stripe[stripe].physical_start +
@@ -210,7 +209,7 @@
 
 static struct target_type stripe_target = {
 	.name   = "striped",
-	.version= {1, 0, 1},
+	.version= {1, 0, 2},
 	.module = THIS_MODULE,
 	.ctr    = stripe_ctr,
 	.dtr    = stripe_dtr,
diff -Nru a/drivers/md/dm-table.c b/drivers/md/dm-table.c
--- a/drivers/md/dm-table.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/md/dm-table.c	2005-03-01 23:39:17 -08:00
@@ -58,7 +58,7 @@
 /*
  * Similar to ceiling(log_size(n))
  */
-static unsigned int int_log(unsigned long n, unsigned long base)
+static unsigned int int_log(unsigned int n, unsigned int base)
 {
 	int result = 0;
 
@@ -849,16 +849,30 @@
 	return t->mode;
 }
 
-void dm_table_suspend_targets(struct dm_table *t)
+static void suspend_targets(struct dm_table *t, unsigned postsuspend)
 {
-	int i;
+	int i = t->num_targets;
+	struct dm_target *ti = t->targets;
 
-	for (i = 0; i < t->num_targets; i++) {
-		struct dm_target *ti = t->targets + i;
+	while (i--) {
+		if (postsuspend) {
+			if (ti->type->postsuspend)
+				ti->type->postsuspend(ti);
+		} else if (ti->type->presuspend)
+			ti->type->presuspend(ti);
 
-		if (ti->type->suspend)
-			ti->type->suspend(ti);
+		ti++;
 	}
+}
+
+void dm_table_presuspend_targets(struct dm_table *t)
+{
+	return suspend_targets(t, 0);
+}
+
+void dm_table_postsuspend_targets(struct dm_table *t)
+{
+	return suspend_targets(t, 1);
 }
 
 void dm_table_resume_targets(struct dm_table *t)
diff -Nru a/drivers/md/dm.c b/drivers/md/dm.c
--- a/drivers/md/dm.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/md/dm.c	2005-03-01 23:39:09 -08:00
@@ -331,8 +331,8 @@
 	 */
 	if (ti->split_io) {
 		sector_t boundary;
-		boundary = dm_round_up(offset + 1, ti->split_io) - offset;
-
+		boundary = ((offset + ti->split_io) & ~(ti->split_io - 1))
+			   - offset;
 		if (len > boundary)
 			len = boundary;
 	}
@@ -919,8 +919,10 @@
 	struct dm_table *map = dm_get_table(md);
 
 	if (atomic_dec_and_test(&md->holders)) {
-		if (!test_bit(DMF_SUSPENDED, &md->flags) && map)
-			dm_table_suspend_targets(map);
+		if (!test_bit(DMF_SUSPENDED, &md->flags) && map) {
+			dm_table_presuspend_targets(map);
+			dm_table_postsuspend_targets(map);
+		}
 		__unbind(md);
 		free_dev(md);
 	}
@@ -1032,7 +1034,11 @@
 		return -EINVAL;
 	}
 
+	map = dm_get_table(md);
+	if (map)
+		dm_table_presuspend_targets(map);
 	__lock_fs(md);
+
 	up_read(&md->lock);
 
 	/*
@@ -1055,7 +1061,6 @@
 	up_write(&md->lock);
 
 	/* unplug */
-	map = dm_get_table(md);
 	if (map) {
 		dm_table_unplug_all(map);
 		dm_table_put(map);
@@ -1090,7 +1095,7 @@
 
 	map = dm_get_table(md);
 	if (map)
-		dm_table_suspend_targets(map);
+		dm_table_postsuspend_targets(map);
 	dm_table_put(map);
 	up_write(&md->lock);
 
diff -Nru a/drivers/md/dm.h b/drivers/md/dm.h
--- a/drivers/md/dm.h	2005-03-01 23:38:56 -08:00
+++ b/drivers/md/dm.h	2005-03-01 23:38:56 -08:00
@@ -115,7 +115,8 @@
 unsigned int dm_table_get_num_targets(struct dm_table *t);
 struct list_head *dm_table_get_devices(struct dm_table *t);
 int dm_table_get_mode(struct dm_table *t);
-void dm_table_suspend_targets(struct dm_table *t);
+void dm_table_presuspend_targets(struct dm_table *t);
+void dm_table_postsuspend_targets(struct dm_table *t);
 void dm_table_resume_targets(struct dm_table *t);
 int dm_table_any_congested(struct dm_table *t, int bdi_bits);
 void dm_table_unplug_all(struct dm_table *t);
@@ -142,21 +143,22 @@
 }
 
 /*
- * ceiling(n / size) * size
+ * Ceiling(n / sz)
  */
-static inline unsigned long dm_round_up(unsigned long n, unsigned long size)
-{
-	unsigned long r = n % size;
-	return n + (r ? (size - r) : 0);
-}
+#define dm_div_up(n, sz) (((n) + (sz) - 1) / (sz))
+
+#define dm_sector_div_up(n, sz) ( \
+{ \
+	sector_t _r = ((n) + (sz) - 1); \
+	sector_div(_r, (sz)); \
+	_r; \
+} \
+)
 
 /*
- * Ceiling(n / size)
+ * ceiling(n / size) * size
  */
-static inline unsigned long dm_div_up(unsigned long n, unsigned long size)
-{
-	return dm_round_up(n, size) / size;
-}
+#define dm_round_up(n, sz) (dm_div_up((n), (sz)) * (sz))
 
 static inline sector_t to_sector(unsigned long n)
 {
diff -Nru a/drivers/md/kcopyd.c b/drivers/md/kcopyd.c
--- a/drivers/md/kcopyd.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/md/kcopyd.c	2005-03-01 23:38:52 -08:00
@@ -211,7 +211,7 @@
  *
  * All three of these are protected by job_lock.
  */
-static spinlock_t _job_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(_job_lock);
 
 static LIST_HEAD(_complete_jobs);
 static LIST_HEAD(_io_jobs);
@@ -649,7 +649,7 @@
 		return -ENOMEM;
 	}
 
-	kc->lock = SPIN_LOCK_UNLOCKED;
+	spin_lock_init(&kc->lock);
 	kc->pages = NULL;
 	kc->nr_pages = kc->nr_free_pages = 0;
 	r = client_alloc_pages(kc, nr_pages);
diff -Nru a/drivers/md/linear.c b/drivers/md/linear.c
--- a/drivers/md/linear.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/md/linear.c	2005-03-01 23:38:56 -08:00
@@ -31,7 +31,7 @@
  */
 static inline dev_info_t *which_dev(mddev_t *mddev, sector_t sector)
 {
-	struct linear_hash *hash;
+	dev_info_t *hash;
 	linear_conf_t *conf = mddev_to_conf(mddev);
 	sector_t block = sector >> 1;
 
@@ -39,12 +39,11 @@
 	 * sector_div(a,b) returns the remainer and sets a to a/b
 	 */
 	(void)sector_div(block, conf->smallest->size);
-	hash = conf->hash_table + block;
+	hash = conf->hash_table[block];
 
-	if ((sector>>1) >= (hash->dev0->size + hash->dev0->offset))
-		return hash->dev1;
-	else
-		return hash->dev0;
+	while ((sector>>1) >= (hash->size + hash->offset))
+		hash++;
+	return hash;
 }
 
 /**
@@ -114,7 +113,7 @@
 static int linear_run (mddev_t *mddev)
 {
 	linear_conf_t *conf;
-	struct linear_hash *table;
+	dev_info_t **table;
 	mdk_rdev_t *rdev;
 	int i, nb_zone, cnt;
 	sector_t start;
@@ -184,7 +183,7 @@
 		nb_zone = conf->nr_zones = sz + (round ? 1 : 0);
 	}
 			
-	conf->hash_table = kmalloc (sizeof (struct linear_hash) * nb_zone,
+	conf->hash_table = kmalloc (sizeof (dev_info_t*) * nb_zone,
 					GFP_KERNEL);
 	if (!conf->hash_table)
 		goto out;
@@ -198,9 +197,6 @@
 	for (i = 0; i < cnt; i++) {
 		dev_info_t *disk = conf->disks + i;
 
-		if (start > curr_offset)
-			table[-1].dev1 = disk;
-
 		disk->offset = curr_offset;
 		curr_offset += disk->size;
 
@@ -208,10 +204,8 @@
 		 * 'start' is the start of table
 		 */
 		while (start < curr_offset) {
-			table->dev0 = disk;
-			table->dev1 = NULL;
+			*table++ = disk;
 			start += conf->smallest->size;
-			table++;
 		}
 	}
 	if (table-conf->hash_table != nb_zone)
@@ -255,13 +249,6 @@
 
 	tmp_dev = which_dev(mddev, bio->bi_sector);
 	block = bio->bi_sector >> 1;
-  
-	if (unlikely(!tmp_dev)) {
-		printk("linear_make_request: hash->dev1==NULL for block %llu\n",
-			(unsigned long long)block);
-		bio_io_error(bio, bio->bi_size);
-		return 0;
-	}
     
 	if (unlikely(block >= (tmp_dev->size + tmp_dev->offset)
 		     || block < tmp_dev->offset)) {
@@ -306,17 +293,20 @@
 #ifdef MD_DEBUG
 	int j;
 	linear_conf_t *conf = mddev_to_conf(mddev);
+	sector_t s = 0;
   
 	seq_printf(seq, "      ");
 	for (j = 0; j < conf->nr_zones; j++)
 	{
 		char b[BDEVNAME_SIZE];
+		s += conf->smallest_size;
 		seq_printf(seq, "[%s",
-			   bdevname(conf->hash_table[j].dev0->rdev->bdev,b));
+			   bdevname(conf->hash_table[j][0].rdev->bdev,b));
 
-		if (conf->hash_table[j].dev1)
+		while (s > conf->hash_table[j][0].offset +
+		           conf->hash_table[j][0].size)
 			seq_printf(seq, "/%s] ",
-				   bdevname(conf->hash_table[j].dev1->rdev->bdev,b));
+				   bdevname(conf->hash_table[j][1].rdev->bdev,b));
 		else
 			seq_printf(seq, "] ");
 	}
diff -Nru a/drivers/md/md.c b/drivers/md/md.c
--- a/drivers/md/md.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/md/md.c	2005-03-01 23:38:54 -08:00
@@ -61,7 +61,7 @@
 #endif
 
 static mdk_personality_t *pers[MAX_PERSONALITY];
-static spinlock_t pers_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(pers_lock);
 
 /*
  * Current RAID-1,4,5 parallel reconstruction 'guaranteed speed limit'
@@ -129,7 +129,7 @@
  * all_mddevs_lock protects this list.
  */
 static LIST_HEAD(all_mddevs);
-static spinlock_t all_mddevs_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(all_mddevs_lock);
 
 
 /*
@@ -332,29 +332,24 @@
 static int sync_page_io(struct block_device *bdev, sector_t sector, int size,
 		   struct page *page, int rw)
 {
-	struct bio bio;
-	struct bio_vec vec;
+	struct bio *bio = bio_alloc(GFP_KERNEL, 1);
 	struct completion event;
+	int ret;
 
 	rw |= (1 << BIO_RW_SYNC);
 
-	bio_init(&bio);
-	bio.bi_io_vec = &vec;
-	vec.bv_page = page;
-	vec.bv_len = size;
-	vec.bv_offset = 0;
-	bio.bi_vcnt = 1;
-	bio.bi_idx = 0;
-	bio.bi_size = size;
-	bio.bi_bdev = bdev;
-	bio.bi_sector = sector;
+	bio->bi_bdev = bdev;
+	bio->bi_sector = sector;
+	bio_add_page(bio, page, size, 0);
 	init_completion(&event);
-	bio.bi_private = &event;
-	bio.bi_end_io = bi_complete;
-	submit_bio(rw, &bio);
+	bio->bi_private = &event;
+	bio->bi_end_io = bi_complete;
+	submit_bio(rw, bio);
 	wait_for_completion(&event);
 
-	return test_bit(BIO_UPTODATE, &bio.bi_flags);
+	ret = test_bit(BIO_UPTODATE, &bio->bi_flags);
+	bio_put(bio);
+	return ret;
 }
 
 static int read_disk_sb(mdk_rdev_t * rdev)
@@ -940,8 +935,8 @@
 
 	max_dev = 0;
 	ITERATE_RDEV(mddev,rdev2,tmp)
-		if (rdev2->desc_nr > max_dev)
-			max_dev = rdev2->desc_nr;
+		if (rdev2->desc_nr+1 > max_dev)
+			max_dev = rdev2->desc_nr+1;
 	
 	sb->max_dev = cpu_to_le32(max_dev);
 	for (i=0; i<max_dev;i++)
@@ -958,6 +953,7 @@
 	}
 
 	sb->recovery_offset = cpu_to_le64(0); /* not supported yet */
+	sb->sb_csum = calc_sb_1_csum(sb);
 }
 
 
@@ -1477,10 +1473,13 @@
 	}
 	disk->major = MAJOR(dev);
 	disk->first_minor = unit << shift;
-	if (partitioned)
+	if (partitioned) {
 		sprintf(disk->disk_name, "md_d%d", unit);
-	else
+		sprintf(disk->devfs_name, "md/d%d", unit);
+	} else {
 		sprintf(disk->disk_name, "md%d", unit);
+		sprintf(disk->devfs_name, "md/%d", unit);
+	}
 	disk->fops = &md_fops;
 	disk->private_data = mddev;
 	disk->queue = mddev->queue;
@@ -2445,6 +2444,9 @@
 {
 	mdk_rdev_t *rdev;
 
+	if (mddev->pers == NULL)
+		return -ENODEV;
+
 	rdev = find_rdev(mddev, dev);
 	if (!rdev)
 		return -ENODEV;
@@ -3367,10 +3369,12 @@
 	init_waitqueue_head(&mddev->recovery_wait);
 	last_check = 0;
 
-	if (j)
+	if (j>2) {
 		printk(KERN_INFO 
 			"md: resuming recovery of %s from checkpoint.\n",
 			mdname(mddev));
+		mddev->curr_resync = j;
+	}
 
 	while (j < max_sectors) {
 		int sectors;
@@ -3452,7 +3456,7 @@
 
 	if (!test_bit(MD_RECOVERY_ERR, &mddev->recovery) &&
 	    mddev->curr_resync > 2 &&
-	    mddev->curr_resync > mddev->recovery_cp) {
+	    mddev->curr_resync >= mddev->recovery_cp) {
 		if (test_bit(MD_RECOVERY_INTR, &mddev->recovery)) {
 			printk(KERN_INFO 
 				"md: checkpointing recovery of %s.\n",
@@ -3660,7 +3664,7 @@
 	for (minor=0; minor < MAX_MD_DEVS; ++minor)
 		devfs_mk_bdev(MKDEV(mdp_major, minor<<MdpMinorShift),
 			      S_IFBLK|S_IRUSR|S_IWUSR,
-			      "md/d%d", minor);
+			      "md/mdp%d", minor);
 
 
 	register_reboot_notifier(&md_notifier);
diff -Nru a/drivers/md/multipath.c b/drivers/md/multipath.c
--- a/drivers/md/multipath.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/md/multipath.c	2005-03-01 23:38:56 -08:00
@@ -491,7 +491,7 @@
 	conf->raid_disks = mddev->raid_disks;
 	mddev->sb_dirty = 1;
 	conf->mddev = mddev;
-	conf->device_lock = SPIN_LOCK_UNLOCKED;
+	spin_lock_init(&conf->device_lock);
 	INIT_LIST_HEAD(&conf->retry_list);
 
 	if (!conf->working_disks) {
diff -Nru a/drivers/md/raid1.c b/drivers/md/raid1.c
--- a/drivers/md/raid1.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/md/raid1.c	2005-03-01 23:38:58 -08:00
@@ -1210,12 +1210,12 @@
 	}
 	conf->raid_disks = mddev->raid_disks;
 	conf->mddev = mddev;
-	conf->device_lock = SPIN_LOCK_UNLOCKED;
+	spin_lock_init(&conf->device_lock);
 	INIT_LIST_HEAD(&conf->retry_list);
 	if (conf->working_disks == 1)
 		mddev->recovery_cp = MaxSector;
 
-	conf->resync_lock = SPIN_LOCK_UNLOCKED;
+	spin_lock_init(&conf->resync_lock);
 	init_waitqueue_head(&conf->wait_idle);
 	init_waitqueue_head(&conf->wait_resume);
 
diff -Nru a/drivers/md/raid10.c b/drivers/md/raid10.c
--- a/drivers/md/raid10.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/md/raid10.c	2005-03-01 23:39:16 -08:00
@@ -1668,10 +1668,10 @@
 	}
 	conf->raid_disks = mddev->raid_disks;
 	conf->mddev = mddev;
-	conf->device_lock = SPIN_LOCK_UNLOCKED;
+	spin_lock_init(&conf->device_lock);
 	INIT_LIST_HEAD(&conf->retry_list);
 
-	conf->resync_lock = SPIN_LOCK_UNLOCKED;
+	spin_lock_init(&conf->resync_lock);
 	init_waitqueue_head(&conf->wait_idle);
 	init_waitqueue_head(&conf->wait_resume);
 
diff -Nru a/drivers/md/raid5.c b/drivers/md/raid5.c
--- a/drivers/md/raid5.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/md/raid5.c	2005-03-01 23:38:53 -08:00
@@ -49,14 +49,14 @@
  * This macro is used to determine the 'next' bio in the list, given the sector
  * of the current stripe+device
  */
-#define r5_next_bio(bio, sect) ( ( bio->bi_sector + (bio->bi_size>>9) < sect + STRIPE_SECTORS) ? bio->bi_next : NULL)
+#define r5_next_bio(bio, sect) ( ( (bio)->bi_sector + ((bio)->bi_size>>9) < sect + STRIPE_SECTORS) ? (bio)->bi_next : NULL)
 /*
  * The following can be used to debug the driver
  */
 #define RAID5_DEBUG	0
 #define RAID5_PARANOIA	1
 #if RAID5_PARANOIA && defined(CONFIG_SMP)
-# define CHECK_DEVLOCK() if (!spin_is_locked(&conf->device_lock)) BUG()
+# define CHECK_DEVLOCK() assert_spin_locked(&conf->device_lock)
 #else
 # define CHECK_DEVLOCK()
 #endif
@@ -232,6 +232,7 @@
 }
 
 static void unplug_slaves(mddev_t *mddev);
+static void raid5_unplug_device(request_queue_t *q);
 
 static struct stripe_head *get_active_stripe(raid5_conf_t *conf, sector_t sector,
 					     int pd_idx, int noblock) 
@@ -302,7 +303,7 @@
 			return 1;
 		memset(sh, 0, sizeof(*sh) + (devs-1)*sizeof(struct r5dev));
 		sh->raid_conf = conf;
-		sh->lock = SPIN_LOCK_UNLOCKED;
+		spin_lock_init(&sh->lock);
 
 		if (grow_buffers(sh, conf->raid_disks)) {
 			shrink_buffers(sh, conf->raid_disks);
@@ -457,6 +458,7 @@
 	bio_init(&dev->req);
 	dev->req.bi_io_vec = &dev->vec;
 	dev->req.bi_vcnt++;
+	dev->req.bi_max_vecs++;
 	dev->vec.bv_page = dev->page;
 	dev->vec.bv_len = STRIPE_SIZE;
 	dev->vec.bv_offset = 0;
@@ -612,11 +614,10 @@
 
 
 /*
- * Copy data between a page in the stripe cache, and one or more bion
- * The page could align with the middle of the bio, or there could be 
- * several bion, each with several bio_vecs, which cover part of the page
- * Multiple bion are linked together on bi_next.  There may be extras
- * at the end of this list.  We ignore them.
+ * Copy data between a page in the stripe cache, and a bio.
+ * There are no alignment or size guarantees between the page or the
+ * bio except that there is some overlap.
+ * All iovecs in the bio must be considered.
  */
 static void copy_data(int frombio, struct bio *bio,
 		     struct page *page,
@@ -625,41 +626,38 @@
 	char *pa = page_address(page);
 	struct bio_vec *bvl;
 	int i;
+	int page_offset;
 
-	for (;bio && bio->bi_sector < sector+STRIPE_SECTORS;
-	      bio = r5_next_bio(bio, sector) ) {
-		int page_offset;
-		if (bio->bi_sector >= sector)
-			page_offset = (signed)(bio->bi_sector - sector) * 512;
-		else 
-			page_offset = (signed)(sector - bio->bi_sector) * -512;
-		bio_for_each_segment(bvl, bio, i) {
-			int len = bio_iovec_idx(bio,i)->bv_len;
-			int clen;
-			int b_offset = 0;			
-
-			if (page_offset < 0) {
-				b_offset = -page_offset;
-				page_offset += b_offset;
-				len -= b_offset;
-			}
-
-			if (len > 0 && page_offset + len > STRIPE_SIZE)
-				clen = STRIPE_SIZE - page_offset;	
-			else clen = len;
+	if (bio->bi_sector >= sector)
+		page_offset = (signed)(bio->bi_sector - sector) * 512;
+	else
+		page_offset = (signed)(sector - bio->bi_sector) * -512;
+	bio_for_each_segment(bvl, bio, i) {
+		int len = bio_iovec_idx(bio,i)->bv_len;
+		int clen;
+		int b_offset = 0;
+
+		if (page_offset < 0) {
+			b_offset = -page_offset;
+			page_offset += b_offset;
+			len -= b_offset;
+		}
+
+		if (len > 0 && page_offset + len > STRIPE_SIZE)
+			clen = STRIPE_SIZE - page_offset;
+		else clen = len;
 			
-			if (clen > 0) {
-				char *ba = __bio_kmap_atomic(bio, i, KM_USER0);
-				if (frombio)
-					memcpy(pa+page_offset, ba+b_offset, clen);
-				else
-					memcpy(ba+b_offset, pa+page_offset, clen);
-				__bio_kunmap_atomic(ba, KM_USER0);
-			}	
-			if (clen < len) /* hit end of page */
-				break;
-			page_offset +=  len;
+		if (clen > 0) {
+			char *ba = __bio_kmap_atomic(bio, i, KM_USER0);
+			if (frombio)
+				memcpy(pa+page_offset, ba+b_offset, clen);
+			else
+				memcpy(ba+b_offset, pa+page_offset, clen);
+			__bio_kunmap_atomic(ba, KM_USER0);
 		}
+		if (clen < len) /* hit end of page */
+			break;
+		page_offset +=  len;
 	}
 }
 
@@ -725,6 +723,10 @@
 				ptr[count++] = page_address(sh->dev[i].page);
 				chosen = sh->dev[i].towrite;
 				sh->dev[i].towrite = NULL;
+
+				if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags))
+					wake_up(&conf->wait_for_overlap);
+
 				if (sh->dev[i].written) BUG();
 				sh->dev[i].written = chosen;
 				check_xor();
@@ -737,6 +739,10 @@
 			if (i!=pd_idx && sh->dev[i].towrite) {
 				chosen = sh->dev[i].towrite;
 				sh->dev[i].towrite = NULL;
+
+				if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags))
+					wake_up(&conf->wait_for_overlap);
+
 				if (sh->dev[i].written) BUG();
 				sh->dev[i].written = chosen;
 			}
@@ -793,7 +799,7 @@
  * toread/towrite point to the first in a chain. 
  * The bi_next chain must be in order.
  */
-static void add_stripe_bio (struct stripe_head *sh, struct bio *bi, int dd_idx, int forwrite)
+static int add_stripe_bio(struct stripe_head *sh, struct bio *bi, int dd_idx, int forwrite)
 {
 	struct bio **bip;
 	raid5_conf_t *conf = sh->raid_conf;
@@ -810,10 +816,13 @@
 	else
 		bip = &sh->dev[dd_idx].toread;
 	while (*bip && (*bip)->bi_sector < bi->bi_sector) {
-		BUG_ON((*bip)->bi_sector + ((*bip)->bi_size >> 9) > bi->bi_sector);
+		if ((*bip)->bi_sector + ((*bip)->bi_size >> 9) > bi->bi_sector)
+			goto overlap;
 		bip = & (*bip)->bi_next;
 	}
-/* FIXME do I need to worry about overlapping bion */
+	if (*bip && (*bip)->bi_sector < bi->bi_sector + ((bi->bi_size)>>9))
+		goto overlap;
+
 	if (*bip && bi->bi_next && (*bip) != bi->bi_next)
 		BUG();
 	if (*bip)
@@ -828,7 +837,7 @@
 		(unsigned long long)sh->sector, dd_idx);
 
 	if (forwrite) {
-		/* check if page is coverred */
+		/* check if page is covered */
 		sector_t sector = sh->dev[dd_idx].sector;
 		for (bi=sh->dev[dd_idx].towrite;
 		     sector < sh->dev[dd_idx].sector + STRIPE_SECTORS &&
@@ -840,6 +849,13 @@
 		if (sector >= sh->dev[dd_idx].sector + STRIPE_SECTORS)
 			set_bit(R5_OVERWRITE, &sh->dev[dd_idx].flags);
 	}
+	return 1;
+
+ overlap:
+	set_bit(R5_Overlap, &sh->dev[dd_idx].flags);
+	spin_unlock_irq(&conf->device_lock);
+	spin_unlock(&sh->lock);
+	return 0;
 }
 
 
@@ -900,6 +916,8 @@
 			spin_lock_irq(&conf->device_lock);
 			rbi = dev->toread;
 			dev->toread = NULL;
+			if (test_and_clear_bit(R5_Overlap, &dev->flags))
+				wake_up(&conf->wait_for_overlap);
 			spin_unlock_irq(&conf->device_lock);
 			while (rbi && rbi->bi_sector < dev->sector + STRIPE_SECTORS) {
 				copy_data(0, rbi, dev->page, dev->sector);
@@ -947,6 +965,9 @@
 			sh->dev[i].towrite = NULL;
 			if (bi) to_write--;
 
+			if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags))
+				wake_up(&conf->wait_for_overlap);
+
 			while (bi && bi->bi_sector < sh->dev[i].sector + STRIPE_SECTORS){
 				struct bio *nextbi = r5_next_bio(bi, sh->dev[i].sector);
 				clear_bit(BIO_UPTODATE, &bi->bi_flags);
@@ -975,6 +996,8 @@
 			if (!test_bit(R5_Insync, &sh->dev[i].flags)) {
 				bi = sh->dev[i].toread;
 				sh->dev[i].toread = NULL;
+				if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags))
+					wake_up(&conf->wait_for_overlap);
 				if (bi) to_read--;
 				while (bi && bi->bi_sector < sh->dev[i].sector + STRIPE_SECTORS){
 					struct bio *nextbi = r5_next_bio(bi, sh->dev[i].sector);
@@ -1266,6 +1289,7 @@
 			bi->bi_sector = sh->sector + rdev->data_offset;
 			bi->bi_flags = 1 << BIO_UPTODATE;
 			bi->bi_vcnt = 1;	
+			bi->bi_max_vecs = 1;
 			bi->bi_idx = 0;
 			bi->bi_io_vec = &sh->dev[i].vec;
 			bi->bi_io_vec[0].bv_len = STRIPE_SIZE;
@@ -1402,6 +1426,7 @@
 	if ( bio_data_dir(bi) == WRITE )
 		md_write_start(mddev);
 	for (;logical_sector < last_sector; logical_sector += STRIPE_SECTORS) {
+		DEFINE_WAIT(w);
 		
 		new_sector = raid5_compute_sector(logical_sector,
 						  raid_disks, data_disks, &dd_idx, &pd_idx, conf);
@@ -1410,17 +1435,28 @@
 			(unsigned long long)new_sector, 
 			(unsigned long long)logical_sector);
 
+	retry:
+		prepare_to_wait(&conf->wait_for_overlap, &w, TASK_UNINTERRUPTIBLE);
 		sh = get_active_stripe(conf, new_sector, pd_idx, (bi->bi_rw&RWA_MASK));
 		if (sh) {
-
-			add_stripe_bio(sh, bi, dd_idx, (bi->bi_rw&RW_MASK));
-
+			if (!add_stripe_bio(sh, bi, dd_idx, (bi->bi_rw&RW_MASK))) {
+				/* Add failed due to overlap.  Flush everything
+				 * and wait a while
+				 */
+				raid5_unplug_device(mddev->queue);
+				release_stripe(sh);
+				schedule();
+				goto retry;
+			}
+			finish_wait(&conf->wait_for_overlap, &w);
 			raid5_plug_device(conf);
 			handle_stripe(sh);
 			release_stripe(sh);
+
 		} else {
 			/* cannot get stripe for read-ahead, just give-up */
 			clear_bit(BIO_UPTODATE, &bi->bi_flags);
+			finish_wait(&conf->wait_for_overlap, &w);
 			break;
 		}
 			
@@ -1566,8 +1602,9 @@
 		goto abort;
 	memset(conf->stripe_hashtbl, 0, HASH_PAGES * PAGE_SIZE);
 
-	conf->device_lock = SPIN_LOCK_UNLOCKED;
+	spin_lock_init(&conf->device_lock);
 	init_waitqueue_head(&conf->wait_for_stripe);
+	init_waitqueue_head(&conf->wait_for_overlap);
 	INIT_LIST_HEAD(&conf->handle_list);
 	INIT_LIST_HEAD(&conf->delayed_list);
 	INIT_LIST_HEAD(&conf->inactive_list);
diff -Nru a/drivers/md/raid6algos.c b/drivers/md/raid6algos.c
--- a/drivers/md/raid6algos.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/md/raid6algos.c	2005-03-01 23:39:18 -08:00
@@ -37,6 +37,10 @@
 extern const struct raid6_calls raid6_sse2x1;
 extern const struct raid6_calls raid6_sse2x2;
 extern const struct raid6_calls raid6_sse2x4;
+extern const struct raid6_calls raid6_altivec1;
+extern const struct raid6_calls raid6_altivec2;
+extern const struct raid6_calls raid6_altivec4;
+extern const struct raid6_calls raid6_altivec8;
 
 const struct raid6_calls * const raid6_algos[] = {
 	&raid6_intx1,
@@ -59,6 +63,12 @@
 	&raid6_sse2x1,
 	&raid6_sse2x2,
 	&raid6_sse2x4,
+#endif
+#ifdef CONFIG_ALTIVEC
+	&raid6_altivec1,
+	&raid6_altivec2,
+	&raid6_altivec4,
+	&raid6_altivec8,
 #endif
 	NULL
 };
diff -Nru a/drivers/md/raid6altivec.uc b/drivers/md/raid6altivec.uc
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/md/raid6altivec.uc	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,122 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright 2002-2004 H. Peter Anvin - 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, Inc., 53 Temple Place Ste 330,
+ *   Bostom MA 02111-1307, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * raid6altivec$#.c
+ *
+ * $#-way unrolled portable integer math RAID-6 instruction set
+ *
+ * This file is postprocessed using unroll.pl
+ *
+ * <benh> hpa: in process,
+ * you can just "steal" the vec unit with enable_kernel_altivec() (but
+ * bracked this with preempt_disable/enable or in a lock)
+ */
+
+#include "raid6.h"
+
+#ifdef CONFIG_ALTIVEC
+
+#include <altivec.h>
+#include <asm/system.h>
+#include <asm/cputable.h>
+
+/*
+ * This is the C data type to use
+ */
+
+typedef vector unsigned char unative_t;
+
+#define NBYTES(x) ((vector unsigned char) {x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x})
+#define NSIZE	sizeof(unative_t)
+
+/*
+ * The SHLBYTE() operation shifts each byte left by 1, *not*
+ * rolling over into the next byte
+ */
+static inline __attribute_const__ unative_t SHLBYTE(unative_t v)
+{
+	return vec_add(v,v);
+}
+
+/*
+ * The MASK() operation returns 0xFF in any byte for which the high
+ * bit is 1, 0x00 for any byte for which the high bit is 0.
+ */
+static inline __attribute_const__ unative_t MASK(unative_t v)
+{
+	unative_t zv = NBYTES(0);
+
+	/* vec_cmpgt returns a vector bool char; thus the need for the cast */
+	return (unative_t)vec_cmpgt(zv, v);
+}
+
+
+/* This is noinline to make damned sure that gcc doesn't move any of the
+   Altivec code around the enable/disable code */
+static void noinline
+raid6_altivec$#_gen_syndrome_real(int disks, size_t bytes, void **ptrs)
+{
+	u8 **dptr = (u8 **)ptrs;
+	u8 *p, *q;
+	int d, z, z0;
+
+	unative_t wd$$, wq$$, wp$$, w1$$, w2$$;
+	unative_t x1d = NBYTES(0x1d);
+
+	z0 = disks - 3;		/* Highest data disk */
+	p = dptr[z0+1];		/* XOR parity */
+	q = dptr[z0+2];		/* RS syndrome */
+
+	for ( d = 0 ; d < bytes ; d += NSIZE*$# ) {
+		wq$$ = wp$$ = *(unative_t *)&dptr[z0][d+$$*NSIZE];
+		for ( z = z0-1 ; z >= 0 ; z-- ) {
+			wd$$ = *(unative_t *)&dptr[z][d+$$*NSIZE];
+			wp$$ = vec_xor(wp$$, wd$$);
+			w2$$ = MASK(wq$$);
+			w1$$ = SHLBYTE(wq$$);
+			w2$$ = vec_and(w2$$, x1d);
+			w1$$ = vec_xor(w1$$, w2$$);
+			wq$$ = vec_xor(w1$$, wd$$);
+		}
+		*(unative_t *)&p[d+NSIZE*$$] = wp$$;
+		*(unative_t *)&q[d+NSIZE*$$] = wq$$;
+	}
+}
+
+static void raid6_altivec$#_gen_syndrome(int disks, size_t bytes, void **ptrs)
+{
+	preempt_disable();
+	enable_kernel_altivec();
+
+	raid6_altivec$#_gen_syndrome_real(disks, bytes, ptrs);
+
+	preempt_enable();
+}
+
+int raid6_have_altivec(void);
+#if $# == 1
+int raid6_have_altivec(void)
+{
+	/* This assumes either all CPUs have Altivec or none does */
+	return cur_cpu_spec->cpu_features & CPU_FTR_ALTIVEC;
+}
+#endif
+
+const struct raid6_calls raid6_altivec$# = {
+	raid6_altivec$#_gen_syndrome,
+	raid6_have_altivec,
+	"altivecx$#",
+	0
+};
+
+#endif /* CONFIG_ALTIVEC */
diff -Nru a/drivers/md/raid6main.c b/drivers/md/raid6main.c
--- a/drivers/md/raid6main.c	2005-03-01 23:38:51 -08:00
+++ b/drivers/md/raid6main.c	2005-03-01 23:38:51 -08:00
@@ -54,7 +54,7 @@
  * This macro is used to determine the 'next' bio in the list, given the sector
  * of the current stripe+device
  */
-#define r5_next_bio(bio, sect) ( ( bio->bi_sector + (bio->bi_size>>9) < sect + STRIPE_SECTORS) ? bio->bi_next : NULL)
+#define r5_next_bio(bio, sect) ( ( (bio)->bi_sector + ((bio)->bi_size>>9) < sect + STRIPE_SECTORS) ? (bio)->bi_next : NULL)
 /*
  * The following can be used to debug the driver
  */
@@ -62,7 +62,7 @@
 #define RAID6_PARANOIA	1	/* Check spinlocks */
 #define RAID6_DUMPSTATE 0	/* Include stripe cache state in /proc/mdstat */
 #if RAID6_PARANOIA && defined(CONFIG_SMP)
-# define CHECK_DEVLOCK() if (!spin_is_locked(&conf->device_lock)) BUG()
+# define CHECK_DEVLOCK() assert_spin_locked(&conf->device_lock)
 #else
 # define CHECK_DEVLOCK()
 #endif
@@ -321,7 +321,7 @@
 			return 1;
 		memset(sh, 0, sizeof(*sh) + (devs-1)*sizeof(struct r5dev));
 		sh->raid_conf = conf;
-		sh->lock = SPIN_LOCK_UNLOCKED;
+		spin_lock_init(&sh->lock);
 
 		if (grow_buffers(sh, conf->raid_disks)) {
 			shrink_buffers(sh, conf->raid_disks);
@@ -478,6 +478,7 @@
 	bio_init(&dev->req);
 	dev->req.bi_io_vec = &dev->vec;
 	dev->req.bi_vcnt++;
+	dev->req.bi_max_vecs++;
 	dev->vec.bv_page = dev->page;
 	dev->vec.bv_len = STRIPE_SIZE;
 	dev->vec.bv_offset = 0;
@@ -670,41 +671,38 @@
 	char *pa = page_address(page);
 	struct bio_vec *bvl;
 	int i;
+	int page_offset;
 
-	for (;bio && bio->bi_sector < sector+STRIPE_SECTORS;
-	      bio = r5_next_bio(bio, sector) ) {
-		int page_offset;
-		if (bio->bi_sector >= sector)
-			page_offset = (signed)(bio->bi_sector - sector) * 512;
-		else
-			page_offset = (signed)(sector - bio->bi_sector) * -512;
-		bio_for_each_segment(bvl, bio, i) {
-			int len = bio_iovec_idx(bio,i)->bv_len;
-			int clen;
-			int b_offset = 0;
-
-			if (page_offset < 0) {
-				b_offset = -page_offset;
-				page_offset += b_offset;
-				len -= b_offset;
-			}
-
-			if (len > 0 && page_offset + len > STRIPE_SIZE)
-				clen = STRIPE_SIZE - page_offset;
-			else clen = len;
-
-			if (clen > 0) {
-				char *ba = __bio_kmap_atomic(bio, i, KM_USER0);
-				if (frombio)
-					memcpy(pa+page_offset, ba+b_offset, clen);
-				else
-					memcpy(ba+b_offset, pa+page_offset, clen);
-				__bio_kunmap_atomic(ba, KM_USER0);
-			}
-			if (clen < len) /* hit end of page */
-				break;
-			page_offset +=  len;
+	if (bio->bi_sector >= sector)
+		page_offset = (signed)(bio->bi_sector - sector) * 512;
+	else
+		page_offset = (signed)(sector - bio->bi_sector) * -512;
+	bio_for_each_segment(bvl, bio, i) {
+		int len = bio_iovec_idx(bio,i)->bv_len;
+		int clen;
+		int b_offset = 0;
+
+		if (page_offset < 0) {
+			b_offset = -page_offset;
+			page_offset += b_offset;
+			len -= b_offset;
+		}
+
+		if (len > 0 && page_offset + len > STRIPE_SIZE)
+			clen = STRIPE_SIZE - page_offset;
+		else clen = len;
+
+		if (clen > 0) {
+			char *ba = __bio_kmap_atomic(bio, i, KM_USER0);
+			if (frombio)
+				memcpy(pa+page_offset, ba+b_offset, clen);
+			else
+				memcpy(ba+b_offset, pa+page_offset, clen);
+			__bio_kunmap_atomic(ba, KM_USER0);
 		}
+		if (clen < len) /* hit end of page */
+			break;
+		page_offset +=  len;
 	}
 }
 
@@ -738,6 +736,10 @@
 			if ( i != pd_idx && i != qd_idx && sh->dev[i].towrite ) {
 				chosen = sh->dev[i].towrite;
 				sh->dev[i].towrite = NULL;
+
+				if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags))
+					wake_up(&conf->wait_for_overlap);
+
 				if (sh->dev[i].written) BUG();
 				sh->dev[i].written = chosen;
 			}
@@ -900,7 +902,7 @@
  * toread/towrite point to the first in a chain.
  * The bi_next chain must be in order.
  */
-static void add_stripe_bio (struct stripe_head *sh, struct bio *bi, int dd_idx, int forwrite)
+static int add_stripe_bio(struct stripe_head *sh, struct bio *bi, int dd_idx, int forwrite)
 {
 	struct bio **bip;
 	raid6_conf_t *conf = sh->raid_conf;
@@ -917,10 +919,13 @@
 	else
 		bip = &sh->dev[dd_idx].toread;
 	while (*bip && (*bip)->bi_sector < bi->bi_sector) {
-		BUG_ON((*bip)->bi_sector + ((*bip)->bi_size >> 9) > bi->bi_sector);
-		bip = & (*bip)->bi_next;
+		if ((*bip)->bi_sector + ((*bip)->bi_size >> 9) > bi->bi_sector)
+			goto overlap;
+		bip = &(*bip)->bi_next;
 	}
-/* FIXME do I need to worry about overlapping bion */
+	if (*bip && (*bip)->bi_sector < bi->bi_sector + ((bi->bi_size)>>9))
+		goto overlap;
+
 	if (*bip && bi->bi_next && (*bip) != bi->bi_next)
 		BUG();
 	if (*bip)
@@ -935,7 +940,7 @@
 		(unsigned long long)sh->sector, dd_idx);
 
 	if (forwrite) {
-		/* check if page is coverred */
+		/* check if page is covered */
 		sector_t sector = sh->dev[dd_idx].sector;
 		for (bi=sh->dev[dd_idx].towrite;
 		     sector < sh->dev[dd_idx].sector + STRIPE_SECTORS &&
@@ -947,6 +952,13 @@
 		if (sector >= sh->dev[dd_idx].sector + STRIPE_SECTORS)
 			set_bit(R5_OVERWRITE, &sh->dev[dd_idx].flags);
 	}
+	return 1;
+
+ overlap:
+	set_bit(R5_Overlap, &sh->dev[dd_idx].flags);
+	spin_unlock_irq(&conf->device_lock);
+	spin_unlock(&sh->lock);
+	return 0;
 }
 
 
@@ -1010,6 +1022,8 @@
 			spin_lock_irq(&conf->device_lock);
 			rbi = dev->toread;
 			dev->toread = NULL;
+			if (test_and_clear_bit(R5_Overlap, &dev->flags))
+				wake_up(&conf->wait_for_overlap);
 			spin_unlock_irq(&conf->device_lock);
 			while (rbi && rbi->bi_sector < dev->sector + STRIPE_SECTORS) {
 				copy_data(0, rbi, dev->page, dev->sector);
@@ -1059,6 +1073,9 @@
 			sh->dev[i].towrite = NULL;
 			if (bi) to_write--;
 
+			if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags))
+				wake_up(&conf->wait_for_overlap);
+
 			while (bi && bi->bi_sector < sh->dev[i].sector + STRIPE_SECTORS){
 				struct bio *nextbi = r5_next_bio(bi, sh->dev[i].sector);
 				clear_bit(BIO_UPTODATE, &bi->bi_flags);
@@ -1087,6 +1104,8 @@
 			if (!test_bit(R5_Insync, &sh->dev[i].flags)) {
 				bi = sh->dev[i].toread;
 				sh->dev[i].toread = NULL;
+				if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags))
+					wake_up(&conf->wait_for_overlap);
 				if (bi) to_read--;
 				while (bi && bi->bi_sector < sh->dev[i].sector + STRIPE_SECTORS){
 					struct bio *nextbi = r5_next_bio(bi, sh->dev[i].sector);
@@ -1429,6 +1448,7 @@
 			bi->bi_sector = sh->sector + rdev->data_offset;
 			bi->bi_flags = 1 << BIO_UPTODATE;
 			bi->bi_vcnt = 1;
+			bi->bi_max_vecs = 1;
 			bi->bi_idx = 0;
 			bi->bi_io_vec = &sh->dev[i].vec;
 			bi->bi_io_vec[0].bv_len = STRIPE_SIZE;
@@ -1566,6 +1586,7 @@
 	if ( bio_data_dir(bi) == WRITE )
 		md_write_start(mddev);
 	for (;logical_sector < last_sector; logical_sector += STRIPE_SECTORS) {
+		DEFINE_WAIT(w);
 
 		new_sector = raid6_compute_sector(logical_sector,
 						  raid_disks, data_disks, &dd_idx, &pd_idx, conf);
@@ -1574,17 +1595,27 @@
 		       (unsigned long long)new_sector,
 		       (unsigned long long)logical_sector);
 
+	retry:
+		prepare_to_wait(&conf->wait_for_overlap, &w, TASK_UNINTERRUPTIBLE);
 		sh = get_active_stripe(conf, new_sector, pd_idx, (bi->bi_rw&RWA_MASK));
 		if (sh) {
-
-			add_stripe_bio(sh, bi, dd_idx, (bi->bi_rw&RW_MASK));
-
+			if (!add_stripe_bio(sh, bi, dd_idx, (bi->bi_rw&RW_MASK))) {
+				/* Add failed due to overlap.  Flush everything
+				 * and wait a while
+				 */
+				raid6_unplug_device(mddev->queue);
+				release_stripe(sh);
+				schedule();
+				goto retry;
+			}
+			finish_wait(&conf->wait_for_overlap, &w);
 			raid6_plug_device(conf);
 			handle_stripe(sh);
 			release_stripe(sh);
 		} else {
 			/* cannot get stripe for read-ahead, just give-up */
 			clear_bit(BIO_UPTODATE, &bi->bi_flags);
+			finish_wait(&conf->wait_for_overlap, &w);
 			break;
 		}
 
@@ -1730,8 +1761,9 @@
 		goto abort;
 	memset(conf->stripe_hashtbl, 0, HASH_PAGES * PAGE_SIZE);
 
-	conf->device_lock = SPIN_LOCK_UNLOCKED;
+	spin_lock_init(&conf->device_lock);
 	init_waitqueue_head(&conf->wait_for_stripe);
+	init_waitqueue_head(&conf->wait_for_overlap);
 	INIT_LIST_HEAD(&conf->handle_list);
 	INIT_LIST_HEAD(&conf->delayed_list);
 	INIT_LIST_HEAD(&conf->inactive_list);
diff -Nru a/drivers/media/Kconfig b/drivers/media/Kconfig
--- a/drivers/media/Kconfig	2005-03-01 23:39:18 -08:00
+++ b/drivers/media/Kconfig	2005-03-01 23:39:18 -08:00
@@ -47,5 +47,8 @@
 config VIDEO_IR
 	tristate
 
+config VIDEO_TVEEPROM
+	tristate
+
 endmenu
 
diff -Nru a/drivers/media/common/ir-common.c b/drivers/media/common/ir-common.c
--- a/drivers/media/common/ir-common.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/media/common/ir-common.c	2005-03-01 23:39:08 -08:00
@@ -1,5 +1,5 @@
 /*
- * $Id: ir-common.c,v 1.5 2004/11/07 13:17:15 kraxel Exp $
+ * $Id: ir-common.c,v 1.6 2004/12/10 12:33:39 kraxel Exp $
  *
  * some common structs and functions to handle infrared remotes via
  * input layer ...
@@ -22,6 +22,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/moduleparam.h>
 
 #include <media/ir-common.h>
 
diff -Nru a/drivers/media/common/saa7146_core.c b/drivers/media/common/saa7146_core.c
--- a/drivers/media/common/saa7146_core.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/media/common/saa7146_core.c	2005-03-01 23:39:08 -08:00
@@ -380,8 +380,8 @@
 	/* disable all irqs */
 	saa7146_write(dev, IER, 0);
 
-	/* shut down all dma transfers */
-	saa7146_write(dev, MC1, 0x00ff0000);
+	/* shut down all dma transfers and rps tasks */
+	saa7146_write(dev, MC1, 0x30ff0000);
 
 	/* clear out any rps-signals pending */
 	saa7146_write(dev, MC2, 0xf8000000);
@@ -426,8 +426,8 @@
 	pci_set_drvdata(pci,dev);
 
         init_MUTEX(&dev->lock);
-	dev->int_slock = SPIN_LOCK_UNLOCKED;
-	dev->slock = SPIN_LOCK_UNLOCKED;
+	spin_lock_init(&dev->int_slock);
+	spin_lock_init(&dev->slock);
 
 	init_MUTEX(&dev->i2c_lock);
 
diff -Nru a/drivers/media/common/saa7146_fops.c b/drivers/media/common/saa7146_fops.c
--- a/drivers/media/common/saa7146_fops.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/media/common/saa7146_fops.c	2005-03-01 23:38:57 -08:00
@@ -73,9 +73,7 @@
 			 struct saa7146_dmaqueue *q,
 			 struct saa7146_buf *buf)
 {
-#ifdef DEBUG_SPINLOCKS
-	BUG_ON(!spin_is_locked(&dev->slock));
-#endif
+	assert_spin_locked(&dev->slock);
 	DEB_EE(("dev:%p, dmaq:%p, buf:%p\n", dev, q, buf));
 
 	BUG_ON(!q);
@@ -96,9 +94,7 @@
 			   struct saa7146_dmaqueue *q,
 			   int state)
 {
-#ifdef DEBUG_SPINLOCKS
-	BUG_ON(!spin_is_locked(&dev->slock));
-#endif
+	assert_spin_locked(&dev->slock);
 	DEB_EE(("dev:%p, dmaq:%p, state:%d\n", dev, q, state));
 	DEB_EE(("q->curr:%p\n",q->curr));
 
@@ -126,9 +122,7 @@
 
 	DEB_INT(("dev:%p, dmaq:%p, vbi:%d\n", dev, q, vbi));
 
-#ifdef DEBUG_SPINLOCKS
-	BUG_ON(!spin_is_locked(&dev->slock));
-#endif
+	assert_spin_locked(&dev->slock);
 	if (!list_empty(&q->queue)) {
 		/* activate next one from queue */
 		buf = list_entry(q->queue.next,struct saa7146_buf,vb.queue);
diff -Nru a/drivers/media/dvb/b2c2/Kconfig b/drivers/media/dvb/b2c2/Kconfig
--- a/drivers/media/dvb/b2c2/Kconfig	2005-03-01 23:38:58 -08:00
+++ b/drivers/media/dvb/b2c2/Kconfig	2005-03-01 23:38:58 -08:00
@@ -4,9 +4,11 @@
 	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.
+	  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.
 
@@ -17,7 +19,7 @@
 	select DVB_MT352
 	help
 	  Support for the Air/Sky/Cable2PC USB DVB device by B2C2. Currently
-	  this does nothing, but providing basic function for the used usb
+	  the does nothing, but providing basic function for the used usb 
 	  protocol.
 
 	  Say Y if you own such a device and want to use it.
diff -Nru a/drivers/media/dvb/b2c2/b2c2-usb-core.c b/drivers/media/dvb/b2c2/b2c2-usb-core.c
--- a/drivers/media/dvb/b2c2/b2c2-usb-core.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/media/dvb/b2c2/b2c2-usb-core.c	2005-03-01 23:39:09 -08:00
@@ -33,7 +33,7 @@
 }
 
 static int debug;
-module_param(debug, int, 0x644);
+module_param(debug, int, 0644);
 MODULE_PARM_DESC(debug, "set debugging level (1=info,ts=2,ctrl=4 (or-able)).");
 
 #define deb_info(args...) dprintk(0x01,args)
@@ -89,12 +89,22 @@
 
 /* request types */
 typedef enum {
+
+/* something is wrong with this part
 	RTYPE_READ_DW         = (1 << 6),
 	RTYPE_WRITE_DW_1      = (3 << 6),
 	RTYPE_READ_V8_MEMORY  = (6 << 6),
 	RTYPE_WRITE_V8_MEMORY = (7 << 6),
 	RTYPE_WRITE_V8_FLASH  = (8 << 6),
 	RTYPE_GENERIC         = (9 << 6),
+*/
+	RTYPE_READ_DW = (3 << 6),
+	RTYPE_WRITE_DW_1 = (1 << 6),
+	
+	RTYPE_READ_V8_MEMORY  = (6 << 6),
+	RTYPE_WRITE_V8_MEMORY = (7 << 6),
+	RTYPE_WRITE_V8_FLASH  = (8 << 6),
+	RTYPE_GENERIC         = (9 << 6),
 } b2c2_usb_request_type_t;
 
 /* request */
@@ -370,7 +380,7 @@
 
 static int b2c2_init_usb(struct usb_b2c2_usb *b2c2)
 {
-	u16 frame_size = b2c2->uintf->cur_altsetting->endpoint[0].desc.wMaxPacketSize;
+	u16 frame_size = le16_to_cpu(b2c2->uintf->cur_altsetting->endpoint[0].desc.wMaxPacketSize);
 	int bufsize = B2C2_USB_NUM_ISO_URB * B2C2_USB_FRAMES_PER_ISO * frame_size,i,j,ret;
 	int buffer_offset = 0;
 
@@ -391,9 +401,9 @@
 		}
 	/* initialising and submitting iso urbs */
 	for (i = 0; i < B2C2_USB_NUM_ISO_URB; i++) {
-		deb_info("initializing and submitting urb no. %d (buf_offset: %d).\n",i,buffer_offset);
 		int frame_offset = 0;
 		struct urb *urb = b2c2->iso_urb[i];
+		deb_info("initializing and submitting urb no. %d (buf_offset: %d).\n",i,buffer_offset);
 
 		urb->dev = b2c2->udev;
 		urb->context = b2c2;
diff -Nru a/drivers/media/dvb/b2c2/skystar2.c b/drivers/media/dvb/b2c2/skystar2.c
--- a/drivers/media/dvb/b2c2/skystar2.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/media/dvb/b2c2/skystar2.c	2005-03-01 23:39:18 -08:00
@@ -53,7 +53,7 @@
 #include "stv0299.h"
 #include "mt352.h"
 #include "mt312.h"
-
+#include "nxt2002.h"
 
 static int debug;
 static int enable_hw_filters = 2;
@@ -1379,10 +1379,7 @@
 		write_reg_dw(adapter, 0x008, adapter->dmaq1.bus_addr & 0xfffffffc);
 		udelay(1000);
 
-		if (subbuffers == 0)
-			dma_enable_disable_irq(adapter, 0, 1, 0);
-		else
-			dma_enable_disable_irq(adapter, 0, 1, 1);
+		dma_enable_disable_irq(adapter, 0, 1, subbuffers ? 1 : 0);
 
 		irq_dma_enable_disable_irq(adapter, 1);
 
@@ -1681,84 +1678,80 @@
 	return IRQ_HANDLED;
 }
 
-static void init_dma_queue(struct adapter *adapter)
+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;
 
-	if (adapter->dmaq1.buffer != 0)
-		return;
-
-	adapter->dmaq1.head = 0;
-	adapter->dmaq1.tail = 0;
-	adapter->dmaq1.buffer = NULL;
-
-	adapter->dmaq1.buffer = pci_alloc_consistent(adapter->pdev, SIZE_OF_BUF_DMA1 + 0x80, &dma_addr);
+	dmaq->head = 0;
+	dmaq->tail = 0;
 
-	if (adapter->dmaq1.buffer != 0) {
-		memset(adapter->dmaq1.buffer, 0, SIZE_OF_BUF_DMA1);
-
-		adapter->dmaq1.bus_addr = dma_addr;
-		adapter->dmaq1.buffer_size = SIZE_OF_BUF_DMA1;
-
-		dma_init_dma(adapter, 0);
+	dmaq->buffer = pci_alloc_consistent(pdev, size + 0x80, &dma_addr);
+	if (!dmaq->buffer)
+		return -ENOMEM;
 
-		adapter->dma_status = adapter->dma_status | 0x10000000;
+	dmaq->bus_addr = dma_addr;
+	dmaq->buffer_size = size;
 
-		ddprintk("%s: allocated dma buffer at 0x%p, length=%d\n", __FUNCTION__, adapter->dmaq1.buffer, SIZE_OF_BUF_DMA1);
+	dma_init_dma(adapter, dmaq_offset);
 
-	} else {
+	ddprintk("%s: allocated dma buffer at 0x%p, length=%d\n",
+		 __FUNCTION__, dmaq->buffer, size);
 
-		adapter->dma_status = adapter->dma_status & ~0x10000000;
+	return 0;
 	}
 
-	if (adapter->dmaq2.buffer != 0)
-		return;
-
-	adapter->dmaq2.head = 0;
-	adapter->dmaq2.tail = 0;
-	adapter->dmaq2.buffer = NULL;
-
-	adapter->dmaq2.buffer = pci_alloc_consistent(adapter->pdev, SIZE_OF_BUF_DMA2 + 0x80, &dma_addr);
-
-	if (adapter->dmaq2.buffer != 0) {
-		memset(adapter->dmaq2.buffer, 0, SIZE_OF_BUF_DMA2);
-
-		adapter->dmaq2.bus_addr = dma_addr;
-		adapter->dmaq2.buffer_size = SIZE_OF_BUF_DMA2;
-
-		dma_init_dma(adapter, 1);
-
-		adapter->dma_status = adapter->dma_status | 0x20000000;
-
-		ddprintk("%s: allocated dma buffer at 0x%p, length=%d\n", __FUNCTION__, adapter->dmaq2.buffer, (int) SIZE_OF_BUF_DMA2);
+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;
 
-	} else {
+	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;
+}
 
-		adapter->dma_status = adapter->dma_status & ~0x20000000;
+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)
 {
-	if (adapter->dmaq1.buffer != 0) {
-		pci_free_consistent(adapter->pdev, SIZE_OF_BUF_DMA1 + 0x80, adapter->dmaq1.buffer, adapter->dmaq1.bus_addr);
+	struct dmaq *dmaq[] = {
+		&adapter->dmaq1,
+		&adapter->dmaq2,
+		NULL
+	}, **p;
 
-		adapter->dmaq1.bus_addr = 0;
-		adapter->dmaq1.head = 0;
-		adapter->dmaq1.tail = 0;
-		adapter->dmaq1.buffer_size = 0;
-		adapter->dmaq1.buffer = NULL;
-	}
-
-	if (adapter->dmaq2.buffer != 0) {
-		pci_free_consistent(adapter->pdev, SIZE_OF_BUF_DMA2 + 0x80, adapter->dmaq2.buffer, adapter->dmaq2.bus_addr);
-
-		adapter->dmaq2.bus_addr = 0;
-		adapter->dmaq2.head = 0;
-		adapter->dmaq2.tail = 0;
-		adapter->dmaq2.buffer_size = 0;
-		adapter->dmaq2.buffer = NULL;
+	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)
@@ -1766,16 +1759,9 @@
 	dprintk("%s:\n", __FUNCTION__);
 
 	close_stream(adapter, 0);
-
-	if (adapter->irq != 0)
 		free_irq(adapter->irq, adapter);
-
 	free_dma_queue(adapter);
-
-	if (adapter->io_mem)
-		iounmap(adapter->io_mem);
-
-	if (adapter != 0)
+	release_adapter(adapter);
 	kfree(adapter);
 }
 
@@ -1784,21 +1770,24 @@
 static int claim_adapter(struct adapter *adapter)
 {
 	struct pci_dev *pdev = adapter->pdev;
-
 	u16 var;
+	int ret;
 
-	if (!request_region(pci_resource_start(pdev, 1), pci_resource_len(pdev, 1), skystar2_pci_driver.name))
-		return -EBUSY;
+	ret = pci_request_region(pdev, 1, skystar2_pci_driver.name);
+	if (ret < 0)
+		goto out;
 
-	if (!request_mem_region(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0), skystar2_pci_driver.name))
-		return -EBUSY;
+	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);
 
-	if (pci_enable_device(pdev))
-		return -EIO;
+	ret = pci_enable_device(pdev);
+	if (ret < 0)
+		goto err_pci_release_0;
 
 	pci_read_config_word(pdev, 4, &var);
 
@@ -1811,13 +1800,23 @@
 
 	if (!adapter->io_mem) {
 		dprintk("%s: can not map io memory\n", __FUNCTION__);
-
-		return 2;
+		ret = -EIO;
+		goto err_pci_disable;
 	}
 
 	dprintk("%s: io memory maped at %p\n", __FUNCTION__, adapter->io_mem);
 
-	return 1;
+	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;
 }
 
 /*
@@ -1873,11 +1872,12 @@
 {
 	struct adapter *adapter;
 	u32 tmp;
+	int ret = -ENOMEM;
 
-	if (!(adapter = kmalloc(sizeof(struct adapter), GFP_KERNEL))) {
+	adapter = kmalloc(sizeof(struct adapter), GFP_KERNEL);
+	if (!adapter) {
 		dprintk("%s: out of memory!\n", __FUNCTION__);
-
-		return -ENOMEM;
+		goto out;
 	}
 
 	memset(adapter, 0, sizeof(struct adapter));
@@ -1887,20 +1887,16 @@
 	adapter->pdev = pdev;
 	adapter->irq = pdev->irq;
 
-	if ((claim_adapter(adapter)) != 1) {
-		free_adapter_object(adapter);
-
-		return -ENODEV;
-	}
+	ret = claim_adapter(adapter);
+	if (ret < 0)
+		goto err_kfree;
 
 	irq_dma_enable_disable_irq(adapter, 0);
 
-	if (request_irq(pdev->irq, isr, 0x4000000, "Skystar2", 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);
-
-		free_adapter_object(adapter);
-
-		return -ENODEV;
+		goto err_release_adapter;
 	}
 
 	read_reg_dw(adapter, 0x208);
@@ -1908,13 +1904,9 @@
 	write_reg_dw(adapter, 0x210, 0xb2ff);
 	write_reg_dw(adapter, 0x208, 0x40);
 
-	init_dma_queue(adapter);
-
-	if ((adapter->dma_status & 0x30000000) == 0) {
-		free_adapter_object(adapter);
-
-		return -ENODEV;
-	}
+	ret = init_dma_queue(adapter);
+	if (ret < 0)
+		goto err_free_irq;
 
 	adapter->b2c2_revision = (read_reg_dw(adapter, 0x204) >> 0x18);
 
@@ -1931,11 +1923,8 @@
 	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__);
-		free_adapter_object(adapter);
-		pci_set_drvdata(pdev, NULL);
-		release_region(pci_resource_start(pdev, 1), pci_resource_len(pdev, 1));
-		release_mem_region(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
-			return -ENODEV;
+		ret = -ENODEV;
+		goto err_free_dma_queue;
 		}
 
 	decide_how_many_hw_filters(adapter);
@@ -1981,14 +1970,24 @@
 
 	adapter->lock = SPIN_LOCK_UNLOCKED;
 
-	return 0;
+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;
-
-	adapter = pci_get_drvdata(pdev);
+	struct adapter *adapter = pci_get_drvdata(pdev);
 
 	irq_dma_enable_disable_irq(adapter, 0);
 
@@ -1998,9 +1997,9 @@
 
 	pci_set_drvdata(pdev, NULL);
 
-	release_region(pci_resource_start(pdev, 1), pci_resource_len(pdev, 1));
-
-	release_mem_region(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
+	pci_disable_device(pdev);
+	pci_release_region(pdev, 1);
+	pci_release_region(pdev, 0);
 }
 
 static int dvb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
@@ -2325,11 +2324,22 @@
 
 
 
+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, 0x10, 0x2d };
+	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 };
@@ -2407,7 +2417,15 @@
 static void frontend_init(struct adapter *skystar2)
 {
 	switch(skystar2->pdev->device) {
-	case 0x2103: // Technisat Skystar2 OR Technisat Airstar2
+	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);
@@ -2462,26 +2480,24 @@
 	struct adapter *adapter;
 	struct dvb_adapter *dvb_adapter;
 	struct dvb_demux *dvbdemux;
+	struct dmx_demux *dmx;
+	int ret = -ENODEV;
 
-	int ret;
-
-	if (pdev == NULL)
-		return -ENODEV;
+	if (!pdev)
+		goto out;
 
-	if (driver_initialize(pdev) != 0)
-		return -ENODEV;
-
-	dvb_register_adapter(&dvb_adapter, skystar2_pci_driver.name, THIS_MODULE);
+	ret = driver_initialize(pdev);
+	if (ret < 0)
+		goto out;
 
-	if (dvb_adapter == NULL) {
+	ret = dvb_register_adapter(&dvb_adapter, skystar2_pci_driver.name,
+				   THIS_MODULE);
+	if (ret < 0) {
 		printk("%s: Error registering DVB adapter\n", __FUNCTION__);
-
-		driver_halt(pdev);
-
-		return -ENODEV;
+		goto err_halt;
 	}
 
-	adapter = (struct adapter *) pci_get_drvdata(pdev);
+	adapter = pci_get_drvdata(pdev);
 
 	dvb_adapter->priv = adapter;
 	adapter->dvb_adapter = dvb_adapter;
@@ -2504,14 +2520,13 @@
 	adapter->i2c_adap.algo_data         = NULL;
 	adapter->i2c_adap.id                = I2C_ALGO_BIT;
 
-	if (i2c_add_adapter(&adapter->i2c_adap) < 0) {
-		dvb_unregister_adapter (adapter->dvb_adapter);
-		return -ENOMEM;
-	}
+	ret = i2c_add_adapter(&adapter->i2c_adap);
+	if (ret < 0)
+		goto err_dvb_unregister;
 
 	dvbdemux = &adapter->demux;
 
-	dvbdemux->priv = (void *) adapter;
+	dvbdemux->priv = adapter;
 	dvbdemux->filternum = N_PID_SLOTS;
 	dvbdemux->feednum = N_PID_SLOTS;
 	dvbdemux->start_feed = dvb_start_feed;
@@ -2519,68 +2534,87 @@
 	dvbdemux->write_to_decoder = NULL;
 	dvbdemux->dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING);
 
-	dvb_dmx_init(&adapter->demux);
+	ret = dvb_dmx_init(&adapter->demux);
+	if (ret < 0)
+		goto err_i2c_del;
 
-	adapter->hw_frontend.source = DMX_FRONTEND_0;
+	dmx = &dvbdemux->dmx;
 
+	adapter->hw_frontend.source = DMX_FRONTEND_0;
 	adapter->dmxdev.filternum = N_PID_SLOTS;
-	adapter->dmxdev.demux = &dvbdemux->dmx;
+	adapter->dmxdev.demux = dmx;
 	adapter->dmxdev.capabilities = 0;
 
-	dvb_dmxdev_init(&adapter->dmxdev, adapter->dvb_adapter);
+	ret = dvb_dmxdev_init(&adapter->dmxdev, adapter->dvb_adapter);
+	if (ret < 0)
+		goto err_dmx_release;
 
-	ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, &adapter->hw_frontend);
+	ret = dmx->add_frontend(dmx, &adapter->hw_frontend);
 	if (ret < 0)
-		return ret;
+		goto err_dmxdev_release;
 
 	adapter->mem_frontend.source = DMX_MEMORY_FE;
 
-	ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, &adapter->mem_frontend);
+	ret = dmx->add_frontend(dmx, &adapter->mem_frontend);
 	if (ret < 0)
-		return ret;
+		goto err_remove_hw_frontend;
 
-	ret = dvbdemux->dmx.connect_frontend(&dvbdemux->dmx, &adapter->hw_frontend);
+	ret = dmx->connect_frontend(dmx, &adapter->hw_frontend);
 	if (ret < 0)
-		return ret;
+		goto err_remove_mem_frontend;
 
 	dvb_net_init(adapter->dvb_adapter, &adapter->dvbnet, &dvbdemux->dmx);
 
 	frontend_init(adapter);
+out:
+	return ret;
 
-	return 0;
+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;
+	struct adapter *adapter = pci_get_drvdata(pdev);
 	struct dvb_demux *dvbdemux;
+	struct dmx_demux *dmx;
 
-	if (pdev == NULL)
+	if (!adapter)
 		return;
 
-	adapter = pci_get_drvdata(pdev);
-
-	if (adapter != NULL) {
 		dvb_net_release(&adapter->dvbnet);
 		dvbdemux = &adapter->demux;
+	dmx = &dvbdemux->dmx;
 
-		dvbdemux->dmx.close(&dvbdemux->dmx);
-		dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &adapter->hw_frontend);
-		dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &adapter->mem_frontend);
+	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(&adapter->demux);
+	dvb_dmx_release(dvbdemux);
+
+	if (adapter->fe != NULL)
+		dvb_unregister_frontend(adapter->fe);
 
-		if (adapter->fe != NULL) dvb_unregister_frontend(adapter->fe);
+	dvb_unregister_adapter(adapter->dvb_adapter);
 
-		if (adapter->dvb_adapter != NULL) {
 			i2c_del_adapter(&adapter->i2c_adap);
 
-			dvb_unregister_adapter(adapter->dvb_adapter);
-		}
 		driver_halt(pdev);
 	}
-}
 
 static struct pci_device_id skystar2_pci_tbl[] = {
 	{0x000013d0, 0x00002103, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000},
diff -Nru a/drivers/media/dvb/bt8xx/Kconfig b/drivers/media/dvb/bt8xx/Kconfig
--- a/drivers/media/dvb/bt8xx/Kconfig	2005-03-01 23:38:56 -08:00
+++ b/drivers/media/dvb/bt8xx/Kconfig	2005-03-01 23:38:56 -08:00
@@ -3,6 +3,8 @@
 	depends on DVB_CORE && PCI && VIDEO_BT848
 	select DVB_MT352
 	select DVB_SP887X
+	select DVB_NXT6000
+	select DVB_CX24110
 	help
 	  Support for PCI cards based on the Bt8xx PCI bridge. Examples are
 	  the Nebula cards, the Pinnacle PCTV cards and Twinhan DST cards.
@@ -10,9 +12,6 @@
           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.
-
-	  If you have a Twinhan card, don't forget to select
-	  "Twinhan DST based DVB-S/-T frontend".
 
 	  Say Y if you own such a device and want to use it.
 
diff -Nru a/drivers/media/dvb/bt8xx/dvb-bt8xx.c b/drivers/media/dvb/bt8xx/dvb-bt8xx.c
--- a/drivers/media/dvb/bt8xx/dvb-bt8xx.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.c	2005-03-01 23:38:53 -08:00
@@ -181,6 +181,70 @@
 	.pll_set = thomson_dtt7579_pll_set,
 };
 
+static int cx24108_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
+{
+   u32 freq = params->frequency;
+   
+   int i, a, n, pump; 
+   u32 band, pll;
+   
+   
+   u32 osci[]={950000,1019000,1075000,1178000,1296000,1432000,
+               1576000,1718000,1856000,2036000,2150000};
+   u32 bandsel[]={0,0x00020000,0x00040000,0x00100800,0x00101000,
+               0x00102000,0x00104000,0x00108000,0x00110000,
+               0x00120000,0x00140000};
+   
+#define XTAL 1011100 /* Hz, really 1.0111 MHz and a /10 prescaler */
+        printk("cx24108 debug: entering SetTunerFreq, freq=%d\n",freq);
+        
+        /* This is really the bit driving the tuner chip cx24108 */
+        
+        if(freq<950000) freq=950000; /* kHz */
+        if(freq>2150000) freq=2150000; /* satellite IF is 950..2150MHz */
+        
+        /* decide which VCO to use for the input frequency */
+        for(i=1;(i<sizeof(osci)/sizeof(osci[0]))&&(osci[i]<freq);i++);
+        printk("cx24108 debug: select vco #%d (f=%d)\n",i,freq);
+        band=bandsel[i];
+        /* the gain values must be set by SetSymbolrate */
+        /* compute the pll divider needed, from Conexant data sheet,
+           resolved for (n*32+a), remember f(vco) is f(receive) *2 or *4,
+           depending on the divider bit. It is set to /4 on the 2 lowest 
+           bands  */
+        n=((i<=2?2:1)*freq*10L)/(XTAL/100);
+        a=n%32; n/=32; if(a==0) n--;
+        pump=(freq<(osci[i-1]+osci[i])/2);
+        pll=0xf8000000|
+            ((pump?1:2)<<(14+11))|
+            ((n&0x1ff)<<(5+11))|
+            ((a&0x1f)<<11);
+        /* everything is shifted left 11 bits to left-align the bits in the
+           32bit word. Output to the tuner goes MSB-aligned, after all */
+        printk("cx24108 debug: pump=%d, n=%d, a=%d\n",pump,n,a);
+        cx24110_pll_write(fe,band);
+        /* set vga and vca to their widest-band settings, as a precaution.
+           SetSymbolrate might not be called to set this up */
+        cx24110_pll_write(fe,0x500c0000);
+        cx24110_pll_write(fe,0x83f1f800);
+        cx24110_pll_write(fe,pll);
+/*        writereg(client,0x56,0x7f);*/
+
+	return 0;
+}
+
+static int pinnsat_pll_init(struct dvb_frontend* fe)
+{
+   return 0;
+}
+
+
+static struct cx24110_config pctvsat_config = {
+
+	.demod_address = 0x55,
+	.pll_init = pinnsat_pll_init,
+	.pll_set = cx24108_pll_set,
+};
 
 
 static int microtune_mt7202dtf_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
@@ -220,7 +284,7 @@
 	return request_firmware(fw, name, &bt->bt->dev->dev);
 }
 
-struct sp887x_config microtune_mt7202dtf_config = {
+static struct sp887x_config microtune_mt7202dtf_config = {
 
 	.demod_address = 0x70,
 	.pll_set = microtune_mt7202dtf_pll_set,
@@ -387,6 +451,13 @@
 			break;
 		}
 		break;
+	
+	case BTTV_PINNACLESAT:
+		card->fe = cx24110_attach(&pctvsat_config, card->i2c_adapter);
+		if (card->fe != NULL) {
+			break;
+		}
+		break;
 	}
 
 	if (card->fe == NULL) {
@@ -510,7 +581,14 @@
 
 	switch(sub->core->type)
 	{
-/*	case BTTV_PINNACLESAT: UNDEFINED HARDWARE */
+	case BTTV_PINNACLESAT:
+		card->gpio_mode = 0x0400c060;
+		/* should be: BT878_A_GAIN=0,BT878_A_PWRDN,BT878_DA_DPM,BT878_DA_SBR,
+		              BT878_DA_IOM=1,BT878_DA_APP to enable serial highspeed mode. */
+		card->op_sync_orin = 0;
+		card->irq_err_ignore = 0;
+		break;
+		
 #ifdef BTTV_DVICO_DVBT_LITE
 	case BTTV_DVICO_DVBT_LITE:
 #endif
diff -Nru a/drivers/media/dvb/bt8xx/dvb-bt8xx.h b/drivers/media/dvb/bt8xx/dvb-bt8xx.h
--- a/drivers/media/dvb/bt8xx/dvb-bt8xx.h	2005-03-01 23:39:17 -08:00
+++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.h	2005-03-01 23:39:17 -08:00
@@ -22,6 +22,9 @@
  *
  */
 
+#ifndef DVB_BT8XX_H
+#define DVB_BT8XX_H
+
 #include <linux/i2c.h>
 #include "dvbdev.h"
 #include "dvb_net.h"
@@ -30,6 +33,7 @@
 #include "sp887x.h"
 #include "dst.h"
 #include "nxt6000.h"
+#include "cx24110.h"
 
 struct dvb_bt8xx_card {
 	struct semaphore lock;
@@ -50,3 +54,5 @@
 				
 	struct dvb_frontend* fe;
 };
+
+#endif /* DVB_BT8XX_H */
diff -Nru a/drivers/media/dvb/cinergyT2/cinergyT2.c b/drivers/media/dvb/cinergyT2/cinergyT2.c
--- a/drivers/media/dvb/cinergyT2/cinergyT2.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/media/dvb/cinergyT2/cinergyT2.c	2005-03-01 23:38:58 -08:00
@@ -541,7 +541,7 @@
 
 	switch (cmd) {
 	case FE_GET_INFO:
-		return copy_to_user((void*) arg, &cinergyt2_fe_info,
+		return copy_to_user((void __user*) arg, &cinergyt2_fe_info,
 				    sizeof(struct dvb_frontend_info));
 
 	case FE_READ_STATUS:
@@ -556,7 +556,7 @@
 		if (stat->lock_bits & (1 << 1))
 			status |= FE_HAS_VITERBI;
 
-		return copy_to_user((void *) arg, &status, sizeof(status));
+		return copy_to_user((void  __user*) arg, &status, sizeof(status));
 
 	case FE_READ_BER:
 		return put_user(le32_to_cpu(stat->viterbi_error_rate),
@@ -584,7 +584,7 @@
 		if ((file->f_flags & O_ACCMODE) == O_RDONLY)
 			return -EPERM;
 
-		if (copy_from_user(&p, (void *) arg, sizeof(p)))
+		if (copy_from_user(&p, (void  __user*) arg, sizeof(p)))
 			return -EFAULT;
 
 		if (down_interruptible(&cinergyt2->sem))
@@ -624,7 +624,7 @@
 		 *  for now we only fill the status field. the parameters
 		 *  are trivial to fill as soon FE_GET_FRONTEND is done.
 		 */
-		struct dvb_frontend_event *e = (void *) arg;
+		struct dvb_frontend_event __user *e = (void __user *) arg;
 		if (cinergyt2->pending_fe_events == 0) {
 			if (file->f_flags & O_NONBLOCK)
 				return -EWOULDBLOCK;
diff -Nru a/drivers/media/dvb/dibusb/Kconfig b/drivers/media/dvb/dibusb/Kconfig
--- a/drivers/media/dvb/dibusb/Kconfig	2005-03-01 23:38:55 -08:00
+++ b/drivers/media/dvb/dibusb/Kconfig	2005-03-01 23:38:55 -08:00
@@ -1,12 +1,13 @@
 config DVB_DIBUSB
-	tristate "DiBcom USB DVB-T devices (see help for device list)"
+	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).
+	  DiBcom (http://www.dibcom.fr) and C&E.
 
 	  Devices supported by this driver:
 
@@ -14,12 +15,14 @@
 		TwinhanDTV Magic Box (VP7041e)
 	    KWorld V-Stream XPERT DTV - DVB-T USB
 	    Hama DVB-T USB-Box
-	    DiBcom reference device (non-public)
+	    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
-	    Yakumo DVB-T mobile USB2.0
+	    Artec T1 USB1.1 and USB2.0 boxes
+	    Yakumo/Typhoon DVB-T USB2.0
+	    Hanftek UMT-010 USB2.0
 
 	  The VP7041 seems to be identical to "CTS Portable" (Chinese
 	  Television System).
@@ -46,6 +49,7 @@
 	    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.
 
diff -Nru a/drivers/media/dvb/dibusb/Makefile b/drivers/media/dvb/dibusb/Makefile
--- a/drivers/media/dvb/dibusb/Makefile	2005-03-01 23:38:58 -08:00
+++ b/drivers/media/dvb/dibusb/Makefile	2005-03-01 23:38:58 -08:00
@@ -1,3 +1,11 @@
+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-dibusb-pid.o
+
 obj-$(CONFIG_DVB_DIBUSB) += dvb-dibusb.o
 
 EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
diff -Nru a/drivers/media/dvb/dibusb/dvb-dibusb-core.c b/drivers/media/dvb/dibusb/dvb-dibusb-core.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/media/dvb/dibusb/dvb-dibusb-core.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,480 @@
+/*
+ * 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;
+module_param(rc_query_interval, int, 0644);
+MODULE_PARM_DESC(rc_query_interval, "interval in msecs for remote control query (default: 100; min: 40)");
+
+/* Vendor IDs */
+#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_HYPER_PALTEK				0x1025
+#define USB_VID_HANFTEK						0x15f4
+#define USB_VID_IMC_NETWORKS				0x13d3
+#define USB_VID_TWINHAN						0x1822
+#define USB_VID_ULTIMA_ELECTRONIC			0x05d8
+
+/* Product IDs */
+#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		0x0025
+#define USB_PID_YAKUMO_DTT200U_COLD			0x0201
+#define USB_PID_YAKUMO_DTT200U_WARM			0x0301
+
+/* 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) },
+
+/* the following device is actually not supported, but when loading the 
+ * correct firmware (ie. its usb ids will change) everything works fine then 
+ */
+/* 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) },
+
+/* 
+ * 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
+/* 30 */	{ USB_DEVICE(USB_VID_ANCHOR,		USB_PID_ULTIMA_TVBOX_ANCHOR_COLD) },
+/* 31 */	{ USB_DEVICE(USB_VID_CYPRESS,		USB_PID_ULTIMA_TVBOX_USB2_FX_COLD) },
+/* 32 */	{ USB_DEVICE(USB_VID_ANCHOR,		USB_PID_ULTIMA_TVBOX_USB2_FX_WARM) },
+/* 33 */	{ 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 }, 
+	},
+};
+
+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 = 3, .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, 
+	  3, 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, 
+	  3, 188*210,
+	  DIBUSB_RC_NEC_PROTOCOL,
+	  &dibusb_demod[DIBUSB_DIB3000MC],
+	  &dibusb_tuner[DIBUSB_TUNER_COFDM_PANASONIC_ENV57H1XD5],
+	},
+	{ UMT2_0, &dibusb_usb_ctrl[2],
+	  "dvb-dibusb-umt-1.fw",
+	  0x01, 0x02, 
+	  15, 188*21,
+	  DIBUSB_RC_NO,
+	  &dibusb_demod[DIBUSB_MT352],
+//	  &dibusb_tuner[DIBUSB_TUNER_COFDM_PANASONIC_ENV77H11D5],
+	  &dibusb_tuner[DIBUSB_TUNER_CABLE_LG_TDTP_E102P],
+	},
+};
+
+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 },
+	},
+	{	"AVermedia/Yakumo/Hama/Typhoon DVB-T USB2.0",
+		&dibusb_device_classes[UMT2_0],
+		{ &dib_table[2], NULL },
+		{ NULL },
+	},	
+	{	"Hanftek UMT-010 DVB-T USB2.0",
+		&dibusb_device_classes[UMT2_0],
+		{ &dib_table[28], NULL },
+		{ &dib_table[29], NULL },
+	},	
+#ifdef CONFIG_DVB_DIBUSB_MISDESIGNED_DEVICES
+	{	"Artec T1 USB1.1 TVBOX with AN2235 (misdesigned)",
+		&dibusb_device_classes[DIBUSB1_1_AN2235],
+		{ &dib_table[30], NULL },
+		{ NULL },
+	},
+	{	"Artec T1 USB2.0 TVBOX with FX2 IDs (misdesigned, please report the warm ID)",
+		&dibusb_device_classes[DIBUSB2_0],
+		{ &dib_table[31], NULL },
+		{ &dib_table[32], 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[33], 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_pid_list_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_pid_list_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_find_device (struct usb_device *udev,int *cold)
+{
+	int i,j;
+	*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;
+				return &dibusb_devices[i];
+			}
+		}
+
+		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;
+				return &dibusb_devices[i];
+			}
+		}
+	}
+	return NULL;
+}
+
+/*
+ * 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;
+
+		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 */
+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 -Nru a/drivers/media/dvb/dibusb/dvb-dibusb-dvb.c b/drivers/media/dvb/dibusb/dvb-dibusb-dvb.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/media/dvb/dibusb/dvb-dibusb-dvb.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,205 @@
+/*
+ * 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;
+	int ret;
+
+	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 % 500 == 0)
+		deb_info("%d urbs completed so far.\n",urb_compl_count);
+
+	switch (urb->status) {
+		case 0:         /* success */
+		case -ETIMEDOUT:    /* NAK */
+			break;
+		case -ECONNRESET:   /* unlink */
+		case -ENOENT:
+		case -ESHUTDOWN:
+			return;
+		default:        /* error */
+			warn("urb completition error %d.", urb->status);
+	}
+
+	if (dib->feedcount > 0) {
+		deb_ts("URB return len: %d\n",urb->actual_length);
+		if (urb->actual_length % 188) 
+			deb_ts("TS Packets: %d, %d\n", urb->actual_length/188,urb->actual_length % 188);
+
+		/* Francois recommends to drop not full-filled packets, even if they may 
+		 * contain valid TS packets, at least for USB1.1
+		 *
+		 * if (urb->actual_length == dib->dibdev->parm->default_size && dib->dvb_is_ready) */
+		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 the " 
+					"actual_length or !dvb_is_ready (%d).\n",dib->init_state & DIBUSB_STATE_DVB);
+	} else 
+		deb_ts("URB dropped because of feedcount.\n");
+
+	ret = usb_submit_urb(urb,GFP_ATOMIC);
+	deb_ts("urb resubmitted, (%d)\n",ret);
+}
+
+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 ((dib->dibdev->parm->firmware_bug && dib->feedcount) || 
+	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;
+			}
+		}
+	}
+	
+	dib->feedcount = newfeedcount;
+
+	/* get a free pid from the list and activate it on the device
+	 * specific pid_filter
+	 */
+	if (dib->pid_parse)
+		dibusb_ctrl_pid(dib,dvbdmxfeed,onoff);
+
+	/* 
+	 * start the feed, either if there is the firmware bug or 
+	 * if this was the first pid to set and there is still a pid for 
+	 * reception.
+	 */
+	
+//	if ((dib->dibdev->parm->firmware_bug)
+	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 LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,4)
+    if ((ret = dvb_register_adapter(&dib->adapter, DRIVER_DESC)) < 0) {
+#else
+    if ((ret = dvb_register_adapter(&dib->adapter, DRIVER_DESC , 
+			THIS_MODULE)) < 0) {
+#endif
+		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 -Nru a/drivers/media/dvb/dibusb/dvb-dibusb-fe-i2c.c b/drivers/media/dvb/dibusb/dvb-dibusb-fe-i2c.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/media/dvb/dibusb/dvb-dibusb-fe-i2c.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,598 @@
+/*
+ * 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>
+
+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;
+}
+
+/* there is a ugly pid_filter in the firmware of the umt devices, it is accessible 
+ * by i2c address 0x8. Don't know how to deactivate it and how many rows it has.
+ */
+static int dibusb_umt_pid_control(struct dvb_frontend *fe, int index, int pid, int onoff)
+{
+	struct usb_dibusb *dib = fe->dvb->priv;
+	u8 b[3];
+	b[0] = index;
+	if (onoff) {
+		b[1] = (pid >> 8) & 0xff;
+		b[2] = pid & 0xff;
+	} else {
+		b[1] = 0;
+		b[2] = 0;
+	}
+	dibusb_i2c_msg(dib, 0x8, b, 3, NULL,0);
+	dibusb_set_streaming_mode(dib,0);
+	dibusb_set_streaming_mode(dib,1);
+	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;
+
+			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);
+					dib->xfer_ops.pid_ctrl = dibusb_umt_pid_control;
+				break;
+			}
+			if (dib->fe != NULL) {
+				info("found demodulator at i2c address 0x%x",dib->dibdev->dev_cl->demod->i2c_addrs[i]);
+				break;
+			}
+		}
+		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 = fep->frequency;
+	u32 tfreq = ((freq + 36125000)*6 + 500000) / 1000000;
+	u8 TA, T210, R210, ctrl1, cp210, p4321;
+	if (freq > 858000000) {
+		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 < 470000000) 
+		cp210 = 2;  // VHF Low and High band ch E12 to E4 to E12
+	else if (freq < 526000000) 
+		cp210 = 4;  // UHF band Ch E21 to E27
+	else // if (freq < 862000000) 
+		cp210 = 5;  // UHF band ch E28 to E69
+
+//*********************    BW select  *******************************
+	if (freq < 153000000) 
+		p4321  = 1; // BW selected for VHF low
+	else if (freq < 470000000) 
+		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 p3210, p4;
+
+#define TUNER_MUL 62500
+
+	div = (fep->frequency + 36125000 + TUNER_MUL / 2) / TUNER_MUL;
+
+	if (fep->frequency < 174500000) 
+		p3210 = 1; // not supported by the tdtp_e102p
+	else if (fep->frequency < 230000000) // VHF
+		p3210 = 2;
+	else 
+		p3210 = 4;
+
+	if (fep->u.ofdm.bandwidth == BANDWIDTH_7_MHZ)
+		p4 = 0;
+	else 
+		p4 = 1;
+		
+	pllbuf[0] = (div >> 8) & 0x7f;
+	pllbuf[1] = div & 0xff;
+	pllbuf[2] = 0xce;
+	pllbuf[3] = (p4 << 4) | p3210;
+
+	return 0;
+}
+
+static int lg_tdtp_e102p_mt352_demod_init(struct dvb_frontend *fe)
+{
+	static u8 mt352_clock_config[] = { 0x89, 0xb0, 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, 0x14, 0x22 };
+	static u8 mt352_sec_agc_cfg[] = { 0x69, 0x00, 0xff, 0xff, 0x00, 0xff, 0x00, 0x40, 0x40 };
+
+	static u8 mt352_unk [] = { 0xb5, 0x7a };
+
+	static u8 mt352_acq_ctl[] = { 0x53, 0x5f };
+	static u8 mt352_input_freq_1[] = { 0x56, 0xf1, 0x05 };
+	
+//	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_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_cfg, sizeof(mt352_sec_agc_cfg));
+
+	mt352_write(fe, mt352_unk, sizeof(mt352_unk));
+	
+	mt352_write(fe, mt352_acq_ctl, sizeof(mt352_acq_ctl));
+	mt352_write(fe, mt352_input_freq_1, sizeof(mt352_input_freq_1));
+	
+//	mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg));
+
+	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 -Nru a/drivers/media/dvb/dibusb/dvb-dibusb-firmware.c b/drivers/media/dvb/dibusb/dvb-dibusb-firmware.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/media/dvb/dibusb/dvb-dibusb-firmware.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,85 @@
+/*
+ * 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, 5*HZ);
+}
+
+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 a valid firmware file. (%s) "
+			"Please see linux/Documentation/dvb/ for more details on firmware-problems.",
+			dibdev->dev_cl->firmware);
+		return ret;
+	}
+	
+	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 -Nru a/drivers/media/dvb/dibusb/dvb-dibusb-pid.c b/drivers/media/dvb/dibusb/dvb-dibusb-pid.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/media/dvb/dibusb/dvb-dibusb-pid.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,80 @@
+/*
+ * dvb-dibusb-pid.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 internal
+ * pid-list. This pid-list mirrors the information currently stored in the
+ * devices pid-list.
+ */
+#include "dvb-dibusb.h"
+
+int dibusb_pid_list_init(struct usb_dibusb *dib)
+{
+	int i;
+	dib->pid_list = kmalloc(sizeof(struct dibusb_pid) * dib->dibdev->dev_cl->demod->pid_filter_count,GFP_KERNEL);
+	if (dib->pid_list == NULL)
+		return -ENOMEM;
+
+	deb_xfer("initializing %d pids for the pid_list.\n",dib->dibdev->dev_cl->demod->pid_filter_count);
+	
+	dib->pid_list_lock = SPIN_LOCK_UNLOCKED;
+	memset(dib->pid_list,0,dib->dibdev->dev_cl->demod->pid_filter_count*(sizeof(struct dibusb_pid)));
+	for (i=0; i < dib->dibdev->dev_cl->demod->pid_filter_count; i++) {
+		dib->pid_list[i].index = i;
+		dib->pid_list[i].pid = 0;
+		dib->pid_list[i].active = 0;
+	}
+
+	dib->init_state |= DIBUSB_STATE_PIDLIST;
+	return 0;
+}
+
+void dibusb_pid_list_exit(struct usb_dibusb *dib)
+{
+	if (dib->init_state & DIBUSB_STATE_PIDLIST)
+		kfree(dib->pid_list);
+	dib->init_state &= ~DIBUSB_STATE_PIDLIST;
+}
+
+/* fetch a pid from pid_list and set it on or off */
+int dibusb_ctrl_pid(struct usb_dibusb *dib, struct dvb_demux_feed *dvbdmxfeed , int onoff)
+{
+	int i,ret = -1;
+	unsigned long flags;
+	u16 pid = dvbdmxfeed->pid;
+
+	if (onoff) {
+		spin_lock_irqsave(&dib->pid_list_lock,flags);
+		for (i=0; i < dib->dibdev->dev_cl->demod->pid_filter_count; i++)
+			if (!dib->pid_list[i].active) {
+				dib->pid_list[i].pid = pid;
+				dib->pid_list[i].active = 1;
+				ret = i;
+				break;
+			}
+		dvbdmxfeed->priv = &dib->pid_list[ret];
+		spin_unlock_irqrestore(&dib->pid_list_lock,flags);
+		
+		if (dib->xfer_ops.pid_ctrl != NULL) 
+			dib->xfer_ops.pid_ctrl(dib->fe,dib->pid_list[ret].index,dib->pid_list[ret].pid,1);
+	} else {
+		struct dibusb_pid *dpid = dvbdmxfeed->priv;
+		
+		if (dib->xfer_ops.pid_ctrl != NULL) 
+			dib->xfer_ops.pid_ctrl(dib->fe,dpid->index,0,0);
+		
+		dpid->pid = 0;
+		dpid->active = 0;
+		ret = dpid->index;
+	}
+	
+	/* a free pid from the list */
+	deb_info("setting pid: %5d %04x at index %d '%s'\n",pid,pid,ret,onoff ? "on" : "off");
+
+	return ret;
+}
+
diff -Nru a/drivers/media/dvb/dibusb/dvb-dibusb-remote.c b/drivers/media/dvb/dibusb/dvb-dibusb-remote.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/media/dvb/dibusb/dvb-dibusb-remote.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,197 @@
+/*
+ * 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; } 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 },
+};
+
+/*
+ * 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;
+	int i;
+	if ((ret = dibusb_readwrite_usb(dib,b,1,rb,5)))
+		return ret;
+
+	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(rc_keys)/sizeof(rc_keys[0]); i++) {
+				if (rc_keys[i].c0 == rb[1] &&
+					rc_keys[i].c1 == rb[2] &&
+				    rc_keys[i].c2 == rb[3]) {
+					dib->rc_input_event = rc_keys[i].key;
+					deb_rc("Translated key 0x%04x\n", dib->rc_input_event);
+					/* Signal down and up events for this key. */
+					input_report_key(&dib->rc_input_dev, dib->rc_input_event, 1);
+					input_report_key(&dib->rc_input_dev, dib->rc_input_event, 0);
+					input_sync(&dib->rc_input_dev);
+					break;
+				}
+			}
+			break;
+		case DIBUSB_RC_NEC_EMPTY: /* No (more) remote control keys. */
+			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. */
+			deb_rc("Key repeat\n");
+			break;
+		default:
+			break;
+	}
+	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";
+
+	for (i=0; i<sizeof(rc_keys)/sizeof(rc_keys[0]); i++)
+		set_bit(rc_keys[i].key, dib->rc_input_dev.keybit);
+
+	input_register_device(&dib->rc_input_dev);
+
+	dib->rc_input_event = KEY_MAX;
+
+	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 -Nru a/drivers/media/dvb/dibusb/dvb-dibusb-usb.c b/drivers/media/dvb/dibusb/dvb-dibusb-usb.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/media/dvb/dibusb/dvb-dibusb-usb.c	2005-03-01 23:39:26 -08:00
@@ -0,0 +1,263 @@
+/*
+ * 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;
+
+	if (dib->feedcount && 
+		wbuf[0] == DIBUSB_REQ_I2C_WRITE && 
+		dib->dibdev->dev_cl->id == DIBUSB1_1)
+		deb_err("BUG: writing to i2c, while TS-streaming destroys the stream."
+				"(%x reg: %x %x)\n", wbuf[0],wbuf[2],wbuf[3]);
+			
+	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
+ */
+
+#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 
+static int dibusb_write_usb(struct usb_dibusb *dib, u8 *buf, u16 len)
+{
+	return dibusb_readwrite_usb(dib,buf,len,NULL,0);
+}
+
+/*
+ * 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");
+	dibusb_ioctl_cmd(dib,DIBUSB_IOCTL_CMD_POWER_MODE, b,1);
+	
+	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");
+	dibusb_ioctl_cmd(dib,DIBUSB_IOCTL_CMD_POWER_MODE, b,1);
+
+	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);
+}
+
+int dibusb_streaming(struct usb_dibusb *dib,int onoff)
+{
+	switch (dib->dibdev->dev_cl->id) {
+		case DIBUSB2_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;
+		case UMT2_0: 
+			return dibusb_set_streaming_mode(dib,onoff);
+			break;
+		default:
+			break;
+	}
+	return 0;
+}
+
+int dibusb_urb_init(struct usb_dibusb *dib)
+{
+	int ret,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;
+		}
+		deb_info("submitting URB no. %d\n",i);
+		
+		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;
+
+		if ((ret = usb_submit_urb(dib->urb_list[i],GFP_ATOMIC))) {
+			err("could not submit buffer urb no. %d\n",i);
+			return ret;
+		}
+		dib->init_state |= DIBUSB_STATE_URB_SUBMIT;
+	}
+
+	/* dib->pid_parse here contains the value of the module parameter */
+	/* decide if pid parsing can be deactivated:
+	 * is possible (by speed) and wanted (by user)
+	 */
+	switch (dib->dibdev->dev_cl->id) {
+		case DIBUSB2_0:
+			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;
+	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("killing URB no. %d.\n",i);
+
+				/* stop the URBs */
+				usb_kill_urb(dib->urb_list[i]);
+				
+				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_SUBMIT;
+		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;
+	return 0;
+}
diff -Nru a/drivers/media/dvb/dibusb/dvb-dibusb.c b/drivers/media/dvb/dibusb/dvb-dibusb.c
--- a/drivers/media/dvb/dibusb/dvb-dibusb.c	2005-03-01 23:38:52 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,1032 +0,0 @@
-/*
- * Driver for mobile USB Budget DVB-T devices based on reference
- * design made by DiBcom (http://www.dibcom.fr/)
- *
- * dvb-dibusb.c
- *
- * Copyright (C) 2004 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 <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/usb.h>
-#include <linux/firmware.h>
-#include <linux/version.h>
-#include <linux/moduleparam.h>
-#include <linux/pci.h>
-#include <linux/input.h>
-
-#include "dmxdev.h"
-#include "dvb_demux.h"
-#include "dvb_filter.h"
-#include "dvb_net.h"
-#include "dvb_frontend.h"
-#include "dib3000.h"
-
-#include "dvb-dibusb.h"
-
-
-/* debug */
-#ifdef CONFIG_DVB_DIBCOM_DEBUG
-#define dprintk(level,args...) \
-	    do { if ((debug & level)) { printk(args); } } while (0)
-
-#define debug_dump(b,l) if (debug) {\
-	int i; deb_xfer("%s: %d > ",__FUNCTION__,l); \
-	for (i = 0; i < l; i++) deb_xfer("%02x ", b[i]); \
-	deb_xfer("\n");\
-}
-
-static int debug;
-module_param(debug, int, 0x644);
-MODULE_PARM_DESC(debug, "set debugging level (1=info,2=xfer,4=alotmore,8=ts,16=err,32=rc (|-able)).");
-#else
-#define dprintk(args...)
-#define debug_dump(b,l)
-#endif
-
-#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)
-
-static int pid_parse;
-module_param(pid_parse, int, 0x644);
-MODULE_PARM_DESC(pid_parse, "enable pid parsing (filtering) when running at USB2.0");
-
-/* Version information */
-#define DRIVER_VERSION "0.1"
-#define DRIVER_DESC "Driver for DiBcom based USB Budget DVB-T device"
-#define DRIVER_AUTHOR "Patrick Boettcher, patrick.boettcher@desy.de"
-
-static 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;
-
-	if (dib->feedcount &&
-		wbuf[0] == DIBUSB_REQ_I2C_WRITE &&
-		dib->dibdev->parm->type == DIBUSB1_1)
-		deb_err("BUG: writing to i2c, while TS-streaming destroys the stream."
-				"(%x reg: %x %x)\n", wbuf[0],wbuf[2],wbuf[3]);
-			
-	debug_dump(wbuf,wlen);
-
-	ret = usb_bulk_msg(dib->udev,usb_sndbulkpipe(dib->udev,
-			dib->dibdev->parm->cmd_pipe), 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->parm->result_pipe),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;
-}
-
-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);
-
-	deb_alot("wo: %d, wlen: %d, len: %d\n",wo,wlen,len);
-
-	sndbuf[0] = wo ? DIBUSB_REQ_I2C_WRITE : DIBUSB_REQ_I2C_READ;
-	sndbuf[1] = (addr & 0xfe) | (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);
-}
-
-/*
- * DVB stuff
- */
-static 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\n",dib->feedcount,urb->status);
-
-	if (dib->feedcount > 0 && urb->status == 0) {
-		deb_ts("URB return len: %d\n",urb->actual_length);
-		if (urb->actual_length % 188)
-			deb_ts("TS Packets: %d, %d\n", urb->actual_length/188,urb->actual_length % 188);
-
-		/* Francois recommends to drop not full-filled packets, even if they may 
-		 * contain valid TS packets
-		 */
-		if (urb->actual_length == dib->dibdev->parm->default_size && dib->dvb_is_ready)
-		dvb_dmx_swfilter_packets(&dib->demux, (u8*) urb->transfer_buffer,urb->actual_length/188);
-		else
-			deb_ts("URB dropped because of the " 
-					"actual_length or !dvb_is_ready (%d).\n",dib->dvb_is_ready);
-	} else 
-		deb_ts("URB dropped because of feedcount or status.\n");
-
-		usb_submit_urb(urb,GFP_KERNEL);
-}
-
-static int dibusb_ctrl_feed(struct usb_dibusb *dib, int pid, int onoff)
-{
-	if (dib->dibdev->parm->firmware_bug && dib->feedcount) {
-		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;
-			}
-		} else {
-			err("fifo_ctrl is not set.");
-			return -ENODEV;
-		}
-	}
-
-	dib->feedcount += onoff ? 1 : -1;
-
-	if (dib->pid_parse) {
-	if (dib->xfer_ops.pid_ctrl != NULL) {
-		if (dib->xfer_ops.pid_ctrl(dib->fe,pid,onoff) < 0) {
-		err("no free pid in list.");
-		return -ENODEV;
-	}
-	} else {
-		err("no pid ctrl callback.");
-		return -ENODEV;
-	}
-	}
-	/*
-	 * start the feed, either if there is the firmware bug or
-	 * if this was the first pid to set.
-	 */
-	if (dib->dibdev->parm->firmware_bug || dib->feedcount == onoff) {
-
-		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;
-			}
-		} else {
-			err("fifo_ctrl is not set.");
-			return -ENODEV;
-}
-	}
-	return 0;
-}
-
-static int dibusb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
-{
-	struct usb_dibusb *dib = dvbdmxfeed->demux->priv;
-	deb_ts("pid: 0x%04x, feedtype: %d\n", dvbdmxfeed->pid,dvbdmxfeed->type);
-	dvbdmxfeed->priv = dib;
-	return dibusb_ctrl_feed(dib,dvbdmxfeed->pid,1);
-}
-
-static int dibusb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
-{
-	struct usb_dibusb *dib = (struct usb_dibusb *) dvbdmxfeed->priv;
-	if (dib == NULL) {
-		err("dib in dmxfeed->priv was NULL");
-		return -EINVAL;
-}
-	deb_ts("dvbdmxfeed pid: 0x%04x, feedtype: %d\n",
-			dvbdmxfeed->pid, dvbdmxfeed->type);
-	return dibusb_ctrl_feed(dib,dvbdmxfeed->pid,0);
-}
-
-/* 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; } 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 },
-};
-
-/*
- * 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;
-	int i;
-	if ((ret = dibusb_readwrite_usb(dib,b,1,rb,5)))
-		return ret;
-
-	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(rc_keys)/sizeof(rc_keys[0]); i++) {
-				if (rc_keys[i].c0 == rb[1] &&
-					rc_keys[i].c1 == rb[2] &&
-				    rc_keys[i].c2 == rb[3]) {
-					dib->rc_input_event = rc_keys[i].key;
-					deb_rc("Translated key 0x%04x\n", dib->rc_input_event);
-					/* Signal down and up events for this key. */
-					input_report_key(&dib->rc_input_dev, dib->rc_input_event, 1);
-					input_report_key(&dib->rc_input_dev, dib->rc_input_event, 0);
-					input_sync(&dib->rc_input_dev);
-					break;
-				}
-			}
-			break;
-		case DIBUSB_RC_NEC_EMPTY: /* No (more) remote control keys. */
-			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. */
-			deb_rc("Key repeat\n");
-			break;
-		default:
-			break;
-	}
-	
-	return 0;
-}
-
-#define RC_QUERY_INTERVAL (100)	/* milliseconds */
-
-/* Remote-control poll function - called every RC_QUERY_INTERVAL ms to see
-   whether the remote control has received anything. */
-static void dibusb_query_rc (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(RC_QUERY_INTERVAL));
-}
-
-/*
- * Cypress controls
- */
-
-#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 :).
- */
-static int dibusb_interrupt_read_loop(struct usb_dibusb *dib)
-{
-	u8 b[1] = { DIBUSB_REQ_INTR_READ };
-	return dibusb_write_usb(dib,b,1);
-}
-
-/*
- * ioctl for power control
- */
-static int dibusb_hw_sleep(struct usb_dibusb *dib)
-{
-	u8 b[1] = { DIBUSB_IOCTL_POWER_SLEEP };
-	return dibusb_ioctl_cmd(dib,DIBUSB_IOCTL_CMD_POWER_MODE, b,1);
-}
-
-#endif
-static int dibusb_write_usb(struct usb_dibusb *dib, u8 *buf, u16 len)
-{
-	return dibusb_readwrite_usb(dib,buf,len,NULL,0);
-}
-
-/*
- * 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;
-	b[0] = DIBUSB_REQ_SET_IOCTL;
-	b[1] = cmd;
-	memcpy(&b[2],param,size);
-
-	return dibusb_write_usb(dib,b,2+size);
-}
-
-static int dibusb_hw_wakeup(struct usb_dibusb *dib)
-{
-	u8 b[1] = { DIBUSB_IOCTL_POWER_WAKEUP };
-	return dibusb_ioctl_cmd(dib,DIBUSB_IOCTL_CMD_POWER_MODE, b,1);
-}
-
-/*
- * I2C
- */
-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;
-
-	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 int thomson_cable_eu_pll_set(struct dvb_frontend* fe, struct
-		dvb_frontend_parameters* params);
-
-static struct dib3000_config thomson_cable_eu_config = {
-	.demod_address = 0x10,
-	.pll_addr = 194,
-	.pll_set = thomson_cable_eu_pll_set,
-};
-
-static int thomson_cable_eu_pll_set(struct dvb_frontend* fe, struct
-		dvb_frontend_parameters* params)
-{
-	struct usb_dibusb* dib = (struct usb_dibusb*) fe->dvb->priv;
-	u8 buf[4];
-	struct i2c_msg msg = {
-		.addr = thomson_cable_eu_config.pll_addr,
-		.flags = 0,
-		.buf = buf,
-		.len = sizeof(buf)
-	};
-	u32 tfreq = (params->frequency + 36125000) / 62500;
-	int vu,p0,p1,p2;
-
-	if (params->frequency > 403250000)
-		vu = 1, p2 = 1, p1 = 0, p0 = 1;
-	else if (params->frequency > 115750000)
-		vu = 0, p2 = 1, p1 = 1, p0 = 0;
-	else if (params->frequency > 44250000)
-		vu = 0, p2 = 0, p1 = 1, p0 = 1;
-	else
-		return -EINVAL;
-
-	buf[0] = (tfreq >> 8) & 0x7f;
-	buf[1] = tfreq & 0xff;
-   	buf[2] = 0x8e;
-   	buf[3] = (vu << 7) | (p2 << 2) | (p1 << 1) | p0;
-
-	if (i2c_transfer (&dib->i2c_adap, &msg, 1) != 1)
-		return -EIO;
-
-	msleep(1);
-	return 0;
-}
-
-static int panasonic_cofdm_env57h1xd5_pll_set(struct dvb_frontend *fe, struct
-		dvb_frontend_parameters *params);
-
-static struct dib3000_config panasonic_cofdm_env57h1xd5 = {
-	.demod_address = 0x18,
-	.pll_addr = 192,
-	.pll_set = panasonic_cofdm_env57h1xd5_pll_set,
-};
-
-static int panasonic_cofdm_env57h1xd5_pll_set(struct dvb_frontend *fe, struct
-		dvb_frontend_parameters *params)
-{
-	struct usb_dibusb* dib = (struct usb_dibusb*) fe->dvb->priv;
-	u8 buf[4];
-	u32 freq = params->frequency;
-	u32 tfreq = (freq + 36125000) / 1000000 * 6 + 1;
-	u8 TA, T210, R210, ctrl1, cp210, p4321;
-	struct i2c_msg msg = {
-		.addr = panasonic_cofdm_env57h1xd5.pll_addr,
-		.flags = 0,
-		.buf = buf,
-		.len = sizeof(buf)
-	};
-
-	if (freq > 858000000) {
-		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 < 470000000)
-		cp210 = 2;  // VHF Low and High band ch E12 to E4 to E12
-	else if (freq < 526000000)
-		cp210 = 4;  // UHF band Ch E21 to E27
-	else // if (freq < 862000000)
-		cp210 = 5;  // UHF band ch E28 to E69
-
-//*********************    BW select  *******************************
-	if (freq < 153000000)
-		p4321  = 1; // BW selected for VHF low
-	else if (freq < 470000000)
-		p4321  = 2; // BW selected for VHF high E5 to E12
-	else // if (freq < 862000000)
-		p4321  = 4; // BW selection for UHF E21 to E69
-
-	buf[0] = (tfreq >> 8) & 0xff;
-	buf[1] = (tfreq >> 0) & 0xff;
-	buf[2] = 0xff & ctrl1;
-	buf[3] =  (cp210 << 5) | (p4321);
-
-	if (i2c_transfer (&dib->i2c_adap, &msg, 1) != 1)
-		return -EIO;
-
-	msleep(1);
-	return 0;
-}
-
-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 void frontend_init(struct usb_dibusb* dib)
-{
-	switch (dib->dibdev->parm->type) {
-		case DIBUSB1_1:
-		case DIBUSB1_1_AN2235:
-	dib->fe = dib3000mb_attach(&thomson_cable_eu_config, &dib->i2c_adap,&dib->xfer_ops);
-			break;
-		case DIBUSB2_0:
-			dib->fe = dib3000mc_attach(&panasonic_cofdm_env57h1xd5,&dib->i2c_adap, &dib->xfer_ops);
-			break;
-	}
-
-	if (dib->fe == NULL) {
-		printk("dvb-dibusb: A frontend driver was not found for device %04x/%04x\n",
-		       dib->udev->descriptor.idVendor,
-		       dib->udev->descriptor.idProduct);
-	} else {
-		if (dvb_register_frontend(dib->adapter, dib->fe)) {
-			printk("dvb-dibusb: Frontend registration failed!\n");
-			if (dib->fe->ops->release)
-				dib->fe->ops->release(dib->fe);
-			dib->fe = NULL;
-		}
-	}
-}
-
-static int dibusb_dvb_init(struct usb_dibusb *dib)
-{
-	int ret;
-
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,4)
-    if ((ret = dvb_register_adapter(&dib->adapter, DRIVER_DESC)) < 0) {
-#else
-    if ((ret = dvb_register_adapter(&dib->adapter, DRIVER_DESC ,
-			THIS_MODULE)) < 0) {
-#endif
-		deb_info("dvb_register_adapter failed: error %d", ret);
-		goto err;
-	}
-	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 ((i2c_add_adapter(&dib->i2c_adap) < 0)) {
-		err("could not add i2c adapter");
-		goto err_i2c;
-	}
-
-	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 = 16;
-	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);
-
-	frontend_init(dib);
-
-	/* Start the remote-control polling. */
-	schedule_delayed_work(&dib->rc_query_work, msecs_to_jiffies(RC_QUERY_INTERVAL));
-
-	goto success;
-err_dmx_dev:
-	dvb_dmx_release(&dib->demux);
-err_dmx:
-	i2c_del_adapter(&dib->i2c_adap);
-err_i2c:
-	dvb_unregister_adapter(dib->adapter);
-err:
-	return ret;
-success:
-	dib->dvb_is_ready = 1;
-	return 0;
-}
-
-static int dibusb_dvb_exit(struct usb_dibusb *dib)
-{
-	cancel_delayed_work(&dib->rc_query_work);
-	flush_scheduled_work();
-	input_unregister_device(&dib->rc_input_dev);
-
-	dib->dvb_is_ready = 0;
-	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);
-	if (dib->fe != NULL) dvb_unregister_frontend(dib->fe);
-	i2c_del_adapter(&dib->i2c_adap);
-	dvb_unregister_adapter(dib->adapter);
-
-	return 0;
-}
-
-static int dibusb_exit(struct usb_dibusb *dib)
-{
-	int i;
-	if (dib->urb_list != NULL) {
-		for (i = 0; i < dib->dibdev->parm->num_urbs; i++) {
-			if (dib->urb_list[i] != NULL) {
-			deb_info("killing URB no. %d.\n",i);
-
-				/* stop the URBs */
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,7)
-				usb_unlink_urb(dib->urb_list[i]);
-#else
-				usb_kill_urb(dib->urb_list[i]);
-#endif
-			
-			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);
-		}
-
-	pci_free_consistent(NULL,
-		dib->dibdev->parm->urb_buf_size*dib->dibdev->parm->num_urbs,dib->buffer,
-		dib->dma_handle);
-	return 0;
-}
-
-static int dibusb_init(struct usb_dibusb *dib)
-{
-	int ret,i,bufsize;
-	sema_init(&dib->usb_sem, 1);
-	sema_init(&dib->i2c_sem, 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->parm->cmd_pipe));
-	usb_clear_halt(dib->udev,usb_rcvbulkpipe(dib->udev,dib->dibdev->parm->result_pipe));
-	usb_clear_halt(dib->udev,usb_rcvbulkpipe(dib->udev,dib->dibdev->parm->data_pipe));
-
-	/* allocate the array for the data transfer URBs */
-	dib->urb_list = kmalloc(dib->dibdev->parm->num_urbs*sizeof(struct urb *),GFP_KERNEL);
-	if (dib->urb_list == NULL)
-		return -ENOMEM;
-	memset(dib->urb_list,0,dib->dibdev->parm->num_urbs*sizeof(struct urb *));
-
-	bufsize = dib->dibdev->parm->num_urbs*dib->dibdev->parm->urb_buf_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");
-		dibusb_exit(dib);
-		return -ENOMEM;
-	}
-	deb_info("allocation complete\n");
-	memset(dib->buffer,0,bufsize);
-
-	/* allocate and submit the URBs */
-	for (i = 0; i < dib->dibdev->parm->num_urbs; i++) {
-		if (!(dib->urb_list[i] = usb_alloc_urb(0,GFP_KERNEL))) {
-		dibusb_exit(dib);
-		return -ENOMEM;
-	}
-		deb_info("submitting URB no. %d\n",i);
-
-		usb_fill_bulk_urb( dib->urb_list[i], dib->udev,
-				usb_rcvbulkpipe(dib->udev,dib->dibdev->parm->data_pipe),
-				&dib->buffer[i*dib->dibdev->parm->urb_buf_size],
-				dib->dibdev->parm->urb_buf_size,
-				dibusb_urb_complete, dib);
-
-		dib->urb_list[i]->transfer_flags = 0;
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,7)
-		dib->urb_list[i]->timeout = 0;
-#endif
-
-		if ((ret = usb_submit_urb(dib->urb_list[i],GFP_KERNEL))) {
-			err("could not submit buffer urb no. %d\n",i);
-			dibusb_exit(dib);
-			return ret;
-		}
-	}
-
-	dib->dvb_is_ready = 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";
-
-	for (i=0; i<sizeof(rc_keys)/sizeof(rc_keys[0]); i++)
-		set_bit(rc_keys[i].key, dib->rc_input_dev.keybit);
-
-	input_register_device(&dib->rc_input_dev);
-
-	dib->rc_input_event = KEY_MAX;
-
-	INIT_WORK(&dib->rc_query_work, dibusb_query_rc, dib);
-
-	dibusb_hw_wakeup(dib);
-
-	if ((ret = dibusb_dvb_init(dib))) {
-		dibusb_exit(dib);
-		return ret;
-	}
-	return 0;
-}
-
-/*
- * 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, 5*HZ);
-}
-
-static int dibusb_loadfirmware(struct usb_device *udev,
-		struct dibusb_device *dibdev)
-{
-	const struct firmware *fw = NULL;
-	const char **fws;
-	u16 addr;
-	u8 *b,*p;
-	int ret = 0,i;
-
-	fws = dibdev->parm->fw_filenames;
-
-	for (i = 0; i < sizeof(fws)/sizeof(const char*); i++) {
-		if ((ret = request_firmware(&fw, fws[i], &udev->dev)) == 0) {
-			info("using firmware file (%s).",fws[i]);
-			break;
-		}
-		deb_info("tried to find '%s' firmware - unsuccessful. (%d)\n",
-				fws[i],ret);
-	}
-
-	if (fw == NULL) {
-		err("did not find a valid firmware file. "
-			"Please see linux/Documentation/dvb/ for more details on firmware-problems.");
-		return -EINVAL;
-	}
-	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->parm->usb_cpu_csreg,&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->parm->usb_cpu_csreg,&reset,1) != 1) {
-			err("could not restart the USB controller CPU.");
-			ret = -EINVAL;
-		}
-
-		kfree(p);
-	} else {
-		ret = -ENOMEM;
-	}
-	release_firmware(fw);
-
-	return ret;
-}
-
-/*
- * 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_device *dibdev = NULL;
-
-	int ret = -ENOMEM,i,cold=0;
-
-	for (i = 0; i < DIBUSB_SUPPORTED_DEVICES; i++)
-		if (dibusb_devices[i].cold_product_id == udev->descriptor.idProduct ||
-			dibusb_devices[i].warm_product_id == udev->descriptor.idProduct) {
-			dibdev = &dibusb_devices[i];
-
-			cold = dibdev->cold_product_id == udev->descriptor.idProduct;
-
-			if (cold)
-				info("found a '%s' in cold state, will try to load a firmware",dibdev->name);
-			else
-				info("found a '%s' in warm state.",dibdev->name);
-		}
-
-	if (dibdev == NULL) {
-		err("something went very wrong, "
-				"unknown product ID: %.4x",udev->descriptor.idProduct);
-		return -ENODEV;
-	}
-
-	if (cold)
-		ret = dibusb_loadfirmware(udev,dibdev);
-	else {
-		dib = kmalloc(sizeof(struct usb_dibusb),GFP_KERNEL);
-		if (dib == NULL) {
-			err("no memory");
-			return ret;
-		}
-		memset(dib,0,sizeof(struct usb_dibusb));
-
-		dib->pid_parse = 1;
-		switch (udev->speed) {
-			case USB_SPEED_LOW:
-				err("cannot handle USB speed because it is to sLOW.");
-				break;
-			case USB_SPEED_FULL:
-				info("running at FULL speed, will use pid parsing.");
-				break;
-			case USB_SPEED_HIGH:
-				if (!pid_parse) {
-					dib->pid_parse = 0;
-				info("running at HIGH speed, will deliver the complete TS.");
-				} else
-					info("running at HIGH speed, will use pid_parsing anyway.");
-				break;
-			case USB_SPEED_UNKNOWN: /* fall through */
-			default:
-				err("cannot handle USB speed because it is unkown.");
-				break;
-		}
-
-		dib->udev = udev;
-		dib->dibdev = dibdev;
-
-		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) {
-		name = dib->dibdev->name;
-		dibusb_dvb_exit(dib);
-		dibusb_exit(dib);
-		kfree(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		= "dvb_dibusb",
-	.probe 		= dibusb_probe,
-	.disconnect = dibusb_disconnect,
-	.id_table 	= dibusb_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 -Nru a/drivers/media/dvb/dibusb/dvb-dibusb.h b/drivers/media/dvb/dibusb/dvb-dibusb.h
--- a/drivers/media/dvb/dibusb/dvb-dibusb.h	2005-03-01 23:38:53 -08:00
+++ b/drivers/media/dvb/dibusb/dvb-dibusb.h	2005-03-01 23:38:53 -08:00
@@ -1,293 +1,165 @@
 /*
  * dvb-dibusb.h
  *
- * Copyright (C) 2004 Patrick Boettcher (patrick.boettcher@desy.de)
+ * 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.c .
+ * 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 "Driver for 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 */
+#define err(format, arg...) printk(KERN_ERR "%s: " format "\n" , __FILE__ , ## arg)
+#define info(format, arg...) printk(KERN_INFO "%s: " format "\n" , __FILE__ , ## arg)
+#define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n" , __FILE__ , ## 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,
-	DIBUSB2_0,
 	DIBUSB1_1_AN2235,
-} dibusb_type;
+	DIBUSB2_0,
+	UMT2_0,
+} dibusb_class_t;
 
-static const char * dibusb_fw_filenames1_1[] = {
-	"dvb-dibusb-5.0.0.11.fw"
-};
+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;
 
-static const char * dibusb_fw_filenames1_1_an2235[] = {
-	"dvb-dibusb-an2235-1.fw"
-};
+typedef enum {
+	DIBUSB_DIB3000MB = 0,
+	DIBUSB_DIB3000MC,
+	DIBUSB_MT352,
+} dibusb_demodulator_t;
 
-static const char * dibusb_fw_filenames2_0[] = {
-	"dvb-dibusb-6.0.0.5.fw"
-};
+typedef enum {
+	DIBUSB_RC_NO = 0,
+	DIBUSB_RC_NEC_PROTOCOL = 1,
+} dibusb_remote_t;
 
-struct dibusb_device_parameter {
-	dibusb_type type;
-	u8 demod_addr;
-	const char **fw_filenames;
-	const char *usb_controller;
-	u16 usb_cpu_csreg;
-
-	int num_urbs;
-	int urb_buf_size;
-	int default_size;
-	int firmware_bug;
-
-	int cmd_pipe;
-	int result_pipe;
-	int data_pipe;
-};
+struct dibusb_tuner {
+	dibusb_tuner_t id;
 
-static struct dibusb_device_parameter dibusb_dev_parm[3] = {
-	{	.type = DIBUSB1_1,
-		.demod_addr = 0x10,
-		.fw_filenames = dibusb_fw_filenames1_1,
-		.usb_controller = "Cypress AN2135",
-		.usb_cpu_csreg = 0x7f92,
-
-		.num_urbs = 3,
-		.urb_buf_size = 4096,
-		.default_size = 188*21,
-		.firmware_bug = 1,
-
-		.cmd_pipe = 0x01,
-		.result_pipe = 0x81,
-		.data_pipe = 0x82,
-	},
-	{	.type = DIBUSB2_0,
-		.demod_addr = 0x18,
-		.fw_filenames = dibusb_fw_filenames2_0,
-		.usb_controller = "Cypress FX2",
-		.usb_cpu_csreg = 0xe600,
-
-		.num_urbs = 3,
-		.urb_buf_size = 40960,
-		.default_size = 188*210,
-		.firmware_bug = 0,
-
-		.cmd_pipe = 0x01,
-		.result_pipe = 0x81,
-		.data_pipe = 0x86,
-	},
-	{	.type = DIBUSB1_1_AN2235,
-		.demod_addr = 0x10,
-		.fw_filenames = dibusb_fw_filenames1_1_an2235,
-		.usb_controller = "Cypress CY7C64613 (AN2235)",
-		.usb_cpu_csreg = 0x7f92,
-
-		.num_urbs = 3,
-		.urb_buf_size = 4096,
-		.default_size = 188*21,
-		.firmware_bug = 1,
-
-		.cmd_pipe = 0x01,
-		.result_pipe = 0x81,
-		.data_pipe = 0x82,
-	}
+	u8 pll_addr;       /* tuner i2c address */
 };
+extern struct dibusb_tuner dibusb_tuner[];
 
-struct dibusb_device {
-	const char *name;
-	u16 cold_product_id;
-	u16 warm_product_id;
-	struct dibusb_device_parameter *parm;
-};
+#define DIBUSB_POSSIBLE_I2C_ADDR_NUM 4
+struct dibusb_demod {
+	dibusb_demodulator_t id;
 
-/* Vendor IDs */
-#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_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_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_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_YAKUMO_DTT200U_COLD			0x0201
-#define USB_PID_YAKUMO_DTT200U_WARM			0x0301
-
-#define DIBUSB_SUPPORTED_DEVICES	15
-
-/* USB Driver stuff */
-static struct dibusb_device dibusb_devices[DIBUSB_SUPPORTED_DEVICES] = {
-	{	.name = "TwinhanDTV USB1.1 / Magic Box / HAMA USB1.1 DVB-T device",
-		.cold_product_id = USB_PID_TWINHAN_VP7041_COLD,
-		.warm_product_id = USB_PID_TWINHAN_VP7041_WARM,
-		.parm = &dibusb_dev_parm[0],
-	},
-	{	.name = "KWorld V-Stream XPERT DTV - DVB-T USB1.1",
-		.cold_product_id = USB_PID_KWORLD_VSTREAM_COLD,
-		.warm_product_id = USB_PID_KWORLD_VSTREAM_WARM,
-		.parm = &dibusb_dev_parm[0],
-	},
-	{	.name = "Grandtec USB1.1 DVB-T/DiBcom USB1.1 DVB-T reference design (MOD3000)",
-		.cold_product_id = USB_PID_DIBCOM_MOD3000_COLD,
-		.warm_product_id = USB_PID_DIBCOM_MOD3000_WARM,
-		.parm = &dibusb_dev_parm[0],
-	},
-	{	.name = "Artec T1 USB1.1 TVBOX with AN2135",
-		.cold_product_id = USB_PID_ULTIMA_TVBOX_COLD,
-		.warm_product_id = USB_PID_ULTIMA_TVBOX_WARM,
-		.parm = &dibusb_dev_parm[0],
-	},
-	{	.name = "Artec T1 USB1.1 TVBOX with AN2235",
-		.cold_product_id = USB_PID_ULTIMA_TVBOX_AN2235_COLD,
-		.warm_product_id = USB_PID_ULTIMA_TVBOX_AN2235_WARM,
-		.parm = &dibusb_dev_parm[2],
-	},
-	{	.name = "Artec T1 USB1.1 TVBOX with AN2235 (misdesigned)",
-		.cold_product_id = USB_PID_ULTIMA_TVBOX_ANCHOR_COLD,
-		.warm_product_id = 0, /* undefined, this design becomes USB_PID_DIBCOM_MOD3000_WARM in warm state */
-		.parm = &dibusb_dev_parm[2],
-	},
-	{	.name = "Artec T1 USB2.0 TVBOX (please report the warm ID)",
-		.cold_product_id = USB_PID_ULTIMA_TVBOX_USB2_COLD,
-		.warm_product_id = 0, /* don't know, it is most likely that the device will get another USB ID in warm state */
-		.parm = &dibusb_dev_parm[1],
-	},
-	{	.name = "Artec T1 USB2.0 TVBOX with FX2 IDs (misdesigned, please report the warm ID)",
-		.cold_product_id = USB_PID_ULTIMA_TVBOX_USB2_FX_COLD,
-		.warm_product_id = USB_PID_ULTIMA_TVBOX_USB2_FX_WARM, /* undefined, it could be that the device will get another USB ID in warm state */
-		.parm = &dibusb_dev_parm[1],
-	},
-	{	.name = "Compro Videomate DVB-U2000 - DVB-T USB1.1",
-		.cold_product_id = USB_PID_COMPRO_DVBU2000_COLD,
-		.warm_product_id = USB_PID_COMPRO_DVBU2000_WARM,
-		.parm = &dibusb_dev_parm[0],
-	},
-	{	.name = "Compro Videomate DVB-U2000 - DVB-T USB1.1 (really ?? please report the name!)",
-		.cold_product_id = USB_PID_COMPRO_DVBU2000_UNK_COLD,
-		.warm_product_id = USB_PID_COMPRO_DVBU2000_UNK_WARM,
-		.parm = &dibusb_dev_parm[0],
-	},
-	{	.name = "Unkown USB1.1 DVB-T device ???? please report the name to the author",
-		.cold_product_id = USB_PID_UNK_HYPER_PALTEK_COLD,
-		.warm_product_id = USB_PID_UNK_HYPER_PALTEK_WARM,
-		.parm = &dibusb_dev_parm[0],
-	},
-	{	.name = "DiBcom USB2.0 DVB-T reference design (MOD3000P)",
-		.cold_product_id = USB_PID_DIBCOM_MOD3001_COLD,
-		.warm_product_id = USB_PID_DIBCOM_MOD3001_WARM,
-		.parm = &dibusb_dev_parm[1],
-	},
-	{	.name = "Grandtec DVB-T USB1.1",
-		.cold_product_id = USB_PID_GRANDTEC_DVBT_USB_COLD,
-		.warm_product_id = USB_PID_GRANDTEC_DVBT_USB_WARM,
-		.parm = &dibusb_dev_parm[0],
-	},
-	{	.name = "Avermedia AverTV DVBT USB1.1",
-		.cold_product_id = USB_PID_AVERMEDIA_DVBT_USB_COLD,
-		.warm_product_id = USB_PID_AVERMEDIA_DVBT_USB_WARM,
-		.parm = &dibusb_dev_parm[0],
-	},
-	{	.name = "Yakumo DVB-T mobile USB2.0",
-		.cold_product_id = USB_PID_YAKUMO_DTT200U_COLD,
-		.warm_product_id = USB_PID_YAKUMO_DTT200U_WARM,
-		.parm = &dibusb_dev_parm[1],
-	}
+	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 */
 };
 
-/* USB Driver stuff */
-/* table of devices that work with this driver */
-static struct usb_device_id dibusb_table [] = {
-	{ USB_DEVICE(USB_VID_AVERMEDIA,		USB_PID_AVERMEDIA_DVBT_USB_COLD)},
-	{ USB_DEVICE(USB_VID_AVERMEDIA,		USB_PID_AVERMEDIA_DVBT_USB_WARM)},
-	{ USB_DEVICE(USB_VID_COMPRO,		USB_PID_COMPRO_DVBU2000_COLD) },
-	{ USB_DEVICE(USB_VID_COMPRO,		USB_PID_COMPRO_DVBU2000_WARM) },
-	{ USB_DEVICE(USB_VID_DIBCOM,		USB_PID_DIBCOM_MOD3000_COLD) },
-	{ USB_DEVICE(USB_VID_DIBCOM,		USB_PID_DIBCOM_MOD3000_WARM) },
-	{ USB_DEVICE(USB_VID_DIBCOM,		USB_PID_DIBCOM_MOD3001_COLD) },
-	{ USB_DEVICE(USB_VID_DIBCOM,		USB_PID_DIBCOM_MOD3001_WARM) },
-	{ USB_DEVICE(USB_VID_EMPIA,			USB_PID_KWORLD_VSTREAM_COLD) },
-	{ USB_DEVICE(USB_VID_EMPIA,			USB_PID_KWORLD_VSTREAM_WARM) },
-	{ USB_DEVICE(USB_VID_GRANDTEC,		USB_PID_GRANDTEC_DVBT_USB_COLD) },
-	{ USB_DEVICE(USB_VID_GRANDTEC,		USB_PID_GRANDTEC_DVBT_USB_WARM) },
-	{ USB_DEVICE(USB_VID_GRANDTEC,		USB_PID_DIBCOM_MOD3000_COLD) },
-	{ USB_DEVICE(USB_VID_GRANDTEC,		USB_PID_DIBCOM_MOD3000_WARM) },
-	{ USB_DEVICE(USB_VID_HYPER_PALTEK,	USB_PID_UNK_HYPER_PALTEK_COLD) },
-	{ USB_DEVICE(USB_VID_HYPER_PALTEK,	USB_PID_UNK_HYPER_PALTEK_WARM) },
-	{ USB_DEVICE(USB_VID_IMC_NETWORKS,	USB_PID_TWINHAN_VP7041_COLD) },
-	{ USB_DEVICE(USB_VID_IMC_NETWORKS,	USB_PID_TWINHAN_VP7041_WARM) },
-	{ USB_DEVICE(USB_VID_TWINHAN, 		USB_PID_TWINHAN_VP7041_COLD) },
-	{ USB_DEVICE(USB_VID_TWINHAN, 		USB_PID_TWINHAN_VP7041_WARM) },
-	{ USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_COLD) },
-	{ USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_WARM) },
-	{ USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_COLD) },
-	{ USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_WARM) },
-	{ USB_DEVICE(USB_VID_AVERMEDIA,		USB_PID_YAKUMO_DTT200U_COLD) },
-	{ USB_DEVICE(USB_VID_AVERMEDIA,		USB_PID_YAKUMO_DTT200U_WARM) },
-	{ USB_DEVICE(USB_PID_COMPRO_DVBU2000_UNK_COLD, USB_VID_COMPRO_UNK) },
-	{ USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC,	USB_PID_ULTIMA_TVBOX_USB2_COLD) },
+#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 */
 
-/*
- * 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
-	{ USB_DEVICE(USB_VID_ANCHOR,		USB_PID_ULTIMA_TVBOX_ANCHOR_COLD) },
-	{ USB_DEVICE(USB_VID_CYPRESS,		USB_PID_ULTIMA_TVBOX_USB2_FX_COLD) },
-	{ USB_DEVICE(USB_VID_ANCHOR,		USB_PID_ULTIMA_TVBOX_USB2_FX_WARM) },
-#endif
-	{ }                 /* Terminating entry */
+	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 */
 };
 
-MODULE_DEVICE_TABLE (usb, dibusb_table);
+#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 */
+};
 
-#define DIBUSB_I2C_TIMEOUT 				HZ*5
+/* 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_device * dibdev;
+	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_SUBMIT 0x004 
+#define DIBUSB_STATE_DVB        0x008
+#define DIBUSB_STATE_I2C        0x010
+#define DIBUSB_STATE_REMOTE		0x020
+#define DIBUSB_STATE_PIDLIST    0x040
+	int init_state;
 
 	int feedcount;
-	int pid_parse;
-	struct dib3000_xfer_ops xfer_ops;
+	struct dib_fe_xfer_ops xfer_ops;
+
+	struct dibusb_tuner *tuner;
 
 	struct urb **urb_list;
 	u8 *buffer;
@@ -295,49 +167,141 @@
 
 	/* I2C */
 	struct i2c_adapter i2c_adap;
-	struct i2c_client i2c_client;
 
 	/* locking */
 	struct semaphore usb_sem;
 	struct semaphore i2c_sem;
 
+	/* pid filtering */
+	spinlock_t pid_list_lock;
+	struct dibusb_pid *pid_list;
+	
 	/* dvb */
-	int dvb_is_ready;
 	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 rc_input_event;
+
+	/* module parameters */
+	int pid_parse;
+	int rc_query_interval;
 };
 
+/* commonly used functions in the separated files */
 
-/* types of first byte of each buffer */
+/* 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_i2c_msg(struct usb_dibusb *dib, u8 addr, 
+		u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen);
+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_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-dibusb-pid.c */
+int dibusb_pid_list_init(struct usb_dibusb *dib);
+void dibusb_pid_list_exit(struct usb_dibusb *dib);
+int dibusb_ctrl_pid(struct usb_dibusb *dib, struct dvb_demux_feed *dvbdmxfeed , int onoff);
+
+/* i2c and transfer stuff */
+#define DIBUSB_I2C_TIMEOUT				HZ*5
+
+/* 
+ * 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
 
-/* prefix for reading the current RC key */
+/* 
+ * 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
 
-/* 0x05 0xXX */
+/* 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 1 byte> <param 32 bytes>
+/* 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
 
@@ -347,5 +311,9 @@
 #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 -Nru a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c
--- a/drivers/media/dvb/dvb-core/dvb_demux.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/media/dvb/dvb-core/dvb_demux.c	2005-03-01 23:38:53 -08:00
@@ -247,7 +247,22 @@
 		}
 
 /* 
-** Losless Section Demux 1.4 by Emard
+** Losless Section Demux 1.4.1 by Emard
+** Valsecchi Patrick:
+**  - middle of section A  (no PUSI)
+**  - end of section A and start of section B 
+**    (with PUSI pointing to the start of the second section)
+**  
+**  In this case, without feed->pusi_seen you'll receive a garbage section
+**  consisting of the end of section A. Basically because tsfeedp
+**  is incemented and the use=0 condition is not raised
+**  when the second packet arrives.
+**
+** Fix:
+** when demux is started, let feed->pusi_seen = 0 to
+** prevent initial feeding of garbage from the end of
+** previous section. When you for the first time see PUSI=1
+** then set feed->pusi_seen = 1
 */
 static int dvb_dmx_swfilter_section_copy_dump(struct dvb_demux_feed *feed, const u8 *buf, u8 len)
 {
@@ -293,7 +308,12 @@
 		sec->seclen = seclen;
 		sec->crc_val = ~0;
 		/* dump [secbuf .. secbuf+seclen) */
+		if(feed->pusi_seen)
 		dvb_dmx_swfilter_section_feed(feed);
+#ifdef DVB_DEMUX_SECTION_LOSS_LOG
+		else
+			printk("dvb_demux.c pusi not seen, discarding section data\n");
+#endif
 		sec->secbufp += seclen; /* secbufp and secbuf moving together is */
 		sec->secbuf += seclen; /* redundand but saves pointer arithmetic */
 		}
@@ -305,7 +325,7 @@
 static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed, const u8 *buf) 
 {
 	u8 p, count;
-	int ccok;
+	int ccok, dc_i = 0;
 	u8 cc;
 
 	count = payload(buf);
@@ -316,31 +336,41 @@
 	p = 188-count; /* payload start */
 
 	cc = buf[3] & 0x0f;
-	ccok = ((feed->cc+1) & 0x0f) == cc ? 1 : 0;
+	ccok = ((feed->cc + 1) & 0x0f) == cc;
 	feed->cc = cc;
-	if(ccok == 0)
-	{
+
+	if (buf[3] & 0x20) {
+		/* adaption field present, check for discontinuity_indicator */
+		if ((buf[4] > 0) && (buf[5] & 0x80))
+			dc_i = 1;
+	}
+
+	if (!ccok || dc_i) {
 #ifdef DVB_DEMUX_SECTION_LOSS_LOG
 		printk("dvb_demux.c discontinuity detected %d bytes lost\n", count);
 		/* those bytes under sume circumstances will again be reported
 		** in the following dvb_dmx_swfilter_section_new
 		*/
 #endif
+		/* Discontinuity detected. Reset pusi_seen = 0 to
+		** stop feeding of suspicious data until next PUSI=1 arrives
+		*/
+		feed->pusi_seen = 0;
 		dvb_dmx_swfilter_section_new(feed);
 		return 0;
 	}
 
-	if(buf[1] & 0x40)
-	{
+	if (buf[1] & 0x40) {
 		// PUSI=1 (is set), section boundary is here
-		if(count > 1 && buf[p] < count)
-		{
+		if (count > 1 && buf[p] < count) {
 			const u8 *before = buf+p+1;
 			u8 before_len = buf[p];
 			const u8 *after = before+before_len;
 			u8 after_len = count-1-before_len;
 
 			dvb_dmx_swfilter_section_copy_dump(feed, before, before_len);
+			/* before start of new section, set pusi_seen = 1 */
+			feed->pusi_seen = 1;
 			dvb_dmx_swfilter_section_new(feed);
 			dvb_dmx_swfilter_section_copy_dump(feed, after, after_len);
 		}
@@ -349,9 +379,7 @@
 			if(count > 0)
 				printk("dvb_demux.c PUSI=1 but %d bytes lost\n", count);
 #endif
-	}
-	else
-	{
+	} else {
 		// PUSI=0 (is not set), no section boundary
 		const u8 *entire = buf+p;
 		u8 entire_len = count;
@@ -784,10 +812,8 @@
 	}
 
 #ifndef NOBUFS
-	if (feed->buffer) { 
 		vfree(feed->buffer);
 		feed->buffer=0;
-	}
 #endif
 
 	feed->state = DMX_STATE_FREE;
@@ -1055,10 +1081,8 @@
 		return -EINVAL;
 	}
 #ifndef NOBUFS
-	if (dvbdmxfeed->buffer) {
 		vfree(dvbdmxfeed->buffer);
 		dvbdmxfeed->buffer=0;
-	}
 #endif
 	dvbdmxfeed->state=DMX_STATE_FREE;
 
@@ -1269,9 +1293,7 @@
 	struct dmx_demux *dmx = &dvbdemux->dmx;
 
 	dmx_unregister_demux(dmx);
-	if (dvbdemux->filter)
 		vfree(dvbdemux->filter);
-	if (dvbdemux->feed)
 		vfree(dvbdemux->feed);
 	return 0;
 }
diff -Nru a/drivers/media/dvb/dvb-core/dvb_demux.h b/drivers/media/dvb/dvb-core/dvb_demux.h
--- a/drivers/media/dvb/dvb-core/dvb_demux.h	2005-03-01 23:39:18 -08:00
+++ b/drivers/media/dvb/dvb-core/dvb_demux.h	2005-03-01 23:39:18 -08:00
@@ -93,6 +93,7 @@
         enum dmx_ts_pes pes_type;
 
         int cc;
+        int pusi_seen; /* prevents feeding of garbage from previous section */
 
         u16 peslen;
 
diff -Nru 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	2005-03-01 23:38:53 -08:00
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c	2005-03-01 23:38:53 -08:00
@@ -89,9 +89,36 @@
 
 static DECLARE_MUTEX(frontend_mutex);
 
+struct dvb_frontend_private {
+
+	struct dvb_device *dvbdev;
+	struct dvb_frontend_parameters parameters;
+	struct dvb_fe_events events;
+	struct semaphore sem;
+	struct list_head list_head;
+	wait_queue_head_t wait_queue;
+	pid_t thread_pid;
+	unsigned long release_jiffies;
+	int state;
+	int bending;
+	int lnb_drift;
+	int inversion;
+	int auto_step;
+	int auto_sub_step;
+	int started_auto_step;
+	int min_delay;
+	int max_drift;
+	int step_size;
+	int exit;
+	int wakeup;
+	fe_status_t status;
+};
+
+
 static void dvb_frontend_add_event(struct dvb_frontend *fe, fe_status_t status)
 {
-	struct dvb_fe_events *events = &fe->events;
+	struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv;
+	struct dvb_fe_events *events = &fepriv->events;
 	struct dvb_frontend_event *e;
 	int wp;
 
@@ -109,7 +136,7 @@
 
 	e = &events->events[events->eventw];
 
-	memcpy (&e->parameters, &fe->parameters, 
+	memcpy (&e->parameters, &fepriv->parameters,
 		sizeof (struct dvb_frontend_parameters));
 
 	if (status & FE_HAS_LOCK)
@@ -128,7 +155,8 @@
 static int dvb_frontend_get_event(struct dvb_frontend *fe,
 			    struct dvb_frontend_event *event, int flags)
 {
-        struct dvb_fe_events *events = &fe->events;
+	struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv;
+	struct dvb_fe_events *events = &fepriv->events;
 
 	dprintk ("%s\n", __FUNCTION__);
 
@@ -143,12 +171,12 @@
                 if (flags & O_NONBLOCK)
                         return -EWOULDBLOCK;
 
-		up(&fe->sem);
+		up(&fepriv->sem);
 
                 ret = wait_event_interruptible (events->wait_queue,
                                                 events->eventw != events->eventr);
 
-        	if (down_interruptible (&fe->sem))
+		if (down_interruptible (&fepriv->sem))
 			return -ERESTARTSYS;
 
                 if (ret < 0)
@@ -206,27 +234,28 @@
 {
 	int autoinversion;
 	int ready = 0;
-	int original_inversion = fe->parameters.inversion;
-	u32 original_frequency = fe->parameters.frequency;
+	struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv;
+	int original_inversion = fepriv->parameters.inversion;
+	u32 original_frequency = fepriv->parameters.frequency;
 
 	/* are we using autoinversion? */
 	autoinversion = ((!(fe->ops->info.caps & FE_CAN_INVERSION_AUTO)) &&
-			 (fe->parameters.inversion == INVERSION_AUTO));
+			 (fepriv->parameters.inversion == INVERSION_AUTO));
 
 	/* setup parameters correctly */
 	while(!ready) {
 		/* calculate the lnb_drift */
-		fe->lnb_drift = fe->auto_step * fe->step_size;
+		fepriv->lnb_drift = fepriv->auto_step * fepriv->step_size;
 
 		/* wrap the auto_step if we've exceeded the maximum drift */
-		if (fe->lnb_drift > fe->max_drift) {
-			fe->auto_step = 0;
-			fe->auto_sub_step = 0;
-			fe->lnb_drift = 0;
+		if (fepriv->lnb_drift > fepriv->max_drift) {
+			fepriv->auto_step = 0;
+			fepriv->auto_sub_step = 0;
+			fepriv->lnb_drift = 0;
 		}
 
 		/* perform inversion and +/- zigzag */
-		switch(fe->auto_sub_step) {
+		switch(fepriv->auto_sub_step) {
 		case 0:
 			/* try with the current inversion and current drift setting */
 			ready = 1;
@@ -235,68 +264,70 @@
 		case 1:
 			if (!autoinversion) break;
 
-			fe->inversion = (fe->inversion == INVERSION_OFF) ? INVERSION_ON : INVERSION_OFF;
+			fepriv->inversion = (fepriv->inversion == INVERSION_OFF) ? INVERSION_ON : INVERSION_OFF;
 			ready = 1;
 			break;
 
 		case 2:
-			if (fe->lnb_drift == 0) break;
+			if (fepriv->lnb_drift == 0) break;
 		    
-			fe->lnb_drift = -fe->lnb_drift;
+			fepriv->lnb_drift = -fepriv->lnb_drift;
 			ready = 1;
 			break;
 	    
 		case 3:
-			if (fe->lnb_drift == 0) break;
+			if (fepriv->lnb_drift == 0) break;
 			if (!autoinversion) break;
 		    
-			fe->inversion = (fe->inversion == INVERSION_OFF) ? INVERSION_ON : INVERSION_OFF;
-			fe->lnb_drift = -fe->lnb_drift;
+			fepriv->inversion = (fepriv->inversion == INVERSION_OFF) ? INVERSION_ON : INVERSION_OFF;
+			fepriv->lnb_drift = -fepriv->lnb_drift;
 			ready = 1;
 			break;
 		    
 		default:
-			fe->auto_step++;
-			fe->auto_sub_step = -1; /* it'll be incremented to 0 in a moment */
+			fepriv->auto_step++;
+			fepriv->auto_sub_step = -1; /* it'll be incremented to 0 in a moment */
 			break;
 		}
 	    
-		if (!ready) fe->auto_sub_step++;
+		if (!ready) fepriv->auto_sub_step++;
 	}
 
 	/* if this attempt would hit where we started, indicate a complete
 	 * iteration has occurred */
-	if ((fe->auto_step == fe->started_auto_step) &&
-	    (fe->auto_sub_step == 0) && check_wrapped) {
+	if ((fepriv->auto_step == fepriv->started_auto_step) &&
+	    (fepriv->auto_sub_step == 0) && check_wrapped) {
 		return 1;
 		}
 
 	dprintk("%s: drift:%i inversion:%i auto_step:%i "
 		"auto_sub_step:%i started_auto_step:%i\n",
-		__FUNCTION__, fe->lnb_drift, fe->inversion,
-		fe->auto_step, fe->auto_sub_step, fe->started_auto_step);
+		__FUNCTION__, fepriv->lnb_drift, fepriv->inversion,
+		fepriv->auto_step, fepriv->auto_sub_step, fepriv->started_auto_step);
     
 	/* set the frontend itself */
-	fe->parameters.frequency += fe->lnb_drift;
+	fepriv->parameters.frequency += fepriv->lnb_drift;
 	if (autoinversion)
-		fe->parameters.inversion = fe->inversion;
+		fepriv->parameters.inversion = fepriv->inversion;
 	if (fe->ops->set_frontend)
-		fe->ops->set_frontend(fe, &fe->parameters);
+		fe->ops->set_frontend(fe, &fepriv->parameters);
 
-	fe->parameters.frequency = original_frequency;
-	fe->parameters.inversion = original_inversion;
+	fepriv->parameters.frequency = original_frequency;
+	fepriv->parameters.inversion = original_inversion;
 
-	fe->auto_sub_step++;
+	fepriv->auto_sub_step++;
 	return 0;
 }
 
 static int dvb_frontend_is_exiting(struct dvb_frontend *fe)
 {
-	if (fe->exit)
+	struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv;
+
+	if (fepriv->exit)
 		return 1;
 
-	if (fe->dvbdev->writers == 1)
-		if (jiffies - fe->release_jiffies > dvb_shutdown_timeout * HZ)
+	if (fepriv->dvbdev->writers == 1)
+		if (jiffies - fepriv->release_jiffies > dvb_shutdown_timeout * HZ)
 			return 1;
 
 	return 0;
@@ -304,8 +335,10 @@
 
 static int dvb_frontend_should_wakeup(struct dvb_frontend *fe)
 {
-	if (fe->wakeup) {
-		fe->wakeup = 0;
+	struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv;
+
+	if (fepriv->wakeup) {
+		fepriv->wakeup = 0;
 		return 1;
 	}
 	return dvb_frontend_is_exiting(fe);
@@ -313,8 +346,10 @@
 
 static void dvb_frontend_wakeup(struct dvb_frontend *fe)
 {
-	fe->wakeup = 1;
-	wake_up_interruptible(&fe->wait_queue);
+	struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv;
+
+	fepriv->wakeup = 1;
+	wake_up_interruptible(&fepriv->wait_queue);
 }
 
 /*
@@ -323,6 +358,7 @@
 static int dvb_frontend_thread (void *data)
 {
 	struct dvb_frontend *fe = (struct dvb_frontend *) data;
+	struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv;
 	unsigned long timeout;
 	char name [15];
 	int quality = 0, delay = 3*HZ;
@@ -338,14 +374,14 @@
         sigfillset (&current->blocked);
         unlock_kernel ();
 
-	fe->status = 0;
+	fepriv->status = 0;
 	dvb_frontend_init (fe);
-	fe->wakeup = 0;
+	fepriv->wakeup = 0;
 
 	while (1) {
-		up (&fe->sem);      /* is locked when we enter the thread... */
+		up(&fepriv->sem);	    /* is locked when we enter the thread... */
 
-		timeout = wait_event_interruptible_timeout(fe->wait_queue,
+		timeout = wait_event_interruptible_timeout(fepriv->wait_queue,
 							   dvb_frontend_should_wakeup(fe),
 							   delay);
 		if (0 != dvb_frontend_is_exiting (fe)) {
@@ -356,44 +392,43 @@
 		if (current->flags & PF_FREEZE)
 			refrigerator(PF_FREEZE);
 
-		if (down_interruptible (&fe->sem))
+		if (down_interruptible(&fepriv->sem))
 			break;
 
 		/* if we've got no parameters, just keep idling */
-		if (fe->state & FESTATE_IDLE) {
+		if (fepriv->state & FESTATE_IDLE) {
 			delay = 3*HZ;
 			quality = 0;
 			continue;
 		}
 
-retune:
 		/* get the frontend status */
-		if (fe->state & FESTATE_RETUNE) {
+		if (fepriv->state & FESTATE_RETUNE) {
 			s = 0;
 		} else {
 			if (fe->ops->read_status)
 				fe->ops->read_status(fe, &s);
-			if (s != fe->status) {
+			if (s != fepriv->status) {
 			dvb_frontend_add_event (fe, s);
-				fe->status = s;
+				fepriv->status = s;
 			}
 		}
 		/* if we're not tuned, and we have a lock, move to the TUNED state */
-		if ((fe->state & FESTATE_WAITFORLOCK) && (s & FE_HAS_LOCK)) {
-			update_delay(&quality, &delay, fe->min_delay, s & FE_HAS_LOCK);
-			fe->state = FESTATE_TUNED;
+		if ((fepriv->state & FESTATE_WAITFORLOCK) && (s & FE_HAS_LOCK)) {
+			update_delay(&quality, &delay, fepriv->min_delay, s & FE_HAS_LOCK);
+			fepriv->state = FESTATE_TUNED;
 
 			/* if we're tuned, then we have determined the correct inversion */
 			if ((!(fe->ops->info.caps & FE_CAN_INVERSION_AUTO)) &&
-			    (fe->parameters.inversion == INVERSION_AUTO)) {
-				fe->parameters.inversion = fe->inversion;
+			    (fepriv->parameters.inversion == INVERSION_AUTO)) {
+				fepriv->parameters.inversion = fepriv->inversion;
 			}
 			continue;
 		}
 
 		/* if we are tuned already, check we're still locked */
-		if (fe->state & FESTATE_TUNED) {
-			update_delay(&quality, &delay, fe->min_delay, s & FE_HAS_LOCK);
+		if (fepriv->state & FESTATE_TUNED) {
+			update_delay(&quality, &delay, fepriv->min_delay, s & FE_HAS_LOCK);
 
 			/* we're tuned, and the lock is still good... */
 			if (s & FE_HAS_LOCK)
@@ -401,49 +436,49 @@
 			else {
 				/* if we _WERE_ tuned, but now don't have a lock,
 				 * need to zigzag */
-				fe->state = FESTATE_ZIGZAG_FAST;
-				fe->started_auto_step = fe->auto_step;
+				fepriv->state = FESTATE_ZIGZAG_FAST;
+				fepriv->started_auto_step = fepriv->auto_step;
 				check_wrapped = 0;
 			}
 		}
 
 		/* don't actually do anything if we're in the LOSTLOCK state,
 		 * the frontend is set to FE_CAN_RECOVER, and the max_drift is 0 */
-		if ((fe->state & FESTATE_LOSTLOCK) && 
-		    (fe->ops->info.caps & FE_CAN_RECOVER) && (fe->max_drift == 0)) {
-			update_delay(&quality, &delay, fe->min_delay, s & FE_HAS_LOCK);
+		if ((fepriv->state & FESTATE_LOSTLOCK) &&
+		    (fe->ops->info.caps & FE_CAN_RECOVER) && (fepriv->max_drift == 0)) {
+			update_delay(&quality, &delay, fepriv->min_delay, s & FE_HAS_LOCK);
 						continue;
 				}
 	    
 		/* don't do anything if we're in the DISEQC state, since this
 		 * might be someone with a motorized dish controlled by DISEQC.
 		 * If its actually a re-tune, there will be a SET_FRONTEND soon enough.	*/
-		if (fe->state & FESTATE_DISEQC) {
-			update_delay(&quality, &delay, fe->min_delay, s & FE_HAS_LOCK);
+		if (fepriv->state & FESTATE_DISEQC) {
+			update_delay(&quality, &delay, fepriv->min_delay, s & FE_HAS_LOCK);
 			continue;
 				}
 
 		/* if we're in the RETUNE state, set everything up for a brand
 		 * new scan, keeping the current inversion setting, as the next
 		 * tune is _very_ likely to require the same */
-		if (fe->state & FESTATE_RETUNE) {
-			fe->lnb_drift = 0;
-			fe->auto_step = 0;
-			fe->auto_sub_step = 0;
-			fe->started_auto_step = 0;
+		if (fepriv->state & FESTATE_RETUNE) {
+			fepriv->lnb_drift = 0;
+			fepriv->auto_step = 0;
+			fepriv->auto_sub_step = 0;
+			fepriv->started_auto_step = 0;
 			check_wrapped = 0;
 		}
 
 		/* fast zigzag. */
-		if ((fe->state & FESTATE_SEARCHING_FAST) || (fe->state & FESTATE_RETUNE)) {
-			delay = fe->min_delay;
+		if ((fepriv->state & FESTATE_SEARCHING_FAST) || (fepriv->state & FESTATE_RETUNE)) {
+			delay = fepriv->min_delay;
 
 			/* peform a tune */
 			if (dvb_frontend_autotune(fe, check_wrapped)) {
 				/* OK, if we've run out of trials at the fast speed.
 				 * Drop back to slow for the _next_ attempt */
-				fe->state = FESTATE_SEARCHING_SLOW;
-				fe->started_auto_step = fe->auto_step;
+				fepriv->state = FESTATE_SEARCHING_SLOW;
+				fepriv->started_auto_step = fepriv->auto_step;
 				continue;
 			}
 			check_wrapped = 1;
@@ -452,15 +487,14 @@
 			 * This ensures we cannot return from an
 			 * FE_SET_FRONTEND ioctl before the first frontend tune
 			 * occurs */
-			if (fe->state & FESTATE_RETUNE) {
-				fe->state = FESTATE_TUNING_FAST;
-				goto retune;
+			if (fepriv->state & FESTATE_RETUNE) {
+				fepriv->state = FESTATE_TUNING_FAST;
 			}
 		}
 
 		/* slow zigzag */
-		if (fe->state & FESTATE_SEARCHING_SLOW) {
-			update_delay(&quality, &delay, fe->min_delay, s & FE_HAS_LOCK);
+		if (fepriv->state & FESTATE_SEARCHING_SLOW) {
+			update_delay(&quality, &delay, fepriv->min_delay, s & FE_HAS_LOCK);
 		    
 			/* Note: don't bother checking for wrapping; we stay in this
 			 * state until we get a lock */
@@ -476,7 +510,7 @@
 			fe->ops->sleep(fe);
 	}
 
-	fe->thread_pid = 0;
+	fepriv->thread_pid = 0;
 	mb();
 
 	dvb_frontend_wakeup(fe);
@@ -486,21 +520,22 @@
 static void dvb_frontend_stop(struct dvb_frontend *fe)
 {
 	unsigned long ret;
+	struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv;
 
 	dprintk ("%s\n", __FUNCTION__);
 
-		fe->exit = 1;
+	fepriv->exit = 1;
 	mb();
 
-	if (!fe->thread_pid)
+	if (!fepriv->thread_pid)
 		return;
 
 	/* check if the thread is really alive */
-	if (kill_proc(fe->thread_pid, 0, 1) == -ESRCH) {
+	if (kill_proc(fepriv->thread_pid, 0, 1) == -ESRCH) {
 		printk("dvb_frontend_stop: thread PID %d already died\n",
-				fe->thread_pid);
+				fepriv->thread_pid);
 		/* make sure the mutex was not held by the thread */
-		init_MUTEX (&fe->sem);
+		init_MUTEX (&fepriv->sem);
 		return;
 	}
 
@@ -508,27 +543,28 @@
 	dvb_frontend_wakeup(fe);
 
 	/* wait until the frontend thread has exited */
-	ret = wait_event_interruptible(fe->wait_queue,0 == fe->thread_pid);
+	ret = wait_event_interruptible(fepriv->wait_queue,0 == fepriv->thread_pid);
 	if (-ERESTARTSYS != ret) {
-		fe->state = FESTATE_IDLE;
+		fepriv->state = FESTATE_IDLE;
 		return;
 	}
-	fe->state = FESTATE_IDLE;
+	fepriv->state = FESTATE_IDLE;
 
 	/* paranoia check in case a signal arrived */
-	if (fe->thread_pid)
+	if (fepriv->thread_pid)
 		printk("dvb_frontend_stop: warning: thread PID %d won't exit\n",
-				fe->thread_pid);
+				fepriv->thread_pid);
 }
 
 static int dvb_frontend_start(struct dvb_frontend *fe)
 {
 	int ret;
+	struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv;
 
 	dprintk ("%s\n", __FUNCTION__);
 
-	if (fe->thread_pid) {
-		if (!fe->exit)
+	if (fepriv->thread_pid) {
+		if (!fepriv->exit)
 			return 0;
 		else
 		dvb_frontend_stop (fe);
@@ -536,21 +572,22 @@
 
 	if (signal_pending(current))
 		return -EINTR;
-	if (down_interruptible (&fe->sem))
+	if (down_interruptible (&fepriv->sem))
 		return -EINTR;
 
-	fe->state = FESTATE_IDLE;
-	fe->exit = 0;
-	fe->thread_pid = 0;
+	fepriv->state = FESTATE_IDLE;
+	fepriv->exit = 0;
+	fepriv->thread_pid = 0;
 	mb();
 
 	ret = kernel_thread (dvb_frontend_thread, fe, 0);
+
 	if (ret < 0) {
 		printk("dvb_frontend_start: failed to start kernel_thread (%d)\n", ret);
-		up(&fe->sem);
+		up(&fepriv->sem);
 		return ret;
 	}
-	fe->thread_pid = ret;
+	fepriv->thread_pid = ret;
 
 	return 0;
 }
@@ -561,11 +598,12 @@
 {
 	struct dvb_device *dvbdev = file->private_data;
 	struct dvb_frontend *fe = dvbdev->priv;
+	struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv;
 	int err = -EOPNOTSUPP;
 
 	dprintk ("%s\n", __FUNCTION__);
 
-	if (!fe || fe->exit)
+	if (!fe || fepriv->exit)
 		return -ENODEV;
 
 	if ((file->f_flags & O_ACCMODE) == O_RDONLY &&
@@ -573,7 +611,7 @@
 	     cmd == FE_DISEQC_RECV_SLAVE_REPLY))
 		return -EPERM;
 
-	if (down_interruptible (&fe->sem))
+	if (down_interruptible (&fepriv->sem))
 		return -ERESTARTSYS;
 
 	switch (cmd) {
@@ -617,48 +655,48 @@
 	case FE_DISEQC_RESET_OVERLOAD:
 		if (fe->ops->diseqc_reset_overload) {
 			err = fe->ops->diseqc_reset_overload(fe);
-			fe->state = FESTATE_DISEQC;
-			fe->status = 0;
+			fepriv->state = FESTATE_DISEQC;
+			fepriv->status = 0;
 		}
 		break;
 
 	case FE_DISEQC_SEND_MASTER_CMD:
 		if (fe->ops->diseqc_send_master_cmd) {
 			err = fe->ops->diseqc_send_master_cmd(fe, (struct dvb_diseqc_master_cmd*) parg);
-			fe->state = FESTATE_DISEQC;
-			fe->status = 0;
+			fepriv->state = FESTATE_DISEQC;
+			fepriv->status = 0;
 		}
 		break;
 
 	case FE_DISEQC_SEND_BURST:
 		if (fe->ops->diseqc_send_burst) {
 			err = fe->ops->diseqc_send_burst(fe, (fe_sec_mini_cmd_t) parg);
-			fe->state = FESTATE_DISEQC;
-			fe->status = 0;
+			fepriv->state = FESTATE_DISEQC;
+			fepriv->status = 0;
 		}
 		break;
 
 	case FE_SET_TONE:
 		if (fe->ops->set_tone) {
 			err = fe->ops->set_tone(fe, (fe_sec_tone_mode_t) parg);
-			fe->state = FESTATE_DISEQC;
-			fe->status = 0;
+			fepriv->state = FESTATE_DISEQC;
+			fepriv->status = 0;
 		}
 		break;
 
 	case FE_SET_VOLTAGE:
 		if (fe->ops->set_voltage) {
 			err = fe->ops->set_voltage(fe, (fe_sec_voltage_t) parg);
-		fe->state = FESTATE_DISEQC;
-			fe->status = 0;
+			fepriv->state = FESTATE_DISEQC;
+			fepriv->status = 0;
 		}
 		break;
 
 	case FE_DISHNETWORK_SEND_LEGACY_CMD:
 		if (fe->ops->dishnetwork_send_legacy_command) {
 			err = fe->ops->dishnetwork_send_legacy_command(fe, (unsigned int) parg);
-			fe->state = FESTATE_DISEQC;
-			fe->status = 0;
+			fepriv->state = FESTATE_DISEQC;
+			fepriv->status = 0;
 		}
 		break;
 
@@ -668,14 +706,14 @@
 		break;
 
 	case FE_ENABLE_HIGH_LNB_VOLTAGE:
-		if (fe->ops->enable_high_lnb_voltage);
+		if (fe->ops->enable_high_lnb_voltage)
 			err = fe->ops->enable_high_lnb_voltage(fe, (int) parg);
 		break;
 
 	case FE_SET_FRONTEND: {
 		struct dvb_frontend_tune_settings fetunesettings;
 	    
-		memcpy (&fe->parameters, parg,
+		memcpy (&fepriv->parameters, parg,
 			sizeof (struct dvb_frontend_parameters));
 
 		memset(&fetunesettings, 0, sizeof(struct dvb_frontend_tune_settings));
@@ -684,41 +722,41 @@
 		    
 		/* force auto frequency inversion if requested */
 		if (dvb_force_auto_inversion) {
-			fe->parameters.inversion = INVERSION_AUTO;
+			fepriv->parameters.inversion = INVERSION_AUTO;
 			fetunesettings.parameters.inversion = INVERSION_AUTO;
 		}
 		if (fe->ops->info.type == FE_OFDM) {
 			/* without hierachical coding code_rate_LP is irrelevant,
 			 * so we tolerate the otherwise invalid FEC_NONE setting */
-			if (fe->parameters.u.ofdm.hierarchy_information == HIERARCHY_NONE &&
-			    fe->parameters.u.ofdm.code_rate_LP == FEC_NONE)
-				fe->parameters.u.ofdm.code_rate_LP = FEC_AUTO;
+			if (fepriv->parameters.u.ofdm.hierarchy_information == HIERARCHY_NONE &&
+			    fepriv->parameters.u.ofdm.code_rate_LP == FEC_NONE)
+				fepriv->parameters.u.ofdm.code_rate_LP = FEC_AUTO;
 		}
 
 		/* get frontend-specific tuning settings */
 		if (fe->ops->get_tune_settings && (fe->ops->get_tune_settings(fe, &fetunesettings) == 0)) {
-			fe->min_delay = (fetunesettings.min_delay_ms * HZ) / 1000;
-			fe->max_drift = fetunesettings.max_drift;
-			fe->step_size = fetunesettings.step_size;
+			fepriv->min_delay = (fetunesettings.min_delay_ms * HZ) / 1000;
+			fepriv->max_drift = fetunesettings.max_drift;
+			fepriv->step_size = fetunesettings.step_size;
 		} else {
 			/* default values */
 			switch(fe->ops->info.type) {
 			case FE_QPSK:
-				fe->min_delay = HZ/20;
-				fe->step_size = fe->parameters.u.qpsk.symbol_rate / 16000;
-				fe->max_drift = fe->parameters.u.qpsk.symbol_rate / 2000;
+				fepriv->min_delay = HZ/20;
+				fepriv->step_size = fepriv->parameters.u.qpsk.symbol_rate / 16000;
+				fepriv->max_drift = fepriv->parameters.u.qpsk.symbol_rate / 2000;
 		break;
 			    
 			case FE_QAM:
-				fe->min_delay = HZ/20;
-				fe->step_size = 0; /* no zigzag */
-				fe->max_drift = 0;
+				fepriv->min_delay = HZ/20;
+				fepriv->step_size = 0; /* no zigzag */
+				fepriv->max_drift = 0;
 				break;
 			    
 			case FE_OFDM:
-				fe->min_delay = HZ/20;
-				fe->step_size = fe->ops->info.frequency_stepsize * 2;
-				fe->max_drift = (fe->ops->info.frequency_stepsize * 2) + 1;
+				fepriv->min_delay = HZ/20;
+				fepriv->step_size = fe->ops->info.frequency_stepsize * 2;
+				fepriv->max_drift = (fe->ops->info.frequency_stepsize * 2) + 1;
 				break;
 			case FE_ATSC:
 				printk("dvb-core: FE_ATSC not handled yet.\n");
@@ -726,12 +764,12 @@
 			}
 		}
 		if (dvb_override_tune_delay > 0)
-		       fe->min_delay = (dvb_override_tune_delay * HZ) / 1000;
+			fepriv->min_delay = (dvb_override_tune_delay * HZ) / 1000;
 
-		fe->state = FESTATE_RETUNE;
+		fepriv->state = FESTATE_RETUNE;
 		dvb_frontend_wakeup(fe);
 		dvb_frontend_add_event (fe, 0);	    
-		fe->status = 0;
+		fepriv->status = 0;
 		err = 0;
 		break;
 	}
@@ -742,13 +780,13 @@
 
 	case FE_GET_FRONTEND:
 		if (fe->ops->get_frontend) {
-			memcpy (parg, &fe->parameters, sizeof (struct dvb_frontend_parameters));
+			memcpy (parg, &fepriv->parameters, sizeof (struct dvb_frontend_parameters));
 			err = fe->ops->get_frontend(fe, (struct dvb_frontend_parameters*) parg);
 		}
 		break;
 	};
 
-	up (&fe->sem);
+	up (&fepriv->sem);
 	return err;
 }
 
@@ -757,12 +795,13 @@
 {
 	struct dvb_device *dvbdev = file->private_data;
 	struct dvb_frontend *fe = dvbdev->priv;
+	struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv;
 
 	dprintk ("%s\n", __FUNCTION__);
 
-	poll_wait (file, &fe->events.wait_queue, wait);
+	poll_wait (file, &fepriv->events.wait_queue, wait);
 
-	if (fe->events.eventw != fe->events.eventr)
+	if (fepriv->events.eventw != fepriv->events.eventr)
 		return (POLLIN | POLLRDNORM | POLLPRI);
 
 	return 0;
@@ -773,6 +812,7 @@
 {
 	struct dvb_device *dvbdev = file->private_data;
 	struct dvb_frontend *fe = dvbdev->priv;
+	struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv;
 	int ret;
 
 	dprintk ("%s\n", __FUNCTION__);
@@ -786,7 +826,7 @@
 			dvb_generic_release (inode, file);
 
 		/*  empty event queue */
-		fe->events.eventr = fe->events.eventw = 0;
+		fepriv->events.eventr = fepriv->events.eventw = 0;
 	}
 	
 	return ret;
@@ -797,11 +837,12 @@
 {
 	struct dvb_device *dvbdev = file->private_data;
 	struct dvb_frontend *fe = dvbdev->priv;
+	struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv;
 
 	dprintk ("%s\n", __FUNCTION__);
 
 	if ((file->f_flags & O_ACCMODE) != O_RDONLY)
-		fe->release_jiffies = jiffies;
+		fepriv->release_jiffies = jiffies;
 
 	return dvb_generic_release (inode, file);
 }
@@ -818,6 +859,7 @@
 int dvb_register_frontend(struct dvb_adapter* dvb,
 			  struct dvb_frontend* fe)
 {
+	struct dvb_frontend_private *fepriv;
 	static const struct dvb_device dvbdev_template = {
 		.users = ~0,
 		.writers = 1,
@@ -831,20 +873,26 @@
 	if (down_interruptible (&frontend_mutex))
 		return -ERESTARTSYS;
 
-	init_MUTEX (&fe->sem);
-	init_waitqueue_head (&fe->wait_queue);
-	init_waitqueue_head (&fe->events.wait_queue);
-	init_MUTEX (&fe->events.sem);
-	fe->events.eventw = fe->events.eventr = 0;
-	fe->events.overflow = 0;
+	fe->frontend_priv = kmalloc(sizeof(struct dvb_frontend_private), GFP_KERNEL);
+	if (fe->frontend_priv == NULL) {
+		up(&frontend_mutex);
+		return -ENOMEM;
+	}
+	fepriv = (struct dvb_frontend_private*) fe->frontend_priv;
+	memset(fe->frontend_priv, 0, sizeof(struct dvb_frontend_private));
+
+	init_MUTEX (&fepriv->sem);
+	init_waitqueue_head (&fepriv->wait_queue);
+	init_waitqueue_head (&fepriv->events.wait_queue);
+	init_MUTEX (&fepriv->events.sem);
 	fe->dvb = dvb;
-	fe->inversion = INVERSION_OFF;
+	fepriv->inversion = INVERSION_OFF;
 
 	printk ("DVB: registering frontend %i (%s)...\n",
 		fe->dvb->num,
 		fe->ops->info.name);
 
-	dvb_register_device (fe->dvb, &fe->dvbdev, &dvbdev_template,
+	dvb_register_device (fe->dvb, &fepriv->dvbdev, &dvbdev_template,
 			     fe, DVB_DEVICE_FRONTEND);
 
 	up (&frontend_mutex);
@@ -854,15 +902,19 @@
 
 int dvb_unregister_frontend(struct dvb_frontend* fe)
 {
+	struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv;
 	dprintk ("%s\n", __FUNCTION__);
 
 	down (&frontend_mutex);
-			dvb_unregister_device (fe->dvbdev);
+	dvb_unregister_device (fepriv->dvbdev);
 			dvb_frontend_stop (fe);
 	if (fe->ops->release)
 		fe->ops->release(fe);
 	else
 		printk("dvb_frontend: Demodulator (%s) does not have a release callback!\n", fe->ops->info.name);
+	/* fe is invalid now */
+	if (fepriv)
+		kfree(fepriv);
 	up (&frontend_mutex);
 	return 0;
 }
diff -Nru 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	2005-03-01 23:39:16 -08:00
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.h	2005-03-01 23:39:16 -08:00
@@ -115,28 +115,7 @@
 	struct dvb_frontend_ops* ops;
 	struct dvb_adapter *dvb;
 	void* demodulator_priv;
-
-	struct dvb_device *dvbdev;
-	struct dvb_frontend_parameters parameters;
-	struct dvb_fe_events events;
-	struct semaphore sem;
-	struct list_head list_head;
-	wait_queue_head_t wait_queue;
-	pid_t thread_pid;
-	unsigned long release_jiffies;
-	int state;
-	int bending;
-	int lnb_drift;
-	int inversion;
-	int auto_step;
-	int auto_sub_step;
-	int started_auto_step;
-	int min_delay;
-	int max_drift;
-	int step_size;
-	int exit;
-	int wakeup;
-	fe_status_t status;
+	void* frontend_priv;
 };
 
 extern int dvb_register_frontend(struct dvb_adapter* dvb,
diff -Nru a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c
--- a/drivers/media/dvb/dvb-core/dvb_net.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/media/dvb/dvb-core/dvb_net.c	2005-03-01 23:38:53 -08:00
@@ -123,7 +123,6 @@
 struct dvb_net_priv {
 	int in_use;
         struct net_device_stats stats;
-        char name[6];
 	u16 pid;
 	struct dvb_net *host;
         struct dmx_demux *demux;
@@ -1165,12 +1164,17 @@
 	if ((if_num = get_if(dvbnet)) < 0)
 		return -EINVAL;
 
-	net = alloc_netdev(sizeof(struct dvb_net_priv), "dvb",
-			   dvb_net_setup);
+	net = alloc_netdev(sizeof(struct dvb_net_priv), "dvb", dvb_net_setup);
 	if (!net)
 		return -ENOMEM;
 	
-	sprintf(net->name, "dvb%d_%d", dvbnet->dvbdev->adapter->num, if_num);
+	if (dvbnet->dvbdev->id)
+		snprintf(net->name, IFNAMSIZ, "dvb%d%u%d",
+			 dvbnet->dvbdev->adapter->num, dvbnet->dvbdev->id, if_num);
+	else
+		/* compatibility fix to keep dvb0_0 format */
+		snprintf(net->name, IFNAMSIZ, "dvb%d_%d",
+			 dvbnet->dvbdev->adapter->num, if_num);
 
 	net->addr_len  		= 6;
 	memcpy(net->dev_addr, dvbnet->dvbdev->adapter->proposed_mac, 6);
@@ -1196,6 +1200,7 @@
 		free_netdev(net);
 		return result;
 	}
+	printk("dvb_net: created network interface %s\n", net->name);
 
         return if_num;
 }
@@ -1214,6 +1219,7 @@
 
 	dvb_net_stop(net);
 	flush_scheduled_work();
+	printk("dvb_net: removed network interface %s\n", net->name);
         unregister_netdev(net);
 	dvbnet->state[num]=0;
 	dvbnet->device[num] = NULL;
diff -Nru a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c
--- a/drivers/media/dvb/dvb-core/dvbdev.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/media/dvb/dvb-core/dvbdev.c	2005-03-01 23:38:53 -08:00
@@ -31,6 +31,8 @@
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/device.h>
+#include <linux/fs.h>
+#include <linux/cdev.h>
 
 #include "dvbdev.h"
 
@@ -50,8 +52,9 @@
 };
 
 
-#define DVB_MAX_IDS              4
+#define DVB_MAX_IDS              6
 #define nums2minor(num,type,id)  ((num << 6) | (id << 4) | type)
+#define MAX_DVB_MINORS           (DVB_MAX_IDS*64)
 
 struct class_simple *dvb_class;
 EXPORT_SYMBOL(dvb_class);
@@ -109,6 +112,11 @@
 };
 
 
+static struct cdev dvb_device_cdev = {
+	.kobj   = {.name = "dvb", },
+	.owner  =       THIS_MODULE,
+};
+
 int dvb_generic_open(struct inode *inode, struct file *file)
 {
         struct dvb_device *dvbdev = file->private_data;
@@ -400,25 +408,41 @@
 static int __init init_dvbdev(void)
 {
 	int retval;
+	dev_t dev = MKDEV(DVB_MAJOR, 0);
+
+	if ((retval = register_chrdev_region(dev, MAX_DVB_MINORS, "DVB")) != 0) {
+		printk("dvb-core: unable to get major %d\n", DVB_MAJOR);
+		return retval;
+	}
 
-	if ((retval = register_chrdev(DVB_MAJOR,"DVB", &dvb_device_fops)))
+	cdev_init(&dvb_device_cdev, &dvb_device_fops);
+	if ((retval = cdev_add(&dvb_device_cdev, dev, MAX_DVB_MINORS)) != 0) {
 		printk("dvb-core: unable to get major %d\n", DVB_MAJOR);
+		goto error;
+	}
 
 	devfs_mk_dir("dvb");
 
 	dvb_class = class_simple_create(THIS_MODULE, "dvb");
-	if (IS_ERR(dvb_class))
-		return PTR_ERR(dvb_class);
+	if (IS_ERR(dvb_class)) {
+		retval = PTR_ERR(dvb_class);
+		goto error;
+	}
+	return 0;
 
+error:
+	cdev_del(&dvb_device_cdev);
+	unregister_chrdev_region(dev, MAX_DVB_MINORS);
 	return retval;
 }
 
 
 static void __exit exit_dvbdev(void)
 {
-	unregister_chrdev(DVB_MAJOR, "DVB");
         devfs_remove("dvb");
 	class_simple_destroy(dvb_class);
+	cdev_del(&dvb_device_cdev);
+        unregister_chrdev_region(MKDEV(DVB_MAJOR, 0), MAX_DVB_MINORS);
 }
 
 module_init(init_dvbdev);
diff -Nru a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
--- a/drivers/media/dvb/frontends/Kconfig	2005-03-01 23:38:53 -08:00
+++ b/drivers/media/dvb/frontends/Kconfig	2005-03-01 23:38:53 -08:00
@@ -46,6 +46,7 @@
 config DVB_SP8870
  	tristate "Spase sp8870 based"
 	depends on DVB_CORE
+	select FW_LOADER
 	help
  	  A DVB-T tuner module. Say Y when you want to support this frontend.
 
@@ -56,6 +57,7 @@
 config DVB_SP887X
  	tristate "Spase sp887x based"
 	depends on DVB_CORE
+	select FW_LOADER
 	help
 	  A DVB-T tuner module. Say Y when you want to support this frontend.
 
@@ -84,6 +86,7 @@
 config DVB_TDA1004X
 	tristate "Philips TDA10045H/TDA10046H based"
 	depends on DVB_CORE
+	select FW_LOADER
 	help
 	  A DVB-T tuner module. Say Y when you want to support this frontend.
 
@@ -144,5 +147,14 @@
 	depends on DVB_CORE
 	help
 	  A DVB-C tuner module. Say Y when you want to support this frontend.
+
+comment "ATSC (North American/Korean Terresterial DTV) frontends"
+	depends on DVB_CORE
+
+config DVB_NXT2002
+	tristate "Nxt2002 based"
+	depends on DVB_CORE
+	help
+	  An ATSC 8VSB tuner module. Say Y when you want to support this frontend.
 
 endmenu
diff -Nru a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile
--- a/drivers/media/dvb/frontends/Makefile	2005-03-01 23:38:44 -08:00
+++ b/drivers/media/dvb/frontends/Makefile	2005-03-01 23:38:44 -08:00
@@ -24,3 +24,5 @@
 obj-$(CONFIG_DVB_TDA80XX) += tda80xx.o
 obj-$(CONFIG_DVB_TDA10021) += tda10021.o
 obj-$(CONFIG_DVB_STV0297) += stv0297.o
+obj-$(CONFIG_DVB_NXT2002) += nxt2002.o
+
diff -Nru a/drivers/media/dvb/frontends/cx22700.c b/drivers/media/dvb/frontends/cx22700.c
--- a/drivers/media/dvb/frontends/cx22700.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/media/dvb/frontends/cx22700.c	2005-03-01 23:39:17 -08:00
@@ -1,4 +1,4 @@
-#/*
+/*
     Conexant cx22700 DVB OFDM demodulator driver
 
     Copyright (C) 2001-2002 Convergence Integrated Media GmbH
diff -Nru a/drivers/media/dvb/frontends/dib3000-common.c b/drivers/media/dvb/frontends/dib3000-common.c
--- a/drivers/media/dvb/frontends/dib3000-common.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/media/dvb/frontends/dib3000-common.c	2005-03-01 23:38:53 -08:00
@@ -2,7 +2,7 @@
 
 #ifdef CONFIG_DVB_DIBCOM_DEBUG
 static int debug;
-module_param(debug, int, 0x644);
+module_param(debug, int, 0644);
 MODULE_PARM_DESC(debug, "set debugging level (1=info,2=i2c,4=srch (|-able)).");
 #endif
 #define deb_info(args...) dprintk(0x01,args)
@@ -42,65 +42,6 @@
 	return i2c_transfer(state->i2c,msg, 1) != 1 ? -EREMOTEIO : 0;
 }
 
-int dib3000_init_pid_list(struct dib3000_state *state, int num)
-{
-	int i;
-	if (state != NULL) {
-		state->pid_list = kmalloc(sizeof(struct dib3000_pid) * num,GFP_KERNEL);
-		if (state->pid_list == NULL)
-			return -ENOMEM;
-
-		deb_info("initializing %d pids for the pid_list.\n",num);
-		state->pid_list_lock = SPIN_LOCK_UNLOCKED;
-		memset(state->pid_list,0,num*(sizeof(struct dib3000_pid)));
-		for (i=0; i < num; i++) {
-			state->pid_list[i].pid = 0;
-			state->pid_list[i].active = 0;
-		}
-		state->feedcount = 0;
-	} else
-		return -EINVAL;
-
-	return 0;
-}
-
-void dib3000_dealloc_pid_list(struct dib3000_state *state)
-{
-	if (state != NULL && state->pid_list != NULL)
-		kfree(state->pid_list);
-}
-
-/* fetch a pid from pid_list */
-int dib3000_get_pid_index(struct dib3000_pid pid_list[], int num_pids, int pid,
-		spinlock_t *pid_list_lock,int onoff)
-{
-	int i,ret = -1;
-	unsigned long flags;
-
-	spin_lock_irqsave(pid_list_lock,flags);
-	for (i=0; i < num_pids; i++)
-		if (onoff) {
-			if (!pid_list[i].active) {
-				pid_list[i].pid = pid;
-				pid_list[i].active = 1;
-				ret = i;
-				break;
-			}
-		} else {
-			if (pid_list[i].active && pid_list[i].pid == pid) {
-				pid_list[i].pid = 0;
-				pid_list[i].active = 0;
-				ret = i;
-				break;
-			}
-		}
-
-	deb_info("setting pid: %5d %04x at index %d '%s'\n",pid,pid,ret,onoff ? "on" : "off");
-
-	spin_unlock_irqrestore(pid_list_lock,flags);
-	return ret;
-}
-
 int dib3000_search_status(u16 irq,u16 lock)
 {
 	if (irq & 0x02) {
@@ -139,7 +80,4 @@
 
 EXPORT_SYMBOL(dib3000_read_reg);
 EXPORT_SYMBOL(dib3000_write_reg);
-EXPORT_SYMBOL(dib3000_init_pid_list);
-EXPORT_SYMBOL(dib3000_dealloc_pid_list);
-EXPORT_SYMBOL(dib3000_get_pid_index);
 EXPORT_SYMBOL(dib3000_search_status);
diff -Nru a/drivers/media/dvb/frontends/dib3000-common.h b/drivers/media/dvb/frontends/dib3000-common.h
--- a/drivers/media/dvb/frontends/dib3000-common.h	2005-03-01 23:38:54 -08:00
+++ b/drivers/media/dvb/frontends/dib3000-common.h	2005-03-01 23:38:54 -08:00
@@ -4,7 +4,7 @@
  *
  * DiBcom (http://www.dibcom.fr/)
  *
- * Copyright (C) 2004 Patrick Boettcher (patrick.boettcher@desy.de)
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
  *
  * based on GPL code from DibCom, which has
  *
@@ -29,19 +29,10 @@
 #include "dvb_frontend.h"
 #include "dib3000.h"
 
-/* info and err, taken from usb.h, if there is anything available like by default,
- * please change !
- */
-#define err(format, arg...) printk(KERN_ERR "%s: " format "\n" , __FILE__ , ## arg)
-#define info(format, arg...) printk(KERN_INFO "%s: " format "\n" , __FILE__ , ## arg)
-#define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n" , __FILE__ , ## arg)
-
-/* a PID for the pid_filter list, when in use */
-struct dib3000_pid
-{
-	u16 pid;
-	int active;
-};
+/* info and err, taken from usb.h, if there is anything available like by default. */
+#define err(format, arg...) printk(KERN_ERR "dib3000mX: " format "\n" , ## arg)
+#define info(format, arg...) printk(KERN_INFO "dib3000mX: " format "\n" , ## arg)
+#define warn(format, arg...) printk(KERN_WARNING "dib3000mX: " format "\n" , ## arg)
 
 /* frontend state */
 struct dib3000_state {
@@ -52,25 +43,18 @@
 /* configuration settings */
 	struct dib3000_config config;
 
-	spinlock_t pid_list_lock;
-	struct dib3000_pid *pid_list;
-
-	int feedcount;
-
 	struct dvb_frontend frontend;
 	int timing_offset;
 	int timing_offset_comp_done;
+
+	fe_bandwidth_t last_tuned_bw;
+	u32 last_tuned_freq;
 };
 
 /* commonly used methods by the dib3000mb/mc/p frontend */
 extern int dib3000_read_reg(struct dib3000_state *state, u16 reg);
 extern int dib3000_write_reg(struct dib3000_state *state, u16 reg, u16 val);
 
-extern int dib3000_init_pid_list(struct dib3000_state *state, int num);
-extern void dib3000_dealloc_pid_list(struct dib3000_state *state);
-extern int dib3000_get_pid_index(struct dib3000_pid pid_list[], int num_pids,
-	int pid, spinlock_t *pid_list_lock,int onoff);
-
 extern int dib3000_search_status(u16 irq,u16 lock);
 
 /* handy shortcuts */
@@ -81,7 +65,7 @@
 
 #define wr_foreach(a,v) { int i; \
 	if (sizeof(a) != sizeof(v)) \
-		err("sizeof: %d %d is different",sizeof(a),sizeof(v));\
+		err("sizeof: %zu %zu is different",sizeof(a),sizeof(v));\
 	for (i=0; i < sizeof(a)/sizeof(u16); i++) \
 		wr(a[i],v[i]); \
 	}
@@ -136,8 +120,8 @@
 #define DIB3000_DDS_INVERSION_OFF		(     0)
 #define DIB3000_DDS_INVERSION_ON		(     1)
 
-#define DIB3000_TUNER_WRITE_ENABLE(a)	(0xffff & (a << 7))
-#define DIB3000_TUNER_WRITE_DISABLE(a)	(0xffff & ((a << 7) | (1 << 7)))
+#define DIB3000_TUNER_WRITE_ENABLE(a)	(0xffff & (a << 8))
+#define DIB3000_TUNER_WRITE_DISABLE(a)	(0xffff & ((a << 8) | (1 << 7)))
 
 /* for auto search */
 extern u16 dib3000_seq[2][2][2];
diff -Nru a/drivers/media/dvb/frontends/dib3000.h b/drivers/media/dvb/frontends/dib3000.h
--- a/drivers/media/dvb/frontends/dib3000.h	2005-03-01 23:38:58 -08:00
+++ b/drivers/media/dvb/frontends/dib3000.h	2005-03-01 23:38:58 -08:00
@@ -2,7 +2,7 @@
  * public header file of the frontend drivers for mobile DVB-T demodulators
  * DiBcom 3000-MB and DiBcom 3000-MC/P (http://www.dibcom.fr/)
  *
- * Copyright (C) 2004 Patrick Boettcher (patrick.boettcher@desy.de)
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
  *
  * based on GPL code from DibCom, which has
  *
@@ -31,25 +31,24 @@
 	/* the demodulator's i2c address */
 	u8 demod_address;
 
-	/* The i2c address of the PLL */
-	u8 pll_addr;
-
-	/* PLL maintenance */
-	int (*pll_init)(struct dvb_frontend *fe);
-	int (*pll_set)(struct dvb_frontend *fe, struct dvb_frontend_parameters* params);
+	/* 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]);
 };
 
-struct dib3000_xfer_ops
+struct dib_fe_xfer_ops
 {
 	/* pid and transfer handling is done in the demodulator */
 	int (*pid_parse)(struct dvb_frontend *fe, int onoff);
 	int (*fifo_ctrl)(struct dvb_frontend *fe, int onoff);
-	int (*pid_ctrl)(struct dvb_frontend *fe, int pid, int onoff);
+	int (*pid_ctrl)(struct dvb_frontend *fe, int index, int pid, int onoff);
+	int (*tuner_pass_ctrl)(struct dvb_frontend *fe, int onoff, u8 pll_ctrl);
 };
 
 extern struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config,
-					     struct i2c_adapter* i2c, struct dib3000_xfer_ops *xfer_ops);
+					     struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops);
 
 extern struct dvb_frontend* dib3000mc_attach(const struct dib3000_config* config,
-					     struct i2c_adapter* i2c, struct dib3000_xfer_ops *xfer_ops);
+					     struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops);
 #endif // DIB3000_H
diff -Nru a/drivers/media/dvb/frontends/dib3000mb.c b/drivers/media/dvb/frontends/dib3000mb.c
--- a/drivers/media/dvb/frontends/dib3000mb.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/media/dvb/frontends/dib3000mb.c	2005-03-01 23:38:54 -08:00
@@ -2,7 +2,7 @@
  * Frontend driver for mobile DVB-T demodulator DiBcom 3000-MB
  * DiBcom (http://www.dibcom.fr/)
  *
- * Copyright (C) 2004 Patrick Boettcher (patrick.boettcher@desy.de)
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
  *
  * based on GPL code from DibCom, which has
  *
@@ -29,7 +29,6 @@
 #include <linux/init.h>
 #include <linux/delay.h>
 
-#include "dvb_frontend.h"
 #include "dib3000-common.h"
 #include "dib3000mb_priv.h"
 #include "dib3000.h"
@@ -41,7 +40,7 @@
 
 #ifdef CONFIG_DVB_DIBCOM_DEBUG
 static int debug;
-module_param(debug, int, 0x644);
+module_param(debug, int, 0644);
 MODULE_PARM_DESC(debug, "set debugging level (1=info,2=xfer,4=setfe,8=getfe (|-able)).");
 #endif
 #define deb_info(args...) dprintk(0x01,args)
@@ -49,6 +48,8 @@
 #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,11 +62,9 @@
 	int search_state,seq;
 
 	if (tuner) {
-		wr(DIB3000MB_REG_TUNER,
-				DIB3000_TUNER_WRITE_ENABLE(state->config.pll_addr));
-		state->config.pll_set(fe, fep);
-		wr(DIB3000MB_REG_TUNER,
-				DIB3000_TUNER_WRITE_DISABLE(state->config.pll_addr));
+		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));
 
 		deb_setf("bandwidth: ");
 		switch (ofdm->bandwidth) {
@@ -390,11 +389,9 @@
 	wr(DIB3000MB_REG_DATA_IN_DIVERSITY,DIB3000MB_DATA_DIVERSITY_IN_OFF);
 
 	if (state->config.pll_init) {
-		wr(DIB3000MB_REG_TUNER,
-			DIB3000_TUNER_WRITE_ENABLE(state->config.pll_addr));
-		state->config.pll_init(fe);
-		wr(DIB3000MB_REG_TUNER,
-			DIB3000_TUNER_WRITE_DISABLE(state->config.pll_addr));
+		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));
 	}
 
 	return 0;
@@ -414,6 +411,7 @@
 		return 0;
 
 	dds_val = ((rd(DIB3000MB_REG_DDS_VALUE_MSB) & 0xff) << 16) + rd(DIB3000MB_REG_DDS_VALUE_LSB);
+	deb_getf("DDS_VAL: %x %x %x",dds_val, rd(DIB3000MB_REG_DDS_VALUE_MSB), rd(DIB3000MB_REG_DDS_VALUE_LSB));
 	if (dds_val < threshold)
 		inv_test1 = 0;
 	else if (dds_val == threshold)
@@ -422,6 +420,7 @@
 		inv_test1 = 2;
 
 	dds_val = ((rd(DIB3000MB_REG_DDS_FREQ_MSB) & 0xff) << 16) + rd(DIB3000MB_REG_DDS_FREQ_LSB);
+	deb_getf("DDS_FREQ: %x %x %x",dds_val, rd(DIB3000MB_REG_DDS_FREQ_MSB), rd(DIB3000MB_REG_DDS_FREQ_LSB));
 	if (dds_val < threshold)
 		inv_test2 = 0;
 	else if (dds_val == threshold)
@@ -714,18 +713,11 @@
 }
 
 /* pid filter and transfer stuff */
-static int dib3000mb_pid_control(struct dvb_frontend *fe,int pid,int onoff)
+static int dib3000mb_pid_control(struct dvb_frontend *fe,int index, int pid,int onoff)
 {
 	struct dib3000_state *state = fe->demodulator_priv;
-	int index = dib3000_get_pid_index(state->pid_list, DIB3000MB_NUM_PIDS, pid, &state->pid_list_lock,onoff);
 	pid = (onoff ? pid | DIB3000_ACTIVATE_PID_FILTERING : 0);
-
-	if (index >= 0) {
 		wr(index+DIB3000MB_REG_FIRST_PID,pid);
-	} else {
-		err("no more pids for filtering.");
-		return -ENOMEM;
-	}
 	return 0;
 }
 
@@ -749,10 +741,21 @@
 	return 0;
 	}
 
+static int dib3000mb_tuner_pass_ctrl(struct dvb_frontend *fe, int onoff, u8 pll_addr)
+{
+	struct dib3000_state *state = (struct dib3000_state*) fe->demodulator_priv;
+	if (onoff) {
+		wr(DIB3000MB_REG_TUNER, DIB3000_TUNER_WRITE_ENABLE(pll_addr));
+	} else {
+		wr(DIB3000MB_REG_TUNER, DIB3000_TUNER_WRITE_DISABLE(pll_addr));
+	}
+	return 0;
+}
+
 static struct dvb_frontend_ops dib3000mb_ops;
 
 struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config,
-				      struct i2c_adapter* i2c, struct dib3000_xfer_ops *xfer_ops)
+				      struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops)
 {
 	struct dib3000_state* state = NULL;
 
@@ -773,9 +776,6 @@
 	if (rd(DIB3000_REG_DEVICE_ID) != DIB3000MB_DEVICE_ID)
 		goto error;
 
-	if (dib3000_init_pid_list(state,DIB3000MB_NUM_PIDS))
-		goto error;
-
 	/* create dvb_frontend */
 	state->frontend.ops = &state->ops;
 	state->frontend.demodulator_priv = state;
@@ -784,6 +784,7 @@
 	xfer_ops->pid_parse = dib3000mb_pid_parse;
 	xfer_ops->fifo_ctrl = dib3000mb_fifo_control;
 	xfer_ops->pid_ctrl = dib3000mb_pid_control;
+	xfer_ops->tuner_pass_ctrl = dib3000mb_tuner_pass_ctrl;
 
 	return &state->frontend;
 
@@ -807,6 +808,7 @@
 				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,
 	},
 
diff -Nru a/drivers/media/dvb/frontends/dib3000mc.c b/drivers/media/dvb/frontends/dib3000mc.c
--- a/drivers/media/dvb/frontends/dib3000mc.c	2005-03-01 23:38:51 -08:00
+++ b/drivers/media/dvb/frontends/dib3000mc.c	2005-03-01 23:38:51 -08:00
@@ -2,9 +2,9 @@
  * Frontend driver for mobile DVB-T demodulator DiBcom 3000-MC/P
  * DiBcom (http://www.dibcom.fr/)
  *
- * Copyright (C) 2004 Patrick Boettcher (patrick.boettcher@desy.de)
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
  *
- * based on GPL code from DibCom, which has
+ * based on GPL code from DiBCom, which has
  *
  * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr)
  *
@@ -28,7 +28,6 @@
 #include <linux/init.h>
 #include <linux/delay.h>
 
-#include "dvb_frontend.h"
 #include "dib3000-common.h"
 #include "dib3000mc_priv.h"
 #include "dib3000.h"
@@ -40,14 +39,16 @@
 
 #ifdef CONFIG_DVB_DIBCOM_DEBUG
 static int debug;
-module_param(debug, int, 0x644);
-MODULE_PARM_DESC(debug, "set debugging level (1=info,2=xfer,4=setfe,8=getfe (|-able)).");
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (1=info,2=xfer,4=setfe,8=getfe,16=stat (|-able)).");
 #endif
 #define deb_info(args...) dprintk(0x01,args)
 #define deb_xfer(args...) dprintk(0x02,args)
 #define deb_setf(args...) dprintk(0x04,args)
 #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)
@@ -185,46 +186,33 @@
 	return 0;
 }
 
-static int dib3000mc_get_frontend(struct dvb_frontend* fe,
-				  struct dvb_frontend_parameters *fep);
+static int dib3000mc_set_adp_cfg(struct dib3000_state *state, fe_modulation_t con)
+{
+	switch (con) {
+		case QAM_64: 
+			wr_foreach(dib3000mc_reg_adp_cfg,dib3000mc_adp_cfg[2]);
+			break;
+		case QAM_16: 
+			wr_foreach(dib3000mc_reg_adp_cfg,dib3000mc_adp_cfg[1]);
+			break;
+		case QPSK: 
+			wr_foreach(dib3000mc_reg_adp_cfg,dib3000mc_adp_cfg[0]);
+			break;
+		case QAM_AUTO:
+			break;
+		default:
+			warn("unkown constellation.");
+			break;
+	}
+	return 0;
+}
 
-static int dib3000mc_set_frontend(struct dvb_frontend* fe,
-				  struct dvb_frontend_parameters *fep, int tuner)
+static int dib3000mc_set_general_cfg(struct dib3000_state *state, struct dvb_frontend_parameters *fep, int *auto_val)
 {
-	struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
 	struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm;
 	fe_code_rate_t fe_cr = FEC_NONE;
-	int search_state, seq;
-	u16 val;
 	u8 fft=0, guard=0, qam=0, alpha=0, sel_hp=0, cr=0, hrch=0;
-
-	if (tuner) {
-		wr(DIB3000MC_REG_TUNER,
-				DIB3000_TUNER_WRITE_ENABLE(state->config.pll_addr));
-		state->config.pll_set(fe, fep);
-		wr(DIB3000MC_REG_TUNER,
-				DIB3000_TUNER_WRITE_DISABLE(state->config.pll_addr));
-	}
-
-	dib3000mc_set_timing(state,0,ofdm->transmission_mode,ofdm->bandwidth);
-	dib3000mc_init_auto_scan(state, ofdm->bandwidth, 0);
-
-	wr(DIB3000MC_REG_RESTART,DIB3000MC_RESTART_AGC);
-	wr(DIB3000MC_REG_RESTART,DIB3000MC_RESTART_OFF);
-
-/* Default cfg isi offset adp */
-	wr_foreach(dib3000mc_reg_offset,dib3000mc_offset[0]);
-
-	wr(DIB3000MC_REG_ISI,DIB3000MC_ISI_DEFAULT | DIB3000MC_ISI_INHIBIT);
-	wr_foreach(dib3000mc_reg_adp_cfg,dib3000mc_adp_cfg[1]);
-	wr(DIB3000MC_REG_UNK_133,DIB3000MC_UNK_133);
-
-	wr_foreach(dib3000mc_reg_bandwidth_general,dib3000mc_bandwidth_general);
-	if (ofdm->bandwidth == BANDWIDTH_8_MHZ) {
-		wr_foreach(dib3000mc_reg_bw,dib3000mc_bw[3]);
-	} else {
-		wr_foreach(dib3000mc_reg_bw,dib3000mc_bw[0]);
-	}
+	int seq;
 
 	switch (ofdm->transmission_mode) {
 		case TRANSMISSION_MODE_2K: fft = DIB3000_TRANSMISSION_MODE_2K; break;
@@ -282,8 +270,7 @@
 		case INVERSION_OFF:
 			wr(DIB3000MC_REG_SET_DDS_FREQ_MSB,DIB3000MC_DDS_FREQ_MSB_INV_OFF);
 			break;
-		case INVERSION_AUTO:
-			break;
+		case INVERSION_AUTO: /* fall through */
 		case INVERSION_ON:
 			wr(DIB3000MC_REG_SET_DDS_FREQ_MSB,DIB3000MC_DDS_FREQ_MSB_INV_ON);
 			break;
@@ -298,168 +285,12 @@
 
 	deb_setf("seq? %d\n", seq);
 	wr(DIB3000MC_REG_SEQ_TPS,DIB3000MC_SEQ_TPS(seq,1));
-
-	dib3000mc_set_impulse_noise(state,0,ofdm->constellation,ofdm->bandwidth);
-
-	val = rd(DIB3000MC_REG_DEMOD_PARM);
-	wr(DIB3000MC_REG_DEMOD_PARM,val|DIB3000MC_DEMOD_RST_DEMOD_ON);
-	wr(DIB3000MC_REG_DEMOD_PARM,val);
-
-	msleep(70);
-
-	wr_foreach(dib3000mc_reg_agc_bandwidth, dib3000mc_agc_bandwidth);
-
-	/* something has to be auto searched */
-	if (ofdm->constellation == QAM_AUTO ||
+	*auto_val = ofdm->constellation == QAM_AUTO ||
 		ofdm->hierarchy_information == HIERARCHY_AUTO ||
 		ofdm->guard_interval == GUARD_INTERVAL_AUTO ||
 		ofdm->transmission_mode == TRANSMISSION_MODE_AUTO ||
 		fe_cr == FEC_AUTO ||
-		fep->inversion == INVERSION_AUTO
-		) {
-		int as_count=0;
-
-		deb_setf("autosearch enabled.\n");
-
-		val = rd(DIB3000MC_REG_DEMOD_PARM);
-		wr(DIB3000MC_REG_DEMOD_PARM,val | DIB3000MC_DEMOD_RST_AUTO_SRCH_ON);
-		wr(DIB3000MC_REG_DEMOD_PARM,val);
-
-		while ((search_state = dib3000_search_status(
-					rd(DIB3000MC_REG_AS_IRQ),1)) < 0 && as_count++ < 100)
-			msleep(10);
-
-		deb_info("search_state after autosearch %d after %d checks\n",search_state,as_count);
-
-		if (search_state == 1) {
-			struct dvb_frontend_parameters feps;
-			feps.u.ofdm.bandwidth = ofdm->bandwidth; /* bw is not auto searched */;
-			if (dib3000mc_get_frontend(fe, &feps) == 0) {
-				deb_setf("reading tuning data from frontend succeeded.\n");
-				return dib3000mc_set_frontend(fe, &feps, 0);
-			}
-		}
-	} else {
-		wr(DIB3000MC_REG_ISI,DIB3000MC_ISI_DEFAULT|DIB3000MC_ISI_ACTIVATE);
-		wr_foreach(dib3000mc_reg_adp_cfg,dib3000mc_adp_cfg[qam]);
-		/* set_offset_cfg */
-		wr_foreach(dib3000mc_reg_offset,
-				dib3000mc_offset[(ofdm->transmission_mode == TRANSMISSION_MODE_8K)+1]);
-
-//		dib3000mc_set_timing(1,ofdm->transmission_mode,ofdm->bandwidth);
-
-//		wr(DIB3000MC_REG_LOCK_MASK,DIB3000MC_ACTIVATE_LOCK_MASK); /* activates some locks if needed */
-
-/*		set_or(DIB3000MC_REG_DEMOD_PARM,DIB3000MC_DEMOD_RST_AUTO_SRCH_ON);
-		set_or(DIB3000MC_REG_DEMOD_PARM,DIB3000MC_DEMOD_RST_AUTO_SRCH_OFF);
-		wr(DIB3000MC_REG_RESTART_VIT,DIB3000MC_RESTART_VIT_ON);
-		wr(DIB3000MC_REG_RESTART_VIT,DIB3000MC_RESTART_VIT_OFF);*/
-	}
-
-	return 0;
-}
-
-
-static int dib3000mc_fe_init(struct dvb_frontend* fe, int mobile_mode)
-{
-	struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
-
-	state->timing_offset = 0;
-	state->timing_offset_comp_done = 0;
-
-	wr(DIB3000MC_REG_ELEC_OUT,DIB3000MC_ELEC_OUT_DIV_OUT_ON);
-	wr(DIB3000MC_REG_OUTMODE,DIB3000MC_OM_PAR_CONT_CLK);
-	wr(DIB3000MC_REG_RST_I2C_ADDR,
-		DIB3000MC_DEMOD_ADDR(state->config.demod_address) |
-		DIB3000MC_DEMOD_ADDR_ON);
-
-	wr(DIB3000MC_REG_RST_I2C_ADDR,
-		DIB3000MC_DEMOD_ADDR(state->config.demod_address));
-
-	wr(DIB3000MC_REG_RESTART,DIB3000MC_RESTART_CONFIG);
-	wr(DIB3000MC_REG_RESTART,DIB3000MC_RESTART_OFF);
-
-	wr(DIB3000MC_REG_CLK_CFG_1,DIB3000MC_CLK_CFG_1_POWER_UP);
-	wr(DIB3000MC_REG_CLK_CFG_2,DIB3000MC_CLK_CFG_2_PUP_MOBILE);
-	wr(DIB3000MC_REG_CLK_CFG_3,DIB3000MC_CLK_CFG_3_POWER_UP);
-	wr(DIB3000MC_REG_CLK_CFG_7,DIB3000MC_CLK_CFG_7_INIT);
-
-	wr(DIB3000MC_REG_RST_UNC,DIB3000MC_RST_UNC_OFF);
-	wr(DIB3000MC_REG_UNK_19,DIB3000MC_UNK_19);
-
-	wr(33,5);
-	wr(36,81);
-	wr(DIB3000MC_REG_UNK_88,DIB3000MC_UNK_88);
-
-	wr(DIB3000MC_REG_UNK_99,DIB3000MC_UNK_99);
-	wr(DIB3000MC_REG_UNK_111,DIB3000MC_UNK_111_PH_N_MODE_0); /* phase noise algo off */
-
-	/* mobile mode - portable reception */
-	wr_foreach(dib3000mc_reg_mobile_mode,dib3000mc_mobile_mode[1]);
-
-/* TUNER_PANASONIC_ENV57H12D5: */
-	wr_foreach(dib3000mc_reg_agc_bandwidth,dib3000mc_agc_bandwidth);
-	wr_foreach(dib3000mc_reg_agc_bandwidth_general,dib3000mc_agc_bandwidth_general);
-	wr_foreach(dib3000mc_reg_agc,dib3000mc_agc_tuner[1]);
-
-	wr(DIB3000MC_REG_UNK_110,DIB3000MC_UNK_110);
-	wr(26,0x6680);
-	wr(DIB3000MC_REG_UNK_1,DIB3000MC_UNK_1);
-	wr(DIB3000MC_REG_UNK_2,DIB3000MC_UNK_2);
-	wr(DIB3000MC_REG_UNK_3,DIB3000MC_UNK_3);
-	wr(DIB3000MC_REG_SEQ_TPS,DIB3000MC_SEQ_TPS_DEFAULT);
-
-	wr_foreach(dib3000mc_reg_bandwidth_general,dib3000mc_bandwidth_general);
-	wr_foreach(dib3000mc_reg_bandwidth,dib3000mc_bandwidth_8mhz);
-
-	wr(DIB3000MC_REG_UNK_4,DIB3000MC_UNK_4);
-
-	wr(DIB3000MC_REG_SET_DDS_FREQ_MSB,DIB3000MC_DDS_FREQ_MSB_INV_OFF);
-	wr(DIB3000MC_REG_SET_DDS_FREQ_LSB,DIB3000MC_DDS_FREQ_LSB);
-
-	dib3000mc_set_timing(state,0,TRANSMISSION_MODE_2K,BANDWIDTH_8_MHZ);
-//	wr_foreach(dib3000mc_reg_timing_freq,dib3000mc_timing_freq[3]);
-
-	wr(DIB3000MC_REG_UNK_120,DIB3000MC_UNK_120);
-	wr(DIB3000MC_REG_UNK_134,DIB3000MC_UNK_134);
-	wr(DIB3000MC_REG_FEC_CFG,DIB3000MC_FEC_CFG);
-
-	dib3000mc_set_impulse_noise(state,0,TRANSMISSION_MODE_8K,BANDWIDTH_8_MHZ);
-
-/* output mode control, just the MPEG2_SLAVE */
-	set_or(DIB3000MC_REG_OUTMODE,DIB3000MC_OM_SLAVE);
-	wr(DIB3000MC_REG_SMO_MODE,DIB3000MC_SMO_MODE_SLAVE);
-	wr(DIB3000MC_REG_FIFO_THRESHOLD,DIB3000MC_FIFO_THRESHOLD_SLAVE);
-	wr(DIB3000MC_REG_ELEC_OUT,DIB3000MC_ELEC_OUT_SLAVE);
-
-/* MPEG2_PARALLEL_CONTINUOUS_CLOCK
-	wr(DIB3000MC_REG_OUTMODE,
-		DIB3000MC_SET_OUTMODE(DIB3000MC_OM_PAR_CONT_CLK,
-			rd(DIB3000MC_REG_OUTMODE)));
-
-	wr(DIB3000MC_REG_SMO_MODE,
-			DIB3000MC_SMO_MODE_DEFAULT |
-			DIB3000MC_SMO_MODE_188);
-
-	wr(DIB3000MC_REG_FIFO_THRESHOLD,DIB3000MC_FIFO_THRESHOLD_DEFAULT);
-	wr(DIB3000MC_REG_ELEC_OUT,DIB3000MC_ELEC_OUT_DIV_OUT_ON);
-*/
-/* diversity */
-	wr(DIB3000MC_REG_DIVERSITY1,DIB3000MC_DIVERSITY1_DEFAULT);
-	wr(DIB3000MC_REG_DIVERSITY2,DIB3000MC_DIVERSITY2_DEFAULT);
-
-	wr(DIB3000MC_REG_DIVERSITY3,DIB3000MC_DIVERSITY3_IN_OFF);
-
-	set_or(DIB3000MC_REG_CLK_CFG_7,DIB3000MC_CLK_CFG_7_DIV_IN_OFF);
-
-
-/*	if (state->config->pll_init) {
-		wr(DIB3000MC_REG_TUNER,
-			DIB3000_TUNER_WRITE_ENABLE(state->config->pll_addr));
-		state->config->pll_init(fe);
-		wr(DIB3000MC_REG_TUNER,
-			DIB3000_TUNER_WRITE_DISABLE(state->config->pll_addr));
-	}*/
+			fep->inversion == INVERSION_AUTO;
 	return 0;
 }
 
@@ -476,7 +307,8 @@
 	if (!(rd(DIB3000MC_REG_LOCK_507) & DIB3000MC_LOCK_507))
 		return 0;
 
-	dds_val = ((rd(DIB3000MC_REG_DDS_FREQ_MSB) & 0xff) << 16) + rd(DIB3000MC_REG_DDS_FREQ_LSB);
+	dds_val = (rd(DIB3000MC_REG_DDS_FREQ_MSB) << 16) + rd(DIB3000MC_REG_DDS_FREQ_LSB);
+	deb_getf("DDS_FREQ: %6x\n",dds_val);
 	if (dds_val < threshold)
 		inv_test1 = 0;
 	else if (dds_val == threshold)
@@ -484,7 +316,8 @@
 	else
 		inv_test1 = 2;
 
-	dds_val = ((rd(DIB3000MC_REG_SET_DDS_FREQ_MSB) & 0xff) << 16) + rd(DIB3000MC_REG_SET_DDS_FREQ_LSB);
+	dds_val = (rd(DIB3000MC_REG_SET_DDS_FREQ_MSB) << 16) + rd(DIB3000MC_REG_SET_DDS_FREQ_LSB);
+	deb_getf("DDS_SET_FREQ: %6x\n",dds_val);
 	if (dds_val < threshold)
 		inv_test2 = 0;
 	else if (dds_val == threshold)
@@ -499,6 +332,9 @@
 
 	deb_getf("inversion %d %d, %d\n", inv_test2, inv_test1, fep->inversion);
 
+	fep->frequency = state->last_tuned_freq;
+	fep->u.ofdm.bandwidth= state->last_tuned_bw;
+	
 	tps_val = rd(DIB3000MC_REG_TUNING_PARM);
 
 	switch (DIB3000MC_TP_QAM(tps_val)) {
@@ -614,9 +450,213 @@
 			err("unexpected transmission mode return by TPS (%d)", tps_val);
 			break;
 	}
+	deb_getf("\n");
+
+	return 0;
+}
+
+static int dib3000mc_set_frontend(struct dvb_frontend* fe,
+				  struct dvb_frontend_parameters *fep, int tuner)
+{
+	struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
+	struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm;
+	int search_state,auto_val;
+	u16 val;
+	
+	if (tuner) { /* 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));
+		
+		state->last_tuned_freq = fep->frequency;
+	//	if (!scanboost) {
+			dib3000mc_set_timing(state,0,ofdm->transmission_mode,ofdm->bandwidth);
+			dib3000mc_init_auto_scan(state, ofdm->bandwidth, 0);
+			state->last_tuned_bw = ofdm->bandwidth;
+
+			wr_foreach(dib3000mc_reg_agc_bandwidth,dib3000mc_agc_bandwidth);
+			wr(DIB3000MC_REG_RESTART,DIB3000MC_RESTART_AGC);
+			wr(DIB3000MC_REG_RESTART,DIB3000MC_RESTART_OFF);
+			
+			/* Default cfg isi offset adp */
+			wr_foreach(dib3000mc_reg_offset,dib3000mc_offset[0]);
+
+			wr(DIB3000MC_REG_ISI,DIB3000MC_ISI_DEFAULT | DIB3000MC_ISI_INHIBIT);
+			dib3000mc_set_adp_cfg(state,ofdm->constellation);
+			wr(DIB3000MC_REG_UNK_133,DIB3000MC_UNK_133);
+
+			wr_foreach(dib3000mc_reg_bandwidth_general,dib3000mc_bandwidth_general);
+			/* power smoothing */
+			if (ofdm->bandwidth != BANDWIDTH_8_MHZ) {
+				wr_foreach(dib3000mc_reg_bw,dib3000mc_bw[0]);
+			} else {
+				wr_foreach(dib3000mc_reg_bw,dib3000mc_bw[3]);
+			}
+			auto_val = 0;
+			dib3000mc_set_general_cfg(state,fep,&auto_val);
+			dib3000mc_set_impulse_noise(state,0,ofdm->constellation,ofdm->bandwidth);
+		
+			val = rd(DIB3000MC_REG_DEMOD_PARM);
+			wr(DIB3000MC_REG_DEMOD_PARM,val|DIB3000MC_DEMOD_RST_DEMOD_ON);
+			wr(DIB3000MC_REG_DEMOD_PARM,val);
+	//	}
+		msleep(70);
+
+		/* something has to be auto searched */
+		if (auto_val) {
+			int as_count=0;
+
+			deb_setf("autosearch enabled.\n");
+			
+			val = rd(DIB3000MC_REG_DEMOD_PARM);
+			wr(DIB3000MC_REG_DEMOD_PARM,val | DIB3000MC_DEMOD_RST_AUTO_SRCH_ON);
+			wr(DIB3000MC_REG_DEMOD_PARM,val);
+
+			while ((search_state = dib3000_search_status(
+						rd(DIB3000MC_REG_AS_IRQ),1)) < 0 && as_count++ < 100) 
+				msleep(10);
+			
+			deb_info("search_state after autosearch %d after %d checks\n",search_state,as_count);
+			
+			if (search_state == 1) {
+				struct dvb_frontend_parameters feps;
+				if (dib3000mc_get_frontend(fe, &feps) == 0) {
+					deb_setf("reading tuning data from frontend succeeded.\n");
+					return dib3000mc_set_frontend(fe, &feps, 0);
+				}
+			}
+		} else {
+			dib3000mc_set_impulse_noise(state,0,ofdm->transmission_mode,ofdm->bandwidth);
+			wr(DIB3000MC_REG_ISI,DIB3000MC_ISI_DEFAULT|DIB3000MC_ISI_ACTIVATE);
+			dib3000mc_set_adp_cfg(state,ofdm->constellation);
+			
+			/* set_offset_cfg */
+			wr_foreach(dib3000mc_reg_offset,
+					dib3000mc_offset[(ofdm->transmission_mode == TRANSMISSION_MODE_8K)+1]);
+		}
+	} else { /* second call, after autosearch (fka: set_WithKnownParams) */
+//		dib3000mc_set_timing(state,1,ofdm->transmission_mode,ofdm->bandwidth);
+		
+		auto_val = 0;
+		dib3000mc_set_general_cfg(state,fep,&auto_val);
+		if (auto_val)
+			deb_info("auto_val is true, even though an auto search was already performed.\n");
+
+		dib3000mc_set_impulse_noise(state,0,ofdm->constellation,ofdm->bandwidth);
+		
+		val = rd(DIB3000MC_REG_DEMOD_PARM);
+		wr(DIB3000MC_REG_DEMOD_PARM,val | DIB3000MC_DEMOD_RST_AUTO_SRCH_ON);
+		wr(DIB3000MC_REG_DEMOD_PARM,val);
+		
+		msleep(30);
+		
+		wr(DIB3000MC_REG_ISI,DIB3000MC_ISI_DEFAULT|DIB3000MC_ISI_ACTIVATE);
+			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;
+
+	deb_info("init start\n");
+
+	state = fe->demodulator_priv;
+	state->timing_offset = 0;
+	state->timing_offset_comp_done = 0;
+	
+	wr(DIB3000MC_REG_RESTART,DIB3000MC_RESTART_CONFIG);
+	wr(DIB3000MC_REG_RESTART,DIB3000MC_RESTART_OFF);
+	wr(DIB3000MC_REG_CLK_CFG_1,DIB3000MC_CLK_CFG_1_POWER_UP);
+	wr(DIB3000MC_REG_CLK_CFG_2,DIB3000MC_CLK_CFG_2_PUP_MOBILE);
+	wr(DIB3000MC_REG_CLK_CFG_3,DIB3000MC_CLK_CFG_3_POWER_UP);
+	wr(DIB3000MC_REG_CLK_CFG_7,DIB3000MC_CLK_CFG_7_INIT);
+	
+	wr(DIB3000MC_REG_RST_UNC,DIB3000MC_RST_UNC_OFF);
+	wr(DIB3000MC_REG_UNK_19,DIB3000MC_UNK_19);
+
+	wr(33,5);
+	wr(36,81);
+	wr(DIB3000MC_REG_UNK_88,DIB3000MC_UNK_88);				  
+	
+	wr(DIB3000MC_REG_UNK_99,DIB3000MC_UNK_99);
+	wr(DIB3000MC_REG_UNK_111,DIB3000MC_UNK_111_PH_N_MODE_0); /* phase noise algo off */
+
+	/* mobile mode - portable reception */
+	wr_foreach(dib3000mc_reg_mobile_mode,dib3000mc_mobile_mode[1]); 
+
+/* TUNER_PANASONIC_ENV57H12D5: */
+	wr_foreach(dib3000mc_reg_agc_bandwidth,dib3000mc_agc_bandwidth);
+	wr_foreach(dib3000mc_reg_agc_bandwidth_general,dib3000mc_agc_bandwidth_general);
+	wr_foreach(dib3000mc_reg_agc,dib3000mc_agc_tuner[1]);
+
+	wr(DIB3000MC_REG_UNK_110,DIB3000MC_UNK_110);
+	wr(26,0x6680);
+	wr(DIB3000MC_REG_UNK_1,DIB3000MC_UNK_1);
+	wr(DIB3000MC_REG_UNK_2,DIB3000MC_UNK_2);
+	wr(DIB3000MC_REG_UNK_3,DIB3000MC_UNK_3);
+	wr(DIB3000MC_REG_SEQ_TPS,DIB3000MC_SEQ_TPS_DEFAULT);
+	
+	wr_foreach(dib3000mc_reg_bandwidth,dib3000mc_bandwidth_8mhz);
+	wr_foreach(dib3000mc_reg_bandwidth_general,dib3000mc_bandwidth_general);
+	
+	wr(DIB3000MC_REG_UNK_4,DIB3000MC_UNK_4);
+
+	wr(DIB3000MC_REG_SET_DDS_FREQ_MSB,DIB3000MC_DDS_FREQ_MSB_INV_OFF);
+	wr(DIB3000MC_REG_SET_DDS_FREQ_LSB,DIB3000MC_DDS_FREQ_LSB);
+
+	dib3000mc_set_timing(state,0,TRANSMISSION_MODE_8K,BANDWIDTH_8_MHZ); 
+//	wr_foreach(dib3000mc_reg_timing_freq,dib3000mc_timing_freq[3]);
+	
+	wr(DIB3000MC_REG_UNK_120,DIB3000MC_UNK_120);
+	wr(DIB3000MC_REG_UNK_134,DIB3000MC_UNK_134);
+	wr(DIB3000MC_REG_FEC_CFG,DIB3000MC_FEC_CFG);
+	
+	wr(DIB3000MC_REG_DIVERSITY3,DIB3000MC_DIVERSITY3_IN_OFF);
+	
+	dib3000mc_set_impulse_noise(state,0,TRANSMISSION_MODE_8K,BANDWIDTH_8_MHZ);
+
+/* output mode control, just the MPEG2_SLAVE */
+//	set_or(DIB3000MC_REG_OUTMODE,DIB3000MC_OM_SLAVE);
+	wr(DIB3000MC_REG_OUTMODE,DIB3000MC_OM_SLAVE);
+	wr(DIB3000MC_REG_SMO_MODE,DIB3000MC_SMO_MODE_SLAVE);
+	wr(DIB3000MC_REG_FIFO_THRESHOLD,DIB3000MC_FIFO_THRESHOLD_SLAVE);
+	wr(DIB3000MC_REG_ELEC_OUT,DIB3000MC_ELEC_OUT_SLAVE);
+
+/* MPEG2_PARALLEL_CONTINUOUS_CLOCK
+	wr(DIB3000MC_REG_OUTMODE,
+		DIB3000MC_SET_OUTMODE(DIB3000MC_OM_PAR_CONT_CLK,
+			rd(DIB3000MC_REG_OUTMODE)));
+
+	wr(DIB3000MC_REG_SMO_MODE,
+			DIB3000MC_SMO_MODE_DEFAULT | 
+			DIB3000MC_SMO_MODE_188);
+
+	wr(DIB3000MC_REG_FIFO_THRESHOLD,DIB3000MC_FIFO_THRESHOLD_DEFAULT);
+	wr(DIB3000MC_REG_ELEC_OUT,DIB3000MC_ELEC_OUT_DIV_OUT_ON);
+*/
+	
+/* diversity */
+	wr(DIB3000MC_REG_DIVERSITY1,DIB3000MC_DIVERSITY1_DEFAULT);
+	wr(DIB3000MC_REG_DIVERSITY2,DIB3000MC_DIVERSITY2_DEFAULT);
+
+	set_and(DIB3000MC_REG_DIVERSITY3,DIB3000MC_DIVERSITY3_IN_OFF);
+
+	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));
+	}*/
+	deb_info("init end\n");
+	return 0;
+}
 static int dib3000mc_read_status(struct dvb_frontend* fe, fe_status_t *stat)
 {
 	struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
@@ -627,12 +667,12 @@
 		*stat |= FE_HAS_SIGNAL;
 	if (DIB3000MC_CARRIER_LOCK(lock))
 		*stat |= FE_HAS_CARRIER;
-	if (DIB3000MC_TPS_LOCK(lock)) /* VIT_LOCK ? */
+	if (DIB3000MC_TPS_LOCK(lock))
 		*stat |= FE_HAS_VITERBI;
 	if (DIB3000MC_MPEG_SYNC_LOCK(lock))
 		*stat |= (FE_HAS_SYNC | FE_HAS_LOCK);
 
-	deb_info("actual status is %2x\n",*stat);
+	deb_stat("actual status is %2x fifo_level: %x,244: %x, 206: %x, 207: %x, 1040: %x\n",*stat,rd(510),rd(244),rd(206),rd(207),rd(1040));
 
 	return 0;
 }
@@ -659,7 +699,7 @@
 	u16 val = rd(DIB3000MC_REG_SIGNAL_NOISE_LSB);
 	*strength = (((val >> 6) & 0xff) << 8) + (val & 0x3f);
 
-	deb_info("signal: mantisse = %d, exponent = %d\n",(*strength >> 8) & 0xff, *strength & 0xff);
+	deb_stat("signal: mantisse = %d, exponent = %d\n",(*strength >> 8) & 0xff, *strength & 0xff);
 	return 0;
 }
 
@@ -667,9 +707,8 @@
 static int dib3000mc_read_snr(struct dvb_frontend* fe, u16 *snr)
 {
 	struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
-
-	u16 val = rd(DIB3000MC_REG_SIGNAL_NOISE_MSB),
-		val2 = rd(DIB3000MC_REG_SIGNAL_NOISE_LSB);
+	u16 val = rd(DIB3000MC_REG_SIGNAL_NOISE_LSB),
+		val2 = rd(DIB3000MC_REG_SIGNAL_NOISE_MSB);
 	u16 sig,noise;
 
 	sig =   (((val >> 6) & 0xff) << 8) + (val & 0x3f);
@@ -679,9 +718,9 @@
 	else
 		*snr = (u16) sig/noise;
 
-	deb_info("signal: mantisse = %d, exponent = %d\n",(sig >> 8) & 0xff, sig & 0xff);
-	deb_info("noise:  mantisse = %d, exponent = %d\n",(noise >> 8) & 0xff, noise & 0xff);
-	deb_info("snr: %d\n",*snr);
+	deb_stat("signal: mantisse = %d, exponent = %d\n",(sig >> 8) & 0xff, sig & 0xff);
+	deb_stat("noise:  mantisse = %d, exponent = %d\n",(noise >> 8) & 0xff, noise & 0xff);
+	deb_stat("snr: %d\n",*snr);
 	return 0;
 }
 
@@ -698,7 +737,7 @@
 
 static int dib3000mc_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
 {
-	tune->min_delay_ms = 800;
+	tune->min_delay_ms = 2000;
 	tune->step_size = 166667;
 	tune->max_drift = 166667 * 2;
 
@@ -718,23 +757,15 @@
 static void dib3000mc_release(struct dvb_frontend* fe)
 {
 	struct dib3000_state *state = (struct dib3000_state*) fe->demodulator_priv;
-	dib3000_dealloc_pid_list(state);
 	kfree(state);
 }
 
 /* pid filter and transfer stuff */
-static int dib3000mc_pid_control(struct dvb_frontend *fe,int pid,int onoff)
+static int dib3000mc_pid_control(struct dvb_frontend *fe,int index, int pid,int onoff)
 {
 	struct dib3000_state *state = fe->demodulator_priv;
-	int index = dib3000_get_pid_index(state->pid_list, DIB3000MC_NUM_PIDS, pid, &state->pid_list_lock,onoff);
 	pid = (onoff ? pid | DIB3000_ACTIVATE_PID_FILTERING : 0);
-
-	if (index >= 0) {
 		wr(index+DIB3000MC_REG_FIRST_PID,pid);
-	} else {
-		err("no more pids for filtering.");
-		return -ENOMEM;
-	}
 	return 0;
 }
 
@@ -742,10 +773,14 @@
 {
 	struct dib3000_state *state = (struct dib3000_state*) fe->demodulator_priv;
 	u16 tmp = rd(DIB3000MC_REG_SMO_MODE);
-	deb_xfer("%s fifo",onoff ? "enabling" : "disabling");
+	
+	deb_xfer("%s fifo\n",onoff ? "enabling" : "disabling");
+	
 	if (onoff) {
+		deb_xfer("%d %x\n",tmp & DIB3000MC_SMO_MODE_FIFO_UNFLUSH,tmp & DIB3000MC_SMO_MODE_FIFO_UNFLUSH);
 		wr(DIB3000MC_REG_SMO_MODE,tmp & DIB3000MC_SMO_MODE_FIFO_UNFLUSH);
 	} else {
+		deb_xfer("%d %x\n",tmp | DIB3000MC_SMO_MODE_FIFO_FLUSH,tmp | DIB3000MC_SMO_MODE_FIFO_FLUSH);
 		wr(DIB3000MC_REG_SMO_MODE,tmp | DIB3000MC_SMO_MODE_FIFO_FLUSH);
 	}
 	return 0;
@@ -755,19 +790,57 @@
 {
 	struct dib3000_state *state = fe->demodulator_priv;
 	u16 tmp = rd(DIB3000MC_REG_SMO_MODE);
-	deb_xfer("%s pid parsing",onoff ? "enabling" : "disabling");
+	
+	deb_xfer("%s pid parsing\n",onoff ? "enabling" : "disabling");
+	
 	if (onoff) {
+		deb_xfer("%d %x\n",tmp | DIB3000MC_SMO_MODE_PID_PARSE,tmp | DIB3000MC_SMO_MODE_PID_PARSE);
 		wr(DIB3000MC_REG_SMO_MODE,tmp | DIB3000MC_SMO_MODE_PID_PARSE);
 	} else {
+		deb_xfer("%d %x\n",tmp & DIB3000MC_SMO_MODE_NO_PID_PARSE,tmp & DIB3000MC_SMO_MODE_NO_PID_PARSE);
 		wr(DIB3000MC_REG_SMO_MODE,tmp & DIB3000MC_SMO_MODE_NO_PID_PARSE);
 	}
 	return 0;
 }
 
+static int dib3000mc_tuner_pass_ctrl(struct dvb_frontend *fe, int onoff, u8 pll_addr)
+{
+	struct dib3000_state *state = (struct dib3000_state*) fe->demodulator_priv;
+	if (onoff) {
+		wr(DIB3000MC_REG_TUNER, DIB3000_TUNER_WRITE_ENABLE(pll_addr));
+	} else {
+		wr(DIB3000MC_REG_TUNER, DIB3000_TUNER_WRITE_DISABLE(pll_addr));
+	}
+	return 0;
+}
+
+static int dib3000mc_demod_init(struct dib3000_state *state) 
+{
+	u16 default_addr = 0x0a;
+	/* first init */
+	if (state->config.demod_address != default_addr) {
+		deb_info("initializing the demod the first time. Setting demod addr to 0x%x\n",default_addr);
+		wr(DIB3000MC_REG_ELEC_OUT,DIB3000MC_ELEC_OUT_DIV_OUT_ON);
+		wr(DIB3000MC_REG_OUTMODE,DIB3000MC_OM_PAR_CONT_CLK);
+		
+		wr(DIB3000MC_REG_RST_I2C_ADDR,
+			DIB3000MC_DEMOD_ADDR(default_addr) |
+			DIB3000MC_DEMOD_ADDR_ON);
+	
+		state->config.demod_address = default_addr;
+		
+		wr(DIB3000MC_REG_RST_I2C_ADDR,
+			DIB3000MC_DEMOD_ADDR(default_addr));
+	} else
+		deb_info("demod is already initialized. Demod addr: 0x%x\n",state->config.demod_address);
+	return 0;
+}
+
+
 static struct dvb_frontend_ops dib3000mc_ops;
 
 struct dvb_frontend* dib3000mc_attach(const struct dib3000_config* config,
-				      struct i2c_adapter* i2c, struct dib3000_xfer_ops *xfer_ops)
+				      struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops)
 {
 	struct dib3000_state* state = NULL;
 	u16 devid;
@@ -790,19 +863,15 @@
 	if (devid != DIB3000MC_DEVICE_ID && devid != DIB3000P_DEVICE_ID)
 		goto error;
 
-
 	switch (devid) {
 		case DIB3000MC_DEVICE_ID:
-			info("Found a DiBcom 3000-MC.");
+			info("Found a DiBcom 3000-MC, interesting...");
 			break;
 		case DIB3000P_DEVICE_ID:
 			info("Found a DiBcom 3000-P.");
 			break;
 	}
 
-	if (dib3000_init_pid_list(state,DIB3000MC_NUM_PIDS))
-		goto error;
-
 	/* create dvb_frontend */
 	state->frontend.ops = &state->ops;
 	state->frontend.demodulator_priv = state;
@@ -811,6 +880,9 @@
 	xfer_ops->pid_parse = dib3000mc_pid_parse;
 	xfer_ops->fifo_ctrl = dib3000mc_fifo_control;
 	xfer_ops->pid_ctrl = dib3000mc_pid_control;
+	xfer_ops->tuner_pass_ctrl = dib3000mc_tuner_pass_ctrl;
+
+	dib3000mc_demod_init(state);
 
 	return &state->frontend;
 
@@ -834,6 +906,7 @@
 				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,
 	},
 
diff -Nru a/drivers/media/dvb/frontends/dib3000mc_priv.h b/drivers/media/dvb/frontends/dib3000mc_priv.h
--- a/drivers/media/dvb/frontends/dib3000mc_priv.h	2005-03-01 23:38:57 -08:00
+++ b/drivers/media/dvb/frontends/dib3000mc_priv.h	2005-03-01 23:38:57 -08:00
@@ -13,31 +13,6 @@
 #ifndef __DIB3000MC_PRIV_H__
 #define __DIB3000MC_PRIV_H__
 
-/* info and err, taken from usb.h, if there is anything available like by default,
- * please change !
- */
-#define err(format, arg...) printk(KERN_ERR "%s: " format "\n" , __FILE__ , ## arg)
-#define info(format, arg...) printk(KERN_INFO "%s: " format "\n" , __FILE__ , ## arg)
-#define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n" , __FILE__ , ## arg)
-
-// defines the phase noise algorithm to be used (O:Inhib, 1:CPE on)
-#define DEF_PHASE_NOISE_MODE                0
-
-// define Mobille algorithms
-#define DEF_MOBILE_MODE      Auto_Reception
-
-// defines the tuner type
-#define DEF_TUNER_TYPE   TUNER_PANASONIC_ENV57H13D5
-
-// defines the impule noise algorithm to be used
-#define DEF_IMPULSE_NOISE_MODE      0
-
-// defines the MPEG2 data output format
-#define DEF_MPEG2_OUTPUT_188       0
-
-// defines the MPEG2 data output format
-#define DEF_OUTPUT_MODE       MPEG2_PARALLEL_CONTINUOUS_CLOCK
-
 /*
  * Demodulator parameters
  * reg: 0  1 1  1 11 11 111
@@ -115,7 +90,7 @@
 	{ 0x1c, 0xfba5, 0x60, 0x9c25, 0x1e3, 0x0cb7, 0x1, 0xb0d0 };
 
 static u16 dib3000mc_bandwidth_8mhz[] =
-	{ 0x19, 0x5c30, 0x54, 0x88a0, 0x1a6, 0xab20, 0x1, 0xb0b0 };
+	{ 0x19, 0x5c30, 0x54, 0x88a0, 0x1a6, 0xab20, 0x1, 0xb0d0 };
 
 static u16 dib3000mc_reg_bandwidth_general[] = { 12,13,14,15 };
 static u16 dib3000mc_bandwidth_general[] = { 0x0000, 0x03e8, 0x0000, 0x03f2 };
@@ -173,11 +148,11 @@
 static u16 dib3000mc_reg_imp_noise_ctl[] = { 34,35 };
 
 static u16 dib3000mc_imp_noise_ctl[][2] = {
-	{ 0x1294, 0xfff8 }, /* mode 0 */
-	{ 0x1294, 0xfff8 }, /* mode 1 */
-	{ 0x1294, 0xfff8 }, /* mode 2 */
-	{ 0x1294, 0xfff8 }, /* mode 3 */
-	{ 0x1294, 0xfff8 }, /* mode 4 */
+	{ 0x1294, 0x1ff8 }, /* mode 0 */
+	{ 0x1294, 0x1ff8 }, /* mode 1 */
+	{ 0x1294, 0x1ff8 }, /* mode 2 */
+	{ 0x1294, 0x1ff8 }, /* mode 3 */
+	{ 0x1294, 0x1ff8 }, /* mode 4 */
 };
 
 /* AGC registers */
@@ -314,12 +289,26 @@
 #define DIB3000MC_REG_FEC_CFG			(   195)
 #define DIB3000MC_FEC_CFG				(  0x10)
 
+/*
+ * reg 206, output mode
+ *              1111 1111
+ *              |||| ||||
+ *              |||| |||+- unk
+ *              |||| ||+-- unk
+ *              |||| |+--- unk (on by default)
+ *              |||| +---- fifo_ctrl (1 = inhibit (flushed), 0 = active (unflushed))
+ *              |||+------ pid_parse (1 = enabled, 0 = disabled)
+ *              ||+------- outp_188  (1 = TS packet size 188, 0 = packet size 204)
+ *              |+-------- unk 
+ *              +--------- unk
+ */
+
 #define DIB3000MC_REG_SMO_MODE			(   206)
 #define DIB3000MC_SMO_MODE_DEFAULT		(1 << 2)
 #define DIB3000MC_SMO_MODE_FIFO_FLUSH	(1 << 3)
-#define DIB3000MC_SMO_MODE_FIFO_UNFLUSH	~DIB3000MC_SMO_MODE_FIFO_FLUSH
+#define DIB3000MC_SMO_MODE_FIFO_UNFLUSH	(0xfff7)
 #define DIB3000MC_SMO_MODE_PID_PARSE	(1 << 4)
-#define DIB3000MC_SMO_MODE_NO_PID_PARSE	~DIB3000MC_SMO_MODE_PID_PARSE
+#define DIB3000MC_SMO_MODE_NO_PID_PARSE	(0xffef)
 #define DIB3000MC_SMO_MODE_188			(1 << 5)
 #define DIB3000MC_SMO_MODE_SLAVE		(DIB3000MC_SMO_MODE_DEFAULT | \
 			DIB3000MC_SMO_MODE_188 | DIB3000MC_SMO_MODE_PID_PARSE | (1<<1))
@@ -392,7 +381,7 @@
 
 #define DIB3000MC_REG_RST_I2C_ADDR		(  1024)
 #define DIB3000MC_DEMOD_ADDR_ON			(     1)
-#define DIB3000MC_DEMOD_ADDR(a)			((a << 3) & 0x03F0)
+#define DIB3000MC_DEMOD_ADDR(a)			((a << 4) & 0x03F0)
 
 #define DIB3000MC_REG_RESTART			(  1027)
 #define DIB3000MC_RESTART_OFF			(0x0000)
diff -Nru a/drivers/media/dvb/frontends/mt352.c b/drivers/media/dvb/frontends/mt352.c
--- a/drivers/media/dvb/frontends/mt352.c	2005-03-01 23:38:51 -08:00
+++ b/drivers/media/dvb/frontends/mt352.c	2005-03-01 23:38:51 -08:00
@@ -58,16 +58,26 @@
 		if (debug) printk(KERN_DEBUG "mt352: " args); \
 } while (0)
 
-int mt352_write(struct dvb_frontend* fe, u8* ibuf, int ilen)
+static int mt352_single_write(struct dvb_frontend *fe, u8 reg, u8 val)
 {
 	struct mt352_state* state = (struct mt352_state*) fe->demodulator_priv;
+	u8 buf[2] = { reg, val };
 	struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0,
-			       .buf = ibuf, .len = ilen };
+			       .buf = buf, .len = 2 };
 	int err = i2c_transfer(state->i2c, &msg, 1);
 	if (err != 1) {
-		dprintk("mt352_write() failed (err = %d)!\n", err);
+		dprintk("mt352_write() to reg %x failed (err = %d)!\n", reg, err);
 		return err;
 }
+	return 0; 
+}
+
+int mt352_write(struct dvb_frontend* fe, u8* ibuf, int ilen)
+{
+	int err,i;
+	for (i=0; i < ilen-1; i++)
+		if ((err = mt352_single_write(fe,ibuf[0]+i,ibuf[i+1]))) 
+			return err;
 
 	return 0;
 }
@@ -92,9 +102,10 @@
 	return b1[0];
 }
 
-
-
-
+u8 mt352_read(struct dvb_frontend *fe, u8 reg)
+{
+	return mt352_read_register(fe->demodulator_priv,reg);
+}
 
 
 
@@ -556,3 +567,4 @@
 
 EXPORT_SYMBOL(mt352_attach);
 EXPORT_SYMBOL(mt352_write);
+EXPORT_SYMBOL(mt352_read);
diff -Nru a/drivers/media/dvb/frontends/mt352.h b/drivers/media/dvb/frontends/mt352.h
--- a/drivers/media/dvb/frontends/mt352.h	2005-03-01 23:39:09 -08:00
+++ b/drivers/media/dvb/frontends/mt352.h	2005-03-01 23:39:09 -08:00
@@ -54,5 +54,6 @@
 					 struct i2c_adapter* i2c);
 
 extern int mt352_write(struct dvb_frontend* fe, u8* ibuf, int ilen);
+extern u8 mt352_read(struct dvb_frontend *fe, u8 reg);
 
 #endif // MT352_H
diff -Nru a/drivers/media/dvb/frontends/nxt2002.c b/drivers/media/dvb/frontends/nxt2002.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/media/dvb/frontends/nxt2002.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,670 @@
+/*
+    Support for B2C2/BBTI Technisat Air2PC - ATSC  
+
+    Copyright (C) 2004 Taylor Jacob <rtjacob@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.
+
+*/
+
+/*
+ * This driver needs external firmware. Please use the command
+ * "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2002" to
+ * download/extract it, and then copy it to /usr/lib/hotplug/firmware.
+ */
+#define NXT2002_DEFAULT_FIRMWARE "dvb-fe-nxt2002.fw"
+#define CRC_CCIT_MASK 0x1021
+
+#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 "nxt2002.h"
+
+struct nxt2002_state {
+
+	struct i2c_adapter* i2c;
+	struct dvb_frontend_ops ops;
+	const struct nxt2002_config* config;
+	struct dvb_frontend frontend;
+
+	/* demodulator private data */
+	u8 initialised:1;
+};
+
+static int debug;
+#define dprintk(args...) \
+	do { \
+		if (debug) printk(KERN_DEBUG "nxt2002: " args); \
+	} while (0)
+
+static int i2c_writebytes (struct nxt2002_state* state, u8 reg, u8 *buf, u8 len)
+{
+	/* probbably a much better way or doing this */
+	u8 buf2 [256],x;
+	int err;
+	struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf2, .len = len + 1 };
+       
+	buf2[0] = reg;
+	for (x = 0 ; x < len ; x++)
+		buf2[x+1] = buf[x];
+
+	if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
+		printk ("%s: i2c write error (addr %02x, err == %i)\n",
+			__FUNCTION__, state->config->demod_address, err);
+		return -EREMOTEIO;
+	}
+
+	return 0;
+}
+
+static u8 i2c_readbytes (struct nxt2002_state* state, u8 reg, u8* buf, u8 len)
+{
+	u8 reg2 [] = { reg };
+
+	struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = reg2, .len = 1 },
+			{ .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = buf, .len = len } };
+
+	int err;
+
+	if ((err = i2c_transfer (state->i2c, msg, 2)) != 2) {
+		printk ("%s: i2c read error (addr %02x, err == %i)\n",
+			__FUNCTION__, state->config->demod_address, err);
+		return -EREMOTEIO;
+	}
+
+	return 0;
+}
+
+static u16 nxt2002_crc(u16 crc, u8 c) 
+{
+
+	u8 i;
+	u16 input = (u16) c & 0xFF;
+  
+	input<<=8;
+	for(i=0 ;i<8 ;i++) {
+		if((crc ^ input) & 0x8000)
+			crc=(crc<<1)^CRC_CCIT_MASK;
+		else
+			crc<<=1;
+	input<<=1;
+	}
+	return crc;
+}
+
+static int nxt2002_writereg_multibyte (struct nxt2002_state* state, u8 reg, u8* data, u8 len)
+{
+	u8 buf;
+	dprintk("%s\n", __FUNCTION__);
+
+	/* set multi register length */
+	i2c_writebytes(state,0x34,&len,1);
+
+	/* set mutli register register */
+	i2c_writebytes(state,0x35,&reg,1);
+
+	/* send the actual data */
+	i2c_writebytes(state,0x36,data,len);
+
+	/* toggle the multireg write bit*/
+	buf = 0x02;
+	i2c_writebytes(state,0x21,&buf,1);
+
+	i2c_readbytes(state,0x21,&buf,1);
+
+	if ((buf & 0x02) == 0)
+		return 0;
+ 
+	dprintk("Error writing multireg register %02X\n",reg);
+
+	return 0;
+}
+
+static int nxt2002_readreg_multibyte (struct nxt2002_state* state, u8 reg, u8* data, u8 len)
+{
+	u8 len2;
+	dprintk("%s\n", __FUNCTION__);
+
+	/* set multi register length */
+	len2 = len & 0x80;
+	i2c_writebytes(state,0x34,&len2,1);
+
+	/* set mutli register register */
+	i2c_writebytes(state,0x35,&reg,1);
+
+	/* send the actual data */
+	i2c_readbytes(state,reg,data,len);
+
+	return 0;
+}
+
+static void nxt2002_microcontroller_stop (struct nxt2002_state* state)
+{
+	u8 buf[2],counter = 0;
+	dprintk("%s\n", __FUNCTION__);
+
+	buf[0] = 0x80;
+	i2c_writebytes(state,0x22,buf,1);
+
+	while (counter < 20) { 
+		i2c_readbytes(state,0x31,buf,1);
+		if (buf[0] & 0x40) 
+			return;
+		msleep(10);
+		counter++;
+	}
+
+	dprintk("Timeout waiting for micro to stop.. This is ok after firmware upload\n");
+	return; 
+}
+
+static void nxt2002_microcontroller_start (struct nxt2002_state* state)
+{
+	u8 buf;
+	dprintk("%s\n", __FUNCTION__);
+
+	buf = 0x00;
+	i2c_writebytes(state,0x22,&buf,1);
+}
+
+static int nxt2002_writetuner (struct nxt2002_state* state, u8* data)
+{
+	u8 buf,count = 0;
+
+	dprintk("Tuner Bytes: %02X %02X %02X %02X\n",data[0],data[1],data[2],data[3]);
+
+	dprintk("%s\n", __FUNCTION__);
+	/* stop the micro first */
+	nxt2002_microcontroller_stop(state);
+
+	/* set the i2c transfer speed to the tuner */
+	buf = 0x03;
+	i2c_writebytes(state,0x20,&buf,1);
+
+	/* setup to transfer 4 bytes via i2c */
+	buf = 0x04;
+	i2c_writebytes(state,0x34,&buf,1);
+
+	/* write actual tuner bytes */
+	i2c_writebytes(state,0x36,data,4);
+
+	/* set tuner i2c address */
+	buf = 0xC2;
+	i2c_writebytes(state,0x35,&buf,1);
+
+	/* write UC Opmode to begin transfer */
+	buf = 0x80;
+	i2c_writebytes(state,0x21,&buf,1);
+ 
+	while (count < 20) {
+		i2c_readbytes(state,0x21,&buf,1);
+		if ((buf & 0x80)== 0x00)
+			return 0;
+		msleep(100);
+		count++;
+	}
+
+	printk("nxt2002: timeout error writing tuner\n");
+	return 0;
+}
+
+static void nxt2002_agc_reset(struct nxt2002_state* state)
+{
+	u8 buf;
+	dprintk("%s\n", __FUNCTION__);
+
+	buf = 0x08;
+	i2c_writebytes(state,0x08,&buf,1);
+
+	buf = 0x00;
+	i2c_writebytes(state,0x08,&buf,1);
+
+	return;
+}
+
+static int nxt2002_load_firmware (struct dvb_frontend* fe, const struct firmware *fw)
+{
+
+	struct nxt2002_state* state = (struct nxt2002_state*) fe->demodulator_priv;
+	u8 buf[256],written = 0,chunkpos = 0;
+	u16 rambase,position,crc = 0;  
+
+	dprintk("%s\n", __FUNCTION__);
+	dprintk("Firmware is %zu bytes\n",fw->size);
+
+	/* Get the RAM base for this nxt2002 */
+	i2c_readbytes(state,0x10,buf,1);
+
+	
+	if (buf[0] & 0x10)
+		rambase = 0x1000;
+	else
+		rambase = 0x0000;
+
+	dprintk("rambase on this nxt2002 is %04X\n",rambase);
+
+	/* Hold the micro in reset while loading firmware */
+	buf[0] = 0x80;
+	i2c_writebytes(state,0x2B,buf,1);
+
+        
+	for (position = 0; position < fw->size ; position++) {
+		if (written == 0) {
+			crc = 0;
+			chunkpos = 0x28;
+			buf[0] = ((rambase + position) >> 8);
+			buf[1] = (rambase + position) & 0xFF;
+			buf[2] = 0x81;
+			/* write starting address */
+			i2c_writebytes(state,0x29,buf,3);
+		}
+		written++;          
+		chunkpos++;
+
+		if ((written % 4) == 0)
+			i2c_writebytes(state,chunkpos,&fw->data[position-3],4);
+
+		crc = nxt2002_crc(crc,fw->data[position]);
+
+            
+		if ((written == 255) || (position+1 == fw->size)) {
+			/* write remaining bytes of firmware */
+			i2c_writebytes(state, chunkpos+4-(written %4),
+				&fw->data[position-(written %4) + 1],
+				written %4);
+			buf[0] = crc << 8;
+			buf[1] = crc & 0xFF;
+               
+			/* write crc */
+			i2c_writebytes(state,0x2C,buf,2);
+
+			/* do a read to stop things */
+			i2c_readbytes(state,0x2A,buf,1);
+
+			/* set transfer mode to complete */
+			buf[0] = 0x80;
+			i2c_writebytes(state,0x2B,buf,1);
+
+			written = 0;
+		}
+	}
+
+	printk ("done.\n");
+	return 0;
+};
+
+
+static int nxt2002_setup_frontend_parameters (struct dvb_frontend* fe,
+					     struct dvb_frontend_parameters *p)
+{
+	struct nxt2002_state* state = (struct nxt2002_state*) fe->demodulator_priv;
+	u32 freq = 0;
+	u16 tunerfreq = 0; 
+	u8 buf[4];
+
+	freq = 44000 + ( p->frequency / 1000 ); 
+
+	dprintk("freq = %d      p->frequency = %d\n",freq,p->frequency);
+
+	tunerfreq = freq * 24/4000;
+ 
+	buf[0] = (tunerfreq >> 8) & 0x7F;
+	buf[1] = (tunerfreq & 0xFF);
+        
+	if (p->frequency <= 214000000) {
+		buf[2] = 0x84 + (0x06 << 3);
+		buf[3] = (p->frequency <= 172000000) ? 0x01 : 0x02;
+	} else if (p->frequency <= 721000000) {
+		buf[2] = 0x84 + (0x07 << 3);
+		buf[3] = (p->frequency <= 467000000) ? 0x02 : 0x08;
+	} else if (p->frequency <= 841000000) {
+		buf[2] = 0x84 + (0x0E << 3);
+		buf[3] = 0x08;
+	} else {
+		buf[2] = 0x84 + (0x0F << 3);         
+		buf[3] = 0x02;
+	}
+
+	/* write frequency information */
+	nxt2002_writetuner(state,buf);
+
+	/* reset the agc now that tuning has been completed */
+	nxt2002_agc_reset(state);
+
+	/* set target power level */
+	buf[0] = 0x70;
+	i2c_writebytes(state,0x42,buf,1);
+
+	/* configure sdm */
+	buf[0] = 0x87;
+	i2c_writebytes(state,0x57,buf,1);
+
+	/* write sdm1 input */
+	buf[0] = 0x10;
+	buf[1] = 0x00;
+	nxt2002_writereg_multibyte(state,0x58,buf,2);
+
+	/* write sdmx input */
+	buf[0] = 0x60;
+	buf[1] = 0x00;
+	nxt2002_writereg_multibyte(state,0x5C,buf,2);
+
+	/* write adc power lpf fc */
+	buf[0] = 0x05;
+	i2c_writebytes(state,0x43,buf,1);
+
+	/* write adc power lpf fc */
+	buf[0] = 0x05;
+	i2c_writebytes(state,0x43,buf,1);
+
+	/* write accumulator2 input */
+	buf[0] = 0x80;
+	buf[1] = 0x00;
+	nxt2002_writereg_multibyte(state,0x4B,buf,2);
+
+	/* write kg1 */
+	buf[0] = 0x00;
+	i2c_writebytes(state,0x4D,buf,1);
+
+	/* write sdm12 lpf fc */
+	buf[0] = 0x44;
+	i2c_writebytes(state,0x55,buf,1);
+
+	/* write agc control reg */
+	buf[0] = 0x04;
+	i2c_writebytes(state,0x41,buf,1);
+
+	/* write agc ucgp0 */
+	buf[0] = 0x00;
+	i2c_writebytes(state,0x30,buf,1);
+
+	/* write agc control reg */
+	buf[0] = 0x00;
+	i2c_writebytes(state,0x41,buf,1);
+
+	/* write accumulator2 input */
+	buf[0] = 0x80;
+	buf[1] = 0x00;
+	nxt2002_writereg_multibyte(state,0x49,buf,2);
+	nxt2002_writereg_multibyte(state,0x4B,buf,2);
+
+	/* write agc control reg */
+	buf[0] = 0x04;
+	i2c_writebytes(state,0x41,buf,1);
+
+	nxt2002_microcontroller_start(state);
+
+	/* adjacent channel detection should be done here, but I don't 
+	have any stations with this need so I cannot test it */
+
+	return 0;
+}
+
+static int nxt2002_read_status(struct dvb_frontend* fe, fe_status_t* status)
+{
+	struct nxt2002_state* state = (struct nxt2002_state*) fe->demodulator_priv;
+	u8 lock;
+	i2c_readbytes(state,0x31,&lock,1);
+
+	*status = 0;
+	if (lock & 0x20) {
+		*status |= FE_HAS_SIGNAL;
+		*status |= FE_HAS_CARRIER;
+		*status |= FE_HAS_VITERBI;
+		*status |= FE_HAS_SYNC;                
+		*status |= FE_HAS_LOCK;
+	}
+	return 0;
+}
+
+static int nxt2002_read_ber(struct dvb_frontend* fe, u32* ber)
+{
+	struct nxt2002_state* state = (struct nxt2002_state*) fe->demodulator_priv;
+	u8 b[3];
+
+	nxt2002_readreg_multibyte(state,0xE6,b,3);        
+
+	*ber = ((b[0] << 8) + b[1]) * 8;
+ 
+	return 0;
+}
+
+static int nxt2002_read_signal_strength(struct dvb_frontend* fe, u16* strength)
+{
+	struct nxt2002_state* state = (struct nxt2002_state*) fe->demodulator_priv;
+	u8 b[2];
+	u16 temp = 0;
+
+	/* setup to read cluster variance */
+	b[0] = 0x00;
+	i2c_writebytes(state,0xA1,b,1);
+
+	/* get multreg val */
+	nxt2002_readreg_multibyte(state,0xA6,b,2);        
+
+	temp = (b[0] << 8) | b[1];
+	*strength = ((0x7FFF - temp) & 0x0FFF) * 16;
+
+	return 0;
+}
+
+static int nxt2002_read_snr(struct dvb_frontend* fe, u16* snr)
+{
+
+	struct nxt2002_state* state = (struct nxt2002_state*) fe->demodulator_priv;
+	u8 b[2];
+	u16 temp = 0, temp2;
+	u32 snrdb = 0;
+
+	/* setup to read cluster variance */
+	b[0] = 0x00;
+	i2c_writebytes(state,0xA1,b,1);
+
+	/* get multreg val from 0xA6 */
+	nxt2002_readreg_multibyte(state,0xA6,b,2);        
+
+	temp = (b[0] << 8) | b[1];
+	temp2 = 0x7FFF - temp;
+
+	/* snr will be in db */
+	if (temp2 > 0x7F00)
+		snrdb = 1000*24 + ( 1000*(30-24) * ( temp2 - 0x7F00 ) / ( 0x7FFF - 0x7F00 ) );
+	else if (temp2 > 0x7EC0)
+		snrdb = 1000*18 + ( 1000*(24-18) * ( temp2 - 0x7EC0 ) / ( 0x7F00 - 0x7EC0 ) );
+	else if (temp2 > 0x7C00)
+		snrdb = 1000*12 + ( 1000*(18-12) * ( temp2 - 0x7C00 ) / ( 0x7EC0 - 0x7C00 ) );
+	else
+		snrdb = 1000*0 + ( 1000*(12-0) * ( temp2 - 0 ) / ( 0x7C00 - 0 ) );
+
+        /* the value reported back from the frontend will be FFFF=32db 0000=0db */
+
+	*snr = snrdb * (0xFFFF/32000);
+
+	return 0;
+}
+
+static int nxt2002_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
+{
+	struct nxt2002_state* state = (struct nxt2002_state*) fe->demodulator_priv;
+	u8 b[3];
+ 
+	nxt2002_readreg_multibyte(state,0xE6,b,3);
+
+	*ucblocks = b[2];
+
+	return 0;
+}
+
+static int nxt2002_sleep(struct dvb_frontend* fe)
+{
+	return 0;
+}
+
+static int nxt2002_init(struct dvb_frontend* fe)
+{
+	struct nxt2002_state* state = (struct nxt2002_state*) fe->demodulator_priv;
+	const struct firmware *fw;
+	int ret;
+	u8 buf[2];
+
+	if (!state->initialised) {
+		/* request the firmware, this will block until someone uploads it */
+		printk("nxt2002: Waiting for firmware upload...\n");
+		ret = state->config->request_firmware(fe, &fw, NXT2002_DEFAULT_FIRMWARE);
+		printk("nxt2002: Waiting for firmware upload(2)...\n");
+		if (ret) {
+			printk("nxt2002: no firmware upload (timeout or file not found?)\n");
+			return ret;
+		}
+
+		ret = nxt2002_load_firmware(fe, fw);
+		if (ret) {
+			printk("nxt2002: writing firmware to device failed\n");
+			release_firmware(fw);
+			return ret;
+		}
+
+		/* Put the micro into reset */
+		nxt2002_microcontroller_stop(state);
+ 
+		/* ensure transfer is complete */
+		buf[0]=0;
+		i2c_writebytes(state,0x2B,buf,1);
+
+		/* Put the micro into reset for real this time */
+		nxt2002_microcontroller_stop(state);
+
+		/* soft reset everything (agc,frontend,eq,fec)*/
+		buf[0] = 0x0F;
+		i2c_writebytes(state,0x08,buf,1);
+		buf[0] = 0x00;
+		i2c_writebytes(state,0x08,buf,1);
+
+		/* write agc sdm configure */
+		buf[0] = 0xF1;		
+		i2c_writebytes(state,0x57,buf,1);
+
+		/* write mod output format */
+		buf[0] = 0x20;		
+		i2c_writebytes(state,0x09,buf,1);
+
+		/* write fec mpeg mode */
+		buf[0] = 0x7E;
+		buf[1] = 0x00;
+		i2c_writebytes(state,0xE9,buf,2);
+
+		/* write mux selection */
+		buf[0] = 0x00;
+		i2c_writebytes(state,0xCC,buf,1);
+
+		state->initialised = 1;
+	}
+
+	return 0;
+}
+
+static int nxt2002_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
+{
+	fesettings->min_delay_ms = 500;
+	fesettings->step_size = 0;
+	fesettings->max_drift = 0;
+	return 0;
+}
+
+static void nxt2002_release(struct dvb_frontend* fe)
+{
+	struct nxt2002_state* state = (struct nxt2002_state*) fe->demodulator_priv;
+	kfree(state);
+}
+
+static struct dvb_frontend_ops nxt2002_ops;
+
+struct dvb_frontend* nxt2002_attach(const struct nxt2002_config* config,
+				   struct i2c_adapter* i2c)
+{
+	struct nxt2002_state* state = NULL;
+	u8 buf [] = {0,0,0,0,0};
+
+	/* allocate memory for the internal state */
+	state = (struct nxt2002_state*) kmalloc(sizeof(struct nxt2002_state), GFP_KERNEL);
+	if (state == NULL) goto error;
+
+	/* setup the state */
+	state->config = config;
+	state->i2c = i2c;
+	memcpy(&state->ops, &nxt2002_ops, sizeof(struct dvb_frontend_ops));
+	state->initialised = 0;
+
+        /* Check the first 5 registers to ensure this a revision we can handle */
+
+	i2c_readbytes(state, 0x00, buf, 5);
+	if (buf[0] != 0x04) goto error; 		/* device id */
+	if (buf[1] != 0x02) goto error; 		/* fab id */
+	if (buf[2] != 0x11) goto error; 		/* month */
+	if (buf[3] != 0x20) goto error; 		/* year msb */
+	if (buf[4] != 0x00) goto error; 		/* year lsb */
+
+	/* create dvb_frontend */
+	state->frontend.ops = &state->ops;
+	state->frontend.demodulator_priv = state;
+	return &state->frontend;
+
+error:
+	if (state) kfree(state);
+	return NULL;
+}
+
+static struct dvb_frontend_ops nxt2002_ops = {
+
+	.info = {
+		.name = "Nextwave nxt2002 VSB/QAM frontend",
+		.type = FE_ATSC,
+		.frequency_min =  54000000,
+		.frequency_max = 803000000,
+                /* stepsize is just a guess */
+		.frequency_stepsize = 166666,	
+		.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 
+	},
+
+	.release = nxt2002_release,
+
+	.init = nxt2002_init,
+	.sleep = nxt2002_sleep,
+
+	.set_frontend = nxt2002_setup_frontend_parameters,
+	.get_tune_settings = nxt2002_get_tune_settings,
+
+	.read_status = nxt2002_read_status,
+	.read_ber = nxt2002_read_ber,
+	.read_signal_strength = nxt2002_read_signal_strength,
+	.read_snr = nxt2002_read_snr,
+	.read_ucblocks = nxt2002_read_ucblocks,
+
+};
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
+
+MODULE_DESCRIPTION("NXT2002 ATSC (8VSB & ITU J83 AnnexB FEC QAM64/256) demodulator driver");
+MODULE_AUTHOR("Taylor Jacob");
+MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(nxt2002_attach);
diff -Nru a/drivers/media/dvb/frontends/nxt2002.h b/drivers/media/dvb/frontends/nxt2002.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/media/dvb/frontends/nxt2002.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,23 @@
+/*
+   Driver for the Nxt2002 demodulator
+*/
+
+#ifndef NXT2002_H
+#define NXT2002_H
+
+#include <linux/dvb/frontend.h>
+#include <linux/firmware.h>
+
+struct nxt2002_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* nxt2002_attach(const struct nxt2002_config* config,
+					  struct i2c_adapter* i2c);
+
+#endif // NXT2002_H
diff -Nru a/drivers/media/dvb/frontends/sp8870.c b/drivers/media/dvb/frontends/sp8870.c
--- a/drivers/media/dvb/frontends/sp8870.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/media/dvb/frontends/sp8870.c	2005-03-01 23:39:17 -08:00
@@ -313,7 +313,7 @@
 
 
 	/* request the firmware, this will block until someone uploads it */
-	printk("sp8870: waiting for firmware upload...\n");
+	printk("sp8870: waiting for firmware upload (%s)...\n", SP8870_DEFAULT_FIRMWARE);
 	if (state->config->request_firmware(fe, &fw, SP8870_DEFAULT_FIRMWARE)) {
 		printk("sp8870: no firmware upload (timeout or file not found?)\n");
 		release_firmware(fw);
@@ -325,6 +325,7 @@
 		release_firmware(fw);
 		return -EIO;
 	}
+	printk("sp8870: firmware upload complete\n");
 
 	/* enable TS output and interface pins */
 	sp8870_writereg(state, 0xc18, 0x00d);
diff -Nru a/drivers/media/dvb/frontends/sp887x.c b/drivers/media/dvb/frontends/sp887x.c
--- a/drivers/media/dvb/frontends/sp887x.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/media/dvb/frontends/sp887x.c	2005-03-01 23:39:08 -08:00
@@ -518,7 +518,7 @@
 
 	if (!state->initialised) {
 	/* request the firmware, this will block until someone uploads it */
-	printk("sp887x: waiting for firmware upload...\n");
+		printk("sp887x: waiting for firmware upload (%s)...\n", SP887X_DEFAULT_FIRMWARE);
 		ret = state->config->request_firmware(fe, &fw, SP887X_DEFAULT_FIRMWARE);
 	if (ret) {
 		printk("sp887x: no firmware upload (timeout or file not found?)\n");
@@ -531,6 +531,7 @@
 			release_firmware(fw);
 			return ret;
 	}
+		printk("sp887x: firmware upload complete\n");
 		state->initialised = 1;
 	}
 
diff -Nru a/drivers/media/dvb/frontends/stv0297.c b/drivers/media/dvb/frontends/stv0297.c
--- a/drivers/media/dvb/frontends/stv0297.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/media/dvb/frontends/stv0297.c	2005-03-01 23:38:53 -08:00
@@ -38,10 +38,7 @@
 
         struct dvb_frontend frontend;
 
-        int freq_off;
-
 	unsigned long base_freq;
-
 	u8 pwm;
 };
 
@@ -162,8 +159,10 @@
         int ret;
         u8 b0[] = { reg };
         u8 b1[] = { 0 };
-        struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 },
-                                  { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
+	struct i2c_msg msg[] = { {.addr = state->config->demod_address,.flags = 0,.buf = b0,.len =
+				  1},
+	{.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = b1,.len = 1}
+	};
 
         // this device needs a STOP between the register and data
         if ((ret = i2c_transfer (state->i2c, &msg[0], 1)) != 1) {
@@ -193,8 +192,10 @@
 static int stv0297_readregs (struct stv0297_state* state, u8 reg1, u8 *b, u8 len)
 {
         int ret;
-        struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = &reg1, .len = 1 },
-                                  { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b, .len = len } };
+	struct i2c_msg msg[] = { {.addr = state->config->demod_address,.flags = 0,.buf =
+				  &reg1,.len = 1},
+	{.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = b,.len = len}
+	};
 
         // this device needs a STOP between the register and data
         if ((ret = i2c_transfer (state->i2c, &msg[0], 1)) != 1) {
@@ -209,6 +210,21 @@
         return 0;
 }
 
+static u32 stv0297_get_symbolrate(struct stv0297_state *state)
+{
+	u64 tmp;
+
+	tmp = stv0297_readreg(state, 0x55);
+	tmp |= stv0297_readreg(state, 0x56) << 8;
+	tmp |= stv0297_readreg(state, 0x57) << 16;
+	tmp |= stv0297_readreg(state, 0x58) << 24;
+
+	tmp *= STV0297_CLOCK_KHZ;
+	tmp >>= 32;
+
+	return (u32) tmp;
+}
+
 static void stv0297_set_symbolrate(struct stv0297_state *state, u32 srate)
 {
 	long tmp;
@@ -259,39 +275,40 @@
 	stv0297_writereg_mask(state, 0x69, 0x0F, (tmp >> 24) & 0x0f);
 }
 
+/*
 static long stv0297_get_carrieroffset(struct stv0297_state* state)
 {
-        s32 raw;
-	long tmp;
+	s64 tmp;
 
         stv0297_writereg(state,0x6B, 0x00);
 
-        raw =   stv0297_readreg(state,0x66);
-        raw |= (stv0297_readreg(state,0x67) << 8);
-        raw |= (stv0297_readreg(state,0x68) << 16);
-        raw |= (stv0297_readreg(state,0x69) & 0x0F) << 24;
+	tmp = stv0297_readreg(state, 0x66);
+	tmp |= (stv0297_readreg(state, 0x67) << 8);
+	tmp |= (stv0297_readreg(state, 0x68) << 16);
+	tmp |= (stv0297_readreg(state, 0x69) & 0x0F) << 24;
 
-        tmp = raw;
-	tmp /= 26844L;
+	tmp *= stv0297_get_symbolrate(state);
+	tmp >>= 28;
 
-	return tmp;
+	return (s32) tmp;
 }
+*/
 
 static void stv0297_set_initialdemodfreq(struct stv0297_state* state, long freq)
 {
-/*
-        s64 tmp;
+	s32 tmp;
 
-        if (freq > 10000) freq -= STV0297_CLOCK_KHZ;
+	if (freq > 10000)
+		freq -= STV0297_CLOCK_KHZ;
 
-        tmp = freq << 16;
-        do_div(tmp, STV0297_CLOCK_KHZ);
-        if (tmp > 0xffff) tmp = 0xffff; // check this calculation
+	tmp = (STV0297_CLOCK_KHZ * 1000) / (1 << 16);
+	tmp = (freq * 1000) / tmp;
+	if (tmp > 0xffff)
+		tmp = 0xffff;
 
         stv0297_writereg_mask(state, 0x25, 0x80, 0x80);
         stv0297_writereg(state, 0x21, tmp >> 8);
         stv0297_writereg(state, 0x20, tmp);
-*/
 }
 
 static int stv0297_set_qam(struct stv0297_state* state, fe_modulation_t modulation)
@@ -413,6 +430,15 @@
         return 0;
 }
 
+static int stv0297_sleep(struct dvb_frontend *fe)
+{
+	struct stv0297_state *state = (struct stv0297_state *) fe->demodulator_priv;
+
+	stv0297_writereg_mask(state, 0x80, 1, 1);
+
+	return 0;
+}
+
 static int stv0297_read_status(struct dvb_frontend* fe, fe_status_t* status)
 {
         struct stv0297_state* state = (struct stv0297_state*) fe->demodulator_priv;
@@ -484,6 +510,7 @@
         int carrieroffset;
         unsigned long starttime;
         unsigned long timeout;
+	fe_spectral_inversion_t inversion;
 
         switch(p->u.qam.modulation) {
         case QAM_16:
@@ -508,8 +535,11 @@
         }
 
         // determine inversion dependant parameters
+	inversion = p->inversion;
+	if (state->config->invert)
+		inversion = (inversion == INVERSION_ON) ? INVERSION_OFF : INVERSION_ON;
         carrieroffset = -330;
-        switch(p->inversion) {
+	switch (inversion) {
         case INVERSION_OFF:
           break;
 
@@ -522,13 +552,14 @@
           return -EINVAL;
         }
 
+	stv0297_init(fe);
         state->config->pll_set(fe, p);
 
 	/* clear software interrupts */
 	stv0297_writereg(state, 0x82, 0x0);
 
 	/* set initial demodulation frequency */
-        stv0297_set_initialdemodfreq(state, state->freq_off + 7250);
+	stv0297_set_initialdemodfreq(state, 7250);
 
 	/* setup AGC */
         stv0297_writereg_mask(state, 0x43, 0x10, 0x00);
@@ -588,7 +619,7 @@
         stv0297_set_symbolrate(state, p->u.qam.symbol_rate/1000);
 	stv0297_set_sweeprate(state, sweeprate, p->u.qam.symbol_rate / 1000);
         stv0297_set_carrieroffset(state, carrieroffset);
-        stv0297_set_inversion(state, p->inversion);
+	stv0297_set_inversion(state, inversion);
 
 	/* kick off lock */
         stv0297_writereg_mask(state, 0x88, 0x08, 0x08);
@@ -664,7 +695,6 @@
 
 	/* success!! */
         stv0297_writereg_mask(state, 0x5a, 0x40, 0x00);
-        state->freq_off = stv0297_get_carrieroffset(state);
         state->base_freq = p->frequency;
         return 0;
 
@@ -681,10 +711,12 @@
         reg_00 = stv0297_readreg(state, 0x00);
         reg_83 = stv0297_readreg(state, 0x83);
 
-        p->frequency = state->base_freq + state->freq_off;
+	p->frequency = state->base_freq;
         p->inversion = (reg_83 & 0x08) ? INVERSION_ON : INVERSION_OFF;
-	p->u.qam.symbol_rate = 0;
-        p->u.qam.fec_inner = 0;
+	if (state->config->invert)
+		p->inversion = (p->inversion == INVERSION_ON) ? INVERSION_OFF : INVERSION_ON;
+	p->u.qam.symbol_rate = stv0297_get_symbolrate(state) * 1000;
+	p->u.qam.fec_inner = FEC_NONE;
 
         switch((reg_00 >> 4) & 0x7) {
 	case 0:
@@ -729,7 +761,6 @@
         state->config = config;
         state->i2c = i2c;
         memcpy(&state->ops, &stv0297_ops, sizeof(struct dvb_frontend_ops));
-        state->freq_off = 0;
         state->base_freq = 0;
         state->pwm = pwm;
 
@@ -764,6 +795,7 @@
         .release = stv0297_release,
 
         .init = stv0297_init,
+	.sleep = stv0297_sleep,
 
         .set_frontend = stv0297_set_frontend,
         .get_frontend = stv0297_get_frontend,
diff -Nru a/drivers/media/dvb/frontends/stv0297.h b/drivers/media/dvb/frontends/stv0297.h
--- a/drivers/media/dvb/frontends/stv0297.h	2005-03-01 23:38:56 -08:00
+++ b/drivers/media/dvb/frontends/stv0297.h	2005-03-01 23:38:56 -08:00
@@ -29,6 +29,9 @@
 	/* the demodulator's i2c address */
 	u8 demod_address;
 
+	/* does the "inversion" need inverted? */
+	u8 invert:1;
+
 	/* PLL maintenance */
 	int (*pll_init)(struct dvb_frontend* fe);
 	int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
diff -Nru a/drivers/media/dvb/frontends/tda10021.c b/drivers/media/dvb/frontends/tda10021.c
--- a/drivers/media/dvb/frontends/tda10021.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/media/dvb/frontends/tda10021.c	2005-03-01 23:39:18 -08:00
@@ -4,7 +4,7 @@
 
     Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
     Copyright (C) 2004 Markus Schulz <msc@antzsystem.de>
-                   Suppport for TDA10021
+                   Support for TDA10021
 
     This 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 -Nru a/drivers/media/dvb/frontends/tda10021.h b/drivers/media/dvb/frontends/tda10021.h
--- a/drivers/media/dvb/frontends/tda10021.h	2005-03-01 23:38:53 -08:00
+++ b/drivers/media/dvb/frontends/tda10021.h	2005-03-01 23:38:53 -08:00
@@ -4,7 +4,7 @@
 
     Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
     Copyright (C) 2004 Markus Schulz <msc@antzsystem.de>
-                   Suppport for TDA10021
+                   Support for TDA10021
 
     This 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 -Nru a/drivers/media/dvb/frontends/tda80xx.c b/drivers/media/dvb/frontends/tda80xx.c
--- a/drivers/media/dvb/frontends/tda80xx.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/media/dvb/frontends/tda80xx.c	2005-03-01 23:39:07 -08:00
@@ -27,7 +27,7 @@
 #include <linux/spinlock.h>
 #include <linux/threads.h>
 #include <linux/interrupt.h>
-#include <linux/irq.h>
+#include <asm/irq.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/slab.h>
diff -Nru a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c
--- a/drivers/media/dvb/ttpci/av7110.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/media/dvb/ttpci/av7110.c	2005-03-01 23:39:07 -08:00
@@ -67,6 +67,12 @@
 #include "av7110_ca.h"
 #include "av7110_ipack.h"
 
+#define TS_WIDTH  376
+#define TS_HEIGHT 512
+#define TS_BUFLEN (TS_WIDTH*TS_HEIGHT)
+#define TS_MAX_PACKETS (TS_BUFLEN/TS_SIZE)
+
+
 int av7110_debug;
 
 static int vidmode=CVBS_RGB_OUT;
@@ -75,6 +81,7 @@
 static int hw_sections;
 static int rgb_on;
 static int volume = 255;
+static int budgetpatch = 0;
 
 module_param_named(debug, av7110_debug, int, 0644);
 MODULE_PARM_DESC(debug, "debug level (bitmask, default 0)");
@@ -91,6 +98,8 @@
 		" signal on SCART pin 16 to switch SCART video mode from CVBS to RGB");
 module_param(volume, int, 0444);
 MODULE_PARM_DESC(volume, "initial volume: default 255 (range 0-255)");
+module_param(budgetpatch, int, 0444);
+MODULE_PARM_DESC(budgetpatch, "use budget-patch hardware modification: default 0 (0 no, 1 autodetect, 2 always)");
 
 static void restart_feeds(struct av7110 *av7110);
 
@@ -349,27 +358,42 @@
 #endif
 }
 
+#define DEBI_READ 0
+#define DEBI_WRITE 1
+static inline void start_debi_dma(struct av7110 *av7110, int dir,
+				  unsigned long addr, unsigned int len)
+{
+	dprintk(8, "%c %08lx %u\n", dir == DEBI_READ ? 'R' : 'W', addr, len);
+	if (saa7146_wait_for_debi_done(av7110->dev, 0)) {
+		printk(KERN_ERR "%s: saa7146_wait_for_debi_done timed out\n", __FUNCTION__);
+		return;
+	}
+
+	SAA7146_ISR_CLEAR(av7110->dev, MASK_19); /* for good measure */
+	SAA7146_IER_ENABLE(av7110->dev, MASK_19);
+	if (len < 5)
+		len = 5; /* we want a real DEBI DMA */
+	if (dir == DEBI_WRITE)
+		iwdebi(av7110, DEBISWAB, addr, 0, (len + 3) & ~3);
+	else
+		irdebi(av7110, DEBISWAB, addr, 0, len);
+}
+
 static void debiirq (unsigned long data)
 {
 	struct av7110 *av7110 = (struct av7110*) data;
         int type=av7110->debitype;
         int handle=(type>>8)&0x1f;
-	
-//	dprintk(4, "%p\n",av7110);
+	unsigned int xfer = 0;
 
         print_time("debi");
-	SAA7146_IER_DISABLE(av7110->dev, MASK_19);
-	SAA7146_ISR_CLEAR(av7110->dev, MASK_19);
+	dprintk(4, "type 0x%04x\n", type);
 
         if (type==-1) {
 		printk("DEBI irq oops @ %ld, psr:0x%08x, ssr:0x%08x\n",
 		       jiffies, saa7146_read(av7110->dev, PSR),
 		       saa7146_read(av7110->dev, SSR));
-		spin_lock(&av7110->debilock);
-                ARM_ClearMailBox(av7110);
-                ARM_ClearIrq(av7110);
-		spin_unlock(&av7110->debilock);
-                return;
+		goto debi_done;
         }
         av7110->debitype=-1;
 
@@ -379,22 +403,16 @@
                 dvb_dmx_swfilter_packets(&av7110->demux, 
                                       (const u8 *)av7110->debi_virt, 
                                       av7110->debilen/188);
-                spin_lock(&av7110->debilock);
-                iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
-                ARM_ClearMailBox(av7110);
-                spin_unlock(&av7110->debilock);
-                return;
+		xfer = RX_BUFF;
+		break;
 
         case DATA_PES_RECORD:
                 if (av7110->demux.recording) 
 			av7110_record_cb(&av7110->p2t[handle],
                                   (u8 *)av7110->debi_virt,
                                   av7110->debilen);
-                spin_lock(&av7110->debilock);
-                iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
-                ARM_ClearMailBox(av7110);
-                spin_unlock(&av7110->debilock);
-                return;
+		xfer = RX_BUFF;
+		break;
 
         case DATA_IPMPE:
         case DATA_FSECTION:
@@ -404,11 +422,8 @@
                                              av7110->debilen, NULL, 0, 
                                              av7110->handle2filter[handle], 
                                              DMX_OK, av7110); 
-                spin_lock(&av7110->debilock);
-                iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
-                ARM_ClearMailBox(av7110);
-                spin_unlock(&av7110->debilock);
-                return;
+		xfer = RX_BUFF;
+		break;
 
         case DATA_CI_GET:
         {
@@ -425,11 +440,8 @@
                         ci_get_data(&av7110->ci_rbuffer, 
                                     av7110->debi_virt, 
                                     av7110->debilen);
-                spin_lock(&av7110->debilock);
-                iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
-                ARM_ClearMailBox(av7110);
-                spin_unlock(&av7110->debilock);
-                return;
+		xfer = RX_BUFF;
+		break;
         }
 
         case DATA_COMMON_INTERFACE:
@@ -449,37 +461,35 @@
                 printk("\n");
         }
 #endif
-                spin_lock(&av7110->debilock);
-                iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
-                ARM_ClearMailBox(av7110);
-                spin_unlock(&av7110->debilock);
-                return;
+		xfer = RX_BUFF;
+		break;
 
         case DATA_DEBUG_MESSAGE:
                 ((s8*)av7110->debi_virt)[Reserved_SIZE-1]=0;
                 printk("%s\n", (s8 *)av7110->debi_virt);
-                spin_lock(&av7110->debilock);
-                iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
-                ARM_ClearMailBox(av7110);
-                spin_unlock(&av7110->debilock);
-                return;
+		xfer = RX_BUFF;
+		break;
 
         case DATA_CI_PUT:
+		dprintk(4, "debi DATA_CI_PUT\n");
         case DATA_MPEG_PLAY:
+		dprintk(4, "debi DATA_MPEG_PLAY\n");
         case DATA_BMP_LOAD:
-                spin_lock(&av7110->debilock);
-                iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
-                ARM_ClearMailBox(av7110);
-                spin_unlock(&av7110->debilock);
-                return;
+		dprintk(4, "debi DATA_BMP_LOAD\n");
+		xfer = TX_BUFF;
+		break;
         default:
                 break;
         }
+debi_done:
         spin_lock(&av7110->debilock);
+	if (xfer)
+		iwdebi(av7110, DEBINOSWAP, xfer, 0, 2);
         ARM_ClearMailBox(av7110);
         spin_unlock(&av7110->debilock);
 }
 
+/* irq from av7110 firmware writing the mailbox register in the DPRAM */
 static void gpioirq (unsigned long data)
 {
 	struct av7110 *av7110 = (struct av7110*) data;
@@ -487,27 +497,29 @@
         int len;
         
         if (av7110->debitype !=-1)
+		/* we shouldn't get any irq while a debi xfer is running */
 		printk("dvb-ttpci: GPIO0 irq oops @ %ld, psr:0x%08x, ssr:0x%08x\n",
 		       jiffies, saa7146_read(av7110->dev, PSR),
 		       saa7146_read(av7110->dev, SSR));
        
-        spin_lock(&av7110->debilock);
+	if (saa7146_wait_for_debi_done(av7110->dev, 0)) {
+		printk(KERN_ERR "%s: saa7146_wait_for_debi_done timed out\n", __FUNCTION__);
+		BUG(); /* maybe we should try resetting the debi? */
+	}
 
+	spin_lock(&av7110->debilock);
 	ARM_ClearIrq(av7110);
 
-	SAA7146_IER_DISABLE(av7110->dev, MASK_19);
-	SAA7146_ISR_CLEAR(av7110->dev, MASK_19);
-
+	/* see what the av7110 wants */
         av7110->debitype = irdebi(av7110, DEBINOSWAP, IRQ_STATE, 0, 2);
         av7110->debilen  = irdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
         rxbuf=irdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
         txbuf=irdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
 	len = (av7110->debilen + 3) & ~3;
 
-//	dprintk(8, "GPIO0 irq %d %d\n", av7110->debitype, av7110->debilen);
         print_time("gpio");
+	dprintk(8, "GPIO0 irq 0x%04x %d\n", av7110->debitype, av7110->debilen);
 
-//	dprintk(8, "GPIO0 irq %02x\n", av7110->debitype&0xff);
         switch (av7110->debitype&0xff) {
 
         case DATA_TS_PLAY:
@@ -579,16 +591,12 @@
 
                 dvb_ringbuffer_read(cibuf,av7110->debi_virt,len,0);
 
-                wake_up(&cibuf->queue);
                 iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2);
                 iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, len, 2);
-		saa7146_wait_for_debi_done(av7110->dev, 0);
-                saa7146_write(av7110->dev, IER, 
-                              saa7146_read(av7110->dev, IER) | MASK_19 );
-		if (len < 5)
-			len = 5; /* we want a real DEBI DMA */
-                iwdebi(av7110, DEBISWAB, DPRAM_BASE+txbuf, 0, (len+3)&~3);
+		dprintk(8, "DMA: CI\n");
+		start_debi_dma(av7110, DEBI_WRITE, DPRAM_BASE + txbuf, len);
                 spin_unlock(&av7110->debilock);
+		wake_up(&cibuf->queue);
                 return;
         }
 
@@ -620,22 +628,21 @@
 		dprintk(8, "GPIO0 PES_PLAY len=%04x\n", len);
                 iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2);
                 iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, len, 2);
-		saa7146_wait_for_debi_done(av7110->dev, 0);
-                saa7146_write(av7110->dev, IER, 
-                              saa7146_read(av7110->dev, IER) | MASK_19 );
-
-                iwdebi(av7110, DEBISWAB, DPRAM_BASE+txbuf, 0, (len+3)&~3);
+		dprintk(8, "DMA: MPEG_PLAY\n");
+		start_debi_dma(av7110, DEBI_WRITE, DPRAM_BASE + txbuf, len);
                 spin_unlock(&av7110->debilock);
                 return;
 
         case DATA_BMP_LOAD:
                 len=av7110->debilen;
+		dprintk(8, "gpio DATA_BMP_LOAD len %d\n", len);
                 if (!len) {
                         av7110->bmp_state=BMP_LOADED;
                         iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
                         iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2);
                         iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
                         wake_up(&av7110->bmpq);
+			dprintk(8, "gpio DATA_BMP_LOAD done\n");
                         break;
                 }
                 if (len>av7110->bmplen)
@@ -647,12 +654,8 @@
                 memcpy(av7110->debi_virt, av7110->bmpbuf+av7110->bmpp, len);
                 av7110->bmpp+=len;
                 av7110->bmplen-=len;
-		saa7146_wait_for_debi_done(av7110->dev, 0);
-                saa7146_write(av7110->dev, IER, 
-                              saa7146_read(av7110->dev, IER) | MASK_19 );
-		if (len < 5)
-			len = 5; /* we want a real DEBI DMA */
-                iwdebi(av7110, DEBISWAB, DPRAM_BASE+txbuf, 0, (len+3)&~3);
+		dprintk(8, "gpio DATA_BMP_LOAD DMA len %d\n", len);
+		start_debi_dma(av7110, DEBI_WRITE, DPRAM_BASE+txbuf, len);
                 spin_unlock(&av7110->debilock);
                 return;
 
@@ -669,22 +672,17 @@
 
         case DATA_TS_RECORD:
         case DATA_PES_RECORD:
-		saa7146_wait_for_debi_done(av7110->dev, 0);
-                saa7146_write(av7110->dev, IER, 
-                              saa7146_read(av7110->dev, IER) | MASK_19);
-                irdebi(av7110, DEBISWAB, DPRAM_BASE+rxbuf, 0, len);
+		dprintk(8, "DMA: TS_REC etc.\n");
+		start_debi_dma(av7110, DEBI_READ, DPRAM_BASE+rxbuf, len);
                 spin_unlock(&av7110->debilock);
                 return;
 
         case DATA_DEBUG_MESSAGE:
-		saa7146_wait_for_debi_done(av7110->dev, 0);
                 if (!len || len>0xff) {
                         iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
                         break;
                 }
-                saa7146_write(av7110->dev, IER, 
-                              saa7146_read(av7110->dev, IER) | MASK_19);
-                irdebi(av7110, DEBISWAB, Reserved, 0, len);
+		start_debi_dma(av7110, DEBI_READ, Reserved, len);
                 spin_unlock(&av7110->debilock);
                 return;
 
@@ -699,8 +697,8 @@
                        av7110->debitype, av7110->debilen);
                 break;
         }      
-        ARM_ClearMailBox(av7110);
         av7110->debitype=-1;
+	ARM_ClearMailBox(av7110);
         spin_unlock(&av7110->debilock);
 }
 
@@ -1145,11 +1143,107 @@
 	return 0;
 }
 
+/* simplified code from budget-core.c */
+static int stop_ts_capture(struct av7110 *budget)
+{
+	dprintk(2, "budget: %p\n", budget);
+
+	if (--budget->feeding1)
+		return budget->feeding1;
+	saa7146_write(budget->dev, MC1, MASK_20);	/* DMA3 off */
+	SAA7146_IER_DISABLE(budget->dev, MASK_10);
+	SAA7146_ISR_CLEAR(budget->dev, MASK_10);
+	return 0;
+}
+
+static int start_ts_capture(struct av7110 *budget)
+{
+	dprintk(2, "budget: %p\n", budget);
+
+	if (budget->feeding1)
+		return ++budget->feeding1;
+	memset(budget->grabbing, 0x00, TS_HEIGHT * TS_WIDTH);
+	budget->tsf = 0xff;
+	budget->ttbp = 0;
+	SAA7146_IER_ENABLE(budget->dev, MASK_10); /* VPE */
+	saa7146_write(budget->dev, MC1, (MASK_04 | MASK_20)); /* DMA3 on */
+	return ++budget->feeding1;
+}
+
+static int budget_start_feed(struct dvb_demux_feed *feed)
+{
+	struct dvb_demux *demux = feed->demux;
+	struct av7110 *budget = (struct av7110 *) demux->priv;
+	int status;
+
+	dprintk(2, "av7110: %p\n", budget);
+
+	spin_lock(&budget->feedlock1);
+	feed->pusi_seen = 0; /* have a clean section start */
+	status = start_ts_capture(budget);
+	spin_unlock(&budget->feedlock1);
+	return status;
+}
+
+static int budget_stop_feed(struct dvb_demux_feed *feed)
+{
+	struct dvb_demux *demux = feed->demux;
+	struct av7110 *budget = (struct av7110 *) demux->priv;
+	int status;
+
+	dprintk(2, "budget: %p\n", budget);
+
+	spin_lock(&budget->feedlock1);
+	status = stop_ts_capture(budget);
+	spin_unlock(&budget->feedlock1);
+	return status;
+}
+
+static void vpeirq(unsigned long data)
+{
+	struct av7110 *budget = (struct av7110 *) data;
+	u8 *mem = (u8 *) (budget->grabbing);
+	u32 olddma = budget->ttbp;
+	u32 newdma = saa7146_read(budget->dev, PCI_VDP3);
+
+	if (!budgetpatch) {
+		printk("av7110.c: vpeirq() called while budgetpatch disabled!"
+		       " check saa7146 IER register\n");
+		BUG();
+	}
+	/* nearest lower position divisible by 188 */
+	newdma -= newdma % 188;
+
+	if (newdma >= TS_BUFLEN)
+		return;
+
+	budget->ttbp = newdma;
+
+	if (!budget->feeding1 || (newdma == olddma))
+		return;
+
+#if 0
+	/* track rps1 activity */
+	printk("vpeirq: %02x Event Counter 1 0x%04x\n",
+	       mem[olddma],
+	       saa7146_read(budget->dev, EC1R) & 0x3fff);
+#endif
+
+	if (newdma > olddma)
+		/* no wraparound, dump olddma..newdma */
+		dvb_dmx_swfilter_packets(&budget->demux1, mem + olddma, (newdma - olddma) / 188);
+	else {
+		/* wraparound, dump olddma..buflen and 0..newdma */
+		dvb_dmx_swfilter_packets(&budget->demux1, mem + olddma, (TS_BUFLEN - olddma) / 188);
+		dvb_dmx_swfilter_packets(&budget->demux1, mem, newdma / 188);
+	}
+}
 
 static int av7110_register(struct av7110 *av7110)
 {
         int ret, i;
         struct dvb_demux *dvbdemux=&av7110->demux;
+	struct dvb_demux *dvbdemux1 = &av7110->demux1;
 
 	dprintk(4, "%p\n", av7110);
 
@@ -1209,6 +1303,32 @@
         
         dvb_net_init(av7110->dvb_adapter, &av7110->dvb_net, &dvbdemux->dmx);
 
+	if (budgetpatch) {
+		/* initialize software demux1 without its own frontend
+		 * demux1 hardware is connected to frontend0 of demux0
+		 */
+		dvbdemux1->priv = (void *) av7110;
+
+		dvbdemux1->filternum = 256;
+		dvbdemux1->feednum = 256;
+		dvbdemux1->start_feed = budget_start_feed;
+		dvbdemux1->stop_feed = budget_stop_feed;
+		dvbdemux1->write_to_decoder = NULL;
+
+		dvbdemux1->dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING |
+					       DMX_MEMORY_BASED_FILTERING);
+
+		dvb_dmx_init(&av7110->demux1);
+
+		av7110->dmxdev1.filternum = 256;
+		av7110->dmxdev1.demux = &dvbdemux1->dmx;
+		av7110->dmxdev1.capabilities = 0;
+
+		dvb_dmxdev_init(&av7110->dmxdev1, av7110->dvb_adapter);
+
+		dvb_net_init(av7110->dvb_adapter, &av7110->dvb_net1, &dvbdemux1->dmx);
+		printk("dvb-ttpci: additional demux1 for budget-patch registered\n");
+	}
 	return 0;
 }
 
@@ -1216,12 +1336,20 @@
 static void dvb_unregister(struct av7110 *av7110)
 {
         struct dvb_demux *dvbdemux=&av7110->demux;
+	struct dvb_demux *dvbdemux1 = &av7110->demux1;
 
 	dprintk(4, "%p\n", av7110);
 
         if (!av7110->registered)
                 return;
 
+	if (budgetpatch) {
+		dvb_net_release(&av7110->dvb_net1);
+		dvbdemux->dmx.close(&dvbdemux1->dmx);
+		dvb_dmxdev_release(&av7110->dmxdev1);
+		dvb_dmx_release(&av7110->demux1);
+	}
+
 	dvb_net_release(&av7110->dvb_net);
 
 	dvbdemux->dmx.close(&dvbdemux->dmx);
@@ -1700,6 +1828,7 @@
 static struct stv0297_config nexusca_stv0297_config = {
 
 	.demod_address = 0x1C,
+	.invert = 1,
 	.pll_set = nexusca_stv0297_pll_set,
 };
 
@@ -1899,12 +2028,22 @@
                         av7110->fe = ves1820_attach(&alps_tdbe2_config, &av7110->i2c_adap, read_pwm(av7110));
 			break;
 
+		case 0x0006: /* Fujitsu-Siemens DVB-S rev 1.6 */
+			/* Grundig 29504-451 */
+			av7110->fe = tda8083_attach(&grundig_29504_451_config, &av7110->i2c_adap);
+			if (av7110->fe) {
+				av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
+				av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst;
+				av7110->fe->ops->set_tone = av7110_set_tone;
+			}
+			break;
+
 		case 0x000A: // Hauppauge/TT Nexus-CA rev1.X
 
 			av7110->fe = stv0297_attach(&nexusca_stv0297_config, &av7110->i2c_adap, 0x7b);
 			if (av7110->fe) {
 				/* set TDA9819 into DVB mode */
-				saa7146_setgpio(av7110->dev, 1, SAA7146_GPIO_OUTHI); // TDA9198 pin9(STD)
+				saa7146_setgpio(av7110->dev, 1, SAA7146_GPIO_OUTLO); // TDA9198 pin9(STD)
 				saa7146_setgpio(av7110->dev, 3, SAA7146_GPIO_OUTLO); // TDA9198 pin30(VIF)
 
 				/* tuner on this needs a slower i2c bus speed */
@@ -1940,13 +2079,169 @@
 	}
 }
 
+/* Budgetpatch note:
+ * Original hardware design by Roberto Deza:
+ * There is a DVB_Wiki at
+ * http://212.227.36.83/linuxtv/wiki/index.php/Main_Page
+ * where is described this 'DVB TT Budget Patch', on Card Modding:
+ * http://212.227.36.83/linuxtv/wiki/index.php/DVB_TT_Budget_Patch
+ * On the short description there is also a link to a external file,
+ * with more details:
+ * http://perso.wanadoo.es/jesussolano/Ttf_tsc1.zip
+ *
+ * New software triggering design by Emard that works on
+ * original Roberto Deza's hardware:
+ *
+ * rps1 code for budgetpatch will copy internal HS event to GPIO3 pin.
+ * GPIO3 is in budget-patch hardware connectd to port B VSYNC
+ * HS is an internal event of 7146, accessible with RPS
+ * and temporarily raised high every n lines
+ * (n in defined in the RPS_THRESH1 counter threshold)
+ * I think HS is raised high on the beginning of the n-th line
+ * and remains high until this n-th line that triggered
+ * it is completely received. When the receiption of n-th line
+ * ends, HS is lowered.
+ *
+ * To transmit data over DMA, 7146 needs changing state at
+ * port B VSYNC pin. Any changing of port B VSYNC will
+ * cause some DMA data transfer, with more or less packets loss.
+ * It depends on the phase and frequency of VSYNC and
+ * the way of 7146 is instructed to trigger on port B (defined
+ * in DD1_INIT register, 3rd nibble from the right valid
+ * numbers are 0-7, see datasheet)
+ *
+ * The correct triggering can minimize packet loss,
+ * dvbtraffic should give this stable bandwidths:
+ *   22k transponder = 33814 kbit/s
+ * 27.5k transponder = 38045 kbit/s
+ * by experiment it is found that the best results
+ * (stable bandwidths and almost no packet loss)
+ * are obtained using DD1_INIT triggering number 2
+ * (Va at rising edge of VS Fa = HS x VS-failing forced toggle)
+ * and a VSYNC phase that occurs in the middle of DMA transfer
+ * (about byte 188*512=96256 in the DMA window).
+ *
+ * Phase of HS is still not clear to me how to control,
+ * It just happens to be so. It can be seen if one enables
+ * RPS_IRQ and print Event Counter 1 in vpeirq(). Every
+ * time RPS_INTERRUPT is called, the Event Counter 1 will
+ * increment. That's how the 7146 is programmed to do event
+ * counting in this budget-patch.c
+ * I *think* HPS setting has something to do with the phase
+ * of HS but I cant be 100% sure in that.
+ *
+ * hardware debug note: a working budget card (including budget patch)
+ * with vpeirq() interrupt setup in mode "0x90" (every 64K) will
+ * generate 3 interrupts per 25-Hz DMA frame of 2*188*512 bytes
+ * and that means 3*25=75 Hz of interrupt freqency, as seen by
+ * watch cat /proc/interrupts
+ *
+ * If this frequency is 3x lower (and data received in the DMA
+ * buffer don't start with 0x47, but in the middle of packets,
+ * whose lengths appear to be like 188 292 188 104 etc.
+ * this means VSYNC line is not connected in the hardware.
+ * (check soldering pcb and pins)
+ * The same behaviour of missing VSYNC can be duplicated on budget
+ * cards, by seting DD1_INIT trigger mode 7 in 3rd nibble.
+ */
 static int av7110_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_data *pci_ext)
 {
 	struct av7110 *av7110 = NULL;
+	int length = TS_WIDTH * TS_HEIGHT;
 	int ret = 0;
+	int count = 0;
 
 	dprintk(4, "dev: %p\n", dev);
 
+        /* Set RPS_IRQ to 1 to track rps1 activity.
+         * Enabling this won't send any interrupt to PC CPU.
+         */
+#define RPS_IRQ 0
+
+	if (budgetpatch == 1) {
+		budgetpatch = 0;
+		/* autodetect the presence of budget patch
+		 * this only works if saa7146 has been recently
+		 * reset with with MASK_31 to MC1
+		 *
+		 * will wait for VBI_B event (vertical blank at port B)
+		 * and will reset GPIO3 after VBI_B is detected.
+		 * (GPIO3 should be raised high by CPU to
+		 * test if GPIO3 will generate vertical blank signal
+		 * in budget patch GPIO3 is connected to VSYNC_B
+		 */
+
+		/* RESET SAA7146 */
+		saa7146_write(dev, MC1, MASK_31);
+		/* autodetection success seems to be time-dependend after reset */
+
+		/* Fix VSYNC level */
+		saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
+		/* set vsync_b triggering */
+		saa7146_write(dev, DD1_STREAM_B, 0);
+		/* port B VSYNC at rising edge */
+		saa7146_write(dev, DD1_INIT, 0x00000200);
+		saa7146_write(dev, BRS_CTRL, 0x00000000);  // VBI
+		saa7146_write(dev, MC2,
+			      1 * (MASK_08 | MASK_24)  |   // BRS control
+			      0 * (MASK_09 | MASK_25)  |   // a
+			      1 * (MASK_10 | MASK_26)  |   // b
+			      0 * (MASK_06 | MASK_22)  |   // HPS_CTRL1
+			      0 * (MASK_05 | MASK_21)  |   // HPS_CTRL2
+			      0 * (MASK_01 | MASK_15)      // DEBI
+		);
+
+		/* start writing RPS1 code from beginning */
+		count = 0;
+		/* Disable RPS1 */
+		saa7146_write(dev, MC1, MASK_29);
+		/* RPS1 timeout disable */
+		saa7146_write(dev, RPS_TOV1, 0);
+		WRITE_RPS1(cpu_to_le32(CMD_PAUSE | EVT_VBI_B));
+		WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2)));
+		WRITE_RPS1(cpu_to_le32(GPIO3_MSK));
+		WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTLO<<24));
+#if RPS_IRQ
+		/* issue RPS1 interrupt to increment counter */
+		WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT));
+#endif
+		WRITE_RPS1(cpu_to_le32(CMD_STOP));
+		/* Jump to begin of RPS program as safety measure               (p37) */
+		WRITE_RPS1(cpu_to_le32(CMD_JUMP));
+		WRITE_RPS1(cpu_to_le32(dev->d_rps1.dma_handle));
+
+#if RPS_IRQ
+		/* set event counter 1 source as RPS1 interrupt (0x03)          (rE4 p53)
+		 * use 0x03 to track RPS1 interrupts - increase by 1 every gpio3 is toggled
+		 * use 0x15 to track VPE  interrupts - increase by 1 every vpeirq() is called
+		 */
+		saa7146_write(dev, EC1SSR, (0x03<<2) | 3 );
+		/* set event counter 1 treshold to maximum allowed value        (rEC p55) */
+		saa7146_write(dev, ECT1R,  0x3fff );
+#endif
+		/* Set RPS1 Address register to point to RPS code               (r108 p42) */
+		saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
+		/* Enable RPS1,                                                 (rFC p33) */
+		saa7146_write(dev, MC1, (MASK_13 | MASK_29 ));
+
+		mdelay(10);
+		/* now send VSYNC_B to rps1 by rising GPIO3 */
+		saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
+		mdelay(10);
+		/* if rps1 responded by lowering the GPIO3,
+		 * then we have budgetpatch hardware
+		 */
+		if ((saa7146_read(dev, GPIO_CTRL) & 0x10000000) == 0) {
+			budgetpatch = 1;
+			printk("dvb-ttpci: BUDGET-PATCH DETECTED.\n");
+		}
+		/* Disable RPS1 */
+		saa7146_write(dev, MC1, ( MASK_29 ));
+#if RPS_IRQ
+		printk("dvb-ttpci: Event Counter 1 0x%04x\n", saa7146_read(dev, EC1R) & 0x3fff );
+#endif
+	}
+
 	/* prepare the av7110 device struct */
 	if (!(av7110 = kmalloc (sizeof (struct av7110), GFP_KERNEL))) {
 		dprintk(1, "out of memory\n");
@@ -1980,6 +2275,7 @@
 	saa7146_i2c_adapter_prepare(dev, &av7110->i2c_adap, SAA7146_I2C_BUS_BIT_RATE_120); /* 275 kHz */
 
 	if (i2c_add_adapter(&av7110->i2c_adap) < 0) {
+err_no_mem:
 		dvb_unregister_adapter (av7110->dvb_adapter);
 		kfree(av7110);
 		return -ENOMEM;
@@ -1987,6 +2283,86 @@
 
 	ttpci_eeprom_parse_mac(&av7110->i2c_adap, av7110->dvb_adapter->proposed_mac);
 
+	if (budgetpatch) {
+		spin_lock_init(&av7110->feedlock1);
+		av7110->grabbing = saa7146_vmalloc_build_pgtable(
+					 dev->pci, length, &av7110->pt);
+		if (!av7110->grabbing)
+			goto err_no_mem;
+		saa7146_write(dev, PCI_BT_V1, 0x1c1f101f);
+		saa7146_write(dev, BCS_CTRL, 0x80400040);
+		/* set dd1 stream a & b */
+		saa7146_write(dev, DD1_STREAM_B, 0x00000000);
+		saa7146_write(dev, DD1_INIT, 0x03000200);
+		saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
+		saa7146_write(dev, BRS_CTRL, 0x60000000);
+		saa7146_write(dev, BASE_ODD3, 0);
+		saa7146_write(dev, BASE_EVEN3, 0);
+		saa7146_write(dev, PROT_ADDR3, TS_WIDTH * TS_HEIGHT);
+		saa7146_write(dev, BASE_PAGE3, av7110->pt.dma | ME1 | 0x90);
+
+		saa7146_write(dev, PITCH3, TS_WIDTH);
+		saa7146_write(dev, NUM_LINE_BYTE3, (TS_HEIGHT << 16) | TS_WIDTH);
+
+		/* upload all */
+		saa7146_write(dev, MC2, 0x077c077c);
+		saa7146_write(dev, GPIO_CTRL, 0x000000);
+#if RPS_IRQ
+		/* set event counter 1 source as RPS1 interrupt (0x03)          (rE4 p53)
+		 * use 0x03 to track RPS1 interrupts - increase by 1 every gpio3 is toggled
+		 * use 0x15 to track VPE  interrupts - increase by 1 every vpeirq() is called
+		 */
+		saa7146_write(dev, EC1SSR, (0x03<<2) | 3 );
+		/* set event counter 1 treshold to maximum allowed value        (rEC p55) */
+		saa7146_write(dev, ECT1R,  0x3fff );
+#endif
+		/* Setup BUDGETPATCH MAIN RPS1 "program" (p35) */
+		count = 0;
+
+		/* Wait Source Line Counter Threshold                           (p36) */
+		WRITE_RPS1(cpu_to_le32(CMD_PAUSE | EVT_HS));
+		/* Set GPIO3=1                                                  (p42) */
+		WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2)));
+		WRITE_RPS1(cpu_to_le32(GPIO3_MSK));
+		WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTHI<<24));
+#if RPS_IRQ
+		/* issue RPS1 interrupt */
+		WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT));
+#endif
+		/* Wait reset Source Line Counter Threshold                     (p36) */
+		WRITE_RPS1(cpu_to_le32(CMD_PAUSE | RPS_INV | EVT_HS));
+		/* Set GPIO3=0                                                  (p42) */
+		WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2)));
+		WRITE_RPS1(cpu_to_le32(GPIO3_MSK));
+		WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTLO<<24));
+#if RPS_IRQ
+		/* issue RPS1 interrupt */
+		WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT));
+#endif
+		/* Jump to begin of RPS program                                 (p37) */
+		WRITE_RPS1(cpu_to_le32(CMD_JUMP));
+		WRITE_RPS1(cpu_to_le32(dev->d_rps1.dma_handle));
+
+		/* Fix VSYNC level */
+		saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
+		/* Set RPS1 Address register to point to RPS code               (r108 p42) */
+		saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
+		/* Set Source Line Counter Threshold, using BRS                 (rCC p43)
+		 * It generates HS event every TS_HEIGHT lines
+		 * this is related to TS_WIDTH set in register
+		 * NUM_LINE_BYTE3. If NUM_LINE_BYTE low 16 bits
+		 * are set to TS_WIDTH bytes (TS_WIDTH=2*188),
+		 * then RPS_THRESH1 should be set to trigger
+		 * every TS_HEIGHT (512) lines.
+		 */
+		saa7146_write(dev, RPS_THRESH1, (TS_HEIGHT*1) | MASK_12 );
+
+		/* Enable RPS1                                                  (rFC p33) */
+		saa7146_write(dev, MC1, (MASK_13 | MASK_29));
+
+		/* end of budgetpatch register initialization */
+		tasklet_init (&av7110->vpe_tasklet,  vpeirq,  (unsigned long) av7110);
+	} else {
 	saa7146_write(dev, PCI_BT_V1, 0x1c00101f);
 	saa7146_write(dev, BCS_CTRL, 0x80400040);
 
@@ -1998,6 +2374,7 @@
 	/* upload all */
 	saa7146_write(dev, MC2, 0x077c077c);
         saa7146_write(dev, GPIO_CTRL, 0x000000);
+	}
 
 	tasklet_init (&av7110->debi_tasklet, debiirq, (unsigned long) av7110);
 	tasklet_init (&av7110->gpio_tasklet, gpioirq, (unsigned long) av7110);
@@ -2109,10 +2486,21 @@
 	struct av7110 *av7110 = (struct av7110*)saa->ext_priv;
 	dprintk(4, "%p\n", av7110);
 	
-	if( 0 == av7110->device_initialized ) {
+	if (!av7110->device_initialized )
 		return 0;
-	}
 
+	if (budgetpatch) {
+		/* Disable RPS1 */
+		saa7146_write(saa, MC1, MASK_29);
+		/* VSYNC LOW (inactive) */
+		saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO);
+		saa7146_write(saa, MC1, MASK_20);	/* DMA3 off */
+		SAA7146_IER_DISABLE(saa, MASK_10);
+		SAA7146_ISR_CLEAR(saa, MASK_10);
+		msleep(50);
+		tasklet_kill(&av7110->vpe_tasklet);
+		saa7146_pgtable_free(saa->pci, &av7110->pt);
+	}
 	av7110_exit_v4l(av7110);
 
 	av7110->arm_rmmod=1;
@@ -2121,6 +2509,9 @@
 	while (av7110->arm_thread)
 		msleep(1);
 
+	tasklet_kill(&av7110->debi_tasklet);
+	tasklet_kill(&av7110->gpio_tasklet);
+
 	dvb_unregister(av7110);
 	
 	SAA7146_IER_DISABLE(saa, MASK_19 | MASK_03);
@@ -2153,13 +2544,43 @@
 {
 	struct av7110 *av7110 = dev->ext_priv;
 
-	if (*isr & MASK_19)
+	//print_time("av7110_irq");
+
+	/* Note: Don't try to handle the DEBI error irq (MASK_18), in
+	 * intel mode the timeout is asserted all the time...
+	 */
+
+	if (*isr & MASK_19) {
+		//printk("av7110_irq: DEBI\n");
+		/* Note 1: The DEBI irq is level triggered: We must enable it
+		 * only after we started a DMA xfer, and disable it here
+		 * immediately, or it will be signalled all the time while
+		 * DEBI is idle.
+		 * Note 2: You would think that an irq which is masked is
+		 * not signalled by the hardware. Not so for the SAA7146:
+		 * An irq is signalled as long as the corresponding bit
+		 * in the ISR is set, and disabling irqs just prevents the
+		 * hardware from setting the ISR bit. This means a) that we
+		 * must clear the ISR *after* disabling the irq (which is why
+		 * we must do it here even though saa7146_core did it already),
+		 * and b) that if we were to disable an edge triggered irq
+		 * (like the gpio irqs sadly are) temporarily we would likely
+		 * loose some. This sucks :-(
+		 */
+		SAA7146_IER_DISABLE(av7110->dev, MASK_19);
+		SAA7146_ISR_CLEAR(av7110->dev, MASK_19);
 		tasklet_schedule (&av7110->debi_tasklet);
+	}
 	
-	if (*isr & MASK_03)
+	if (*isr & MASK_03) {
+		//printk("av7110_irq: GPIO\n");
 		tasklet_schedule (&av7110->gpio_tasklet);
 }
 
+	if ((*isr & MASK_10) && budgetpatch)
+		tasklet_schedule(&av7110->vpe_tasklet);
+}
+
 
 static struct saa7146_extension av7110_extension;
 
@@ -2173,8 +2594,9 @@
 MAKE_AV7110_INFO(ttc_1_X,    "Technotrend/Hauppauge WinTV Nexus-CA rev1.X");
 MAKE_AV7110_INFO(ttc_2_X,    "Technotrend/Hauppauge WinTV DVB-C rev2.X");
 MAKE_AV7110_INFO(tts_2_X,    "Technotrend/Hauppauge WinTV Nexus-S rev2.X");
-MAKE_AV7110_INFO(tts_1_3se,  "Technotrend/Hauppauge WinTV Nexus-S rev1.3");
+MAKE_AV7110_INFO(tts_1_3se,  "Technotrend/Hauppauge WinTV DVB-S rev1.3 SE");
 MAKE_AV7110_INFO(fsc,        "Fujitsu Siemens DVB-C");
+MAKE_AV7110_INFO(fss,        "Fujitsu Siemens DVB-S rev1.6");
 
 static struct pci_device_id pci_tbl[] = {
 	MAKE_EXTENSION_PCI(tts_1_X,   0x13c2, 0x0000),
@@ -2184,10 +2606,10 @@
 	MAKE_EXTENSION_PCI(tts_1_3se, 0x13c2, 0x1002),
 	MAKE_EXTENSION_PCI(fsc,       0x110a, 0x0000),
 	MAKE_EXTENSION_PCI(ttc_1_X,   0x13c2, 0x000a),
+	MAKE_EXTENSION_PCI(fss,       0x13c2, 0x0006),
 
 /*	MAKE_EXTENSION_PCI(???, 0x13c2, 0x0004), UNDEFINED CARD */ // Galaxis DVB PC-Sat-Carte
 /*	MAKE_EXTENSION_PCI(???, 0x13c2, 0x0005), UNDEFINED CARD */ // Technisat SkyStar1
-/*	MAKE_EXTENSION_PCI(???, 0x13c2, 0x0006), UNDEFINED CARD */ // TT/Hauppauge WinTV Nexus-S v????
 /*	MAKE_EXTENSION_PCI(???, 0x13c2, 0x0008), UNDEFINED CARD */ // TT/Hauppauge WinTV DVB-T v????
 /*	MAKE_EXTENSION_PCI(???, 0x13c2, 0x0009), UNDEFINED CARD */ // TT/Hauppauge WinTV Nexus-CA v????
 
@@ -2208,7 +2630,7 @@
 	.attach		= av7110_attach,
 	.detach		= av7110_detach,
 
-	.irq_mask	= MASK_19|MASK_03,
+	.irq_mask	= MASK_19 | MASK_03 | MASK_10,
 	.irq_func	= av7110_irq,
 };	
 
diff -Nru a/drivers/media/dvb/ttpci/av7110.h b/drivers/media/dvb/ttpci/av7110.h
--- a/drivers/media/dvb/ttpci/av7110.h	2005-03-01 23:38:44 -08:00
+++ b/drivers/media/dvb/ttpci/av7110.h	2005-03-01 23:38:44 -08:00
@@ -115,7 +115,7 @@
 
         int                     bmpp;
         int                     bmplen;
-        int                     bmp_state;
+	volatile int		bmp_state;
 #define BMP_NONE     0
 #define BMP_LOADING  1
 #define BMP_LOADINGS 2
@@ -157,6 +157,18 @@
 
         struct dmx_frontend	hw_frontend;
         struct dmx_frontend	mem_frontend;
+
+	/* for budget mode demux1 */
+	struct dmxdev		dmxdev1;
+	struct dvb_demux	demux1;
+	struct dvb_net		dvb_net1;
+	spinlock_t		feedlock1;
+	int			feeding1;
+	u8			tsf;
+	u32			ttbp;
+	unsigned char           *grabbing;
+	struct saa7146_pgtable  pt;
+	struct tasklet_struct   vpe_tasklet;
 
         int                     fe_synced; 
         struct semaphore        pid_mutex;
diff -Nru a/drivers/media/dvb/ttpci/av7110_hw.c b/drivers/media/dvb/ttpci/av7110_hw.c
--- a/drivers/media/dvb/ttpci/av7110_hw.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/media/dvb/ttpci/av7110_hw.c	2005-03-01 23:39:07 -08:00
@@ -153,8 +153,10 @@
 	base = DRAM_START_CODE;
 
 	for (i = 0; i < blocks; i++) {
-		if (waitdebi(av7110, BOOT_STATE, BOOTSTATE_BUFFER_EMPTY) < 0)
+		if (waitdebi(av7110, BOOT_STATE, BOOTSTATE_BUFFER_EMPTY) < 0) {
+			printk(KERN_ERR "dvb-ttpci: load_dram(): timeout at block %d\n", i);
 			return -1;
+		}
 		dprintk(4, "writing DRAM block %d\n", i);
 		mwdebi(av7110, DEBISWAB, bootblock,
 		       ((char*)data) + i * BOOT_MAX_SIZE, BOOT_MAX_SIZE);
@@ -166,8 +168,10 @@
 	}
 
 	if (rest > 0) {
-		if (waitdebi(av7110, BOOT_STATE, BOOTSTATE_BUFFER_EMPTY) < 0)
+		if (waitdebi(av7110, BOOT_STATE, BOOTSTATE_BUFFER_EMPTY) < 0) {
+			printk(KERN_ERR "dvb-ttpci: load_dram(): timeout at last block\n");
 			return -1;
+		}
 		if (rest > 4)
 			mwdebi(av7110, DEBISWAB, bootblock,
 			       ((char*)data) + i * BOOT_MAX_SIZE, rest);
@@ -179,12 +183,16 @@
 		iwdebi(av7110, DEBINOSWAP, BOOT_SIZE, rest, 2);
 		iwdebi(av7110, DEBINOSWAP, BOOT_STATE, BOOTSTATE_BUFFER_FULL, 2);
 	}
-	if (waitdebi(av7110, BOOT_STATE, BOOTSTATE_BUFFER_EMPTY) < 0)
+	if (waitdebi(av7110, BOOT_STATE, BOOTSTATE_BUFFER_EMPTY) < 0) {
+		printk(KERN_ERR "dvb-ttpci: load_dram(): timeout after last block\n");
 		return -1;
+	}
 	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)
+	if (waitdebi(av7110, BOOT_STATE, BOOTSTATE_BOOT_COMPLETE) < 0) {
+		printk(KERN_ERR "dvb-ttpci: load_dram(): final handshake timeout\n");
 		return -1;
+	}
 	return 0;
 }
 
@@ -261,8 +269,11 @@
 	mdelay(1);
 
 	dprintk(1, "load dram code\n");
-	if (load_dram(av7110, (u32 *)av7110->bin_root, av7110->size_root) < 0)
+	if (load_dram(av7110, (u32 *)av7110->bin_root, av7110->size_root) < 0) {
+		printk(KERN_ERR "dvb-ttpci: av7110_bootarm(): "
+		       "load_dram() failed\n");
 		return -1;
+	}
 
 	saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTLO);
 	mdelay(1);
@@ -336,7 +347,7 @@
 
 	if (!av7110->arm_ready) {
 		dprintk(1, "arm not ready.\n");
-		return -1;
+		return -ENXIO;
 	}
 
 	start = jiffies;
@@ -344,7 +355,7 @@
 		msleep(1);
 		if (time_after(jiffies, start + ARM_WAIT_FREE)) {
 			printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for COMMAND idle\n", __FUNCTION__);
-			return -1;
+			return -ETIMEDOUT;
 		}
 	}
 
@@ -356,7 +367,7 @@
 		msleep(1);
 		if (time_after(jiffies, start + ARM_WAIT_SHAKE)) {
 			printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for HANDSHAKE_REG\n", __FUNCTION__);
-			return -1;
+			return -ETIMEDOUT;
 		}
 	}
 #endif
@@ -375,6 +386,13 @@
 		flags[0] = OSDQOver;
 		flags[1] = OSDQFull;
 		break;
+	case COMTYPE_MISC:
+		if (FW_VERSION(av7110->arm_app) >= 0x261d) {
+			type = "MSG";
+			flags[0] = GPMQOver;
+			flags[1] = GPMQBusy;
+		}
+		break;
 	default:
 		break;
 	}
@@ -419,18 +437,18 @@
 		if (time_after(jiffies, start + ARM_WAIT_FREE)) {
 			printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for COMMAND to complete\n",
 			       __FUNCTION__);
-			return -1;
+			return -ETIMEDOUT;
 		}
 	}
 
 	stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2);
 	if (stat & GPMQOver) {
 		printk(KERN_ERR "dvb-ttpci: %s(): GPMQOver\n", __FUNCTION__);
-		return -1;
+		return -ENOSPC;
 	}
 	else if (stat & OSDQOver) {
 		printk(KERN_ERR "dvb-ttpci: %s(): OSDQOver\n", __FUNCTION__);
-		return -1;
+		return -ENOSPC;
 	}
 #endif
 
@@ -453,7 +471,8 @@
 	ret = __av7110_send_fw_cmd(av7110, buf, length);
 	up(&av7110->dcomlock);
 	if (ret)
-		printk("dvb-ttpci: %s(): av7110_send_fw_cmd error\n", __FUNCTION__);
+		printk(KERN_ERR "dvb-ttpci: %s(): av7110_send_fw_cmd error %d\n",
+		       __FUNCTION__, ret);
 	return ret;
 }
 
@@ -477,7 +496,7 @@
 
 	ret = av7110_send_fw_cmd(av7110, buf, num + 2);
 	if (ret)
-		printk("dvb-ttpci: av7110_fw_cmd error\n");
+		printk(KERN_ERR "dvb-ttpci: av7110_fw_cmd error %d\n", ret);
 	return ret;
 }
 
@@ -499,7 +518,7 @@
 
 	ret = av7110_send_fw_cmd(av7110, cmd, 18);
 	if (ret)
-		printk("dvb-ttpci: av7110_send_ci_cmd error\n");
+		printk(KERN_ERR "dvb-ttpci: av7110_send_ci_cmd error %d\n", ret);
 	return ret;
 }
 
@@ -525,7 +544,7 @@
 
 	if ((err = __av7110_send_fw_cmd(av7110, request_buf, request_buf_len)) < 0) {
 		up(&av7110->dcomlock);
-		printk("dvb-ttpci: av7110_fw_request error\n");
+		printk(KERN_ERR "dvb-ttpci: av7110_fw_request error %d\n", err);
 		return err;
 	}
 
@@ -579,7 +598,7 @@
 	int ret;
 	ret = av7110_fw_request(av7110, &tag, 0, buf, length);
 	if (ret)
-		printk("dvb-ttpci: av7110_fw_query error\n");
+		printk(KERN_ERR "dvb-ttpci: av7110_fw_query error %d\n", ret);
 	return ret;
 }
 
@@ -626,7 +645,7 @@
 
 int av7110_diseqc_send(struct av7110 *av7110, int len, u8 *msg, unsigned long burst)
 {
-	int i;
+	int i, ret;
 	u16 buf[18] = { ((COMTYPE_AUDIODAC << 8) + SendDiSEqC),
 			16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
 
@@ -646,8 +665,8 @@
 	for (i = 0; i < len; i++)
 		buf[i + 4] = msg[i];
 
-	if (av7110_send_fw_cmd(av7110, buf, 18))
-		printk("dvb-ttpci: av7110_diseqc_send error\n");
+	if ((ret = av7110_send_fw_cmd(av7110, buf, 18)))
+		printk(KERN_ERR "dvb-ttpci: av7110_diseqc_send error %d\n", ret);
 
 	return 0;
 }
@@ -655,21 +674,11 @@
 
 #ifdef CONFIG_DVB_AV7110_OSD
 
-static inline int ResetBlend(struct av7110 *av7110, u8 windownr)
-{
-	return av7110_fw_cmd(av7110, COMTYPE_OSD, SetNonBlend, 1, windownr);
-}
-
 static inline int SetColorBlend(struct av7110 *av7110, u8 windownr)
 {
 	return av7110_fw_cmd(av7110, COMTYPE_OSD, SetCBlend, 1, windownr);
 }
 
-static inline int SetWindowBlend(struct av7110 *av7110, u8 windownr, u8 blending)
-{
-	return av7110_fw_cmd(av7110, COMTYPE_OSD, SetWBlend, 2, windownr, blending);
-}
-
 static inline int SetBlend_(struct av7110 *av7110, u8 windownr,
 		     enum av7110_osd_palette_type colordepth, u16 index, u8 blending)
 {
@@ -684,11 +693,6 @@
 			     windownr, colordepth, index, colorhi, colorlo);
 }
 
-static inline int BringToTop(struct av7110 *av7110, u8 windownr)
-{
-	return av7110_fw_cmd(av7110, COMTYPE_OSD, WTop, 1, windownr);
-}
-
 static inline int SetFont(struct av7110 *av7110, u8 windownr, u8 fontsize,
 			  u16 colorfg, u16 colorbg)
 {
@@ -756,7 +760,7 @@
 	ret = __av7110_send_fw_cmd(av7110, cbuf, 5);
 	up(&av7110->dcomlock);
 	if (ret)
-		printk("dvb-ttpci: WriteText error\n");
+		printk(KERN_ERR "dvb-ttpci: WriteText error %d\n", ret);
 	return ret;
 }
 
@@ -823,7 +827,8 @@
 
 	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 %s()\n", __FUNCTION__);
+		printk("dvb-ttpci: warning: timeout waiting in LoadBitmap: %d, %d\n",
+		       ret, av7110->bmp_state);
 		av7110->bmp_state = BMP_NONE;
 		return -1;
 	}
@@ -865,6 +870,7 @@
 		}
 	}
 	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);
 }
 
@@ -876,11 +882,13 @@
 
 	BUG_ON (av7110->bmp_state == BMP_NONE);
 
-	ret = wait_event_interruptible_timeout(av7110->bmpq, av7110->bmp_state != BMP_LOADING, HZ);
+	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 %s()\n", __FUNCTION__);
+		printk("dvb-ttpci: warning: timeout waiting in BlitBitmap: %d, %d\n",
+		       ret, av7110->bmp_state);
 		av7110->bmp_state = BMP_NONE;
-		return -1;
+		return (ret == 0) ? -ETIMEDOUT : ret;
 		}
 
 	BUG_ON (av7110->bmp_state != BMP_LOADED);
@@ -958,6 +966,7 @@
 {
 	uint w, h, bpp, bpl, size, lpb, bnum, brest;
 	int i;
+	int rc;
 
 	w = x1 - x0 + 1;
 	h = y1 - y0 + 1;
@@ -973,15 +982,23 @@
 	brest = size - bnum * lpb * bpl;
 
 	for (i = 0; i < bnum; i++) {
-		LoadBitmap(av7110, bpp2bit[av7110->osdbpp[av7110->osdwin]],
+		rc = LoadBitmap(av7110, bpp2bit[av7110->osdbpp[av7110->osdwin]],
 			   w, lpb, inc, data);
-		BlitBitmap(av7110, av7110->osdwin, x0, y0 + i * lpb, 0);
+		if (rc)
+			return rc;
+		rc = BlitBitmap(av7110, av7110->osdwin, x0, y0 + i * lpb, 0);
+		if (rc)
+			return rc;
 		data += lpb * inc;
 	}
 	if (brest) {
-		LoadBitmap(av7110, bpp2bit[av7110->osdbpp[av7110->osdwin]],
+		rc = LoadBitmap(av7110, bpp2bit[av7110->osdbpp[av7110->osdwin]],
 			   w, brest / bpl, inc, data);
-		BlitBitmap(av7110, av7110->osdwin, x0, y0 + bnum * lpb, 0);
+		if (rc)
+			return rc;
+		rc = BlitBitmap(av7110, av7110->osdwin, x0, y0 + bnum * lpb, 0);
+		if (rc)
+			return rc;
 	}
 	ReleaseBitmap(av7110);
 	return 0;
@@ -1034,7 +1051,7 @@
 			goto out;
 		} else {
 			int i, len = dc->x0-dc->color+1;
-			u8 __user *colors = (u8 *)dc->data;
+			u8 __user *colors = (u8 __user *)dc->data;
 			u8 r, g, b, blend;
 
 			for (i = 0; i<len; i++) {
@@ -1063,7 +1080,7 @@
 		dc->y1 = dc->y0;
 		/* fall through */
 	case OSD_SetBlock:
-		OSDSetBlock(av7110, dc->x0, dc->y0, dc->x1, dc->y1, dc->color, dc->data);
+		ret = OSDSetBlock(av7110, dc->x0, dc->y0, dc->x1, dc->y1, dc->color, dc->data);
 		goto out;
 	case OSD_FillRow:
 		DrawBlock(av7110, av7110->osdwin, dc->x0, dc->y0,
diff -Nru a/drivers/media/dvb/ttpci/av7110_v4l.c b/drivers/media/dvb/ttpci/av7110_v4l.c
--- a/drivers/media/dvb/ttpci/av7110_v4l.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/media/dvb/ttpci/av7110_v4l.c	2005-03-01 23:38:58 -08:00
@@ -250,7 +250,7 @@
 			if (ves1820_writereg(dev, 0x09, 0x0f, 0x20))
 				dprintk(1, "setting band in demodulator failed.\n");
 		} else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) {
-			saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); // TDA9198 pin9(STD)
+			saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTLO); // TDA9198 pin9(STD)
 			saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); // TDA9198 pin30(VIF)
 		}
 	}
@@ -591,7 +591,7 @@
 			if (ves1820_writereg(av7110->dev, 0x09, 0x0f, 0x20))
 				dprintk(1, "setting band in demodulator failed.\n");
 		} else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) {
-			saa7146_setgpio(av7110->dev, 1, SAA7146_GPIO_OUTHI); // TDA9198 pin9(STD)
+			saa7146_setgpio(av7110->dev, 1, SAA7146_GPIO_OUTLO); // TDA9198 pin9(STD)
 			saa7146_setgpio(av7110->dev, 3, SAA7146_GPIO_OUTLO); // TDA9198 pin30(VIF)
 		}
 
diff -Nru a/drivers/media/dvb/ttpci/budget-core.c b/drivers/media/dvb/ttpci/budget-core.c
--- a/drivers/media/dvb/ttpci/budget-core.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/media/dvb/ttpci/budget-core.c	2005-03-01 23:38:55 -08:00
@@ -89,11 +89,18 @@
 	 *	Pitch: 188, NumBytes3: 188, NumLines3: 1024
 	 */
 
-	if (budget->card->type == BUDGET_FS_ACTIVY) {
+        switch(budget->card->type) {
+	case BUDGET_FS_ACTIVY:
 		saa7146_write(dev, DD1_INIT, 0x04000000);
 		saa7146_write(dev, MC2, (MASK_09 | MASK_25));
 		saa7146_write(dev, BRS_CTRL, 0x00000000);
-	} else {
+		break;
+	case BUDGET_PATCH:
+		saa7146_write(dev, DD1_INIT, 0x00000200);
+		saa7146_write(dev, MC2, (MASK_10 | MASK_26));
+		saa7146_write(dev, BRS_CTRL, 0x60000000);
+		break;
+	default:
 		if (budget->video_port == BUDGET_VIDEO_PORTA) {
 			saa7146_write(dev, DD1_INIT, 0x06000200);
 			saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
@@ -122,9 +129,10 @@
 	}
 
       	saa7146_write(dev, MC2, (MASK_04 | MASK_20));
-     	saa7146_write(dev, MC1, (MASK_04 | MASK_20)); // DMA3 on
 
-	SAA7146_IER_ENABLE(budget->dev, MASK_10);	// VPE
+	SAA7146_ISR_CLEAR(budget->dev, MASK_10);	/* VPE */
+	SAA7146_IER_ENABLE(budget->dev, MASK_10);	/* VPE */
+	saa7146_write(dev, MC1, (MASK_04 | MASK_20));	/* DMA3 on */
 
         return ++budget->feeding;
 }
@@ -249,6 +257,7 @@
                 return -EINVAL;
 
    	spin_lock(&budget->feedlock);   
+	feed->pusi_seen = 0; /* have a clean section start */
 	status = start_ts_capture (budget);
    	spin_unlock(&budget->feedlock);
 	return status;
diff -Nru a/drivers/media/dvb/ttpci/budget-patch.c b/drivers/media/dvb/ttpci/budget-patch.c
--- a/drivers/media/dvb/ttpci/budget-patch.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/media/dvb/ttpci/budget-patch.c	2005-03-01 23:38:52 -08:00
@@ -41,34 +41,127 @@
 
 static struct saa7146_extension budget_extension;
 
-MAKE_BUDGET_INFO(fs_1_3,"Siemens/Technotrend/Hauppauge PCI rev1.3+Budget_Patch", BUDGET_PATCH);
+MAKE_BUDGET_INFO(ttbp, "TT-Budget/Patch DVB-S 1.x PCI", BUDGET_PATCH);
+//MAKE_BUDGET_INFO(satel,"TT-Budget/Patch SATELCO PCI", BUDGET_TT_HW_DISEQC);
 
 static struct pci_device_id pci_tbl[] = {
-        MAKE_EXTENSION_PCI(fs_1_3,0x13c2, 0x0000),
+        MAKE_EXTENSION_PCI(ttbp,0x13c2, 0x0000),
+//        MAKE_EXTENSION_PCI(satel, 0x13c2, 0x1013),
         {
                 .vendor    = 0,
         }
 };
 
-static int budget_wdebi(struct budget_patch *budget, u32 config, int addr, u32 val, int count)
+/* those lines are for budget-patch to be tried
+** on a true budget card and observe the
+** behaviour of VSYNC generated by rps1.
+** this code was shamelessly copy/pasted from budget.c 
+*/
+static void gpio_Set22K (struct budget *budget, int state)
+{
+	struct saa7146_dev *dev=budget->dev;
+	dprintk(2, "budget: %p\n", budget);
+	saa7146_setgpio(dev, 3, (state ? SAA7146_GPIO_OUTHI : SAA7146_GPIO_OUTLO));
+}
+
+/* Diseqc functions only for TT Budget card */
+/* taken from the Skyvision DVB driver by
+   Ralph Metzler <rjkm@metzlerbros.de> */
+
+static void DiseqcSendBit (struct budget *budget, int data)
+{
+	struct saa7146_dev *dev=budget->dev;
+	dprintk(2, "budget: %p\n", budget);
+
+	saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
+	udelay(data ? 500 : 1000);
+	saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
+	udelay(data ? 1000 : 500);
+}
+
+static void DiseqcSendByte (struct budget *budget, int data)
+{
+	int i, par=1, d;
+
+	dprintk(2, "budget: %p\n", budget);
+
+	for (i=7; i>=0; i--) {
+		d = (data>>i)&1;
+		par ^= d;
+		DiseqcSendBit(budget, d);
+	}
+
+	DiseqcSendBit(budget, par);
+}
+
+static int SendDiSEqCMsg (struct budget *budget, int len, u8 *msg, unsigned long burst)
 {
         struct saa7146_dev *dev=budget->dev;
+	int i;
 
         dprintk(2, "budget: %p\n", budget);
 
-        if (count <= 0 || count > 4)
-                return -1;
+	saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
+	mdelay(16);
+
+	for (i=0; i<len; i++)
+		DiseqcSendByte(budget, msg[i]);
+
+	mdelay(16);
+
+	if (burst!=-1) {
+		if (burst)
+			DiseqcSendByte(budget, 0xff);
+		else {
+			saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
+			udelay(12500);
+			saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
+		}
+		msleep(20);
+	}
+
+	return 0;
+}
+
+/* shamelessly copy/pasted from budget.c 
+*/
+static int budget_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
+{
+	struct budget* budget = (struct budget*) fe->dvb->priv;
+
+	switch (tone) {
+	case SEC_TONE_ON:
+		gpio_Set22K (budget, 1);
+		break;
+
+	case SEC_TONE_OFF:
+		gpio_Set22K (budget, 0);
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
 
-        saa7146_write(dev, DEBI_CONFIG, config);
+static int budget_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd)
+{
+	struct budget* budget = (struct budget*) fe->dvb->priv;
 
-        saa7146_write(dev, DEBI_AD, val );
-        saa7146_write(dev, DEBI_COMMAND, (count << 17) | (addr & 0xffff));
-        saa7146_write(dev, MC2, (2 << 16) | 2);
-        mdelay(5);
+	SendDiSEqCMsg (budget, cmd->msg_len, cmd->msg, 0);
 
         return 0;
 }
 
+static int budget_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd)
+{
+	struct budget* budget = (struct budget*) fe->dvb->priv;
+
+	SendDiSEqCMsg (budget, 0, NULL, minicmd);
+
+	return 0;
+}
 
 static int budget_av7110_send_fw_cmd(struct budget_patch *budget, u16* buf, int length)
 {
@@ -77,14 +170,17 @@
         dprintk(2, "budget: %p\n", budget);
 
         for (i = 2; i < length; i++)
-                budget_wdebi(budget, DEBINOSWAP, COMMAND + 2*i, (u32) buf[i], 2);
-
+        {
+                  ttpci_budget_debiwrite(budget, DEBINOSWAP, COMMAND + 2*i, 2, (u32) buf[i], 0,0);
+                  msleep(5);
+        }                  
         if (length)
-                budget_wdebi(budget, DEBINOSWAP, COMMAND + 2, (u32) buf[1], 2);
+                  ttpci_budget_debiwrite(budget, DEBINOSWAP, COMMAND + 2, 2, (u32) buf[1], 0,0);
         else
-                budget_wdebi(budget, DEBINOSWAP, COMMAND + 2, 0, 2);
-
-        budget_wdebi(budget, DEBINOSWAP, COMMAND, (u32) buf[0], 2);
+                  ttpci_budget_debiwrite(budget, DEBINOSWAP, COMMAND + 2, 2, 0, 0,0);
+        msleep(5);     
+        ttpci_budget_debiwrite(budget, DEBINOSWAP, COMMAND, 2, (u32) buf[0], 0,0);
+        msleep(5);
         return 0;
 }
 
@@ -319,6 +415,7 @@
 {
 	switch(budget->dev->pci->subsystem_device) {
 	case 0x0000: // Hauppauge/TT WinTV DVB-S rev1.X
+        case 0x1013: // SATELCO Multimedia PCI
 
 		// try the ALPS BSRV2 first of all
 		budget->dvb_frontend = ves1x93_attach(&alps_bsrv2_config, &budget->i2c_adap);
@@ -332,18 +429,18 @@
 		// try the ALPS BSRU6 now
 		budget->dvb_frontend = stv0299_attach(&alps_bsru6_config, &budget->i2c_adap);
 		if (budget->dvb_frontend) {
-			budget->dvb_frontend->ops->diseqc_send_master_cmd = budget_patch_diseqc_send_master_cmd;
-			budget->dvb_frontend->ops->diseqc_send_burst = budget_patch_diseqc_send_burst;
-			budget->dvb_frontend->ops->set_tone = budget_patch_set_tone;
+			budget->dvb_frontend->ops->diseqc_send_master_cmd = budget_diseqc_send_master_cmd;
+			budget->dvb_frontend->ops->diseqc_send_burst = budget_diseqc_send_burst;
+			budget->dvb_frontend->ops->set_tone = budget_set_tone;
 			break;
 		}
 
 		// Try the grundig 29504-451
 		budget->dvb_frontend = tda8083_attach(&grundig_29504_451_config, &budget->i2c_adap);
 		if (budget->dvb_frontend) {
-			budget->dvb_frontend->ops->diseqc_send_master_cmd = budget_patch_diseqc_send_master_cmd;
-			budget->dvb_frontend->ops->diseqc_send_burst = budget_patch_diseqc_send_burst;
-			budget->dvb_frontend->ops->set_tone = budget_patch_set_tone;
+			budget->dvb_frontend->ops->diseqc_send_master_cmd = budget_diseqc_send_master_cmd;
+			budget->dvb_frontend->ops->diseqc_send_burst = budget_diseqc_send_burst;
+			budget->dvb_frontend->ops->set_tone = budget_set_tone;
 			break;
 		}
 		break;
@@ -365,23 +462,120 @@
 	}
 }
 
+/* written by Emard */
 static int budget_patch_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_data *info)
 {
         struct budget_patch *budget;
         int err;
 	int count = 0;
+	int detected = 0;
 
-        if (!(budget = kmalloc (sizeof(struct budget_patch), GFP_KERNEL)))
-                return -ENOMEM;
+#define PATCH_RESET 0
+#define RPS_IRQ 0
+#define HPS_SETUP 0
+#if PATCH_RESET
+        saa7146_write(dev, MC1, MASK_31);
+        msleep(40);
+#endif
+#if HPS_SETUP
+        // initialize registers. Better to have it like this
+        // than leaving something unconfigured
+	saa7146_write(dev, DD1_STREAM_B, 0);
+	// port B VSYNC at rising edge
+	saa7146_write(dev, DD1_INIT, 0x00000200);  // have this in budget-core too!
+	saa7146_write(dev, BRS_CTRL, 0x00000000);  // VBI
+
+	// debi config
+	// saa7146_write(dev, DEBI_CONFIG, MASK_30|MASK_28|MASK_18);
+
+        // zero all HPS registers
+        saa7146_write(dev, HPS_H_PRESCALE, 0);                  // r68
+        saa7146_write(dev, HPS_H_SCALE, 0);                     // r6c
+        saa7146_write(dev, BCS_CTRL, 0);                        // r70
+        saa7146_write(dev, HPS_V_SCALE, 0);                     // r60
+        saa7146_write(dev, HPS_V_GAIN, 0);                      // r64
+        saa7146_write(dev, CHROMA_KEY_RANGE, 0);                // r74
+        saa7146_write(dev, CLIP_FORMAT_CTRL, 0);                // r78
+        // Set HPS prescaler for port B input
+        saa7146_write(dev, HPS_CTRL, (1<<30) | (0<<29) | (1<<28) | (0<<12) );
+        saa7146_write(dev, MC2, 
+          0 * (MASK_08 | MASK_24)  |   // BRS control
+          0 * (MASK_09 | MASK_25)  |   // a
+          0 * (MASK_10 | MASK_26)  |   // b
+          1 * (MASK_06 | MASK_22)  |   // HPS_CTRL1
+          1 * (MASK_05 | MASK_21)  |   // HPS_CTRL2
+          0 * (MASK_01 | MASK_15)      // DEBI
+           );
+#endif
+	// Disable RPS1 and RPS0
+        saa7146_write(dev, MC1, ( MASK_29 | MASK_28));
+        // RPS1 timeout disable
+        saa7146_write(dev, RPS_TOV1, 0);
+
+	// code for autodetection 
+	// will wait for VBI_B event (vertical blank at port B)
+	// and will reset GPIO3 after VBI_B is detected.
+	// (GPIO3 should be raised high by CPU to
+	// test if GPIO3 will generate vertical blank signal 
+	// in budget patch GPIO3 is connected to VSYNC_B
+	count = 0;
+#if 0
+	WRITE_RPS1(cpu_to_le32(CMD_UPLOAD | 
+	  MASK_10 | MASK_09 | MASK_08 | MASK_06 | MASK_05 | MASK_04 | MASK_03 | MASK_02 ));
+#endif
+        WRITE_RPS1(cpu_to_le32(CMD_PAUSE | EVT_VBI_B));
+        WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2)));
+        WRITE_RPS1(cpu_to_le32(GPIO3_MSK));
+        WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTLO<<24));
+#if RPS_IRQ
+        // issue RPS1 interrupt to increment counter
+        WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT));
+        // at least a NOP is neede between two interrupts
+        WRITE_RPS1(cpu_to_le32(CMD_NOP));
+        // interrupt again
+        WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT));
+#endif
+        WRITE_RPS1(cpu_to_le32(CMD_STOP));
+
+#if RPS_IRQ
+        // set event counter 1 source as RPS1 interrupt (0x03)          (rE4 p53)
+        // use 0x03 to track RPS1 interrupts - increase by 1 every gpio3 is toggled
+        // use 0x15 to track VPE  interrupts - increase by 1 every vpeirq() is called
+        saa7146_write(dev, EC1SSR, (0x03<<2) | 3 );
+        // set event counter 1 treshold to maximum allowed value        (rEC p55)
+        saa7146_write(dev, ECT1R,  0x3fff );
+#endif
+        // Fix VSYNC level
+        saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
+        // Set RPS1 Address register to point to RPS code               (r108 p42)
+        saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
+        // Enable RPS1,                                                 (rFC p33)
+        saa7146_write(dev, MC1, (MASK_13 | MASK_29 ));
 
-        dprintk(2, "budget: %p\n", budget);
 
-        if ((err = ttpci_budget_init (budget, dev, info, THIS_MODULE))) {
-                kfree (budget);
-                return err;
-        }
+        mdelay(50);
+        saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
+	mdelay(150);
+
+	
+	if( (saa7146_read(dev, GPIO_CTRL) & 0x10000000) == 0)
+		detected = 1;
+
+#if RPS_IRQ
+        printk("Event Counter 1 0x%04x\n", saa7146_read(dev, EC1R) & 0x3fff );
+#endif
+	// Disable RPS1
+        saa7146_write(dev, MC1, ( MASK_29 ));
+
+	if(detected == 0)
+                printk("budget-patch not detected or saa7146 in non-default state.\n"
+                       "try enabling ressetting of 7146 with MASK_31 in MC1 register\n");
+                
+	else
+                printk("BUDGET-PATCH DETECTED.\n");
+
 
-/*
+/*      OLD (Original design by Roberto Deza):
 **      This code will setup the SAA7146_RPS1 to generate a square 
 **      wave on GPIO3, changing when a field (TS_HEIGHT/2 "lines" of 
 **      TS_WIDTH packets) has been acquired on SAA7146_D1B video port; 
@@ -393,24 +587,85 @@
 **      which seems that can be done perfectly without this :-)).
 */                                                      
 
+/*      New design (By Emard)
+**      this rps1 code will copy internal HS event to GPIO3 pin.
+**      GPIO3 is in budget-patch hardware connectd to port B VSYNC
+
+**      HS is an internal event of 7146, accessible with RPS
+**      and temporarily raised high every n lines 
+**      (n in defined in the RPS_THRESH1 counter threshold)
+**      I think HS is raised high on the beginning of the n-th line
+**      and remains high until this n-th line that triggered
+**      it is completely received. When the receiption of n-th line
+**      ends, HS is lowered.
+
+**      To transmit data over DMA, 7146 needs changing state at 
+**      port B VSYNC pin. Any changing of port B VSYNC will 
+**      cause some DMA data transfer, with more or less packets loss.
+**      It depends on the phase and frequency of VSYNC and 
+**      the way of 7146 is instructed to trigger on port B (defined
+**      in DD1_INIT register, 3rd nibble from the right valid
+**      numbers are 0-7, see datasheet)
+**
+**      The correct triggering can minimize packet loss, 
+**      dvbtraffic should give this stable bandwidths:
+**        22k transponder = 33814 kbit/s
+**      27.5k transponder = 38045 kbit/s
+**      by experiment it is found that the best results 
+**      (stable bandwidths and almost no packet loss) 
+**      are obtained using DD1_INIT triggering number 2 
+**      (Va at rising edge of VS Fa = HS x VS-failing forced toggle) 
+**      and a VSYNC phase that occurs in the middle of DMA transfer
+**      (about byte 188*512=96256 in the DMA window).
+**
+**      Phase of HS is still not clear to me how to control,
+**      It just happens to be so. It can be seen if one enables
+**      RPS_IRQ and print Event Counter 1 in vpeirq(). Every
+**      time RPS_INTERRUPT is called, the Event Counter 1 will
+**      increment. That's how the 7146 is programmed to do event
+**      counting in this budget-patch.c
+**      I *think* HPS setting has something to do with the phase
+**      of HS but I cant be 100% sure in that. 
+
+**      hardware debug note: a working budget card (including budget patch)
+**      with vpeirq() interrupt setup in mode "0x90" (every 64K) will
+**      generate 3 interrupts per 25-Hz DMA frame of 2*188*512 bytes
+**      and that means 3*25=75 Hz of interrupt freqency, as seen by
+**      watch cat /proc/interrupts 
+**
+**      If this frequency is 3x lower (and data received in the DMA
+**      buffer don't start with 0x47, but in the middle of packets,
+**      whose lengths appear to be like 188 292 188 104 etc.
+**      this means VSYNC line is not connected in the hardware. 
+**      (check soldering pcb and pins)
+**      The same behaviour of missing VSYNC can be duplicated on budget 
+**      cards, by seting DD1_INIT trigger mode 7 in 3rd nibble.
+*/
+
 	// Setup RPS1 "program" (p35)
+        count = 0;
+
 
-        // Wait reset Source Line Counter Threshold                     (p36)
-        WRITE_RPS1(cpu_to_le32(CMD_PAUSE | RPS_INV | EVT_HS));
         // Wait Source Line Counter Threshold                           (p36)
         WRITE_RPS1(cpu_to_le32(CMD_PAUSE | EVT_HS));
         // Set GPIO3=1                                                  (p42)
         WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2)));
         WRITE_RPS1(cpu_to_le32(GPIO3_MSK));
         WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTHI<<24));
+#if RPS_IRQ
+        // issue RPS1 interrupt
+        WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT));
+#endif
         // Wait reset Source Line Counter Threshold                     (p36)
         WRITE_RPS1(cpu_to_le32(CMD_PAUSE | RPS_INV | EVT_HS));
-        // Wait Source Line Counter Threshold
-        WRITE_RPS1(cpu_to_le32(CMD_PAUSE | EVT_HS));
         // Set GPIO3=0                                                  (p42)
         WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2)));
         WRITE_RPS1(cpu_to_le32(GPIO3_MSK));
         WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTLO<<24));
+#if RPS_IRQ
+        // issue RPS1 interrupt
+        WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT));
+#endif
         // Jump to begin of RPS program                                 (p37)
         WRITE_RPS1(cpu_to_le32(CMD_JUMP));
         WRITE_RPS1(cpu_to_le32(dev->d_rps1.dma_handle));
@@ -420,9 +675,30 @@
         // Set RPS1 Address register to point to RPS code               (r108 p42)
         saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
         // Set Source Line Counter Threshold, using BRS                 (rCC p43)
-        saa7146_write(dev, RPS_THRESH1, ((TS_HEIGHT/2) | MASK_12));
+        // It generates HS event every TS_HEIGHT lines
+        // this is related to TS_WIDTH set in register
+        // NUM_LINE_BYTE3 in budget-core.c. If NUM_LINE_BYTE
+        // low 16 bits are set to TS_WIDTH bytes (TS_WIDTH=2*188
+        //,then RPS_THRESH1
+        // should be set to trigger every TS_HEIGHT (512) lines.
+        // 
+        saa7146_write(dev, RPS_THRESH1, (TS_HEIGHT*1) | MASK_12 );
+        
+        // saa7146_write(dev, RPS_THRESH0, ((TS_HEIGHT/2)<<16) |MASK_28| (TS_HEIGHT/2) |MASK_12 );
         // Enable RPS1                                                  (rFC p33)
         saa7146_write(dev, MC1, (MASK_13 | MASK_29));
+
+	
+        if (!(budget = kmalloc (sizeof(struct budget_patch), GFP_KERNEL)))
+                return -ENOMEM;
+
+        dprintk(2, "budget: %p\n", budget);
+
+        if ((err = ttpci_budget_init (budget, dev, info, THIS_MODULE))) {
+                kfree (budget);
+                return err;
+        }
+
 
         dev->ext_priv = budget;
 
diff -Nru a/drivers/media/dvb/ttpci/budget.c b/drivers/media/dvb/ttpci/budget.c
--- a/drivers/media/dvb/ttpci/budget.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/media/dvb/ttpci/budget.c	2005-03-01 23:38:58 -08:00
@@ -414,7 +414,7 @@
 {
 	switch(budget->dev->pci->subsystem_device) {
 	case 0x1003: // Hauppauge/TT Nova budget (stv0299/ALPS BSRU6(tsa5059) OR ves1893/ALPS BSRV2(sp5659))
-
+	case 0x1013:
 		// try the ALPS BSRV2 first of all
 		budget->dvb_frontend = ves1x93_attach(&alps_bsrv2_config, &budget->i2c_adap);
 		if (budget->dvb_frontend) {
@@ -522,14 +522,14 @@
 MAKE_BUDGET_INFO(ttbs,	"TT-Budget/WinTV-NOVA-S  PCI",	BUDGET_TT);
 MAKE_BUDGET_INFO(ttbc,	"TT-Budget/WinTV-NOVA-C  PCI",	BUDGET_TT);
 MAKE_BUDGET_INFO(ttbt,	"TT-Budget/WinTV-NOVA-T  PCI",	BUDGET_TT);
-/* MAKE_BUDGET_INFO(satel,	"SATELCO Multimedia PCI",	BUDGET_TT_HW_DISEQC); UNDEFINED HARDWARE - mail linuxtv.org list */
+MAKE_BUDGET_INFO(satel,	"SATELCO Multimedia PCI",	BUDGET_TT_HW_DISEQC);
 MAKE_BUDGET_INFO(fsacs, "Fujitsu Siemens Activy Budget-S PCI", BUDGET_FS_ACTIVY);
 
 static struct pci_device_id pci_tbl[] = {
 	MAKE_EXTENSION_PCI(ttbs,  0x13c2, 0x1003),
 	MAKE_EXTENSION_PCI(ttbc,  0x13c2, 0x1004),
 	MAKE_EXTENSION_PCI(ttbt,  0x13c2, 0x1005),
-/*	MAKE_EXTENSION_PCI(satel, 0x13c2, 0x1013), UNDEFINED HARDWARE */
+	MAKE_EXTENSION_PCI(satel, 0x13c2, 0x1013),
 	MAKE_EXTENSION_PCI(fsacs, 0x1131, 0x4f61),
 	{
 		.vendor    = 0,
diff -Nru 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	2005-03-01 23:39:17 -08:00
+++ b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c	2005-03-01 23:39:17 -08:00
@@ -1348,7 +1348,7 @@
 
 static void frontend_init(struct ttusb* ttusb)
 {
-	switch(ttusb->dev->descriptor.idProduct) {
+	switch(le16_to_cpu(ttusb->dev->descriptor.idProduct)) {
 	case 0x1003: // Hauppauge/TT Nova-USB-S budget (stv0299/ALPS BSRU6(tsa5059)
 		// try the ALPS BSRU6 first
 		ttusb->fe = stv0299_attach(&alps_bsru6_config, &ttusb->i2c_adap);
@@ -1381,8 +1381,8 @@
 
 	if (ttusb->fe == NULL) {
 		printk("dvb-ttusb-budget: A frontend driver was not found for device %04x/%04x\n",
-		       ttusb->dev->descriptor.idVendor,
-		       ttusb->dev->descriptor.idProduct);
+		       le16_to_cpu(ttusb->dev->descriptor.idVendor),
+		       le16_to_cpu(ttusb->dev->descriptor.idProduct));
 	} else {
 		if (dvb_register_frontend(ttusb->adapter, ttusb->fe)) {
 			printk("dvb-ttusb-budget: Frontend registration failed!\n");
diff -Nru 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	2005-03-01 23:39:16 -08:00
+++ b/drivers/media/dvb/ttusb-dec/ttusb_dec.c	2005-03-01 23:39:16 -08:00
@@ -756,7 +756,7 @@
 
 	if (!dec->iso_stream_count) {
 		for (i = 0; i < ISO_BUF_COUNT; i++)
-			usb_unlink_urb(dec->iso_urb[i]);
+			usb_kill_urb(dec->iso_urb[i]);
 	}
 
 	up(&dec->iso_sem);
@@ -821,7 +821,7 @@
 				       "error %d\n", __FUNCTION__, i, result);
 
 				while (i) {
-					usb_unlink_urb(dec->iso_urb[i - 1]);
+					usb_kill_urb(dec->iso_urb[i - 1]);
 					i--;
 				}
 
@@ -1090,7 +1090,7 @@
 
 static void ttusb_dec_init_tasklet(struct ttusb_dec *dec)
 {
-	dec->urb_frame_list_lock = SPIN_LOCK_UNLOCKED;
+	spin_lock_init(&dec->urb_frame_list_lock);
 	INIT_LIST_HEAD(&dec->urb_frame_list);
 	tasklet_init(&dec->urb_tasklet, ttusb_dec_process_urb_frame_list,
 		     (unsigned long)dec);
@@ -1379,7 +1379,7 @@
 	dec->iso_stream_count = 0;
 
 	for (i = 0; i < ISO_BUF_COUNT; i++)
-		usb_unlink_urb(dec->iso_urb[i]);
+		usb_kill_urb(dec->iso_urb[i]);
 
 	ttusb_dec_free_iso_urbs(dec);
 }
@@ -1401,7 +1401,7 @@
 static void ttusb_dec_init_filters(struct ttusb_dec *dec)
 {
 	INIT_LIST_HEAD(&dec->filter_info_list);
-	dec->filter_info_list_lock = SPIN_LOCK_UNLOCKED;
+	spin_lock_init(&dec->filter_info_list_lock);
 }
 
 static void ttusb_dec_exit_filters(struct ttusb_dec *dec)
@@ -1447,7 +1447,7 @@
 
 	memset(dec, 0, sizeof(struct ttusb_dec));
 
-	switch (id->idProduct) {
+	switch (le16_to_cpu(id->idProduct)) {
 		case 0x1006:
 		ttusb_dec_set_model(dec, TTUSB_DEC3000S);
 			break;
@@ -1471,7 +1471,7 @@
 	ttusb_dec_init_dvb(dec);
 
 	dec->adapter->priv = dec;
-	switch (id->idProduct) {
+	switch (le16_to_cpu(id->idProduct)) {
 	case 0x1006:
 		dec->fe = ttusbdecfe_dvbs_attach(&fe_config);
 		break;
@@ -1484,8 +1484,8 @@
 
 	if (dec->fe == NULL) {
 		printk("dvb-ttusb-dec: A frontend driver was not found for device %04x/%04x\n",
-		       dec->udev->descriptor.idVendor,
-		       dec->udev->descriptor.idProduct);
+		       le16_to_cpu(dec->udev->descriptor.idVendor),
+		       le16_to_cpu(dec->udev->descriptor.idProduct));
 	} else {
 		if (dvb_register_frontend(dec->adapter, dec->fe)) {
 			printk("budget-ci: Frontend registration failed!\n");
diff -Nru a/drivers/media/radio/miropcm20-radio.c b/drivers/media/radio/miropcm20-radio.c
--- a/drivers/media/radio/miropcm20-radio.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/media/radio/miropcm20-radio.c	2005-03-01 23:38:54 -08:00
@@ -26,7 +26,7 @@
 #include "miropcm20-rds-core.h"
 
 static int radio_nr = -1;
-MODULE_PARM(radio_nr, "i");
+module_param(radio_nr, int, 0);
 
 struct pcm20_device {
 	unsigned long freq;
diff -Nru a/drivers/media/radio/radio-aimslab.c b/drivers/media/radio/radio-aimslab.c
--- a/drivers/media/radio/radio-aimslab.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/media/radio/radio-aimslab.c	2005-03-01 23:38:54 -08:00
@@ -130,7 +130,7 @@
  * and bit 4 (+16) is to keep the signal strength meter enabled
  */
 
-void send_0_byte(int port, struct rt_device *dev)
+static void send_0_byte(int port, struct rt_device *dev)
 {
 	if ((dev->curvol == 0) || (dev->muted)) {
 		outb_p(128+64+16+  1, port);   /* wr-enable + data low */
@@ -143,7 +143,7 @@
 	sleep_delay(1000); 
 }
 
-void send_1_byte(int port, struct rt_device *dev)
+static void send_1_byte(int port, struct rt_device *dev)
 {
 	if ((dev->curvol == 0) || (dev->muted)) {
 		outb_p(128+64+16+4  +1, port);   /* wr-enable+data high */
@@ -353,9 +353,9 @@
 MODULE_DESCRIPTION("A driver for the RadioTrack/RadioReveal radio card.");
 MODULE_LICENSE("GPL");
 
-MODULE_PARM(io, "i");
+module_param(io, int, 0);
 MODULE_PARM_DESC(io, "I/O address of the RadioTrack card (0x20f or 0x30f)");
-MODULE_PARM(radio_nr, "i");
+module_param(radio_nr, int, 0);
 
 static void __exit cleanup_rtrack_module(void)
 {
diff -Nru a/drivers/media/radio/radio-aztech.c b/drivers/media/radio/radio-aztech.c
--- a/drivers/media/radio/radio-aztech.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/media/radio/radio-aztech.c	2005-03-01 23:39:18 -08:00
@@ -301,8 +301,8 @@
 MODULE_DESCRIPTION("A driver for the Aztech radio card.");
 MODULE_LICENSE("GPL");
 
-MODULE_PARM(io, "i");
-MODULE_PARM(radio_nr, "i");
+module_param(io, int, 0);
+module_param(radio_nr, int, 0);
 MODULE_PARM_DESC(io, "I/O address of the Aztech card (0x350 or 0x358)");
 
 static void __exit aztech_cleanup(void)
diff -Nru a/drivers/media/radio/radio-cadet.c b/drivers/media/radio/radio-cadet.c
--- a/drivers/media/radio/radio-cadet.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/media/radio/radio-cadet.c	2005-03-01 23:38:56 -08:00
@@ -46,7 +46,7 @@
 static int tunestat=0;
 static int sigstrength=0;
 static wait_queue_head_t read_queue;
-struct timer_list tunertimer,rdstimer,readtimer;
+static struct timer_list readtimer;
 static __u8 rdsin=0,rdsout=0,rdsstat=0;
 static unsigned char rdsbuf[RDS_BUFFER];
 static spinlock_t cadet_io_lock;
@@ -280,7 +280,7 @@
 	spin_unlock(&cadet_io_lock);
 }  
 
-void cadet_handler(unsigned long data)
+static void cadet_handler(unsigned long data)
 {
 	/*
 	 * Service the RDS fifo
@@ -604,9 +604,9 @@
 MODULE_DESCRIPTION("A driver for the ADS Cadet AM/FM/RDS radio card.");
 MODULE_LICENSE("GPL");
 
-MODULE_PARM(io, "i");
+module_param(io, int, 0);
 MODULE_PARM_DESC(io, "I/O address of Cadet card (0x330,0x332,0x334,0x336,0x338,0x33a,0x33c,0x33e)");
-MODULE_PARM(radio_nr, "i");
+module_param(radio_nr, int, 0);
 
 static void __exit cadet_cleanup_module(void)
 {
diff -Nru a/drivers/media/radio/radio-gemtek-pci.c b/drivers/media/radio/radio-gemtek-pci.c
--- a/drivers/media/radio/radio-gemtek-pci.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/media/radio/radio-gemtek-pci.c	2005-03-01 23:38:52 -08:00
@@ -294,7 +294,7 @@
 
 MODULE_DEVICE_TABLE( pci, gemtek_pci_id );
 
-static u8 mx = 1;
+static int mx = 1;
 
 static struct file_operations gemtek_pci_fops = {
 	.owner		= THIS_MODULE,
@@ -406,9 +406,9 @@
 MODULE_DESCRIPTION( "The video4linux driver for the Gemtek PCI Radio Card" );
 MODULE_LICENSE("GPL");
 
-MODULE_PARM( mx, "b" );
+module_param(mx, bool, 0);
 MODULE_PARM_DESC( mx, "single digit: 1 - turn off the turner upon module exit (default), 0 - do not" );
-MODULE_PARM( nr_radio, "i");
+module_param(nr_radio, int, 0);
 MODULE_PARM_DESC( nr_radio, "video4linux device number to use");
 
 module_init( gemtek_pci_init_module );
diff -Nru a/drivers/media/radio/radio-gemtek.c b/drivers/media/radio/radio-gemtek.c
--- a/drivers/media/radio/radio-gemtek.c	2005-03-01 23:38:43 -08:00
+++ b/drivers/media/radio/radio-gemtek.c	2005-03-01 23:38:43 -08:00
@@ -127,7 +127,7 @@
 	return 0;
 }
 
-int gemtek_getsigstr(struct gemtek_device *dev)
+static int gemtek_getsigstr(struct gemtek_device *dev)
 {
 	spin_lock(&lock);
 	inb(io);
@@ -284,9 +284,9 @@
 MODULE_DESCRIPTION("A driver for the GemTek Radio Card");
 MODULE_LICENSE("GPL");
 
-MODULE_PARM(io, "i");
+module_param(io, int, 0);
 MODULE_PARM_DESC(io, "I/O address of the GemTek card (0x20c, 0x30c, 0x24c or 0x34c (0x20c or 0x248 have been reported to work for the combined sound/radiocard)).");
-MODULE_PARM(radio_nr, "i");
+module_param(radio_nr, int, 0);
 
 static void __exit gemtek_cleanup(void)
 {
diff -Nru a/drivers/media/radio/radio-maestro.c b/drivers/media/radio/radio-maestro.c
--- a/drivers/media/radio/radio-maestro.c	2005-03-01 23:38:59 -08:00
+++ b/drivers/media/radio/radio-maestro.c	2005-03-01 23:38:59 -08:00
@@ -62,7 +62,7 @@
 #define BITS2FREQ(x)	((x) * FREQ_STEP - FREQ_IF)
 
 static int radio_nr = -1;
-MODULE_PARM(radio_nr, "i");
+module_param(radio_nr, int, 0);
 
 static int radio_ioctl(struct inode *inode, struct file *file,
 		       unsigned int cmd, unsigned long arg);
@@ -256,12 +256,12 @@
 MODULE_DESCRIPTION("Radio driver for the Maestro PCI sound card radio.");
 MODULE_LICENSE("GPL");
 
-void __exit maestro_radio_exit(void)
+static void __exit maestro_radio_exit(void)
 {
 	video_unregister_device(&maestro_radio);
 }
 
-int __init maestro_radio_init(void)
+static int __init maestro_radio_init(void)
 {
 	register __u16 found=0;
 	struct pci_dev *pcidev = NULL;
diff -Nru a/drivers/media/radio/radio-maxiradio.c b/drivers/media/radio/radio-maxiradio.c
--- a/drivers/media/radio/radio-maxiradio.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/media/radio/radio-maxiradio.c	2005-03-01 23:39:16 -08:00
@@ -57,7 +57,7 @@
 static const int clk = 1, data = 2, wren = 4, mo_st = 8, power = 16 ;
 
 static int radio_nr = -1;
-MODULE_PARM(radio_nr, "i");
+module_param(radio_nr, int, 0);
 
 
 #define FREQ_LO		 50*16000
@@ -335,12 +335,12 @@
 	.remove		= __devexit_p(maxiradio_remove_one),
 };
 
-int __init maxiradio_radio_init(void)
+static int __init maxiradio_radio_init(void)
 {
 	return pci_module_init(&maxiradio_driver);
 }
 
-void __exit maxiradio_radio_exit(void)
+static void __exit maxiradio_radio_exit(void)
 {
 	pci_unregister_driver(&maxiradio_driver);
 }
diff -Nru a/drivers/media/radio/radio-rtrack2.c b/drivers/media/radio/radio-rtrack2.c
--- a/drivers/media/radio/radio-rtrack2.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/media/radio/radio-rtrack2.c	2005-03-01 23:39:07 -08:00
@@ -246,9 +246,9 @@
 MODULE_DESCRIPTION("A driver for the RadioTrack II radio card.");
 MODULE_LICENSE("GPL");
 
-MODULE_PARM(io, "i");
+module_param(io, int, 0);
 MODULE_PARM_DESC(io, "I/O address of the RadioTrack card (0x20c or 0x30c)");
-MODULE_PARM(radio_nr, "i");
+module_param(radio_nr, int, 0);
 
 static void __exit rtrack2_cleanup_module(void)
 {
diff -Nru a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c
--- a/drivers/media/radio/radio-sf16fmi.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/media/radio/radio-sf16fmi.c	2005-03-01 23:39:16 -08:00
@@ -312,9 +312,9 @@
 MODULE_DESCRIPTION("A driver for the SF16MI radio.");
 MODULE_LICENSE("GPL");
 
-MODULE_PARM(io, "i");
+module_param(io, int, 0);
 MODULE_PARM_DESC(io, "I/O address of the SF16MI card (0x284 or 0x384)");
-MODULE_PARM(radio_nr, "i");
+module_param(radio_nr, int, 0);
 
 static void __exit fmi_cleanup_module(void)
 {
diff -Nru a/drivers/media/radio/radio-sf16fmr2.c b/drivers/media/radio/radio-sf16fmr2.c
--- a/drivers/media/radio/radio-sf16fmr2.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/media/radio/radio-sf16fmr2.c	2005-03-01 23:38:56 -08:00
@@ -408,9 +408,9 @@
 MODULE_DESCRIPTION("A driver for the SF16FMR2 radio.");
 MODULE_LICENSE("GPL");
 
-MODULE_PARM(io, "i");
+module_param(io, int, 0);
 MODULE_PARM_DESC(io, "I/O address of the SF16FMR2 card (should be 0x384, if do not work try 0x284)");
-MODULE_PARM(radio_nr, "i");
+module_param(radio_nr, int, 0);
 
 static void __exit fmr2_cleanup_module(void)
 {
diff -Nru a/drivers/media/radio/radio-terratec.c b/drivers/media/radio/radio-terratec.c
--- a/drivers/media/radio/radio-terratec.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/media/radio/radio-terratec.c	2005-03-01 23:38:56 -08:00
@@ -175,7 +175,7 @@
   	return 0;
 }
 
-int tt_getsigstr(struct tt_device *dev)		/* TODO */
+static int tt_getsigstr(struct tt_device *dev)		/* TODO */
 {
 	if (inb(io) & 2)	/* bit set = no signal present	*/
 		return 0;
@@ -325,9 +325,9 @@
 MODULE_AUTHOR("R.OFFERMANNS & others");
 MODULE_DESCRIPTION("A driver for the TerraTec ActiveRadio Standalone radio card.");
 MODULE_LICENSE("GPL");
-MODULE_PARM(io, "i");
+module_param(io, int, 0);
 MODULE_PARM_DESC(io, "I/O address of the TerraTec ActiveRadio card (0x590 or 0x591)");
-MODULE_PARM(radio_nr, "i");
+module_param(radio_nr, int, 0);
 
 static void __exit terratec_cleanup_module(void)
 {
diff -Nru a/drivers/media/radio/radio-trust.c b/drivers/media/radio/radio-trust.c
--- a/drivers/media/radio/radio-trust.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/media/radio/radio-trust.c	2005-03-01 23:38:57 -08:00
@@ -306,9 +306,9 @@
 MODULE_DESCRIPTION("A driver for the Trust FM Radio card.");
 MODULE_LICENSE("GPL");
 
-MODULE_PARM(io, "i");
+module_param(io, int, 0);
 MODULE_PARM_DESC(io, "I/O address of the Trust FM Radio card (0x350 or 0x358)");
-MODULE_PARM(radio_nr, "i");
+module_param(radio_nr, int, 0);
 
 static void __exit cleanup_trust_module(void)
 {
diff -Nru a/drivers/media/radio/radio-typhoon.c b/drivers/media/radio/radio-typhoon.c
--- a/drivers/media/radio/radio-typhoon.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/media/radio/radio-typhoon.c	2005-03-01 23:38:55 -08:00
@@ -305,17 +305,17 @@
 MODULE_DESCRIPTION("A driver for the Typhoon radio card (a.k.a. EcoRadio).");
 MODULE_LICENSE("GPL");
 
-MODULE_PARM(io, "i");
-MODULE_PARM_DESC(io, "I/O address of the Typhoon card (0x316 or 0x336)");
-MODULE_PARM(mutefreq, "i");
-MODULE_PARM_DESC(mutefreq, "Frequency used when muting the card (in kHz)");
-MODULE_PARM(radio_nr, "i");
-
 static int io = -1;
 static int radio_nr = -1;
 
+module_param(io, int, 0);
+MODULE_PARM_DESC(io, "I/O address of the Typhoon card (0x316 or 0x336)");
+module_param(radio_nr, int, 0);
+
 #ifdef MODULE
 static unsigned long mutefreq = 0;
+module_param(mutefreq, ulong, 0);
+MODULE_PARM_DESC(mutefreq, "Frequency used when muting the card (in kHz)");
 #endif
 
 static int __init typhoon_init(void)
diff -Nru a/drivers/media/radio/radio-zoltrix.c b/drivers/media/radio/radio-zoltrix.c
--- a/drivers/media/radio/radio-zoltrix.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/media/radio/radio-zoltrix.c	2005-03-01 23:39:17 -08:00
@@ -169,7 +169,7 @@
 
 /* Get signal strength */
 
-int zol_getsigstr(struct zol_device *dev)
+static int zol_getsigstr(struct zol_device *dev)
 {
 	int a, b;
 
@@ -194,7 +194,7 @@
  	return (0);
 }
 
-int zol_is_stereo (struct zol_device *dev)
+static int zol_is_stereo (struct zol_device *dev)
 {
 	int x1, x2;
 
@@ -382,9 +382,9 @@
 MODULE_DESCRIPTION("A driver for the Zoltrix Radio Plus.");
 MODULE_LICENSE("GPL");
 
-MODULE_PARM(io, "i");
+module_param(io, int, 0);
 MODULE_PARM_DESC(io, "I/O address of the Zoltrix Radio Plus (0x20c or 0x30c)");
-MODULE_PARM(radio_nr, "i");
+module_param(radio_nr, int, 0);
 
 static void __exit zoltrix_cleanup_module(void)
 {
diff -Nru a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
--- a/drivers/media/video/Kconfig	2005-03-01 23:39:16 -08:00
+++ b/drivers/media/video/Kconfig	2005-03-01 23:39:16 -08:00
@@ -16,13 +16,14 @@
 	select VIDEO_BUF
 	select VIDEO_IR
 	select VIDEO_TUNER
+	select VIDEO_TVEEPROM
 	---help---
 	  Support for BT848 based frame grabber/overlay boards. This includes
 	  the Miro, Hauppauge and STB boards. Please read the material in
 	  <file:Documentation/video4linux/bttv/> for more information.
 
 	  If you say Y or M here, you need to say Y or M to "I2C support" and
-	  "I2C bit-banging interfaces" in the character device section.
+	  "I2C bit-banging interfaces" in the device drivers section.
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called bttv.
@@ -145,7 +146,8 @@
 
 config VIDEO_VINO
 	tristate "SGI Vino Video For Linux (EXPERIMENTAL)"
-	depends on EXPERIMENTAL && VIDEO_DEV && SGI
+	depends on VIDEO_DEV && I2C && SGI_IP22 && EXPERIMENTAL
+	select I2C_ALGO_SGI
 	help
 	  Say Y here to build in support for the Vino video input system found
 	  on SGI Indy machines.
diff -Nru a/drivers/media/video/Makefile b/drivers/media/video/Makefile
--- a/drivers/media/video/Makefile	2005-03-01 23:38:55 -08:00
+++ b/drivers/media/video/Makefile	2005-03-01 23:38:55 -08:00
@@ -48,6 +48,7 @@
 obj-$(CONFIG_VIDEO_BUF)   += video-buf.o
 obj-$(CONFIG_VIDEO_BUF_DVB) += video-buf-dvb.o
 obj-$(CONFIG_VIDEO_BTCX)  += btcx-risc.o
+obj-$(CONFIG_VIDEO_TVEEPROM) += tveeprom.o
 
 obj-$(CONFIG_VIDEO_M32R_AR_M64278) += arv.o
 
diff -Nru a/drivers/media/video/adv7170.c b/drivers/media/video/adv7170.c
--- a/drivers/media/video/adv7170.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/media/video/adv7170.c	2005-03-01 23:39:16 -08:00
@@ -61,7 +61,7 @@
 #include <linux/video_encoder.h>
 
 static int debug = 0;
-MODULE_PARM(debug, "i");
+module_param(debug, int, 0);
 MODULE_PARM_DESC(debug, "Debug level (0-1)");
 
 #define dprintk(num, format, args...) \
diff -Nru a/drivers/media/video/adv7175.c b/drivers/media/video/adv7175.c
--- a/drivers/media/video/adv7175.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/media/video/adv7175.c	2005-03-01 23:39:16 -08:00
@@ -57,7 +57,7 @@
 #include <linux/video_encoder.h>
 
 static int debug = 0;
-MODULE_PARM(debug, "i");
+module_param(debug, int, 0);
 MODULE_PARM_DESC(debug, "Debug level (0-1)");
 
 #define dprintk(num, format, args...) \
diff -Nru a/drivers/media/video/arv.c b/drivers/media/video/arv.c
--- a/drivers/media/video/arv.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/media/video/arv.c	2005-03-01 23:39:16 -08:00
@@ -627,7 +627,7 @@
  */
 static int ar_initialize(struct video_device *dev)
 {
-	struct ar_device *ar = (struct ar_device *)dev->priv;
+	struct ar_device *ar = dev->priv;
 	unsigned long cr = 0;
 	int i,found=0;
 
diff -Nru a/drivers/media/video/bt819.c b/drivers/media/video/bt819.c
--- a/drivers/media/video/bt819.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/media/video/bt819.c	2005-03-01 23:38:52 -08:00
@@ -61,7 +61,7 @@
 #include <linux/video_decoder.h>
 
 static int debug = 0;
-MODULE_PARM(debug, "i");
+module_param(debug, int, 0);
 MODULE_PARM_DESC(debug, "Debug level (0-1)");
 
 #define dprintk(num, format, args...) \
@@ -95,7 +95,7 @@
 };
 
 /* for values, see the bt819 datasheet */
-struct timing timing_data[] = {
+static struct timing timing_data[] = {
 	{864 - 24, 20, 625 - 2, 1, 0x0504, 0x0000},
 	{858 - 24, 20, 525 - 2, 1, 0x00f8, 0x0000},
 };
diff -Nru a/drivers/media/video/bt856.c b/drivers/media/video/bt856.c
--- a/drivers/media/video/bt856.c	2005-03-01 23:38:44 -08:00
+++ b/drivers/media/video/bt856.c	2005-03-01 23:38:44 -08:00
@@ -61,7 +61,7 @@
 #include <linux/video_encoder.h>
 
 static int debug = 0;
-MODULE_PARM(debug, "i");
+module_param(debug, int, 0);
 MODULE_PARM_DESC(debug, "Debug level (0-1)");
 
 #define dprintk(num, format, args...) \
diff -Nru a/drivers/media/video/btcx-risc.c b/drivers/media/video/btcx-risc.c
--- a/drivers/media/video/btcx-risc.c	2005-03-01 23:38:44 -08:00
+++ b/drivers/media/video/btcx-risc.c	2005-03-01 23:38:44 -08:00
@@ -1,5 +1,5 @@
 /*
-    $Id: btcx-risc.c,v 1.4 2004/11/07 13:17:14 kraxel Exp $
+    $Id: btcx-risc.c,v 1.5 2004/12/10 12:33:39 kraxel Exp $
 
     btcx-risc.c
 
@@ -24,6 +24,7 @@
 */
 
 #include <linux/module.h>
+#include <linux/moduleparam.h>
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/interrupt.h>
diff -Nru a/drivers/media/video/bttv-cards.c b/drivers/media/video/bttv-cards.c
--- a/drivers/media/video/bttv-cards.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/media/video/bttv-cards.c	2005-03-01 23:38:57 -08:00
@@ -1,5 +1,5 @@
 /*
-    $Id: bttv-cards.c,v 1.32 2004/11/07 13:17:14 kraxel Exp $
+    $Id: bttv-cards.c,v 1.42 2005/01/13 17:22:33 kraxel Exp $
 
     bttv-cards.c
 
@@ -29,18 +29,19 @@
 #include <linux/config.h>
 #include <linux/delay.h>
 #include <linux/module.h>
+#include <linux/moduleparam.h>
 #include <linux/kmod.h>
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/vmalloc.h>
-#if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE)
-# include <linux/firmware.h>
-#endif
+#include <linux/firmware.h>
 
 #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);
@@ -76,6 +77,9 @@
 static void picolo_tetra_muxsel(struct bttv *btv, unsigned int input);
 static void picolo_tetra_init(struct bttv *btv);
 
+static void tibetCS16_muxsel(struct bttv *btv, unsigned int input);
+static void tibetCS16_init(struct bttv *btv);
+
 static void sigmaSLC_muxsel(struct bttv *btv, unsigned int input);
 static void sigmaSQ_muxsel(struct bttv *btv, unsigned int input);
 
@@ -84,12 +88,13 @@
 static int tea5757_write(struct bttv *btv, int value);
 static void identify_by_eeprom(struct bttv *btv,
 			       unsigned char eeprom_data[256]);
+static int __devinit pvr_boot(struct bttv *btv);
 
 /* config variables */
 static unsigned int triton1=0;
 static unsigned int vsfx=0;
 static unsigned int latency = UNSET;
-unsigned int no_overlay=-1;
+static unsigned 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 };
@@ -283,12 +288,12 @@
 
 	// DVB cards (using pci function .1 for mpeg data xfer)
 	{ 0x01010071, BTTV_NEBULA_DIGITV, "Nebula Electronics DigiTV" },
-	{ 0x07611461, BTTV_AVDVBT_761,    "AverMedia AverTV DVB-T" },
+	{ 0x07611461, BTTV_AVDVBT_761,    "AverMedia AverTV DVB-T 761" },
 	{ 0x001c11bd, BTTV_PINNACLESAT,   "Pinnacle PCTV Sat" },
 	{ 0x002611bd, BTTV_TWINHAN_DST,   "Pinnacle PCTV SAT CI" },
 	{ 0x00011822, BTTV_TWINHAN_DST,   "Twinhan VisionPlus DVB-T" },
 	{ 0xfc00270f, BTTV_TWINHAN_DST,   "ChainTech digitop DST-1000 DVB-S" },
-	{ 0x07711461, BTTV_AVDVBT_771,    "AVermedia DVB-T 771" },
+	{ 0x07711461, BTTV_AVDVBT_771,    "AVermedia AverTV DVB-T 771" },
 	{ 0xdb1018ac, BTTV_DVICO_DVBT_LITE,    "DVICO FusionHDTV DVB-T Lite" },
 
 	{ 0, -1, NULL }
@@ -2156,9 +2161,36 @@
 	.tuner_type     = TUNER_PHILIPS_NTSC_M,
 	.has_radio      = 0,
 	// .has_remote     = 1,
+},{
+	/* Rick C <cryptdragoon@gmail.com> */
+        .name           = "Super TV Tuner",
+        .video_inputs   = 4,
+        .audio_inputs   = 1,
+        .tuner          = 0,
+        .svhs           = 2,
+        .muxsel         = { 2, 3, 1, 0},
+        .tuner_type     = TUNER_PHILIPS_NTSC,
+        .gpiomask       = 0x008007,
+        .audiomux       = { 0, 0x000001,0,0, 0},
+        .needs_tvaudio  = 1,
+        .has_radio      = 1,
+},{
+		/* Chris Fanning <video4linux@haydon.net> */
+		.name           = "Tibet Systems 'Progress DVR' CS16",
+		.video_inputs   = 16,
+		.audio_inputs   = 0,
+		.tuner          = -1,
+		.svhs           = -1,
+		.muxsel         = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
+		.pll		= PLL_28,
+		.no_msp34xx     = 1,
+		.no_tda9875     = 1,
+		.no_tda7432	= 1,
+		.tuner_type     = -1,
+		.muxsel_hook    = tibetCS16_muxsel,
 }};
 
-const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards);
+static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards);
 
 /* ----------------------------------------------------------------------- */
 
@@ -2327,10 +2359,10 @@
 	//todo: if(has_tda9874) btv->audio_hook = fv2000s_audio;
 }
 
-int miro_tunermap[] = { 0,6,2,3,   4,5,6,0,  3,0,4,5,  5,2,16,1,
-			14,2,17,1, 4,1,4,3,  1,2,16,1, 4,4,4,4 };
-int miro_fmtuner[]  = { 0,0,0,0,   0,0,0,0,  0,0,0,0,  0,0,0,1,
-			1,1,1,1,   1,1,1,0,  0,0,0,0,  0,1,0,0 };
+static int miro_tunermap[] = { 0,6,2,3,   4,5,6,0,  3,0,4,5,  5,2,16,1,
+			       14,2,17,1, 4,1,4,3,  1,2,16,1, 4,4,4,4 };
+static int miro_fmtuner[]  = { 0,0,0,0,   0,0,0,0,  0,0,0,0,  0,0,0,1,
+			       1,1,1,1,   1,1,1,0,  0,0,0,0,  0,1,0,0 };
 
 static void miro_pinnacle_gpio(struct bttv *btv)
 {
@@ -2499,7 +2531,7 @@
 
 /* ----------------------------------------------------------------------- */
 
-void bttv_reset_audio(struct bttv *btv)
+static void bttv_reset_audio(struct bttv *btv)
 {
 	/*
 	 * BT878A has a audio-reset register.
@@ -2542,6 +2574,8 @@
 		btv->use_i2c_hw = 1;
 		break;
 	}
+	if (!bttv_tvcards[btv->c.type].has_dvb)
+		bttv_reset_audio(btv);
 }
 
 /* initialization part two -- after registering i2c bus */
@@ -2645,6 +2679,9 @@
 	case BTTV_LMLBT4:
 		init_lmlbt4x(btv);
 		break;
+	case BTTV_TIBET_CS16:
+		tibetCS16_init(btv);
+		break;
 	}
 
 	/* pll configuration */
@@ -2681,6 +2718,8 @@
         }
 	btv->pll.pll_current = -1;
 
+	bttv_reset_audio(btv);
+
 	/* tuner configuration (from card list / autodetect / insmod option) */
  	if (UNSET != bttv_tvcards[btv->c.type].tuner_type)
 		if(UNSET == btv->tuner_type)
@@ -2745,7 +2784,10 @@
 	if (0 == tda9887 && 0 == bttv_tvcards[btv->c.type].has_dvb &&
 	    bttv_I2CRead(btv, I2C_TDA9887, "TDA9887") >=0)
 		tda9887 = 1;
-	if (tda9887)
+	if((btv->tuner_type == TUNER_PHILIPS_FM1216ME_MK3) ||
+	   (btv->tuner_type == TUNER_PHILIPS_FM1236_MK3) ||
+	   (btv->tuner_type == TUNER_PHILIPS_FM1256_IH3) ||
+	    tda9887)
 		request_module("tda9887");
 	if (btv->tuner_type != UNSET)
 		request_module("tuner");
@@ -2753,67 +2795,6 @@
 
 
 /* ----------------------------------------------------------------------- */
-/* some hauppauge specific stuff                                           */
-
-static struct HAUPPAUGE_TUNER
-{
-        int  id;
-        char *name;
-}
-hauppauge_tuner[] __devinitdata =
-{
-        { TUNER_ABSENT,        "" },
-        { TUNER_ABSENT,        "External" },
-        { TUNER_ABSENT,        "Unspecified" },
-        { TUNER_PHILIPS_PAL,   "Philips FI1216" },
-        { TUNER_PHILIPS_SECAM, "Philips FI1216MF" },
-        { TUNER_PHILIPS_NTSC,  "Philips FI1236" },
-        { TUNER_PHILIPS_PAL_I, "Philips FI1246" },
-        { TUNER_PHILIPS_PAL_DK,"Philips FI1256" },
-        { TUNER_PHILIPS_PAL,   "Philips FI1216 MK2" },
-        { TUNER_PHILIPS_SECAM, "Philips FI1216MF MK2" },
-        { TUNER_PHILIPS_NTSC,  "Philips FI1236 MK2" },
-        { TUNER_PHILIPS_PAL_I, "Philips FI1246 MK2" },
-        { TUNER_PHILIPS_PAL_DK,"Philips FI1256 MK2" },
-        { TUNER_TEMIC_NTSC,    "Temic 4032FY5" },
-        { TUNER_TEMIC_PAL,     "Temic 4002FH5" },
-        { TUNER_TEMIC_PAL_I,   "Temic 4062FY5" },
-        { TUNER_PHILIPS_PAL,   "Philips FR1216 MK2" },
-        { TUNER_PHILIPS_SECAM, "Philips FR1216MF MK2" },
-        { TUNER_PHILIPS_NTSC,  "Philips FR1236 MK2" },
-        { TUNER_PHILIPS_PAL_I, "Philips FR1246 MK2" },
-        { TUNER_PHILIPS_PAL_DK,"Philips FR1256 MK2" },
-        { TUNER_PHILIPS_PAL,   "Philips FM1216" },
-        { TUNER_PHILIPS_SECAM, "Philips FM1216MF" },
-        { TUNER_PHILIPS_NTSC,  "Philips FM1236" },
-        { TUNER_PHILIPS_PAL_I, "Philips FM1246" },
-        { TUNER_PHILIPS_PAL_DK,"Philips FM1256" },
-        { TUNER_TEMIC_4036FY5_NTSC, "Temic 4036FY5" },
-        { TUNER_ABSENT,        "Samsung TCPN9082D" },
-        { TUNER_ABSENT,        "Samsung TCPM9092P" },
-        { TUNER_TEMIC_4006FH5_PAL, "Temic 4006FH5" },
-        { TUNER_ABSENT,        "Samsung TCPN9085D" },
-        { TUNER_ABSENT,        "Samsung TCPB9085P" },
-        { TUNER_ABSENT,        "Samsung TCPL9091P" },
-        { TUNER_TEMIC_4039FR5_NTSC, "Temic 4039FR5" },
-        { TUNER_PHILIPS_FQ1216ME,   "Philips FQ1216 ME" },
-        { TUNER_TEMIC_4066FY5_PAL_I, "Temic 4066FY5" },
-        { TUNER_PHILIPS_NTSC,        "Philips TD1536" },
-        { TUNER_PHILIPS_NTSC,        "Philips TD1536D" },
-	{ TUNER_PHILIPS_NTSC,  "Philips FMR1236" }, /* mono radio */
-        { TUNER_ABSENT,        "Philips FI1256MP" },
-        { TUNER_ABSENT,        "Samsung TCPQ9091P" },
-        { TUNER_TEMIC_4006FN5_MULTI_PAL, "Temic 4006FN5" },
-        { TUNER_TEMIC_4009FR5_PAL, "Temic 4009FR5" },
-        { TUNER_TEMIC_4046FM5,     "Temic 4046FM5" },
-	{ TUNER_TEMIC_4009FN5_MULTI_PAL_FM, "Temic 4009FN5" },
-	{ TUNER_ABSENT,        "Philips TD1536D_FH_44"},
-	{ TUNER_LG_NTSC_FM,    "LG TPI8NSR01F"},
-	{ TUNER_LG_PAL_FM,     "LG TPI8PSB01D"},
-	{ TUNER_LG_PAL,        "LG TPI8PSB11D"},
-	{ TUNER_LG_PAL_I_FM,   "LG TAPC-I001D"},
-	{ TUNER_LG_PAL_I,      "LG TAPC-I701D"}
-};
 
 static void modtec_eeprom(struct bttv *btv)
 {
@@ -2837,31 +2818,11 @@
 
 static void __devinit hauppauge_eeprom(struct bttv *btv)
 {
-	unsigned int blk2,tuner,radio,model;
+	struct tveeprom tv;
 
-	if (eeprom_data[0] != 0x84 || eeprom_data[2] != 0)
-		printk(KERN_WARNING "bttv%d: Hauppauge eeprom: invalid\n",
-		       btv->c.nr);
-
-	/* Block 2 starts after len+3 bytes header */
-	blk2 = eeprom_data[1] + 3;
-
-	/* decode + use some config infos */
-	model = eeprom_data[12] << 8 | eeprom_data[11];
-	tuner = eeprom_data[9];
-	radio = eeprom_data[blk2-1] & 0x01;
-
-        if (tuner < ARRAY_SIZE(hauppauge_tuner))
-                btv->tuner_type = hauppauge_tuner[tuner].id;
-	if (radio)
-		btv->has_radio = 1;
-
-	if (bttv_verbose)
-		printk(KERN_INFO "bttv%d: Hauppauge eeprom: model=%d, "
-		       "tuner=%s (%d), radio=%s\n",
-		       btv->c.nr, model, (tuner < ARRAY_SIZE(hauppauge_tuner)
-					  ? hauppauge_tuner[tuner].name : "?"),
-		       btv->tuner_type, radio ? "yes" : "no");
+	tveeprom_hauppauge_analog(&tv, eeprom_data);
+	btv->tuner_type = tv.tuner_type;
+	btv->has_radio  = tv.has_radio;
 }
 
 static int terratec_active_radio_upgrade(struct bttv *btv)
@@ -2947,7 +2908,7 @@
 	return 0;
 }
 
-int __devinit pvr_boot(struct bttv *btv)
+static int __devinit pvr_boot(struct bttv *btv)
 {
         const struct firmware *fw_entry;
 	int rc;
@@ -3072,12 +3033,13 @@
 /* ----------------------------------------------------------------------- */
 /* AVermedia specific stuff, from  bktr_card.c                             */
 
-int tuner_0_table[] = {
+static int tuner_0_table[] = {
         TUNER_PHILIPS_NTSC,  TUNER_PHILIPS_PAL /* PAL-BG*/,
         TUNER_PHILIPS_PAL,   TUNER_PHILIPS_PAL /* PAL-I*/,
         TUNER_PHILIPS_PAL,   TUNER_PHILIPS_PAL,
         TUNER_PHILIPS_SECAM, TUNER_PHILIPS_SECAM,
-        TUNER_PHILIPS_SECAM, TUNER_PHILIPS_PAL};
+        TUNER_PHILIPS_SECAM, TUNER_PHILIPS_PAL,
+	TUNER_PHILIPS_FM1216ME_MK3 };
 #if 0
 int tuner_0_fm_table[] = {
         PHILIPS_FR1236_NTSC,  PHILIPS_FR1216_PAL,
@@ -3087,7 +3049,7 @@
         PHILIPS_FR1236_SECAM, PHILIPS_FR1216_PAL};
 #endif
 
-int tuner_1_table[] = {
+static int tuner_1_table[] = {
         TUNER_TEMIC_NTSC,  TUNER_TEMIC_PAL,
 	TUNER_TEMIC_PAL,   TUNER_TEMIC_PAL,
 	TUNER_TEMIC_PAL,   TUNER_TEMIC_PAL,
@@ -3104,12 +3066,16 @@
 	btv->has_remote = (eeprom_data[0x42] & 0x01);
 
 	if (tuner_make == 0 || tuner_make == 2)
-		if(tuner_format <=9)
+		if(tuner_format <=0x0a)
 			tuner = tuner_0_table[tuner_format];
 	if (tuner_make == 1)
 		if(tuner_format <=9)
 			tuner = tuner_1_table[tuner_format];
 
+	if (tuner_make == 4)
+		if(tuner_format == 0x09)
+			tuner = TUNER_LG_NTSC_NEW_TAPC; // TAPC-G702P
+
 	printk(KERN_INFO "bttv%d: Avermedia eeprom[0x%02x%02x]: tuner=",
 		btv->c.nr,eeprom_data[0x41],eeprom_data[0x42]);
 	if(tuner) {
@@ -3167,6 +3133,7 @@
 
 static void __devinit boot_bt832(struct bttv *btv)
 {
+#if 0 /* not working yet */
 	int resetbit=0;
 
 	switch (btv->c.type) {
@@ -3195,6 +3162,7 @@
 	// 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
 }
 
 /* ----------------------------------------------------------------------- */
@@ -3281,7 +3249,7 @@
  * Brutally hacked by Dan Sheridan <dan.sheridan@contact.org.uk> djs52 8/3/00
  */
 
-void bus_low(struct bttv *btv, int bit)
+static void bus_low(struct bttv *btv, int bit)
 {
 	if (btv->mbox_ior) {
 		gpio_bits(btv->mbox_ior | btv->mbox_iow | btv->mbox_csel,
@@ -3298,7 +3266,7 @@
 	}
 }
 
-void bus_high(struct bttv *btv, int bit)
+static void bus_high(struct bttv *btv, int bit)
 {
 	if (btv->mbox_ior) {
 		gpio_bits(btv->mbox_ior | btv->mbox_iow | btv->mbox_csel,
@@ -3315,7 +3283,7 @@
 	}
 }
 
-int bus_in(struct bttv *btv, int bit)
+static int bus_in(struct bttv *btv, int bit)
 {
 	if (btv->mbox_ior) {
 		gpio_bits(btv->mbox_ior | btv->mbox_iow | btv->mbox_csel,
@@ -3883,6 +3851,47 @@
 	mdelay(1);
 	gpio_bits(0x480,0x080);
 	mdelay(1);
+}
+
+/* Tibet Systems 'Progress DVR' CS16 muxsel helper [Chris Fanning]
+ *
+ * The CS16 (available on eBay cheap) is a PCI board with four Fusion
+ * 878A chips, a PCI bridge, an Atmel microcontroller, four sync seperator
+ * chips, ten eight input analog multiplexors, a not chip and a few
+ * other components.
+ *
+ * 16 inputs on a secondary bracket are provided and can be selected
+ * from each of the four capture chips.  Two of the eight input
+ * multiplexors are used to select from any of the 16 input signals.
+ *
+ * Unsupported hardware capabilities:
+ *  . A video output monitor on the secondary bracket can be selected from
+ *    one of the 878A chips.
+ *  . Another passthrough but I haven't spent any time investigating it.
+ *  . Digital I/O (logic level connected to GPIO) is available from an
+ *    onboard header.
+ *
+ * The on chip input mux should always be set to 2.
+ * GPIO[16:19] - Video input selection
+ * GPIO[0:3]   - Video output monitor select (only available from one 878A)
+ * GPIO[?:?]   - Digital I/O.
+ *
+ * There is an ATMEL microcontroller with an 8031 core on board.  I have not
+ * determined what function (if any) it provides.  With the microcontroller
+ * and sync seperator chips a guess is that it might have to do with video
+ * switching and maybe some digital I/O.
+ */
+static void tibetCS16_muxsel(struct bttv *btv, unsigned int input)
+{
+	/* video mux */
+	gpio_bits(0x0f0000, input << 16);
+}
+
+static void tibetCS16_init(struct bttv *btv)
+{
+	/* enable gpio bits, mask obtained via btSpy */
+	gpio_inout(0xffffff, 0x0f7fff);
+	gpio_write(0x0f7fff);
 }
 
 // The Grandtec X-Guard framegrabber card uses two Dual 4-channel
diff -Nru a/drivers/media/video/bttv-driver.c b/drivers/media/video/bttv-driver.c
--- a/drivers/media/video/bttv-driver.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/media/video/bttv-driver.c	2005-03-01 23:39:08 -08:00
@@ -1,5 +1,5 @@
 /*
-    $Id: bttv-driver.c,v 1.27 2004/11/07 14:44:59 kraxel Exp $
+    $Id: bttv-driver.c,v 1.34 2005/01/07 13:11:19 kraxel Exp $
 
     bttv - Bt848 frame grabber driver
 
@@ -27,6 +27,7 @@
 
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/moduleparam.h>
 #include <linux/delay.h>
 #include <linux/errno.h>
 #include <linux/fs.h>
@@ -105,6 +106,7 @@
 module_param(whitecrush_upper,  int, 0444);
 module_param(whitecrush_lower,  int, 0444);
 module_param(vcr_hack,          int, 0444);
+
 module_param_array(radio, int, NULL, 0444);
 
 MODULE_PARM_DESC(radio,"The TV card supports radio, default is 0 (no)");
@@ -313,12 +315,12 @@
 		.sram           = -1,
 	}
 };
-const unsigned int BTTV_TVNORMS = ARRAY_SIZE(bttv_tvnorms);
+static const unsigned int BTTV_TVNORMS = ARRAY_SIZE(bttv_tvnorms);
 
 /* ----------------------------------------------------------------------- */
 /* bttv format list
    packed pixel formats must come first */
-const struct bttv_format bttv_formats[] = {
+static const struct bttv_format bttv_formats[] = {
 	{
 		.name     = "8 bpp, gray",
 		.palette  = VIDEO_PALETTE_GREY,
@@ -470,7 +472,7 @@
 		.flags    = FORMAT_FLAGS_RAW,
 	}
 };
-const unsigned int BTTV_FORMATS = ARRAY_SIZE(bttv_formats);
+static const unsigned int BTTV_FORMATS = ARRAY_SIZE(bttv_formats);
 
 /* ----------------------------------------------------------------------- */
 
@@ -619,7 +621,7 @@
 	}
 
 };
-const int BTTV_CTLS = ARRAY_SIZE(bttv_ctls);
+static const int BTTV_CTLS = ARRAY_SIZE(bttv_ctls);
 
 /* ----------------------------------------------------------------------- */
 /* resource management                                                     */
@@ -755,7 +757,7 @@
 }
 
 /* used to switch between the bt848's analog/digital video capture modes */
-void bt848A_set_timing(struct bttv *btv)
+static void bt848A_set_timing(struct bttv *btv)
 {
 	int i, len;
 	int table_idx = bttv_tvnorms[btv->tvnorm].sram;
@@ -1063,7 +1065,7 @@
 	init_irqreg(btv);
 }
 
-void bttv_reinit_bt848(struct bttv *btv)
+static void bttv_reinit_bt848(struct bttv *btv)
 {
 	unsigned long flags;
 
@@ -1267,7 +1269,7 @@
 	       btv->c.nr,outbits,data & outbits, data & ~outbits, comment);
 }
 
-void bttv_field_count(struct bttv *btv)
+static void bttv_field_count(struct bttv *btv)
 {
 	int need_count = 0;
 
@@ -1467,7 +1469,7 @@
 	"SMICROCODE", "GVBIFMT", "SVBIFMT" };
 #define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls)
 
-int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
+static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
 {
 	switch (cmd) {
         case BTTV_VERSION:
@@ -2531,9 +2533,11 @@
 			V4L2_CAP_VIDEO_CAPTURE |
 			V4L2_CAP_VIDEO_OVERLAY |
 			V4L2_CAP_VBI_CAPTURE |
-			V4L2_CAP_TUNER |
 			V4L2_CAP_READWRITE |
 			V4L2_CAP_STREAMING;
+		if (bttv_tvcards[btv->c.type].tuner != UNSET &&
+		    bttv_tvcards[btv->c.type].tuner != TUNER_ABSENT)
+			cap->capabilities |= V4L2_CAP_TUNER;
 		return 0;
 	}
 
@@ -2988,6 +2992,9 @@
 		free_btres(btv,fh,RESOURCE_VBI);
 	}
 
+	/* free stuff */
+	videobuf_mmap_free(&fh->cap);
+	videobuf_mmap_free(&fh->vbi);
 	v4l2_prio_close(&btv->prio,&fh->prio);
 	file->private_data = NULL;
 	kfree(fh);
@@ -3030,7 +3037,7 @@
 	.minor    = -1,
 };
 
-struct video_device bttv_vbi_template =
+static struct video_device bttv_vbi_template =
 {
 	.name     = "bt848/878 vbi",
 	.type     = VID_TYPE_TUNER|VID_TYPE_TELETEXT,
@@ -3717,8 +3724,8 @@
 	/* initialize structs / fill in defaults */
         init_MUTEX(&btv->lock);
         init_MUTEX(&btv->reslock);
-        btv->s_lock    = SPIN_LOCK_UNLOCKED;
-        btv->gpio_lock = SPIN_LOCK_UNLOCKED;
+        spin_lock_init(&btv->s_lock);
+        spin_lock_init(&btv->gpio_lock);
         init_waitqueue_head(&btv->gpioq);
         init_waitqueue_head(&btv->i2c_queue);
         INIT_LIST_HEAD(&btv->c.subs);
@@ -3942,7 +3949,7 @@
 
 	/* save pci state */
 	pci_save_state(pci_dev);
-	if (0 != pci_set_power_state(pci_dev, state)) {
+	if (0 != pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state))) {
 		pci_disable_device(pci_dev);
 		btv->state.disabled = 1;
 	}
@@ -3961,7 +3968,7 @@
 		pci_enable_device(pci_dev);
 		btv->state.disabled = 0;
 	}
-	pci_set_power_state(pci_dev, 0);
+	pci_set_power_state(pci_dev, PCI_D0);
 	pci_restore_state(pci_dev);
 
 	/* restore bt878 state */
diff -Nru a/drivers/media/video/bttv-i2c.c b/drivers/media/video/bttv-i2c.c
--- a/drivers/media/video/bttv-i2c.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/media/video/bttv-i2c.c	2005-03-01 23:38:52 -08:00
@@ -1,5 +1,5 @@
 /*
-    $Id: bttv-i2c.c,v 1.13 2004/11/07 13:17:15 kraxel Exp $
+    $Id: bttv-i2c.c,v 1.17 2004/12/14 15:33:30 kraxel Exp $
 
     bttv-i2c.c  --  all the i2c code is here
 
@@ -26,6 +26,7 @@
 */
 
 #include <linux/module.h>
+#include <linux/moduleparam.h>
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <asm/io.h>
@@ -51,7 +52,7 @@
 /* ----------------------------------------------------------------------- */
 /* I2C functions - bitbanging adapter (software i2c)                       */
 
-void bttv_bit_setscl(void *data, int state)
+static void bttv_bit_setscl(void *data, int state)
 {
 	struct bttv *btv = (struct bttv*)data;
 
@@ -63,7 +64,7 @@
 	btread(BT848_I2C);
 }
 
-void bttv_bit_setsda(void *data, int state)
+static void bttv_bit_setsda(void *data, int state)
 {
 	struct bttv *btv = (struct bttv*)data;
 
@@ -244,7 +245,7 @@
        	return retval;
 }
 
-int bttv_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num)
+static int bttv_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num)
 {
 	struct bttv *btv = i2c_get_adapdata(i2c_adap);
 	int retval = 0;
@@ -327,13 +328,6 @@
 	i2c_clients_command(&btv->c.i2c_adap, cmd, arg);
 }
 
-void bttv_i2c_call(unsigned int card, unsigned int cmd, void *arg)
-{
-	if (card >= bttv_num)
-		return;
-	bttv_call_i2c_clients(&bttvs[card], cmd, arg);
-}
-
 static struct i2c_client bttv_i2c_client_template = {
 	I2C_DEVNAME("bttv internal"),
         .id       = -1,
@@ -385,19 +379,8 @@
 /* read EEPROM content */
 void __devinit bttv_readee(struct bttv *btv, unsigned char *eedata, int addr)
 {
-	int i;
-
-	if (bttv_I2CWrite(btv, addr, 0, -1, 0)<0) {
-		printk(KERN_WARNING "bttv: readee error\n");
-		return;
-	}
 	btv->i2c_client.addr = addr >> 1;
-	for (i=0; i<256; i+=16) {
-		if (16 != i2c_master_recv(&btv->i2c_client,eedata+i,16)) {
-			printk(KERN_WARNING "bttv: readee error\n");
-			break;
-		}
-	}
+	tveeprom_read(&btv->i2c_client, eedata, 256);
 }
 
 static char *i2c_devs[128] = {
diff -Nru a/drivers/media/video/bttv-if.c b/drivers/media/video/bttv-if.c
--- a/drivers/media/video/bttv-if.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/media/video/bttv-if.c	2005-03-01 23:38:52 -08:00
@@ -1,5 +1,5 @@
 /*
-    $Id: bttv-if.c,v 1.3 2004/10/13 10:39:00 kraxel Exp $
+    $Id: bttv-if.c,v 1.4 2004/11/17 18:47:47 kraxel Exp $
 
     bttv-if.c  --  old gpio interface to other kernel modules
                    don't use in new code, will go away in 2.7
@@ -50,6 +50,8 @@
 
 int bttv_get_cardinfo(unsigned int card, int *type, unsigned *cardid)
 {
+	printk("The bttv_* interface is obsolete and will go away,\n"
+	       "please use the new, sysfs based interface instead.\n");
 	if (card >= bttv_num) {
 		return -1;
 	}
@@ -67,7 +69,8 @@
 
 int bttv_get_id(unsigned int card)
 {
-	printk("bttv_get_id is obsolete, use bttv_get_cardinfo instead\n");
+	printk("The bttv_* interface is obsolete and will go away,\n"
+	       "please use the new, sysfs based interface instead.\n");
 	if (card >= bttv_num) {
 		return -1;
 	}
@@ -141,6 +144,13 @@
 		return NULL;
 	}
 	return &btv->gpioq;
+}
+
+void bttv_i2c_call(unsigned int card, unsigned int cmd, void *arg)
+{
+	if (card >= bttv_num)
+		return;
+	bttv_call_i2c_clients(&bttvs[card], cmd, arg);
 }
 
 /*
diff -Nru a/drivers/media/video/bttv-risc.c b/drivers/media/video/bttv-risc.c
--- a/drivers/media/video/bttv-risc.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/media/video/bttv-risc.c	2005-03-01 23:38:57 -08:00
@@ -1,5 +1,5 @@
 /*
-    $Id: bttv-risc.c,v 1.9 2004/10/13 10:39:00 kraxel Exp $
+    $Id: bttv-risc.c,v 1.10 2004/11/19 18:07:12 kraxel Exp $
 
     bttv-risc.c  --  interfaces to other kernel modules
 
@@ -109,7 +109,7 @@
 	return 0;
 }
 
-int
+static int
 bttv_risc_planar(struct bttv *btv, struct btcx_riscmem *risc,
 		 struct scatterlist *sglist,
 		 unsigned int yoffset,  unsigned int ybpl,
@@ -227,7 +227,7 @@
 	return 0;
 }
 
-int
+static int
 bttv_risc_overlay(struct bttv *btv, struct btcx_riscmem *risc,
 		  const struct bttv_format *fmt, struct bttv_overlay *ov,
 		  int skip_even, int skip_odd)
@@ -315,7 +315,7 @@
 
 /* ---------------------------------------------------------- */
 
-void
+static void
 bttv_calc_geo(struct bttv *btv, struct bttv_geometry *geo,
 	      int width, int height, int interleaved, int norm)
 {
@@ -363,7 +363,7 @@
         }
 }
 
-void
+static void
 bttv_apply_geo(struct bttv *btv, struct bttv_geometry *geo, int odd)
 {
         int off = odd ? 0x80 : 0x00;
diff -Nru a/drivers/media/video/bttv-vbi.c b/drivers/media/video/bttv-vbi.c
--- a/drivers/media/video/bttv-vbi.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/media/video/bttv-vbi.c	2005-03-01 23:39:07 -08:00
@@ -1,5 +1,5 @@
 /*
-    $Id: bttv-vbi.c,v 1.7 2004/11/07 13:17:15 kraxel Exp $
+    $Id: bttv-vbi.c,v 1.9 2005/01/13 17:22:33 kraxel Exp $
 
     bttv - Bt848 frame grabber driver
     vbi interface
@@ -22,6 +22,7 @@
 */
 
 #include <linux/module.h>
+#include <linux/moduleparam.h>
 #include <linux/errno.h>
 #include <linux/fs.h>
 #include <linux/kernel.h>
@@ -182,7 +183,7 @@
 	case 2: /* SECAM */
 	default:
 		start0 = 7;
-		start1 = 319;
+		start1 = 320;
 	}
 
 	count0 = (f->fmt.vbi.start[0] + f->fmt.vbi.count[0]) - start0;
diff -Nru a/drivers/media/video/bttv.h b/drivers/media/video/bttv.h
--- a/drivers/media/video/bttv.h	2005-03-01 23:38:52 -08:00
+++ b/drivers/media/video/bttv.h	2005-03-01 23:38:52 -08:00
@@ -1,5 +1,5 @@
 /*
- * $Id: bttv.h,v 1.10 2004/10/13 10:39:00 kraxel Exp $
+ * $Id: bttv.h,v 1.14 2005/01/07 13:11:19 kraxel Exp $
  *
  *  bttv - Bt848 frame grabber driver
  *
@@ -133,6 +133,7 @@
 #define BTTV_MATRIX_VISIONSLC 0x7e
 #define BTTV_APAC_VIEWCOMP  0x7f
 #define BTTV_DVICO_DVBT_LITE  0x80
+#define BTTV_TIBET_CS16  0x83
 
 /* i2c address list */
 #define I2C_TSA5522        0xc2
@@ -149,7 +150,7 @@
 #define I2C_VHX            0xc0
 #define I2C_MSP3400        0x80
 #define I2C_MSP3400_ALT    0x88
-#define I2C_TEA6300        0x80
+#define I2C_TEA6300        0x80 /* also used by 6320 */
 #define I2C_DPL3518	   0x84
 #define I2C_TDA9887	   0x86
 
@@ -219,7 +220,6 @@
 };
 
 extern struct tvcard bttv_tvcards[];
-extern const unsigned int bttv_num_tvcards;
 
 /* identification / initialization of the card */
 extern void bttv_idcard(struct bttv *btv);
@@ -325,8 +325,6 @@
 /* ---------------------------------------------------------- */
 /* i2c                                                        */
 
-extern void bttv_bit_setscl(void *data, int state);
-extern void bttv_bit_setsda(void *data, int state);
 extern void bttv_call_i2c_clients(struct bttv *btv, unsigned int cmd, void *arg);
 extern int bttv_I2CRead(struct bttv *btv, unsigned char addr, char *probe_for);
 extern int bttv_I2CWrite(struct bttv *btv, unsigned char addr, unsigned char b1,
diff -Nru a/drivers/media/video/bttvp.h b/drivers/media/video/bttvp.h
--- a/drivers/media/video/bttvp.h	2005-03-01 23:39:18 -08:00
+++ b/drivers/media/video/bttvp.h	2005-03-01 23:39:18 -08:00
@@ -1,5 +1,5 @@
 /*
-    $Id: bttvp.h,v 1.12 2004/10/25 11:26:36 kraxel Exp $
+    $Id: bttvp.h,v 1.15 2004/12/14 15:33:30 kraxel Exp $
 
     bttv - Bt848 frame grabber driver
 
@@ -43,6 +43,7 @@
 #include <media/video-buf.h>
 #include <media/audiochip.h>
 #include <media/tuner.h>
+#include <media/tveeprom.h>
 #include <media/ir-common.h>
 
 #include "bt848.h"
@@ -89,7 +90,6 @@
 	int   sram;
 };
 extern const struct bttv_tvnorm bttv_tvnorms[];
-extern const unsigned int BTTV_TVNORMS;
 
 struct bttv_format {
 	char *name;
@@ -101,8 +101,6 @@
 	int  flags;
 	int  hshift,vshift;   /* for planar modes   */
 };
-extern const struct bttv_format bttv_formats[];
-extern const unsigned int BTTV_FORMATS;
 
 /* ---------------------------------------------------------- */
 
@@ -173,22 +171,6 @@
 		     struct scatterlist *sglist,
 		     unsigned int offset, unsigned int bpl,
 		     unsigned int pitch, unsigned int lines);
-int bttv_risc_planar(struct bttv *btv, struct btcx_riscmem *risc,
-		     struct scatterlist *sglist,
-		     unsigned int yoffset,  unsigned int ybpl,
-		     unsigned int ypadding, unsigned int ylines,
-		     unsigned int uoffset,  unsigned int voffset,
-		     unsigned int hshift,   unsigned int vshift,
-		     unsigned int cpadding);
-int bttv_risc_overlay(struct bttv *btv, struct btcx_riscmem *risc,
-		      const struct bttv_format *fmt,
-		      struct bttv_overlay *ov,
-		      int skip_top, int skip_bottom);
-
-/* calculate / apply geometry settings */
-void bttv_calc_geo(struct bttv *btv, struct bttv_geometry *geo,
-		   int width, int height, int interleaved, int norm);
-void bttv_apply_geo(struct bttv *btv, struct bttv_geometry *geo, int top);
 
 /* control dma register + risc main loop */
 void bttv_set_dma(struct bttv *btv, int override);
@@ -240,11 +222,6 @@
 extern void bttv_gpio_tracking(struct bttv *btv, char *comment);
 extern int init_bttv_i2c(struct bttv *btv);
 extern int fini_bttv_i2c(struct bttv *btv);
-extern int pvr_boot(struct bttv *btv);
-
-extern int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg);
-extern void bttv_reinit_bt848(struct bttv *btv);
-extern void bttv_field_count(struct bttv *btv);
 
 #define vprintk  if (bttv_verbose) printk
 #define dprintk  if (bttv_debug >= 1) printk
diff -Nru a/drivers/media/video/bw-qcam.c b/drivers/media/video/bw-qcam.c
--- a/drivers/media/video/bw-qcam.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/media/video/bw-qcam.c	2005-03-01 23:38:54 -08:00
@@ -82,9 +82,9 @@
 static unsigned int yieldlines=4;  /* Yield after this many during capture */
 static int video_nr = -1;
 
-MODULE_PARM(maxpoll,"i");
-MODULE_PARM(yieldlines,"i");   
-MODULE_PARM(video_nr,"i");
+module_param(maxpoll, int, 0);
+module_param(yieldlines, int, 0);
+module_param(video_nr, int, 0);
 
 static inline int read_lpstatus(struct qcam_device *q)
 {
@@ -441,7 +441,7 @@
 /* Reset the QuickCam and program for brightness, contrast,
  * white-balance, and resolution. */
 
-void qc_set(struct qcam_device *q)
+static void qc_set(struct qcam_device *q)
 {
 	int val;
 	int val2;
@@ -591,7 +591,7 @@
  * n=2^(bit depth)-1.  Ask me for more details if you don't understand
  * this. */
 
-long qc_capture(struct qcam_device * q, char __user *buf, unsigned long len)
+static long qc_capture(struct qcam_device * q, char __user *buf, unsigned long len)
 {
 	int i, j, k, yield;
 	int bytes;
@@ -891,7 +891,7 @@
 static struct qcam_device *qcams[MAX_CAMS];
 static unsigned int num_cams = 0;
 
-int init_bwqcam(struct parport *port)
+static int init_bwqcam(struct parport *port)
 {
 	struct qcam_device *qcam;
 
@@ -934,7 +934,7 @@
 	return 0;
 }
 
-void close_bwqcam(struct qcam_device *qcam)
+static void close_bwqcam(struct qcam_device *qcam)
 {
 	video_unregister_device(&qcam->vdev);
 	parport_unregister_device(qcam->pdev);
@@ -946,7 +946,7 @@
  *       -- March 14, 1999  Billy Donahue <billy@escape.com> */
 #ifdef MODULE
 static char *parport[MAX_CAMS] = { NULL, };
-MODULE_PARM(parport, "1-" __MODULE_STRING(MAX_CAMS) "s");
+module_param_array(parport, charp, NULL, 0);
 #endif
 
 static int accept_bwqcam(struct parport *port)
diff -Nru a/drivers/media/video/c-qcam.c b/drivers/media/video/c-qcam.c
--- a/drivers/media/video/c-qcam.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/media/video/c-qcam.c	2005-03-01 23:38:56 -08:00
@@ -741,7 +741,7 @@
 static struct qcam_device *qcams[MAX_CAMS];
 static unsigned int num_cams = 0;
 
-int init_cqcam(struct parport *port)
+static int init_cqcam(struct parport *port)
 {
 	struct qcam_device *qcam;
 
@@ -798,7 +798,7 @@
 	return 0;
 }
 
-void close_cqcam(struct qcam_device *qcam)
+static void close_cqcam(struct qcam_device *qcam)
 {
 	video_unregister_device(&qcam->vdev);
 	parport_unregister_device(qcam->pdev);
@@ -842,13 +842,14 @@
 MODULE_DESCRIPTION(BANNER);
 MODULE_LICENSE("GPL");
 
+/* FIXME: parport=auto would never have worked, surely? --RR */
 MODULE_PARM_DESC(parport ,"parport=<auto|n[,n]...> for port detection method\n\
 probe=<0|1|2> for camera detection method\n\
 force_rgb=<0|1> for RGB data format (default BGR)");
-MODULE_PARM(parport, "1-" __MODULE_STRING(MAX_CAMS) "i");
-MODULE_PARM(probe, "i");
-MODULE_PARM(force_rgb, "i");
-MODULE_PARM(video_nr,"i");
+module_param_array(parport, int, NULL, 0);
+module_param(probe, int, 0);
+module_param(force_rgb, bool, 0);
+module_param(video_nr, int, 0);
 
 module_init(cqcam_init);
 module_exit(cqcam_cleanup);
diff -Nru a/drivers/media/video/cpia.c b/drivers/media/video/cpia.c
--- a/drivers/media/video/cpia.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/media/video/cpia.c	2005-03-01 23:39:08 -08:00
@@ -57,7 +57,7 @@
 static int video_nr = -1;
 
 #ifdef MODULE
-MODULE_PARM(video_nr,"i");
+module_param(video_nr, int, 0);
 MODULE_AUTHOR("Scott J. Bertin <sbertin@securenym.net> & Peter Pregler <Peter_Pregler@email.com> & Johannes Erdfelt <johannes@erdfeld.com>");
 MODULE_DESCRIPTION("V4L-driver for Vision CPiA based cameras");
 MODULE_LICENSE("GPL");
diff -Nru a/drivers/media/video/cpia_pp.c b/drivers/media/video/cpia_pp.c
--- a/drivers/media/video/cpia_pp.c	2005-03-01 23:38:44 -08:00
+++ b/drivers/media/video/cpia_pp.c	2005-03-01 23:38:44 -08:00
@@ -71,7 +71,7 @@
 MODULE_DESCRIPTION("Parallel port driver for Vision CPiA based cameras");
 MODULE_LICENSE("GPL");
 
-MODULE_PARM(parport, "1-" __MODULE_STRING(PARPORT_MAX) "s");
+module_param_array(parport, charp, NULL, 0);
 MODULE_PARM_DESC(parport, "'auto' or a list of parallel port numbers. Just like lp.");
 #else
 static int parport_nr[PARPORT_MAX] __initdata =
diff -Nru a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c
--- a/drivers/media/video/cx88/cx88-i2c.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/media/video/cx88/cx88-i2c.c	2005-03-01 23:38:55 -08:00
@@ -134,7 +134,7 @@
 static struct i2c_adapter cx8800_i2c_adap_template = {
 	I2C_DEVNAME("cx2388x"),
 	.owner             = THIS_MODULE,
-	.id                = I2C_HW_B_BT848,
+	.id                = I2C_HW_B_CX2388x,
 	.client_register   = attach_inform,
 	.client_unregister = detach_inform,
 };
diff -Nru a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c
--- a/drivers/media/video/cx88/cx88-mpeg.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/media/video/cx88/cx88-mpeg.c	2005-03-01 23:39:18 -08:00
@@ -343,7 +343,7 @@
 
 	/* initialize driver struct */
         init_MUTEX(&dev->lock);
-	dev->slock = SPIN_LOCK_UNLOCKED;
+	spin_lock_init(&dev->slock);
 
 	/* init dma queue */
 	INIT_LIST_HEAD(&dev->mpegq.active);
diff -Nru a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
--- a/drivers/media/video/cx88/cx88-video.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/media/video/cx88/cx88-video.c	2005-03-01 23:38:58 -08:00
@@ -2026,7 +2026,7 @@
 
 	/* initialize driver struct */
         init_MUTEX(&dev->lock);
-	dev->slock = SPIN_LOCK_UNLOCKED;
+	spin_lock_init(&dev->slock);
 	core->tvnorm = tvnorms;
 
 	/* init video dma queues */
diff -Nru a/drivers/media/video/dpc7146.c b/drivers/media/video/dpc7146.c
--- a/drivers/media/video/dpc7146.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/media/video/dpc7146.c	2005-03-01 23:38:56 -08:00
@@ -55,11 +55,10 @@
 #define DPC_BOARD_CAN_DO_VBI(dev)   (dev->revision != 0) 
 
 static int debug = 0;
-MODULE_PARM(debug,"i");
+module_param(debug, int, 0);
 MODULE_PARM_DESC(debug, "debug verbosity");
 
-/* global variables */
-int dpc_num = 0;
+static int dpc_num = 0;
 
 #define DPC_INPUTS	2
 static struct v4l2_input dpc_inputs[DPC_INPUTS] = {
@@ -379,7 +378,7 @@
 	.irq_func	= NULL,
 };	
 
-int __init dpc_init_module(void) 
+static int __init dpc_init_module(void)
 {
 	if( 0 != saa7146_register_extension(&extension)) {
 		DEB_S(("failed to register extension.\n"));
@@ -389,7 +388,7 @@
 	return 0;
 }
 
-void __exit dpc_cleanup_module(void) 
+static void __exit dpc_cleanup_module(void)
 {
 	saa7146_unregister_extension(&extension);
 }
diff -Nru a/drivers/media/video/hexium_gemini.c b/drivers/media/video/hexium_gemini.c
--- a/drivers/media/video/hexium_gemini.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/media/video/hexium_gemini.c	2005-03-01 23:38:54 -08:00
@@ -26,7 +26,7 @@
 #include <media/saa7146_vv.h>
 
 static int debug = 0;
-MODULE_PARM(debug, "i");
+module_param(debug, int, 0);
 MODULE_PARM_DESC(debug, "debug verbosity");
 
 /* global variables */
diff -Nru a/drivers/media/video/hexium_orion.c b/drivers/media/video/hexium_orion.c
--- a/drivers/media/video/hexium_orion.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/media/video/hexium_orion.c	2005-03-01 23:39:18 -08:00
@@ -26,7 +26,7 @@
 #include <media/saa7146_vv.h>
 
 static int debug = 0;
-MODULE_PARM(debug, "i");
+module_param(debug, int, 0);
 MODULE_PARM_DESC(debug, "debug verbosity");
 
 /* global variables */
@@ -499,7 +499,7 @@
 	.irq_func = NULL,
 };
 
-int __init hexium_init_module(void)
+static int __init hexium_init_module(void)
 {
 	if (0 != saa7146_register_extension(&extension)) {
 		DEB_S(("failed to register extension.\n"));
@@ -509,7 +509,7 @@
 	return 0;
 }
 
-void __exit hexium_cleanup_module(void)
+static void __exit hexium_cleanup_module(void)
 {
 	saa7146_unregister_extension(&extension);
 }
diff -Nru a/drivers/media/video/ir-kbd-gpio.c b/drivers/media/video/ir-kbd-gpio.c
--- a/drivers/media/video/ir-kbd-gpio.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/media/video/ir-kbd-gpio.c	2005-03-01 23:39:09 -08:00
@@ -1,5 +1,5 @@
 /*
- * $Id: ir-kbd-gpio.c,v 1.10 2004/09/15 16:15:24 kraxel Exp $
+ * $Id: ir-kbd-gpio.c,v 1.11 2004/10/25 11:26:36 kraxel Exp $
  *
  * Copyright (c) 2003 Gerd Knorr
  * Copyright (c) 2003 Pavel Machek
@@ -366,7 +366,7 @@
 		break;
 
 	case BTTV_AVDVBT_761:
-	/* case BTTV_AVDVBT_771: */
+	case BTTV_AVDVBT_771:
 		ir_codes         = ir_codes_avermedia_dvbt;
 		ir->mask_keycode = 0x0f00c0;
 		ir->mask_keydown = 0x000020;
diff -Nru a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c
--- a/drivers/media/video/ir-kbd-i2c.c	2005-03-01 23:38:44 -08:00
+++ b/drivers/media/video/ir-kbd-i2c.c	2005-03-01 23:38:44 -08:00
@@ -1,5 +1,5 @@
 /*
- * $Id: ir-kbd-i2c.c,v 1.8 2004/09/15 16:15:24 kraxel Exp $
+ * $Id: ir-kbd-i2c.c,v 1.10 2004/12/09 12:51:35 kraxel Exp $
  *
  * keyboard input driver for i2c IR remote controls
  *
@@ -155,16 +155,6 @@
 
 /* ----------------------------------------------------------------------- */
 
-static inline int reverse(int data, int bits)
-{
-	int i,c;
-
-	for (c=0,i=0; i<bits; i++) {
-		c |= (((data & (1<<i)) ? 1:0)) << (bits-1-i);
-	}
-	return c;
-}
-
 static int get_key_haup(struct IR *ir, u32 *ir_key, u32 *ir_raw)
 {
 	unsigned char buf[3];
@@ -443,7 +433,7 @@
 	*/
 
 	static const int probe_bttv[] = { 0x1a, 0x18, 0x4b, 0x64, 0x30, -1};
-	static const int probe_saa7134[] = { 0x7a, -1};
+	static const int probe_saa7134[] = { 0x7a, -1 };
 	const int *probe = NULL;
 	struct i2c_client c; char buf; int i,rc;
 
diff -Nru a/drivers/media/video/meye.c b/drivers/media/video/meye.c
--- a/drivers/media/video/meye.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/media/video/meye.c	2005-03-01 23:38:58 -08:00
@@ -1829,14 +1829,14 @@
 		goto outvmalloc;
 	}
 
-	meye.grabq_lock = SPIN_LOCK_UNLOCKED;
+	spin_lock_init(&meye.grabq_lock);
 	meye.grabq = kfifo_alloc(sizeof(int) * MEYE_MAX_BUFNBRS, GFP_KERNEL,
 				 &meye.grabq_lock);
 	if (IS_ERR(meye.grabq)) {
 		printk(KERN_ERR "meye: fifo allocation failed\n");
 		goto outkfifoalloc1;
 	}
-	meye.doneq_lock = SPIN_LOCK_UNLOCKED;
+	spin_lock_init(&meye.doneq_lock);
 	meye.doneq = kfifo_alloc(sizeof(int) * MEYE_MAX_BUFNBRS, GFP_KERNEL,
 				 &meye.doneq_lock);
 	if (IS_ERR(meye.doneq)) {
diff -Nru a/drivers/media/video/msp3400.c b/drivers/media/video/msp3400.c
--- a/drivers/media/video/msp3400.c	2005-03-01 23:39:06 -08:00
+++ b/drivers/media/video/msp3400.c	2005-03-01 23:39:06 -08:00
@@ -36,6 +36,7 @@
 
 #include <linux/config.h>
 #include <linux/module.h>
+#include <linux/moduleparam.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/string.h>
@@ -379,7 +380,7 @@
 	int val = 0, bal = 0;
 
 	if (!muted) {
-		val = (volume * 0x73 / 65535) << 8;
+		val = (volume * 0x7F / 65535) << 8;
 	}
 	if (val) {
 		bal = (balance / 256) - 128;
@@ -633,14 +634,6 @@
 	char *name;
 };
 
-struct REGISTER_DUMP d1[] = {
-	{ 0x007e, "autodetect" },
-	{ 0x0023, "C_AD_BITS " },
-	{ 0x0038, "ADD_BITS  " },
-	{ 0x003e, "CIB_BITS  " },
-	{ 0x0057, "ERROR_RATE" },
-};
-
 static int
 autodetect_stereo(struct i2c_client *client)
 {
@@ -1210,7 +1203,7 @@
 static int msp34xxg_init(struct i2c_client *client)
 {
 	struct msp3400c *msp = i2c_get_clientdata(client);
-	int modus;
+	int modus,std;
 
 	if (msp3400c_reset(client))
 		return -1;
@@ -1224,12 +1217,18 @@
 
 	/* step-by-step initialisation, as described in the manual */
 	modus = msp34xx_modus(msp->norm);
+	std   = msp34xx_standard(msp->norm);
 	modus &= ~0x03; /* STATUS_CHANGE=0 */
 	modus |= 0x01;  /* AUTOMATIC_SOUND_DETECTION=1 */
 	if (msp3400c_write(client,
 			   I2C_MSP3400C_DEM,
 			   0x30/*MODUS*/,
 			   modus))
+		return -1;
+	if (msp3400c_write(client,
+			   I2C_MSP3400C_DEM,
+			   0x20/*stanard*/,
+			   std))
 		return -1;
 
 	/* write the dfps that may have an influence on
diff -Nru a/drivers/media/video/mxb.c b/drivers/media/video/mxb.c
--- a/drivers/media/video/mxb.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/media/video/mxb.c	2005-03-01 23:38:52 -08:00
@@ -1012,7 +1012,7 @@
 	.irq_func	= NULL,
 };	
 
-int __init mxb_init_module(void) 
+static int __init mxb_init_module(void)
 {
 	if( 0 != saa7146_register_extension(&extension)) {
 		DEB_S(("failed to register extension.\n"));
@@ -1022,7 +1022,7 @@
 	return 0;
 }
 
-void __exit mxb_cleanup_module(void) 
+static void __exit mxb_cleanup_module(void)
 {
 	saa7146_unregister_extension(&extension);
 }
diff -Nru a/drivers/media/video/mxb.h b/drivers/media/video/mxb.h
--- a/drivers/media/video/mxb.h	2005-03-01 23:39:09 -08:00
+++ b/drivers/media/video/mxb.h	2005-03-01 23:39:09 -08:00
@@ -12,7 +12,7 @@
 
 /* these are the available audio sources, which can switched
    to the line- and cd-output individually */
-struct v4l2_audio mxb_audios[MXB_AUDIOS] = {
+static struct v4l2_audio mxb_audios[MXB_AUDIOS] = {
 	    {
 		.index	= 0,
 		.name	= "Tuner",
diff -Nru a/drivers/media/video/pms.c b/drivers/media/video/pms.c
--- a/drivers/media/video/pms.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/media/video/pms.c	2005-03-01 23:39:09 -08:00
@@ -896,7 +896,7 @@
 	.fops           = &pms_fops,
 };
 
-struct pms_device pms_device;
+static struct pms_device pms_device;
 
 
 /*
@@ -1036,9 +1036,9 @@
 	return video_register_device((struct video_device *)&pms_device, VFL_TYPE_GRABBER, video_nr);
 }
 
-MODULE_PARM(io_port,"i");
-MODULE_PARM(mem_base,"i");
-MODULE_PARM(video_nr,"i");
+module_param(io_port, int, 0);
+module_param(mem_base, int, 0);
+module_param(video_nr, int, 0);
 MODULE_LICENSE("GPL");
 
 
diff -Nru a/drivers/media/video/saa5246a.c b/drivers/media/video/saa5246a.c
--- a/drivers/media/video/saa5246a.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/media/video/saa5246a.c	2005-03-01 23:38:56 -08:00
@@ -682,6 +682,54 @@
 }
 
 /*
+ * Translates old vtx IOCTLs to new ones
+ *
+ * This keeps new kernel versions compatible with old userspace programs.
+ */
+static inline unsigned int vtx_fix_command(unsigned int cmd)
+{
+	switch (cmd) {
+	case VTXIOCGETINFO_OLD:
+		cmd = VTXIOCGETINFO;
+		break;
+	case VTXIOCCLRPAGE_OLD:
+		cmd = VTXIOCCLRPAGE;
+		break;
+	case VTXIOCCLRFOUND_OLD:
+		cmd = VTXIOCCLRFOUND;
+		break;
+	case VTXIOCPAGEREQ_OLD:
+		cmd = VTXIOCPAGEREQ;
+		break;
+	case VTXIOCGETSTAT_OLD:
+		cmd = VTXIOCGETSTAT;
+		break;
+	case VTXIOCGETPAGE_OLD:
+		cmd = VTXIOCGETPAGE;
+		break;
+	case VTXIOCSTOPDAU_OLD:
+		cmd = VTXIOCSTOPDAU;
+		break;
+	case VTXIOCPUTPAGE_OLD:
+		cmd = VTXIOCPUTPAGE;
+		break;
+	case VTXIOCSETDISP_OLD:
+		cmd = VTXIOCSETDISP;
+		break;
+	case VTXIOCPUTSTAT_OLD:
+		cmd = VTXIOCPUTSTAT;
+		break;
+	case VTXIOCCLRCACHE_OLD:
+		cmd = VTXIOCCLRCACHE;
+		break;
+	case VTXIOCSETVIRT_OLD:
+		cmd = VTXIOCSETVIRT;
+		break;
+	}
+	return cmd;
+}
+
+/*
  *	Handle the locking
  */
 static int saa5246a_ioctl(struct inode *inode, struct file *file,
@@ -691,6 +739,7 @@
 	struct saa5246a_device *t = vd->priv;
 	int err;
 
+	cmd = vtx_fix_command(cmd);
 	down(&t->lock);
 	err = video_usercopy(inode, file, cmd, arg, do_saa5246a_ioctl);
 	up(&t->lock);
diff -Nru a/drivers/media/video/saa5246a.h b/drivers/media/video/saa5246a.h
--- a/drivers/media/video/saa5246a.h	2005-03-01 23:39:08 -08:00
+++ b/drivers/media/video/saa5246a.h	2005-03-01 23:39:08 -08:00
@@ -23,7 +23,7 @@
 #define __SAA5246A_H__
 
 #define MAJOR_VERSION 1		/* driver major version number */
-#define MINOR_VERSION 7		/* driver minor version number */
+#define MINOR_VERSION 8		/* driver minor version number */
 
 #define IF_NAME "SAA5246A"
 
diff -Nru a/drivers/media/video/saa5249.c b/drivers/media/video/saa5249.c
--- a/drivers/media/video/saa5249.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/media/video/saa5249.c	2005-03-01 23:39:08 -08:00
@@ -1,4 +1,7 @@
 /*
+ * Modified in order to keep it compatible both with new and old videotext IOCTLs by
+ * Michael Geng <linux@MichaelGeng.de>
+ *
  *	Cleaned up to use existing videodev interface and allow the idea
  *	of multiple teletext decoders on the video4linux iface. Changed i2c
  *	to cover addressing clashes on device busses. It's also rebuilt so
@@ -58,7 +61,7 @@
 #include <asm/uaccess.h>
 
 #define VTX_VER_MAJ 1
-#define VTX_VER_MIN 7
+#define VTX_VER_MIN 8
 
 
 
@@ -578,6 +581,54 @@
 }
 
 /*
+ * Translates old vtx IOCTLs to new ones
+ *
+ * This keeps new kernel versions compatible with old userspace programs.
+ */
+static inline unsigned int vtx_fix_command(unsigned int cmd)
+{
+	switch (cmd) {
+	case VTXIOCGETINFO_OLD:
+		cmd = VTXIOCGETINFO;
+		break;
+	case VTXIOCCLRPAGE_OLD:
+		cmd = VTXIOCCLRPAGE;
+		break;
+	case VTXIOCCLRFOUND_OLD:
+		cmd = VTXIOCCLRFOUND;
+		break;
+	case VTXIOCPAGEREQ_OLD:
+		cmd = VTXIOCPAGEREQ;
+		break;
+	case VTXIOCGETSTAT_OLD:
+		cmd = VTXIOCGETSTAT;
+		break;
+	case VTXIOCGETPAGE_OLD:
+		cmd = VTXIOCGETPAGE;
+		break;
+	case VTXIOCSTOPDAU_OLD:
+		cmd = VTXIOCSTOPDAU;
+		break;
+	case VTXIOCPUTPAGE_OLD:
+		cmd = VTXIOCPUTPAGE;
+		break;
+	case VTXIOCSETDISP_OLD:
+		cmd = VTXIOCSETDISP;
+		break;
+	case VTXIOCPUTSTAT_OLD:
+		cmd = VTXIOCPUTSTAT;
+		break;
+	case VTXIOCCLRCACHE_OLD:
+		cmd = VTXIOCCLRCACHE;
+		break;
+	case VTXIOCSETVIRT_OLD:
+		cmd = VTXIOCSETVIRT;
+		break;
+	}
+	return cmd;
+}
+
+/*
  *	Handle the locking
  */
  
@@ -588,6 +639,7 @@
 	struct saa5249_device *t=vd->priv;
 	int err;
 	
+	cmd = vtx_fix_command(cmd);
 	down(&t->lock);
 	err = video_usercopy(inode,file,cmd,arg,do_saa5249_ioctl);
 	up(&t->lock);
diff -Nru a/drivers/media/video/saa7110.c b/drivers/media/video/saa7110.c
--- a/drivers/media/video/saa7110.c	2005-03-01 23:38:43 -08:00
+++ b/drivers/media/video/saa7110.c	2005-03-01 23:38:43 -08:00
@@ -46,7 +46,7 @@
 #include <linux/video_decoder.h>
 
 static int debug = 0;
-MODULE_PARM(debug, "i");
+module_param(debug, int, 0);
 MODULE_PARM_DESC(debug, "Debug level (0-1)");
 
 #define dprintk(num, format, args...) \
diff -Nru a/drivers/media/video/saa7114.c b/drivers/media/video/saa7114.c
--- a/drivers/media/video/saa7114.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/media/video/saa7114.c	2005-03-01 23:39:09 -08:00
@@ -63,7 +63,7 @@
 #include <linux/video_decoder.h>
 
 static int debug = 0;
-MODULE_PARM(debug, "i");
+module_param(debug, int, 0);
 MODULE_PARM_DESC(debug, "Debug level (0-1)");
 
 #define dprintk(num, format, args...) \
diff -Nru a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
--- a/drivers/media/video/saa7134/saa7134-core.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/media/video/saa7134/saa7134-core.c	2005-03-01 23:38:55 -08:00
@@ -21,6 +21,7 @@
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/list.h>
 #include <linux/module.h>
@@ -222,10 +223,61 @@
 }
 #endif
 
+/* ----------------------------------------------------------- */
+/* delayed request_module                                      */
+
+#ifdef CONFIG_MODULES
+
+static int need_empress;
+static int need_dvb;
+
+static int pending_call(struct notifier_block *self, unsigned long state,
+			void *module)
+{
+	if (module != THIS_MODULE || state != MODULE_STATE_LIVE)
+		return NOTIFY_DONE;
+
+        if (need_empress)
+                request_module("saa7134-empress");
+        if (need_dvb)
+                request_module("saa7134-dvb");
+	return NOTIFY_DONE;
+}
+
+static int pending_registered;
+static struct notifier_block pending_notifier = {
+	.notifier_call = pending_call,
+};
+
+static void request_module_depend(char *name, int *flag)
+{
+	switch (THIS_MODULE->state) {
+	case MODULE_STATE_COMING:
+		if (!pending_registered) {
+			register_module_notifier(&pending_notifier);
+			pending_registered = 1;
+		}
+		*flag = 1;
+		break;
+	case MODULE_STATE_LIVE:
+		request_module(name);
+		break;
+	default:
+		/* nothing */;
+		break;
+	}
+}
+
+#else
+
+#define request_module_depend(name,flag)
+
+#endif /* CONFIG_MODULES */
+
 /* ------------------------------------------------------------------ */
 
 /* nr of (saa7134-)pages for the given buffer size */
-int saa7134_buffer_pages(int size)
+static int saa7134_buffer_pages(int size)
 {
 	size  = PAGE_ALIGN(size);
 	size += PAGE_SIZE; /* for non-page-aligned buffers */
@@ -319,10 +371,8 @@
 			 struct saa7134_buf *buf)
 {
 	struct saa7134_buf *next = NULL;
-#ifdef DEBUG_SPINLOCKS
-	BUG_ON(!spin_is_locked(&dev->slock));
-#endif
 
+	assert_spin_locked(&dev->slock);
 	dprintk("buffer_queue %p\n",buf);
 	if (NULL == q->curr) {
 		if (!q->need_two) {
@@ -348,9 +398,7 @@
 			   struct saa7134_dmaqueue *q,
 			   unsigned int state)
 {
-#ifdef DEBUG_SPINLOCKS
-	BUG_ON(!spin_is_locked(&dev->slock));
-#endif
+	assert_spin_locked(&dev->slock);
 	dprintk("buffer_finish %p\n",q->curr);
 
 	/* finish current buffer */
@@ -365,9 +413,7 @@
 {
 	struct saa7134_buf *buf,*next = NULL;
 
-#ifdef DEBUG_SPINLOCKS
-	BUG_ON(!spin_is_locked(&dev->slock));
-#endif
+	assert_spin_locked(&dev->slock);
 	BUG_ON(NULL != q->curr);
 
 	if (!list_empty(&q->queue)) {
@@ -422,9 +468,7 @@
 	enum v4l2_field cap = V4L2_FIELD_ANY;
 	enum v4l2_field ov  = V4L2_FIELD_ANY;
 
-#ifdef DEBUG_SPINLOCKS
-	BUG_ON(!spin_is_locked(&dev->slock));
-#endif
+	assert_spin_locked(&dev->slock);
 
 	/* video capture -- dma 0 + video task A */
 	if (dev->video_q.curr) {
@@ -630,7 +674,7 @@
 	saa_writel(SAA7134_IRQ1, 0);
 	saa_writel(SAA7134_IRQ2, 0);
         init_MUTEX(&dev->lock);
-	dev->slock = SPIN_LOCK_UNLOCKED;
+	spin_lock_init(&dev->slock);
 
 	saa7134_track_gpio(dev,"pre-init");
 	saa7134_video_init1(dev);
@@ -941,11 +985,11 @@
 	if (dev->tda9887_conf)
 		request_module("tda9887");
   	if (card_is_empress(dev)) {
-		request_module("saa7134-empress");
 		request_module("saa6752hs");
+		request_module_depend("saa7134-empress",&need_empress);
 	}
   	if (card_is_dvb(dev))
-		request_module("saa7134-dvb");
+		request_module_depend("saa7134-dvb",&need_dvb);
 
 	v4l2_prio_init(&dev->prio);
 
diff -Nru a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c
--- a/drivers/media/video/saa7134/saa7134-video.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/media/video/saa7134/saa7134-video.c	2005-03-01 23:38:53 -08:00
@@ -1378,7 +1378,7 @@
 
 /* ------------------------------------------------------------------ */
 
-void saa7134_vbi_fmt(struct saa7134_dev *dev, struct v4l2_format *f)
+static void saa7134_vbi_fmt(struct saa7134_dev *dev, struct v4l2_format *f)
 {
 	struct saa7134_tvnorm *norm = dev->tvnorm;
 
@@ -1401,8 +1401,8 @@
 #endif
 }
 
-int saa7134_g_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh,
-		  struct v4l2_format *f)
+static int saa7134_g_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh,
+			 struct v4l2_format *f)
 {
 	switch (f->type) {
 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
@@ -1427,8 +1427,8 @@
 	}
 }
 
-int saa7134_try_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh,
-		    struct v4l2_format *f)
+static int saa7134_try_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh,
+			   struct v4l2_format *f)
 {
 	int err;
 
@@ -1492,8 +1492,8 @@
 	}
 }
 
-int saa7134_s_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh,
-		  struct v4l2_format *f)
+static int saa7134_s_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh,
+			 struct v4l2_format *f)
 {
 	unsigned long flags;
 	int err;
diff -Nru a/drivers/media/video/saa7185.c b/drivers/media/video/saa7185.c
--- a/drivers/media/video/saa7185.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/media/video/saa7185.c	2005-03-01 23:39:18 -08:00
@@ -57,7 +57,7 @@
 #include <linux/video_encoder.h>
 
 static int debug = 0;
-MODULE_PARM(debug, "i");
+module_param(debug, int, 0);
 MODULE_PARM_DESC(debug, "Debug level (0-1)");
 
 #define dprintk(num, format, args...) \
diff -Nru a/drivers/media/video/stradis.c b/drivers/media/video/stradis.c
--- a/drivers/media/video/stradis.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/media/video/stradis.c	2005-03-01 23:39:16 -08:00
@@ -60,7 +60,7 @@
 static int saa_num = 0;		/* number of SAA7146s in use */
 
 static int video_nr = -1;
-MODULE_PARM(video_nr,"i");
+module_param(video_nr, int, 0);
 MODULE_LICENSE("GPL");
 
 
@@ -96,13 +96,6 @@
 #define debVideo	(NewCard ? nDebVideo : oDebVideo)
 #define debAudio	(NewCard ? nDebAudio : oDebAudio)
 #define debDMA		(NewCard ? nDebDMA : oDebDMA)
-
-#ifdef DEBUG
-int stradis_driver(void)	/* for the benefit of ksymoops */
-{
-	return 1;
-}
-#endif
 
 #ifdef USE_RESCUE_EEPROM_SDM275
 static unsigned char rescue_eeprom[64] = {
diff -Nru a/drivers/media/video/tda7432.c b/drivers/media/video/tda7432.c
--- a/drivers/media/video/tda7432.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/media/video/tda7432.c	2005-03-01 23:39:08 -08:00
@@ -60,13 +60,13 @@
 MODULE_DESCRIPTION("bttv driver for the tda7432 audio processor chip");
 MODULE_LICENSE("GPL");
 
-MODULE_PARM(debug,"i");
-MODULE_PARM(loudness,"i");
+static int maxvol;
+static int loudness; /* disable loudness by default */
+static int debug;	 /* insmod parameter */
+module_param(debug, int, S_IRUGO | S_IWUSR);
+module_param(loudness, int, S_IRUGO);
 MODULE_PARM_DESC(maxvol,"Set maximium volume to +20db (0), default is 0db(1)");
-MODULE_PARM(maxvol,"i");
-static int maxvol = 0;
-static int loudness = 0; /* disable loudness by default */
-static int debug = 0;	 /* insmod parameter */
+module_param(maxvol, int, S_IRUGO | S_IWUSR);
 
 
 /* Address to scan (I2C address of this chip) */
diff -Nru a/drivers/media/video/tda9875.c b/drivers/media/video/tda9875.c
--- a/drivers/media/video/tda9875.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/media/video/tda9875.c	2005-03-01 23:38:56 -08:00
@@ -34,10 +34,10 @@
 #include <media/audiochip.h>
 #include <media/id.h>
 
-MODULE_PARM(debug,"i");
+static int debug; /* insmod parameter */
+module_param(debug, int, S_IRUGO | S_IWUSR);
 MODULE_LICENSE("GPL");
 
-static int debug = 0;	/* insmod parameter */
 
 /* Addresses to scan */
 static unsigned short normal_i2c[] =  {
diff -Nru a/drivers/media/video/tda9887.c b/drivers/media/video/tda9887.c
--- a/drivers/media/video/tda9887.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/media/video/tda9887.c	2005-03-01 23:39:18 -08:00
@@ -1,4 +1,5 @@
 #include <linux/module.h>
+#include <linux/moduleparam.h>
 #include <linux/kernel.h>
 #include <linux/i2c.h>
 #include <linux/types.h>
@@ -27,6 +28,7 @@
 
 /* Addresses to scan */
 static unsigned short normal_i2c[] = {
+	0x84 >>1,
 	0x86 >>1,
 	0x96 >>1,
 	I2C_CLIENT_END,
@@ -303,9 +305,9 @@
 	printk("  B5   force mute audio: %s\n",
 	       (buf[1] & 0x20) ? "yes" : "no");
 	printk("  B6   output port 1   : %s\n",
-	       (buf[1] & 0x40) ? "high" : "low");
+	       (buf[1] & 0x40) ? "high (inactive)" : "low (active)");
 	printk("  B7   output port 2   : %s\n",
-	       (buf[1] & 0x80) ? "high" : "low");
+	       (buf[1] & 0x80) ? "high (inactive)" : "low (active)");
 
 	printk(PREFIX "write: byte C 0x%02x\n",buf[2]);
 	printk("  C0-4 top adjustment  : %s dB\n", adjust[buf[2] & 0x1f]);
@@ -374,8 +376,8 @@
 	return 0;
 }
 
-static unsigned int port1  = 1;
-static unsigned int port2  = 1;
+static unsigned int port1  = UNSET;
+static unsigned int port2  = UNSET;
 static unsigned int qss    = UNSET;
 static unsigned int adjust = 0x10;
 module_param(port1, int, 0644);
@@ -385,10 +387,19 @@
 
 static int tda9887_set_insmod(struct tda9887 *t, char *buf)
 {
-	if (port1)
-		buf[1] |= cOutputPort1Inactive;
-	if (port2)
-		buf[1] |= cOutputPort2Inactive;
+	if (UNSET != port1) {
+		if (port1)
+			buf[1] |= cOutputPort1Inactive;
+		else
+			buf[1] &= ~cOutputPort1Inactive;
+	}
+	if (UNSET != port2) {
+		if (port2)
+			buf[1] |= cOutputPort2Inactive;
+		else
+			buf[1] &= ~cOutputPort2Inactive;
+	}
+
 	if (UNSET != qss) {
 		if (qss)
 			buf[1] |= cQSS;
@@ -403,10 +414,15 @@
 
 static int tda9887_set_config(struct tda9887 *t, char *buf)
 {
-	if (t->config & TDA9887_PORT1)
+	if (t->config & TDA9887_PORT1_ACTIVE)
+		buf[1] &= ~cOutputPort1Inactive;
+	if (t->config & TDA9887_PORT1_INACTIVE)
 		buf[1] |= cOutputPort1Inactive;
-	if (t->config & TDA9887_PORT2)
+	if (t->config & TDA9887_PORT2_ACTIVE)
+		buf[1] &= ~cOutputPort2Inactive;
+	if (t->config & TDA9887_PORT2_INACTIVE)
 		buf[1] |= cOutputPort2Inactive;
+
 	if (t->config & TDA9887_QSS)
 		buf[1] |= cQSS;
 	if (t->config & TDA9887_INTERCARRIER)
@@ -437,14 +453,14 @@
 {
 	unsigned int bCarrierMode = UNSET;
 
-	if (t->std & V4L2_STD_PAL) {
+	if (t->std & V4L2_STD_625_50) {
 		if ((1 == t->pinnacle_id) || (7 == t->pinnacle_id)) {
 			bCarrierMode = cIntercarrier;
 		} else {
 			bCarrierMode = cQSS;
 		}
 	}
-	if (t->std & V4L2_STD_NTSC) {
+	if (t->std & V4L2_STD_525_60) {
                 if ((5 == t->pinnacle_id) || (6 == t->pinnacle_id)) {
 			bCarrierMode = cIntercarrier;
 		} else {
@@ -530,16 +546,23 @@
 
 	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]);
diff -Nru a/drivers/media/video/tuner-3036.c b/drivers/media/video/tuner-3036.c
--- a/drivers/media/video/tuner-3036.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/media/video/tuner-3036.c	2005-03-01 23:38:56 -08:00
@@ -197,14 +197,14 @@
 	.name		= "SAB3036",
 };
 
-int __init
+static int __init
 tuner3036_init(void)
 {
 	i2c_add_driver(&i2c_driver_tuner);
 	return 0;
 }
 
-void __exit
+static void __exit
 tuner3036_exit(void)
 {
 	i2c_del_driver(&i2c_driver_tuner);
@@ -214,7 +214,7 @@
 MODULE_AUTHOR("Philip Blundell <philb@gnu.org>");
 MODULE_LICENSE("GPL");
 
-MODULE_PARM(debug,"i");
+module_param(debug, int, 0);
 MODULE_PARM_DESC(debug,"Enable debugging output");
 
 module_init(tuner3036_init);
diff -Nru a/drivers/media/video/tuner.c b/drivers/media/video/tuner.c
--- a/drivers/media/video/tuner.c	2005-03-01 23:39:19 -08:00
+++ b/drivers/media/video/tuner.c	2005-03-01 23:39:19 -08:00
@@ -1,5 +1,5 @@
 /*
- * $Id: tuner.c,v 1.31 2004/11/10 11:07:24 kraxel Exp $
+ * $Id: tuner.c,v 1.36 2005/01/14 13:29:40 kraxel Exp $
  */
 
 #include <linux/module.h>
@@ -62,7 +62,7 @@
 	v4l2_std_id  std;
 	int          using_v4l2;
 
-	unsigned int radio;
+	enum v4l2_tuner_type mode;
 	unsigned int input;
 
 	// only for MT2032
@@ -265,6 +265,11 @@
 	{ "Philips PAL/SECAM_D (FM 1256 I-H3)", Philips, PAL,
 	  16*160.00,16*442.00,0x01,0x02,0x04,0x8e,623 },
 
+	{ "Thomson DDT 7610 ATSC/NTSC)", THOMSON, ATSC,
+	  16*157.25,16*454.00,0x39,0x3a,0x3c,0x8e,732},
+	{ "Philips FQ1286", Philips, NTSC,
+	  16*160.00,16*454.00,0x41,0x42,0x04,0x8e,940}, // UHF band untested
+
 };
 #define TUNERS ARRAY_SIZE(tuners)
 
@@ -663,7 +668,8 @@
 	int ret;
 	unsigned char buf[6];
 
-	dprintk("mt2050_set_if_freq freq=%d\n",freq);
+	dprintk("mt2050_set_if_freq freq=%d if1=%d if2=%d\n",
+		freq,if1,if2);
 
 	f_lo1=freq+if1;
 	f_lo1=(f_lo1/1000000)*1000000;
@@ -688,9 +694,10 @@
 	div2a=(lo2/8)-1;
 	div2b=lo2-(div2a+1)*8;
 
-	dprintk("lo1 lo2 = %d %d\n", lo1, lo2);
-        dprintk("num1 num2 div1a div1b div2a div2b= %x %x %x %x %x %x\n",num1,num2,div1a,div1b,div2a,div2b);
-
+	if (debug > 1) {
+		printk("lo1 lo2 = %d %d\n", lo1, lo2);
+		printk("num1 num2 div1a div1b div2a div2b= %x %x %x %x %x %x\n",num1,num2,div1a,div1b,div2a,div2b);
+	}
 
 	buf[0]=1;
 	buf[1]= 4*div1b + num1;
@@ -702,7 +709,7 @@
 	buf[5]=div2a;
 	if(num2!=0) buf[5]=buf[5]|0x40;
 
-	if(debug) {
+	if (debug > 1) {
 		int i;
 		printk("bufs is: ");
 		for(i=0;i<6;i++)
@@ -727,6 +734,10 @@
                 // PAL
                 if2 = 38900*1000;
         }
+	if (V4L2_TUNER_DIGITAL_TV == t->mode) {
+		// testing for DVB ...
+		if2 = 36150*1000;
+	}
 	mt2050_set_if_freq(c, freq*62500, if2);
 	mt2050_set_antenna(c, tv_antenna);
 }
@@ -1069,14 +1080,18 @@
 {
 	struct tuner *t = i2c_get_clientdata(c);
 
-	if (t->radio) {
+	switch (t->mode) {
+	case V4L2_TUNER_RADIO:
 		dprintk("tuner: radio freq set to %lu.%02lu\n",
 			freq/16,freq%16*100/16);
 		set_radio_freq(c,freq);
-	} else {
+		break;
+	case V4L2_TUNER_ANALOG_TV:
+	case V4L2_TUNER_DIGITAL_TV:
 		dprintk("tuner: tv freq set to %lu.%02lu\n",
 			freq/16,freq%16*100/16);
 		set_tv_freq(c, freq);
+		break;
 	}
 	t->freq = freq;
 }
@@ -1237,9 +1252,9 @@
 		set_type(client,*iarg,client->adapter->name);
 		break;
 	case AUDC_SET_RADIO:
-		if (!t->radio) {
+		if (V4L2_TUNER_RADIO != t->mode) {
 			set_tv_freq(client,400 * 16);
-			t->radio = 1;
+			t->mode = V4L2_TUNER_RADIO;
 		}
 		break;
 	case AUDC_CONFIG_PINNACLE:
@@ -1271,7 +1286,7 @@
 		struct video_channel *vc = arg;
 
 		CHECK_V4L2;
-		t->radio = 0;
+		t->mode = V4L2_TUNER_ANALOG_TV;
 		if (vc->norm < ARRAY_SIZE(map))
 			t->std = map[vc->norm];
 		tuner_fixup_std(t);
@@ -1292,7 +1307,7 @@
 		struct video_tuner *vt = arg;
 
 		CHECK_V4L2;
-		if (t->radio)
+		if (V4L2_TUNER_RADIO == t->mode)
 			vt->signal = tuner_signal(client);
 		return 0;
 	}
@@ -1301,7 +1316,7 @@
 		struct video_audio *va = arg;
 
 		CHECK_V4L2;
-		if (t->radio)
+		if (V4L2_TUNER_RADIO == t->mode)
 			va->mode = (tuner_stereo(client) ? VIDEO_SOUND_STEREO : VIDEO_SOUND_MONO);
 		return 0;
 	}
@@ -1311,7 +1326,7 @@
 		v4l2_std_id *id = arg;
 
 		SWITCH_V4L2;
-		t->radio = 0;
+		t->mode = V4L2_TUNER_ANALOG_TV;
 		t->std = *id;
 		tuner_fixup_std(t);
 		if (t->freq)
@@ -1323,15 +1338,10 @@
 		struct v4l2_frequency *f = arg;
 
 		SWITCH_V4L2;
-		if (V4L2_TUNER_ANALOG_TV == f->type) {
-			t->radio = 0;
-		}
-		if (V4L2_TUNER_RADIO == f->type) {
-			if (!t->radio) {
-				set_tv_freq(client,400*16);
-				t->radio = 1;
-			}
-		}
+		if (V4L2_TUNER_RADIO == f->type &&
+		    V4L2_TUNER_RADIO != t->mode)
+			set_tv_freq(client,400*16);
+		t->mode  = f->type;
 		t->freq  = f->frequency;
 		set_freq(client,t->freq);
 		break;
@@ -1341,7 +1351,7 @@
 		struct v4l2_tuner *tuner = arg;
 
 		SWITCH_V4L2;
-		if (t->radio)
+		if (V4L2_TUNER_RADIO == t->mode)
 			tuner->signal = tuner_signal(client);
 		break;
 	}
diff -Nru a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c
--- a/drivers/media/video/tvaudio.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/media/video/tvaudio.c	2005-03-01 23:38:55 -08:00
@@ -16,6 +16,7 @@
 
 #include <linux/config.h>
 #include <linux/module.h>
+#include <linux/moduleparam.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/string.h>
@@ -1027,6 +1028,21 @@
 #define TEA6300_S_SC       0x04  /* stereo C */
 #define TEA6300_S_GMU      0x80  /* general mute */
 
+#define TEA6320_V          0x00  /* volume (0-5)/loudness off (6)/zero crossing mute(7) */
+#define TEA6320_FFR        0x01  /* fader front right (0-5) */
+#define TEA6320_FFL        0x02  /* fader front left (0-5) */
+#define TEA6320_FRR        0x03  /* fader rear right (0-5) */
+#define TEA6320_FRL        0x04  /* fader rear left (0-5) */
+#define TEA6320_BA         0x05  /* bass (0-4) */
+#define TEA6320_TR         0x06  /* treble (0-4) */
+#define TEA6320_S          0x07  /* switch register */
+                                 /* values for those registers: */
+#define TEA6320_S_SA       0x07  /* stereo A input */
+#define TEA6320_S_SB       0x06  /* stereo B */
+#define TEA6320_S_SC       0x05  /* stereo C */
+#define TEA6320_S_SD       0x04  /* stereo D */
+#define TEA6320_S_GMU      0x80  /* general mute */
+
 #define TEA6420_S_SA       0x00  /* stereo A input */
 #define TEA6420_S_SB       0x01  /* stereo B */
 #define TEA6420_S_SC       0x02  /* stereo C */
@@ -1037,6 +1053,20 @@
 static int tea6300_shift10(int val) { return val >> 10; }
 static int tea6300_shift12(int val) { return val >> 12; }
 
+/* Assumes 16bit input (values 0x3f to 0x0c are unique, values less than */
+/* 0x0c mirror those immediately higher) */
+static int tea6320_volume(int val) { return (val / (65535/(63-12)) + 12) & 0x3f; }
+static int tea6320_shift11(int val) { return val >> 11; }
+static int tea6320_initialize(struct CHIPSTATE * chip)
+{
+	chip_write(chip, TEA6320_FFR, 0x3f);
+	chip_write(chip, TEA6320_FFL, 0x3f);
+	chip_write(chip, TEA6320_FRR, 0x3f);
+	chip_write(chip, TEA6320_FRL, 0x3f);
+
+	return 0;
+}
+
 
 /* ---------------------------------------------------------------------- */
 /* audio chip descriptions - defines+functions for tda8425                */
@@ -1214,6 +1244,7 @@
 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
@@ -1225,6 +1256,7 @@
 module_param(tda9873, int, 0444);
 module_param(tda9874a, int, 0444);
 module_param(tea6300, int, 0444);
+module_param(tea6320, int, 0444);
 module_param(tea6420, int, 0444);
 module_param(pic16c54, int, 0444);
 module_param(ta8874z, int, 0444);
@@ -1339,6 +1371,28 @@
 		.inputmute  = TEA6300_S_GMU,
 	},
 	{
+		.name       = "tea6320",
+		.id         = I2C_DRIVERID_TEA6300,
+		.initialize = tea6320_initialize,
+		.insmodopt  = &tea6320,
+		.addr_lo    = I2C_TEA6300 >> 1,
+		.addr_hi    = I2C_TEA6300 >> 1,
+		.registers  = 8,
+		.flags      = CHIP_HAS_VOLUME | CHIP_HAS_BASSTREBLE | CHIP_HAS_INPUTSEL,
+
+		.leftreg    = TEA6320_V,
+		.rightreg   = TEA6320_V,
+		.bassreg    = TEA6320_BA,
+		.treblereg  = TEA6320_TR,
+		.volfunc    = tea6320_volume,
+		.bassfunc   = tea6320_shift11,
+		.treblefunc = tea6320_shift11,
+
+		.inputreg   = TEA6320_S,
+		.inputmap   = { TEA6320_S_SA, TEA6420_S_SB, TEA6300_S_SC, TEA6320_S_SD },
+		.inputmute  = TEA6300_S_GMU,
+	},
+	{
 		.name       = "tea6420",
 		.id         = I2C_DRIVERID_TEA6420,
 		.insmodopt  = &tea6420,
@@ -1571,8 +1625,11 @@
 		if (desc->flags & CHIP_HAS_VOLUME) {
 			va->flags  |= VIDEO_AUDIO_VOLUME;
 			va->volume  = max(chip->left,chip->right);
-			va->balance = (32768*min(chip->left,chip->right))/
-				(va->volume ? va->volume : 1);
+			if (va->volume)
+				va->balance = (32768*min(chip->left,chip->right))/
+					va->volume;
+			else
+				va->balance = 32768;
 		}
 		if (desc->flags & CHIP_HAS_BASSTREBLE) {
 			va->flags |= VIDEO_AUDIO_BASS | VIDEO_AUDIO_TREBLE;
diff -Nru a/drivers/media/video/tvaudio.h b/drivers/media/video/tvaudio.h
--- a/drivers/media/video/tvaudio.h	2005-03-01 23:38:44 -08:00
+++ b/drivers/media/video/tvaudio.h	2005-03-01 23:38:44 -08:00
@@ -8,7 +8,7 @@
 #define I2C_TDA985x_H      0xb6
 #define I2C_TDA9874        0xb0 /* also used by 9875 */
 
-#define I2C_TEA6300        0x80
+#define I2C_TEA6300        0x80 /* also used by 6320 */
 #define I2C_TEA6420	   0x98
 
 #define I2C_PIC16C54       0x96 /* PV951 */
diff -Nru a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/media/video/tveeprom.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,577 @@
+/*
+ * tveeprom - eeprom decoder for tvcard configuration eeproms
+ *
+ * Data and decoding routines shamelessly borrowed from bttv-cards.c
+ * eeprom access routine shamelessly borrowed from bttv-if.c
+ * which are:
+
+    Copyright (C) 1996,97,98 Ralph  Metzler (rjkm@thp.uni-koeln.de)
+                           & Marcus Metzler (mocm@thp.uni-koeln.de)
+    (c) 1999-2001 Gerd Knorr <kraxel@goldbach.in-berlin.de>
+
+ * Adjustments to fit a more general model and all bugs:
+
+ 	Copyright (C) 2003 John Klar <linpvr at projectplasma.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/errno.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/i2c.h>
+
+#include <media/tuner.h>
+#include <media/tveeprom.h>
+
+MODULE_DESCRIPTION("i2c Hauppauge eeprom decoder driver");
+MODULE_AUTHOR("John Klar");
+MODULE_LICENSE("GPL");
+
+static int debug = 0;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Debug level (0-2)");
+
+#define STRM(array,i) (i < sizeof(array)/sizeof(char*) ? array[i] : "unknown")
+
+#define dprintk(num, args...) \
+	do { \
+		if (debug >= num) \
+			printk(KERN_INFO "tveeprom: " args); \
+	} while (0)
+
+#define TVEEPROM_KERN_ERR(args...) printk(KERN_ERR "tveeprom: " args);
+#define TVEEPROM_KERN_INFO(args...) printk(KERN_INFO "tveeprom: " args);
+
+/* ----------------------------------------------------------------------- */
+/* some hauppauge specific stuff                                           */
+
+static struct HAUPPAUGE_TUNER_FMT
+{
+	int	id;
+	char *name;
+}
+hauppauge_tuner_fmt[] =
+{
+	{ 0x00000000, "unknown1" },
+	{ 0x00000000, "unknown2" },
+	{ 0x00000007, "PAL(B/G)" },
+	{ 0x00001000, "NTSC(M)" },
+	{ 0x00000010, "PAL(I)" },
+	{ 0x00400000, "SECAM(L/Lï¿½)" },
+	{ 0x00000e00, "PAL(D/K)" },
+	{ 0x03000000, "ATSC Digital" },
+};
+
+/* This is the full list of possible tuners. Many thanks to Hauppauge for
+   supplying this information. Note that many tuners where only used for
+   testing and never made it to the outside world. So you will only see
+   a subset in actual produced cards. */
+static struct HAUPPAUGE_TUNER
+{
+	int  id;
+	char *name;
+}
+hauppauge_tuner[] =
+{
+	/* 0-9 */
+	{ TUNER_ABSENT,        "None" },
+	{ TUNER_ABSENT,        "External" },
+	{ TUNER_ABSENT,        "Unspecified" },
+	{ TUNER_PHILIPS_PAL,   "Philips FI1216" },
+	{ TUNER_PHILIPS_SECAM, "Philips FI1216MF" },
+	{ TUNER_PHILIPS_NTSC,  "Philips FI1236" },
+	{ TUNER_PHILIPS_PAL_I, "Philips FI1246" },
+	{ TUNER_PHILIPS_PAL_DK,"Philips FI1256" },
+	{ TUNER_PHILIPS_PAL,   "Philips FI1216 MK2" },
+	{ TUNER_PHILIPS_SECAM, "Philips FI1216MF MK2" },
+	/* 10-19 */
+	{ TUNER_PHILIPS_NTSC,  "Philips FI1236 MK2" },
+	{ TUNER_PHILIPS_PAL_I, "Philips FI1246 MK2" },
+	{ TUNER_PHILIPS_PAL_DK,"Philips FI1256 MK2" },
+	{ TUNER_TEMIC_NTSC,    "Temic 4032FY5" },
+	{ TUNER_TEMIC_PAL,     "Temic 4002FH5" },
+	{ TUNER_TEMIC_PAL_I,   "Temic 4062FY5" },
+	{ TUNER_PHILIPS_PAL,   "Philips FR1216 MK2" },
+	{ TUNER_PHILIPS_SECAM, "Philips FR1216MF MK2" },
+	{ TUNER_PHILIPS_NTSC,  "Philips FR1236 MK2" },
+	{ TUNER_PHILIPS_PAL_I, "Philips FR1246 MK2" },
+	/* 20-29 */
+	{ TUNER_PHILIPS_PAL_DK,"Philips FR1256 MK2" },
+	{ TUNER_PHILIPS_PAL,   "Philips FM1216" },
+	{ TUNER_PHILIPS_SECAM, "Philips FM1216MF" },
+	{ TUNER_PHILIPS_NTSC,  "Philips FM1236" },
+	{ TUNER_PHILIPS_PAL_I, "Philips FM1246" },
+	{ TUNER_PHILIPS_PAL_DK,"Philips FM1256" },
+	{ TUNER_TEMIC_4036FY5_NTSC, "Temic 4036FY5" },
+	{ TUNER_ABSENT,        "Samsung TCPN9082D" },
+	{ TUNER_ABSENT,        "Samsung TCPM9092P" },
+	{ TUNER_TEMIC_4006FH5_PAL, "Temic 4006FH5" },
+	/* 30-39 */
+	{ TUNER_ABSENT,        "Samsung TCPN9085D" },
+	{ TUNER_ABSENT,        "Samsung TCPB9085P" },
+	{ TUNER_ABSENT,        "Samsung TCPL9091P" },
+	{ TUNER_TEMIC_4039FR5_NTSC, "Temic 4039FR5" },
+	{ TUNER_PHILIPS_FQ1216ME,   "Philips FQ1216 ME" },
+	{ TUNER_TEMIC_4066FY5_PAL_I, "Temic 4066FY5" },
+        { TUNER_PHILIPS_NTSC,        "Philips TD1536" },
+        { TUNER_PHILIPS_NTSC,        "Philips TD1536D" },
+	{ TUNER_PHILIPS_NTSC,  "Philips FMR1236" }, /* mono radio */
+	{ TUNER_ABSENT,        "Philips FI1256MP" },
+	/* 40-49 */
+	{ TUNER_ABSENT,        "Samsung TCPQ9091P" },
+	{ TUNER_TEMIC_4006FN5_MULTI_PAL, "Temic 4006FN5" },
+	{ TUNER_TEMIC_4009FR5_PAL, "Temic 4009FR5" },
+	{ TUNER_TEMIC_4046FM5,     "Temic 4046FM5" },
+	{ TUNER_TEMIC_4009FN5_MULTI_PAL_FM, "Temic 4009FN5" },
+	{ TUNER_ABSENT,        "Philips TD1536D FH 44"},
+	{ TUNER_LG_NTSC_FM,    "LG TP18NSR01F"},
+	{ TUNER_LG_PAL_FM,     "LG TP18PSB01D"},
+	{ TUNER_LG_PAL,        "LG TP18PSB11D"},
+	{ TUNER_LG_PAL_I_FM,   "LG TAPC-I001D"},
+	/* 50-59 */
+	{ TUNER_LG_PAL_I,      "LG TAPC-I701D"},
+	{ TUNER_ABSENT,        "Temic 4042FI5"},
+	{ TUNER_MICROTUNE_4049FM5, "Microtune 4049 FM5"},
+	{ TUNER_ABSENT,        "LG TPI8NSR11F"},
+	{ TUNER_ABSENT,        "Microtune 4049 FM5 Alt I2C"},
+	{ TUNER_ABSENT,        "Philips FQ1216ME MK3"},
+	{ TUNER_ABSENT,        "Philips FI1236 MK3"},
+	{ TUNER_PHILIPS_FM1216ME_MK3, "Philips FM1216 ME MK3"},
+	{ TUNER_ABSENT,        "Philips FM1236 MK3"},
+	{ TUNER_ABSENT,        "Philips FM1216MP MK3"},
+	/* 60-69 */
+	{ TUNER_ABSENT,        "LG S001D MK3"},
+	{ TUNER_ABSENT,        "LG M001D MK3"},
+	{ TUNER_ABSENT,        "LG S701D MK3"},
+	{ TUNER_ABSENT,        "LG M701D MK3"},
+	{ TUNER_ABSENT,        "Temic 4146FM5"},
+	{ TUNER_ABSENT,        "Temic 4136FY5"},
+	{ TUNER_ABSENT,        "Temic 4106FH5"},
+	{ TUNER_ABSENT,        "Philips FQ1216LMP MK3"},
+	{ TUNER_LG_NTSC_TAPE,  "LG TAPE H001F MK3"},
+	{ TUNER_ABSENT,        "LG TAPE H701F MK3"},
+	/* 70-79 */
+	{ TUNER_ABSENT,        "LG TALN H200T"},
+	{ TUNER_ABSENT,        "LG TALN H250T"},
+	{ TUNER_ABSENT,        "LG TALN M200T"},
+	{ TUNER_ABSENT,        "LG TALN Z200T"},
+	{ TUNER_ABSENT,        "LG TALN S200T"},
+	{ TUNER_ABSENT,        "Thompson DTT7595"},
+	{ TUNER_ABSENT,        "Thompson DTT7592"},
+	{ TUNER_ABSENT,        "Silicon TDA8275C1 8290"},
+	{ TUNER_ABSENT,        "Silicon TDA8275C1 8290 FM"},
+	{ TUNER_ABSENT,        "Thompson DTT757"},
+	/* 80-89 */
+	{ TUNER_ABSENT,        "Philips FQ1216LME MK3"},
+	{ TUNER_ABSENT,        "LG TAPC G701D"},
+	{ TUNER_LG_NTSC_NEW_TAPC, "LG TAPC H791F"},
+	{ TUNER_ABSENT,        "TCL 2002MB 3"},
+	{ TUNER_ABSENT,        "TCL 2002MI 3"},
+	{ TUNER_TCL_2002N,     "TCL 2002N 6A"},
+	{ TUNER_ABSENT,        "Philips FQ1236 MK3"},
+	{ TUNER_ABSENT,        "Samsung TCPN 2121P30A"},
+	{ TUNER_ABSENT,        "Samsung TCPE 4121P30A"},
+	{ TUNER_ABSENT,        "TCL MFPE05 2"},
+	/* 90-99 */
+	{ TUNER_ABSENT,        "LG TALN H202T"},
+	{ TUNER_ABSENT,        "Philips FQ1216AME MK4"},
+	{ TUNER_ABSENT,        "Philips FQ1236A MK4"},
+	{ TUNER_ABSENT,        "Philips FQ1286A MK4"},
+	{ TUNER_ABSENT,        "Philips FQ1216ME MK5"},
+	{ TUNER_ABSENT,        "Philips FQ1236 MK5"},
+};
+
+static char *sndtype[] = {
+	"None", "TEA6300", "TEA6320", "TDA9850", "MSP3400C", "MSP3410D",
+	"MSP3415", "MSP3430", "MSP3438", "CS5331", "MSP3435", "MSP3440",
+	"MSP3445", "MSP3411", "MSP3416", "MSP3425",
+
+	"Type 0x10","Type 0x11","Type 0x12","Type 0x13",
+	"Type 0x14","Type 0x15","Type 0x16","Type 0x17",
+	"Type 0x18","MSP4418","Type 0x1a","MSP4448",
+	"Type 0x1c","Type 0x1d","Type 0x1e","Type 0x1f",
+};
+
+static int hasRadioTuner(int tunerType)
+{
+        switch (tunerType) {
+                case 18: //PNPEnv_TUNER_FR1236_MK2:
+                case 23: //PNPEnv_TUNER_FM1236:
+                case 38: //PNPEnv_TUNER_FMR1236:
+                case 16: //PNPEnv_TUNER_FR1216_MK2:
+                case 19: //PNPEnv_TUNER_FR1246_MK2:
+                case 21: //PNPEnv_TUNER_FM1216:
+                case 24: //PNPEnv_TUNER_FM1246:
+                case 17: //PNPEnv_TUNER_FR1216MF_MK2:
+                case 22: //PNPEnv_TUNER_FM1216MF:
+                case 20: //PNPEnv_TUNER_FR1256_MK2:
+                case 25: //PNPEnv_TUNER_FM1256:
+                case 33: //PNPEnv_TUNER_4039FR5:
+                case 42: //PNPEnv_TUNER_4009FR5:
+                case 52: //PNPEnv_TUNER_4049FM5:
+                case 54: //PNPEnv_TUNER_4049FM5_AltI2C:
+                case 44: //PNPEnv_TUNER_4009FN5:
+                case 31: //PNPEnv_TUNER_TCPB9085P:
+                case 30: //PNPEnv_TUNER_TCPN9085D:
+                case 46: //PNPEnv_TUNER_TP18NSR01F:
+                case 47: //PNPEnv_TUNER_TP18PSB01D:
+                case 49: //PNPEnv_TUNER_TAPC_I001D:
+                case 60: //PNPEnv_TUNER_TAPE_S001D_MK3:
+                case 57: //PNPEnv_TUNER_FM1216ME_MK3:
+                case 59: //PNPEnv_TUNER_FM1216MP_MK3:
+                case 58: //PNPEnv_TUNER_FM1236_MK3:
+                case 68: //PNPEnv_TUNER_TAPE_H001F_MK3:
+                case 61: //PNPEnv_TUNER_TAPE_M001D_MK3:
+                case 78: //PNPEnv_TUNER_TDA8275C1_8290_FM:
+                case 89: //PNPEnv_TUNER_TCL_MFPE05_2:
+                    return 1;
+        }
+        return 0;
+}
+
+void tveeprom_hauppauge_analog(struct tveeprom *tvee, unsigned char *eeprom_data)
+{
+	/* ----------------------------------------------
+	** The hauppauge eeprom format is tagged
+	**
+	** if packet[0] == 0x84, then packet[0..1] == length
+	** else length = packet[0] & 3f;
+	** if packet[0] & f8 == f8, then EOD and packet[1] == checksum
+	**
+	** In our (ivtv) case we're interested in the following:
+	** tuner type: tag [00].05 or [0a].01 (index into hauppauge_tuners)
+	** tuner fmts: tag [00].04 or [0a].00 (bitmask index into hauppauge_fmts)
+	** radio:      tag [00].{last} or [0e].00  (bitmask.  bit2=FM)
+	** audio proc: tag [02].01 or [05].00 (lower nibble indexes lut?)
+
+	** Fun info:
+	** model:      tag [00].07-08 or [06].00-01
+	** revision:   tag [00].09-0b or [06].04-06
+	** serial#:    tag [01].05-07 or [04].04-06
+
+	** # of inputs/outputs ???
+	*/
+
+	int i, j, len, done, tag, tuner = 0, t_format = 0;
+	char *t_name = NULL, *t_fmt_name = NULL;
+
+	dprintk(1, "%s\n",__FUNCTION__);
+	tvee->revision = done = len = 0;
+	for (i = 0; !done && i < 256; i += len) {
+		dprintk(2, "processing pos = %02x (%02x, %02x)\n",
+			i, eeprom_data[i], eeprom_data[i + 1]);
+
+		if (eeprom_data[i] == 0x84) {
+			len = eeprom_data[i + 1] + (eeprom_data[i + 2] << 8);
+			i+=3;
+		} else if ((eeprom_data[i] & 0xf0) == 0x70) {
+			if ((eeprom_data[i] & 0x08)) {
+				/* verify checksum! */
+				done = 1;
+				break;
+			}
+			len = eeprom_data[i] & 0x07;
+			++i;
+		} else {
+			TVEEPROM_KERN_ERR("Encountered bad packet header [%02x]. "
+				   "Corrupt or not a Hauppauge eeprom.\n", eeprom_data[i]);
+			return;
+		}
+
+		dprintk(1, "%3d [%02x] ", len, eeprom_data[i]);
+		for(j = 1; j < len; j++) {
+			dprintk(1, "%02x ", eeprom_data[i + j]);
+		}
+		dprintk(1, "\n");
+
+		/* process by tag */
+		tag = eeprom_data[i];
+		switch (tag) {
+		case 0x00:
+			tuner = eeprom_data[i+6];
+			t_format = eeprom_data[i+5];
+			tvee->has_radio = eeprom_data[i+len-1];
+			tvee->model =
+				eeprom_data[i+8] +
+				(eeprom_data[i+9] << 8);
+			tvee->revision = eeprom_data[i+10] +
+				(eeprom_data[i+11] << 8) +
+				(eeprom_data[i+12] << 16);
+			break;
+		case 0x01:
+			tvee->serial_number =
+				eeprom_data[i+6] +
+				(eeprom_data[i+7] << 8) +
+				(eeprom_data[i+8] << 16);
+			break;
+		case 0x02:
+			tvee->audio_processor = eeprom_data[i+2] & 0x0f;
+			break;
+		case 0x04:
+			tvee->serial_number =
+				eeprom_data[i+5] +
+				(eeprom_data[i+6] << 8) +
+				(eeprom_data[i+7] << 16);
+			break;
+		case 0x05:
+			tvee->audio_processor = eeprom_data[i+1] & 0x0f;
+			break;
+		case 0x06:
+			tvee->model =
+				eeprom_data[i+1] +
+				(eeprom_data[i+2] << 8);
+			tvee->revision = eeprom_data[i+5] +
+				(eeprom_data[i+6] << 8) +
+				(eeprom_data[i+7] << 16);
+			break;
+		case 0x0a:
+			tuner = eeprom_data[i+2];
+			t_format = eeprom_data[i+1];
+			break;
+		case 0x0e:
+			tvee->has_radio = eeprom_data[i+1];
+			break;
+		default:
+			dprintk(1, "Not sure what to do with tag [%02x]\n", tag);
+			/* dump the rest of the packet? */
+		}
+
+	}
+
+	if (!done) {
+		TVEEPROM_KERN_ERR("Ran out of data!\n");
+		return;
+	}
+
+	if (tvee->revision != 0) {
+		tvee->rev_str[0] = 32 + ((tvee->revision >> 18) & 0x3f);
+		tvee->rev_str[1] = 32 + ((tvee->revision >> 12) & 0x3f);
+		tvee->rev_str[2] = 32 + ((tvee->revision >>  6) & 0x3f);
+		tvee->rev_str[3] = 32 + ( tvee->revision        & 0x3f);
+		tvee->rev_str[4] = 0;
+	}
+
+        if (hasRadioTuner(tuner) && !tvee->has_radio) {
+	    TVEEPROM_KERN_INFO("The eeprom says no radio is present, but the tuner type\n");
+	    TVEEPROM_KERN_INFO("indicates otherwise. I will assume that radio is present.\n");
+            tvee->has_radio = 1;
+        }
+
+	if (tuner < sizeof(hauppauge_tuner)/sizeof(struct HAUPPAUGE_TUNER)) {
+		tvee->tuner_type = hauppauge_tuner[tuner].id;
+		t_name = hauppauge_tuner[tuner].name;
+	} else {
+		t_name = "<unknown>";
+	}
+
+	tvee->tuner_formats = 0;
+	t_fmt_name = "<none>";
+	for (i = 0; i < 8; i++) {
+		if (t_format & (1<<i)) {
+			tvee->tuner_formats |= hauppauge_tuner_fmt[i].id;
+			/* yuck */
+			t_fmt_name = hauppauge_tuner_fmt[i].name;
+		}
+	}
+
+#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,
+		   tvee->rev_str,
+		   tvee->serial_number);
+	TVEEPROM_KERN_INFO("tuner = %s (idx = %d, type = %d)\n",
+		   t_name,
+		   tuner,
+		   tvee->tuner_type);
+	TVEEPROM_KERN_INFO("tuner fmt = %s (eeprom = 0x%02x, v4l2 = 0x%08x)\n",
+		   t_fmt_name,
+		   t_format,
+		   tvee->tuner_formats);
+
+	TVEEPROM_KERN_INFO("audio_processor = %s (type = %d)\n",
+		   STRM(sndtype,tvee->audio_processor),
+		   tvee->audio_processor);
+
+}
+EXPORT_SYMBOL(tveeprom_hauppauge_analog);
+
+/* ----------------------------------------------------------------------- */
+/* generic helper functions                                                */
+
+int tveeprom_read(struct i2c_client *c, unsigned char *eedata, int len)
+{
+	unsigned char buf;
+	int err;
+
+	dprintk(1, "%s\n",__FUNCTION__);
+	buf = 0;
+	if (1 != (err = i2c_master_send(c,&buf,1))) {
+		printk(KERN_INFO "tveeprom(%s): Huh, no eeprom present (err=%d)?\n",
+		       c->name,err);
+		return -1;
+	}
+	if (len != (err = i2c_master_recv(c,eedata,len))) {
+		printk(KERN_WARNING "tveeprom(%s): i2c eeprom read error (err=%d)\n",
+		       c->name,err);
+		return -1;
+	}
+	return 0;
+}
+EXPORT_SYMBOL(tveeprom_read);
+
+int tveeprom_dump(unsigned char *eedata, int len)
+{
+	int i;
+
+	dprintk(1, "%s\n",__FUNCTION__);
+	for (i = 0; i < len; i++) {
+		if (0 == (i % 16))
+			printk(KERN_INFO "tveeprom: %02x:",i);
+		printk(" %02x",eedata[i]);
+		if (15 == (i % 16))
+			printk("\n");
+	}
+	return 0;
+}
+EXPORT_SYMBOL(tveeprom_dump);
+
+/* ----------------------------------------------------------------------- */
+/* needed for ivtv.sf.net at the moment.  Should go away in the long       */
+/* run, just call the exported tveeprom_* directly, there is no point in   */
+/* using the indirect way via i2c_driver->command()                        */
+
+#ifndef I2C_DRIVERID_TVEEPROM
+# define I2C_DRIVERID_TVEEPROM I2C_DRIVERID_EXP2
+#endif
+
+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 int
+tveeprom_command(struct i2c_client *client,
+		 unsigned int       cmd,
+		 void              *arg)
+{
+	struct tveeprom eeprom;
+	u32 *eeprom_props = arg;
+	u8 *buf;
+
+	switch (cmd) {
+	case 0:
+		buf = kmalloc(256,GFP_KERNEL);
+		memset(buf,0,256);
+		tveeprom_read(client,buf,256);
+		tveeprom_hauppauge_analog(&eeprom,buf);
+		kfree(buf);
+		eeprom_props[0] = eeprom.tuner_type;
+		eeprom_props[1] = eeprom.tuner_formats;
+		eeprom_props[2] = eeprom.model;
+		eeprom_props[3] = eeprom.revision;
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int
+tveeprom_detect_client(struct i2c_adapter *adapter,
+		       int                 address,
+		       int                 kind)
+{
+	struct i2c_client *client;
+
+	dprintk(1,"%s: id 0x%x @ 0x%x\n",__FUNCTION__,
+	       adapter->id, address << 1);
+	client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
+	if (NULL == client)
+		return -ENOMEM;
+	memset(client, 0, sizeof(struct i2c_client));
+	client->addr = address;
+	client->adapter = adapter;
+	client->driver = &i2c_driver_tveeprom;
+	client->flags = I2C_CLIENT_ALLOW_USE;
+	snprintf(client->name, sizeof(client->name), "tveeprom");
+        i2c_attach_client(client);
+	return 0;
+}
+
+static int
+tveeprom_attach_adapter (struct i2c_adapter *adapter)
+{
+	dprintk(1,"%s: id 0x%x\n",__FUNCTION__,adapter->id);
+	if (adapter->id != (I2C_ALGO_BIT | I2C_HW_B_BT848))
+		return 0;
+	return i2c_probe(adapter, &addr_data, tveeprom_detect_client);
+}
+
+static int
+tveeprom_detach_client (struct i2c_client *client)
+{
+	int err;
+
+	err = i2c_detach_client(client);
+	if (err < 0)
+		return err;
+	kfree(client);
+	return 0;
+}
+
+struct i2c_driver i2c_driver_tveeprom = {
+	.owner          = THIS_MODULE,
+	.name           = "tveeprom",
+	.id             = I2C_DRIVERID_TVEEPROM,
+	.flags          = I2C_DF_NOTIFY,
+	.attach_adapter = tveeprom_attach_adapter,
+	.detach_client  = tveeprom_detach_client,
+	.command        = tveeprom_command,
+};
+
+static int __init tveeprom_init(void)
+{
+	return i2c_add_driver(&i2c_driver_tveeprom);
+}
+
+static void __exit tveeprom_exit(void)
+{
+	i2c_del_driver(&i2c_driver_tveeprom);
+}
+
+module_init(tveeprom_init);
+module_exit(tveeprom_exit);
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff -Nru a/drivers/media/video/tvmixer.c b/drivers/media/video/tvmixer.c
--- a/drivers/media/video/tvmixer.c	2005-03-01 23:39:10 -08:00
+++ b/drivers/media/video/tvmixer.c	2005-03-01 23:39:10 -08:00
@@ -1,4 +1,5 @@
 #include <linux/module.h>
+#include <linux/moduleparam.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/string.h>
diff -Nru a/drivers/media/video/video-buf-dvb.c b/drivers/media/video/video-buf-dvb.c
--- a/drivers/media/video/video-buf-dvb.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/media/video/video-buf-dvb.c	2005-03-01 23:38:52 -08:00
@@ -1,5 +1,5 @@
 /*
- * $Id: video-buf-dvb.c,v 1.5 2004/11/07 13:17:15 kraxel Exp $
+ * $Id: video-buf-dvb.c,v 1.7 2004/12/09 12:51:35 kraxel Exp $
  *
  * some helper function for simple DVB cards which simply DMA the
  * complete transport stream and let the computer sort everything else
@@ -35,7 +35,7 @@
 MODULE_PARM_DESC(debug,"enable debug messages");
 
 #define dprintk(fmt, arg...)	if (debug)			\
-	printk(KERN_DEBUG "%s/dvb: " fmt, dvb->name, ## arg)
+	printk(KERN_DEBUG "%s/dvb: " fmt, dvb->name , ## arg)
 
 /* ------------------------------------------------------------------ */
 
@@ -134,19 +134,22 @@
 
 /* ------------------------------------------------------------------ */
 
-int videobuf_dvb_register(struct videobuf_dvb *dvb)
+int videobuf_dvb_register(struct videobuf_dvb *dvb,
+			  struct module *module,
+			  void *adapter_priv)
 {
 	int result;
 
 	init_MUTEX(&dvb->lock);
 
 	/* register adapter */
-	result = dvb_register_adapter(&dvb->adapter, dvb->name, THIS_MODULE);
+	result = dvb_register_adapter(&dvb->adapter, dvb->name, module);
 	if (result < 0) {
 		printk(KERN_WARNING "%s: dvb_register_adapter failed (errno = %d)\n",
 		       dvb->name, result);
 		goto fail_adapter;
 	}
+	dvb->adapter->priv = adapter_priv;
 
 	/* register frontend */
 	result = dvb_register_frontend(dvb->adapter, dvb->frontend);
diff -Nru a/drivers/media/video/video-buf.c b/drivers/media/video/video-buf.c
--- a/drivers/media/video/video-buf.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/media/video/video-buf.c	2005-03-01 23:38:57 -08:00
@@ -1,5 +1,5 @@
 /*
- * $Id: video-buf.c,v 1.15 2004/11/07 14:45:00 kraxel Exp $
+ * $Id: video-buf.c,v 1.17 2004/12/10 12:33:40 kraxel Exp $
  *
  * generic helper functions for video4linux capture buffers, to handle
  * memory management and PCI DMA.  Right now bttv + saa7134 use it.
@@ -20,6 +20,7 @@
 
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/moduleparam.h>
 #include <linux/vmalloc.h>
 #include <linux/pagemap.h>
 #include <linux/slab.h>
@@ -892,6 +893,7 @@
 	int i;
 
 	videobuf_queue_cancel(q);
+	videobuf_mmap_free(q);
 	INIT_LIST_HEAD(&q->stream);
 	for (i = 0; i < VIDEO_MAX_FRAME; i++) {
 		if (NULL == q->bufs[i])
diff -Nru a/drivers/media/video/videocodec.c b/drivers/media/video/videocodec.c
--- a/drivers/media/video/videocodec.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/media/video/videocodec.c	2005-03-01 23:38:58 -08:00
@@ -46,7 +46,7 @@
 #include "videocodec.h"
 
 static int debug = 0;
-MODULE_PARM(debug, "i");
+module_param(debug, int, 0);
 MODULE_PARM_DESC(debug, "Debug level (0-4)");
 
 #define dprintk(num, format, args...) \
diff -Nru a/drivers/media/video/videocodec.h b/drivers/media/video/videocodec.h
--- a/drivers/media/video/videocodec.h	2005-03-01 23:38:55 -08:00
+++ b/drivers/media/video/videocodec.h	2005-03-01 23:38:55 -08:00
@@ -248,6 +248,17 @@
 	u16 Wt, Wa, HStart, HSyncStart, Ht, Ha, VStart;
 };
 
+struct jpeg_com_marker {
+	int len; /* number of usable bytes in data */
+	char data[60];
+};
+
+struct jpeg_app_marker {
+	int appn; /* number app segment */
+	int len; /* number of usable bytes in data */
+	char data[60];
+};
+
 struct videocodec {
 	struct module *owner;
 	/* -- filled in by slave device during register -- */
diff -Nru a/drivers/media/video/vino.c b/drivers/media/video/vino.c
--- a/drivers/media/video/vino.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/media/video/vino.c	2005-03-01 23:38:54 -08:00
@@ -1,267 +1,347 @@
-/* $Id: vino.c,v 1.5 1999/10/09 00:01:14 ralf Exp $
- * drivers/char/vino.c
+/*
+ * (incomplete) Driver for the VINO (Video In No Out) system found in SGI Indys.
  *
- * (incomplete) Driver for the Vino Video input system found in SGI Indys.
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License version 2 as published by the Free Software Foundation.
  *
- * Copyright (C) 1999 Ulf Carlsson (ulfc@bun.falkenberg.se)
- *
- * This isn't complete yet, please don't expect any video until I've written
- * some more code.
+ * Copyright (C) 2003 Ladislav Michl <ladis@linux-mips.org>
  */
 
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/wrapper.h>
 #include <linux/errno.h>
+#include <linux/irq.h>
+#include <linux/delay.h>
 #include <linux/videodev.h>
+#include <linux/i2c.h>
+#include <linux/i2c-algo-sgi.h>
 
 #include <asm/addrspace.h>
 #include <asm/system.h>
+#include <asm/bootinfo.h>
+#include <asm/pgtable.h>
+#include <asm/paccess.h>
+#include <asm/io.h>
+#include <asm/sgi/ip22.h>
+#include <asm/sgi/hpc3.h>
+#include <asm/sgi/mc.h>
 
 #include "vino.h"
 
+/* debugging? */
+#if 1
+#define DEBUG(x...)     printk(x);
+#else
+#define DEBUG(x...)
+#endif
+
+
+/* VINO ASIC registers */
+struct sgi_vino *vino;
+
+static const char *vinostr = "VINO IndyCam/TV";
+static int threshold_a = 512;
+static int threshold_b = 512;
+
 struct vino_device {
 	struct video_device vdev;
+#define VINO_CHAN_A		1
+#define VINO_CHAN_B		2
+	int chan;
+};
 
-	unsigned long chan;
-#define VINO_CHAN_A		0
-#define VINO_CHAN_B		1
-
-	unsigned long flags;
-#define VINO_DMA_ACTIVE		(1<<0)
+struct vino_client {
+	struct i2c_client *driver;
+	int owner;
 };
 
-/* We can actually receive TV and IndyCam input at the same time. Believe it or
- * not..
- */
-static struct vino_device vino[2];
+struct vino_video {
+	struct vino_device chA;
+	struct vino_device chB;
+
+	struct vino_client decoder;
+	struct vino_client camera;
+
+	struct semaphore input_lock;
+
+	/* Loaded into VINO descriptors to clear End Of Descriptors table
+	 * interupt condition */
+	unsigned long dummy_page;
+	unsigned int dummy_buf[4] __attribute__((aligned(8)));
+};
 
-/* Those registers have to be accessed by either *one* 64 bit write or *one* 64
- * bit read. We need some asm to fix this. We can't use mips3 as standard
- * because we just save 32 bits at context switch.
- */
+static struct vino_video *Vino;
 
-static __inline__ unsigned long long vino_reg_read(unsigned long addr)
+unsigned i2c_vino_getctrl(void *data)
 {
-	unsigned long long ret __attribute__ ((aligned (64)));
-	unsigned long virt_addr = KSEG1ADDR(addr + VINO_BASE);
-	unsigned long flags;
-
-	save_and_cli(flags);
-	__asm__ __volatile__(
-		".set\tmips3\n\t"
-		".set\tnoat\n\t"
-		"ld\t$1,(%0)\n\t"
-		"sd\t$1,(%1)\n\t"
-		".set\tat\n\t"
-		".set\tmips0"
-		:
-		:"r" (virt_addr),
-		 "r" (&ret)
-		:"$1");
-	restore_flags(flags);
-
-	return ret;
+	return vino->i2c_control;
 }
 
-static __inline__ void vino_reg_write(unsigned long long value,
-				      unsigned long addr)
+void i2c_vino_setctrl(void *data, unsigned val)
 {
-	unsigned long virt_addr = KSEG1ADDR(addr + VINO_BASE);
-	unsigned long flags;
+	vino->i2c_control = val;
+}
 
-	/* we might lose the upper parts of the registers which are not saved
-	 * if there comes an interrupt in our way, play safe */
+unsigned i2c_vino_rdata(void *data)
+{
+	return vino->i2c_data;
+}
 
-	save_and_cli(flags);
-	__asm__ __volatile__(
-		".set\tmips3\n\t"
-		".set\tnoat\n\t"
-		"ld\t$1,(%0)\n\t"
-		"sd\t$1,(%1)\n\t"
-		".set\tat\n\t"
-		".set\tmips0"
-		:
-		:"r" (&value),
-		 "r" (virt_addr)
-		:"$1");
-	restore_flags(flags);
-}
-
-static __inline__ void vino_reg_and(unsigned long long value,
-				    unsigned long addr)
-{
-	unsigned long virt_addr = KSEG1ADDR(addr + VINO_BASE);
-	unsigned long flags;
-
-	save_and_cli(flags);
-	__asm__ __volatile__(
-		".set\tmips3\n\t"
-		".set\tnoat\n\t"
-		"ld\t$1,(%0)\n\t"
-		"ld\t$2,(%1)\n\t"
-		"and\t$1,$1,$2\n\t"
-		"sd\t$1,(%0)\n\t"
-		".set\tat\n\t"
-		".set\tmips0"
-		:
-		:"r" (virt_addr),
-		 "r" (&value)
-		:"$1","$2");
-	restore_flags(flags);
-}
-
-static __inline__ void vino_reg_or(unsigned long long value,
-				   unsigned long addr)
-{
-	unsigned long virt_addr = KSEG1ADDR(addr + VINO_BASE);
-	unsigned long flags;
-
-	save_and_cli(flags);
-	__asm__ __volatile__(
-		".set\tmips3\n\t"
-		".set\tnoat\n\t"
-		"ld\t$1,(%0)\n\t"
-		"ld\t$2,(%1)\n\t"
-		"or\t$1,$1,$2\n\t"
-		"sd\t$1,(%0)\n\t"
-		".set\tat\n\t"
-		".set\tmips0"
-		:
-		:"r" (virt_addr),
-		 "r" (&value)
-		:"$1","$2");
-	restore_flags(flags);
+void i2c_vino_wdata(void *data, unsigned val)
+{
+	vino->i2c_data = val;
 }
 
-static int vino_dma_setup(void)
+static struct i2c_algo_sgi_data i2c_sgi_vino_data =
 {
-	return 0;
+	.getctrl = &i2c_vino_getctrl,
+	.setctrl = &i2c_vino_setctrl,
+	.rdata   = &i2c_vino_rdata,
+	.wdata   = &i2c_vino_wdata,
+	.xfer_timeout = 200,
+	.ack_timeout  = 1000,
+};
+
+/*
+ * There are two possible clients on VINO I2C bus, so we limit usage only
+ * to them.
+ */
+static int i2c_vino_client_reg(struct i2c_client *client)
+{
+	int res = 0;
+
+	down(&Vino->input_lock);
+	switch (client->driver->id) {
+	case I2C_DRIVERID_SAA7191:
+		if (Vino->decoder.driver)
+			res = -EBUSY;
+		else
+			Vino->decoder.driver = client;
+		break;
+	case I2C_DRIVERID_INDYCAM:
+		if (Vino->camera.driver)
+			res = -EBUSY;
+		else
+			Vino->camera.driver = client;
+		break;
+	default:
+		res = -ENODEV;
+	}
+	up(&Vino->input_lock);
+
+	return res;
 }
 
-static void vino_dma_stop(void)
+static int i2c_vino_client_unreg(struct i2c_client *client)
 {
+	int res = 0;
+
+	down(&Vino->input_lock);
+	if (client == Vino->decoder.driver) {
+		if (Vino->decoder.owner)
+			res = -EBUSY;
+		else
+			Vino->decoder.driver = NULL;
+	} else if (client == Vino->camera.driver) {
+		if (Vino->camera.owner)
+			res = -EBUSY;
+		else
+			Vino->camera.driver = NULL;
+	}
+	up(&Vino->input_lock);
 
+	return res;
 }
 
-static int vino_init(void)
+static struct i2c_adapter vino_i2c_adapter =
 {
-	unsigned long ret;
-	unsigned short rev, id;
-	unsigned long long foo;
-	unsigned long *bar;
-
-	bar = (unsigned long *) &foo;
-
-	ret = vino_reg_read(VINO_REVID);
-
-	rev = (ret & VINO_REVID_REV_MASK);
-	id = (ret & VINO_REVID_ID_MASK) >> 4;
-
-	printk("Vino: ID:%02hx Rev:%02hx\n", id, rev);
-
-	foo = vino_reg_read(VINO_A_DESC_DATA0);
-	printk("0x%lx", bar[0]);
-	printk("%lx ", bar[1]);
-	foo = vino_reg_read(VINO_A_DESC_DATA1);
-	printk("0x%lx", bar[0]);
-	printk("%lx ", bar[1]);
-	foo = vino_reg_read(VINO_A_DESC_DATA2);
-	printk("0x%lx", bar[0]);
-	printk("%lx ", bar[1]);
-	foo = vino_reg_read(VINO_A_DESC_DATA3);
-	printk("0x%lx", bar[0]);
-	printk("%lx\n", bar[1]);
-	foo = vino_reg_read(VINO_B_DESC_DATA0);
-	printk("0x%lx", bar[0]);
-	printk("%lx ", bar[1]);
-	foo = vino_reg_read(VINO_B_DESC_DATA1);
-	printk("0x%lx", bar[0]);
-	printk("%lx ", bar[1]);
-	foo = vino_reg_read(VINO_B_DESC_DATA2);
-	printk("0x%lx", bar[0]);
-	printk("%lx ", bar[1]);
-	foo = vino_reg_read(VINO_B_DESC_DATA3);
-	printk("0x%lx", bar[0]);
-	printk("%lx\n", bar[1]);
+	.name			= "VINO I2C bus",
+	.id			= I2C_HW_SGI_VINO,
+	.algo_data		= &i2c_sgi_vino_data,
+	.client_register	= &i2c_vino_client_reg,
+	.client_unregister	= &i2c_vino_client_unreg,
+};
 
-	return 0;
+static int vino_i2c_add_bus(void)
+{
+	return i2c_sgi_add_bus(&vino_i2c_adapter);
 }
 
-static void vino_dma_go(struct vino_device *v)
+static int vino_i2c_del_bus(void)
 {
-	
+	return i2c_sgi_del_bus(&vino_i2c_adapter);
 }
 
-/* Reset the vino back to default state */
 
-static void vino_setup(struct vino_device *v)
+static void vino_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-	
 }
 
 static int vino_open(struct video_device *dev, int flags)
 {
+	struct vino_device *videv = (struct vino_device *)dev;
+
 	return 0;
 }
 
 static void vino_close(struct video_device *dev)
 {
+	struct vino_device *videv = (struct vino_device *)dev;
 }
 
-static int vino_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
+static int vino_mmap(struct video_device *dev, const char *adr,
+		     unsigned long size)
 {
-	return 0;
+	struct vino_device *videv = (struct vino_device *)dev;
+
+	return -EINVAL;
 }
 
-static int vino_mmap(struct video_device *dev, const char *adr,
-		     unsigned long size)
+static int vino_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
 {
-	return 0;
+	struct vino_device *videv = (struct vino_device *)dev;
+
+	return -EINVAL;
 }
 
-static struct video_device vino_dev = {
+static const struct video_device vino_device = {
 	.owner		= THIS_MODULE,
-	.name		= "Vino IndyCam/TV",
-	.type		= VID_TYPE_CAPTURE,
+	.type		= VID_TYPE_CAPTURE | VID_TYPE_SUBCAPTURE,
 	.hardware	= VID_HARDWARE_VINO,
+	.name		= "VINO",
 	.open		= vino_open,
 	.close		= vino_close,
 	.ioctl		= vino_ioctl,
 	.mmap		= vino_mmap,
 };
 
-int __init init_vino(struct video_device *dev)
+static int __init vino_init(void)
 {
-	int err;
+	unsigned long rev;
+	int i, ret = 0;
 
-	err = vino_init();
-	if (err)
-		return err;
+	/* VINO is Indy specific beast */
+	if (ip22_is_fullhouse())
+		return -ENODEV;
 
-#if 0
-	if (video_register_device(&vinodev, VFL_TYPE_GRABBER) == -1) {
+	/*
+	 * VINO is in the EISA address space, so the sysid register will tell
+	 * us if the EISA_PRESENT pin on MC has been pulled low.
+	 *
+	 * If EISA_PRESENT is not set we definitely don't have a VINO equiped
+	 * system.
+	 */
+	if (!(sgimc->systemid & SGIMC_SYSID_EPRESENT)) {
+		printk(KERN_ERR "VINO not found\n");
 		return -ENODEV;
 	}
-#endif
 
-	return 0;
-}
+	vino = (struct sgi_vino *)ioremap(VINO_BASE, sizeof(struct sgi_vino));
+	if (!vino)
+		return -EIO;
+
+	/* Okay, once we know that VINO is present we'll read its revision
+	 * safe way. One never knows... */
+	if (get_dbe(rev, &(vino->rev_id))) {
+		printk(KERN_ERR "VINO: failed to read revision register\n");
+		ret = -ENODEV;
+		goto out_unmap;
+	}
+	if (VINO_ID_VALUE(rev) != VINO_CHIP_ID) {
+		printk(KERN_ERR "VINO is not VINO (Rev/ID: 0x%04lx)\n", rev);
+		ret = -ENODEV;
+		goto out_unmap;
+	}
+	printk(KERN_INFO "VINO Rev: 0x%02lx\n", VINO_REV_NUM(rev));
 
-#ifdef MODULE
-int init_module(void)
-{
-	int err;
+	Vino = (struct vino_video *)
+		kmalloc(sizeof(struct vino_video), GFP_KERNEL);
+	if (!Vino) {
+		ret = -ENOMEM;
+		goto out_unmap;
+	}
+
+	Vino->dummy_page = get_zeroed_page(GFP_KERNEL | GFP_DMA);
+	if (!Vino->dummy_page) {
+		ret = -ENOMEM;
+		goto out_free_vino;
+	}
+	for (i = 0; i < 4; i++)
+		Vino->dummy_buf[i] = PHYSADDR(Vino->dummy_page);
+
+	vino->control = 0;
+	/* prevent VINO from throwing spurious interrupts */
+	vino->a.next_4_desc = PHYSADDR(Vino->dummy_buf);
+	vino->b.next_4_desc = PHYSADDR(Vino->dummy_buf);
+	udelay(5);
+	vino->intr_status = 0;
+        /* set threshold level */
+        vino->a.fifo_thres = threshold_a;
+	vino->b.fifo_thres = threshold_b;
+
+	init_MUTEX(&Vino->input_lock);
+
+	if (request_irq(SGI_VINO_IRQ, vino_interrupt, 0, vinostr, NULL)) {
+		printk(KERN_ERR "VINO: irq%02d registration failed\n",
+		       SGI_VINO_IRQ);
+		ret = -EAGAIN;
+		goto out_free_page;
+	}
 
-	err = vino_init();
-	if (err)
-		return err;
+	ret = vino_i2c_add_bus();
+	if (ret) {
+		printk(KERN_ERR "VINO: I2C bus registration failed\n");
+		goto out_free_irq;
+	}
+
+	if (video_register_device(&Vino->chA.vdev, VFL_TYPE_GRABBER, -1) < 0) {
+		printk("%s, chnl %d: device registration failed.\n",
+			Vino->chA.vdev.name, Vino->chA.chan);
+		ret = -EINVAL;
+		goto out_i2c_del_bus;
+	}
+	if (video_register_device(&Vino->chB.vdev, VFL_TYPE_GRABBER, -1) < 0) {
+		printk("%s, chnl %d: device registration failed.\n",
+			Vino->chB.vdev.name, Vino->chB.chan);
+		ret = -EINVAL;
+		goto out_unregister_vdev;
+	}
 
 	return 0;
+
+out_unregister_vdev:
+	video_unregister_device(&Vino->chA.vdev);
+out_i2c_del_bus:
+	vino_i2c_del_bus();
+out_free_irq:
+	free_irq(SGI_VINO_IRQ, NULL);
+out_free_page:
+	free_page(Vino->dummy_page);
+out_free_vino:
+	kfree(Vino);
+out_unmap:
+	iounmap(vino);
+
+	return ret;
 }
 
-void cleanup_module(void)
+static void __exit vino_exit(void)
 {
+	video_unregister_device(&Vino->chA.vdev);
+	video_unregister_device(&Vino->chB.vdev);
+	vino_i2c_del_bus();
+	free_irq(SGI_VINO_IRQ, NULL);
+	free_page(Vino->dummy_page);
+	kfree(Vino);
+	iounmap(vino);
 }
-#endif
+
+module_init(vino_init);
+module_exit(vino_exit);
+
+MODULE_DESCRIPTION("Video4Linux driver for SGI Indy VINO (IndyCam)");
+MODULE_LICENSE("GPL");
diff -Nru a/drivers/media/video/vino.h b/drivers/media/video/vino.h
--- a/drivers/media/video/vino.h	2005-03-01 23:38:51 -08:00
+++ b/drivers/media/video/vino.h	2005-03-01 23:38:51 -08:00
@@ -1,64 +1,84 @@
 /*
- * Copyright (C) 1999 Ulf Carlsson (ulfc@bun.falkenberg.se)
- * Copyright (C) 2001 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 1999 Ulf Karlsson <ulfc@bun.falkenberg.se>
+ * Copyright (C) 2003 Ladislav Michl <ladis@linux-mips.org>
  */
 
-#define VINO_BASE		0x00080000	/* In EISA address space */
+#ifndef VINO_H
+#define VINO_H
 
-#define VINO_REVID		0x0000
-#define VINO_CTRL		0x0008
-#define VINO_INTSTAT		0x0010	/* Interrupt status */
-#define VINO_I2C_CTRL		0x0018
-#define VINO_I2C_DATA		0x0020
-#define VINO_A_ALPHA		0x0028	/* Channel A ... */
-#define VINO_A_CLIPS		0x0030	/* Clipping start */
-#define VINO_A_CLIPE		0x0038	/* Clipping end */
-#define VINO_A_FRAMERT		0x0040	/* Framerate */
-#define VINO_A_FLDCNT		0x0048	/* Field counter */
-#define VINO_A_LNSZ		0x0050
-#define VINO_A_LNCNT		0x0058
-#define VINO_A_PGIX		0x0060	/* Page index */
-#define VINO_A_DESC_PTR		0x0068	/* Ptr to next four descriptors */
-#define VINO_A_DESC_TLB_PTR	0x0070	/* Ptr to start of descriptor table */
-#define VINO_A_DESC_DATA0	0x0078	/* Descriptor data 0 */
-#define VINO_A_DESC_DATA1	0x0080	/* ... */
-#define VINO_A_DESC_DATA2	0x0088
-#define VINO_A_DESC_DATA3	0x0090
-#define VINO_A_FIFO_THRESHOLD	0x0098	/* FIFO threshold */
-#define VINO_A_FIFO_RP		0x00a0
-#define VINO_A_FIFO_WP		0x00a8
-#define VINO_B_ALPHA		0x00b0	/* Channel B ... */
-#define VINO_B_CLIPS		0x00b8
-#define VINO_B_CLIPE		0x00c0
-#define VINO_B_FRAMERT		0x00c8
-#define VINO_B_FLDCNT		0x00d0
-#define VINO_B_LNSZ		0x00d8
-#define VINO_B_LNCNT		0x00e0
-#define VINO_B_PGIX		0x00e8
-#define VINO_B_DESC_PTR		0x00f0
-#define VINO_B_DESC_TLB_PTR	0x00f8
-#define VINO_B_DESC_DATA0	0x0100
-#define VINO_B_DESC_DATA1	0x0108
-#define VINO_B_DESC_DATA2	0x0110
-#define VINO_B_DESC_DATA3	0x0118
-#define VINO_B_FIFO_THRESHOLD	0x0120
-#define VINO_B_FIFO_RP		0x0128
-#define VINO_B_FIFO_WP		0x0130
+#define VINO_BASE	0x00080000	/* Vino is in the EISA address space,
+					 * but it is not an EISA bus card */
 
-/* Bits in the VINO_REVID register */
-
-#define VINO_REVID_REV_MASK		0x000f	/* bits 0:3 */
-#define VINO_REVID_ID_MASK		0x00f0	/* bits 4:7 */
-
-/* Bits in the VINO_CTRL register */
+struct sgi_vino_channel {
+	u32 _pad_alpha;
+	volatile u32 alpha;
+
+#define VINO_CLIP_X(x)		((x) & 0x3ff)		/* bits 0:9 */
+#define VINO_CLIP_ODD(x)	(((x) & 0x1ff) << 10)	/* bits 10:18 */
+#define VINO_CLIP_EVEN(x)	(((x) & 0x1ff) << 19)	/* bits 19:27 */
+	u32 _pad_clip_start;
+	volatile u32 clip_start;
+	u32 _pad_clip_end;
+	volatile u32 clip_end;
+
+#define VINO_FRAMERT_PAL	(1<<0)			/* 0=NTSC 1=PAL */
+#define VINO_FRAMERT_RT(x)	(((x) & 0x1fff) << 1)	/* bits 1:12 */
+	u32 _pad_frame_rate;
+	volatile u32 frame_rate;
+
+	u32 _pad_field_counter;
+	volatile u32 field_counter;
+	u32 _pad_line_size;
+	volatile u32 line_size;
+	u32 _pad_line_count;
+	volatile u32 line_count;
+	u32 _pad_page_index;
+	volatile u32 page_index;
+	u32 _pad_next_4_desc;
+	volatile u32 next_4_desc;
+	u32 _pad_start_desc_tbl;
+	volatile u32 start_desc_tbl;
+
+#define VINO_DESC_JUMP		(1<<30)
+#define VINO_DESC_STOP		(1<<31)
+#define VINO_DESC_VALID		(1<<32)
+	u32 _pad_desc_0;
+	volatile u32 desc_0;
+	u32 _pad_desc_1;
+	volatile u32 desc_1;
+	u32 _pad_desc_2;
+	volatile u32 desc_2;
+	u32 _pad_Bdesc_3;
+	volatile u32 desc_3;
+
+	u32 _pad_fifo_thres;
+	volatile u32 fifo_thres;
+	u32 _pad_fifo_read;
+	volatile u32 fifo_read;
+	u32 _pad_fifo_write;
+	volatile u32 fifo_write;
+};
+
+struct sgi_vino {
+#define VINO_CHIP_ID		0xb
+#define VINO_REV_NUM(x)		((x) & 0x0f)
+#define VINO_ID_VALUE(x)	(((x) & 0xf0) >> 4)
+	u32 _pad_rev_id;
+	volatile u32 rev_id;
 
 #define VINO_CTRL_LITTLE_ENDIAN		(1<<0)
 #define VINO_CTRL_A_FIELD_TRANS_INT	(1<<1)	/* Field transferred int */
 #define VINO_CTRL_A_FIFO_OF_INT		(1<<2)	/* FIFO overflow int */
 #define VINO_CTRL_A_END_DESC_TBL_INT	(1<<3)	/* End of desc table int */
+#define VINO_CTRL_A_INT			(VINO_CTRL_A_FIELD_TRANS_INT | \
+					 VINO_CTRL_A_FIFO_OF_INT | \
+					 VINO_CTRL_A_END_DESC_TBL_INT)
 #define VINO_CTRL_B_FIELD_TRANS_INT	(1<<4)	/* Field transferred int */
 #define VINO_CTRL_B_FIFO_OF_INT		(1<<5)	/* FIFO overflow int */
-#define VINO_CTRL_B_END_DESC_TLB_INT	(1<<6)	/* End of desc table int */
+#define VINO_CTRL_B_END_DESC_TBL_INT	(1<<6)	/* End of desc table int */
+#define VINO_CTRL_B_INT			(VINO_CTRL_B_FIELD_TRANS_INT | \
+					 VINO_CTRL_B_FIFO_OF_INT | \
+					 VINO_CTRL_B_END_DESC_TBL_INT)
 #define VINO_CTRL_A_DMA_ENBL		(1<<7)
 #define VINO_CTRL_A_INTERLEAVE_ENBL	(1<<8)
 #define VINO_CTRL_A_SYNC_ENBL		(1<<9)
@@ -67,51 +87,45 @@
 #define VINO_CTRL_A_LUMA_ONLY		(1<<12)
 #define VINO_CTRL_A_DEC_ENBL		(1<<13)	/* Decimation */
 #define VINO_CTRL_A_DEC_SCALE_MASK	0x1c000	/* bits 14:17 */
+#define VINO_CTRL_A_DEC_SCALE_SHIFT	(14)
 #define VINO_CTRL_A_DEC_HOR_ONLY	(1<<17)	/* Horizontal only */
 #define VINO_CTRL_A_DITHER		(1<<18)	/* 24 -> 8 bit dither */
 #define VINO_CTRL_B_DMA_ENBL		(1<<19)
 #define VINO_CTRL_B_INTERLEAVE_ENBL	(1<<20)
 #define VINO_CTRL_B_SYNC_ENBL		(1<<21)
 #define VINO_CTRL_B_SELECT		(1<<22)	/* 1=D1 0=Philips */
-#define VINO_CTRL_B_RGB			(1<<22)	/* 1=RGB 0=YUV */
-#define VINO_CTRL_B_LUMA_ONLY		(1<<23)
-#define VINO_CTRL_B_DEC_ENBL		(1<<24)	/* Decimation */
-#define VINO_CTRL_B_DEC_SCALE_MASK	0x1c000000	/* bits 25:28 */
+#define VINO_CTRL_B_RGB			(1<<23)	/* 1=RGB 0=YUV */
+#define VINO_CTRL_B_LUMA_ONLY		(1<<24)
+#define VINO_CTRL_B_DEC_ENBL		(1<<25)	/* Decimation */
+#define VINO_CTRL_B_DEC_SCALE_MASK	0x1c000000	/* bits 26:28 */
+#define VINO_CTRL_B_DEC_SCALE_SHIFT	(26)
 #define VINO_CTRL_B_DEC_HOR_ONLY	(1<<29)	/* Decimation horizontal only */
 #define VINO_CTRL_B_DITHER		(1<<30)	/* ChanB 24 -> 8 bit dither */
-
-/* Bits in the Interrupt and Status register */
+	u32 _pad_control;
+	volatile u32 control;
 
 #define VINO_INTSTAT_A_FIELD_TRANS	(1<<0)	/* Field transferred int */
 #define VINO_INTSTAT_A_FIFO_OF		(1<<1)	/* FIFO overflow int */
 #define VINO_INTSTAT_A_END_DESC_TBL	(1<<2)	/* End of desc table int */
+#define VINO_INTSTAT_A			(VINO_INTSTAT_A_FIELD_TRANS | \
+					 VINO_INTSTAT_A_FIFO_OF | \
+					 VINO_INTSTAT_A_END_DESC_TBL)
 #define VINO_INTSTAT_B_FIELD_TRANS	(1<<3)	/* Field transferred int */
 #define VINO_INTSTAT_B_FIFO_OF		(1<<4)	/* FIFO overflow int */
 #define VINO_INTSTAT_B_END_DESC_TBL	(1<<5)	/* End of desc table int */
+#define VINO_INTSTAT_B			(VINO_INTSTAT_B_FIELD_TRANS | \
+					 VINO_INTSTAT_B_FIFO_OF | \
+					 VINO_INTSTAT_B_END_DESC_TBL)
+	u32 _pad_intr_status;
+	volatile u32 intr_status;
+
+	u32 _pad_i2c_control;
+	volatile u32 i2c_control;
+	u32 _pad_i2c_data;
+	volatile u32 i2c_data;
+
+	struct sgi_vino_channel a;
+	struct sgi_vino_channel b;
+};
 
-/* Bits in the Clipping Start register */
-
-#define VINO_CLIPS_START		0x3ff		/* bits 0:9 */
-#define VINO_CLIPS_ODD_MASK		0x7fc00		/* bits 10:18 */
-#define VINO_CLIPS_EVEN_MASK		0xff80000	/* bits 19:27 */
-
-/* Bits in the Clipping End register */
-
-#define VINO_CLIPE_END			0x3ff		/* bits 0:9 */
-#define VINO_CLIPE_ODD_MASK		0x7fc00		/* bits 10:18 */
-#define VINO_CLIPE_EVEN_MASK		0xff80000	/* bits 19:27 */
-
-/* Bits in the Frame Rate register */
-
-#define VINO_FRAMERT_PAL		(1<<0)	/* 0=NTSC 1=PAL */
-#define VINO_FRAMERT_RT_MASK		0x1ffe		/* bits 1:12 */
-
-/* Bits in the VINO_I2C_CTRL */
-
-#define VINO_CTRL_I2C_IDLE		(1<<0)	/* write: 0=force idle
-						 * read: 0=idle 1=not idle */
-#define VINO_CTRL_I2C_DIR		(1<<1)	/* 0=read 1=write */
-#define VINO_CTRL_I2C_MORE_BYTES	(1<<2)	/* 0=last byte 1=more bytes */
-#define VINO_CTRL_I2C_TRANS_BUSY	(1<<4)	/* 0=trans done 1=trans busy */
-#define VINO_CTRL_I2C_ACK		(1<<5)	/* 0=ack received 1=ack not */
-#define VINO_CTRL_I2C_BUS_ERROR		(1<<7)	/* 0=no bus err 1=bus err */
+#endif
diff -Nru a/drivers/media/video/vpx3220.c b/drivers/media/video/vpx3220.c
--- a/drivers/media/video/vpx3220.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/media/video/vpx3220.c	2005-03-01 23:38:58 -08:00
@@ -41,7 +41,7 @@
 #define VPX3220_DEBUG	KERN_DEBUG "vpx3220: "
 
 static int debug = 0;
-MODULE_PARM(debug, "i");
+module_param(debug, int, 0);
 MODULE_PARM_DESC(debug, "Debug level (0-1)");
 
 #define dprintk(num, format, args...) \
diff -Nru a/drivers/media/video/w9966.c b/drivers/media/video/w9966.c
--- a/drivers/media/video/w9966.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/media/video/w9966.c	2005-03-01 23:38:54 -08:00
@@ -127,18 +127,18 @@
 #else
 static const char* pardev[] = {[0 ... W9966_MAXCAMS] = "aggressive"};
 #endif
-MODULE_PARM(pardev, "1-" __MODULE_STRING(W9966_MAXCAMS) "s");
+module_param_array(pardev, charp, NULL, 0);
 MODULE_PARM_DESC(pardev, "pardev: where to search for\n\
 \teach camera. 'aggressive' means brute-force search.\n\
 \tEg: >pardev=parport3,aggressive,parport2,parport1< would assign\n\
 \tcam 1 to parport3 and search every parport for cam 2 etc...");
 
 static int parmode = 0;
-MODULE_PARM(parmode, "i");
+module_param(parmode, int, 0);
 MODULE_PARM_DESC(parmode, "parmode: transfer mode (0=auto, 1=ecp, 2=epp");
 
 static int video_nr = -1;
-MODULE_PARM(video_nr, "i");
+module_param(video_nr, int, 0);
 
 /*
  *	Private data
@@ -330,7 +330,7 @@
 
 // Fill in the video_device struct and register us to v4l
 	memcpy(&cam->vdev, &w9966_template, sizeof(struct video_device));
-	cam->vdev.priv = (void*)cam;
+	cam->vdev.priv = cam;
 
 	if (video_register_device(&cam->vdev, VFL_TYPE_GRABBER, video_nr) == -1)		 
 		return -1;
@@ -712,7 +712,7 @@
 			      unsigned int cmd, void *arg)
 {
 	struct video_device *vdev = video_devdata(file);
-	struct w9966_dev *cam = (struct w9966_dev*)vdev->priv;
+	struct w9966_dev *cam = vdev->priv;
 	
 	switch(cmd)
 	{
@@ -871,7 +871,7 @@
 			      size_t count, loff_t *ppos)
 {
 	struct video_device *vdev = video_devdata(file);
-	struct w9966_dev *cam = (struct w9966_dev *)vdev->priv;
+	struct w9966_dev *cam = vdev->priv;
 	unsigned char addr = 0xa0;	// ECP, read, CCD-transfer, 00000
 	unsigned char __user *dest = (unsigned char __user *)buf;
 	unsigned long dleft = count;
diff -Nru a/drivers/media/video/zoran_card.c b/drivers/media/video/zoran_card.c
--- a/drivers/media/video/zoran_card.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/media/video/zoran_card.c	2005-03-01 23:38:58 -08:00
@@ -58,18 +58,17 @@
 #define I2C_NAME(x) (x)->name
 
 extern const struct zoran_format zoran_formats[];
-extern const int zoran_num_formats;
 
 static int card[BUZ_MAX] = { -1, -1, -1, -1 };
-MODULE_PARM(card, "1-" __stringify(BUZ_MAX) "i");
+module_param_array(card, int, NULL, 0);
 MODULE_PARM_DESC(card, "The type of card");
 
 static int encoder[BUZ_MAX] = { -1, -1, -1, -1 };
-MODULE_PARM(encoder, "1-" __stringify(BUZ_MAX) "i");
+module_param_array(encoder, int, NULL, 0);
 MODULE_PARM_DESC(encoder, "i2c TV encoder");
 
 static int decoder[BUZ_MAX] = { -1, -1, -1, -1 };
-MODULE_PARM(decoder, "1-" __stringify(BUZ_MAX) "i");
+module_param_array(decoder, int, NULL, 0);
 MODULE_PARM_DESC(decoder, "i2c TV decoder");
 
 /*
@@ -81,23 +80,23 @@
  */
 
 static unsigned long vidmem = 0;	/* Video memory base address */
-MODULE_PARM(vidmem, "i");
+module_param(vidmem, ulong, 0);
 
 /*
    Default input and video norm at startup of the driver.
 */
 
 static int default_input = 0;	/* 0=Composite, 1=S-Video */
-MODULE_PARM(default_input, "i");
+module_param(default_input, int, 0);
 MODULE_PARM_DESC(default_input,
 		 "Default input (0=Composite, 1=S-Video, 2=Internal)");
 
 static int default_norm = 0;	/* 0=PAL, 1=NTSC 2=SECAM */
-MODULE_PARM(default_norm, "i");
+module_param(default_norm, int, 0);
 MODULE_PARM_DESC(default_norm, "Default norm (0=PAL, 1=NTSC, 2=SECAM)");
 
 static int video_nr = -1;	/* /dev/videoN, -1 for autodetect */
-MODULE_PARM(video_nr, "i");
+module_param(video_nr, int, 0);
 MODULE_PARM_DESC(video_nr, "video device number");
 
 /*
@@ -119,27 +118,27 @@
 
 int v4l_nbufs = 2;
 int v4l_bufsize = 128;		/* Everybody should be able to work with this setting */
-MODULE_PARM(v4l_nbufs, "i");
+module_param(v4l_nbufs, int, 0);
 MODULE_PARM_DESC(v4l_nbufs, "Maximum number of V4L buffers to use");
-MODULE_PARM(v4l_bufsize, "i");
+module_param(v4l_bufsize, int, 0);
 MODULE_PARM_DESC(v4l_bufsize, "Maximum size per V4L buffer (in kB)");
 
 int jpg_nbufs = 32;
 int jpg_bufsize = 512;		/* max size for 100% quality full-PAL frame */
-MODULE_PARM(jpg_nbufs, "i");
+module_param(jpg_nbufs, int, 0);
 MODULE_PARM_DESC(jpg_nbufs, "Maximum number of JPG buffers to use");
-MODULE_PARM(jpg_bufsize, "i");
+module_param(jpg_bufsize, int, 0);
 MODULE_PARM_DESC(jpg_bufsize, "Maximum size per JPG buffer (in kB)");
 
 int pass_through = 0;		/* 1=Pass through TV signal when device is not used */
 				/* 0=Show color bar when device is not used (LML33: only if lml33dpath=1) */
-MODULE_PARM(pass_through, "i");
+module_param(pass_through, int, 0);
 MODULE_PARM_DESC(pass_through,
 		 "Pass TV signal through to TV-out when idling");
 
 static int debug = 1;
 int *zr_debug = &debug;
-MODULE_PARM(debug, "i");
+module_param(debug, int, 0);
 MODULE_PARM_DESC(debug, "Debug level (0-4)");
 
 MODULE_DESCRIPTION("Zoran-36057/36067 JPEG codec driver");
diff -Nru a/drivers/media/video/zoran_device.c b/drivers/media/video/zoran_device.c
--- a/drivers/media/video/zoran_device.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/media/video/zoran_device.c	2005-03-01 23:38:58 -08:00
@@ -32,6 +32,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/vmalloc.h>
+#include <linux/byteorder/generic.h>
 
 #include <linux/interrupt.h>
 #include <linux/proc_fs.h>
@@ -57,7 +58,6 @@
 		   ZR36057_ISR_JPEGRepIRQ )
 
 extern const struct zoran_format zoran_formats[];
-extern const int zoran_num_formats;
 
 extern int *zr_debug;
 
@@ -76,10 +76,13 @@
 				 * load on Bt819 input, there will be
 				 * some image imperfections */
 
-MODULE_PARM(lml33dpath, "i");
+module_param(lml33dpath, bool, 0);
 MODULE_PARM_DESC(lml33dpath,
 		 "Use digital path capture mode (on LML33 cards)");
 
+static void
+zr36057_init_vfe (struct zoran *zr);
+
 /*
  * General Purpose I/O and Guest bus access
  */
@@ -758,7 +761,7 @@
 		zr->jpg_buffers.buffer[i].state = BUZ_STATE_USER;	/* nothing going on */
 	}
 	for (i = 0; i < BUZ_NUM_STAT_COM; i++) {
-		zr->stat_com[i] = 1;	/* mark as unavailable to zr36057 */
+		zr->stat_com[i] = cpu_to_le32(1);	/* mark as unavailable to zr36057 */
 	}
 }
 
@@ -1033,7 +1036,10 @@
 
 	switch (mode) {
 
-	case BUZ_MODE_MOTION_COMPRESS:
+	case BUZ_MODE_MOTION_COMPRESS: {
+		struct jpeg_app_marker app;
+		struct jpeg_com_marker com;
+
 		/* In motion compress mode, the decoder output must be enabled, and
 		 * the video bus direction set to input.
 		 */
@@ -1043,6 +1049,19 @@
 
 		/* Take the JPEG codec and the VFE out of sleep */
 		jpeg_codec_sleep(zr, 0);
+
+		/* set JPEG app/com marker */
+		app.appn = zr->jpg_settings.jpg_comp.APPn;
+		app.len = zr->jpg_settings.jpg_comp.APP_len;
+		memcpy(app.data, zr->jpg_settings.jpg_comp.APP_data, 60);
+		zr->codec->control(zr->codec, CODEC_S_JPEG_APP_DATA,
+				   sizeof(struct jpeg_app_marker), &app);
+
+		com.len = zr->jpg_settings.jpg_comp.COM_len;
+		memcpy(com.data, zr->jpg_settings.jpg_comp.COM_data, 60);
+		zr->codec->control(zr->codec, CODEC_S_JPEG_COM_DATA,
+				   sizeof(struct jpeg_com_marker), &com);
+
 		/* Setup the JPEG codec */
 		zr->codec->control(zr->codec, CODEC_S_JPEG_TDS_BYTE,
 				   sizeof(int), &field_size);
@@ -1066,6 +1085,7 @@
 		dprintk(2, KERN_INFO "%s: enable_jpg(MOTION_COMPRESS)\n",
 			ZR_DEVNAME(zr));
 		break;
+	}
 
 	case BUZ_MODE_MOTION_DECOMPRESS:
 		/* In motion decompression mode, the decoder output must be disabled, and
@@ -1146,20 +1166,20 @@
 			/* fill 1 stat_com entry */
 			i = (zr->jpg_dma_head -
 			     zr->jpg_err_shift) & BUZ_MASK_STAT_COM;
-			if (!(zr->stat_com[i] & 1))
+			if (!(zr->stat_com[i] & cpu_to_le32(1)))
 				break;
 			zr->stat_com[i] =
-			    zr->jpg_buffers.buffer[frame].frag_tab_bus;
+			    cpu_to_le32(zr->jpg_buffers.buffer[frame].frag_tab_bus);
 		} else {
 			/* fill 2 stat_com entries */
 			i = ((zr->jpg_dma_head -
 			      zr->jpg_err_shift) & 1) * 2;
-			if (!(zr->stat_com[i] & 1))
+			if (!(zr->stat_com[i] & cpu_to_le32(1)))
 				break;
 			zr->stat_com[i] =
-			    zr->jpg_buffers.buffer[frame].frag_tab_bus;
+			    cpu_to_le32(zr->jpg_buffers.buffer[frame].frag_tab_bus);
 			zr->stat_com[i + 1] =
-			    zr->jpg_buffers.buffer[frame].frag_tab_bus;
+			    cpu_to_le32(zr->jpg_buffers.buffer[frame].frag_tab_bus);
 		}
 		zr->jpg_buffers.buffer[frame].state = BUZ_STATE_DMA;
 		zr->jpg_dma_head++;
@@ -1196,7 +1216,7 @@
 			i = ((zr->jpg_dma_tail -
 			      zr->jpg_err_shift) & 1) * 2 + 1;
 
-		stat_com = zr->stat_com[i];
+		stat_com = le32_to_cpu(zr->stat_com[i]);
 
 		if ((stat_com & 1) == 0) {
 			return;
@@ -1292,7 +1312,7 @@
 					for (i = 0;
 					     i < zr->jpg_buffers.num_buffers;
 					     i++) {
-						if (zr->stat_com[j] ==
+						if (le32_to_cpu(zr->stat_com[j]) ==
 						    zr->jpg_buffers.
 						    buffer[i].
 						    frag_tab_bus) {
@@ -1304,7 +1324,6 @@
 				printk("\n");
 			}
 		}
-
 		/* Find an entry in stat_com and rotate contents */
 		{
 			int i;
@@ -1317,9 +1336,9 @@
 				      zr->jpg_err_shift) & 1) * 2;
 			if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS) {
 				/* Mimic zr36067 operation */
-				zr->stat_com[i] |= 1;
+				zr->stat_com[i] |= cpu_to_le32(1);
 				if (zr->jpg_settings.TmpDcm != 1)
-					zr->stat_com[i + 1] |= 1;
+					zr->stat_com[i + 1] |= cpu_to_le32(1);
 				/* Refill */
 				zoran_reap_stat_com(zr);
 				zoran_feed_stat_com(zr);
@@ -1338,12 +1357,17 @@
 				int j;
 				u32 bus_addr[BUZ_NUM_STAT_COM];
 
+				/* Here we are copying the stat_com array, which
+				 * is already in little endian format, so
+				 * no endian conversions here
+				 */
 				memcpy(bus_addr, zr->stat_com,
 				       sizeof(bus_addr));
 				for (j = 0; j < BUZ_NUM_STAT_COM; j++) {
 					zr->stat_com[j] =
 					    bus_addr[(i + j) &
 						     BUZ_MASK_STAT_COM];
+
 				}
 				zr->jpg_err_shift += i;
 				zr->jpg_err_shift &= BUZ_MASK_STAT_COM;
@@ -1547,7 +1571,7 @@
 						int i;
 						strcpy(sv, sc);
 						for (i = 0; i < 4; i++) {
-							if (zr->stat_com[i] & 1)
+							if (le32_to_cpu(zr->stat_com[i]) & 1)
 								sv[i] = '1';
 						}
 						sv[4] = 0;
@@ -1575,7 +1599,7 @@
 					       ZR_DEVNAME(zr), zr->jpg_seq_num);
 					for (i = 0; i < 4; i++) {
 						printk(" %08x",
-						       zr->stat_com[i]);
+						       le32_to_cpu(zr->stat_com[i]));
 					}
 					printk("\n");
 				}
@@ -1701,7 +1725,7 @@
  * initialize video front end
  */
 
-void
+static void
 zr36057_init_vfe (struct zoran *zr)
 {
 	u32 reg;
diff -Nru a/drivers/media/video/zoran_device.h b/drivers/media/video/zoran_device.h
--- a/drivers/media/video/zoran_device.h	2005-03-01 23:38:56 -08:00
+++ b/drivers/media/video/zoran_device.h	2005-03-01 23:38:56 -08:00
@@ -79,7 +79,6 @@
 				 int set_master);
 extern void zoran_init_hardware(struct zoran *zr);
 extern void zr36057_restart(struct zoran *zr);
-extern void zr36057_init_vfe(struct zoran *zr);
 
 /* i2c */
 extern int decoder_command(struct zoran *zr,
diff -Nru a/drivers/media/video/zoran_driver.c b/drivers/media/video/zoran_driver.c
--- a/drivers/media/video/zoran_driver.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/media/video/zoran_driver.c	2005-03-01 23:39:08 -08:00
@@ -52,6 +52,7 @@
 #include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/vmalloc.h>
+#include <linux/byteorder/generic.h>
 
 #include <linux/interrupt.h>
 #include <linux/i2c.h>
@@ -176,7 +177,7 @@
 			 ZORAN_FORMAT_COMPRESSED,
 	}
 };
-const int zoran_num_formats =
+static const int zoran_num_formats =
     (sizeof(zoran_formats) / sizeof(struct zoran_format));
 
 // RJ: Test only - want to test BUZ_USE_HIMEM even when CONFIG_BIGPHYS_AREA is defined
@@ -204,7 +205,7 @@
 extern int pass_through;
 
 static int lock_norm = 0;	/* 1=Don't change TV standard (norm) */
-MODULE_PARM(lock_norm, "i");
+module_param(lock_norm, int, 0);
 MODULE_PARM_DESC(lock_norm, "Users can't change norm");
 
 #ifdef HAVE_V4L2
@@ -516,6 +517,16 @@
  *       virtual addresses) and then again have to make a lot of efforts
  *       to get the physical address.
  *
+ *   Ben Capper:
+ *       On big-endian architectures (such as ppc) some extra steps
+ *       are needed. When reading and writing to the stat_com array
+ *       and fragment buffers, the device expects to see little-
+ *       endian values. The use of cpu_to_le32() and le32_to_cpu()
+ *       in this function (and one or two others in zoran_device.c)
+ *       ensure that these values are always stored in little-endian
+ *       form, regardless of architecture. The zr36057 does Very Bad
+ *       Things on big endian architectures if the stat_com array
+ *       and fragment buffers are not little-endian.
  */
 
 static int
@@ -569,9 +580,9 @@
 				return -ENOBUFS;
 			}
 			fh->jpg_buffers.buffer[i].frag_tab[0] =
-			    virt_to_bus((void *) mem);
+			    cpu_to_le32(virt_to_bus((void *) mem));
 			fh->jpg_buffers.buffer[i].frag_tab[1] =
-			    ((fh->jpg_buffers.buffer_size / 4) << 1) | 1;
+			    cpu_to_le32(((fh->jpg_buffers.buffer_size / 4) << 1) | 1);
 			for (off = 0; off < fh->jpg_buffers.buffer_size;
 			     off += PAGE_SIZE)
 				SetPageReserved(MAP_NR(mem + off));
@@ -591,14 +602,14 @@
 				}
 
 				fh->jpg_buffers.buffer[i].frag_tab[2 * j] =
-				    virt_to_bus((void *) mem);
+				    cpu_to_le32(virt_to_bus((void *) mem));
 				fh->jpg_buffers.buffer[i].frag_tab[2 * j +
 								   1] =
-				    (PAGE_SIZE / 4) << 1;
+				    cpu_to_le32((PAGE_SIZE / 4) << 1);
 				SetPageReserved(MAP_NR(mem));
 			}
 
-			fh->jpg_buffers.buffer[i].frag_tab[2 * j - 1] |= 1;
+			fh->jpg_buffers.buffer[i].frag_tab[2 * j - 1] |= cpu_to_le32(1);
 		}
 	}
 
@@ -631,13 +642,8 @@
 		//if (alloc_contig) {
 		if (fh->jpg_buffers.need_contiguous) {
 			if (fh->jpg_buffers.buffer[i].frag_tab[0]) {
-				mem =
-				    (unsigned char *) bus_to_virt(fh->
-								  jpg_buffers.
-								  buffer
-								  [i].
-								  frag_tab
-								  [0]);
+				mem = (unsigned char *) bus_to_virt(le32_to_cpu(
+					fh->jpg_buffers.buffer[i].frag_tab[0]));
 				for (off = 0;
 				     off < fh->jpg_buffers.buffer_size;
 				     off += PAGE_SIZE)
@@ -656,13 +662,16 @@
 					break;
 				ClearPageReserved(MAP_NR
 						  (bus_to_virt
-						   (fh->jpg_buffers.
-						    buffer[i].frag_tab[2 *
-								       j])));
+						   (le32_to_cpu
+						    (fh->jpg_buffers.
+						     buffer[i].frag_tab[2 *
+								       j]))));
 				free_page((unsigned long)
-					  bus_to_virt(fh->jpg_buffers.
+					  bus_to_virt
+					          (le32_to_cpu
+						   (fh->jpg_buffers.
 						      buffer[i].
-						      frag_tab[2 * j]));
+						      frag_tab[2 * j])));
 				fh->jpg_buffers.buffer[i].frag_tab[2 * j] =
 				    0;
 				fh->jpg_buffers.buffer[i].frag_tab[2 * j +
@@ -2005,6 +2014,8 @@
 {
 	struct zoran_fh *fh = file->private_data;
 	struct zoran *zr = fh->zr;
+	/* CAREFUL: used in multiple places here */
+	struct zoran_jpg_settings settings;
 
 	/* we might have older buffers lying around... We don't want
 	 * to wait, but we do want to try cleaning them up ASAP. So
@@ -2453,7 +2464,6 @@
 	case BUZIOC_S_PARAMS:
 	{
 		struct zoran_params *bparams = arg;
-		struct zoran_jpg_settings settings;
 		int res = 0;
 
 		dprintk(3, KERN_DEBUG "%s: BUZIOC_S_PARAMS\n", ZR_DEVNAME(zr));
@@ -2910,8 +2920,6 @@
 			}
 
 			if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG) {
-				struct zoran_jpg_settings settings;
-
 				down(&zr->resource_lock);
 
 				settings = fh->jpg_settings;
@@ -3974,7 +3982,8 @@
 	{
 		struct v4l2_crop *crop = arg;
 		int res = 0;
-		struct zoran_jpg_settings settings = fh->jpg_settings;
+
+		settings = fh->jpg_settings;
 
 		dprintk(3,
 			KERN_ERR
@@ -4056,9 +4065,10 @@
 	case VIDIOC_S_JPEGCOMP:
 	{
 		struct v4l2_jpegcompression *params = arg;
-		struct zoran_jpg_settings settings = fh->jpg_settings;
 		int res = 0;
 
+		settings = fh->jpg_settings;
+
 		dprintk(3,
 			KERN_DEBUG
 			"%s: VIDIOC_S_JPEGCOMP - quality=%d, APPN=%d, APP_len=%d, COM_len=%d\n",
@@ -4142,8 +4152,7 @@
 			down(&zr->resource_lock);
 
 			if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG) {
-				struct zoran_jpg_settings settings =
-				    fh->jpg_settings;
+				settings = fh->jpg_settings;
 
 				/* we actually need to set 'real' parameters now */
 				if ((fmt->fmt.pix.height * 2) >
@@ -4539,14 +4548,14 @@
 			     j < fh->jpg_buffers.buffer_size / PAGE_SIZE;
 			     j++) {
 				fraglen =
-				    (fh->jpg_buffers.buffer[i].
-				     frag_tab[2 * j + 1] & ~1) << 1;
+				    (le32_to_cpu(fh->jpg_buffers.buffer[i].
+				     frag_tab[2 * j + 1]) & ~1) << 1;
 				todo = size;
 				if (todo > fraglen)
 					todo = fraglen;
 				pos =
-				    (unsigned long) fh->jpg_buffers.
-				    buffer[i].frag_tab[2 * j];
+				    le32_to_cpu((unsigned long) fh->jpg_buffers.
+				    buffer[i].frag_tab[2 * j]);
 				/* should just be pos on i386 */
 				page = virt_to_phys(bus_to_virt(pos))
 								>> PAGE_SHIFT;
@@ -4563,8 +4572,8 @@
 				start += todo;
 				if (size == 0)
 					break;
-				if (fh->jpg_buffers.buffer[i].
-				    frag_tab[2 * j + 1] & 1)
+				if (le32_to_cpu(fh->jpg_buffers.buffer[i].
+				    frag_tab[2 * j + 1]) & 1)
 					break;	/* was last fragment */
 			}
 			fh->jpg_buffers.buffer[i].map = map;
@@ -4689,3 +4698,4 @@
 	.release = &zoran_vdev_release,
 	.minor = -1
 };
+
diff -Nru a/drivers/media/video/zr36016.c b/drivers/media/video/zr36016.c
--- a/drivers/media/video/zr36016.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/media/video/zr36016.c	2005-03-01 23:38:57 -08:00
@@ -61,7 +61,7 @@
 /* debugging is available via module parameter */
 
 static int debug = 0;
-MODULE_PARM(debug, "i");
+module_param(debug, int, 0);
 MODULE_PARM_DESC(debug, "Debug level (0-4)");
 
 #define dprintk(num, format, args...) \
diff -Nru a/drivers/media/video/zr36050.c b/drivers/media/video/zr36050.c
--- a/drivers/media/video/zr36050.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/media/video/zr36050.c	2005-03-01 23:38:58 -08:00
@@ -58,7 +58,7 @@
 /* debugging is available via module parameter */
 
 static int debug = 0;
-MODULE_PARM(debug, "i");
+module_param(debug, int, 0);
 MODULE_PARM_DESC(debug, "Debug level (0-4)");
 
 #define dprintk(num, format, args...) \
@@ -325,32 +325,6 @@
 	0xF9, 0xFA
 };
 
-static const char zr36050_app[0x40] = {
-	0xff, 0xe0,		//Marker: APP0
-	0x00, 0x3e,		//Length: 60+2
-	' ', 'A', 'V', 'I', '1', 0, 0, 0,	// 'AVI' field
-	0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0
-};
-
-static const char zr36050_com[0x40] = {
-	0xff, 0xfe,		//Marker: COM
-	0x00, 0x3e,		//Length: 60+2
-	' ', 'C', 'O', 'M', 0, 0, 0, 0,	// 'COM' field
-	0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0
-};
-
 /* jpeg baseline setup, this is just fixed in this driver (YUV pictures) */
 #define NO_OF_COMPONENTS          0x3	//Y,U,V
 #define BASELINE_PRECISION        0x8	//MCU size (?)
@@ -499,10 +473,18 @@
 				      sizeof(zr36050_dqt), zr36050_dqt);
 		sum += zr36050_pushit(ptr, ZR050_DHT_IDX,
 				      sizeof(zr36050_dht), zr36050_dht);
-		sum += zr36050_pushit(ptr, ZR050_APP_IDX,
-				      sizeof(zr36050_app), zr36050_app);
-		sum += zr36050_pushit(ptr, ZR050_COM_IDX,
-				      sizeof(zr36050_com), zr36050_com);
+		zr36050_write(ptr, ZR050_APP_IDX, 0xff);
+		zr36050_write(ptr, ZR050_APP_IDX + 1, 0xe0 + ptr->app.appn);
+		zr36050_write(ptr, ZR050_APP_IDX + 2, 0x00);
+		zr36050_write(ptr, ZR050_APP_IDX + 3, ptr->app.len + 2);
+		sum += zr36050_pushit(ptr, ZR050_APP_IDX + 4, 60,
+				      ptr->app.data) + 4;
+		zr36050_write(ptr, ZR050_COM_IDX, 0xff);
+		zr36050_write(ptr, ZR050_COM_IDX + 1, 0xfe);
+		zr36050_write(ptr, ZR050_COM_IDX + 2, 0x00);
+		zr36050_write(ptr, ZR050_COM_IDX + 3, ptr->com.len + 2);
+		sum += zr36050_pushit(ptr, ZR050_COM_IDX + 4, 60,
+				      ptr->com.data) + 4;
 
 		/* do the internal huffman table preload */
 		zr36050_write(ptr, ZR050_MARKERS_EN, ZR050_ME_DHTI);
@@ -553,8 +535,9 @@
 
 		/* this headers seem to deliver "valid AVI" jpeg frames */
 		zr36050_write(ptr, ZR050_MARKERS_EN,
-			      ZR050_ME_APP | ZR050_ME_DQT | ZR050_ME_DHT |
-			      ZR050_ME_COM);
+			      ZR050_ME_DQT | ZR050_ME_DHT |
+			      ((ptr->app.len > 0) ? ZR050_ME_APP : 0) |
+			      ((ptr->com.len > 0) ? ZR050_ME_COM : 0));
 	} else {
 		dprintk(2, "%s: EXPANSION SETUP\n", ptr->name);
 
@@ -733,6 +716,47 @@
 			return -EFAULT;
 		ptr->scalefact = *ival;
 		break;
+
+	case CODEC_G_JPEG_APP_DATA: {	/* get appn marker data */
+		struct jpeg_app_marker *app = data;
+
+		if (size != sizeof(struct jpeg_app_marker))
+			return -EFAULT;
+
+		*app = ptr->app;
+		break;
+	}
+
+	case CODEC_S_JPEG_APP_DATA: {	 /* set appn marker data */
+		struct jpeg_app_marker *app = data;
+
+		if (size != sizeof(struct jpeg_app_marker))
+			return -EFAULT;
+
+		ptr->app = *app;
+		break;
+	}
+
+	case CODEC_G_JPEG_COM_DATA: {	/* get comment marker data */
+		struct jpeg_com_marker *com = data;
+
+		if (size != sizeof(struct jpeg_com_marker))
+			return -EFAULT;
+
+		*com = ptr->com;
+		break;
+	}
+
+	case CODEC_S_JPEG_COM_DATA: {	/* set comment marker data */
+		struct jpeg_com_marker *com = data;
+
+		if (size != sizeof(struct jpeg_com_marker))
+			return -EFAULT;
+
+		ptr->com = *com;
+		break;
+	}
+
 	default:
 		return -EINVAL;
 	}
@@ -821,6 +845,12 @@
 	ptr->max_block_vol = 240;
 	ptr->scalefact = 0x100;
 	ptr->dri = 1;
+
+	/* no app/com marker by default */
+	ptr->app.appn = 0;
+	ptr->app.len = 0;
+	ptr->com.len = 0;
+
 	zr36050_init(ptr);
 
 	dprintk(1, KERN_INFO "%s: codec attached and running\n",
diff -Nru a/drivers/media/video/zr36050.h b/drivers/media/video/zr36050.h
--- a/drivers/media/video/zr36050.h	2005-03-01 23:38:53 -08:00
+++ b/drivers/media/video/zr36050.h	2005-03-01 23:38:53 -08:00
@@ -27,6 +27,8 @@
 #ifndef ZR36050_H
 #define ZR36050_H
 
+#include "videocodec.h"
+
 /* data stored for each zoran jpeg codec chip */
 struct zr36050 {
 	char name[32];
@@ -51,6 +53,10 @@
 	__u8 v_samp_ratio[8];
 	__u16 scalefact;
 	__u16 dri;
+
+	/* com/app marker */
+	struct jpeg_com_marker com;
+	struct jpeg_app_marker app;
 };
 
 /* zr36050 register addresses */
diff -Nru a/drivers/media/video/zr36060.c b/drivers/media/video/zr36060.c
--- a/drivers/media/video/zr36060.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/media/video/zr36060.c	2005-03-01 23:39:07 -08:00
@@ -56,12 +56,12 @@
 static int zr36060_codecs = 0;
 
 static int low_bitrate = 0;
-MODULE_PARM(low_bitrate, "i");
+module_param(low_bitrate, bool, 0);
 MODULE_PARM_DESC(low_bitrate, "Buz compatibility option, halves bitrate");
 
 /* debugging is available via module parameter */
 static int debug = 0;
-MODULE_PARM(debug, "i");
+module_param(debug, int, 0);
 MODULE_PARM_DESC(debug, "Debug level (0-4)");
 
 #define dprintk(num, format, args...) \
@@ -315,32 +315,6 @@
 	0xF9, 0xFA
 };
 
-static const char zr36060_app[0x40] = {
-	0xff, 0xe0,		//Marker: APP0
-	0x00, 0x07,		//Length: 7
-	' ', 'A', 'V', 'I', '1', 0, 0, 0,	// 'AVI' field
-	0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0
-};
-
-static const char zr36060_com[0x40] = {
-	0xff, 0xfe,		//Marker: COM
-	0x00, 0x06,		//Length: 6
-	' ', 'C', 'O', 'M', 0, 0, 0, 0,	// 'COM' field
-	0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0
-};
-
 /* jpeg baseline setup, this is just fixed in this driver (YUV pictures) */
 #define NO_OF_COMPONENTS          0x3	//Y,U,V
 #define BASELINE_PRECISION        0x8	//MCU size (?)
@@ -498,12 +472,18 @@
 		sum +=
 		    zr36060_pushit(ptr, ZR060_DHT_IDX, sizeof(zr36060_dht),
 				   zr36060_dht);
-		sum +=
-		    zr36060_pushit(ptr, ZR060_APP_IDX, sizeof(zr36060_app),
-				   zr36060_app);
-		sum +=
-		    zr36060_pushit(ptr, ZR060_COM_IDX, sizeof(zr36060_com),
-				   zr36060_com);
+		zr36060_write(ptr, ZR060_APP_IDX, 0xff);
+		zr36060_write(ptr, ZR060_APP_IDX + 1, 0xe0 + ptr->app.appn);
+		zr36060_write(ptr, ZR060_APP_IDX + 2, 0x00);
+		zr36060_write(ptr, ZR060_APP_IDX + 3, ptr->app.len + 2);
+		sum += zr36060_pushit(ptr, ZR060_APP_IDX + 4, 60,
+				      ptr->app.data) + 4;
+		zr36060_write(ptr, ZR060_COM_IDX, 0xff);
+		zr36060_write(ptr, ZR060_COM_IDX + 1, 0xfe);
+		zr36060_write(ptr, ZR060_COM_IDX + 2, 0x00);
+		zr36060_write(ptr, ZR060_COM_IDX + 3, ptr->com.len + 2);
+		sum += zr36060_pushit(ptr, ZR060_COM_IDX + 4, 60,
+				      ptr->com.data) + 4;
 
 		/* setup misc. data for compression (target code sizes) */
 
@@ -535,8 +515,9 @@
 
 		/* JPEG markers to be included in the compressed stream */
 		zr36060_write(ptr, ZR060_MER,
-			      ZR060_MER_App | ZR060_MER_Com | ZR060_MER_DQT
-			      | ZR060_MER_DHT);
+			      ZR060_MER_DQT | ZR060_MER_DHT |
+			      ((ptr->com.len > 0) ? ZR060_MER_Com : 0) |
+			      ((ptr->app.len > 0) ? ZR060_MER_App : 0));
 
 		/* Setup the Video Frontend */
 		/* Limit pixel range to 16..235 as per CCIR-601 */
@@ -841,6 +822,47 @@
 			return -EFAULT;
 		ptr->scalefact = *ival;
 		break;
+
+	case CODEC_G_JPEG_APP_DATA: {	/* get appn marker data */
+		struct jpeg_app_marker *app = data;
+
+		if (size != sizeof(struct jpeg_app_marker))
+			return -EFAULT;
+
+		*app = ptr->app;
+		break;
+	}
+
+	case CODEC_S_JPEG_APP_DATA: {	/* set appn marker data */
+		struct jpeg_app_marker *app = data;
+
+		if (size != sizeof(struct jpeg_app_marker))
+			return -EFAULT;
+
+		ptr->app = *app;
+		break;
+	}
+
+	case CODEC_G_JPEG_COM_DATA: {	/* get comment marker data */
+		struct jpeg_com_marker *com = data;
+
+		if (size != sizeof(struct jpeg_com_marker))
+			return -EFAULT;
+
+		*com = ptr->com;
+		break;
+	}
+
+	case CODEC_S_JPEG_COM_DATA: {	/* set comment marker data */
+		struct jpeg_com_marker *com = data;
+
+		if (size != sizeof(struct jpeg_com_marker))
+			return -EFAULT;
+
+		ptr->com = *com;
+		break;
+	}
+
 	default:
 		return -EINVAL;
 	}
@@ -930,6 +952,12 @@
 	ptr->max_block_vol = 240;	/* CHECKME, was 120 is 240 */
 	ptr->scalefact = 0x100;
 	ptr->dri = 1;		/* CHECKME, was 8 is 1 */
+
+	/* by default, no COM or APP markers - app should set those */
+	ptr->com.len = 0;
+	ptr->app.appn = 0;
+	ptr->app.len = 0;
+
 	zr36060_init(ptr);
 
 	dprintk(1, KERN_INFO "%s: codec attached and running\n",
diff -Nru a/drivers/media/video/zr36060.h b/drivers/media/video/zr36060.h
--- a/drivers/media/video/zr36060.h	2005-03-01 23:38:53 -08:00
+++ b/drivers/media/video/zr36060.h	2005-03-01 23:38:53 -08:00
@@ -27,6 +27,8 @@
 #ifndef ZR36060_H
 #define ZR36060_H
 
+#include "videocodec.h"
+
 /* data stored for each zoran jpeg codec chip */
 struct zr36060 {
 	char name[32];
@@ -51,6 +53,10 @@
 	__u8 v_samp_ratio[8];
 	__u16 scalefact;
 	__u16 dri;
+
+	/* app/com marker data */
+	struct jpeg_app_marker app;
+	struct jpeg_com_marker com;
 };
 
 /* ZR36060 register addresses */
diff -Nru a/drivers/media/video/zr36120.c b/drivers/media/video/zr36120.c
--- a/drivers/media/video/zr36120.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/media/video/zr36120.c	2005-03-01 23:38:57 -08:00
@@ -338,7 +338,7 @@
 {
 	u32 stat,estat;
 	int count = 0;
-	struct zoran *ztv = (struct zoran *)dev_id;
+	struct zoran *ztv = dev_id;
 
 	UNUSED(irq); UNUSED(regs);
 	for (;;) {
@@ -775,7 +775,7 @@
 	memset(ztv->fbuffer,0,ZORAN_MAX_FBUFSIZE);
 
 	if (!ztv->overinfo.overlay)
-		ztv->overinfo.overlay = (void*)kmalloc(1024*1024/8, GFP_KERNEL);
+		ztv->overinfo.overlay = kmalloc(1024*1024/8, GFP_KERNEL);
 	if (!ztv->overinfo.overlay) {
 		/* could not get an overlay buffer, bail out */
 		bfree(ztv->fbuffer, ZORAN_MAX_FBUFSIZE);
@@ -1500,7 +1500,7 @@
 static
 int vbi_open(struct video_device *dev, int flags)
 {
-	struct zoran *ztv = (struct zoran*)dev->priv;
+	struct zoran *ztv = dev->priv;
 	struct vidinfo* item;
 
 	DEBUG(printk(CARD_DEBUG "vbi_open(dev,%d)\n",CARD,flags));
@@ -1549,7 +1549,7 @@
 static
 void vbi_close(struct video_device *dev)
 {
-	struct zoran *ztv = (struct zoran*)dev->priv;
+	struct zoran *ztv = dev->priv;
 	struct vidinfo* item;
 
 	DEBUG(printk(CARD_DEBUG "vbi_close(dev)\n",CARD));
@@ -1585,7 +1585,7 @@
 static
 long vbi_read(struct video_device* dev, char* buf, unsigned long count, int nonblock)
 {
-	struct zoran *ztv = (struct zoran*)dev->priv;
+	struct zoran *ztv = dev->priv;
 	unsigned long max;
 	struct vidinfo* unused = 0;
 	struct vidinfo* done = 0;
@@ -1740,7 +1740,7 @@
 static
 unsigned int vbi_poll(struct video_device *dev, struct file *file, poll_table *wait)
 {
-	struct zoran *ztv = (struct zoran*)dev->priv;
+	struct zoran *ztv = dev->priv;
 	struct vidinfo* item;
 	unsigned int mask = 0;
 
@@ -1761,7 +1761,7 @@
 static
 int vbi_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
 {
-	struct zoran* ztv = (struct zoran*)dev->priv;
+	struct zoran* ztv = dev->priv;
 
 	switch (cmd) {
 	 case VIDIOCGVBIFMT:
@@ -1861,7 +1861,7 @@
 		DEBUG(printk(KERN_DEBUG "zoran: mapped-memory at 0x%p\n",ztv->zoran_mem));
 
 		result = request_irq(dev->irq, zoran_irq,
-			SA_SHIRQ|SA_INTERRUPT,"zoran",(void *)ztv);
+			SA_SHIRQ|SA_INTERRUPT,"zoran", ztv);
 		if (result==-EINVAL)
 		{
 			iounmap(ztv->zoran_mem);
@@ -1950,7 +1950,7 @@
 	ztv->tuner_type = 0;
 	ztv->running = 0;
 	ztv->users = 0;
-	ztv->lock = RW_LOCK_UNLOCKED;
+	rwlock_init(&ztv->lock);
 	ztv->workqueue = 0;
 	ztv->fieldnr = 0;
 	ztv->lastfieldnr = 0;
diff -Nru a/drivers/message/fusion/mptlan.c b/drivers/message/fusion/mptlan.c
--- a/drivers/message/fusion/mptlan.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/message/fusion/mptlan.c	2005-03-01 23:38:57 -08:00
@@ -179,7 +179,7 @@
 
 #ifdef QLOGIC_NAA_WORKAROUND
 static struct NAA_Hosed *mpt_bad_naa = NULL;
-rwlock_t bad_naa_lock = RW_LOCK_UNLOCKED;
+DEFINE_RWLOCK(bad_naa_lock);
 #endif
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -1401,8 +1401,8 @@
 			priv->max_buckets_out));
 
 	priv->bucketthresh = priv->max_buckets_out * 2 / 3;
-	priv->txfidx_lock = SPIN_LOCK_UNLOCKED;
-	priv->rxfidx_lock = SPIN_LOCK_UNLOCKED;
+	spin_lock_init(&priv->txfidx_lock);
+	spin_lock_init(&priv->rxfidx_lock);
 
 	memset(&priv->stats, 0, sizeof(priv->stats));
 
diff -Nru a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
--- a/drivers/message/fusion/mptscsih.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/message/fusion/mptscsih.c	2005-03-01 23:39:18 -08:00
@@ -241,7 +241,7 @@
 /*
  * Domain Validation task structure
  */
-static spinlock_t dvtaskQ_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(dvtaskQ_lock);
 static int dvtaskQ_active = 0;
 static int dvtaskQ_release = 0;
 static struct work_struct	mptscsih_dvTask;
diff -Nru a/drivers/message/i2o/device.c b/drivers/message/i2o/device.c
--- a/drivers/message/i2o/device.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/message/i2o/device.c	2005-03-01 23:38:58 -08:00
@@ -66,10 +66,11 @@
 
 	rc = i2o_device_issue_claim(dev, I2O_CMD_UTIL_CLAIM, I2O_CLAIM_PRIMARY);
 	if (!rc)
-		pr_debug("claim of device %d succeded\n", dev->lct_data.tid);
+		pr_debug("i2o: claim of device %d succeded\n",
+			 dev->lct_data.tid);
 	else
-		pr_debug("claim of device %d failed %d\n", dev->lct_data.tid,
-			 rc);
+		pr_debug("i2o: claim of device %d failed %d\n",
+			 dev->lct_data.tid, rc);
 
 	up(&dev->lock);
 
@@ -111,10 +112,10 @@
 	}
 
 	if (!rc)
-		pr_debug("claim release of device %d succeded\n",
+		pr_debug("i2o: claim release of device %d succeded\n",
 			 dev->lct_data.tid);
 	else
-		pr_debug("claim release of device %d failed %d\n",
+		pr_debug("i2o: claim release of device %d failed %d\n",
 			 dev->lct_data.tid, rc);
 
 	up(&dev->lock);
@@ -133,7 +134,7 @@
 {
 	struct i2o_device *i2o_dev = to_i2o_device(dev);
 
-	pr_debug("Release I2O device %s\n", dev->bus_id);
+	pr_debug("i2o: device %s released\n", dev->bus_id);
 
 	kfree(i2o_dev);
 };
@@ -241,7 +242,7 @@
 
 	i2o_driver_notify_device_add_all(dev);
 
-	pr_debug("I2O device %s added\n", dev->device.bus_id);
+	pr_debug("i2o: device %s added\n", dev->device.bus_id);
 
 	return dev;
 };
@@ -304,7 +305,8 @@
 
 	max = (lct->table_size - 3) / 9;
 
-	pr_debug("LCT has %d entries (LCT size: %d)\n", max, lct->table_size);
+	pr_debug("%s: LCT has %d entries (LCT size: %d)\n", c->name, max,
+		 lct->table_size);
 
 	/* remove devices, which are not in the LCT anymore */
 	list_for_each_entry_safe(dev, tmp, &c->devices, list) {
diff -Nru a/drivers/message/i2o/driver.c b/drivers/message/i2o/driver.c
--- a/drivers/message/i2o/driver.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/message/i2o/driver.c	2005-03-01 23:39:17 -08:00
@@ -76,7 +76,7 @@
 	int rc = 0;
 	unsigned long flags;
 
-	pr_debug("Register driver %s\n", drv->name);
+	pr_debug("i2o: Register driver %s\n", drv->name);
 
 	if (drv->event) {
 		drv->event_queue = create_workqueue(drv->name);
@@ -85,7 +85,8 @@
 			       "for driver %s\n", drv->name);
 			return -EFAULT;
 		}
-		pr_debug("Event queue initialized for driver %s\n", drv->name);
+		pr_debug("i2o: Event queue initialized for driver %s\n",
+			 drv->name);
 	} else
 		drv->event_queue = NULL;
 
@@ -107,7 +108,8 @@
 
 	spin_unlock_irqrestore(&i2o_drivers_lock, flags);
 
-	pr_debug("driver %s gets context id %d\n", drv->name, drv->context);
+	pr_debug("i2o: driver %s gets context id %d\n", drv->name,
+		 drv->context);
 
 	list_for_each_entry(c, &i2o_controllers, list) {
 		struct i2o_device *i2o_dev;
@@ -137,7 +139,7 @@
 	struct i2o_controller *c;
 	unsigned long flags;
 
-	pr_debug("unregister driver %s\n", drv->name);
+	pr_debug("i2o: unregister driver %s\n", drv->name);
 
 	driver_unregister(&drv->driver);
 
@@ -157,7 +159,7 @@
 	if (drv->event_queue) {
 		destroy_workqueue(drv->event_queue);
 		drv->event_queue = NULL;
-		pr_debug("event queue removed for %s\n", drv->name);
+		pr_debug("i2o: event queue removed for %s\n", drv->name);
 	}
 };
 
@@ -186,8 +188,8 @@
 		spin_unlock(&i2o_drivers_lock);
 
 		if (unlikely(!drv)) {
-			printk(KERN_WARNING "i2o: Spurious reply to unknown "
-			       "driver %d\n", context);
+			printk(KERN_WARNING "%s: Spurious reply to unknown "
+			       "driver %d\n", c->name, context);
 			return -EIO;
 		}
 
@@ -233,8 +235,8 @@
 				 " defined!\n", c->name, drv->name);
 		return -EIO;
 	} else
-		printk(KERN_WARNING "i2o: Spurious reply to unknown driver "
-		       "%d\n", readl(&msg->u.s.icntxt));
+		printk(KERN_WARNING "%s: Spurious reply to unknown driver "
+		       "%d\n", c->name, readl(&msg->u.s.icntxt));
 	return -EIO;
 }
 
@@ -336,7 +338,7 @@
 		       ">=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);
+	printk(KERN_INFO "i2o: max drivers = %d\n", i2o_max_drivers);
 
 	i2o_drivers =
 	    kmalloc(i2o_max_drivers * sizeof(*i2o_drivers), GFP_KERNEL);
diff -Nru a/drivers/message/i2o/exec-osm.c b/drivers/message/i2o/exec-osm.c
--- a/drivers/message/i2o/exec-osm.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/message/i2o/exec-osm.c	2005-03-01 23:39:07 -08:00
@@ -31,6 +31,8 @@
 #include <linux/i2o.h>
 #include <linux/delay.h>
 
+#define OSM_NAME "exec-osm"
+
 struct i2o_driver i2o_exec_driver;
 
 static int i2o_exec_lct_notify(struct i2o_controller *c, u32 change_ind);
@@ -236,7 +238,8 @@
 
 				dev = &c->pdev->dev;
 
-				pr_debug("timedout reply received!\n");
+				pr_debug("%s: timedout reply received!\n",
+					 c->name);
 				i2o_dma_free(dev, &wait->dma);
 				i2o_exec_wait_free(wait);
 				rc = -1;
@@ -250,7 +253,7 @@
 
 	spin_unlock(&lock);
 
-	pr_debug("i2o: Bogus reply in POST WAIT (tr-context: %08x)!\n",
+	pr_debug("%s: Bogus reply in POST WAIT (tr-context: %08x)!\n", c->name,
 		 context);
 
 	return -1;
@@ -378,8 +381,8 @@
  */
 static void i2o_exec_event(struct i2o_event *evt)
 {
-	printk(KERN_INFO "Event received from device: %d\n",
-	       evt->i2o_dev->lct_data.tid);
+	osm_info("Event received from device: %d\n",
+		 evt->i2o_dev->lct_data.tid);
 	kfree(evt);
 };
 
@@ -468,7 +471,7 @@
 
 /* Exec OSM driver struct */
 struct i2o_driver i2o_exec_driver = {
-	.name = "exec-osm",
+	.name = OSM_NAME,
 	.reply = i2o_exec_reply,
 	.event = i2o_exec_event,
 	.classes = i2o_exec_class_id,
diff -Nru a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c
--- a/drivers/message/i2o/i2o_block.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/message/i2o/i2o_block.c	2005-03-01 23:39:08 -08:00
@@ -61,6 +61,10 @@
 
 #include "i2o_block.h"
 
+#define OSM_NAME	"block-osm"
+#define OSM_VERSION	"$Rev$"
+#define OSM_DESCRIPTION	"I2O Block Device OSM"
+
 static struct i2o_driver i2o_block_driver;
 
 /* global Block OSM request mempool */
@@ -100,8 +104,7 @@
 	struct i2o_device *i2o_dev = to_i2o_device(dev);
 	struct i2o_block_device *i2o_blk_dev = dev_get_drvdata(dev);
 
-	printk(KERN_INFO "block-osm: Device removed %s\n",
-	       i2o_blk_dev->gd->disk_name);
+	osm_info("Device removed %s\n", i2o_blk_dev->gd->disk_name);
 
 	i2o_event_register(i2o_dev, &i2o_block_driver, 0, 0);
 
@@ -137,7 +140,7 @@
 	writel(I2O_CMD_BLOCK_CFLUSH << 24 | HOST_TID << 12 | dev->lct_data.tid,
 	       &msg->u.head[1]);
 	writel(60 << 16, &msg->body[0]);
-	pr_debug("Flushing...\n");
+	osm_debug("Flushing...\n");
 
 	return i2o_msg_post_wait(dev->iop, m, 60);
 };
@@ -166,7 +169,7 @@
 	       &msg->u.head[1]);
 	writel(-1, &msg->body[0]);
 	writel(0, &msg->body[1]);
-	pr_debug("Mounting...\n");
+	osm_debug("Mounting...\n");
 
 	return i2o_msg_post_wait(dev->iop, m, 2);
 };
@@ -194,7 +197,7 @@
 	writel(I2O_CMD_BLOCK_MLOCK << 24 | HOST_TID << 12 | dev->lct_data.tid,
 	       &msg->u.head[1]);
 	writel(-1, &msg->body[0]);
-	pr_debug("Locking...\n");
+	osm_debug("Locking...\n");
 
 	return i2o_msg_post_wait(dev->iop, m, 2);
 };
@@ -222,7 +225,7 @@
 	writel(I2O_CMD_BLOCK_MUNLOCK << 24 | HOST_TID << 12 | dev->lct_data.tid,
 	       &msg->u.head[1]);
 	writel(media_id, &msg->body[0]);
-	pr_debug("Unlocking...\n");
+	osm_debug("Unlocking...\n");
 
 	return i2o_msg_post_wait(dev->iop, m, 2);
 };
@@ -252,7 +255,7 @@
 	writel(I2O_CMD_BLOCK_POWER << 24 | HOST_TID << 12 | i2o_dev->lct_data.
 	       tid, &msg->u.head[1]);
 	writel(op << 24, &msg->body[0]);
-	pr_debug("Power...\n");
+	osm_debug("Power...\n");
 
 	rc = i2o_msg_post_wait(c, m, 60);
 	if (!rc)
@@ -350,7 +353,7 @@
 
 	/* request is already processed by us, so return */
 	if (req->flags & REQ_SPECIAL) {
-		pr_debug("REQ_SPECIAL already set!\n");
+		osm_debug("REQ_SPECIAL already set!\n");
 		req->flags |= REQ_DONTPREP;
 		return BLKPREP_OK;
 	}
@@ -359,7 +362,7 @@
 	if (!req->special) {
 		ireq = i2o_block_request_alloc();
 		if (unlikely(IS_ERR(ireq))) {
-			pr_debug("unable to allocate i2o_block_request!\n");
+			osm_debug("unable to allocate i2o_block_request!\n");
 			return BLKPREP_DEFER;
 		}
 
@@ -435,7 +438,7 @@
 
 		req = i2o_cntxt_list_get(c, le32_to_cpu(pmsg->u.s.tcntxt));
 		if (unlikely(!req)) {
-			printk(KERN_ERR "block-osm: NULL reply received!\n");
+			osm_err("NULL reply received!\n");
 			return -1;
 		}
 
@@ -465,7 +468,7 @@
 
 	req = i2o_cntxt_list_get(c, le32_to_cpu(msg->u.s.tcntxt));
 	if (unlikely(!req)) {
-		printk(KERN_ERR "block-osm: NULL reply received!\n");
+		osm_err("NULL reply received!\n");
 		return -1;
 	}
 
@@ -482,8 +485,7 @@
 		 * goes kaput...
 		 */
 		req->errors++;
-		printk(KERN_WARNING
-		       "I2O Block: Data transfer to deleted device!\n");
+		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]))) ;
@@ -537,8 +539,8 @@
 		 *      Don't stick a supertrak100 into cache aggressive modes
 		 */
 
-		printk(KERN_ERR "/dev/%s error: %s", dev->gd->disk_name,
-		       bsa_errors[le32_to_cpu(msg->body[0]) & 0xffff]);
+		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);
@@ -563,14 +565,14 @@
 		i2o_block_sglist_free(ireq);
 		i2o_block_request_free(ireq);
 	} else
-		printk(KERN_ERR "i2o_block: still remaining chunks\n");
+		osm_err("still remaining chunks\n");
 
 	return 1;
 };
 
 static void i2o_block_event(struct i2o_event *evt)
 {
-	printk(KERN_INFO "block-osm: event received\n");
+	osm_info("block-osm: event received\n");
 };
 
 /*
@@ -648,7 +650,7 @@
 
 	i2o_block_device_lock(dev->i2o_dev, -1);
 
-	pr_debug("Ready.\n");
+	osm_debug("Ready.\n");
 
 	return 0;
 };
@@ -877,11 +879,11 @@
 		 (unsigned long)&msg->u.head[0]) >> 2) | SGL_OFFSET_8,
 	       &msg->u.head[0]);
 
-	i2o_msg_post(c, m);
-
 	list_add_tail(&ireq->queue, &dev->open_queue);
 	dev->open_queue_depth++;
 
+	i2o_msg_post(c, m);
+
 	return 0;
 
       context_remove:
@@ -936,7 +938,7 @@
 			INIT_WORK(&dreq->work, i2o_block_delayed_request_fn,
 				  dreq);
 
-			printk(KERN_INFO "block-osm: transfer error\n");
+			osm_info("transfer error\n");
 			if (!queue_delayed_work(i2o_block_driver.event_queue,
 						&dreq->work,
 						I2O_BLOCK_RETRY_TIME))
@@ -977,8 +979,7 @@
 
 	dev = kmalloc(sizeof(*dev), GFP_KERNEL);
 	if (!dev) {
-		printk(KERN_ERR "block-osm: Insufficient memory to allocate "
-		       "I2O Block disk.\n");
+		osm_err("Insufficient memory to allocate I2O Block disk.\n");
 		rc = -ENOMEM;
 		goto exit;
 	}
@@ -992,8 +993,7 @@
 	/* allocate a gendisk with 16 partitions */
 	gd = alloc_disk(16);
 	if (!gd) {
-		printk(KERN_ERR "block-osm: Insufficient memory to allocate "
-		       "gendisk.\n");
+		osm_err("Insufficient memory to allocate gendisk.\n");
 		rc = -ENOMEM;
 		goto cleanup_dev;
 	}
@@ -1001,8 +1001,7 @@
 	/* initialize the request queue */
 	queue = blk_init_queue(i2o_block_request_fn, &dev->lock);
 	if (!queue) {
-		printk(KERN_ERR "block-osm: Insufficient memory to allocate "
-		       "request queue.\n");
+		osm_err("Insufficient memory to allocate request queue.\n");
 		rc = -ENOMEM;
 		goto cleanup_queue;
 	}
@@ -1054,24 +1053,21 @@
 
 	/* skip devices which are used by IOP */
 	if (i2o_dev->lct_data.user_tid != 0xfff) {
-		pr_debug("skipping used device %03x\n", i2o_dev->lct_data.tid);
+		osm_debug("skipping used device %03x\n", i2o_dev->lct_data.tid);
 		return -ENODEV;
 	}
 
-	printk(KERN_INFO "block-osm: New device detected (TID: %03x)\n",
-	       i2o_dev->lct_data.tid);
+	osm_info("New device detected (TID: %03x)\n", i2o_dev->lct_data.tid);
 
 	if (i2o_device_claim(i2o_dev)) {
-		printk(KERN_WARNING "block-osm: Unable to claim device. "
-		       "Installation aborted\n");
+		osm_warn("Unable to claim device. Installation aborted\n");
 		rc = -EFAULT;
 		goto exit;
 	}
 
 	i2o_blk_dev = i2o_block_device_alloc();
 	if (IS_ERR(i2o_blk_dev)) {
-		printk(KERN_ERR "block-osm: could not alloc a new I2O block"
-		       "device");
+		osm_err("could not alloc a new I2O block device");
 		rc = PTR_ERR(i2o_blk_dev);
 		goto claim_release;
 	}
@@ -1106,9 +1102,9 @@
 
 	blk_queue_max_hw_segments(queue, segments);
 
-	pr_debug("max sectors:   %d\n", I2O_MAX_SECTORS);
-	pr_debug("phys segments: %d\n", I2O_MAX_SEGMENTS);
-	pr_debug("hw segments:   %d\n", 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);
 
 	/*
 	 *      Ask for the current media data. If that isn't supported
@@ -1119,7 +1115,7 @@
 		i2o_parm_field_get(i2o_dev, 0x0000, 3, &blocksize, 4);
 		i2o_parm_field_get(i2o_dev, 0x0000, 4, &size, 8);
 	}
-	pr_debug("blocksize:     %d\n", blocksize);
+	osm_debug("blocksize = %d\n", blocksize);
 
 	if (i2o_parm_field_get(i2o_dev, 0x0000, 2, &power, 2))
 		power = 0;
@@ -1145,7 +1141,7 @@
 
 /* Block OSM driver struct */
 static struct i2o_driver i2o_block_driver = {
-	.name = "block-osm",
+	.name = OSM_NAME,
 	.event = i2o_block_event,
 	.reply = i2o_block_reply,
 	.classes = i2o_block_class_id,
@@ -1168,8 +1164,7 @@
 	int rc;
 	int size;
 
-	printk(KERN_INFO "I2O Block Storage OSM v0.9\n");
-	printk(KERN_INFO "   (c) Copyright 1999-2001 Red Hat Software.\n");
+	printk(KERN_INFO OSM_DESCRIPTION " v" OSM_VERSION "\n");
 
 	/* Allocate request mempool and slab */
 	size = sizeof(struct i2o_block_request);
@@ -1177,7 +1172,7 @@
 						  SLAB_HWCACHE_ALIGN, NULL,
 						  NULL);
 	if (!i2o_blk_req_pool.slab) {
-		printk(KERN_ERR "block-osm: can't init request slab\n");
+		osm_err("can't init request slab\n");
 		rc = -ENOMEM;
 		goto exit;
 	}
@@ -1187,7 +1182,7 @@
 					       mempool_free_slab,
 					       i2o_blk_req_pool.slab);
 	if (!i2o_blk_req_pool.pool) {
-		printk(KERN_ERR "block-osm: can't init request mempool\n");
+		osm_err("can't init request mempool\n");
 		rc = -ENOMEM;
 		goto free_slab;
 	}
@@ -1195,18 +1190,17 @@
 	/* Register the block device interfaces */
 	rc = register_blkdev(I2O_MAJOR, "i2o_block");
 	if (rc) {
-		printk(KERN_ERR "block-osm: unable to register block device\n");
+		osm_err("unable to register block device\n");
 		goto free_mempool;
 	}
 #ifdef MODULE
-	printk(KERN_INFO "block-osm: registered device at major %d\n",
-	       I2O_MAJOR);
+	osm_info("registered device at major %d\n", I2O_MAJOR);
 #endif
 
 	/* Register Block OSM into I2O core */
 	rc = i2o_driver_register(&i2o_block_driver);
 	if (rc) {
-		printk(KERN_ERR "block-osm: Could not register Block driver\n");
+		osm_err("Could not register Block driver\n");
 		goto unregister_blkdev;
 	}
 
@@ -1245,8 +1239,9 @@
 };
 
 MODULE_AUTHOR("Red Hat");
-MODULE_DESCRIPTION("I2O Block Device OSM");
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION(OSM_DESCRIPTION);
+MODULE_VERSION(OSM_VERSION);
 
 module_init(i2o_block_init);
 module_exit(i2o_block_exit);
diff -Nru a/drivers/message/i2o/i2o_config.c b/drivers/message/i2o/i2o_config.c
--- a/drivers/message/i2o/i2o_config.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/message/i2o/i2o_config.c	2005-03-01 23:39:16 -08:00
@@ -48,6 +48,10 @@
 #include <asm/uaccess.h>
 #include <asm/io.h>
 
+#define OSM_NAME	"config-osm"
+#define OSM_VERSION	"$Rev$"
+#define OSM_DESCRIPTION	"I2O Configuration OSM"
+
 extern int i2o_parm_issue(struct i2o_device *, int, void *, int, void *, int);
 
 static spinlock_t i2o_config_lock;
@@ -79,7 +83,7 @@
  */
 
 static struct i2o_driver i2o_config_driver = {
-	.name = "Config-OSM"
+	.name = OSM_NAME
 };
 
 static int i2o_cfg_getiops(unsigned long arg)
@@ -296,7 +300,7 @@
 	writel(0xD0000000 | fragsize, &msg->body[3]);
 	writel(buffer.phys, &msg->body[4]);
 
-//      printk(KERN_INFO "i2o_config: swdl frag %d/%d (size %d)\n", curfrag, maxfrag, fragsize);
+	osm_debug("swdl frag %d/%d (size %d)\n", curfrag, maxfrag, fragsize);
 	status = i2o_msg_post_wait_mem(c, m, 60, &buffer);
 
 	if (status != -ETIMEDOUT)
@@ -305,9 +309,7 @@
 	if (status != I2O_POST_WAIT_OK) {
 		// it fails if you try and send frags out of order
 		// and for some yet unknown reasons too
-		printk(KERN_INFO
-		       "i2o_config: swdl failed, DetailedStatus = %d\n",
-		       status);
+		osm_info("swdl failed, DetailedStatus = %d\n", status);
 		return status;
 	}
 
@@ -370,16 +372,14 @@
 	writel(0xD0000000 | fragsize, &msg->body[3]);
 	writel(buffer.phys, &msg->body[4]);
 
-//      printk(KERN_INFO "i2o_config: swul frag %d/%d (size %d)\n", curfrag, maxfrag, fragsize);
+	osm_debug("swul frag %d/%d (size %d)\n", curfrag, maxfrag, fragsize);
 	status = i2o_msg_post_wait_mem(c, m, 60, &buffer);
 
 	if (status != I2O_POST_WAIT_OK) {
 		if (status != -ETIMEDOUT)
 			i2o_dma_free(&c->pdev->dev, &buffer);
 
-		printk(KERN_INFO
-		       "i2o_config: swul failed, DetailedStatus = %d\n",
-		       status);
+		osm_info("swul failed, DetailedStatus = %d\n", status);
 		return status;
 	}
 
@@ -432,9 +432,7 @@
 	token = i2o_msg_post_wait(c, m, 10);
 
 	if (token != I2O_POST_WAIT_OK) {
-		printk(KERN_INFO
-		       "i2o_config: swdel failed, DetailedStatus = %d\n",
-		       token);
+		osm_info("swdel failed, DetailedStatus = %d\n", token);
 		return -ETIMEDOUT;
 	}
 
@@ -466,8 +464,8 @@
 	token = i2o_msg_post_wait(c, m, 10);
 
 	if (token != I2O_POST_WAIT_OK) {
-		printk(KERN_INFO "Can't validate configuration, ErrorStatus = "
-		       "%d\n", token);
+		osm_info("Can't validate configuration, ErrorStatus = %d\n",
+			 token);
 		return -ETIMEDOUT;
 	}
 
@@ -569,7 +567,7 @@
 
 	c = i2o_find_iop(iop);
 	if (!c) {
-		pr_debug("controller %d not found\n", iop);
+		osm_debug("controller %d not found\n", iop);
 		return -ENXIO;
 	}
 
@@ -578,13 +576,13 @@
 	sb = c->status_block.virt;
 
 	if (get_user(size, &user_msg[0])) {
-		printk(KERN_WARNING "unable to get size!\n");
+		osm_warn("unable to get size!\n");
 		return -EFAULT;
 	}
 	size = size >> 16;
 
 	if (size > sb->inbound_frame_size) {
-		pr_debug("size of message > inbound_frame_size");
+		osm_warn("size of message > inbound_frame_size");
 		return -EFAULT;
 	}
 
@@ -594,7 +592,7 @@
 
 	/* Copy in the user's I2O command */
 	if (copy_from_user(msg, user_msg, size)) {
-		printk(KERN_WARNING "unable to copy user message\n");
+		osm_warn("unable to copy user message\n");
 		return -EFAULT;
 	}
 	i2o_dump_message(msg);
@@ -692,7 +690,6 @@
 		// TODO 64bit fix
 		struct sg_simple_element *sg;
 		int sg_size;
-		printk(KERN_INFO "sg_offset\n");
 
 		// re-acquire the original message to handle correctly the sg copy operation
 		memset(&msg, 0, MSG_FRAME_SIZE * 4);
@@ -737,7 +734,6 @@
 	/* Copy back the reply to user space */
 	if (reply_size) {
 		// we wrote our own values for context - now restore the user supplied ones
-		printk(KERN_INFO "reply_size\n");
 		if (copy_from_user(reply + 2, user_msg + 2, sizeof(u32) * 2)) {
 			printk(KERN_WARNING
 			       "%s: Could not copy message context FROM user\n",
@@ -753,7 +749,6 @@
 
       cleanup:
 	kfree(reply);
-	printk(KERN_INFO "rcode: %d\n", rcode);
 	return rcode;
 }
 
@@ -786,7 +781,7 @@
 
 	c = i2o_find_iop(iop);
 	if (!c) {
-		pr_debug("controller %d not found\n", iop);
+		osm_warn("controller %d not found\n", iop);
 		return -ENXIO;
 	}
 
@@ -799,7 +794,7 @@
 	size = size >> 16;
 
 	if (size > sb->inbound_frame_size) {
-		pr_debug("size of message > inbound_frame_size");
+		osm_warn("size of message > inbound_frame_size");
 		return -EFAULT;
 	}
 
@@ -902,7 +897,6 @@
 		// TODO 64bit fix
 		struct sg_simple_element *sg;
 		int sg_size;
-		printk(KERN_INFO "sg_offset\n");
 
 		// re-acquire the original message to handle correctly the sg copy operation
 		memset(&msg, 0, MSG_FRAME_SIZE * 4);
@@ -947,7 +941,6 @@
 	/* Copy back the reply to user space */
 	if (reply_size) {
 		// we wrote our own values for context - now restore the user supplied ones
-		printk(KERN_INFO "reply_size\n");
 		if (copy_from_user(reply + 2, user_msg + 2, sizeof(u32) * 2)) {
 			printk(KERN_WARNING
 			       "%s: Could not copy message context FROM user\n",
@@ -1027,7 +1020,7 @@
 #endif
 
 	default:
-		pr_debug("i2o_config: unknown ioctl called!\n");
+		osm_debug("unknown ioctl called!\n");
 		ret = -EINVAL;
 	}
 
@@ -1125,20 +1118,19 @@
 
 static int __init i2o_config_init(void)
 {
-	printk(KERN_INFO "I2O configuration manager v 0.04.\n");
-	printk(KERN_INFO "  (C) Copyright 1999 Red Hat Software\n");
+	printk(KERN_INFO OSM_DESCRIPTION " v" OSM_VERSION "\n");
 
 	spin_lock_init(&i2o_config_lock);
 
 	if (misc_register(&i2o_miscdev) < 0) {
-		printk(KERN_ERR "i2o_config: can't register device.\n");
+		osm_err("can't register device.\n");
 		return -EBUSY;
 	}
 	/*
 	 *      Install our handler
 	 */
 	if (i2o_driver_register(&i2o_config_driver)) {
-		printk(KERN_ERR "i2o_config: handler register failed.\n");
+		osm_err("handler register failed.\n");
 		misc_deregister(&i2o_miscdev);
 		return -EBUSY;
 	}
@@ -1160,8 +1152,9 @@
 }
 
 MODULE_AUTHOR("Red Hat Software");
-MODULE_DESCRIPTION("I2O Configuration");
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION(OSM_DESCRIPTION);
+MODULE_VERSION(OSM_VERSION);
 
 module_init(i2o_config_init);
 module_exit(i2o_config_exit);
diff -Nru a/drivers/message/i2o/i2o_proc.c b/drivers/message/i2o/i2o_proc.c
--- a/drivers/message/i2o/i2o_proc.c	2005-03-01 23:39:06 -08:00
+++ b/drivers/message/i2o/i2o_proc.c	2005-03-01 23:39:06 -08:00
@@ -27,6 +27,10 @@
  *			Changes for new I2O API
  */
 
+#define OSM_NAME	"proc-osm"
+#define OSM_VERSION	"$Rev$"
+#define OSM_DESCRIPTION	"I2O ProcFS OSM"
+
 #define I2O_MAX_MODULES 4
 // FIXME!
 #define FMT_U64_HEX "0x%08x%08x"
@@ -60,7 +64,7 @@
 
 /* proc OSM driver struct */
 static struct i2o_driver i2o_proc_driver = {
-	.name = "proc-osm",
+	.name = OSM_NAME,
 };
 
 static int print_serial_number(struct seq_file *seq, u8 * serialno, int max_len)
@@ -1938,11 +1942,11 @@
 
 	sprintf(buff, "%03x", dev->lct_data.tid);
 
-	pr_debug("Adding device /proc/i2o/iop%d/%s\n", dev->iop->unit, buff);
+	osm_debug("adding device /proc/i2o/%s/%s\n", dev->iop->name, buff);
 
 	devdir = proc_mkdir(buff, dir);
 	if (!devdir) {
-		printk(KERN_WARNING "i2o: Could not allocate procdir!\n");
+		osm_warn("Could not allocate procdir!\n");
 		return;
 	}
 
@@ -1978,13 +1982,10 @@
 {
 	struct proc_dir_entry *iopdir;
 	struct i2o_device *dev;
-	char buff[10];
 
-	snprintf(buff, 10, "iop%d", c->unit);
+	osm_debug("adding IOP /proc/i2o/%s\n", c->name);
 
-	pr_debug("Adding IOP /proc/i2o/%s\n", buff);
-
-	iopdir = proc_mkdir(buff, dir);
+	iopdir = proc_mkdir(c->name, dir);
 	if (!iopdir)
 		return -1;
 
@@ -2018,7 +2019,7 @@
 			i2o_proc_subdir_remove(pe);
 			remove_proc_entry(pe->name, dir);
 		}
-		pr_debug("Removing IOP /proc/i2o/iop%d\n", c->unit);
+		osm_debug("removing IOP /proc/i2o/%s\n", c->name);
 		pe = tmp;
 	}
 }
@@ -2076,6 +2077,8 @@
 {
 	int rc;
 
+	printk(KERN_INFO OSM_DESCRIPTION " v" OSM_VERSION "\n");
+
 	rc = i2o_driver_register(&i2o_proc_driver);
 	if (rc)
 		return rc;
@@ -2101,8 +2104,9 @@
 };
 
 MODULE_AUTHOR("Deepak Saxena");
-MODULE_DESCRIPTION("I2O procfs Handler");
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION(OSM_DESCRIPTION);
+MODULE_VERSION(OSM_VERSION);
 
 module_init(i2o_proc_init);
 module_exit(i2o_proc_exit);
diff -Nru a/drivers/message/i2o/i2o_scsi.c b/drivers/message/i2o/i2o_scsi.c
--- a/drivers/message/i2o/i2o_scsi.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/message/i2o/i2o_scsi.c	2005-03-01 23:39:09 -08:00
@@ -65,7 +65,9 @@
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_cmnd.h>
 
-#define VERSION_STRING        "Version 0.1.2"
+#define OSM_NAME	"scsi-osm"
+#define OSM_VERSION	"$Rev$"
+#define OSM_DESCRIPTION	"I2O SCSI Peripheral OSM"
 
 static struct i2o_driver i2o_scsi_driver;
 
@@ -106,8 +108,7 @@
 	}
 
 	if (!max_channel) {
-		printk(KERN_WARNING "scsi-osm: no channels found on %s\n",
-		       c->name);
+		osm_warn("no channels found on %s\n", c->name);
 		return ERR_PTR(-EFAULT);
 	}
 
@@ -116,7 +117,7 @@
 
 	scsi_host = scsi_host_alloc(&i2o_scsi_host_template, size);
 	if (!scsi_host) {
-		printk(KERN_WARNING "scsi-osm: Could not allocate SCSI host\n");
+		osm_warn("Could not allocate SCSI host\n");
 		return ERR_PTR(-ENOMEM);
 	}
 
@@ -221,24 +222,23 @@
 		return -EFAULT;
 
 	if (id >= scsi_host->max_id) {
-		printk(KERN_WARNING "scsi-osm: SCSI device id (%d) >= max_id "
-		       "of I2O host (%d)", id, scsi_host->max_id);
+		osm_warn("SCSI device id (%d) >= max_id of I2O host (%d)", id,
+			 scsi_host->max_id);
 		return -EFAULT;
 	}
 
 	if (i2o_parm_field_get(i2o_dev, 0, 4, &lun, 8) < 0)
 		return -EFAULT;
 	if (lun >= scsi_host->max_lun) {
-		printk(KERN_WARNING "scsi-osm: SCSI device id (%d) >= max_lun "
-		       "of I2O host (%d)", (unsigned int)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) {
-		printk(KERN_WARNING "scsi-osm: can not find parent of device "
-		       "%03x\n", i2o_dev->lct_data.tid);
+		osm_warn("can not find parent of device %03x\n",
+			 i2o_dev->lct_data.tid);
 		return -EFAULT;
 	}
 
@@ -247,8 +247,8 @@
 			channel = i;
 
 	if (channel == -1) {
-		printk(KERN_WARNING "scsi-osm: can not find channel of device "
-		       "%03x\n", i2o_dev->lct_data.tid);
+		osm_warn("can not find channel of device %03x\n",
+			 i2o_dev->lct_data.tid);
 		return -EFAULT;
 	}
 
@@ -256,13 +256,13 @@
 	    __scsi_add_device(i2o_shost->scsi_host, channel, id, lun, i2o_dev);
 
 	if (!scsi_dev) {
-		printk(KERN_WARNING "scsi-osm: can not add SCSI device "
-		       "%03x\n", i2o_dev->lct_data.tid);
+		osm_warn("can not add SCSI device %03x\n",
+			 i2o_dev->lct_data.tid);
 		return -EFAULT;
 	}
 
-	pr_debug("Added new SCSI device %03x (cannel: %d, id: %d, lun: %d)\n",
-		 i2o_dev->lct_data.tid, channel, id, (unsigned int)lun);
+	osm_debug("added new SCSI device %03x (cannel: %d, id: %d, lun: %d)\n",
+		  i2o_dev->lct_data.tid, channel, id, (unsigned int)lun);
 
 	return 0;
 };
@@ -307,24 +307,24 @@
 
 		pmsg = i2o_msg_in_to_virt(c, pm);
 
-		printk(KERN_ERR "IOP fail.\n");
-		printk(KERN_ERR "From %d To %d Cmd %d.\n",
-		       (msg->u.head[1] >> 12) & 0xFFF,
-		       msg->u.head[1] & 0xFFF, msg->u.head[1] >> 24);
-		printk(KERN_ERR "Failure Code %d.\n", msg->body[0] >> 24);
+		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))
-			printk(KERN_ERR "Format error.\n");
+			osm_err("Format error.\n");
 		if (msg->body[0] & (1 << 17))
-			printk(KERN_ERR "Path error.\n");
+			osm_err("Path error.\n");
 		if (msg->body[0] & (1 << 18))
-			printk(KERN_ERR "Path State.\n");
+			osm_err("Path State.\n");
 		if (msg->body[0] & (1 << 18))
 		{
-			printk(KERN_ERR "Congestion.\n");
+			osm_err("Congestion.\n");
 			err = DID_BUS_BUSY;
 		}
 
-		printk(KERN_DEBUG "Failing message is %p.\n", pmsg);
+		osm_debug("Failing message is %p.\n", pmsg);
 
 		cmd = i2o_cntxt_list_get(c, readl(&pmsg->u.s.tcntxt));
 		if (!cmd)
@@ -353,13 +353,12 @@
 
 	if (!cmd) {
 		if (st)
-			printk(KERN_WARNING "SCSI abort: %08X",
-			       le32_to_cpu(msg->body[0]));
-		printk(KERN_INFO "SCSI abort completed.\n");
+			osm_warn("SCSI abort: %08X", le32_to_cpu(msg->body[0]));
+		osm_info("SCSI abort completed.\n");
 		return -EFAULT;
 	}
 
-	pr_debug("Completed %ld\n", cmd->serial_number);
+	osm_debug("Completed %ld\n", cmd->serial_number);
 
 	if (st) {
 		u32 count, error;
@@ -370,13 +369,13 @@
 			count = le32_to_cpu(msg->body[1]);
 			if (count < cmd->underflow) {
 				int i;
-				printk(KERN_ERR "SCSI: underflow 0x%08X 0x%08X"
-				       "\n", count, cmd->underflow);
-				printk(KERN_DEBUG "Cmd: ");
+
+				osm_err("SCSI underflow 0x%08X 0x%08X\n", count,
+					cmd->underflow);
+				osm_debug("Cmd: ");
 				for (i = 0; i < 15; i++)
-					printk(KERN_DEBUG "%02X ",
-					       cmd->cmnd[i]);
-				printk(KERN_DEBUG ".\n");
+					pr_debug("%02X ", cmd->cmnd[i]);
+				pr_debug(".\n");
 				cmd->result = (DID_ERROR << 16);
 			}
 			break;
@@ -384,7 +383,7 @@
 		default:
 			error = le32_to_cpu(msg->body[0]);
 
-			printk(KERN_ERR "scsi-osm: SCSI error %08x\n", error);
+			osm_err("SCSI error %08x\n", error);
 
 			if ((error & 0xff) == 0x02 /*CHECK_CONDITION */ ) {
 				int i;
@@ -394,8 +393,8 @@
 				memcpy(cmd->sense_buffer, (void *)&msg->body[3],
 				       len);
 				for (i = 0; i <= len; i++)
-					printk(KERN_INFO "%02x\n",
-					       cmd->sense_buffer[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 */
@@ -467,21 +466,20 @@
 
 	i2o_shost = i2o_scsi_host_alloc(c);
 	if (IS_ERR(i2o_shost)) {
-		printk(KERN_ERR "scsi-osm: Could not initialize"
-		       " SCSI host\n");
+		osm_err("Could not initialize SCSI host\n");
 		return;
 	}
 
 	rc = scsi_add_host(i2o_shost->scsi_host, &c->device);
 	if (rc) {
-		printk(KERN_ERR "scsi-osm: Could not add SCSI " "host\n");
+		osm_err("Could not add SCSI host\n");
 		scsi_host_put(i2o_shost->scsi_host);
 		return;
 	}
 
 	c->driver_data[i2o_scsi_driver.context] = i2o_shost;
 
-	pr_debug("new I2O SCSI host added\n");
+	osm_debug("new I2O SCSI host added\n");
 };
 
 /**
@@ -503,12 +501,12 @@
 
 	scsi_remove_host(i2o_shost->scsi_host);
 	scsi_host_put(i2o_shost->scsi_host);
-	pr_debug("I2O SCSI host removed\n");
+	pr_info("I2O SCSI host removed\n");
 };
 
 /* SCSI OSM driver struct */
 static struct i2o_driver i2o_scsi_driver = {
-	.name = "scsi-osm",
+	.name = OSM_NAME,
 	.reply = i2o_scsi_reply,
 	.classes = i2o_scsi_class_id,
 	.notify_controller_add = i2o_scsi_notify_controller_add,
@@ -561,7 +559,7 @@
 	SCpnt->scsi_done = done;
 
 	if (unlikely(!i2o_dev)) {
-		printk(KERN_WARNING "scsi-osm: no I2O device in request\n");
+		osm_warn("no I2O device in request\n");
 		SCpnt->result = DID_NO_CONNECT << 16;
 		done(SCpnt);
 		return 0;
@@ -569,8 +567,8 @@
 
 	tid = i2o_dev->lct_data.tid;
 
-	pr_debug("qcmd: Tid = %03x\n", tid);
-	pr_debug("Real scsi messages.\n");
+	osm_debug("qcmd: Tid = %03x\n", tid);
+	osm_debug("Real scsi messages.\n");
 
 	/*
 	 *      Obtain an I2O message. If there are none free then
@@ -702,7 +700,7 @@
 	/* Queue the message */
 	i2o_msg_post(c, m);
 
-	pr_debug("Issued %ld\n", SCpnt->serial_number);
+	osm_debug("Issued %ld\n", SCpnt->serial_number);
 
 	return 0;
 };
@@ -727,7 +725,7 @@
 	int tid;
 	int status = FAILED;
 
-	printk(KERN_WARNING "i2o_scsi: Aborting command block.\n");
+	osm_warn("Aborting command block.\n");
 
 	i2o_dev = SCpnt->device->hostdata;
 	c = i2o_dev->iop;
@@ -777,8 +775,8 @@
 }
 
 static struct scsi_host_template i2o_scsi_host_template = {
-	.proc_name = "SCSI-OSM",
-	.name = "I2O SCSI Peripheral OSM",
+	.proc_name = OSM_NAME,
+	.name = OSM_DESCRIPTION,
 	.info = i2o_scsi_info,
 	.queuecommand = i2o_scsi_queuecommand,
 	.eh_abort_handler = i2o_scsi_abort,
@@ -789,15 +787,6 @@
 	.use_clustering = ENABLE_CLUSTERING,
 };
 
-/*
-int
-i2o_scsi_queuecommand(struct scsi_cmnd * cmd, void (*done) (struct scsi_cmnd *))
-{
-	printk(KERN_INFO "queuecommand\n");
-	return SCSI_MLQUEUE_HOST_BUSY;
-};
-*/
-
 /**
  *	i2o_scsi_init - SCSI OSM initialization function
  *
@@ -809,12 +798,12 @@
 {
 	int rc;
 
-	printk(KERN_INFO "I2O SCSI Peripheral OSM\n");
+	printk(KERN_INFO OSM_DESCRIPTION " v" OSM_VERSION "\n");
 
 	/* Register SCSI OSM into I2O core */
 	rc = i2o_driver_register(&i2o_scsi_driver);
 	if (rc) {
-		printk(KERN_ERR "scsi-osm: Could not register SCSI driver\n");
+		osm_err("Could not register SCSI driver\n");
 		return rc;
 	}
 
@@ -834,6 +823,8 @@
 
 MODULE_AUTHOR("Red Hat Software");
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION(OSM_DESCRIPTION);
+MODULE_VERSION(OSM_VERSION);
 
 module_init(i2o_scsi_init);
 module_exit(i2o_scsi_exit);
diff -Nru a/drivers/message/i2o/iop.c b/drivers/message/i2o/iop.c
--- a/drivers/message/i2o/iop.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/message/i2o/iop.c	2005-03-01 23:38:55 -08:00
@@ -29,6 +29,9 @@
 #include <linux/i2o.h>
 #include <linux/delay.h>
 
+#define OSM_VERSION	"$Rev$"
+#define OSM_DESCRIPTION	"I2O subsystem"
+
 /* global I2O controller list */
 LIST_HEAD(i2o_controllers);
 
@@ -126,12 +129,13 @@
 	unsigned long flags;
 
 	if (!ptr)
-		printk(KERN_ERR "NULL pointer found!\n");
+		printk(KERN_ERR "%s: couldn't add NULL pointer to context list!"
+		       "\n", c->name);
 
 	entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
 	if (!entry) {
-		printk(KERN_ERR "i2o: Could not allocate memory for context "
-		       "list element\n");
+		printk(KERN_ERR "%s: Could not allocate memory for context "
+		       "list element\n", c->name);
 		return 0;
 	}
 
@@ -150,7 +154,7 @@
 
 	spin_unlock_irqrestore(&c->context_list_lock, flags);
 
-	pr_debug("Add context to list %p -> %d\n", ptr, context);
+	pr_debug("%s: Add context to list %p -> %d\n", c->name, ptr, context);
 
 	return entry->context;
 };
@@ -182,10 +186,11 @@
 	spin_unlock_irqrestore(&c->context_list_lock, flags);
 
 	if (!context)
-		printk(KERN_WARNING "i2o: Could not remove nonexistent ptr "
-		       "%p\n", ptr);
+		printk(KERN_WARNING "%s: Could not remove nonexistent ptr "
+		       "%p\n", c->name, ptr);
 
-	pr_debug("remove ptr from context list %d -> %p\n", context, ptr);
+	pr_debug("%s: remove ptr from context list %d -> %p\n", c->name,
+		 context, ptr);
 
 	return context;
 };
@@ -215,9 +220,11 @@
 	spin_unlock_irqrestore(&c->context_list_lock, flags);
 
 	if (!ptr)
-		printk(KERN_WARNING "i2o: context id %d not found\n", context);
+		printk(KERN_WARNING "%s: context id %d not found\n", c->name,
+		       context);
 
-	pr_debug("get ptr from context list %d -> %p\n", context, ptr);
+	pr_debug("%s: get ptr from context list %d -> %p\n", c->name, context,
+		 ptr);
 
 	return ptr;
 };
@@ -245,10 +252,11 @@
 	spin_unlock_irqrestore(&c->context_list_lock, flags);
 
 	if (!context)
-		printk(KERN_WARNING "i2o: Could not find nonexistent ptr "
-		       "%p\n", ptr);
+		printk(KERN_WARNING "%s: Could not find nonexistent ptr "
+		       "%p\n", c->name, ptr);
 
-	pr_debug("get context id from context list %p -> %d\n", ptr, context);
+	pr_debug("%s: get context id from context list %p -> %d\n", c->name,
+		 ptr, context);
 
 	return context;
 };
@@ -467,7 +475,7 @@
 	i2o_status_block *sb = c->status_block.virt;
 	int rc = 0;
 
-	pr_debug("Resetting controller\n");
+	pr_debug("%s: Resetting controller\n", c->name);
 
 	m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);
 	if (m == I2O_QUEUE_EMPTY)
@@ -494,7 +502,7 @@
 	timeout = jiffies + I2O_TIMEOUT_RESET * HZ;
 	while (!*status) {
 		if (time_after(jiffies, timeout)) {
-			printk(KERN_ERR "IOP reset timeout.\n");
+			printk(KERN_ERR "%s: IOP reset timeout.\n", c->name);
 			rc = -ETIMEDOUT;
 			goto exit;
 		}
@@ -526,7 +534,8 @@
 		m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_RESET);
 		while (m == I2O_QUEUE_EMPTY) {
 			if (time_after(jiffies, timeout)) {
-				printk(KERN_ERR "IOP reset timeout.\n");
+				printk(KERN_ERR "%s: IOP reset timeout.\n",
+				       c->name);
 				rc = -ETIMEDOUT;
 				goto exit;
 			}
@@ -676,14 +685,14 @@
 
 	rc = i2o_status_get(c);
 	if (rc) {
-		printk(KERN_INFO "Unable to obtain status of %s, "
+		printk(KERN_INFO "%s: Unable to obtain status, "
 		       "attempting a reset.\n", c->name);
 		if (i2o_iop_reset(c))
 			return rc;
 	}
 
 	if (sb->i2o_version > I2OVER15) {
-		printk(KERN_ERR "%s: Not running vrs. 1.5. of the I2O "
+		printk(KERN_ERR "%s: Not running version 1.5 of the I2O "
 		       "Specification.\n", c->name);
 		return -ENODEV;
 	}
@@ -697,7 +706,7 @@
 	case ADAPTER_STATE_OPERATIONAL:
 	case ADAPTER_STATE_HOLD:
 	case ADAPTER_STATE_FAILED:
-		pr_debug("already running, trying to reset...\n");
+		pr_debug("%s: already running, trying to reset...\n", c->name);
 		if (i2o_iop_reset(c))
 			return -ENODEV;
 	}
@@ -751,15 +760,16 @@
 		       c->name);
 		root = pci_find_parent_resource(c->pdev, res);
 		if (root == NULL)
-			printk(KERN_WARNING "Can't find parent resource!\n");
+			printk(KERN_WARNING "%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);
+			printk(KERN_INFO "%s: allocated %ld bytes of PCI memory"
+			       " at 0x%08lX.\n", c->name,
+			       1 + res->end - res->start, res->start);
 		}
 	}
 
@@ -773,15 +783,16 @@
 		       c->name);
 		root = pci_find_parent_resource(c->pdev, res);
 		if (root == NULL)
-			printk(KERN_WARNING "Can't find parent resource!\n");
+			printk(KERN_WARNING "%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);
+			printk(KERN_INFO "%s: allocated %ld bytes of PCI I/O at"
+			       " 0x%08lX.\n", c->name,
+			       1 + res->end - res->start, res->start);
 		}
 	}
 
@@ -871,7 +882,7 @@
 {
 	struct i2o_device *dev, *tmp;
 
-	pr_debug("Deleting controller %s\n", c->name);
+	pr_debug("%s: deleting controller\n", c->name);
 
 	i2o_driver_notify_controller_remove_all(c);
 
@@ -1114,7 +1125,7 @@
 
 	c = kmalloc(sizeof(*c), GFP_KERNEL);
 	if (!c) {
-		printk(KERN_ERR "i2o: Insufficient memory to allocate the "
+		printk(KERN_ERR "i2o: Insufficient memory to allocate a I2O "
 		       "controller.\n");
 		return ERR_PTR(-ENOMEM);
 	}
@@ -1162,27 +1173,27 @@
 	       "devices\n", c->name);
 
 	if ((rc = i2o_iop_activate(c))) {
-		printk(KERN_ERR "%s: controller could not activated\n",
+		printk(KERN_ERR "%s: could not activate controller\n",
 		       c->name);
 		i2o_iop_reset(c);
 		return rc;
 	}
 
-	pr_debug("building sys table %s...\n", c->name);
+	pr_debug("%s: building sys table...\n", c->name);
 
 	if ((rc = i2o_systab_build())) {
 		i2o_iop_reset(c);
 		return rc;
 	}
 
-	pr_debug("online controller %s...\n", c->name);
+	pr_debug("%s: online controller...\n", c->name);
 
 	if ((rc = i2o_iop_online(c))) {
 		i2o_iop_reset(c);
 		return rc;
 	}
 
-	pr_debug("getting LCT %s...\n", c->name);
+	pr_debug("%s: getting LCT...\n", c->name);
 
 	if ((rc = i2o_exec_lct_get(c))) {
 		i2o_iop_reset(c);
@@ -1247,7 +1258,7 @@
 {
 	int rc = 0;
 
-	printk(KERN_INFO "I2O Core - (C) Copyright 1999 Red Hat Software\n");
+	printk(KERN_INFO OSM_DESCRIPTION " v" OSM_VERSION "\n");
 
 	rc = i2o_device_init();
 	if (rc)
@@ -1297,8 +1308,9 @@
 module_exit(i2o_iop_exit);
 
 MODULE_AUTHOR("Red Hat Software");
-MODULE_DESCRIPTION("I2O Core");
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION(OSM_DESCRIPTION);
+MODULE_VERSION(OSM_VERSION);
 
 #if BITS_PER_LONG == 64
 EXPORT_SYMBOL(i2o_cntxt_list_add);
diff -Nru a/drivers/message/i2o/pci.c b/drivers/message/i2o/pci.c
--- a/drivers/message/i2o/pci.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/message/i2o/pci.c	2005-03-01 23:39:18 -08:00
@@ -83,7 +83,7 @@
  *	Remove all allocated DMA memory and unmap memory IO regions. If MTRR
  *	is enabled, also remove it again.
  */
-static void __devexit i2o_pci_free(struct i2o_controller *c)
+static void i2o_pci_free(struct i2o_controller *c)
 {
 	struct device *dev;
 
@@ -159,34 +159,36 @@
 	}
 
 	if (i == 6) {
-		printk(KERN_ERR "i2o: I2O controller has no memory regions"
-		       " defined.\n");
+		printk(KERN_ERR "%s: I2O controller has no memory regions"
+		       " defined.\n", c->name);
 		i2o_pci_free(c);
 		return -EINVAL;
 	}
 
 	/* Map the I2O controller */
 	if (c->raptor) {
-		printk(KERN_INFO "i2o: PCI I2O controller\n");
+		printk(KERN_INFO "%s: PCI I2O controller\n", c->name);
 		printk(KERN_INFO "     BAR0 at 0x%08lX size=%ld\n",
 		       (unsigned long)c->base.phys, (unsigned long)c->base.len);
 		printk(KERN_INFO "     BAR1 at 0x%08lX size=%ld\n",
 		       (unsigned long)c->in_queue.phys,
 		       (unsigned long)c->in_queue.len);
 	} else
-		printk(KERN_INFO "i2o: PCI I2O controller at %08lX size=%ld\n",
-		       (unsigned long)c->base.phys, (unsigned long)c->base.len);
+		printk(KERN_INFO "%s: PCI I2O controller at %08lX size=%ld\n",
+		       c->name, (unsigned long)c->base.phys,
+		       (unsigned long)c->base.len);
 
 	c->base.virt = ioremap(c->base.phys, c->base.len);
 	if (!c->base.virt) {
-		printk(KERN_ERR "i2o: Unable to map controller.\n");
+		printk(KERN_ERR "%s: Unable to map controller.\n", c->name);
 		return -ENOMEM;
 	}
 
 	if (c->raptor) {
 		c->in_queue.virt = ioremap(c->in_queue.phys, c->in_queue.len);
 		if (!c->in_queue.virt) {
-			printk(KERN_ERR "i2o: Unable to map controller.\n");
+			printk(KERN_ERR "%s: Unable to map controller.\n",
+			       c->name);
 			i2o_pci_free(c);
 			return -ENOMEM;
 		}
@@ -204,10 +206,10 @@
 	c->mtrr_reg1 = -1;
 
 	if (c->mtrr_reg0 < 0)
-		printk(KERN_WARNING "i2o: could not enable write combining "
-		       "MTRR\n");
+		printk(KERN_WARNING "%s: could not enable write combining "
+		       "MTRR\n", c->name);
 	else
-		printk(KERN_INFO "i2o: using write combining MTRR\n");
+		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
@@ -216,14 +218,14 @@
 	 */
 	if ((pdev->vendor == PCI_VENDOR_ID_INTEL ||
 	     pdev->vendor == PCI_VENDOR_ID_DPT) && !c->raptor) {
-		printk(KERN_INFO "i2o: MTRR workaround for Intel i960 processor"
-		       "\n");
+		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 "i2o_pci: Error in setting "
-			       "MTRR_TYPE_UNCACHABLE\n");
+			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;
@@ -288,7 +290,7 @@
 		if (unlikely(mv == I2O_QUEUE_EMPTY)) {
 			return IRQ_NONE;
 		} else
-			pr_debug("960 bug detected\n");
+			pr_debug("%s: 960 bug detected\n", c->name);
 	}
 
 	while (mv != I2O_QUEUE_EMPTY) {
@@ -303,7 +305,7 @@
 		 *      Ensure this message is seen coherently but cachably by
 		 *      the processor
 		 */
-		dma_sync_single_for_cpu(dev, c->out_queue.phys, MSG_FRAME_SIZE,
+		dma_sync_single_for_cpu(dev, mv, MSG_FRAME_SIZE * 4,
 					PCI_DMA_FROMDEVICE);
 
 		/* dispatch it */
@@ -425,12 +427,14 @@
 	/* Cards that fall apart if you hit them with large I/O loads... */
 	if (pdev->vendor == PCI_VENDOR_ID_NCR && pdev->device == 0x0630) {
 		c->short_req = 1;
-		printk(KERN_INFO "i2o: Symbios FC920 workarounds activated.\n");
+		printk(KERN_INFO "%s: Symbios FC920 workarounds activated.\n",
+		       c->name);
 	}
 
 	if (pdev->subsystem_vendor == PCI_VENDOR_ID_PROMISE) {
 		c->promise = 1;
-		printk(KERN_INFO "i2o: Promise workarounds activated.\n");
+		printk(KERN_INFO "%s: Promise workarounds activated.\n",
+		       c->name);
 	}
 
 	/* Cards that go bananas if you quiesce them before you reset them. */
@@ -441,14 +445,14 @@
 	}
 
 	if ((rc = i2o_pci_alloc(c))) {
-		printk(KERN_ERR "i2o: DMA / IO allocation for I2O controller "
-		       " failed\n");
+		printk(KERN_ERR "%s: DMA / IO allocation for I2O controller "
+		       " failed\n", c->name);
 		goto free_controller;
 	}
 
 	if (i2o_pci_irq_enable(c)) {
-		printk(KERN_ERR "i2o: unable to enable interrupts for I2O "
-		       "controller\n");
+		printk(KERN_ERR "%s: unable to enable interrupts for I2O "
+		       "controller\n", c->name);
 		goto free_pci;
 	}
 
diff -Nru a/drivers/misc/Kconfig b/drivers/misc/Kconfig
--- a/drivers/misc/Kconfig	2005-03-01 23:38:53 -08:00
+++ b/drivers/misc/Kconfig	2005-03-01 23:38:53 -08:00
@@ -22,7 +22,7 @@
 	  
 	  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/ww/eserver/xseries/serverproven> for
 	  information on the specific driver level and support statement
 	  for your IBM server.
 
diff -Nru a/drivers/misc/ibmasm/ibmasmfs.c b/drivers/misc/ibmasm/ibmasmfs.c
--- a/drivers/misc/ibmasm/ibmasmfs.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/misc/ibmasm/ibmasmfs.c	2005-03-01 23:39:08 -08:00
@@ -131,6 +131,7 @@
 	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
 	sb->s_magic = IBMASMFS_MAGIC;
 	sb->s_op = &ibmasmfs_s_ops;
+	sb->s_time_gran = 1;
 
 	root = ibmasmfs_make_inode (sb, S_IFDIR | 0500);
 	if (!root)
diff -Nru a/drivers/misc/ibmasm/module.c b/drivers/misc/ibmasm/module.c
--- a/drivers/misc/ibmasm/module.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/misc/ibmasm/module.c	2005-03-01 23:39:07 -08:00
@@ -57,7 +57,7 @@
 #include "remote.h"
 
 
-static int __init ibmasm_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
+static int __devinit ibmasm_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
 {
 	int err, result = -ENOMEM;
 	struct service_processor *sp;
@@ -107,7 +107,7 @@
 		goto error_remote_queue;
 	}
 
-	sp->lock = SPIN_LOCK_UNLOCKED;
+	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);
@@ -161,7 +161,7 @@
 	return result;
 }
 
-static void __exit ibmasm_remove_one(struct pci_dev *pdev)
+static void __devexit ibmasm_remove_one(struct pci_dev *pdev)
 {
 	struct service_processor *sp = (struct service_processor *)pci_get_drvdata(pdev);
 
diff -Nru a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
--- a/drivers/mmc/Kconfig	2005-03-01 23:39:18 -08:00
+++ b/drivers/mmc/Kconfig	2005-03-01 23:39:18 -08:00
@@ -51,7 +51,7 @@
 
 config MMC_WBSD
 	tristate "Winbond W83L51xD SD/MMC Card Interface support"
-	depends on MMC
+	depends on MMC && ISA
 	help
 	  This selects the Winbond(R) W83L51xD Secure digital and
           Multimedia card Interface.
diff -Nru a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
--- a/drivers/mmc/mmc.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/mmc/mmc.c	2005-03-01 23:39:18 -08:00
@@ -301,14 +301,15 @@
 
 #define UNSTUFF_BITS(resp,start,size)					\
 	({								\
-		const u32 __mask = (1 << (size)) - 1;			\
+		const int __size = size;				\
+		const u32 __mask = (__size < 32 ? 1 << __size : 0) - 1;	\
 		const int __off = 3 - ((start) / 32);			\
 		const int __shft = (start) & 31;			\
 		u32 __res;						\
 									\
 		__res = resp[__off] >> __shft;				\
-		if ((size) + __shft >= 32)				\
-			__res |= resp[__off-1] << (32 - __shft);	\
+		if (__size + __shft > 32)				\
+			__res |= resp[__off-1] << ((32 - __shft) % 32);	\
 		__res & __mask;						\
 	})
 
diff -Nru a/drivers/mmc/mmc_block.c b/drivers/mmc/mmc_block.c
--- a/drivers/mmc/mmc_block.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/mmc/mmc_block.c	2005-03-01 23:39:18 -08:00
@@ -180,7 +180,6 @@
 
 		brq.cmd.arg = req->sector << 9;
 		brq.cmd.flags = MMC_RSP_R1;
-		brq.data.req = req;
 		brq.data.timeout_ns = card->csd.tacc_ns * 10;
 		brq.data.timeout_clks = card->csd.tacc_clks * 10;
 		brq.data.blksz_bits = md->block_bits;
@@ -332,6 +331,18 @@
 		md->disk->private_data = md;
 		md->disk->queue = md->queue.queue;
 		md->disk->driverfs_dev = &card->dev;
+
+		/*
+		 * As discussed on lkml, GENHD_FL_REMOVABLE should:
+		 *
+		 * - be set for removable media with permanent block devices
+		 * - be unset for removable block devices with permanent media
+		 *
+		 * Since MMC block devices clearly fall under the second
+		 * case, we do not set GENHD_FL_REMOVABLE.  Userspace
+		 * should use the block device creation/destruction hotplug
+		 * messages to tell when the card is present.
+		 */
 
 		sprintf(md->disk->disk_name, "mmcblk%d", devidx);
 		sprintf(md->disk->devfs_name, "mmc/blk%d", devidx);
diff -Nru a/drivers/mmc/mmci.c b/drivers/mmc/mmci.c
--- a/drivers/mmc/mmci.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/mmc/mmci.c	2005-03-01 23:39:08 -08:00
@@ -14,14 +14,15 @@
 #include <linux/ioport.h>
 #include <linux/device.h>
 #include <linux/interrupt.h>
-#include <linux/blkdev.h>
 #include <linux/delay.h>
 #include <linux/err.h>
+#include <linux/highmem.h>
 #include <linux/mmc/host.h>
 #include <linux/mmc/protocol.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
+#include <asm/scatterlist.h>
 #include <asm/hardware/amba.h>
 #include <asm/hardware/clock.h>
 #include <asm/mach/mmc.h>
diff -Nru a/drivers/mmc/pxamci.c b/drivers/mmc/pxamci.c
--- a/drivers/mmc/pxamci.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/mmc/pxamci.c	2005-03-01 23:39:07 -08:00
@@ -23,7 +23,6 @@
 #include <linux/device.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
-#include <linux/blkdev.h>
 #include <linux/dma-mapping.h>
 #include <linux/mmc/host.h>
 #include <linux/mmc/protocol.h>
@@ -31,6 +30,7 @@
 #include <asm/dma.h>
 #include <asm/io.h>
 #include <asm/irq.h>
+#include <asm/scatterlist.h>
 #include <asm/sizes.h>
 
 #include <asm/arch/pxa-regs.h>
@@ -52,7 +52,7 @@
 	struct mmc_host		*mmc;
 	spinlock_t		lock;
 	struct resource		*res;
-	void			*base;
+	void __iomem		*base;
 	int			irq;
 	int			dma;
 	unsigned int		clkrt;
diff -Nru a/drivers/mmc/wbsd.c b/drivers/mmc/wbsd.c
--- a/drivers/mmc/wbsd.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/mmc/wbsd.c	2005-03-01 23:39:16 -08:00
@@ -1,11 +1,24 @@
 /*
- *  linux/drivers/mmc/wbsd.c
+ *  linux/drivers/mmc/wbsd.c - Winbond W83L51xD SD/MMC driver
  *
- *  Copyright (C) 2004 Pierre Ossman, All Rights Reserved.
+ *  Copyright (C) 2004-2005 Pierre Ossman, 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.
+ *
+ *
+ * Warning!
+ *
+ * Changes to the FIFO system should be done with extreme care since
+ * the hardware is full of bugs related to the FIFO. Known issues are:
+ *
+ * - FIFO size field in FSR is always zero.
+ *
+ * - FIFO interrupts tend not to work as they should. Interrupts are
+ *   triggered only for full/empty events, not for threshold values.
+ *
+ * - On APIC systems the FIFO empty interrupt is sometimes lost.
  */
 
 #include <linux/config.h>
@@ -16,24 +29,24 @@
 #include <linux/device.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
-#include <linux/blkdev.h>
-
+#include <linux/highmem.h>
 #include <linux/mmc/host.h>
 #include <linux/mmc/protocol.h>
 
 #include <asm/io.h>
 #include <asm/dma.h>
+#include <asm/scatterlist.h>
 
 #include "wbsd.h"
 
 #define DRIVER_NAME "wbsd"
-#define DRIVER_VERSION "1.0"
+#define DRIVER_VERSION "1.1"
 
 #ifdef CONFIG_MMC_DEBUG
 #define DBG(x...) \
 	printk(KERN_DEBUG DRIVER_NAME ": " x)
 #define DBGF(f, x...) \
-	printk(KERN_DEBUG DRIVER_NAME " [%s()]: " f, __func__, ##x)
+	printk(KERN_DEBUG DRIVER_NAME " [%s()]: " f, __func__ , ##x)
 #else
 #define DBG(x...)	do { } while (0)
 #define DBGF(x...)	do { } while (0)
@@ -205,8 +218,6 @@
 
 static inline void wbsd_init_sg(struct wbsd_host* host, struct mmc_data* data)
 {
-	struct request* req = data->req;
-	
 	/*
 	 * Get info. about SG list from data structure.
 	 */
@@ -239,13 +250,14 @@
 
 static inline char* wbsd_kmap_sg(struct wbsd_host* host)
 {
-	return kmap_atomic(host->cur_sg->page, KM_BIO_SRC_IRQ) +
+	host->mapped_sg = kmap_atomic(host->cur_sg->page, KM_BIO_SRC_IRQ) +
 		host->cur_sg->offset;
+	return host->mapped_sg;
 }
 
 static inline void wbsd_kunmap_sg(struct wbsd_host* host)
 {
-	kunmap_atomic(host->cur_sg->page, KM_BIO_SRC_IRQ);
+	kunmap_atomic(host->mapped_sg, KM_BIO_SRC_IRQ);
 }
 
 static inline void wbsd_sg_to_dma(struct wbsd_host* host, struct mmc_data* data)
@@ -272,7 +284,7 @@
 			memcpy(dmabuf, sgbuf, size);
 		else
 			memcpy(dmabuf, sgbuf, sg[i].length);
-		kunmap_atomic(sg[i].page, KM_BIO_SRC_IRQ);
+		kunmap_atomic(sgbuf, KM_BIO_SRC_IRQ);
 		dmabuf += sg[i].length;
 		
 		if (size < sg[i].length)
@@ -318,7 +330,7 @@
 			memcpy(sgbuf, dmabuf, size);
 		else
 			memcpy(sgbuf, dmabuf, sg[i].length);
-		kunmap_atomic(sg[i].page, KM_BIO_SRC_IRQ);
+		kunmap_atomic(sgbuf, KM_BIO_SRC_IRQ);
 		dmabuf += sg[i].length;
 		
 		if (size < sg[i].length)
@@ -400,16 +412,16 @@
 static void wbsd_send_command(struct wbsd_host* host, struct mmc_command* cmd)
 {
 	int i;
-	u8 status, eir, isr;
+	u8 status, isr;
 	
 	DBGF("Sending cmd (%x)\n", cmd->opcode);
 
 	/*
-	 * Disable interrupts as the interrupt routine
-	 * will destroy the contents of ISR.
+	 * Clear accumulated ISR. The interrupt routine
+	 * will fill this one with events that occur during
+	 * transfer.
 	 */
-	eir = inb(host->base + WBSD_EIR);
-	outb(0, host->base + WBSD_EIR);
+	host->isr = 0;
 	
 	/*
 	 * Send the command (CRC calculated by host).
@@ -435,7 +447,7 @@
 		/*
 		 * Read back status.
 		 */
-		isr = inb(host->base + WBSD_ISR);
+		isr = host->isr;
 		
 		/* Card removed? */
 		if (isr & WBSD_INT_CARD)
@@ -456,17 +468,6 @@
 		}
 	}
 
-	/*
-	 * Restore interrupt mask to previous value.
-	 */
-	outb(eir, host->base + WBSD_EIR);
-	
-	/*
-	 * Call the interrupt routine to jump start
-	 * interrupts.
-	 */
-	wbsd_irq(0, host, NULL);
-
 	DBGF("Sent cmd (%x), res %d\n", cmd->opcode, cmd->error);
 }
 
@@ -478,6 +479,7 @@
 {
 	struct mmc_data* data = host->mrq->cmd->data;
 	char* buffer;
+	int i, fsr, fifo;
 	
 	/*
 	 * Handle excessive data.
@@ -491,60 +493,83 @@
 	 * Drain the fifo. This has a tendency to loop longer
 	 * than the FIFO length (usually one block).
 	 */
-	while (!(inb(host->base + WBSD_FSR) & WBSD_FIFO_EMPTY))
+	while (!((fsr = inb(host->base + WBSD_FSR)) & WBSD_FIFO_EMPTY))
 	{
-		*buffer = inb(host->base + WBSD_DFR);
-		buffer++;
-		host->offset++;
-		host->remain--;
-
-		data->bytes_xfered++;
-		
 		/*
-		 * Transfer done?
-		 */
-		if (data->bytes_xfered == host->size)
-		{
-			wbsd_kunmap_sg(host);				
-			return;
-		}
+		 * The size field in the FSR is broken so we have to
+		 * do some guessing.
+		 */		
+		if (fsr & WBSD_FIFO_FULL)
+			fifo = 16;
+		else if (fsr & WBSD_FIFO_FUTHRE)
+			fifo = 8;
+		else
+			fifo = 1;
 		
-		/*
-		 * End of scatter list entry?
-		 */
-		if (host->remain == 0)
+		for (i = 0;i < fifo;i++)
 		{
-			wbsd_kunmap_sg(host);
+			*buffer = inb(host->base + WBSD_DFR);
+			buffer++;
+			host->offset++;
+			host->remain--;
+
+			data->bytes_xfered++;
+			
+			/*
+			 * Transfer done?
+			 */
+			if (data->bytes_xfered == host->size)
+			{
+				wbsd_kunmap_sg(host);				
+				return;
+			}
 			
 			/*
-			 * Get next entry. Check if last.
+			 * End of scatter list entry?
 			 */
-			if (!wbsd_next_sg(host))
+			if (host->remain == 0)
 			{
+				wbsd_kunmap_sg(host);
+				
 				/*
-				 * We should never reach this point.
-				 * It means that we're trying to
-				 * transfer more blocks than can fit
-				 * into the scatter list.
+				 * Get next entry. Check if last.
 				 */
-				BUG_ON(1);
-				
-				host->size = data->bytes_xfered;
+				if (!wbsd_next_sg(host))
+				{
+					/*
+					 * We should never reach this point.
+					 * It means that we're trying to
+					 * transfer more blocks than can fit
+					 * into the scatter list.
+					 */
+					BUG_ON(1);
+					
+					host->size = data->bytes_xfered;
+					
+					return;
+				}
 				
-				return;
+				buffer = wbsd_kmap_sg(host);
 			}
-			
-			buffer = wbsd_kmap_sg(host);
 		}
 	}
 	
 	wbsd_kunmap_sg(host);
+
+	/*
+	 * This is a very dirty hack to solve a
+	 * hardware problem. The chip doesn't trigger
+	 * FIFO threshold interrupts properly.
+	 */
+	if ((host->size - data->bytes_xfered) < 16)
+		tasklet_schedule(&host->fifo_tasklet);
 }
 
 static void wbsd_fill_fifo(struct wbsd_host* host)
 {
 	struct mmc_data* data = host->mrq->cmd->data;
 	char* buffer;
+	int i, fsr, fifo;
 	
 	/*
 	 * Check that we aren't being called after the
@@ -559,50 +584,64 @@
 	 * Fill the fifo. This has a tendency to loop longer
 	 * than the FIFO length (usually one block).
 	 */
-	while (!(inb(host->base + WBSD_FSR) & WBSD_FIFO_FULL))
+	while (!((fsr = inb(host->base + WBSD_FSR)) & WBSD_FIFO_FULL))
 	{
-		outb(*buffer, host->base + WBSD_DFR);
-		buffer++;
-		host->offset++;
-		host->remain--;
-		
-		data->bytes_xfered++;
-		
 		/*
-		 * Transfer done?
-		 */
-		if (data->bytes_xfered == host->size)
-		{
-			wbsd_kunmap_sg(host);
-			return;
-		}
+		 * The size field in the FSR is broken so we have to
+		 * do some guessing.
+		 */		
+		if (fsr & WBSD_FIFO_EMPTY)
+			fifo = 0;
+		else if (fsr & WBSD_FIFO_EMTHRE)
+			fifo = 8;
+		else
+			fifo = 15;
 
-		/*
-		 * End of scatter list entry?
-		 */
-		if (host->remain == 0)
+		for (i = 16;i > fifo;i--)
 		{
-			wbsd_kunmap_sg(host);
+			outb(*buffer, host->base + WBSD_DFR);
+			buffer++;
+			host->offset++;
+			host->remain--;
+			
+			data->bytes_xfered++;
 			
 			/*
-			 * Get next entry. Check if last.
+			 * Transfer done?
+			 */
+			if (data->bytes_xfered == host->size)
+			{
+				wbsd_kunmap_sg(host);
+				return;
+			}
+
+			/*
+			 * End of scatter list entry?
 			 */
-			if (!wbsd_next_sg(host))
+			if (host->remain == 0)
 			{
+				wbsd_kunmap_sg(host);
+				
 				/*
-				 * We should never reach this point.
-				 * It means that we're trying to
-				 * transfer more blocks than can fit
-				 * into the scatter list.
+				 * Get next entry. Check if last.
 				 */
-				BUG_ON(1);
-				
-				host->size = data->bytes_xfered;
+				if (!wbsd_next_sg(host))
+				{
+					/*
+					 * We should never reach this point.
+					 * It means that we're trying to
+					 * transfer more blocks than can fit
+					 * into the scatter list.
+					 */
+					BUG_ON(1);
+					
+					host->size = data->bytes_xfered;
+					
+					return;
+				}
 				
-				return;
+				buffer = wbsd_kmap_sg(host);
 			}
-			
-			buffer = wbsd_kmap_sg(host);
 		}
 	}
 	
@@ -689,9 +728,9 @@
 		disable_dma(host->dma);
 		clear_dma_ff(host->dma);
 		if (data->flags & MMC_DATA_READ)
-			set_dma_mode(host->dma, DMA_MODE_READ);
+			set_dma_mode(host->dma, DMA_MODE_READ & ~0x40);
 		else
-			set_dma_mode(host->dma, DMA_MODE_WRITE);
+			set_dma_mode(host->dma, DMA_MODE_WRITE & ~0x40);
 		set_dma_addr(host->dma, host->dma_addr);
 		set_dma_count(host->dma, host->size);
 
@@ -701,8 +740,7 @@
 		/*
 		 * Enable DMA on the host.
 		 */
-		wbsd_write_index(host, WBSD_IDX_DMA,
-			WBSD_DMA_SINGLE | WBSD_DMA_ENABLE);
+		wbsd_write_index(host, WBSD_IDX_DMA, WBSD_DMA_ENABLE);
 	}
 	else
 	{
@@ -746,6 +784,7 @@
 {
 	unsigned long dmaflags;
 	int count;
+	u8 status;
 	
 	WARN_ON(host->mrq == NULL);
 
@@ -754,6 +793,15 @@
 	 */
 	if (data->stop)
 		wbsd_send_command(host, data->stop);
+
+	/*
+	 * Wait for the controller to leave data
+	 * transfer state.
+	 */
+	do
+	{
+		status = wbsd_read_index(host, WBSD_IDX_STATUS);
+	} while (status & (WBSD_BLOCK_READ | WBSD_BLOCK_WRITE));
 	
 	/*
 	 * DMA transfer?
@@ -851,7 +899,13 @@
 	 * transfered.
 	 */	
 	if (cmd->data && (cmd->error == MMC_ERR_NONE))
-	{		
+	{
+		/*
+		 * Dirty fix for hardware bug.
+		 */
+		if (host->dma == -1)
+			tasklet_schedule(&host->fifo_tasklet);
+
 		spin_unlock_bh(&host->lock);
 
 		return;
@@ -1021,7 +1075,6 @@
 	
 	spin_lock(&host->lock);
 	
-	WARN_ON(!host->mrq);
 	if (!host->mrq)
 		goto end;
 	
@@ -1046,7 +1099,6 @@
 	
 	spin_lock(&host->lock);
 	
-	WARN_ON(!host->mrq);
 	if (!host->mrq)
 		goto end;
 	
@@ -1126,6 +1178,8 @@
 	 */
 	if (isr == 0xff || isr == 0x00)
 		return IRQ_NONE;
+	
+	host->isr |= isr;
 
 	/*
 	 * Schedule tasklets as needed.
@@ -1133,7 +1187,7 @@
 	if (isr & WBSD_INT_CARD)
 		tasklet_schedule(&host->card_tasklet);
 	if (isr & WBSD_INT_FIFO_THRE)
-		tasklet_hi_schedule(&host->fifo_tasklet);
+		tasklet_schedule(&host->fifo_tasklet);
 	if (isr & WBSD_INT_CRC)
 		tasklet_hi_schedule(&host->crc_tasklet);
 	if (isr & WBSD_INT_TIMEOUT)
@@ -1392,8 +1446,8 @@
 	 * Maximum number of segments. Worst case is one sector per segment
 	 * so this will be 64kB/512.
 	 */
-	mmc->max_hw_segs = NR_SG;
-	mmc->max_phys_segs = NR_SG;
+	mmc->max_hw_segs = 128;
+	mmc->max_phys_segs = 128;
 	
 	/*
 	 * Maximum number of sectors in one transfer. Also limited by 64kB
@@ -1590,6 +1644,7 @@
 
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Winbond W83L51xD SD/MMC card interface driver");
+MODULE_VERSION(DRIVER_VERSION);
 
 MODULE_PARM_DESC(io, "I/O base to allocate. Must be 8 byte aligned. (default 0x248)");
 MODULE_PARM_DESC(irq, "IRQ to allocate. (default 6)");
diff -Nru a/drivers/mmc/wbsd.h b/drivers/mmc/wbsd.h
--- a/drivers/mmc/wbsd.h	2005-03-01 23:38:53 -08:00
+++ b/drivers/mmc/wbsd.h	2005-03-01 23:38:53 -08:00
@@ -1,7 +1,7 @@
 /*
- *  linux/drivers/mmc/wbsd.h
+ *  linux/drivers/mmc/wbsd.h - Winbond W83L51xD SD/MMC driver
  *
- *  Copyright (C) 2004 Pierre Ossman, All Rights Reserved.
+ *  Copyright (C) 2004-2005 Pierre Ossman, 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
@@ -119,6 +119,8 @@
 #define WBSD_FIFOEN_FULL	0x10
 #define WBSD_FIFO_THREMASK	0x0F
 
+#define WBSD_BLOCK_READ		0x80
+#define WBSD_BLOCK_WRITE	0x40
 #define WBSD_BUSY		0x20
 #define WBSD_CARDTRAFFIC	0x04
 #define WBSD_SENDCMD		0x02
@@ -132,9 +134,6 @@
 #define WBSD_CRC_FAIL		0x0B /* S101E (01011) */
 
 
-/* 64kB / 512 */
-#define NR_SG			128
-
 struct wbsd_host
 {
 	struct mmc_host*	mmc;		/* MMC structure */
@@ -143,9 +142,11 @@
 
 	struct mmc_request*	mrq;		/* Current request */
 	
-	struct scatterlist	sg[NR_SG];	/* SG list */
+	u8			isr;		/* Accumulated ISR */
+	
 	struct scatterlist*	cur_sg;		/* Current SG entry */
 	unsigned int		num_sg;		/* Number of entries left */
+	void*			mapped_sg;	/* vaddr of mapped sg */
 	
 	unsigned int		offset;		/* Offset into current entry */
 	unsigned int		remain;		/* Data left in curren entry */
diff -Nru a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig
--- a/drivers/mtd/Kconfig	2005-03-01 23:38:53 -08:00
+++ b/drivers/mtd/Kconfig	2005-03-01 23:38:53 -08:00
@@ -1,4 +1,4 @@
-# $Id: Kconfig,v 1.6 2004/08/09 13:19:42 dwmw2 Exp $
+# $Id: Kconfig,v 1.7 2004/11/22 11:33:56 ijc Exp $
 
 menu "Memory Technology Devices (MTD)"
 
@@ -54,8 +54,8 @@
 	depends on MTD_PARTITIONS
 	---help---
 	  RedBoot is a ROM monitor and bootloader which deals with multiple
-	  'images' in flash devices by putting a table in the last erase
-	  block of the device, similar to a partition table, which gives
+	  'images' in flash devices by putting a table one of the erase
+	  blocks on the device, similar to a partition table, which gives
 	  the offsets, lengths and names of all the images stored in the
 	  flash.
 
@@ -68,6 +68,23 @@
 	  SA1100 map driver (CONFIG_MTD_SA1100) has an option for this, for 
 	  example.
 
+config MTD_REDBOOT_DIRECTORY_BLOCK
+	int "Location of RedBoot partition table"
+	depends on MTD_REDBOOT_PARTS
+	default "-1"
+	---help---
+	  This option is the Linux counterpart to the
+	  CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK RedBoot compile time
+	  option.
+
+	  The option specifies which Flash sectors holds the RedBoot
+	  partition table.  A zero or positive value gives an absolete
+	  erase block number. A negative value specifies a number of
+	  sectors before the end of the device.
+	  
+	  For example "2" means block number 2, "-1" means the last
+	  block and "-2" means the penultimate block.
+	  
 config MTD_REDBOOT_PARTS_UNALLOCATED
 	bool "  Include unallocated flash regions"
 	depends on MTD_REDBOOT_PARTS
diff -Nru a/drivers/mtd/chips/Kconfig b/drivers/mtd/chips/Kconfig
--- a/drivers/mtd/chips/Kconfig	2005-03-01 23:38:54 -08:00
+++ b/drivers/mtd/chips/Kconfig	2005-03-01 23:38:54 -08:00
@@ -1,5 +1,5 @@
 # drivers/mtd/chips/Kconfig
-# $Id: Kconfig,v 1.9 2004/07/16 15:32:14 dwmw2 Exp $
+# $Id: Kconfig,v 1.13 2004/12/01 15:49:10 nico Exp $
 
 menu "RAM/ROM/Flash chip drivers"
 	depends on MTD!=n
@@ -7,6 +7,7 @@
 config MTD_CFI
 	tristate "Detect flash chips by Common Flash Interface (CFI) probe"
 	depends on MTD
+	select MTD_GEN_PROBE
 	help
 	  The Common Flash Interface specification was developed by Intel,
 	  AMD and other flash manufactures that provides a universal method
@@ -18,6 +19,7 @@
 config MTD_JEDECPROBE
 	tristate "Detect non-CFI AMD/JEDEC-compatible flash chips"
 	depends on MTD
+	select MTD_GEN_PROBE
 	help
 	  This option enables JEDEC-style probing of flash chips which are not
 	  compatible with the Common Flash Interface, but will use the common
@@ -29,8 +31,6 @@
 
 config MTD_GEN_PROBE
 	tristate
-	default m if MTD_CFI!=y && !MTD_INTELPROBE && MTD_JEDECPROBE!=y && (MTD_CFI=m || MTD_JEDECPROBE=m)
-	default y if MTD_CFI=y || MTD_INTELPROBE || MTD_JEDECPROBE=y
 
 config MTD_CFI_ADV_OPTIONS
 	bool "Flash chip driver advanced configuration options"
@@ -158,6 +158,7 @@
 config MTD_CFI_INTELEXT
 	tristate "Support for Intel/Sharp flash chips"
 	depends on MTD_GEN_PROBE
+	select MTD_CFI_UTIL
 	help
 	  The Common Flash Interface defines a number of different command
 	  sets which a CFI-compliant chip may claim to implement. This code
@@ -167,6 +168,7 @@
 config MTD_CFI_AMDSTD
 	tristate "Support for AMD/Fujitsu flash chips"
 	depends on MTD_GEN_PROBE
+	select MTD_CFI_UTIL
 	help
 	  The Common Flash Interface defines a number of different command
 	  sets which a CFI-compliant chip may claim to implement. This code
@@ -197,6 +199,7 @@
 config MTD_CFI_STAA
 	tristate "Support for ST (Advanced Architecture) flash chips"
 	depends on MTD_GEN_PROBE
+	select MTD_CFI_UTIL
 	help
 	  The Common Flash Interface defines a number of different command
 	  sets which a CFI-compliant chip may claim to implement. This code
@@ -204,8 +207,6 @@
 
 config MTD_CFI_UTIL
 	tristate
-	default y if MTD_CFI_INTELEXT=y || MTD_CFI_AMDSTD=y || MTD_CFI_STAA=y
-	default m if MTD_CFI_INTELEXT=m || MTD_CFI_AMDSTD=m || MTD_CFI_STAA=m
 
 config MTD_RAM
 	tristate "Support for RAM chips in bus mapping"
@@ -271,6 +272,15 @@
 	  only called JEDEC because the JEDEC association
 	  <http://www.jedec.org/> distributes the identification codes for the
 	  chips.
+
+config MTD_XIP
+	bool "XIP aware MTD support"
+	depends on !SMP && MTD_CFI_INTELEXT && EXPERIMENTAL
+	default y if XIP_KERNEL
+	help
+	  This allows MTD support to work with flash memory which is also
+	  used for XIP purposes.  If you're not sure what this is all about
+	  then say N.
 
 endmenu
 
diff -Nru a/drivers/mtd/chips/amd_flash.c b/drivers/mtd/chips/amd_flash.c
--- a/drivers/mtd/chips/amd_flash.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/mtd/chips/amd_flash.c	2005-03-01 23:38:54 -08:00
@@ -3,7 +3,7 @@
  *
  * Author: Jonas Holmberg <jonas.holmberg@axis.com>
  *
- * $Id: amd_flash.c,v 1.25 2004/08/09 13:19:43 dwmw2 Exp $
+ * $Id: amd_flash.c,v 1.26 2004/11/20 12:49:04 dwmw2 Exp $
  *
  * Copyright (c) 2001 Axis Communications AB
  *
@@ -1122,7 +1122,7 @@
 	timeo = jiffies + (HZ * 20);
 
 	spin_unlock_bh(chip->mutex);
-	schedule_timeout(HZ);
+	msleep(1000);
 	spin_lock_bh(chip->mutex);
 	
 	while (flash_is_busy(map, adr, private->interleave)) {
diff -Nru a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c
--- a/drivers/mtd/chips/cfi_cmdset_0001.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c	2005-03-01 23:38:54 -08:00
@@ -4,9 +4,8 @@
  *
  * (C) 2000 Red Hat. GPL'd
  *
- * $Id: cfi_cmdset_0001.c,v 1.160 2004/11/01 06:02:24 nico Exp $
- * (+ suspend fix from v1.162)
- * (+ partition detection fix from v1.163)
+ * $Id: cfi_cmdset_0001.c,v 1.164 2004/11/16 18:29:00 dwmw2 Exp $
+ *
  * 
  * 10/10/2000	Nicolas Pitre <nico@cam.org>
  * 	- completely revamped method functions so they are aware and
@@ -30,12 +29,14 @@
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
+#include <linux/mtd/xip.h>
 #include <linux/mtd/map.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/compatmac.h>
 #include <linux/mtd/cfi.h>
 
 /* #define CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE */
+/* #define CMDSET0001_DISABLE_WRITE_SUSPEND */
 
 // debugging, turns off buffer write mode if set to 1
 #define FORCE_WORD_WRITE 0
@@ -147,6 +148,20 @@
 }
 #endif
 
+#ifdef CMDSET0001_DISABLE_WRITE_SUSPEND
+static void fixup_no_write_suspend(struct mtd_info *mtd, void* param)
+{
+	struct map_info *map = mtd->priv;
+	struct cfi_private *cfi = map->fldrv_priv;
+	struct cfi_pri_intelext *cfip = cfi->cmdset_priv;
+
+	if (cfip && (cfip->FeatureSupport&4)) {
+		cfip->FeatureSupport &= ~4;
+		printk(KERN_WARNING "cfi_cmdset_0001: write suspend disabled\n");
+	}
+}
+#endif
+
 static void fixup_st_m28w320ct(struct mtd_info *mtd, void* param)
 {
 	struct map_info *map = mtd->priv;
@@ -189,6 +204,9 @@
 #ifdef CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE
 	{ CFI_MFR_ANY, CFI_ID_ANY, fixup_intel_strataflash, NULL }, 
 #endif
+#ifdef CMDSET0001_DISABLE_WRITE_SUSPEND
+	{ CFI_MFR_ANY, CFI_ID_ANY, fixup_no_write_suspend, NULL },
+#endif
 #if !FORCE_WORD_WRITE
 	{ CFI_MFR_ANY, CFI_ID_ANY, fixup_use_write_buffers, NULL },
 #endif
@@ -679,6 +697,14 @@
 		chip->state = FL_STATUS;
 		return 0;
 
+	case FL_XIP_WHILE_ERASING:
+		if (mode != FL_READY && mode != FL_POINT &&
+		    (mode != FL_WRITING || !cfip || !(cfip->SuspendCmdSupport&1)))
+			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)
@@ -703,7 +729,7 @@
 	if (chip->priv) {
 		struct flchip_shared *shared = chip->priv;
 		spin_lock(&shared->lock);
-		if (shared->writing == chip) {
+		if (shared->writing == chip && chip->oldstate == FL_READY) {
 			/* We own the ability to write, but we're done */
 			shared->writing = shared->erasing;
 			if (shared->writing && shared->writing != chip) {
@@ -715,17 +741,24 @@
 				put_chip(map, loaner, loaner->start);
 				spin_lock(chip->mutex);
 				spin_unlock(loaner->mutex);
-			} else {
-				if (chip->oldstate != FL_ERASING) {
-					shared->erasing = NULL;
-					if (chip->oldstate != FL_WRITING)
-						shared->writing = NULL;
-				}
-				spin_unlock(&shared->lock);
+				wake_up(&chip->wq);
+				return;
 			}
-		} else {
+			shared->erasing = NULL;
+			shared->writing = NULL;
+		} else if (shared->erasing == chip && shared->writing != chip) {
+			/*
+			 * We own the ability to erase without the ability
+			 * to write, which means the erase was suspended
+			 * and some other partition is currently writing.
+			 * Don't let the switch below mess things up since
+			 * we don't have ownership to resume anything.
+			 */
 			spin_unlock(&shared->lock);
+			wake_up(&chip->wq);
+			return;
 		}
+		spin_unlock(&shared->lock);
 	}
 
 	switch(chip->oldstate) {
@@ -746,6 +779,11 @@
 		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:
 	case FL_JEDEC_QUERY:
@@ -758,6 +796,201 @@
 	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.
+ * 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,
+			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 */
+	preempt_disable();
+	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(0xff), adr);
+		chip->state = FL_READY;
+	}
+	(void) map_read(map, adr);
+	asm volatile (".rep 8; nop; .endr"); /* fill instruction prefetch */
+	local_irq_enable();
+	preempt_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 or write 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_intelext *cfip = cfi->cmdset_priv;
+	map_word status, OK = CMD(0x80);
+	unsigned long suspended, start = xip_currtime();
+	flstate_t oldstate, newstate;
+
+	do {
+		cpu_relax();
+		if (xip_irqpending() && cfip &&
+		    ((chip->state == FL_ERASING && (cfip->FeatureSupport&2)) ||
+		     (chip->state == FL_WRITING && (cfip->FeatureSupport&4))) &&
+		    (cfi_interleave_is_1(cfi) || chip->oldstate == FL_READY)) {
+			/*
+			 * Let's suspend the erase or write 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);
+			map_write(map, CMD(0x70), 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 (oldstate == FL_ERASING) {
+				if (!map_word_bitsset(map, status, CMD(0x40)))
+					break;
+				newstate = FL_XIP_WHILE_ERASING;
+				chip->erase_suspended = 1;
+			} else {
+				if (!map_word_bitsset(map, status, CMD(0x04)))
+					break;
+				newstate = FL_XIP_WHILE_WRITING;
+				chip->write_suspended = 1;
+			}
+			chip->state = newstate;
+			map_write(map, CMD(0xff), adr);
+			(void) map_read(map, adr);
+			asm volatile (".rep 8; nop; .endr");
+			local_irq_enable();
+			preempt_enable();
+			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.
+			 */
+			preempt_disable();
+			while (chip->state != newstate) {
+				DECLARE_WAITQUEUE(wait, current);
+				set_current_state(TASK_UNINTERRUPTIBLE);
+				add_wait_queue(&chip->wq, &wait);
+				preempt_enable();
+				schedule();
+				remove_wait_queue(&chip->wq, &wait);
+				preempt_disable();
+			}
+			/* Disallow XIP again */
+			local_irq_disable();
+
+			/* Resume the write or erase operation */
+			map_write(map, CMD(0xd0), adr);
+			map_write(map, CMD(0x70), 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.
+ */
+#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)
+
+/*
+ * 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 UDELAY(map, chip, adr, usec)  cfi_udelay(usec)
+
+#define XIP_INVAL_CACHED_RANGE(x...)
+
+#endif
+
 static int do_point_onechip (struct map_info *map, struct flchip *chip, loff_t adr, size_t len)
 {
 	unsigned long cmd_addr;
@@ -944,7 +1177,11 @@
 }
 
 #if 0
-static int 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)
+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;
@@ -973,6 +1210,8 @@
 			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;
@@ -985,6 +1224,7 @@
 			count--;
 		}
 
+		xip_enable(map, chip, chip->start);
 		put_chip(map, chip, chip->start);
 		spin_unlock(chip->mutex);
 
@@ -1036,7 +1276,8 @@
 }
 #endif
 
-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;
 	map_word status, status_OK;
@@ -1055,14 +1296,16 @@
 		return ret;
 	}
 
+	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, datum, adr);
 	chip->state = FL_WRITING;
 
 	spin_unlock(chip->mutex);
 	INVALIDATE_CACHED_RANGE(map, adr, map_bankwidth(map));
-	cfi_udelay(chip->word_write_time);
+	UDELAY(map, chip, adr, chip->word_write_time);
 	spin_lock(chip->mutex);
 
 	timeo = jiffies + (HZ/2);
@@ -1089,6 +1332,7 @@
 		/* OK Still waiting */
 		if (time_after(jiffies, timeo)) {
 			chip->state = FL_STATUS;
+			xip_enable(map, chip, adr);
 			printk(KERN_ERR "waiting for chip to be ready timed out in word write\n");
 			ret = -EIO;
 			goto out;
@@ -1097,7 +1341,7 @@
 		/* Latency issues. Drop the lock, wait a while and retry */
 		spin_unlock(chip->mutex);
 		z++;
-		cfi_udelay(1);
+		UDELAY(map, chip, adr, 1);
 		spin_lock(chip->mutex);
 	}
 	if (!z) {
@@ -1119,8 +1363,9 @@
 		map_write(map, CMD(0x70), adr);
 		ret = -EROFS;
 	}
- out:
-	put_chip(map, chip, adr);
+
+	xip_enable(map, chip, adr);
+ out:	put_chip(map, chip, adr);
 	spin_unlock(chip->mutex);
 
 	return ret;
@@ -1210,8 +1455,8 @@
 }
 
 
-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;
 	map_word status, status_OK;
@@ -1232,6 +1477,10 @@
 		return ret;
 	}
 
+	XIP_INVAL_CACHED_RANGE(map, adr, len);
+	ENABLE_VPP(map);
+	xip_disable(map, chip, cmd_adr);
+
 	/* §4.8 of the 28FxxxJ3A datasheet says "Any time SR.4 and/or SR.5 is set
 	   [...], the device will not accept any more Write to Buffer commands". 
 	   So we must check here and reset those bits if they're set. Otherwise
@@ -1240,12 +1489,13 @@
 		map_write(map, CMD(0x70), cmd_adr);
 	status = map_read(map, cmd_adr);
 	if (map_word_bitsset(map, status, CMD(0x30))) {
+		xip_enable(map, chip, cmd_adr);
 		printk(KERN_WARNING "SR.4 or SR.5 bits set in buffer write (status %lx). Clearing.\n", status.x[0]);
+		xip_disable(map, chip, cmd_adr);
 		map_write(map, CMD(0x50), cmd_adr);
 		map_write(map, CMD(0x70), cmd_adr);
 	}
 
-	ENABLE_VPP(map);
 	chip->state = FL_WRITING_TO_BUFFER;
 
 	z = 0;
@@ -1257,7 +1507,7 @@
 			break;
 
 		spin_unlock(chip->mutex);
-		cfi_udelay(1);
+		UDELAY(map, chip, cmd_adr, 1);
 		spin_lock(chip->mutex);
 
 		if (++z > 20) {
@@ -1269,6 +1519,7 @@
 			/* Odd. Clear status bits */
 			map_write(map, CMD(0x50), cmd_adr);
 			map_write(map, CMD(0x70), cmd_adr);
+			xip_enable(map, chip, cmd_adr);
 			printk(KERN_ERR "Chip not ready for buffer write. status = %lx, Xstatus = %lx\n",
 			       status.x[0], Xstatus.x[0]);
 			ret = -EIO;
@@ -1305,7 +1556,7 @@
 
 	spin_unlock(chip->mutex);
 	INVALIDATE_CACHED_RANGE(map, adr, len);
-	cfi_udelay(chip->buffer_write_time);
+	UDELAY(map, chip, cmd_adr, chip->buffer_write_time);
 	spin_lock(chip->mutex);
 
 	timeo = jiffies + (HZ/2);
@@ -1331,6 +1582,7 @@
 		/* OK Still waiting */
 		if (time_after(jiffies, timeo)) {
 			chip->state = FL_STATUS;
+			xip_enable(map, chip, cmd_adr);
 			printk(KERN_ERR "waiting for chip to be ready timed out in bufwrite\n");
 			ret = -EIO;
 			goto out;
@@ -1338,7 +1590,7 @@
 		
 		/* Latency issues. Drop the lock, wait a while and retry */
 		spin_unlock(chip->mutex);
-		cfi_udelay(1);
+		UDELAY(map, chip, cmd_adr, 1);
 		z++;
 		spin_lock(chip->mutex);
 	}
@@ -1362,8 +1614,8 @@
 		ret = -EROFS;
 	}
 
- out:
-	put_chip(map, chip, cmd_adr);
+	xip_enable(map, chip, cmd_adr);
+ out:	put_chip(map, chip, cmd_adr);
 	spin_unlock(chip->mutex);
 	return ret;
 }
@@ -1432,8 +1684,8 @@
 	return 0;
 }
 
-static 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;
 	map_word status, status_OK;
@@ -1455,7 +1707,10 @@
 		return ret;
 	}
 
+	XIP_INVAL_CACHED_RANGE(map, adr, len);
 	ENABLE_VPP(map);
+	xip_disable(map, chip, adr);
+
 	/* Clear the status register first */
 	map_write(map, CMD(0x50), adr);
 
@@ -1467,7 +1722,7 @@
 
 	spin_unlock(chip->mutex);
 	INVALIDATE_CACHED_RANGE(map, adr, len);
-	msleep(chip->erase_time / 2);
+	UDELAY(map, chip, adr, chip->erase_time*1000/2);
 	spin_lock(chip->mutex);
 
 	/* FIXME. Use a timer to check this, and return immediately. */
@@ -1505,6 +1760,7 @@
 			/* Clear status bits */
 			map_write(map, CMD(0x50), adr);
 			map_write(map, CMD(0x70), adr);
+			xip_enable(map, chip, adr);
 			printk(KERN_ERR "waiting for erase at %08lx to complete timed out. status = %lx, Xstatus = %lx.\n",
 			       adr, status.x[0], Xstatus.x[0]);
 			ret = -EIO;
@@ -1513,8 +1769,7 @@
 		
 		/* Latency issues. Drop the lock, wait a while and retry */
 		spin_unlock(chip->mutex);
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(1);
+		UDELAY(map, chip, adr, 1000000/HZ);
 		spin_lock(chip->mutex);
 	}
 
@@ -1530,6 +1785,7 @@
 		/* 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))) {
@@ -1565,6 +1821,7 @@
 			ret = -EIO;
 		}
 	} else {
+		xip_enable(map, chip, adr);
 		ret = 0;
 	}
 
@@ -1632,15 +1889,19 @@
 }
 
 #ifdef DEBUG_LOCK_BITS
-static int do_printlockstatus_oneblock(struct map_info *map, struct flchip *chip,
-				       unsigned long adr, int len, void *thunk)
+static int __xipram do_printlockstatus_oneblock(struct map_info *map,
+						struct flchip *chip,
+						unsigned long adr,
+						int len, void *thunk)
 {
 	struct cfi_private *cfi = map->fldrv_priv;
 	int status, ofs_factor = cfi->interleave * cfi->device_type;
 
+	xip_disable(map, chip, adr+(2*ofs_factor));
 	cfi_send_gen_cmd(0x90, 0x55, 0, map, cfi, cfi->device_type, NULL);
 	chip->state = FL_JEDEC_QUERY;
 	status = cfi_read_query(map, adr+(2*ofs_factor));
+	xip_enable(map, chip, 0);
 	printk(KERN_DEBUG "block status register for 0x%08lx is %x\n",
 	       adr, status);
 	return 0;
@@ -1650,8 +1911,8 @@
 #define DO_XXLOCK_ONEBLOCK_LOCK		((void *) 1)
 #define DO_XXLOCK_ONEBLOCK_UNLOCK	((void *) 2)
 
-static int do_xxlock_oneblock(struct map_info *map, struct flchip *chip,
-			      unsigned long adr, int len, void *thunk)
+static int __xipram do_xxlock_oneblock(struct map_info *map, struct flchip *chip,
+				       unsigned long adr, int len, void *thunk)
 {
 	struct cfi_private *cfi = map->fldrv_priv;
 	map_word status, status_OK;
@@ -1671,8 +1932,9 @@
 	}
 
 	ENABLE_VPP(map);
+	xip_disable(map, chip, adr);
+	
 	map_write(map, CMD(0x60), adr);
-
 	if (thunk == DO_XXLOCK_ONEBLOCK_LOCK) {
 		map_write(map, CMD(0x01), adr);
 		chip->state = FL_LOCKING;
@@ -1683,7 +1945,7 @@
 		BUG();
 
 	spin_unlock(chip->mutex);
-	schedule_timeout(HZ);
+	UDELAY(map, chip, adr, 1000000/HZ);
 	spin_lock(chip->mutex);
 
 	/* FIXME. Use a timer to check this, and return immediately. */
@@ -1702,6 +1964,7 @@
 			map_write(map, CMD(0x70), adr);
 			chip->state = FL_STATUS;
 			Xstatus = map_read(map, adr);
+			xip_enable(map, chip, adr);
 			printk(KERN_ERR "waiting for unlock to complete timed out. status = %lx, Xstatus = %lx.\n",
 			       status.x[0], Xstatus.x[0]);
 			put_chip(map, chip, adr);
@@ -1711,12 +1974,13 @@
 		
 		/* Latency issues. Drop the lock, wait a while and retry */
 		spin_unlock(chip->mutex);
-		cfi_udelay(1);
+		UDELAY(map, chip, adr, 1);
 		spin_lock(chip->mutex);
 	}
 	
 	/* Done and happy. */
 	chip->state = FL_STATUS;
+	xip_enable(map, chip, adr);
 	put_chip(map, chip, adr);
 	spin_unlock(chip->mutex);
 	return 0;
@@ -1875,7 +2139,7 @@
 static char im_name_1[]="cfi_cmdset_0001";
 static char im_name_3[]="cfi_cmdset_0003";
 
-int __init cfi_intelext_init(void)
+static int __init cfi_intelext_init(void)
 {
 	inter_module_register(im_name_1, THIS_MODULE, &cfi_cmdset_0001);
 	inter_module_register(im_name_3, THIS_MODULE, &cfi_cmdset_0001);
diff -Nru a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c
--- a/drivers/mtd/chips/cfi_cmdset_0002.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c	2005-03-01 23:38:56 -08:00
@@ -13,7 +13,7 @@
  *
  * This code is GPL
  *
- * $Id: cfi_cmdset_0002.c,v 1.111 2004/11/16 18:29:00 dwmw2 Exp $
+ * $Id: cfi_cmdset_0002.c,v 1.114 2004/12/11 15:43:53 dedekind Exp $
  *
  */
 
@@ -707,7 +707,7 @@
 	 */
 	unsigned long uWriteTimeout = ( HZ / 1000 ) + 1;
 	int ret = 0;
-	map_word oldd, curd;
+	map_word oldd;
 	int retry_cnt = 0;
 
 	adr += chip->start;
@@ -764,23 +764,11 @@
 			continue;
 		}
 
-		/* Test to see if toggling has stopped. */
-		oldd = map_read(map, adr);
-		curd = map_read(map, adr);
-		if (map_word_equal(map, curd, oldd)) {
-			/* Do we have the correct value? */
-			if (map_word_equal(map, curd, datum)) {
-				goto op_done;
-			}
-			/* Nope something has gone wrong. */
-			break;
-		}
+		if (chip_ready(map, adr))
+			goto op_done;
 
-		if (time_after(jiffies, timeo)) {
-			printk(KERN_WARNING "MTD %s(): software timeout\n",
-				__func__ );
-			break;
-		}
+		if (time_after(jiffies, timeo))
+                        break;
 
 		/* Latency issues. Drop the lock, wait a while and retry */
 		cfi_spin_unlock(chip->mutex);
@@ -788,6 +776,8 @@
 		cfi_spin_lock(chip->mutex);
 	}
 
+	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 */
@@ -1173,8 +1163,7 @@
 	chip->in_progress_block_addr = adr;
 
 	cfi_spin_unlock(chip->mutex);
-	set_current_state(TASK_UNINTERRUPTIBLE);
-	schedule_timeout((chip->erase_time*HZ)/(2*1000));
+	msleep(chip->erase_time/2);
 	cfi_spin_lock(chip->mutex);
 
 	timeo = jiffies + (HZ*20);
@@ -1259,8 +1248,7 @@
 	chip->in_progress_block_addr = adr;
 	
 	cfi_spin_unlock(chip->mutex);
-	set_current_state(TASK_UNINTERRUPTIBLE);
-	schedule_timeout((chip->erase_time*HZ)/(2*1000));
+	msleep(chip->erase_time/2);
 	cfi_spin_lock(chip->mutex);
 
 	timeo = jiffies + (HZ*20);
diff -Nru a/drivers/mtd/chips/cfi_cmdset_0020.c b/drivers/mtd/chips/cfi_cmdset_0020.c
--- a/drivers/mtd/chips/cfi_cmdset_0020.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/mtd/chips/cfi_cmdset_0020.c	2005-03-01 23:38:55 -08:00
@@ -4,7 +4,7 @@
  *
  * (C) 2000 Red Hat. GPL'd
  *
- * $Id: cfi_cmdset_0020.c,v 1.16 2004/11/16 18:29:00 dwmw2 Exp $
+ * $Id: cfi_cmdset_0020.c,v 1.17 2004/11/20 12:49:04 dwmw2 Exp $
  * 
  * 10/10/2000	Nicolas Pitre <nico@cam.org>
  * 	- completely revamped method functions so they are aware and
@@ -788,7 +788,7 @@
 	chip->state = FL_ERASING;
 	
 	spin_unlock_bh(chip->mutex);
-	schedule_timeout(HZ);
+	msleep(1000);
 	spin_lock_bh(chip->mutex);
 
 	/* FIXME. Use a timer to check this, and return immediately. */
@@ -1087,7 +1087,7 @@
 	chip->state = FL_LOCKING;
 	
 	spin_unlock_bh(chip->mutex);
-	schedule_timeout(HZ);
+	msleep(1000);
 	spin_lock_bh(chip->mutex);
 
 	/* FIXME. Use a timer to check this, and return immediately. */
@@ -1236,7 +1236,7 @@
 	chip->state = FL_UNLOCKING;
 	
 	spin_unlock_bh(chip->mutex);
-	schedule_timeout(HZ);
+	msleep(1000);
 	spin_lock_bh(chip->mutex);
 
 	/* FIXME. Use a timer to check this, and return immediately. */
diff -Nru a/drivers/mtd/chips/cfi_probe.c b/drivers/mtd/chips/cfi_probe.c
--- a/drivers/mtd/chips/cfi_probe.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/mtd/chips/cfi_probe.c	2005-03-01 23:39:08 -08:00
@@ -1,7 +1,7 @@
 /* 
    Common Flash Interface probe code.
    (C) 2000 Red Hat. GPL'd.
-   $Id: cfi_probe.c,v 1.79 2004/10/20 23:04:01 dwmw2 Exp $
+   $Id: cfi_probe.c,v 1.83 2004/11/16 18:19:02 nico Exp $
 */
 
 #include <linux/config.h>
@@ -15,6 +15,7 @@
 #include <linux/slab.h>
 #include <linux/interrupt.h>
 
+#include <linux/mtd/xip.h>
 #include <linux/mtd/map.h>
 #include <linux/mtd/cfi.h>
 #include <linux/mtd/gen_probe.h>
@@ -31,11 +32,47 @@
 
 struct mtd_info *cfi_probe(struct map_info *map);
 
+#ifdef CONFIG_MTD_XIP
+
+/* only needed for short periods, so this is rather simple */
+#define xip_disable()	local_irq_disable()
+
+#define xip_allowed(base, map) \
+do { \
+	(void) map_read(map, base); \
+	asm volatile (".rep 8; nop; .endr"); \
+	local_irq_enable(); \
+} while (0)
+
+#define xip_enable(base, map, cfi) \
+do { \
+	cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); \
+	cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL); \
+	xip_allowed(base, map); \
+} while (0)
+
+#define xip_disable_qry(base, map, cfi) \
+do { \
+	xip_disable(); \
+	cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); \
+	cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL); \
+	cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL); \
+} while (0)
+
+#else
+
+#define xip_disable()			do { } while (0)
+#define xip_allowed(base, map)		do { } while (0)
+#define xip_enable(base, map, cfi)	do { } while (0)
+#define xip_disable_qry(base, map, cfi) do { } while (0)
+
+#endif
+
 /* check for QRY.
    in: interleave,type,mode
    ret: table index, <0 for error
  */
-static int qry_present(struct map_info *map, __u32 base,
+static int __xipram qry_present(struct map_info *map, __u32 base,
 				struct cfi_private *cfi)
 {
 	int osf = cfi->interleave * cfi->device_type;	// scale factor
@@ -59,11 +96,11 @@
 	if (!map_word_equal(map, qry[2], val[2]))
 		return 0;
 
-	return 1; 	// nothing found
+	return 1; 	// "QRY" found
 }
 
-static int cfi_probe_chip(struct map_info *map, __u32 base,
-			  unsigned long *chip_map, struct cfi_private *cfi)
+static int __xipram cfi_probe_chip(struct map_info *map, __u32 base,
+				   unsigned long *chip_map, struct cfi_private *cfi)
 {
 	int i;
 	
@@ -79,12 +116,16 @@
 			(unsigned long)base + 0x55, map->size -1);
 		return 0;
 	}
+
+	xip_disable();
 	cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
 	cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL);
 	cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL);
 
-	if (!qry_present(map,base,cfi))
+	if (!qry_present(map,base,cfi)) {
+		xip_enable(base, map, cfi);
 		return 0;
+	}
 
 	if (!cfi->numchips) {
 		/* This is the first time we're called. Set up the CFI 
@@ -110,6 +151,7 @@
 
 			/* If the QRY marker goes away, it's an alias */
 			if (!qry_present(map, start, cfi)) {
+				xip_allowed(base, map);
 				printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n",
 				       map->name, base, start);
 				return 0;
@@ -122,6 +164,7 @@
 			cfi_send_gen_cmd(0xFF, 0, start, map, cfi, cfi->device_type, NULL);
 			
 			if (qry_present(map, base, cfi)) {
+				xip_allowed(base, map);
 				printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n",
 				       map->name, base, start);
 				return 0;
@@ -137,6 +180,7 @@
 	/* Put it back into Read Mode */
 	cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
 	cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL);
+	xip_allowed(base, map);
 
 	printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit bank\n",
 	       map->name, cfi->interleave, cfi->device_type*8, base,
@@ -145,14 +189,15 @@
 	return 1;
 }
 
-static int cfi_chip_setup(struct map_info *map, 
-		   struct cfi_private *cfi)
+static int __xipram cfi_chip_setup(struct map_info *map, 
+				   struct cfi_private *cfi)
 {
 	int ofs_factor = cfi->interleave*cfi->device_type;
 	__u32 base = 0;
 	int num_erase_regions = cfi_read_query(map, base + (0x10 + 28)*ofs_factor);
 	int i;
 
+	xip_enable(base, map, cfi);
 #ifdef DEBUG_CFI
 	printk("Number of erase regions: %d\n", num_erase_regions);
 #endif
@@ -170,13 +215,33 @@
 	cfi->cfi_mode = CFI_MODE_CFI;
 	
 	/* Read the CFI info structure */
-	for (i=0; i<(sizeof(struct cfi_ident) + num_erase_regions * 4); i++) {
+	xip_disable_qry(base, map, cfi);
+	for (i=0; i<(sizeof(struct cfi_ident) + num_erase_regions * 4); i++)
 		((unsigned char *)cfi->cfiq)[i] = cfi_read_query(map,base + (0x10 + i)*ofs_factor);
-	}
-	
+
+	/* Note we put the device back into Read Mode BEFORE going into Auto
+	 * Select Mode, as some devices support nesting of modes, others
+	 * don't. This way should always work.
+	 * On cmdset 0001 the writes of 0xaa and 0x55 are not needed, and
+	 * so should be treated as nops or illegal (and so put the device
+	 * back into Read Mode, which is a nop in this case).
+	 */
+	cfi_send_gen_cmd(0xf0,     0, base, map, cfi, cfi->device_type, NULL);
+	cfi_send_gen_cmd(0xaa, 0x555, base, map, cfi, cfi->device_type, NULL);
+	cfi_send_gen_cmd(0x55, 0x2aa, base, map, cfi, cfi->device_type, NULL);
+	cfi_send_gen_cmd(0x90, 0x555, base, map, cfi, cfi->device_type, NULL);
+	cfi->mfr = cfi_read_query(map, base);
+	cfi->id = cfi_read_query(map, base + ofs_factor);    
+
+	/* Put it back into Read Mode */
+	cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
+	/* ... even if it's an Intel chip */
+	cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL);
+	xip_allowed(base, map);
+
 	/* Do any necessary byteswapping */
 	cfi->cfiq->P_ID = le16_to_cpu(cfi->cfiq->P_ID);
-	
+
 	cfi->cfiq->P_ADR = le16_to_cpu(cfi->cfiq->P_ADR);
 	cfi->cfiq->A_ID = le16_to_cpu(cfi->cfiq->A_ID);
 	cfi->cfiq->A_ADR = le16_to_cpu(cfi->cfiq->A_ADR);
@@ -197,25 +262,6 @@
 		       (cfi->cfiq->EraseRegionInfo[i] & 0xffff) + 1);
 #endif
 	}
-
-	/* Note we put the device back into Read Mode BEFORE going into Auto
-	 * Select Mode, as some devices support nesting of modes, others
-	 * don't. This way should always work.
-	 * On cmdset 0001 the writes of 0xaa and 0x55 are not needed, and
-	 * so should be treated as nops or illegal (and so put the device
-	 * back into Read Mode, which is a nop in this case).
-	 */
-	cfi_send_gen_cmd(0xf0,     0, base, map, cfi, cfi->device_type, NULL);
-	cfi_send_gen_cmd(0xaa, 0x555, base, map, cfi, cfi->device_type, NULL);
-	cfi_send_gen_cmd(0x55, 0x2aa, base, map, cfi, cfi->device_type, NULL);
-	cfi_send_gen_cmd(0x90, 0x555, base, map, cfi, cfi->device_type, NULL);
-	cfi->mfr = cfi_read_query(map, base);
-	cfi->id = cfi_read_query(map, base + ofs_factor);    
-
-	/* Put it back into Read Mode */
-	cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
-	/* ... even if it's an Intel chip */
-	cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL);
 
 	printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit bank\n",
 	       map->name, cfi->interleave, cfi->device_type*8, base,
diff -Nru a/drivers/mtd/chips/cfi_util.c b/drivers/mtd/chips/cfi_util.c
--- a/drivers/mtd/chips/cfi_util.c	2005-03-01 23:38:59 -08:00
+++ b/drivers/mtd/chips/cfi_util.c	2005-03-01 23:38:59 -08:00
@@ -7,7 +7,7 @@
  *
  * This code is covered by the GPL.
  *
- * $Id: cfi_util.c,v 1.5 2004/08/12 06:40:23 eric Exp $
+ * $Id: cfi_util.c,v 1.8 2004/12/14 19:55:56 nico Exp $
  *
  */
 
@@ -22,13 +22,14 @@
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
+#include <linux/mtd/xip.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/map.h>
 #include <linux/mtd/cfi.h>
 #include <linux/mtd/compatmac.h>
 
 struct cfi_extquery *
-cfi_read_pri(struct map_info *map, __u16 adr, __u16 size, const char* name)
+__xipram cfi_read_pri(struct map_info *map, __u16 adr, __u16 size, const char* name)
 {
 	struct cfi_private *cfi = map->fldrv_priv;
 	__u32 base = 0; // cfi->chips[0].start;
@@ -40,21 +41,35 @@
 	if (!adr)
 		goto out;
 
-	/* Switch it into Query Mode */
-	cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL);
-
 	extp = kmalloc(size, GFP_KERNEL);
 	if (!extp) {
 		printk(KERN_ERR "Failed to allocate memory\n");
 		goto out;
 	}
-		
+
+#ifdef CONFIG_MTD_XIP
+	local_irq_disable();
+#endif
+
+	/* Switch it into Query Mode */
+	cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL);
+
 	/* Read in the Extended Query Table */
 	for (i=0; i<size; i++) {
 		((unsigned char *)extp)[i] = 
 			cfi_read_query(map, base+((adr+i)*ofs_factor));
 	}
 
+	/* Make sure it returns to read mode */
+	cfi_send_gen_cmd(0xf0, 0, base, map, cfi, cfi->device_type, NULL);
+	cfi_send_gen_cmd(0xff, 0, base, map, cfi, cfi->device_type, NULL);
+
+#ifdef CONFIG_MTD_XIP
+	(void) map_read(map, base);
+	asm volatile (".rep 8; nop; .endr");
+	local_irq_enable();
+#endif
+
 	if (extp->MajorVersion != '1' || 
 	    (extp->MinorVersion < '0' || extp->MinorVersion > '3')) {
 		printk(KERN_WARNING "  Unknown %s Extended Query "
@@ -62,15 +77,9 @@
 		       extp->MinorVersion);
 		kfree(extp);
 		extp = NULL;
-		goto out;
 	}
 
-out:
-	/* Make sure it's in read mode */
-	cfi_send_gen_cmd(0xf0, 0, base, map, cfi, cfi->device_type, NULL);
-	cfi_send_gen_cmd(0xff, 0, base, map, cfi, cfi->device_type, NULL);
-
-	return extp;
+ out:	return extp;
 }
 
 EXPORT_SYMBOL(cfi_read_pri);
@@ -156,7 +165,6 @@
 	i=first;
 
 	while(len) {
-		unsigned long chipmask;
 		int size = regions[i].erasesize;
 
 		ret = (*frob)(map, &cfi->chips[chipnum], adr, size, thunk);
@@ -165,10 +173,10 @@
 			return ret;
 
 		adr += size;
+		ofs += size;
 		len -= size;
 
-		chipmask = (1 << cfi->chipshift) - 1;
-		if ((adr & chipmask) == ((regions[i].offset + size * regions[i].numblocks) & chipmask))
+		if (ofs == regions[i].offset + size * regions[i].numblocks)
 			i++;
 
 		if (adr >> cfi->chipshift) {
diff -Nru a/drivers/mtd/chips/chipreg.c b/drivers/mtd/chips/chipreg.c
--- a/drivers/mtd/chips/chipreg.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/mtd/chips/chipreg.c	2005-03-01 23:38:55 -08:00
@@ -15,7 +15,7 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/compatmac.h>
 
-static spinlock_t chip_drvs_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(chip_drvs_lock);
 static LIST_HEAD(chip_drvs_list);
 
 void register_mtd_chip_driver(struct mtd_chip_driver *drv)
diff -Nru a/drivers/mtd/chips/jedec.c b/drivers/mtd/chips/jedec.c
--- a/drivers/mtd/chips/jedec.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/mtd/chips/jedec.c	2005-03-01 23:38:58 -08:00
@@ -11,7 +11,7 @@
  * not going to guess how to send commands to them, plus I expect they will
  * all speak CFI..
  *
- * $Id: jedec.c,v 1.21 2004/08/09 13:19:43 dwmw2 Exp $
+ * $Id: jedec.c,v 1.22 2005/01/05 18:05:11 dwmw2 Exp $
  */
 
 #include <linux/init.h>
@@ -529,7 +529,7 @@
 static int jedec_read(struct mtd_info *mtd, loff_t from, size_t len, 
 		      size_t *retlen, u_char *buf)
 {
-   struct map_info *map = (struct map_info *)mtd->priv;
+   struct map_info *map = mtd->priv;
    
    map_copy_from(map, buf, from, len);
    *retlen = len;
@@ -541,8 +541,8 @@
 static int jedec_read_banked(struct mtd_info *mtd, loff_t from, size_t len, 
 			     size_t *retlen, u_char *buf)
 {
-   struct map_info *map = (struct map_info *)mtd->priv;
-   struct jedec_private *priv = (struct jedec_private *)map->fldrv_priv;
+   struct map_info *map = mtd->priv;
+   struct jedec_private *priv = map->fldrv_priv;
 
    *retlen = 0;
    while (len > 0)
@@ -593,8 +593,8 @@
    unsigned long NoTime = 0;
    unsigned long start = instr->addr, len = instr->len;
    unsigned int I;
-   struct map_info *map = (struct map_info *)mtd->priv;
-   struct jedec_private *priv = (struct jedec_private *)map->fldrv_priv;
+   struct map_info *map = mtd->priv;
+   struct jedec_private *priv = map->fldrv_priv;
 
    // Verify the arguments..
    if (start + len > mtd->size ||
@@ -800,8 +800,8 @@
    #define flread(x) map_read8(map,base+(off&((1<<chip->addrshift)-1))+((x)<<chip->addrshift))
    #define flwrite(v,x) map_write8(map,v,base+(off&((1<<chip->addrshift)-1))+((x)<<chip->addrshift))
    
-   struct map_info *map = (struct map_info *)mtd->priv;
-   struct jedec_private *priv = (struct jedec_private *)map->fldrv_priv;
+   struct map_info *map = mtd->priv;
+   struct jedec_private *priv = map->fldrv_priv;
    unsigned long base;
    unsigned long off;
    size_t save_len = len;
diff -Nru a/drivers/mtd/chips/jedec_probe.c b/drivers/mtd/chips/jedec_probe.c
--- a/drivers/mtd/chips/jedec_probe.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/mtd/chips/jedec_probe.c	2005-03-01 23:39:17 -08:00
@@ -1,7 +1,7 @@
 /* 
    Common Flash Interface probe code.
    (C) 2000 Red Hat. GPL'd.
-   $Id: jedec_probe.c,v 1.58 2004/11/16 18:29:00 dwmw2 Exp $
+   $Id: jedec_probe.c,v 1.61 2004/11/19 20:52:16 thayne Exp $
    See JEDEC (http://www.jedec.org/) standard JESD21C (section 3.5)
    for the standard this probe goes back to.
 
@@ -32,6 +32,7 @@
 #define MANUFACTURER_HYUNDAI	0x00AD
 #define MANUFACTURER_INTEL	0x0089
 #define MANUFACTURER_MACRONIX	0x00C2
+#define MANUFACTURER_NEC	0x0010
 #define MANUFACTURER_PMC	0x009D
 #define MANUFACTURER_SST	0x00BF
 #define MANUFACTURER_ST		0x0020
@@ -115,6 +116,9 @@
 #define MX29F004T	0x0045
 #define MX29F004B	0x0046
 
+/* NEC */
+#define UPD29F064115	0x221C
+
 /* PMC */
 #define PM49FL002	0x006D
 #define PM49FL004	0x006E
@@ -227,6 +231,11 @@
 	[MTD_UADDR_DONT_CARE] = {
 		.addr1 = 0x0000,      /* Doesn't matter which address */
 		.addr2 = 0x0000       /* is used - must be last entry */
+	},
+
+	[MTD_UADDR_UNNECESSARY] = {
+		.addr1 = 0x0000,
+		.addr2 = 0x0000
 	}
 };
 
@@ -514,15 +523,20 @@
 			ERASEINFO(0x10000,8),
 		}
 	}, {
-		mfr_id: MANUFACTURER_AMD,
-		dev_id: AM29F002T,
-		name: "AMD AM29F002T",
-		DevSize: SIZE_256KiB,
-		NumEraseRegions: 4,
-		regions: {ERASEINFO(0x10000,3),
-			  ERASEINFO(0x08000,1),
-			  ERASEINFO(0x02000,2),
-			  ERASEINFO(0x04000,1)
+		.mfr_id		= MANUFACTURER_AMD,
+		.dev_id		= AM29F002T,
+		.name		= "AMD AM29F002T",
+		.uaddr		= {
+			[0] = MTD_UADDR_0x0555_0x02AA /* x8 */
+		},
+		.DevSize	= SIZE_256KiB,
+		.CmdSet		= P_ID_AMD_STD,
+		.NumEraseRegions= 4,
+		.regions	= {
+			ERASEINFO(0x10000,3),
+			ERASEINFO(0x08000,1),
+			ERASEINFO(0x02000,2),
+			ERASEINFO(0x04000,1),
 		}
 	}, {
 		.mfr_id		= MANUFACTURER_ATMEL,
@@ -770,15 +784,20 @@
 			ERASEINFO(0x04000,1)
 		}
 	}, {
-		mfr_id: MANUFACTURER_HYUNDAI,
-		dev_id: HY29F002T,
-		name: "Hyundai HY29F002T",
-		DevSize: SIZE_256KiB,
-		NumEraseRegions: 4,
-		regions: {ERASEINFO(0x10000,3),
-			  ERASEINFO(0x08000,1),
-			  ERASEINFO(0x02000,2),
-			  ERASEINFO(0x04000,1)
+		.mfr_id		= MANUFACTURER_HYUNDAI,
+		.dev_id		= HY29F002T,
+		.name		= "Hyundai HY29F002T",
+		.uaddr		= {
+			[0] = MTD_UADDR_0x0555_0x02AA /* x8 */
+		},
+		.DevSize	= SIZE_256KiB,
+		.CmdSet		= P_ID_AMD_STD,
+		.NumEraseRegions= 4,
+		.regions	= {
+			ERASEINFO(0x10000,3),
+			ERASEINFO(0x08000,1),
+			ERASEINFO(0x02000,2),
+			ERASEINFO(0x04000,1),
 		}
 	}, {
 		.mfr_id		= MANUFACTURER_INTEL,
@@ -1115,6 +1134,22 @@
 			ERASEINFO(0x04000,1)
 		}
 	}, {
+		.mfr_id		= MANUFACTURER_NEC,
+		.dev_id		= UPD29F064115,
+		.name		= "NEC uPD29F064115",
+		.uaddr		= {
+			[0] = MTD_UADDR_0x0555_0x02AA,  /* x8 */
+			[1] = MTD_UADDR_0x0555_0x02AA,  /* x16 */
+		},
+		.DevSize	= SIZE_8MiB,
+		.CmdSet		= P_ID_AMD_STD,
+		.NumEraseRegions= 3,
+		.regions	= {
+			ERASEINFO(0x2000,8),
+			ERASEINFO(0x10000,126),
+			ERASEINFO(0x2000,8),
+		}
+	}, {
 		.mfr_id		= MANUFACTURER_MACRONIX,
 		.dev_id		= MX29LV160B,
 		.name		= "MXIC MX29LV160B",
@@ -1177,15 +1212,20 @@
 			ERASEINFO(0x10000,7),
 		}
 	}, {
-		mfr_id: MANUFACTURER_MACRONIX,
-		dev_id: MX29F002T,
-		name: "Macronix MX29F002T",
-		DevSize: SIZE_256KiB,
-		NumEraseRegions: 4,
-		regions: {ERASEINFO(0x10000,3),
-			  ERASEINFO(0x08000,1),
-			  ERASEINFO(0x02000,2),
-			  ERASEINFO(0x04000,1)
+		.mfr_id		= MANUFACTURER_MACRONIX,
+		.dev_id		= MX29F002T,
+		.name		= "Macronix MX29F002T",
+		.uaddr		= {
+			[0] = MTD_UADDR_0x0555_0x02AA /* x8 */
+		},
+		.DevSize	= SIZE_256KiB,
+		.CmdSet		= P_ID_AMD_STD,
+		.NumEraseRegions= 4,
+		.regions	= {
+			ERASEINFO(0x10000,3),
+			ERASEINFO(0x08000,1),
+			ERASEINFO(0x02000,2),
+			ERASEINFO(0x04000,1),
 		}
 	}, {
 		.mfr_id		= MANUFACTURER_PMC,
@@ -1262,7 +1302,7 @@
  		.DevSize	= SIZE_256KiB,
  		.CmdSet		= P_ID_SST_PAGE,
  		.NumEraseRegions= 1,
- 		regions: {ERASEINFO(0x01000,64),
+ 		.regions = {ERASEINFO(0x01000,64),
  		}
          }, {
  		.mfr_id		= MANUFACTURER_SST,
@@ -1274,7 +1314,7 @@
  		.DevSize	= SIZE_256KiB,
  		.CmdSet		= P_ID_SST_PAGE,
  		.NumEraseRegions= 1,
- 		regions: {ERASEINFO(0x01000,64),
+ 		.regions = {ERASEINFO(0x01000,64),
  		}
 	}, {
 		.mfr_id		= MANUFACTURER_SST,
@@ -1780,7 +1820,6 @@
 		return 0;
 	}
 
-	/* Mask out address bits which are smaller than the device type */
 	p_cfi->addr_unlock1 = unlock_addrs[uaddr].addr1;
 	p_cfi->addr_unlock2 = unlock_addrs[uaddr].addr2;
 
@@ -1923,7 +1962,6 @@
 		if (MTD_UADDR_UNNECESSARY == uaddr_idx)
 			return 0;
 
-		/* Mask out address bits which are smaller than the device type */
 		cfi->addr_unlock1 = unlock_addrs[uaddr_idx].addr1;
 		cfi->addr_unlock2 = unlock_addrs[uaddr_idx].addr2;
 	}
diff -Nru a/drivers/mtd/chips/map_ram.c b/drivers/mtd/chips/map_ram.c
--- a/drivers/mtd/chips/map_ram.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/mtd/chips/map_ram.c	2005-03-01 23:38:54 -08:00
@@ -1,7 +1,7 @@
 /*
  * Common code to handle map devices which are simple RAM
  * (C) 2000 Red Hat. GPL'd.
- * $Id: map_ram.c,v 1.21 2004/11/16 18:29:00 dwmw2 Exp $
+ * $Id: map_ram.c,v 1.22 2005/01/05 18:05:12 dwmw2 Exp $
  */
 
 #include <linux/module.h>
@@ -83,7 +83,7 @@
 
 static int mapram_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
 {
-	struct map_info *map = (struct map_info *)mtd->priv;
+	struct map_info *map = mtd->priv;
 
 	map_copy_from(map, buf, from, len);
 	*retlen = len;
@@ -92,7 +92,7 @@
 
 static int mapram_write (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf)
 {
-	struct map_info *map = (struct map_info *)mtd->priv;
+	struct map_info *map = mtd->priv;
 
 	map_copy_to(map, to, buf, len);
 	*retlen = len;
@@ -103,7 +103,7 @@
 {
 	/* Yeah, it's inefficient. Who cares? It's faster than a _real_
 	   flash erase. */
-	struct map_info *map = (struct map_info *)mtd->priv;
+	struct map_info *map = mtd->priv;
 	map_word allff;
 	unsigned long i;
 
diff -Nru a/drivers/mtd/chips/map_rom.c b/drivers/mtd/chips/map_rom.c
--- a/drivers/mtd/chips/map_rom.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/mtd/chips/map_rom.c	2005-03-01 23:39:07 -08:00
@@ -1,7 +1,7 @@
 /*
  * Common code to handle map devices which are simple ROM
  * (C) 2000 Red Hat. GPL'd.
- * $Id: map_rom.c,v 1.22 2004/11/16 18:29:00 dwmw2 Exp $
+ * $Id: map_rom.c,v 1.23 2005/01/05 18:05:12 dwmw2 Exp $
  */
 
 #include <linux/module.h>
@@ -57,7 +57,7 @@
 
 static int maprom_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
 {
-	struct map_info *map = (struct map_info *)mtd->priv;
+	struct map_info *map = mtd->priv;
 
 	map_copy_from(map, buf, from, len);
 	*retlen = len;
diff -Nru a/drivers/mtd/cmdlinepart.c b/drivers/mtd/cmdlinepart.c
--- a/drivers/mtd/cmdlinepart.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/mtd/cmdlinepart.c	2005-03-01 23:39:08 -08:00
@@ -1,5 +1,5 @@
 /*
- * $Id: cmdlinepart.c,v 1.16 2004/11/16 18:28:59 dwmw2 Exp $
+ * $Id: cmdlinepart.c,v 1.17 2004/11/26 11:18:47 lavinen Exp $
  *
  * Read flash partition table from command line
  *
@@ -338,8 +338,10 @@
  * This is the handler for our kernel parameter, called from 
  * main.c::checksetup(). Note that we can not yet kmalloc() anything,
  * so we only save the commandline for later processing.
+ *
+ * This function needs to be visible for bootloaders.
  */
-static int mtdpart_setup(char *s)
+int mtdpart_setup(char *s)
 {
 	cmdline = s;
 	return 1;
diff -Nru a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig
--- a/drivers/mtd/devices/Kconfig	2005-03-01 23:39:18 -08:00
+++ b/drivers/mtd/devices/Kconfig	2005-03-01 23:39:18 -08:00
@@ -1,5 +1,5 @@
 # drivers/mtd/maps/Kconfig
-# $Id: Kconfig,v 1.13 2004/10/01 21:47:13 gleixner Exp $
+# $Id: Kconfig,v 1.15 2004/12/22 17:51:15 joern Exp $
 
 menu "Self-contained MTD device drivers"
 	depends on MTD!=n
@@ -125,11 +125,22 @@
 	  Testing MTD users (eg JFFS2) on large media and media that might
 	  be removed during a write (using the floppy drive).
 
+config MTD_BLOCK2MTD
+	tristate "MTD using block device (rewrite)"
+	depends on MTD && EXPERIMENTAL
+	help
+	  This driver is basically the same at MTD_BLKMTD above, but
+	  experienced some interface changes plus serious speedups.  In
+	  the long term, it should replace MTD_BLKMTD.  Right now, you
+	  shouldn't entrust important data to it yet.
+
 comment "Disk-On-Chip Device Drivers"
 
 config MTD_DOC2000
 	tristate "M-Systems Disk-On-Chip 2000 and Millennium (DEPRECATED)"
 	depends on MTD
+	select MTD_DOCPROBE
+	select MTD_NAND_IDS
 	---help---
 	  This provides an MTD device driver for the M-Systems DiskOnChip
 	  2000 and Millennium devices.  Originally designed for the DiskOnChip
@@ -151,6 +162,8 @@
 config MTD_DOC2001
 	tristate "M-Systems Disk-On-Chip Millennium-only alternative driver (DEPRECATED)"
 	depends on MTD
+	select MTD_DOCPROBE
+	select MTD_NAND_IDS
 	---help---
 	  This provides an alternative MTD device driver for the M-Systems 
 	  DiskOnChip Millennium devices.  Use this if you have problems with
@@ -171,6 +184,8 @@
 config MTD_DOC2001PLUS
 	tristate "M-Systems Disk-On-Chip Millennium Plus"
 	depends on MTD
+	select MTD_DOCPROBE
+	select MTD_NAND_IDS
 	---help---
 	  This provides an MTD device driver for the M-Systems DiskOnChip
 	  Millennium Plus devices.
@@ -186,17 +201,10 @@
 
 config MTD_DOCPROBE
 	tristate
-	default m if MTD_DOC2001!=y && MTD_DOC2000!=y && MTD_DOC2001PLUS!=y && (MTD_DOC2001=m || MTD_DOC2000=m || MTD_DOC2001PLUS=m)
-	default y if MTD_DOC2001=y || MTD_DOC2000=y || MTD_DOC2001PLUS=y
-	help
-	  This isn't a real config option; it's derived.
+	select MTD_DOCECC
 
 config MTD_DOCECC
 	tristate
-	default m if MTD_DOCPROBE=m
-	default y if MTD_DOCPROBE=y
-	help
-	  This isn't a real config option; it's derived.
 
 config MTD_DOCPROBE_ADVANCED
 	bool "Advanced detection options for DiskOnChip"
diff -Nru a/drivers/mtd/devices/Makefile b/drivers/mtd/devices/Makefile
--- a/drivers/mtd/devices/Makefile	2005-03-01 23:38:44 -08:00
+++ b/drivers/mtd/devices/Makefile	2005-03-01 23:38:44 -08:00
@@ -1,7 +1,7 @@
 #
 # linux/drivers/devices/Makefile
 #
-# $Id: Makefile.common,v 1.6 2004/07/12 16:07:30 dwmw2 Exp $
+# $Id: Makefile.common,v 1.7 2004/12/22 17:51:15 joern Exp $
 
 #                       *** BIG UGLY NOTE ***
 #
@@ -22,3 +22,4 @@
 obj-$(CONFIG_MTD_MTDRAM)	+= mtdram.o
 obj-$(CONFIG_MTD_LART)		+= lart.o
 obj-$(CONFIG_MTD_BLKMTD)	+= blkmtd.o
+obj-$(CONFIG_MTD_BLOCK2MTD)	+= block2mtd.o
diff -Nru a/drivers/mtd/devices/blkmtd.c b/drivers/mtd/devices/blkmtd.c
--- a/drivers/mtd/devices/blkmtd.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/mtd/devices/blkmtd.c	2005-03-01 23:39:18 -08:00
@@ -68,13 +68,13 @@
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Simon Evans <spse@secret.org.uk>");
 MODULE_DESCRIPTION("Emulate an MTD using a block device");
-MODULE_PARM(device, "1-4s");
+module_param_array(device, charp, NULL, 0);
 MODULE_PARM_DESC(device, "block device to use");
-MODULE_PARM(erasesz, "1-4i");
+module_param_array(erasesz, int, NULL, 0);
 MODULE_PARM_DESC(erasesz, "optional erase size to use in KiB. eg 4=4KiB.");
-MODULE_PARM(ro, "1-4i");
+module_param_array(ro, bool, NULL, 0);
 MODULE_PARM_DESC(ro, "1=Read only, writes and erases cause errors");
-MODULE_PARM(sync, "i");
+module_param(sync, bool, 0);
 MODULE_PARM_DESC(sync, "1=Synchronous writes");
 
 
@@ -661,7 +661,6 @@
 
 	memset(dev, 0, sizeof(struct blkmtd_dev));
 	dev->blkdev = bdev;
-	atomic_set(&(dev->blkdev->bd_inode->i_mapping->truncate_count), 0);
 	if(!readonly) {
 		init_MUTEX(&dev->wrbuf_mutex);
 	}
diff -Nru a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/mtd/devices/block2mtd.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,495 @@
+/*
+ * $Id: block2mtd.c,v 1.23 2005/01/05 17:05:46 dwmw2 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
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/blkdev.h>
+#include <linux/bio.h>
+#include <linux/pagemap.h>
+#include <linux/list.h>
+#include <linux/init.h>
+#include <linux/mtd/mtd.h>
+#include <linux/buffer_head.h>
+
+#define VERSION "$Revision: 1.23 $"
+
+
+#define ERROR(fmt, args...) printk(KERN_ERR "block2mtd: " fmt "\n" , ## args)
+#define INFO(fmt, args...) printk(KERN_INFO "block2mtd: " fmt "\n" , ## args)
+
+
+/* Info for the block device */
+struct block2mtd_dev {
+	struct list_head list;
+	struct block_device *blkdev;
+	struct mtd_info mtd;
+	struct semaphore write_mutex;
+};
+
+
+/* Static info about the MTD, used in cleanup_module */
+static LIST_HEAD(blkmtd_device_list);
+
+
+#define PAGE_READAHEAD 64
+void cache_readahead(struct address_space *mapping, int index)
+{
+	filler_t *filler = (filler_t*)mapping->a_ops->readpage;
+	int i, pagei;
+	unsigned ret = 0;
+	unsigned long end_index;
+	struct page *page;
+	LIST_HEAD(page_pool);
+	struct inode *inode = mapping->host;
+	loff_t isize = i_size_read(inode);
+
+	if (!isize) {
+		INFO("iSize=0 in cache_readahead\n");
+		return;
+	}
+
+	end_index = ((isize - 1) >> PAGE_CACHE_SHIFT);
+
+	spin_lock_irq(&mapping->tree_lock);
+	for (i = 0; i < PAGE_READAHEAD; i++) {
+		pagei = index + i;
+		if (pagei > end_index) {
+			INFO("Overrun end of disk in cache readahead\n");
+			break;
+		}
+		page = radix_tree_lookup(&mapping->page_tree, pagei);
+		if (page && (!i))
+			break;
+		if (page)
+			continue;
+		spin_unlock_irq(&mapping->tree_lock);
+		page = page_cache_alloc_cold(mapping);
+		spin_lock_irq(&mapping->tree_lock);
+		if (!page)
+			break;
+		page->index = pagei;
+		list_add(&page->lru, &page_pool);
+		ret++;
+	}
+	spin_unlock_irq(&mapping->tree_lock);
+	if (ret)
+		read_cache_pages(mapping, &page_pool, filler, NULL);
+}
+
+
+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);
+}
+
+
+/* erase a specified part of the device */
+static int _block2mtd_erase(struct block2mtd_dev *dev, loff_t to, size_t len)
+{
+	struct address_space *mapping = dev->blkdev->bd_inode->i_mapping;
+	struct page *page;
+	int index = to >> PAGE_SHIFT;	// page index
+	int pages = len >> PAGE_SHIFT;
+	u_long *p;
+	u_long *max;
+
+	while (pages) {
+		page = page_readahead(mapping, index);
+		if (!page)
+			return -ENOMEM;
+		if (IS_ERR(page))
+			return PTR_ERR(page);
+
+		max = (u_long*)page_address(page) + PAGE_SIZE;
+		for (p=(u_long*)page_address(page); p<max; p++) 
+			if (*p != -1UL) {
+				lock_page(page);
+				memset(page_address(page), 0xff, PAGE_SIZE);
+				set_page_dirty(page);
+				unlock_page(page);
+				break;
+			}
+
+		page_cache_release(page);
+		pages--;
+		index++;
+	}
+	return 0;
+}
+static int block2mtd_erase(struct mtd_info *mtd, struct erase_info *instr)
+{
+	struct block2mtd_dev *dev = mtd->priv;
+	size_t from = instr->addr;
+	size_t len = instr->len;
+	int err;
+
+	instr->state = MTD_ERASING;
+	down(&dev->write_mutex);
+	err = _block2mtd_erase(dev, from, len);
+	up(&dev->write_mutex);
+	if (err) {
+		ERROR("erase failed err = %d", err);
+		instr->state = MTD_ERASE_FAILED;
+	} else
+		instr->state = MTD_ERASE_DONE;
+
+	instr->state = MTD_ERASE_DONE;
+	mtd_erase_callback(instr);
+	return err;
+}
+
+
+static int block2mtd_read(struct mtd_info *mtd, loff_t from, size_t len,
+		size_t *retlen, u_char *buf)
+{
+	struct block2mtd_dev *dev = mtd->priv;
+	struct page *page;
+	int index = from >> PAGE_SHIFT;
+	int offset = from & (PAGE_SHIFT-1);
+	int cpylen;
+
+	if (from > mtd->size)
+		return -EINVAL;
+	if (from + len > mtd->size)
+		len = mtd->size - from;
+
+	if (retlen)
+		*retlen = 0;
+
+	while (len) {
+		if ((offset + len) > PAGE_SIZE)
+			cpylen = PAGE_SIZE - offset;	// multiple pages
+		else
+			cpylen = len;	// this page
+		len = len - cpylen;
+
+		//      Get page
+		page = page_readahead(dev->blkdev->bd_inode->i_mapping, index);
+		if (!page)
+			return -ENOMEM;
+		if (IS_ERR(page))
+			return PTR_ERR(page);
+
+		memcpy(buf, page_address(page) + offset, cpylen);
+		page_cache_release(page);
+
+		if (retlen)
+			*retlen += cpylen;
+		buf += cpylen;
+		offset = 0;
+		index++;
+	}
+	return 0;
+}
+
+
+/* write data to the underlying device */
+static int _block2mtd_write(struct block2mtd_dev *dev, const u_char *buf,
+		loff_t to, size_t len, size_t *retlen)
+{
+	struct page *page;
+	struct address_space *mapping = dev->blkdev->bd_inode->i_mapping;
+	int index = to >> PAGE_SHIFT;	// page index
+	int offset = to & ~PAGE_MASK;	// page offset
+	int cpylen;
+
+	if (retlen)
+		*retlen = 0;
+	while (len) {
+		if ((offset+len) > PAGE_SIZE) 
+			cpylen = PAGE_SIZE - offset;	// multiple pages
+		else
+			cpylen = len;			// this page
+		len = len - cpylen;
+
+		//	Get page
+		page = page_readahead(mapping, index);
+		if (!page)
+			return -ENOMEM;
+		if (IS_ERR(page))
+			return PTR_ERR(page);
+
+		if (memcmp(page_address(page)+offset, buf, cpylen)) {
+			lock_page(page);
+			memcpy(page_address(page) + offset, buf, cpylen);
+			set_page_dirty(page);
+			unlock_page(page);
+		}
+		page_cache_release(page);
+
+		if (retlen)
+			*retlen += cpylen;
+
+		buf += cpylen;
+		offset = 0;
+		index++;
+	}
+	return 0;
+}
+static int block2mtd_write(struct mtd_info *mtd, loff_t to, size_t len,
+		size_t *retlen, const u_char *buf)
+{
+	struct block2mtd_dev *dev = mtd->priv;
+	int err;
+
+	if (!len)
+		return 0;
+	if (to >= mtd->size)
+		return -ENOSPC;
+	if (to + len > mtd->size)
+		len = mtd->size - to;
+
+	down(&dev->write_mutex);
+	err = _block2mtd_write(dev, buf, to, len, retlen);
+	up(&dev->write_mutex);
+	if (err > 0)
+		err = 0;
+	return err;
+}
+
+
+/* sync the device - wait until the write queue is empty */
+static void block2mtd_sync(struct mtd_info *mtd)
+{
+	struct block2mtd_dev *dev = mtd->priv;
+	sync_blockdev(dev->blkdev);
+	return;
+}
+
+
+static void block2mtd_free_device(struct block2mtd_dev *dev)
+{
+	if (!dev)
+		return;
+
+	kfree(dev->mtd.name);
+
+	if (dev->blkdev) {
+		invalidate_inode_pages(dev->blkdev->bd_inode->i_mapping);
+		close_bdev_excl(dev->blkdev);
+	}
+
+	kfree(dev);
+}
+
+
+/* FIXME: ensure that mtd->size % erase_size == 0 */
+static struct block2mtd_dev *add_device(char *devname, int erase_size)
+{
+	struct block_device *bdev;
+	struct block2mtd_dev *dev;
+
+	if (!devname)
+		return NULL;
+
+	dev = kmalloc(sizeof(struct block2mtd_dev), GFP_KERNEL);
+	if (!dev)
+		return NULL;
+	memset(dev, 0, sizeof(*dev));
+
+	/* Get a handle on the device */
+	bdev = open_bdev_excl(devname, O_RDWR, NULL);
+	if (IS_ERR(bdev)) {
+		ERROR("error: cannot open device %s", devname);
+		goto devinit_err;
+	}
+	dev->blkdev = bdev;
+
+	if (MAJOR(bdev->bd_dev) == MTD_BLOCK_MAJOR) {
+		ERROR("attempting to use an MTD device as a block device");
+		goto devinit_err;
+	}
+
+	init_MUTEX(&dev->write_mutex);
+
+	/* Setup the MTD structure */
+	/* make the name contain the block device in */
+	dev->mtd.name = kmalloc(sizeof("block2mtd: ") + strlen(devname),
+			GFP_KERNEL);
+	if (!dev->mtd.name)
+		goto devinit_err;
+
+	sprintf(dev->mtd.name, "block2mtd: %s", devname);
+
+	dev->mtd.size = dev->blkdev->bd_inode->i_size & PAGE_MASK;
+	dev->mtd.erasesize = erase_size;
+	dev->mtd.type = MTD_RAM;
+	dev->mtd.flags = MTD_CAP_RAM;
+	dev->mtd.erase = block2mtd_erase;
+	dev->mtd.write = block2mtd_write;
+	dev->mtd.writev = default_mtd_writev;
+	dev->mtd.sync = block2mtd_sync;
+	dev->mtd.read = block2mtd_read;
+	dev->mtd.readv = default_mtd_readv;
+	dev->mtd.priv = dev;
+	dev->mtd.owner = THIS_MODULE;
+
+	if (add_mtd_device(&dev->mtd)) {
+		/* Device didnt get added, so free the entry */
+		goto devinit_err;
+	}
+	list_add(&dev->list, &blkmtd_device_list);
+	INFO("mtd%d: [%s] erase_size = %dKiB [%d]", dev->mtd.index,
+			dev->mtd.name + strlen("blkmtd: "),
+			dev->mtd.erasesize >> 10, dev->mtd.erasesize);
+	return dev;
+
+devinit_err:
+	block2mtd_free_device(dev);
+	return NULL;
+}
+
+
+static int ustrtoul(const char *cp, char **endp, unsigned int base)
+{
+	unsigned long result = simple_strtoul(cp, endp, base);
+	switch (**endp) {
+	case 'G' :
+		result *= 1024;
+	case 'M':
+		result *= 1024;
+	case 'k':
+		result *= 1024;
+	/* By dwmw2 editorial decree, "ki", "Mi" or "Gi" are to be used. */
+		if ((*endp)[1] == 'i')
+			(*endp) += 2;
+	}
+	return result;
+}
+
+
+static int parse_num32(u32 *num32, const char *token)
+{
+	char *endp;
+	unsigned long n;
+
+	n = ustrtoul(token, &endp, 0);
+	if (*endp)
+		return -EINVAL;
+
+	*num32 = n;
+	return 0;
+}
+
+
+static int parse_name(char **pname, const char *token, size_t limit)
+{
+	size_t len;
+	char *name;
+
+	len = strlen(token) + 1;
+	if (len > limit)
+		return -ENOSPC;
+
+	name = kmalloc(len, GFP_KERNEL);
+	if (!name)
+		return -ENOMEM;
+
+	strcpy(name, token);
+
+	*pname = name;
+	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("block2mtd: " fmt "\n", ## args);	\
+	return 0;				\
+} while (0)
+
+static int block2mtd_setup(const char *val, struct kernel_param *kp)
+{
+	char buf[80+12], *str=buf; /* 80 for device, 12 for erase size */
+	char *token[2];
+	char *name;
+	u32 erase_size = PAGE_SIZE;
+	int i, ret;
+
+	if (strnlen(val, sizeof(buf)) >= sizeof(buf))
+		parse_err("parameter too long");
+
+	strcpy(str, val);
+	kill_final_newline(str);
+
+	for (i=0; i<2; i++)
+		token[i] = strsep(&str, ",");
+
+	if (str)
+		parse_err("too many arguments");
+
+	if (!token[0])
+		parse_err("no argument");
+
+	ret = parse_name(&name, token[0], 80);
+	if (ret == -ENOMEM)
+		parse_err("out of memory");
+	if (ret == -ENOSPC)
+		parse_err("name too long");
+	if (ret)
+		return 0;
+
+	if (token[1]) {
+		ret = parse_num32(&erase_size, token[1]);
+		if (ret)
+			parse_err("illegal erase size");
+	}
+
+	add_device(name, erase_size);
+
+	return 0;
+}
+
+
+module_param_call(block2mtd, block2mtd_setup, NULL, NULL, 0200);
+MODULE_PARM_DESC(block2mtd, "Device to use. \"block2mtd=<dev>[,<erasesize>]\"");
+
+static int __init block2mtd_init(void)
+{
+	INFO("version " VERSION);
+	return 0;
+}
+
+
+static void __devexit block2mtd_exit(void)
+{
+	struct list_head *pos, *next;
+
+	/* Remove the MTD devices */
+	list_for_each_safe(pos, next, &blkmtd_device_list) {
+		struct block2mtd_dev *dev = list_entry(pos, typeof(*dev), list);
+		block2mtd_sync(&dev->mtd);
+		del_mtd_device(&dev->mtd);
+		INFO("mtd%d: [%s] removed", dev->mtd.index,
+				dev->mtd.name + strlen("blkmtd: "));
+		list_del(&dev->list);
+		block2mtd_free_device(dev);
+	}
+}
+
+
+module_init(block2mtd_init);
+module_exit(block2mtd_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Simon Evans <spse@secret.org.uk> and others");
+MODULE_DESCRIPTION("Emulate an MTD using a block device");
diff -Nru a/drivers/mtd/devices/doc1000.c b/drivers/mtd/devices/doc1000.c
--- a/drivers/mtd/devices/doc1000.c	2005-03-01 23:39:07 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,594 +0,0 @@
-/*======================================================================
-
-  $Id: doc1000.c,v 1.15 2001/10/02 15:05:13 dwmw2 Exp $
-
-======================================================================*/
-
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <asm/uaccess.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/major.h>
-#include <linux/fs.h>
-#include <linux/ioctl.h>
-#include <asm/io.h>
-#include <asm/system.h>
-#include <stdarg.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/iflash.h>
-
-/* Parameters that can be set with 'insmod' */
-
-static u_long base              = 0xe0000;
-static int erase_timeout	= 10*HZ;	/* in ticks */
-static int retry_limit		= 4;		/* write retries */
-static u_long max_tries       	= 4096;		/* status polling */
-
-MODULE_PARM(base,"l");
-MODULE_PARM(erase_timeout, "i");
-MODULE_PARM(retry_limit, "i");
-MODULE_PARM(max_tries, "i");
-
-#define WINDOW_SIZE 0x2000
-#define WINDOW_MASK (WINDOW_SIZE - 1)
-#define PAGEREG_LO (WINDOW_SIZE)
-#define PAGEREG_HI (WINDOW_SIZE + 2)
-
-static struct mtd_info *mymtd;
-static struct timer_list flashcard_timer;
-
-#define MAX_CELLS		32
-#define MAX_FLASH_DEVICES       8
-
-/* A flash region is composed of one or more "cells", where we allow
-   simultaneous erases if they are in different cells */
-
-
-
-struct mypriv {
-	u_char *baseaddr;
-	u_short curpage;
-	u_char locked;
-	u_short numdevices;
-	u_char interleave;
-	struct erase_info *cur_erases;
-	wait_queue_head_t wq;
-	u_char devstat[MAX_FLASH_DEVICES];
-	u_long devshift;
-};
-
-
-static void flashcard_periodic(u_long data);
-static int flashcard_erase (struct mtd_info *mtd, struct erase_info *instr);
-static int flashcard_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
-static int flashcard_write (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf);
-static void flashcard_sync (struct mtd_info *mtd);
-
-static inline void resume_erase(volatile u_char *addr);
-static inline int suspend_erase(volatile u_char *addr);
-static inline int byte_write (volatile u_char *addr, u_char byte);
-static inline int word_write (volatile u_char *addr, __u16 word);
-static inline int check_write(volatile u_char *addr);
-static inline void block_erase (volatile u_char *addr);
-static inline int check_erase(volatile u_char *addr);
-
-#ifdef CONFIG_SMP
-#warning This is definitely not SMP safe. Lock the paging mechanism.
-#endif
-
-static u_char *pagein(struct mtd_info *mtd, u_long addr)
-{
-  struct mypriv *priv=mtd->priv;
-  u_short page = addr >> 13;
-
-  priv->baseaddr[PAGEREG_LO] = page & 0xff;
-  priv->baseaddr[PAGEREG_HI] = page >> 8;
-  priv->curpage = page;
-  
-  return &priv->baseaddr[addr & WINDOW_MASK];
-}
-
-
-void flashcard_sync (struct mtd_info *mtd)
-{
-	struct mypriv *priv=mtd->priv;
-
-	flashcard_periodic((u_long) mtd);
-	printk("sync...");
-	if (priv->cur_erases)
-		interruptible_sleep_on(&priv->wq);
-	printk("Done.\n");
-}
-
-int flashcard_erase (struct mtd_info *mtd, struct erase_info *instr)
-{
-	u_char *pageaddr;
-	struct mypriv *priv=mtd->priv;
-	struct erase_info **tmp=&priv->cur_erases;
-	
-	if (instr->len != mtd->erasesize)
-		return -EINVAL;
-	if (instr->addr + instr->len > mtd->size)
-		return -EINVAL;
-
-	pageaddr=pagein(mtd,instr->addr);
-	instr->mtd = mtd;
-	instr->dev = instr->addr >> priv->devshift;
-	instr->cell = (instr->addr - (instr->dev << priv->devshift)) / mtd->erasesize;
-	instr->next = NULL;
-	instr->state = MTD_ERASE_PENDING;
-	
-	while (*tmp)
-	{
-		tmp = &((*tmp) -> next);
-	}
-	
-	*tmp = instr;
-	flashcard_periodic((u_long)mtd);
-	return 0;
-}
-
-
-int flashcard_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
-{
- 	u_char *pageaddr=pagein(mtd,from);
-	struct mypriv *priv=mtd->priv;
-	u_char device = from >> priv->devshift;
-	u_char cell = (int) (from - (device << priv->devshift)) / mtd->erasesize;
-	int ret = 0, timeron = 0;
-
-	if ((from & WINDOW_MASK) + len <= WINDOW_SIZE)
-		*retlen = len;
-	else
-		*retlen = WINDOW_SIZE - (from & WINDOW_MASK);
-
-	if (priv->devstat[device])
-	{
-		
-		/* There is an erase in progress or pending for this device. Stop it */
-		timeron = del_timer(&flashcard_timer);
-		
-		if (priv->cur_erases && priv->cur_erases->cell == cell) 
-			
-		{
-			/* The erase is on the current cell. Just return all 0xff */ 
-			add_timer(&flashcard_timer);
-			
-			
-			printk("Cell %d currently erasing. Setting to all 0xff\n",cell);
-			memset(buf, 0xff, *retlen);
-			return 0;
-		}
-		if (priv->devstat[device] == MTD_ERASING)
-		{
-			ret = suspend_erase(pageaddr);
-			priv->devstat[device] = MTD_ERASE_SUSPEND;
-		       
-			if (ret) 
-			{
-				printk("flashcard: failed to suspend erase\n");
-				add_timer (&flashcard_timer);
-				return ret;
-			}
-		}
-
-	}
-
-	writew(IF_READ_ARRAY, (u_long)pageaddr & ~1);
-	
-	ret = 0;
-	memcpy (buf, pageaddr, *retlen);
-	
-	writew(IF_READ_CSR, (u_long)pageaddr & ~1);
-	
-	
-	if (priv->devstat[device] & MTD_ERASE_SUSPEND)
-	{
-		resume_erase(pageaddr);
-		priv->devstat[device]=MTD_ERASING;
-	}
-
-
-	if (timeron) add_timer (&flashcard_timer);
-		
-	return ret;
-}
-
-
-int flashcard_write (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf)
-{
-	struct mypriv *priv = (struct mypriv *)mtd->priv;
- 	u_char *endaddr, *startaddr;
-	register u_char *pageaddr;
-	u_char device = to >> priv->devshift;
-/*	jiffies_t oldj=jiffies;*/
-	int ret;
-
-	while (priv->devstat[device])
-	{
-		flashcard_sync(mtd);
-	}
-
-	if ((to & WINDOW_MASK) + len <= WINDOW_SIZE)
-		*retlen = len;
-	else
-		*retlen = WINDOW_SIZE - (to & WINDOW_MASK);
-	
-	pageaddr = pagein(mtd, to);
-	startaddr = (u_char *)((u_long) pageaddr & ~1);
-	endaddr = pageaddr+(*retlen);
-
-
-
-	/* Set up to read */
-	writew(IF_READ_CSR, startaddr);
-	
-	/* Make sure it's aligned by reading the first byte if necessary */
-	if (to & 1)
-	{
-		/* Unaligned access */
-
-		u_char cbuf;
-
-		cbuf = *buf;
-
-		if (!((u_long)pageaddr & 0xf))
-			schedule();
-			
-		ret = byte_write(pageaddr, cbuf);
-		if (ret) return ret;
-
-		pageaddr++; buf++;
-	}
-
-
-	for ( ; pageaddr + 1 < endaddr; buf += 2, pageaddr += 2)
-		{
-			/* if ((u_long)pageaddr & 0xf) schedule();*/
-			
-			ret = word_write(pageaddr, *(__u16 *)buf);
-			if (ret) 
-				return ret;
-		}
-	
-	if (pageaddr != endaddr)
-	{
-		/* One more byte to write at the end. */
-		u_char cbuf;
-
-		cbuf = *buf;
-
-		ret = byte_write(pageaddr, cbuf);
-
-		if (ret) return ret;
-	}
-
-	return check_write(startaddr);
-/*	printk("Time taken in flashcard_write: %lx jiffies\n",jiffies - oldj);*/
-}
-
-
-
-
-/*====================================================================*/
-
-static inline int byte_write (volatile u_char *addr, u_char byte)
-{
-	register u_char status;
-	register u_short i = 0;
-
-	do {
-		status = readb(addr);
-		if (status & CSR_WR_READY)
-		{
-			writeb(IF_WRITE & 0xff, addr);
-			writeb(byte, addr);
-			return 0;
-		}
-		i++;
-	} while(i < max_tries);
-
-		
-	printk(KERN_NOTICE "flashcard: byte_write timed out, status 0x%x\n",status);
-	return -EIO;
-}
-
-static inline int word_write (volatile u_char *addr, __u16 word)
-{
-	register u_short status;
-	register u_short i = 0;
-	
-	do {
-		status = readw(addr);
-		if ((status & CSR_WR_READY) == CSR_WR_READY)
-		{
-			writew(IF_WRITE, addr);
-			writew(word, addr);
-			return 0;
-		}
-		i++;
-	} while(i < max_tries);
-		
-	printk(KERN_NOTICE "flashcard: word_write timed out at %p, status 0x%x\n", addr, status);
-	return -EIO;
-}
-
-static inline void block_erase (volatile u_char *addr)
-{
-	writew(IF_BLOCK_ERASE, addr);
-	writew(IF_CONFIRM, addr);
-}
-
-
-static inline int check_erase(volatile u_char *addr)
-{
-	__u16 status;
-	
-/*	writew(IF_READ_CSR, addr);*/
-	status = readw(addr);
-	
-
-	if ((status & CSR_WR_READY) != CSR_WR_READY)
-		return -EBUSY;
-	
-	if (status & (CSR_ERA_ERR | CSR_VPP_LOW | CSR_WR_ERR)) 
-	{
-		printk(KERN_NOTICE "flashcard: erase failed, status 0x%x\n",
-		       status);
-		return -EIO;
-	}
-	
-	return 0;
-}
-
-static inline int suspend_erase(volatile u_char *addr)
-{
-	__u16 status;
-	u_long i = 0;
-	
-	writew(IF_ERASE_SUSPEND, addr);
-	writew(IF_READ_CSR, addr);
-	
-	do {
-		status = readw(addr);
-		if ((status & CSR_WR_READY) == CSR_WR_READY)
-			return 0;
-		i++;
-	} while(i < max_tries);
-
-	printk(KERN_NOTICE "flashcard: suspend_erase timed out, status 0x%x\n", status);
-	return -EIO;
-
-}
-
-static inline void resume_erase(volatile u_char *addr)
-{
-	__u16 status;
-	
-	writew(IF_READ_CSR, addr);
-	status = readw(addr);
-	
-	/* Only give resume signal if the erase is really suspended */
-	if (status & CSR_ERA_SUSPEND)
-		writew(IF_CONFIRM, addr);
-}
-
-static inline void reset_block(volatile u_char *addr)
-{
-	u_short i;
-	__u16 status;
-
-	writew(IF_CLEAR_CSR, addr);
-
-	for (i = 0; i < 100; i++) {
-		writew(IF_READ_CSR, addr);
-		status = readw(addr);
-		if (status != 0xffff) break;
-		udelay(1000);
-	}
-
-	writew(IF_READ_CSR, addr);
-}
-
-static inline int check_write(volatile u_char *addr)
-{
-	u_short status, i = 0;
-	
-	writew(IF_READ_CSR, addr);
-	
-	do {
-		status = readw(addr);
-		if (status & (CSR_WR_ERR | CSR_VPP_LOW))
-		{
-			printk(KERN_NOTICE "flashcard: write failure at %p, status 0x%x\n", addr, status);
-			reset_block(addr);
-			return -EIO;
-		}
-		if ((status & CSR_WR_READY) == CSR_WR_READY)
-			return 0;
-		i++;
-	} while (i < max_tries);
-
-	printk(KERN_NOTICE "flashcard: write timed out at %p, status 0x%x\n", addr, status);
-	return -EIO;
-}
-
-
-/*====================================================================*/
-
-
-
-static void flashcard_periodic(unsigned long data)
-{
-	register struct mtd_info *mtd = (struct mtd_info *)data;
-	register struct mypriv *priv = mtd->priv;
-	struct erase_info *erase = priv->cur_erases;
-	u_char *pageaddr;
-
-	del_timer (&flashcard_timer);
-
-	if (!erase)
-		return;
-
-	pageaddr = pagein(mtd, erase->addr);
-	
-	if (erase->state == MTD_ERASE_PENDING)
-	{
-		block_erase(pageaddr);
-		priv->devstat[erase->dev] = erase->state = MTD_ERASING;
-		erase->time = jiffies;
-		erase->retries = 0;
-	}
-	else if (erase->state == MTD_ERASING)
-	{
-		/* It's trying to erase. Check whether it's finished */
-
-		int ret = check_erase(pageaddr);
-
-		if (!ret)
-		{
-			/* It's finished OK */
-			priv->devstat[erase->dev] = 0;
-			priv->cur_erases = erase->next;
-			erase->state = MTD_ERASE_DONE;
-			if (erase->callback)
-				(*(erase->callback))(erase);
-			else
-				kfree(erase);
-		}
-		else if (ret == -EIO)
-		{
-			if (++erase->retries > retry_limit)
-			{
-				printk("Failed too many times. Giving up\n");
-				priv->cur_erases = erase->next;
-				priv->devstat[erase->dev] = 0;
-				erase->state = MTD_ERASE_FAILED;
-				if (erase->callback)
-					(*(erase->callback))(erase);
-				else
-					kfree(erase);
-			}
-			else
-				priv->devstat[erase->dev] = erase->state = MTD_ERASE_PENDING;
-		}
-		else if (erase->time + erase_timeout < jiffies)
-		{
-			printk("Flash erase timed out. The world is broken.\n");
-
-			/* Just ignore and hope it goes away. For a while, read ops will give the CSR
-			   and writes won't work. */
-
-			priv->cur_erases = erase->next;
-			priv->devstat[erase->dev] = 0;
-			erase->state = MTD_ERASE_FAILED;
-			if (erase->callback)
-					(*(erase->callback))(erase);
-				else
-					kfree(erase);
-		}
-	}
-
-	if (priv->cur_erases)
-	{
-		flashcard_timer.expires = jiffies + HZ;
-		add_timer (&flashcard_timer);
-	}
-	else 
-		wake_up_interruptible(&priv->wq);
-
-}
-
-int __init init_doc1000(void)
-{
-	struct mypriv *priv;
-
-	if (!base)
-	{
-		printk(KERN_NOTICE "flashcard: No start address for memory device.\n");
-		return -EINVAL;
-	}
-
-	mymtd  = kmalloc(sizeof(struct mtd_info), GFP_KERNEL);
-
-	if (!mymtd)
-	{
-		printk(KERN_NOTICE "physmem: Cannot allocate memory for new MTD device.\n");
-		return -ENOMEM;
-	}
-
-	memset(mymtd,0,sizeof(struct mtd_info));
-
-	mymtd->priv = (void *) kmalloc (sizeof(struct mypriv), GFP_KERNEL);
-	if (!mymtd->priv)
-	  {
-	    kfree(mymtd);
-	    printk(KERN_NOTICE "physmem: Cannot allocate memory for new MTD device's private data.\n");
-	    return -ENOMEM;
-	  }
-	
-
-
-
-	priv=mymtd->priv;
-	init_waitqueue_head(&priv->wq);
-
-	memset (priv,0,sizeof(struct mypriv));
-
-	priv->baseaddr = phys_to_virt(base);
-	priv->numdevices = 4;
-	
-	mymtd->name = "M-Systems DiskOnChip 1000";
-
-	mymtd->size = 0x100000;
-	mymtd->flags = MTD_CLEAR_BITS | MTD_ERASEABLE;
-        mymtd->erase = flashcard_erase;
-	mymtd->point = NULL;
-	mymtd->unpoint = NULL;
-	mymtd->read = flashcard_read;
-	mymtd->write = flashcard_write;
-
-	mymtd->sync = flashcard_sync;
-	mymtd->erasesize = 0x10000;
-	//	mymtd->interleave = 2;
-	priv->devshift =  24;
-	mymtd->type = MTD_NORFLASH;
-	
-	if (add_mtd_device(mymtd))
-	{
-		printk(KERN_NOTICE "MTD device registration failed!\n");
-		kfree(mymtd->priv);
-		kfree(mymtd);
-		return -EAGAIN;
-	}
-	
-	init_timer(&flashcard_timer);
-	flashcard_timer.function = flashcard_periodic;
-	flashcard_timer.data = (u_long)mymtd;
-	return 0;
-}
-
-static void __init cleanup_doc1000(void)
-{
-	kfree (mymtd->priv);
-	del_mtd_device(mymtd);
-	kfree(mymtd);
-}
-
-module_init(init_doc1000);
-module_exit(cleanup_doc1000);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
-MODULE_DESCRIPTION("MTD driver for DiskOnChip 1000");
-
diff -Nru a/drivers/mtd/devices/doc2000.c b/drivers/mtd/devices/doc2000.c
--- a/drivers/mtd/devices/doc2000.c	2005-03-01 23:38:44 -08:00
+++ b/drivers/mtd/devices/doc2000.c	2005-03-01 23:38:44 -08:00
@@ -4,7 +4,7 @@
  * (c) 1999 Machine Vision Holdings, Inc.
  * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
  *
- * $Id: doc2000.c,v 1.64 2004/11/16 18:29:01 dwmw2 Exp $
+ * $Id: doc2000.c,v 1.66 2005/01/05 18:05:12 dwmw2 Exp $
  */
 
 #include <linux/kernel.h>
@@ -527,26 +527,26 @@
  */
 static void DoC2k_init(struct mtd_info *mtd)
 {
-	struct DiskOnChip *this = (struct DiskOnChip *) mtd->priv;
+	struct DiskOnChip *this = mtd->priv;
 	struct DiskOnChip *old = NULL;
 	int maxchips;
 
 	/* We must avoid being called twice for the same device. */
 
 	if (doc2klist)
-		old = (struct DiskOnChip *) doc2klist->priv;
+		old = doc2klist->priv;
 
 	while (old) {
 		if (DoC2k_is_alias(old, this)) {
 			printk(KERN_NOTICE
 			       "Ignoring DiskOnChip 2000 at 0x%lX - already configured\n",
 			       this->physadr);
-			iounmap((void *) this->virtadr);
+			iounmap(this->virtadr);
 			kfree(mtd);
 			return;
 		}
 		if (old->nextdoc)
-			old = (struct DiskOnChip *) old->nextdoc->priv;
+			old = old->nextdoc->priv;
 		else
 			old = NULL;
 	}
@@ -573,7 +573,7 @@
 	default:
 		printk("Unknown ChipID 0x%02x\n", this->ChipID);
 		kfree(mtd);
-		iounmap((void *) this->virtadr);
+		iounmap(this->virtadr);
 		return;
 	}
 
@@ -612,7 +612,7 @@
 
 	if (!this->totlen) {
 		kfree(mtd);
-		iounmap((void *) this->virtadr);
+		iounmap(this->virtadr);
 	} else {
 		this->nextdoc = doc2klist;
 		doc2klist = mtd;
@@ -633,7 +633,7 @@
 static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
 			size_t * retlen, u_char * buf, u_char * eccbuf, struct nand_oobinfo *oobsel)
 {
-	struct DiskOnChip *this = (struct DiskOnChip *) mtd->priv;
+	struct DiskOnChip *this = mtd->priv;
 	void __iomem *docptr = this->virtadr;
 	struct Nand *mychip;
 	unsigned char syndrome[6];
@@ -790,7 +790,7 @@
 			 size_t * retlen, const u_char * buf,
 			 u_char * eccbuf, struct nand_oobinfo *oobsel)
 {
-	struct DiskOnChip *this = (struct DiskOnChip *) mtd->priv;
+	struct DiskOnChip *this = mtd->priv;
 	int di; /* Yes, DI is a hangover from when I was disassembling the binary driver */
 	void __iomem *docptr = this->virtadr;
 	volatile char dummy;
@@ -1033,7 +1033,7 @@
 static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
 			size_t * retlen, u_char * buf)
 {
-	struct DiskOnChip *this = (struct DiskOnChip *) mtd->priv;
+	struct DiskOnChip *this = mtd->priv;
 	int len256 = 0, ret;
 	struct Nand *mychip;
 
@@ -1091,7 +1091,7 @@
 static int doc_write_oob_nolock(struct mtd_info *mtd, loff_t ofs, size_t len,
 				size_t * retlen, const u_char * buf)
 {
-	struct DiskOnChip *this = (struct DiskOnChip *) mtd->priv;
+	struct DiskOnChip *this = mtd->priv;
 	int len256 = 0;
 	void __iomem *docptr = this->virtadr;
 	struct Nand *mychip = &this->chips[ofs >> this->chipshift];
@@ -1194,7 +1194,7 @@
 static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
  			 size_t * retlen, const u_char * buf)
 {
- 	struct DiskOnChip *this = (struct DiskOnChip *) mtd->priv;
+ 	struct DiskOnChip *this = mtd->priv;
  	int ret;
 
  	down(&this->lock);
@@ -1206,7 +1206,7 @@
 
 static int doc_erase(struct mtd_info *mtd, struct erase_info *instr)
 {
-	struct DiskOnChip *this = (struct DiskOnChip *) mtd->priv;
+	struct DiskOnChip *this = mtd->priv;
 	__u32 ofs = instr->addr;
 	__u32 len = instr->len;
 	volatile int dummy;
@@ -1288,12 +1288,12 @@
 	struct DiskOnChip *this;
 
 	while ((mtd = doc2klist)) {
-		this = (struct DiskOnChip *) mtd->priv;
+		this = mtd->priv;
 		doc2klist = this->nextdoc;
 
 		del_mtd_device(mtd);
 
-		iounmap((void *) this->virtadr);
+		iounmap(this->virtadr);
 		kfree(this->chips);
 		kfree(mtd);
 	}
diff -Nru a/drivers/mtd/devices/doc2001.c b/drivers/mtd/devices/doc2001.c
--- a/drivers/mtd/devices/doc2001.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/mtd/devices/doc2001.c	2005-03-01 23:38:54 -08:00
@@ -4,7 +4,7 @@
  * (c) 1999 Machine Vision Holdings, Inc.
  * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
  *
- * $Id: doc2001.c,v 1.46 2004/11/16 18:29:01 dwmw2 Exp $
+ * $Id: doc2001.c,v 1.48 2005/01/05 18:05:12 dwmw2 Exp $
  */
 
 #include <linux/kernel.h>
@@ -335,23 +335,23 @@
  */
 static void DoCMil_init(struct mtd_info *mtd)
 {
-	struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv;
+	struct DiskOnChip *this = mtd->priv;
 	struct DiskOnChip *old = NULL;
 
 	/* We must avoid being called twice for the same device. */
 	if (docmillist)
-		old = (struct DiskOnChip *)docmillist->priv;
+		old = docmillist->priv;
 
 	while (old) {
 		if (DoCMil_is_alias(this, old)) {
 			printk(KERN_NOTICE "Ignoring DiskOnChip Millennium at "
 			       "0x%lX - already configured\n", this->physadr);
-			iounmap((void *)this->virtadr);
+			iounmap(this->virtadr);
 			kfree(mtd);
 			return;
 		}
 		if (old->nextdoc)
-			old = (struct DiskOnChip *)old->nextdoc->priv;
+			old = old->nextdoc->priv;
 		else
 			old = NULL;
 	}
@@ -392,7 +392,7 @@
 
 	if (!this->totlen) {
 		kfree(mtd);
-		iounmap((void *)this->virtadr);
+		iounmap(this->virtadr);
 	} else {
 		this->nextdoc = docmillist;
 		docmillist = mtd;
@@ -416,7 +416,7 @@
 	int i, ret;
 	volatile char dummy;
 	unsigned char syndrome[6];
-	struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv;
+	struct DiskOnChip *this = mtd->priv;
 	void __iomem *docptr = this->virtadr;
 	struct Nand *mychip = &this->chips[from >> (this->chipshift)];
 
@@ -542,7 +542,7 @@
 {
 	int i,ret = 0;
 	volatile char dummy;
-	struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv;
+	struct DiskOnChip *this = mtd->priv;
 	void __iomem *docptr = this->virtadr;
 	struct Nand *mychip = &this->chips[to >> (this->chipshift)];
 
@@ -677,7 +677,7 @@
 	int i;
 #endif
 	volatile char dummy;
-	struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv;
+	struct DiskOnChip *this = mtd->priv;
 	void __iomem *docptr = this->virtadr;
 	struct Nand *mychip = &this->chips[ofs >> this->chipshift];
 
@@ -729,7 +729,7 @@
 #endif
 	volatile char dummy;
 	int ret = 0;
-	struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv;
+	struct DiskOnChip *this = mtd->priv;
 	void __iomem *docptr = this->virtadr;
 	struct Nand *mychip = &this->chips[ofs >> this->chipshift];
 
@@ -796,7 +796,7 @@
 int doc_erase (struct mtd_info *mtd, struct erase_info *instr)
 {
 	volatile char dummy;
-	struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv;
+	struct DiskOnChip *this = mtd->priv;
 	__u32 ofs = instr->addr;
 	__u32 len = instr->len;
 	void __iomem *docptr = this->virtadr;
@@ -868,12 +868,12 @@
 	struct DiskOnChip *this;
 
 	while ((mtd=docmillist)) {
-		this = (struct DiskOnChip *)mtd->priv;
+		this = mtd->priv;
 		docmillist = this->nextdoc;
 			
 		del_mtd_device(mtd);
 			
-		iounmap((void *)this->virtadr);
+		iounmap(this->virtadr);
 		kfree(this->chips);
 		kfree(mtd);
 	}
diff -Nru a/drivers/mtd/devices/doc2001plus.c b/drivers/mtd/devices/doc2001plus.c
--- a/drivers/mtd/devices/doc2001plus.c	2005-03-01 23:38:44 -08:00
+++ b/drivers/mtd/devices/doc2001plus.c	2005-03-01 23:38:44 -08:00
@@ -6,7 +6,7 @@
  * (c) 1999 Machine Vision Holdings, Inc.
  * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
  *
- * $Id: doc2001plus.c,v 1.11 2004/11/16 18:29:01 dwmw2 Exp $
+ * $Id: doc2001plus.c,v 1.13 2005/01/05 18:05:12 dwmw2 Exp $
  *
  * Released under GPL
  */
@@ -190,7 +190,7 @@
    may not want it */
 static unsigned int DoC_GetDataOffset(struct mtd_info *mtd, loff_t *from)
 {
-	struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv;
+	struct DiskOnChip *this = mtd->priv;
 
 	if (this->interleave) {
 		unsigned int ofs = *from & 0x3ff;
@@ -458,24 +458,24 @@
  */
 static void DoCMilPlus_init(struct mtd_info *mtd)
 {
-	struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv;
+	struct DiskOnChip *this = mtd->priv;
 	struct DiskOnChip *old = NULL;
 
 	/* We must avoid being called twice for the same device. */
 	if (docmilpluslist)
-		old = (struct DiskOnChip *)docmilpluslist->priv;
+		old = docmilpluslist->priv;
 
 	while (old) {
 		if (DoCMilPlus_is_alias(this, old)) {
 			printk(KERN_NOTICE "Ignoring DiskOnChip Millennium "
 				"Plus at 0x%lX - already configured\n",
 				this->physadr);
-			iounmap((void *)this->virtadr);
+			iounmap(this->virtadr);
 			kfree(mtd);
 			return;
 		}
 		if (old->nextdoc)
-			old = (struct DiskOnChip *)old->nextdoc->priv;
+			old = old->nextdoc->priv;
 		else
 			old = NULL;
 	}
@@ -514,7 +514,7 @@
 
 	if (!this->totlen) {
 		kfree(mtd);
-		iounmap((void *)this->virtadr);
+		iounmap(this->virtadr);
 	} else {
 		this->nextdoc = docmilpluslist;
 		docmilpluslist = mtd;
@@ -530,7 +530,7 @@
 {
 	int i;
 	loff_t fofs;
-	struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv;
+	struct DiskOnChip *this = mtd->priv;
 	void __iomem * docptr = this->virtadr;
 	struct Nand *mychip = &this->chips[from >> (this->chipshift)];
 	unsigned char *bp, buf[1056];
@@ -615,7 +615,7 @@
 	volatile char dummy;
 	loff_t fofs;
 	unsigned char syndrome[6];
-	struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv;
+	struct DiskOnChip *this = mtd->priv;
 	void __iomem * docptr = this->virtadr;
 	struct Nand *mychip = &this->chips[from >> (this->chipshift)];
 
@@ -754,7 +754,7 @@
 	int i, before, ret = 0;
 	loff_t fto;
 	volatile char dummy;
-	struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv;
+	struct DiskOnChip *this = mtd->priv;
 	void __iomem * docptr = this->virtadr;
 	struct Nand *mychip = &this->chips[to >> (this->chipshift)];
 
@@ -880,7 +880,7 @@
 			size_t *retlen, u_char *buf)
 {
 	loff_t fofs, base;
-	struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv;
+	struct DiskOnChip *this = mtd->priv;
 	void __iomem * docptr = this->virtadr;
 	struct Nand *mychip = &this->chips[ofs >> this->chipshift];
 	size_t i, size, got, want;
@@ -958,7 +958,7 @@
 {
 	volatile char dummy;
 	loff_t fofs, base;
-	struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv;
+	struct DiskOnChip *this = mtd->priv;
 	void __iomem * docptr = this->virtadr;
 	struct Nand *mychip = &this->chips[ofs >> this->chipshift];
 	size_t i, size, got, want;
@@ -1058,7 +1058,7 @@
 int doc_erase(struct mtd_info *mtd, struct erase_info *instr)
 {
 	volatile char dummy;
-	struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv;
+	struct DiskOnChip *this = mtd->priv;
 	__u32 ofs = instr->addr;
 	__u32 len = instr->len;
 	void __iomem * docptr = this->virtadr;
@@ -1134,12 +1134,12 @@
 	struct DiskOnChip *this;
 
 	while ((mtd=docmilpluslist)) {
-		this = (struct DiskOnChip *)mtd->priv;
+		this = mtd->priv;
 		docmilpluslist = this->nextdoc;
 			
 		del_mtd_device(mtd);
 			
-		iounmap((void *)this->virtadr);
+		iounmap(this->virtadr);
 		kfree(this->chips);
 		kfree(mtd);
 	}
diff -Nru a/drivers/mtd/devices/docprobe.c b/drivers/mtd/devices/docprobe.c
--- a/drivers/mtd/devices/docprobe.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/mtd/devices/docprobe.c	2005-03-01 23:39:08 -08:00
@@ -4,7 +4,7 @@
 /* (C) 1999 Machine Vision Holdings, Inc.			*/
 /* (C) 1999-2003 David Woodhouse <dwmw2@infradead.org>		*/
 
-/* $Id: docprobe.c,v 1.43 2004/11/16 18:29:01 dwmw2 Exp $	*/
+/* $Id: docprobe.c,v 1.44 2005/01/05 12:40:36 dwmw2 Exp $	*/
 
 
 
@@ -62,7 +62,7 @@
 
 
 static unsigned long doc_config_location = CONFIG_MTD_DOCPROBE_ADDRESS;
-MODULE_PARM(doc_config_location, "l");
+module_param(doc_config_location, ulong, 0);
 MODULE_PARM_DESC(doc_config_location, "Physical memory address at which to probe for DiskOnChip");
 
 static unsigned long __initdata doc_locations[] = {
@@ -94,9 +94,9 @@
 
 /* doccheck: Probe a given memory window to see if there's a DiskOnChip present */
 
-static inline int __init doccheck(unsigned long potential, unsigned long physadr)
+static inline int __init doccheck(void __iomem *potential, unsigned long physadr)
 {
-	unsigned long window=potential;
+	void __iomem *window=potential;
 	unsigned char tmp, tmpb, tmpc, ChipID;
 #ifndef DOC_PASSIVE_PROBE
 	unsigned char tmp2;
@@ -233,7 +233,7 @@
 
 static void __init DoC_Probe(unsigned long physadr)
 {
-	unsigned long docptr;
+	void __iomem *docptr;
 	struct DiskOnChip *this;
 	struct mtd_info *mtd;
 	int ChipID;
@@ -243,7 +243,7 @@
 	char *im_modname = NULL;
 	void (*initroutine)(struct mtd_info *) = NULL;
 
-	docptr = (unsigned long)ioremap(physadr, DOC_IOREMAP_LEN);
+	docptr = ioremap(physadr, DOC_IOREMAP_LEN);
 	
 	if (!docptr)
 		return;
@@ -252,7 +252,7 @@
 		if (ChipID == DOC_ChipID_Doc2kTSOP) {
 			/* Remove this at your own peril. The hardware driver works but nothing prevents you from erasing bad blocks */
 			printk(KERN_NOTICE "Refusing to drive DiskOnChip 2000 TSOP until Bad Block Table is correctly supported by INFTL\n");
-			iounmap((void *)docptr);
+			iounmap(docptr);
 			return;
 		}
 		docfound = 1;
@@ -260,7 +260,7 @@
 
 		if (!mtd) {
 			printk(KERN_WARNING "Cannot allocate memory for data structures. Dropping.\n");
-			iounmap((void *)docptr);
+			iounmap(docptr);
 			return;
 		}
 		
@@ -270,7 +270,7 @@
 		memset((char *)this, 0, sizeof(struct DiskOnChip));
 
 		mtd->priv = this;
-		this->virtadr = (void __iomem *)docptr;
+		this->virtadr = docptr;
 		this->physadr = physadr;
 		this->ChipID = ChipID;
 		sprintf(namebuf, "with ChipID %2.2X", ChipID);
@@ -318,7 +318,7 @@
 		printk(KERN_NOTICE "Cannot find driver for DiskOnChip %s at 0x%lX\n", name, physadr);
 		kfree(mtd);
 	}
-	iounmap((void *)docptr);
+	iounmap(docptr);
 }
 
 
diff -Nru a/drivers/mtd/devices/ms02-nv.c b/drivers/mtd/devices/ms02-nv.c
--- a/drivers/mtd/devices/ms02-nv.c	2005-03-01 23:38:51 -08:00
+++ b/drivers/mtd/devices/ms02-nv.c	2005-03-01 23:38:51 -08:00
@@ -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.7 2004/07/29 14:16:45 macro Exp $
+ *	$Id: ms02-nv.c,v 1.8 2005/01/05 18:05:12 dwmw2 Exp $
  */
 
 #include <linux/init.h>
@@ -59,7 +59,7 @@
 static int ms02nv_read(struct mtd_info *mtd, loff_t from,
 			size_t len, size_t *retlen, u_char *buf)
 {
-	struct ms02nv_private *mp = (struct ms02nv_private *)mtd->priv;
+	struct ms02nv_private *mp = mtd->priv;
 
 	if (from + len > mtd->size)
 		return -EINVAL;
@@ -73,7 +73,7 @@
 static int ms02nv_write(struct mtd_info *mtd, loff_t to,
 			size_t len, size_t *retlen, const u_char *buf)
 {
-	struct ms02nv_private *mp = (struct ms02nv_private *)mtd->priv;
+	struct ms02nv_private *mp = mtd->priv;
 
 	if (to + len > mtd->size)
 		return -EINVAL;
@@ -265,7 +265,7 @@
 static void __exit ms02nv_remove_one(void)
 {
 	struct mtd_info *mtd = root_ms02nv_mtd;
-	struct ms02nv_private *mp = (struct ms02nv_private *)mtd->priv;
+	struct ms02nv_private *mp = mtd->priv;
 
 	root_ms02nv_mtd = mp->next;
 
diff -Nru a/drivers/mtd/devices/mtdram.c b/drivers/mtd/devices/mtdram.c
--- a/drivers/mtd/devices/mtdram.c	2005-03-01 23:38:51 -08:00
+++ b/drivers/mtd/devices/mtdram.c	2005-03-01 23:38:51 -08:00
@@ -1,6 +1,6 @@
 /*
  * mtdram - a test mtd device
- * $Id: mtdram.c,v 1.34 2004/11/16 18:29:01 dwmw2 Exp $
+ * $Id: mtdram.c,v 1.35 2005/01/05 18:05:12 dwmw2 Exp $
  * Author: Alexander Larsson <alex@cendio.se>
  *
  * Copyright (c) 1999 Alexander Larsson <alex@cendio.se>
@@ -29,9 +29,9 @@
 #ifdef MODULE
 static unsigned long total_size = CONFIG_MTDRAM_TOTAL_SIZE;
 static unsigned long erase_size = CONFIG_MTDRAM_ERASE_SIZE;
-MODULE_PARM(total_size,"l");
+module_param(total_size,ulong,0);
 MODULE_PARM_DESC(total_size, "Total device size in KiB");
-MODULE_PARM(erase_size,"l");
+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)
@@ -158,7 +158,7 @@
   void *addr;
   int err;
   /* Allocate some memory */
-   mtd_info = (struct mtd_info *)kmalloc(sizeof(struct mtd_info), GFP_KERNEL);
+   mtd_info = kmalloc(sizeof(struct mtd_info), GFP_KERNEL);
    if (!mtd_info)
      return -ENOMEM;
    
@@ -191,7 +191,7 @@
   void *addr;
   int err;
   /* Allocate some memory */
-   mtd_info = (struct mtd_info *)kmalloc(sizeof(struct mtd_info), GFP_KERNEL);
+   mtd_info = kmalloc(sizeof(struct mtd_info), GFP_KERNEL);
    if (!mtd_info)
      return -ENOMEM;
 
diff -Nru a/drivers/mtd/devices/phram.c b/drivers/mtd/devices/phram.c
--- a/drivers/mtd/devices/phram.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/mtd/devices/phram.c	2005-03-01 23:39:17 -08:00
@@ -1,13 +1,8 @@
 /**
+ * $Id: phram.c,v 1.11 2005/01/05 18:05:13 dwmw2 Exp $
  *
- * $Id: phram.c,v 1.3 2004/11/16 18:29:01 dwmw2 Exp $
- *
- * Copyright (c) Jochen Schaeuble <psionic@psionic.de>
- * 07/2003	rewritten by Joern Engel <joern@wh.fh-wedel.de>
- *
- * DISCLAIMER:  This driver makes use of Rusty's excellent module code,
- * so it will not work for 2.4 without changes and it wont work for 2.4
- * as a module without major changes.  Oh well!
+ * Copyright (c) ????		Jochen Schäuble <psionic@psionic.de>
+ * Copyright (c) 2003-2004	Jörn Engel <joern@wh.fh-wedel.de>
  *
  * Usage:
  *
@@ -15,9 +10,12 @@
  *   phram=<name>,<start>,<len>
  * <name> may be up to 63 characters.
  * <start> and <len> can be octal, decimal or hexadecimal.  If followed
- * by "k", "M" or "G", the numbers will be interpreted as kilo, mega or
+ * by "ki", "Mi" or "Gi", the numbers will be interpreted as kilo, mega or
  * gigabytes.
  *
+ * Example:
+ *	phram=swap,64Mi,128Mi phram=test,900Mi,1Mi
+ *
  */
 
 #include <asm/io.h>
@@ -31,8 +29,8 @@
 #define ERROR(fmt, args...) printk(KERN_ERR "phram: " fmt , ## args)
 
 struct phram_mtd_list {
+	struct mtd_info mtd;
 	struct list_head list;
-	struct mtd_info *mtdinfo;
 };
 
 static LIST_HEAD(phram_list);
@@ -41,7 +39,7 @@
 
 static int phram_erase(struct mtd_info *mtd, struct erase_info *instr)
 {
-	u_char *start = (u_char *)mtd->priv;
+	u_char *start = mtd->priv;
 
 	if (instr->addr + instr->len > mtd->size)
 		return -EINVAL;
@@ -63,7 +61,7 @@
 static int phram_point(struct mtd_info *mtd, loff_t from, size_t len,
 		size_t *retlen, u_char **mtdbuf)
 {
-	u_char *start = (u_char *)mtd->priv;
+	u_char *start = mtd->priv;
 
 	if (from + len > mtd->size)
 		return -EINVAL;
@@ -80,7 +78,7 @@
 static int phram_read(struct mtd_info *mtd, loff_t from, size_t len,
 		size_t *retlen, u_char *buf)
 {
-	u_char *start = (u_char *)mtd->priv;
+	u_char *start = mtd->priv;
 
 	if (from + len > mtd->size)
 		return -EINVAL;
@@ -94,7 +92,7 @@
 static int phram_write(struct mtd_info *mtd, loff_t to, size_t len,
 		size_t *retlen, const u_char *buf)
 {
-	u_char *start = (u_char *)mtd->priv;
+	u_char *start = mtd->priv;
 
 	if (to + len > mtd->size)
 		return -EINVAL;
@@ -112,9 +110,8 @@
 	struct phram_mtd_list *this;
 
 	list_for_each_entry(this, &phram_list, list) {
-		del_mtd_device(this->mtdinfo);
-		iounmap(this->mtdinfo->priv);
-		kfree(this->mtdinfo);
+		del_mtd_device(&this->mtd);
+		iounmap(this->mtd.priv);
 		kfree(this);
 	}
 }
@@ -128,45 +125,39 @@
 	if (!new)
 		goto out0;
 
-	new->mtdinfo = kmalloc(sizeof(struct mtd_info), GFP_KERNEL);
-	if (!new->mtdinfo)
-		goto out1;
-	
-	memset(new->mtdinfo, 0, sizeof(struct mtd_info));
+	memset(new, 0, sizeof(*new));
 
 	ret = -EIO;
-	new->mtdinfo->priv = ioremap(start, len);
-	if (!new->mtdinfo->priv) {
+	new->mtd.priv = ioremap(start, len);
+	if (!new->mtd.priv) {
 		ERROR("ioremap failed\n");
-		goto out2;
+		goto out1;
 	}
 
 
-	new->mtdinfo->name = name;
-	new->mtdinfo->size = len;
-	new->mtdinfo->flags = MTD_CAP_RAM | MTD_ERASEABLE | MTD_VOLATILE;
-        new->mtdinfo->erase = phram_erase;
-	new->mtdinfo->point = phram_point;
-	new->mtdinfo->unpoint = phram_unpoint;
-	new->mtdinfo->read = phram_read;
-	new->mtdinfo->write = phram_write;
-	new->mtdinfo->owner = THIS_MODULE;
-	new->mtdinfo->type = MTD_RAM;
-	new->mtdinfo->erasesize = 0x0;
+	new->mtd.name = name;
+	new->mtd.size = len;
+	new->mtd.flags = MTD_CAP_RAM | MTD_ERASEABLE | MTD_VOLATILE;
+        new->mtd.erase = phram_erase;
+	new->mtd.point = phram_point;
+	new->mtd.unpoint = phram_unpoint;
+	new->mtd.read = phram_read;
+	new->mtd.write = phram_write;
+	new->mtd.owner = THIS_MODULE;
+	new->mtd.type = MTD_RAM;
+	new->mtd.erasesize = 0;
 
 	ret = -EAGAIN;
-	if (add_mtd_device(new->mtdinfo)) {
+	if (add_mtd_device(&new->mtd)) {
 		ERROR("Failed to register new device\n");
-		goto out3;
+		goto out2;
 	}
 
 	list_add_tail(&new->list, &phram_list);
 	return 0;	
 
-out3:
-	iounmap(new->mtdinfo->priv);
 out2:
-	kfree(new->mtdinfo);
+	iounmap(new->mtd.priv);
 out1:
 	kfree(new);
 out0:
@@ -184,7 +175,9 @@
 		result *= 1024;
 	case 'k':
 		result *= 1024;
-		endp++;
+	/* By dwmw2 editorial decree, "ki", "Mi" or "Gi" are to be used. */
+		if ((*endp)[1] == 'i')
+			(*endp) += 2;
 	}
 	return result;
 }
@@ -235,7 +228,7 @@
 	uint32_t len;
 	int i, ret;
 
-	if (strnlen(val, sizeof(str)) >= sizeof(str))
+	if (strnlen(val, sizeof(buf)) >= sizeof(buf))
 		parse_err("parameter too long\n");
 
 	strcpy(str, val);
@@ -271,78 +264,11 @@
 }
 
 module_param_call(phram, phram_setup, NULL, NULL, 000);
-MODULE_PARM_DESC(phram, "Memory region to map. \"map=<name>,<start><length>\"");
-
-/*
- * Just for compatibility with slram, this is horrible and should go someday.
- */
-static int __init slram_setup(const char *val, struct kernel_param *kp)
-{
-	char buf[256], *str = buf;
-
-	if (!val || !val[0])
-		parse_err("no arguments to \"slram=\"\n");
-
-	if (strnlen(val, sizeof(str)) >= sizeof(str))
-		parse_err("parameter too long\n");
-
-	strcpy(str, val);
-
-	while (str) {
-		char *token[3];
-		char *name;
-		uint32_t start;
-		uint32_t len;
-		int i, ret;
-
-		for (i=0; i<3; i++) {
-			token[i] = strsep(&str, ",");
-			if (token[i])
-				continue;
-			parse_err("wrong number of arguments to \"slram=\"\n");
-		}
-
-		/* name */
-		ret = parse_name(&name, token[0]);
-		if (ret == -ENOMEM)
-			parse_err("of memory\n");
-		if (ret == -ENOSPC)
-			parse_err("too long\n");
-		if (ret)
-			return 1;
-
-		/* start */
-		ret = parse_num32(&start, token[1]);
-		if (ret)
-			parse_err("illegal start address\n");
-
-		/* len */
-		if (token[2][0] == '+')
-			ret = parse_num32(&len, token[2] + 1);
-		else
-			ret = parse_num32(&len, token[2]);
-
-		if (ret)
-			parse_err("illegal device length\n");
-
-		if (token[2][0] != '+') {
-			if (len < start)
-				parse_err("end < start\n");
-			len -= start;
-		}
-
-		register_device(name, start, len);
-	}
-	return 1;
-}
-
-module_param_call(slram, slram_setup, NULL, NULL, 000);
-MODULE_PARM_DESC(slram, "List of memory regions to map. \"map=<name>,<start><length/end>\"");
+MODULE_PARM_DESC(phram,"Memory region to map. \"map=<name>,<start>,<length>\"");
 
 
 static int __init init_phram(void)
 {
-	printk(KERN_ERR "phram loaded\n");
 	return 0;
 }
 
diff -Nru a/drivers/mtd/devices/pmc551.c b/drivers/mtd/devices/pmc551.c
--- a/drivers/mtd/devices/pmc551.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/mtd/devices/pmc551.c	2005-03-01 23:39:08 -08:00
@@ -1,5 +1,5 @@
 /*
- * $Id: pmc551.c,v 1.29 2004/11/16 18:29:01 dwmw2 Exp $
+ * $Id: pmc551.c,v 1.30 2005/01/05 18:05:13 dwmw2 Exp $
  *
  * PMC551 PCI Mezzanine Ram Device
  *
@@ -113,7 +113,7 @@
 
 static int pmc551_erase (struct mtd_info *mtd, struct erase_info *instr)
 {
-        struct mypriv *priv = (struct mypriv *)mtd->priv;
+        struct mypriv *priv = mtd->priv;
         u32 soff_hi, soff_lo; /* start address offset hi/lo */
         u32 eoff_hi, eoff_lo; /* end address offset hi/lo */
         unsigned long end;
@@ -176,7 +176,7 @@
 
 static int pmc551_point (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf)
 {
-        struct mypriv *priv = (struct mypriv *)mtd->priv;
+        struct mypriv *priv = mtd->priv;
         u32 soff_hi;
         u32 soff_lo;
 
@@ -217,7 +217,7 @@
 
 static int pmc551_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
 {
-        struct mypriv *priv = (struct mypriv *)mtd->priv;
+        struct mypriv *priv = mtd->priv;
         u32 soff_hi, soff_lo; /* start address offset hi/lo */
         u32 eoff_hi, eoff_lo; /* end address offset hi/lo */
         unsigned long end;
@@ -279,7 +279,7 @@
 
 static int pmc551_write (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf)
 {
-        struct mypriv *priv = (struct mypriv *)mtd->priv;
+        struct mypriv *priv = mtd->priv;
         u32 soff_hi, soff_lo; /* start address offset hi/lo */
         u32 eoff_hi, eoff_lo; /* end address offset hi/lo */
         unsigned long end;
@@ -630,10 +630,6 @@
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Mark Ferrell <mferrell@mvista.com>");
 MODULE_DESCRIPTION(PMC551_VERSION);
-MODULE_PARM(msize, "i");
-MODULE_PARM_DESC(msize, "memory size in Megabytes [1 - 1024]");
-MODULE_PARM(asize, "i");
-MODULE_PARM_DESC(asize, "aperture size, must be <= memsize [1-1024]");
 
 /*
  * Stuff these outside the ifdef so as to not bust compiled in driver support
@@ -645,6 +641,11 @@
 static int asize=0;
 #endif
 
+module_param(msize, int, 0);
+MODULE_PARM_DESC(msize, "memory size in Megabytes [1 - 1024]");
+module_param(asize, int, 0);
+MODULE_PARM_DESC(asize, "aperture size, must be <= memsize [1-1024]");
+
 /*
  * PMC551 Card Initialization
  */
@@ -820,7 +821,7 @@
 	struct mypriv *priv;
 
 	while((mtd=pmc551list)) {
-		priv = (struct mypriv *)mtd->priv;
+		priv = mtd->priv;
 		pmc551list = priv->nextpmc551;
 		
 		if(priv->start) {
diff -Nru a/drivers/mtd/devices/slram.c b/drivers/mtd/devices/slram.c
--- a/drivers/mtd/devices/slram.c	2005-03-01 23:38:44 -08:00
+++ b/drivers/mtd/devices/slram.c	2005-03-01 23:38:44 -08:00
@@ -1,6 +1,6 @@
 /*======================================================================
 
-  $Id: slram.c,v 1.32 2004/11/16 18:29:01 dwmw2 Exp $
+  $Id: slram.c,v 1.33 2005/01/05 18:05:13 dwmw2 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
@@ -66,13 +66,13 @@
 
 #ifdef MODULE
 static char *map[SLRAM_MAX_DEVICES_PARAMS];
+
+module_param_array(map, charp, NULL, 0);
+MODULE_PARM_DESC(map, "List of memory regions to map. \"map=<name>, <start>, <length / end>\"");
 #else
 static char *map;
 #endif
 
-MODULE_PARM(map, "3-" __MODULE_STRING(SLRAM_MAX_DEVICES_PARAMS) "s");
-MODULE_PARM_DESC(map, "List of memory regions to map. \"map=<name>, <start>, <length / end>\"");
-
 static slram_mtd_list_t *slram_mtdlist = NULL;
 
 static int slram_erase(struct mtd_info *, struct erase_info *);
@@ -106,7 +106,7 @@
 static int slram_point(struct mtd_info *mtd, loff_t from, size_t len,
 		size_t *retlen, u_char **mtdbuf)
 {
-	slram_priv_t *priv = (slram_priv_t *)mtd->priv;
+	slram_priv_t *priv = mtd->priv;
 
 	*mtdbuf = priv->start + from;
 	*retlen = len;
@@ -120,7 +120,7 @@
 static int slram_read(struct mtd_info *mtd, loff_t from, size_t len,
 		size_t *retlen, u_char *buf)
 {
-	slram_priv_t *priv = (slram_priv_t *)mtd->priv;
+	slram_priv_t *priv = mtd->priv;
 	
 	memcpy(buf, priv->start + from, len);
 
@@ -131,7 +131,7 @@
 static int slram_write(struct mtd_info *mtd, loff_t to, size_t len,
 		size_t *retlen, const u_char *buf)
 {
-	slram_priv_t *priv = (slram_priv_t *)mtd->priv;
+	slram_priv_t *priv = mtd->priv;
 
 	memcpy(priv->start + to, buf, len);
 
@@ -161,7 +161,7 @@
 	if ((*curmtd)->mtdinfo)	{
 		memset((char *)(*curmtd)->mtdinfo, 0, sizeof(struct mtd_info));
 		(*curmtd)->mtdinfo->priv =
-			(void *)kmalloc(sizeof(slram_priv_t), GFP_KERNEL);
+			kmalloc(sizeof(slram_priv_t), GFP_KERNEL);
 		
 		if (!(*curmtd)->mtdinfo->priv) {
 			kfree((*curmtd)->mtdinfo);
diff -Nru a/drivers/mtd/ftl.c b/drivers/mtd/ftl.c
--- a/drivers/mtd/ftl.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/mtd/ftl.c	2005-03-01 23:39:09 -08:00
@@ -80,7 +80,7 @@
 
 /* Parameters that can be set with 'insmod' */
 static int shuffle_freq = 50;
-MODULE_PARM(shuffle_freq, "i");
+module_param(shuffle_freq, int, 0);
 
 /*====================================================================*/
 
diff -Nru a/drivers/mtd/inftlmount.c b/drivers/mtd/inftlmount.c
--- a/drivers/mtd/inftlmount.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/mtd/inftlmount.c	2005-03-01 23:38:52 -08:00
@@ -8,7 +8,7 @@
  * Author: Fabrice Bellard (fabrice.bellard@netgem.com) 
  * Copyright (C) 2000 Netgem S.A.
  *
- * $Id: inftlmount.c,v 1.15 2004/11/05 21:55:55 kalev Exp $
+ * $Id: inftlmount.c,v 1.16 2004/11/22 13:50:53 kalev 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
@@ -41,7 +41,7 @@
 #include <linux/mtd/inftl.h>
 #include <linux/mtd/compatmac.h>
 
-char inftlmountrev[]="$Revision: 1.15 $";
+char inftlmountrev[]="$Revision: 1.16 $";
 
 /*
  * find_boot_record: Find the INFTL Media Header and its Spare copy which
@@ -389,8 +389,6 @@
 	struct erase_info *instr = &inftl->instr;
 	int physblock;
 
-	instr->mtd = inftl->mbd.mtd;
-
 	DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_formatblock(inftl=%p,"
 		"block=%d)\n", inftl, block);
 
@@ -400,6 +398,7 @@
 	   _first_? */
 
 	/* Use async erase interface, test return code */
+	instr->mtd = inftl->mbd.mtd;
 	instr->addr = block * inftl->EraseSize;
 	instr->len = inftl->mbd.mtd->erasesize;
 	/* Erase one physical eraseblock at a time, even though the NAND api
diff -Nru a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
--- a/drivers/mtd/maps/Kconfig	2005-03-01 23:39:17 -08:00
+++ b/drivers/mtd/maps/Kconfig	2005-03-01 23:39:17 -08:00
@@ -1,5 +1,5 @@
 # drivers/mtd/maps/Kconfig
-# $Id: Kconfig,v 1.37 2004/10/20 22:57:18 dwmw2 Exp $
+# $Id: Kconfig,v 1.42 2005/01/05 16:59:50 dwmw2 Exp $
 
 menu "Mapping drivers for chip access"
 	depends on MTD!=n
@@ -159,7 +159,7 @@
 
 config MTD_SCx200_DOCFLASH
 	tristate "Flash device mapped with DOCCS on NatSemi SCx200"
-	depends on X86 && MTD_CFI
+	depends on X86 && MTD_CFI && MTD_PARTITIONS
 	help
 	  Enable support for a flash chip mapped using the DOCCS signal on a
 	  National Semiconductor SCx200 processor.
@@ -354,7 +354,7 @@
 	tristate "CFI Flash device mapping on FlagaDM"
 	depends on PPC32 && 8xx && MTD_CFI
 	help
-	  Mapping for the Flaga digital module. If you don´t have one, ignore
+	  Mapping for the Flaga digital module. If you don't have one, ignore
 	  this setting.
 
 config MTD_BEECH
@@ -373,9 +373,17 @@
 	  Arctic board. If you have one of these boards and would like to
 	  use the flash chips on it, say 'Y'.
 
+config MTD_WALNUT
+	tristate "Flash device mapped on IBM 405GP Walnut"
+	depends on MTD_JEDECPROBE && PPC32 && 40x && WALNUT
+	help
+	  This enables access routines for the flash chips on the IBM 405GP
+	  Walnut board. If you have one of these boards and would like to
+	  use the flash chips on it, say 'Y'.
+
 config MTD_EBONY
 	tristate "Flash devices mapped on IBM 440GP Ebony"
-	depends on MTD_CFI && PPC32 && 44x && EBONY
+	depends on MTD_JEDECPROBE && PPC32 && 44x && EBONY
 	help
 	  This enables access routines for the flash chips on the IBM 440GP
 	  Ebony board. If you have one of these boards and would like to
@@ -397,11 +405,19 @@
 	  Redwood board. If you have one of these boards and would like to
 	  use the flash chips on it, say 'Y'.
 
+config MTD_CHESTNUT
+	tristate "CFI Flash devices mapped on IBM 750FX or IBM 750GX Eval Boards"
+	depends on MTD_CFI && PPC32 && CHESTNUT && MTD_PARTITIONS
+	help
+	  This enables access routines for the flash chips on the IBM
+	  750FX and 750GX Eval Boards. If you have one of these boards and
+	  would like to use the flash chips on it, say 'Y'
+
 config MTD_CSTM_MIPS_IXX
 	tristate "Flash chip mapping on ITE QED-4N-S01B, Globespan IVR or custom board"
 	depends on MIPS && MTD_CFI && MTD_JEDECPROBE && MTD_PARTITIONS
 	help
-	  This provides a mapping driver for the Integrated Tecnology
+	  This provides a mapping driver for the Integrated Technology
 	  Express, Inc (ITE) QED-4N-S01B eval board and the Globespan IVR
 	  Reference Board. It provides the necessary addressing, length,
 	  buswidth, vpp code and addition setup of the flash device for
@@ -644,6 +660,12 @@
 	int "Maximum size for BAST flash area (MiB)"
 	depends on MTD_BAST
 	default "4"
+
+config MTD_SHARP_SL
+	bool "ROM maped on Sharp SL Series"
+	depends on MTD && ARCH_PXA
+	help
+	  This enables access to the flash chip on the Sharp SL Series of PDAs.
 
 endmenu
 
diff -Nru a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile
--- a/drivers/mtd/maps/Makefile	2005-03-01 23:38:44 -08:00
+++ b/drivers/mtd/maps/Makefile	2005-03-01 23:38:44 -08:00
@@ -1,7 +1,7 @@
 #
 # linux/drivers/maps/Makefile
 #
-# $Id: Makefile.common,v 1.19 2004/09/21 14:27:16 bjd Exp $
+# $Id: Makefile.common,v 1.23 2005/01/05 17:06:36 dwmw2 Exp $
 
 ifeq ($(CONFIG_MTD_COMPLEX_MAPPINGS),y)
 obj-$(CONFIG_MTD)		+= map_funcs.o
@@ -54,6 +54,7 @@
 obj-$(CONFIG_MTD_IMPA7)		+= impa7.o
 obj-$(CONFIG_MTD_FORTUNET)	+= fortunet.o
 obj-$(CONFIG_MTD_REDWOOD)	+= redwood.o
+obj-$(CONFIG_MTD_CHESTNUT)	+= chestnut.o
 obj-$(CONFIG_MTD_UCLINUX)	+= uclinux.o
 obj-$(CONFIG_MTD_NETtel)	+= nettel.o
 obj-$(CONFIG_MTD_SCB2_FLASH)	+= scb2_flash.o
@@ -61,6 +62,7 @@
 obj-$(CONFIG_MTD_OCOTEA)	+= ocotea.o
 obj-$(CONFIG_MTD_BEECH)		+= beech-mtd.o
 obj-$(CONFIG_MTD_ARCTIC)	+= arctic-mtd.o
+obj-$(CONFIG_MTD_WALNUT)        += walnut.o
 obj-$(CONFIG_MTD_H720X)		+= h720x-flash.o
 obj-$(CONFIG_MTD_SBC8240)	+= sbc8240.o
 obj-$(CONFIG_MTD_NOR_TOTO)	+= omap-toto-flash.o
@@ -69,3 +71,4 @@
 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
diff -Nru a/drivers/mtd/maps/amd76xrom.c b/drivers/mtd/maps/amd76xrom.c
--- a/drivers/mtd/maps/amd76xrom.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/mtd/maps/amd76xrom.c	2005-03-01 23:38:54 -08:00
@@ -2,7 +2,7 @@
  * amd76xrom.c
  *
  * Normal mappings of chips in physical memory
- * $Id: amd76xrom.c,v 1.18 2004/11/16 18:29:02 dwmw2 Exp $
+ * $Id: amd76xrom.c,v 1.19 2004/11/28 09:40:39 dwmw2 Exp $
  */
 
 #include <linux/module.h>
diff -Nru a/drivers/mtd/maps/chestnut.c b/drivers/mtd/maps/chestnut.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/mtd/maps/chestnut.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,91 @@
+/*
+ * drivers/mtd/maps/chestnut.c
+ *
+ * $Id: chestnut.c,v 1.1 2005/01/05 16:59:50 dwmw2 Exp $
+ *
+ * Flash map driver for IBM Chestnut (750FXGX Eval)
+ *
+ * Chose not to enable 8 bit flash as it contains the firmware and board
+ * info.  Thus only the 32bit flash is supported.
+ *
+ * Author: <source@mvista.com>
+ *
+ * 2004 (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/module.h>
+#include <linux/init.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 <platforms/chestnut.h>
+
+static struct map_info chestnut32_map = {
+   	.name 		= "User FS",
+   	.size 		= CHESTNUT_32BIT_SIZE,
+   	.bankwidth 	= 4,
+	.phys 		= CHESTNUT_32BIT_BASE,
+};
+
+static struct mtd_partition chestnut32_partitions[] = {
+	{
+		.name 	= "User FS",
+		.offset	= 0,
+		.size	= CHESTNUT_32BIT_SIZE,
+	}
+};
+
+static struct mtd_info *flash32;
+
+int __init init_chestnut(void)
+{
+	/* 32-bit FLASH */
+
+   	chestnut32_map.virt = ioremap(chestnut32_map.phys, chestnut32_map.size);
+
+   	if (!chestnut32_map.virt) {
+      		printk(KERN_NOTICE "Failed to ioremap 32-bit flash\n");
+		return -EIO;
+   	}
+
+	simple_map_init(&chestnut32_map);
+
+   	flash32 = do_map_probe("cfi_probe", &chestnut32_map);
+   	if (flash32) {
+   		flash32->owner = THIS_MODULE;
+   		add_mtd_partitions(flash32, chestnut32_partitions,
+					ARRAY_SIZE(chestnut32_partitions));
+   	} else {
+      		printk(KERN_NOTICE "map probe failed for 32-bit flash\n");
+		return -ENXIO;
+	}
+
+   	return 0;
+}
+
+static void __exit
+cleanup_chestnut(void)
+{
+   	if (flash32) {
+      		del_mtd_partitions(flash32);
+		map_destroy(flash32);
+   	}
+
+   	if (chestnut32_map.virt) {
+      		iounmap((void *)chestnut32_map.virt);
+	  	chestnut32_map.virt = 0;
+   	}
+}
+
+module_init(init_chestnut);
+module_exit(cleanup_chestnut);
+
+MODULE_DESCRIPTION("MTD map and partitions for IBM Chestnut (750fxgx Eval)");
+MODULE_AUTHOR("<source@mvista.com>");
+MODULE_LICENSE("GPL");
diff -Nru a/drivers/mtd/maps/cstm_mips_ixx.c b/drivers/mtd/maps/cstm_mips_ixx.c
--- a/drivers/mtd/maps/cstm_mips_ixx.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/mtd/maps/cstm_mips_ixx.c	2005-03-01 23:38:53 -08:00
@@ -58,7 +58,7 @@
 #if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR)
 void cstm_mips_ixx_set_vpp(struct map_info *map,int vpp)
 {
-	static spinlock_t vpp_lock = SPIN_LOCK_UNLOCKED;
+	static DEFINE_SPINLOCK(vpp_lock);
 	static int vpp_count = 0;
 	unsigned long flags;
 
diff -Nru a/drivers/mtd/maps/dilnetpc.c b/drivers/mtd/maps/dilnetpc.c
--- a/drivers/mtd/maps/dilnetpc.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/mtd/maps/dilnetpc.c	2005-03-01 23:38:53 -08:00
@@ -14,7 +14,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: dilnetpc.c,v 1.16 2004/11/04 13:24:14 gleixner Exp $
+ * $Id: dilnetpc.c,v 1.17 2004/11/28 09:40:39 dwmw2 Exp $
  *
  * The DIL/Net PC is a tiny embedded PC board made by SSV Embedded Systems
  * featuring the AMD Elan SC410 processor. There are two variants of this
@@ -197,7 +197,7 @@
 ************************************************************
 */
 
-static spinlock_t dnpc_spin   = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(dnpc_spin);
 static int        vpp_counter = 0;
 /*
 ** This is what has to be done for the DNP board ..
diff -Nru a/drivers/mtd/maps/ebony.c b/drivers/mtd/maps/ebony.c
--- a/drivers/mtd/maps/ebony.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/mtd/maps/ebony.c	2005-03-01 23:39:09 -08:00
@@ -1,5 +1,5 @@
 /*
- * $Id: ebony.c,v 1.13 2004/11/04 13:24:14 gleixner Exp $
+ * $Id: ebony.c,v 1.15 2004/12/09 18:39:54 holindho Exp $
  * 
  * Mapping for Ebony user flash
  *
@@ -103,7 +103,7 @@
 
 	simple_map_init(&ebony_small_map);
 
-	flash = do_map_probe("map_rom", &ebony_small_map);
+	flash = do_map_probe("jedec_probe", &ebony_small_map);
 	if (flash) {
 		flash->owner = THIS_MODULE;
 		add_mtd_partitions(flash, ebony_small_partitions,
@@ -124,7 +124,7 @@
 
 	simple_map_init(&ebony_large_map);
 
-	flash = do_map_probe("cfi_probe", &ebony_large_map);
+	flash = do_map_probe("jedec_probe", &ebony_large_map);
 	if (flash) {
 		flash->owner = THIS_MODULE;
 		add_mtd_partitions(flash, ebony_large_partitions,
diff -Nru a/drivers/mtd/maps/elan-104nc.c b/drivers/mtd/maps/elan-104nc.c
--- a/drivers/mtd/maps/elan-104nc.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/mtd/maps/elan-104nc.c	2005-03-01 23:38:57 -08:00
@@ -16,7 +16,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: elan-104nc.c,v 1.24 2004/11/16 18:29:02 dwmw2 Exp $
+   $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.
@@ -54,7 +54,7 @@
 
 static volatile int page_in_window = -1; // Current page in window.
 static void __iomem *iomapadr;
-static spinlock_t elan_104nc_spin = SPIN_LOCK_UNLOCKED;
+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
diff -Nru a/drivers/mtd/maps/ichxrom.c b/drivers/mtd/maps/ichxrom.c
--- a/drivers/mtd/maps/ichxrom.c	2005-03-01 23:38:51 -08:00
+++ b/drivers/mtd/maps/ichxrom.c	2005-03-01 23:38:51 -08:00
@@ -2,7 +2,7 @@
  * ichxrom.c
  *
  * Normal mappings of chips in physical memory
- * $Id: ichxrom.c,v 1.15 2004/11/16 18:29:02 dwmw2 Exp $
+ * $Id: ichxrom.c,v 1.16 2004/11/28 09:40:39 dwmw2 Exp $
  */
 
 #include <linux/module.h>
diff -Nru a/drivers/mtd/maps/ipaq-flash.c b/drivers/mtd/maps/ipaq-flash.c
--- a/drivers/mtd/maps/ipaq-flash.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/mtd/maps/ipaq-flash.c	2005-03-01 23:39:07 -08:00
@@ -143,7 +143,7 @@
 };
 #endif
 
-static spinlock_t ipaq_vpp_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(ipaq_vpp_lock);
 
 static void h3xxx_set_vpp(struct map_info *map, int vpp)
 {
diff -Nru a/drivers/mtd/maps/l440gx.c b/drivers/mtd/maps/l440gx.c
--- a/drivers/mtd/maps/l440gx.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/mtd/maps/l440gx.c	2005-03-01 23:39:09 -08:00
@@ -1,5 +1,5 @@
 /*
- * $Id: l440gx.c,v 1.16 2004/11/16 18:29:02 dwmw2 Exp $
+ * $Id: l440gx.c,v 1.17 2004/11/28 09:40:39 dwmw2 Exp $
  *
  * BIOS Flash chip on Intel 440GX board.
  *
diff -Nru a/drivers/mtd/maps/netsc520.c b/drivers/mtd/maps/netsc520.c
--- a/drivers/mtd/maps/netsc520.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/mtd/maps/netsc520.c	2005-03-01 23:39:09 -08:00
@@ -3,7 +3,7 @@
  * Copyright (C) 2001 Mark Langsdorf (mark.langsdorf@amd.com)
  *	based on sc520cdp.c by Sysgo Real-Time Solutions GmbH
  *
- * $Id: netsc520.c,v 1.12 2004/11/04 13:24:15 gleixner Exp $
+ * $Id: netsc520.c,v 1.13 2004/11/28 09:40:40 dwmw2 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
diff -Nru a/drivers/mtd/maps/nettel.c b/drivers/mtd/maps/nettel.c
--- a/drivers/mtd/maps/nettel.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/mtd/maps/nettel.c	2005-03-01 23:38:54 -08:00
@@ -6,7 +6,7 @@
  *      (C) Copyright 2000-2001, Greg Ungerer (gerg@snapgear.com)
  *      (C) Copyright 2001-2002, SnapGear (www.snapgear.com)
  *
- *	$Id: nettel.c,v 1.8 2004/11/04 13:24:15 gleixner Exp $
+ *	$Id: nettel.c,v 1.10 2005/01/05 17:11:29 dwmw2 Exp $
  */
 
 /****************************************************************************/
@@ -332,8 +332,8 @@
 
 		/* Destroy useless AMD MTD mapping */
 		amd_mtd = NULL;
-		iounmap((void *) nettel_amd_map.virt);
-		nettel_amd_map.virt = (unsigned long) NULL;
+		iounmap(nettel_amd_map.virt);
+		nettel_amd_map.virt = NULL;
 #else
 		/* Only AMD flash supported */
 		return(-ENXIO);
@@ -357,8 +357,7 @@
 	/* Probe for the the size of the first Intel flash */
 	nettel_intel_map.size = maxsize;
 	nettel_intel_map.phys = intel0addr;
-	nettel_intel_map.virt = (unsigned long)
-		ioremap_nocache(intel0addr, maxsize);
+	nettel_intel_map.virt = ioremap_nocache(intel0addr, maxsize);
 	if (!nettel_intel_map.virt) {
 		printk("SNAPGEAR: failed to ioremap() ROMCS1\n");
 		return(-EIO);
@@ -366,8 +365,8 @@
 	simple_map_init(&nettel_intel_map);
 
 	intel_mtd = do_map_probe("cfi_probe", &nettel_intel_map);
-	if (! intel_mtd) {
-		iounmap((void *) nettel_intel_map.virt);
+	if (!intel_mtd) {
+		iounmap(nettel_intel_map.virt);
 		return(-ENXIO);
 	}
 
@@ -388,11 +387,10 @@
 	/* Delete the old map and probe again to do both chips */
 	map_destroy(intel_mtd);
 	intel_mtd = NULL;
-	iounmap((void *) nettel_intel_map.virt);
+	iounmap(nettel_intel_map.virt);
 
 	nettel_intel_map.size = maxsize;
-	nettel_intel_map.virt = (unsigned long)
-		ioremap_nocache(intel0addr, maxsize);
+	nettel_intel_map.virt = ioremap_nocache(intel0addr, maxsize);
 	if (!nettel_intel_map.virt) {
 		printk("SNAPGEAR: failed to ioremap() ROMCS1/2\n");
 		return(-EIO);
@@ -480,7 +478,7 @@
 		map_destroy(intel_mtd);
 	}
 	if (nettel_intel_map.virt) {
-		iounmap((void *)nettel_intel_map.virt);
+		iounmap(nettel_intel_map.virt);
 		nettel_intel_map.virt = 0;
 	}
 #endif
diff -Nru a/drivers/mtd/maps/ocelot.c b/drivers/mtd/maps/ocelot.c
--- a/drivers/mtd/maps/ocelot.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/mtd/maps/ocelot.c	2005-03-01 23:39:17 -08:00
@@ -1,5 +1,5 @@
 /*
- * $Id: ocelot.c,v 1.15 2004/11/04 13:24:15 gleixner Exp $
+ * $Id: ocelot.c,v 1.16 2005/01/05 18:05:13 dwmw2 Exp $
  *
  * Flash on Momenco Ocelot
  */
@@ -28,7 +28,7 @@
 
 static void ocelot_ram_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf)
 {
-        struct map_info *map = (struct map_info *)mtd->priv;
+        struct map_info *map = mtd->priv;
 	size_t done = 0;
 
 	/* If we use memcpy, it does word-wide writes. Even though we told the 
diff -Nru a/drivers/mtd/maps/octagon-5066.c b/drivers/mtd/maps/octagon-5066.c
--- a/drivers/mtd/maps/octagon-5066.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/mtd/maps/octagon-5066.c	2005-03-01 23:38:53 -08:00
@@ -41,7 +41,7 @@
 
 static volatile char page_n_dev = 0;
 static unsigned long iomapadr;
-static spinlock_t oct5066_spin = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(oct5066_spin);
 
 /*
  * We use map_priv_1 to identify which device we are.
diff -Nru a/drivers/mtd/maps/pci.c b/drivers/mtd/maps/pci.c
--- a/drivers/mtd/maps/pci.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/mtd/maps/pci.c	2005-03-01 23:38:55 -08:00
@@ -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.8 2004/07/12 22:38:29 dwmw2 Exp $
+ *  $Id: pci.c,v 1.9 2004/11/28 09:40:40 dwmw2 Exp $
  * 
  * Generic PCI memory map driver.  We support the following boards:
  *  - Intel IQ80310 ATU.
diff -Nru a/drivers/mtd/maps/pcmciamtd.c b/drivers/mtd/maps/pcmciamtd.c
--- a/drivers/mtd/maps/pcmciamtd.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/mtd/maps/pcmciamtd.c	2005-03-01 23:38:52 -08:00
@@ -800,7 +800,6 @@
 
 	/* Register with Card Services */
 	client_reg.dev_info = &dev_info;
-	client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
 	client_reg.EventMask =
 		CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
 		CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
@@ -854,35 +853,7 @@
 {
 	DEBUG(1, DRIVER_DESC " unloading");
 	pcmcia_unregister_driver(&pcmciamtd_driver);
-
-	while(dev_list) {
-		dev_link_t *link = dev_list;
-
-		dev_list = link->next;
-		if (link) {
-			struct pcmciamtd_dev *dev = link->priv;
-			
- 			if(dev) {
-				if(link->state & DEV_PRESENT) {
-					if (!(link->state & DEV_STALE_LINK)) {
-						pcmciamtd_detach(link);
-					}
-					link->state &= ~DEV_PRESENT;
-					if(dev->mtd_info) {
-						del_mtd_device(dev->mtd_info);
-						info("mtd%d: Removed",
-						     dev->mtd_info->index);
-					}
-				}
-				if(dev->mtd_info) {
-					DEBUG(2, "Destroying map for mtd%d",
-					      dev->mtd_info->index);
-					map_destroy(dev->mtd_info);
-				}
-				kfree(dev);
-			}
-		}
-	}
+	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_pcmciamtd);
diff -Nru a/drivers/mtd/maps/physmap.c b/drivers/mtd/maps/physmap.c
--- a/drivers/mtd/maps/physmap.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/mtd/maps/physmap.c	2005-03-01 23:39:07 -08:00
@@ -1,5 +1,5 @@
 /*
- * $Id: physmap.c,v 1.36 2004/11/04 13:24:15 gleixner Exp $
+ * $Id: physmap.c,v 1.37 2004/11/28 09:40:40 dwmw2 Exp $
  *
  * Normal mappings of chips in physical memory
  *
diff -Nru a/drivers/mtd/maps/sbc_gxx.c b/drivers/mtd/maps/sbc_gxx.c
--- a/drivers/mtd/maps/sbc_gxx.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/mtd/maps/sbc_gxx.c	2005-03-01 23:38:58 -08:00
@@ -17,7 +17,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: sbc_gxx.c,v 1.32 2004/11/16 18:29:02 dwmw2 Exp $
+   $Id: sbc_gxx.c,v 1.33 2004/11/28 09:40:40 dwmw2 Exp $
 
 The SBC-MediaGX / SBC-GXx has up to 16 MiB of 
 Intel StrataFlash (28F320/28F640) in x8 mode.  
@@ -85,7 +85,7 @@
 
 static volatile int page_in_window = -1; // Current page in window.
 static void __iomem *iomapadr;
-static spinlock_t sbc_gxx_spin = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(sbc_gxx_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
diff -Nru a/drivers/mtd/maps/sc520cdp.c b/drivers/mtd/maps/sc520cdp.c
--- a/drivers/mtd/maps/sc520cdp.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/mtd/maps/sc520cdp.c	2005-03-01 23:39:16 -08:00
@@ -16,7 +16,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: sc520cdp.c,v 1.18 2004/11/04 13:24:15 gleixner Exp $
+ * $Id: sc520cdp.c,v 1.21 2004/12/13 10:27:08 dedekind Exp $
  *
  *
  * The SC520CDP is an evaluation board for the Elan SC520 processor available
diff -Nru a/drivers/mtd/maps/scb2_flash.c b/drivers/mtd/maps/scb2_flash.c
--- a/drivers/mtd/maps/scb2_flash.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/mtd/maps/scb2_flash.c	2005-03-01 23:38:58 -08:00
@@ -1,6 +1,6 @@
 /*
  * MTD map driver for BIOS Flash on Intel SCB2 boards
- * $Id: scb2_flash.c,v 1.10 2004/11/16 18:29:02 dwmw2 Exp $
+ * $Id: scb2_flash.c,v 1.11 2004/11/28 09:40:40 dwmw2 Exp $
  * Copyright (C) 2002 Sun Microsystems, Inc.
  * Tim Hockin <thockin@sun.com>
  *
diff -Nru a/drivers/mtd/maps/scx200_docflash.c b/drivers/mtd/maps/scx200_docflash.c
--- a/drivers/mtd/maps/scx200_docflash.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/mtd/maps/scx200_docflash.c	2005-03-01 23:39:08 -08:00
@@ -2,7 +2,7 @@
 
    Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com>
 
-   $Id: scx200_docflash.c,v 1.9 2004/11/16 18:29:02 dwmw2 Exp $ 
+   $Id: scx200_docflash.c,v 1.10 2004/11/28 09:40:40 dwmw2 Exp $ 
 
    National Semiconductor SCx200 flash mapped with DOCCS
 */
@@ -26,23 +26,20 @@
 MODULE_DESCRIPTION("NatSemi SCx200 DOCCS Flash Driver");
 MODULE_LICENSE("GPL");
 
-/* Set this to one if you want to partition the flash */
-#define PARTITION 1
+static int probe = 0;		/* Don't autoprobe */
+static unsigned size = 0x1000000; /* 16 MiB the whole ISA address space */
+static unsigned width = 8;	/* Default to 8 bits wide */
+static char *flashtype = "cfi_probe";
 
-MODULE_PARM(probe, "i");
+module_param(probe, int, 0);
 MODULE_PARM_DESC(probe, "Probe for a BIOS mapping");
-MODULE_PARM(size, "i");
+module_param(size, int, 0);
 MODULE_PARM_DESC(size, "Size of the flash mapping");
-MODULE_PARM(width, "i");
+module_param(width, int, 0);
 MODULE_PARM_DESC(width, "Data width of the flash mapping (8/16)");
-MODULE_PARM(flashtype, "s");
+module_param(flashtype, charp, 0);
 MODULE_PARM_DESC(flashtype, "Type of MTD probe to do");
 
-static int probe = 0;		/* Don't autoprobe */
-static unsigned size = 0x1000000; /* 16 MiB the whole ISA address space */
-static unsigned width = 8;	/* Default to 8 bits wide */
-static char *flashtype = "cfi_probe";
-
 static struct resource docmem = {
 	.flags = IORESOURCE_MEM,
 	.name  = "NatSemi SCx200 DOCCS Flash",
@@ -50,7 +47,7 @@
 
 static struct mtd_info *mymtd;
 
-#if PARTITION
+#ifdef CONFIG_MTD_PARTITIONS
 static struct mtd_partition partition_info[] = {
 	{ 
 		.name   = "DOCCS Boot kernel", 
@@ -200,7 +197,7 @@
 
 	mymtd->owner = THIS_MODULE;
 
-#if PARTITION
+#ifdef CONFIG_MTD_PARTITIONS
 	partition_info[3].offset = mymtd->size-partition_info[3].size;
 	partition_info[2].size = partition_info[3].offset-partition_info[2].offset;
 	add_mtd_partitions(mymtd, partition_info, NUM_PARTITIONS);
@@ -213,7 +210,7 @@
 static void __exit cleanup_scx200_docflash(void)
 {
 	if (mymtd) {
-#if PARTITION
+#ifdef CONFIG_MTD_PARTITIONS
 		del_mtd_partitions(mymtd);
 #else
 		del_mtd_device(mymtd);
diff -Nru a/drivers/mtd/maps/sharpsl-flash.c b/drivers/mtd/maps/sharpsl-flash.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/mtd/maps/sharpsl-flash.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,101 @@
+/*
+ * sharpsl-flash.c
+ * 
+ * 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 $
+ *
+ * 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
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/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>
+
+#define WINDOW_ADDR 0x00000000
+#define WINDOW_SIZE 0x01000000
+#define BANK_WIDTH 2
+
+static struct mtd_info *mymtd;
+
+struct map_info sharpsl_map = {
+	.name = "sharpsl-flash",
+	.size = WINDOW_SIZE,
+	.bankwidth = BANK_WIDTH,
+	.phys = WINDOW_ADDR
+};
+
+static struct mtd_partition sharpsl_partitions[1] = {
+	{
+		name:		"Filesystem",
+		size:		0x006d0000,
+		offset:		0x00120000
+	}
+};
+
+#define NB_OF(x)  (sizeof(x)/sizeof(x[0]))
+
+int __init init_sharpsl(void)
+{
+	struct mtd_partition *parts;
+	int nb_parts = 0;
+	char *part_type = "static";
+
+	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;
+	}
+	mymtd = do_map_probe("map_rom", &sharpsl_map);
+	if (!mymtd) {
+		iounmap(sharpsl_map.virt);
+		return -ENXIO;
+	}
+
+	mymtd->owner = THIS_MODULE;
+
+	parts = sharpsl_partitions;
+	nb_parts = NB_OF(sharpsl_partitions);
+
+	printk(KERN_NOTICE "Using %s partision definition\n", part_type);
+	add_mtd_partitions(mymtd, parts, nb_parts);
+
+	return 0;
+}
+
+static void __exit cleanup_sharpsl(void)
+{
+	if (mymtd) {
+		del_mtd_partitions(mymtd);
+		map_destroy(mymtd);
+	}
+	if (sharpsl_map.virt) {
+		iounmap(sharpsl_map.virt);
+		sharpsl_map.virt = 0;
+	}
+}
+
+module_init(init_sharpsl);
+module_exit(cleanup_sharpsl);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("SHARP (Original: Arnold Christensen <AKC@pel.dk>)");
+MODULE_DESCRIPTION("MTD map driver for SHARP SL series");
diff -Nru a/drivers/mtd/maps/sun_uflash.c b/drivers/mtd/maps/sun_uflash.c
--- a/drivers/mtd/maps/sun_uflash.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/mtd/maps/sun_uflash.c	2005-03-01 23:39:07 -08:00
@@ -109,7 +109,7 @@
 	/* MTD registration */
 	pdev->mtd = do_map_probe("cfi_probe", &pdev->map);
 	if(0 == pdev->mtd) {
-		iounmap((void *)pdev->map.virt);
+		iounmap(pdev->map.virt);
 		kfree(pdev->name);
 		kfree(pdev);
 		return(-ENXIO);
@@ -163,8 +163,8 @@
 			map_destroy(udev->mtd);
 		}
 		if(0 != udev->map.virt) {
-			iounmap((void*)udev->map.virt);
-			udev->map.virt = 0;
+			iounmap(udev->map.virt);
+			udev->map.virt = NULL;
 		}
 		if(0 != udev->name) {
 			kfree(udev->name);
diff -Nru a/drivers/mtd/maps/ts5500_flash.c b/drivers/mtd/maps/ts5500_flash.c
--- a/drivers/mtd/maps/ts5500_flash.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/mtd/maps/ts5500_flash.c	2005-03-01 23:39:16 -08:00
@@ -25,7 +25,7 @@
  * - If you have created your own jffs file system and the bios overwrites 
  *   it during boot, try disabling Drive A: and B: in the boot order.
  *
- * $Id: ts5500_flash.c,v 1.1 2004/09/20 15:33:26 sean Exp $
+ * $Id: ts5500_flash.c,v 1.2 2004/11/28 09:40:40 dwmw2 Exp $
  */
 
 #include <linux/config.h>
diff -Nru a/drivers/mtd/maps/uclinux.c b/drivers/mtd/maps/uclinux.c
--- a/drivers/mtd/maps/uclinux.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/mtd/maps/uclinux.c	2005-03-01 23:39:16 -08:00
@@ -5,7 +5,7 @@
  *
  *	(C) Copyright 2002, Greg Ungerer (gerg@snapgear.com)
  *
- * 	$Id: uclinux.c,v 1.9 2004/11/04 13:24:15 gleixner Exp $
+ * 	$Id: uclinux.c,v 1.10 2005/01/05 18:05:13 dwmw2 Exp $
  */
 
 /****************************************************************************/
@@ -47,7 +47,7 @@
 int uclinux_point(struct mtd_info *mtd, loff_t from, size_t len,
 	size_t *retlen, u_char **mtdbuf)
 {
-	struct map_info *map = (struct map_info *) mtd->priv;
+	struct map_info *map = mtd->priv;
 	*mtdbuf = (u_char *) (map->virt + ((int) from));
 	*retlen = len;
 	return(0);
@@ -81,7 +81,7 @@
 	mtd = do_map_probe("map_ram", mapp);
 	if (!mtd) {
 		printk("uclinux[mtd]: failed to find a mapping?\n");
-		iounmap((void *) mapp->virt);
+		iounmap(mapp->virt);
 		return(-ENXIO);
 	}
 		
diff -Nru a/drivers/mtd/maps/vmax301.c b/drivers/mtd/maps/vmax301.c
--- a/drivers/mtd/maps/vmax301.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/mtd/maps/vmax301.c	2005-03-01 23:38:54 -08:00
@@ -38,7 +38,7 @@
    the extra indirection from having one of the map->map_priv 
    fields pointing to yet another private struct.
 */
-static spinlock_t vmax301_spin = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(vmax301_spin);
 
 static void __vmax301_page(struct map_info *map, unsigned long page)
 {
diff -Nru a/drivers/mtd/maps/walnut.c b/drivers/mtd/maps/walnut.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/mtd/maps/walnut.c	2005-03-01 23:39:26 -08:00
@@ -0,0 +1,122 @@
+/*
+ * $Id: walnut.c,v 1.2 2004/12/10 12:07:42 holindho Exp $
+ * 
+ * Mapping for Walnut flash
+ * (used ebony.c as a "framework")
+ * 
+ * Heikki Lindholm <holindho@infradead.org>
+ * 
+ * 
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+#include <linux/config.h>
+#include <linux/version.h>
+#include <asm/io.h>
+#include <asm/ibm4xx.h>
+#include <platforms/4xx/walnut.h>
+
+/* these should be in platforms/4xx/walnut.h ? */
+#define WALNUT_FLASH_ONBD_N(x)		(x & 0x02)
+#define WALNUT_FLASH_SRAM_SEL(x)	(x & 0x01)
+#define WALNUT_FLASH_LOW		0xFFF00000
+#define WALNUT_FLASH_HIGH		0xFFF80000
+#define WALNUT_FLASH_SIZE		0x80000
+
+static struct mtd_info *flash;
+
+static struct map_info walnut_map = {
+	.name =		"Walnut flash",
+	.size =		WALNUT_FLASH_SIZE,
+	.bankwidth =	1,
+};
+
+/* Actually, OpenBIOS is the last 128 KiB of the flash - better
+ * partitioning could be made */
+static struct mtd_partition walnut_partitions[] = {
+	{
+		.name =   "OpenBIOS",
+		.offset = 0x0,
+		.size =   WALNUT_FLASH_SIZE,
+		/*.mask_flags = MTD_WRITEABLE, */ /* force read-only */		
+	}
+};
+
+int __init init_walnut(void)
+{
+	u8 fpga_brds1;
+	void *fpga_brds1_adr;
+	void *fpga_status_adr;
+	unsigned long flash_base;
+
+	/* this should already be mapped (platform/4xx/walnut.c) */
+	fpga_status_adr = ioremap(WALNUT_FPGA_BASE, 8);
+	if (!fpga_status_adr)
+		return -ENOMEM;
+
+	fpga_brds1_adr = fpga_status_adr+5;
+	fpga_brds1 = readb(fpga_brds1_adr);
+	/* iounmap(fpga_status_adr); */
+
+	if (WALNUT_FLASH_ONBD_N(fpga_brds1)) {
+		printk("The on-board flash is disabled (U79 sw 5)!");
+		return -EIO;
+	}
+	if (WALNUT_FLASH_SRAM_SEL(fpga_brds1)) 
+		flash_base = WALNUT_FLASH_LOW;
+	else
+		flash_base = WALNUT_FLASH_HIGH;
+	
+	walnut_map.phys = flash_base;
+	walnut_map.virt =
+		(void __iomem *)ioremap(flash_base, walnut_map.size);
+
+	if (!walnut_map.virt) {
+		printk("Failed to ioremap flash.\n");
+		return -EIO;
+	}
+
+	simple_map_init(&walnut_map);
+
+	flash = do_map_probe("jedec_probe", &walnut_map);
+	if (flash) {
+		flash->owner = THIS_MODULE;
+		add_mtd_partitions(flash, walnut_partitions,
+					ARRAY_SIZE(walnut_partitions));
+	} else {
+		printk("map probe failed for flash\n");
+		return -ENXIO;
+	}
+
+	return 0;
+}
+
+static void __exit cleanup_walnut(void)
+{
+	if (flash) {
+		del_mtd_partitions(flash);
+		map_destroy(flash);
+	}
+
+	if (walnut_map.virt) {
+		iounmap((void *)walnut_map.virt);
+		walnut_map.virt = 0;
+	}
+}
+
+module_init(init_walnut);
+module_exit(cleanup_walnut);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Heikki Lindholm <holindho@infradead.org>");
+MODULE_DESCRIPTION("MTD map and partitions for IBM 405GP Walnut boards");
diff -Nru a/drivers/mtd/mtdblock.c b/drivers/mtd/mtdblock.c
--- a/drivers/mtd/mtdblock.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/mtd/mtdblock.c	2005-03-01 23:38:55 -08:00
@@ -1,7 +1,7 @@
 /* 
  * Direct MTD block device access
  *
- * $Id: mtdblock.c,v 1.65 2004/11/16 18:28:59 dwmw2 Exp $
+ * $Id: mtdblock.c,v 1.66 2004/11/25 13:52:52 joern Exp $
  *
  * (C) 2000-2003 Nicolas Pitre <nico@cam.org>
  * (C) 1999-2003 David Woodhouse <dwmw2@infradead.org>
@@ -248,7 +248,7 @@
 			      unsigned long block, char *buf)
 {
 	struct mtdblk_dev *mtdblk = mtdblks[dev->devnum];
-	if (unlikely(!mtdblk->cache_data)) {
+	if (unlikely(!mtdblk->cache_data && mtdblk->cache_size)) {
 		mtdblk->cache_data = vmalloc(mtdblk->mtd->erasesize);
 		if (!mtdblk->cache_data)
 			return -EINTR;
diff -Nru a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
--- a/drivers/mtd/mtdchar.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/mtd/mtdchar.c	2005-03-01 23:39:07 -08:00
@@ -1,5 +1,5 @@
 /*
- * $Id: mtdchar.c,v 1.65 2004/09/23 23:45:47 gleixner Exp $
+ * $Id: mtdchar.c,v 1.66 2005/01/05 18:05:11 dwmw2 Exp $
  *
  * Character-device access to raw MTD devices.
  *
@@ -61,7 +61,7 @@
 
 static loff_t mtd_lseek (struct file *file, loff_t offset, int orig)
 {
-	struct mtd_info *mtd=(struct mtd_info *)file->private_data;
+	struct mtd_info *mtd = file->private_data;
 
 	switch (orig) {
 	case 0:
@@ -134,7 +134,7 @@
 
 	DEBUG(MTD_DEBUG_LEVEL0, "MTD_close\n");
 
-	mtd = (struct mtd_info *)file->private_data;
+	mtd = file->private_data;
 	
 	if (mtd->sync)
 		mtd->sync(mtd);
@@ -151,7 +151,7 @@
 
 static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t *ppos)
 {
-	struct mtd_info *mtd = (struct mtd_info *)file->private_data;
+	struct mtd_info *mtd = file->private_data;
 	size_t retlen=0;
 	size_t total_retlen=0;
 	int ret=0;
@@ -210,7 +210,7 @@
 
 static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count,loff_t *ppos)
 {
-	struct mtd_info *mtd = (struct mtd_info *)file->private_data;
+	struct mtd_info *mtd = file->private_data;
 	char *kbuf;
 	size_t retlen;
 	size_t total_retlen=0;
@@ -276,7 +276,7 @@
 static int mtd_ioctl(struct inode *inode, struct file *file,
 		     u_int cmd, u_long arg)
 {
-	struct mtd_info *mtd = (struct mtd_info *)file->private_data;
+	struct mtd_info *mtd = file->private_data;
 	void __user *argp = (void __user *)arg;
 	int ret = 0;
 	u_long size;
diff -Nru a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
--- a/drivers/mtd/mtdpart.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/mtd/mtdpart.c	2005-03-01 23:39:08 -08:00
@@ -523,7 +523,7 @@
 EXPORT_SYMBOL(add_mtd_partitions);
 EXPORT_SYMBOL(del_mtd_partitions);
 
-static spinlock_t part_parser_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(part_parser_lock);
 static LIST_HEAD(part_parsers);
 
 static struct mtd_part_parser *get_partition_parser(const char *name)
diff -Nru a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
--- a/drivers/mtd/nand/Kconfig	2005-03-01 23:39:08 -08:00
+++ b/drivers/mtd/nand/Kconfig	2005-03-01 23:39:08 -08:00
@@ -1,5 +1,5 @@
 # drivers/mtd/nand/Kconfig
-# $Id: Kconfig,v 1.22 2004/10/05 22:11:46 gleixner Exp $
+# $Id: Kconfig,v 1.26 2005/01/05 12:42:24 dwmw2 Exp $
 
 menu "NAND Flash Device Drivers"
 	depends on MTD!=n
@@ -7,6 +7,7 @@
 config MTD_NAND
 	tristate "NAND Device Support"
 	depends on MTD
+	select MTD_NAND_IDS
 	help
 	  This enables support for accessing all type of NAND flash
 	  devices. For further information see
@@ -56,8 +57,6 @@
 
 config MTD_NAND_IDS
 	tristate
-	default y if MTD_NAND = y || MTD_DOC2000 = y || MTD_DOC2001 = y || MTD_DOC2001PLUS = y
-	default m if MTD_NAND = m || MTD_DOC2000 = m || MTD_DOC2001 = m || MTD_DOC2001PLUS = m
 
 config MTD_NAND_TX4925NDFMC
 	tristate "SmartMedia Card on Toshiba RBTX4925 reference board"
@@ -192,4 +191,17 @@
 	  Even if you leave this disabled, you can enable BBT writes at module
 	  load time (assuming you build diskonchip as a module) with the module
 	  parameter "inftl_bbt_write=1".
+	  
+ config MTD_NAND_SHARPSL
+ 	bool "Support for NAND Flash on Sharp SL Series (C7xx + others)"
+ 	depends on MTD_NAND	&& ARCH_PXA
+ 
+ config MTD_NAND_NANDSIM
+ 	bool "Support for NAND Flash Simulator"
+ 	depends on MTD_NAND && MTD_PARTITIONS
+
+	help
+	  The simulator may simulate verious NAND flash chips for the
+	  MTD nand layer.
+ 
 endmenu
diff -Nru a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
--- a/drivers/mtd/nand/Makefile	2005-03-01 23:38:51 -08:00
+++ b/drivers/mtd/nand/Makefile	2005-03-01 23:38:51 -08:00
@@ -1,7 +1,7 @@
 #
 # linux/drivers/nand/Makefile
 #
-# $Id: Makefile.common,v 1.13 2004/09/28 22:04:23 bjd Exp $
+# $Id: Makefile.common,v 1.15 2004/11/26 12:28:22 dedekind Exp $
 
 obj-$(CONFIG_MTD_NAND)			+= nand.o nand_ecc.o
 obj-$(CONFIG_MTD_NAND_IDS)		+= nand_ids.o
@@ -18,5 +18,7 @@
 obj-$(CONFIG_MTD_NAND_DISKONCHIP)	+= diskonchip.o
 obj-$(CONFIG_MTD_NAND_H1900)		+= h1910.o
 obj-$(CONFIG_MTD_NAND_RTC_FROM4)	+= rtc_from4.o
+obj-$(CONFIG_MTD_NAND_SHARPSL)		+= sharpsl.o
+obj-$(CONFIG_MTD_NAND_NANDSIM)		+= nandsim.o
 
 nand-objs = nand_base.o nand_bbt.o
diff -Nru a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c
--- a/drivers/mtd/nand/diskonchip.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/mtd/nand/diskonchip.c	2005-03-01 23:38:54 -08:00
@@ -16,7 +16,7 @@
  *  
  * Interface to generic NAND code for M-Systems DiskOnChip devices
  *
- * $Id: diskonchip.c,v 1.42 2004/11/16 18:29:03 dwmw2 Exp $
+ * $Id: diskonchip.c,v 1.45 2005/01/05 18:05:14 dwmw2 Exp $
  */
 
 #include <linux/kernel.h>
@@ -24,6 +24,7 @@
 #include <linux/sched.h>
 #include <linux/delay.h>
 #include <linux/rslib.h>
+#include <linux/moduleparam.h>
 #include <asm/io.h>
 
 #include <linux/mtd/mtd.h>
@@ -308,7 +309,7 @@
 static void doc2000_write_byte(struct mtd_info *mtd, u_char datum)
 {
 	struct nand_chip *this = mtd->priv;
-	struct doc_priv *doc = (void *)this->priv;
+	struct doc_priv *doc = this->priv;
         void __iomem *docptr = doc->virtadr;
 
 	if(debug)printk("write_byte %02x\n", datum);
@@ -319,7 +320,7 @@
 static u_char doc2000_read_byte(struct mtd_info *mtd)
 {
 	struct nand_chip *this = mtd->priv;
-	struct doc_priv *doc = (void *)this->priv;
+	struct doc_priv *doc = this->priv;
         void __iomem *docptr = doc->virtadr;
 	u_char ret;
 
@@ -334,7 +335,7 @@
 			     const u_char *buf, int len)
 {
 	struct nand_chip *this = mtd->priv;
-	struct doc_priv *doc = (void *)this->priv;
+	struct doc_priv *doc = this->priv;
         void __iomem *docptr = doc->virtadr;
 	int i;
 	if (debug)printk("writebuf of %d bytes: ", len);
@@ -350,7 +351,7 @@
 			    u_char *buf, int len)
 {
 	struct nand_chip *this = mtd->priv;
-	struct doc_priv *doc = (void *)this->priv;
+	struct doc_priv *doc = this->priv;
         void __iomem *docptr = doc->virtadr;
  	int i;
 
@@ -365,7 +366,7 @@
 			    u_char *buf, int len)
 {
 	struct nand_chip *this = mtd->priv;
-	struct doc_priv *doc = (void *)this->priv;
+	struct doc_priv *doc = this->priv;
         void __iomem *docptr = doc->virtadr;
  	int i;
 
@@ -386,7 +387,7 @@
 			      const u_char *buf, int len)
 {
 	struct nand_chip *this = mtd->priv;
-	struct doc_priv *doc = (void *)this->priv;
+	struct doc_priv *doc = this->priv;
         void __iomem *docptr = doc->virtadr;
 	int i;
 
@@ -399,7 +400,7 @@
 static uint16_t __init doc200x_ident_chip(struct mtd_info *mtd, int nr)
 {
 	struct nand_chip *this = mtd->priv;
-	struct doc_priv *doc = (void *)this->priv;
+	struct doc_priv *doc = this->priv;
 	uint16_t ret;
 
 	doc200x_select_chip(mtd, nr);
@@ -441,7 +442,7 @@
 static void __init doc2000_count_chips(struct mtd_info *mtd)
 {
 	struct nand_chip *this = mtd->priv;
-	struct doc_priv *doc = (void *)this->priv;
+	struct doc_priv *doc = this->priv;
 	uint16_t mfrid;
 	int i;
 
@@ -462,7 +463,7 @@
 
 static int doc200x_wait(struct mtd_info *mtd, struct nand_chip *this, int state)
 {
-	struct doc_priv *doc = (void *)this->priv;
+	struct doc_priv *doc = this->priv;
 
 	int status;
 	
@@ -477,7 +478,7 @@
 static void doc2001_write_byte(struct mtd_info *mtd, u_char datum)
 {
 	struct nand_chip *this = mtd->priv;
-	struct doc_priv *doc = (void *)this->priv;
+	struct doc_priv *doc = this->priv;
         void __iomem *docptr = doc->virtadr;
 
 	WriteDOC(datum, docptr, CDSNSlowIO);
@@ -488,7 +489,7 @@
 static u_char doc2001_read_byte(struct mtd_info *mtd)
 {
 	struct nand_chip *this = mtd->priv;
-	struct doc_priv *doc = (void *)this->priv;
+	struct doc_priv *doc = this->priv;
         void __iomem *docptr = doc->virtadr;
 
 	//ReadDOC(docptr, CDSNSlowIO);
@@ -503,7 +504,7 @@
 			     const u_char *buf, int len)
 {
 	struct nand_chip *this = mtd->priv;
-	struct doc_priv *doc = (void *)this->priv;
+	struct doc_priv *doc = this->priv;
         void __iomem *docptr = doc->virtadr;
 	int i;
 
@@ -517,7 +518,7 @@
 			    u_char *buf, int len)
 {
 	struct nand_chip *this = mtd->priv;
-	struct doc_priv *doc = (void *)this->priv;
+	struct doc_priv *doc = this->priv;
         void __iomem *docptr = doc->virtadr;
 	int i;
 
@@ -535,7 +536,7 @@
 			     const u_char *buf, int len)
 {
 	struct nand_chip *this = mtd->priv;
-	struct doc_priv *doc = (void *)this->priv;
+	struct doc_priv *doc = this->priv;
         void __iomem *docptr = doc->virtadr;
 	int i;
 
@@ -555,7 +556,7 @@
 static u_char doc2001plus_read_byte(struct mtd_info *mtd)
 {
 	struct nand_chip *this = mtd->priv;
-	struct doc_priv *doc = (void *)this->priv;
+	struct doc_priv *doc = this->priv;
         void __iomem *docptr = doc->virtadr;
 	u_char ret;
 
@@ -570,7 +571,7 @@
 			     const u_char *buf, int len)
 {
 	struct nand_chip *this = mtd->priv;
-	struct doc_priv *doc = (void *)this->priv;
+	struct doc_priv *doc = this->priv;
         void __iomem *docptr = doc->virtadr;
 	int i;
 
@@ -587,7 +588,7 @@
 			    u_char *buf, int len)
 {
 	struct nand_chip *this = mtd->priv;
-	struct doc_priv *doc = (void *)this->priv;
+	struct doc_priv *doc = this->priv;
         void __iomem *docptr = doc->virtadr;
 	int i;
 
@@ -617,7 +618,7 @@
 			     const u_char *buf, int len)
 {
 	struct nand_chip *this = mtd->priv;
-	struct doc_priv *doc = (void *)this->priv;
+	struct doc_priv *doc = this->priv;
         void __iomem *docptr = doc->virtadr;
 	int i;
 
@@ -643,7 +644,7 @@
 static void doc2001plus_select_chip(struct mtd_info *mtd, int chip)
 {
 	struct nand_chip *this = mtd->priv;
-	struct doc_priv *doc = (void *)this->priv;
+	struct doc_priv *doc = this->priv;
         void __iomem *docptr = doc->virtadr;
 	int floor = 0;
 
@@ -669,7 +670,7 @@
 static void doc200x_select_chip(struct mtd_info *mtd, int chip)
 {
 	struct nand_chip *this = mtd->priv;
-	struct doc_priv *doc = (void *)this->priv;
+	struct doc_priv *doc = this->priv;
         void __iomem *docptr = doc->virtadr;
 	int floor = 0;
 
@@ -696,7 +697,7 @@
 static void doc200x_hwcontrol(struct mtd_info *mtd, int cmd)
 {
 	struct nand_chip *this = mtd->priv;
-	struct doc_priv *doc = (void *)this->priv;
+	struct doc_priv *doc = this->priv;
         void __iomem *docptr = doc->virtadr;
 
 	switch(cmd) {
@@ -734,7 +735,7 @@
 static void doc2001plus_command (struct mtd_info *mtd, unsigned command, int column, int page_addr)
 {
 	struct nand_chip *this = mtd->priv;
-	struct doc_priv *doc = (void *)this->priv;
+	struct doc_priv *doc = this->priv;
         void __iomem *docptr = doc->virtadr;
 
 	/*
@@ -838,7 +839,7 @@
 static int doc200x_dev_ready(struct mtd_info *mtd)
 {
 	struct nand_chip *this = mtd->priv;
-	struct doc_priv *doc = (void *)this->priv;
+	struct doc_priv *doc = this->priv;
         void __iomem *docptr = doc->virtadr;
 
 	if (DoC_is_MillenniumPlus(doc)) {
@@ -876,7 +877,7 @@
 static void doc200x_enable_hwecc(struct mtd_info *mtd, int mode)
 {
 	struct nand_chip *this = mtd->priv;
-	struct doc_priv *doc = (void *)this->priv;
+	struct doc_priv *doc = this->priv;
         void __iomem *docptr = doc->virtadr;
 
 	/* Prime the ECC engine */
@@ -895,7 +896,7 @@
 static void doc2001plus_enable_hwecc(struct mtd_info *mtd, int mode)
 {
 	struct nand_chip *this = mtd->priv;
-	struct doc_priv *doc = (void *)this->priv;
+	struct doc_priv *doc = this->priv;
         void __iomem *docptr = doc->virtadr;
 
 	/* Prime the ECC engine */
@@ -916,7 +917,7 @@
 				 unsigned char *ecc_code)
 {
 	struct nand_chip *this = mtd->priv;
-	struct doc_priv *doc = (void *)this->priv;
+	struct doc_priv *doc = this->priv;
         void __iomem *docptr = doc->virtadr;
 	int i;
 	int emptymatch = 1;
@@ -974,7 +975,7 @@
 {
 	int i, ret = 0;
 	struct nand_chip *this = mtd->priv;
-	struct doc_priv *doc = (void *)this->priv;
+	struct doc_priv *doc = this->priv;
         void __iomem *docptr = doc->virtadr;
 	volatile u_char dummy;
 	int emptymatch = 1;
@@ -1062,7 +1063,7 @@
 				     const char *id, int findmirror)
 {
 	struct nand_chip *this = mtd->priv;
-	struct doc_priv *doc = (void *)this->priv;
+	struct doc_priv *doc = this->priv;
 	unsigned offs, end = (MAX_MEDIAHEADER_SCAN << this->phys_erase_shift);
 	int ret;
 	size_t retlen;
@@ -1105,7 +1106,7 @@
 				struct mtd_partition *parts)
 {
 	struct nand_chip *this = mtd->priv;
-	struct doc_priv *doc = (void *)this->priv;
+	struct doc_priv *doc = this->priv;
 	int ret = 0;
 	u_char *buf;
 	struct NFTLMediaHeader *mh;
@@ -1201,7 +1202,7 @@
 				 struct mtd_partition *parts)
 {
 	struct nand_chip *this = mtd->priv;
-	struct doc_priv *doc = (void *)this->priv;
+	struct doc_priv *doc = this->priv;
 	int ret = 0;
 	u_char *buf;
 	struct INFTLMediaHeader *mh;
@@ -1326,7 +1327,7 @@
 {
 	int ret, numparts;
 	struct nand_chip *this = mtd->priv;
-	struct doc_priv *doc = (void *)this->priv;
+	struct doc_priv *doc = this->priv;
 	struct mtd_partition parts[2];
 
 	memset((char *) parts, 0, sizeof(parts));
@@ -1365,7 +1366,7 @@
 {
 	int ret, numparts;
 	struct nand_chip *this = mtd->priv;
-	struct doc_priv *doc = (void *)this->priv;
+	struct doc_priv *doc = this->priv;
 	struct mtd_partition parts[5];
 
 	if (this->numchips > doc->chips_per_floor) {
@@ -1424,7 +1425,7 @@
 static inline int __init doc2000_init(struct mtd_info *mtd)
 {
 	struct nand_chip *this = mtd->priv;
-	struct doc_priv *doc = (void *)this->priv;
+	struct doc_priv *doc = this->priv;
 
 	this->write_byte = doc2000_write_byte;
 	this->read_byte = doc2000_read_byte;
@@ -1442,7 +1443,7 @@
 static inline int __init doc2001_init(struct mtd_info *mtd)
 {
 	struct nand_chip *this = mtd->priv;
-	struct doc_priv *doc = (void *)this->priv;
+	struct doc_priv *doc = this->priv;
 
 	this->write_byte = doc2001_write_byte;
 	this->read_byte = doc2001_read_byte;
@@ -1474,7 +1475,7 @@
 static inline int __init doc2001plus_init(struct mtd_info *mtd)
 {
 	struct nand_chip *this = mtd->priv;
-	struct doc_priv *doc = (void *)this->priv;
+	struct doc_priv *doc = this->priv;
 
 	this->write_byte = NULL;
 	this->read_byte = doc2001plus_read_byte;
@@ -1596,7 +1597,7 @@
 		unsigned char oldval;
 		unsigned char newval;
 		nand = mtd->priv;
-		doc = (void *)nand->priv;
+		doc = nand->priv;
 		/* Use the alias resolution register to determine if this is
 		   in fact the same DOC aliased to a new address.  If writes
 		   to one chip's alias resolution register change the value on
@@ -1645,10 +1646,10 @@
 	nand->bbt_td		= (struct nand_bbt_descr *) (doc + 1);
 	nand->bbt_md		= nand->bbt_td + 1;
 
-	mtd->priv		= (void *) nand;
+	mtd->priv		= nand;
 	mtd->owner		= THIS_MODULE;
 
-	nand->priv		= (void *) doc;
+	nand->priv		= doc;
 	nand->select_chip	= doc200x_select_chip;
 	nand->hwcontrol		= doc200x_hwcontrol;
 	nand->dev_ready		= doc200x_dev_ready;
@@ -1699,7 +1700,7 @@
 	   actually a DiskOnChip.  */
 	WriteDOC(save_control, virtadr, DOCControl);
 fail:
-	iounmap((void *)virtadr);
+	iounmap(virtadr);
 	return ret;
 }
 
@@ -1711,11 +1712,11 @@
 
 	for (mtd = doclist; mtd; mtd = nextmtd) {
 		nand = mtd->priv;
-		doc = (void *)nand->priv;
+		doc = nand->priv;
 
 		nextmtd = doc->nextdoc;
 		nand_release(mtd);
-		iounmap((void *)doc->virtadr);
+		iounmap(doc->virtadr);
 		kfree(mtd);
 	}
 }
diff -Nru a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
--- a/drivers/mtd/nand/nand_base.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/mtd/nand/nand_base.c	2005-03-01 23:39:18 -08:00
@@ -41,7 +41,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.121 2004/10/06 19:53:11 gleixner Exp $
+ * $Id: nand_base.c,v 1.126 2004/12/13 11:22:25 lavinen 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
@@ -810,7 +810,7 @@
 	u_char *oob_buf,  struct nand_oobinfo *oobsel, int cached)
 {
 	int 	i, status;
-	u_char	ecc_code[8];
+	u_char	ecc_code[32];
 	int	eccmode = oobsel->useecc ? this->eccmode : NAND_ECC_NONE;
 	int  	*oob_config = oobsel->eccpos;
 	int	datidx = 0, eccidx = 0, eccsteps = this->eccsteps;
@@ -840,18 +840,8 @@
 		}
 		this->write_buf(mtd, this->data_poi, mtd->oobblock);
 		break;
-		
-	/* Hardware ecc 8 byte / 512 byte data */	
-	case NAND_ECC_HW8_512:	
-		eccbytes += 2;
-	/* Hardware ecc 6 byte / 512 byte data */	
-	case NAND_ECC_HW6_512:	
-		eccbytes += 3;
-	/* Hardware ecc 3 byte / 256 data */	
-	/* Hardware ecc 3 byte / 512 byte data */	
-	case NAND_ECC_HW3_256:		
-	case NAND_ECC_HW3_512:
-		eccbytes += 3;
+	default:
+		eccbytes = this->eccbytes;
 		for (; eccsteps; eccsteps--) {
 			/* enable hardware ecc logic for write */
 			this->enable_hwecc(mtd, NAND_ECC_WRITE);
@@ -864,14 +854,9 @@
 			 * the data bytes (words) */
 			if (this->options & NAND_HWECC_SYNDROME)
 				this->write_buf(mtd, ecc_code, eccbytes);
-
 			datidx += this->eccsize;
 		}
 		break;
-
-	default:
-		printk (KERN_WARNING "Invalid NAND_ECC_MODE %d\n", this->eccmode);
-		BUG();	
 	}
 										
 	/* Write out OOB data */
@@ -1051,7 +1036,7 @@
         int eccmode, eccsteps;
 	int	*oob_config, datidx;
 	int	blockcheck = (1 << (this->phys_erase_shift - this->page_shift)) - 1;
-	int	eccbytes = 3;
+	int	eccbytes;
 	int	compareecc = 1;
 	int	oobreadlen;
 
@@ -1092,19 +1077,9 @@
 
 	end = mtd->oobblock;
 	ecc = this->eccsize;
-	switch (eccmode) {
-	case NAND_ECC_HW6_512: /* Hardware ECC 6 byte / 512 byte data  */
-		eccbytes = 6;
-		break;						
-	case NAND_ECC_HW8_512: /* Hardware ECC 8 byte / 512 byte data  */
-		eccbytes = 8;
-		break;
-	case NAND_ECC_NONE:
-		compareecc = 0;
-		break;						
-	}	 
-
-	if (this->options & NAND_HWECC_SYNDROME)
+	eccbytes = this->eccbytes;
+	
+	if ((eccmode == NAND_ECC_NONE) || (this->options & NAND_HWECC_SYNDROME))
 		compareecc = 0;
 
 	oobreadlen = mtd->oobsize;
@@ -1164,13 +1139,10 @@
 			for (i = 0, datidx = 0; eccsteps; eccsteps--, i+=3, datidx += ecc) 
 				this->calculate_ecc(mtd, &data_poi[datidx], &ecc_calc[i]);
 			break;	
-			
-		case NAND_ECC_HW3_256: /* Hardware ECC 3 byte /256 byte data */
-		case NAND_ECC_HW3_512: /* Hardware ECC 3 byte /512 byte data */	
-		case NAND_ECC_HW6_512: /* Hardware ECC 6 byte / 512 byte data  */
-		case NAND_ECC_HW8_512: /* Hardware ECC 8 byte / 512 byte data  */
+
+		default:
 			for (i = 0, datidx = 0; eccsteps; eccsteps--, i+=eccbytes, datidx += ecc) {
-				this->enable_hwecc(mtd, NAND_ECC_READ);	
+				this->enable_hwecc(mtd, NAND_ECC_READ);
 				this->read_buf(mtd, &data_poi[datidx], ecc);
 
 				/* HW ecc with syndrome calculation must read the
@@ -1193,10 +1165,6 @@
 				}	
 			}
 			break;						
-
-		default:
-			printk (KERN_WARNING "Invalid NAND_ECC_MODE %d\n", this->eccmode);
-			BUG();	
 		}
 
 		/* read oobdata */
@@ -2433,8 +2401,19 @@
 	 * fallback to software ECC 
 	*/
 	this->eccsize = 256;	/* set default eccsize */	
+	this->eccbytes = 3;
 
 	switch (this->eccmode) {
+	case NAND_ECC_HW12_2048:
+		if (mtd->oobblock < 2048) {
+			printk(KERN_WARNING "2048 byte HW ECC not possible on %d byte page size, fallback to SW ECC\n",
+			       mtd->oobblock);
+			this->eccmode = NAND_ECC_SOFT;
+			this->calculate_ecc = nand_calculate_ecc;
+			this->correct_data = nand_correct_data;
+		} else
+			this->eccsize = 2048;
+		break;
 
 	case NAND_ECC_HW3_512: 
 	case NAND_ECC_HW6_512: 
@@ -2444,16 +2423,13 @@
 			this->eccmode = NAND_ECC_SOFT;
 			this->calculate_ecc = nand_calculate_ecc;
 			this->correct_data = nand_correct_data;
-			break;		
 		} else 
-			this->eccsize = 512; /* set eccsize to 512 and fall through for function check */
-
+			this->eccsize = 512; /* set eccsize to 512 */
+		break;
+			
 	case NAND_ECC_HW3_256:
-		if (this->calculate_ecc && this->correct_data && this->enable_hwecc)
-			break;
-		printk (KERN_WARNING "No ECC functions supplied, Hardware ECC not possible\n");
-		BUG();	
-
+		break;
+		
 	case NAND_ECC_NONE: 
 		printk (KERN_WARNING "NAND_ECC_NONE selected by board driver. This is not recommended !!\n");
 		this->eccmode = NAND_ECC_NONE;
@@ -2468,11 +2444,32 @@
 		printk (KERN_WARNING "Invalid NAND_ECC_MODE %d\n", this->eccmode);
 		BUG();	
 	}	
-	
+
+	/* Check hardware ecc function availability and adjust number of ecc bytes per 
+	 * calculation step
+	*/
+	switch (this->eccmode) {
+	case NAND_ECC_HW12_2048:
+		this->eccbytes += 4;
+	case NAND_ECC_HW8_512: 
+		this->eccbytes += 2;
+	case NAND_ECC_HW6_512: 
+		this->eccbytes += 3;
+	case NAND_ECC_HW3_512: 
+	case NAND_ECC_HW3_256:
+		if (this->calculate_ecc && this->correct_data && this->enable_hwecc)
+			break;
+		printk (KERN_WARNING "No ECC functions supplied, Hardware ECC not possible\n");
+		BUG();	
+	}
+		
 	mtd->eccsize = this->eccsize;
 	
 	/* Set the number of read / write steps for one page to ensure ECC generation */
 	switch (this->eccmode) {
+	case NAND_ECC_HW12_2048:
+		this->eccsteps = mtd->oobblock / 2048;
+		break;
 	case NAND_ECC_HW3_512:
 	case NAND_ECC_HW6_512:
 	case NAND_ECC_HW8_512:
diff -Nru a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c
--- a/drivers/mtd/nand/nand_bbt.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/mtd/nand/nand_bbt.c	2005-03-01 23:38:57 -08:00
@@ -6,7 +6,7 @@
  *   
  *  Copyright (C) 2004 Thomas Gleixner (tglx@linutronix.de)
  *
- * $Id: nand_bbt.c,v 1.26 2004/10/05 13:50:20 gleixner Exp $
+ * $Id: nand_bbt.c,v 1.28 2004/11/13 10:19:09 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
@@ -1001,25 +1001,27 @@
 		return nand_scan_bbt (mtd, &agand_flashbased);
 	}
 	
+	
 	/* Is a flash based bad block table requested ? */
 	if (this->options & NAND_USE_FLASH_BBT) {
 		/* Use the default pattern descriptors */	
 		if (!this->bbt_td) {	
 			this->bbt_td = &bbt_main_descr;
 			this->bbt_md = &bbt_mirror_descr;
-		}	
-		if (mtd->oobblock > 512)
-			return nand_scan_bbt (mtd, &largepage_flashbased);
-		else	
-			return nand_scan_bbt (mtd, &smallpage_flashbased);			
+		}
+		if (!this->badblock_pattern) {
+			this->badblock_pattern = (mtd->oobblock > 512) ?
+				&largepage_flashbased : &smallpage_flashbased;
+		}
 	} else {
 		this->bbt_td = NULL;
 		this->bbt_md = NULL;
-		if (mtd->oobblock > 512)
-			return nand_scan_bbt (mtd, &largepage_memorybased);
-		else
-			return nand_scan_bbt (mtd, &smallpage_memorybased);
+		if (!this->badblock_pattern) {
+			this->badblock_pattern = (mtd->oobblock > 512) ?
+				&largepage_memorybased : &smallpage_memorybased;
+		}
 	}
+	return nand_scan_bbt (mtd, this->badblock_pattern);
 }
 
 /**
diff -Nru a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/mtd/nand/nandsim.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,1613 @@
+/*
+ * NAND flash simulator.
+ *
+ * Author: Artem B. Bityuckiy <dedekind@oktetlabs.ru>, <dedekind@infradead.org>
+ *
+ * Copyright (C) 2004 Nokia Corporation 
+ *
+ * Note: NS means "NAND Simulator".
+ * Note: Input means input TO flash chip, output means output FROM 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, or (at your option) any later
+ * version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ *
+ * You 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: nandsim.c,v 1.7 2004/12/06 11:53:06 dedekind Exp $
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/vmalloc.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <linux/delay.h>
+#ifdef CONFIG_NS_ABS_POS
+#include <asm/io.h>
+#endif
+
+
+/* Default simulator parameters values */
+#if !defined(CONFIG_NANDSIM_FIRST_ID_BYTE)  || \
+    !defined(CONFIG_NANDSIM_SECOND_ID_BYTE) || \
+    !defined(CONFIG_NANDSIM_THIRD_ID_BYTE)  || \
+    !defined(CONFIG_NANDSIM_FOURTH_ID_BYTE)
+#define CONFIG_NANDSIM_FIRST_ID_BYTE  0x98
+#define CONFIG_NANDSIM_SECOND_ID_BYTE 0x39
+#define CONFIG_NANDSIM_THIRD_ID_BYTE  0xFF /* No byte */
+#define CONFIG_NANDSIM_FOURTH_ID_BYTE 0xFF /* No byte */
+#endif
+
+#ifndef CONFIG_NANDSIM_ACCESS_DELAY
+#define CONFIG_NANDSIM_ACCESS_DELAY 25
+#endif
+#ifndef CONFIG_NANDSIM_PROGRAMM_DELAY
+#define CONFIG_NANDSIM_PROGRAMM_DELAY 200
+#endif
+#ifndef CONFIG_NANDSIM_ERASE_DELAY
+#define CONFIG_NANDSIM_ERASE_DELAY 2
+#endif
+#ifndef CONFIG_NANDSIM_OUTPUT_CYCLE
+#define CONFIG_NANDSIM_OUTPUT_CYCLE 40
+#endif
+#ifndef CONFIG_NANDSIM_INPUT_CYCLE
+#define CONFIG_NANDSIM_INPUT_CYCLE  50
+#endif
+#ifndef CONFIG_NANDSIM_BUS_WIDTH
+#define CONFIG_NANDSIM_BUS_WIDTH  8
+#endif
+#ifndef CONFIG_NANDSIM_DO_DELAYS
+#define CONFIG_NANDSIM_DO_DELAYS  0
+#endif
+#ifndef CONFIG_NANDSIM_LOG
+#define CONFIG_NANDSIM_LOG        0
+#endif
+#ifndef CONFIG_NANDSIM_DBG
+#define CONFIG_NANDSIM_DBG        0
+#endif
+
+static uint first_id_byte  = CONFIG_NANDSIM_FIRST_ID_BYTE;
+static uint second_id_byte = CONFIG_NANDSIM_SECOND_ID_BYTE;
+static uint third_id_byte  = CONFIG_NANDSIM_THIRD_ID_BYTE;
+static uint fourth_id_byte = CONFIG_NANDSIM_FOURTH_ID_BYTE;
+static uint access_delay   = CONFIG_NANDSIM_ACCESS_DELAY;
+static uint programm_delay = CONFIG_NANDSIM_PROGRAMM_DELAY;
+static uint erase_delay    = CONFIG_NANDSIM_ERASE_DELAY;
+static uint output_cycle   = CONFIG_NANDSIM_OUTPUT_CYCLE;
+static uint input_cycle    = CONFIG_NANDSIM_INPUT_CYCLE;
+static uint bus_width      = CONFIG_NANDSIM_BUS_WIDTH;
+static uint do_delays      = CONFIG_NANDSIM_DO_DELAYS;
+static uint log            = CONFIG_NANDSIM_LOG;
+static uint dbg            = CONFIG_NANDSIM_DBG;
+
+module_param(first_id_byte,  uint, 0400);
+module_param(second_id_byte, uint, 0400);
+module_param(third_id_byte,  uint, 0400);
+module_param(fourth_id_byte, uint, 0400);
+module_param(access_delay,   uint, 0400);
+module_param(programm_delay, uint, 0400);
+module_param(erase_delay,    uint, 0400);
+module_param(output_cycle,   uint, 0400);
+module_param(input_cycle,    uint, 0400);
+module_param(bus_width,      uint, 0400);
+module_param(do_delays,      uint, 0400);
+module_param(log,            uint, 0400);
+module_param(dbg,            uint, 0400);
+
+MODULE_PARM_DESC(first_id_byte,  "The fist byte returned by NAND Flash 'read ID' command (manufaturer ID)");
+MODULE_PARM_DESC(second_id_byte, "The second byte returned by NAND Flash 'read ID' command (chip ID)");
+MODULE_PARM_DESC(third_id_byte,  "The third byte returned by NAND Flash 'read ID' command");
+MODULE_PARM_DESC(fourth_id_byte, "The fourth byte returned by NAND Flash 'read ID' command");
+MODULE_PARM_DESC(access_delay,   "Initial page access delay (microiseconds)");
+MODULE_PARM_DESC(programm_delay, "Page programm delay (microseconds");
+MODULE_PARM_DESC(erase_delay,    "Sector erase delay (milliseconds)");
+MODULE_PARM_DESC(output_cycle,   "Word output (from flash) time (nanodeconds)");
+MODULE_PARM_DESC(input_cycle,    "Word input (to flash) time (nanodeconds)");
+MODULE_PARM_DESC(bus_width,      "Chip's bus width (8- or 16-bit)");
+MODULE_PARM_DESC(do_delays,      "Simulate NAND delays using busy-waits if not zero");
+MODULE_PARM_DESC(log,            "Perform logging if not zero");
+MODULE_PARM_DESC(dbg,            "Output debug information if not zero");
+
+/* The largest possible page size */
+#define NS_LARGEST_PAGE_SIZE	2048
+	
+/* The prefix for simulator output */
+#define NS_OUTPUT_PREFIX "[nandsim]"
+
+/* Simulator's output macros (logging, debugging, warning, error) */
+#define NS_LOG(args...) \
+	do { if (log) printk(KERN_DEBUG NS_OUTPUT_PREFIX " log: " args); } while(0)
+#define NS_DBG(args...) \
+	do { if (dbg) printk(KERN_DEBUG NS_OUTPUT_PREFIX " debug: " args); } while(0)
+#define NS_WARN(args...) \
+	do { printk(KERN_WARNING NS_OUTPUT_PREFIX " warnig: " args); } while(0)
+#define NS_ERR(args...) \
+	do { printk(KERN_ERR NS_OUTPUT_PREFIX " errorr: " args); } while(0)
+
+/* Busy-wait delay macros (microseconds, milliseconds) */
+#define NS_UDELAY(us) \
+        do { if (do_delays) udelay(us); } while(0)
+#define NS_MDELAY(us) \
+        do { if (do_delays) mdelay(us); } while(0)
+	
+/* Is the nandsim structure initialized ? */
+#define NS_IS_INITIALIZED(ns) ((ns)->geom.totsz != 0)
+
+/* Good operation completion status */
+#define NS_STATUS_OK(ns) (NAND_STATUS_READY | (NAND_STATUS_WP * ((ns)->lines.wp == 0)))
+
+/* Operation failed completion status */
+#define NS_STATUS_FAILED(ns) (NAND_STATUS_FAIL | NS_STATUS_OK(ns)) 
+
+/* Calculate the page offset in flash RAM image by (row, column) address */
+#define NS_RAW_OFFSET(ns) \
+	(((ns)->regs.row << (ns)->geom.pgshift) + ((ns)->regs.row * (ns)->geom.oobsz) + (ns)->regs.column)
+	
+/* Calculate the OOB offset in flash RAM image by (row, column) address */
+#define NS_RAW_OFFSET_OOB(ns) (NS_RAW_OFFSET(ns) + ns->geom.pgsz)
+
+/* After a command is input, the simulator goes to one of the following states */
+#define STATE_CMD_READ0        0x00000001 /* read data from the beginning of page */
+#define STATE_CMD_READ1        0x00000002 /* read data from the second half of page */
+#define STATE_CMD_READSTART      0x00000003 /* read data second command (large page devices) */
+#define STATE_CMD_PAGEPROG     0x00000004 /* start page programm */
+#define STATE_CMD_READOOB      0x00000005 /* read OOB area */
+#define STATE_CMD_ERASE1       0x00000006 /* sector erase first command */
+#define STATE_CMD_STATUS       0x00000007 /* read status */
+#define STATE_CMD_STATUS_M     0x00000008 /* read multi-plane status (isn't implemented) */
+#define STATE_CMD_SEQIN        0x00000009 /* sequential data imput */
+#define STATE_CMD_READID       0x0000000A /* read ID */
+#define STATE_CMD_ERASE2       0x0000000B /* sector erase second command */
+#define STATE_CMD_RESET        0x0000000C /* reset */
+#define STATE_CMD_MASK         0x0000000F /* command states mask */
+
+/* After an addres is input, the simulator goes to one of these states */
+#define STATE_ADDR_PAGE        0x00000010 /* full (row, column) address is accepted */
+#define STATE_ADDR_SEC         0x00000020 /* sector address was accepted */
+#define STATE_ADDR_ZERO        0x00000030 /* one byte zero address was accepted */
+#define STATE_ADDR_MASK        0x00000030 /* address states mask */
+
+/* Durind data input/output the simulator is in these states */
+#define STATE_DATAIN           0x00000100 /* waiting for data input */
+#define STATE_DATAIN_MASK      0x00000100 /* data input states mask */
+
+#define STATE_DATAOUT          0x00001000 /* waiting for page data output */
+#define STATE_DATAOUT_ID       0x00002000 /* waiting for ID bytes output */
+#define STATE_DATAOUT_STATUS   0x00003000 /* waiting for status output */
+#define STATE_DATAOUT_STATUS_M 0x00004000 /* waiting for multi-plane status output */
+#define STATE_DATAOUT_MASK     0x00007000 /* data output states mask */
+
+/* Previous operation is done, ready to accept new requests */
+#define STATE_READY            0x00000000
+
+/* This state is used to mark that the next state isn't known yet */
+#define STATE_UNKNOWN          0x10000000
+
+/* Simulator's actions bit masks */
+#define ACTION_CPY       0x00100000 /* copy page/OOB to the internal buffer */
+#define ACTION_PRGPAGE   0x00200000 /* programm the internal buffer to flash */
+#define ACTION_SECERASE  0x00300000 /* erase sector */
+#define ACTION_ZEROOFF   0x00400000 /* don't add any offset to address */
+#define ACTION_HALFOFF   0x00500000 /* add to address half of page */
+#define ACTION_OOBOFF    0x00600000 /* add to address OOB offset */
+#define ACTION_MASK      0x00700000 /* action mask */
+
+#define NS_OPER_NUM      12 /* Number of operations supported by the simulator */
+#define NS_OPER_STATES   6  /* Maximum number of states in operation */
+
+#define OPT_ANY          0xFFFFFFFF /* any chip supports this operation */
+#define OPT_PAGE256      0x00000001 /* 256-byte  page chips */
+#define OPT_PAGE512      0x00000002 /* 512-byte  page chips */
+#define OPT_PAGE2048     0x00000008 /* 2048-byte page chips */
+#define OPT_SMARTMEDIA   0x00000010 /* SmartMedia technology chips */
+#define OPT_AUTOINCR     0x00000020 /* page number auto inctimentation is possible */
+#define OPT_PAGE512_8BIT 0x00000040 /* 512-byte page chips with 8-bit bus width */
+#define OPT_LARGEPAGE    (OPT_PAGE2048) /* 2048-byte page chips */
+#define OPT_SMALLPAGE    (OPT_PAGE256  | OPT_PAGE512)  /* 256 and 512-byte page chips */
+
+/* Remove action bits ftom state */
+#define NS_STATE(x) ((x) & ~ACTION_MASK)
+	
+/* 
+ * Maximum previous states which need to be saved. Currently saving is
+ * only needed for page programm operation with preceeded read command
+ * (which is only valid for 512-byte pages).
+ */
+#define NS_MAX_PREVSTATES 1
+
+/* 
+ * The structure which describes all the internal simulator data.
+ */
+struct nandsim {
+	struct mtd_partition part;
+
+	uint busw;              /* flash chip bus width (8 or 16) */
+	u_char ids[4];          /* chip's ID bytes */
+	uint32_t options;       /* chip's characteristic bits */
+	uint32_t state;         /* current chip state */
+	uint32_t nxstate;       /* next expected state */
+	
+	uint32_t *op;           /* current operation, NULL operations isn't known yet  */
+	uint32_t pstates[NS_MAX_PREVSTATES]; /* previous states */
+	uint16_t npstates;      /* number of previous states saved */
+	uint16_t stateidx;      /* current state index */
+
+	/* The simulated NAND flash image */
+	union flash_media {
+		u_char *byte;
+		uint16_t    *word;
+	} mem;
+
+	/* Internal buffer of page + OOB size bytes */
+	union internal_buffer {
+		u_char *byte;    /* for byte access */
+		uint16_t *word;  /* for 16-bit word access */
+	} buf;
+
+	/* NAND flash "geometry" */
+	struct nandsin_geometry {
+		uint32_t totsz;     /* total flash size, bytes */
+		uint32_t secsz;     /* flash sector (erase block) size, bytes */
+		uint pgsz;          /* NAND flash page size, bytes */
+		uint oobsz;         /* page OOB area size, bytes */
+		uint32_t totszoob;  /* total flash size including OOB, bytes */
+		uint pgszoob;       /* page size including OOB , bytes*/
+		uint secszoob;      /* sector size including OOB, bytes */
+		uint pgnum;         /* total number of pages */
+		uint pgsec;         /* number of pages per sector */
+		uint secshift;      /* bits number in sector size */
+		uint pgshift;       /* bits number in page size */
+		uint oobshift;      /* bits number in OOB size */
+		uint pgaddrbytes;   /* bytes per page address */
+		uint secaddrbytes;  /* bytes per sector address */
+		uint idbytes;       /* the number ID bytes that this chip outputs */
+	} geom;
+
+	/* NAND flash internal registers */
+	struct nandsim_regs {
+		unsigned command; /* the command register */
+		u_char   status;  /* the status register */
+		uint     row;     /* the page number */
+		uint     column;  /* the offset within page */
+		uint     count;   /* internal counter */
+		uint     num;     /* number of bytes which must be processed */
+		uint     off;     /* fixed page offset */
+	} regs;
+
+	/* NAND flash lines state */
+        struct ns_lines_status {
+                int ce;  /* chip Enable */
+                int cle; /* command Latch Enable */
+                int ale; /* address Latch Enable */
+                int wp;  /* write Protect */
+        } lines;
+};
+
+/*
+ * Operations array. To perform any operation the simulator must pass
+ * through the correspondent states chain.
+ */
+static struct nandsim_operations {
+	uint32_t reqopts;  /* options which are required to perform the operation */
+	uint32_t states[NS_OPER_STATES]; /* operation's states */
+} ops[NS_OPER_NUM] = {
+	/* Read page + OOB from the beginning */
+	{OPT_SMALLPAGE, {STATE_CMD_READ0 | ACTION_ZEROOFF, STATE_ADDR_PAGE | ACTION_CPY,
+			STATE_DATAOUT, STATE_READY}},
+	/* Read page + OOB from the second half */
+	{OPT_PAGE512_8BIT, {STATE_CMD_READ1 | ACTION_HALFOFF, STATE_ADDR_PAGE | ACTION_CPY,
+			STATE_DATAOUT, STATE_READY}},
+	/* Read OOB */
+	{OPT_SMALLPAGE, {STATE_CMD_READOOB | ACTION_OOBOFF, STATE_ADDR_PAGE | ACTION_CPY,
+			STATE_DATAOUT, STATE_READY}},
+	/* Programm page starting from the beginning */
+	{OPT_ANY, {STATE_CMD_SEQIN, STATE_ADDR_PAGE, STATE_DATAIN,
+			STATE_CMD_PAGEPROG | ACTION_PRGPAGE, STATE_READY}},
+	/* Programm page starting from the beginning */
+	{OPT_SMALLPAGE, {STATE_CMD_READ0, STATE_CMD_SEQIN | ACTION_ZEROOFF, STATE_ADDR_PAGE,
+			      STATE_DATAIN, STATE_CMD_PAGEPROG | ACTION_PRGPAGE, STATE_READY}},
+	/* Programm page starting from the second half */
+	{OPT_PAGE512, {STATE_CMD_READ1, STATE_CMD_SEQIN | ACTION_HALFOFF, STATE_ADDR_PAGE,
+			      STATE_DATAIN, STATE_CMD_PAGEPROG | ACTION_PRGPAGE, STATE_READY}},
+	/* Programm OOB */
+	{OPT_SMALLPAGE, {STATE_CMD_READOOB, STATE_CMD_SEQIN | ACTION_OOBOFF, STATE_ADDR_PAGE,
+			      STATE_DATAIN, STATE_CMD_PAGEPROG | ACTION_PRGPAGE, STATE_READY}},
+	/* Erase sector */
+	{OPT_ANY, {STATE_CMD_ERASE1, STATE_ADDR_SEC, STATE_CMD_ERASE2 | ACTION_SECERASE, STATE_READY}},
+	/* Read status */
+	{OPT_ANY, {STATE_CMD_STATUS, STATE_DATAOUT_STATUS, STATE_READY}},
+	/* Read multi-plane status */
+	{OPT_SMARTMEDIA, {STATE_CMD_STATUS_M, STATE_DATAOUT_STATUS_M, STATE_READY}},
+	/* Read ID */
+	{OPT_ANY, {STATE_CMD_READID, STATE_ADDR_ZERO, STATE_DATAOUT_ID, STATE_READY}},
+	/* Large page devices read page */
+	{OPT_LARGEPAGE, {STATE_CMD_READ0, STATE_ADDR_PAGE, STATE_CMD_READSTART | ACTION_CPY,
+			       STATE_DATAOUT, STATE_READY}}
+};
+
+/* MTD structure for NAND controller */
+static struct mtd_info *nsmtd;
+
+static u_char ns_verify_buf[NS_LARGEST_PAGE_SIZE];
+
+/*
+ * Initialize the nandsim structure.
+ *
+ * RETURNS: 0 if success, -ERRNO if failure.
+ */
+static int
+init_nandsim(struct mtd_info *mtd)
+{
+	struct nand_chip *chip = (struct nand_chip *)mtd->priv;
+	struct nandsim   *ns   = (struct nandsim *)(chip->priv);
+	int i;
+
+	if (NS_IS_INITIALIZED(ns)) {
+		NS_ERR("init_nandsim: nandsim is already initialized\n");
+		return -EIO;
+	}
+
+	/* Force mtd to not do delays */
+	chip->chip_delay = 0;
+
+	/* Initialize the NAND flash parameters */
+	ns->busw = chip->options & NAND_BUSWIDTH_16 ? 16 : 8;
+	ns->geom.totsz    = mtd->size;
+	ns->geom.pgsz     = mtd->oobblock;
+	ns->geom.oobsz    = mtd->oobsize;
+	ns->geom.secsz    = mtd->erasesize;
+	ns->geom.pgszoob  = ns->geom.pgsz + ns->geom.oobsz;
+	ns->geom.pgnum    = ns->geom.totsz / ns->geom.pgsz;
+	ns->geom.totszoob = ns->geom.totsz + ns->geom.pgnum * ns->geom.oobsz;
+	ns->geom.secshift = ffs(ns->geom.secsz) - 1;
+	ns->geom.pgshift  = chip->page_shift;
+	ns->geom.oobshift = ffs(ns->geom.oobsz) - 1;
+	ns->geom.pgsec    = ns->geom.secsz / ns->geom.pgsz;
+	ns->geom.secszoob = ns->geom.secsz + ns->geom.oobsz * ns->geom.pgsec;
+	ns->options = 0;
+
+	if (ns->geom.pgsz == 256) {
+		ns->options |= OPT_PAGE256;
+	}
+	else if (ns->geom.pgsz == 512) {
+		ns->options |= (OPT_PAGE512 | OPT_AUTOINCR);
+		if (ns->busw == 8)
+			ns->options |= OPT_PAGE512_8BIT;
+	} else if (ns->geom.pgsz == 2048) {
+		ns->options |= OPT_PAGE2048;
+	} else {
+		NS_ERR("init_nandsim: unknown page size %u\n", ns->geom.pgsz);
+		return -EIO;
+	}
+
+	if (ns->options & OPT_SMALLPAGE) {
+		if (ns->geom.totsz < (64 << 20)) {
+			ns->geom.pgaddrbytes  = 3;
+			ns->geom.secaddrbytes = 2;
+		} else {
+			ns->geom.pgaddrbytes  = 4;
+			ns->geom.secaddrbytes = 3;
+		}
+	} else {
+		if (ns->geom.totsz <= (128 << 20)) {
+			ns->geom.pgaddrbytes  = 5;
+			ns->geom.secaddrbytes = 2;
+		} else {
+			ns->geom.pgaddrbytes  = 5;
+			ns->geom.secaddrbytes = 3;
+		}
+	}
+	
+	/* Detect how many ID bytes the NAND chip outputs */
+        for (i = 0; nand_flash_ids[i].name != NULL; i++) {
+                if (second_id_byte != nand_flash_ids[i].id)
+                        continue;
+		if (!(nand_flash_ids[i].options & NAND_NO_AUTOINCR))
+			ns->options |= OPT_AUTOINCR;
+	}
+
+	if (ns->busw == 16)
+		NS_WARN("16-bit flashes support wasn't tested\n");
+
+	printk("flash size: %u MiB\n",          ns->geom.totsz >> 20);
+	printk("page size: %u bytes\n",         ns->geom.pgsz);
+	printk("OOB area size: %u bytes\n",     ns->geom.oobsz);
+	printk("sector size: %u KiB\n",         ns->geom.secsz >> 10);
+	printk("pages number: %u\n",            ns->geom.pgnum);
+	printk("pages per sector: %u\n",        ns->geom.pgsec);
+	printk("bus width: %u\n",               ns->busw);
+	printk("bits in sector size: %u\n",     ns->geom.secshift);
+	printk("bits in page size: %u\n",       ns->geom.pgshift);
+	printk("bits in OOB size: %u\n",        ns->geom.oobshift);
+	printk("flash size with OOB: %u KiB\n", ns->geom.totszoob >> 10);
+	printk("page address bytes: %u\n",      ns->geom.pgaddrbytes);
+	printk("sector address bytes: %u\n",    ns->geom.secaddrbytes);
+	printk("options: %#x\n",                ns->options);
+
+	/* Map / allocate and initialize the flash image */
+#ifdef CONFIG_NS_ABS_POS
+	ns->mem.byte = ioremap(CONFIG_NS_ABS_POS, ns->geom.totszoob);
+	if (!ns->mem.byte) {
+		NS_ERR("init_nandsim: failed to map the NAND flash image at address %p\n", 
+			(void *)CONFIG_NS_ABS_POS);
+		return -ENOMEM;
+	}
+#else
+	ns->mem.byte = vmalloc(ns->geom.totszoob);
+	if (!ns->mem.byte) {
+		NS_ERR("init_nandsim: unable to allocate %u bytes for flash image\n",
+			ns->geom.totszoob);
+		return -ENOMEM;
+	}
+	memset(ns->mem.byte, 0xFF, ns->geom.totszoob);
+#endif
+
+	/* Allocate / initialize the internal buffer */
+	ns->buf.byte = kmalloc(ns->geom.pgszoob, GFP_KERNEL);
+	if (!ns->buf.byte) {
+		NS_ERR("init_nandsim: unable to allocate %u bytes for the internal buffer\n",
+			ns->geom.pgszoob);
+		goto error;
+	}
+	memset(ns->buf.byte, 0xFF, ns->geom.pgszoob);
+
+	/* Fill the partition_info structure */
+	ns->part.name   = "NAND simulator partition";
+	ns->part.offset = 0;
+	ns->part.size   = ns->geom.totsz;
+
+	return 0;
+
+error:
+#ifdef CONFIG_NS_ABS_POS
+	iounmap(ns->mem.byte);
+#else
+	vfree(ns->mem.byte);
+#endif
+
+	return -ENOMEM;
+}
+
+/*
+ * Free the nandsim structure.
+ */
+static void
+free_nandsim(struct nandsim *ns)
+{
+	kfree(ns->buf.byte);
+
+#ifdef CONFIG_NS_ABS_POS
+	iounmap(ns->mem.byte);
+#else
+	vfree(ns->mem.byte);
+#endif
+
+	return;
+}
+
+/*
+ * Returns the string representation of 'state' state.
+ */
+static char *
+get_state_name(uint32_t state)
+{
+	switch (NS_STATE(state)) {
+		case STATE_CMD_READ0:
+			return "STATE_CMD_READ0";
+		case STATE_CMD_READ1:
+			return "STATE_CMD_READ1";
+		case STATE_CMD_PAGEPROG:
+			return "STATE_CMD_PAGEPROG";
+		case STATE_CMD_READOOB:
+			return "STATE_CMD_READOOB";
+		case STATE_CMD_READSTART:
+			return "STATE_CMD_READSTART";
+		case STATE_CMD_ERASE1:
+			return "STATE_CMD_ERASE1";
+		case STATE_CMD_STATUS:
+			return "STATE_CMD_STATUS";
+		case STATE_CMD_STATUS_M:
+			return "STATE_CMD_STATUS_M";
+		case STATE_CMD_SEQIN:
+			return "STATE_CMD_SEQIN";
+		case STATE_CMD_READID:
+			return "STATE_CMD_READID";
+		case STATE_CMD_ERASE2:
+			return "STATE_CMD_ERASE2";
+		case STATE_CMD_RESET:
+			return "STATE_CMD_RESET";
+		case STATE_ADDR_PAGE:
+			return "STATE_ADDR_PAGE";
+		case STATE_ADDR_SEC:
+			return "STATE_ADDR_SEC";
+		case STATE_ADDR_ZERO:
+			return "STATE_ADDR_ZERO";
+		case STATE_DATAIN:
+			return "STATE_DATAIN";
+		case STATE_DATAOUT:
+			return "STATE_DATAOUT";
+		case STATE_DATAOUT_ID:
+			return "STATE_DATAOUT_ID";
+		case STATE_DATAOUT_STATUS:
+			return "STATE_DATAOUT_STATUS";
+		case STATE_DATAOUT_STATUS_M:
+			return "STATE_DATAOUT_STATUS_M";
+		case STATE_READY:
+			return "STATE_READY";
+		case STATE_UNKNOWN:
+			return "STATE_UNKNOWN";
+	}
+
+	NS_ERR("get_state_name: unknown state, BUG\n");
+	return NULL;
+}
+
+/*
+ * Check if command is valid.
+ *
+ * RETURNS: 1 if wrong command, 0 if right.
+ */
+static int
+check_command(int cmd)
+{
+	switch (cmd) {
+		
+	case NAND_CMD_READ0:
+	case NAND_CMD_READSTART:
+	case NAND_CMD_PAGEPROG:
+	case NAND_CMD_READOOB:
+	case NAND_CMD_ERASE1:
+	case NAND_CMD_STATUS:
+	case NAND_CMD_SEQIN:
+	case NAND_CMD_READID:
+	case NAND_CMD_ERASE2:
+	case NAND_CMD_RESET:
+	case NAND_CMD_READ1:
+		return 0;
+		
+	case NAND_CMD_STATUS_MULTI:
+	default:
+		return 1;
+	}
+}
+
+/*
+ * Returns state after command is accepted by command number.
+ */
+static uint32_t
+get_state_by_command(unsigned command)
+{
+	switch (command) {
+		case NAND_CMD_READ0:
+			return STATE_CMD_READ0;
+		case NAND_CMD_READ1:
+			return STATE_CMD_READ1;
+		case NAND_CMD_PAGEPROG:
+			return STATE_CMD_PAGEPROG;
+		case NAND_CMD_READSTART:
+			return STATE_CMD_READSTART;
+		case NAND_CMD_READOOB:
+			return STATE_CMD_READOOB;
+		case NAND_CMD_ERASE1:
+			return STATE_CMD_ERASE1;
+		case NAND_CMD_STATUS:
+			return STATE_CMD_STATUS;
+		case NAND_CMD_STATUS_MULTI:
+			return STATE_CMD_STATUS_M;
+		case NAND_CMD_SEQIN:
+			return STATE_CMD_SEQIN;
+		case NAND_CMD_READID:
+			return STATE_CMD_READID;
+		case NAND_CMD_ERASE2:
+			return STATE_CMD_ERASE2;
+		case NAND_CMD_RESET:
+			return STATE_CMD_RESET;
+	}
+
+	NS_ERR("get_state_by_command: unknown command, BUG\n");
+	return 0;
+}
+
+/*
+ * Move an address byte to the correspondent internal register.
+ */
+static inline void
+accept_addr_byte(struct nandsim *ns, u_char bt)
+{
+	uint byte = (uint)bt;
+	
+	if (ns->regs.count < (ns->geom.pgaddrbytes - ns->geom.secaddrbytes))
+		ns->regs.column |= (byte << 8 * ns->regs.count);
+	else {
+		ns->regs.row |= (byte << 8 * (ns->regs.count -
+						ns->geom.pgaddrbytes +
+						ns->geom.secaddrbytes));
+	}
+
+	return;
+}
+		
+/*
+ * Switch to STATE_READY state.
+ */
+static inline void 
+switch_to_ready_state(struct nandsim *ns, u_char status)
+{
+	NS_DBG("switch_to_ready_state: switch to %s state\n", get_state_name(STATE_READY));
+
+	ns->state       = STATE_READY;
+	ns->nxstate     = STATE_UNKNOWN;
+	ns->op          = NULL;
+	ns->npstates    = 0;
+	ns->stateidx    = 0;
+	ns->regs.num    = 0;
+	ns->regs.count  = 0;
+	ns->regs.off    = 0;
+	ns->regs.row    = 0;
+	ns->regs.column = 0;
+	ns->regs.status = status;
+}
+
+/*
+ * If the operation isn't known yet, try to find it in the global array
+ * of supported operations.
+ *
+ * Operation can be unknown because of the following.
+ *   1. New command was accepted and this is the firs call to find the
+ *      correspondent states chain. In this case ns->npstates = 0;
+ *   2. There is several operations which begin with the same command(s)
+ *      (for example program from the second half and read from the
+ *      second half operations both begin with the READ1 command). In this
+ *      case the ns->pstates[] array contains previous states.
+ * 
+ * Thus, the function tries to find operation containing the following
+ * states (if the 'flag' parameter is 0):
+ *    ns->pstates[0], ... ns->pstates[ns->npstates], ns->state
+ *
+ * If (one and only one) matching operation is found, it is accepted (
+ * ns->ops, ns->state, ns->nxstate are initialized, ns->npstate is
+ * zeroed).
+ * 
+ * If there are several maches, the current state is pushed to the
+ * ns->pstates.
+ *
+ * The operation can be unknown only while commands are input to the chip.
+ * As soon as address command is accepted, the operation must be known.
+ * In such situation the function is called with 'flag' != 0, and the
+ * operation is searched using the following pattern:
+ *     ns->pstates[0], ... ns->pstates[ns->npstates], <address input>
+ * 
+ * It is supposed that this pattern must either match one operation on
+ * none. There can't be ambiguity in that case.
+ *
+ * If no matches found, the functions does the following:
+ *   1. if there are saved states present, try to ignore them and search
+ *      again only using the last command. If nothing was found, switch
+ *      to the STATE_READY state.
+ *   2. if there are no saved states, switch to the STATE_READY state.
+ *
+ * RETURNS: -2 - no matched operations found.
+ *          -1 - several matches.
+ *           0 - operation is found.
+ */
+static int
+find_operation(struct nandsim *ns, uint32_t flag)
+{
+	int opsfound = 0;
+	int i, j, idx = 0;
+	
+	for (i = 0; i < NS_OPER_NUM; i++) {
+
+		int found = 1;
+	
+		if (!(ns->options & ops[i].reqopts))
+			/* Ignore operations we can't perform */
+			continue;
+			
+		if (flag) {
+			if (!(ops[i].states[ns->npstates] & STATE_ADDR_MASK))
+				continue;
+		} else {
+			if (NS_STATE(ns->state) != NS_STATE(ops[i].states[ns->npstates]))
+				continue;
+		}
+
+		for (j = 0; j < ns->npstates; j++) 
+			if (NS_STATE(ops[i].states[j]) != NS_STATE(ns->pstates[j])
+				&& (ns->options & ops[idx].reqopts)) {
+				found = 0;
+				break;
+			}
+
+		if (found) {
+			idx = i;
+			opsfound += 1;
+		}
+	}
+
+	if (opsfound == 1) {
+		/* Exact match */
+		ns->op = &ops[idx].states[0];
+		if (flag) {
+			/* 
+			 * In this case the find_operation function was
+			 * called when address has just began input. But it isn't
+			 * yet fully input and the current state must
+			 * not be one of STATE_ADDR_*, but the STATE_ADDR_*
+			 * state must be the next state (ns->nxstate).
+			 */
+			ns->stateidx = ns->npstates - 1;
+		} else {
+			ns->stateidx = ns->npstates;
+		}
+		ns->npstates = 0;
+		ns->state = ns->op[ns->stateidx];
+		ns->nxstate = ns->op[ns->stateidx + 1];
+		NS_DBG("find_operation: operation found, index: %d, state: %s, nxstate %s\n",
+				idx, get_state_name(ns->state), get_state_name(ns->nxstate));
+		return 0;
+	}
+	
+	if (opsfound == 0) {
+		/* Nothing was found. Try to ignore previous commands (if any) and search again */
+		if (ns->npstates != 0) {
+			NS_DBG("find_operation: no operation found, try again with state %s\n",
+					get_state_name(ns->state));
+			ns->npstates = 0;
+			return find_operation(ns, 0);
+
+		}
+		NS_DBG("find_operation: no operations found\n");
+		switch_to_ready_state(ns, NS_STATUS_FAILED(ns));
+		return -2;
+	}
+	
+	if (flag) {
+		/* This shouldn't happen */
+		NS_DBG("find_operation: BUG, operation must be known if address is input\n");
+		return -2;
+	}
+	
+	NS_DBG("find_operation: there is still ambiguity\n");
+
+	ns->pstates[ns->npstates++] = ns->state;
+
+	return -1;
+}
+
+/*
+ * If state has any action bit, perform this action.
+ *
+ * RETURNS: 0 if success, -1 if error.
+ */
+static int
+do_state_action(struct nandsim *ns, uint32_t action)
+{
+	int i, num;
+	int busdiv = ns->busw == 8 ? 1 : 2;
+
+	action &= ACTION_MASK;
+	
+	/* Check that page address input is correct */
+	if (action != ACTION_SECERASE && ns->regs.row >= ns->geom.pgnum) {
+		NS_WARN("do_state_action: wrong page number (%#x)\n", ns->regs.row);
+		return -1;
+	}
+
+	switch (action) {
+
+	case ACTION_CPY:
+		/*
+		 * Copy page data to the internal buffer.
+		 */
+
+		/* Column shouldn't be very large */
+		if (ns->regs.column >= (ns->geom.pgszoob - ns->regs.off)) {
+			NS_ERR("do_state_action: column number is too large\n");
+			break;
+		}
+		num = ns->geom.pgszoob - ns->regs.off - ns->regs.column;
+		memcpy(ns->buf.byte, ns->mem.byte + NS_RAW_OFFSET(ns) + ns->regs.off, num);
+
+		NS_DBG("do_state_action: (ACTION_CPY:) copy %d bytes to int buf, raw offset %d\n",
+			num, NS_RAW_OFFSET(ns) + ns->regs.off);
+		
+		if (ns->regs.off == 0)
+			NS_LOG("read page %d\n", ns->regs.row);
+		else if (ns->regs.off < ns->geom.pgsz)
+			NS_LOG("read page %d (second half)\n", ns->regs.row);
+		else
+			NS_LOG("read OOB of page %d\n", ns->regs.row);
+		
+		NS_UDELAY(access_delay);
+		NS_UDELAY(input_cycle * ns->geom.pgsz / 1000 / busdiv);
+
+		break;
+
+	case ACTION_SECERASE:
+		/*
+		 * Erase sector.
+		 */
+		
+		if (ns->lines.wp) {
+			NS_ERR("do_state_action: device is write-protected, ignore sector erase\n");
+			return -1;
+		}
+		
+		if (ns->regs.row >= ns->geom.pgnum - ns->geom.pgsec
+			|| (ns->regs.row & ~(ns->geom.secsz - 1))) {
+			NS_ERR("do_state_action: wrong sector address (%#x)\n", ns->regs.row);
+			return -1;
+		}
+		
+		ns->regs.row = (ns->regs.row <<
+				8 * (ns->geom.pgaddrbytes - ns->geom.secaddrbytes)) | ns->regs.column;
+		ns->regs.column = 0;
+		
+		NS_DBG("do_state_action: erase sector at address %#x, off = %d\n",
+				ns->regs.row, NS_RAW_OFFSET(ns));
+		NS_LOG("erase sector %d\n", ns->regs.row >> (ns->geom.secshift - ns->geom.pgshift));
+
+		memset(ns->mem.byte + NS_RAW_OFFSET(ns), 0xFF, ns->geom.secszoob);
+		
+		NS_MDELAY(erase_delay);
+		
+		break;
+
+	case ACTION_PRGPAGE:
+		/*
+		 * Programm page - move internal buffer data to the page.
+		 */
+
+		if (ns->lines.wp) {
+			NS_WARN("do_state_action: device is write-protected, programm\n");
+			return -1;
+		}
+
+		num = ns->geom.pgszoob - ns->regs.off - ns->regs.column;
+		if (num != ns->regs.count) {
+			NS_ERR("do_state_action: too few bytes were input (%d instead of %d)\n",
+					ns->regs.count, num);
+			return -1;
+		}
+
+		for (i = 0; i < num; i++)
+			ns->mem.byte[NS_RAW_OFFSET(ns) + ns->regs.off + i] &= ns->buf.byte[i];
+
+		NS_DBG("do_state_action: copy %d bytes from int buf to (%#x, %#x), raw off = %d\n",
+			num, ns->regs.row, ns->regs.column, NS_RAW_OFFSET(ns) + ns->regs.off);
+		NS_LOG("programm page %d\n", ns->regs.row);
+		
+		NS_UDELAY(programm_delay);
+		NS_UDELAY(output_cycle * ns->geom.pgsz / 1000 / busdiv);
+		
+		break;
+	
+	case ACTION_ZEROOFF:
+		NS_DBG("do_state_action: set internal offset to 0\n");
+		ns->regs.off = 0;
+		break;
+
+	case ACTION_HALFOFF:
+		if (!(ns->options & OPT_PAGE512_8BIT)) {
+			NS_ERR("do_state_action: BUG! can't skip half of page for non-512"
+				"byte page size 8x chips\n");
+			return -1;
+		}
+		NS_DBG("do_state_action: set internal offset to %d\n", ns->geom.pgsz/2);
+		ns->regs.off = ns->geom.pgsz/2;
+		break;
+
+	case ACTION_OOBOFF:
+		NS_DBG("do_state_action: set internal offset to %d\n", ns->geom.pgsz);
+		ns->regs.off = ns->geom.pgsz;
+		break;
+		
+	default:
+		NS_DBG("do_state_action: BUG! unknown action\n");
+	}
+
+	return 0;
+}
+
+/*
+ * Switch simulator's state.
+ */
+static void
+switch_state(struct nandsim *ns)
+{
+	if (ns->op) {
+		/*
+		 * The current operation have already been identified.
+		 * Just follow the states chain.
+		 */
+		
+		ns->stateidx += 1;
+		ns->state = ns->nxstate;
+		ns->nxstate = ns->op[ns->stateidx + 1];
+
+		NS_DBG("switch_state: operation is known, switch to the next state, "
+			"state: %s, nxstate: %s\n",
+			get_state_name(ns->state), get_state_name(ns->nxstate));
+
+		/* See, whether we need to do some action */
+		if ((ns->state & ACTION_MASK) && do_state_action(ns, ns->state) < 0) {
+			switch_to_ready_state(ns, NS_STATUS_FAILED(ns));
+			return;
+		}
+		
+	} else {
+		/*
+		 * We don't yet know which operation we perform.
+		 * Try to identify it.
+		 */
+
+		/*  
+		 *  The only event causing the switch_state function to
+		 *  be called with yet unknown operation is new command.
+		 */
+		ns->state = get_state_by_command(ns->regs.command);
+
+		NS_DBG("switch_state: operation is unknown, try to find it\n");
+
+		if (find_operation(ns, 0) != 0)
+			return;
+
+		if ((ns->state & ACTION_MASK) && do_state_action(ns, ns->state) < 0) {
+			switch_to_ready_state(ns, NS_STATUS_FAILED(ns));
+			return;
+		}
+	}
+
+	/* For 16x devices column means the page offset in words */
+	if ((ns->nxstate & STATE_ADDR_MASK) && ns->busw == 16) {
+		NS_DBG("switch_state: double the column number for 16x device\n");
+		ns->regs.column <<= 1;
+	}
+
+	if (NS_STATE(ns->nxstate) == STATE_READY) {
+		/*
+		 * The current state is the last. Return to STATE_READY
+		 */
+
+		u_char status = NS_STATUS_OK(ns);
+		
+		/* In case of data states, see if all bytes were input/output */
+		if ((ns->state & (STATE_DATAIN_MASK | STATE_DATAOUT_MASK))
+			&& ns->regs.count != ns->regs.num) {
+			NS_WARN("switch_state: not all bytes were processed, %d left\n",
+					ns->regs.num - ns->regs.count);
+			status = NS_STATUS_FAILED(ns);
+		}
+				
+		NS_DBG("switch_state: operation complete, switch to STATE_READY state\n");
+
+		switch_to_ready_state(ns, status);
+
+		return;
+	} else if (ns->nxstate & (STATE_DATAIN_MASK | STATE_DATAOUT_MASK)) {
+		/* 
+		 * If the next state is data input/output, switch to it now
+		 */
+		
+		ns->state      = ns->nxstate;
+		ns->nxstate    = ns->op[++ns->stateidx + 1];
+		ns->regs.num   = ns->regs.count = 0;
+
+		NS_DBG("switch_state: the next state is data I/O, switch, "
+			"state: %s, nxstate: %s\n",
+			get_state_name(ns->state), get_state_name(ns->nxstate));
+
+		/*
+		 * Set the internal register to the count of bytes which
+		 * are expected to be input or output
+		 */
+		switch (NS_STATE(ns->state)) {
+			case STATE_DATAIN:
+			case STATE_DATAOUT:
+				ns->regs.num = ns->geom.pgszoob - ns->regs.off - ns->regs.column;
+				break;
+				
+			case STATE_DATAOUT_ID:
+				ns->regs.num = ns->geom.idbytes;
+				break;
+				
+			case STATE_DATAOUT_STATUS:
+			case STATE_DATAOUT_STATUS_M:
+				ns->regs.count = ns->regs.num = 0;
+				break;
+				
+			default:
+				NS_ERR("switch_state: BUG! unknown data state\n");
+		}
+
+	} else if (ns->nxstate & STATE_ADDR_MASK) {
+		/*
+		 * If the next state is address input, set the internal
+		 * register to the number of expected address bytes
+		 */
+
+		ns->regs.count = 0;
+		
+		switch (NS_STATE(ns->nxstate)) {
+			case STATE_ADDR_PAGE:
+				ns->regs.num = ns->geom.pgaddrbytes;
+		
+				break;
+			case STATE_ADDR_SEC:
+				ns->regs.num = ns->geom.secaddrbytes;
+				break;
+	
+			case STATE_ADDR_ZERO:
+				ns->regs.num = 1;
+				break;
+
+			default:
+				NS_ERR("switch_state: BUG! unknown address state\n");
+		}
+	} else {
+		/* 
+		 * Just reset internal counters.
+		 */
+
+		ns->regs.num = 0;
+		ns->regs.count = 0;
+	}
+}
+
+static void
+ns_hwcontrol(struct mtd_info *mtd, int cmd)
+{
+	struct nandsim *ns = (struct nandsim *)((struct nand_chip *)mtd->priv)->priv;
+
+	switch (cmd) {
+
+	/* set CLE line high */
+	case NAND_CTL_SETCLE:
+		NS_DBG("ns_hwcontrol: start command latch cycles\n");
+		ns->lines.cle  = 1;
+		break;
+
+	/* set CLE line low */
+	case NAND_CTL_CLRCLE:
+		NS_DBG("ns_hwcontrol: stop command latch cycles\n");
+		ns->lines.cle  = 0;
+		break;
+
+	/* set ALE line high */
+	case NAND_CTL_SETALE:
+		NS_DBG("ns_hwcontrol: start address latch cycles\n");
+		ns->lines.ale   = 1;
+		break;
+
+	/* set ALE line low */
+	case NAND_CTL_CLRALE:
+		NS_DBG("ns_hwcontrol: stop address latch cycles\n");
+		ns->lines.ale  = 0;
+		break;
+
+	/* set WP line high */
+	case NAND_CTL_SETWP:
+		NS_DBG("ns_hwcontrol: enable write protection\n");
+		ns->lines.wp = 1;
+		break;
+
+	/* set WP line low */
+	case NAND_CTL_CLRWP:
+		NS_DBG("ns_hwcontrol: disable write protection\n");
+		ns->lines.wp = 0;
+		break;
+
+	/* set CE line low */
+	case NAND_CTL_SETNCE:
+		NS_DBG("ns_hwcontrol: enable chip\n");
+		ns->lines.ce = 1;
+		break;
+
+	/* set CE line high */
+	case NAND_CTL_CLRNCE:
+		NS_DBG("ns_hwcontrol: disable chip\n");
+		ns->lines.ce = 0;
+		break;
+
+	default:
+		NS_ERR("hwcontrol: unknown command\n");
+        }
+
+	return;
+}
+
+static u_char
+ns_nand_read_byte(struct mtd_info *mtd)
+{
+        struct nandsim *ns = (struct nandsim *)((struct nand_chip *)mtd->priv)->priv;
+	u_char outb = 0x00;
+
+	/* Sanity and correctness checks */
+	if (!ns->lines.ce) {
+		NS_ERR("read_byte: chip is disabled, return %#x\n", (uint)outb);
+		return outb;
+	}
+	if (ns->lines.ale || ns->lines.cle) {
+		NS_ERR("read_byte: ALE or CLE pin is high, return %#x\n", (uint)outb);
+		return outb;
+	}
+	if (!(ns->state & STATE_DATAOUT_MASK)) {
+		NS_WARN("read_byte: unexpected data output cycle, state is %s "
+			"return %#x\n", get_state_name(ns->state), (uint)outb);
+		return outb;
+	}
+
+	/* Status register may be read as many times as it is wanted */
+	if (NS_STATE(ns->state) == STATE_DATAOUT_STATUS) {
+		NS_DBG("read_byte: return %#x status\n", ns->regs.status);
+		return ns->regs.status;
+	}
+
+	/* Check if there is any data in the internal buffer which may be read */
+	if (ns->regs.count == ns->regs.num) {
+		NS_WARN("read_byte: no more data to output, return %#x\n", (uint)outb);
+		return outb;
+	}
+
+	switch (NS_STATE(ns->state)) {
+		case STATE_DATAOUT:
+			if (ns->busw == 8) {
+				outb = ns->buf.byte[ns->regs.count];
+				ns->regs.count += 1;
+			} else {
+				outb = (u_char)cpu_to_le16(ns->buf.word[ns->regs.count >> 1]);
+				ns->regs.count += 2;
+			}
+			break;
+		case STATE_DATAOUT_ID:
+			NS_DBG("read_byte: read ID byte %d, total = %d\n", ns->regs.count, ns->regs.num);
+			outb = ns->ids[ns->regs.count];
+			ns->regs.count += 1;
+			break;
+		default:
+			BUG();
+	}
+	
+	if (ns->regs.count == ns->regs.num) {
+		NS_DBG("read_byte: all bytes were read\n");
+
+		/*
+		 * The OPT_AUTOINCR allows to read next conseqitive pages without
+		 * new read operation cycle.
+		 */
+		if ((ns->options & OPT_AUTOINCR) && NS_STATE(ns->state) == STATE_DATAOUT) {
+			ns->regs.count = 0;
+			if (ns->regs.row + 1 < ns->geom.pgnum)
+				ns->regs.row += 1;
+			NS_DBG("read_byte: switch to the next page (%#x)\n", ns->regs.row);
+			do_state_action(ns, ACTION_CPY);
+		}
+		else if (NS_STATE(ns->nxstate) == STATE_READY)
+			switch_state(ns);
+		
+	}
+	
+	return outb;
+}
+
+static void
+ns_nand_write_byte(struct mtd_info *mtd, u_char byte)
+{
+        struct nandsim *ns = (struct nandsim *)((struct nand_chip *)mtd->priv)->priv;
+	
+	/* Sanity and correctness checks */
+	if (!ns->lines.ce) {
+		NS_ERR("write_byte: chip is disabled, ignore write\n");
+		return;
+	}
+	if (ns->lines.ale && ns->lines.cle) {
+		NS_ERR("write_byte: ALE and CLE pins are high simultaneously, ignore write\n");
+		return;
+	}
+			
+	if (ns->lines.cle == 1) {
+		/*
+		 * The byte written is a command.
+		 */
+
+		if (byte == NAND_CMD_RESET) {
+			NS_LOG("reset chip\n");
+			switch_to_ready_state(ns, NS_STATUS_OK(ns));
+			return;
+		}
+
+		/* 
+		 * Chip might still be in STATE_DATAOUT
+		 * (if OPT_AUTOINCR feature is supported), STATE_DATAOUT_STATUS or
+		 * STATE_DATAOUT_STATUS_M state. If so, switch state.
+		 */
+		if (NS_STATE(ns->state) == STATE_DATAOUT_STATUS
+			|| NS_STATE(ns->state) == STATE_DATAOUT_STATUS_M
+			|| ((ns->options & OPT_AUTOINCR) && NS_STATE(ns->state) == STATE_DATAOUT))
+			switch_state(ns);
+
+		/* Check if chip is expecting command */
+		if (NS_STATE(ns->nxstate) != STATE_UNKNOWN && !(ns->nxstate & STATE_CMD_MASK)) {
+			/*
+			 * We are in situation when something else (not command)
+			 * was expected but command was input. In this case ignore
+			 * previous command(s)/state(s) and accept the last one.
+			 */
+			NS_WARN("write_byte: command (%#x) wasn't expected, expected state is %s, "
+				"ignore previous states\n", (uint)byte, get_state_name(ns->nxstate));
+			switch_to_ready_state(ns, NS_STATUS_FAILED(ns));
+		}
+		
+		/* Check that the command byte is correct */
+		if (check_command(byte)) {
+			NS_ERR("write_byte: unknown command %#x\n", (uint)byte);
+			return;
+		}
+		
+		NS_DBG("command byte corresponding to %s state accepted\n",
+			get_state_name(get_state_by_command(byte)));
+		ns->regs.command = byte;
+		switch_state(ns);
+
+	} else if (ns->lines.ale == 1) {
+		/*
+		 * The byte written is an address.
+		 */
+
+		if (NS_STATE(ns->nxstate) == STATE_UNKNOWN) {
+
+			NS_DBG("write_byte: operation isn't known yet, identify it\n");
+
+			if (find_operation(ns, 1) < 0)
+				return;
+			
+			if ((ns->state & ACTION_MASK) && do_state_action(ns, ns->state) < 0) {
+				switch_to_ready_state(ns, NS_STATUS_FAILED(ns));
+				return;
+			}
+				
+			ns->regs.count = 0;
+			switch (NS_STATE(ns->nxstate)) {
+				case STATE_ADDR_PAGE:
+					ns->regs.num = ns->geom.pgaddrbytes;
+					break;
+				case STATE_ADDR_SEC:
+					ns->regs.num = ns->geom.secaddrbytes;
+					break;
+				case STATE_ADDR_ZERO:
+					ns->regs.num = 1;
+					break;
+				default:
+					BUG();
+			}
+		}
+
+		/* Check that chip is expecting address */
+		if (!(ns->nxstate & STATE_ADDR_MASK)) {
+			NS_ERR("write_byte: address (%#x) isn't expected, expected state is %s, "
+				"switch to STATE_READY\n", (uint)byte, get_state_name(ns->nxstate));
+			switch_to_ready_state(ns, NS_STATUS_FAILED(ns));
+			return;
+		}
+		
+		/* Check if this is expected byte */
+		if (ns->regs.count == ns->regs.num) {
+			NS_ERR("write_byte: no more address bytes expected\n");
+			switch_to_ready_state(ns, NS_STATUS_FAILED(ns));
+			return;
+		}
+
+		accept_addr_byte(ns, byte);
+
+		ns->regs.count += 1;
+
+		NS_DBG("write_byte: address byte %#x was accepted (%d bytes input, %d expected)\n",
+				(uint)byte, ns->regs.count, ns->regs.num);
+
+		if (ns->regs.count == ns->regs.num) {
+			NS_DBG("address (%#x, %#x) is accepted\n", ns->regs.row, ns->regs.column);
+			switch_state(ns);
+		}
+		
+	} else {
+		/*
+		 * The byte written is an input data.
+		 */
+		
+		/* Check that chip is expecting data input */
+		if (!(ns->state & STATE_DATAIN_MASK)) {
+			NS_ERR("write_byte: data input (%#x) isn't expected, state is %s, "
+				"switch to %s\n", (uint)byte,
+				get_state_name(ns->state), get_state_name(STATE_READY));
+			switch_to_ready_state(ns, NS_STATUS_FAILED(ns));
+			return;
+		}
+
+		/* Check if this is expected byte */
+		if (ns->regs.count == ns->regs.num) {
+			NS_WARN("write_byte: %u input bytes has already been accepted, ignore write\n",
+					ns->regs.num);
+			return;
+		}
+
+		if (ns->busw == 8) {
+			ns->buf.byte[ns->regs.count] = byte;
+			ns->regs.count += 1;
+		} else {
+			ns->buf.word[ns->regs.count >> 1] = cpu_to_le16((uint16_t)byte);
+			ns->regs.count += 2;
+		}
+	}
+
+	return;
+}
+
+static int
+ns_device_ready(struct mtd_info *mtd)
+{
+	NS_DBG("device_ready\n");
+	return 1;
+}
+
+static uint16_t
+ns_nand_read_word(struct mtd_info *mtd)
+{
+	struct nand_chip *chip = (struct nand_chip *)mtd->priv;
+
+	NS_DBG("read_word\n");
+	
+	return chip->read_byte(mtd) | (chip->read_byte(mtd) << 8);
+}
+
+static void
+ns_nand_write_word(struct mtd_info *mtd, uint16_t word)
+{
+	struct nand_chip *chip = (struct nand_chip *)mtd->priv;
+	
+	NS_DBG("write_word\n");
+	
+	chip->write_byte(mtd, word & 0xFF);
+	chip->write_byte(mtd, word >> 8);
+}
+
+static void 
+ns_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
+{
+        struct nandsim *ns = (struct nandsim *)((struct nand_chip *)mtd->priv)->priv;
+
+	/* Check that chip is expecting data input */
+	if (!(ns->state & STATE_DATAIN_MASK)) {
+		NS_ERR("write_buf: data input isn't expected, state is %s, "
+			"switch to STATE_READY\n", get_state_name(ns->state));
+		switch_to_ready_state(ns, NS_STATUS_FAILED(ns));
+		return;
+	}
+
+	/* Check if these are expected bytes */
+	if (ns->regs.count + len > ns->regs.num) {
+		NS_ERR("write_buf: too many input bytes\n");
+		switch_to_ready_state(ns, NS_STATUS_FAILED(ns));
+		return;
+	}
+
+	memcpy(ns->buf.byte + ns->regs.count, buf, len);
+	ns->regs.count += len;
+	
+	if (ns->regs.count == ns->regs.num) {
+		NS_DBG("write_buf: %d bytes were written\n", ns->regs.count);
+	}
+}
+
+static void 
+ns_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
+{
+        struct nandsim *ns = (struct nandsim *)((struct nand_chip *)mtd->priv)->priv;
+
+	/* Sanity and correctness checks */
+	if (!ns->lines.ce) {
+		NS_ERR("read_buf: chip is disabled\n");
+		return;
+	}
+	if (ns->lines.ale || ns->lines.cle) {
+		NS_ERR("read_buf: ALE or CLE pin is high\n");
+		return;
+	}
+	if (!(ns->state & STATE_DATAOUT_MASK)) {
+		NS_WARN("read_buf: unexpected data output cycle, current state is %s\n",
+			get_state_name(ns->state));
+		return;
+	}
+
+	if (NS_STATE(ns->state) != STATE_DATAOUT) {
+		int i;
+
+		for (i = 0; i < len; i++)
+			buf[i] = ((struct nand_chip *)mtd->priv)->read_byte(mtd);
+
+		return;
+	}
+
+	/* Check if these are expected bytes */
+	if (ns->regs.count + len > ns->regs.num) {
+		NS_ERR("read_buf: too many bytes to read\n");
+		switch_to_ready_state(ns, NS_STATUS_FAILED(ns));
+		return;
+	}
+
+	memcpy(buf, ns->buf.byte + ns->regs.count, len);
+	ns->regs.count += len;
+	
+	if (ns->regs.count == ns->regs.num) {
+		if ((ns->options & OPT_AUTOINCR) && NS_STATE(ns->state) == STATE_DATAOUT) {
+			ns->regs.count = 0;
+			if (ns->regs.row + 1 < ns->geom.pgnum)
+				ns->regs.row += 1;
+			NS_DBG("read_buf: switch to the next page (%#x)\n", ns->regs.row);
+			do_state_action(ns, ACTION_CPY);
+		}
+		else if (NS_STATE(ns->nxstate) == STATE_READY)
+			switch_state(ns);
+	}
+	
+	return;
+}
+
+static int 
+ns_nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
+{
+	ns_nand_read_buf(mtd, (u_char *)&ns_verify_buf[0], len);
+
+	if (!memcmp(buf, &ns_verify_buf[0], len)) {
+		NS_DBG("verify_buf: the buffer is OK\n");
+		return 0;
+	} else {
+		NS_DBG("verify_buf: the buffer is wrong\n");
+		return -EFAULT;
+	}
+}
+
+/*
+ * 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)
+{
+	struct nand_chip *chip;
+	struct nandsim *nand;
+	int retval = -ENOMEM;
+
+	if (bus_width != 8 && bus_width != 16) {
+		NS_ERR("wrong bus width (%d), use only 8 or 16\n", bus_width);
+		return -EINVAL;
+	}
+	
+	/* Allocate and initialize mtd_info, nand_chip and nandsim structures */
+	nsmtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip)
+				+ sizeof(struct nandsim), GFP_KERNEL);
+	if (!nsmtd) {
+		NS_ERR("unable to allocate core structures.\n");
+		return -ENOMEM;
+	}
+	memset(nsmtd, 0, sizeof(struct mtd_info) + sizeof(struct nand_chip) +
+			sizeof(struct nandsim));
+	chip        = (struct nand_chip *)(nsmtd + 1);
+        nsmtd->priv = (void *)chip;
+	nand        = (struct nandsim *)(chip + 1);
+	chip->priv  = (void *)nand;	
+
+	/*
+	 * Register simulator's callbacks.
+	 */
+	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;
+	chip->verify_buf = ns_nand_verify_buf;
+	chip->write_word = ns_nand_write_word;
+	chip->read_word  = ns_nand_read_word;
+	chip->eccmode    = NAND_ECC_SOFT;
+
+	/* 
+	 * Perform minimum nandsim structure initialization to handle
+	 * the initial ID read command correctly 
+	 */
+	if (third_id_byte != 0xFF || fourth_id_byte != 0xFF)
+		nand->geom.idbytes = 4;
+	else
+		nand->geom.idbytes = 2;
+	nand->regs.status = NS_STATUS_OK(nand);
+	nand->nxstate = STATE_UNKNOWN;
+	nand->options |= OPT_PAGE256; /* temporary value */
+	nand->ids[0] = first_id_byte;
+	nand->ids[1] = second_id_byte;
+	nand->ids[2] = third_id_byte;
+	nand->ids[3] = fourth_id_byte;
+	if (bus_width == 16) {
+		nand->busw = 16;
+		chip->options |= NAND_BUSWIDTH_16;
+	}
+
+	if ((retval = nand_scan(nsmtd, 1)) != 0) {
+		NS_ERR("can't register NAND Simulator\n");
+		if (retval > 0)
+			retval = -ENXIO;
+		goto error;
+	}
+
+	/* Register NAND as one big partition */
+	add_mtd_partitions(nsmtd, &nand->part, 1);
+
+        return 0;
+
+error:
+	kfree(nsmtd);
+
+	return retval;
+}
+
+module_init(ns_init_module);
+
+/*
+ * Module clean-up function
+ */
+static void __exit ns_cleanup_module(void)
+{
+	struct nandsim *ns = (struct nandsim *)(((struct nand_chip *)nsmtd->priv)->priv);
+
+	free_nandsim(ns);    /* Free nandsim private resources */
+	nand_release(nsmtd); /* Unregisterd drived */
+	kfree(nsmtd);        /* Free other structures */
+}
+
+module_exit(ns_cleanup_module);
+
+MODULE_LICENSE ("GPL");
+MODULE_AUTHOR ("Artem B. Bityuckiy");
+MODULE_DESCRIPTION ("The NAND flash simulator");
+
diff -Nru a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c
--- a/drivers/mtd/nand/s3c2410.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/mtd/nand/s3c2410.c	2005-03-01 23:39:07 -08:00
@@ -11,7 +11,7 @@
  *	28-Sep-2004  BJD  Fixed ECC placement for Hardware mode
  *	12-Oct-2004  BJD  Fixed errors in use of platform data
  *
- * $Id: s3c2410.c,v 1.5 2004/10/12 10:10:15 bjd Exp $
+ * $Id: s3c2410.c,v 1.7 2005/01/05 18:05:14 dwmw2 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
@@ -117,12 +117,12 @@
 
 static struct s3c2410_nand_info *to_nand_info(struct device *dev)
 {
-	return (struct s3c2410_nand_info *)dev_get_drvdata(dev);
+	return dev_get_drvdata(dev);
 }
 
 static struct s3c2410_platform_nand *to_nand_plat(struct device *dev)
 {
-	return (struct s3c2410_platform_nand *)dev->platform_data;
+	return dev->platform_data;
 }
 
 /* timing calculations */
@@ -167,7 +167,7 @@
 	if (plat != NULL) {
 		tacls = s3c2410_nand_calc_rate(plat->tacls, clkrate, 8);
 		twrph0 = s3c2410_nand_calc_rate(plat->twrph0, clkrate, 8);
-		twrph1 = s3c2410_nand_calc_rate(plat->twrph0, clkrate, 8);
+		twrph1 = s3c2410_nand_calc_rate(plat->twrph1, clkrate, 8);
 	} else {
 		/* default timings */
 		tacls = 8;
@@ -205,7 +205,7 @@
 	struct nand_chip *this = mtd->priv;
 	unsigned long cur;
 
-	nmtd = (struct s3c2410_nand_mtd *)this->priv;
+	nmtd = this->priv;
 	info = nmtd->info;
 
 	cur = readl(info->regs + S3C2410_NFCONF);
@@ -424,14 +424,14 @@
 
 static void s3c2410_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
 {
-	struct nand_chip *this = (struct nand_chip *)mtd->priv;
+	struct nand_chip *this = mtd->priv;
 	readsb(this->IO_ADDR_R, buf, len);
 }
 
 static void s3c2410_nand_write_buf(struct mtd_info *mtd,
 				   const u_char *buf, int len)
 {
-	struct nand_chip *this = (struct nand_chip *)mtd->priv;
+	struct nand_chip *this = mtd->priv;
 	writesb(this->IO_ADDR_W, buf, len);
 }
 
diff -Nru a/drivers/mtd/nand/sharpsl.c b/drivers/mtd/nand/sharpsl.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/mtd/nand/sharpsl.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,260 @@
+/*
+ * drivers/mtd/nand/sharpsl.c
+ *
+ *  Copyright (C) 2004 Richard Purdie
+ *
+ *  $Id: sharpsl.c,v 1.3 2005/01/03 14:53:50 rpurdie Exp $
+ *
+ *  Based on Sharp's NAND driver sharp_sl.c
+ *
+ * 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/genhd.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+#include <linux/interrupt.h>
+#include <asm/io.h>
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+
+static void __iomem *sharpsl_io_base;
+static int sharpsl_phys_base = 0x0C000000;
+
+/* register offset */
+#define ECCLPLB	 	sharpsl_io_base+0x00	/* line parity 7 - 0 bit */
+#define ECCLPUB	 	sharpsl_io_base+0x04	/* line parity 15 - 8 bit */
+#define ECCCP	   	sharpsl_io_base+0x08	/* column parity 5 - 0 bit */
+#define ECCCNTR	 	sharpsl_io_base+0x0C	/* ECC byte counter */
+#define ECCCLRR	 	sharpsl_io_base+0x10	/* cleare ECC */
+#define FLASHIO	 	sharpsl_io_base+0x14	/* Flash I/O */
+#define FLASHCTL	sharpsl_io_base+0x18	/* Flash Control */
+
+/* Flash control bit */
+#define FLRYBY		(1 << 5)
+#define FLCE1		(1 << 4)
+#define FLWP		(1 << 3)
+#define FLALE		(1 << 2)
+#define FLCLE		(1 << 1)
+#define FLCE0		(1 << 0)
+
+
+/*
+ * MTD structure for SharpSL
+ */
+static struct mtd_info *sharpsl_mtd = NULL;
+
+/*
+ * Define partitions for flash device
+ */
+#define DEFAULT_NUM_PARTITIONS 3
+
+static int nr_partitions;
+static struct mtd_partition sharpsl_nand_default_partition_info[] = {
+	{
+	.name = "System Area",
+	.offset = 0,
+	.size = 7 * 1024 * 1024,
+	},
+	{
+	.name = "Root Filesystem",
+	.offset = 7 * 1024 * 1024,
+	.size = 30 * 1024 * 1024,
+	},
+	{
+	.name = "Home Filesystem",
+	.offset = MTDPART_OFS_APPEND ,
+	.size = MTDPART_SIZ_FULL ,
+	},
+};
+
+/* 
+ *	hardware specific access to control-lines
+ */
+static void
+sharpsl_nand_hwcontrol(struct mtd_info* mtd, int cmd)
+{
+	switch (cmd) {
+	case NAND_CTL_SETCLE: 
+		writeb(readb(FLASHCTL) | FLCLE, FLASHCTL);
+		break;
+	case NAND_CTL_CLRCLE:
+		writeb(readb(FLASHCTL) & ~FLCLE, FLASHCTL);
+		break;
+
+	case NAND_CTL_SETALE:
+		writeb(readb(FLASHCTL) | FLALE, FLASHCTL);
+		break;
+	case NAND_CTL_CLRALE:
+		writeb(readb(FLASHCTL) & ~FLALE, FLASHCTL);
+		break;
+
+	case NAND_CTL_SETNCE: 
+		writeb(readb(FLASHCTL) & ~(FLCE0|FLCE1), FLASHCTL);
+		break;
+	case NAND_CTL_CLRNCE: 
+		writeb(readb(FLASHCTL) | (FLCE0|FLCE1), FLASHCTL);
+		break;
+	}
+}
+
+static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
+
+static struct nand_bbt_descr sharpsl_bbt = {
+	.options = 0,
+	.offs = 4,
+	.len = 2,
+	.pattern = scan_ff_pattern
+};
+
+static int
+sharpsl_nand_dev_ready(struct mtd_info* mtd)
+{
+	return !((readb(FLASHCTL) & FLRYBY) == 0);
+}
+
+static void
+sharpsl_nand_enable_hwecc(struct mtd_info* mtd, int mode)
+{
+	writeb(0 ,ECCCLRR);
+}
+
+static int
+sharpsl_nand_calculate_ecc(struct mtd_info* mtd, const u_char* dat,
+				u_char* ecc_code)
+{
+	ecc_code[0] = ~readb(ECCLPUB);
+	ecc_code[1] = ~readb(ECCLPLB);
+	ecc_code[2] = (~readb(ECCCP) << 2) | 0x03;
+	return readb(ECCCNTR) != 0;
+}
+
+
+#ifdef CONFIG_MTD_PARTITIONS
+const char *part_probes[] = { "cmdlinepart", NULL };
+#endif
+
+
+/*
+ * Main initialization routine
+ */
+int __init
+sharpsl_nand_init(void)
+{
+	struct nand_chip *this;
+	struct mtd_partition* sharpsl_partition_info;
+	int err = 0;
+
+	/* Allocate memory for MTD device structure and private data */
+	sharpsl_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip),
+				GFP_KERNEL);
+	if (!sharpsl_mtd) {
+		printk ("Unable to allocate SharpSL NAND MTD device structure.\n");
+		return -ENOMEM;
+	}
+	
+	/* map physical adress */
+	sharpsl_io_base = ioremap(sharpsl_phys_base, 0x1000);
+	if(!sharpsl_io_base){
+		printk("ioremap to access Sharp SL NAND chip failed\n");
+		kfree(sharpsl_mtd);
+		return -EIO;
+	}
+	
+	/* Get pointer to private data */
+	this = (struct nand_chip *) (&sharpsl_mtd[1]);
+
+	/* Initialize structures */
+	memset((char *) sharpsl_mtd, 0, sizeof(struct mtd_info));
+	memset((char *) this, 0, sizeof(struct nand_chip));
+
+	/* Link the private data with the MTD structure */
+	sharpsl_mtd->priv = this;
+
+	/*
+	 * PXA initialize
+	 */
+	writeb(readb(FLASHCTL) | FLWP, FLASHCTL);
+
+	/* Set address of NAND IO lines */
+	this->IO_ADDR_R = FLASHIO;
+	this->IO_ADDR_W = FLASHIO;
+	/* Set address of hardware control function */
+	this->hwcontrol = sharpsl_nand_hwcontrol;
+	this->dev_ready = sharpsl_nand_dev_ready;
+	/* 15 us command delay time */
+	this->chip_delay = 15;
+	/* set eccmode using hardware ECC */
+	this->eccmode = NAND_ECC_HW3_256;
+	this->enable_hwecc = sharpsl_nand_enable_hwecc;
+	this->calculate_ecc = sharpsl_nand_calculate_ecc;
+	this->correct_data = nand_correct_data;
+	this->badblock_pattern = &sharpsl_bbt;
+
+	/* Scan to find existence of the device */
+	err=nand_scan(sharpsl_mtd,1);
+	if (err) {
+		iounmap(sharpsl_io_base);
+		kfree(sharpsl_mtd);
+		return err;
+	}
+
+	/* Register the partitions */
+	sharpsl_mtd->name = "sharpsl-nand";
+	nr_partitions = parse_mtd_partitions(sharpsl_mtd, part_probes,
+						&sharpsl_partition_info, 0);
+						 
+	if (nr_partitions <= 0) {
+		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;
+		} else if (machine_is_corgi() || machine_is_shepherd()) {
+			sharpsl_partition_info[1].size=25 * 1024 * 1024;
+		} else if (machine_is_husky()) {
+			sharpsl_partition_info[1].size=53 * 1024 * 1024;
+		} 		
+	}
+
+	if (machine_is_husky()) {
+		/* Need to use small eraseblock size for backward compatibility */
+		sharpsl_mtd->flags |= MTD_NO_VIRTBLOCKS;
+	}
+
+	add_mtd_partitions(sharpsl_mtd, sharpsl_partition_info, nr_partitions);
+
+	/* Return happy */
+	return 0;
+}
+module_init(sharpsl_nand_init);
+
+/*
+ * Clean up routine
+ */
+#ifdef MODULE
+static void __exit sharpsl_nand_cleanup(void)
+{
+	struct nand_chip *this = (struct nand_chip *) &sharpsl_mtd[1];
+
+	/* Release resources, unregister device */
+	nand_release(sharpsl_mtd);
+
+	iounmap(sharpsl_io_base);
+
+	/* Free the MTD device structure */
+	kfree(sharpsl_mtd);
+}
+module_exit(sharpsl_nand_cleanup);
+#endif
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>");
+MODULE_DESCRIPTION("Device specific logic for NAND flash on Sharp SL-C7xx Series");
diff -Nru a/drivers/mtd/nftlmount.c b/drivers/mtd/nftlmount.c
--- a/drivers/mtd/nftlmount.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/mtd/nftlmount.c	2005-03-01 23:39:07 -08:00
@@ -4,7 +4,7 @@
  * Author: Fabrice Bellard (fabrice.bellard@netgem.com) 
  * Copyright (C) 2000 Netgem S.A.
  *
- * $Id: nftlmount.c,v 1.39 2004/11/05 22:51:41 kalev Exp $
+ * $Id: nftlmount.c,v 1.40 2004/11/22 14:38:29 kalev 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
@@ -31,7 +31,7 @@
 
 #define SECTORSIZE 512
 
-char nftlmountrev[]="$Revision: 1.39 $";
+char nftlmountrev[]="$Revision: 1.40 $";
 
 /* find_boot_record: Find the NFTL Media Header and its Spare copy which contains the
  *	various device information of the NFTL partition and Bad Unit Table. Update
@@ -302,8 +302,6 @@
 	struct nftl_uci1 uci;
 	struct erase_info *instr = &nftl->instr;
 
-	instr->mtd = nftl->mbd.mtd;
-
 	/* Read the Unit Control Information #1 for Wear-Leveling */
 	if (MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + SECTORSIZE + 8,
 			8, &retlen, (char *)&uci) < 0)
@@ -320,6 +318,7 @@
 	memset(instr, 0, sizeof(struct erase_info));
 
 	/* XXX: use async erase interface, XXX: test return code */
+	instr->mtd = nftl->mbd.mtd;
 	instr->addr = block * nftl->EraseSize;
 	instr->len = nftl->EraseSize;
 	MTD_ERASE(nftl->mbd.mtd, instr);
diff -Nru a/drivers/mtd/redboot.c b/drivers/mtd/redboot.c
--- a/drivers/mtd/redboot.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/mtd/redboot.c	2005-03-01 23:39:18 -08:00
@@ -1,5 +1,5 @@
 /*
- * $Id: redboot.c,v 1.15 2004/08/10 07:55:16 dwmw2 Exp $
+ * $Id: redboot.c,v 1.17 2004/11/22 11:33:56 ijc Exp $
  *
  * Parse RedBoot-style Flash Image System (FIS) tables and
  * produce a Linux partition array to match.
@@ -30,6 +30,9 @@
 	struct fis_list *next;
 };
 
+static int directory = CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK;
+module_param(directory, int, 0);
+
 static inline int redboot_checksum(struct fis_image_desc *img)
 {
 	/* RedBoot doesn't actually write the desc_cksum field yet AFAICT */
@@ -50,6 +53,8 @@
 	char *nullname;
 	int namelen = 0;
 	int nulllen = 0;
+	int numslots;
+	unsigned long offset;
 #ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED
 	static char nullstring[] = "unallocated";
 #endif
@@ -59,8 +64,15 @@
 	if (!buf)
 		return -ENOMEM;
 
-	/* Read the start of the last erase block */
-	ret = master->read(master, master->size - master->erasesize,
+	if ( directory < 0 )
+		offset = master->size + directory*master->erasesize;
+	else
+		offset = directory*master->erasesize;
+
+	printk(KERN_NOTICE "Searching for RedBoot partition table in %s at offset 0x%lx\n",
+	       master->name, offset);
+
+	ret = master->read(master, offset,
 			   master->erasesize, &retlen, (void *)buf);
 
 	if (ret)
@@ -71,12 +83,16 @@
 		goto out;
 	}
 
-	/* RedBoot image could appear in any of the first three slots */
-	for (i = 0; i < 3; i++) {
-		if (!memcmp(buf[i].name, "RedBoot", 8))
+	numslots = (master->erasesize / sizeof(struct fis_image_desc));
+	for (i = 0; i < numslots; i++) {
+		if (buf[i].name[0] == 0xff) {
+			i = numslots;
+			break;
+		}
+		if (!memcmp(buf[i].name, "FIS directory", 14))
 			break;
 	}
-	if (i == 3) {
+	if (i == numslots) {
 		/* Didn't find it */
 		printk(KERN_NOTICE "No RedBoot partition table detected in %s\n",
 		       master->name);
@@ -84,7 +100,7 @@
 		goto out;
 	}
 
-	for (i = 0; i < master->erasesize / sizeof(struct fis_image_desc); i++) {
+	for (i = 0; i < numslots; i++) {
 		struct fis_list *new_fl, **prev;
 
 		if (buf[i].name[0] == 0xff)
diff -Nru a/drivers/net/3c501.c b/drivers/net/3c501.c
--- a/drivers/net/3c501.c	2005-03-01 23:38:44 -08:00
+++ b/drivers/net/3c501.c	2005-03-01 23:38:44 -08:00
@@ -892,8 +892,8 @@
 
 static struct net_device *dev_3c501;
 
-MODULE_PARM(io, "i");
-MODULE_PARM(irq, "i");
+module_param(io, int, 0);
+module_param(irq, int, 0);
 MODULE_PARM_DESC(io, "EtherLink I/O base address");
 MODULE_PARM_DESC(irq, "EtherLink IRQ number");
 
diff -Nru a/drivers/net/3c503.c b/drivers/net/3c503.c
--- a/drivers/net/3c503.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/net/3c503.c	2005-03-01 23:39:08 -08:00
@@ -673,9 +673,9 @@
 static int io[MAX_EL2_CARDS];
 static int irq[MAX_EL2_CARDS];
 static int xcvr[MAX_EL2_CARDS];	/* choose int. or ext. xcvr */
-MODULE_PARM(io, "1-" __MODULE_STRING(MAX_EL2_CARDS) "i");
-MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_EL2_CARDS) "i");
-MODULE_PARM(xcvr, "1-" __MODULE_STRING(MAX_EL2_CARDS) "i");
+module_param_array(io, int, NULL, 0);
+module_param_array(irq, int, NULL, 0);
+module_param_array(xcvr, int, NULL, 0);
 MODULE_PARM_DESC(io, "I/O base address(es)");
 MODULE_PARM_DESC(irq, "IRQ number(s) (assigned)");
 MODULE_PARM_DESC(xcvr, "transceiver(s) (0=internal, 1=external)");
diff -Nru a/drivers/net/3c505.c b/drivers/net/3c505.c
--- a/drivers/net/3c505.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/net/3c505.c	2005-03-01 23:39:17 -08:00
@@ -228,16 +228,6 @@
 	outb(val, base_addr + PORT_COMMAND);
 }
 
-static inline unsigned int inw_data(unsigned int base_addr)
-{
-	return inw(base_addr + PORT_DATA);
-}
-
-static inline void outw_data(unsigned int val, unsigned int base_addr)
-{
-	outw(val, base_addr + PORT_DATA);
-}
-
 static inline unsigned int backlog_next(unsigned int n)
 {
 	return (n + 1) % BACKLOG_SIZE;
@@ -1638,9 +1628,9 @@
 static int io[ELP_MAX_CARDS];
 static int irq[ELP_MAX_CARDS];
 static int dma[ELP_MAX_CARDS];
-MODULE_PARM(io, "1-" __MODULE_STRING(ELP_MAX_CARDS) "i");
-MODULE_PARM(irq, "1-" __MODULE_STRING(ELP_MAX_CARDS) "i");
-MODULE_PARM(dma, "1-" __MODULE_STRING(ELP_MAX_CARDS) "i");
+module_param_array(io, int, NULL, 0);
+module_param_array(irq, int, NULL, 0);
+module_param_array(dma, int, NULL, 0);
 MODULE_PARM_DESC(io, "EtherLink Plus I/O base address(es)");
 MODULE_PARM_DESC(irq, "EtherLink Plus IRQ number(s) (assigned)");
 MODULE_PARM_DESC(dma, "EtherLink Plus DMA channel(s)");
diff -Nru a/drivers/net/3c507.c b/drivers/net/3c507.c
--- a/drivers/net/3c507.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/net/3c507.c	2005-03-01 23:39:08 -08:00
@@ -127,6 +127,7 @@
 	ushort tx_reap;
 	ushort tx_pkts_in_ring;
 	spinlock_t lock;
+	void __iomem *base;
 };
 
 /*
@@ -348,6 +349,7 @@
 	return dev;
 out1:
 	free_irq(dev->irq, dev);
+	iounmap(((struct net_local *)netdev_priv(dev))->base);
 	release_region(dev->base_addr, EL16_IO_EXTENT);
 out:
 	free_netdev(dev);
@@ -395,7 +397,7 @@
 
 	irqval = request_irq(irq, &el16_interrupt, 0, DRV_NAME, dev);
 	if (irqval) {
-		printk ("unable to get IRQ %d (irqval=%d).\n", irq, irqval);
+		printk(KERN_ERR "3c507: unable to get IRQ %d (irqval=%d).\n", irq, irqval);
 		retval = -EAGAIN;
 		goto out;
 	}
@@ -445,6 +447,12 @@
 	lp = netdev_priv(dev);
  	memset(lp, 0, sizeof(*lp));
 	spin_lock_init(&lp->lock);
+	lp->base = ioremap(dev->mem_start, RX_BUF_END);
+	if (!lp->base) {
+		printk(KERN_ERR "3c507: unable to remap memory\n");
+		retval = -EAGAIN;
+		goto out1;
+	}
 
  	dev->open = el16_open;
  	dev->stop = el16_close;
@@ -455,6 +463,8 @@
 	dev->ethtool_ops = &netdev_ethtool_ops;
  	dev->flags &= ~IFF_MULTICAST;	/* Multicast doesn't work */
 	return 0;
+out1:
+	free_irq(dev->irq, dev);
 out:
 	release_region(ioaddr, EL16_IO_EXTENT);
 	return retval;
@@ -474,11 +484,11 @@
 {
 	struct net_local *lp = netdev_priv(dev);
 	int ioaddr = dev->base_addr;
-	unsigned long shmem = dev->mem_start;
+	void __iomem *shmem = lp->base;
 
 	if (net_debug > 1)
 		printk ("%s: transmit timed out, %s?  ", dev->name,
-			isa_readw (shmem + iSCB_STATUS) & 0x8000 ? "IRQ conflict" :
+			readw(shmem + iSCB_STATUS) & 0x8000 ? "IRQ conflict" :
 			"network cable problem");
 	/* Try to restart the adaptor. */
 	if (lp->last_restart == lp->stats.tx_packets) {
@@ -491,7 +501,7 @@
 		/* Issue the channel attention signal and hope it "gets better". */
 		if (net_debug > 1)
 			printk ("Kicking board.\n");
-		isa_writew (0xf000 | CUC_START | RX_START, shmem + iSCB_CMD);
+		writew(0xf000 | CUC_START | RX_START, shmem + iSCB_CMD);
 		outb (0, ioaddr + SIGNAL_CA);	/* Issue channel-attn. */
 		lp->last_restart = lp->stats.tx_packets;
 	}
@@ -539,7 +549,7 @@
 	struct net_local *lp;
 	int ioaddr, status, boguscount = 0;
 	ushort ack_cmd = 0;
-	unsigned long shmem;
+	void __iomem *shmem;
 
 	if (dev == NULL) {
 		printk ("net_interrupt(): irq %d for unknown device.\n", irq);
@@ -548,11 +558,11 @@
 
 	ioaddr = dev->base_addr;
 	lp = netdev_priv(dev);
-	shmem = dev->mem_start;
+	shmem = lp->base;
 
 	spin_lock(&lp->lock);
 
-	status = isa_readw(shmem+iSCB_STATUS);
+	status = readw(shmem+iSCB_STATUS);
 
 	if (net_debug > 4) {
 		printk("%s: 3c507 interrupt, status %4.4x.\n", dev->name, status);
@@ -563,7 +573,7 @@
 
 	/* Reap the Tx packet buffers. */
 	while (lp->tx_pkts_in_ring) {
-	  unsigned short tx_status = isa_readw(shmem+lp->tx_reap);
+	  unsigned short tx_status = readw(shmem+lp->tx_reap);
 	  if (!(tx_status & 0x8000)) {
 		if (net_debug > 5) 
 			printk("Tx command incomplete (%#x).\n", lp->tx_reap);
@@ -619,11 +629,11 @@
 			printk("%s: Rx unit stopped, status %04x, restarting.\n",
 				   dev->name, status);
 		init_rx_bufs(dev);
-		isa_writew(RX_BUF_START,shmem+iSCB_RFA);
+		writew(RX_BUF_START,shmem+iSCB_RFA);
 		ack_cmd |= RX_START;
 	}
 
-	isa_writew(ack_cmd,shmem+iSCB_CMD);
+	writew(ack_cmd,shmem+iSCB_CMD);
 	outb(0, ioaddr + SIGNAL_CA);			/* Issue channel-attn. */
 
 	/* Clear the latched interrupt. */
@@ -637,13 +647,14 @@
 
 static int el16_close(struct net_device *dev)
 {
+	struct net_local *lp = netdev_priv(dev);
 	int ioaddr = dev->base_addr;
-	unsigned long shmem = dev->mem_start;
+	void __iomem *shmem = lp->base;
 
 	netif_stop_queue(dev);
 
 	/* Flush the Tx and disable Rx. */
-	isa_writew(RX_SUSPEND | CUC_SUSPEND,shmem+iSCB_CMD);
+	writew(RX_SUSPEND | CUC_SUSPEND,shmem+iSCB_CMD);
 	outb(0, ioaddr + SIGNAL_CA);
 
 	/* Disable the 82586's input to the interrupt line. */
@@ -671,7 +682,7 @@
 static void init_rx_bufs(struct net_device *dev)
 {
 	struct net_local *lp = netdev_priv(dev);
-	unsigned long write_ptr;
+	void __iomem *write_ptr;
 	unsigned short SCB_base = SCB_BASE;
 
 	int cur_rxbuf = lp->rx_head = RX_BUF_START;
@@ -679,26 +690,26 @@
 	/* Initialize each Rx frame + data buffer. */
 	do {	/* While there is room for one more. */
 
-	  write_ptr = dev->mem_start + cur_rxbuf;
+		write_ptr = lp->base + cur_rxbuf;
 
-		isa_writew(0x0000,write_ptr);			/* Status */
-		isa_writew(0x0000,write_ptr+=2);			/* Command */
-		isa_writew(cur_rxbuf + RX_BUF_SIZE,write_ptr+=2);	/* Link */
-		isa_writew(cur_rxbuf + 22,write_ptr+=2);		/* Buffer offset */
-		isa_writew(0x0000,write_ptr+=2);			/* Pad for dest addr. */
-		isa_writew(0x0000,write_ptr+=2);
-		isa_writew(0x0000,write_ptr+=2);
-		isa_writew(0x0000,write_ptr+=2);			/* Pad for source addr. */
-		isa_writew(0x0000,write_ptr+=2);
-		isa_writew(0x0000,write_ptr+=2);
-		isa_writew(0x0000,write_ptr+=2);			/* Pad for protocol. */
-
-		isa_writew(0x0000,write_ptr+=2);			/* Buffer: Actual count */
-		isa_writew(-1,write_ptr+=2);			/* Buffer: Next (none). */
-		isa_writew(cur_rxbuf + 0x20 + SCB_base,write_ptr+=2);/* Buffer: Address low */
-		isa_writew(0x0000,write_ptr+=2);
+		writew(0x0000,write_ptr);			/* Status */
+		writew(0x0000,write_ptr+=2);			/* Command */
+		writew(cur_rxbuf + RX_BUF_SIZE,write_ptr+=2);	/* Link */
+		writew(cur_rxbuf + 22,write_ptr+=2);		/* Buffer offset */
+		writew(0x0000,write_ptr+=2);			/* Pad for dest addr. */
+		writew(0x0000,write_ptr+=2);
+		writew(0x0000,write_ptr+=2);
+		writew(0x0000,write_ptr+=2);			/* Pad for source addr. */
+		writew(0x0000,write_ptr+=2);
+		writew(0x0000,write_ptr+=2);
+		writew(0x0000,write_ptr+=2);			/* Pad for protocol. */
+
+		writew(0x0000,write_ptr+=2);			/* Buffer: Actual count */
+		writew(-1,write_ptr+=2);			/* Buffer: Next (none). */
+		writew(cur_rxbuf + 0x20 + SCB_base,write_ptr+=2);/* Buffer: Address low */
+		writew(0x0000,write_ptr+=2);
 		/* Finally, the number of bytes in the buffer. */
-		isa_writew(0x8000 + RX_BUF_SIZE-0x20,write_ptr+=2);
+		writew(0x8000 + RX_BUF_SIZE-0x20,write_ptr+=2);
 
 		lp->rx_tail = cur_rxbuf;
 		cur_rxbuf += RX_BUF_SIZE;
@@ -706,16 +717,16 @@
 
 	/* Terminate the list by setting the EOL bit, and wrap the pointer to make
 	   the list a ring. */
-	write_ptr = dev->mem_start + lp->rx_tail + 2;
-	isa_writew(0xC000,write_ptr);				/* Command, mark as last. */
-	isa_writew(lp->rx_head,write_ptr+2);			/* Link */
+	write_ptr = lp->base + lp->rx_tail + 2;
+	writew(0xC000,write_ptr);				/* Command, mark as last. */
+	writew(lp->rx_head,write_ptr+2);			/* Link */
 }
 
 static void init_82586_mem(struct net_device *dev)
 {
 	struct net_local *lp = netdev_priv(dev);
 	short ioaddr = dev->base_addr;
-	unsigned long shmem = dev->mem_start;
+	void __iomem *shmem = lp->base;
 
 	/* Enable loopback to protect the wire while starting up,
 	   and hold the 586 in reset during the memory initialization. */
@@ -726,13 +737,13 @@
 	init_words[7] = SCB_BASE;
 
 	/* Write the words at 0xfff6 (address-aliased to 0xfffff6). */
-	isa_memcpy_toio(dev->mem_end-10, init_words, 10);
+	memcpy_toio(lp->base + RX_BUF_END - 10, init_words, 10);
 
 	/* Write the words at 0x0000. */
-	isa_memcpy_toio(dev->mem_start, init_words + 5, sizeof(init_words) - 10);
+	memcpy_toio(lp->base, init_words + 5, sizeof(init_words) - 10);
 
 	/* Fill in the station address. */
-	isa_memcpy_toio(dev->mem_start+SA_OFFSET, dev->dev_addr,
+	memcpy_toio(lp->base+SA_OFFSET, dev->dev_addr,
 		   sizeof(dev->dev_addr));
 
 	/* The Tx-block list is written as needed.  We just set up the values. */
@@ -750,11 +761,11 @@
 
 	{
 		int boguscnt = 50;
-		while (isa_readw(shmem+iSCB_STATUS) == 0)
+		while (readw(shmem+iSCB_STATUS) == 0)
 			if (--boguscnt == 0) {
 				printk("%s: i82586 initialization timed out with status %04x,"
 					   "cmd %04x.\n", dev->name,
-					   isa_readw(shmem+iSCB_STATUS), isa_readw(shmem+iSCB_CMD));
+					   readw(shmem+iSCB_STATUS), readw(shmem+iSCB_CMD));
 				break;
 			}
 		/* Issue channel-attn -- the 82586 won't start. */
@@ -765,7 +776,7 @@
 	outb(0x84, ioaddr + MISC_CTRL);
 	if (net_debug > 4)
 		printk("%s: Initialized 82586, status %04x.\n", dev->name,
-			   isa_readw(shmem+iSCB_STATUS));
+			   readw(shmem+iSCB_STATUS));
 	return;
 }
 
@@ -774,33 +785,33 @@
 	struct net_local *lp = netdev_priv(dev);
 	short ioaddr = dev->base_addr;
 	ushort tx_block = lp->tx_head;
-	unsigned long write_ptr = dev->mem_start + tx_block;
+	void __iomem *write_ptr = lp->base + tx_block;
 	static char padding[ETH_ZLEN];
 
 	/* Set the write pointer to the Tx block, and put out the header. */
-	isa_writew(0x0000,write_ptr);			/* Tx status */
-	isa_writew(CMD_INTR|CmdTx,write_ptr+=2);		/* Tx command */
-	isa_writew(tx_block+16,write_ptr+=2);		/* Next command is a NoOp. */
-	isa_writew(tx_block+8,write_ptr+=2);			/* Data Buffer offset. */
+	writew(0x0000,write_ptr);			/* Tx status */
+	writew(CMD_INTR|CmdTx,write_ptr+=2);		/* Tx command */
+	writew(tx_block+16,write_ptr+=2);		/* Next command is a NoOp. */
+	writew(tx_block+8,write_ptr+=2);			/* Data Buffer offset. */
 
 	/* Output the data buffer descriptor. */
-	isa_writew((pad + length) | 0x8000,write_ptr+=2);		/* Byte count parameter. */
-	isa_writew(-1,write_ptr+=2);			/* No next data buffer. */
-	isa_writew(tx_block+22+SCB_BASE,write_ptr+=2);	/* Buffer follows the NoOp command. */
-	isa_writew(0x0000,write_ptr+=2);			/* Buffer address high bits (always zero). */
+	writew((pad + length) | 0x8000,write_ptr+=2);		/* Byte count parameter. */
+	writew(-1,write_ptr+=2);			/* No next data buffer. */
+	writew(tx_block+22+SCB_BASE,write_ptr+=2);	/* Buffer follows the NoOp command. */
+	writew(0x0000,write_ptr+=2);			/* Buffer address high bits (always zero). */
 
 	/* Output the Loop-back NoOp command. */
-	isa_writew(0x0000,write_ptr+=2);			/* Tx status */
-	isa_writew(CmdNOp,write_ptr+=2);			/* Tx command */
-	isa_writew(tx_block+16,write_ptr+=2);		/* Next is myself. */
+	writew(0x0000,write_ptr+=2);			/* Tx status */
+	writew(CmdNOp,write_ptr+=2);			/* Tx command */
+	writew(tx_block+16,write_ptr+=2);		/* Next is myself. */
 
 	/* Output the packet at the write pointer. */
-	isa_memcpy_toio(write_ptr+2, buf, length);
+	memcpy_toio(write_ptr+2, buf, length);
 	if (pad)
-		isa_memcpy_toio(write_ptr+length+2, padding, pad);
+		memcpy_toio(write_ptr+length+2, padding, pad);
 
 	/* Set the old command link pointing to this send packet. */
-	isa_writew(tx_block,dev->mem_start + lp->tx_cmd_link);
+	writew(tx_block,lp->base + lp->tx_cmd_link);
 	lp->tx_cmd_link = tx_block + 20;
 
 	/* Set the next free tx region. */
@@ -821,19 +832,19 @@
 static void el16_rx(struct net_device *dev)
 {
 	struct net_local *lp = netdev_priv(dev);
-	unsigned long shmem = dev->mem_start;
+	void __iomem *shmem = lp->base;
 	ushort rx_head = lp->rx_head;
 	ushort rx_tail = lp->rx_tail;
 	ushort boguscount = 10;
 	short frame_status;
 
-	while ((frame_status = isa_readw(shmem+rx_head)) < 0) {   /* Command complete */
-		unsigned long read_frame = dev->mem_start + rx_head;
-		ushort rfd_cmd = isa_readw(read_frame+2);
-		ushort next_rx_frame = isa_readw(read_frame+4);
-		ushort data_buffer_addr = isa_readw(read_frame+6);
-		unsigned long data_frame = dev->mem_start + data_buffer_addr;
-		ushort pkt_len = isa_readw(data_frame);
+	while ((frame_status = readw(shmem+rx_head)) < 0) {   /* Command complete */
+		void __iomem *read_frame = lp->base + rx_head;
+		ushort rfd_cmd = readw(read_frame+2);
+		ushort next_rx_frame = readw(read_frame+4);
+		ushort data_buffer_addr = readw(read_frame+6);
+		void __iomem *data_frame = lp->base + data_buffer_addr;
+		ushort pkt_len = readw(data_frame);
 
 		if (rfd_cmd != 0 || data_buffer_addr != rx_head + 22
 			|| (pkt_len & 0xC000) != 0xC000) {
@@ -865,7 +876,7 @@
 			skb->dev = dev;
 
 			/* 'skb->data' points to the start of sk_buff data area. */
-			isa_memcpy_fromio(skb_put(skb,pkt_len), data_frame + 10, pkt_len);
+			memcpy_fromio(skb_put(skb,pkt_len), data_frame + 10, pkt_len);
 
 			skb->protocol=eth_type_trans(skb,dev);
 			netif_rx(skb);
@@ -875,10 +886,10 @@
 		}
 
 		/* Clear the status word and set End-of-List on the rx frame. */
-		isa_writew(0,read_frame);
-		isa_writew(0xC000,read_frame+2);
+		writew(0,read_frame);
+		writew(0xC000,read_frame+2);
 		/* Clear the end-of-list on the prev. RFD. */
-		isa_writew(0x0000,dev->mem_start + rx_tail + 2);
+		writew(0x0000,lp->base + rx_tail + 2);
 
 		rx_tail = rx_head;
 		rx_head = next_rx_frame;
@@ -916,8 +927,8 @@
 
 #ifdef MODULE
 static struct net_device *dev_3c507;
-MODULE_PARM(io, "i");
-MODULE_PARM(irq, "i");
+module_param(io, int, 0);
+module_param(irq, int, 0);
 MODULE_PARM_DESC(io, "EtherLink16 I/O base address");
 MODULE_PARM_DESC(irq, "(ignored)");
 
@@ -935,6 +946,7 @@
 	struct net_device *dev = dev_3c507;
 	unregister_netdev(dev);
 	free_irq(dev->irq, dev);
+	iounmap(((struct net_local *)netdev_priv(dev))->base);
 	release_region(dev->base_addr, EL16_IO_EXTENT);
 	free_netdev(dev);
 }
diff -Nru a/drivers/net/3c509.c b/drivers/net/3c509.c
--- a/drivers/net/3c509.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/net/3c509.c	2005-03-01 23:39:18 -08:00
@@ -209,6 +209,9 @@
 #if defined(CONFIG_EISA) || defined(CONFIG_MCA)
 static int el3_device_remove (struct device *device);
 #endif
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void el3_poll_controller(struct net_device *dev);
+#endif
 
 #ifdef CONFIG_EISA
 struct eisa_device_id el3_eisa_ids[] = {
@@ -321,6 +324,9 @@
 	dev->set_multicast_list = &set_multicast_list;
 	dev->tx_timeout = el3_tx_timeout;
 	dev->watchdog_timeo = TX_TIMEOUT;
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	dev->poll_controller = el3_poll_controller;
+#endif
 	SET_ETHTOOL_OPS(dev, &ethtool_ops);
 
 	err = register_netdev(dev);
@@ -999,6 +1005,19 @@
 }
 
 
+#ifdef CONFIG_NET_POLL_CONTROLLER
+/*
+ * Polling receive - used by netconsole and other diagnostic tools
+ * to allow network i/o with interrupts disabled.
+ */
+static void el3_poll_controller(struct net_device *dev)
+{
+	disable_irq(dev->irq);
+	el3_interrupt(dev->irq, dev, NULL);
+	enable_irq(dev->irq);
+}
+#endif
+
 static struct net_device_stats *
 el3_get_stats(struct net_device *dev)
 {
@@ -1535,16 +1554,16 @@
 static int irq[] = {-1, -1, -1, -1, -1, -1, -1, -1};
 static int xcvr[] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
 
-MODULE_PARM(debug,"i");
-MODULE_PARM(irq,"1-8i");
-MODULE_PARM(xcvr,"1-12i");
-MODULE_PARM(max_interrupt_work, "i");
+module_param(debug,int, 0);
+module_param_array(irq, int, NULL, 0);
+module_param_array(xcvr, int, NULL, 0);
+module_param(max_interrupt_work, int, 0);
 MODULE_PARM_DESC(debug, "debug level (0-6)");
 MODULE_PARM_DESC(irq, "IRQ number(s) (assigned)");
 MODULE_PARM_DESC(xcvr,"transceiver(s) (0=internal, 1=external)");
 MODULE_PARM_DESC(max_interrupt_work, "maximum events handled per interrupt");
 #if defined(__ISAPNP__)
-MODULE_PARM(nopnp, "i");
+module_param(nopnp, int, 0);
 MODULE_PARM_DESC(nopnp, "disable ISA PnP support (0-1)");
 MODULE_DEVICE_TABLE(isapnp, el3_isapnp_adapters);
 #endif	/* __ISAPNP__ */
diff -Nru a/drivers/net/3c515.c b/drivers/net/3c515.c
--- a/drivers/net/3c515.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/net/3c515.c	2005-03-01 23:38:53 -08:00
@@ -34,7 +34,7 @@
 /* "Knobs" that adjust features and parameters. */
 /* Set the copy breakpoint for the copy-only-tiny-frames scheme.
    Setting to > 1512 effectively disables this feature. */
-static const int rx_copybreak = 200;
+static int rx_copybreak = 200;
 
 /* Allow setting MTU to a larger size, bypassing the normal ethernet setup. */
 static const int mtu = 1500;
@@ -87,15 +87,6 @@
 MODULE_DESCRIPTION("3Com 3c515 Corkscrew driver");
 MODULE_LICENSE("GPL");
 
-MODULE_PARM(debug, "i");
-MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i");
-MODULE_PARM(rx_copybreak, "i");
-MODULE_PARM(max_interrupt_work, "i");
-MODULE_PARM_DESC(debug, "3c515 debug level (0-6)");
-MODULE_PARM_DESC(options, "3c515: Bits 0-2: media type, bit 3: full duplex, bit 4: bus mastering");
-MODULE_PARM_DESC(rx_copybreak, "3c515 copy breakpoint for copy-only-tiny-frames");
-MODULE_PARM_DESC(max_interrupt_work, "3c515 maximum events handled per interrupt");
-
 /* "Knobs" for adjusting internal parameters. */
 /* Put out somewhat more debugging messages. (0 - no msg, 1 minimal msgs). */
 #define DRIVER_DEBUG 1
@@ -409,6 +400,16 @@
 
 #ifdef MODULE
 static int debug = -1;
+
+module_param(debug, int, 0);
+module_param_array(options, int, NULL, 0);
+module_param(rx_copybreak, int, 0);
+module_param(max_interrupt_work, int, 0);
+MODULE_PARM_DESC(debug, "3c515 debug level (0-6)");
+MODULE_PARM_DESC(options, "3c515: Bits 0-2: media type, bit 3: full duplex, bit 4: bus mastering");
+MODULE_PARM_DESC(rx_copybreak, "3c515 copy breakpoint for copy-only-tiny-frames");
+MODULE_PARM_DESC(max_interrupt_work, "3c515 maximum events handled per interrupt");
+
 /* A list of all installed Vortex devices, for removing the driver module. */
 /* we will need locking (and refcounting) if we ever use it for more */
 static LIST_HEAD(root_corkscrew_dev);
diff -Nru a/drivers/net/3c523.c b/drivers/net/3c523.c
--- a/drivers/net/3c523.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/net/3c523.c	2005-03-01 23:39:18 -08:00
@@ -1271,8 +1271,8 @@
 static struct net_device *dev_elmc[MAX_3C523_CARDS];
 static int irq[MAX_3C523_CARDS];
 static int io[MAX_3C523_CARDS];
-MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_3C523_CARDS) "i");
-MODULE_PARM(io, "1-" __MODULE_STRING(MAX_3C523_CARDS) "i");
+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)");
 
diff -Nru a/drivers/net/3c59x.c b/drivers/net/3c59x.c
--- a/drivers/net/3c59x.c	2005-03-01 23:38:44 -08:00
+++ b/drivers/net/3c59x.c	2005-03-01 23:38:44 -08:00
@@ -277,37 +277,8 @@
 MODULE_DESCRIPTION("3Com 3c59x/3c9xx ethernet driver "
 					DRV_VERSION " " DRV_RELDATE);
 MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
 
-MODULE_PARM(debug, "i");
-MODULE_PARM(global_options, "i");
-MODULE_PARM(options, "1-" __MODULE_STRING(8) "i");
-MODULE_PARM(global_full_duplex, "i");
-MODULE_PARM(full_duplex, "1-" __MODULE_STRING(8) "i");
-MODULE_PARM(hw_checksums, "1-" __MODULE_STRING(8) "i");
-MODULE_PARM(flow_ctrl, "1-" __MODULE_STRING(8) "i");
-MODULE_PARM(global_enable_wol, "i");
-MODULE_PARM(enable_wol, "1-" __MODULE_STRING(8) "i");
-MODULE_PARM(rx_copybreak, "i");
-MODULE_PARM(max_interrupt_work, "i");
-MODULE_PARM(compaq_ioaddr, "i");
-MODULE_PARM(compaq_irq, "i");
-MODULE_PARM(compaq_device_id, "i");
-MODULE_PARM(watchdog, "i");
-MODULE_PARM_DESC(debug, "3c59x debug level (0-6)");
-MODULE_PARM_DESC(options, "3c59x: Bits 0-3: media type, bit 4: bus mastering, bit 9: full duplex");
-MODULE_PARM_DESC(global_options, "3c59x: same as options, but applies to all NICs if options is unset");
-MODULE_PARM_DESC(full_duplex, "3c59x full duplex setting(s) (1)");
-MODULE_PARM_DESC(global_full_duplex, "3c59x: same as full_duplex, but applies to all NICs if options is unset");
-MODULE_PARM_DESC(hw_checksums, "3c59x Hardware checksum checking by adapter(s) (0-1)");
-MODULE_PARM_DESC(flow_ctrl, "3c59x 802.3x flow control usage (PAUSE only) (0-1)");
-MODULE_PARM_DESC(enable_wol, "3c59x: Turn on Wake-on-LAN for adapter(s) (0-1)");
-MODULE_PARM_DESC(global_enable_wol, "3c59x: same as enable_wol, but applies to all NICs if options is unset");
-MODULE_PARM_DESC(rx_copybreak, "3c59x copy breakpoint for copy-only-tiny-frames");
-MODULE_PARM_DESC(max_interrupt_work, "3c59x maximum events handled per interrupt");
-MODULE_PARM_DESC(compaq_ioaddr, "3c59x PCI I/O base address (Compaq BIOS problem workaround)");
-MODULE_PARM_DESC(compaq_irq, "3c59x PCI IRQ number (Compaq BIOS problem workaround)");
-MODULE_PARM_DESC(compaq_device_id, "3c59x PCI device ID (Compaq BIOS problem workaround)");
-MODULE_PARM_DESC(watchdog, "3c59x transmit timeout in milliseconds");
 
 /* Operational parameter that usually are not changed. */
 
@@ -416,7 +387,7 @@
 	HAS_PWR_CTRL=0x20, HAS_MII=0x40, HAS_NWAY=0x80, HAS_CB_FNS=0x100,
 	INVERT_MII_PWR=0x200, INVERT_LED_PWR=0x400, MAX_COLLISION_RESET=0x800,
 	EEPROM_OFFSET=0x1000, HAS_HWCKSM=0x2000, WNO_XCVR_PWR=0x4000,
-	EXTRA_PREAMBLE=0x8000, };
+	EXTRA_PREAMBLE=0x8000, EEPROM_RESET=0x10000, };
 
 enum vortex_chips {
 	CH_3C590 = 0,
@@ -491,9 +462,9 @@
 	{"3c595 Vortex 100base-MII",
 	 PCI_USES_IO|PCI_USES_MASTER, IS_VORTEX, 32, },
 	{"3c900 Boomerang 10baseT",
-	 PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG, 64, },
+	 PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG|EEPROM_RESET, 64, },
 	{"3c900 Boomerang 10Mbps Combo",
-	 PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG, 64, },
+	 PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG|EEPROM_RESET, 64, },
 	{"3c900 Cyclone 10Mbps TPO",						/* AKPM: from Don's 0.99M */
 	 PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, },
 	{"3c900 Cyclone 10Mbps Combo",
@@ -504,9 +475,9 @@
 	{"3c900B-FL Cyclone 10base-FL",
 	 PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, },
 	{"3c905 Boomerang 100baseTx",
-	 PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG|HAS_MII, 64, },
+	 PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG|HAS_MII|EEPROM_RESET, 64, },
 	{"3c905 Boomerang 100baseT4",
-	 PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG|HAS_MII, 64, },
+	 PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG|HAS_MII|EEPROM_RESET, 64, },
 	{"3c905B Cyclone 100baseTx",
 	 PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM|EXTRA_PREAMBLE, 128, },
 
@@ -781,6 +752,12 @@
 /* Chip features we care about in vp->capabilities, read from the EEPROM. */
 enum ChipCaps { CapBusMaster=0x20, CapPwrMgmt=0x2000 };
 
+struct vortex_extra_stats {
+        unsigned long tx_deferred;
+        unsigned long tx_multiple_collisions;
+        unsigned long rx_bad_ssd;
+};
+
 struct vortex_private {
 	/* The Rx and Tx rings should be quad-word-aligned. */
 	struct boom_rx_desc* rx_ring;
@@ -792,7 +769,8 @@
 	struct sk_buff* tx_skbuff[TX_RING_SIZE];
 	unsigned int cur_rx, cur_tx;		/* The next free ring entry */
 	unsigned int dirty_rx, dirty_tx;	/* The ring entries to be free()ed. */
-	struct net_device_stats stats;
+	struct net_device_stats stats;		/* Generic stats */
+	struct vortex_extra_stats xstats;	/* NIC-specific extra stats */
 	struct sk_buff *tx_skb;				/* Packet being eaten by bus master ctrl.  */
 	dma_addr_t tx_skb_dma;				/* Allocated DMA address for bus master ctrl DMA.   */
 
@@ -833,7 +811,7 @@
 										 * bale from the ISR */
 	u16 io_size;						/* Size of PCI region (for release_region) */
 	spinlock_t lock;					/* Serialise access to device & its vortex_private */
-	spinlock_t mdio_lock;				/* Serialise access to mdio hardware */
+	struct mii_if_info mii;				/* MII lib hooks/info */
 };
 
 #ifdef CONFIG_PCI
@@ -880,6 +858,17 @@
   { "Default",	 0,			0xFF, XCVR_10baseT, 10000},
 };
 
+static struct {
+	const char str[ETH_GSTRING_LEN];
+} ethtool_stats_keys[] = {
+	{ "tx_deferred" },
+	{ "tx_multiple_collisions" },
+	{ "rx_bad_ssd" },
+};
+
+/* number of ETHTOOL_GSTATS u64's */
+#define VORTEX_NUM_STATS     3
+
 static int vortex_probe1(struct device *gendev, long ioaddr, int irq,
 				   int chip_idx, int card_idx);
 static void vortex_up(struct net_device *dev);
@@ -930,10 +919,41 @@
 
 static int vortex_cards_found;
 
+module_param(debug, int, 0);
+module_param(global_options, int, 0);
+module_param_array(options, int, NULL, 0);
+module_param(global_full_duplex, int, 0);
+module_param_array(full_duplex, int, NULL, 0);
+module_param_array(hw_checksums, int, NULL, 0);
+module_param_array(flow_ctrl, int, NULL, 0);
+module_param(global_enable_wol, int, 0);
+module_param_array(enable_wol, int, NULL, 0);
+module_param(rx_copybreak, int, 0);
+module_param(max_interrupt_work, int, 0);
+module_param(compaq_ioaddr, int, 0);
+module_param(compaq_irq, int, 0);
+module_param(compaq_device_id, int, 0);
+module_param(watchdog, int, 0);
+MODULE_PARM_DESC(debug, "3c59x debug level (0-6)");
+MODULE_PARM_DESC(options, "3c59x: Bits 0-3: media type, bit 4: bus mastering, bit 9: full duplex");
+MODULE_PARM_DESC(global_options, "3c59x: same as options, but applies to all NICs if options is unset");
+MODULE_PARM_DESC(full_duplex, "3c59x full duplex setting(s) (1)");
+MODULE_PARM_DESC(global_full_duplex, "3c59x: same as full_duplex, but applies to all NICs if options is unset");
+MODULE_PARM_DESC(hw_checksums, "3c59x Hardware checksum checking by adapter(s) (0-1)");
+MODULE_PARM_DESC(flow_ctrl, "3c59x 802.3x flow control usage (PAUSE only) (0-1)");
+MODULE_PARM_DESC(enable_wol, "3c59x: Turn on Wake-on-LAN for adapter(s) (0-1)");
+MODULE_PARM_DESC(global_enable_wol, "3c59x: same as enable_wol, but applies to all NICs if options is unset");
+MODULE_PARM_DESC(rx_copybreak, "3c59x copy breakpoint for copy-only-tiny-frames");
+MODULE_PARM_DESC(max_interrupt_work, "3c59x maximum events handled per interrupt");
+MODULE_PARM_DESC(compaq_ioaddr, "3c59x PCI I/O base address (Compaq BIOS problem workaround)");
+MODULE_PARM_DESC(compaq_irq, "3c59x PCI IRQ number (Compaq BIOS problem workaround)");
+MODULE_PARM_DESC(compaq_device_id, "3c59x PCI device ID (Compaq BIOS problem workaround)");
+MODULE_PARM_DESC(watchdog, "3c59x transmit timeout in milliseconds");
+
 #ifdef CONFIG_NET_POLL_CONTROLLER
 static void poll_vortex(struct net_device *dev)
 {
-	struct vortex_private *vp = (struct vortex_private *)dev->priv;
+	struct vortex_private *vp = netdev_priv(dev);
 	unsigned long flags;
 	local_save_flags(flags);
 	local_irq_disable();
@@ -1074,14 +1094,20 @@
 	int rc;
 
 	/* wake up and enable device */		
-	if (pci_enable_device (pdev)) {
-		rc = -EIO;
-	} else {
-		rc = vortex_probe1 (&pdev->dev, pci_resource_start (pdev, 0),
-							pdev->irq, ent->driver_data, vortex_cards_found);
-		if (rc == 0)
-			vortex_cards_found++;
+	rc = pci_enable_device (pdev);
+	if (rc < 0)
+		goto out;
+
+	rc = vortex_probe1 (&pdev->dev, pci_resource_start (pdev, 0),
+						pdev->irq, ent->driver_data, vortex_cards_found);
+	if (rc < 0) {
+		pci_disable_device (pdev);
+		goto out;
 	}
+
+	vortex_cards_found++;
+
+out:
 	return rc;
 }
 
@@ -1210,8 +1236,12 @@
 	}
 
 	spin_lock_init(&vp->lock);
-	spin_lock_init(&vp->mdio_lock);
 	vp->gendev = gendev;
+	vp->mii.dev = dev;
+	vp->mii.mdio_read = mdio_read;
+	vp->mii.mdio_write = mdio_write;
+	vp->mii.phy_id_mask = 0x1f;
+	vp->mii.reg_num_mask = 0x1f;
 
 	/* Makes sure rings are at least 16 byte aligned. */
 	vp->rx_ring = pci_alloc_consistent(pdev, sizeof(struct boom_rx_desc) * RX_RING_SIZE
@@ -1446,6 +1476,7 @@
 				mdio_write(dev, vp->phys[0], 4, vp->advertising);
 			}
 		}
+		vp->mii.phy_id = vp->phys[0];
 	}
 
 	if (vp->capabilities & CapBusMaster) {
@@ -1491,7 +1522,7 @@
 #ifdef CONFIG_NET_POLL_CONTROLLER
 	dev->poll_controller = poll_vortex; 
 #endif
-	if (pdev && vp->enable_wol) {
+	if (pdev) {
 		vp->pm_state_valid = 1;
  		pci_save_state(VORTEX_PCI(vp));
  		acpi_set_WOL(dev);
@@ -1548,9 +1579,10 @@
 	unsigned int config;
 	int i;
 
-	if (VORTEX_PCI(vp) && vp->enable_wol) {
-		pci_set_power_state(VORTEX_PCI(vp), 0);	/* Go active */
+	if (VORTEX_PCI(vp)) {
+		pci_set_power_state(VORTEX_PCI(vp), PCI_D0);	/* Go active */
 		pci_restore_state(VORTEX_PCI(vp));
+		pci_enable_device(VORTEX_PCI(vp));
 	}
 
 	/* Before initializing select the active media port. */
@@ -1838,6 +1870,7 @@
 		break;
 	case XCVR_MII: case XCVR_NWAY:
 		{
+			spin_lock_bh(&vp->lock);
 			mii_status = mdio_read(dev, vp->phys[0], 1);
 			ok = 1;
 			if (vortex_debug > 2)
@@ -1871,6 +1904,7 @@
 			} else {
 				netif_carrier_off(dev);
 			}
+			spin_unlock_bh(&vp->lock);
 		}
 		break;
 	  default:					/* Other media types handled by Tx timeouts. */
@@ -2706,7 +2740,7 @@
 	if (vp->full_bus_master_tx)
 		outl(0, ioaddr + DownListPtr);
 
-	if (final_down && VORTEX_PCI(vp) && vp->enable_wol) {
+	if (final_down && VORTEX_PCI(vp)) {
 		pci_save_state(VORTEX_PCI(vp));
 		acpi_set_WOL(dev);
 	}
@@ -2839,23 +2873,23 @@
 	/* Switch to the stats window, and read everything. */
 	EL3WINDOW(6);
 	vp->stats.tx_carrier_errors		+= inb(ioaddr + 0);
-	vp->stats.tx_heartbeat_errors	+= inb(ioaddr + 1);
-	/* Multiple collisions. */		inb(ioaddr + 2);
+	vp->stats.tx_heartbeat_errors		+= inb(ioaddr + 1);
 	vp->stats.collisions			+= inb(ioaddr + 3);
 	vp->stats.tx_window_errors		+= inb(ioaddr + 4);
 	vp->stats.rx_fifo_errors		+= inb(ioaddr + 5);
 	vp->stats.tx_packets			+= inb(ioaddr + 6);
 	vp->stats.tx_packets			+= (inb(ioaddr + 9)&0x30) << 4;
-	/* Rx packets	*/				inb(ioaddr + 7);   /* Must read to clear */
-	/* Tx deferrals */				inb(ioaddr + 8);
+	/* Rx packets	*/			inb(ioaddr + 7);   /* Must read to clear */
 	/* Don't bother with register 9, an extension of registers 6&7.
 	   If we do use the 6&7 values the atomic update assumption above
 	   is invalid. */
-	vp->stats.rx_bytes += inw(ioaddr + 10);
-	vp->stats.tx_bytes += inw(ioaddr + 12);
-	/* New: On the Vortex we must also clear the BadSSD counter. */
+	vp->stats.rx_bytes 			+= inw(ioaddr + 10);
+	vp->stats.tx_bytes 			+= inw(ioaddr + 12);
+	/* Extra stats for get_ethtool_stats() */
+	vp->xstats.tx_multiple_collisions	+= inb(ioaddr + 2);
+	vp->xstats.tx_deferred			+= inb(ioaddr + 8);
 	EL3WINDOW(4);
-	inb(ioaddr + 12);
+	vp->xstats.rx_bad_ssd			+= inb(ioaddr + 12);
 
 	{
 		u8 up = inb(ioaddr + 13);
@@ -2867,6 +2901,104 @@
 	return;
 }
 
+static int vortex_nway_reset(struct net_device *dev)
+{
+	struct vortex_private *vp = netdev_priv(dev);
+	long ioaddr = dev->base_addr;
+	unsigned long flags;
+	int rc;
+
+	spin_lock_irqsave(&vp->lock, flags);
+	EL3WINDOW(4);
+	rc = mii_nway_restart(&vp->mii);
+	spin_unlock_irqrestore(&vp->lock, flags);
+	return rc;
+}
+
+static u32 vortex_get_link(struct net_device *dev)
+{
+	struct vortex_private *vp = netdev_priv(dev);
+	long ioaddr = dev->base_addr;
+	unsigned long flags;
+	int rc;
+
+	spin_lock_irqsave(&vp->lock, flags);
+	EL3WINDOW(4);
+	rc = mii_link_ok(&vp->mii);
+	spin_unlock_irqrestore(&vp->lock, flags);
+	return rc;
+}
+
+static int vortex_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+	struct vortex_private *vp = netdev_priv(dev);
+	long ioaddr = dev->base_addr;
+	unsigned long flags;
+	int rc;
+
+	spin_lock_irqsave(&vp->lock, flags);
+	EL3WINDOW(4);
+	rc = mii_ethtool_gset(&vp->mii, cmd);
+	spin_unlock_irqrestore(&vp->lock, flags);
+	return rc;
+}
+
+static int vortex_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+	struct vortex_private *vp = netdev_priv(dev);
+	long ioaddr = dev->base_addr;
+	unsigned long flags;
+	int rc;
+
+	spin_lock_irqsave(&vp->lock, flags);
+	EL3WINDOW(4);
+	rc = mii_ethtool_sset(&vp->mii, cmd);
+	spin_unlock_irqrestore(&vp->lock, flags);
+	return rc;
+}
+
+static u32 vortex_get_msglevel(struct net_device *dev)
+{
+	return vortex_debug;
+}
+
+static void vortex_set_msglevel(struct net_device *dev, u32 dbg)
+{
+	vortex_debug = dbg;
+}
+
+static int vortex_get_stats_count(struct net_device *dev)
+{
+	return VORTEX_NUM_STATS;
+}
+
+static void vortex_get_ethtool_stats(struct net_device *dev,
+	struct ethtool_stats *stats, u64 *data)
+{
+	struct vortex_private *vp = netdev_priv(dev);
+	unsigned long flags;
+
+	spin_lock_irqsave(&vp->lock, flags);
+	update_stats(dev->base_addr, dev);
+	spin_unlock_irqrestore(&vp->lock, flags);
+
+	data[0] = vp->xstats.tx_deferred;
+	data[1] = vp->xstats.tx_multiple_collisions;
+	data[2] = vp->xstats.rx_bad_ssd;
+}
+
+
+static void vortex_get_strings(struct net_device *dev, u32 stringset, u8 *data)
+{
+	switch (stringset) {
+	case ETH_SS_STATS:
+		memcpy(data, &ethtool_stats_keys, sizeof(ethtool_stats_keys));
+		break;
+	default:
+		WARN_ON(1);
+		break;
+	}
+}
 
 static void vortex_get_drvinfo(struct net_device *dev,
 					struct ethtool_drvinfo *info)
@@ -2888,44 +3020,18 @@
 
 static struct ethtool_ops vortex_ethtool_ops = {
 	.get_drvinfo		= vortex_get_drvinfo,
+	.get_strings            = vortex_get_strings,
+	.get_msglevel           = vortex_get_msglevel,
+	.set_msglevel           = vortex_set_msglevel,
+	.get_ethtool_stats      = vortex_get_ethtool_stats,
+	.get_stats_count        = vortex_get_stats_count,
+	.get_settings           = vortex_get_settings,
+	.set_settings           = vortex_set_settings,
+	.get_link               = vortex_get_link,
+	.nway_reset             = vortex_nway_reset,
 };
 
 #ifdef CONFIG_PCI
-static int vortex_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
-{
-	struct vortex_private *vp = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
-	struct mii_ioctl_data *data = if_mii(rq);
-	int phy = vp->phys[0] & 0x1f;
-	int retval;
-
-	switch(cmd) {
-	case SIOCGMIIPHY:		/* Get address of MII PHY in use. */
-		data->phy_id = phy;
-
-	case SIOCGMIIREG:		/* Read MII PHY register. */
-		EL3WINDOW(4);
-		data->val_out = mdio_read(dev, data->phy_id & 0x1f, data->reg_num & 0x1f);
-		retval = 0;
-		break;
-
-	case SIOCSMIIREG:		/* Write MII PHY register. */
-		if (!capable(CAP_NET_ADMIN)) {
-			retval = -EPERM;
-		} else {
-			EL3WINDOW(4);
-			mdio_write(dev, data->phy_id & 0x1f, data->reg_num & 0x1f, data->val_in);
-			retval = 0;
-		}
-		break;
-	default:
-		retval = -EOPNOTSUPP;
-		break;
-	}
-
-	return retval;
-}
-
 /*
  *	Must power the device up to do MDIO operations
  */
@@ -2933,6 +3039,8 @@
 {
 	int err;
 	struct vortex_private *vp = netdev_priv(dev);
+	long ioaddr = dev->base_addr;
+	unsigned long flags;
 	int state = 0;
 
 	if(VORTEX_PCI(vp))
@@ -2941,8 +3049,11 @@
 	/* The kernel core really should have pci_get_power_state() */
 
 	if(state != 0)
-		pci_set_power_state(VORTEX_PCI(vp), 0);
-	err = vortex_do_ioctl(dev, rq, cmd);
+		pci_set_power_state(VORTEX_PCI(vp), PCI_D0);
+	spin_lock_irqsave(&vp->lock, flags);
+	EL3WINDOW(4);
+	err = generic_mii_ioctl(&vp->mii, if_mii(rq), cmd, NULL);
+	spin_unlock_irqrestore(&vp->lock, flags);
 	if(state != 0)
 		pci_set_power_state(VORTEX_PCI(vp), state);
 
@@ -2981,7 +3092,7 @@
 
 static void set_8021q_mode(struct net_device *dev, int enable)
 {
-	struct vortex_private *vp = (struct vortex_private *)dev->priv;
+	struct vortex_private *vp = netdev_priv(dev);
 	long ioaddr = dev->base_addr;
 	int old_window = inw(ioaddr + EL3_CMD);
 	int mac_ctrl;
@@ -3060,15 +3171,12 @@
 
 static int mdio_read(struct net_device *dev, int phy_id, int location)
 {
-	struct vortex_private *vp = netdev_priv(dev);
 	int i;
 	long ioaddr = dev->base_addr;
 	int read_cmd = (0xf6 << 10) | (phy_id << 5) | location;
 	unsigned int retval = 0;
 	long mdio_addr = ioaddr + Wn4_PhysicalMgmt;
 
-	spin_lock_bh(&vp->mdio_lock);
-
 	if (mii_preamble_required)
 		mdio_sync(ioaddr, 32);
 
@@ -3088,20 +3196,16 @@
 		outw(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr);
 		mdio_delay();
 	}
-	spin_unlock_bh(&vp->mdio_lock);
 	return retval & 0x20000 ? 0xffff : retval>>1 & 0xffff;
 }
 
 static void mdio_write(struct net_device *dev, int phy_id, int location, int value)
 {
-	struct vortex_private *vp = netdev_priv(dev);
 	long ioaddr = dev->base_addr;
 	int write_cmd = 0x50020000 | (phy_id << 23) | (location << 18) | value;
 	long mdio_addr = ioaddr + Wn4_PhysicalMgmt;
 	int i;
 
-	spin_lock_bh(&vp->mdio_lock);
-
 	if (mii_preamble_required)
 		mdio_sync(ioaddr, 32);
 
@@ -3120,7 +3224,6 @@
 		outw(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr);
 		mdio_delay();
 	}
-	spin_unlock_bh(&vp->mdio_lock);
 	return;
 }
 
@@ -3131,16 +3234,18 @@
 	struct vortex_private *vp = netdev_priv(dev);
 	long ioaddr = dev->base_addr;
 
-	/* Power up on: 1==Downloaded Filter, 2==Magic Packets, 4==Link Status. */
-	EL3WINDOW(7);
-	outw(2, ioaddr + 0x0c);
-	/* The RxFilter must accept the WOL frames. */
-	outw(SetRxFilter|RxStation|RxMulticast|RxBroadcast, ioaddr + EL3_CMD);
-	outw(RxEnable, ioaddr + EL3_CMD);
+	if (vp->enable_wol) {
+		/* Power up on: 1==Downloaded Filter, 2==Magic Packets, 4==Link Status. */
+		EL3WINDOW(7);
+		outw(2, ioaddr + 0x0c);
+		/* The RxFilter must accept the WOL frames. */
+		outw(SetRxFilter|RxStation|RxMulticast|RxBroadcast, ioaddr + EL3_CMD);
+		outw(RxEnable, ioaddr + EL3_CMD);
 
+		pci_enable_wake(VORTEX_PCI(vp), 0, 1);
+	}
 	/* Change the power state to D3; RxEnable doesn't take effect. */
-	pci_enable_wake(VORTEX_PCI(vp), 0, 1);
-	pci_set_power_state(VORTEX_PCI(vp), 3);
+	pci_set_power_state(VORTEX_PCI(vp), PCI_D3hot);
 }
 
 
@@ -3162,13 +3267,15 @@
 	 */
 	unregister_netdev(dev);
 
-	if (VORTEX_PCI(vp) && vp->enable_wol) {
-		pci_set_power_state(VORTEX_PCI(vp), 0);	/* Go active */
+	if (VORTEX_PCI(vp)) {
+		pci_set_power_state(VORTEX_PCI(vp), PCI_D0);	/* Go active */
 		if (vp->pm_state_valid)
 			pci_restore_state(VORTEX_PCI(vp));
+		pci_disable_device(VORTEX_PCI(vp));
 	}
 	/* Should really use issue_and_wait() here */
-	outw(TotalReset|0x14, dev->base_addr + EL3_CMD);
+	outw(TotalReset | ((vp->drv_flags & EEPROM_RESET) ? 0x04 : 0x14),
+	     dev->base_addr + EL3_CMD);
 
 	pci_free_consistent(pdev,
 						sizeof(struct boom_rx_desc) * RX_RING_SIZE
diff -Nru a/drivers/net/8139cp.c b/drivers/net/8139cp.c
--- a/drivers/net/8139cp.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/net/8139cp.c	2005-03-01 23:38:57 -08:00
@@ -398,6 +398,8 @@
 static struct pci_device_id cp_pci_tbl[] = {
 	{ PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8139,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
+	{ PCI_VENDOR_ID_TTTECH, PCI_DEVICE_ID_TTTECH_MC322,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
 	{ },
 };
 MODULE_DEVICE_TABLE(pci, cp_pci_tbl);
@@ -1623,7 +1625,7 @@
 static void cp_set_d3_state (struct cp_private *cp)
 {
 	pci_enable_wake (cp->pdev, 0, 1); /* Enable PME# generation */
-	pci_set_power_state (cp->pdev, 3);
+	pci_set_power_state (cp->pdev, PCI_D3hot);
 }
 
 static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
@@ -1813,7 +1815,7 @@
 		BUG();
 	unregister_netdev(dev);
 	iounmap(cp->regs);
-	if (cp->wol_enabled) pci_set_power_state (pdev, 0);
+	if (cp->wol_enabled) pci_set_power_state (pdev, PCI_D0);
 	pci_release_regions(pdev);
 	pci_clear_mwi(pdev);
 	pci_disable_device(pdev);
@@ -1863,7 +1865,7 @@
 	netif_device_attach (dev);
 	
 	if (cp->pdev && cp->wol_enabled) {
-		pci_set_power_state (cp->pdev, 0);
+		pci_set_power_state (cp->pdev, PCI_D0);
 		pci_restore_state (cp->pdev);
 	}
 	
diff -Nru a/drivers/net/8139too.c b/drivers/net/8139too.c
--- a/drivers/net/8139too.c	2005-03-01 23:38:43 -08:00
+++ b/drivers/net/8139too.c	2005-03-01 23:38:43 -08:00
@@ -108,7 +108,6 @@
 #include <linux/mii.h>
 #include <linux/completion.h>
 #include <linux/crc32.h>
-#include <linux/suspend.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
 #include <asm/irq.h>
@@ -598,6 +597,7 @@
 MODULE_AUTHOR ("Jeff Garzik <jgarzik@pobox.com>");
 MODULE_DESCRIPTION ("RealTek RTL-8139 Fast Ethernet driver");
 MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
 
 module_param(multicast_filter_limit, int, 0);
 module_param_array(media, int, NULL, 0);
@@ -1624,8 +1624,7 @@
 		do {
 			timeout = interruptible_sleep_on_timeout (&tp->thr_wait, timeout);
 			/* make swsusp happy with our thread */
-			if (current->flags & PF_FREEZE)
-				refrigerator(PF_FREEZE);
+			try_to_freeze(PF_FREEZE);
 		} while (!signal_pending (current) && (timeout > 0));
 
 		if (signal_pending (current)) {
@@ -1635,7 +1634,8 @@
 		if (tp->time_to_die)
 			break;
 
-		rtnl_lock ();
+		if (rtnl_lock_interruptible ())
+			break;
 		rtl8139_thread_iter (dev, tp, tp->mmio_addr);
 		rtnl_unlock ();
 	}
@@ -2607,7 +2607,7 @@
 
 	spin_unlock_irqrestore (&tp->lock, flags);
 
-	pci_set_power_state (pdev, 3);
+	pci_set_power_state (pdev, PCI_D3hot);
 
 	return 0;
 }
@@ -2620,7 +2620,7 @@
 	pci_restore_state (pdev);
 	if (!netif_running (dev))
 		return 0;
-	pci_set_power_state (pdev, 0);
+	pci_set_power_state (pdev, PCI_D0);
 	rtl8139_init_ring (dev);
 	rtl8139_hw_start (dev);
 	netif_device_attach (dev);
diff -Nru a/drivers/net/82596.c b/drivers/net/82596.c
--- a/drivers/net/82596.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/net/82596.c	2005-03-01 23:39:08 -08:00
@@ -150,7 +150,7 @@
 MODULE_DESCRIPTION("i82596 driver");
 MODULE_LICENSE("GPL");
 
-MODULE_PARM(i596_debug, "i");
+module_param(i596_debug, int, 0);
 MODULE_PARM_DESC(i596_debug, "i82596 debug mask");
 
 
@@ -1572,13 +1572,13 @@
 static struct net_device *dev_82596;
 
 #ifdef ENABLE_APRICOT
-MODULE_PARM(irq, "i");
+module_param(irq, int, 0);
 MODULE_PARM_DESC(irq, "Apricot IRQ number");
 #endif
 
-MODULE_PARM(debug, "i");
-MODULE_PARM_DESC(debug, "i82596 debug mask");
 static int debug = -1;
+module_param(debug, int, 0);
+MODULE_PARM_DESC(debug, "i82596 debug mask");
 
 int init_module(void)
 {
diff -Nru a/drivers/net/8390.c b/drivers/net/8390.c
--- a/drivers/net/8390.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/net/8390.c	2005-03-01 23:38:52 -08:00
@@ -43,6 +43,7 @@
   Paul Gortmaker	: Separate out Tx timeout code from Tx path.
   Paul Gortmaker	: Remove old unused single Tx buffer code.
   Hayato Fujiwara	: Add m32r support.
+  Paul Gortmaker	: use skb_padto() instead of stack scratch area
 
   Sources:
   The National Semiconductor LAN Databook, and the 3Com 3c503 databook.
@@ -272,11 +273,15 @@
 {
 	long e8390_base = dev->base_addr;
 	struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
-	int length, send_length, output_page;
+	int send_length = skb->len, output_page;
 	unsigned long flags;
-	char scratch[ETH_ZLEN];
 
-	length = skb->len;
+	if (skb->len < ETH_ZLEN) {
+		skb = skb_padto(skb, ETH_ZLEN);
+		if (skb == NULL)
+			return 0;
+		send_length = ETH_ZLEN;
+	}
 
 	/* Mask interrupts from the ethercard. 
 	   SMP: We have to grab the lock here otherwise the IRQ handler
@@ -298,8 +303,6 @@
 	
 	ei_local->irqlock = 1;
 
-	send_length = ETH_ZLEN < length ? length : ETH_ZLEN;
-    
 	/*
 	 * We have two Tx slots available for use. Find the first free
 	 * slot, and then perform some sanity checks. With two Tx bufs,
@@ -344,13 +347,7 @@
 	 * trigger the send later, upon receiving a Tx done interrupt.
 	 */
 	 
-	if (length == send_length)
-		ei_block_output(dev, length, skb->data, output_page);
-	else {
-		memset(scratch, 0, ETH_ZLEN);
-		memcpy(scratch, skb->data, skb->len);
-		ei_block_output(dev, ETH_ZLEN, scratch, output_page);
-	}
+	ei_block_output(dev, send_length, skb->data, output_page);
 		
 	if (! ei_local->txing) 
 	{
@@ -1114,7 +1111,6 @@
 #ifdef CONFIG_NET_POLL_CONTROLLER
 EXPORT_SYMBOL(ei_poll);
 #endif
-EXPORT_SYMBOL(ei_tx_timeout);
 EXPORT_SYMBOL(NS8390_init);
 EXPORT_SYMBOL(__alloc_ei_netdev);
 
diff -Nru a/drivers/net/8390.h b/drivers/net/8390.h
--- a/drivers/net/8390.h	2005-03-01 23:39:08 -08:00
+++ b/drivers/net/8390.h	2005-03-01 23:39:08 -08:00
@@ -52,6 +52,7 @@
 	void (*block_input)(struct net_device *, int, struct sk_buff *, int);
 	unsigned long rmem_start;
 	unsigned long rmem_end;
+	void __iomem *mem;
 	unsigned char mcfilter[8];
 	unsigned open:1;
 	unsigned word16:1;  		/* We have the 16-bit (vs 8-bit) version of the card. */
diff -Nru a/drivers/net/Kconfig b/drivers/net/Kconfig
--- a/drivers/net/Kconfig	2005-03-01 23:39:09 -08:00
+++ b/drivers/net/Kconfig	2005-03-01 23:39:09 -08:00
@@ -84,6 +84,7 @@
 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
 	  programs.  It can be viewed as a simple Point-to-Point or Ethernet
@@ -691,6 +692,7 @@
 config VORTEX
 	tristate "3c590/3c900 series (592/595/597) \"Vortex/Boomerang\" support"
 	depends on NET_VENDOR_3COM && (PCI || EISA)
+	select MII
 	---help---
 	  This option enables driver support for a large number of 10mbps and
 	  10/100mbps EISA, PCI and PCMCIA 3Com network cards:
@@ -1179,37 +1181,38 @@
 	  be called ibmveth.
 
 config IBM_EMAC
-       tristate "IBM PPC4xx EMAC driver support"
-       depends on 4xx
-       ---help---
-       This driver supports the IBM PPC4xx EMAC family of on-chip
-       Ethernet controllers.
+	tristate "IBM PPC4xx EMAC driver support"
+	depends on 4xx
+	select CRC32
+	---help---
+	  This driver supports the IBM PPC4xx EMAC family of on-chip
+	  Ethernet controllers.
 
 config IBM_EMAC_ERRMSG
-       bool "Verbose error messages"
-       depends on IBM_EMAC
+	bool "Verbose error messages"
+	depends on IBM_EMAC
 
 config IBM_EMAC_RXB
-       int "Number of receive buffers"
-       depends on IBM_EMAC
-       default "128" if IBM_EMAC4
-       default "64"
+	int "Number of receive buffers"
+	depends on IBM_EMAC
+	default "128" if IBM_EMAC4
+	default "64"
 
 config IBM_EMAC_TXB
-       int "Number of transmit buffers"
-       depends on IBM_EMAC
-       default "128" if IBM_EMAC4
-       default "8"
+	int "Number of transmit buffers"
+	depends on IBM_EMAC
+	default "128" if IBM_EMAC4
+	default "8"
 
 config IBM_EMAC_FGAP
-       int "Frame gap"
-       depends on IBM_EMAC
-       default "8"
+	int "Frame gap"
+	depends on IBM_EMAC
+	default "8"
 
 config IBM_EMAC_SKBRES
-       int "Skb reserve amount"
-       depends on IBM_EMAC
-       default "0"
+	int "Skb reserve amount"
+	depends on IBM_EMAC
+	default "0"
 
 config NET_PCI
 	bool "EISA, VLB, PCI and on board controllers"
@@ -1398,16 +1401,6 @@
 	  will be called eepro100.
 
 
-config EEPRO100_PIO
-	bool "Use PIO instead of MMIO" if !X86_VISWS
-	depends on EEPRO100
-	default y if X86_VISWS
-	help
-	  This instructs the driver to use programmed I/O ports (PIO) instead
-	  of PCI shared memory (MMIO).  This can possibly solve some problems
-	  in case your mainboard has memory consistency issues.  If unsure,
-	  say N.
-
 config E100
 	tristate "Intel(R) PRO/100+ support"
 	depends on NET_PCI && PCI
@@ -1420,13 +1413,13 @@
 
 	  Use the above information and the Adapter & Driver ID Guide at:
 
-	  http://support.intel.com/support/network/adapter/pro100/21397.htm
+	  <http://support.intel.com/support/network/adapter/pro100/21397.htm>
 
           to identify the adapter.
 
 	  For the latest Intel PRO/100 network driver for Linux, see:
 
-	  http://appsr.intel.com/scripts-df/support_intel.asp
+	  <http://appsr.intel.com/scripts-df/support_intel.asp>
 
 	  More specific information on configuring the driver is in 
 	  <file:Documentation/networking/e100.txt>.
@@ -1667,7 +1660,7 @@
 	  <file:Documentation/networking/net-modules.txt>. The module
 	  will be called tlan.
 
-	  Please email feedback to  torben.mathiasen@compaq.com.
+	  Please email feedback to <torben.mathiasen@compaq.com>.
 
 config VIA_RHINE
 	tristate "VIA Rhine support"
@@ -1979,6 +1972,15 @@
 
 	  If in doubt, say N.
 
+config R8169_VLAN
+	bool "VLAN support"
+	depends on R8169 && VLAN_8021Q
+	---help---
+	  Say Y here for the r8169 driver to support the functions required
+	  by the kernel 802.1Q code.
+	  
+	  If in doubt, say Y.
+
 config SK98LIN
 	tristate "Marvell Yukon Chipset / SysKonnect SK-98xx Support"
 	depends on PCI
@@ -2048,14 +2050,14 @@
 	  The dual link adapters support link-failover and dual port features.
 	  Both Marvell Yukon and SysKonnect SK-98xx/SK-95xx adapters support 
 	  the scatter-gather functionality with sendfile(). Please refer to 
-	  Documentation/networking/sk98lin.txt for more information about
+	  <file:Documentation/networking/sk98lin.txt> for more information about
 	  optional driver parameters.
 	  Questions concerning this driver may be addressed to:
-	      linux@syskonnect.de
+	      <linux@syskonnect.de>
 	  
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
-	  say M here and read Documentation/kbuild/modules.txt. The module will
+	  say M here and read <file:Documentation/kbuild/modules.txt>. The module will
 	  be called sk98lin. This is recommended.
 
 config VIA_VELOCITY
@@ -2191,6 +2193,17 @@
 
 	  If in doubt, say N.
 
+config 2BUFF_MODE
+	bool "Use 2 Buffer Mode on Rx side."
+	depends on S2IO
+	---help---
+	On enabling the 2 buffer mode, the received frame will be
+	split into 2 parts before being DMA'ed to the hosts memory.
+	The parts are the ethernet header and ethernet payload. 
+	This is useful on systems where DMA'ing to to unaligned 
+	physical memory loactions comes with a heavy price.
+	If not sure please say N.
+
 endmenu
 
 source "drivers/net/tokenring/Kconfig"
@@ -2253,7 +2266,7 @@
 	  the driver.
 
 	  Questions concerning this driver can be addressed to:
-	  linux@syskonnect.de
+	  <linux@syskonnect.de>
 
 	  To compile this driver as a module, choose M here: the module
 	  will be called skfp.  This is recommended.
@@ -2449,7 +2462,7 @@
 
 	  This driver requires the latest version of pppd from the CVS
 	  repository at cvs.samba.org.  Alternatively, see the 
-	  RoaringPenguin package (http://www.roaringpenguin.com/pppoe)
+	  RoaringPenguin package (<http://www.roaringpenguin.com/pppoe>)
 	  which contains instruction on how to use this driver (under 
 	  the heading "Kernel mode PPPoE").
 
@@ -2577,5 +2590,5 @@
 	depends on NETDEVICES && EXPERIMENTAL
 	---help---
 	If you want to log kernel messages over the network, enable this.
-	See Documentation/networking/netconsole.txt for details.
+	See <file:Documentation/networking/netconsole.txt> for details.
 
diff -Nru a/drivers/net/Makefile b/drivers/net/Makefile
--- a/drivers/net/Makefile	2005-03-01 23:38:54 -08:00
+++ b/drivers/net/Makefile	2005-03-01 23:38:54 -08:00
@@ -66,7 +66,7 @@
 
 obj-$(CONFIG_SUNDANCE) += sundance.o
 obj-$(CONFIG_HAMACHI) += hamachi.o
-obj-$(CONFIG_NET) += Space.o net_init.o loopback.o
+obj-$(CONFIG_NET) += Space.o loopback.o
 obj-$(CONFIG_SEEQ8005) += seeq8005.o
 obj-$(CONFIG_ETHERTAP) += ethertap.o
 obj-$(CONFIG_NET_SB1000) += sb1000.o
diff -Nru a/drivers/net/ac3200.c b/drivers/net/ac3200.c
--- a/drivers/net/ac3200.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/net/ac3200.c	2005-03-01 23:39:07 -08:00
@@ -128,8 +128,7 @@
 	/* Someday free_irq may be in ac_close_card() */
 	free_irq(dev->irq, dev);
 	release_region(dev->base_addr, AC_IO_EXTENT);
-	if (ei_status.reg0)
-		iounmap((void *)dev->mem_start);
+	iounmap(ei_status.mem);
 }
 
 #ifndef MODULE
@@ -237,32 +236,22 @@
 	/*
 	 *  BEWARE!! Some dain-bramaged EISA SCUs will allow you to put
 	 *  the card mem within the region covered by `normal' RAM  !!!
+	 *
+	 *  ioremap() will fail in that case.
 	 */
-	if (dev->mem_start > 1024*1024) {	/* phys addr > 1MB */
-		if (dev->mem_start < virt_to_phys(high_memory)) {
-			printk(KERN_CRIT "ac3200.c: Card RAM overlaps with normal memory!!!\n");
-			printk(KERN_CRIT "ac3200.c: Use EISA SCU to set card memory below 1MB,\n");
-			printk(KERN_CRIT "ac3200.c: or to an address above 0x%lx.\n", virt_to_phys(high_memory));
-			printk(KERN_CRIT "ac3200.c: Driver NOT installed.\n");
-			retval = -EINVAL;
-			goto out1;
-		}
-		dev->mem_start = (unsigned long)ioremap(dev->mem_start, AC_STOP_PG*0x100);
-		if (dev->mem_start == 0) {
-			printk(KERN_ERR "ac3200.c: Unable to remap card memory above 1MB !!\n");
-			printk(KERN_ERR "ac3200.c: Try using EISA SCU to set memory below 1MB.\n");
-			printk(KERN_ERR "ac3200.c: Driver NOT installed.\n");
-			retval = -EINVAL;
-			goto out1;
-		}
-		ei_status.reg0 = 1;	/* Use as remap flag */
-		printk("ac3200.c: remapped %dkB card memory to virtual address %#lx\n",
-				AC_STOP_PG/4, dev->mem_start);
-	}
-
-	ei_status.rmem_start = dev->mem_start + TX_PAGES*256;
-	dev->mem_end = ei_status.rmem_end = dev->mem_start
-		+ (AC_STOP_PG - AC_START_PG)*256;
+	ei_status.mem = ioremap(dev->mem_start, AC_STOP_PG*0x100);
+	if (!ei_status.mem) {
+		printk(KERN_ERR "ac3200.c: Unable to remap card memory above 1MB !!\n");
+		printk(KERN_ERR "ac3200.c: Try using EISA SCU to set memory below 1MB.\n");
+		printk(KERN_ERR "ac3200.c: Driver NOT installed.\n");
+		retval = -EINVAL;
+		goto out1;
+	}
+	printk("ac3200.c: remapped %dkB card memory to virtual address %p\n",
+			AC_STOP_PG/4, ei_status.mem);
+
+	dev->mem_start = (unsigned long)ei_status.mem;
+	dev->mem_end = dev->mem_start + (AC_STOP_PG - AC_START_PG)*256;
 
 	ei_status.name = "AC3200";
 	ei_status.tx_start_page = AC_START_PG;
@@ -324,8 +313,8 @@
 static void
 ac_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
 {
-	unsigned long hdr_start = dev->mem_start + ((ring_page - AC_START_PG)<<8);
-	isa_memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
+	void __iomem *hdr_start = ei_status.mem + ((ring_page - AC_START_PG)<<8);
+	memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
 }
 
 /*  Block input and output are easy on shared memory ethercards, the only
@@ -334,26 +323,27 @@
 static void ac_block_input(struct net_device *dev, int count, struct sk_buff *skb,
 						  int ring_offset)
 {
-	unsigned long xfer_start = dev->mem_start + ring_offset - (AC_START_PG<<8);
+	void __iomem *start = ei_status.mem + ring_offset - AC_START_PG*256;
 
-	if (xfer_start + count > ei_status.rmem_end) {
+	if (ring_offset + count > AC_STOP_PG*256) {
 		/* We must wrap the input move. */
-		int semi_count = ei_status.rmem_end - xfer_start;
-		isa_memcpy_fromio(skb->data, xfer_start, semi_count);
+		int semi_count = AC_STOP_PG*256 - ring_offset;
+		memcpy_fromio(skb->data, start, semi_count);
 		count -= semi_count;
-		isa_memcpy_fromio(skb->data + semi_count, ei_status.rmem_start, count);
+		memcpy_fromio(skb->data + semi_count,
+				ei_status.mem + TX_PAGES*256, count);
 	} else {
 		/* Packet is in one chunk -- we can copy + cksum. */
-		isa_eth_io_copy_and_sum(skb, xfer_start, count, 0);
+		eth_io_copy_and_sum(skb, start, count, 0);
 	}
 }
 
 static void ac_block_output(struct net_device *dev, int count,
 							const unsigned char *buf, int start_page)
 {
-	unsigned long shmem = dev->mem_start + ((start_page - AC_START_PG)<<8);
+	void __iomem *shmem = ei_status.mem + ((start_page - AC_START_PG)<<8);
 
-	isa_memcpy_toio(shmem, buf, count);
+	memcpy_toio(shmem, buf, count);
 }
 
 static int ac_close_card(struct net_device *dev)
@@ -377,9 +367,9 @@
 static int io[MAX_AC32_CARDS];
 static int irq[MAX_AC32_CARDS];
 static int mem[MAX_AC32_CARDS];
-MODULE_PARM(io, "1-" __MODULE_STRING(MAX_AC32_CARDS) "i");
-MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_AC32_CARDS) "i");
-MODULE_PARM(mem, "1-" __MODULE_STRING(MAX_AC32_CARDS) "i");
+module_param_array(io, int, NULL, 0);
+module_param_array(irq, int, NULL, 0);
+module_param_array(mem, int, NULL, 0);
 MODULE_PARM_DESC(io, "I/O base address(es)");
 MODULE_PARM_DESC(irq, "IRQ number(s)");
 MODULE_PARM_DESC(mem, "Memory base address(es)");
diff -Nru a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c
--- a/drivers/net/amd8111e.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/net/amd8111e.c	2005-03-01 23:39:18 -08:00
@@ -105,11 +105,11 @@
 MODULE_AUTHOR("Advanced Micro Devices, Inc.");
 MODULE_DESCRIPTION ("AMD8111 based 10/100 Ethernet Controller. Driver Version 3.0.3");
 MODULE_LICENSE("GPL");
-MODULE_PARM(speed_duplex, "1-" __MODULE_STRING (MAX_UNITS) "i");
+module_param_array(speed_duplex, int, NULL, 0);
 MODULE_PARM_DESC(speed_duplex, "Set device speed and duplex modes, 0: Auto Negotitate, 1: 10Mbps Half Duplex, 2: 10Mbps Full Duplex, 3: 100Mbps Half Duplex, 4: 100Mbps Full Duplex");
-MODULE_PARM(coalesce, "1-" __MODULE_STRING(MAX_UNITS) "i");
+module_param_array(coalesce, bool, NULL, 0);
 MODULE_PARM_DESC(coalesce, "Enable or Disable interrupt coalescing, 1: Enable, 0: Disable");
-MODULE_PARM(dynamic_ipg, "1-" __MODULE_STRING(MAX_UNITS) "i");
+module_param_array(dynamic_ipg, bool, NULL, 0);
 MODULE_PARM_DESC(dynamic_ipg, "Enable or Disable dynamic IPG, 1: Enable, 0: Disable");
 
 static struct pci_device_id amd8111e_pci_tbl[] = {
@@ -1826,17 +1826,17 @@
 		if(lp->options & OPTION_WAKE_PHY_ENABLE)
 			amd8111e_enable_link_change(lp);	
 		
-		pci_enable_wake(pci_dev, 3, 1);
-		pci_enable_wake(pci_dev, 4, 1); /* D3 cold */
+		pci_enable_wake(pci_dev, PCI_D3hot, 1);
+		pci_enable_wake(pci_dev, PCI_D3cold, 1);
 
 	}
 	else{		
-		pci_enable_wake(pci_dev, 3, 0);
-		pci_enable_wake(pci_dev, 4, 0); /* 4 == D3 cold */
+		pci_enable_wake(pci_dev, PCI_D3hot, 0);
+		pci_enable_wake(pci_dev, PCI_D3cold, 0);
 	}
 	
 	pci_save_state(pci_dev);
-	pci_set_power_state(pci_dev, 3);
+	pci_set_power_state(pci_dev, PCI_D3hot);
 
 	return 0;
 }
@@ -1848,11 +1848,11 @@
 	if (!netif_running(dev))
 		return 0;
 
-	pci_set_power_state(pci_dev, 0);
+	pci_set_power_state(pci_dev, PCI_D0);
 	pci_restore_state(pci_dev);
 
-	pci_enable_wake(pci_dev, 3, 0);
-	pci_enable_wake(pci_dev, 4, 0); /* D3 cold */
+	pci_enable_wake(pci_dev, PCI_D3hot, 0);
+	pci_enable_wake(pci_dev, PCI_D3cold, 0); /* D3 cold */
 
 	netif_device_attach(dev);
 
diff -Nru a/drivers/net/appletalk/cops.c b/drivers/net/appletalk/cops.c
--- a/drivers/net/appletalk/cops.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/net/appletalk/cops.c	2005-03-01 23:38:57 -08:00
@@ -1027,9 +1027,9 @@
 static struct net_device *cops_dev;
 
 MODULE_LICENSE("GPL");
-MODULE_PARM(io, "i");
-MODULE_PARM(irq, "i");
-MODULE_PARM(board_type, "i");
+module_param(io, int, 0);
+module_param(irq, int, 0);
+module_param(board_type, int, 0);
 
 int init_module(void)
 {
diff -Nru a/drivers/net/appletalk/ipddp.c b/drivers/net/appletalk/ipddp.c
--- a/drivers/net/appletalk/ipddp.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/net/appletalk/ipddp.c	2005-03-01 23:38:52 -08:00
@@ -289,7 +289,7 @@
 static struct net_device *dev_ipddp;
 
 MODULE_LICENSE("GPL");
-MODULE_PARM(ipddp_mode, "i");
+module_param(ipddp_mode, int, 0);
 
 static int __init ipddp_init_module(void)
 {
diff -Nru a/drivers/net/appletalk/ltpc.c b/drivers/net/appletalk/ltpc.c
--- a/drivers/net/appletalk/ltpc.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/net/appletalk/ltpc.c	2005-03-01 23:38:54 -08:00
@@ -236,8 +236,8 @@
 /* our stuff */
 #include "ltpc.h"
 
-static spinlock_t txqueue_lock = SPIN_LOCK_UNLOCKED;
-static spinlock_t mbox_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(txqueue_lock);
+static DEFINE_SPINLOCK(mbox_lock);
 
 /* function prototypes */
 static int do_read(struct net_device *dev, void *cbuf, int cbuflen,
@@ -1257,10 +1257,10 @@
 #ifdef MODULE
 
 MODULE_LICENSE("GPL");
-MODULE_PARM(debug, "i");
-MODULE_PARM(io, "i");
-MODULE_PARM(irq, "i");
-MODULE_PARM(dma, "i");
+module_param(debug, int, 0);
+module_param(io, int, 0);
+module_param(irq, int, 0);
+module_param(dma, int, 0);
 
 
 int __init init_module(void)
diff -Nru a/drivers/net/arcnet/Kconfig b/drivers/net/arcnet/Kconfig
--- a/drivers/net/arcnet/Kconfig	2005-03-01 23:39:16 -08:00
+++ b/drivers/net/arcnet/Kconfig	2005-03-01 23:39:16 -08:00
@@ -59,6 +59,25 @@
 	  to work unless talking to a copy of the same Linux arcnet driver,
 	  but perhaps marginally faster in that case.
 
+config ARCNET_CAP
+	tristate "Enable CAP mode packet interface"
+	depends on ARCNET
+	help
+	  ARCnet "cap mode" packet encapsulation. Used to get the hardware
+          acknowledge back to userspace. After the initial protocol byte every
+          packet is stuffed with an extra 4 byte "cookie" which doesn't
+          actually appear on the network. After transmit the driver will send
+          back a packet with protocol byte 0 containing the status of the
+          transmition:
+             0=no hardware acknowledge
+             1=excessive nak
+             2=transmition accepted by the reciever hardware
+
+          Received packets are also stuffed with the extra 4 bytes but it will
+          be random data.
+
+          Cap only listens to protocol 1-8.
+
 config ARCNET_COM90xx
 	tristate "ARCnet COM90xx (normal) chipset driver"
 	depends on ARCNET
@@ -91,7 +110,7 @@
 	  This is yet another chipset driver for the COM90xx cards, but this
 	  time only using memory-mapped mode, and no IO ports at all. This
 	  driver is completely untested, so if you have one of these cards,
-	  please mail dwmw2@infradead.org, especially if it works!
+	  please mail <dwmw2@infradead.org>, especially if it works!
 
 	  To compile this driver as a module, choose M here and read
 	  <file:Documentation/networking/net-modules.txt>.  The module will
diff -Nru a/drivers/net/arcnet/Makefile b/drivers/net/arcnet/Makefile
--- a/drivers/net/arcnet/Makefile	2005-03-01 23:39:07 -08:00
+++ b/drivers/net/arcnet/Makefile	2005-03-01 23:39:07 -08:00
@@ -5,6 +5,7 @@
 obj-$(CONFIG_ARCNET_1201) += rfc1201.o
 obj-$(CONFIG_ARCNET_1051) += rfc1051.o
 obj-$(CONFIG_ARCNET_RAW) += arc-rawmode.o
+obj-$(CONFIG_ARCNET_CAP) += capmode.o
 obj-$(CONFIG_ARCNET_COM90xx) += com90xx.o
 obj-$(CONFIG_ARCNET_COM90xxIO) += com90io.o
 obj-$(CONFIG_ARCNET_RIM_I) += arc-rimi.o
diff -Nru a/drivers/net/arcnet/arc-rawmode.c b/drivers/net/arcnet/arc-rawmode.c
--- a/drivers/net/arcnet/arc-rawmode.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/net/arcnet/arc-rawmode.c	2005-03-01 23:39:17 -08:00
@@ -42,7 +42,6 @@
 static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length,
 		      int bufnum);
 
-
 struct ArcProto rawmode_proto =
 {
 	.suffix		= 'r',
@@ -50,6 +49,8 @@
 	.rx		= rx,
 	.build_header	= build_header,
 	.prepare_tx	= prepare_tx,
+	.continue_tx    = NULL,
+	.ack_tx         = NULL
 };
 
 
@@ -121,7 +122,8 @@
 
 	BUGLVL(D_SKB) arcnet_dump_skb(dev, skb, "rx");
 
-	skb->protocol = 0;
+	skb->protocol = __constant_htons(ETH_P_ARCNET);
+;
 	netif_rx(skb);
 	dev->last_rx = jiffies;
 }
@@ -189,6 +191,9 @@
 		hard->offset[1] = ofs = 512 - length - 3;
 	} else
 		hard->offset[0] = ofs = 256 - length;
+
+	BUGMSG(D_DURING, "prepare_tx: length=%d ofs=%d\n",
+	       length,ofs);
 
 	lp->hw.copy_to_card(dev, bufnum, 0, hard, ARC_HDR_SIZE);
 	lp->hw.copy_to_card(dev, bufnum, ofs, &pkt->soft, length);
diff -Nru a/drivers/net/arcnet/arcnet.c b/drivers/net/arcnet/arcnet.c
--- a/drivers/net/arcnet/arcnet.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/net/arcnet/arcnet.c	2005-03-01 23:39:07 -08:00
@@ -53,7 +53,6 @@
 #include <linux/init.h>
 #include <linux/arcdevice.h>
 
-
 /* "do nothing" functions for protocol drivers */
 static void null_rx(struct net_device *dev, int bufnum,
 		    struct archdr *pkthdr, int length);
@@ -69,29 +68,31 @@
  * arc_proto_default instead.  It also must not be NULL; if you would like
  * to set it to NULL, set it to &arc_proto_null instead.
  */
-struct ArcProto *arc_proto_map[256], *arc_proto_default, *arc_bcast_proto;
+ struct ArcProto *arc_proto_map[256], *arc_proto_default,
+   *arc_bcast_proto, *arc_raw_proto;
 
 struct ArcProto arc_proto_null =
 {
 	.suffix		= '?',
 	.mtu		= XMTU,
+	.is_ip          = 0,
 	.rx		= null_rx,
 	.build_header	= null_build_header,
 	.prepare_tx	= null_prepare_tx,
+	.continue_tx    = NULL,
+	.ack_tx         = NULL
 };
 
-static spinlock_t arcnet_lock = SPIN_LOCK_UNLOCKED;
-
 /* Exported function prototypes */
 int arcnet_debug = ARCNET_DEBUG;
 
 EXPORT_SYMBOL(arc_proto_map);
 EXPORT_SYMBOL(arc_proto_default);
 EXPORT_SYMBOL(arc_bcast_proto);
+EXPORT_SYMBOL(arc_raw_proto);
 EXPORT_SYMBOL(arc_proto_null);
 EXPORT_SYMBOL(arcnet_unregister_proto);
 EXPORT_SYMBOL(arcnet_debug);
-EXPORT_SYMBOL(arcdev_setup);
 EXPORT_SYMBOL(alloc_arcdev);
 EXPORT_SYMBOL(arcnet_interrupt);
 
@@ -108,7 +109,7 @@
 static int go_tx(struct net_device *dev);
 
 static int debug = ARCNET_DEBUG;
-MODULE_PARM(debug, "i");
+module_param(debug, int, 0);
 MODULE_LICENSE("GPL");
 
 static int __init arcnet_init(void)
@@ -131,7 +132,7 @@
 #endif
 
 	/* initialize the protocol map */
-	arc_proto_default = arc_bcast_proto = &arc_proto_null;
+	arc_raw_proto = arc_proto_default = arc_bcast_proto = &arc_proto_null;
 	for (count = 0; count < 256; count++)
 		arc_proto_map[count] = arc_proto_default;
 
@@ -155,7 +156,8 @@
  * Dump the contents of an sk_buff
  */
 #if ARCNET_DEBUG_MAX & D_SKB
-void arcnet_dump_skb(struct net_device *dev, struct sk_buff *skb, char *desc)
+void arcnet_dump_skb(struct net_device *dev,
+		     struct sk_buff *skb, char *desc)
 {
 	int i;
 
@@ -176,18 +178,22 @@
  * Dump the contents of an ARCnet buffer
  */
 #if (ARCNET_DEBUG_MAX & (D_RX | D_TX))
-void arcnet_dump_packet(struct net_device *dev, int bufnum, char *desc)
+void arcnet_dump_packet(struct net_device *dev, int bufnum, char *desc,
+			int take_arcnet_lock)
 {
 	struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
 	int i, length;
-	unsigned long flags;
+	unsigned long flags = 0;
 	static uint8_t buf[512];
 
 	/* hw.copy_from_card expects IRQ context so take the IRQ lock
 	   to keep it single threaded */
-	spin_lock_irqsave(&arcnet_lock, flags);
+	if(take_arcnet_lock)
+		spin_lock_irqsave(&lp->lock, flags);
+
 	lp->hw.copy_from_card(dev, bufnum, 0, buf, 512);
-	spin_unlock_irqrestore(&arcnet_lock, flags);
+	if(take_arcnet_lock)
+		spin_unlock_irqrestore(&lp->lock, flags);
 
 	/* if the offset[0] byte is nonzero, this is a 256-byte packet */
 	length = (buf[2] ? 256 : 512);
@@ -219,6 +225,8 @@
 		arc_proto_default = &arc_proto_null;
 	if (arc_bcast_proto == proto)
 		arc_bcast_proto = arc_proto_default;
+	if (arc_raw_proto == proto)
+		arc_raw_proto = arc_proto_default;
 
 	for (count = 0; count < 256; count++) {
 		if (arc_proto_map[count] == proto)
@@ -261,8 +269,11 @@
 	struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
 	int buf = -1, i;
 
-	if (!atomic_dec_and_test(&lp->buf_lock))	/* already in this function */
-		BUGMSG(D_NORMAL, "get_arcbuf: overlap (%d)!\n", lp->buf_lock.counter);
+	if (!atomic_dec_and_test(&lp->buf_lock)) {
+		/* already in this function */
+		BUGMSG(D_NORMAL, "get_arcbuf: overlap (%d)!\n",
+		       lp->buf_lock.counter);
+	}
 	else {			/* we can continue */
 		if (lp->next_buf >= 5)
 			lp->next_buf -= 5;
@@ -305,14 +316,14 @@
 
 
 /* Setup a struct device for ARCnet. */
-void arcdev_setup(struct net_device *dev)
+static void arcdev_setup(struct net_device *dev)
 {
 	dev->type = ARPHRD_ARCNET;
 	dev->hard_header_len = sizeof(struct archdr);
 	dev->mtu = choose_mtu();
 
 	dev->addr_len = ARCNET_ALEN;
-	dev->tx_queue_len = 30;
+	dev->tx_queue_len = 100;
 	dev->broadcast[0] = 0x00;	/* for us, broadcasts are address 0 */
 	dev->watchdog_timeo = TX_TIMEOUT;
 
@@ -334,8 +345,16 @@
 
 struct net_device *alloc_arcdev(char *name)
 {
-	return alloc_netdev(sizeof(struct arcnet_local),
-			    name && *name ? name : "arc%d", arcdev_setup);
+	struct net_device *dev;
+
+	dev = alloc_netdev(sizeof(struct arcnet_local),
+			   name && *name ? name : "arc%d", arcdev_setup);
+	if(dev) {
+		struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+		spin_lock_init(&lp->lock);
+	}
+
+	return dev;
 }
 
 /*
@@ -351,6 +370,8 @@
 	struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
 	int count, newmtu, error;
 
+	BUGMSG(D_INIT,"opened.");
+
 	if (!try_module_get(lp->hw.owner))
 		return -ENODEV;
 
@@ -377,6 +398,8 @@
 	if (newmtu < dev->mtu)
 		dev->mtu = newmtu;
 
+	BUGMSG(D_INIT, "arcnet_open: mtu: %d.\n", dev->mtu);
+
 	/* autodetect the encapsulation for each host. */
 	memset(lp->default_proto, 0, sizeof(lp->default_proto));
 
@@ -390,6 +413,7 @@
 
 	/* initialize buffers */
 	atomic_set(&lp->buf_lock, 1);
+
 	lp->next_buf = lp->first_free_buf = 0;
 	release_arcbuf(dev, 0);
 	release_arcbuf(dev, 1);
@@ -411,17 +435,24 @@
 		BUGMSG(D_NORMAL, "WARNING!  Station address FF may confuse "
 		       "DOS networking programs!\n");
 
-	if (ASTATUS() & RESETflag)
+	BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
+	if (ASTATUS() & RESETflag) {
+	  	BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
 		ACOMMAND(CFLAGScmd | RESETclear);
+	}
+
 
+	BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
 	/* make sure we're ready to receive IRQ's. */
 	AINTMASK(0);
 	udelay(1);		/* give it time to set the mask before
 				 * we reset it again. (may not even be
 				 * necessary)
 				 */
+	BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
 	lp->intmask = NORXflag | RECONflag;
 	AINTMASK(lp->intmask);
+	BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
 
 	netif_start_queue(dev);
 
@@ -467,32 +498,41 @@
 	       daddr ? *(uint8_t *) daddr : -1,
 	       type, type, len);
 
-	if (len != skb->len)
+	if (skb->len!=0 && len != skb->len)
 		BUGMSG(D_NORMAL, "arcnet_header: Yikes!  skb->len(%d) != len(%d)!\n",
 		       skb->len, len);
 
-	/*
-	 * if the dest addr isn't provided, we can't choose an encapsulation!
-	 * Store the packet type (eg. ETH_P_IP) for now, and we'll push on a
-	 * real header when we do rebuild_header. 
-	 */
-	if (!daddr) {
+
+  	/* Type is host order - ? */
+  	if(type == ETH_P_ARCNET) {
+  		proto = arc_raw_proto;
+  		BUGMSG(D_DEBUG, "arc_raw_proto used. proto='%c'\n",proto->suffix);
+  		_daddr = daddr ? *(uint8_t *) daddr : 0;
+  	}
+	else if (!daddr) {
+		/*
+		 * if the dest addr isn't provided, we can't choose an encapsulation!
+		 * Store the packet type (eg. ETH_P_IP) for now, and we'll push on a
+		 * real header when we do rebuild_header.
+		 */
 		*(uint16_t *) skb_push(skb, 2) = type;
 		if (skb->nh.raw - skb->mac.raw != 2)
 			BUGMSG(D_NORMAL, "arcnet_header: Yikes!  diff (%d) is not 2!\n",
 			       (int)(skb->nh.raw - skb->mac.raw));
 		return -2;	/* return error -- can't transmit yet! */
 	}
-	/* otherwise, we can just add the header as usual. */
-	_daddr = *(uint8_t *) daddr;
-	proto_num = lp->default_proto[_daddr];
-	proto = arc_proto_map[proto_num];
-	BUGMSG(D_DURING, "building header for %02Xh using protocol '%c'\n",
-	       proto_num, proto->suffix);
-	if (proto == &arc_proto_null && arc_bcast_proto != proto) {
-		BUGMSG(D_DURING, "actually, let's use '%c' instead.\n",
-		       arc_bcast_proto->suffix);
-		proto = arc_bcast_proto;
+	else {
+		/* otherwise, we can just add the header as usual. */
+		_daddr = *(uint8_t *) daddr;
+		proto_num = lp->default_proto[_daddr];
+		proto = arc_proto_map[proto_num];
+		BUGMSG(D_DURING, "building header for %02Xh using protocol '%c'\n",
+		       proto_num, proto->suffix);
+		if (proto == &arc_proto_null && arc_bcast_proto != proto) {
+			BUGMSG(D_DURING, "actually, let's use '%c' instead.\n",
+			       arc_bcast_proto->suffix);
+			proto = arc_bcast_proto;
+		}
 	}
 	return proto->build_header(skb, dev, type, _daddr);
 }
@@ -519,6 +559,7 @@
 		return 0;
 	}
 	type = *(uint16_t *) skb_pull(skb, 2);
+	BUGMSG(D_DURING, "rebuild header for protocol %Xh\n", type);
 
 	if (type == ETH_P_IP) {
 #ifdef CONFIG_INET
@@ -555,10 +596,12 @@
 	struct arc_rfc1201 *soft;
 	struct ArcProto *proto;
 	int txbuf;
+	unsigned long flags;
+	int freeskb = 0;
 
 	BUGMSG(D_DURING,
-	       "transmit requested (status=%Xh, txbufs=%d/%d, len=%d)\n",
-	       ASTATUS(), lp->cur_tx, lp->next_tx, skb->len);
+	       "transmit requested (status=%Xh, txbufs=%d/%d, len=%d, protocol %x)\n",
+	       ASTATUS(), lp->cur_tx, lp->next_tx, skb->len,skb->protocol);
 
 	pkt = (struct archdr *) skb->data;
 	soft = &pkt->soft.rfc1201;
@@ -578,38 +621,49 @@
 	/* We're busy transmitting a packet... */
 	netif_stop_queue(dev);
 
+	spin_lock_irqsave(&lp->lock, flags);
 	AINTMASK(0);
 
 	txbuf = get_arcbuf(dev);
 	if (txbuf != -1) {
-		if (proto->prepare_tx(dev, pkt, skb->len, txbuf)) {
-			/* done right away */
+		if (proto->prepare_tx(dev, pkt, skb->len, txbuf) &&
+		    !proto->ack_tx) {
+			/* done right away and we don't want to acknowledge
+			   the package later - forget about it now */
 			lp->stats.tx_bytes += skb->len;
-			dev_kfree_skb(skb);
+			freeskb = 1;
 		} else {
 			/* do it the 'split' way */
 			lp->outgoing.proto = proto;
 			lp->outgoing.skb = skb;
 			lp->outgoing.pkt = pkt;
 
-			if (!proto->continue_tx)
-				BUGMSG(D_NORMAL, "bug! prep_tx==0, but no continue_tx!\n");
-			else if (proto->continue_tx(dev, txbuf)) {
-				BUGMSG(D_NORMAL,
-				       "bug! continue_tx finished the first time! "
-				       "(proto='%c')\n", proto->suffix);
+			if (proto->continue_tx &&
+			    proto->continue_tx(dev, txbuf)) {
+			  BUGMSG(D_NORMAL,
+				 "bug! continue_tx finished the first time! "
+				 "(proto='%c')\n", proto->suffix);
 			}
 		}
 
 		lp->next_tx = txbuf;
-	} else
-		dev_kfree_skb(skb);
+	} else {
+		freeskb = 1;
+	}
 
+	BUGMSG(D_DEBUG, "%s: %d: %s, status: %x\n",__FILE__,__LINE__,__FUNCTION__,ASTATUS());
 	/* make sure we didn't ignore a TX IRQ while we were in here */
 	AINTMASK(0);
-	lp->intmask |= TXFREEflag;
+
+	BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
+	lp->intmask |= TXFREEflag|EXCNAKflag;
 	AINTMASK(lp->intmask);
+	BUGMSG(D_DEBUG, "%s: %d: %s, status: %x\n",__FILE__,__LINE__,__FUNCTION__,ASTATUS());
 
+	spin_unlock_irqrestore(&lp->lock, flags);
+	if (freeskb) {
+		dev_kfree_skb(skb);
+	}
 	return 0;		/* no need to try again */
 }
 
@@ -628,7 +682,7 @@
 	if (lp->cur_tx != -1 || lp->next_tx == -1)
 		return 0;
 
-	BUGLVL(D_TX) arcnet_dump_packet(dev, lp->next_tx, "go_tx");
+	BUGLVL(D_TX) arcnet_dump_packet(dev, lp->next_tx, "go_tx", 0);
 
 	lp->cur_tx = lp->next_tx;
 	lp->next_tx = -1;
@@ -640,7 +694,8 @@
 	lp->stats.tx_packets++;
 	lp->lasttrans_dest = lp->lastload_dest;
 	lp->lastload_dest = 0;
-	lp->intmask |= TXFREEflag;
+	lp->excnak_pending = 0;
+	lp->intmask |= TXFREEflag|EXCNAKflag;
 
 	return 1;
 }
@@ -654,7 +709,7 @@
 	int status = ASTATUS();
 	char *msg;
 
-	spin_lock_irqsave(&arcnet_lock, flags);
+	spin_lock_irqsave(&lp->lock, flags);
 	if (status & TXFREEflag) {	/* transmit _DID_ finish */
 		msg = " - missed IRQ?";
 	} else {
@@ -665,12 +720,12 @@
 	}
 	lp->stats.tx_errors++;
 
-	/* make sure we didn't miss a TX IRQ */
+	/* make sure we didn't miss a TX or a EXC NAK IRQ */
 	AINTMASK(0);
-	lp->intmask |= TXFREEflag;
+	lp->intmask |= TXFREEflag|EXCNAKflag;
 	AINTMASK(lp->intmask);
 	
-	spin_unlock_irqrestore(&arcnet_lock, flags);
+	spin_unlock_irqrestore(&lp->lock, flags);
 
 	if (jiffies - lp->last_timeout > 10*HZ) {
 		BUGMSG(D_EXTRA, "tx timed out%s (status=%Xh, intmask=%Xh, dest=%02Xh)\n",
@@ -692,18 +747,19 @@
 {
 	struct net_device *dev = dev_id;
 	struct arcnet_local *lp;
-	int recbuf, status, didsomething, boguscount;
+	int recbuf, status, diagstatus, didsomething, boguscount;
+	int retval = IRQ_NONE;
 
 	BUGMSG(D_DURING, "\n");
 
 	BUGMSG(D_DURING, "in arcnet_interrupt\n");
-
-	spin_lock(&arcnet_lock);
 	
 	lp = (struct arcnet_local *) dev->priv;
 	if (!lp)
 		BUG();
 		
+	spin_lock(&lp->lock);
+
 	/*
 	 * RESET flag was enabled - if device is not running, we must clear it right
 	 * away (but nothing else).
@@ -712,7 +768,7 @@
 		if (ASTATUS() & RESETflag)
 			ACOMMAND(CFLAGScmd | RESETclear);
 		AINTMASK(0);
-		spin_unlock(&arcnet_lock);
+		spin_unlock(&lp->lock);
 		return IRQ_HANDLED;
 	}
 
@@ -722,6 +778,10 @@
 	boguscount = 5;
 	do {
 		status = ASTATUS();
+                diagstatus = (status >> 8) & 0xFF;
+
+		BUGMSG(D_DEBUG, "%s: %d: %s: status=%x\n",
+			__FILE__,__LINE__,__FUNCTION__,status);
 		didsomething = 0;
 
 		/*
@@ -761,24 +821,55 @@
 			}
 			didsomething++;
 		}
+
+		if((diagstatus & EXCNAKflag)) {
+			BUGMSG(D_DURING, "EXCNAK IRQ (diagstat=%Xh)\n",
+			       diagstatus);
+
+                        ACOMMAND(NOTXcmd);      /* disable transmit */
+                        lp->excnak_pending = 1;
+
+                        ACOMMAND(EXCNAKclear);
+			lp->intmask &= ~(EXCNAKflag);
+                        didsomething++;
+                }
+
+
 		/* a transmit finished, and we're interested in it. */
 		if ((status & lp->intmask & TXFREEflag) || lp->timed_out) {
-			lp->intmask &= ~TXFREEflag;
+			lp->intmask &= ~(TXFREEflag|EXCNAKflag);
 
 			BUGMSG(D_DURING, "TX IRQ (stat=%Xh)\n", status);
 
-			if (lp->cur_tx != -1 && !(status & TXACKflag) && !lp->timed_out) {
-				if (lp->lasttrans_dest != 0) {
-					BUGMSG(D_EXTRA, "transmit was not acknowledged! "
-					    "(status=%Xh, dest=%02Xh)\n",
-					     status, lp->lasttrans_dest);
-					lp->stats.tx_errors++;
-					lp->stats.tx_carrier_errors++;
-				} else {
-					BUGMSG(D_DURING,
-					       "broadcast was not acknowledged; that's normal "
-					    "(status=%Xh, dest=%02Xh)\n",
-					     status, lp->lasttrans_dest);
+			if (lp->cur_tx != -1 && !lp->timed_out) {
+				if(!(status & TXACKflag)) {
+					if (lp->lasttrans_dest != 0) {
+						BUGMSG(D_EXTRA,
+						       "transmit was not acknowledged! "
+						       "(status=%Xh, dest=%02Xh)\n",
+						       status, lp->lasttrans_dest);
+						lp->stats.tx_errors++;
+						lp->stats.tx_carrier_errors++;
+					} else {
+						BUGMSG(D_DURING,
+						       "broadcast was not acknowledged; that's normal "
+						       "(status=%Xh, dest=%02Xh)\n",
+						       status, lp->lasttrans_dest);
+					}
+				}
+
+				if (lp->outgoing.proto &&
+				    lp->outgoing.proto->ack_tx) {
+				  int ackstatus;
+				  if(status & TXACKflag)
+                                    ackstatus=2;
+                                  else if(lp->excnak_pending)
+                                    ackstatus=1;
+                                  else
+                                    ackstatus=0;
+
+                                  lp->outgoing.proto
+                                    ->ack_tx(dev, ackstatus);
 				}
 			}
 			if (lp->cur_tx != -1)
@@ -798,8 +889,11 @@
 					if (lp->outgoing.proto->continue_tx(dev, txbuf)) {
 						/* that was the last segment */
 						lp->stats.tx_bytes += lp->outgoing.skb->len;
-						dev_kfree_skb_irq(lp->outgoing.skb);
-						lp->outgoing.proto = NULL;
+						if(!lp->outgoing.proto->ack_tx)
+						  {
+						    dev_kfree_skb_irq(lp->outgoing.skb);
+						    lp->outgoing.proto = NULL;
+						  }
 					}
 					lp->next_tx = txbuf;
 				}
@@ -810,7 +904,7 @@
 		}
 		/* now process the received packet, if any */
 		if (recbuf != -1) {
-			BUGLVL(D_RX) arcnet_dump_packet(dev, recbuf, "rx irq");
+			BUGLVL(D_RX) arcnet_dump_packet(dev, recbuf, "rx irq", 0);
 
 			arcnet_rx(dev, recbuf);
 			release_arcbuf(dev, recbuf);
@@ -868,6 +962,10 @@
 
 			BUGMSG(D_DURING, "not recon: clearing counters anyway.\n");
 		}
+
+		if(didsomething) {
+			retval |= IRQ_HANDLED;
+		}
 	}
 	while (--boguscount && didsomething);
 
@@ -880,8 +978,8 @@
 	udelay(1);
 	AINTMASK(lp->intmask);
 	
-	spin_unlock(&arcnet_lock);
-	return IRQ_RETVAL(didsomething);
+	spin_unlock(&lp->lock);
+	return retval;
 }
 
 
@@ -908,7 +1006,7 @@
 	}
 
 	/* get the full header, if possible */
-	if (sizeof(pkt.soft) < length)
+	if (sizeof(pkt.soft) <= length)
 		lp->hw.copy_from_card(dev, bufnum, ofs, soft, sizeof(pkt.soft));
 	else {
 		memset(&pkt.soft, 0, sizeof(pkt.soft));
@@ -923,7 +1021,7 @@
 	lp->stats.rx_bytes += length + ARC_HDR_SIZE;
 
 	/* call the right receiver for the protocol */
-	if (arc_proto_map[soft->proto] != &arc_proto_null) {
+	if (arc_proto_map[soft->proto]->is_ip) {
 		BUGLVL(D_PROTO) {
 			struct ArcProto
 			*oldp = arc_proto_map[lp->default_proto[pkt.hard.source]],
diff -Nru a/drivers/net/arcnet/capmode.c b/drivers/net/arcnet/capmode.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/net/arcnet/capmode.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,296 @@
+/*
+ * Linux ARCnet driver - "cap mode" packet encapsulation.
+ * It adds sequence numbers to packets for communicating between a user space
+ * application and the driver. After a transmit it sends a packet with protocol
+ * byte 0 back up to the userspace containing the sequence number of the packet
+ * plus the transmit-status on the ArcNet.
+ *
+ * Written 2002-4 by Esben Nielsen, Vestas Wind Systems A/S
+ * Derived from arc-rawmode.c by Avery Pennarun.
+ * arc-rawmode was in turned based on skeleton.c, see below.
+ *
+ * **********************
+ *
+ * The original copyright of skeleton.c was as follows:
+ *
+ * skeleton.c Written 1993 by Donald Becker.
+ * Copyright 1993 United States Government as represented by the
+ * Director, National Security Agency.  This software may only be used
+ * and distributed according to the terms of the GNU General Public License as
+ * modified by SRC, incorporated herein by reference.
+ *
+ * **********************
+ *
+ * For more details, see drivers/net/arcnet.c
+ *
+ * **********************
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/if_arp.h>
+#include <net/arp.h>
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/arcdevice.h>
+
+#define VERSION "arcnet: cap mode (`c') encapsulation support loaded.\n"
+
+
+static void rx(struct net_device *dev, int bufnum,
+	       struct archdr *pkthdr, int length);
+static int build_header(struct sk_buff *skb,
+			struct net_device *dev,
+			unsigned short type,
+			uint8_t daddr);
+static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length,
+		      int bufnum);
+static int ack_tx(struct net_device *dev, int acked);
+
+
+struct ArcProto capmode_proto =
+{
+	'r',
+	XMTU,
+	0,
+       	rx,
+	build_header,
+	prepare_tx,
+	NULL,
+	ack_tx
+};
+
+
+void arcnet_cap_init(void)
+{
+	int count;
+
+	for (count = 1; count <= 8; count++)
+		if (arc_proto_map[count] == arc_proto_default)
+			arc_proto_map[count] = &capmode_proto;
+
+	/* for cap mode, we only set the bcast proto if there's no better one */
+	if (arc_bcast_proto == arc_proto_default)
+		arc_bcast_proto = &capmode_proto;
+
+	arc_proto_default = &capmode_proto;
+	arc_raw_proto = &capmode_proto;
+}
+
+
+#ifdef MODULE
+
+int __init init_module(void)
+{
+	printk(VERSION);
+	arcnet_cap_init();
+	return 0;
+}
+
+void cleanup_module(void)
+{
+	arcnet_unregister_proto(&capmode_proto);
+}
+
+MODULE_LICENSE("GPL");
+#endif				/* MODULE */
+
+
+
+/* packet receiver */
+static void rx(struct net_device *dev, int bufnum,
+	       struct archdr *pkthdr, int length)
+{
+	struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+	struct sk_buff *skb;
+	struct archdr *pkt = pkthdr;
+	char *pktbuf, *pkthdrbuf;
+	int ofs;
+
+	BUGMSG(D_DURING, "it's a raw(cap) packet (length=%d)\n", length);
+
+	if (length >= MinTU)
+		ofs = 512 - length;
+	else
+		ofs = 256 - length;
+
+	skb = alloc_skb(length + ARC_HDR_SIZE + sizeof(int), GFP_ATOMIC);
+	if (skb == NULL) {
+		BUGMSG(D_NORMAL, "Memory squeeze, dropping packet.\n");
+		lp->stats.rx_dropped++;
+		return;
+	}
+	skb_put(skb, length + ARC_HDR_SIZE + sizeof(int));
+	skb->dev = dev;
+
+	pkt = (struct archdr *) skb->data;
+
+	skb->mac.raw = skb->data;
+	skb_pull(skb, ARC_HDR_SIZE);
+
+	/* up to sizeof(pkt->soft) has already been copied from the card */
+	/* squeeze in an int for the cap encapsulation */
+
+	/* use these variables to be sure we count in bytes, not in
+	   sizeof(struct archdr) */
+	pktbuf=(char*)pkt;
+	pkthdrbuf=(char*)pkthdr;
+	memcpy(pktbuf, pkthdrbuf, ARC_HDR_SIZE+sizeof(pkt->soft.cap.proto));
+	memcpy(pktbuf+ARC_HDR_SIZE+sizeof(pkt->soft.cap.proto)+sizeof(int),
+	       pkthdrbuf+ARC_HDR_SIZE+sizeof(pkt->soft.cap.proto),
+	       sizeof(struct archdr)-ARC_HDR_SIZE-sizeof(pkt->soft.cap.proto));
+
+	if (length > sizeof(pkt->soft))
+		lp->hw.copy_from_card(dev, bufnum, ofs + sizeof(pkt->soft),
+				      pkt->soft.raw + sizeof(pkt->soft)
+				      + sizeof(int),
+				      length - sizeof(pkt->soft));
+
+	BUGLVL(D_SKB) arcnet_dump_skb(dev, skb, "rx");
+
+	skb->protocol = __constant_htons(ETH_P_ARCNET);
+;
+	netif_rx(skb);
+	dev->last_rx = jiffies;
+}
+
+
+/*
+ * Create the ARCnet hard/soft headers for cap mode.
+ * There aren't any soft headers in cap mode - not even the protocol id.
+ */
+static int build_header(struct sk_buff *skb,
+			struct net_device *dev,
+			unsigned short type,
+			uint8_t daddr)
+{
+	int hdr_size = ARC_HDR_SIZE;
+	struct archdr *pkt = (struct archdr *) skb_push(skb, hdr_size);
+
+	BUGMSG(D_PROTO, "Preparing header for cap packet %x.\n",
+	       *((int*)&pkt->soft.cap.cookie[0]));
+	/*
+	 * Set the source hardware address.
+	 *
+	 * This is pretty pointless for most purposes, but it can help in
+	 * debugging.  ARCnet does not allow us to change the source address in
+	 * the actual packet sent)
+	 */
+	pkt->hard.source = *dev->dev_addr;
+
+	/* see linux/net/ethernet/eth.c to see where I got the following */
+
+	if (dev->flags & (IFF_LOOPBACK | IFF_NOARP)) {
+		/*
+		 * FIXME: fill in the last byte of the dest ipaddr here to better
+		 * comply with RFC1051 in "noarp" mode.
+		 */
+		pkt->hard.dest = 0;
+		return hdr_size;
+	}
+	/* otherwise, just fill it in and go! */
+	pkt->hard.dest = daddr;
+
+	return hdr_size;	/* success */
+}
+
+
+static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length,
+		      int bufnum)
+{
+	struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+	struct arc_hardware *hard = &pkt->hard;
+	int ofs;
+
+
+	/* hard header is not included in packet length */
+	length -= ARC_HDR_SIZE;
+	/* And neither is the cookie field */
+	length -= sizeof(int);
+
+	BUGMSG(D_DURING, "prepare_tx: txbufs=%d/%d/%d\n",
+	       lp->next_tx, lp->cur_tx, bufnum);
+
+	BUGMSG(D_PROTO, "Sending for cap packet %x.\n",
+	       *((int*)&pkt->soft.cap.cookie[0]));
+
+	if (length > XMTU) {
+		/* should never happen! other people already check for this. */
+		BUGMSG(D_NORMAL, "Bug!  prepare_tx with size %d (> %d)\n",
+		       length, XMTU);
+		length = XMTU;
+	}
+	if (length > MinTU) {
+		hard->offset[0] = 0;
+		hard->offset[1] = ofs = 512 - length;
+	} else if (length > MTU) {
+		hard->offset[0] = 0;
+		hard->offset[1] = ofs = 512 - length - 3;
+	} else
+		hard->offset[0] = ofs = 256 - length;
+
+	BUGMSG(D_DURING, "prepare_tx: length=%d ofs=%d\n",
+	       length,ofs);
+
+	// Copy the arcnet-header + the protocol byte down:
+	lp->hw.copy_to_card(dev, bufnum, 0, hard, ARC_HDR_SIZE);
+	lp->hw.copy_to_card(dev, bufnum, ofs, &pkt->soft.cap.proto,
+			    sizeof(pkt->soft.cap.proto));
+
+	// Skip the extra integer we have written into it as a cookie
+	// but write the rest of the message:
+	lp->hw.copy_to_card(dev, bufnum, ofs+1,
+			    ((unsigned char*)&pkt->soft.cap.mes),length-1);
+
+	lp->lastload_dest = hard->dest;
+
+	return 1;		/* done */
+}
+
+
+static int ack_tx(struct net_device *dev, int acked)
+{
+  struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+  struct sk_buff *ackskb;
+  struct archdr *ackpkt;
+  int length=sizeof(struct arc_cap);
+
+  BUGMSG(D_DURING, "capmode: ack_tx: protocol: %x: result: %d\n",
+	 lp->outgoing.skb->protocol, acked);
+
+  BUGLVL(D_SKB) arcnet_dump_skb(dev, lp->outgoing.skb, "ack_tx");
+
+  /* Now alloc a skb to send back up through the layers: */
+  ackskb = alloc_skb(length + ARC_HDR_SIZE , GFP_ATOMIC);
+  if (ackskb == NULL) {
+	  BUGMSG(D_NORMAL, "Memory squeeze, can't acknowledge.\n");
+	  goto free_outskb;
+  }
+
+  skb_put(ackskb, length + ARC_HDR_SIZE );
+  ackskb->dev = dev;
+
+  ackpkt = (struct archdr *) ackskb->data;
+
+  ackskb->mac.raw = ackskb->data;
+  /* skb_pull(ackskb, ARC_HDR_SIZE); */
+
+
+  memcpy(ackpkt, lp->outgoing.skb->data, ARC_HDR_SIZE+sizeof(struct arc_cap));
+  ackpkt->soft.cap.proto=0; /* using protocol 0 for acknowledge */
+  ackpkt->soft.cap.mes.ack=acked;
+
+  BUGMSG(D_PROTO, "Ackknowledge for cap packet %x.\n",
+	 *((int*)&ackpkt->soft.cap.cookie[0]));
+
+  ackskb->protocol = __constant_htons(ETH_P_ARCNET);
+
+  BUGLVL(D_SKB) arcnet_dump_skb(dev, ackskb, "ack_tx_recv");
+  netif_rx(ackskb);
+
+ free_outskb:
+  dev_kfree_skb_irq(lp->outgoing.skb);
+  lp->outgoing.proto = NULL; /* We are always finished when in this protocol */
+
+  return 0;
+}
diff -Nru a/drivers/net/arcnet/com20020-isa.c b/drivers/net/arcnet/com20020-isa.c
--- a/drivers/net/arcnet/com20020-isa.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/net/arcnet/com20020-isa.c	2005-03-01 23:38:52 -08:00
@@ -41,7 +41,6 @@
 
 #include <asm/io.h>
 
-
 #define VERSION "arcnet: COM20020 ISA support (by David Woodhouse et al.)\n"
 
 
diff -Nru a/drivers/net/arcnet/com20020.c b/drivers/net/arcnet/com20020.c
--- a/drivers/net/arcnet/com20020.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/net/arcnet/com20020.c	2005-03-01 23:38:54 -08:00
@@ -117,7 +117,7 @@
 	lp->config = 0x21 | (lp->timeout << 3) | (lp->backplane << 2);
 	/* set node ID to 0x42 (but transmitter is disabled, so it's okay) */
 	SETCONF;
-	outb(0x42, ioaddr + 7);
+	outb(0x42, ioaddr + BUS_ALIGN*7);
 
 	status = ASTATUS();
 
@@ -129,7 +129,7 @@
 
 	/* Enable TX */
 	outb(0x39, _CONFIG);
-	outb(inb(ioaddr + 8), ioaddr + 7);
+	outb(inb(ioaddr + BUS_ALIGN*8), ioaddr + BUS_ALIGN*7);
 
 	ACOMMAND(CFLAGScmd | RESETclear | CONFIGclear);
 
@@ -173,7 +173,7 @@
 	dev->set_multicast_list = com20020_set_mc_list;
 
 	if (!dev->dev_addr[0])
-		dev->dev_addr[0] = inb(ioaddr + 8);	/* FIXME: do this some other way! */
+		dev->dev_addr[0] = inb(ioaddr + BUS_ALIGN*8);	/* FIXME: do this some other way! */
 
 	SET_SUBADR(SUB_SETUP1);
 	outb(lp->setup, _XREG);
@@ -188,7 +188,6 @@
 		outb(0x18, _COMMAND);
 	}
 
-
 	lp->config = 0x20 | (lp->timeout << 3) | (lp->backplane << 2) | 1;
 	/* Default 0x38 + register: Node ID */
 	SETCONF;
@@ -235,15 +234,19 @@
 static int com20020_reset(struct net_device *dev, int really_reset)
 {
 	struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
-	short ioaddr = dev->base_addr;
+	u_int ioaddr = dev->base_addr;
 	u_char inbyte;
 
+	BUGMSG(D_DEBUG, "%s: %d: %s: dev: %p, lp: %p, dev->name: %s\n",
+		__FILE__,__LINE__,__FUNCTION__,dev,lp,dev->name);
 	BUGMSG(D_INIT, "Resetting %s (status=%02Xh)\n",
 	       dev->name, ASTATUS());
 
+	BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
 	lp->config = TXENcfg | (lp->timeout << 3) | (lp->backplane << 2);
 	/* power-up defaults */
 	SETCONF;
+	BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
 
 	if (really_reset) {
 		/* reset the card */
@@ -251,17 +254,22 @@
 		mdelay(RESETtime * 2);	/* COM20020 seems to be slower sometimes */
 	}
 	/* clear flags & end reset */
+	BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
 	ACOMMAND(CFLAGScmd | RESETclear | CONFIGclear);
 
 	/* verify that the ARCnet signature byte is present */
+	BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
 
 	com20020_copy_from_card(dev, 0, 0, &inbyte, 1);
+	BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
 	if (inbyte != TESTvalue) {
+		BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
 		BUGMSG(D_NORMAL, "reset failed: TESTvalue not present.\n");
 		return 1;
 	}
 	/* enable extended (512-byte) packets */
 	ACOMMAND(CONFIGcmd | EXTconf);
+	BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
 
 	/* done!  return success. */
 	return 0;
@@ -270,22 +278,24 @@
 
 static void com20020_setmask(struct net_device *dev, int mask)
 {
-	short ioaddr = dev->base_addr;
+	u_int ioaddr = dev->base_addr;
+	BUGMSG(D_DURING, "Setting mask to %x at %x\n",mask,ioaddr);
 	AINTMASK(mask);
 }
 
 
 static void com20020_command(struct net_device *dev, int cmd)
 {
-	short ioaddr = dev->base_addr;
+	u_int ioaddr = dev->base_addr;
 	ACOMMAND(cmd);
 }
 
 
 static int com20020_status(struct net_device *dev)
 {
-	short ioaddr = dev->base_addr;
-	return ASTATUS();
+	u_int ioaddr = dev->base_addr;
+
+	return ASTATUS() + (ADIAGSTATUS()<<8);
 }
 
 static void com20020_close(struct net_device *dev)
diff -Nru a/drivers/net/arcnet/rfc1051.c b/drivers/net/arcnet/rfc1051.c
--- a/drivers/net/arcnet/rfc1051.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/net/arcnet/rfc1051.c	2005-03-01 23:39:07 -08:00
@@ -47,9 +47,12 @@
 {
 	.suffix		= 's',
 	.mtu		= XMTU - RFC1051_HDR_SIZE,
+	.is_ip          = 1,
 	.rx		= rx,
 	.build_header	= build_header,
 	.prepare_tx	= prepare_tx,
+	.continue_tx    = NULL,
+	.ack_tx         = NULL
 };
 
 
diff -Nru a/drivers/net/arcnet/rfc1201.c b/drivers/net/arcnet/rfc1201.c
--- a/drivers/net/arcnet/rfc1201.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/net/arcnet/rfc1201.c	2005-03-01 23:38:57 -08:00
@@ -47,10 +47,12 @@
 {
 	.suffix		= 'a',
 	.mtu		= 1500,	/* could be more, but some receivers can't handle it... */
+	.is_ip          = 1,    /* This is for sending IP and ARP packages */
 	.rx		= rx,
 	.build_header	= build_header,
 	.prepare_tx	= prepare_tx,
 	.continue_tx	= continue_tx,
+	.ack_tx         = NULL
 };
 
 
diff -Nru a/drivers/net/at1700.c b/drivers/net/at1700.c
--- a/drivers/net/at1700.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/net/at1700.c	2005-03-01 23:38:55 -08:00
@@ -899,9 +899,9 @@
 #ifdef MODULE
 static struct net_device *dev_at1700;
 
-MODULE_PARM(io, "i");
-MODULE_PARM(irq, "i");
-MODULE_PARM(net_debug, "i");
+module_param(io, int, 0);
+module_param(irq, int, 0);
+module_param(net_debug, int, 0);
 MODULE_PARM_DESC(io, "AT1700/FMV18X I/O base address");
 MODULE_PARM_DESC(irq, "AT1700/FMV18X IRQ number");
 MODULE_PARM_DESC(net_debug, "AT1700/FMV18X debug level (0-6)");
diff -Nru a/drivers/net/atp.c b/drivers/net/atp.c
--- a/drivers/net/atp.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/net/atp.c	2005-03-01 23:39:17 -08:00
@@ -153,11 +153,11 @@
 MODULE_DESCRIPTION("RealTek RTL8002/8012 parallel port Ethernet driver");
 MODULE_LICENSE("GPL");
 
-MODULE_PARM(max_interrupt_work, "i");
-MODULE_PARM(debug, "i");
-MODULE_PARM(io, "1-" __MODULE_STRING(NUM_UNITS) "i");
-MODULE_PARM(irq, "1-" __MODULE_STRING(NUM_UNITS) "i");
-MODULE_PARM(xcvr, "1-" __MODULE_STRING(NUM_UNITS) "i");
+module_param(max_interrupt_work, int, 0);
+module_param(debug, int, 0);
+module_param_array(io, int, NULL, 0);
+module_param_array(irq, int, NULL, 0);
+module_param_array(xcvr, int, NULL, 0);
 MODULE_PARM_DESC(max_interrupt_work, "ATP maximum events handled per interrupt");
 MODULE_PARM_DESC(debug, "ATP debug level (0-7)");
 MODULE_PARM_DESC(io, "ATP I/O base address(es)");
@@ -909,7 +909,7 @@
 			 i++, mclist = mclist->next)
 		{
 			int filterbit = ether_crc_le(ETH_ALEN, mclist->dmi_addr) & 0x3f;
-			mc_filter[filterbit >> 5] |= cpu_to_le32(1 << (filterbit & 31));
+			mc_filter[filterbit >> 5] |= 1 << (filterbit & 31);
 		}
 		new_mode = CMR2h_Normal;
 	}
diff -Nru a/drivers/net/bmac.c b/drivers/net/bmac.c
--- a/drivers/net/bmac.c	2005-03-01 23:38:51 -08:00
+++ b/drivers/net/bmac.c	2005-03-01 23:38:51 -08:00
@@ -59,9 +59,9 @@
 struct bmac_data {
 	/* volatile struct bmac *bmac; */
 	struct sk_buff_head *queue;
-	volatile struct dbdma_regs *tx_dma;
+	volatile struct dbdma_regs __iomem *tx_dma;
 	int tx_dma_intr;
-	volatile struct dbdma_regs *rx_dma;
+	volatile struct dbdma_regs __iomem *rx_dma;
 	int rx_dma_intr;
 	volatile struct dbdma_cmd *tx_cmds;	/* xmit dma command list */
 	volatile struct dbdma_cmd *rx_cmds;	/* recv dma command list */
@@ -165,35 +165,35 @@
 #define	DBDMA_CLEAR(x)	( (x) << 16)
 
 static inline void
-dbdma_st32(volatile unsigned long *a, unsigned long x)
+dbdma_st32(volatile __u32 __iomem *a, unsigned long x)
 {
 	__asm__ volatile( "stwbrx %0,0,%1" : : "r" (x), "r" (a) : "memory");
 	return;
 }
 
 static inline unsigned long
-dbdma_ld32(volatile unsigned long *a)
+dbdma_ld32(volatile __u32 __iomem *a)
 {
-	unsigned long swap;
+	__u32 swap;
 	__asm__ volatile ("lwbrx %0,0,%1" :  "=r" (swap) : "r" (a));
 	return swap;
 }
 
 static void
-dbdma_continue(volatile struct dbdma_regs *dmap)
+dbdma_continue(volatile struct dbdma_regs __iomem *dmap)
 {
-	dbdma_st32((volatile unsigned long *)&dmap->control,
+	dbdma_st32(&dmap->control,
 		   DBDMA_SET(RUN|WAKE) | DBDMA_CLEAR(PAUSE|DEAD));
 	eieio();
 }
 
 static void
-dbdma_reset(volatile struct dbdma_regs *dmap)
+dbdma_reset(volatile struct dbdma_regs __iomem *dmap)
 {
-	dbdma_st32((volatile unsigned long *)&dmap->control,
+	dbdma_st32(&dmap->control,
 		   DBDMA_CLEAR(ACTIVE|DEAD|WAKE|FLUSH|PAUSE|RUN));
 	eieio();
-	while (dbdma_ld32((volatile unsigned long *)&dmap->status) & RUN)
+	while (dbdma_ld32(&dmap->status) & RUN)
 		eieio();
 }
 
@@ -213,22 +213,22 @@
 static inline
 void bmwrite(struct net_device *dev, unsigned long reg_offset, unsigned data )
 {
-	out_le16((void *)dev->base_addr + reg_offset, data);
+	out_le16((void __iomem *)dev->base_addr + reg_offset, data);
 }
 
 
 static inline
 volatile unsigned short bmread(struct net_device *dev, unsigned long reg_offset )
 {
-	return in_le16((void *)dev->base_addr + reg_offset);
+	return in_le16((void __iomem *)dev->base_addr + reg_offset);
 }
 
 static void
 bmac_enable_and_reset_chip(struct net_device *dev)
 {
 	struct bmac_data *bp = netdev_priv(dev);
-	volatile struct dbdma_regs *rd = bp->rx_dma;
-	volatile struct dbdma_regs *td = bp->tx_dma;
+	volatile struct dbdma_regs __iomem *rd = bp->rx_dma;
+	volatile struct dbdma_regs __iomem *td = bp->tx_dma;
 
 	if (rd)
 		dbdma_reset(rd);
@@ -406,7 +406,7 @@
 bmac_start_chip(struct net_device *dev)
 {
 	struct bmac_data *bp = netdev_priv(dev);
-	volatile struct dbdma_regs *rd = bp->rx_dma;
+	volatile struct dbdma_regs __iomem *rd = bp->rx_dma;
 	unsigned short	oldConfig;
 
 	/* enable rx dma channel */
@@ -476,8 +476,8 @@
 	bp->sleeping = 1;
 	spin_unlock_irqrestore(&bp->lock, flags);
 	if (bp->opened) {
-		volatile struct dbdma_regs *rd = bp->rx_dma;
-		volatile struct dbdma_regs *td = bp->tx_dma;
+		volatile struct dbdma_regs __iomem *rd = bp->rx_dma;
+		volatile struct dbdma_regs __iomem *td = bp->tx_dma;
 			
 		config = bmread(dev, RXCFG);
 		bmwrite(dev, RXCFG, (config & ~RxMACEnable));
@@ -602,7 +602,7 @@
 static void
 bmac_init_tx_ring(struct bmac_data *bp)
 {
-	volatile struct dbdma_regs *td = bp->tx_dma;
+	volatile struct dbdma_regs __iomem *td = bp->tx_dma;
 
 	memset((char *)bp->tx_cmds, 0, (N_TX_RING+1) * sizeof(struct dbdma_cmd));
 
@@ -623,7 +623,7 @@
 static int
 bmac_init_rx_ring(struct bmac_data *bp)
 {
-	volatile struct dbdma_regs *rd = bp->rx_dma;
+	volatile struct dbdma_regs __iomem *rd = bp->rx_dma;
 	int i;
 	struct sk_buff *skb;
 
@@ -657,7 +657,7 @@
 static int bmac_transmit_packet(struct sk_buff *skb, struct net_device *dev)
 {
 	struct bmac_data *bp = netdev_priv(dev);
-	volatile struct dbdma_regs *td = bp->tx_dma;
+	volatile struct dbdma_regs __iomem *td = bp->tx_dma;
 	int i;
 
 	/* see if there's a free slot in the tx ring */
@@ -693,7 +693,7 @@
 {
 	struct net_device *dev = (struct net_device *) dev_id;
 	struct bmac_data *bp = netdev_priv(dev);
-	volatile struct dbdma_regs *rd = bp->rx_dma;
+	volatile struct dbdma_regs __iomem *rd = bp->rx_dma;
 	volatile struct dbdma_cmd *cp;
 	int i, nb, stat;
 	struct sk_buff *skb;
@@ -1331,13 +1331,11 @@
 		goto err_out_iounmap;
 
 	bp->is_bmac_plus = is_bmac_plus;
-	bp->tx_dma = (volatile struct dbdma_regs *)
-		ioremap(macio_resource_start(mdev, 1), macio_resource_len(mdev, 1));
+	bp->tx_dma = ioremap(macio_resource_start(mdev, 1), macio_resource_len(mdev, 1));
 	if (!bp->tx_dma)
 		goto err_out_iounmap;
 	bp->tx_dma_intr = macio_irq(mdev, 1);
-	bp->rx_dma = (volatile struct dbdma_regs *)
-		ioremap(macio_resource_start(mdev, 2), macio_resource_len(mdev, 2));
+	bp->rx_dma = ioremap(macio_resource_start(mdev, 2), macio_resource_len(mdev, 2));
 	if (!bp->rx_dma)
 		goto err_out_iounmap_tx;
 	bp->rx_dma_intr = macio_irq(mdev, 2);
@@ -1392,11 +1390,11 @@
 err_out_irq0:
 	free_irq(dev->irq, dev);
 err_out_iounmap_rx:
-	iounmap((void *)bp->rx_dma);
+	iounmap(bp->rx_dma);
 err_out_iounmap_tx:
-	iounmap((void *)bp->tx_dma);
+	iounmap(bp->tx_dma);
 err_out_iounmap:
-	iounmap((void *)dev->base_addr);
+	iounmap((void __iomem *)dev->base_addr);
 out_release:
 	macio_release_resources(mdev);
 out_free:
@@ -1421,8 +1419,8 @@
 static int bmac_close(struct net_device *dev)
 {
 	struct bmac_data *bp = netdev_priv(dev);
-	volatile struct dbdma_regs *rd = bp->rx_dma;
-	volatile struct dbdma_regs *td = bp->tx_dma;
+	volatile struct dbdma_regs __iomem *rd = bp->rx_dma;
+	volatile struct dbdma_regs __iomem *td = bp->tx_dma;
 	unsigned short config;
 	int i;
 
@@ -1505,8 +1503,8 @@
 {
 	struct net_device *dev = (struct net_device *) data;
 	struct bmac_data *bp = netdev_priv(dev);
-	volatile struct dbdma_regs *td = bp->tx_dma;
-	volatile struct dbdma_regs *rd = bp->rx_dma;
+	volatile struct dbdma_regs __iomem *td = bp->tx_dma;
+	volatile struct dbdma_regs __iomem *rd = bp->rx_dma;
 	volatile struct dbdma_cmd *cp;
 	unsigned long flags;
 	unsigned short config, oldConfig;
@@ -1638,9 +1636,9 @@
 	free_irq(bp->tx_dma_intr, dev);	
 	free_irq(bp->rx_dma_intr, dev);
 
-	iounmap((void *)dev->base_addr);
-	iounmap((void *)bp->tx_dma);
-	iounmap((void *)bp->rx_dma);
+	iounmap((void __iomem *)dev->base_addr);
+	iounmap(bp->tx_dma);
+	iounmap(bp->rx_dma);
 
 	macio_release_resources(mdev);
 
diff -Nru a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
--- a/drivers/net/bonding/bond_3ad.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/net/bonding/bond_3ad.c	2005-03-01 23:39:08 -08:00
@@ -130,7 +130,6 @@
 static u16 __get_link_speed(struct port *port);
 static u8 __get_duplex(struct port *port);
 static inline void __initialize_port_locks(struct port *port);
-static inline void __deinitialize_port_locks(struct port *port);
 //conversions
 static void __ntohs_lacpdu(struct lacpdu *lacpdu);
 static u16 __ad_timer_to_ticks(u16 timer_type, u16 Par);
@@ -443,15 +442,6 @@
 {
 	// make sure it isn't called twice
 	spin_lock_init(&(SLAVE_AD_INFO(port->slave).rx_machine_lock));
-}
-
-/**
- * __deinitialize_port_locks - deinitialize a port's RX machine spinlock
- * @port: the port we're looking at
- *
- */
-static inline void __deinitialize_port_locks(struct port *port)
-{
 }
 
 //conversions
diff -Nru a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
--- a/drivers/net/bonding/bond_main.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/net/bonding/bond_main.c	2005-03-01 23:39:16 -08:00
@@ -540,25 +540,25 @@
 static int arp_interval = BOND_LINK_ARP_INTERV;
 static char *arp_ip_target[BOND_MAX_ARP_TARGETS] = { NULL, };
 
-MODULE_PARM(max_bonds, "i");
+module_param(max_bonds, int, 0);
 MODULE_PARM_DESC(max_bonds, "Max number of bonded devices");
-MODULE_PARM(miimon, "i");
+module_param(miimon, int, 0);
 MODULE_PARM_DESC(miimon, "Link check interval in milliseconds");
-MODULE_PARM(updelay, "i");
+module_param(updelay, int, 0);
 MODULE_PARM_DESC(updelay, "Delay before considering link up, in milliseconds");
-MODULE_PARM(downdelay, "i");
+module_param(downdelay, int, 0);
 MODULE_PARM_DESC(downdelay, "Delay before considering link down, in milliseconds");
-MODULE_PARM(use_carrier, "i");
+module_param(use_carrier, int, 0);
 MODULE_PARM_DESC(use_carrier, "Use netif_carrier_ok (vs MII ioctls) in miimon; 0 for off, 1 for on (default)");
-MODULE_PARM(mode, "s");
+module_param(mode, charp, 0);
 MODULE_PARM_DESC(mode, "Mode of operation : 0 for round robin, 1 for active-backup, 2 for xor");
-MODULE_PARM(primary, "s");
+module_param(primary, charp, 0);
 MODULE_PARM_DESC(primary, "Primary network device to use");
-MODULE_PARM(lacp_rate, "s");
+module_param(lacp_rate, charp, 0);
 MODULE_PARM_DESC(lacp_rate, "LACPDU tx rate to request from 802.3ad partner (slow/fast)");
-MODULE_PARM(arp_interval, "i");
+module_param(arp_interval, int, 0);
 MODULE_PARM_DESC(arp_interval, "arp interval in milliseconds");
-MODULE_PARM(arp_ip_target, "1-" __MODULE_STRING(BOND_MAX_ARP_TARGETS) "s");
+module_param_array(arp_ip_target, charp, NULL, 0);
 MODULE_PARM_DESC(arp_ip_target, "arp targets in n.n.n.n form");
 
 /*----------------------------- Global variables ----------------------------*/
diff -Nru a/drivers/net/cs89x0.c b/drivers/net/cs89x0.c
--- a/drivers/net/cs89x0.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/net/cs89x0.c	2005-03-01 23:39:09 -08:00
@@ -1710,14 +1710,14 @@
 static int dma;
 static int dmasize=16;			/* or 64 */
 
-MODULE_PARM(io, "i");
-MODULE_PARM(irq, "i");
-MODULE_PARM(debug, "i");
-MODULE_PARM(media, "c8");
-MODULE_PARM(duplex, "i");
-MODULE_PARM(dma , "i");
-MODULE_PARM(dmasize , "i");
-MODULE_PARM(use_dma , "i");
+module_param(io, int, 0);
+module_param(irq, int, 0);
+module_param(debug, int, 0);
+module_param_string(media, media, sizeof(media), 0);
+module_param(duplex, int, 0);
+module_param(dma , int, 0);
+module_param(dmasize , int, 0);
+module_param(use_dma , int, 0);
 MODULE_PARM_DESC(io, "cs89x0 I/O base address");
 MODULE_PARM_DESC(irq, "cs89x0 IRQ number");
 #if DEBUGGING
diff -Nru a/drivers/net/de600.c b/drivers/net/de600.c
--- a/drivers/net/de600.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/net/de600.c	2005-03-01 23:39:17 -08:00
@@ -75,15 +75,15 @@
 #include "de600.h"
 
 static unsigned int de600_debug = DE600_DEBUG;
-MODULE_PARM(de600_debug, "i");
+module_param(de600_debug, int, 0);
 MODULE_PARM_DESC(de600_debug, "DE-600 debug level (0-2)");
 
 static unsigned int check_lost = 1;
-MODULE_PARM(check_lost, "i");
+module_param(check_lost, bool, 0);
 MODULE_PARM_DESC(check_lost, "If set then check for unplugged de600");
 
 static unsigned int delay_time = 10;
-MODULE_PARM(delay_time, "i");
+module_param(delay_time, int, 0);
 MODULE_PARM_DESC(delay_time, "DE-600 deley on I/O in microseconds");
 
 
@@ -99,7 +99,7 @@
 static volatile int		tx_fifo_out;
 static volatile int		free_tx_pages = TX_PAGES;
 static int			was_down;
-static spinlock_t		de600_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(de600_lock);
 
 static inline u8 de600_read_status(struct net_device *dev)
 {
diff -Nru a/drivers/net/de620.c b/drivers/net/de620.c
--- a/drivers/net/de620.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/net/de620.c	2005-03-01 23:38:57 -08:00
@@ -190,12 +190,12 @@
 
 static spinlock_t de620_lock;
 
-MODULE_PARM(bnc, "i");
-MODULE_PARM(utp, "i");
-MODULE_PARM(io, "i");
-MODULE_PARM(irq, "i");
-MODULE_PARM(clone, "i");
-MODULE_PARM(de620_debug, "i");
+module_param(bnc, int, 0);
+module_param(utp, int, 0);
+module_param(io, int, 0);
+module_param(irq, int, 0);
+module_param(clone, int, 0);
+module_param(de620_debug, int, 0);
 MODULE_PARM_DESC(bnc, "DE-620 set BNC medium (0-1)");
 MODULE_PARM_DESC(utp, "DE-620 set UTP medium (0-1)");
 MODULE_PARM_DESC(io, "DE-620 I/O base address,required");
diff -Nru a/drivers/net/depca.c b/drivers/net/depca.c
--- a/drivers/net/depca.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/net/depca.c	2005-03-01 23:38:57 -08:00
@@ -463,11 +463,11 @@
         } depca_bus;	        /* type of bus */
 	struct depca_init init_block;	/* Shadow Initialization block            */
 /* CPU address space fields */
-	struct depca_rx_desc *rx_ring;	/* Pointer to start of RX descriptor ring */
-	struct depca_tx_desc *tx_ring;	/* Pointer to start of TX descriptor ring */
-	void *rx_buff[NUM_RX_DESC];	/* CPU virt address of sh'd memory buffs  */
-	void *tx_buff[NUM_TX_DESC];	/* CPU virt address of sh'd memory buffs  */
-	void *sh_mem;		/* CPU mapped virt address of device RAM  */
+	struct depca_rx_desc __iomem *rx_ring;	/* Pointer to start of RX descriptor ring */
+	struct depca_tx_desc __iomem *tx_ring;	/* Pointer to start of TX descriptor ring */
+	void __iomem *rx_buff[NUM_RX_DESC];	/* CPU virt address of sh'd memory buffs  */
+	void __iomem *tx_buff[NUM_TX_DESC];	/* CPU virt address of sh'd memory buffs  */
+	void __iomem *sh_mem;	/* CPU mapped virt address of device RAM  */
 	u_long mem_start;	/* Bus address of device RAM (before remap) */
 	u_long mem_len;		/* device memory size */
 /* Device address space fields */
@@ -693,11 +693,11 @@
 
 	/* Tx & Rx descriptors (aligned to a quadword boundary) */
 	offset = (offset + DEPCA_ALIGN) & ~DEPCA_ALIGN;
-	lp->rx_ring = (struct depca_rx_desc *) (lp->sh_mem + offset);
+	lp->rx_ring = (struct depca_rx_desc __iomem *) (lp->sh_mem + offset);
 	lp->rx_ring_offset = offset;
 
 	offset += (sizeof(struct depca_rx_desc) * NUM_RX_DESC);
-	lp->tx_ring = (struct depca_tx_desc *) (lp->sh_mem + offset);
+	lp->tx_ring = (struct depca_tx_desc __iomem *) (lp->sh_mem + offset);
 	lp->tx_ring_offset = offset;
 
 	offset += (sizeof(struct depca_tx_desc) * NUM_TX_DESC);
@@ -1649,7 +1649,7 @@
 static int __init DepcaSignature(char *name, u_long base_addr)
 {
 	u_int i, j, k;
-	void *ptr;
+	void __iomem *ptr;
 	char tmpstr[16];
 	u_long prom_addr = base_addr + 0xc000;
 	u_long mem_addr = base_addr + 0x8000; /* 32KB */
@@ -1876,17 +1876,17 @@
 		printk("Descriptor addresses (CPU):\nRX: ");
 		for (i = 0; i < lp->rxRingMask; i++) {
 			if (i < 3) {
-				printk("0x%8.8lx ", (long) &lp->rx_ring[i].base);
+				printk("%p ", &lp->rx_ring[i].base);
 			}
 		}
-		printk("...0x%8.8lx\n", (long) &lp->rx_ring[i].base);
+		printk("...%p\n", &lp->rx_ring[i].base);
 		printk("TX: ");
 		for (i = 0; i < lp->txRingMask; i++) {
 			if (i < 3) {
-				printk("0x%8.8lx ", (long) &lp->tx_ring[i].base);
+				printk("%p ", &lp->tx_ring[i].base);
 			}
 		}
-		printk("...0x%8.8lx\n", (long) &lp->tx_ring[i].base);
+		printk("...%p\n", &lp->tx_ring[i].base);
 		printk("\nDescriptor buffers (Device):\nRX: ");
 		for (i = 0; i < lp->rxRingMask; i++) {
 			if (i < 3) {
diff -Nru a/drivers/net/dgrs.c b/drivers/net/dgrs.c
--- a/drivers/net/dgrs.c	2005-03-01 23:38:51 -08:00
+++ b/drivers/net/dgrs.c	2005-03-01 23:38:51 -08:00
@@ -1534,14 +1534,14 @@
 static __u32	ipxnet = -1;
 static int	nicmode = -1;
 
-MODULE_PARM(debug, "i");
-MODULE_PARM(dma, "i");
-MODULE_PARM(hashexpire, "i");
-MODULE_PARM(spantree, "i");
-MODULE_PARM(ipaddr, "1-4i");
-MODULE_PARM(iptrap, "1-4i");
-MODULE_PARM(ipxnet, "i");
-MODULE_PARM(nicmode, "i");
+module_param(debug, int, 0);
+module_param(dma, int, 0);
+module_param(hashexpire, int, 0);
+module_param(spantree, int, 0);
+module_param_array(ipaddr, int, NULL, 0);
+module_param_array(iptrap, int, NULL, 0);
+module_param(ipxnet, int, 0);
+module_param(nicmode, int, 0);
 MODULE_PARM_DESC(debug, "Digi RightSwitch enable debugging (0-1)");
 MODULE_PARM_DESC(dma, "Digi RightSwitch enable BM DMA (0-1)");
 MODULE_PARM_DESC(nicmode, "Digi RightSwitch operating mode (1: switch, 2: multi-NIC)");
diff -Nru a/drivers/net/dl2k.c b/drivers/net/dl2k.c
--- a/drivers/net/dl2k.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/net/dl2k.c	2005-03-01 23:38:56 -08:00
@@ -72,16 +72,16 @@
 MODULE_AUTHOR ("Edward Peng");
 MODULE_DESCRIPTION ("D-Link DL2000-based Gigabit Ethernet Adapter");
 MODULE_LICENSE("GPL");
-MODULE_PARM (mtu, "1-" __MODULE_STRING (MAX_UNITS) "i");
-MODULE_PARM (media, "1-" __MODULE_STRING (MAX_UNITS) "s");
-MODULE_PARM (vlan, "1-" __MODULE_STRING (MAX_UNITS) "i");
-MODULE_PARM (jumbo, "1-" __MODULE_STRING (MAX_UNITS) "i");
-MODULE_PARM (tx_flow, "i");
-MODULE_PARM (rx_flow, "i");
-MODULE_PARM (copy_thresh, "i");
-MODULE_PARM (rx_coalesce, "i");	/* Rx frame count each interrupt */
-MODULE_PARM (rx_timeout, "i");	/* Rx DMA wait time in 64ns increments */
-MODULE_PARM (tx_coalesce, "i"); /* HW xmit count each TxDMAComplete */
+module_param_array(mtu, int, NULL, 0);
+module_param_array(media, charp, NULL, 0);
+module_param_array(vlan, int, NULL, 0);
+module_param_array(jumbo, int, NULL, 0);
+module_param(tx_flow, int, 0);
+module_param(rx_flow, int, 0);
+module_param(copy_thresh, int, 0);
+module_param(rx_coalesce, int, 0);	/* Rx frame count each interrupt */
+module_param(rx_timeout, int, 0);	/* Rx DMA wait time in 64ns increments */
+module_param(tx_coalesce, int, 0); /* HW xmit count each TxDMAComplete */
 
 
 /* Enable the default interrupts */
diff -Nru a/drivers/net/e100.c b/drivers/net/e100.c
--- a/drivers/net/e100.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/net/e100.c	2005-03-01 23:39:17 -08:00
@@ -155,7 +155,7 @@
 
 #define DRV_NAME		"e100"
 #define DRV_EXT		"-NAPI"
-#define DRV_VERSION		"3.2.3-k2"DRV_EXT
+#define DRV_VERSION		"3.3.6-k2"DRV_EXT
 #define DRV_DESCRIPTION		"Intel(R) PRO/100 Network Driver"
 #define DRV_COPYRIGHT		"Copyright(c) 1999-2004 Intel Corporation"
 #define PFX			DRV_NAME ": "
@@ -166,6 +166,7 @@
 MODULE_DESCRIPTION(DRV_DESCRIPTION);
 MODULE_AUTHOR(DRV_COPYRIGHT);
 MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
 
 static int debug = 3;
 module_param(debug, int, 0);
@@ -200,6 +201,7 @@
 	INTEL_8255X_ETHERNET_DEVICE(0x1055, 5),
 	INTEL_8255X_ETHERNET_DEVICE(0x1056, 5),
 	INTEL_8255X_ETHERNET_DEVICE(0x1057, 5),
+	INTEL_8255X_ETHERNET_DEVICE(0x1059, 0),
 	INTEL_8255X_ETHERNET_DEVICE(0x1064, 6),
 	INTEL_8255X_ETHERNET_DEVICE(0x1065, 6),
 	INTEL_8255X_ETHERNET_DEVICE(0x1066, 6),
@@ -208,7 +210,6 @@
 	INTEL_8255X_ETHERNET_DEVICE(0x1069, 6),
 	INTEL_8255X_ETHERNET_DEVICE(0x106A, 6),
 	INTEL_8255X_ETHERNET_DEVICE(0x106B, 6),
-	INTEL_8255X_ETHERNET_DEVICE(0x1059, 0),
 	INTEL_8255X_ETHERNET_DEVICE(0x1209, 0),
 	INTEL_8255X_ETHERNET_DEVICE(0x1229, 0),
 	INTEL_8255X_ETHERNET_DEVICE(0x2449, 2),
@@ -620,8 +621,7 @@
 	writel(selftest | dma_addr, &nic->csr->port);
 	e100_write_flush(nic);
 	/* Wait 10 msec for self-test to complete */
-	set_current_state(TASK_UNINTERRUPTIBLE);
-	schedule_timeout(HZ / 100 + 1);
+	msleep(10);
 
 	/* Interrupts are enabled after self-test */
 	e100_disable_irq(nic);
@@ -669,8 +669,7 @@
 			e100_write_flush(nic); udelay(4);
 		}
 		/* Wait 10 msec for cmd to complete */
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(HZ / 100 + 1);
+		msleep(10);
 
 		/* Chip deselect */
 		writeb(0, &nic->csr->eeprom_ctrl_lo);
@@ -1631,6 +1630,7 @@
 	struct nic *nic = netdev_priv(netdev);
 	e100_disable_irq(nic);
 	e100_intr(nic->pdev->irq, netdev, NULL);
+	e100_tx_clean(nic);
 	e100_enable_irq(nic);
 }
 #endif
@@ -1759,8 +1759,7 @@
 	memset(skb->data, 0xFF, ETH_DATA_LEN);
 	e100_xmit_frame(skb, nic->netdev);
 
-	set_current_state(TASK_UNINTERRUPTIBLE);
-	schedule_timeout(HZ / 100 + 1);
+	msleep(10);
 
 	if(memcmp(nic->rx_to_clean->skb->data + sizeof(struct rfd),
 	   skb->data, ETH_DATA_LEN))
@@ -1846,8 +1845,7 @@
 			mdio_read(netdev, nic->mii.phy_id, i);
 	memset(nic->mem->dump_buf, 0, sizeof(nic->mem->dump_buf));
 	e100_exec_cb(nic, NULL, e100_dump);
-	set_current_state(TASK_UNINTERRUPTIBLE);
-	schedule_timeout(HZ / 100 + 1);
+	msleep(10);
 	memcpy(&buff[2 + E100_PHY_REGS], nic->mem->dump_buf,
 		sizeof(nic->mem->dump_buf));
 }
@@ -2026,8 +2024,7 @@
 	if(!data || data > (u32)(MAX_SCHEDULE_TIMEOUT / HZ))
 		data = (u32)(MAX_SCHEDULE_TIMEOUT / HZ);
 	mod_timer(&nic->blink_timer, jiffies);
-	set_current_state(TASK_INTERRUPTIBLE);
-	schedule_timeout(data * HZ);
+	msleep_interruptible(data * 1000);
 	del_timer_sync(&nic->blink_timer);
 	mdio_write(netdev, nic->mii.phy_id, MII_LED_CONTROL, 0);
 
@@ -2326,7 +2323,7 @@
 	pci_save_state(pdev);
 	pci_enable_wake(pdev, state, nic->flags & (wol_magic | e100_asf(nic)));
 	pci_disable_device(pdev);
-	pci_set_power_state(pdev, state);
+	pci_set_power_state(pdev, pci_choose_state(pdev, state));
 
 	return 0;
 }
@@ -2336,7 +2333,7 @@
 	struct net_device *netdev = pci_get_drvdata(pdev);
 	struct nic *nic = netdev_priv(netdev);
 
-	pci_set_power_state(pdev, 0);
+	pci_set_power_state(pdev, PCI_D0);
 	pci_restore_state(pdev);
 	e100_hw_init(nic);
 
diff -Nru a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c
--- a/drivers/net/e1000/e1000_ethtool.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/net/e1000/e1000_ethtool.c	2005-03-01 23:38:56 -08:00
@@ -776,7 +776,7 @@
 e1000_intr_test(struct e1000_adapter *adapter, uint64_t *data)
 {
 	struct net_device *netdev = adapter->netdev;
- 	uint32_t icr, mask, i=0, shared_int = TRUE;
+ 	uint32_t mask, i=0, shared_int = TRUE;
  	uint32_t irq = adapter->pdev->irq;
 
 	*data = 0;
@@ -784,7 +784,8 @@
 	/* Hook up test interrupt handler just for this test */
  	if(!request_irq(irq, &e1000_test_intr, 0, netdev->name, netdev)) {
  		shared_int = FALSE;
- 	} else if(request_irq(irq, &e1000_test_intr, SA_SHIRQ, netdev->name, netdev)){
+ 	} else if(request_irq(irq, &e1000_test_intr, SA_SHIRQ, 
+			netdev->name, netdev)){
 		*data = 1;
 		return -1;
 	}
@@ -793,21 +794,6 @@
 	E1000_WRITE_REG(&adapter->hw, IMC, 0xFFFFFFFF);
 	msec_delay(10);
 
-	/* Interrupts are disabled, so read interrupt cause
-	 * register (icr) twice to verify that there are no interrupts
-	 * pending.  icr is clear on read.
-	 */
-	icr = E1000_READ_REG(&adapter->hw, ICR);
-	icr = E1000_READ_REG(&adapter->hw, ICR);
-
-	if(icr != 0) {
-		/* if icr is non-zero, there is no point
-		 * running other interrupt tests.
-		 */
-		*data = 2;
-		i = 10;
-	}
-
 	/* Test each interrupt */
 	for(; i < 10; i++) {
 
@@ -856,8 +842,10 @@
 			 * test failed.
 			 */
 			adapter->test_icr = 0;
-			E1000_WRITE_REG(&adapter->hw, IMC, ~mask);
-			E1000_WRITE_REG(&adapter->hw, ICS, ~mask);
+			E1000_WRITE_REG(&adapter->hw, IMC, 
+					(~mask & 0x00007FFF));
+			E1000_WRITE_REG(&adapter->hw, ICS, 
+					(~mask & 0x00007FFF));
 			msec_delay(10);
 
 			if(adapter->test_icr) {
@@ -1336,10 +1324,17 @@
 
 	msec_delay(200);
 
-	pci_dma_sync_single_for_cpu(pdev, rxdr->buffer_info[0].dma,
-			    rxdr->buffer_info[0].length, PCI_DMA_FROMDEVICE);
+	i = 0;
+	do {
+		pci_dma_sync_single_for_cpu(pdev, rxdr->buffer_info[i].dma,
+					    rxdr->buffer_info[i].length,
+					    PCI_DMA_FROMDEVICE);
+
+		if (!e1000_check_lbtest_frame(rxdr->buffer_info[i++].skb, 1024))
+			return 0;
+	} while (i < 64);
 
-	return e1000_check_lbtest_frame(rxdr->buffer_info[0].skb, 1024);
+	return 13;
 }
 
 static int
@@ -1358,10 +1353,27 @@
 e1000_link_test(struct e1000_adapter *adapter, uint64_t *data)
 {
 	*data = 0;
-	e1000_check_for_link(&adapter->hw);
 
-	if(!(E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_LU)) {
-		*data = 1;
+	if (adapter->hw.media_type == e1000_media_type_internal_serdes) {
+		int i = 0;
+		adapter->hw.serdes_link_down = TRUE;
+
+		/* on some blade server designs link establishment */
+		/* could take as long as 2-3 minutes.              */
+		do {
+			e1000_check_for_link(&adapter->hw);
+			if (adapter->hw.serdes_link_down == FALSE)
+				return *data;
+			msec_delay(20);
+		} while (i++ < 3750);
+
+		*data = 1; 
+	} else {
+		e1000_check_for_link(&adapter->hw);
+
+		if(!(E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_LU)) {
+			*data = 1;
+		}
 	}
 	return *data;
 }
@@ -1490,6 +1502,8 @@
 	case E1000_DEV_ID_82543GC_COPPER:
 	case E1000_DEV_ID_82544EI_FIBER:
 	case E1000_DEV_ID_82546EB_QUAD_COPPER:
+	case E1000_DEV_ID_82545EM_FIBER:
+	case E1000_DEV_ID_82545EM_COPPER:
 		return wol->wolopts ? -EOPNOTSUPP : 0;
 
 	case E1000_DEV_ID_82546EB_FIBER:
@@ -1554,9 +1568,7 @@
 	e1000_setup_led(&adapter->hw);
 	mod_timer(&adapter->blink_timer, jiffies);
 
-	set_current_state(TASK_INTERRUPTIBLE);
-
-	schedule_timeout(data * HZ);
+	msleep_interruptible(data * 1000);
 	del_timer_sync(&adapter->blink_timer);
 	e1000_led_off(&adapter->hw);
 	clear_bit(E1000_LED_ON, &adapter->led_status);
@@ -1654,7 +1666,7 @@
 	.get_ethtool_stats      = e1000_get_ethtool_stats,
 };
 
-void set_ethtool_ops(struct net_device *netdev)
+void e1000_set_ethtool_ops(struct net_device *netdev)
 {
 	SET_ETHTOOL_OPS(netdev, &e1000_ethtool_ops);
 }
diff -Nru a/drivers/net/e1000/e1000_hw.c b/drivers/net/e1000/e1000_hw.c
--- a/drivers/net/e1000/e1000_hw.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/net/e1000/e1000_hw.c	2005-03-01 23:39:17 -08:00
@@ -123,16 +123,31 @@
 static void
 e1000_phy_init_script(struct e1000_hw *hw)
 {
+    uint32_t ret_val;
+    uint16_t phy_saved_data;
+
     DEBUGFUNC("e1000_phy_init_script");
 
+
     if(hw->phy_init_script) {
         msec_delay(20);
 
+        /* Save off the current value of register 0x2F5B to be restored at
+         * the end of this routine. */
+        ret_val = e1000_read_phy_reg(hw, 0x2F5B, &phy_saved_data);
+
+        /* Disabled the PHY transmitter */
+        e1000_write_phy_reg(hw, 0x2F5B, 0x0003);
+
+        msec_delay(20);
+
         e1000_write_phy_reg(hw,0x0000,0x0140);
 
         msec_delay(5);
 
-        if(hw->mac_type == e1000_82541 || hw->mac_type == e1000_82547) {
+        switch(hw->mac_type) {
+        case e1000_82541:
+        case e1000_82547:
             e1000_write_phy_reg(hw, 0x1F95, 0x0001);
 
             e1000_write_phy_reg(hw, 0x1F71, 0xBD21);
@@ -150,12 +165,23 @@
             e1000_write_phy_reg(hw, 0x1F96, 0x003F);
 
             e1000_write_phy_reg(hw, 0x2010, 0x0008);
-        } else {
+            break;
+
+        case e1000_82541_rev_2:
+        case e1000_82547_rev_2:
             e1000_write_phy_reg(hw, 0x1F73, 0x0099);
+            break;
+        default:
+            break;
         }
 
         e1000_write_phy_reg(hw, 0x0000, 0x3300);
 
+        msec_delay(20);
+
+        /* Now enable the transmitter */
+        e1000_write_phy_reg(hw, 0x2F5B, phy_saved_data);
+
         if(hw->mac_type == e1000_82547) {
             uint16_t fused, fine, coarse;
 
@@ -244,6 +270,7 @@
     case E1000_DEV_ID_82546GB_COPPER:
     case E1000_DEV_ID_82546GB_FIBER:
     case E1000_DEV_ID_82546GB_SERDES:
+    case E1000_DEV_ID_82546GB_PCIE:
         hw->mac_type = e1000_82546_rev_3;
         break;
     case E1000_DEV_ID_82541EI:
@@ -967,7 +994,7 @@
 
             if((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
                 hw->dsp_config_state = e1000_dsp_config_disabled;
-                /* Force MDI for IGP B-0 PHY */
+                /* Force MDI for earlier revs of the IGP PHY */
                 phy_data &= ~(IGP01E1000_PSCR_AUTO_MDIX |
                               IGP01E1000_PSCR_FORCE_MDI_MDIX);
                 hw->mdix = 1;
@@ -2111,7 +2138,7 @@
          * at gigabit speed, then TBI compatibility is not needed.  If we are
          * at gigabit speed, we turn on TBI compatibility.
          */
-	if(hw->tbi_compatibility_en) {
+        if(hw->tbi_compatibility_en) {
             uint16_t speed, duplex;
             e1000_get_speed_and_duplex(hw, &speed, &duplex);
             if(speed != SPEED_1000) {
@@ -2466,12 +2493,14 @@
 
     DEBUGFUNC("e1000_read_phy_reg");
 
+
     if(hw->phy_type == e1000_phy_igp &&
        (reg_addr > MAX_PHY_MULTI_PAGE_REG)) {
         ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT,
                                          (uint16_t)reg_addr);
-        if(ret_val)
+        if(ret_val) {
             return ret_val;
+        }
     }
 
     ret_val = e1000_read_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT & reg_addr,
@@ -2570,12 +2599,14 @@
 
     DEBUGFUNC("e1000_write_phy_reg");
 
+
     if(hw->phy_type == e1000_phy_igp &&
        (reg_addr > MAX_PHY_MULTI_PAGE_REG)) {
         ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT,
                                          (uint16_t)reg_addr);
-        if(ret_val)
+        if(ret_val) {
             return ret_val;
+        }
     }
 
     ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT & reg_addr,
@@ -3478,7 +3509,7 @@
     /* A check for invalid values:  offset too large, too many words, and not
      * enough words.
      */
-    if((offset > eeprom->word_size) || (words > eeprom->word_size - offset) ||
+    if((offset >= eeprom->word_size) || (words > eeprom->word_size - offset) ||
        (words == 0)) {
         DEBUGOUT("\"words\" parameter out of bounds\n");
         return -E1000_ERR_EEPROM;
@@ -3626,7 +3657,7 @@
     /* A check for invalid values:  offset too large, too many words, and not
      * enough words.
      */
-    if((offset > eeprom->word_size) || (words > eeprom->word_size - offset) ||
+    if((offset >= eeprom->word_size) || (words > eeprom->word_size - offset) ||
        (words == 0)) {
         DEBUGOUT("\"words\" parameter out of bounds\n");
         return -E1000_ERR_EEPROM;
@@ -4918,7 +4949,7 @@
                                    boolean_t link_up)
 {
     int32_t ret_val;
-    uint16_t phy_data, speed, duplex, i;
+    uint16_t phy_data, phy_saved_data, speed, duplex, i;
     uint16_t dsp_reg_array[IGP01E1000_PHY_CHANNEL_NUM] =
                                         {IGP01E1000_PHY_AGC_PARAM_A,
                                         IGP01E1000_PHY_AGC_PARAM_B,
@@ -4999,6 +5030,21 @@
         }
     } else {
         if(hw->dsp_config_state == e1000_dsp_config_activated) {
+            /* Save off the current value of register 0x2F5B to be restored at
+             * the end of the routines. */
+            ret_val = e1000_read_phy_reg(hw, 0x2F5B, &phy_saved_data);
+
+            if(ret_val)
+                return ret_val;
+
+            /* Disable the PHY transmitter */
+            ret_val = e1000_write_phy_reg(hw, 0x2F5B, 0x0003);
+
+            if(ret_val)
+                return ret_val;
+
+            msec_delay(20);
+
             ret_val = e1000_write_phy_reg(hw, 0x0000,
                                           IGP01E1000_IEEE_FORCE_GIGA);
             if(ret_val)
@@ -5021,10 +5067,33 @@
             if(ret_val)
                 return ret_val;
 
+            msec_delay(20);
+
+            /* Now enable the transmitter */
+            ret_val = e1000_write_phy_reg(hw, 0x2F5B, phy_saved_data);
+
+            if(ret_val)
+                return ret_val;
+
             hw->dsp_config_state = e1000_dsp_config_enabled;
         }
 
         if(hw->ffe_config_state == e1000_ffe_config_active) {
+            /* Save off the current value of register 0x2F5B to be restored at
+             * the end of the routines. */
+            ret_val = e1000_read_phy_reg(hw, 0x2F5B, &phy_saved_data);
+
+            if(ret_val)
+                return ret_val;
+
+            /* Disable the PHY transmitter */
+            ret_val = e1000_write_phy_reg(hw, 0x2F5B, 0x0003);
+
+            if(ret_val)
+                return ret_val;
+
+            msec_delay(20);
+
             ret_val = e1000_write_phy_reg(hw, 0x0000,
                                           IGP01E1000_IEEE_FORCE_GIGA);
             if(ret_val)
@@ -5038,6 +5107,15 @@
                                           IGP01E1000_IEEE_RESTART_AUTONEG);
             if(ret_val)
                 return ret_val;
+
+            msec_delay(20);
+
+            /* Now enable the transmitter */
+            ret_val = e1000_write_phy_reg(hw, 0x2F5B, phy_saved_data);
+
+            if(ret_val)
+                return ret_val;
+
             hw->ffe_config_state = e1000_ffe_config_enabled;
         }
     }
@@ -5126,14 +5204,29 @@
          * Dx states where the power conservation is most important.  During
          * driver activity we should enable SmartSpeed, so performance is
          * maintained. */
-        ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, &phy_data);
-        if(ret_val)
-            return ret_val;
+        if (hw->smart_speed == e1000_smart_speed_on) {
+            ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
+                                         &phy_data);
+            if(ret_val)
+                return ret_val;
 
-        phy_data |= IGP01E1000_PSCFR_SMART_SPEED;
-        ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, phy_data);
-        if(ret_val)
-            return ret_val;
+            phy_data |= IGP01E1000_PSCFR_SMART_SPEED;
+            ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
+                                          phy_data);
+            if(ret_val)
+                return ret_val;
+        } else if (hw->smart_speed == e1000_smart_speed_off) {
+            ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
+                                         &phy_data);
+	    if (ret_val)
+                return ret_val;
+
+            phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
+            ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
+                                          phy_data);
+            if(ret_val)
+                return ret_val;
+        }
 
     } else if((hw->autoneg_advertised == AUTONEG_ADVERTISE_SPEED_DEFAULT) ||
               (hw->autoneg_advertised == AUTONEG_ADVERTISE_10_ALL ) ||
diff -Nru a/drivers/net/e1000/e1000_hw.h b/drivers/net/e1000/e1000_hw.h
--- a/drivers/net/e1000/e1000_hw.h	2005-03-01 23:39:09 -08:00
+++ b/drivers/net/e1000/e1000_hw.h	2005-03-01 23:39:09 -08:00
@@ -168,6 +168,12 @@
 } e1000_downshift;
 
 typedef enum {
+    e1000_smart_speed_default = 0,
+    e1000_smart_speed_on,
+    e1000_smart_speed_off
+} e1000_smart_speed;
+
+typedef enum {
     e1000_polarity_reversal_enabled = 0,
     e1000_polarity_reversal_disabled,
     e1000_polarity_reversal_undefined = 0xFF
@@ -361,6 +367,7 @@
 #define E1000_DEV_ID_82546GB_COPPER      0x1079
 #define E1000_DEV_ID_82546GB_FIBER       0x107A
 #define E1000_DEV_ID_82546GB_SERDES      0x107B
+#define E1000_DEV_ID_82546GB_PCIE        0x108A
 #define E1000_DEV_ID_82547EI             0x1019
 #define NODE_ADDRESS_SIZE 6
 #define ETH_LENGTH_OF_ADDRESS 6
@@ -1026,6 +1033,7 @@
     uint8_t perm_mac_addr[NODE_ADDRESS_SIZE];
     boolean_t disable_polarity_correction;
     boolean_t speed_downgraded;
+    e1000_smart_speed smart_speed;
     e1000_dsp_config dsp_config_state;
     boolean_t get_link_status;
     boolean_t serdes_link_down;
diff -Nru a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
--- a/drivers/net/e1000/e1000_main.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/net/e1000/e1000_main.c	2005-03-01 23:39:18 -08:00
@@ -35,10 +35,19 @@
  * - More errlogging support from Jon Mason <jonmason@us.ibm.com>
  * - Fix TSO issues on PPC64 machines -- Jon Mason <jonmason@us.ibm.com>
  *
- * 5.3.11	6/4/04
- * - ethtool register dump reads MANC register conditionally.
- *
- * 5.3.10	6/1/04
+ * 5.6.5 	11/01/04
+ * - Enabling NETIF_F_SG without checksum offload is illegal - 
+     John Mason <jdmason@us.ibm.com>
+ * 5.6.3        10/26/04
+ * - Remove redundant initialization - Jamal Hadi
+ * - Reset buffer_info->dma in tx resource cleanup logic
+ * 5.6.2	10/12/04
+ * - Avoid filling tx_ring completely - shemminger@osdl.org
+ * - Replace schedule_timeout() with msleep()/msleep_interruptible() -
+ *   nacc@us.ibm.com
+ * - Sparse cleanup - shemminger@osdl.org
+ * - Fix tx resource cleanup logic
+ * - LLTX support - ak@suse.de and hadi@cyberus.ca
  */
 
 char e1000_driver_name[] = "e1000";
@@ -48,7 +57,7 @@
 #else
 #define DRIVERNAPI "-NAPI"
 #endif
-char e1000_driver_version[] = "5.5.4-k2"DRIVERNAPI;
+char e1000_driver_version[] = "5.6.10.1-k2"DRIVERNAPI;
 char e1000_copyright[] = "Copyright (c) 1999-2004 Intel Corporation.";
 
 /* e1000_pci_tbl - PCI Device ID Table
@@ -90,6 +99,7 @@
 	INTEL_E1000_ETHERNET_DEVICE(0x107A),
 	INTEL_E1000_ETHERNET_DEVICE(0x107B),
 	INTEL_E1000_ETHERNET_DEVICE(0x107C),
+	INTEL_E1000_ETHERNET_DEVICE(0x108A),
 	/* required last entry */
 	{0,}
 };
@@ -128,8 +138,6 @@
 static struct net_device_stats * e1000_get_stats(struct net_device *netdev);
 static int e1000_change_mtu(struct net_device *netdev, int new_mtu);
 static int e1000_set_mac(struct net_device *netdev, void *p);
-static void e1000_irq_disable(struct e1000_adapter *adapter);
-static void e1000_irq_enable(struct e1000_adapter *adapter);
 static irqreturn_t e1000_intr(int irq, void *data, struct pt_regs *regs);
 static boolean_t e1000_clean_tx_irq(struct e1000_adapter *adapter);
 #ifdef CONFIG_E1000_NAPI
@@ -143,12 +151,9 @@
 static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd);
 static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
 			   int cmd);
-void set_ethtool_ops(struct net_device *netdev);
+void e1000_set_ethtool_ops(struct net_device *netdev);
 static void e1000_enter_82542_rst(struct e1000_adapter *adapter);
 static void e1000_leave_82542_rst(struct e1000_adapter *adapter);
-static void e1000_rx_checksum(struct e1000_adapter *adapter,
-				struct e1000_rx_desc *rx_desc,
-				struct sk_buff *skb);
 static void e1000_tx_timeout(struct net_device *dev);
 static void e1000_tx_timeout_task(struct net_device *dev);
 static void e1000_smartspeed(struct e1000_adapter *adapter);
@@ -242,6 +247,33 @@
 
 module_exit(e1000_exit_module);
 
+/**
+ * e1000_irq_disable - Mask off interrupt generation on the NIC
+ * @adapter: board private structure
+ **/
+
+static inline void
+e1000_irq_disable(struct e1000_adapter *adapter)
+{
+	atomic_inc(&adapter->irq_sem);
+	E1000_WRITE_REG(&adapter->hw, IMC, ~0);
+	E1000_WRITE_FLUSH(&adapter->hw);
+	synchronize_irq(adapter->pdev->irq);
+}
+
+/**
+ * e1000_irq_enable - Enable default interrupt generation settings
+ * @adapter: board private structure
+ **/
+
+static inline void
+e1000_irq_enable(struct e1000_adapter *adapter)
+{
+	if(likely(atomic_dec_and_test(&adapter->irq_sem))) {
+		E1000_WRITE_REG(&adapter->hw, IMS, IMS_ENABLE_MASK);
+		E1000_WRITE_FLUSH(&adapter->hw);
+	}
+}
 
 int
 e1000_up(struct e1000_adapter *adapter)
@@ -443,7 +475,7 @@
 	netdev->set_mac_address = &e1000_set_mac;
 	netdev->change_mtu = &e1000_change_mtu;
 	netdev->do_ioctl = &e1000_ioctl;
-	set_ethtool_ops(netdev);
+	e1000_set_ethtool_ops(netdev);
 	netdev->tx_timeout = &e1000_tx_timeout;
 	netdev->watchdog_timeo = 5 * HZ;
 #ifdef CONFIG_E1000_NAPI
@@ -475,8 +507,6 @@
 				   NETIF_F_HW_VLAN_TX |
 				   NETIF_F_HW_VLAN_RX |
 				   NETIF_F_HW_VLAN_FILTER;
-	} else {
-		netdev->features = NETIF_F_SG;
 	}
 
 #ifdef NETIF_F_TSO
@@ -1061,6 +1091,24 @@
 	adapter->tx_ring.desc = NULL;
 }
 
+static inline void
+e1000_unmap_and_free_tx_resource(struct e1000_adapter *adapter,
+			struct e1000_buffer *buffer_info)
+{
+	struct pci_dev *pdev = adapter->pdev;
+	if(buffer_info->dma) {
+		pci_unmap_page(pdev,
+			       buffer_info->dma,
+			       buffer_info->length,
+			       PCI_DMA_TODEVICE);
+		buffer_info->dma = 0;
+	}
+	if(buffer_info->skb) {
+		dev_kfree_skb_any(buffer_info->skb);
+		buffer_info->skb = NULL;
+	}
+}
+
 /**
  * e1000_clean_tx_ring - Free Tx Buffers
  * @adapter: board private structure
@@ -1071,7 +1119,6 @@
 {
 	struct e1000_desc_ring *tx_ring = &adapter->tx_ring;
 	struct e1000_buffer *buffer_info;
-	struct pci_dev *pdev = adapter->pdev;
 	unsigned long size;
 	unsigned int i;
 
@@ -1079,17 +1126,7 @@
 
 	for(i = 0; i < tx_ring->count; i++) {
 		buffer_info = &tx_ring->buffer_info[i];
-		if(buffer_info->skb) {
-
-			pci_unmap_page(pdev,
-				       buffer_info->dma,
-				       buffer_info->length,
-				       PCI_DMA_TODEVICE);
-
-			dev_kfree_skb(buffer_info->skb);
-
-			buffer_info->skb = NULL;
-		}
+		e1000_unmap_and_free_tx_resource(adapter, buffer_info);
 	}
 
 	size = sizeof(struct e1000_buffer) * tx_ring->count;
@@ -1762,7 +1799,6 @@
 	unsigned int mss = 0;
 	int count = 0;
 	unsigned int f;
-	nr_frags = skb_shinfo(skb)->nr_frags;
 	len -= skb->data_len;
 
 	if(unlikely(skb->len <= 0)) {
@@ -1811,7 +1847,7 @@
 
 	/* need: count + 2 desc gap to keep tail from touching
 	 * head, otherwise try next time */
-	if(E1000_DESC_UNUSED(&adapter->tx_ring) < count + 2) {
+	if(unlikely(E1000_DESC_UNUSED(&adapter->tx_ring) < count + 2)) {
 		netif_stop_queue(netdev);
 		spin_unlock_irqrestore(&adapter->tx_lock, flags);
 		return NETDEV_TX_BUSY;
@@ -1844,6 +1880,10 @@
 
 	netdev->trans_start = jiffies;
 
+	/* Make sure there is space in the ring for the next send. */
+	if(unlikely(E1000_DESC_UNUSED(&adapter->tx_ring) < MAX_SKB_FRAGS + 2))
+		netif_stop_queue(netdev);
+
 	spin_unlock_irqrestore(&adapter->tx_lock, flags);
 	return NETDEV_TX_OK;
 }
@@ -1904,9 +1944,9 @@
 	int max_frame = new_mtu + ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
 
 	if((max_frame < MINIMUM_ETHERNET_FRAME_SIZE) ||
-	   (max_frame > MAX_JUMBO_FRAME_SIZE)) {
-		DPRINTK(PROBE, ERR, "Invalid MTU setting\n");
-		return -EINVAL;
+		(max_frame > MAX_JUMBO_FRAME_SIZE)) {
+			DPRINTK(PROBE, ERR, "Invalid MTU setting\n");
+			return -EINVAL;
 	}
 
 	if(max_frame <= MAXIMUM_ETHERNET_FRAME_SIZE) {
@@ -2074,34 +2114,6 @@
 }
 
 /**
- * e1000_irq_disable - Mask off interrupt generation on the NIC
- * @adapter: board private structure
- **/
-
-static void
-e1000_irq_disable(struct e1000_adapter *adapter)
-{
-	atomic_inc(&adapter->irq_sem);
-	E1000_WRITE_REG(&adapter->hw, IMC, ~0);
-	E1000_WRITE_FLUSH(&adapter->hw);
-	synchronize_irq(adapter->pdev->irq);
-}
-
-/**
- * e1000_irq_enable - Enable default interrupt generation settings
- * @adapter: board private structure
- **/
-
-static void
-e1000_irq_enable(struct e1000_adapter *adapter)
-{
-	if(likely(atomic_dec_and_test(&adapter->irq_sem))) {
-		E1000_WRITE_REG(&adapter->hw, IMS, IMS_ENABLE_MASK);
-		E1000_WRITE_FLUSH(&adapter->hw);
-	}
-}
-
-/**
  * e1000_intr - Interrupt Handler
  * @irq: interrupt number
  * @data: pointer to a network interface device structure
@@ -2162,6 +2174,9 @@
 	int tx_cleaned;
 	int work_done = 0;
 	
+	if (!netif_carrier_ok(netdev))
+		goto quit_polling;
+
 	tx_cleaned = e1000_clean_tx_irq(adapter);
 	e1000_clean_rx_irq(adapter, &work_done, work_to_do);
 
@@ -2171,7 +2186,7 @@
 	/* if no Rx and Tx cleanup work was done, exit the polling mode */
 	if(!tx_cleaned || (work_done < work_to_do) || 
 				!netif_running(netdev)) {
-		netif_rx_complete(netdev);
+quit_polling:	netif_rx_complete(netdev);
 		e1000_irq_enable(adapter);
 		return 0;
 	}
@@ -2190,7 +2205,6 @@
 {
 	struct e1000_desc_ring *tx_ring = &adapter->tx_ring;
 	struct net_device *netdev = adapter->netdev;
-	struct pci_dev *pdev = adapter->pdev;
 	struct e1000_tx_desc *tx_desc, *eop_desc;
 	struct e1000_buffer *buffer_info;
 	unsigned int i, eop;
@@ -2205,19 +2219,7 @@
 			tx_desc = E1000_TX_DESC(*tx_ring, i);
 			buffer_info = &tx_ring->buffer_info[i];
 
-			if(likely(buffer_info->dma)) {
-				pci_unmap_page(pdev,
-					       buffer_info->dma,
-					       buffer_info->length,
-					       PCI_DMA_TODEVICE);
-				buffer_info->dma = 0;
-			}
-
-			if(buffer_info->skb) {
-				dev_kfree_skb_any(buffer_info->skb);
-				buffer_info->skb = NULL;
-			}
-
+			e1000_unmap_and_free_tx_resource(adapter, buffer_info);
 			tx_desc->buffer_addr = 0;
 			tx_desc->lower.data = 0;
 			tx_desc->upper.data = 0;
@@ -2244,6 +2246,41 @@
 }
 
 /**
+ * e1000_rx_checksum - Receive Checksum Offload for 82543
+ * @adapter: board private structure
+ * @rx_desc: receive descriptor
+ * @sk_buff: socket buffer with received data
+ **/
+
+static inline void
+e1000_rx_checksum(struct e1000_adapter *adapter,
+                  struct e1000_rx_desc *rx_desc,
+                  struct sk_buff *skb)
+{
+	/* 82543 or newer only */
+	if(unlikely((adapter->hw.mac_type < e1000_82543) ||
+	/* Ignore Checksum bit is set */
+	(rx_desc->status & E1000_RXD_STAT_IXSM) ||
+	/* TCP Checksum has not been calculated */
+	(!(rx_desc->status & E1000_RXD_STAT_TCPCS)))) {
+		skb->ip_summed = CHECKSUM_NONE;
+		return;
+	}
+
+	/* At this point we know the hardware did the TCP checksum */
+	/* now look at the TCP checksum error bit */
+	if(rx_desc->errors & E1000_RXD_ERR_TCPE) {
+		/* let the stack verify checksum errors */
+		skb->ip_summed = CHECKSUM_NONE;
+		adapter->hw_csum_err++;
+	} else {
+		/* TCP checksum is good */
+		skb->ip_summed = CHECKSUM_UNNECESSARY;
+		adapter->hw_csum_good++;
+	}
+}
+
+/**
  * e1000_clean_rx_irq - Send received data up the network stack
  * @adapter: board private structure
  **/
@@ -2291,7 +2328,7 @@
 		if(unlikely(!(rx_desc->status & E1000_RXD_STAT_EOP))) {
 			/* All receives must fit into a single buffer */
 			E1000_DBG("%s: Receive packet consumed multiple"
-				  " buffers\n", netdev->name);
+					" buffers\n", netdev->name);
 			dev_kfree_skb_irq(skb);
 			goto next_desc;
 		}
@@ -2376,8 +2413,8 @@
 	buffer_info = &rx_ring->buffer_info[i];
 
 	while(!buffer_info->skb) {
-
 		skb = dev_alloc_skb(adapter->rx_buffer_len + NET_IP_ALIGN);
+
 		if(unlikely(!skb)) {
 			/* Better luck next round */
 			break;
@@ -2585,41 +2622,6 @@
 		return -EOPNOTSUPP;
 	}
 	return E1000_SUCCESS;
-}
-
-/**
- * e1000_rx_checksum - Receive Checksum Offload for 82543
- * @adapter: board private structure
- * @rx_desc: receive descriptor
- * @sk_buff: socket buffer with received data
- **/
-
-static void
-e1000_rx_checksum(struct e1000_adapter *adapter,
-                  struct e1000_rx_desc *rx_desc,
-                  struct sk_buff *skb)
-{
-	/* 82543 or newer only */
-	if(unlikely((adapter->hw.mac_type < e1000_82543) ||
-	/* Ignore Checksum bit is set */
-	(rx_desc->status & E1000_RXD_STAT_IXSM) ||
-	/* TCP Checksum has not been calculated */
-	(!(rx_desc->status & E1000_RXD_STAT_TCPCS)))) {
-		skb->ip_summed = CHECKSUM_NONE;
-		return;
-	}
-
-	/* At this point we know the hardware did the TCP checksum */
-	/* now look at the TCP checksum error bit */
-	if(rx_desc->errors & E1000_RXD_ERR_TCPE) {
-		/* let the stack verify checksum errors */
-		skb->ip_summed = CHECKSUM_NONE;
-		adapter->hw_csum_err++;
-	} else {
-		/* TCP checksum is good */
-		skb->ip_summed = CHECKSUM_UNNECESSARY;
-		adapter->hw_csum_good++;
-	}
 }
 
 void
diff -Nru a/drivers/net/e1000/e1000_osdep.h b/drivers/net/e1000/e1000_osdep.h
--- a/drivers/net/e1000/e1000_osdep.h	2005-03-01 23:38:53 -08:00
+++ b/drivers/net/e1000/e1000_osdep.h	2005-03-01 23:38:53 -08:00
@@ -42,13 +42,8 @@
 #include <linux/sched.h>
 
 #ifndef msec_delay
-#define msec_delay(x)	do { if(in_interrupt()) { \
-				/* Don't mdelay in interrupt context! */ \
-	                	BUG(); \
-			} else { \
-				set_current_state(TASK_UNINTERRUPTIBLE); \
-				schedule_timeout((x * HZ)/1000 + 2); \
-			} } while(0)
+#define msec_delay(x) msleep(x)
+
 /* Some workarounds require millisecond delays and are run during interrupt
  * context.  Most notably, when establishing link, the phy may need tweaking
  * but cannot process phy register reads/writes faster than millisecond
diff -Nru a/drivers/net/e1000/e1000_param.c b/drivers/net/e1000/e1000_param.c
--- a/drivers/net/e1000/e1000_param.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/net/e1000/e1000_param.c	2005-03-01 23:39:08 -08:00
@@ -47,7 +47,7 @@
 #define E1000_PARAM(X, desc) \
 	static int __devinitdata X[E1000_MAX_NIC+1] = E1000_PARAM_INIT; \
 	static int num_##X = 0; \
-	module_param_array(X, int, &num_##X, 0); \
+	module_param_array_named(X, X, int, &num_##X, 0); \
 	MODULE_PARM_DESC(X, desc);
 
 /* Transmit Descriptor Count
@@ -470,9 +470,6 @@
 		if (num_InterruptThrottleRate > bd) {
 			adapter->itr = InterruptThrottleRate[bd];
 			switch(adapter->itr) {
-			case -1:
-				adapter->itr = 1;
-				break;
 			case 0:
 				DPRINTK(PROBE, INFO, "%s turned off\n", 
 					opt.name);
@@ -481,13 +478,14 @@
 				DPRINTK(PROBE, INFO, "%s set to dynamic mode\n", 
 					opt.name);
 				break;
+			case -1:
 			default:
 				e1000_validate_option(&adapter->itr, &opt, 
 					adapter);
 				break;
 			}
 		} else {
-			adapter->itr = 1;
+			adapter->itr = opt.def;
 		}
 	}
 
diff -Nru a/drivers/net/e2100.c b/drivers/net/e2100.c
--- a/drivers/net/e2100.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/net/e2100.c	2005-03-01 23:39:16 -08:00
@@ -72,7 +72,7 @@
 #define E21_SAPROM		0x10	/* Offset to station address data. */
 #define E21_IO_EXTENT	 0x20
 
-static inline void mem_on(short port, volatile char *mem_base,
+static inline void mem_on(short port, volatile char __iomem *mem_base,
 						  unsigned char start_page )
 {
 	/* This is a little weird: set the shared memory window by doing a
@@ -143,6 +143,7 @@
 static void cleanup_card(struct net_device *dev)
 {
 	/* NB: e21_close() handles free_irq */
+	iounmap(ei_status.mem);
 	release_region(dev->base_addr, E21_IO_EXTENT);
 }
 
@@ -257,6 +258,13 @@
 	if (dev->mem_start == 0)
 		dev->mem_start = 0xd0000;
 
+	ei_status.mem = ioremap(dev->mem_start, 2*1024);
+	if (!ei_status.mem) {
+		printk("unable to remap memory\n");
+		retval = -EAGAIN;
+		goto out;
+	}
+
 #ifdef notdef
 	/* These values are unused.  The E2100 has a 2K window into the packet
 	   buffer.  The window can be set to start on any page boundary. */
@@ -329,7 +337,7 @@
 {
 
 	short ioaddr = dev->base_addr;
-	char *shared_mem = (char *)dev->mem_start;
+	char __iomem *shared_mem = ei_status.mem;
 
 	mem_on(ioaddr, shared_mem, ring_page);
 
@@ -352,12 +360,12 @@
 e21_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset)
 {
 	short ioaddr = dev->base_addr;
-	char *shared_mem = (char *)dev->mem_start;
+	char __iomem *shared_mem = ei_status.mem;
 
 	mem_on(ioaddr, shared_mem, (ring_offset>>8));
 
 	/* Packet is always in one chunk -- we can copy + cksum. */
-	eth_io_copy_and_sum(skb, dev->mem_start + (ring_offset & 0xff), count, 0);
+	eth_io_copy_and_sum(skb, ei_status.mem + (ring_offset & 0xff), count, 0);
 
 	mem_off(ioaddr);
 }
@@ -367,7 +375,7 @@
 				 int start_page)
 {
 	short ioaddr = dev->base_addr;
-	volatile char *shared_mem = (char *)dev->mem_start;
+	volatile char __iomem *shared_mem = ei_status.mem;
 
 	/* Set the shared memory window start by doing a read, with the low address
 	   bits specifying the starting page. */
@@ -413,10 +421,10 @@
 static int mem[MAX_E21_CARDS];
 static int xcvr[MAX_E21_CARDS];		/* choose int. or ext. xcvr */
 
-MODULE_PARM(io, "1-" __MODULE_STRING(MAX_E21_CARDS) "i");
-MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_E21_CARDS) "i");
-MODULE_PARM(mem, "1-" __MODULE_STRING(MAX_E21_CARDS) "i");
-MODULE_PARM(xcvr, "1-" __MODULE_STRING(MAX_E21_CARDS) "i");
+module_param_array(io, int, NULL, 0);
+module_param_array(irq, int, NULL, 0);
+module_param_array(mem, int, NULL, 0);
+module_param_array(xcvr, int, NULL, 0);
 MODULE_PARM_DESC(io, "I/O base address(es)");
 MODULE_PARM_DESC(irq, "IRQ number(s)");
 MODULE_PARM_DESC(mem, " memory base address(es)");
diff -Nru a/drivers/net/eepro.c b/drivers/net/eepro.c
--- a/drivers/net/eepro.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/net/eepro.c	2005-03-01 23:39:08 -08:00
@@ -23,6 +23,7 @@
 	This is a compatibility hardware problem.
 
 	Versions:
+	0.13b	basic ethtool support (aris, 09/13/2004)
 	0.13a   in memory shortage, drop packets also in board
 		(Michael Westermann <mw@microdata-pos.de>, 07/30/2002)
 	0.13    irq sharing, rewrote probe function, fixed a nasty bug in
@@ -104,7 +105,7 @@
 */
 
 static const char version[] =
-	"eepro.c: v0.13 11/08/2001 aris@cathedrallabs.org\n";
+	"eepro.c: v0.13b 09/13/2004 aris@cathedrallabs.org\n";
 
 #include <linux/module.h>
 
@@ -146,19 +147,21 @@
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/bitops.h>
+#include <linux/ethtool.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
 #include <asm/dma.h>
 
 #define DRV_NAME "eepro"
+#define DRV_VERSION "0.13b"
 
 #define compat_dev_kfree_skb( skb, mode ) dev_kfree_skb( (skb) )
 /* I had reports of looong delays with SLOW_DOWN defined as udelay(2) */
 #define SLOW_DOWN inb(0x80)
 /* udelay(2) */
 #define compat_init_data     __initdata
-
+enum iftype { AUI=0, BNC=1, TPE=2 };
 
 /* First, a few definitions that the brave might change. */
 /* A zero-terminated list of I/O addresses to be probed. */
@@ -214,6 +217,7 @@
 	short rcv_lower_limit;
 	short rcv_upper_limit;
 	unsigned char eeprom_reg;
+	unsigned short word[8];
 };
 
 /* The station (ethernet) address prefix, used for IDing the board. */
@@ -608,16 +612,22 @@
 }
 #endif
 
-static void __init printEEPROMInfo(short ioaddr, struct net_device *dev)
+static void __init printEEPROMInfo(struct net_device *dev)
 {
+	struct eepro_local *lp = (struct eepro_local *)dev->priv;
+	int ioaddr = dev->base_addr;
 	unsigned short Word;
 	int i,j;
 
-	for (i=0, j=ee_Checksum; i<ee_SIZE; i++)
-		j+=read_eeprom(ioaddr,i,dev);
+	j = ee_Checksum;
+	for (i = 0; i < 8; i++)
+		j += lp->word[i];
+	for ( ; i < ee_SIZE; i++)
+		j += read_eeprom(ioaddr, i, dev);
+
 	printk(KERN_DEBUG "Checksum: %#x\n",j&0xffff);
 
-	Word=read_eeprom(ioaddr, 0, dev);
+	Word = lp->word[0];
 	printk(KERN_DEBUG "Word0:\n");
 	printk(KERN_DEBUG " Plug 'n Pray: %d\n",GetBit(Word,ee_PnP));
 	printk(KERN_DEBUG " Buswidth: %d\n",(GetBit(Word,ee_BusWidth)+1)*8 );
@@ -625,7 +635,7 @@
 	printk(KERN_DEBUG " IO Address: %#x\n", (Word>>ee_IO0)<<4);
 
 	if (net_debug>4)  {
-		Word=read_eeprom(ioaddr, 1, dev);
+		Word = lp->word[1];
 		printk(KERN_DEBUG "Word1:\n");
 		printk(KERN_DEBUG " INT: %d\n", Word & ee_IntMask);
 		printk(KERN_DEBUG " LI: %d\n", GetBit(Word,ee_LI));
@@ -636,7 +646,7 @@
 		printk(KERN_DEBUG " Duplex: %d\n", GetBit(Word,ee_Duplex));
 	}
 
-	Word=read_eeprom(ioaddr, 5, dev);
+	Word = lp->word[5];
 	printk(KERN_DEBUG "Word5:\n");
 	printk(KERN_DEBUG " BNC: %d\n",GetBit(Word,ee_BNC_TPE));
 	printk(KERN_DEBUG " NumConnectors: %d\n",GetBit(Word,ee_NumConn));
@@ -646,12 +656,12 @@
 	if (GetBit(Word,ee_PortAUI)) printk(KERN_DEBUG "AUI ");
 	printk(KERN_DEBUG "port(s) \n");
 
-	Word=read_eeprom(ioaddr, 6, dev);
+	Word = lp->word[6];
 	printk(KERN_DEBUG "Word6:\n");
 	printk(KERN_DEBUG " Stepping: %d\n",Word & ee_StepMask);
 	printk(KERN_DEBUG " BoardID: %d\n",Word>>ee_BoardID);
 
-	Word=read_eeprom(ioaddr, 7, dev);
+	Word = lp->word[7];
 	printk(KERN_DEBUG "Word7:\n");
 	printk(KERN_DEBUG " INT to IRQ:\n");
 
@@ -725,7 +735,7 @@
 		printk(", %s.\n", ifmap[dev->if_port]);
 
 	if (net_debug > 3) {
-		i = read_eeprom(dev->base_addr, 5, dev);
+		i = lp->word[5];
 		if (i & 0x2000) /* bit 13 of EEPROM word 5 */
 			printk(KERN_DEBUG "%s: Concurrent Processing is "
 				"enabled but not used!\n", dev->name);
@@ -733,19 +743,20 @@
 
 	/* Check the station address for the manufacturer's code */
 	if (net_debug>3)
-		printEEPROMInfo(dev->base_addr, dev);
+		printEEPROMInfo(dev);
 }
 
+static struct ethtool_ops eepro_ethtool_ops;
+
 /* This is the real probe routine.  Linux has a history of friendly device
    probes on the ISA bus.  A good device probe avoids doing writes, and
    verifies that the correct device exists and functions.  */
 
 static int __init eepro_probe1(struct net_device *dev, int autoprobe)
 {
-	unsigned short station_addr[6], id, counter;
+	unsigned short station_addr[3], id, counter;
 	int i;
 	struct eepro_local *lp;
-	enum iftype { AUI=0, BNC=1, TPE=2 };
 	int ioaddr = dev->base_addr;
 
 	/* Grab the region so we can find another board if autoIRQ fails. */
@@ -796,11 +807,16 @@
 		lp->xmt_bar = XMT_BAR_10;
 		station_addr[0] = read_eeprom(ioaddr, 2, dev);
 	}
-	station_addr[1] = read_eeprom(ioaddr, 3, dev);
-	station_addr[2] = read_eeprom(ioaddr, 4, dev);
+
+	/* get all words at once. will be used here and for ethtool */
+	for (i = 0; i < 8; i++) {
+		lp->word[i] = read_eeprom(ioaddr, i, dev);
+	}
+	station_addr[1] = lp->word[3];
+	station_addr[2] = lp->word[4];
 
 	if (!lp->eepro) {
-		if (read_eeprom(ioaddr,7,dev)== ee_FX_INT2IRQ)
+		if (lp->word[7] == ee_FX_INT2IRQ)
 			lp->eepro = 2;
 		else if (station_addr[2] == SA_ADDR1)
 			lp->eepro = 1;
@@ -817,15 +833,15 @@
 	/* calculate {xmt,rcv}_{lower,upper}_limit */
 	eepro_recalc(dev);
 
-	if (GetBit( read_eeprom(ioaddr, 5, dev),ee_BNC_TPE))
+	if (GetBit(lp->word[5], ee_BNC_TPE))
 		dev->if_port = BNC;
 	else
 		dev->if_port = TPE;
 
  	if (dev->irq < 2 && lp->eepro != 0) {
  		/* Mask off INT number */
- 		int count = read_eeprom(ioaddr, 1, dev) & 7;
- 		unsigned irqMask = read_eeprom(ioaddr, 7, dev);
+ 		int count = lp->word[1] & 7;
+ 		unsigned irqMask = lp->word[7];
  
  		while (count--)
  			irqMask &= irqMask - 1;
@@ -850,6 +866,7 @@
  	dev->set_multicast_list = &set_multicast_list;
  	dev->tx_timeout		= eepro_tx_timeout;
  	dev->watchdog_timeo	= TX_TIMEOUT;
+	dev->ethtool_ops	= &eepro_ethtool_ops;
  
 	/* print boot time info */
 	eepro_print_info(dev);
@@ -941,7 +958,7 @@
 	if (net_debug > 3)
 		printk(KERN_DEBUG "%s: entering eepro_open routine.\n", dev->name);
 
-	irqMask = read_eeprom(ioaddr,7,dev);
+	irqMask = lp->word[7];
 
 	if (lp->eepro == LAN595FX_10ISA) {
 		if (net_debug > 3) printk(KERN_DEBUG "p->eepro = 3;\n");
@@ -1070,8 +1087,6 @@
 		old9 = inb(ioaddr + 9);
 
 		if (irqMask==ee_FX_INT2IRQ) {
-			enum iftype { AUI=0, BNC=1, TPE=2 };
-
 			if (net_debug > 3) {
 				printk(KERN_DEBUG "IrqMask: %#x\n",irqMask);
 				printk(KERN_DEBUG "i82595FX detected!\n");
@@ -1701,12 +1716,72 @@
 	}
 }
 
+static int eepro_ethtool_get_settings(struct net_device *dev,
+					struct ethtool_cmd *cmd)
+{
+	struct eepro_local	*lp = (struct eepro_local *)dev->priv;
+
+	cmd->supported = 	SUPPORTED_10baseT_Half | 
+				SUPPORTED_10baseT_Full |
+				SUPPORTED_Autoneg;
+	cmd->advertising =	ADVERTISED_10baseT_Half |
+				ADVERTISED_10baseT_Full |
+				ADVERTISED_Autoneg;
+
+	if (GetBit(lp->word[5], ee_PortTPE)) {
+		cmd->supported |= SUPPORTED_TP;
+		cmd->advertising |= ADVERTISED_TP;
+	}
+	if (GetBit(lp->word[5], ee_PortBNC)) {
+		cmd->supported |= SUPPORTED_BNC;
+		cmd->advertising |= ADVERTISED_BNC;
+	}
+	if (GetBit(lp->word[5], ee_PortAUI)) {
+		cmd->supported |= SUPPORTED_AUI;
+		cmd->advertising |= ADVERTISED_AUI;
+	}
+
+	cmd->speed = SPEED_10;
+
+	if (dev->if_port == TPE && lp->word[1] & ee_Duplex) {
+		cmd->duplex = DUPLEX_FULL;
+	}
+	else {
+		cmd->duplex = DUPLEX_HALF;
+	}
+
+	cmd->port = dev->if_port;
+	cmd->phy_address = dev->base_addr;
+	cmd->transceiver = XCVR_INTERNAL;
+
+	if (lp->word[0] & ee_AutoNeg) {
+		cmd->autoneg = 1;
+	}
+
+	return 0;
+}
+
+static void eepro_ethtool_get_drvinfo(struct net_device *dev,
+					struct ethtool_drvinfo *drvinfo)
+{
+	strcpy(drvinfo->driver, DRV_NAME);
+	strcpy(drvinfo->version, DRV_VERSION);
+	sprintf(drvinfo->bus_info, "ISA 0x%lx", dev->base_addr);
+}
+
+static struct ethtool_ops eepro_ethtool_ops = {
+	.get_settings	= eepro_ethtool_get_settings,
+	.get_drvinfo 	= eepro_ethtool_get_drvinfo,
+};
+
 #ifdef MODULE
 
 #define MAX_EEPRO 8
 static struct net_device *dev_eepro[MAX_EEPRO];
 
-static int io[MAX_EEPRO];
+static int io[MAX_EEPRO] = {
+  [0 ... MAX_EEPRO-1] = -1
+};
 static int irq[MAX_EEPRO];
 static int mem[MAX_EEPRO] = {	/* Size of the rx buffer in KB */
   [0 ... MAX_EEPRO-1] = RCV_DEFAULT_RAM/1024
@@ -1716,14 +1791,15 @@
 static int n_eepro;
 /* For linux 2.1.xx */
 
-MODULE_AUTHOR("Pascal Dupuis, and aris@cathedrallabs.org");
+MODULE_AUTHOR("Pascal Dupuis and others");
 MODULE_DESCRIPTION("Intel i82595 ISA EtherExpressPro10/10+ driver");
 MODULE_LICENSE("GPL");
 
-MODULE_PARM(io, "1-" __MODULE_STRING(MAX_EEPRO) "i");
-MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_EEPRO) "i");
-MODULE_PARM(mem, "1-" __MODULE_STRING(MAX_EEPRO) "i");
-MODULE_PARM(autodetect, "1-" __MODULE_STRING(1) "i");
+static int num_params;
+module_param_array(io, int, &num_params, 0);
+module_param_array(irq, int, &num_params, 0);
+module_param_array(mem, int, &num_params, 0);
+module_param(autodetect, int, 0);
 MODULE_PARM_DESC(io, "EtherExpress Pro/10 I/O base addres(es)");
 MODULE_PARM_DESC(irq, "EtherExpress Pro/10 IRQ number(s)");
 MODULE_PARM_DESC(mem, "EtherExpress Pro/10 Rx buffer size(es) in kB (3-29)");
@@ -1734,19 +1810,21 @@
 {
 	struct net_device *dev;
 	int i;
-	if (io[0] == 0 && autodetect == 0) {
+	if (io[0] == -1 && autodetect == 0) {
 		printk(KERN_WARNING "eepro_init_module: Probe is very dangerous in ISA boards!\n");
 		printk(KERN_WARNING "eepro_init_module: Please add \"autodetect=1\" to force probe\n");
-		return 1;
+		return -ENODEV;
 	}
 	else if (autodetect) {
 		/* if autodetect is set then we must force detection */
-		io[0] = 0;
+		for (i = 0; i < MAX_EEPRO; i++) {
+			io[i] = 0;
+		}
 
 		printk(KERN_INFO "eepro_init_module: Auto-detecting boards (May God protect us...)\n");
 	}
 
-	for (i = 0; i < MAX_EEPRO; i++) {
+	for (i = 0; io[i] != -1 && i < MAX_EEPRO; i++) {
 		dev = alloc_etherdev(sizeof(struct eepro_local));
 		if (!dev)
 			break;
diff -Nru a/drivers/net/eepro100.c b/drivers/net/eepro100.c
--- a/drivers/net/eepro100.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/net/eepro100.c	2005-03-01 23:39:07 -08:00
@@ -114,11 +114,7 @@
 #include <linux/skbuff.h>
 #include <linux/ethtool.h>
 
-/* enable PIO instead of MMIO, if CONFIG_EEPRO100_PIO is selected */
-#ifdef CONFIG_EEPRO100_PIO
-#define USE_IO 1
-#endif
-
+static int use_io;
 static int debug = -1;
 #define DEBUG_DEFAULT		(NETIF_MSG_DRV		| \
 				 NETIF_MSG_HW		| \
@@ -130,17 +126,18 @@
 MODULE_AUTHOR("Maintainer: Andrey V. Savochkin <saw@saw.sw.com.sg>");
 MODULE_DESCRIPTION("Intel i82557/i82558/i82559 PCI EtherExpressPro driver");
 MODULE_LICENSE("GPL");
-MODULE_PARM(debug, "i");
-MODULE_PARM(options, "1-" __MODULE_STRING(8) "i");
-MODULE_PARM(full_duplex, "1-" __MODULE_STRING(8) "i");
-MODULE_PARM(congenb, "i");
-MODULE_PARM(txfifo, "i");
-MODULE_PARM(rxfifo, "i");
-MODULE_PARM(txdmacount, "i");
-MODULE_PARM(rxdmacount, "i");
-MODULE_PARM(rx_copybreak, "i");
-MODULE_PARM(max_interrupt_work, "i");
-MODULE_PARM(multicast_filter_limit, "i");
+module_param(use_io, int, 0);
+module_param(debug, int, 0);
+module_param_array(options, int, NULL, 0);
+module_param_array(full_duplex, int, NULL, 0);
+module_param(congenb, int, 0);
+module_param(txfifo, int, 0);
+module_param(rxfifo, int, 0);
+module_param(txdmacount, int, 0);
+module_param(rxdmacount, int, 0);
+module_param(rx_copybreak, int, 0);
+module_param(max_interrupt_work, int, 0);
+module_param(multicast_filter_limit, int, 0);
 MODULE_PARM_DESC(debug, "debug level (0-6)");
 MODULE_PARM_DESC(options, "Bits 0-3: transceiver type, bit 4: full duplex, bit 5: 100Mbps");
 MODULE_PARM_DESC(full_duplex, "full duplex setting(s) (1)");
@@ -289,39 +286,13 @@
 
 */
 
-static int speedo_found1(struct pci_dev *pdev, long ioaddr, int fnd_cnt, int acpi_idle_state);
+static int speedo_found1(struct pci_dev *pdev, void __iomem *ioaddr, int fnd_cnt, int acpi_idle_state);
 
 enum pci_flags_bit {
 	PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4,
 	PCI_ADDR0=0x10<<0, PCI_ADDR1=0x10<<1, PCI_ADDR2=0x10<<2, PCI_ADDR3=0x10<<3,
 };
 
-static inline unsigned int io_inw(unsigned long port)
-{
-	return inw(port);
-}
-static inline void io_outw(unsigned int val, unsigned long port)
-{
-	outw(val, port);
-}
-
-#ifndef USE_IO
-/* Currently alpha headers define in/out macros.
-   Undefine them.  2000/03/30  SAW */
-#undef inb
-#undef inw
-#undef inl
-#undef outb
-#undef outw
-#undef outl
-#define inb readb
-#define inw readw
-#define inl readl
-#define outb writeb
-#define outw writew
-#define outl writel
-#endif
-
 /* Offsets to the various registers.
    All accesses need not be longword aligned. */
 enum speedo_offsets {
@@ -453,6 +424,7 @@
    Unfortunately, all the positions have been shifted since there.
    A new re-alignment is required.  2000/03/06  SAW */
 struct speedo_private {
+    void __iomem *regs;
 	struct TxFD	*tx_ring;		/* Commands (usually CmdTxPacket). */
 	struct RxFD *rx_ringp[RX_RING_SIZE];	/* Rx descriptor, used as ring. */
 	/* The addresses of a Tx/Rx-in-place packets/buffers. */
@@ -520,7 +492,7 @@
 static int eepro100_init_one(struct pci_dev *pdev,
 		const struct pci_device_id *ent);
 
-static int do_eeprom_cmd(long ioaddr, int cmd, int cmd_len);
+static int do_eeprom_cmd(void __iomem *ioaddr, int cmd, int cmd_len);
 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, int value);
 static int speedo_open(struct net_device *dev);
@@ -551,15 +523,16 @@
 
 /* How to wait for the command unit to accept a command.
    Typically this takes 0 ticks. */
-static inline unsigned char wait_for_cmd_done(struct net_device *dev)
+static inline unsigned char wait_for_cmd_done(struct net_device *dev,
+											  	struct speedo_private *sp)
 {
 	int wait = 1000;
-	long cmd_ioaddr = dev->base_addr + SCBCmd;
+	void __iomem *cmd_ioaddr = sp->regs + SCBCmd;
 	unsigned char r;
 
 	do  {
 		udelay(1);
-		r = inb(cmd_ioaddr);
+		r = ioread8(cmd_ioaddr);
 	} while(r && --wait >= 0);
 
 	if (wait < 0)
@@ -570,10 +543,11 @@
 static int __devinit eepro100_init_one (struct pci_dev *pdev,
 		const struct pci_device_id *ent)
 {
-	unsigned long ioaddr;
-	int irq;
+	void __iomem *ioaddr;
+	int irq, pci_bar;
 	int acpi_idle_state = 0, pm;
 	static int cards_found /* = 0 */;
+	unsigned long pci_base;
 
 #ifndef MODULE
 	/* when built-in, we only print version if device is found */
@@ -607,24 +581,17 @@
 	}
 
 	irq = pdev->irq;
-#ifdef USE_IO
-	ioaddr = pci_resource_start(pdev, 1);
+	pci_bar = use_io ? 1 : 0;
+	pci_base = pci_resource_start(pdev, pci_bar);
 	if (DEBUG & NETIF_MSG_PROBE)
-		printk("Found Intel i82557 PCI Speedo at I/O %#lx, IRQ %d.\n",
-			   ioaddr, irq);
-#else
-	ioaddr = (unsigned long)ioremap(pci_resource_start(pdev, 0),
-									pci_resource_len(pdev, 0));
+		printk("Found Intel i82557 PCI Speedo at %#lx, IRQ %d.\n",
+		       pci_base, irq);
+
+	ioaddr = pci_iomap(pdev, pci_bar, 0);
 	if (!ioaddr) {
-		printk (KERN_ERR "eepro100: cannot remap MMIO region %lx @ %lx\n",
-				pci_resource_len(pdev, 0), pci_resource_start(pdev, 0));
+		printk (KERN_ERR "eepro100: cannot remap IO\n");
 		goto err_out_free_mmio_region;
 	}
-	if (DEBUG & NETIF_MSG_PROBE)
-		printk("Found Intel i82557 PCI Speedo, MMIO at %#lx, IRQ %d.\n",
-			   pci_resource_start(pdev, 0), irq);
-#endif
-
 
 	if (speedo_found1(pdev, ioaddr, cards_found, acpi_idle_state) == 0)
 		cards_found++;
@@ -634,9 +601,7 @@
 	return 0;
 
 err_out_iounmap: ;
-#ifndef USE_IO
-	iounmap ((void *)ioaddr);
-#endif
+	pci_iounmap(pdev, ioaddr);
 err_out_free_mmio_region:
 	release_mem_region(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
 err_out_free_pio_region:
@@ -663,7 +628,7 @@
 #endif
 
 static int __devinit speedo_found1(struct pci_dev *pdev,
-		long ioaddr, int card_idx, int acpi_idle_state)
+		void __iomem *ioaddr, int card_idx, int acpi_idle_state)
 {
 	struct net_device *dev;
 	struct speedo_private *sp;
@@ -706,14 +671,16 @@
 	   The size test is for 6 bit vs. 8 bit address serial EEPROMs.
 	*/
 	{
-		unsigned long iobase;
+		void __iomem *iobase;
 		int read_cmd, ee_size;
 		u16 sum;
 		int j;
 
 		/* Use IO only to avoid postponed writes and satisfy EEPROM timing
 		   requirements. */
-		iobase = pci_resource_start(pdev, 1);
+		iobase = pci_iomap(pdev, 1, pci_resource_len(pdev, 1));
+		if (!iobase)
+			goto err_free_unlock;
 		if ((do_eeprom_cmd(iobase, EE_READ_CMD << 24, 27) & 0xffe0000)
 			== 0xffe0000) {
 			ee_size = 0x100;
@@ -739,13 +706,15 @@
 		/* Don't  unregister_netdev(dev);  as the EEPro may actually be
 		   usable, especially if the MAC address is set later.
 		   On the other hand, it may be unusable if MDI data is corrupted. */
+
+		pci_iounmap(pdev, iobase);
 	}
 
 	/* Reset the chip: stop Tx and Rx processes and clear counters.
 	   This takes less than 10usec and will easily finish before the next
 	   action. */
-	outl(PortReset, ioaddr + SCBPort);
-	inl(ioaddr + SCBPort);
+	iowrite32(PortReset, ioaddr + SCBPort);
+	ioread32(ioaddr + SCBPort);
 	udelay(10);
 
 	if (eeprom[3] & 0x0100)
@@ -758,13 +727,12 @@
 	for (i = 0; i < 5; i++)
 		printk("%2.2X:", dev->dev_addr[i]);
 	printk("%2.2X, ", dev->dev_addr[i]);
-#ifdef USE_IO
-	printk("I/O at %#3lx, ", ioaddr);
-#endif
 	printk("IRQ %d.\n", pdev->irq);
 
-	/* we must initialize base_addr early, for mdio_{read,write} */
-	dev->base_addr = ioaddr;
+	sp = netdev_priv(dev);
+
+	/* we must initialize this early, for mdio_{read,write} */
+	sp->regs = ioaddr;
 
 #if 1 || defined(kernel_bloat)
 	/* OK, this is pure kernel bloat.  I don't like it when other drivers
@@ -811,7 +779,7 @@
 		self_test_results = (s32*) ((((long) tx_ring_space) + 15) & ~0xf);
 		self_test_results[0] = 0;
 		self_test_results[1] = -1;
-		outl(tx_ring_dma | PortSelfTest, ioaddr + SCBPort);
+		iowrite32(tx_ring_dma | PortSelfTest, ioaddr + SCBPort);
 		do {
 			udelay(10);
 		} while (self_test_results[1] == -1  &&  --boguscnt >= 0);
@@ -835,8 +803,8 @@
 	}
 #endif  /* kernel_bloat */
 
-	outl(PortReset, ioaddr + SCBPort);
-	inl(ioaddr + SCBPort);
+	iowrite32(PortReset, ioaddr + SCBPort);
+	ioread32(ioaddr + SCBPort);
 	udelay(10);
 
 	/* Return the chip to its original power state. */
@@ -847,7 +815,6 @@
 
 	dev->irq = pdev->irq;
 
-	sp = netdev_priv(dev);
 	sp->pdev = pdev;
 	sp->msg_enable = DEBUG;
 	sp->acpi_pwr = acpi_idle_state;
@@ -910,27 +877,27 @@
 	return -1;
 }
 
-static void do_slow_command(struct net_device *dev, int cmd)
+static void do_slow_command(struct net_device *dev, struct speedo_private *sp, int cmd)
 {
-	long cmd_ioaddr = dev->base_addr + SCBCmd;
+	void __iomem *cmd_ioaddr = sp->regs + SCBCmd;
 	int wait = 0;
 	do
-		if (inb(cmd_ioaddr) == 0) break;
+		if (ioread8(cmd_ioaddr) == 0) break;
 	while(++wait <= 200);
 	if (wait > 100)
 		printk(KERN_ERR "Command %4.4x never accepted (%d polls)!\n",
-		       inb(cmd_ioaddr), wait);
+		       ioread8(cmd_ioaddr), wait);
 
-	outb(cmd, cmd_ioaddr);
+	iowrite8(cmd, cmd_ioaddr);
 
 	for (wait = 0; wait <= 100; wait++)
-		if (inb(cmd_ioaddr) == 0) return;
+		if (ioread8(cmd_ioaddr) == 0) return;
 	for (; wait <= 20000; wait++)
-		if (inb(cmd_ioaddr) == 0) return;
+		if (ioread8(cmd_ioaddr) == 0) return;
 		else udelay(1);
 	printk(KERN_ERR "Command %4.4x was not accepted after %d polls!"
 	       "  Current status %8.8x.\n",
-	       cmd, wait, inl(dev->base_addr + SCBStatus));
+	       cmd, wait, ioread32(sp->regs + SCBStatus));
 }
 
 /* Serial EEPROM section.
@@ -952,35 +919,36 @@
    interval for serial EEPROM.  However, it looks like that there is an
    additional requirement dictating larger udelay's in the code below.
    2000/05/24  SAW */
-static int __devinit do_eeprom_cmd(long ioaddr, int cmd, int cmd_len)
+static int __devinit do_eeprom_cmd(void __iomem *ioaddr, int cmd, int cmd_len)
 {
 	unsigned retval = 0;
-	long ee_addr = ioaddr + SCBeeprom;
+	void __iomem *ee_addr = ioaddr + SCBeeprom;
 
-	io_outw(EE_ENB, ee_addr); udelay(2);
-	io_outw(EE_ENB | EE_SHIFT_CLK, ee_addr); udelay(2);
+	iowrite16(EE_ENB, ee_addr); udelay(2);
+	iowrite16(EE_ENB | EE_SHIFT_CLK, ee_addr); udelay(2);
 
 	/* Shift the command bits out. */
 	do {
 		short dataval = (cmd & (1 << cmd_len)) ? EE_WRITE_1 : EE_WRITE_0;
-		io_outw(dataval, ee_addr); udelay(2);
-		io_outw(dataval | EE_SHIFT_CLK, ee_addr); udelay(2);
-		retval = (retval << 1) | ((io_inw(ee_addr) & EE_DATA_READ) ? 1 : 0);
+		iowrite16(dataval, ee_addr); udelay(2);
+		iowrite16(dataval | EE_SHIFT_CLK, ee_addr); udelay(2);
+		retval = (retval << 1) | ((ioread16(ee_addr) & EE_DATA_READ) ? 1 : 0);
 	} while (--cmd_len >= 0);
-	io_outw(EE_ENB, ee_addr); udelay(2);
+	iowrite16(EE_ENB, ee_addr); udelay(2);
 
 	/* Terminate the EEPROM access. */
-	io_outw(EE_ENB & ~EE_CS, ee_addr);
+	iowrite16(EE_ENB & ~EE_CS, ee_addr);
 	return retval;
 }
 
 static int mdio_read(struct net_device *dev, int phy_id, int location)
 {
-	long ioaddr = dev->base_addr;
+	struct speedo_private *sp = netdev_priv(dev);
+	void __iomem *ioaddr = sp->regs;
 	int val, boguscnt = 64*10;		/* <64 usec. to complete, typ 27 ticks */
-	outl(0x08000000 | (location<<16) | (phy_id<<21), ioaddr + SCBCtrlMDI);
+	iowrite32(0x08000000 | (location<<16) | (phy_id<<21), ioaddr + SCBCtrlMDI);
 	do {
-		val = inl(ioaddr + SCBCtrlMDI);
+		val = ioread32(ioaddr + SCBCtrlMDI);
 		if (--boguscnt < 0) {
 			printk(KERN_ERR " mdio_read() timed out with val = %8.8x.\n", val);
 			break;
@@ -991,12 +959,13 @@
 
 static void mdio_write(struct net_device *dev, int phy_id, int location, int value)
 {
-	long ioaddr = dev->base_addr;
+	struct speedo_private *sp = netdev_priv(dev);
+	void __iomem *ioaddr = sp->regs;
 	int val, boguscnt = 64*10;		/* <64 usec. to complete, typ 27 ticks */
-	outl(0x04000000 | (location<<16) | (phy_id<<21) | value,
+	iowrite32(0x04000000 | (location<<16) | (phy_id<<21) | value,
 		 ioaddr + SCBCtrlMDI);
 	do {
-		val = inl(ioaddr + SCBCtrlMDI);
+		val = ioread32(ioaddr + SCBCtrlMDI);
 		if (--boguscnt < 0) {
 			printk(KERN_ERR" mdio_write() timed out with val = %8.8x.\n", val);
 			break;
@@ -1008,13 +977,13 @@
 speedo_open(struct net_device *dev)
 {
 	struct speedo_private *sp = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = sp->regs;
 	int retval;
 
 	if (netif_msg_ifup(sp))
 		printk(KERN_DEBUG "%s: speedo_open() irq %d.\n", dev->name, dev->irq);
 
-	pci_set_power_state(sp->pdev, 0);
+	pci_set_power_state(sp->pdev, PCI_D0);
 
 	/* Set up the Tx queue early.. */
 	sp->cur_tx = 0;
@@ -1052,7 +1021,7 @@
 	speedo_init_rx_ring(dev);
 
 	/* Fire up the hardware. */
-	outw(SCBMaskAll, ioaddr + SCBCmd);
+	iowrite16(SCBMaskAll, ioaddr + SCBCmd);
 	speedo_resume(dev);
 
 	netdevice_start(dev);
@@ -1071,7 +1040,7 @@
 
 	if (netif_msg_ifup(sp)) {
 		printk(KERN_DEBUG "%s: Done speedo_open(), status %8.8x.\n",
-			   dev->name, inw(ioaddr + SCBStatus));
+			   dev->name, ioread16(ioaddr + SCBStatus));
 	}
 
 	/* Set the timer.  The timer serves a dual purpose:
@@ -1095,46 +1064,46 @@
 static void speedo_resume(struct net_device *dev)
 {
 	struct speedo_private *sp = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = sp->regs;
 
 	/* Start with a Tx threshold of 256 (0x..20.... 8 byte units). */
 	sp->tx_threshold = 0x01208000;
 
 	/* Set the segment registers to '0'. */
-	if (wait_for_cmd_done(dev) != 0) {
-		outl(PortPartialReset, ioaddr + SCBPort);
+	if (wait_for_cmd_done(dev, sp) != 0) {
+		iowrite32(PortPartialReset, ioaddr + SCBPort);
 		udelay(10);
 	}
 
-        outl(0, ioaddr + SCBPointer);
-        inl(ioaddr + SCBPointer);			/* Flush to PCI. */
+        iowrite32(0, ioaddr + SCBPointer);
+        ioread32(ioaddr + SCBPointer);			/* Flush to PCI. */
         udelay(10);			/* Bogus, but it avoids the bug. */
 
         /* Note: these next two operations can take a while. */
-        do_slow_command(dev, RxAddrLoad);
-        do_slow_command(dev, CUCmdBase);
+        do_slow_command(dev, sp, RxAddrLoad);
+        do_slow_command(dev, sp, CUCmdBase);
 
 	/* Load the statistics block and rx ring addresses. */
-	outl(sp->lstats_dma, ioaddr + SCBPointer);
-	inl(ioaddr + SCBPointer);			/* Flush to PCI */
+	iowrite32(sp->lstats_dma, ioaddr + SCBPointer);
+	ioread32(ioaddr + SCBPointer);			/* Flush to PCI */
 
-	outb(CUStatsAddr, ioaddr + SCBCmd);
+	iowrite8(CUStatsAddr, ioaddr + SCBCmd);
 	sp->lstats->done_marker = 0;
-	wait_for_cmd_done(dev);
+	wait_for_cmd_done(dev, sp);
 
 	if (sp->rx_ringp[sp->cur_rx % RX_RING_SIZE] == NULL) {
 		if (netif_msg_rx_err(sp))
 			printk(KERN_DEBUG "%s: NULL cur_rx in speedo_resume().\n",
 					dev->name);
 	} else {
-		outl(sp->rx_ring_dma[sp->cur_rx % RX_RING_SIZE],
+		iowrite32(sp->rx_ring_dma[sp->cur_rx % RX_RING_SIZE],
 			 ioaddr + SCBPointer);
-		inl(ioaddr + SCBPointer);		/* Flush to PCI */
+		ioread32(ioaddr + SCBPointer);		/* Flush to PCI */
 	}
 
 	/* Note: RxStart should complete instantly. */
-	do_slow_command(dev, RxStart);
-	do_slow_command(dev, CUDumpStats);
+	do_slow_command(dev, sp, RxStart);
+	do_slow_command(dev, sp, CUDumpStats);
 
 	/* Fill the first command with our physical address. */
 	{
@@ -1153,11 +1122,11 @@
 	}
 
 	/* Start the chip's Tx process and unmask interrupts. */
-	outl(TX_RING_ELEM_DMA(sp, sp->dirty_tx % TX_RING_SIZE),
+	iowrite32(TX_RING_ELEM_DMA(sp, sp->dirty_tx % TX_RING_SIZE),
 		 ioaddr + SCBPointer);
 	/* We are not ACK-ing FCP and ER in the interrupt handler yet so they should
 	   remain masked --Dragan */
-	outw(CUStart | SCBMaskEarlyRx | SCBMaskFlowCtl, ioaddr + SCBCmd);
+	iowrite16(CUStart | SCBMaskEarlyRx | SCBMaskFlowCtl, ioaddr + SCBCmd);
 }
 
 /*
@@ -1176,29 +1145,29 @@
 {
 	struct speedo_private *sp = netdev_priv(dev);
 	struct RxFD *rfd;
-	long ioaddr;
+	void __iomem *ioaddr;
 
-	ioaddr = dev->base_addr;
-	if (wait_for_cmd_done(dev) != 0) {
+	ioaddr = sp->regs;
+	if (wait_for_cmd_done(dev, sp) != 0) {
 		printk("%s: previous command stalled\n", dev->name);
 		return;
 	}
 	/*
 	* Put the hardware into a known state.
 	*/
-	outb(RxAbort, ioaddr + SCBCmd);
+	iowrite8(RxAbort, ioaddr + SCBCmd);
 
 	rfd = sp->rx_ringp[sp->cur_rx % RX_RING_SIZE];
 
 	rfd->rx_buf_addr = 0xffffffff;
 
-	if (wait_for_cmd_done(dev) != 0) {
+	if (wait_for_cmd_done(dev, sp) != 0) {
 		printk("%s: RxAbort command stalled\n", dev->name);
 		return;
 	}
-	outl(sp->rx_ring_dma[sp->cur_rx % RX_RING_SIZE],
+	iowrite32(sp->rx_ring_dma[sp->cur_rx % RX_RING_SIZE],
 		ioaddr + SCBPointer);
-	outb(RxStart, ioaddr + SCBCmd);
+	iowrite8(RxStart, ioaddr + SCBCmd);
 }
 
 
@@ -1207,7 +1176,7 @@
 {
 	struct net_device *dev = (struct net_device *)data;
 	struct speedo_private *sp = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = sp->regs;
 	int phy_num = sp->phy[0] & 0x1f;
 
 	/* We have MII and lost link beat. */
@@ -1230,7 +1199,7 @@
 	mii_check_link(&sp->mii_if);
 	if (netif_msg_timer(sp)) {
 		printk(KERN_DEBUG "%s: Media control tick, status %4.4x.\n",
-			   dev->name, inw(ioaddr + SCBStatus));
+			   dev->name, ioread16(ioaddr + SCBStatus));
 	}
 	if (sp->rx_mode < 0  ||
 		(sp->rx_bug  && jiffies - sp->last_rx_time > 2*HZ)) {
@@ -1277,7 +1246,7 @@
 
 #if 0
 	{
-		long ioaddr = dev->base_addr;
+		void __iomem *ioaddr = sp->regs;
 		int phy_num = sp->phy[0] & 0x1f;
 		for (i = 0; i < 16; i++) {
 			/* FIXME: what does it mean?  --SAW */
@@ -1398,14 +1367,14 @@
 static void speedo_tx_timeout(struct net_device *dev)
 {
 	struct speedo_private *sp = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
-	int status = inw(ioaddr + SCBStatus);
+	void __iomem *ioaddr = sp->regs;
+	int status = ioread16(ioaddr + SCBStatus);
 	unsigned long flags;
 
 	if (netif_msg_tx_err(sp)) {
 		printk(KERN_WARNING "%s: Transmit timed out: status %4.4x "
 		   " %4.4x at %d/%d command %8.8x.\n",
-		   dev->name, status, inw(ioaddr + SCBCmd),
+		   dev->name, status, ioread16(ioaddr + SCBCmd),
 		   sp->dirty_tx, sp->cur_tx,
 		   sp->tx_ring[sp->dirty_tx % TX_RING_SIZE].status);
 
@@ -1417,9 +1386,9 @@
 		/* Only the command unit has stopped. */
 		printk(KERN_WARNING "%s: Trying to restart the transmitter...\n",
 			   dev->name);
-		outl(TX_RING_ELEM_DMA(sp, dirty_tx % TX_RING_SIZE]),
+		iowrite32(TX_RING_ELEM_DMA(sp, dirty_tx % TX_RING_SIZE]),
 			 ioaddr + SCBPointer);
-		outw(CUStart, ioaddr + SCBCmd);
+		iowrite16(CUStart, ioaddr + SCBCmd);
 		reset_mii(dev);
 	} else {
 #else
@@ -1427,12 +1396,12 @@
 #endif
 		del_timer_sync(&sp->timer);
 		/* Reset the Tx and Rx units. */
-		outl(PortReset, ioaddr + SCBPort);
+		iowrite32(PortReset, ioaddr + SCBPort);
 		/* We may get spurious interrupts here.  But I don't think that they
 		   may do much harm.  1999/12/09 SAW */
 		udelay(10);
 		/* Disable interrupts. */
-		outw(SCBMaskAll, ioaddr + SCBCmd);
+		iowrite16(SCBMaskAll, ioaddr + SCBCmd);
 		synchronize_irq(dev->irq);
 		speedo_tx_buffer_gc(dev);
 		/* Free as much as possible.
@@ -1460,7 +1429,7 @@
 speedo_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct speedo_private *sp = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = sp->regs;
 	int entry;
 
 	/* Prevent interrupts from changing the Tx ring from underneath us. */
@@ -1499,18 +1468,18 @@
 	/* workaround for hardware bug on 10 mbit half duplex */
 
 	if ((sp->partner == 0) && (sp->chip_id == 1)) {
-		wait_for_cmd_done(dev);
-		outb(0 , ioaddr + SCBCmd);
+		wait_for_cmd_done(dev, sp);
+		iowrite8(0 , ioaddr + SCBCmd);
 		udelay(1);
 	}
 
 	/* Trigger the command unit resume. */
-	wait_for_cmd_done(dev);
+	wait_for_cmd_done(dev, sp);
 	clear_suspend(sp->last_cmd);
 	/* We want the time window between clearing suspend flag on the previous
 	   command and resuming CU to be as small as possible.
 	   Interrupts in between are very undesired.  --SAW */
-	outb(CUResume, ioaddr + SCBCmd);
+	iowrite8(CUResume, ioaddr + SCBCmd);
 	sp->last_cmd = (struct descriptor *)&sp->tx_ring[entry];
 
 	/* Leave room for set_rx_mode(). If there is no more space than reserved
@@ -1592,12 +1561,13 @@
 {
 	struct net_device *dev = (struct net_device *)dev_instance;
 	struct speedo_private *sp;
-	long ioaddr, boguscnt = max_interrupt_work;
+	void __iomem *ioaddr;
+	long boguscnt = max_interrupt_work;
 	unsigned short status;
 	unsigned int handled = 0;
 
-	ioaddr = dev->base_addr;
 	sp = netdev_priv(dev);
+	ioaddr = sp->regs;
 
 #ifndef final_version
 	/* A lock to prevent simultaneous entry on SMP machines. */
@@ -1610,11 +1580,11 @@
 #endif
 
 	do {
-		status = inw(ioaddr + SCBStatus);
+		status = ioread16(ioaddr + SCBStatus);
 		/* Acknowledge all of the current interrupt sources ASAP. */
 		/* Will change from 0xfc00 to 0xff00 when we start handling
 		   FCP and ER interrupts --Dragan */
-		outw(status & 0xfc00, ioaddr + SCBStatus);
+		iowrite16(status & 0xfc00, ioaddr + SCBStatus);
 
 		if (netif_msg_intr(sp))
 			printk(KERN_DEBUG "%s: interrupt  status=%#4.4x.\n",
@@ -1674,14 +1644,14 @@
 			/* Clear all interrupt sources. */
 			/* Will change from 0xfc00 to 0xff00 when we start handling
 			   FCP and ER interrupts --Dragan */
-			outw(0xfc00, ioaddr + SCBStatus);
+			iowrite16(0xfc00, ioaddr + SCBStatus);
 			break;
 		}
 	} while (1);
 
 	if (netif_msg_intr(sp))
 		printk(KERN_DEBUG "%s: exiting interrupt, status=%#4.4x.\n",
-			   dev->name, inw(ioaddr + SCBStatus));
+			   dev->name, ioread16(ioaddr + SCBStatus));
 
 	clear_bit(0, (void*)&sp->in_interrupt);
 	return IRQ_RETVAL(handled);
@@ -1900,8 +1870,8 @@
 static int
 speedo_close(struct net_device *dev)
 {
-	long ioaddr = dev->base_addr;
 	struct speedo_private *sp = netdev_priv(dev);
+	void __iomem *ioaddr = sp->regs;
 	int i;
 
 	netdevice_stop(dev);
@@ -1909,16 +1879,16 @@
 
 	if (netif_msg_ifdown(sp))
 		printk(KERN_DEBUG "%s: Shutting down ethercard, status was %4.4x.\n",
-			   dev->name, inw(ioaddr + SCBStatus));
+			   dev->name, ioread16(ioaddr + SCBStatus));
 
 	/* Shut off the media monitoring timer. */
 	del_timer_sync(&sp->timer);
 
-	outw(SCBMaskAll, ioaddr + SCBCmd);
+	iowrite16(SCBMaskAll, ioaddr + SCBCmd);
 
 	/* Shutting down the chip nicely fails to disable flow control. So.. */
-	outl(PortPartialReset, ioaddr + SCBPort);
-	inl(ioaddr + SCBPort); /* flush posted write */
+	iowrite32(PortPartialReset, ioaddr + SCBPort);
+	ioread32(ioaddr + SCBPort); /* flush posted write */
 	/*
 	 * The chip requires a 10 microsecond quiet period.  Wait here!
 	 */
@@ -1963,7 +1933,7 @@
 	if (netif_msg_ifdown(sp))
 		printk(KERN_DEBUG "%s: %d multicast blocks dropped.\n", dev->name, i);
 
-	pci_set_power_state(sp->pdev, 2);
+	pci_set_power_state(sp->pdev, PCI_D2);
 
 	return 0;
 }
@@ -1980,7 +1950,7 @@
 speedo_get_stats(struct net_device *dev)
 {
 	struct speedo_private *sp = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = sp->regs;
 
 	/* Update only if the previous dump finished. */
 	if (sp->lstats->done_marker == le32_to_cpu(0xA007)) {
@@ -2001,8 +1971,8 @@
 			/* Take a spinlock to make wait_for_cmd_done and sending the
 			   command atomic.  --SAW */
 			spin_lock_irqsave(&sp->lock, flags);
-			wait_for_cmd_done(dev);
-			outb(CUDumpStats, ioaddr + SCBCmd);
+			wait_for_cmd_done(dev, sp);
+			iowrite8(CUDumpStats, ioaddr + SCBCmd);
 			spin_unlock_irqrestore(&sp->lock, flags);
 		}
 	}
@@ -2088,7 +2058,7 @@
 		   access from the timeout handler.
 		   They are currently serialized only with MDIO access from the
 		   timer routine.  2000/05/09 SAW */
-		saved_acpi = pci_set_power_state(sp->pdev, 0);
+		saved_acpi = pci_set_power_state(sp->pdev, PCI_D0);
 		t = del_timer_sync(&sp->timer);
 		data->val_out = mdio_read(dev, data->phy_id & 0x1f, data->reg_num & 0x1f);
 		if (t)
@@ -2099,7 +2069,7 @@
 	case SIOCSMIIREG:		/* Write MII PHY register. */
 		if (!capable(CAP_NET_ADMIN))
 			return -EPERM;
-		saved_acpi = pci_set_power_state(sp->pdev, 0);
+		saved_acpi = pci_set_power_state(sp->pdev, PCI_D0);
 		t = del_timer_sync(&sp->timer);
 		mdio_write(dev, data->phy_id, data->reg_num, data->val_in);
 		if (t)
@@ -2123,7 +2093,7 @@
 static void set_rx_mode(struct net_device *dev)
 {
 	struct speedo_private *sp = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = sp->regs;
 	struct descriptor *last_cmd;
 	char new_rx_mode;
 	unsigned long flags;
@@ -2178,9 +2148,9 @@
 			config_cmd_data[8] = 0;
 		}
 		/* Trigger the command unit resume. */
-		wait_for_cmd_done(dev);
+		wait_for_cmd_done(dev, sp);
 		clear_suspend(last_cmd);
-		outb(CUResume, ioaddr + SCBCmd);
+		iowrite8(CUResume, ioaddr + SCBCmd);
 		if ((int)(sp->cur_tx - sp->dirty_tx) >= TX_QUEUE_LIMIT) {
 			netif_stop_queue(dev);
 			sp->tx_full = 1;
@@ -2215,10 +2185,10 @@
 			*setup_params++ = *eaddrs++;
 		}
 
-		wait_for_cmd_done(dev);
+		wait_for_cmd_done(dev, sp);
 		clear_suspend(last_cmd);
 		/* Immediately trigger the command unit resume. */
-		outb(CUResume, ioaddr + SCBCmd);
+		iowrite8(CUResume, ioaddr + SCBCmd);
 
 		if ((int)(sp->cur_tx - sp->dirty_tx) >= TX_QUEUE_LIMIT) {
 			netif_stop_queue(dev);
@@ -2291,10 +2261,10 @@
 		pci_dma_sync_single_for_device(sp->pdev, mc_blk->frame_dma,
 									   mc_blk->len, PCI_DMA_TODEVICE);
 
-		wait_for_cmd_done(dev);
+		wait_for_cmd_done(dev, sp);
 		clear_suspend(last_cmd);
 		/* Immediately trigger the command unit resume. */
-		outb(CUResume, ioaddr + SCBCmd);
+		iowrite8(CUResume, ioaddr + SCBCmd);
 
 		if ((int)(sp->cur_tx - sp->dirty_tx) >= TX_QUEUE_LIMIT) {
 			netif_stop_queue(dev);
@@ -2315,7 +2285,7 @@
 {
 	struct net_device *dev = pci_get_drvdata (pdev);
 	struct speedo_private *sp = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = sp->regs;
 
 	pci_save_state(pdev);
 
@@ -2325,7 +2295,7 @@
 	del_timer_sync(&sp->timer);
 
 	netif_device_detach(dev);
-	outl(PortPartialReset, ioaddr + SCBPort);
+	iowrite32(PortPartialReset, ioaddr + SCBPort);
 	
 	/* XXX call pci_set_power_state ()? */
 	pci_disable_device(pdev);
@@ -2337,7 +2307,7 @@
 {
 	struct net_device *dev = pci_get_drvdata (pdev);
 	struct speedo_private *sp = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = sp->regs;
 
 	pci_set_power_state(pdev, 0);
 	pci_restore_state(pdev);
@@ -2354,7 +2324,7 @@
 		  reinitialization;
 		- serialization with other driver calls.
 	   2000/03/08  SAW */
-	outw(SCBMaskAll, ioaddr + SCBCmd);
+	iowrite16(SCBMaskAll, ioaddr + SCBCmd);
 	speedo_resume(dev);
 	netif_device_attach(dev);
 	sp->rx_mode = -1;
@@ -2376,10 +2346,7 @@
 	release_region(pci_resource_start(pdev, 1), pci_resource_len(pdev, 1));
 	release_mem_region(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
 
-#ifndef USE_IO
-	iounmap((char *)dev->base_addr);
-#endif
-
+	pci_iounmap(pdev, sp->regs);
 	pci_free_consistent(pdev, TX_RING_SIZE * sizeof(struct TxFD)
 								+ sizeof(struct speedo_stats),
 						sp->tx_ring, sp->tx_ring_dma);
diff -Nru a/drivers/net/eexpress.c b/drivers/net/eexpress.c
--- a/drivers/net/eexpress.c	2005-03-01 23:38:44 -08:00
+++ b/drivers/net/eexpress.c	2005-03-01 23:38:44 -08:00
@@ -1691,8 +1691,8 @@
 static int irq[EEXP_MAX_CARDS];
 static int io[EEXP_MAX_CARDS];
 
-MODULE_PARM(io, "1-" __MODULE_STRING(EEXP_MAX_CARDS) "i");
-MODULE_PARM(irq, "1-" __MODULE_STRING(EEXP_MAX_CARDS) "i");
+module_param_array(io, int, NULL, 0);
+module_param_array(irq, int, NULL, 0);
 MODULE_PARM_DESC(io, "EtherExpress 16 I/O base address(es)");
 MODULE_PARM_DESC(irq, "EtherExpress 16 IRQ number(s)");
 MODULE_LICENSE("GPL");
diff -Nru a/drivers/net/epic100.c b/drivers/net/epic100.c
--- a/drivers/net/epic100.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/net/epic100.c	2005-03-01 23:38:56 -08:00
@@ -149,10 +149,10 @@
 MODULE_DESCRIPTION("SMC 83c170 EPIC series Ethernet driver");
 MODULE_LICENSE("GPL");
 
-MODULE_PARM(debug, "i");
-MODULE_PARM(rx_copybreak, "i");
-MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i");
-MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
+module_param(debug, int, 0);
+module_param(rx_copybreak, int, 0);
+module_param_array(options, int, NULL, 0);
+module_param_array(full_duplex, int, NULL, 0);
 MODULE_PARM_DESC(debug, "EPIC/100 debug level (0-5)");
 MODULE_PARM_DESC(options, "EPIC/100: Bits 0-3: media type, bit 4: full duplex");
 MODULE_PARM_DESC(rx_copybreak, "EPIC/100 copy breakpoint for copy-only-tiny-frames");
diff -Nru a/drivers/net/es3210.c b/drivers/net/es3210.c
--- a/drivers/net/es3210.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/net/es3210.c	2005-03-01 23:39:09 -08:00
@@ -414,9 +414,9 @@
 static int irq[MAX_ES_CARDS];
 static int mem[MAX_ES_CARDS];
 
-MODULE_PARM(io, "1-" __MODULE_STRING(MAX_ES_CARDS) "i");
-MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_ES_CARDS) "i");
-MODULE_PARM(mem, "1-" __MODULE_STRING(MAX_ES_CARDS) "i");
+module_param_array(io, int, NULL, 0);
+module_param_array(irq, int, NULL, 0);
+module_param_array(mem, int, NULL, 0);
 MODULE_PARM_DESC(io, "I/O base address(es)");
 MODULE_PARM_DESC(irq, "IRQ number(s)");
 MODULE_PARM_DESC(mem, "memory base address(es)");
diff -Nru a/drivers/net/eth16i.c b/drivers/net/eth16i.c
--- a/drivers/net/eth16i.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/net/eth16i.c	2005-03-01 23:39:09 -08:00
@@ -1420,18 +1420,18 @@
 MODULE_LICENSE("GPL");
 
 
-MODULE_PARM(io, "1-" __MODULE_STRING(MAX_ETH16I_CARDS) "i");
+module_param_array(io, int, NULL, 0);
 MODULE_PARM_DESC(io, "eth16i I/O base address(es)");
 
 #if 0
-MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_ETH16I_CARDS) "i");
+module_param_array(irq, int, NULL, 0);
 MODULE_PARM_DESC(irq, "eth16i interrupt request number");
 #endif
 
-MODULE_PARM(mediatype, "1-" __MODULE_STRING(MAX_ETH16I_CARDS) "s");
+module_param_array(mediatype, charp, NULL, 0);
 MODULE_PARM_DESC(mediatype, "eth16i media type of interface(s) (bnc,tp,dix,auto,eprom)");
 
-MODULE_PARM(debug, "i");
+module_param(debug, int, 0);
 MODULE_PARM_DESC(debug, "eth16i debug level (0-6)");
 
 int init_module(void)
diff -Nru a/drivers/net/ewrk3.c b/drivers/net/ewrk3.c
--- a/drivers/net/ewrk3.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/net/ewrk3.c	2005-03-01 23:39:17 -08:00
@@ -202,7 +202,6 @@
 #define EWRK3_IOP_INC 0x20	/* I/O address increment */
 #define EWRK3_TOTAL_SIZE 0x20	/* required I/O address length */
 
-/* If you change this, remember to also change MODULE_PARM array limits */
 #ifndef MAX_NUM_EWRK3S
 #define MAX_NUM_EWRK3S 21
 #endif
@@ -1945,8 +1944,8 @@
 static int io[MAX_NUM_EWRK3S+1] = { 0x300, 0, };
 
 /* '21' below should really be 'MAX_NUM_EWRK3S' */
-MODULE_PARM(io, "0-21i");
-MODULE_PARM(irq, "0-21i");
+module_param_array(io, int, NULL, 0);
+module_param_array(irq, int, NULL, 0);
 MODULE_PARM_DESC(io, "EtherWORKS 3 I/O base address(es)");
 MODULE_PARM_DESC(irq, "EtherWORKS 3 IRQ number(s)");
 
diff -Nru a/drivers/net/fc/iph5526_ip.h b/drivers/net/fc/iph5526_ip.h
--- a/drivers/net/fc/iph5526_ip.h	2005-03-01 23:39:18 -08:00
+++ b/drivers/net/fc/iph5526_ip.h	2005-03-01 23:39:18 -08:00
@@ -18,7 +18,6 @@
 
 static void rx_net_packet(struct fc_info *fi, u_char *buff_addr, int payload_size);
 static void rx_net_mfs_packet(struct fc_info *fi, struct sk_buff *skb);
-unsigned short fc_type_trans(struct sk_buff *skb, struct net_device *dev); 
 static int tx_ip_packet(struct sk_buff *skb, unsigned long len, struct fc_info *fi);
 static int tx_arp_packet(char *data, unsigned long len, struct fc_info *fi);
 #endif
diff -Nru a/drivers/net/fealnx.c b/drivers/net/fealnx.c
--- a/drivers/net/fealnx.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/net/fealnx.c	2005-03-01 23:39:08 -08:00
@@ -125,13 +125,13 @@
 MODULE_AUTHOR("Myson or whoever");
 MODULE_DESCRIPTION("Myson MTD-8xx 100/10M Ethernet PCI Adapter Driver");
 MODULE_LICENSE("GPL");
-MODULE_PARM(max_interrupt_work, "i");
+module_param(max_interrupt_work, int, 0);
 //MODULE_PARM(min_pci_latency, "i");
-MODULE_PARM(debug, "i");
-MODULE_PARM(rx_copybreak, "i");
-MODULE_PARM(multicast_filter_limit, "i");
-MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i");
-MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
+module_param(debug, int, 0);
+module_param(rx_copybreak, int, 0);
+module_param(multicast_filter_limit, int, 0);
+module_param_array(options, int, NULL, 0);
+module_param_array(full_duplex, int, NULL, 0);
 MODULE_PARM_DESC(max_interrupt_work, "fealnx maximum events handled per interrupt");
 MODULE_PARM_DESC(debug, "fealnx enable debugging (0-1)");
 MODULE_PARM_DESC(rx_copybreak, "fealnx copy breakpoint for copy-only-tiny-frames");
diff -Nru a/drivers/net/fec_8xx/fec_mii.c b/drivers/net/fec_8xx/fec_mii.c
--- a/drivers/net/fec_8xx/fec_mii.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/net/fec_8xx/fec_mii.c	2005-03-01 23:38:58 -08:00
@@ -54,7 +54,7 @@
 /*************************************************/
 
 /* XXX both FECs use the MII interface of FEC1 */
-static spinlock_t fec_mii_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(fec_mii_lock);
 
 #define FEC_MII_LOOPS	10000
 
diff -Nru a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
--- a/drivers/net/forcedeth.c	2005-03-01 23:38:51 -08:00
+++ b/drivers/net/forcedeth.c	2005-03-01 23:38:51 -08:00
@@ -79,6 +79,8 @@
  *	0.30: 25 Sep 2004: rx checksum support for nf 250 Gb. Add rx reset
  *			   into nv_close, otherwise reenabling for wol can
  *			   cause DMA to kfree'd memory.
+ *	0.31: 14 Nov 2004: ethtool support for getting/setting link
+ *	                   capabilities.
  *
  * Known bugs:
  * We suspect that on some hardware no TX done interrupts are generated.
@@ -90,7 +92,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.30"
+#define FORCEDETH_VERSION		"0.31"
 #define DRV_NAME			"forcedeth"
 
 #include <linux/module.h>
@@ -210,6 +212,7 @@
 #define NVREG_LINKSPEED_10	1000
 #define NVREG_LINKSPEED_100	100
 #define NVREG_LINKSPEED_1000	50
+#define NVREG_LINKSPEED_MASK	(0xFFF)
 	NvRegUnknownSetupReg5 = 0x130,
 #define NVREG_UNKSETUP5_BIT31	(1<<31)
 	NvRegUnknownSetupReg3 = 0x13c,
@@ -441,6 +444,8 @@
 	int in_shutdown;
 	u32 linkspeed;
 	int duplex;
+	int autoneg;
+	int fixed_mode;
 	int phyaddr;
 	int wolenabled;
 	unsigned int phy_oui;
@@ -765,50 +770,6 @@
 	return &np->stats;
 }
 
-static void nv_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
-{
-	struct fe_priv *np = get_nvpriv(dev);
-	strcpy(info->driver, "forcedeth");
-	strcpy(info->version, FORCEDETH_VERSION);
-	strcpy(info->bus_info, pci_name(np->pci_dev));
-}
-
-static void nv_get_wol(struct net_device *dev, struct ethtool_wolinfo *wolinfo)
-{
-	struct fe_priv *np = get_nvpriv(dev);
-	wolinfo->supported = WAKE_MAGIC;
-
-	spin_lock_irq(&np->lock);
-	if (np->wolenabled)
-		wolinfo->wolopts = WAKE_MAGIC;
-	spin_unlock_irq(&np->lock);
-}
-
-static int nv_set_wol(struct net_device *dev, struct ethtool_wolinfo *wolinfo)
-{
-	struct fe_priv *np = get_nvpriv(dev);
-	u8 __iomem *base = get_hwbase(dev);
-
-	spin_lock_irq(&np->lock);
-	if (wolinfo->wolopts == 0) {
-		writel(0, base + NvRegWakeUpFlags);
-		np->wolenabled = 0;
-	}
-	if (wolinfo->wolopts & WAKE_MAGIC) {
-		writel(NVREG_WAKEUPFLAGS_ENABLE, base + NvRegWakeUpFlags);
-		np->wolenabled = 1;
-	}
-	spin_unlock_irq(&np->lock);
-	return 0;
-}
-
-static struct ethtool_ops ops = {
-	.get_drvinfo = nv_get_drvinfo,
-	.get_link = ethtool_op_get_link,
-	.get_wol = nv_get_wol,
-	.set_wol = nv_set_wol,
-};
-
 /*
  * nv_alloc_rx: fill rx ring entries.
  * Return 1 if the allocations for the skbs failed and the
@@ -1286,6 +1247,25 @@
 		goto set_speed;
 	}
 
+	if (np->autoneg == 0) {
+		dprintk(KERN_DEBUG "%s: nv_update_linkspeed: autoneg off, PHY set to 0x%04x.\n",
+				dev->name, np->fixed_mode);
+		if (np->fixed_mode & LPA_100FULL) {
+			newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_100;
+			newdup = 1;
+		} else if (np->fixed_mode & LPA_100HALF) {
+			newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_100;
+			newdup = 0;
+		} else if (np->fixed_mode & LPA_10FULL) {
+			newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_10;
+			newdup = 1;
+		} else {
+			newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_10;
+			newdup = 0;
+		}
+		retval = 1;
+		goto set_speed;
+	}
 	/* check auto negotiation is complete */
 	if (!(mii_status & BMSR_ANEGCOMPLETE)) {
 		/* still in autonegotiation - configure nic for 10 MBit HD and wait. */
@@ -1303,7 +1283,7 @@
 
 		if ((control_1000 & ADVERTISE_1000FULL) &&
 			(status_1000 & LPA_1000FULL)) {
-		dprintk(KERN_DEBUG "%s: nv_update_linkspeed: GBit ethernet detected.\n",
+			dprintk(KERN_DEBUG "%s: nv_update_linkspeed: GBit ethernet detected.\n",
 				dev->name);
 			newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_1000;
 			newdup = 1;
@@ -1362,9 +1342,9 @@
 	phyreg &= ~(PHY_HALF|PHY_100|PHY_1000);
 	if (np->duplex == 0)
 		phyreg |= PHY_HALF;
-	if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_100)
+	if ((np->linkspeed & NVREG_LINKSPEED_MASK) == NVREG_LINKSPEED_100)
 		phyreg |= PHY_100;
-	else if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_1000)
+	else if ((np->linkspeed & NVREG_LINKSPEED_MASK) == NVREG_LINKSPEED_1000)
 		phyreg |= PHY_1000;
 	writel(phyreg, base + NvRegPhyInterface);
 
@@ -1500,6 +1480,227 @@
 	enable_irq(dev->irq);
 }
 
+static void nv_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
+{
+	struct fe_priv *np = get_nvpriv(dev);
+	strcpy(info->driver, "forcedeth");
+	strcpy(info->version, FORCEDETH_VERSION);
+	strcpy(info->bus_info, pci_name(np->pci_dev));
+}
+
+static void nv_get_wol(struct net_device *dev, struct ethtool_wolinfo *wolinfo)
+{
+	struct fe_priv *np = get_nvpriv(dev);
+	wolinfo->supported = WAKE_MAGIC;
+
+	spin_lock_irq(&np->lock);
+	if (np->wolenabled)
+		wolinfo->wolopts = WAKE_MAGIC;
+	spin_unlock_irq(&np->lock);
+}
+
+static int nv_set_wol(struct net_device *dev, struct ethtool_wolinfo *wolinfo)
+{
+	struct fe_priv *np = get_nvpriv(dev);
+	u8 __iomem *base = get_hwbase(dev);
+
+	spin_lock_irq(&np->lock);
+	if (wolinfo->wolopts == 0) {
+		writel(0, base + NvRegWakeUpFlags);
+		np->wolenabled = 0;
+	}
+	if (wolinfo->wolopts & WAKE_MAGIC) {
+		writel(NVREG_WAKEUPFLAGS_ENABLE, base + NvRegWakeUpFlags);
+		np->wolenabled = 1;
+	}
+	spin_unlock_irq(&np->lock);
+	return 0;
+}
+
+static int nv_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
+{
+	struct fe_priv *np = netdev_priv(dev);
+	int adv;
+
+	spin_lock_irq(&np->lock);
+	ecmd->port = PORT_MII;
+	if (!netif_running(dev)) {
+		/* We do not track link speed / duplex setting if the
+		 * interface is disabled. Force a link check */
+		nv_update_linkspeed(dev);
+	}
+	switch(np->linkspeed & (NVREG_LINKSPEED_MASK)) {
+		case NVREG_LINKSPEED_10:
+			ecmd->speed = SPEED_10;
+			break;
+		case NVREG_LINKSPEED_100:
+			ecmd->speed = SPEED_100;
+			break;
+		case NVREG_LINKSPEED_1000:
+			ecmd->speed = SPEED_1000;
+			break;
+	}
+	ecmd->duplex = DUPLEX_HALF;
+	if (np->duplex)
+		ecmd->duplex = DUPLEX_FULL;
+
+	ecmd->autoneg = np->autoneg;
+
+	ecmd->advertising = ADVERTISED_MII;
+	if (np->autoneg) {
+		ecmd->advertising |= ADVERTISED_Autoneg;
+		adv = mii_rw(dev, np->phyaddr, MII_ADVERTISE, MII_READ);
+	} else {
+		adv = np->fixed_mode;
+	}
+	if (adv & ADVERTISE_10HALF)
+		ecmd->advertising |= ADVERTISED_10baseT_Half;
+	if (adv & ADVERTISE_10FULL)
+		ecmd->advertising |= ADVERTISED_10baseT_Full;
+	if (adv & ADVERTISE_100HALF)
+		ecmd->advertising |= ADVERTISED_100baseT_Half;
+	if (adv & ADVERTISE_100FULL)
+		ecmd->advertising |= ADVERTISED_100baseT_Full;
+	if (np->autoneg && np->gigabit == PHY_GIGABIT) {
+		adv = mii_rw(dev, np->phyaddr, MII_1000BT_CR, MII_READ);
+		if (adv & ADVERTISE_1000FULL)
+			ecmd->advertising |= ADVERTISED_1000baseT_Full;
+	}
+
+	ecmd->supported = (SUPPORTED_Autoneg |
+		SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |
+		SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full |
+		SUPPORTED_MII);
+	if (np->gigabit == PHY_GIGABIT)
+		ecmd->supported |= SUPPORTED_1000baseT_Full;
+
+	ecmd->phy_address = np->phyaddr;
+	ecmd->transceiver = XCVR_EXTERNAL;
+
+	/* ignore maxtxpkt, maxrxpkt for now */
+	spin_unlock_irq(&np->lock);
+	return 0;
+}
+
+static int nv_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
+{
+	struct fe_priv *np = netdev_priv(dev);
+
+	if (ecmd->port != PORT_MII)
+		return -EINVAL;
+	if (ecmd->transceiver != XCVR_EXTERNAL)
+		return -EINVAL;
+	if (ecmd->phy_address != np->phyaddr) {
+		/* TODO: support switching between multiple phys. Should be
+		 * trivial, but not enabled due to lack of test hardware. */
+		return -EINVAL;
+	}
+	if (ecmd->autoneg == AUTONEG_ENABLE) {
+		u32 mask;
+
+		mask = ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full |
+			  ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full;
+		if (np->gigabit == PHY_GIGABIT)
+			mask |= ADVERTISED_1000baseT_Full;
+
+		if ((ecmd->advertising & mask) == 0)
+			return -EINVAL;
+
+	} else if (ecmd->autoneg == AUTONEG_DISABLE) {
+		/* Note: autonegotiation disable, speed 1000 intentionally
+		 * forbidden - noone should need that. */
+
+		if (ecmd->speed != SPEED_10 && ecmd->speed != SPEED_100)
+			return -EINVAL;
+		if (ecmd->duplex != DUPLEX_HALF && ecmd->duplex != DUPLEX_FULL)
+			return -EINVAL;
+	} else {
+		return -EINVAL;
+	}
+
+	spin_lock_irq(&np->lock);
+	if (ecmd->autoneg == AUTONEG_ENABLE) {
+		int adv, bmcr;
+
+		np->autoneg = 1;
+
+		/* advertise only what has been requested */
+		adv = mii_rw(dev, np->phyaddr, MII_ADVERTISE, MII_READ);
+		adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4);
+		if (ecmd->advertising & ADVERTISED_10baseT_Half)
+			adv |= ADVERTISE_10HALF;
+		if (ecmd->advertising & ADVERTISED_10baseT_Full)
+			adv |= ADVERTISE_10FULL;
+		if (ecmd->advertising & ADVERTISED_100baseT_Half)
+			adv |= ADVERTISE_100HALF;
+		if (ecmd->advertising & ADVERTISED_100baseT_Full)
+			adv |= ADVERTISE_100FULL;
+		mii_rw(dev, np->phyaddr, MII_ADVERTISE, adv);
+
+		if (np->gigabit == PHY_GIGABIT) {
+			adv = mii_rw(dev, np->phyaddr, MII_1000BT_CR, MII_READ);
+			adv &= ~ADVERTISE_1000FULL;
+			if (ecmd->advertising & ADVERTISED_1000baseT_Full)
+				adv |= ADVERTISE_1000FULL;
+			mii_rw(dev, np->phyaddr, MII_1000BT_CR, adv);
+		}
+
+		bmcr = mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ);
+		bmcr |= (BMCR_ANENABLE | BMCR_ANRESTART);
+		mii_rw(dev, np->phyaddr, MII_BMCR, bmcr);
+
+	} else {
+		int adv, bmcr;
+
+		np->autoneg = 0;
+
+		adv = mii_rw(dev, np->phyaddr, MII_ADVERTISE, MII_READ);
+		adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4);
+		if (ecmd->speed == SPEED_10 && ecmd->duplex == DUPLEX_HALF)
+			adv |= ADVERTISE_10HALF;
+		if (ecmd->speed == SPEED_10 && ecmd->duplex == DUPLEX_FULL)
+			adv |= ADVERTISE_10FULL;
+		if (ecmd->speed == SPEED_100 && ecmd->duplex == DUPLEX_HALF)
+			adv |= ADVERTISE_100HALF;
+		if (ecmd->speed == SPEED_100 && ecmd->duplex == DUPLEX_FULL)
+			adv |= ADVERTISE_100FULL;
+		mii_rw(dev, np->phyaddr, MII_ADVERTISE, adv);
+		np->fixed_mode = adv;
+
+		if (np->gigabit == PHY_GIGABIT) {
+			adv = mii_rw(dev, np->phyaddr, MII_1000BT_CR, MII_READ);
+			adv &= ~ADVERTISE_1000FULL;
+			mii_rw(dev, np->phyaddr, MII_1000BT_CR, adv);
+		}
+
+		bmcr = mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ);
+		bmcr |= ~(BMCR_ANENABLE|BMCR_SPEED100|BMCR_FULLDPLX);
+		if (adv & (ADVERTISE_10FULL|ADVERTISE_100FULL))
+			bmcr |= BMCR_FULLDPLX;
+		if (adv & (ADVERTISE_100HALF|ADVERTISE_100FULL))
+			bmcr |= BMCR_SPEED100;
+		mii_rw(dev, np->phyaddr, MII_BMCR, bmcr);
+
+		if (netif_running(dev)) {
+			/* Wait a bit and then reconfigure the nic. */
+			udelay(10);
+			nv_linkchange(dev);
+		}
+	}
+	spin_unlock_irq(&np->lock);
+
+	return 0;
+}
+
+static struct ethtool_ops ops = {
+	.get_drvinfo = nv_get_drvinfo,
+	.get_link = ethtool_op_get_link,
+	.get_wol = nv_get_wol,
+	.set_wol = nv_set_wol,
+	.get_settings = nv_get_settings,
+	.set_settings = nv_set_settings,
+};
+
 static int nv_open(struct net_device *dev)
 {
 	struct fe_priv *np = get_nvpriv(dev);
@@ -1550,9 +1751,6 @@
 		base + NvRegRingSizes);
 
 	/* 5) continue setup */
-	np->linkspeed = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_10;
-	np->duplex = 0;
-
 	writel(np->linkspeed, base + NvRegLinkSpeed);
 	writel(NVREG_UNKSETUP3_VAL1, base + NvRegUnknownSetupReg3);
 	writel(np->desc_ver, base + NvRegTxRxControl);
@@ -1865,6 +2063,11 @@
 		/* reset it */
 		phy_init(dev);
 	}
+
+	/* set default link speed settings */
+	np->linkspeed = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_10;
+	np->duplex = 0;
+	np->autoneg = 1;
 
 	err = register_netdev(dev);
 	if (err) {
diff -Nru a/drivers/net/gianfar.c b/drivers/net/gianfar.c
--- a/drivers/net/gianfar.c	2005-03-01 23:38:44 -08:00
+++ b/drivers/net/gianfar.c	2005-03-01 23:38:44 -08:00
@@ -26,7 +26,7 @@
  *  controllers on the Freescale 8540/8560 integrated processors,
  *  as well as the Fast Ethernet Controller on the 8540.  
  *  
- *  The driver is initialized through OCP.  Structures which
+ *  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
  *  discount the possibility that other architectures could one
@@ -85,6 +85,7 @@
 #include <linux/skbuff.h>
 #include <linux/spinlock.h>
 #include <linux/mm.h>
+#include <linux/device.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
@@ -130,8 +131,8 @@
 static void adjust_link(struct net_device *dev);
 static void init_registers(struct net_device *dev);
 static int init_phy(struct net_device *dev);
-static int gfar_probe(struct ocp_device *ocpdev);
-static void gfar_remove(struct ocp_device *ocpdev);
+static int gfar_probe(struct device *device);
+static int gfar_remove(struct device *device);
 void free_skb_resources(struct gfar_private *priv);
 static void gfar_set_multi(struct net_device *dev);
 static void gfar_set_hash_for_addr(struct net_device *dev, u8 *addr);
@@ -148,45 +149,27 @@
 MODULE_DESCRIPTION("Gianfar Ethernet Driver");
 MODULE_LICENSE("GPL");
 
-/* Called by the ocp code to initialize device data structures
- * required for bringing up the device
- * returns 0 on success */
-static int gfar_probe(struct ocp_device *ocpdev)
+static int gfar_probe(struct device *device)
 {
 	u32 tempval;
-	struct ocp_device *mdiodev;
 	struct net_device *dev = NULL;
 	struct gfar_private *priv = NULL;
-	struct ocp_gfar_data *einfo;
+	struct platform_device *pdev = to_platform_device(device);
+	struct gianfar_platform_data *einfo;
+	struct resource *r;
 	int idx;
 	int err = 0;
 	int dev_ethtool_ops = 0;
 
-	einfo = (struct ocp_gfar_data *) ocpdev->def->additions;
+	einfo = (struct gianfar_platform_data *) pdev->dev.platform_data;
 
 	if (einfo == NULL) {
 		printk(KERN_ERR "gfar %d: Missing additional data!\n",
-		       ocpdev->def->index);
+		       pdev->id);
 
 		return -ENODEV;
 	}
 
-	/* get a pointer to the register memory which can
-	 * configure the PHYs.  If it's different from this set,
-	 * get the device which has those regs */
-	if ((einfo->phyregidx >= 0) && 
-			(einfo->phyregidx != ocpdev->def->index)) {
-		mdiodev = ocp_find_device(OCP_ANY_ID,
-					  OCP_FUNC_GFAR, einfo->phyregidx);
-
-		/* If the device which holds the MDIO regs isn't
-		 * up, wait for it to come up */
-		if (mdiodev == NULL)
-			return -EAGAIN;
-	} else {
-		mdiodev = ocpdev;
-	}
-
 	/* Create an ethernet device instance */
 	dev = alloc_etherdev(sizeof (*priv));
 
@@ -198,9 +181,19 @@
 	/* Set the info in the priv to the current info */
 	priv->einfo = einfo;
 
+	/* fill out IRQ fields */
+	if (einfo->device_flags & FSL_GIANFAR_DEV_HAS_MULTI_INTR) {
+		priv->interruptTransmit = platform_get_irq_byname(pdev, "tx");
+		priv->interruptReceive = platform_get_irq_byname(pdev, "rx");
+		priv->interruptError = platform_get_irq_byname(pdev, "error");
+	} else {
+		priv->interruptTransmit = platform_get_irq(pdev, 0);
+	}
+
 	/* get a pointer to the register memory */
+	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	priv->regs = (struct gfar *)
-		ioremap(ocpdev->def->paddr, sizeof (struct gfar));
+		ioremap(r->start, sizeof (struct gfar));
 
 	if (priv->regs == NULL) {
 		err = -ENOMEM;
@@ -209,7 +202,7 @@
 
 	/* Set the PHY base address */
 	priv->phyregs = (struct gfar *)
-	    ioremap(mdiodev->def->paddr, sizeof (struct gfar));
+	    ioremap(einfo->phy_reg_addr, sizeof (struct gfar));
 
 	if (priv->phyregs == NULL) {
 		err = -ENOMEM;
@@ -218,7 +211,7 @@
 
 	spin_lock_init(&priv->lock);
 
-	ocp_set_drvdata(ocpdev, dev);
+	dev_set_drvdata(device, dev);
 
 	/* Stop the DMA engine now, in case it was running before */
 	/* (The firmware could have used it, and left it running). */
@@ -255,7 +248,7 @@
 	dev->base_addr = (unsigned long) (priv->regs);
 
 	SET_MODULE_OWNER(dev);
-	SET_NETDEV_DEV(dev, &ocpdev->dev);
+	SET_NETDEV_DEV(dev, device);
 
 	/* Fill in the dev structure */
 	dev->open = gfar_enet_open;
@@ -274,10 +267,10 @@
 
 	/* Index into the array of possible ethtool
 	 * ops to catch all 4 possibilities */
-	if((priv->einfo->flags & GFAR_HAS_RMON) == 0)
+	if((priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_RMON) == 0)
 		dev_ethtool_ops += 1;
 
-	if((priv->einfo->flags & GFAR_HAS_COALESCE) == 0)
+	if((priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_COALESCE) == 0)
 		dev_ethtool_ops += 2;
 
 	dev->ethtool_ops = gfar_op_array[dev_ethtool_ops];
@@ -332,18 +325,21 @@
 	return -ENOMEM;
 }
 
-static void gfar_remove(struct ocp_device *ocpdev)
+static int gfar_remove(struct device *device)
 {
-	struct net_device *dev = ocp_get_drvdata(ocpdev);
+	struct net_device *dev = dev_get_drvdata(device);
 	struct gfar_private *priv = netdev_priv(dev);
 
-	ocp_set_drvdata(ocpdev, NULL);
+	dev_set_drvdata(device, NULL);
 
 	iounmap((void *) priv->regs);
 	iounmap((void *) priv->phyregs);
 	free_netdev(dev);
+
+	return 0;
 }
 
+
 /* Configure the PHY for dev.
  * returns 0 if success.  -1 if failure
  */
@@ -470,7 +466,7 @@
 	gfar_write(&priv->regs->rctrl, 0x00000000);
 
 	/* Zero out the rmon mib registers if it has them */
-	if (priv->einfo->flags & GFAR_HAS_RMON) {
+	if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_RMON) {
 		memset((void *) &(priv->regs->rmon), 0,
 		       sizeof (struct rmon_mib));
 
@@ -536,7 +532,7 @@
 	tempval &= ~(MACCFG1_RX_EN | MACCFG1_TX_EN);
 	gfar_write(&regs->maccfg1, tempval);
 
-	if (priv->einfo->flags & GFAR_HAS_PHY_INTR) {
+	if (priv->einfo->board_flags & FSL_GIANFAR_BRD_HAS_PHY_INTR) {
 		/* Clear any pending interrupts */
 		mii_clear_phy_interrupt(priv->mii_info);
 
@@ -548,15 +544,15 @@
 	spin_unlock_irqrestore(&priv->lock, flags);
 
 	/* Free the IRQs */
-	if (priv->einfo->flags & GFAR_HAS_MULTI_INTR) {
-		free_irq(priv->einfo->interruptError, dev);
-		free_irq(priv->einfo->interruptTransmit, dev);
-		free_irq(priv->einfo->interruptReceive, dev);
+	if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_MULTI_INTR) {
+		free_irq(priv->interruptError, dev);
+		free_irq(priv->interruptTransmit, dev);
+		free_irq(priv->interruptReceive, dev);
 	} else {
-		free_irq(priv->einfo->interruptTransmit, dev);
+		free_irq(priv->interruptTransmit, dev);
 	}
 
-	if (priv->einfo->flags & GFAR_HAS_PHY_INTR) {
+	if (priv->einfo->board_flags & FSL_GIANFAR_BRD_HAS_PHY_INTR) {
 		free_irq(priv->einfo->interruptPHY, dev);
 	} else {
 		del_timer_sync(&priv->phy_info_timer);
@@ -727,41 +723,41 @@
 
 	/* If the device has multiple interrupts, register for
 	 * them.  Otherwise, only register for the one */
-	if (priv->einfo->flags & GFAR_HAS_MULTI_INTR) {
+	if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_MULTI_INTR) {
 		/* Install our interrupt handlers for Error, 
 		 * Transmit, and Receive */
-		if (request_irq(priv->einfo->interruptError, gfar_error,
+		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->einfo->interruptError);
+			       dev->name, priv->interruptError);
 
 			err = -1;
 			goto err_irq_fail;
 		}
 
-		if (request_irq(priv->einfo->interruptTransmit, gfar_transmit,
+		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->einfo->interruptTransmit);
+			       dev->name, priv->interruptTransmit);
 
 			err = -1;
 
 			goto tx_irq_fail;
 		}
 
-		if (request_irq(priv->einfo->interruptReceive, gfar_receive,
+		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->einfo->interruptReceive);
+			       dev->name, priv->interruptReceive);
 
 			err = -1;
 			goto rx_irq_fail;
 		}
 	} else {
-		if (request_irq(priv->einfo->interruptTransmit, gfar_interrupt,
+		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->einfo->interruptError);
+			       dev->name, priv->interruptError);
 
 			err = -1;
 			goto err_irq_fail;
@@ -815,9 +811,9 @@
 	return 0;
 
 rx_irq_fail:
-	free_irq(priv->einfo->interruptTransmit, dev);
+	free_irq(priv->interruptTransmit, dev);
 tx_irq_fail:
-	free_irq(priv->einfo->interruptError, dev);
+	free_irq(priv->interruptError, dev);
 err_irq_fail:
 rx_skb_fail:
 	free_skb_resources(priv);
@@ -1194,8 +1190,8 @@
 	} 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));
+		       dev->name, gfar_read(&priv->regs->ievent),
+		       gfar_read(&priv->regs->imask));
 #endif
 	}
 #else
@@ -1419,7 +1415,7 @@
 
 #ifdef VERBOSE_GFAR_ERRORS
 		printk(KERN_DEBUG "%s: busy error (rhalt: %x)\n", dev->name,
-		       gfar_read(priv->regs->rstat));
+		       gfar_read(&priv->regs->rstat));
 #endif
 	}
 	if (events & IEVENT_BABR) {
@@ -1490,7 +1486,7 @@
 		adjust_link(dev);
 
 	/* Reenable interrupts, if needed */
-	if (priv->einfo->flags & GFAR_HAS_PHY_INTR)
+	if (priv->einfo->board_flags & FSL_GIANFAR_BRD_HAS_PHY_INTR)
 		mii_configure_phy_interrupt(priv->mii_info,
 				MII_INTERRUPT_ENABLED);
 }
@@ -1547,7 +1543,7 @@
 	del_timer_sync(&priv->phy_info_timer);
 
 	/* Grab the PHY interrupt, if necessary/possible */
-	if (priv->einfo->flags & GFAR_HAS_PHY_INTR) {
+	if (priv->einfo->board_flags & FSL_GIANFAR_BRD_HAS_PHY_INTR) {
 		if (request_irq(priv->einfo->interruptPHY, 
 					phy_interrupt,
 					SA_SHIRQ, 
@@ -1758,7 +1754,7 @@
 	/* 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));
+	       dev->name, events, gfar_read(&priv->regs->imask));
 #endif
 
 	/* Update the error counters */
@@ -1797,7 +1793,7 @@
 
 #ifdef VERBOSE_GFAR_ERRORS
 		printk(KERN_DEBUG "%s: busy error (rhalt: %x)\n", dev->name,
-		       gfar_read(priv->regs->rstat));
+		       gfar_read(&priv->regs->rstat));
 #endif
 	}
 	if (events & IEVENT_BABR) {
@@ -1829,36 +1825,23 @@
 }
 
 /* Structure for a device driver */
-static struct ocp_device_id gfar_ids[] = {
-	{.vendor = OCP_ANY_ID,.function = OCP_FUNC_GFAR},
-	{.vendor = OCP_VENDOR_INVALID}
-};
-
-static struct ocp_driver gfar_driver = {
-	.name = "gianfar",
-	.id_table = gfar_ids,
-
+static struct device_driver gfar_driver = {
+	.name = "fsl-gianfar",
+	.bus = &platform_bus_type,
 	.probe = gfar_probe,
 	.remove = gfar_remove,
 };
 
 static int __init gfar_init(void)
 {
-	int rc;
-
-	rc = ocp_register_driver(&gfar_driver);
-	if (rc != 0) {
-		ocp_unregister_driver(&gfar_driver);
-		return -ENODEV;
-	}
-
-	return 0;
+	return driver_register(&gfar_driver);
 }
 
 static void __exit gfar_exit(void)
 {
-	ocp_unregister_driver(&gfar_driver);
+	driver_unregister(&gfar_driver);
 }
 
 module_init(gfar_init);
 module_exit(gfar_exit);
+
diff -Nru a/drivers/net/gianfar.h b/drivers/net/gianfar.h
--- a/drivers/net/gianfar.h	2005-03-01 23:39:10 -08:00
+++ b/drivers/net/gianfar.h	2005-03-01 23:39:10 -08:00
@@ -37,6 +37,7 @@
 #include <linux/skbuff.h>
 #include <linux/spinlock.h>
 #include <linux/mm.h>
+#include <linux/fsl_devices.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
@@ -47,7 +48,6 @@
 #include <linux/workqueue.h>
 #include <linux/ethtool.h>
 #include <linux/netdevice.h>
-#include <asm/ocp.h>
 #include "gianfar_phy.h"
 
 /* The maximum number of packets to be handled in one call of gfar_poll */
@@ -510,7 +510,10 @@
 	unsigned int rxclean;
 
 	/* Info structure initialized by board setup code */
-	struct ocp_gfar_data *einfo;
+	unsigned int interruptTransmit;
+	unsigned int interruptReceive;
+	unsigned int interruptError;
+	struct gianfar_platform_data *einfo;
 
 	struct gfar_mii_info *mii_info;
 	int oldspeed;
diff -Nru a/drivers/net/gianfar_ethtool.c b/drivers/net/gianfar_ethtool.c
--- a/drivers/net/gianfar_ethtool.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/net/gianfar_ethtool.c	2005-03-01 23:39:08 -08:00
@@ -186,9 +186,11 @@
 {
 	struct gfar_private *priv = netdev_priv(dev);
 	uint gigabit_support = 
-		priv->einfo->flags & GFAR_HAS_GIGABIT ? SUPPORTED_1000baseT_Full : 0;
+		priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_GIGABIT ?
+			SUPPORTED_1000baseT_Full : 0;
 	uint gigabit_advert = 
-		priv->einfo->flags & GFAR_HAS_GIGABIT ? ADVERTISED_1000baseT_Full: 0;
+		priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_GIGABIT ?
+			ADVERTISED_1000baseT_Full: 0;
 
 	cmd->supported = (SUPPORTED_10baseT_Half
 			  | SUPPORTED_100baseT_Half
diff -Nru a/drivers/net/gt96100eth.c b/drivers/net/gt96100eth.c
--- a/drivers/net/gt96100eth.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/net/gt96100eth.c	2005-03-01 23:39:18 -08:00
@@ -187,10 +187,8 @@
 {
 	if (in_interrupt())
 		return;
-	else {
-		current->state = TASK_INTERRUPTIBLE;
-		schedule_timeout(ms*HZ/1000);
-	}
+	else
+		msleep_interruptible(ms);
 }
 
 static int
@@ -527,7 +525,7 @@
 
 	// wait for abort to complete
 	while (GT96100ETH_READ(gp, GT96100_ETH_SDMA_COMM) & abort_bits) {
-		// snooze for 20 msec and check again
+		// snooze for 1 msec and check again
 		gt96100_delay(1);
 	
 		if (--timedout == 0) {
diff -Nru a/drivers/net/hamachi.c b/drivers/net/hamachi.c
--- a/drivers/net/hamachi.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/net/hamachi.c	2005-03-01 23:39:17 -08:00
@@ -512,27 +512,28 @@
 	u32 rx_int_var, tx_int_var;	/* interrupt control variables */
 	u32 option;							/* Hold on to a copy of the options */
 	struct pci_dev *pci_dev;
+	void __iomem *base;
 };
 
 MODULE_AUTHOR("Donald Becker <becker@scyld.com>, Eric Kasten <kasten@nscl.msu.edu>, Keith Underwood <keithu@parl.clemson.edu>");
 MODULE_DESCRIPTION("Packet Engines 'Hamachi' GNIC-II Gigabit Ethernet driver");
 MODULE_LICENSE("GPL");
 
-MODULE_PARM(max_interrupt_work, "i");
-MODULE_PARM(mtu, "i");
-MODULE_PARM(debug, "i");
-MODULE_PARM(min_rx_pkt, "i");
-MODULE_PARM(max_rx_gap, "i");
-MODULE_PARM(max_rx_latency, "i");
-MODULE_PARM(min_tx_pkt, "i");
-MODULE_PARM(max_tx_gap, "i");
-MODULE_PARM(max_tx_latency, "i");
-MODULE_PARM(rx_copybreak, "i");
-MODULE_PARM(rx_params, "1-" __MODULE_STRING(MAX_UNITS) "i");
-MODULE_PARM(tx_params, "1-" __MODULE_STRING(MAX_UNITS) "i");
-MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i");
-MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
-MODULE_PARM(force32, "i");
+module_param(max_interrupt_work, int, 0);
+module_param(mtu, int, 0);
+module_param(debug, int, 0);
+module_param(min_rx_pkt, int, 0);
+module_param(max_rx_gap, int, 0);
+module_param(max_rx_latency, int, 0);
+module_param(min_tx_pkt, int, 0);
+module_param(max_tx_gap, int, 0);
+module_param(max_tx_latency, int, 0);
+module_param(rx_copybreak, int, 0);
+module_param_array(rx_params, int, NULL, 0);
+module_param_array(tx_params, int, NULL, 0);
+module_param_array(options, int, NULL, 0);
+module_param_array(full_duplex, int, NULL, 0);
+module_param(force32, int, 0);
 MODULE_PARM_DESC(max_interrupt_work, "GNIC-II maximum events handled per interrupt");
 MODULE_PARM_DESC(mtu, "GNIC-II MTU (all boards)");
 MODULE_PARM_DESC(debug, "GNIC-II debug level (0-7)");
@@ -549,7 +550,7 @@
 MODULE_PARM_DESC(full_duplex, "GNIC-II full duplex setting(s) (1)");
 MODULE_PARM_DESC(force32, "GNIC-II: Bit 0: 32 bit PCI, bit 1: disable parity, bit 2: 64 bit PCI (all boards)");
                                                                         
-static int read_eeprom(long ioaddr, int location);
+static int read_eeprom(void __iomem *ioaddr, int location);
 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, int value);
 static int hamachi_open(struct net_device *dev);
@@ -575,7 +576,8 @@
 	int option, i, rx_int_var, tx_int_var, boguscnt;
 	int chip_id = ent->driver_data;
 	int irq;
-	long ioaddr;
+	void __iomem *ioaddr;
+	unsigned long base;
 	static int card_idx;
 	struct net_device *dev;
 	void *ring_space;
@@ -594,9 +596,9 @@
 		goto err_out;
 	}
 
-	ioaddr = pci_resource_start(pdev, 0);
+	base = pci_resource_start(pdev, 0);
 #ifdef __alpha__				/* Really "64 bit addrs" */
-	ioaddr |= (pci_resource_start(pdev, 1) << 32);
+	base |= (pci_resource_start(pdev, 1) << 32);
 #endif
 
 	pci_set_master(pdev);
@@ -605,7 +607,7 @@
 	if (i) return i;
 
 	irq = pdev->irq;
-	ioaddr = (long) ioremap(ioaddr, 0x400);
+	ioaddr = ioremap(base, 0x400);
 	if (!ioaddr)
 		goto err_out_release;
 
@@ -678,7 +680,8 @@
 		i = readb(ioaddr + PCIClkMeas);	
 	}
 
-	dev->base_addr = ioaddr;
+	hmp->base = ioaddr;
+	dev->base_addr = (unsigned long)ioaddr;
 	dev->irq = irq;
 	pci_set_drvdata(pdev, dev);
 
@@ -741,7 +744,7 @@
 		goto err_out_unmap_rx;
 	}
 
-	printk(KERN_INFO "%s: %s type %x at 0x%lx, ",
+	printk(KERN_INFO "%s: %s type %x at %p, ",
 		   dev->name, chip_tbl[chip_id].name, readl(ioaddr + ChipRev),
 		   ioaddr);
 	for (i = 0; i < 5; i++)
@@ -790,14 +793,14 @@
 err_out_cleardev:
 	free_netdev (dev);
 err_out_iounmap:
-	iounmap((char *)ioaddr);
+	iounmap(ioaddr);
 err_out_release:
 	pci_release_regions(pdev);
 err_out:
 	return ret;
 }
 
-static int __devinit read_eeprom(long ioaddr, int location)
+static int __devinit read_eeprom(void __iomem *ioaddr, int location)
 {
 	int bogus_cnt = 1000;
 
@@ -819,7 +822,8 @@
 
 static int mdio_read(struct net_device *dev, int phy_id, int location)
 {
-	long ioaddr = dev->base_addr;
+	struct hamachi_private *hmp = netdev_priv(dev);
+	void __iomem *ioaddr = hmp->base;
 	int i;
 
 	/* We should check busy first - per docs -KDU */
@@ -836,7 +840,8 @@
 
 static void mdio_write(struct net_device *dev, int phy_id, int location, int value)
 {
-	long ioaddr = dev->base_addr;
+	struct hamachi_private *hmp = netdev_priv(dev);
+	void __iomem *ioaddr = hmp->base;
 	int i;
 
 	/* We should check busy first - per docs -KDU */
@@ -857,7 +862,7 @@
 static int hamachi_open(struct net_device *dev)
 {
 	struct hamachi_private *hmp = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = hmp->base;
 	int i;
 	u32 rx_int_var, tx_int_var;
 	u16 fifo_info;
@@ -987,7 +992,7 @@
 	writew(0x001D, ioaddr + RxDMACtrl);
 	writew(0x001D, ioaddr + TxDMACtrl);
 #endif
-	writew(0x0001, dev->base_addr + RxCmd);
+	writew(0x0001, ioaddr + RxCmd);
 
 	if (hamachi_debug > 2) {
 		printk(KERN_DEBUG "%s: Done hamachi_open(), status: Rx %x Tx %x.\n",
@@ -1038,7 +1043,7 @@
 {
 	struct net_device *dev = (struct net_device *)data;
 	struct hamachi_private *hmp = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = hmp->base;
 	int next_tick = 10*HZ;
 
 	if (hamachi_debug > 2) {
@@ -1063,7 +1068,7 @@
 {
 	int i;
 	struct hamachi_private *hmp = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = hmp->base;
 
 	printk(KERN_WARNING "%s: Hamachi transmit timed out, status %8.8x,"
 		   " resetting...\n", dev->name, (int)readw(ioaddr + TxStatus));
@@ -1115,7 +1120,7 @@
 	}
 
 	udelay(60); /* Sleep 60 us just for safety sake */
-	writew(0x0002, dev->base_addr + RxCmd); /* STOP Rx */
+	writew(0x0002, ioaddr + RxCmd); /* STOP Rx */
 		
 	writeb(0x01, ioaddr + ChipReset);  /* Reinit the hardware */ 
 
@@ -1157,9 +1162,9 @@
 	hmp->stats.tx_errors++;
 
 	/* Restart the chip's Tx/Rx processes . */
-	writew(0x0002, dev->base_addr + TxCmd); /* STOP Tx */
-	writew(0x0001, dev->base_addr + TxCmd); /* START Tx */
-	writew(0x0001, dev->base_addr + RxCmd); /* START Rx */
+	writew(0x0002, ioaddr + TxCmd); /* STOP Tx */
+	writew(0x0001, ioaddr + TxCmd); /* START Tx */
+	writew(0x0001, ioaddr + RxCmd); /* START Rx */
 
 	netif_wake_queue(dev);
 }
@@ -1275,9 +1280,9 @@
 
 		/* Wake the potentially-idle transmit channel. */
 		/* If we don't need to read status, DON'T -KDU */
-		status=readw(dev->base_addr + TxStatus);
+		status=readw(hmp->base + TxStatus);
 		if( !(status & 0x0001) || (status & 0x0002))
-			writew(0x0001, dev->base_addr + TxCmd);
+			writew(0x0001, hmp->base + TxCmd);
 		return 1;
 	} 
 
@@ -1343,9 +1348,9 @@
 
 	/* Wake the potentially-idle transmit channel. */
 	/* If we don't need to read status, DON'T -KDU */
-	status=readw(dev->base_addr + TxStatus);
+	status=readw(hmp->base + TxStatus);
 	if( !(status & 0x0001) || (status & 0x0002))
-		writew(0x0001, dev->base_addr + TxCmd);
+		writew(0x0001, hmp->base + TxCmd);
 
 	/* Immediately before returning, let's clear as many entries as we can. */
 	hamachi_tx(dev);
@@ -1376,8 +1381,9 @@
 static irqreturn_t hamachi_interrupt(int irq, void *dev_instance, struct pt_regs *rgs)
 {
 	struct net_device *dev = dev_instance;
-	struct hamachi_private *hmp;
-	long ioaddr, boguscnt = max_interrupt_work;
+	struct hamachi_private *hmp = netdev_priv(dev);
+	void __iomem *ioaddr = hmp->base;
+	long boguscnt = max_interrupt_work;
 	int handled = 0;
 
 #ifndef final_version			/* Can never occur. */
@@ -1387,8 +1393,6 @@
 	}
 #endif
 
-	ioaddr = dev->base_addr;
-	hmp = netdev_priv(dev);
 	spin_lock(&hmp->lock);
 
 	do {
@@ -1687,8 +1691,8 @@
 
 	/* Restart Rx engine if stopped. */
 	/* If we don't need to check status, don't. -KDU */
-	if (readw(dev->base_addr + RxStatus) & 0x0002)
-		writew(0x0001, dev->base_addr + RxCmd);
+	if (readw(hmp->base + RxStatus) & 0x0002)
+		writew(0x0001, hmp->base + RxCmd);
 
 	return 0;
 }
@@ -1697,8 +1701,8 @@
    than just errors. */
 static void hamachi_error(struct net_device *dev, int intr_status)
 {
-	long ioaddr = dev->base_addr;
 	struct hamachi_private *hmp = netdev_priv(dev);
+	void __iomem *ioaddr = hmp->base;
 
 	if (intr_status & (LinkChange|NegotiationChange)) {
 		if (hamachi_debug > 1)
@@ -1731,8 +1735,8 @@
 
 static int hamachi_close(struct net_device *dev)
 {
-	long ioaddr = dev->base_addr;
 	struct hamachi_private *hmp = netdev_priv(dev);
+	void __iomem *ioaddr = hmp->base;
 	struct sk_buff *skb;
 	int i;
 
@@ -1817,8 +1821,8 @@
 
 static struct net_device_stats *hamachi_get_stats(struct net_device *dev)
 {
-	long ioaddr = dev->base_addr;
 	struct hamachi_private *hmp = netdev_priv(dev);
+	void __iomem *ioaddr = hmp->base;
 
 	/* We should lock this segment of code for SMP eventually, although
 	   the vulnerability window is very small and statistics are
@@ -1845,7 +1849,8 @@
 
 static void set_rx_mode(struct net_device *dev)
 {
-	long ioaddr = dev->base_addr;
+	struct hamachi_private *hmp = netdev_priv(dev);
+	void __iomem *ioaddr = hmp->base;
 
 	if (dev->flags & IFF_PROMISC) {			/* Set promiscuous. */
 		/* Unconditionally log net taps. */
@@ -1950,11 +1955,11 @@
 		 */
 		if (!capable(CAP_NET_ADMIN))
 			return -EPERM;
-		writel(d[0], dev->base_addr + TxIntrCtrl);
-		writel(d[1], dev->base_addr + RxIntrCtrl);
+		writel(d[0], np->base + TxIntrCtrl);
+		writel(d[1], np->base + RxIntrCtrl);
 		printk(KERN_NOTICE "%s: tx %08x, rx %08x intr\n", dev->name,
-		  (u32) readl(dev->base_addr + TxIntrCtrl),
-		  (u32) readl(dev->base_addr + RxIntrCtrl));
+		  (u32) readl(np->base + TxIntrCtrl),
+		  (u32) readl(np->base + RxIntrCtrl));
 		rc = 0;
 	}
 
@@ -1980,7 +1985,7 @@
 		pci_free_consistent(pdev, TX_TOTAL_SIZE, hmp->tx_ring, 
 			hmp->tx_ring_dma);
 		unregister_netdev(dev);
-		iounmap((char *)dev->base_addr);
+		iounmap(hmp->base);
 		free_netdev(dev);
 		pci_release_regions(pdev);
 		pci_set_drvdata(pdev, NULL);
diff -Nru a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c
--- a/drivers/net/hamradio/6pack.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/net/hamradio/6pack.c	2005-03-01 23:38:53 -08:00
@@ -4,7 +4,7 @@
  *		kernel's AX.25 protocol layers.
  *
  * Authors:	Andreas Könsgen <ajk@iehk.rwth-aachen.de>
- *              Ralf Baechle DO1GRB <ralf@linux-mips.org>
+ *              Ralf Baechle DL5RB <ralf@linux-mips.org>
  *
  * Quite a lot of stuff "stolen" by Joerg Reuter from slip.c, written by
  *
@@ -119,11 +119,10 @@
 	unsigned char		status1;
 	unsigned char		status2;
 	unsigned char		tx_enable;
-	unsigned char		tnc_ok;
+	unsigned char		tnc_state;
 
 	struct timer_list	tx_t;
 	struct timer_list	resync_t;
-
 	atomic_t		refcnt;
 	struct semaphore	dead_sem;
 	spinlock_t		lock;
@@ -134,7 +133,6 @@
 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);
-static int sixpack_init(struct net_device *dev);
 
 /*
  * perform the persistence/slottime algorithm for CSMA access. If the
@@ -187,6 +185,11 @@
 		goto out_drop;
 	}
 
+	if (len > sp->mtu) {	/* sp->mtu = AX25_MTU = max. PACLEN = 256 */
+		msg = "oversized transmit packet!";
+		goto out_drop;
+	}
+
 	if (p[0] > 5) {
 		msg = "invalid KISS command";
 		goto out_drop;
@@ -249,8 +252,8 @@
 out_drop:
 	sp->stats.tx_dropped++;
 	netif_start_queue(sp->dev);
-	printk(KERN_DEBUG "%s: %s - dropped.\n", sp->dev->name, msg);
-	return;
+	if (net_ratelimit())
+		printk(KERN_DEBUG "%s: %s - dropped.\n", sp->dev->name, msg);
 }
 
 /* Encapsulate an IP datagram and kick it into a TTY queue. */
@@ -313,10 +316,20 @@
 	return &sp->stats;
 }
 
-static int sp_set_dev_mac_address(struct net_device *dev, void *addr)
+static int sp_set_mac_address(struct net_device *dev, void *addr)
 {
-	struct sockaddr *sa = addr;
-	memcpy(dev->dev_addr, sa->sa_data, AX25_ADDR_LEN);
+	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);
+
 	return 0;
 }
 
@@ -337,7 +350,6 @@
 		{'L'<<1,'I'<<1,'N'<<1,'U'<<1,'X'<<1,' '<<1,'1'<<1};
 
 	/* Finish setting up the DEVICE info. */
-	dev->init		= sixpack_init;
 	dev->mtu		= SIXP_MTU;
 	dev->hard_start_xmit	= sp_xmit;
 	dev->open		= sp_open_dev;
@@ -345,7 +357,7 @@
 	dev->stop		= sp_close;
 	dev->hard_header	= sp_header;
 	dev->get_stats	        = sp_get_stats;
-	dev->set_mac_address    = sp_set_dev_mac_address;
+	dev->set_mac_address    = sp_set_mac_address;
 	dev->hard_header_len	= AX25_MAX_HEADER_LEN;
 	dev->addr_len		= AX25_ADDR_LEN;
 	dev->type		= ARPHRD_AX25;
@@ -359,51 +371,9 @@
 
 	SET_MODULE_OWNER(dev);
 
-	/* New-style flags. */
 	dev->flags		= 0;
 }
 
-/* Find a free 6pack channel, and link in this `tty' line. */
-static inline struct sixpack *sp_alloc(void)
-{
-	struct sixpack *sp = NULL;
-	struct net_device *dev = NULL;
-
-	dev = alloc_netdev(sizeof(struct sixpack), "sp%d", sp_setup);
-	if (!dev)
-		return NULL;
-
-	sp = netdev_priv(dev);
-	sp->dev = dev;
-
-	spin_lock_init(&sp->lock);
-
-	if (register_netdev(dev))
-		goto out_free;
-
-	return sp;
-
-out_free:
-	printk(KERN_WARNING "sp_alloc() - register_netdev() failure.\n");
-
-	free_netdev(dev);
-
-	return NULL;
-}
-
-/* Free a 6pack channel. */
-static inline void sp_free(struct sixpack *sp)
-{
-	void * tmp;
-
-	/* Free all 6pack frame buffers. */
-	if ((tmp = xchg(&sp->rbuff, NULL)) != NULL)
-		kfree(tmp);
-	if ((tmp = xchg(&sp->xbuff, NULL)) != NULL)
-		kfree(tmp);
-}
-
-
 /* Send one completely decapsulated IP datagram to the IP layer. */
 
 /*
@@ -452,7 +422,7 @@
  * best way to fix this is to use a rwlock in the tty struct, but for now we
  * use a single global rwlock for all ttys in ppp line discipline.
  */
-static rwlock_t disc_data_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(disc_data_lock);
                                                                                 
 static struct sixpack *sp_get(struct tty_struct *tty)
 {
@@ -482,6 +452,8 @@
 	struct sixpack *sp = sp_get(tty);
 	int actual;
 
+	if (!sp)
+		return;
 	if (sp->xleft <= 0)  {
 		/* Now serial buffer is almost free & we can start
 		 * transmission of another packet */
@@ -492,7 +464,7 @@
 		goto out;
 	}
 
-	if (sp->tx_enable == 1) {
+	if (sp->tx_enable) {
 		actual = tty->driver->write(tty, sp->xhead, sp->xleft);
 		sp->xleft -= actual;
 		sp->xhead += actual;
@@ -504,80 +476,6 @@
 
 /* ----------------------------------------------------------------------- */
 
-/* Open the low-level part of the 6pack channel. */
-static int sp_open(struct net_device *dev)
-{
-	struct sixpack *sp = netdev_priv(dev);
-	char *rbuff, *xbuff = NULL;
-	int err = -ENOBUFS;
-	unsigned long len;
-
-	/* !!! length of the buffers. MTU is IP MTU, not PACLEN!  */
-
-	len = dev->mtu * 2;
-
-	rbuff = kmalloc(len + 4, GFP_KERNEL);
-	if (rbuff == NULL)
-		goto err_exit;
-
-	xbuff = kmalloc(len + 4, GFP_KERNEL);
-	if (xbuff == NULL)
-		goto err_exit;
-
-	spin_lock_bh(&sp->lock);
-
-	if (sp->tty == NULL)
-		return -ENODEV;
-
-	/*
-	 * Allocate the 6pack frame buffers:
-	 *
-	 * rbuff	Receive buffer.
-	 * xbuff	Transmit buffer.
-	 */
-
-	rbuff = xchg(&sp->rbuff, rbuff);
-	xbuff = xchg(&sp->xbuff, xbuff);
-
-	sp->mtu	     = AX25_MTU + 73;
-	sp->buffsize = len;
-	sp->rcount   = 0;
-	sp->rx_count = 0;
-	sp->rx_count_cooked = 0;
-	sp->xleft    = 0;
-
-	sp->flags	= 0;		/* Clear ESCAPE & ERROR flags */
-
-	sp->duplex = 0;
-	sp->tx_delay    = SIXP_TXDELAY;
-	sp->persistence = SIXP_PERSIST;
-	sp->slottime    = SIXP_SLOTTIME;
-	sp->led_state   = 0x60;
-	sp->status      = 1;
-	sp->status1     = 1;
-	sp->status2     = 0;
-	sp->tnc_ok      = 0;
-	sp->tx_enable   = 0;
-
-	netif_start_queue(dev);
-
-	init_timer(&sp->tx_t);
-	init_timer(&sp->resync_t);
-
-	spin_unlock_bh(&sp->lock);
-
-	err = 0;
-
-err_exit:
-	if (xbuff)
-		kfree(xbuff);
-	if (rbuff)
-		kfree(rbuff);
-
-	return err;
-}
-
-
 static int sixpack_receive_room(struct tty_struct *tty)
 {
 	return 65536;  /* We can handle an infinite amount of data. :-) */
@@ -629,14 +527,45 @@
  * decode_prio_command
  */
 
+#define TNC_UNINITIALIZED	0
+#define TNC_UNSYNC_STARTUP	1
+#define TNC_UNSYNCED		2
+#define TNC_IN_SYNC		3
+
+static void __tnc_set_sync_state(struct sixpack *sp, int new_tnc_state)
+{
+	char *msg;
+
+	switch (new_tnc_state) {
+	default:			/* gcc oh piece-o-crap ... */
+	case TNC_UNSYNC_STARTUP:
+		msg = "Synchronizing with TNC";
+		break;
+	case TNC_UNSYNCED:
+		msg = "Lost synchronization with TNC\n";
+		break;
+	case TNC_IN_SYNC:
+		msg = "Found TNC";
+		break;
+	}
+
+	sp->tnc_state = new_tnc_state;
+	printk(KERN_INFO "%s: %s\n", sp->dev->name, msg);
+}
+
+static inline void tnc_set_sync_state(struct sixpack *sp, int new_tnc_state)
+{
+	int old_tnc_state = sp->tnc_state;
+
+	if (old_tnc_state != new_tnc_state)
+		__tnc_set_sync_state(sp, new_tnc_state);
+}
+
 static void resync_tnc(unsigned long channel)
 {
 	struct sixpack *sp = (struct sixpack *) channel;
-	struct net_device *dev = sp->dev;
 	static char resync_cmd = 0xe8;
 
-	printk(KERN_INFO "%s: resyncing TNC\n", dev->name);
-
 	/* clear any data that might have been received */
 
 	sp->rx_count = 0;
@@ -647,7 +576,6 @@
 	sp->status = 1;
 	sp->status1 = 1;
 	sp->status2 = 0;
-	sp->tnc_ok = 0;
 
 	/* resync the TNC */
 
@@ -659,9 +587,9 @@
 	/* Start resync timer again -- the TNC might be still absent */
 
 	del_timer(&sp->resync_t);
-	sp->resync_t.data = (unsigned long) sp;
-	sp->resync_t.function = resync_tnc;
-	sp->resync_t.expires = jiffies + SIXP_RESYNC_TIMEOUT;
+	sp->resync_t.data	= (unsigned long) sp;
+	sp->resync_t.function	= resync_tnc;
+	sp->resync_t.expires	= jiffies + SIXP_RESYNC_TIMEOUT;
 	add_timer(&sp->resync_t);
 }
 
@@ -669,6 +597,8 @@
 {
 	unsigned char inbyte = 0xe8;
 
+	tnc_set_sync_state(sp, TNC_UNSYNC_STARTUP);
+
 	sp->tty->driver->write(sp->tty, &inbyte, 1);
 
 	del_timer(&sp->resync_t);
@@ -689,31 +619,91 @@
  */
 static int sixpack_open(struct tty_struct *tty)
 {
+	char *rbuff = NULL, *xbuff = NULL;
+	struct net_device *dev;
 	struct sixpack *sp;
+	unsigned long len;
 	int err = 0;
 
 	if (!capable(CAP_NET_ADMIN))
 		return -EPERM;
 
-	sp = sp_alloc();
-	if (!sp) {
+	dev = alloc_netdev(sizeof(struct sixpack), "sp%d", sp_setup);
+	if (!dev) {
 		err = -ENOMEM;
 		goto out;
 	}
 
-	sp->tty = tty;
+	sp = netdev_priv(dev);
+	sp->dev = dev;
+
+	spin_lock_init(&sp->lock);
 	atomic_set(&sp->refcnt, 1);
 	init_MUTEX_LOCKED(&sp->dead_sem);
 
-	/* Perform the low-level 6pack initialization. */
-	if ((err = sp_open(sp->dev)))
-		goto out;
+	/* !!! length of the buffers. MTU is IP MTU, not PACLEN!  */
+
+	len = dev->mtu * 2;
+
+	rbuff = kmalloc(len + 4, GFP_KERNEL);
+	xbuff = kmalloc(len + 4, GFP_KERNEL);
+
+	if (rbuff == NULL || xbuff == NULL) {
+		err = -ENOBUFS;
+		goto out_free;
+	}
+
+	spin_lock_bh(&sp->lock);
+
+	sp->tty = tty;
+
+	sp->rbuff	= rbuff;
+	sp->xbuff	= xbuff;
+
+	sp->mtu		= AX25_MTU + 73;
+	sp->buffsize	= len;
+	sp->rcount	= 0;
+	sp->rx_count	= 0;
+	sp->rx_count_cooked = 0;
+	sp->xleft	= 0;
+
+	sp->flags	= 0;		/* Clear ESCAPE & ERROR flags */
+
+	sp->duplex	= 0;
+	sp->tx_delay    = SIXP_TXDELAY;
+	sp->persistence = SIXP_PERSIST;
+	sp->slottime    = SIXP_SLOTTIME;
+	sp->led_state   = 0x60;
+	sp->status      = 1;
+	sp->status1     = 1;
+	sp->status2     = 0;
+	sp->tx_enable   = 0;
+
+	netif_start_queue(dev);
+
+	init_timer(&sp->tx_t);
+	init_timer(&sp->resync_t);
+
+	spin_unlock_bh(&sp->lock);
 
 	/* Done.  We have linked the TTY line to a channel. */
 	tty->disc_data = sp;
 
+	/* Now we're ready to register. */
+	if (register_netdev(dev))
+		goto out_free;
+
 	tnc_init(sp);
 
+	return 0;
+
+out_free:
+	kfree(xbuff);
+	kfree(rbuff);
+
+	if (dev)
+		free_netdev(dev);
+
 out:
 	return err;
 }
@@ -727,7 +717,7 @@
  */
 static void sixpack_close(struct tty_struct *tty)
 {
-	struct sixpack *sp = (struct sixpack *) tty->disc_data;
+	struct sixpack *sp;
 
 	write_lock(&disc_data_lock);
 	sp = tty->disc_data;
@@ -743,16 +733,14 @@
 	if (!atomic_dec_and_test(&sp->refcnt))
 		down(&sp->dead_sem);
 
+	unregister_netdev(sp->dev);
+
 	del_timer(&sp->tx_t);
 	del_timer(&sp->resync_t);
 
-	sp_free(sp);
-	unregister_netdev(sp->dev);
-}
-
-static int sp_set_mac_address(struct net_device *dev, void __user *addr)
-{
-	return copy_from_user(dev->dev_addr, addr, AX25_ADDR_LEN) ? -EFAULT : 0;
+	/* Free all 6pack frame buffers. */
+	kfree(sp->rbuff);
+	kfree(sp->xbuff);
 }
 
 /* Perform I/O control on an active 6pack channel. */
@@ -760,6 +748,7 @@
 	unsigned int cmd, unsigned long arg)
 {
 	struct sixpack *sp = sp_get(tty);
+	struct net_device *dev = sp->dev;
 	unsigned int tmp, err;
 
 	if (!sp)
@@ -767,8 +756,8 @@
 
 	switch(cmd) {
 	case SIOCGIFNAME:
-		err = copy_to_user((void __user *) arg, sp->dev->name,
-		                   strlen(sp->dev->name) + 1) ? -EFAULT : 0;
+		err = copy_to_user((void *) arg, dev->name,
+		                   strlen(dev->name) + 1) ? -EFAULT : 0;
 		break;
 
 	case SIOCGIFENCAP:
@@ -782,16 +771,30 @@
 		}
 
 		sp->mode = tmp;
-		sp->dev->addr_len        = AX25_ADDR_LEN;	  /* sizeof an AX.25 addr */
-		sp->dev->hard_header_len = AX25_KISS_HEADER_LEN + AX25_MAX_HEADER_LEN + 3;
-		sp->dev->type            = ARPHRD_AX25;
+		dev->addr_len        = AX25_ADDR_LEN;
+		dev->hard_header_len = AX25_KISS_HEADER_LEN +
+		                       AX25_MAX_HEADER_LEN + 3;
+		dev->type            = ARPHRD_AX25;
 
 		err = 0;
 		break;
 
-	 case SIOCSIFHWADDR:
-		err = sp_set_mac_address(sp->dev, (void __user *) arg);
+	 case SIOCSIFHWADDR: {
+		char addr[AX25_ADDR_LEN];
+
+		if (copy_from_user(&addr,
+		                   (void __user *) arg, AX25_ADDR_LEN)) {
+			err = -EFAULT;
+			break;
+		}
+
+		spin_lock_irq(&dev->xmit_lock);
+		memcpy(dev->dev_addr, &addr, AX25_ADDR_LEN);
+		spin_unlock_irq(&dev->xmit_lock);
+
+		err = 0;
 		break;
+	}
 
 	/* Allow stty to read, but not set, the serial port */
 	case TCGETS:
@@ -800,7 +803,7 @@
 		break;
 
 	default:
-		return -ENOIOCTLCMD;
+		err = -ENOIOCTLCMD;
 	}
 
 	sp_put(sp);
@@ -808,7 +811,6 @@
 	return err;
 }
 
-/* Fill in our line protocol discipline */
 static struct tty_ldisc sp_ldisc = {
 	.owner		= THIS_MODULE,
 	.magic		= TTY_LDISC_MAGIC,
@@ -823,8 +825,10 @@
 
 /* Initialize 6pack control device -- register 6pack line discipline */
 
-static char msg_banner[]  __initdata = KERN_INFO "AX.25: 6pack driver, " SIXPACK_VERSION "\n";
-static char msg_regfail[] __initdata = KERN_ERR  "6pack: can't register line discipline (err = %d)\n";
+static char msg_banner[]  __initdata = KERN_INFO \
+	"AX.25: 6pack driver, " SIXPACK_VERSION "\n";
+static char msg_regfail[] __initdata = KERN_ERR  \
+	"6pack: can't register line discipline (err = %d)\n";
 
 static int __init sixpack_init_driver(void)
 {
@@ -839,7 +843,8 @@
 	return status;
 }
 
-static const char msg_unregfail[] __exitdata = KERN_ERR "6pack: can't unregister line discipline (err = %d)\n";
+static const char msg_unregfail[] __exitdata = KERN_ERR \
+	"6pack: can't unregister line discipline (err = %d)\n";
 
 static void __exit sixpack_exit_driver(void)
 {
@@ -849,22 +854,6 @@
 		printk(msg_unregfail, ret);
 }
 
-/* Initialize the 6pack driver.  Called by DDI. */
-static int sixpack_init(struct net_device *dev)
-{
-	struct sixpack *sp = netdev_priv(dev);
-
-	if (sp == NULL)		/* Allocation failed ?? */
-		return -ENODEV;
-
-	/* Set up the "6pack Control Block". (And clear statistics) */
-
-	memset(sp, 0, sizeof (struct sixpack));
-	sp->dev	   = dev;
-
-	return 0;
-}
-
 /* encode an AX.25 packet into 6pack */
 
 static int encode_sixpack(unsigned char *tx_buf, unsigned char *tx_buf_raw,
@@ -905,7 +894,7 @@
 
 /* decode 4 sixpack-encoded bytes into 3 data bytes */
 
-static void decode_data(unsigned char inbyte, struct sixpack *sp)
+static void decode_data(struct sixpack *sp, unsigned char inbyte)
 {
 	unsigned char *buf;
 
@@ -927,7 +916,7 @@
 
 /* identify and execute a 6pack priority command byte */
 
-static void decode_prio_command(unsigned char cmd, struct sixpack *sp)
+static void decode_prio_command(struct sixpack *sp, unsigned char cmd)
 {
 	unsigned char channel;
 	int actual;
@@ -971,11 +960,11 @@
         /* if the state byte has been received, the TNC is present,
            so the resync timer can be reset. */
 
-	if (sp->tnc_ok == 1) {
+	if (sp->tnc_state == TNC_IN_SYNC) {
 		del_timer(&sp->resync_t);
-		sp->resync_t.data = (unsigned long) sp;
-		sp->resync_t.function = resync_tnc;
-		sp->resync_t.expires = jiffies + SIXP_INIT_RESYNC_TIMEOUT;
+		sp->resync_t.data	= (unsigned long) sp;
+		sp->resync_t.function	= resync_tnc;
+		sp->resync_t.expires	= jiffies + SIXP_INIT_RESYNC_TIMEOUT;
 		add_timer(&sp->resync_t);
 	}
 
@@ -984,7 +973,7 @@
 
 /* identify and execute a standard 6pack command byte */
 
-static void decode_std_command(unsigned char cmd, struct sixpack *sp)
+static void decode_std_command(struct sixpack *sp, unsigned char cmd)
 {
 	unsigned char checksum = 0, rest = 0, channel;
 	short i;
@@ -1005,7 +994,7 @@
 			rest = sp->rx_count;
 			if (rest != 0)
 				 for (i = rest; i <= 3; i++)
-					decode_data(0, sp);
+					decode_data(sp, 0);
 			if (rest == 2)
 				sp->rx_count_cooked -= 2;
 			else if (rest == 3)
@@ -1033,7 +1022,7 @@
 /* decode a 6pack packet */
 
 static void
-sixpack_decode(struct sixpack *sp, unsigned char pre_rbuff[], int count)
+sixpack_decode(struct sixpack *sp, unsigned char *pre_rbuff, int count)
 {
 	unsigned char inbyte;
 	int count1;
@@ -1041,16 +1030,15 @@
 	for (count1 = 0; count1 < count; count1++) {
 		inbyte = pre_rbuff[count1];
 		if (inbyte == SIXP_FOUND_TNC) {
-			printk(KERN_INFO "6pack: TNC found.\n");
-			sp->tnc_ok = 1;
+			tnc_set_sync_state(sp, TNC_IN_SYNC);
 			del_timer(&sp->resync_t);
 		}
 		if ((inbyte & SIXP_PRIO_CMD_MASK) != 0)
-			decode_prio_command(inbyte, sp);
+			decode_prio_command(sp, inbyte);
 		else if ((inbyte & SIXP_STD_CMD_MASK) != 0)
-			decode_std_command(inbyte, sp);
+			decode_std_command(sp, inbyte);
 		else if ((sp->status & SIXP_RX_DCD_MASK) == SIXP_RX_DCD_MASK)
-			decode_data(inbyte, sp);
+			decode_data(sp, inbyte);
 	}
 }
 
diff -Nru a/drivers/net/hamradio/baycom_epp.c b/drivers/net/hamradio/baycom_epp.c
--- a/drivers/net/hamradio/baycom_epp.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/net/hamradio/baycom_epp.c	2005-03-01 23:39:17 -08:00
@@ -1294,9 +1294,9 @@
 static const char *mode[NR_PORTS] = { "", };
 static int iobase[NR_PORTS] = { 0x378, };
 
-MODULE_PARM(mode, "1-" __MODULE_STRING(NR_PORTS) "s");
+module_param_array(mode, charp, NULL, 0);
 MODULE_PARM_DESC(mode, "baycom operating mode");
-MODULE_PARM(iobase, "1-" __MODULE_STRING(NR_PORTS) "i");
+module_param_array(iobase, int, NULL, 0);
 MODULE_PARM_DESC(iobase, "baycom io base address");
 
 MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu");
diff -Nru a/drivers/net/hamradio/baycom_par.c b/drivers/net/hamradio/baycom_par.c
--- a/drivers/net/hamradio/baycom_par.c	2005-03-01 23:39:19 -08:00
+++ b/drivers/net/hamradio/baycom_par.c	2005-03-01 23:39:19 -08:00
@@ -480,9 +480,9 @@
 static const char *mode[NR_PORTS] = { "picpar", };
 static int iobase[NR_PORTS] = { 0x378, };
 
-MODULE_PARM(mode, "1-" __MODULE_STRING(NR_PORTS) "s");
+module_param_array(mode, charp, NULL, 0);
 MODULE_PARM_DESC(mode, "baycom operating mode; eg. par96 or picpar");
-MODULE_PARM(iobase, "1-" __MODULE_STRING(NR_PORTS) "i");
+module_param_array(iobase, int, NULL, 0);
 MODULE_PARM_DESC(iobase, "baycom io base address");
 
 MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu");
diff -Nru a/drivers/net/hamradio/baycom_ser_fdx.c b/drivers/net/hamradio/baycom_ser_fdx.c
--- a/drivers/net/hamradio/baycom_ser_fdx.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/net/hamradio/baycom_ser_fdx.c	2005-03-01 23:38:58 -08:00
@@ -599,13 +599,13 @@
 static int irq[NR_PORTS] = { 4, };
 static int baud[NR_PORTS] = { [0 ... NR_PORTS-1] = 1200 };
 
-MODULE_PARM(mode, "1-" __MODULE_STRING(NR_PORTS) "s");
+module_param_array(mode, charp, NULL, 0);
 MODULE_PARM_DESC(mode, "baycom operating mode; * for software DCD");
-MODULE_PARM(iobase, "1-" __MODULE_STRING(NR_PORTS) "i");
+module_param_array(iobase, int, NULL, 0);
 MODULE_PARM_DESC(iobase, "baycom io base address");
-MODULE_PARM(irq, "1-" __MODULE_STRING(NR_PORTS) "i");
+module_param_array(irq, int, NULL, 0);
 MODULE_PARM_DESC(irq, "baycom irq number");
-MODULE_PARM(baud, "1-" __MODULE_STRING(NR_PORTS) "i");
+module_param_array(baud, int, NULL, 0);
 MODULE_PARM_DESC(baud, "baycom baud rate (300 to 4800)");
 
 MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu");
diff -Nru a/drivers/net/hamradio/baycom_ser_hdx.c b/drivers/net/hamradio/baycom_ser_hdx.c
--- a/drivers/net/hamradio/baycom_ser_hdx.c	2005-03-01 23:38:51 -08:00
+++ b/drivers/net/hamradio/baycom_ser_hdx.c	2005-03-01 23:38:51 -08:00
@@ -638,11 +638,11 @@
 static int iobase[NR_PORTS] = { 0x3f8, };
 static int irq[NR_PORTS] = { 4, };
 
-MODULE_PARM(mode, "1-" __MODULE_STRING(NR_PORTS) "s");
+module_param_array(mode, charp, NULL, 0);
 MODULE_PARM_DESC(mode, "baycom operating mode; * for software DCD");
-MODULE_PARM(iobase, "1-" __MODULE_STRING(NR_PORTS) "i");
+module_param_array(iobase, int, NULL, 0);
 MODULE_PARM_DESC(iobase, "baycom io base address");
-MODULE_PARM(irq, "1-" __MODULE_STRING(NR_PORTS) "i");
+module_param_array(irq, int, NULL, 0);
 MODULE_PARM_DESC(irq, "baycom irq number");
 
 MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu");
diff -Nru a/drivers/net/hamradio/scc.c b/drivers/net/hamradio/scc.c
--- a/drivers/net/hamradio/scc.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/net/hamradio/scc.c	2005-03-01 23:39:09 -08:00
@@ -237,7 +237,7 @@
 
 /* These provide interrupt save 2-step access to the Z8530 registers */
 
-static spinlock_t iolock = SPIN_LOCK_UNLOCKED;	/* Guards paired accesses */
+static DEFINE_SPINLOCK(iolock);	/* Guards paired accesses */
 
 static inline unsigned char InReg(io_port port, unsigned char reg)
 {
diff -Nru a/drivers/net/hp-plus.c b/drivers/net/hp-plus.c
--- a/drivers/net/hp-plus.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/net/hp-plus.c	2005-03-01 23:38:52 -08:00
@@ -437,8 +437,8 @@
 static int io[MAX_HPP_CARDS];
 static int irq[MAX_HPP_CARDS];
 
-MODULE_PARM(io, "1-" __MODULE_STRING(MAX_HPP_CARDS) "i");
-MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_HPP_CARDS) "i");
+module_param_array(io, int, NULL, 0);
+module_param_array(irq, int, NULL, 0);
 MODULE_PARM_DESC(io, "I/O port address(es)");
 MODULE_PARM_DESC(irq, "IRQ number(s); ignored if properly detected");
 MODULE_DESCRIPTION("HP PC-LAN+ ISA ethernet driver");
diff -Nru a/drivers/net/hp.c b/drivers/net/hp.c
--- a/drivers/net/hp.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/net/hp.c	2005-03-01 23:38:53 -08:00
@@ -406,8 +406,8 @@
 static int io[MAX_HP_CARDS];
 static int irq[MAX_HP_CARDS];
 
-MODULE_PARM(io, "1-" __MODULE_STRING(MAX_HP_CARDS) "i");
-MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_HP_CARDS) "i");
+module_param_array(io, int, NULL, 0);
+module_param_array(irq, int, NULL, 0);
 MODULE_PARM_DESC(io, "I/O base address(es)");
 MODULE_PARM_DESC(irq, "IRQ number(s) (assigned)");
 MODULE_DESCRIPTION("HP PC-LAN ISA ethernet driver");
diff -Nru a/drivers/net/hp100.c b/drivers/net/hp100.c
--- a/drivers/net/hp100.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/net/hp100.c	2005-03-01 23:38:55 -08:00
@@ -224,9 +224,9 @@
 static int hp100_priority_tx = HP100_DEFAULT_PRIORITY_TX;
 static int hp100_mode = 1;
 
-MODULE_PARM(hp100_rx_ratio, "1i");
-MODULE_PARM(hp100_priority_tx, "1i");
-MODULE_PARM(hp100_mode, "1i");
+module_param(hp100_rx_ratio, int, 0);
+module_param(hp100_priority_tx, int, 0);
+module_param(hp100_mode, int, 0);
 
 /*
  *  prototypes
@@ -280,8 +280,14 @@
  * address - Jean II */
 static inline dma_addr_t virt_to_whatever(struct net_device *dev, u32 * ptr)
 {
-	return ((u_long) ptr) +
-		((struct hp100_private *) (dev->priv))->whatever_offset;
+	struct hp100_private *lp = netdev_priv(dev);
+	return ((u_long) ptr) + lp->whatever_offset;
+}
+
+static inline u_int pdl_map_data(struct hp100_private *lp, void *data)
+{
+	return pci_map_single(lp->pci_dev, data, 
+			      MAX_ETHER_SIZE, PCI_DMA_FROMDEVICE);
 }
 
 /* TODO: This function should not really be needed in a good design... */
@@ -300,7 +306,7 @@
  * Read board id and convert to string.
  * Effectively same code as decode_eisa_sig
  */
-static __init const char *hp100_read_id(int ioaddr)
+static __devinit const char *hp100_read_id(int ioaddr)
 {
 	int i;
 	static char str[HP100_SIG_LEN];
@@ -423,8 +429,8 @@
 }
 #endif
 
-static int __init hp100_probe1(struct net_device *dev, int ioaddr,
-			       u_char bus, struct pci_dev *pci_dev)
+static int __devinit hp100_probe1(struct net_device *dev, int ioaddr,
+				  u_char bus, struct pci_dev *pci_dev)
 {
 	int i;
 	int err = -ENODEV;
@@ -631,7 +637,7 @@
 	}
 
 	/* Initialise the "private" data structure for this card. */
-	lp = (struct hp100_private *) dev->priv;
+	lp = netdev_priv(dev);
 
 	spin_lock_init(&lp->lock);
 	strlcpy(lp->id, eid, HP100_SIG_LEN);
@@ -781,7 +787,7 @@
 static void hp100_hwinit(struct net_device *dev)
 {
 	int ioaddr = dev->base_addr;
-	struct hp100_private *lp = (struct hp100_private *) dev->priv;
+	struct hp100_private *lp = netdev_priv(dev);
 
 #ifdef HP100_DEBUG_B
 	hp100_outw(0x4202, TRACE);
@@ -875,7 +881,7 @@
 static void hp100_mmuinit(struct net_device *dev)
 {
 	int ioaddr = dev->base_addr;
-	struct hp100_private *lp = (struct hp100_private *) dev->priv;
+	struct hp100_private *lp = netdev_priv(dev);
 	int i;
 
 #ifdef HP100_DEBUG_B
@@ -1053,7 +1059,7 @@
 
 static int hp100_open(struct net_device *dev)
 {
-	struct hp100_private *lp = (struct hp100_private *) dev->priv;
+	struct hp100_private *lp = netdev_priv(dev);
 #ifdef HP100_DEBUG_B
 	int ioaddr = dev->base_addr;
 #endif
@@ -1093,7 +1099,7 @@
 static int hp100_close(struct net_device *dev)
 {
 	int ioaddr = dev->base_addr;
-	struct hp100_private *lp = (struct hp100_private *) dev->priv;
+	struct hp100_private *lp = netdev_priv(dev);
 
 #ifdef HP100_DEBUG_B
 	hp100_outw(0x4205, TRACE);
@@ -1126,7 +1132,7 @@
  */
 static void hp100_init_pdls(struct net_device *dev)
 {
-	struct hp100_private *lp = (struct hp100_private *) dev->priv;
+	struct hp100_private *lp = netdev_priv(dev);
 	hp100_ring_t *ringptr;
 	u_int *pageptr;		/* Warning : increment by 4 - Jean II */
 	int i;
@@ -1273,7 +1279,8 @@
 		/* Conversion to new PCI API : map skbuf data to PCI bus.
 		 * Doc says it's OK for EISA as well - Jean II */
 		ringptr->pdl[0] = 0x00020000;	/* Write PDH */
-		ringptr->pdl[3] = ((u_int) pci_map_single(((struct hp100_private *) (dev->priv))->pci_dev, ringptr->skb->data, MAX_ETHER_SIZE, PCI_DMA_FROMDEVICE));
+		ringptr->pdl[3] = pdl_map_data(netdev_priv(dev), 
+					       ringptr->skb->data);
 		ringptr->pdl[4] = MAX_ETHER_SIZE;	/* Length of Data */
 
 #ifdef HP100_DEBUG_BM
@@ -1310,7 +1317,7 @@
 {
 	int ioaddr = dev->base_addr;
 
-	struct hp100_private *lp = (struct hp100_private *) dev->priv;
+	struct hp100_private *lp = netdev_priv(dev);
 	hp100_ring_t *ringptr;
 
 #ifdef HP100_DEBUG_B
@@ -1351,7 +1358,7 @@
 static void hp100_BM_shutdown(struct net_device *dev)
 {
 	int ioaddr = dev->base_addr;
-	struct hp100_private *lp = (struct hp100_private *) dev->priv;
+	struct hp100_private *lp = netdev_priv(dev);
 	unsigned long time;
 
 #ifdef HP100_DEBUG_B
@@ -1432,7 +1439,7 @@
 
 static int hp100_check_lan(struct net_device *dev)
 {
-	struct hp100_private *lp = (struct hp100_private *) dev->priv;
+	struct hp100_private *lp = netdev_priv(dev);
 
 	if (lp->lan_type < 0) {	/* no LAN type detected yet? */
 		hp100_stop_interface(dev);
@@ -1458,7 +1465,7 @@
 	unsigned long flags;
 	int i, ok_flag;
 	int ioaddr = dev->base_addr;
-	struct hp100_private *lp = (struct hp100_private *) dev->priv;
+	struct hp100_private *lp = netdev_priv(dev);
 	hp100_ring_t *ringptr;
 
 #ifdef HP100_DEBUG_B
@@ -1576,7 +1583,7 @@
  */
 static void hp100_clean_txring(struct net_device *dev)
 {
-	struct hp100_private *lp = (struct hp100_private *) dev->priv;
+	struct hp100_private *lp = netdev_priv(dev);
 	int ioaddr = dev->base_addr;
 	int donecount;
 
@@ -1615,7 +1622,7 @@
 	int i, ok_flag;
 	int ioaddr = dev->base_addr;
 	u_short val;
-	struct hp100_private *lp = (struct hp100_private *) dev->priv;
+	struct hp100_private *lp = netdev_priv(dev);
 
 #ifdef HP100_DEBUG_B
 	hp100_outw(0x4212, TRACE);
@@ -1755,7 +1762,7 @@
 {
 	int packets, pkt_len;
 	int ioaddr = dev->base_addr;
-	struct hp100_private *lp = (struct hp100_private *) dev->priv;
+	struct hp100_private *lp = netdev_priv(dev);
 	u_int header;
 	struct sk_buff *skb;
 
@@ -1864,7 +1871,7 @@
 static void hp100_rx_bm(struct net_device *dev)
 {
 	int ioaddr = dev->base_addr;
-	struct hp100_private *lp = (struct hp100_private *) dev->priv;
+	struct hp100_private *lp = netdev_priv(dev);
 	hp100_ring_t *ptr;
 	u_int header;
 	int pkt_len;
@@ -1973,7 +1980,7 @@
 {
 	unsigned long flags;
 	int ioaddr = dev->base_addr;
-	struct hp100_private *lp = (struct hp100_private *) dev->priv;
+	struct hp100_private *lp = netdev_priv(dev);
 
 #ifdef HP100_DEBUG_B
 	hp100_outw(0x4215, TRACE);
@@ -1991,7 +1998,7 @@
 {
 	int ioaddr = dev->base_addr;
 	u_short val;
-	struct hp100_private *lp = (struct hp100_private *) dev->priv;
+	struct hp100_private *lp = netdev_priv(dev);
 
 #ifdef HP100_DEBUG_B
 	hp100_outw(0x4216, TRACE);
@@ -2017,7 +2024,7 @@
 #ifdef HP100_DEBUG_B
 	int ioaddr = dev->base_addr;
 #endif
-	struct hp100_private *lp = (struct hp100_private *) dev->priv;
+	struct hp100_private *lp = netdev_priv(dev);
 
 #ifdef HP100_DEBUG_B
 	int ioaddr = dev->base_addr;
@@ -2061,7 +2068,7 @@
 {
 	unsigned long flags;
 	int ioaddr = dev->base_addr;
-	struct hp100_private *lp = (struct hp100_private *) dev->priv;
+	struct hp100_private *lp = netdev_priv(dev);
 
 #ifdef HP100_DEBUG_B
 	hp100_outw(0x4218, TRACE);
@@ -2191,7 +2198,7 @@
 static irqreturn_t hp100_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	struct net_device *dev = (struct net_device *) dev_id;
-	struct hp100_private *lp = (struct hp100_private *) dev->priv;
+	struct hp100_private *lp = netdev_priv(dev);
 
 	int ioaddr;
 	u_int val;
@@ -2322,7 +2329,7 @@
 {
 	unsigned long flags;
 	int ioaddr = dev->base_addr;
-	struct hp100_private *lp = (struct hp100_private *) dev->priv;
+	struct hp100_private *lp = netdev_priv(dev);
 
 #ifdef HP100_DEBUG_B
 	hp100_outw(0x4220, TRACE);
@@ -2381,7 +2388,7 @@
 
 static void hp100_stop_interface(struct net_device *dev)
 {
-	struct hp100_private *lp = (struct hp100_private *) dev->priv;
+	struct hp100_private *lp = netdev_priv(dev);
 	int ioaddr = dev->base_addr;
 	u_int val;
 
@@ -2442,7 +2449,7 @@
 {
 	int ioaddr = dev->base_addr;
 	u_short val_VG, val_10;
-	struct hp100_private *lp = (struct hp100_private *) dev->priv;
+	struct hp100_private *lp = netdev_priv(dev);
 
 #ifdef HP100_DEBUG_B
 	hp100_outw(0x4223, TRACE);
@@ -2488,7 +2495,7 @@
 
 static int hp100_down_vg_link(struct net_device *dev)
 {
-	struct hp100_private *lp = (struct hp100_private *) dev->priv;
+	struct hp100_private *lp = netdev_priv(dev);
 	int ioaddr = dev->base_addr;
 	unsigned long time;
 	long savelan, newlan;
@@ -2604,7 +2611,7 @@
 static int hp100_login_to_vg_hub(struct net_device *dev, u_short force_relogin)
 {
 	int ioaddr = dev->base_addr;
-	struct hp100_private *lp = (struct hp100_private *) dev->priv;
+	struct hp100_private *lp = netdev_priv(dev);
 	u_short val = 0;
 	unsigned long time;
 	int startst;
@@ -2775,7 +2782,7 @@
 static void hp100_cascade_reset(struct net_device *dev, u_short enable)
 {
 	int ioaddr = dev->base_addr;
-	struct hp100_private *lp = (struct hp100_private *) dev->priv;
+	struct hp100_private *lp = netdev_priv(dev);
 
 #ifdef HP100_DEBUG_B
 	hp100_outw(0x4226, TRACE);
@@ -2836,7 +2843,7 @@
 
 static void cleanup_dev(struct net_device *d)
 {
-	struct hp100_private *p = (struct hp100_private *) d->priv;
+	struct hp100_private *p = netdev_priv(d);
 
 	unregister_netdev(d);
 	release_region(d->base_addr, HP100_REGION_SIZE);
@@ -2998,7 +3005,7 @@
 #define HP100_DEVICES 5
 /* Parameters set by insmod */
 static int hp100_port[HP100_DEVICES] = { 0, [1 ... (HP100_DEVICES-1)] = -1 };
-MODULE_PARM(hp100_port, "1-" __MODULE_STRING(HP100_DEVICES) "i");
+module_param_array(hp100_port, int, NULL, 0);
 
 /* List of devices */
 static struct net_device *hp100_devlist[HP100_DEVICES];
diff -Nru a/drivers/net/ibm_emac/ibm_emac.h b/drivers/net/ibm_emac/ibm_emac.h
--- a/drivers/net/ibm_emac/ibm_emac.h	2005-03-01 23:39:18 -08:00
+++ b/drivers/net/ibm_emac/ibm_emac.h	2005-03-01 23:39:18 -08:00
@@ -98,7 +98,7 @@
 #endif				/* CONFIG_IBM_EMAC4 */
 #define EMAC_M1_BASE			(EMAC_M1_TX_FIFO_2K | \
 					EMAC_M1_APP | \
-					EMAC_M1_TR)
+					EMAC_M1_TR | EMAC_M1_VLE)
 
 /* Transmit Mode Register 0 */
 #define EMAC_TMR0_GNP0			0x80000000
diff -Nru 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	2005-03-01 23:38:51 -08:00
+++ b/drivers/net/ibm_emac/ibm_emac_core.c	2005-03-01 23:38:51 -08:00
@@ -475,8 +475,9 @@
 
 	out_be32(&emacp->em0stacr, stacr);
 
-	while (((stacr = in_be32(&emacp->em0stacr) & EMAC_STACR_OC) == 0)
-					&& (count++ < 5000))
+	count = 0;
+	while ((((stacr = in_be32(&emacp->em0stacr)) & EMAC_STACR_OC) == 0)
+					&& (count++ < MDIO_DELAY))
 		udelay(1);
 	MDIO_DEBUG((" (count was %d)\n", count));
 
@@ -912,7 +913,6 @@
 		PKT_DEBUG(("emac_start_xmit() stopping queue\n"));
 		netif_stop_queue(dev);
 		spin_unlock_irqrestore(&fep->lock, flags);
-		restore_flags(flags);
 		return -EBUSY;
 	}
 
@@ -1281,7 +1281,7 @@
 	/* Format the receive descriptor ring. */
 	ep->rx_slot = 0;
 	/* Default is MTU=1500 + Ethernet overhead */
-	ep->rx_buffer_size = ENET_DEF_BUF_SIZE;
+	ep->rx_buffer_size = dev->mtu + ENET_HEADER_SIZE + ENET_FCS_SIZE;
 	emac_rx_fill(dev, 0);
 	if (ep->rx_slot != 0) {
 		printk(KERN_ERR
@@ -1363,6 +1363,9 @@
 
 	/* set frame gap */
 	out_be32(&emacp->em0ipgvr, CONFIG_IBM_EMAC_FGAP);
+	
+	/* set VLAN Tag Protocol Identifier */
+	out_be32(&emacp->em0vtpid, 0x8100);
 
 	/* Init ring buffers */
 	emac_init_rings(fep->ndev);
@@ -1700,6 +1703,15 @@
 	.rxde = &emac_rxde_dev,
 };
 
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static int emac_netpoll(struct net_device *ndev)
+{
+	emac_rxeob_dev((void *)ndev, 0);
+	emac_txeob_dev((void *)ndev, 0);
+	return 0;
+}
+#endif
+
 static int emac_init_device(struct ocp_device *ocpdev, struct ibm_ocp_mal *mal)
 {
 	int deferred_init = 0;
@@ -1882,6 +1894,9 @@
 	SET_ETHTOOL_OPS(ndev, &emac_ethtool_ops);
 	if (emacdata->tah_idx >= 0)
 		ndev->features = NETIF_F_IP_CSUM | NETIF_F_SG;
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	ndev->poll_controller = emac_netpoll;
+#endif
 
 	SET_MODULE_OWNER(ndev);
 
diff -Nru a/drivers/net/ibm_emac/ibm_emac_core.h b/drivers/net/ibm_emac/ibm_emac_core.h
--- a/drivers/net/ibm_emac/ibm_emac_core.h	2005-03-01 23:38:53 -08:00
+++ b/drivers/net/ibm_emac/ibm_emac_core.h	2005-03-01 23:38:53 -08:00
@@ -77,8 +77,6 @@
 
 #define ENET_HEADER_SIZE	14
 #define ENET_FCS_SIZE		4
-#define ENET_DEF_MTU_SIZE	1500
-#define ENET_DEF_BUF_SIZE	(ENET_DEF_MTU_SIZE + ENET_HEADER_SIZE + ENET_FCS_SIZE)
 #define EMAC_MIN_FRAME		64
 #define EMAC_MAX_FRAME		9018
 #define EMAC_MIN_MTU		(EMAC_MIN_FRAME - ENET_HEADER_SIZE - ENET_FCS_SIZE)
diff -Nru a/drivers/net/ibm_emac/ibm_emac_mal.c b/drivers/net/ibm_emac/ibm_emac_mal.c
--- a/drivers/net/ibm_emac/ibm_emac_mal.c	2005-03-01 23:39:10 -08:00
+++ b/drivers/net/ibm_emac/ibm_emac_mal.c	2005-03-01 23:39:10 -08:00
@@ -33,7 +33,7 @@
 /* This lock protects the commac list. On today UP implementations, it's
  * really only used as IRQ protection in mal_{register,unregister}_commac()
  */
-static rwlock_t mal_list_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(mal_list_lock);
 
 int mal_register_commac(struct ibm_ocp_mal *mal, struct mal_commac *commac)
 {
diff -Nru a/drivers/net/ibm_emac/ibm_emac_phy.c b/drivers/net/ibm_emac/ibm_emac_phy.c
--- a/drivers/net/ibm_emac/ibm_emac_phy.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/net/ibm_emac/ibm_emac_phy.c	2005-03-01 23:39:07 -08:00
@@ -191,17 +191,18 @@
 	u16 lpa;
 
 	if (phy->autoneg) {
-		lpa = phy_read(phy, MII_LPA);
+		lpa = phy_read(phy, MII_LPA) & phy_read(phy, MII_ADVERTISE);
 
-		if (lpa & (LPA_10FULL | LPA_100FULL))
-			phy->duplex = DUPLEX_FULL;
-		else
-			phy->duplex = DUPLEX_HALF;
-		if (lpa & (LPA_100FULL | LPA_100HALF))
-			phy->speed = SPEED_100;
-		else
-			phy->speed = SPEED_10;
+		phy->speed = SPEED_10;
+		phy->duplex = DUPLEX_HALF;
 		phy->pause = 0;
+
+		if (lpa & (LPA_100FULL | LPA_100HALF)) {
+			phy->speed = SPEED_100;
+			if (lpa & LPA_100FULL)
+				phy->duplex = DUPLEX_FULL;
+		} else if (lpa & LPA_10FULL)
+			phy->duplex = DUPLEX_FULL;
 	}
 	/* On non-aneg, we assume what we put in BMCR is the speed,
 	 * though magic-aneg shouldn't prevent this case from occurring
diff -Nru a/drivers/net/ibmlana.c b/drivers/net/ibmlana.c
--- a/drivers/net/ibmlana.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/net/ibmlana.c	2005-03-01 23:38:53 -08:00
@@ -1020,8 +1020,8 @@
 static int irq;
 static int io;
 
-MODULE_PARM(irq, "i");
-MODULE_PARM(io, "i");
+module_param(irq, int, 0);
+module_param(io, int, 0);
 MODULE_PARM_DESC(irq, "IBM LAN/A IRQ number");
 MODULE_PARM_DESC(io, "IBM LAN/A I/O base address");
 MODULE_LICENSE("GPL");
diff -Nru a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c
--- a/drivers/net/ibmveth.c	2005-03-01 23:38:44 -08:00
+++ b/drivers/net/ibmveth.c	2005-03-01 23:38:44 -08:00
@@ -218,7 +218,8 @@
 		ibmveth_assert(index != IBM_VETH_INVALID_MAP);
 		ibmveth_assert(pool->skbuff[index] == NULL);
 
-		dma_addr = vio_map_single(adapter->vdev, skb->data, pool->buff_size, DMA_FROM_DEVICE);
+		dma_addr = dma_map_single(&adapter->vdev->dev, skb->data,
+				pool->buff_size, DMA_FROM_DEVICE);
 
 		pool->free_map[free_index] = IBM_VETH_INVALID_MAP;
 		pool->dma_addr[index] = dma_addr;
@@ -238,7 +239,9 @@
 			pool->free_map[free_index] = IBM_VETH_INVALID_MAP;
 			pool->skbuff[index] = NULL;
 			pool->consumer_index--;
-			vio_unmap_single(adapter->vdev, pool->dma_addr[index], pool->buff_size, DMA_FROM_DEVICE);
+			dma_unmap_single(&adapter->vdev->dev,
+					pool->dma_addr[index], pool->buff_size,
+					DMA_FROM_DEVICE);
 			dev_kfree_skb_any(skb);
 			adapter->replenish_add_buff_failure++;
 			break;
@@ -260,6 +263,15 @@
 		(atomic_read(&adapter->rx_buff_pool[2].available) < adapter->rx_buff_pool[2].threshold));
 }
 
+/* kick the replenish tasklet if we need replenishing and it isn't already running */
+static inline void ibmveth_schedule_replenishing(struct ibmveth_adapter *adapter)
+{
+	if(ibmveth_is_replenishing_needed(adapter) &&
+	   (atomic_dec_if_positive(&adapter->not_replenishing) == 0)) {
+		schedule_work(&adapter->replenish_task);
+	}
+}
+
 /* replenish tasklet routine */
 static void ibmveth_replenish_task(struct ibmveth_adapter *adapter) 
 {
@@ -276,15 +288,6 @@
 	ibmveth_schedule_replenishing(adapter);
 }
 
-/* kick the replenish tasklet if we need replenishing and it isn't already running */
-static inline void ibmveth_schedule_replenishing(struct ibmveth_adapter *adapter)
-{
-	if(ibmveth_is_replenishing_needed(adapter) && 
-	   (atomic_dec_if_positive(&adapter->not_replenishing) == 0)) {	
-		schedule_work(&adapter->replenish_task);
-	}
-}
-
 /* empty and free ana buffer pool - also used to do cleanup in error paths */
 static void ibmveth_free_buffer_pool(struct ibmveth_adapter *adapter, struct ibmveth_buff_pool *pool)
 {
@@ -299,7 +302,7 @@
 		for(i = 0; i < pool->size; ++i) {
 			struct sk_buff *skb = pool->skbuff[i];
 			if(skb) {
-				vio_unmap_single(adapter->vdev,
+				dma_unmap_single(&adapter->vdev->dev,
 						 pool->dma_addr[i],
 						 pool->buff_size,
 						 DMA_FROM_DEVICE);
@@ -337,7 +340,7 @@
 
 	adapter->rx_buff_pool[pool].skbuff[index] = NULL;
 
-	vio_unmap_single(adapter->vdev,
+	dma_unmap_single(&adapter->vdev->dev,
 			 adapter->rx_buff_pool[pool].dma_addr[index],
 			 adapter->rx_buff_pool[pool].buff_size,
 			 DMA_FROM_DEVICE);
@@ -408,7 +411,9 @@
 {
 	if(adapter->buffer_list_addr != NULL) {
 		if(!dma_mapping_error(adapter->buffer_list_dma)) {
-			vio_unmap_single(adapter->vdev, adapter->buffer_list_dma, 4096, DMA_BIDIRECTIONAL);
+			dma_unmap_single(&adapter->vdev->dev,
+					adapter->buffer_list_dma, 4096,
+					DMA_BIDIRECTIONAL);
 			adapter->buffer_list_dma = DMA_ERROR_CODE;
 		}
 		free_page((unsigned long)adapter->buffer_list_addr);
@@ -417,7 +422,9 @@
 
 	if(adapter->filter_list_addr != NULL) {
 		if(!dma_mapping_error(adapter->filter_list_dma)) {
-			vio_unmap_single(adapter->vdev, adapter->filter_list_dma, 4096, DMA_BIDIRECTIONAL);
+			dma_unmap_single(&adapter->vdev->dev,
+					adapter->filter_list_dma, 4096,
+					DMA_BIDIRECTIONAL);
 			adapter->filter_list_dma = DMA_ERROR_CODE;
 		}
 		free_page((unsigned long)adapter->filter_list_addr);
@@ -426,7 +433,10 @@
 
 	if(adapter->rx_queue.queue_addr != NULL) {
 		if(!dma_mapping_error(adapter->rx_queue.queue_dma)) {
-			vio_unmap_single(adapter->vdev, adapter->rx_queue.queue_dma, adapter->rx_queue.queue_len, DMA_BIDIRECTIONAL);
+			dma_unmap_single(&adapter->vdev->dev,
+					adapter->rx_queue.queue_dma,
+					adapter->rx_queue.queue_len,
+					DMA_BIDIRECTIONAL);
 			adapter->rx_queue.queue_dma = DMA_ERROR_CODE;
 		}
 		kfree(adapter->rx_queue.queue_addr);
@@ -472,9 +482,13 @@
 		return -ENOMEM;
 	}
 
-	adapter->buffer_list_dma = vio_map_single(adapter->vdev, adapter->buffer_list_addr, 4096, DMA_BIDIRECTIONAL);
-	adapter->filter_list_dma = vio_map_single(adapter->vdev, adapter->filter_list_addr, 4096, DMA_BIDIRECTIONAL);
-	adapter->rx_queue.queue_dma = vio_map_single(adapter->vdev, adapter->rx_queue.queue_addr, adapter->rx_queue.queue_len, DMA_BIDIRECTIONAL);
+	adapter->buffer_list_dma = dma_map_single(&adapter->vdev->dev,
+			adapter->buffer_list_addr, 4096, DMA_BIDIRECTIONAL);
+	adapter->filter_list_dma = dma_map_single(&adapter->vdev->dev,
+			adapter->filter_list_addr, 4096, DMA_BIDIRECTIONAL);
+	adapter->rx_queue.queue_dma = dma_map_single(&adapter->vdev->dev,
+			adapter->rx_queue.queue_addr,
+			adapter->rx_queue.queue_len, DMA_BIDIRECTIONAL);
 
 	if((dma_mapping_error(adapter->buffer_list_dma) ) ||
 	   (dma_mapping_error(adapter->filter_list_dma)) ||
@@ -644,7 +658,7 @@
 
 	/* map the initial fragment */
 	desc[0].fields.length  = nfrags ? skb->len - skb->data_len : skb->len;
-	desc[0].fields.address = vio_map_single(adapter->vdev, skb->data,
+	desc[0].fields.address = dma_map_single(&adapter->vdev->dev, skb->data,
 					desc[0].fields.length, DMA_TO_DEVICE);
 	desc[0].fields.valid   = 1;
 
@@ -662,7 +676,7 @@
 	while(curfrag--) {
 		skb_frag_t *frag = &skb_shinfo(skb)->frags[curfrag];
 		desc[curfrag+1].fields.address
-			= vio_map_single(adapter->vdev,
+			= dma_map_single(&adapter->vdev->dev,
 				page_address(frag->page) + frag->page_offset,
 				frag->size, DMA_TO_DEVICE);
 		desc[curfrag+1].fields.length = frag->size;
@@ -674,7 +688,7 @@
 			adapter->stats.tx_dropped++;
 			/* Free all the mappings we just created */
 			while(curfrag < nfrags) {
-				vio_unmap_single(adapter->vdev,
+				dma_unmap_single(&adapter->vdev->dev,
 						 desc[curfrag+1].fields.address,
 						 desc[curfrag+1].fields.length,
 						 DMA_TO_DEVICE);
@@ -714,7 +728,9 @@
 	}
 
 	do {
-		vio_unmap_single(adapter->vdev, desc[nfrags].fields.address, desc[nfrags].fields.length, DMA_TO_DEVICE);
+		dma_unmap_single(&adapter->vdev->dev,
+				desc[nfrags].fields.address,
+				desc[nfrags].fields.length, DMA_TO_DEVICE);
 	} while(--nfrags >= 0);
 
 	dev_kfree_skb(skb);
diff -Nru a/drivers/net/irda/ali-ircc.c b/drivers/net/irda/ali-ircc.c
--- a/drivers/net/irda/ali-ircc.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/net/irda/ali-ircc.c	2005-03-01 23:38:56 -08:00
@@ -2264,11 +2264,11 @@
 MODULE_LICENSE("GPL");
 
 
-MODULE_PARM(io,  "1-4i");
+module_param_array(io, int, NULL, 0);
 MODULE_PARM_DESC(io, "Base I/O addresses");
-MODULE_PARM(irq, "1-4i");
+module_param_array(irq, int, NULL, 0);
 MODULE_PARM_DESC(irq, "IRQ lines");
-MODULE_PARM(dma, "1-4i");
+module_param_array(dma, int, NULL, 0);
 MODULE_PARM_DESC(dma, "DMA channels");
 
 module_init(ali_ircc_init);
diff -Nru a/drivers/net/irda/au1k_ir.c b/drivers/net/irda/au1k_ir.c
--- a/drivers/net/irda/au1k_ir.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/net/irda/au1k_ir.c	2005-03-01 23:39:09 -08:00
@@ -72,7 +72,7 @@
 static BCSR * const bcsr = (BCSR *)0xAE000000;
 #endif
 
-static spinlock_t ir_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(ir_lock);
 
 /*
  * IrDA peripheral bug. You have to read the register
diff -Nru a/drivers/net/irda/donauboe.c b/drivers/net/irda/donauboe.c
--- a/drivers/net/irda/donauboe.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/net/irda/donauboe.c	2005-03-01 23:38:56 -08:00
@@ -1493,11 +1493,11 @@
 MODULE_AUTHOR("James McKenzie <james@fishsoup.dhs.org>");
 MODULE_LICENSE("GPL");
 
-MODULE_PARM (max_baud, "i");
+module_param (max_baud, int, 0);
 MODULE_PARM_DESC(max_baud, "Maximum baud rate");
 
 #ifdef USE_PROBE
-MODULE_PARM (do_probe, "i");
+module_param (do_probe, bool, 0);
 MODULE_PARM_DESC(do_probe, "Enable/disable chip probing and self-test");
 #endif
 
diff -Nru a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c
--- a/drivers/net/irda/irda-usb.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/net/irda/irda-usb.c	2005-03-01 23:38:57 -08:00
@@ -1220,7 +1220,7 @@
 		ep = endpoint[i].desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
 		dir = endpoint[i].desc.bEndpointAddress & USB_ENDPOINT_DIR_MASK;
 		attr = endpoint[i].desc.bmAttributes;
-		psize = endpoint[i].desc.wMaxPacketSize;
+		psize = le16_to_cpu(endpoint[i].desc.wMaxPacketSize);
 
 		/* Is it a bulk endpoint ??? */
 		if(attr == USB_ENDPOINT_XFER_BULK) {
@@ -1360,8 +1360,8 @@
 	 * Jean II */
 
 	MESSAGE("IRDA-USB found at address %d, Vendor: %x, Product: %x\n",
-		dev->devnum, dev->descriptor.idVendor,
-		dev->descriptor.idProduct);
+		dev->devnum, le16_to_cpu(dev->descriptor.idVendor),
+		le16_to_cpu(dev->descriptor.idProduct));
 
 	net = alloc_irdadev(sizeof(*self));
 	if (!net) 
diff -Nru a/drivers/net/irda/irtty-sir.c b/drivers/net/irda/irtty-sir.c
--- a/drivers/net/irda/irtty-sir.c	2005-03-01 23:38:43 -08:00
+++ b/drivers/net/irda/irtty-sir.c	2005-03-01 23:38:43 -08:00
@@ -39,10 +39,10 @@
 #include "sir-dev.h"
 #include "irtty-sir.h"
 
-MODULE_PARM(qos_mtt_bits, "i");
-MODULE_PARM_DESC(qos_mtt_bits, "Minimum Turn Time");
-
 static int qos_mtt_bits = 0x03;      /* 5 ms or more */
+
+module_param(qos_mtt_bits, int, 0);
+MODULE_PARM_DESC(qos_mtt_bits, "Minimum Turn Time");
 
 /* ------------------------------------------------------- */
 
diff -Nru a/drivers/net/irda/nsc-ircc.c b/drivers/net/irda/nsc-ircc.c
--- a/drivers/net/irda/nsc-ircc.c	2005-03-01 23:38:44 -08:00
+++ b/drivers/net/irda/nsc-ircc.c	2005-03-01 23:38:44 -08:00
@@ -2206,15 +2206,15 @@
 MODULE_LICENSE("GPL");
 
 
-MODULE_PARM(qos_mtt_bits, "i");
+module_param(qos_mtt_bits, int, 0);
 MODULE_PARM_DESC(qos_mtt_bits, "Minimum Turn Time");
-MODULE_PARM(io,  "1-4i");
+module_param_array(io, int, NULL, 0);
 MODULE_PARM_DESC(io, "Base I/O addresses");
-MODULE_PARM(irq, "1-4i");
+module_param_array(irq, int, NULL, 0);
 MODULE_PARM_DESC(irq, "IRQ lines");
-MODULE_PARM(dma, "1-4i");
+module_param_array(dma, int, NULL, 0);
 MODULE_PARM_DESC(dma, "DMA channels");
-MODULE_PARM(dongle_id, "i");
+module_param(dongle_id, int, 0);
 MODULE_PARM_DESC(dongle_id, "Type-id of used dongle");
 
 module_init(nsc_ircc_init);
diff -Nru a/drivers/net/irda/sir_kthread.c b/drivers/net/irda/sir_kthread.c
--- a/drivers/net/irda/sir_kthread.c	2005-03-01 23:39:19 -08:00
+++ b/drivers/net/irda/sir_kthread.c	2005-03-01 23:39:19 -08:00
@@ -19,7 +19,6 @@
 #include <linux/smp_lock.h>
 #include <linux/completion.h>
 #include <linux/delay.h>
-#include <linux/suspend.h>
 
 #include <net/irda/irda.h>
 
diff -Nru a/drivers/net/irda/smsc-ircc2.c b/drivers/net/irda/smsc-ircc2.c
--- a/drivers/net/irda/smsc-ircc2.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/net/irda/smsc-ircc2.c	2005-03-01 23:39:07 -08:00
@@ -2378,15 +2378,15 @@
 MODULE_DESCRIPTION("SMC IrCC SIR/FIR controller driver");
 MODULE_LICENSE("GPL");
 
-MODULE_PARM(ircc_dma, "1i");
+module_param(ircc_dma, int, 0);
 MODULE_PARM_DESC(ircc_dma, "DMA channel");
-MODULE_PARM(ircc_irq, "1i");
+module_param(ircc_irq, int, 0);
 MODULE_PARM_DESC(ircc_irq, "IRQ line");
-MODULE_PARM(ircc_fir, "1-4i");
+module_param(ircc_fir, int, 0);
 MODULE_PARM_DESC(ircc_fir, "FIR Base Address");
-MODULE_PARM(ircc_sir, "1-4i");
+module_param(ircc_sir, int, 0);
 MODULE_PARM_DESC(ircc_sir, "SIR Base Address");
-MODULE_PARM(ircc_cfg, "1-4i");
+module_param(ircc_cfg, int, 0);
 MODULE_PARM_DESC(ircc_cfg, "Configuration register base address");
-MODULE_PARM(ircc_transceiver, "1i");
+module_param(ircc_transceiver, int, 0);
 MODULE_PARM_DESC(ircc_transceiver, "Transceiver type");
diff -Nru a/drivers/net/irda/stir4200.c b/drivers/net/irda/stir4200.c
--- a/drivers/net/irda/stir4200.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/net/irda/stir4200.c	2005-03-01 23:38:54 -08:00
@@ -46,7 +46,6 @@
 #include <linux/time.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
-#include <linux/suspend.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/usb.h>
@@ -1072,8 +1071,8 @@
 
 	printk(KERN_INFO "SigmaTel STIr4200 IRDA/USB found at address %d, "
 		"Vendor: %x, Product: %x\n",
-	       dev->devnum, dev->descriptor.idVendor,
-	       dev->descriptor.idProduct);
+	       dev->devnum, le16_to_cpu(dev->descriptor.idVendor),
+	       le16_to_cpu(dev->descriptor.idProduct));
 
 	/* Initialize QoS for this device */
 	irda_init_max_qos_capabilies(&stir->qos);
diff -Nru a/drivers/net/irda/tekram-sir.c b/drivers/net/irda/tekram-sir.c
--- a/drivers/net/irda/tekram-sir.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/net/irda/tekram-sir.c	2005-03-01 23:38:54 -08:00
@@ -32,9 +32,9 @@
 
 #include "sir-dev.h"
 
-MODULE_PARM(tekram_delay, "i");
-MODULE_PARM_DESC(tekram_delay, "tekram dongle write complete delay");
 static int tekram_delay = 150;		/* default is 150 ms */
+module_param(tekram_delay, int, 0);
+MODULE_PARM_DESC(tekram_delay, "tekram dongle write complete delay");
 
 static int tekram_open(struct sir_dev *);
 static int tekram_close(struct sir_dev *);
diff -Nru a/drivers/net/irda/via-ircc.c b/drivers/net/irda/via-ircc.c
--- a/drivers/net/irda/via-ircc.c	2005-03-01 23:38:43 -08:00
+++ b/drivers/net/irda/via-ircc.c	2005-03-01 23:38:43 -08:00
@@ -73,7 +73,7 @@
 static int dongle_id = 0;	/* default: probe */
 
 /* We can't guess the type of connected dongle, user *must* supply it. */
-MODULE_PARM(dongle_id, "i");
+module_param(dongle_id, int, 0);
 
 /* FIXME : we should not need this, because instances should be automatically
  * managed by the PCI layer. Especially that we seem to only be using the
diff -Nru a/drivers/net/irda/vlsi_ir.c b/drivers/net/irda/vlsi_ir.c
--- a/drivers/net/irda/vlsi_ir.c	2005-03-01 23:38:51 -08:00
+++ b/drivers/net/irda/vlsi_ir.c	2005-03-01 23:38:51 -08:00
@@ -83,9 +83,9 @@
  *		3: external 40MHz XCLK (HP OB-800)
  */
 
-MODULE_PARM(clksrc, "i");
-MODULE_PARM_DESC(clksrc, "clock input source selection");
 static int clksrc = 0;			/* default is 0(auto) */
+module_param(clksrc, int, 0);
+MODULE_PARM_DESC(clksrc, "clock input source selection");
 
 /*	ringsize: size of the tx and rx descriptor rings
  *		independent for tx and rx
@@ -95,9 +95,9 @@
  *		there should be no gain when using rings larger than 8
  */
 
-MODULE_PARM(ringsize, "1-2i");
-MODULE_PARM_DESC(ringsize, "TX, RX ring descriptor size");
 static int ringsize[] = {8,8};		/* default is tx=8 / rx=8 */
+module_param_array(ringsize, int, NULL, 0);
+MODULE_PARM_DESC(ringsize, "TX, RX ring descriptor size");
 
 /*	sirpulse: tuning of the SIR pulse width within IrPHY 1.3 limits
  *		0: very short, 1.5us (exception: 6us at 2.4 kbaud)
@@ -108,9 +108,9 @@
  *		pulse width saves more than 90% of the transmitted IR power.
  */
 
-MODULE_PARM(sirpulse, "i");
-MODULE_PARM_DESC(sirpulse, "SIR pulse width tuning");
 static int sirpulse = 1;		/* default is 3/16 bittime */
+module_param(sirpulse, int, 0);
+MODULE_PARM_DESC(sirpulse, "SIR pulse width tuning");
 
 /*	qos_mtt_bits: encoded min-turn-time value we require the peer device
  *		 to use before transmitting to us. "Type 1" (per-station)
@@ -119,9 +119,9 @@
  *		 pretty common HP HDLS-1100 requires 1 msec - so lets use this.
  */
 
-MODULE_PARM(qos_mtt_bits, "i");
-MODULE_PARM_DESC(qos_mtt_bits, "IrLAP bitfield representing min-turn-time");
 static int qos_mtt_bits = 0x07;		/* default is 1 ms or more */
+module_param(qos_mtt_bits, int, 0);
+MODULE_PARM_DESC(qos_mtt_bits, "IrLAP bitfield representing min-turn-time");
 
 /********************************************************/
 
diff -Nru a/drivers/net/irda/w83977af_ir.c b/drivers/net/irda/w83977af_ir.c
--- a/drivers/net/irda/w83977af_ir.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/net/irda/w83977af_ir.c	2005-03-01 23:38:55 -08:00
@@ -1355,11 +1355,11 @@
 MODULE_LICENSE("GPL");
 
 
-MODULE_PARM(qos_mtt_bits, "i");
+module_param(qos_mtt_bits, int, 0);
 MODULE_PARM_DESC(qos_mtt_bits, "Mimimum Turn Time");
-MODULE_PARM(io, "1-4i");
+module_param_array(io, int, NULL, 0);
 MODULE_PARM_DESC(io, "Base I/O addresses");
-MODULE_PARM(irq, "1-4i");
+module_param_array(irq, int, NULL, 0);
 MODULE_PARM_DESC(irq, "IRQ lines");
 
 /*
diff -Nru a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c
--- a/drivers/net/iseries_veth.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/net/iseries_veth.c	2005-03-01 23:38:58 -08:00
@@ -642,7 +642,7 @@
 	return 0;
 }
 
-static void veth_destroy_connection(u8 rlp)
+static void veth_stop_connection(u8 rlp)
 {
 	struct veth_lpar_connection *cnx = veth_cnx[rlp];
 
@@ -671,9 +671,18 @@
 				      HvLpEvent_Type_VirtualLan,
 				      cnx->num_ack_events,
 				      NULL, NULL);
+}
+
+static void veth_destroy_connection(u8 rlp)
+{
+	struct veth_lpar_connection *cnx = veth_cnx[rlp];
+
+	if (! cnx)
+		return;
 
-	if (cnx->msgs)
-		kfree(cnx->msgs);
+	kfree(cnx->msgs);
+	kfree(cnx);
+	veth_cnx[rlp] = NULL;
 }
 
 /*
@@ -1375,9 +1384,18 @@
 	vio_unregister_driver(&veth_driver);
 
 	for (i = 0; i < HVMAXARCHITECTEDLPS; ++i)
-		veth_destroy_connection(i);
+		veth_stop_connection(i);
 
 	HvLpEvent_unregisterHandler(HvLpEvent_Type_VirtualLan);
+
+	/* Hypervisor callbacks may have scheduled more work while we
+	 * were destroying connections. Now that we've disconnected from
+	 * the hypervisor make sure everything's finished. */
+	flush_scheduled_work();
+
+	for (i = 0; i < HVMAXARCHITECTEDLPS; ++i)
+		veth_destroy_connection(i);
+
 }
 module_exit(veth_module_cleanup);
 
diff -Nru a/drivers/net/ixgb/ixgb.h b/drivers/net/ixgb/ixgb.h
--- a/drivers/net/ixgb/ixgb.h	2005-03-01 23:38:55 -08:00
+++ b/drivers/net/ixgb/ixgb.h	2005-03-01 23:38:55 -08:00
@@ -46,6 +46,7 @@
 #include <linux/delay.h>
 #include <linux/timer.h>
 #include <linux/slab.h>
+#include <linux/vmalloc.h>
 #include <linux/interrupt.h>
 #include <linux/string.h>
 #include <linux/pagemap.h>
@@ -85,6 +86,20 @@
 
 #define IXGB_ERR(args...) printk(KERN_ERR "ixgb: " args)
 
+/* TX/RX descriptor defines */
+#define DEFAULT_TXD	 256
+#define MAX_TXD   	4096
+#define MIN_TXD	  64
+
+/* hardware cannot reliably support more than 512 descriptors owned by
+ * hardware descrioptor cache otherwise an unreliable ring under heavy 
+ * recieve load may result */
+/* #define DEFAULT_RXD	   1024 */
+/* #define MAX_RXD	   4096 */
+#define DEFAULT_RXD	512
+#define MAX_RXD	512
+#define MIN_RXD	 64
+
 /* Supported Rx Buffer Sizes */
 #define IXGB_RXBUFFER_2048  2048
 #define IXGB_RXBUFFER_4096  4096
@@ -105,9 +120,9 @@
 struct ixgb_buffer {
 	struct sk_buff *skb;
 	uint64_t dma;
-	unsigned long length;
 	unsigned long time_stamp;
-	unsigned int next_to_watch;
+	uint16_t length;
+	uint16_t next_to_watch;
 };
 
 struct ixgb_desc_ring {
@@ -167,7 +182,6 @@
 	uint64_t hw_csum_rx_error;
 	uint64_t hw_csum_rx_good;
 	uint32_t rx_int_delay;
-	boolean_t raidc;
 	boolean_t rx_csum;
 
 	/* OS defined structs */
@@ -178,5 +192,8 @@
 	/* structs defined in ixgb_hw.h */
 	struct ixgb_hw hw;
 	struct ixgb_hw_stats stats;
+#ifdef CONFIG_PCI_MSI
+	boolean_t have_msi;
+#endif
 };
-#endif				/* _IXGB_H_ */
+#endif /* _IXGB_H_ */
diff -Nru a/drivers/net/ixgb/ixgb_ee.c b/drivers/net/ixgb/ixgb_ee.c
--- a/drivers/net/ixgb/ixgb_ee.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/net/ixgb/ixgb_ee.c	2005-03-01 23:39:18 -08:00
@@ -32,7 +32,8 @@
 static uint16_t ixgb_shift_in_bits(struct ixgb_hw *hw);
 
 static void ixgb_shift_out_bits(struct ixgb_hw *hw,
-				uint16_t data, uint16_t count);
+				uint16_t data,
+				uint16_t count);
 static void ixgb_standby_eeprom(struct ixgb_hw *hw);
 
 static boolean_t ixgb_wait_eeprom_command(struct ixgb_hw *hw);
@@ -45,7 +46,9 @@
  * hw - Struct containing variables accessed by shared code
  * eecd_reg - EECD's current value
  *****************************************************************************/
-static void ixgb_raise_clock(struct ixgb_hw *hw, uint32_t * eecd_reg)
+static void
+ixgb_raise_clock(struct ixgb_hw *hw,
+		  uint32_t *eecd_reg)
 {
 	/* Raise the clock input to the EEPROM (by setting the SK bit), and then
 	 *  wait 50 microseconds.
@@ -62,7 +65,9 @@
  * hw - Struct containing variables accessed by shared code
  * eecd_reg - EECD's current value
  *****************************************************************************/
-static void ixgb_lower_clock(struct ixgb_hw *hw, uint32_t * eecd_reg)
+static void
+ixgb_lower_clock(struct ixgb_hw *hw,
+		  uint32_t *eecd_reg)
 {
 	/* Lower the clock input to the EEPROM (by clearing the SK bit), and then
 	 * wait 50 microseconds.
@@ -81,7 +86,9 @@
  * count - number of bits to shift out
  *****************************************************************************/
 static void
-ixgb_shift_out_bits(struct ixgb_hw *hw, uint16_t data, uint16_t count)
+ixgb_shift_out_bits(struct ixgb_hw *hw,
+					 uint16_t data,
+					 uint16_t count)
 {
 	uint32_t eecd_reg;
 	uint32_t mask;
@@ -101,7 +108,7 @@
 		 */
 		eecd_reg &= ~IXGB_EECD_DI;
 
-		if (data & mask)
+		if(data & mask)
 			eecd_reg |= IXGB_EECD_DI;
 
 		IXGB_WRITE_REG(hw, EECD, eecd_reg);
@@ -113,7 +120,7 @@
 
 		mask = mask >> 1;
 
-	} while (mask);
+	} while(mask);
 
 	/* We leave the "DI" bit set to "0" when we leave this routine. */
 	eecd_reg &= ~IXGB_EECD_DI;
@@ -126,7 +133,8 @@
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-static uint16_t ixgb_shift_in_bits(struct ixgb_hw *hw)
+static uint16_t
+ixgb_shift_in_bits(struct ixgb_hw *hw)
 {
 	uint32_t eecd_reg;
 	uint32_t i;
@@ -144,14 +152,14 @@
 	eecd_reg &= ~(IXGB_EECD_DO | IXGB_EECD_DI);
 	data = 0;
 
-	for (i = 0; i < 16; i++) {
+	for(i = 0; i < 16; i++) {
 		data = data << 1;
 		ixgb_raise_clock(hw, &eecd_reg);
 
 		eecd_reg = IXGB_READ_REG(hw, EECD);
 
 		eecd_reg &= ~(IXGB_EECD_DI);
-		if (eecd_reg & IXGB_EECD_DO)
+		if(eecd_reg & IXGB_EECD_DO)
 			data |= 1;
 
 		ixgb_lower_clock(hw, &eecd_reg);
@@ -168,7 +176,8 @@
  * Lowers EEPROM clock. Clears input pin. Sets the chip select pin. This
  * function should be called before issuing a command to the EEPROM.
  *****************************************************************************/
-static void ixgb_setup_eeprom(struct ixgb_hw *hw)
+static void
+ixgb_setup_eeprom(struct ixgb_hw *hw)
 {
 	uint32_t eecd_reg;
 
@@ -189,7 +198,8 @@
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-static void ixgb_standby_eeprom(struct ixgb_hw *hw)
+static void
+ixgb_standby_eeprom(struct ixgb_hw *hw)
 {
 	uint32_t eecd_reg;
 
@@ -222,7 +232,8 @@
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-static void ixgb_clock_eeprom(struct ixgb_hw *hw)
+static void
+ixgb_clock_eeprom(struct ixgb_hw *hw)
 {
 	uint32_t eecd_reg;
 
@@ -245,7 +256,8 @@
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-static void ixgb_cleanup_eeprom(struct ixgb_hw *hw)
+static void
+ixgb_cleanup_eeprom(struct ixgb_hw *hw)
 {
 	uint32_t eecd_reg;
 
@@ -270,7 +282,8 @@
  *      TRUE: EEPROM data pin is high before timeout.
  *      FALSE:  Time expired.
  *****************************************************************************/
-static boolean_t ixgb_wait_eeprom_command(struct ixgb_hw *hw)
+static boolean_t
+ixgb_wait_eeprom_command(struct ixgb_hw *hw)
 {
 	uint32_t eecd_reg;
 	uint32_t i;
@@ -284,10 +297,10 @@
 	 * signal that the command has been completed by raising the DO signal.
 	 * If DO does not go high in 10 milliseconds, then error out.
 	 */
-	for (i = 0; i < 200; i++) {
+	for(i = 0; i < 200; i++) {
 		eecd_reg = IXGB_READ_REG(hw, EECD);
 
-		if (eecd_reg & IXGB_EECD_DO)
+		if(eecd_reg & IXGB_EECD_DO)
 			return (TRUE);
 
 		udelay(50);
@@ -309,15 +322,16 @@
  *  TRUE: Checksum is valid
  *  FALSE: Checksum is not valid.
  *****************************************************************************/
-boolean_t ixgb_validate_eeprom_checksum(struct ixgb_hw * hw)
+boolean_t
+ixgb_validate_eeprom_checksum(struct ixgb_hw *hw)
 {
 	uint16_t checksum = 0;
 	uint16_t i;
 
-	for (i = 0; i < (EEPROM_CHECKSUM_REG + 1); i++)
+	for(i = 0; i < (EEPROM_CHECKSUM_REG + 1); i++)
 		checksum += ixgb_read_eeprom(hw, i);
 
-	if (checksum == (uint16_t) EEPROM_SUM)
+	if(checksum == (uint16_t) EEPROM_SUM)
 		return (TRUE);
 	else
 		return (FALSE);
@@ -331,12 +345,13 @@
  * Sums the first 63 16 bit words of the EEPROM. Subtracts the sum from 0xBABA.
  * Writes the difference to word offset 63 of the EEPROM.
  *****************************************************************************/
-void ixgb_update_eeprom_checksum(struct ixgb_hw *hw)
+void
+ixgb_update_eeprom_checksum(struct ixgb_hw *hw)
 {
 	uint16_t checksum = 0;
 	uint16_t i;
 
-	for (i = 0; i < EEPROM_CHECKSUM_REG; i++)
+	for(i = 0; i < EEPROM_CHECKSUM_REG; i++)
 		checksum += ixgb_read_eeprom(hw, i);
 
 	checksum = (uint16_t) EEPROM_SUM - checksum;
@@ -356,7 +371,10 @@
  * EEPROM will most likely contain an invalid checksum.
  *
  *****************************************************************************/
-void ixgb_write_eeprom(struct ixgb_hw *hw, uint16_t offset, uint16_t data)
+void
+ixgb_write_eeprom(struct ixgb_hw *hw,
+		   uint16_t offset,
+		   uint16_t data)
 {
 	/*  Prepare the EEPROM for writing  */
 	ixgb_setup_eeprom(hw);
@@ -404,7 +422,9 @@
  * Returns:
  *  The 16-bit value read from the eeprom
  *****************************************************************************/
-uint16_t ixgb_read_eeprom(struct ixgb_hw * hw, uint16_t offset)
+uint16_t
+ixgb_read_eeprom(struct ixgb_hw *hw,
+		  uint16_t offset)
 {
 	uint16_t data;
 
@@ -437,7 +457,8 @@
  *      TRUE: if eeprom read is successful
  *      FALSE: otherwise.
  *****************************************************************************/
-boolean_t ixgb_get_eeprom_data(struct ixgb_hw * hw)
+boolean_t
+ixgb_get_eeprom_data(struct ixgb_hw *hw)
 {
 	uint16_t i;
 	uint16_t checksum = 0;
@@ -448,7 +469,7 @@
 	ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
 
 	DEBUGOUT("ixgb_ee: Reading eeprom data\n");
-	for (i = 0; i < IXGB_EEPROM_SIZE; i++) {
+	for(i = 0; i < IXGB_EEPROM_SIZE ; i++) {
 		uint16_t ee_data;
 		ee_data = ixgb_read_eeprom(hw, i);
 		checksum += ee_data;
@@ -461,12 +482,12 @@
 	}
 
 	if ((ee_map->init_ctrl_reg_1 & le16_to_cpu(EEPROM_ICW1_SIGNATURE_MASK))
-	    != le16_to_cpu(EEPROM_ICW1_SIGNATURE_VALID)) {
+		 != le16_to_cpu(EEPROM_ICW1_SIGNATURE_VALID)) {
 		DEBUGOUT("ixgb_ee: Signature invalid.\n");
-		return (FALSE);
+		return(FALSE);
 	}
 
-	return (TRUE);
+	return(TRUE);
 }
 
 /******************************************************************************
@@ -479,7 +500,8 @@
  *      TRUE: eeprom signature was good and the eeprom read was successful
  *      FALSE: otherwise.
  ******************************************************************************/
-static boolean_t ixgb_check_and_get_eeprom_data(struct ixgb_hw *hw)
+static boolean_t
+ixgb_check_and_get_eeprom_data (struct ixgb_hw* hw)
 {
 	struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
 
@@ -500,15 +522,16 @@
  * Returns:
  *          Word at indexed offset in eeprom, if valid, 0 otherwise.
  ******************************************************************************/
-uint16_t ixgb_get_eeprom_word(struct ixgb_hw * hw, uint16_t index)
+uint16_t
+ixgb_get_eeprom_word(struct ixgb_hw *hw, uint16_t index)
 {
 
 	if ((index < IXGB_EEPROM_SIZE) &&
-	    (ixgb_check_and_get_eeprom_data(hw) == TRUE)) {
-		return (hw->eeprom[index]);
+		(ixgb_check_and_get_eeprom_data(hw) == TRUE)) {
+	   return(hw->eeprom[index]);
 	}
 
-	return (0);
+	return(0);
 }
 
 /******************************************************************************
@@ -519,7 +542,9 @@
  *
  * Returns: None.
  ******************************************************************************/
-void ixgb_get_ee_mac_addr(struct ixgb_hw *hw, uint8_t * mac_addr)
+void
+ixgb_get_ee_mac_addr(struct ixgb_hw *hw,
+			uint8_t *mac_addr)
 {
 	int i;
 	struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
@@ -542,14 +567,15 @@
  * Returns:
  *          compatibility flags if EEPROM contents are valid, 0 otherwise
  ******************************************************************************/
-uint16_t ixgb_get_ee_compatibility(struct ixgb_hw *hw)
+uint16_t
+ixgb_get_ee_compatibility(struct ixgb_hw *hw)
 {
 	struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
 
-	if (ixgb_check_and_get_eeprom_data(hw) == TRUE)
-		return (ee_map->compatibility);
+	if(ixgb_check_and_get_eeprom_data(hw) == TRUE)
+		return(ee_map->compatibility);
 
-	return (0);
+	return(0);
 }
 
 /******************************************************************************
@@ -560,13 +586,14 @@
  * Returns:
  *          PBA number if EEPROM contents are valid, 0 otherwise
  ******************************************************************************/
-uint32_t ixgb_get_ee_pba_number(struct ixgb_hw * hw)
+uint32_t
+ixgb_get_ee_pba_number(struct ixgb_hw *hw)
 {
-	if (ixgb_check_and_get_eeprom_data(hw) == TRUE)
+	if(ixgb_check_and_get_eeprom_data(hw) == TRUE)
 		return (le16_to_cpu(hw->eeprom[EEPROM_PBA_1_2_REG])
-			| (le16_to_cpu(hw->eeprom[EEPROM_PBA_3_4_REG]) << 16));
+			| (le16_to_cpu(hw->eeprom[EEPROM_PBA_3_4_REG])<<16));
 
-	return (0);
+	return(0);
 }
 
 /******************************************************************************
@@ -577,14 +604,15 @@
  * Returns:
  *          Initialization Control Word 1 if EEPROM contents are valid, 0 otherwise
  ******************************************************************************/
-uint16_t ixgb_get_ee_init_ctrl_reg_1(struct ixgb_hw * hw)
+uint16_t
+ixgb_get_ee_init_ctrl_reg_1(struct ixgb_hw *hw)
 {
 	struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
 
-	if (ixgb_check_and_get_eeprom_data(hw) == TRUE)
-		return (ee_map->init_ctrl_reg_1);
+	if(ixgb_check_and_get_eeprom_data(hw) == TRUE)
+		return(ee_map->init_ctrl_reg_1);
 
-	return (0);
+	return(0);
 }
 
 /******************************************************************************
@@ -595,14 +623,15 @@
  * Returns:
  *          Initialization Control Word 2 if EEPROM contents are valid, 0 otherwise
  ******************************************************************************/
-uint16_t ixgb_get_ee_init_ctrl_reg_2(struct ixgb_hw * hw)
+uint16_t
+ixgb_get_ee_init_ctrl_reg_2(struct ixgb_hw *hw)
 {
 	struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
 
-	if (ixgb_check_and_get_eeprom_data(hw) == TRUE)
-		return (ee_map->init_ctrl_reg_2);
+	if(ixgb_check_and_get_eeprom_data(hw) == TRUE)
+		return(ee_map->init_ctrl_reg_2);
 
-	return (0);
+	return(0);
 }
 
 /******************************************************************************
@@ -613,14 +642,15 @@
  * Returns:
  *          Subsystem Id if EEPROM contents are valid, 0 otherwise
  ******************************************************************************/
-uint16_t ixgb_get_ee_subsystem_id(struct ixgb_hw * hw)
+uint16_t
+ixgb_get_ee_subsystem_id(struct ixgb_hw *hw)
 {
 	struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
 
-	if (ixgb_check_and_get_eeprom_data(hw) == TRUE)
-		return (ee_map->subsystem_id);
+	if(ixgb_check_and_get_eeprom_data(hw) == TRUE)
+	   return(ee_map->subsystem_id);
 
-	return (0);
+	return(0);
 }
 
 /******************************************************************************
@@ -631,14 +661,15 @@
  * Returns:
  *          Sub Vendor Id if EEPROM contents are valid, 0 otherwise
  ******************************************************************************/
-uint16_t ixgb_get_ee_subvendor_id(struct ixgb_hw * hw)
+uint16_t
+ixgb_get_ee_subvendor_id(struct ixgb_hw *hw)
 {
 	struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
 
-	if (ixgb_check_and_get_eeprom_data(hw) == TRUE)
-		return (ee_map->subvendor_id);
+	if(ixgb_check_and_get_eeprom_data(hw) == TRUE)
+		return(ee_map->subvendor_id);
 
-	return (0);
+	return(0);
 }
 
 /******************************************************************************
@@ -649,14 +680,15 @@
  * Returns:
  *          Device Id if EEPROM contents are valid, 0 otherwise
  ******************************************************************************/
-uint16_t ixgb_get_ee_device_id(struct ixgb_hw * hw)
+uint16_t
+ixgb_get_ee_device_id(struct ixgb_hw *hw)
 {
 	struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
 
-	if (ixgb_check_and_get_eeprom_data(hw) == TRUE)
-		return (ee_map->device_id);
+	if(ixgb_check_and_get_eeprom_data(hw) == TRUE)
+		return(ee_map->device_id);
 
-	return (0);
+	return(0);
 }
 
 /******************************************************************************
@@ -667,14 +699,15 @@
  * Returns:
  *          Device Id if EEPROM contents are valid, 0 otherwise
  ******************************************************************************/
-uint16_t ixgb_get_ee_vendor_id(struct ixgb_hw * hw)
+uint16_t
+ixgb_get_ee_vendor_id(struct ixgb_hw *hw)
 {
 	struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
 
-	if (ixgb_check_and_get_eeprom_data(hw) == TRUE)
-		return (ee_map->vendor_id);
+	if(ixgb_check_and_get_eeprom_data(hw) == TRUE)
+		return(ee_map->vendor_id);
 
-	return (0);
+	return(0);
 }
 
 /******************************************************************************
@@ -685,14 +718,15 @@
  * Returns:
  *          SDP Register if EEPROM contents are valid, 0 otherwise
  ******************************************************************************/
-uint16_t ixgb_get_ee_swdpins_reg(struct ixgb_hw * hw)
+uint16_t
+ixgb_get_ee_swdpins_reg(struct ixgb_hw *hw)
 {
 	struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
 
-	if (ixgb_check_and_get_eeprom_data(hw) == TRUE)
-		return (ee_map->swdpins_reg);
+	if(ixgb_check_and_get_eeprom_data(hw) == TRUE)
+		return(ee_map->swdpins_reg);
 
-	return (0);
+	return(0);
 }
 
 /******************************************************************************
@@ -703,14 +737,15 @@
  * Returns:
  *          D3 Power Management Bits if EEPROM contents are valid, 0 otherwise
  ******************************************************************************/
-uint8_t ixgb_get_ee_d3_power(struct ixgb_hw * hw)
+uint8_t
+ixgb_get_ee_d3_power(struct ixgb_hw *hw)
 {
 	struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
 
-	if (ixgb_check_and_get_eeprom_data(hw) == TRUE)
-		return (ee_map->d3_power);
+	if(ixgb_check_and_get_eeprom_data(hw) == TRUE)
+		return(ee_map->d3_power);
 
-	return (0);
+	return(0);
 }
 
 /******************************************************************************
@@ -721,12 +756,13 @@
  * Returns:
  *          D0 Power Management Bits if EEPROM contents are valid, 0 otherwise
  ******************************************************************************/
-uint8_t ixgb_get_ee_d0_power(struct ixgb_hw * hw)
+uint8_t
+ixgb_get_ee_d0_power(struct ixgb_hw *hw)
 {
 	struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
 
-	if (ixgb_check_and_get_eeprom_data(hw) == TRUE)
-		return (ee_map->d0_power);
+	if(ixgb_check_and_get_eeprom_data(hw) == TRUE)
+		return(ee_map->d0_power);
 
-	return (0);
+	return(0);
 }
diff -Nru a/drivers/net/ixgb/ixgb_ethtool.c b/drivers/net/ixgb/ixgb_ethtool.c
--- a/drivers/net/ixgb/ixgb_ethtool.c	2005-03-01 23:39:10 -08:00
+++ b/drivers/net/ixgb/ixgb_ethtool.c	2005-03-01 23:39:10 -08:00
@@ -37,6 +37,12 @@
 
 extern int ixgb_up(struct ixgb_adapter *adapter);
 extern void ixgb_down(struct ixgb_adapter *adapter, boolean_t kill_watchdog);
+extern void ixgb_reset(struct ixgb_adapter *adapter);
+extern int ixgb_setup_rx_resources(struct ixgb_adapter *adapter);
+extern int ixgb_setup_tx_resources(struct ixgb_adapter *adapter);
+extern void ixgb_free_rx_resources(struct ixgb_adapter *adapter);
+extern void ixgb_free_tx_resources(struct ixgb_adapter *adapter);
+extern void ixgb_update_stats(struct ixgb_adapter *adapter);
 
 struct ixgb_stats {
 	char stat_string[ETH_GSTRING_LEN];
@@ -89,7 +95,7 @@
 	sizeof(ixgb_gstrings_stats) / sizeof(struct ixgb_stats)
 
 static int
-ixgb_ethtool_gset(struct net_device *netdev, struct ethtool_cmd *ecmd)
+ixgb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
 {
 	struct ixgb_adapter *adapter = netdev->priv;
 	ecmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE);
@@ -97,7 +103,7 @@
 	ecmd->port = PORT_FIBRE;
 	ecmd->transceiver = XCVR_EXTERNAL;
 
-	if (netif_carrier_ok(adapter->netdev)) {
+	if(netif_carrier_ok(adapter->netdev)) {
 		ecmd->speed = SPEED_10000;
 		ecmd->duplex = DUPLEX_FULL;
 	} else {
@@ -110,86 +116,140 @@
 }
 
 static int
-ixgb_ethtool_sset(struct net_device *netdev, struct ethtool_cmd *ecmd)
+ixgb_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
 {
 	struct ixgb_adapter *adapter = netdev->priv;
-	if (ecmd->autoneg == AUTONEG_ENABLE ||
-	    ecmd->speed + ecmd->duplex != SPEED_10000 + DUPLEX_FULL)
+	if(ecmd->autoneg == AUTONEG_ENABLE ||
+	   ecmd->speed + ecmd->duplex != SPEED_10000 + DUPLEX_FULL)
 		return -EINVAL;
-	else {
+	
+	if(netif_running(adapter->netdev)) {
 		ixgb_down(adapter, TRUE);
+		ixgb_reset(adapter);
 		ixgb_up(adapter);
-	}
+	} else
+		ixgb_reset(adapter);
+
 	return 0;
 }
 
 static void
-ixgb_ethtool_gpause(struct net_device *dev,
-		    struct ethtool_pauseparam *epause)
+ixgb_get_pauseparam(struct net_device *netdev,
+			 struct ethtool_pauseparam *pause)
 {
-	struct ixgb_adapter *adapter = dev->priv;
+	struct ixgb_adapter *adapter = netdev->priv;
 	struct ixgb_hw *hw = &adapter->hw;
-
-	epause->autoneg = AUTONEG_DISABLE;
-
-	if (hw->fc.type == ixgb_fc_rx_pause)
-		epause->rx_pause = 1;
-	else if (hw->fc.type == ixgb_fc_tx_pause)
-		epause->tx_pause = 1;
-	else if (hw->fc.type == ixgb_fc_full) {
-		epause->rx_pause = 1;
-		epause->tx_pause = 1;
+	
+	pause->autoneg = AUTONEG_DISABLE;
+		
+	if(hw->fc.type == ixgb_fc_rx_pause)
+		pause->rx_pause = 1;
+	else if(hw->fc.type == ixgb_fc_tx_pause)
+		pause->tx_pause = 1;
+	else if(hw->fc.type == ixgb_fc_full) {
+		pause->rx_pause = 1;
+		pause->tx_pause = 1;
 	}
 }
 
 static int
-ixgb_ethtool_spause(struct net_device *dev,
-		    struct ethtool_pauseparam *epause)
+ixgb_set_pauseparam(struct net_device *netdev,
+			 struct ethtool_pauseparam *pause)
 {
-	struct ixgb_adapter *adapter = dev->priv;
+	struct ixgb_adapter *adapter = netdev->priv;
 	struct ixgb_hw *hw = &adapter->hw;
-
-	if (epause->autoneg == AUTONEG_ENABLE)
+	
+	if(pause->autoneg == AUTONEG_ENABLE)
 		return -EINVAL;
 
-	if (epause->rx_pause && epause->tx_pause)
+	if(pause->rx_pause && pause->tx_pause)
 		hw->fc.type = ixgb_fc_full;
-	else if (epause->rx_pause && !epause->tx_pause)
+	else if(pause->rx_pause && !pause->tx_pause)
 		hw->fc.type = ixgb_fc_rx_pause;
-	else if (!epause->rx_pause && epause->tx_pause)
+	else if(!pause->rx_pause && pause->tx_pause)
 		hw->fc.type = ixgb_fc_tx_pause;
-	else if (!epause->rx_pause && !epause->tx_pause)
+	else if(!pause->rx_pause && !pause->tx_pause)
 		hw->fc.type = ixgb_fc_none;
 
-	ixgb_down(adapter, TRUE);
-	ixgb_up(adapter);
-
+	if(netif_running(adapter->netdev)) {
+		ixgb_down(adapter, TRUE);
+		ixgb_up(adapter);
+	} else
+		ixgb_reset(adapter);
+		
 	return 0;
 }
 
-static void
-ixgb_ethtool_gdrvinfo(struct net_device *netdev,
-		      struct ethtool_drvinfo *drvinfo)
+static uint32_t
+ixgb_get_rx_csum(struct net_device *netdev)
 {
 	struct ixgb_adapter *adapter = netdev->priv;
-	strncpy(drvinfo->driver, ixgb_driver_name, 32);
-	strncpy(drvinfo->version, ixgb_driver_version, 32);
-	strncpy(drvinfo->fw_version, "N/A", 32);
-	strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32);
+	return adapter->rx_csum;
 }
 
+static int
+ixgb_set_rx_csum(struct net_device *netdev, uint32_t data)
+{
+	struct ixgb_adapter *adapter = netdev->priv;
+	adapter->rx_csum = data;
+
+	if(netif_running(netdev)) {
+		ixgb_down(adapter,TRUE);
+		ixgb_up(adapter);
+	} else
+		ixgb_reset(adapter);
+	return 0;
+}
+	
+static uint32_t
+ixgb_get_tx_csum(struct net_device *netdev)
+{
+	return (netdev->features & NETIF_F_HW_CSUM) != 0;
+}
+
+static int
+ixgb_set_tx_csum(struct net_device *netdev, uint32_t data)
+{
+	if (data)
+		netdev->features |= NETIF_F_HW_CSUM;
+	else
+		netdev->features &= ~NETIF_F_HW_CSUM;
+
+	return 0;
+}
+
+#ifdef NETIF_F_TSO
+static int
+ixgb_set_tso(struct net_device *netdev, uint32_t data)
+{
+	if(data)
+		netdev->features |= NETIF_F_TSO;
+	else
+		netdev->features &= ~NETIF_F_TSO;
+	return 0;
+} 
+#endif /* NETIF_F_TSO */
+
 #define IXGB_GET_STAT(_A_, _R_) _A_->stats._R_
+
+static int 
+ixgb_get_regs_len(struct net_device *netdev)
+{
+#define IXGB_REG_DUMP_LEN  136*sizeof(uint32_t)
+	return IXGB_REG_DUMP_LEN;
+}
+
 static void
-ixgb_ethtool_gregs(struct net_device *dev, struct ethtool_regs *regs, void *buf)
+ixgb_get_regs(struct net_device *netdev,
+		   struct ethtool_regs *regs, void *p)
 {
-	struct ixgb_adapter *adapter = dev->priv;
+	struct ixgb_adapter *adapter = netdev->priv;
 	struct ixgb_hw *hw = &adapter->hw;
-	uint32_t *reg = buf;
+	uint32_t *reg = p;
 	uint32_t *reg_start = reg;
 	uint8_t i;
 
-	regs->version =
-	    (adapter->hw.device_id << 16) | adapter->hw.subsystem_id;
+	regs->version = (adapter->hw.device_id << 16) | adapter->hw.subsystem_id;
 
 	/* General Registers */
 	*reg++ = IXGB_READ_REG(hw, CTRL0);	/*   0 */
@@ -219,8 +279,8 @@
 	*reg++ = IXGB_READ_REG(hw, RXCSUM);	/*  20 */
 
 	for (i = 0; i < IXGB_RAR_ENTRIES; i++) {
-		*reg++ = IXGB_READ_REG_ARRAY(hw, RAL, (i << 1));	/*21,...,51 */
-		*reg++ = IXGB_READ_REG_ARRAY(hw, RAH, (i << 1));	/*22,...,52 */
+		*reg++ = IXGB_READ_REG_ARRAY(hw, RAL, (i << 1)); /*21,...,51 */
+		*reg++ = IXGB_READ_REG_ARRAY(hw, RAH, (i << 1)); /*22,...,52 */
 	}
 
 	/* Transmit */
@@ -316,73 +376,222 @@
 }
 
 static int
-ixgb_ethtool_geeprom(struct net_device *dev,
-		     struct ethtool_eeprom *eeprom, u8 *data)
+ixgb_get_eeprom_len(struct net_device *netdev)
 {
-	struct ixgb_adapter *adapter = dev->priv;
+	/* return size in bytes */
+	return (IXGB_EEPROM_SIZE << 1);
+}
+
+static int
+ixgb_get_eeprom(struct net_device *netdev,
+		  struct ethtool_eeprom *eeprom, uint8_t *bytes)
+{
+	struct ixgb_adapter *adapter = netdev->priv;
 	struct ixgb_hw *hw = &adapter->hw;
+	uint16_t *eeprom_buff;
+	int i, max_len, first_word, last_word;
+	int ret_val = 0;
+
+	if(eeprom->len == 0) {
+		ret_val = -EINVAL;
+		goto geeprom_error;
+	}
 
 	eeprom->magic = hw->vendor_id | (hw->device_id << 16);
 
-	/* use our function to read the eeprom and update our cache */
-	ixgb_get_eeprom_data(hw);
-	memcpy(data, (char *)hw->eeprom + eeprom->offset, eeprom->len);
-	return 0;
+	max_len = ixgb_get_eeprom_len(netdev);
+
+	if(eeprom->offset > eeprom->offset + eeprom->len) {
+		ret_val = -EINVAL;
+		goto geeprom_error;
+	}
+
+	if((eeprom->offset + eeprom->len) > max_len)
+		eeprom->len = (max_len - eeprom->offset);
+
+	first_word = eeprom->offset >> 1;
+	last_word = (eeprom->offset + eeprom->len - 1) >> 1;
+
+	eeprom_buff = kmalloc(sizeof(uint16_t) *
+			(last_word - first_word + 1), GFP_KERNEL);
+	if(!eeprom_buff)
+		return -ENOMEM;
+
+	/* note the eeprom was good because the driver loaded */
+	for(i = 0; i <= (last_word - first_word); i++) {
+		eeprom_buff[i] = ixgb_get_eeprom_word(hw, (first_word + i));
+	}
+
+	memcpy(bytes, (uint8_t *)eeprom_buff + (eeprom->offset & 1),
+			eeprom->len);
+	kfree(eeprom_buff);
+
+geeprom_error:
+	return ret_val;
 }
 
 static int
-ixgb_ethtool_seeprom(struct net_device *dev,
-		     struct ethtool_eeprom *eeprom, u8 *data)
+ixgb_set_eeprom(struct net_device *netdev,
+		  struct ethtool_eeprom *eeprom, uint8_t *bytes)
 {
-	struct ixgb_adapter *adapter = dev->priv;
+	struct ixgb_adapter *adapter = netdev->priv;
 	struct ixgb_hw *hw = &adapter->hw;
-	/* We are under rtnl, so static is OK */
-	static uint16_t eeprom_buff[IXGB_EEPROM_SIZE];
-	int i, first_word, last_word;
-	char *ptr;
+	uint16_t *eeprom_buff;
+	void *ptr;
+	int max_len, first_word, last_word;
+	uint16_t i;
+
+	if(eeprom->len == 0)
+		return -EINVAL;
 
-	if (eeprom->magic != (hw->vendor_id | (hw->device_id << 16)))
+	if(eeprom->magic != (hw->vendor_id | (hw->device_id << 16)))
 		return -EFAULT;
 
+	max_len = ixgb_get_eeprom_len(netdev);
+
+	if(eeprom->offset > eeprom->offset + eeprom->len)
+		return -EINVAL;
+
+	if((eeprom->offset + eeprom->len) > max_len)
+		eeprom->len = (max_len - eeprom->offset);
+
 	first_word = eeprom->offset >> 1;
 	last_word = (eeprom->offset + eeprom->len - 1) >> 1;
-	ptr = (char *)eeprom_buff;
+	eeprom_buff = kmalloc(max_len, GFP_KERNEL);
+	if(!eeprom_buff)
+		return -ENOMEM;
+
+	ptr = (void *)eeprom_buff;
 
-	if (eeprom->offset & 1) {
+	if(eeprom->offset & 1) {
 		/* need read/modify/write of first changed EEPROM word */
 		/* only the second byte of the word is being modified */
 		eeprom_buff[0] = ixgb_read_eeprom(hw, first_word);
 		ptr++;
 	}
-	if ((eeprom->offset + eeprom->len) & 1) {
+	if((eeprom->offset + eeprom->len) & 1) {
 		/* need read/modify/write of last changed EEPROM word */
 		/* only the first byte of the word is being modified */
-		eeprom_buff[last_word - first_word]
-		    = ixgb_read_eeprom(hw, last_word);
+		eeprom_buff[last_word - first_word] 
+			= ixgb_read_eeprom(hw, last_word);
 	}
-	memcpy(ptr, data, eeprom->len);
 
-	for (i = 0; i <= (last_word - first_word); i++)
+	memcpy(ptr, bytes, eeprom->len);
+	for(i = 0; i <= (last_word - first_word); i++)
 		ixgb_write_eeprom(hw, first_word + i, eeprom_buff[i]);
 
 	/* Update the checksum over the first part of the EEPROM if needed */
-	if (first_word <= EEPROM_CHECKSUM_REG)
+	if(first_word <= EEPROM_CHECKSUM_REG)
 		ixgb_update_eeprom_checksum(hw);
 
+	kfree(eeprom_buff);
 	return 0;
 }
 
+static void
+ixgb_get_drvinfo(struct net_device *netdev,
+		   struct ethtool_drvinfo *drvinfo)
+{
+	struct ixgb_adapter *adapter = netdev->priv;
+
+	strncpy(drvinfo->driver,  ixgb_driver_name, 32);
+	strncpy(drvinfo->version, ixgb_driver_version, 32);
+	strncpy(drvinfo->fw_version, "N/A", 32);
+	strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32);
+	drvinfo->n_stats = IXGB_STATS_LEN;
+	drvinfo->regdump_len = ixgb_get_regs_len(netdev);
+	drvinfo->eedump_len = ixgb_get_eeprom_len(netdev);
+}
+
+static void
+ixgb_get_ringparam(struct net_device *netdev,
+		struct ethtool_ringparam *ring)
+{
+	struct ixgb_adapter *adapter = netdev->priv;
+	struct ixgb_desc_ring *txdr = &adapter->tx_ring;
+	struct ixgb_desc_ring *rxdr = &adapter->rx_ring;
+
+	ring->rx_max_pending = MAX_RXD; 
+	ring->tx_max_pending = MAX_TXD;
+	ring->rx_mini_max_pending = 0;
+	ring->rx_jumbo_max_pending = 0;
+	ring->rx_pending = rxdr->count;
+	ring->tx_pending = txdr->count;
+	ring->rx_mini_pending = 0;
+	ring->rx_jumbo_pending = 0;
+}
+
+static int 
+ixgb_set_ringparam(struct net_device *netdev,
+		struct ethtool_ringparam *ring)
+{
+	struct ixgb_adapter *adapter = netdev->priv;
+	struct ixgb_desc_ring *txdr = &adapter->tx_ring;
+	struct ixgb_desc_ring *rxdr = &adapter->rx_ring;
+	struct ixgb_desc_ring tx_old, tx_new, rx_old, rx_new;
+	int err;
+
+	tx_old = adapter->tx_ring;
+	rx_old = adapter->rx_ring;
+
+	if((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) 
+		return -EINVAL;
+
+	if(netif_running(adapter->netdev))
+		ixgb_down(adapter,TRUE);
+
+	rxdr->count = max(ring->rx_pending,(uint32_t)MIN_RXD);
+	rxdr->count = min(rxdr->count,(uint32_t)MAX_RXD);
+	IXGB_ROUNDUP(rxdr->count, IXGB_REQ_RX_DESCRIPTOR_MULTIPLE); 
+
+	txdr->count = max(ring->tx_pending,(uint32_t)MIN_TXD);
+	txdr->count = min(txdr->count,(uint32_t)MAX_TXD);
+	IXGB_ROUNDUP(txdr->count, IXGB_REQ_TX_DESCRIPTOR_MULTIPLE); 
+
+	if(netif_running(adapter->netdev)) {
+		/* Try to get new resources before deleting old */
+		if((err = ixgb_setup_rx_resources(adapter)))
+			goto err_setup_rx;
+		if((err = ixgb_setup_tx_resources(adapter)))
+			goto err_setup_tx;
+
+		/* save the new, restore the old in order to free it,
+		 * then restore the new back again */
+
+		rx_new = adapter->rx_ring;
+		tx_new = adapter->tx_ring;
+		adapter->rx_ring = rx_old;
+		adapter->tx_ring = tx_old;
+		ixgb_free_rx_resources(adapter);
+		ixgb_free_tx_resources(adapter);
+		adapter->rx_ring = rx_new;
+		adapter->tx_ring = tx_new;
+		if((err = ixgb_up(adapter)))
+			return err;
+	}
+
+	return 0;
+err_setup_tx:
+	ixgb_free_rx_resources(adapter);
+err_setup_rx:
+	adapter->rx_ring = rx_old;
+	adapter->tx_ring = tx_old;
+	ixgb_up(adapter);
+	return err;
+}
+
 /* toggle LED 4 times per second = 2 "blinks" per second */
 #define IXGB_ID_INTERVAL	(HZ/4)
 
 /* bit defines for adapter->led_status */
 #define IXGB_LED_ON		0
 
-static void ixgb_led_blink_callback(unsigned long data)
+static void
+ixgb_led_blink_callback(unsigned long data)
 {
 	struct ixgb_adapter *adapter = (struct ixgb_adapter *)data;
 
-	if (test_and_change_bit(IXGB_LED_ON, &adapter->led_status))
+	if(test_and_change_bit(IXGB_LED_ON, &adapter->led_status))
 		ixgb_led_off(&adapter->hw);
 	else
 		ixgb_led_on(&adapter->hw);
@@ -391,10 +600,14 @@
 }
 
 static int
-ixgb_ethtool_led_blink(struct net_device *netdev, u32 data)
+ixgb_phys_id(struct net_device *netdev, uint32_t data)
 {
 	struct ixgb_adapter *adapter = netdev->priv;
-	if (!adapter->blink_timer.function) {
+
+	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 = ixgb_led_blink_callback;
 		adapter->blink_timer.data = (unsigned long)adapter;
@@ -403,7 +616,7 @@
 	mod_timer(&adapter->blink_timer, jiffies);
 
 	set_current_state(TASK_INTERRUPTIBLE);
-	if (data)
+	if(data)
 		schedule_timeout(data * HZ);
 	else
 		schedule_timeout(MAX_SCHEDULE_TIMEOUT);
@@ -415,141 +628,74 @@
 	return 0;
 }
 
-static int ixgb_nway_reset(struct net_device *netdev)
-{
-	if (netif_running(netdev)) {
-		struct ixgb_adapter *adapter = netdev->priv;
-		ixgb_down(adapter, TRUE);
-		ixgb_up(adapter);
-	}
-	return 0;
-}
-
-static int ixgb_get_stats_count(struct net_device *dev)
+static int 
+ixgb_get_stats_count(struct net_device *netdev)
 {
 	return IXGB_STATS_LEN;
 }
 
-static void ixgb_get_strings(struct net_device *dev, u32 stringset, u8 *data)
+static void 
+ixgb_get_ethtool_stats(struct net_device *netdev, 
+		struct ethtool_stats *stats, uint64_t *data)
 {
+	struct ixgb_adapter *adapter = netdev->priv;
 	int i;
-	for (i = 0; i < IXGB_STATS_LEN; i++) {
-		memcpy(data + i * ETH_GSTRING_LEN,
-		       ixgb_gstrings_stats[i].stat_string,
-		       ETH_GSTRING_LEN);
-	}
-}
-
-static int ixgb_get_regs_len(struct net_device *dev)
-{
-	return 136*sizeof(uint32_t);
-}
 
-static int ixgb_get_eeprom_len(struct net_device *dev)
-{
-	/* return size in bytes */
-	return (IXGB_EEPROM_SIZE << 1);
+	ixgb_update_stats(adapter);
+	for(i = 0; i < IXGB_STATS_LEN; i++) {
+		char *p = (char *)adapter+ixgb_gstrings_stats[i].stat_offset;	
+		data[i] = (ixgb_gstrings_stats[i].sizeof_stat == 
+			sizeof(uint64_t)) ? *(uint64_t *)p : *(uint32_t *)p;
+	}
 }
 
-static void get_ethtool_stats(struct net_device *dev,
-		struct ethtool_stats *stats, u64 *data)
+static void 
+ixgb_get_strings(struct net_device *netdev, uint32_t stringset, uint8_t *data)
 {
-	struct ixgb_adapter *adapter = dev->priv;
 	int i;
 
-	for (i = 0; i < IXGB_STATS_LEN; i++) {
-		void *p = (char *)adapter + ixgb_gstrings_stats[i].stat_offset;
-		stats->data[i] =
-		    (ixgb_gstrings_stats[i].sizeof_stat == sizeof(uint64_t))
-		    ? *(uint64_t *) p
-		    : *(uint32_t *) p;
+	switch(stringset) {
+	case ETH_SS_STATS:
+		for(i=0; i < IXGB_STATS_LEN; i++) {
+			memcpy(data + i * ETH_GSTRING_LEN, 
+			ixgb_gstrings_stats[i].stat_string,
+			ETH_GSTRING_LEN);
+		}
+		break;
 	}
 }
 
-static u32 ixgb_get_rx_csum(struct net_device *dev)
-{
-	struct ixgb_adapter *adapter = dev->priv;
-	return adapter->rx_csum;
-}
-
-static int ixgb_set_rx_csum(struct net_device *dev, u32 sum)
-{
-	struct ixgb_adapter *adapter = dev->priv;
-	adapter->rx_csum = sum;
-	ixgb_down(adapter, TRUE);
-	ixgb_up(adapter);
-	return 0;
-}
-
-static u32 ixgb_get_tx_csum(struct net_device *dev)
-{
-	return (dev->features & NETIF_F_HW_CSUM) != 0;
-}
-
-static int ixgb_set_tx_csum(struct net_device *dev, u32 sum)
-{
-	if (sum)
-		dev->features |= NETIF_F_HW_CSUM;
-	else
-		dev->features &= ~NETIF_F_HW_CSUM;
-	return 0;
-}
-
-static u32 ixgb_get_sg(struct net_device *dev)
-{
-	return (dev->features & NETIF_F_SG) != 0;
-}
-
-static int ixgb_set_sg(struct net_device *dev, u32 sum)
-{
-	if (sum)
-		dev->features |= NETIF_F_SG;
-	else
-		dev->features &= ~NETIF_F_SG;
-	return 0;
-}
-
-#ifdef NETIF_F_TSO
-static u32 ixgb_get_tso(struct net_device *dev)
-{
-	return (dev->features & NETIF_F_TSO) != 0;
-}
-
-static int ixgb_set_tso(struct net_device *dev, u32 sum)
-{
-	if (sum)
-		dev->features |= NETIF_F_TSO;
-	else
-		dev->features &= ~NETIF_F_TSO;
-	return 0;
-}
-#endif
-
 struct ethtool_ops ixgb_ethtool_ops = {
-	.get_settings = ixgb_ethtool_gset,
-	.set_settings = ixgb_ethtool_sset,
-	.get_drvinfo = ixgb_ethtool_gdrvinfo,
-	.nway_reset = ixgb_nway_reset,
-	.get_link = ethtool_op_get_link,
-	.phys_id = ixgb_ethtool_led_blink,
-	.get_strings = ixgb_get_strings,
-	.get_stats_count = ixgb_get_stats_count,
-	.get_regs = ixgb_ethtool_gregs,
+	.get_settings = ixgb_get_settings,
+	.set_settings = ixgb_set_settings,
+	.get_drvinfo = ixgb_get_drvinfo,
 	.get_regs_len = ixgb_get_regs_len,
+	.get_regs = ixgb_get_regs,
+	.get_link = ethtool_op_get_link,
 	.get_eeprom_len = ixgb_get_eeprom_len,
-	.get_eeprom = ixgb_ethtool_geeprom,
-	.set_eeprom = ixgb_ethtool_seeprom,
-	.get_pauseparam = ixgb_ethtool_gpause,
-	.set_pauseparam = ixgb_ethtool_spause,
-	.get_ethtool_stats = get_ethtool_stats,
+	.get_eeprom = ixgb_get_eeprom,
+	.set_eeprom = ixgb_set_eeprom,
+	.get_ringparam = ixgb_get_ringparam,
+	.set_ringparam = ixgb_set_ringparam,
+	.get_pauseparam	= ixgb_get_pauseparam,
+	.set_pauseparam	= ixgb_set_pauseparam,
 	.get_rx_csum = ixgb_get_rx_csum,
 	.set_rx_csum = ixgb_set_rx_csum,
 	.get_tx_csum = ixgb_get_tx_csum,
 	.set_tx_csum = ixgb_set_tx_csum,
-	.get_sg = ixgb_get_sg,
-	.set_sg = ixgb_set_sg,
+	.get_sg	= ethtool_op_get_sg,
+	.set_sg	= ethtool_op_set_sg,
 #ifdef NETIF_F_TSO
-	.get_tso = ixgb_get_tso,
+	.get_tso = ethtool_op_get_tso,
 	.set_tso = ixgb_set_tso,
 #endif
+	.get_strings = ixgb_get_strings,
+	.phys_id = ixgb_phys_id,
+	.get_stats_count = ixgb_get_stats_count,
+	.get_ethtool_stats = ixgb_get_ethtool_stats,
 };
+
+void ixgb_set_ethtool_ops(struct net_device *netdev)
+{
+	SET_ETHTOOL_OPS(netdev, &ixgb_ethtool_ops);
+}
diff -Nru a/drivers/net/ixgb/ixgb_hw.c b/drivers/net/ixgb/ixgb_hw.c
--- a/drivers/net/ixgb/ixgb_hw.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/net/ixgb/ixgb_hw.c	2005-03-01 23:39:07 -08:00
@@ -53,9 +53,14 @@
 {
 	uint32_t ctrl_reg;
 
-	ctrl_reg = IXGB_CTRL0_RST | IXGB_CTRL0_SDP3_DIR |	/* All pins are Output=1 */
-	    IXGB_CTRL0_SDP2_DIR | IXGB_CTRL0_SDP1_DIR | IXGB_CTRL0_SDP0_DIR | IXGB_CTRL0_SDP3 |	/* Initial value 1101   */
-	    IXGB_CTRL0_SDP2 | IXGB_CTRL0_SDP0;
+	ctrl_reg =  IXGB_CTRL0_RST |
+				IXGB_CTRL0_SDP3_DIR |   /* All pins are Output=1 */
+				IXGB_CTRL0_SDP2_DIR |
+				IXGB_CTRL0_SDP1_DIR |
+				IXGB_CTRL0_SDP0_DIR |
+				IXGB_CTRL0_SDP3	 |   /* Initial value 1101   */
+				IXGB_CTRL0_SDP2	 |
+				IXGB_CTRL0_SDP0;
 
 #ifdef HP_ZX1
 	/* Workaround for 82597EX reset errata */
@@ -84,7 +89,8 @@
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-boolean_t ixgb_adapter_stop(struct ixgb_hw * hw)
+boolean_t
+ixgb_adapter_stop(struct ixgb_hw *hw)
 {
 	uint32_t ctrl_reg;
 	uint32_t icr_reg;
@@ -94,7 +100,7 @@
 	/* If we are stopped or resetting exit gracefully and wait to be
 	 * started again before accessing the hardware.
 	 */
-	if (hw->adapter_stopped) {
+	if(hw->adapter_stopped) {
 		DEBUGOUT("Exiting because the adapter is already stopped!!!\n");
 		return FALSE;
 	}
@@ -135,6 +141,7 @@
 	return (ctrl_reg & IXGB_CTRL0_RST);
 }
 
+
 /******************************************************************************
  * Identifies the vendor of the optics module on the adapter.  The SR adapters
  * support two different types of XPAK optics, so it is necessary to determine
@@ -144,7 +151,8 @@
  *
  * Returns: the vendor of the XPAK optics module.
  *****************************************************************************/
-static ixgb_xpak_vendor ixgb_identify_xpak_vendor(struct ixgb_hw *hw)
+static ixgb_xpak_vendor
+ixgb_identify_xpak_vendor(struct ixgb_hw *hw)
 {
 	uint32_t i;
 	uint16_t vendor_name[5];
@@ -183,7 +191,8 @@
  *
  * Returns: the phy type of the adapter.
  *****************************************************************************/
-static ixgb_phy_type ixgb_identify_phy(struct ixgb_hw *hw)
+static ixgb_phy_type
+ixgb_identify_phy(struct ixgb_hw *hw)
 {
 	ixgb_phy_type phy_type;
 	ixgb_xpak_vendor xpak_vendor;
@@ -210,7 +219,10 @@
 			phy_type = ixgb_phy_type_g6005;
 		}
 		break;
-
+	case IXGB_DEVICE_ID_82597EX_LR:
+		DEBUGOUT("Identified G6104 optics\n");
+		phy_type = ixgb_phy_type_g6104;
+		break;
 	default:
 		DEBUGOUT("Unknown physical layer module\n");
 		phy_type = ixgb_phy_type_unknown;
@@ -237,7 +249,8 @@
  *      TRUE if successful,
  *      FALSE if unrecoverable problems were encountered.
  *****************************************************************************/
-boolean_t ixgb_init_hw(struct ixgb_hw * hw)
+boolean_t
+ixgb_init_hw(struct ixgb_hw *hw)
 {
 	uint32_t i;
 	uint32_t ctrl_reg;
@@ -266,7 +279,7 @@
 	msec_delay(IXGB_DELAY_AFTER_EE_RESET);
 
 	if (ixgb_get_eeprom_data(hw) == FALSE) {
-		return (FALSE);
+		return(FALSE);
 	}
 
 	/* Use the device id to determine the type of phy/transceiver. */
@@ -284,7 +297,7 @@
 	 */
 	if (!mac_addr_valid(hw->curr_mac_addr)) {
 		DEBUGOUT("MAC address invalid after ixgb_init_rx_addrs\n");
-		return (FALSE);
+		return(FALSE);
 	}
 
 	/* tell the routines in this file they can access hardware again */
@@ -295,7 +308,7 @@
 
 	/* Zero out the Multicast HASH table */
 	DEBUGOUT("Zeroing the MTA\n");
-	for (i = 0; i < IXGB_MC_TBL_SIZE; i++)
+	for(i = 0; i < IXGB_MC_TBL_SIZE; i++)
 		IXGB_WRITE_REG_ARRAY(hw, MTA, i, 0);
 
 	/* Zero out the VLAN Filter Table Array */
@@ -322,7 +335,8 @@
  * of the receive addresss registers. Clears the multicast table. Assumes
  * the receiver is in reset when the routine is called.
  *****************************************************************************/
-void ixgb_init_rx_addrs(struct ixgb_hw *hw)
+void
+ixgb_init_rx_addrs(struct ixgb_hw *hw)
 {
 	uint32_t i;
 
@@ -360,7 +374,7 @@
 
 	/* Zero out the other 15 receive addresses. */
 	DEBUGOUT("Clearing RAR[1-15]\n");
-	for (i = 1; i < IXGB_RAR_ENTRIES; i++) {
+	for(i = 1; i < IXGB_RAR_ENTRIES; i++) {
 		IXGB_WRITE_REG_ARRAY(hw, RA, (i << 1), 0);
 		IXGB_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0);
 	}
@@ -383,12 +397,13 @@
  *****************************************************************************/
 void
 ixgb_mc_addr_list_update(struct ixgb_hw *hw,
-			 uint8_t * mc_addr_list,
-			 uint32_t mc_addr_count, uint32_t pad)
+			  uint8_t *mc_addr_list,
+			  uint32_t mc_addr_count,
+			  uint32_t pad)
 {
 	uint32_t hash_value;
 	uint32_t i;
-	uint32_t rar_used_count = 1;	/* RAR[0] is used for our MAC address */
+	uint32_t rar_used_count = 1;		/* RAR[0] is used for our MAC address */
 
 	DEBUGFUNC("ixgb_mc_addr_list_update");
 
@@ -397,19 +412,19 @@
 
 	/* Clear RAR[1-15] */
 	DEBUGOUT(" Clearing RAR[1-15]\n");
-	for (i = rar_used_count; i < IXGB_RAR_ENTRIES; i++) {
+	for(i = rar_used_count; i < IXGB_RAR_ENTRIES; i++) {
 		IXGB_WRITE_REG_ARRAY(hw, RA, (i << 1), 0);
 		IXGB_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0);
 	}
 
 	/* Clear the MTA */
 	DEBUGOUT(" Clearing MTA\n");
-	for (i = 0; i < IXGB_MC_TBL_SIZE; i++) {
+	for(i = 0; i < IXGB_MC_TBL_SIZE; i++) {
 		IXGB_WRITE_REG_ARRAY(hw, MTA, i, 0);
 	}
 
 	/* Add the new addresses */
-	for (i = 0; i < mc_addr_count; i++) {
+	for(i = 0; i < mc_addr_count; i++) {
 		DEBUGOUT(" Adding the multicast addresses:\n");
 		DEBUGOUT7(" MC Addr #%d =%.2X %.2X %.2X %.2X %.2X %.2X\n", i,
 			  mc_addr_list[i * (IXGB_ETH_LENGTH_OF_ADDRESS + pad)],
@@ -427,7 +442,7 @@
 		/* Place this multicast address in the RAR if there is room, *
 		 * else put it in the MTA
 		 */
-		if (rar_used_count < IXGB_RAR_ENTRIES) {
+		if(rar_used_count < IXGB_RAR_ENTRIES) {
 			ixgb_rar_set(hw,
 				     mc_addr_list +
 				     (i * (IXGB_ETH_LENGTH_OF_ADDRESS + pad)),
@@ -460,7 +475,9 @@
  * Returns:
  *      The hash value
  *****************************************************************************/
-static uint32_t ixgb_hash_mc_addr(struct ixgb_hw *hw, uint8_t * mc_addr)
+static uint32_t
+ixgb_hash_mc_addr(struct ixgb_hw *hw,
+		   uint8_t *mc_addr)
 {
 	uint32_t hash_value = 0;
 
@@ -506,7 +523,9 @@
  * hw - Struct containing variables accessed by shared code
  * hash_value - Multicast address hash value
  *****************************************************************************/
-static void ixgb_mta_set(struct ixgb_hw *hw, uint32_t hash_value)
+static void
+ixgb_mta_set(struct ixgb_hw *hw,
+		  uint32_t hash_value)
 {
 	uint32_t hash_bit, hash_reg;
 	uint32_t mta_reg;
@@ -538,7 +557,10 @@
  * addr - Address to put into receive address register
  * index - Receive address register to write
  *****************************************************************************/
-void ixgb_rar_set(struct ixgb_hw *hw, uint8_t * addr, uint32_t index)
+void
+ixgb_rar_set(struct ixgb_hw *hw,
+		  uint8_t *addr,
+		  uint32_t index)
 {
 	uint32_t rar_low, rar_high;
 
@@ -548,11 +570,13 @@
 	 * from network order (big endian) to little endian
 	 */
 	rar_low = ((uint32_t) addr[0] |
-		   ((uint32_t) addr[1] << 8) |
-		   ((uint32_t) addr[2] << 16) | ((uint32_t) addr[3] << 24));
+		   ((uint32_t)addr[1] << 8) |
+		   ((uint32_t)addr[2] << 16) |
+		   ((uint32_t)addr[3] << 24));
 
 	rar_high = ((uint32_t) addr[4] |
-		    ((uint32_t) addr[5] << 8) | IXGB_RAH_AV);
+			((uint32_t)addr[5] << 8) |
+			IXGB_RAH_AV);
 
 	IXGB_WRITE_REG_ARRAY(hw, RA, (index << 1), rar_low);
 	IXGB_WRITE_REG_ARRAY(hw, RA, ((index << 1) + 1), rar_high);
@@ -566,7 +590,10 @@
  * offset - Offset in VLAN filer table to write
  * value - Value to write into VLAN filter table
  *****************************************************************************/
-void ixgb_write_vfta(struct ixgb_hw *hw, uint32_t offset, uint32_t value)
+void
+ixgb_write_vfta(struct ixgb_hw *hw,
+		 uint32_t offset,
+		 uint32_t value)
 {
 	IXGB_WRITE_REG_ARRAY(hw, VFTA, offset, value);
 	return;
@@ -577,11 +604,12 @@
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-void ixgb_clear_vfta(struct ixgb_hw *hw)
+void
+ixgb_clear_vfta(struct ixgb_hw *hw)
 {
 	uint32_t offset;
 
-	for (offset = 0; offset < IXGB_VLAN_FILTER_TBL_SIZE; offset++)
+	for(offset = 0; offset < IXGB_VLAN_FILTER_TBL_SIZE; offset++)
 		IXGB_WRITE_REG_ARRAY(hw, VFTA, offset, 0);
 	return;
 }
@@ -592,10 +620,11 @@
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
 
-boolean_t ixgb_setup_fc(struct ixgb_hw * hw)
+boolean_t
+ixgb_setup_fc(struct ixgb_hw *hw)
 {
 	uint32_t ctrl_reg;
-	uint32_t pap_reg = 0;	/* by default, assume no pause time */
+	uint32_t pap_reg = 0;   /* by default, assume no pause time */
 	boolean_t status = TRUE;
 
 	DEBUGFUNC("ixgb_setup_fc");
@@ -660,16 +689,16 @@
 	 * ability to transmit pause frames in not enabled, then these
 	 * registers will be set to 0.
 	 */
-	if (!(hw->fc.type & ixgb_fc_tx_pause)) {
+	if(!(hw->fc.type & ixgb_fc_tx_pause)) {
 		IXGB_WRITE_REG(hw, FCRTL, 0);
 		IXGB_WRITE_REG(hw, FCRTH, 0);
 	} else {
-		/* We need to set up the Receive Threshold high and low water
-		 * marks as well as (optionally) enabling the transmission of XON frames.
-		 */
-		if (hw->fc.send_xon) {
+	   /* We need to set up the Receive Threshold high and low water
+	    * marks as well as (optionally) enabling the transmission of XON
+	    * frames. */
+		if(hw->fc.send_xon) {
 			IXGB_WRITE_REG(hw, FCRTL,
-				       (hw->fc.low_water | IXGB_FCRTL_XONE));
+				(hw->fc.low_water | IXGB_FCRTL_XONE));
 		} else {
 			IXGB_WRITE_REG(hw, FCRTL, hw->fc.low_water);
 		}
@@ -694,9 +723,10 @@
  * read command.
  *****************************************************************************/
 uint16_t
-ixgb_read_phy_reg(struct ixgb_hw * hw,
-		  uint32_t reg_address,
-		  uint32_t phy_address, uint32_t device_type)
+ixgb_read_phy_reg(struct ixgb_hw *hw,
+		uint32_t reg_address,
+		uint32_t phy_address,
+		uint32_t device_type)
 {
 	uint32_t i;
 	uint32_t data;
@@ -721,7 +751,8 @@
     ** from the CPU Write to the Ready bit assertion.
     **************************************************************/
 
-	for (i = 0; i < 10; i++) {
+	for(i = 0; i < 10; i++)
+	{
 		udelay(10);
 
 		command = IXGB_READ_REG(hw, MSCA);
@@ -747,7 +778,8 @@
     ** from the CPU Write to the Ready bit assertion.
     **************************************************************/
 
-	for (i = 0; i < 10; i++) {
+	for(i = 0; i < 10; i++)
+	{
 		udelay(10);
 
 		command = IXGB_READ_REG(hw, MSCA);
@@ -763,7 +795,7 @@
 	 */
 	data = IXGB_READ_REG(hw, MSRWD);
 	data >>= IXGB_MSRWD_READ_DATA_SHIFT;
-	return ((uint16_t) data);
+	return((uint16_t) data);
 }
 
 /******************************************************************************
@@ -785,8 +817,10 @@
  *****************************************************************************/
 void
 ixgb_write_phy_reg(struct ixgb_hw *hw,
-		   uint32_t reg_address,
-		   uint32_t phy_address, uint32_t device_type, uint16_t data)
+			uint32_t reg_address,
+			uint32_t phy_address,
+			uint32_t device_type,
+			uint16_t data)
 {
 	uint32_t i;
 	uint32_t command = 0;
@@ -796,24 +830,25 @@
 	ASSERT(device_type <= IXGB_MAX_PHY_DEV_TYPE);
 
 	/* Put the data in the MDIO Read/Write Data register */
-	IXGB_WRITE_REG(hw, MSRWD, (uint32_t) data);
+	IXGB_WRITE_REG(hw, MSRWD, (uint32_t)data);
 
 	/* Setup and write the address cycle command */
-	command = ((reg_address << IXGB_MSCA_NP_ADDR_SHIFT) |
-		   (device_type << IXGB_MSCA_DEV_TYPE_SHIFT) |
-		   (phy_address << IXGB_MSCA_PHY_ADDR_SHIFT) |
-		   (IXGB_MSCA_ADDR_CYCLE | IXGB_MSCA_MDI_COMMAND));
+	command = ((reg_address << IXGB_MSCA_NP_ADDR_SHIFT)  |
+			   (device_type << IXGB_MSCA_DEV_TYPE_SHIFT) |
+			   (phy_address << IXGB_MSCA_PHY_ADDR_SHIFT) |
+			   (IXGB_MSCA_ADDR_CYCLE | IXGB_MSCA_MDI_COMMAND));
 
 	IXGB_WRITE_REG(hw, MSCA, command);
 
-    /**************************************************************
-    ** Check every 10 usec to see if the address cycle completed
-    ** The COMMAND bit will clear when the operation is complete.
-    ** This may take as long as 64 usecs (we'll wait 100 usecs max)
-    ** from the CPU Write to the Ready bit assertion.
-    **************************************************************/
+	/**************************************************************
+	** Check every 10 usec to see if the address cycle completed
+	** The COMMAND bit will clear when the operation is complete.
+	** This may take as long as 64 usecs (we'll wait 100 usecs max)
+	** from the CPU Write to the Ready bit assertion.
+	**************************************************************/
 
-	for (i = 0; i < 10; i++) {
+	for(i = 0; i < 10; i++)
+	{
 		udelay(10);
 
 		command = IXGB_READ_REG(hw, MSCA);
@@ -825,21 +860,22 @@
 	ASSERT((command & IXGB_MSCA_MDI_COMMAND) == 0);
 
 	/* Address cycle complete, setup and write the write command */
-	command = ((reg_address << IXGB_MSCA_NP_ADDR_SHIFT) |
-		   (device_type << IXGB_MSCA_DEV_TYPE_SHIFT) |
-		   (phy_address << IXGB_MSCA_PHY_ADDR_SHIFT) |
-		   (IXGB_MSCA_WRITE | IXGB_MSCA_MDI_COMMAND));
+	command = ((reg_address << IXGB_MSCA_NP_ADDR_SHIFT)  |
+			   (device_type << IXGB_MSCA_DEV_TYPE_SHIFT) |
+			   (phy_address << IXGB_MSCA_PHY_ADDR_SHIFT) |
+			   (IXGB_MSCA_WRITE | IXGB_MSCA_MDI_COMMAND));
 
 	IXGB_WRITE_REG(hw, MSCA, command);
 
-    /**************************************************************
-    ** Check every 10 usec to see if the read command completed
-    ** The COMMAND bit will clear when the operation is complete.
-    ** The write may take as long as 64 usecs (we'll wait 100 usecs max)
-    ** from the CPU Write to the Ready bit assertion.
-    **************************************************************/
+	/**************************************************************
+	** Check every 10 usec to see if the read command completed
+	** The COMMAND bit will clear when the operation is complete.
+	** The write may take as long as 64 usecs (we'll wait 100 usecs max)
+	** from the CPU Write to the Ready bit assertion.
+	**************************************************************/
 
-	for (i = 0; i < 10; i++) {
+	for(i = 0; i < 10; i++)
+	{
 		udelay(10);
 
 		command = IXGB_READ_REG(hw, MSCA);
@@ -860,7 +896,8 @@
  *
  * Called by any function that needs to check the link status of the adapter.
  *****************************************************************************/
-void ixgb_check_for_link(struct ixgb_hw *hw)
+void
+ixgb_check_for_link(struct ixgb_hw *hw)
 {
 	uint32_t status_reg;
 	uint32_t xpcss_reg;
@@ -922,14 +959,15 @@
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-void ixgb_clear_hw_cntrs(struct ixgb_hw *hw)
+void
+ixgb_clear_hw_cntrs(struct ixgb_hw *hw)
 {
 	volatile uint32_t temp_reg;
 
 	DEBUGFUNC("ixgb_clear_hw_cntrs");
 
 	/* if we are stopped or resetting exit gracefully */
-	if (hw->adapter_stopped) {
+	if(hw->adapter_stopped) {
 		DEBUGOUT("Exiting because the adapter is stopped!!!\n");
 		return;
 	}
@@ -1002,7 +1040,8 @@
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-void ixgb_led_on(struct ixgb_hw *hw)
+void
+ixgb_led_on(struct ixgb_hw *hw)
 {
 	uint32_t ctrl0_reg = IXGB_READ_REG(hw, CTRL0);
 
@@ -1017,7 +1056,8 @@
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-void ixgb_led_off(struct ixgb_hw *hw)
+void
+ixgb_led_off(struct ixgb_hw *hw)
 {
 	uint32_t ctrl0_reg = IXGB_READ_REG(hw, CTRL0);
 
@@ -1032,18 +1072,19 @@
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-static void ixgb_get_bus_info(struct ixgb_hw *hw)
+static void
+ixgb_get_bus_info(struct ixgb_hw *hw)
 {
 	uint32_t status_reg;
 
 	status_reg = IXGB_READ_REG(hw, STATUS);
 
 	hw->bus.type = (status_reg & IXGB_STATUS_PCIX_MODE) ?
-	    ixgb_bus_type_pcix : ixgb_bus_type_pci;
+		ixgb_bus_type_pcix : ixgb_bus_type_pci;
 
 	if (hw->bus.type == ixgb_bus_type_pci) {
 		hw->bus.speed = (status_reg & IXGB_STATUS_PCI_SPD) ?
-		    ixgb_bus_speed_66 : ixgb_bus_speed_33;
+			ixgb_bus_speed_66 : ixgb_bus_speed_33;
 	} else {
 		switch (status_reg & IXGB_STATUS_PCIX_SPD_MASK) {
 		case IXGB_STATUS_PCIX_SPD_66:
@@ -1062,7 +1103,7 @@
 	}
 
 	hw->bus.width = (status_reg & IXGB_STATUS_BUS64) ?
-	    ixgb_bus_width_64 : ixgb_bus_width_32;
+		ixgb_bus_width_64 : ixgb_bus_width_32;
 
 	return;
 }
@@ -1073,7 +1114,8 @@
  * mac_addr - pointer to MAC address.
  *
  *****************************************************************************/
-boolean_t mac_addr_valid(uint8_t * mac_addr)
+boolean_t
+mac_addr_valid(uint8_t *mac_addr)
 {
 	boolean_t is_valid = TRUE;
 	DEBUGFUNC("mac_addr_valid");
@@ -1090,9 +1132,11 @@
 	}
 	/* Reject the zero address */
 	else if (mac_addr[0] == 0 &&
-		 mac_addr[1] == 0 &&
-		 mac_addr[2] == 0 &&
-		 mac_addr[3] == 0 && mac_addr[4] == 0 && mac_addr[5] == 0) {
+			 mac_addr[1] == 0 &&
+			 mac_addr[2] == 0 &&
+			 mac_addr[3] == 0 &&
+			 mac_addr[4] == 0 &&
+			 mac_addr[5] == 0) {
 		DEBUGOUT("MAC address is all zeros\n");
 		is_valid = FALSE;
 	}
@@ -1105,7 +1149,8 @@
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-boolean_t ixgb_link_reset(struct ixgb_hw * hw)
+boolean_t
+ixgb_link_reset(struct ixgb_hw *hw)
 {
 	boolean_t link_status = FALSE;
 	uint8_t wait_retries = MAX_RESET_ITERATIONS;
@@ -1135,20 +1180,22 @@
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-void ixgb_optics_reset(struct ixgb_hw *hw)
+void
+ixgb_optics_reset(struct ixgb_hw *hw)
 {
 	if (hw->phy_type == ixgb_phy_type_txn17401) {
 		uint16_t mdio_reg;
 
 		ixgb_write_phy_reg(hw,
-				   MDIO_PMA_PMD_CR1,
-				   IXGB_PHY_ADDRESS,
-				   MDIO_PMA_PMD_DID, MDIO_PMA_PMD_CR1_RESET);
-
-		mdio_reg = ixgb_read_phy_reg(hw,
-					     MDIO_PMA_PMD_CR1,
-					     IXGB_PHY_ADDRESS,
-					     MDIO_PMA_PMD_DID);
+					MDIO_PMA_PMD_CR1,
+					IXGB_PHY_ADDRESS,
+					MDIO_PMA_PMD_DID,
+					MDIO_PMA_PMD_CR1_RESET);
+
+		mdio_reg = ixgb_read_phy_reg( hw,
+						MDIO_PMA_PMD_CR1,
+						IXGB_PHY_ADDRESS,
+						MDIO_PMA_PMD_DID);
 	}
 
 	return;
diff -Nru a/drivers/net/ixgb/ixgb_hw.h b/drivers/net/ixgb/ixgb_hw.h
--- a/drivers/net/ixgb/ixgb_hw.h	2005-03-01 23:38:44 -08:00
+++ b/drivers/net/ixgb/ixgb_hw.h	2005-03-01 23:38:44 -08:00
@@ -616,17 +616,17 @@
 #define IXGB_CONTEXT_DESC_STATUS_DD 0x01
 
 /* Filters */
-#define IXGB_RAR_ENTRIES          16	/* Number of entries in Rx Address array */
 #define IXGB_MC_TBL_SIZE          128	/* Multicast Filter Table (4096 bits) */
 #define IXGB_VLAN_FILTER_TBL_SIZE 128	/* VLAN Filter Table (4096 bits) */
+#define IXGB_RAR_ENTRIES		  3	/* Number of entries in Rx Address array */
 
 #define IXGB_MEMORY_REGISTER_BASE_ADDRESS   0
-#define ENET_HEADER_SIZE            14
-#define ENET_FCS_LENGTH             4
-#define IXGB_MAX_NUM_MULTICAST_ADDRESSES    128
-#define IXGB_MIN_ENET_FRAME_SIZE_WITHOUT_FCS    60
-#define IXGB_MAX_ENET_FRAME_SIZE_WITHOUT_FCS    1514
-#define IXGB_MAX_JUMBO_FRAME_SIZE       0x3F00
+#define ENET_HEADER_SIZE			14
+#define ENET_FCS_LENGTH			 4
+#define IXGB_MAX_NUM_MULTICAST_ADDRESSES	128
+#define IXGB_MIN_ENET_FRAME_SIZE_WITHOUT_FCS	60
+#define IXGB_MAX_ENET_FRAME_SIZE_WITHOUT_FCS	1514
+#define IXGB_MAX_JUMBO_FRAME_SIZE		0x3F00
 
 /* Phy Addresses */
 #define IXGB_OPTICAL_PHY_ADDR 0x0	/* Optical Module phy address */
@@ -789,32 +789,39 @@
 extern boolean_t ixgb_check_for_bad_link(struct ixgb_hw *hw);
 extern boolean_t ixgb_setup_fc(struct ixgb_hw *hw);
 extern void ixgb_clear_hw_cntrs(struct ixgb_hw *hw);
-extern boolean_t mac_addr_valid(uint8_t * mac_addr);
+extern boolean_t mac_addr_valid(uint8_t *mac_addr);
 
 extern uint16_t ixgb_read_phy_reg(struct ixgb_hw *hw,
-				  uint32_t reg_addr,
-				  uint32_t phy_addr, uint32_t device_type);
+				uint32_t reg_addr,
+				uint32_t phy_addr,
+				uint32_t device_type);
 
 extern void ixgb_write_phy_reg(struct ixgb_hw *hw,
-			       uint32_t reg_addr,
-			       uint32_t phy_addr,
-			       uint32_t device_type, uint16_t data);
+				uint32_t reg_addr,
+				uint32_t phy_addr,
+				uint32_t device_type,
+				uint16_t data);
+
+extern void ixgb_rar_set(struct ixgb_hw *hw,
+				uint8_t *addr,
+				uint32_t index);
 
-extern void ixgb_rar_set(struct ixgb_hw *hw, uint8_t * addr, uint32_t index);
 
 /* Filters (multicast, vlan, receive) */
 extern void ixgb_mc_addr_list_update(struct ixgb_hw *hw,
-				     uint8_t * mc_addr_list,
-				     uint32_t mc_addr_count, uint32_t pad);
+				   uint8_t *mc_addr_list,
+				   uint32_t mc_addr_count,
+				   uint32_t pad);
 
 /* Vfta functions */
 extern void ixgb_write_vfta(struct ixgb_hw *hw,
-			    uint32_t offset, uint32_t value);
+				 uint32_t offset,
+				 uint32_t value);
 
 extern void ixgb_clear_vfta(struct ixgb_hw *hw);
 
 /* Access functions to eeprom data */
-void ixgb_get_ee_mac_addr(struct ixgb_hw *hw, uint8_t * mac_addr);
+void ixgb_get_ee_mac_addr(struct ixgb_hw *hw, uint8_t *mac_addr);
 uint16_t ixgb_get_ee_compatibility(struct ixgb_hw *hw);
 uint32_t ixgb_get_ee_pba_number(struct ixgb_hw *hw);
 uint16_t ixgb_get_ee_init_ctrl_reg_1(struct ixgb_hw *hw);
@@ -832,6 +839,9 @@
 /* Everything else */
 void ixgb_led_on(struct ixgb_hw *hw);
 void ixgb_led_off(struct ixgb_hw *hw);
-void ixgb_write_pci_cfg(struct ixgb_hw *hw, uint32_t reg, uint16_t * value);
+void ixgb_write_pci_cfg(struct ixgb_hw *hw,
+			 uint32_t reg,
+			 uint16_t * value);
 
-#endif				/* _IXGB_HW_H_ */
+
+#endif /* _IXGB_HW_H_ */
diff -Nru a/drivers/net/ixgb/ixgb_ids.h b/drivers/net/ixgb/ixgb_ids.h
--- a/drivers/net/ixgb/ixgb_ids.h	2005-03-01 23:38:57 -08:00
+++ b/drivers/net/ixgb/ixgb_ids.h	2005-03-01 23:38:57 -08:00
@@ -33,21 +33,16 @@
 ** The Device and Vendor IDs for 10 Gigabit MACs
 **********************************************************************/
 
-#define INTEL_VENDOR_ID         0x8086
-#define INTEL_SUBVENDOR_ID      0x8086
+#define INTEL_VENDOR_ID             0x8086
+#define INTEL_SUBVENDOR_ID          0x8086
 
-#define IXGB_DEVICE_ID_82597EX      0x1048
-#define IXGB_DEVICE_ID_82597EX_SR   0x1A48
 
-#define IXGB_SUBDEVICE_ID_A11F  0xA11F
-#define IXGB_SUBDEVICE_ID_A01F  0xA01F
+#define IXGB_DEVICE_ID_82597EX      0x1048   
+#define IXGB_DEVICE_ID_82597EX_SR   0x1A48   
+#define IXGB_DEVICE_ID_82597EX_LR   0x1B48
+#define IXGB_SUBDEVICE_ID_A11F      0xA11F   
+#define IXGB_SUBDEVICE_ID_A01F      0xA01F   
 
-#define IXGB_SUBDEVICE_ID_A15F  0xA15F
-#define IXGB_SUBDEVICE_ID_A05F  0xA05F
-
-#define IXGB_SUBDEVICE_ID_A12F  0xA12F
-#define IXGB_SUBDEVICE_ID_A02F  0xA02F
-
-#endif				/* #ifndef _IXGB_IDS_H_ */
+#endif /* #ifndef _IXGB_IDS_H_ */
 
 /* End of File */
diff -Nru a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c
--- a/drivers/net/ixgb/ixgb_main.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/net/ixgb/ixgb_main.c	2005-03-01 23:39:18 -08:00
@@ -28,10 +28,23 @@
 
 #include "ixgb.h"
 
+/* Change Log
+ * 1.0.84 10/26/04
+ * - reset buffer_info->dma in Tx resource cleanup logic
+ * 1.0.83 10/12/04
+ * - sparse cleanup - shemminger@osdl.org
+ * - fix tx resource cleanup logic
+ */
+
 char ixgb_driver_name[] = "ixgb";
 char ixgb_driver_string[] = "Intel(R) PRO/10GbE Network Driver";
-char ixgb_driver_version[] = "1.0.66-k2";
-char ixgb_copyright[] = "Copyright (c) 2001-2004 Intel Corporation.";
+#ifndef CONFIG_IXGB_NAPI
+#define DRIVERNAPI
+#else
+#define DRIVERNAPI "-NAPI"
+#endif
+char ixgb_driver_version[] = "1.0.87-k2"DRIVERNAPI;
+char ixgb_copyright[] = "Copyright (c) 1999-2004 Intel Corporation.";
 
 /* ixgb_pci_tbl - PCI Device ID Table
  *
@@ -46,6 +59,8 @@
 	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
 	{INTEL_VENDOR_ID, IXGB_DEVICE_ID_82597EX_SR,
 	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{INTEL_VENDOR_ID, IXGB_DEVICE_ID_82597EX_LR,  
+	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
 
 	/* required last entry */
 	{0,}
@@ -55,11 +70,14 @@
 
 /* Local Function Prototypes */
 
-static inline void ixgb_irq_disable(struct ixgb_adapter *adapter);
-static inline void ixgb_irq_enable(struct ixgb_adapter *adapter);
 int ixgb_up(struct ixgb_adapter *adapter);
 void ixgb_down(struct ixgb_adapter *adapter, boolean_t kill_watchdog);
 void ixgb_reset(struct ixgb_adapter *adapter);
+int ixgb_setup_tx_resources(struct ixgb_adapter *adapter);
+int ixgb_setup_rx_resources(struct ixgb_adapter *adapter);
+void ixgb_free_tx_resources(struct ixgb_adapter *adapter);
+void ixgb_free_rx_resources(struct ixgb_adapter *adapter);
+void ixgb_update_stats(struct ixgb_adapter *adapter);
 
 static int ixgb_init_module(void);
 static void ixgb_exit_module(void);
@@ -68,27 +86,19 @@
 static int ixgb_sw_init(struct ixgb_adapter *adapter);
 static int ixgb_open(struct net_device *netdev);
 static int ixgb_close(struct net_device *netdev);
-static int ixgb_setup_tx_resources(struct ixgb_adapter *adapter);
-static int ixgb_setup_rx_resources(struct ixgb_adapter *adapter);
 static void ixgb_configure_tx(struct ixgb_adapter *adapter);
 static void ixgb_configure_rx(struct ixgb_adapter *adapter);
 static void ixgb_setup_rctl(struct ixgb_adapter *adapter);
 static void ixgb_clean_tx_ring(struct ixgb_adapter *adapter);
 static void ixgb_clean_rx_ring(struct ixgb_adapter *adapter);
-static void ixgb_free_tx_resources(struct ixgb_adapter *adapter);
-static void ixgb_free_rx_resources(struct ixgb_adapter *adapter);
 static void ixgb_set_multi(struct net_device *netdev);
 static void ixgb_watchdog(unsigned long data);
 static int ixgb_xmit_frame(struct sk_buff *skb, struct net_device *netdev);
 static struct net_device_stats *ixgb_get_stats(struct net_device *netdev);
 static int ixgb_change_mtu(struct net_device *netdev, int new_mtu);
 static int ixgb_set_mac(struct net_device *netdev, void *p);
-static void ixgb_update_stats(struct ixgb_adapter *adapter);
 static irqreturn_t ixgb_intr(int irq, void *data, struct pt_regs *regs);
 static boolean_t ixgb_clean_tx_irq(struct ixgb_adapter *adapter);
-static inline void ixgb_rx_checksum(struct ixgb_adapter *adapter,
-				    struct ixgb_rx_desc *rx_desc,
-				    struct sk_buff *skb);
 #ifdef CONFIG_IXGB_NAPI
 static int ixgb_clean(struct net_device *netdev, int *budget);
 static boolean_t ixgb_clean_rx_irq(struct ixgb_adapter *adapter,
@@ -97,6 +107,7 @@
 static boolean_t ixgb_clean_rx_irq(struct ixgb_adapter *adapter);
 #endif
 static void ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter);
+void ixgb_set_ethtool_ops(struct net_device *netdev);
 static void ixgb_tx_timeout(struct net_device *dev);
 static void ixgb_tx_timeout_task(struct net_device *dev);
 static void ixgb_vlan_rx_register(struct net_device *netdev,
@@ -123,7 +134,6 @@
 /* Exported from other modules */
 
 extern void ixgb_check_options(struct ixgb_adapter *adapter);
-extern struct ethtool_ops ixgb_ethtool_ops;
 
 static struct pci_driver ixgb_driver = {
 	.name = ixgb_driver_name,
@@ -152,7 +162,8 @@
  * loaded. All it does is register with the PCI subsystem.
  **/
 
-static int __init ixgb_init_module(void)
+static int __init
+ixgb_init_module(void)
 {
 	int ret;
 	printk(KERN_INFO "%s - version %s\n",
@@ -161,7 +172,7 @@
 	printk(KERN_INFO "%s\n", ixgb_copyright);
 
 	ret = pci_module_init(&ixgb_driver);
-	if (ret >= 0) {
+	if(ret >= 0) {
 		register_reboot_notifier(&ixgb_notifier_reboot);
 	}
 	return ret;
@@ -176,7 +187,8 @@
  * from memory.
  **/
 
-static void __exit ixgb_exit_module(void)
+static void __exit
+ixgb_exit_module(void)
 {
 	unregister_reboot_notifier(&ixgb_notifier_reboot);
 	pci_unregister_driver(&ixgb_driver);
@@ -189,7 +201,8 @@
  * @adapter: board private structure
  **/
 
-static inline void ixgb_irq_disable(struct ixgb_adapter *adapter)
+static inline void
+ixgb_irq_disable(struct ixgb_adapter *adapter)
 {
 	atomic_inc(&adapter->irq_sem);
 	IXGB_WRITE_REG(&adapter->hw, IMC, ~0);
@@ -202,17 +215,19 @@
  * @adapter: board private structure
  **/
 
-static inline void ixgb_irq_enable(struct ixgb_adapter *adapter)
+static inline void
+ixgb_irq_enable(struct ixgb_adapter *adapter)
 {
-	if (atomic_dec_and_test(&adapter->irq_sem)) {
+	if(atomic_dec_and_test(&adapter->irq_sem)) {
 		IXGB_WRITE_REG(&adapter->hw, IMS,
-			       IXGB_INT_RXT0 | IXGB_INT_RXDMT0 | IXGB_INT_TXDW |
-			       IXGB_INT_RXO | IXGB_INT_LSC);
+			   IXGB_INT_RXT0 | IXGB_INT_RXDMT0 | IXGB_INT_TXDW |
+			   IXGB_INT_RXO | IXGB_INT_LSC);
 		IXGB_WRITE_FLUSH(&adapter->hw);
 	}
 }
 
-int ixgb_up(struct ixgb_adapter *adapter)
+int
+ixgb_up(struct ixgb_adapter *adapter)
 {
 	struct net_device *netdev = adapter->netdev;
 	int err;
@@ -230,27 +245,44 @@
 	ixgb_configure_rx(adapter);
 	ixgb_alloc_rx_buffers(adapter);
 
-	if ((err = request_irq(adapter->pdev->irq, &ixgb_intr,
-			       SA_SHIRQ | SA_SAMPLE_RANDOM,
-			       netdev->name, netdev)))
+#ifdef CONFIG_PCI_MSI
+	{
+	boolean_t pcix = (IXGB_READ_REG(&adapter->hw, STATUS) & 
+						  IXGB_STATUS_PCIX_MODE) ? TRUE : FALSE;
+	adapter->have_msi = TRUE;
+
+	if (!pcix)
+	   adapter->have_msi = FALSE;
+	else if((err = pci_enable_msi(adapter->pdev))) {
+		printk (KERN_ERR
+		 "Unable to allocate MSI interrupt Error: %d\n", err);
+		adapter->have_msi = FALSE;
+		/* proceed to try to request regular interrupt */
+	}
+	}
+
+#endif
+	if((err = request_irq(adapter->pdev->irq, &ixgb_intr,
+				  SA_SHIRQ | SA_SAMPLE_RANDOM,
+				  netdev->name, netdev)))
 		return err;
 
 	/* disable interrupts and get the hardware into a known state */
 	IXGB_WRITE_REG(&adapter->hw, IMC, 0xffffffff);
 
-	if ((hw->max_frame_size != max_frame) ||
-	    (hw->max_frame_size !=
-	     (IXGB_READ_REG(hw, MFS) >> IXGB_MFS_SHIFT))) {
+	if((hw->max_frame_size != max_frame) ||
+		(hw->max_frame_size !=
+		(IXGB_READ_REG(hw, MFS) >> IXGB_MFS_SHIFT))) {
 
 		hw->max_frame_size = max_frame;
 
 		IXGB_WRITE_REG(hw, MFS, hw->max_frame_size << IXGB_MFS_SHIFT);
 
-		if (hw->max_frame_size >
-		    IXGB_MAX_ENET_FRAME_SIZE_WITHOUT_FCS + ENET_FCS_LENGTH) {
+		if(hw->max_frame_size >
+		   IXGB_MAX_ENET_FRAME_SIZE_WITHOUT_FCS + ENET_FCS_LENGTH) {
 			uint32_t ctrl0 = IXGB_READ_REG(hw, CTRL0);
 
-			if (!(ctrl0 & IXGB_CTRL0_JFE)) {
+			if(!(ctrl0 & IXGB_CTRL0_JFE)) {
 				ctrl0 |= IXGB_CTRL0_JFE;
 				IXGB_WRITE_REG(hw, CTRL0, ctrl0);
 			}
@@ -263,13 +295,19 @@
 	return 0;
 }
 
-void ixgb_down(struct ixgb_adapter *adapter, boolean_t kill_watchdog)
+void
+ixgb_down(struct ixgb_adapter *adapter, boolean_t kill_watchdog)
 {
 	struct net_device *netdev = adapter->netdev;
 
 	ixgb_irq_disable(adapter);
 	free_irq(adapter->pdev->irq, netdev);
-	if (kill_watchdog)
+#ifdef CONFIG_PCI_MSI
+	if(adapter->have_msi == TRUE)
+		pci_disable_msi(adapter->pdev);
+
+#endif
+	if(kill_watchdog)
 		del_timer_sync(&adapter->watchdog_timer);
 	adapter->link_speed = 0;
 	adapter->link_duplex = 0;
@@ -281,11 +319,12 @@
 	ixgb_clean_rx_ring(adapter);
 }
 
-void ixgb_reset(struct ixgb_adapter *adapter)
+void
+ixgb_reset(struct ixgb_adapter *adapter)
 {
 
 	ixgb_adapter_stop(&adapter->hw);
-	if (!ixgb_init_hw(&adapter->hw))
+	if(!ixgb_init_hw(&adapter->hw))
 		IXGB_DBG("ixgb_init_hw failed.\n");
 }
 
@@ -302,7 +341,8 @@
  **/
 
 static int __devinit
-ixgb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+ixgb_probe(struct pci_dev *pdev,
+		const struct pci_device_id *ent)
 {
 	struct net_device *netdev = NULL;
 	struct ixgb_adapter *adapter;
@@ -313,26 +353,26 @@
 	int i;
 	int err;
 
-	if ((err = pci_enable_device(pdev)))
+	if((err = pci_enable_device(pdev)))
 		return err;
 
-	if (!(err = pci_set_dma_mask(pdev, DMA_64BIT_MASK))) {
+	if(!(err = pci_set_dma_mask(pdev, DMA_64BIT_MASK))) {
 		pci_using_dac = 1;
 	} else {
-		if ((err = pci_set_dma_mask(pdev, DMA_32BIT_MASK))) {
+		if((err = pci_set_dma_mask(pdev, DMA_32BIT_MASK))) {
 			IXGB_ERR("No usable DMA configuration, aborting\n");
 			return err;
 		}
 		pci_using_dac = 0;
 	}
 
-	if ((err = pci_request_regions(pdev, ixgb_driver_name)))
+	if((err = pci_request_regions(pdev, ixgb_driver_name)))
 		return err;
 
 	pci_set_master(pdev);
 
 	netdev = alloc_etherdev(sizeof(struct ixgb_adapter));
-	if (!netdev) {
+	if(!netdev) {
 		err = -ENOMEM;
 		goto err_alloc_etherdev;
 	}
@@ -350,15 +390,15 @@
 	mmio_len = pci_resource_len(pdev, BAR_0);
 
 	adapter->hw.hw_addr = ioremap(mmio_start, mmio_len);
-	if (!adapter->hw.hw_addr) {
+	if(!adapter->hw.hw_addr) {
 		err = -EIO;
 		goto err_ioremap;
 	}
 
-	for (i = BAR_1; i <= BAR_5; i++) {
-		if (pci_resource_len(pdev, i) == 0)
+	for(i = BAR_1; i <= BAR_5; i++) {
+		if(pci_resource_len(pdev, i) == 0)
 			continue;
-		if (pci_resource_flags(pdev, i) & IORESOURCE_IO) {
+		if(pci_resource_flags(pdev, i) & IORESOURCE_IO) {
 			adapter->hw.io_base = pci_resource_start(pdev, i);
 			break;
 		}
@@ -371,9 +411,9 @@
 	netdev->set_multicast_list = &ixgb_set_multi;
 	netdev->set_mac_address = &ixgb_set_mac;
 	netdev->change_mtu = &ixgb_change_mtu;
+	ixgb_set_ethtool_ops(netdev);
 	netdev->tx_timeout = &ixgb_tx_timeout;
 	netdev->watchdog_timeo = HZ;
-	SET_ETHTOOL_OPS(netdev, &ixgb_ethtool_ops);
 #ifdef CONFIG_IXGB_NAPI
 	netdev->poll = &ixgb_clean;
 	netdev->weight = 64;
@@ -395,22 +435,24 @@
 
 	/* setup the private structure */
 
-	if ((err = ixgb_sw_init(adapter)))
+	if((err = ixgb_sw_init(adapter)))
 		goto err_sw_init;
 
 	netdev->features = NETIF_F_SG |
-	    NETIF_F_HW_CSUM |
-	    NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER;
+			   NETIF_F_HW_CSUM |
+			   NETIF_F_HW_VLAN_TX |
+			   NETIF_F_HW_VLAN_RX |
+			   NETIF_F_HW_VLAN_FILTER;
 #ifdef NETIF_F_TSO
 	netdev->features |= NETIF_F_TSO;
 #endif
 
-	if (pci_using_dac)
+	if(pci_using_dac)
 		netdev->features |= NETIF_F_HIGHDMA;
 
 	/* make sure the EEPROM is good */
 
-	if (!ixgb_validate_eeprom_checksum(&adapter->hw)) {
+	if(!ixgb_validate_eeprom_checksum(&adapter->hw)) {
 		printk(KERN_ERR "The EEPROM Checksum Is Not Valid\n");
 		err = -EIO;
 		goto err_eeprom;
@@ -418,7 +460,7 @@
 
 	ixgb_get_ee_mac_addr(&adapter->hw, netdev->dev_addr);
 
-	if (!is_valid_ether_addr(netdev->dev_addr)) {
+	if(!is_valid_ether_addr(netdev->dev_addr)) {
 		err = -EIO;
 		goto err_eeprom;
 	}
@@ -432,7 +474,7 @@
 	INIT_WORK(&adapter->tx_timeout_task,
 		  (void (*)(void *))ixgb_tx_timeout_task, netdev);
 
-	if ((err = register_netdev(netdev)))
+	if((err = register_netdev(netdev)))
 		goto err_register;
 
 	/* we're going to reset, so assume we have no link for now */
@@ -441,7 +483,7 @@
 	netif_stop_queue(netdev);
 
 	printk(KERN_INFO "%s: Intel(R) PRO/10GbE Network Connection\n",
-	       netdev->name);
+		   netdev->name);
 	ixgb_check_options(adapter);
 	/* reset the hardware with the new settings */
 
@@ -450,13 +492,13 @@
 	cards_found++;
 	return 0;
 
-      err_register:
-      err_sw_init:
-      err_eeprom:
+err_register:
+err_sw_init:
+err_eeprom:
 	iounmap(adapter->hw.hw_addr);
-      err_ioremap:
+err_ioremap:
 	free_netdev(netdev);
-      err_alloc_etherdev:
+err_alloc_etherdev:
 	pci_release_regions(pdev);
 	return err;
 }
@@ -471,7 +513,8 @@
  * memory.
  **/
 
-static void __devexit ixgb_remove(struct pci_dev *pdev)
+static void __devexit
+ixgb_remove(struct pci_dev *pdev)
 {
 	struct net_device *netdev = pci_get_drvdata(pdev);
 	struct ixgb_adapter *adapter = netdev->priv;
@@ -493,7 +536,8 @@
  * OS network device settings (MTU size).
  **/
 
-static int __devinit ixgb_sw_init(struct ixgb_adapter *adapter)
+static int __devinit
+ixgb_sw_init(struct ixgb_adapter *adapter)
 {
 	struct ixgb_hw *hw = &adapter->hw;
 	struct net_device *netdev = adapter->netdev;
@@ -510,9 +554,10 @@
 
 	hw->max_frame_size = netdev->mtu + ENET_HEADER_SIZE + ENET_FCS_LENGTH;
 
-	if ((hw->device_id == IXGB_DEVICE_ID_82597EX)
-	    || (hw->device_id == IXGB_DEVICE_ID_82597EX_SR))
-		hw->mac_type = ixgb_82597;
+	if((hw->device_id == IXGB_DEVICE_ID_82597EX)
+	   ||(hw->device_id == IXGB_DEVICE_ID_82597EX_LR)
+	   ||(hw->device_id == IXGB_DEVICE_ID_82597EX_SR))
+			hw->mac_type = ixgb_82597;
 	else {
 		/* should never have loaded on this device */
 		printk(KERN_ERR "ixgb: unsupported device id\n");
@@ -540,31 +585,32 @@
  * and the stack is notified that the interface is ready.
  **/
 
-static int ixgb_open(struct net_device *netdev)
+static int
+ixgb_open(struct net_device *netdev)
 {
 	struct ixgb_adapter *adapter = netdev->priv;
 	int err;
 
 	/* allocate transmit descriptors */
 
-	if ((err = ixgb_setup_tx_resources(adapter)))
+	if((err = ixgb_setup_tx_resources(adapter)))
 		goto err_setup_tx;
 
 	/* allocate receive descriptors */
 
-	if ((err = ixgb_setup_rx_resources(adapter)))
+	if((err = ixgb_setup_rx_resources(adapter)))
 		goto err_setup_rx;
 
-	if ((err = ixgb_up(adapter)))
+	if((err = ixgb_up(adapter)))
 		goto err_up;
 
 	return 0;
 
-      err_up:
+err_up:
 	ixgb_free_rx_resources(adapter);
-      err_setup_rx:
+err_setup_rx:
 	ixgb_free_tx_resources(adapter);
-      err_setup_tx:
+err_setup_tx:
 	ixgb_reset(adapter);
 
 	return err;
@@ -582,7 +628,8 @@
  * hardware, and all transmit and receive resources are freed.
  **/
 
-static int ixgb_close(struct net_device *netdev)
+static int
+ixgb_close(struct net_device *netdev)
 {
 	struct ixgb_adapter *adapter = netdev->priv;
 
@@ -601,15 +648,16 @@
  * Return 0 on success, negative on failure
  **/
 
-static int ixgb_setup_tx_resources(struct ixgb_adapter *adapter)
+int
+ixgb_setup_tx_resources(struct ixgb_adapter *adapter)
 {
 	struct ixgb_desc_ring *txdr = &adapter->tx_ring;
 	struct pci_dev *pdev = adapter->pdev;
 	int size;
 
 	size = sizeof(struct ixgb_buffer) * txdr->count;
-	txdr->buffer_info = kmalloc(size, GFP_KERNEL);
-	if (!txdr->buffer_info) {
+	txdr->buffer_info = vmalloc(size);
+	if(!txdr->buffer_info) {
 		return -ENOMEM;
 	}
 	memset(txdr->buffer_info, 0, size);
@@ -620,8 +668,8 @@
 	IXGB_ROUNDUP(txdr->size, 4096);
 
 	txdr->desc = pci_alloc_consistent(pdev, txdr->size, &txdr->dma);
-	if (!txdr->desc) {
-		kfree(txdr->buffer_info);
+	if(!txdr->desc) {
+		vfree(txdr->buffer_info);
 		return -ENOMEM;
 	}
 	memset(txdr->desc, 0, txdr->size);
@@ -639,7 +687,8 @@
  * Configure the Tx unit of the MAC after a reset.
  **/
 
-static void ixgb_configure_tx(struct ixgb_adapter *adapter)
+static void
+ixgb_configure_tx(struct ixgb_adapter *adapter)
 {
 	uint64_t tdba = adapter->tx_ring.dma;
 	uint32_t tdlen = adapter->tx_ring.count * sizeof(struct ixgb_tx_desc);
@@ -679,8 +728,8 @@
 
 	/* Setup Transmit Descriptor Settings for this adapter */
 	adapter->tx_cmd_type =
-	    IXGB_TX_DESC_TYPE
-	    | (adapter->tx_int_delay_enable ? IXGB_TX_DESC_CMD_IDE : 0);
+		IXGB_TX_DESC_TYPE 
+		| (adapter->tx_int_delay_enable ? IXGB_TX_DESC_CMD_IDE : 0);
 }
 
 /**
@@ -690,15 +739,16 @@
  * Returns 0 on success, negative on failure
  **/
 
-static int ixgb_setup_rx_resources(struct ixgb_adapter *adapter)
+int
+ixgb_setup_rx_resources(struct ixgb_adapter *adapter)
 {
 	struct ixgb_desc_ring *rxdr = &adapter->rx_ring;
 	struct pci_dev *pdev = adapter->pdev;
 	int size;
 
 	size = sizeof(struct ixgb_buffer) * rxdr->count;
-	rxdr->buffer_info = kmalloc(size, GFP_KERNEL);
-	if (!rxdr->buffer_info) {
+	rxdr->buffer_info = vmalloc(size);
+	if(!rxdr->buffer_info) {
 		return -ENOMEM;
 	}
 	memset(rxdr->buffer_info, 0, size);
@@ -710,8 +760,8 @@
 
 	rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma);
 
-	if (!rxdr->desc) {
-		kfree(rxdr->buffer_info);
+	if(!rxdr->desc) {
+		vfree(rxdr->buffer_info);
 		return -ENOMEM;
 	}
 	memset(rxdr->desc, 0, rxdr->size);
@@ -727,7 +777,8 @@
  * @adapter: Board private structure
  **/
 
-static void ixgb_setup_rctl(struct ixgb_adapter *adapter)
+static void
+ixgb_setup_rctl(struct ixgb_adapter *adapter)
 {
 	uint32_t rctl;
 
@@ -736,9 +787,9 @@
 	rctl &= ~(3 << IXGB_RCTL_MO_SHIFT);
 
 	rctl |=
-	    IXGB_RCTL_BAM | IXGB_RCTL_RDMTS_1_2 |
-	    IXGB_RCTL_RXEN | IXGB_RCTL_CFF |
-	    (adapter->hw.mc_filter_type << IXGB_RCTL_MO_SHIFT);
+		IXGB_RCTL_BAM | IXGB_RCTL_RDMTS_1_2 | 
+		IXGB_RCTL_RXEN | IXGB_RCTL_CFF | 
+		(adapter->hw.mc_filter_type << IXGB_RCTL_MO_SHIFT);
 
 	rctl |= IXGB_RCTL_SECRC;
 
@@ -768,7 +819,8 @@
  * Configure the Rx unit of the MAC after a reset.
  **/
 
-static void ixgb_configure_rx(struct ixgb_adapter *adapter)
+static void
+ixgb_configure_rx(struct ixgb_adapter *adapter)
 {
 	uint64_t rdba = adapter->rx_ring.dma;
 	uint32_t rdlen = adapter->rx_ring.count * sizeof(struct ixgb_rx_desc);
@@ -797,51 +849,14 @@
 	IXGB_WRITE_REG(hw, RDH, 0);
 	IXGB_WRITE_REG(hw, RDT, 0);
 
-	/* burst 16 or burst when RXT0 */
-	rxdctl = RXDCTL_WTHRESH_DEFAULT << IXGB_RXDCTL_WTHRESH_SHIFT
-	    | RXDCTL_HTHRESH_DEFAULT << IXGB_RXDCTL_HTHRESH_SHIFT
-	    | RXDCTL_PTHRESH_DEFAULT << IXGB_RXDCTL_PTHRESH_SHIFT;
+						/* burst 16 or burst when RXT0*/
+	rxdctl =  RXDCTL_WTHRESH_DEFAULT << IXGB_RXDCTL_WTHRESH_SHIFT 
+			| RXDCTL_HTHRESH_DEFAULT << IXGB_RXDCTL_HTHRESH_SHIFT 
+			| RXDCTL_PTHRESH_DEFAULT << IXGB_RXDCTL_PTHRESH_SHIFT;
 	IXGB_WRITE_REG(hw, RXDCTL, rxdctl);
 
-	if (adapter->raidc) {
-		uint32_t raidc;
-		uint8_t poll_threshold;
-
-		/* Poll every rx_int_delay period, if RBD exists
-		 * Receive Backlog Detection is set to <threshold> 
-		 * Rx Descriptors
-		 * max is 0x3F == set to poll when 504 RxDesc left 
-		 * min is 0 */
-
-		/* polling times are 1 == 0.8192us
-		   2 == 1.6384us
-		   3 == 3.2768us etc
-		   ...
-		   511 == 418 us
-		 */
-#define IXGB_RAIDC_POLL_DEFAULT 122	/* set to poll every ~100 us under load 
-					   also known as 10000 interrupts / sec */
-
-		/* divide this by 2^3 (8) to get a register size count */
-		poll_threshold = ((adapter->rx_ring.count - 1) >> 3);
-		/* poll at half of that size */
-		poll_threshold >>= 1;
-		/* make sure its not bigger than our max */
-		poll_threshold &= 0x3F;
-
-		raidc = IXGB_RAIDC_EN |	/* turn on raidc style moderation */
-		    IXGB_RAIDC_RXT_GATE |	/* don't interrupt with rxt0 while
-						   in RBD mode (polling) */
-		    (IXGB_RAIDC_POLL_DEFAULT << IXGB_RAIDC_POLL_SHIFT) |
-		    /* this sets the regular "min interrupt delay" */
-		    (adapter->rx_int_delay << IXGB_RAIDC_DELAY_SHIFT) |
-		    poll_threshold;
-
-		IXGB_WRITE_REG(hw, RAIDC, raidc);
-	}
-
 	/* Enable Receive Checksum Offload for TCP and UDP */
-	if (adapter->rx_csum == TRUE) {
+	if(adapter->rx_csum == TRUE) {
 		rxcsum = IXGB_READ_REG(hw, RXCSUM);
 		rxcsum |= IXGB_RXCSUM_TUOFL;
 		IXGB_WRITE_REG(hw, RXCSUM, rxcsum);
@@ -859,13 +874,14 @@
  * Free all transmit software resources
  **/
 
-static void ixgb_free_tx_resources(struct ixgb_adapter *adapter)
+void
+ixgb_free_tx_resources(struct ixgb_adapter *adapter)
 {
 	struct pci_dev *pdev = adapter->pdev;
 
 	ixgb_clean_tx_ring(adapter);
 
-	kfree(adapter->tx_ring.buffer_info);
+	vfree(adapter->tx_ring.buffer_info);
 	adapter->tx_ring.buffer_info = NULL;
 
 	pci_free_consistent(pdev, adapter->tx_ring.size,
@@ -874,33 +890,42 @@
 	adapter->tx_ring.desc = NULL;
 }
 
+static inline void
+ixgb_unmap_and_free_tx_resource(struct ixgb_adapter *adapter,
+					struct ixgb_buffer *buffer_info)
+{
+	struct pci_dev *pdev = adapter->pdev;
+	if(buffer_info->dma) {
+		pci_unmap_page(pdev,
+			   buffer_info->dma,
+			   buffer_info->length,
+			   PCI_DMA_TODEVICE);
+		buffer_info->dma = 0;
+	}
+	if(buffer_info->skb) {
+		dev_kfree_skb_any(buffer_info->skb);
+		buffer_info->skb = NULL;
+	}
+}
+
 /**
  * ixgb_clean_tx_ring - Free Tx Buffers
  * @adapter: board private structure
  **/
 
-static void ixgb_clean_tx_ring(struct ixgb_adapter *adapter)
+static void
+ixgb_clean_tx_ring(struct ixgb_adapter *adapter)
 {
 	struct ixgb_desc_ring *tx_ring = &adapter->tx_ring;
 	struct ixgb_buffer *buffer_info;
-	struct pci_dev *pdev = adapter->pdev;
 	unsigned long size;
 	unsigned int i;
 
 	/* Free all the Tx ring sk_buffs */
 
-	for (i = 0; i < tx_ring->count; i++) {
+	for(i = 0; i < tx_ring->count; i++) {
 		buffer_info = &tx_ring->buffer_info[i];
-		if (buffer_info->skb) {
-
-			pci_unmap_page(pdev,
-				       buffer_info->dma,
-				       buffer_info->length, PCI_DMA_TODEVICE);
-
-			dev_kfree_skb(buffer_info->skb);
-
-			buffer_info->skb = NULL;
-		}
+		ixgb_unmap_and_free_tx_resource(adapter, buffer_info);
 	}
 
 	size = sizeof(struct ixgb_buffer) * tx_ring->count;
@@ -924,14 +949,15 @@
  * Free all receive software resources
  **/
 
-static void ixgb_free_rx_resources(struct ixgb_adapter *adapter)
+void
+ixgb_free_rx_resources(struct ixgb_adapter *adapter)
 {
 	struct ixgb_desc_ring *rx_ring = &adapter->rx_ring;
 	struct pci_dev *pdev = adapter->pdev;
 
 	ixgb_clean_rx_ring(adapter);
 
-	kfree(rx_ring->buffer_info);
+	vfree(rx_ring->buffer_info);
 	rx_ring->buffer_info = NULL;
 
 	pci_free_consistent(pdev, rx_ring->size, rx_ring->desc, rx_ring->dma);
@@ -944,7 +970,8 @@
  * @adapter: board private structure
  **/
 
-static void ixgb_clean_rx_ring(struct ixgb_adapter *adapter)
+static void
+ixgb_clean_rx_ring(struct ixgb_adapter *adapter)
 {
 	struct ixgb_desc_ring *rx_ring = &adapter->rx_ring;
 	struct ixgb_buffer *buffer_info;
@@ -954,9 +981,9 @@
 
 	/* Free all the Rx ring sk_buffs */
 
-	for (i = 0; i < rx_ring->count; i++) {
+	for(i = 0; i < rx_ring->count; i++) {
 		buffer_info = &rx_ring->buffer_info[i];
-		if (buffer_info->skb) {
+		if(buffer_info->skb) {
 
 			pci_unmap_single(pdev,
 					 buffer_info->dma,
@@ -991,12 +1018,13 @@
  * Returns 0 on success, negative on failure
  **/
 
-static int ixgb_set_mac(struct net_device *netdev, void *p)
+static int
+ixgb_set_mac(struct net_device *netdev, void *p)
 {
 	struct ixgb_adapter *adapter = netdev->priv;
 	struct sockaddr *addr = p;
 
-	if (!is_valid_ether_addr(addr->sa_data))
+	if(!is_valid_ether_addr(addr->sa_data))
 		return -EADDRNOTAVAIL;
 
 	memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
@@ -1016,7 +1044,8 @@
  * promiscuous mode, and all-multi behavior.
  **/
 
-static void ixgb_set_multi(struct net_device *netdev)
+static void
+ixgb_set_multi(struct net_device *netdev)
 {
 	struct ixgb_adapter *adapter = netdev->priv;
 	struct ixgb_hw *hw = &adapter->hw;
@@ -1028,16 +1057,16 @@
 
 	rctl = IXGB_READ_REG(hw, RCTL);
 
-	if (netdev->flags & IFF_PROMISC) {
+	if(netdev->flags & IFF_PROMISC) {
 		rctl |= (IXGB_RCTL_UPE | IXGB_RCTL_MPE);
-	} else if (netdev->flags & IFF_ALLMULTI) {
+	} else if(netdev->flags & IFF_ALLMULTI) {
 		rctl |= IXGB_RCTL_MPE;
 		rctl &= ~IXGB_RCTL_UPE;
 	} else {
 		rctl &= ~(IXGB_RCTL_UPE | IXGB_RCTL_MPE);
 	}
 
-	if (netdev->mc_count > IXGB_MAX_NUM_MULTICAST_ADDRESSES) {
+	if(netdev->mc_count > IXGB_MAX_NUM_MULTICAST_ADDRESSES) {
 		rctl |= IXGB_RCTL_MPE;
 		IXGB_WRITE_REG(hw, RCTL, rctl);
 	} else {
@@ -1045,10 +1074,10 @@
 
 		IXGB_WRITE_REG(hw, RCTL, rctl);
 
-		for (i = 0, mc_ptr = netdev->mc_list; mc_ptr;
-		     i++, mc_ptr = mc_ptr->next)
+		for(i = 0, mc_ptr = netdev->mc_list; mc_ptr;
+			i++, mc_ptr = mc_ptr->next)
 			memcpy(&mta[i * IXGB_ETH_LENGTH_OF_ADDRESS],
-			       mc_ptr->dmi_addr, IXGB_ETH_LENGTH_OF_ADDRESS);
+				   mc_ptr->dmi_addr, IXGB_ETH_LENGTH_OF_ADDRESS);
 
 		ixgb_mc_addr_list_update(hw, mta, netdev->mc_count, 0);
 	}
@@ -1059,7 +1088,8 @@
  * @data: pointer to netdev cast into an unsigned long
  **/
 
-static void ixgb_watchdog(unsigned long data)
+static void
+ixgb_watchdog(unsigned long data)
 {
 	struct ixgb_adapter *adapter = (struct ixgb_adapter *)data;
 	struct net_device *netdev = adapter->netdev;
@@ -1073,21 +1103,22 @@
 		netif_stop_queue(netdev);
 	}
 
-	if (adapter->hw.link_up) {
-		if (!netif_carrier_ok(netdev)) {
+	if(adapter->hw.link_up) {
+		if(!netif_carrier_ok(netdev)) {
 			printk(KERN_INFO "ixgb: %s NIC Link is Up %d Mbps %s\n",
-			       netdev->name, 10000, "Full Duplex");
+				   netdev->name, 10000, "Full Duplex");
 			adapter->link_speed = 10000;
 			adapter->link_duplex = FULL_DUPLEX;
 			netif_carrier_on(netdev);
 			netif_wake_queue(netdev);
 		}
 	} else {
-		if (netif_carrier_ok(netdev)) {
+		if(netif_carrier_ok(netdev)) {
 			adapter->link_speed = 0;
 			adapter->link_duplex = 0;
 			printk(KERN_INFO
-			       "ixgb: %s NIC Link is Down\n", netdev->name);
+				   "ixgb: %s NIC Link is Down\n",
+				   netdev->name);
 			netif_carrier_off(netdev);
 			netif_stop_queue(netdev);
 
@@ -1096,8 +1127,8 @@
 
 	ixgb_update_stats(adapter);
 
-	if (!netif_carrier_ok(netdev)) {
-		if (IXGB_DESC_UNUSED(txdr) + 1 < txdr->count) {
+	if(!netif_carrier_ok(netdev)) {
+		if(IXGB_DESC_UNUSED(txdr) + 1 < txdr->count) {
 			/* We've lost link, so the controller stops DMA,
 			 * but we've got queued Tx work that's never going
 			 * to get done, so reset controller to flush Tx.
@@ -1108,9 +1139,9 @@
 
 	/* Early detection of hung controller */
 	i = txdr->next_to_clean;
-	if (txdr->buffer_info[i].dma &&
-	    time_after(jiffies, txdr->buffer_info[i].time_stamp + HZ) &&
-	    !(IXGB_READ_REG(&adapter->hw, STATUS) & IXGB_STATUS_TXOFF))
+	if(txdr->buffer_info[i].dma &&
+	   time_after(jiffies, txdr->buffer_info[i].time_stamp + HZ) &&
+	   !(IXGB_READ_REG(&adapter->hw, STATUS) & IXGB_STATUS_TXOFF))
 		netif_stop_queue(netdev);
 
 	/* generate an interrupt to force clean up of any stragglers */
@@ -1133,7 +1164,7 @@
 	uint8_t ipcss, ipcso, tucss, tucso, hdr_len;
 	uint16_t ipcse, tucse, mss;
 
-	if (likely(skb_shinfo(skb)->tso_size)) {
+	if(likely(skb_shinfo(skb)->tso_size)) {
 		hdr_len = ((skb->h.raw - skb->data) + (skb->h.th->doff << 2));
 		mss = skb_shinfo(skb)->tso_size;
 		skb->nh.iph->tot_len = 0;
@@ -1160,22 +1191,16 @@
 		context_desc->mss = cpu_to_le16(mss);
 		context_desc->hdr_len = hdr_len;
 		context_desc->status = 0;
-		context_desc->cmd_type_len = cpu_to_le32(IXGB_CONTEXT_DESC_TYPE
-							 |
-							 IXGB_CONTEXT_DESC_CMD_TSE
-							 |
-							 IXGB_CONTEXT_DESC_CMD_IP
-							 |
-							 IXGB_CONTEXT_DESC_CMD_TCP
-							 |
-							 IXGB_CONTEXT_DESC_CMD_RS
-							 |
-							 IXGB_CONTEXT_DESC_CMD_IDE
-							 | (skb->len -
-							    (hdr_len)));
+		context_desc->cmd_type_len = cpu_to_le32(
+						  IXGB_CONTEXT_DESC_TYPE 
+						| IXGB_CONTEXT_DESC_CMD_TSE
+						| IXGB_CONTEXT_DESC_CMD_IP
+						| IXGB_CONTEXT_DESC_CMD_TCP
+						| IXGB_CONTEXT_DESC_CMD_RS
+						| IXGB_CONTEXT_DESC_CMD_IDE
+						| (skb->len - (hdr_len)));
 
-		if (++i == adapter->tx_ring.count)
-			i = 0;
+		if(++i == adapter->tx_ring.count) i = 0;
 		adapter->tx_ring.next_to_use = i;
 
 		return TRUE;
@@ -1192,7 +1217,7 @@
 	unsigned int i;
 	uint8_t css, cso;
 
-	if (likely(skb->ip_summed == CHECKSUM_HW)) {
+	if(likely(skb->ip_summed == CHECKSUM_HW)) {
 		css = skb->h.raw - skb->data;
 		cso = (skb->h.raw + skb->csum) - skb->data;
 
@@ -1203,16 +1228,16 @@
 		context_desc->tucso = cso;
 		context_desc->tucse = 0;
 		/* zero out any previously existing data in one instruction */
-		*(uint32_t *) & (context_desc->ipcss) = 0;
+		*(uint32_t *)&(context_desc->ipcss) = 0;
 		context_desc->status = 0;
 		context_desc->hdr_len = 0;
 		context_desc->mss = 0;
 		context_desc->cmd_type_len =
-		    cpu_to_le32(IXGB_CONTEXT_DESC_TYPE
-				| IXGB_TX_DESC_CMD_RS | IXGB_TX_DESC_CMD_IDE);
+			cpu_to_le32(IXGB_CONTEXT_DESC_TYPE
+					| IXGB_TX_DESC_CMD_RS 
+					| IXGB_TX_DESC_CMD_IDE);
 
-		if (++i == adapter->tx_ring.count)
-			i = 0;
+		if(++i == adapter->tx_ring.count) i = 0;
 		adapter->tx_ring.next_to_use = i;
 
 		return TRUE;
@@ -1239,45 +1264,46 @@
 
 	i = tx_ring->next_to_use;
 
-	while (len) {
+	while(len) {
 		buffer_info = &tx_ring->buffer_info[i];
 		size = min(len, IXGB_MAX_JUMBO_FRAME_SIZE);
 		buffer_info->length = size;
 		buffer_info->dma =
-		    pci_map_single(adapter->pdev,
-				   skb->data + offset, size, PCI_DMA_TODEVICE);
+			pci_map_single(adapter->pdev,
+				skb->data + offset,
+				size,
+				PCI_DMA_TODEVICE);
 		buffer_info->time_stamp = jiffies;
 
 		len -= size;
 		offset += size;
 		count++;
-		if (++i == tx_ring->count)
-			i = 0;
+		if(++i == tx_ring->count) i = 0;
 	}
 
-	for (f = 0; f < nr_frags; f++) {
+	for(f = 0; f < nr_frags; f++) {
 		struct skb_frag_struct *frag;
 
 		frag = &skb_shinfo(skb)->frags[f];
 		len = frag->size;
 		offset = 0;
 
-		while (len) {
+		while(len) {
 			buffer_info = &tx_ring->buffer_info[i];
 			size = min(len, IXGB_MAX_JUMBO_FRAME_SIZE);
 			buffer_info->length = size;
 			buffer_info->dma =
-			    pci_map_page(adapter->pdev,
-					 frag->page,
-					 frag->page_offset + offset,
-					 size, PCI_DMA_TODEVICE);
+				pci_map_page(adapter->pdev,
+					frag->page,
+					frag->page_offset + offset,
+					size,
+					PCI_DMA_TODEVICE);
 			buffer_info->time_stamp = jiffies;
 
 			len -= size;
 			offset += size;
 			count++;
-			if (++i == tx_ring->count)
-				i = 0;
+			if(++i == tx_ring->count) i = 0;
 		}
 	}
 	i = (i == 0) ? tx_ring->count - 1 : i - 1;
@@ -1288,8 +1314,7 @@
 }
 
 static inline void
-ixgb_tx_queue(struct ixgb_adapter *adapter, int count, int vlan_id,
-	      int tx_flags)
+ixgb_tx_queue(struct ixgb_adapter *adapter, int count, int vlan_id,int tx_flags)
 {
 	struct ixgb_desc_ring *tx_ring = &adapter->tx_ring;
 	struct ixgb_tx_desc *tx_desc = NULL;
@@ -1299,36 +1324,35 @@
 	uint8_t popts = 0;
 	unsigned int i;
 
-	if (tx_flags & IXGB_TX_FLAGS_TSO) {
+	if(tx_flags & IXGB_TX_FLAGS_TSO) {
 		cmd_type_len |= IXGB_TX_DESC_CMD_TSE;
 		popts |= (IXGB_TX_DESC_POPTS_IXSM | IXGB_TX_DESC_POPTS_TXSM);
 	}
 
-	if (tx_flags & IXGB_TX_FLAGS_CSUM)
+	if(tx_flags & IXGB_TX_FLAGS_CSUM)
 		popts |= IXGB_TX_DESC_POPTS_TXSM;
 
-	if (tx_flags & IXGB_TX_FLAGS_VLAN) {
+	if(tx_flags & IXGB_TX_FLAGS_VLAN) {
 		cmd_type_len |= IXGB_TX_DESC_CMD_VLE;
 	}
 
 	i = tx_ring->next_to_use;
 
-	while (count--) {
+	while(count--) {
 		buffer_info = &tx_ring->buffer_info[i];
 		tx_desc = IXGB_TX_DESC(*tx_ring, i);
 		tx_desc->buff_addr = cpu_to_le64(buffer_info->dma);
 		tx_desc->cmd_type_len =
-		    cpu_to_le32(cmd_type_len | buffer_info->length);
+			cpu_to_le32(cmd_type_len | buffer_info->length);
 		tx_desc->status = status;
 		tx_desc->popts = popts;
 		tx_desc->vlan = cpu_to_le16(vlan_id);
 
-		if (++i == tx_ring->count)
-			i = 0;
+		if(++i == tx_ring->count) i = 0;
 	}
 
-	tx_desc->cmd_type_len |= cpu_to_le32(IXGB_TX_DESC_CMD_EOP
-					     | IXGB_TX_DESC_CMD_RS);
+	tx_desc->cmd_type_len |= cpu_to_le32(IXGB_TX_DESC_CMD_EOP 
+				| IXGB_TX_DESC_CMD_RS );
 
 	/* Force memory writes to complete before letting h/w
 	 * know there are new descriptors to fetch.  (Only
@@ -1346,7 +1370,8 @@
 #define DESC_NEEDED TXD_USE_COUNT(IXGB_MAX_DATA_PER_TXD) + \
 	MAX_SKB_FRAGS * TXD_USE_COUNT(PAGE_SIZE) + 1
 
-static int ixgb_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
+static int
+ixgb_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 {
 	struct ixgb_adapter *adapter = netdev->priv;
 	unsigned int first;
@@ -1354,33 +1379,33 @@
 	unsigned long flags;
 	int vlan_id = 0;
 
-	if (skb->len <= 0) {
+	if(skb->len <= 0) {
 		dev_kfree_skb_any(skb);
 		return 0;
 	}
 
 	spin_lock_irqsave(&adapter->tx_lock, flags);
-	if (unlikely(IXGB_DESC_UNUSED(&adapter->tx_ring) < DESC_NEEDED)) {
+	if(unlikely(IXGB_DESC_UNUSED(&adapter->tx_ring) < DESC_NEEDED)) {
 		netif_stop_queue(netdev);
 		spin_unlock_irqrestore(&adapter->tx_lock, flags);
 		return 1;
 	}
 	spin_unlock_irqrestore(&adapter->tx_lock, flags);
 
-	if (adapter->vlgrp && vlan_tx_tag_present(skb)) {
+	if(adapter->vlgrp && vlan_tx_tag_present(skb)) {
 		tx_flags |= IXGB_TX_FLAGS_VLAN;
 		vlan_id = vlan_tx_tag_get(skb);
 	}
 
 	first = adapter->tx_ring.next_to_use;
-
-	if (ixgb_tso(adapter, skb))
+	
+	if(ixgb_tso(adapter, skb))
 		tx_flags |= IXGB_TX_FLAGS_TSO;
-	else if (ixgb_tx_csum(adapter, skb))
+	else if(ixgb_tx_csum(adapter, skb))
 		tx_flags |= IXGB_TX_FLAGS_CSUM;
 
 	ixgb_tx_queue(adapter, ixgb_tx_map(adapter, skb, first), vlan_id,
-		      tx_flags);
+			tx_flags);
 
 	netdev->trans_start = jiffies;
 
@@ -1392,7 +1417,8 @@
  * @netdev: network interface device structure
  **/
 
-static void ixgb_tx_timeout(struct net_device *netdev)
+static void
+ixgb_tx_timeout(struct net_device *netdev)
 {
 	struct ixgb_adapter *adapter = netdev->priv;
 
@@ -1400,14 +1426,13 @@
 	schedule_work(&adapter->tx_timeout_task);
 }
 
-static void ixgb_tx_timeout_task(struct net_device *netdev)
+static void
+ixgb_tx_timeout_task(struct net_device *netdev)
 {
 	struct ixgb_adapter *adapter = netdev->priv;
 
-	netif_device_detach(netdev);
 	ixgb_down(adapter, TRUE);
 	ixgb_up(adapter);
-	netif_device_attach(netdev);
 }
 
 /**
@@ -1418,7 +1443,8 @@
  * The statistics are actually updated from the timer callback.
  **/
 
-static struct net_device_stats *ixgb_get_stats(struct net_device *netdev)
+static struct net_device_stats *
+ixgb_get_stats(struct net_device *netdev)
 {
 	struct ixgb_adapter *adapter = netdev->priv;
 
@@ -1433,27 +1459,28 @@
  * Returns 0 on success, negative on failure
  **/
 
-static int ixgb_change_mtu(struct net_device *netdev, int new_mtu)
+static int
+ixgb_change_mtu(struct net_device *netdev, int new_mtu)
 {
 	struct ixgb_adapter *adapter = netdev->priv;
-	uint32_t old_mtu = adapter->rx_buffer_len;
 	int max_frame = new_mtu + ENET_HEADER_SIZE + ENET_FCS_LENGTH;
+	int old_max_frame = netdev->mtu + ENET_HEADER_SIZE + ENET_FCS_LENGTH;
+
 
-	if ((max_frame < IXGB_MIN_ENET_FRAME_SIZE_WITHOUT_FCS + ENET_FCS_LENGTH)
-	    || (max_frame > IXGB_MAX_JUMBO_FRAME_SIZE + ENET_FCS_LENGTH)) {
+	if((max_frame < IXGB_MIN_ENET_FRAME_SIZE_WITHOUT_FCS + ENET_FCS_LENGTH)
+	   || (max_frame > IXGB_MAX_JUMBO_FRAME_SIZE + ENET_FCS_LENGTH)) {
 		IXGB_ERR("Invalid MTU setting\n");
 		return -EINVAL;
 	}
 
-	if ((max_frame <=
-	     IXGB_MAX_ENET_FRAME_SIZE_WITHOUT_FCS + ENET_FCS_LENGTH)
-	    || (max_frame <= IXGB_RXBUFFER_2048)) {
+	if((max_frame <= IXGB_MAX_ENET_FRAME_SIZE_WITHOUT_FCS + ENET_FCS_LENGTH)
+	   || (max_frame <= IXGB_RXBUFFER_2048)) {
 		adapter->rx_buffer_len = IXGB_RXBUFFER_2048;
 
-	} else if (max_frame <= IXGB_RXBUFFER_4096) {
+	} else if(max_frame <= IXGB_RXBUFFER_4096) {
 		adapter->rx_buffer_len = IXGB_RXBUFFER_4096;
 
-	} else if (max_frame <= IXGB_RXBUFFER_8192) {
+	} else if(max_frame <= IXGB_RXBUFFER_8192) {
 		adapter->rx_buffer_len = IXGB_RXBUFFER_8192;
 
 	} else {
@@ -1462,7 +1489,7 @@
 
 	netdev->mtu = new_mtu;
 
-	if (old_mtu != adapter->rx_buffer_len && netif_running(netdev)) {
+	if(old_max_frame != max_frame && netif_running(netdev)) {
 
 		ixgb_down(adapter, TRUE);
 		ixgb_up(adapter);
@@ -1476,7 +1503,8 @@
  * @adapter: board private structure
  **/
 
-static void ixgb_update_stats(struct ixgb_adapter *adapter)
+void
+ixgb_update_stats(struct ixgb_adapter *adapter)
 {
 	adapter->stats.tprl += IXGB_READ_REG(&adapter->hw, TPRL);
 	adapter->stats.tprh += IXGB_READ_REG(&adapter->hw, TPRH);
@@ -1585,31 +1613,33 @@
  * @pt_regs: CPU registers structure
  **/
 
-static irqreturn_t ixgb_intr(int irq, void *data, struct pt_regs *regs)
+static irqreturn_t
+ixgb_intr(int irq, void *data, struct pt_regs *regs)
 {
 	struct net_device *netdev = data;
 	struct ixgb_adapter *adapter = netdev->priv;
 	struct ixgb_hw *hw = &adapter->hw;
-	uint32_t icr = IXGB_READ_REG(&adapter->hw, ICR);
+	uint32_t icr = IXGB_READ_REG(hw, ICR);
 #ifndef CONFIG_IXGB_NAPI
 	unsigned int i;
 #endif
 
-	if (unlikely(!icr))
-		return IRQ_NONE;	/* Not our interrupt */
+	if(unlikely(!icr))
+		return IRQ_NONE;  /* Not our interrupt */
 
-	if (unlikely(icr & (IXGB_INT_RXSEQ | IXGB_INT_LSC))) {
+	if(unlikely(icr & (IXGB_INT_RXSEQ | IXGB_INT_LSC))) {
 		mod_timer(&adapter->watchdog_timer, jiffies);
 	}
+
 #ifdef CONFIG_IXGB_NAPI
-	if (netif_rx_schedule_prep(netdev)) {
+	if(netif_rx_schedule_prep(netdev)) {
 
 		/* Disable interrupts and register for poll. The flush 
-		   of the posted write is intentionally left out.
-		 */
+		  of the posted write is intentionally left out.
+		*/
 
 		atomic_inc(&adapter->irq_sem);
-		IXGB_WRITE_REG(hw, IMC, ~0);
+		IXGB_WRITE_REG(&adapter->hw, IMC, ~0);
 		__netif_rx_schedule(netdev);
 	}
 #else
@@ -1621,16 +1651,7 @@
 		if(!ixgb_clean_rx_irq(adapter) &
 		   !ixgb_clean_tx_irq(adapter))
 			break;
-	/* if RAIDC:EN == 1 and ICR:RXDMT0 == 1, we need to
-	 * set IMS:RXDMT0 to 1 to restart the RBD timer (POLL)
-	 */
-	if ((icr & IXGB_INT_RXDMT0) && adapter->raidc) {
-		/* ready the timer by writing the clear reg */
-		IXGB_WRITE_REG(hw, IMC, IXGB_INT_RXDMT0);
-		/* now restart it, h/w will decide if its necessary */
-		IXGB_WRITE_REG(hw, IMS, IXGB_INT_RXDMT0);
-	}
-#endif
+#endif 
 	return IRQ_HANDLED;
 }
 
@@ -1640,25 +1661,32 @@
  * @adapter: board private structure
  **/
 
-static int ixgb_clean(struct net_device *netdev, int *budget)
+static int
+ixgb_clean(struct net_device *netdev, int *budget)
 {
 	struct ixgb_adapter *adapter = netdev->priv;
 	int work_to_do = min(*budget, netdev->quota);
+	int tx_cleaned;
 	int work_done = 0;
+	
+	if (!netif_carrier_ok(netdev))
+		goto quit_polling;
 
-	ixgb_clean_tx_irq(adapter);
+	tx_cleaned = ixgb_clean_tx_irq(adapter);
 	ixgb_clean_rx_irq(adapter, &work_done, work_to_do);
 
 	*budget -= work_done;
 	netdev->quota -= work_done;
-
-	if (work_done < work_to_do || !netif_running(netdev)) {
-		netif_rx_complete(netdev);
-		/* RAIDC will be automatically restarted by irq_enable */
+	
+	/* if no Tx cleanup and not enough Rx work done, exit the polling mode */
+	if((!tx_cleaned && (work_done < work_to_do)) || 
+				!netif_running(netdev)) {
+quit_polling:	netif_rx_complete(netdev);
 		ixgb_irq_enable(adapter);
+		return 0;
 	}
 
-	return (work_done >= work_to_do);
+	return 1;
 }
 #endif
 
@@ -1667,11 +1695,11 @@
  * @adapter: board private structure
  **/
 
-static boolean_t ixgb_clean_tx_irq(struct ixgb_adapter *adapter)
+static boolean_t
+ixgb_clean_tx_irq(struct ixgb_adapter *adapter)
 {
 	struct ixgb_desc_ring *tx_ring = &adapter->tx_ring;
 	struct net_device *netdev = adapter->netdev;
-	struct pci_dev *pdev = adapter->pdev;
 	struct ixgb_tx_desc *tx_desc, *eop_desc;
 	struct ixgb_buffer *buffer_info;
 	unsigned int i, eop;
@@ -1681,9 +1709,9 @@
 	eop = tx_ring->buffer_info[i].next_to_watch;
 	eop_desc = IXGB_TX_DESC(*tx_ring, eop);
 
-	while (eop_desc->status & IXGB_TX_DESC_STATUS_DD) {
+	while(eop_desc->status & IXGB_TX_DESC_STATUS_DD) {
 
-		for (cleaned = FALSE; !cleaned;) {
+		for(cleaned = FALSE; !cleaned; ) {
 			tx_desc = IXGB_TX_DESC(*tx_ring, i);
 			buffer_info = &tx_ring->buffer_info[i];
 
@@ -1692,28 +1720,12 @@
 			       IXGB_TX_DESC_POPTS_IXSM))
 				adapter->hw_csum_tx_good++;
 
-			if (buffer_info->dma) {
-
-				pci_unmap_page(pdev,
-					       buffer_info->dma,
-					       buffer_info->length,
-					       PCI_DMA_TODEVICE);
-
-				buffer_info->dma = 0;
-			}
-
-			if (buffer_info->skb) {
-
-				dev_kfree_skb_any(buffer_info->skb);
+			ixgb_unmap_and_free_tx_resource(adapter, buffer_info);
 
-				buffer_info->skb = NULL;
-			}
-
-			*(uint32_t *) & (tx_desc->status) = 0;
+			*(uint32_t *)&(tx_desc->status) = 0;
 
 			cleaned = (i == eop);
-			if (++i == tx_ring->count)
-				i = 0;
+			if(++i == tx_ring->count) i = 0;
 		}
 
 		eop = tx_ring->buffer_info[i].next_to_watch;
@@ -1723,8 +1735,8 @@
 	tx_ring->next_to_clean = i;
 
 	spin_lock(&adapter->tx_lock);
-	if (cleaned && netif_queue_stopped(netdev) && netif_carrier_ok(netdev)
-	    && (IXGB_DESC_UNUSED(tx_ring) > IXGB_TX_QUEUE_WAKE)) {
+	if(cleaned && netif_queue_stopped(netdev) && netif_carrier_ok(netdev) &&
+	   (IXGB_DESC_UNUSED(tx_ring) > IXGB_TX_QUEUE_WAKE)) {
 
 		netif_wake_queue(netdev);
 	}
@@ -1742,20 +1754,21 @@
 
 static inline void
 ixgb_rx_checksum(struct ixgb_adapter *adapter,
-		 struct ixgb_rx_desc *rx_desc, struct sk_buff *skb)
+		 struct ixgb_rx_desc *rx_desc,
+		 struct sk_buff *skb)
 {
 	/* Ignore Checksum bit is set OR
 	 * TCP Checksum has not been calculated
 	 */
-	if ((rx_desc->status & IXGB_RX_DESC_STATUS_IXSM) ||
-	    (!(rx_desc->status & IXGB_RX_DESC_STATUS_TCPCS))) {
+	if((rx_desc->status & IXGB_RX_DESC_STATUS_IXSM) ||
+	   (!(rx_desc->status & IXGB_RX_DESC_STATUS_TCPCS))) {
 		skb->ip_summed = CHECKSUM_NONE;
 		return;
 	}
 
 	/* At this point we know the hardware did the TCP checksum */
 	/* now look at the TCP checksum error bit */
-	if (rx_desc->errors & IXGB_RX_DESC_ERRORS_TCPE) {
+	if(rx_desc->errors & IXGB_RX_DESC_ERRORS_TCPE) {
 		/* let the stack verify checksum errors */
 		skb->ip_summed = CHECKSUM_NONE;
 		adapter->hw_csum_rx_error++;
@@ -1792,18 +1805,22 @@
 	rx_desc = IXGB_RX_DESC(*rx_ring, i);
 	buffer_info = &rx_ring->buffer_info[i];
 
-	while (rx_desc->status & IXGB_RX_DESC_STATUS_DD) {
+	while(rx_desc->status & IXGB_RX_DESC_STATUS_DD) {
 
+#ifdef CONFIG_IXGB_NAPI
+		if(*work_done >= work_to_do)
+			break;
+
+		(*work_done)++;
+#endif
 		skb = buffer_info->skb;
 		prefetch(skb->data);
 
-		if (++i == rx_ring->count)
-			i = 0;
+		if(++i == rx_ring->count) i = 0;
 		next_rxd = IXGB_RX_DESC(*rx_ring, i);
 		prefetch(next_rxd);
 
-		if ((j = i + 1) == rx_ring->count)
-			j = 0;
+		if((j = i + 1) == rx_ring->count) j = 0;
 		next2_buffer = &rx_ring->buffer_info[j];
 		prefetch(next2_buffer);
 
@@ -1811,27 +1828,22 @@
 		next_skb = next_buffer->skb;
 		prefetch(next_skb);
 
-#ifdef CONFIG_IXGB_NAPI
-		if (*work_done >= work_to_do)
-			break;
-
-		(*work_done)++;
-#endif
 
 		cleaned = TRUE;
 
 		pci_unmap_single(pdev,
 				 buffer_info->dma,
-				 buffer_info->length, PCI_DMA_FROMDEVICE);
+				 buffer_info->length,
+				 PCI_DMA_FROMDEVICE);
 
 		length = le16_to_cpu(rx_desc->length);
 
-		if (unlikely(!(rx_desc->status & IXGB_RX_DESC_STATUS_EOP))) {
+		if(unlikely(!(rx_desc->status & IXGB_RX_DESC_STATUS_EOP))) {
 
 			/* All receives must fit into a single buffer */
 
 			IXGB_DBG("Receive packet consumed multiple buffers "
-				 "length<%x>\n", length);
+					 "length<%x>\n", length);
 
 			dev_kfree_skb_irq(skb);
 			rx_desc->status = 0;
@@ -1864,26 +1876,22 @@
 
 		skb->protocol = eth_type_trans(skb, netdev);
 #ifdef CONFIG_IXGB_NAPI
-		if (adapter->vlgrp
-		    && (rx_desc->status & IXGB_RX_DESC_STATUS_VP)) {
+		if(adapter->vlgrp && (rx_desc->status & IXGB_RX_DESC_STATUS_VP)) {
 			vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
-						 le16_to_cpu(rx_desc->
-							     special &
-							     IXGB_RX_DESC_SPECIAL_VLAN_MASK));
+				le16_to_cpu(rx_desc->special) &
+					IXGB_RX_DESC_SPECIAL_VLAN_MASK);
 		} else {
 			netif_receive_skb(skb);
 		}
-#else				/* CONFIG_IXGB_NAPI */
-		if (adapter->vlgrp
-		    && (rx_desc->status & IXGB_RX_DESC_STATUS_VP)) {
+#else /* CONFIG_IXGB_NAPI */
+		if(adapter->vlgrp && (rx_desc->status & IXGB_RX_DESC_STATUS_VP)) {
 			vlan_hwaccel_rx(skb, adapter->vlgrp,
-					le16_to_cpu(rx_desc->
-						    special &
-						    IXGB_RX_DESC_SPECIAL_VLAN_MASK));
+				le16_to_cpu(rx_desc->special) &
+					IXGB_RX_DESC_SPECIAL_VLAN_MASK);
 		} else {
 			netif_rx(skb);
 		}
-#endif				/* CONFIG_IXGB_NAPI */
+#endif /* CONFIG_IXGB_NAPI */
 		netdev->last_rx = jiffies;
 
 		rx_desc->status = 0;
@@ -1905,7 +1913,8 @@
  * @adapter: address of board private structure
  **/
 
-static void ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter)
+static void
+ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter)
 {
 	struct ixgb_desc_ring *rx_ring = &adapter->rx_ring;
 	struct net_device *netdev = adapter->netdev;
@@ -1921,19 +1930,15 @@
 	buffer_info = &rx_ring->buffer_info[i];
 	cleancount = IXGB_DESC_UNUSED(rx_ring);
 
-	/* lessen this to 4 if we're
-	 * in the midst of raidc and rbd is occuring
-	 * because we don't want to delay returning buffers when low
-	 */
-	num_group_tail_writes = adapter->raidc ? 4 : IXGB_RX_BUFFER_WRITE;
+	num_group_tail_writes = IXGB_RX_BUFFER_WRITE;
 
 	/* leave one descriptor unused */
-	while (--cleancount > 0) {
+	while(--cleancount > 0) {
 		rx_desc = IXGB_RX_DESC(*rx_ring, i);
 
 		skb = dev_alloc_skb(adapter->rx_buffer_len + NET_IP_ALIGN);
 
-		if (unlikely(!skb)) {
+		if(unlikely(!skb)) {
 			/* Better luck next round */
 			break;
 		}
@@ -1949,13 +1954,14 @@
 		buffer_info->skb = skb;
 		buffer_info->length = adapter->rx_buffer_len;
 		buffer_info->dma =
-		    pci_map_single(pdev,
+			pci_map_single(pdev,
 				   skb->data,
-				   adapter->rx_buffer_len, PCI_DMA_FROMDEVICE);
+				   adapter->rx_buffer_len,
+				   PCI_DMA_FROMDEVICE);
 
 		rx_desc->buff_addr = cpu_to_le64(buffer_info->dma);
 
-		if ((i & ~(num_group_tail_writes - 1)) == i) {
+		if((i & ~(num_group_tail_writes- 1)) == i) {
 			/* Force memory writes to complete before letting h/w
 			 * know there are new descriptors to fetch.  (Only
 			 * applicable for weak-ordered memory model archs,
@@ -1965,8 +1971,7 @@
 			IXGB_WRITE_REG(&adapter->hw, RDT, i);
 		}
 
-		if (++i == rx_ring->count)
-			i = 0;
+		if(++i == rx_ring->count) i = 0;
 		buffer_info = &rx_ring->buffer_info[i];
 	}
 
@@ -1988,7 +1993,7 @@
 	ixgb_irq_disable(adapter);
 	adapter->vlgrp = grp;
 
-	if (grp) {
+	if(grp) {
 		/* enable VLAN tag insert/strip */
 		ctrl = IXGB_READ_REG(&adapter->hw, CTRL0);
 		ctrl |= IXGB_CTRL0_VME;
@@ -2017,7 +2022,8 @@
 	ixgb_irq_enable(adapter);
 }
 
-static void ixgb_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid)
+static void
+ixgb_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid)
 {
 	struct ixgb_adapter *adapter = netdev->priv;
 	uint32_t vfta, index;
@@ -2030,19 +2036,20 @@
 	ixgb_write_vfta(&adapter->hw, index, vfta);
 }
 
-static void ixgb_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid)
+static void
+ixgb_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid)
 {
 	struct ixgb_adapter *adapter = netdev->priv;
 	uint32_t vfta, index;
 
 	ixgb_irq_disable(adapter);
 
-	if (adapter->vlgrp)
+	if(adapter->vlgrp)
 		adapter->vlgrp->vlan_devices[vid] = NULL;
 
 	ixgb_irq_enable(adapter);
 
-	/* remove VID from filter table */
+	/* remove VID from filter table*/
 
 	index = (vid >> 5) & 0x7F;
 	vfta = IXGB_READ_REG_ARRAY(&adapter->hw, VFTA, index);
@@ -2050,14 +2057,15 @@
 	ixgb_write_vfta(&adapter->hw, index, vfta);
 }
 
-static void ixgb_restore_vlan(struct ixgb_adapter *adapter)
+static void
+ixgb_restore_vlan(struct ixgb_adapter *adapter)
 {
 	ixgb_vlan_rx_register(adapter->netdev, adapter->vlgrp);
 
-	if (adapter->vlgrp) {
+	if(adapter->vlgrp) {
 		uint16_t vid;
-		for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
-			if (!adapter->vlgrp->vlan_devices[vid])
+		for(vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
+			if(!adapter->vlgrp->vlan_devices[vid])
 				continue;
 			ixgb_vlan_rx_add_vid(adapter->netdev, vid);
 		}
@@ -2075,7 +2083,7 @@
 {
 	struct pci_dev *pdev = NULL;
 
-	switch (event) {
+	switch(event) {
 	case SYS_DOWN:
 	case SYS_HALT:
 	case SYS_POWER_OFF:
@@ -2092,14 +2100,15 @@
  * @param pdev pci driver structure used for passing to
  * @param state power state to enter 
  **/
-static int ixgb_suspend(struct pci_dev *pdev, uint32_t state)
+static int
+ixgb_suspend(struct pci_dev *pdev, uint32_t state)
 {
 	struct net_device *netdev = pci_get_drvdata(pdev);
 	struct ixgb_adapter *adapter = netdev->priv;
 
 	netif_device_detach(netdev);
 
-	if (netif_running(netdev))
+	if(netif_running(netdev))
 		ixgb_down(adapter, TRUE);
 
 	pci_save_state(pdev);
diff -Nru a/drivers/net/ixgb/ixgb_osdep.h b/drivers/net/ixgb/ixgb_osdep.h
--- a/drivers/net/ixgb/ixgb_osdep.h	2005-03-01 23:39:07 -08:00
+++ b/drivers/net/ixgb/ixgb_osdep.h	2005-03-01 23:39:07 -08:00
@@ -78,19 +78,19 @@
 #define DEBUGOUT7 DEBUGOUT3
 
 #define IXGB_WRITE_REG(a, reg, value) ( \
-    writel((value), ((a)->hw_addr + IXGB_##reg)))
+	writel((value), ((a)->hw_addr + IXGB_##reg)))
 
 #define IXGB_READ_REG(a, reg) ( \
-    readl((a)->hw_addr + IXGB_##reg))
+	readl((a)->hw_addr + IXGB_##reg))
 
 #define IXGB_WRITE_REG_ARRAY(a, reg, offset, value) ( \
-    writel((value), ((a)->hw_addr + IXGB_##reg + ((offset) << 2))))
+	writel((value), ((a)->hw_addr + IXGB_##reg + ((offset) << 2))))
 
 #define IXGB_READ_REG_ARRAY(a, reg, offset) ( \
-    readl((a)->hw_addr + IXGB_##reg + ((offset) << 2)))
+	readl((a)->hw_addr + IXGB_##reg + ((offset) << 2)))
 
 #define IXGB_WRITE_FLUSH(a) IXGB_READ_REG(a, STATUS)
 
 #define IXGB_MEMCPY memcpy
 
-#endif				/* _IXGB_OSDEP_H_ */
+#endif /* _IXGB_OSDEP_H_ */
diff -Nru a/drivers/net/ixgb/ixgb_param.c b/drivers/net/ixgb/ixgb_param.c
--- a/drivers/net/ixgb/ixgb_param.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/net/ixgb/ixgb_param.c	2005-03-01 23:39:18 -08:00
@@ -34,31 +34,21 @@
 
 #define IXGB_MAX_NIC 8
 
-#define OPTION_UNSET    -1
+#define OPTION_UNSET	-1
 #define OPTION_DISABLED 0
 #define OPTION_ENABLED  1
 
-/* Module Parameters are always initialized to -1, so that the driver
- * can tell the difference between no user specified value or the
- * user asking for the default value.
- * The true default values are loaded in when ixgb_check_options is called.
- *
- * This is a GCC extension to ANSI C.
- * See the item "Labeled Elements in Initializers" in the section
- * "Extensions to the C Language Family" of the GCC documentation.
- */
-
-#define IXGB_PARAM_INIT { [0 ... IXGB_MAX_NIC] = OPTION_UNSET }
-
 /* All parameters are treated the same, as an integer array of values.
  * This macro just reduces the need to repeat the same declaration code
  * over and over (plus this helps to avoid typo bugs).
  */
 
-#define IXGB_PARAM(X, S) \
-static const int __devinitdata X[IXGB_MAX_NIC + 1] = IXGB_PARAM_INIT; \
-MODULE_PARM(X, "1-" __MODULE_STRING(IXGB_MAX_NIC) "i"); \
-MODULE_PARM_DESC(X, S);
+#define IXGB_PARAM_INIT { [0 ... IXGB_MAX_NIC] = OPTION_UNSET }
+#define IXGB_PARAM(X, desc) \
+	static int __devinitdata X[IXGB_MAX_NIC+1] = IXGB_PARAM_INIT; \
+	static int num_##X = 0; \
+	module_param_array_named(X, X, int, &num_##X, 0); \
+	MODULE_PARM_DESC(X, desc);
 
 /* Transmit Descriptor Count
  *
@@ -121,15 +111,6 @@
 
 IXGB_PARAM(RxIntDelay, "Receive Interrupt Delay");
 
-/* Receive Interrupt Moderation enable (uses RxIntDelay too)
- *
- * Valid Range: 0,1
- *
- * Default Value: 1
- */
-
-IXGB_PARAM(RAIDC, "Disable or enable Receive Interrupt Moderation");
-
 /* Receive Flow control high threshold (when we send a pause frame)
  * (FCRTH)
  *
@@ -173,13 +154,6 @@
 
 IXGB_PARAM(IntDelayEnable, "Transmit Interrupt Delay Enable");
 
-#define DEFAULT_TXD			    256
-#define MAX_TXD				   4096
-#define MIN_TXD				     64
-
-#define DEFAULT_RXD			   1024
-#define MAX_RXD				   4096
-#define MIN_RXD				     64
 
 #define DEFAULT_TIDV	   		     32
 #define MAX_TIDV			 0xFFFF
@@ -224,9 +198,10 @@
 	} arg;
 };
 
-static int __devinit ixgb_validate_option(int *value, struct ixgb_option *opt)
+static int __devinit
+ixgb_validate_option(int *value, struct ixgb_option *opt)
 {
-	if (*value == OPTION_UNSET) {
+	if(*value == OPTION_UNSET) {
 		*value = opt->def;
 		return 0;
 	}
@@ -243,32 +218,31 @@
 		}
 		break;
 	case range_option:
-		if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) {
+		if(*value >= opt->arg.r.min && *value <= opt->arg.r.max) {
 			printk(KERN_INFO "%s set to %i\n", opt->name, *value);
 			return 0;
 		}
 		break;
-	case list_option:{
-			int i;
-			struct ixgb_opt_list *ent;
-
-			for (i = 0; i < opt->arg.l.nr; i++) {
-				ent = &opt->arg.l.p[i];
-				if (*value == ent->i) {
-					if (ent->str[0] != '\0')
-						printk(KERN_INFO "%s\n",
-						       ent->str);
-					return 0;
-				}
+	case list_option: {
+		int i;
+		struct ixgb_opt_list *ent;
+
+		for(i = 0; i < opt->arg.l.nr; i++) {
+			ent = &opt->arg.l.p[i];
+			if(*value == ent->i) {
+				if(ent->str[0] != '\0')
+					printk(KERN_INFO "%s\n", ent->str);
+				return 0;
 			}
 		}
+	}
 		break;
 	default:
 		BUG();
 	}
 
 	printk(KERN_INFO "Invalid %s specified (%i) %s\n",
-	       opt->name, *value, opt->err);
+		   opt->name, *value, opt->err);
 	*value = opt->def;
 	return -1;
 }
@@ -285,198 +259,218 @@
  * in a variable in the adapter structure.
  **/
 
-void __devinit ixgb_check_options(struct ixgb_adapter *adapter)
+void __devinit
+ixgb_check_options(struct ixgb_adapter *adapter)
 {
 	int bd = adapter->bd_number;
-	if (bd >= IXGB_MAX_NIC) {
+	if(bd >= IXGB_MAX_NIC) {
 		printk(KERN_NOTICE
-		       "Warning: no configuration for board #%i\n", bd);
+			   "Warning: no configuration for board #%i\n", bd);
 		printk(KERN_NOTICE "Using defaults for all values\n");
-		bd = IXGB_MAX_NIC;
 	}
 
-	{			/* Transmit Descriptor Count */
+	{ /* Transmit Descriptor Count */
 		struct ixgb_option opt = {
 			.type = range_option,
 			.name = "Transmit Descriptors",
-			.err = "using default of " __MODULE_STRING(DEFAULT_TXD),
-			.def = DEFAULT_TXD,
-			.arg = {.r = {.min = MIN_TXD,
-				      .max = MAX_TXD}}
+			.err  = "using default of " __MODULE_STRING(DEFAULT_TXD),
+			.def  = DEFAULT_TXD,
+			.arg  = { .r = { .min = MIN_TXD,
+					 .max = MAX_TXD}}
 		};
 		struct ixgb_desc_ring *tx_ring = &adapter->tx_ring;
 
-		tx_ring->count = TxDescriptors[bd];
-		ixgb_validate_option(&tx_ring->count, &opt);
+		if(num_TxDescriptors > bd) {
+			tx_ring->count = TxDescriptors[bd];
+			ixgb_validate_option(&tx_ring->count, &opt);
+		} else {
+			tx_ring->count = opt.def;
+		}
 		IXGB_ROUNDUP(tx_ring->count, IXGB_REQ_TX_DESCRIPTOR_MULTIPLE);
 	}
-	{			/* Receive Descriptor Count */
+	{ /* Receive Descriptor Count */
 		struct ixgb_option opt = {
 			.type = range_option,
 			.name = "Receive Descriptors",
-			.err = "using default of " __MODULE_STRING(DEFAULT_RXD),
-			.def = DEFAULT_RXD,
-			.arg = {.r = {.min = MIN_RXD,
-				      .max = MAX_RXD}}
+			.err  = "using default of " __MODULE_STRING(DEFAULT_RXD),
+			.def  = DEFAULT_RXD,
+			.arg  = { .r = { .min = MIN_RXD,
+					 .max = MAX_RXD}}
 		};
 		struct ixgb_desc_ring *rx_ring = &adapter->rx_ring;
 
-		rx_ring->count = RxDescriptors[bd];
-		ixgb_validate_option(&rx_ring->count, &opt);
+		if(num_RxDescriptors > bd) {
+			rx_ring->count = RxDescriptors[bd];
+			ixgb_validate_option(&rx_ring->count, &opt);
+		} else {
+			rx_ring->count = opt.def;
+		}
 		IXGB_ROUNDUP(rx_ring->count, IXGB_REQ_RX_DESCRIPTOR_MULTIPLE);
 	}
-	{			/* Receive Checksum Offload Enable */
+	{ /* Receive Checksum Offload Enable */
 		struct ixgb_option opt = {
 			.type = enable_option,
 			.name = "Receive Checksum Offload",
-			.err = "defaulting to Enabled",
-			.def = OPTION_ENABLED
+			.err  = "defaulting to Enabled",
+			.def  = OPTION_ENABLED
 		};
 
-		int rx_csum = XsumRX[bd];
-		ixgb_validate_option(&rx_csum, &opt);
-		adapter->rx_csum = rx_csum;
+		if(num_XsumRX > bd) {
+			int rx_csum = XsumRX[bd];
+			ixgb_validate_option(&rx_csum, &opt);
+			adapter->rx_csum = rx_csum;
+		} else {
+			adapter->rx_csum = opt.def;
+		}
 	}
-	{			/* Flow Control */
+	{ /* Flow Control */
 
 		struct ixgb_opt_list fc_list[] =
-		    { {ixgb_fc_none, "Flow Control Disabled"},
-		{ixgb_fc_rx_pause, "Flow Control Receive Only"},
-		{ixgb_fc_tx_pause, "Flow Control Transmit Only"},
-		{ixgb_fc_full, "Flow Control Enabled"},
-		{ixgb_fc_default, "Flow Control Hardware Default"}
-		};
+			{{ ixgb_fc_none,	"Flow Control Disabled" },
+			 { ixgb_fc_rx_pause,"Flow Control Receive Only" },
+			 { ixgb_fc_tx_pause,"Flow Control Transmit Only" },
+			 { ixgb_fc_full,	"Flow Control Enabled" },
+			 { ixgb_fc_default, "Flow Control Hardware Default" }};
 
 		struct ixgb_option opt = {
 			.type = list_option,
 			.name = "Flow Control",
-			.err = "reading default settings from EEPROM",
-			.def = ixgb_fc_full,
-			.arg = {.l = {.nr = LIST_LEN(fc_list),
-				      .p = fc_list}}
+			.err  = "reading default settings from EEPROM",
+			.def  = ixgb_fc_full,
+			.arg  = { .l = { .nr = LIST_LEN(fc_list),
+					 .p = fc_list }}
 		};
 
-		int fc = FlowControl[bd];
-		ixgb_validate_option(&fc, &opt);
-		adapter->hw.fc.type = fc;
+		if(num_FlowControl > bd) {
+			int fc = FlowControl[bd];
+			ixgb_validate_option(&fc, &opt);
+			adapter->hw.fc.type = fc;
+		} else {
+			adapter->hw.fc.type = opt.def;
+		}
 	}
-	{			/* Receive Flow Control High Threshold */
+	{ /* Receive Flow Control High Threshold */
 		struct ixgb_option opt = {
 			.type = range_option,
 			.name = "Rx Flow Control High Threshold",
-			.err =
-			    "using default of " __MODULE_STRING(DEFAULT_FCRTH),
-			.def = DEFAULT_FCRTH,
-			.arg = {.r = {.min = MIN_FCRTH,
-				      .max = MAX_FCRTH}}
+			.err  = "using default of " __MODULE_STRING(DEFAULT_FCRTH),
+			.def  = DEFAULT_FCRTH,
+			.arg  = { .r = { .min = MIN_FCRTH,
+					 .max = MAX_FCRTH}}
 		};
 
-		adapter->hw.fc.high_water = RxFCHighThresh[bd];
-		ixgb_validate_option(&adapter->hw.fc.high_water, &opt);
-		if (!(adapter->hw.fc.type & ixgb_fc_rx_pause))
-			printk(KERN_INFO
-			       "Ignoring RxFCHighThresh when no RxFC\n");
+		if(num_RxFCHighThresh > bd) {
+			adapter->hw.fc.high_water = RxFCHighThresh[bd];
+			ixgb_validate_option(&adapter->hw.fc.high_water, &opt);
+		} else {
+			adapter->hw.fc.high_water = opt.def;
+		}
+		if(!(adapter->hw.fc.type & ixgb_fc_rx_pause) )
+			printk (KERN_INFO 
+				"Ignoring RxFCHighThresh when no RxFC\n");
 	}
-	{			/* Receive Flow Control Low Threshold */
+	{ /* Receive Flow Control Low Threshold */
 		struct ixgb_option opt = {
 			.type = range_option,
 			.name = "Rx Flow Control Low Threshold",
-			.err =
-			    "using default of " __MODULE_STRING(DEFAULT_FCRTL),
-			.def = DEFAULT_FCRTL,
-			.arg = {.r = {.min = MIN_FCRTL,
-				      .max = MAX_FCRTL}}
+			.err  = "using default of " __MODULE_STRING(DEFAULT_FCRTL),
+			.def  = DEFAULT_FCRTL,
+			.arg  = { .r = { .min = MIN_FCRTL,
+					 .max = MAX_FCRTL}}
 		};
 
-		adapter->hw.fc.low_water = RxFCLowThresh[bd];
-		ixgb_validate_option(&adapter->hw.fc.low_water, &opt);
-		if (!(adapter->hw.fc.type & ixgb_fc_rx_pause))
-			printk(KERN_INFO
-			       "Ignoring RxFCLowThresh when no RxFC\n");
+		if(num_RxFCLowThresh > bd) {
+			adapter->hw.fc.low_water = RxFCLowThresh[bd];
+			ixgb_validate_option(&adapter->hw.fc.low_water, &opt);
+		} else {
+			adapter->hw.fc.low_water = opt.def;
+		}
+		if(!(adapter->hw.fc.type & ixgb_fc_rx_pause) )
+			printk (KERN_INFO 
+				"Ignoring RxFCLowThresh when no RxFC\n");
 	}
-	{			/* Flow Control Pause Time Request */
+	{ /* Flow Control Pause Time Request*/
 		struct ixgb_option opt = {
 			.type = range_option,
 			.name = "Flow Control Pause Time Request",
-			.err =
-			    "using default of "
-			    __MODULE_STRING(DEFAULT_FCPAUSE),
-			.def = DEFAULT_FCPAUSE,
-			.arg = {.r = {.min = MIN_FCPAUSE,
-				      .max = MAX_FCPAUSE}}
+			.err  = "using default of "__MODULE_STRING(DEFAULT_FCPAUSE),
+			.def  = DEFAULT_FCPAUSE,
+			.arg = { .r = { .min = MIN_FCPAUSE,
+					.max = MAX_FCPAUSE}}
 		};
 
-		int pause_time = FCReqTimeout[bd];
-
-		ixgb_validate_option(&pause_time, &opt);
-		if (!(adapter->hw.fc.type & ixgb_fc_rx_pause))
-			printk(KERN_INFO
-			       "Ignoring FCReqTimeout when no RxFC\n");
-		adapter->hw.fc.pause_time = pause_time;
+		if(num_FCReqTimeout > bd) {
+			int pause_time = FCReqTimeout[bd];
+			ixgb_validate_option(&pause_time, &opt);
+			adapter->hw.fc.pause_time = pause_time;
+		} else {
+			adapter->hw.fc.pause_time = opt.def;
+		}
+		if(!(adapter->hw.fc.type & ixgb_fc_rx_pause) )
+			printk (KERN_INFO 
+				"Ignoring FCReqTimeout when no RxFC\n");
 	}
 	/* high low and spacing check for rx flow control thresholds */
 	if (adapter->hw.fc.type & ixgb_fc_rx_pause) {
 		/* high must be greater than low */
 		if (adapter->hw.fc.high_water < (adapter->hw.fc.low_water + 8)) {
 			/* set defaults */
-			printk(KERN_INFO
-			       "RxFCHighThresh must be >= (RxFCLowThresh + 8), "
-			       "Using Defaults\n");
+			printk (KERN_INFO 
+				"RxFCHighThresh must be >= (RxFCLowThresh + 8), "
+				"Using Defaults\n");
 			adapter->hw.fc.high_water = DEFAULT_FCRTH;
-			adapter->hw.fc.low_water = DEFAULT_FCRTL;
+			adapter->hw.fc.low_water  = DEFAULT_FCRTL;
 		}
 	}
-	{			/* Receive Interrupt Delay */
+	{ /* Receive Interrupt Delay */
 		struct ixgb_option opt = {
 			.type = range_option,
 			.name = "Receive Interrupt Delay",
-			.err =
-			    "using default of " __MODULE_STRING(DEFAULT_RDTR),
-			.def = DEFAULT_RDTR,
-			.arg = {.r = {.min = MIN_RDTR,
-				      .max = MAX_RDTR}}
-		};
-
-		adapter->rx_int_delay = RxIntDelay[bd];
-		ixgb_validate_option(&adapter->rx_int_delay, &opt);
-	}
-	{			/* Receive Interrupt Moderation */
-		struct ixgb_option opt = {
-			.type = enable_option,
-			.name = "Advanced Receive Interrupt Moderation",
-			.err = "defaulting to Enabled",
-			.def = OPTION_ENABLED
+			.err  = "using default of " __MODULE_STRING(DEFAULT_RDTR),
+			.def  = DEFAULT_RDTR,
+			.arg  = { .r = { .min = MIN_RDTR,
+					 .max = MAX_RDTR}}
 		};
-		int raidc = RAIDC[bd];
 
-		ixgb_validate_option(&raidc, &opt);
-		adapter->raidc = raidc;
+		if(num_RxIntDelay > bd) {
+			adapter->rx_int_delay = RxIntDelay[bd];
+			ixgb_validate_option(&adapter->rx_int_delay, &opt);
+		} else {
+			adapter->rx_int_delay = opt.def;
+		}
 	}
-	{			/* Transmit Interrupt Delay */
+	{ /* Transmit Interrupt Delay */
 		struct ixgb_option opt = {
 			.type = range_option,
 			.name = "Transmit Interrupt Delay",
-			.err =
-			    "using default of " __MODULE_STRING(DEFAULT_TIDV),
-			.def = DEFAULT_TIDV,
-			.arg = {.r = {.min = MIN_TIDV,
-				      .max = MAX_TIDV}}
+			.err  = "using default of " __MODULE_STRING(DEFAULT_TIDV),
+			.def  = DEFAULT_TIDV,
+			.arg  = { .r = { .min = MIN_TIDV,
+					 .max = MAX_TIDV}}
 		};
 
-		adapter->tx_int_delay = TxIntDelay[bd];
-		ixgb_validate_option(&adapter->tx_int_delay, &opt);
+		if(num_TxIntDelay > bd) {
+			adapter->tx_int_delay = TxIntDelay[bd];
+			ixgb_validate_option(&adapter->tx_int_delay, &opt);
+		} else {
+			adapter->tx_int_delay = opt.def;
+		}
 	}
 
-	{			/* Transmit Interrupt Delay Enable */
+	{ /* Transmit Interrupt Delay Enable */
 		struct ixgb_option opt = {
 			.type = enable_option,
 			.name = "Tx Interrupt Delay Enable",
-			.err = "defaulting to Enabled",
-			.def = OPTION_ENABLED
+			.err  = "defaulting to Enabled",
+			.def  = OPTION_ENABLED
 		};
-		int ide = IntDelayEnable[bd];
 
-		ixgb_validate_option(&ide, &opt);
-		adapter->tx_int_delay_enable = ide;
+		if(num_IntDelayEnable > bd) {
+			int ide = IntDelayEnable[bd];
+			ixgb_validate_option(&ide, &opt);
+			adapter->tx_int_delay_enable = ide;
+		} else {
+			adapter->tx_int_delay_enable = opt.def;
+		}
 	}
 }
diff -Nru a/drivers/net/lance.c b/drivers/net/lance.c
--- a/drivers/net/lance.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/net/lance.c	2005-03-01 23:38:52 -08:00
@@ -327,10 +327,10 @@
 static int dma[MAX_CARDS];
 static int irq[MAX_CARDS];
 
-MODULE_PARM(io, "1-" __MODULE_STRING(MAX_CARDS) "i");
-MODULE_PARM(dma, "1-" __MODULE_STRING(MAX_CARDS) "i");
-MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_CARDS) "i");
-MODULE_PARM(lance_debug, "i");
+module_param_array(io, int, NULL, 0);
+module_param_array(dma, int, NULL, 0);
+module_param_array(irq, int, NULL, 0);
+module_param(lance_debug, int, 0);
 MODULE_PARM_DESC(io, "LANCE/PCnet I/O base address(es),required");
 MODULE_PARM_DESC(dma, "LANCE/PCnet ISA DMA channel (ignored for some devices)");
 MODULE_PARM_DESC(irq, "LANCE/PCnet IRQ number (ignored for some devices)");
diff -Nru a/drivers/net/lne390.c b/drivers/net/lne390.c
--- a/drivers/net/lne390.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/net/lne390.c	2005-03-01 23:39:16 -08:00
@@ -149,8 +149,7 @@
 {
 	free_irq(dev->irq, dev);
 	release_region(dev->base_addr, LNE390_IO_EXTENT);
-	if (ei_status.reg0)
-		iounmap((void *)dev->mem_start);
+	iounmap(ei_status.mem);
 }
 
 #ifndef MODULE
@@ -257,32 +256,22 @@
 	/*
 	   BEWARE!! Some dain-bramaged EISA SCUs will allow you to put
 	   the card mem within the region covered by `normal' RAM  !!!
+
+	   ioremap() will fail in that case.
 	*/
-	if (dev->mem_start > 1024*1024) {	/* phys addr > 1MB */
-		if (dev->mem_start < virt_to_phys(high_memory)) {
-			printk(KERN_CRIT "lne390.c: Card RAM overlaps with normal memory!!!\n");
-			printk(KERN_CRIT "lne390.c: Use EISA SCU to set card memory below 1MB,\n");
-			printk(KERN_CRIT "lne390.c: or to an address above 0x%lx.\n", virt_to_phys(high_memory));
-			printk(KERN_CRIT "lne390.c: Driver NOT installed.\n");
-			ret = -EINVAL;
-			goto cleanup;
-		}
-		dev->mem_start = (unsigned long)ioremap(dev->mem_start, LNE390_STOP_PG*0x100);
-		if (dev->mem_start == 0) {
-			printk(KERN_ERR "lne390.c: Unable to remap card memory above 1MB !!\n");
-			printk(KERN_ERR "lne390.c: Try using EISA SCU to set memory below 1MB.\n");
-			printk(KERN_ERR "lne390.c: Driver NOT installed.\n");
-			ret = -EAGAIN;
-			goto cleanup;
-		}
-		ei_status.reg0 = 1;	/* Use as remap flag */
-		printk("lne390.c: remapped %dkB card memory to virtual address %#lx\n",
-				LNE390_STOP_PG/4, dev->mem_start);
+	ei_status.mem = ioremap(dev->mem_start, LNE390_STOP_PG*0x100);
+	if (!ei_status.mem) {
+		printk(KERN_ERR "lne390.c: Unable to remap card memory above 1MB !!\n");
+		printk(KERN_ERR "lne390.c: Try using EISA SCU to set memory below 1MB.\n");
+		printk(KERN_ERR "lne390.c: Driver NOT installed.\n");
+		ret = -EAGAIN;
+		goto cleanup;
 	}
+	printk("lne390.c: remapped %dkB card memory to virtual address %p\n",
+			LNE390_STOP_PG/4, ei_status.mem);
 
-	dev->mem_end = ei_status.rmem_end = dev->mem_start
-		+ (LNE390_STOP_PG - LNE390_START_PG)*256;
-	ei_status.rmem_start = dev->mem_start + TX_PAGES*256;
+	dev->mem_start = (unsigned long)ei_status.mem;
+	dev->mem_end = dev->mem_start + (LNE390_STOP_PG - LNE390_START_PG)*256;
 
 	/* The 8390 offset is zero for the LNE390 */
 	dev->base_addr = ioaddr;
@@ -352,8 +341,8 @@
 static void
 lne390_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
 {
-	unsigned long hdr_start = dev->mem_start + ((ring_page - LNE390_START_PG)<<8);
-	isa_memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
+	void __iomem *hdr_start = ei_status.mem + ((ring_page - LNE390_START_PG)<<8);
+	memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
 	hdr->count = (hdr->count + 3) & ~3;     /* Round up allocation. */
 }
 
@@ -366,27 +355,28 @@
 static void lne390_block_input(struct net_device *dev, int count, struct sk_buff *skb,
 						  int ring_offset)
 {
-	unsigned long xfer_start = dev->mem_start + ring_offset - (LNE390_START_PG<<8);
+	void __iomem *xfer_start = ei_status.mem + ring_offset - (LNE390_START_PG<<8);
 
-	if (xfer_start + count > ei_status.rmem_end) {
+	if (ring_offset + count > (LNE390_STOP_PG<<8)) {
 		/* Packet wraps over end of ring buffer. */
-		int semi_count = ei_status.rmem_end - xfer_start;
-		isa_memcpy_fromio(skb->data, xfer_start, semi_count);
+		int semi_count = (LNE390_STOP_PG<<8) - ring_offset;
+		memcpy_fromio(skb->data, xfer_start, semi_count);
 		count -= semi_count;
-		isa_memcpy_fromio(skb->data + semi_count, ei_status.rmem_start, count);
+		memcpy_fromio(skb->data + semi_count,
+			ei_status.mem + (TX_PAGES<<8), count);
 	} else {
 		/* Packet is in one chunk. */
-		isa_memcpy_fromio(skb->data, xfer_start, count);
+		memcpy_fromio(skb->data, xfer_start, count);
 	}
 }
 
 static void lne390_block_output(struct net_device *dev, int count,
 				const unsigned char *buf, int start_page)
 {
-	unsigned long shmem = dev->mem_start + ((start_page - LNE390_START_PG)<<8);
+	void __iomem *shmem = ei_status.mem + ((start_page - LNE390_START_PG)<<8);
 
 	count = (count + 3) & ~3;     /* Round up to doubleword */
-	isa_memcpy_toio(shmem, buf, count);
+	memcpy_toio(shmem, buf, count);
 }
 
 static int lne390_open(struct net_device *dev)
@@ -412,9 +402,9 @@
 static int irq[MAX_LNE_CARDS];
 static int mem[MAX_LNE_CARDS];
 
-MODULE_PARM(io, "1-" __MODULE_STRING(MAX_LNE_CARDS) "i");
-MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_LNE_CARDS) "i");
-MODULE_PARM(mem, "1-" __MODULE_STRING(MAX_LNE_CARDS) "i");
+module_param_array(io, int, NULL, 0);
+module_param_array(irq, int, NULL, 0);
+module_param_array(mem, int, NULL, 0);
 MODULE_PARM_DESC(io, "I/O base address(es)");
 MODULE_PARM_DESC(irq, "IRQ number(s)");
 MODULE_PARM_DESC(mem, "memory base address(es)");
diff -Nru a/drivers/net/lp486e.c b/drivers/net/lp486e.c
--- a/drivers/net/lp486e.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/net/lp486e.c	2005-03-01 23:38:54 -08:00
@@ -1302,18 +1302,18 @@
 MODULE_DESCRIPTION("Intel Panther onboard i82596 driver");
 MODULE_LICENSE("GPL");
 
-MODULE_PARM(debug, "i");
-//MODULE_PARM(max_interrupt_work, "i");
-//MODULE_PARM(reverse_probe, "i");
-//MODULE_PARM(rx_copybreak, "i");
-MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i");
-MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
-
 static struct net_device *dev_lp486e;
 static int full_duplex;
 static int options;
 static int io = IOADDR;
 static int irq = IRQ;
+
+module_param(debug, int, 0);
+//module_param(max_interrupt_work, int, 0);
+//module_param(reverse_probe, int, 0);
+//module_param(rx_copybreak, int, 0);
+module_param(options, int, 0);
+module_param(full_duplex, int, 0);
 
 static int __init lp486e_init_module(void) {
 	int err;
diff -Nru a/drivers/net/mace.c b/drivers/net/mace.c
--- a/drivers/net/mace.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/net/mace.c	2005-03-01 23:38:54 -08:00
@@ -40,10 +40,10 @@
 #define TX_DMA_ERR	0x80
 
 struct mace_data {
-    volatile struct mace *mace;
-    volatile struct dbdma_regs *tx_dma;
+    volatile struct mace __iomem *mace;
+    volatile struct dbdma_regs __iomem *tx_dma;
     int tx_dma_intr;
-    volatile struct dbdma_regs *rx_dma;
+    volatile struct dbdma_regs __iomem *rx_dma;
     int rx_dma_intr;
     volatile struct dbdma_cmd *tx_cmds;	/* xmit dma command list */
     volatile struct dbdma_cmd *rx_cmds;	/* recv dma command list */
@@ -88,7 +88,7 @@
 static irqreturn_t mace_rxdma_intr(int irq, void *dev_id, struct pt_regs *regs);
 static void mace_set_timeout(struct net_device *dev);
 static void mace_tx_timeout(unsigned long data);
-static inline void dbdma_reset(volatile struct dbdma_regs *dma);
+static inline void dbdma_reset(volatile struct dbdma_regs __iomem *dma);
 static inline void mace_clean_rings(struct mace_data *mp);
 static void __mace_set_address(struct net_device *dev, void *addr);
 
@@ -164,7 +164,7 @@
 	macio_set_drvdata(mdev, dev);
 
 	dev->base_addr = macio_resource_start(mdev, 0);
-	mp->mace = (volatile struct mace *)ioremap(dev->base_addr, 0x1000);
+	mp->mace = ioremap(dev->base_addr, 0x1000);
 	if (mp->mace == NULL) {
 		printk(KERN_ERR "MACE: can't map IO resources !\n");
 		rc = -ENOMEM;
@@ -183,8 +183,7 @@
 	mp = (struct mace_data *) dev->priv;
 	mp->maccc = ENXMT | ENRCV;
 
-	mp->tx_dma = (volatile struct dbdma_regs *)
-		ioremap(macio_resource_start(mdev, 1), 0x1000);
+	mp->tx_dma = ioremap(macio_resource_start(mdev, 1), 0x1000);
 	if (mp->tx_dma == NULL) {
 		printk(KERN_ERR "MACE: can't map TX DMA resources !\n");
 		rc = -ENOMEM;
@@ -192,8 +191,7 @@
 	}
 	mp->tx_dma_intr = macio_irq(mdev, 1);
 
-	mp->rx_dma = (volatile struct dbdma_regs *)
-		ioremap(macio_resource_start(mdev, 2), 0x1000);
+	mp->rx_dma = ioremap(macio_resource_start(mdev, 2), 0x1000);
 	if (mp->rx_dma == NULL) {
 		printk(KERN_ERR "MACE: can't map RX DMA resources !\n");
 		rc = -ENOMEM;
@@ -275,11 +273,11 @@
  err_free_irq:
 	free_irq(macio_irq(mdev, 0), dev);
  err_unmap_rx_dma:
-	iounmap((void*)mp->rx_dma);
+	iounmap(mp->rx_dma);
  err_unmap_tx_dma:
-	iounmap((void*)mp->tx_dma);
+	iounmap(mp->tx_dma);
  err_unmap_io:
-	iounmap((void*)mp->mace);
+	iounmap(mp->mace);
  err_free:
 	free_netdev(dev);
  err_release:
@@ -305,9 +303,9 @@
 	free_irq(mp->tx_dma_intr, dev);
 	free_irq(mp->rx_dma_intr, dev);
 
-	iounmap((void*)mp->rx_dma);
-	iounmap((void*)mp->tx_dma);
-	iounmap((void*)mp->mace);
+	iounmap(mp->rx_dma);
+	iounmap(mp->tx_dma);
+	iounmap(mp->mace);
 
 	free_netdev(dev);
 
@@ -316,7 +314,7 @@
 	return 0;
 }
 
-static void dbdma_reset(volatile struct dbdma_regs *dma)
+static void dbdma_reset(volatile struct dbdma_regs __iomem *dma)
 {
     int i;
 
@@ -334,7 +332,7 @@
 static void mace_reset(struct net_device *dev)
 {
     struct mace_data *mp = (struct mace_data *) dev->priv;
-    volatile struct mace *mb = mp->mace;
+    volatile struct mace __iomem *mb = mp->mace;
     int i;
 
     /* soft-reset the chip */
@@ -389,7 +387,7 @@
 static void __mace_set_address(struct net_device *dev, void *addr)
 {
     struct mace_data *mp = (struct mace_data *) dev->priv;
-    volatile struct mace *mb = mp->mace;
+    volatile struct mace __iomem *mb = mp->mace;
     unsigned char *p = addr;
     int i;
 
@@ -410,7 +408,7 @@
 static int mace_set_address(struct net_device *dev, void *addr)
 {
     struct mace_data *mp = (struct mace_data *) dev->priv;
-    volatile struct mace *mb = mp->mace;
+    volatile struct mace __iomem *mb = mp->mace;
     unsigned long flags;
 
     spin_lock_irqsave(&mp->lock, flags);
@@ -445,9 +443,9 @@
 static int mace_open(struct net_device *dev)
 {
     struct mace_data *mp = (struct mace_data *) dev->priv;
-    volatile struct mace *mb = mp->mace;
-    volatile struct dbdma_regs *rd = mp->rx_dma;
-    volatile struct dbdma_regs *td = mp->tx_dma;
+    volatile struct mace __iomem *mb = mp->mace;
+    volatile struct dbdma_regs __iomem *rd = mp->rx_dma;
+    volatile struct dbdma_regs __iomem *td = mp->tx_dma;
     volatile struct dbdma_cmd *cp;
     int i;
     struct sk_buff *skb;
@@ -515,9 +513,9 @@
 static int mace_close(struct net_device *dev)
 {
     struct mace_data *mp = (struct mace_data *) dev->priv;
-    volatile struct mace *mb = mp->mace;
-    volatile struct dbdma_regs *rd = mp->rx_dma;
-    volatile struct dbdma_regs *td = mp->tx_dma;
+    volatile struct mace __iomem *mb = mp->mace;
+    volatile struct dbdma_regs __iomem *rd = mp->rx_dma;
+    volatile struct dbdma_regs __iomem *td = mp->tx_dma;
 
     /* disable rx and tx */
     out_8(&mb->maccc, 0);
@@ -548,7 +546,7 @@
 static int mace_xmit_start(struct sk_buff *skb, struct net_device *dev)
 {
     struct mace_data *mp = (struct mace_data *) dev->priv;
-    volatile struct dbdma_regs *td = mp->tx_dma;
+    volatile struct dbdma_regs __iomem *td = mp->tx_dma;
     volatile struct dbdma_cmd *cp, *np;
     unsigned long flags;
     int fill, next, len;
@@ -610,7 +608,7 @@
 static void mace_set_multicast(struct net_device *dev)
 {
     struct mace_data *mp = (struct mace_data *) dev->priv;
-    volatile struct mace *mb = mp->mace;
+    volatile struct mace __iomem *mb = mp->mace;
     int i, j;
     u32 crc;
     unsigned long flags;
@@ -662,7 +660,7 @@
 
 static void mace_handle_misc_intrs(struct mace_data *mp, int intr)
 {
-    volatile struct mace *mb = mp->mace;
+    volatile struct mace __iomem *mb = mp->mace;
     static int mace_babbles, mace_jabbers;
 
     if (intr & MPCO)
@@ -685,8 +683,8 @@
 {
     struct net_device *dev = (struct net_device *) dev_id;
     struct mace_data *mp = (struct mace_data *) dev->priv;
-    volatile struct mace *mb = mp->mace;
-    volatile struct dbdma_regs *td = mp->tx_dma;
+    volatile struct mace __iomem *mb = mp->mace;
+    volatile struct dbdma_regs __iomem *td = mp->tx_dma;
     volatile struct dbdma_cmd *cp;
     int intr, fs, i, stat, x;
     int xcount, dstat;
@@ -831,9 +829,9 @@
 {
     struct net_device *dev = (struct net_device *) data;
     struct mace_data *mp = (struct mace_data *) dev->priv;
-    volatile struct mace *mb = mp->mace;
-    volatile struct dbdma_regs *td = mp->tx_dma;
-    volatile struct dbdma_regs *rd = mp->rx_dma;
+    volatile struct mace __iomem *mb = mp->mace;
+    volatile struct dbdma_regs __iomem *td = mp->tx_dma;
+    volatile struct dbdma_regs __iomem *rd = mp->rx_dma;
     volatile struct dbdma_cmd *cp;
     unsigned long flags;
     int i;
@@ -902,7 +900,7 @@
 {
     struct net_device *dev = (struct net_device *) dev_id;
     struct mace_data *mp = (struct mace_data *) dev->priv;
-    volatile struct dbdma_regs *rd = mp->rx_dma;
+    volatile struct dbdma_regs __iomem *rd = mp->rx_dma;
     volatile struct dbdma_cmd *cp, *np;
     int i, nb, stat, next;
     struct sk_buff *skb;
diff -Nru a/drivers/net/myri_sbus.c b/drivers/net/myri_sbus.c
--- a/drivers/net/myri_sbus.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/net/myri_sbus.c	2005-03-01 23:38:52 -08:00
@@ -118,7 +118,7 @@
 
 static inline void bang_the_chip(struct myri_eth *mp)
 {
-	struct myri_shmem *shmem	= mp->shmem;
+	struct myri_shmem __iomem *shmem = mp->shmem;
 	void __iomem *cregs		= mp->cregs;
 
 	sbus_writel(1, &shmem->send);
@@ -127,9 +127,9 @@
 
 static int myri_do_handshake(struct myri_eth *mp)
 {
-	struct myri_shmem *shmem	= mp->shmem;
+	struct myri_shmem __iomem *shmem = mp->shmem;
 	void __iomem *cregs = mp->cregs;
-	struct myri_channel *chan	= &shmem->channel;
+	struct myri_channel __iomem *chan = &shmem->channel;
 	int tick 			= 0;
 
 	DET(("myri_do_handshake: "));
@@ -427,7 +427,7 @@
 		u32 csum		= sbus_readl(&rxdack->csum);
 		int len			= sbus_readl(&rxdack->myri_scatters[0].len);
 		int index		= sbus_readl(&rxdack->ctx);
-		struct myri_rxd __iomem *rxd	= &rq->myri_rxd[rq->tail];
+		struct myri_rxd __iomem *rxd = &rq->myri_rxd[sbus_readl(&rq->tail)];
 		struct sk_buff *skb	= mp->rx_skbs[index];
 
 		/* Ack it. */
@@ -546,7 +546,7 @@
 	struct net_device *dev		= (struct net_device *) dev_id;
 	struct myri_eth *mp		= (struct myri_eth *) dev->priv;
 	void __iomem *lregs		= mp->lregs;
-	struct myri_channel *chan	= &mp->shmem->channel;
+	struct myri_channel __iomem *chan = &mp->shmem->channel;
 	unsigned long flags;
 	u32 status;
 	int handled = 0;
diff -Nru a/drivers/net/natsemi.c b/drivers/net/natsemi.c
--- a/drivers/net/natsemi.c	2005-03-01 23:38:51 -08:00
+++ b/drivers/net/natsemi.c	2005-03-01 23:38:51 -08:00
@@ -251,12 +251,12 @@
 MODULE_DESCRIPTION("National Semiconductor DP8381x series PCI Ethernet driver");
 MODULE_LICENSE("GPL");
 
-MODULE_PARM(max_interrupt_work, "i");
-MODULE_PARM(mtu, "i");
-MODULE_PARM(debug, "i");
-MODULE_PARM(rx_copybreak, "i");
-MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i");
-MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
+module_param(max_interrupt_work, int, 0);
+module_param(mtu, int, 0);
+module_param(debug, int, 0);
+module_param(rx_copybreak, int, 0);
+module_param_array(options, int, NULL, 0);
+module_param_array(full_duplex, int, NULL, 0);
 MODULE_PARM_DESC(max_interrupt_work, 
 	"DP8381x maximum events handled per interrupt");
 MODULE_PARM_DESC(mtu, "DP8381x MTU (all boards)");
@@ -441,6 +441,7 @@
 #define DSPCFG_VAL	0x5040
 #define SDCFG_VAL	0x008c	/* set voltage thresholds for Signal Detect */
 #define DSPCFG_LOCK	0x20	/* coefficient lock bit in DSPCFG */
+#define DSPCFG_COEF	0x1000	/* see coefficient (in TSTDAT) bit in DSPCFG */
 #define TSTDAT_FIXED	0xe8	/* magic number for bad coefficients */
 
 /* misc PCI space registers */
@@ -1243,7 +1244,8 @@
 		writew(1, ioaddr + PGSEL);
 		writew(PMDCSR_VAL, ioaddr + PMDCSR);
 		writew(TSTDAT_VAL, ioaddr + TSTDAT);
-		np->dspcfg = DSPCFG_VAL;
+		np->dspcfg = (np->srr <= SRR_DP83815_C)?
+			DSPCFG_VAL : (DSPCFG_COEF | readw(ioaddr + DSPCFG));
 		writew(np->dspcfg, ioaddr + DSPCFG);
 		writew(SDCFG_VAL, ioaddr + SDCFG);
 		writew(0, ioaddr + PGSEL);
diff -Nru a/drivers/net/ne.c b/drivers/net/ne.c
--- a/drivers/net/ne.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/net/ne.c	2005-03-01 23:38:56 -08:00
@@ -800,9 +800,9 @@
 static int irq[MAX_NE_CARDS];
 static int bad[MAX_NE_CARDS];	/* 0xbad = bad sig or no reset ack */
 
-MODULE_PARM(io, "1-" __MODULE_STRING(MAX_NE_CARDS) "i");
-MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_NE_CARDS) "i");
-MODULE_PARM(bad, "1-" __MODULE_STRING(MAX_NE_CARDS) "i");
+module_param_array(io, int, NULL, 0);
+module_param_array(irq, int, NULL, 0);
+module_param_array(bad, int, NULL, 0);
 MODULE_PARM_DESC(io, "I/O base address(es),required");
 MODULE_PARM_DESC(irq, "IRQ number(s)");
 MODULE_PARM_DESC(bad, "Accept card(s) with bad signatures");
diff -Nru a/drivers/net/ne2.c b/drivers/net/ne2.c
--- a/drivers/net/ne2.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/net/ne2.c	2005-03-01 23:39:17 -08:00
@@ -776,9 +776,9 @@
 static int bad[MAX_NE_CARDS];	/* 0xbad = bad sig or no reset ack */
 MODULE_LICENSE("GPL");
 
-MODULE_PARM(io, "1-" __MODULE_STRING(MAX_NE_CARDS) "i");
-MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_NE_CARDS) "i");
-MODULE_PARM(bad, "1-" __MODULE_STRING(MAX_NE_CARDS) "i");
+module_param_array(io, int, NULL, 0);
+module_param_array(irq, int, NULL, 0);
+module_param_array(bad, int, NULL, 0);
 MODULE_PARM_DESC(io, "(ignored)");
 MODULE_PARM_DESC(irq, "(ignored)");
 MODULE_PARM_DESC(bad, "(ignored)");
diff -Nru a/drivers/net/ne2k-pci.c b/drivers/net/ne2k-pci.c
--- a/drivers/net/ne2k-pci.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/net/ne2k-pci.c	2005-03-01 23:38:53 -08:00
@@ -77,9 +77,9 @@
 MODULE_DESCRIPTION("PCI NE2000 clone driver");
 MODULE_LICENSE("GPL");
 
-MODULE_PARM(debug, "i");
-MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i");
-MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
+module_param(debug, int, 0);
+module_param_array(options, int, NULL, 0);
+module_param_array(full_duplex, int, NULL, 0);
 MODULE_PARM_DESC(debug, "debug level (1-2)");
 MODULE_PARM_DESC(options, "Bit 5: full duplex");
 MODULE_PARM_DESC(full_duplex, "full duplex setting(s) (1)");
diff -Nru a/drivers/net/ne3210.c b/drivers/net/ne3210.c
--- a/drivers/net/ne3210.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/net/ne3210.c	2005-03-01 23:38:56 -08:00
@@ -174,18 +174,17 @@
 	printk("%dkB memory at physical address %#lx\n",
 	       NE3210_STOP_PG/4, phys_mem);
 
-	dev->mem_start = (unsigned long)ioremap(phys_mem, NE3210_STOP_PG*0x100);
-	if (dev->mem_start == 0) {
+	ei_status.mem = ioremap(phys_mem, NE3210_STOP_PG*0x100);
+	if (!ei_status.mem) {
 		printk(KERN_ERR "ne3210.c: Unable to remap card memory !!\n");
 		printk(KERN_ERR "ne3210.c: Driver NOT installed.\n");
 		retval = -EAGAIN;
 		goto out4;
 	}
-	printk("ne3210.c: remapped %dkB card memory to virtual address %#lx\n",
-	       NE3210_STOP_PG/4, dev->mem_start);
-	dev->mem_end = ei_status.rmem_end = dev->mem_start
-		+ (NE3210_STOP_PG - NE3210_START_PG)*256;
-	ei_status.rmem_start = dev->mem_start + TX_PAGES*256;
+	printk("ne3210.c: remapped %dkB card memory to virtual address %p\n",
+	       NE3210_STOP_PG/4, ei_status.mem);
+	dev->mem_start = (unsigned long)ei_status.mem;
+	dev->mem_end = dev->mem_start + (NE3210_STOP_PG - NE3210_START_PG)*256;
 
 	/* The 8390 offset is zero for the NE3210 */
 	dev->base_addr = ioaddr;
@@ -219,7 +218,7 @@
 	return 0;
 
  out5:
-	iounmap((void *)dev->mem_start);
+	iounmap(ei_status.mem);
  out4:
 	release_mem_region (phys_mem, NE3210_STOP_PG*0x100);
  out3:
@@ -240,7 +239,7 @@
 	unsigned long       ioaddr = to_eisa_device (device)->base_addr;
 
 	unregister_netdev (dev);
-	iounmap((void *)dev->mem_start);
+	iounmap(ei_status.mem);
 	release_mem_region (ei_status.priv, NE3210_STOP_PG*0x100);
 	free_irq (dev->irq, dev);
 	release_region (ioaddr + NE3210_CFG1, NE3210_CFG_EXTENT);
@@ -288,7 +287,7 @@
 static void
 ne3210_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
 {
-	unsigned long hdr_start = dev->mem_start + ((ring_page - NE3210_START_PG)<<8);
+	void __iomem *hdr_start = ei_status.mem + ((ring_page - NE3210_START_PG)<<8);
 	memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
 	hdr->count = (hdr->count + 3) & ~3;     /* Round up allocation. */
 }
@@ -302,24 +301,25 @@
 static void ne3210_block_input(struct net_device *dev, int count, struct sk_buff *skb,
 						  int ring_offset)
 {
-	unsigned long xfer_start = dev->mem_start + ring_offset - (NE3210_START_PG<<8);
+	void __iomem *start = ei_status.mem + ring_offset - NE3210_START_PG*256;
 
-	if (xfer_start + count > ei_status.rmem_end) {
+	if (ring_offset + count > NE3210_STOP_PG*256) {
 		/* Packet wraps over end of ring buffer. */
-		int semi_count = ei_status.rmem_end - xfer_start;
-		memcpy_fromio(skb->data, xfer_start, semi_count);
+		int semi_count = NE3210_STOP_PG*256 - ring_offset;
+		memcpy_fromio(skb->data, start, semi_count);
 		count -= semi_count;
-		memcpy_fromio(skb->data + semi_count, ei_status.rmem_start, count);
+		memcpy_fromio(skb->data + semi_count,
+				ei_status.mem + TX_PAGES*256, count);
 	} else {
 		/* Packet is in one chunk. */
-		memcpy_fromio(skb->data, xfer_start, count);
+		memcpy_fromio(skb->data, start, count);
 	}
 }
 
 static void ne3210_block_output(struct net_device *dev, int count,
 				const unsigned char *buf, int start_page)
 {
-	unsigned long shmem = dev->mem_start + ((start_page - NE3210_START_PG)<<8);
+	void __iomem *shmem = ei_status.mem + ((start_page - NE3210_START_PG)<<8);
 
 	count = (count + 3) & ~3;     /* Round up to doubleword */
 	memcpy_toio(shmem, buf, count);
diff -Nru a/drivers/net/net_init.c b/drivers/net/net_init.c
--- a/drivers/net/net_init.c	2005-03-01 23:38:51 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,152 +0,0 @@
-/* net_init.c: Initialization for network devices. */
-/*
-	Written 1993,1994,1995 by Donald Becker.
-
-	The author may be reached as becker@scyld.com, or C/O
-	Scyld Computing Corporation
-	410 Severn Ave., Suite 210
-	Annapolis MD 21403
-
-	This file contains the initialization for the "pl14+" style ethernet
-	drivers.  It should eventually replace most of drivers/net/Space.c.
-	It's primary advantage is that it's able to allocate low-memory buffers.
-	A secondary advantage is that the dangerous NE*000 netcards can reserve
-	their I/O port region before the SCSI probes start.
-
-	Modifications/additions by Bjorn Ekwall <bj0rn@blox.se>:
-		ethdev_index[MAX_ETH_CARDS]
-		register_netdev() / unregister_netdev()
-		
-	Modifications by Wolfgang Walter
-		Use dev_close cleanly so we always shut things down tidily.
-		
-	Changed 29/10/95, Alan Cox to pass sockaddr's around for mac addresses.
-	
-	14/06/96 - Paul Gortmaker:	Add generic eth_change_mtu() function. 
-	24/09/96 - Paul Norton: Add token-ring variants of the netdev functions. 
-	
-	08/11/99 - Alan Cox: Got fed up of the mess in this file and cleaned it
-			up. We now share common code and have regularised name
-			allocation setups. Abolished the 16 card limits.
-	03/19/2000 - jgarzik and Urban Widmark: init_etherdev 32-byte align
-	03/21/2001 - jgarzik: alloc_etherdev and friends
-
-*/
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/fs.h>
-#include <linux/slab.h>
-#include <linux/if_ether.h>
-#include <linux/string.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/fddidevice.h>
-#include <linux/hippidevice.h>
-#include <linux/trdevice.h>
-#include <linux/fcdevice.h>
-#include <linux/if_arp.h>
-#include <linux/if_ltalk.h>
-#include <linux/rtnetlink.h>
-#include <net/neighbour.h>
-
-/* The network devices currently exist only in the socket namespace, so these
-   entries are unused.  The only ones that make sense are
-    open	start the ethercard
-    close	stop  the ethercard
-    ioctl	To get statistics, perhaps set the interface port (AUI, BNC, etc.)
-   One can also imagine getting raw packets using
-    read & write
-   but this is probably better handled by a raw packet socket.
-
-   Given that almost all of these functions are handled in the current
-   socket-based scheme, putting ethercard devices in /dev/ seems pointless.
-   
-   [Removed all support for /dev network devices. When someone adds
-    streams then by magic we get them, but otherwise they are un-needed
-	and a space waste]
-*/
-
-
-struct net_device *alloc_netdev(int sizeof_priv, const char *mask,
-				       void (*setup)(struct net_device *))
-{
-	void *p;
-	struct net_device *dev;
-	int alloc_size;
-
-	/* ensure 32-byte alignment of both the device and private area */
-
-	alloc_size = (sizeof(struct net_device) + NETDEV_ALIGN_CONST)
-			& ~NETDEV_ALIGN_CONST;
-	alloc_size += sizeof_priv + NETDEV_ALIGN_CONST;
-
-	p = kmalloc (alloc_size, GFP_KERNEL);
-	if (!p) {
-		printk(KERN_ERR "alloc_dev: Unable to allocate device.\n");
-		return NULL;
-	}
-
-	memset(p, 0, alloc_size);
-
-	dev = (struct net_device *)(((long)p + NETDEV_ALIGN_CONST)
-				& ~NETDEV_ALIGN_CONST);
-	dev->padded = (char *)dev - (char *)p;
-
-	if (sizeof_priv)
-		dev->priv = netdev_priv(dev);
-
-	setup(dev);
-	strcpy(dev->name, mask);
-
-	return dev;
-}
-EXPORT_SYMBOL(alloc_netdev);
-
-int register_netdev(struct net_device *dev)
-{
-	int err;
-
-	rtnl_lock();
-
-	/*
-	 *	If the name is a format string the caller wants us to
-	 *	do a name allocation
-	 */
-	 
-	if (strchr(dev->name, '%'))
-	{
-		err = dev_alloc_name(dev, dev->name);
-		if (err < 0)
-			goto out;
-	}
-	
-	/*
-	 *	Back compatibility hook. Kill this one in 2.5
-	 */
-	
-	if (dev->name[0]==0 || dev->name[0]==' ')
-	{
-		err = dev_alloc_name(dev, "eth%d");
-		if (err < 0)
-			goto out;
-	}
-
-	err = register_netdevice(dev);
-
-out:
-	rtnl_unlock();
-	return err;
-}
-
-void unregister_netdev(struct net_device *dev)
-{
-	rtnl_lock();
-	unregister_netdevice(dev);
-	rtnl_unlock();
-}
-
-EXPORT_SYMBOL(register_netdev);
-EXPORT_SYMBOL(unregister_netdev);
diff -Nru a/drivers/net/ni52.c b/drivers/net/ni52.c
--- a/drivers/net/ni52.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/net/ni52.c	2005-03-01 23:38:58 -08:00
@@ -1314,10 +1314,10 @@
 #ifdef MODULE
 static struct net_device *dev_ni52;
 
-MODULE_PARM(io, "i");
-MODULE_PARM(irq, "i");
-MODULE_PARM(memstart, "l");
-MODULE_PARM(memend, "l");
+module_param(io, int, 0);
+module_param(irq, int, 0);
+module_param(memstart, long, 0);
+module_param(memend, long, 0);
 MODULE_PARM_DESC(io, "NI5210 I/O base address,required");
 MODULE_PARM_DESC(irq, "NI5210 IRQ number,required");
 MODULE_PARM_DESC(memstart, "NI5210 memory base address,required");
diff -Nru a/drivers/net/ni65.c b/drivers/net/ni65.c
--- a/drivers/net/ni65.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/net/ni65.c	2005-03-01 23:38:54 -08:00
@@ -1250,9 +1250,9 @@
 #ifdef MODULE
 static struct net_device *dev_ni65;
 
-MODULE_PARM(irq, "i");
-MODULE_PARM(io, "i");
-MODULE_PARM(dma, "i");
+module_param(irq, int, 0);
+module_param(io, int, 0);
+module_param(dma, int, 0);
 MODULE_PARM_DESC(irq, "ni6510 IRQ number (ignored for some cards)");
 MODULE_PARM_DESC(io, "ni6510 I/O base address");
 MODULE_PARM_DESC(dma, "ni6510 ISA DMA channel (ignored for some cards)");
diff -Nru a/drivers/net/pci-skeleton.c b/drivers/net/pci-skeleton.c
--- a/drivers/net/pci-skeleton.c	2005-03-01 23:38:51 -08:00
+++ b/drivers/net/pci-skeleton.c	2005-03-01 23:38:51 -08:00
@@ -1921,7 +1921,7 @@
 	spin_unlock_irqrestore (&tp->lock, flags);
 
 	pci_save_state (pdev);
-	pci_set_power_state (pdev, 3);
+	pci_set_power_state (pdev, PCI_D3hot);
 
 	return 0;
 }
@@ -1934,7 +1934,7 @@
 
 	if (!netif_running(dev))
 		return 0;
-	pci_set_power_state (pdev, 0);
+	pci_set_power_state (pdev, PCI_D0);
 	pci_restore_state (pdev);
 	netif_device_attach (dev);
 	netdrv_hw_start (dev);
diff -Nru a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c
--- a/drivers/net/pcmcia/3c574_cs.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/net/pcmcia/3c574_cs.c	2005-03-01 23:38:53 -08:00
@@ -107,12 +107,7 @@
 MODULE_DESCRIPTION("3Com 3c574 series PCMCIA ethernet driver");
 MODULE_LICENSE("GPL");
 
-#define INT_MODULE_PARM(n, v) static int n = v; MODULE_PARM(n, "i")
-
-/* Now-standard PC card module parameters. */
-INT_MODULE_PARM(irq_mask, 0xdeb8);
-static int irq_list[4] = { -1 };
-MODULE_PARM(irq_list, "1-4i");
+#define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0)
 
 /* Maximum events (Rx packets, etc.) to handle at each interrupt. */
 INT_MODULE_PARM(max_interrupt_work, 32);
@@ -236,10 +231,10 @@
 static int tc574_event(event_t event, int priority,
 					   event_callback_args_t *args);
 
-static void mdio_sync(ioaddr_t ioaddr, int bits);
-static int mdio_read(ioaddr_t ioaddr, int phy_id, int location);
-static void mdio_write(ioaddr_t ioaddr, int phy_id, int location, int value);
-static unsigned short read_eeprom(ioaddr_t ioaddr, int index);
+static void mdio_sync(kio_addr_t ioaddr, int bits);
+static int mdio_read(kio_addr_t ioaddr, int phy_id, int location);
+static void mdio_write(kio_addr_t ioaddr, int phy_id, int location, int value);
+static unsigned short read_eeprom(kio_addr_t ioaddr, int index);
 static void tc574_wait_for_completion(struct net_device *dev, int cmd);
 
 static void tc574_reset(struct net_device *dev);
@@ -275,7 +270,7 @@
 	client_reg_t client_reg;
 	dev_link_t *link;
 	struct net_device *dev;
-	int i, ret;
+	int ret;
 
 	DEBUG(0, "3c574_attach()\n");
 
@@ -291,12 +286,7 @@
 	link->io.NumPorts1 = 32;
 	link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
 	link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
-	link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
-	if (irq_list[0] == -1)
-		link->irq.IRQInfo2 = irq_mask;
-	else
-		for (i = 0; i < 4; i++)
-			link->irq.IRQInfo2 |= 1 << irq_list[i];
+	link->irq.IRQInfo1 = IRQ_LEVEL_ID;
 	link->irq.Handler = &el3_interrupt;
 	link->irq.Instance = dev;
 	link->conf.Attributes = CONF_ENABLE_IRQ;
@@ -322,7 +312,6 @@
 	link->next = dev_list;
 	dev_list = link;
 	client_reg.dev_info = &dev_info;
-	client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
 	client_reg.EventMask =
 		CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
 			CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
@@ -396,7 +385,7 @@
 	cisparse_t parse;
 	unsigned short buf[32];
 	int last_fn, last_ret, i, j;
-	ioaddr_t ioaddr;
+	kio_addr_t ioaddr;
 	u16 *phys_addr;
 	char *cardname;
 	union wn3_config config;
@@ -519,6 +508,7 @@
 
 	link->state &= ~DEV_CONFIG_PENDING;
 	link->dev = &lp->node;
+	SET_NETDEV_DEV(dev, &handle_to_dev(handle));
 
 	if (register_netdev(dev) != 0) {
 		printk(KERN_NOTICE "3c574_cs: register_netdev() failed\n");
@@ -616,7 +606,7 @@
 
 static void dump_status(struct net_device *dev)
 {
-	ioaddr_t ioaddr = dev->base_addr;
+	kio_addr_t ioaddr = dev->base_addr;
 	EL3WINDOW(1);
 	printk(KERN_INFO "  irq status %04x, rx status %04x, tx status "
 		   "%02x, tx free %04x\n", inw(ioaddr+EL3_STATUS),
@@ -645,7 +635,7 @@
 /* Read a word from the EEPROM using the regular EEPROM access register.
    Assume that we are in register window zero.
  */
-static unsigned short read_eeprom(ioaddr_t ioaddr, int index)
+static unsigned short read_eeprom(kio_addr_t ioaddr, int index)
 {
 	int timer;
 	outw(EEPROM_Read + index, ioaddr + Wn0EepromCmd);
@@ -673,9 +663,9 @@
 
 /* Generate the preamble required for initial synchronization and
    a few older transceivers. */
-static void mdio_sync(ioaddr_t ioaddr, int bits)
+static void mdio_sync(kio_addr_t ioaddr, int bits)
 {
-	int mdio_addr = ioaddr + Wn4_PhysicalMgmt;
+	kio_addr_t mdio_addr = ioaddr + Wn4_PhysicalMgmt;
 
 	/* Establish sync by sending at least 32 logic ones. */
 	while (-- bits >= 0) {
@@ -684,12 +674,12 @@
 	}
 }
 
-static int mdio_read(ioaddr_t ioaddr, int phy_id, int location)
+static int mdio_read(kio_addr_t ioaddr, int phy_id, int location)
 {
 	int i;
 	int read_cmd = (0xf6 << 10) | (phy_id << 5) | location;
 	unsigned int retval = 0;
-	int mdio_addr = ioaddr + Wn4_PhysicalMgmt;
+	kio_addr_t mdio_addr = ioaddr + Wn4_PhysicalMgmt;
 
 	if (mii_preamble_required)
 		mdio_sync(ioaddr, 32);
@@ -709,10 +699,10 @@
 	return (retval>>1) & 0xffff;
 }
 
-static void mdio_write(ioaddr_t ioaddr, int phy_id, int location, int value)
+static void mdio_write(kio_addr_t ioaddr, int phy_id, int location, int value)
 {
 	int write_cmd = 0x50020000 | (phy_id << 23) | (location << 18) | value;
-	int mdio_addr = ioaddr + Wn4_PhysicalMgmt;
+	kio_addr_t mdio_addr = ioaddr + Wn4_PhysicalMgmt;
 	int i;
 
 	if (mii_preamble_required)
@@ -737,7 +727,8 @@
 static void tc574_reset(struct net_device *dev)
 {
 	struct el3_private *lp = netdev_priv(dev);
-	int i, ioaddr = dev->base_addr;
+	int i;
+	kio_addr_t ioaddr = dev->base_addr;
 	unsigned long flags;
 
 	tc574_wait_for_completion(dev, TotalReset|0x10);
@@ -841,7 +832,7 @@
 static void el3_tx_timeout(struct net_device *dev)
 {
 	struct el3_private *lp = netdev_priv(dev);
-	ioaddr_t ioaddr = dev->base_addr;
+	kio_addr_t ioaddr = dev->base_addr;
 	
 	printk(KERN_NOTICE "%s: Transmit timed out!\n", dev->name);
 	dump_status(dev);
@@ -856,7 +847,7 @@
 static void pop_tx_status(struct net_device *dev)
 {
 	struct el3_private *lp = netdev_priv(dev);
-	ioaddr_t ioaddr = dev->base_addr;
+	kio_addr_t ioaddr = dev->base_addr;
 	int i;
     
 	/* Clear the Tx status stack. */
@@ -879,7 +870,7 @@
 
 static int el3_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-	ioaddr_t ioaddr = dev->base_addr;
+	kio_addr_t ioaddr = dev->base_addr;
 	struct el3_private *lp = netdev_priv(dev);
 	unsigned long flags;
 
@@ -913,7 +904,8 @@
 {
 	struct net_device *dev = (struct net_device *) dev_id;
 	struct el3_private *lp = netdev_priv(dev);
-	ioaddr_t ioaddr, status;
+	kio_addr_t ioaddr;
+	unsigned status;
 	int work_budget = max_interrupt_work;
 	int handled = 0;
 
@@ -1006,7 +998,7 @@
 {
 	struct net_device *dev = (struct net_device *) arg;
 	struct el3_private *lp = netdev_priv(dev);
-	ioaddr_t ioaddr = dev->base_addr;
+	kio_addr_t ioaddr = dev->base_addr;
 	unsigned long flags;
 	unsigned short /* cable, */ media, partner;
 
@@ -1095,7 +1087,7 @@
 static void update_stats(struct net_device *dev)
 {
 	struct el3_private *lp = netdev_priv(dev);
-	ioaddr_t ioaddr = dev->base_addr;
+	kio_addr_t ioaddr = dev->base_addr;
 	u8 rx, tx, up;
 
 	DEBUG(2, "%s: updating the statistics.\n", dev->name);
@@ -1132,7 +1124,7 @@
 static int el3_rx(struct net_device *dev, int worklimit)
 {
 	struct el3_private *lp = netdev_priv(dev);
-	ioaddr_t ioaddr = dev->base_addr;
+	kio_addr_t ioaddr = dev->base_addr;
 	short rx_status;
 	
 	DEBUG(3, "%s: in rx_packet(), status %4.4x, rx_status %4.4x.\n",
@@ -1194,7 +1186,7 @@
 static int el3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
 	struct el3_private *lp = netdev_priv(dev);
-	ioaddr_t ioaddr = dev->base_addr;
+	kio_addr_t ioaddr = dev->base_addr;
 	u16 *data = (u16 *)&rq->ifr_ifru;
 	int phy = lp->phys & 0x1f;
 
@@ -1248,7 +1240,7 @@
 
 static void set_rx_mode(struct net_device *dev)
 {
-	ioaddr_t ioaddr = dev->base_addr;
+	kio_addr_t ioaddr = dev->base_addr;
 
 	if (dev->flags & IFF_PROMISC)
 		outw(SetRxFilter | RxStation | RxMulticast | RxBroadcast | RxProm,
@@ -1261,7 +1253,7 @@
 
 static int el3_close(struct net_device *dev)
 {
-	ioaddr_t ioaddr = dev->base_addr;
+	kio_addr_t ioaddr = dev->base_addr;
 	struct el3_private *lp = netdev_priv(dev);
 	dev_link_t *link = &lp->link;
 
@@ -1308,8 +1300,7 @@
 static void __exit exit_tc574(void)
 {
 	pcmcia_unregister_driver(&tc574_driver);
-	while (dev_list != NULL)
-		tc574_detach(dev_list);
+	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_tc574);
diff -Nru a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c
--- a/drivers/net/pcmcia/3c589_cs.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/net/pcmcia/3c589_cs.c	2005-03-01 23:39:16 -08:00
@@ -126,16 +126,11 @@
 MODULE_DESCRIPTION("3Com 3c589 series PCMCIA ethernet driver");
 MODULE_LICENSE("GPL");
 
-#define INT_MODULE_PARM(n, v) static int n = v; MODULE_PARM(n, "i")
+#define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0)
 
 /* Special hook for setting if_port when module is loaded */
 INT_MODULE_PARM(if_port, 0);
 
-/* Bit map of interrupts to choose from */
-INT_MODULE_PARM(irq_mask, 0xdeb8);
-static int irq_list[4] = { -1 };
-MODULE_PARM(irq_list, "1-4i");
-
 #ifdef PCMCIA_DEBUG
 INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
 #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
@@ -152,7 +147,7 @@
 static int tc589_event(event_t event, int priority,
 		       event_callback_args_t *args);
 
-static u16 read_eeprom(ioaddr_t ioaddr, int index);
+static u16 read_eeprom(kio_addr_t ioaddr, int index);
 static void tc589_reset(struct net_device *dev);
 static void media_check(unsigned long arg);
 static int el3_config(struct net_device *dev, struct ifmap *map);
@@ -188,7 +183,7 @@
     client_reg_t client_reg;
     dev_link_t *link;
     struct net_device *dev;
-    int i, ret;
+    int ret;
 
     DEBUG(0, "3c589_attach()\n");
     
@@ -204,12 +199,7 @@
     link->io.NumPorts1 = 16;
     link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
     link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
-    link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
-    if (irq_list[0] == -1)
-	link->irq.IRQInfo2 = irq_mask;
-    else
-	for (i = 0; i < 4; i++)
-	    link->irq.IRQInfo2 |= 1 << irq_list[i];
+    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
     link->irq.Handler = &el3_interrupt;
     link->irq.Instance = dev;
     link->conf.Attributes = CONF_ENABLE_IRQ;
@@ -236,7 +226,6 @@
     link->next = dev_list;
     dev_list = link;
     client_reg.dev_info = &dev_info;
-    client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
     client_reg.EventMask =
 	CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
 	CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
@@ -310,7 +299,7 @@
     cisparse_t parse;
     u16 buf[32], *phys_addr;
     int last_fn, last_ret, i, j, multi = 0, fifo;
-    ioaddr_t ioaddr;
+    kio_addr_t ioaddr;
     char *ram_split[] = {"5:3", "3:1", "1:1", "3:5"};
     
     DEBUG(0, "3c589_config(0x%p)\n", link);
@@ -391,6 +380,7 @@
     
     link->dev = &lp->node;
     link->state &= ~DEV_CONFIG_PENDING;
+    SET_NETDEV_DEV(dev, &handle_to_dev(handle));
 
     if (register_netdev(dev) != 0) {
 	printk(KERN_ERR "3c589_cs: register_netdev() failed\n");
@@ -510,7 +500,7 @@
   Read a word from the EEPROM using the regular EEPROM access register.
   Assume that we are in register window zero.
 */
-static u16 read_eeprom(ioaddr_t ioaddr, int index)
+static u16 read_eeprom(kio_addr_t ioaddr, int index)
 {
     int i;
     outw(EEPROM_READ + index, ioaddr + 10);
@@ -528,7 +518,7 @@
 static void tc589_set_xcvr(struct net_device *dev, int if_port)
 {
     struct el3_private *lp = netdev_priv(dev);
-    ioaddr_t ioaddr = dev->base_addr;
+    kio_addr_t ioaddr = dev->base_addr;
     
     EL3WINDOW(0);
     switch (if_port) {
@@ -550,7 +540,7 @@
 
 static void dump_status(struct net_device *dev)
 {
-    ioaddr_t ioaddr = dev->base_addr;
+    kio_addr_t ioaddr = dev->base_addr;
     EL3WINDOW(1);
     printk(KERN_INFO "  irq status %04x, rx status %04x, tx status "
 	   "%02x  tx free %04x\n", inw(ioaddr+EL3_STATUS),
@@ -566,7 +556,7 @@
 /* Reset and restore all of the 3c589 registers. */
 static void tc589_reset(struct net_device *dev)
 {
-    ioaddr_t ioaddr = dev->base_addr;
+    kio_addr_t ioaddr = dev->base_addr;
     int i;
     
     EL3WINDOW(0);
@@ -674,7 +664,7 @@
 static void el3_tx_timeout(struct net_device *dev)
 {
     struct el3_private *lp = netdev_priv(dev);
-    ioaddr_t ioaddr = dev->base_addr;
+    kio_addr_t ioaddr = dev->base_addr;
     
     printk(KERN_WARNING "%s: Transmit timed out!\n", dev->name);
     dump_status(dev);
@@ -689,7 +679,7 @@
 static void pop_tx_status(struct net_device *dev)
 {
     struct el3_private *lp = netdev_priv(dev);
-    ioaddr_t ioaddr = dev->base_addr;
+    kio_addr_t ioaddr = dev->base_addr;
     int i;
     
     /* Clear the Tx status stack. */
@@ -711,7 +701,7 @@
 
 static int el3_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-    ioaddr_t ioaddr = dev->base_addr;
+    kio_addr_t ioaddr = dev->base_addr;
     struct el3_private *priv = netdev_priv(dev);
 
     DEBUG(3, "%s: el3_start_xmit(length = %ld) called, "
@@ -744,7 +734,8 @@
 {
     struct net_device *dev = (struct net_device *) dev_id;
     struct el3_private *lp = netdev_priv(dev);
-    ioaddr_t ioaddr, status;
+    kio_addr_t ioaddr;
+    __u16 status;
     int i = 0, handled = 1;
     
     if (!netif_device_present(dev))
@@ -829,7 +820,7 @@
 {
     struct net_device *dev = (struct net_device *)(arg);
     struct el3_private *lp = netdev_priv(dev);
-    ioaddr_t ioaddr = dev->base_addr;
+    kio_addr_t ioaddr = dev->base_addr;
     u16 media, errs;
     unsigned long flags;
 
@@ -931,7 +922,7 @@
 static void update_stats(struct net_device *dev)
 {
     struct el3_private *lp = netdev_priv(dev);
-    ioaddr_t ioaddr = dev->base_addr;
+    kio_addr_t ioaddr = dev->base_addr;
 
     DEBUG(2, "%s: updating the statistics.\n", dev->name);
     /* Turn off statistics updates while reading. */
@@ -958,7 +949,7 @@
 static int el3_rx(struct net_device *dev)
 {
     struct el3_private *lp = netdev_priv(dev);
-    ioaddr_t ioaddr = dev->base_addr;
+    kio_addr_t ioaddr = dev->base_addr;
     int worklimit = 32;
     short rx_status;
     
@@ -1013,7 +1004,7 @@
 {
     struct el3_private *lp = netdev_priv(dev);
     dev_link_t *link = &lp->link;
-    ioaddr_t ioaddr = dev->base_addr;
+    kio_addr_t ioaddr = dev->base_addr;
     u16 opts = SetRxFilter | RxStation | RxBroadcast;
 
     if (!(DEV_OK(link))) return;
@@ -1028,7 +1019,7 @@
 {
     struct el3_private *lp = netdev_priv(dev);
     dev_link_t *link = &lp->link;
-    ioaddr_t ioaddr = dev->base_addr;
+    kio_addr_t ioaddr = dev->base_addr;
     
     DEBUG(1, "%s: shutting down ethercard.\n", dev->name);
 
@@ -1083,8 +1074,7 @@
 static void __exit exit_tc589(void)
 {
 	pcmcia_unregister_driver(&tc589_driver);
-	while (dev_list != NULL)
-		tc589_detach(dev_list);
+	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_tc589);
diff -Nru a/drivers/net/pcmcia/Kconfig b/drivers/net/pcmcia/Kconfig
--- a/drivers/net/pcmcia/Kconfig	2005-03-01 23:39:18 -08:00
+++ b/drivers/net/pcmcia/Kconfig	2005-03-01 23:39:18 -08:00
@@ -3,7 +3,7 @@
 #
 
 menu "PCMCIA network device support"
-	depends on NETDEVICES && HOTPLUG && PCMCIA!=n
+	depends on NETDEVICES && PCMCIA!=n
 
 config NET_PCMCIA
 	bool "PCMCIA network device support"
diff -Nru a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c
--- a/drivers/net/pcmcia/axnet_cs.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/net/pcmcia/axnet_cs.c	2005-03-01 23:38:58 -08:00
@@ -73,14 +73,9 @@
 MODULE_DESCRIPTION("Asix AX88190 PCMCIA ethernet driver");
 MODULE_LICENSE("GPL");
 
-#define INT_MODULE_PARM(n, v) static int n = v; MODULE_PARM(n, "i")
-
-/* Bit map of interrupts to choose from */
-INT_MODULE_PARM(irq_mask,	0xdeb8);
-static int irq_list[4] = { -1 };
-MODULE_PARM(irq_list, "1-4i");
-
 #ifdef PCMCIA_DEBUG
+#define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0)
+
 INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
 #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
 static char *version =
@@ -103,8 +98,8 @@
 static void ei_watchdog(u_long arg);
 static void axnet_reset_8390(struct net_device *dev);
 
-static int mdio_read(ioaddr_t addr, int phy_id, int loc);
-static void mdio_write(ioaddr_t addr, int phy_id, int loc, int value);
+static int mdio_read(kio_addr_t addr, int phy_id, int loc);
+static void mdio_write(kio_addr_t addr, int phy_id, int loc, int value);
 
 static void get_8390_hdr(struct net_device *,
 			 struct e8390_pkt_hdr *, int);
@@ -159,7 +154,7 @@
     dev_link_t *link;
     struct net_device *dev;
     client_reg_t client_reg;
-    int i, ret;
+    int ret;
 
     DEBUG(0, "axnet_attach()\n");
 
@@ -173,12 +168,7 @@
     link = &info->link;
     link->priv = dev;
     link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
-    link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
-    if (irq_list[0] == -1)
-	link->irq.IRQInfo2 = irq_mask;
-    else
-	for (i = 0; i < 4; i++)
-	    link->irq.IRQInfo2 |= 1 << irq_list[i];
+    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.IntType = INT_MEMORY_AND_IO;
 
@@ -191,7 +181,6 @@
     link->next = dev_list;
     dev_list = link;
     client_reg.dev_info = &dev_info;
-    client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
     client_reg.EventMask =
 	CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
 	CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
@@ -254,7 +243,7 @@
 static int get_prom(dev_link_t *link)
 {
     struct net_device *dev = link->priv;
-    ioaddr_t ioaddr = dev->base_addr;
+    kio_addr_t ioaddr = dev->base_addr;
     int i, j;
 
     /* This is based on drivers/net/ne.c */
@@ -458,6 +447,7 @@
     info->phy_id = (i < 32) ? i : -1;
     link->dev = &info->node;
     link->state &= ~DEV_CONFIG_PENDING;
+    SET_NETDEV_DEV(dev, &handle_to_dev(handle));
 
     if (register_netdev(dev) != 0) {
 	printk(KERN_NOTICE "axnet_cs: register_netdev() failed\n");
@@ -573,7 +563,7 @@
 #define MDIO_MASK		0x0f
 #define MDIO_ENB_IN		0x02
 
-static void mdio_sync(ioaddr_t addr)
+static void mdio_sync(kio_addr_t addr)
 {
     int bits;
     for (bits = 0; bits < 32; bits++) {
@@ -582,7 +572,7 @@
     }
 }
 
-static int mdio_read(ioaddr_t addr, int phy_id, int loc)
+static int mdio_read(kio_addr_t addr, int phy_id, int loc)
 {
     u_int cmd = (0xf6<<10)|(phy_id<<5)|loc;
     int i, retval = 0;
@@ -601,7 +591,7 @@
     return (retval>>1) & 0xffff;
 }
 
-static void mdio_write(ioaddr_t addr, int phy_id, int loc, int value)
+static void mdio_write(kio_addr_t addr, int phy_id, int loc, int value)
 {
     u_int cmd = (0x05<<28)|(phy_id<<23)|(loc<<18)|(1<<17)|value;
     int i;
@@ -672,7 +662,7 @@
 
 static void axnet_reset_8390(struct net_device *dev)
 {
-    ioaddr_t nic_base = dev->base_addr;
+    kio_addr_t nic_base = dev->base_addr;
     int i;
 
     ei_status.txing = ei_status.dmaing = 0;
@@ -707,8 +697,8 @@
 {
     struct net_device *dev = (struct net_device *)(arg);
     axnet_dev_t *info = PRIV(dev);
-    ioaddr_t nic_base = dev->base_addr;
-    ioaddr_t mii_addr = nic_base + AXNET_MII_EEP;
+    kio_addr_t nic_base = dev->base_addr;
+    kio_addr_t mii_addr = nic_base + AXNET_MII_EEP;
     u_short link;
 
     if (!netif_device_present(dev)) goto reschedule;
@@ -778,7 +768,7 @@
 {
     axnet_dev_t *info = PRIV(dev);
     u16 *data = (u16 *)&rq->ifr_ifru;
-    ioaddr_t mii_addr = dev->base_addr + AXNET_MII_EEP;
+    kio_addr_t mii_addr = dev->base_addr + AXNET_MII_EEP;
     switch (cmd) {
     case SIOCGMIIPHY:
 	data[0] = info->phy_id;
@@ -800,7 +790,7 @@
 			 struct e8390_pkt_hdr *hdr,
 			 int ring_page)
 {
-    ioaddr_t nic_base = dev->base_addr;
+    kio_addr_t nic_base = dev->base_addr;
 
     outb_p(0, nic_base + EN0_RSARLO);		/* On page boundary */
     outb_p(ring_page, nic_base + EN0_RSARHI);
@@ -818,7 +808,7 @@
 static void block_input(struct net_device *dev, int count,
 			struct sk_buff *skb, int ring_offset)
 {
-    ioaddr_t nic_base = dev->base_addr;
+    kio_addr_t nic_base = dev->base_addr;
     int xfer_count = count;
     char *buf = skb->data;
 
@@ -841,7 +831,7 @@
 static void block_output(struct net_device *dev, int count,
 			 const u_char *buf, const int start_page)
 {
-    ioaddr_t nic_base = dev->base_addr;
+    kio_addr_t nic_base = dev->base_addr;
 
 #ifdef PCMCIA_DEBUG
     if (ei_debug > 4)
@@ -877,8 +867,7 @@
 static void __exit exit_axnet_cs(void)
 {
 	pcmcia_unregister_driver(&axnet_cs_driver);
-	while (dev_list != NULL)
-		axnet_detach(dev_list);
+	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_axnet_cs);
diff -Nru a/drivers/net/pcmcia/com20020_cs.c b/drivers/net/pcmcia/com20020_cs.c
--- a/drivers/net/pcmcia/com20020_cs.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/net/pcmcia/com20020_cs.c	2005-03-01 23:38:57 -08:00
@@ -57,7 +57,7 @@
 #ifdef PCMCIA_DEBUG
 
 static int pc_debug = PCMCIA_DEBUG;
-MODULE_PARM(pc_debug, "i");
+module_param(pc_debug, int, 0);
 #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
 
 static void regdump(struct net_device *dev)
@@ -109,18 +109,12 @@
 static int clockp;
 static int clockm;
 
-MODULE_PARM(node, "i");
-MODULE_PARM(timeout, "i");
-MODULE_PARM(backplane, "i");
-MODULE_PARM(clockp, "i");
-MODULE_PARM(clockm, "i");
-
-/* Bit map of interrupts to choose from */
-static u_int irq_mask = 0xdeb8;
-static int irq_list[4] = { -1 };
+module_param(node, int, 0);
+module_param(timeout, int, 0);
+module_param(backplane, int, 0);
+module_param(clockp, int, 0);
+module_param(clockm, int, 0);
 
-MODULE_PARM(irq_mask, "i");
-MODULE_PARM(irq_list, "1-4i");
 MODULE_LICENSE("GPL");
 
 /*====================================================================*/
@@ -158,7 +152,7 @@
     dev_link_t *link;
     com20020_dev_t *info;
     struct net_device *dev;
-    int i, ret;
+    int ret;
     struct arcnet_local *lp;
     
     DEBUG(0, "com20020_attach()\n");
@@ -192,12 +186,7 @@
     link->io.NumPorts1 = 16;
     link->io.IOAddrLines = 16;
     link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
-    link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
-    if (irq_list[0] == -1)
-	link->irq.IRQInfo2 = irq_mask;
-    else
-	for (i = 0; i < 4; i++)
-	    link->irq.IRQInfo2 |= 1 << irq_list[i];
+    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.Vcc = 50;
     link->conf.IntType = INT_MEMORY_AND_IO;
@@ -211,7 +200,6 @@
     link->next = dev_list;
     dev_list = link;
     client_reg.dev_info = &dev_info;
-    client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
     client_reg.EventMask =
         CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
         CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
@@ -394,6 +382,7 @@
 
     link->dev = &info->node;
     link->state &= ~DEV_CONFIG_PENDING;
+    SET_NETDEV_DEV(dev, &handle_to_dev(handle));
 
     i = com20020_found(dev, 0);	/* calls register_netdev */
     
@@ -513,8 +502,7 @@
 static void __exit exit_com20020_cs(void)
 {
 	pcmcia_unregister_driver(&com20020_cs_driver);
-	while (dev_list != NULL)
-		com20020_detach(dev_list);
+	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_com20020_cs);
diff -Nru a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c
--- a/drivers/net/pcmcia/fmvj18x_cs.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/net/pcmcia/fmvj18x_cs.c	2005-03-01 23:39:07 -08:00
@@ -67,13 +67,7 @@
 MODULE_DESCRIPTION("fmvj18x and compatible PCMCIA ethernet driver");
 MODULE_LICENSE("GPL");
 
-#define INT_MODULE_PARM(n, v) static int n = v; MODULE_PARM(n, "i")
-
-/* Bit map of interrupts to choose from */
-/* This means pick from 15, 14, 12, 11, 10, 9, 7, 5, 4, and 3 */
-INT_MODULE_PARM(irq_mask, 0xdeb8);
-static int irq_list[4] = { -1 };
-MODULE_PARM(irq_list, "1-4i");
+#define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0)
 
 /* SRAM configuration */
 /* 0:4KB*2 TX buffer   else:8KB*2 TX buffer */
@@ -248,7 +242,7 @@
     dev_link_t *link;
     struct net_device *dev;
     client_reg_t client_reg;
-    int i, ret;
+    int ret;
     
     DEBUG(0, "fmvj18x_attach()\n");
 
@@ -267,12 +261,7 @@
 
     /* Interrupt setup */
     link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
-    link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
-    if (irq_list[0] == -1)
-	link->irq.IRQInfo2 = irq_mask;
-    else
-	for (i = 0; i < 4; i++)
-	    link->irq.IRQInfo2 |= 1 << irq_list[i];
+    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
     link->irq.Handler = &fjn_interrupt;
     link->irq.Instance = dev;
     
@@ -299,7 +288,6 @@
     link->next = dev_list;
     dev_list = link;
     client_reg.dev_info = &dev_info;
-    client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
     client_reg.EventMask =
 	CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
 	CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
@@ -355,7 +343,7 @@
 static int mfc_try_io_port(dev_link_t *link)
 {
     int i, ret;
-    static ioaddr_t serial_base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
+    static kio_addr_t serial_base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
 
     for (i = 0; i < 5; i++) {
 	link->io.BasePort2 = serial_base[i];
@@ -373,7 +361,7 @@
 static int ungermann_try_io_port(dev_link_t *link)
 {
     int ret;
-    ioaddr_t ioaddr;
+    kio_addr_t ioaddr;
     /*
 	Ungermann-Bass Access/CARD accepts 0x300,0x320,0x340,0x360
 	0x380,0x3c0 only for ioport.
@@ -400,7 +388,7 @@
     cisparse_t parse;
     u_short buf[32];
     int i, last_fn, last_ret, ret;
-    ioaddr_t ioaddr;
+    kio_addr_t ioaddr;
     cardtype_t cardtype;
     char *card_name = "unknown";
     u_char *node_id;
@@ -591,6 +579,7 @@
     lp->cardtype = cardtype;
     link->dev = &lp->node;
     link->state &= ~DEV_CONFIG_PENDING;
+    SET_NETDEV_DEV(dev, &handle_to_dev(handle));
 
     if (register_netdev(dev) != 0) {
 	printk(KERN_NOTICE "fmvj18x_cs: register_netdev() failed\n");
@@ -623,7 +612,7 @@
 {
     win_req_t req;
     memreq_t mem;
-    u_char *base;
+    u_char __iomem *base;
     int i, j;
 
     /* Allocate a small memory window */
@@ -676,10 +665,10 @@
 {
     win_req_t req;
     memreq_t mem;
-    u_char *base;
+    u_char __iomem *base;
     int i, j;
     struct net_device *dev = link->priv;
-    ioaddr_t ioaddr;
+    kio_addr_t ioaddr;
 
     /* Allocate a small memory window */
     req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
@@ -792,8 +781,7 @@
 static void __exit exit_fmvj18x_cs(void)
 {
 	pcmcia_unregister_driver(&fmvj18x_cs_driver);
-	while (dev_list != NULL)
-		fmvj18x_detach(dev_list);
+	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_fmvj18x_cs);
@@ -805,7 +793,7 @@
 {
     struct net_device *dev = dev_id;
     local_info_t *lp = netdev_priv(dev);
-    ioaddr_t ioaddr;
+    kio_addr_t ioaddr;
     unsigned short tx_stat, rx_stat;
 
     if (lp == NULL) {
@@ -864,7 +852,7 @@
 static void fjn_tx_timeout(struct net_device *dev)
 {
     struct local_info_t *lp = netdev_priv(dev);
-    ioaddr_t ioaddr = dev->base_addr;
+    kio_addr_t ioaddr = dev->base_addr;
 
     printk(KERN_NOTICE "%s: transmit timed out with status %04x, %s?\n",
 	   dev->name, htons(inw(ioaddr + TX_STATUS)),
@@ -894,7 +882,7 @@
 static int fjn_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
     struct local_info_t *lp = netdev_priv(dev);
-    ioaddr_t ioaddr = dev->base_addr;
+    kio_addr_t ioaddr = dev->base_addr;
     short length = skb->len;
     
     if (length < ETH_ZLEN)
@@ -968,7 +956,7 @@
 static void fjn_reset(struct net_device *dev)
 {
     struct local_info_t *lp = netdev_priv(dev);
-    ioaddr_t ioaddr = dev->base_addr;
+    kio_addr_t ioaddr = dev->base_addr;
     int i;
 
     DEBUG(4, "fjn_reset(%s) called.\n",dev->name);
@@ -1054,7 +1042,7 @@
 static void fjn_rx(struct net_device *dev)
 {
     struct local_info_t *lp = netdev_priv(dev);
-    ioaddr_t ioaddr = dev->base_addr;
+    kio_addr_t ioaddr = dev->base_addr;
     int boguscount = 10;	/* 5 -> 10: by agy 19940922 */
 
     DEBUG(4, "%s: in rx_packet(), rx_status %02x.\n",
@@ -1209,7 +1197,7 @@
 {
     struct local_info_t *lp = netdev_priv(dev);
     dev_link_t *link = &lp->link;
-    ioaddr_t ioaddr = dev->base_addr;
+    kio_addr_t ioaddr = dev->base_addr;
 
     DEBUG(4, "fjn_close('%s').\n", dev->name);
 
@@ -1252,7 +1240,7 @@
 
 static void set_rx_mode(struct net_device *dev)
 {
-    ioaddr_t ioaddr = dev->base_addr;
+    kio_addr_t ioaddr = dev->base_addr;
     struct local_info_t *lp = netdev_priv(dev);
     u_char mc_filter[8];		 /* Multicast hash filter */
     u_long flags;
diff -Nru a/drivers/net/pcmcia/ibmtr_cs.c b/drivers/net/pcmcia/ibmtr_cs.c
--- a/drivers/net/pcmcia/ibmtr_cs.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/net/pcmcia/ibmtr_cs.c	2005-03-01 23:38:57 -08:00
@@ -72,7 +72,7 @@
 
 #ifdef PCMCIA_DEBUG
 static int pc_debug = PCMCIA_DEBUG;
-MODULE_PARM(pc_debug, "i");
+module_param(pc_debug, int, 0);
 #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
 static char *version =
 "ibmtr_cs.c 1.10   1996/01/06 05:19:00 (Steve Kipisz)\n"
@@ -86,10 +86,6 @@
 
 /* Parameters that can be set with 'insmod' */
 
-/* Bit map of interrupts to choose from */
-static u_int irq_mask = 0xdeb8;
-static int irq_list[4] = { -1 };
-
 /* MMIO base address */
 static u_long mmiobase = 0xce000;
 
@@ -102,12 +98,10 @@
 /* Ringspeed 4,16 */
 static int ringspeed = 16;
 
-MODULE_PARM(irq_mask, "i");
-MODULE_PARM(irq_list, "1-4i");
-MODULE_PARM(mmiobase, "i");
-MODULE_PARM(srambase, "i");
-MODULE_PARM(sramsize, "i");
-MODULE_PARM(ringspeed, "i");
+module_param(mmiobase, ulong, 0);
+module_param(srambase, ulong, 0);
+module_param(sramsize, ulong, 0);
+module_param(ringspeed, int, 0);
 MODULE_LICENSE("GPL");
 
 /*====================================================================*/
@@ -162,7 +156,7 @@
     dev_link_t *link;
     struct net_device *dev;
     client_reg_t client_reg;
-    int i, ret;
+    int ret;
     
     DEBUG(0, "ibmtr_attach()\n");
 
@@ -184,12 +178,7 @@
     link->io.NumPorts1 = 4;
     link->io.IOAddrLines = 16;
     link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
-    link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
-    if (irq_list[0] == -1)
-	link->irq.IRQInfo2 = irq_mask;
-    else
-	for (i = 0; i < 4; i++)
-	    link->irq.IRQInfo2 |= 1 << irq_list[i];
+    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
     link->irq.Handler = &tok_interrupt;
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.Vcc = 50;
@@ -204,7 +193,6 @@
     link->next = dev_list;
     dev_list = link;
     client_reg.dev_info = &dev_info;
-    client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
     client_reg.EventMask =
         CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
         CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
@@ -366,6 +354,7 @@
 
     link->dev = &info->node;
     link->state &= ~DEV_CONFIG_PENDING;
+    SET_NETDEV_DEV(dev, &handle_to_dev(handle));
 
     i = ibmtr_probe_card(dev);
     if (i != 0) {
@@ -538,8 +527,7 @@
 static void __exit exit_ibmtr_cs(void)
 {
 	pcmcia_unregister_driver(&ibmtr_cs_driver);
-	while (dev_list != NULL)
-		ibmtr_detach(dev_list);
+	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_ibmtr_cs);
diff -Nru a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c
--- a/drivers/net/pcmcia/nmclan_cs.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/net/pcmcia/nmclan_cs.c	2005-03-01 23:38:52 -08:00
@@ -405,15 +405,10 @@
 MODULE_DESCRIPTION("New Media PCMCIA ethernet driver");
 MODULE_LICENSE("GPL");
 
-#define INT_MODULE_PARM(n, v) static int n = v; MODULE_PARM(n, "i")
-
-static int irq_list[4] = { -1 };
-MODULE_PARM(irq_list, "1-4i");
+#define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0)
 
 /* 0=auto, 1=10baseT, 2 = 10base2, default=auto */
 INT_MODULE_PARM(if_port, 0);
-/* Bit map of interrupts to choose from */
-INT_MODULE_PARM(irq_mask, 0xdeb8);
 
 #ifdef PCMCIA_DEBUG
 INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
@@ -461,7 +456,7 @@
     dev_link_t *link;
     struct net_device *dev;
     client_reg_t client_reg;
-    int i, ret;
+    int ret;
 
     DEBUG(0, "nmclan_attach()\n");
     DEBUG(1, "%s\n", rcsid);
@@ -479,12 +474,7 @@
     link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
     link->io.IOAddrLines = 5;
     link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
-    link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
-    if (irq_list[0] == -1)
-	link->irq.IRQInfo2 = irq_mask;
-    else
-	for (i = 0; i < 4; i++)
-	    link->irq.IRQInfo2 |= 1 << irq_list[i];
+    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
     link->irq.Handler = &mace_interrupt;
     link->irq.Instance = dev;
     link->conf.Attributes = CONF_ENABLE_IRQ;
@@ -512,7 +502,6 @@
     link->next = dev_list;
     dev_list = link;
     client_reg.dev_info = &dev_info;
-    client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
     client_reg.EventMask =
 	CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
 	CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
@@ -572,7 +561,7 @@
 	assuming that during normal operation, the MACE is always in
 	bank 0.
 ---------------------------------------------------------------------------- */
-static int mace_read(mace_private *lp, ioaddr_t ioaddr, int reg)
+static int mace_read(mace_private *lp, kio_addr_t ioaddr, int reg)
 {
   int data = 0xFF;
   unsigned long flags;
@@ -599,7 +588,7 @@
 	are assuming that during normal operation, the MACE is always in
 	bank 0.
 ---------------------------------------------------------------------------- */
-static void mace_write(mace_private *lp, ioaddr_t ioaddr, int reg, int data)
+static void mace_write(mace_private *lp, kio_addr_t ioaddr, int reg, int data)
 {
   unsigned long flags;
 
@@ -621,7 +610,7 @@
 mace_init
 	Resets the MACE chip.
 ---------------------------------------------------------------------------- */
-static int mace_init(mace_private *lp, ioaddr_t ioaddr, char *enet_addr)
+static int mace_init(mace_private *lp, kio_addr_t ioaddr, char *enet_addr)
 {
   int i;
   int ct = 0;
@@ -713,7 +702,7 @@
   cisparse_t parse;
   u_char buf[64];
   int i, last_ret, last_fn;
-  ioaddr_t ioaddr;
+  kio_addr_t ioaddr;
 
   DEBUG(0, "nmclan_config(0x%p)\n", link);
 
@@ -775,6 +764,7 @@
 
   link->dev = &lp->node;
   link->state &= ~DEV_CONFIG_PENDING;
+  SET_NETDEV_DEV(dev, &handle_to_dev(handle));
 
   i = register_netdev(dev);
   if (i != 0) {
@@ -945,7 +935,7 @@
 ---------------------------------------------------------------------------- */
 static int mace_open(struct net_device *dev)
 {
-  ioaddr_t ioaddr = dev->base_addr;
+  kio_addr_t ioaddr = dev->base_addr;
   mace_private *lp = netdev_priv(dev);
   dev_link_t *link = &lp->link;
 
@@ -968,7 +958,7 @@
 ---------------------------------------------------------------------------- */
 static int mace_close(struct net_device *dev)
 {
-  ioaddr_t ioaddr = dev->base_addr;
+  kio_addr_t ioaddr = dev->base_addr;
   mace_private *lp = netdev_priv(dev);
   dev_link_t *link = &lp->link;
 
@@ -1041,7 +1031,7 @@
 static int mace_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
   mace_private *lp = netdev_priv(dev);
-  ioaddr_t ioaddr = dev->base_addr;
+  kio_addr_t ioaddr = dev->base_addr;
 
   netif_stop_queue(dev);
 
@@ -1102,7 +1092,7 @@
 {
   struct net_device *dev = (struct net_device *) dev_id;
   mace_private *lp = netdev_priv(dev);
-  ioaddr_t ioaddr = dev->base_addr;
+  kio_addr_t ioaddr = dev->base_addr;
   int status;
   int IntrCnt = MACE_MAX_IR_ITERATIONS;
 
@@ -1244,7 +1234,7 @@
 static int mace_rx(struct net_device *dev, unsigned char RxCnt)
 {
   mace_private *lp = netdev_priv(dev);
-  ioaddr_t ioaddr = dev->base_addr;
+  kio_addr_t ioaddr = dev->base_addr;
   unsigned char rx_framecnt;
   unsigned short rx_status;
 
@@ -1408,7 +1398,7 @@
 	card's SRAM fast enough.  If this happens, something is
 	seriously wrong with the hardware.
 ---------------------------------------------------------------------------- */
-static void update_stats(ioaddr_t ioaddr, struct net_device *dev)
+static void update_stats(kio_addr_t ioaddr, struct net_device *dev)
 {
   mace_private *lp = netdev_priv(dev);
 
@@ -1554,7 +1544,7 @@
   mace_private *lp = netdev_priv(dev);
   int num_addrs = lp->multicast_num_addrs;
   int *ladrf = lp->multicast_ladrf;
-  ioaddr_t ioaddr = dev->base_addr;
+  kio_addr_t ioaddr = dev->base_addr;
   int i;
 
   DEBUG(2, "%s: restoring Rx mode to %d addresses.\n",
@@ -1646,7 +1636,7 @@
 
 static void restore_multicast_list(struct net_device *dev)
 {
-  ioaddr_t ioaddr = dev->base_addr;
+  kio_addr_t ioaddr = dev->base_addr;
   mace_private *lp = netdev_priv(dev);
 
   DEBUG(2, "%s: restoring Rx mode to %d addresses.\n", dev->name,
@@ -1702,8 +1692,7 @@
 static void __exit exit_nmclan_cs(void)
 {
 	pcmcia_unregister_driver(&nmclan_cs_driver);
-	while (dev_list != NULL)
-		nmclan_detach(dev_list);
+	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_nmclan_cs);
diff -Nru a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c
--- a/drivers/net/pcmcia/pcnet_cs.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/net/pcmcia/pcnet_cs.c	2005-03-01 23:39:09 -08:00
@@ -71,7 +71,7 @@
 
 #ifdef PCMCIA_DEBUG
 static int pc_debug = PCMCIA_DEBUG;
-MODULE_PARM(pc_debug, "i");
+module_param(pc_debug, int, 0);
 #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
 static char *version =
 "pcnet_cs.c 1.153 2003/11/09 18:53:09 (David Hinds)";
@@ -87,12 +87,7 @@
 MODULE_DESCRIPTION("NE2000 compatible PCMCIA ethernet driver");
 MODULE_LICENSE("GPL");
 
-#define INT_MODULE_PARM(n, v) static int n = v; MODULE_PARM(n, "i")
-
-/* Bit map of interrupts to choose from */
-INT_MODULE_PARM(irq_mask,	0xdeb8);
-static int irq_list[4] = { -1 };
-MODULE_PARM(irq_list, "1-4i");
+#define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0)
 
 INT_MODULE_PARM(if_port,	1);	/* Transceiver type */
 INT_MODULE_PARM(use_big_buf,	1);	/* use 64K packet buffer? */
@@ -104,7 +99,7 @@
 
 /* Ugh!  Let the user hardwire the hardware address for queer cards */
 static int hw_addr[6] = { 0, /* ... */ };
-MODULE_PARM(hw_addr, "6i");
+module_param_array(hw_addr, int, NULL, 0);
 
 /*====================================================================*/
 
@@ -227,7 +222,7 @@
     dev_link_t		link;
     dev_node_t		node;
     u_int		flags;
-    caddr_t		base;
+    void		__iomem *base;
     struct timer_list	watchdog;
     int			stale, fast_poll;
     u_char		phy_id;
@@ -256,7 +251,7 @@
     dev_link_t *link;
     struct net_device *dev;
     client_reg_t client_reg;
-    int i, ret;
+    int ret;
 
     DEBUG(0, "pcnet_attach()\n");
 
@@ -268,12 +263,7 @@
     link->priv = dev;
 
     link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
-    link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
-    if (irq_list[0] == -1)
-	link->irq.IRQInfo2 = irq_mask;
-    else
-	for (i = 0; i < 4; i++)
-	    link->irq.IRQInfo2 |= 1 << irq_list[i];
+    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.IntType = INT_MEMORY_AND_IO;
 
@@ -286,7 +276,6 @@
     link->next = dev_list;
     dev_list = link;
     client_reg.dev_info = &dev_info;
-    client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
     client_reg.EventMask =
 	CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
 	CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
@@ -352,7 +341,7 @@
     struct net_device *dev = link->priv;
     win_req_t req;
     memreq_t mem;
-    u_char *base, *virt;
+    u_char __iomem *base, *virt;
     int i, j;
 
     /* Allocate a small memory window */
@@ -399,7 +388,7 @@
 static hw_info_t *get_prom(dev_link_t *link)
 {
     struct net_device *dev = link->priv;
-    ioaddr_t ioaddr = dev->base_addr;
+    kio_addr_t ioaddr = dev->base_addr;
     u_char prom[32];
     int i, j;
 
@@ -475,7 +464,7 @@
 static hw_info_t *get_ax88190(dev_link_t *link)
 {
     struct net_device *dev = link->priv;
-    ioaddr_t ioaddr = dev->base_addr;
+    kio_addr_t ioaddr = dev->base_addr;
     int i, j;
 
     /* Not much of a test, but the alternatives are messy */
@@ -722,6 +711,7 @@
 
     link->dev = &info->node;
     link->state &= ~DEV_CONFIG_PENDING;
+    SET_NETDEV_DEV(dev, &handle_to_dev(handle));
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
     dev->poll_controller = ei_poll;
@@ -862,7 +852,7 @@
 #define MDIO_DATA_READ		0x10
 #define MDIO_MASK		0x0f
 
-static void mdio_sync(ioaddr_t addr)
+static void mdio_sync(kio_addr_t addr)
 {
     int bits, mask = inb(addr) & MDIO_MASK;
     for (bits = 0; bits < 32; bits++) {
@@ -871,7 +861,7 @@
     }
 }
 
-static int mdio_read(ioaddr_t addr, int phy_id, int loc)
+static int mdio_read(kio_addr_t addr, int phy_id, int loc)
 {
     u_int cmd = (0x06<<10)|(phy_id<<5)|loc;
     int i, retval = 0, mask = inb(addr) & MDIO_MASK;
@@ -890,7 +880,7 @@
     return (retval>>1) & 0xffff;
 }
 
-static void mdio_write(ioaddr_t addr, int phy_id, int loc, int value)
+static void mdio_write(kio_addr_t addr, int phy_id, int loc, int value)
 {
     u_int cmd = (0x05<<28)|(phy_id<<23)|(loc<<18)|(1<<17)|value;
     int i, mask = inb(addr) & MDIO_MASK;
@@ -907,7 +897,7 @@
     }
 }
 
-static void mdio_reset(ioaddr_t addr, int phy_id)
+static void mdio_reset(kio_addr_t addr, int phy_id)
 {
     outb_p(0x08, addr);
     outb_p(0x0c, addr);
@@ -933,10 +923,10 @@
 
 #define DL19FDUPLX	0x0400	/* DL10019 Full duplex mode */
 
-static int read_eeprom(ioaddr_t ioaddr, int location)
+static int read_eeprom(kio_addr_t ioaddr, int location)
 {
     int i, retval = 0;
-    ioaddr_t ee_addr = ioaddr + DLINK_EEPROM;
+    kio_addr_t ee_addr = ioaddr + DLINK_EEPROM;
     int read_cmd = location | (EE_READ_CMD << 8);
 
     outb(0, ee_addr);
@@ -967,10 +957,10 @@
     In ASIC mode, EE_ADOT is used to output the data to the ASIC.
 */
 
-static void write_asic(ioaddr_t ioaddr, int location, short asic_data)
+static void write_asic(kio_addr_t ioaddr, int location, short asic_data)
 {
 	int i;
-	ioaddr_t ee_addr = ioaddr + DLINK_EEPROM;
+	kio_addr_t ee_addr = ioaddr + DLINK_EEPROM;
 	short dataval;
 	int read_cmd = location | (EE_READ_CMD << 8);
 
@@ -1012,7 +1002,7 @@
 
 static void set_misc_reg(struct net_device *dev)
 {
-    ioaddr_t nic_base = dev->base_addr;
+    kio_addr_t nic_base = dev->base_addr;
     pcnet_dev_t *info = PRIV(dev);
     u_char tmp;
     
@@ -1044,7 +1034,7 @@
 static void mii_phy_probe(struct net_device *dev)
 {
     pcnet_dev_t *info = PRIV(dev);
-    ioaddr_t mii_addr = dev->base_addr + DLINK_GPIO;
+    kio_addr_t mii_addr = dev->base_addr + DLINK_GPIO;
     int i;
     u_int tmp, phyid;
 
@@ -1119,7 +1109,7 @@
 
 static void pcnet_reset_8390(struct net_device *dev)
 {
-    ioaddr_t nic_base = dev->base_addr;
+    kio_addr_t nic_base = dev->base_addr;
     int i;
 
     ei_status.txing = ei_status.dmaing = 0;
@@ -1177,8 +1167,8 @@
 {
     struct net_device *dev = (struct net_device *)arg;
     pcnet_dev_t *info = PRIV(dev);
-    ioaddr_t nic_base = dev->base_addr;
-    ioaddr_t mii_addr = nic_base + DLINK_GPIO;
+    kio_addr_t nic_base = dev->base_addr;
+    kio_addr_t mii_addr = nic_base + DLINK_GPIO;
     u_short link;
 
     if (!netif_device_present(dev)) goto reschedule;
@@ -1281,7 +1271,7 @@
 {
     pcnet_dev_t *info = PRIV(dev);
     u16 *data = (u16 *)&rq->ifr_ifru;
-    ioaddr_t mii_addr = dev->base_addr + DLINK_GPIO;
+    kio_addr_t mii_addr = dev->base_addr + DLINK_GPIO;
     switch (cmd) {
     case SIOCGMIIPHY:
 	data[0] = info->phy_id;
@@ -1303,7 +1293,7 @@
 			     struct e8390_pkt_hdr *hdr,
 			     int ring_page)
 {
-    ioaddr_t nic_base = dev->base_addr;
+    kio_addr_t nic_base = dev->base_addr;
 
     if (ei_status.dmaing) {
 	printk(KERN_NOTICE "%s: DMAing conflict in dma_block_input."
@@ -1334,7 +1324,7 @@
 static void dma_block_input(struct net_device *dev, int count,
 			    struct sk_buff *skb, int ring_offset)
 {
-    ioaddr_t nic_base = dev->base_addr;
+    kio_addr_t nic_base = dev->base_addr;
     int xfer_count = count;
     char *buf = skb->data;
 
@@ -1389,7 +1379,7 @@
 static void dma_block_output(struct net_device *dev, int count,
 			     const u_char *buf, const int start_page)
 {
-    ioaddr_t nic_base = dev->base_addr;
+    kio_addr_t nic_base = dev->base_addr;
     pcnet_dev_t *info = PRIV(dev);
 #ifdef PCMCIA_DEBUG
     int retries = 0;
@@ -1491,9 +1481,10 @@
 
 /*====================================================================*/
 
-static void copyin(u_char *dest, u_char *src, int c)
+static void copyin(void *dest, void __iomem *src, int c)
 {
-    u_short *d = (u_short *)dest, *s = (u_short *)src;
+    u_short *d = dest;
+    u_short __iomem *s = src;
     int odd;
 
     if (c <= 0)
@@ -1508,9 +1499,10 @@
 	*((u_char *)d) = readw(s) & 0xff;
 }
 
-static void copyout(u_char *dest, const u_char *src, int c)
+static void copyout(void __iomem *dest, const void *src, int c)
 {
-    u_short *d = (u_short *)dest, *s = (u_short *)src;
+    u_short __iomem *d = dest;
+    const u_short *s = src;
     int odd;
 
     if (c <= 0)
@@ -1531,10 +1523,11 @@
 			       struct e8390_pkt_hdr *hdr,
 			       int ring_page)
 {
-    void *xfer_start = (void *)(ei_status.rmem_start + (ring_page << 8)
-				- (ei_status.rx_start_page << 8));
+    void __iomem *xfer_start = ei_status.mem + (TX_PAGES<<8)
+				+ (ring_page << 8)
+				- (ei_status.rx_start_page << 8);
     
-    copyin((void *)hdr, xfer_start, sizeof(struct e8390_pkt_hdr));
+    copyin(hdr, xfer_start, sizeof(struct e8390_pkt_hdr));
     /* Fix for big endian systems */
     hdr->count = le16_to_cpu(hdr->count);
 }
@@ -1544,17 +1537,17 @@
 static void shmem_block_input(struct net_device *dev, int count,
 			      struct sk_buff *skb, int ring_offset)
 {
-    void *xfer_start = (void *)(ei_status.rmem_start + ring_offset
-				- (ei_status.rx_start_page << 8));
+    void __iomem *xfer_start = ei_status.mem + (TX_PAGES<<8)
+				+ ring_offset
+				- (ei_status.rx_start_page << 8);
     char *buf = skb->data;
     
-    if (xfer_start + count > (void *)ei_status.rmem_end) {
+    if (xfer_start + count > (void __iomem *)ei_status.rmem_end) {
 	/* We must wrap the input move. */
-	int semi_count = (void*)ei_status.rmem_end - xfer_start;
+	int semi_count = (void __iomem *)ei_status.rmem_end - xfer_start;
 	copyin(buf, xfer_start, semi_count);
 	buf += semi_count;
-	ring_offset = ei_status.rx_start_page << 8;
-	xfer_start = (void *)ei_status.rmem_start;
+	xfer_start = ei_status.mem + (TX_PAGES<<8);
 	count -= semi_count;
     }
     copyin(buf, xfer_start, count);
@@ -1565,7 +1558,7 @@
 static void shmem_block_output(struct net_device *dev, int count,
 			       const u_char *buf, const int start_page)
 {
-    void *shmem = (void *)dev->mem_start + (start_page << 8);
+    void __iomem *shmem = ei_status.mem + (start_page << 8);
     shmem -= ei_status.tx_start_page << 8;
     copyout(shmem, buf, count);
 }
@@ -1617,8 +1610,8 @@
 	goto failed;
     }
     
-    dev->mem_start = (u_long)info->base + offset;
-    ei_status.rmem_start = dev->mem_start + (TX_PAGES<<8);
+    ei_status.mem = info->base + offset;
+    dev->mem_start = (u_long)ei_status.mem;
     dev->mem_end = ei_status.rmem_end = (u_long)info->base + req.Size;
 
     ei_status.tx_start_page = start_pg;
@@ -1659,8 +1652,7 @@
 {
     DEBUG(0, "pcnet_cs: unloading\n");
     pcmcia_unregister_driver(&pcnet_driver);
-    while (dev_list != NULL)
-	pcnet_detach(dev_list);
+    BUG_ON(dev_list != NULL);
 }
 
 module_init(init_pcnet_cs);
diff -Nru a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c
--- a/drivers/net/pcmcia/smc91c92_cs.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/net/pcmcia/smc91c92_cs.c	2005-03-01 23:39:07 -08:00
@@ -66,7 +66,7 @@
 MODULE_DESCRIPTION("SMC 91c92 series PCMCIA ethernet driver");
 MODULE_LICENSE("GPL");
 
-#define INT_MODULE_PARM(n, v) static int n = v; MODULE_PARM(n, "i")
+#define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0)
 
 /*
   Transceiver/media type.
@@ -76,11 +76,6 @@
 */
 INT_MODULE_PARM(if_port, 0);
 
-/* Bit map of interrupts to choose from. */
-INT_MODULE_PARM(irq_mask, 0xdeb8);
-static int irq_list[4] = { -1 };
-MODULE_PARM(irq_list, "1-4i");
-
 #ifdef PCMCIA_DEBUG
 INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
 static const char *version =
@@ -120,7 +115,7 @@
     dev_node_t			node;
     struct sk_buff		*saved_skb;
     int				packets_waiting;
-    caddr_t			base;
+    void			__iomem *base;
     u_short			cfg;
     struct timer_list		media;
     int				watchdog, tx_err;
@@ -300,7 +295,7 @@
 static void smc_set_xcvr(struct net_device *dev, int if_port);
 static void smc_reset(struct net_device *dev);
 static void media_check(u_long arg);
-static void mdio_sync(ioaddr_t addr);
+static void mdio_sync(kio_addr_t addr);
 static int mdio_read(struct net_device *dev, int phy_id, int loc);
 static void mdio_write(struct net_device *dev, int phy_id, int loc, int value);
 static int smc_link_ok(struct net_device *dev);
@@ -320,7 +315,7 @@
     struct smc_private *smc;
     dev_link_t *link;
     struct net_device *dev;
-    int i, ret;
+    int ret;
 
     DEBUG(0, "smc91c92_attach()\n");
 
@@ -337,12 +332,7 @@
     link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
     link->io.IOAddrLines = 4;
     link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
-    link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
-    if (irq_list[0] == -1)
-	link->irq.IRQInfo2 = irq_mask;
-    else
-	for (i = 0; i < 4; i++)
-	    link->irq.IRQInfo2 |= 1 << irq_list[i];
+    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
     link->irq.Handler = &smc_interrupt;
     link->irq.Instance = dev;
     link->conf.Attributes = CONF_ENABLE_IRQ;
@@ -374,7 +364,6 @@
     link->next = dev_list;
     dev_list = link;
     client_reg.dev_info = &dev_info;
-    client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
     client_reg.EventMask = CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
 	CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
 	CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
@@ -622,8 +611,8 @@
 {
     struct net_device *dev = link->priv;
     struct smc_private *smc = netdev_priv(dev);
-    ioaddr_t ioaddr = dev->base_addr;
-    ioaddr_t iouart = link->io.BasePort2;
+    kio_addr_t ioaddr = dev->base_addr;
+    kio_addr_t iouart = link->io.BasePort2;
 
     /* Set UART base address and force map with COR bit 1 */
     writeb(iouart & 0xff,        smc->base + MOT_UART + CISREG_IOBASE_0);
@@ -642,7 +631,7 @@
 static int mot_setup(dev_link_t *link)
 {
     struct net_device *dev = link->priv;
-    ioaddr_t ioaddr = dev->base_addr;
+    kio_addr_t ioaddr = dev->base_addr;
     int i, wait, loop;
     u_int addr;
 
@@ -750,7 +739,7 @@
 static int osi_config(dev_link_t *link)
 {
     struct net_device *dev = link->priv;
-    static ioaddr_t com[4] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 };
+    static kio_addr_t com[4] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 };
     int i, j;
 
     link->conf.Attributes |= CONF_ENABLE_SPKR;
@@ -839,7 +828,7 @@
 static int check_sig(dev_link_t *link)
 {
     struct net_device *dev = link->priv;
-    ioaddr_t ioaddr = dev->base_addr;
+    kio_addr_t ioaddr = dev->base_addr;
     int width;
     u_short s;
 
@@ -903,7 +892,7 @@
     u_short buf[32];
     char *name;
     int i, j, rev;
-    ioaddr_t ioaddr;
+    kio_addr_t ioaddr;
     u_long mir;
 
     DEBUG(0, "smc91c92_config(0x%p)\n", link);
@@ -1024,6 +1013,7 @@
 
     link->dev = &smc->node;
     link->state &= ~DEV_CONFIG_PENDING;
+    SET_NETDEV_DEV(dev, &handle_to_dev(handle));
 
     if (register_netdev(dev) != 0) {
 	printk(KERN_ERR "smc91c92_cs: register_netdev() failed\n");
@@ -1181,7 +1171,7 @@
 #define MDIO_DATA_WRITE1	(MDIO_DIR_WRITE | MDIO_DATA_OUT)
 #define MDIO_DATA_READ		0x02
 
-static void mdio_sync(ioaddr_t addr)
+static void mdio_sync(kio_addr_t addr)
 {
     int bits;
     for (bits = 0; bits < 32; bits++) {
@@ -1192,7 +1182,7 @@
 
 static int mdio_read(struct net_device *dev, int phy_id, int loc)
 {
-    ioaddr_t addr = dev->base_addr + MGMT;
+    kio_addr_t addr = dev->base_addr + MGMT;
     u_int cmd = (0x06<<10)|(phy_id<<5)|loc;
     int i, retval = 0;
 
@@ -1212,7 +1202,7 @@
 
 static void mdio_write(struct net_device *dev, int phy_id, int loc, int value)
 {
-    ioaddr_t addr = dev->base_addr + MGMT;
+    kio_addr_t addr = dev->base_addr + MGMT;
     u_int cmd = (0x05<<28)|(phy_id<<23)|(loc<<18)|(1<<17)|value;
     int i;
 
@@ -1238,7 +1228,7 @@
 #ifdef PCMCIA_DEBUG
 static void smc_dump(struct net_device *dev)
 {
-    ioaddr_t ioaddr = dev->base_addr;
+    kio_addr_t ioaddr = dev->base_addr;
     u_short i, w, save;
     save = inw(ioaddr + BANK_SELECT);
     for (w = 0; w < 4; w++) {
@@ -1293,7 +1283,7 @@
 {
     struct smc_private *smc = netdev_priv(dev);
     dev_link_t *link = &smc->link;
-    ioaddr_t ioaddr = dev->base_addr;
+    kio_addr_t ioaddr = dev->base_addr;
 
     DEBUG(0, "%s: smc_close(), status %4.4x.\n",
 	  dev->name, inw(ioaddr + BANK_SELECT));
@@ -1330,7 +1320,7 @@
 {
     struct smc_private *smc = netdev_priv(dev);
     struct sk_buff *skb = smc->saved_skb;
-    ioaddr_t ioaddr = dev->base_addr;
+    kio_addr_t ioaddr = dev->base_addr;
     u_char packet_no;
 
     if (!skb) {
@@ -1394,7 +1384,7 @@
 static void smc_tx_timeout(struct net_device *dev)
 {
     struct smc_private *smc = netdev_priv(dev);
-    ioaddr_t ioaddr = dev->base_addr;
+    kio_addr_t ioaddr = dev->base_addr;
 
     printk(KERN_NOTICE "%s: SMC91c92 transmit timed out, "
 	   "Tx_status %2.2x status %4.4x.\n",
@@ -1409,7 +1399,7 @@
 static int smc_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
     struct smc_private *smc = netdev_priv(dev);
-    ioaddr_t ioaddr = dev->base_addr;
+    kio_addr_t ioaddr = dev->base_addr;
     u_short num_pages;
     short time_out, ir;
 
@@ -1475,7 +1465,7 @@
 static void smc_tx_err(struct net_device * dev)
 {
     struct smc_private *smc = netdev_priv(dev);
-    ioaddr_t ioaddr = dev->base_addr;
+    kio_addr_t ioaddr = dev->base_addr;
     int saved_packet = inw(ioaddr + PNR_ARR) & 0xff;
     int packet_no = inw(ioaddr + FIFO_PORTS) & 0x7f;
     int tx_status;
@@ -1519,7 +1509,7 @@
 static void smc_eph_irq(struct net_device *dev)
 {
     struct smc_private *smc = netdev_priv(dev);
-    ioaddr_t ioaddr = dev->base_addr;
+    kio_addr_t ioaddr = dev->base_addr;
     u_short card_stats, ephs;
 
     SMC_SELECT_BANK(0);
@@ -1554,7 +1544,7 @@
 {
     struct net_device *dev = dev_id;
     struct smc_private *smc = netdev_priv(dev);
-    ioaddr_t ioaddr;
+    kio_addr_t ioaddr;
     u_short saved_bank, saved_pointer, mask, status;
     unsigned int handled = 1;
     char bogus_cnt = INTR_WORK;		/* Work we are willing to do. */
@@ -1672,7 +1662,7 @@
 static void smc_rx(struct net_device *dev)
 {
     struct smc_private *smc = netdev_priv(dev);
-    ioaddr_t ioaddr = dev->base_addr;
+    kio_addr_t ioaddr = dev->base_addr;
     int rx_status;
     int packet_length;	/* Caution: not frame length, rather words
 			   to transfer from the chip. */
@@ -1778,7 +1768,7 @@
 
 static void set_rx_mode(struct net_device *dev)
 {
-    ioaddr_t ioaddr = dev->base_addr;
+    kio_addr_t ioaddr = dev->base_addr;
     struct smc_private *smc = netdev_priv(dev);
     u_int multicast_table[ 2 ] = { 0, };
     unsigned long flags;
@@ -1845,7 +1835,7 @@
 static void smc_set_xcvr(struct net_device *dev, int if_port)
 {
     struct smc_private *smc = netdev_priv(dev);
-    ioaddr_t ioaddr = dev->base_addr;
+    kio_addr_t ioaddr = dev->base_addr;
     u_short saved_bank;
 
     saved_bank = inw(ioaddr + BANK_SELECT);
@@ -1868,7 +1858,7 @@
 
 static void smc_reset(struct net_device *dev)
 {
-    ioaddr_t ioaddr = dev->base_addr;
+    kio_addr_t ioaddr = dev->base_addr;
     struct smc_private *smc = netdev_priv(dev);
     int i;
 
@@ -1945,7 +1935,7 @@
 {
     struct net_device *dev = (struct net_device *) arg;
     struct smc_private *smc = netdev_priv(dev);
-    ioaddr_t ioaddr = dev->base_addr;
+    kio_addr_t ioaddr = dev->base_addr;
     u_short i, media, saved_bank;
     u_short link;
 
@@ -2057,7 +2047,7 @@
 
 static int smc_link_ok(struct net_device *dev)
 {
-    ioaddr_t ioaddr = dev->base_addr;
+    kio_addr_t ioaddr = dev->base_addr;
     struct smc_private *smc = netdev_priv(dev);
 
     if (smc->cfg & CFG_MII_SELECT) {
@@ -2071,7 +2061,7 @@
 static int smc_netdev_get_ecmd(struct net_device *dev, struct ethtool_cmd *ecmd)
 {
     u16 tmp;
-    ioaddr_t ioaddr = dev->base_addr;
+    kio_addr_t ioaddr = dev->base_addr;
 
     ecmd->supported = (SUPPORTED_TP | SUPPORTED_AUI |
 	SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full);
@@ -2093,7 +2083,7 @@
 static int smc_netdev_set_ecmd(struct net_device *dev, struct ethtool_cmd *ecmd)
 {
     u16 tmp;
-    ioaddr_t ioaddr = dev->base_addr;
+    kio_addr_t ioaddr = dev->base_addr;
 
     if (ecmd->speed != SPEED_10)
     	return -EINVAL;
@@ -2136,7 +2126,7 @@
 static int smc_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 {
 	struct smc_private *smc = netdev_priv(dev);
-	ioaddr_t ioaddr = dev->base_addr;
+	kio_addr_t ioaddr = dev->base_addr;
 	u16 saved_bank = inw(ioaddr + BANK_SELECT);
 	int ret;
 
@@ -2154,7 +2144,7 @@
 static int smc_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 {
 	struct smc_private *smc = netdev_priv(dev);
-	ioaddr_t ioaddr = dev->base_addr;
+	kio_addr_t ioaddr = dev->base_addr;
 	u16 saved_bank = inw(ioaddr + BANK_SELECT);
 	int ret;
 
@@ -2172,7 +2162,7 @@
 static u32 smc_get_link(struct net_device *dev)
 {
 	struct smc_private *smc = netdev_priv(dev);
-	ioaddr_t ioaddr = dev->base_addr;
+	kio_addr_t ioaddr = dev->base_addr;
 	u16 saved_bank = inw(ioaddr + BANK_SELECT);
 	u32 ret;
 
@@ -2200,7 +2190,7 @@
 {
 	struct smc_private *smc = netdev_priv(dev);
 	if (smc->cfg & CFG_MII_SELECT) {
-		ioaddr_t ioaddr = dev->base_addr;
+		kio_addr_t ioaddr = dev->base_addr;
 		u16 saved_bank = inw(ioaddr + BANK_SELECT);
 		int res;
 
@@ -2232,7 +2222,7 @@
 	struct mii_ioctl_data *mii = if_mii(rq);
 	int rc = 0;
 	u16 saved_bank;
-	ioaddr_t ioaddr = dev->base_addr;
+	kio_addr_t ioaddr = dev->base_addr;
 
 	if (!netif_running(dev))
 		return -EINVAL;
@@ -2263,8 +2253,7 @@
 static void __exit exit_smc91c92_cs(void)
 {
 	pcmcia_unregister_driver(&smc91c92_cs_driver);
-	while (dev_list != NULL)
-		smc91c92_detach(dev_list);
+	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_smc91c92_cs);
diff -Nru a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c
--- a/drivers/net/pcmcia/xirc2ps_cs.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/net/pcmcia/xirc2ps_cs.c	2005-03-01 23:38:55 -08:00
@@ -220,7 +220,7 @@
  */
 #ifdef PCMCIA_DEBUG
 static int pc_debug = PCMCIA_DEBUG;
-MODULE_PARM(pc_debug, "i");
+module_param(pc_debug, int, 0);
 #define DEBUG(n, args...) if (pc_debug>(n)) printk(KDBG_XIRC args)
 #else
 #define DEBUG(n, args...)
@@ -255,11 +255,8 @@
 MODULE_DESCRIPTION("Xircom PCMCIA ethernet driver");
 MODULE_LICENSE("Dual MPL/GPL");
 
-#define INT_MODULE_PARM(n, v) static int n = v; MODULE_PARM(n, "i")
+#define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0)
 
-static int irq_list[4] = { -1 };
-MODULE_PARM(irq_list, "1-4i");
-INT_MODULE_PARM(irq_mask,	0xdeb8);
 INT_MODULE_PARM(if_port,	0);
 INT_MODULE_PARM(full_duplex,	0);
 INT_MODULE_PARM(do_sound, 	1);
@@ -277,12 +274,12 @@
 static unsigned maxrx_bytes = 22000;
 
 /* MII management prototypes */
-static void mii_idle(ioaddr_t ioaddr);
-static void mii_putbit(ioaddr_t ioaddr, unsigned data);
-static int  mii_getbit(ioaddr_t ioaddr);
-static void mii_wbits(ioaddr_t ioaddr, unsigned data, int len);
-static unsigned mii_rd(ioaddr_t ioaddr,	u_char phyaddr, u_char phyreg);
-static void mii_wr(ioaddr_t ioaddr, u_char phyaddr, u_char phyreg,
+static void mii_idle(kio_addr_t ioaddr);
+static void mii_putbit(kio_addr_t ioaddr, unsigned data);
+static int  mii_getbit(kio_addr_t ioaddr);
+static void mii_wbits(kio_addr_t ioaddr, unsigned data, int len);
+static unsigned mii_rd(kio_addr_t ioaddr, u_char phyaddr, u_char phyreg);
+static void mii_wr(kio_addr_t ioaddr, u_char phyaddr, u_char phyreg,
 		   unsigned data, int len);
 
 /*
@@ -365,7 +362,7 @@
     int dingo;	 /* a CEM56 type card */
     int new_mii; /* has full 10baseT/100baseT MII */
     int modem;	 /* is a multi function card (i.e with a modem) */
-    caddr_t dingo_ccr; /* only used for CEM56 cards */
+    void __iomem *dingo_ccr; /* only used for CEM56 cards */
     unsigned last_ptr_value; /* last packets transmitted value */
     const char *manf_str;
 } local_info_t;
@@ -428,7 +425,7 @@
 static void
 PrintRegisters(struct net_device *dev)
 {
-    ioaddr_t ioaddr = dev->base_addr;
+    kio_addr_t ioaddr = dev->base_addr;
 
     if (pc_debug > 1) {
 	int i, page;
@@ -464,7 +461,7 @@
  * Turn around for read
  */
 static void
-mii_idle(ioaddr_t ioaddr)
+mii_idle(kio_addr_t ioaddr)
 {
     PutByte(XIRCREG2_GPR2, 0x04|0); /* drive MDCK low */
     udelay(1);
@@ -476,7 +473,7 @@
  * Write a bit to MDI/O
  */
 static void
-mii_putbit(ioaddr_t ioaddr, unsigned data)
+mii_putbit(kio_addr_t ioaddr, unsigned data)
 {
   #if 1
     if (data) {
@@ -509,7 +506,7 @@
  * Get a bit from MDI/O
  */
 static int
-mii_getbit(ioaddr_t ioaddr)
+mii_getbit(kio_addr_t ioaddr)
 {
     unsigned d;
 
@@ -522,7 +519,7 @@
 }
 
 static void
-mii_wbits(ioaddr_t ioaddr, unsigned data, int len)
+mii_wbits(kio_addr_t ioaddr, unsigned data, int len)
 {
     unsigned m = 1 << (len-1);
     for (; m; m >>= 1)
@@ -530,7 +527,7 @@
 }
 
 static unsigned
-mii_rd(ioaddr_t ioaddr,	u_char phyaddr, u_char phyreg)
+mii_rd(kio_addr_t ioaddr,	u_char phyaddr, u_char phyreg)
 {
     int i;
     unsigned data=0, m;
@@ -552,7 +549,7 @@
 }
 
 static void
-mii_wr(ioaddr_t ioaddr, u_char phyaddr, u_char phyreg, unsigned data, int len)
+mii_wr(kio_addr_t ioaddr, u_char phyaddr, u_char phyreg, unsigned data, int len)
 {
     int i;
 
@@ -627,7 +624,6 @@
     link->next = dev_list;
     dev_list = link;
     client_reg.dev_info = &dev_info;
-    client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
     client_reg.EventMask =
 	CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
 	CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
@@ -809,7 +805,7 @@
     local_info_t *local = netdev_priv(dev);
     tuple_t tuple;
     cisparse_t parse;
-    ioaddr_t ioaddr;
+    kio_addr_t ioaddr;
     int err, i;
     u_char buf[64];
     cistpl_lan_node_id_t *node_id = (cistpl_lan_node_id_t*)parse.funce.data;
@@ -922,13 +918,7 @@
     link->io.IOAddrLines =10;
     link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
     link->irq.Attributes = IRQ_HANDLE_PRESENT;
-    link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
-    if (irq_list[0] == -1)
-	link->irq.IRQInfo2 = irq_mask;
-    else {
-	for (i = 0; i < 4; i++)
-	    link->irq.IRQInfo2 |= 1 << irq_list[i];
-    }
+    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
     if (local->modem) {
 	int pass;
 
@@ -1121,6 +1111,7 @@
 
     link->dev = &local->node;
     link->state &= ~DEV_CONFIG_PENDING;
+    SET_NETDEV_DEV(dev, &handle_to_dev(handle));
 
     if ((err=register_netdev(dev))) {
 	printk(KNOT_XIRC "register_netdev() failed\n");
@@ -1249,7 +1240,7 @@
 {
     struct net_device *dev = (struct net_device *)dev_id;
     local_info_t *lp = netdev_priv(dev);
-    ioaddr_t ioaddr;
+    kio_addr_t ioaddr;
     u_char saved_page;
     unsigned bytes_rcvd;
     unsigned int_status, eth_status, rx_status, tx_status;
@@ -1354,7 +1345,7 @@
 		    unsigned i;
 		    u_long *p = skb_put(skb, pktlen);
 		    register u_long a;
-		    ioaddr_t edpreg = ioaddr+XIRCREG_EDP-2;
+		    kio_addr_t edpreg = ioaddr+XIRCREG_EDP-2;
 		    for (i=0; i < len ; i += 4, p++) {
 			a = inl(edpreg);
 			__asm__("rorl $16,%0\n\t"
@@ -1483,7 +1474,7 @@
 do_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
     local_info_t *lp = netdev_priv(dev);
-    ioaddr_t ioaddr = dev->base_addr;
+    kio_addr_t ioaddr = dev->base_addr;
     int okay;
     unsigned freespace;
     unsigned pktlen = skb? skb->len : 0;
@@ -1553,7 +1544,7 @@
 static void
 set_addresses(struct net_device *dev)
 {
-    ioaddr_t ioaddr = dev->base_addr;
+    kio_addr_t ioaddr = dev->base_addr;
     local_info_t *lp = netdev_priv(dev);
     struct dev_mc_list *dmi = dev->mc_list;
     char *addr;
@@ -1595,7 +1586,7 @@
 static void
 set_multicast_list(struct net_device *dev)
 {
-    ioaddr_t ioaddr = dev->base_addr;
+    kio_addr_t ioaddr = dev->base_addr;
 
     SelectPage(0x42);
     if (dev->flags & IFF_PROMISC) { /* snoop */
@@ -1679,7 +1670,7 @@
 do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
     local_info_t *local = netdev_priv(dev);
-    ioaddr_t ioaddr = dev->base_addr;
+    kio_addr_t ioaddr = dev->base_addr;
     u16 *data = (u16 *)&rq->ifr_ifru;
 
     DEBUG(1, "%s: ioctl(%-.6s, %#04x) %04x %04x %04x %04x\n",
@@ -1711,7 +1702,7 @@
 hardreset(struct net_device *dev)
 {
     local_info_t *local = netdev_priv(dev);
-    ioaddr_t ioaddr = dev->base_addr;
+    kio_addr_t ioaddr = dev->base_addr;
 
     SelectPage(4);
     udelay(1);
@@ -1728,7 +1719,7 @@
 do_reset(struct net_device *dev, int full)
 {
     local_info_t *local = netdev_priv(dev);
-    ioaddr_t ioaddr = dev->base_addr;
+    kio_addr_t ioaddr = dev->base_addr;
     unsigned value;
 
     DEBUG(0, "%s: do_reset(%p,%d)\n", dev? dev->name:"eth?", dev, full);
@@ -1889,7 +1880,7 @@
 init_mii(struct net_device *dev)
 {
     local_info_t *local = netdev_priv(dev);
-    ioaddr_t ioaddr = dev->base_addr;
+    kio_addr_t ioaddr = dev->base_addr;
     unsigned control, status, linkpartner;
     int i;
 
@@ -1962,7 +1953,7 @@
 do_powerdown(struct net_device *dev)
 {
 
-    ioaddr_t ioaddr = dev->base_addr;
+    kio_addr_t ioaddr = dev->base_addr;
 
     DEBUG(0, "do_powerdown(%p)\n", dev);
 
@@ -1974,7 +1965,7 @@
 static int
 do_stop(struct net_device *dev)
 {
-    ioaddr_t ioaddr = dev->base_addr;
+    kio_addr_t ioaddr = dev->base_addr;
     local_info_t *lp = netdev_priv(dev);
     dev_link_t *link = &lp->link;
 
@@ -2016,9 +2007,7 @@
 exit_xirc2ps_cs(void)
 {
 	pcmcia_unregister_driver(&xirc2ps_cs_driver);
-
-	while (dev_list)
-		xirc2ps_detach(dev_list);
+	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_xirc2ps_cs);
@@ -2027,23 +2016,17 @@
 #ifndef MODULE
 static int __init setup_xirc2ps_cs(char *str)
 {
-	/* irq, irq_mask, if_port, full_duplex, do_sound, lockup_hack
-	 * [,irq2 [,irq3 [,irq4]]]
+	/* if_port, full_duplex, do_sound, lockup_hack
 	 */
 	int ints[10] = { -1 };
 
 	str = get_options(str, 9, ints);
 
 #define MAYBE_SET(X,Y) if (ints[0] >= Y && ints[Y] != -1) { X = ints[Y]; }
-	MAYBE_SET(irq_list[0], 1);
-	MAYBE_SET(irq_mask, 2);
 	MAYBE_SET(if_port, 3);
 	MAYBE_SET(full_duplex, 4);
 	MAYBE_SET(do_sound, 5);
 	MAYBE_SET(lockup_hack, 6);
-	MAYBE_SET(irq_list[1], 7);
-	MAYBE_SET(irq_list[2], 8);
-	MAYBE_SET(irq_list[3], 9);
 #undef  MAYBE_SET
 
 	return 0;
diff -Nru a/drivers/net/plip.c b/drivers/net/plip.c
--- a/drivers/net/plip.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/net/plip.c	2005-03-01 23:39:17 -08:00
@@ -1242,8 +1242,8 @@
 static int parport[PLIP_MAX] = { [0 ... PLIP_MAX-1] = -1 };
 static int timid;
 
-MODULE_PARM(parport, "1-" __MODULE_STRING(PLIP_MAX) "i");
-MODULE_PARM(timid, "1i");
+module_param_array(parport, int, NULL, 0);
+module_param(timid, int, 0);
 MODULE_PARM_DESC(parport, "List of parport device numbers to use by plip");
 
 static struct net_device *dev_plip[PLIP_MAX] = { NULL, };
diff -Nru a/drivers/net/ppp_async.c b/drivers/net/ppp_async.c
--- a/drivers/net/ppp_async.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/net/ppp_async.c	2005-03-01 23:39:08 -08:00
@@ -84,7 +84,7 @@
 #define SC_RCV_BITS	(SC_RCV_B7_1|SC_RCV_B7_0|SC_RCV_ODDP|SC_RCV_EVNP)
 
 static int flag_time = HZ;
-MODULE_PARM(flag_time, "i");
+module_param(flag_time, int, 0);
 MODULE_PARM_DESC(flag_time, "ppp_async: interval between flagged packets (in clock ticks)");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_LDISC(N_PPP);
@@ -126,7 +126,7 @@
  * FIXME: this is no longer true. The _close path for the ldisc is 
  * now guaranteed to be sane. 
  */
-static rwlock_t disc_data_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(disc_data_lock);
 
 static struct asyncppp *ap_get(struct tty_struct *tty)
 {
diff -Nru a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
--- a/drivers/net/ppp_generic.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/net/ppp_generic.c	2005-03-01 23:39:16 -08:00
@@ -210,7 +210,7 @@
  * and the atomicity of find a channel and updating its file.refcnt
  * field.
  */
-static spinlock_t all_channels_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(all_channels_lock);
 static LIST_HEAD(all_channels);
 static LIST_HEAD(new_channels);
 static int last_channel_index;
@@ -2218,7 +2218,7 @@
 
 /* List of compressors. */
 static LIST_HEAD(compressor_list);
-static spinlock_t compressor_list_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(compressor_list_lock);
 
 struct compressor_entry {
 	struct list_head list;
diff -Nru a/drivers/net/ppp_synctty.c b/drivers/net/ppp_synctty.c
--- a/drivers/net/ppp_synctty.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/net/ppp_synctty.c	2005-03-01 23:38:56 -08:00
@@ -178,7 +178,7 @@
  *
  * FIXME: Fixed in tty_io nowdays.
  */
-static rwlock_t disc_data_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(disc_data_lock);
 
 static struct syncppp *sp_get(struct tty_struct *tty)
 {
diff -Nru a/drivers/net/pppoe.c b/drivers/net/pppoe.c
--- a/drivers/net/pppoe.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/net/pppoe.c	2005-03-01 23:39:07 -08:00
@@ -86,7 +86,7 @@
 static int __pppoe_xmit(struct sock *sk, struct sk_buff *skb);
 
 static struct proto_ops pppoe_ops;
-static rwlock_t pppoe_hash_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(pppoe_hash_lock);
 
 static struct ppp_channel_ops pppoe_chan_ops;
 
diff -Nru a/drivers/net/r8169.c b/drivers/net/r8169.c
--- a/drivers/net/r8169.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/net/r8169.c	2005-03-01 23:38:57 -08:00
@@ -6,6 +6,7 @@
  History:
  Feb  4 2002	- created initially by ShuChen <shuchen@realtek.com.tw>.
  May 20 2002	- Add link status force-mode and TBI mode support.
+        2004	- Massive updates. See kernel SCM system for details.
 =========================================================================
   1. [DEPRECATED: use ethtool instead] The media can be forced in 5 modes.
 	 Command: 'insmod r8169 media = SET_MEDIA'
@@ -33,24 +34,43 @@
 	- Copy mc_filter setup code from 8139cp
 	  (includes an optimization, and avoids set_bit use)
 
-*/
+VERSION 1.6LK	<2004/04/14>
+
+	- Merge of Realtek's version 1.6
+	- Conversion to DMA API
+	- Suspend/resume
+	- Endianness
+	- Misc Rx/Tx bugs
+
+VERSION 2.2LK	<2005/01/25>
+
+	- RX csum, TX csum/SG, TSO
+	- VLAN
+	- baby (< 7200) Jumbo frames support
+	- Merge of Realtek's version 2.2 (new phy)
+ */
 
 #include <linux/module.h>
+#include <linux/moduleparam.h>
 #include <linux/pci.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/delay.h>
 #include <linux/ethtool.h>
 #include <linux/mii.h>
+#include <linux/if_vlan.h>
 #include <linux/crc32.h>
+#include <linux/in.h>
+#include <linux/ip.h>
+#include <linux/tcp.h>
 #include <linux/init.h>
 #include <linux/dma-mapping.h>
 
 #include <asm/io.h>
+#include <asm/irq.h>
 
-#define RTL8169_VERSION "1.2"
+#define RTL8169_VERSION "2.2LK"
 #define MODULENAME "r8169"
-#define RTL8169_DRIVER_NAME   MODULENAME " Gigabit Ethernet driver " RTL8169_VERSION
 #define PFX MODULENAME ": "
 
 #ifdef RTL8169_DEBUG
@@ -59,46 +79,49 @@
 	        printk( "Assertion failed! %s,%s,%s,line=%d\n",	\
         	#expr,__FILE__,__FUNCTION__,__LINE__);		\
         }
-#define dprintk(fmt, args...)	do { printk(PFX fmt, ## args) } while (0)
+#define dprintk(fmt, args...)	do { printk(PFX fmt, ## args); } while (0)
 #else
 #define assert(expr) do {} while (0)
 #define dprintk(fmt, args...)	do {} while (0)
 #endif /* RTL8169_DEBUG */
 
+#define TX_BUFFS_AVAIL(tp) \
+	(tp->dirty_tx + NUM_TX_DESC - tp->cur_tx - 1)
+
 #ifdef CONFIG_R8169_NAPI
 #define rtl8169_rx_skb			netif_receive_skb
+#define rtl8169_rx_hwaccel_skb		vlan_hwaccel_rx
 #define rtl8169_rx_quota(count, quota)	min(count, quota)
 #else
 #define rtl8169_rx_skb			netif_rx
+#define rtl8169_rx_hwaccel_skb		vlan_hwaccel_receive_skb
 #define rtl8169_rx_quota(count, quota)	count
 #endif
 
 /* media options */
 #define MAX_UNITS 8
 static int media[MAX_UNITS] = { -1, -1, -1, -1, -1, -1, -1, -1 };
+static int num_media = 0;
 
 /* Maximum events (Rx packets, etc.) to handle at each interrupt. */
 static int max_interrupt_work = 20;
 
 /* 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.  */
+   The RTL chips use a 64 element hash table based on the Ethernet CRC. */
 static int multicast_filter_limit = 32;
 
-/* MAC address length*/
+/* MAC address length */
 #define MAC_ADDR_LEN	6
 
-/* max supported gigabit ethernet frame size -- must be at least (dev->mtu+14+4).*/
-#define MAX_ETH_FRAME_SIZE	1536
-
-#define TX_FIFO_THRESH 256	/* In bytes */
-
-#define RX_FIFO_THRESH	7	/* 7 means NO threshold, Rx buffer level before first PCI xfer.  */
+#define RX_FIFO_THRESH	7	/* 7 means NO threshold, Rx buffer level before first PCI xfer. */
 #define RX_DMA_BURST	6	/* Maximum PCI burst, '6' is 1024 */
 #define TX_DMA_BURST	6	/* Maximum PCI burst, '6' is 1024 */
 #define EarlyTxThld 	0x3F	/* 0x3F means NO early transmit */
-#define RxPacketMaxSize	0x0800	/* Maximum size supported is 16K-1 */
+#define RxPacketMaxSize	0x3FE8	/* 16K - 1 - ETH_HLEN - VLAN - CRC... */
+#define SafeMtu		0x1c20	/* ... actually life sucks beyond ~7k */
 #define InterFrameGap	0x03	/* 3 means InterFrameGap = the shortest one */
 
+#define R8169_REGS_SIZE		256
 #define R8169_NAPI_WEIGHT	64
 #define NUM_TX_DESC	64	/* Number of Tx descriptor registers */
 #define NUM_RX_DESC	256	/* Number of Rx descriptor registers */
@@ -106,7 +129,6 @@
 #define R8169_TX_RING_BYTES	(NUM_TX_DESC * sizeof(struct TxDesc))
 #define R8169_RX_RING_BYTES	(NUM_RX_DESC * sizeof(struct RxDesc))
 
-#define RTL_MIN_IO_SIZE 0x80
 #define RTL8169_TX_TIMEOUT	(6*HZ)
 #define RTL8169_PHY_TIMEOUT	(10*HZ)
 
@@ -122,7 +144,8 @@
 	RTL_GIGA_MAC_VER_B = 0x00,
 	/* RTL_GIGA_MAC_VER_C = 0x03, */
 	RTL_GIGA_MAC_VER_D = 0x01,
-	RTL_GIGA_MAC_VER_E = 0x02
+	RTL_GIGA_MAC_VER_E = 0x02,
+	RTL_GIGA_MAC_VER_X = 0x04	/* Greater than RTL_GIGA_MAC_VER_E */
 };
 
 enum phy_version {
@@ -131,6 +154,7 @@
 	RTL_GIGA_PHY_VER_E = 0x05, /* PHY Reg 0x03 bit0-3 == 0x0000 */
 	RTL_GIGA_PHY_VER_F = 0x06, /* PHY Reg 0x03 bit0-3 == 0x0001 */
 	RTL_GIGA_PHY_VER_G = 0x07, /* PHY Reg 0x03 bit0-3 == 0x0002 */
+	RTL_GIGA_PHY_VER_H = 0x08, /* PHY Reg 0x03 bit0-3 == 0x0003 */
 };
 
 
@@ -144,7 +168,8 @@
 } rtl_chip_info[] = {
 	_R("RTL8169",		RTL_GIGA_MAC_VER_B, 0xff7e1880),
 	_R("RTL8169s/8110s",	RTL_GIGA_MAC_VER_D, 0xff7e1880),
-	_R("RTL8169s/8110s",	RTL_GIGA_MAC_VER_E, 0xff7e1880)
+	_R("RTL8169s/8110s",	RTL_GIGA_MAC_VER_E, 0xff7e1880),
+	_R("RTL8169s/8110s",	RTL_GIGA_MAC_VER_X, 0xff7e1880),
 };
 #undef _R
 
@@ -190,6 +215,7 @@
 	PHYstatus = 0x6C,
 	RxMaxSize = 0xDA,
 	CPlusCmd = 0xE0,
+	IntrMitigate = 0xE2,
 	RxDescAddrLow = 0xE4,
 	RxDescAddrHigh = 0xE8,
 	EarlyTxThres = 0xEC,
@@ -200,7 +226,7 @@
 };
 
 enum RTL8169_register_content {
-	/*InterruptStatusBits */
+	/* InterruptStatusBits */
 	SYSErr = 0x8000,
 	PCSTimeout = 0x4000,
 	SWInt = 0x0100,
@@ -213,23 +239,23 @@
 	RxErr = 0x02,
 	RxOK = 0x01,
 
-	/*RxStatusDesc */
+	/* RxStatusDesc */
 	RxRES = 0x00200000,
 	RxCRC = 0x00080000,
 	RxRUNT = 0x00100000,
 	RxRWT = 0x00400000,
 
-	/*ChipCmdBits */
+	/* ChipCmdBits */
 	CmdReset = 0x10,
 	CmdRxEnb = 0x08,
 	CmdTxEnb = 0x04,
 	RxBufEmpty = 0x01,
 
-	/*Cfg9346Bits */
+	/* Cfg9346Bits */
 	Cfg9346_Lock = 0x00,
 	Cfg9346_Unlock = 0xC0,
 
-	/*rx_mode_bits */
+	/* rx_mode_bits */
 	AcceptErr = 0x20,
 	AcceptRunt = 0x10,
 	AcceptBroadcast = 0x08,
@@ -237,11 +263,11 @@
 	AcceptMyPhys = 0x02,
 	AcceptAllPhys = 0x01,
 
-	/*RxConfigBits */
+	/* RxConfigBits */
 	RxCfgFIFOShift = 13,
 	RxCfgDMAShift = 8,
 
-	/*TxConfigBits */
+	/* TxConfigBits */
 	TxInterFrameGapShift = 24,
 	TxDMAShift = 8,	/* DMA burst value (0-7) is shift this many bits */
 
@@ -259,7 +285,7 @@
 	PCIDAC		= (1 << 4),
 	PCIMulRW	= (1 << 3),
 
-	/*rtl8169_PHYstatus */
+	/* rtl8169_PHYstatus */
 	TBI_Enable = 0x80,
 	TxFlowCtrl = 0x40,
 	RxFlowCtrl = 0x20,
@@ -269,65 +295,94 @@
 	LinkStatus = 0x02,
 	FullDup = 0x01,
 
-	/*GIGABIT_PHY_registers */
+	/* GIGABIT_PHY_registers */
 	PHY_CTRL_REG = 0,
 	PHY_STAT_REG = 1,
 	PHY_AUTO_NEGO_REG = 4,
 	PHY_1000_CTRL_REG = 9,
 
-	/*GIGABIT_PHY_REG_BIT */
+	/* GIGABIT_PHY_REG_BIT */
 	PHY_Restart_Auto_Nego = 0x0200,
 	PHY_Enable_Auto_Nego = 0x1000,
 
-	//PHY_STAT_REG = 1;
+	/* PHY_STAT_REG = 1 */
 	PHY_Auto_Neco_Comp = 0x0020,
 
-	//PHY_AUTO_NEGO_REG = 4;
+	/* PHY_AUTO_NEGO_REG = 4 */
 	PHY_Cap_10_Half = 0x0020,
 	PHY_Cap_10_Full = 0x0040,
 	PHY_Cap_100_Half = 0x0080,
 	PHY_Cap_100_Full = 0x0100,
 
-	//PHY_1000_CTRL_REG = 9;
+	/* PHY_1000_CTRL_REG = 9 */
 	PHY_Cap_1000_Full = 0x0200,
 
 	PHY_Cap_Null = 0x0,
 
-	/*_MediaType*/
+	/* _MediaType */
 	_10_Half = 0x01,
 	_10_Full = 0x02,
 	_100_Half = 0x04,
 	_100_Full = 0x08,
 	_1000_Full = 0x10,
 
-	/*_TBICSRBit*/
+	/* _TBICSRBit */
 	TBILinkOK = 0x02000000,
 };
 
 enum _DescStatusBit {
-	OWNbit = 0x80000000,
-	EORbit = 0x40000000,
-	FSbit = 0x20000000,
-	LSbit = 0x10000000,
+	DescOwn		= (1 << 31), /* Descriptor is owned by NIC */
+	RingEnd		= (1 << 30), /* End of descriptor ring */
+	FirstFrag	= (1 << 29), /* First segment of a packet */
+	LastFrag	= (1 << 28), /* Final segment of a packet */
+
+	/* Tx private */
+	LargeSend	= (1 << 27), /* TCP Large Send Offload (TSO) */
+	MSSShift	= 16,        /* MSS value position */
+	MSSMask		= 0xfff,     /* MSS value + LargeSend bit: 12 bits */
+	IPCS		= (1 << 18), /* Calculate IP checksum */
+	UDPCS		= (1 << 17), /* Calculate UDP/IP checksum */
+	TCPCS		= (1 << 16), /* Calculate TCP/IP checksum */
+	TxVlanTag	= (1 << 17), /* Add VLAN tag */
+
+	/* Rx private */
+	PID1		= (1 << 18), /* Protocol ID bit 1/2 */
+	PID0		= (1 << 17), /* Protocol ID bit 2/2 */
+
+#define RxProtoUDP	(PID1)
+#define RxProtoTCP	(PID0)
+#define RxProtoIP	(PID1 | PID0)
+#define RxProtoMask	RxProtoIP
+
+	IPFail		= (1 << 16), /* IP checksum failed */
+	UDPFail		= (1 << 15), /* UDP/IP checksum failed */
+	TCPFail		= (1 << 14), /* TCP/IP checksum failed */
+	RxVlanTag	= (1 << 16), /* VLAN tag available */
 };
 
 #define RsvdMask	0x3fffc000
 
 struct TxDesc {
-	u32 status;
-	u32 vlan_tag;
+	u32 opts1;
+	u32 opts2;
 	u64 addr;
 };
 
 struct RxDesc {
-	u32 status;
-	u32 vlan_tag;
+	u32 opts1;
+	u32 opts2;
 	u64 addr;
 };
 
+struct ring_info {
+	struct sk_buff	*skb;
+	u32		len;
+	u8		__pad[sizeof(void *) - sizeof(u32)];
+};
+
 struct rtl8169_private {
-	void *mmio_addr;		/* memory map physical address */
-	struct pci_dev *pci_dev;	/* Index of PCI device  */
+	void __iomem *mmio_addr;	/* memory map physical address */
+	struct pci_dev *pci_dev;	/* Index of PCI device */
 	struct net_device_stats stats;	/* statistics of net device */
 	spinlock_t lock;		/* spin lock flag */
 	int chipset;
@@ -342,27 +397,32 @@
 	dma_addr_t TxPhyAddr;
 	dma_addr_t RxPhyAddr;
 	struct sk_buff *Rx_skbuff[NUM_RX_DESC];	/* Rx data buffers */
-	struct sk_buff *Tx_skbuff[NUM_TX_DESC];	/* Tx data buffers */
+	struct ring_info tx_skb[NUM_TX_DESC];	/* Tx data buffers */
+	unsigned rx_buf_sz;
 	struct timer_list timer;
 	u16 cp_cmd;
 	u16 intr_mask;
 	int phy_auto_nego_reg;
 	int phy_1000_ctrl_reg;
-
+#ifdef CONFIG_R8169_VLAN
+	struct vlan_group *vlgrp;
+#endif
 	int (*set_speed)(struct net_device *, u8 autoneg, u16 speed, u8 duplex);
 	void (*get_settings)(struct net_device *, struct ethtool_cmd *);
-	void (*phy_reset_enable)(void *);
-	unsigned int (*phy_reset_pending)(void *);
-	unsigned int (*link_ok)(void *);
+	void (*phy_reset_enable)(void __iomem *);
+	unsigned int (*phy_reset_pending)(void __iomem *);
+	unsigned int (*link_ok)(void __iomem *);
+	struct work_struct task;
 };
 
-MODULE_AUTHOR("Realtek");
+MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@oss.sgi.com>");
 MODULE_DESCRIPTION("RealTek RTL-8169 Gigabit Ethernet driver");
-MODULE_PARM(media, "1-" __MODULE_STRING(MAX_UNITS) "i");
-MODULE_PARM(rx_copybreak, "i");
-MODULE_PARM(use_dac, "i");
+module_param_array(media, int, &num_media, 0);
+module_param(rx_copybreak, int, 0);
+module_param(use_dac, int, 0);
 MODULE_PARM_DESC(use_dac, "Enable PCI DAC. Unsafe on 32 bit PCI slot.");
 MODULE_LICENSE("GPL");
+MODULE_VERSION(RTL8169_VERSION);
 
 static int rtl8169_open(struct net_device *dev);
 static int rtl8169_start_xmit(struct sk_buff *skb, struct net_device *dev);
@@ -374,6 +434,11 @@
 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 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 void rtl8169_down(struct net_device *dev);
+
 #ifdef CONFIG_R8169_NAPI
 static int rtl8169_poll(struct net_device *dev, int *budget);
 #endif
@@ -390,7 +455,7 @@
 #define PHY_Cap_100_Half_Or_Less PHY_Cap_100_Half | PHY_Cap_10_Full_Or_Less
 #define PHY_Cap_100_Full_Or_Less PHY_Cap_100_Full | PHY_Cap_100_Half_Or_Less
 
-static void mdio_write(void *ioaddr, int RegAddr, int value)
+static void mdio_write(void __iomem *ioaddr, int RegAddr, int value)
 {
 	int i;
 
@@ -398,14 +463,14 @@
 	udelay(1000);
 
 	for (i = 2000; i > 0; i--) {
-		// Check if the RTL8169 has completed writing to the specified MII register
+		/* Check if the RTL8169 has completed writing to the specified MII register */
 		if (!(RTL_R32(PHYAR) & 0x80000000)) 
 			break;
 		udelay(100);
 	}
 }
 
-static int mdio_read(void *ioaddr, int RegAddr)
+static int mdio_read(void __iomem *ioaddr, int RegAddr)
 {
 	int i, value = -1;
 
@@ -413,7 +478,7 @@
 	udelay(1000);
 
 	for (i = 2000; i > 0; i--) {
-		// Check if the RTL8169 has completed retrieving data from the specified MII register
+		/* Check if the RTL8169 has completed retrieving data from the specified MII register */
 		if (RTL_R32(PHYAR) & 0x80000000) {
 			value = (int) (RTL_R32(PHYAR) & 0xFFFF);
 			break;
@@ -423,32 +488,46 @@
 	return value;
 }
 
-static unsigned int rtl8169_tbi_reset_pending(void *ioaddr)
+static void rtl8169_irq_mask_and_ack(void __iomem *ioaddr)
+{
+	RTL_W16(IntrMask, 0x0000);
+
+	RTL_W16(IntrStatus, 0xffff);
+}
+
+static void rtl8169_asic_down(void __iomem *ioaddr)
+{
+	RTL_W8(ChipCmd, 0x00);
+	rtl8169_irq_mask_and_ack(ioaddr);
+	RTL_R16(CPlusCmd);
+}
+
+static unsigned int rtl8169_tbi_reset_pending(void __iomem *ioaddr)
 {
 	return RTL_R32(TBICSR) & TBIReset;
 }
 
-static unsigned int rtl8169_xmii_reset_pending(void *ioaddr)
+static unsigned int rtl8169_xmii_reset_pending(void __iomem *ioaddr)
 {
 	return mdio_read(ioaddr, 0) & 0x8000;
 }
 
-static unsigned int rtl8169_tbi_link_ok(void *ioaddr)
+static unsigned int rtl8169_tbi_link_ok(void __iomem *ioaddr)
 {
 	return RTL_R32(TBICSR) & TBILinkOk;
 }
 
-static unsigned int rtl8169_xmii_link_ok(void *ioaddr)
+static unsigned int rtl8169_xmii_link_ok(void __iomem *ioaddr)
 {
 	return RTL_R8(PHYstatus) & LinkStatus;
 }
 
-static void rtl8169_tbi_reset_enable(void *ioaddr)
+static void rtl8169_tbi_reset_enable(void __iomem *ioaddr)
 {
 	RTL_W32(TBICSR, RTL_R32(TBICSR) | TBIReset);
 }
 
-static void rtl8169_xmii_reset_enable(void *ioaddr)
+static void rtl8169_xmii_reset_enable(void __iomem *ioaddr)
 {
 	unsigned int val;
 
@@ -457,7 +536,7 @@
 }
 
 static void rtl8169_check_link_status(struct net_device *dev,
-				      struct rtl8169_private *tp, void *ioaddr)
+				      struct rtl8169_private *tp, void __iomem *ioaddr)
 {
 	unsigned long flags;
 
@@ -507,16 +586,21 @@
 {
 	struct rtl8169_private *tp = netdev_priv(dev);
 
-	strcpy(info->driver, RTL8169_DRIVER_NAME);
-	strcpy(info->version, RTL8169_VERSION );
+	strcpy(info->driver, MODULENAME);
+	strcpy(info->version, RTL8169_VERSION);
 	strcpy(info->bus_info, pci_name(tp->pci_dev));
 }
 
+static int rtl8169_get_regs_len(struct net_device *dev)
+{
+	return R8169_REGS_SIZE;
+}
+
 static int rtl8169_set_speed_tbi(struct net_device *dev,
 				 u8 autoneg, u16 speed, u8 duplex)
 {
 	struct rtl8169_private *tp = netdev_priv(dev);
-	void *ioaddr = tp->mmio_addr;
+	void __iomem *ioaddr = tp->mmio_addr;
 	int ret = 0;
 	u32 reg;
 
@@ -540,7 +624,7 @@
 				  u8 autoneg, u16 speed, u8 duplex)
 {
 	struct rtl8169_private *tp = netdev_priv(dev);
-	void *ioaddr = tp->mmio_addr;
+	void __iomem *ioaddr = tp->mmio_addr;
 	int auto_nego, giga_ctrl;
 
 	auto_nego = mdio_read(ioaddr, PHY_AUTO_NEGO_REG);
@@ -602,10 +686,108 @@
 	return ret;
 }
 
+static u32 rtl8169_get_rx_csum(struct net_device *dev)
+{
+	struct rtl8169_private *tp = netdev_priv(dev);
+
+	return tp->cp_cmd & RxChkSum;
+}
+
+static int rtl8169_set_rx_csum(struct net_device *dev, u32 data)
+{
+	struct rtl8169_private *tp = netdev_priv(dev);
+	void __iomem *ioaddr = tp->mmio_addr;
+	unsigned long flags;
+
+	spin_lock_irqsave(&tp->lock, flags);
+
+	if (data)
+		tp->cp_cmd |= RxChkSum;
+	else
+		tp->cp_cmd &= ~RxChkSum;
+
+	RTL_W16(CPlusCmd, tp->cp_cmd);
+	RTL_R16(CPlusCmd);
+
+	spin_unlock_irqrestore(&tp->lock, flags);
+
+	return 0;
+}
+
+#ifdef CONFIG_R8169_VLAN
+
+static inline u32 rtl8169_tx_vlan_tag(struct rtl8169_private *tp,
+				      struct sk_buff *skb)
+{
+	return (tp->vlgrp && vlan_tx_tag_present(skb)) ?
+		TxVlanTag | swab16(vlan_tx_tag_get(skb)) : 0x00;
+}
+
+static void rtl8169_vlan_rx_register(struct net_device *dev,
+				     struct vlan_group *grp)
+{
+	struct rtl8169_private *tp = netdev_priv(dev);
+	void __iomem *ioaddr = tp->mmio_addr;
+	unsigned long flags;
+
+	spin_lock_irqsave(&tp->lock, flags);
+	tp->vlgrp = grp;
+	if (tp->vlgrp)
+		tp->cp_cmd |= RxVlan;
+	else
+		tp->cp_cmd &= ~RxVlan;
+	RTL_W16(CPlusCmd, tp->cp_cmd);
+	RTL_R16(CPlusCmd);
+	spin_unlock_irqrestore(&tp->lock, flags);
+}
+
+static void rtl8169_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
+{
+	struct rtl8169_private *tp = netdev_priv(dev);
+	unsigned long flags;
+
+	spin_lock_irqsave(&tp->lock, flags);
+	if (tp->vlgrp)
+		tp->vlgrp->vlan_devices[vid] = NULL;
+	spin_unlock_irqrestore(&tp->lock, flags);
+}
+
+static int rtl8169_rx_vlan_skb(struct rtl8169_private *tp, struct RxDesc *desc,
+			       struct sk_buff *skb)
+{
+	u32 opts2 = le32_to_cpu(desc->opts2);
+	int ret;
+
+	if (tp->vlgrp && (opts2 & RxVlanTag)) {
+		rtl8169_rx_hwaccel_skb(skb, tp->vlgrp,
+				       swab16(opts2 & 0xffff));
+		ret = 0;
+	} else
+		ret = -1;
+	desc->opts2 = 0;
+	return ret;
+}
+
+#else /* !CONFIG_R8169_VLAN */
+
+static inline u32 rtl8169_tx_vlan_tag(struct rtl8169_private *tp,
+				      struct sk_buff *skb)
+{
+	return 0;
+}
+
+static int rtl8169_rx_vlan_skb(struct rtl8169_private *tp, struct RxDesc *desc,
+			       struct sk_buff *skb)
+{
+	return -1;
+}
+
+#endif
+
 static void rtl8169_gset_tbi(struct net_device *dev, struct ethtool_cmd *cmd)
 {
 	struct rtl8169_private *tp = netdev_priv(dev);
-	void *ioaddr = tp->mmio_addr;
+	void __iomem *ioaddr = tp->mmio_addr;
 	u32 status;
 
 	cmd->supported =
@@ -624,7 +806,7 @@
 static void rtl8169_gset_xmii(struct net_device *dev, struct ethtool_cmd *cmd)
 {
 	struct rtl8169_private *tp = netdev_priv(dev);
-	void *ioaddr = tp->mmio_addr;
+	void __iomem *ioaddr = tp->mmio_addr;
 	u8 status;
 
 	cmd->supported = SUPPORTED_10baseT_Half |
@@ -675,15 +857,38 @@
 	return 0;
 }
 
+static void rtl8169_get_regs(struct net_device *dev, struct ethtool_regs *regs,
+			     void *p)
+{
+        struct rtl8169_private *tp = netdev_priv(dev);
+        unsigned long flags;
+
+        if (regs->len > R8169_REGS_SIZE)
+        	regs->len = R8169_REGS_SIZE;
+
+        spin_lock_irqsave(&tp->lock, flags);
+        memcpy_fromio(p, tp->mmio_addr, regs->len);
+        spin_unlock_irqrestore(&tp->lock, flags);
+}
 
 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_rx_csum		= rtl8169_get_rx_csum,
+	.set_rx_csum		= rtl8169_set_rx_csum,
+	.get_tx_csum		= ethtool_op_get_tx_csum,
+	.set_tx_csum		= ethtool_op_set_tx_csum,
+	.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		= rtl8169_get_regs,
 };
 
-static void rtl8169_write_gmii_reg_bit(void *ioaddr, int reg, int bitnum,
+static void rtl8169_write_gmii_reg_bit(void __iomem *ioaddr, int reg, int bitnum,
 				       int bitval)
 {
 	int val;
@@ -694,12 +899,13 @@
 	mdio_write(ioaddr, reg, val & 0xffff); 
 }
 
-static void rtl8169_get_mac_version(struct rtl8169_private *tp, void *ioaddr)
+static void rtl8169_get_mac_version(struct rtl8169_private *tp, void __iomem *ioaddr)
 {
 	const struct {
 		u32 mask;
 		int mac_version;
 	} mac_info[] = {
+		{ 0x1 << 28,	RTL_GIGA_MAC_VER_X },
 		{ 0x1 << 26,	RTL_GIGA_MAC_VER_E },
 		{ 0x1 << 23,	RTL_GIGA_MAC_VER_D }, 
 		{ 0x00000000,	RTL_GIGA_MAC_VER_B } /* Catch-all */
@@ -734,7 +940,7 @@
 	dprintk("mac_version == Unknown\n");
 }
 
-static void rtl8169_get_phy_version(struct rtl8169_private *tp, void *ioaddr)
+static void rtl8169_get_phy_version(struct rtl8169_private *tp, void __iomem *ioaddr)
 {
 	const struct {
 		u16 mask;
@@ -780,7 +986,7 @@
 static void rtl8169_hw_phy_config(struct net_device *dev)
 {
 	struct rtl8169_private *tp = netdev_priv(dev);
-	void *ioaddr = tp->mmio_addr;
+	void __iomem *ioaddr = tp->mmio_addr;
 	struct {
 		u16 regs[5]; /* Beware of bit-sign propagation */
 	} phy_magic[5] = { {
@@ -818,7 +1024,7 @@
 
 	if (tp->mac_version <= RTL_GIGA_MAC_VER_B)
 		return;
-	if (tp->phy_version >= RTL_GIGA_PHY_VER_F) 
+	if (tp->phy_version >= RTL_GIGA_PHY_VER_H)
 		return;
 
 	dprintk("MAC version != 0 && PHY version == 0 or 1\n");
@@ -826,7 +1032,19 @@
 
 	/* Shazam ! */
 
-	// phy config for RTL8169s mac_version C chip
+	if (tp->mac_version == RTL_GIGA_MAC_VER_X) {
+		mdio_write(ioaddr, 31, 0x0001);
+		mdio_write(ioaddr,  9, 0x273a);
+		mdio_write(ioaddr, 14, 0x7bfb);
+		mdio_write(ioaddr, 27, 0x841e);
+
+		mdio_write(ioaddr, 31, 0x0002);
+		mdio_write(ioaddr,  1, 0x90d0);
+		mdio_write(ioaddr, 31, 0x0000);
+		return;
+	}
+
+	/* phy config for RTL8169s mac_version C chip */
 	mdio_write(ioaddr, 31, 0x0001);			//w 31 2 0 1
 	mdio_write(ioaddr, 21, 0x1000);			//w 21 15 0 1000
 	mdio_write(ioaddr, 24, 0x65c7);			//w 24 15 0 65c7
@@ -850,11 +1068,11 @@
 	struct net_device *dev = (struct net_device *)__opaque;
 	struct rtl8169_private *tp = netdev_priv(dev);
 	struct timer_list *timer = &tp->timer;
-	void *ioaddr = tp->mmio_addr;
+	void __iomem *ioaddr = tp->mmio_addr;
 	unsigned long timeout = RTL8169_PHY_TIMEOUT;
 
 	assert(tp->mac_version > RTL_GIGA_MAC_VER_B);
-	assert(tp->phy_version < RTL_GIGA_PHY_VER_G);
+	assert(tp->phy_version < RTL_GIGA_PHY_VER_H);
 
 	if (!(tp->phy_1000_ctrl_reg & PHY_Cap_1000_Full))
 		return;
@@ -889,7 +1107,7 @@
 	struct timer_list *timer = &tp->timer;
 
 	if ((tp->mac_version <= RTL_GIGA_MAC_VER_B) ||
-	    (tp->phy_version >= RTL_GIGA_PHY_VER_G))
+	    (tp->phy_version >= RTL_GIGA_PHY_VER_H))
 		return;
 
 	del_timer_sync(timer);
@@ -901,7 +1119,7 @@
 	struct timer_list *timer = &tp->timer;
 
 	if ((tp->mac_version <= RTL_GIGA_MAC_VER_B) ||
-	    (tp->phy_version >= RTL_GIGA_PHY_VER_G))
+	    (tp->phy_version >= RTL_GIGA_PHY_VER_H))
 		return;
 
 	init_timer(timer);
@@ -911,41 +1129,65 @@
 	add_timer(timer);
 }
 
+#ifdef CONFIG_NET_POLL_CONTROLLER
+/*
+ * Polling 'interrupt' - used by things like netconsole to send skbs
+ * without having to re-enable interrupts. It's not called while
+ * the interrupt routine is executing.
+ */
+static void rtl8169_netpoll(struct net_device *dev)
+{
+	struct rtl8169_private *tp = netdev_priv(dev);
+	struct pci_dev *pdev = tp->pci_dev;
+
+	disable_irq(pdev->irq);
+	rtl8169_interrupt(pdev->irq, dev, NULL);
+	enable_irq(pdev->irq);
+}
+#endif
+
+static void rtl8169_release_board(struct pci_dev *pdev, struct net_device *dev,
+				  void __iomem *ioaddr)
+{
+	iounmap(ioaddr);
+	pci_release_regions(pdev);
+	pci_disable_device(pdev);
+	free_netdev(dev);
+}
+
 static int __devinit
 rtl8169_init_board(struct pci_dev *pdev, struct net_device **dev_out,
-		   void **ioaddr_out)
+		   void __iomem **ioaddr_out)
 {
-	void *ioaddr = NULL;
+	void __iomem *ioaddr;
 	struct net_device *dev;
 	struct rtl8169_private *tp;
-	unsigned long mmio_start, mmio_end, mmio_flags, mmio_len;
-	int rc, i, acpi_idle_state = 0, pm_cap;
-
+	int rc = -ENOMEM, i, acpi_idle_state = 0, pm_cap;
 
-	assert(pdev != NULL);
 	assert(ioaddr_out != NULL);
 
-	*ioaddr_out = NULL;
-	*dev_out = NULL;
-
-	// dev zeroed in alloc_etherdev 
+	/* dev zeroed in alloc_etherdev */
 	dev = alloc_etherdev(sizeof (*tp));
 	if (dev == NULL) {
 		printk(KERN_ERR PFX "unable to alloc new ethernet\n");
-		return -ENOMEM;
+		goto err_out;
 	}
 
 	SET_MODULE_OWNER(dev);
 	SET_NETDEV_DEV(dev, &pdev->dev);
-	tp = dev->priv;
+	tp = netdev_priv(dev);
 
-	// enable device (incl. PCI PM wakeup and hotplug setup)
+	/* enable device (incl. PCI PM wakeup and hotplug setup) */
 	rc = pci_enable_device(pdev);
 	if (rc) {
 		printk(KERN_ERR PFX "%s: enable failure\n", pdev->slot_name);
-		goto err_out;
+		goto err_out_free_dev;
 	}
 
+	rc = pci_set_mwi(pdev);
+	if (rc < 0)
+		goto err_out_disable;
+
 	/* save power state before pci_enable_device overwrites it */
 	pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM);
 	if (pm_cap) {
@@ -956,41 +1198,37 @@
 	} else {
 		printk(KERN_ERR PFX
 		       "Cannot find PowerManagement capability, aborting.\n");
-		goto err_out_free_res;
+		goto err_out_mwi;
 	}
 
-	mmio_start = pci_resource_start(pdev, 1);
-	mmio_end = pci_resource_end(pdev, 1);
-	mmio_flags = pci_resource_flags(pdev, 1);
-	mmio_len = pci_resource_len(pdev, 1);
-
-	// make sure PCI base addr 1 is MMIO
-	if (!(mmio_flags & IORESOURCE_MEM)) {
+	/* 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");
 		rc = -ENODEV;
-		goto err_out_disable;
+		goto err_out_mwi;
 	}
-	// check for weird/broken PCI region reporting
-	if (mmio_len < RTL_MIN_IO_SIZE) {
+	/* 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");
 		rc = -ENODEV;
-		goto err_out_disable;
+		goto err_out_mwi;
 	}
 
 	rc = pci_request_regions(pdev, MODULENAME);
 	if (rc) {
 		printk(KERN_ERR PFX "%s: could not request regions.\n",
 		       pdev->slot_name);
-		goto err_out_disable;
+		goto err_out_mwi;
 	}
 
 	tp->cp_cmd = PCIMulRW | RxChkSum;
 
 	if ((sizeof(dma_addr_t) > 4) &&
-	    !pci_set_dma_mask(pdev, DMA_64BIT_MASK) && use_dac)
+	    !pci_set_dma_mask(pdev, DMA_64BIT_MASK) && use_dac) {
 		tp->cp_cmd |= PCIDAC;
-	else {
+		dev->features |= NETIF_F_HIGHDMA;
+	} else {
 		rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
 		if (rc < 0) {
 			printk(KERN_ERR PFX "DMA configuration failed.\n");
@@ -998,29 +1236,30 @@
 		}
 	}
 
-
-	// enable PCI bus-mastering
 	pci_set_master(pdev);
 
-	// ioremap MMIO region 
-	ioaddr = ioremap(mmio_start, mmio_len);
+	/* 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");
 		rc = -EIO;
 		goto err_out_free_res;
 	}
 
-	// Soft reset the chip. 
+	/* Unneeded ? Don't mess with Mrs. Murphy. */
+	rtl8169_irq_mask_and_ack(ioaddr);
+
+	/* Soft reset the chip. */
 	RTL_W8(ChipCmd, CmdReset);
 
-	// Check that the chip has finished the reset.
+	/* Check that the chip has finished the reset. */
 	for (i = 1000; i > 0; i--) {
 		if ((RTL_R8(ChipCmd) & CmdReset) == 0)
 			break;
 		udelay(10);
 	}
 
-	// Identify chip attached to board
+	/* Identify chip attached to board */
 	rtl8169_get_mac_version(tp, ioaddr);
 	rtl8169_get_phy_version(tp, ioaddr);
 
@@ -1042,25 +1281,32 @@
 
 	*ioaddr_out = ioaddr;
 	*dev_out = dev;
-	return 0;
+out:
+	return rc;
 
 err_out_free_res:
 	pci_release_regions(pdev);
 
+err_out_mwi:
+	pci_clear_mwi(pdev);
+
 err_out_disable:
 	pci_disable_device(pdev);
 
-err_out:
+err_out_free_dev:
 	free_netdev(dev);
-	return rc;
+err_out:
+	*ioaddr_out = NULL;
+	*dev_out = NULL;
+	goto out;
 }
 
 static int __devinit
 rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
 	struct net_device *dev = NULL;
-	struct rtl8169_private *tp = NULL;
-	void *ioaddr = NULL;
+	struct rtl8169_private *tp;
+	void __iomem *ioaddr = NULL;
 	static int board_idx = -1;
 	static int printed_version = 0;
 	u8 autoneg, duplex;
@@ -1073,7 +1319,8 @@
 	board_idx++;
 
 	if (!printed_version) {
-		printk(KERN_INFO RTL8169_DRIVER_NAME " loaded\n");
+		printk(KERN_INFO "%s Gigabit Ethernet driver %s loaded\n",
+		       MODULENAME, RTL8169_VERSION);
 		printed_version = 1;
 	}
 
@@ -1081,10 +1328,8 @@
 	if (rc)
 		return rc;
 
-	tp = dev->priv;
+	tp = netdev_priv(dev);
 	assert(ioaddr != NULL);
-	assert(dev != NULL);
-	assert(tp != NULL);
 
 	if (RTL_R8(PHYstatus) & TBI_Enable) {
 		tp->set_speed = rtl8169_set_speed_tbi;
@@ -1102,25 +1347,38 @@
 		tp->link_ok = rtl8169_xmii_link_ok;
 	}
 
-	// Get MAC address.  FIXME: read EEPROM
+	/* Get MAC address.  FIXME: read EEPROM */
 	for (i = 0; i < MAC_ADDR_LEN; i++)
 		dev->dev_addr[i] = RTL_R8(MAC0 + i);
 
 	dev->open = rtl8169_open;
 	dev->hard_start_xmit = rtl8169_start_xmit;
 	dev->get_stats = rtl8169_get_stats;
-	dev->ethtool_ops = &rtl8169_ethtool_ops;
+	SET_ETHTOOL_OPS(dev, &rtl8169_ethtool_ops);
 	dev->stop = rtl8169_close;
 	dev->tx_timeout = rtl8169_tx_timeout;
 	dev->set_multicast_list = rtl8169_set_rx_mode;
 	dev->watchdog_timeo = RTL8169_TX_TIMEOUT;
 	dev->irq = pdev->irq;
 	dev->base_addr = (unsigned long) ioaddr;
+	dev->change_mtu = rtl8169_change_mtu;
+
 #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
+	dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
+	dev->vlan_rx_register = rtl8169_vlan_rx_register;
+	dev->vlan_rx_kill_vid = rtl8169_vlan_rx_kill_vid;
+#endif
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	dev->poll_controller = rtl8169_netpoll;
+#endif
+
 	tp->intr_mask = 0xffff;
 	tp->pci_dev = pdev;
 	tp->mmio_addr = ioaddr;
@@ -1129,10 +1387,7 @@
 
 	rc = register_netdev(dev);
 	if (rc) {
-		iounmap(ioaddr);
-		pci_release_regions(pdev);
-		pci_disable_device(pdev);
-		free_netdev(dev);
+		rtl8169_release_board(pdev, dev, ioaddr);
 		return rc;
 	}
 
@@ -1188,11 +1443,7 @@
 	assert(tp != NULL);
 
 	unregister_netdev(dev);
-	iounmap(tp->mmio_addr);
-	pci_release_regions(pdev);
-
-	pci_disable_device(pdev);
-	free_netdev(dev);
+	rtl8169_release_board(pdev, dev, tp->mmio_addr);
 	pci_set_drvdata(pdev, NULL);
 }
 
@@ -1202,7 +1453,7 @@
 {
 	struct net_device *dev = pci_get_drvdata(pdev);
 	struct rtl8169_private *tp = netdev_priv(dev);
-	void *ioaddr = tp->mmio_addr;
+	void __iomem *ioaddr = tp->mmio_addr;
 	unsigned long flags;
 
 	if (!netif_running(dev))
@@ -1239,13 +1490,22 @@
                                                                                 
 #endif /* CONFIG_PM */
 
-static int
-rtl8169_open(struct net_device *dev)
+static void rtl8169_set_rxbufsize(struct rtl8169_private *tp,
+				  struct net_device *dev)
+{
+	unsigned int mtu = dev->mtu;
+
+	tp->rx_buf_sz = (mtu > RX_BUF_SIZE) ? mtu + ETH_HLEN + 8 : RX_BUF_SIZE;
+}
+
+static int rtl8169_open(struct net_device *dev)
 {
 	struct rtl8169_private *tp = netdev_priv(dev);
 	struct pci_dev *pdev = tp->pci_dev;
 	int retval;
 
+	rtl8169_set_rxbufsize(tp, dev);
+
 	retval =
 	    request_irq(dev->irq, rtl8169_interrupt, SA_SHIRQ, dev->name, dev);
 	if (retval < 0)
@@ -1271,6 +1531,8 @@
 	if (retval < 0)
 		goto err_free_rx;
 
+	INIT_WORK(&tp->task, NULL, dev);
+
 	rtl8169_hw_start(dev);
 
 	rtl8169_request_timer(dev);
@@ -1290,11 +1552,23 @@
 	goto out;
 }
 
+static void rtl8169_hw_reset(void __iomem *ioaddr)
+{
+	/* Disable interrupts */
+	rtl8169_irq_mask_and_ack(ioaddr);
+
+	/* Reset the chipset */
+	RTL_W8(ChipCmd, CmdReset);
+
+	/* PCI commit */
+	RTL_R8(ChipCmd);
+}
+
 static void
 rtl8169_hw_start(struct net_device *dev)
 {
 	struct rtl8169_private *tp = netdev_priv(dev);
-	void *ioaddr = tp->mmio_addr;
+	void __iomem *ioaddr = tp->mmio_addr;
 	u32 i;
 
 	/* Soft reset the chip. */
@@ -1311,10 +1585,10 @@
 	RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
 	RTL_W8(EarlyTxThres, EarlyTxThld);
 
-	// For gigabit rtl8169
-	RTL_W16(RxMaxSize, RxPacketMaxSize);
+	/* For gigabit rtl8169, MTU + header + CRC + VLAN */
+	RTL_W16(RxMaxSize, tp->rx_buf_sz);
 
-	// Set Rx Config register
+	/* Set Rx Config register */
 	i = rtl8169_rx_config |
 		(RTL_R32(RxConfig) & rtl_chip_info[tp->chipset].RxConfigMask);
 	RTL_W32(RxConfig, i);
@@ -1326,14 +1600,19 @@
 	tp->cp_cmd |= RTL_R16(CPlusCmd);
 	RTL_W16(CPlusCmd, tp->cp_cmd);
 
-	if (tp->mac_version == RTL_GIGA_MAC_VER_D) {
+	if ((tp->mac_version == RTL_GIGA_MAC_VER_D) ||
+	    (tp->mac_version == RTL_GIGA_MAC_VER_E)) {
 		dprintk(KERN_INFO PFX "Set MAC Reg C+CR Offset 0xE0. "
 			"Bit-3 and bit-14 MUST be 1\n");
 		tp->cp_cmd |= (1 << 14) | PCIMulRW;
 		RTL_W16(CPlusCmd, tp->cp_cmd);
 	}
 
-	tp->cur_rx = 0;
+	/*
+	 * Undocumented corner. Supposedly:
+	 * (TxTimer << 12) | (TxPackets << 8) | (RxTimer << 4) | RxPackets
+	 */
+	RTL_W16(IntrMitigate, 0x0000);
 
 	RTL_W32(TxDescStartAddrLow, ((u64) tp->TxPhyAddr & DMA_32BIT_MASK));
 	RTL_W32(TxDescStartAddrHigh, ((u64) tp->TxPhyAddr >> 32));
@@ -1355,52 +1634,85 @@
 	netif_start_queue(dev);
 }
 
+static int rtl8169_change_mtu(struct net_device *dev, int new_mtu)
+{
+	struct rtl8169_private *tp = netdev_priv(dev);
+	int ret = 0;
+
+	if (new_mtu < ETH_ZLEN || new_mtu > SafeMtu)
+		return -EINVAL;
+
+	dev->mtu = new_mtu;
+
+	if (!netif_running(dev))
+		goto out;
+
+	rtl8169_down(dev);
+
+	rtl8169_set_rxbufsize(tp, dev);
+
+	ret = rtl8169_init_ring(dev);
+	if (ret < 0)
+		goto out;
+
+	netif_poll_enable(dev);
+
+	rtl8169_hw_start(dev);
+
+	rtl8169_request_timer(dev);
+
+out:
+	return ret;
+}
+
 static inline void rtl8169_make_unusable_by_asic(struct RxDesc *desc)
 {
 	desc->addr = 0x0badbadbadbadbadull;
-	desc->status &= ~cpu_to_le32(OWNbit | RsvdMask);
+	desc->opts1 &= ~cpu_to_le32(DescOwn | RsvdMask);
 }
 
-static void rtl8169_free_rx_skb(struct pci_dev *pdev, struct sk_buff **sk_buff,
-				struct RxDesc *desc)
+static void rtl8169_free_rx_skb(struct rtl8169_private *tp,
+				struct sk_buff **sk_buff, struct RxDesc *desc)
 {
-	pci_unmap_single(pdev, le64_to_cpu(desc->addr), RX_BUF_SIZE,
+	struct pci_dev *pdev = tp->pci_dev;
+
+	pci_unmap_single(pdev, le64_to_cpu(desc->addr), tp->rx_buf_sz,
 			 PCI_DMA_FROMDEVICE);
 	dev_kfree_skb(*sk_buff);
 	*sk_buff = NULL;
 	rtl8169_make_unusable_by_asic(desc);
 }
 
-static inline void rtl8169_return_to_asic(struct RxDesc *desc)
+static inline void rtl8169_return_to_asic(struct RxDesc *desc, int rx_buf_sz)
 {
-	desc->status |= cpu_to_le32(OWNbit + RX_BUF_SIZE);
+	desc->opts1 |= cpu_to_le32(DescOwn + rx_buf_sz);
 }
 
-static inline void rtl8169_give_to_asic(struct RxDesc *desc, dma_addr_t mapping)
+static inline void rtl8169_give_to_asic(struct RxDesc *desc, dma_addr_t mapping,
+					int rx_buf_sz)
 {
 	desc->addr = cpu_to_le64(mapping);
-	desc->status |= cpu_to_le32(OWNbit + RX_BUF_SIZE);
+	desc->opts1 |= cpu_to_le32(DescOwn + rx_buf_sz);
 }
 
-static int rtl8169_alloc_rx_skb(struct pci_dev *pdev, struct net_device *dev,
-				struct sk_buff **sk_buff, struct RxDesc *desc)
+static int rtl8169_alloc_rx_skb(struct pci_dev *pdev, struct sk_buff **sk_buff,
+				struct RxDesc *desc, int rx_buf_sz)
 {
 	struct sk_buff *skb;
 	dma_addr_t mapping;
 	int ret = 0;
 
-	skb = dev_alloc_skb(RX_BUF_SIZE);
+	skb = dev_alloc_skb(rx_buf_sz + NET_IP_ALIGN);
 	if (!skb)
 		goto err_out;
 
-	skb->dev = dev;
-	skb_reserve(skb, 2);
+	skb_reserve(skb, NET_IP_ALIGN);
 	*sk_buff = skb;
 
-	mapping = pci_map_single(pdev, skb->tail, RX_BUF_SIZE,
+	mapping = pci_map_single(pdev, skb->tail, rx_buf_sz,
 				 PCI_DMA_FROMDEVICE);
 
-	rtl8169_give_to_asic(desc, mapping);
+	rtl8169_give_to_asic(desc, mapping, rx_buf_sz);
 
 out:
 	return ret;
@@ -1417,7 +1729,7 @@
 
 	for (i = 0; i < NUM_RX_DESC; i++) {
 		if (tp->Rx_skbuff[i]) {
-			rtl8169_free_rx_skb(tp->pci_dev, tp->Rx_skbuff + i,
+			rtl8169_free_rx_skb(tp, tp->Rx_skbuff + i,
 					    tp->RxDescArray + i);
 		}
 	}
@@ -1434,8 +1746,8 @@
 		if (tp->Rx_skbuff[i])
 			continue;
 			
-		ret = rtl8169_alloc_rx_skb(tp->pci_dev, dev, tp->Rx_skbuff + i,
-					   tp->RxDescArray + i);
+		ret = rtl8169_alloc_rx_skb(tp->pci_dev, tp->Rx_skbuff + i,
+					   tp->RxDescArray + i, tp->rx_buf_sz);
 		if (ret < 0)
 			break;
 	}
@@ -1444,19 +1756,21 @@
 
 static inline void rtl8169_mark_as_last_descriptor(struct RxDesc *desc)
 {
-	desc->status |= cpu_to_le32(EORbit);
+	desc->opts1 |= cpu_to_le32(RingEnd);
+}
+
+static void rtl8169_init_ring_indexes(struct rtl8169_private *tp)
+{
+	tp->dirty_tx = tp->dirty_rx = tp->cur_tx = tp->cur_rx = 0;
 }
 
 static int rtl8169_init_ring(struct net_device *dev)
 {
 	struct rtl8169_private *tp = netdev_priv(dev);
 
-	tp->cur_rx = tp->dirty_rx = 0;
-	tp->cur_tx = tp->dirty_tx = 0;
-	memset(tp->TxDescArray, 0x0, NUM_TX_DESC * sizeof (struct TxDesc));
-	memset(tp->RxDescArray, 0x0, NUM_RX_DESC * sizeof (struct RxDesc));
+	rtl8169_init_ring_indexes(tp);
 
-	memset(tp->Tx_skbuff, 0x0, NUM_TX_DESC * sizeof(struct sk_buff *));
+	memset(tp->tx_skb, 0x0, NUM_TX_DESC * sizeof(struct ring_info));
 	memset(tp->Rx_skbuff, 0x0, NUM_RX_DESC * sizeof(struct sk_buff *));
 
 	if (rtl8169_rx_fill(tp, dev, 0, NUM_RX_DESC) != NUM_RX_DESC)
@@ -1471,123 +1785,300 @@
 	return -ENOMEM;
 }
 
-static void rtl8169_unmap_tx_skb(struct pci_dev *pdev, struct sk_buff **sk_buff,
+static void rtl8169_unmap_tx_skb(struct pci_dev *pdev, struct ring_info *tx_skb,
 				 struct TxDesc *desc)
 {
-	u32 len = sk_buff[0]->len;
+	unsigned int len = tx_skb->len;
 
-	pci_unmap_single(pdev, le64_to_cpu(desc->addr),
-			 len < ETH_ZLEN ? ETH_ZLEN : len, PCI_DMA_TODEVICE);
+	pci_unmap_single(pdev, le64_to_cpu(desc->addr), len, PCI_DMA_TODEVICE);
+	desc->opts1 = 0x00;
+	desc->opts2 = 0x00;
 	desc->addr = 0x00;
-	*sk_buff = NULL;
+	tx_skb->len = 0;
 }
 
-static void
-rtl8169_tx_clear(struct rtl8169_private *tp)
+static void rtl8169_tx_clear(struct rtl8169_private *tp)
 {
-	int i;
+	unsigned int i;
 
-	tp->cur_tx = 0;
-	for (i = 0; i < NUM_TX_DESC; i++) {
-		struct sk_buff *skb = tp->Tx_skbuff[i];
+	for (i = tp->dirty_tx; i < tp->dirty_tx + NUM_TX_DESC; i++) {
+		unsigned int entry = i % NUM_TX_DESC;
+		struct ring_info *tx_skb = tp->tx_skb + entry;
+		unsigned int len = tx_skb->len;
 
-		if (skb) {
-			rtl8169_unmap_tx_skb(tp->pci_dev, tp->Tx_skbuff + i,
-					     tp->TxDescArray + i);
-			dev_kfree_skb(skb);
+		if (len) {
+			struct sk_buff *skb = tx_skb->skb;
+
+			rtl8169_unmap_tx_skb(tp->pci_dev, tx_skb,
+					     tp->TxDescArray + entry);
+			if (skb) {
+				dev_kfree_skb(skb);
+				tx_skb->skb = NULL;
+			}
 			tp->stats.tx_dropped++;
 		}
 	}
+	tp->cur_tx = tp->dirty_tx = 0;
 }
 
-static void
-rtl8169_tx_timeout(struct net_device *dev)
+static void rtl8169_schedule_work(struct net_device *dev, void (*task)(void *))
 {
 	struct rtl8169_private *tp = netdev_priv(dev);
-	void *ioaddr = tp->mmio_addr;
-	u8 tmp8;
 
-	printk(KERN_INFO "%s: TX Timeout\n", dev->name);
-	/* disable Tx, if not already */
-	tmp8 = RTL_R8(ChipCmd);
-	if (tmp8 & CmdTxEnb)
-		RTL_W8(ChipCmd, tmp8 & ~CmdTxEnb);
+	PREPARE_WORK(&tp->task, task, dev);
+	schedule_delayed_work(&tp->task, 4);
+}
 
-	/* Disable interrupts by clearing the interrupt mask. */
-	RTL_W16(IntrMask, 0x0000);
+static void rtl8169_wait_for_quiescence(struct net_device *dev)
+{
+	struct rtl8169_private *tp = netdev_priv(dev);
+	void __iomem *ioaddr = tp->mmio_addr;
 
-	/* Stop a shared interrupt from scavenging while we are. */
-	spin_lock_irq(&tp->lock);
-	rtl8169_tx_clear(tp);
-	spin_unlock_irq(&tp->lock);
+	synchronize_irq(dev->irq);
 
-	/* ...and finally, reset everything */
-	rtl8169_hw_start(dev);
+	/* Wait for any pending NAPI task to complete */
+	netif_poll_disable(dev);
+
+	rtl8169_irq_mask_and_ack(ioaddr);
 
-	netif_wake_queue(dev);
+	netif_poll_enable(dev);
 }
 
-static int
-rtl8169_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static void rtl8169_reinit_task(void *_data)
+{
+	struct net_device *dev = _data;
+	int ret;
+
+	if (netif_running(dev)) {
+		rtl8169_wait_for_quiescence(dev);
+		rtl8169_close(dev);
+	}
+
+	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);
+		}
+		rtl8169_schedule_work(dev, rtl8169_reinit_task);
+	}
+}
+
+static void rtl8169_reset_task(void *_data)
 {
+	struct net_device *dev = _data;
 	struct rtl8169_private *tp = netdev_priv(dev);
-	void *ioaddr = tp->mmio_addr;
-	unsigned int entry = tp->cur_tx % NUM_TX_DESC;
-	u32 len = skb->len;
-
-	if (unlikely(skb->len < ETH_ZLEN)) {
-		skb = skb_padto(skb, ETH_ZLEN);
-		if (!skb)
-			goto err_update_stats;
-		len = ETH_ZLEN;
+
+	if (!netif_running(dev))
+		return;
+
+	rtl8169_wait_for_quiescence(dev);
+
+	rtl8169_rx_interrupt(dev, tp, tp->mmio_addr);
+	rtl8169_tx_clear(tp);
+
+	if (tp->dirty_rx == tp->cur_rx) {
+		rtl8169_init_ring_indexes(tp);
+		rtl8169_hw_start(dev);
+		netif_wake_queue(dev);
+	} else {
+		if (net_ratelimit()) {
+			printk(PFX KERN_EMERG "%s: Rx buffers shortage\n",
+			       dev->name);
+		}
+		rtl8169_schedule_work(dev, rtl8169_reset_task);
 	}
-	
-	if (!(le32_to_cpu(tp->TxDescArray[entry].status) & OWNbit)) {
+}
+
+static void rtl8169_tx_timeout(struct net_device *dev)
+{
+	struct rtl8169_private *tp = netdev_priv(dev);
+
+	rtl8169_hw_reset(tp->mmio_addr);
+
+	/* Let's wait a bit while any (async) irq lands on */
+	rtl8169_schedule_work(dev, rtl8169_reset_task);
+}
+
+static int rtl8169_xmit_frags(struct rtl8169_private *tp, struct sk_buff *skb,
+			      u32 opts1)
+{
+	struct skb_shared_info *info = skb_shinfo(skb);
+	unsigned int cur_frag, entry;
+	struct TxDesc *txd;
+
+	entry = tp->cur_tx;
+	for (cur_frag = 0; cur_frag < info->nr_frags; cur_frag++) {
+		skb_frag_t *frag = info->frags + cur_frag;
 		dma_addr_t mapping;
-		u32 status;
+		u32 status, len;
+		void *addr;
 
-		mapping = pci_map_single(tp->pci_dev, skb->data, len,
-					 PCI_DMA_TODEVICE);
+		entry = (entry + 1) % NUM_TX_DESC;
 
-		tp->Tx_skbuff[entry] = skb;
-		tp->TxDescArray[entry].addr = cpu_to_le64(mapping);
+		txd = tp->TxDescArray + entry;
+		len = frag->size;
+		addr = ((void *) page_address(frag->page)) + frag->page_offset;
+		mapping = pci_map_single(tp->pci_dev, addr, len, PCI_DMA_TODEVICE);
 
-		/* anti gcc 2.95.3 bugware */
-		status = OWNbit | FSbit | LSbit | len |
-			 (EORbit * !((entry + 1) % NUM_TX_DESC));
-		tp->TxDescArray[entry].status = cpu_to_le32(status);
-			
-		RTL_W8(TxPoll, 0x40);	//set polling bit
+		/* anti gcc 2.95.3 bugware (sic) */
+		status = opts1 | len | (RingEnd * !((entry + 1) % NUM_TX_DESC));
 
-		dev->trans_start = jiffies;
+		txd->opts1 = cpu_to_le32(status);
+		txd->addr = cpu_to_le64(mapping);
 
-		tp->cur_tx++;
-		smp_wmb();
-	} else
-		goto err_drop;
+		tp->tx_skb[entry].len = len;
+	}
+
+	if (cur_frag) {
+		tp->tx_skb[entry].skb = skb;
+		txd->opts1 |= cpu_to_le32(LastFrag);
+	}
+
+	return cur_frag;
+}
+
+static inline u32 rtl8169_tso_csum(struct sk_buff *skb, struct net_device *dev)
+{
+	if (dev->features & NETIF_F_TSO) {
+		u32 mss = skb_shinfo(skb)->tso_size;
+
+		if (mss)
+			return LargeSend | ((mss & MSSMask) << MSSShift);
+	}
+	if (skb->ip_summed == CHECKSUM_HW) {
+		const struct iphdr *ip = skb->nh.iph;
+
+		if (ip->protocol == IPPROTO_TCP)
+			return IPCS | TCPCS;
+		else if (ip->protocol == IPPROTO_UDP)
+			return IPCS | UDPCS;
+		WARN_ON(1);	/* we need a WARN() */
+	}
+	return 0;
+}
 
-	if ((tp->cur_tx - NUM_TX_DESC) == tp->dirty_tx) {
-		u32 dirty = tp->dirty_tx;
+static int rtl8169_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	struct rtl8169_private *tp = netdev_priv(dev);
+	unsigned int frags, entry = tp->cur_tx % NUM_TX_DESC;
+	struct TxDesc *txd = tp->TxDescArray + entry;
+	void __iomem *ioaddr = tp->mmio_addr;
+	dma_addr_t mapping;
+	u32 status, len;
+	u32 opts1;
+	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);
+		goto err_stop;
+	}
+
+	if (unlikely(le32_to_cpu(txd->opts1) & DescOwn))
+		goto err_stop;
+
+	opts1 = DescOwn | rtl8169_tso_csum(skb, dev);
+
+	frags = rtl8169_xmit_frags(tp, skb, opts1);
+	if (frags) {
+		len = skb_headlen(skb);
+		opts1 |= FirstFrag;
+	} else {
+		len = skb->len;
+
+		if (unlikely(len < ETH_ZLEN)) {
+			skb = skb_padto(skb, ETH_ZLEN);
+			if (!skb)
+				goto err_update_stats;
+			len = ETH_ZLEN;
+		}
+
+		opts1 |= FirstFrag | LastFrag;
+		tp->tx_skb[entry].skb = skb;
+	}
+
+	mapping = pci_map_single(tp->pci_dev, skb->data, len, PCI_DMA_TODEVICE);
+
+	tp->tx_skb[entry].len = len;
+	txd->addr = cpu_to_le64(mapping);
+	txd->opts2 = cpu_to_le32(rtl8169_tx_vlan_tag(tp, skb));
+
+	wmb();
+
+	/* anti gcc 2.95.3 bugware (sic) */
+	status = opts1 | len | (RingEnd * !((entry + 1) % NUM_TX_DESC));
+	txd->opts1 = cpu_to_le32(status);
+
+	dev->trans_start = jiffies;
+
+	tp->cur_tx += frags + 1;
+
+	smp_wmb();
+
+	RTL_W8(TxPoll, 0x40);	/* set polling bit */
+
+	if (TX_BUFFS_AVAIL(tp) < MAX_SKB_FRAGS) {
 		netif_stop_queue(dev);
 		smp_rmb();
-		if (dirty != tp->dirty_tx)
+		if (TX_BUFFS_AVAIL(tp) >= MAX_SKB_FRAGS)
 			netif_wake_queue(dev);
 	}
 
 out:
-	return 0;
+	return ret;
 
-err_drop:
-	dev_kfree_skb(skb);
+err_stop:
+	netif_stop_queue(dev);
+	ret = 1;
 err_update_stats:
 	tp->stats.tx_dropped++;
 	goto out;
 }
 
+static void rtl8169_pcierr_interrupt(struct net_device *dev)
+{
+	struct rtl8169_private *tp = netdev_priv(dev);
+	struct pci_dev *pdev = tp->pci_dev;
+	void __iomem *ioaddr = tp->mmio_addr;
+	u16 pci_status, pci_cmd;
+
+	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);
+
+	/*
+	 * The recovery sequence below admits a very elaborated explanation:
+	 * - it seems to work;
+	 * - I did not see what else could be done.
+	 *
+	 * Feel free to adjust to your needs.
+	 */
+	pci_write_config_word(pdev, PCI_COMMAND,
+			      pci_cmd | PCI_COMMAND_SERR | PCI_COMMAND_PARITY);
+
+	pci_write_config_word(pdev, PCI_STATUS,
+		pci_status & (PCI_STATUS_DETECTED_PARITY |
+		PCI_STATUS_SIG_SYSTEM_ERROR | PCI_STATUS_REC_MASTER_ABORT |
+		PCI_STATUS_REC_TARGET_ABORT | PCI_STATUS_SIG_TARGET_ABORT));
+
+	/* 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);
+		tp->cp_cmd &= ~PCIDAC;
+		RTL_W16(CPlusCmd, tp->cp_cmd);
+		dev->features &= ~NETIF_F_HIGHDMA;
+		rtl8169_schedule_work(dev, rtl8169_reinit_task);
+	}
+
+	rtl8169_hw_reset(ioaddr);
+}
+
 static void
 rtl8169_tx_interrupt(struct net_device *dev, struct rtl8169_private *tp,
-		     void *ioaddr)
+		     void __iomem *ioaddr)
 {
 	unsigned int dirty_tx, tx_left;
 
@@ -1601,22 +2092,24 @@
 
 	while (tx_left > 0) {
 		unsigned int entry = dirty_tx % NUM_TX_DESC;
-		struct sk_buff *skb = tp->Tx_skbuff[entry];
+		struct ring_info *tx_skb = tp->tx_skb + entry;
+		u32 len = tx_skb->len;
 		u32 status;
 
 		rmb();
-		status = le32_to_cpu(tp->TxDescArray[entry].status);
-		if (status & OWNbit)
+		status = le32_to_cpu(tp->TxDescArray[entry].opts1);
+		if (status & DescOwn)
 			break;
 
-		/* FIXME: is it really accurate for TxErr ? */
-		tp->stats.tx_bytes += skb->len >= ETH_ZLEN ?
-				      skb->len : ETH_ZLEN;
+		tp->stats.tx_bytes += len;
 		tp->stats.tx_packets++;
-		rtl8169_unmap_tx_skb(tp->pci_dev, tp->Tx_skbuff + entry,
-				     tp->TxDescArray + entry);
-		dev_kfree_skb_irq(skb);
-		tp->Tx_skbuff[entry] = NULL;
+
+		rtl8169_unmap_tx_skb(tp->pci_dev, tx_skb, tp->TxDescArray + entry);
+
+		if (status & LastFrag) {
+			dev_kfree_skb_irq(tx_skb->skb);
+			tx_skb->skb = NULL;
+		}
 		dirty_tx++;
 		tx_left--;
 	}
@@ -1624,27 +2117,40 @@
 	if (tp->dirty_tx != dirty_tx) {
 		tp->dirty_tx = dirty_tx;
 		smp_wmb();
-		if (netif_queue_stopped(dev))
+		if (netif_queue_stopped(dev) &&
+		    (TX_BUFFS_AVAIL(tp) >= MAX_SKB_FRAGS)) {
 			netif_wake_queue(dev);
+		}
 	}
 }
 
+static inline void rtl8169_rx_csum(struct sk_buff *skb, struct RxDesc *desc)
+{
+	u32 opts1 = le32_to_cpu(desc->opts1);
+	u32 status = opts1 & RxProtoMask;
+
+	if (((status == RxProtoTCP) && !(opts1 & TCPFail)) ||
+	    ((status == RxProtoUDP) && !(opts1 & UDPFail)) ||
+	    ((status == RxProtoIP) && !(opts1 & IPFail)))
+		skb->ip_summed = CHECKSUM_UNNECESSARY;
+	else
+		skb->ip_summed = CHECKSUM_NONE;
+}
+
 static inline int rtl8169_try_rx_copy(struct sk_buff **sk_buff, int pkt_size,
-				      struct RxDesc *desc,
-				      struct net_device *dev)
+				      struct RxDesc *desc, int rx_buf_sz)
 {
 	int ret = -1;
 
 	if (pkt_size < rx_copybreak) {
 		struct sk_buff *skb;
 
-		skb = dev_alloc_skb(pkt_size + 2);
+		skb = dev_alloc_skb(pkt_size + NET_IP_ALIGN);
 		if (skb) {
-			skb->dev = dev;
-			skb_reserve(skb, 2);
+			skb_reserve(skb, NET_IP_ALIGN);
 			eth_copy_and_sum(skb, sk_buff[0]->tail, pkt_size, 0);
 			*sk_buff = skb;
-			rtl8169_return_to_asic(desc);
+			rtl8169_return_to_asic(desc, rx_buf_sz);
 			ret = 0;
 		}
 	}
@@ -1653,10 +2159,10 @@
 
 static int
 rtl8169_rx_interrupt(struct net_device *dev, struct rtl8169_private *tp,
-		     void *ioaddr)
+		     void __iomem *ioaddr)
 {
-	unsigned int cur_rx, rx_left, count;
-	int delta;
+	unsigned int cur_rx, rx_left;
+	unsigned int delta, count;
 
 	assert(dev != NULL);
 	assert(tp != NULL);
@@ -1671,9 +2177,9 @@
 		u32 status;
 
 		rmb();
-		status = le32_to_cpu(tp->RxDescArray[entry].status);
+		status = le32_to_cpu(tp->RxDescArray[entry].opts1);
 
-		if (status & OWNbit)
+		if (status & DescOwn)
 			break;
 		if (status & RxRES) {
 			printk(KERN_INFO "%s: Rx ERROR!!!\n", dev->name);
@@ -1689,22 +2195,27 @@
 			void (*pci_action)(struct pci_dev *, dma_addr_t,
 				size_t, int) = pci_dma_sync_single_for_device;
 
-
+			rtl8169_rx_csum(skb, desc);
+			
 			pci_dma_sync_single_for_cpu(tp->pci_dev,
-				le64_to_cpu(desc->addr), RX_BUF_SIZE,
+				le64_to_cpu(desc->addr), tp->rx_buf_sz,
 				PCI_DMA_FROMDEVICE);
 
-			if (rtl8169_try_rx_copy(&skb, pkt_size, desc, dev)) {
+			if (rtl8169_try_rx_copy(&skb, pkt_size, desc,
+						tp->rx_buf_sz)) {
 				pci_action = pci_unmap_single;
 				tp->Rx_skbuff[entry] = NULL;
 			}
 
 			pci_action(tp->pci_dev, le64_to_cpu(desc->addr),
-				   RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
+				   tp->rx_buf_sz, PCI_DMA_FROMDEVICE);
 
+			skb->dev = dev;
 			skb_put(skb, pkt_size);
 			skb->protocol = eth_type_trans(skb, dev);
-			rtl8169_rx_skb(skb);
+
+			if (rtl8169_rx_vlan_skb(tp, desc, skb) < 0)
+				rtl8169_rx_skb(skb);
 
 			dev->last_rx = jiffies;
 			tp->stats.rx_bytes += pkt_size;
@@ -1719,10 +2230,8 @@
 	tp->cur_rx = cur_rx;
 
 	delta = rtl8169_rx_fill(tp, dev, tp->dirty_rx, tp->cur_rx);
-	if (delta < 0) {
+	if (!delta && count)
 		printk(KERN_INFO "%s: no Rx buffer allocated\n", dev->name);
-		delta = 0;
-	}
 	tp->dirty_rx += delta;
 
 	/*
@@ -1745,8 +2254,8 @@
 	struct net_device *dev = (struct net_device *) dev_instance;
 	struct rtl8169_private *tp = netdev_priv(dev);
 	int boguscnt = max_interrupt_work;
-	void *ioaddr = tp->mmio_addr;
-	int status = 0;
+	void __iomem *ioaddr = tp->mmio_addr;
+	int status;
 	int handled = 0;
 
 	do {
@@ -1758,6 +2267,11 @@
 
 		handled = 1;
 
+		if (unlikely(!netif_running(dev))) {
+			rtl8169_asic_down(ioaddr);
+			goto out;
+		}
+
 		status &= tp->intr_mask;
 		RTL_W16(IntrStatus,
 			(status & RxFIFOOver) ? (status | RxOverflow) : status);
@@ -1766,11 +2280,7 @@
 			break;
 
 		if (unlikely(status & SYSErr)) {
-			printk(KERN_ERR PFX "%s: PCI error (status: 0x%04x)."
-			       " Device disabled.\n", dev->name, status);
-			RTL_W8(ChipCmd, 0x00);
-			RTL_W16(IntrMask, 0x0000);
-			RTL_R16(IntrMask);
+			rtl8169_pcierr_interrupt(dev);
 			break;
 		}
 
@@ -1784,16 +2294,16 @@
 		if (likely(netif_rx_schedule_prep(dev)))
 			__netif_rx_schedule(dev);
 		else {
-			printk(KERN_INFO "%s: interrupt %x taken in poll\n",
+			printk(KERN_INFO "%s: interrupt %04x taken in poll\n",
 			       dev->name, status);	
 		}
 		break;
 #else
-		// Rx interrupt 
+		/* Rx interrupt */
 		if (status & (RxOK | RxOverflow | RxFIFOOver)) {
 			rtl8169_rx_interrupt(dev, tp, ioaddr);
 		}
-		// Tx interrupt
+		/* Tx interrupt */
 		if (status & (TxOK | TxErr))
 			rtl8169_tx_interrupt(dev, tp, ioaddr);
 #endif
@@ -1807,6 +2317,7 @@
 		/* Clear all interrupt sources. */
 		RTL_W16(IntrStatus, 0xffff);
 	}
+out:
 	return IRQ_RETVAL(handled);
 }
 
@@ -1815,7 +2326,7 @@
 {
 	unsigned int work_done, work_to_do = min(*budget, dev->quota);
 	struct rtl8169_private *tp = netdev_priv(dev);
-	void *ioaddr = tp->mmio_addr;
+	void __iomem *ioaddr = tp->mmio_addr;
 
 	work_done = rtl8169_rx_interrupt(dev, tp, ioaddr);
 	rtl8169_tx_interrupt(dev, tp, ioaddr);
@@ -1823,7 +2334,7 @@
 	*budget -= work_done;
 	dev->quota -= work_done;
 
-	if ((work_done < work_to_do) || !netif_running(dev)) {
+	if (work_done < work_to_do) {
 		netif_rx_complete(dev);
 		tp->intr_mask = 0xffff;
 		/*
@@ -1840,24 +2351,22 @@
 }
 #endif
 
-static int
-rtl8169_close(struct net_device *dev)
+static void rtl8169_down(struct net_device *dev)
 {
 	struct rtl8169_private *tp = netdev_priv(dev);
-	struct pci_dev *pdev = tp->pci_dev;
-	void *ioaddr = tp->mmio_addr;
+	void __iomem *ioaddr = tp->mmio_addr;
+	unsigned int poll_locked = 0;
+
+	rtl8169_delete_timer(dev);
 
 	netif_stop_queue(dev);
 
-	rtl8169_delete_timer(dev);
+	flush_scheduled_work();
 
+core_down:
 	spin_lock_irq(&tp->lock);
 
-	/* Stop the chip's Tx and Rx DMA processes. */
-	RTL_W8(ChipCmd, 0x00);
-
-	/* Disable interrupts by clearing the interrupt mask. */
-	RTL_W16(IntrMask, 0x0000);
+	rtl8169_asic_down(ioaddr);
 
 	/* Update the error counts. */
 	tp->stats.rx_missed_errors += RTL_R32(RxMissed);
@@ -1866,11 +2375,44 @@
 	spin_unlock_irq(&tp->lock);
 
 	synchronize_irq(dev->irq);
-	free_irq(dev->irq, dev);
+
+	if (!poll_locked) {
+		netif_poll_disable(dev);
+		poll_locked++;
+	}
+
+	/* Give a racing hard_start_xmit a few cycles to complete. */
+	synchronize_kernel();
+
+	/*
+	 * And now for the 50k$ question: are IRQ disabled or not ?
+	 *
+	 * Two paths lead here:
+	 * 1) dev->close
+	 *    -> netif_running() is available to sync the current code and the
+	 *       IRQ handler. See rtl8169_interrupt for details.
+	 * 2) dev->change_mtu
+	 *    -> rtl8169_poll can not be issued again and re-enable the
+	 *       interruptions. Let's simply issue the IRQ down sequence again.
+	 */
+	if (RTL_R16(IntrMask))
+		goto core_down;
 
 	rtl8169_tx_clear(tp);
 
 	rtl8169_rx_clear(tp);
+}
+
+static int rtl8169_close(struct net_device *dev)
+{
+	struct rtl8169_private *tp = netdev_priv(dev);
+	struct pci_dev *pdev = tp->pci_dev;
+
+	rtl8169_down(dev);
+
+	free_irq(dev->irq, dev);
+
+	netif_poll_enable(dev);
 
 	pci_free_consistent(pdev, R8169_RX_RING_BYTES, tp->RxDescArray,
 			    tp->RxPhyAddr);
@@ -1886,7 +2428,7 @@
 rtl8169_set_rx_mode(struct net_device *dev)
 {
 	struct rtl8169_private *tp = netdev_priv(dev);
-	void *ioaddr = tp->mmio_addr;
+	void __iomem *ioaddr = tp->mmio_addr;
 	unsigned long flags;
 	u32 mc_filter[2];	/* Multicast hash filter */
 	int i, rx_mode;
@@ -1938,7 +2480,7 @@
 static struct net_device_stats *rtl8169_get_stats(struct net_device *dev)
 {
 	struct rtl8169_private *tp = netdev_priv(dev);
-	void *ioaddr = tp->mmio_addr;
+	void __iomem *ioaddr = tp->mmio_addr;
 	unsigned long flags;
 
 	if (netif_running(dev)) {
diff -Nru a/drivers/net/rrunner.c b/drivers/net/rrunner.c
--- a/drivers/net/rrunner.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/net/rrunner.c	2005-03-01 23:38:54 -08:00
@@ -62,7 +62,7 @@
 MODULE_DESCRIPTION("Essential RoadRunner HIPPI driver");
 MODULE_LICENSE("GPL");
 
-static char version[] __initdata = "rrunner.c: v0.50 11/11/2002  Jes Sorensen (jes@wildopensource.com)\n";
+static char version[] __devinitdata = "rrunner.c: v0.50 11/11/2002  Jes Sorensen (jes@wildopensource.com)\n";
 
 /*
  * Implementation notes:
diff -Nru a/drivers/net/s2io-regs.h b/drivers/net/s2io-regs.h
--- a/drivers/net/s2io-regs.h	2005-03-01 23:38:57 -08:00
+++ b/drivers/net/s2io-regs.h	2005-03-01 23:38:57 -08:00
@@ -289,6 +289,8 @@
 	u64 tda_err_alarm;
 
 	u64 pcc_err_reg;
+#define PCC_FB_ECC_DB_ERR		vBIT(0xFF, 16, 8)
+
 	u64 pcc_err_mask;
 	u64 pcc_err_alarm;
 
@@ -512,6 +514,7 @@
 #define RX_PA_CFG_IGNORE_FRM_ERR           BIT(1)
 #define RX_PA_CFG_IGNORE_SNAP_OUI          BIT(2)
 #define RX_PA_CFG_IGNORE_LLC_CTRL          BIT(3)
+#define RX_PA_CFG_IGNORE_L2_ERR            BIT(6)
 
 	u8 unused12[0x700 - 0x1D8];
 
diff -Nru a/drivers/net/s2io.c b/drivers/net/s2io.c
--- a/drivers/net/s2io.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/net/s2io.c	2005-03-01 23:39:07 -08:00
@@ -26,17 +26,13 @@
  *			  	
  * The module loadable parameters that are supported by the driver and a brief
  * explaination of all the variables.
- * ring_num : This can be used to program the number of receive rings used 
+ * rx_ring_num : This can be used to program the number of receive rings used 
  * in the driver.  					
- * frame_len: This is an array of size 8. Using this we can set the maximum 
- * size of the received frame that can be steered into the corrsponding 
- * receive ring.
- * ring_len: This defines the number of descriptors each ring can have. This 
+ * rx_ring_len: This defines the number of descriptors each ring can have. This 
  * is also an array of size 8.
- * fifo_num: This defines the number of Tx FIFOs thats used int the driver.
- * fifo_len: This too is an array of 8. Each element defines the number of 
+ * tx_fifo_num: This defines the number of Tx FIFOs thats used int the driver.
+ * tx_fifo_len: This too is an array of 8. Each element defines the number of 
  * Tx descriptors that can be associated with each corresponding FIFO.
- * latency_timer: This input is programmed into the Latency timer register
  * in PCI Configuration space.
  ************************************************************************/
 
@@ -69,21 +65,30 @@
 
 /* S2io Driver name & version. */
 static char s2io_driver_name[] = "s2io";
-static char s2io_driver_version[] = "Version 1.0";
+static char s2io_driver_version[] = "Version 1.7.5.1";
+
+/* 
+ * Cards with following subsystem_id have a link state indication
+ * problem, 600B, 600C, 600D, 640B, 640C and 640D.
+ * macro below identifies these cards given the subsystem_id.
+ */
+#define CARDS_WITH_FAULTY_LINK_INDICATORS(subid) \
+		(((subid >= 0x600B) && (subid <= 0x600D)) || \
+		 ((subid >= 0x640B) && (subid <= 0x640D))) ? 1 : 0
 
 #define LINK_IS_UP(val64) (!(val64 & (ADAPTER_STATUS_RMAC_REMOTE_FAULT | \
 				      ADAPTER_STATUS_RMAC_LOCAL_FAULT)))
-#define TASKLET_IN_USE test_and_set_bit(0, \
-				(unsigned long *)(&sp->tasklet_status))
+#define TASKLET_IN_USE test_and_set_bit(0, (&sp->tasklet_status))
 #define PANIC	1
 #define LOW	2
 static inline int rx_buffer_level(nic_t * sp, int rxb_size, int ring)
 {
 	int level = 0;
-	if ((sp->pkt_cnt[ring] - rxb_size) > 128) {
+	if ((sp->pkt_cnt[ring] - rxb_size) > 16) {
 		level = LOW;
-		if (rxb_size < sp->pkt_cnt[ring] / 8)
+		if ((sp->pkt_cnt[ring] - rxb_size) < MAX_RXDS_PER_BLOCK) {
 			level = PANIC;
+		}
 	}
 
 	return level;
@@ -99,45 +104,45 @@
 };
 
 static char ethtool_stats_keys[][ETH_GSTRING_LEN] = {
-	"tmac_frms",
-	"tmac_data_octets",
-	"tmac_drop_frms",
-	"tmac_mcst_frms",
-	"tmac_bcst_frms",
-	"tmac_pause_ctrl_frms",
-	"tmac_any_err_frms",
-	"tmac_vld_ip_octets",
-	"tmac_vld_ip",
-	"tmac_drop_ip",
-	"tmac_icmp",
-	"tmac_rst_tcp",
-	"tmac_tcp",
-	"tmac_udp",
-	"rmac_vld_frms",
-	"rmac_data_octets",
-	"rmac_fcs_err_frms",
-	"rmac_drop_frms",
-	"rmac_vld_mcst_frms",
-	"rmac_vld_bcst_frms",
-	"rmac_in_rng_len_err_frms",
-	"rmac_long_frms",
-	"rmac_pause_ctrl_frms",
-	"rmac_discarded_frms",
-	"rmac_usized_frms",
-	"rmac_osized_frms",
-	"rmac_frag_frms",
-	"rmac_jabber_frms",
-	"rmac_ip",
-	"rmac_ip_octets",
-	"rmac_hdr_err_ip",
-	"rmac_drop_ip",
-	"rmac_icmp",
-	"rmac_tcp",
-	"rmac_udp",
-	"rmac_err_drp_udp",
-	"rmac_pause_cnt",
-	"rmac_accepted_ip",
-	"rmac_err_tcp",
+	{"tmac_frms"},
+	{"tmac_data_octets"},
+	{"tmac_drop_frms"},
+	{"tmac_mcst_frms"},
+	{"tmac_bcst_frms"},
+	{"tmac_pause_ctrl_frms"},
+	{"tmac_any_err_frms"},
+	{"tmac_vld_ip_octets"},
+	{"tmac_vld_ip"},
+	{"tmac_drop_ip"},
+	{"tmac_icmp"},
+	{"tmac_rst_tcp"},
+	{"tmac_tcp"},
+	{"tmac_udp"},
+	{"rmac_vld_frms"},
+	{"rmac_data_octets"},
+	{"rmac_fcs_err_frms"},
+	{"rmac_drop_frms"},
+	{"rmac_vld_mcst_frms"},
+	{"rmac_vld_bcst_frms"},
+	{"rmac_in_rng_len_err_frms"},
+	{"rmac_long_frms"},
+	{"rmac_pause_ctrl_frms"},
+	{"rmac_discarded_frms"},
+	{"rmac_usized_frms"},
+	{"rmac_osized_frms"},
+	{"rmac_frag_frms"},
+	{"rmac_jabber_frms"},
+	{"rmac_ip"},
+	{"rmac_ip_octets"},
+	{"rmac_hdr_err_ip"},
+	{"rmac_drop_ip"},
+	{"rmac_icmp"},
+	{"rmac_tcp"},
+	{"rmac_udp"},
+	{"rmac_err_drp_udp"},
+	{"rmac_pause_cnt"},
+	{"rmac_accepted_ip"},
+	{"rmac_err_tcp"},
 };
 
 #define S2IO_STAT_LEN sizeof(ethtool_stats_keys)/ ETH_GSTRING_LEN
@@ -147,7 +152,8 @@
 #define S2IO_STRINGS_LEN	S2IO_TEST_LEN * ETH_GSTRING_LEN
 
 
-/* Constants to be programmed into the Xena's registers to configure
+/* 
+ * Constants to be programmed into the Xena's registers, to configure
  * the XAUI.
  */
 
@@ -188,7 +194,9 @@
 	END_SIGN
 };
 
-/* Constants for Fixing the MacAddress problem seen mostly on
+
+/* 
+ * Constants for Fixing the MacAddress problem seen mostly on
  * Alpha machines.
  */
 static u64 fix_mac[] = {
@@ -209,16 +217,23 @@
 	END_SIGN
 };
 
-
 /* Module Loadable parameters. */
-static u32 ring_num;
-static u32 frame_len[MAX_RX_RINGS];
-static u32 ring_len[MAX_RX_RINGS];
-static u32 fifo_num;
-static u32 fifo_len[MAX_TX_FIFOS];
-static u32 rx_prio;
-static u32 tx_prio;
-static u8 latency_timer = 0;
+static unsigned int tx_fifo_num = 1;
+static unsigned int tx_fifo_len[MAX_TX_FIFOS] =
+    {[0 ...(MAX_TX_FIFOS - 1)] = 0 };
+static unsigned int rx_ring_num = 1;
+static unsigned int rx_ring_sz[MAX_RX_RINGS] =
+    {[0 ...(MAX_RX_RINGS - 1)] = 0 };
+static unsigned int Stats_refresh_time = 4;
+static unsigned int rmac_pause_time = 65535;
+static unsigned int mc_pause_threshold_q0q3 = 187;
+static unsigned int mc_pause_threshold_q4q7 = 187;
+static unsigned int shared_splits;
+static unsigned int tmac_util_period = 5;
+static unsigned int rmac_util_period = 5;
+#ifndef CONFIG_S2IO_NAPI
+static unsigned int indicate_max_pkts;
+#endif
 
 /* 
  * S2IO device table.
@@ -241,24 +256,30 @@
       .remove = __devexit_p(s2io_rem_nic),
 };
 
-/*  
- *  Input Arguments: 
- *  Device private variable.
- *  Return Value: 
- *  SUCCESS on success and an appropriate -ve value on failure.
- *  Description: 
- *  The function allocates the all memory areas shared 
- *  between the NIC and the driver. This includes Tx descriptors, 
- *  Rx descriptors and the statistics block.
+/* A simplifier macro used both by init and free shared_mem Fns(). */
+#define TXD_MEM_PAGE_CNT(len, per_each) ((len+per_each - 1) / per_each)
+
+/**
+ * init_shared_mem - Allocation and Initialization of Memory
+ * @nic: Device private variable.
+ * Description: The function allocates all the memory areas shared 
+ * between the NIC and the driver. This includes Tx descriptors, 
+ * Rx descriptors and the statistics block.
  */
-static int initSharedMem(struct s2io_nic *nic)
+
+static int init_shared_mem(struct s2io_nic *nic)
 {
 	u32 size;
 	void *tmp_v_addr, *tmp_v_addr_next;
 	dma_addr_t tmp_p_addr, tmp_p_addr_next;
 	RxD_block_t *pre_rxd_blk = NULL;
 	int i, j, blk_cnt;
+	int lst_size, lst_per_page;
 	struct net_device *dev = nic->dev;
+#ifdef CONFIG_2BUFF_MODE
+	unsigned long tmp;
+	buffAdd_t *ba;
+#endif
 
 	mac_info_t *mac_control;
 	struct config_param *config;
@@ -269,8 +290,8 @@
 
 	/* Allocation and initialization of TXDLs in FIOFs */
 	size = 0;
-	for (i = 0; i < config->TxFIFONum; i++) {
-		size += config->TxCfg[i].FifoLen;
+	for (i = 0; i < config->tx_fifo_num; i++) {
+		size += config->tx_cfg[i].fifo_len;
 	}
 	if (size > MAX_AVAILABLE_TXDS) {
 		DBG_PRINT(ERR_DBG, "%s: Total number of Tx FIFOs ",
@@ -279,77 +300,96 @@
 		DBG_PRINT(ERR_DBG, "that can be used\n");
 		return FAILURE;
 	}
-	size *= (sizeof(TxD_t) * config->MaxTxDs);
 
-	mac_control->txd_list_mem = pci_alloc_consistent
-	    (nic->pdev, size, &mac_control->txd_list_mem_phy);
-	if (!mac_control->txd_list_mem) {
-		return -ENOMEM;
-	}
-	mac_control->txd_list_mem_sz = size;
-
-	tmp_v_addr = mac_control->txd_list_mem;
-	tmp_p_addr = mac_control->txd_list_mem_phy;
-	memset(tmp_v_addr, 0, size);
+	lst_size = (sizeof(TxD_t) * config->max_txds);
+	lst_per_page = PAGE_SIZE / lst_size;
 
-	DBG_PRINT(INIT_DBG, "%s:List Mem PHY: 0x%llx\n", dev->name,
-		  (unsigned long long) tmp_p_addr);
-
-	for (i = 0; i < config->TxFIFONum; i++) {
-		mac_control->txdl_start_phy[i] = tmp_p_addr;
-		mac_control->txdl_start[i] = (TxD_t *) tmp_v_addr;
+	for (i = 0; i < config->tx_fifo_num; i++) {
+		int fifo_len = config->tx_cfg[i].fifo_len;
+		int list_holder_size = fifo_len * sizeof(list_info_hold_t);
+		nic->list_info[i] = kmalloc(list_holder_size, GFP_KERNEL);
+		if (!nic->list_info[i]) {
+			DBG_PRINT(ERR_DBG,
+				  "Malloc failed for list_info\n");
+			return -ENOMEM;
+		}
+		memset(nic->list_info[i], 0, list_holder_size);
+	}
+	for (i = 0; i < config->tx_fifo_num; i++) {
+		int page_num = TXD_MEM_PAGE_CNT(config->tx_cfg[i].fifo_len,
+						lst_per_page);
 		mac_control->tx_curr_put_info[i].offset = 0;
 		mac_control->tx_curr_put_info[i].fifo_len =
-		    config->TxCfg[i].FifoLen - 1;
+		    config->tx_cfg[i].fifo_len - 1;
 		mac_control->tx_curr_get_info[i].offset = 0;
 		mac_control->tx_curr_get_info[i].fifo_len =
-		    config->TxCfg[i].FifoLen - 1;
-
-		tmp_p_addr +=
-		    (config->TxCfg[i].FifoLen * (sizeof(TxD_t)) *
-		     config->MaxTxDs);
-		tmp_v_addr +=
-		    (config->TxCfg[i].FifoLen * (sizeof(TxD_t)) *
-		     config->MaxTxDs);
+		    config->tx_cfg[i].fifo_len - 1;
+		for (j = 0; j < page_num; j++) {
+			int k = 0;
+			dma_addr_t tmp_p;
+			void *tmp_v;
+			tmp_v = pci_alloc_consistent(nic->pdev,
+						     PAGE_SIZE, &tmp_p);
+			if (!tmp_v) {
+				DBG_PRINT(ERR_DBG,
+					  "pci_alloc_consistent ");
+				DBG_PRINT(ERR_DBG, "failed for TxDL\n");
+				return -ENOMEM;
+			}
+			while (k < lst_per_page) {
+				int l = (j * lst_per_page) + k;
+				if (l == config->tx_cfg[i].fifo_len)
+					goto end_txd_alloc;
+				nic->list_info[i][l].list_virt_addr =
+				    tmp_v + (k * lst_size);
+				nic->list_info[i][l].list_phy_addr =
+				    tmp_p + (k * lst_size);
+				k++;
+			}
+		}
 	}
+      end_txd_alloc:
 
 	/* Allocation and initialization of RXDs in Rings */
 	size = 0;
-	for (i = 0; i < config->RxRingNum; i++) {
-		if (config->RxCfg[i].NumRxd % (MAX_RXDS_PER_BLOCK + 1)) {
+	for (i = 0; i < config->rx_ring_num; i++) {
+		if (config->rx_cfg[i].num_rxd % (MAX_RXDS_PER_BLOCK + 1)) {
 			DBG_PRINT(ERR_DBG, "%s: RxD count of ", dev->name);
 			DBG_PRINT(ERR_DBG, "Ring%d is not a multiple of ",
 				  i);
 			DBG_PRINT(ERR_DBG, "RxDs per Block");
 			return FAILURE;
 		}
-		size += config->RxCfg[i].NumRxd;
+		size += config->rx_cfg[i].num_rxd;
 		nic->block_count[i] =
-		    config->RxCfg[i].NumRxd / (MAX_RXDS_PER_BLOCK + 1);
+		    config->rx_cfg[i].num_rxd / (MAX_RXDS_PER_BLOCK + 1);
 		nic->pkt_cnt[i] =
-		    config->RxCfg[i].NumRxd - nic->block_count[i];
+		    config->rx_cfg[i].num_rxd - nic->block_count[i];
 	}
-	size = (size * (sizeof(RxD_t)));
-	mac_control->rxd_ring_mem_sz = size;
 
-	for (i = 0; i < config->RxRingNum; i++) {
+	for (i = 0; i < config->rx_ring_num; i++) {
 		mac_control->rx_curr_get_info[i].block_index = 0;
 		mac_control->rx_curr_get_info[i].offset = 0;
 		mac_control->rx_curr_get_info[i].ring_len =
-		    config->RxCfg[i].NumRxd - 1;
+		    config->rx_cfg[i].num_rxd - 1;
 		mac_control->rx_curr_put_info[i].block_index = 0;
 		mac_control->rx_curr_put_info[i].offset = 0;
 		mac_control->rx_curr_put_info[i].ring_len =
-		    config->RxCfg[i].NumRxd - 1;
+		    config->rx_cfg[i].num_rxd - 1;
 		blk_cnt =
-		    config->RxCfg[i].NumRxd / (MAX_RXDS_PER_BLOCK + 1);
+		    config->rx_cfg[i].num_rxd / (MAX_RXDS_PER_BLOCK + 1);
 		/*  Allocating all the Rx blocks */
 		for (j = 0; j < blk_cnt; j++) {
+#ifndef CONFIG_2BUFF_MODE
 			size = (MAX_RXDS_PER_BLOCK + 1) * (sizeof(RxD_t));
+#else
+			size = SIZE_OF_BLOCK;
+#endif
 			tmp_v_addr = pci_alloc_consistent(nic->pdev, size,
 							  &tmp_p_addr);
 			if (tmp_v_addr == NULL) {
-				/* In case of failure, freeSharedMem() 
+				/*
+				 * In case of failure, free_shared_mem() 
 				 * is called, which should free any 
 				 * memory that was alloced till the 
 				 * failure happened.
@@ -377,20 +417,68 @@
 			pre_rxd_blk->reserved_1 = END_OF_BLOCK;	/* last RxD 
 								 * marker.
 								 */
+#ifndef	CONFIG_2BUFF_MODE
 			pre_rxd_blk->reserved_2_pNext_RxD_block =
 			    (unsigned long) tmp_v_addr_next;
+#endif
 			pre_rxd_blk->pNext_RxD_Blk_physical =
 			    (u64) tmp_p_addr_next;
 		}
 	}
 
+#ifdef CONFIG_2BUFF_MODE
+	/* 
+	 * Allocation of Storages for buffer addresses in 2BUFF mode
+	 * and the buffers as well.
+	 */
+	for (i = 0; i < config->rx_ring_num; i++) {
+		blk_cnt =
+		    config->rx_cfg[i].num_rxd / (MAX_RXDS_PER_BLOCK + 1);
+		nic->ba[i] = kmalloc((sizeof(buffAdd_t *) * blk_cnt),
+				     GFP_KERNEL);
+		if (!nic->ba[i])
+			return -ENOMEM;
+		for (j = 0; j < blk_cnt; j++) {
+			int k = 0;
+			nic->ba[i][j] = kmalloc((sizeof(buffAdd_t) *
+						 (MAX_RXDS_PER_BLOCK + 1)),
+						GFP_KERNEL);
+			if (!nic->ba[i][j])
+				return -ENOMEM;
+			while (k != MAX_RXDS_PER_BLOCK) {
+				ba = &nic->ba[i][j][k];
+
+				ba->ba_0_org = kmalloc
+				    (BUF0_LEN + ALIGN_SIZE, GFP_KERNEL);
+				if (!ba->ba_0_org)
+					return -ENOMEM;
+				tmp = (unsigned long) ba->ba_0_org;
+				tmp += ALIGN_SIZE;
+				tmp &= ~((unsigned long) ALIGN_SIZE);
+				ba->ba_0 = (void *) tmp;
+
+				ba->ba_1_org = kmalloc
+				    (BUF1_LEN + ALIGN_SIZE, GFP_KERNEL);
+				if (!ba->ba_1_org)
+					return -ENOMEM;
+				tmp = (unsigned long) ba->ba_1_org;
+				tmp += ALIGN_SIZE;
+				tmp &= ~((unsigned long) ALIGN_SIZE);
+				ba->ba_1 = (void *) tmp;
+				k++;
+			}
+		}
+	}
+#endif
+
 	/* Allocation and initialization of Statistics block */
 	size = sizeof(StatInfo_t);
 	mac_control->stats_mem = pci_alloc_consistent
 	    (nic->pdev, size, &mac_control->stats_mem_phy);
 
 	if (!mac_control->stats_mem) {
-		/* In case of failure, freeSharedMem() is called, which 
+		/* 
+		 * In case of failure, free_shared_mem() is called, which 
 		 * should free any memory that was alloced till the 
 		 * failure happened.
 		 */
@@ -399,7 +487,7 @@
 	mac_control->stats_mem_sz = size;
 
 	tmp_v_addr = mac_control->stats_mem;
-	mac_control->StatsInfo = (StatInfo_t *) tmp_v_addr;
+	mac_control->stats_info = (StatInfo_t *) tmp_v_addr;
 	memset(tmp_v_addr, 0, size);
 
 	DBG_PRINT(INIT_DBG, "%s:Ring Mem PHY: 0x%llx\n", dev->name,
@@ -408,22 +496,21 @@
 	return SUCCESS;
 }
 
-/*  
- *  Input Arguments: 
- *  Device peivate variable.
- *  Return Value: 
- *  NONE
- *  Description: 
- *  This function is to free all memory locations allocated by
- *  the initSharedMem() function and return it to the kernel.
+/**  
+ * free_shared_mem - Free the allocated Memory 
+ * @nic:  Device private variable.
+ * Description: This function is to free all memory locations allocated by
+ * the init_shared_mem() function and return it to the kernel.
  */
-static void freeSharedMem(struct s2io_nic *nic)
+
+static void free_shared_mem(struct s2io_nic *nic)
 {
 	int i, j, blk_cnt, size;
 	void *tmp_v_addr;
 	dma_addr_t tmp_p_addr;
 	mac_info_t *mac_control;
 	struct config_param *config;
+	int lst_size, lst_per_page;
 
 
 	if (!nic)
@@ -432,15 +519,31 @@
 	mac_control = &nic->mac_control;
 	config = &nic->config;
 
-	if (mac_control->txd_list_mem) {
-		pci_free_consistent(nic->pdev,
-				    mac_control->txd_list_mem_sz,
-				    mac_control->txd_list_mem,
-				    mac_control->txd_list_mem_phy);
+	lst_size = (sizeof(TxD_t) * config->max_txds);
+	lst_per_page = PAGE_SIZE / lst_size;
+
+	for (i = 0; i < config->tx_fifo_num; i++) {
+		int page_num = TXD_MEM_PAGE_CNT(config->tx_cfg[i].fifo_len,
+						lst_per_page);
+		for (j = 0; j < page_num; j++) {
+			int mem_blks = (j * lst_per_page);
+			if (!nic->list_info[i][mem_blks].list_virt_addr)
+				break;
+			pci_free_consistent(nic->pdev, PAGE_SIZE,
+					    nic->list_info[i][mem_blks].
+					    list_virt_addr,
+					    nic->list_info[i][mem_blks].
+					    list_phy_addr);
+		}
+		kfree(nic->list_info[i]);
 	}
 
+#ifndef CONFIG_2BUFF_MODE
 	size = (MAX_RXDS_PER_BLOCK + 1) * (sizeof(RxD_t));
-	for (i = 0; i < config->RxRingNum; i++) {
+#else
+	size = SIZE_OF_BLOCK;
+#endif
+	for (i = 0; i < config->rx_ring_num; i++) {
 		blk_cnt = nic->block_count[i];
 		for (j = 0; j < blk_cnt; j++) {
 			tmp_v_addr = nic->rx_blocks[i][j].block_virt_addr;
@@ -452,6 +555,42 @@
 		}
 	}
 
+#ifdef CONFIG_2BUFF_MODE
+	/* Freeing buffer storage addresses in 2BUFF mode. */
+	for (i = 0; i < config->rx_ring_num; i++) {
+		blk_cnt =
+		    config->rx_cfg[i].num_rxd / (MAX_RXDS_PER_BLOCK + 1);
+		if (!nic->ba[i])
+			goto end_free;
+		for (j = 0; j < blk_cnt; j++) {
+			int k = 0;
+			if (!nic->ba[i][j]) {
+				kfree(nic->ba[i]);
+				goto end_free;
+			}
+			while (k != MAX_RXDS_PER_BLOCK) {
+				buffAdd_t *ba = &nic->ba[i][j][k];
+				if (!ba || !ba->ba_0_org || !ba->ba_1_org)
+				{
+					kfree(nic->ba[i]);
+					kfree(nic->ba[i][j]);
+					if(ba->ba_0_org)
+						kfree(ba->ba_0_org);
+					if(ba->ba_1_org)
+						kfree(ba->ba_1_org);
+					goto end_free;
+				}
+				kfree(ba->ba_0_org);
+				kfree(ba->ba_1_org);
+				k++;
+			}
+			kfree(nic->ba[i][j]);
+		}
+		kfree(nic->ba[i]);
+	}
+end_free:
+#endif
+
 	if (mac_control->stats_mem) {
 		pci_free_consistent(nic->pdev,
 				    mac_control->stats_mem_sz,
@@ -460,21 +599,21 @@
 	}
 }
 
-/*  
- *  Input Arguments: 
- *  device peivate variable
- *  Return Value: 
- *  SUCCESS on success and '-1' on failure (endian settings incorrect).
- *  Description: 
- *  The function sequentially configures every block 
+/**  
+ *  init_nic - Initialization of hardware 
+ *  @nic: device peivate variable
+ *  Description: The function sequentially configures every block 
  *  of the H/W from their reset values. 
+ *  Return Value:  SUCCESS on success and 
+ *  '-1' on failure (endian settings incorrect).
  */
-static int initNic(struct s2io_nic *nic)
+
+static int init_nic(struct s2io_nic *nic)
 {
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+	XENA_dev_config_t __iomem *bar0 = nic->bar0;
 	struct net_device *dev = nic->dev;
 	register u64 val64 = 0;
-	void *add;
+	void __iomem *add;
 	u32 time;
 	int i, j;
 	mac_info_t *mac_control;
@@ -485,11 +624,13 @@
 	mac_control = &nic->mac_control;
 	config = &nic->config;
 
-	/*  Set proper endian settings and verify the same by 
-	 *  reading the PIF Feed-back register.
+	/* 
+	 * Set proper endian settings and verify the same by 
+	 * reading the PIF Feed-back register.
 	 */
 #ifdef  __BIG_ENDIAN
-	/* The device by default set to a big endian format, so 
+	/*
+	 * The device by default set to a big endian format, so 
 	 * a big endian driver need not set anything.
 	 */
 	writeq(0xffffffffffffffffULL, &bar0->swapper_ctrl);
@@ -510,7 +651,8 @@
 		 SWAPPER_CTRL_STATS_FE | SWAPPER_CTRL_STATS_SE);
 	writeq(val64, &bar0->swapper_ctrl);
 #else
-	/* Initially we enable all bits to make it accessible by 
+	/* 
+	 * Initially we enable all bits to make it accessible by 
 	 * the driver, then we selectively enable only those bits 
 	 * that we want to set.
 	 */
@@ -537,8 +679,9 @@
 	writeq(val64, &bar0->swapper_ctrl);
 #endif
 
-	/* Verifying if endian settings are accurate by reading 
-	 * a feedback register.
+	/* 
+	 * Verifying if endian settings are accurate by 
+	 * reading a feedback register.
 	 */
 	val64 = readq(&bar0->pif_rd_swapper_fb);
 	if (val64 != 0x0123456789ABCDEFULL) {
@@ -559,10 +702,13 @@
 	schedule_timeout(HZ / 2);
 
 	/*  Enable Receiving broadcasts */
+	add = &bar0->mac_cfg;
 	val64 = readq(&bar0->mac_cfg);
 	val64 |= MAC_RMAC_BCAST_ENABLE;
 	writeq(RMAC_CFG_KEY(0x4C0D), &bar0->rmac_cfg_key);
-	writeq(val64, &bar0->mac_cfg);
+	writel((u32) val64, add);
+	writeq(RMAC_CFG_KEY(0x4C0D), &bar0->rmac_cfg_key);
+	writel((u32) (val64 >> 32), (add + 4));
 
 	/* Read registers in all blocks */
 	val64 = readq(&bar0->mac_int_mask);
@@ -573,8 +719,9 @@
 	val64 = dev->mtu;
 	writeq(vBIT(val64, 2, 14), &bar0->rmac_max_pyld_len);
 
-	/* Configuring the XAUI Interface of Xena. 
-	 *****************************************
+	/* 
+	 * Configuring the XAUI Interface of Xena. 
+	 * ***************************************
 	 * To Configure the Xena's XAUI, one has to write a series 
 	 * of 64 bit values into two registers in a particular 
 	 * sequence. Hence a macro 'SWITCH_SIGN' has been defined 
@@ -593,8 +740,8 @@
 				dtx_cnt++;
 				goto mdio_cfg;
 			}
-			writeq(default_dtx_cfg[dtx_cnt],
-			       &bar0->dtx_control);
+			SPECIAL_REG_WRITE(default_dtx_cfg[dtx_cnt],
+					  &bar0->dtx_control, UF);
 			val64 = readq(&bar0->dtx_control);
 			dtx_cnt++;
 		}
@@ -604,8 +751,8 @@
 				mdio_cnt++;
 				goto dtx_cfg;
 			}
-			writeq(default_mdio_cfg[mdio_cnt],
-			       &bar0->mdio_control);
+			SPECIAL_REG_WRITE(default_mdio_cfg[mdio_cnt],
+					  &bar0->mdio_control, UF);
 			val64 = readq(&bar0->mdio_control);
 			mdio_cnt++;
 		}
@@ -625,13 +772,13 @@
 	writeq(val64, &bar0->tx_fifo_partition_3);
 
 
-	for (i = 0, j = 0; i < config->TxFIFONum; i++) {
+	for (i = 0, j = 0; i < config->tx_fifo_num; i++) {
 		val64 |=
-		    vBIT(config->TxCfg[i].FifoLen - 1, ((i * 32) + 19),
-			 13) | vBIT(config->TxCfg[i].FifoPriority,
+		    vBIT(config->tx_cfg[i].fifo_len - 1, ((i * 32) + 19),
+			 13) | vBIT(config->tx_cfg[i].fifo_priority,
 				    ((i * 32) + 5), 3);
 
-		if (i == (config->TxFIFONum - 1)) {
+		if (i == (config->tx_fifo_num - 1)) {
 			if (i % 2 == 0)
 				i++;
 		}
@@ -675,56 +822,59 @@
 
 	/* Rx DMA intialization. */
 	val64 = 0;
-	for (i = 0; i < config->RxRingNum; i++) {
+	for (i = 0; i < config->rx_ring_num; i++) {
 		val64 |=
-		    vBIT(config->RxCfg[i].RingPriority, (5 + (i * 8)), 3);
+		    vBIT(config->rx_cfg[i].ring_priority, (5 + (i * 8)),
+			 3);
 	}
 	writeq(val64, &bar0->rx_queue_priority);
 
-	/* Allocating equal share of memory to all the configured 
-	 * Rings.
+	/* 
+	 * Allocating equal share of memory to all the 
+	 * configured Rings.
 	 */
 	val64 = 0;
-	for (i = 0; i < config->RxRingNum; i++) {
+	for (i = 0; i < config->rx_ring_num; i++) {
 		switch (i) {
 		case 0:
-			mem_share = (64 / config->RxRingNum +
-				     64 % config->RxRingNum);
+			mem_share = (64 / config->rx_ring_num +
+				     64 % config->rx_ring_num);
 			val64 |= RX_QUEUE_CFG_Q0_SZ(mem_share);
 			continue;
 		case 1:
-			mem_share = (64 / config->RxRingNum);
+			mem_share = (64 / config->rx_ring_num);
 			val64 |= RX_QUEUE_CFG_Q1_SZ(mem_share);
 			continue;
 		case 2:
-			mem_share = (64 / config->RxRingNum);
+			mem_share = (64 / config->rx_ring_num);
 			val64 |= RX_QUEUE_CFG_Q2_SZ(mem_share);
 			continue;
 		case 3:
-			mem_share = (64 / config->RxRingNum);
+			mem_share = (64 / config->rx_ring_num);
 			val64 |= RX_QUEUE_CFG_Q3_SZ(mem_share);
 			continue;
 		case 4:
-			mem_share = (64 / config->RxRingNum);
+			mem_share = (64 / config->rx_ring_num);
 			val64 |= RX_QUEUE_CFG_Q4_SZ(mem_share);
 			continue;
 		case 5:
-			mem_share = (64 / config->RxRingNum);
+			mem_share = (64 / config->rx_ring_num);
 			val64 |= RX_QUEUE_CFG_Q5_SZ(mem_share);
 			continue;
 		case 6:
-			mem_share = (64 / config->RxRingNum);
+			mem_share = (64 / config->rx_ring_num);
 			val64 |= RX_QUEUE_CFG_Q6_SZ(mem_share);
 			continue;
 		case 7:
-			mem_share = (64 / config->RxRingNum);
+			mem_share = (64 / config->rx_ring_num);
 			val64 |= RX_QUEUE_CFG_Q7_SZ(mem_share);
 			continue;
 		}
 	}
 	writeq(val64, &bar0->rx_queue_cfg);
 
-	/* Initializing the Tx round robin registers to 0.
+	/* 
+	 * Initializing the Tx round robin registers to 0.
 	 * Filling Tx and Rx round robin registers as per the 
 	 * number of FIFOs and Rings is still TODO.
 	 */
@@ -734,20 +884,13 @@
 	writeq(0, &bar0->tx_w_round_robin_3);
 	writeq(0, &bar0->tx_w_round_robin_4);
 
-	/* Disable Rx steering. Hard coding all packets be steered to
+	/* 
+	 * TODO
+	 * Disable Rx steering. Hard coding all packets be steered to
 	 * Queue 0 for now. 
-	 * TODO*/
-	if (rx_prio) {
-		u64 def = 0x8000000000000000ULL, tmp;
-		for (i = 0; i < MAX_RX_RINGS; i++) {
-			tmp = (u64) (def >> (i % config->RxRingNum));
-			val64 |= (u64) (tmp >> (i * 8));
-		}
-		writeq(val64, &bar0->rts_qos_steering);
-	} else {
-		val64 = 0x8080808080808080ULL;
-		writeq(val64, &bar0->rts_qos_steering);
-	}
+	 */
+	val64 = 0x8080808080808080ULL;
+	writeq(val64, &bar0->rts_qos_steering);
 
 	/* UDP Fix */
 	val64 = 0;
@@ -760,34 +903,40 @@
 
 	/* Enable statistics */
 	writeq(mac_control->stats_mem_phy, &bar0->stat_addr);
-	val64 = SET_UPDT_PERIOD(8) | STAT_CFG_STAT_RO | STAT_CFG_STAT_EN;
+	val64 = SET_UPDT_PERIOD(Stats_refresh_time) |
+	    STAT_CFG_STAT_RO | STAT_CFG_STAT_EN;
 	writeq(val64, &bar0->stat_cfg);
 
-	/* Initializing the sampling rate for the device to calculate the
+	/* 
+	 * Initializing the sampling rate for the device to calculate the
 	 * bandwidth utilization.
 	 */
-	val64 = MAC_TX_LINK_UTIL_VAL(0x5) | MAC_RX_LINK_UTIL_VAL(0x5);
+	val64 = MAC_TX_LINK_UTIL_VAL(tmac_util_period) |
+	    MAC_RX_LINK_UTIL_VAL(rmac_util_period);
 	writeq(val64, &bar0->mac_link_util);
 
 
-	/* Initializing the Transmit and Receive Traffic Interrupt 
+	/* 
+	 * Initializing the Transmit and Receive Traffic Interrupt 
 	 * Scheme.
 	 */
 	/* TTI Initialization */
 	val64 = TTI_DATA1_MEM_TX_TIMER_VAL(0xFFF) |
-	    TTI_DATA1_MEM_TX_URNG_A(0xA) | TTI_DATA1_MEM_TX_URNG_B(0x10) |
+	    TTI_DATA1_MEM_TX_URNG_A(0xA) |
+	    TTI_DATA1_MEM_TX_URNG_B(0x10) |
 	    TTI_DATA1_MEM_TX_URNG_C(0x30) | TTI_DATA1_MEM_TX_TIMER_AC_EN;
 	writeq(val64, &bar0->tti_data1_mem);
 
-	val64 =
-	    TTI_DATA2_MEM_TX_UFC_A(0x10) | TTI_DATA2_MEM_TX_UFC_B(0x20) |
+	val64 = TTI_DATA2_MEM_TX_UFC_A(0x10) |
+	    TTI_DATA2_MEM_TX_UFC_B(0x20) |
 	    TTI_DATA2_MEM_TX_UFC_C(0x40) | TTI_DATA2_MEM_TX_UFC_D(0x80);
 	writeq(val64, &bar0->tti_data2_mem);
 
 	val64 = TTI_CMD_MEM_WE | TTI_CMD_MEM_STROBE_NEW_CMD;
 	writeq(val64, &bar0->tti_command_mem);
 
-	/* Once the operation completes, the Strobe bit of the command
+	/* 
+	 * Once the operation completes, the Strobe bit of the command
 	 * register will be reset. We poll for this particular condition
 	 * We wait for a maximum of 500ms for the operation to complete,
 	 * if it's not complete by then we return error.
@@ -810,18 +959,22 @@
 
 	/* RTI Initialization */
 	val64 = RTI_DATA1_MEM_RX_TIMER_VAL(0xFFF) |
-	    RTI_DATA1_MEM_RX_URNG_A(0xA) | RTI_DATA1_MEM_RX_URNG_B(0x10) |
+	    RTI_DATA1_MEM_RX_URNG_A(0xA) |
+	    RTI_DATA1_MEM_RX_URNG_B(0x10) |
 	    RTI_DATA1_MEM_RX_URNG_C(0x30) | RTI_DATA1_MEM_RX_TIMER_AC_EN;
+
 	writeq(val64, &bar0->rti_data1_mem);
 
-	val64 = RTI_DATA2_MEM_RX_UFC_A(0x1) | RTI_DATA2_MEM_RX_UFC_B(0x2) |
+	val64 = RTI_DATA2_MEM_RX_UFC_A(0x1) |
+	    RTI_DATA2_MEM_RX_UFC_B(0x2) |
 	    RTI_DATA2_MEM_RX_UFC_C(0x40) | RTI_DATA2_MEM_RX_UFC_D(0x80);
 	writeq(val64, &bar0->rti_data2_mem);
 
 	val64 = RTI_CMD_MEM_WE | RTI_CMD_MEM_STROBE_NEW_CMD;
 	writeq(val64, &bar0->rti_command_mem);
 
-	/* Once the operation completes, the Strobe bit of the command
+	/* 
+	 * Once the operation completes, the Strobe bit of the command
 	 * register will be reset. We poll for this particular condition
 	 * We wait for a maximum of 500ms for the operation to complete,
 	 * if it's not complete by then we return error.
@@ -842,14 +995,15 @@
 		schedule_timeout(HZ / 20);
 	}
 
-	/* Initializing proper values as Pause threshold into all 
+	/* 
+	 * Initializing proper values as Pause threshold into all 
 	 * the 8 Queues on Rx side.
 	 */
 	writeq(0xffbbffbbffbbffbbULL, &bar0->mc_pause_thresh_q0q3);
 	writeq(0xffbbffbbffbbffbbULL, &bar0->mc_pause_thresh_q4q7);
 
 	/* Disable RMAC PAD STRIPPING */
-	add = (void *) &bar0->mac_cfg;
+	add = &bar0->mac_cfg;
 	val64 = readq(&bar0->mac_cfg);
 	val64 &= ~(MAC_CFG_RMAC_STRIP_PAD);
 	writeq(RMAC_CFG_KEY(0x4C0D), &bar0->rmac_cfg_key);
@@ -858,24 +1012,64 @@
 	writel((u32) (val64 >> 32), (add + 4));
 	val64 = readq(&bar0->mac_cfg);
 
+	/* 
+	 * Set the time value to be inserted in the pause frame 
+	 * generated by xena.
+	 */
+	val64 = readq(&bar0->rmac_pause_cfg);
+	val64 &= ~(RMAC_PAUSE_HG_PTIME(0xffff));
+	val64 |= RMAC_PAUSE_HG_PTIME(nic->mac_control.rmac_pause_time);
+	writeq(val64, &bar0->rmac_pause_cfg);
+
+	/* 
+	 * Set the Threshold Limit for Generating the pause frame
+	 * If the amount of data in any Queue exceeds ratio of
+	 * (mac_control.mc_pause_threshold_q0q3 or q4q7)/256
+	 * pause frame is generated
+	 */
+	val64 = 0;
+	for (i = 0; i < 4; i++) {
+		val64 |=
+		    (((u64) 0xFF00 | nic->mac_control.
+		      mc_pause_threshold_q0q3)
+		     << (i * 2 * 8));
+	}
+	writeq(val64, &bar0->mc_pause_thresh_q0q3);
+
+	val64 = 0;
+	for (i = 0; i < 4; i++) {
+		val64 |=
+		    (((u64) 0xFF00 | nic->mac_control.
+		      mc_pause_threshold_q4q7)
+		     << (i * 2 * 8));
+	}
+	writeq(val64, &bar0->mc_pause_thresh_q4q7);
+
+	/* 
+	 * TxDMA will stop Read request if the number of read split has 
+	 * exceeded the limit pointed by shared_splits
+	 */
+	val64 = readq(&bar0->pic_control);
+	val64 |= PIC_CNTL_SHARED_SPLITS(shared_splits);
+	writeq(val64, &bar0->pic_control);
+
 	return SUCCESS;
 }
 
-/*  
- *  Input Arguments: 
- *  device private variable,
- *  A mask indicating which Intr block must be modified and,
- *  A flag indicating whether to enable or disable the Intrs.
- *  Return Value: 
- *  NONE.
- *  Description: 
- *  This function will either disable or enable the interrupts 
+/**  
+ *  en_dis_able_nic_intrs - Enable or Disable the interrupts 
+ *  @nic: device private variable,
+ *  @mask: A mask indicating which Intr block must be modified and,
+ *  @flag: A flag indicating whether to enable or disable the Intrs.
+ *  Description: This function will either disable or enable the interrupts
  *  depending on the flag argument. The mask argument can be used to 
  *  enable/disable any Intr block. 
+ *  Return Value: NONE.
  */
-static void en_dis_able_NicIntrs(struct s2io_nic *nic, u16 mask, int flag)
+
+static void en_dis_able_nic_intrs(struct s2io_nic *nic, u16 mask, int flag)
 {
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+	XENA_dev_config_t __iomem *bar0 = nic->bar0;
 	register u64 val64 = 0, temp64 = 0;
 
 	/*  Top level interrupt classification */
@@ -887,15 +1081,20 @@
 			temp64 = readq(&bar0->general_int_mask);
 			temp64 &= ~((u64) val64);
 			writeq(temp64, &bar0->general_int_mask);
-			/*  Disabled all PCIX, Flash, MDIO, IIC and GPIO
-			 *  interrupts for now. 
-			 * TODO */
+			/*  
+			 * Disabled all PCIX, Flash, MDIO, IIC and GPIO
+			 * interrupts for now. 
+			 * TODO 
+			 */
 			writeq(DISABLE_ALL_INTRS, &bar0->pic_int_mask);
-			/*  No MSI Support is available presently, so TTI and
+			/* 
+			 * No MSI Support is available presently, so TTI and
 			 * RTI interrupts are also disabled.
 			 */
 		} else if (flag == DISABLE_INTRS) {
-			/*  Disable PIC Intrs in the general intr mask register 
+			/*  
+			 * Disable PIC Intrs in the general 
+			 * intr mask register 
 			 */
 			writeq(DISABLE_ALL_INTRS, &bar0->pic_int_mask);
 			temp64 = readq(&bar0->general_int_mask);
@@ -907,24 +1106,34 @@
 	/*  DMA Interrupts */
 	/*  Enabling/Disabling Tx DMA interrupts */
 	if (mask & TX_DMA_INTR) {
-		/*  Enable TxDMA Intrs in the general intr mask register */
+		/* Enable TxDMA Intrs in the general intr mask register */
 		val64 = TXDMA_INT_M;
 		if (flag == ENABLE_INTRS) {
 			temp64 = readq(&bar0->general_int_mask);
 			temp64 &= ~((u64) val64);
 			writeq(temp64, &bar0->general_int_mask);
-			/* Disable all interrupts other than PFC interrupt in 
-			 * DMA level.
+			/* 
+			 * Keep all interrupts other than PFC interrupt 
+			 * and PCC interrupt disabled in DMA level.
 			 */
-			val64 = DISABLE_ALL_INTRS & (~TXDMA_PFC_INT_M);
+			val64 = DISABLE_ALL_INTRS & ~(TXDMA_PFC_INT_M |
+						      TXDMA_PCC_INT_M);
 			writeq(val64, &bar0->txdma_int_mask);
-			/* Enable only the MISC error 1 interrupt in PFC block 
+			/* 
+			 * Enable only the MISC error 1 interrupt in PFC block 
 			 */
 			val64 = DISABLE_ALL_INTRS & (~PFC_MISC_ERR_1);
 			writeq(val64, &bar0->pfc_err_mask);
+			/* 
+			 * Enable only the FB_ECC error interrupt in PCC block 
+			 */
+			val64 = DISABLE_ALL_INTRS & (~PCC_FB_ECC_ERR);
+			writeq(val64, &bar0->pcc_err_mask);
 		} else if (flag == DISABLE_INTRS) {
-			/*  Disable TxDMA Intrs in the general intr mask 
-			 *  register */
+			/* 
+			 * Disable TxDMA Intrs in the general intr mask 
+			 * register 
+			 */
 			writeq(DISABLE_ALL_INTRS, &bar0->txdma_int_mask);
 			writeq(DISABLE_ALL_INTRS, &bar0->pfc_err_mask);
 			temp64 = readq(&bar0->general_int_mask);
@@ -941,12 +1150,16 @@
 			temp64 = readq(&bar0->general_int_mask);
 			temp64 &= ~((u64) val64);
 			writeq(temp64, &bar0->general_int_mask);
-			/* All RxDMA block interrupts are disabled for now 
-			 * TODO */
+			/* 
+			 * All RxDMA block interrupts are disabled for now 
+			 * TODO 
+			 */
 			writeq(DISABLE_ALL_INTRS, &bar0->rxdma_int_mask);
 		} else if (flag == DISABLE_INTRS) {
-			/*  Disable RxDMA Intrs in the general intr mask 
-			 *  register */
+			/*  
+			 * Disable RxDMA Intrs in the general intr mask 
+			 * register 
+			 */
 			writeq(DISABLE_ALL_INTRS, &bar0->rxdma_int_mask);
 			temp64 = readq(&bar0->general_int_mask);
 			val64 |= temp64;
@@ -962,9 +1175,11 @@
 			temp64 = readq(&bar0->general_int_mask);
 			temp64 &= ~((u64) val64);
 			writeq(temp64, &bar0->general_int_mask);
-			/* All MAC block error interrupts are disabled for now 
+			/* 
+			 * All MAC block error interrupts are disabled for now 
 			 * except the link status change interrupt.
-			 * TODO*/
+			 * TODO
+			 */
 			val64 = MAC_INT_STATUS_RMAC_INT;
 			temp64 = readq(&bar0->mac_int_mask);
 			temp64 &= ~((u64) val64);
@@ -974,7 +1189,8 @@
 			val64 &= ~((u64) RMAC_LINK_STATE_CHANGE_INT);
 			writeq(val64, &bar0->mac_rmac_err_mask);
 		} else if (flag == DISABLE_INTRS) {
-			/*  Disable MAC Intrs in the general intr mask register 
+			/*  
+			 * Disable MAC Intrs in the general intr mask register 
 			 */
 			writeq(DISABLE_ALL_INTRS, &bar0->mac_int_mask);
 			writeq(DISABLE_ALL_INTRS,
@@ -993,11 +1209,14 @@
 			temp64 = readq(&bar0->general_int_mask);
 			temp64 &= ~((u64) val64);
 			writeq(temp64, &bar0->general_int_mask);
-			/* All XGXS block error interrupts are disabled for now
-			 *  TODO */
+			/* 
+			 * All XGXS block error interrupts are disabled for now
+			 * TODO 
+			 */
 			writeq(DISABLE_ALL_INTRS, &bar0->xgxs_int_mask);
 		} else if (flag == DISABLE_INTRS) {
-			/*  Disable MC Intrs in the general intr mask register 
+			/*  
+			 * Disable MC Intrs in the general intr mask register 
 			 */
 			writeq(DISABLE_ALL_INTRS, &bar0->xgxs_int_mask);
 			temp64 = readq(&bar0->general_int_mask);
@@ -1013,11 +1232,14 @@
 			temp64 = readq(&bar0->general_int_mask);
 			temp64 &= ~((u64) val64);
 			writeq(temp64, &bar0->general_int_mask);
-			/* All MC block error interrupts are disabled for now
-			 * TODO */
+			/* 
+			 * All MC block error interrupts are disabled for now
+			 * TODO 
+			 */
 			writeq(DISABLE_ALL_INTRS, &bar0->mc_int_mask);
 		} else if (flag == DISABLE_INTRS) {
-			/*  Disable MC Intrs in the general intr mask register
+			/*
+			 * Disable MC Intrs in the general intr mask register
 			 */
 			writeq(DISABLE_ALL_INTRS, &bar0->mc_int_mask);
 			temp64 = readq(&bar0->general_int_mask);
@@ -1034,15 +1256,15 @@
 			temp64 = readq(&bar0->general_int_mask);
 			temp64 &= ~((u64) val64);
 			writeq(temp64, &bar0->general_int_mask);
-			/* Enable all the Tx side interrupts */
-			writeq(0x0, &bar0->tx_traffic_mask);	/* '0' Enables 
-								 * all 64 TX 
-								 * interrupt 
-								 * levels.
-								 */
+			/* 
+			 * Enable all the Tx side interrupts
+			 * writing 0 Enables all 64 TX interrupt levels 
+			 */
+			writeq(0x0, &bar0->tx_traffic_mask);
 		} else if (flag == DISABLE_INTRS) {
-			/*  Disable Tx Traffic Intrs in the general intr mask 
-			 *  register.
+			/* 
+			 * Disable Tx Traffic Intrs in the general intr mask 
+			 * register.
 			 */
 			writeq(DISABLE_ALL_INTRS, &bar0->tx_traffic_mask);
 			temp64 = readq(&bar0->general_int_mask);
@@ -1058,14 +1280,12 @@
 			temp64 = readq(&bar0->general_int_mask);
 			temp64 &= ~((u64) val64);
 			writeq(temp64, &bar0->general_int_mask);
-			writeq(0x0, &bar0->rx_traffic_mask);	/* '0' Enables 
-								 * all 8 RX 
-								 * interrupt 
-								 * levels.
-								 */
+			/* writing 0 Enables all 8 RX interrupt levels */
+			writeq(0x0, &bar0->rx_traffic_mask);
 		} else if (flag == DISABLE_INTRS) {
-			/*  Disable Rx Traffic Intrs in the general intr mask 
-			 *  register.
+			/*  
+			 * Disable Rx Traffic Intrs in the general intr mask 
+			 * register.
 			 */
 			writeq(DISABLE_ALL_INTRS, &bar0->rx_traffic_mask);
 			temp64 = readq(&bar0->general_int_mask);
@@ -1075,17 +1295,19 @@
 	}
 }
 
-/*  
- *  Input Arguments: 
- *   val64 - Value read from adapter status register.
- *   flag - indicates if the adapter enable bit was ever written once before.
- *  Return Value: 
- *   void.
- *  Description: 
- *   Returns whether the H/W is ready to go or not. Depending on whether 
- *   adapter enable bit was written or not the comparison differs and the 
- *   calling function passes the input argument flag to indicate this.
+/**  
+ *  verify_xena_quiescence - Checks whether the H/W is ready 
+ *  @val64 :  Value read from adapter status register.
+ *  @flag : indicates if the adapter enable bit was ever written once
+ *  before.
+ *  Description: Returns whether the H/W is ready to go or not. Depending
+ *  on whether adapter enable bit was written or not the comparison 
+ *  differs and the calling function passes the input argument flag to
+ *  indicate this.
+ *  Return: 1 If xena is quiescence 
+ *          0 If Xena is not quiescence
  */
+
 static int verify_xena_quiescence(u64 val64, int flag)
 {
 	int ret = 0;
@@ -1122,13 +1344,17 @@
 	return ret;
 }
 
-/* 
+/**
+ * fix_mac_address -  Fix for Mac addr problem on Alpha platforms
+ * @sp: Pointer to device specifc structure
+ * Description : 
  * New procedure to clear mac address reading  problems on Alpha platforms
  *
  */
-void FixMacAddress(nic_t * sp)
+
+void fix_mac_address(nic_t * sp)
 {
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0;
+	XENA_dev_config_t __iomem *bar0 = sp->bar0;
 	u64 val64;
 	int i = 0;
 
@@ -1138,21 +1364,22 @@
 	}
 }
 
-/*  
- *  Input Arguments: 
- *  device private variable.
- *  Return Value: 
- *  SUCCESS on success and -1 on failure.
+/**
+ *  start_nic - Turns the device on   
+ *  @nic : device private variable.
  *  Description: 
- *  This function actually turns the device on. Before this 
- *  function is called, all Registers are configured from their reset states 
+ *  This function actually turns the device on. Before this  function is 
+ *  called,all Registers are configured from their reset states 
  *  and shared memory is allocated but the NIC is still quiescent. On 
  *  calling this function, the device interrupts are cleared and the NIC is
  *  literally switched on by writing into the adapter control register.
+ *  Return Value: 
+ *  SUCCESS on success and -1 on failure.
  */
-static int startNic(struct s2io_nic *nic)
+
+static int start_nic(struct s2io_nic *nic)
 {
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+	XENA_dev_config_t __iomem *bar0 = nic->bar0;
 	struct net_device *dev = nic->dev;
 	register u64 val64 = 0;
 	u16 interruptible, i;
@@ -1164,22 +1391,34 @@
 	config = &nic->config;
 
 	/*  PRC Initialization and configuration */
-	for (i = 0; i < config->RxRingNum; i++) {
+	for (i = 0; i < config->rx_ring_num; i++) {
 		writeq((u64) nic->rx_blocks[i][0].block_dma_addr,
 		       &bar0->prc_rxd0_n[i]);
 
 		val64 = readq(&bar0->prc_ctrl_n[i]);
+#ifndef CONFIG_2BUFF_MODE
 		val64 |= PRC_CTRL_RC_ENABLED;
+#else
+		val64 |= PRC_CTRL_RC_ENABLED | PRC_CTRL_RING_MODE_3;
+#endif
 		writeq(val64, &bar0->prc_ctrl_n[i]);
 	}
 
-	/* Enabling MC-RLDRAM. After enabling the device, we timeout
+#ifdef CONFIG_2BUFF_MODE
+	/* Enabling 2 buffer mode by writing into Rx_pa_cfg reg. */
+	val64 = readq(&bar0->rx_pa_cfg);
+	val64 |= RX_PA_CFG_IGNORE_L2_ERR;
+	writeq(val64, &bar0->rx_pa_cfg);
+#endif
+
+	/* 
+	 * Enabling MC-RLDRAM. After enabling the device, we timeout
 	 * for around 100ms, which is approximately the time required
 	 * for the device to be ready for operation.
 	 */
 	val64 = readq(&bar0->mc_rldram_mrs);
 	val64 |= MC_RLDRAM_QUEUE_SIZE_ENABLE | MC_RLDRAM_MRS_ENABLE;
-	writeq(val64, &bar0->mc_rldram_mrs);
+	SPECIAL_REG_WRITE(val64, &bar0->mc_rldram_mrs, UF);
 	val64 = readq(&bar0->mc_rldram_mrs);
 
 	set_current_state(TASK_UNINTERRUPTIBLE);
@@ -1190,14 +1429,16 @@
 	val64 &= ~ADAPTER_ECC_EN;
 	writeq(val64, &bar0->adapter_control);
 
-	/* Clearing any possible Link state change interrupts that 
+	/* 
+	 * Clearing any possible Link state change interrupts that 
 	 * could have popped up just before Enabling the card.
 	 */
 	val64 = readq(&bar0->mac_rmac_err_reg);
 	if (val64)
 		writeq(val64, &bar0->mac_rmac_err_reg);
 
-	/* Verify if the device is ready to be enabled, if so enable 
+	/* 
+	 * Verify if the device is ready to be enabled, if so enable 
 	 * it.
 	 */
 	val64 = readq(&bar0->adapter_status);
@@ -1211,9 +1452,10 @@
 	/*  Enable select interrupts */
 	interruptible = TX_TRAFFIC_INTR | RX_TRAFFIC_INTR | TX_MAC_INTR |
 	    RX_MAC_INTR;
-	en_dis_able_NicIntrs(nic, interruptible, ENABLE_INTRS);
+	en_dis_able_nic_intrs(nic, interruptible, ENABLE_INTRS);
 
-	/* With some switches, link might be already up at this point.
+	/* 
+	 * With some switches, link might be already up at this point.
 	 * Because of this weird behavior, when we enable laser, 
 	 * we may not get link. We need to handle this. We cannot 
 	 * figure out which switch is misbehaving. So we are forced to 
@@ -1232,92 +1474,90 @@
 		val64 |= 0x0000800000000000ULL;
 		writeq(val64, &bar0->gpio_control);
 		val64 = 0x0411040400000000ULL;
-		writeq(val64, (void *) ((u8 *) bar0 + 0x2700));
+		writeq(val64, (void __iomem *) bar0 + 0x2700);
 	}
 
 	/* 
+	 * Don't see link state interrupts on certain switches, so 
+	 * directly scheduling a link state task from here.
+	 */
+	schedule_work(&nic->set_link_task);
+
+	/* 
 	 * Here we are performing soft reset on XGXS to 
 	 * force link down. Since link is already up, we will get
 	 * link state change interrupt after this reset
 	 */
-	writeq(0x8007051500000000ULL, &bar0->dtx_control);
+	SPECIAL_REG_WRITE(0x80010515001E0000ULL, &bar0->dtx_control, UF);
 	val64 = readq(&bar0->dtx_control);
-	writeq(0x80070515000000E0ULL, &bar0->dtx_control);
+	udelay(50);
+	SPECIAL_REG_WRITE(0x80010515001E00E0ULL, &bar0->dtx_control, UF);
 	val64 = readq(&bar0->dtx_control);
-	writeq(0x80070515001F00E4ULL, &bar0->dtx_control);
+	udelay(50);
+	SPECIAL_REG_WRITE(0x80070515001F00E4ULL, &bar0->dtx_control, UF);
 	val64 = readq(&bar0->dtx_control);
+	udelay(50);
 
 	return SUCCESS;
 }
 
-/*  
- *  Input Arguments: 
- *   nic - device private variable.
- *  Return Value: 
- *   void.
+/** 
+ *  free_tx_buffers - Free all queued Tx buffers 
+ *  @nic : device private variable.
  *  Description: 
- *   Free all queued Tx buffers.
- */
-void freeTxBuffers(struct s2io_nic *nic)
+ *  Free all queued Tx buffers.
+ *  Return Value: void 
+*/
+
+void free_tx_buffers(struct s2io_nic *nic)
 {
 	struct net_device *dev = nic->dev;
 	struct sk_buff *skb;
 	TxD_t *txdp;
 	int i, j;
-#if DEBUG_ON
-	int cnt = 0;
-#endif
 	mac_info_t *mac_control;
 	struct config_param *config;
+	int cnt = 0;
 
 	mac_control = &nic->mac_control;
 	config = &nic->config;
 
-	for (i = 0; i < config->TxFIFONum; i++) {
-		for (j = 0; j < config->TxCfg[i].FifoLen - 1; j++) {
-			txdp = mac_control->txdl_start[i] +
-			    (config->MaxTxDs * j);
-
-			if (!(txdp->Control_1 & TXD_LIST_OWN_XENA)) {
-				/* If owned by host, ignore */
-				continue;
-			}
+	for (i = 0; i < config->tx_fifo_num; i++) {
+		for (j = 0; j < config->tx_cfg[i].fifo_len - 1; j++) {
+			txdp = (TxD_t *) nic->list_info[i][j].
+			    list_virt_addr;
 			skb =
 			    (struct sk_buff *) ((unsigned long) txdp->
 						Host_Control);
 			if (skb == NULL) {
-				DBG_PRINT(ERR_DBG, "%s: NULL skb ",
-					  dev->name);
-				DBG_PRINT(ERR_DBG, "in Tx Int\n");
-				return;
+				memset(txdp, 0, sizeof(TxD_t));
+				continue;
 			}
-#if DEBUG_ON
-			cnt++;
-#endif
 			dev_kfree_skb(skb);
 			memset(txdp, 0, sizeof(TxD_t));
+			cnt++;
 		}
-#if DEBUG_ON
 		DBG_PRINT(INTR_DBG,
 			  "%s:forcibly freeing %d skbs on FIFO%d\n",
 			  dev->name, cnt, i);
-#endif
+		mac_control->tx_curr_get_info[i].offset = 0;
+		mac_control->tx_curr_put_info[i].offset = 0;
 	}
 }
 
-/*  
- *  Input Arguments: 
- *   nic - device private variable.
- *  Return Value: 
+/**  
+ *   stop_nic -  To stop the nic  
+ *   @nic ; device private variable.
+ *   Description: 
+ *   This function does exactly the opposite of what the start_nic() 
+ *   function does. This function is called to stop the device.
+ *   Return Value:
  *   void.
- *  Description: 
- *   This function does exactly the opposite of what the startNic() 
- *   function does. This function is called to stop 
- *   the device.
  */
-static void stopNic(struct s2io_nic *nic)
+
+static void stop_nic(struct s2io_nic *nic)
 {
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+	XENA_dev_config_t __iomem *bar0 = nic->bar0;
 	register u64 val64 = 0;
 	u16 interruptible, i;
 	mac_info_t *mac_control;
@@ -1326,24 +1566,23 @@
 	mac_control = &nic->mac_control;
 	config = &nic->config;
 
-/*  Disable all interrupts */
+	/*  Disable all interrupts */
 	interruptible = TX_TRAFFIC_INTR | RX_TRAFFIC_INTR | TX_MAC_INTR |
 	    RX_MAC_INTR;
-	en_dis_able_NicIntrs(nic, interruptible, DISABLE_INTRS);
+	en_dis_able_nic_intrs(nic, interruptible, DISABLE_INTRS);
 
-/*  Disable PRCs */
-	for (i = 0; i < config->RxRingNum; i++) {
+	/*  Disable PRCs */
+	for (i = 0; i < config->rx_ring_num; i++) {
 		val64 = readq(&bar0->prc_ctrl_n[i]);
 		val64 &= ~((u64) PRC_CTRL_RC_ENABLED);
 		writeq(val64, &bar0->prc_ctrl_n[i]);
 	}
 }
 
-/*  
- *  Input Arguments: 
- *  device private variable
- *  Return Value: 
- *  SUCCESS on success or an appropriate -ve value on failure.
+/**  
+ *  fill_rx_buffers - Allocates the Rx side skbs 
+ *  @nic:  device private variable
+ *  @ring_no: ring number 
  *  Description: 
  *  The function allocates Rx side skbs and puts the physical
  *  address of these buffers into the RxD buffer pointers, so that the NIC
@@ -1354,9 +1593,13 @@
  *  3. Five buffer modes.
  *  Each mode defines how many fragments the received frame will be split 
  *  up into by the NIC. The frame is split into L3 header, L4 Header, 
- *  L4 payload in three buffer mode and in 5 buffer mode, L4 payload itself 
- *  is split into 3 fragments. As of now only single buffer mode is supported.
+ *  L4 payload in three buffer mode and in 5 buffer mode, L4 payload itself
+ *  is split into 3 fragments. As of now only single buffer mode is
+ *  supported.
+ *   Return Value:
+ *  SUCCESS on success or an appropriate -ve value on failure.
  */
+
 int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
 {
 	struct net_device *dev = nic->dev;
@@ -1369,19 +1612,22 @@
 	    atomic_read(&nic->rx_bufs_left[ring_no]);
 	mac_info_t *mac_control;
 	struct config_param *config;
+#ifdef CONFIG_2BUFF_MODE
+	RxD_t *rxdpnext;
+	int nextblk;
+	unsigned long tmp;
+	buffAdd_t *ba;
+	dma_addr_t rxdpphys;
+#endif
+#ifndef CONFIG_S2IO_NAPI
+	unsigned long flags;
+#endif
 
 	mac_control = &nic->mac_control;
 	config = &nic->config;
 
-	if (frame_len[ring_no]) {
-		if (frame_len[ring_no] > dev->mtu)
-			dev->mtu = frame_len[ring_no];
-		size = frame_len[ring_no] + HEADER_ETHERNET_II_802_3_SIZE +
-		    HEADER_802_2_SIZE + HEADER_SNAP_SIZE;
-	} else {
-		size = dev->mtu + HEADER_ETHERNET_II_802_3_SIZE +
-		    HEADER_802_2_SIZE + HEADER_SNAP_SIZE;
-	}
+	size = dev->mtu + HEADER_ETHERNET_II_802_3_SIZE +
+	    HEADER_802_2_SIZE + HEADER_SNAP_SIZE;
 
 	while (alloc_tab < alloc_cnt) {
 		block_no = mac_control->rx_curr_put_info[ring_no].
@@ -1390,8 +1636,13 @@
 		    block_index;
 		off = mac_control->rx_curr_put_info[ring_no].offset;
 		off1 = mac_control->rx_curr_get_info[ring_no].offset;
+#ifndef CONFIG_2BUFF_MODE
 		offset = block_no * (MAX_RXDS_PER_BLOCK + 1) + off;
 		offset1 = block_no1 * (MAX_RXDS_PER_BLOCK + 1) + off1;
+#else
+		offset = block_no * (MAX_RXDS_PER_BLOCK) + off;
+		offset1 = block_no1 * (MAX_RXDS_PER_BLOCK) + off1;
+#endif
 
 		rxdp = nic->rx_blocks[ring_no][block_no].
 		    block_virt_addr + off;
@@ -1400,7 +1651,7 @@
 			DBG_PRINT(INTR_DBG, " info equated\n");
 			goto end;
 		}
-
+#ifndef	CONFIG_2BUFF_MODE
 		if (rxdp->Control_1 == END_OF_BLOCK) {
 			mac_control->rx_curr_put_info[ring_no].
 			    block_index++;
@@ -1412,25 +1663,86 @@
 			off %= (MAX_RXDS_PER_BLOCK + 1);
 			mac_control->rx_curr_put_info[ring_no].offset =
 			    off;
-			/*rxdp = nic->rx_blocks[ring_no][block_no].
-			   block_virt_addr + off; */
 			rxdp = (RxD_t *) ((unsigned long) rxdp->Control_2);
 			DBG_PRINT(INTR_DBG, "%s: Next block at: %p\n",
 				  dev->name, rxdp);
 		}
+#ifndef CONFIG_S2IO_NAPI
+		spin_lock_irqsave(&nic->put_lock, flags);
+		nic->put_pos[ring_no] =
+		    (block_no * (MAX_RXDS_PER_BLOCK + 1)) + off;
+		spin_unlock_irqrestore(&nic->put_lock, flags);
+#endif
+#else
+		if (rxdp->Host_Control == END_OF_BLOCK) {
+			mac_control->rx_curr_put_info[ring_no].
+			    block_index++;
+			mac_control->rx_curr_put_info[ring_no].
+			    block_index %= nic->block_count[ring_no];
+			block_no = mac_control->rx_curr_put_info
+			    [ring_no].block_index;
+			off = 0;
+			DBG_PRINT(INTR_DBG, "%s: block%d at: 0x%llx\n",
+				  dev->name, block_no,
+				  (unsigned long long) rxdp->Control_1);
+			mac_control->rx_curr_put_info[ring_no].offset =
+			    off;
+			rxdp = nic->rx_blocks[ring_no][block_no].
+			    block_virt_addr;
+		}
+#ifndef CONFIG_S2IO_NAPI
+		spin_lock_irqsave(&nic->put_lock, flags);
+		nic->put_pos[ring_no] = (block_no *
+					 (MAX_RXDS_PER_BLOCK + 1)) + off;
+		spin_unlock_irqrestore(&nic->put_lock, flags);
+#endif
+#endif
 
-		if (rxdp->Control_1 & RXD_OWN_XENA) {
+#ifndef	CONFIG_2BUFF_MODE
+		if (rxdp->Control_1 & RXD_OWN_XENA)
+#else
+		if (rxdp->Control_2 & BIT(0))
+#endif
+		{
 			mac_control->rx_curr_put_info[ring_no].
 			    offset = off;
 			goto end;
 		}
+#ifdef	CONFIG_2BUFF_MODE
+		/* 
+		 * RxDs Spanning cache lines will be replenished only 
+		 * if the succeeding RxD is also owned by Host. It 
+		 * will always be the ((8*i)+3) and ((8*i)+6) 
+		 * descriptors for the 48 byte descriptor. The offending 
+		 * decsriptor is of-course the 3rd descriptor.
+		 */
+		rxdpphys = nic->rx_blocks[ring_no][block_no].
+		    block_dma_addr + (off * sizeof(RxD_t));
+		if (((u64) (rxdpphys)) % 128 > 80) {
+			rxdpnext = nic->rx_blocks[ring_no][block_no].
+			    block_virt_addr + (off + 1);
+			if (rxdpnext->Host_Control == END_OF_BLOCK) {
+				nextblk = (block_no + 1) %
+				    (nic->block_count[ring_no]);
+				rxdpnext = nic->rx_blocks[ring_no]
+				    [nextblk].block_virt_addr;
+			}
+			if (rxdpnext->Control_2 & BIT(0))
+				goto end;
+		}
+#endif
 
+#ifndef	CONFIG_2BUFF_MODE
 		skb = dev_alloc_skb(size + NET_IP_ALIGN);
+#else
+		skb = dev_alloc_skb(dev->mtu + ALIGN_SIZE + BUF0_LEN + 4);
+#endif
 		if (!skb) {
 			DBG_PRINT(ERR_DBG, "%s: Out of ", dev->name);
 			DBG_PRINT(ERR_DBG, "memory to allocate SKBs\n");
 			return -ENOMEM;
 		}
+#ifndef	CONFIG_2BUFF_MODE
 		skb_reserve(skb, NET_IP_ALIGN);
 		memset(rxdp, 0, sizeof(RxD_t));
 		rxdp->Buffer0_ptr = pci_map_single
@@ -1442,6 +1754,35 @@
 		off++;
 		off %= (MAX_RXDS_PER_BLOCK + 1);
 		mac_control->rx_curr_put_info[ring_no].offset = off;
+#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;
+
+		memset(rxdp, 0, sizeof(RxD_t));
+		rxdp->Buffer2_ptr = pci_map_single
+		    (nic->pdev, skb->data, dev->mtu + BUF0_LEN + 4,
+		     PCI_DMA_FROMDEVICE);
+		rxdp->Buffer0_ptr =
+		    pci_map_single(nic->pdev, ba->ba_0, BUF0_LEN,
+				   PCI_DMA_FROMDEVICE);
+		rxdp->Buffer1_ptr =
+		    pci_map_single(nic->pdev, ba->ba_1, BUF1_LEN,
+				   PCI_DMA_FROMDEVICE);
+
+		rxdp->Control_2 = SET_BUFFER2_SIZE(dev->mtu + 4);
+		rxdp->Control_2 |= SET_BUFFER0_SIZE(BUF0_LEN);
+		rxdp->Control_2 |= SET_BUFFER1_SIZE(1);	/* dummy. */
+		rxdp->Control_2 |= BIT(0);	/* Set Buffer_Empty bit. */
+		rxdp->Host_Control = (u64) ((unsigned long) (skb));
+		rxdp->Control_1 |= RXD_OWN_XENA;
+		off++;
+		mac_control->rx_curr_put_info[ring_no].offset = off;
+#endif
 		atomic_inc(&nic->rx_bufs_left[ring_no]);
 		alloc_tab++;
 	}
@@ -1450,15 +1791,16 @@
 	return SUCCESS;
 }
 
-/*  
- *  Input Arguments: 
- *  device private variable.
- *  Return Value: 
- *  NONE.
+/**
+ *  free_rx_buffers - Frees all Rx buffers   
+ *  @sp: device private variable.
  *  Description: 
  *  This function will free all Rx buffers allocated by host.
+ *  Return Value:
+ *  NONE.
  */
-static void freeRxBuffers(struct s2io_nic *sp)
+
+static void free_rx_buffers(struct s2io_nic *sp)
 {
 	struct net_device *dev = sp->dev;
 	int i, j, blk = 0, off, buf_cnt = 0;
@@ -1466,15 +1808,19 @@
 	struct sk_buff *skb;
 	mac_info_t *mac_control;
 	struct config_param *config;
+#ifdef CONFIG_2BUFF_MODE
+	buffAdd_t *ba;
+#endif
 
 	mac_control = &sp->mac_control;
 	config = &sp->config;
 
-	for (i = 0; i < config->RxRingNum; i++) {
-		for (j = 0, blk = 0; j < config->RxCfg[i].NumRxd; j++) {
+	for (i = 0; i < config->rx_ring_num; i++) {
+		for (j = 0, blk = 0; j < config->rx_cfg[i].num_rxd; j++) {
 			off = j % (MAX_RXDS_PER_BLOCK + 1);
 			rxdp = sp->rx_blocks[i][blk].block_virt_addr + off;
 
+#ifndef CONFIG_2BUFF_MODE
 			if (rxdp->Control_1 == END_OF_BLOCK) {
 				rxdp =
 				    (RxD_t *) ((unsigned long) rxdp->
@@ -1482,11 +1828,23 @@
 				j++;
 				blk++;
 			}
+#else
+			if (rxdp->Host_Control == END_OF_BLOCK) {
+				blk++;
+				continue;
+			}
+#endif
+
+			if (!(rxdp->Control_1 & RXD_OWN_XENA)) {
+				memset(rxdp, 0, sizeof(RxD_t));
+				continue;
+			}
 
 			skb =
 			    (struct sk_buff *) ((unsigned long) rxdp->
 						Host_Control);
 			if (skb) {
+#ifndef CONFIG_2BUFF_MODE
 				pci_unmap_single(sp->pdev, (dma_addr_t)
 						 rxdp->Buffer0_ptr,
 						 dev->mtu +
@@ -1494,6 +1852,21 @@
 						 + HEADER_802_2_SIZE +
 						 HEADER_SNAP_SIZE,
 						 PCI_DMA_FROMDEVICE);
+#else
+				ba = &sp->ba[i][blk][off];
+				pci_unmap_single(sp->pdev, (dma_addr_t)
+						 rxdp->Buffer0_ptr,
+						 BUF0_LEN,
+						 PCI_DMA_FROMDEVICE);
+				pci_unmap_single(sp->pdev, (dma_addr_t)
+						 rxdp->Buffer1_ptr,
+						 BUF1_LEN,
+						 PCI_DMA_FROMDEVICE);
+				pci_unmap_single(sp->pdev, (dma_addr_t)
+						 rxdp->Buffer2_ptr,
+						 dev->mtu + BUF0_LEN + 4,
+						 PCI_DMA_FROMDEVICE);
+#endif
 				dev_kfree_skb(skb);
 				atomic_dec(&sp->rx_bufs_left[i]);
 				buf_cnt++;
@@ -1510,32 +1883,38 @@
 	}
 }
 
-/*
- *  Input Argument: 
- *   dev - pointer to the device structure.
- *   budget - The number of packets that were budgeted to be processed during
- *   one pass through the 'Poll" function.
- *  Return value:
- *   0 on success and 1 if there are No Rx packets to be processed.
- *  Description:
- *   Comes into picture only if NAPI support has been incorporated. It does
- *   the same thing that rxIntrHandler does, but not in a interrupt context
- *   also It will process only a given number of packets.
+/**
+ * s2io_poll - Rx interrupt handler for NAPI support
+ * @dev : pointer to the device structure.
+ * @budget : The number of packets that were budgeted to be processed 
+ * during  one pass through the 'Poll" function.
+ * Description:
+ * Comes into picture only if NAPI support has been incorporated. It does
+ * the same thing that rx_intr_handler does, but not in a interrupt context
+ * also It will process only a given number of packets.
+ * Return value:
+ * 0 on success and 1 if there are No Rx packets to be processed.
  */
+
 #ifdef CONFIG_S2IO_NAPI
 static int s2io_poll(struct net_device *dev, int *budget)
 {
 	nic_t *nic = dev->priv;
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+	XENA_dev_config_t __iomem *bar0 = nic->bar0;
 	int pkts_to_process = *budget, pkt_cnt = 0;
 	register u64 val64 = 0;
-	rx_curr_get_info_t offset_info;
-	int i, block_no;
+	rx_curr_get_info_t get_info, put_info;
+	int i, get_block, put_block, get_offset, put_offset, ring_bufs;
+#ifndef CONFIG_2BUFF_MODE
 	u16 val16, cksum;
+#endif
 	struct sk_buff *skb;
 	RxD_t *rxdp;
 	mac_info_t *mac_control;
 	struct config_param *config;
+#ifdef CONFIG_2BUFF_MODE
+	buffAdd_t *ba;
+#endif
 
 	mac_control = &nic->mac_control;
 	config = &nic->config;
@@ -1546,30 +1925,42 @@
 	val64 = readq(&bar0->rx_traffic_int);
 	writeq(val64, &bar0->rx_traffic_int);
 
-	for (i = 0; i < config->RxRingNum; i++) {
-		if (--pkts_to_process < 0) {
-			goto no_rx;
-		}
-		offset_info = mac_control->rx_curr_get_info[i];
-		block_no = offset_info.block_index;
-		rxdp = nic->rx_blocks[i][block_no].block_virt_addr +
-		    offset_info.offset;
-		while (!(rxdp->Control_1 & RXD_OWN_XENA)) {
+	for (i = 0; i < config->rx_ring_num; i++) {
+		get_info = mac_control->rx_curr_get_info[i];
+		get_block = get_info.block_index;
+		put_info = mac_control->rx_curr_put_info[i];
+		put_block = put_info.block_index;
+		ring_bufs = config->rx_cfg[i].num_rxd;
+		rxdp = nic->rx_blocks[i][get_block].block_virt_addr +
+		    get_info.offset;
+#ifndef	CONFIG_2BUFF_MODE
+		get_offset = (get_block * (MAX_RXDS_PER_BLOCK + 1)) +
+		    get_info.offset;
+		put_offset = (put_block * (MAX_RXDS_PER_BLOCK + 1)) +
+		    put_info.offset;
+		while ((!(rxdp->Control_1 & RXD_OWN_XENA)) &&
+		       (((get_offset + 1) % ring_bufs) != put_offset)) {
+			if (--pkts_to_process < 0) {
+				goto no_rx;
+			}
 			if (rxdp->Control_1 == END_OF_BLOCK) {
 				rxdp =
 				    (RxD_t *) ((unsigned long) rxdp->
 					       Control_2);
-				offset_info.offset++;
-				offset_info.offset %=
+				get_info.offset++;
+				get_info.offset %=
 				    (MAX_RXDS_PER_BLOCK + 1);
-				block_no++;
-				block_no %= nic->block_count[i];
+				get_block++;
+				get_block %= nic->block_count[i];
 				mac_control->rx_curr_get_info[i].
-				    offset = offset_info.offset;
+				    offset = get_info.offset;
 				mac_control->rx_curr_get_info[i].
-				    block_index = block_no;
+				    block_index = get_block;
 				continue;
 			}
+			get_offset =
+			    (get_block * (MAX_RXDS_PER_BLOCK + 1)) +
+			    get_info.offset;
 			skb =
 			    (struct sk_buff *) ((unsigned long) rxdp->
 						Host_Control);
@@ -1577,7 +1968,7 @@
 				DBG_PRINT(ERR_DBG, "%s: The skb is ",
 					  dev->name);
 				DBG_PRINT(ERR_DBG, "Null in Rx Intr\n");
-				return 0;
+				goto no_rx;
 			}
 			val64 = RXD_GET_BUFFER0_SIZE(rxdp->Control_2);
 			val16 = (u16) (val64 >> 48);
@@ -1589,97 +1980,184 @@
 					 HEADER_802_2_SIZE +
 					 HEADER_SNAP_SIZE,
 					 PCI_DMA_FROMDEVICE);
-			rxOsmHandler(nic, val16, rxdp, i);
+			rx_osm_handler(nic, val16, rxdp, i);
 			pkt_cnt++;
-			offset_info.offset++;
-			offset_info.offset %= (MAX_RXDS_PER_BLOCK + 1);
+			get_info.offset++;
+			get_info.offset %= (MAX_RXDS_PER_BLOCK + 1);
 			rxdp =
-			    nic->rx_blocks[i][block_no].block_virt_addr +
-			    offset_info.offset;
+			    nic->rx_blocks[i][get_block].block_virt_addr +
+			    get_info.offset;
+			mac_control->rx_curr_get_info[i].offset =
+			    get_info.offset;
+		}
+#else
+		get_offset = (get_block * (MAX_RXDS_PER_BLOCK + 1)) +
+		    get_info.offset;
+		put_offset = (put_block * (MAX_RXDS_PER_BLOCK + 1)) +
+		    put_info.offset;
+		while (((!(rxdp->Control_1 & RXD_OWN_XENA)) &&
+			!(rxdp->Control_2 & BIT(0))) &&
+		       (((get_offset + 1) % ring_bufs) != put_offset)) {
+			if (--pkts_to_process < 0) {
+				goto no_rx;
+			}
+			skb = (struct sk_buff *) ((unsigned long)
+						  rxdp->Host_Control);
+			if (skb == NULL) {
+				DBG_PRINT(ERR_DBG, "%s: The skb is ",
+					  dev->name);
+				DBG_PRINT(ERR_DBG, "Null in Rx Intr\n");
+				goto no_rx;
+			}
+
+			pci_unmap_single(nic->pdev, (dma_addr_t)
+					 rxdp->Buffer0_ptr,
+					 BUF0_LEN, PCI_DMA_FROMDEVICE);
+			pci_unmap_single(nic->pdev, (dma_addr_t)
+					 rxdp->Buffer1_ptr,
+					 BUF1_LEN, PCI_DMA_FROMDEVICE);
+			pci_unmap_single(nic->pdev, (dma_addr_t)
+					 rxdp->Buffer2_ptr,
+					 dev->mtu + BUF0_LEN + 4,
+					 PCI_DMA_FROMDEVICE);
+			ba = &nic->ba[i][get_block][get_info.offset];
+
+			rx_osm_handler(nic, rxdp, i, ba);
+
+			get_info.offset++;
 			mac_control->rx_curr_get_info[i].offset =
-			    offset_info.offset;
+			    get_info.offset;
+			rxdp =
+			    nic->rx_blocks[i][get_block].block_virt_addr +
+			    get_info.offset;
+
+			if (get_info.offset &&
+			    (!(get_info.offset % MAX_RXDS_PER_BLOCK))) {
+				get_info.offset = 0;
+				mac_control->rx_curr_get_info[i].
+				    offset = get_info.offset;
+				get_block++;
+				get_block %= nic->block_count[i];
+				mac_control->rx_curr_get_info[i].
+				    block_index = get_block;
+				rxdp =
+				    nic->rx_blocks[i][get_block].
+				    block_virt_addr;
+			}
+			get_offset =
+			    (get_block * (MAX_RXDS_PER_BLOCK + 1)) +
+			    get_info.offset;
+			pkt_cnt++;
 		}
+#endif
 	}
 	if (!pkt_cnt)
 		pkt_cnt = 1;
 
-	for (i = 0; i < config->RxRingNum; i++)
-		fill_rx_buffers(nic, i);
-
 	dev->quota -= pkt_cnt;
 	*budget -= pkt_cnt;
 	netif_rx_complete(dev);
 
-/* Re enable the Rx interrupts. */
-	en_dis_able_NicIntrs(nic, RX_TRAFFIC_INTR, ENABLE_INTRS);
+	for (i = 0; i < config->rx_ring_num; i++) {
+		if (fill_rx_buffers(nic, i) == -ENOMEM) {
+			DBG_PRINT(ERR_DBG, "%s:Out of memory", dev->name);
+			DBG_PRINT(ERR_DBG, " in Rx Poll!!\n");
+			break;
+		}
+	}
+	/* Re enable the Rx interrupts. */
+	en_dis_able_nic_intrs(nic, RX_TRAFFIC_INTR, ENABLE_INTRS);
 	return 0;
 
       no_rx:
-	for (i = 0; i < config->RxRingNum; i++)
-		fill_rx_buffers(nic, i);
 	dev->quota -= pkt_cnt;
 	*budget -= pkt_cnt;
+
+	for (i = 0; i < config->rx_ring_num; i++) {
+		if (fill_rx_buffers(nic, i) == -ENOMEM) {
+			DBG_PRINT(ERR_DBG, "%s:Out of memory", dev->name);
+			DBG_PRINT(ERR_DBG, " in Rx Poll!!\n");
+			break;
+		}
+	}
 	return 1;
 }
 #else
-/*  
- *  Input Arguments: 
- *  device private variable.
- *  Return Value: 
- *  NONE.
+/**  
+ *  rx_intr_handler - Rx interrupt handler
+ *  @nic: device private variable.
  *  Description: 
- * If the interrupt is because of a received frame or if the 
- *  receive ring contains fresh as yet un-processed frames, this function is
+ *  If the interrupt is because of a received frame or if the 
+ *  receive ring contains fresh as yet un-processed frames,this function is
  *  called. It picks out the RxD at which place the last Rx processing had 
  *  stopped and sends the skb to the OSM's Rx handler and then increments 
  *  the offset.
+ *  Return Value:
+ *  NONE.
  */
-static void rxIntrHandler(struct s2io_nic *nic)
+
+static void rx_intr_handler(struct s2io_nic *nic)
 {
 	struct net_device *dev = (struct net_device *) nic->dev;
 	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
-	rx_curr_get_info_t offset_info;
+	rx_curr_get_info_t get_info, put_info;
 	RxD_t *rxdp;
 	struct sk_buff *skb;
+#ifndef CONFIG_2BUFF_MODE
 	u16 val16, cksum;
+#endif
 	register u64 val64 = 0;
-	int i, block_no;
+	int get_block, get_offset, put_block, put_offset, ring_bufs;
+	int i, pkt_cnt = 0;
 	mac_info_t *mac_control;
 	struct config_param *config;
+#ifdef CONFIG_2BUFF_MODE
+	buffAdd_t *ba;
+#endif
 
 	mac_control = &nic->mac_control;
 	config = &nic->config;
 
-#if DEBUG_ON
-	nic->rxint_cnt++;
-#endif
-
-/* rx_traffic_int reg is an R1 register, hence we read and write back 
- * the samevalue in the register to clear it.
- */
+	/* 
+	 * rx_traffic_int reg is an R1 register, hence we read and write back 
+	 * the samevalue in the register to clear it.
+	 */
 	val64 = readq(&bar0->rx_traffic_int);
 	writeq(val64, &bar0->rx_traffic_int);
 
-	for (i = 0; i < config->RxRingNum; i++) {
-		offset_info = mac_control->rx_curr_get_info[i];
-		block_no = offset_info.block_index;
-		rxdp = nic->rx_blocks[i][block_no].block_virt_addr +
-		    offset_info.offset;
-		while (!(rxdp->Control_1 & RXD_OWN_XENA)) {
+	for (i = 0; i < config->rx_ring_num; i++) {
+		get_info = mac_control->rx_curr_get_info[i];
+		get_block = get_info.block_index;
+		put_info = mac_control->rx_curr_put_info[i];
+		put_block = put_info.block_index;
+		ring_bufs = config->rx_cfg[i].num_rxd;
+		rxdp = nic->rx_blocks[i][get_block].block_virt_addr +
+		    get_info.offset;
+#ifndef	CONFIG_2BUFF_MODE
+		get_offset = (get_block * (MAX_RXDS_PER_BLOCK + 1)) +
+		    get_info.offset;
+		spin_lock(&nic->put_lock);
+		put_offset = nic->put_pos[i];
+		spin_unlock(&nic->put_lock);
+		while ((!(rxdp->Control_1 & RXD_OWN_XENA)) &&
+		       (((get_offset + 1) % ring_bufs) != put_offset)) {
 			if (rxdp->Control_1 == END_OF_BLOCK) {
 				rxdp = (RxD_t *) ((unsigned long)
 						  rxdp->Control_2);
-				offset_info.offset++;
-				offset_info.offset %=
+				get_info.offset++;
+				get_info.offset %=
 				    (MAX_RXDS_PER_BLOCK + 1);
-				block_no++;
-				block_no %= nic->block_count[i];
+				get_block++;
+				get_block %= nic->block_count[i];
 				mac_control->rx_curr_get_info[i].
-				    offset = offset_info.offset;
+				    offset = get_info.offset;
 				mac_control->rx_curr_get_info[i].
-				    block_index = block_no;
+				    block_index = get_block;
 				continue;
 			}
+			get_offset =
+			    (get_block * (MAX_RXDS_PER_BLOCK + 1)) +
+			    get_info.offset;
 			skb = (struct sk_buff *) ((unsigned long)
 						  rxdp->Host_Control);
 			if (skb == NULL) {
@@ -1698,35 +2176,102 @@
 					 HEADER_802_2_SIZE +
 					 HEADER_SNAP_SIZE,
 					 PCI_DMA_FROMDEVICE);
-			rxOsmHandler(nic, val16, rxdp, i);
-			offset_info.offset++;
-			offset_info.offset %= (MAX_RXDS_PER_BLOCK + 1);
+			rx_osm_handler(nic, val16, rxdp, i);
+			get_info.offset++;
+			get_info.offset %= (MAX_RXDS_PER_BLOCK + 1);
 			rxdp =
-			    nic->rx_blocks[i][block_no].block_virt_addr +
-			    offset_info.offset;
+			    nic->rx_blocks[i][get_block].block_virt_addr +
+			    get_info.offset;
 			mac_control->rx_curr_get_info[i].offset =
-			    offset_info.offset;
+			    get_info.offset;
+			pkt_cnt++;
+			if ((indicate_max_pkts)
+			    && (pkt_cnt > indicate_max_pkts))
+				break;
 		}
+#else
+		get_offset = (get_block * (MAX_RXDS_PER_BLOCK + 1)) +
+		    get_info.offset;
+		spin_lock(&nic->put_lock);
+		put_offset = nic->put_pos[i];
+		spin_unlock(&nic->put_lock);
+		while (((!(rxdp->Control_1 & RXD_OWN_XENA)) &&
+			!(rxdp->Control_2 & BIT(0))) &&
+		       (((get_offset + 1) % ring_bufs) != put_offset)) {
+			skb = (struct sk_buff *) ((unsigned long)
+						  rxdp->Host_Control);
+			if (skb == NULL) {
+				DBG_PRINT(ERR_DBG, "%s: The skb is ",
+					  dev->name);
+				DBG_PRINT(ERR_DBG, "Null in Rx Intr\n");
+				return;
+			}
+
+			pci_unmap_single(nic->pdev, (dma_addr_t)
+					 rxdp->Buffer0_ptr,
+					 BUF0_LEN, PCI_DMA_FROMDEVICE);
+			pci_unmap_single(nic->pdev, (dma_addr_t)
+					 rxdp->Buffer1_ptr,
+					 BUF1_LEN, PCI_DMA_FROMDEVICE);
+			pci_unmap_single(nic->pdev, (dma_addr_t)
+					 rxdp->Buffer2_ptr,
+					 dev->mtu + BUF0_LEN + 4,
+					 PCI_DMA_FROMDEVICE);
+			ba = &nic->ba[i][get_block][get_info.offset];
+
+			rx_osm_handler(nic, rxdp, i, ba);
+
+			get_info.offset++;
+			mac_control->rx_curr_get_info[i].offset =
+			    get_info.offset;
+			rxdp =
+			    nic->rx_blocks[i][get_block].block_virt_addr +
+			    get_info.offset;
+
+			if (get_info.offset &&
+			    (!(get_info.offset % MAX_RXDS_PER_BLOCK))) {
+				get_info.offset = 0;
+				mac_control->rx_curr_get_info[i].
+				    offset = get_info.offset;
+				get_block++;
+				get_block %= nic->block_count[i];
+				mac_control->rx_curr_get_info[i].
+				    block_index = get_block;
+				rxdp =
+				    nic->rx_blocks[i][get_block].
+				    block_virt_addr;
+			}
+			get_offset =
+			    (get_block * (MAX_RXDS_PER_BLOCK + 1)) +
+			    get_info.offset;
+			pkt_cnt++;
+			if ((indicate_max_pkts)
+			    && (pkt_cnt > indicate_max_pkts))
+				break;
+		}
+#endif
+		if ((indicate_max_pkts) && (pkt_cnt > indicate_max_pkts))
+			break;
 	}
 }
 #endif
-
-/*  
- *  Input Arguments: 
- *  device private variable
- *  Return Value: 
- *  NONE
+/**  
+ *  tx_intr_handler - Transmit interrupt handler
+ *  @nic : device private variable
  *  Description: 
  *  If an interrupt was raised to indicate DMA complete of the 
- *  Tx packet, this function is called. It identifies the last TxD whose buffer
- *  was freed and frees all skbs whose data have already DMA'ed into the NICs
- *  internal memory.
+ *  Tx packet, this function is called. It identifies the last TxD 
+ *  whose buffer was freed and frees all skbs whose data have already 
+ *  DMA'ed into the NICs internal memory.
+ *  Return Value:
+ *  NONE
  */
-static void txIntrHandler(struct s2io_nic *nic)
+
+static void tx_intr_handler(struct s2io_nic *nic)
 {
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+	XENA_dev_config_t __iomem *bar0 = nic->bar0;
 	struct net_device *dev = (struct net_device *) nic->dev;
-	tx_curr_get_info_t offset_info, offset_info1;
+	tx_curr_get_info_t get_info, put_info;
 	struct sk_buff *skb;
 	TxD_t *txdlp;
 	register u64 val64 = 0;
@@ -1734,27 +2279,24 @@
 	u16 j, frg_cnt;
 	mac_info_t *mac_control;
 	struct config_param *config;
-#if DEBUG_ON
-	int cnt = 0;
-	nic->txint_cnt++;
-#endif
 
 	mac_control = &nic->mac_control;
 	config = &nic->config;
 
-	/* tx_traffic_int reg is an R1 register, hence we read and write 
+	/* 
+	 * tx_traffic_int reg is an R1 register, hence we read and write 
 	 * back the samevalue in the register to clear it.
 	 */
 	val64 = readq(&bar0->tx_traffic_int);
 	writeq(val64, &bar0->tx_traffic_int);
 
-	for (i = 0; i < config->TxFIFONum; i++) {
-		offset_info = mac_control->tx_curr_get_info[i];
-		offset_info1 = mac_control->tx_curr_put_info[i];
-		txdlp = mac_control->txdl_start[i] +
-		    (config->MaxTxDs * offset_info.offset);
+	for (i = 0; i < config->tx_fifo_num; i++) {
+		get_info = mac_control->tx_curr_get_info[i];
+		put_info = mac_control->tx_curr_put_info[i];
+		txdlp = (TxD_t *) nic->list_info[i][get_info.offset].
+		    list_virt_addr;
 		while ((!(txdlp->Control_1 & TXD_LIST_OWN_XENA)) &&
-		       (offset_info.offset != offset_info1.offset) &&
+		       (get_info.offset != put_info.offset) &&
 		       (txdlp->Host_Control)) {
 			/* Check for TxD errors */
 			if (txdlp->Control_1 & TXD_T_CODE) {
@@ -1797,28 +2339,20 @@
 				txdlp = temp;
 			}
 			memset(txdlp, 0,
-			       (sizeof(TxD_t) * config->MaxTxDs));
+			       (sizeof(TxD_t) * config->max_txds));
 
 			/* Updating the statistics block */
 			nic->stats.tx_packets++;
 			nic->stats.tx_bytes += skb->len;
-#if DEBUG_ON
-			nic->txpkt_bytes += skb->len;
-			cnt++;
-#endif
 			dev_kfree_skb_irq(skb);
 
-			offset_info.offset++;
-			offset_info.offset %= offset_info.fifo_len + 1;
-			txdlp = mac_control->txdl_start[i] +
-			    (config->MaxTxDs * offset_info.offset);
+			get_info.offset++;
+			get_info.offset %= get_info.fifo_len + 1;
+			txdlp = (TxD_t *) nic->list_info[i]
+			    [get_info.offset].list_virt_addr;
 			mac_control->tx_curr_get_info[i].offset =
-			    offset_info.offset;
+			    get_info.offset;
 		}
-#if DEBUG_ON
-		DBG_PRINT(INTR_DBG, "%s: freed %d Tx Pkts\n", dev->name,
-			  cnt);
-#endif
 	}
 
 	spin_lock(&nic->tx_lock);
@@ -1827,67 +2361,79 @@
 	spin_unlock(&nic->tx_lock);
 }
 
-/*  
- *  Input Arguments: 
- *  device private variable
- *  Return Value: 
+/**  
+ *  alarm_intr_handler - Alarm Interrrupt handler
+ *  @nic: device private variable
+ *  Description: If the interrupt was neither because of Rx packet or Tx 
+ *  complete, this function is called. If the interrupt was to indicate
+ *  a loss of link, the OSM link status handler is invoked for any other 
+ *  alarm interrupt the block that raised the interrupt is displayed 
+ *  and a H/W reset is issued.
+ *  Return Value:
  *  NONE
- *  Description: 
- *  If the interrupt was neither because of Rx packet or Tx 
- *  complete, this function is called. If the interrupt was to indicate a loss
- *  of link, the OSM link status handler is invoked for any other alarm 
- *  interrupt the block that raised the interrupt is displayed and a H/W reset 
- *  is issued.
- */
-static void alarmIntrHandler(struct s2io_nic *nic)
+*/
+
+static void alarm_intr_handler(struct s2io_nic *nic)
 {
 	struct net_device *dev = (struct net_device *) nic->dev;
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+	XENA_dev_config_t __iomem *bar0 = nic->bar0;
 	register u64 val64 = 0, err_reg = 0;
 
-
 	/* Handling link status change error Intr */
 	err_reg = readq(&bar0->mac_rmac_err_reg);
+	writeq(err_reg, &bar0->mac_rmac_err_reg);
 	if (err_reg & RMAC_LINK_STATE_CHANGE_INT) {
 		schedule_work(&nic->set_link_task);
 	}
 
-	/* Handling SERR errors by stopping device Xmit queue and forcing 
-	 * a H/W reset.
-	 */
+	/* In case of a serious error, the device will be Reset. */
 	val64 = readq(&bar0->serr_source);
 	if (val64 & SERR_SOURCE_ANY) {
 		DBG_PRINT(ERR_DBG, "%s: Device indicates ", dev->name);
 		DBG_PRINT(ERR_DBG, "serious error!!\n");
 		netif_stop_queue(dev);
+		schedule_work(&nic->rst_timer_task);
 	}
-/* Other type of interrupts are not being handled now,  TODO*/
+
+	/*
+	 * Also as mentioned in the latest Errata sheets if the PCC_FB_ECC
+	 * Error occurs, the adapter will be recycled by disabling the
+	 * adapter enable bit and enabling it again after the device 
+	 * becomes Quiescent.
+	 */
+	val64 = readq(&bar0->pcc_err_reg);
+	writeq(val64, &bar0->pcc_err_reg);
+	if (val64 & PCC_FB_ECC_DB_ERR) {
+		u64 ac = readq(&bar0->adapter_control);
+		ac &= ~(ADAPTER_CNTL_EN);
+		writeq(ac, &bar0->adapter_control);
+		ac = readq(&bar0->adapter_control);
+		schedule_work(&nic->set_link_task);
+	}
+
+	/* Other type of interrupts are not being handled now,  TODO */
 }
 
-/*
- *  Input Argument: 
- *  sp - private member of the device structure, which is a pointer to the 
- *   	s2io_nic structure.
+/** 
+ *  wait_for_cmd_complete - waits for a command to complete.
+ *  @sp : private member of the device structure, which is a pointer to the 
+ *  s2io_nic structure.
+ *  Description: Function that waits for a command to Write into RMAC 
+ *  ADDR DATA registers to be completed and returns either success or 
+ *  error depending on whether the command was complete or not. 
  *  Return value:
  *   SUCCESS on success and FAILURE on failure.
- *  Description:
- *   Function that waits for a command to Write into RMAC ADDR DATA registers 
- *   to be completed and returns either success or error depending on whether 
- *   the command was complete or not. 
  */
-int waitForCmdComplete(nic_t * sp)
+
+int wait_for_cmd_complete(nic_t * sp)
 {
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0;
+	XENA_dev_config_t __iomem *bar0 = sp->bar0;
 	int ret = FAILURE, cnt = 0;
 	u64 val64;
 
 	while (TRUE) {
-		val64 =
-		    RMAC_ADDR_CMD_MEM_RD | RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD
-		    | RMAC_ADDR_CMD_MEM_OFFSET(0);
-		writeq(val64, &bar0->rmac_addr_cmd_mem);
 		val64 = readq(&bar0->rmac_addr_cmd_mem);
-		if (!val64) {
+		if (!(val64 & RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING)) {
 			ret = SUCCESS;
 			break;
 		}
@@ -1900,27 +2446,27 @@
 	return ret;
 }
 
-/*
- *  Input Argument: 
- *  sp - private member of the device structure, which is a pointer to the 
- *   	s2io_nic structure.
+/** 
+ *  s2io_reset - Resets the card. 
+ *  @sp : private member of the device structure.
+ *  Description: Function to Reset the card. This function then also
+ *  restores the previously saved PCI configuration space registers as 
+ *  the card reset also resets the configuration space.
  *  Return value:
- *   void.
- *  Description:
- *   Function to Reset the card. This function then also restores the previously
- *   saved PCI configuration space registers as the card reset also resets the
- *   Configration space.
+ *  void.
  */
+
 void s2io_reset(nic_t * sp)
 {
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0;
+	XENA_dev_config_t __iomem *bar0 = sp->bar0;
 	u64 val64;
 	u16 subid;
 
 	val64 = SW_RESET_ALL;
 	writeq(val64, &bar0->sw_reset);
 
-	/* At this stage, if the PCI write is indeed completed, the 
+	/* 
+	 * At this stage, if the PCI write is indeed completed, the 
 	 * card is reset and so is the PCI Config space of the device. 
 	 * So a read cannot be issued at this stage on any of the 
 	 * registers to ensure the write into "sw_reset" register
@@ -1948,35 +2494,37 @@
 		val64 |= 0x0000800000000000ULL;
 		writeq(val64, &bar0->gpio_control);
 		val64 = 0x0411040400000000ULL;
-		writeq(val64, (void *) ((u8 *) bar0 + 0x2700));
+		writeq(val64, (void __iomem *) bar0 + 0x2700);
 	}
 
 	sp->device_enabled_once = FALSE;
 }
 
-/*
- *  Input Argument: 
- *  sp - private member of the device structure, which is a pointer to the 
- *   	s2io_nic structure.
+/**
+ *  s2io_set_swapper - to set the swapper controle on the card 
+ *  @sp : private member of the device structure, 
+ *  pointer to the s2io_nic structure.
+ *  Description: Function to set the swapper control on the card 
+ *  correctly depending on the 'endianness' of the system.
  *  Return value:
  *  SUCCESS on success and FAILURE on failure.
- *  Description:
- * Function to set the swapper control on the card correctly depending on the
- * 'endianness' of the system.
  */
+
 int s2io_set_swapper(nic_t * sp)
 {
 	struct net_device *dev = sp->dev;
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0;
+	XENA_dev_config_t __iomem *bar0 = sp->bar0;
 	u64 val64;
 
-/*  Set proper endian settings and verify the same by reading the PIF 
- *  Feed-back register.
- */
+	/* 
+	 * Set proper endian settings and verify the same by reading
+	 * the PIF Feed-back register.
+	 */
 #ifdef  __BIG_ENDIAN
-/* The device by default set to a big endian format, so a big endian 
- * driver need not set anything.
- */
+	/* 
+	 * The device by default set to a big endian format, so a 
+	 * big endian driver need not set anything.
+	 */
 	writeq(0xffffffffffffffffULL, &bar0->swapper_ctrl);
 	val64 = (SWAPPER_CTRL_PIF_R_FE |
 		 SWAPPER_CTRL_PIF_R_SE |
@@ -1995,9 +2543,11 @@
 		 SWAPPER_CTRL_STATS_FE | SWAPPER_CTRL_STATS_SE);
 	writeq(val64, &bar0->swapper_ctrl);
 #else
-/* Initially we enable all bits to make it accessible by the driver,
- * then we selectively enable only those bits that we want to set.
- */
+	/* 
+	 * Initially we enable all bits to make it accessible by the
+	 * driver, then we selectively enable only those bits that 
+	 * we want to set.
+	 */
 	writeq(0xffffffffffffffffULL, &bar0->swapper_ctrl);
 	val64 = (SWAPPER_CTRL_PIF_R_FE |
 		 SWAPPER_CTRL_PIF_R_SE |
@@ -2021,9 +2571,10 @@
 	writeq(val64, &bar0->swapper_ctrl);
 #endif
 
-/*  Verifying if endian settings are accurate by reading a feedback
- *  register.
- */
+	/* 
+	 * Verifying if endian settings are accurate by reading a 
+	 * feedback register.
+	 */
 	val64 = readq(&bar0->pif_rd_swapper_fb);
 	if (val64 != 0x0123456789ABCDEFULL) {
 		/* Endian settings are incorrect, calls for another dekko. */
@@ -2041,216 +2592,139 @@
  * Functions defined below concern the OS part of the driver *
  * ********************************************************* */
 
-/*
- *  Input Argument: 
- *  dev - pointer to the device structure.
- *  Return value:
- *  '0' on success and an appropriate (-)ve integer as defined in errno.h
- *   file on failure.
+/**  
+ *  s2io_open - open entry point of the driver
+ *  @dev : pointer to the device structure.
  *  Description:
  *  This function is the open entry point of the driver. It mainly calls a
  *  function to allocate Rx buffers and inserts them into the buffer
  *  descriptors and then enables the Rx part of the NIC. 
+ *  Return value:
+ *  0 on success and an appropriate (-)ve integer as defined in errno.h
+ *   file on failure.
  */
+
 int s2io_open(struct net_device *dev)
 {
 	nic_t *sp = dev->priv;
-	int i, ret = 0, err = 0;
-	mac_info_t *mac_control;
-	struct config_param *config;
+	int err = 0;
 
-
-/* Make sure you have link off by default every time Nic is initialized*/
+	/* 
+	 * Make sure you have link off by default every time 
+	 * Nic is initialized
+	 */
 	netif_carrier_off(dev);
 	sp->last_link_state = LINK_DOWN;
 
-/*  Initialize the H/W I/O registers */
-	if (initNic(sp) != 0) {
+	/* Initialize H/W and enable interrupts */
+	if (s2io_card_up(sp)) {
 		DBG_PRINT(ERR_DBG, "%s: H/W initialization failed\n",
 			  dev->name);
 		return -ENODEV;
 	}
 
-/*  After proper initialization of H/W, register ISR */
-	err =
-	    request_irq((int) sp->irq, s2io_isr, SA_SHIRQ, sp->name, dev);
+	/* After proper initialization of H/W, register ISR */
+	err = request_irq((int) sp->irq, s2io_isr, SA_SHIRQ,
+			  sp->name, dev);
 	if (err) {
 		s2io_reset(sp);
 		DBG_PRINT(ERR_DBG, "%s: ISR registration failed\n",
 			  dev->name);
 		return err;
 	}
+
 	if (s2io_set_mac_addr(dev, dev->dev_addr) == FAILURE) {
 		DBG_PRINT(ERR_DBG, "Set Mac Address Failed\n");
 		s2io_reset(sp);
 		return -ENODEV;
 	}
 
-
-/*  Setting its receive mode */
-	s2io_set_multicast(dev);
-
-/*  Initializing the Rx buffers. For now we are considering only 1 Rx ring
- * and initializing buffers into 1016 RxDs or 8 Rx blocks
- */
-	mac_control = &sp->mac_control;
-	config = &sp->config;
-
-	for (i = 0; i < config->RxRingNum; i++) {
-		if ((ret = fill_rx_buffers(sp, i))) {
-			DBG_PRINT(ERR_DBG, "%s: Out of memory in Open\n",
-				  dev->name);
-			s2io_reset(sp);
-			free_irq(dev->irq, dev);
-			freeRxBuffers(sp);
-			return -ENOMEM;
-		}
-		DBG_PRINT(INFO_DBG, "Buf in ring:%d is %d:\n", i,
-			  atomic_read(&sp->rx_bufs_left[i]));
-	}
-
-/*  Enable tasklet for the device */
-	tasklet_init(&sp->task, s2io_tasklet, (unsigned long) dev);
-
-/*  Enable Rx Traffic and interrupts on the NIC */
-	if (startNic(sp)) {
-		DBG_PRINT(ERR_DBG, "%s: Starting NIC failed\n", dev->name);
-		tasklet_kill(&sp->task);
-		s2io_reset(sp);
-		free_irq(dev->irq, dev);
-		freeRxBuffers(sp);
-		return -ENODEV;
-	}
-
-	sp->device_close_flag = FALSE;	/* Device is up and running. */
 	netif_start_queue(dev);
-
 	return 0;
 }
 
-/*
- *  Input Argument/s: 
- *  dev - device pointer.
- *  Return value:
- *  '0' on success and an appropriate (-)ve integer as defined in errno.h
- *  file on failure.
+/**
+ *  s2io_close -close entry point of the driver
+ *  @dev : device pointer.
  *  Description:
  *  This is the stop entry point of the driver. It needs to undo exactly
- *  whatever was done by the open entry point, thus it's usually referred to
- *  as the close function. Among other things this function mainly stops the
+ *  whatever was done by the open entry point,thus it's usually referred to
+ *  as the close function.Among other things this function mainly stops the
  *  Rx side of the NIC and frees all the Rx buffers in the Rx rings.
+ *  Return value:
+ *  0 on success and an appropriate (-)ve integer as defined in errno.h
+ *  file on failure.
  */
+
 int s2io_close(struct net_device *dev)
 {
 	nic_t *sp = dev->priv;
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0;
-	register u64 val64 = 0;
-	u16 cnt = 0;
 
-	spin_lock(&sp->isr_lock);
+	flush_scheduled_work();
 	netif_stop_queue(dev);
+	/* Reset card, kill tasklet and free Tx and Rx buffers. */
+	s2io_card_down(sp);
 
-/* disable Tx and Rx traffic on the NIC */
-	stopNic(sp);
-
-	spin_unlock(&sp->isr_lock);
-
-/* If the device tasklet is running, wait till its done before killing it */
-	while (atomic_read(&(sp->tasklet_status))) {
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(HZ / 10);
-	}
-	tasklet_kill(&sp->task);
-
-/* Check if the device is Quiescent and then Reset the NIC */
-	do {
-		val64 = readq(&bar0->adapter_status);
-		if (verify_xena_quiescence(val64, sp->device_enabled_once)) {
-			break;
-		}
-
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(HZ / 20);
-		cnt++;
-		if (cnt == 10) {
-			DBG_PRINT(ERR_DBG,
-				  "s2io_close:Device not Quiescent ");
-			DBG_PRINT(ERR_DBG, "adaper status reads 0x%llx\n",
-				  (unsigned long long) val64);
-			break;
-		}
-	} while (1);
-	s2io_reset(sp);
-
-/*  Free the Registered IRQ */
 	free_irq(dev->irq, dev);
-
-/* Free all Tx Buffers waiting for transmission */
-	freeTxBuffers(sp);
-
-/*  Free all Rx buffers allocated by host */
-	freeRxBuffers(sp);
-
 	sp->device_close_flag = TRUE;	/* Device is shut down. */
-
 	return 0;
 }
 
-/*
- *  Input Argument/s: 
- *  skb - the socket buffer containing the Tx data.
- *  dev - device pointer.
- *  Return value:
- *  '0' on success & 1 on failure. 
- *  NOTE: when device cant queue the pkt, just the trans_start variable will
- *  not be upadted.
- *  Description:
+/**
+ *  s2io_xmit - Tx entry point of te driver
+ *  @skb : the socket buffer containing the Tx data.
+ *  @dev : device pointer.
+ *  Description :
  *  This function is the Tx entry point of the driver. S2IO NIC supports
  *  certain protocol assist features on Tx side, namely  CSO, S/G, LSO.
+ *  NOTE: when device cant queue the pkt,just the trans_start variable will
+ *  not be upadted.
+ *  Return value:
+ *  0 on success & 1 on failure.
  */
+
 int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	nic_t *sp = dev->priv;
-	u16 off, txd_len, frg_cnt, frg_len, i, queue, off1, queue_len;
+	u16 frg_cnt, frg_len, i, queue, queue_len, put_off, get_off;
 	register u64 val64;
 	TxD_t *txdp;
-	TxFIFO_element_t *tx_fifo;
+	TxFIFO_element_t __iomem *tx_fifo;
 	unsigned long flags;
 #ifdef NETIF_F_TSO
 	int mss;
 #endif
 	mac_info_t *mac_control;
 	struct config_param *config;
+	XENA_dev_config_t __iomem *bar0 = sp->bar0;
 
 	mac_control = &sp->mac_control;
 	config = &sp->config;
 
 	DBG_PRINT(TX_DBG, "%s: In S2IO Tx routine\n", dev->name);
-
 	spin_lock_irqsave(&sp->tx_lock, flags);
-	queue = 0;
-	/* Multi FIFO Tx is disabled for now. */
-	if (!queue && tx_prio) {
-		u8 x = (skb->data)[5];
-		queue = x % config->TxFIFONum;
-	}
 
+	if (atomic_read(&sp->card_state) == CARD_DOWN) {
+		DBG_PRINT(ERR_DBG, "%s: Card going down for reset\n",
+			  dev->name);
+		spin_unlock_irqrestore(&sp->tx_lock, flags);
+		return 1;
+	}
 
-	off = (u16) mac_control->tx_curr_put_info[queue].offset;
-	off1 = (u16) mac_control->tx_curr_get_info[queue].offset;
-	txd_len = mac_control->txdl_len;
-	txdp = mac_control->txdl_start[queue] + (config->MaxTxDs * off);
+	queue = 0;
+	put_off = (u16) mac_control->tx_curr_put_info[queue].offset;
+	get_off = (u16) mac_control->tx_curr_get_info[queue].offset;
+	txdp = (TxD_t *) sp->list_info[queue][put_off].list_virt_addr;
 
 	queue_len = mac_control->tx_curr_put_info[queue].fifo_len + 1;
 	/* Avoid "put" pointer going beyond "get" pointer */
-	if (txdp->Host_Control || (((off + 1) % queue_len) == off1)) {
+	if (txdp->Host_Control || (((put_off + 1) % queue_len) == get_off)) {
 		DBG_PRINT(ERR_DBG, "Error in xmit, No free TXDs.\n");
 		netif_stop_queue(dev);
 		dev_kfree_skb(skb);
 		spin_unlock_irqrestore(&sp->tx_lock, flags);
 		return 0;
 	}
-
 #ifdef NETIF_F_TSO
 	mss = skb_shinfo(skb)->tso_size;
 	if (mss) {
@@ -2271,7 +2745,7 @@
 		     TXD_TX_CKO_UDP_EN);
 	}
 
-	txdp->Control_2 |= config->TxIntrType;
+	txdp->Control_2 |= config->tx_intr_type;
 
 	txdp->Control_1 |= (TXD_BUFFER0_SIZE(frg_len) |
 			    TXD_GATHER_CODE_FIRST);
@@ -2289,8 +2763,7 @@
 	txdp->Control_1 |= TXD_GATHER_CODE_LAST;
 
 	tx_fifo = mac_control->tx_FIFO_start[queue];
-	val64 = (mac_control->txdl_start_phy[queue] +
-		 (sizeof(TxD_t) * txd_len * off));
+	val64 = sp->list_info[queue][put_off].list_phy_addr;
 	writeq(val64, &tx_fifo->TxDL_Pointer);
 
 	val64 = (TX_FIFO_LAST_TXD_NUM(frg_cnt) | TX_FIFO_FIRST_LIST |
@@ -2301,15 +2774,18 @@
 #endif
 	writeq(val64, &tx_fifo->List_Control);
 
-	off++;
-	off %= mac_control->tx_curr_put_info[queue].fifo_len + 1;
-	mac_control->tx_curr_put_info[queue].offset = off;
+	/* Perform a PCI read to flush previous writes */
+	val64 = readq(&bar0->general_int_status);
+
+	put_off++;
+	put_off %= mac_control->tx_curr_put_info[queue].fifo_len + 1;
+	mac_control->tx_curr_put_info[queue].offset = put_off;
 
 	/* Avoid "put" pointer going beyond "get" pointer */
-	if (((off + 1) % queue_len) == off1) {
-		DBG_PRINT(TX_DBG, 
-		  "No free TxDs for xmit, Put: 0x%x Get:0x%x\n",
-		  off, off1);
+	if (((put_off + 1) % queue_len) == get_off) {
+		DBG_PRINT(TX_DBG,
+			  "No free TxDs for xmit, Put: 0x%x Get:0x%x\n",
+			  put_off, get_off);
 		netif_stop_queue(dev);
 	}
 
@@ -2319,36 +2795,37 @@
 	return 0;
 }
 
-/*
- *  Input Argument/s: 
- *  irq: the irq of the device.
- *  dev_id: a void pointer to the dev structure of the NIC.
- *  ptregs: pointer to the registers pushed on the stack.
+/**
+ *  s2io_isr - ISR handler of the device .
+ *  @irq: the irq of the device.
+ *  @dev_id: a void pointer to the dev structure of the NIC.
+ *  @pt_regs: pointer to the registers pushed on the stack.
+ *  Description:  This function is the ISR handler of the device. It 
+ *  identifies the reason for the interrupt and calls the relevant 
+ *  service routines. As a contongency measure, this ISR allocates the 
+ *  recv buffers, if their numbers are below the panic value which is
+ *  presently set to 25% of the original number of rcv buffers allocated.
  *  Return value:
- *  void.
- *  Description:
- *  This function is the ISR handler of the device. It identifies the reason 
- *  for the interrupt and calls the relevant service routines.
- *  As a contongency measure, this ISR allocates the recv buffers, if their 
- *  numbers are below the panic value which is presently set to 25% of the
- *  original number of rcv buffers allocated.
+ *   IRQ_HANDLED: will be returned if IRQ was handled by this routine 
+ *   IRQ_NONE: will be returned if interrupt is not from our device
  */
-
 static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs)
 {
 	struct net_device *dev = (struct net_device *) dev_id;
 	nic_t *sp = dev->priv;
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0;
-	u64 reason = 0, general_mask = 0;
+	XENA_dev_config_t __iomem *bar0 = sp->bar0;
+#ifndef CONFIG_S2IO_NAPI
+	int i, ret;
+#endif
+	u64 reason = 0;
 	mac_info_t *mac_control;
 	struct config_param *config;
 
 	mac_control = &sp->mac_control;
 	config = &sp->config;
 
-	spin_lock(&sp->isr_lock);
-
-	/* Identify the cause for interrupt and call the appropriate
+	/* 
+	 * Identify the cause for interrupt and call the appropriate
 	 * interrupt handler. Causes for the interrupt could be;
 	 * 1. Rx of packet.
 	 * 2. Tx complete.
@@ -2359,101 +2836,73 @@
 
 	if (!reason) {
 		/* The interrupt was not raised by Xena. */
-		spin_unlock(&sp->isr_lock);
 		return IRQ_NONE;
 	}
-	/* Mask the interrupts on the NIC */
-	general_mask = readq(&bar0->general_int_mask);
-	writeq(0xFFFFFFFFFFFFFFFFULL, &bar0->general_int_mask);
-
-#if DEBUG_ON
-	sp->int_cnt++;
-#endif
 
 	/* If Intr is because of Tx Traffic */
 	if (reason & GEN_INTR_TXTRAFFIC) {
-		txIntrHandler(sp);
+		tx_intr_handler(sp);
 	}
 
 	/* If Intr is because of an error */
 	if (reason & (GEN_ERROR_INTR))
-		alarmIntrHandler(sp);
+		alarm_intr_handler(sp);
 
 #ifdef CONFIG_S2IO_NAPI
 	if (reason & GEN_INTR_RXTRAFFIC) {
 		if (netif_rx_schedule_prep(dev)) {
-			en_dis_able_NicIntrs(sp, RX_TRAFFIC_INTR,
-					     DISABLE_INTRS);
-			/* We retake the snap shot of the general interrupt 
-			 * register.
-			 */
-			general_mask = readq(&bar0->general_int_mask);
+			en_dis_able_nic_intrs(sp, RX_TRAFFIC_INTR,
+					      DISABLE_INTRS);
 			__netif_rx_schedule(dev);
 		}
 	}
 #else
 	/* If Intr is because of Rx Traffic */
 	if (reason & GEN_INTR_RXTRAFFIC) {
-		rxIntrHandler(sp);
+		rx_intr_handler(sp);
 	}
 #endif
 
-/* If the Rx buffer count is below the panic threshold then reallocate the
- * buffers from the interrupt handler itself, else schedule a tasklet to 
- * reallocate the buffers.
- */
-#if 1
-	{
-	int i;
-
-	for (i = 0; i < config->RxRingNum; i++) {
+	/* 
+	 * If the Rx buffer count is below the panic threshold then 
+	 * reallocate the buffers from the interrupt handler itself, 
+	 * else schedule a tasklet to reallocate the buffers.
+	 */
+#ifndef CONFIG_S2IO_NAPI
+	for (i = 0; i < config->rx_ring_num; i++) {
 		int rxb_size = atomic_read(&sp->rx_bufs_left[i]);
 		int level = rx_buffer_level(sp, rxb_size, i);
 
 		if ((level == PANIC) && (!TASKLET_IN_USE)) {
-			int ret;
-
-			DBG_PRINT(ERR_DBG, "%s: Rx BD hit ", dev->name);
-			DBG_PRINT(ERR_DBG, "PANIC levels\n");
+			DBG_PRINT(INTR_DBG, "%s: Rx BD hit ", dev->name);
+			DBG_PRINT(INTR_DBG, "PANIC levels\n");
 			if ((ret = fill_rx_buffers(sp, i)) == -ENOMEM) {
 				DBG_PRINT(ERR_DBG, "%s:Out of memory",
 					  dev->name);
 				DBG_PRINT(ERR_DBG, " in ISR!!\n");
-				writeq(general_mask,
-				       &bar0->general_int_mask);
-				spin_unlock(&sp->isr_lock);
+				clear_bit(0, (&sp->tasklet_status));
 				return IRQ_HANDLED;
 			}
-			clear_bit(0,
-				  (unsigned long *) (&sp->tasklet_status));
-		} else if ((level == LOW)
-			   && (!atomic_read(&sp->tasklet_status))) {
+			clear_bit(0, (&sp->tasklet_status));
+		} else if (level == LOW) {
 			tasklet_schedule(&sp->task);
 		}
-
-	}
-
 	}
-#else
-	tasklet_schedule(&sp->task);
 #endif
 
-	/* Unmask all the previously enabled interrupts on the NIC */
-	writeq(general_mask, &bar0->general_int_mask);
-
-	spin_unlock(&sp->isr_lock);
 	return IRQ_HANDLED;
 }
 
-/*
- *  Input Argument/s: 
- *  dev - pointer to the device structure.
- *  Return value:
- *  pointer to the updated net_device_stats structure.
+/**
+ *  s2io_get_stats - Updates the device statistics structure. 
+ *  @dev : pointer to the device structure.
  *  Description:
  *  This function updates the device statistics structure in the s2io_nic 
  *  structure and returns a pointer to the same.
+ *  Return value:
+ *  pointer to the updated net_device_stats structure.
  */
+
 struct net_device_stats *s2io_get_stats(struct net_device *dev)
 {
 	nic_t *sp = dev->priv;
@@ -2463,37 +2912,38 @@
 	mac_control = &sp->mac_control;
 	config = &sp->config;
 
-	sp->stats.tx_errors = mac_control->StatsInfo->tmac_any_err_frms;
-	sp->stats.rx_errors = mac_control->StatsInfo->rmac_drop_frms;
-	sp->stats.multicast = mac_control->StatsInfo->rmac_vld_mcst_frms;
+	sp->stats.tx_errors = mac_control->stats_info->tmac_any_err_frms;
+	sp->stats.rx_errors = mac_control->stats_info->rmac_drop_frms;
+	sp->stats.multicast = mac_control->stats_info->rmac_vld_mcst_frms;
 	sp->stats.rx_length_errors =
-	    mac_control->StatsInfo->rmac_long_frms;
+	    mac_control->stats_info->rmac_long_frms;
 
 	return (&sp->stats);
 }
 
-/*
- *  Input Argument/s: 
- *  dev - pointer to the device structure
- *  Return value:
- *  void.
+/**
+ *  s2io_set_multicast - entry point for multicast address enable/disable.
+ *  @dev : pointer to the device structure
  *  Description:
  *  This function is a driver entry point which gets called by the kernel 
  *  whenever multicast addresses must be enabled/disabled. This also gets 
  *  called to set/reset promiscuous mode. Depending on the deivce flag, we
  *  determine, if multicast address must be enabled or if promiscuous mode
  *  is to be disabled etc.
+ *  Return value:
+ *  void.
  */
+
 static void s2io_set_multicast(struct net_device *dev)
 {
 	int i, j, prev_cnt;
 	struct dev_mc_list *mclist;
 	nic_t *sp = dev->priv;
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0;
+	XENA_dev_config_t __iomem *bar0 = sp->bar0;
 	u64 val64 = 0, multi_mac = 0x010203040506ULL, mask =
 	    0xfeffffffffffULL;
 	u64 dis_addr = 0xffffffffffffULL, mac_addr = 0;
-	void *add;
+	void __iomem *add;
 
 	if ((dev->flags & IFF_ALLMULTI) && (!sp->m_cast_flg)) {
 		/*  Enable all Multicast addresses */
@@ -2506,7 +2956,7 @@
 		    RMAC_ADDR_CMD_MEM_OFFSET(MAC_MC_ALL_MC_ADDR_OFFSET);
 		writeq(val64, &bar0->rmac_addr_cmd_mem);
 		/* Wait till command completes */
-		waitForCmdComplete(sp);
+		wait_for_cmd_complete(sp);
 
 		sp->m_cast_flg = 1;
 		sp->all_multi_pos = MAC_MC_ALL_MC_ADDR_OFFSET;
@@ -2519,7 +2969,7 @@
 		    RMAC_ADDR_CMD_MEM_OFFSET(sp->all_multi_pos);
 		writeq(val64, &bar0->rmac_addr_cmd_mem);
 		/* Wait till command completes */
-		waitForCmdComplete(sp);
+		wait_for_cmd_complete(sp);
 
 		sp->m_cast_flg = 0;
 		sp->all_multi_pos = 0;
@@ -2527,7 +2977,7 @@
 
 	if ((dev->flags & IFF_PROMISC) && (!sp->promisc_flg)) {
 		/*  Put the NIC into promiscuous mode */
-		add = (void *) &bar0->mac_cfg;
+		add = &bar0->mac_cfg;
 		val64 = readq(&bar0->mac_cfg);
 		val64 |= MAC_CFG_RMAC_PROM_ENABLE;
 
@@ -2542,7 +2992,7 @@
 			  dev->name);
 	} else if (!(dev->flags & IFF_PROMISC) && (sp->promisc_flg)) {
 		/*  Remove the NIC from promiscuous mode */
-		add = (void *) &bar0->mac_cfg;
+		add = &bar0->mac_cfg;
 		val64 = readq(&bar0->mac_cfg);
 		val64 &= ~MAC_CFG_RMAC_PROM_ENABLE;
 
@@ -2575,6 +3025,8 @@
 		for (i = 0; i < prev_cnt; i++) {
 			writeq(RMAC_ADDR_DATA0_MEM_ADDR(dis_addr),
 			       &bar0->rmac_addr_data0_mem);
+			writeq(RMAC_ADDR_DATA1_MEM_MASK(0ULL),
+		       		&bar0->rmac_addr_data1_mem);
 			val64 = RMAC_ADDR_CMD_MEM_WE |
 			    RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD |
 			    RMAC_ADDR_CMD_MEM_OFFSET
@@ -2582,7 +3034,7 @@
 			writeq(val64, &bar0->rmac_addr_cmd_mem);
 
 			/* Wait for command completes */
-			if (waitForCmdComplete(sp)) {
+			if (wait_for_cmd_complete(sp)) {
 				DBG_PRINT(ERR_DBG, "%s: Adding ",
 					  dev->name);
 				DBG_PRINT(ERR_DBG, "Multicasts failed\n");
@@ -2599,8 +3051,11 @@
 				mac_addr |= mclist->dmi_addr[j];
 				mac_addr <<= 8;
 			}
+			mac_addr >>= 8;
 			writeq(RMAC_ADDR_DATA0_MEM_ADDR(mac_addr),
 			       &bar0->rmac_addr_data0_mem);
+			writeq(RMAC_ADDR_DATA1_MEM_MASK(0ULL),
+		       		&bar0->rmac_addr_data1_mem);
 
 			val64 = RMAC_ADDR_CMD_MEM_WE |
 			    RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD |
@@ -2609,7 +3064,7 @@
 			writeq(val64, &bar0->rmac_addr_cmd_mem);
 
 			/* Wait for command completes */
-			if (waitForCmdComplete(sp)) {
+			if (wait_for_cmd_complete(sp)) {
 				DBG_PRINT(ERR_DBG, "%s: Adding ",
 					  dev->name);
 				DBG_PRINT(ERR_DBG, "Multicasts failed\n");
@@ -2619,21 +3074,20 @@
 	}
 }
 
-/*
- *  Input Argument/s: 
- *  dev - pointer to the device structure.
- *  new_mac - a uchar pointer to the new mac address which is to be set.
- *  Return value:
- *  SUCCESS on success and an appropriate (-)ve integer as defined in errno.h
- *  file on failure.
- *  Description:
- *  This procedure will program the Xframe to receive frames with new
- *  Mac Address
+/**
+ *  s2io_set_mac_addr - Programs the Xframe mac address 
+ *  @dev : pointer to the device structure.
+ *  @addr: a uchar pointer to the new mac address which is to be set.
+ *  Description : This procedure will program the Xframe to receive 
+ *  frames with new Mac Address
+ *  Return value: SUCCESS on success and an appropriate (-)ve integer 
+ *  as defined in errno.h file on failure.
  */
+
 int s2io_set_mac_addr(struct net_device *dev, u8 * addr)
 {
 	nic_t *sp = dev->priv;
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0;
+	XENA_dev_config_t __iomem *bar0 = sp->bar0;
 	register u64 val64, mac_addr = 0;
 	int i;
 
@@ -2655,7 +3109,7 @@
 	    RMAC_ADDR_CMD_MEM_OFFSET(0);
 	writeq(val64, &bar0->rmac_addr_cmd_mem);
 	/* Wait till command completes */
-	if (waitForCmdComplete(sp)) {
+	if (wait_for_cmd_complete(sp)) {
 		DBG_PRINT(ERR_DBG, "%s: set_mac_addr failed\n", dev->name);
 		return FAILURE;
 	}
@@ -2663,18 +3117,18 @@
 	return SUCCESS;
 }
 
-/*
- * Input Argument/s: 
- *  sp - private member of the device structure, which is a pointer to the 
- *   	s2io_nic structure.
- *  info - pointer to the structure with parameters given by ethtool to set
- *  link information.
- * Return value:
- *  0 on success.
+/**
+ * s2io_ethtool_sset - Sets different link parameters. 
+ * @sp : private member of the device structure, which is a pointer to the  * s2io_nic structure.
+ * @info: pointer to the structure with parameters given by ethtool to set
+ * link information.
  * Description:
- *  The function sets different link parameters provided by the user onto 
- *  the NIC.
- */
+ * The function sets different link parameters provided by the user onto 
+ * the NIC.
+ * Return value:
+ * 0 on success.
+*/
+
 static int s2io_ethtool_sset(struct net_device *dev,
 			     struct ethtool_cmd *info)
 {
@@ -2690,17 +3144,18 @@
 	return 0;
 }
 
-/*
- * Input Argument/s: 
- *  sp - private member of the device structure, which is a pointer to the 
- *   	s2io_nic structure.
- *  info - pointer to the structure with parameters given by ethtool to return
- *  link information.
- * Return value:
- *  void
+/**
+ * s2io_ethtol_gset - Return link specific information. 
+ * @sp : private member of the device structure, pointer to the
+ *      s2io_nic structure.
+ * @info : pointer to the structure with parameters given by ethtool
+ * to return link information.
  * Description:
- *  Returns link specefic information like speed, duplex etc.. to ethtool.
+ * Returns link specific information like speed, duplex etc.. to ethtool.
+ * Return value :
+ * return 0 on success.
  */
+
 int s2io_ethtool_gset(struct net_device *dev, struct ethtool_cmd *info)
 {
 	nic_t *sp = dev->priv;
@@ -2721,17 +3176,18 @@
 	return 0;
 }
 
-/*
- * Input Argument/s: 
- *  sp - private member of the device structure, which is a pointer to the 
- *   	s2io_nic structure.
- *  info - pointer to the structure with parameters given by ethtool to return
- *  driver information.
+/**
+ * s2io_ethtool_gdrvinfo - Returns driver specific information. 
+ * @sp : private member of the device structure, which is a pointer to the 
+ * s2io_nic structure.
+ * @info : pointer to the structure with parameters given by ethtool to
+ * return driver information.
+ * Description:
+ * Returns driver specefic information like name, version etc.. to ethtool.
  * Return value:
  *  void
- * Description:
- *  Returns driver specefic information like name, version etc.. to ethtool.
  */
+
 static void s2io_ethtool_gdrvinfo(struct net_device *dev,
 				  struct ethtool_drvinfo *info)
 {
@@ -2748,19 +3204,20 @@
 	info->n_stats = S2IO_STAT_LEN;
 }
 
-/*
- * Input Argument/s: 
- *  sp - private member of the device structure, which is a pointer to the 
- *   	s2io_nic structure.
- *  regs - pointer to the structure with parameters given by ethtool for 
+/**
+ *  s2io_ethtool_gregs - dumps the entire space of Xfame into the buffer.
+ *  @sp: private member of the device structure, which is a pointer to the 
+ *  s2io_nic structure.
+ *  @regs : pointer to the structure with parameters given by ethtool for 
  *  dumping the registers.
- *  reg_space - The input argumnet into which all the registers are dumped.
- * Return value:
- *  void
- * Description:
- *  Dumps the entire register space of xFrame NIC into the user given buffer 
- *  area.
- */
+ *  @reg_space: The input argumnet into which all the registers are dumped.
+ *  Description:
+ *  Dumps the entire register space of xFrame NIC into the user given
+ *  buffer area.
+ * Return value :
+ * void .
+*/
+
 static void s2io_ethtool_gregs(struct net_device *dev,
 			       struct ethtool_regs *regs, void *space)
 {
@@ -2773,26 +3230,24 @@
 	regs->version = sp->pdev->subsystem_device;
 
 	for (i = 0; i < regs->len; i += 8) {
-		reg = readq((void *) (sp->bar0 + i));
+		reg = readq(sp->bar0 + i);
 		memcpy((reg_space + i), &reg, 8);
 	}
 }
 
-/*
- * Input Argument/s: 
- *  data - address of the private member of the device structure, which 
+/**
+ *  s2io_phy_id  - timer function that alternates adapter LED.
+ *  @data : address of the private member of the device structure, which 
  *  is a pointer to the s2io_nic structure, provided as an u32.
- * Return value:
- *  void
- * Description:
- *  This is actually the timer function that alternates the adapter LED bit
- *  of the adapter control bit to set/reset every time on invocation.
- *  The timer is set for 1/2 a second, hence tha NIC blinks once every second.
- */
+ * Description: This is actually the timer function that alternates the 
+ * adapter LED bit of the adapter control bit to set/reset every time on 
+ * invocation. The timer is set for 1/2 a second, hence tha NIC blinks 
+ *  once every second.
+*/
 static void s2io_phy_id(unsigned long data)
 {
 	nic_t *sp = (nic_t *) data;
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0;
+	XENA_dev_config_t __iomem *bar0 = sp->bar0;
 	u64 val64 = 0;
 	u16 subid;
 
@@ -2810,28 +3265,30 @@
 	mod_timer(&sp->id_timer, jiffies + HZ / 2);
 }
 
-/*
- * Input Argument/s: 
- *  sp - private member of the device structure, which is a pointer to the 
- *   	s2io_nic structure.
- *  id - pointer to the structure with identification parameters given by 
- *  ethtool.
+/**
+ * s2io_ethtool_idnic - To physically identify the nic on the system.
+ * @sp : private member of the device structure, which is a pointer to the
+ * s2io_nic structure.
+ * @id : pointer to the structure with identification parameters given by 
+ * ethtool.
+ * Description: Used to physically identify the NIC on the system.
+ * The Link LED will blink for a time specified by the user for 
+ * identification.
+ * NOTE: The Link has to be Up to be able to blink the LED. Hence 
+ * identification is possible only if it's link is up.
  * Return value:
- *  int , returns '0' on success
- * Description:
- *  Used to physically identify the NIC on the system. The Link LED will blink
- *  for a time specified by the user for identification.
- *  NOTE: The Link has to be Up to be able to blink the LED. Hence 
- *  identification is possible only if it's link is up.
+ * int , returns 0 on success
  */
+
 static int s2io_ethtool_idnic(struct net_device *dev, u32 data)
 {
-	u64 val64 = 0;
+	u64 val64 = 0, last_gpio_ctrl_val;
 	nic_t *sp = dev->priv;
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0;
+	XENA_dev_config_t __iomem *bar0 = sp->bar0;
 	u16 subid;
 
 	subid = sp->pdev->subsystem_device;
+	last_gpio_ctrl_val = readq(&bar0->gpio_control);
 	if ((subid & 0xFF) < 0x07) {
 		val64 = readq(&bar0->adapter_control);
 		if (!(val64 & ADAPTER_CNTL_EN)) {
@@ -2853,25 +3310,29 @@
 		schedule_timeout(MAX_SCHEDULE_TIMEOUT);
 	del_timer_sync(&sp->id_timer);
 
+	if (CARDS_WITH_FAULTY_LINK_INDICATORS(subid)) {
+		writeq(last_gpio_ctrl_val, &bar0->gpio_control);
+		last_gpio_ctrl_val = readq(&bar0->gpio_control);
+	}
+
 	return 0;
 }
 
-/*
- * Input Argument/s: 
- *  sp - private member of the device structure, which is a pointer to the 
- *   	s2io_nic structure.
- *  ep - pointer to the structure with pause parameters given by ethtool.
+/**
+ * s2io_ethtool_getpause_data -Pause frame frame generation and reception.
+ * @sp : private member of the device structure, which is a pointer to the  * s2io_nic structure.
+ * @ep : pointer to the structure with pause parameters given by ethtool.
+ * Description:
+ * Returns the Pause frame generation and reception capability of the NIC.
  * Return value:
  *  void
- * Description:
- *  Returns the Pause frame generation and reception capability of the NIC.
  */
 static void s2io_ethtool_getpause_data(struct net_device *dev,
 				       struct ethtool_pauseparam *ep)
 {
 	u64 val64;
 	nic_t *sp = dev->priv;
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0;
+	XENA_dev_config_t __iomem *bar0 = sp->bar0;
 
 	val64 = readq(&bar0->rmac_pause_cfg);
 	if (val64 & RMAC_PAUSE_GEN_ENABLE)
@@ -2881,23 +3342,24 @@
 	ep->autoneg = FALSE;
 }
 
-/*
- * Input Argument/s: 
- * sp - private member of the device structure, which is a pointer to the 
- *   	s2io_nic structure.
- * ep - pointer to the structure with pause parameters given by ethtool.
- * Return value:
- * int, returns '0' on Success
+/**
+ * s2io_ethtool_setpause_data -  set/reset pause frame generation.
+ * @sp : private member of the device structure, which is a pointer to the 
+ *      s2io_nic structure.
+ * @ep : pointer to the structure with pause parameters given by ethtool.
  * Description:
- * It can be used to set or reset Pause frame generation or reception support 
- * of the NIC.
+ * It can be used to set or reset Pause frame generation or reception
+ * support of the NIC.
+ * Return value:
+ * int, returns 0 on Success
  */
+
 int s2io_ethtool_setpause_data(struct net_device *dev,
 			       struct ethtool_pauseparam *ep)
 {
 	u64 val64;
 	nic_t *sp = dev->priv;
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0;
+	XENA_dev_config_t __iomem *bar0 = sp->bar0;
 
 	val64 = readq(&bar0->rmac_pause_cfg);
 	if (ep->tx_pause)
@@ -2912,35 +3374,40 @@
 	return 0;
 }
 
-/*
- * Input Argument/s: 
- *  sp - private member of the device structure, which is a pointer to the 
- *   	s2io_nic structure.
- *  off - offset at which the data must be written
- * Return value:
- *  -1 on failure and the value read from the Eeprom if successful.
+/**
+ * read_eeprom - reads 4 bytes of data from user given offset.
+ * @sp : private member of the device structure, which is a pointer to the 
+ *      s2io_nic structure.
+ * @off : offset at which the data must be written
+ * @data : Its an output parameter where the data read at the given
+ * 	offset is stored.
  * Description:
- *  Will read 4 bytes of data from the user given offset and return the 
- *  read data.
+ * Will read 4 bytes of data from the user given offset and return the 
+ * read data.
  * NOTE: Will allow to read only part of the EEPROM visible through the
- * 	 I2C bus.
+ *   I2C bus.
+ * Return value:
+ *  -1 on failure and 0 on success.
  */
+
 #define S2IO_DEV_ID		5
-static u32 readEeprom(nic_t * sp, int off)
+static int read_eeprom(nic_t * sp, int off, u32 * data)
 {
-	u32 data = -1, exit_cnt = 0;
+	int ret = -1;
+	u32 exit_cnt = 0;
 	u64 val64;
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0;
+	XENA_dev_config_t __iomem *bar0 = sp->bar0;
 
 	val64 = I2C_CONTROL_DEV_ID(S2IO_DEV_ID) | I2C_CONTROL_ADDR(off) |
 	    I2C_CONTROL_BYTE_CNT(0x3) | I2C_CONTROL_READ |
 	    I2C_CONTROL_CNTL_START;
-	writeq(val64, &bar0->i2c_control);
+	SPECIAL_REG_WRITE(val64, &bar0->i2c_control, LF);
 
 	while (exit_cnt < 5) {
 		val64 = readq(&bar0->i2c_control);
 		if (I2C_CONTROL_CNTL_END(val64)) {
-			data = I2C_CONTROL_GET_DATA(val64);
+			*data = I2C_CONTROL_GET_DATA(val64);
+			ret = 0;
 			break;
 		}
 		set_current_state(TASK_UNINTERRUPTIBLE);
@@ -2948,33 +3415,34 @@
 		exit_cnt++;
 	}
 
-	return data;
+	return ret;
 }
 
-/*
- * Input Argument/s: 
- *  sp - private member of the device structure, which is a pointer to the 
- *   	s2io_nic structure.
- *  off - offset at which the data must be written
- *  data - The data that is to be written
- *  cnt - Number of bytes of the data that are actually to be written into 
+/**
+ *  write_eeprom - actually writes the relevant part of the data value.
+ *  @sp : private member of the device structure, which is a pointer to the
+ *       s2io_nic structure.
+ *  @off : offset at which the data must be written
+ *  @data : The data that is to be written
+ *  @cnt : Number of bytes of the data that are actually to be written into 
  *  the Eeprom. (max of 3)
- * Return value:
- *  '0' on success, -1 on failure.
  * Description:
  *  Actually writes the relevant part of the data value into the Eeprom
  *  through the I2C bus.
+ * Return value:
+ *  0 on success, -1 on failure.
  */
-static int writeEeprom(nic_t * sp, int off, u32 data, int cnt)
+
+static int write_eeprom(nic_t * sp, int off, u32 data, int cnt)
 {
 	int exit_cnt = 0, ret = -1;
 	u64 val64;
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0;
+	XENA_dev_config_t __iomem *bar0 = sp->bar0;
 
 	val64 = I2C_CONTROL_DEV_ID(S2IO_DEV_ID) | I2C_CONTROL_ADDR(off) |
 	    I2C_CONTROL_BYTE_CNT(cnt) | I2C_CONTROL_SET_DATA(data) |
 	    I2C_CONTROL_CNTL_START;
-	writeq(val64, &bar0->i2c_control);
+	SPECIAL_REG_WRITE(val64, &bar0->i2c_control, LF);
 
 	while (exit_cnt < 5) {
 		val64 = readq(&bar0->i2c_control);
@@ -2991,39 +3459,19 @@
 	return ret;
 }
 
-/* 
- * A helper function used to invert the 4 byte u32 data field
- * byte by byte. This will be used by the Read Eeprom function
- * for display purposes.
- */
-u32 inv(u32 data)
-{
-	static u32 ret = 0;
-
-	if (data) {
-		u8 c = data;
-		ret = ((ret << 8) + c);
-		data >>= 8;
-		inv(data);
-	}
-
-	return ret;
-}
-
-/*
- * Input Argument/s: 
- *  sp - private member of the device structure, which is a pointer to the 
- *   	s2io_nic structure.
- *  eeprom - pointer to the user level structure provided by ethtool, 
- *   containing all relevant information.
- *  data_buf - user defined value to be written into Eeprom.
- * Return value:
- *  int  '0' on success
- * Description:
- *  Reads the values stored in the Eeprom at given offset for a given length.
- *  Stores these values int the input argument data buffer 'data_buf' and
- *  returns these to the caller (ethtool.)
+/**
+ *  s2io_ethtool_geeprom  - reads the value stored in the Eeprom.
+ *  @sp : private member of the device structure, which is a pointer to the *       s2io_nic structure.
+ *  @eeprom : pointer to the user level structure provided by ethtool, 
+ *  containing all relevant information.
+ *  @data_buf : user defined value to be written into Eeprom.
+ *  Description: Reads the values stored in the Eeprom at given offset
+ *  for a given length. Stores these values int the input argument data
+ *  buffer 'data_buf' and returns these to the caller (ethtool.)
+ *  Return value:
+ *  int  0 on success
  */
+
 int s2io_ethtool_geeprom(struct net_device *dev,
 			 struct ethtool_eeprom *eeprom, u8 * data_buf)
 {
@@ -3036,30 +3484,30 @@
 		eeprom->len = XENA_EEPROM_SPACE - eeprom->offset;
 
 	for (i = 0; i < eeprom->len; i += 4) {
-		data = readEeprom(sp, eeprom->offset + i);
-		if (data < 0) {
+		if (read_eeprom(sp, (eeprom->offset + i), &data)) {
 			DBG_PRINT(ERR_DBG, "Read of EEPROM failed\n");
 			return -EFAULT;
 		}
-		valid = inv(data);
+		valid = INV(data);
 		memcpy((data_buf + i), &valid, 4);
 	}
 	return 0;
 }
 
-/*
- * Input Argument/s: 
- *  sp - private member of the device structure, which is a pointer to the 
- *   	s2io_nic structure.
- *  eeprom - pointer to the user level structure provided by ethtool, 
- *   containing all relevant information.
- *  data_buf - user defined value to be written into Eeprom.
- * Return value:
- *  '0' on success, -EFAULT on failure.
- * Description:
+/**
+ *  s2io_ethtool_seeprom - tries to write the user provided value in Eeprom
+ *  @sp : private member of the device structure, which is a pointer to the
+ *  s2io_nic structure.
+ *  @eeprom : pointer to the user level structure provided by ethtool, 
+ *  containing all relevant information.
+ *  @data_buf ; user defined value to be written into Eeprom.
+ *  Description:
  *  Tries to write the user provided value in the Eeprom, at the offset
  *  given by the user.
+ *  Return value:
+ *  0 on success, -EFAULT on failure.
  */
+
 static int s2io_ethtool_seeprom(struct net_device *dev,
 				struct ethtool_eeprom *eeprom,
 				u8 * data_buf)
@@ -3083,7 +3531,7 @@
 		} else
 			valid = data;
 
-		if (writeEeprom(sp, (eeprom->offset + cnt), valid, 0)) {
+		if (write_eeprom(sp, (eeprom->offset + cnt), valid, 0)) {
 			DBG_PRINT(ERR_DBG,
 				  "ETHTOOL_WRITE_EEPROM Err: Cannot ");
 			DBG_PRINT(ERR_DBG,
@@ -3097,21 +3545,22 @@
 	return 0;
 }
 
-/*
- * Input Argument/s: 
- *  sp - private member of the device structure, which is a pointer to the 
- *   	s2io_nic structure.
- *  data - variable that returns the result of each of the test conducted by 
- *  	the driver.
- * Return value:
- *  '0' on success.
+/**
+ * s2io_register_test - reads and writes into all clock domains. 
+ * @sp : private member of the device structure, which is a pointer to the 
+ * s2io_nic structure.
+ * @data : variable that returns the result of each of the test conducted b
+ * by the driver.
  * Description:
- *  Read and write into all clock domains. The NIC has 3 clock domains,
- *  see that registers in all the three regions are accessible.
+ * Read and write into all clock domains. The NIC has 3 clock domains,
+ * see that registers in all the three regions are accessible.
+ * Return value:
+ * 0 on success.
  */
-static int s2io_registerTest(nic_t * sp, uint64_t * data)
+
+static int s2io_register_test(nic_t * sp, uint64_t * data)
 {
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0;
+	XENA_dev_config_t __iomem *bar0 = sp->bar0;
 	u64 val64 = 0;
 	int fail = 0;
 
@@ -3159,88 +3608,91 @@
 	return 0;
 }
 
-/*
- * Input Argument/s: 
- *  sp - private member of the device structure, which is a pointer to the 
- *   	s2io_nic structure.
- *  data - variable that returns the result of each of the test conducted by 
- *  	the driver.
- * Return value:
- *  '0' on success.
+/**
+ * s2io_eeprom_test - to verify that EEprom in the xena can be programmed. 
+ * @sp : private member of the device structure, which is a pointer to the
+ * s2io_nic structure.
+ * @data:variable that returns the result of each of the test conducted by
+ * the driver.
  * Description:
- *  Verify that EEPROM in the xena can be programmed using I2C_CONTROL 
- *  register.
+ * Verify that EEPROM in the xena can be programmed using I2C_CONTROL 
+ * register.
+ * Return value:
+ * 0 on success.
  */
-static int s2io_eepromTest(nic_t * sp, uint64_t * data)
+
+static int s2io_eeprom_test(nic_t * sp, uint64_t * data)
 {
-	int fail = 0, ret_data;
+	int fail = 0;
+	u32 ret_data;
 
 	/* Test Write Error at offset 0 */
-	if (!writeEeprom(sp, 0, 0, 3))
+	if (!write_eeprom(sp, 0, 0, 3))
 		fail = 1;
 
 	/* Test Write at offset 4f0 */
-	if (writeEeprom(sp, 0x4F0, 0x01234567, 3))
+	if (write_eeprom(sp, 0x4F0, 0x01234567, 3))
 		fail = 1;
-	if ((ret_data = readEeprom(sp, 0x4f0)) < 0)
+	if (read_eeprom(sp, 0x4F0, &ret_data))
 		fail = 1;
 
 	if (ret_data != 0x01234567)
 		fail = 1;
 
 	/* Reset the EEPROM data go FFFF */
-	writeEeprom(sp, 0x4F0, 0xFFFFFFFF, 3);
+	write_eeprom(sp, 0x4F0, 0xFFFFFFFF, 3);
 
 	/* Test Write Request Error at offset 0x7c */
-	if (!writeEeprom(sp, 0x07C, 0, 3))
+	if (!write_eeprom(sp, 0x07C, 0, 3))
 		fail = 1;
 
 	/* Test Write Request at offset 0x7fc */
-	if (writeEeprom(sp, 0x7FC, 0x01234567, 3))
+	if (write_eeprom(sp, 0x7FC, 0x01234567, 3))
 		fail = 1;
-	if ((ret_data = readEeprom(sp, 0x7FC)) < 0)
+	if (read_eeprom(sp, 0x7FC, &ret_data))
 		fail = 1;
 
 	if (ret_data != 0x01234567)
 		fail = 1;
 
 	/* Reset the EEPROM data go FFFF */
-	writeEeprom(sp, 0x7FC, 0xFFFFFFFF, 3);
+	write_eeprom(sp, 0x7FC, 0xFFFFFFFF, 3);
 
 	/* Test Write Error at offset 0x80 */
-	if (!writeEeprom(sp, 0x080, 0, 3))
+	if (!write_eeprom(sp, 0x080, 0, 3))
 		fail = 1;
 
 	/* Test Write Error at offset 0xfc */
-	if (!writeEeprom(sp, 0x0FC, 0, 3))
+	if (!write_eeprom(sp, 0x0FC, 0, 3))
 		fail = 1;
 
 	/* Test Write Error at offset 0x100 */
-	if (!writeEeprom(sp, 0x100, 0, 3))
+	if (!write_eeprom(sp, 0x100, 0, 3))
 		fail = 1;
 
 	/* Test Write Error at offset 4ec */
-	if (!writeEeprom(sp, 0x4EC, 0, 3))
+	if (!write_eeprom(sp, 0x4EC, 0, 3))
 		fail = 1;
 
 	*data = fail;
 	return 0;
 }
 
-/*
- * Input Argument/s: 
- *  sp - private member of the device structure, which is a pointer to the 
- *   	s2io_nic structure.
- *  data - variable that returns the result of each of the test conducted by 
- *  	the driver.
- * Return value:
- *  '0' on success and -1 on failure.
+/**
+ * s2io_bist_test - invokes the MemBist test of the card .
+ * @sp : private member of the device structure, which is a pointer to the 
+ * s2io_nic structure.
+ * @data:variable that returns the result of each of the test conducted by 
+ * the driver.
  * Description:
- *  This invokes the MemBist test of the card. We give around
- *  2 secs time for the Test to complete. If it's still not complete
- *  within this peiod, we consider that the test failed. 
+ * This invokes the MemBist test of the card. We give around
+ * 2 secs time for the Test to complete. If it's still not complete
+ * within this peiod, we consider that the test failed. 
+ * Return value:
+ * 0 on success and -1 on failure.
  */
-static int s2io_bistTest(nic_t * sp, uint64_t * data)
+
+static int s2io_bist_test(nic_t * sp, uint64_t * data)
 {
 	u8 bist = 0;
 	int cnt = 0, ret = -1;
@@ -3264,21 +3716,22 @@
 	return ret;
 }
 
-/*
- * Input Argument/s: 
- *  sp - private member of the device structure, which is a pointer to the 
- *   	s2io_nic structure.
- *  data - variable that returns the result of each of the test conducted by 
- *  	the driver.
- * Return value:
- *  '0' on success.
+/**
+ * s2io-link_test - verifies the link state of the nic  
+ * @sp ; private member of the device structure, which is a pointer to the 
+ * s2io_nic structure.
+ * @data: variable that returns the result of each of the test conducted by
+ * the driver.
  * Description:
- *  The function verifies the link state of the NIC and updates the input 
- *  argument 'data' appropriately.
+ * The function verifies the link state of the NIC and updates the input 
+ * argument 'data' appropriately.
+ * Return value:
+ * 0 on success.
  */
-static int s2io_linkTest(nic_t * sp, uint64_t * data)
+
+static int s2io_link_test(nic_t * sp, uint64_t * data)
 {
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0;
+	XENA_dev_config_t __iomem *bar0 = sp->bar0;
 	u64 val64;
 
 	val64 = readq(&bar0->adapter_status);
@@ -3288,21 +3741,22 @@
 	return 0;
 }
 
-/*
- * Input Argument/s: 
- *  sp - private member of the device structure, which is a pointer to the 
- *   	s2io_nic structure.
- *  data - variable that returns the result of each of the test conducted by 
- *  	the driver.
- * Return value:
- *  '0' on success.
+/**
+ * s2io_rldram_test - offline test for access to the RldRam chip on the NIC 
+ * @sp - private member of the device structure, which is a pointer to the  
+ * s2io_nic structure.
+ * @data - variable that returns the result of each of the test 
+ * conducted by the driver.
  * Description:
  *  This is one of the offline test that tests the read and write 
  *  access to the RldRam chip on the NIC.
+ * Return value:
+ *  0 on success.
  */
-static int s2io_rldramTest(nic_t * sp, uint64_t * data)
+
+static int s2io_rldram_test(nic_t * sp, uint64_t * data)
 {
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0;
+	XENA_dev_config_t __iomem *bar0 = sp->bar0;
 	u64 val64;
 	int cnt, iteration = 0, test_pass = 0;
 
@@ -3316,10 +3770,10 @@
 
 	val64 = readq(&bar0->mc_rldram_mrs);
 	val64 |= MC_RLDRAM_QUEUE_SIZE_ENABLE;
-	writeq(val64, &bar0->mc_rldram_mrs);
+	SPECIAL_REG_WRITE(val64, &bar0->mc_rldram_mrs, UF);
 
 	val64 |= MC_RLDRAM_MRS_ENABLE;
-	writeq(val64, &bar0->mc_rldram_mrs);
+	SPECIAL_REG_WRITE(val64, &bar0->mc_rldram_mrs, UF);
 
 	while (iteration < 2) {
 		val64 = 0x55555555aaaa0000ULL;
@@ -3395,20 +3849,21 @@
 	return 0;
 }
 
-/*
- * Input Argument/s: 
- *  sp - private member of the device structure, which is a pointer to the 
- *   	s2io_nic structure.
- *  ethtest - pointer to a ethtool command specific structure that will be
- *  	returned to the user.
- *  data - variable that returns the result of each of the test conducted by 
- *  	the driver.
- * Return value:
- *  SUCCESS on success and an appropriate -1 on failure.
+/**
+ *  s2io_ethtool_test - conducts 6 tsets to determine the health of card.
+ *  @sp : private member of the device structure, which is a pointer to the
+ *  s2io_nic structure.
+ *  @ethtest : pointer to a ethtool command specific structure that will be
+ *  returned to the user.
+ *  @data : variable that returns the result of each of the test 
+ * conducted by the driver.
  * Description:
  *  This function conducts 6 tests ( 4 offline and 2 online) to determine
- *  	the health of the card.
+ *  the health of the card.
+ * Return value:
+ *  void
  */
+
 static void s2io_ethtool_test(struct net_device *dev,
 			      struct ethtool_test *ethtest,
 			      uint64_t * data)
@@ -3424,22 +3879,22 @@
 		} else
 			s2io_set_swapper(sp);
 
-		if (s2io_registerTest(sp, &data[0]))
+		if (s2io_register_test(sp, &data[0]))
 			ethtest->flags |= ETH_TEST_FL_FAILED;
 
 		s2io_reset(sp);
 		s2io_set_swapper(sp);
 
-		if (s2io_rldramTest(sp, &data[3]))
+		if (s2io_rldram_test(sp, &data[3]))
 			ethtest->flags |= ETH_TEST_FL_FAILED;
 
 		s2io_reset(sp);
 		s2io_set_swapper(sp);
 
-		if (s2io_eepromTest(sp, &data[1]))
+		if (s2io_eeprom_test(sp, &data[1]))
 			ethtest->flags |= ETH_TEST_FL_FAILED;
 
-		if (s2io_bistTest(sp, &data[4]))
+		if (s2io_bist_test(sp, &data[4]))
 			ethtest->flags |= ETH_TEST_FL_FAILED;
 
 		if (orig_state)
@@ -3459,7 +3914,7 @@
 			data[4] = -1;
 		}
 
-		if (s2io_linkTest(sp, &data[2]))
+		if (s2io_link_test(sp, &data[2]))
 			ethtest->flags |= ETH_TEST_FL_FAILED;
 
 		data[0] = 0;
@@ -3475,7 +3930,7 @@
 {
 	int i = 0;
 	nic_t *sp = dev->priv;
-	StatInfo_t *stat_info = sp->mac_control.StatsInfo;
+	StatInfo_t *stat_info = sp->mac_control.stats_info;
 
 	tmp_stats[i++] = stat_info->tmac_frms;
 	tmp_stats[i++] = stat_info->tmac_data_octets;
@@ -3567,6 +4022,17 @@
 	return (S2IO_STAT_LEN);
 }
 
+int s2io_ethtool_op_set_tx_csum(struct net_device *dev, u32 data)
+{
+	if (data)
+		dev->features |= NETIF_F_IP_CSUM;
+	else
+		dev->features &= ~NETIF_F_IP_CSUM;
+
+	return 0;
+}
+
+
 static struct ethtool_ops netdev_ethtool_ops = {
 	.get_settings = s2io_ethtool_gset,
 	.set_settings = s2io_ethtool_sset,
@@ -3582,7 +4048,7 @@
 	.get_rx_csum = s2io_ethtool_get_rx_csum,
 	.set_rx_csum = s2io_ethtool_set_rx_csum,
 	.get_tx_csum = ethtool_op_get_tx_csum,
-	.set_tx_csum = ethtool_op_set_tx_csum,
+	.set_tx_csum = s2io_ethtool_op_set_tx_csum,
 	.get_sg = ethtool_op_get_sg,
 	.set_sg = ethtool_op_set_sg,
 #ifdef NETIF_F_TSO
@@ -3597,40 +4063,41 @@
 	.get_ethtool_stats = s2io_get_ethtool_stats
 };
 
-/*
- *  Input Argument/s: 
- *  dev -   Device pointer.
- *  ifr -   An IOCTL specefic structure, that can contain a pointer to
- *      a proprietary structure used to pass information to the driver.
- *  cmd -   This is used to distinguish between the different commands that
- *      can be passed to the IOCTL functions.
- *  Return value:
- *  '0' on success and an appropriate (-)ve integer as defined in errno.h
- *  file on failure.
+/**
+ *  s2io_ioctl - Entry point for the Ioctl 
+ *  @dev :  Device pointer.
+ *  @ifr :  An IOCTL specefic structure, that can contain a pointer to
+ *  a proprietary structure used to pass information to the driver.
+ *  @cmd :  This is used to distinguish between the different commands that
+ *  can be passed to the IOCTL functions.
  *  Description:
  *  This function has support for ethtool, adding multiple MAC addresses on 
  *  the NIC and some DBG commands for the util tool.
+ *  Return value:
+ *  Currently the IOCTL supports no operations, hence by default this
+ *  function returns OP NOT SUPPORTED value.
  */
+
 int s2io_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
 	return -EOPNOTSUPP;
 }
 
-/*
- *  Input Argument/s: 
- *   dev - device pointer.
- *   new_mtu - the new MTU size for the device.
+/**
+ *  s2io_change_mtu - entry point to change MTU size for the device.
+ *   @dev : device pointer.
+ *   @new_mtu : the new MTU size for the device.
+ *   Description: A driver entry point to change MTU size for the device.
+ *   Before changing the MTU the device must be stopped.
  *  Return value:
- *   '0' on success and an appropriate (-)ve integer as defined in errno.h
+ *   0 on success and an appropriate (-)ve integer as defined in errno.h
  *   file on failure.
- *  Description:
- *   A driver entry point to change MTU size for the device. Before changing
- *   the MTU the device must be stopped.
  */
+
 int s2io_change_mtu(struct net_device *dev, int new_mtu)
 {
 	nic_t *sp = dev->priv;
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0;
+	XENA_dev_config_t __iomem *bar0 = sp->bar0;
 	register u64 val64;
 
 	if (netif_running(dev)) {
@@ -3645,7 +4112,7 @@
 		return -EPERM;
 	}
 
-/* Set the new MTU into the PYLD register of the NIC */
+	/* Set the new MTU into the PYLD register of the NIC */
 	val64 = new_mtu;
 	writeq(vBIT(val64, 2, 14), &bar0->rmac_max_pyld_len);
 
@@ -3654,18 +4121,19 @@
 	return 0;
 }
 
-/*
- *  Input Argument/s: 
- *  dev_adr - address of the device structure in dma_addr_t format.
- *  Return value:
- *  void.
+/**
+ *  s2io_tasklet - Bottom half of the ISR.
+ *  @dev_adr : address of the device structure in dma_addr_t format.
  *  Description:
  *  This is the tasklet or the bottom half of the ISR. This is
  *  an extension of the ISR which is scheduled by the scheduler to be run 
  *  when the load on the CPU is low. All low priority tasks of the ISR can
  *  be pushed into the tasklet. For now the tasklet is used only to 
  *  replenish the Rx buffers in the Rx buffer descriptors.
+ *  Return value:
+ *  void.
  */
+
 static void s2io_tasklet(unsigned long dev_addr)
 {
 	struct net_device *dev = (struct net_device *) dev_addr;
@@ -3678,37 +4146,46 @@
 	config = &sp->config;
 
 	if (!TASKLET_IN_USE) {
-		for (i = 0; i < config->RxRingNum; i++) {
+		for (i = 0; i < config->rx_ring_num; i++) {
 			ret = fill_rx_buffers(sp, i);
 			if (ret == -ENOMEM) {
 				DBG_PRINT(ERR_DBG, "%s: Out of ",
 					  dev->name);
 				DBG_PRINT(ERR_DBG, "memory in tasklet\n");
-				return;
+				break;
 			} else if (ret == -EFILL) {
 				DBG_PRINT(ERR_DBG,
 					  "%s: Rx Ring %d is full\n",
 					  dev->name, i);
-				return;
+				break;
 			}
 		}
-		clear_bit(0, (unsigned long *) (&sp->tasklet_status));
+		clear_bit(0, (&sp->tasklet_status));
 	}
 }
 
-
-/*
- * Description:
- * 
+/**
+ * s2io_set_link - Set the LInk status
+ * @data: long pointer to device private structue
+ * Description: Sets the link status for the adapter
  */
+
 static void s2io_set_link(unsigned long data)
 {
 	nic_t *nic = (nic_t *) data;
 	struct net_device *dev = nic->dev;
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
-	register u64 val64, err_reg;
+	XENA_dev_config_t __iomem *bar0 = nic->bar0;
+	register u64 val64;
+	u16 subid;
+
+	if (test_and_set_bit(0, &(nic->link_state))) {
+		/* The card is being reset, no point doing anything */
+		return;
+	}
 
-	/* Allow a small delay for the NICs self initiated 
+	subid = nic->pdev->subsystem_device;
+	/* 
+	 * Allow a small delay for the NICs self initiated 
 	 * cleanup to complete.
 	 */
 	set_current_state(TASK_UNINTERRUPTIBLE);
@@ -3716,16 +4193,19 @@
 
 	val64 = readq(&bar0->adapter_status);
 	if (verify_xena_quiescence(val64, nic->device_enabled_once)) {
-		/* Acknowledge interrupt and clear the R1 register */
-		err_reg = readq(&bar0->mac_rmac_err_reg);
-		writeq(err_reg, &bar0->mac_rmac_err_reg);
-
 		if (LINK_IS_UP(val64)) {
 			val64 = readq(&bar0->adapter_control);
 			val64 |= ADAPTER_CNTL_EN;
 			writeq(val64, &bar0->adapter_control);
-			val64 |= ADAPTER_LED_ON;
-			writeq(val64, &bar0->adapter_control);
+			if (CARDS_WITH_FAULTY_LINK_INDICATORS(subid)) {
+				val64 = readq(&bar0->gpio_control);
+				val64 |= GPIO_CTRL_GPIO_0;
+				writeq(val64, &bar0->gpio_control);
+				val64 = readq(&bar0->gpio_control);
+			} else {
+				val64 |= ADAPTER_LED_ON;
+				writeq(val64, &bar0->adapter_control);
+			}
 			val64 = readq(&bar0->adapter_status);
 			if (!LINK_IS_UP(val64)) {
 				DBG_PRINT(ERR_DBG, "%s:", dev->name);
@@ -3739,6 +4219,12 @@
 			}
 			s2io_link(nic, LINK_UP);
 		} else {
+			if (CARDS_WITH_FAULTY_LINK_INDICATORS(subid)) {
+				val64 = readq(&bar0->gpio_control);
+				val64 &= ~GPIO_CTRL_GPIO_0;
+				writeq(val64, &bar0->gpio_control);
+				val64 = readq(&bar0->gpio_control);
+			}
 			s2io_link(nic, LINK_DOWN);
 		}
 	} else {		/* NIC is not Quiescent. */
@@ -3746,39 +4232,149 @@
 		DBG_PRINT(ERR_DBG, "device is not Quiescent\n");
 		netif_stop_queue(dev);
 	}
+	clear_bit(0, &(nic->link_state));
+}
+
+static void s2io_card_down(nic_t * sp)
+{
+	int cnt = 0;
+	XENA_dev_config_t __iomem *bar0 = sp->bar0;
+	unsigned long flags;
+	register u64 val64 = 0;
+
+	/* If s2io_set_link task is executing, wait till it completes. */
+	while (test_and_set_bit(0, &(sp->link_state))) {
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		schedule_timeout(HZ / 20);
+	}
+	atomic_set(&sp->card_state, CARD_DOWN);
+
+	/* disable Tx and Rx traffic on the NIC */
+	stop_nic(sp);
+
+	/* Kill tasklet. */
+	tasklet_kill(&sp->task);
+
+	/* Check if the device is Quiescent and then Reset the NIC */
+	do {
+		val64 = readq(&bar0->adapter_status);
+		if (verify_xena_quiescence(val64, sp->device_enabled_once)) {
+			break;
+		}
+
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		schedule_timeout(HZ / 20);
+		cnt++;
+		if (cnt == 10) {
+			DBG_PRINT(ERR_DBG,
+				  "s2io_close:Device not Quiescent ");
+			DBG_PRINT(ERR_DBG, "adaper status reads 0x%llx\n",
+				  (unsigned long long) val64);
+			break;
+		}
+	} while (1);
+	spin_lock_irqsave(&sp->tx_lock, flags);
+	s2io_reset(sp);
+
+	/* Free all unused Tx and Rx buffers */
+	free_tx_buffers(sp);
+	free_rx_buffers(sp);
+
+	spin_unlock_irqrestore(&sp->tx_lock, flags);
+	clear_bit(0, &(sp->link_state));
+}
+
+static int s2io_card_up(nic_t * sp)
+{
+	int i, ret;
+	mac_info_t *mac_control;
+	struct config_param *config;
+	struct net_device *dev = (struct net_device *) sp->dev;
+
+	/* Initialize the H/W I/O registers */
+	if (init_nic(sp) != 0) {
+		DBG_PRINT(ERR_DBG, "%s: H/W initialization failed\n",
+			  dev->name);
+		return -ENODEV;
+	}
+
+	/* 
+	 * Initializing the Rx buffers. For now we are considering only 1 
+	 * Rx ring and initializing buffers into 30 Rx blocks
+	 */
+	mac_control = &sp->mac_control;
+	config = &sp->config;
+
+	for (i = 0; i < config->rx_ring_num; i++) {
+		if ((ret = fill_rx_buffers(sp, i))) {
+			DBG_PRINT(ERR_DBG, "%s: Out of memory in Open\n",
+				  dev->name);
+			s2io_reset(sp);
+			free_rx_buffers(sp);
+			return -ENOMEM;
+		}
+		DBG_PRINT(INFO_DBG, "Buf in ring:%d is %d:\n", i,
+			  atomic_read(&sp->rx_bufs_left[i]));
+	}
+
+	/* Setting its receive mode */
+	s2io_set_multicast(dev);
+
+	/* Enable tasklet for the device */
+	tasklet_init(&sp->task, s2io_tasklet, (unsigned long) dev);
+
+	/* Enable Rx Traffic and interrupts on the NIC */
+	if (start_nic(sp)) {
+		DBG_PRINT(ERR_DBG, "%s: Starting NIC failed\n", dev->name);
+		tasklet_kill(&sp->task);
+		s2io_reset(sp);
+		free_irq(dev->irq, dev);
+		free_rx_buffers(sp);
+		return -ENODEV;
+	}
+
+	atomic_set(&sp->card_state, CARD_UP);
+	return 0;
 }
 
-/*
+/** 
+ * s2io_restart_nic - Resets the NIC.
+ * @data : long pointer to the device private structure
  * Description:
  * This function is scheduled to be run by the s2io_tx_watchdog
  * function after 0.5 secs to reset the NIC. The idea is to reduce 
  * the run time of the watch dog routine which is run holding a
  * spin lock.
  */
+
 static void s2io_restart_nic(unsigned long data)
 {
 	struct net_device *dev = (struct net_device *) data;
 	nic_t *sp = dev->priv;
 
-	s2io_close(dev);
-	sp->device_close_flag = TRUE;
-	s2io_open(dev);
-	DBG_PRINT(ERR_DBG,
-		  "%s: was reset by Tx watchdog timer.\n", dev->name);
+	s2io_card_down(sp);
+	if (s2io_card_up(sp)) {
+		DBG_PRINT(ERR_DBG, "%s: Device bring up failed\n",
+			  dev->name);
+	}
+	netif_wake_queue(dev);
+	DBG_PRINT(ERR_DBG, "%s: was reset by Tx watchdog timer\n",
+		  dev->name);
 }
 
-/*
- *  Input Argument/s: 
- *  dev - device pointer.
- *  Return value:
- *  void
+/** 
+ *  s2io_tx_watchdog - Watchdog for transmit side. 
+ *  @dev : Pointer to net device structure
  *  Description:
  *  This function is triggered if the Tx Queue is stopped
  *  for a pre-defined amount of time when the Interface is still up.
  *  If the Interface is jammed in such a situation, the hardware is
  *  reset (by s2io_close) and restarted again (by s2io_open) to
  *  overcome any problem that might have been caused in the hardware.
+ *  Return value:
+ *  void
  */
+
 static void s2io_tx_watchdog(struct net_device *dev)
 {
 	nic_t *sp = dev->priv;
@@ -3788,36 +4384,45 @@
 	}
 }
 
-/*
- *  Input Argument/s: 
- *   sp - private member of the device structure, which is a pointer to the 
- *   s2io_nic structure.
- *   skb - the socket buffer pointer.
- *   len - length of the packet
- *   cksum - FCS checksum of the frame.
- *  ring_no - the ring from which this RxD was extracted.
- *  Return value:
- *   SUCCESS on success and -1 on failure.
- *  Description: 
- *   This function is called by the Tx interrupt serivce routine to perform 
+/**
+ *   rx_osm_handler - To perform some OS related operations on SKB.
+ *   @sp: private member of the device structure,pointer to s2io_nic structure.
+ *   @skb : the socket buffer pointer.
+ *   @len : length of the packet
+ *   @cksum : FCS checksum of the frame.
+ *   @ring_no : the ring from which this RxD was extracted.
+ *   Description: 
+ *   This function is called by the Tx interrupt serivce routine to perform
  *   some OS related operations on the SKB before passing it to the upper
  *   layers. It mainly checks if the checksum is OK, if so adds it to the
  *   SKBs cksum variable, increments the Rx packet count and passes the SKB
  *   to the upper layer. If the checksum is wrong, it increments the Rx
  *   packet error count, frees the SKB and returns error.
+ *   Return value:
+ *   SUCCESS on success and -1 on failure.
  */
-static int rxOsmHandler(nic_t * sp, u16 len, RxD_t * rxdp, int ring_no)
+#ifndef CONFIG_2BUFF_MODE
+static int rx_osm_handler(nic_t * sp, u16 len, RxD_t * rxdp, int ring_no)
+#else
+static int rx_osm_handler(nic_t * sp, RxD_t * rxdp, int ring_no,
+			  buffAdd_t * ba)
+#endif
 {
 	struct net_device *dev = (struct net_device *) sp->dev;
 	struct sk_buff *skb =
 	    (struct sk_buff *) ((unsigned long) rxdp->Host_Control);
 	u16 l3_csum, l4_csum;
+#ifdef CONFIG_2BUFF_MODE
+	int buf0_len, buf2_len;
+	unsigned char *buff;
+#endif
 
 	l3_csum = RXD_GET_L3_CKSUM(rxdp->Control_1);
 	if ((rxdp->Control_1 & TCP_OR_UDP_FRAME) && (sp->rx_csum)) {
 		l4_csum = RXD_GET_L4_CKSUM(rxdp->Control_1);
 		if ((l3_csum == L3_CKSUM_OK) && (l4_csum == L4_CKSUM_OK)) {
-			/* NIC verifies if the Checksum of the received
+			/* 
+			 * NIC verifies if the Checksum of the received
 			 * frame is Ok or not and accordingly returns
 			 * a flag in the RxD.
 			 */
@@ -3833,9 +4438,26 @@
 		skb->ip_summed = CHECKSUM_NONE;
 	}
 
+	if (rxdp->Control_1 & RXD_T_CODE) {
+		unsigned long long err = rxdp->Control_1 & RXD_T_CODE;
+		DBG_PRINT(ERR_DBG, "%s: Rx error Value: 0x%llx\n",
+			  dev->name, err);
+	}
+#ifdef CONFIG_2BUFF_MODE
+	buf0_len = RXD_GET_BUFFER0_SIZE(rxdp->Control_2);
+	buf2_len = RXD_GET_BUFFER2_SIZE(rxdp->Control_2);
+#endif
+
 	skb->dev = dev;
+#ifndef CONFIG_2BUFF_MODE
 	skb_put(skb, len);
 	skb->protocol = eth_type_trans(skb, dev);
+#else
+	buff = skb_push(skb, buf0_len);
+	memcpy(buff, ba->ba_0, buf0_len);
+	skb_put(skb, buf2_len);
+	skb->protocol = eth_type_trans(skb, dev);
+#endif
 
 #ifdef CONFIG_S2IO_NAPI
 	netif_receive_skb(skb);
@@ -3844,50 +4466,32 @@
 #endif
 
 	dev->last_rx = jiffies;
-#if DEBUG_ON
-	sp->rxpkt_cnt++;
-#endif
 	sp->rx_pkt_count++;
 	sp->stats.rx_packets++;
+#ifndef CONFIG_2BUFF_MODE
 	sp->stats.rx_bytes += len;
-	sp->rxpkt_bytes += len;
+#else
+	sp->stats.rx_bytes += buf0_len + buf2_len;
+#endif
 
 	atomic_dec(&sp->rx_bufs_left[ring_no]);
 	rxdp->Host_Control = 0;
 	return SUCCESS;
 }
 
-int check_for_txSpace(nic_t * sp)
-{
-	u32 put_off, get_off, queue_len;
-	int ret = TRUE, i;
-
-	for (i = 0; i < sp->config.TxFIFONum; i++) {
-		queue_len = sp->mac_control.tx_curr_put_info[i].fifo_len
-		    + 1;
-		put_off = sp->mac_control.tx_curr_put_info[i].offset;
-		get_off = sp->mac_control.tx_curr_get_info[i].offset;
-		if (((put_off + 1) % queue_len) == get_off) {
-			ret = FALSE;
-			break;
-		}
-	}
-
-	return ret;
-}
+/**
+ *  s2io_link - stops/starts the Tx queue.
+ *  @sp : private member of the device structure, which is a pointer to the
+ *  s2io_nic structure.
+ *  @link : inidicates whether link is UP/DOWN.
+ *  Description:
+ *  This function stops/starts the Tx queue depending on whether the link
+ *  status of the NIC is is down or up. This is called by the Alarm 
+ *  interrupt handler whenever a link change interrupt comes up. 
+ *  Return value:
+ *  void.
+ */
 
-/*
-*  Input Argument/s: 
-*   sp - private member of the device structure, which is a pointer to the 
-*   s2io_nic structure.
-*   link - inidicates whether link is UP/DOWN.
-*  Return value:
-*   void.
-*  Description:
-*   This function stops/starts the Tx queue depending on whether the link
-*   status of the NIC is is down or up. This is called by the Alarm interrupt 
-*  handler whenever a link change interrupt comes up. 
-*/
 void s2io_link(nic_t * sp, int link)
 {
 	struct net_device *dev = (struct net_device *) sp->dev;
@@ -3896,29 +4500,23 @@
 		if (link == LINK_DOWN) {
 			DBG_PRINT(ERR_DBG, "%s: Link down\n", dev->name);
 			netif_carrier_off(dev);
-			netif_stop_queue(dev);
 		} else {
 			DBG_PRINT(ERR_DBG, "%s: Link Up\n", dev->name);
 			netif_carrier_on(dev);
-			if (check_for_txSpace(sp) == TRUE) {
-				/* Don't wake the queue, if we know there
-				 * are no free TxDs available.
-				 */
-				netif_wake_queue(dev);
-			}
 		}
 	}
 	sp->last_link_state = link;
 }
 
-/*
-*  Input Argument/s: 
-*   pdev - structure containing the PCI related information of the device.
-*  Return value:
-*   returns the revision ID of the device.
-*  Description:
-*   Function to identify the Revision ID of xena.
-*/
+/**
+ *  get_xena_rev_id - to identify revision ID of xena. 
+ *  @pdev : PCI Dev structure
+ *  Description:
+ *  Function to identify the Revision ID of xena.
+ *  Return value:
+ *  returns the revision ID of the device.
+ */
+
 int get_xena_rev_id(struct pci_dev *pdev)
 {
 	u8 id = 0;
@@ -3927,21 +4525,22 @@
 	return id;
 }
 
-/*
-*  Input Argument/s: 
-*   sp - private member of the device structure, which is a pointer to the 
-*   s2io_nic structure.
-*  Return value:
-*   void
-*  Description:
-*   This function initializes a few of the PCI and PCI-X configuration registers
-*   with recommended values.
-*/
+/**
+ *  s2io_init_pci -Initialization of PCI and PCI-X configuration registers . 
+ *  @sp : private member of the device structure, which is a pointer to the 
+ *  s2io_nic structure.
+ *  Description:
+ *  This function initializes a few of the PCI and PCI-X configuration registers
+ *  with recommended values.
+ *  Return value:
+ *  void
+ */
+
 static void s2io_init_pci(nic_t * sp)
 {
 	u16 pci_cmd = 0;
 
-/* Enable Data Parity Error Recovery in PCI-X command register. */
+	/* Enable Data Parity Error Recovery in PCI-X command register. */
 	pci_read_config_word(sp->pdev, PCIX_COMMAND_REGISTER,
 			     &(sp->pcix_cmd));
 	pci_write_config_word(sp->pdev, PCIX_COMMAND_REGISTER,
@@ -3949,63 +4548,64 @@
 	pci_read_config_word(sp->pdev, PCIX_COMMAND_REGISTER,
 			     &(sp->pcix_cmd));
 
-/* Set the PErr Response bit in PCI command register. */
+	/* Set the PErr Response bit in PCI command register. */
 	pci_read_config_word(sp->pdev, PCI_COMMAND, &pci_cmd);
 	pci_write_config_word(sp->pdev, PCI_COMMAND,
 			      (pci_cmd | PCI_COMMAND_PARITY));
 	pci_read_config_word(sp->pdev, PCI_COMMAND, &pci_cmd);
 
-/* Set user specified value in Latency Timer */
-	if (latency_timer) {
-		pci_write_config_byte(sp->pdev, PCI_LATENCY_TIMER,
-				      latency_timer);
-		pci_read_config_byte(sp->pdev, PCI_LATENCY_TIMER,
-				     &latency_timer);
-	}
-
-/* Set MMRB count to 4096 in PCI-X Command register. */
-	pci_write_config_word(sp->pdev, PCIX_COMMAND_REGISTER,
-			      (sp->pcix_cmd | 0x0C));
+	/* Set MMRB count to 1024 in PCI-X Command register. */
+	sp->pcix_cmd &= 0xFFF3;
+	pci_write_config_word(sp->pdev, PCIX_COMMAND_REGISTER, (sp->pcix_cmd | (0x1 << 2)));	/* MMRBC 1K */
 	pci_read_config_word(sp->pdev, PCIX_COMMAND_REGISTER,
 			     &(sp->pcix_cmd));
 
-/* Setting Maximum outstanding splits to two for now. */
-	sp->pcix_cmd &= 0xFF1F;
+	/*  Setting Maximum outstanding splits based on system type. */
+	sp->pcix_cmd &= 0xFF8F;
 
-	sp->pcix_cmd |=
-	    XENA_MAX_OUTSTANDING_SPLITS(XENA_TWO_SPLIT_TRANSACTION);
+	sp->pcix_cmd |= XENA_MAX_OUTSTANDING_SPLITS(0x1);	/* 2 splits. */
+	pci_write_config_word(sp->pdev, PCIX_COMMAND_REGISTER,
+			      sp->pcix_cmd);
+	pci_read_config_word(sp->pdev, PCIX_COMMAND_REGISTER,
+			     &(sp->pcix_cmd));
+	/* Forcibly disabling relaxed ordering capability of the card. */
+	sp->pcix_cmd &= 0xfffd;
 	pci_write_config_word(sp->pdev, PCIX_COMMAND_REGISTER,
 			      sp->pcix_cmd);
 	pci_read_config_word(sp->pdev, PCIX_COMMAND_REGISTER,
 			     &(sp->pcix_cmd));
-
 }
 
 MODULE_AUTHOR("Raghavendra Koushik <raghavendra.koushik@s2io.com>");
 MODULE_LICENSE("GPL");
-module_param(ring_num, uint, 0);
-module_param_array(frame_len, uint, NULL, 0);
-module_param_array(ring_len, uint, NULL, 0);
-module_param(fifo_num, uint, 0);
-module_param_array(fifo_len, uint, NULL, 0);
-module_param(rx_prio, uint, 0);
-module_param(tx_prio, uint, 0);
-module_param(latency_timer, byte, 0);
-
-/*
-*  Input Argument/s: 
-*   pdev - structure containing the PCI related information of the device.
-*   pre -  the List of PCI devices supported by the driver listed in s2io_tbl.
-*  Return value:
-*   returns '0' on success and negative on failure.
-*  Description:
-*  The function initializes an adapter identified by the pci_dec structure.
-*  All OS related initialization including memory and device structure and 
-*  initlaization of the device private variable is done. Also the swapper 
-*  control register is initialized to enable read and write into the I/O 
-*  registers of the device.
-*  
-*/
+module_param(tx_fifo_num, int, 0);
+module_param_array(tx_fifo_len, int, NULL, 0);
+module_param(rx_ring_num, int, 0);
+module_param_array(rx_ring_sz, int, NULL, 0);
+module_param(Stats_refresh_time, int, 0);
+module_param(rmac_pause_time, int, 0);
+module_param(mc_pause_threshold_q0q3, int, 0);
+module_param(mc_pause_threshold_q4q7, int, 0);
+module_param(shared_splits, int, 0);
+module_param(tmac_util_period, int, 0);
+module_param(rmac_util_period, int, 0);
+#ifndef CONFIG_S2IO_NAPI
+module_param(indicate_max_pkts, int, 0);
+#endif
+/**
+ *  s2io_init_nic - Initialization of the adapter . 
+ *  @pdev : structure containing the PCI related information of the device.
+ *  @pre: List of PCI devices supported by the driver listed in s2io_tbl.
+ *  Description:
+ *  The function initializes an adapter identified by the pci_dec structure.
+ *  All OS related initialization including memory and device structure and 
+ *  initlaization of the device private variable is done. Also the swapper 
+ *  control register is initialized to enable read and write into the I/O 
+ *  registers of the device.
+ *  Return value:
+ *  returns 0 on success and negative on failure.
+ */
+
 static int __devinit
 s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
 {
@@ -4016,12 +4616,15 @@
 	int dma_flag = FALSE;
 	u32 mac_up, mac_down;
 	u64 val64 = 0, tmp64 = 0;
-	XENA_dev_config_t *bar0 = NULL;
+	XENA_dev_config_t __iomem *bar0 = NULL;
 	u16 subid;
 	mac_info_t *mac_control;
 	struct config_param *config;
 
 
+	DBG_PRINT(ERR_DBG, "Loading S2IO driver with %s\n",
+		s2io_driver_version);
+
 	if ((ret = pci_enable_device(pdev))) {
 		DBG_PRINT(ERR_DBG,
 			  "s2io_init_nic: pci_enable_device failed\n");
@@ -4031,6 +4634,7 @@
 	if (!pci_set_dma_mask(pdev, 0xffffffffffffffffULL)) {
 		DBG_PRINT(INIT_DBG, "s2io_init_nic: Using 64bit DMA\n");
 		dma_flag = TRUE;
+
 		if (pci_set_consistent_dma_mask
 		    (pdev, 0xffffffffffffffffULL)) {
 			DBG_PRINT(ERR_DBG,
@@ -4080,7 +4684,8 @@
 	/* Initialize some PCI/PCI-X fields of the NIC. */
 	s2io_init_pci(sp);
 
-	/* Setting the device configuration parameters.
+	/* 
+	 * Setting the device configuration parameters.
 	 * Most of these parameters can be specified by the user during 
 	 * module insertion as they are module loadable parameters. If 
 	 * these parameters are not not specified during load time, they 
@@ -4090,104 +4695,72 @@
 	config = &sp->config;
 
 	/* Tx side parameters. */
-	config->TxFIFONum = fifo_num ? fifo_num : 1;
-
-	if (!fifo_len[0] && (fifo_num > 1)) {
-		printk(KERN_ERR "Fifo Lens not specified for all FIFOs\n");
-		goto init_failed;
-	}
-
-	if (fifo_len[0]) {
-		int cnt;
-
-		for (cnt = 0; fifo_len[cnt]; cnt++);
-		if (fifo_num) {
-			if (cnt < fifo_num) {
-				printk(KERN_ERR
-				       "Fifo Lens not specified for ");
-				printk(KERN_ERR "all FIFOs\n");
-				goto init_failed;
-			}
-		}
-		for (cnt = 0; cnt < config->TxFIFONum; cnt++) {
-			config->TxCfg[cnt].FifoLen = fifo_len[cnt];
-			config->TxCfg[cnt].FifoPriority = cnt;
-		}
-	} else {
-		config->TxCfg[0].FifoLen = DEFAULT_FIFO_LEN;
-		config->TxCfg[0].FifoPriority = 0;
+	tx_fifo_len[0] = DEFAULT_FIFO_LEN;	/* Default value. */
+	config->tx_fifo_num = tx_fifo_num;
+	for (i = 0; i < MAX_TX_FIFOS; i++) {
+		config->tx_cfg[i].fifo_len = tx_fifo_len[i];
+		config->tx_cfg[i].fifo_priority = i;
 	}
 
-	config->TxIntrType = TXD_INT_TYPE_UTILZ;
-	for (i = 0; i < config->TxFIFONum; i++) {
-		if (config->TxCfg[i].FifoLen < 65) {
-			config->TxIntrType = TXD_INT_TYPE_PER_LIST;
+	config->tx_intr_type = TXD_INT_TYPE_UTILZ;
+	for (i = 0; i < config->tx_fifo_num; i++) {
+		config->tx_cfg[i].f_no_snoop =
+		    (NO_SNOOP_TXD | NO_SNOOP_TXD_BUFFER);
+		if (config->tx_cfg[i].fifo_len < 65) {
+			config->tx_intr_type = TXD_INT_TYPE_PER_LIST;
 			break;
 		}
 	}
-
-	config->TxCfg[0].fNoSnoop = (NO_SNOOP_TXD | NO_SNOOP_TXD_BUFFER);
-	config->MaxTxDs = MAX_SKB_FRAGS;
-	config->TxFlow = TRUE;
+	config->max_txds = MAX_SKB_FRAGS;
 
 	/* Rx side parameters. */
-	config->RxRingNum = ring_num ? ring_num : 1;
-
-	if (ring_len[0]) {
-		int cnt;
-		for (cnt = 0; cnt < config->RxRingNum; cnt++) {
-			config->RxCfg[cnt].NumRxd = ring_len[cnt];
-			config->RxCfg[cnt].RingPriority = cnt;
-		}
-	} else {
-		int id;
-		if ((id = get_xena_rev_id(pdev)) == 1) {
-			config->RxCfg[0].NumRxd = LARGE_RXD_CNT;
+	rx_ring_sz[0] = SMALL_BLK_CNT;	/* Default value. */
+	config->rx_ring_num = rx_ring_num;
+	for (i = 0; i < MAX_RX_RINGS; i++) {
+		config->rx_cfg[i].num_rxd = rx_ring_sz[i] *
+		    (MAX_RXDS_PER_BLOCK + 1);
+		config->rx_cfg[i].ring_priority = i;
+	}
 
-		} else {
-			config->RxCfg[0].NumRxd = SMALL_RXD_CNT;
-		}
-		config->RxCfg[0].RingPriority = 0;
+	for (i = 0; i < rx_ring_num; i++) {
+		config->rx_cfg[i].ring_org = RING_ORG_BUFF1;
+		config->rx_cfg[i].f_no_snoop =
+		    (NO_SNOOP_RXD | NO_SNOOP_RXD_BUFFER);
 	}
-	config->RxCfg[0].RingOrg = RING_ORG_BUFF1;
-	config->RxCfg[0].RxdThresh = DEFAULT_RXD_THRESHOLD;
-	config->RxCfg[0].fNoSnoop = (NO_SNOOP_RXD | NO_SNOOP_RXD_BUFFER);
-	config->RxCfg[0].RxD_BackOff_Interval = TBD;
-	config->RxFlow = TRUE;
-
-	/* Miscellaneous parameters. */
-	config->RxVLANEnable = TRUE;
-	config->MTU = MAX_MTU_VLAN;
-	config->JumboEnable = FALSE;
 
 	/*  Setting Mac Control parameters */
-	mac_control->txdl_len = MAX_SKB_FRAGS;
-	mac_control->rmac_pause_time = 0;
+	mac_control->rmac_pause_time = rmac_pause_time;
+	mac_control->mc_pause_threshold_q0q3 = mc_pause_threshold_q0q3;
+	mac_control->mc_pause_threshold_q4q7 = mc_pause_threshold_q4q7;
+
 
 	/* Initialize Ring buffer parameters. */
-	for (i = 0; i < config->RxRingNum; i++)
+	for (i = 0; i < config->rx_ring_num; i++)
 		atomic_set(&sp->rx_bufs_left[i], 0);
 
 	/*  initialize the shared memory used by the NIC and the host */
-	if (initSharedMem(sp)) {
+	if (init_shared_mem(sp)) {
 		DBG_PRINT(ERR_DBG, "%s: Memory allocation failed\n",
 			  dev->name);
+		ret = -ENOMEM;
 		goto mem_alloc_failed;
 	}
 
-	sp->bar0 = (caddr_t) ioremap(pci_resource_start(pdev, 0),
+	sp->bar0 = ioremap(pci_resource_start(pdev, 0),
 				     pci_resource_len(pdev, 0));
 	if (!sp->bar0) {
 		DBG_PRINT(ERR_DBG, "%s: S2IO: cannot remap io mem1\n",
 			  dev->name);
+		ret = -ENOMEM;
 		goto bar0_remap_failed;
 	}
 
-	sp->bar1 = (caddr_t) ioremap(pci_resource_start(pdev, 2),
+	sp->bar1 = ioremap(pci_resource_start(pdev, 2),
 				     pci_resource_len(pdev, 2));
 	if (!sp->bar1) {
 		DBG_PRINT(ERR_DBG, "%s: S2IO: cannot remap io mem2\n",
 			  dev->name);
+		ret = -ENOMEM;
 		goto bar1_remap_failed;
 	}
 
@@ -4196,7 +4769,7 @@
 
 	/* Initializing the BAR1 address as the start of the FIFO pointer. */
 	for (j = 0; j < MAX_TX_FIFOS; j++) {
-		mac_control->tx_FIFO_start[j] = (TxFIFO_element_t *)
+		mac_control->tx_FIFO_start[j] = (TxFIFO_element_t __iomem *)
 		    (sp->bar1 + (j * 0x00020000));
 	}
 
@@ -4209,14 +4782,13 @@
 	dev->do_ioctl = &s2io_ioctl;
 	dev->change_mtu = &s2io_change_mtu;
 	SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
-
 	/*
 	 * will use eth_mac_addr() for  dev->set_mac_address
 	 * mac address will be set every time dev->open() is called
 	 */
 #ifdef CONFIG_S2IO_NAPI
 	dev->poll = s2io_poll;
-	dev->weight = 128;	/* For now. */
+	dev->weight = 90;
 #endif
 
 	dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
@@ -4233,77 +4805,84 @@
 	INIT_WORK(&sp->set_link_task,
 		  (void (*)(void *)) s2io_set_link, sp);
 
-	if (register_netdev(dev)) {
-		DBG_PRINT(ERR_DBG, "Device registration failed\n");
-		goto register_failed;
-	}
-
 	pci_save_state(sp->pdev);
 
 	/* Setting swapper control on the NIC, for proper reset operation */
 	if (s2io_set_swapper(sp)) {
 		DBG_PRINT(ERR_DBG, "%s:swapper settings are wrong\n",
 			  dev->name);
+		ret = -EAGAIN;
 		goto set_swap_failed;
 	}
 
 	/* Fix for all "FFs" MAC address problems observed on Alpha platforms */
-	FixMacAddress(sp);
+	fix_mac_address(sp);
 	s2io_reset(sp);
 
-	/* Setting swapper control on the NIC, so the MAC address can be read.
+	/*
+	 * Setting swapper control on the NIC, so the MAC address can be read.
 	 */
 	if (s2io_set_swapper(sp)) {
 		DBG_PRINT(ERR_DBG,
 			  "%s: S2IO: swapper settings are wrong\n",
 			  dev->name);
+		ret = -EAGAIN;
 		goto set_swap_failed;
 	}
 
-	/*  MAC address initialization.
-	 *  For now only one mac address will be read and used.
+	/*  
+	 * MAC address initialization.
+	 * For now only one mac address will be read and used.
 	 */
-	bar0 = (XENA_dev_config_t *) sp->bar0;
+	bar0 = sp->bar0;
 	val64 = RMAC_ADDR_CMD_MEM_RD | RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD |
 	    RMAC_ADDR_CMD_MEM_OFFSET(0 + MAC_MAC_ADDR_START_OFFSET);
 	writeq(val64, &bar0->rmac_addr_cmd_mem);
-	waitForCmdComplete(sp);
+	wait_for_cmd_complete(sp);
 
 	tmp64 = readq(&bar0->rmac_addr_data0_mem);
 	mac_down = (u32) tmp64;
 	mac_up = (u32) (tmp64 >> 32);
 
-	memset(sp->defMacAddr[0].mac_addr, 0, sizeof(ETH_ALEN));
+	memset(sp->def_mac_addr[0].mac_addr, 0, sizeof(ETH_ALEN));
 
-	sp->defMacAddr[0].mac_addr[3] = (u8) (mac_up);
-	sp->defMacAddr[0].mac_addr[2] = (u8) (mac_up >> 8);
-	sp->defMacAddr[0].mac_addr[1] = (u8) (mac_up >> 16);
-	sp->defMacAddr[0].mac_addr[0] = (u8) (mac_up >> 24);
-	sp->defMacAddr[0].mac_addr[5] = (u8) (mac_down >> 16);
-	sp->defMacAddr[0].mac_addr[4] = (u8) (mac_down >> 24);
+	sp->def_mac_addr[0].mac_addr[3] = (u8) (mac_up);
+	sp->def_mac_addr[0].mac_addr[2] = (u8) (mac_up >> 8);
+	sp->def_mac_addr[0].mac_addr[1] = (u8) (mac_up >> 16);
+	sp->def_mac_addr[0].mac_addr[0] = (u8) (mac_up >> 24);
+	sp->def_mac_addr[0].mac_addr[5] = (u8) (mac_down >> 16);
+	sp->def_mac_addr[0].mac_addr[4] = (u8) (mac_down >> 24);
 
 	DBG_PRINT(INIT_DBG,
 		  "DEFAULT MAC ADDR:0x%02x-%02x-%02x-%02x-%02x-%02x\n",
-		  sp->defMacAddr[0].mac_addr[0],
-		  sp->defMacAddr[0].mac_addr[1],
-		  sp->defMacAddr[0].mac_addr[2],
-		  sp->defMacAddr[0].mac_addr[3],
-		  sp->defMacAddr[0].mac_addr[4],
-		  sp->defMacAddr[0].mac_addr[5]);
+		  sp->def_mac_addr[0].mac_addr[0],
+		  sp->def_mac_addr[0].mac_addr[1],
+		  sp->def_mac_addr[0].mac_addr[2],
+		  sp->def_mac_addr[0].mac_addr[3],
+		  sp->def_mac_addr[0].mac_addr[4],
+		  sp->def_mac_addr[0].mac_addr[5]);
 
 	/*  Set the factory defined MAC address initially   */
 	dev->addr_len = ETH_ALEN;
-	memcpy(dev->dev_addr, sp->defMacAddr, ETH_ALEN);
+	memcpy(dev->dev_addr, sp->def_mac_addr, ETH_ALEN);
 
-	/*  Initialize the tasklet status flag */
-	atomic_set(&(sp->tasklet_status), 0);
+	/*
+	 * Initialize the tasklet status and link state flags 
+	 * and the card statte parameter
+	 */
+	atomic_set(&(sp->card_state), 0);
+	sp->tasklet_status = 0;
+	sp->link_state = 0;
 
 
 	/* Initialize spinlocks */
-	spin_lock_init(&sp->isr_lock);
 	spin_lock_init(&sp->tx_lock);
+#ifndef CONFIG_S2IO_NAPI
+	spin_lock_init(&sp->put_lock);
+#endif
 
-	/* SXE-002: Configure link and activity LED to init state 
+	/* 
+	 * SXE-002: Configure link and activity LED to init state 
 	 * on driver load. 
 	 */
 	subid = sp->pdev->subsystem_device;
@@ -4312,49 +4891,53 @@
 		val64 |= 0x0000800000000000ULL;
 		writeq(val64, &bar0->gpio_control);
 		val64 = 0x0411040400000000ULL;
-		writeq(val64, (u64 *) ((u8 *) bar0 + 0x2700));
+		writeq(val64, (void __iomem *) bar0 + 0x2700);
 		val64 = readq(&bar0->gpio_control);
 	}
 
-	/* Make Link state as off at this point, when the Link change 
+	sp->rx_csum = 1;	/* Rx chksum verify enabled by default */
+
+	if (register_netdev(dev)) {
+		DBG_PRINT(ERR_DBG, "Device registration failed\n");
+		ret = -ENODEV;
+		goto register_failed;
+	}
+
+	/* 
+	 * Make Link state as off at this point, when the Link change 
 	 * interrupt comes the state will be automatically changed to 
 	 * the right state.
 	 */
 	netif_carrier_off(dev);
 	sp->last_link_state = LINK_DOWN;
 
-	sp->rx_csum = 1;	/* Rx chksum verify enabled by default */
-
 	return 0;
 
-      set_swap_failed:
-	unregister_netdev(dev);
       register_failed:
+      set_swap_failed:
 	iounmap(sp->bar1);
       bar1_remap_failed:
 	iounmap(sp->bar0);
       bar0_remap_failed:
       mem_alloc_failed:
-	freeSharedMem(sp);
-      init_failed:
+	free_shared_mem(sp);
 	pci_disable_device(pdev);
 	pci_release_regions(pdev);
 	pci_set_drvdata(pdev, NULL);
 	free_netdev(dev);
 
-	return -ENODEV;
+	return ret;
 }
 
-/*
-*  Input Argument/s: 
-*   pdev - structure containing the PCI related information of the device.
-*  Return value:
-*  void
-*  Description:
-*  This function is called by the Pci subsystem to release a PCI device 
-*  and free up all resource held up by the device. This could be in response 
-*  to a Hot plug event or when the driver is to be removed from memory.
-*/
+/**
+ * s2io_rem_nic - Free the PCI device 
+ * @pdev: structure containing the PCI related information of the device.
+ * Description: This function is called by the Pci subsystem to release a 
+ * PCI device and free up all resource held up by the device. This could
+ * be in response to a Hot plug event or when the driver is to be removed 
+ * from memory.
+ */
+
 static void __devexit s2io_rem_nic(struct pci_dev *pdev)
 {
 	struct net_device *dev =
@@ -4365,23 +4948,35 @@
 		DBG_PRINT(ERR_DBG, "Driver Data is NULL!!\n");
 		return;
 	}
+
 	sp = dev->priv;
-	freeSharedMem(sp);
+	unregister_netdev(dev);
+
+	free_shared_mem(sp);
 	iounmap(sp->bar0);
 	iounmap(sp->bar1);
 	pci_disable_device(pdev);
 	pci_release_regions(pdev);
 	pci_set_drvdata(pdev, NULL);
 
-	unregister_netdev(dev);
-
 	free_netdev(dev);
 }
 
+/**
+ * s2io_starter - Entry point for the driver
+ * Description: This function is the entry point for the driver. It verifies
+ * the module loadable parameters and initializes PCI configuration space.
+ */
+
 int __init s2io_starter(void)
 {
 	return pci_module_init(&s2io_driver);
 }
+
+/**
+ * s2io_closer - Cleanup routine for the driver 
+ * Description: This function is the cleanup routine for the driver. It unregist * ers the driver.
+ */
 
 void s2io_closer(void)
 {
diff -Nru a/drivers/net/s2io.h b/drivers/net/s2io.h
--- a/drivers/net/s2io.h	2005-03-01 23:38:54 -08:00
+++ b/drivers/net/s2io.h	2005-03-01 23:38:54 -08:00
@@ -16,6 +16,7 @@
 #define TBD 0
 #define BIT(loc)		(0x8000000000000000ULL >> (loc))
 #define vBIT(val, loc, sz)	(((u64)val) << (64-loc-sz))
+#define INV(d)  ((d&0xff)<<24) | (((d>>8)&0xff)<<16) | (((d>>16)&0xff)<<8)| ((d>>24)&0xff)
 
 #ifndef BOOL
 #define BOOL    int
@@ -52,8 +53,6 @@
 /*
  * Debug related variables.
  */
-#define DEBUG_ON TRUE
-
 /* different debug levels. */
 #define	ERR_DBG		0
 #define	INIT_DBG	1
@@ -62,7 +61,7 @@
 #define	INTR_DBG	4
 
 /* Global variable that defines the present debug level of the driver. */
-int debug_level = ERR_DBG;	/* Default level. */
+static int debug_level = ERR_DBG;	/* Default level. */
 
 /* DEBUG message print. */
 #define DBG_PRINT(dbg_level, args...)  if(!(debug_level<dbg_level)) printk(args)
@@ -312,7 +311,7 @@
 /* Maintains Per FIFO related information. */
 typedef struct tx_fifo_config {
 #define	MAX_AVAILABLE_TXDS	8192
-	u32 FifoLen;		/* specifies len of FIFO upto 8192, ie no of TxDLs */
+	u32 fifo_len;		/* specifies len of FIFO upto 8192, ie no of TxDLs */
 /* Priority definition */
 #define TX_FIFO_PRI_0               0	/*Highest */
 #define TX_FIFO_PRI_1               1
@@ -322,9 +321,9 @@
 #define TX_FIFO_PRI_5               5
 #define TX_FIFO_PRI_6               6
 #define TX_FIFO_PRI_7               7	/*lowest */
-	u8 FifoPriority;	/* specifies pointer level for FIFO */
+	u8 fifo_priority;	/* specifies pointer level for FIFO */
 	/* user should not set twos fifos with same pri */
-	u8 fNoSnoop;
+	u8 f_no_snoop;
 #define NO_SNOOP_TXD                0x01
 #define NO_SNOOP_TXD_BUFFER          0x02
 } tx_fifo_config_t;
@@ -332,7 +331,7 @@
 
 /* Maintains per Ring related information */
 typedef struct rx_ring_config {
-	u32 NumRxd;		/*No of RxDs per Rx Ring */
+	u32 num_rxd;		/*No of RxDs per Rx Ring */
 #define RX_RING_PRI_0               0	/* highest */
 #define RX_RING_PRI_1               1
 #define RX_RING_PRI_2               2
@@ -342,70 +341,37 @@
 #define RX_RING_PRI_6               6
 #define RX_RING_PRI_7               7	/* lowest */
 
-	u8 RingPriority;	/*Specifies service priority of ring */
+	u8 ring_priority;	/*Specifies service priority of ring */
 	/* OSM should not set any two rings with same priority */
-	u8 RingOrg;		/*Organization of ring */
-#define RING_ORG_BUFF1           0x01
-#define RX_RING_ORG_BUFF3           0x03
-#define RX_RING_ORG_BUFF5           0x05
-
-/* In case of 3 buffer recv. mode, size of three buffers is expected as.. */
-#define BUFF_SZ_1                   22	/* ethernet header */
-#define BUFF_SZ_2                   (64+64)	/* max. IP+TCP header size */
-#define BUFF_SZ_3                   (1500-20-20)	/* TCP payload */
-#define BUFF_SZ_3_JUMBO             (9600-20-20)	/* Jumbo TCP payload */
-
-	u32 RxdThresh;		/*No of used Rxds NIC can store before transfer to host */
-#define DEFAULT_RXD_THRESHOLD       0x1	/* TODO */
-	u8 fNoSnoop;
+	u8 ring_org;		/*Organization of ring */
+#define RING_ORG_BUFF1		0x01
+#define RX_RING_ORG_BUFF3	0x03
+#define RX_RING_ORG_BUFF5	0x05
+
+	u8 f_no_snoop;
 #define NO_SNOOP_RXD                0x01
 #define NO_SNOOP_RXD_BUFFER         0x02
-	u32 RxD_BackOff_Interval;
-#define RXD_BACKOFF_INTERVAL_DEF        0x0
-#define RXD_BACKOFF_INTERVAL_MIN        0x0
-#define RXD_BACKOFF_INTERVAL_MAX        0x0
 } rx_ring_config_t;
 
 /* This structure provides contains values of the tunable parameters 
  * of the H/W 
  */
 struct config_param {
-
 /* Tx Side */
-	u32 TxFIFONum;		/*Number of Tx FIFOs */
+	u32 tx_fifo_num;	/*Number of Tx FIFOs */
 #define MAX_TX_FIFOS 8
 
-	tx_fifo_config_t TxCfg[MAX_TX_FIFOS];	/*Per-Tx FIFO config */
-	u32 MaxTxDs;		/*Max no. of Tx buffer descriptor per TxDL */
-	BOOL TxVLANEnable;	/*TRUE: Insert VLAN ID, FALSE: Don't insert */
-#define TX_REQ_TIMEOUT_DEFAULT          0x0
-#define TX_REQ_TIMEOUT_MIN              0x0
-#define TX_REQ_TIMEOUT_MAX              0x0
-	u32 TxReqTimeOut;
-	BOOL TxFlow;		/*Tx flow control enable */
-	BOOL RxFlow;
-	BOOL OverrideTxServiceState;	/* TRUE: Overide, FALSE: Do not override 
-					   Use the new priority information
-					   of service state. It is not recommended
-					   to change but OSM can opt to do so */
-#define MAX_SERVICE_STATES  36
-	u8 TxServiceState[MAX_SERVICE_STATES];
-	/* Array element represent 'priority' 
-	 * and array index represents
-	 *  'Service state' e.g. 
-	 *  TxServiceState[3]=7; it means 
-	 *  Service state 3 is associated 
-	 *  with priority 7 of a Tx FIFO */
-	u64 TxIntrType;		/* Specifies if Tx Intr is UTILZ or PER_LIST type. */
+	tx_fifo_config_t tx_cfg[MAX_TX_FIFOS];	/*Per-Tx FIFO config */
+	u32 max_txds;		/*Max no. of Tx buffer descriptor per TxDL */
+	u64 tx_intr_type;
+	/* Specifies if Tx Intr is UTILZ or PER_LIST type. */
 
 /* Rx Side */
-	u32 RxRingNum;		/*Number of receive rings */
+	u32 rx_ring_num;	/*Number of receive rings */
 #define MAX_RX_RINGS 8
 #define MAX_RX_BLOCKS_PER_RING  150
 
-	rx_ring_config_t RxCfg[MAX_RX_RINGS];	/*Per-Rx Ring config */
-	BOOL RxVLANEnable;	/*TRUE: Strip off VLAN tag from the frame,
-				   FALSE: Don't strip off VLAN tag */
+	rx_ring_config_t rx_cfg[MAX_RX_RINGS];	/*Per-Rx Ring config */
 
 #define HEADER_ETHERNET_II_802_3_SIZE 14
 #define HEADER_802_2_SIZE              3
@@ -419,23 +385,6 @@
 #define MAX_PYLD_JUMBO              9600
 #define MAX_MTU_JUMBO               (MAX_PYLD_JUMBO+18)
 #define MAX_MTU_JUMBO_VLAN          (MAX_PYLD_JUMBO+22)
-	u32 MTU;		/*Maximum Payload */
-	BOOL JumboEnable;	/*Enable Jumbo frames recv/send */
-	BOOL OverrideRxServiceState;	/* TRUE: Overide, FALSE: Do not override 
-					   Use the new priority information
-					   of service state. It is not recommended
-					   to change but OSM can opt to do so */
-#define MAX_SERVICE_STATES  36
-	u8 RxServiceState[MAX_SERVICE_STATES];
-	/* Array element represent 'priority' 
-	 * and array index represents 
-	 * 'Service state'e.g. 
-	 * RxServiceState[3]=7; it means 
-	 * Service state 3 is associated 
-	 * with priority 7 of a Rx FIFO */
-	BOOL StatAutoRefresh;	/* When true, StatRefreshTime have valid value */
-	u32 StatRefreshTime;	/*Time for refreshing statistics */
-#define     STAT_TRSF_PER_1_SECOND      0x208D5
 };
 
 /* Structure representing MAC Addrs */
@@ -491,6 +440,12 @@
 	u64 Host_Control;	/* reserved for host */
 } TxD_t;
 
+/* Structure to hold the phy and virt addr of every TxDL. */
+typedef struct list_info_hold {
+	dma_addr_t list_phy_addr;
+	void *list_virt_addr;
+} list_info_hold_t;
+
 /* Rx descriptor structure */
 typedef struct _RxD_t {
 	u64 Host_Control;	/* reserved for host */
@@ -507,36 +462,80 @@
 #define RXD_GET_L4_CKSUM(val)   ((u16)(val) & 0xFFFF)
 
 	u64 Control_2;
+#ifndef CONFIG_2BUFF_MODE
 #define MASK_BUFFER0_SIZE       vBIT(0xFFFF,0,16)
 #define SET_BUFFER0_SIZE(val)   vBIT(val,0,16)
+#else
+#define MASK_BUFFER0_SIZE       vBIT(0xFF,0,16)
+#define MASK_BUFFER1_SIZE       vBIT(0xFFFF,16,16)
+#define MASK_BUFFER2_SIZE       vBIT(0xFFFF,32,16)
+#define SET_BUFFER0_SIZE(val)   vBIT(val,8,8)
+#define SET_BUFFER1_SIZE(val)   vBIT(val,16,16)
+#define SET_BUFFER2_SIZE(val)   vBIT(val,32,16)
+#endif
+
 #define MASK_VLAN_TAG           vBIT(0xFFFF,48,16)
 #define SET_VLAN_TAG(val)       vBIT(val,48,16)
 #define SET_NUM_TAG(val)       vBIT(val,16,32)
 
+#ifndef CONFIG_2BUFF_MODE
 #define RXD_GET_BUFFER0_SIZE(Control_2) (u64)((Control_2 & vBIT(0xFFFF,0,16)))
-/*    
-#define TXD_GET_BUFFER1_SIZE(Control_2) (u16)((Control_2 & MASK_BUFFER1_SIZE) >> (63-31))  
-#define TXD_GET_BUFFER2_SIZE(Control_2) (u16)((Control_2 & MASK_BUFFER2_SIZE) >> (63-47))  
-*/
+#else
+#define RXD_GET_BUFFER0_SIZE(Control_2) (u8)((Control_2 & MASK_BUFFER0_SIZE) \
+							>> 48)
+#define RXD_GET_BUFFER1_SIZE(Control_2) (u16)((Control_2 & MASK_BUFFER1_SIZE) \
+							>> 32)
+#define RXD_GET_BUFFER2_SIZE(Control_2) (u16)((Control_2 & MASK_BUFFER2_SIZE) \
+							>> 16)
+#define BUF0_LEN	40
+#define BUF1_LEN	1
+#endif
+
 	u64 Buffer0_ptr;
+#ifdef CONFIG_2BUFF_MODE
+	u64 Buffer1_ptr;
+	u64 Buffer2_ptr;
+#endif
 } RxD_t;
 
-
 /* Structure that represents the Rx descriptor block which contains 
  * 128 Rx descriptors.
  */
+#ifndef CONFIG_2BUFF_MODE
 typedef struct _RxD_block {
 #define MAX_RXDS_PER_BLOCK             127
 	RxD_t rxd[MAX_RXDS_PER_BLOCK];
 
 	u64 reserved_0;
 #define END_OF_BLOCK    0xFEFFFFFFFFFFFFFFULL
-	u64 reserved_1;		/* 0xFEFFFFFFFFFFFFFF to mark last Rxd in this blk */
-	u64 reserved_2_pNext_RxD_block;	/*@ Logical ptr to next */
-	u64 pNext_RxD_Blk_physical;	/* Buff0_ptr.
-					   In a 32 bit arch the upper 32 bits 
-					   should be 0 */
+	u64 reserved_1;		/* 0xFEFFFFFFFFFFFFFF to mark last 
+				 * Rxd in this blk */
+	u64 reserved_2_pNext_RxD_block;	/* Logical ptr to next */
+	u64 pNext_RxD_Blk_physical;	/* Buff0_ptr.In a 32 bit arch
+					 * the upper 32 bits should 
+					 * be 0 */
 } RxD_block_t;
+#else
+typedef struct _RxD_block {
+#define MAX_RXDS_PER_BLOCK             85
+	RxD_t rxd[MAX_RXDS_PER_BLOCK];
+
+#define END_OF_BLOCK    0xFEFFFFFFFFFFFFFFULL
+	u64 reserved_1;		/* 0xFEFFFFFFFFFFFFFF to mark last Rxd 
+				 * in this blk */
+	u64 pNext_RxD_Blk_physical;	/* Phy ponter to next blk. */
+} RxD_block_t;
+#define SIZE_OF_BLOCK	4096
+
+/* Structure to hold virtual addresses of Buf0 and Buf1 in 
+ * 2buf mode. */
+typedef struct bufAdd {
+	void *ba_0_org;
+	void *ba_1_org;
+	void *ba_0;
+	void *ba_1;
+} buffAdd_t;
+#endif
 
 /* Structure which stores all the MAC control parameters */
 
@@ -568,10 +567,6 @@
  */
 typedef struct mac_info {
 /* rx side stuff */
-	u32 rxd_ring_mem_sz;
-	RxD_t *RxRing[MAX_RX_RINGS];	/* Logical Rx ring pointers */
-	dma_addr_t RxRing_Phy[MAX_RX_RINGS];
-
 	/* Put pointer info which indictes which RxD has to be replenished 
 	 * with a new buffer.
 	 */
@@ -583,41 +578,21 @@
 	rx_curr_get_info_t rx_curr_get_info[MAX_RX_RINGS];
 
 	u16 rmac_pause_time;
-
-	/* this will be used in receive function, this decides which ring would
-	   be processed first. eg: ring with priority value 0 (highest) should
-	   be processed first. 
-	   first 3 LSB bits represent ring number which should be processed 
-	   first, similarly next 3 bits represent next ring to be processed.
-	   eg: value of _rx_ring_pri_map = 0x0000 003A means 
-	   ring #2 would be processed first and #7 would be processed next
-	 */
-	u32 _rx_ring_pri_map;
+	u16 mc_pause_threshold_q0q3;
+	u16 mc_pause_threshold_q4q7;
 
 /* tx side stuff */
-	void *txd_list_mem;	/* orignal pointer to allocated mem */
-	dma_addr_t txd_list_mem_phy;
-	u32 txd_list_mem_sz;
-
 	/* logical pointer of start of each Tx FIFO */
-	TxFIFO_element_t *tx_FIFO_start[MAX_TX_FIFOS];
-
-	/* logical pointer of start of TxDL which corresponds to each Tx FIFO */
-	TxD_t *txdl_start[MAX_TX_FIFOS];
-
-	/* Same as txdl_start but phy addr */
-	dma_addr_t txdl_start_phy[MAX_TX_FIFOS];
+	TxFIFO_element_t __iomem *tx_FIFO_start[MAX_TX_FIFOS];
 
 /* Current offset within tx_FIFO_start, where driver would write new Tx frame*/
 	tx_curr_put_info_t tx_curr_put_info[MAX_TX_FIFOS];
 	tx_curr_get_info_t tx_curr_get_info[MAX_TX_FIFOS];
 
-	u16 txdl_len;		/* length of a TxDL, same for all */
-
 	void *stats_mem;	/* orignal pointer to allocated mem */
 	dma_addr_t stats_mem_phy;	/* Physical address of the stat block */
 	u32 stats_mem_sz;
-	StatInfo_t *StatsInfo;	/* Logical address of the stat block */
+	StatInfo_t *stats_info;	/* Logical address of the stat block */
 } mac_info_t;
 
 /* structure representing the user defined MAC addresses */
@@ -632,17 +607,24 @@
 	dma_addr_t block_dma_addr;
 } rx_block_info_t;
 
+/* Default Tunable parameters of the NIC. */
+#define DEFAULT_FIFO_LEN 4096
+#define SMALL_RXD_CNT	30 * (MAX_RXDS_PER_BLOCK+1)
+#define LARGE_RXD_CNT	100 * (MAX_RXDS_PER_BLOCK+1)
+#define SMALL_BLK_CNT	30
+#define LARGE_BLK_CNT	100
+
 /* Structure representing one instance of the NIC */
 typedef struct s2io_nic {
 #define MAX_MAC_SUPPORTED   16
 #define MAX_SUPPORTED_MULTICASTS MAX_MAC_SUPPORTED
 
-	macaddr_t defMacAddr[MAX_MAC_SUPPORTED];
-	macaddr_t preMacAddr[MAX_MAC_SUPPORTED];
+	macaddr_t def_mac_addr[MAX_MAC_SUPPORTED];
+	macaddr_t pre_mac_addr[MAX_MAC_SUPPORTED];
 
 	struct net_device_stats stats;
-	caddr_t bar0;
-	caddr_t bar1;
+	void __iomem *bar0;
+	void __iomem *bar1;
 	struct config_param config;
 	mac_info_t mac_control;
 	int high_dma_flag;
@@ -651,7 +633,7 @@
 
 	char name[32];
 	struct tasklet_struct task;
-	atomic_t tasklet_status;
+	volatile unsigned long tasklet_status;
 	struct timer_list timer;
 	struct net_device *dev;
 	struct pci_dev *pdev;
@@ -670,8 +652,10 @@
 	u32 irq;
 	atomic_t rx_bufs_left[MAX_RX_RINGS];
 
-	spinlock_t isr_lock;
 	spinlock_t tx_lock;
+#ifndef CONFIG_S2IO_NAPI
+	spinlock_t put_lock;
+#endif
 
 #define PROMISC     1
 #define ALL_MULTI   2
@@ -690,23 +674,22 @@
 	u16 tx_err_count;
 	u16 rx_err_count;
 
-#if DEBUG_ON
-	u64 rxpkt_bytes;
-	u64 txpkt_bytes;
-	int int_cnt;
-	int rxint_cnt;
-	int txint_cnt;
-	u64 rxpkt_cnt;
+#ifndef CONFIG_S2IO_NAPI
+	/* Index to the absolute position of the put pointer of Rx ring. */
+	int put_pos[MAX_RX_RINGS];
 #endif
 
-	/*  Place holders for the virtual and physical addresses of 
+	/*
+	 *  Place holders for the virtual and physical addresses of 
 	 *  all the Rx Blocks
 	 */
-	struct rx_block_info
-	 rx_blocks[MAX_RX_RINGS][MAX_RX_BLOCKS_PER_RING];
+	rx_block_info_t rx_blocks[MAX_RX_RINGS][MAX_RX_BLOCKS_PER_RING];
 	int block_count[MAX_RX_RINGS];
 	int pkt_cnt[MAX_RX_RINGS];
 
+	/* Place holder of all the TX List's Phy and Virt addresses. */
+	list_info_hold_t *list_info[MAX_TX_FIFOS];
+
 	/*  Id timer, used to blink NIC to physically identify NIC. */
 	struct timer_list id_timer;
 
@@ -736,22 +719,26 @@
 	u16 last_link_state;
 #define	LINK_DOWN	1
 #define	LINK_UP		2
+
+#ifdef CONFIG_2BUFF_MODE
+	/* Buffer Address store. */
+	buffAdd_t **ba[MAX_RX_RINGS];
+#endif
+	int task_flag;
+#define CARD_DOWN 1
+#define CARD_UP 2
+	atomic_t card_state;
+	volatile unsigned long link_state;
 } nic_t;
 
 #define RESET_ERROR 1;
 #define CMD_ERROR   2;
 
-/* Default Tunable parameters of the NIC. */
-#define DEFAULT_FIFO_LEN 4096
-#define SMALL_RXD_CNT	40 * (MAX_RXDS_PER_BLOCK+1)
-#define LARGE_RXD_CNT	100 * (MAX_RXDS_PER_BLOCK+1)
-
 /*  OS related system calls */
 #ifndef readq
-static inline u64 readq(void *addr)
+static inline u64 readq(void __iomem *addr)
 {
-	u64 ret = 0;
-	ret = readl(addr + 4);
+	u64 ret = readl(addr + 4);
 	ret <<= 32;
 	ret |= readl(addr);
 
@@ -760,11 +747,32 @@
 #endif
 
 #ifndef writeq
-static inline void writeq(u64 val, void *addr)
+static inline void writeq(u64 val, void __iomem *addr)
 {
 	writel((u32) (val), addr);
 	writel((u32) (val >> 32), (addr + 4));
 }
+
+/* In 32 bit modes, some registers have to be written in a 
+ * particular order to expect correct hardware operation. The
+ * macro SPECIAL_REG_WRITE is used to perform such ordered 
+ * writes. Defines UF (Upper First) and LF (Lower First) will 
+ * be used to specify the required write order.
+ */
+#define UF	1
+#define LF	2
+static inline void SPECIAL_REG_WRITE(u64 val, void __iomem *addr, int order)
+{
+	if (order == LF) {
+		writel((u32) (val), addr);
+		writel((u32) (val >> 32), (addr + 4));
+	} else {
+		writel((u32) (val >> 32), (addr + 4));
+		writel((u32) (val), addr);
+	}
+}
+#else
+#define SPECIAL_REG_WRITE(val, addr, dummy) writeq(val, addr)
 #endif
 
 /*  Interrupt related values of Xena */
@@ -815,30 +823,41 @@
 
 /*  DMA level Inressupts */
 #define TXDMA_PFC_INT_M     BIT(0)
-    /*  PFC block interrupts */
+#define TXDMA_PCC_INT_M     BIT(2)
+
+/*  PFC block interrupts */
 #define PFC_MISC_ERR_1      BIT(0)	/* Interrupt to indicate FIFO full */
 
+/* PCC block interrupts. */
+#define	PCC_FB_ECC_ERR	   vBIT(0xff, 16, 8)	/* Interrupt to indicate
+						   PCC_FB_ECC Error. */
+
 /*
  * Prototype declaration.
  */
 static int __devinit s2io_init_nic(struct pci_dev *pdev,
 				   const struct pci_device_id *pre);
 static void __devexit s2io_rem_nic(struct pci_dev *pdev);
-static int initSharedMem(struct s2io_nic *sp);
-static void freeSharedMem(struct s2io_nic *sp);
-static int initNic(struct s2io_nic *nic);
+static int init_shared_mem(struct s2io_nic *sp);
+static void free_shared_mem(struct s2io_nic *sp);
+static int init_nic(struct s2io_nic *nic);
 #ifndef CONFIG_S2IO_NAPI
-static void rxIntrHandler(struct s2io_nic *sp);
+static void rx_intr_handler(struct s2io_nic *sp);
 #endif
-static void txIntrHandler(struct s2io_nic *sp);
-static void alarmIntrHandler(struct s2io_nic *sp);
+static void tx_intr_handler(struct s2io_nic *sp);
+static void alarm_intr_handler(struct s2io_nic *sp);
 
 static int s2io_starter(void);
 void s2io_closer(void);
 static void s2io_tx_watchdog(struct net_device *dev);
 static void s2io_tasklet(unsigned long dev_addr);
 static void s2io_set_multicast(struct net_device *dev);
-static int rxOsmHandler(nic_t * sp, u16 len, RxD_t * rxdp, int ring_no);
+#ifndef CONFIG_2BUFF_MODE
+static int rx_osm_handler(nic_t * sp, u16 len, RxD_t * rxdp, int ring_no);
+#else
+static int rx_osm_handler(nic_t * sp, RxD_t * rxdp, int ring_no,
+			  buffAdd_t * ba);
+#endif
 void s2io_link(nic_t * sp, int link);
 void s2io_reset(nic_t * sp);
 #ifdef CONFIG_S2IO_NAPI
@@ -849,5 +868,8 @@
 static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs);
 static int verify_xena_quiescence(u64 val64, int flag);
 static struct ethtool_ops netdev_ethtool_ops;
+static void s2io_set_link(unsigned long data);
+static void s2io_card_down(nic_t * nic);
+static int s2io_card_up(nic_t * nic);
 
 #endif				/* _S2IO_H */
diff -Nru a/drivers/net/seeq8005.c b/drivers/net/seeq8005.c
--- a/drivers/net/seeq8005.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/net/seeq8005.c	2005-03-01 23:39:08 -08:00
@@ -737,8 +737,8 @@
 
 static struct net_device *dev_seeq;
 MODULE_LICENSE("GPL");
-MODULE_PARM(io, "i");
-MODULE_PARM(irq, "i");
+module_param(io, int, 0);
+module_param(irq, int, 0);
 MODULE_PARM_DESC(io, "SEEQ 8005 I/O base address");
 MODULE_PARM_DESC(irq, "SEEQ 8005 IRQ number");
 
diff -Nru a/drivers/net/shaper.c b/drivers/net/shaper.c
--- a/drivers/net/shaper.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/net/shaper.c	2005-03-01 23:39:08 -08:00
@@ -674,7 +674,7 @@
 static int shapers = 1;
 #ifdef MODULE
 
-MODULE_PARM(shapers, "i");
+module_param(shapers, int, 0);
 MODULE_PARM_DESC(shapers, "Traffic shaper: maximum number of shapers");
 
 #else /* MODULE */
diff -Nru a/drivers/net/sis900.c b/drivers/net/sis900.c
--- a/drivers/net/sis900.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/net/sis900.c	2005-03-01 23:38:56 -08:00
@@ -48,6 +48,7 @@
 */
 
 #include <linux/module.h>
+#include <linux/moduleparam.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/timer.h>
@@ -120,6 +121,7 @@
 } mii_chip_table[] = {
 	{ "SiS 900 Internal MII PHY", 		0x001d, 0x8000, LAN },
 	{ "SiS 7014 Physical Layer Solution", 	0x0016, 0xf830, LAN },
+	{ "Altimata AC101LF PHY",               0x0022, 0x5520, LAN },
 	{ "AMD 79C901 10BASE-T PHY",  		0x0000, 0x6B70, LAN },
 	{ "AMD 79C901 HomePNA PHY",		0x0000, 0x6B90, HOME},
 	{ "ICS LAN PHY",			0x0015, 0xF440, LAN },
@@ -178,9 +180,9 @@
 MODULE_DESCRIPTION("SiS 900 PCI Fast Ethernet driver");
 MODULE_LICENSE("GPL");
 
-MODULE_PARM(multicast_filter_limit, "i");
-MODULE_PARM(max_interrupt_work, "i");
-MODULE_PARM(debug, "i");
+module_param(multicast_filter_limit, int, 0444);
+module_param(max_interrupt_work, int, 0444);
+module_param(debug, int, 0444);
 MODULE_PARM_DESC(multicast_filter_limit, "SiS 900/7016 maximum number of filtered multicast addresses");
 MODULE_PARM_DESC(max_interrupt_work, "SiS 900/7016 maximum events handled per interrupt");
 MODULE_PARM_DESC(debug, "SiS 900/7016 debug level (2-4)");
@@ -2238,7 +2240,7 @@
 	/* Stop the chip's Tx and Rx Status Machine */
 	outl(RxDIS | TxDIS | inl(ioaddr + cr), ioaddr + cr);
 
-	pci_set_power_state(pci_dev, 3);
+	pci_set_power_state(pci_dev, PCI_D3hot);
 	pci_save_state(pci_dev);
 
 	return 0;
@@ -2253,7 +2255,7 @@
 	if(!netif_running(net_dev))
 		return 0;
 	pci_restore_state(pci_dev);
-	pci_set_power_state(pci_dev, 0);
+	pci_set_power_state(pci_dev, PCI_D0);
 
 	sis900_init_rxfilter(net_dev);
 
diff -Nru a/drivers/net/sk98lin/Makefile b/drivers/net/sk98lin/Makefile
--- a/drivers/net/sk98lin/Makefile	2005-03-01 23:38:43 -08:00
+++ b/drivers/net/sk98lin/Makefile	2005-03-01 23:38:43 -08:00
@@ -13,6 +13,7 @@
 obj-$(CONFIG_SK98LIN) += sk98lin.o
 sk98lin-objs    :=	\
 		skge.o		\
+		skethtool.o	\
 		skdim.o		\
 		skaddr.o	\
 		skgehwt.o	\
diff -Nru a/drivers/net/sk98lin/h/skdrv2nd.h b/drivers/net/sk98lin/h/skdrv2nd.h
--- a/drivers/net/sk98lin/h/skdrv2nd.h	2005-03-01 23:39:17 -08:00
+++ b/drivers/net/sk98lin/h/skdrv2nd.h	2005-03-01 23:39:17 -08:00
@@ -266,7 +266,6 @@
 typedef struct s_DevNet DEV_NET;
 
 struct s_DevNet {
-	struct			proc_dir_entry *proc;
 	int             PortNr;
 	int             NetNr;
 	int             Mtu;
@@ -383,6 +382,8 @@
 	SK_CSUM		Csum;		/* for checksum module */
 	SK_RLMT		Rlmt;		/* for rlmt module */
 	spinlock_t	SlowPathLock;	/* Normal IRQ lock */
+	struct timer_list BlinkTimer;	/* for LED blinking */
+	int		LedsOn;
 	SK_PNMI_STRUCT_DATA PnmiStruct;	/* structure to get all Pnmi-Data */
 	int			RlmtMode;	/* link check mode to set */
 	int			RlmtNets;	/* Number of nets */
@@ -395,7 +396,7 @@
 	SK_U32		PciDevId;	/* pci device id */
 	struct SK_NET_DEVICE	*dev[2];	/* pointer to device struct */
 	char		Name[30];	/* driver name */
-	struct SK_NET_DEVICE	*Next;		/* link all devices (for clearing) */
+
 	int		RxBufSize;	/* length of receive buffers */
         struct net_device_stats stats;	/* linux 'netstat -i' statistics */
 	int		Index;		/* internal board index number */
diff -Nru a/drivers/net/sk98lin/skaddr.c b/drivers/net/sk98lin/skaddr.c
--- a/drivers/net/sk98lin/skaddr.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/net/sk98lin/skaddr.c	2005-03-01 23:38:58 -08:00
@@ -79,7 +79,7 @@
 
 /* 64-bit hash values with all bits set. */
 
-SK_U16	OnesHash[4] = {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF};
+static const SK_U16	OnesHash[4] = {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF};
 
 /* local variables ************************************************************/
 
diff -Nru a/drivers/net/sk98lin/skethtool.c b/drivers/net/sk98lin/skethtool.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/net/sk98lin/skethtool.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,555 @@
+/******************************************************************************
+ *
+ * Name:        skethtool.c
+ * Project:     GEnesis, PCI Gigabit Ethernet Adapter
+ * Version:     $Revision: 1.7 $
+ * Date:        $Date: 2004/09/29 13:32:07 $
+ * Purpose:     All functions regarding ethtool handling
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *	(C)Copyright 1998-2002 SysKonnect GmbH.
+ *	(C)Copyright 2002-2004 Marvell.
+ *
+ *	Driver for Marvell Yukon/2 chipset and SysKonnect Gigabit Ethernet 
+ *      Server Adapters.
+ *
+ *	Author: Ralph Roesler (rroesler@syskonnect.de)
+ *	        Mirko Lindner (mlindner@syskonnect.de)
+ *
+ *	Address all question to: linux@syskonnect.de
+ *
+ *	The technical manual for the adapters is available from SysKonnect's
+ *	web pages: www.syskonnect.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.
+ *
+ *	The information in this file is provided "AS IS" without warranty.
+ *
+ *****************************************************************************/
+
+#include "h/skdrv1st.h"
+#include "h/skdrv2nd.h"
+#include "h/skversion.h"
+
+#include <linux/ethtool.h>
+#include <linux/timer.h>
+#include <linux/delay.h>
+
+/******************************************************************************
+ *
+ * Defines
+ *
+ *****************************************************************************/
+
+#define SUPP_COPPER_ALL (SUPPORTED_10baseT_Half  | SUPPORTED_10baseT_Full  | \
+                         SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | \
+                         SUPPORTED_1000baseT_Half| SUPPORTED_1000baseT_Full| \
+                         SUPPORTED_TP)
+
+#define ADV_COPPER_ALL  (ADVERTISED_10baseT_Half  | ADVERTISED_10baseT_Full  | \
+                         ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full | \
+                         ADVERTISED_1000baseT_Half| ADVERTISED_1000baseT_Full| \
+                         ADVERTISED_TP)
+
+#define SUPP_FIBRE_ALL  (SUPPORTED_1000baseT_Full | \
+                         SUPPORTED_FIBRE          | \
+                         SUPPORTED_Autoneg)
+
+#define ADV_FIBRE_ALL   (ADVERTISED_1000baseT_Full | \
+                         ADVERTISED_FIBRE          | \
+                         ADVERTISED_Autoneg)
+
+
+/******************************************************************************
+ *
+ * Local Functions
+ *
+ *****************************************************************************/
+
+/*****************************************************************************
+ *
+ * 	getSettings - retrieves the current settings of the selected adapter
+ *
+ * Description:
+ *	The current configuration of the selected adapter is returned.
+ *	This configuration involves a)speed, b)duplex and c)autoneg plus
+ *	a number of other variables.
+ *
+ * Returns:    always 0
+ *
+ */
+static int getSettings(struct net_device *dev, struct ethtool_cmd *ecmd)
+{
+	const DEV_NET *pNet = netdev_priv(dev);
+	int port = pNet->PortNr;
+	const SK_AC *pAC = pNet->pAC;
+	const SK_GEPORT *pPort = &pAC->GIni.GP[port];
+
+	static int DuplexAutoNegConfMap[9][3]= {
+		{ -1                     , -1         , -1              },
+		{ 0                      , -1         , -1              },
+		{ SK_LMODE_HALF          , DUPLEX_HALF, AUTONEG_DISABLE },
+		{ SK_LMODE_FULL          , DUPLEX_FULL, AUTONEG_DISABLE },
+		{ SK_LMODE_AUTOHALF      , DUPLEX_HALF, AUTONEG_ENABLE  },
+		{ SK_LMODE_AUTOFULL      , DUPLEX_FULL, AUTONEG_ENABLE  },
+		{ SK_LMODE_AUTOBOTH      , DUPLEX_FULL, AUTONEG_ENABLE  },
+		{ SK_LMODE_AUTOSENSE     , -1         , -1              },
+		{ SK_LMODE_INDETERMINATED, -1         , -1              }
+	};
+	static int SpeedConfMap[6][2] = {
+		{ 0                       , -1         },
+		{ SK_LSPEED_AUTO          , -1         },
+		{ SK_LSPEED_10MBPS        , SPEED_10   },
+		{ SK_LSPEED_100MBPS       , SPEED_100  },
+		{ SK_LSPEED_1000MBPS      , SPEED_1000 },
+		{ SK_LSPEED_INDETERMINATED, -1         }
+	};
+	static int AdvSpeedMap[6][2] = {
+		{ 0                       , -1         },
+		{ SK_LSPEED_AUTO          , -1         },
+		{ SK_LSPEED_10MBPS        , ADVERTISED_10baseT_Half   | ADVERTISED_10baseT_Full },
+		{ SK_LSPEED_100MBPS       , ADVERTISED_100baseT_Half  | ADVERTISED_100baseT_Full },
+		{ SK_LSPEED_1000MBPS      , ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full},
+		{ SK_LSPEED_INDETERMINATED, -1         }
+	};
+
+	ecmd->phy_address = port;
+	ecmd->speed       = SpeedConfMap[pPort->PLinkSpeedUsed][1];
+	ecmd->duplex      = DuplexAutoNegConfMap[pPort->PLinkModeStatus][1];
+	ecmd->autoneg     = DuplexAutoNegConfMap[pPort->PLinkModeStatus][2];
+	ecmd->transceiver = XCVR_INTERNAL;
+
+	if (pAC->GIni.GICopperType) {
+		ecmd->port        = PORT_TP;
+		ecmd->supported   = (SUPP_COPPER_ALL|SUPPORTED_Autoneg);
+		if (pAC->GIni.GIGenesis) {
+			ecmd->supported &= ~(SUPPORTED_10baseT_Half);
+			ecmd->supported &= ~(SUPPORTED_10baseT_Full);
+			ecmd->supported &= ~(SUPPORTED_100baseT_Half);
+			ecmd->supported &= ~(SUPPORTED_100baseT_Full);
+		} else {
+			if (pAC->GIni.GIChipId == CHIP_ID_YUKON) {
+				ecmd->supported &= ~(SUPPORTED_1000baseT_Half);
+			} 
+#ifdef CHIP_ID_YUKON_FE
+			if (pAC->GIni.GIChipId == CHIP_ID_YUKON_FE) {
+				ecmd->supported &= ~(SUPPORTED_1000baseT_Half);
+				ecmd->supported &= ~(SUPPORTED_1000baseT_Full);
+			}
+#endif
+		}
+		if (pAC->GIni.GP[0].PLinkSpeed != SK_LSPEED_AUTO) {
+			ecmd->advertising = AdvSpeedMap[pPort->PLinkSpeed][1];
+			if (pAC->GIni.GIChipId == CHIP_ID_YUKON) {
+				ecmd->advertising &= ~(SUPPORTED_1000baseT_Half);
+			} 
+		} else {
+			ecmd->advertising = ecmd->supported;
+		}
+
+		if (ecmd->autoneg == AUTONEG_ENABLE) 
+			ecmd->advertising |= ADVERTISED_Autoneg;
+	} else {
+		ecmd->port        = PORT_FIBRE;
+		ecmd->supported   = SUPP_FIBRE_ALL;
+		ecmd->advertising = ADV_FIBRE_ALL;
+	}
+	return 0;
+}
+
+/*
+ * MIB infrastructure uses instance value starting at 1
+ * based on board and port.
+ */
+static inline u32 pnmiInstance(const DEV_NET *pNet)
+{
+	return 1 + (pNet->pAC->RlmtNets == 2) + pNet->PortNr;
+}
+
+/*****************************************************************************
+ *
+ *	setSettings - configures the settings of a selected adapter
+ *
+ * Description:
+ *	Possible settings that may be altered are a)speed, b)duplex or 
+ *	c)autonegotiation.
+ *
+ * Returns:
+ *	0:	everything fine, no error
+ *	<0:	the return value is the error code of the failure 
+ */
+static int setSettings(struct net_device *dev, struct ethtool_cmd *ecmd)
+{
+	DEV_NET *pNet = netdev_priv(dev);
+	SK_AC *pAC = pNet->pAC;
+	u32 instance;
+	char buf[4];
+	int len = 1;
+
+	if (ecmd->speed != SPEED_10 && ecmd->speed != SPEED_100 
+	    && ecmd->speed != SPEED_1000)
+		return -EINVAL;
+
+	if (ecmd->duplex != DUPLEX_HALF && ecmd->duplex != DUPLEX_FULL)
+		return -EINVAL;
+
+	if (ecmd->autoneg != AUTONEG_DISABLE && ecmd->autoneg != AUTONEG_ENABLE)
+		return -EINVAL;
+
+	if (ecmd->autoneg == AUTONEG_DISABLE)
+		*buf = (ecmd->duplex == DUPLEX_FULL) 
+			? SK_LMODE_FULL : SK_LMODE_HALF;
+	else
+		*buf = (ecmd->duplex == DUPLEX_FULL) 
+			? SK_LMODE_AUTOFULL : SK_LMODE_AUTOHALF;
+	
+	instance = pnmiInstance(pNet);
+	if (SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_LINK_MODE, 
+			   &buf, &len, instance, pNet->NetNr) != SK_PNMI_ERR_OK)
+		return -EINVAL;
+
+	switch(ecmd->speed) {
+	case SPEED_1000:
+		*buf = SK_LSPEED_1000MBPS;
+		break;
+	case SPEED_100:
+		*buf = SK_LSPEED_100MBPS;
+		break;
+	case SPEED_10:
+		*buf = SK_LSPEED_10MBPS;
+	}
+
+	if (SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_SPEED_MODE, 
+			 &buf, &len, instance, pNet->NetNr) != SK_PNMI_ERR_OK)
+		return -EINVAL;
+
+	return 0;
+}
+
+/*****************************************************************************
+ *
+ * 	getDriverInfo - returns generic driver and adapter information
+ *
+ * Description:
+ *	Generic driver information is returned via this function, such as
+ *	the name of the driver, its version and and firmware version.
+ *	In addition to this, the location of the selected adapter is 
+ *	returned as a bus info string (e.g. '01:05.0').
+ *	
+ * Returns:	N/A
+ *
+ */
+static void getDriverInfo(struct net_device *dev, struct ethtool_drvinfo *info)
+{
+	const DEV_NET	*pNet = netdev_priv(dev);
+	const SK_AC *pAC = pNet->pAC;
+	char vers[32];
+
+	snprintf(vers, sizeof(vers)-1, VER_STRING "(v%d.%d)",
+		(pAC->GIni.GIPciHwRev >> 4) & 0xf, pAC->GIni.GIPciHwRev & 0xf);
+
+	strlcpy(info->driver, DRIVER_FILE_NAME, sizeof(info->driver));
+	strcpy(info->version, vers);
+	strcpy(info->fw_version, "N/A");
+	strlcpy(info->bus_info, pAC->PciDev->slot_name, ETHTOOL_BUSINFO_LEN);
+}
+
+/*
+ * Ethtool statistics support.
+ */
+static const char StringsStats[][ETH_GSTRING_LEN] = {
+	"rx_packets",	"tx_packets",
+	"rx_bytes",	"tx_bytes",
+	"rx_errors",	"tx_errors",	
+	"rx_dropped",	"tx_dropped",
+	"multicasts",	"collisions",	
+	"rx_length_errors",		"rx_buffer_overflow_errors",
+	"rx_crc_errors",		"rx_frame_errors",
+	"rx_too_short_errors",		"rx_too_long_errors",
+	"rx_carrier_extension_errors",	"rx_symbol_errors",
+	"rx_llc_mac_size_errors",	"rx_carrier_errors",	
+	"rx_jabber_errors",		"rx_missed_errors",
+	"tx_abort_collision_errors",	"tx_carrier_errors",
+	"tx_buffer_underrun_errors",	"tx_heartbeat_errors",
+	"tx_window_errors",
+};
+
+static int getStatsCount(struct net_device *dev)
+{
+	return ARRAY_SIZE(StringsStats);
+}
+
+static void getStrings(struct net_device *dev, u32 stringset, u8 *data)
+{
+	switch(stringset) {
+	case ETH_SS_STATS:
+		memcpy(data, *StringsStats, sizeof(StringsStats));
+		break;
+	}
+}
+
+static void getEthtoolStats(struct net_device *dev,
+			    struct ethtool_stats *stats, u64 *data)
+{
+	const DEV_NET	*pNet = netdev_priv(dev);
+	const SK_AC *pAC = pNet->pAC;
+	const SK_PNMI_STRUCT_DATA *pPnmiStruct = &pAC->PnmiStruct;
+
+	*data++ = pPnmiStruct->Stat[0].StatRxOkCts;
+	*data++ = pPnmiStruct->Stat[0].StatTxOkCts;
+	*data++ = pPnmiStruct->Stat[0].StatRxOctetsOkCts;
+	*data++ = pPnmiStruct->Stat[0].StatTxOctetsOkCts;
+	*data++ = pPnmiStruct->InErrorsCts;
+	*data++ = pPnmiStruct->Stat[0].StatTxSingleCollisionCts;
+	*data++ = pPnmiStruct->RxNoBufCts;
+	*data++ = pPnmiStruct->TxNoBufCts;
+	*data++ = pPnmiStruct->Stat[0].StatRxMulticastOkCts;
+	*data++ = pPnmiStruct->Stat[0].StatTxSingleCollisionCts;
+	*data++ = pPnmiStruct->Stat[0].StatRxRuntCts;
+	*data++ = pPnmiStruct->Stat[0].StatRxFifoOverflowCts;
+	*data++ = pPnmiStruct->Stat[0].StatRxFcsCts;
+	*data++ = pPnmiStruct->Stat[0].StatRxFramingCts;
+	*data++ = pPnmiStruct->Stat[0].StatRxShortsCts;
+	*data++ = pPnmiStruct->Stat[0].StatRxTooLongCts;
+	*data++ = pPnmiStruct->Stat[0].StatRxCextCts;
+	*data++ = pPnmiStruct->Stat[0].StatRxSymbolCts;
+	*data++ = pPnmiStruct->Stat[0].StatRxIRLengthCts;
+	*data++ = pPnmiStruct->Stat[0].StatRxCarrierCts;
+	*data++ = pPnmiStruct->Stat[0].StatRxJabberCts;
+	*data++ = pPnmiStruct->Stat[0].StatRxMissedCts;
+	*data++ = pAC->stats.tx_aborted_errors;
+	*data++ = pPnmiStruct->Stat[0].StatTxCarrierCts;
+	*data++ = pPnmiStruct->Stat[0].StatTxFifoUnderrunCts;
+	*data++ = pPnmiStruct->Stat[0].StatTxCarrierCts;
+	*data++ = pAC->stats.tx_window_errors;
+}
+
+
+/*****************************************************************************
+ *
+ * 	toggleLeds - Changes the LED state of an adapter
+ *
+ * Description:
+ *	This function changes the current state of all LEDs of an adapter so
+ *	that it can be located by a user. 
+ *
+ * Returns:	N/A
+ *
+ */
+static void toggleLeds(DEV_NET *pNet, int on)
+{
+	SK_AC *pAC = pNet->pAC;
+	int port = pNet->PortNr;
+	void __iomem *io = pAC->IoBase;
+
+	if (pAC->GIni.GIGenesis) {
+		SK_OUT8(io, MR_ADDR(port,LNK_LED_REG), 
+			on ? SK_LNK_ON : SK_LNK_OFF);
+		SkGeYellowLED(pAC, io, 
+			      on ? (LED_ON >> 1) : (LED_OFF >> 1));
+		SkGeXmitLED(pAC, io, MR_ADDR(port,RX_LED_INI),
+			    on ? SK_LED_TST : SK_LED_DIS);
+
+		if (pAC->GIni.GP[port].PhyType == SK_PHY_BCOM)
+			SkXmPhyWrite(pAC, io, port, PHY_BCOM_P_EXT_CTRL, 
+				     on ? PHY_B_PEC_LED_ON : PHY_B_PEC_LED_OFF);
+		else if (pAC->GIni.GP[port].PhyType == SK_PHY_LONE)
+			SkXmPhyWrite(pAC, io, port, PHY_LONE_LED_CFG,
+				     on ? 0x0800 : PHY_L_LC_LEDT);
+		else
+			SkGeXmitLED(pAC, io, MR_ADDR(port,TX_LED_INI),
+				    on ? SK_LED_TST : SK_LED_DIS);
+	} else {
+		const u16 YukLedOn = (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));
+		const u16  YukLedOff = (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));
+	
+
+		SkGmPhyWrite(pAC,io,port,PHY_MARV_LED_CTRL,0);
+		SkGmPhyWrite(pAC,io,port,PHY_MARV_LED_OVER, 
+			     on ? YukLedOn : YukLedOff);
+	}
+}
+
+/*****************************************************************************
+ *
+ * 	skGeBlinkTimer - Changes the LED state of an adapter
+ *
+ * Description:
+ *	This function changes the current state of all LEDs of an adapter so
+ *	that it can be located by a user. If the requested time interval for
+ *	this test has elapsed, this function cleans up everything that was 
+ *	temporarily setup during the locate NIC test. This involves of course
+ *	also closing or opening any adapter so that the initial board state 
+ *	is recovered.
+ *
+ * Returns:	N/A
+ *
+ */
+void SkGeBlinkTimer(unsigned long data)
+{
+	struct net_device *dev = (struct net_device *) data;
+	DEV_NET *pNet = netdev_priv(dev);
+	SK_AC *pAC = pNet->pAC;
+
+	toggleLeds(pNet, pAC->LedsOn);
+
+	pAC->LedsOn = !pAC->LedsOn;
+	mod_timer(&pAC->BlinkTimer, jiffies + HZ/4);
+}
+
+/*****************************************************************************
+ *
+ * 	locateDevice - start the locate NIC feature of the elected adapter 
+ *
+ * Description:
+ *	This function is used if the user want to locate a particular NIC.
+ *	All LEDs are regularly switched on and off, so the NIC can easily
+ *	be identified.
+ *
+ * Returns:	
+ *	==0:	everything fine, no error, locateNIC test was started
+ *	!=0:	one locateNIC test runs already
+ *
+ */
+static int locateDevice(struct net_device *dev, u32 data)
+{
+	DEV_NET *pNet = netdev_priv(dev);
+	SK_AC *pAC = pNet->pAC;
+
+	if(!data || data > (u32)(MAX_SCHEDULE_TIMEOUT / HZ))
+		data = (u32)(MAX_SCHEDULE_TIMEOUT / HZ);
+
+	/* start blinking */
+	pAC->LedsOn = 0;
+	mod_timer(&pAC->BlinkTimer, jiffies);
+	msleep_interruptible(data * 1000);
+
+	set_current_state(TASK_INTERRUPTIBLE);
+	schedule_timeout(data * HZ);
+	del_timer_sync(&pAC->BlinkTimer);
+	toggleLeds(pNet, 0);
+
+	return 0;
+}
+
+/*****************************************************************************
+ *
+ * 	getPauseParams - retrieves the pause parameters
+ *
+ * Description:
+ *	All current pause parameters of a selected adapter are placed 
+ *	in the passed ethtool_pauseparam structure and are returned.
+ *
+ * Returns:	N/A
+ *
+ */
+static void getPauseParams(struct net_device *dev, struct ethtool_pauseparam *epause) 
+{
+	DEV_NET	*pNet = netdev_priv(dev);
+	SK_AC *pAC = pNet->pAC;
+	SK_GEPORT *pPort = &pAC->GIni.GP[pNet->PortNr];
+
+	epause->rx_pause = (pPort->PFlowCtrlMode == SK_FLOW_MODE_SYMMETRIC) ||
+		  (pPort->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM);
+
+	epause->tx_pause = epause->rx_pause || (pPort->PFlowCtrlMode == SK_FLOW_MODE_LOC_SEND);
+	epause->autoneg = epause->rx_pause || epause->tx_pause;
+}
+
+/*****************************************************************************
+ *
+ *	setPauseParams - configures the pause parameters of an adapter
+ *
+ * Description:
+ *	This function sets the Rx or Tx pause parameters 
+ *
+ * Returns:
+ *	==0:	everything fine, no error
+ *	!=0:	the return value is the error code of the failure 
+ */
+static int setPauseParams(struct net_device *dev , struct ethtool_pauseparam *epause)
+{
+	DEV_NET	*pNet = netdev_priv(dev);
+	SK_AC *pAC = pNet->pAC;
+	SK_GEPORT *pPort = &pAC->GIni.GP[pNet->PortNr];
+	u32	instance = pnmiInstance(pNet);
+	struct ethtool_pauseparam old;
+	u8	oldspeed = pPort->PLinkSpeedUsed;
+	char	buf[4];
+	int	len = 1;
+	int ret;
+
+	/*
+	** we have to determine the current settings to see if 
+	** the operator requested any modification of the flow 
+	** control parameters...
+	*/
+	getPauseParams(dev, &old);
+
+	/*
+	** perform modifications regarding the changes 
+	** requested by the operator
+	*/
+	if (epause->autoneg != old.autoneg) 
+		*buf = epause->autoneg ? SK_FLOW_MODE_NONE : SK_FLOW_MODE_SYMMETRIC;
+	else {
+		if (epause->rx_pause && epause->tx_pause) 
+			*buf = SK_FLOW_MODE_SYMMETRIC;
+		else if (epause->rx_pause && !epause->tx_pause)
+			*buf =  SK_FLOW_MODE_SYM_OR_REM;
+		else if (!epause->rx_pause && epause->tx_pause)
+			*buf =  SK_FLOW_MODE_LOC_SEND;
+		else
+			*buf = SK_FLOW_MODE_NONE;
+	}
+
+	ret = SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_FLOWCTRL_MODE,
+			 &buf, &len, instance, pNet->NetNr);
+
+	if (ret != SK_PNMI_ERR_OK) {
+		SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_CTRL,
+			   ("ethtool (sk98lin): error changing rx/tx pause (%i)\n", ret));
+		goto err;
+	}
+
+	/*
+	** It may be that autoneg has been disabled! Therefore
+	** set the speed to the previously used value...
+	*/
+	if (!epause->autoneg) {
+		len = 1;
+		ret = SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_SPEED_MODE, 
+				   &oldspeed, &len, instance, pNet->NetNr);
+		if (ret != SK_PNMI_ERR_OK) 
+			SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_CTRL,
+				   ("ethtool (sk98lin): error setting speed (%i)\n", ret));
+	}
+ err:
+        return ret ? -EIO : 0;
+}
+
+struct ethtool_ops SkGeEthtoolOps = {
+	.get_settings		= getSettings,
+	.set_settings		= setSettings,
+	.get_drvinfo		= getDriverInfo,
+	.get_strings		= getStrings,
+	.get_stats_count	= getStatsCount,
+	.get_ethtool_stats	= getEthtoolStats,
+	.phys_id		= locateDevice,
+	.get_pauseparam		= getPauseParams,
+	.set_pauseparam		= setPauseParams,
+};
diff -Nru a/drivers/net/sk98lin/skge.c b/drivers/net/sk98lin/skge.c
--- a/drivers/net/sk98lin/skge.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/net/sk98lin/skge.c	2005-03-01 23:38:53 -08:00
@@ -109,6 +109,7 @@
 #include	"h/skversion.h"
 
 #include	<linux/module.h>
+#include	<linux/moduleparam.h>
 #include	<linux/init.h>
 #include 	<linux/proc_fs.h>
 
@@ -233,17 +234,33 @@
  * Extern Function Prototypes
  *
  ******************************************************************************/
-
-#ifdef CONFIG_PROC_FS
-static const char 	SK_Root_Dir_entry[] = "sk98lin";
+static const char 	SKRootName[] = "sk98lin";
 static struct		proc_dir_entry *pSkRootDir;
 extern struct	file_operations sk_proc_fops;
-#endif
+
+static inline void SkGeProcCreate(struct net_device *dev)
+{
+	struct proc_dir_entry *pe;
+
+	if (pSkRootDir && 
+	    (pe = create_proc_entry(dev->name, S_IRUGO, pSkRootDir))) {
+		pe->proc_fops = &sk_proc_fops;
+		pe->data = dev;
+		pe->owner = THIS_MODULE;
+	}
+}
+ 
+static inline void SkGeProcRemove(struct net_device *dev)
+{
+	if (pSkRootDir)
+		remove_proc_entry(dev->name, pSkRootDir);
+}
 
 extern void SkDimEnableModerationIfNeeded(SK_AC *pAC);	
 extern void SkDimDisplayModerationSettings(SK_AC *pAC);
 extern void SkDimStartModerationTimer(SK_AC *pAC);
 extern void SkDimModerate(SK_AC *pAC);
+extern void SkGeBlinkTimer(unsigned long data);
 
 #ifdef DEBUG
 static void	DumpMsg(struct sk_buff*, char*);
@@ -252,8 +269,8 @@
 #endif
 
 /* global variables *********************************************************/
-struct SK_NET_DEVICE *SkGeRootDev = NULL;
 static SK_BOOL DoPrintInterfaceChange = SK_TRUE;
+extern  struct ethtool_ops SkGeEthtoolOps;
 
 /* local variables **********************************************************/
 static uintptr_t TxQueueAddr[SK_MAX_MACS][2] = {{0x680, 0x600},{0x780, 0x700}};
@@ -337,22 +354,20 @@
 DEV_NET		*pNet;
 SK_AC		*pAC;
 
-	if (dev->priv) {
-		pNet = (DEV_NET*) dev->priv;
-		pAC = pNet->pAC;
-		AllocFlag = pAC->AllocFlag;
-		if (pAC->PciDev) {
-			pci_release_regions(pAC->PciDev);
-		}
-		if (AllocFlag & SK_ALLOC_IRQ) {
-			free_irq(dev->irq, dev);
-		}
-		if (pAC->IoBase) {
-			iounmap(pAC->IoBase);
-		}
-		if (pAC->pDescrMem) {
-			BoardFreeMem(pAC);
-		}
+	pNet = netdev_priv(dev);
+	pAC = pNet->pAC;
+	AllocFlag = pAC->AllocFlag;
+	if (pAC->PciDev) {
+		pci_release_regions(pAC->PciDev);
+	}
+	if (AllocFlag & SK_ALLOC_IRQ) {
+		free_irq(dev->irq, dev);
+	}
+	if (pAC->IoBase) {
+		iounmap(pAC->IoBase);
+	}
+	if (pAC->pDescrMem) {
+		BoardFreeMem(pAC);
 	}
 	
 } /* FreeResources */
@@ -360,26 +375,6 @@
 MODULE_AUTHOR("Mirko Lindner <mlindner@syskonnect.de>");
 MODULE_DESCRIPTION("SysKonnect SK-NET Gigabit Ethernet SK-98xx driver");
 MODULE_LICENSE("GPL");
-MODULE_PARM(Speed_A,    "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
-MODULE_PARM(Speed_B,    "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
-MODULE_PARM(AutoNeg_A,  "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
-MODULE_PARM(AutoNeg_B,  "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
-MODULE_PARM(DupCap_A,   "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
-MODULE_PARM(DupCap_B,   "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
-MODULE_PARM(FlowCtrl_A, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
-MODULE_PARM(FlowCtrl_B, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
-MODULE_PARM(Role_A,	"1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
-MODULE_PARM(Role_B,	"1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
-MODULE_PARM(ConType,	"1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
-MODULE_PARM(PrefPort,   "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
-MODULE_PARM(RlmtMode,   "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
-/* used for interrupt moderation */
-MODULE_PARM(IntsPerSec,     "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "i");
-MODULE_PARM(Moderation,     "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
-MODULE_PARM(Stats,          "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
-MODULE_PARM(ModerationMask, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
-MODULE_PARM(AutoSizing,     "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
-
 
 #ifdef LINK_SPEED_A
 static char *Speed_A[SK_MAX_CARD_PARAM] = LINK_SPEED;
@@ -465,6 +460,26 @@
 static char *AutoSizing[SK_MAX_CARD_PARAM];
 static char *Stats[SK_MAX_CARD_PARAM];
 
+module_param_array(Speed_A, charp, NULL, 0);
+module_param_array(Speed_B, charp, NULL, 0);
+module_param_array(AutoNeg_A, charp, NULL, 0);
+module_param_array(AutoNeg_B, charp, NULL, 0);
+module_param_array(DupCap_A, charp, NULL, 0);
+module_param_array(DupCap_B, charp, NULL, 0);
+module_param_array(FlowCtrl_A, charp, NULL, 0);
+module_param_array(FlowCtrl_B, charp, NULL, 0);
+module_param_array(Role_A, charp, NULL, 0);
+module_param_array(Role_B, charp, NULL, 0);
+module_param_array(ConType, charp, NULL, 0);
+module_param_array(PrefPort, charp, NULL, 0);
+module_param_array(RlmtMode, charp, NULL, 0);
+/* used for interrupt moderation */
+module_param_array(IntsPerSec, int, NULL, 0);
+module_param_array(Moderation, charp, NULL, 0);
+module_param_array(Stats, charp, NULL, 0);
+module_param_array(ModerationMask, charp, NULL, 0);
+module_param_array(AutoSizing, charp, NULL, 0);
+
 /*****************************************************************************
  *
  * 	SkGeBoardInit - do level 0 and 1 initialization
@@ -503,6 +518,11 @@
 	}
 	spin_lock_init(&pAC->SlowPathLock);
 
+	/* setup phy_id blink timer */
+	pAC->BlinkTimer.function = SkGeBlinkTimer;
+	pAC->BlinkTimer.data = (unsigned long) dev;
+	init_timer(&pAC->BlinkTimer);
+
 	/* level 0 init common modules here */
 	
 	spin_lock_irqsave(&pAC->SlowPathLock, Flags);
@@ -601,12 +621,6 @@
 		return(-EAGAIN);
 	}
 
-	/*
-	 * Register the device here
-	 */
-	pAC->Next = SkGeRootDev;
-	SkGeRootDev = dev;
-
 	return (0);
 } /* SkGeBoardInit */
 
@@ -887,7 +901,7 @@
 SK_AC		*pAC;
 SK_U32		IntSrc;		/* interrupts source register contents */	
 
-	pNet = (DEV_NET*) dev->priv;
+	pNet = netdev_priv(dev);
 	pAC = pNet->pAC;
 	
 	/*
@@ -1036,7 +1050,7 @@
 SK_AC		*pAC;
 SK_U32		IntSrc;		/* interrupts source register contents */	
 
-	pNet = (DEV_NET*) dev->priv;
+	pNet = netdev_priv(dev);
 	pAC = pNet->pAC;
 	
 	/*
@@ -1126,6 +1140,24 @@
 		return SkIsrRetHandled;
 } /* SkGeIsrOnePort */
 
+#ifdef CONFIG_NET_POLL_CONTROLLER
+/****************************************************************************
+ *
+ * 	SkGePollController - polling receive, for netconsole
+ *
+ * Description:
+ *	Polling receive - used by netconsole and other diagnostic tools
+ *	to allow network i/o with interrupts disabled.
+ *
+ * Returns: N/A
+ */
+static void SkGePollController(struct net_device *dev)
+{
+	disable_irq(dev->irq);
+	SkGeIsr(dev->irq, dev, NULL);
+	enable_irq(dev->irq);
+}
+#endif
 
 /****************************************************************************
  *
@@ -1152,7 +1184,7 @@
 	int				i;
 	SK_EVPARA		EvPara;		/* an event parameter union */
 
-	pNet = (DEV_NET*) dev->priv;
+	pNet = netdev_priv(dev);
 	pAC = pNet->pAC;
 	
 	SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
@@ -1166,10 +1198,6 @@
 	}
 #endif
 
-	if (!try_module_get(THIS_MODULE)) {
-		return (-1);	/* increase of usage count not possible */
-	}
-
 	/* Set blink mode */
 	if ((pAC->PciDev->vendor == 0x1186) || (pAC->PciDev->vendor == 0x11ab ))
 		pAC->GIni.GILedBlinkCtrl = OEM_CONFIG_VALUE;
@@ -1177,7 +1205,6 @@
 	if (pAC->BoardLevel == SK_INIT_DATA) {
 		/* level 1 init common modules here */
 		if (SkGeInit(pAC, pAC->IoBase, SK_INIT_IO) != 0) {
-			module_put(THIS_MODULE); /* decrease usage count */
 			printk("%s: HWInit (1) failed.\n", pAC->dev[pNet->PortNr]->name);
 			return (-1);
 		}
@@ -1193,7 +1220,6 @@
 	if (pAC->BoardLevel != SK_INIT_RUN) {
 		/* tschilling: Level 2 init modules here, check return value. */
 		if (SkGeInit(pAC, pAC->IoBase, SK_INIT_RUN) != 0) {
-			module_put(THIS_MODULE); /* decrease usage count */
 			printk("%s: HWInit (2) failed.\n", pAC->dev[pNet->PortNr]->name);
 			return (-1);
 		}
@@ -1279,19 +1305,18 @@
 	SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
 		("SkGeClose: pAC=0x%lX ", (unsigned long)pAC));
 
-	pNet = (DEV_NET*) dev->priv;
+	pNet = netdev_priv(dev);
 	pAC = pNet->pAC;
 
 #ifdef SK_DIAG_SUPPORT
 	if (pAC->DiagModeActive == DIAG_ACTIVE) {
 		if (pAC->DiagFlowCtrl == SK_FALSE) {
-			module_put(THIS_MODULE);
 			/* 
 			** notify that the interface which has been closed
 			** by operator interaction must not be started up 
 			** again when the DIAG has finished. 
 			*/
-			newPtrNet = (DEV_NET *) pAC->dev[0]->priv;
+			newPtrNet = netdev_priv(pAC->dev[0]);
 			if (newPtrNet == pNet) {
 				pAC->WasIfUp[0] = SK_FALSE;
 			} else {
@@ -1376,7 +1401,6 @@
 	pAC->MaxPorts--;
 	pNet->Up = 0;
 
-	module_put(THIS_MODULE);
 	return (0);
 } /* SkGeClose */
 
@@ -1402,7 +1426,7 @@
 SK_AC		*pAC;
 int			Rc;	/* return code of XmitFrame */
 
-	pNet = (DEV_NET*) dev->priv;
+	pNet = netdev_priv(dev);
 	pAC = pNet->pAC;
 
 	if ((!skb_shinfo(skb)->nr_frags) ||
@@ -2498,7 +2522,7 @@
 static int SkGeSetMacAddr(struct SK_NET_DEVICE *dev, void *p)
 {
 
-DEV_NET *pNet = (DEV_NET*) dev->priv;
+DEV_NET *pNet = netdev_priv(dev);
 SK_AC	*pAC = pNet->pAC;
 
 struct sockaddr	*addr = p;
@@ -2555,7 +2579,7 @@
 	SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
 		("SkGeSetRxMode starts now... "));
 
-	pNet = (DEV_NET*) dev->priv;
+	pNet = netdev_priv(dev);
 	pAC = pNet->pAC;
 	if (pAC->RlmtNets == 1)
 		PortIdx = pAC->ActivePort;
@@ -2627,7 +2651,7 @@
 	SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
 		("SkGeChangeMtu starts now...\n"));
 
-	pNet = (DEV_NET*) dev->priv;
+	pNet = netdev_priv(dev);
 	pAC  = pNet->pAC;
 
 	if ((NewMtu < 68) || (NewMtu > SK_JUMBO_MTU)) {
@@ -2649,7 +2673,7 @@
 #endif
 
 	pNet->Mtu = NewMtu;
-	pOtherNet = (DEV_NET*)pAC->dev[1 - pNet->NetNr]->priv;
+	pOtherNet = netdev_priv(pAC->dev[1 - pNet->NetNr]);
 	if ((pOtherNet->Mtu>1500) && (NewMtu<=1500) && (pOtherNet->Up==1)) {
 		return(0);
 	}
@@ -2855,7 +2879,7 @@
  */
 static struct net_device_stats *SkGeStats(struct SK_NET_DEVICE *dev)
 {
-DEV_NET *pNet = (DEV_NET*) dev->priv;
+DEV_NET *pNet = netdev_priv(dev);
 SK_AC	*pAC = pNet->pAC;
 SK_PNMI_STRUCT_DATA *pPnmiStruct;       /* structure for all Pnmi-Data */
 SK_PNMI_STAT    *pPnmiStat;             /* pointer to virtual XMAC stat. data */
@@ -2953,7 +2977,7 @@
 	SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
 		("SkGeIoctl starts now...\n"));
 
-	pNet = (DEV_NET*) dev->priv;
+	pNet = netdev_priv(dev);
 	pAC = pNet->pAC;
 	
 	if(copy_from_user(&Ioctl, rq->ifr_data, sizeof(SK_GE_IOCTL))) {
@@ -4539,11 +4563,8 @@
 int SkDrvEnterDiagMode(
 SK_AC   *pAc)   /* pointer to adapter context */
 {
-	SK_AC   *pAC  = NULL;
-	DEV_NET *pNet = NULL;
-
-	pNet = (DEV_NET *) pAc->dev[0]->priv;
-	pAC = pNet->pAC;
+	DEV_NET *pNet = netdev_priv(pAc->dev[0]);
+	SK_AC   *pAC  = pNet->pAC;
 
 	SK_MEMCPY(&(pAc->PnmiBackup), &(pAc->PnmiStruct), 
 			sizeof(SK_PNMI_STRUCT_DATA));
@@ -4558,8 +4579,8 @@
 		} else {
 			pAC->WasIfUp[0] = SK_FALSE;
 		}
-		if (pNet != (DEV_NET *) pAc->dev[1]->priv) {
-			pNet = (DEV_NET *) pAc->dev[1]->priv;
+		if (pNet != netdev_priv(pAC->dev[1])) {
+			pNet = netdev_priv(pAC->dev[1]);
 			if (pNet->Up) {
 				pAC->WasIfUp[1] = SK_TRUE;
 				pAC->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */
@@ -4681,20 +4702,11 @@
 
 	dev = pAC->dev[devNbr];
 
-	/*
-	** Function SkGeClose() uses MOD_DEC_USE_COUNT (2.2/2.4)
-	** or module_put() (2.6) to decrease the number of users for
-	** a device, but if a device is to be put under control of 
-	** the DIAG, that count is OK already and does not need to 
-	** be adapted! Hence the opposite MOD_INC_USE_COUNT or 
-	** try_module_get() needs to be used again to correct that.
+	/* On Linux 2.6 the network driver does NOT mess with reference
+	** counts.  The driver MUST be able to be unloaded at any time
+	** due to the possibility of hotplug.
 	*/
-	if (!try_module_get(THIS_MODULE)) {
-		return (-1);
-	}
-
 	if (SkGeClose(dev) != 0) {
-		module_put(THIS_MODULE);
 		return (-1);
 	}
 	return (0);
@@ -4723,17 +4735,6 @@
 
 	if (SkGeOpen(dev) != 0) {
 		return (-1);
-	} else {
-		/*
-		** Function SkGeOpen() uses MOD_INC_USE_COUNT (2.2/2.4) 
-		** or try_module_get() (2.6) to increase the number of 
-		** users for a device, but if a device was just under 
-		** control of the DIAG, that count is OK already and 
-		** does not need to be adapted! Hence the opposite 
-		** MOD_DEC_USE_COUNT or module_put() needs to be used 
-		** again to correct that.
-		*/
-		module_put(THIS_MODULE);
 	}
 
 	/*
@@ -4904,9 +4905,6 @@
 	SK_AC			*pAC;
 	DEV_NET			*pNet = NULL;
 	struct net_device	*dev = NULL;
-#ifdef CONFIG_PROC_FS
-	struct proc_dir_entry	*pProcFile;
-#endif
 	static int boards_found = 0;
 	int error = -ENODEV;
 
@@ -4925,7 +4923,7 @@
 		goto out_disable_device;
 	}
 
-	pNet = dev->priv;
+	pNet = netdev_priv(dev);
 	pNet->pAC = kmalloc(sizeof(SK_AC), GFP_KERNEL);
 	if (!pNet->pAC) {
 		printk(KERN_ERR "Unable to allocate adapter "
@@ -4960,8 +4958,12 @@
 	dev->set_mac_address =	&SkGeSetMacAddr;
 	dev->do_ioctl =		&SkGeIoctl;
 	dev->change_mtu =	&SkGeChangeMtu;
+#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);
 
 #ifdef SK_ZEROCOPY
 #ifdef USE_SK_TX_CHECKSUM
@@ -5002,14 +5004,7 @@
 
 	memcpy(&dev->dev_addr, &pAC->Addr.Net[0].CurrentMacAddress, 6);
 
-#ifdef CONFIG_PROC_FS
-	pProcFile = create_proc_entry(dev->name, S_IRUGO, pSkRootDir);
-	if (pProcFile) {
-		pProcFile->proc_fops = &sk_proc_fops;
-		pProcFile->data = dev;
-		pProcFile->owner = THIS_MODULE;
-	}
-#endif
+	SkGeProcCreate(dev);
 
 	pNet->PortNr = 0;
 	pNet->NetNr  = 0;
@@ -5025,7 +5020,7 @@
 		}
 
 		pAC->dev[1]   = dev;
-		pNet          = dev->priv;
+		pNet          = netdev_priv(dev);
 		pNet->PortNr  = 1;
 		pNet->NetNr   = 1;
 		pNet->pAC     = pAC;
@@ -5041,6 +5036,8 @@
 		dev->do_ioctl           = &SkGeIoctl;
 		dev->change_mtu         = &SkGeChangeMtu;
 		dev->flags             &= ~IFF_RUNNING;
+		SET_NETDEV_DEV(dev, &pdev->dev);
+		SET_ETHTOOL_OPS(dev, &SkGeEthtoolOps);
 
 #ifdef SK_ZEROCOPY
 #ifdef USE_SK_TX_CHECKSUM
@@ -5056,16 +5053,7 @@
 			free_netdev(dev);
 			pAC->dev[1] = pAC->dev[0];
 		} else {
-#ifdef CONFIG_PROC_FS
-			pProcFile = create_proc_entry(dev->name, S_IRUGO,
-					pSkRootDir);
-			if (pProcFile) {
-				pProcFile->proc_fops = &sk_proc_fops;
-				pProcFile->data = dev;
-				pProcFile->owner = THIS_MODULE;
-			}
-#endif
-
+			SkGeProcCreate(dev);
 			memcpy(&dev->dev_addr,
 					&pAC->Addr.Net[1].CurrentMacAddress, 6);
 	
@@ -5101,19 +5089,14 @@
 static void __devexit skge_remove_one(struct pci_dev *pdev)
 {
 	struct net_device *dev = pci_get_drvdata(pdev);
-	DEV_NET *pNet = (DEV_NET *) dev->priv;
+	DEV_NET *pNet = netdev_priv(dev);
 	SK_AC *pAC = pNet->pAC;
-	int have_second_mac = 0;
-
-	if ((pAC->GIni.GIMacsFound == 2) && pAC->RlmtNets == 2)
-		have_second_mac = 1;
+	struct net_device *otherdev = pAC->dev[1];
 
-	remove_proc_entry(dev->name, pSkRootDir);
+	SkGeProcRemove(dev);
 	unregister_netdev(dev);
-	if (have_second_mac) {
-		remove_proc_entry(pAC->dev[1]->name, pSkRootDir);
-		unregister_netdev(pAC->dev[1]);
-	}
+	if (otherdev != dev)
+		SkGeProcRemove(otherdev);
 
 	SkGeYellowLED(pAC, pAC->IoBase, 0);
 
@@ -5146,8 +5129,8 @@
 
 	FreeResources(dev);
 	free_netdev(dev);
-	if (have_second_mac)
-		free_netdev(pAC->dev[1]);
+	if (otherdev != dev)
+		free_netdev(otherdev);
 	kfree(pAC);
 }
 
@@ -5180,34 +5163,21 @@
 {
 	int error;
 
-#ifdef CONFIG_PROC_FS
-	memcpy(&SK_Root_Dir_entry, BOOT_STRING, sizeof(SK_Root_Dir_entry) - 1);
-
-	pSkRootDir = proc_mkdir(SK_Root_Dir_entry, proc_net);
-	if (!pSkRootDir) {
-		printk(KERN_WARNING "Unable to create /proc/net/%s",
-				SK_Root_Dir_entry);
-		return -ENOMEM;
-	}
-	pSkRootDir->owner = THIS_MODULE;
-#endif
-
-	error = pci_module_init(&skge_driver);
-	if (error) {
-#ifdef CONFIG_PROC_FS
-		remove_proc_entry(pSkRootDir->name, proc_net);
-#endif
-	}
-
+	pSkRootDir = proc_mkdir(SKRootName, proc_net);
+	if (pSkRootDir) 
+		pSkRootDir->owner = THIS_MODULE;
+	
+	error = pci_register_driver(&skge_driver);
+	if (error)
+		proc_net_remove(SKRootName);
 	return error;
 }
 
 static void __exit skge_exit(void)
 {
-	 pci_unregister_driver(&skge_driver);
-#ifdef CONFIG_PROC_FS
-	remove_proc_entry(pSkRootDir->name, proc_net);
-#endif
+	pci_unregister_driver(&skge_driver);
+	proc_net_remove(SKRootName);
+
 }
 
 module_init(skge_init);
diff -Nru a/drivers/net/sk98lin/skproc.c b/drivers/net/sk98lin/skproc.c
--- a/drivers/net/sk98lin/skproc.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/net/sk98lin/skproc.c	2005-03-01 23:38:52 -08:00
@@ -31,13 +31,9 @@
 #include "h/skdrv2nd.h"
 #include "h/skversion.h"
 
-extern struct SK_NET_DEVICE *SkGeRootDev;
-static int sk_proc_print(void *writePtr, char *format, ...);
-static void sk_gen_browse(void *buffer);
-int len;
-
 static int sk_seq_show(struct seq_file *seq, void *v);
 static int sk_proc_open(struct inode *inode, struct file *file);
+
 struct file_operations sk_proc_fops = {
 	.owner		= THIS_MODULE,
 	.open		= sk_proc_open,
@@ -45,315 +41,206 @@
 	.llseek		= seq_lseek,
 	.release	= single_release,
 };
-struct net_device *currDev = NULL;
+
 
 /*****************************************************************************
  *
- * 	sk_gen_browse -generic  print "summaries" entry 
+ *      sk_seq_show - show proc information of a particular adapter
  *
  * Description:
  *  This function fills the proc entry with statistic data about 
- *  the ethernet device.
+ *  the ethernet device. It invokes the generic sk_gen_browse() to
+ *  print out all items one per one.
  *  
- * Returns: -
- *	
+ * Returns: 0
+ *      
  */
-static void sk_gen_browse(void *buffer)
+static int sk_seq_show(struct seq_file *seq, void *v)
 {
-	struct SK_NET_DEVICE	*SkgeProcDev = SkGeRootDev;
-	struct SK_NET_DEVICE	*next;
-	SK_PNMI_STRUCT_DATA 	*pPnmiStruct;
-	SK_PNMI_STAT		*pPnmiStat;
+	struct net_device *dev = seq->private;
+	DEV_NET			*pNet = netdev_priv(dev);
+	SK_AC			*pAC = pNet->pAC;
+	SK_PNMI_STRUCT_DATA 	*pPnmiStruct = &pAC->PnmiStruct;
 	unsigned long		Flags;	
 	unsigned int		Size;
-	DEV_NET			*pNet;
-	SK_AC			*pAC;
 	char			sens_msg[50];
-	int			MaxSecurityCount = 0;
 	int 			t;
 	int 			i;
 
-	while (SkgeProcDev) {
-		MaxSecurityCount++;
-		if (MaxSecurityCount > 100) {
-			printk("Max limit for sk_proc_read security counter!\n");
-			return;
-		}
-		pNet = (DEV_NET*) SkgeProcDev->priv;
-		pAC = pNet->pAC;
-		next = pAC->Next;
-		pPnmiStruct = &pAC->PnmiStruct;
-		/* NetIndex in GetStruct is now required, zero is only dummy */
-
-		for (t=pAC->GIni.GIMacsFound; t > 0; t--) {
-			if ((pAC->GIni.GIMacsFound == 2) && pAC->RlmtNets == 1)
-				t--;
+	/* NetIndex in GetStruct is now required, zero is only dummy */
+	for (t=pAC->GIni.GIMacsFound; t > 0; t--) {
+		if ((pAC->GIni.GIMacsFound == 2) && pAC->RlmtNets == 1)
+			t--;
 
-			spin_lock_irqsave(&pAC->SlowPathLock, Flags);
-			Size = SK_PNMI_STRUCT_SIZE;
+		spin_lock_irqsave(&pAC->SlowPathLock, Flags);
+		Size = SK_PNMI_STRUCT_SIZE;
 #ifdef SK_DIAG_SUPPORT
-			if (pAC->BoardLevel == SK_INIT_DATA) {
-				SK_MEMCPY(&(pAC->PnmiStruct), &(pAC->PnmiBackup), sizeof(SK_PNMI_STRUCT_DATA));
-				if (pAC->DiagModeActive == DIAG_NOTACTIVE) {
-					pAC->Pnmi.DiagAttached = SK_DIAG_IDLE;
-				}
-			} else {
-				SkPnmiGetStruct(pAC, pAC->IoBase, pPnmiStruct, &Size, t-1);
+		if (pAC->BoardLevel == SK_INIT_DATA) {
+			SK_MEMCPY(&(pAC->PnmiStruct), &(pAC->PnmiBackup), sizeof(SK_PNMI_STRUCT_DATA));
+			if (pAC->DiagModeActive == DIAG_NOTACTIVE) {
+				pAC->Pnmi.DiagAttached = SK_DIAG_IDLE;
 			}
+		} else {
+			SkPnmiGetStruct(pAC, pAC->IoBase, pPnmiStruct, &Size, t-1);
+		}
 #else
-			SkPnmiGetStruct(pAC, pAC->IoBase, 
+		SkPnmiGetStruct(pAC, pAC->IoBase, 
 				pPnmiStruct, &Size, t-1);
 #endif
-			spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
+		spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
 	
-			if (strcmp(pAC->dev[t-1]->name, currDev->name) == 0) {
-				pPnmiStat = &pPnmiStruct->Stat[0];
-				len = sk_proc_print(buffer, 
-					"\nDetailed statistic for device %s\n",
-					pAC->dev[t-1]->name);
-				len += sk_proc_print(buffer,
-					"=======================================\n");
+		if (pAC->dev[t-1] == dev) {
+			SK_PNMI_STAT	*pPnmiStat = &pPnmiStruct->Stat[0];
+
+			seq_printf(seq, "\nDetailed statistic for device %s\n",
+				      pAC->dev[t-1]->name);
+			seq_printf(seq, "=======================================\n");
 	
-				/* Board statistics */
-				len += sk_proc_print(buffer, 
-					"\nBoard statistics\n\n");
-				len += sk_proc_print(buffer,
-					"Active Port                    %c\n",
-					'A' + pAC->Rlmt.Net[t-1].Port[pAC->Rlmt.
-					Net[t-1].PrefPort]->PortNumber);
-				len += sk_proc_print(buffer,
-					"Preferred Port                 %c\n",
-					'A' + pAC->Rlmt.Net[t-1].Port[pAC->Rlmt.
-					Net[t-1].PrefPort]->PortNumber);
-
-				len += sk_proc_print(buffer,
-					"Bus speed (MHz)                %d\n",
-					pPnmiStruct->BusSpeed);
-
-				len += sk_proc_print(buffer,
-					"Bus width (Bit)                %d\n",
-					pPnmiStruct->BusWidth);
-				len += sk_proc_print(buffer,
-					"Driver version                 %s\n",
-					VER_STRING);
-				len += sk_proc_print(buffer,
-					"Hardware revision              v%d.%d\n",
-					(pAC->GIni.GIPciHwRev >> 4) & 0x0F,
-					pAC->GIni.GIPciHwRev & 0x0F);
-
-				/* Print sensor informations */
-				for (i=0; i < pAC->I2c.MaxSens; i ++) {
-					/* Check type */
-					switch (pAC->I2c.SenTable[i].SenType) {
-					case 1:
-						strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
-						strcat(sens_msg, " (C)");
-						len += sk_proc_print(buffer,
-							"%-25s      %d.%02d\n",
-							sens_msg,
-							pAC->I2c.SenTable[i].SenValue / 10,
-							pAC->I2c.SenTable[i].SenValue % 10);
-
-						strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
-						strcat(sens_msg, " (F)");
-						len += sk_proc_print(buffer,
-							"%-25s      %d.%02d\n",
-							sens_msg,
-							((((pAC->I2c.SenTable[i].SenValue)
-							*10)*9)/5 + 3200)/100,
-							((((pAC->I2c.SenTable[i].SenValue)
-							*10)*9)/5 + 3200) % 10);
-						break;
-					case 2:
-						strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
-						strcat(sens_msg, " (V)");
-						len += sk_proc_print(buffer,
-							"%-25s      %d.%03d\n",
-							sens_msg,
-							pAC->I2c.SenTable[i].SenValue / 1000,
-							pAC->I2c.SenTable[i].SenValue % 1000);
-						break;
-					case 3:
-						strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
-						strcat(sens_msg, " (rpm)");
-						len += sk_proc_print(buffer,
-							"%-25s      %d\n",
-							sens_msg,
-							pAC->I2c.SenTable[i].SenValue);
-						break;
-					default:
-						break;
-					}
+			/* Board statistics */
+			seq_printf(seq, "\nBoard statistics\n\n");
+			seq_printf(seq, "Active Port                    %c\n",
+				      'A' + pAC->Rlmt.Net[t-1].Port[pAC->Rlmt.
+								    Net[t-1].PrefPort]->PortNumber);
+			seq_printf(seq, "Preferred Port                 %c\n",
+				      'A' + pAC->Rlmt.Net[t-1].Port[pAC->Rlmt.
+								    Net[t-1].PrefPort]->PortNumber);
+
+			seq_printf(seq, "Bus speed (MHz)                %d\n",
+				      pPnmiStruct->BusSpeed);
+
+			seq_printf(seq, "Bus width (Bit)                %d\n",
+				      pPnmiStruct->BusWidth);
+			seq_printf(seq, "Driver version                 %s\n",
+				      VER_STRING);
+			seq_printf(seq, "Hardware revision              v%d.%d\n",
+				      (pAC->GIni.GIPciHwRev >> 4) & 0x0F,
+				      pAC->GIni.GIPciHwRev & 0x0F);
+
+			/* Print sensor informations */
+			for (i=0; i < pAC->I2c.MaxSens; i ++) {
+				/* Check type */
+				switch (pAC->I2c.SenTable[i].SenType) {
+				case 1:
+					strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
+					strcat(sens_msg, " (C)");
+					seq_printf(seq, "%-25s      %d.%02d\n",
+						      sens_msg,
+						      pAC->I2c.SenTable[i].SenValue / 10,
+						      pAC->I2c.SenTable[i].SenValue % 10);
+
+					strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
+					strcat(sens_msg, " (F)");
+					seq_printf(seq, "%-25s      %d.%02d\n",
+						      sens_msg,
+						      ((((pAC->I2c.SenTable[i].SenValue)
+							 *10)*9)/5 + 3200)/100,
+						      ((((pAC->I2c.SenTable[i].SenValue)
+							 *10)*9)/5 + 3200) % 10);
+					break;
+				case 2:
+					strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
+					strcat(sens_msg, " (V)");
+					seq_printf(seq, "%-25s      %d.%03d\n",
+						      sens_msg,
+						      pAC->I2c.SenTable[i].SenValue / 1000,
+						      pAC->I2c.SenTable[i].SenValue % 1000);
+					break;
+				case 3:
+					strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
+					strcat(sens_msg, " (rpm)");
+					seq_printf(seq, "%-25s      %d\n",
+						      sens_msg,
+						      pAC->I2c.SenTable[i].SenValue);
+					break;
+				default:
+					break;
 				}
+			}
 				
-				/*Receive statistics */
-				len += sk_proc_print(buffer, 
-				"\nReceive statistics\n\n");
-
-				len += sk_proc_print(buffer,
-					"Received bytes                 %Lu\n",
-					(unsigned long long) pPnmiStat->StatRxOctetsOkCts);
-				len += sk_proc_print(buffer,
-					"Received packets               %Lu\n",
-					(unsigned long long) pPnmiStat->StatRxOkCts);
+			/*Receive statistics */
+			seq_printf(seq, "\nReceive statistics\n\n");
+
+			seq_printf(seq, "Received bytes                 %Lu\n",
+				      (unsigned long long) pPnmiStat->StatRxOctetsOkCts);
+			seq_printf(seq, "Received packets               %Lu\n",
+				      (unsigned long long) pPnmiStat->StatRxOkCts);
 #if 0
-				if (pAC->GIni.GP[0].PhyType == SK_PHY_XMAC && 
-					pAC->HWRevision < 12) {
-					pPnmiStruct->InErrorsCts = pPnmiStruct->InErrorsCts - 
-						pPnmiStat->StatRxShortsCts;
-					pPnmiStat->StatRxShortsCts = 0;
-				}
+			if (pAC->GIni.GP[0].PhyType == SK_PHY_XMAC && 
+			    pAC->HWRevision < 12) {
+				pPnmiStruct->InErrorsCts = pPnmiStruct->InErrorsCts - 
+					pPnmiStat->StatRxShortsCts;
+				pPnmiStat->StatRxShortsCts = 0;
+			}
 #endif
-				if (pNet->Mtu > 1500) 
-					pPnmiStruct->InErrorsCts = pPnmiStruct->InErrorsCts -
-						pPnmiStat->StatRxTooLongCts;
-
-				len += sk_proc_print(buffer,
-					"Receive errors                 %Lu\n",
-					(unsigned long long) pPnmiStruct->InErrorsCts);
-				len += sk_proc_print(buffer,
-					"Receive dropped                %Lu\n",
-					(unsigned long long) pPnmiStruct->RxNoBufCts);
-				len += sk_proc_print(buffer,
-					"Received multicast             %Lu\n",
-					(unsigned long long) pPnmiStat->StatRxMulticastOkCts);
-				len += sk_proc_print(buffer,
-					"Receive error types\n");
-				len += sk_proc_print(buffer,
-					"   length                      %Lu\n",
-					(unsigned long long) pPnmiStat->StatRxRuntCts);
-				len += sk_proc_print(buffer,
-					"   buffer overflow             %Lu\n",
-					(unsigned long long) pPnmiStat->StatRxFifoOverflowCts);
-				len += sk_proc_print(buffer,
-					"   bad crc                     %Lu\n",
-					(unsigned long long) pPnmiStat->StatRxFcsCts);
-				len += sk_proc_print(buffer,
-					"   framing                     %Lu\n",
-					(unsigned long long) pPnmiStat->StatRxFramingCts);
-				len += sk_proc_print(buffer,
-					"   missed frames               %Lu\n",
-					(unsigned long long) pPnmiStat->StatRxMissedCts);
-
-				if (pNet->Mtu > 1500)
-					pPnmiStat->StatRxTooLongCts = 0;
-
-				len += sk_proc_print(buffer,
-					"   too long                    %Lu\n",
-					(unsigned long long) pPnmiStat->StatRxTooLongCts);					
-				len += sk_proc_print(buffer,
-					"   carrier extension           %Lu\n",
-					(unsigned long long) pPnmiStat->StatRxCextCts);				
-				len += sk_proc_print(buffer,
-					"   too short                   %Lu\n",
-					(unsigned long long) pPnmiStat->StatRxShortsCts);				
-				len += sk_proc_print(buffer,
-					"   symbol                      %Lu\n",
-					(unsigned long long) pPnmiStat->StatRxSymbolCts);				
-				len += sk_proc_print(buffer,
-					"   LLC MAC size                %Lu\n",
-					(unsigned long long) pPnmiStat->StatRxIRLengthCts);				
-				len += sk_proc_print(buffer,
-					"   carrier event               %Lu\n",
-					(unsigned long long) pPnmiStat->StatRxCarrierCts);				
-				len += sk_proc_print(buffer,
-					"   jabber                      %Lu\n",
-					(unsigned long long) pPnmiStat->StatRxJabberCts);				
-
-
-				/*Transmit statistics */
-				len += sk_proc_print(buffer, 
-				"\nTransmit statistics\n\n");
+			if (dev->mtu > 1500)
+				pPnmiStruct->InErrorsCts = pPnmiStruct->InErrorsCts -
+					pPnmiStat->StatRxTooLongCts;
+
+			seq_printf(seq, "Receive errors                 %Lu\n",
+				      (unsigned long long) pPnmiStruct->InErrorsCts);
+			seq_printf(seq, "Receive dropped                %Lu\n",
+				      (unsigned long long) pPnmiStruct->RxNoBufCts);
+			seq_printf(seq, "Received multicast             %Lu\n",
+				      (unsigned long long) pPnmiStat->StatRxMulticastOkCts);
+			seq_printf(seq, "Receive error types\n");
+			seq_printf(seq, "   length                      %Lu\n",
+				      (unsigned long long) pPnmiStat->StatRxRuntCts);
+			seq_printf(seq, "   buffer overflow             %Lu\n",
+				      (unsigned long long) pPnmiStat->StatRxFifoOverflowCts);
+			seq_printf(seq, "   bad crc                     %Lu\n",
+				      (unsigned long long) pPnmiStat->StatRxFcsCts);
+			seq_printf(seq, "   framing                     %Lu\n",
+				      (unsigned long long) pPnmiStat->StatRxFramingCts);
+			seq_printf(seq, "   missed frames               %Lu\n",
+				      (unsigned long long) pPnmiStat->StatRxMissedCts);
+
+			if (dev->mtu > 1500)
+				pPnmiStat->StatRxTooLongCts = 0;
+
+			seq_printf(seq, "   too long                    %Lu\n",
+				      (unsigned long long) pPnmiStat->StatRxTooLongCts);					
+			seq_printf(seq, "   carrier extension           %Lu\n",
+				      (unsigned long long) pPnmiStat->StatRxCextCts);				
+			seq_printf(seq, "   too short                   %Lu\n",
+				      (unsigned long long) pPnmiStat->StatRxShortsCts);				
+			seq_printf(seq, "   symbol                      %Lu\n",
+				      (unsigned long long) pPnmiStat->StatRxSymbolCts);				
+			seq_printf(seq, "   LLC MAC size                %Lu\n",
+				      (unsigned long long) pPnmiStat->StatRxIRLengthCts);				
+			seq_printf(seq, "   carrier event               %Lu\n",
+				      (unsigned long long) pPnmiStat->StatRxCarrierCts);				
+			seq_printf(seq, "   jabber                      %Lu\n",
+				      (unsigned long long) pPnmiStat->StatRxJabberCts);				
+
+
+			/*Transmit statistics */
+			seq_printf(seq, "\nTransmit statistics\n\n");
 				
-				len += sk_proc_print(buffer,
-					"Transmited bytes               %Lu\n",
-					(unsigned long long) pPnmiStat->StatTxOctetsOkCts);
-				len += sk_proc_print(buffer,
-					"Transmited packets             %Lu\n",
-					(unsigned long long) pPnmiStat->StatTxOkCts);
-				len += sk_proc_print(buffer,
-					"Transmit errors                %Lu\n",
-					(unsigned long long) pPnmiStat->StatTxSingleCollisionCts);
-				len += sk_proc_print(buffer,
-					"Transmit dropped               %Lu\n",
-					(unsigned long long) pPnmiStruct->TxNoBufCts);
-				len += sk_proc_print(buffer,
-					"Transmit collisions            %Lu\n",
-					(unsigned long long) pPnmiStat->StatTxSingleCollisionCts);
-				len += sk_proc_print(buffer,
-					"Transmit error types\n");
-				len += sk_proc_print(buffer,
-					"   excessive collision         %ld\n",
-					pAC->stats.tx_aborted_errors);
-				len += sk_proc_print(buffer,
-					"   carrier                     %Lu\n",
-					(unsigned long long) pPnmiStat->StatTxCarrierCts);
-				len += sk_proc_print(buffer,
-					"   fifo underrun               %Lu\n",
-					(unsigned long long) pPnmiStat->StatTxFifoUnderrunCts);
-				len += sk_proc_print(buffer,
-					"   heartbeat                   %Lu\n",
-					(unsigned long long) pPnmiStat->StatTxCarrierCts);
-				len += sk_proc_print(buffer,
-					"   window                      %ld\n",
-					pAC->stats.tx_window_errors);
+			seq_printf(seq, "Transmited bytes               %Lu\n",
+				      (unsigned long long) pPnmiStat->StatTxOctetsOkCts);
+			seq_printf(seq, "Transmited packets             %Lu\n",
+				      (unsigned long long) pPnmiStat->StatTxOkCts);
+			seq_printf(seq, "Transmit errors                %Lu\n",
+				      (unsigned long long) pPnmiStat->StatTxSingleCollisionCts);
+			seq_printf(seq, "Transmit dropped               %Lu\n",
+				      (unsigned long long) pPnmiStruct->TxNoBufCts);
+			seq_printf(seq, "Transmit collisions            %Lu\n",
+				      (unsigned long long) pPnmiStat->StatTxSingleCollisionCts);
+			seq_printf(seq, "Transmit error types\n");
+			seq_printf(seq, "   excessive collision         %ld\n",
+				      pAC->stats.tx_aborted_errors);
+			seq_printf(seq, "   carrier                     %Lu\n",
+				      (unsigned long long) pPnmiStat->StatTxCarrierCts);
+			seq_printf(seq, "   fifo underrun               %Lu\n",
+				      (unsigned long long) pPnmiStat->StatTxFifoUnderrunCts);
+			seq_printf(seq, "   heartbeat                   %Lu\n",
+				      (unsigned long long) pPnmiStat->StatTxCarrierCts);
+			seq_printf(seq, "   window                      %ld\n",
+				      pAC->stats.tx_window_errors);
 				
-			} /* if (strcmp(pACname, currDeviceName) == 0) */
 		}
-		SkgeProcDev = next;
 	}
-}
-
-/*****************************************************************************
- *
- *      sk_proc_print -generic line print  
- *
- * Description:
- *  This function fills the proc entry with statistic data about 
- *  the ethernet device.
- *  
- * Returns: number of bytes written
- *      
- */ 
-static int sk_proc_print(void *writePtr, char *format, ...)
-{   
-#define MAX_LEN_SINGLE_LINE 256
-	char     str[MAX_LEN_SINGLE_LINE];
-	va_list  a_start;
-	int      lenght = 0;
-
-	struct seq_file *seq = (struct seq_file *) writePtr;
-
-	SK_MEMSET(str, 0, MAX_LEN_SINGLE_LINE);
-
-	va_start(a_start, format);
-	vsprintf(str, format, a_start);
-	va_end(a_start);
-
-	lenght = strlen(str);
-
-	seq_printf(seq, str);
-	return lenght;
-}
-
-/*****************************************************************************
- *
- *      sk_seq_show - show proc information of a particular adapter
- *
- * Description:
- *  This function fills the proc entry with statistic data about 
- *  the ethernet device. It invokes the generic sk_gen_browse() to
- *  print out all items one per one.
- *  
- * Returns: number of bytes written
- *      
- */
-static int sk_seq_show(struct seq_file *seq, void *v)
-{
-    void *castedBuffer = (void *) seq;
-    currDev = seq->private;
-    sk_gen_browse(castedBuffer);
-    return 0;
+	return 0;
 }
 
 /*****************************************************************************
diff -Nru a/drivers/net/sk_g16.c b/drivers/net/sk_g16.c
--- a/drivers/net/sk_g16.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/net/sk_g16.c	2005-03-01 23:39:18 -08:00
@@ -457,7 +457,7 @@
 /* static variables */
 
 static SK_RAM *board;  /* pointer to our memory mapped board components */
-static spinlock_t SK_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(SK_lock);
 
 /* Macros */
 
diff -Nru a/drivers/net/skfp/h/fplustm.h b/drivers/net/skfp/h/fplustm.h
--- a/drivers/net/skfp/h/fplustm.h	2005-03-01 23:38:52 -08:00
+++ b/drivers/net/skfp/h/fplustm.h	2005-03-01 23:38:52 -08:00
@@ -21,11 +21,7 @@
 #define _FPLUS_
 
 #ifndef	HW_PTR
-#ifdef	MEM_MAPPED_IO
-#define	HW_PTR	u_long
-#else
-#define	HW_PTR	u_short
-#endif
+#define	HW_PTR	void __iomem *
 #endif
 
 /*
diff -Nru a/drivers/net/skfp/h/targethw.h b/drivers/net/skfp/h/targethw.h
--- a/drivers/net/skfp/h/targethw.h	2005-03-01 23:39:09 -08:00
+++ b/drivers/net/skfp/h/targethw.h	2005-03-01 23:39:09 -08:00
@@ -33,11 +33,7 @@
 #endif
 
 #ifndef	HW_PTR
-#ifdef  MEM_MAPPED_IO
-#define HW_PTR  u_long
-#else
-#define HW_PTR  u_short
-#endif
+#define HW_PTR  void __iomem *
 #endif
 
 #ifdef MULT_OEM
diff -Nru a/drivers/net/skfp/h/targetos.h b/drivers/net/skfp/h/targetos.h
--- a/drivers/net/skfp/h/targetos.h	2005-03-01 23:38:54 -08:00
+++ b/drivers/net/skfp/h/targetos.h	2005-03-01 23:38:54 -08:00
@@ -53,7 +53,7 @@
 // is redefined by linux, but we need our definition
 #undef ADDR
 #ifdef MEM_MAPPED_IO
-#define	ADDR(a) (char far *) smc->hw.iop+(a)
+#define	ADDR(a) (smc->hw.iop+(a))
 #else
 #define	ADDR(a) (((a)>>7) ? (outp(smc->hw.iop+B0_RAP,(a)>>7), (smc->hw.iop+( ((a)&0x7F) | ((a)>>7 ? 0x80:0)) )) : (smc->hw.iop+(((a)&0x7F)|((a)>>7 ? 0x80:0))))
 #endif
diff -Nru a/drivers/net/skfp/h/types.h b/drivers/net/skfp/h/types.h
--- a/drivers/net/skfp/h/types.h	2005-03-01 23:38:58 -08:00
+++ b/drivers/net/skfp/h/types.h	2005-03-01 23:38:58 -08:00
@@ -29,20 +29,11 @@
 #define _far
 #endif
 
-#ifndef MEM_MAPPED_IO // "normal" IO
-#define inp(p)  inb(p)
-#define inpw(p)	inw(p)
-#define inpd(p) inl(p)
-#define outp(p,c)  outb(c,p)
-#define outpw(p,s) outw(s,p)
-#define outpd(p,l) outl(l,p)
-#else // memory mapped io
-#define inp(a)		readb(a)
-#define inpw(a)		readw(a)
-#define inpd(a)		readl(a)
-#define outp(a,v)	writeb(v, a)	
-#define outpw(a,v)	writew(v, a)	
-#define outpd(a,v)	writel(v, a)	
-#endif
+#define inp(p)  ioread8(p)
+#define inpw(p)	ioread16(p)
+#define inpd(p) ioread32(p)
+#define outp(p,c)  iowrite8(c,p)
+#define outpw(p,s) iowrite16(s,p)
+#define outpd(p,l) iowrite32(l,p)
 
 #endif	/* _TYPES_ */
diff -Nru a/drivers/net/skfp/skfddi.c b/drivers/net/skfp/skfddi.c
--- a/drivers/net/skfp/skfddi.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/net/skfp/skfddi.c	2005-03-01 23:38:52 -08:00
@@ -169,8 +169,6 @@
 #define PRINTK(s, args...)
 #endif				// DRIVERDEBUG
 
-#define PRIV(dev) (&(((struct s_smc *)dev->priv)->os))
-
 /*
  * =================
  * = skfp_init_one =
@@ -205,7 +203,7 @@
 {
 	struct net_device *dev;
 	struct s_smc *smc;	/* board pointer */
-	unsigned long port, len;
+	void __iomem *mem;
 	int err;
 
 	PRINTK(KERN_INFO "entering skfp_init_one\n");
@@ -215,64 +213,45 @@
 
 	err = pci_enable_device(pdev);
 	if (err)
+		return err;
+
+	err = pci_request_regions(pdev, "skfddi");
+	if (err)
 		goto err_out1;
 
+	pci_set_master(pdev);
 
 #ifdef MEM_MAPPED_IO
 	if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
 		printk(KERN_ERR "skfp: region is not an MMIO resource\n");
 		err = -EIO;
-		goto err_out1;
+		goto err_out2;
 	}
-	port = pci_resource_start(pdev, 0);
-	len = pci_resource_len(pdev, 0);
 
-	if (len < 0x4000) {
-		printk(KERN_ERR "skfp: Invalid PCI region size: %lu\n", len);
-		err = -EIO;
-		goto err_out1;
-	}
+	mem = ioremap(pci_resource_start(pdev, 0), 0x4000);
 #else
 	if (!(pci_resource_flags(pdev, 1) & IO_RESOURCE_IO)) {
 		printk(KERN_ERR "skfp: region is not PIO resource\n");
 		err = -EIO;
-		goto err_out1;
+		goto err_out2;
 	}
 
-	port = pci_resource_start(pdev, 1);
-	len = pci_resource_len(pdev, 1);
-	if (len < FP_IO_LEN) {
-		printk(KERN_ERR "skfp: Invalid PCI region size: %d\n",
-		       io_len);
+	mem = ioport_map(pci_resource_start(pdev, 1), FP_IO_LEN);
+#endif
+	if (!mem) {
+		printk(KERN_ERR "skfp:  Unable to map register, "
+				"FDDI adapter will be disabled.\n");
 		err = -EIO;
-		goto err_out1;
+		goto err_out2;
 	}
-#endif
-	err = pci_request_regions(pdev, "skfddi");
-	if (err)
-		goto err_out1;
-
-	pci_set_master(pdev);
 
 	dev = alloc_fddidev(sizeof(struct s_smc));
 	if (!dev) {
 		printk(KERN_ERR "skfp: Unable to allocate fddi device, "
 				"FDDI adapter will be disabled.\n");
 		err = -ENOMEM;
-		goto err_out2;
-	}
-
-#ifdef MEM_MAPPED_IO
-	dev->base_addr = (unsigned long) ioremap(port, len);
-	if (!dev->base_addr) {
-		printk(KERN_ERR "skfp:  Unable to map MEMORY register, "
-				"FDDI adapter will be disabled.\n");
-		err = -EIO;
 		goto err_out3;
 	}
-#else
-	dev->base_addr = port;
-#endif
 
 	dev->irq = pdev->irq;
 	dev->get_stats = &skfp_ctl_get_stats;
@@ -288,7 +267,7 @@
 	SET_NETDEV_DEV(dev, &pdev->dev);
 
 	/* Initialize board structure with bus-specific info */
-	smc = (struct s_smc *) dev->priv;
+	smc = netdev_priv(dev);
 	smc->os.dev = dev;
 	smc->os.bus_type = SK_BUS_TYPE_PCI;
 	smc->os.pdev = *pdev;
@@ -296,9 +275,12 @@
 	smc->os.MaxFrameSize = MAX_FRAME_SIZE;
 	smc->os.dev = dev;
 	smc->hw.slot = -1;
+	smc->hw.iop = mem;
 	smc->os.ResetRequested = FALSE;
 	skb_queue_head_init(&smc->os.SendSkbQueue);
 
+	dev->base_addr = (unsigned long)mem;
+
 	err = skfp_driver_init(dev);
 	if (err)
 		goto err_out4;
@@ -327,14 +309,17 @@
 	pci_free_consistent(pdev, MAX_FRAME_SIZE,
 			    smc->os.LocalRxBuffer, smc->os.LocalRxBufferDMA);
 err_out4:
+	free_netdev(dev);
+err_out3:
 #ifdef MEM_MAPPED_IO
-	iounmap((void *) dev->base_addr);
+	iounmap(mem);
+#else
+	ioport_unmap(mem);
 #endif
-err_out3:
-	free_netdev(dev);
 err_out2:
 	pci_release_regions(pdev);
 err_out1:
+	pci_disable_device(pdev);
 	return err;
 }
 
@@ -344,7 +329,7 @@
 static void __devexit skfp_remove_one(struct pci_dev *pdev)
 {
 	struct net_device *p = pci_get_drvdata(pdev);
-	struct s_smc *lp = p->priv;
+	struct s_smc *lp = netdev_priv(p);
 
 	unregister_netdev(p);
 
@@ -363,11 +348,14 @@
 		lp->os.LocalRxBuffer = NULL;
 	}
 #ifdef MEM_MAPPED_IO
-	iounmap((void *) p->base_addr);
+	iounmap(lp->hw.iop);
+#else
+	ioport_unmap(lp->hw.iop);
 #endif
 	pci_release_regions(pdev);
 	free_netdev(p);
 
+	pci_disable_device(pdev);
 	pci_set_drvdata(pdev, NULL);
 }
 
@@ -398,15 +386,14 @@
  */
 static  int skfp_driver_init(struct net_device *dev)
 {
-	struct s_smc *smc = (struct s_smc *) dev->priv;
-	skfddi_priv *bp = PRIV(dev);
+	struct s_smc *smc = netdev_priv(dev);
+	skfddi_priv *bp = &smc->os;
 	int err = -EIO;
 
 	PRINTK(KERN_INFO "entering skfp_driver_init\n");
 
 	// set the io address in private structures
 	bp->base_addr = dev->base_addr;
-	smc->hw.iop = dev->base_addr;
 
 	// Get the interrupt level from the PCI Configuration Table
 	smc->hw.irq = dev->irq;
@@ -506,7 +493,7 @@
  */
 static int skfp_open(struct net_device *dev)
 {
-	struct s_smc *smc = (struct s_smc *) dev->priv;
+	struct s_smc *smc = netdev_priv(dev);
 	int err;
 
 	PRINTK(KERN_INFO "entering skfp_open\n");
@@ -573,8 +560,8 @@
  */
 static int skfp_close(struct net_device *dev)
 {
-	struct s_smc *smc = (struct s_smc *) dev->priv;
-	skfddi_priv *bp = PRIV(dev);
+	struct s_smc *smc = netdev_priv(dev);
+	skfddi_priv *bp = &smc->os;
 
 	CLI_FBI();
 	smt_reset_defaults(smc, 1);
@@ -633,15 +620,15 @@
 {
 	struct net_device *dev = (struct net_device *) dev_id;
 	struct s_smc *smc;	/* private board structure pointer */
-	skfddi_priv *bp = PRIV(dev);
-
+	skfddi_priv *bp;
 
 	if (dev == NULL) {
 		printk("%s: irq %d for unknown device\n", dev->name, irq);
 		return IRQ_NONE;
 	}
 
-	smc = (struct s_smc *) dev->priv;
+	smc = netdev_priv(dev);
+	bp = &smc->os;
 
 	// IRQs enabled or disabled ?
 	if (inpd(ADDR(B0_IMSK)) == 0) {
@@ -703,7 +690,7 @@
  */
 struct net_device_stats *skfp_ctl_get_stats(struct net_device *dev)
 {
-	struct s_smc *bp = (struct s_smc *) dev->priv;
+	struct s_smc *bp = netdev_priv(dev);
 
 	/* Fill the bp->stats structure with driver-maintained counters */
 
@@ -867,7 +854,8 @@
  */
 static void skfp_ctl_set_multicast_list(struct net_device *dev)
 {
-	skfddi_priv *bp = PRIV(dev);
+	struct s_smc *smc = netdev_priv(dev);
+	skfddi_priv *bp = &smc->os;
 	unsigned long Flags;
 
 	spin_lock_irqsave(&bp->DriverLock, Flags);
@@ -880,7 +868,7 @@
 
 static void skfp_ctl_set_multicast_list_wo_lock(struct net_device *dev)
 {
-	struct s_smc *smc = (struct s_smc *) dev->priv;
+	struct s_smc *smc = netdev_priv(dev);
 	struct dev_mc_list *dmi;	/* ptr to multicast addr entry */
 	int i;
 
@@ -963,9 +951,9 @@
  */
 static int skfp_ctl_set_mac_address(struct net_device *dev, void *addr)
 {
-	struct s_smc *smc = (struct s_smc *) dev->priv;
+	struct s_smc *smc = netdev_priv(dev);
 	struct sockaddr *p_sockaddr = (struct sockaddr *) addr;
-	skfddi_priv *bp = (skfddi_priv *) & smc->os;
+	skfddi_priv *bp = &smc->os;
 	unsigned long Flags;
 
 
@@ -1003,12 +991,14 @@
 
 static int skfp_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
-	skfddi_priv *lp = PRIV(dev);
+	struct s_smc *smc = netdev_priv(dev);
+	skfddi_priv *lp = &smc->os;
 	struct s_skfp_ioctl ioc;
 	int status = 0;
 
 	if (copy_from_user(&ioc, rq->ifr_data, sizeof(struct s_skfp_ioctl)))
 		return -EFAULT;
+
 	switch (ioc.cmd) {
 	case SKFP_GET_STATS:	/* Get the driver statistics */
 		ioc.len = sizeof(lp->MacStat);
@@ -1081,7 +1071,8 @@
  */
 static int skfp_send_pkt(struct sk_buff *skb, struct net_device *dev)
 {
-	skfddi_priv *bp = PRIV(dev);
+	struct s_smc *smc = netdev_priv(dev);
+	skfddi_priv *bp = &smc->os;
 
 	PRINTK(KERN_INFO "skfp_send_pkt\n");
 
@@ -1108,7 +1099,7 @@
 	}
 	bp->QueueSkb--;
 	skb_queue_tail(&bp->SendSkbQueue, skb);
-	send_queued_packets((struct s_smc *) dev->priv);
+	send_queued_packets(netdev_priv(dev));
 	if (bp->QueueSkb == 0) {
 		netif_stop_queue(dev);
 	}
@@ -1143,7 +1134,7 @@
  */
 static void send_queued_packets(struct s_smc *smc)
 {
-	skfddi_priv *bp = (skfddi_priv *) & smc->os;
+	skfddi_priv *bp = &smc->os;
 	struct sk_buff *skb;
 	unsigned char fc;
 	int queue;
@@ -1315,7 +1306,7 @@
  ************************/
 void llc_restart_tx(struct s_smc *smc)
 {
-	skfddi_priv *bp = (skfddi_priv *) & smc->os;
+	skfddi_priv *bp = &smc->os;
 
 	PRINTK(KERN_INFO "[llc_restart_tx]\n");
 
@@ -1499,7 +1490,7 @@
 	 * unmap first, the hardware module could read inconsistent data.
 	 */
 	if (flag & DMA_WR) {
-		skfddi_priv *bp = (skfddi_priv *) & smc->os;
+		skfddi_priv *bp = &smc->os;
 		volatile struct s_smt_fp_rxd *r = &descr->r;
 
 		/* If SKB is NULL, we used the local buffer. */
@@ -1613,7 +1604,7 @@
 void mac_drv_rx_complete(struct s_smc *smc, volatile struct s_smt_fp_rxd *rxd,
 			 int frag_count, int len)
 {
-	skfddi_priv *bp = (skfddi_priv *) & smc->os;
+	skfddi_priv *bp = &smc->os;
 	struct sk_buff *skb;
 	unsigned char *virt, *cp;
 	unsigned short ri;
@@ -1745,7 +1736,7 @@
 
 		printk("fddi: Multi-fragment requeue!\n");
 
-	MaxFrameSize = ((skfddi_priv *) & smc->os)->MaxFrameSize;
+	MaxFrameSize = smc->os.MaxFrameSize;
 	src_rxd = rxd;
 	for (; frag_count > 0; frag_count--) {
 		next_rxd = src_rxd->rxd_next;
@@ -1821,7 +1812,7 @@
 	// Walk through the list of free receive buffers, passing receive
 	// buffers to the HWM as long as RXDs are available.
 
-	MaxFrameSize = ((skfddi_priv *) & smc->os)->MaxFrameSize;
+	MaxFrameSize = smc->os.MaxFrameSize;
 	// Check if there is any RXD left.
 	while (HWM_GET_RX_FREE(smc) > 0) {
 		PRINTK(KERN_INFO ".\n");
@@ -1890,7 +1881,7 @@
 	for (; frag_count > 0; frag_count--) {
 		skb = rxd->rxd_os.skb;
 		if (skb != NULL) {
-			skfddi_priv *bp = (skfddi_priv *) & smc->os;
+			skfddi_priv *bp = &smc->os;
 			int MaxFrameSize = bp->MaxFrameSize;
 
 			pci_unmap_single(&bp->pdev, rxd->rxd_os.dma_addr,
@@ -1957,7 +1948,7 @@
 	memcpy(skb->data, look_ahead, len);
 
 	// deliver frame to system
-	skb->protocol = fddi_type_trans(skb, ((skfddi_priv *) & smc->os)->dev);
+	skb->protocol = fddi_type_trans(skb, smc->os.dev);
 	skb->dev->last_rx = jiffies;
 	netif_rx(skb);
 
diff -Nru a/drivers/net/skfp/smt.c b/drivers/net/skfp/smt.c
--- a/drivers/net/skfp/smt.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/net/skfp/smt.c	2005-03-01 23:39:09 -08:00
@@ -135,13 +135,6 @@
 		*(short *)(&smc->mib.m[MAC0].fddiMACSMTAddress.a[4])) ;
 }
 
-static inline int is_zero(const struct fddi_addr *addr)
-{
-	return(*(short *)(&addr->a[0]) == 0 &&
-	       *(short *)(&addr->a[2]) == 0 &&
-	       *(short *)(&addr->a[4]) == 0 ) ;
-}
-
 static inline int is_broadcast(const struct fddi_addr *addr)
 {
 	return(*(u_short *)(&addr->a[0]) == 0xffff &&
diff -Nru a/drivers/net/smc-mca.c b/drivers/net/smc-mca.c
--- a/drivers/net/smc-mca.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/net/smc-mca.c	2005-03-01 23:38:52 -08:00
@@ -95,8 +95,8 @@
 static int ultra_irq[MAX_ULTRAMCA_CARDS];
 MODULE_LICENSE("GPL");
 
-MODULE_PARM(ultra_io, "1-" __MODULE_STRING(MAX_ULTRAMCA_CARDS) "i");
-MODULE_PARM(ultra_irq, "1-" __MODULE_STRING(MAX_ULTRAMCA_CARDS) "i");
+module_param_array(ultra_io, int, NULL, 0);
+module_param_array(ultra_irq, int, NULL, 0);
 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)");
 
diff -Nru a/drivers/net/smc-ultra.c b/drivers/net/smc-ultra.c
--- a/drivers/net/smc-ultra.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/net/smc-ultra.c	2005-03-01 23:38:53 -08:00
@@ -156,8 +156,6 @@
 	/* Look for any installed ISAPnP cards */
 	if (isapnp_present() && (ultra_probe_isapnp(dev) == 0))
 		return 0;
-
-	printk(KERN_NOTICE "smc-ultra.c: No ISAPnP cards found, trying standard ones...\n");
 #endif
 
 	for (i = 0; ultra_portlist[i]; i++) {
@@ -553,8 +551,8 @@
 static int io[MAX_ULTRA_CARDS];
 static int irq[MAX_ULTRA_CARDS];
 
-MODULE_PARM(io, "1-" __MODULE_STRING(MAX_ULTRA_CARDS) "i");
-MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_ULTRA_CARDS) "i");
+module_param_array(io, int, NULL, 0);
+module_param_array(irq, int, NULL, 0);
 MODULE_PARM_DESC(io, "I/O base address(es)");
 MODULE_PARM_DESC(irq, "IRQ number(s) (assigned)");
 MODULE_DESCRIPTION("SMC Ultra/EtherEZ ISA/PnP Ethernet driver");
diff -Nru a/drivers/net/smc9194.c b/drivers/net/smc9194.c
--- a/drivers/net/smc9194.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/net/smc9194.c	2005-03-01 23:39:08 -08:00
@@ -1600,9 +1600,9 @@
 static struct net_device *devSMC9194;
 MODULE_LICENSE("GPL");
 
-MODULE_PARM(io, "i");
-MODULE_PARM(irq, "i");
-MODULE_PARM(ifport, "i");
+module_param(io, int, 0);
+module_param(irq, int, 0);
+module_param(ifport, int, 0);
 MODULE_PARM_DESC(io, "SMC 99194 I/O base address");
 MODULE_PARM_DESC(irq, "SMC 99194 IRQ number");
 MODULE_PARM_DESC(ifport, "SMC 99194 interface port (0-default, 1-TP, 2-AUI)");
diff -Nru a/drivers/net/smc91x.c b/drivers/net/smc91x.c
--- a/drivers/net/smc91x.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/net/smc91x.c	2005-03-01 23:39:17 -08:00
@@ -1333,6 +1333,19 @@
 	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 smc_poll_controller(struct net_device *dev)
+{
+	disable_irq(dev->irq);
+	smc_interrupt(dev->irq, dev, NULL);
+	enable_irq(dev->irq);
+}
+#endif
+
 /* Our watchdog timed out. Called by the networking layer */
 static void smc_timeout(struct net_device *dev)
 {
@@ -1912,6 +1925,9 @@
 	dev->get_stats = smc_query_statistics;
 	dev->set_multicast_list = smc_set_multicast_list;
 	dev->ethtool_ops = &smc_ethtool_ops;
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	dev->poll_controller = smc_poll_controller;
+#endif
 
 	tasklet_init(&lp->tx_task, smc_hardware_send_pkt, (unsigned long)dev);
 	INIT_WORK(&lp->phy_configure, smc_phy_configure, dev);
diff -Nru a/drivers/net/starfire.c b/drivers/net/starfire.c
--- a/drivers/net/starfire.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/net/starfire.c	2005-03-01 23:39:18 -08:00
@@ -372,15 +372,15 @@
 MODULE_DESCRIPTION("Adaptec Starfire Ethernet driver");
 MODULE_LICENSE("GPL");
 
-MODULE_PARM(max_interrupt_work, "i");
-MODULE_PARM(mtu, "i");
-MODULE_PARM(debug, "i");
-MODULE_PARM(rx_copybreak, "i");
-MODULE_PARM(intr_latency, "i");
-MODULE_PARM(small_frames, "i");
-MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i");
-MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
-MODULE_PARM(enable_hw_cksum, "i");
+module_param(max_interrupt_work, int, 0);
+module_param(mtu, int, 0);
+module_param(debug, int, 0);
+module_param(rx_copybreak, int, 0);
+module_param(intr_latency, int, 0);
+module_param(small_frames, int, 0);
+module_param_array(options, int, NULL, 0);
+module_param_array(full_duplex, int, NULL, 0);
+module_param(enable_hw_cksum, int, 0);
 MODULE_PARM_DESC(max_interrupt_work, "Maximum events handled per interrupt");
 MODULE_PARM_DESC(mtu, "MTU (all boards)");
 MODULE_PARM_DESC(debug, "Debug level (0-6)");
@@ -776,6 +776,7 @@
 	struct mii_if_info mii_if;		/* MII lib hooks/info */
 	int phy_cnt;			/* MII device addresses. */
 	unsigned char phys[PHY_CNT];	/* MII device addresses. */
+	void __iomem *base;
 };
 
 
@@ -846,6 +847,7 @@
 	struct net_device *dev;
 	static int card_idx = -1;
 	long ioaddr;
+	void __iomem *base;
 	int drv_flags, io_size;
 	int boguscnt;
 
@@ -884,14 +886,12 @@
 	}
 
 	/* ioremap is borken in Linux-2.2.x/sparc64 */
-#if !defined(CONFIG_SPARC64) || LINUX_VERSION_CODE > 0x20300
-	ioaddr = (long) ioremap(ioaddr, io_size);
-	if (!ioaddr) {
+	base = ioremap(ioaddr, io_size);
+	if (!base) {
 		printk(KERN_ERR DRV_NAME " %d: cannot remap %#x @ %#lx, aborting\n",
 			card_idx, io_size, ioaddr);
 		goto err_out_free_res;
 	}
-#endif /* !CONFIG_SPARC64 || Linux 2.3.0+ */
 
 	pci_set_master(pdev);
 
@@ -918,27 +918,27 @@
 
 	/* Serial EEPROM reads are hidden by the hardware. */
 	for (i = 0; i < 6; i++)
-		dev->dev_addr[i] = readb(ioaddr + EEPROMCtrl + 20 - i);
+		dev->dev_addr[i] = readb(base + EEPROMCtrl + 20 - i);
 
 #if ! defined(final_version) /* Dump the EEPROM contents during development. */
 	if (debug > 4)
 		for (i = 0; i < 0x20; i++)
 			printk("%2.2x%s",
-			       (unsigned int)readb(ioaddr + EEPROMCtrl + i),
+			       (unsigned int)readb(base + EEPROMCtrl + i),
 			       i % 16 != 15 ? " " : "\n");
 #endif
 
 	/* Issue soft reset */
-	writel(MiiSoftReset, ioaddr + TxMode);
+	writel(MiiSoftReset, base + TxMode);
 	udelay(1000);
-	writel(0, ioaddr + TxMode);
+	writel(0, base + TxMode);
 
 	/* Reset the chip to erase previous misconfiguration. */
-	writel(1, ioaddr + PCIDeviceConfig);
+	writel(1, base + PCIDeviceConfig);
 	boguscnt = 1000;
 	while (--boguscnt > 0) {
 		udelay(10);
-		if ((readl(ioaddr + PCIDeviceConfig) & 1) == 0)
+		if ((readl(base + PCIDeviceConfig) & 1) == 0)
 			break;
 	}
 	if (boguscnt == 0)
@@ -946,10 +946,11 @@
 	/* wait a little longer */
 	udelay(1000);
 
-	dev->base_addr = ioaddr;
+	dev->base_addr = (unsigned long)base;
 	dev->irq = irq;
 
 	np = netdev_priv(dev);
+	np->base = base;
 	spin_lock_init(&np->lock);
 	pci_set_drvdata(pdev, dev);
 
@@ -1021,8 +1022,8 @@
 	if (register_netdev(dev))
 		goto err_out_cleardev;
 
-	printk(KERN_INFO "%s: %s at %#lx, ",
-		   dev->name, netdrv_tbl[chip_idx].name, ioaddr);
+	printk(KERN_INFO "%s: %s at %p, ",
+		   dev->name, netdrv_tbl[chip_idx].name, base);
 	for (i = 0; i < 5; i++)
 		printk("%2.2x:", dev->dev_addr[i]);
 	printk("%2.2x, IRQ %d.\n", dev->dev_addr[i], irq);
@@ -1065,7 +1066,7 @@
 
 err_out_cleardev:
 	pci_set_drvdata(pdev, NULL);
-	iounmap((void *)ioaddr);
+	iounmap(base);
 err_out_free_res:
 	pci_release_regions (pdev);
 err_out_free_netdev:
@@ -1077,7 +1078,8 @@
 /* Read the MII Management Data I/O (MDIO) interfaces. */
 static int mdio_read(struct net_device *dev, int phy_id, int location)
 {
-	long mdio_addr = dev->base_addr + MIICtrl + (phy_id<<7) + (location<<2);
+	struct netdev_private *np = netdev_priv(dev);
+	void __iomem *mdio_addr = np->base + MIICtrl + (phy_id<<7) + (location<<2);
 	int result, boguscnt=1000;
 	/* ??? Should we add a busy-wait here? */
 	do
@@ -1093,7 +1095,8 @@
 
 static void mdio_write(struct net_device *dev, int phy_id, int location, int value)
 {
-	long mdio_addr = dev->base_addr + MIICtrl + (phy_id<<7) + (location<<2);
+	struct netdev_private *np = netdev_priv(dev);
+	void __iomem *mdio_addr = np->base + MIICtrl + (phy_id<<7) + (location<<2);
 	writel(value, mdio_addr);
 	/* The busy-wait will occur before a read. */
 }
@@ -1102,7 +1105,7 @@
 static int netdev_open(struct net_device *dev)
 {
 	struct netdev_private *np = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = np->base;
 	int i, retval;
 	size_t tx_done_q_size, rx_done_q_size, tx_ring_size, rx_ring_size;
 
@@ -1191,7 +1194,7 @@
 	writew(0, ioaddr + PerfFilterTable + 8);
 	for (i = 1; i < 16; i++) {
 		u16 *eaddrs = (u16 *)dev->dev_addr;
-		long setup_frm = ioaddr + PerfFilterTable + i * 16;
+		void __iomem *setup_frm = ioaddr + PerfFilterTable + i * 16;
 		writew(cpu_to_be16(eaddrs[2]), setup_frm); setup_frm += 4;
 		writew(cpu_to_be16(eaddrs[1]), setup_frm); setup_frm += 4;
 		writew(cpu_to_be16(eaddrs[0]), setup_frm); setup_frm += 8;
@@ -1295,7 +1298,7 @@
 static void tx_timeout(struct net_device *dev)
 {
 	struct netdev_private *np = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = np->base;
 	int old_debug;
 
 	printk(KERN_WARNING "%s: Transmit timed out, status %#8.8x, "
@@ -1343,7 +1346,7 @@
 		/* Grrr, we cannot offset to correctly align the IP header. */
 		np->rx_ring[i].rxaddr = cpu_to_dma(np->rx_info[i].mapping | RxDescValid);
 	}
-	writew(i - 1, dev->base_addr + RxDescQIdx);
+	writew(i - 1, np->base + RxDescQIdx);
 	np->dirty_rx = (unsigned int)(i - RX_RING_SIZE);
 
 	/* Clear the remainder of the Rx buffer ring. */
@@ -1464,7 +1467,7 @@
 	wmb();
 
 	/* Update the producer index. */
-	writel(entry * (sizeof(starfire_tx_desc) / 8), dev->base_addr + TxProducerIdx);
+	writel(entry * (sizeof(starfire_tx_desc) / 8), np->base + TxProducerIdx);
 
 	/* 4 is arbitrary, but should be ok */
 	if ((np->cur_tx - np->dirty_tx) + 4 > TX_RING_SIZE)
@@ -1481,16 +1484,13 @@
 static irqreturn_t intr_handler(int irq, void *dev_instance, struct pt_regs *rgs)
 {
 	struct net_device *dev = dev_instance;
-	struct netdev_private *np;
-	long ioaddr;
+	struct netdev_private *np = netdev_priv(dev);
+	void __iomem *ioaddr = np->base;
 	int boguscnt = max_interrupt_work;
 	int consumer;
 	int tx_status;
 	int handled = 0;
 
-	ioaddr = dev->base_addr;
-	np = netdev_priv(dev);
-
 	do {
 		u32 intr_status = readl(ioaddr + IntrClear);
 
@@ -1697,7 +1697,7 @@
 		desc->status = 0;
 		np->rx_done = (np->rx_done + 1) % DONE_Q_SIZE;
 	}
-	writew(np->rx_done, dev->base_addr + CompletionQConsumerIdx);
+	writew(np->rx_done, np->base + CompletionQConsumerIdx);
 
  out:
 	refill_rx_ring(dev);
@@ -1712,7 +1712,8 @@
 static int netdev_poll(struct net_device *dev, int *budget)
 {
 	u32 intr_status;
-	long ioaddr = dev->base_addr;
+	struct netdev_private *np = netdev_priv(dev);
+	void __iomem *ioaddr = np->base;
 	int retcode = 0, quota = dev->quota;
 
 	do {
@@ -1766,14 +1767,14 @@
 			np->rx_ring[entry].rxaddr |= cpu_to_dma(RxDescEndRing);
 	}
 	if (entry >= 0)
-		writew(entry, dev->base_addr + RxDescQIdx);
+		writew(entry, np->base + RxDescQIdx);
 }
 
 
 static void netdev_media_change(struct net_device *dev)
 {
 	struct netdev_private *np = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = np->base;
 	u16 reg0, reg1, reg4, reg5;
 	u32 new_tx_mode;
 	u32 new_intr_timer_ctrl;
@@ -1852,7 +1853,7 @@
 	/* Came close to underrunning the Tx FIFO, increase threshold. */
 	if (intr_status & IntrTxDataLow) {
 		if (np->tx_threshold <= PKT_BUF_SZ / 16) {
-			writel(++np->tx_threshold, dev->base_addr + TxThreshold);
+			writel(++np->tx_threshold, np->base + TxThreshold);
 			printk(KERN_NOTICE "%s: PCI bus congestion, increasing Tx FIFO threshold to %d bytes\n",
 			       dev->name, np->tx_threshold * 16);
 		} else
@@ -1874,8 +1875,8 @@
 
 static struct net_device_stats *get_stats(struct net_device *dev)
 {
-	long ioaddr = dev->base_addr;
 	struct netdev_private *np = netdev_priv(dev);
+	void __iomem *ioaddr = np->base;
 
 	/* This adapter architecture needs no SMP locks. */
 	np->stats.tx_bytes = readl(ioaddr + 0x57010);
@@ -1904,17 +1905,17 @@
 */
 static void set_rx_mode(struct net_device *dev)
 {
-	long ioaddr = dev->base_addr;
+	struct netdev_private *np = netdev_priv(dev);
+	void __iomem *ioaddr = np->base;
 	u32 rx_mode = MinVLANPrio;
 	struct dev_mc_list *mclist;
 	int i;
 #ifdef VLAN_SUPPORT
-	struct netdev_private *np = netdev_priv(dev);
 
 	rx_mode |= VlanMode;
 	if (np->vlgrp) {
 		int vlan_count = 0;
-		long filter_addr = ioaddr + HashTable + 8;
+		void __iomem *filter_addr = ioaddr + HashTable + 8;
 		for (i = 0; i < VLAN_VID_MASK; i++) {
 			if (np->vlgrp->vlan_devices[i]) {
 				if (vlan_count >= 32)
@@ -1943,7 +1944,7 @@
 		rx_mode |= AcceptBroadcast|AcceptAllMulticast|PerfectFilter;
 	} else if (dev->mc_count <= 14) {
 		/* Use the 16 element perfect filter, skip first two entries. */
-		long filter_addr = ioaddr + PerfFilterTable + 2 * 16;
+		void __iomem *filter_addr = ioaddr + PerfFilterTable + 2 * 16;
 		u16 *eaddrs;
 		for (i = 2, mclist = dev->mc_list; mclist && i < dev->mc_count + 2;
 		     i++, mclist = mclist->next) {
@@ -1961,7 +1962,7 @@
 		rx_mode |= AcceptBroadcast|PerfectFilter;
 	} else {
 		/* Must use a multicast hash table. */
-		long filter_addr;
+		void __iomem *filter_addr;
 		u16 *eaddrs;
 		u16 mc_filter[32] __attribute__ ((aligned(sizeof(long))));	/* Multicast hash filter */
 
@@ -2077,8 +2078,8 @@
 
 static int netdev_close(struct net_device *dev)
 {
-	long ioaddr = dev->base_addr;
 	struct netdev_private *np = netdev_priv(dev);
+	void __iomem *ioaddr = np->base;
 	int i;
 
 	netif_stop_queue(dev);
@@ -2159,10 +2160,10 @@
 
 
 	/* XXX: add wakeup code -- requires firmware for MagicPacket */
-	pci_set_power_state(pdev, 3);	/* go to sleep in D3 mode */
+	pci_set_power_state(pdev, PCI_D3hot);	/* go to sleep in D3 mode */
 	pci_disable_device(pdev);
 
-	iounmap((char *)dev->base_addr);
+	iounmap(np->base);
 	pci_release_regions(pdev);
 
 	pci_set_drvdata(pdev, NULL);
diff -Nru a/drivers/net/sundance.c b/drivers/net/sundance.c
--- a/drivers/net/sundance.c	2005-03-01 23:38:59 -08:00
+++ b/drivers/net/sundance.c	2005-03-01 23:38:59 -08:00
@@ -188,10 +188,10 @@
 MODULE_DESCRIPTION("Sundance Alta Ethernet driver");
 MODULE_LICENSE("GPL");
 
-MODULE_PARM(debug, "i");
-MODULE_PARM(rx_copybreak, "i");
-MODULE_PARM(media, "1-" __MODULE_STRING(MAX_UNITS) "s");
-MODULE_PARM(flowctrl, "i");
+module_param(debug, int, 0);
+module_param(rx_copybreak, int, 0);
+module_param_array(media, charp, NULL, 0);
+module_param(flowctrl, int, 0);
 MODULE_PARM_DESC(debug, "Sundance Alta debug level (0-5)");
 MODULE_PARM_DESC(rx_copybreak, "Sundance Alta copy breakpoint for copy-only-tiny-frames");
 MODULE_PARM_DESC(flowctrl, "Sundance Alta flow control [0|1]");
@@ -305,20 +305,6 @@
 
 /* This driver was written to use PCI memory space, however x86-oriented
    hardware often uses I/O space accesses. */
-#ifdef USE_IO_OPS
-#undef readb
-#undef readw
-#undef readl
-#undef writeb
-#undef writew
-#undef writel
-#define readb inb
-#define readw inw
-#define readl inl
-#define writeb outb
-#define writew outw
-#define writel outl
-#endif
 
 /* Offsets to the device registers.
    Unlike software-only systems, device drivers interact with complex hardware.
@@ -480,6 +466,7 @@
 	int mii_preamble_required;
 	unsigned char phys[MII_CNT];		/* MII device addresses, only first one used. */
 	struct pci_dev *pci_dev;
+	void __iomem *base;
 	unsigned char pci_rev_id;
 };
 
@@ -490,7 +477,7 @@
 			LinkChange)
 
 static int  change_mtu(struct net_device *dev, int new_mtu);
-static int  eeprom_read(long ioaddr, int location);
+static int  eeprom_read(void __iomem *ioaddr, int location);
 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, int value);
 static int  netdev_open(struct net_device *dev);
@@ -522,10 +509,15 @@
 	int chip_idx = ent->driver_data;
 	int irq;
 	int i;
-	long ioaddr;
+	void __iomem *ioaddr;
 	u16 mii_ctl;
 	void *ring_space;
 	dma_addr_t ring_dma;
+#ifdef USE_IO_OPS
+	int bar = 0;
+#else
+	int bar = 1;
+#endif
 
 
 /* when built into the kernel, we only print version if device is found */
@@ -550,23 +542,19 @@
 	if (pci_request_regions(pdev, DRV_NAME))
 		goto err_out_netdev;
 
-#ifdef USE_IO_OPS
-	ioaddr = pci_resource_start(pdev, 0);
-#else
-	ioaddr = pci_resource_start(pdev, 1);
-	ioaddr = (long) ioremap (ioaddr, netdev_io_size);
+	ioaddr = pci_iomap(pdev, bar, netdev_io_size);
 	if (!ioaddr)
 		goto err_out_res;
-#endif
 
 	for (i = 0; i < 3; i++)
 		((u16 *)dev->dev_addr)[i] =
 			le16_to_cpu(eeprom_read(ioaddr, i + EEPROM_SA_OFFSET));
 
-	dev->base_addr = ioaddr;
+	dev->base_addr = (unsigned long)ioaddr;
 	dev->irq = irq;
 
 	np = netdev_priv(dev);
+	np->base = ioaddr;
 	np->pci_dev = pdev;
 	np->chip_id = chip_idx;
 	np->msg_enable = (1 << debug) - 1;
@@ -611,7 +599,7 @@
 	if (i)
 		goto err_out_unmap_rx;
 
-	printk(KERN_INFO "%s: %s at 0x%lx, ",
+	printk(KERN_INFO "%s: %s at %p, ",
 		   dev->name, pci_id_tbl[chip_idx].name, ioaddr);
 	for (i = 0; i < 5; i++)
 			printk("%2.2x:", dev->dev_addr[i]);
@@ -637,7 +625,7 @@
 
 		if (phy_idx == 0) {
 			printk(KERN_INFO "%s: No MII transceiver found, aborting.  ASIC status %x\n",
-				   dev->name, readl(ioaddr + ASICCtrl));
+				   dev->name, ioread32(ioaddr + ASICCtrl));
 			goto err_out_unregister;
 		}
 
@@ -674,7 +662,7 @@
 	}
 
 	/* Fibre PHY? */
-	if (readl (ioaddr + ASICCtrl) & 0x80) {
+	if (ioread32 (ioaddr + ASICCtrl) & 0x80) {
 		/* Default 100Mbps Full */
 		if (np->an_enable) {
 			np->speed = 100;
@@ -703,10 +691,10 @@
 	/* Perhaps move the reset here? */
 	/* Reset the chip to erase previous misconfiguration. */
 	if (netif_msg_hw(np))
-		printk("ASIC Control is %x.\n", readl(ioaddr + ASICCtrl));
-	writew(0x007f, ioaddr + ASICCtrl + 2);
+		printk("ASIC Control is %x.\n", ioread32(ioaddr + ASICCtrl));
+	iowrite16(0x007f, ioaddr + ASICCtrl + 2);
 	if (netif_msg_hw(np))
-		printk("ASIC Control is now %x.\n", readl(ioaddr + ASICCtrl));
+		printk("ASIC Control is now %x.\n", ioread32(ioaddr + ASICCtrl));
 
 	card_idx++;
 	return 0;
@@ -719,10 +707,8 @@
         pci_free_consistent(pdev, TX_TOTAL_SIZE, np->tx_ring, np->tx_ring_dma);
 err_out_cleardev:
 	pci_set_drvdata(pdev, NULL);
-#ifndef USE_IO_OPS
-	iounmap((void *)ioaddr);
+	pci_iounmap(pdev, ioaddr);
 err_out_res:
-#endif
 	pci_release_regions(pdev);
 err_out_netdev:
 	free_netdev (dev);
@@ -739,16 +725,16 @@
 	return 0;
 }
 
-#define eeprom_delay(ee_addr)	readl(ee_addr)
+#define eeprom_delay(ee_addr)	ioread32(ee_addr)
 /* Read the EEPROM and MII Management Data I/O (MDIO) interfaces. */
-static int __devinit eeprom_read(long ioaddr, int location)
+static int __devinit eeprom_read(void __iomem *ioaddr, int location)
 {
 	int boguscnt = 10000;		/* Typical 1900 ticks. */
-	writew(0x0200 | (location & 0xff), ioaddr + EECtrl);
+	iowrite16(0x0200 | (location & 0xff), ioaddr + EECtrl);
 	do {
 		eeprom_delay(ioaddr + EECtrl);
-		if (! (readw(ioaddr + EECtrl) & 0x8000)) {
-			return readw(ioaddr + EEData);
+		if (! (ioread16(ioaddr + EECtrl) & 0x8000)) {
+			return ioread16(ioaddr + EEData);
 		}
 	} while (--boguscnt > 0);
 	return 0;
@@ -761,7 +747,7 @@
 
 	The maximum data clock rate is 2.5 Mhz.  The minimum timing is usually
 	met by back-to-back 33Mhz PCI cycles. */
-#define mdio_delay() readb(mdio_addr)
+#define mdio_delay() ioread8(mdio_addr)
 
 enum mii_reg_bits {
 	MDIO_ShiftClk=0x0001, MDIO_Data=0x0002, MDIO_EnbOutput=0x0004,
@@ -772,15 +758,15 @@
 
 /* Generate the preamble required for initial synchronization and
    a few older transceivers. */
-static void mdio_sync(long mdio_addr)
+static void mdio_sync(void __iomem *mdio_addr)
 {
 	int bits = 32;
 
 	/* Establish sync by sending at least 32 logic ones. */
 	while (--bits >= 0) {
-		writeb(MDIO_WRITE1, mdio_addr);
+		iowrite8(MDIO_WRITE1, mdio_addr);
 		mdio_delay();
-		writeb(MDIO_WRITE1 | MDIO_ShiftClk, mdio_addr);
+		iowrite8(MDIO_WRITE1 | MDIO_ShiftClk, mdio_addr);
 		mdio_delay();
 	}
 }
@@ -788,7 +774,7 @@
 static int mdio_read(struct net_device *dev, int phy_id, int location)
 {
 	struct netdev_private *np = netdev_priv(dev);
-	long mdio_addr = dev->base_addr + MIICtrl;
+	void __iomem *mdio_addr = np->base + MIICtrl;
 	int mii_cmd = (0xf6 << 10) | (phy_id << 5) | location;
 	int i, retval = 0;
 
@@ -799,17 +785,17 @@
 	for (i = 15; i >= 0; i--) {
 		int dataval = (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;
 
-		writeb(dataval, mdio_addr);
+		iowrite8(dataval, mdio_addr);
 		mdio_delay();
-		writeb(dataval | MDIO_ShiftClk, mdio_addr);
+		iowrite8(dataval | MDIO_ShiftClk, mdio_addr);
 		mdio_delay();
 	}
 	/* Read the two transition, 16 data, and wire-idle bits. */
 	for (i = 19; i > 0; i--) {
-		writeb(MDIO_EnbIn, mdio_addr);
+		iowrite8(MDIO_EnbIn, mdio_addr);
 		mdio_delay();
-		retval = (retval << 1) | ((readb(mdio_addr) & MDIO_Data) ? 1 : 0);
-		writeb(MDIO_EnbIn | MDIO_ShiftClk, mdio_addr);
+		retval = (retval << 1) | ((ioread8(mdio_addr) & MDIO_Data) ? 1 : 0);
+		iowrite8(MDIO_EnbIn | MDIO_ShiftClk, mdio_addr);
 		mdio_delay();
 	}
 	return (retval>>1) & 0xffff;
@@ -818,7 +804,7 @@
 static void mdio_write(struct net_device *dev, int phy_id, int location, int value)
 {
 	struct netdev_private *np = netdev_priv(dev);
-	long mdio_addr = dev->base_addr + MIICtrl;
+	void __iomem *mdio_addr = np->base + MIICtrl;
 	int mii_cmd = (0x5002 << 16) | (phy_id << 23) | (location<<18) | value;
 	int i;
 
@@ -829,16 +815,16 @@
 	for (i = 31; i >= 0; i--) {
 		int dataval = (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;
 
-		writeb(dataval, mdio_addr);
+		iowrite8(dataval, mdio_addr);
 		mdio_delay();
-		writeb(dataval | MDIO_ShiftClk, mdio_addr);
+		iowrite8(dataval | MDIO_ShiftClk, mdio_addr);
 		mdio_delay();
 	}
 	/* Clear out extra bits. */
 	for (i = 2; i > 0; i--) {
-		writeb(MDIO_EnbIn, mdio_addr);
+		iowrite8(MDIO_EnbIn, mdio_addr);
 		mdio_delay();
-		writeb(MDIO_EnbIn | MDIO_ShiftClk, mdio_addr);
+		iowrite8(MDIO_EnbIn | MDIO_ShiftClk, mdio_addr);
 		mdio_delay();
 	}
 	return;
@@ -847,7 +833,7 @@
 static int netdev_open(struct net_device *dev)
 {
 	struct netdev_private *np = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = np->base;
 	int i;
 
 	/* Do we need to reset the chip??? */
@@ -861,18 +847,18 @@
 			   dev->name, dev->irq);
 	init_ring(dev);
 
-	writel(np->rx_ring_dma, ioaddr + RxListPtr);
+	iowrite32(np->rx_ring_dma, ioaddr + RxListPtr);
 	/* The Tx list pointer is written as packets are queued. */
 
 	/* Initialize other registers. */
 	__set_mac_addr(dev);
 #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
-	writew(dev->mtu + 18, ioaddr + MaxFrameSize);
+	iowrite16(dev->mtu + 18, ioaddr + MaxFrameSize);
 #else
-	writew(dev->mtu + 14, ioaddr + MaxFrameSize);
+	iowrite16(dev->mtu + 14, ioaddr + MaxFrameSize);
 #endif
 	if (dev->mtu > 2047)
-		writel(readl(ioaddr + ASICCtrl) | 0x0C, ioaddr + ASICCtrl);
+		iowrite32(ioread32(ioaddr + ASICCtrl) | 0x0C, ioaddr + ASICCtrl);
 
 	/* Configure the PCI bus bursts and FIFO thresholds. */
 
@@ -882,24 +868,24 @@
 	spin_lock_init(&np->mcastlock);
 
 	set_rx_mode(dev);
-	writew(0, ioaddr + IntrEnable);
-	writew(0, ioaddr + DownCounter);
+	iowrite16(0, ioaddr + IntrEnable);
+	iowrite16(0, ioaddr + DownCounter);
 	/* Set the chip to poll every N*320nsec. */
-	writeb(100, ioaddr + RxDMAPollPeriod);
-	writeb(127, ioaddr + TxDMAPollPeriod);
+	iowrite8(100, ioaddr + RxDMAPollPeriod);
+	iowrite8(127, ioaddr + TxDMAPollPeriod);
 	/* Fix DFE-580TX packet drop issue */
 	if (np->pci_rev_id >= 0x14)
-		writeb(0x01, ioaddr + DebugCtrl1);
+		iowrite8(0x01, ioaddr + DebugCtrl1);
 	netif_start_queue(dev);
 
-	writew (StatsEnable | RxEnable | TxEnable, ioaddr + MACCtrl1);
+	iowrite16 (StatsEnable | RxEnable | TxEnable, ioaddr + MACCtrl1);
 
 	if (netif_msg_ifup(np))
 		printk(KERN_DEBUG "%s: Done netdev_open(), status: Rx %x Tx %x "
 			   "MAC Control %x, %4.4x %4.4x.\n",
-			   dev->name, readl(ioaddr + RxStatus), readb(ioaddr + TxStatus),
-			   readl(ioaddr + MACCtrl0),
-			   readw(ioaddr + MACCtrl1), readw(ioaddr + MACCtrl0));
+			   dev->name, ioread32(ioaddr + RxStatus), ioread8(ioaddr + TxStatus),
+			   ioread32(ioaddr + MACCtrl0),
+			   ioread16(ioaddr + MACCtrl1), ioread16(ioaddr + MACCtrl0));
 
 	/* Set the timer to check for link beat. */
 	init_timer(&np->timer);
@@ -909,7 +895,7 @@
 	add_timer(&np->timer);
 
 	/* Enable interrupts by setting the interrupt mask. */
-	writew(DEFAULT_INTR, ioaddr + IntrEnable);
+	iowrite16(DEFAULT_INTR, ioaddr + IntrEnable);
 
 	return 0;
 }
@@ -917,7 +903,7 @@
 static void check_duplex(struct net_device *dev)
 {
 	struct netdev_private *np = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = np->base;
 	int mii_lpa = mdio_read(dev, np->phys[0], MII_LPA);
 	int negotiated = mii_lpa & np->mii_if.advertising;
 	int duplex;
@@ -925,7 +911,7 @@
 	/* Force media */
 	if (!np->an_enable || mii_lpa == 0xffff) {
 		if (np->mii_if.full_duplex)
-			writew (readw (ioaddr + MACCtrl0) | EnbFullDuplex,
+			iowrite16 (ioread16 (ioaddr + MACCtrl0) | EnbFullDuplex,
 				ioaddr + MACCtrl0);
 		return;
 	}
@@ -938,7 +924,7 @@
 			printk(KERN_INFO "%s: Setting %s-duplex based on MII #%d "
 				   "negotiated capability %4.4x.\n", dev->name,
 				   duplex ? "full" : "half", np->phys[0], negotiated);
-		writew(readw(ioaddr + MACCtrl0) | duplex ? 0x20 : 0, ioaddr + MACCtrl0);
+		iowrite16(ioread16(ioaddr + MACCtrl0) | duplex ? 0x20 : 0, ioaddr + MACCtrl0);
 	}
 }
 
@@ -946,14 +932,14 @@
 {
 	struct net_device *dev = (struct net_device *)data;
 	struct netdev_private *np = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = np->base;
 	int next_tick = 10*HZ;
 
 	if (netif_msg_timer(np)) {
 		printk(KERN_DEBUG "%s: Media selection timer tick, intr status %4.4x, "
 			   "Tx %x Rx %x.\n",
-			   dev->name, readw(ioaddr + IntrEnable),
-			   readb(ioaddr + TxStatus), readl(ioaddr + RxStatus));
+			   dev->name, ioread16(ioaddr + IntrEnable),
+			   ioread8(ioaddr + TxStatus), ioread32(ioaddr + RxStatus));
 	}
 	check_duplex(dev);
 	np->timer.expires = jiffies + next_tick;
@@ -963,16 +949,16 @@
 static void tx_timeout(struct net_device *dev)
 {
 	struct netdev_private *np = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = np->base;
 	unsigned long flag;
 	
 	netif_stop_queue(dev);
 	tasklet_disable(&np->tx_tasklet);
-	writew(0, ioaddr + IntrEnable);
+	iowrite16(0, ioaddr + IntrEnable);
 	printk(KERN_WARNING "%s: Transmit timed out, TxStatus %2.2x "
 		   "TxFrameId %2.2x,"
-		   " resetting...\n", dev->name, readb(ioaddr + TxStatus),
-		   readb(ioaddr + TxFrameId));
+		   " resetting...\n", dev->name, ioread8(ioaddr + TxStatus),
+		   ioread8(ioaddr + TxFrameId));
 
 	{
 		int i;
@@ -986,7 +972,7 @@
 				le32_to_cpu(np->tx_ring[i].frag[0].length));
 		}
 		printk(KERN_DEBUG "TxListPtr=%08x netif_queue_stopped=%d\n", 
-			readl(dev->base_addr + TxListPtr), 
+			ioread32(np->base + TxListPtr), 
 			netif_queue_stopped(dev));
 		printk(KERN_DEBUG "cur_tx=%d(%02x) dirty_tx=%d(%02x)\n", 
 			np->cur_tx, np->cur_tx % TX_RING_SIZE,
@@ -1007,7 +993,7 @@
 	if (np->cur_tx - np->dirty_tx < TX_QUEUE_LEN - 4) {
 		netif_wake_queue(dev);
 	}
-	writew(DEFAULT_INTR, ioaddr + IntrEnable);
+	iowrite16(DEFAULT_INTR, ioaddr + IntrEnable);
 	tasklet_enable(&np->tx_tasklet);
 }
 
@@ -1076,9 +1062,9 @@
 	/* Indicate the latest descriptor of tx ring */
 	txdesc->status |= cpu_to_le32(DescIntrOnTx);
 
-	if (readl (dev->base_addr + TxListPtr) == 0)
-		writel (np->tx_ring_dma + head * sizeof(struct netdev_desc),
-			dev->base_addr + TxListPtr);
+	if (ioread32 (np->base + TxListPtr) == 0)
+		iowrite32 (np->tx_ring_dma + head * sizeof(struct netdev_desc),
+			np->base + TxListPtr);
 	return;
 }
 
@@ -1128,17 +1114,17 @@
 reset_tx (struct net_device *dev)
 {
 	struct netdev_private *np = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = np->base;
 	struct sk_buff *skb;
 	int i;
 	int irq = in_interrupt();
 	
 	/* Reset tx logic, TxListPtr will be cleaned */
-	writew (TxDisable, ioaddr + MACCtrl1);
-	writew (TxReset | DMAReset | FIFOReset | NetworkReset,
+	iowrite16 (TxDisable, ioaddr + MACCtrl1);
+	iowrite16 (TxReset | DMAReset | FIFOReset | NetworkReset,
 			ioaddr + ASICCtrl + 2);
 	for (i=50; i > 0; i--) {
-		if ((readw(ioaddr + ASICCtrl + 2) & ResetBusy) == 0)
+		if ((ioread16(ioaddr + ASICCtrl + 2) & ResetBusy) == 0)
 			break;
 		mdelay(1);
 	}
@@ -1159,7 +1145,7 @@
 	}
 	np->cur_tx = np->dirty_tx = 0;
 	np->cur_task = 0;
-	writew (StatsEnable | RxEnable | TxEnable, ioaddr + MACCtrl1);
+	iowrite16 (StatsEnable | RxEnable | TxEnable, ioaddr + MACCtrl1);
 	return 0;
 }
 
@@ -1168,19 +1154,17 @@
 static irqreturn_t intr_handler(int irq, void *dev_instance, struct pt_regs *rgs)
 {
 	struct net_device *dev = (struct net_device *)dev_instance;
-	struct netdev_private *np;
-	long ioaddr;
+	struct netdev_private *np = netdev_priv(dev);
+	void __iomem *ioaddr = np->base;
 	int hw_frame_id;
 	int tx_cnt;
 	int tx_status;
 	int handled = 0;
 
-	ioaddr = dev->base_addr;
-	np = netdev_priv(dev);
 
 	do {
-		int intr_status = readw(ioaddr + IntrStatus);
-		writew(intr_status, ioaddr + IntrStatus);
+		int intr_status = ioread16(ioaddr + IntrStatus);
+		iowrite16(intr_status, ioaddr + IntrStatus);
 
 		if (netif_msg_intr(np))
 			printk(KERN_DEBUG "%s: Interrupt, status %4.4x.\n",
@@ -1192,14 +1176,14 @@
 		handled = 1;
 
 		if (intr_status & (IntrRxDMADone)) {
-			writew(DEFAULT_INTR & ~(IntrRxDone|IntrRxDMADone),
+			iowrite16(DEFAULT_INTR & ~(IntrRxDone|IntrRxDMADone),
 					ioaddr + IntrEnable);
 			if (np->budget < 0)
 				np->budget = RX_BUDGET;
 			tasklet_schedule(&np->rx_tasklet);
 		}
 		if (intr_status & (IntrTxDone | IntrDrvRqst)) {
-			tx_status = readw (ioaddr + TxStatus);
+			tx_status = ioread16 (ioaddr + TxStatus);
 			for (tx_cnt=32; tx_status & 0x80; --tx_cnt) {
 				if (netif_msg_tx_done(np))
 					printk
@@ -1221,18 +1205,18 @@
 						spin_unlock(&np->lock);
 					}
 					if (tx_status & 0x1e)	/* Restart the Tx. */
-						writew (TxEnable,
+						iowrite16 (TxEnable,
 							ioaddr + MACCtrl1);
 				}
 				/* Yup, this is a documentation bug.  It cost me *hours*. */
-				writew (0, ioaddr + TxStatus);
-				tx_status = readw (ioaddr + TxStatus);
+				iowrite16 (0, ioaddr + TxStatus);
+				tx_status = ioread16 (ioaddr + TxStatus);
 				if (tx_cnt < 0)
 					break;
 			}
 			hw_frame_id = (tx_status >> 8) & 0xff;
 		} else 	{
-			hw_frame_id = readb(ioaddr + TxFrameId);
+			hw_frame_id = ioread8(ioaddr + TxFrameId);
 		}
 			
 		if (np->pci_rev_id >= 0x14) {	
@@ -1293,8 +1277,8 @@
 	} while (0);
 	if (netif_msg_intr(np))
 		printk(KERN_DEBUG "%s: exiting interrupt, status=%#4.4x.\n",
-			   dev->name, readw(ioaddr + IntrStatus));
-	writel(5000, ioaddr + DownCounter);
+			   dev->name, ioread16(ioaddr + IntrStatus));
+	iowrite32(5000, ioaddr + DownCounter);
 	return IRQ_RETVAL(handled);
 }
 
@@ -1304,7 +1288,7 @@
 	struct netdev_private *np = netdev_priv(dev);
 	int entry = np->cur_rx % RX_RING_SIZE;
 	int boguscnt = np->budget;
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = np->base;
 	int received = 0;
 
 	/* If EOP is set on the next entry, it's a new packet. Send it up. */
@@ -1381,7 +1365,7 @@
 	np->cur_rx = entry;
 	refill_rx (dev);
 	np->budget -= received;
-	writew(DEFAULT_INTR, ioaddr + IntrEnable);
+	iowrite16(DEFAULT_INTR, ioaddr + IntrEnable);
 	return;
 
 not_done:
@@ -1428,8 +1412,8 @@
 }
 static void netdev_error(struct net_device *dev, int intr_status)
 {
-	long ioaddr = dev->base_addr;
 	struct netdev_private *np = netdev_priv(dev);
+	void __iomem *ioaddr = np->base;
 	u16 mii_ctl, mii_advertise, mii_lpa;
 	int speed;
 
@@ -1465,9 +1449,9 @@
 		}
 		check_duplex (dev);
 		if (np->flowctrl && np->mii_if.full_duplex) {
-			writew(readw(ioaddr + MulticastFilter1+2) | 0x0200,
+			iowrite16(ioread16(ioaddr + MulticastFilter1+2) | 0x0200,
 				ioaddr + MulticastFilter1+2);
-			writew(readw(ioaddr + MACCtrl0) | EnbFlowCtrl,
+			iowrite16(ioread16(ioaddr + MACCtrl0) | EnbFlowCtrl,
 				ioaddr + MACCtrl0);
 		}
 	}
@@ -1484,35 +1468,35 @@
 static struct net_device_stats *get_stats(struct net_device *dev)
 {
 	struct netdev_private *np = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = np->base;
 	int i;
 
 	/* We should lock this segment of code for SMP eventually, although
 	   the vulnerability window is very small and statistics are
 	   non-critical. */
 	/* The chip only need report frame silently dropped. */
-	np->stats.rx_missed_errors	+= readb(ioaddr + RxMissed);
-	np->stats.tx_packets += readw(ioaddr + TxFramesOK);
-	np->stats.rx_packets += readw(ioaddr + RxFramesOK);
-	np->stats.collisions += readb(ioaddr + StatsLateColl);
-	np->stats.collisions += readb(ioaddr + StatsMultiColl);
-	np->stats.collisions += readb(ioaddr + StatsOneColl);
-	np->stats.tx_carrier_errors += readb(ioaddr + StatsCarrierError);
-	readb(ioaddr + StatsTxDefer);
+	np->stats.rx_missed_errors	+= ioread8(ioaddr + RxMissed);
+	np->stats.tx_packets += ioread16(ioaddr + TxFramesOK);
+	np->stats.rx_packets += ioread16(ioaddr + RxFramesOK);
+	np->stats.collisions += ioread8(ioaddr + StatsLateColl);
+	np->stats.collisions += ioread8(ioaddr + StatsMultiColl);
+	np->stats.collisions += ioread8(ioaddr + StatsOneColl);
+	np->stats.tx_carrier_errors += ioread8(ioaddr + StatsCarrierError);
+	ioread8(ioaddr + StatsTxDefer);
 	for (i = StatsTxDefer; i <= StatsMcastRx; i++)
-		readb(ioaddr + i);
-	np->stats.tx_bytes += readw(ioaddr + TxOctetsLow);
-	np->stats.tx_bytes += readw(ioaddr + TxOctetsHigh) << 16;
-	np->stats.rx_bytes += readw(ioaddr + RxOctetsLow);
-	np->stats.rx_bytes += readw(ioaddr + RxOctetsHigh) << 16;
+		ioread8(ioaddr + i);
+	np->stats.tx_bytes += ioread16(ioaddr + TxOctetsLow);
+	np->stats.tx_bytes += ioread16(ioaddr + TxOctetsHigh) << 16;
+	np->stats.rx_bytes += ioread16(ioaddr + RxOctetsLow);
+	np->stats.rx_bytes += ioread16(ioaddr + RxOctetsHigh) << 16;
 
 	return &np->stats;
 }
 
 static void set_rx_mode(struct net_device *dev)
 {
-	long ioaddr = dev->base_addr;
 	struct netdev_private *np = netdev_priv(dev);
+	void __iomem *ioaddr = np->base;
 	u16 mc_filter[4];			/* Multicast hash filter */
 	u32 rx_mode;
 	int i;
@@ -1542,27 +1526,28 @@
 		}
 		rx_mode = AcceptBroadcast | AcceptMultiHash | AcceptMyPhys;
 	} else {
-		writeb(AcceptBroadcast | AcceptMyPhys, ioaddr + RxMode);
+		iowrite8(AcceptBroadcast | AcceptMyPhys, ioaddr + RxMode);
 		return;
 	}
 	if (np->mii_if.full_duplex && np->flowctrl)
 		mc_filter[3] |= 0x0200;
 
 	for (i = 0; i < 4; i++)
-		writew(mc_filter[i], ioaddr + MulticastFilter0 + i*2);
-	writeb(rx_mode, ioaddr + RxMode);
+		iowrite16(mc_filter[i], ioaddr + MulticastFilter0 + i*2);
+	iowrite8(rx_mode, ioaddr + RxMode);
 }
 
 static int __set_mac_addr(struct net_device *dev)
 {
+	struct netdev_private *np = netdev_priv(dev);
 	u16 addr16;
 
 	addr16 = (dev->dev_addr[0] | (dev->dev_addr[1] << 8));
-	writew(addr16, dev->base_addr + StationAddr);
+	iowrite16(addr16, np->base + StationAddr);
 	addr16 = (dev->dev_addr[2] | (dev->dev_addr[3] << 8));
-	writew(addr16, dev->base_addr + StationAddr+2);
+	iowrite16(addr16, np->base + StationAddr+2);
 	addr16 = (dev->dev_addr[4] | (dev->dev_addr[5] << 8));
-	writew(addr16, dev->base_addr + StationAddr+4);
+	iowrite16(addr16, np->base + StationAddr+4);
 	return 0;
 }
 
@@ -1638,9 +1623,9 @@
 static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
 	struct netdev_private *np = netdev_priv(dev);
+	void __iomem *ioaddr = np->base;
 	int rc;
 	int i;
-	long ioaddr = dev->base_addr;
 
 	if (!netif_running(dev))
 		return -EINVAL;
@@ -1661,14 +1646,14 @@
 				le32_to_cpu(np->tx_ring[i].frag[0].length));
 		}
 		printk(KERN_DEBUG "TxListPtr=%08x netif_queue_stopped=%d\n", 
-			readl(dev->base_addr + TxListPtr), 
+			ioread32(np->base + TxListPtr), 
 			netif_queue_stopped(dev));
 		printk(KERN_DEBUG "cur_tx=%d(%02x) dirty_tx=%d(%02x)\n", 
 			np->cur_tx, np->cur_tx % TX_RING_SIZE,
 			np->dirty_tx, np->dirty_tx % TX_RING_SIZE);
 		printk(KERN_DEBUG "cur_rx=%d dirty_rx=%d\n", np->cur_rx, np->dirty_rx);
 		printk(KERN_DEBUG "cur_task=%d\n", np->cur_task);
-		printk(KERN_DEBUG "TxStatus=%04x\n", readw(ioaddr + TxStatus));
+		printk(KERN_DEBUG "TxStatus=%04x\n", ioread16(ioaddr + TxStatus));
 			return 0;
 	}
 				
@@ -1678,8 +1663,8 @@
 
 static int netdev_close(struct net_device *dev)
 {
-	long ioaddr = dev->base_addr;
 	struct netdev_private *np = netdev_priv(dev);
+	void __iomem *ioaddr = np->base;
 	struct sk_buff *skb;
 	int i;
 
@@ -1688,17 +1673,17 @@
 	if (netif_msg_ifdown(np)) {
 		printk(KERN_DEBUG "%s: Shutting down ethercard, status was Tx %2.2x "
 			   "Rx %4.4x Int %2.2x.\n",
-			   dev->name, readb(ioaddr + TxStatus),
-			   readl(ioaddr + RxStatus), readw(ioaddr + IntrStatus));
+			   dev->name, ioread8(ioaddr + TxStatus),
+			   ioread32(ioaddr + RxStatus), ioread16(ioaddr + IntrStatus));
 		printk(KERN_DEBUG "%s: Queue pointers were Tx %d / %d,  Rx %d / %d.\n",
 			   dev->name, np->cur_tx, np->dirty_tx, np->cur_rx, np->dirty_rx);
 	}
 
 	/* Disable interrupts by clearing the interrupt mask. */
-	writew(0x0000, ioaddr + IntrEnable);
+	iowrite16(0x0000, ioaddr + IntrEnable);
 
 	/* Stop the chip's Tx and Rx processes. */
-	writew(TxDisable | RxDisable | StatsDisable, ioaddr + MACCtrl1);
+	iowrite16(TxDisable | RxDisable | StatsDisable, ioaddr + MACCtrl1);
 
 	/* Wait and kill tasklet */
 	tasklet_kill(&np->rx_tasklet);
@@ -1765,10 +1750,8 @@
 			np->rx_ring_dma);
 	        pci_free_consistent(pdev, TX_TOTAL_SIZE, np->tx_ring,
 			np->tx_ring_dma);
+		pci_iounmap(pdev, np->base);
 		pci_release_regions(pdev);
-#ifndef USE_IO_OPS
-		iounmap((char *)(dev->base_addr));
-#endif
 		free_netdev(dev);
 		pci_set_drvdata(pdev, NULL);
 	}
diff -Nru a/drivers/net/sunhme.c b/drivers/net/sunhme.c
--- a/drivers/net/sunhme.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/net/sunhme.c	2005-03-01 23:38:55 -08:00
@@ -73,7 +73,7 @@
 static int macaddr[6];
 
 /* accept MAC address of the form macaddr=0x08,0x00,0x20,0x30,0x40,0x50 */
-MODULE_PARM(macaddr, "6i");
+module_param_array(macaddr, int, NULL, 0);
 MODULE_PARM_DESC(macaddr, "Happy Meal MAC address to set");
 MODULE_LICENSE("GPL");
 
diff -Nru a/drivers/net/sunlance.c b/drivers/net/sunlance.c
--- a/drivers/net/sunlance.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/net/sunlance.c	2005-03-01 23:38:54 -08:00
@@ -232,7 +232,8 @@
 struct lance_private {
 	void __iomem	*lregs;		/* Lance RAP/RDP regs.		*/
 	void __iomem	*dregs;		/* DMA controller regs.		*/
-	struct lance_init_block *init_block;
+	struct lance_init_block __iomem *init_block_iomem;
+	struct lance_init_block *init_block_mem;
     
 	spinlock_t	lock;
 
@@ -314,7 +315,7 @@
 static void lance_init_ring_dvma(struct net_device *dev)
 {
 	struct lance_private *lp = netdev_priv(dev);
-	struct lance_init_block *ib = lp->init_block;
+	struct lance_init_block *ib = lp->init_block_mem;
 	dma_addr_t aib = lp->init_block_dvma;
 	__u32 leptr;
 	int i;
@@ -371,7 +372,7 @@
 static void lance_init_ring_pio(struct net_device *dev)
 {
 	struct lance_private *lp = netdev_priv(dev);
-	struct lance_init_block *ib = lp->init_block;
+	struct lance_init_block __iomem *ib = lp->init_block_iomem;
 	u32 leptr;
 	int i;
     
@@ -501,7 +502,7 @@
 static void lance_rx_dvma(struct net_device *dev)
 {
 	struct lance_private *lp = netdev_priv(dev);
-	struct lance_init_block *ib = lp->init_block;
+	struct lance_init_block *ib = lp->init_block_mem;
 	struct lance_rx_desc *rd;
 	u8 bits;
 	int len, entry = lp->rx_new;
@@ -564,7 +565,7 @@
 static void lance_tx_dvma(struct net_device *dev)
 {
 	struct lance_private *lp = netdev_priv(dev);
-	struct lance_init_block *ib = lp->init_block;
+	struct lance_init_block *ib = lp->init_block_mem;
 	int i, j;
 
 	spin_lock(&lp->lock);
@@ -674,8 +675,8 @@
 static void lance_rx_pio(struct net_device *dev)
 {
 	struct lance_private *lp = netdev_priv(dev);
-	struct lance_init_block *ib = lp->init_block;
-	struct lance_rx_desc *rd;
+	struct lance_init_block __iomem *ib = lp->init_block_iomem;
+	struct lance_rx_desc __iomem *rd;
 	unsigned char bits;
 	int len, entry;
 	struct sk_buff *skb;
@@ -736,14 +737,14 @@
 static void lance_tx_pio(struct net_device *dev)
 {
 	struct lance_private *lp = netdev_priv(dev);
-	struct lance_init_block *ib = lp->init_block;
+	struct lance_init_block __iomem *ib = lp->init_block_iomem;
 	int i, j;
 
 	spin_lock(&lp->lock);
 
 	j = lp->tx_old;
 	for (i = j; i != lp->tx_new; i = j) {
-		struct lance_tx_desc *td = &ib->btx_ring [i];
+		struct lance_tx_desc __iomem *td = &ib->btx_ring [i];
 		u8 bits = sbus_readb(&td->tmd1_bits);
 
 		/* If we hit a packet not owned by us, stop */
@@ -880,15 +881,13 @@
 static void build_fake_packet(struct lance_private *lp)
 {
 	struct net_device *dev = lp->dev;
-	struct lance_init_block *ib = lp->init_block;
-	u16 *packet;
-	struct ethhdr *eth;
 	int i, entry;
 
 	entry = lp->tx_new & TX_RING_MOD_MASK;
-	packet = (u16 *) &(ib->tx_buf[entry][0]);
-	eth = (struct ethhdr *) packet;
 	if (lp->pio_buffer) {
+		struct lance_init_block __iomem *ib = lp->init_block_iomem;
+		u16 __iomem *packet = (u16 __iomem *) &(ib->tx_buf[entry][0]);
+		struct ethhdr __iomem *eth = (struct ethhdr __iomem *) packet;
 		for (i = 0; i < (ETH_ZLEN / sizeof(u16)); i++)
 			sbus_writew(0, &packet[i]);
 		for (i = 0; i < 6; i++) {
@@ -899,6 +898,9 @@
 		sbus_writew(0, &ib->btx_ring[entry].misc);
 		sbus_writeb(LE_T1_POK|LE_T1_OWN, &ib->btx_ring[entry].tmd1_bits);
 	} else {
+		struct lance_init_block *ib = lp->init_block_mem;
+		u16 *packet = (u16 *) &(ib->tx_buf[entry][0]);
+		struct ethhdr *eth = (struct ethhdr *) packet;
 		memset(packet, 0, ETH_ZLEN);
 		for (i = 0; i < 6; i++) {
 			eth->h_dest[i] = dev->dev_addr[i];
@@ -916,7 +918,6 @@
 static int lance_open(struct net_device *dev)
 {
 	struct lance_private *lp = netdev_priv(dev);
-	struct lance_init_block *ib = lp->init_block;
 	int status = 0;
 
 	last_dev = dev;
@@ -943,10 +944,12 @@
 	 * BTW it is common bug in all lance drivers! --ANK
 	 */
 	if (lp->pio_buffer) {
+		struct lance_init_block __iomem *ib = lp->init_block_iomem;
 		sbus_writew(0, &ib->mode);
 		sbus_writel(0, &ib->filter[0]);
 		sbus_writel(0, &ib->filter[1]);
 	} else {
+		struct lance_init_block *ib = lp->init_block_mem;
 		ib->mode = 0;
 		ib->filter [0] = 0;
 		ib->filter [1] = 0;
@@ -1113,7 +1116,6 @@
 static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct lance_private *lp = netdev_priv(dev);
-	struct lance_init_block *ib = lp->init_block;
 	int entry, skblen, len;
 
 	skblen = skb->len;
@@ -1126,6 +1128,7 @@
 
 	entry = lp->tx_new & TX_RING_MOD_MASK;
 	if (lp->pio_buffer) {
+		struct lance_init_block __iomem *ib = lp->init_block_iomem;
 		sbus_writew((-len) | 0xf000, &ib->btx_ring[entry].length);
 		sbus_writew(0, &ib->btx_ring[entry].misc);
 		lance_piocopy_from_skb(&ib->tx_buf[entry][0], skb->data, skblen);
@@ -1133,6 +1136,7 @@
 			lance_piozero(&ib->tx_buf[entry][skblen], len - skblen);
 		sbus_writeb(LE_T1_POK | LE_T1_OWN, &ib->btx_ring[entry].tmd1_bits);
 	} else {
+		struct lance_init_block *ib = lp->init_block_mem;
 		ib->btx_ring [entry].length = (-len) | 0xf000;
 		ib->btx_ring [entry].misc = 0;
 		memcpy((char *)&ib->tx_buf [entry][0], skb->data, skblen);
@@ -1174,33 +1178,31 @@
 static void lance_load_multicast(struct net_device *dev)
 {
 	struct lance_private *lp = netdev_priv(dev);
-	struct lance_init_block *ib = lp->init_block;
-	u16 *mcast_table = (u16 *) &ib->filter;
 	struct dev_mc_list *dmi = dev->mc_list;
 	char *addrs;
 	int i;
 	u32 crc;
+	u32 val;
 	
 	/* set all multicast bits */
-	if (dev->flags & IFF_ALLMULTI) {
-		if (lp->pio_buffer) {
-			sbus_writel(0xffffffff, &ib->filter[0]);
-			sbus_writel(0xffffffff, &ib->filter[1]);
-		} else {
-			ib->filter [0] = 0xffffffff;
-			ib->filter [1] = 0xffffffff;
-		}
-		return;
-	}
-	/* clear the multicast filter */
+	if (dev->flags & IFF_ALLMULTI)
+		val = ~0;
+	else
+		val = 0;
+
 	if (lp->pio_buffer) {
-		sbus_writel(0, &ib->filter[0]);
-		sbus_writel(0, &ib->filter[1]);
+		struct lance_init_block __iomem *ib = lp->init_block_iomem;
+		sbus_writel(val, &ib->filter[0]);
+		sbus_writel(val, &ib->filter[1]);
 	} else {
-		ib->filter [0] = 0;
-		ib->filter [1] = 0;
+		struct lance_init_block *ib = lp->init_block_mem;
+		ib->filter [0] = val;
+		ib->filter [1] = val;
 	}
 
+	if (dev->flags & IFF_ALLMULTI)
+		return;
+	
 	/* Add addresses */
 	for (i = 0; i < dev->mc_count; i++) {
 		addrs = dmi->dmi_addr;
@@ -1212,10 +1214,14 @@
 		crc = ether_crc_le(6, addrs);
 		crc = crc >> 26;
 		if (lp->pio_buffer) {
+			struct lance_init_block __iomem *ib = lp->init_block_iomem;
+			u16 __iomem *mcast_table = (u16 __iomem *) &ib->filter;
 			u16 tmp = sbus_readw(&mcast_table[crc>>4]);
 			tmp |= 1 << (crc & 0xf);
 			sbus_writew(tmp, &mcast_table[crc>>4]);
 		} else {
+			struct lance_init_block *ib = lp->init_block_mem;
+			u16 *mcast_table = (u16 *) &ib->filter;
 			mcast_table [crc >> 4] |= 1 << (crc & 0xf);
 		}
 	}
@@ -1224,7 +1230,8 @@
 static void lance_set_multicast(struct net_device *dev)
 {
 	struct lance_private *lp = netdev_priv(dev);
-	struct lance_init_block *ib = lp->init_block;
+	struct lance_init_block *ib_mem = lp->init_block_mem;
+	struct lance_init_block __iomem *ib_iomem = lp->init_block_iomem;
 	u16 mode;
 
 	if (!netif_running(dev))
@@ -1242,21 +1249,21 @@
 	lp->init_ring(dev);
 
 	if (lp->pio_buffer)
-		mode = sbus_readw(&ib->mode);
+		mode = sbus_readw(&ib_iomem->mode);
 	else
-		mode = ib->mode;
+		mode = ib_mem->mode;
 	if (dev->flags & IFF_PROMISC) {
 		mode |= LE_MO_PROM;
 		if (lp->pio_buffer)
-			sbus_writew(mode, &ib->mode);
+			sbus_writew(mode, &ib_iomem->mode);
 		else
-			ib->mode = mode;
+			ib_mem->mode = mode;
 	} else {
 		mode &= ~LE_MO_PROM;
 		if (lp->pio_buffer)
-			sbus_writew(mode, &ib->mode);
+			sbus_writew(mode, &ib_iomem->mode);
 		else
-			ib->mode = mode;
+			ib_mem->mode = mode;
 		lance_load_multicast(dev);
 	}
 	load_csrs(lp);
@@ -1275,16 +1282,14 @@
 {
 	if (lp->lregs)
 		sbus_iounmap(lp->lregs, LANCE_REG_SIZE);
-	if (lp->init_block != NULL) {
-		if (lp->pio_buffer) {
-			sbus_iounmap(lp->init_block,
-				     sizeof(struct lance_init_block));
-		} else {
-			sbus_free_consistent(lp->sdev,
-					     sizeof(struct lance_init_block),
-					     lp->init_block,
-					     lp->init_block_dvma);
-		}
+	if (lp->init_block_iomem) {
+		sbus_iounmap(lp->init_block_iomem,
+			     sizeof(struct lance_init_block));
+	} else if (lp->init_block_mem) {
+		sbus_free_consistent(lp->sdev,
+				     sizeof(struct lance_init_block),
+				     lp->init_block_mem,
+				     lp->init_block_dvma);
 	}
 }
 
@@ -1326,6 +1331,7 @@
 		return -ENOMEM;
 
 	lp = netdev_priv(dev);
+	memset(lp, 0, sizeof(*lp));
 
 	if (sparc_lance_debug && version_printed++ == 0)
 		printk (KERN_INFO "%s", version);
@@ -1342,17 +1348,22 @@
 	/* Get the IO region */
 	lp->lregs = sbus_ioremap(&sdev->resource[0], 0,
 				 LANCE_REG_SIZE, lancestr);
-	if (lp->lregs == 0UL) {
+	if (!lp->lregs) {
 		printk(KERN_ERR "SunLance: Cannot map registers.\n");
 		goto fail;
 	}
 
 	lp->sdev = sdev;
 	if (lebuffer) {
-		lp->init_block =
+		/* sanity check */
+		if (lebuffer->resource[0].start & 7) {
+			printk(KERN_ERR "SunLance: ERROR: Rx and Tx rings not on even boundary.\n");
+			goto fail;
+		}
+		lp->init_block_iomem =
 			sbus_ioremap(&lebuffer->resource[0], 0,
 				     sizeof(struct lance_init_block), "lebuffer");
-		if (lp->init_block == NULL) {
+		if (!lp->init_block_iomem) {
 			printk(KERN_ERR "SunLance: Cannot map PIO buffer.\n");
 			goto fail;
 		}
@@ -1362,11 +1373,10 @@
 		lp->rx = lance_rx_pio;
 		lp->tx = lance_tx_pio;
 	} else {
-		lp->init_block =
+		lp->init_block_mem =
 			sbus_alloc_consistent(sdev, sizeof(struct lance_init_block),
 					      &lp->init_block_dvma);
-		if (lp->init_block == NULL ||
-		    lp->init_block_dvma == 0) {
+		if (!lp->init_block_mem || lp->init_block_dvma == 0) {
 			printk(KERN_ERR "SunLance: Cannot allocate consistent DMA memory.\n");
 			goto fail;
 		}
@@ -1449,13 +1459,7 @@
 		udelay(200);
 		sbus_writel(csr & ~DMA_RST_ENET, lp->dregs + DMA_CSR);
 	} else
-		lp->dregs = 0;
-
-	/* This should never happen. */
-	if ((unsigned long)(lp->init_block->brx_ring) & 0x07) {
-		printk(KERN_ERR "SunLance: ERROR: Rx and Tx rings not on even boundary.\n");
-		goto fail;
-	}
+		lp->dregs = NULL;
 
 	lp->dev = dev;
 	SET_MODULE_OWNER(dev);
@@ -1499,8 +1503,7 @@
 	return 0;
 
 fail:
-	if (lp != NULL)
-		lance_free_hwresources(lp);
+	lance_free_hwresources(lp);
 	free_netdev(dev);
 	return -ENODEV;
 }
@@ -1539,7 +1542,7 @@
 		memset(&sdev, 0, sizeof(sdev));
 		sdev.reg_addrs[0].phys_addr = sun4_eth_physaddr;
 		sdev.irqs[0] = 6;
-		return sparc_lance_init(&sdev, 0, 0);
+		return sparc_lance_init(&sdev, NULL, NULL);
 	}
 	return -ENODEV;
 }
diff -Nru a/drivers/net/tg3.c b/drivers/net/tg3.c
--- a/drivers/net/tg3.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/net/tg3.c	2005-03-01 23:38:58 -08:00
@@ -60,8 +60,8 @@
 
 #define DRV_MODULE_NAME		"tg3"
 #define PFX DRV_MODULE_NAME	": "
-#define DRV_MODULE_VERSION	"3.14"
-#define DRV_MODULE_RELDATE	"November 15, 2004"
+#define DRV_MODULE_VERSION	"3.23"
+#define DRV_MODULE_RELDATE	"February 15, 2005"
 
 #define TG3_DEF_MAC_MODE	0
 #define TG3_DEF_RX_MODE		0
@@ -493,7 +493,8 @@
 static int tg3_readphy(struct tg3 *tp, int reg, u32 *val)
 {
 	u32 frame_val;
-	int loops, ret;
+	unsigned int loops;
+	int ret;
 
 	if ((tp->mi_mode & MAC_MI_MODE_AUTO_POLL) != 0) {
 		tw32_f(MAC_MI_MODE,
@@ -501,7 +502,7 @@
 		udelay(80);
 	}
 
-	*val = 0xffffffff;
+	*val = 0x0;
 
 	frame_val  = ((PHY_ADDR << MI_COM_PHY_ADDR_SHIFT) &
 		      MI_COM_PHY_ADDR_MASK);
@@ -512,7 +513,7 @@
 	tw32_f(MAC_MI_COM, frame_val);
 
 	loops = PHY_BUSY_LOOPS;
-	while (loops-- > 0) {
+	while (loops != 0) {
 		udelay(10);
 		frame_val = tr32(MAC_MI_COM);
 
@@ -521,10 +522,11 @@
 			frame_val = tr32(MAC_MI_COM);
 			break;
 		}
+		loops -= 1;
 	}
 
 	ret = -EBUSY;
-	if (loops > 0) {
+	if (loops != 0) {
 		*val = frame_val & MI_COM_DATA_MASK;
 		ret = 0;
 	}
@@ -540,7 +542,8 @@
 static int tg3_writephy(struct tg3 *tp, int reg, u32 val)
 {
 	u32 frame_val;
-	int loops, ret;
+	unsigned int loops;
+	int ret;
 
 	if ((tp->mi_mode & MAC_MI_MODE_AUTO_POLL) != 0) {
 		tw32_f(MAC_MI_MODE,
@@ -558,7 +561,7 @@
 	tw32_f(MAC_MI_COM, frame_val);
 
 	loops = PHY_BUSY_LOOPS;
-	while (loops-- > 0) {
+	while (loops != 0) {
 		udelay(10);
 		frame_val = tr32(MAC_MI_COM);
 		if ((frame_val & MI_COM_BUSY) == 0) {
@@ -566,10 +569,11 @@
 			frame_val = tr32(MAC_MI_COM);
 			break;
 		}
+		loops -= 1;
 	}
 
 	ret = -EBUSY;
-	if (loops > 0)
+	if (loops != 0)
 		ret = 0;
 
 	if ((tp->mi_mode & MAC_MI_MODE_AUTO_POLL) != 0) {
@@ -587,9 +591,10 @@
 	if (tp->tg3_flags2 & TG3_FLG2_NO_ETH_WIRE_SPEED)
 		return;
 
-	tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x7007);
-	tg3_readphy(tp, MII_TG3_AUX_CTRL, &val);
-	tg3_writephy(tp, MII_TG3_AUX_CTRL, (val | (1 << 15) | (1 << 4)));
+	if (!tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x7007) &&
+	    !tg3_readphy(tp, MII_TG3_AUX_CTRL, &val))
+		tg3_writephy(tp, MII_TG3_AUX_CTRL,
+			     (val | (1 << 15) | (1 << 4)));
 }
 
 static int tg3_bmcr_reset(struct tg3 *tp)
@@ -630,9 +635,10 @@
 	while (limit--) {
 		u32 tmp32;
 
-		tg3_readphy(tp, 0x16, &tmp32);
-		if ((tmp32 & 0x1000) == 0)
-			break;
+		if (!tg3_readphy(tp, 0x16, &tmp32)) {
+			if ((tmp32 & 0x1000) == 0)
+				break;
+		}
 	}
 	if (limit <= 0)
 		return -EBUSY;
@@ -684,9 +690,9 @@
 		for (i = 0; i < 6; i += 2) {
 			u32 low, high;
 
-			tg3_readphy(tp, MII_TG3_DSP_RW_PORT, &low);
-			tg3_readphy(tp, MII_TG3_DSP_RW_PORT, &high);
-			if (tg3_wait_macro_done(tp)) {
+			if (tg3_readphy(tp, MII_TG3_DSP_RW_PORT, &low) ||
+			    tg3_readphy(tp, MII_TG3_DSP_RW_PORT, &high) ||
+			    tg3_wait_macro_done(tp)) {
 				*resetp = 1;
 				return -EBUSY;
 			}
@@ -742,7 +748,9 @@
 		}
 
 		/* Disable transmitter and interrupt.  */
-		tg3_readphy(tp, MII_TG3_EXT_CTRL, &reg32);
+		if (tg3_readphy(tp, MII_TG3_EXT_CTRL, &reg32))
+			continue;
+
 		reg32 |= 0x3000;
 		tg3_writephy(tp, MII_TG3_EXT_CTRL, reg32);
 
@@ -751,7 +759,9 @@
 			     BMCR_FULLDPLX | TG3_BMCR_SPEED1000);
 
 		/* Set to master mode.  */
-		tg3_readphy(tp, MII_TG3_CTRL, &phy9_orig);
+		if (tg3_readphy(tp, MII_TG3_CTRL, &phy9_orig))
+			continue;
+
 		tg3_writephy(tp, MII_TG3_CTRL,
 			     (MII_TG3_CTRL_AS_MASTER |
 			      MII_TG3_CTRL_ENABLE_AS_MASTER));
@@ -789,9 +799,11 @@
 
 	tg3_writephy(tp, MII_TG3_CTRL, phy9_orig);
 
-	tg3_readphy(tp, MII_TG3_EXT_CTRL, &reg32);
-	reg32 &= ~0x3000;
-	tg3_writephy(tp, MII_TG3_EXT_CTRL, reg32);
+	if (!tg3_readphy(tp, MII_TG3_EXT_CTRL, &reg32)) {
+		reg32 &= ~0x3000;
+		tg3_writephy(tp, MII_TG3_EXT_CTRL, reg32);
+	} else if (!err)
+		err = -EBUSY;
 
 	return err;
 }
@@ -855,9 +867,9 @@
 		u32 phy_reg;
 
 		/* Set bit 14 with read-modify-write to preserve other bits */
-		tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0007);
-		tg3_readphy(tp, MII_TG3_AUX_CTRL, &phy_reg);
-		tg3_writephy(tp, MII_TG3_AUX_CTRL, phy_reg | 0x4000);
+		if (!tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0007) &&
+		    !tg3_readphy(tp, MII_TG3_AUX_CTRL, &phy_reg))
+			tg3_writephy(tp, MII_TG3_AUX_CTRL, phy_reg | 0x4000);
 	}
 	tg3_phy_set_wirespeed(tp);
 	return 0;
@@ -889,7 +901,7 @@
 			      GRC_LCLCTRL_GPIO_OUTPUT1));
 			udelay(100);
 		} else {
-			int no_gpio2;
+			u32 no_gpio2;
 			u32 grc_local_ctrl;
 
 			if (tp_peer != tp &&
@@ -897,8 +909,8 @@
 				return;
 
 			/* On 5753 and variants, GPIO2 cannot be used. */
-			no_gpio2 = (tp->nic_sram_data_cfg &
-				    NIC_SRAM_DATA_CFG_NO_GPIO2) != 0;
+			no_gpio2 = tp->nic_sram_data_cfg &
+				    NIC_SRAM_DATA_CFG_NO_GPIO2;
 
 			grc_local_ctrl = GRC_LCLCTRL_GPIO_OE0 |
 					 GRC_LCLCTRL_GPIO_OE1 |
@@ -910,29 +922,17 @@
 						    GRC_LCLCTRL_GPIO_OUTPUT2);
 			}
 			tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl |
-			       grc_local_ctrl);
+						grc_local_ctrl);
 			udelay(100);
 
-			grc_local_ctrl = GRC_LCLCTRL_GPIO_OE0 |
-					 GRC_LCLCTRL_GPIO_OE1 |
-					 GRC_LCLCTRL_GPIO_OE2 |
-					 GRC_LCLCTRL_GPIO_OUTPUT0 |
-					 GRC_LCLCTRL_GPIO_OUTPUT1 |
-					 GRC_LCLCTRL_GPIO_OUTPUT2;
-			if (no_gpio2) {
-				grc_local_ctrl &= ~(GRC_LCLCTRL_GPIO_OE2 |
-						    GRC_LCLCTRL_GPIO_OUTPUT2);
-			}
+			grc_local_ctrl |= GRC_LCLCTRL_GPIO_OUTPUT0;
+
 			tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl |
-			       grc_local_ctrl);
+						grc_local_ctrl);
 			udelay(100);
 
-			grc_local_ctrl = GRC_LCLCTRL_GPIO_OE0 |
-					 GRC_LCLCTRL_GPIO_OE1 |
-					 GRC_LCLCTRL_GPIO_OE2 |
-					 GRC_LCLCTRL_GPIO_OUTPUT0 |
-					 GRC_LCLCTRL_GPIO_OUTPUT1;
 			if (!no_gpio2) {
+				grc_local_ctrl &= ~GRC_LCLCTRL_GPIO_OUTPUT2;
 				tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl |
 				       grc_local_ctrl);
 				udelay(100);
@@ -1252,7 +1252,7 @@
 	};
 }
 
-static int tg3_phy_copper_begin(struct tg3 *tp)
+static void tg3_phy_copper_begin(struct tg3 *tp)
 {
 	u32 new_adv;
 	int i;
@@ -1367,15 +1367,16 @@
 		if (tp->link_config.duplex == DUPLEX_FULL)
 			bmcr |= BMCR_FULLDPLX;
 
-		tg3_readphy(tp, MII_BMCR, &orig_bmcr);
-		if (bmcr != orig_bmcr) {
+		if (!tg3_readphy(tp, MII_BMCR, &orig_bmcr) &&
+		    (bmcr != orig_bmcr)) {
 			tg3_writephy(tp, MII_BMCR, BMCR_LOOPBACK);
 			for (i = 0; i < 1500; i++) {
 				u32 tmp;
 
 				udelay(10);
-				tg3_readphy(tp, MII_BMSR, &tmp);
-				tg3_readphy(tp, MII_BMSR, &tmp);
+				if (tg3_readphy(tp, MII_BMSR, &tmp) ||
+				    tg3_readphy(tp, MII_BMSR, &tmp))
+					continue;
 				if (!(tmp & BMSR_LSTATUS)) {
 					udelay(40);
 					break;
@@ -1388,8 +1389,6 @@
 		tg3_writephy(tp, MII_BMCR,
 			     BMCR_ANENABLE | BMCR_ANRESTART);
 	}
-
-	return 0;
 }
 
 static int tg3_init_5401phy_dsp(struct tg3 *tp)
@@ -1424,7 +1423,9 @@
 {
 	u32 adv_reg, all_mask;
 
-	tg3_readphy(tp, MII_ADVERTISE, &adv_reg);
+	if (tg3_readphy(tp, MII_ADVERTISE, &adv_reg))
+		return 0;
+
 	all_mask = (ADVERTISE_10HALF | ADVERTISE_10FULL |
 		    ADVERTISE_100HALF | ADVERTISE_100FULL);
 	if ((adv_reg & all_mask) != all_mask)
@@ -1432,7 +1433,9 @@
 	if (!(tp->tg3_flags & TG3_FLAG_10_100_ONLY)) {
 		u32 tg3_ctrl;
 
-		tg3_readphy(tp, MII_TG3_CTRL, &tg3_ctrl);
+		if (tg3_readphy(tp, MII_TG3_CTRL, &tg3_ctrl))
+			return 0;
+
 		all_mask = (MII_TG3_CTRL_ADV_1000_HALF |
 			    MII_TG3_CTRL_ADV_1000_FULL);
 		if ((tg3_ctrl & all_mask) != all_mask)
@@ -1472,8 +1475,8 @@
 	     GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) &&
 	    netif_carrier_ok(tp->dev)) {
 		tg3_readphy(tp, MII_BMSR, &bmsr);
-		tg3_readphy(tp, MII_BMSR, &bmsr);
-		if (!(bmsr & BMSR_LSTATUS))
+		if (!tg3_readphy(tp, MII_BMSR, &bmsr) &&
+		    !(bmsr & BMSR_LSTATUS))
 			force_reset = 1;
 	}
 	if (force_reset)
@@ -1481,9 +1484,8 @@
 
 	if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401) {
 		tg3_readphy(tp, MII_BMSR, &bmsr);
-		tg3_readphy(tp, MII_BMSR, &bmsr);
-
-		if (!(tp->tg3_flags & TG3_FLAG_INIT_COMPLETE))
+		if (tg3_readphy(tp, MII_BMSR, &bmsr) ||
+		    !(tp->tg3_flags & TG3_FLAG_INIT_COMPLETE))
 			bmsr = 0;
 
 		if (!(bmsr & BMSR_LSTATUS)) {
@@ -1494,8 +1496,8 @@
 			tg3_readphy(tp, MII_BMSR, &bmsr);
 			for (i = 0; i < 1000; i++) {
 				udelay(10);
-				tg3_readphy(tp, MII_BMSR, &bmsr);
-				if (bmsr & BMSR_LSTATUS) {
+				if (!tg3_readphy(tp, MII_BMSR, &bmsr) &&
+				    (bmsr & BMSR_LSTATUS)) {
 					udelay(40);
 					break;
 				}
@@ -1557,8 +1559,8 @@
 	bmsr = 0;
 	for (i = 0; i < 100; i++) {
 		tg3_readphy(tp, MII_BMSR, &bmsr);
-		tg3_readphy(tp, MII_BMSR, &bmsr);
-		if (bmsr & BMSR_LSTATUS)
+		if (!tg3_readphy(tp, MII_BMSR, &bmsr) &&
+		    (bmsr & BMSR_LSTATUS))
 			break;
 		udelay(40);
 	}
@@ -1569,8 +1571,8 @@
 		tg3_readphy(tp, MII_TG3_AUX_STAT, &aux_stat);
 		for (i = 0; i < 2000; i++) {
 			udelay(10);
-			tg3_readphy(tp, MII_TG3_AUX_STAT, &aux_stat);
-			if (aux_stat)
+			if (!tg3_readphy(tp, MII_TG3_AUX_STAT, &aux_stat) &&
+			    aux_stat)
 				break;
 		}
 
@@ -1581,7 +1583,8 @@
 		bmcr = 0;
 		for (i = 0; i < 200; i++) {
 			tg3_readphy(tp, MII_BMCR, &bmcr);
-			tg3_readphy(tp, MII_BMCR, &bmcr);
+			if (tg3_readphy(tp, MII_BMCR, &bmcr))
+				continue;
 			if (bmcr && bmcr != 0x7fff)
 				break;
 			udelay(10);
@@ -1618,10 +1621,13 @@
 	    (tp->link_config.autoneg == AUTONEG_ENABLE)) {
 		u32 local_adv, remote_adv;
 
-		tg3_readphy(tp, MII_ADVERTISE, &local_adv);
+		if (tg3_readphy(tp, MII_ADVERTISE, &local_adv))
+			local_adv = 0;
 		local_adv &= (ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM);
 
-		tg3_readphy(tp, MII_LPA, &remote_adv);
+		if (tg3_readphy(tp, MII_LPA, &remote_adv))
+			remote_adv = 0;
+
 		remote_adv &= (LPA_PAUSE_CAP | LPA_PAUSE_ASYM);
 
 		/* If we are not advertising full pause capability,
@@ -1640,8 +1646,8 @@
 		tg3_phy_copper_begin(tp);
 
 		tg3_readphy(tp, MII_BMSR, &tmp);
-		tg3_readphy(tp, MII_BMSR, &tmp);
-		if (tmp & BMSR_LSTATUS)
+		if (!tg3_readphy(tp, MII_BMSR, &tmp) &&
+		    (tmp & BMSR_LSTATUS))
 			current_link_up = 1;
 	}
 
@@ -2142,8 +2148,9 @@
 		if (tr32(TG3PCI_DUAL_MAC_CTRL) & DUAL_MAC_CTRL_ID)
 			port_a = 0;
 
-		serdes_cfg = tr32(MAC_SERDES_CFG) &
-			((1 << 23) | (1 << 22) | (1 << 21) | (1 << 20));
+		/* preserve bits 0-11,13,14 for signal pre-emphasis */
+		/* preserve bits 20-23 for voltage regulator */
+		serdes_cfg = tr32(MAC_SERDES_CFG) & 0x00f06fff;
 	}
 
 	sg_dig_ctrl = tr32(SG_DIG_CTRL);
@@ -2154,9 +2161,9 @@
 				u32 val = serdes_cfg;
 
 				if (port_a)
-					val |= 0xc010880;
+					val |= 0xc010000;
 				else
-					val |= 0x4010880;
+					val |= 0x4010000;
 				tw32_f(MAC_SERDES_CFG, val);
 			}
 			tw32_f(SG_DIG_CTRL, 0x01388400);
@@ -2179,7 +2186,7 @@
 
 	if (sg_dig_ctrl != expected_sg_dig_ctrl) {
 		if (workaround)
-			tw32_f(MAC_SERDES_CFG, serdes_cfg | 0xc011880);
+			tw32_f(MAC_SERDES_CFG, serdes_cfg | 0xc011000);
 		tw32_f(SG_DIG_CTRL, expected_sg_dig_ctrl | (1 << 30));
 		udelay(5);
 		tw32_f(SG_DIG_CTRL, expected_sg_dig_ctrl);
@@ -2220,9 +2227,9 @@
 					u32 val = serdes_cfg;
 
 					if (port_a)
-						val |= 0xc010880;
+						val |= 0xc010000;
 					else
-						val |= 0x4010880;
+						val |= 0x4010000;
 
 					tw32_f(MAC_SERDES_CFG, val);
 				}
@@ -2230,8 +2237,12 @@
 				tw32_f(SG_DIG_CTRL, 0x01388400);
 				udelay(40);
 
+				/* Link parallel detection - link is up */
+				/* only if we have PCS_SYNC and not */
+				/* receiving config code words */
 				mac_status = tr32(MAC_STATUS);
-				if (mac_status & MAC_STATUS_PCS_SYNCED) {
+				if ((mac_status & MAC_STATUS_PCS_SYNCED) &&
+				    !(mac_status & MAC_STATUS_RCVD_CFG)) {
 					tg3_setup_flow_control(tp, 0, 0);
 					current_link_up = 1;
 				}
@@ -2702,7 +2713,11 @@
 
 		len = ((desc->idx_len & RXD_LEN_MASK) >> RXD_LEN_SHIFT) - 4; /* omit crc */
 
-		if (len > RX_COPY_THRESHOLD) {
+		if (len > RX_COPY_THRESHOLD 
+			&& tp->rx_offset == 2
+			/* rx_offset != 2 iff this is a 5701 card running
+			 * in PCI-X mode [see tg3_get_invariants()] */
+		) {
 			int skb_size;
 
 			skb_size = tg3_alloc_rx_skb(tp, opaque_key,
@@ -3103,11 +3118,19 @@
 
 		skb->nh.iph->check = 0;
 		skb->nh.iph->tot_len = ntohs(mss + ip_tcp_len + tcp_opt_len);
-		skb->h.th->check = ~csum_tcpudp_magic(skb->nh.iph->saddr,
-						      skb->nh.iph->daddr,
-						      0, IPPROTO_TCP, 0);
+		if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) {
+			skb->h.th->check = 0;
+			base_flags &= ~TXD_FLAG_TCPUDP_CSUM;
+		}
+		else {
+			skb->h.th->check =
+				~csum_tcpudp_magic(skb->nh.iph->saddr,
+						   skb->nh.iph->daddr,
+						   0, IPPROTO_TCP, 0);
+		}
 
-		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) {
+		if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO) ||
+		    (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705)) {
 			if (tcp_opt_len || skb->nh.iph->ihl > 5) {
 				int tsflags;
 
@@ -3174,7 +3197,7 @@
 				would_hit_hwbug = entry + 1;
 			}
 
-			if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750)
+			if (tp->tg3_flags2 & TG3_FLG2_HW_TSO)
 				tg3_set_txd(tp, entry, mapping, len,
 					    base_flags, (i == last)|(mss << 1));
 			else
@@ -4766,7 +4789,7 @@
 	unsigned long cpu_base, cpu_scratch_base, cpu_scratch_size;
 	int err, i;
 
-	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750)
+	if (tp->tg3_flags2 & TG3_FLG2_HW_TSO)
 		return 0;
 
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) {
@@ -4850,9 +4873,8 @@
 		tw32(MAC_ADDR_0_LOW + (i * 8), addr_low);
 	}
 
-	if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700 &&
-	    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701 &&
-	    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) {
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 ||
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) {
 		for (i = 0; i < 12; i++) {
 			tw32(MAC_EXTADDR_0_HIGH + (i * 8), addr_high);
 			tw32(MAC_EXTADDR_0_LOW + (i * 8), addr_low);
@@ -4898,7 +4920,8 @@
 		      (bdinfo_addr + TG3_BDINFO_MAXLEN_FLAGS),
 		       maxlen_flags);
 
-	if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705)
+	if ((GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) &&
+	    (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5750))
 		tg3_write_mem(tp,
 			      (bdinfo_addr + TG3_BDINFO_NIC_ADDR),
 			      nic_addr);
@@ -5200,7 +5223,7 @@
 	}
 
 #if TG3_TSO_SUPPORT != 0
-	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750)
+	if (tp->tg3_flags2 & TG3_FLG2_HW_TSO)
 		rdmac_mode |= (1 << 27);
 #endif
 
@@ -5350,7 +5373,7 @@
 	tw32(RCVDBDI_MODE, RCVDBDI_MODE_ENABLE | RCVDBDI_MODE_INV_RING_SZ);
 	tw32(SNDDATAI_MODE, SNDDATAI_MODE_ENABLE);
 #if TG3_TSO_SUPPORT != 0
-	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750)
+	if (tp->tg3_flags2 & TG3_FLG2_HW_TSO)
 		tw32(SNDDATAI_MODE, SNDDATAI_MODE_ENABLE | 0x8);
 #endif
 	tw32(SNDBDI_MODE, SNDBDI_MODE_ENABLE | SNDBDI_MODE_ATTN_ENABLE);
@@ -5400,8 +5423,10 @@
 	udelay(10);
 
 	if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) {
-		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) {
+		if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) &&
+			!(tp->tg3_flags2 & TG3_FLG2_SERDES_PREEMPHASIS)) {
 			/* Set drive transmission level to 1.2V  */
+			/* only if the signal pre-emphasis bit is not set  */
 			val = tr32(MAC_SERDES_CFG);
 			val &= 0xfffff000;
 			val |= 0x880;
@@ -5430,9 +5455,10 @@
 		u32 tmp;
 
 		/* Clear CRC stats. */
-		tg3_readphy(tp, 0x1e, &tmp);
-		tg3_writephy(tp, 0x1e, tmp | 0x8000);
-		tg3_readphy(tp, 0x14, &tmp);
+		if (!tg3_readphy(tp, 0x1e, &tmp)) {
+			tg3_writephy(tp, 0x1e, tmp | 0x8000);
+			tg3_readphy(tp, 0x14, &tmp);
+		}
 	}
 
 	__tg3_set_rx_mode(tp->dev);
@@ -6022,9 +6048,11 @@
 		u32 val;
 
 		spin_lock_irqsave(&tp->lock, flags);
-		tg3_readphy(tp, 0x1e, &val);
-		tg3_writephy(tp, 0x1e, val | 0x8000);
-		tg3_readphy(tp, 0x14, &val);
+		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);
 
 		tp->phy_crc_errors += val;
@@ -6370,11 +6398,13 @@
 
 static int tg3_get_eeprom_len(struct net_device *dev)
 {
-	return EEPROM_CHIP_SIZE;
+	struct tg3 *tp = netdev_priv(dev);
+
+	return tp->nvram_size;
 }
 
-static int tg3_nvram_read_using_eeprom(struct tg3 *tp,
-					u32 offset, u32 *val);
+static int tg3_nvram_read(struct tg3 *tp, u32 offset, u32 *val);
+
 static int tg3_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, u8 *data)
 {
 	struct tg3 *tp = netdev_priv(dev);
@@ -6386,10 +6416,7 @@
 	len = eeprom->len;
 	eeprom->len = 0;
 
-	ret = tg3_nvram_read_using_eeprom(tp, 0, &eeprom->magic);
-	if (ret)
-		return ret;
-	eeprom->magic = swab32(eeprom->magic);
+	eeprom->magic = TG3_EEPROM_MAGIC;
 
 	if (offset & 3) {
 		/* adjustments to start on required 4 byte boundary */
@@ -6399,9 +6426,10 @@
 			/* i.e. offset=1 len=2 */
 			b_count = len;
 		}
-		ret = tg3_nvram_read_using_eeprom(tp, offset-b_offset, &val);
+		ret = tg3_nvram_read(tp, offset-b_offset, &val);
 		if (ret)
 			return ret;
+		val = cpu_to_le32(val);
 		memcpy(data, ((char*)&val) + b_offset, b_count);
 		len -= b_count;
 		offset += b_count;
@@ -6411,12 +6439,13 @@
 	/* read bytes upto the last 4 byte boundary */
 	pd = &data[eeprom->len];
 	for (i = 0; i < (len - (len & 3)); i += 4) {
-		ret = tg3_nvram_read_using_eeprom(tp, offset + i, 
-				(u32*)(pd + i));
+		ret = tg3_nvram_read(tp, offset + i, &val);
 		if (ret) {
 			eeprom->len += i;
 			return ret;
 		}
+		val = cpu_to_le32(val);
+		memcpy(pd + i, &val, 4);
 	}
 	eeprom->len += i;
 
@@ -6425,15 +6454,72 @@
 		pd = &data[eeprom->len];
 		b_count = len & 3;
 		b_offset = offset + len - b_count;
-		ret = tg3_nvram_read_using_eeprom(tp, b_offset, &val);
+		ret = tg3_nvram_read(tp, b_offset, &val);
 		if (ret)
 			return ret;
+		val = cpu_to_le32(val);
 		memcpy(pd, ((char*)&val), b_count);
 		eeprom->len += b_count;
 	}
 	return 0;
 }
 
+static int tg3_nvram_write_block(struct tg3 *tp, u32 offset, u32 len, u8 *buf); 
+
+static int tg3_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, u8 *data)
+{
+	struct tg3 *tp = netdev_priv(dev);
+	int ret;
+	u32 offset, len, b_offset, odd_len, start, end;
+	u8 *buf;
+
+	if (eeprom->magic != TG3_EEPROM_MAGIC)
+		return -EINVAL;
+
+	offset = eeprom->offset;
+	len = eeprom->len;
+
+	if ((b_offset = (offset & 3))) {
+		/* adjustments to start on required 4 byte boundary */
+		ret = tg3_nvram_read(tp, offset-b_offset, &start);
+		if (ret)
+			return ret;
+		start = cpu_to_le32(start);
+		len += b_offset;
+		offset &= ~3;
+	}
+
+	odd_len = 0;
+	if ((len & 3) && ((len > 4) || (b_offset == 0))) {
+		/* adjustments to end on required 4 byte boundary */
+		odd_len = 1;
+		len = (len + 3) & ~3;
+		ret = tg3_nvram_read(tp, offset+len-4, &end);
+		if (ret)
+			return ret;
+		end = cpu_to_le32(end);
+	}
+
+	buf = data;
+	if (b_offset || odd_len) {
+		buf = kmalloc(len, GFP_KERNEL);
+		if (buf == 0)
+			return -ENOMEM;
+		if (b_offset)
+			memcpy(buf, &start, 4);
+		if (odd_len)
+			memcpy(buf+len-4, &end, 4);
+		memcpy(buf + b_offset, data, eeprom->len);
+	}
+
+	ret = tg3_nvram_write_block(tp, offset, len, buf);
+
+	if (buf != data)
+		kfree(buf);
+
+	return ret;
+}
+
 static int tg3_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
   	struct tg3 *tp = netdev_priv(dev);
@@ -6582,10 +6668,10 @@
 	int r;
   
 	spin_lock_irq(&tp->lock);
-	tg3_readphy(tp, MII_BMCR, &bmcr);
-	tg3_readphy(tp, MII_BMCR, &bmcr);
 	r = -EINVAL;
-	if (bmcr & BMCR_ANENABLE) {
+	tg3_readphy(tp, MII_BMCR, &bmcr);
+	if (!tg3_readphy(tp, MII_BMCR, &bmcr) &&
+	    (bmcr & BMCR_ANENABLE)) {
 		tg3_writephy(tp, MII_BMCR, bmcr | BMCR_ANRESTART);
 		r = 0;
 	}
@@ -6833,6 +6919,7 @@
 	.get_link		= ethtool_op_get_link,
 	.get_eeprom_len		= tg3_get_eeprom_len,
 	.get_eeprom		= tg3_get_eeprom,
+	.set_eeprom		= tg3_set_eeprom,
 	.get_ringparam		= tg3_get_ringparam,
 	.set_ringparam		= tg3_set_ringparam,
 	.get_pauseparam		= tg3_get_pauseparam,
@@ -6852,6 +6939,103 @@
 	.get_ethtool_stats	= tg3_get_ethtool_stats,
 };
 
+static void __devinit tg3_get_eeprom_size(struct tg3 *tp)
+{
+	u32 cursize, val;
+
+	tp->nvram_size = EEPROM_CHIP_SIZE;
+
+	if (tg3_nvram_read(tp, 0, &val) != 0)
+		return;
+
+	if (swab32(val) != TG3_EEPROM_MAGIC)
+		return;
+
+	/*
+	 * Size the chip by reading offsets at increasing powers of two.
+	 * When we encounter our validation signature, we know the addressing
+	 * has wrapped around, and thus have our chip size.
+	 */
+	cursize = 0x800;
+
+	while (cursize < tp->nvram_size) {
+		if (tg3_nvram_read(tp, cursize, &val) != 0)
+			return;
+
+		if (swab32(val) == TG3_EEPROM_MAGIC)
+			break;
+
+		cursize <<= 1;
+	}
+
+	tp->nvram_size = cursize;
+}
+		
+static void __devinit tg3_get_nvram_size(struct tg3 *tp)
+{
+	u32 val;
+
+	if (tg3_nvram_read(tp, 0xf0, &val) == 0) {
+		if (val != 0) {
+			tp->nvram_size = (val >> 16) * 1024;
+			return;
+		}
+	}
+	tp->nvram_size = 0x20000;
+}
+
+static void __devinit tg3_get_nvram_info(struct tg3 *tp)
+{
+	u32 nvcfg1;
+
+	nvcfg1 = tr32(NVRAM_CFG1);
+	if (nvcfg1 & NVRAM_CFG1_FLASHIF_ENAB) {
+		tp->tg3_flags2 |= TG3_FLG2_FLASH;
+	}
+	else {
+		nvcfg1 &= ~NVRAM_CFG1_COMPAT_BYPASS;
+		tw32(NVRAM_CFG1, nvcfg1);
+	}
+
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) {
+		switch (nvcfg1 & NVRAM_CFG1_VENDOR_MASK) {
+			case FLASH_VENDOR_ATMEL_FLASH_BUFFERED:
+				tp->nvram_jedecnum = JEDEC_ATMEL;
+				tp->nvram_pagesize = ATMEL_AT45DB0X1B_PAGE_SIZE;
+				tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+				break;
+			case FLASH_VENDOR_ATMEL_FLASH_UNBUFFERED:
+				tp->nvram_jedecnum = JEDEC_ATMEL;
+                         	tp->nvram_pagesize = ATMEL_AT25F512_PAGE_SIZE;
+				break;
+			case FLASH_VENDOR_ATMEL_EEPROM:
+				tp->nvram_jedecnum = JEDEC_ATMEL;
+                         	tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE;
+				tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+				break;
+			case FLASH_VENDOR_ST:
+				tp->nvram_jedecnum = JEDEC_ST;
+				tp->nvram_pagesize = ST_M45PEX0_PAGE_SIZE;
+				tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+				break;
+			case FLASH_VENDOR_SAIFUN:
+				tp->nvram_jedecnum = JEDEC_SAIFUN;
+				tp->nvram_pagesize = SAIFUN_SA25F0XX_PAGE_SIZE;
+				break;
+			case FLASH_VENDOR_SST_SMALL:
+			case FLASH_VENDOR_SST_LARGE:
+				tp->nvram_jedecnum = JEDEC_SST;
+				tp->nvram_pagesize = SST_25VF0X0_PAGE_SIZE;
+				break;
+		}
+	}
+	else {
+		tp->nvram_jedecnum = JEDEC_ATMEL;
+		tp->nvram_pagesize = ATMEL_AT45DB0X1B_PAGE_SIZE;
+		tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+	}
+}
+
 /* Chips other than 5700/5701 use the NVRAM for fetching info. */
 static void __devinit tg3_nvram_init(struct tg3 *tp)
 {
@@ -6876,32 +7060,27 @@
 
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700 &&
 	    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701) {
-		u32 nvcfg1;
+		tp->tg3_flags |= TG3_FLAG_NVRAM;
 
 		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) {
 			u32 nvaccess = tr32(NVRAM_ACCESS);
 
-			tw32_f(NVRAM_ACCESS, nvaccess | ACCESS_ENABLE);
+			tw32(NVRAM_ACCESS, nvaccess | ACCESS_ENABLE);
 		}
 
-		nvcfg1 = tr32(NVRAM_CFG1);
-
-		tp->tg3_flags |= TG3_FLAG_NVRAM;
-		if (nvcfg1 & NVRAM_CFG1_FLASHIF_ENAB) {
-			if (nvcfg1 & NVRAM_CFG1_BUFFERED_MODE)
-				tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
-		} else {
-			nvcfg1 &= ~NVRAM_CFG1_COMPAT_BYPASS;
-			tw32(NVRAM_CFG1, nvcfg1);
-		}
+		tg3_get_nvram_info(tp);
+		tg3_get_nvram_size(tp);
 
 		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) {
 			u32 nvaccess = tr32(NVRAM_ACCESS);
 
-			tw32_f(NVRAM_ACCESS, nvaccess & ~ACCESS_ENABLE);
+			tw32(NVRAM_ACCESS, nvaccess & ~ACCESS_ENABLE);
 		}
+
 	} else {
 		tp->tg3_flags &= ~(TG3_FLAG_NVRAM | TG3_FLAG_NVRAM_BUFFERED);
+
+		tg3_get_eeprom_size(tp);
 	}
 }
 
@@ -6939,11 +7118,30 @@
 	return 0;
 }
 
-static int __devinit tg3_nvram_read(struct tg3 *tp,
-				    u32 offset, u32 *val)
+#define NVRAM_CMD_TIMEOUT 10000
+
+static int tg3_nvram_exec_cmd(struct tg3 *tp, u32 nvram_cmd)
 {
 	int i;
 
+	tw32(NVRAM_CMD, nvram_cmd);
+	for (i = 0; i < NVRAM_CMD_TIMEOUT; i++) {
+		udelay(10);
+		if (tr32(NVRAM_CMD) & NVRAM_CMD_DONE) {
+			udelay(10);
+			break;
+		}
+	}
+	if (i == NVRAM_CMD_TIMEOUT) {
+		return -EBUSY;
+	}
+	return 0;
+}
+
+static int tg3_nvram_read(struct tg3 *tp, u32 offset, u32 *val)
+{
+	int ret;
+
 	if (tp->tg3_flags2 & TG3_FLG2_SUN_570X) {
 		printk(KERN_ERR PFX "Attempt to do nvram_read on Sun 570X\n");
 		return -EINVAL;
@@ -6952,10 +7150,14 @@
 	if (!(tp->tg3_flags & TG3_FLAG_NVRAM))
 		return tg3_nvram_read_using_eeprom(tp, offset, val);
 
-	if (tp->tg3_flags & TG3_FLAG_NVRAM_BUFFERED)
-		offset = ((offset / NVRAM_BUFFERED_PAGE_SIZE) <<
-			  NVRAM_BUFFERED_PAGE_POS) +
-			(offset % NVRAM_BUFFERED_PAGE_SIZE);
+	if ((tp->tg3_flags & TG3_FLAG_NVRAM_BUFFERED) &&
+		(tp->tg3_flags2 & TG3_FLG2_FLASH) &&
+		(tp->nvram_jedecnum == JEDEC_ATMEL)) {
+
+		offset = ((offset / tp->nvram_pagesize) <<
+			  ATMEL_AT45DB0X1B_PAGE_POS) +
+			(offset % tp->nvram_pagesize);
+	}
 
 	if (offset > NVRAM_ADDR_MSK)
 		return -EINVAL;
@@ -6969,19 +7171,11 @@
 	}
 
 	tw32(NVRAM_ADDR, offset);
-	tw32(NVRAM_CMD,
-	     NVRAM_CMD_RD | NVRAM_CMD_GO |
-	     NVRAM_CMD_FIRST | NVRAM_CMD_LAST | NVRAM_CMD_DONE);
+	ret = tg3_nvram_exec_cmd(tp, NVRAM_CMD_RD | NVRAM_CMD_GO |
+		NVRAM_CMD_FIRST | NVRAM_CMD_LAST | NVRAM_CMD_DONE);
 
-	/* Wait for done bit to clear. */
-	for (i = 0; i < 1000; i++) {
-		udelay(10);
-		if (tr32(NVRAM_CMD) & NVRAM_CMD_DONE) {
-			udelay(10);
-			*val = swab32(tr32(NVRAM_RDDATA));
-			break;
-		}
-	}
+	if (ret == 0)
+		*val = swab32(tr32(NVRAM_RDDATA));
 
 	tg3_nvram_unlock(tp);
 
@@ -6991,10 +7185,268 @@
 		tw32_f(NVRAM_ACCESS, nvaccess & ~ACCESS_ENABLE);
 	}
 
-	if (i >= 1000)
-		return -EBUSY;
+	return ret;
+}
 
-	return 0;
+static int tg3_nvram_write_block_using_eeprom(struct tg3 *tp,
+				    u32 offset, u32 len, u8 *buf)
+{
+	int i, j, rc = 0;
+	u32 val;
+
+	for (i = 0; i < len; i += 4) {
+		u32 addr, data;
+
+		addr = offset + i;
+
+		memcpy(&data, buf + i, 4);
+
+		tw32(GRC_EEPROM_DATA, cpu_to_le32(data));
+
+		val = tr32(GRC_EEPROM_ADDR);
+		tw32(GRC_EEPROM_ADDR, val | EEPROM_ADDR_COMPLETE);
+
+		val &= ~(EEPROM_ADDR_ADDR_MASK | EEPROM_ADDR_DEVID_MASK |
+			EEPROM_ADDR_READ);
+		tw32(GRC_EEPROM_ADDR, val |
+			(0 << EEPROM_ADDR_DEVID_SHIFT) |
+			(addr & EEPROM_ADDR_ADDR_MASK) |
+			EEPROM_ADDR_START |
+			EEPROM_ADDR_WRITE);
+		
+		for (j = 0; j < 10000; j++) {
+			val = tr32(GRC_EEPROM_ADDR);
+
+			if (val & EEPROM_ADDR_COMPLETE)
+				break;
+			udelay(100);
+		}
+		if (!(val & EEPROM_ADDR_COMPLETE)) {
+			rc = -EBUSY;
+			break;
+		}
+	}
+
+	return rc;
+}
+
+/* offset and length are dword aligned */
+static int tg3_nvram_write_block_unbuffered(struct tg3 *tp, u32 offset, u32 len,
+		u8 *buf)
+{
+	int ret = 0;
+	u32 pagesize = tp->nvram_pagesize;
+	u32 pagemask = pagesize - 1;
+	u32 nvram_cmd;
+	u8 *tmp;
+
+	tmp = kmalloc(pagesize, GFP_KERNEL);
+	if (tmp == NULL)
+		return -ENOMEM;
+
+	while (len) {
+		int j;
+		u32 phy_addr, page_off, size, nvaccess;
+
+		phy_addr = offset & ~pagemask;
+	
+		for (j = 0; j < pagesize; j += 4) {
+			if ((ret = tg3_nvram_read(tp, phy_addr + j,
+						(u32 *) (tmp + j))))
+				break;
+		}
+		if (ret)
+			break;
+
+	        page_off = offset & pagemask;
+		size = pagesize;
+		if (len < size)
+			size = len;
+
+		len -= size;
+
+		memcpy(tmp + page_off, buf, size);
+
+		offset = offset + (pagesize - page_off);
+
+		nvaccess = tr32(NVRAM_ACCESS);
+		tw32_f(NVRAM_ACCESS, nvaccess | ACCESS_ENABLE);
+
+		/*
+		 * Before we can erase the flash page, we need
+		 * to issue a special "write enable" command.
+		 */
+		nvram_cmd = NVRAM_CMD_WREN | NVRAM_CMD_GO | NVRAM_CMD_DONE;
+
+		if (tg3_nvram_exec_cmd(tp, nvram_cmd))
+			break;
+
+		/* Erase the target page */
+		tw32(NVRAM_ADDR, phy_addr);
+
+		nvram_cmd = NVRAM_CMD_GO | NVRAM_CMD_DONE | NVRAM_CMD_WR |
+			NVRAM_CMD_FIRST | NVRAM_CMD_LAST | NVRAM_CMD_ERASE;
+
+	        if (tg3_nvram_exec_cmd(tp, nvram_cmd))
+			break;
+
+		/* Issue another write enable to start the write. */
+		nvram_cmd = NVRAM_CMD_WREN | NVRAM_CMD_GO | NVRAM_CMD_DONE;
+
+		if (tg3_nvram_exec_cmd(tp, nvram_cmd))
+			break;
+
+		for (j = 0; j < pagesize; j += 4) {
+			u32 data;
+
+	    		data = *((u32 *) (tmp + j));
+			tw32(NVRAM_WRDATA, cpu_to_be32(data));
+
+			tw32(NVRAM_ADDR, phy_addr + j);
+
+			nvram_cmd = NVRAM_CMD_GO | NVRAM_CMD_DONE |
+				NVRAM_CMD_WR;
+
+			if (j == 0)
+				nvram_cmd |= NVRAM_CMD_FIRST;
+			else if (j == (pagesize - 4))
+				nvram_cmd |= NVRAM_CMD_LAST;
+
+			if ((ret = tg3_nvram_exec_cmd(tp, nvram_cmd)))
+				break;
+		}
+		if (ret)
+			break;
+	}
+
+	nvram_cmd = NVRAM_CMD_WRDI | NVRAM_CMD_GO | NVRAM_CMD_DONE;
+	tg3_nvram_exec_cmd(tp, nvram_cmd);
+
+	kfree(tmp);
+
+	return ret;
+}
+
+/* offset and length are dword aligned */
+static int tg3_nvram_write_block_buffered(struct tg3 *tp, u32 offset, u32 len,
+		u8 *buf)
+{
+	int i, ret = 0;
+
+	for (i = 0; i < len; i += 4, offset += 4) {
+		u32 data, page_off, phy_addr, nvram_cmd;
+
+		memcpy(&data, buf + i, 4);
+		tw32(NVRAM_WRDATA, cpu_to_be32(data));
+
+	        page_off = offset % tp->nvram_pagesize;
+
+		if ((tp->tg3_flags2 & TG3_FLG2_FLASH) &&
+			(tp->nvram_jedecnum == JEDEC_ATMEL)) {
+
+			phy_addr = ((offset / tp->nvram_pagesize) <<
+				    ATMEL_AT45DB0X1B_PAGE_POS) + page_off;
+		}
+		else {
+			phy_addr = offset;
+		}
+
+		tw32(NVRAM_ADDR, phy_addr);
+
+		nvram_cmd = NVRAM_CMD_GO | NVRAM_CMD_DONE | NVRAM_CMD_WR;
+
+	        if ((page_off == 0) || (i == 0))
+			nvram_cmd |= NVRAM_CMD_FIRST;
+		else if (page_off == (tp->nvram_pagesize - 4))
+			nvram_cmd |= NVRAM_CMD_LAST;
+
+		if (i == (len - 4))
+			nvram_cmd |= NVRAM_CMD_LAST;
+
+		if ((tp->nvram_jedecnum == JEDEC_ST) &&
+			(nvram_cmd & NVRAM_CMD_FIRST)) {
+
+			if ((ret = tg3_nvram_exec_cmd(tp,
+				NVRAM_CMD_WREN | NVRAM_CMD_GO |
+				NVRAM_CMD_DONE)))
+
+				break;
+		}
+		if (!(tp->tg3_flags2 & TG3_FLG2_FLASH)) {
+			/* We always do complete word writes to eeprom. */
+			nvram_cmd |= (NVRAM_CMD_FIRST | NVRAM_CMD_LAST);
+		}
+
+		if ((ret = tg3_nvram_exec_cmd(tp, nvram_cmd)))
+			break;
+	}
+	return ret;
+}
+
+/* offset and length are dword aligned */
+static int tg3_nvram_write_block(struct tg3 *tp, u32 offset, u32 len, u8 *buf)
+{
+	int ret;
+
+	if (tp->tg3_flags2 & TG3_FLG2_SUN_570X) {
+		printk(KERN_ERR PFX "Attempt to do nvram_write on Sun 570X\n");
+		return -EINVAL;
+	}
+
+	if (tp->tg3_flags & TG3_FLAG_EEPROM_WRITE_PROT) {
+		tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl |
+		       GRC_LCLCTRL_GPIO_OE1);
+		udelay(40);
+	}
+
+	if (!(tp->tg3_flags & TG3_FLAG_NVRAM)) {
+		ret = tg3_nvram_write_block_using_eeprom(tp, offset, len, buf);
+	}
+	else {
+		u32 grc_mode;
+
+		tg3_nvram_lock(tp);
+
+		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) {
+			u32 nvaccess = tr32(NVRAM_ACCESS);
+
+			tw32(NVRAM_ACCESS, nvaccess | ACCESS_ENABLE);
+
+			tw32(NVRAM_WRITE1, 0x406);
+		}
+
+		grc_mode = tr32(GRC_MODE);
+		tw32(GRC_MODE, grc_mode | GRC_MODE_NVRAM_WR_ENABLE);
+
+		if ((tp->tg3_flags & TG3_FLAG_NVRAM_BUFFERED) ||
+			!(tp->tg3_flags2 & TG3_FLG2_FLASH)) {
+
+			ret = tg3_nvram_write_block_buffered(tp, offset, len,
+				buf);
+		}
+		else {
+			ret = tg3_nvram_write_block_unbuffered(tp, offset, len,
+				buf);
+		}
+
+		grc_mode = tr32(GRC_MODE);
+		tw32(GRC_MODE, grc_mode & ~GRC_MODE_NVRAM_WR_ENABLE);
+
+		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) {
+			u32 nvaccess = tr32(NVRAM_ACCESS);
+
+			tw32(NVRAM_ACCESS, nvaccess & ~ACCESS_ENABLE);
+		}
+		tg3_nvram_unlock(tp);
+	}
+
+	if (tp->tg3_flags & TG3_FLAG_EEPROM_WRITE_PROT) {
+		tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl |
+		       GRC_LCLCTRL_GPIO_OE1 | GRC_LCLCTRL_GPIO_OUTPUT1);
+		udelay(40);
+	}
+
+	return ret;
 }
 
 struct subsys_tbl_ent {
@@ -7068,11 +7520,19 @@
 	tg3_read_mem(tp, NIC_SRAM_DATA_SIG, &val);
 	if (val == NIC_SRAM_DATA_SIG_MAGIC) {
 		u32 nic_cfg, led_cfg;
-		u32 nic_phy_id, cfg2;
+		u32 nic_phy_id, ver, cfg2 = 0;
 
 		tg3_read_mem(tp, NIC_SRAM_DATA_CFG, &nic_cfg);
 		tp->nic_sram_data_cfg = nic_cfg;
 
+		tg3_read_mem(tp, NIC_SRAM_DATA_VER, &ver);
+		ver >>= NIC_SRAM_DATA_VER_SHIFT;
+		if ((GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700) &&
+		    (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701) &&
+		    (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5703) &&
+		    (ver > 0) && (ver < 0x100))
+			tg3_read_mem(tp, NIC_SRAM_DATA_CFG_2, &cfg2);
+
 		eeprom_signature_found = 1;
 
 		if ((nic_cfg & NIC_SRAM_DATA_CFG_PHY_TYPE_MASK) ==
@@ -7091,8 +7551,7 @@
 			eeprom_phy_id = 0;
 
 		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) {
-			tg3_read_mem(tp, NIC_SRAM_DATA_CFG_2, &led_cfg);
-			led_cfg &= (NIC_SRAM_DATA_CFG_LED_MODE_MASK |
+			led_cfg = cfg2 & (NIC_SRAM_DATA_CFG_LED_MODE_MASK |
 				    SHASTA_EXT_LED_MODE_MASK);
 		} else
 			led_cfg = nic_cfg & NIC_SRAM_DATA_CFG_LED_MODE_MASK;
@@ -7137,9 +7596,8 @@
 		    tp->pdev->subsystem_vendor == PCI_VENDOR_ID_DELL)
 			tp->led_ctrl = LED_CTRL_MODE_PHY_2;
 
-		if (((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703) ||
-		     (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) ||
-		     (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705)) &&
+		if ((GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700) &&
+		    (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701) &&
 		    (nic_cfg & NIC_SRAM_DATA_CFG_EEPROM_WP))
 			tp->tg3_flags |= TG3_FLAG_EEPROM_WRITE_PROT;
 
@@ -7151,9 +7609,13 @@
 		if (nic_cfg & NIC_SRAM_DATA_CFG_FIBER_WOL)
 			tp->tg3_flags |= TG3_FLAG_SERDES_WOL_CAP;
 
-		tg3_read_mem(tp, NIC_SRAM_DATA_PHY_ID, &cfg2);
 		if (cfg2 & (1 << 17))
 			tp->tg3_flags2 |= TG3_FLG2_CAPACITIVE_COUPLING;
+
+		/* serdes signal pre-emphasis in register 0x590 set by */
+		/* bootcode if bit 18 is set */
+		if (cfg2 & (1 << 18))
+			tp->tg3_flags2 |= TG3_FLG2_SERDES_PREEMPHASIS;
 	}
 
 	/* Reading the PHY ID register can conflict with ASF
@@ -7209,9 +7671,8 @@
 		u32 bmsr, adv_reg, tg3_ctrl;
 
 		tg3_readphy(tp, MII_BMSR, &bmsr);
-		tg3_readphy(tp, MII_BMSR, &bmsr);
-
-		if (bmsr & BMSR_LSTATUS)
+		if (!tg3_readphy(tp, MII_BMSR, &bmsr) &&
+		    (bmsr & BMSR_LSTATUS))
 			goto skip_phy_reset;
 		    
 		err = tg3_phy_reset(tp);
@@ -7435,6 +7896,9 @@
 	tp->pci_hdr_type     = (cacheline_sz_reg >> 16) & 0xff;
 	tp->pci_bist         = (cacheline_sz_reg >> 24) & 0xff;
 
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750)
+		tp->tg3_flags2 |= TG3_FLG2_HW_TSO;
+
 	if (pci_find_capability(tp->pdev, PCI_CAP_ID_EXP) != 0)
 		tp->tg3_flags2 |= TG3_FLG2_PCI_EXPRESS;
 
@@ -8330,11 +8794,13 @@
 	}
 
 #if TG3_TSO_SUPPORT != 0
-	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
+	if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) {
+		tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE;
+	}
+	else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
 	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701 ||
 	    tp->pci_chip_rev_id == CHIPREV_ID_5705_A0 ||
-	    ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) != 0 &&
-	     GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5750)) {
+	    (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) != 0) {
 		tp->tg3_flags2 &= ~TG3_FLG2_TSO_CAPABLE;
 	} else {
 		tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE;
diff -Nru a/drivers/net/tg3.h b/drivers/net/tg3.h
--- a/drivers/net/tg3.h	2005-03-01 23:38:53 -08:00
+++ b/drivers/net/tg3.h	2005-03-01 23:38:53 -08:00
@@ -1274,6 +1274,7 @@
 #define  GRC_MODE_HOST_STACKUP		0x00010000
 #define  GRC_MODE_HOST_SENDBDS		0x00020000
 #define  GRC_MODE_NO_TX_PHDR_CSUM	0x00100000
+#define  GRC_MODE_NVRAM_WR_ENABLE	0x00200000
 #define  GRC_MODE_NO_RX_PHDR_CSUM	0x00800000
 #define  GRC_MODE_IRQ_ON_TX_CPU_ATTN	0x01000000
 #define  GRC_MODE_IRQ_ON_RX_CPU_ATTN	0x02000000
@@ -1366,6 +1367,8 @@
 #define  NVRAM_CMD_ERASE		 0x00000040
 #define  NVRAM_CMD_FIRST		 0x00000080
 #define  NVRAM_CMD_LAST			 0x00000100
+#define  NVRAM_CMD_WREN			 0x00010000
+#define  NVRAM_CMD_WRDI			 0x00020000
 #define NVRAM_STAT			0x00007004
 #define NVRAM_WRDATA			0x00007008
 #define NVRAM_ADDR			0x0000700c
@@ -1375,8 +1378,18 @@
 #define  NVRAM_CFG1_FLASHIF_ENAB	 0x00000001
 #define  NVRAM_CFG1_BUFFERED_MODE	 0x00000002
 #define  NVRAM_CFG1_PASS_THRU		 0x00000004
+#define  NVRAM_CFG1_STATUS_BITS		 0x00000070
 #define  NVRAM_CFG1_BIT_BANG		 0x00000008
+#define  NVRAM_CFG1_FLASH_SIZE		 0x02000000
 #define  NVRAM_CFG1_COMPAT_BYPASS	 0x80000000
+#define  NVRAM_CFG1_VENDOR_MASK		 0x03000003
+#define  FLASH_VENDOR_ATMEL_EEPROM	 0x02000000
+#define  FLASH_VENDOR_ATMEL_FLASH_BUFFERED	 0x02000003
+#define  FLASH_VENDOR_ATMEL_FLASH_UNBUFFERED	 0x00000003
+#define  FLASH_VENDOR_ST			 0x03000001
+#define  FLASH_VENDOR_SAIFUN		 0x01000003
+#define  FLASH_VENDOR_SST_SMALL		 0x00000001
+#define  FLASH_VENDOR_SST_LARGE		 0x02000001
 #define NVRAM_CFG2			0x00007018
 #define NVRAM_CFG3			0x0000701c
 #define NVRAM_SWARB			0x00007020
@@ -1396,15 +1409,16 @@
 #define  SWARB_REQ1			 0x00002000
 #define  SWARB_REQ2			 0x00004000
 #define  SWARB_REQ3			 0x00008000
-#define    NVRAM_BUFFERED_PAGE_SIZE	   264
-#define    NVRAM_BUFFERED_PAGE_POS	   9
 #define NVRAM_ACCESS			0x00007024
 #define  ACCESS_ENABLE			 0x00000001
 #define  ACCESS_WR_ENABLE		 0x00000002
-/* 0x7024 --> 0x7400 unused */
+#define NVRAM_WRITE1			0x00007028
+/* 0x702c --> 0x7400 unused */
 
 /* 0x7400 --> 0x8000 unused */
 
+#define TG3_EEPROM_MAGIC		0x669955aa
+
 /* 32K Window into NIC internal memory */
 #define NIC_SRAM_WIN_BASE		0x00008000
 
@@ -1438,6 +1452,9 @@
 #define  NIC_SRAM_DATA_CFG_FIBER_WOL		 0x00004000
 #define  NIC_SRAM_DATA_CFG_NO_GPIO2		 0x00100000
 
+#define NIC_SRAM_DATA_VER			0x00000b5c
+#define  NIC_SRAM_DATA_VER_SHIFT		 16
+
 #define NIC_SRAM_DATA_PHY_ID		0x00000b74
 #define  NIC_SRAM_DATA_PHY_ID1_MASK	 0xffff0000
 #define  NIC_SRAM_DATA_PHY_ID2_MASK	 0x0000ffff
@@ -2090,6 +2107,9 @@
 #define TG3_FLG2_PHY_JUST_INITTED	0x00001000
 #define TG3_FLG2_PHY_SERDES		0x00002000
 #define TG3_FLG2_CAPACITIVE_COUPLING	0x00004000
+#define TG3_FLG2_FLASH			0x00008000
+#define TG3_FLG2_HW_TSO			0x00010000
+#define TG3_FLG2_SERDES_PREEMPHASIS	0x00020000
 
 	u32				split_mode_max_reqs;
 #define SPLIT_MODE_5704_MAX_REQ		3
@@ -2163,6 +2183,34 @@
 	struct tg3_hw_stats		*hw_stats;
 	dma_addr_t			stats_mapping;
 	struct work_struct		reset_task;
+
+	u32				nvram_size;
+	u32				nvram_pagesize;
+	u32				nvram_jedecnum;
+
+#define JEDEC_ATMEL			0x1f
+#define JEDEC_ST			0x20
+#define JEDEC_SAIFUN			0x4f
+#define JEDEC_SST			0xbf
+
+#define ATMEL_AT24C64_CHIP_SIZE		(64 * 1024)
+#define ATMEL_AT24C64_PAGE_SIZE		(32)
+
+#define ATMEL_AT24C512_CHIP_SIZE	(512 * 1024)
+#define ATMEL_AT24C512_PAGE_SIZE	(128)
+
+#define ATMEL_AT45DB0X1B_PAGE_POS	9
+#define ATMEL_AT45DB0X1B_PAGE_SIZE	264
+
+#define ATMEL_AT25F512_PAGE_SIZE	256
+
+#define ST_M45PEX0_PAGE_SIZE		256
+
+#define SAIFUN_SA25F0XX_PAGE_SIZE	256
+
+#define SST_25VF0X0_PAGE_SIZE		4098
+
+
 };
 
 #endif /* !(_T3_H) */
diff -Nru a/drivers/net/tlan.c b/drivers/net/tlan.c
--- a/drivers/net/tlan.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/net/tlan.c	2005-03-01 23:38:52 -08:00
@@ -198,16 +198,6 @@
 MODULE_DESCRIPTION("Driver for TI ThunderLAN based ethernet PCI adapters");
 MODULE_LICENSE("GPL");
 
-MODULE_PARM(aui, "1-" __MODULE_STRING(MAX_TLAN_BOARDS) "i");
-MODULE_PARM(duplex, "1-" __MODULE_STRING(MAX_TLAN_BOARDS) "i");
-MODULE_PARM(speed, "1-" __MODULE_STRING(MAX_TLAN_BOARDS) "i");
-MODULE_PARM(debug, "i");
-MODULE_PARM(bbuf, "i");
-MODULE_PARM_DESC(aui, "ThunderLAN use AUI port(s) (0-1)");
-MODULE_PARM_DESC(duplex, "ThunderLAN duplex setting(s) (0-default, 1-half, 2-full)");
-MODULE_PARM_DESC(speed, "ThunderLAN port speen setting(s) (0,10,100)");
-MODULE_PARM_DESC(debug, "ThunderLAN debug mask");
-MODULE_PARM_DESC(bbuf, "ThunderLAN use big buffer (0-1)");
 
 /* Define this to enable Link beat monitoring */
 #undef MONITOR
@@ -223,13 +213,11 @@
 static  int tlan_have_pci;
 static  int tlan_have_eisa;
 
-const char *media[] = {
+static const char *media[] = {
 	"10BaseT-HD ", "10BaseT-FD ","100baseTx-HD ", 
 	"100baseTx-FD", "100baseT4", NULL
 };
 
-int media_map[] = { 0x0020, 0x0040, 0x0080, 0x0100, 0x0200,};
-
 static struct board {
 	const char	*deviceLabel;
 	u32	   	flags;
@@ -382,7 +370,7 @@
 static inline void
 TLan_SetTimer( struct net_device *dev, u32 ticks, u32 type )
 {
-	TLanPrivateInfo *priv = dev->priv;
+	TLanPrivateInfo *priv = netdev_priv(dev);
 	unsigned long flags = 0;
 	
 	if (!in_irq())
@@ -438,7 +426,7 @@
 static void __devexit tlan_remove_one( struct pci_dev *pdev)
 {
 	struct net_device *dev = pci_get_drvdata( pdev );
-	TLanPrivateInfo	*priv = dev->priv;
+	TLanPrivateInfo	*priv = netdev_priv(dev);
 	
 	unregister_netdev( dev );
 
@@ -557,7 +545,7 @@
 	SET_MODULE_OWNER(dev);
 	SET_NETDEV_DEV(dev, &pdev->dev);
 	
-	priv = dev->priv;
+	priv = netdev_priv(dev);
 
 	priv->pciDev = pdev;
 	
@@ -693,7 +681,7 @@
 	
 	while( tlan_have_eisa ) {
 		dev = TLan_Eisa_Devices;
-		priv = dev->priv;
+		priv = netdev_priv(dev);
 		if (priv->dmaStorage) {
 			pci_free_consistent(priv->pciDev, priv->dmaSize, priv->dmaStorage, priv->dmaStorageDMA );
 		}
@@ -854,7 +842,7 @@
 	int		i;
 	TLanPrivateInfo	*priv;
 
-	priv = dev->priv;
+	priv = netdev_priv(dev);
 	
 	if ( bbuf ) {
 		dma_size = ( TLAN_NUM_RX_LISTS + TLAN_NUM_TX_LISTS )
@@ -937,7 +925,7 @@
 
 static int TLan_Open( struct net_device *dev )
 {
-	TLanPrivateInfo	*priv = dev->priv;
+	TLanPrivateInfo	*priv = netdev_priv(dev);
 	int		err;
 	
 	priv->tlanRev = TLan_DioRead8( dev->base_addr, TLAN_DEF_REVISION );
@@ -983,7 +971,7 @@
 
 static int TLan_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
-	TLanPrivateInfo *priv = dev->priv;
+	TLanPrivateInfo *priv = netdev_priv(dev);
 	struct mii_ioctl_data *data = if_mii(rq);
 	u32 phy   = priv->phy[priv->phyNum];
 	
@@ -1062,7 +1050,7 @@
 
 static int TLan_StartTx( struct sk_buff *skb, struct net_device *dev )
 {
-	TLanPrivateInfo *priv = dev->priv;
+	TLanPrivateInfo *priv = netdev_priv(dev);
 	TLanList	*tail_list;
 	dma_addr_t	tail_list_phys;
 	u8		*tail_buffer;
@@ -1170,7 +1158,7 @@
 	TLanPrivateInfo *priv;
 
 	dev = dev_id;
-	priv = dev->priv;
+	priv = netdev_priv(dev);
 
 	spin_lock(&priv->lock);
 
@@ -1211,7 +1199,7 @@
 
 static int TLan_Close(struct net_device *dev)
 {
-	TLanPrivateInfo *priv = dev->priv;
+	TLanPrivateInfo *priv = netdev_priv(dev);
 
 	netif_stop_queue(dev);
 	priv->neg_be_verbose = 0;
@@ -1251,7 +1239,7 @@
 
 static struct net_device_stats *TLan_GetStats( struct net_device *dev )
 {
-	TLanPrivateInfo	*priv = dev->priv;
+	TLanPrivateInfo	*priv = netdev_priv(dev);
 	int i;
 
 	/* Should only read stats if open ? */
@@ -1270,7 +1258,7 @@
 			TLan_PrintList( priv->txList + i, "TX", i );
 	}
 	
-	return ( &( (TLanPrivateInfo *) dev->priv )->stats );
+	return ( &( (TLanPrivateInfo *) netdev_priv(dev) )->stats );
 
 } /* TLan_GetStats */
 
@@ -1405,7 +1393,7 @@
 
 u32 TLan_HandleTxEOF( struct net_device *dev, u16 host_int )
 {
-	TLanPrivateInfo	*priv = dev->priv;
+	TLanPrivateInfo	*priv = netdev_priv(dev);
 	int		eoc = 0;
 	TLanList	*head_list;
 	dma_addr_t	head_list_phys;
@@ -1527,7 +1515,7 @@
 
 u32 TLan_HandleRxEOF( struct net_device *dev, u16 host_int )
 {
-	TLanPrivateInfo	*priv = dev->priv;
+	TLanPrivateInfo	*priv = netdev_priv(dev);
 	u32		ack = 0;
 	int		eoc = 0;
 	u8		*head_buffer;
@@ -1694,7 +1682,7 @@
 
 u32 TLan_HandleTxEOC( struct net_device *dev, u16 host_int )
 {
-	TLanPrivateInfo	*priv = dev->priv;
+	TLanPrivateInfo	*priv = netdev_priv(dev);
 	TLanList		*head_list;
 	dma_addr_t		head_list_phys;
 	u32			ack = 1;
@@ -1742,7 +1730,7 @@
 
 u32 TLan_HandleStatusCheck( struct net_device *dev, u16 host_int )
 {	
-	TLanPrivateInfo	*priv = dev->priv;
+	TLanPrivateInfo	*priv = netdev_priv(dev);
 	u32		ack;
 	u32		error;
 	u8		net_sts;
@@ -1817,7 +1805,7 @@
 
 u32 TLan_HandleRxEOC( struct net_device *dev, u16 host_int )
 {
-	TLanPrivateInfo	*priv = dev->priv;
+	TLanPrivateInfo	*priv = netdev_priv(dev);
 	dma_addr_t	head_list_phys;
 	u32		ack = 1;
 
@@ -1878,7 +1866,7 @@
 void TLan_Timer( unsigned long data )
 {
 	struct net_device	*dev = (struct net_device *) data;
-	TLanPrivateInfo	*priv = dev->priv;
+	TLanPrivateInfo	*priv = netdev_priv(dev);
 	u32		elapsed;
 	unsigned long	flags = 0;
 
@@ -1958,7 +1946,7 @@
 
 void TLan_ResetLists( struct net_device *dev )
 {
-	TLanPrivateInfo *priv = dev->priv;
+	TLanPrivateInfo *priv = netdev_priv(dev);
 	int		i;
 	TLanList	*list;
 	dma_addr_t	list_phys;
@@ -2018,7 +2006,7 @@
 
 void TLan_FreeLists( struct net_device *dev )
 {
-	TLanPrivateInfo *priv = dev->priv;
+	TLanPrivateInfo *priv = netdev_priv(dev);
 	int		i;
 	TLanList	*list;
 	struct sk_buff	*skb;
@@ -2138,7 +2126,7 @@
 
 void TLan_ReadAndClearStats( struct net_device *dev, int record )
 {
-	TLanPrivateInfo	*priv = dev->priv;
+	TLanPrivateInfo	*priv = netdev_priv(dev);
 	u32		tx_good, tx_under;
 	u32		rx_good, rx_over;
 	u32		def_tx, crc, code;
@@ -2214,7 +2202,7 @@
 void
 TLan_ResetAdapter( struct net_device *dev )
 {
-	TLanPrivateInfo	*priv = dev->priv;
+	TLanPrivateInfo	*priv = netdev_priv(dev);
 	int		i;
 	u32		addr;
 	u32		data;
@@ -2300,7 +2288,7 @@
 void
 TLan_FinishReset( struct net_device *dev )
 {
-	TLanPrivateInfo	*priv = dev->priv;
+	TLanPrivateInfo	*priv = netdev_priv(dev);
 	u8		data;
 	u32		phy;
 	u8		sio;
@@ -2464,7 +2452,7 @@
 
 void TLan_PhyPrint( struct net_device *dev )
 {
-	TLanPrivateInfo *priv = dev->priv;
+	TLanPrivateInfo *priv = netdev_priv(dev);
 	u16 i, data0, data1, data2, data3, phy;
 
 	phy = priv->phy[priv->phyNum];
@@ -2513,7 +2501,7 @@
 
 void TLan_PhyDetect( struct net_device *dev )
 {
-	TLanPrivateInfo *priv = dev->priv;
+	TLanPrivateInfo *priv = netdev_priv(dev);
 	u16		control;
 	u16		hi;
 	u16		lo;
@@ -2560,7 +2548,7 @@
 
 void TLan_PhyPowerDown( struct net_device *dev )
 {
-	TLanPrivateInfo	*priv = dev->priv;
+	TLanPrivateInfo	*priv = netdev_priv(dev);
 	u16		value;
 
 	TLAN_DBG( TLAN_DEBUG_GNRL, "%s: Powering down PHY(s).\n", dev->name );
@@ -2585,7 +2573,7 @@
 
 void TLan_PhyPowerUp( struct net_device *dev )
 {
-	TLanPrivateInfo	*priv = dev->priv;
+	TLanPrivateInfo	*priv = netdev_priv(dev);
 	u16		value;
 
 	TLAN_DBG( TLAN_DEBUG_GNRL, "%s: Powering up PHY.\n", dev->name );
@@ -2606,7 +2594,7 @@
 
 void TLan_PhyReset( struct net_device *dev )
 {
-	TLanPrivateInfo	*priv = dev->priv;
+	TLanPrivateInfo	*priv = netdev_priv(dev);
 	u16		phy;
 	u16		value;
 
@@ -2634,7 +2622,7 @@
 
 void TLan_PhyStartLink( struct net_device *dev )
 {
-	TLanPrivateInfo	*priv = dev->priv;
+	TLanPrivateInfo	*priv = netdev_priv(dev);
 	u16		ability;
 	u16		control;
 	u16		data;
@@ -2721,7 +2709,7 @@
 
 void TLan_PhyFinishAutoNeg( struct net_device *dev )
 {
-	TLanPrivateInfo	*priv = dev->priv;
+	TLanPrivateInfo	*priv = netdev_priv(dev);
 	u16		an_adv;
 	u16		an_lpa;
 	u16		data;
@@ -2805,7 +2793,7 @@
 
 void TLan_PhyMonitor( struct net_device *dev )
 {
-	TLanPrivateInfo *priv = dev->priv;
+	TLanPrivateInfo *priv = netdev_priv(dev);
 	u16     phy;
 	u16     phy_status;
 
@@ -2882,7 +2870,7 @@
  	u32	i;
 	int	err;
 	int	minten;
-	TLanPrivateInfo *priv = dev->priv;
+	TLanPrivateInfo *priv = netdev_priv(dev);
 	unsigned long flags = 0;
 
 	err = FALSE;
@@ -3051,7 +3039,7 @@
 	u16	sio;
 	int	minten;
 	unsigned long flags = 0;
-	TLanPrivateInfo *priv = dev->priv;
+	TLanPrivateInfo *priv = netdev_priv(dev);
 
 	outw(TLAN_NET_SIO, dev->base_addr + TLAN_DIO_ADR);
 	sio = dev->base_addr + TLAN_DIO_DATA + TLAN_NET_SIO;
@@ -3278,7 +3266,7 @@
 int TLan_EeReadByte( struct net_device *dev, u8 ee_addr, u8 *data )
 {
 	int err;
-	TLanPrivateInfo *priv = dev->priv;
+	TLanPrivateInfo *priv = netdev_priv(dev);
 	unsigned long flags = 0;
 	int ret=0;
 
diff -Nru a/drivers/net/tlan.h b/drivers/net/tlan.h
--- a/drivers/net/tlan.h	2005-03-01 23:39:09 -08:00
+++ b/drivers/net/tlan.h	2005-03-01 23:39:09 -08:00
@@ -443,7 +443,7 @@
 
 /* Routines to access internal registers. */
 
-inline u8 TLan_DioRead8(u16 base_addr, u16 internal_addr)
+static inline u8 TLan_DioRead8(u16 base_addr, u16 internal_addr)
 {
 	outw(internal_addr, base_addr + TLAN_DIO_ADR);
 	return (inb((base_addr + TLAN_DIO_DATA) + (internal_addr & 0x3)));
@@ -453,7 +453,7 @@
 
 
 
-inline u16 TLan_DioRead16(u16 base_addr, u16 internal_addr)
+static inline u16 TLan_DioRead16(u16 base_addr, u16 internal_addr)
 {
 	outw(internal_addr, base_addr + TLAN_DIO_ADR);
 	return (inw((base_addr + TLAN_DIO_DATA) + (internal_addr & 0x2)));
@@ -463,7 +463,7 @@
 
 
 
-inline u32 TLan_DioRead32(u16 base_addr, u16 internal_addr)
+static inline u32 TLan_DioRead32(u16 base_addr, u16 internal_addr)
 {
 	outw(internal_addr, base_addr + TLAN_DIO_ADR);
 	return (inl(base_addr + TLAN_DIO_DATA));
@@ -473,7 +473,7 @@
 
 
 
-inline void TLan_DioWrite8(u16 base_addr, u16 internal_addr, u8 data)
+static inline void TLan_DioWrite8(u16 base_addr, u16 internal_addr, u8 data)
 {
 	outw(internal_addr, base_addr + TLAN_DIO_ADR);
 	outb(data, base_addr + TLAN_DIO_DATA + (internal_addr & 0x3));
@@ -483,7 +483,7 @@
 
 
 
-inline void TLan_DioWrite16(u16 base_addr, u16 internal_addr, u16 data)
+static inline void TLan_DioWrite16(u16 base_addr, u16 internal_addr, u16 data)
 {
 	outw(internal_addr, base_addr + TLAN_DIO_ADR);
 	outw(data, base_addr + TLAN_DIO_DATA + (internal_addr & 0x2));
@@ -493,46 +493,38 @@
 
 
 
-inline void TLan_DioWrite32(u16 base_addr, u16 internal_addr, u32 data)
+static inline void TLan_DioWrite32(u16 base_addr, u16 internal_addr, u32 data)
 {
 	outw(internal_addr, base_addr + TLAN_DIO_ADR);
 	outl(data, base_addr + TLAN_DIO_DATA + (internal_addr & 0x2));
 
 }
 
-
-
-#if 0
-inline void TLan_ClearBit(u8 bit, u16 port)
-{
-	outb_p(inb_p(port) & ~bit, port);
-}
-
-
-
-
-inline int TLan_GetBit(u8 bit, u16 port)
-{
-	return ((int) (inb_p(port) & bit));
-}
-
-
-
-
-inline void TLan_SetBit(u8 bit, u16 port)
-{
-	outb_p(inb_p(port) | bit, port);
-}
-#endif
-
 #define TLan_ClearBit( bit, port )	outb_p(inb_p(port) & ~bit, port)
 #define TLan_GetBit( bit, port )	((int) (inb_p(port) & bit))
 #define TLan_SetBit( bit, port )	outb_p(inb_p(port) | bit, port)
 
-#ifdef I_LIKE_A_FAST_HASH_FUNCTION
-/* given 6 bytes, view them as 8 6-bit numbers and return the XOR of those */
-/* the code below is about seven times as fast as the original code */
-inline u32 TLan_HashFunc( u8 *a )
+/*
+ * given 6 bytes, view them as 8 6-bit numbers and return the XOR of those 
+ * the code below is about seven times as fast as the original code 
+ *
+ * The original code was:
+ *
+ * u32	xor( u32 a, u32 b ) {	return ( ( a && ! b ) || ( ! a && b ) ); }
+ *
+ * #define XOR8( a, b, c, d, e, f, g, h )	\
+ * 	xor( a, xor( b, xor( c, xor( d, xor( e, xor( f, xor( g, h ) ) ) ) ) ) )
+ * #define DA( a, bit )		( ( (u8) a[bit/8] ) & ( (u8) ( 1 << bit%8 ) ) )
+ *
+ * 	hash  = XOR8( DA(a,0), DA(a, 6), DA(a,12), DA(a,18), DA(a,24), DA(a,30), DA(a,36), DA(a,42) );
+ * 	hash |= XOR8( DA(a,1), DA(a, 7), DA(a,13), DA(a,19), DA(a,25), DA(a,31), DA(a,37), DA(a,43) ) << 1;
+ * 	hash |= XOR8( DA(a,2), DA(a, 8), DA(a,14), DA(a,20), DA(a,26), DA(a,32), DA(a,38), DA(a,44) ) << 2;
+ * 	hash |= XOR8( DA(a,3), DA(a, 9), DA(a,15), DA(a,21), DA(a,27), DA(a,33), DA(a,39), DA(a,45) ) << 3;
+ * 	hash |= XOR8( DA(a,4), DA(a,10), DA(a,16), DA(a,22), DA(a,28), DA(a,34), DA(a,40), DA(a,46) ) << 4;
+ * 	hash |= XOR8( DA(a,5), DA(a,11), DA(a,17), DA(a,23), DA(a,29), DA(a,35), DA(a,41), DA(a,47) ) << 5;
+ *
+ */
+static inline u32 TLan_HashFunc( const u8 *a )
 {
         u8     hash;
 
@@ -545,30 +537,4 @@
 
         return (hash & 077);
 }
-
-#else /* original code */
-
-inline	u32	xor( u32 a, u32 b )
-{
-	return ( ( a && ! b ) || ( ! a && b ) );
-}
-#define XOR8( a, b, c, d, e, f, g, h )	xor( a, xor( b, xor( c, xor( d, xor( e, xor( f, xor( g, h ) ) ) ) ) ) )
-#define DA( a, bit )					( ( (u8) a[bit/8] ) & ( (u8) ( 1 << bit%8 ) ) )
-
-inline u32 TLan_HashFunc( u8 *a )
-{
-	u32	hash;
-
-	hash  = XOR8( DA(a,0), DA(a, 6), DA(a,12), DA(a,18), DA(a,24), DA(a,30), DA(a,36), DA(a,42) );
-	hash |= XOR8( DA(a,1), DA(a, 7), DA(a,13), DA(a,19), DA(a,25), DA(a,31), DA(a,37), DA(a,43) ) << 1;
-	hash |= XOR8( DA(a,2), DA(a, 8), DA(a,14), DA(a,20), DA(a,26), DA(a,32), DA(a,38), DA(a,44) ) << 2;
-	hash |= XOR8( DA(a,3), DA(a, 9), DA(a,15), DA(a,21), DA(a,27), DA(a,33), DA(a,39), DA(a,45) ) << 3;
-	hash |= XOR8( DA(a,4), DA(a,10), DA(a,16), DA(a,22), DA(a,28), DA(a,34), DA(a,40), DA(a,46) ) << 4;
-	hash |= XOR8( DA(a,5), DA(a,11), DA(a,17), DA(a,23), DA(a,29), DA(a,35), DA(a,41), DA(a,47) ) << 5;
-
-	return hash;
-
-} 
-
-#endif /* I_LIKE_A_FAST_HASH_FUNCTION */
 #endif
diff -Nru a/drivers/net/tokenring/3c359.c b/drivers/net/tokenring/3c359.c
--- a/drivers/net/tokenring/3c359.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/net/tokenring/3c359.c	2005-03-01 23:39:17 -08:00
@@ -94,20 +94,20 @@
 
 static int ringspeed[XL_MAX_ADAPTERS] = {0,} ;
 
-MODULE_PARM(ringspeed, "1-" __MODULE_STRING(XL_MAX_ADAPTERS) "i");
+module_param_array(ringspeed, int, NULL, 0);
 MODULE_PARM_DESC(ringspeed,"3c359: Ringspeed selection - 4,16 or 0") ; 
 
 /* Packet buffer size */
 
 static int pkt_buf_sz[XL_MAX_ADAPTERS] = {0,} ;
  
-MODULE_PARM(pkt_buf_sz, "1-" __MODULE_STRING(XL_MAX_ADAPTERS) "i") ; 
+module_param_array(pkt_buf_sz, int, NULL, 0) ;
 MODULE_PARM_DESC(pkt_buf_sz,"3c359: Initial buffer size") ; 
 /* Message Level */
 
 static int message_level[XL_MAX_ADAPTERS] = {0,} ; 
 
-MODULE_PARM(message_level, "1-" __MODULE_STRING(XL_MAX_ADAPTERS) "i") ; 
+module_param_array(message_level, int, NULL, 0) ;
 MODULE_PARM_DESC(message_level, "3c359: Level of reported messages \n") ; 
 /* 
  *	This is a real nasty way of doing this, but otherwise you
@@ -159,7 +159,7 @@
 
 	struct xl_private *xl_priv = (struct xl_private *)dev->priv ; 
 	struct xl_tx_desc *txd ; 
-	u8 *xl_mmio = xl_priv->xl_mmio ; 
+	u8 __iomem *xl_mmio = xl_priv->xl_mmio ; 
 	int i ; 
 
 	printk("tx_ring_head: %d, tx_ring_tail: %d, free_ent: %d \n",xl_priv->tx_ring_head, 
@@ -182,7 +182,7 @@
 
 	struct xl_private *xl_priv = (struct xl_private *)dev->priv ; 
 	struct xl_rx_desc *rxd ; 
-	u8 *xl_mmio = xl_priv->xl_mmio ; 
+	u8 __iomem *xl_mmio = xl_priv->xl_mmio ; 
 	int i ; 
 
 	printk("rx_ring_tail: %d \n", xl_priv->rx_ring_tail) ; 
@@ -215,7 +215,7 @@
 static u16 xl_ee_read(struct net_device *dev, int ee_addr)
 { 
     	struct xl_private *xl_priv = (struct xl_private *)dev->priv ;
-	u8 *xl_mmio = xl_priv->xl_mmio ; 
+	u8 __iomem *xl_mmio = xl_priv->xl_mmio ; 
 
 	/* Wait for EEProm to not be busy */
 	writel(IO_WORD_READ | EECONTROL, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
@@ -247,7 +247,7 @@
 static void  xl_ee_write(struct net_device *dev, int ee_addr, u16 ee_value) 
 {
     	struct xl_private *xl_priv = (struct xl_private *)dev->priv ;
-	u8 *xl_mmio = xl_priv->xl_mmio ; 
+	u8 __iomem *xl_mmio = xl_priv->xl_mmio ; 
 
 	/* Wait for EEProm to not be busy */
 	writel(IO_WORD_READ | EECONTROL, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
@@ -386,7 +386,7 @@
 static int xl_hw_reset(struct net_device *dev) 
 { 
     	struct xl_private *xl_priv = (struct xl_private *)dev->priv ;
-	u8 *xl_mmio = xl_priv->xl_mmio ; 
+	u8 __iomem *xl_mmio = xl_priv->xl_mmio ; 
 	unsigned long t ; 
 	u16 i ; 
     	u16 result_16 ; 
@@ -569,7 +569,7 @@
 static int xl_open(struct net_device *dev) 
 {
 	struct xl_private *xl_priv=(struct xl_private *)dev->priv;
-	u8 * xl_mmio = xl_priv->xl_mmio ; 
+	u8 __iomem *xl_mmio = xl_priv->xl_mmio ; 
 	u8 i ; 
 	u16 hwaddr[3] ; /* Should be u8[6] but we get word return values */
 	int open_err ;
@@ -727,7 +727,7 @@
 static int xl_open_hw(struct net_device *dev) 
 { 
 	struct xl_private *xl_priv=(struct xl_private *)dev->priv;
-	u8 * xl_mmio = xl_priv->xl_mmio ; 
+	u8 __iomem *xl_mmio = xl_priv->xl_mmio ; 
 	u16 vsoff ;
 	char ver_str[33];  
 	int open_err ; 
@@ -891,7 +891,7 @@
 static void xl_rx(struct net_device *dev)
 {
 	struct xl_private *xl_priv=(struct xl_private *)dev->priv;
-	u8 * xl_mmio = xl_priv->xl_mmio ; 
+	u8 __iomem * xl_mmio = xl_priv->xl_mmio ; 
 	struct sk_buff *skb, *skb2 ; 
 	int frame_length = 0, copy_len = 0  ; 	
 	int temp_ring_loc ;  
@@ -999,7 +999,7 @@
 static void xl_reset(struct net_device *dev) 
 {
 	struct xl_private *xl_priv=(struct xl_private *)dev->priv;
-	u8 * xl_mmio = xl_priv->xl_mmio ; 
+	u8 __iomem * xl_mmio = xl_priv->xl_mmio ; 
 	unsigned long t; 
 
 	writew( GLOBAL_RESET, xl_mmio + MMIO_COMMAND ) ; 
@@ -1046,7 +1046,7 @@
 {
 	struct net_device *dev = (struct net_device *)dev_id;
  	struct xl_private *xl_priv =(struct xl_private *)dev->priv;
-	u8 * xl_mmio = xl_priv->xl_mmio ; 
+	u8 __iomem * xl_mmio = xl_priv->xl_mmio ; 
 	u16 intstatus, macstatus  ;
 
 	if (!dev) { 
@@ -1234,7 +1234,7 @@
 static void xl_dn_comp(struct net_device *dev) 
 {
 	struct xl_private *xl_priv=(struct xl_private *)dev->priv;
-	u8 * xl_mmio = xl_priv->xl_mmio ; 
+	u8 __iomem * xl_mmio = xl_priv->xl_mmio ; 
 	struct xl_tx_desc *txd ; 
 
 
@@ -1270,7 +1270,7 @@
 static int xl_close(struct net_device *dev) 
 {
 	struct xl_private *xl_priv = (struct xl_private *) dev->priv ; 
-	u8 * xl_mmio = xl_priv->xl_mmio ; 
+	u8 __iomem * xl_mmio = xl_priv->xl_mmio ; 
 	unsigned long t ; 
 
 	netif_stop_queue(dev) ; 
@@ -1409,7 +1409,7 @@
 static void xl_srb_bh(struct net_device *dev) 
 { 
 	struct xl_private *xl_priv = (struct xl_private *) dev->priv ; 
-	u8 * xl_mmio = xl_priv->xl_mmio ; 
+	u8 __iomem * xl_mmio = xl_priv->xl_mmio ; 
 	u8 srb_cmd, ret_code ; 
 	int i ; 
 
@@ -1506,7 +1506,7 @@
 static void xl_arb_cmd(struct net_device *dev)
 {
 	struct xl_private *xl_priv = (struct xl_private *) dev->priv;
-	u8 * xl_mmio = xl_priv->xl_mmio ; 
+	u8 __iomem * xl_mmio = xl_priv->xl_mmio ; 
 	u8 arb_cmd ; 
 	u16 lan_status, lan_status_diff ; 
 
@@ -1634,7 +1634,7 @@
 static void xl_asb_cmd(struct net_device *dev)
 {
 	struct xl_private *xl_priv = (struct xl_private *) dev->priv ; 
-	u8 * xl_mmio = xl_priv->xl_mmio ; 
+	u8 __iomem * xl_mmio = xl_priv->xl_mmio ; 
 
 	if (xl_priv->asb_queued == 1) 
 		writel(ACK_INTERRUPT | LATCH_ACK | ASBFACK, xl_mmio + MMIO_COMMAND) ; 
@@ -1665,7 +1665,7 @@
 static void xl_asb_bh(struct net_device *dev) 
 {
 	struct xl_private *xl_priv = (struct xl_private *) dev->priv ; 
-	u8 * xl_mmio = xl_priv->xl_mmio ; 
+	u8 __iomem * xl_mmio = xl_priv->xl_mmio ; 
 	u8 ret_code ; 
 
 	writel(MMIO_BYTE_READ | 0xd0000 | xl_priv->asb | 2, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
@@ -1693,7 +1693,7 @@
 static void xl_srb_cmd(struct net_device *dev, int srb_cmd) 
 {
 	struct xl_private *xl_priv = (struct xl_private *) dev->priv ; 
-	u8 * xl_mmio = xl_priv->xl_mmio ; 
+	u8 __iomem * xl_mmio = xl_priv->xl_mmio ; 
 
 	switch (srb_cmd) { 
 	case READ_LOG:
@@ -1750,7 +1750,7 @@
 static void xl_wait_misr_flags(struct net_device *dev) 
 {
 	struct xl_private *xl_priv = (struct xl_private *) dev->priv ; 
-	u8 * xl_mmio = xl_priv->xl_mmio ; 
+	u8 __iomem * xl_mmio = xl_priv->xl_mmio ; 
 	
 	int i  ; 
 	
diff -Nru a/drivers/net/tokenring/3c359.h b/drivers/net/tokenring/3c359.h
--- a/drivers/net/tokenring/3c359.h	2005-03-01 23:38:53 -08:00
+++ b/drivers/net/tokenring/3c359.h	2005-03-01 23:38:53 -08:00
@@ -263,7 +263,7 @@
 	u16 arb;
 	u16 asb;
 
-	u8 *xl_mmio;
+	u8 __iomem *xl_mmio;
 	char *xl_card_name;
 	struct pci_dev *pdev ; 
 	
diff -Nru a/drivers/net/tokenring/Kconfig b/drivers/net/tokenring/Kconfig
--- a/drivers/net/tokenring/Kconfig	2005-03-01 23:38:54 -08:00
+++ b/drivers/net/tokenring/Kconfig	2005-03-01 23:38:54 -08:00
@@ -84,7 +84,7 @@
 
 config TMS380TR
 	tristate "Generic TMS380 Token Ring ISA/PCI adapter support"
-	depends on TR && (PCI || ISA) && HOTPLUG
+	depends on TR && (PCI || ISA)
 	select FW_LOADER
 	---help---
 	  This driver provides generic support for token ring adapters
diff -Nru a/drivers/net/tokenring/ibmtr.c b/drivers/net/tokenring/ibmtr.c
--- a/drivers/net/tokenring/ibmtr.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/net/tokenring/ibmtr.c	2005-03-01 23:39:07 -08:00
@@ -1945,9 +1945,9 @@
 
 MODULE_LICENSE("GPL");
 
-MODULE_PARM(io, "1-" __MODULE_STRING(IBMTR_MAX_ADAPTERS) "i");
-MODULE_PARM(irq, "1-" __MODULE_STRING(IBMTR_MAX_ADAPTERS) "i");
-MODULE_PARM(mem, "1-" __MODULE_STRING(IBMTR_MAX_ADAPTERS) "i");
+module_param_array(io, int, NULL, 0);
+module_param_array(irq, int, NULL, 0);
+module_param_array(mem, int, NULL, 0);
 
 static int __init ibmtr_init(void)
 {
diff -Nru a/drivers/net/tokenring/lanstreamer.c b/drivers/net/tokenring/lanstreamer.c
--- a/drivers/net/tokenring/lanstreamer.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/net/tokenring/lanstreamer.c	2005-03-01 23:39:17 -08:00
@@ -182,20 +182,19 @@
 
 static int ringspeed[STREAMER_MAX_ADAPTERS] = { 0, };
 
-MODULE_PARM(ringspeed, "1-" __MODULE_STRING(STREAMER_MAX_ADAPTERS) "i");
+module_param_array(ringspeed, int, NULL, 0);
 
 /* Packet buffer size */
 
 static int pkt_buf_sz[STREAMER_MAX_ADAPTERS] = { 0, };
 
-MODULE_PARM(pkt_buf_sz, "1-" __MODULE_STRING(STREAMER_MAX_ADAPTERS) "i");
+module_param_array(pkt_buf_sz, int, NULL, 0);
 
 /* Message Level */
 
 static int message_level[STREAMER_MAX_ADAPTERS] = { 1, };
 
-MODULE_PARM(message_level,
-	    "1-" __MODULE_STRING(STREAMER_MAX_ADAPTERS) "i");
+module_param_array(message_level, int, NULL, 0);
 
 #if STREAMER_IOCTL
 static int streamer_ioctl(struct net_device *, struct ifreq *, int);
@@ -443,7 +442,7 @@
 static int streamer_reset(struct net_device *dev)
 {
 	struct streamer_private *streamer_priv;
-	__u8 *streamer_mmio;
+	__u8 __iomem *streamer_mmio;
 	unsigned long t;
 	unsigned int uaa_addr;
 	struct sk_buff *skb = NULL;
@@ -591,7 +590,7 @@
 static int streamer_open(struct net_device *dev)
 {
 	struct streamer_private *streamer_priv = (struct streamer_private *) dev->priv;
-	__u8 *streamer_mmio = streamer_priv->streamer_mmio;
+	__u8 __iomem *streamer_mmio = streamer_priv->streamer_mmio;
 	unsigned long flags;
 	char open_error[255];
 	int i, open_finished = 1;
@@ -908,7 +907,7 @@
 {
 	struct streamer_private *streamer_priv =
 	    (struct streamer_private *) dev->priv;
-	__u8 *streamer_mmio = streamer_priv->streamer_mmio;
+	__u8 __iomem *streamer_mmio = streamer_priv->streamer_mmio;
 	struct streamer_rx_desc *rx_desc;
 	int rx_ring_last_received, length, frame_length, buffer_cnt = 0;
 	struct sk_buff *skb, *skb2;
@@ -1035,7 +1034,7 @@
 	struct net_device *dev = (struct net_device *) dev_id;
 	struct streamer_private *streamer_priv =
 	    (struct streamer_private *) dev->priv;
-	__u8 *streamer_mmio = streamer_priv->streamer_mmio;
+	__u8 __iomem *streamer_mmio = streamer_priv->streamer_mmio;
 	__u16 sisr;
 	__u16 misr;
 	u8 max_intr = MAX_INTR;
@@ -1158,7 +1157,7 @@
 {
 	struct streamer_private *streamer_priv =
 	    (struct streamer_private *) dev->priv;
-	__u8 *streamer_mmio = streamer_priv->streamer_mmio;
+	__u8 __iomem *streamer_mmio = streamer_priv->streamer_mmio;
 	unsigned long flags ;
 
 	spin_lock_irqsave(&streamer_priv->streamer_lock, flags);
@@ -1209,7 +1208,7 @@
 {
 	struct streamer_private *streamer_priv =
 	    (struct streamer_private *) dev->priv;
-	__u8 *streamer_mmio = streamer_priv->streamer_mmio;
+	__u8 __iomem *streamer_mmio = streamer_priv->streamer_mmio;
 	unsigned long flags;
 	int i;
 
@@ -1275,7 +1274,7 @@
 {
 	struct streamer_private *streamer_priv =
 	    (struct streamer_private *) dev->priv;
-	__u8 *streamer_mmio = streamer_priv->streamer_mmio;
+	__u8 __iomem *streamer_mmio = streamer_priv->streamer_mmio;
 	__u8 options = 0;
 	struct dev_mc_list *dmi;
 	unsigned char dev_mc_address[5];
@@ -1334,7 +1333,7 @@
 static void streamer_srb_bh(struct net_device *dev)
 {
 	struct streamer_private *streamer_priv = (struct streamer_private *) dev->priv;
-	__u8 *streamer_mmio = streamer_priv->streamer_mmio;
+	__u8 __iomem *streamer_mmio = streamer_priv->streamer_mmio;
 	__u16 srb_word;
 
 	writew(streamer_priv->srb, streamer_mmio + LAPA);
@@ -1531,7 +1530,7 @@
 {
 	struct streamer_private *streamer_priv =
 	    (struct streamer_private *) dev->priv;
-	__u8 *streamer_mmio = streamer_priv->streamer_mmio;
+	__u8 __iomem *streamer_mmio = streamer_priv->streamer_mmio;
 	__u8 header_len;
 	__u16 frame_len, buffer_len;
 	struct sk_buff *mac_frame;
@@ -1747,7 +1746,7 @@
 {
 	struct streamer_private *streamer_priv =
 	    (struct streamer_private *) dev->priv;
-	__u8 *streamer_mmio = streamer_priv->streamer_mmio;
+	__u8 __iomem *streamer_mmio = streamer_priv->streamer_mmio;
 
 	if (streamer_priv->asb_queued == 1) 
 	{
@@ -1855,7 +1854,7 @@
 {
 	struct streamer_private *streamer_priv =
 	    (struct streamer_private *) dev->priv;
-	__u8 *streamer_mmio = streamer_priv->streamer_mmio;
+	__u8 __iomem *streamer_mmio = streamer_priv->streamer_mmio;
 	struct streamer_adapter_addr_table sat;
 	struct streamer_parameters_table spt;
 	int size = 0;
@@ -1939,7 +1938,7 @@
 {
         int i;
 	struct streamer_private *streamer_priv = (struct streamer_private *) dev->priv;
-	u8 *streamer_mmio = streamer_priv->streamer_mmio;
+	u8 __iomem *streamer_mmio = streamer_priv->streamer_mmio;
 
 	switch(cmd) {
 	case IOCTL_SISR_MASK:
diff -Nru a/drivers/net/tokenring/lanstreamer.h b/drivers/net/tokenring/lanstreamer.h
--- a/drivers/net/tokenring/lanstreamer.h	2005-03-01 23:38:54 -08:00
+++ b/drivers/net/tokenring/lanstreamer.h	2005-03-01 23:38:54 -08:00
@@ -293,7 +293,7 @@
 
         struct streamer_private *next;
         struct pci_dev *pci_dev;
-	__u8 *streamer_mmio;
+	__u8 __iomem *streamer_mmio;
         char *streamer_card_name;
  
         spinlock_t streamer_lock;
diff -Nru a/drivers/net/tokenring/olympic.c b/drivers/net/tokenring/olympic.c
--- a/drivers/net/tokenring/olympic.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/net/tokenring/olympic.c	2005-03-01 23:39:08 -08:00
@@ -150,17 +150,17 @@
  */
 
 static int ringspeed[OLYMPIC_MAX_ADAPTERS] = {0,} ;
-MODULE_PARM(ringspeed, "1-" __MODULE_STRING(OLYMPIC_MAX_ADAPTERS) "i");
+module_param_array(ringspeed, int, NULL, 0);
 
 /* Packet buffer size */
 
 static int pkt_buf_sz[OLYMPIC_MAX_ADAPTERS] = {0,} ;
-MODULE_PARM(pkt_buf_sz, "1-" __MODULE_STRING(OLYMPIC_MAX_ADAPTERS) "i") ; 
+module_param_array(pkt_buf_sz, int, NULL, 0) ;
 
 /* Message Level */
 
 static int message_level[OLYMPIC_MAX_ADAPTERS] = {0,} ; 
-MODULE_PARM(message_level, "1-" __MODULE_STRING(OLYMPIC_MAX_ADAPTERS) "i") ; 
+module_param_array(message_level, int, NULL, 0) ;
 
 /* Change network_monitor to receive mac frames through the arb channel.
  * Will also create a /proc/net/olympic_tr%d entry, where %d is the tr
@@ -169,7 +169,7 @@
  * i.e. it will give you the source address of beaconers on the ring 
  */
 static int network_monitor[OLYMPIC_MAX_ADAPTERS] = {0,};
-MODULE_PARM(network_monitor, "1-" __MODULE_STRING(OLYMPIC_MAX_ADAPTERS) "i");
+module_param_array(network_monitor, int, NULL, 0);
 
 static struct pci_device_id olympic_pci_tbl[] = {
 	{PCI_VENDOR_ID_IBM,PCI_DEVICE_ID_IBM_TR_WAKE,PCI_ANY_ID,PCI_ANY_ID,},
@@ -438,8 +438,8 @@
 	struct olympic_private *olympic_priv=(struct olympic_private *)dev->priv;
 	u8 __iomem *olympic_mmio=olympic_priv->olympic_mmio,*init_srb;
 	unsigned long flags, t;
-	char open_error[255] ; 
 	int i, open_finished = 1 ;
+	u8 resp, err;
 
 	DECLARE_WAITQUEUE(wait,current) ; 
 
@@ -540,52 +540,48 @@
                  * timed out.
 		 */
 
-		if(readb(init_srb+2)== OLYMPIC_CLEAR_RET_CODE) {
+		switch (resp = readb(init_srb+2)) {
+		case OLYMPIC_CLEAR_RET_CODE:
 			printk(KERN_WARNING "%s: Adapter Open time out or error.\n", dev->name) ; 
-			return -EIO ; 
-		}	
+			goto out;
+		case 0:
+			open_finished = 1;
+			break;
+		case 0x07:
+			if (!olympic_priv->olympic_ring_speed && open_finished) { /* Autosense , first time around */
+				printk(KERN_WARNING "%s: Retrying at different ring speed \n", dev->name); 
+				open_finished = 0 ;  
+				continue;
+			}
 
-		if(readb(init_srb+2)!=0) {
-			if (readb(init_srb+2) == 0x07) {  
-				if (!olympic_priv->olympic_ring_speed && open_finished) { /* Autosense , first time around */
-					printk(KERN_WARNING "%s: Retrying at different ring speed \n", dev->name); 
-					open_finished = 0 ;  
-				} else {
-
-					strcpy(open_error, open_maj_error[(readb(init_srb+7) & 0xf0) >> 4]) ; 
-					strcat(open_error," - ") ; 
-					strcat(open_error, open_min_error[(readb(init_srb+7) & 0x0f)]) ;
-
-					if (!olympic_priv->olympic_ring_speed && ((readb(init_srb+7) & 0x0f) == 0x0d)) { 
-						printk(KERN_WARNING "%s: Tried to autosense ring speed with no monitors present\n",dev->name);
-						printk(KERN_WARNING "%s: Please try again with a specified ring speed \n",dev->name);
-						free_irq(dev->irq, dev);
-						return -EIO ;
-					}
-
-					printk(KERN_WARNING "%s: %s\n",dev->name,open_error);
-					free_irq(dev->irq,dev) ; 
-					return -EIO ; 
- 
-				}	/* if autosense && open_finished */
-			} else if (init_srb[2] == 0x32) {
-				printk(KERN_WARNING "%s: Invalid LAA: %02x:%02x:%02x:%02x:%02x:%02x\n",
-					dev->name, 
-					olympic_priv->olympic_laa[0],
-					olympic_priv->olympic_laa[1],
-					olympic_priv->olympic_laa[2],
-					olympic_priv->olympic_laa[3],
-					olympic_priv->olympic_laa[4],
-					olympic_priv->olympic_laa[5]) ; 
-				free_irq(dev->irq,dev) ; 
-				return -EIO ; 
-			} else {  
-				printk(KERN_WARNING "%s: Bad OPEN response: %x\n", dev->name,init_srb[2]);
-				free_irq(dev->irq, dev);
-				return -EIO;
-			} 
-		} else 
-			open_finished = 1 ; 
+			err = readb(init_srb+7);
+
+			if (!olympic_priv->olympic_ring_speed && ((err & 0x0f) == 0x0d)) { 
+				printk(KERN_WARNING "%s: Tried to autosense ring speed with no monitors present\n",dev->name);
+				printk(KERN_WARNING "%s: Please try again with a specified ring speed \n",dev->name);
+			} else {
+				printk(KERN_WARNING "%s: %s - %s\n", dev->name,
+					open_maj_error[(err & 0xf0) >> 4],
+					open_min_error[(err & 0x0f)]);
+			}
+			goto out;
+
+		case 0x32:
+			printk(KERN_WARNING "%s: Invalid LAA: %02x:%02x:%02x:%02x:%02x:%02x\n",
+				dev->name, 
+				olympic_priv->olympic_laa[0],
+				olympic_priv->olympic_laa[1],
+				olympic_priv->olympic_laa[2],
+				olympic_priv->olympic_laa[3],
+				olympic_priv->olympic_laa[4],
+				olympic_priv->olympic_laa[5]) ; 
+			goto out;
+
+		default:
+			printk(KERN_WARNING "%s: Bad OPEN response: %x\n", dev->name, resp);
+			goto out;
+
+		}
 	} while (!(open_finished)) ; /* Will only loop if ring speed mismatch re-open attempted && autosense is on */	
 
 	if (readb(init_srb+18) & (1<<3)) 
@@ -634,8 +630,7 @@
 
 	if (i==0) {
 		printk(KERN_WARNING "%s: Not enough memory to allocate rx buffers. Adapter disabled\n",dev->name);
-		free_irq(dev->irq, dev);
-		return -EIO;
+		goto out;
 	}
 
 	olympic_priv->rx_ring_dma_addr = pci_map_single(olympic_priv->pdev,olympic_priv->olympic_rx_ring, 
@@ -737,7 +732,10 @@
 	
 	netif_start_queue(dev);
 	return 0;
-	
+
+out:
+	free_irq(dev->irq, dev);
+	return -EIO;
 }	
 
 /*
diff -Nru a/drivers/net/tokenring/proteon.c b/drivers/net/tokenring/proteon.c
--- a/drivers/net/tokenring/proteon.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/net/tokenring/proteon.c	2005-03-01 23:39:17 -08:00
@@ -362,9 +362,9 @@
 
 MODULE_LICENSE("GPL");
 
-MODULE_PARM(io, "1-" __MODULE_STRING(ISATR_MAX_ADAPTERS) "i");
-MODULE_PARM(irq, "1-" __MODULE_STRING(ISATR_MAX_ADAPTERS) "i");
-MODULE_PARM(dma, "1-" __MODULE_STRING(ISATR_MAX_ADAPTERS) "i");
+module_param_array(io, int, NULL, 0);
+module_param_array(irq, int, NULL, 0);
+module_param_array(dma, int, NULL, 0);
 
 static struct net_device *proteon_dev[ISATR_MAX_ADAPTERS];
 
diff -Nru a/drivers/net/tokenring/skisa.c b/drivers/net/tokenring/skisa.c
--- a/drivers/net/tokenring/skisa.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/net/tokenring/skisa.c	2005-03-01 23:38:52 -08:00
@@ -371,9 +371,9 @@
 
 MODULE_LICENSE("GPL");
 
-MODULE_PARM(io, "1-" __MODULE_STRING(ISATR_MAX_ADAPTERS) "i");
-MODULE_PARM(irq, "1-" __MODULE_STRING(ISATR_MAX_ADAPTERS) "i");
-MODULE_PARM(dma, "1-" __MODULE_STRING(ISATR_MAX_ADAPTERS) "i");
+module_param_array(io, int, NULL, 0);
+module_param_array(irq, int, NULL, 0);
+module_param_array(dma, int, NULL, 0);
 
 static struct net_device *sk_isa_dev[ISATR_MAX_ADAPTERS];
 
diff -Nru a/drivers/net/tokenring/smctr.c b/drivers/net/tokenring/smctr.c
--- a/drivers/net/tokenring/smctr.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/net/tokenring/smctr.c	2005-03-01 23:38:57 -08:00
@@ -5663,9 +5663,9 @@
 
 MODULE_LICENSE("GPL");
 
-MODULE_PARM(io, "1-" __MODULE_STRING(SMCTR_MAX_ADAPTERS) "i");
-MODULE_PARM(irq, "1-" __MODULE_STRING(SMCTR_MAX_ADAPTERS) "i");
-MODULE_PARM(ringspeed, "i");
+module_param_array(io, int, NULL, 0);
+module_param_array(irq, int, NULL, 0);
+module_param(ringspeed, int, 0);
 
 static struct net_device *setup_card(int n)
 {
diff -Nru a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c
--- a/drivers/net/tulip/de2104x.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/net/tulip/de2104x.c	2005-03-01 23:39:09 -08:00
@@ -56,9 +56,10 @@
 MODULE_AUTHOR("Jeff Garzik <jgarzik@pobox.com>");
 MODULE_DESCRIPTION("Intel/Digital 21040/1 series PCI Ethernet driver");
 MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
 
 static int debug = -1;
-MODULE_PARM (debug, "i");
+module_param (debug, int, 0);
 MODULE_PARM_DESC (debug, "de2104x bitmapped message enable number");
 
 /* Set the copy breakpoint for the copy-only-tiny-buffer Rx structure. */
@@ -69,7 +70,7 @@
 #else
 static int rx_copybreak = 100;
 #endif
-MODULE_PARM (rx_copybreak, "i");
+module_param (rx_copybreak, int, 0);
 MODULE_PARM_DESC (rx_copybreak, "de2104x Breakpoint at which Rx packets are copied");
 
 #define PFX			DRV_NAME ": "
@@ -1702,6 +1703,7 @@
 			value = dr32(ROMCmd);
 		while (value < 0 && --boguscnt > 0);
 		de->dev->dev_addr[i] = value;
+		udelay(1);
 		if (boguscnt <= 0)
 			printk(KERN_WARNING PFX "timeout reading 21040 MAC address byte %u\n", i);
 	}
@@ -1958,8 +1960,6 @@
 	dev->tx_timeout = de_tx_timeout;
 	dev->watchdog_timeo = TX_TIMEOUT;
 
-	dev->irq = pdev->irq;
-
 	de = dev->priv;
 	de->de21040 = ent->driver_data == 0 ? 1 : 0;
 	de->pdev = pdev;
@@ -1994,6 +1994,8 @@
 		       pdev->irq, pci_name(pdev));
 		goto err_out_res;
 	}
+
+	dev->irq = pdev->irq;
 
 	/* obtain and check validity of PCI I/O address */
 	pciaddr = pci_resource_start(pdev, 1);
diff -Nru a/drivers/net/tulip/dmfe.c b/drivers/net/tulip/dmfe.c
--- a/drivers/net/tulip/dmfe.c	2005-03-01 23:39:10 -08:00
+++ b/drivers/net/tulip/dmfe.c	2005-03-01 23:39:10 -08:00
@@ -1987,16 +1987,17 @@
 MODULE_AUTHOR("Sten Wang, sten_wang@davicom.com.tw");
 MODULE_DESCRIPTION("Davicom DM910X fast ethernet driver");
 MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
 
-MODULE_PARM(debug, "i");
-MODULE_PARM(mode, "i");
-MODULE_PARM(cr6set, "i");
-MODULE_PARM(chkmode, "i");
-MODULE_PARM(HPNA_mode, "i");
-MODULE_PARM(HPNA_rx_cmd, "i");
-MODULE_PARM(HPNA_tx_cmd, "i");
-MODULE_PARM(HPNA_NoiseFloor, "i");
-MODULE_PARM(SF_mode, "i");
+module_param(debug, int, 0);
+module_param(mode, byte, 0);
+module_param(cr6set, int, 0);
+module_param(chkmode, byte, 0);
+module_param(HPNA_mode, byte, 0);
+module_param(HPNA_rx_cmd, byte, 0);
+module_param(HPNA_tx_cmd, byte, 0);
+module_param(HPNA_NoiseFloor, byte, 0);
+module_param(SF_mode, byte, 0);
 MODULE_PARM_DESC(debug, "Davicom DM9xxx enable debugging (0-1)");
 MODULE_PARM_DESC(mode, "Davicom DM9xxx: Bit 0: 10/100Mbps, bit 2: duplex, bit 8: HomePNA");
 MODULE_PARM_DESC(SF_mode, "Davicom DM9xxx special function (bit 0: VLAN, bit 1 Flow Control, bit 2: TX pause packet)");
diff -Nru a/drivers/net/tulip/media.c b/drivers/net/tulip/media.c
--- a/drivers/net/tulip/media.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/net/tulip/media.c	2005-03-01 23:38:54 -08:00
@@ -81,6 +81,25 @@
 		return retval & 0xffff;
 	}
 
+	if(tp->chip_id == ULI526X && tp->revision >= 0x40) {
+		int value;
+		int i = 1000;
+		
+		value = ioread32(ioaddr + CSR9);
+		iowrite32(value & 0xFFEFFFFF, ioaddr + CSR9);
+		
+		value = (phy_id << 21) | (location << 16) | 0x80000000;
+		iowrite32(value, ioaddr + CSR10);
+		
+		while(--i > 0) {
+			mdio_delay();
+			if(ioread32(ioaddr + CSR10) & 0x10000000)
+				break;
+		}
+		retval = ioread32(ioaddr + CSR10);
+		spin_unlock_irqrestore(&tp->mii_lock, flags);
+		return retval & 0xFFFF;
+	}
 	/* Establish sync by sending at least 32 logic ones. */
 	for (i = 32; i >= 0; i--) {
 		iowrite32(MDIO_ENB | MDIO_DATA_WRITE1, mdio_addr);
@@ -140,7 +159,23 @@
 		spin_unlock_irqrestore(&tp->mii_lock, flags);
 		return;
 	}
-
+	if (tp->chip_id == ULI526X && tp->revision >= 0x40) {
+		int value;
+		int i = 1000;
+		
+		value = ioread32(ioaddr + CSR9);
+		iowrite32(value & 0xFFEFFFFF, ioaddr + CSR9);
+		
+		value = (phy_id << 21) | (location << 16) | 0x40000000 | (val & 0xFFFF);
+		iowrite32(value, ioaddr + CSR10);
+		
+		while(--i > 0) {
+			if (ioread32(ioaddr + CSR10) & 0x10000000)
+				break;
+		}
+		spin_unlock_irqrestore(&tp->mii_lock, flags);
+	}
+		
 	/* Establish sync by sending 32 logic ones. */
 	for (i = 32; i >= 0; i--) {
 		iowrite32(MDIO_ENB | MDIO_DATA_WRITE1, mdio_addr);
diff -Nru a/drivers/net/tulip/timer.c b/drivers/net/tulip/timer.c
--- a/drivers/net/tulip/timer.c	2005-03-01 23:38:43 -08:00
+++ b/drivers/net/tulip/timer.c	2005-03-01 23:38:43 -08:00
@@ -39,6 +39,7 @@
 	case MX98713:
 	case COMPEX9881:
 	case DM910X:
+	case ULI526X:
 	default: {
 		struct medialeaf *mleaf;
 		unsigned char *p;
diff -Nru a/drivers/net/tulip/tulip.h b/drivers/net/tulip/tulip.h
--- a/drivers/net/tulip/tulip.h	2005-03-01 23:39:16 -08:00
+++ b/drivers/net/tulip/tulip.h	2005-03-01 23:39:16 -08:00
@@ -88,6 +88,7 @@
 	I21145,
 	DM910X,
 	CONEXANT,
+	ULI526X
 };
 
 
@@ -481,8 +482,11 @@
 
 static inline void tulip_restart_rxtx(struct tulip_private *tp)
 {
-	tulip_stop_rxtx(tp);
-	udelay(5);
+	if(!(tp->chip_id == ULI526X && 
+		(tp->revision == 0x40 || tp->revision == 0x50))) {
+		tulip_stop_rxtx(tp);
+		udelay(5);
+	}
 	tulip_start_rxtx(tp);
 }
 
diff -Nru a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c
--- a/drivers/net/tulip/tulip_core.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/net/tulip/tulip_core.c	2005-03-01 23:38:58 -08:00
@@ -88,9 +88,9 @@
 	ToDo: Non-Intel setting could be better.
 */
 
-#if defined(__alpha__) || defined(__ia64__) || defined(__x86_64__)
+#if defined(__alpha__) || defined(__ia64__)
 static int csr0 = 0x01A00000 | 0xE000;
-#elif defined(__i386__) || defined(__powerpc__)
+#elif defined(__i386__) || defined(__powerpc__) || defined(__x86_64__)
 static int csr0 = 0x01A00000 | 0x8000;
 #elif defined(__sparc__) || defined(__hppa__)
 /* The UltraSparc PCI controllers will disconnect at every 64-byte
@@ -115,12 +115,13 @@
 MODULE_AUTHOR("The Linux Kernel Team");
 MODULE_DESCRIPTION("Digital 21*4* Tulip ethernet driver");
 MODULE_LICENSE("GPL");
-MODULE_PARM(tulip_debug, "i");
-MODULE_PARM(max_interrupt_work, "i");
-MODULE_PARM(rx_copybreak, "i");
-MODULE_PARM(csr0, "i");
-MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i");
-MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
+MODULE_VERSION(DRV_VERSION);
+module_param(tulip_debug, int, 0);
+module_param(max_interrupt_work, int, 0);
+module_param(rx_copybreak, int, 0);
+module_param(csr0, int, 0);
+module_param_array(options, int, NULL, 0);
+module_param_array(full_duplex, int, NULL, 0);
 
 #define PFX DRV_NAME ": "
 
@@ -197,6 +198,10 @@
   /* RS7112 */
   { "Conexant LANfinity", 256, 0x0001ebef,
 	HAS_MII | HAS_ACPI, tulip_timer },
+
+   /* ULi526X */
+   { "ULi M5261/M5263", 128, 0x0001ebef,
+        HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM | HAS_ACPI, tulip_timer },
 };
 
 
@@ -228,12 +233,14 @@
 	{ 0x1113, 0x9511, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
 	{ 0x1186, 0x1541, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
 	{ 0x1186, 0x1561, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
+	{ 0x1186, 0x1591, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
 	{ 0x14f1, 0x1803, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CONEXANT },
 	{ 0x1626, 0x8410, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
 	{ 0x1737, 0xAB09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
 	{ 0x1737, 0xAB08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
 	{ 0x17B3, 0xAB08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
- 	{ 0x10b9, 0x5261, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DM910X },	/* ALi 1563 integrated ethernet */
+ 	{ 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 */
 	{ } /* terminate list */
 };
@@ -514,7 +521,7 @@
 				   dev->name);
 	} else if (tp->chip_id == DC21140 || tp->chip_id == DC21142
 			   || tp->chip_id == MX98713 || tp->chip_id == COMPEX9881
-			   || tp->chip_id == DM910X) {
+			   || tp->chip_id == DM910X || tp->chip_id == ULI526X) {
 		printk(KERN_WARNING "%s: 21140 transmit timed out, status %8.8x, "
 			   "SIA %8.8x %8.8x %8.8x %8.8x, resetting...\n",
 			   dev->name, ioread32(ioaddr + CSR5), ioread32(ioaddr + CSR12),
@@ -1044,7 +1051,7 @@
 				else
 					filterbit = ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26;
 				filterbit &= 0x3f;
-				mc_filter[filterbit >> 5] |= cpu_to_le32(1 << (filterbit & 31));
+				mc_filter[filterbit >> 5] |= 1 << (filterbit & 31);
 				if (tulip_debug > 2) {
 					printk(KERN_INFO "%s: Added filter for %2.2x:%2.2x:%2.2x:"
 						   "%2.2x:%2.2x:%2.2x  %8.8x bit %d.\n", dev->name,
@@ -1215,6 +1222,22 @@
 }
 #endif
 
+/*
+ *	Chips that have the MRM/reserved bit quirk and the burst quirk. That
+ *	is the DM910X and the on chip ULi devices
+ */
+ 
+static int tulip_uli_dm_quirk(struct pci_dev *pdev)
+{
+	if (pdev->vendor == 0x1282 && pdev->device == 0x9102)
+		return 1;
+	if (pdev->vendor == 0x10b9 && pdev->device == 0x5261)
+		return 1;
+	if (pdev->vendor == 0x10b9 && pdev->device == 0x5263)
+		return 1;
+	return 0;
+}
+
 static int __devinit tulip_init_one (struct pci_dev *pdev,
 				     const struct pci_device_id *ent)
 {
@@ -1303,17 +1326,12 @@
 		csr0 &= ~0xfff10000; /* zero reserved bits 31:20, 16 */
 
 	/* DM9102A has troubles with MRM & clear reserved bits 24:22, 20, 16, 7:1 */
-	if ((pdev->vendor == 0x1282 && pdev->device == 0x9102)
-		|| (pdev->vendor == 0x10b9 && pdev->device == 0x5261))
+	if (tulip_uli_dm_quirk(pdev)) {
 		csr0 &= ~0x01f100ff;
-
 #if defined(__sparc__)
-        /* DM9102A needs 32-dword alignment/burst length on sparc - chip bug? */
-	if ((pdev->vendor == 0x1282 && pdev->device == 0x9102)
-		|| (pdev->vendor == 0x10b9 && pdev->device == 0x5261))
                 csr0 = (csr0 & ~0xff00) | 0xe000;
 #endif
-
+	}
 	/*
 	 *	And back to business
 	 */
@@ -1658,6 +1676,7 @@
 	switch (chip_idx) {
 	case DC21140:
 	case DM910X:
+	case ULI526X:
 	default:
 		if (tp->mtable)
 			iowrite32(tp->mtable->csr12dir | 0x100, ioaddr + CSR12);
diff -Nru a/drivers/net/tulip/winbond-840.c b/drivers/net/tulip/winbond-840.c
--- a/drivers/net/tulip/winbond-840.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/net/tulip/winbond-840.c	2005-03-01 23:38:53 -08:00
@@ -144,13 +144,14 @@
 MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
 MODULE_DESCRIPTION("Winbond W89c840 Ethernet driver");
 MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
 
-MODULE_PARM(max_interrupt_work, "i");
-MODULE_PARM(debug, "i");
-MODULE_PARM(rx_copybreak, "i");
-MODULE_PARM(multicast_filter_limit, "i");
-MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i");
-MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
+module_param(max_interrupt_work, int, 0);
+module_param(debug, int, 0);
+module_param(rx_copybreak, int, 0);
+module_param(multicast_filter_limit, int, 0);
+module_param_array(options, int, NULL, 0);
+module_param_array(full_duplex, int, NULL, 0);
 MODULE_PARM_DESC(max_interrupt_work, "winbond-840 maximum events handled per interrupt");
 MODULE_PARM_DESC(debug, "winbond-840 debug level (0-6)");
 MODULE_PARM_DESC(rx_copybreak, "winbond-840 copy breakpoint for copy-only-tiny-frames");
@@ -1409,7 +1410,7 @@
 			 i++, mclist = mclist->next) {
 			int filterbit = (ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26) ^ 0x3F;
 			filterbit &= 0x3f;
-			mc_filter[filterbit >> 5] |= cpu_to_le32(1 << (filterbit & 31));
+			mc_filter[filterbit >> 5] |= 1 << (filterbit & 31);
 		}
 		rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
 	}
diff -Nru a/drivers/net/tulip/xircom_tulip_cb.c b/drivers/net/tulip/xircom_tulip_cb.c
--- a/drivers/net/tulip/xircom_tulip_cb.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/net/tulip/xircom_tulip_cb.c	2005-03-01 23:38:53 -08:00
@@ -33,6 +33,13 @@
 
 /* A few user-configurable values. */
 
+#define xircom_debug debug
+#ifdef XIRCOM_DEBUG
+static int xircom_debug = XIRCOM_DEBUG;
+#else
+static int xircom_debug = 1;
+#endif
+
 /* Maximum events (Rx packets, etc.) to handle at each interrupt. */
 static int max_interrupt_work = 25;
 
@@ -93,6 +100,7 @@
 
 #include <linux/config.h>
 #include <linux/module.h>
+#include <linux/moduleparam.h>
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/netdevice.h>
@@ -116,22 +124,17 @@
 MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
 MODULE_DESCRIPTION("Xircom CBE-100 ethernet driver");
 MODULE_LICENSE("GPL v2");
+MODULE_VERSION(DRV_VERSION);
 
-MODULE_PARM(debug, "i");
-MODULE_PARM(max_interrupt_work, "i");
-MODULE_PARM(rx_copybreak, "i");
-MODULE_PARM(csr0, "i");
-MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i");
-MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
+module_param(debug, int, 0);
+module_param(max_interrupt_work, int, 0);
+module_param(rx_copybreak, int, 0);
+module_param(csr0, int, 0);
 
-#define RUN_AT(x) (jiffies + (x))
+module_param_array(options, int, NULL, 0);
+module_param_array(full_duplex, int, NULL, 0);
 
-#define xircom_debug debug
-#ifdef XIRCOM_DEBUG
-static int xircom_debug = XIRCOM_DEBUG;
-#else
-static int xircom_debug = 1;
-#endif
+#define RUN_AT(x) (jiffies + (x))
 
 /*
 				Theory of Operation
diff -Nru a/drivers/net/tun.c b/drivers/net/tun.c
--- a/drivers/net/tun.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/net/tun.c	2005-03-01 23:38:56 -08:00
@@ -16,11 +16,25 @@
  */
 
 /*
+ *  Changes:
+ *
+ *  Mark Smith <markzzzsmith@yahoo.com.au>
+ *   Use random_ether_addr() for tap MAC address.
+ *
+ *  Harald Roelle <harald.roelle@ifi.lmu.de>  2004/04/20
+ *    Fixes in packet dropping, queue length setting and queue wakeup.
+ *    Increased default tx queue length.
+ *    Added ethtool API.
+ *    Minor cleanups
+ *
  *  Daniel Podlejski <underley@underley.eu.org>
  *    Modifications for 2.3.99-pre5 kernel.
  */
 
-#define TUN_VER "1.5"
+#define DRV_NAME	"tun"
+#define DRV_VERSION	"1.6"
+#define DRV_DESCRIPTION	"Universal TUN/TAP device driver"
+#define DRV_COPYRIGHT	"(C) 1999-2004 Max Krasnyansky <maxk@qualcomm.com>"
 
 #include <linux/config.h>
 #include <linux/module.h>
@@ -31,16 +45,17 @@
 #include <linux/poll.h>
 #include <linux/fcntl.h>
 #include <linux/init.h>
-#include <linux/random.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/miscdevice.h>
+#include <linux/ethtool.h>
 #include <linux/rtnetlink.h>
 #include <linux/if.h>
 #include <linux/if_arp.h>
 #include <linux/if_ether.h>
 #include <linux/if_tun.h>
+#include <linux/crc32.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -52,6 +67,7 @@
 /* Network device part of the driver */
 
 static LIST_HEAD(tun_dev_list);
+static struct ethtool_ops tun_ethtool_ops;
 
 /* Net device open. */
 static int tun_net_open(struct net_device *dev)
@@ -78,19 +94,26 @@
 	if (!tun->attached)
 		goto drop;
 
-	/* Queue packet */
-	if (!(tun->flags & TUN_ONE_QUEUE)) {
-		/* Normal queueing mode.
-		 * Packet scheduler handles dropping. */
-		if (skb_queue_len(&tun->readq) >= TUN_READQ_SIZE)
+	/* Packet dropping */
+	if (skb_queue_len(&tun->readq) >= dev->tx_queue_len) {
+		if (!(tun->flags & TUN_ONE_QUEUE)) {
+			/* Normal queueing mode. */
+			/* Packet scheduler handles dropping of further packets. */
 			netif_stop_queue(dev);
-	} else {
-		/* Single queue mode.
-		 * Driver handles dropping itself. */
-		if (skb_queue_len(&tun->readq) >= dev->tx_queue_len)
+
+			/* We won't see all dropped packets individually, so overrun
+			 * error is more appropriate. */
+			tun->stats.tx_fifo_errors++;
+		} else {
+			/* Single queue mode.
+			 * Driver handles dropping of all packets itself. */
 			goto drop;
+		}
 	}
+
+	/* Queue packet */
 	skb_queue_tail(&tun->readq, skb);
+	dev->trans_start = jiffies;
 
 	/* Notify and wake up reader process */
 	if (tun->flags & TUN_FASYNC)
@@ -104,11 +127,42 @@
 	return 0;
 }
 
-static void tun_net_mclist(struct net_device *dev)
+/** Add the specified Ethernet address to this multicast filter. */
+static void
+add_multi(u32* filter, const u8* addr)
+{
+	int bit_nr = ether_crc(ETH_ALEN, addr) >> 26;
+	filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
+}
+
+/** Remove the specified Ethernet addres from this multicast filter. */
+static void
+del_multi(u32* filter, const u8* addr)
+{
+	int bit_nr = ether_crc(ETH_ALEN, addr) >> 26;
+	filter[bit_nr >> 5] &= ~(1 << (bit_nr & 31));
+}
+
+/** Update the list of multicast groups to which the network device belongs.
+ * This list is used to filter packets being sent from the character device to
+ * the network device. */
+static void
+tun_net_mclist(struct net_device *dev)
 {
-	/* Nothing to do for multicast filters. 
-	 * We always accept all frames. */
-	return;
+	struct tun_struct *tun = netdev_priv(dev);
+	const struct dev_mc_list *mclist;
+	int i;
+	DBG(KERN_DEBUG "%s: tun_net_mclist: mc_count %d\n",
+			dev->name, dev->mc_count);
+	memset(tun->chr_filter, 0, sizeof tun->chr_filter);
+	for (i = 0, mclist = dev->mc_list; i < dev->mc_count && mclist != NULL;
+			i++, mclist = mclist->next) {
+		add_multi(tun->net_filter, mclist->dmi_addr);
+		DBG(KERN_DEBUG "%s: tun_net_mclist: %x:%x:%x:%x:%x:%x\n",
+				dev->name,
+				mclist->dmi_addr[0], mclist->dmi_addr[1], mclist->dmi_addr[2],
+				mclist->dmi_addr[3], mclist->dmi_addr[4], mclist->dmi_addr[5]);
+	}
 }
 
 static struct net_device_stats *tun_net_stats(struct net_device *dev)
@@ -132,18 +186,16 @@
 		/* Zero header length */
 		dev->type = ARPHRD_NONE; 
 		dev->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST;
-		dev->tx_queue_len = 10;
+		dev->tx_queue_len = TUN_READQ_SIZE;  /* We prefer our own queue length */
 		break;
 
 	case TUN_TAP_DEV:
 		/* Ethernet TAP Device */
 		dev->set_multicast_list = tun_net_mclist;
 
-		/* Generate random Ethernet address.  */
-		*(u16 *)dev->dev_addr = htons(0x00FF);
-		get_random_bytes(dev->dev_addr + sizeof(u16), 4);
-
 		ether_setup(dev);
+		random_ether_addr(dev->dev_addr);
+		dev->tx_queue_len = TUN_READQ_SIZE;  /* We prefer our own queue length */
 		break;
 	}
 }
@@ -208,6 +260,7 @@
 		skb->ip_summed = CHECKSUM_UNNECESSARY;
  
 	netif_rx_ni(skb);
+	tun->dev->last_rx = jiffies;
    
 	tun->stats.rx_packets++;
 	tun->stats.rx_bytes += len;
@@ -301,6 +354,10 @@
 
 	add_wait_queue(&tun->read_wait, &wait);
 	while (len) {
+		const u8 ones[ ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+		u8 addr[ ETH_ALEN];
+		int bit_nr;
+
 		current->state = TASK_INTERRUPTIBLE;
 
 		/* Read frames from the queue */
@@ -318,12 +375,40 @@
 			schedule();
 			continue;
 		}
-		netif_start_queue(tun->dev);
+		netif_wake_queue(tun->dev);
 
-		ret = tun_put_user(tun, skb, (struct iovec *) iv, len);
-
-		kfree_skb(skb);
-		break;
+		/** Decide whether to accept this packet. This code is designed to
+		 * behave identically to an Ethernet interface. Accept the packet if
+		 * - we are promiscuous.
+		 * - the packet is addressed to us.
+		 * - the packet is broadcast.
+		 * - the packet is multicast and
+		 *   - we are multicast promiscous.
+		 *   - we belong to the multicast group.
+		 */
+		memcpy(addr, skb->data,
+		       min_t(size_t, sizeof addr, skb->len));
+		bit_nr = ether_crc(sizeof addr, addr) >> 26;
+		if ((tun->if_flags & IFF_PROMISC) ||
+				memcmp(addr, tun->dev_addr, sizeof addr) == 0 ||
+				memcmp(addr, ones, sizeof addr) == 0 ||
+				(((addr[0] == 1 && addr[1] == 0 && addr[2] == 0x5e) ||
+				  (addr[0] == 0x33 && addr[1] == 0x33)) &&
+				 ((tun->if_flags & IFF_ALLMULTI) ||
+				  (tun->chr_filter[bit_nr >> 5] & (1 << (bit_nr & 31)))))) {
+			DBG(KERN_DEBUG "%s: tun_chr_readv: accepted: %x:%x:%x:%x:%x:%x\n",
+					tun->dev->name, addr[0], addr[1], addr[2],
+					addr[3], addr[4], addr[5]);
+			ret = tun_put_user(tun, skb, (struct iovec *) iv, len);
+			kfree_skb(skb);
+			break;
+		} else {
+			DBG(KERN_DEBUG "%s: tun_chr_readv: rejected: %x:%x:%x:%x:%x:%x\n",
+					tun->dev->name, addr[0], addr[1], addr[2],
+					addr[3], addr[4], addr[5]);
+			kfree_skb(skb);
+			continue;
+		}
 	}
 
 	current->state = TASK_RUNNING;
@@ -354,6 +439,7 @@
 	dev->hard_start_xmit = tun_net_xmit;
 	dev->stop = tun_net_close;
 	dev->get_stats = tun_net_stats;
+	dev->ethtool_ops = &tun_ethtool_ops;
 	dev->destructor = free_netdev;
 }
 
@@ -417,6 +503,12 @@
 		tun = netdev_priv(dev);
 		tun->dev = dev;
 		tun->flags = flags;
+		/* Be promiscuous by default to maintain previous behaviour. */
+		tun->if_flags = IFF_PROMISC;
+		/* Generate random Ethernet address. */
+		*(u16 *)tun->dev_addr = htons(0x00FF);
+		get_random_bytes(tun->dev_addr + sizeof(u16), 4);
+		memset(tun->chr_filter, 0, sizeof tun->chr_filter);
 
 		tun_net_init(dev);
 
@@ -457,13 +549,16 @@
 			 unsigned int cmd, unsigned long arg)
 {
 	struct tun_struct *tun = file->private_data;
+	void __user* argp = (void __user*)arg;
+	struct ifreq ifr;
+
+	if (cmd == TUNSETIFF || _IOC_TYPE(cmd) == 0x89)
+		if (copy_from_user(&ifr, argp, sizeof ifr))
+			return -EFAULT;
 
 	if (cmd == TUNSETIFF && !tun) {
-		struct ifreq ifr;
 		int err;
 
-		if (copy_from_user(&ifr, (void __user *)arg, sizeof(ifr)))
-			return -EFAULT;
 		ifr.ifr_name[IFNAMSIZ-1] = '\0';
 
 		rtnl_lock();
@@ -473,7 +568,7 @@
 		if (err)
 			return err;
 
-		if (copy_to_user((void __user *)arg, &ifr, sizeof(ifr)))
+		if (copy_to_user(argp, &ifr, sizeof(ifr)))
 			return -EFAULT;
 		return 0;
 	}
@@ -519,6 +614,61 @@
 		break;
 #endif
 
+	case SIOCGIFFLAGS:
+		ifr.ifr_flags = tun->if_flags;
+		if (copy_to_user( argp, &ifr, sizeof ifr))
+			return -EFAULT;
+		return 0;
+
+	case SIOCSIFFLAGS:
+		/** Set the character device's interface flags. Currently only
+		 * IFF_PROMISC and IFF_ALLMULTI are used. */
+		tun->if_flags = ifr.ifr_flags;
+		DBG(KERN_INFO "%s: interface flags 0x%lx\n",
+				tun->dev->name, tun->if_flags);
+		return 0;
+
+	case SIOCGIFHWADDR:
+		memcpy(ifr.ifr_hwaddr.sa_data, tun->dev_addr,
+				min(sizeof ifr.ifr_hwaddr.sa_data, sizeof tun->dev_addr));
+		if (copy_to_user( argp, &ifr, sizeof ifr))
+			return -EFAULT;
+		return 0;
+
+	case SIOCSIFHWADDR:
+		/** Set the character device's hardware address. This is used when
+		 * filtering packets being sent from the network device to the character
+		 * device. */
+		memcpy(tun->dev_addr, ifr.ifr_hwaddr.sa_data,
+				min(sizeof ifr.ifr_hwaddr.sa_data, sizeof tun->dev_addr));
+		DBG(KERN_DEBUG "%s: set hardware address: %x:%x:%x:%x:%x:%x\n",
+				tun->dev->name,
+				tun->dev_addr[0], tun->dev_addr[1], tun->dev_addr[2],
+				tun->dev_addr[3], tun->dev_addr[4], tun->dev_addr[5]);
+		return 0;
+
+	case SIOCADDMULTI:
+		/** Add the specified group to the character device's multicast filter
+		 * list. */
+		add_multi(tun->chr_filter, ifr.ifr_hwaddr.sa_data);
+		DBG(KERN_DEBUG "%s: add multi: %x:%x:%x:%x:%x:%x\n",
+				tun->dev->name,
+				(u8)ifr.ifr_hwaddr.sa_data[0], (u8)ifr.ifr_hwaddr.sa_data[1],
+				(u8)ifr.ifr_hwaddr.sa_data[2], (u8)ifr.ifr_hwaddr.sa_data[3],
+				(u8)ifr.ifr_hwaddr.sa_data[4], (u8)ifr.ifr_hwaddr.sa_data[5]);
+		return 0;
+
+	case SIOCDELMULTI:
+		/** Remove the specified group from the character device's multicast
+		 * filter list. */
+		del_multi(tun->chr_filter, ifr.ifr_hwaddr.sa_data);
+		DBG(KERN_DEBUG "%s: del multi: %x:%x:%x:%x:%x:%x\n",
+				tun->dev->name,
+				(u8)ifr.ifr_hwaddr.sa_data[0], (u8)ifr.ifr_hwaddr.sa_data[1],
+				(u8)ifr.ifr_hwaddr.sa_data[2], (u8)ifr.ifr_hwaddr.sa_data[3],
+				(u8)ifr.ifr_hwaddr.sa_data[4], (u8)ifr.ifr_hwaddr.sa_data[5]);
+		return 0;
+
 	default:
 		return -EINVAL;
 	};
@@ -608,12 +758,97 @@
 	.devfs_name = "net/tun",
 };
 
+/* ethtool interface */
+
+static int tun_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+	cmd->supported		= 0;
+	cmd->advertising	= 0;
+	cmd->speed		= SPEED_10;
+	cmd->duplex		= DUPLEX_FULL;
+	cmd->port		= PORT_TP;
+	cmd->phy_address	= 0;
+	cmd->transceiver	= XCVR_INTERNAL;
+	cmd->autoneg		= AUTONEG_DISABLE;
+	cmd->maxtxpkt		= 0;
+	cmd->maxrxpkt		= 0;
+	return 0;
+}
+
+static void tun_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
+{
+	struct tun_struct *tun = netdev_priv(dev);
+
+	strcpy(info->driver, DRV_NAME);
+	strcpy(info->version, DRV_VERSION);
+	strcpy(info->fw_version, "N/A");
+
+	switch (tun->flags & TUN_TYPE_MASK) {
+	case TUN_TUN_DEV:
+		strcpy(info->bus_info, "tun");
+		break;
+	case TUN_TAP_DEV:
+		strcpy(info->bus_info, "tap");
+		break;
+	}
+}
+
+static u32 tun_get_msglevel(struct net_device *dev)
+{
+#ifdef TUN_DEBUG
+	struct tun_struct *tun = netdev_priv(dev);
+	return tun->debug;
+#else
+	return -EOPNOTSUPP;
+#endif
+}
+
+static void tun_set_msglevel(struct net_device *dev, u32 value)
+{
+#ifdef TUN_DEBUG
+	struct tun_struct *tun = netdev_priv(dev);
+	tun->debug = value;
+#endif
+}
+
+static u32 tun_get_link(struct net_device *dev)
+{
+	struct tun_struct *tun = netdev_priv(dev);
+	return tun->attached;
+}
+
+static u32 tun_get_rx_csum(struct net_device *dev)
+{
+	struct tun_struct *tun = netdev_priv(dev);
+	return (tun->flags & TUN_NOCHECKSUM) == 0;
+}
+
+static int tun_set_rx_csum(struct net_device *dev, u32 data)
+{
+	struct tun_struct *tun = netdev_priv(dev);
+	if (data)
+		tun->flags &= ~TUN_NOCHECKSUM;
+	else
+		tun->flags |= TUN_NOCHECKSUM;
+	return 0;
+}
+
+static struct ethtool_ops tun_ethtool_ops = {
+	.get_settings	= tun_get_settings,
+	.get_drvinfo	= tun_get_drvinfo,
+	.get_msglevel	= tun_get_msglevel,
+	.set_msglevel	= tun_set_msglevel,
+	.get_link	= tun_get_link,
+	.get_rx_csum	= tun_get_rx_csum,
+	.set_rx_csum	= tun_set_rx_csum
+};
+
 int __init tun_init(void)
 {
 	int ret = 0;
 
-	printk(KERN_INFO "Universal TUN/TAP device driver %s " 
-	       "(C)1999-2002 Maxim Krasnyansky\n", TUN_VER);
+	printk(KERN_INFO "tun: %s, %s\n", DRV_DESCRIPTION, DRV_VERSION);
+	printk(KERN_INFO "tun: %s\n", DRV_COPYRIGHT);
 
 	ret = misc_register(&tun_miscdev);
 	if (ret)
@@ -638,5 +873,7 @@
 
 module_init(tun_init);
 module_exit(tun_cleanup);
+MODULE_DESCRIPTION(DRV_DESCRIPTION);
+MODULE_AUTHOR(DRV_COPYRIGHT);
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_MISCDEV(TUN_MINOR);
diff -Nru a/drivers/net/typhoon.c b/drivers/net/typhoon.c
--- a/drivers/net/typhoon.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/net/typhoon.c	2005-03-01 23:39:07 -08:00
@@ -1687,8 +1687,7 @@
 		skb = rxb->skb;
 		dma_addr = rxb->dma_addr;
 
-		rxaddr += sizeof(struct rx_desc);
-		rxaddr %= RX_ENTRIES * sizeof(struct rx_desc);
+		typhoon_inc_rx_index(&rxaddr, 1);
 
 		if(rx->flags & TYPHOON_RX_ERROR) {
 			typhoon_recycle_rx_skb(tp, idx);
@@ -1890,7 +1889,7 @@
 
 	pci_enable_wake(tp->pdev, state, 1);
 	pci_disable_device(pdev);
-	return pci_set_power_state(pdev, state);
+	return pci_set_power_state(pdev, pci_choose_state(pdev, state));
 }
 
 static int
@@ -1899,7 +1898,7 @@
 	struct pci_dev *pdev = tp->pdev;
 	void __iomem *ioaddr = tp->ioaddr;
 
-	pci_set_power_state(pdev, 0);
+	pci_set_power_state(pdev, PCI_D0);
 	pci_restore_state(pdev);
 
 	/* Post 2.x.x versions of the Sleep Image require a reset before
@@ -2553,7 +2552,7 @@
 	struct typhoon *tp = netdev_priv(dev);
 
 	unregister_netdev(dev);
-	pci_set_power_state(pdev, 0);
+	pci_set_power_state(pdev, PCI_D0);
 	pci_restore_state(pdev);
 	typhoon_reset(tp->ioaddr, NoWait);
 	iounmap(tp->ioaddr);
diff -Nru a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c
--- a/drivers/net/via-rhine.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/net/via-rhine.c	2005-03-01 23:39:17 -08:00
@@ -177,6 +177,7 @@
 #define PKT_BUF_SZ	1536	/* Size of each temporary Rx buffer.*/
 
 #include <linux/module.h>
+#include <linux/moduleparam.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/timer.h>
@@ -208,27 +209,15 @@
 #ifdef CONFIG_VIA_RHINE_MMIO
 #define USE_MMIO
 #else
-#undef readb
-#undef readw
-#undef readl
-#undef writeb
-#undef writew
-#undef writel
-#define readb inb
-#define readw inw
-#define readl inl
-#define writeb outb
-#define writew outw
-#define writel outl
 #endif
 
 MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
 MODULE_DESCRIPTION("VIA Rhine PCI Fast Ethernet driver");
 MODULE_LICENSE("GPL");
 
-MODULE_PARM(max_interrupt_work, "i");
-MODULE_PARM(debug, "i");
-MODULE_PARM(rx_copybreak, "i");
+module_param(max_interrupt_work, int, 0);
+module_param(debug, int, 0);
+module_param(rx_copybreak, int, 0);
 MODULE_PARM_DESC(max_interrupt_work, "VIA Rhine maximum events handled per interrupt");
 MODULE_PARM_DESC(debug, "VIA Rhine debug level (0-7)");
 MODULE_PARM_DESC(rx_copybreak, "VIA Rhine copy breakpoint for copy-only-tiny-frames");
@@ -363,7 +352,7 @@
  */
 
 /* Beware of PCI posted writes */
-#define IOSYNC	do { readb(dev->base_addr + StationAddr); } while (0)
+#define IOSYNC	do { ioread8(ioaddr + StationAddr); } while (0)
 
 static struct pci_device_id rhine_pci_tbl[] =
 {
@@ -500,6 +489,7 @@
 	u8 tx_thresh, rx_thresh;
 
 	struct mii_if_info mii_if;
+	void __iomem *base;
 };
 
 static int  mdio_read(struct net_device *dev, int phy_id, int location);
@@ -529,14 +519,14 @@
 
 static inline u32 get_intr_status(struct net_device *dev)
 {
-	long ioaddr = dev->base_addr;
 	struct rhine_private *rp = netdev_priv(dev);
+	void __iomem *ioaddr = rp->base;
 	u32 intr_status;
 
-	intr_status = readw(ioaddr + IntrStatus);
+	intr_status = ioread16(ioaddr + IntrStatus);
 	/* On Rhine-II, Bit 3 indicates Tx descriptor write-back race. */
 	if (rp->quirks & rqStatusWBRace)
-		intr_status |= readb(ioaddr + IntrStatus2) << 16;
+		intr_status |= ioread8(ioaddr + IntrStatus2) << 16;
 	return intr_status;
 }
 
@@ -546,32 +536,32 @@
  */
 static void rhine_power_init(struct net_device *dev)
 {
-	long ioaddr = dev->base_addr;
 	struct rhine_private *rp = netdev_priv(dev);
+	void __iomem *ioaddr = rp->base;
 	u16 wolstat;
 
 	if (rp->quirks & rqWOL) {
 		/* Make sure chip is in power state D0 */
-		writeb(readb(ioaddr + StickyHW) & 0xFC, ioaddr + StickyHW);
+		iowrite8(ioread8(ioaddr + StickyHW) & 0xFC, ioaddr + StickyHW);
 
 		/* Disable "force PME-enable" */
-		writeb(0x80, ioaddr + WOLcgClr);
+		iowrite8(0x80, ioaddr + WOLcgClr);
 
 		/* Clear power-event config bits (WOL) */
-		writeb(0xFF, ioaddr + WOLcrClr);
+		iowrite8(0xFF, ioaddr + WOLcrClr);
 		/* More recent cards can manage two additional patterns */
 		if (rp->quirks & rq6patterns)
-			writeb(0x03, ioaddr + WOLcrClr1);
+			iowrite8(0x03, ioaddr + WOLcrClr1);
 
 		/* Save power-event status bits */
-		wolstat = readb(ioaddr + PwrcsrSet);
+		wolstat = ioread8(ioaddr + PwrcsrSet);
 		if (rp->quirks & rq6patterns)
-			wolstat |= (readb(ioaddr + PwrcsrSet1) & 0x03) << 8;
+			wolstat |= (ioread8(ioaddr + PwrcsrSet1) & 0x03) << 8;
 
 		/* Clear power-event status bits */
-		writeb(0xFF, ioaddr + PwrcsrClr);
+		iowrite8(0xFF, ioaddr + PwrcsrClr);
 		if (rp->quirks & rq6patterns)
-			writeb(0x03, ioaddr + PwrcsrClr1);
+			iowrite8(0x03, ioaddr + PwrcsrClr1);
 
 		if (wolstat) {
 			char *reason;
@@ -602,27 +592,27 @@
 
 static void rhine_chip_reset(struct net_device *dev)
 {
-	long ioaddr = dev->base_addr;
 	struct rhine_private *rp = netdev_priv(dev);
+	void __iomem *ioaddr = rp->base;
 
-	writeb(Cmd1Reset, ioaddr + ChipCmd1);
+	iowrite8(Cmd1Reset, ioaddr + ChipCmd1);
 	IOSYNC;
 
-	if (readb(ioaddr + ChipCmd1) & Cmd1Reset) {
+	if (ioread8(ioaddr + ChipCmd1) & Cmd1Reset) {
 		printk(KERN_INFO "%s: Reset not complete yet. "
 			"Trying harder.\n", DRV_NAME);
 
 		/* Force reset */
 		if (rp->quirks & rqForceReset)
-			writeb(0x40, ioaddr + MiscCmd);
+			iowrite8(0x40, ioaddr + MiscCmd);
 
 		/* Reset can take somewhat longer (rare) */
-		RHINE_WAIT_FOR(!(readb(ioaddr + ChipCmd1) & Cmd1Reset));
+		RHINE_WAIT_FOR(!(ioread8(ioaddr + ChipCmd1) & Cmd1Reset));
 	}
 
 	if (debug > 1)
 		printk(KERN_INFO "%s: Reset %s.\n", dev->name,
-			(readb(ioaddr + ChipCmd1) & Cmd1Reset) ?
+			(ioread8(ioaddr + ChipCmd1) & Cmd1Reset) ?
 			"failed" : "succeeded");
 }
 
@@ -647,8 +637,8 @@
  */
 static void __devinit rhine_reload_eeprom(long pioaddr, struct net_device *dev)
 {
-	long ioaddr = dev->base_addr;
 	struct rhine_private *rp = netdev_priv(dev);
+	void __iomem *ioaddr = rp->base;
 
 	outb(0x20, pioaddr + MACRegEEcsr);
 	RHINE_WAIT_FOR(!(inb(pioaddr + MACRegEEcsr) & 0x20));
@@ -664,7 +654,7 @@
 
 	/* Turn off EEPROM-controlled wake-up (magic packet) */
 	if (rp->quirks & rqWOL)
-		writeb(readb(ioaddr + ConfigA) & 0xFE, ioaddr + ConfigA);
+		iowrite8(ioread8(ioaddr + ConfigA) & 0xFC, ioaddr + ConfigA);
 
 }
 
@@ -702,9 +692,14 @@
 	u32 quirks;
 	long pioaddr;
 	long memaddr;
-	long ioaddr;
+	void __iomem *ioaddr;
 	int io_size, phy_id;
 	const char *name;
+#ifdef USE_MMIO
+	int bar = 1;
+#else
+	int bar = 0;
+#endif
 
 /* when built into the kernel, we only print version if device is found */
 #ifndef MODULE
@@ -783,10 +778,7 @@
 	if (rc)
 		goto err_out_free_netdev;
 
-#ifdef USE_MMIO
-	enable_mmio(pioaddr, quirks);
-
-	ioaddr = (long) ioremap(memaddr, io_size);
+	ioaddr = pci_iomap(pdev, bar, io_size);
 	if (!ioaddr) {
 		rc = -EIO;
 		printk(KERN_ERR "ioremap failed for device %s, region 0x%X "
@@ -794,6 +786,9 @@
 		goto err_out_free_res;
 	}
 
+#ifdef USE_MMIO
+	enable_mmio(pioaddr, quirks);
+
 	/* Check that selected MMIO registers match the PIO ones */
 	i = 0;
 	while (mmio_verify_registers[i]) {
@@ -807,18 +802,17 @@
 			goto err_out_unmap;
 		}
 	}
-#else
-	ioaddr = pioaddr;
 #endif /* USE_MMIO */
 
-	dev->base_addr = ioaddr;
+	dev->base_addr = (unsigned long)ioaddr;
+	rp->base = ioaddr;
 
 	/* Get chip registers into a sane state */
 	rhine_power_init(dev);
 	rhine_hw_init(dev, pioaddr);
 
 	for (i = 0; i < 6; i++)
-		dev->dev_addr[i] = readb(ioaddr + StationAddr + i);
+		dev->dev_addr[i] = ioread8(ioaddr + StationAddr + i);
 
 	if (!is_valid_ether_addr(dev->dev_addr)) {
 		rc = -EIO;
@@ -828,7 +822,7 @@
 
 	/* For Rhine-I/II, phy_id is loaded from EEPROM */
 	if (!phy_id)
-		phy_id = readb(ioaddr + 0x6C);
+		phy_id = ioread8(ioaddr + 0x6C);
 
 	dev->irq = pdev->irq;
 
@@ -865,7 +859,7 @@
 #ifdef USE_MMIO
 		memaddr
 #else
-		ioaddr
+		(long)ioaddr
 #endif
 		 );
 
@@ -901,10 +895,8 @@
 	return 0;
 
 err_out_unmap:
-#ifdef USE_MMIO
-	iounmap((void *)ioaddr);
+	pci_iounmap(pdev, ioaddr);
 err_out_free_res:
-#endif
 	pci_release_regions(pdev);
 err_out_free_netdev:
 	free_netdev(dev);
@@ -947,7 +939,7 @@
 	return 0;
 }
 
-void free_ring(struct net_device* dev)
+static void free_ring(struct net_device* dev)
 {
 	struct rhine_private *rp = netdev_priv(dev);
 
@@ -1071,102 +1063,102 @@
 static void rhine_check_media(struct net_device *dev, unsigned int init_media)
 {
 	struct rhine_private *rp = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = rp->base;
 
 	mii_check_media(&rp->mii_if, debug, init_media);
 
 	if (rp->mii_if.full_duplex)
-	    writeb(readb(ioaddr + ChipCmd1) | Cmd1FDuplex,
+	    iowrite8(ioread8(ioaddr + ChipCmd1) | Cmd1FDuplex,
 		   ioaddr + ChipCmd1);
 	else
-	    writeb(readb(ioaddr + ChipCmd1) & ~Cmd1FDuplex,
+	    iowrite8(ioread8(ioaddr + ChipCmd1) & ~Cmd1FDuplex,
 		   ioaddr + ChipCmd1);
 }
 
 static void init_registers(struct net_device *dev)
 {
 	struct rhine_private *rp = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = rp->base;
 	int i;
 
 	for (i = 0; i < 6; i++)
-		writeb(dev->dev_addr[i], ioaddr + StationAddr + i);
+		iowrite8(dev->dev_addr[i], ioaddr + StationAddr + i);
 
 	/* Initialize other registers. */
-	writew(0x0006, ioaddr + PCIBusConfig);	/* Tune configuration??? */
+	iowrite16(0x0006, ioaddr + PCIBusConfig);	/* Tune configuration??? */
 	/* Configure initial FIFO thresholds. */
-	writeb(0x20, ioaddr + TxConfig);
+	iowrite8(0x20, ioaddr + TxConfig);
 	rp->tx_thresh = 0x20;
 	rp->rx_thresh = 0x60;		/* Written in rhine_set_rx_mode(). */
 
-	writel(rp->rx_ring_dma, ioaddr + RxRingPtr);
-	writel(rp->tx_ring_dma, ioaddr + TxRingPtr);
+	iowrite32(rp->rx_ring_dma, ioaddr + RxRingPtr);
+	iowrite32(rp->tx_ring_dma, ioaddr + TxRingPtr);
 
 	rhine_set_rx_mode(dev);
 
 	/* Enable interrupts by setting the interrupt mask. */
-	writew(IntrRxDone | IntrRxErr | IntrRxEmpty| IntrRxOverflow |
+	iowrite16(IntrRxDone | IntrRxErr | IntrRxEmpty| IntrRxOverflow |
 	       IntrRxDropped | IntrRxNoBuf | IntrTxAborted |
 	       IntrTxDone | IntrTxError | IntrTxUnderrun |
 	       IntrPCIErr | IntrStatsMax | IntrLinkChange,
 	       ioaddr + IntrEnable);
 
-	writew(CmdStart | CmdTxOn | CmdRxOn | (Cmd1NoTxPoll << 8),
+	iowrite16(CmdStart | CmdTxOn | CmdRxOn | (Cmd1NoTxPoll << 8),
 	       ioaddr + ChipCmd);
 	rhine_check_media(dev, 1);
 }
 
 /* Enable MII link status auto-polling (required for IntrLinkChange) */
-static void rhine_enable_linkmon(long ioaddr)
+static void rhine_enable_linkmon(void __iomem *ioaddr)
 {
-	writeb(0, ioaddr + MIICmd);
-	writeb(MII_BMSR, ioaddr + MIIRegAddr);
-	writeb(0x80, ioaddr + MIICmd);
+	iowrite8(0, ioaddr + MIICmd);
+	iowrite8(MII_BMSR, ioaddr + MIIRegAddr);
+	iowrite8(0x80, ioaddr + MIICmd);
 
-	RHINE_WAIT_FOR((readb(ioaddr + MIIRegAddr) & 0x20));
+	RHINE_WAIT_FOR((ioread8(ioaddr + MIIRegAddr) & 0x20));
 
-	writeb(MII_BMSR | 0x40, ioaddr + MIIRegAddr);
+	iowrite8(MII_BMSR | 0x40, ioaddr + MIIRegAddr);
 }
 
 /* Disable MII link status auto-polling (required for MDIO access) */
-static void rhine_disable_linkmon(long ioaddr, u32 quirks)
+static void rhine_disable_linkmon(void __iomem *ioaddr, u32 quirks)
 {
-	writeb(0, ioaddr + MIICmd);
+	iowrite8(0, ioaddr + MIICmd);
 
 	if (quirks & rqRhineI) {
-		writeb(0x01, ioaddr + MIIRegAddr);	// MII_BMSR
+		iowrite8(0x01, ioaddr + MIIRegAddr);	// MII_BMSR
 
 		/* Can be called from ISR. Evil. */
 		mdelay(1);
 
 		/* 0x80 must be set immediately before turning it off */
-		writeb(0x80, ioaddr + MIICmd);
+		iowrite8(0x80, ioaddr + MIICmd);
 
-		RHINE_WAIT_FOR(readb(ioaddr + MIIRegAddr) & 0x20);
+		RHINE_WAIT_FOR(ioread8(ioaddr + MIIRegAddr) & 0x20);
 
 		/* Heh. Now clear 0x80 again. */
-		writeb(0, ioaddr + MIICmd);
+		iowrite8(0, ioaddr + MIICmd);
 	}
 	else
-		RHINE_WAIT_FOR(readb(ioaddr + MIIRegAddr) & 0x80);
+		RHINE_WAIT_FOR(ioread8(ioaddr + MIIRegAddr) & 0x80);
 }
 
 /* Read and write over the MII Management Data I/O (MDIO) interface. */
 
 static int mdio_read(struct net_device *dev, int phy_id, int regnum)
 {
-	long ioaddr = dev->base_addr;
 	struct rhine_private *rp = netdev_priv(dev);
+	void __iomem *ioaddr = rp->base;
 	int result;
 
 	rhine_disable_linkmon(ioaddr, rp->quirks);
 
 	/* rhine_disable_linkmon already cleared MIICmd */
-	writeb(phy_id, ioaddr + MIIPhyAddr);
-	writeb(regnum, ioaddr + MIIRegAddr);
-	writeb(0x40, ioaddr + MIICmd);		/* Trigger read */
-	RHINE_WAIT_FOR(!(readb(ioaddr + MIICmd) & 0x40));
-	result = readw(ioaddr + MIIData);
+	iowrite8(phy_id, ioaddr + MIIPhyAddr);
+	iowrite8(regnum, ioaddr + MIIRegAddr);
+	iowrite8(0x40, ioaddr + MIICmd);		/* Trigger read */
+	RHINE_WAIT_FOR(!(ioread8(ioaddr + MIICmd) & 0x40));
+	result = ioread16(ioaddr + MIIData);
 
 	rhine_enable_linkmon(ioaddr);
 	return result;
@@ -1175,16 +1167,16 @@
 static void mdio_write(struct net_device *dev, int phy_id, int regnum, int value)
 {
 	struct rhine_private *rp = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = rp->base;
 
 	rhine_disable_linkmon(ioaddr, rp->quirks);
 
 	/* rhine_disable_linkmon already cleared MIICmd */
-	writeb(phy_id, ioaddr + MIIPhyAddr);
-	writeb(regnum, ioaddr + MIIRegAddr);
-	writew(value, ioaddr + MIIData);
-	writeb(0x20, ioaddr + MIICmd);		/* Trigger write */
-	RHINE_WAIT_FOR(!(readb(ioaddr + MIICmd) & 0x20));
+	iowrite8(phy_id, ioaddr + MIIPhyAddr);
+	iowrite8(regnum, ioaddr + MIIRegAddr);
+	iowrite16(value, ioaddr + MIIData);
+	iowrite8(0x20, ioaddr + MIICmd);		/* Trigger write */
+	RHINE_WAIT_FOR(!(ioread8(ioaddr + MIICmd) & 0x20));
 
 	rhine_enable_linkmon(ioaddr);
 }
@@ -1192,7 +1184,7 @@
 static int rhine_open(struct net_device *dev)
 {
 	struct rhine_private *rp = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = rp->base;
 	int rc;
 
 	rc = request_irq(rp->pdev->irq, &rhine_interrupt, SA_SHIRQ, dev->name,
@@ -1214,7 +1206,7 @@
 	if (debug > 2)
 		printk(KERN_DEBUG "%s: Done rhine_open(), status %4.4x "
 		       "MII status: %4.4x.\n",
-		       dev->name, readw(ioaddr + ChipCmd),
+		       dev->name, ioread16(ioaddr + ChipCmd),
 		       mdio_read(dev, rp->mii_if.phy_id, MII_BMSR));
 
 	netif_start_queue(dev);
@@ -1225,11 +1217,11 @@
 static void rhine_tx_timeout(struct net_device *dev)
 {
 	struct rhine_private *rp = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = rp->base;
 
 	printk(KERN_WARNING "%s: Transmit timed out, status %4.4x, PHY status "
 	       "%4.4x, resetting...\n",
-	       dev->name, readw(ioaddr + IntrStatus),
+	       dev->name, ioread16(ioaddr + IntrStatus),
 	       mdio_read(dev, rp->mii_if.phy_id, MII_BMSR));
 
 	/* protect against concurrent rx interrupts */
@@ -1258,7 +1250,7 @@
 static int rhine_start_tx(struct sk_buff *skb, struct net_device *dev)
 {
 	struct rhine_private *rp = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = rp->base;
 	unsigned entry;
 
 	/* Caution: the write order is important here, set the field
@@ -1276,7 +1268,7 @@
 	rp->tx_skbuff[entry] = skb;
 
 	if ((rp->quirks & rqRhineI) &&
-	    (((long)skb->data & 3) || skb_shinfo(skb)->nr_frags != 0 || skb->ip_summed == CHECKSUM_HW)) {
+	    (((unsigned long)skb->data & 3) || skb_shinfo(skb)->nr_frags != 0 || skb->ip_summed == CHECKSUM_HW)) {
 		/* Must use alignment buffer. */
 		if (skb->len > PKT_BUF_SZ) {
 			/* packet too long, drop it */
@@ -1311,7 +1303,7 @@
 	/* Non-x86 Todo: explicitly flush cache lines here. */
 
 	/* Wake the potentially-idle transmit channel */
-	writeb(readb(ioaddr + ChipCmd1) | Cmd1TxDemand,
+	iowrite8(ioread8(ioaddr + ChipCmd1) | Cmd1TxDemand,
 	       ioaddr + ChipCmd1);
 	IOSYNC;
 
@@ -1334,20 +1326,19 @@
 static irqreturn_t rhine_interrupt(int irq, void *dev_instance, struct pt_regs *rgs)
 {
 	struct net_device *dev = dev_instance;
-	long ioaddr;
+	struct rhine_private *rp = netdev_priv(dev);
+	void __iomem *ioaddr = rp->base;
 	u32 intr_status;
 	int boguscnt = max_interrupt_work;
 	int handled = 0;
 
-	ioaddr = dev->base_addr;
-
 	while ((intr_status = get_intr_status(dev))) {
 		handled = 1;
 
 		/* Acknowledge all of the current interrupt sources ASAP. */
 		if (intr_status & IntrTxDescRace)
-			writeb(0x08, ioaddr + IntrStatus2);
-		writew(intr_status & 0xffff, ioaddr + IntrStatus);
+			iowrite8(0x08, ioaddr + IntrStatus2);
+		iowrite16(intr_status & 0xffff, ioaddr + IntrStatus);
 		IOSYNC;
 
 		if (debug > 4)
@@ -1361,9 +1352,9 @@
 		if (intr_status & (IntrTxErrSummary | IntrTxDone)) {
 			if (intr_status & IntrTxErrSummary) {
 				/* Avoid scavenging before Tx engine turned off */
-				RHINE_WAIT_FOR(!(readb(ioaddr+ChipCmd) & CmdTxOn));
+				RHINE_WAIT_FOR(!(ioread8(ioaddr+ChipCmd) & CmdTxOn));
 				if (debug > 2 &&
-				    readb(ioaddr+ChipCmd) & CmdTxOn)
+				    ioread8(ioaddr+ChipCmd) & CmdTxOn)
 					printk(KERN_WARNING "%s: "
 					       "rhine_interrupt() Tx engine"
 					       "still on.\n", dev->name);
@@ -1387,7 +1378,7 @@
 
 	if (debug > 3)
 		printk(KERN_DEBUG "%s: exiting interrupt, status=%8.8x.\n",
-		       dev->name, readw(ioaddr + IntrStatus));
+		       dev->name, ioread16(ioaddr + IntrStatus));
 	return IRQ_RETVAL(handled);
 }
 
@@ -1582,16 +1573,16 @@
  * these, for others the counters are set to 1 when written to and
  * instead cleared when read. So we clear them both ways ...
  */
-static inline void clear_tally_counters(const long ioaddr)
+static inline void clear_tally_counters(void __iomem *ioaddr)
 {
-	writel(0, ioaddr + RxMissed);
-	readw(ioaddr + RxCRCErrs);
-	readw(ioaddr + RxMissed);
+	iowrite32(0, ioaddr + RxMissed);
+	ioread16(ioaddr + RxCRCErrs);
+	ioread16(ioaddr + RxMissed);
 }
 
 static void rhine_restart_tx(struct net_device *dev) {
 	struct rhine_private *rp = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = rp->base;
 	int entry = rp->dirty_tx % TX_RING_SIZE;
 	u32 intr_status;
 
@@ -1604,12 +1595,12 @@
 	if ((intr_status & IntrTxErrSummary) == 0) {
 
 		/* We know better than the chip where it should continue. */
-		writel(rp->tx_ring_dma + entry * sizeof(struct tx_desc),
+		iowrite32(rp->tx_ring_dma + entry * sizeof(struct tx_desc),
 		       ioaddr + TxRingPtr);
 
-		writeb(readb(ioaddr + ChipCmd) | CmdTxOn,
+		iowrite8(ioread8(ioaddr + ChipCmd) | CmdTxOn,
 		       ioaddr + ChipCmd);
-		writeb(readb(ioaddr + ChipCmd1) | Cmd1TxDemand,
+		iowrite8(ioread8(ioaddr + ChipCmd1) | Cmd1TxDemand,
 		       ioaddr + ChipCmd1);
 		IOSYNC;
 	}
@@ -1626,15 +1617,15 @@
 static void rhine_error(struct net_device *dev, int intr_status)
 {
 	struct rhine_private *rp = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = rp->base;
 
 	spin_lock(&rp->lock);
 
 	if (intr_status & IntrLinkChange)
 		rhine_check_media(dev, 0);
 	if (intr_status & IntrStatsMax) {
-		rp->stats.rx_crc_errors += readw(ioaddr + RxCRCErrs);
-		rp->stats.rx_missed_errors += readw(ioaddr + RxMissed);
+		rp->stats.rx_crc_errors += ioread16(ioaddr + RxCRCErrs);
+		rp->stats.rx_missed_errors += ioread16(ioaddr + RxMissed);
 		clear_tally_counters(ioaddr);
 	}
 	if (intr_status & IntrTxAborted) {
@@ -1644,7 +1635,7 @@
 	}
 	if (intr_status & IntrTxUnderrun) {
 		if (rp->tx_thresh < 0xE0)
-			writeb(rp->tx_thresh += 0x20, ioaddr + TxConfig);
+			iowrite8(rp->tx_thresh += 0x20, ioaddr + TxConfig);
 		if (debug > 1)
 			printk(KERN_INFO "%s: Transmitter underrun, Tx "
 			       "threshold now %2.2x.\n",
@@ -1659,7 +1650,7 @@
 	    (intr_status & (IntrTxAborted |
 	     IntrTxUnderrun | IntrTxDescRace)) == 0) {
 		if (rp->tx_thresh < 0xE0) {
-			writeb(rp->tx_thresh += 0x20, ioaddr + TxConfig);
+			iowrite8(rp->tx_thresh += 0x20, ioaddr + TxConfig);
 		}
 		if (debug > 1)
 			printk(KERN_INFO "%s: Unspecified error. Tx "
@@ -1684,12 +1675,12 @@
 static struct net_device_stats *rhine_get_stats(struct net_device *dev)
 {
 	struct rhine_private *rp = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = rp->base;
 	unsigned long flags;
 
 	spin_lock_irqsave(&rp->lock, flags);
-	rp->stats.rx_crc_errors += readw(ioaddr + RxCRCErrs);
-	rp->stats.rx_missed_errors += readw(ioaddr + RxMissed);
+	rp->stats.rx_crc_errors += ioread16(ioaddr + RxCRCErrs);
+	rp->stats.rx_missed_errors += ioread16(ioaddr + RxMissed);
 	clear_tally_counters(ioaddr);
 	spin_unlock_irqrestore(&rp->lock, flags);
 
@@ -1699,7 +1690,7 @@
 static void rhine_set_rx_mode(struct net_device *dev)
 {
 	struct rhine_private *rp = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = rp->base;
 	u32 mc_filter[2];	/* Multicast hash filter */
 	u8 rx_mode;		/* Note: 0x02=accept runt, 0x01=accept errs */
 
@@ -1708,13 +1699,13 @@
 		printk(KERN_NOTICE "%s: Promiscuous mode enabled.\n",
 		       dev->name);
 		rx_mode = 0x1C;
-		writel(0xffffffff, ioaddr + MulticastFilter0);
-		writel(0xffffffff, ioaddr + MulticastFilter1);
+		iowrite32(0xffffffff, ioaddr + MulticastFilter0);
+		iowrite32(0xffffffff, ioaddr + MulticastFilter1);
 	} else if ((dev->mc_count > multicast_filter_limit)
 		   || (dev->flags & IFF_ALLMULTI)) {
 		/* Too many to match, or accept all multicasts. */
-		writel(0xffffffff, ioaddr + MulticastFilter0);
-		writel(0xffffffff, ioaddr + MulticastFilter1);
+		iowrite32(0xffffffff, ioaddr + MulticastFilter0);
+		iowrite32(0xffffffff, ioaddr + MulticastFilter1);
 		rx_mode = 0x0C;
 	} else {
 		struct dev_mc_list *mclist;
@@ -1726,11 +1717,11 @@
 
 			mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
 		}
-		writel(mc_filter[0], ioaddr + MulticastFilter0);
-		writel(mc_filter[1], ioaddr + MulticastFilter1);
+		iowrite32(mc_filter[0], ioaddr + MulticastFilter0);
+		iowrite32(mc_filter[1], ioaddr + MulticastFilter1);
 		rx_mode = 0x0C;
 	}
-	writeb(rp->rx_thresh | rx_mode, ioaddr + RxConfig);
+	iowrite8(rp->rx_thresh | rx_mode, ioaddr + RxConfig);
 }
 
 static void netdev_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
@@ -1854,8 +1845,8 @@
 
 static int rhine_close(struct net_device *dev)
 {
-	long ioaddr = dev->base_addr;
 	struct rhine_private *rp = netdev_priv(dev);
+	void __iomem *ioaddr = rp->base;
 
 	spin_lock_irq(&rp->lock);
 
@@ -1864,16 +1855,16 @@
 	if (debug > 1)
 		printk(KERN_DEBUG "%s: Shutting down ethercard, "
 		       "status was %4.4x.\n",
-		       dev->name, readw(ioaddr + ChipCmd));
+		       dev->name, ioread16(ioaddr + ChipCmd));
 
 	/* Switch to loopback mode to avoid hardware races. */
-	writeb(rp->tx_thresh | 0x02, ioaddr + TxConfig);
+	iowrite8(rp->tx_thresh | 0x02, ioaddr + TxConfig);
 
 	/* Disable interrupts by clearing the interrupt mask. */
-	writew(0x0000, ioaddr + IntrEnable);
+	iowrite16(0x0000, ioaddr + IntrEnable);
 
 	/* Stop the chip's Tx and Rx processes. */
-	writew(CmdStop, ioaddr + ChipCmd);
+	iowrite16(CmdStop, ioaddr + ChipCmd);
 
 	spin_unlock_irq(&rp->lock);
 
@@ -1889,15 +1880,13 @@
 static void __devexit rhine_remove_one(struct pci_dev *pdev)
 {
 	struct net_device *dev = pci_get_drvdata(pdev);
+	struct rhine_private *rp = netdev_priv(dev);
 
 	unregister_netdev(dev);
 
+	pci_iounmap(pdev, rp->base);
 	pci_release_regions(pdev);
 
-#ifdef USE_MMIO
-	iounmap((char *)(dev->base_addr));
-#endif
-
 	free_netdev(dev);
 	pci_disable_device(pdev);
 	pci_set_drvdata(pdev, NULL);
@@ -1908,33 +1897,40 @@
 	struct pci_dev *pdev = to_pci_dev(gendev);
 	struct net_device *dev = pci_get_drvdata(pdev);
 	struct rhine_private *rp = netdev_priv(dev);
-
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = rp->base;
 
 	rhine_power_init(dev);
 
 	/* Make sure we use pattern 0, 1 and not 4, 5 */
 	if (rp->quirks & rq6patterns)
-		writeb(0x04, ioaddr + 0xA7);
+		iowrite8(0x04, ioaddr + 0xA7);
 
-	if (rp->wolopts & WAKE_MAGIC)
-		writeb(WOLmagic, ioaddr + WOLcrSet);
+	if (rp->wolopts & WAKE_MAGIC) {
+		iowrite8(WOLmagic, ioaddr + WOLcrSet);
+		/*
+		 * Turn EEPROM-controlled wake-up back on -- some hardware may
+		 * not cooperate otherwise.
+		 */
+		iowrite8(ioread8(ioaddr + ConfigA) | 0x03, ioaddr + ConfigA);
+	}
 
 	if (rp->wolopts & (WAKE_BCAST|WAKE_MCAST))
-		writeb(WOLbmcast, ioaddr + WOLcgSet);
+		iowrite8(WOLbmcast, ioaddr + WOLcgSet);
 
 	if (rp->wolopts & WAKE_PHY)
-		writeb(WOLlnkon | WOLlnkoff, ioaddr + WOLcrSet);
+		iowrite8(WOLlnkon | WOLlnkoff, ioaddr + WOLcrSet);
 
 	if (rp->wolopts & WAKE_UCAST)
-		writeb(WOLucast, ioaddr + WOLcrSet);
+		iowrite8(WOLucast, ioaddr + WOLcrSet);
 
-	/* Enable legacy WOL (for old motherboards) */
-	writeb(0x01, ioaddr + PwcfgSet);
-	writeb(readb(ioaddr + StickyHW) | 0x04, ioaddr + StickyHW);
+	if (rp->wolopts) {
+		/* Enable legacy WOL (for old motherboards) */
+		iowrite8(0x01, ioaddr + PwcfgSet);
+		iowrite8(ioread8(ioaddr + StickyHW) | 0x04, ioaddr + StickyHW);
+	}
 
 	/* Hit power state D3 (sleep) */
-	writeb(readb(ioaddr + StickyHW) | 0x03, ioaddr + StickyHW);
+	iowrite8(ioread8(ioaddr + StickyHW) | 0x03, ioaddr + StickyHW);
 
 	/* TODO: Check use of pci_enable_wake() */
 
@@ -1974,7 +1970,7 @@
         if (request_irq(dev->irq, rhine_interrupt, SA_SHIRQ, dev->name, dev))
 		printk(KERN_ERR "via-rhine %s: request_irq failed\n", dev->name);
 
-	ret = pci_set_power_state(pdev, 0);
+	ret = pci_set_power_state(pdev, PCI_D0);
 	if (debug > 1)
 		printk(KERN_INFO "%s: Entering power state D0 %s (%d).\n",
 			dev->name, ret ? "failed" : "succeeded", ret);
diff -Nru a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c
--- a/drivers/net/via-velocity.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/net/via-velocity.c	2005-03-01 23:39:08 -08:00
@@ -100,8 +100,8 @@
 MODULE_DESCRIPTION("VIA Networking Velocity Family Gigabit Ethernet Adapter Driver");
 
 #define VELOCITY_PARAM(N,D) \
-        static const int N[MAX_UNITS]=OPTION_DEFAULT;\
-        MODULE_PARM(N, "1-" __MODULE_STRING(MAX_UNITS) "i");\
+        static int N[MAX_UNITS]=OPTION_DEFAULT;\
+	module_param_array(N, int, NULL, 0); \
         MODULE_PARM_DESC(N, D);
 
 #define RX_DESC_MIN     64
@@ -229,7 +229,7 @@
 VELOCITY_PARAM(int_works, "Number of packets per interrupt services");
 
 static int rx_copybreak = 200;
-MODULE_PARM(rx_copybreak, "i");
+module_param(rx_copybreak, int, 0644);
 MODULE_PARM_DESC(rx_copybreak, "Copy breakpoint for copy-only-tiny-frames");
 
 static void velocity_init_info(struct pci_dev *pdev, struct velocity_info *vptr, struct velocity_info_tbl *info);
@@ -272,7 +272,7 @@
       .notifier_call	= velocity_netdev_event,
 };
 
-static spinlock_t velocity_dev_list_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(velocity_dev_list_lock);
 static LIST_HEAD(velocity_dev_list);
 
 static void velocity_register_notifier(void)
@@ -804,7 +804,7 @@
 	
 	/* and leave the chip powered down */
 	
-	pci_set_power_state(pdev, 3);
+	pci_set_power_state(pdev, PCI_D3hot);
 #ifdef CONFIG_PM
 	{
 		unsigned long flags;
@@ -1742,7 +1742,7 @@
 		goto err_free_rd_ring;
 	
 	/* Ensure chip is running */	
-	pci_set_power_state(vptr->pdev, 0);
+	pci_set_power_state(vptr->pdev, PCI_D0);
 	
 	velocity_init_registers(vptr, VELOCITY_INIT_COLD);
 
@@ -1750,7 +1750,7 @@
 			  dev->name, dev);
 	if (ret < 0) {
 		/* Power down the chip */
-		pci_set_power_state(vptr->pdev, 3);
+		pci_set_power_state(vptr->pdev, PCI_D3hot);
 		goto err_free_td_ring;
 	}
 
@@ -1868,7 +1868,7 @@
 		free_irq(dev->irq, dev);
 		
 	/* Power down the chip */
-	pci_set_power_state(vptr->pdev, 3);
+	pci_set_power_state(vptr->pdev, PCI_D3hot);
 	
 	/* Free the resources */
 	velocity_free_td_ring(vptr);
@@ -2194,8 +2194,8 @@
 	/* If we are asked for information and the device is power
 	   saving then we need to bring the device back up to talk to it */
 	   	
-	if(!netif_running(dev))
-		pci_set_power_state(vptr->pdev, 0);
+	if (!netif_running(dev))
+		pci_set_power_state(vptr->pdev, PCI_D0);
 		
 	switch (cmd) {
 	case SIOCGMIIPHY:	/* Get address of MII PHY in use. */
@@ -2207,8 +2207,8 @@
 	default:
 		ret = -EOPNOTSUPP;
 	}
-	if(!netif_running(dev))
-		pci_set_power_state(vptr->pdev, 3);
+	if (!netif_running(dev))
+		pci_set_power_state(vptr->pdev, PCI_D3hot);
 		
 		
 	return ret;
@@ -2818,8 +2818,8 @@
 static int velocity_ethtool_up(struct net_device *dev)
 {
 	struct velocity_info *vptr = dev->priv;
-	if(!netif_running(dev))
-		pci_set_power_state(vptr->pdev, 0);
+	if (!netif_running(dev))
+		pci_set_power_state(vptr->pdev, PCI_D0);
 	return 0;
 }	
 
@@ -2834,8 +2834,8 @@
 static void velocity_ethtool_down(struct net_device *dev)
 {
 	struct velocity_info *vptr = dev->priv;
-	if(!netif_running(dev))
-		pci_set_power_state(vptr->pdev, 3);
+	if (!netif_running(dev))
+		pci_set_power_state(vptr->pdev, PCI_D3hot);
 }
 
 static int velocity_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
@@ -3229,15 +3229,15 @@
 		velocity_shutdown(vptr);
 		velocity_set_wol(vptr);
 		pci_enable_wake(pdev, 3, 1);
-		pci_set_power_state(pdev, 3);
+		pci_set_power_state(pdev, PCI_D3hot);
 	} else {
 		velocity_save_context(vptr, &vptr->context);
 		velocity_shutdown(vptr);
 		pci_disable_device(pdev);
-		pci_set_power_state(pdev, state);
+		pci_set_power_state(pdev, pci_choose_state(pdev, state));
 	}
 #else
-	pci_set_power_state(pdev, state);
+	pci_set_power_state(pdev, pci_choose_state(pdev, state));
 #endif
 	spin_unlock_irqrestore(&vptr->lock, flags);
 	return 0;
@@ -3252,7 +3252,7 @@
 	if(!netif_running(vptr->dev))
 		return 0;
 
-	pci_set_power_state(pdev, 0);
+	pci_set_power_state(pdev, PCI_D0);
 	pci_enable_wake(pdev, 0, 0);
 	pci_restore_state(pdev);
 
diff -Nru a/drivers/net/via-velocity.h b/drivers/net/via-velocity.h
--- a/drivers/net/via-velocity.h	2005-03-01 23:39:17 -08:00
+++ b/drivers/net/via-velocity.h	2005-03-01 23:39:17 -08:00
@@ -291,10 +291,10 @@
 	dma_addr_t buf_dma;
 };
 
-enum {
+enum  velocity_owner {
 	OWNED_BY_HOST = 0,
 	OWNED_BY_NIC = 1
-} velocity_owner;
+};
 
 
 /*
diff -Nru a/drivers/net/wan/Kconfig b/drivers/net/wan/Kconfig
--- a/drivers/net/wan/Kconfig	2005-03-01 23:38:54 -08:00
+++ b/drivers/net/wan/Kconfig	2005-03-01 23:38:54 -08:00
@@ -109,7 +109,7 @@
 	  V.24, V.35 or V.36 interface) to your Linux box.
 
 	  - LMC 1200 with on board DSU board allows you to connect your Linux
-	  box dirrectly to a T1 or E1 circuit.
+	  box directly to a T1 or E1 circuit.
 
 	  - LMC 5200 board provides a HSSI interface capable of running up to
 	  52 Mbits per second.
@@ -459,7 +459,7 @@
 	depends on VENDOR_SANGOMA
 	help
 	  Connect a WANPIPE card to a Frame Relay network, or use Frame Felay
-	  API to develope custom applications.
+	  API to develop custom applications.
 
 	  Contains the Ethernet Bridging over Frame Relay feature, where
 	  a WANPIPE frame relay link can be directly connected to the Linux
diff -Nru a/drivers/net/wan/c101.c b/drivers/net/wan/c101.c
--- a/drivers/net/wan/c101.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/net/wan/c101.c	2005-03-01 23:39:08 -08:00
@@ -113,9 +113,6 @@
 }
 
 
-#define close_windows(card) {} /* no hardware support */
-
-
 #include "hd6457x.c"
 
 
diff -Nru a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c
--- a/drivers/net/wan/cosa.c	2005-03-01 23:38:51 -08:00
+++ b/drivers/net/wan/cosa.c	2005-03-01 23:38:51 -08:00
@@ -238,11 +238,11 @@
 static struct class_simple *cosa_class;
 
 #ifdef MODULE
-MODULE_PARM(io, "1-" __MODULE_STRING(MAX_CARDS) "i");
+module_param_array(io, int, NULL, 0);
 MODULE_PARM_DESC(io, "The I/O bases of the COSA or SRP cards");
-MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_CARDS) "i");
+module_param_array(irq, int, NULL, 0);
 MODULE_PARM_DESC(irq, "The IRQ lines of the COSA or SRP cards");
-MODULE_PARM(dma, "1-" __MODULE_STRING(MAX_CARDS) "i");
+module_param_array(dma, int, NULL, 0);
 MODULE_PARM_DESC(dma, "The DMA channels of the COSA or SRP cards");
 
 MODULE_AUTHOR("Jan \"Yenya\" Kasprzak, <kas@fi.muni.cz>");
@@ -642,11 +642,11 @@
 		return;
 	}
 	chan->pppdev.dev = d;
-	sppp_attach(&chan->pppdev);
 	d->base_addr = chan->cosa->datareg;
 	d->irq = chan->cosa->irq;
 	d->dma = chan->cosa->dma;
 	d->priv = chan;
+	sppp_attach(&chan->pppdev);
 	if (register_netdev(d)) {
 		printk(KERN_WARNING "%s: register_netdev failed.\n", d->name);
 		sppp_detach(d);
diff -Nru a/drivers/net/wan/cosa.h b/drivers/net/wan/cosa.h
--- a/drivers/net/wan/cosa.h	2005-03-01 23:39:18 -08:00
+++ b/drivers/net/wan/cosa.h	2005-03-01 23:39:18 -08:00
@@ -76,10 +76,16 @@
 #define COSAIOSTRT	_IOW('C',0xf1, int)
 
 /* Read the block from the device memory */
-#define COSAIORMEM	_IOWR('C',0xf2, struct cosa_download)
+#define COSAIORMEM	_IOWR('C',0xf2, struct cosa_download *)
+	/* actually the struct cosa_download itself; this is to keep
+	 * the ioctl number same as in 2.4 in order to keep the user-space
+	 * utils compatible. */
 
 /* Write the block to the device memory (i.e. download the microcode) */
-#define COSAIODOWNLD	_IOW('C',0xf2, struct cosa_download)
+#define COSAIODOWNLD	_IOW('C',0xf2, struct cosa_download *)
+	/* actually the struct cosa_download itself; this is to keep
+	 * the ioctl number same as in 2.4 in order to keep the user-space
+	 * utils compatible. */
 
 /* Read the device type (one of "srp", "cosa", and "cosa8" for now) */
 #define COSAIORTYPE	_IOR('C',0xf3, char *)
diff -Nru a/drivers/net/wan/cycx_main.c b/drivers/net/wan/cycx_main.c
--- a/drivers/net/wan/cycx_main.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/net/wan/cycx_main.c	2005-03-01 23:38:57 -08:00
@@ -57,7 +57,7 @@
 MODULE_AUTHOR("Arnaldo Carvalho de Melo");
 MODULE_DESCRIPTION("Cyclom 2X Sync Card Driver.");
 MODULE_LICENSE("GPL");
-MODULE_PARM(cycx_debug, "i");
+module_param(cycx_debug, int, 0);
 MODULE_PARM_DESC(cycx_debug, "cyclomx debug level");
 
 /* Defines & Macros */
diff -Nru a/drivers/net/wan/dscc4.c b/drivers/net/wan/dscc4.c
--- a/drivers/net/wan/dscc4.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/net/wan/dscc4.c	2005-03-01 23:39:18 -08:00
@@ -125,9 +125,9 @@
 MODULE_AUTHOR("Maintainer: Francois Romieu <romieu@cogenit.fr>");
 MODULE_DESCRIPTION("Siemens PEB20534 PCI Controler");
 MODULE_LICENSE("GPL");
-MODULE_PARM(debug,"i");
+module_param(debug, int, 0);
 MODULE_PARM_DESC(debug,"Enable/disable extra messages");
-MODULE_PARM(quartz,"i");
+module_param(quartz, int, 0);
 MODULE_PARM_DESC(quartz,"If present, on-board quartz frequency (Hz)");
 
 /* Structures */
@@ -691,7 +691,7 @@
 	root = ppriv->root;
 
 	for (i = 0; i < dev_per_card; i++)
-		unregister_hdlc_device(dscc4_to_dev(&root[i]));
+		unregister_hdlc_device(dscc4_to_dev(root + i));
 
 	pci_set_drvdata(pdev, NULL);
 
@@ -706,33 +706,36 @@
 {
 	struct dscc4_pci_priv *priv;
 	struct dscc4_dev_priv *dpriv;
-	static int cards_found = 0;
 	void __iomem *ioaddr;
-	int i;
+	int i, rc;
 
 	printk(KERN_DEBUG "%s", version);
 
-	if (pci_enable_device(pdev))
-		goto err_out;
-	if (!request_mem_region(pci_resource_start(pdev, 0),
-	                	pci_resource_len(pdev, 0), "registers")) {
+	rc = pci_enable_device(pdev);
+	if (rc < 0)
+		goto out;
+
+	rc = pci_request_region(pdev, 0, "registers");
+	if (rc < 0) {
 	        printk(KERN_ERR "%s: can't reserve MMIO region (regs)\n",
 			DRV_NAME);
-	        goto err_out;
+	        goto err_disable_0;
 	}
-	if (!request_mem_region(pci_resource_start(pdev, 1),
-	                        pci_resource_len(pdev, 1), "LBI interface")) {
+	rc = pci_request_region(pdev, 1, "LBI interface");
+	if (rc < 0) {
 	        printk(KERN_ERR "%s: can't reserve MMIO region (lbi)\n",
 			DRV_NAME);
-	        goto err_out_free_mmio_region0;
+	        goto err_free_mmio_region_1;
 	}
+
 	ioaddr = ioremap(pci_resource_start(pdev, 0),
 					pci_resource_len(pdev, 0));
 	if (!ioaddr) {
 		printk(KERN_ERR "%s: cannot remap MMIO region %lx @ %lx\n",
 			DRV_NAME, pci_resource_len(pdev, 0),
 			pci_resource_start(pdev, 0));
-		goto err_out_free_mmio_region;
+		rc = -EIO;
+		goto err_free_mmio_regions_2;
 	}
 	printk(KERN_DEBUG "Siemens DSCC4, MMIO at %#lx (regs), %#lx (lbi), IRQ %d\n",
 	        pci_resource_start(pdev, 0),
@@ -742,14 +745,16 @@
 	pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xf8);
 	pci_set_master(pdev);
 
-	if (dscc4_found1(pdev, ioaddr))
-	        goto err_out_iounmap;
+	rc = dscc4_found1(pdev, ioaddr);
+	if (rc < 0)
+	        goto err_iounmap_3;
 
-	priv = (struct dscc4_pci_priv *)pci_get_drvdata(pdev);
+	priv = pci_get_drvdata(pdev);
 
-	if (request_irq(pdev->irq, &dscc4_irq, SA_SHIRQ, DRV_NAME, priv->root)){
+	rc = request_irq(pdev->irq, dscc4_irq, SA_SHIRQ, DRV_NAME, priv->root);
+	if (rc < 0) {
 		printk(KERN_WARNING "%s: IRQ %d busy\n", DRV_NAME, pdev->irq);
-		goto err_out_free1;
+		goto err_release_4;
 	}
 
 	/* power up/little endian/dma core controlled via lrda/ltda */
@@ -769,9 +774,11 @@
 	priv->iqcfg = (u32 *) pci_alloc_consistent(pdev,
 		IRQ_RING_SIZE*sizeof(u32), &priv->iqcfg_dma);
 	if (!priv->iqcfg)
-		goto err_out_free_irq;
+		goto err_free_irq_5;
 	writel(priv->iqcfg_dma, ioaddr + IQCFG);
 
+	rc = -ENOMEM;
+
 	/*
 	 * SCC 0-3 private rx/tx irq structures
 	 * IQRX/TXi needs to be set soon. Learned it the hard way...
@@ -781,7 +788,7 @@
 		dpriv->iqtx = (u32 *) pci_alloc_consistent(pdev,
 			IRQ_RING_SIZE*sizeof(u32), &dpriv->iqtx_dma);
 		if (!dpriv->iqtx)
-			goto err_out_free_iqtx;
+			goto err_free_iqtx_6;
 		writel(dpriv->iqtx_dma, ioaddr + IQTX0 + i*4);
 	}
 	for (i = 0; i < dev_per_card; i++) {
@@ -789,7 +796,7 @@
 		dpriv->iqrx = (u32 *) pci_alloc_consistent(pdev,
 			IRQ_RING_SIZE*sizeof(u32), &dpriv->iqrx_dma);
 		if (!dpriv->iqrx)
-			goto err_out_free_iqrx;
+			goto err_free_iqrx_7;
 		writel(dpriv->iqrx_dma, ioaddr + IQRX0 + i*4);
 	}
 
@@ -804,17 +811,18 @@
 
 	writel(0xff200001, ioaddr + GCMDR);
 
-	cards_found++;
-	return 0;
+	rc = 0;
+out:
+	return rc;
 
-err_out_free_iqrx:
+err_free_iqrx_7:
 	while (--i >= 0) {
 		dpriv = priv->root + i;
 		pci_free_consistent(pdev, IRQ_RING_SIZE*sizeof(u32),
 				    dpriv->iqrx, dpriv->iqrx_dma);
 	}
 	i = dev_per_card;
-err_out_free_iqtx:
+err_free_iqtx_6:
 	while (--i >= 0) {
 		dpriv = priv->root + i;
 		pci_free_consistent(pdev, IRQ_RING_SIZE*sizeof(u32),
@@ -822,20 +830,19 @@
 	}
 	pci_free_consistent(pdev, IRQ_RING_SIZE*sizeof(u32), priv->iqcfg,
 			    priv->iqcfg_dma);
-err_out_free_irq:
+err_free_irq_5:
 	free_irq(pdev->irq, priv->root);
-err_out_free1:
+err_release_4:
 	dscc4_free1(pdev);
-err_out_iounmap:
+err_iounmap_3:
 	iounmap (ioaddr);
-err_out_free_mmio_region:
-	release_mem_region(pci_resource_start(pdev, 1),
-			   pci_resource_len(pdev, 1));
-err_out_free_mmio_region0:
-	release_mem_region(pci_resource_start(pdev, 0),
-			   pci_resource_len(pdev, 0));
-err_out:
-	return -ENODEV;
+err_free_mmio_regions_2:
+	pci_release_region(pdev, 1);
+err_free_mmio_region_1:
+	pci_release_region(pdev, 0);
+err_disable_0:
+	pci_disable_device(pdev);
+	goto out;
 };
 
 /*
@@ -882,8 +889,7 @@
 	struct dscc4_dev_priv *root;
 	int i, ret = -ENOMEM;
 
-	root = (struct dscc4_dev_priv *)
-		kmalloc(dev_per_card*sizeof(*root), GFP_KERNEL);
+	root = kmalloc(dev_per_card*sizeof(*root), GFP_KERNEL);
 	if (!root) {
 		printk(KERN_ERR "%s: can't allocate data\n", DRV_NAME);
 		goto err_out;
@@ -892,22 +898,17 @@
 
 	for (i = 0; i < dev_per_card; i++) {
 		root[i].dev = alloc_hdlcdev(root + i);
-		if (!root[i].dev) {
-			while (i--)
-				free_netdev(root[i].dev);
+		if (!root[i].dev)
 			goto err_free_dev;
-		}
 	}
 
-	ppriv = (struct dscc4_pci_priv *) kmalloc(sizeof(*ppriv), GFP_KERNEL);
+	ppriv = kmalloc(sizeof(*ppriv), GFP_KERNEL);
 	if (!ppriv) {
 		printk(KERN_ERR "%s: can't allocate private data\n", DRV_NAME);
-		goto err_free_dev2;
+		goto err_free_dev;
 	}
 	memset(ppriv, 0, sizeof(struct dscc4_pci_priv));
-	ret = dscc4_set_quartz(root, quartz);
-	if (ret < 0)
-		goto err_free_priv;
+
 	ppriv->root = root;
 	spin_lock_init(&ppriv->lock);
 
@@ -951,20 +952,24 @@
 			goto err_unregister;
 	        }
 	}
+
+	ret = dscc4_set_quartz(root, quartz);
+	if (ret < 0)
+		goto err_unregister;
+
 	pci_set_drvdata(pdev, ppriv);
 	return ret;
 
 err_unregister:
-	while (--i >= 0) {
+	while (i-- > 0) {
 		dscc4_release_ring(root + i);
-		unregister_hdlc_device(dscc4_to_dev(&root[i]));
+		unregister_hdlc_device(dscc4_to_dev(root + i));
 	}
-err_free_priv:
 	kfree(ppriv);
-err_free_dev2:
-	for (i = 0; i < dev_per_card; i++)
-		free_netdev(root[i].dev);
+	i = dev_per_card;
 err_free_dev:
+	while (i-- > 0)
+		free_netdev(root[i].dev);
 	kfree(root);
 err_out:
 	return ret;
@@ -1998,10 +2003,10 @@
 
 	iounmap(ioaddr);
 
-	release_mem_region(pci_resource_start(pdev, 1),
-			   pci_resource_len(pdev, 1));
-	release_mem_region(pci_resource_start(pdev, 0),
-			   pci_resource_len(pdev, 0));
+	pci_release_region(pdev, 1);
+	pci_release_region(pdev, 0);
+
+	pci_disable_device(pdev);
 }
 
 static int dscc4_hdlc_attach(struct net_device *dev, unsigned short encoding,
diff -Nru a/drivers/net/wan/farsync.c b/drivers/net/wan/farsync.c
--- a/drivers/net/wan/farsync.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/net/wan/farsync.c	2005-03-01 23:39:08 -08:00
@@ -33,11 +33,6 @@
  */
 MODULE_AUTHOR("R.J.Dunlop <bob.dunlop@farsite.co.uk>");
 MODULE_DESCRIPTION("FarSync T-Series WAN driver. FarSite Communications Ltd.");
-MODULE_PARM(fst_txq_low, "i");
-MODULE_PARM(fst_txq_high, "i");
-MODULE_PARM(fst_max_reads, "i");
-MODULE_PARM(fst_excluded_cards, "i");
-MODULE_PARM(fst_excluded_list, "0-32i");
 MODULE_LICENSE("GPL");
 
 /*      Driver configuration and global parameters
@@ -84,6 +79,12 @@
 int fst_max_reads = 7;
 int fst_excluded_cards = 0;
 int fst_excluded_list[FST_MAX_CARDS];
+
+module_param(fst_txq_low, int, 0);
+module_param(fst_txq_high, int, 0);
+module_param(fst_max_reads, int, 0);
+module_param(fst_excluded_cards, int, 0);
+module_param_array(fst_excluded_list, int, NULL, 0);
 
 /*      Card shared memory layout
  *      =========================
diff -Nru a/drivers/net/wan/hostess_sv11.c b/drivers/net/wan/hostess_sv11.c
--- a/drivers/net/wan/hostess_sv11.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/net/wan/hostess_sv11.c	2005-03-01 23:39:08 -08:00
@@ -263,7 +263,7 @@
 	/* We want a fast IRQ for this device. Actually we'd like an even faster
 	   IRQ ;) - This is one driver RtLinux is made for */
 	   
-	if(request_irq(irq, &z8530_interrupt, SA_INTERRUPT, "Hostess SV/11", dev)<0)
+	if(request_irq(irq, &z8530_interrupt, SA_INTERRUPT, "Hostess SV11", dev)<0)
 	{
 		printk(KERN_WARNING "hostess: IRQ %d already in use.\n", irq);
 		goto fail1;
@@ -388,11 +388,11 @@
 static int io=0x200;
 static int irq=9;
 
-MODULE_PARM(io,"i");
+module_param(io, int, 0);
 MODULE_PARM_DESC(io, "The I/O base of the Comtrol Hostess SV11 card");
-MODULE_PARM(dma,"i");
+module_param(dma, int, 0);
 MODULE_PARM_DESC(dma, "Set this to 1 to use DMA1/DMA3 for TX/RX");
-MODULE_PARM(irq,"i");
+module_param(irq, int, 0);
 MODULE_PARM_DESC(irq, "The interrupt line setting for the Comtrol Hostess SV11 card");
 
 MODULE_AUTHOR("Alan Cox");
diff -Nru a/drivers/net/wan/n2.c b/drivers/net/wan/n2.c
--- a/drivers/net/wan/n2.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/net/wan/n2.c	2005-03-01 23:38:53 -08:00
@@ -159,11 +159,6 @@
 }
 
 
-static __inline__ void close_windows(card_t *card)
-{
-	outb(inb(card->io + N2_PCR) & ~PCR_ENWIN, card->io + N2_PCR);
-}
-
 
 #include "hd6457x.c"
 
diff -Nru a/drivers/net/wan/pc300_drv.c b/drivers/net/wan/pc300_drv.c
--- a/drivers/net/wan/pc300_drv.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/net/wan/pc300_drv.c	2005-03-01 23:39:16 -08:00
@@ -1776,7 +1776,7 @@
 	pc300_t *card = (pc300_t *) chan->card;
 	struct net_device_stats *stats = hdlc_stats(dev);
 	int ch = chan->channel;
-	uclong flags;
+	unsigned long flags;
 	ucchar ilar;
 
 	stats->tx_errors++;
@@ -1804,7 +1804,7 @@
 	pc300_t *card = (pc300_t *) chan->card;
 	struct net_device_stats *stats = hdlc_stats(dev);
 	int ch = chan->channel;
-	uclong flags;
+	unsigned long flags;
 #ifdef PC300_DEBUG_TX
 	int i;
 #endif
@@ -2407,7 +2407,7 @@
 {
 	ucchar ilar;
 	void __iomem *scabase = card->hw.scabase;
-	uclong flags;
+	unsigned long flags;
 
 	tx_dma_buf_check(card, ch);
 	rx_dma_buf_check(card, ch);
@@ -2499,7 +2499,7 @@
 {
 	pc300ch_t *chan = &card->chan[ch];
 	falc_t *pfalc = (falc_t *) & chan->falc;
-	uclong flags;
+	unsigned long flags;
 
 	CPC_LOCK(card, flags);
 	printk("CH%d:   %s %s  %d channels\n",
@@ -3179,7 +3179,7 @@
 	pc300dev_t *d = (pc300dev_t *) dev->priv;
 	pc300ch_t *chan = (pc300ch_t *) d->chan;
 	pc300_t *card = (pc300_t *) chan->card;
-	uclong flags;
+	unsigned long flags;
 
 #ifdef	PC300_DEBUG_OTHER
 	printk("pc300: cpc_close");
diff -Nru a/drivers/net/wan/sbni.c b/drivers/net/wan/sbni.c
--- a/drivers/net/wan/sbni.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/net/wan/sbni.c	2005-03-01 23:38:55 -08:00
@@ -1485,14 +1485,12 @@
 
 
 #ifdef MODULE
-
-MODULE_PARM(	io,	"1-" __MODULE_STRING( SBNI_MAX_NUM_CARDS ) "i" );
-MODULE_PARM(	irq,	"1-" __MODULE_STRING( SBNI_MAX_NUM_CARDS ) "i" );
-MODULE_PARM(	baud,	"1-" __MODULE_STRING( SBNI_MAX_NUM_CARDS ) "i" );
-MODULE_PARM(	rxl,	"1-" __MODULE_STRING( SBNI_MAX_NUM_CARDS ) "i" );
-MODULE_PARM(	mac,	"1-" __MODULE_STRING( SBNI_MAX_NUM_CARDS ) "i" );
-
-MODULE_PARM(	skip_pci_probe,	"i" );
+module_param_array(io, int, NULL, 0);
+module_param_array(irq, int, NULL, 0);
+module_param_array(baud, int, NULL, 0);
+module_param_array(rxl, int, NULL, 0);
+module_param_array(mac, int, NULL, 0);
+module_param(skip_pci_probe, bool, 0);
 
 MODULE_LICENSE("GPL");
 
diff -Nru a/drivers/net/wan/sdla.c b/drivers/net/wan/sdla.c
--- a/drivers/net/wan/sdla.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/net/wan/sdla.c	2005-03-01 23:39:18 -08:00
@@ -69,7 +69,7 @@
                                     0xD0000, 0xD2000, 0xD4000, 0xD6000, 0xD8000, 0xDA000, 0xDC000, 0xDE000,
                                     0xE0000, 0xE2000, 0xE4000, 0xE6000, 0xE8000, 0xEA000, 0xEC000, 0xEE000}; 
 
-static spinlock_t sdla_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(sdla_lock);
 
 /*********************************************************
  *
@@ -1306,6 +1306,8 @@
 
 		case SDLA_WRITEMEM:
 		case SDLA_READMEM:
+			if(!capable(CAP_SYS_RAWIO))
+				return -EPERM;
 			return(sdla_xfer(dev, ifr->ifr_data, cmd == SDLA_READMEM));
 
 		case SDLA_START:
diff -Nru a/drivers/net/wan/sealevel.c b/drivers/net/wan/sealevel.c
--- a/drivers/net/wan/sealevel.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/net/wan/sealevel.c	2005-03-01 23:39:07 -08:00
@@ -431,15 +431,15 @@
 static int irq=5;
 static int slow=0;
 
-MODULE_PARM(io,"i");
+module_param(io, int, 0);
 MODULE_PARM_DESC(io, "The I/O base of the Sealevel card");
-MODULE_PARM(txdma,"i");
+module_param(txdma, int, 0);
 MODULE_PARM_DESC(txdma, "Transmit DMA channel");
-MODULE_PARM(rxdma,"i");
+module_param(rxdma, int, 0);
 MODULE_PARM_DESC(rxdma, "Receive DMA channel");
-MODULE_PARM(irq,"i");
+module_param(irq, int, 0);
 MODULE_PARM_DESC(irq, "The interrupt line setting for the SeaLevel card");
-MODULE_PARM(slow,"i");
+module_param(slow, bool, 0);
 MODULE_PARM_DESC(slow, "Set this for an older Sealevel card such as the 4012");
 
 MODULE_AUTHOR("Alan Cox");
diff -Nru a/drivers/net/wan/syncppp.c b/drivers/net/wan/syncppp.c
--- a/drivers/net/wan/syncppp.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/net/wan/syncppp.c	2005-03-01 23:38:54 -08:00
@@ -131,7 +131,7 @@
 
 static struct sppp *spppq;
 static struct timer_list sppp_keepalive_timer;
-static spinlock_t spppq_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(spppq_lock);
 
 /* global xmit queue for sending packets while spinlock is held */
 static struct sk_buff_head tx_queue;
@@ -1483,6 +1483,6 @@
 
 module_init(sync_ppp_init);
 module_exit(sync_ppp_cleanup);
-MODULE_PARM(debug,"1i");
+module_param(debug, int, 0);
 MODULE_LICENSE("GPL");
 
diff -Nru a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c
--- a/drivers/net/wan/x25_asy.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/net/wan/x25_asy.c	2005-03-01 23:38:53 -08:00
@@ -39,7 +39,7 @@
 static struct net_device **x25_asy_devs;
 static int x25_asy_maxdev = SL_NRUNIT;
 
-MODULE_PARM(x25_asy_maxdev, "i");
+module_param(x25_asy_maxdev, int, 0);
 MODULE_LICENSE("GPL");
 
 static int x25_asy_esc(unsigned char *p, unsigned char *d, int len);
diff -Nru a/drivers/net/wd.c b/drivers/net/wd.c
--- a/drivers/net/wd.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/net/wd.c	2005-03-01 23:38:52 -08:00
@@ -487,10 +487,10 @@
 static int mem[MAX_WD_CARDS];
 static int mem_end[MAX_WD_CARDS];	/* for non std. mem size */
 
-MODULE_PARM(io, "1-" __MODULE_STRING(MAX_WD_CARDS) "i");
-MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_WD_CARDS) "i");
-MODULE_PARM(mem, "1-" __MODULE_STRING(MAX_WD_CARDS) "i");
-MODULE_PARM(mem_end, "1-" __MODULE_STRING(MAX_WD_CARDS) "i");
+module_param_array(io, int, NULL, 0);
+module_param_array(irq, int, NULL, 0);
+module_param_array(mem, int, NULL, 0);
+module_param_array(mem_end, int, NULL, 0);
 MODULE_PARM_DESC(io, "I/O base address(es)");
 MODULE_PARM_DESC(irq, "IRQ number(s) (ignored for PureData boards)");
 MODULE_PARM_DESC(mem, "memory base address(es)(ignored for PureData boards)");
diff -Nru a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
--- a/drivers/net/wireless/Kconfig	2005-03-01 23:38:54 -08:00
+++ b/drivers/net/wireless/Kconfig	2005-03-01 23:38:54 -08:00
@@ -235,7 +235,7 @@
         one of these, you will need to provide a firmware image
         to be loaded into the card by the driver. The Atmel
         firmware package can be downloaded from
-        http://www.thekelleys.org.uk/atmel
+        <http://www.thekelleys.org.uk/atmel>
 
 config PCI_ATMEL
       tristate "Atmel at76c506 PCI cards"
@@ -311,7 +311,7 @@
 	depends on NET_RADIO && PCI
 config PRISM54
 	tristate 'Intersil Prism GT/Duette/Indigo PCI/Cardbus' 
-	depends on PCI && NET_RADIO && EXPERIMENTAL && HOTPLUG
+	depends on PCI && NET_RADIO && EXPERIMENTAL
 	select FW_LOADER
 	---help---
 	  Enable PCI and Cardbus support for the following chipset based cards:
diff -Nru a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
--- a/drivers/net/wireless/airo.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/net/wireless/airo.c	2005-03-01 23:38:52 -08:00
@@ -33,7 +33,6 @@
 #include <linux/string.h>
 #include <linux/timer.h>
 #include <linux/interrupt.h>
-#include <linux/suspend.h>
 #include <linux/in.h>
 #include <linux/bitops.h>
 #include <asm/io.h>
@@ -246,36 +245,36 @@
 		   for PCMCIA when used with airo_cs.");
 MODULE_LICENSE("Dual BSD/GPL");
 MODULE_SUPPORTED_DEVICE("Aironet 4500, 4800 and Cisco 340/350");
-MODULE_PARM(io,"1-4i");
-MODULE_PARM(irq,"1-4i");
-MODULE_PARM(basic_rate,"i");
-MODULE_PARM(rates,"1-8i");
-MODULE_PARM(ssids,"1-3s");
-MODULE_PARM(auto_wep,"i");
+module_param_array(io, int, NULL, 0);
+module_param_array(irq, int, NULL, 0);
+module_param(basic_rate, int, 0);
+module_param_array(rates, int, NULL, 0);
+module_param_array(ssids, charp, NULL, 0);
+module_param(auto_wep, int, 0);
 MODULE_PARM_DESC(auto_wep, "If non-zero, the driver will keep looping through \
 the authentication options until an association is made.  The value of \
 auto_wep is number of the wep keys to check.  A value of 2 will try using \
 the key at index 0 and index 1.");
-MODULE_PARM(aux_bap,"i");
+module_param(aux_bap, int, 0);
 MODULE_PARM_DESC(aux_bap, "If non-zero, the driver will switch into a mode \
 than seems to work better for older cards with some older buses.  Before \
 switching it checks that the switch is needed.");
-MODULE_PARM(maxencrypt, "i");
+module_param(maxencrypt, int, 0);
 MODULE_PARM_DESC(maxencrypt, "The maximum speed that the card can do \
 encryption.  Units are in 512kbs.  Zero (default) means there is no limit. \
 Older cards used to be limited to 2mbs (4).");
-MODULE_PARM(adhoc, "i");
+module_param(adhoc, int, 0);
 MODULE_PARM_DESC(adhoc, "If non-zero, the card will start in adhoc mode.");
-MODULE_PARM(probe, "i");
+module_param(probe, int, 0);
 MODULE_PARM_DESC(probe, "If zero, the driver won't start the card.");
 
-MODULE_PARM(proc_uid, "i");
+module_param(proc_uid, int, 0);
 MODULE_PARM_DESC(proc_uid, "The uid that the /proc files will belong to.");
-MODULE_PARM(proc_gid, "i");
+module_param(proc_gid, int, 0);
 MODULE_PARM_DESC(proc_gid, "The gid that the /proc files will belong to.");
-MODULE_PARM(airo_perm, "i");
+module_param(airo_perm, int, 0);
 MODULE_PARM_DESC(airo_perm, "The permission bits of /proc/[driver/]aironet.");
-MODULE_PARM(proc_perm, "i");
+module_param(proc_perm, int, 0);
 MODULE_PARM_DESC(proc_perm, "The permission bits of the files in /proc");
 
 /* This is a kind of sloppy hack to get this information to OUT4500 and
@@ -970,7 +969,7 @@
  * Host receive descriptor
  */
 typedef struct {
-	unsigned char *card_ram_off;	     /* offset into card memory of the
+	unsigned char __iomem *card_ram_off; /* offset into card memory of the
 						desc */
 	RxFid         rx_desc;		     /* card receive descriptor */
 	char          *virtual_host_addr;    /* virtual address of host receive
@@ -982,7 +981,7 @@
  * Host transmit descriptor
  */
 typedef struct {
-	unsigned char *card_ram_off;	     /* offset into card memory of the
+	unsigned char __iomem *card_ram_off;	     /* offset into card memory of the
 						desc */
 	TxFid         tx_desc;		     /* card transmit descriptor */
 	char          *virtual_host_addr;    /* virtual address of host receive
@@ -994,7 +993,7 @@
  * Host RID descriptor
  */
 typedef struct {
-	unsigned char *card_ram_off;      /* offset into card memory of the
+	unsigned char __iomem *card_ram_off;      /* offset into card memory of the
 					     descriptor */
 	Rid           rid_desc;		  /* card RID descriptor */
 	char          *virtual_host_addr; /* virtual address of host receive
@@ -1203,8 +1202,8 @@
 	unsigned long ridbus; // phys addr of config_desc
 	struct sk_buff_head txq;// tx queue used by mpi350 code
 	struct pci_dev          *pci;
-	unsigned char		*pcimem;
-	unsigned char		*pciaux;
+	unsigned char		__iomem *pcimem;
+	unsigned char		__iomem *pciaux;
 	unsigned char		*shared;
 	dma_addr_t		shared_dma;
 	int			power;
@@ -2029,8 +2028,8 @@
 		memcpy(sendbuf, buffer, len);
 	}
 
-	memcpy((char *)ai->txfids[0].card_ram_off,
-		(char *)&ai->txfids[0].tx_desc, sizeof(TxFid));
+	memcpy_toio(ai->txfids[0].card_ram_off,
+		&ai->txfids[0].tx_desc, sizeof(TxFid));
 
 	OUT4500(ai, EVACK, 8);
 
@@ -2460,7 +2459,7 @@
 	}
 
 	for (i=0; i<MPI_MAX_FIDS; i++) {
-		memcpy(ai->rxfids[i].card_ram_off,
+		memcpy_toio(ai->rxfids[i].card_ram_off,
 			&ai->rxfids[i].rx_desc, sizeof(RxFid));
 	}
 
@@ -2476,7 +2475,7 @@
 
 	for (i=0; i<MPI_MAX_FIDS; i++) {
 		ai->txfids[i].tx_desc.valid = 1;
-		memcpy((char *)ai->txfids[i].card_ram_off,
+		memcpy_toio(ai->txfids[i].card_ram_off,
 			&ai->txfids[i].tx_desc, sizeof(TxFid));
 	}
 	ai->txfids[i-1].tx_desc.eoc = 1; /* Last descriptor has EOC set */
@@ -2501,8 +2500,8 @@
 		return rc;
 	}
 
-	memcpy((char *)ai->config_desc.card_ram_off,
-		(char *)&ai->config_desc.rid_desc, sizeof(Rid));
+	memcpy_toio(ai->config_desc.card_ram_off,
+		&ai->config_desc.rid_desc, sizeof(Rid));
 
 	return rc;
 }
@@ -2520,7 +2519,7 @@
 	int rc = -1;
 	int i;
 	unsigned char *busaddroff,*vpackoff;
-	unsigned char *pciaddroff;
+	unsigned char __iomem *pciaddroff;
 
 	mem_start = pci_resource_start(pci, 1);
 	mem_len = pci_resource_len(pci, 1);
@@ -2697,7 +2696,8 @@
 }
 
 struct net_device *_init_airo_card( unsigned short irq, int port,
-				    int is_pcmcia, struct pci_dev *pci )
+				    int is_pcmcia, struct pci_dev *pci,
+				    struct device *dmdev )
 {
 	struct net_device *dev;
 	struct airo_info *ai;
@@ -2759,10 +2759,8 @@
 	dev->irq = irq;
 	dev->base_addr = port;
 
-	/* what is with PCMCIA ??? */
-	if (pci) {
-		SET_NETDEV_DEV(dev, &pci->dev);
-	}
+	SET_NETDEV_DEV(dev, dmdev);
+
 
 	if (test_bit(FLAG_MPI,&ai->flags))
 		reset_card (dev, 1);
@@ -2844,9 +2842,10 @@
 	return NULL;
 }
 
-struct net_device *init_airo_card( unsigned short irq, int port, int is_pcmcia )
+struct net_device *init_airo_card( unsigned short irq, int port, int is_pcmcia,
+				  struct device *dmdev)
 {
-	return _init_airo_card ( irq, port, is_pcmcia, NULL);
+	return _init_airo_card ( irq, port, is_pcmcia, NULL, dmdev);
 }
 
 EXPORT_SYMBOL(init_airo_card);
@@ -2918,8 +2917,7 @@
 			flush_signals(current);
 
 		/* make swsusp happy with our thread */
-		if (current->flags & PF_FREEZE)
-			refrigerator(PF_FREEZE);
+		try_to_freeze(PF_FREEZE);
 
 		if (test_bit(JOB_DIE, &ai->flags))
 			break;
@@ -3441,7 +3439,7 @@
 	MICBuffer micbuf;
 #endif
 
-	memcpy ((char *)&rxd, ai->rxfids[0].card_ram_off, sizeof(rxd));
+	memcpy_fromio(&rxd, ai->rxfids[0].card_ram_off, sizeof(rxd));
 	/* Make sure we got something */
 	if (rxd.rdy && rxd.valid == 0) {
 		len = rxd.len + 12;
@@ -3504,7 +3502,7 @@
 		rxd.valid = 1;
 		rxd.rdy = 0;
 		rxd.len = PKTSIZE;
-		memcpy (ai->rxfids[0].card_ram_off, (char *)&rxd, sizeof(rxd));
+		memcpy_toio(ai->rxfids[0].card_ram_off, &rxd, sizeof(rxd));
 	}
 }
 
@@ -3526,7 +3524,7 @@
 	u16 *buffer;
 	char *ptr = ai->rxfids[0].virtual_host_addr+4;
 
-	memcpy ((char *)&rxd, ai->rxfids[0].card_ram_off, sizeof(rxd));
+	memcpy_fromio(&rxd, ai->rxfids[0].card_ram_off, sizeof(rxd));
 	memcpy ((char *)&hdr, ptr, sizeof(hdr));
 	ptr += sizeof(hdr);
 	/* Bad CRC. Ignore packet */
@@ -3610,7 +3608,7 @@
 		rxd.valid = 1;
 		rxd.rdy = 0;
 		rxd.len = PKTSIZE;
-		memcpy (ai->rxfids[0].card_ram_off, (char *)&rxd, sizeof(rxd));
+		memcpy_toio(ai->rxfids[0].card_ram_off, &rxd, sizeof(rxd));
 	}
 }
 
@@ -3990,8 +3988,8 @@
 		cmd.cmd = CMD_ACCESS;
 		cmd.parm0 = rid;
 
-		memcpy((char *)ai->config_desc.card_ram_off,
-			(char *)&ai->config_desc.rid_desc, sizeof(Rid));
+		memcpy_toio(ai->config_desc.card_ram_off,
+			&ai->config_desc.rid_desc, sizeof(Rid));
 
 		rc = issuecommand(ai, &cmd, &rsp);
 
@@ -4062,8 +4060,8 @@
 		cmd.cmd = CMD_WRITERID;
 		cmd.parm0 = rid;
 
-		memcpy((char *)ai->config_desc.card_ram_off,
-			(char *)&ai->config_desc.rid_desc, sizeof(Rid));
+		memcpy_toio(ai->config_desc.card_ram_off,
+			&ai->config_desc.rid_desc, sizeof(Rid));
 
 		if (len < 4 || len > 2047) {
 			printk(KERN_ERR "%s: len=%d\n",__FUNCTION__,len);
@@ -5455,9 +5453,9 @@
 	pci_set_master(pdev);
 
 	if (pdev->device == 0x5000 || pdev->device == 0xa504)
-			dev = _init_airo_card(pdev->irq, pdev->resource[0].start, 0, pdev);
+			dev = _init_airo_card(pdev->irq, pdev->resource[0].start, 0, pdev, &pdev->dev);
 	else
-			dev = _init_airo_card(pdev->irq, pdev->resource[2].start, 0, pdev);
+			dev = _init_airo_card(pdev->irq, pdev->resource[2].start, 0, pdev, &pdev->dev);
 	if (!dev)
 		return -ENODEV;
 
@@ -5559,7 +5557,7 @@
 		printk( KERN_INFO
 			"airo:  Trying to configure ISA adapter at irq=%d io=0x%x\n",
 			irq[i], io[i] );
-		if (init_airo_card( irq[i], io[i], 0 ))
+		if (init_airo_card( irq[i], io[i], 0, NULL ))
 			have_isa_dev = 1;
 	}
 
@@ -7591,7 +7589,7 @@
 
 	/* Write stuff */
 	if (test_bit(FLAG_MPI,&ai->flags))
-		memcpy(ai->pciaux + 0x8000, ai->flash, FLASHSIZE);
+		memcpy_toio(ai->pciaux + 0x8000, ai->flash, FLASHSIZE);
 	else {
 		OUT4500(ai,AUXPAGE,0x100);
 		OUT4500(ai,AUXOFF,0);
diff -Nru a/drivers/net/wireless/airo_cs.c b/drivers/net/wireless/airo_cs.c
--- a/drivers/net/wireless/airo_cs.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/net/wireless/airo_cs.c	2005-03-01 23:39:09 -08:00
@@ -52,7 +52,7 @@
 */
 #ifdef PCMCIA_DEBUG
 static int pc_debug = PCMCIA_DEBUG;
-MODULE_PARM(pc_debug, "i");
+module_param(pc_debug, int, 0);
 static char *version = "$Revision: 1.2 $";
 #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args);
 #else
@@ -61,22 +61,12 @@
 
 /*====================================================================*/
 
-/* Parameters that can be set with 'insmod' */
-
-/* The old way: bit map of interrupts to choose from */
-/* This means pick from 15, 14, 12, 11, 10, 9, 7, 5, 4, and 3 */
-static u_int irq_mask = 0xdeb8;
-/* Newer, simpler way of listing specific interrupts */
-static int irq_list[4] = { -1 };
-
 MODULE_AUTHOR("Benjamin Reed");
 MODULE_DESCRIPTION("Support for Cisco/Aironet 802.11 wireless ethernet \
                    cards.  This is the module that links the PCMCIA card \
 		   with the airo module.");
 MODULE_LICENSE("Dual BSD/GPL");
 MODULE_SUPPORTED_DEVICE("Aironet 4500, 4800 and Cisco 340 PCMCIA cards");
-MODULE_PARM(irq_mask, "i");
-MODULE_PARM(irq_list, "1-4i");
 
 /*====================================================================*/
 
@@ -89,7 +79,7 @@
    event handler. 
 */
 
-struct net_device *init_airo_card( int, int, int );
+struct net_device *init_airo_card( int, int, int, struct device * );
 void stop_airo_card( struct net_device *, int );
 int reset_airo_card( struct net_device * );
 
@@ -178,7 +168,7 @@
 	client_reg_t client_reg;
 	dev_link_t *link;
 	local_info_t *local;
-	int ret, i;
+	int ret;
 	
 	DEBUG(0, "airo_attach()\n");
 
@@ -192,12 +182,7 @@
 	
 	/* Interrupt setup */
 	link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
-	link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
-	if (irq_list[0] == -1)
-		link->irq.IRQInfo2 = irq_mask;
-	else
-		for (i = 0; i < 4; i++)
-			link->irq.IRQInfo2 |= 1 << irq_list[i];
+	link->irq.IRQInfo1 = IRQ_LEVEL_ID;
 	link->irq.Handler = NULL;
 	
 	/*
@@ -225,7 +210,6 @@
 	link->next = dev_list;
 	dev_list = link;
 	client_reg.dev_info = &dev_info;
-	client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
 	client_reg.EventMask =
 		CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
 		CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
@@ -450,7 +434,7 @@
 	CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf));
 	((local_info_t*)link->priv)->eth_dev = 
 		init_airo_card( link->irq.AssignedIRQ,
-				link->io.BasePort1, 1 );
+				link->io.BasePort1, 1, &handle_to_dev(handle) );
 	if (!((local_info_t*)link->priv)->eth_dev) goto cs_failed;
 	
 	/*
@@ -592,13 +576,7 @@
 static void airo_cs_cleanup(void)
 {
 	pcmcia_unregister_driver(&airo_driver);
-
-	/* XXX: this really needs to move into generic code.. */
-	while (dev_list != NULL) {
-		if (dev_list->state & DEV_CONFIG)
-			airo_release(dev_list);
-		airo_detach(dev_list);
-	}
+	BUG_ON(dev_list != NULL);
 }
 
 /*
diff -Nru a/drivers/net/wireless/arlan-main.c b/drivers/net/wireless/arlan-main.c
--- a/drivers/net/wireless/arlan-main.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/net/wireless/arlan-main.c	2005-03-01 23:39:07 -08:00
@@ -39,35 +39,32 @@
 static int irq = irqUNKNOWN;
 static int txScrambled = 1;
 static int mdebug;
-#endif
 
-MODULE_PARM(irq, "i");
-MODULE_PARM(mem, "i");
-MODULE_PARM(arlan_debug, "i");
-MODULE_PARM(testMemory, "i");
-MODULE_PARM(spreadingCode, "i");
-MODULE_PARM(channelNumber, "i");
-MODULE_PARM(channelSet, "i");
-MODULE_PARM(systemId, "i");
-MODULE_PARM(registrationMode, "i");
-MODULE_PARM(radioNodeId, "i");
-MODULE_PARM(SID, "i");
-MODULE_PARM(txScrambled, "i");
-MODULE_PARM(keyStart, "i");
-MODULE_PARM(mdebug, "i");
-MODULE_PARM(tx_delay_ms, "i");
-MODULE_PARM(retries, "i");
-MODULE_PARM(async, "i");
-MODULE_PARM(tx_queue_len, "i");
-MODULE_PARM(arlan_entry_debug, "i");
-MODULE_PARM(arlan_exit_debug, "i");
-MODULE_PARM(arlan_entry_and_exit_debug, "i");
-MODULE_PARM(arlan_EEPROM_bad, "i");
+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(mem, "Arlan memory address for single device probing");
-MODULE_PARM_DESC(arlan_debug, "Arlan debug enable (0-1)");
 MODULE_PARM_DESC(testMemory, "(unused)");
 MODULE_PARM_DESC(mdebug, "Arlan multicast debugging (0-1)");
+#endif
+
+module_param(arlan_debug, int, 0);
+module_param(spreadingCode, int, 0);
+module_param(channelNumber, int, 0);
+module_param(channelSet, int, 0);
+module_param(systemId, int, 0);
+module_param(registrationMode, int, 0);
+module_param(radioNodeId, int, 0);
+module_param(SID, int, 0);
+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_PARM_DESC(retries, "Arlan maximum packet retransmisions");
 #ifdef ARLAN_ENTRY_EXIT_DEBUGGING
 MODULE_PARM_DESC(arlan_entry_debug, "Arlan driver function entry debugging");
@@ -129,7 +126,7 @@
 
 static inline int arlan_drop_tx(struct net_device *dev)
 {
-	struct arlan_private *priv = dev->priv;
+	struct arlan_private *priv = netdev_priv(dev);
 
 	priv->stats.tx_errors++;
 	if (priv->Conf->tx_delay_ms)
@@ -152,8 +149,8 @@
 
 int arlan_command(struct net_device *dev, int command_p)
 {
-	struct arlan_private *priv = dev->priv;
-	volatile struct arlan_shmem *arlan = priv->card;
+	struct arlan_private *priv = netdev_priv(dev);
+	volatile struct arlan_shmem __iomem *arlan = priv->card;
 	struct arlan_conf_stru *conf = priv->Conf;
 	int udelayed = 0;
 	int i = 0;
@@ -368,7 +365,7 @@
 		if (!registrationBad(dev))
 		{
 			setInterruptEnable(dev);
-			memset_io((void *) arlan->commandParameter, 0, 0xf);
+			memset_io(arlan->commandParameter, 0, 0xf);
 			WRITESHMB(arlan->commandByte, ARLAN_COM_INT | ARLAN_COM_RX_ENABLE);
 			WRITESHMB(arlan->commandParameter[0], conf->rxParameter);
 			arlan_interrupt_lancpu(dev);
@@ -398,9 +395,9 @@
 					   priv->last_rx_int_ack_time + us2ticks(conf->rx_tweak2)))
 			{
 				setInterruptEnable(dev);
-				memset_io((void *) arlan->commandParameter, 0, 0xf);
+				memset_io(arlan->commandParameter, 0, 0xf);
 				WRITESHMB(arlan->commandByte, ARLAN_COM_TX_ENABLE | ARLAN_COM_INT);
-				memcpy_toio((void *) arlan->commandParameter, &TXLAST(dev), 14);
+				memcpy_toio(arlan->commandParameter, &TXLAST(dev), 14);
 //				for ( i=1 ; i < 15 ; i++) printk("%02x:",READSHMB(arlan->commandParameter[i]));
 				priv->tx_last_sent = jiffies;
 				arlan_interrupt_lancpu(dev);
@@ -481,7 +478,7 @@
 
 static inline void arlan_command_process(struct net_device *dev)
 {
-	struct arlan_private *priv = dev->priv;
+	struct arlan_private *priv = netdev_priv(dev);
 
 	int times = 0;
 	while (priv->waiting_command_mask && times < 8)
@@ -502,7 +499,7 @@
 
 static inline void arlan_retransmit_now(struct net_device *dev)
 {
-	struct arlan_private *priv = dev->priv;
+	struct arlan_private *priv = netdev_priv(dev);
 
 
 	ARLAN_DEBUG_ENTRY("arlan_retransmit_now");
@@ -540,7 +537,7 @@
 static void arlan_registration_timer(unsigned long data)
 {
 	struct net_device *dev = (struct net_device *) data;
-	struct arlan_private *priv = dev->priv;
+	struct arlan_private *priv = netdev_priv(dev);
 	int bh_mark_needed = 0;
 	int next_tick = 1;
 	long lostTime = ((long)jiffies - (long)priv->registrationLastSeen)
@@ -633,7 +630,7 @@
 
 static void arlan_print_registers(struct net_device *dev, int line)
 {
-	struct arlan_private *priv = dev->priv;
+	struct arlan_private *priv = netdev_priv(dev);
 	volatile struct arlan_shmem *arlan = priv->card;
 
 	u_char hostcpuLock, lancpuLock, controlRegister, cntrlRegImage,
@@ -663,8 +660,8 @@
 {
 	int i;
 
-	struct arlan_private *priv = dev->priv;
-	volatile struct arlan_shmem *arlan = priv->card;
+	struct arlan_private *priv = netdev_priv(dev);
+	volatile struct arlan_shmem __iomem *arlan = priv->card;
 	struct arlan_conf_stru *conf = priv->Conf;
 
 	int tailStarts = 0x800;
@@ -673,9 +670,9 @@
 
 	ARLAN_DEBUG_ENTRY("arlan_hw_tx");
 	if (TXHEAD(dev).offset)
-		headEnds = (((TXHEAD(dev).offset + TXHEAD(dev).length - (((int) arlan->txBuffer) - ((int) arlan))) / 64) + 1) * 64;
+		headEnds = (((TXHEAD(dev).offset + TXHEAD(dev).length - offsetof(struct arlan_shmem, txBuffer)) / 64) + 1) * 64;
 	if (TXTAIL(dev).offset)
-		tailStarts = 0x800 - (((TXTAIL(dev).offset - (((int) arlan->txBuffer) - ((int) arlan))) / 64) + 2) * 64;
+		tailStarts = 0x800 - (((TXTAIL(dev).offset - offsetof(struct arlan_shmem, txBuffer)) / 64) + 2) * 64;
 
 
 	if (!TXHEAD(dev).offset && length < tailStarts)
@@ -684,7 +681,7 @@
 			printk(KERN_ERR "TXHEAD insert, tailStart %d\n", tailStarts);
 
 		TXHEAD(dev).offset =
-			(((int) arlan->txBuffer) - ((int) arlan));
+			offsetof(struct arlan_shmem, txBuffer);
 		TXHEAD(dev).length = length - ARLAN_FAKE_HDR_LEN;
 		for (i = 0; i < 6; i++)
 			TXHEAD(dev).dest[i] = buf[i];
@@ -692,7 +689,7 @@
 		TXHEAD(dev).retries = conf->txRetries;	/* 0 is use default */
 		TXHEAD(dev).routing = conf->txRouting;
 		TXHEAD(dev).scrambled = conf->txScrambled;
-		memcpy_toio(((char *) arlan + TXHEAD(dev).offset), buf + ARLAN_FAKE_HDR_LEN, TXHEAD(dev).length);
+		memcpy_toio((char __iomem *)arlan + TXHEAD(dev).offset, buf + ARLAN_FAKE_HDR_LEN, TXHEAD(dev).length);
 	}
 	else if (!TXTAIL(dev).offset && length < (0x800 - headEnds))
 	{
@@ -700,7 +697,7 @@
 			printk(KERN_ERR "TXTAIL insert, headEnd %d\n", headEnds);
 
 		TXTAIL(dev).offset =
-			(((int) arlan->txBuffer) - ((int) arlan)) + 0x800 - (length / 64 + 2) * 64;
+			offsetof(struct arlan_shmem, txBuffer) + 0x800 - (length / 64 + 2) * 64;
 		TXTAIL(dev).length = length - ARLAN_FAKE_HDR_LEN;
 		for (i = 0; i < 6; i++)
 			TXTAIL(dev).dest[i] = buf[i];
@@ -708,7 +705,7 @@
 		TXTAIL(dev).retries = conf->txRetries;
 		TXTAIL(dev).routing = conf->txRouting;
 		TXTAIL(dev).scrambled = conf->txScrambled;
-		memcpy_toio(((char *) arlan + TXTAIL(dev).offset), buf + ARLAN_FAKE_HDR_LEN, TXTAIL(dev).length);
+		memcpy_toio(((char __iomem *)arlan + TXTAIL(dev).offset), buf + ARLAN_FAKE_HDR_LEN, TXTAIL(dev).length);
 	}
 	else
 	{
@@ -764,8 +761,8 @@
 
 static int arlan_hw_config(struct net_device *dev)
 {
-	struct arlan_private *priv = dev->priv;
-	volatile struct arlan_shmem *arlan = priv->card;
+	struct arlan_private *priv = netdev_priv(dev);
+	volatile struct arlan_shmem __iomem *arlan = priv->card;
 	struct arlan_conf_stru *conf = priv->Conf;
 
 	ARLAN_DEBUG_ENTRY("arlan_hw_config");
@@ -847,8 +844,8 @@
 static int arlan_read_card_configuration(struct net_device *dev)
 {
 	u_char tlx415;
-	struct arlan_private *priv = dev->priv;
-	volatile struct arlan_shmem *arlan = priv->card;
+	struct arlan_private *priv = netdev_priv(dev);
+	volatile struct arlan_shmem __iomem *arlan = priv->card;
 	struct arlan_conf_stru *conf = priv->Conf;
 
 	ARLAN_DEBUG_ENTRY("arlan_read_card_configuration");
@@ -972,7 +969,7 @@
 static int __init arlan_check_fingerprint(unsigned long memaddr)
 {
 	static const char probeText[] = "TELESYSTEM SLW INC.    ARLAN \0";
-	volatile struct arlan_shmem *arlan = (struct arlan_shmem *) memaddr;
+	volatile struct arlan_shmem __iomem *arlan = (struct arlan_shmem *) memaddr;
 	unsigned long paddr = virt_to_phys((void *) memaddr);
 	char tempBuf[49];
 
@@ -1000,7 +997,7 @@
 
 static int arlan_change_mtu(struct net_device *dev, int new_mtu)
 {
-	struct arlan_private *priv = dev->priv;
+	struct arlan_private *priv = netdev_priv(dev);
 	struct arlan_conf_stru *conf = priv->Conf;
 
 	ARLAN_DEBUG_ENTRY("arlan_change_mtu");
@@ -1040,7 +1037,7 @@
 
 static int __init arlan_setup_device(struct net_device *dev, int num)
 {
-	struct arlan_private *ap = dev->priv;
+	struct arlan_private *ap = netdev_priv(dev);
 	int err;
 
 	ARLAN_DEBUG_ENTRY("arlan_setup_device");
@@ -1081,7 +1078,7 @@
 static int __init arlan_probe_here(struct net_device *dev, 
 				   unsigned long memaddr)
 {
-	struct arlan_private *ap = dev->priv;
+	struct arlan_private *ap = netdev_priv(dev);
 
 	ARLAN_DEBUG_ENTRY("arlan_probe_here");
 
@@ -1110,8 +1107,8 @@
 
 static int arlan_open(struct net_device *dev)
 {
-	struct arlan_private *priv = dev->priv;
-	volatile struct arlan_shmem *arlan = priv->card;
+	struct arlan_private *priv = netdev_priv(dev);
+	volatile struct arlan_shmem __iomem *arlan = priv->card;
 	int ret = 0;
 
 	ARLAN_DEBUG_ENTRY("arlan_open");
@@ -1208,7 +1205,7 @@
 
 static inline int DoNotReTransmitCrap(struct net_device *dev)
 {
-	struct arlan_private *priv = dev->priv;
+	struct arlan_private *priv = netdev_priv(dev);
 
 	if (TXLAST(dev).length < priv->Conf->ReTransmitPacketMaxSize)
 		return 1;
@@ -1218,7 +1215,7 @@
 
 static inline int DoNotWaitReTransmitCrap(struct net_device *dev)
 {
-	struct arlan_private *priv = dev->priv;
+	struct arlan_private *priv = netdev_priv(dev);
 
 	if (TXLAST(dev).length < priv->Conf->waitReTransmitPacketMaxSize)
 		return 1;
@@ -1227,7 +1224,7 @@
 
 static inline void arlan_queue_retransmit(struct net_device *dev)
 {
-	struct arlan_private *priv = dev->priv;
+	struct arlan_private *priv = netdev_priv(dev);
 
 	ARLAN_DEBUG_ENTRY("arlan_queue_retransmit");
 
@@ -1242,7 +1239,7 @@
 
 static inline void RetryOrFail(struct net_device *dev)
 {
-	struct arlan_private *priv = dev->priv;
+	struct arlan_private *priv = netdev_priv(dev);
 
 	ARLAN_DEBUG_ENTRY("RetryOrFail");
 
@@ -1263,7 +1260,7 @@
 
 static void arlan_tx_done_interrupt(struct net_device *dev, int status)
 {
-	struct arlan_private *priv = dev->priv;
+	struct arlan_private *priv = netdev_priv(dev);
 
 	ARLAN_DEBUG_ENTRY("arlan_tx_done_interrupt");
 
@@ -1405,8 +1402,8 @@
 	char *skbtmp;
 	int i = 0;
 
-	struct arlan_private *priv = dev->priv;
-	volatile struct arlan_shmem *arlan = priv->card;
+	struct arlan_private *priv = netdev_priv(dev);
+	volatile struct arlan_shmem __iomem *arlan = priv->card;
 	struct arlan_conf_stru *conf = priv->Conf;
 
 
@@ -1509,7 +1506,7 @@
 			skb->dev = dev;
 			skbtmp = skb_put(skb, pkt_len);
 
-			memcpy_fromio(skbtmp + ARLAN_FAKE_HDR_LEN, ((char *) arlan) + rxOffset, pkt_len - ARLAN_FAKE_HDR_LEN);
+			memcpy_fromio(skbtmp + ARLAN_FAKE_HDR_LEN, ((char __iomem *) arlan) + rxOffset, pkt_len - ARLAN_FAKE_HDR_LEN);
 			memcpy_fromio(skbtmp, arlan->ultimateDestAddress, 6);
 			memcpy_fromio(skbtmp + 6, arlan->rxSrc, 6);
 			WRITESHMB(arlan->rxStatus, 0x00);
@@ -1557,8 +1554,8 @@
 
 static void arlan_process_interrupt(struct net_device *dev)
 {
-	struct arlan_private *priv = dev->priv;
-	volatile struct arlan_shmem *arlan = priv->card;
+	struct arlan_private *priv = netdev_priv(dev);
+	volatile struct arlan_shmem __iomem *arlan = priv->card;
 	u_char rxStatus = READSHMB(arlan->rxStatus);
 	u_char txStatus = READSHMB(arlan->txStatus);
 	u_short rxOffset = READSHMS(arlan->rxOffset);
@@ -1660,8 +1657,8 @@
 static irqreturn_t arlan_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	struct net_device *dev = dev_id;
-	struct arlan_private *priv = dev->priv;
-	volatile struct arlan_shmem *arlan = priv->card;
+	struct arlan_private *priv = netdev_priv(dev);
+	volatile struct arlan_shmem __iomem *arlan = priv->card;
 	u_char rxStatus = READSHMB(arlan->rxStatus);
 	u_char txStatus = READSHMB(arlan->txStatus);
 
@@ -1683,7 +1680,7 @@
 
 static int arlan_close(struct net_device *dev)
 {
-	struct arlan_private *priv = dev->priv;
+	struct arlan_private *priv = netdev_priv(dev);
 
 	ARLAN_DEBUG_ENTRY("arlan_close");
 
@@ -1717,8 +1714,8 @@
 
 static struct net_device_stats *arlan_statistics(struct net_device *dev)
 {
-	struct arlan_private *priv = dev->priv;
-	volatile struct arlan_shmem *arlan = priv->card;
+	struct arlan_private *priv = netdev_priv(dev);
+	volatile struct arlan_shmem __iomem *arlan = priv->card;
 
 
 	ARLAN_DEBUG_ENTRY("arlan_statistics");
@@ -1747,8 +1744,8 @@
 
 static void arlan_set_multicast(struct net_device *dev)
 {
-	struct arlan_private *priv = dev->priv;
-	volatile struct arlan_shmem *arlan = priv->card;
+	struct arlan_private *priv = netdev_priv(dev);
+	volatile struct arlan_shmem __iomem *arlan = priv->card;
 	struct arlan_conf_stru *conf = priv->Conf;
 	int board_conf_needed = 0;
 
diff -Nru a/drivers/net/wireless/arlan-proc.c b/drivers/net/wireless/arlan-proc.c
--- a/drivers/net/wireless/arlan-proc.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/net/wireless/arlan-proc.c	2005-03-01 23:38:58 -08:00
@@ -58,7 +58,8 @@
 static const char *arlan_diagnostic_info_string(struct net_device *dev)
 {
 
-	volatile struct arlan_shmem *arlan = ((struct arlan_private *) dev->priv)->card;
+	struct arlan_private *priv = netdev_priv(dev);
+	volatile struct arlan_shmem __iomem *arlan = priv->card;
 	u_char diagnosticInfo;
 
 	READSHM(diagnosticInfo, arlan->diagnosticInfo, u_char);
@@ -113,7 +114,8 @@
 static const char *arlan_hardware_type_string(struct net_device *dev)
 {
 	u_char hardwareType;
-	volatile struct arlan_shmem *arlan = ((struct arlan_private *) dev->priv)->card;
+	struct arlan_private *priv = netdev_priv(dev);
+	volatile struct arlan_shmem __iomem *arlan = priv->card;
 
 	READSHM(hardwareType, arlan->hardwareType, u_char);
 	switch (hardwareType)
@@ -189,7 +191,8 @@
 	u_char diagnosticInfo;
 	u_short diagnosticOffset;
 	u_char hardwareType;
-	volatile struct arlan_shmem *arlan = ((struct arlan_private *) dev->priv)->card;
+	struct arlan_private *priv = netdev_priv(dev);
+	volatile struct arlan_shmem __iomem *arlan = priv->card;
 
 	//  ARLAN_DEBUG_ENTRY("arlan_print_diagnostic_info");
 
@@ -254,7 +257,8 @@
 	int i;
 	int memlen = sizeof(struct arlan_shmem) - 0xF;	/* avoid control register */
 	volatile char *arlan_mem = (char *) (dev->mem_start);
-	volatile struct arlan_shmem *arlan = ((struct arlan_private *) dev->priv)->card;
+	struct arlan_private *priv = netdev_priv(dev);
+	volatile struct arlan_shmem __iomem *arlan = priv->card;
 	char pattern;
 
 	ptr = NULL;
@@ -319,7 +323,8 @@
 static int arlan_setup_card_by_book(struct net_device *dev)
 {
 	u_char irqLevel, configuredStatusFlag;
-	volatile struct arlan_shmem *arlan = ((struct arlan_private *) dev->priv)->card;
+	struct arlan_private *priv = netdev_priv(dev);
+	volatile struct arlan_shmem __iomem *arlan = priv->card;
 
 //	ARLAN_DEBUG_ENTRY("arlan_setup_card");
 
diff -Nru a/drivers/net/wireless/arlan.h b/drivers/net/wireless/arlan.h
--- a/drivers/net/wireless/arlan.h	2005-03-01 23:38:58 -08:00
+++ b/drivers/net/wireless/arlan.h	2005-03-01 23:38:58 -08:00
@@ -332,7 +332,7 @@
 /* Information that need to be kept for each board. */
 struct arlan_private {
       struct net_device_stats stats;
-      struct arlan_shmem * card;
+      struct arlan_shmem __iomem * card;
       struct arlan_shmem * conf;
 
       struct arlan_conf_stru * Conf;	     
@@ -403,14 +403,12 @@
 #define ARLAN_COM_INT                 0x80
 
 
-#define TXLAST(dev) (((struct arlan_private *)dev->priv)->txRing[((struct arlan_private *)dev->priv)->txLast])
-#define TXHEAD(dev) (((struct arlan_private *)dev->priv)->txRing[0])
-#define TXTAIL(dev) (((struct arlan_private *)dev->priv)->txRing[1])
-
-#define TXBuffStart(dev) \
- ((int)(((struct arlan_private *)dev->priv)->card)->txBuffer) - ((int)(((struct arlan_private *)dev->priv)->card) )
-#define TXBuffEnd(dev) \
- ((int)(((struct arlan_private *)dev->priv)->card)->rxBuffer) - ((int)(((struct arlan_private *)dev->priv)->card)
+#define TXLAST(dev) (((struct arlan_private *)netdev_priv(dev))->txRing[((struct arlan_private *)netdev_priv(dev))->txLast])
+#define TXHEAD(dev) (((struct arlan_private *)netdev_priv(dev))->txRing[0])
+#define TXTAIL(dev) (((struct arlan_private *)netdev_priv(dev))->txRing[1])
+
+#define TXBuffStart(dev) offsetof(struct arlan_shmem, txBuffer)
+#define TXBuffEnd(dev) offsetof(struct arlan_shmem, xxBuffer)
  
 #define READSHM(to,from,atype) {\
 	atype tmp;\
@@ -451,16 +449,16 @@
 
 
 #define registrationBad(dev)\
-   ( (   READSHMB(((struct arlan_private *)dev->priv)->card->registrationMode)    > 0) && \
-     (   READSHMB(((struct arlan_private *)dev->priv)->card->registrationStatus) == 0)    )
+   ( (   READSHMB(((struct arlan_private *)netdev_priv(dev))->card->registrationMode)    > 0) && \
+     (   READSHMB(((struct arlan_private *)netdev_priv(dev))->card->registrationStatus) == 0)    )
 
 
 #define readControlRegister(dev)\
- 	READSHMB(((struct arlan_private *)dev->priv)->card->cntrlRegImage)
+ 	READSHMB(((struct arlan_private *)netdev_priv(dev))->card->cntrlRegImage)
 
 #define writeControlRegister(dev, v){\
-   WRITESHMB(((struct arlan_private *)dev->priv)->card->cntrlRegImage	,((v) &0xF) );\
-   WRITESHMB(((struct arlan_private *)dev->priv)->card->controlRegister	,(v) 	);}
+   WRITESHMB(((struct arlan_private *)netdev_priv(dev))->card->cntrlRegImage	,((v) &0xF) );\
+   WRITESHMB(((struct arlan_private *)netdev_priv(dev))->card->controlRegister	,(v) 	);}
 
 
 #define arlan_interrupt_lancpu(dev) {\
diff -Nru a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c
--- a/drivers/net/wireless/atmel_cs.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/net/wireless/atmel_cs.c	2005-03-01 23:38:57 -08:00
@@ -65,7 +65,7 @@
 */
 #ifdef PCMCIA_DEBUG
 static int pc_debug = PCMCIA_DEBUG;
-MODULE_PARM(pc_debug, "i");
+module_param(pc_debug, int, 0);
 static char *version = "$Revision: 1.2 $";
 #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args);
 #else
@@ -74,20 +74,10 @@
 
 /*====================================================================*/
 
-/* Parameters that can be set with 'insmod' */
-
-/* The old way: bit map of interrupts to choose from */
-/* This means pick from 15, 14, 12, 11, 10, 9, 7, 5, 4, and 3 */
-static u_int irq_mask = 0xdeb8;
-/* Newer, simpler way of listing specific interrupts */
-static int irq_list[4] = { -1 };
-
 MODULE_AUTHOR("Simon Kelley");
 MODULE_DESCRIPTION("Support for Atmel at76c50x 802.11 wireless ethernet cards.");
 MODULE_LICENSE("GPL");
 MODULE_SUPPORTED_DEVICE("Atmel at76c50x PCMCIA cards");
-MODULE_PARM(irq_mask, "i");
-MODULE_PARM(irq_list, "1-4i");
 
 /*====================================================================*/
 
@@ -190,7 +180,7 @@
 	client_reg_t client_reg;
 	dev_link_t *link;
 	local_info_t *local;
-	int ret, i;
+	int ret;
 	
 	DEBUG(0, "atmel_attach()\n");
 
@@ -204,12 +194,7 @@
 	
 	/* Interrupt setup */
 	link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
-	link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
-	if (irq_list[0] == -1)
-		link->irq.IRQInfo2 = irq_mask;
-	else
-		for (i = 0; i < 4; i++)
-			link->irq.IRQInfo2 |= 1 << irq_list[i];
+	link->irq.IRQInfo1 = IRQ_LEVEL_ID;
 	link->irq.Handler = NULL;
 	
 	/*
@@ -237,7 +222,6 @@
 	link->next = dev_list;
 	dev_list = link;
 	client_reg.dev_info = &dev_info;
-	client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
 	client_reg.EventMask =
 		CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
 		CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
@@ -347,18 +331,6 @@
 	{ 0, 0, "11WAVE/11WP611AL-E", "atmel_at76c502e%s.bin", "11WAVE WaveBuddy" } 
 };
 
-/* This is strictly temporary, until PCMCIA devices get integrated into the device model. */
-static struct device *atmel_device(void)
-{
-	static struct device dev = {
-		.bus_id    = "pcmcia",
-	};
-	kobject_set_name(&dev.kobj, "atmel_cs");
-	kobject_init(&dev.kobj);
-	
-	return &dev;
-}
-
 static void atmel_config(dev_link_t *link)
 {
 	client_handle_t handle;
@@ -549,7 +521,7 @@
 		init_atmel_card(link->irq.AssignedIRQ,
 				link->io.BasePort1,
 				card_index == -1 ? NULL :  card_table[card_index].firmware,
-				atmel_device(),
+				&handle_to_dev(handle),
 				card_present, 
 				link);
 	if (!((local_info_t*)link->priv)->eth_dev) 
@@ -693,13 +665,7 @@
 static void atmel_cs_cleanup(void)
 {
         pcmcia_unregister_driver(&atmel_driver);
-
-        /* XXX: this really needs to move into generic code.. */
-        while (dev_list != NULL) {
-                if (dev_list->state & DEV_CONFIG)
-                        atmel_release(dev_list);
-                atmel_detach(dev_list);
-        }
+	BUG_ON(dev_list != NULL);
 }
 
 /*
diff -Nru a/drivers/net/wireless/netwave_cs.c b/drivers/net/wireless/netwave_cs.c
--- a/drivers/net/wireless/netwave_cs.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/net/wireless/netwave_cs.c	2005-03-01 23:39:17 -08:00
@@ -161,7 +161,7 @@
 
 #ifdef PCMCIA_DEBUG
 static int pc_debug = PCMCIA_DEBUG;
-MODULE_PARM(pc_debug, "i");
+module_param(pc_debug, int, 0);
 #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
 static char *version =
 "netwave_cs.c 0.3.0 Thu Jul 17 14:36:02 1997 (John Markus Bjørndalen)\n";
@@ -190,16 +190,9 @@
  */
 static int mem_speed;
 
-/* Bit map of interrupts to choose from */
-/* This means pick from 15, 14, 12, 11, 10, 9, 7, 5, 4, and 3 */
-static u_int irq_mask = 0xdeb8;
-static int irq_list[4] = { -1 };
-
-MODULE_PARM(domain, "i");
-MODULE_PARM(scramble_key, "i");
-MODULE_PARM(mem_speed, "i");
-MODULE_PARM(irq_mask, "i");
-MODULE_PARM(irq_list, "1-4i");
+module_param(domain, int, 0);
+module_param(scramble_key, int, 0);
+module_param(mem_speed, int, 0);
 
 /*====================================================================*/
 
@@ -213,7 +206,7 @@
 static void netwave_detach(dev_link_t *);    /* Destroy instance */
 
 /* Hardware configuration */
-static void netwave_doreset(ioaddr_t iobase, u_char* ramBase);
+static void netwave_doreset(kio_addr_t iobase, u_char __iomem *ramBase);
 static void netwave_reset(struct net_device *dev);
 
 /* Misc device stuff */
@@ -321,7 +314,7 @@
     dev_link_t link;
     spinlock_t	spinlock;	/* Serialize access to the hardware (SMP) */
     dev_node_t node;
-    u_char     *ramBase;
+    u_char     __iomem *ramBase;
     int        timeoutCounter;
     int        lastExec;
     struct timer_list      watchdog;	/* To avoid blocking state */
@@ -340,12 +333,12 @@
  * The Netwave card is little-endian, so won't work for big endian
  * systems.
  */
-static inline unsigned short get_uint16(u_char* staddr) 
+static inline unsigned short get_uint16(u_char __iomem *staddr) 
 {
     return readw(staddr); /* Return only 16 bits */
 }
 
-static inline short get_int16(u_char* staddr)
+static inline short get_int16(u_char __iomem * staddr)
 {
     return readw(staddr);
 }
@@ -362,8 +355,8 @@
 }
 
 #ifdef WIRELESS_EXT
-static void netwave_snapshot(netwave_private *priv, u_char *ramBase, 
-			     ioaddr_t iobase) { 
+static void netwave_snapshot(netwave_private *priv, u_char __iomem *ramBase, 
+			     kio_addr_t iobase) {
     u_short resultBuffer;
 
     /* if time since last snapshot is > 1 sec. (100 jiffies?)  then take 
@@ -396,9 +389,9 @@
 static struct iw_statistics *netwave_get_wireless_stats(struct net_device *dev)
 {	
     unsigned long flags;
-    ioaddr_t iobase = dev->base_addr;
-    netwave_private *priv = (netwave_private *) dev->priv;
-    u_char *ramBase = priv->ramBase;
+    kio_addr_t iobase = dev->base_addr;
+    netwave_private *priv = netdev_priv(dev);
+    u_char __iomem *ramBase = priv->ramBase;
     struct iw_statistics* wstats;
 	
     wstats = &priv->iw_stats;
@@ -438,7 +431,7 @@
     dev_link_t *link;
     struct net_device *dev;
     netwave_private *priv;
-    int i, ret;
+    int ret;
     
     DEBUG(0, "netwave_attach()\n");
     
@@ -446,7 +439,7 @@
     dev = alloc_etherdev(sizeof(netwave_private));
     if (!dev)
 	return NULL;
-    priv = dev->priv;
+    priv = netdev_priv(dev);
     link = &priv->link;
     link->priv = dev;
 
@@ -459,12 +452,7 @@
     
     /* Interrupt setup */
     link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
-    link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
-    if (irq_list[0] == -1)
-	link->irq.IRQInfo2 = irq_mask;
-    else
-	for (i = 0; i < 4; i++)
-	    link->irq.IRQInfo2 |= 1 << irq_list[i];
+    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
     link->irq.Handler = &netwave_interrupt;
     
     /* General socket configuration */
@@ -503,7 +491,6 @@
     link->next = dev_list;
     dev_list = link;
     client_reg.dev_info = &dev_info;
-    client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
     client_reg.EventMask =
 	CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
 	CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
@@ -588,9 +575,9 @@
 			    char *extra)
 {
 	unsigned long flags;
-	ioaddr_t iobase = dev->base_addr;
-	netwave_private *priv = (netwave_private *) dev->priv;
-	u_char *ramBase = priv->ramBase;
+	kio_addr_t iobase = dev->base_addr;
+	netwave_private *priv = netdev_priv(dev);
+	u_char __iomem *ramBase = priv->ramBase;
 
 	/* Disable interrupts & save flags */
 	spin_lock_irqsave(&priv->spinlock, flags);
@@ -646,9 +633,9 @@
 				char *key)
 {
 	unsigned long flags;
-	ioaddr_t iobase = dev->base_addr;
-	netwave_private *priv = (netwave_private *) dev->priv;
-	u_char *ramBase = priv->ramBase;
+	kio_addr_t iobase = dev->base_addr;
+	netwave_private *priv = netdev_priv(dev);
+	u_char __iomem *ramBase = priv->ramBase;
 
 	/* Disable interrupts & save flags */
 	spin_lock_irqsave(&priv->spinlock, flags);
@@ -762,9 +749,9 @@
 			    char *extra)
 {
 	unsigned long flags;
-	ioaddr_t iobase = dev->base_addr;
-	netwave_private *priv = (netwave_private *) dev->priv;
-	u_char *ramBase = priv->ramBase;
+	kio_addr_t iobase = dev->base_addr;
+	netwave_private *priv = netdev_priv(dev);
+	u_char __iomem *ramBase = priv->ramBase;
 
 	/* Disable interrupts & save flags */
 	spin_lock_irqsave(&priv->spinlock, flags);
@@ -996,14 +983,14 @@
 static void netwave_pcmcia_config(dev_link_t *link) {
     client_handle_t handle = link->handle;
     struct net_device *dev = link->priv;
-    netwave_private *priv = dev->priv;
+    netwave_private *priv = netdev_priv(dev);
     tuple_t tuple;
     cisparse_t parse;
     int i, j, last_ret, last_fn;
     u_char buf[64];
     win_req_t req;
     memreq_t mem;
-    u_char *ramBase = NULL;
+    u_char __iomem *ramBase = NULL;
 
     DEBUG(0, "netwave_pcmcia_config(0x%p)\n", link);
 
@@ -1069,10 +1056,12 @@
 
     /* Store base address of the common window frame */
     ramBase = ioremap(req.Base, 0x8000);
-    ((netwave_private*)dev->priv)->ramBase = ramBase;
+    priv->ramBase = ramBase;
 
     dev->irq = link->irq.AssignedIRQ;
     dev->base_addr = link->io.BasePort1;
+    SET_NETDEV_DEV(dev, &handle_to_dev(handle));
+
     if (register_netdev(dev) != 0) {
 	printk(KERN_DEBUG "netwave_cs: register_netdev() failed\n");
 	goto failed;
@@ -1118,7 +1107,7 @@
 static void netwave_release(dev_link_t *link)
 {
     struct net_device *dev = link->priv;
-    netwave_private *priv = dev->priv;
+    netwave_private *priv = netdev_priv(dev);
 
     DEBUG(0, "netwave_release(0x%p)\n", link);
 
@@ -1149,7 +1138,8 @@
  *
  */
 static int netwave_event(event_t event, int priority,
-			 event_callback_args_t *args) {
+			 event_callback_args_t *args)
+{
     dev_link_t *link = args->client_data;
     struct net_device *dev = link->priv;
 	
@@ -1202,7 +1192,8 @@
  *
  *    Proper hardware reset of the card.
  */
-static void netwave_doreset(ioaddr_t ioBase, u_char* ramBase) {
+static void netwave_doreset(kio_addr_t ioBase, u_char __iomem *ramBase)
+{
     /* Reset card */
     wait_WOC(ioBase);
     outb(0x80, ioBase + NETWAVE_REG_PMR);
@@ -1217,9 +1208,9 @@
  */
 static void netwave_reset(struct net_device *dev) {
     /* u_char state; */
-    netwave_private *priv = (netwave_private*) dev->priv;
-    u_char *ramBase = priv->ramBase;
-    ioaddr_t iobase = dev->base_addr;
+    netwave_private *priv = netdev_priv(dev);
+    u_char __iomem *ramBase = priv->ramBase;
+    kio_addr_t iobase = dev->base_addr;
 
     DEBUG(0, "netwave_reset: Done with hardware reset\n");
 
@@ -1298,9 +1289,9 @@
                  DataOffset;
     int tmpcount; 
 	
-    netwave_private *priv = (netwave_private *) dev->priv;
-    u_char* ramBase = priv->ramBase;
-    ioaddr_t iobase = dev->base_addr;
+    netwave_private *priv = netdev_priv(dev);
+    u_char __iomem * ramBase = priv->ramBase;
+    kio_addr_t iobase = dev->base_addr;
 
     /* Disable interrupts & save flags */
     spin_lock_irqsave(&priv->spinlock, flags);
@@ -1390,11 +1381,12 @@
  *	     ready to transmit another packet.
  *	  3. A command has completed execution.
  */
-static irqreturn_t netwave_interrupt(int irq, void* dev_id, struct pt_regs *regs) {
-    ioaddr_t iobase;
-    u_char *ramBase;
+static irqreturn_t netwave_interrupt(int irq, void* dev_id, struct pt_regs *regs)
+{
+    kio_addr_t iobase;
+    u_char __iomem *ramBase;
     struct net_device *dev = (struct net_device *)dev_id;
-    struct netwave_private *priv = dev->priv;
+    struct netwave_private *priv = netdev_priv(dev);
     dev_link_t *link = &priv->link;
     int i;
     
@@ -1524,7 +1516,7 @@
 } /* netwave_watchdog */
 
 static struct net_device_stats *netwave_get_stats(struct net_device *dev) {
-    netwave_private *priv = (netwave_private*)dev->priv;
+    netwave_private *priv = netdev_priv(dev);
 
     update_stats(dev);
 
@@ -1547,7 +1539,7 @@
 
 static void update_stats(struct net_device *dev) {
     //unsigned long flags;
-/*     netwave_private *priv = (netwave_private*) dev->priv; */
+/*     netwave_private *priv = netdev_priv(dev); */
 
     //spin_lock_irqsave(&priv->spinlock, flags);
 
@@ -1557,10 +1549,11 @@
     //spin_unlock_irqrestore(&priv->spinlock, flags);
 }
 
-static int netwave_rx(struct net_device *dev) {
-    netwave_private *priv = (netwave_private*)(dev->priv);
-    u_char *ramBase = priv->ramBase;
-    ioaddr_t iobase = dev->base_addr;
+static int netwave_rx(struct net_device *dev)
+{
+    netwave_private *priv = netdev_priv(dev);
+    u_char __iomem *ramBase = priv->ramBase;
+    kio_addr_t iobase = dev->base_addr;
     u_char rxStatus;
     struct sk_buff *skb = NULL;
     unsigned int curBuffer,
@@ -1647,7 +1640,7 @@
 }
 
 static int netwave_open(struct net_device *dev) {
-    netwave_private *priv = dev->priv;
+    netwave_private *priv = netdev_priv(dev);
     dev_link_t *link = &priv->link;
 
     DEBUG(1, "netwave_open: starting.\n");
@@ -1664,7 +1657,7 @@
 }
 
 static int netwave_close(struct net_device *dev) {
-    netwave_private *priv = (netwave_private *)dev->priv;
+    netwave_private *priv = netdev_priv(dev);
     dev_link_t *link = &priv->link;
 
     DEBUG(1, "netwave_close: finishing.\n");
@@ -1692,9 +1685,7 @@
 static void __exit exit_netwave_cs(void)
 {
 	pcmcia_unregister_driver(&netwave_driver);
-
-	if (dev_list != NULL)	/* Critical situation */
-		printk("netwave_cs: devices remaining when removing module\n");
+	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_netwave_cs);
@@ -1708,8 +1699,9 @@
  */
 static void set_multicast_list(struct net_device *dev)
 {
-    ioaddr_t iobase = dev->base_addr;
-    u_char* ramBase = ((netwave_private*) dev->priv)->ramBase;
+    kio_addr_t iobase = dev->base_addr;
+    netwave_private *priv = netdev_priv(dev);
+    u_char __iomem * ramBase = priv->ramBase;
     u_char  rcvMode = 0;
    
 #ifdef PCMCIA_DEBUG
diff -Nru a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
--- a/drivers/net/wireless/orinoco.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/net/wireless/orinoco.c	2005-03-01 23:39:18 -08:00
@@ -461,12 +461,12 @@
 /* Level of debugging. Used in the macros in orinoco.h */
 #ifdef ORINOCO_DEBUG
 int orinoco_debug = ORINOCO_DEBUG;
-MODULE_PARM(orinoco_debug, "i");
+module_param(orinoco_debug, int, 0);
 EXPORT_SYMBOL(orinoco_debug);
 #endif
 
 static int suppress_linkstatus; /* = 0 */
-MODULE_PARM(suppress_linkstatus, "i");
+module_param(suppress_linkstatus, bool, 0);
 
 /********************************************************************/
 /* Compile time configuration and compatibility stuff               */
@@ -617,9 +617,8 @@
 	unsigned long flags;
 	int err;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 
 	err = __orinoco_up(dev);
 
@@ -671,10 +670,9 @@
 		return NULL; /* FIXME: Can we do better than this? */
 	}
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return NULL; /* FIXME: Erg, we've been signalled, how
-			      * do we propagate this back up? */
+	if (orinoco_lock(priv, &flags) != 0)
+		return NULL;  /* FIXME: Erg, we've been signalled, how
+			       * do we propagate this back up? */
 
 	if (priv->iw_mode == IW_MODE_ADHOC) {
 		memset(&wstats->qual, 0, sizeof(wstats->qual));
@@ -1819,10 +1817,8 @@
 		return 0;
 	}
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
-
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 		
 	err = hermes_disable_port(hw, 0);
 	if (err) {
@@ -1864,11 +1860,10 @@
 {
 	struct orinoco_private *priv = netdev_priv(dev);
 	struct hermes *hw = &priv->hw;
-	int err;
+	int err = 0;
 	unsigned long flags;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
+	if (orinoco_lock(priv, &flags) != 0)
 		/* When the hardware becomes available again, whatever
 		 * detects that is responsible for re-initializing
 		 * it. So no need for anything further */
@@ -2411,9 +2406,8 @@
 	int err = 0;
 	unsigned long flags;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 
 	err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTBSSID,
 			      ETH_ALEN, NULL, buf);
@@ -2433,9 +2427,8 @@
 	int len;
 	unsigned long flags;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 
 	if (strlen(priv->desired_essid) > 0) {
 		/* We read the desired SSID from the hardware rather
@@ -2486,9 +2479,8 @@
 	long freq = 0;
 	unsigned long flags;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 	
 	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CURRENTCHANNEL, &channel);
 	if (err)
@@ -2528,9 +2520,8 @@
 	int i;
 	unsigned long flags;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 
 	err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_SUPPORTEDDATARATES,
 			      sizeof(list), NULL, &list);
@@ -2568,9 +2559,8 @@
 
 	rrq->length = sizeof(range);
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 
 	mode = priv->iw_mode;
 	orinoco_unlock(priv, &flags);
@@ -2639,9 +2629,8 @@
 	range.min_frag = 256;
 	range.max_frag = 2346;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 	if (priv->has_wep) {
 		range.max_encoding_tokens = ORINOCO_MAX_KEYS;
 
@@ -2706,10 +2695,9 @@
 		if (copy_from_user(keybuf, erq->pointer, erq->length))
 			return -EFAULT;
 	}
-	
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 	
 	if (erq->pointer) {
 		if (erq->length > ORINOCO_MAX_KEY_SIZE) {
@@ -2788,12 +2776,10 @@
 	int index = (erq->flags & IW_ENCODE_INDEX) - 1;
 	u16 xlen = 0;
 	char keybuf[ORINOCO_MAX_KEY_SIZE];
-	int err;
 	unsigned long flags;
-	
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 
 	if ((index < 0) || (index >= ORINOCO_MAX_KEYS))
 		index = priv->tx_key;
@@ -2833,7 +2819,6 @@
 {
 	struct orinoco_private *priv = netdev_priv(dev);
 	char essidbuf[IW_ESSID_MAX_SIZE+1];
-	int err;
 	unsigned long flags;
 
 	/* Note : ESSID is ignored in Ad-Hoc demo mode, but we can set it
@@ -2851,9 +2836,8 @@
 		essidbuf[erq->length] = '\0';
 	}
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 
 	memcpy(priv->desired_essid, essidbuf, sizeof(priv->desired_essid));
 
@@ -2877,9 +2861,8 @@
 		if (err)
 			return err;
 	} else {
-		err = orinoco_lock(priv, &flags);
-		if (err)
-			return err;
+		if (orinoco_lock(priv, &flags) != 0)
+			return -EBUSY;
 		memcpy(essidbuf, priv->desired_essid, sizeof(essidbuf));
 		orinoco_unlock(priv, &flags);
 	}
@@ -2899,7 +2882,6 @@
 {
 	struct orinoco_private *priv = netdev_priv(dev);
 	char nickbuf[IW_ESSID_MAX_SIZE+1];
-	int err;
 	unsigned long flags;
 
 	if (nrq->length > IW_ESSID_MAX_SIZE)
@@ -2912,9 +2894,8 @@
 
 	nickbuf[nrq->length] = '\0';
 	
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 
 	memcpy(priv->nick, nickbuf, sizeof(priv->nick));
 
@@ -2927,12 +2908,10 @@
 {
 	struct orinoco_private *priv = netdev_priv(dev);
 	char nickbuf[IW_ESSID_MAX_SIZE+1];
-	int err;
 	unsigned long flags;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 
 	memcpy(nickbuf, priv->nick, IW_ESSID_MAX_SIZE+1);
 	orinoco_unlock(priv, &flags);
@@ -2949,7 +2928,6 @@
 {
 	struct orinoco_private *priv = netdev_priv(dev);
 	int chan = -1;
-	int err;
 	unsigned long flags;
 
 	/* We can only use this in Ad-Hoc demo mode to set the operating
@@ -2978,9 +2956,8 @@
 	     ! (priv->channel_mask & (1 << (chan-1)) ) )
 		return -EINVAL;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 	priv->channel = chan;
 	orinoco_unlock(priv, &flags);
 
@@ -2998,9 +2975,8 @@
 	if (!priv->has_sensitivity)
 		return -EOPNOTSUPP;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 	err = hermes_read_wordrec(hw, USER_BAP,
 				  HERMES_RID_CNFSYSTEMSCALE, &val);
 	orinoco_unlock(priv, &flags);
@@ -3018,7 +2994,6 @@
 {
 	struct orinoco_private *priv = netdev_priv(dev);
 	int val = srq->value;
-	int err;
 	unsigned long flags;
 
 	if (!priv->has_sensitivity)
@@ -3027,9 +3002,8 @@
 	if ((val < 1) || (val > 3))
 		return -EINVAL;
 	
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 	priv->ap_density = val;
 	orinoco_unlock(priv, &flags);
 
@@ -3040,7 +3014,6 @@
 {
 	struct orinoco_private *priv = netdev_priv(dev);
 	int val = rrq->value;
-	int err;
 	unsigned long flags;
 
 	if (rrq->disabled)
@@ -3049,9 +3022,8 @@
 	if ( (val < 0) || (val > 2347) )
 		return -EINVAL;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 
 	priv->rts_thresh = val;
 	orinoco_unlock(priv, &flags);
@@ -3065,9 +3037,8 @@
 	int err = 0;
 	unsigned long flags;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 
 	if (priv->has_mwo) {
 		if (frq->disabled)
@@ -3102,9 +3073,8 @@
 	u16 val;
 	unsigned long flags;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 	
 	if (priv->has_mwo) {
 		err = hermes_read_wordrec(hw, USER_BAP,
@@ -3166,9 +3136,8 @@
 	if (ratemode == -1)
 		return -EINVAL;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 	priv->bitratemode = ratemode;
 	orinoco_unlock(priv, &flags);
 
@@ -3185,9 +3154,8 @@
 	u16 val;
 	unsigned long flags;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 
 	ratemode = priv->bitratemode;
 
@@ -3247,9 +3215,8 @@
 	int err = 0;
 	unsigned long flags;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 
 	if (prq->disabled) {
 		priv->pm_on = 0;
@@ -3302,9 +3269,8 @@
 	u16 enable, period, timeout, mcast;
 	unsigned long flags;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 	
 	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFPMENABLED, &enable);
 	if (err)
@@ -3351,9 +3317,8 @@
 	u16 short_limit, long_limit, lifetime;
 	unsigned long flags;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 	
 	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_SHORTRETRYLIMIT,
 				  &short_limit);
@@ -3399,12 +3364,10 @@
 {
 	struct orinoco_private *priv = netdev_priv(dev);
 	int val = *( (int *) wrq->u.name );
-	int err;
 	unsigned long flags;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 
 	priv->ibss_port = val ;
 
@@ -3419,12 +3382,10 @@
 {
 	struct orinoco_private *priv = netdev_priv(dev);
 	int *val = (int *)wrq->u.name;
-	int err;
 	unsigned long flags;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 
 	*val = priv->ibss_port;
 	orinoco_unlock(priv, &flags);
@@ -3439,9 +3400,8 @@
 	int err = 0;
 	unsigned long flags;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 
 	switch (val) {
 	case 0: /* Try to do IEEE ad-hoc mode */
@@ -3478,12 +3438,10 @@
 {
 	struct orinoco_private *priv = netdev_priv(dev);
 	int *val = (int *)wrq->u.name;
-	int err;
 	unsigned long flags;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 
 	*val = priv->prefer_port3;
 	orinoco_unlock(priv, &flags);
@@ -3513,9 +3471,8 @@
 	}
 
 	/* Make sure nobody mess with the structure while we do */
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 
 	/* orinoco_lock() doesn't disable interrupts, so make sure the
 	 * interrupt rx path don't get confused while we copy */
@@ -3546,12 +3503,10 @@
 	struct iw_quality spy_stat[IW_MAX_SPY];
 	int number;
 	int i;
-	int err;
 	unsigned long flags;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 
 	number = priv->spy_number;
 	if ((number > 0) && (srq->pointer)) {
@@ -3621,9 +3576,8 @@
 		break;
 
 	case SIOCSIWMODE:
-		err = orinoco_lock(priv, &flags);
-		if (err)
-			return err;
+		if (orinoco_lock(priv, &flags) != 0)
+			return -EBUSY;
 		switch (wrq->u.mode) {
 		case IW_MODE_ADHOC:
 			if (! (priv->has_ibss || priv->has_port3) )
@@ -3648,9 +3602,8 @@
 		break;
 
 	case SIOCGIWMODE:
-		err = orinoco_lock(priv, &flags);
-		if (err)
-			return err;
+		if (orinoco_lock(priv, &flags) != 0)
+			return -EBUSY;
 		wrq->u.mode = priv->iw_mode;
 		orinoco_unlock(priv, &flags);
 		break;
@@ -3865,9 +3818,8 @@
 		if(priv->has_preamble) {
 			int val = *( (int *) wrq->u.name );
 
-			err = orinoco_lock(priv, &flags);
-			if (err)
-				return err;
+			if (orinoco_lock(priv, &flags) != 0)
+				return -EBUSY;
 			if (val)
 				priv->preamble = 1;
 			else
@@ -3882,9 +3834,8 @@
 		if(priv->has_preamble) {
 			int *val = (int *)wrq->u.name;
 
-			err = orinoco_lock(priv, &flags);
-			if (err)
-				return err;
+			if (orinoco_lock(priv, &flags) != 0)
+				return -EBUSY;
 			*val = priv->preamble;
 			orinoco_unlock(priv, &flags);
 		} else
diff -Nru a/drivers/net/wireless/orinoco_cs.c b/drivers/net/wireless/orinoco_cs.c
--- a/drivers/net/wireless/orinoco_cs.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/net/wireless/orinoco_cs.c	2005-03-01 23:39:16 -08:00
@@ -54,19 +54,11 @@
 
 /* Module parameters */
 
-/* The old way: bit map of interrupts to choose from */
-/* This means pick from 15, 14, 12, 11, 10, 9, 7, 5, 4, and 3 */
-static uint irq_mask = 0xdeb8;
-/* Newer, simpler way of listing specific interrupts */
-static int irq_list[4] = { -1 };
-
 /* Some D-Link cards have buggy CIS. They do work at 5v properly, but
  * don't have any CIS entry for it. This workaround it... */
 static int ignore_cis_vcc; /* = 0 */
 
-MODULE_PARM(irq_mask, "i");
-MODULE_PARM(irq_list, "1-4i");
-MODULE_PARM(ignore_cis_vcc, "i");
+module_param(ignore_cis_vcc, int, 0);
 
 /********************************************************************/
 /* Magic constants						    */
@@ -161,7 +153,7 @@
 	struct orinoco_pccard *card;
 	dev_link_t *link;
 	client_reg_t client_reg;
-	int ret, i;
+	int ret;
 
 	dev = alloc_orinocodev(sizeof(*card), orinoco_cs_hard_reset);
 	if (! dev)
@@ -175,12 +167,7 @@
 
 	/* Interrupt setup */
 	link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
-	link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
-	if (irq_list[0] == -1)
-		link->irq.IRQInfo2 = irq_mask;
-	else
-		for (i = 0; i < 4; i++)
-			link->irq.IRQInfo2 |= 1 << irq_list[i];
+	link->irq.IRQInfo1 = IRQ_LEVEL_ID;
 	link->irq.Handler = NULL;
 
 	/* General socket configuration defaults can go here.  In this
@@ -197,7 +184,6 @@
 	dev_list = link;
 
 	client_reg.dev_info = &dev_info;
-	client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
 	client_reg.EventMask =
 		CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
 		CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
@@ -416,16 +402,8 @@
 	 * the irq structure is initialized.
 	 */
 	if (link->conf.Attributes & CONF_ENABLE_IRQ) {
-		int i;
-
 		link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
-		link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
-		if (irq_list[0] == -1)
-			link->irq.IRQInfo2 = irq_mask;
-		else
-			for (i=0; i<4; i++)
-				link->irq.IRQInfo2 |= 1 << irq_list[i];
-		
+		link->irq.IRQInfo1 = IRQ_LEVEL_ID;
   		link->irq.Handler = orinoco_interrupt; 
   		link->irq.Instance = dev; 
 		
@@ -454,6 +432,7 @@
 
 	/* register_netdev will give us an ethX name */
 	dev->name[0] = '\0';
+	SET_NETDEV_DEV(dev, &handle_to_dev(handle));
 	/* Tell the stack we exist */
 	if (register_netdev(dev) != 0) {
 		printk(KERN_ERR PFX "register_netdev() failed\n");
@@ -653,14 +632,7 @@
 exit_orinoco_cs(void)
 {
 	pcmcia_unregister_driver(&orinoco_driver);
-
-	if (dev_list)
-		DEBUG(0, PFX "Removing leftover devices.\n");
-	while (dev_list != NULL) {
-		if (dev_list->state & DEV_CONFIG)
-			orinoco_cs_release(dev_list);
-		orinoco_cs_detach(dev_list);
-	}
+	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_orinoco_cs);
diff -Nru a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c
--- a/drivers/net/wireless/prism54/isl_ioctl.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/net/wireless/prism54/isl_ioctl.c	2005-03-01 23:38:54 -08:00
@@ -1524,31 +1524,35 @@
 		     const struct obj_mlme *mlme, int error)
 {
 	union iwreq_data wrqu;
+	char *memptr;
 
-	wrqu.data.pointer = kmalloc(IW_CUSTOM_MAX, GFP_KERNEL);
-	if (!wrqu.data.pointer)
+	memptr = kmalloc(IW_CUSTOM_MAX, GFP_KERNEL);
+	if (!memptr)
 		return;
+	wrqu.data.pointer = memptr;
 	wrqu.data.length = 0;
-	format_event(priv, wrqu.data.pointer, str, mlme, &wrqu.data.length,
+	format_event(priv, memptr, str, mlme, &wrqu.data.length,
 		     error);
-	wireless_send_event(priv->ndev, IWEVCUSTOM, &wrqu, wrqu.data.pointer);
-	kfree(wrqu.data.pointer);
+	wireless_send_event(priv->ndev, IWEVCUSTOM, &wrqu, memptr);
+	kfree(memptr);
 }
 
 static void
 send_simple_event(islpci_private *priv, const char *str)
 {
 	union iwreq_data wrqu;
+	char *memptr;
 	int n = strlen(str);
 
-	wrqu.data.pointer = kmalloc(IW_CUSTOM_MAX, GFP_KERNEL);
-	if (!wrqu.data.pointer)
+	memptr = kmalloc(IW_CUSTOM_MAX, GFP_KERNEL);
+	if (!memptr)
 		return;
 	BUG_ON(n > IW_CUSTOM_MAX);
+	wrqu.data.pointer = memptr;
 	wrqu.data.length = n;
-	strcpy(wrqu.data.pointer, str);
-	wireless_send_event(priv->ndev, IWEVCUSTOM, &wrqu, wrqu.data.pointer);
-	kfree(wrqu.data.pointer);
+	strcpy(memptr, str);
+	wireless_send_event(priv->ndev, IWEVCUSTOM, &wrqu, memptr);
+	kfree(memptr);
 }
 
 static void
diff -Nru a/drivers/net/wireless/prism54/islpci_dev.c b/drivers/net/wireless/prism54/islpci_dev.c
--- a/drivers/net/wireless/prism54/islpci_dev.c	2005-03-01 23:38:51 -08:00
+++ b/drivers/net/wireless/prism54/islpci_dev.c	2005-03-01 23:38:51 -08:00
@@ -419,7 +419,7 @@
 	 * currently in progress by emptying the TX and RX queues. */
 
 	/* wait until interrupts have finished executing on other CPUs */
-	prism54_synchronize_irq(priv->pdev->irq);
+	synchronize_irq(priv->pdev->irq);
 
 	reg = readl(device_base + ISL38XX_CTRL_STAT_REG);
 	reg &= ~(ISL38XX_CTRL_STAT_RESET | ISL38XX_CTRL_STAT_RAMBOOT);
diff -Nru a/drivers/net/wireless/prism54/islpci_hotplug.c b/drivers/net/wireless/prism54/islpci_hotplug.c
--- a/drivers/net/wireless/prism54/islpci_hotplug.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/net/wireless/prism54/islpci_hotplug.c	2005-03-01 23:38:57 -08:00
@@ -163,7 +163,7 @@
 	if (rvalue || !mem_addr) {
 		printk(KERN_ERR "%s: PCI device memory region not configured; fix your BIOS or CardBus bridge/drivers\n",
 		       DRV_NAME);
-		goto do_pci_disable_device;
+		goto do_pci_release_regions;
 	}
 
 	/* enable PCI bus-mastering */
@@ -291,6 +291,8 @@
 	struct net_device *ndev = pci_get_drvdata(pdev);
 	islpci_private *priv = ndev ? netdev_priv(ndev) : NULL;
 	BUG_ON(!priv);
+
+	pci_enable_device(pdev);
 
 	printk(KERN_NOTICE "%s: got resume request\n", ndev->name);
 
diff -Nru a/drivers/net/wireless/prism54/prismcompat.h b/drivers/net/wireless/prism54/prismcompat.h
--- a/drivers/net/wireless/prism54/prismcompat.h	2005-03-01 23:38:55 -08:00
+++ b/drivers/net/wireless/prism54/prismcompat.h	2005-03-01 23:38:55 -08:00
@@ -34,11 +34,9 @@
 #include <linux/workqueue.h>
 #include <linux/compiler.h>
 
-#if !defined(CONFIG_FW_LOADER) && !defined(CONFIG_FW_LOADER_MODULE)
-#error Firmware Loading is not configured in the kernel !
+#ifndef __iomem
+#define __iomem
 #endif
-
-#define prism54_synchronize_irq(irq) synchronize_irq(irq)
 
 #define PRISM_FW_PDEV		&priv->pdev->dev
 
diff -Nru a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c
--- a/drivers/net/wireless/ray_cs.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/net/wireless/ray_cs.c	2005-03-01 23:38:55 -08:00
@@ -84,7 +84,7 @@
 #ifdef PCMCIA_DEBUG
 static int ray_debug;
 static int pc_debug = PCMCIA_DEBUG;
-MODULE_PARM(pc_debug, "i");
+module_param(pc_debug, int, 0);
 /* #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args); */
 #define DEBUG(n, args...) if (pc_debug>(n)) printk(args);
 #else
@@ -155,15 +155,8 @@
 static void start_net(u_long local);
 /* void start_net(ray_dev_t *local); */
 
-/* Create symbol table for registering with kernel in init_module */
-EXPORT_SYMBOL(ray_dev_ioctl);
-EXPORT_SYMBOL(ray_rx);
-
 /*===========================================================================*/
 /* Parameters that can be set with 'insmod' */
-/* Bit map of interrupts to choose from */
-/* This means pick from 15, 14, 12, 11, 10, 9, 7, 5, 4, and 3 */
-static u_long irq_mask = 0xdeb8;
 
 /* ADHOC=0, Infrastructure=1 */
 static int net_type = ADHOC;
@@ -226,18 +219,17 @@
 MODULE_DESCRIPTION("Raylink/WebGear wireless LAN driver");
 MODULE_LICENSE("GPL");
 
-MODULE_PARM(irq_mask,"i");
-MODULE_PARM(net_type,"i");
-MODULE_PARM(hop_dwell,"i");
-MODULE_PARM(beacon_period,"i");
-MODULE_PARM(psm,"i");
-MODULE_PARM(essid,"s");
-MODULE_PARM(translate,"i");
-MODULE_PARM(country,"i");
-MODULE_PARM(sniffer,"i");
-MODULE_PARM(bc,"i");
-MODULE_PARM(phy_addr,"s");
-MODULE_PARM(ray_mem_speed, "i");
+module_param(net_type, int, 0);
+module_param(hop_dwell, int, 0);
+module_param(beacon_period, int, 0);
+module_param(psm, int, 0);
+module_param(essid, charp, 0);
+module_param(translate, int, 0);
+module_param(country, int, 0);
+module_param(sniffer, int, 0);
+module_param(bc, int, 0);
+module_param(phy_addr, charp, 0);
+module_param(ray_mem_speed, int, 0);
 
 static UCHAR b5_default_startup_parms[] = {
     0,   0,                         /* Adhoc station */
@@ -358,8 +350,7 @@
 
     /* Interrupt setup. For PCMCIA, driver takes what's given */
     link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
-    link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
-    link->irq.IRQInfo2 = irq_mask;
+    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
     link->irq.Handler = &ray_interrupt;
 
     /* General socket configuration */
@@ -402,7 +393,6 @@
     link->next = dev_list;
     dev_list = link;
     client_reg.dev_info = &dev_info;
-    client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
     client_reg.EventMask =
         CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
         CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
@@ -568,6 +558,7 @@
         return;
     }
 
+    SET_NETDEV_DEV(dev, &handle_to_dev(handle));
     i = register_netdev(dev);
     if (i != 0) {
         printk("ray_config register_netdev() failed\n");
@@ -2956,8 +2947,7 @@
 #endif
 
     pcmcia_unregister_driver(&ray_driver);
-    while (dev_list != NULL)
-        ray_detach(dev_list);
+    BUG_ON(dev_list != NULL);
 } /* exit_ray_cs */
 
 module_init(init_ray_cs);
diff -Nru a/drivers/net/wireless/strip.c b/drivers/net/wireless/strip.c
--- a/drivers/net/wireless/strip.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/net/wireless/strip.c	2005-03-01 23:39:08 -08:00
@@ -437,7 +437,7 @@
 /* Global variables							*/
 
 static LIST_HEAD(strip_list);
-static spinlock_t strip_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(strip_lock);
 
 /************************************************************************/
 /* Macros								*/
@@ -2398,7 +2398,7 @@
 	return 0;
 }
 
-static int dev_set_mac_address(struct net_device *dev, void *addr)
+static int strip_set_mac_address(struct net_device *dev, void *addr)
 {
 	struct strip *strip_info = (struct strip *) (dev->priv);
 	struct sockaddr *sa = addr;
@@ -2552,7 +2552,7 @@
 	dev->hard_start_xmit = strip_xmit;
 	dev->hard_header = strip_header;
 	dev->rebuild_header = strip_rebuild_header;
-	dev->set_mac_address = dev_set_mac_address;
+	dev->set_mac_address = strip_set_mac_address;
 	dev->get_stats = strip_get_stats;
 	dev->change_mtu = strip_change_mtu;
 }
diff -Nru a/drivers/net/wireless/wavelan.c b/drivers/net/wireless/wavelan.c
--- a/drivers/net/wireless/wavelan.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/net/wireless/wavelan.c	2005-03-01 23:39:16 -08:00
@@ -4344,7 +4344,8 @@
 		struct net_device *dev = alloc_etherdev(sizeof(net_local));
 		if (!dev)
 			break;
-		memcpy(dev->name, name[i], IFNAMSIZ);	/* Copy name */
+		if (name[i])
+			strcpy(dev->name, name[i]);	/* Copy name */
 		dev->base_addr = io[i];
 		dev->irq = irq[i];
 
diff -Nru a/drivers/net/wireless/wavelan.p.h b/drivers/net/wireless/wavelan.p.h
--- a/drivers/net/wireless/wavelan.p.h	2005-03-01 23:39:08 -08:00
+++ b/drivers/net/wireless/wavelan.p.h	2005-03-01 23:39:08 -08:00
@@ -703,10 +703,11 @@
 /* Parameters set by insmod */
 static int	io[4];
 static int	irq[4];
-static char	name[4][IFNAMSIZ];
-MODULE_PARM(io, "1-4i");
-MODULE_PARM(irq, "1-4i");
-MODULE_PARM(name, "1-4c" __MODULE_STRING(IFNAMSIZ));
+static char	*name[4];
+module_param_array(io, int, NULL, 0);
+module_param_array(irq, int, NULL, 0);
+module_param_array(name, charp, NULL, 0);
+
 MODULE_PARM_DESC(io, "WaveLAN I/O base address(es),required");
 MODULE_PARM_DESC(irq, "WaveLAN IRQ number(s)");
 MODULE_PARM_DESC(name, "WaveLAN interface neme(s)");
diff -Nru a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c
--- a/drivers/net/wireless/wavelan_cs.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/net/wireless/wavelan_cs.c	2005-03-01 23:38:58 -08:00
@@ -136,7 +136,8 @@
 	 u_char *	b,	/* buffer to fill */
 	 int		n)	/* size to read */
 {
-  u_char *	ptr = ((u_char *)dev->mem_start) + PSA_ADDR + (o << 1);
+  net_local *lp = netdev_priv(dev);
+  u_char __iomem *ptr = lp->mem + PSA_ADDR + (o << 1);
 
   while(n-- > 0)
     {
@@ -160,12 +161,13 @@
 	  u_char *	b,	/* Buffer in memory */
 	  int		n)	/* Length of buffer */
 {
-  u_char *	ptr = ((u_char *) dev->mem_start) + PSA_ADDR + (o << 1);
+  net_local *lp = netdev_priv(dev);
+  u_char __iomem *ptr = lp->mem + PSA_ADDR + (o << 1);
   int		count = 0;
-  ioaddr_t	base = dev->base_addr;
+  kio_addr_t	base = dev->base_addr;
   /* As there seem to have no flag PSA_BUSY as in the ISA model, we are
    * oblige to verify this address to know when the PSA is ready... */
-  volatile u_char *	verify = ((u_char *) dev->mem_start) + PSA_ADDR +
+  volatile u_char __iomem *verify = lp->mem + PSA_ADDR +
     (psaoff(0, psa_comp_number) << 1);
 
   /* Authorize writting to PSA */
@@ -723,7 +725,7 @@
 /* Perform a handover to a new WavePoint */
 void wv_roam_handover(wavepoint_history *wavepoint, net_local *lp)
 {
-  ioaddr_t              base = lp->dev->base_addr;  
+  kio_addr_t		base = lp->dev->base_addr;
   mm_t                  m;
   unsigned long         flags;
 
@@ -836,7 +838,7 @@
 	     int	cmd,
 	     int	result)
 {
-  ioaddr_t	base = dev->base_addr;
+  kio_addr_t	base = dev->base_addr;
   int		status;
   int		wait_completed;
   long		spin;
@@ -950,7 +952,7 @@
 		  OP0_DIAGNOSE, SR0_DIAGNOSE_PASSED))
     ret = TRUE;
 
-#ifdef DEBUG_CONFIG_ERROR
+#ifdef DEBUG_CONFIG_ERRORS
   printk(KERN_INFO "wavelan_cs: i82593 Self Test failed!\n");
 #endif
   return(ret);
@@ -968,7 +970,7 @@
 	     char *	buf,
 	     int	len)
 {
-  ioaddr_t	base = dev->base_addr;
+  kio_addr_t	base = dev->base_addr;
   int		ring_ptr = addr;
   int		chunk_len;
   char *	buf_ptr = buf;
@@ -1134,7 +1136,7 @@
 static void
 wv_mmc_show(struct net_device *	dev)
 {
-  ioaddr_t	base = dev->base_addr;
+  kio_addr_t	base = dev->base_addr;
   net_local *	lp = netdev_priv(dev);
   mmr_t		m;
 
@@ -1314,7 +1316,7 @@
 static inline void
 wv_init_info(struct net_device *	dev)
 {
-  ioaddr_t	base = dev->base_addr;
+  kio_addr_t	base = dev->base_addr;
   psa_t		psa;
   int		i;
 
@@ -1333,7 +1335,7 @@
 
 #ifdef DEBUG_BASIC_SHOW
   /* Now, let's go for the basic stuff */
-  printk(KERN_NOTICE "%s: WaveLAN: port %#x, irq %d, hw_addr",
+  printk(KERN_NOTICE "%s: WaveLAN: port %#lx, irq %d, hw_addr",
 	 dev->name, base, dev->irq);
   for(i = 0; i < WAVELAN_ADDR_SIZE; i++)
     printk("%s%02X", (i == 0) ? " " : ":", dev->dev_addr[i]);
@@ -1868,7 +1870,7 @@
 			    union iwreq_data *wrqu,
 			    char *extra)
 {
-	ioaddr_t base = dev->base_addr;
+	kio_addr_t base = dev->base_addr;
 	net_local *lp = netdev_priv(dev);
 	psa_t psa;
 	mm_t m;
@@ -1958,7 +1960,7 @@
 			    union iwreq_data *wrqu,
 			    char *extra)
 {
-	ioaddr_t base = dev->base_addr;
+	kio_addr_t base = dev->base_addr;
 	net_local *lp = netdev_priv(dev);
 	unsigned long flags;
 	int ret;
@@ -1988,7 +1990,7 @@
 			    union iwreq_data *wrqu,
 			    char *extra)
 {
-	ioaddr_t base = dev->base_addr;
+	kio_addr_t base = dev->base_addr;
 	net_local *lp = netdev_priv(dev);
 	psa_t psa;
 	unsigned long flags;
@@ -2034,7 +2036,7 @@
 			    union iwreq_data *wrqu,
 			    char *extra)
 {
-	ioaddr_t base = dev->base_addr;
+	kio_addr_t base = dev->base_addr;
 	net_local *lp = netdev_priv(dev);
 	psa_t psa;
 	unsigned long flags;
@@ -2100,7 +2102,7 @@
 			      union iwreq_data *wrqu,
 			      char *extra)
 {
-	ioaddr_t base = dev->base_addr;
+	kio_addr_t base = dev->base_addr;
 	net_local *lp = netdev_priv(dev);
 	unsigned long flags;
 	psa_t psa;
@@ -2170,7 +2172,7 @@
 			      union iwreq_data *wrqu,
 			      char *extra)
 {
-	ioaddr_t base = dev->base_addr;
+	kio_addr_t base = dev->base_addr;
 	net_local *lp = netdev_priv(dev);
 	psa_t psa;
 	unsigned long flags;
@@ -2389,7 +2391,7 @@
 			     union iwreq_data *wrqu,
 			     char *extra)
 {
-	ioaddr_t base = dev->base_addr;
+	kio_addr_t base = dev->base_addr;
 	net_local *lp = netdev_priv(dev);
 	struct iw_range *range = (struct iw_range *) extra;
 	unsigned long flags;
@@ -2465,7 +2467,7 @@
 			    union iwreq_data *wrqu,
 			    char *extra)
 {
-	ioaddr_t base = dev->base_addr;
+	kio_addr_t base = dev->base_addr;
 	net_local *lp = netdev_priv(dev);
 	psa_t psa;
 	unsigned long flags;
@@ -2741,7 +2743,7 @@
 static iw_stats *
 wavelan_get_wireless_stats(struct net_device *	dev)
 {
-  ioaddr_t		base = dev->base_addr;
+  kio_addr_t		base = dev->base_addr;
   net_local *		lp = netdev_priv(dev);
   mmr_t			m;
   iw_stats *		wstats;
@@ -2805,7 +2807,7 @@
 		  int		rfp,	/* end of frame */
 		  int		wrap)	/* start of buffer */
 {
-  ioaddr_t	base = dev->base_addr;
+  kio_addr_t	base = dev->base_addr;
   int		rp;
   int		len;
 
@@ -2968,7 +2970,7 @@
 static inline void
 wv_packet_rcv(struct net_device *	dev)
 {
-  ioaddr_t	base = dev->base_addr;
+  kio_addr_t	base = dev->base_addr;
   net_local *	lp = netdev_priv(dev);
   int		newrfp;
   int		rp;
@@ -3105,7 +3107,7 @@
 		short		length)
 {
   net_local *		lp = netdev_priv(dev);
-  ioaddr_t		base = dev->base_addr;
+  kio_addr_t		base = dev->base_addr;
   unsigned long		flags;
   int			clen = length;
   register u_short	xmtdata_base = TX_BASE;
@@ -3229,7 +3231,7 @@
 static inline int
 wv_mmc_init(struct net_device *	dev)
 {
-  ioaddr_t	base = dev->base_addr;
+  kio_addr_t	base = dev->base_addr;
   psa_t		psa;
   mmw_t		m;
   int		configured;
@@ -3423,7 +3425,7 @@
 static int
 wv_ru_stop(struct net_device *	dev)
 {
-  ioaddr_t	base = dev->base_addr;
+  kio_addr_t	base = dev->base_addr;
   net_local *	lp = netdev_priv(dev);
   unsigned long	flags;
   int		status;
@@ -3463,7 +3465,7 @@
   /* If there was a problem */
   if(spin <= 0)
     {
-#ifdef DEBUG_CONFIG_ERROR
+#ifdef DEBUG_CONFIG_ERRORS
       printk(KERN_INFO "%s: wv_ru_stop(): The chip doesn't want to stop...\n",
 	     dev->name);
 #endif
@@ -3486,7 +3488,7 @@
 static int
 wv_ru_start(struct net_device *	dev)
 {
-  ioaddr_t	base = dev->base_addr;
+  kio_addr_t	base = dev->base_addr;
   net_local *	lp = netdev_priv(dev);
   unsigned long	flags;
 
@@ -3574,7 +3576,7 @@
 static int
 wv_82593_config(struct net_device *	dev)
 {
-  ioaddr_t			base = dev->base_addr;
+  kio_addr_t			base = dev->base_addr;
   net_local *			lp = netdev_priv(dev);
   struct i82593_conf_block	cfblk;
   int				ret = TRUE;
@@ -3811,7 +3813,7 @@
 wv_hw_config(struct net_device *	dev)
 {
   net_local *		lp = netdev_priv(dev);
-  ioaddr_t		base = dev->base_addr;
+  kio_addr_t		base = dev->base_addr;
   unsigned long		flags;
   int			ret = FALSE;
 
@@ -3948,17 +3950,16 @@
 static inline int
 wv_pcmcia_config(dev_link_t *	link)
 {
-  client_handle_t	handle;
+  client_handle_t	handle = link->handle;
   tuple_t		tuple;
   cisparse_t		parse;
-  struct net_device *	dev;
+  struct net_device *	dev = (struct net_device *) link->priv;
   int			i;
   u_char		buf[64];
   win_req_t		req;
   memreq_t		mem;
+  net_local *		lp = netdev_priv(dev);
 
-  handle = link->handle;
-  dev = (struct net_device *) link->priv;
 
 #ifdef DEBUG_CONFIG_TRACE
   printk(KERN_DEBUG "->wv_pcmcia_config(0x%p)\n", link);
@@ -4045,7 +4046,8 @@
 	  break;
 	}
 
-      dev->mem_start = (u_long)ioremap(req.Base, req.Size);
+      lp->mem = ioremap(req.Base, req.Size);
+      dev->mem_start = (u_long)lp->mem;
       dev->mem_end = dev->mem_start + req.Size;
 
       mem.CardOffset = 0; mem.Page = 0;
@@ -4062,10 +4064,11 @@
       netif_start_queue(dev);
 
 #ifdef DEBUG_CONFIG_INFO
-      printk(KERN_DEBUG "wv_pcmcia_config: MEMSTART 0x%x IRQ %d IOPORT 0x%x\n",
-	     (u_int) dev->mem_start, dev->irq, (u_int) dev->base_addr);
+      printk(KERN_DEBUG "wv_pcmcia_config: MEMSTART %p IRQ %d IOPORT 0x%x\n",
+	     lp->mem, dev->irq, (u_int) dev->base_addr);
 #endif
 
+      SET_NETDEV_DEV(dev, &handle_to_dev(handle));
       i = register_netdev(dev);
       if(i != 0)
 	{
@@ -4104,13 +4107,14 @@
 wv_pcmcia_release(dev_link_t *link)
 {
   struct net_device *	dev = (struct net_device *) link->priv;
+  net_local *		lp = netdev_priv(dev);
 
 #ifdef DEBUG_CONFIG_TRACE
   printk(KERN_DEBUG "%s: -> wv_pcmcia_release(0x%p)\n", dev->name, link);
 #endif
 
   /* Don't bother checking to see if these succeed or not */
-  iounmap((u_char *)dev->mem_start);
+  iounmap(lp->mem);
   pcmcia_release_window(link->win);
   pcmcia_release_configuration(link->handle);
   pcmcia_release_io(link->handle, &link->io);
@@ -4140,7 +4144,7 @@
 {
   struct net_device *	dev;
   net_local *	lp;
-  ioaddr_t	base;
+  kio_addr_t	base;
   int		status0;
   u_int		tx_status;
 
@@ -4408,7 +4412,7 @@
 wavelan_watchdog(struct net_device *	dev)
 {
   net_local *		lp = netdev_priv(dev);
-  ioaddr_t		base = dev->base_addr;
+  kio_addr_t		base = dev->base_addr;
   unsigned long		flags;
   int			aborted = FALSE;
 
@@ -4484,7 +4488,7 @@
 {
   net_local *	lp = netdev_priv(dev);
   dev_link_t *	link = lp->link;
-  ioaddr_t	base = dev->base_addr;
+  kio_addr_t	base = dev->base_addr;
 
 #ifdef DEBUG_CALLBACK_TRACE
   printk(KERN_DEBUG "%s: ->wavelan_open(dev=0x%x)\n", dev->name,
@@ -4538,7 +4542,7 @@
 wavelan_close(struct net_device *	dev)
 {
   dev_link_t *	link = ((net_local *)netdev_priv(dev))->link;
-  ioaddr_t	base = dev->base_addr;
+  kio_addr_t	base = dev->base_addr;
 
 #ifdef DEBUG_CALLBACK_TRACE
   printk(KERN_DEBUG "%s: ->wavelan_close(dev=0x%x)\n", dev->name,
@@ -4597,7 +4601,7 @@
   dev_link_t *	link;		/* Info for cardmgr */
   struct net_device *	dev;		/* Interface generic data */
   net_local *	lp;		/* Interface specific data */
-  int		i, ret;
+  int		ret;
 
 #ifdef DEBUG_CALLBACK_TRACE
   printk(KERN_DEBUG "-> wavelan_attach()\n");
@@ -4615,12 +4619,7 @@
 
   /* Interrupt setup */
   link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
-  link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
-  if (irq_list[0] == -1)
-    link->irq.IRQInfo2 = irq_mask;
-  else
-    for (i = 0; i < 4; i++)
-      link->irq.IRQInfo2 |= 1 << irq_list[i];
+  link->irq.IRQInfo1 = IRQ_LEVEL_ID;
   link->irq.Handler = wavelan_interrupt;
 
   /* General socket configuration */
@@ -4685,7 +4684,6 @@
 
   /* Register with Card Services */
   client_reg.dev_info = &dev_info;
-  client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
   client_reg.EventMask = 
     CS_EVENT_REGISTRATION_COMPLETE |
     CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
diff -Nru a/drivers/net/wireless/wavelan_cs.p.h b/drivers/net/wireless/wavelan_cs.p.h
--- a/drivers/net/wireless/wavelan_cs.p.h	2005-03-01 23:39:09 -08:00
+++ b/drivers/net/wireless/wavelan_cs.p.h	2005-03-01 23:39:09 -08:00
@@ -645,6 +645,7 @@
   int			cell_search;		/* Searching for new cell? */
   struct timer_list	cell_timer;		/* Garbage collection */
 #endif	/* WAVELAN_ROAMING */
+  void __iomem *mem;
 };
 
 /**************************** PROTOTYPES ****************************/
@@ -794,23 +795,16 @@
  * The exact syntax is 'insmod wavelan_cs.o <var>=<value>'
  */
 
-/* Bit map of interrupts to choose from */
-/* This means pick from 15, 14, 12, 11, 10, 9, 7, 5, 4 and 3 */
-static int	irq_mask = 0xdeb8;
-static int 	irq_list[4] = { -1 };
-
 /* Shared memory speed, in ns */
 static int	mem_speed = 0;
 
 /* New module interface */
-MODULE_PARM(irq_mask, "i");
-MODULE_PARM(irq_list, "1-4i");
-MODULE_PARM(mem_speed, "i");
+module_param(mem_speed, int, 0);
 
 #ifdef WAVELAN_ROAMING		/* Conditional compile, see above in options */
 /* Enable roaming mode ? No ! Please keep this to 0 */
 static int	do_roaming = 0;
-MODULE_PARM(do_roaming, "i");
+module_param(do_roaming, bool, 0);
 #endif	/* WAVELAN_ROAMING */
 
 MODULE_LICENSE("GPL");
diff -Nru a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c
--- a/drivers/net/wireless/wl3501_cs.c	2005-03-01 23:38:43 -08:00
+++ b/drivers/net/wireless/wl3501_cs.c	2005-03-01 23:38:43 -08:00
@@ -79,7 +79,7 @@
 #define PCMCIA_DEBUG 0
 #ifdef PCMCIA_DEBUG
 static int pc_debug = PCMCIA_DEBUG;
-MODULE_PARM(pc_debug, "i");
+module_param(pc_debug, int, 0);
 #define dprintk(n, format, args...) \
 	{ if (pc_debug > (n)) \
 		printk(KERN_INFO "%s: " format "\n", __FUNCTION__ , ##args); }
@@ -97,12 +97,6 @@
 #define WL3501_RESUME	0
 #define WL3501_SUSPEND	1
 
-/* Parameters that can be set with 'insmod' */
-/* Bit map of interrupts to choose from */
-/* This means pick from 15, 14, 12, 11, 10, 9, 7, 5, 4, and 3 */
-static unsigned long wl3501_irq_mask = 0xdeb8;
-static int wl3501_irq_list[4] = { -1 };
-
 /*
  * The event() function is this driver's Card Services event handler.  It will
  * be called by Card Services when an appropriate card status event is
@@ -1967,7 +1961,7 @@
 	client_reg_t client_reg;
 	dev_link_t *link;
 	struct net_device *dev;
-	int ret, i;
+	int ret;
 
 	/* Initialize the dev_link_t structure */
 	link = kmalloc(sizeof(*link), GFP_KERNEL);
@@ -1982,11 +1976,7 @@
 
 	/* Interrupt setup */
 	link->irq.Attributes	= IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
-	link->irq.IRQInfo1	= IRQ_INFO2_VALID | IRQ_LEVEL_ID;
-	link->irq.IRQInfo2	= wl3501_irq_mask;
-	if (wl3501_irq_list[0] != -1)
-		for (i = 0; i < 4; i++)
-			link->irq.IRQInfo2 |= 1 << wl3501_irq_list[i];
+	link->irq.IRQInfo1	= IRQ_LEVEL_ID;
 	link->irq.Handler = wl3501_interrupt;
 
 	/* General socket configuration */
@@ -2015,7 +2005,6 @@
 	link->next		 = wl3501_dev_list;
 	wl3501_dev_list		 = link;
 	client_reg.dev_info	 = &wl3501_dev_info;
-	client_reg.Attributes	 = INFO_IO_CLIENT | INFO_CARD_SHARE;
 	client_reg.EventMask	 = CS_EVENT_CARD_INSERTION |
 				   CS_EVENT_RESET_PHYSICAL |
 				   CS_EVENT_CARD_RESET |
@@ -2105,6 +2094,7 @@
 
 	dev->irq = link->irq.AssignedIRQ;
 	dev->base_addr = link->io.BasePort1;
+	SET_NETDEV_DEV(dev, &handle_to_dev(handle));
 	if (register_netdev(dev)) {
 		printk(KERN_NOTICE "wl3501_cs: register_netdev() failed\n");
 		goto failed;
@@ -2267,20 +2257,12 @@
 {
 	dprintk(0, ": unloading");
 	pcmcia_unregister_driver(&wl3501_driver);
-	while (wl3501_dev_list) {
-		/* Mark the device as non-existing to minimize calls to card */
-		wl3501_dev_list->state &= ~DEV_PRESENT;
-		if (wl3501_dev_list->state & DEV_CONFIG)
-			wl3501_release(wl3501_dev_list);
-		wl3501_detach(wl3501_dev_list);
-	}
+	BUG_ON(wl3501_dev_list != NULL);
 }
 
 module_init(wl3501_init_module);
 module_exit(wl3501_exit_module);
 
-MODULE_PARM(wl3501_irq_mask, "i");
-MODULE_PARM(wl3501_irq_list, "1-4i");
 MODULE_AUTHOR("Fox Chen <mhchen@golf.ccl.itri.org.tw>, "
 	      "Arnaldo Carvalho de Melo <acme@conectiva.com.br>,"
 	      "Gustavo Niemeyer <niemeyer@conectiva.com>");
diff -Nru a/drivers/net/yellowfin.c b/drivers/net/yellowfin.c
--- a/drivers/net/yellowfin.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/net/yellowfin.c	2005-03-01 23:38:55 -08:00
@@ -140,13 +140,13 @@
 MODULE_DESCRIPTION("Packet Engines Yellowfin G-NIC Gigabit Ethernet driver");
 MODULE_LICENSE("GPL");
 
-MODULE_PARM(max_interrupt_work, "i");
-MODULE_PARM(mtu, "i");
-MODULE_PARM(debug, "i");
-MODULE_PARM(rx_copybreak, "i");
-MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i");
-MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
-MODULE_PARM(gx_fix, "i");
+module_param(max_interrupt_work, int, 0);
+module_param(mtu, int, 0);
+module_param(debug, int, 0);
+module_param(rx_copybreak, int, 0);
+module_param_array(options, int, NULL, 0);
+module_param_array(full_duplex, int, NULL, 0);
+module_param(gx_fix, int, 0);
 MODULE_PARM_DESC(max_interrupt_work, "G-NIC maximum events handled per interrupt");
 MODULE_PARM_DESC(mtu, "G-NIC MTU (all boards)");
 MODULE_PARM_DESC(debug, "G-NIC debug level (0-7)");
diff -Nru a/drivers/net/znet.c b/drivers/net/znet.c
--- a/drivers/net/znet.c	2005-03-01 23:38:44 -08:00
+++ b/drivers/net/znet.c	2005-03-01 23:38:44 -08:00
@@ -113,7 +113,7 @@
 #define ZNET_DEBUG 1
 #endif
 static unsigned int znet_debug = ZNET_DEBUG;
-MODULE_PARM (znet_debug, "i");
+module_param (znet_debug, int, 0);
 MODULE_PARM_DESC (znet_debug, "ZNet debug level");
 MODULE_LICENSE("GPL");
 
diff -Nru a/drivers/oprofile/buffer_sync.c b/drivers/oprofile/buffer_sync.c
--- a/drivers/oprofile/buffer_sync.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/oprofile/buffer_sync.c	2005-03-01 23:38:54 -08:00
@@ -35,7 +35,7 @@
 static LIST_HEAD(dying_tasks);
 static LIST_HEAD(dead_tasks);
 cpumask_t marked_cpus = CPU_MASK_NONE;
-static spinlock_t task_mortuary = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(task_mortuary);
 void process_task_mortuary(void);
 
 
@@ -46,7 +46,7 @@
  */
 static int task_free_notify(struct notifier_block * self, unsigned long val, void * data)
 {
-	struct task_struct * task = (struct task_struct *)data;
+	struct task_struct * task = data;
 	spin_lock(&task_mortuary);
 	list_add(&task->tasks, &dying_tasks);
 	spin_unlock(&task_mortuary);
@@ -62,7 +62,7 @@
 	/* 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(_smp_processor_id());
   	return 0;
 }
 
@@ -86,7 +86,7 @@
 		/* 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(_smp_processor_id());
 		return 0;
 	}
 
@@ -296,6 +296,13 @@
 }
 
  
+static void add_trace_begin(void)
+{
+	add_event_entry(ESCAPE_CODE);
+	add_event_entry(TRACE_BEGIN_CODE);
+}
+
+
 static void add_sample_entry(unsigned long offset, unsigned long event)
 {
 	add_event_entry(offset);
@@ -303,7 +310,7 @@
 }
 
 
-static void add_us_sample(struct mm_struct * mm, struct op_sample * s)
+static int add_us_sample(struct mm_struct * mm, struct op_sample * s)
 {
 	unsigned long cookie;
 	off_t offset;
@@ -312,7 +319,7 @@
  
 	if (!cookie) {
 		atomic_inc(&oprofile_stats.sample_lost_no_mapping);
-		return;
+		return 0;
 	}
 
 	if (cookie != last_cookie) {
@@ -321,6 +328,8 @@
 	}
 
 	add_sample_entry(offset, s->event);
+
+	return 1;
 }
 
  
@@ -328,15 +337,18 @@
  * sample is converted into a persistent dentry/offset pair
  * for later lookup from userspace.
  */
-static void add_sample(struct mm_struct * mm, struct op_sample * s, int in_kernel)
+static int
+add_sample(struct mm_struct * mm, struct op_sample * s, int in_kernel)
 {
 	if (in_kernel) {
 		add_sample_entry(s->eip, s->event);
+		return 1;
 	} else if (mm) {
-		add_us_sample(mm, s);
+		return add_us_sample(mm, s);
 	} else {
 		atomic_inc(&oprofile_stats.sample_lost_no_mm);
 	}
+	return 0;
 }
  
 
@@ -358,9 +370,9 @@
 }
 
 
-static inline int is_ctx_switch(unsigned long val)
+static inline int is_code(unsigned long val)
 {
-	return val == ~0UL;
+	return val == ESCAPE_CODE;
 }
  
 
@@ -397,7 +409,7 @@
 
 	rmb();
 
-	if (new_tail < (b->buffer_size))
+	if (new_tail < b->buffer_size)
 		b->tail_pos = new_tail;
 	else
 		b->tail_pos = 0;
@@ -454,6 +466,17 @@
 }
 
 
+/* FIXME: this is not sufficient if we implement syscall barrier backtrace
+ * traversal, the code switch to sb_sample_start at first kernel enter/exit
+ * switch so we need a fifth state and some special handling in sync_buffer()
+ */
+typedef enum {
+	sb_bt_ignore = -2,
+	sb_buffer_start,
+	sb_bt_start,
+	sb_sample_start,
+} sync_buffer_state;
+
 /* Sync one of the CPU's buffers into the global event buffer.
  * Here we need to go through each batch of samples punctuated
  * by context switch notes, taking the task's mmap_sem and doing
@@ -468,6 +491,7 @@
 	unsigned long cookie = 0;
 	int in_kernel = 1;
 	unsigned int i;
+	sync_buffer_state state = sb_buffer_start;
 	unsigned long available;
 
 	down(&buffer_sem);
@@ -478,14 +502,19 @@
 
 	available = get_slots(cpu_buf);
 
-	for (i=0; i < available; ++i) {
+	for (i = 0; i < available; ++i) {
 		struct op_sample * s = &cpu_buf->buffer[cpu_buf->tail_pos];
  
-		if (is_ctx_switch(s->eip)) {
-			if (s->event <= 1) {
+		if (is_code(s->eip)) {
+			if (s->event <= CPU_IS_KERNEL) {
 				/* kernel/userspace switch */
 				in_kernel = s->event;
+				if (state == sb_buffer_start)
+					state = sb_sample_start;
 				add_kernel_ctx_switch(s->event);
+			} else if (s->event == CPU_TRACE_BEGIN) {
+				state = sb_bt_start;
+				add_trace_begin();
 			} else {
 				struct mm_struct * oldmm = mm;
 
@@ -499,7 +528,13 @@
 				add_user_ctx_switch(new, cookie);
 			}
 		} else {
-			add_sample(mm, s, in_kernel);
+			if (state >= sb_bt_start &&
+			    !add_sample(mm, s, in_kernel)) {
+				if (state == sb_bt_start) {
+					state = sb_bt_ignore;
+					atomic_inc(&oprofile_stats.bt_lost_no_mapping);
+				}
+			}
 		}
 
 		increment_tail(cpu_buf);
diff -Nru a/drivers/oprofile/cpu_buffer.c b/drivers/oprofile/cpu_buffer.c
--- a/drivers/oprofile/cpu_buffer.c	2005-03-01 23:38:51 -08:00
+++ b/drivers/oprofile/cpu_buffer.c	2005-03-01 23:38:51 -08:00
@@ -18,9 +18,11 @@
  */
 
 #include <linux/sched.h>
+#include <linux/oprofile.h>
 #include <linux/vmalloc.h>
 #include <linux/errno.h>
  
+#include "event_buffer.h"
 #include "cpu_buffer.h"
 #include "buffer_sync.h"
 #include "oprof.h"
@@ -32,13 +34,12 @@
 #define DEFAULT_TIMER_EXPIRE (HZ / 10)
 int work_enabled;
 
-static void __free_cpu_buffers(int num)
+void free_cpu_buffers(void)
 {
 	int i;
  
 	for_each_online_cpu(i) {
-		if (cpu_buffer[i].buffer)
-			vfree(cpu_buffer[i].buffer);
+		vfree(cpu_buffer[i].buffer);
 	}
 }
  
@@ -58,6 +59,7 @@
  
 		b->last_task = NULL;
 		b->last_is_kernel = -1;
+		b->tracing = 0;
 		b->buffer_size = buffer_size;
 		b->tail_pos = 0;
 		b->head_pos = 0;
@@ -69,17 +71,11 @@
 	return 0;
 
 fail:
-	__free_cpu_buffers(i);
+	free_cpu_buffers();
 	return -ENOMEM;
 }
  
 
-void free_cpu_buffers(void)
-{
-	__free_cpu_buffers(NR_CPUS);
-}
-
-
 void start_cpu_work(void)
 {
 	int i;
@@ -114,6 +110,18 @@
 }
 
 
+/* Resets the cpu buffer to a sane state. */
+void cpu_buffer_reset(struct oprofile_cpu_buffer * cpu_buf)
+{
+	/* reset these to invalid values; the next sample
+	 * collected will populate the buffer with proper
+	 * values to initialize the buffer
+	 */
+	cpu_buf->last_is_kernel = -1;
+	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)
 {
@@ -135,74 +143,148 @@
 	 * increment is visible */
 	wmb();
 
-	if (new_head < (b->buffer_size))
+	if (new_head < b->buffer_size)
 		b->head_pos = new_head;
 	else
 		b->head_pos = 0;
 }
 
 
+
+
+inline static void
+add_sample(struct oprofile_cpu_buffer * cpu_buf,
+           unsigned long pc, unsigned long event)
+{
+	struct op_sample * entry = &cpu_buf->buffer[cpu_buf->head_pos];
+	entry->eip = pc;
+	entry->event = event;
+	increment_head(cpu_buf);
+}
+
+
+inline static 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.
  *
  * is_kernel is needed because on some architectures you cannot
  * tell if you are in kernel or user space simply by looking at
- * eip. We tag this in the buffer by generating kernel enter/exit
+ * pc. We tag this in the buffer by generating kernel enter/exit
  * events whenever is_kernel changes
  */
-void oprofile_add_sample(unsigned long eip, unsigned int is_kernel, 
-	unsigned long event, int cpu)
+static int log_sample(struct oprofile_cpu_buffer * cpu_buf, unsigned long pc,
+		      int is_kernel, unsigned long event)
 {
-	struct oprofile_cpu_buffer * cpu_buf = &cpu_buffer[cpu];
 	struct task_struct * task;
 
-	is_kernel = !!is_kernel;
-
 	cpu_buf->sample_received++;
- 
 
 	if (nr_available_slots(cpu_buf) < 3) {
 		cpu_buf->sample_lost_overflow++;
-		return;
+		return 0;
 	}
 
+	is_kernel = !!is_kernel;
+
 	task = current;
 
 	/* notice a switch from user->kernel or vice versa */
 	if (cpu_buf->last_is_kernel != is_kernel) {
 		cpu_buf->last_is_kernel = is_kernel;
-		cpu_buf->buffer[cpu_buf->head_pos].eip = ~0UL;
-		cpu_buf->buffer[cpu_buf->head_pos].event = is_kernel;
-		increment_head(cpu_buf);
+		add_code(cpu_buf, is_kernel);
 	}
 
 	/* notice a task switch */
 	if (cpu_buf->last_task != task) {
 		cpu_buf->last_task = task;
-		cpu_buf->buffer[cpu_buf->head_pos].eip = ~0UL;
-		cpu_buf->buffer[cpu_buf->head_pos].event = (unsigned long)task;
-		increment_head(cpu_buf);
+		add_code(cpu_buf, (unsigned long)task);
 	}
  
-	cpu_buf->buffer[cpu_buf->head_pos].eip = eip;
-	cpu_buf->buffer[cpu_buf->head_pos].event = event;
-	increment_head(cpu_buf);
+	add_sample(cpu_buf, pc, event);
+	return 1;
 }
 
+static int oprofile_begin_trace(struct oprofile_cpu_buffer * cpu_buf)
+{
+	if (nr_available_slots(cpu_buf) < 4) {
+		cpu_buf->sample_lost_overflow++;
+		return 0;
+	}
 
-/* Resets the cpu buffer to a sane state. */
-void cpu_buffer_reset(struct oprofile_cpu_buffer * cpu_buf)
+	add_code(cpu_buf, CPU_TRACE_BEGIN);
+	cpu_buf->tracing = 1;
+	return 1;
+}
+
+
+static void oprofile_end_trace(struct oprofile_cpu_buffer * cpu_buf)
 {
-	/* reset these to invalid values; the next sample
-	 * collected will populate the buffer with proper
-	 * values to initialize the buffer
-	 */
-	cpu_buf->last_is_kernel = -1;
-	cpu_buf->last_task = NULL;
+	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()];
+	unsigned long pc = profile_pc(regs);
+	int is_kernel = !user_mode(regs);
+
+	if (!backtrace_depth) {
+		log_sample(cpu_buf, pc, is_kernel, event);
+		return;
+	}
+
+	if (!oprofile_begin_trace(cpu_buf))
+		return;
+
+	/* if log_sample() fail we can't backtrace since we lost the source
+	 * of this event */
+	if (log_sample(cpu_buf, pc, is_kernel, event))
+		oprofile_ops.backtrace(regs, backtrace_depth);
+	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()];
+
+	if (!cpu_buf->tracing)
+		return;
+
+	if (nr_available_slots(cpu_buf) < 1) {
+		cpu_buf->tracing = 0;
+		cpu_buf->sample_lost_overflow++;
+		return;
+	}
+
+	/* broken frame can give an eip with the same value as an escape code,
+	 * abort the trace if we get it */
+	if (pc == ESCAPE_CODE) {
+		cpu_buf->tracing = 0;
+		cpu_buf->backtrace_aborted++;
+		return;
+	}
+
+	add_sample(cpu_buf, pc, 0);
+}
+
+
+
 /*
  * This serves to avoid cpu buffer overflow, and makes sure
  * the task mortuary progresses
@@ -212,7 +294,7 @@
  */
 static void wq_sync_buffer(void * data)
 {
-	struct oprofile_cpu_buffer * b = (struct oprofile_cpu_buffer *)data;
+	struct oprofile_cpu_buffer * b = data;
 	if (b->cpu != smp_processor_id()) {
 		printk("WQ on CPU%d, prefer CPU%d\n",
 		       smp_processor_id(), b->cpu);
diff -Nru a/drivers/oprofile/cpu_buffer.h b/drivers/oprofile/cpu_buffer.h
--- a/drivers/oprofile/cpu_buffer.h	2005-03-01 23:39:19 -08:00
+++ b/drivers/oprofile/cpu_buffer.h	2005-03-01 23:39:19 -08:00
@@ -37,9 +37,11 @@
 	unsigned long buffer_size;
 	struct task_struct * last_task;
 	int last_is_kernel;
+	int tracing;
 	struct op_sample * buffer;
 	unsigned long sample_received;
 	unsigned long sample_lost_overflow;
+	unsigned long backtrace_aborted;
 	int cpu;
 	struct work_struct work;
 } ____cacheline_aligned;
@@ -47,5 +49,9 @@
 extern struct oprofile_cpu_buffer cpu_buffer[];
 
 void cpu_buffer_reset(struct oprofile_cpu_buffer * cpu_buf);
+
+/* transient events for the CPU buffer -> event buffer */
+#define CPU_IS_KERNEL 1
+#define CPU_TRACE_BEGIN 2
 
 #endif /* OPROFILE_CPU_BUFFER_H */
diff -Nru a/drivers/oprofile/event_buffer.h b/drivers/oprofile/event_buffer.h
--- a/drivers/oprofile/event_buffer.h	2005-03-01 23:38:52 -08:00
+++ b/drivers/oprofile/event_buffer.h	2005-03-01 23:38:52 -08:00
@@ -32,6 +32,8 @@
 #define KERNEL_EXIT_SWITCH_CODE		5
 #define MODULE_LOADED_CODE		6
 #define CTX_TGID_CODE			7
+#define TRACE_BEGIN_CODE		8
+#define TRACE_END_CODE			9
  
 /* add data to the event buffer */
 void add_event_entry(unsigned long data);
diff -Nru a/drivers/oprofile/oprof.c b/drivers/oprofile/oprof.c
--- a/drivers/oprofile/oprof.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/oprofile/oprof.c	2005-03-01 23:38:54 -08:00
@@ -20,8 +20,10 @@
 #include "buffer_sync.h"
 #include "oprofile_stats.h"
  
-struct oprofile_operations * oprofile_ops;
+struct oprofile_operations oprofile_ops;
+
 unsigned long oprofile_started;
+unsigned long backtrace_depth;
 static unsigned long is_setup;
 static DECLARE_MUTEX(start_sem);
 
@@ -43,7 +45,7 @@
 	if ((err = alloc_event_buffer()))
 		goto out1;
  
-	if (oprofile_ops->setup && (err = oprofile_ops->setup()))
+	if (oprofile_ops.setup && (err = oprofile_ops.setup()))
 		goto out2;
  
 	/* Note even though this starts part of the
@@ -59,8 +61,8 @@
 	return 0;
  
 out3:
-	if (oprofile_ops->shutdown)
-		oprofile_ops->shutdown();
+	if (oprofile_ops.shutdown)
+		oprofile_ops.shutdown();
 out2:
 	free_event_buffer();
 out1:
@@ -88,7 +90,7 @@
  
 	oprofile_reset_stats();
 
-	if ((err = oprofile_ops->start()))
+	if ((err = oprofile_ops.start()))
 		goto out;
 
 	oprofile_started = 1;
@@ -104,7 +106,7 @@
 	down(&start_sem);
 	if (!oprofile_started)
 		goto out;
-	oprofile_ops->stop();
+	oprofile_ops.stop();
 	oprofile_started = 0;
 	/* wake up the daemon to read what remains */
 	wake_up_buffer_waiter();
@@ -117,8 +119,8 @@
 {
 	down(&start_sem);
 	sync_stop();
-	if (oprofile_ops->shutdown)
-		oprofile_ops->shutdown(); 
+	if (oprofile_ops.shutdown)
+		oprofile_ops.shutdown();
 	is_setup = 0;
 	free_event_buffer();
 	free_cpu_buffers();
@@ -126,38 +128,45 @@
 }
 
 
-extern void timer_init(struct oprofile_operations ** ops);
+int oprofile_set_backtrace(unsigned long val)
+{
+	int err = 0;
 
+	down(&start_sem);
 
-static int __init oprofile_init(void)
-{
-	/* Architecture must fill in the interrupt ops and the
-	 * logical CPU type, or we can fall back to the timer
-	 * interrupt profiler.
-	 */
-	int err = oprofile_arch_init(&oprofile_ops);
+	if (oprofile_started) {
+		err = -EBUSY;
+		goto out;
+	}
 
-	if (err == -ENODEV || timer) {
-		timer_init(&oprofile_ops);
-		err = 0;
-	} else if (err) {
+	if (!oprofile_ops.backtrace) {
+		err = -EINVAL;
 		goto out;
 	}
 
-	if (!oprofile_ops->cpu_type) {
-		printk(KERN_ERR "oprofile: cpu_type not set !\n");
-		err = -EFAULT;
-	} else {
-		err = oprofilefs_register();
+	backtrace_depth = val;
+
+out:
+	up(&start_sem);
+	return err;
+}
+
+static int __init oprofile_init(void)
+{
+	int err;
+
+	err = oprofile_arch_init(&oprofile_ops);
+
+	if (err < 0 || timer) {
+		printk(KERN_INFO "oprofile: using timer interrupt.\n");
+		oprofile_timer_init(&oprofile_ops);
 	}
- 
+
+	err = oprofilefs_register();
 	if (err)
-		goto out_exit;
-out:
+		oprofile_arch_exit();
+
 	return err;
-out_exit:
-	oprofile_arch_exit();
-	goto out;
 }
 
 
diff -Nru a/drivers/oprofile/oprof.h b/drivers/oprofile/oprof.h
--- a/drivers/oprofile/oprof.h	2005-03-01 23:38:53 -08:00
+++ b/drivers/oprofile/oprof.h	2005-03-01 23:38:53 -08:00
@@ -24,12 +24,16 @@
 extern unsigned long fs_buffer_size;
 extern unsigned long fs_cpu_buffer_size;
 extern unsigned long fs_buffer_watershed;
-extern struct oprofile_operations * oprofile_ops;
+extern struct oprofile_operations oprofile_ops;
 extern unsigned long oprofile_started;
+extern unsigned long backtrace_depth;
  
 struct super_block;
 struct dentry;
 
 void oprofile_create_files(struct super_block * sb, struct dentry * root);
+void oprofile_timer_init(struct oprofile_operations * ops);
+
+int oprofile_set_backtrace(unsigned long depth);
  
 #endif /* OPROF_H */
diff -Nru a/drivers/oprofile/oprofile_files.c b/drivers/oprofile/oprofile_files.c
--- a/drivers/oprofile/oprofile_files.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/oprofile/oprofile_files.c	2005-03-01 23:38:57 -08:00
@@ -18,6 +18,37 @@
 unsigned long fs_cpu_buffer_size = 8192;
 unsigned long fs_buffer_watershed = 32768; /* FIXME: tune */
 
+static ssize_t depth_read(struct file * file, char * buf, size_t count, loff_t * offset)
+{
+	return oprofilefs_ulong_to_user(backtrace_depth, buf, count, offset);
+}
+
+
+static ssize_t depth_write(struct file * file, char const * buf, size_t count, loff_t * offset)
+{
+	unsigned long val;
+	int retval;
+
+	if (*offset)
+		return -EINVAL;
+
+	retval = oprofilefs_ulong_from_user(&val, buf, count);
+	if (retval)
+		return retval;
+
+	retval = oprofile_set_backtrace(val);
+
+	if (retval)
+		return retval;
+	return count;
+}
+
+
+static struct file_operations depth_fops = {
+	.read		= depth_read,
+	.write		= depth_write
+};
+
  
 static ssize_t pointer_size_read(struct file * file, char __user * buf, size_t count, loff_t * offset)
 {
@@ -32,7 +63,7 @@
 
 static ssize_t cpu_type_read(struct file * file, char __user * buf, size_t count, loff_t * offset)
 {
-	return oprofilefs_str_to_user(oprofile_ops->cpu_type, buf, count, offset);
+	return oprofilefs_str_to_user(oprofile_ops.cpu_type, buf, count, offset);
 }
  
  
@@ -47,7 +78,7 @@
 }
 
 
-static ssize_t enable_write(struct file *file, char const __user * buf, size_t count, loff_t * offset)
+static ssize_t enable_write(struct file * file, char const __user * buf, size_t count, loff_t * offset)
 {
 	unsigned long val;
 	int retval;
@@ -76,7 +107,7 @@
 };
 
 
-static ssize_t dump_write(struct file *file, char const __user * buf, size_t count, loff_t * offset)
+static ssize_t dump_write(struct file * file, char const __user * buf, size_t count, loff_t * offset)
 {
 	wake_up_buffer_waiter();
 	return count;
@@ -96,8 +127,9 @@
 	oprofilefs_create_ulong(sb, root, "buffer_watershed", &fs_buffer_watershed);
 	oprofilefs_create_ulong(sb, root, "cpu_buffer_size", &fs_cpu_buffer_size);
 	oprofilefs_create_file(sb, root, "cpu_type", &cpu_type_fops); 
+	oprofilefs_create_file(sb, root, "backtrace_depth", &depth_fops);
 	oprofilefs_create_file(sb, root, "pointer_size", &pointer_size_fops);
 	oprofile_create_stats_files(sb, root);
-	if (oprofile_ops->create_files)
-		oprofile_ops->create_files(sb, root);
+	if (oprofile_ops.create_files)
+		oprofile_ops.create_files(sb, root);
 }
diff -Nru a/drivers/oprofile/oprofile_stats.c b/drivers/oprofile/oprofile_stats.c
--- a/drivers/oprofile/oprofile_stats.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/oprofile/oprofile_stats.c	2005-03-01 23:39:07 -08:00
@@ -59,6 +59,8 @@
 			&cpu_buf->sample_received);
 		oprofilefs_create_ro_ulong(sb, cpudir, "sample_lost_overflow",
 			&cpu_buf->sample_lost_overflow);
+		oprofilefs_create_ro_ulong(sb, cpudir, "backtrace_aborted",
+			&cpu_buf->backtrace_aborted);
 	}
  
 	oprofilefs_create_ro_atomic(sb, dir, "sample_lost_no_mm",
@@ -67,4 +69,6 @@
 		&oprofile_stats.sample_lost_no_mapping);
 	oprofilefs_create_ro_atomic(sb, dir, "event_lost_overflow",
 		&oprofile_stats.event_lost_overflow);
+	oprofilefs_create_ro_atomic(sb, dir, "bt_lost_no_mapping",
+		&oprofile_stats.bt_lost_no_mapping);
 }
diff -Nru a/drivers/oprofile/oprofile_stats.h b/drivers/oprofile/oprofile_stats.h
--- a/drivers/oprofile/oprofile_stats.h	2005-03-01 23:39:18 -08:00
+++ b/drivers/oprofile/oprofile_stats.h	2005-03-01 23:39:18 -08:00
@@ -15,6 +15,7 @@
 struct oprofile_stat_struct {
 	atomic_t sample_lost_no_mm;
 	atomic_t sample_lost_no_mapping;
+	atomic_t bt_lost_no_mapping;
 	atomic_t event_lost_overflow;
 };
 
diff -Nru a/drivers/oprofile/oprofilefs.c b/drivers/oprofile/oprofilefs.c
--- a/drivers/oprofile/oprofilefs.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/oprofile/oprofilefs.c	2005-03-01 23:38:55 -08:00
@@ -21,7 +21,7 @@
 
 #define OPROFILEFS_MAGIC 0x6f70726f
 
-spinlock_t oprofilefs_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(oprofilefs_lock);
 
 static struct inode * oprofilefs_get_inode(struct super_block * sb, int mode)
 {
@@ -250,6 +250,7 @@
 	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
 	sb->s_magic = OPROFILEFS_MAGIC;
 	sb->s_op = &s_ops;
+	sb->s_time_gran = 1;
 
 	root_inode = oprofilefs_get_inode(sb, S_IFDIR | 0755);
 	if (!root_inode)
diff -Nru a/drivers/oprofile/timer_int.c b/drivers/oprofile/timer_int.c
--- a/drivers/oprofile/timer_int.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/oprofile/timer_int.c	2005-03-01 23:38:55 -08:00
@@ -14,13 +14,12 @@
 #include <linux/profile.h>
 #include <linux/init.h>
 #include <asm/ptrace.h>
- 
+
+#include "oprof.h"
+
 static int timer_notify(struct pt_regs *regs)
 {
-	int cpu = smp_processor_id();
-	unsigned long eip = profile_pc(regs);
- 
-	oprofile_add_sample(eip, !user_mode(regs), 0, cpu);
+ 	oprofile_add_sample(regs, 0);
 	return 0;
 }
 
@@ -36,15 +35,12 @@
 }
 
 
-static struct oprofile_operations timer_ops = {
-	.start	= timer_start,
-	.stop	= timer_stop,
-	.cpu_type = "timer"
-};
-
- 
-void __init timer_init(struct oprofile_operations ** ops)
+void __init oprofile_timer_init(struct oprofile_operations * ops)
 {
-	*ops = &timer_ops;
-	printk(KERN_INFO "oprofile: using timer interrupt.\n");
+	ops->create_files = NULL;
+	ops->setup = NULL;
+	ops->shutdown = NULL;
+	ops->start = timer_start;
+	ops->stop = timer_stop;
+	ops->cpu_type = "timer";
 }
diff -Nru a/drivers/parisc/Makefile b/drivers/parisc/Makefile
--- a/drivers/parisc/Makefile	2005-03-01 23:38:53 -08:00
+++ b/drivers/parisc/Makefile	2005-03-01 23:38:53 -08:00
@@ -2,11 +2,6 @@
 # Makefile for most of the non-PCI devices in PA-RISC machines
 #
 
-obj-y :=
-obj-m :=
-obj-n :=
-obj-  :=
-
 # I/O SAPIC is also on IA64 platforms.
 # The two could be merged into a common source some day.
 obj-$(CONFIG_IOSAPIC)		+= iosapic.o
@@ -17,7 +12,7 @@
 # obj-$(CONFIG_IOMMU_CCIO)	+= ccio-rm-dma.o
 obj-$(CONFIG_IOMMU_CCIO)	+= ccio-dma.o
 
-obj-y				+= gsc.o
+obj-$(CONFIG_GSC)		+= gsc.o
 
 obj-$(CONFIG_HPPB)		+= hppb.o
 obj-$(CONFIG_GSC_DINO)		+= dino.o
diff -Nru a/drivers/parisc/asp.c b/drivers/parisc/asp.c
--- a/drivers/parisc/asp.c	2005-03-01 23:39:19 -08:00
+++ b/drivers/parisc/asp.c	2005-03-01 23:39:19 -08:00
@@ -13,7 +13,7 @@
 
 #include <linux/errno.h>
 #include <linux/init.h>
-#include <linux/irq.h>
+#include <linux/interrupt.h>
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/types.h>
@@ -30,25 +30,27 @@
 
 #define VIPER_INT_WORD  0xFFFBF088      /* addr of viper interrupt word */
 
-static int asp_choose_irq(struct parisc_device *dev)
+static void asp_choose_irq(struct parisc_device *dev, void *ctrl)
 {
-	int irq = -1;
+	int irq;
 
 	switch (dev->id.sversion) {
-	case 0x71:	irq = 22; break; /* SCSI */
-	case 0x72:	irq = 23; break; /* LAN */
-	case 0x73:	irq = 30; break; /* HIL */
-	case 0x74:	irq = 24; break; /* Centronics */
-	case 0x75:	irq = (dev->hw_path == 4) ? 26 : 25; break; /* RS232 */
-	case 0x76:	irq = 21; break; /* EISA BA */
-	case 0x77:	irq = 20; break; /* Graphics1 */
-	case 0x7a:	irq = 18; break; /* Audio (Bushmaster) */
-	case 0x7b:	irq = 18; break; /* Audio (Scorpio) */
-	case 0x7c:	irq = 28; break; /* FW SCSI */
-	case 0x7d:	irq = 27; break; /* FDDI */
-	case 0x7f:	irq = 18; break; /* Audio (Outfield) */
+	case 0x71:	irq =  9; break; /* SCSI */
+	case 0x72:	irq =  8; break; /* LAN */
+	case 0x73:	irq =  1; break; /* HIL */
+	case 0x74:	irq =  7; break; /* Centronics */
+	case 0x75:	irq = (dev->hw_path == 4) ? 5 : 6; break; /* RS232 */
+	case 0x76:	irq = 10; break; /* EISA BA */
+	case 0x77:	irq = 11; break; /* Graphics1 */
+	case 0x7a:	irq = 13; break; /* Audio (Bushmaster) */
+	case 0x7b:	irq = 13; break; /* Audio (Scorpio) */
+	case 0x7c:	irq =  3; break; /* FW SCSI */
+	case 0x7d:	irq =  4; break; /* FDDI */
+	case 0x7f:	irq = 13; break; /* Audio (Outfield) */
+	default:	return;		 /* Unknown */
 	}
-	return irq;
+
+	gsc_asic_assign_irq(ctrl, irq, &dev->irq);
 }
 
 /* There are two register ranges we're interested in.  Interrupt /
@@ -62,11 +64,11 @@
 int __init
 asp_init_chip(struct parisc_device *dev)
 {
-	struct busdevice *asp;
+	struct gsc_asic *asp;
 	struct gsc_irq gsc_irq;
-	int irq, ret;
+	int ret;
 
-	asp = kmalloc(sizeof(struct busdevice), GFP_KERNEL);
+	asp = kmalloc(sizeof(*asp), GFP_KERNEL);
 	if(!asp)
 		return -ENOMEM;
 
@@ -79,37 +81,34 @@
 
 	/* the IRQ ASP should use */
 	ret = -EBUSY;
-	irq = gsc_claim_irq(&gsc_irq, ASP_GSC_IRQ);
-	if (irq < 0) {
+	dev->irq = gsc_claim_irq(&gsc_irq, ASP_GSC_IRQ);
+	if (dev->irq < 0) {
 		printk(KERN_ERR "%s(): cannot get GSC irq\n", __FUNCTION__);
 		goto out;
 	}
 
-	ret = request_irq(gsc_irq.irq, busdev_barked, 0, "asp", asp);
+	asp->eim = ((u32) gsc_irq.txn_addr) | gsc_irq.txn_data;
+
+	ret = request_irq(gsc_irq.irq, gsc_asic_intr, 0, "asp", asp);
 	if (ret < 0)
 		goto out;
 
-	/* Save this for debugging later */
-	asp->parent_irq = gsc_irq.irq;
-	asp->eim = ((u32) gsc_irq.txn_addr) | gsc_irq.txn_data;
-
 	/* Program VIPER to interrupt on the ASP irq */
 	gsc_writel((1 << (31 - ASP_GSC_IRQ)),VIPER_INT_WORD);
 
 	/* Done init'ing, register this driver */
-	ret = gsc_common_irqsetup(dev, asp);
+	ret = gsc_common_setup(dev, asp);
 	if (ret)
 		goto out;
 
-	fixup_child_irqs(dev, asp->busdev_region->data.irqbase, asp_choose_irq);
+	gsc_fixup_irqs(dev, asp, asp_choose_irq);
 	/* Mongoose is a sibling of Asp, not a child... */
-	fixup_child_irqs(dev->parent, asp->busdev_region->data.irqbase,
-			asp_choose_irq);
+	gsc_fixup_irqs(parisc_parent(dev), asp, asp_choose_irq);
 
 	/* initialize the chassis LEDs */ 
 #ifdef CONFIG_CHASSIS_LCD_LED	
 	register_led_driver(DISPLAY_MODEL_OLD_ASP, LED_CMD_REG_NONE, 
-		    (char *)ASP_LED_ADDR);
+		    ASP_LED_ADDR);
 #endif
 
 	return 0;
diff -Nru a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c
--- a/drivers/parisc/ccio-dma.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/parisc/ccio-dma.c	2005-03-01 23:38:53 -08:00
@@ -1198,9 +1198,10 @@
  * to/from certain pages.  To avoid this happening, we mark these pages
  * as `used', and ensure that nothing will try to allocate from them.
  */
-void ccio_cujo20_fixup(struct parisc_device *dev, u32 iovp)
+void ccio_cujo20_fixup(struct parisc_device *cujo, u32 iovp)
 {
 	unsigned int idx;
+	struct parisc_device *dev = parisc_parent(cujo);
 	struct ioc *ioc = ccio_get_iommu(dev);
 	u8 *res_ptr;
 
@@ -1556,9 +1557,12 @@
 		create_proc_read_entry(MODULE_NAME"-bitmap", S_IRWXU,
 				       proc_runway_root, ccio_resource_map, NULL);
 	}
+
+	ioc_count++;
+
 	parisc_vmerge_boundary = IOVP_SIZE;
 	parisc_vmerge_max_size = BITS_PER_LONG * IOVP_SIZE;
-	ioc_count++;
+	parisc_has_iommu();
 	return 0;
 }
 
diff -Nru a/drivers/parisc/dino.c b/drivers/parisc/dino.c
--- a/drivers/parisc/dino.c	2005-03-01 23:38:51 -08:00
+++ b/drivers/parisc/dino.c	2005-03-01 23:38:51 -08:00
@@ -57,7 +57,6 @@
 #include <asm/page.h>
 #include <asm/system.h>
 #include <asm/io.h>
-#include <asm/irq.h>
 #include <asm/hardware.h>
 
 #include "gsc.h"
@@ -146,12 +145,10 @@
 	spinlock_t		dinosaur_pen;
 	unsigned long		txn_addr; /* EIR addr to generate interrupt */ 
 	u32			txn_data; /* EIR data assign to each dino */ 
-	int			irq;      /* Virtual IRQ dino uses */
-	struct irq_region	*dino_region;  /* region for this Dino */
-
-	u32 			imr; /* IRQ's which are enabled */ 
+	u32 			imr;	  /* IRQ's which are enabled */ 
+	int			global_irq[12]; /* map IMR bit to global irq */
 #ifdef DINO_DEBUG
-	unsigned int		dino_irr0; /* save most recent IRQ line stat */ 
+	unsigned int		dino_irr0; /* save most recent IRQ line stat */
 #endif
 };
 
@@ -178,22 +175,21 @@
 	struct dino_device *d = DINO_DEV(parisc_walk_tree(bus->bridge));
 	u32 local_bus = (bus->parent == NULL) ? 0 : bus->secondary;
 	u32 v = DINO_CFG_TOK(local_bus, devfn, where & ~3);
-	unsigned long base_addr = d->hba.base_addr;
+	void __iomem *base_addr = d->hba.base_addr;
 	unsigned long flags;
 
 	spin_lock_irqsave(&d->dinosaur_pen, flags);
 
 	/* tell HW which CFG address */
-	gsc_writel(v, base_addr + DINO_PCI_ADDR);
+	__raw_writel(v, base_addr + DINO_PCI_ADDR);
 
 	/* generate cfg read cycle */
 	if (size == 1) {
-		*val = gsc_readb(base_addr + DINO_CONFIG_DATA + (where & 3));
+		*val = readb(base_addr + DINO_CONFIG_DATA + (where & 3));
 	} else if (size == 2) {
-		*val = le16_to_cpu(gsc_readw(base_addr +
-					DINO_CONFIG_DATA + (where & 2)));
+		*val = readw(base_addr + DINO_CONFIG_DATA + (where & 2));
 	} else if (size == 4) {
-		*val = le32_to_cpu(gsc_readl(base_addr + DINO_CONFIG_DATA));
+		*val = readl(base_addr + DINO_CONFIG_DATA);
 	}
 
 	spin_unlock_irqrestore(&d->dinosaur_pen, flags);
@@ -212,25 +208,24 @@
 	struct dino_device *d = DINO_DEV(parisc_walk_tree(bus->bridge));
 	u32 local_bus = (bus->parent == NULL) ? 0 : bus->secondary;
 	u32 v = DINO_CFG_TOK(local_bus, devfn, where & ~3);
-	unsigned long base_addr = d->hba.base_addr;
+	void __iomem *base_addr = d->hba.base_addr;
 	unsigned long flags;
 
 	spin_lock_irqsave(&d->dinosaur_pen, flags);
 
 	/* avoid address stepping feature */
-	gsc_writel(v & 0xffffff00, base_addr + DINO_PCI_ADDR);
-	gsc_readl(base_addr + DINO_CONFIG_DATA);
+	__raw_writel(v & 0xffffff00, base_addr + DINO_PCI_ADDR);
+	__raw_readl(base_addr + DINO_CONFIG_DATA);
 
 	/* tell HW which CFG address */
-	gsc_writel(v, base_addr + DINO_PCI_ADDR);
+	__raw_writel(v, base_addr + DINO_PCI_ADDR);
 	/* generate cfg read cycle */
 	if (size == 1) {
-		gsc_writeb(val, base_addr + DINO_CONFIG_DATA + (where & 3));
+		writeb(val, base_addr + DINO_CONFIG_DATA + (where & 3));
 	} else if (size == 2) {
-		gsc_writew(cpu_to_le16(val),
-				base_addr + DINO_CONFIG_DATA + (where & 2));
+		writew(val, base_addr + DINO_CONFIG_DATA + (where & 2));
 	} else if (size == 4) {
-		gsc_writel(cpu_to_le32(val), base_addr + DINO_CONFIG_DATA);
+		writel(val, base_addr + DINO_CONFIG_DATA);
 	}
 
 	spin_unlock_irqrestore(&d->dinosaur_pen, flags);
@@ -252,9 +247,6 @@
  * I/O port instead of MMIO.
  */
 
-#define cpu_to_le8(x) (x)
-#define le8_to_cpu(x) (x)
-
 #define DINO_PORT_IN(type, size, mask) \
 static u##size dino_in##size (struct pci_hba_data *d, u16 addr) \
 { \
@@ -262,11 +254,11 @@
 	unsigned long flags; \
 	spin_lock_irqsave(&(DINO_DEV(d)->dinosaur_pen), flags); \
 	/* tell HW which IO Port address */ \
-	gsc_writel((u32) addr, d->base_addr + DINO_PCI_ADDR); \
+	__raw_writel((u32) addr, d->base_addr + DINO_PCI_ADDR); \
 	/* generate I/O PORT read cycle */ \
-	v = gsc_read##type(d->base_addr+DINO_IO_DATA+(addr&mask)); \
+	v = read##type(d->base_addr+DINO_IO_DATA+(addr&mask)); \
 	spin_unlock_irqrestore(&(DINO_DEV(d)->dinosaur_pen), flags); \
-	return le##size##_to_cpu(v); \
+	return v; \
 }
 
 DINO_PORT_IN(b,  8, 3)
@@ -279,9 +271,9 @@
 	unsigned long flags; \
 	spin_lock_irqsave(&(DINO_DEV(d)->dinosaur_pen), flags); \
 	/* tell HW which IO port address */ \
-	gsc_writel((u32) addr, d->base_addr + DINO_PCI_ADDR); \
+	__raw_writel((u32) addr, d->base_addr + DINO_PCI_ADDR); \
 	/* generate cfg write cycle */ \
-	gsc_write##type(cpu_to_le##size(val), d->base_addr+DINO_IO_DATA+(addr&mask)); \
+	write##type(val, d->base_addr+DINO_IO_DATA+(addr&mask)); \
 	spin_unlock_irqrestore(&(DINO_DEV(d)->dinosaur_pen), flags); \
 }
 
@@ -298,45 +290,37 @@
 	.outl	= dino_out32
 };
 
-static void
-dino_mask_irq(void *irq_dev, int irq)
+static void dino_disable_irq(unsigned int irq)
 {
-	struct dino_device *dino_dev = DINO_DEV(irq_dev);
+	struct dino_device *dino_dev = irq_desc[irq].handler_data;
+	int local_irq = gsc_find_local_irq(irq, dino_dev->global_irq, irq);
 
 	DBG(KERN_WARNING "%s(0x%p, %d)\n", __FUNCTION__, irq_dev, irq);
 
-	if (NULL == irq_dev || irq > DINO_IRQS || irq < 0) {
-		printk(KERN_WARNING "%s(0x%lx, %d) - not a dino irq?\n",
-			__FUNCTION__, (long) irq_dev, irq);
-		BUG();
-	} else {
-		/*
-		** Clear the matching bit in the IMR register
-		*/
-		dino_dev->imr &= ~(DINO_MASK_IRQ(irq));
-		gsc_writel(dino_dev->imr, dino_dev->hba.base_addr+DINO_IMR);
-	}
+	/* Clear the matching bit in the IMR register */
+	dino_dev->imr &= ~(DINO_MASK_IRQ(local_irq));
+	__raw_writel(dino_dev->imr, dino_dev->hba.base_addr+DINO_IMR);
 }
 
-
-static void
-dino_unmask_irq(void *irq_dev, int irq)
+static void dino_enable_irq(unsigned int irq)
 {
-	struct dino_device *dino_dev = DINO_DEV(irq_dev);
+	struct dino_device *dino_dev = irq_desc[irq].handler_data;
+	int local_irq = gsc_find_local_irq(irq, dino_dev->global_irq, irq);
 	u32 tmp;
 
 	DBG(KERN_WARNING "%s(0x%p, %d)\n", __FUNCTION__, irq_dev, irq);
 
-	if (NULL == irq_dev || irq > DINO_IRQS) {
-		printk(KERN_WARNING "%s(): %d not a dino irq?\n",
-				__FUNCTION__, irq);
-		BUG();
-		return;
-	}
+	/*
+	** clear pending IRQ bits
+	**
+	** This does NOT change ILR state!
+	** See comment below for ILR usage.
+	*/
+	__raw_readl(dino_dev->hba.base_addr+DINO_IPR);
 
 	/* set the matching bit in the IMR register */
-	dino_dev->imr |= DINO_MASK_IRQ(irq);          /* used in dino_isr() */
-	gsc_writel( dino_dev->imr, dino_dev->hba.base_addr+DINO_IMR);
+	dino_dev->imr |= DINO_MASK_IRQ(local_irq);	/* used in dino_isr() */
+	__raw_writel( dino_dev->imr, dino_dev->hba.base_addr+DINO_IMR);
 
 	/* Emulate "Level Triggered" Interrupt
 	** Basically, a driver is blowing it if the IRQ line is asserted
@@ -347,38 +331,28 @@
 	** dino_isr() will read IPR and find nothing. But then catch this
 	** when it also checks ILR.
 	*/
-	tmp = gsc_readl(dino_dev->hba.base_addr+DINO_ILR);
-	if (tmp & DINO_MASK_IRQ(irq)) {
+	tmp = __raw_readl(dino_dev->hba.base_addr+DINO_ILR);
+	if (tmp & DINO_MASK_IRQ(local_irq)) {
 		DBG(KERN_WARNING "%s(): IRQ asserted! (ILR 0x%x)\n",
 				__FUNCTION__, tmp);
 		gsc_writel(dino_dev->txn_data, dino_dev->txn_addr);
 	}
 }
 
-
-
-static void
-dino_enable_irq(void *irq_dev, int irq)
+static unsigned int dino_startup_irq(unsigned int irq)
 {
-	struct dino_device *dino_dev = DINO_DEV(irq_dev);
-
-	/*
-	** clear pending IRQ bits
-	**
-	** This does NOT change ILR state!
-	** See comments in dino_unmask_irq() for ILR usage.
-	*/
-	gsc_readl(dino_dev->hba.base_addr+DINO_IPR);
-
-	dino_unmask_irq(irq_dev, irq);
+	dino_enable_irq(irq);
+	return 0;
 }
 
-
-static struct irq_region_ops dino_irq_ops = {
-	.disable_irq	= dino_mask_irq,	/* ??? */
-	.enable_irq	= dino_enable_irq, 
-	.mask_irq	= dino_mask_irq,
-	.unmask_irq	= dino_unmask_irq
+static struct hw_interrupt_type dino_interrupt_type = {
+	.typename	= "GSC-PCI",
+	.startup	= dino_startup_irq,
+	.shutdown	= dino_disable_irq,
+	.enable		= dino_enable_irq, 
+	.disable	= dino_disable_irq,
+	.ack		= no_ack_irq,
+	.end		= no_end_irq,
 };
 
 
@@ -391,34 +365,28 @@
 static irqreturn_t
 dino_isr(int irq, void *intr_dev, struct pt_regs *regs)
 {
-	struct dino_device *dino_dev = DINO_DEV(intr_dev);
+	struct dino_device *dino_dev = intr_dev;
 	u32 mask;
 	int ilr_loop = 100;
-	extern void do_irq(struct irqaction *a, int i, struct pt_regs *p);
-
 
 	/* read and acknowledge pending interrupts */
 #ifdef DINO_DEBUG
 	dino_dev->dino_irr0 =
 #endif
-	mask = gsc_readl(dino_dev->hba.base_addr+DINO_IRR0) & DINO_IRR_MASK;
-
-ilr_again:
-	while (mask)
-	{
-		int irq;
-
-		irq = __ffs(mask);
+	mask = __raw_readl(dino_dev->hba.base_addr+DINO_IRR0) & DINO_IRR_MASK;
 
-		mask &= ~(1<<irq);
+	if (mask == 0)
+		return IRQ_NONE;
 
-		DBG(KERN_WARNING "%s(%x, %p) mask %0x\n",
+ilr_again:
+	do {
+		int local_irq = __ffs(mask);
+		int irq = dino_dev->global_irq[local_irq];
+		DBG(KERN_DEBUG "%s(%d, %p) mask 0x%x\n",
 			__FUNCTION__, irq, intr_dev, mask);
-		do_irq(&dino_dev->dino_region->action[irq],
-			dino_dev->dino_region->data.irqbase + irq,
-			regs);
-
-	}
+		__do_IRQ(irq, regs);
+		mask &= ~(1 << local_irq);
+	} while (mask);
 
 	/* Support for level triggered IRQ lines.
 	** 
@@ -427,27 +395,40 @@
 	** device drivers may assume lines are level triggered (and not
 	** edge triggered like EISA/ISA can be).
 	*/
-	mask = gsc_readl(dino_dev->hba.base_addr+DINO_ILR) & dino_dev->imr;
+	mask = __raw_readl(dino_dev->hba.base_addr+DINO_ILR) & dino_dev->imr;
 	if (mask) {
 		if (--ilr_loop > 0)
 			goto ilr_again;
-		printk(KERN_ERR "Dino %lx: stuck interrupt %d\n", dino_dev->hba.base_addr, mask);
+		printk(KERN_ERR "Dino 0x%p: stuck interrupt %d\n", 
+		       dino_dev->hba.base_addr, mask);
 		return IRQ_NONE;
 	}
 	return IRQ_HANDLED;
 }
 
-static int dino_choose_irq(struct parisc_device *dev)
+static void dino_assign_irq(struct dino_device *dino, int local_irq, int *irqp)
 {
-	int irq = -1;
+	int irq = gsc_assign_irq(&dino_interrupt_type, dino);
+	if (irq == NO_IRQ)
+		return;
+
+	*irqp = irq;
+	dino->global_irq[local_irq] = irq;
+}
+
+static void dino_choose_irq(struct parisc_device *dev, void *ctrl)
+{
+	int irq;
+	struct dino_device *dino = ctrl;
 
 	switch (dev->id.sversion) {
 		case 0x00084:	irq =  8; break; /* PS/2 */
 		case 0x0008c:	irq = 10; break; /* RS232 */
 		case 0x00096:	irq =  8; break; /* PS/2 */
+		default:	return;		 /* Unknown */
 	}
 
-	return irq;
+	dino_assign_irq(dino, irq, &dev->irq);
 }
 
 static void __init
@@ -465,7 +446,7 @@
  */
 #define _8MB 0x00800000UL
 static void __init
-dino_card_setup(struct pci_bus *bus, unsigned long base_addr)
+dino_card_setup(struct pci_bus *bus, void __iomem *base_addr)
 {
 	int i;
 	struct dino_device *dino_dev = DINO_DEV(parisc_walk_tree(bus->bridge));
@@ -475,7 +456,8 @@
 
 	res = &dino_dev->hba.lmmio_space;
 	res->flags = IORESOURCE_MEM;
-	size = scnprintf(name, sizeof(name), "Dino LMMIO (%s)", bus->bridge->bus_id);
+	size = scnprintf(name, sizeof(name), "Dino LMMIO (%s)", 
+			 bus->bridge->bus_id);
 	res->name = kmalloc(size+1, GFP_KERNEL);
 	if(res->name)
 		strcpy((char *)res->name, name);
@@ -510,7 +492,7 @@
 	}
 	DBG("DINO GSC WRITE i=%d, start=%lx, dino addr = %lx\n",
 	    i, res->start, base_addr + DINO_IO_ADDR_EN);
-	gsc_writel(1 << i, base_addr + DINO_IO_ADDR_EN);
+	__raw_writel(1 << i, base_addr + DINO_IO_ADDR_EN);
 }
 
 static void __init
@@ -531,7 +513,8 @@
 	** Set Latency Timer to 0xff (not a shared bus)
 	** Set CACHELINE_SIZE.
 	*/
-	dino_cfg_write(dev->bus, dev->devfn, PCI_CACHE_LINE_SIZE, 2, 0xff00 | L1_CACHE_BYTES/4); 
+	dino_cfg_write(dev->bus, dev->devfn, 
+		       PCI_CACHE_LINE_SIZE, 2, 0xff00 | L1_CACHE_BYTES/4); 
 
 	/*
 	** Program INT_LINE for card-mode devices.
@@ -563,8 +546,9 @@
         struct dino_device *dino_dev = DINO_DEV(parisc_walk_tree(bus->bridge));
 	int port_base = HBA_PORT_BASE(dino_dev->hba.hba_num);
 
-	DBG(KERN_WARNING "%s(0x%p) bus %d sysdata 0x%p\n",
-			__FUNCTION__, bus, bus->secondary, bus->bridge->platform_data);
+	DBG(KERN_WARNING "%s(0x%p) bus %d platform_data 0x%p\n",
+	    __FUNCTION__, bus, bus->secondary, 
+	    bus->bridge->platform_data);
 
 	/* Firmware doesn't set up card-mode dino, so we have to */
 	if (is_card_dino(&dino_dev->hba.dev->id)) {
@@ -589,7 +573,8 @@
 
 
 		for(i = PCI_BRIDGE_RESOURCES; i < PCI_NUM_RESOURCES; i++) {
-			if((bus->self->resource[i].flags & (IORESOURCE_IO | IORESOURCE_MEM)) == 0)
+			if((bus->self->resource[i].flags & 
+			    (IORESOURCE_IO | IORESOURCE_MEM)) == 0)
 				continue;
 			
 			if(bus->self->resource[i].flags & IORESOURCE_MEM) {
@@ -664,11 +649,15 @@
 
 			u32 irq_pin;
 			
-			dino_cfg_read(dev->bus, dev->devfn, PCI_INTERRUPT_PIN, 1, &irq_pin);
-			dev->irq = (irq_pin + PCI_SLOT(dev->devfn) - 1) % 4 ;
-			dino_cfg_write(dev->bus, dev->devfn, PCI_INTERRUPT_LINE, 1, dev->irq);
-			dev->irq += dino_dev->dino_region->data.irqbase;
-			printk(KERN_WARNING "Device %s has undefined IRQ, setting to %d\n", dev->slot_name, irq_pin);
+			dino_cfg_read(dev->bus, dev->devfn, 
+				      PCI_INTERRUPT_PIN, 1, &irq_pin);
+			irq_pin = (irq_pin + PCI_SLOT(dev->devfn) - 1) % 4 ;
+			printk(KERN_WARNING "Device %s has undefined IRQ, "
+					"setting to %d\n", dev->slot_name,
+					irq_pin);
+			dino_cfg_write(dev->bus, dev->devfn, 
+				       PCI_INTERRUPT_LINE, 1, irq_pin);
+			dino_assign_irq(dino_dev, irq_pin, &dev->irq);
 #else
 			dev->irq = 65535;
 			printk(KERN_WARNING "Device %s has unassigned IRQ\n", dev->slot_name);	
@@ -676,7 +665,7 @@
 		} else {
 
 			/* Adjust INT_LINE for that busses region */
-			dev->irq += dino_dev->dino_region->data.irqbase;
+			dino_assign_irq(dino_dev, dev->irq, &dev->irq);
 		}
 	}
 }
@@ -696,9 +685,9 @@
 {
 	u32 brdg_feat = 0x00784e05;
 
-	gsc_writel(0x00000000, dino_dev->hba.base_addr+DINO_GMASK);
-	gsc_writel(0x00000001, dino_dev->hba.base_addr+DINO_IO_FBB_EN);
-	gsc_writel(0x00000000, dino_dev->hba.base_addr+DINO_ICR);
+	__raw_writel(0x00000000, dino_dev->hba.base_addr+DINO_GMASK);
+	__raw_writel(0x00000001, dino_dev->hba.base_addr+DINO_IO_FBB_EN);
+	__raw_writel(0x00000000, dino_dev->hba.base_addr+DINO_ICR);
 
 #if 1
 /* REVISIT - should be a runtime check (eg if (CPU_IS_PCX_L) ...) */
@@ -708,34 +697,34 @@
 	*/
 	brdg_feat &= ~0x4;	/* UXQL */
 #endif
-	gsc_writel( brdg_feat, dino_dev->hba.base_addr+DINO_BRDG_FEAT);
+	__raw_writel( brdg_feat, dino_dev->hba.base_addr+DINO_BRDG_FEAT);
 
 	/*
 	** Don't enable address decoding until we know which I/O range
 	** currently is available from the host. Only affects MMIO
 	** and not I/O port space.
 	*/
-	gsc_writel(0x00000000, dino_dev->hba.base_addr+DINO_IO_ADDR_EN);
+	__raw_writel(0x00000000, dino_dev->hba.base_addr+DINO_IO_ADDR_EN);
 
-	gsc_writel(0x00000000, dino_dev->hba.base_addr+DINO_DAMODE);
-	gsc_writel(0x00222222, dino_dev->hba.base_addr+DINO_PCIROR);
-	gsc_writel(0x00222222, dino_dev->hba.base_addr+DINO_PCIWOR);
-
-	gsc_writel(0x00000040, dino_dev->hba.base_addr+DINO_MLTIM);
-	gsc_writel(0x00000080, dino_dev->hba.base_addr+DINO_IO_CONTROL);
-	gsc_writel(0x0000008c, dino_dev->hba.base_addr+DINO_TLTIM);
+	__raw_writel(0x00000000, dino_dev->hba.base_addr+DINO_DAMODE);
+	__raw_writel(0x00222222, dino_dev->hba.base_addr+DINO_PCIROR);
+	__raw_writel(0x00222222, dino_dev->hba.base_addr+DINO_PCIWOR);
+
+	__raw_writel(0x00000040, dino_dev->hba.base_addr+DINO_MLTIM);
+	__raw_writel(0x00000080, dino_dev->hba.base_addr+DINO_IO_CONTROL);
+	__raw_writel(0x0000008c, dino_dev->hba.base_addr+DINO_TLTIM);
 
 	/* Disable PAMR before writing PAPR */
-	gsc_writel(0x0000007e, dino_dev->hba.base_addr+DINO_PAMR);
-	gsc_writel(0x0000007f, dino_dev->hba.base_addr+DINO_PAPR);
-	gsc_writel(0x00000000, dino_dev->hba.base_addr+DINO_PAMR);
+	__raw_writel(0x0000007e, dino_dev->hba.base_addr+DINO_PAMR);
+	__raw_writel(0x0000007f, dino_dev->hba.base_addr+DINO_PAPR);
+	__raw_writel(0x00000000, dino_dev->hba.base_addr+DINO_PAMR);
 
 	/*
 	** Dino ERS encourages enabling FBB (0x6f).
 	** We can't until we know *all* devices below us can support it.
 	** (Something in device configuration header tells us).
 	*/
-	gsc_writel(0x0000004f, dino_dev->hba.base_addr+DINO_PCICMD);
+	__raw_writel(0x0000004f, dino_dev->hba.base_addr+DINO_PCICMD);
 
 	/* Somewhere, the PCI spec says give devices 1 second
 	** to recover from the #RESET being de-asserted.
@@ -756,7 +745,7 @@
 	 * since PDC has already initialized this.
 	 */
 
-	io_addr = gsc_readl(dino_dev->hba.base_addr + DINO_IO_ADDR_EN);
+	io_addr = __raw_readl(dino_dev->hba.base_addr + DINO_IO_ADDR_EN);
 	if (io_addr == 0) {
 		printk(KERN_WARNING "%s: No PCI devices enabled.\n", name);
 		return -ENODEV;
@@ -830,7 +819,7 @@
 	**   still only has 11 IRQ input lines - just map some of them
 	**   to a different processor.
 	*/
-	dino_dev->irq = gsc_alloc_irq(&gsc_irq);
+	dev->irq = gsc_alloc_irq(&gsc_irq);
 	dino_dev->txn_addr = gsc_irq.txn_addr;
 	dino_dev->txn_data = gsc_irq.txn_data;
 	eim = ((u32) gsc_irq.txn_addr) | gsc_irq.txn_data;
@@ -839,49 +828,36 @@
 	** Dino needs a PA "IRQ" to get a processor's attention.
 	** arch/parisc/kernel/irq.c returns an EIRR bit.
 	*/
-	if (dino_dev->irq < 0) {
+	if (dev->irq < 0) {
 		printk(KERN_WARNING "%s: gsc_alloc_irq() failed\n", name);
 		return 1;
 	}
 
-	status = request_irq(dino_dev->irq, dino_isr, 0, name, dino_dev);
+	status = request_irq(dev->irq, dino_isr, 0, name, dino_dev);
 	if (status) {
 		printk(KERN_WARNING "%s: request_irq() failed with %d\n", 
 			name, status);
 		return 1;
 	}
 
-	/*
-	** Tell generic interrupt support we have 11 bits which need
-	** be checked in the interrupt handler.
-	*/
-	dino_dev->dino_region = alloc_irq_region(DINO_IRQS, &dino_irq_ops,
-						name, dino_dev);
-
-	if (NULL == dino_dev->dino_region) {
-		printk(KERN_WARNING "%s: alloc_irq_region() failed\n", name);
-		return 1;
-	}
-
 	/* Support the serial port which is sometimes attached on built-in
 	 * Dino / Cujo chips.
 	 */
 
-	fixup_child_irqs(dev, dino_dev->dino_region->data.irqbase,
-			dino_choose_irq);
+	gsc_fixup_irqs(dev, dino_dev, dino_choose_irq);
 
 	/*
 	** This enables DINO to generate interrupts when it sees
 	** any of its inputs *change*. Just asserting an IRQ
 	** before it's enabled (ie unmasked) isn't good enough.
 	*/
-	gsc_writel(eim, dino_dev->hba.base_addr+DINO_IAR0);
+	__raw_writel(eim, dino_dev->hba.base_addr+DINO_IAR0);
 
 	/*
 	** Some platforms don't clear Dino's IRR0 register at boot time.
 	** Reading will clear it now.
 	*/
-	gsc_readl(dino_dev->hba.base_addr+DINO_IRR0);
+	__raw_readl(dino_dev->hba.base_addr+DINO_IRR0);
 
 	/* allocate I/O Port resource region */
 	res = &dino_dev->hba.io_space;
@@ -894,8 +870,9 @@
 	res->end = res->start + (HBA_PORT_SPACE_SIZE - 1);
 	res->flags = IORESOURCE_IO; /* do not mark it busy ! */
 	if (request_resource(&ioport_resource, res) < 0) {
-		printk(KERN_ERR "%s: request I/O Port region failed 0x%lx/%lx (hpa 0x%lx)\n",
-				name, res->start, res->end, dino_dev->hba.base_addr);
+		printk(KERN_ERR "%s: request I/O Port region failed "
+		       "0x%lx/%lx (hpa 0x%p)\n",
+		       name, res->start, res->end, dino_dev->hba.base_addr);
 		return 1;
 	}
 
@@ -931,20 +908,11 @@
 {
 	struct dino_device *dino_dev;	// Dino specific control struct
 	const char *version = "unknown";
-	const int name_len = 32;
-	char hw_path[64];
 	char *name;
 	int is_cujo = 0;
 	struct pci_bus *bus;
 	
-	name = kmalloc(name_len, GFP_KERNEL);
-	if(name) {
-		print_pa_hwpath(dev, hw_path);
-		snprintf(name, name_len, "Dino [%s]", hw_path);
-	} 
-	else
-		name = "Dino";
-
+	name = "Dino";
 	if (is_card_dino(&dev->id)) {
 		version = "3.x (card mode)";
 	} else {
@@ -974,9 +942,9 @@
 #ifdef CONFIG_IOMMU_CCIO
 		printk(KERN_WARNING "Enabling Cujo 2.0 bug workaround\n");
 		if (dev->hpa == (unsigned long)CUJO_RAVEN_ADDR) {
-			ccio_cujo20_fixup(dev->parent, CUJO_RAVEN_BADPAGE);
+			ccio_cujo20_fixup(dev, CUJO_RAVEN_BADPAGE);
 		} else if (dev->hpa == (unsigned long)CUJO_FIREHAWK_ADDR) {
-			ccio_cujo20_fixup(dev->parent, CUJO_FIREHAWK_BADPAGE);
+			ccio_cujo20_fixup(dev, CUJO_FIREHAWK_BADPAGE);
 		} else {
 			printk("Don't recognise Cujo at address 0x%lx, not enabling workaround\n", dev->hpa);
 		}
@@ -1003,9 +971,9 @@
 	memset(dino_dev, 0, sizeof(struct dino_device));
 
 	dino_dev->hba.dev = dev;
-	dino_dev->hba.base_addr = dev->hpa;  /* faster access */
+	dino_dev->hba.base_addr = ioremap(dev->hpa, 4096); /* faster access */
 	dino_dev->hba.lmmio_space_offset = 0;	/* CPU addrs == bus addrs */
-	dino_dev->dinosaur_pen = SPIN_LOCK_UNLOCKED;
+	spin_lock_init(&dino_dev->dinosaur_pen);
 	dino_dev->hba.iommu = ccio_get_iommu(dev);
 
 	if (is_card_dino(&dev->id)) {
diff -Nru a/drivers/parisc/eisa.c b/drivers/parisc/eisa.c
--- a/drivers/parisc/eisa.c	2005-03-01 23:38:44 -08:00
+++ b/drivers/parisc/eisa.c	2005-03-01 23:38:44 -08:00
@@ -29,7 +29,7 @@
 
 #include <linux/init.h>
 #include <linux/ioport.h>
-#include <linux/irq.h>
+#include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/pci.h>
@@ -54,7 +54,7 @@
 #define SNAKES_EEPROM_BASE_ADDR 0xF0810400
 #define MIRAGE_EEPROM_BASE_ADDR 0xF00C0400
 
-static spinlock_t eisa_irq_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(eisa_irq_lock);
 
 /* We can only have one EISA adapter in the system because neither
  * implementation can be flexed.
@@ -142,7 +142,7 @@
 
 
 /* called by free irq */
-static void eisa_disable_irq(void *irq_dev, int irq)
+static void eisa_disable_irq(unsigned int irq)
 {
 	unsigned long flags;
 
@@ -162,7 +162,7 @@
 }
 
 /* called by request irq */
-static void eisa_enable_irq(void *irq_dev, int irq)
+static void eisa_enable_irq(unsigned int irq)
 {
 	unsigned long flags;
 	EISA_DBG("enable irq %d\n", irq);
@@ -180,52 +180,24 @@
 	EISA_DBG("pic1 mask %02x\n", eisa_in8(0xa1));
 }
 
-static void eisa_mask_irq(void *irq_dev, int irq)
+static unsigned int eisa_startup_irq(unsigned int irq)
 {
-	unsigned long flags;
-	EISA_DBG("mask irq %d\n", irq);
-	
-        /* mask irq */
-	spin_lock_irqsave(&eisa_irq_lock, flags);
-	if (irq & 8) {
-		slave_mask |= (1 << (irq&7));
-		eisa_out8(slave_mask, 0xa1);
-	} else {
-		master_mask |= (1 << (irq&7));
-		eisa_out8(master_mask, 0x21);
-	}
-	spin_unlock_irqrestore(&eisa_irq_lock, flags);
+	eisa_enable_irq(irq);
+	return 0;
 }
 
-static void eisa_unmask_irq(void *irq_dev, int irq)
-{
-	unsigned long flags;
-	EISA_DBG("unmask irq %d\n", irq);
-        
-	/* unmask */
-	spin_lock_irqsave(&eisa_irq_lock, flags);
-	if (irq & 8) {
-		slave_mask &= ~(1 << (irq&7));
-		eisa_out8(slave_mask, 0xa1);
-	} else {
-		master_mask &= ~(1 << (irq&7));
-		eisa_out8(master_mask, 0x21);
-	}
-	spin_unlock_irqrestore(&eisa_irq_lock, flags);
-}
-
-static struct irqaction action[IRQ_PER_REGION];
-
-/* EISA needs to be fixed at IRQ region #0 (EISA_IRQ_REGION) */
-static struct irq_region eisa_irq_region = {
-	.ops	= { eisa_disable_irq, eisa_enable_irq, eisa_mask_irq, eisa_unmask_irq },
-	.data	= { .name = "EISA", .irqbase = 0 },
-	.action	= action,
+static struct hw_interrupt_type eisa_interrupt_type = {
+	.typename =	"EISA",
+	.startup =	eisa_startup_irq,
+	.shutdown =	eisa_disable_irq,
+	.enable =	eisa_enable_irq,
+	.disable =	eisa_disable_irq,
+	.ack =		no_ack_irq,
+	.end =		no_end_irq,
 };
 
-static irqreturn_t eisa_irq(int _, void *intr_dev, struct pt_regs *regs)
+static irqreturn_t eisa_irq(int wax_irq, void *intr_dev, struct pt_regs *regs)
 {
-	extern void do_irq(struct irqaction *a, int i, struct pt_regs *p);
 	int irq = gsc_readb(0xfc01f000); /* EISA supports 16 irqs */
 	unsigned long flags;
         
@@ -259,8 +231,7 @@
 	}
 	spin_unlock_irqrestore(&eisa_irq_lock, flags);
 
-   
-	do_irq(&eisa_irq_region.action[irq], EISA_IRQ_REGION + irq, regs);
+	__do_IRQ(irq, regs);
    
 	spin_lock_irqsave(&eisa_irq_lock, flags);
 	/* unmask */
@@ -281,6 +252,11 @@
 	return IRQ_HANDLED;
 }
 
+static struct irqaction irq2_action = {
+	.handler = dummy_irq2_handler,
+	.name = "cascade",
+};
+
 static void init_eisa_pic(void)
 {
 	unsigned long flags;
@@ -331,7 +307,7 @@
 
 static int __devinit eisa_probe(struct parisc_device *dev)
 {
-	int result;
+	int i, result;
 
 	char *name = is_mongoose(dev) ? "Mongoose" : "Wax";
 
@@ -361,18 +337,18 @@
 	}
 	pcibios_register_hba(&eisa_dev.hba);
 
-	result = request_irq(dev->irq, eisa_irq, SA_SHIRQ, "EISA", NULL);
+	result = request_irq(dev->irq, eisa_irq, SA_SHIRQ, "EISA", &eisa_dev);
 	if (result) {
 		printk(KERN_ERR "EISA: request_irq failed!\n");
 		return result;
 	}
 	
 	/* Reserve IRQ2 */
-	action[2].handler = dummy_irq2_handler;
-	action[2].name = "cascade";
+	irq_desc[2].action = &irq2_action;
 	
-	eisa_irq_region.data.dev = dev;
-	irq_region[0] = &eisa_irq_region;
+	for (i = 0; i < 16; i++) {
+		irq_desc[i].handler = &eisa_interrupt_type;
+	}
 	
 	EISA_bus = 1;
 	if (dev->num_addrs) {
diff -Nru a/drivers/parisc/gsc.c b/drivers/parisc/gsc.c
--- a/drivers/parisc/gsc.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/parisc/gsc.c	2005-03-01 23:39:16 -08:00
@@ -25,15 +25,9 @@
 
 #include <asm/hardware.h>
 #include <asm/io.h>
-#include <asm/irq.h>
 
 #include "gsc.h"
 
-/* This sets the vmerge boundary and size, it's here because it has to
- * be available on all platforms (zero means no-virtual merging) */
-unsigned long parisc_vmerge_boundary = 0;
-unsigned long parisc_vmerge_max_size = 0;
-
 #undef DEBUG
 
 #ifdef DEBUG
@@ -61,7 +55,7 @@
 {
 	int c = irq;
 
-	irq += IRQ_FROM_REGION(CPU_IRQ_REGION); /* virtualize the IRQ first */
+	irq += CPU_IRQ_BASE; /* virtualize the IRQ first */
 
 	irq = txn_claim_irq(irq);
 	if (irq < 0) {
@@ -79,116 +73,146 @@
 EXPORT_SYMBOL(gsc_alloc_irq);
 EXPORT_SYMBOL(gsc_claim_irq);
 
-/* IRQ bits must be numbered from Most Significant Bit */
-#define GSC_FIX_IRQ(x)	(31-(x))
-#define GSC_MASK_IRQ(x)	(1<<(GSC_FIX_IRQ(x)))
-
 /* Common interrupt demultiplexer used by Asp, Lasi & Wax.  */
-irqreturn_t busdev_barked(int busdev_irq, void *dev, struct pt_regs *regs)
+irqreturn_t gsc_asic_intr(int gsc_asic_irq, void *dev, struct pt_regs *regs)
 {
-	unsigned long irq;
-	struct busdevice *busdev = (struct busdevice *) dev;
+	unsigned long irr;
+	struct gsc_asic *gsc_asic = dev;
 
-	/* 
-	    Don't need to protect OFFSET_IRR with spinlock since this is
-	    the only place it's touched.
-	    Protect busdev_region by disabling this region's interrupts,
-	    modifying the region, and then re-enabling the region.
-	*/
-
-	irq = gsc_readl(busdev->hpa+OFFSET_IRR);
-	if (irq == 0) {
-		printk(KERN_ERR "%s: barking without apparent reason.\n", busdev->name);
-	} else {
-		DEBPRINTK ("%s (0x%x) barked, mask=0x%x, irq=%d\n", 
-		    busdev->name, busdev->busdev_region->data.irqbase, 
-		    irq, GSC_FIX_IRQ(ffs(irq))+1 );
+	irr = gsc_readl(gsc_asic->hpa + OFFSET_IRR);
+	if (irr == 0)
+		return IRQ_NONE;
+
+	DEBPRINTK("%s intr, mask=0x%x\n", gsc_asic->name, irr);
+
+	do {
+		int local_irq = __ffs(irr);
+		unsigned int irq = gsc_asic->global_irq[local_irq];
+		__do_IRQ(irq, regs);
+		irr &= ~(1 << local_irq);
+	} while (irr);
 
-		do_irq_mask(irq, busdev->busdev_region, regs);
-	}
 	return IRQ_HANDLED;
 }
 
-static void
-busdev_disable_irq(void *irq_dev, int irq)
+int gsc_find_local_irq(unsigned int irq, int *global_irqs, int limit)
 {
-	/* Disable the IRQ line by clearing the bit in the IMR */
-	u32 imr = gsc_readl(BUSDEV_DEV(irq_dev)->hpa+OFFSET_IMR);
-	imr &= ~(GSC_MASK_IRQ(irq));
+	int local_irq;
 
-	DEBPRINTK( KERN_WARNING "%s(%p, %d) %s: IMR 0x%x\n", 
-		    __FUNCTION__, irq_dev, irq, BUSDEV_DEV(irq_dev)->name, imr);
+	for (local_irq = 0; local_irq < limit; local_irq++) {
+		if (global_irqs[local_irq] == irq)
+			return local_irq;
+	}
 
-	gsc_writel(imr, BUSDEV_DEV(irq_dev)->hpa+OFFSET_IMR);
+	return NO_IRQ;
 }
 
+static void gsc_asic_disable_irq(unsigned int irq)
+{
+	struct gsc_asic *irq_dev = irq_desc[irq].handler_data;
+	int local_irq = gsc_find_local_irq(irq, irq_dev->global_irq, 32);
+	u32 imr;
+
+	DEBPRINTK(KERN_DEBUG "%s(%d) %s: IMR 0x%x\n", __FUNCTION__, irq,
+			irq_dev->name, imr);
+
+	/* Disable the IRQ line by clearing the bit in the IMR */
+	imr = gsc_readl(irq_dev->hpa + OFFSET_IMR);
+	imr &= ~(1 << local_irq);
+	gsc_writel(imr, irq_dev->hpa + OFFSET_IMR);
+}
 
-static void
-busdev_enable_irq(void *irq_dev, int irq)
+static void gsc_asic_enable_irq(unsigned int irq)
 {
+	struct gsc_asic *irq_dev = irq_desc[irq].handler_data;
+	int local_irq = gsc_find_local_irq(irq, irq_dev->global_irq, 32);
+	u32 imr;
+
+	DEBPRINTK(KERN_DEBUG "%s(%d) %s: IMR 0x%x\n", __FUNCTION__, irq,
+			irq_dev->name, imr);
+
 	/* Enable the IRQ line by setting the bit in the IMR */
-	unsigned long addr = BUSDEV_DEV(irq_dev)->hpa + OFFSET_IMR;
-	u32 imr = gsc_readl(addr);
-	imr |= GSC_MASK_IRQ(irq);
+	imr = gsc_readl(irq_dev->hpa + OFFSET_IMR);
+	imr |= 1 << local_irq;
+	gsc_writel(imr, irq_dev->hpa + OFFSET_IMR);
+	/*
+	 * FIXME: read IPR to make sure the IRQ isn't already pending.
+	 *   If so, we need to read IRR and manually call do_irq().
+	 */
+}
+
+static unsigned int gsc_asic_startup_irq(unsigned int irq)
+{
+	gsc_asic_enable_irq(irq);
+	return 0;
+}
+
+static struct hw_interrupt_type gsc_asic_interrupt_type = {
+	.typename =	"GSC-ASIC",
+	.startup =	gsc_asic_startup_irq,
+	.shutdown =	gsc_asic_disable_irq,
+	.enable =	gsc_asic_enable_irq,
+	.disable =	gsc_asic_disable_irq,
+	.ack =		no_ack_irq,
+	.end =		no_end_irq,
+};
 
-	DEBPRINTK (KERN_WARNING "%s(%p, %d) %s: IMR 0x%x\n", 
-		    __FUNCTION__, irq_dev, irq, BUSDEV_DEV(irq_dev)->name, imr);
+int gsc_assign_irq(struct hw_interrupt_type *type, void *data)
+{
+	static int irq = GSC_IRQ_BASE;
 
-	gsc_writel(imr, addr);
-//	gsc_writel(~0L, addr);
+	if (irq > GSC_IRQ_MAX)
+		return NO_IRQ;
 
-/* FIXME: read IPR to make sure the IRQ isn't already pending.
-**   If so, we need to read IRR and manually call do_irq_mask().
-**   This code should be shared with busdev_unmask_irq().
-*/
+	irq_desc[irq].handler = type;
+	irq_desc[irq].handler_data = data;
+	return irq++;
 }
 
-static void
-busdev_mask_irq(void *irq_dev, int irq)
+void gsc_asic_assign_irq(struct gsc_asic *asic, int local_irq, int *irqp)
 {
-/* FIXME: Clear the IMR bit in busdev for that IRQ */
+	int irq = gsc_assign_irq(&gsc_asic_interrupt_type, asic);
+	if (irq == NO_IRQ)
+		return;
+
+	*irqp = irq;
+	asic->global_irq[local_irq] = irq;
 }
 
-static void
-busdev_unmask_irq(void *irq_dev, int irq)
+void gsc_fixup_irqs(struct parisc_device *parent, void *ctrl,
+			void (*choose_irq)(struct parisc_device *, void *))
 {
-/* FIXME: Read IPR. Set the IMR bit in busdev for that IRQ.
-   call do_irq_mask() if IPR is non-zero
-*/
-}
+	struct device *dev;
 
-struct irq_region_ops busdev_irq_ops = {
-	.disable_irq =	busdev_disable_irq,
-	.enable_irq =	busdev_enable_irq,
-	.mask_irq =	busdev_mask_irq,
-	.unmask_irq =	busdev_unmask_irq
-};
+	list_for_each_entry(dev, &parent->dev.children, node) {
+		struct parisc_device *padev = to_parisc_device(dev);
 
+		/* work-around for 715/64 and others which have parent 
+		   at path [5] and children at path [5/0/x] */
+		if (padev->id.hw_type == HPHW_FAULTY)
+			return gsc_fixup_irqs(padev, ctrl, choose_irq);
+		choose_irq(padev, ctrl);
+	}
+}
 
-int gsc_common_irqsetup(struct parisc_device *parent, struct busdevice *busdev)
+int gsc_common_setup(struct parisc_device *parent, struct gsc_asic *gsc_asic)
 {
 	struct resource *res;
 
-	busdev->gsc = parent;
-
-	/* the IRQs we simulate */
-	busdev->busdev_region = alloc_irq_region(32, &busdev_irq_ops,
-						 busdev->name, busdev);
-	if (!busdev->busdev_region)
-		return -ENOMEM;
+	gsc_asic->gsc = parent;
 
 	/* allocate resource region */
-	res = request_mem_region(busdev->hpa, 0x100000, busdev->name);
+	res = request_mem_region(gsc_asic->hpa, 0x100000, gsc_asic->name);
 	if (res) {
 		res->flags = IORESOURCE_MEM; 	/* do not mark it busy ! */
 	}
 
 #if 0
-	printk(KERN_WARNING "%s IRQ %d EIM 0x%x", busdev->name,
-			busdev->parent_irq, busdev->eim);
-	if (gsc_readl(busdev->hpa + OFFSET_IMR))
+	printk(KERN_WARNING "%s IRQ %d EIM 0x%x", gsc_asic->name,
+			parent->irq, gsc_asic->eim);
+	if (gsc_readl(gsc_asic->hpa + OFFSET_IMR))
 		printk("  IMR is non-zero! (0x%x)",
-				gsc_readl(busdev->hpa + OFFSET_IMR));
+				gsc_readl(gsc_asic->hpa + OFFSET_IMR));
 	printk("\n");
 #endif
 
diff -Nru a/drivers/parisc/gsc.h b/drivers/parisc/gsc.h
--- a/drivers/parisc/gsc.h	2005-03-01 23:38:52 -08:00
+++ b/drivers/parisc/gsc.h	2005-03-01 23:38:52 -08:00
@@ -25,22 +25,23 @@
 	int irq;		/* virtual IRQ */
 };
 
-struct busdevice {
+struct gsc_asic {
 	struct parisc_device *gsc;
 	unsigned long hpa;
 	char *name;
 	int version;
 	int type;
-	int parent_irq;
 	int eim;
-	struct irq_region *busdev_region;
+	int global_irq[32];
 };
 
-/* short cut to keep the compiler happy */
-#define BUSDEV_DEV(x)	((struct busdevice *) (x))
+int gsc_common_setup(struct parisc_device *parent, struct gsc_asic *gsc_asic);
+int gsc_alloc_irq(struct gsc_irq *dev);			/* dev needs an irq */
+int gsc_claim_irq(struct gsc_irq *dev, int irq);	/* dev needs this irq */
+int gsc_assign_irq(struct hw_interrupt_type *type, void *data);
+int gsc_find_local_irq(unsigned int irq, int *global_irq, int limit);
+void gsc_fixup_irqs(struct parisc_device *parent, void *ctrl,
+		void (*choose)(struct parisc_device *child, void *ctrl));
+void gsc_asic_assign_irq(struct gsc_asic *asic, int local_irq, int *irqp);
 
-int gsc_common_irqsetup(struct parisc_device *parent, struct busdevice *busdev);
-extern int gsc_alloc_irq(struct gsc_irq *dev);	/* dev needs an irq */
-extern int gsc_claim_irq(struct gsc_irq *dev, int irq);	/* dev needs this irq */
-
-irqreturn_t busdev_barked(int busdev_irq, void *dev, struct pt_regs *regs);
+irqreturn_t gsc_asic_intr(int irq, void *dev, struct pt_regs *regs);
diff -Nru a/drivers/parisc/iosapic.c b/drivers/parisc/iosapic.c
--- a/drivers/parisc/iosapic.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/parisc/iosapic.c	2005-03-01 23:39:18 -08:00
@@ -76,35 +76,13 @@
 ** iosapic_register().
 **
 **
-** IRQ region notes
-** ----------------
-** The data passed to iosapic_interrupt() is per IRQ line.
-** Each IRQ line will get one txn_addr/data pair. Thus each IRQ region,
-** will have several txn_addr/data pairs (up to 7 for current I/O SAPIC
-** implementations).  The IRQ region "sysdata" will NOT be directly passed
-** to the interrupt handler like GSCtoPCI (dino.c).
-**
-** iosapic interrupt handler will NOT call do_irq_mask().
-** It doesn't need to read a bit mask to determine which IRQ line was pulled
-** since it already knows based on vector_info passed to iosapic_interrupt().
-**
-** One IRQ number represents both an IRQ line and a driver ISR.
-** The I/O sapic driver can't manage shared IRQ lines because
-** additional data besides the IRQ number must be passed via
-** irq_region_ops. do_irq() and request_irq() must manage
-** a sharing a bit in the mask.
-**
-** iosapic_interrupt() replaces do_irq_mask() and calls do_irq().
-** Which IRQ line was asserted is already known since each
-** line has unique data associated with it. We could omit
-** iosapic_interrupt() from the calling path if it did NOT need
-** to write EOI. For unshared lines, it really doesn't.
-**
-** Unfortunately, can't optimize out EOI if IRQ line isn't "shared".
-** N-class console "device" and some sort of heartbeat actually share
-** one line though only one driver is registered...<sigh>...this was
-** true for HP-UX at least. May not be true for parisc-linux.
-**
+** IRQ handling notes
+** ------------------
+** The IO-SAPIC can indicate to the CPU which interrupt was asserted.
+** So, unlike the GSC-ASIC and Dino, we allocate one CPU interrupt per
+** IO-SAPIC interrupt and call the device driver's handler directly.
+** The IO-SAPIC driver hijacks the CPU interrupt handler so it can
+** issue the End Of Interrupt command to the IO-SAPIC.
 **
 ** Overview of exported iosapic functions
 ** --------------------------------------
@@ -138,11 +116,6 @@
 **   o locate vector_info (needs: isi, intr_line)
 **   o allocate processor "irq" and get txn_addr/data
 **   o request_irq(processor_irq,  iosapic_interrupt, vector_info,...)
-**   o pcidev->irq = isi->isi_region...base + intr_line;
-**
-** iosapic_interrupt:
-**   o call do_irq(vector->isi->irq_region, vector->irq_line, regs)
-**   o assume level triggered and write EOI
 **
 ** iosapic_enable_irq:
 **   o clear any pending IRQ on that line
@@ -151,8 +124,6 @@
 **
 ** iosapic_disable_irq:
 **   o disable IRdT - call disable_irq(vector[line]->processor_irq)
-**
-** FIXME: mask/unmask
 */
 
 
@@ -160,18 +131,15 @@
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/spinlock.h>
-#include <linux/pci.h>		/* pci cfg accessor functions  */
+#include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
-#include <linux/interrupt.h>	/* irqaction */
-#include <linux/irq.h>		/* irq_region support */
+#include <linux/interrupt.h>
 
 #include <asm/byteorder.h>	/* get in-line asm for swab */
 #include <asm/pdc.h>
 #include <asm/pdcpat.h>
 #include <asm/page.h>
-#include <asm/segment.h>
 #include <asm/system.h>
 #include <asm/io.h>		/* read/write functions */
 #ifdef CONFIG_SUPERIO
@@ -278,10 +246,12 @@
 #define IOSAPIC_IRDT_ID_EID_SHIFT              0x10
 
 
-static struct iosapic_info *iosapic_list;
-static spinlock_t iosapic_lock;
-static int iosapic_count;
+static spinlock_t iosapic_lock = SPIN_LOCK_UNLOCKED;
 
+static inline void iosapic_eoi(void __iomem *addr, unsigned int data)
+{
+	__raw_writel(data, addr);
+}
 
 /*
 ** REVISIT: future platforms may have more than one IRT.
@@ -426,7 +396,7 @@
 	unsigned long cell = 0;
 
 	/* init global data */
-	iosapic_lock = SPIN_LOCK_UNLOCKED;
+	spin_lock_init(&iosapic_lock);
         iosapic_list = (struct iosapic_info *) NULL;
 	iosapic_count = 0;
 
@@ -598,167 +568,34 @@
 	return irt_find_irqline(isi, intr_slot, intr_pin);
 }
 
-
-static irqreturn_t
-iosapic_interrupt(int irq, void *dev_id, struct pt_regs * regs)
-{
-	struct vector_info *vi = (struct vector_info *) dev_id;
-	extern void do_irq(struct irqaction *a, int i, struct pt_regs *p);
-	int irq_num = vi->iosapic->isi_region->data.irqbase + vi->irqline;
-
-	DBG("iosapic_interrupt(): irq %d line %d eoi 0x%p 0x%x\n",
-		irq, vi->irqline, vi->eoi_addr, vi->eoi_data);
-
-	/* Do NOT need to mask/unmask IRQ. processor is already masked. */
-
-	do_irq(&vi->iosapic->isi_region->action[vi->irqline], irq_num, regs);
-
-	/*
-	** PARISC only supports PCI devices below I/O SAPIC.
-	** PCI only supports level triggered in order to share IRQ lines.
-	** ergo I/O SAPIC must always issue EOI on parisc.
-	**
-	** i386/ia64 support ISA devices and have to deal with
-	** edge-triggered interrupts too.
-	*/
-	__raw_writel(vi->eoi_data, vi->eoi_addr);
-	return IRQ_HANDLED;
-}
-
-
-int
-iosapic_fixup_irq(void *isi_obj, struct pci_dev *pcidev)
-{
-	struct iosapic_info *isi = (struct iosapic_info *)isi_obj;
-	struct irt_entry *irte = NULL;  /* only used if PAT PDC */
-	struct vector_info *vi;
-	int isi_line;	/* line used by device */
-	int tmp;
-
-	if (NULL == isi) {
-		printk(KERN_WARNING MODULE_NAME ": hpa not registered for %s\n",
-			pci_name(pcidev));
-		return(-1);
-	}
-
-#ifdef CONFIG_SUPERIO
-	/*
-	 * HACK ALERT! (non-compliant PCI device support)
-	 *
-	 * All SuckyIO interrupts are routed through the PIC's on function 1.
-	 * But SuckyIO OHCI USB controller gets an IRT entry anyway because
-	 * it advertises INT D for INT_PIN.  Use that IRT entry to get the
-	 * SuckyIO interrupt routing for PICs on function 1 (*BLEECCHH*).
-	 */
-	if (is_superio_device(pcidev)) {
-		/* We must call superio_fixup_irq() to register the pdev */
-		pcidev->irq = superio_fixup_irq(pcidev);
-
-		/* Don't return if need to program the IOSAPIC's IRT... */
-		if (PCI_FUNC(pcidev->devfn) != SUPERIO_USB_FN)
-			return pcidev->irq;
-	}
-#endif /* CONFIG_SUPERIO */
-
-	/* lookup IRT entry for isi/slot/pin set */
-	irte = iosapic_xlate_pin(isi, pcidev);
-	if (NULL == irte) {
-		printk("iosapic: no IRTE for %s (IRQ not connected?)\n",
-				pci_name(pcidev));
-		return(-1);
-	}
-	DBG_IRT("iosapic_fixup_irq(): irte %p %x %x %x %x %x %x %x %x\n",
-		irte,
-		irte->entry_type,
-		irte->entry_length,
-		irte->polarity_trigger,
-		irte->src_bus_irq_devno,
-		irte->src_bus_id,
-		irte->src_seg_id,
-		irte->dest_iosapic_intin,
-		(u32) irte->dest_iosapic_addr);
-	isi_line = irte->dest_iosapic_intin;
-	pcidev->irq = isi->isi_region->data.irqbase + isi_line;
-
-	/* get vector info for this input line */
-	ASSERT(NULL != isi->isi_vector);
-	vi = &(isi->isi_vector[isi_line]);
-	DBG_IRT("iosapic_fixup_irq:  line %d vi 0x%p\n", isi_line, vi);
-
-	/* If this IRQ line has already been setup, skip it */
-	if (vi->irte)
-		return pcidev->irq;
-
-	vi->irte = irte;
-
-	/* Allocate processor IRQ */
-	vi->txn_irq = txn_alloc_irq();
-
-/* XXX/FIXME The txn_alloc_irq() code and related code should be moved
-** to enable_irq(). That way we only allocate processor IRQ bits
-** for devices that actually have drivers claiming them.
-** Right now we assign an IRQ to every PCI device present regardless
-** of whether it's used or not.
-*/
-	if (vi->txn_irq < 0)
-		panic("I/O sapic: couldn't get TXN IRQ\n");
-
-	/* enable_irq() will use txn_* to program IRdT */
-	vi->txn_addr = txn_alloc_addr(vi->txn_irq);
-	vi->txn_data = txn_alloc_data(vi->txn_irq, 8);
-        ASSERT(vi->txn_data < 256);  /* matches 8 above */
-
-	tmp = request_irq(vi->txn_irq, iosapic_interrupt, 0,
-						vi->name, vi);
-	ASSERT(tmp == 0);
-
-	vi->eoi_addr = (u32 *) (isi->isi_hpa + IOSAPIC_REG_EOI);
-	vi->eoi_data = cpu_to_le32(vi->txn_data);
-	ASSERT(NULL != isi->isi_region);
-
-	DBG_IRT("iosapic_fixup_irq() %d:%d %x %x line %d irq %d\n",
-		PCI_SLOT(pcidev->devfn), PCI_FUNC(pcidev->irq),
-		pcidev->vendor, pcidev->device, isi_line, pcidev->irq);
-
-	return pcidev->irq;
-}
-
-
-static void
-iosapic_rd_irt_entry(struct vector_info *vi , u32 *dp0, u32 *dp1)
+static void iosapic_rd_irt_entry(struct vector_info *vi , u32 *dp0, u32 *dp1)
 {
 	struct iosapic_info *isp = vi->iosapic;
 	u8 idx = vi->irqline;
 
-	*dp0 = iosapic_read(isp->isi_hpa, IOSAPIC_IRDT_ENTRY(idx));
-	*dp1 = iosapic_read(isp->isi_hpa, IOSAPIC_IRDT_ENTRY_HI(idx));
+	*dp0 = iosapic_read(isp->addr, IOSAPIC_IRDT_ENTRY(idx));
+	*dp1 = iosapic_read(isp->addr, IOSAPIC_IRDT_ENTRY_HI(idx));
 }
 
 
-static void
-iosapic_wr_irt_entry(struct vector_info *vi, u32 dp0, u32 dp1)
+static void iosapic_wr_irt_entry(struct vector_info *vi, u32 dp0, u32 dp1)
 {
 	struct iosapic_info *isp = vi->iosapic;
 
-	ASSERT(NULL != isp);
-	ASSERT(0 != isp->isi_hpa);
-	DBG_IRT("iosapic_wr_irt_entry(): irq %d hpa %p 0x%x 0x%x\n",
-		vi->irqline,
-		isp->isi_hpa,
-		dp0, dp1);
+	DBG_IRT("iosapic_wr_irt_entry(): irq %d hpa %lx 0x%x 0x%x\n",
+		vi->irqline, isp->isi_hpa, dp0, dp1);
 
-	iosapic_write(isp->isi_hpa, IOSAPIC_IRDT_ENTRY(vi->irqline), dp0);
+	iosapic_write(isp->addr, IOSAPIC_IRDT_ENTRY(vi->irqline), dp0);
 
 	/* Read the window register to flush the writes down to HW  */
-	dp0 = readl(isp->isi_hpa+IOSAPIC_REG_WINDOW);
+	dp0 = readl(isp->addr+IOSAPIC_REG_WINDOW);
 
-	iosapic_write(isp->isi_hpa, IOSAPIC_IRDT_ENTRY_HI(vi->irqline), dp1);
+	iosapic_write(isp->addr, IOSAPIC_IRDT_ENTRY_HI(vi->irqline), dp1);
 
 	/* Read the window register to flush the writes down to HW  */
-	dp1 = readl(isp->isi_hpa+IOSAPIC_REG_WINDOW);
+	dp1 = readl(isp->addr+IOSAPIC_REG_WINDOW);
 }
 
-
 /*
 ** set_irt prepares the data (dp0, dp1) according to the vector_info
 ** and target cpu (id_eid).  dp0/dp1 are then used to program I/O SAPIC
@@ -810,62 +647,31 @@
 }
 
 
-static void
-iosapic_disable_irq(void *irq_dev, int irq)
+static struct vector_info *iosapic_get_vector(unsigned int irq)
 {
-	ulong irqflags;
-	struct vector_info *vi = &(((struct vector_info *) irq_dev)[irq]);
-	u32 d0, d1;
-
-	ASSERT(NULL != vi);
-
-	IOSAPIC_LOCK(&iosapic_lock);
-
-#ifdef REVISIT_DESIGN_ISSUE
-/* 
-** XXX/FIXME
-
-disable_irq()/enable_irq(): drawback of using IRQ as a "handle"
-
-Current disable_irq interface only allows the irq_region support routines
-to manage sharing of "irq" objects.  The problem is the disable_irq()
-interface specifies which IRQ line needs to be disabled but does not
-identify the particular ISR which needs to be disabled.  IO sapic
-(and similar code in Dino) can only support one handler per IRQ
-since they don't further encode the meaning of the IRQ number.
-irq_region support has to hide it's implementation of "shared IRQ"
-behind a function call.
-
-Encoding the IRQ would be possible by I/O SAPIC but makes life really
-complicated for the IRQ handler and not help performance.
+	return irq_desc[irq].handler_data;
+}
 
-Need more info on how Linux supports shared IRQ lines on a PC.
-*/
-#endif /* REVISIT_DESIGN_ISSUE */
+static void iosapic_disable_irq(unsigned int irq)
+{
+	unsigned long flags;
+	struct vector_info *vi = iosapic_get_vector(irq);
+	u32 d0, d1;
 
+	spin_lock_irqsave(&iosapic_lock, flags);
 	iosapic_rd_irt_entry(vi, &d0, &d1);
 	d0 |= IOSAPIC_IRDT_ENABLE;
 	iosapic_wr_irt_entry(vi, d0, d1);
-
-	IOSAPIC_UNLOCK(&iosapic_lock);
-
-	/* disable ISR for parent */
-	disable_irq(vi->txn_irq);
+	spin_unlock_irqrestore(&iosapic_lock, flags);
 }
 
-
-static void
-iosapic_enable_irq(void *dev, int irq)
+static void iosapic_enable_irq(unsigned int irq)
 {
-	struct vector_info *vi = &(((struct vector_info *) dev)[irq]);
+	struct vector_info *vi = iosapic_get_vector(irq);
 	u32 d0, d1;
 
-	ASSERT(NULL != vi);
-	ASSERT(NULL != vi->irte);
-
 	/* data is initialized by fixup_irq */
-	ASSERT(0 < vi->txn_irq);
-	ASSERT(0UL != vi->txn_data);
+	WARN_ON(vi->txn_irq  == 0);
 
 	iosapic_set_irt_data(vi, &d0, &d1);
 	iosapic_wr_irt_entry(vi, d0, d1);
@@ -884,7 +690,7 @@
 	struct iosapic_info *isp = vi->iosapic;
 
 	for (d0=0x10; d0<0x1e; d0++) {
-		d1 = iosapic_read(isp->isi_hpa, d0);
+		d1 = iosapic_read(isp->addr, d0);
 		printk(" %x", d1);
 	}
 }
@@ -892,35 +698,141 @@
 #endif
 
 	/*
-	** Issueing I/O SAPIC an EOI causes an interrupt IFF IRQ line is
-	** asserted.  IRQ generally should not be asserted when a driver
-	** enables their IRQ. It can lead to "interesting" race conditions
-	** in the driver initialization sequence.
-	*/
-	__raw_writel(vi->eoi_data, vi->eoi_addr);
+	 * Issuing I/O SAPIC an EOI causes an interrupt IFF IRQ line is
+	 * asserted.  IRQ generally should not be asserted when a driver
+	 * enables their IRQ. It can lead to "interesting" race conditions
+	 * in the driver initialization sequence.
+	 */
+	DBG(KERN_DEBUG "enable_irq(%d): eoi(%p, 0x%x)\n", irq,
+			vi->eoi_addr, vi->eoi_data);
+	iosapic_eoi(vi->eoi_addr, vi->eoi_data);
 }
 
+/*
+ * PARISC only supports PCI devices below I/O SAPIC.
+ * PCI only supports level triggered in order to share IRQ lines.
+ * ergo I/O SAPIC must always issue EOI on parisc.
+ *
+ * i386/ia64 support ISA devices and have to deal with
+ * edge-triggered interrupts too.
+ */
+static void iosapic_end_irq(unsigned int irq)
+{
+	struct vector_info *vi = iosapic_get_vector(irq);
+	DBG(KERN_DEBUG "end_irq(%d): eoi(%p, 0x%x)\n", irq,
+			vi->eoi_addr, vi->eoi_data);
+	iosapic_eoi(vi->eoi_addr, vi->eoi_data);
+}
 
-static void
-iosapic_mask_irq(void *dev, int irq)
+static unsigned int iosapic_startup_irq(unsigned int irq)
 {
-	BUG();
+	iosapic_enable_irq(irq);
+	return 0;
 }
 
+static struct hw_interrupt_type iosapic_interrupt_type = {
+	.typename =	"IO-SAPIC-level",
+	.startup =	iosapic_startup_irq,
+	.shutdown =	iosapic_disable_irq,
+	.enable =	iosapic_enable_irq,
+	.disable =	iosapic_disable_irq,
+	.ack =		no_ack_irq,
+	.end =		iosapic_end_irq,
+//	.set_affinity =	iosapic_set_affinity_irq,
+};
 
-static void
-iosapic_unmask_irq(void *dev, int irq)
+int iosapic_fixup_irq(void *isi_obj, struct pci_dev *pcidev)
 {
-	BUG();
-}
+	struct iosapic_info *isi = isi_obj;
+	struct irt_entry *irte = NULL;  /* only used if PAT PDC */
+	struct vector_info *vi;
+	int isi_line;	/* line used by device */
 
+	if (!isi) {
+		printk(KERN_WARNING MODULE_NAME ": hpa not registered for %s\n",
+			pci_name(pcidev));
+		return -1;
+	}
 
-static struct irq_region_ops iosapic_irq_ops = {
-	.disable_irq =	iosapic_disable_irq,
-	.enable_irq =	iosapic_enable_irq,
-	.mask_irq =	iosapic_mask_irq,
-	.unmask_irq =	iosapic_unmask_irq
-};
+#ifdef CONFIG_SUPERIO
+	/*
+	 * HACK ALERT! (non-compliant PCI device support)
+	 *
+	 * All SuckyIO interrupts are routed through the PIC's on function 1.
+	 * But SuckyIO OHCI USB controller gets an IRT entry anyway because
+	 * it advertises INT D for INT_PIN.  Use that IRT entry to get the
+	 * SuckyIO interrupt routing for PICs on function 1 (*BLEECCHH*).
+	 */
+	if (is_superio_device(pcidev)) {
+		/* We must call superio_fixup_irq() to register the pdev */
+		pcidev->irq = superio_fixup_irq(pcidev);
+
+		/* Don't return if need to program the IOSAPIC's IRT... */
+		if (PCI_FUNC(pcidev->devfn) != SUPERIO_USB_FN)
+			return pcidev->irq;
+	}
+#endif /* CONFIG_SUPERIO */
+
+	/* lookup IRT entry for isi/slot/pin set */
+	irte = iosapic_xlate_pin(isi, pcidev);
+	if (!irte) {
+		printk("iosapic: no IRTE for %s (IRQ not connected?)\n",
+				pci_name(pcidev));
+		return -1;
+	}
+	DBG_IRT("iosapic_fixup_irq(): irte %p %x %x %x %x %x %x %x %x\n",
+		irte,
+		irte->entry_type,
+		irte->entry_length,
+		irte->polarity_trigger,
+		irte->src_bus_irq_devno,
+		irte->src_bus_id,
+		irte->src_seg_id,
+		irte->dest_iosapic_intin,
+		(u32) irte->dest_iosapic_addr);
+	isi_line = irte->dest_iosapic_intin;
+
+	/* get vector info for this input line */
+	vi = isi->isi_vector + isi_line;
+	DBG_IRT("iosapic_fixup_irq:  line %d vi 0x%p\n", isi_line, vi);
+
+	/* If this IRQ line has already been setup, skip it */
+	if (vi->irte)
+		goto out;
+
+	vi->irte = irte;
+
+	/* Allocate processor IRQ */
+	vi->txn_irq = txn_alloc_irq();
+
+	/*
+	 * XXX/FIXME The txn_alloc_irq() code and related code should be
+	 * moved to enable_irq(). That way we only allocate processor IRQ
+	 * bits for devices that actually have drivers claiming them.
+	 * Right now we assign an IRQ to every PCI device present,
+	 * regardless of whether it's used or not.
+	 */
+	if (vi->txn_irq < 0)
+		panic("I/O sapic: couldn't get TXN IRQ\n");
+
+	/* enable_irq() will use txn_* to program IRdT */
+	vi->txn_addr = txn_alloc_addr(vi->txn_irq);
+	vi->txn_data = txn_alloc_data(vi->txn_irq, 8);
+
+	vi->eoi_addr = isi->addr + IOSAPIC_REG_EOI;
+	vi->eoi_data = cpu_to_le32(vi->txn_data);
+
+	cpu_claim_irq(vi->txn_irq, &iosapic_interrupt_type, vi);
+
+ out:
+	pcidev->irq = vi->txn_irq;
+
+	DBG_IRT("iosapic_fixup_irq() %d:%d %x %x line %d irq %d\n",
+		PCI_SLOT(pcidev->devfn), PCI_FUNC(pcidev->devfn),
+		pcidev->vendor, pcidev->device, isi_line, pcidev->irq);
+
+	return pcidev->irq;
+}
 
 
 /*
@@ -944,10 +856,9 @@
 **	o read iosapic version and squirrel that away
 **	o read size of IRdT.
 **	o allocate and initialize isi_vector[]
-**	o allocate isi_region (registers region handlers)
+**	o allocate irq region
 */
-void *
-iosapic_register(unsigned long hpa)
+void *iosapic_register(unsigned long hpa)
 {
 	struct iosapic_info *isi = NULL;
 	struct irt_entry *irte = irt_cell;
@@ -993,27 +904,16 @@
 
 	if (vip == NULL) {
 		IOSAPIC_FREE(isi, struct iosapic_info, 1);
-		return (NULL);
+		return NULL;
 	}
 
 	memset(vip, 0, sizeof(struct vector_info) * isi->isi_num_vectors);
-	sprintf(isi->isi_name, "IO-SAPIC%02d", iosapic_count++);
 
-	/*
-	** Initialize vector array
-	*/
 	for (cnt=0; cnt < isi->isi_num_vectors; cnt++, vip++) {
 		vip->irqline = (unsigned char) cnt;
 		vip->iosapic = isi;
-		sprintf(vip->name, "%s-L%d", isi->isi_name, cnt);
 	}
-
-	isi->isi_region = alloc_irq_region(isi->isi_num_vectors,
-				&iosapic_irq_ops, isi->isi_name,
-				(void *) isi->isi_vector);
-
-	ASSERT(NULL != isi->isi_region);
-	return ((void *) isi);
+	return isi;
 }
 
 
diff -Nru a/drivers/parisc/iosapic_private.h b/drivers/parisc/iosapic_private.h
--- a/drivers/parisc/iosapic_private.h	2005-03-01 23:38:55 -08:00
+++ b/drivers/parisc/iosapic_private.h	2005-03-01 23:38:55 -08:00
@@ -136,23 +136,20 @@
 	u32	eoi_data;		/* IA64: ?       PA: swapped txn_data */
 	int	txn_irq;		/* virtual IRQ number for processor */
 	ulong	txn_addr;		/* IA64: id_eid  PA: partial HPA */
-	ulong	txn_data;		/* IA64: vector  PA: EIR bit */
+	u32	txn_data;		/* CPU interrupt bit */
 	u8	status;			/* status/flags */
 	u8	irqline;		/* INTINn(IRQ) */
-	char	name[32];		/* user visible identity */
 };
 
 
 struct iosapic_info {
-	struct iosapic_info  *isi_next;      /* list of I/O SAPIC          */
-	unsigned long	     isi_hpa;	     /* physical base address */
-	struct irq_region    *isi_region;    /* each I/O SAPIC is one region */
-	struct vector_info   *isi_vector;    /* IRdT (IRQ line) array  */
-	int                  isi_num_vectors; /* size of IRdT array */
-	int                  isi_status;     /* status/flags               */
-	unsigned int         isi_version;    /* DEBUG: data fr version reg */
-	/* round up to next cacheline */
-	char                 isi_name[20]; /* identify region for users */
+	struct iosapic_info *	isi_next;	/* list of I/O SAPIC */
+	void __iomem *		addr;		/* remapped address */
+	unsigned long		isi_hpa;	/* physical base address */
+	struct vector_info *	isi_vector;	/* IRdT (IRQ line) array */
+	int			isi_num_vectors; /* size of IRdT array */
+	int			isi_status;	/* status/flags */
+	unsigned int		isi_version;	/* DEBUG: data fr version reg */
 };
 
 
diff -Nru a/drivers/parisc/lasi.c b/drivers/parisc/lasi.c
--- a/drivers/parisc/lasi.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/parisc/lasi.c	2005-03-01 23:39:07 -08:00
@@ -16,7 +16,7 @@
 
 #include <linux/errno.h>
 #include <linux/init.h>
-#include <linux/irq.h>
+#include <linux/interrupt.h>
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/pm.h>
@@ -35,33 +35,30 @@
 #define LASI_IO_CONF	0x7FFFE	/* LASI primary configuration register */
 #define LASI_IO_CONF2	0x7FFFF	/* LASI secondary configuration register */
 
-static int lasi_choose_irq(struct parisc_device *dev)
+static void lasi_choose_irq(struct parisc_device *dev, void *ctrl)
 {
 	int irq;
 
-	/*
-	** "irq" bits below are numbered relative to most significant bit.
-	*/
 	switch (dev->id.sversion) {
-		case 0x74:	irq = 24; break; /* Centronics */
-		case 0x7B:	irq = 18; break; /* Audio */
-		case 0x81:	irq = 17; break; /* Lasi itself */
-		case 0x82:	irq = 22; break; /* SCSI */
-		case 0x83:	irq = 11; break; /* Floppy */
-		case 0x84:	irq =  5; break; /* PS/2 Keyboard */
-		case 0x87:	irq = 13; break; /* ISDN */
-		case 0x8A:	irq = 23; break; /* LAN */
-		case 0x8C:	irq = 26; break; /* RS232 */
-		case 0x8D:	irq = (dev->hw_path == 13) ? 15 : 14;
-						break; /* Telephone */
-		default: 	irq = -1; break; /* unknown */
+		case 0x74:	irq =  7; break; /* Centronics */
+		case 0x7B:	irq = 13; break; /* Audio */
+		case 0x81:	irq = 14; break; /* Lasi itself */
+		case 0x82:	irq =  9; break; /* SCSI */
+		case 0x83:	irq = 20; break; /* Floppy */
+		case 0x84:	irq = 26; break; /* PS/2 Keyboard */
+		case 0x87:	irq = 18; break; /* ISDN */
+		case 0x8A:	irq =  8; break; /* LAN */
+		case 0x8C:	irq =  5; break; /* RS232 */
+		case 0x8D:	irq = (dev->hw_path == 13) ? 16 : 17; break;
+						 /* Telephone */
+		default: 	return;		 /* unknown */
 	}
 
-	return irq;
+	gsc_asic_assign_irq(ctrl, irq, &dev->irq);
 }
 
 static void __init
-lasi_init_irq(struct busdevice *this_lasi)
+lasi_init_irq(struct gsc_asic *this_lasi)
 {
 	unsigned long lasi_base = this_lasi->hpa;
 
@@ -170,11 +167,11 @@
 int __init
 lasi_init_chip(struct parisc_device *dev)
 {
-	struct busdevice *lasi;
+	struct gsc_asic *lasi;
 	struct gsc_irq gsc_irq;
-	int irq, ret;
+	int ret;
 
-	lasi = kmalloc(sizeof(struct busdevice), GFP_KERNEL);
+	lasi = kmalloc(sizeof(*lasi), GFP_KERNEL);
 	if (!lasi)
 		return -ENOMEM;
 
@@ -193,36 +190,33 @@
 	lasi_init_irq(lasi);
 
 	/* the IRQ lasi should use */
-	irq = gsc_alloc_irq(&gsc_irq);
-	if (irq < 0) {
+	dev->irq = gsc_alloc_irq(&gsc_irq);
+	if (dev->irq < 0) {
 		printk(KERN_ERR "%s(): cannot get GSC irq\n",
 				__FUNCTION__);
 		kfree(lasi);
 		return -EBUSY;
 	}
 
-	ret = request_irq(gsc_irq.irq, busdev_barked, 0, "lasi", lasi);
+	lasi->eim = ((u32) gsc_irq.txn_addr) | gsc_irq.txn_data;
+
+	ret = request_irq(gsc_irq.irq, gsc_asic_intr, 0, "lasi", lasi);
 	if (ret < 0) {
 		kfree(lasi);
 		return ret;
 	}
 
-	/* Save this for debugging later */
-	lasi->parent_irq = gsc_irq.irq;
-	lasi->eim = ((u32) gsc_irq.txn_addr) | gsc_irq.txn_data;
-
 	/* enable IRQ's for devices below LASI */
 	gsc_writel(lasi->eim, lasi->hpa + OFFSET_IAR);
 
 	/* Done init'ing, register this driver */
-	ret = gsc_common_irqsetup(dev, lasi);
+	ret = gsc_common_setup(dev, lasi);
 	if (ret) {
 		kfree(lasi);
 		return ret;
 	}    
 
-	fixup_child_irqs(dev, lasi->busdev_region->data.irqbase,
-			lasi_choose_irq);
+	gsc_fixup_irqs(dev, lasi, lasi_choose_irq);
 
 	/* initialize the power off function */
 	/* FIXME: Record the LASI HPA for the power off function.  This should
diff -Nru a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c
--- a/drivers/parisc/lba_pci.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/parisc/lba_pci.c	2005-03-01 23:39:08 -08:00
@@ -41,11 +41,9 @@
 #include <linux/smp_lock.h>
 
 #include <asm/byteorder.h>
-#include <asm/irq.h>		/* for struct irq_region support */
 #include <asm/pdc.h>
 #include <asm/pdcpat.h>
 #include <asm/page.h>
-#include <asm/segment.h>
 #include <asm/system.h>
 
 #include <asm/hardware.h>	/* for register_parisc_driver() stuff */
@@ -1565,7 +1563,7 @@
 {
 	pci_bios = &lba_bios_ops;
 	pcibios_register_hba(HBA_DATA(lba_dev));
-	lba_dev->lba_lock = SPIN_LOCK_UNLOCKED;	
+	spin_lock_init(&lba_dev->lba_lock);
 
 	/*
 	** Set flags which depend on hw_rev
diff -Nru a/drivers/parisc/led.c b/drivers/parisc/led.c
--- a/drivers/parisc/led.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/parisc/led.c	2005-03-01 23:38:54 -08:00
@@ -26,7 +26,7 @@
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/ioport.h>
-#include <linux/version.h>
+#include <linux/utsname.h>
 #include <linux/delay.h>
 #include <linux/netdevice.h>
 #include <linux/inetdevice.h>
@@ -56,7 +56,7 @@
 static int led_diskio = 1;
 static int led_lanrxtx = 1;
 static char lcd_text[32];
-static char lcd_text_default[] = "Linux " UTS_RELEASE;
+static char lcd_text_default[32];
 
 #if 0
 #define DPRINTK(x)	printk x
@@ -675,6 +675,9 @@
 {
 	struct pdc_chassis_info chassis_info;
 	int ret;
+
+	snprintf(lcd_text_default, sizeof(lcd_text_default),
+		"Linux %s", system_utsname.release);
 
 	/* Work around the buggy PDC of KittyHawk-machines */
 	switch (CPU_HVERSION) {
diff -Nru a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c
--- a/drivers/parisc/sba_iommu.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/parisc/sba_iommu.c	2005-03-01 23:39:08 -08:00
@@ -1861,7 +1861,7 @@
 			__FUNCTION__, i, res_size, sba_dev->ioc[i].res_map);
 	}
 
-	sba_dev->sba_lock = SPIN_LOCK_UNLOCKED;
+	spin_lock_init(&sba_dev->sba_lock);
 	ioc_needs_fdc = boot_cpu_data.pdc.capabilities & PDC_MODEL_IOPDIR_FDC;
 
 #ifdef DEBUG_SBA_INIT
diff -Nru a/drivers/parisc/superio.c b/drivers/parisc/superio.c
--- a/drivers/parisc/superio.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/parisc/superio.c	2005-03-01 23:39:07 -08:00
@@ -72,7 +72,6 @@
 
 #include <asm/io.h>
 #include <asm/hardware.h>
-#include <asm/irq.h>
 #include <asm/superio.h>
 
 static struct superio_device sio_dev;
@@ -87,9 +86,8 @@
 #endif
 
 static irqreturn_t
-superio_interrupt(int irq, void *devp, struct pt_regs *regs)
+superio_interrupt(int parent_irq, void *devp, struct pt_regs *regs)
 {
-	struct superio_device *sio = (struct superio_device *)devp;
 	u8 results;
 	u8 local_irq;
 
@@ -108,7 +106,7 @@
 		 * We don't know if an interrupt was/is pending and thus
 		 * just call the handler for that IRQ as if it were pending.
 		 */
-		return IRQ_HANDLED;
+		return IRQ_NONE;
 	}
 
 	/* Check to see which device is interrupting */
@@ -116,7 +114,6 @@
 
 	if (local_irq == 2 || local_irq > 7) {
 		printk(KERN_ERR "SuperIO: slave interrupted!\n");
-		BUG();
 		return IRQ_HANDLED;
 	}
 
@@ -133,9 +130,7 @@
 	}
 
 	/* Call the appropriate device's interrupt */
-	do_irq(&sio->irq_region->action[local_irq],
-		sio->irq_region->data.irqbase + local_irq,
-		regs);
+	__do_IRQ(local_irq, regs);
 
 	/* set EOI - forces a new interrupt if a lower priority device
 	 * still needs service.
@@ -280,59 +275,53 @@
 }
 
 
-static void
-superio_disable_irq(void *dev, int local_irq)
+static void superio_disable_irq(unsigned int irq)
 {
 	u8 r8;
 
-	if ((local_irq < 1) || (local_irq == 2) || (local_irq > 7)) {
-	    printk(KERN_ERR "SuperIO: Illegal irq number.\n");
-	    BUG();
-	    return;
+	if ((irq < 1) || (irq == 2) || (irq > 7)) {
+		printk(KERN_ERR "SuperIO: Illegal irq number.\n");
+		BUG();
+		return;
 	}
 
 	/* Mask interrupt */
 
 	r8 = inb(IC_PIC1+1);
-	r8 |= (1 << local_irq);
+	r8 |= (1 << irq);
 	outb (r8,IC_PIC1+1);
 }
 
-static void
-superio_enable_irq(void *dev, int local_irq)
+static void superio_enable_irq(unsigned int irq)
 {
 	u8 r8;
 
-	if ((local_irq < 1) || (local_irq == 2) || (local_irq > 7)) {
-	    printk(KERN_ERR "SuperIO: Illegal irq number (%d).\n", local_irq);
-	    BUG();
-	    return;
+	if ((irq < 1) || (irq == 2) || (irq > 7)) {
+		printk(KERN_ERR "SuperIO: Illegal irq number (%d).\n", irq);
+		BUG();
+		return;
 	}
 
 	/* Unmask interrupt */
 	r8 = inb(IC_PIC1+1);
-	r8 &= ~(1 << local_irq);
+	r8 &= ~(1 << irq);
 	outb (r8,IC_PIC1+1);
 }
 
-
-static void
-superio_mask_irq(void *dev, int local_irq)
-{
-	BUG();
-}
-
-static void
-superio_unmask_irq(void *dev, int local_irq)
+static unsigned int superio_startup_irq(unsigned int irq)
 {
-	BUG();
+	superio_enable_irq(irq);
+	return 0;
 }
 
-static struct irq_region_ops superio_irq_ops = {
-	.disable_irq =	superio_disable_irq,
-	.enable_irq =	superio_enable_irq,
-	.mask_irq =	superio_mask_irq,
-	.unmask_irq =	superio_unmask_irq
+static struct hw_interrupt_type superio_interrupt_type = {
+	.typename =	"SuperIO",
+	.startup =	superio_startup_irq,
+	.shutdown =	superio_disable_irq,
+	.enable =	superio_enable_irq,
+	.disable =	superio_disable_irq,
+	.ack =		no_ack_irq,
+	.end =		no_end_irq,
 };
 
 #ifdef DEBUG_SUPERIO_INIT
@@ -345,7 +334,7 @@
 
 int superio_fixup_irq(struct pci_dev *pcidev)
 {
-	int local_irq;
+	int local_irq, i;
 
 #ifdef DEBUG_SUPERIO_INIT
 	int fn;
@@ -362,15 +351,8 @@
 		__builtin_return_address(0));
 #endif
 
-	if (!sio_dev.irq_region) {
-		/* Allocate an irq region for SuperIO devices */
-		sio_dev.irq_region = alloc_irq_region(SUPERIO_NIRQS,
-						&superio_irq_ops,
-						"SuperIO", (void *) &sio_dev);
-		if (!sio_dev.irq_region) {
-			printk(KERN_WARNING "SuperIO: alloc_irq_region failed\n");
-			return -1;
-		}
+	for (i = 0; i < 16; i++) {
+		irq_desc[i].handler = &superio_interrupt_type;
 	}
 
 	/*
@@ -396,7 +378,7 @@
 		break;
 	}
 
-	return(sio_dev.irq_region->data.irqbase + local_irq);
+	return local_irq;
 }
 
 static struct uart_port serial[] = {
@@ -416,25 +398,13 @@
 	}
 };
 
-void __devinit
-superio_serial_init(void)
+static void __devinit superio_serial_init(void)
 {
 #ifdef CONFIG_SERIAL_8250
 	int retval;
-#ifdef CONFIG_SERIAL_8250_CONSOLE
-	extern void serial8250_console_init(void); /* drivers/serial/8250.c */
-#endif        
         
-	if (!sio_dev.irq_region)
-		return; /* superio not present */
-
-	if (!serial) {
-		printk(KERN_WARNING "SuperIO: Could not get memory for serial struct.\n");
-		return;
-	}
-
 	serial[0].iobase = sio_dev.sp1_base;
-	serial[0].irq = sio_dev.irq_region->data.irqbase + SP1_IRQ;
+	serial[0].irq = SP1_IRQ;
 
 	retval = early_serial_setup(&serial[0]);
 	if (retval < 0) {
@@ -442,12 +412,8 @@
 		return;
 	}
 
-#ifdef CONFIG_SERIAL_8250_CONSOLE
-	serial8250_console_init();
-#endif
-        
 	serial[1].iobase = sio_dev.sp2_base;
-	serial[1].irq = sio_dev.irq_region->data.irqbase + SP2_IRQ;
+	serial[1].irq = SP2_IRQ;
 	retval = early_serial_setup(&serial[1]);
 
 	if (retval < 0)
@@ -456,13 +422,12 @@
 }
 
 
-static void __devinit
-superio_parport_init(void)
+static void __devinit superio_parport_init(void)
 {
 #ifdef CONFIG_PARPORT_PC
 	if (!parport_pc_probe_port(sio_dev.pp_base,
 			0 /*base_hi*/,
-			sio_dev.irq_region->data.irqbase + PAR_IRQ, 
+			PAR_IRQ, 
 			PARPORT_DMA_NONE /* dma */,
 			NULL /*struct pci_dev* */) )
 
@@ -471,7 +436,7 @@
 }
 
 
-void superio_fixup_pci(struct pci_dev *pdev)
+static void superio_fixup_pci(struct pci_dev *pdev)
 {
 	u8 prog;
 
diff -Nru a/drivers/parisc/wax.c b/drivers/parisc/wax.c
--- a/drivers/parisc/wax.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/parisc/wax.c	2005-03-01 23:39:08 -08:00
@@ -21,28 +21,28 @@
 
 #include <asm/io.h>
 #include <asm/hardware.h>
-#include <asm/irq.h>
 
 #include "gsc.h"
 
 #define WAX_GSC_IRQ	7	/* Hardcoded Interrupt for GSC */
 #define WAX_GSC_NMI_IRQ	29
 
-static int wax_choose_irq(struct parisc_device *dev)
+static void wax_choose_irq(struct parisc_device *dev, void *ctrl)
 {
-	int irq = -1;
+	int irq;
 
 	switch (dev->id.sversion) {
-		case 0x73:	irq = 30; break; /* HIL */
-		case 0x8c:	irq = 25; break; /* RS232 */
-		case 0x90:	irq = 21; break; /* WAX EISA BA */
+		case 0x73:	irq =  1; break; /* HIL */
+		case 0x8c:	irq =  6; break; /* RS232 */
+		case 0x90:	irq = 10; break; /* WAX EISA BA */
+		default:	return;		 /* Unknown */
 	}
 
-	return irq;
+	gsc_asic_assign_irq(ctrl, irq, &dev->irq);
 }
 
 static void __init
-wax_init_irq(struct busdevice *wax)
+wax_init_irq(struct gsc_asic *wax)
 {
 	unsigned long base = wax->hpa;
 
@@ -50,7 +50,7 @@
 	gsc_writel(0x00000000, base+OFFSET_IMR);
 
 	/* clear pending interrupts */
-	(volatile u32) gsc_readl(base+OFFSET_IRR);
+	gsc_readl(base+OFFSET_IRR);
 
 	/* We're not really convinced we want to reset the onboard
          * devices. Firmware does it for us...
@@ -69,11 +69,12 @@
 int __init
 wax_init_chip(struct parisc_device *dev)
 {
-	struct busdevice *wax;
+	struct gsc_asic *wax;
+	struct parisc_device *parent;
 	struct gsc_irq gsc_irq;
-	int irq, ret;
+	int ret;
 
-	wax = kmalloc(sizeof(struct busdevice), GFP_KERNEL);
+	wax = kmalloc(sizeof(*wax), GFP_KERNEL);
 	if (!wax)
 		return -ENOMEM;
 
@@ -87,40 +88,37 @@
 	wax_init_irq(wax);
 
 	/* the IRQ wax should use */
-	irq = gsc_claim_irq(&gsc_irq, WAX_GSC_IRQ);
-	if (irq < 0) {
+	dev->irq = gsc_claim_irq(&gsc_irq, WAX_GSC_IRQ);
+	if (dev->irq < 0) {
 		printk(KERN_ERR "%s(): cannot get GSC irq\n",
 				__FUNCTION__);
 		kfree(wax);
 		return -EBUSY;
 	}
 
-	ret = request_irq(gsc_irq.irq, busdev_barked, 0, "wax", wax);
+	wax->eim = ((u32) gsc_irq.txn_addr) | gsc_irq.txn_data;
+
+	ret = request_irq(gsc_irq.irq, gsc_asic_intr, 0, "wax", wax);
 	if (ret < 0) {
 		kfree(wax);
 		return ret;
 	}
 
-	/* Save this for debugging later */
-	wax->parent_irq = gsc_irq.irq;
-	wax->eim = ((u32) gsc_irq.txn_addr) | gsc_irq.txn_data;
-
 	/* enable IRQ's for devices below WAX */
 	gsc_writel(wax->eim, wax->hpa + OFFSET_IAR);
 
 	/* Done init'ing, register this driver */
-	ret = gsc_common_irqsetup(dev, wax);
+	ret = gsc_common_setup(dev, wax);
 	if (ret) {
 		kfree(wax);
 		return ret;
 	}
 
-	fixup_child_irqs(dev, wax->busdev_region->data.irqbase,
-			wax_choose_irq);
+	gsc_fixup_irqs(dev, wax, wax_choose_irq);
 	/* On 715-class machines, Wax EISA is a sibling of Wax, not a child. */
-	if (dev->parent->id.hw_type != HPHW_IOA) {
-		fixup_child_irqs(dev->parent, wax->busdev_region->data.irqbase,
-				wax_choose_irq);
+	parent = parisc_parent(dev);
+	if (parent->id.hw_type != HPHW_IOA) {
+		gsc_fixup_irqs(parent, wax, wax_choose_irq);
 	}
 
 	return ret;
diff -Nru a/drivers/parport/Kconfig b/drivers/parport/Kconfig
--- a/drivers/parport/Kconfig	2005-03-01 23:39:17 -08:00
+++ b/drivers/parport/Kconfig	2005-03-01 23:39:17 -08:00
@@ -83,7 +83,7 @@
 
 config PARPORT_PC_PCMCIA
 	tristate "Support for PCMCIA management for PC-style ports"
-	depends on PARPORT!=n && HOTPLUG && (PCMCIA!=n && PARPORT_PC=m && PARPORT_PC || PARPORT_PC=y && PCMCIA)
+	depends on PARPORT!=n && (PCMCIA!=n && PARPORT_PC=m && PARPORT_PC || PARPORT_PC=y && PCMCIA)
 	help
 	  Say Y here if you need PCMCIA support for your PC-style parallel
 	  ports. If unsure, say N.
diff -Nru a/drivers/parport/daisy.c b/drivers/parport/daisy.c
--- a/drivers/parport/daisy.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/parport/daisy.c	2005-03-01 23:38:54 -08:00
@@ -41,7 +41,7 @@
 	int daisy;
 	int devnum;
 } *topology = NULL;
-static spinlock_t topology_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(topology_lock);
 
 static int numdevs = 0;
 
diff -Nru a/drivers/parport/parport_cs.c b/drivers/parport/parport_cs.c
--- a/drivers/parport/parport_cs.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/parport/parport_cs.c	2005-03-01 23:39:17 -08:00
@@ -64,12 +64,7 @@
 MODULE_DESCRIPTION("PCMCIA parallel port card driver");
 MODULE_LICENSE("Dual MPL/GPL");
 
-#define INT_MODULE_PARM(n, v) static int n = v; MODULE_PARM(n, "i")
-
-/* Bit map of interrupts to choose from */
-INT_MODULE_PARM(irq_mask, 0xdeb8);
-static int irq_list[4] = { -1 };
-MODULE_PARM(irq_list, "1-4i");
+#define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0)
 
 INT_MODULE_PARM(epp_mode, 1);
 
@@ -116,7 +111,7 @@
     parport_info_t *info;
     dev_link_t *link;
     client_reg_t client_reg;
-    int i, ret;
+    int ret;
     
     DEBUG(0, "parport_attach()\n");
 
@@ -129,12 +124,7 @@
     link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
     link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
     link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
-    link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
-    if (irq_list[0] == -1)
-	link->irq.IRQInfo2 = irq_mask;
-    else
-	for (i = 0; i < 4; i++)
-	    link->irq.IRQInfo2 |= 1 << irq_list[i];
+    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.Vcc = 50;
     link->conf.IntType = INT_MEMORY_AND_IO;
@@ -143,7 +133,6 @@
     link->next = dev_list;
     dev_list = link;
     client_reg.dev_info = &dev_info;
-    client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
     client_reg.EventMask =
 	CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
 	CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
@@ -401,10 +390,7 @@
 static void __exit exit_parport_cs(void)
 {
 	pcmcia_unregister_driver(&parport_cs_driver);
-
-	/* XXX: this really needs to move into generic code.. */
-	while (dev_list != NULL)
-		parport_detach(dev_list);
+	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_parport_cs);
diff -Nru a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c
--- a/drivers/parport/parport_pc.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/parport/parport_pc.c	2005-03-01 23:39:17 -08:00
@@ -193,6 +193,7 @@
 
 #ifdef CONFIG_PARPORT_1284
 /* Find FIFO lossage; FIFO is reset */
+#if 0
 static int get_fifo_residue (struct parport *p)
 {
 	int residue;
@@ -233,6 +234,7 @@
 	DPRINTK (KERN_DEBUG "*** get_fifo_residue: done residue collecting (ecr = 0x%2.2x)\n", inb (ECONTROL (p)));
 	return residue;
 }
+#endif  /*  0 */
 #endif /* IEEE 1284 support */
 #endif /* FIFO support */
 
@@ -273,7 +275,7 @@
 	return IRQ_HANDLED;
 }
 
-void parport_pc_init_state(struct pardevice *dev, struct parport_state *s)
+static void parport_pc_init_state(struct pardevice *dev, struct parport_state *s)
 {
 	s->u.pc.ctr = 0xc;
 	if (dev->irq_func &&
@@ -285,7 +287,7 @@
 			     * D.Gruszka VScom */
 }
 
-void parport_pc_save_state(struct parport *p, struct parport_state *s)
+static void parport_pc_save_state(struct parport *p, struct parport_state *s)
 {
 	const struct parport_pc_private *priv = p->physport->private_data;
 	s->u.pc.ctr = priv->ctr;
@@ -293,7 +295,7 @@
 		s->u.pc.ecr = inb (ECONTROL (p));
 }
 
-void parport_pc_restore_state(struct parport *p, struct parport_state *s)
+static void parport_pc_restore_state(struct parport *p, struct parport_state *s)
 {
 	struct parport_pc_private *priv = p->physport->private_data;
 	register unsigned char c = s->u.pc.ctr & priv->ctr_writable;
@@ -732,9 +734,9 @@
 }
 
 /* Parallel Port FIFO mode (ECP chipsets) */
-size_t parport_pc_compat_write_block_pio (struct parport *port,
-					  const void *buf, size_t length,
-					  int flags)
+static size_t parport_pc_compat_write_block_pio (struct parport *port,
+						 const void *buf, size_t length,
+						 int flags)
 {
 	size_t written;
 	int r;
@@ -809,9 +811,9 @@
 
 /* ECP */
 #ifdef CONFIG_PARPORT_1284
-size_t parport_pc_ecp_write_block_pio (struct parport *port,
-				       const void *buf, size_t length,
-				       int flags)
+static size_t parport_pc_ecp_write_block_pio (struct parport *port,
+					      const void *buf, size_t length,
+					      int flags)
 {
 	size_t written;
 	int r;
@@ -924,8 +926,10 @@
 	return written;
 }
 
-size_t parport_pc_ecp_read_block_pio (struct parport *port,
-				      void *buf, size_t length, int flags)
+#if 0
+static size_t parport_pc_ecp_read_block_pio (struct parport *port,
+					     void *buf, size_t length,
+					     int flags)
 {
 	size_t left = length;
 	size_t fifofull;
@@ -1143,7 +1147,7 @@
 dump_parport_state ("fwd idle", port);
 	return length - left;
 }
-
+#endif  /*  0  */
 #endif /* IEEE 1284 support */
 #endif /* Allowed to use FIFO/DMA */
 
@@ -1156,7 +1160,7 @@
 
 /* GCC is not inlining extern inline function later overwriten to non-inline,
    so we use outlined_ variants here.  */
-struct parport_operations parport_pc_ops = 
+static struct parport_operations parport_pc_ops =
 {
 	.write_data	= parport_pc_write_data,
 	.read_data	= parport_pc_read_data,
@@ -2126,7 +2130,7 @@
 /* --- Initialisation code -------------------------------- */
 
 static LIST_HEAD(ports_list);
-static spinlock_t ports_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(ports_lock);
 
 struct parport *parport_pc_probe_port (unsigned long int base,
 				       unsigned long int base_hi,
@@ -2484,7 +2488,7 @@
 
 /* VIA 8231 support by Pavel Fedin <sonic_amiga@rambler.ru>
    based on VIA 686a support code by Jeff Garzik <jgarzik@pobox.com> */
-static int __initdata parport_init_mode = 0;
+static int __devinitdata parport_init_mode = 0;
 
 /* Data for two known VIA chips */
 static struct parport_pc_via_data via_686a_data __devinitdata = {
@@ -3176,7 +3180,6 @@
 #ifdef MODULE
 static const char *irq[PARPORT_PC_MAX_PORTS];
 static const char *dma[PARPORT_PC_MAX_PORTS];
-static char *init_mode;
 
 MODULE_PARM_DESC(io, "Base I/O address (SPP regs)");
 module_param_array(io, int, NULL, 0);
@@ -3192,8 +3195,9 @@
 module_param(verbose_probing, int, 0644);
 #endif
 #ifdef CONFIG_PCI
+static char *init_mode;
 MODULE_PARM_DESC(init_mode, "Initialise mode for VIA VT8231 port (spp, ps2, epp, ecp or ecpepp)");
-MODULE_PARM(init_mode, "s");
+module_param(init_mode, charp, 0);
 #endif
 
 static int __init parse_parport_params(void)
diff -Nru a/drivers/parport/probe.c b/drivers/parport/probe.c
--- a/drivers/parport/probe.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/parport/probe.c	2005-03-01 23:38:54 -08:00
@@ -164,8 +164,16 @@
 		if (retval != 2) goto end_id;
 
 		idlen = (length[0] << 8) + length[1] - 2;
-		if (idlen < len)
+		/*
+		 * Check if the caller-allocated buffer is large enough
+		 * otherwise bail out or there will be an at least off by one.
+		 */
+		if (idlen + 1 < len)
 			len = idlen;
+		else {
+			retval = -EINVAL;
+			goto out;
+		}
 		retval = parport_read (dev->port, buffer, len);
 
 		if (retval != len)
@@ -205,11 +213,12 @@
 		buffer[len] = '\0';
 		parport_negotiate (dev->port, IEEE1284_MODE_COMPAT);
 	}
-	parport_release (dev);
 
 	if (retval > 2)
 		parse_data (dev->port, dev->daisy, buffer);
 
+out:
+	parport_release (dev);
 	parport_close (dev);
 	return retval;
 }
diff -Nru a/drivers/parport/share.c b/drivers/parport/share.c
--- a/drivers/parport/share.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/parport/share.c	2005-03-01 23:38:57 -08:00
@@ -42,11 +42,11 @@
 int parport_default_spintime =  DEFAULT_SPIN_TIME;
 
 static LIST_HEAD(portlist);
-static spinlock_t parportlist_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(parportlist_lock);
 
 /* list of all allocated ports, sorted by ->number */
 static LIST_HEAD(all_ports);
-static spinlock_t full_list_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(full_list_lock);
 
 static LIST_HEAD(drivers);
 
@@ -306,7 +306,7 @@
 	tmp->ops = ops;
 	tmp->physport = tmp;
 	memset (tmp->probe_info, 0, 5 * sizeof (struct parport_device_info));
-	tmp->cad_lock = RW_LOCK_UNLOCKED;
+	rwlock_init(&tmp->cad_lock);
 	spin_lock_init(&tmp->waitlist_lock);
 	spin_lock_init(&tmp->pardevice_lock);
 	tmp->ieee1284.mode = IEEE1284_MODE_COMPAT;
diff -Nru a/drivers/pci/Kconfig b/drivers/pci/Kconfig
--- a/drivers/pci/Kconfig	2005-03-01 23:38:54 -08:00
+++ b/drivers/pci/Kconfig	2005-03-01 23:38:54 -08:00
@@ -25,7 +25,7 @@
 
 	  lspci can provide the same data, as well as much more. lspci is a part of
 	  the pci-utils package, which should be installed by your distribution. 
-	  See Documentation/Changes for information on where to get the latest 
+	  See <file:Documentation/Changes> for information on where to get the latest
 	  version. 
 
 	  When in doubt, say N.
diff -Nru a/drivers/pci/Makefile b/drivers/pci/Makefile
--- a/drivers/pci/Makefile	2005-03-01 23:39:16 -08:00
+++ b/drivers/pci/Makefile	2005-03-01 23:39:16 -08:00
@@ -56,4 +56,6 @@
 # Files generated that shall be removed upon make clean
 clean-files := devlist.h classlist.h
 
+# Build PCI Express stuff if needed
+obj-$(CONFIG_PCIEPORTBUS) += pcie/
 
diff -Nru a/drivers/pci/access.c b/drivers/pci/access.c
--- a/drivers/pci/access.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/pci/access.c	2005-03-01 23:39:17 -08:00
@@ -7,7 +7,7 @@
  * configuration space.
  */
 
-static spinlock_t pci_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(pci_lock);
 
 /*
  *  Wrappers for all PCI configuration access functions.  They just check
diff -Nru a/drivers/pci/hotplug/Kconfig b/drivers/pci/hotplug/Kconfig
--- a/drivers/pci/hotplug/Kconfig	2005-03-01 23:39:18 -08:00
+++ b/drivers/pci/hotplug/Kconfig	2005-03-01 23:39:18 -08:00
@@ -3,11 +3,11 @@
 #
 
 menu "PCI Hotplug Support"
-	depends on HOTPLUG
 
 config HOTPLUG_PCI
 	tristate "Support for PCI Hotplug (EXPERIMENTAL)"
 	depends on PCI && EXPERIMENTAL
+	select HOTPLUG
 	---help---
 	  Say Y here if you have a motherboard with a PCI Hotplug controller.
 	  This allows you to add and remove PCI cards while the machine is
@@ -132,27 +132,6 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called cpcihp_generic.
 
-	  When in doubt, say N.
-
-config HOTPLUG_PCI_PCIE
-	tristate "PCI Express Hotplug driver"
-	depends on HOTPLUG_PCI
-	help
-	  Say Y here if you have a motherboard that supports PCI Express Native
-	  Hotplug
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called pciehp.
-
-	  When in doubt, say N.
-
-config HOTPLUG_PCI_PCIE_POLL_EVENT_MODE
-	bool "Use polling mechanism for hot-plug events (for testing purpose)"
-	depends on HOTPLUG_PCI_PCIE
-	help
-	  Say Y here if you want to use the polling mechanism for hot-plug 
-	  events for early platform testing.
-	   
 	  When in doubt, say N.
 
 config HOTPLUG_PCI_SHPC
diff -Nru a/drivers/pci/hotplug/acpiphp_ibm.c b/drivers/pci/hotplug/acpiphp_ibm.c
--- a/drivers/pci/hotplug/acpiphp_ibm.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/pci/hotplug/acpiphp_ibm.c	2005-03-01 23:39:09 -08:00
@@ -47,7 +47,7 @@
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRIVER_VERSION);
-module_param(debug, bool, 644);
+module_param(debug, bool, 0644);
 MODULE_PARM_DESC(debug, " Debugging mode enabled or not");
 #define MY_NAME "acpiphp_ibm"
 
diff -Nru a/drivers/pci/hotplug/cpci_hotplug_pci.c b/drivers/pci/hotplug/cpci_hotplug_pci.c
--- a/drivers/pci/hotplug/cpci_hotplug_pci.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/pci/hotplug/cpci_hotplug_pci.c	2005-03-01 23:39:07 -08:00
@@ -32,7 +32,7 @@
 #include "pci_hotplug.h"
 #include "cpci_hotplug.h"
 
-#if !defined(CONFIG_HOTPLUG_CPCI_MODULE)
+#if !defined(MODULE)
 #define MY_NAME	"cpci_hotplug"
 #else
 #define MY_NAME	THIS_MODULE->name
diff -Nru a/drivers/pci/hotplug/cpcihp_generic.c b/drivers/pci/hotplug/cpcihp_generic.c
--- a/drivers/pci/hotplug/cpcihp_generic.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/pci/hotplug/cpcihp_generic.c	2005-03-01 23:38:57 -08:00
@@ -45,7 +45,7 @@
 #define DRIVER_AUTHOR	"Scott Murray <scottm@somanetworks.com>"
 #define DRIVER_DESC	"Generic port I/O CompactPCI Hot Plug Driver"
 
-#if !defined(CONFIG_HOTPLUG_CPCI_GENERIC_MODULE)
+#if !defined(MODULE)
 #define MY_NAME	"cpcihp_generic"
 #else
 #define MY_NAME	THIS_MODULE->name
diff -Nru a/drivers/pci/hotplug/cpqphp_pci.c b/drivers/pci/hotplug/cpqphp_pci.c
--- a/drivers/pci/hotplug/cpqphp_pci.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/pci/hotplug/cpqphp_pci.c	2005-03-01 23:39:16 -08:00
@@ -151,18 +151,29 @@
  */
 int cpqhp_set_irq (u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num)
 {
-	int rc;
-	u16 temp_word;
-	struct pci_dev fakedev;
-	struct pci_bus fakebus;
+	int rc = 0;
 
 	if (cpqhp_legacy_mode) {
-		fakedev.devfn = dev_num << 3;
-		fakedev.bus = &fakebus;
-		fakebus.number = bus_num;
+		struct pci_dev *fakedev;
+		struct pci_bus *fakebus;
+		u16 temp_word;
+
+		fakedev = kmalloc(sizeof(*fakedev), GFP_KERNEL);
+		fakebus = kmalloc(sizeof(*fakebus), GFP_KERNEL);
+		if (!fakedev || !fakebus) {
+			kfree(fakedev);
+			kfree(fakebus);
+			return -ENOMEM;
+		}
+
+		fakedev->devfn = dev_num << 3;
+		fakedev->bus = fakebus;
+		fakebus->number = bus_num;
 		dbg("%s: dev %d, bus %d, pin %d, num %d\n",
 		    __FUNCTION__, dev_num, bus_num, int_pin, irq_num);
-		rc = pcibios_set_irq_routing(&fakedev, int_pin - 0x0a, irq_num);
+		rc = pcibios_set_irq_routing(fakedev, int_pin - 0x0a, irq_num);
+		kfree(fakedev);
+		kfree(fakebus);
 		dbg("%s: rc %d\n", __FUNCTION__, rc);
 		if (!rc)
 			return !rc;
@@ -176,9 +187,10 @@
 		// This should only be for x86 as it sets the Edge Level Control Register
 		outb((u8) (temp_word & 0xFF), 0x4d0);
 		outb((u8) ((temp_word & 0xFF00) >> 8), 0x4d1);
+		rc = 0;
 	}
 
-	return 0;
+	return rc;
 }
 
 
diff -Nru a/drivers/pci/hotplug/fakephp.c b/drivers/pci/hotplug/fakephp.c
--- a/drivers/pci/hotplug/fakephp.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/pci/hotplug/fakephp.c	2005-03-01 23:39:07 -08:00
@@ -40,7 +40,7 @@
 #include "pci_hotplug.h"
 #include "../pci.h"
 
-#if !defined(CONFIG_HOTPLUG_PCI_FAKE_MODULE)
+#if !defined(MODULE)
 	#define MY_NAME	"fakephp"
 #else
 	#define MY_NAME	THIS_MODULE->name
diff -Nru a/drivers/pci/hotplug/ibmphp.h b/drivers/pci/hotplug/ibmphp.h
--- a/drivers/pci/hotplug/ibmphp.h	2005-03-01 23:38:52 -08:00
+++ b/drivers/pci/hotplug/ibmphp.h	2005-03-01 23:38:52 -08:00
@@ -34,7 +34,7 @@
 
 extern int ibmphp_debug;
 
-#if !defined(CONFIG_HOTPLUG_PCI_IBM_MODULE)
+#if !defined(MODULE)
 	#define MY_NAME "ibmphpd"
 #else
 	#define MY_NAME THIS_MODULE->name
diff -Nru a/drivers/pci/hotplug/ibmphp_core.c b/drivers/pci/hotplug/ibmphp_core.c
--- a/drivers/pci/hotplug/ibmphp_core.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/pci/hotplug/ibmphp_core.c	2005-03-01 23:39:18 -08:00
@@ -59,7 +59,8 @@
 struct pci_bus *ibmphp_pci_bus;
 static int max_slots;
 
-static int irqs[16];    /* PIC mode IRQ's we're using so far (in case MPS tables don't provide default info for empty slots */
+static int irqs[16];    /* PIC mode IRQ's we're using so far (in case MPS
+			 * tables don't provide default info for empty slots */
 
 static int init_flag;
 
@@ -71,36 +72,40 @@
 	return get_max_adapter_speed_1 (hs, value, 1);
 }
 */
-static inline int get_cur_bus_info (struct slot **sl) 
+static inline int get_cur_bus_info(struct slot **sl) 
 {
 	int rc = 1;
 	struct slot * slot_cur = *sl;
 
-	debug ("options = %x\n", slot_cur->ctrl->options);
-	debug ("revision = %x\n", slot_cur->ctrl->revision);	
+	debug("options = %x\n", slot_cur->ctrl->options);
+	debug("revision = %x\n", slot_cur->ctrl->revision);	
 
-	if (READ_BUS_STATUS (slot_cur->ctrl)) 
-		rc = ibmphp_hpc_readslot (slot_cur, READ_BUSSTATUS, NULL);
+	if (READ_BUS_STATUS(slot_cur->ctrl)) 
+		rc = ibmphp_hpc_readslot(slot_cur, READ_BUSSTATUS, NULL);
 	
 	if (rc) 
 		return rc;
 	  
-	slot_cur->bus_on->current_speed = CURRENT_BUS_SPEED (slot_cur->busstatus);
-	if (READ_BUS_MODE (slot_cur->ctrl))
-		slot_cur->bus_on->current_bus_mode = CURRENT_BUS_MODE (slot_cur->busstatus);
+	slot_cur->bus_on->current_speed = CURRENT_BUS_SPEED(slot_cur->busstatus);
+	if (READ_BUS_MODE(slot_cur->ctrl))
+		slot_cur->bus_on->current_bus_mode =
+				CURRENT_BUS_MODE(slot_cur->busstatus);
 	else
 		slot_cur->bus_on->current_bus_mode = 0xFF;
 
-	debug ("busstatus = %x, bus_speed = %x, bus_mode = %x\n", slot_cur->busstatus, slot_cur->bus_on->current_speed, slot_cur->bus_on->current_bus_mode);
+	debug("busstatus = %x, bus_speed = %x, bus_mode = %x\n",
+			slot_cur->busstatus,
+			slot_cur->bus_on->current_speed,
+			slot_cur->bus_on->current_bus_mode);
 	
 	*sl = slot_cur;
 	return 0;
 }
 
-static inline int slot_update (struct slot **sl)
+static inline int slot_update(struct slot **sl)
 {
 	int rc;
- 	rc = ibmphp_hpc_readslot (*sl, READ_ALLSTAT, NULL);
+ 	rc = ibmphp_hpc_readslot(*sl, READ_ALLSTAT, NULL);
 	if (rc) 
 		return rc;
 	if (!init_flag)
@@ -114,10 +119,10 @@
 	struct list_head * tmp;
 	u8 slot_count = 0;
 
-	list_for_each (tmp, &ibmphp_slot_head) {
-		slot_cur = list_entry (tmp, struct slot, ibm_slot_list);
+	list_for_each(tmp, &ibmphp_slot_head) {
+		slot_cur = list_entry(tmp, struct slot, ibm_slot_list);
 		/* sometimes the hot-pluggable slots start with 4 (not always from 1) */
-		slot_count = max (slot_count, slot_cur->number);
+		slot_count = max(slot_count, slot_cur->number);
 	}
 	return slot_count;
 }
@@ -128,46 +133,61 @@
  * Parameters: struct slot
  * Returns 0 or errors
  */
-int ibmphp_init_devno (struct slot **cur_slot)
+int ibmphp_init_devno(struct slot **cur_slot)
 {
 	struct irq_routing_table *rtable;
 	int len;
 	int loop;
 	int i;
 
-	rtable = pcibios_get_irq_routing_table ();
+	rtable = pcibios_get_irq_routing_table();
 	if (!rtable) {
-		err ("no BIOS routing table...\n");
+		err("no BIOS routing table...\n");
 		return -ENOMEM;
 	}
 
-	len = (rtable->size - sizeof (struct irq_routing_table)) / sizeof (struct irq_info);
+	len = (rtable->size - sizeof(struct irq_routing_table)) /
+			sizeof(struct irq_info);
 
 	if (!len)
 		return -1;
 	for (loop = 0; loop < len; loop++) {
 		if ((*cur_slot)->number == rtable->slots[loop].slot) {
 		if ((*cur_slot)->bus == rtable->slots[loop].bus) {
-			(*cur_slot)->device = PCI_SLOT (rtable->slots[loop].devfn);
+			(*cur_slot)->device = PCI_SLOT(rtable->slots[loop].devfn);
 			for (i = 0; i < 4; i++)
-				(*cur_slot)->irq[i] = IO_APIC_get_PCI_irq_vector ((int) (*cur_slot)->bus, (int) (*cur_slot)->device, i);
+				(*cur_slot)->irq[i] = IO_APIC_get_PCI_irq_vector((int) (*cur_slot)->bus,
+						(int) (*cur_slot)->device, i);
 
-				debug ("(*cur_slot)->irq[0] = %x\n", (*cur_slot)->irq[0]);
-				debug ("(*cur_slot)->irq[1] = %x\n", (*cur_slot)->irq[1]);
-				debug ("(*cur_slot)->irq[2] = %x\n", (*cur_slot)->irq[2]);
-				debug ("(*cur_slot)->irq[3] = %x\n", (*cur_slot)->irq[3]);
-
-				debug ("rtable->exlusive_irqs = %x\n", rtable->exclusive_irqs);
-				debug ("rtable->slots[loop].irq[0].bitmap = %x\n", rtable->slots[loop].irq[0].bitmap);
-				debug ("rtable->slots[loop].irq[1].bitmap = %x\n", rtable->slots[loop].irq[1].bitmap);
-				debug ("rtable->slots[loop].irq[2].bitmap = %x\n", rtable->slots[loop].irq[2].bitmap);
-				debug ("rtable->slots[loop].irq[3].bitmap = %x\n", rtable->slots[loop].irq[3].bitmap);
-
-				debug ("rtable->slots[loop].irq[0].link= %x\n", rtable->slots[loop].irq[0].link);
-				debug ("rtable->slots[loop].irq[1].link = %x\n", rtable->slots[loop].irq[1].link);
-				debug ("rtable->slots[loop].irq[2].link = %x\n", rtable->slots[loop].irq[2].link);
-				debug ("rtable->slots[loop].irq[3].link = %x\n", rtable->slots[loop].irq[3].link);
-				debug ("end of init_devno\n");
+				debug("(*cur_slot)->irq[0] = %x\n",
+						(*cur_slot)->irq[0]);
+				debug("(*cur_slot)->irq[1] = %x\n",
+						(*cur_slot)->irq[1]);
+				debug("(*cur_slot)->irq[2] = %x\n",
+						(*cur_slot)->irq[2]);
+				debug("(*cur_slot)->irq[3] = %x\n",
+						(*cur_slot)->irq[3]);
+
+				debug("rtable->exlusive_irqs = %x\n",
+					rtable->exclusive_irqs);
+				debug("rtable->slots[loop].irq[0].bitmap = %x\n",
+					rtable->slots[loop].irq[0].bitmap);
+				debug("rtable->slots[loop].irq[1].bitmap = %x\n",
+					rtable->slots[loop].irq[1].bitmap);
+				debug("rtable->slots[loop].irq[2].bitmap = %x\n",
+					rtable->slots[loop].irq[2].bitmap);
+				debug("rtable->slots[loop].irq[3].bitmap = %x\n",
+					rtable->slots[loop].irq[3].bitmap);
+
+				debug("rtable->slots[loop].irq[0].link = %x\n",
+					rtable->slots[loop].irq[0].link);
+				debug("rtable->slots[loop].irq[1].link = %x\n",
+					rtable->slots[loop].irq[1].link);
+				debug("rtable->slots[loop].irq[2].link = %x\n",
+					rtable->slots[loop].irq[2].link);
+				debug("rtable->slots[loop].irq[3].link = %x\n",
+					rtable->slots[loop].irq[3].link);
+				debug("end of init_devno\n");
 				return 0;
 			}
 		}
@@ -176,49 +196,50 @@
 	return -1;
 }
 
-static inline int power_on (struct slot *slot_cur)
+static inline int power_on(struct slot *slot_cur)
 {
 	u8 cmd = HPC_SLOT_ON;
 	int retval;
 
-	retval = ibmphp_hpc_writeslot (slot_cur, cmd);
+	retval = ibmphp_hpc_writeslot(slot_cur, cmd);
 	if (retval) {
-		err ("power on failed\n");
+		err("power on failed\n");
 		return retval;
 	}
-	if (CTLR_RESULT (slot_cur->ctrl->status)) {
-		err ("command not completed successfully in power_on\n");
+	if (CTLR_RESULT(slot_cur->ctrl->status)) {
+		err("command not completed successfully in power_on\n");
 		return -EIO;
 	}
 	msleep(3000);	/* For ServeRAID cards, and some 66 PCI */
 	return 0;
 }
 
-static inline int power_off (struct slot *slot_cur)
+static inline int power_off(struct slot *slot_cur)
 {
 	u8 cmd = HPC_SLOT_OFF;
 	int retval;
 
-	retval = ibmphp_hpc_writeslot (slot_cur, cmd);
+	retval = ibmphp_hpc_writeslot(slot_cur, cmd);
 	if (retval) {
-		err ("power off failed\n");
+		err("power off failed\n");
 		return retval;
 	}
-	if (CTLR_RESULT (slot_cur->ctrl->status)) {
-		err ("command not completed successfully in power_off\n");
+	if (CTLR_RESULT(slot_cur->ctrl->status)) {
+		err("command not completed successfully in power_off\n");
 		retval = -EIO;
 	}
 	return retval;
 }
 
-static int set_attention_status (struct hotplug_slot *hotplug_slot, u8 value)
+static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 value)
 {
 	int rc = 0;
 	struct slot *pslot;
 	u8 cmd;
 
-	debug ("set_attention_status - Entry hotplug_slot[%lx] value[%x]\n", (ulong) hotplug_slot, value);
-	ibmphp_lock_operations ();
+	debug("set_attention_status - Entry hotplug_slot[%lx] value[%x]\n",
+			(ulong) hotplug_slot, value);
+	ibmphp_lock_operations();
 	cmd = 0x00;     // avoid compiler warning
 
 	if (hotplug_slot) {
@@ -234,11 +255,12 @@
 			break;
 		default:
 			rc = -ENODEV;
-			err ("set_attention_status - Error : invalid input [%x]\n", value);
+			err("set_attention_status - Error : invalid input [%x]\n",
+					value);
 			break;
 		}
 		if (rc == 0) {
-			pslot = (struct slot *) hotplug_slot->private;
+			pslot = hotplug_slot->private;
 			if (pslot)
 				rc = ibmphp_hpc_writeslot(pslot, cmd);
 			else
@@ -247,101 +269,114 @@
 	} else	
 		rc = -ENODEV;
 
-	ibmphp_unlock_operations ();
+	ibmphp_unlock_operations();
 
-	debug ("set_attention_status - Exit rc[%d]\n", rc);
+	debug("set_attention_status - Exit rc[%d]\n", rc);
 	return rc;
 }
 
-static int get_attention_status (struct hotplug_slot *hotplug_slot, u8 * value)
+static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 * value)
 {
 	int rc = -ENODEV;
 	struct slot *pslot;
 	struct slot myslot;
 
-	debug ("get_attention_status - Entry hotplug_slot[%lx] pvalue[%lx]\n", (ulong) hotplug_slot, (ulong) value);
+	debug("get_attention_status - Entry hotplug_slot[%lx] pvalue[%lx]\n",
+					(ulong) hotplug_slot, (ulong) value);
         
-	ibmphp_lock_operations ();
+	ibmphp_lock_operations();
 	if (hotplug_slot && value) {
-		pslot = (struct slot *) hotplug_slot->private;
+		pslot = hotplug_slot->private;
 		if (pslot) {
-			memcpy ((void *) &myslot, (void *) pslot, sizeof (struct slot));
-			rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS, &(myslot.status));
+			memcpy(&myslot, pslot, sizeof(struct slot));
+			rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS,
+						&(myslot.status));
 			if (!rc)
-				rc = ibmphp_hpc_readslot(pslot, READ_EXTSLOTSTATUS, &(myslot.ext_status));
+				rc = ibmphp_hpc_readslot(pslot,
+						READ_EXTSLOTSTATUS,
+						&(myslot.ext_status));
 			if (!rc)
-				*value = SLOT_ATTN (myslot.status, myslot.ext_status);
+				*value = SLOT_ATTN(myslot.status,
+						myslot.ext_status);
 		}
 	}
 
-	ibmphp_unlock_operations ();
+	ibmphp_unlock_operations();
 	debug("get_attention_status - Exit rc[%d] value[%x]\n", rc, *value);
 	return rc;
 }
 
-static int get_latch_status (struct hotplug_slot *hotplug_slot, u8 * value)
+static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 * value)
 {
 	int rc = -ENODEV;
 	struct slot *pslot;
 	struct slot myslot;
 
-	debug ("get_latch_status - Entry hotplug_slot[%lx] pvalue[%lx]\n", (ulong) hotplug_slot, (ulong) value);
-	ibmphp_lock_operations ();
+	debug("get_latch_status - Entry hotplug_slot[%lx] pvalue[%lx]\n",
+					(ulong) hotplug_slot, (ulong) value);
+	ibmphp_lock_operations();
 	if (hotplug_slot && value) {
-		pslot = (struct slot *) hotplug_slot->private;
+		pslot = hotplug_slot->private;
 		if (pslot) {
-			memcpy ((void *) &myslot, (void *) pslot, sizeof (struct slot));
-			rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS, &(myslot.status));
+			memcpy(&myslot, pslot, sizeof(struct slot));
+			rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS,
+						&(myslot.status));
 			if (!rc)
-				*value = SLOT_LATCH (myslot.status);
+				*value = SLOT_LATCH(myslot.status);
 		}
 	}
 
-	ibmphp_unlock_operations ();
-	debug("get_latch_status - Exit rc[%d] rc[%x] value[%x]\n", rc, rc, *value);
+	ibmphp_unlock_operations();
+	debug("get_latch_status - Exit rc[%d] rc[%x] value[%x]\n",
+			rc, rc, *value);
 	return rc;
 }
 
 
-static int get_power_status (struct hotplug_slot *hotplug_slot, u8 * value)
+static int get_power_status(struct hotplug_slot *hotplug_slot, u8 * value)
 {
 	int rc = -ENODEV;
 	struct slot *pslot;
 	struct slot myslot;
 
-	debug ("get_power_status - Entry hotplug_slot[%lx] pvalue[%lx]\n", (ulong) hotplug_slot, (ulong) value);
-	ibmphp_lock_operations ();
+	debug("get_power_status - Entry hotplug_slot[%lx] pvalue[%lx]\n",
+					(ulong) hotplug_slot, (ulong) value);
+	ibmphp_lock_operations();
 	if (hotplug_slot && value) {
-		pslot = (struct slot *) hotplug_slot->private;
+		pslot = hotplug_slot->private;
 		if (pslot) {
-			memcpy ((void *) &myslot, (void *) pslot, sizeof (struct slot));
-			rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS, &(myslot.status));
+			memcpy(&myslot, pslot, sizeof(struct slot));
+			rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS,
+						&(myslot.status));
 			if (!rc)
-				*value = SLOT_PWRGD (myslot.status);
+				*value = SLOT_PWRGD(myslot.status);
 		}
 	}
 
-	ibmphp_unlock_operations ();
-	debug("get_power_status - Exit rc[%d] rc[%x] value[%x]\n", rc, rc, *value);
+	ibmphp_unlock_operations();
+	debug("get_power_status - Exit rc[%d] rc[%x] value[%x]\n",
+			rc, rc, *value);
 	return rc;
 }
 
-static int get_adapter_present (struct hotplug_slot *hotplug_slot, u8 * value)
+static int get_adapter_present(struct hotplug_slot *hotplug_slot, u8 * value)
 {
 	int rc = -ENODEV;
 	struct slot *pslot;
 	u8 present;
 	struct slot myslot;
 
-	debug ("get_adapter_status - Entry hotplug_slot[%lx] pvalue[%lx]\n", (ulong) hotplug_slot, (ulong) value);
-	ibmphp_lock_operations ();
+	debug("get_adapter_status - Entry hotplug_slot[%lx] pvalue[%lx]\n",
+					(ulong) hotplug_slot, (ulong) value);
+	ibmphp_lock_operations();
 	if (hotplug_slot && value) {
-		pslot = (struct slot *) hotplug_slot->private;
+		pslot = hotplug_slot->private;
 		if (pslot) {
-			memcpy ((void *) &myslot, (void *) pslot, sizeof (struct slot));
-			rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS, &(myslot.status));
+			memcpy(&myslot, pslot, sizeof(struct slot));
+			rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS,
+						&(myslot.status));
 			if (!rc) {
-				present = SLOT_PRESENT (myslot.status);
+				present = SLOT_PRESENT(myslot.status);
 				if (present == HPC_SLOT_EMPTY)
 					*value = 0;
 				else
@@ -350,24 +385,24 @@
 		}
 	}
 
-	ibmphp_unlock_operations ();
+	ibmphp_unlock_operations();
 	debug("get_adapter_present - Exit rc[%d] value[%x]\n", rc, *value);
 	return rc;
 }
 
-static int get_max_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
+static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
 {
 	int rc = -ENODEV;
 	struct slot *pslot;
 	u8 mode = 0;
 
-	debug ("%s - Entry hotplug_slot[%p] pvalue[%p]\n", __FUNCTION__,
+	debug("%s - Entry hotplug_slot[%p] pvalue[%p]\n", __FUNCTION__,
 		hotplug_slot, value);
 
-	ibmphp_lock_operations ();
+	ibmphp_lock_operations();
 
 	if (hotplug_slot && value) {
-		pslot = (struct slot *) hotplug_slot->private;
+		pslot = hotplug_slot->private;
 		if (pslot) {
 			rc = 0;
 			mode = pslot->supported_bus_mode;
@@ -390,26 +425,26 @@
 		}
 	}
 
-	ibmphp_unlock_operations ();
-	debug ("%s - Exit rc[%d] value[%x]\n", __FUNCTION__, rc, *value);
+	ibmphp_unlock_operations();
+	debug("%s - Exit rc[%d] value[%x]\n", __FUNCTION__, rc, *value);
 	return rc;
 }
 
-static int get_cur_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
+static int get_cur_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
 {
 	int rc = -ENODEV;
 	struct slot *pslot;
 	u8 mode = 0;
 
-	debug ("%s - Entry hotplug_slot[%p] pvalue[%p]\n", __FUNCTION__,
+	debug("%s - Entry hotplug_slot[%p] pvalue[%p]\n", __FUNCTION__,
 		hotplug_slot, value);
 
-	ibmphp_lock_operations ();
+	ibmphp_lock_operations();
 
 	if (hotplug_slot && value) {
-		pslot = (struct slot *) hotplug_slot->private;
+		pslot = hotplug_slot->private;
 		if (pslot) {
-			rc = get_cur_bus_info (&pslot);
+			rc = get_cur_bus_info(&pslot);
 			if (!rc) {
 				mode = pslot->bus_on->current_bus_mode;
 				*value = pslot->bus_on->current_speed;
@@ -436,121 +471,129 @@
 		}
 	}
 
-	ibmphp_unlock_operations ();
-	debug ("%s - Exit rc[%d] value[%x]\n", __FUNCTION__, rc, *value);
+	ibmphp_unlock_operations();
+	debug("%s - Exit rc[%d] value[%x]\n", __FUNCTION__, rc, *value);
 	return rc;
 }
+
 /*
-static int get_max_adapter_speed_1 (struct hotplug_slot *hotplug_slot, u8 * value, u8 flag)
+static int get_max_adapter_speed_1(struct hotplug_slot *hotplug_slot, u8 * value, u8 flag)
 {
 	int rc = -ENODEV;
 	struct slot *pslot;
 	struct slot myslot;
 
-	debug ("get_max_adapter_speed_1 - Entry hotplug_slot[%lx] pvalue[%lx]\n", (ulong)hotplug_slot, (ulong) value);
+	debug("get_max_adapter_speed_1 - Entry hotplug_slot[%lx] pvalue[%lx]\n",
+						(ulong)hotplug_slot, (ulong) value);
 
 	if (flag)
-		ibmphp_lock_operations ();
+		ibmphp_lock_operations();
 
 	if (hotplug_slot && value) {
-		pslot = (struct slot *) hotplug_slot->private;
+		pslot = hotplug_slot->private;
 		if (pslot) {
-			memcpy ((void *) &myslot, (void *) pslot, sizeof (struct slot));
-			rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS, &(myslot.status));
-
-			if (!(SLOT_LATCH (myslot.status)) && (SLOT_PRESENT (myslot.status))) {
-				rc = ibmphp_hpc_readslot(pslot, READ_EXTSLOTSTATUS, &(myslot.ext_status));
+			memcpy(&myslot, pslot, sizeof(struct slot));
+			rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS,
+						&(myslot.status));
+
+			if (!(SLOT_LATCH (myslot.status)) &&
+					(SLOT_PRESENT (myslot.status))) {
+				rc = ibmphp_hpc_readslot(pslot,
+						READ_EXTSLOTSTATUS,
+						&(myslot.ext_status));
 				if (!rc)
-					*value = SLOT_SPEED (myslot.ext_status);
+					*value = SLOT_SPEED(myslot.ext_status);
 			} else
 				*value = MAX_ADAPTER_NONE;
                 }
 	}
 
 	if (flag)
-		ibmphp_unlock_operations ();
+		ibmphp_unlock_operations();
 
 	debug("get_max_adapter_speed_1 - Exit rc[%d] value[%x]\n", rc, *value);
 	return rc;
 }
 
-static int get_bus_name (struct hotplug_slot *hotplug_slot, char * value)
+static int get_bus_name(struct hotplug_slot *hotplug_slot, char * value)
 {
 	int rc = -ENODEV;
 	struct slot *pslot = NULL;
 
-	debug ("get_bus_name - Entry hotplug_slot[%lx]\n", (ulong)hotplug_slot);
+	debug("get_bus_name - Entry hotplug_slot[%lx]\n", (ulong)hotplug_slot);
 
-	ibmphp_lock_operations ();
+	ibmphp_lock_operations();
 
 	if (hotplug_slot) {
-		pslot = (struct slot *) hotplug_slot->private;
+		pslot = hotplug_slot->private;
 		if (pslot) {
 			rc = 0;
-			snprintf (value, 100, "Bus %x", pslot->bus);
+			snprintf(value, 100, "Bus %x", pslot->bus);
 		}
 	} else
 		rc = -ENODEV;
 
-	ibmphp_unlock_operations ();
-	debug ("get_bus_name - Exit rc[%d] value[%x]\n", rc, *value);
+	ibmphp_unlock_operations();
+	debug("get_bus_name - Exit rc[%d] value[%x]\n", rc, *value);
 	return rc;
 }
 */
 
-/*******************************************************************************
+/****************************************************************************
  * This routine will initialize the ops data structure used in the validate
  * function. It will also power off empty slots that are powered on since BIOS
  * leaves those on, albeit disconnected
- ******************************************************************************/
-static int __init init_ops (void)
+ ****************************************************************************/
+static int __init init_ops(void)
 {
 	struct slot *slot_cur;
 	struct list_head *tmp;
 	int retval;
 	int rc;
 
-	list_for_each (tmp, &ibmphp_slot_head) {
-		slot_cur = list_entry (tmp, struct slot, ibm_slot_list);
+	list_for_each(tmp, &ibmphp_slot_head) {
+		slot_cur = list_entry(tmp, struct slot, ibm_slot_list);
 
 		if (!slot_cur)
 			return -ENODEV;
 
-		debug ("BEFORE GETTING SLOT STATUS, slot # %x\n", slot_cur->number);
+		debug("BEFORE GETTING SLOT STATUS, slot # %x\n",
+							slot_cur->number);
 		if (slot_cur->ctrl->revision == 0xFF) 
-			if (get_ctrl_revision (slot_cur, &slot_cur->ctrl->revision))
+			if (get_ctrl_revision(slot_cur,
+						&slot_cur->ctrl->revision))
 				return -1;
 
 		if (slot_cur->bus_on->current_speed == 0xFF) 
-			if (get_cur_bus_info (&slot_cur)) 
+			if (get_cur_bus_info(&slot_cur)) 
 				return -1;
 
 		if (slot_cur->ctrl->options == 0xFF)
-			if (get_hpc_options (slot_cur, &slot_cur->ctrl->options))
+			if (get_hpc_options(slot_cur, &slot_cur->ctrl->options))
 				return -1;
 
-		retval = slot_update (&slot_cur);
+		retval = slot_update(&slot_cur);
 		if (retval)
 			return retval;
 
-		debug ("status = %x\n", slot_cur->status);
-		debug ("ext_status = %x\n", slot_cur->ext_status);
-		debug ("SLOT_POWER = %x\n", SLOT_POWER (slot_cur->status));
-		debug ("SLOT_PRESENT = %x\n", SLOT_PRESENT (slot_cur->status));
-		debug ("SLOT_LATCH = %x\n", SLOT_LATCH (slot_cur->status));
-
-		if ((SLOT_PWRGD (slot_cur->status)) && 
-		    !(SLOT_PRESENT (slot_cur->status)) && 
-		    !(SLOT_LATCH (slot_cur->status))) {
-			debug ("BEFORE POWER OFF COMMAND\n");
-				rc = power_off (slot_cur);
+		debug("status = %x\n", slot_cur->status);
+		debug("ext_status = %x\n", slot_cur->ext_status);
+		debug("SLOT_POWER = %x\n", SLOT_POWER(slot_cur->status));
+		debug("SLOT_PRESENT = %x\n", SLOT_PRESENT(slot_cur->status));
+		debug("SLOT_LATCH = %x\n", SLOT_LATCH(slot_cur->status));
+
+		if ((SLOT_PWRGD(slot_cur->status)) && 
+		    !(SLOT_PRESENT(slot_cur->status)) && 
+		    !(SLOT_LATCH(slot_cur->status))) {
+			debug("BEFORE POWER OFF COMMAND\n");
+				rc = power_off(slot_cur);
 				if (rc)
 					return rc;
 
-	/*		retval = slot_update (&slot_cur);
+	/*		retval = slot_update(&slot_cur);
 	 *		if (retval)
 	 *			return retval;
-	 *		ibmphp_update_slot_info (slot_cur);
+	 *		ibmphp_update_slot_info(slot_cur);
 	 */
 		}
 	}
@@ -563,7 +606,7 @@
  * Parameters: slot, operation
  * Returns: 0 or error codes
  */
-static int validate (struct slot *slot_cur, int opn)
+static int validate(struct slot *slot_cur, int opn)
 {
 	int number;
 	int retval;
@@ -573,89 +616,91 @@
 	number = slot_cur->number;
 	if ((number > max_slots) || (number < 0))
 		return -EBADSLT;
-	debug ("slot_number in validate is %d\n", slot_cur->number);
+	debug("slot_number in validate is %d\n", slot_cur->number);
 
-	retval = slot_update (&slot_cur);
+	retval = slot_update(&slot_cur);
 	if (retval)
 		return retval;
 
 	switch (opn) {
 		case ENABLE:
-			if (!(SLOT_PWRGD (slot_cur->status)) && 
-			     (SLOT_PRESENT (slot_cur->status)) && 
-			     !(SLOT_LATCH (slot_cur->status)))
+			if (!(SLOT_PWRGD(slot_cur->status)) && 
+			     (SLOT_PRESENT(slot_cur->status)) && 
+			     !(SLOT_LATCH(slot_cur->status)))
 				return 0;
 			break;
 		case DISABLE:
-			if ((SLOT_PWRGD (slot_cur->status)) && 
-			    (SLOT_PRESENT (slot_cur->status)) &&
-			    !(SLOT_LATCH (slot_cur->status)))
+			if ((SLOT_PWRGD(slot_cur->status)) && 
+			    (SLOT_PRESENT(slot_cur->status)) &&
+			    !(SLOT_LATCH(slot_cur->status)))
 				return 0;
 			break;
 		default:
 			break;
 	}
-	err ("validate failed....\n");
+	err("validate failed....\n");
 	return -EINVAL;
 }
 
-/********************************************************************************
+/****************************************************************************
  * This routine is for updating the data structures in the hotplug core
  * Parameters: struct slot
  * Returns: 0 or error
- *******************************************************************************/
-int ibmphp_update_slot_info (struct slot *slot_cur)
+ ****************************************************************************/
+int ibmphp_update_slot_info(struct slot *slot_cur)
 {
 	struct hotplug_slot_info *info;
 	int rc;
 	u8 bus_speed;
 	u8 mode;
 
-	info = kmalloc (sizeof (struct hotplug_slot_info), GFP_KERNEL);
+	info = kmalloc(sizeof(struct hotplug_slot_info), GFP_KERNEL);
 	if (!info) {
-		err ("out of system memory\n");
+		err("out of system memory\n");
 		return -ENOMEM;
 	}
         
-	info->power_status = SLOT_PWRGD (slot_cur->status);
-	info->attention_status = SLOT_ATTN (slot_cur->status, slot_cur->ext_status);
-	info->latch_status = SLOT_LATCH (slot_cur->status);
-        if (!SLOT_PRESENT (slot_cur->status)) {
+	info->power_status = SLOT_PWRGD(slot_cur->status);
+	info->attention_status = SLOT_ATTN(slot_cur->status,
+						slot_cur->ext_status);
+	info->latch_status = SLOT_LATCH(slot_cur->status);
+        if (!SLOT_PRESENT(slot_cur->status)) {
                 info->adapter_status = 0;
-//		info->max_adapter_speed_status = MAX_ADAPTER_NONE;
+/*		info->max_adapter_speed_status = MAX_ADAPTER_NONE; */
 	} else {
                 info->adapter_status = 1;
-//		get_max_adapter_speed_1 (slot_cur->hotplug_slot, &info->max_adapter_speed_status, 0);
+/*		get_max_adapter_speed_1(slot_cur->hotplug_slot,
+					&info->max_adapter_speed_status, 0); */
 	}
 
 	bus_speed = slot_cur->bus_on->current_speed;
 	mode = slot_cur->bus_on->current_bus_mode;
 
 	switch (bus_speed) {
-	case BUS_SPEED_33:
-		break;
-	case BUS_SPEED_66:
-		if (mode == BUS_MODE_PCIX) 
+		case BUS_SPEED_33:
+			break;
+		case BUS_SPEED_66:
+			if (mode == BUS_MODE_PCIX) 
+				bus_speed += 0x01;
+			else if (mode == BUS_MODE_PCI)
+				;
+			else
+				bus_speed = PCI_SPEED_UNKNOWN;
+			break;
+		case BUS_SPEED_100:
+		case BUS_SPEED_133:
 			bus_speed += 0x01;
-		else if (mode == BUS_MODE_PCI)
-			;
-		else
+			break;
+		default:
 			bus_speed = PCI_SPEED_UNKNOWN;
-		break;
-	case BUS_SPEED_100:
-	case BUS_SPEED_133:
-		bus_speed += 0x01;
-		break;
-	default:
-		bus_speed = PCI_SPEED_UNKNOWN;
 	}
 
 	info->cur_bus_speed = bus_speed;
 	info->max_bus_speed = slot_cur->hotplug_slot->info->max_bus_speed;
 	// To do: bus_names 
 	
-	rc = pci_hp_change_slot_info (slot_cur->hotplug_slot, info);
-	kfree (info);
+	rc = pci_hp_change_slot_info(slot_cur->hotplug_slot, info);
+	kfree(info);
 	return rc;
 }
 
@@ -665,17 +710,19 @@
  * is called from visit routines
  ******************************************************************************/
 
-static struct pci_func *ibm_slot_find (u8 busno, u8 device, u8 function)
+static struct pci_func *ibm_slot_find(u8 busno, u8 device, u8 function)
 {
 	struct pci_func *func_cur;
 	struct slot *slot_cur;
 	struct list_head * tmp;
-	list_for_each (tmp, &ibmphp_slot_head) {
-		slot_cur = list_entry (tmp, struct slot, ibm_slot_list);
+	list_for_each(tmp, &ibmphp_slot_head) {
+		slot_cur = list_entry(tmp, struct slot, ibm_slot_list);
 		if (slot_cur->func) {
 			func_cur = slot_cur->func;
 			while (func_cur) {
-				if ((func_cur->busno == busno) && (func_cur->device == device) && (func_cur->function == function))
+				if ((func_cur->busno == busno) &&
+						(func_cur->device == device) &&
+						(func_cur->function == function))
 					return func_cur;
 				func_cur = func_cur->next;
 			}
@@ -689,19 +736,19 @@
  * the pointers to pci_func, bus, hotplug_slot, controller,
  * and deregistering from the hotplug core
  *************************************************************/
-static void free_slots (void)
+static void free_slots(void)
 {
 	struct slot *slot_cur;
 	struct list_head * tmp;
 	struct list_head * next;
 
-	debug ("%s -- enter\n", __FUNCTION__);
+	debug("%s -- enter\n", __FUNCTION__);
 
-	list_for_each_safe (tmp, next, &ibmphp_slot_head) {
-		slot_cur = list_entry (tmp, struct slot, ibm_slot_list);
-		pci_hp_deregister (slot_cur->hotplug_slot);
+	list_for_each_safe(tmp, next, &ibmphp_slot_head) {
+		slot_cur = list_entry(tmp, struct slot, ibm_slot_list);
+		pci_hp_deregister(slot_cur->hotplug_slot);
 	}
-	debug ("%s -- exit\n", __FUNCTION__);
+	debug("%s -- exit\n", __FUNCTION__);
 }
 
 static void ibm_unconfigure_device(struct pci_func *func)
@@ -710,7 +757,8 @@
 	u8 j;
 
 	debug("inside %s\n", __FUNCTION__);
-	debug("func->device = %x, func->function = %x\n", func->device, func->function);
+	debug("func->device = %x, func->function = %x\n",
+					func->device, func->function);
 	debug("func->device << 3 | 0x0  = %x\n", func->device << 3 | 0x0);
 
 	for (j = 0; j < 0x08; j++) {
@@ -725,25 +773,24 @@
  * getting bus entries, here we manually add those primary 
  * bus entries to kernel bus structure whenever apply
  */
-
-static u8 bus_structure_fixup (u8 busno)
+static u8 bus_structure_fixup(u8 busno)
 {
 	struct pci_bus *bus;
 	struct pci_dev *dev;
 	u16 l;
 
-	if (pci_find_bus(0, busno) || !(ibmphp_find_same_bus_num (busno)))
+	if (pci_find_bus(0, busno) || !(ibmphp_find_same_bus_num(busno)))
 		return 1;
 
-	bus = kmalloc (sizeof (*bus), GFP_KERNEL);
+	bus = kmalloc(sizeof(*bus), GFP_KERNEL);
 	if (!bus) {
-		err ("%s - out of memory\n", __FUNCTION__);
+		err("%s - out of memory\n", __FUNCTION__);
 		return 1;
 	}
-	dev = kmalloc (sizeof (*dev), GFP_KERNEL);
+	dev = kmalloc(sizeof(*dev), GFP_KERNEL);
 	if (!dev) {
-		kfree (bus);
-		err ("%s - out of memory\n", __FUNCTION__);
+		kfree(bus);
+		err("%s - out of memory\n", __FUNCTION__);
 		return 1;
 	}
 
@@ -751,50 +798,56 @@
 	bus->ops = ibmphp_pci_bus->ops;
 	dev->bus = bus;
 	for (dev->devfn = 0; dev->devfn < 256; dev->devfn += 8) {
-		if (!pci_read_config_word (dev, PCI_VENDOR_ID, &l) &&  l != 0x0000 && l != 0xffff) {
-			debug ("%s - Inside bus_struture_fixup()\n", __FUNCTION__);
-			pci_scan_bus (busno, ibmphp_pci_bus->ops, NULL);
+		if (!pci_read_config_word(dev, PCI_VENDOR_ID, &l) &&
+					(l != 0x0000) && (l != 0xffff)) {
+			debug("%s - Inside bus_struture_fixup()\n",
+							__FUNCTION__);
+			pci_scan_bus(busno, ibmphp_pci_bus->ops, NULL);
 			break;
 		}
 	}
 
-	kfree (dev);
-	kfree (bus);
+	kfree(dev);
+	kfree(bus);
 
 	return 0;
 }
 
-static int ibm_configure_device (struct pci_func *func)
+static int ibm_configure_device(struct pci_func *func)
 {
 	unsigned char bus;
 	struct pci_bus *child;
 	int num;
-	int flag = 0;	/* this is to make sure we don't double scan the bus, for bridged devices primarily */
+	int flag = 0;	/* this is to make sure we don't double scan the bus,
+					for bridged devices primarily */
 
-	if (!(bus_structure_fixup (func->busno)))
+	if (!(bus_structure_fixup(func->busno)))
 		flag = 1;
 	if (func->dev == NULL)
-		func->dev = pci_find_slot (func->busno, PCI_DEVFN(func->device, func->function));
+		func->dev = pci_find_slot(func->busno,
+				PCI_DEVFN(func->device, func->function));
 
 	if (func->dev == NULL) {
 		struct pci_bus *bus = pci_find_bus(0, func->busno);
 		if (!bus)
 			return 0;
 
-		num = pci_scan_slot(bus, PCI_DEVFN(func->device, func->function));
+		num = pci_scan_slot(bus,
+				PCI_DEVFN(func->device, func->function));
 		if (num)
 			pci_bus_add_devices(bus);
 
-		func->dev = pci_find_slot(func->busno, PCI_DEVFN(func->device, func->function));
+		func->dev = pci_find_slot(func->busno,
+				PCI_DEVFN(func->device, func->function));
 		if (func->dev == NULL) {
-			err ("ERROR... : pci_dev still NULL\n");
+			err("ERROR... : pci_dev still NULL\n");
 			return 0;
 		}
 	}
 	if (!(flag) && (func->dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)) {
-		pci_read_config_byte (func->dev, PCI_SECONDARY_BUS, &bus);
-		child = (struct pci_bus *) pci_add_new_bus (func->dev->bus, (func->dev), bus);
-		pci_do_scan_bus (child);
+		pci_read_config_byte(func->dev, PCI_SECONDARY_BUS, &bus);
+		child = pci_add_new_bus(func->dev->bus, func->dev, bus);
+		pci_do_scan_bus(child);
 	}
 
 	return 0;
@@ -803,7 +856,7 @@
 /*******************************************************
  * Returns whether the bus is empty or not 
  *******************************************************/
-static int is_bus_empty (struct slot * slot_cur)
+static int is_bus_empty(struct slot * slot_cur)
 {
 	int rc;
 	struct slot * tmp_slot;
@@ -814,13 +867,14 @@
 			i++;
 			continue;
 		}
-		tmp_slot = ibmphp_get_slot_from_physical_num (i);
+		tmp_slot = ibmphp_get_slot_from_physical_num(i);
 		if (!tmp_slot)
 			return 0;
-		rc = slot_update (&tmp_slot);
+		rc = slot_update(&tmp_slot);
 		if (rc)
 			return 0;
-		if (SLOT_PRESENT (tmp_slot->status) && SLOT_PWRGD (tmp_slot->status))
+		if (SLOT_PRESENT(tmp_slot->status) &&
+					SLOT_PWRGD(tmp_slot->status))
 			return 0;
 		i++;
 	}
@@ -833,7 +887,7 @@
  * Parameters: slot
  * Returns: bus is set (0) or error code
  ***********************************************************/
-static int set_bus (struct slot * slot_cur)
+static int set_bus(struct slot * slot_cur)
 {
 	int rc;
 	u8 speed;
@@ -844,22 +898,23 @@
 	        { },
 	};	
 
-	debug ("%s - entry slot # %d\n", __FUNCTION__, slot_cur->number);
-	if (SET_BUS_STATUS (slot_cur->ctrl) && is_bus_empty (slot_cur)) {
-		rc = slot_update (&slot_cur);
+	debug("%s - entry slot # %d\n", __FUNCTION__, slot_cur->number);
+	if (SET_BUS_STATUS(slot_cur->ctrl) && is_bus_empty(slot_cur)) {
+		rc = slot_update(&slot_cur);
 		if (rc)
 			return rc;
-		speed = SLOT_SPEED (slot_cur->ext_status);
-		debug ("ext_status = %x, speed = %x\n", slot_cur->ext_status, speed);
+		speed = SLOT_SPEED(slot_cur->ext_status);
+		debug("ext_status = %x, speed = %x\n", slot_cur->ext_status, speed);
 		switch (speed) {
 		case HPC_SLOT_SPEED_33:
 			cmd = HPC_BUS_33CONVMODE;
 			break;
 		case HPC_SLOT_SPEED_66:
-			if (SLOT_PCIX (slot_cur->ext_status)) {
-				if ((slot_cur->supported_speed >= BUS_SPEED_66) && (slot_cur->supported_bus_mode == BUS_MODE_PCIX))
+			if (SLOT_PCIX(slot_cur->ext_status)) {
+				if ((slot_cur->supported_speed >= BUS_SPEED_66) &&
+						(slot_cur->supported_bus_mode == BUS_MODE_PCIX))
 					cmd = HPC_BUS_66PCIXMODE;
-				else if (!SLOT_BUS_MODE (slot_cur->ext_status))
+				else if (!SLOT_BUS_MODE(slot_cur->ext_status))
 					/* if max slot/bus capability is 66 pci
 					and there's no bus mode mismatch, then
 					the adapter supports 66 pci */ 
@@ -890,33 +945,35 @@
 			case BUS_SPEED_133:
 				/* This is to take care of the bug in CIOBX chip */
 				if (pci_dev_present(ciobx))
-					ibmphp_hpc_writeslot (slot_cur, HPC_BUS_100PCIXMODE);
+					ibmphp_hpc_writeslot(slot_cur,
+							HPC_BUS_100PCIXMODE);
 				cmd = HPC_BUS_133PCIXMODE;
 				break;
 			default:
-				err ("Wrong bus speed\n");
+				err("Wrong bus speed\n");
 				return -ENODEV;
 			}
 			break;
 		default:
-			err ("wrong slot speed\n");
+			err("wrong slot speed\n");
 			return -ENODEV;
 		}
-		debug ("setting bus speed for slot %d, cmd %x\n", slot_cur->number, cmd);
-		retval = ibmphp_hpc_writeslot (slot_cur, cmd);
+		debug("setting bus speed for slot %d, cmd %x\n",
+						slot_cur->number, cmd);
+		retval = ibmphp_hpc_writeslot(slot_cur, cmd);
 		if (retval) {
-			err ("setting bus speed failed\n");
+			err("setting bus speed failed\n");
 			return retval;
 		}
-		if (CTLR_RESULT (slot_cur->ctrl->status)) {
-			err ("command not completed successfully in set_bus\n");
+		if (CTLR_RESULT(slot_cur->ctrl->status)) {
+			err("command not completed successfully in set_bus\n");
 			return -EIO;
 		}
 	}
 	/* This is for x440, once Brandon fixes the firmware, 
 	will not need this delay */
 	msleep(1000);
-	debug ("%s -Exit\n", __FUNCTION__);
+	debug("%s -Exit\n", __FUNCTION__);
 	return 0;
 }
 
@@ -927,7 +984,7 @@
  * Parameters: slot
  * Returns: 0 = no limitations, -EINVAL = exceeded limitations on the bus
  */
-static int check_limitations (struct slot *slot_cur)
+static int check_limitations(struct slot *slot_cur)
 {
 	u8 i;
 	struct slot * tmp_slot;
@@ -935,13 +992,14 @@
 	u8 limitation = 0;
 
 	for (i = slot_cur->bus_on->slot_min; i <= slot_cur->bus_on->slot_max; i++) {
-		tmp_slot = ibmphp_get_slot_from_physical_num (i);
+		tmp_slot = ibmphp_get_slot_from_physical_num(i);
 		if (!tmp_slot)
 			return -ENODEV;
-		if ((SLOT_PWRGD (tmp_slot->status)) && !(SLOT_CONNECT (tmp_slot->status))) 
+		if ((SLOT_PWRGD(tmp_slot->status)) &&
+					!(SLOT_CONNECT(tmp_slot->status)))
 			count++;
 	}
-	get_cur_bus_info (&slot_cur);
+	get_cur_bus_info(&slot_cur);
 	switch (slot_cur->bus_on->current_speed) {
 	case BUS_SPEED_33:
 		limitation = slot_cur->bus_on->slots_at_33_conv;
@@ -965,17 +1023,17 @@
 	return 0;
 }
 
-static inline void print_card_capability (struct slot *slot_cur)
+static inline void print_card_capability(struct slot *slot_cur)
 {
-	info ("capability of the card is ");
+	info("capability of the card is ");
 	if ((slot_cur->ext_status & CARD_INFO) == PCIX133) 
-		info ("   133 MHz PCI-X\n");
+		info("   133 MHz PCI-X\n");
 	else if ((slot_cur->ext_status & CARD_INFO) == PCIX66)
-		info ("    66 MHz PCI-X\n");
+		info("    66 MHz PCI-X\n");
 	else if ((slot_cur->ext_status & CARD_INFO) == PCI66)
-		info ("    66 MHz PCI\n");
+		info("    66 MHz PCI\n");
 	else
-		info ("    33 MHz PCI\n");
+		info("    33 MHz PCI\n");
 
 }
 
@@ -984,118 +1042,128 @@
  * Parameters: hotplug_slot
  * Returns: 0 or failure codes
  */
-static int enable_slot (struct hotplug_slot *hs)
+static int enable_slot(struct hotplug_slot *hs)
 {
 	int rc, i, rcpr;
 	struct slot *slot_cur;
 	u8 function;
 	struct pci_func *tmp_func;
 
-	ibmphp_lock_operations ();
+	ibmphp_lock_operations();
 
-	debug ("ENABLING SLOT........\n");
-	slot_cur = (struct slot *) hs->private;
+	debug("ENABLING SLOT........\n");
+	slot_cur = hs->private;
 
-	if ((rc = validate (slot_cur, ENABLE))) {
-		err ("validate function failed\n");
+	if ((rc = validate(slot_cur, ENABLE))) {
+		err("validate function failed\n");
 		goto error_nopower;
 	}
 
-	attn_LED_blink (slot_cur);
+	attn_LED_blink(slot_cur);
 	
-	rc = set_bus (slot_cur);
+	rc = set_bus(slot_cur);
 	if (rc) {
-		err ("was not able to set the bus\n");
+		err("was not able to set the bus\n");
 		goto error_nopower;
 	}
 
 	/*-----------------debugging------------------------------*/
-	get_cur_bus_info (&slot_cur);
-	debug ("the current bus speed right after set_bus = %x\n", slot_cur->bus_on->current_speed); 
+	get_cur_bus_info(&slot_cur);
+	debug("the current bus speed right after set_bus = %x\n",
+					slot_cur->bus_on->current_speed);
 	/*----------------------------------------------------------*/
 
-	rc = check_limitations (slot_cur);
+	rc = check_limitations(slot_cur);
 	if (rc) {
-		err ("Adding this card exceeds the limitations of this bus.\n");
-		err ("(i.e., >1 133MHz cards running on same bus, or "
+		err("Adding this card exceeds the limitations of this bus.\n");
+		err("(i.e., >1 133MHz cards running on same bus, or "
 		     ">2 66 PCI cards running on same bus\n.");
-		err ("Try hot-adding into another bus\n");
+		err("Try hot-adding into another bus\n");
 		rc = -EINVAL;
 		goto error_nopower;
 	}
 
-	rc = power_on (slot_cur);
+	rc = power_on(slot_cur);
 
 	if (rc) {
-		err ("something wrong when powering up... please see below for details\n");
+		err("something wrong when powering up... please see below for details\n");
 		/* need to turn off before on, otherwise, blinking overwrites */
 		attn_off(slot_cur);
-		attn_on (slot_cur);
-		if (slot_update (&slot_cur)) {
-			attn_off (slot_cur);
-			attn_on (slot_cur);
+		attn_on(slot_cur);
+		if (slot_update(&slot_cur)) {
+			attn_off(slot_cur);
+			attn_on(slot_cur);
 			rc = -ENODEV;
 			goto exit;
 		}
 		/* Check to see the error of why it failed */
-		if ((SLOT_POWER (slot_cur->status)) && !(SLOT_PWRGD (slot_cur->status)))
-			err ("power fault occurred trying to power up\n");
-		else if (SLOT_BUS_SPEED (slot_cur->status)) {
-			err ("bus speed mismatch occurred.  please check current bus speed and card capability\n");
-			print_card_capability (slot_cur);
-		} else if (SLOT_BUS_MODE (slot_cur->ext_status)) {
-			err ("bus mode mismatch occurred.  please check current bus mode and card capability\n");
-			print_card_capability (slot_cur);
+		if ((SLOT_POWER(slot_cur->status)) &&
+					!(SLOT_PWRGD(slot_cur->status)))
+			err("power fault occurred trying to power up\n");
+		else if (SLOT_BUS_SPEED(slot_cur->status)) {
+			err("bus speed mismatch occurred.  please check "
+				"current bus speed and card capability\n");
+			print_card_capability(slot_cur);
+		} else if (SLOT_BUS_MODE(slot_cur->ext_status)) {
+			err("bus mode mismatch occurred.  please check "
+				"current bus mode and card capability\n");
+			print_card_capability(slot_cur);
 		}
-		ibmphp_update_slot_info (slot_cur);
+		ibmphp_update_slot_info(slot_cur);
 		goto exit;
 	}
-	debug ("after power_on\n");
+	debug("after power_on\n");
 	/*-----------------------debugging---------------------------*/
-	get_cur_bus_info (&slot_cur);
-	debug ("the current bus speed right after power_on = %x\n", slot_cur->bus_on->current_speed);
+	get_cur_bus_info(&slot_cur);
+	debug("the current bus speed right after power_on = %x\n",
+					slot_cur->bus_on->current_speed);
 	/*----------------------------------------------------------*/
 
-	rc = slot_update (&slot_cur);
+	rc = slot_update(&slot_cur);
 	if (rc)
 		goto error_power;
 	
 	rc = -EINVAL;
-	if (SLOT_POWER (slot_cur->status) && !(SLOT_PWRGD (slot_cur->status))) {
-		err ("power fault occurred trying to power up...\n");
+	if (SLOT_POWER(slot_cur->status) && !(SLOT_PWRGD(slot_cur->status))) {
+		err("power fault occurred trying to power up...\n");
 		goto error_power;
 	}
-	if (SLOT_POWER (slot_cur->status) && (SLOT_BUS_SPEED (slot_cur->status))) {
-		err ("bus speed mismatch occurred.  please check current bus speed and card capability\n");
-		print_card_capability (slot_cur);
+	if (SLOT_POWER(slot_cur->status) && (SLOT_BUS_SPEED(slot_cur->status))) {
+		err("bus speed mismatch occurred.  please check current bus "
+					"speed and card capability\n");
+		print_card_capability(slot_cur);
 		goto error_power;
 	} 
-	/* Don't think this case will happen after above checks... but just in case, for paranoia sake */
-	if (!(SLOT_POWER (slot_cur->status))) {
-		err ("power on failed...\n");
+	/* Don't think this case will happen after above checks...
+	 * but just in case, for paranoia sake */
+	if (!(SLOT_POWER(slot_cur->status))) {
+		err("power on failed...\n");
 		goto error_power;
 	}
 
-	slot_cur->func = (struct pci_func *) kmalloc (sizeof (struct pci_func), GFP_KERNEL);
+	slot_cur->func = kmalloc(sizeof(struct pci_func), GFP_KERNEL);
 	if (!slot_cur->func) {
 		/* We cannot do update_slot_info here, since no memory for
 		 * kmalloc n.e.ways, and update_slot_info allocates some */
-		err ("out of system memory\n");
+		err("out of system memory\n");
 		rc = -ENOMEM;
 		goto error_power;
 	}
-	memset (slot_cur->func, 0, sizeof (struct pci_func));
+	memset(slot_cur->func, 0, sizeof(struct pci_func));
 	slot_cur->func->busno = slot_cur->bus;
 	slot_cur->func->device = slot_cur->device;
 	for (i = 0; i < 4; i++)
 		slot_cur->func->irq[i] = slot_cur->irq[i];
 
-	debug ("b4 configure_card, slot_cur->bus = %x, slot_cur->device = %x\n", slot_cur->bus, slot_cur->device);
+	debug("b4 configure_card, slot_cur->bus = %x, slot_cur->device = %x\n",
+					slot_cur->bus, slot_cur->device);
 
-	if (ibmphp_configure_card (slot_cur->func, slot_cur->number)) {
-		err ("configure_card was unsuccessful...\n");
-		ibmphp_unconfigure_card (&slot_cur, 1); /* true because don't need to actually deallocate resources, just remove references */
-		debug ("after unconfigure_card\n");
+	if (ibmphp_configure_card(slot_cur->func, slot_cur->number)) {
+		err("configure_card was unsuccessful...\n");
+		/* true because don't need to actually deallocate resources,
+		 * just remove references */
+		ibmphp_unconfigure_card(&slot_cur, 1);
+		debug("after unconfigure_card\n");
 		slot_cur->func = NULL;
 		rc = -ENOMEM;
 		goto error_power;
@@ -1103,38 +1171,39 @@
 
 	function = 0x00;
 	do {
-		tmp_func = ibm_slot_find (slot_cur->bus, slot_cur->func->device, function++);
+		tmp_func = ibm_slot_find(slot_cur->bus, slot_cur->func->device,
+							function++);
 		if (tmp_func && !(tmp_func->dev))
-			ibm_configure_device (tmp_func);
+			ibm_configure_device(tmp_func);
 	} while (tmp_func);
 
-	attn_off (slot_cur);
-	if (slot_update (&slot_cur)) {
+	attn_off(slot_cur);
+	if (slot_update(&slot_cur)) {
 		rc = -EFAULT;
 		goto exit;
 	}
-	ibmphp_print_test ();
-	rc = ibmphp_update_slot_info (slot_cur);
+	ibmphp_print_test();
+	rc = ibmphp_update_slot_info(slot_cur);
 exit:
 	ibmphp_unlock_operations(); 
 	return rc;
 
 error_nopower:
-	attn_off (slot_cur);	/* need to turn off if was blinking b4 */
-	attn_on (slot_cur);
+	attn_off(slot_cur);	/* need to turn off if was blinking b4 */
+	attn_on(slot_cur);
 error_cont:
-	rcpr = slot_update (&slot_cur);
+	rcpr = slot_update(&slot_cur);
 	if (rcpr) {
 		rc = rcpr;
 		goto exit;
 	}
-	ibmphp_update_slot_info (slot_cur);
+	ibmphp_update_slot_info(slot_cur);
 	goto exit;
 
 error_power:
-	attn_off (slot_cur);	/* need to turn off if was blinking b4 */
-	attn_on (slot_cur);
-	rcpr = power_off (slot_cur);
+	attn_off(slot_cur);	/* need to turn off if was blinking b4 */
+	attn_on(slot_cur);
+	rcpr = power_off(slot_cur);
 	if (rcpr) {
 		rc = rcpr;
 		goto exit;
@@ -1148,7 +1217,7 @@
 * OUTPUT: SUCCESS 0 ; FAILURE: UNCONFIGURE , VALIDATE         *
           DISABLE POWER ,                                    *
 **************************************************************/
-static int ibmphp_disable_slot (struct hotplug_slot *hotplug_slot)
+static int ibmphp_disable_slot(struct hotplug_slot *hotplug_slot)
 {
 	struct slot *slot = hotplug_slot->private;
 	int rc;
@@ -1159,12 +1228,12 @@
 	return rc;
 }
 
-int ibmphp_do_disable_slot (struct slot *slot_cur)
+int ibmphp_do_disable_slot(struct slot *slot_cur)
 {
 	int rc;
 	u8 flag;
 
-	debug ("DISABLING SLOT...\n"); 
+	debug("DISABLING SLOT...\n"); 
 		
 	if ((slot_cur == NULL) || (slot_cur->ctrl == NULL)) {
 		return -ENODEV;
@@ -1174,21 +1243,22 @@
 	slot_cur->flag = TRUE;
 
 	if (flag == TRUE) {
-		rc = validate (slot_cur, DISABLE);	/* checking if powered off already & valid slot # */
+		rc = validate(slot_cur, DISABLE);
+			/* checking if powered off already & valid slot # */
 		if (rc)
 			goto error;
 	}
-	attn_LED_blink (slot_cur);
+	attn_LED_blink(slot_cur);
 
 	if (slot_cur->func == NULL) {
 		/* We need this for fncs's that were there on bootup */
-		slot_cur->func = (struct pci_func *) kmalloc (sizeof (struct pci_func), GFP_KERNEL);
+		slot_cur->func = kmalloc(sizeof(struct pci_func), GFP_KERNEL);
 		if (!slot_cur->func) {
-			err ("out of system memory\n");
+			err("out of system memory\n");
 			rc = -ENOMEM;
 			goto error;
 		}
-		memset (slot_cur->func, 0, sizeof (struct pci_func));
+		memset(slot_cur->func, 0, sizeof(struct pci_func));
 		slot_cur->func->busno = slot_cur->bus;
 		slot_cur->func->device = slot_cur->device;
 	}
@@ -1202,42 +1272,42 @@
 	lists at least */
 
 	if (!flag) {
-		attn_off (slot_cur);
+		attn_off(slot_cur);
 		return 0;
 	}
 
-	rc = ibmphp_unconfigure_card (&slot_cur, 0);
+	rc = ibmphp_unconfigure_card(&slot_cur, 0);
 	slot_cur->func = NULL;
-	debug ("in disable_slot. after unconfigure_card\n");
+	debug("in disable_slot. after unconfigure_card\n");
 	if (rc) {
-		err ("could not unconfigure card.\n");
+		err("could not unconfigure card.\n");
 		goto error;
 	}
 
-	rc = ibmphp_hpc_writeslot (slot_cur, HPC_SLOT_OFF);
+	rc = ibmphp_hpc_writeslot(slot_cur, HPC_SLOT_OFF);
 	if (rc)
 		goto error;
 
-	attn_off (slot_cur);
-	rc = slot_update (&slot_cur);
+	attn_off(slot_cur);
+	rc = slot_update(&slot_cur);
 	if (rc)
 		goto exit;
 
-	rc = ibmphp_update_slot_info (slot_cur);
-	ibmphp_print_test ();
+	rc = ibmphp_update_slot_info(slot_cur);
+	ibmphp_print_test();
 exit:
 	return rc;
 
 error:
 	/*  Need to turn off if was blinking b4 */
-	attn_off (slot_cur);
-	attn_on (slot_cur);
-	if (slot_update (&slot_cur)) {
+	attn_off(slot_cur);
+	attn_on(slot_cur);
+	if (slot_update(&slot_cur)) {
 		rc = -EFAULT;
 		goto exit;
 	}
 	if (flag)		
-		ibmphp_update_slot_info (slot_cur);
+		ibmphp_update_slot_info(slot_cur);
 	goto exit;
 }
 
@@ -1258,22 +1328,22 @@
 */
 };
 
-static void ibmphp_unload (void)
+static void ibmphp_unload(void)
 {
-	free_slots ();
-	debug ("after slots\n");
-	ibmphp_free_resources ();
-	debug ("after resources\n");
-	ibmphp_free_bus_info_queue ();
-	debug ("after bus info\n");
-	ibmphp_free_ebda_hpc_queue ();
-	debug ("after ebda hpc\n");
-	ibmphp_free_ebda_pci_rsrc_queue ();
-	debug ("after ebda pci rsrc\n");
-	kfree (ibmphp_pci_bus);
+	free_slots();
+	debug("after slots\n");
+	ibmphp_free_resources();
+	debug("after resources\n");
+	ibmphp_free_bus_info_queue();
+	debug("after bus info\n");
+	ibmphp_free_ebda_hpc_queue();
+	debug("after ebda hpc\n");
+	ibmphp_free_ebda_pci_rsrc_queue();
+	debug("after ebda pci rsrc\n");
+	kfree(ibmphp_pci_bus);
 }
 
-static int __init ibmphp_init (void)
+static int __init ibmphp_init(void)
 {
 	struct pci_bus *bus;
 	int i = 0;
@@ -1281,50 +1351,50 @@
 
 	init_flag = 1;
 
-	info (DRIVER_DESC " version: " DRIVER_VERSION "\n");
+	info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
 
-	ibmphp_pci_bus = kmalloc (sizeof (*ibmphp_pci_bus), GFP_KERNEL);
+	ibmphp_pci_bus = kmalloc(sizeof(*ibmphp_pci_bus), GFP_KERNEL);
 	if (!ibmphp_pci_bus) {
-		err ("out of memory\n");
+		err("out of memory\n");
 		rc = -ENOMEM;
 		goto exit;
 	}
 
 	bus = pci_find_bus(0, 0);
 	if (!bus) {
-		err ("Can't find the root pci bus, can not continue\n");
+		err("Can't find the root pci bus, can not continue\n");
 		rc = -ENODEV;
 		goto error;
 	}
-	memcpy (ibmphp_pci_bus, bus, sizeof (*ibmphp_pci_bus));
+	memcpy(ibmphp_pci_bus, bus, sizeof(*ibmphp_pci_bus));
 
 	ibmphp_debug = debug;
 
-	ibmphp_hpc_initvars ();
+	ibmphp_hpc_initvars();
 
 	for (i = 0; i < 16; i++)
 		irqs[i] = 0;
 
-	if ((rc = ibmphp_access_ebda ()))
+	if ((rc = ibmphp_access_ebda()))
 		goto error;
-	debug ("after ibmphp_access_ebda ()\n");
+	debug("after ibmphp_access_ebda()\n");
 
-	if ((rc = ibmphp_rsrc_init ()))
+	if ((rc = ibmphp_rsrc_init()))
 		goto error;
-	debug ("AFTER Resource & EBDA INITIALIZATIONS\n");
+	debug("AFTER Resource & EBDA INITIALIZATIONS\n");
 
-	max_slots = get_max_slots ();
+	max_slots = get_max_slots();
 	
-	if ((rc = ibmphp_register_pci ()))
+	if ((rc = ibmphp_register_pci()))
 		goto error;
 
-	if (init_ops ()) {
+	if (init_ops()) {
 		rc = -ENODEV;
 		goto error;
 	}
 
-	ibmphp_print_test ();
-	if ((rc = ibmphp_hpc_start_poll_thread ())) {
+	ibmphp_print_test();
+	if ((rc = ibmphp_hpc_start_poll_thread())) {
 		goto error;
 	}
 
@@ -1336,17 +1406,17 @@
 	return rc;
 
 error:
-	ibmphp_unload ();
+	ibmphp_unload();
 	goto exit;
 }
 
-static void __exit ibmphp_exit (void)
+static void __exit ibmphp_exit(void)
 {
-	ibmphp_hpc_stop_poll_thread ();
-	debug ("after polling\n");
-	ibmphp_unload ();
-	debug ("done\n");
+	ibmphp_hpc_stop_poll_thread();
+	debug("after polling\n");
+	ibmphp_unload();
+	debug("done\n");
 }
 
-module_init (ibmphp_init);
-module_exit (ibmphp_exit);
+module_init(ibmphp_init);
+module_exit(ibmphp_exit);
diff -Nru a/drivers/pci/hotplug/ibmphp_pci.c b/drivers/pci/hotplug/ibmphp_pci.c
--- a/drivers/pci/hotplug/ibmphp_pci.c	2005-03-01 23:38:44 -08:00
+++ b/drivers/pci/hotplug/ibmphp_pci.c	2005-03-01 23:38:44 -08:00
@@ -164,7 +164,7 @@
 						cleanup_count = 6;
 						goto error;
 					}
-					newfunc = (struct pci_func *) kmalloc (sizeof (struct pci_func), GFP_KERNEL);
+					newfunc = kmalloc(sizeof(*newfunc), GFP_KERNEL);
 					if (!newfunc) {
 						err ("out of system memory\n");
 						return -ENOMEM;
@@ -203,7 +203,7 @@
 					flag = FALSE;
 					for (i = 0; i < 32; i++) {
 						if (func->devices[i]) {
-							newfunc = (struct pci_func *) kmalloc (sizeof (struct pci_func), GFP_KERNEL);
+							newfunc = kmalloc(sizeof(*newfunc), GFP_KERNEL);
 							if (!newfunc) {
 								err ("out of system memory\n");
 								return -ENOMEM;
@@ -232,7 +232,7 @@
 						}
 					}
 
-					newfunc = (struct pci_func *) kmalloc (sizeof (struct pci_func), GFP_KERNEL);
+					newfunc = kmalloc(sizeof(*newfunc), GFP_KERNEL);
 					if (!newfunc) {
 						err ("out of system memory\n");
 						return -ENOMEM;
@@ -279,7 +279,7 @@
 					for (i = 0; i < 32; i++) {
 						if (func->devices[i]) {
 							debug ("inside for loop, device is %x\n", i);
-							newfunc = (struct pci_func *) kmalloc (sizeof (struct pci_func), GFP_KERNEL);
+							newfunc = kmalloc(sizeof(*newfunc), GFP_KERNEL);
 							if (!newfunc) {
 								err (" out of system memory\n");
 								return -ENOMEM;
@@ -414,7 +414,7 @@
 			memset (io[count], 0, sizeof (struct resource_node));
 			io[count]->type = IO;
 			io[count]->busno = func->busno;
-			io[count]->devfunc = ((func->device << 3) | (func->function & 0x7));
+			io[count]->devfunc = PCI_DEVFN(func->device, func->function);
 			io[count]->len = len[count];
 			if (ibmphp_check_resource(io[count], 0) == 0) {
 				ibmphp_add_resource (io[count]);
@@ -452,14 +452,15 @@
 				memset (pfmem[count], 0, sizeof (struct resource_node));
 				pfmem[count]->type = PFMEM;
 				pfmem[count]->busno = func->busno;
-				pfmem[count]->devfunc = ((func->device << 3) | (func->function & 0x7));
+				pfmem[count]->devfunc = PCI_DEVFN(func->device,
+							func->function);
 				pfmem[count]->len = len[count];
 				pfmem[count]->fromMem = FALSE;
 				if (ibmphp_check_resource (pfmem[count], 0) == 0) {
 					ibmphp_add_resource (pfmem[count]);
 					func->pfmem[count] = pfmem[count];
 				} else {
-					mem_tmp = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
+					mem_tmp = kmalloc(sizeof(*mem_tmp), GFP_KERNEL);
 					if (!mem_tmp) {
 						err ("out of system memory\n");
 						kfree (pfmem[count]);
@@ -519,7 +520,8 @@
 				memset (mem[count], 0, sizeof (struct resource_node));
 				mem[count]->type = MEM;
 				mem[count]->busno = func->busno;
-				mem[count]->devfunc = ((func->device << 3) | (func->function & 0x7));
+				mem[count]->devfunc = PCI_DEVFN(func->device,
+							func->function);
 				mem[count]->len = len[count];
 				if (ibmphp_check_resource (mem[count], 0) == 0) {
 					ibmphp_add_resource (mem[count]);
@@ -685,7 +687,8 @@
 			memset (bus_io[count], 0, sizeof (struct resource_node));
 			bus_io[count]->type = IO;
 			bus_io[count]->busno = func->busno;
-			bus_io[count]->devfunc = ((func->device << 3) | (func->function & 0x7));
+			bus_io[count]->devfunc = PCI_DEVFN(func->device,
+							func->function);
 			bus_io[count]->len = len[count];
 			if (ibmphp_check_resource (bus_io[count], 0) == 0) {
 				ibmphp_add_resource (bus_io[count]);
@@ -717,14 +720,15 @@
 				memset (bus_pfmem[count], 0, sizeof (struct resource_node));
 				bus_pfmem[count]->type = PFMEM;
 				bus_pfmem[count]->busno = func->busno;
-				bus_pfmem[count]->devfunc = ((func->device << 3) | (func->function & 0x7));
+				bus_pfmem[count]->devfunc = PCI_DEVFN(func->device,
+							func->function);
 				bus_pfmem[count]->len = len[count];
 				bus_pfmem[count]->fromMem = FALSE;
 				if (ibmphp_check_resource (bus_pfmem[count], 0) == 0) {
 					ibmphp_add_resource (bus_pfmem[count]);
 					func->pfmem[count] = bus_pfmem[count];
 				} else {
-					mem_tmp = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
+					mem_tmp = kmalloc(sizeof(*mem_tmp), GFP_KERNEL);
 					if (!mem_tmp) {
 						err ("out of system memory\n");
 						retval = -ENOMEM;
@@ -775,7 +779,8 @@
 				memset (bus_mem[count], 0, sizeof (struct resource_node));
 				bus_mem[count]->type = MEM;
 				bus_mem[count]->busno = func->busno;
-				bus_mem[count]->devfunc = ((func->device << 3) | (func->function & 0x7));
+				bus_mem[count]->devfunc = PCI_DEVFN(func->device,
+							func->function);
 				bus_mem[count]->len = len[count];
 				if (ibmphp_check_resource (bus_mem[count], 0) == 0) {
 					ibmphp_add_resource (bus_mem[count]);
@@ -836,7 +841,7 @@
 		flag_io = TRUE;
 	} else {
 		debug ("it wants %x IO behind the bridge\n", amount_needed->io);
-		io = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
+		io = kmalloc(sizeof(*io), GFP_KERNEL);
 		
 		if (!io) {
 			err ("out of system memory\n");
@@ -846,7 +851,7 @@
 		memset (io, 0, sizeof (struct resource_node));
 		io->type = IO;
 		io->busno = func->busno;
-		io->devfunc = ((func->device << 3) | (func->function & 0x7));
+		io->devfunc = PCI_DEVFN(func->device, func->function);
 		io->len = amount_needed->io;
 		if (ibmphp_check_resource (io, 1) == 0) {
 			debug ("were we able to add io\n");
@@ -860,7 +865,7 @@
 		flag_mem = TRUE;
 	} else {
 		debug ("it wants %x memory behind the bridge\n", amount_needed->mem);
-		mem = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
+		mem = kmalloc(sizeof(*mem), GFP_KERNEL);
 		if (!mem) {
 			err ("out of system memory\n");
 			retval = -ENOMEM;
@@ -869,7 +874,7 @@
 		memset (mem, 0, sizeof (struct resource_node));
 		mem->type = MEM;
 		mem->busno = func->busno;
-		mem->devfunc = ((func->device << 3) | (func->function & 0x7));
+		mem->devfunc = PCI_DEVFN(func->device, func->function);
 		mem->len = amount_needed->mem;
 		if (ibmphp_check_resource (mem, 1) == 0) {
 			ibmphp_add_resource (mem);
@@ -883,7 +888,7 @@
 		flag_pfmem = TRUE;
 	} else {
 		debug ("it wants %x pfmemory behind the bridge\n", amount_needed->pfmem);
-		pfmem = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
+		pfmem = kmalloc(sizeof(*pfmem), GFP_KERNEL);
 		if (!pfmem) {
 			err ("out of system memory\n");
 			retval = -ENOMEM;
@@ -892,14 +897,14 @@
 		memset (pfmem, 0, sizeof (struct resource_node));
 		pfmem->type = PFMEM;
 		pfmem->busno = func->busno;
-		pfmem->devfunc = ((func->device << 3) | (func->function & 0x7));
+		pfmem->devfunc = PCI_DEVFN(func->device, func->function);
 		pfmem->len = amount_needed->pfmem;
 		pfmem->fromMem = FALSE;
 		if (ibmphp_check_resource (pfmem, 1) == 0) {
 			ibmphp_add_resource (pfmem);
 			flag_pfmem = TRUE;
 		} else {
-			mem_tmp = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
+			mem_tmp = kmalloc(sizeof(*mem_tmp), GFP_KERNEL);
 			if (!mem_tmp) {
 				err ("out of system memory\n");
 				retval = -ENOMEM;
@@ -931,7 +936,7 @@
 		 */
 		bus = ibmphp_find_res_bus (sec_number);
 		if (!bus) {
-			bus = kmalloc (sizeof (struct bus_node), GFP_KERNEL);
+			bus = kmalloc(sizeof(*bus), GFP_KERNEL);
 			if (!bus) {
 				err ("out of system memory\n");
 				retval = -ENOMEM;
@@ -1057,8 +1062,7 @@
 	}
 
 error:
-	if (amount_needed)
-		kfree (amount_needed);
+	kfree(amount_needed);
 	if (pfmem)
 		ibmphp_remove_resource (pfmem);
 	if (io)
@@ -1107,7 +1111,7 @@
 	};
 	struct res_needed *amount;
 
-	amount = kmalloc (sizeof (struct res_needed), GFP_KERNEL);
+	amount = kmalloc(sizeof(*amount), GFP_KERNEL);
 	if (amount == NULL)
 		return NULL;
 	memset (amount, 0, sizeof (struct res_needed));
@@ -1680,7 +1684,7 @@
 		list_add (&bus->bus_list, &cur_bus->bus_list);
 	}
 	if (io) {
-		io_range = kmalloc (sizeof (struct range_node), GFP_KERNEL);
+		io_range = kmalloc(sizeof(*io_range), GFP_KERNEL);
 		if (!io_range) {
 			err ("out of system memory\n");
 			return -ENOMEM;
@@ -1693,7 +1697,7 @@
 		bus->rangeIO = io_range;
 	}
 	if (mem) {
-		mem_range = kmalloc (sizeof (struct range_node), GFP_KERNEL);
+		mem_range = kmalloc(sizeof(*mem_range), GFP_KERNEL);
 		if (!mem_range) {
 			err ("out of system memory\n");
 			return -ENOMEM;
@@ -1706,7 +1710,7 @@
 		bus->rangeMem = mem_range;
 	}
 	if (pfmem) {
-		pfmem_range = kmalloc (sizeof (struct range_node), GFP_KERNEL);
+		pfmem_range = kmalloc(sizeof(*pfmem_range), GFP_KERNEL);
 		if (!pfmem_range) {	
 			err ("out of system memory\n");
 			return -ENOMEM;
diff -Nru a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
--- a/drivers/pci/hotplug/pciehp.h	2005-03-01 23:39:08 -08:00
+++ b/drivers/pci/hotplug/pciehp.h	2005-03-01 23:39:08 -08:00
@@ -34,6 +34,7 @@
 #include <linux/delay.h>
 #include <asm/semaphore.h>
 #include <asm/io.h>		
+#include <linux/pcieport_if.h>
 #include "pci_hotplug.h"
 
 #define MY_NAME	"pciehp"
@@ -311,7 +312,7 @@
 
 typedef u8(*php_intr_callback_t) (unsigned int change_id, void *instance_id);
 
-int pcie_init(struct controller *ctrl, struct pci_dev *pdev,
+int pcie_init(struct controller *ctrl, struct pcie_device *dev,
 		php_intr_callback_t attention_button_callback,
 		php_intr_callback_t switch_change_callback,
 		php_intr_callback_t presence_change_callback,
diff -Nru a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c
--- a/drivers/pci/hotplug/pciehp_core.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/pci/hotplug/pciehp_core.c	2005-03-01 23:39:18 -08:00
@@ -33,7 +33,6 @@
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/proc_fs.h>
-#include <linux/miscdevice.h>
 #include <linux/slab.h>
 #include <linux/workqueue.h>
 #include <linux/pci.h>
@@ -41,6 +40,7 @@
 #include <asm/uaccess.h>
 #include "pciehp.h"
 #include "pciehprm.h"
+#include <linux/interrupt.h>
 
 /* Global variables */
 int pciehp_debug;
@@ -347,7 +347,7 @@
 	return 0;
 }
 
-static int pcie_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_id *id)
 {
 	int rc;
 	struct controller *ctrl;
@@ -355,7 +355,9 @@
 	int first_device_num = 0 ;	/* first PCI device number supported by this PCIE */  
 	int num_ctlr_slots;		/* number of slots supported by this HPC */
 	u8 value;
-
+	struct pci_dev *pdev;
+	
+	dbg("%s: Called by hp_drv\n", __FUNCTION__);
 	ctrl = kmalloc(sizeof(*ctrl), GFP_KERNEL);
 	if (!ctrl) {
 		err("%s : out of memory\n", __FUNCTION__);
@@ -364,8 +366,10 @@
 	memset(ctrl, 0, sizeof(struct controller));
 
 	dbg("%s: DRV_thread pid = %d\n", __FUNCTION__, current->pid);
+	
+	pdev = dev->port;
 
-	rc = pcie_init(ctrl, pdev,
+	rc = pcie_init(ctrl, dev,
 		(php_intr_callback_t) pciehp_handle_attention_button,
 		(php_intr_callback_t) pciehp_handle_switch_change,
 		(php_intr_callback_t) pciehp_handle_presence_change,
@@ -563,32 +567,52 @@
 
 }
 
+int hpdriver_context = 0;
 
-static struct pci_device_id pcied_pci_tbl[] = {
-	{
-	.class =        ((PCI_CLASS_BRIDGE_PCI << 8) | 0x00),
-	.class_mask =	~0,
-	.vendor =       PCI_ANY_ID,
-	.device =       PCI_ANY_ID,
-	.subvendor =    PCI_ANY_ID,
-	.subdevice =    PCI_ANY_ID,
-	},
-	
-	{ /* end: all zeroes */ }
-};
-
-MODULE_DEVICE_TABLE(pci, pcied_pci_tbl);
+static void pciehp_remove (struct pcie_device *device)
+{
+	printk("%s ENTRY\n", __FUNCTION__);	
+	printk("%s -> Call free_irq for irq = %d\n",  
+		__FUNCTION__, device->irq);
+	free_irq(device->irq, &hpdriver_context);
+}
 
+#ifdef CONFIG_PM
+static int pciehp_suspend (struct pcie_device *dev, u32 state)
+{
+	printk("%s ENTRY\n", __FUNCTION__);	
+	return 0;
+}
 
+static int pciehp_resume (struct pcie_device *dev)
+{
+	printk("%s ENTRY\n", __FUNCTION__);	
+	return 0;
+}
+#endif
 
-static struct pci_driver pcie_driver = {
-	.name		=	PCIE_MODULE_NAME,
-	.id_table	=	pcied_pci_tbl,
-	.probe		=	pcie_probe,
-	/* remove:	pcie_remove_one, */
+static struct pcie_port_service_id port_pci_ids[] = { { 
+	.vendor = PCI_ANY_ID, 
+	.device = PCI_ANY_ID,
+	.port_type = PCIE_RC_PORT, 
+	.service_type = PCIE_PORT_SERVICE_HP,
+	.driver_data =	0, 
+	}, { /* end: all zeroes */ }
 };
+static const char device_name[] = "hpdriver";
 
-
+static struct pcie_port_service_driver hpdriver_portdrv = {
+	.name		= (char *)device_name,
+	.id_table	= &port_pci_ids[0],
+
+	.probe		= pciehp_probe,
+	.remove		= pciehp_remove,
+
+#ifdef	CONFIG_PM
+	.suspend	= pciehp_suspend,
+	.resume		= pciehp_resume,
+#endif	/* PM */
+};
 
 static int __init pcied_init(void)
 {
@@ -604,9 +628,11 @@
 
 	retval = pciehprm_init(PCI);
 	if (!retval) {
-		retval = pci_register_driver(&pcie_driver);
-		dbg("pci_register_driver = %d\n", retval);
-		info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
+ 		retval = pcie_port_service_register(&hpdriver_portdrv);
+ 		dbg("pcie_port_service_register = %d\n", retval);
+  		info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
+ 		if (retval)
+ 		   dbg("%s: Failure to register service\n", __FUNCTION__);
 	}
 
 error_hpc_init:
@@ -626,8 +652,8 @@
 
 	pciehprm_cleanup();
 
-	dbg("pci_unregister_driver\n");
-	pci_unregister_driver(&pcie_driver);
+	dbg("pcie_port_service_unregister\n");
+	pcie_port_service_unregister(&hpdriver_portdrv);
 
 	info(DRIVER_DESC " version: " DRIVER_VERSION " unloaded\n");
 }
diff -Nru a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
--- a/drivers/pci/hotplug/pciehp_hpc.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/pci/hotplug/pciehp_hpc.c	2005-03-01 23:39:07 -08:00
@@ -237,7 +237,7 @@
 static spinlock_t hpc_event_lock;
 
 DEFINE_DBG_BUFFER		/* Debug string buffer for entire HPC defined here */
-static struct php_ctlr_state_s *php_ctlr_list_head = 0;	/* HPC state linked list */
+static struct php_ctlr_state_s *php_ctlr_list_head; /* HPC state linked list */
 static int ctlr_seq_num = 0;	/* Controller sequence # */
 static spinlock_t list_lock;
 
@@ -1249,7 +1249,7 @@
 };
 
 int pcie_init(struct controller * ctrl,
-	struct pci_dev *pdev,
+	struct pcie_device *dev,
 	php_intr_callback_t attention_button_callback,
 	php_intr_callback_t switch_change_callback,
 	php_intr_callback_t presence_change_callback,
@@ -1265,6 +1265,7 @@
 	u32 slot_cap;
 	int cap_base, saved_cap_base;
 	u16 slot_status, slot_ctrl;
+	struct pci_dev *pdev;
 
 	DBG_ENTER_ROUTINE
 	
@@ -1277,7 +1278,8 @@
 	}
 
 	memset(php_ctlr, 0, sizeof(struct php_ctlr_state_s));
-
+	
+	pdev = dev->port;
 	php_ctlr->pci_dev = pdev;	/* save pci_dev in context */
 
 	dbg("%s: pdev->vendor %x pdev->device %x\n", __FUNCTION__,
@@ -1338,7 +1340,7 @@
 	}
 
 	dbg("pdev = %p: b:d:f:irq=0x%x:%x:%x:%x\n", pdev, pdev->bus->number, 
-		PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), pdev->irq);
+		PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), dev->irq);
 	for ( rc = 0; rc < DEVICE_COUNT_RESOURCE; rc++)
 		if (pci_resource_len(pdev, rc) > 0)
 			dbg("pci resource[%d] start=0x%lx(len=0x%lx)\n", rc,
@@ -1355,7 +1357,7 @@
 	init_waitqueue_head(&ctrl->queue);
 
 	/* find the IRQ */
-	php_ctlr->irq = pdev->irq;
+	php_ctlr->irq = dev->irq;
 	dbg("HPC interrupt = %d\n", php_ctlr->irq);
 
 	/* Save interrupt callback info */
@@ -1407,17 +1409,6 @@
 		start_int_poll_timer( php_ctlr, 10 );   /* start with 10 second delay */
 	} else {
 		/* Installs the interrupt handler */
-		dbg("%s: pcie_mch_quirk = %x\n", __FUNCTION__, pcie_mch_quirk);
-		if (!pcie_mch_quirk) {
-			rc = pci_enable_msi(pdev);
-			if (rc) {
-				info("Can't get msi for the hotplug controller\n");
-				info("Use INTx for the hotplug controller\n");
-				dbg("%s: rc = %x\n", __FUNCTION__, rc);
-			} else 
-				php_ctlr->irq = pdev->irq;
-		}
-
 		rc = request_irq(php_ctlr->irq, pcie_isr, SA_SHIRQ, MY_NAME, (void *) ctrl);
 		dbg("%s: request_irq %d for hpc%d (returns %d)\n", __FUNCTION__, php_ctlr->irq, ctlr_seq_num, rc);
 		if (rc) {
diff -Nru a/drivers/pci/hotplug/rpaphp.h b/drivers/pci/hotplug/rpaphp.h
--- a/drivers/pci/hotplug/rpaphp.h	2005-03-01 23:38:55 -08:00
+++ b/drivers/pci/hotplug/rpaphp.h	2005-03-01 23:38:55 -08:00
@@ -109,13 +109,6 @@
 extern struct list_head rpaphp_slot_head;
 extern int num_slots;
 
-static inline int is_hotplug_capable(struct device_node *dn)
-{
-	unsigned char *ptr = get_property(dn, "ibm,fw-pci-hot-plug-ctrl", NULL);
-
-	return (int) (ptr != NULL);
-}
-
 /* function prototypes */
 
 /* rpaphp_pci.c */
diff -Nru a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c
--- a/drivers/pci/hotplug/rpaphp_core.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/pci/hotplug/rpaphp_core.c	2005-03-01 23:39:17 -08:00
@@ -224,7 +224,7 @@
 
 	if (!indexes || !names || !types || !domains) {
 		/* Slot does not have dynamically-removable children */
-		return 1;
+		return -EINVAL;
 	}
 	if (drc_indexes)
 		*drc_indexes = indexes;
@@ -260,7 +260,7 @@
 	}
 
 	rc = get_children_props(dn->parent, &indexes, &names, &types, &domains);
-	if (rc) {
+	if (rc < 0) {
 		return 1;
 	}
 
@@ -287,26 +287,43 @@
 	return 1;
 }
 
-static int is_php_dn(struct device_node *dn, int **indexes, int **names, int **types,
-	  int **power_domains)
+static int is_php_type(char *drc_type)
+{
+	unsigned long value;
+	char *endptr;
+
+	/* PCI Hotplug nodes have an integer for drc_type */
+	value = simple_strtoul(drc_type, &endptr, 10);
+	if (endptr == drc_type)
+		return 0;
+
+	return 1;
+}
+
+static int is_php_dn(struct device_node *dn, int **indexes, int **names,
+		int **types, int **power_domains)
 {
+	int *drc_types;
 	int rc;
 
-	if (!is_hotplug_capable(dn))
-		return (0);
-	rc = get_children_props(dn, indexes, names, types, power_domains);
-	if (rc)
-		return (0);
-	return (1);
+	rc = get_children_props(dn, indexes, names, &drc_types, power_domains);
+	if (rc >= 0) {
+		if (is_php_type((char *) &drc_types[1])) {
+			*types = drc_types;
+			return 1;
+		}
+	}
+
+	return 0;
 }
 
-static int is_dr_dn(struct device_node *dn, int **indexes, int **names, int **types,
-	  int **power_domains, int **my_drc_index)
+static int is_dr_dn(struct device_node *dn, int **indexes, int **names,
+		int **types, int **power_domains, int **my_drc_index)
 {
 	int rc;
 
 	*my_drc_index = (int *) get_property(dn, "ibm,my-drc-index", NULL);
-	if(!*my_drc_index) 		
+	if(!*my_drc_index)
 		return (0);
 
 	if (!dn->parent)
@@ -314,7 +331,7 @@
 
 	rc = get_children_props(dn->parent, indexes, names, types,
 				power_domains);
-	return (rc == 0);
+	return (rc >= 0);
 }
 
 static inline int is_vdevice_root(struct device_node *dn)
diff -Nru a/drivers/pci/hotplug/rpaphp_pci.c b/drivers/pci/hotplug/rpaphp_pci.c
--- a/drivers/pci/hotplug/rpaphp_pci.c	2005-03-01 23:38:44 -08:00
+++ b/drivers/pci/hotplug/rpaphp_pci.c	2005-03-01 23:38:44 -08:00
@@ -25,6 +25,7 @@
 #include <linux/pci.h>
 #include <asm/pci-bridge.h>
 #include <asm/rtas.h>
+#include <asm/machdep.h>
 #include "../pci.h"		/* for pci_add_new_bus */
 
 #include "rpaphp.h"
@@ -168,6 +169,9 @@
 		if (list_empty(&dev->global_list)) {
 			int i;
 			
+			/* Need to setup IOMMU tables */
+			ppc_md.iommu_dev_setup(dev);
+
 			if(fix_bus)
 				pcibios_fixup_device_resources(dev, bus);
 			pci_read_irq_line(dev);
diff -Nru a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h
--- a/drivers/pci/hotplug/shpchp.h	2005-03-01 23:39:08 -08:00
+++ b/drivers/pci/hotplug/shpchp.h	2005-03-01 23:39:08 -08:00
@@ -36,7 +36,7 @@
 #include <asm/io.h>		
 #include "pci_hotplug.h"
 
-#if !defined(CONFIG_HOTPLUG_PCI_SHPC_MODULE)
+#if !defined(MODULE)
 	#define MY_NAME	"shpchp"
 #else
 	#define MY_NAME	THIS_MODULE->name
diff -Nru a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c
--- a/drivers/pci/hotplug/shpchp_core.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/pci/hotplug/shpchp_core.c	2005-03-01 23:39:18 -08:00
@@ -33,7 +33,6 @@
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/proc_fs.h>
-#include <linux/miscdevice.h>
 #include <linux/slab.h>
 #include <linux/workqueue.h>
 #include <linux/pci.h>
diff -Nru a/drivers/pci/hotplug/shpchprm_legacy.c b/drivers/pci/hotplug/shpchprm_legacy.c
--- a/drivers/pci/hotplug/shpchprm_legacy.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/pci/hotplug/shpchprm_legacy.c	2005-03-01 23:38:55 -08:00
@@ -41,16 +41,16 @@
 #include "shpchprm.h"
 #include "shpchprm_legacy.h"
 
-static void *shpchp_rom_start;
+static void __iomem *shpchp_rom_start;
 static u16 unused_IRQ;
 
-void shpchprm_cleanup()
+void shpchprm_cleanup(void)
 {
 	if (shpchp_rom_start)
 		iounmap(shpchp_rom_start);
 }
 
-int shpchprm_print_pirt()
+int shpchprm_print_pirt(void)
 {
 	return 0;
 }
@@ -64,10 +64,10 @@
 }
 
 /* Find the Hot Plug Resource Table in the specified region of memory */
-static void *detect_HRT_floating_pointer(void *begin, void *end)
+static void __iomem *detect_HRT_floating_pointer(void __iomem *begin, void __iomem *end)
 {
-	void *fp;
-	void *endp;
+	void __iomem *fp;
+	void __iomem *endp;
 	u8 temp1, temp2, temp3, temp4;
 	int status = 0;
 
@@ -104,7 +104,7 @@
 {
 	u8 populated_slot;
 	u8 bridged_slot;
-	void *one_slot;
+	void __iomem *one_slot;
 	struct pci_func *func = NULL;
 	int i = 10, index = 0;
 	u32 temp_dword, rc;
@@ -113,7 +113,7 @@
 	struct pci_resource *p_mem_node;
 	struct pci_resource *io_node;
 	struct pci_resource *bus_node;
-	void *rom_resource_table;
+	void __iomem *rom_resource_table;
 	struct pci_bus lpci_bus, *pci_bus;
 	u8 cfgspc_irq, temp;
 
@@ -413,7 +413,7 @@
 
 static int legacy_shpchprm_init_pci(void)
 {
-	shpchp_rom_start = (u8 *) ioremap(ROM_PHY_ADDR, ROM_PHY_LEN);
+	shpchp_rom_start = ioremap(ROM_PHY_ADDR, ROM_PHY_LEN);
 	if (!shpchp_rom_start) {
 		err("Could not ioremap memory region for ROM\n");
 		return -EIO;
diff -Nru a/drivers/pci/msi.c b/drivers/pci/msi.c
--- a/drivers/pci/msi.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/pci/msi.c	2005-03-01 23:39:16 -08:00
@@ -22,7 +22,7 @@
 
 #include "msi.h"
 
-static spinlock_t msi_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(msi_lock);
 static struct msi_desc* msi_desc[NR_IRQS] = { [0 ... NR_IRQS-1] = NULL };
 static kmem_cache_t* msi_cachep;
 
@@ -374,19 +374,18 @@
 
 	if ((status = msi_cache_init()) < 0) {
 		pci_msi_enable = 0;
-		printk(KERN_INFO "WARNING: MSI INIT FAILURE\n");
+		printk(KERN_WARNING "PCI: MSI cache init failed\n");
 		return status;
 	}
 	last_alloc_vector = assign_irq_vector(AUTO_ASSIGN);
 	if (last_alloc_vector < 0) {
 		pci_msi_enable = 0;
-		printk(KERN_INFO "WARNING: ALL VECTORS ARE BUSY\n");
+		printk(KERN_WARNING "PCI: No interrupt vectors available for MSI\n");
 		status = -EBUSY;
 		return status;
 	}
 	vector_irq[last_alloc_vector] = 0;
 	nr_released_vectors++;
-	printk(KERN_INFO "MSI INIT SUCCESS\n");
 
 	return status;
 }
@@ -736,7 +735,9 @@
 	/* Check whether driver already requested for MSI-X vectors */
    	if ((pos = pci_find_capability(dev, PCI_CAP_ID_MSIX)) > 0 &&
 		!msi_lookup_vector(dev, PCI_CAP_ID_MSIX)) {
-			printk(KERN_INFO "Can't enable MSI. Device already had MSI-X vectors assigned\n");
+			printk(KERN_INFO "PCI: %s: Can't enable MSI.  "
+			       "Device already has MSI-X vectors assigned\n",
+			       pci_name(dev));
 			dev->irq = temp;
 			return -EINVAL;
 	}
@@ -774,9 +775,9 @@
 	}
 	if (entry->msi_attrib.state) {
 		spin_unlock_irqrestore(&msi_lock, flags);
-		printk(KERN_DEBUG "Driver[%d:%d:%d] unloaded wo doing free_irq on vector->%d\n",
-		dev->bus->number, PCI_SLOT(dev->devfn),	PCI_FUNC(dev->devfn),
-		dev->irq);
+		printk(KERN_WARNING "PCI: %s: pci_disable_msi() called without "
+		       "free_irq() on MSI vector %d\n",
+		       pci_name(dev), dev->irq);
 		BUG_ON(entry->msi_attrib.state > 0);
 	} else {
 		vector_irq[dev->irq] = 0; /* free it */
@@ -982,7 +983,9 @@
 	/* Check whether driver already requested for MSI vector */
    	if (pci_find_capability(dev, PCI_CAP_ID_MSI) > 0 &&
 		!msi_lookup_vector(dev, PCI_CAP_ID_MSI)) {
-		printk(KERN_INFO "Can't enable MSI-X. Device already had MSI vector assigned\n");
+		printk(KERN_INFO "PCI: %s: Can't enable MSI-X.  "
+		       "Device already has an MSI vector assigned\n",
+		       pci_name(dev));
 		dev->irq = temp;
 		return -EINVAL;
 	}
@@ -1050,9 +1053,9 @@
 		spin_unlock_irqrestore(&msi_lock, flags);
 		if (warning) {
 			dev->irq = temp;
-			printk(KERN_DEBUG "Driver[%d:%d:%d] unloaded wo doing free_irq on all vectors\n",
-			dev->bus->number, PCI_SLOT(dev->devfn),
-			PCI_FUNC(dev->devfn));
+			printk(KERN_WARNING "PCI: %s: pci_disable_msix() called without "
+			       "free_irq() on all MSI-X vectors\n",
+			       pci_name(dev));
 			BUG_ON(warning > 0);
 		} else {
 			dev->irq = temp;
@@ -1088,9 +1091,9 @@
 		state = msi_desc[dev->irq]->msi_attrib.state;
 		spin_unlock_irqrestore(&msi_lock, flags);
 		if (state) {
-			printk(KERN_DEBUG "Driver[%d:%d:%d] unloaded wo doing free_irq on vector->%d\n",
-			dev->bus->number, PCI_SLOT(dev->devfn),
-			PCI_FUNC(dev->devfn), dev->irq);
+			printk(KERN_WARNING "PCI: %s: msi_remove_pci_irq_vectors() "
+			       "called without free_irq() on MSI vector %d\n",
+			       pci_name(dev), dev->irq);
 			BUG_ON(state > 0);
 		} else /* Release MSI vector assigned to this device */
 			msi_free_vector(dev, dev->irq, 0);
@@ -1132,9 +1135,9 @@
 			iounmap(base);
 			release_mem_region(phys_addr, PCI_MSIX_ENTRY_SIZE *
 				multi_msix_capable(control));
-			printk(KERN_DEBUG "Driver[%d:%d:%d] unloaded wo doing free_irq on all vectors\n",
-				dev->bus->number, PCI_SLOT(dev->devfn),
-				PCI_FUNC(dev->devfn));
+			printk(KERN_WARNING "PCI: %s: msi_remove_pci_irq_vectors() "
+			       "called without free_irq() on all MSI-X vectors\n",
+			       pci_name(dev));
 			BUG_ON(warning > 0);
 		}
 		dev->irq = temp;		/* Restore IOAPIC IRQ */
diff -Nru a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
--- a/drivers/pci/pci-driver.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/pci/pci-driver.c	2005-03-01 23:39:08 -08:00
@@ -284,27 +284,14 @@
 	return 0;
 }
 
-static int pci_device_suspend(struct device * dev, u32 state)
+static int pci_device_suspend(struct device * dev, pm_message_t state)
 {
 	struct pci_dev * pci_dev = to_pci_dev(dev);
 	struct pci_driver * drv = pci_dev->driver;
-	u32 dev_state;
 	int i = 0;
 
-	/* Translate PM_SUSPEND_xx states to PCI device states */
-	static u32 state_conversion[] = {
-		[PM_SUSPEND_ON] = 0,
-		[PM_SUSPEND_STANDBY] = 1,
-		[PM_SUSPEND_MEM] = 3,
-		[PM_SUSPEND_DISK] = 3,
-	};
-
-	if (state >= sizeof(state_conversion) / sizeof(state_conversion[1]))
-		return -EINVAL;
-
-	dev_state = state_conversion[state];
 	if (drv && drv->suspend)
-		i = drv->suspend(pci_dev, dev_state);
+		i = drv->suspend(pci_dev, state);
 	else
 		pci_save_state(pci_dev);
 	return i;
diff -Nru a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
--- a/drivers/pci/pci-sysfs.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/pci/pci-sysfs.c	2005-03-01 23:38:58 -08:00
@@ -20,6 +20,7 @@
 #include <linux/pci.h>
 #include <linux/stat.h>
 #include <linux/topology.h>
+#include <linux/mm.h>
 
 #include "pci.h"
 
@@ -178,6 +179,164 @@
 	return count;
 }
 
+#ifdef HAVE_PCI_LEGACY
+/**
+ * pci_read_legacy_io - read byte(s) from legacy I/O port space
+ * @kobj: kobject corresponding to file to read from
+ * @buf: buffer to store results
+ * @off: offset into legacy I/O port space
+ * @count: number of bytes to read
+ *
+ * Reads 1, 2, or 4 bytes from legacy I/O port space using an arch specific
+ * callback routine (pci_legacy_read).
+ */
+ssize_t
+pci_read_legacy_io(struct kobject *kobj, char *buf, loff_t off, size_t count)
+{
+        struct pci_bus *bus = to_pci_bus(container_of(kobj,
+                                                      struct class_device,
+						      kobj));
+
+        /* Only support 1, 2 or 4 byte accesses */
+        if (count != 1 && count != 2 && count != 4)
+                return -EINVAL;
+
+        return pci_legacy_read(bus, off, (u32 *)buf, count);
+}
+
+/**
+ * pci_write_legacy_io - write byte(s) to legacy I/O port space
+ * @kobj: kobject corresponding to file to read from
+ * @buf: buffer containing value to be written
+ * @off: offset into legacy I/O port space
+ * @count: number of bytes to write
+ *
+ * Writes 1, 2, or 4 bytes from legacy I/O port space using an arch specific
+ * callback routine (pci_legacy_write).
+ */
+ssize_t
+pci_write_legacy_io(struct kobject *kobj, char *buf, loff_t off, size_t count)
+{
+        struct pci_bus *bus = to_pci_bus(container_of(kobj,
+						      struct class_device,
+						      kobj));
+        /* Only support 1, 2 or 4 byte accesses */
+        if (count != 1 && count != 2 && count != 4)
+                return -EINVAL;
+
+        return pci_legacy_write(bus, off, *(u32 *)buf, count);
+}
+
+/**
+ * pci_mmap_legacy_mem - map legacy PCI memory into user memory space
+ * @kobj: kobject corresponding to device to be mapped
+ * @attr: struct bin_attribute for this file
+ * @vma: struct vm_area_struct passed to mmap
+ *
+ * Uses an arch specific callback, pci_mmap_legacy_page_range, to mmap
+ * legacy memory space (first meg of bus space) into application virtual
+ * memory space.
+ */
+int
+pci_mmap_legacy_mem(struct kobject *kobj, struct bin_attribute *attr,
+                    struct vm_area_struct *vma)
+{
+        struct pci_bus *bus = to_pci_bus(container_of(kobj,
+                                                      struct class_device,
+						      kobj));
+
+        return pci_mmap_legacy_page_range(bus, vma);
+}
+#endif /* HAVE_PCI_LEGACY */
+
+#ifdef HAVE_PCI_MMAP
+/**
+ * pci_mmap_resource - map a PCI resource into user memory space
+ * @kobj: kobject for mapping
+ * @attr: struct bin_attribute for the file being mapped
+ * @vma: struct vm_area_struct passed into the mmap
+ *
+ * Use the regular PCI mapping routines to map a PCI resource into userspace.
+ * FIXME: write combining?  maybe automatic for prefetchable regions?
+ */
+static int
+pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr,
+		  struct vm_area_struct *vma)
+{
+	struct pci_dev *pdev = to_pci_dev(container_of(kobj,
+						       struct device, kobj));
+	struct resource *res = (struct resource *)attr->private;
+	enum pci_mmap_state mmap_type;
+
+	vma->vm_pgoff += res->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);
+}
+
+/**
+ * pci_create_resource_files - create resource files in sysfs for @dev
+ * @dev: dev in question
+ *
+ * Walk the resources in @dev creating files for each resource available.
+ */
+static void
+pci_create_resource_files(struct pci_dev *pdev)
+{
+	int i;
+
+	/* Expose the PCI resources from this device as files */
+	for (i = 0; i < PCI_ROM_RESOURCE; i++) {
+		struct bin_attribute *res_attr;
+
+		/* skip empty resources */
+		if (!pci_resource_len(pdev, i))
+			continue;
+
+		res_attr = kmalloc(sizeof(*res_attr) + 10, GFP_ATOMIC);
+		if (res_attr) {
+			memset(res_attr, 0, sizeof(*res_attr) + 10);
+			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);
+			res_attr->attr.mode = S_IRUSR | S_IWUSR;
+			res_attr->attr.owner = THIS_MODULE;
+			res_attr->mmap = pci_mmap_resource;
+			res_attr->private = &pdev->resource[i];
+			sysfs_create_bin_file(&pdev->dev.kobj, res_attr);
+		}
+	}
+}
+
+/**
+ * pci_remove_resource_files - cleanup resource files
+ * @dev: dev to cleanup
+ *
+ * If we created resource files for @dev, remove them from sysfs and
+ * free their resources.
+ */
+static void
+pci_remove_resource_files(struct pci_dev *pdev)
+{
+	int i;
+
+	for (i = 0; i < PCI_ROM_RESOURCE; i++) {
+		struct bin_attribute *res_attr;
+
+		res_attr = pdev->res_attr[i];
+		if (res_attr) {
+			sysfs_remove_bin_file(&pdev->dev.kobj, res_attr);
+			kfree(res_attr);
+		}
+	}
+}
+#else /* !HAVE_PCI_MMAP */
+static inline void pci_create_resource_files(struct pci_dev *dev) { return; }
+static inline void pci_remove_resource_files(struct pci_dev *dev) { return; }
+#endif /* HAVE_PCI_MMAP */
+
 /**
  * pci_write_rom - used to enable access to the PCI ROM display
  * @kobj: kernel object handle
@@ -269,12 +428,15 @@
 	else
 		sysfs_create_bin_file(&pdev->dev.kobj, &pcie_config_attr);
 
+	pci_create_resource_files(pdev);
+
 	/* If the device has a ROM, try to expose it in sysfs. */
 	if (pci_resource_len(pdev, PCI_ROM_RESOURCE)) {
 		struct bin_attribute *rom_attr;
 		
 		rom_attr = kmalloc(sizeof(*rom_attr), GFP_ATOMIC);
 		if (rom_attr) {
+			memset(rom_attr, 0x00, sizeof(*rom_attr));
 			pdev->rom_attr = rom_attr;
 			rom_attr->size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
 			rom_attr->attr.name = "rom";
@@ -303,6 +465,8 @@
 		sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr);
 	else
 		sysfs_remove_bin_file(&pdev->dev.kobj, &pcie_config_attr);
+
+	pci_remove_resource_files(pdev);
 
 	if (pci_resource_len(pdev, PCI_ROM_RESOURCE)) {
 		if (pdev->rom_attr) {
diff -Nru a/drivers/pci/pci.c b/drivers/pci/pci.c
--- a/drivers/pci/pci.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/pci/pci.c	2005-03-01 23:38:54 -08:00
@@ -229,7 +229,7 @@
 /**
  * pci_set_power_state - Set the power state of a PCI device
  * @dev: PCI device to be suspended
- * @state: Power state we're entering
+ * @state: PCI power state (D0, D1, D2, D3hot, D3cold) we're entering
  *
  * Transition a device to a new power state, using the Power Management 
  * Capabilities in the device's config space.
@@ -242,19 +242,20 @@
  */
 
 int
-pci_set_power_state(struct pci_dev *dev, int state)
+pci_set_power_state(struct pci_dev *dev, pci_power_t state)
 {
 	int pm;
-	u16 pmcsr;
+	u16 pmcsr, pmc;
 
 	/* bound the state we're entering */
-	if (state > 3) state = 3;
+	if (state > PCI_D3hot)
+		state = PCI_D3hot;
 
 	/* Validate current state:
 	 * Can enter D0 from any state, but if we can only go deeper 
 	 * to sleep if we're already in a low power state
 	 */
-	if (state > 0 && dev->current_state > state)
+	if (state != PCI_D0 && dev->current_state > state)
 		return -EINVAL;
 	else if (dev->current_state == state) 
 		return 0;        /* we're already there */
@@ -263,21 +264,30 @@
 	pm = pci_find_capability(dev, PCI_CAP_ID_PM);
 	
 	/* abort if the device doesn't support PM capabilities */
-	if (!pm) return -EIO; 
+	if (!pm)
+		return -EIO; 
+
+	pci_read_config_word(dev,pm + PCI_PM_PMC,&pmc);
+	if ((pmc & PCI_PM_CAP_VER_MASK) > 2) {
+		printk(KERN_DEBUG
+		       "PCI: %s has unsupported PM cap regs version (%u)\n",
+		       dev->slot_name, pmc & PCI_PM_CAP_VER_MASK);
+		return -EIO;
+	}
 
 	/* check if this device supports the desired state */
-	if (state == 1 || state == 2) {
-		u16 pmc;
-		pci_read_config_word(dev,pm + PCI_PM_PMC,&pmc);
-		if (state == 1 && !(pmc & PCI_PM_CAP_D1)) return -EIO;
-		else if (state == 2 && !(pmc & PCI_PM_CAP_D2)) return -EIO;
+	if (state == PCI_D1 || state == PCI_D2) {
+		if (state == PCI_D1 && !(pmc & PCI_PM_CAP_D1))
+			return -EIO;
+		else if (state == PCI_D2 && !(pmc & PCI_PM_CAP_D2))
+			return -EIO;
 	}
 
 	/* If we're in D3, force entire word to 0.
 	 * This doesn't affect PME_Status, disables PME_En, and
 	 * sets PowerState to 0.
 	 */
-	if (dev->current_state >= 3)
+	if (dev->current_state >= PCI_D3hot)
 		pmcsr = 0;
 	else {
 		pci_read_config_word(dev, pm + PCI_PM_CTRL, &pmcsr);
@@ -290,9 +300,9 @@
 
 	/* Mandatory power management transition delays */
 	/* see PCI PM 1.1 5.6.1 table 18 */
-	if(state == 3 || dev->current_state == 3)
+	if (state == PCI_D3hot || dev->current_state == PCI_D3hot)
 		msleep(10);
-	else if(state == 2 || dev->current_state == 2)
+	else if (state == PCI_D2 || dev->current_state == PCI_D2)
 		udelay(200);
 	dev->current_state = state;
 
@@ -300,6 +310,31 @@
 }
 
 /**
+ * pci_choose_state - Choose the power state of a PCI device
+ * @dev: PCI device to be suspended
+ * @state: target sleep state for the whole system
+ *
+ * Returns PCI power state suitable for given device and given system
+ * message.
+ */
+
+pci_power_t pci_choose_state(struct pci_dev *dev, u32 state)
+{
+	if (!pci_find_capability(dev, PCI_CAP_ID_PM))
+		return PCI_D0;
+
+	switch (state) {
+	case 0:	return PCI_D0;
+	case 2: return PCI_D2;
+	case 3: return PCI_D3hot;
+	default: BUG();
+	}
+	return PCI_D0;
+}
+
+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
@@ -348,7 +383,7 @@
 {
 	int err;
 
-	pci_set_power_state(dev, 0);
+	pci_set_power_state(dev, PCI_D0);
 	if ((err = pcibios_enable_device(dev, bars)) < 0)
 		return err;
 	return 0;
@@ -422,7 +457,7 @@
  * 0 if operation is successful.
  * 
  */
-int pci_enable_wake(struct pci_dev *dev, u32 state, int enable)
+int pci_enable_wake(struct pci_dev *dev, pci_power_t state, int enable)
 {
 	int pm;
 	u16 value;
diff -Nru a/drivers/pci/pci.h b/drivers/pci/pci.h
--- a/drivers/pci/pci.h	2005-03-01 23:38:55 -08:00
+++ b/drivers/pci/pci.h	2005-03-01 23:38:55 -08:00
@@ -59,12 +59,14 @@
 extern int pci_visit_dev(struct pci_visit *fn,
 			 struct pci_dev_wrapped *wrapped_dev,
 			 struct pci_bus_wrapped *wrapped_parent);
+extern void pci_remove_legacy_files(struct pci_bus *bus);
 
 /* Lock for read/write access to pci device and bus lists */
 extern spinlock_t pci_bus_lock;
 
 extern int pcie_mch_quirk;
 extern struct device_attribute pci_dev_attrs[];
+extern struct class_device_attribute class_device_attr_cpuaffinity;
 
 /**
  * pci_match_one_device - Tell if a PCI device structure has a matching
diff -Nru a/drivers/pci/pci.ids b/drivers/pci/pci.ids
--- a/drivers/pci/pci.ids	2005-03-01 23:38:57 -08:00
+++ b/drivers/pci/pci.ids	2005-03-01 23:38:57 -08:00
@@ -4433,6 +4433,7 @@
 11ab  Marvell Technology Group Ltd.
 	0146  GT-64010/64010A System Controller
 	1fa6  Marvell W8300 802.11 Adapter
+	4146  GT-64011/GT-64111 System Controller
 	4320  Yukon Gigabit Ethernet 10/100/1000Base-T Adapter
 	4611  GT-64115 System Controller
 	4620  GT-64120/64120A/64121A System Controller
@@ -8088,6 +8089,7 @@
 	24c0  82801DB/DBL (ICH4/ICH4-L) LPC Bridge
 		1014 0267  NetVista A30p
 		1462 5800  845PE Max (MS-6580)
+	24c1  82801DBL (ICH4-L) IDE Controller
 	24c2  82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #1
 		1014 0267  NetVista A30p
 		1071 8160  MIM2000
diff -Nru a/drivers/pci/pcie/Kconfig b/drivers/pci/pcie/Kconfig
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/pci/pcie/Kconfig	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,38 @@
+#
+# PCI Express Port Bus Configuration
+#
+config PCIEPORTBUS
+	bool "PCI Express support"
+	depends on PCI_GOMMCONFIG || PCI_GOANY
+	default n
+
+	---help---
+	This automatically enables PCI Express Port Bus support. Users can
+	choose Native Hot-Plug support, Advanced Error Reporting support,
+	Power Management Event support and Virtual Channel support to run
+	on PCI Express Ports (Root or Switch).
+
+#
+# Include service Kconfig here
+#
+config HOTPLUG_PCI_PCIE
+	tristate "PCI Express Hotplug driver"
+	depends on HOTPLUG_PCI && PCIEPORTBUS
+	help
+	  Say Y here if you have a motherboard that supports PCI Express Native
+	  Hotplug
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called pciehp.
+
+	  When in doubt, say N.
+
+config HOTPLUG_PCI_PCIE_POLL_EVENT_MODE
+	bool "Use polling mechanism for hot-plug events (for testing purpose)"
+	depends on HOTPLUG_PCI_PCIE
+	help
+	  Say Y here if you want to use the polling mechanism for hot-plug 
+	  events for early platform testing.
+	   
+	  When in doubt, say N.
+
diff -Nru a/drivers/pci/pcie/Makefile b/drivers/pci/pcie/Makefile
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/pci/pcie/Makefile	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,7 @@
+#
+# Makefile for PCI-Express PORT Driver
+#
+
+pcieportdrv-y			:= portdrv_core.o portdrv_pci.o portdrv_bus.o
+
+obj-$(CONFIG_PCIEPORTBUS)	+= pcieportdrv.o
diff -Nru a/drivers/pci/pcie/portdrv.h b/drivers/pci/pcie/portdrv.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/pci/pcie/portdrv.h	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,41 @@
+/*
+ * File:	portdrv.h
+ * Purpose:	PCI Express Port Bus Driver's Internal Data Structures
+ *
+ * Copyright (C) 2004 Intel
+ * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com)
+ */
+
+#ifndef _PORTDRV_H_
+#define _PORTDRV_H_
+
+#if !defined(PCI_CAP_ID_PME)
+#define PCI_CAP_ID_PME			1
+#endif
+
+#if !defined(PCI_CAP_ID_EXP)
+#define PCI_CAP_ID_EXP			0x10
+#endif
+
+#define PORT_TYPE_MASK			0xf
+#define PORT_TO_SLOT_MASK		0x100
+#define SLOT_HP_CAPABLE_MASK		0x40
+#define PCIE_CAPABILITIES_REG		0x2
+#define PCIE_SLOT_CAPABILITIES_REG	0x14
+#define PCIE_PORT_DEVICE_MAXSERVICES	4
+#define PCI_CFG_SPACE_SIZE		256
+
+#define get_descriptor_id(type, service) (((type - 4) << 4) | service)
+
+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);
+#ifdef CONFIG_PM
+extern int pcie_port_device_suspend(struct pci_dev *dev, u32 state);
+extern int pcie_port_device_resume(struct pci_dev *dev);
+#endif
+extern void pcie_port_device_remove(struct pci_dev *dev);
+extern void pcie_port_bus_register(void);
+extern void pcie_port_bus_unregister(void);
+
+#endif /* _PORTDRV_H_ */
diff -Nru a/drivers/pci/pcie/portdrv_bus.c b/drivers/pci/pcie/portdrv_bus.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/pci/pcie/portdrv_bus.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,77 @@
+/*
+ * File:	portdrv_bus.c
+ * Purpose:	PCI Express Port Bus Driver's Bus Overloading Functions
+ *
+ * Copyright (C) 2004 Intel
+ * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com)
+ */
+
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/pm.h>
+
+#include <linux/pcieport_if.h>
+
+static int pcie_port_bus_match(struct device *dev, struct device_driver *drv);
+static int pcie_port_bus_suspend(struct device *dev, u32 state);
+static int pcie_port_bus_resume(struct device *dev);
+
+struct bus_type pcie_port_bus_type = {
+	.name 		= "pci_express",
+	.match 		= pcie_port_bus_match,
+	.suspend	= pcie_port_bus_suspend,
+	.resume		= pcie_port_bus_resume, 
+};
+
+static int pcie_port_bus_match(struct device *dev, struct device_driver *drv)
+{
+	struct pcie_device *pciedev;
+	struct pcie_port_service_driver *driver;
+
+	if (drv->bus != &pcie_port_bus_type || dev->bus != &pcie_port_bus_type)
+		return 0;
+	
+	pciedev = to_pcie_device(dev);
+	driver = to_service_driver(drv);
+	if (   (driver->id_table->vendor != PCI_ANY_ID && 
+		driver->id_table->vendor != pciedev->id.vendor) ||
+	       (driver->id_table->device != PCI_ANY_ID &&
+		driver->id_table->device != pciedev->id.device) ||	
+		driver->id_table->port_type != pciedev->id.port_type ||
+		driver->id_table->service_type != pciedev->id.service_type )
+		return 0;
+
+	return 1;
+}
+
+static int pcie_port_bus_suspend(struct device *dev, u32 state)
+{
+	struct pcie_device *pciedev;
+	struct pcie_port_service_driver *driver;
+
+	if (!dev || !dev->driver)
+		return 0;
+
+	pciedev = to_pcie_device(dev);
+ 	driver = to_service_driver(dev->driver);
+	if (driver && driver->suspend)
+		driver->suspend(pciedev, state);
+	return 0;
+}
+
+static int pcie_port_bus_resume(struct device *dev)
+{
+	struct pcie_device *pciedev;
+	struct pcie_port_service_driver *driver;
+
+	if (!dev || !dev->driver)
+		return 0;
+
+	pciedev = to_pcie_device(dev);
+ 	driver = to_service_driver(dev->driver);
+	if (driver && driver->resume)
+		driver->resume(pciedev);
+	return 0;
+}
diff -Nru a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/pci/pcie/portdrv_core.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,434 @@
+/*
+ * File:	portdrv_core.c
+ * Purpose:	PCI Express Port Bus Driver's Core Functions
+ *
+ * Copyright (C) 2004 Intel
+ * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com)
+ */
+
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/pm.h>
+#include <linux/pcieport_if.h>
+
+#include "portdrv.h"
+
+extern int pcie_mch_quirk;	/* MSI-quirk Indicator */
+
+static int pcie_port_probe_service(struct device *dev)
+{
+	struct pcie_device *pciedev;
+	struct pcie_port_service_driver *driver;
+	int status = -ENODEV;
+
+	if (!dev || !dev->driver)
+		return status;
+
+ 	driver = to_service_driver(dev->driver);
+	if (!driver || !driver->probe)
+		return status;
+
+	pciedev = to_pcie_device(dev);
+	status = driver->probe(pciedev, driver->id_table);
+	if (!status) {
+		printk(KERN_DEBUG "Load service driver %s on pcie device %s\n",
+			driver->name, dev->bus_id);
+		get_device(dev);
+	}
+	return status;
+}
+
+static int pcie_port_remove_service(struct device *dev)
+{
+	struct pcie_device *pciedev;
+	struct pcie_port_service_driver *driver;
+
+	if (!dev || !dev->driver)
+		return 0;
+
+	pciedev = to_pcie_device(dev);
+ 	driver = to_service_driver(dev->driver);
+	if (driver && driver->remove) { 
+		printk(KERN_DEBUG "Unload service driver %s on pcie device %s\n",
+			driver->name, dev->bus_id);
+		driver->remove(pciedev);
+		put_device(dev);
+	}
+	return 0;
+}
+
+static void pcie_port_shutdown_service(struct device *dev) {}
+
+static int pcie_port_suspend_service(struct device *dev, u32 state, u32 level)
+{
+	struct pcie_device *pciedev;
+	struct pcie_port_service_driver *driver;
+
+	if (!dev || !dev->driver)
+		return 0;
+
+	pciedev = to_pcie_device(dev);
+ 	driver = to_service_driver(dev->driver);
+	if (driver && driver->suspend)
+		driver->suspend(pciedev, state);
+	return 0;
+}
+
+static int pcie_port_resume_service(struct device *dev, u32 state)
+{
+	struct pcie_device *pciedev;
+	struct pcie_port_service_driver *driver;
+
+	if (!dev || !dev->driver)
+		return 0;
+
+	pciedev = to_pcie_device(dev);
+ 	driver = to_service_driver(dev->driver);
+
+	if (driver && driver->resume)
+		driver->resume(pciedev);
+	return 0;
+}
+
+/*
+ * release_pcie_device
+ *	
+ *	Being invoked automatically when device is being removed 
+ *	in response to device_unregister(dev) call.
+ *	Release all resources being claimed.
+ */
+static void release_pcie_device(struct device *dev)
+{
+	printk(KERN_DEBUG "Free Port Service[%s]\n", dev->bus_id);
+	kfree(to_pcie_device(dev));			
+}
+
+static int is_msi_quirked(struct pci_dev *dev)
+{
+	int port_type, quirk = 0;
+	u16 reg16;
+
+	pci_read_config_word(dev, 
+		pci_find_capability(dev, PCI_CAP_ID_EXP) + 
+		PCIE_CAPABILITIES_REG, &reg16);
+	port_type = (reg16 >> 4) & PORT_TYPE_MASK;
+	switch(port_type) {
+	case PCIE_RC_PORT:
+		if (pcie_mch_quirk == 1)
+			quirk = 1;
+		break;
+	case PCIE_SW_UPSTREAM_PORT:
+	case PCIE_SW_DOWNSTREAM_PORT:
+	default:
+		break;	
+	}
+	return quirk;
+}
+	
+static int assign_interrupt_mode(struct pci_dev *dev, int *vectors, int mask)
+{
+	int i, pos, nvec, status = -EINVAL;
+	int interrupt_mode = PCIE_PORT_INTx_MODE;
+
+	/* Set INTx as default */
+	for (i = 0, nvec = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) {
+		if (mask & (1 << i)) 
+			nvec++;
+		vectors[i] = dev->irq;
+	}
+	
+	/* Check MSI quirk */
+	if (is_msi_quirked(dev))
+		return interrupt_mode;
+
+	/* Select MSI-X over MSI if supported */		
+	pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
+	if (pos) {
+		struct msix_entry msix_entries[PCIE_PORT_DEVICE_MAXSERVICES] = 
+			{{0, 0}, {0, 1}, {0, 2}, {0, 3}};
+		printk("%s Found MSIX capability\n", __FUNCTION__);
+		status = pci_enable_msix(dev, msix_entries, nvec);
+		if (!status) {
+			int j = 0;
+
+			interrupt_mode = PCIE_PORT_MSIX_MODE;
+			for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) {
+				if (mask & (1 << i)) 
+					vectors[i] = msix_entries[j++].vector;
+			}
+		}
+	} 
+	if (status) {
+		pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
+		if (pos) {
+			printk("%s Found MSI capability\n", __FUNCTION__);
+			status = pci_enable_msi(dev);
+			if (!status) {
+				interrupt_mode = PCIE_PORT_MSI_MODE;
+				for (i = 0;i < PCIE_PORT_DEVICE_MAXSERVICES;i++)
+					vectors[i] = dev->irq;
+			}
+		}
+	} 
+	return interrupt_mode;
+}
+
+static int get_port_device_capability(struct pci_dev *dev)
+{
+	int services = 0, pos;
+	u16 reg16;
+	u32 reg32;
+
+	pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
+	pci_read_config_word(dev, pos + PCIE_CAPABILITIES_REG, &reg16);
+	/* Hot-Plug Capable */
+	if (reg16 & PORT_TO_SLOT_MASK) {
+		pci_read_config_dword(dev, 
+			pos + PCIE_SLOT_CAPABILITIES_REG, &reg32);
+		if (reg32 & SLOT_HP_CAPABLE_MASK)
+			services |= PCIE_PORT_SERVICE_HP;
+	} 
+	/* PME Capable */
+	pos = pci_find_capability(dev, PCI_CAP_ID_PME);
+	if (pos) 
+		services |= PCIE_PORT_SERVICE_PME;
+	
+	pos = PCI_CFG_SPACE_SIZE;
+	while (pos) {
+		pci_read_config_dword(dev, pos, &reg32);
+		switch (reg32 & 0xffff) {
+		case PCI_EXT_CAP_ID_ERR:
+			services |= PCIE_PORT_SERVICE_AER;
+			pos = reg32 >> 20;
+			break;
+		case PCI_EXT_CAP_ID_VC:
+			services |= PCIE_PORT_SERVICE_VC;
+			pos = reg32 >> 20;
+			break;
+		default:
+			pos = 0;
+			break;
+		}
+	}
+
+	return services;
+}
+
+static void pcie_device_init(struct pci_dev *parent, struct pcie_device *dev, 
+	int port_type, int service_type, int irq, int irq_mode)
+{
+	struct device *device;
+
+	dev->port = parent;
+	dev->interrupt_mode = irq_mode;
+	dev->irq = irq;
+	dev->id.vendor = parent->vendor;
+	dev->id.device = parent->device;
+	dev->id.port_type = port_type;
+	dev->id.service_type = (1 << service_type);
+
+	/* 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->release = release_pcie_device;	/* callback to free pcie dev */
+	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, 
+	int port_type, int service_type, int irq, int irq_mode)
+{
+	struct pcie_device *device;
+
+	device = kmalloc(sizeof(struct pcie_device), GFP_KERNEL);
+	if (!device)
+		return NULL;
+
+	memset(device, 0, sizeof(struct pcie_device));
+	pcie_device_init(parent, device, port_type, service_type, irq,irq_mode);
+	printk(KERN_DEBUG "Allocate Port Service[%s]\n", device->device.bus_id);
+	return device;
+}
+
+int pcie_port_device_probe(struct pci_dev *dev)
+{
+	int pos, type;
+	u16 reg;
+
+	if (!(pos = pci_find_capability(dev, PCI_CAP_ID_EXP)))
+		return -ENODEV;
+
+	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 )  
+		return 0;
+ 
+	return -ENODEV;
+}
+
+int pcie_port_device_register(struct pci_dev *dev)
+{
+	int status, type, capabilities, irq_mode, i;
+	int vectors[PCIE_PORT_DEVICE_MAXSERVICES];
+	u16 reg16;
+
+	/* Get port type */
+	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);
+
+	/* Allocate child services if any */
+	for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) {
+		struct pcie_device *child;
+
+		if (capabilities & (1 << i)) {
+			child = alloc_pcie_device(
+				dev, 		/* parent */
+				type,		/* port type */ 
+				i,		/* service type */
+				vectors[i],	/* irq */
+				irq_mode	/* interrupt mode */);
+			if (child) { 
+				status = device_register(&child->device);
+				if (status) {
+					kfree(child);
+					continue;
+				}
+				get_device(&child->device);
+			}
+		}
+	}
+	return 0;
+}
+
+#ifdef CONFIG_PM
+int pcie_port_device_suspend(struct pci_dev *dev, u32 state)
+{
+	struct list_head 		*head, *tmp;
+	struct device 			*parent, *child;
+	struct device_driver 		*driver;
+	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->suspend)  
+			service_driver->suspend(to_pcie_device(child), state);
+	}
+	return 0; 
+}
+
+int pcie_port_device_resume(struct pci_dev *dev) 
+{ 
+	struct list_head 		*head, *tmp;
+	struct device 			*parent, *child;
+	struct device_driver 		*driver;
+	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));
+	}
+	return 0; 
+
+}
+#endif
+
+void pcie_port_device_remove(struct pci_dev *dev)
+{
+	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));
+		}
+		interrupt_mode = (to_pcie_device(child))->interrupt_mode;
+		put_device(child);
+		device_unregister(child);
+	}
+	/* Switch to INTx by default if MSI enabled */
+	if (interrupt_mode == PCIE_PORT_MSIX_MODE)
+		pci_disable_msix(dev);
+	else if (interrupt_mode == PCIE_PORT_MSI_MODE)
+		pci_disable_msi(dev);
+}
+
+void pcie_port_bus_register(void)
+{
+	bus_register(&pcie_port_bus_type);
+}
+
+void pcie_port_bus_unregister(void)
+{
+	bus_unregister(&pcie_port_bus_type);
+}
+
+int pcie_port_service_register(struct pcie_port_service_driver *new)
+{
+	new->driver.name = (char *)new->name;
+	new->driver.bus = &pcie_port_bus_type;
+	new->driver.probe = pcie_port_probe_service;
+	new->driver.remove = pcie_port_remove_service;
+	new->driver.shutdown = pcie_port_shutdown_service;
+	new->driver.suspend = pcie_port_suspend_service;
+	new->driver.resume = pcie_port_resume_service;
+
+	return driver_register(&new->driver);
+} 
+
+void pcie_port_service_unregister(struct pcie_port_service_driver *new)
+{
+	driver_unregister(&new->driver);
+}
+
+EXPORT_SYMBOL(pcie_port_service_register);
+EXPORT_SYMBOL(pcie_port_service_unregister);
diff -Nru a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/pci/pcie/portdrv_pci.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,122 @@
+/*
+ * File:	portdrv_pci.c
+ * Purpose:	PCI Express Port Bus Driver
+ *
+ * Copyright (C) 2004 Intel
+ * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com)
+ */
+
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/pm.h>
+#include <linux/init.h>
+#include <linux/pcieport_if.h>
+
+#include "portdrv.h"
+
+/*
+ * Version Information
+ */
+#define DRIVER_VERSION "v1.0"
+#define DRIVER_AUTHOR "tom.l.nguyen@intel.com"
+#define DRIVER_DESC "PCIE Port Bus Driver"
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+
+/* global data */
+static const char device_name[] = "pcieport-driver";
+
+/*
+ * pcie_portdrv_probe - Probe PCI-Express port devices
+ * @dev: PCI-Express port device being probed
+ *
+ * If detected invokes the pcie_port_device_register() method for 
+ * this port device.
+ *
+ */
+static int __devinit pcie_portdrv_probe (struct pci_dev *dev, 
+				const struct pci_device_id *id )
+{
+	int			status;
+
+	status = pcie_port_device_probe(dev);
+	if (status)
+		return status;
+
+	if (pci_enable_device(dev) < 0) 
+		return -ENODEV;
+	
+	pci_set_master(dev);
+        if (!dev->irq) {
+		printk(KERN_WARNING 
+		"%s->Dev[%04x:%04x] has invalid IRQ. Check vendor BIOS\n", 
+		__FUNCTION__, dev->device, dev->vendor);
+	}
+	if (pcie_port_device_register(dev)) 
+		return -ENOMEM;
+
+	return 0;
+}
+
+static void pcie_portdrv_remove (struct pci_dev *dev)
+{
+	pcie_port_device_remove(dev);
+}
+
+#ifdef CONFIG_PM
+static int pcie_portdrv_suspend (struct pci_dev *dev, u32 state)
+{
+	return pcie_port_device_suspend(dev, state);
+}
+
+static int pcie_portdrv_resume (struct pci_dev *dev)
+{
+	return pcie_port_device_resume(dev);
+}
+#endif
+
+/*
+ * LINUX Device Driver Model
+ */
+static const struct pci_device_id port_pci_ids[] = { {
+	/* handle any PCI-Express port */
+	PCI_DEVICE_CLASS(((PCI_CLASS_BRIDGE_PCI << 8) | 0x00), ~0),
+	}, { /* end: all zeroes */ }
+};
+MODULE_DEVICE_TABLE(pci, port_pci_ids);
+
+static struct pci_driver pcie_portdrv = {
+	.name		= (char *)device_name,
+	.id_table	= &port_pci_ids[0],
+
+	.probe		= pcie_portdrv_probe,
+	.remove		= pcie_portdrv_remove,
+
+#ifdef	CONFIG_PM
+	.suspend	= pcie_portdrv_suspend,
+	.resume		= pcie_portdrv_resume,
+#endif	/* PM */
+};
+
+static int __init pcie_portdrv_init(void)
+{
+	int retval = 0;
+
+	pcie_port_bus_register();
+	retval = pci_module_init(&pcie_portdrv);
+	if (retval)
+		pcie_port_bus_unregister();
+	return retval;
+}
+
+static void __exit pcie_portdrv_exit(void) 
+{
+	pci_unregister_driver(&pcie_portdrv);
+	pcie_port_bus_unregister();
+}
+
+module_init(pcie_portdrv_init);
+module_exit(pcie_portdrv_exit);
diff -Nru a/drivers/pci/probe.c b/drivers/pci/probe.c
--- a/drivers/pci/probe.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/pci/probe.c	2005-03-01 23:39:08 -08:00
@@ -2,6 +2,7 @@
  * probe.c - PCI detection and setup code
  */
 
+#include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/slab.h>
@@ -27,12 +28,73 @@
 
 LIST_HEAD(pci_devices);
 
+#ifdef HAVE_PCI_LEGACY
+/**
+ * pci_create_legacy_files - create legacy I/O port and memory files
+ * @b: bus to create files under
+ *
+ * Some platforms allow access to legacy I/O port and ISA memory space on
+ * a per-bus basis.  This routine creates the files and ties them into
+ * their associated read, write and mmap files from pci-sysfs.c
+ */
+static void pci_create_legacy_files(struct pci_bus *b)
+{
+	b->legacy_io = kmalloc(sizeof(struct bin_attribute) * 2,
+			       GFP_ATOMIC);
+	if (b->legacy_io) {
+		memset(b->legacy_io, 0, sizeof(struct bin_attribute) * 2);
+		b->legacy_io->attr.name = "legacy_io";
+		b->legacy_io->size = 0xffff;
+		b->legacy_io->attr.mode = S_IRUSR | S_IWUSR;
+		b->legacy_io->attr.owner = THIS_MODULE;
+		b->legacy_io->read = pci_read_legacy_io;
+		b->legacy_io->write = pci_write_legacy_io;
+		class_device_create_bin_file(&b->class_dev, b->legacy_io);
+
+		/* Allocated above after the legacy_io struct */
+		b->legacy_mem = b->legacy_io + 1;
+		b->legacy_mem->attr.name = "legacy_mem";
+		b->legacy_mem->size = 1024*1024;
+		b->legacy_mem->attr.mode = S_IRUSR | S_IWUSR;
+		b->legacy_mem->attr.owner = THIS_MODULE;
+		b->legacy_mem->mmap = pci_mmap_legacy_mem;
+		class_device_create_bin_file(&b->class_dev, b->legacy_mem);
+	}
+}
+
+void pci_remove_legacy_files(struct pci_bus *b)
+{
+	class_device_remove_bin_file(&b->class_dev, b->legacy_io);
+	class_device_remove_bin_file(&b->class_dev, b->legacy_mem);
+	kfree(b->legacy_io); /* both are allocated here */
+}
+#else /* !HAVE_PCI_LEGACY */
+static inline void pci_create_legacy_files(struct pci_bus *bus) { return; }
+void pci_remove_legacy_files(struct pci_bus *bus) { return; }
+#endif /* HAVE_PCI_LEGACY */
+
+/*
+ * PCI Bus Class Devices
+ */
+static ssize_t pci_bus_show_cpuaffinity(struct class_device *class_dev, char *buf)
+{
+	cpumask_t cpumask = pcibus_to_cpumask((to_pci_bus(class_dev))->number);
+	int ret;
+
+	ret = cpumask_scnprintf(buf, PAGE_SIZE, cpumask);
+	if (ret < PAGE_SIZE)
+		buf[ret++] = '\n';
+	return ret;
+}
+CLASS_DEVICE_ATTR(cpuaffinity, S_IRUGO, pci_bus_show_cpuaffinity, NULL);
+
 /*
  * PCI Bus Class
  */
 static void release_pcibus_dev(struct class_device *class_dev)
 {
 	struct pci_bus *pci_bus = to_pci_bus(class_dev);
+
 	if (pci_bus->bridge)
 		put_device(pci_bus->bridge);
 	kfree(pci_bus);
@@ -50,21 +112,6 @@
 postcore_initcall(pcibus_class_init);
 
 /*
- * PCI Bus Class Devices
- */
-static ssize_t pci_bus_show_cpuaffinity(struct class_device *class_dev, char *buf)
-{
-	cpumask_t cpumask = pcibus_to_cpumask((to_pci_bus(class_dev))->number);
-	int ret;
-
-	ret = cpumask_scnprintf(buf, PAGE_SIZE, cpumask);
-	if (ret < PAGE_SIZE)
-		buf[ret++] = '\n';
-	return ret;
-}
-static CLASS_DEVICE_ATTR(cpuaffinity, S_IRUGO, pci_bus_show_cpuaffinity, NULL);
-
-/*
  * Translate the low bits of the PCI base
  * to the resource type
  */
@@ -336,6 +383,22 @@
 	return child;
 }
 
+static void pci_enable_crs(struct pci_dev *dev)
+{
+	u16 cap, rpctl;
+	int rpcap = pci_find_capability(dev, PCI_CAP_ID_EXP);
+	if (!rpcap)
+		return;
+
+	pci_read_config_word(dev, rpcap + PCI_CAP_FLAGS, &cap);
+	if (((cap & PCI_EXP_FLAGS_TYPE) >> 4) != PCI_EXP_TYPE_ROOT_PORT)
+		return;
+
+	pci_read_config_word(dev, rpcap + PCI_EXP_RTCTL, &rpctl);
+	rpctl |= PCI_EXP_RTCTL_CRSSVE;
+	pci_write_config_word(dev, rpcap + PCI_EXP_RTCTL, rpctl);
+}
+
 unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus);
 
 /*
@@ -366,6 +429,8 @@
 	pci_write_config_word(dev, PCI_BRIDGE_CONTROL,
 			      bctl & ~PCI_BRIDGE_CTL_MASTER_ABORT);
 
+	pci_enable_crs(dev);
+
 	if ((buses & 0xffff00) && !pcibios_assign_all_busses() && !is_cardbus) {
 		unsigned int cmax, busnr;
 		/*
@@ -375,6 +440,17 @@
 		if (pass)
 			return max;
 		busnr = (buses >> 8) & 0xFF;
+
+		/*
+		 * If we already got to this bus through a different bridge,
+		 * ignore it.  This can happen with the i450NX chipset.
+		 */
+		if (pci_find_bus(pci_domain_nr(bus), busnr)) {
+			printk(KERN_INFO "PCI: Bus %04x:%02x already known\n",
+					pci_domain_nr(bus), busnr);
+			return max;
+		}
+
 		child = pci_alloc_child_bus(bus, dev, busnr);
 		if (!child)
 			return max;
@@ -490,6 +566,7 @@
 
 	/* Early fixups, before probing the BARs */
 	pci_fixup_device(pci_fixup_early, dev);
+	class = dev->class >> 8;
 
 	switch (dev->hdr_type) {		    /* header type */
 	case PCI_HEADER_TYPE_NORMAL:		    /* standard header */
@@ -602,9 +679,7 @@
 	struct pci_dev *dev;
 	u32 l;
 	u8 hdr_type;
-
-	if (pci_bus_read_config_byte(bus, devfn, PCI_HEADER_TYPE, &hdr_type))
-		return NULL;
+	int delay = 1;
 
 	if (pci_bus_read_config_dword(bus, devfn, PCI_VENDOR_ID, &l))
 		return NULL;
@@ -614,6 +689,25 @@
 	    l == 0x0000ffff || l == 0xffff0000)
 		return NULL;
 
+	/* Configuration request Retry Status */
+	while (l == 0xffff0001) {
+		msleep(delay);
+		delay *= 2;
+		if (pci_bus_read_config_dword(bus, devfn, PCI_VENDOR_ID, &l))
+			return NULL;
+		/* Card hasn't responded in 60 seconds?  Must be stuck. */
+		if (delay > 60 * 1000) {
+			printk(KERN_WARNING "Device %04x:%02x:%02x.%d not "
+					"responding\n", pci_domain_nr(bus),
+					bus->number, PCI_SLOT(devfn),
+					PCI_FUNC(devfn));
+			return NULL;
+		}
+	}
+
+	if (pci_bus_read_config_byte(bus, devfn, PCI_HEADER_TYPE, &hdr_type))
+		return NULL;
+
 	dev = kmalloc(sizeof(struct pci_dev), GFP_KERNEL);
 	if (!dev)
 		return NULL;
@@ -785,7 +879,7 @@
 
 	if (pci_find_bus(pci_domain_nr(b), bus)) {
 		/* If we already got to this bus through a different bridge, ignore it */
-		DBG("PCI: Bus %02x already known\n", bus);
+		DBG("PCI: Bus %04x:%02x already known\n", pci_domain_nr(b), bus);
 		goto err_out;
 	}
 	list_add_tail(&b->node, &pci_root_buses);
@@ -807,6 +901,9 @@
 	error = class_device_create_file(&b->class_dev, &class_device_attr_cpuaffinity);
 	if (error)
 		goto class_dev_create_file_err;
+
+	/* Create legacy_io and legacy_mem files for this bus */
+	pci_create_legacy_files(b);
 
 	error = sysfs_create_link(&b->class_dev.kobj, &b->bridge->kobj, "bridge");
 	if (error)
diff -Nru a/drivers/pci/quirks.c b/drivers/pci/quirks.c
--- a/drivers/pci/quirks.c	2005-03-01 23:38:51 -08:00
+++ b/drivers/pci/quirks.c	2005-03-01 23:38:51 -08:00
@@ -216,6 +216,16 @@
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 	PCI_DEVICE_ID_INTEL_82443BX_2, 	quirk_natoma );
 
 /*
+ *  This chip can cause PCI parity errors if config register 0xA0 is read
+ *  while DMAs are occurring.
+ */
+static void __devinit quirk_citrine(struct pci_dev *dev)
+{
+	dev->cfg_size = 0xA0;
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_IBM,	PCI_DEVICE_ID_IBM_CITRINE,	quirk_citrine );
+
+/*
  *  S3 868 and 968 chips report region size equal to 32M, but they decode 64M.
  *  If it's needed, re-allocate the region.
  */
@@ -479,26 +489,6 @@
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C586_3,	quirk_via_acpi );
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C686_4,	quirk_via_acpi );
 
-static void quirk_via_irqpic(struct pci_dev *dev)
-{
-	u8 irq, new_irq = dev->irq & 0xf;
-
-	pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq);
-
-	if (new_irq != irq) {
-		printk(KERN_INFO "PCI: Via IRQ fixup for %s, from %d to %d\n",
-		       pci_name(dev), irq, new_irq);
-
-		udelay(15);
-		pci_write_config_byte(dev, PCI_INTERRUPT_LINE, new_irq);
-	}
-}
-DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C586_2,	quirk_via_irqpic );
-DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C686_5,	quirk_via_irqpic );
-DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C686_6,	quirk_via_irqpic );
-DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_8233_5,	quirk_via_irqpic );
-
-
 /*
  * PIIX3 USB: We have to disable USB interrupts that are
  * hardwired to PIRQD# and may be shared with an
@@ -691,12 +681,14 @@
 /*
  *	VIA northbridges care about PCI_INTERRUPT_LINE
  */
-int interrupt_line_quirk;
+int via_interrupt_line_quirk;
 
 static void __devinit quirk_via_bridge(struct pci_dev *pdev)
 {
-	if(pdev->devfn == 0)
-		interrupt_line_quirk = 1;
+	if(pdev->devfn == 0) {
+		printk(KERN_INFO "PCI: Via IRQ fixup\n");
+		via_interrupt_line_quirk = 1;
+	}
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA,	PCI_ANY_ID,                     quirk_via_bridge );
 
@@ -717,6 +709,26 @@
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5IDE, quirk_svwks_csb5ide );
 
+/*
+ *	Intel 82801CAM ICH3-M datasheet says IDE modes must be the same
+ */
+static void __init quirk_ide_samemode(struct pci_dev *pdev)
+{
+	u8 prog;
+
+	pci_read_config_byte(pdev, PCI_CLASS_PROG, &prog);
+
+	if (((prog & 1) && !(prog & 4)) || ((prog & 4) && !(prog & 1))) {
+		printk(KERN_INFO "PCI: IDE mode mismatch; forcing legacy mode\n");
+		prog &= ~5;
+		pdev->class &= ~5;
+		pci_write_config_byte(pdev, PCI_CLASS_PROG, prog);
+		/* need to re-assign BARs for compat mode */
+		quirk_ide_bases(pdev);
+	}
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_10, quirk_ide_samemode);
+
 /* This was originally an Alpha specific thing, but it really fits here.
  * The i82375 PCI/EISA bridge appears as non-classified. Fix that.
  */
@@ -1162,6 +1174,10 @@
 	case 0x2653:
 		ich = 6;
 		break;
+	case 0x27c0:
+	case 0x27c4:
+		ich = 7;
+		break;
 	default:
 		/* we do not handle this PCI device */
 		return;
@@ -1181,7 +1197,7 @@
 		else
 			return;			/* not in combined mode */
 	} else {
-		WARN_ON(ich != 6);
+		WARN_ON((ich != 6) && (ich != 7));
 		tmp &= 0x3;  /* interesting bits 1:0 */
 		if (tmp & (1 << 0))
 			comb = (1 << 2);	/* PATA port 0, SATA port 1 */
@@ -1237,6 +1253,8 @@
 	}
 }
 
+extern struct pci_fixup __start_pci_fixups_early[];
+extern struct pci_fixup __end_pci_fixups_early[];
 extern struct pci_fixup __start_pci_fixups_header[];
 extern struct pci_fixup __end_pci_fixups_header[];
 extern struct pci_fixup __start_pci_fixups_final[];
@@ -1250,6 +1268,11 @@
 	struct pci_fixup *start, *end;
 
 	switch(pass) {
+	case pci_fixup_early:
+		start = __start_pci_fixups_early;
+		end = __end_pci_fixups_early;
+		break;
+
 	case pci_fixup_header:
 		start = __start_pci_fixups_header;
 		end = __end_pci_fixups_header;
diff -Nru a/drivers/pci/remove.c b/drivers/pci/remove.c
--- a/drivers/pci/remove.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/pci/remove.c	2005-03-01 23:38:53 -08:00
@@ -61,15 +61,18 @@
 }
 EXPORT_SYMBOL(pci_remove_device_safe);
 
-void pci_remove_bus(struct pci_bus *b)
+void pci_remove_bus(struct pci_bus *pci_bus)
 {
-	pci_proc_detach_bus(b);
+	pci_proc_detach_bus(pci_bus);
 
 	spin_lock(&pci_bus_lock);
-	list_del(&b->node);
+	list_del(&pci_bus->node);
 	spin_unlock(&pci_bus_lock);
-
-	class_device_unregister(&b->class_dev);
+	pci_remove_legacy_files(pci_bus);
+	class_device_remove_file(&pci_bus->class_dev,
+		&class_device_attr_cpuaffinity);
+	sysfs_remove_link(&pci_bus->class_dev.kobj, "bridge");
+	class_device_unregister(&pci_bus->class_dev);
 }
 EXPORT_SYMBOL(pci_remove_bus);
 
diff -Nru a/drivers/pci/rom.c b/drivers/pci/rom.c
--- a/drivers/pci/rom.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/pci/rom.c	2005-03-01 23:38:57 -08:00
@@ -5,10 +5,7 @@
  * (C) Copyright 2004 Silicon Graphics, Inc. Jesse Barnes <jbarnes@sgi.com>
  *
  * PCI ROM access routines
- *
  */
-
-
 #include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/pci.h>
@@ -24,11 +21,10 @@
  * between the ROM and other resources, so enabling it may disable access
  * to MMIO registers or other card memory.
  */
-static void
-pci_enable_rom(struct pci_dev *pdev)
+static void pci_enable_rom(struct pci_dev *pdev)
 {
 	u32 rom_addr;
-	
+
 	pci_read_config_dword(pdev, pdev->rom_base_reg, &rom_addr);
 	rom_addr |= PCI_ROM_ADDRESS_ENABLE;
 	pci_write_config_dword(pdev, pdev->rom_base_reg, rom_addr);
@@ -41,8 +37,7 @@
  * Disable ROM decoding on a PCI device by turning off the last bit in the
  * ROM BAR.
  */
-static void
-pci_disable_rom(struct pci_dev *pdev)
+static void pci_disable_rom(struct pci_dev *pdev)
 {
 	u32 rom_addr;
 	pci_read_config_dword(pdev, pdev->rom_base_reg, &rom_addr);
@@ -57,7 +52,7 @@
  * @return: kernel virtual pointer to image of ROM
  *
  * Map a PCI ROM into kernel space. If ROM is boot video ROM,
- * the shadow BIOS copy will be returned instead of the 
+ * the shadow BIOS copy will be returned instead of the
  * actual ROM.
  */
 void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size)
@@ -67,10 +62,12 @@
 	void __iomem *rom;
 	void __iomem *image;
 	int last_image;
-	
-	if (res->flags & IORESOURCE_ROM_SHADOW) {	/* IORESOURCE_ROM_SHADOW only set on x86 */
-		start = (loff_t)0xC0000; 	/* primary video rom always starts here */
-		*size = 0x20000;		/* cover C000:0 through E000:0 */
+
+	/* IORESOURCE_ROM_SHADOW only set on x86 */
+	if (res->flags & IORESOURCE_ROM_SHADOW) {
+		/* primary video rom always starts here */
+		start = (loff_t)0xC0000;
+		*size = 0x20000; /* cover C000:0 through E000:0 */
 	} else {
 		if (res->flags & IORESOURCE_ROM_COPY) {
 			*size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
@@ -79,28 +76,32 @@
 			/* assign the ROM an address if it doesn't have one */
 			if (res->parent == NULL)
 				pci_assign_resource(pdev, PCI_ROM_RESOURCE);
-	
+
 			start = pci_resource_start(pdev, PCI_ROM_RESOURCE);
 			*size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
 			if (*size == 0)
 				return NULL;
-			
+
 			/* Enable ROM space decodes */
 			pci_enable_rom(pdev);
 		}
 	}
-	
+
 	rom = ioremap(start, *size);
 	if (!rom) {
 		/* restore enable if ioremap fails */
-		if (!(res->flags & (IORESOURCE_ROM_ENABLE | IORESOURCE_ROM_SHADOW | IORESOURCE_ROM_COPY)))
+		if (!(res->flags & (IORESOURCE_ROM_ENABLE |
+				    IORESOURCE_ROM_SHADOW |
+				    IORESOURCE_ROM_COPY)))
 			pci_disable_rom(pdev);
 		return NULL;
-	}		
+	}
 
-	/* Try to find the true size of the ROM since sometimes the PCI window */
-	/* size is much larger than the actual size of the ROM. */
-	/* True size is important if the ROM is going to be copied. */
+	/*
+	 * Try to find the true size of the ROM since sometimes the PCI window
+	 * size is much larger than the actual size of the ROM.
+	 * True size is important if the ROM is going to be copied.
+	 */
 	image = rom;
 	do {
 		void __iomem *pds;
@@ -136,30 +137,30 @@
  * @return: kernel virtual pointer to image of ROM
  *
  * Map a PCI ROM into kernel space. If ROM is boot video ROM,
- * the shadow BIOS copy will be returned instead of the 
+ * the shadow BIOS copy will be returned instead of the
  * actual ROM.
  */
 void __iomem *pci_map_rom_copy(struct pci_dev *pdev, size_t *size)
 {
 	struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
 	void __iomem *rom;
-	
+
 	rom = pci_map_rom(pdev, size);
 	if (!rom)
 		return NULL;
-		
+
 	if (res->flags & (IORESOURCE_ROM_COPY | IORESOURCE_ROM_SHADOW))
 		return rom;
-		
+
 	res->start = (unsigned long)kmalloc(*size, GFP_KERNEL);
-	if (!res->start) 
+	if (!res->start)
 		return rom;
 
-	res->end = res->start + *size; 
+	res->end = res->start + *size;
 	memcpy_fromio((void*)res->start, rom, *size);
 	pci_unmap_rom(pdev, rom);
 	res->flags |= IORESOURCE_ROM_COPY;
-	
+
 	return (void __iomem *)res->start;
 }
 
@@ -170,16 +171,15 @@
  *
  * Remove a mapping of a previously mapped ROM
  */
-void 
-pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom)
+void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom)
 {
 	struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
 
 	if (res->flags & IORESOURCE_ROM_COPY)
 		return;
-		
+
 	iounmap(rom);
-		
+
 	/* Disable again before continuing, leave enabled if pci=rom */
 	if (!(res->flags & (IORESOURCE_ROM_ENABLE | IORESOURCE_ROM_SHADOW)))
 		pci_disable_rom(pdev);
@@ -189,26 +189,28 @@
  * pci_remove_rom - disable the ROM and remove its sysfs attribute
  * @dev: pointer to pci device struct
  *
+ * Remove the rom file in sysfs and disable ROM decoding.
  */
-void 
-pci_remove_rom(struct pci_dev *pdev) 
+void pci_remove_rom(struct pci_dev *pdev)
 {
 	struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
-	
+
 	if (pci_resource_len(pdev, PCI_ROM_RESOURCE))
 		sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr);
-	if (!(res->flags & (IORESOURCE_ROM_ENABLE | IORESOURCE_ROM_SHADOW | IORESOURCE_ROM_COPY)))
+	if (!(res->flags & (IORESOURCE_ROM_ENABLE |
+			    IORESOURCE_ROM_SHADOW |
+			    IORESOURCE_ROM_COPY)))
 		pci_disable_rom(pdev);
 }
 
 /**
- * pci_cleanup_rom - internal routine for freeing the ROM copy created 
+ * pci_cleanup_rom - internal routine for freeing the ROM copy created
  * by pci_map_rom_copy called from remove.c
  * @dev: pointer to pci device struct
  *
+ * Free the copied ROM if we allocated one.
  */
-void 
-pci_cleanup_rom(struct pci_dev *pdev) 
+void pci_cleanup_rom(struct pci_dev *pdev)
 {
 	struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
 	if (res->flags & IORESOURCE_ROM_COPY) {
diff -Nru a/drivers/pci/search.c b/drivers/pci/search.c
--- a/drivers/pci/search.c	2005-03-01 23:38:44 -08:00
+++ b/drivers/pci/search.c	2005-03-01 23:38:44 -08:00
@@ -13,7 +13,7 @@
 #include <linux/interrupt.h>
 #include "pci.h"
 
-spinlock_t pci_bus_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(pci_bus_lock);
 
 static struct pci_bus * __devinit
 pci_do_find_bus(struct pci_bus* bus, unsigned char busnr)
diff -Nru a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
--- a/drivers/pci/setup-bus.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/pci/setup-bus.c	2005-03-01 23:39:17 -08:00
@@ -57,8 +57,13 @@
 	list_for_each_entry(dev, &bus->devices, bus_list) {
 		u16 class = dev->class >> 8;
 
-		if (class == PCI_CLASS_DISPLAY_VGA
-				|| class == PCI_CLASS_NOT_DEFINED_VGA)
+		/* Don't touch classless devices and host bridges.  */
+		if (class == PCI_CLASS_NOT_DEFINED ||
+		    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);
diff -Nru a/drivers/pci/setup-irq.c b/drivers/pci/setup-irq.c
--- a/drivers/pci/setup-irq.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/pci/setup-irq.c	2005-03-01 23:38:57 -08:00
@@ -53,7 +53,8 @@
 		irq = 0;
 	dev->irq = irq;
 
-	DBGC((KERN_ERR "PCI fixup irq: (%s) got %d\n", dev->dev.name, dev->irq));
+	DBGC((KERN_ERR "PCI fixup irq: (%s) got %d\n", 
+		dev->dev.kobj.name, dev->irq));
 
 	/* Always tell the device, so the driver knows what is
 	   the real IRQ to use; the device does not use it. */
diff -Nru a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
--- a/drivers/pcmcia/Kconfig	2005-03-01 23:39:08 -08:00
+++ b/drivers/pcmcia/Kconfig	2005-03-01 23:39:08 -08:00
@@ -6,10 +6,10 @@
 #
 
 menu "PCCARD (PCMCIA/CardBus) support"
-	depends on HOTPLUG
 
 config PCCARD
 	tristate "PCCard (PCMCIA/CardBus) support"
+	select HOTPLUG
 	---help---
 	  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,
@@ -39,18 +39,6 @@
 	  In all the above examples, N is the debugging verbosity
 	  level.
 
-config PCMCIA_OBSOLETE
-	bool "Enable obsolete PCCARD code"
-	depends on PCCARD != n
-	help
-	  Say Y here to enable some code found in the PCCARD subsystem
-	  which has no in-kernel usage, but might be needed for certain
-	  external PCMCIA drivers. If you do need to say Y here so that
-	  one such driver compiles and/or works correctly, please report
-	  this to linux-pcmcia <at> lists.infradead.org
-
-	  If unsure, say N
-
 config PCMCIA
 	tristate "16-bit PCMCIA support"
 	depends on PCCARD
@@ -92,6 +80,7 @@
 	depends on PCCARD && PCI
 #fixme: remove dependendcy on CARDBUS
 	depends on CARDBUS
+	select PCCARD_NONSTATIC
 	---help---
 	  This option enables support for CardBus host bridges.  Virtually
 	  all modern PCMCIA bridges are CardBus compatible.  A "bridge" is 
@@ -106,6 +95,7 @@
 config PD6729
 	tristate "Cirrus PD6729 compatible bridge support"
 	depends on PCMCIA && PCI
+	select PCCARD_NONSTATIC
 	help
 	  This provides support for the Cirrus PD6729 PCI-to-PCMCIA bridge
 	  device, found in some older laptops and PCMCIA card readers.
@@ -113,6 +103,7 @@
 config I82092
 	tristate "i82092 compatible bridge support"
 	depends on PCMCIA && PCI
+	select PCCARD_NONSTATIC
 	help
 	  This provides support for the Intel I82092AA PCI-to-PCMCIA bridge device,
 	  found in some older laptops and more commonly in evaluation boards for the
@@ -121,6 +112,7 @@
 config I82365
 	tristate "i82365 compatible bridge support"
 	depends on PCMCIA && ISA
+	select PCCARD_NONSTATIC
 	help
 	  Say Y here to include support for ISA-bus PCMCIA host bridges that
 	  are register compatible with the Intel i82365.  These are found on
@@ -131,6 +123,7 @@
 config TCIC
 	tristate "Databook TCIC host bridge support"
 	depends on PCMCIA
+	select PCCARD_NONSTATIC
 	help
 	  Say Y here to include support for the Databook TCIC family of PCMCIA
 	  host bridges. These are only found on a handful of old systems.
@@ -141,6 +134,10 @@
 	tristate "HD64465 host bridge support"
 	depends on HD64465 && PCMCIA
 
+config PCMCIA_AU1X00
+	tristate "Au1x00 pcmcia support"
+	depends on SOC_AU1X00 && PCMCIA
+
 config PCMCIA_SA1100
 	tristate "SA1100 support"
 	depends on ARM && ARCH_SA1100 && PCMCIA
@@ -189,5 +186,17 @@
 	default "1" if PLAT_USRV || PLAT_M32700UT || PLAT_MAPPI2 || PLAT_OPSPUT
 	help
 	  Set the number of M32R CF slots.
+
+config PCMCIA_VRC4171
+	tristate "NEC VRC4171 Card Controllers support"
+	depends on VRC4171 && PCMCIA
+
+config PCMCIA_VRC4173
+	tristate "NEC VRC4173 CARDU support"
+	depends on CPU_VR41XX && PCI && PCMCIA
+
+config PCCARD_NONSTATIC
+	tristate
+	depends on PCCARD
 
 endmenu
diff -Nru a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile
--- a/drivers/pcmcia/Makefile	2005-03-01 23:39:09 -08:00
+++ b/drivers/pcmcia/Makefile	2005-03-01 23:39:09 -08:00
@@ -10,9 +10,11 @@
 pcmcia_core-$(CONFIG_CARDBUS)			+= cardbus.o
 obj-$(CONFIG_PCCARD)				+= pcmcia_core.o
 
-pcmcia-y					+= ds.o bulkmem.o pcmcia_compat.o
+pcmcia-y					+= ds.o pcmcia_compat.o
 obj-$(CONFIG_PCMCIA)				+= pcmcia.o
 
+obj-$(CONFIG_PCCARD_NONSTATIC)			+= rsrc_nonstatic.o
+
 
 # socket drivers
 
@@ -28,10 +30,23 @@
 obj-$(CONFIG_PCMCIA_PXA2XX)                     += pxa2xx_core.o pxa2xx_cs.o
 obj-$(CONFIG_M32R_PCC)				+= m32r_pcc.o
 obj-$(CONFIG_M32R_CFC)				+= m32r_cfc.o
+obj-$(CONFIG_PCMCIA_AU1X00)			+= au1x00_ss.o
+obj-$(CONFIG_PCMCIA_VRC4171)			+= vrc4171_card.o
+obj-$(CONFIG_PCMCIA_VRC4173)			+= vrc4173_cardu.o
 
 sa11xx_core-y					+= soc_common.o sa11xx_base.o
 pxa2xx_core-y					+= soc_common.o pxa2xx_base.o
 
+au1x00_ss-y					+= au1000_generic.o
+au1x00_ss-$(CONFIG_MIPS_PB1000)			+= au1000_pb1x00.o
+au1x00_ss-$(CONFIG_MIPS_PB1100)			+= au1000_pb1x00.o
+au1x00_ss-$(CONFIG_MIPS_PB1500)			+= au1000_pb1x00.o
+au1x00_ss-$(CONFIG_MIPS_DB1000)			+= au1000_db1x00.o
+au1x00_ss-$(CONFIG_MIPS_DB1100)			+= au1000_db1x00.o
+au1x00_ss-$(CONFIG_MIPS_DB1500)			+= au1000_db1x00.o
+au1x00_ss-$(CONFIG_MIPS_DB1550)			+= au1000_db1x00.o
+au1x00_ss-$(CONFIG_MIPS_XXS1500)               += au1000_xxs1500.o
+
 sa1111_cs-y					+= sa1111_generic.o
 sa1111_cs-$(CONFIG_ASSABET_NEPONSET)		+= sa1100_neponset.o
 sa1111_cs-$(CONFIG_SA1100_BADGE4)		+= sa1100_badge4.o
@@ -46,4 +61,5 @@
 
 pxa2xx_cs-$(CONFIG_ARCH_LUBBOCK)		+= pxa2xx_lubbock.o sa1111_generic.o
 pxa2xx_cs-$(CONFIG_MACH_MAINSTONE)		+= pxa2xx_mainstone.o
+pxa2xx_cs-$(CONFIG_PXA_SHARPSL)			+= pxa2xx_sharpsl.o
 
diff -Nru a/drivers/pcmcia/au1000_db1x00.c b/drivers/pcmcia/au1000_db1x00.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/pcmcia/au1000_db1x00.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,288 @@
+/*
+ *
+ * Alchemy Semi Db1x00 boards specific pcmcia routines.
+ *
+ * Copyright 2002 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ * Copyright 2004 Pete Popov, updated the driver to 2.6.
+ * Followed the sa11xx API and largely copied many of the hardware
+ * independent functions.
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You 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/kernel.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/device.h>
+#include <linux/init.h>
+
+#include <asm/irq.h>
+#include <asm/signal.h>
+#include <asm/mach-au1x00/au1000.h>
+#include <asm/mach-db1x00/db1x00.h>
+
+#include "au1000_generic.h"
+
+#if 0
+#define debug(x,args...) printk(KERN_DEBUG "%s: " x, __func__ , ##args)
+#else
+#define debug(x,args...)
+#endif
+
+static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
+
+struct au1000_pcmcia_socket au1000_pcmcia_socket[PCMCIA_NUM_SOCKS];
+extern int au1x00_pcmcia_socket_probe(struct device *, struct pcmcia_low_level *, int, int);
+
+static int db1x00_pcmcia_hw_init(struct au1000_pcmcia_socket *skt)
+{
+#ifdef CONFIG_MIPS_DB1550
+	skt->irq = skt->nr ? AU1000_GPIO_5 : AU1000_GPIO_3;
+#else
+	skt->irq = skt->nr ? AU1000_GPIO_5 : AU1000_GPIO_2;
+#endif
+	return 0;
+}
+
+static void db1x00_pcmcia_shutdown(struct au1000_pcmcia_socket *skt)
+{
+	bcsr->pcmcia = 0; /* turn off power */
+	au_sync_delay(2);
+}
+
+static void
+db1x00_pcmcia_socket_state(struct au1000_pcmcia_socket *skt, struct pcmcia_state *state)
+{
+	u32 inserted;
+	unsigned char vs;
+
+	state->ready = 0;
+	state->vs_Xv = 0;
+	state->vs_3v = 0;
+	state->detect = 0;
+
+	switch (skt->nr) {
+	case 0:
+		vs = bcsr->status & 0x3;
+		inserted = !(bcsr->status & (1<<4));
+		break;
+	case 1:
+		vs = (bcsr->status & 0xC)>>2;
+		inserted = !(bcsr->status & (1<<5));
+		break;
+	default:/* should never happen */
+		return;
+	}
+
+	if (inserted)
+		debug("db1x00 socket %d: inserted %d, vs %d pcmcia %x\n",
+				skt->nr, inserted, vs, bcsr->pcmcia);
+
+	if (inserted) {
+		switch (vs) {
+			case 0:
+			case 2:
+				state->vs_3v=1;
+				break;
+			case 3: /* 5V */
+				break;
+			default:
+				/* return without setting 'detect' */
+				printk(KERN_ERR "db1x00 bad VS (%d)\n",
+						vs);
+		}
+		state->detect = 1;
+		state->ready = 1;
+	}
+	else {
+		/* if the card was previously inserted and then ejected,
+		 * we should turn off power to it
+		 */
+		if ((skt->nr == 0) && (bcsr->pcmcia & BCSR_PCMCIA_PC0RST)) {
+			bcsr->pcmcia &= ~(BCSR_PCMCIA_PC0RST |
+					BCSR_PCMCIA_PC0DRVEN |
+					BCSR_PCMCIA_PC0VPP |
+					BCSR_PCMCIA_PC0VCC);
+			au_sync_delay(10);
+		}
+		else if ((skt->nr == 1) && bcsr->pcmcia & BCSR_PCMCIA_PC1RST) {
+			bcsr->pcmcia &= ~(BCSR_PCMCIA_PC1RST |
+					BCSR_PCMCIA_PC1DRVEN |
+					BCSR_PCMCIA_PC1VPP |
+					BCSR_PCMCIA_PC1VCC);
+			au_sync_delay(10);
+		}
+	}
+
+	state->bvd1=1;
+	state->bvd2=1;
+	state->wrprot=0;
+}
+
+static int
+db1x00_pcmcia_configure_socket(struct au1000_pcmcia_socket *skt, struct socket_state_t *state)
+{
+	u16 pwr;
+	int sock = skt->nr;
+
+	debug("config_skt %d Vcc %dV Vpp %dV, reset %d\n",
+			sock, state->Vcc, state->Vpp,
+			state->flags & SS_RESET);
+
+	/* pcmcia reg was set to zero at init time. Be careful when
+	 * initializing a socket not to wipe out the settings of the
+	 * other socket.
+	 */
+	pwr = bcsr->pcmcia;
+	pwr &= ~(0xf << sock*8); /* clear voltage settings */
+
+	state->Vpp = 0;
+	switch(state->Vcc){
+		case 0:  /* Vcc 0 */
+			pwr |= SET_VCC_VPP(0,0,sock);
+			break;
+		case 50: /* Vcc 5V */
+			switch(state->Vpp) {
+				case 0:
+					pwr |= SET_VCC_VPP(2,0,sock);
+					break;
+				case 50:
+					pwr |= SET_VCC_VPP(2,1,sock);
+					break;
+				case 12:
+					pwr |= SET_VCC_VPP(2,2,sock);
+					break;
+				case 33:
+				default:
+					pwr |= SET_VCC_VPP(0,0,sock);
+					printk("%s: bad Vcc/Vpp (%d:%d)\n",
+							__FUNCTION__,
+							state->Vcc,
+							state->Vpp);
+					break;
+			}
+			break;
+		case 33: /* Vcc 3.3V */
+			switch(state->Vpp) {
+				case 0:
+					pwr |= SET_VCC_VPP(1,0,sock);
+					break;
+				case 12:
+					pwr |= SET_VCC_VPP(1,2,sock);
+					break;
+				case 33:
+					pwr |= SET_VCC_VPP(1,1,sock);
+					break;
+				case 50:
+				default:
+					pwr |= SET_VCC_VPP(0,0,sock);
+					printk("%s: bad Vcc/Vpp (%d:%d)\n",
+							__FUNCTION__,
+							state->Vcc,
+							state->Vpp);
+					break;
+			}
+			break;
+		default: /* what's this ? */
+			pwr |= SET_VCC_VPP(0,0,sock);
+			printk(KERN_ERR "%s: bad Vcc %d\n",
+					__FUNCTION__, state->Vcc);
+			break;
+	}
+
+	bcsr->pcmcia = pwr;
+	au_sync_delay(300);
+
+	if (sock == 0) {
+		if (!(state->flags & SS_RESET)) {
+			pwr |= BCSR_PCMCIA_PC0DRVEN;
+			bcsr->pcmcia = pwr;
+			au_sync_delay(300);
+			pwr |= BCSR_PCMCIA_PC0RST;
+			bcsr->pcmcia = pwr;
+			au_sync_delay(100);
+		}
+		else {
+			pwr &= ~(BCSR_PCMCIA_PC0RST | BCSR_PCMCIA_PC0DRVEN);
+			bcsr->pcmcia = pwr;
+			au_sync_delay(100);
+		}
+	}
+	else {
+		if (!(state->flags & SS_RESET)) {
+			pwr |= BCSR_PCMCIA_PC1DRVEN;
+			bcsr->pcmcia = pwr;
+			au_sync_delay(300);
+			pwr |= BCSR_PCMCIA_PC1RST;
+			bcsr->pcmcia = pwr;
+			au_sync_delay(100);
+		}
+		else {
+			pwr &= ~(BCSR_PCMCIA_PC1RST | BCSR_PCMCIA_PC1DRVEN);
+			bcsr->pcmcia = pwr;
+			au_sync_delay(100);
+		}
+	}
+	return 0;
+}
+
+/*
+ * Enable card status IRQs on (re-)initialisation.  This can
+ * be called at initialisation, power management event, or
+ * pcmcia event.
+ */
+void db1x00_socket_init(struct au1000_pcmcia_socket *skt)
+{
+	/* nothing to do for now */
+}
+
+/*
+ * Disable card status IRQs and PCMCIA bus on suspend.
+ */
+void db1x00_socket_suspend(struct au1000_pcmcia_socket *skt)
+{
+	/* nothing to do for now */
+}
+
+struct pcmcia_low_level db1x00_pcmcia_ops = {
+	.owner			= THIS_MODULE,
+
+	.hw_init 		= db1x00_pcmcia_hw_init,
+	.hw_shutdown		= db1x00_pcmcia_shutdown,
+
+	.socket_state		= db1x00_pcmcia_socket_state,
+	.configure_socket	= db1x00_pcmcia_configure_socket,
+
+	.socket_init		= db1x00_socket_init,
+	.socket_suspend		= db1x00_socket_suspend
+};
+
+int __init au1x_board_init(struct device *dev)
+{
+	int ret = -ENODEV;
+	bcsr->pcmcia = 0; /* turn off power, if it's not already off */
+	au_sync_delay(2);
+	ret = au1x00_pcmcia_socket_probe(dev, &db1x00_pcmcia_ops, 0, 2);
+	return ret;
+}
diff -Nru a/drivers/pcmcia/au1000_generic.c b/drivers/pcmcia/au1000_generic.c
--- a/drivers/pcmcia/au1000_generic.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/pcmcia/au1000_generic.c	2005-03-01 23:38:58 -08:00
@@ -2,9 +2,13 @@
  *
  * Alchemy Semi Au1000 pcmcia driver
  *
- * Copyright 2001 MontaVista Software Inc.
+ * Copyright 2001-2003 MontaVista Software Inc.
  * Author: MontaVista Software, Inc.
- *         	ppopov@mvista.com or source@mvista.com
+ *         	ppopov@embeddedalley.com or source@mvista.com
+ *
+ * Copyright 2004 Pete Popov, Embedded Alley Solutions, Inc.
+ * Updated the driver to 2.6. Followed the sa11xx API and largely
+ * copied many of the hardware independent functions.
  *
  * ########################################################################
  *
@@ -25,450 +29,255 @@
  *
  * 
  */
+
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/init.h>
 #include <linux/config.h>
-#include <linux/delay.h>
+#include <linux/cpufreq.h>
 #include <linux/ioport.h>
 #include <linux/kernel.h>
-#include <linux/tqueue.h>
 #include <linux/timer.h>
 #include <linux/mm.h>
-#include <linux/proc_fs.h>
-#include <linux/types.h>
-#include <linux/vmalloc.h>
-
-#include <pcmcia/version.h>
-#include <pcmcia/cs_types.h>
-#include <pcmcia/cs.h>
-#include <pcmcia/ss.h>
-#include <pcmcia/bulkmem.h>
-#include <pcmcia/cistpl.h>
-#include <pcmcia/bus_ops.h>
-#include "cs_internal.h"
+#include <linux/notifier.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/device.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/system.h>
 
-#include <asm/au1000.h>
-#include <asm/au1000_pcmcia.h>
-
-#ifdef DEBUG
-static int pc_debug;
-
-module_param(pc_debug, int, 0644);
-
-#define debug(lvl,fmt) do {			\
-	if (pc_debug > (lvl))			\
-		printk(KERN_DEBUG fmt);		\
-} while (0)
-#else
-#define debug(lvl,fmt) do { } while (0)
-#endif
+#include <asm/mach-au1x00/au1000.h>
+#include "au1000_generic.h"
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Pete Popov, MontaVista Software <ppopov@mvista.com>");
+MODULE_AUTHOR("Pete Popov <ppopov@embeddedalley.com>");
 MODULE_DESCRIPTION("Linux PCMCIA Card Services: Au1x00 Socket Controller");
 
-#define MAP_SIZE 0x1000000
-
-/* This structure maintains housekeeping state for each socket, such
- * as the last known values of the card detect pins, or the Card Services
- * callback value associated with the socket:
- */
-static struct au1000_pcmcia_socket *pcmcia_socket;
-static int socket_count;
-
-
-/* Returned by the low-level PCMCIA interface: */
-static struct pcmcia_low_level *pcmcia_low_level;
-
-/* Event poll timer structure */
-static struct timer_list poll_timer;
-
-
-/* Prototypes for routines which are used internally: */
-
-static int  au1000_pcmcia_driver_init(void);
-static void au1000_pcmcia_driver_shutdown(void);
-static void au1000_pcmcia_task_handler(void *data);
-static void au1000_pcmcia_poll_event(unsigned long data);
-static void au1000_pcmcia_interrupt(int irq, void *dev, struct pt_regs *regs);
-static struct tq_struct au1000_pcmcia_task;
-
-#ifdef CONFIG_PROC_FS
-static int au1000_pcmcia_proc_status(char *buf, char **start, 
-		off_t pos, int count, int *eof, void *data);
+#if 0
+#define debug(x,args...) printk(KERN_DEBUG "%s: " x, __func__ , ##args)
+#else
+#define debug(x,args...)
 #endif
 
+#define MAP_SIZE 0x100000
+extern struct au1000_pcmcia_socket au1000_pcmcia_socket[];
+#define PCMCIA_SOCKET(x)	(au1000_pcmcia_socket + (x))
+#define to_au1000_socket(x)	container_of(x, struct au1000_pcmcia_socket, socket)
 
-/* Prototypes for operations which are exported to the
- * new-and-impr^H^H^H^H^H^H^H^H^H^H in-kernel PCMCIA core:
+/* Some boards like to support CF cards as IDE root devices, so they
+ * grab pcmcia sockets directly.
  */
+u32 *pcmcia_base_vaddrs[2];
+extern const unsigned long mips_io_port_base;
 
-static int au1000_pcmcia_init(u32 sock);
-static int au1000_pcmcia_suspend(u32 sock);
-static int au1000_pcmcia_register_callback(u32 sock, 
-		void (*handler)(void *, u32), void *info);
-static int au1000_pcmcia_inquire_socket(u32 sock, socket_cap_t *cap);
-static int au1000_pcmcia_get_status(u32 sock, u_int *value);
-static int au1000_pcmcia_get_socket(u32 sock, socket_state_t *state);
-static int au1000_pcmcia_set_socket(u32 sock, socket_state_t *state);
-static int au1000_pcmcia_get_io_map(u32 sock, struct pccard_io_map *io);
-static int au1000_pcmcia_set_io_map(u32 sock, struct pccard_io_map *io);
-static int au1000_pcmcia_get_mem_map(u32 sock, struct pccard_mem_map *mem);
-static int au1000_pcmcia_set_mem_map(u32 sock, struct pccard_mem_map *mem);
-#ifdef CONFIG_PROC_FS
-static void au1000_pcmcia_proc_setup(u32 sock, struct proc_dir_entry *base);
-#endif
+DECLARE_MUTEX(pcmcia_sockets_lock);
 
-static struct pccard_operations au1000_pcmcia_operations = {
-	au1000_pcmcia_init,
-	au1000_pcmcia_suspend,
-	au1000_pcmcia_register_callback,
-	au1000_pcmcia_inquire_socket,
-	au1000_pcmcia_get_status,
-	au1000_pcmcia_get_socket,
-	au1000_pcmcia_set_socket,
-	au1000_pcmcia_get_io_map,
-	au1000_pcmcia_set_io_map,
-	au1000_pcmcia_get_mem_map,
-	au1000_pcmcia_set_mem_map,
-#ifdef CONFIG_PROC_FS
-	au1000_pcmcia_proc_setup
-#endif
+static int (*au1x00_pcmcia_hw_init[])(struct device *dev) = {
+	au1x_board_init,
 };
 
-static spinlock_t pcmcia_lock = SPIN_LOCK_UNLOCKED;
-
-static int __init au1000_pcmcia_driver_init(void)
+static int
+au1x00_pcmcia_skt_state(struct au1000_pcmcia_socket *skt)
 {
-	struct pcmcia_init pcmcia_init;
 	struct pcmcia_state state;
-	unsigned int i;
+	unsigned int stat;
 
-	printk("\nAu1x00 PCMCIA\n");
+	memset(&state, 0, sizeof(struct pcmcia_state));
 
-#ifndef CONFIG_64BIT_PHYS_ADDR
-	printk(KERN_ERR "Au1x00 PCMCIA 36 bit IO support not enabled\n");
-	return -1;
-#endif
-
-#if defined(CONFIG_MIPS_PB1000) || defined(CONFIG_MIPS_PB1100) || defined(CONFIG_MIPS_PB1500)
-	pcmcia_low_level=&pb1x00_pcmcia_ops;
-#else
-#error Unsupported AU1000 board.
-#endif
+	skt->ops->socket_state(skt, &state);
 
-	pcmcia_init.handler=au1000_pcmcia_interrupt;
-	if((socket_count=pcmcia_low_level->init(&pcmcia_init))<0) {
-		printk(KERN_ERR "Unable to initialize PCMCIA service.\n");
-		return -EIO;
-	}
+	stat = state.detect  ? SS_DETECT : 0;
+	stat |= state.ready  ? SS_READY  : 0;
+	stat |= state.wrprot ? SS_WRPROT : 0;
+	stat |= state.vs_3v  ? SS_3VCARD : 0;
+	stat |= state.vs_Xv  ? SS_XVCARD : 0;
+	stat |= skt->cs_state.Vcc ? SS_POWERON : 0;
 
-	/* NOTE: the chip select must already be setup */
-
-	pcmcia_socket = 
-		kmalloc(sizeof(struct au1000_pcmcia_socket) * socket_count, 
-				GFP_KERNEL);
-	if (!pcmcia_socket) {
-		printk(KERN_ERR "Card Services can't get memory \n");
-		return -1;
+	if (skt->cs_state.flags & SS_IOCARD)
+		stat |= state.bvd1 ? SS_STSCHG : 0;
+	else {
+		if (state.bvd1 == 0)
+			stat |= SS_BATDEAD;
+		else if (state.bvd2 == 0)
+			stat |= SS_BATWARN;
 	}
-	memset(pcmcia_socket, 0,
-			sizeof(struct au1000_pcmcia_socket) * socket_count);
-			
-	/* 
-	 * Assuming max of 2 sockets, which the Au1000 supports.
-	 * WARNING: the Pb1000 has two sockets, and both work, but you
-	 * can't use them both at the same time due to glue logic conflicts.
-	 */
-	for(i=0; i < socket_count; i++) {
+	return stat;
+}
 
-		if(pcmcia_low_level->socket_state(i, &state)<0){
-			printk(KERN_ERR "Unable to get PCMCIA status\n");
-			return -EIO;
-		}
-		pcmcia_socket[i].k_state=state;
-		pcmcia_socket[i].cs_state.csc_mask=SS_DETECT;
-		
-		if (i == 0) {
-			pcmcia_socket[i].virt_io = 
-				(u32)ioremap((ioaddr_t)0xF00000000, 0x1000);
-			pcmcia_socket[i].phys_attr = (memaddr_t)0xF40000000;
-			pcmcia_socket[i].phys_mem = (memaddr_t)0xF80000000;
-		}
-		else  {
-			pcmcia_socket[i].virt_io = 
-				(u32)ioremap((ioaddr_t)0xF08000000, 0x1000);
-			pcmcia_socket[i].phys_attr = (memaddr_t)0xF48000000;
-			pcmcia_socket[i].phys_mem = (memaddr_t)0xF88000000;
-		}
-	}
+/*
+ * au100_pcmcia_config_skt
+ *
+ * Convert PCMCIA socket state to our socket configure structure.
+ */
+static int
+au1x00_pcmcia_config_skt(struct au1000_pcmcia_socket *skt, socket_state_t *state)
+{
+	int ret;
 
-	/* Only advertise as many sockets as we can detect: */
-	if(register_ss_entry(socket_count, &au1000_pcmcia_operations)<0){
-		printk(KERN_ERR "Unable to register socket service routine\n");
-		return -ENXIO;
+	ret = skt->ops->configure_socket(skt, state);
+	if (ret == 0) {
+		skt->cs_state = *state;
 	}
 
-	/* Start the event poll timer.  
-	 * It will reschedule by itself afterwards. 
-	 */
-	au1000_pcmcia_poll_event(0);
+	if (ret < 0)
+		debug("unable to configure socket %d\n", skt->nr);
 
-	debug(1, "au1000: initialization complete\n");
-	return 0;
-
-}  /* au1000_pcmcia_driver_init() */
-
-module_init(au1000_pcmcia_driver_init);
-
-static void __exit au1000_pcmcia_driver_shutdown(void)
-{
-	int i;
-
-	del_timer_sync(&poll_timer);
-	unregister_ss_entry(&au1000_pcmcia_operations);
-	pcmcia_low_level->shutdown();
-	flush_scheduled_tasks();
-	for(i=0; i < socket_count; i++) {
-		if (pcmcia_socket[i].virt_io) 
-			iounmap((void *)pcmcia_socket[i].virt_io);
-	}
-	debug(1, "au1000: shutdown complete\n");
+	return ret;
 }
 
-module_exit(au1000_pcmcia_driver_shutdown);
+/* au1x00_pcmcia_sock_init()
+ *
+ * (Re-)Initialise the socket, turning on status interrupts
+ * and PCMCIA bus.  This must wait for power to stabilise
+ * so that the card status signals report correctly.
+ *
+ * Returns: 0
+ */
+static int au1x00_pcmcia_sock_init(struct pcmcia_socket *sock)
+{
+	struct au1000_pcmcia_socket *skt = to_au1000_socket(sock);
 
-static int au1000_pcmcia_init(unsigned int sock) { return 0; }
+	debug("initializing socket %u\n", skt->nr);
 
-static int au1000_pcmcia_suspend(unsigned int sock)
-{
+	skt->ops->socket_init(skt);
 	return 0;
 }
 
-
-static inline unsigned 
-au1000_pcmcia_events(struct pcmcia_state *state, 
-		struct pcmcia_state *prev_state, 
-		unsigned int mask, unsigned int flags)
+/*
+ * au1x00_pcmcia_suspend()
+ *
+ * Remove power on the socket, disable IRQs from the card.
+ * Turn off status interrupts, and disable the PCMCIA bus.
+ *
+ * Returns: 0
+ */
+static int au1x00_pcmcia_suspend(struct pcmcia_socket *sock)
 {
-	unsigned int events=0;
+	struct au1000_pcmcia_socket *skt = to_au1000_socket(sock);
+	int ret;
 
-	if(state->detect!=prev_state->detect){
-		debug(2, "%s(): card detect value %u\n", 
-				__FUNCTION__, state->detect);
-		events |= mask&SS_DETECT;
-	}
+	debug("suspending socket %u\n", skt->nr);
 
+	ret = au1x00_pcmcia_config_skt(skt, &dead_socket);
+	if (ret == 0)
+		skt->ops->socket_suspend(skt);
 
-	if(state->ready!=prev_state->ready){
-		debug(2, "%s(): card ready value %u\n", 
-				__FUNCTION__, state->ready);
-		events |= mask&((flags&SS_IOCARD)?0:SS_READY);
-	}
-
-	*prev_state=*state;
-	return events;
-
-}  /* au1000_pcmcia_events() */
+	return ret;
+}
 
+static DEFINE_SPINLOCK(status_lock);
 
-/* 
- * Au1000_pcmcia_task_handler()
- * Processes socket events.
+/*
+ * au1x00_check_status()
  */
-static void au1000_pcmcia_task_handler(void *data) 
+static void au1x00_check_status(struct au1000_pcmcia_socket *skt)
 {
-	struct pcmcia_state state;
-	int i, events, irq_status;
-
-	for(i=0; i<socket_count; i++)  {
-		if((irq_status = pcmcia_low_level->socket_state(i, &state))<0)
-			printk(KERN_ERR "low-level PCMCIA error\n");
-
-		events = au1000_pcmcia_events(&state, 
-				&pcmcia_socket[i].k_state, 
-				pcmcia_socket[i].cs_state.csc_mask, 
-				pcmcia_socket[i].cs_state.flags);
-		if(pcmcia_socket[i].handler!=NULL) {
-			pcmcia_socket[i].handler(pcmcia_socket[i].handler_info,
-					events);
-		}
-	}
-
-}  /* au1000_pcmcia_task_handler() */
-
-static struct tq_struct au1000_pcmcia_task = {
-	routine: au1000_pcmcia_task_handler
-};
+	unsigned int events;
 
+	debug("entering PCMCIA monitoring thread\n");
 
-static void au1000_pcmcia_poll_event(unsigned long dummy)
-{
-	poll_timer.function = au1000_pcmcia_poll_event;
-	poll_timer.expires = jiffies + AU1000_PCMCIA_POLL_PERIOD;
-	add_timer(&poll_timer);
-	schedule_task(&au1000_pcmcia_task);
+	do {
+		unsigned int status;
+		unsigned long flags;
+
+		status = au1x00_pcmcia_skt_state(skt);
+
+		spin_lock_irqsave(&status_lock, flags);
+		events = (status ^ skt->status) & skt->cs_state.csc_mask;
+		skt->status = status;
+		spin_unlock_irqrestore(&status_lock, flags);
+
+		debug("events: %s%s%s%s%s%s\n",
+			events == 0         ? "<NONE>"   : "",
+			events & SS_DETECT  ? "DETECT "  : "",
+			events & SS_READY   ? "READY "   : "",
+			events & SS_BATDEAD ? "BATDEAD " : "",
+			events & SS_BATWARN ? "BATWARN " : "",
+			events & SS_STSCHG  ? "STSCHG "  : "");
+
+		if (events)
+			pcmcia_parse_events(&skt->socket, events);
+	} while (events);
 }
 
-
 /* 
- * au1000_pcmcia_interrupt()
- * The actual interrupt work is performed by au1000_pcmcia_task(), 
- * because the Card Services event handling code performs scheduling 
- * operations which cannot be executed from within an interrupt context.
+ * au1x00_pcmcia_poll_event()
+ * Let's poll for events in addition to IRQs since IRQ only is unreliable...
  */
-static void 
-au1000_pcmcia_interrupt(int irq, void *dev, struct pt_regs *regs)
+static void au1x00_pcmcia_poll_event(unsigned long dummy)
 {
-	schedule_task(&au1000_pcmcia_task);
-}
+	struct au1000_pcmcia_socket *skt = (struct au1000_pcmcia_socket *)dummy;
+	debug("polling for events\n");
 
+	mod_timer(&skt->poll_timer, jiffies + AU1000_PCMCIA_POLL_PERIOD);
 
-static int 
-au1000_pcmcia_register_callback(unsigned int sock, 
-		void (*handler)(void *, unsigned int), void *info)
-{
-	if(handler==NULL){
-		pcmcia_socket[sock].handler=NULL;
-		MOD_DEC_USE_COUNT;
-	} else {
-		MOD_INC_USE_COUNT;
-		pcmcia_socket[sock].handler=handler;
-		pcmcia_socket[sock].handler_info=info;
-	}
-	return 0;
+	au1x00_check_status(skt);
 }
 
-
-/* au1000_pcmcia_inquire_socket()
- *
- * From the sa1100 socket driver : 
- *
- * Implements the inquire_socket() operation for the in-kernel PCMCIA
- * service (formerly SS_InquireSocket in Card Services).  We set 
- * SS_CAP_STATIC_MAP, which disables the memory resource database check. 
- * (Mapped memory is set up within the socket driver itself.)
+/* au1x00_pcmcia_get_status()
  *
- * In conjunction with the STATIC_MAP capability is a new field,
- * `io_offset', recommended by David Hinds. Rather than go through
- * the SetIOMap interface (which is not quite suited for communicating
- * window locations up from the socket driver), we just pass up 
- * an offset which is applied to client-requested base I/O addresses
- * in alloc_io_space().
+ * From the sa11xx_core.c:
+ * Implements the get_status() operation for the in-kernel PCMCIA
+ * service (formerly SS_GetStatus in Card Services). Essentially just
+ * fills in bits in `status' according to internal driver state or
+ * the value of the voltage detect chipselect register.
+ *
+ * As a debugging note, during card startup, the PCMCIA core issues
+ * three set_socket() commands in a row the first with RESET deasserted,
+ * the second with RESET asserted, and the last with RESET deasserted
+ * again. Following the third set_socket(), a get_status() command will
+ * be issued. The kernel is looking for the SS_READY flag (see
+ * setup_socket(), reset_socket(), and unreset_socket() in cs.c).
  *
- * Returns: 0 on success, -1 if no pin has been configured for `sock'
+ * Returns: 0
  */
-static int au1000_pcmcia_inquire_socket(unsigned int sock, socket_cap_t *cap)
+static int
+au1x00_pcmcia_get_status(struct pcmcia_socket *sock, unsigned int *status)
 {
-	struct pcmcia_irq_info irq_info;
-
-	if(sock > socket_count){
-		printk(KERN_ERR "au1000: socket %u not configured\n", sock);
-		return -1;
-	}
-
-	/* from the sa1100_generic driver: */
-
-	/* SS_CAP_PAGE_REGS: used by setup_cis_mem() in cistpl.c to set the
-	*   force_low argument to validate_mem() in rsrc_mgr.c -- since in
-	*   general, the mapped * addresses of the PCMCIA memory regions
-	*   will not be within 0xffff, setting force_low would be
-	*   undesirable.
-	*
-	* SS_CAP_STATIC_MAP: don't bother with the (user-configured) memory
-	*   resource database; we instead pass up physical address ranges
-	*   and allow other parts of Card Services to deal with remapping.
-	*
-	* SS_CAP_PCCARD: we can deal with 16-bit PCMCIA & CF cards, but
-	*   not 32-bit CardBus devices.
-	*/
-	cap->features=(SS_CAP_PAGE_REGS  | SS_CAP_STATIC_MAP | SS_CAP_PCCARD);
-
-	irq_info.sock=sock;
-	irq_info.irq=-1;
-
-	if(pcmcia_low_level->get_irq_info(&irq_info)<0){
-		printk(KERN_ERR "Error obtaining IRQ info socket %u\n", sock);
-		return -1;
-	}
+	struct au1000_pcmcia_socket *skt = to_au1000_socket(sock);
 
-	cap->irq_mask=0;
-	cap->map_size=MAP_SIZE;
-	cap->pci_irq=irq_info.irq;
-	cap->io_offset=pcmcia_socket[sock].virt_io;
+	skt->status = au1x00_pcmcia_skt_state(skt);
+	*status = skt->status;
 
 	return 0;
+}
 
-}  /* au1000_pcmcia_inquire_socket() */
-
-
-static int 
-au1000_pcmcia_get_status(unsigned int sock, unsigned int *status)
+/* au1x00_pcmcia_get_socket()
+ * Implements the get_socket() operation for the in-kernel PCMCIA
+ * service (formerly SS_GetSocket in Card Services). Not a very
+ * exciting routine.
+ *
+ * Returns: 0
+ */
+static int
+au1x00_pcmcia_get_socket(struct pcmcia_socket *sock, socket_state_t *state)
 {
-	struct pcmcia_state state;
-
-
-	if((pcmcia_low_level->socket_state(sock, &state))<0){
-		printk(KERN_ERR "Unable to get PCMCIA status from kernel.\n");
-		return -1;
-	}
-
-	pcmcia_socket[sock].k_state = state;
+  struct au1000_pcmcia_socket *skt = to_au1000_socket(sock);
 
-	*status = state.detect?SS_DETECT:0;
-
-	*status |= state.ready?SS_READY:0;
-
-	*status |= pcmcia_socket[sock].cs_state.Vcc?SS_POWERON:0;
-
-	if(pcmcia_socket[sock].cs_state.flags&SS_IOCARD)
-		*status |= state.bvd1?SS_STSCHG:0;
-	else {
-		if(state.bvd1==0)
-			*status |= SS_BATDEAD;
-		else if(state.bvd2 == 0)
-			*status |= SS_BATWARN;
-	}
-
-	*status|=state.vs_3v?SS_3VCARD:0;
-
-	*status|=state.vs_Xv?SS_XVCARD:0;
-
-	debug(2, "\tstatus: %s%s%s%s%s%s%s%s\n",
-	(*status&SS_DETECT)?"DETECT ":"",
-	(*status&SS_READY)?"READY ":"", 
-	(*status&SS_BATDEAD)?"BATDEAD ":"",
-	(*status&SS_BATWARN)?"BATWARN ":"",
-	(*status&SS_POWERON)?"POWERON ":"",
-	(*status&SS_STSCHG)?"STSCHG ":"",
-	(*status&SS_3VCARD)?"3VCARD ":"",
-	(*status&SS_XVCARD)?"XVCARD ":"");
-
-	return 0;
-
-}  /* au1000_pcmcia_get_status() */
-
-
-static int 
-au1000_pcmcia_get_socket(unsigned int sock, socket_state_t *state)
-{
-	*state = pcmcia_socket[sock].cs_state;
-	return 0;
+  debug("for sock %u\n", skt->nr);
+  *state = skt->cs_state;
+  return 0;
 }
 
-
-static int 
-au1000_pcmcia_set_socket(unsigned int sock, socket_state_t *state)
+/* au1x00_pcmcia_set_socket()
+ * Implements the set_socket() operation for the in-kernel PCMCIA
+ * service (formerly SS_SetSocket in Card Services). We more or
+ * less punt all of this work and let the kernel handle the details
+ * of power configuration, reset, &c. We also record the value of
+ * `state' in order to regurgitate it to the PCMCIA core later.
+ *
+ * Returns: 0
+ */
+static int
+au1x00_pcmcia_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
 {
-	struct pcmcia_configure configure;
+  struct au1000_pcmcia_socket *skt = to_au1000_socket(sock);
+
+  debug("for sock %u\n", skt->nr);
 
-	debug(2, "\tmask:  %s%s%s%s%s%s\n\tflags: %s%s%s%s%s%s\n"
-	"\tVcc %d  Vpp %d  irq %d\n",
+  debug("\tmask:  %s%s%s%s%s%s\n\tflags: %s%s%s%s%s%s\n",
 	(state->csc_mask==0)?"<NONE>":"",
 	(state->csc_mask&SS_DETECT)?"DETECT ":"",
 	(state->csc_mask&SS_READY)?"READY ":"",
@@ -480,217 +289,294 @@
 	(state->flags&SS_IOCARD)?"IOCARD ":"",
 	(state->flags&SS_RESET)?"RESET ":"",
 	(state->flags&SS_SPKR_ENA)?"SPKR_ENA ":"",
-	(state->flags&SS_OUTPUT_ENA)?"OUTPUT_ENA ":"",
+	(state->flags&SS_OUTPUT_ENA)?"OUTPUT_ENA ":"");
+  debug("\tVcc %d  Vpp %d  irq %d\n",
 	state->Vcc, state->Vpp, state->io_irq);
 
-	configure.sock=sock;
-	configure.vcc=state->Vcc;
-	configure.vpp=state->Vpp;
-	configure.output=(state->flags&SS_OUTPUT_ENA)?1:0;
-	configure.speaker=(state->flags&SS_SPKR_ENA)?1:0;
-	configure.reset=(state->flags&SS_RESET)?1:0;
-
-	if(pcmcia_low_level->configure_socket(&configure)<0){
-		printk(KERN_ERR "Unable to configure socket %u\n", sock);
-		return -1;
-	}
-
-	pcmcia_socket[sock].cs_state = *state;
-	return 0;
-
-}  /* au1000_pcmcia_set_socket() */
-
-
-static int 
-au1000_pcmcia_get_io_map(unsigned int sock, struct pccard_io_map *map)
-{
-	debug(1, "au1000_pcmcia_get_io_map: sock %d\n", sock);
-	if(map->map>=MAX_IO_WIN){
-		printk(KERN_ERR "%s(): map (%d) out of range\n", 
-				__FUNCTION__, map->map);
-		return -1;
-	}
-	*map=pcmcia_socket[sock].io_map[map->map];
-	return 0;
+  return au1x00_pcmcia_config_skt(skt, state);
 }
 
-
 int 
-au1000_pcmcia_set_io_map(unsigned int sock, struct pccard_io_map *map)
+au1x00_pcmcia_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *map)
 {
+	struct au1000_pcmcia_socket *skt = to_au1000_socket(sock);
 	unsigned int speed;
-	unsigned long start;
 
 	if(map->map>=MAX_IO_WIN){
-		printk(KERN_ERR "%s(): map (%d) out of range\n", 
-				__FUNCTION__, map->map);
+		debug("map (%d) out of range\n", map->map);
 		return -1;
 	}
 
 	if(map->flags&MAP_ACTIVE){
 		speed=(map->speed>0)?map->speed:AU1000_PCMCIA_IO_SPEED;
-		pcmcia_socket[sock].speed_io=speed;
+		skt->spd_io[map->map] = speed;
 	}
 
-	start=map->start;
-
-	if(map->stop==1) {
-		map->stop=PAGE_SIZE-1;
-	}
-
-	map->start=pcmcia_socket[sock].virt_io;
-	map->stop=map->start+(map->stop-start);
-	pcmcia_socket[sock].io_map[map->map]=*map;
-	debug(3, "set_io_map %d start %x stop %x\n", 
-			map->map, map->start, map->stop);
+	map->start=(ioaddr_t)(u32)skt->virt_io;
+	map->stop=map->start+MAP_SIZE;
 	return 0;
 
-}  /* au1000_pcmcia_set_io_map() */
+}  /* au1x00_pcmcia_set_io_map() */
 
 
 static int 
-au1000_pcmcia_get_mem_map(unsigned int sock, struct pccard_mem_map *map)
+au1x00_pcmcia_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *map)
 {
+	struct au1000_pcmcia_socket *skt = to_au1000_socket(sock);
+	unsigned short speed = map->speed;
 
-	if(map->map>=MAX_WIN) {
-		printk(KERN_ERR "%s(): map (%d) out of range\n", 
-				__FUNCTION__, map->map);
+	if(map->map>=MAX_WIN){
+		debug("map (%d) out of range\n", map->map);
 		return -1;
 	}
-	*map=pcmcia_socket[sock].mem_map[map->map];
+
+	if (map->flags & MAP_ATTRIB) {
+		skt->spd_attr[map->map] = speed;
+		skt->spd_mem[map->map] = 0;
+	} else {
+		skt->spd_attr[map->map] = 0;
+		skt->spd_mem[map->map] = speed;
+	}
+
+	if (map->flags & MAP_ATTRIB) {
+		map->static_start = skt->phys_attr + map->card_start;
+	}
+	else {
+		map->static_start = skt->phys_mem + map->card_start;
+	}
+
+	debug("set_mem_map %d start %08lx card_start %08x\n",
+			map->map, map->static_start, map->card_start);
 	return 0;
-}
 
+}  /* au1x00_pcmcia_set_mem_map() */
 
-static int 
-au1000_pcmcia_set_mem_map(unsigned int sock, struct pccard_mem_map *map)
+static struct pccard_operations au1x00_pcmcia_operations = {
+	.init			= au1x00_pcmcia_sock_init,
+	.suspend		= au1x00_pcmcia_suspend,
+	.get_status		= au1x00_pcmcia_get_status,
+	.get_socket		= au1x00_pcmcia_get_socket,
+	.set_socket		= au1x00_pcmcia_set_socket,
+	.set_io_map		= au1x00_pcmcia_set_io_map,
+	.set_mem_map		= au1x00_pcmcia_set_mem_map,
+};
+
+static const char *skt_names[] = {
+	"PCMCIA socket 0",
+	"PCMCIA socket 1",
+};
+
+struct skt_dev_info {
+	int nskt;
+};
+
+int au1x00_pcmcia_socket_probe(struct device *dev, struct pcmcia_low_level *ops, int first, int nr)
 {
-	unsigned int speed;
-	u_long flags;
+	struct skt_dev_info *sinfo;
+	int ret, i;
 
-	if(map->map>=MAX_WIN){
-		printk(KERN_ERR "%s(): map (%d) out of range\n", 
-				__FUNCTION__, map->map);
-		return -1;
+	sinfo = kmalloc(sizeof(struct skt_dev_info), GFP_KERNEL);
+	if (!sinfo) {
+		ret = -ENOMEM;
+		goto out;
 	}
 
-	if(map->flags&MAP_ACTIVE){
-		speed=(map->speed>0)?map->speed:AU1000_PCMCIA_MEM_SPEED;
+	memset(sinfo, 0, sizeof(struct skt_dev_info));
+	sinfo->nskt = nr;
 
-		/* TBD */
-		if(map->flags&MAP_ATTRIB){
-			pcmcia_socket[sock].speed_attr=speed;
-		} 
-		else {
-			pcmcia_socket[sock].speed_mem=speed;
+	/*
+	 * Initialise the per-socket structure.
+	 */
+	for (i = 0; i < nr; i++) {
+		struct au1000_pcmcia_socket *skt = PCMCIA_SOCKET(i);
+		memset(skt, 0, sizeof(*skt));
+
+		skt->socket.ops = &au1x00_pcmcia_operations;
+		skt->socket.owner = ops->owner;
+		skt->socket.dev.dev = dev;
+
+		init_timer(&skt->poll_timer);
+		skt->poll_timer.function = au1x00_pcmcia_poll_event;
+		skt->poll_timer.data = (unsigned long)skt;
+		skt->poll_timer.expires = jiffies + AU1000_PCMCIA_POLL_PERIOD;
+
+		skt->nr		= first + i;
+		skt->irq	= 255;
+		skt->dev	= dev;
+		skt->ops	= ops;
+
+		skt->res_skt.name	= skt_names[skt->nr];
+		skt->res_io.name	= "io";
+		skt->res_io.flags	= IORESOURCE_MEM | IORESOURCE_BUSY;
+		skt->res_mem.name	= "memory";
+		skt->res_mem.flags	= IORESOURCE_MEM;
+		skt->res_attr.name	= "attribute";
+		skt->res_attr.flags	= IORESOURCE_MEM;
+
+		/*
+		 * PCMCIA client drivers use the inb/outb macros to access the
+		 * IO registers. Since mips_io_port_base is added to the
+		 * access address of the mips implementation of inb/outb,
+		 * we need to subtract it here because we want to access the
+		 * I/O or MEM address directly, without going through this
+		 * "mips_io_port_base" mechanism.
+		 */
+		if (i == 0) {
+			skt->virt_io = (void *)
+				(ioremap((phys_t)AU1X_SOCK0_IO, 0x1000) -
+				(u32)mips_io_port_base);
+			skt->phys_attr = AU1X_SOCK0_PSEUDO_PHYS_ATTR;
+			skt->phys_mem = AU1X_SOCK0_PSEUDO_PHYS_MEM;
 		}
-	}
+#ifndef CONFIG_MIPS_XXS1500
+		else  {
+			skt->virt_io = (void *)
+				(ioremap((phys_t)AU1X_SOCK1_IO, 0x1000) -
+				(u32)mips_io_port_base);
+			skt->phys_attr = AU1X_SOCK1_PSEUDO_PHYS_ATTR;
+			skt->phys_mem = AU1X_SOCK1_PSEUDO_PHYS_MEM;
+		}
+#endif
+		pcmcia_base_vaddrs[i] = (u32 *)skt->virt_io;
+		ret = ops->hw_init(skt);
 
-	spin_lock_irqsave(&pcmcia_lock, flags);
-	if (map->flags & MAP_ATTRIB) {
-		map->static_start = pcmcia_socket[sock].phys_attr + 
-			map->card_start;
-	}
-	else {
-		map->static_start = pcmcia_socket[sock].phys_mem + 
-			map->card_start;
+		skt->socket.features = SS_CAP_STATIC_MAP|SS_CAP_PCCARD;
+		skt->socket.irq_mask = 0;
+		skt->socket.map_size = MAP_SIZE;
+		skt->socket.pci_irq = skt->irq;
+		skt->socket.io_offset = (unsigned long)skt->virt_io;
+
+		skt->status = au1x00_pcmcia_skt_state(skt);
+
+		ret = pcmcia_register_socket(&skt->socket);
+		if (ret)
+			goto out_err;
+
+		WARN_ON(skt->socket.sock != i);
+
+		add_timer(&skt->poll_timer);
 	}
 
-	pcmcia_socket[sock].mem_map[map->map]=*map;
-	spin_unlock_irqrestore(&pcmcia_lock, flags);
-	debug(3, "set_mem_map %d start %x card_start %x\n", 
-			map->map, map->static_start,
-			map->card_start);
+	dev_set_drvdata(dev, sinfo);
 	return 0;
 
-}  /* au1000_pcmcia_set_mem_map() */
+	do {
+		struct au1000_pcmcia_socket *skt = PCMCIA_SOCKET(i);
+
+		del_timer_sync(&skt->poll_timer);
+		pcmcia_unregister_socket(&skt->socket);
+out_err:
+		flush_scheduled_work();
+		ops->hw_shutdown(skt);
+
+		i--;
+	} while (i > 0);
+	kfree(sinfo);
+out:
+	return ret;
+}
+
+int au1x00_drv_pcmcia_remove(struct device *dev)
+{
+	struct skt_dev_info *sinfo = dev_get_drvdata(dev);
+	int i;
+
+	down(&pcmcia_sockets_lock);
+	dev_set_drvdata(dev, NULL);
 
+	for (i = 0; i < sinfo->nskt; i++) {
+		struct au1000_pcmcia_socket *skt = PCMCIA_SOCKET(i);
+
+		del_timer_sync(&skt->poll_timer);
+		pcmcia_unregister_socket(&skt->socket);
+		flush_scheduled_work();
+		skt->ops->hw_shutdown(skt);
+		au1x00_pcmcia_config_skt(skt, &dead_socket);
+		iounmap(skt->virt_io);
+		skt->virt_io = NULL;
+	}
+
+	kfree(sinfo);
+	up(&pcmcia_sockets_lock);
+	return 0;
+}
 
-#if defined(CONFIG_PROC_FS)
 
-static void 
-au1000_pcmcia_proc_setup(unsigned int sock, struct proc_dir_entry *base)
+/*
+ * PCMCIA "Driver" API
+ */
+
+static int au1x00_drv_pcmcia_probe(struct device *dev)
 {
-	struct proc_dir_entry *entry;
+	int i, ret = -ENODEV;
 
-	if((entry=create_proc_entry("status", 0, base))==NULL){
-		printk(KERN_ERR "Unable to install \"status\" procfs entry\n");
-		return;
+	down(&pcmcia_sockets_lock);
+	for (i=0; i < ARRAY_SIZE(au1x00_pcmcia_hw_init); i++) {
+		ret = au1x00_pcmcia_hw_init[i](dev);
+		if (ret == 0)
+			break;
 	}
+	up(&pcmcia_sockets_lock);
+	return ret;
+}
 
-	entry->read_proc=au1000_pcmcia_proc_status;
-	entry->data=(void *)sock;
+
+static int au1x00_drv_pcmcia_suspend(struct device *dev, u32 state, u32 level)
+{
+	int ret = 0;
+	if (level == SUSPEND_SAVE_STATE)
+		ret = pcmcia_socket_dev_suspend(dev, state);
+	return ret;
 }
 
+static int au1x00_drv_pcmcia_resume(struct device *dev, u32 level)
+{
+	int ret = 0;
+	if (level == RESUME_RESTORE_STATE)
+		ret = pcmcia_socket_dev_resume(dev);
+	return ret;
+}
+
+
+static struct device_driver au1x00_pcmcia_driver = {
+	.probe		= au1x00_drv_pcmcia_probe,
+	.remove		= au1x00_drv_pcmcia_remove,
+	.name		= "au1x00-pcmcia",
+	.bus		= &platform_bus_type,
+	.suspend	= au1x00_drv_pcmcia_suspend,
+	.resume		= au1x00_drv_pcmcia_resume
+};
+
+static struct platform_device au1x00_device = {
+	.name = "au1x00-pcmcia",
+	.id = 0,
+};
 
-/* au1000_pcmcia_proc_status()
- * Implements the /proc/bus/pccard/??/status file.
+/* au1x00_pcmcia_init()
  *
- * Returns: the number of characters added to the buffer
+ * This routine performs low-level PCMCIA initialization and then
+ * registers this socket driver with Card Services.
+ *
+ * Returns: 0 on success, -ve error code on failure
  */
-static int 
-au1000_pcmcia_proc_status(char *buf, char **start, off_t pos, 
-		int count, int *eof, void *data)
+static int __init au1x00_pcmcia_init(void)
 {
-	char *p=buf;
-	unsigned int sock=(unsigned int)data;
-
-	p+=sprintf(p, "k_flags  : %s%s%s%s%s%s%s\n", 
-	     pcmcia_socket[sock].k_state.detect?"detect ":"",
-	     pcmcia_socket[sock].k_state.ready?"ready ":"",
-	     pcmcia_socket[sock].k_state.bvd1?"bvd1 ":"",
-	     pcmcia_socket[sock].k_state.bvd2?"bvd2 ":"",
-	     pcmcia_socket[sock].k_state.wrprot?"wrprot ":"",
-	     pcmcia_socket[sock].k_state.vs_3v?"vs_3v ":"",
-	     pcmcia_socket[sock].k_state.vs_Xv?"vs_Xv ":"");
-
-	p+=sprintf(p, "status   : %s%s%s%s%s%s%s%s%s\n",
-	     pcmcia_socket[sock].k_state.detect?"SS_DETECT ":"",
-	     pcmcia_socket[sock].k_state.ready?"SS_READY ":"",
-	     pcmcia_socket[sock].cs_state.Vcc?"SS_POWERON ":"",
-	     pcmcia_socket[sock].cs_state.flags&SS_IOCARD?\
-	     "SS_IOCARD ":"",
-	     (pcmcia_socket[sock].cs_state.flags&SS_IOCARD &&
-	      pcmcia_socket[sock].k_state.bvd1)?"SS_STSCHG ":"",
-	     ((pcmcia_socket[sock].cs_state.flags&SS_IOCARD)==0 &&
-	      (pcmcia_socket[sock].k_state.bvd1==0))?"SS_BATDEAD ":"",
-	     ((pcmcia_socket[sock].cs_state.flags&SS_IOCARD)==0 &&
-	      (pcmcia_socket[sock].k_state.bvd2==0))?"SS_BATWARN ":"",
-	     pcmcia_socket[sock].k_state.vs_3v?"SS_3VCARD ":"",
-	     pcmcia_socket[sock].k_state.vs_Xv?"SS_XVCARD ":"");
-
-	p+=sprintf(p, "mask     : %s%s%s%s%s\n",
-	     pcmcia_socket[sock].cs_state.csc_mask&SS_DETECT?\
-	     "SS_DETECT ":"",
-	     pcmcia_socket[sock].cs_state.csc_mask&SS_READY?\
-	     "SS_READY ":"",
-	     pcmcia_socket[sock].cs_state.csc_mask&SS_BATDEAD?\
-	     "SS_BATDEAD ":"",
-	     pcmcia_socket[sock].cs_state.csc_mask&SS_BATWARN?\
-	     "SS_BATWARN ":"",
-	     pcmcia_socket[sock].cs_state.csc_mask&SS_STSCHG?\
-	     "SS_STSCHG ":"");
-
-	p+=sprintf(p, "cs_flags : %s%s%s%s%s\n",
-	     pcmcia_socket[sock].cs_state.flags&SS_PWR_AUTO?\
-	     "SS_PWR_AUTO ":"",
-	     pcmcia_socket[sock].cs_state.flags&SS_IOCARD?\
-	     "SS_IOCARD ":"",
-	     pcmcia_socket[sock].cs_state.flags&SS_RESET?\
-	     "SS_RESET ":"",
-	     pcmcia_socket[sock].cs_state.flags&SS_SPKR_ENA?\
-	     "SS_SPKR_ENA ":"",
-	     pcmcia_socket[sock].cs_state.flags&SS_OUTPUT_ENA?\
-	     "SS_OUTPUT_ENA ":"");
-
-	p+=sprintf(p, "Vcc      : %d\n", pcmcia_socket[sock].cs_state.Vcc);
-	p+=sprintf(p, "Vpp      : %d\n", pcmcia_socket[sock].cs_state.Vpp);
-	p+=sprintf(p, "irq      : %d\n", pcmcia_socket[sock].cs_state.io_irq);
-	p+=sprintf(p, "I/O      : %u\n", pcmcia_socket[sock].speed_io);
-	p+=sprintf(p, "attribute: %u\n", pcmcia_socket[sock].speed_attr);
-	p+=sprintf(p, "common   : %u\n", pcmcia_socket[sock].speed_mem);
-	return p-buf;
+	int error = 0;
+	if ((error = driver_register(&au1x00_pcmcia_driver)))
+		return error;
+	platform_device_register(&au1x00_device);
+	return error;
 }
 
+/* au1x00_pcmcia_exit()
+ * Invokes the low-level kernel service to free IRQs associated with this
+ * socket controller and reset GPIO edge detection.
+ */
+static void __exit au1x00_pcmcia_exit(void)
+{
+	driver_unregister(&au1x00_pcmcia_driver);
+	platform_device_unregister(&au1x00_device);
+}
 
-#endif  /* defined(CONFIG_PROC_FS) */
+module_init(au1x00_pcmcia_init);
+module_exit(au1x00_pcmcia_exit);
diff -Nru a/drivers/pcmcia/au1000_generic.h b/drivers/pcmcia/au1000_generic.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/pcmcia/au1000_generic.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,150 @@
+/*
+ * Alchemy Semi Au1000 pcmcia driver include file
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You 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 __ASM_AU1000_PCMCIA_H
+#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>
+#include <pcmcia/bulkmem.h>
+#include <pcmcia/cistpl.h>
+#include "cs_internal.h"
+
+#define AU1000_PCMCIA_POLL_PERIOD    (2*HZ)
+#define AU1000_PCMCIA_IO_SPEED       (255)
+#define AU1000_PCMCIA_MEM_SPEED      (300)
+
+#define AU1X_SOCK0_IO        0xF00000000
+#define AU1X_SOCK0_PHYS_ATTR 0xF40000000
+#define AU1X_SOCK0_PHYS_MEM  0xF80000000
+/* pseudo 32 bit phys addresses, which get fixed up to the
+ * real 36 bit address in fixup_bigphys_addr() */
+#define AU1X_SOCK0_PSEUDO_PHYS_ATTR 0xF4000000
+#define AU1X_SOCK0_PSEUDO_PHYS_MEM  0xF8000000
+
+/* pcmcia socket 1 needs external glue logic so the memory map
+ * differs from board to board.
+ */
+#if defined(CONFIG_MIPS_PB1000) || defined(CONFIG_MIPS_PB1100) || defined(CONFIG_MIPS_PB1500) || defined(CONFIG_MIPS_PB1550)
+#define AU1X_SOCK1_IO        0xF08000000
+#define AU1X_SOCK1_PHYS_ATTR 0xF48000000
+#define AU1X_SOCK1_PHYS_MEM  0xF88000000
+#define AU1X_SOCK1_PSEUDO_PHYS_ATTR 0xF4800000
+#define AU1X_SOCK1_PSEUDO_PHYS_MEM  0xF8800000
+#elif defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) || defined(CONFIG_MIPS_DB1500) || defined(CONFIG_MIPS_DB1550)
+#define AU1X_SOCK1_IO        0xF04000000
+#define AU1X_SOCK1_PHYS_ATTR 0xF44000000
+#define AU1X_SOCK1_PHYS_MEM  0xF84000000
+#define AU1X_SOCK1_PSEUDO_PHYS_ATTR 0xF4400000
+#define AU1X_SOCK1_PSEUDO_PHYS_MEM  0xF8400000
+#endif
+
+struct pcmcia_state {
+  unsigned detect: 1,
+            ready: 1,
+           wrprot: 1,
+	     bvd1: 1,
+	     bvd2: 1,
+            vs_3v: 1,
+            vs_Xv: 1;
+};
+
+struct pcmcia_configure {
+  unsigned sock: 8,
+            vcc: 8,
+            vpp: 8,
+         output: 1,
+        speaker: 1,
+          reset: 1;
+};
+
+struct pcmcia_irqs {
+	int sock;
+	int irq;
+	const char *str;
+};
+
+
+struct au1000_pcmcia_socket {
+	struct pcmcia_socket socket;
+
+	/*
+	 * Info from low level handler
+	 */
+	struct device		*dev;
+	unsigned int		nr;
+	unsigned int		irq;
+
+	/*
+	 * Core PCMCIA state
+	 */
+	struct pcmcia_low_level *ops;
+
+	unsigned int 		status;
+	socket_state_t		cs_state;
+
+	unsigned short		spd_io[MAX_IO_WIN];
+	unsigned short		spd_mem[MAX_WIN];
+	unsigned short		spd_attr[MAX_WIN];
+
+	struct resource		res_skt;
+	struct resource		res_io;
+	struct resource		res_mem;
+	struct resource		res_attr;
+
+	void *                 	virt_io;
+	ioaddr_t              	phys_io;
+	unsigned int           	phys_attr;
+	unsigned int           	phys_mem;
+	unsigned short        	speed_io, speed_attr, speed_mem;
+
+	unsigned int		irq_state;
+
+	struct timer_list	poll_timer;
+};
+
+struct pcmcia_low_level {
+	struct module *owner;
+
+	int (*hw_init)(struct au1000_pcmcia_socket *);
+	void (*hw_shutdown)(struct au1000_pcmcia_socket *);
+
+	void (*socket_state)(struct au1000_pcmcia_socket *, struct pcmcia_state *);
+	int (*configure_socket)(struct au1000_pcmcia_socket *, struct socket_state_t *);
+
+	/*
+	 * Enable card status IRQs on (re-)initialisation.  This can
+	 * be called at initialisation, power management event, or
+	 * pcmcia event.
+	 */
+	void (*socket_init)(struct au1000_pcmcia_socket *);
+
+	/*
+	 * Disable card status IRQs and PCMCIA bus on suspend.
+	 */
+	void (*socket_suspend)(struct au1000_pcmcia_socket *);
+};
+
+extern int au1x_board_init(struct device *dev);
+
+#endif /* __ASM_AU1000_PCMCIA_H */
diff -Nru a/drivers/pcmcia/au1000_pb1x00.c b/drivers/pcmcia/au1000_pb1x00.c
--- a/drivers/pcmcia/au1000_pb1x00.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/pcmcia/au1000_pb1x00.c	2005-03-01 23:38:54 -08:00
@@ -30,6 +30,7 @@
 #include <linux/timer.h>
 #include <linux/mm.h>
 #include <linux/proc_fs.h>
+#include <linux/version.h>
 #include <linux/types.h>
 
 #include <pcmcia/version.h>
@@ -55,7 +56,7 @@
 #define PCMCIA_IRQ AU1000_GPIO_15
 #elif defined (CONFIG_MIPS_PB1500)
 #include <asm/pb1500.h>
-#define PCMCIA_IRQ AU1000_GPIO_11   /* fixme */
+#define PCMCIA_IRQ AU1500_GPIO_203
 #elif defined (CONFIG_MIPS_PB1100)
 #include <asm/pb1100.h>
 #define PCMCIA_IRQ AU1000_GPIO_11
@@ -82,9 +83,9 @@
 #else /* fixme -- take care of the Pb1500 at some point */
 
 	u16 pcr;
-	pcr = au_readw(PB1100_MEM_PCMCIA) & ~0xf; /* turn off power */
-	pcr &= ~(PB1100_PC_DEASSERT_RST | PB1100_PC_DRV_EN);
-	au_writew(pcr, PB1100_MEM_PCMCIA);
+	pcr = au_readw(PCMCIA_BOARD_REG) & ~0xf; /* turn off power */
+	pcr &= ~(PC_DEASSERT_RST | PC_DRV_EN);
+	au_writew(pcr, PCMCIA_BOARD_REG);
 	au_sync_delay(500);
 	return PCMCIA_NUM_SOCKS;
 #endif
@@ -102,9 +103,9 @@
 	return 0;
 #else
 	u16 pcr;
-	pcr = au_readw(PB1100_MEM_PCMCIA) & ~0xf; /* turn off power */
-	pcr &= ~(PB1100_PC_DEASSERT_RST | PB1100_PC_DRV_EN);
-	au_writew(pcr, PB1100_MEM_PCMCIA);
+	pcr = au_readw(PCMCIA_BOARD_REG) & ~0xf; /* turn off power */
+	pcr &= ~(PC_DEASSERT_RST | PC_DRV_EN);
+	au_writew(pcr, PCMCIA_BOARD_REG);
 	au_sync_delay(2);
 	return 0;
 #endif
@@ -123,9 +124,14 @@
 	vs0 = (vs0 >> 4) & 0x3;
 	vs1 = (vs1 >> 12) & 0x3;
 #else
-	vs0 = (au_readw(PB1100_BOARD_STATUS) >> 4) & 0x3;
+	vs0 = (au_readw(BOARD_STATUS_REG) >> 4) & 0x3;
+#ifdef CONFIG_MIPS_PB1500
+	inserted0 = !((au_readl(GPIO2_PINSTATE) >> 1) & 0x1); /* gpio 201 */
+#else /* Pb1100 */
 	inserted0 = !((au_readl(SYS_PINSTATERD) >> 9) & 0x1); /* gpio 9 */
 #endif
+	inserted1 = 0;
+#endif
 
 	state->ready = 0;
 	state->vs_Xv = 0;
@@ -145,7 +151,7 @@
 					/* return without setting 'detect' */
 					printk(KERN_ERR "pb1x00 bad VS (%d)\n",
 							vs0);
-					return;
+					return 0;
 			}
 			state->detect = 1;
 		}
@@ -163,7 +169,7 @@
 					/* return without setting 'detect' */
 					printk(KERN_ERR "pb1x00 bad VS (%d)\n",
 							vs1);
-					return;
+					return 0;
 			}
 			state->detect = 1;
 		}
@@ -324,7 +330,7 @@
 
 #else
 
-	pcr = au_readw(PB1100_MEM_PCMCIA) & ~0xf;
+	pcr = au_readw(PCMCIA_BOARD_REG) & ~0xf;
 
 	debug("Vcc %dV Vpp %dV, pcr %x, reset %d\n", 
 			configure->vcc, configure->vpp, pcr, configure->reset);
@@ -383,25 +389,26 @@
 			break;
 	}
 
-	au_writew(pcr, PB1100_MEM_PCMCIA);
+	au_writew(pcr, PCMCIA_BOARD_REG);
 	au_sync_delay(300);
 
 	if (!configure->reset) {
-		pcr |= PB1100_PC_DRV_EN;
-		au_writew(pcr, PB1100_MEM_PCMCIA);
+		pcr |= PC_DRV_EN;
+		au_writew(pcr, PCMCIA_BOARD_REG);
 		au_sync_delay(100);
-		pcr |= PB1100_PC_DEASSERT_RST;
-		au_writew(pcr, PB1100_MEM_PCMCIA);
+		pcr |= PC_DEASSERT_RST;
+		au_writew(pcr, PCMCIA_BOARD_REG);
 		au_sync_delay(100);
 	}
 	else {
-		pcr &= ~(PB1100_PC_DEASSERT_RST | PB1100_PC_DRV_EN);
-		au_writew(pcr, PB1100_MEM_PCMCIA);
+		pcr &= ~(PC_DEASSERT_RST | PC_DRV_EN);
+		au_writew(pcr, PCMCIA_BOARD_REG);
 		au_sync_delay(100);
 	}
 #endif
 	return 0;
 }
+
 
 struct pcmcia_low_level pb1x00_pcmcia_ops = { 
 	pb1x00_pcmcia_init,
diff -Nru a/drivers/pcmcia/au1000_xxs1500.c b/drivers/pcmcia/au1000_xxs1500.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/pcmcia/au1000_xxs1500.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,191 @@
+/*
+ *
+ * MyCable board specific pcmcia routines.
+ *
+ * Copyright 2003 MontaVista Software Inc.
+ * Author: Pete Popov, MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You 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/init.h>
+#include <linux/config.h>
+#include <linux/delay.h>
+#include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/tqueue.h>
+#include <linux/timer.h>
+#include <linux/mm.h>
+#include <linux/proc_fs.h>
+#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>
+#include <pcmcia/bulkmem.h>
+#include <pcmcia/cistpl.h>
+#include <pcmcia/bus_ops.h>
+#include "cs_internal.h"
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+
+#include <asm/au1000.h>
+#include <asm/au1000_pcmcia.h>
+#include <asm/xxs1500.h>
+
+#if 0
+#define DEBUG(x,args...)	printk(__FUNCTION__ ": " x,##args)
+#else
+#define DEBUG(x,args...)
+#endif
+
+static int xxs1500_pcmcia_init(struct pcmcia_init *init)
+{
+	return PCMCIA_NUM_SOCKS;
+}
+
+static int xxs1500_pcmcia_shutdown(void)
+{
+	/* turn off power */
+	au_writel(au_readl(GPIO2_PINSTATE) | (1<<14)|(1<<30),
+			GPIO2_OUTPUT);
+	au_sync_delay(100);
+
+	/* assert reset */
+	au_writel(au_readl(GPIO2_PINSTATE) | (1<<4)|(1<<20),
+			GPIO2_OUTPUT);
+	au_sync_delay(100);
+	return 0;
+}
+
+
+static int
+xxs1500_pcmcia_socket_state(unsigned sock, struct pcmcia_state *state)
+{
+	u32 inserted; u32 vs;
+	unsigned long gpio, gpio2;
+
+	if(sock > PCMCIA_MAX_SOCK) return -1;
+
+	gpio = au_readl(SYS_PINSTATERD);
+	gpio2 = au_readl(GPIO2_PINSTATE);
+
+	vs = gpio2 & ((1<<8) | (1<<9));
+	inserted = (!(gpio & 0x1) && !(gpio & 0x2));
+
+	state->ready = 0;
+	state->vs_Xv = 0;
+	state->vs_3v = 0;
+	state->detect = 0;
+
+	if (inserted) {
+		switch (vs) {
+			case 0:
+			case 1:
+			case 2:
+				state->vs_3v=1;
+				break;
+			case 3: /* 5V */
+			default:
+				/* return without setting 'detect' */
+				printk(KERN_ERR "au1x00_cs: unsupported VS\n",
+						vs);
+				return;
+		}
+		state->detect = 1;
+	}
+
+	if (state->detect) {
+		state->ready = 1;
+	}
+
+	state->bvd1= gpio2 & (1<<10);
+	state->bvd2 = gpio2 & (1<<11);
+	state->wrprot=0;
+	return 1;
+}
+
+
+static int xxs1500_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
+{
+
+	if(info->sock > PCMCIA_MAX_SOCK) return -1;
+	info->irq = PCMCIA_IRQ;
+	return 0;
+}
+
+
+static int
+xxs1500_pcmcia_configure_socket(const struct pcmcia_configure *configure)
+{
+
+	if(configure->sock > PCMCIA_MAX_SOCK) return -1;
+
+	DEBUG("Vcc %dV Vpp %dV, reset %d\n",
+			configure->vcc, configure->vpp, configure->reset);
+
+	switch(configure->vcc){
+		case 33: /* Vcc 3.3V */
+			/* turn on power */
+			DEBUG("turn on power\n");
+			au_writel((au_readl(GPIO2_PINSTATE) & ~(1<<14))|(1<<30),
+					GPIO2_OUTPUT);
+			au_sync_delay(100);
+			break;
+		case 50: /* Vcc 5V */
+		default: /* what's this ? */
+			printk(KERN_ERR "au1x00_cs: unsupported VCC\n");
+		case 0:  /* Vcc 0 */
+			/* turn off power */
+			au_sync_delay(100);
+			au_writel(au_readl(GPIO2_PINSTATE) | (1<<14)|(1<<30),
+					GPIO2_OUTPUT);
+			break;
+	}
+
+	if (!configure->reset) {
+		DEBUG("deassert reset\n");
+		au_writel((au_readl(GPIO2_PINSTATE) & ~(1<<4))|(1<<20),
+				GPIO2_OUTPUT);
+		au_sync_delay(100);
+		au_writel((au_readl(GPIO2_PINSTATE) & ~(1<<5))|(1<<21),
+				GPIO2_OUTPUT);
+	}
+	else {
+		DEBUG("assert reset\n");
+		au_writel(au_readl(GPIO2_PINSTATE) | (1<<4)|(1<<20),
+				GPIO2_OUTPUT);
+	}
+	au_sync_delay(100);
+	return 0;
+}
+
+struct pcmcia_low_level xxs1500_pcmcia_ops = {
+	xxs1500_pcmcia_init,
+	xxs1500_pcmcia_shutdown,
+	xxs1500_pcmcia_socket_state,
+	xxs1500_pcmcia_get_irq_info,
+	xxs1500_pcmcia_configure_socket
+};
diff -Nru a/drivers/pcmcia/bulkmem.c b/drivers/pcmcia/bulkmem.c
--- a/drivers/pcmcia/bulkmem.c	2005-03-01 23:39:18 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,218 +0,0 @@
-/*======================================================================
-
-    PCMCIA Bulk Memory Services
-
-    bulkmem.c 1.38 2000/09/25 19:29:51
-
-    The contents of this file are subject to the Mozilla Public
-    License Version 1.1 (the "License"); you may not use this file
-    except in compliance with the License. You may obtain a copy of
-    the License at http://www.mozilla.org/MPL/
-
-    Software distributed under the License is distributed on an "AS
-    IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-    implied. See the License for the specific language governing
-    rights and limitations under the License.
-
-    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.
-
-    Alternatively, the contents of this file may be used under the
-    terms of the GNU General Public License version 2 (the "GPL"), in which
-    case the provisions of the GPL are applicable instead of the
-    above.  If you wish to allow the use of your version of this file
-    only under the terms of the GPL and not to allow others to use
-    your version of this file under the MPL, indicate your decision
-    by deleting the provisions above and replace them with the notice
-    and other provisions required by the GPL.  If you do not delete
-    the provisions above, a recipient may use your version of this
-    file under either the MPL or the GPL.
-    
-======================================================================*/
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/sched.h>
-#include <linux/timer.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 "cs_internal.h"
-
-#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 "ds: %s: " fmt, 	\
-		       cs_socket_name(skt) , ## arg);	\
-} while (0)
-#else
-#define ds_dbg(lvl, fmt, arg...) do { } while (0)
-#endif
-
-/*======================================================================
-
-    This stuff is used by Card Services to initialize the table of
-    region info used for subsequent calls to GetFirstRegion and
-    GetNextRegion.
-    
-======================================================================*/
-
-static void setup_regions(struct pcmcia_socket *s, unsigned int function,
-			  int attr,  memory_handle_t *list)
-{
-    int i, code, has_jedec, has_geo;
-    u_int offset;
-    cistpl_device_t device;
-    cistpl_jedec_t jedec;
-    cistpl_device_geo_t geo;
-    memory_handle_t r;
-
-    ds_dbg(s, 1, "setup_regions(0x%d, %d, 0x%p)\n",
-	   function, attr, list);
-
-    code = (attr) ? CISTPL_DEVICE_A : CISTPL_DEVICE;
-    if (pccard_read_tuple(s, function, code, &device) != CS_SUCCESS)
-	return;
-    code = (attr) ? CISTPL_JEDEC_A : CISTPL_JEDEC_C;
-    has_jedec = (pccard_read_tuple(s, function, code, &jedec) == CS_SUCCESS);
-    if (has_jedec && (device.ndev != jedec.nid)) {
-	ds_dbg(s, 0, "Device info does not match JEDEC info.\n");
-	has_jedec = 0;
-    }
-    code = (attr) ? CISTPL_DEVICE_GEO_A : CISTPL_DEVICE_GEO;
-    has_geo = (pccard_read_tuple(s, function, code, &geo) == CS_SUCCESS);
-    if (has_geo && (device.ndev != geo.ngeo)) {
-	ds_dbg(s, 0, "Device info does not match geometry tuple.\n");
-	has_geo = 0;
-    }
-    
-    offset = 0;
-    for (i = 0; i < device.ndev; i++) {
-	if ((device.dev[i].type != CISTPL_DTYPE_NULL) &&
-	    (device.dev[i].size != 0)) {
-	    r = kmalloc(sizeof(*r), GFP_KERNEL);
-	    if (!r) {
-		printk(KERN_NOTICE "cs: setup_regions: kmalloc failed!\n");
-		return;
-	    }
-	    r->region_magic = REGION_MAGIC;
-	    r->state = 0;
-	    r->dev_info[0] = '\0';
-	    r->mtd = NULL;
-	    r->info.Attributes = (attr) ? REGION_TYPE_AM : 0;
-	    r->info.CardOffset = offset;
-	    r->info.RegionSize = device.dev[i].size;
-	    r->info.AccessSpeed = device.dev[i].speed;
-	    if (has_jedec) {
-		r->info.JedecMfr = jedec.id[i].mfr;
-		r->info.JedecInfo = jedec.id[i].info;
-	    } else
-		r->info.JedecMfr = r->info.JedecInfo = 0;
-	    if (has_geo) {
-		r->info.BlockSize = geo.geo[i].buswidth *
-		    geo.geo[i].erase_block * geo.geo[i].interleave;
-		r->info.PartMultiple =
-		    r->info.BlockSize * geo.geo[i].partition;
-	    } else
-		r->info.BlockSize = r->info.PartMultiple = 1;
-	    r->info.next = *list; *list = r;
-	}
-	offset += device.dev[i].size;
-    }
-} /* setup_regions */
-
-/*======================================================================
-
-    This is tricky.  When get_first_region() is called by Driver
-    Services, we initialize the region info table in the socket
-    structure.  When it is called by an MTD, we can just scan the
-    table for matching entries.
-    
-======================================================================*/
-
-static int pccard_match_region(memory_handle_t list, region_info_t *match)
-{
-	if (list) {
-		*match = list->info;
-		return CS_SUCCESS;
-	}
-	return CS_NO_MORE_ITEMS;
-} /* match_region */
-
-int pccard_get_first_region(struct pcmcia_socket *s, region_info_t *rgn)
-{
-	if (!(s->state & SOCKET_REGION_INFO)) {
-		setup_regions(s, BIND_FN_ALL, 0, &s->c_region);
-		setup_regions(s, BIND_FN_ALL, 1, &s->a_region);
-		s->state |= SOCKET_REGION_INFO;
-	}
-
-	if (rgn->Attributes & REGION_TYPE_AM)
-		return pccard_match_region(s->a_region, rgn);
-	else
-		return pccard_match_region(s->c_region, rgn);
-} /* get_first_region */
-
-int pccard_get_next_region(struct pcmcia_socket *s, region_info_t *rgn)
-{
-    return pccard_match_region(rgn->next, rgn);
-} /* get_next_region */
-
-
-#ifdef CONFIG_PCMCIA_OBSOLETE
-
-static int match_region(client_handle_t handle, memory_handle_t list,
-			region_info_t *match)
-{
-    while (list != NULL) {
-	if (!(handle->Attributes & INFO_MTD_CLIENT) ||
-	    (strcmp(handle->dev_info, list->dev_info) == 0)) {
-	    *match = list->info;
-	    return CS_SUCCESS;
-	}
-	list = list->info.next;
-    }
-    return CS_NO_MORE_ITEMS;
-} /* match_region */
-
-int pcmcia_get_first_region(client_handle_t handle, region_info_t *rgn)
-{
-    struct pcmcia_socket *s = SOCKET(handle);
-    if (CHECK_HANDLE(handle))
-	return CS_BAD_HANDLE;
-    
-    if ((handle->Attributes & INFO_MASTER_CLIENT) &&
-	(!(s->state & SOCKET_REGION_INFO))) {
-	setup_regions(s, handle->Function, 0, &s->c_region);
-	setup_regions(s, handle->Function, 1, &s->a_region);
-	s->state |= SOCKET_REGION_INFO;
-    }
-
-    if (rgn->Attributes & REGION_TYPE_AM)
-	return match_region(handle, s->a_region, rgn);
-    else
-	return match_region(handle, s->c_region, rgn);
-} /* get_first_region */
-EXPORT_SYMBOL(pcmcia_get_first_region);
-
-int pcmcia_get_next_region(client_handle_t handle, region_info_t *rgn)
-{
-    if (CHECK_HANDLE(handle))
-	return CS_BAD_HANDLE;
-    return match_region(handle, rgn->next, rgn);
-} /* get_next_region */
-EXPORT_SYMBOL(pcmcia_get_next_region);
-
-#endif
diff -Nru a/drivers/pcmcia/cardbus.c b/drivers/pcmcia/cardbus.c
--- a/drivers/pcmcia/cardbus.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/pcmcia/cardbus.c	2005-03-01 23:38:54 -08:00
@@ -1,35 +1,16 @@
-/*======================================================================
-  
-    Cardbus device configuration
-    
-    cardbus.c 1.87 2002/10/24 06:11:41
-
-    The contents of this file are subject to the Mozilla Public
-    License Version 1.1 (the "License"); you may not use this file
-    except in compliance with the License. You may obtain a copy of
-    the License at http://www.mozilla.org/MPL/
-
-    Software distributed under the License is distributed on an "AS
-    IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-    implied. See the License for the specific language governing
-    rights and limitations under the License.
-
-    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.
-
-    Alternatively, the contents of this file may be used under the
-    terms of the GNU General Public License version 2 (the "GPL"), in which
-    case the provisions of the GPL are applicable instead of the
-    above.  If you wish to allow the use of your version of this file
-    only under the terms of the GPL and not to allow others to use
-    your version of this file under the MPL, indicate your decision
-    by deleting the provisions above and replace them with the notice
-    and other provisions required by the GPL.  If you do not delete
-    the provisions above, a recipient may use your version of this
-    file under either the MPL or the GPL.
-    
-======================================================================*/
+/*
+ * cardbus.c -- 16-bit PCMCIA core 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.
+ *
+ * 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
+ */
 
 /*
  * Cardbus handling has been re-written to be more of a PCI bridge thing,
diff -Nru a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c
--- a/drivers/pcmcia/cistpl.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/pcmcia/cistpl.c	2005-03-01 23:38:54 -08:00
@@ -1,35 +1,16 @@
-/*======================================================================
-
-    PCMCIA Card Information Structure parser
-
-    cistpl.c 1.99 2002/10/24 06:11:48
-
-    The contents of this file are subject to the Mozilla Public
-    License Version 1.1 (the "License"); you may not use this file
-    except in compliance with the License. You may obtain a copy of
-    the License at http://www.mozilla.org/MPL/
-
-    Software distributed under the License is distributed on an "AS
-    IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-    implied. See the License for the specific language governing
-    rights and limitations under the License.
-
-    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.
-
-    Alternatively, the contents of this file may be used under the
-    terms of the GNU General Public License version 2 (the "GPL"), in
-    which case the provisions of the GPL are applicable instead of the
-    above.  If you wish to allow the use of your version of this file
-    only under the terms of the GPL and not to allow others to use
-    your version of this file under the MPL, indicate your decision
-    by deleting the provisions above and replace them with the notice
-    and other provisions required by the GPL.  If you do not delete
-    the provisions above, a recipient may use your version of this
-    file under either the MPL or the GPL.
-    
-======================================================================*/
+/*
+ * cistpl.c -- 16-bit PCMCIA Card Information Structure parser
+ *
+ * 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
+ */
 
 #include <linux/config.h>
 #include <linux/module.h>
@@ -97,6 +78,7 @@
 	s->cis_virt = NULL;
     }
 }
+EXPORT_SYMBOL(release_cis_mem);
 
 /*
  * Map the card memory at "card_offset" into virtual space.
@@ -108,8 +90,7 @@
 {
     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,
-				   "card services", s);
+	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;
@@ -340,6 +321,7 @@
 		s->fake_cis = NULL;
 	}
 }
+EXPORT_SYMBOL(destroy_cis_cache);
 
 /*======================================================================
 
diff -Nru a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c
--- a/drivers/pcmcia/cs.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/pcmcia/cs.c	2005-03-01 23:38:54 -08:00
@@ -1,35 +1,16 @@
-/*======================================================================
-
-    Kernel Card Services -- core services
-
-    cs.c 1.271 2000/10/02 20:27:49
-    
-    The contents of this file are subject to the Mozilla Public
-    License Version 1.1 (the "License"); you may not use this file
-    except in compliance with the License. You may obtain a copy of
-    the License at http://www.mozilla.org/MPL/
-
-    Software distributed under the License is distributed on an "AS
-    IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-    implied. See the License for the specific language governing
-    rights and limitations under the License.
-
-    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.
-
-    Alternatively, the contents of this file may be used under the
-    terms of the GNU General Public License version 2 (the "GPL"), in which
-    case the provisions of the GPL are applicable instead of the
-    above.  If you wish to allow the use of your version of this file
-    only under the terms of the GPL and not to allow others to use
-    your version of this file under the MPL, indicate your decision
-    by deleting the provisions above and replace them with the notice
-    and other provisions required by the GPL.  If you do not delete
-    the provisions above, a recipient may use your version of this
-    file under either the MPL or the GPL.
-    
-======================================================================*/
+/*
+ * cs.c -- Kernel Card Services - core services
+ *
+ * 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
+ */
 
 #include <linux/module.h>
 #include <linux/moduleparam.h>
@@ -48,7 +29,6 @@
 #include <linux/pm.h>
 #include <linux/pci.h>
 #include <linux/device.h>
-#include <linux/suspend.h>
 #include <asm/system.h>
 #include <asm/irq.h>
 
@@ -60,6 +40,7 @@
 #include <pcmcia/bulkmem.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/cisreg.h>
+#include <pcmcia/ds.h>
 #include "cs_internal.h"
 
 #ifdef CONFIG_PCI
@@ -92,7 +73,7 @@
 
 MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
 MODULE_DESCRIPTION("Linux Kernel Card Services\noptions:" OPTIONS);
-MODULE_LICENSE("Dual MPL/GPL");	  
+MODULE_LICENSE("GPL");
 
 #define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0444)
 
@@ -132,8 +113,15 @@
 /* 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
+
 /*====================================================================
 
     Low-level PC Card interface drivers need to register with Card
@@ -189,16 +177,32 @@
 EXPORT_SYMBOL(pcmcia_socket_dev_resume);
 
 
+struct pcmcia_socket * pcmcia_get_socket(struct pcmcia_socket *skt)
+{
+	struct class_device *cl_dev = class_device_get(&skt->dev);
+	if (!cl_dev)
+		return NULL;
+	skt = class_get_devdata(cl_dev);
+	if (!try_module_get(skt->owner)) {
+		class_device_put(&skt->dev);
+		return NULL;
+	}
+	return (skt);
+}
+EXPORT_SYMBOL(pcmcia_get_socket);
+
+
+void pcmcia_put_socket(struct pcmcia_socket *skt)
+{
+	module_put(skt->owner);
+	class_device_put(&skt->dev);
+}
+EXPORT_SYMBOL(pcmcia_put_socket);
+
+
 static void pcmcia_release_socket(struct class_device *class_dev)
 {
 	struct pcmcia_socket *socket = class_get_devdata(class_dev);
-	client_t *client;
-
-	while (socket->clients) {
-		client = socket->clients;
-		socket->clients = socket->clients->next;
-		kfree(client);
-	}
 
 	complete(&socket->socket_released);
 }
@@ -212,11 +216,17 @@
 {
 	int ret;
 
-	if (!socket || !socket->ops || !socket->dev.dev)
+	if (!socket || !socket->ops || !socket->dev.dev || !socket->resource_ops)
 		return -EINVAL;
 
 	cs_dbg(socket, 0, "pcmcia_register_socket(0x%p)\n", socket->ops);
 
+	if (socket->resource_ops->init) {
+		ret = socket->resource_ops->init(socket);
+		if (ret)
+			return (ret);
+	}
+
 	/* 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 
@@ -305,6 +315,7 @@
 	up_write(&pcmcia_socket_list_rwsem);
 
 	/* wait for sysfs to drop all references */
+	release_resource_db(socket);
 	wait_for_completion(&socket->socket_released);
 } /* pcmcia_unregister_socket */
 EXPORT_SYMBOL(pcmcia_unregister_socket);
@@ -330,31 +341,15 @@
 
 /*======================================================================
 
-    Shutdown_Socket() and setup_socket() are scheduled using add_timer
-    calls by the main event handler when card insertion and removal
-    events are received.  Shutdown_Socket() unconfigures a socket and
-    turns off socket power.  Setup_socket() turns on socket power
-    and resets the socket, in two stages.
+    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 free_regions(memory_handle_t *list)
-{
-    memory_handle_t tmp;
-    while (*list != NULL) {
-	tmp = *list;
-	*list = tmp->info.next;
-	tmp->region_magic = 0;
-	kfree(tmp);
-    }
-}
-
-static int send_event(struct pcmcia_socket *s, event_t event, int priority);
-
 static void shutdown_socket(struct pcmcia_socket *s)
 {
-    client_t **c;
-    
     cs_dbg(s, 1, "shutdown_socket\n");
 
     /* Blank out the socket state */
@@ -372,17 +367,6 @@
 	kfree(s->config);
 	s->config = NULL;
     }
-    for (c = &s->clients; *c; ) {
-	if ((*c)->state & CLIENT_UNBOUND) {
-	    client_t *d = *c;
-	    *c = (*c)->next;
-	    kfree(d);
-	} else {
-	    c = &((*c)->next);
-	}
-    }
-    free_regions(&s->a_region);
-    free_regions(&s->c_region);
 
     {
 	int status;
@@ -395,45 +379,44 @@
 
 /*======================================================================
 
-    The central event handler.  Send_event() sends an event to all
-    valid clients.  Parse_events() interprets the event bits from
+    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. */
+
 static int send_event(struct pcmcia_socket *s, event_t event, int priority)
 {
-    client_t *client = s->clients;
-    int ret;
-    cs_dbg(s, 1, "send_event(event %d, pri %d)\n",
-	   event, priority);
-    ret = 0;
-    if (s->state & SOCKET_CARDBUS)
-	    return 0;
-    for (; client; client = client->next) { 
-	if (client->state & (CLIENT_UNBOUND|CLIENT_STALE))
-	    continue;
-	if (client->EventMask & event) {
-	    ret = EVENT(client, event, priority);
-	    if (ret != 0)
-		return ret;
-	}
-    }
-    return ret;
-} /* send_event */
+	int ret;
+
+	if (s->state & SOCKET_CARDBUS)
+		return 0;
+
+	cs_dbg(s, 1, "send_event(event %d, pri %d, callback 0x%p)\n",
+	   event, priority, s->callback);
+
+	if (!s->callback)
+		return 0;
+	if (!try_module_get(s->callback->owner))
+		return 0;
+
+	ret = s->callback->event(s, event, priority);
+
+	module_put(s->callback->owner);
+
+	return ret;
+}
 
 static void socket_remove_drivers(struct pcmcia_socket *skt)
 {
-	client_t *client;
-
 	cs_dbg(skt, 4, "remove_drivers\n");
 
 	send_event(skt, CS_EVENT_CARD_REMOVAL, CS_EVENT_PRI_HIGH);
-
-	for (client = skt->clients; client; client = client->next)
-		if (!(client->Attributes & INFO_MASTER_CLIENT))
-			client->state |= CLIENT_STALE;
 }
 
 static void socket_shutdown(struct pcmcia_socket *skt)
@@ -718,8 +701,7 @@
 		}
 
 		schedule();
-		if (current->flags & PF_FREEZE)
-			refrigerator(PF_FREEZE);
+		try_to_freeze(PF_FREEZE);
 
 		if (!skt->thread)
 			break;
@@ -756,22 +738,22 @@
 ======================================================================*/
 
 static int alloc_io_space(struct pcmcia_socket *s, u_int attr, ioaddr_t *base,
-			  ioaddr_t num, u_int lines, char *name)
+			  ioaddr_t num, u_int lines)
 {
     int i;
-    ioaddr_t try, align;
+    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 %04x align %04x\n",
+	    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 %04x align %04x\n",
+	cs_dbg(s, 0, "odd IO request: base %#x align %#lx\n",
 	       *base, align);
 	align = 0;
     }
@@ -788,7 +770,7 @@
 	    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, name, s);
+	    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;
@@ -888,49 +870,6 @@
 } /* access_configuration_register */
 EXPORT_SYMBOL(pccard_access_configuration_register);
 
-/*====================================================================*/
-
-int pcmcia_deregister_client(client_handle_t handle)
-{
-    client_t **client;
-    struct pcmcia_socket *s;
-    u_long flags;
-    int i;
-    
-    if (CHECK_HANDLE(handle))
-	return CS_BAD_HANDLE;
-
-    s = SOCKET(handle);
-    cs_dbg(s, 1, "deregister_client(%p)\n", handle);
-
-    if (handle->state &
-	(CLIENT_IRQ_REQ|CLIENT_IO_REQ|CLIENT_CONFIG_LOCKED))
-	return CS_IN_USE;
-    for (i = 0; i < MAX_WIN; i++)
-	if (handle->state & CLIENT_WIN_REQ(i))
-	    return CS_IN_USE;
-
-    if ((handle->state & CLIENT_STALE) ||
-	(handle->Attributes & INFO_MASTER_CLIENT)) {
-	spin_lock_irqsave(&s->lock, flags);
-	client = &s->clients;
-	while ((*client) && ((*client) != handle))
-	    client = &(*client)->next;
-	if (*client == NULL) {
-	    spin_unlock_irqrestore(&s->lock, flags);
-	    return CS_BAD_HANDLE;
-	}
-	*client = handle->next;
-	handle->client_magic = 0;
-	kfree(handle);
-	spin_unlock_irqrestore(&s->lock, flags);
-    } else {
-	handle->state = CLIENT_UNBOUND;
-	handle->event_handler = NULL;
-    }
-
-    return CS_SUCCESS;
-} /* deregister_client */
 
 /*====================================================================*/
 
@@ -1014,53 +953,6 @@
     return CS_SUCCESS;
 } /* get_card_services_info */
 
-#ifdef CONFIG_PCMCIA_OBSOLETE
-
-/*======================================================================
-
-    Note that get_first_client() *does* recognize the Socket field
-    in the request structure.
-    
-======================================================================*/
-
-int pcmcia_get_first_client(client_handle_t *handle, client_req_t *req)
-{
-    socket_t s;
-    struct pcmcia_socket *socket;
-    if (req->Attributes & CLIENT_THIS_SOCKET)
-	s = req->Socket;
-    else
-	s = 0;
-    socket = pcmcia_get_socket_by_nr(s);
-    if (!socket)
-	return CS_BAD_SOCKET;
-    if (socket->clients == NULL)
-	return CS_NO_MORE_ITEMS;
-    *handle = socket->clients;
-    return CS_SUCCESS;
-} /* get_first_client */
-EXPORT_SYMBOL(pcmcia_get_first_client);
-
-/*====================================================================*/
-
-int pcmcia_get_next_client(client_handle_t *handle, client_req_t *req)
-{
-    struct pcmcia_socket *s;
-    if ((handle == NULL) || CHECK_HANDLE(*handle))
-	return CS_BAD_HANDLE;
-    if ((*handle)->next == NULL) {
-	if (req->Attributes & CLIENT_THIS_SOCKET)
-	    return CS_NO_MORE_ITEMS;
-	s = (*handle)->Socket;
-	if (s->clients == NULL)
-	    return CS_NO_MORE_ITEMS;
-	*handle = s->clients;
-    } else
-	*handle = (*handle)->next;
-    return CS_SUCCESS;
-} /* get_next_client */
-EXPORT_SYMBOL(pcmcia_get_next_client);
-#endif /* CONFIG_PCMCIA_OBSOLETE */
 
 /*====================================================================*/
 
@@ -1251,117 +1143,33 @@
     return CS_SUCCESS;
 } /* modify_configuration */
 
-#ifdef CONFIG_PCMCIA_OBSOLETE
-
-/*======================================================================
-
-    Modify the attributes of a window returned by RequestWindow.
-
-======================================================================*/
-
-int pcmcia_modify_window(window_handle_t win, modwin_t *req)
+/* register pcmcia_callback */
+int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c)
 {
-    if ((win == NULL) || (win->magic != WINDOW_MAGIC))
-	return CS_BAD_HANDLE;
+        int ret = 0;
 
-    win->ctl.flags &= ~(MAP_ATTRIB|MAP_ACTIVE);
-    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.speed = req->AccessSpeed;
-    win->sock->ops->set_mem_map(win->sock, &win->ctl);
-    
-    return CS_SUCCESS;
-} /* modify_window */
-EXPORT_SYMBOL(pcmcia_modify_window);
-
-#endif /* CONFIG_PCMCIA_OBSOLETE */
-
-
-/*======================================================================
-
-    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.
-    
-======================================================================*/
+	/* s->skt_sem also protects s->callback */
+	down(&s->skt_sem);
 
-int pcmcia_register_client(client_handle_t *handle, client_reg_t *req)
-{
-    client_t *client = NULL;
-    struct pcmcia_socket *s;
-    
-    /* Look for unbound client with matching dev_info */
-    down_read(&pcmcia_socket_list_rwsem);
-    list_for_each_entry(s, &pcmcia_socket_list, socket_list) {
-	client = s->clients;
-	while (client != NULL) {
-	    if ((strcmp(client->dev_info, (char *)req->dev_info) == 0)
-		&& (client->state & CLIENT_UNBOUND)) break;
-	    client = client->next;
-	}
-	if (client != NULL) break;
-    }
-    up_read(&pcmcia_socket_list_rwsem);
-    if (client == NULL)
-	return CS_OUT_OF_RESOURCE;
+	if (c) {
+		/* registration */
+		if (s->callback) {
+			ret = -EBUSY;
+			goto err;
+		}
 
-    /*
-     * Prevent this racing with a card insertion.
-     */
-    down(&s->skt_sem);
-    *handle = client;
-    client->state &= ~CLIENT_UNBOUND;
-    client->Socket = s;
-    client->Attributes = req->Attributes;
-    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;
-
-    if (s->state & SOCKET_CARDBUS)
-	client->state |= CLIENT_CARDBUS;
-    
-    if ((!(s->state & SOCKET_CARDBUS)) && (s->functions == 0) &&
-	(client->Function != BIND_FN_ALL)) {
-	cistpl_longlink_mfc_t mfc;
-	if (pccard_read_tuple(s, client->Function, CISTPL_LONGLINK_MFC, &mfc)
-	    == CS_SUCCESS)
-	    s->functions = mfc.nfn;
-	else
-	    s->functions = 1;
-	s->config = kmalloc(sizeof(config_t) * s->functions,
-			    GFP_KERNEL);
-	if (!s->config)
-		goto out_no_resource;
-	memset(s->config, 0, sizeof(config_t) * s->functions);
-    }
-    
-    cs_dbg(s, 1, "register_client(): client 0x%p, dev %s\n",
-	   client, client->dev_info);
-    if (client->EventMask & CS_EVENT_REGISTRATION_COMPLETE)
-	EVENT(client, CS_EVENT_REGISTRATION_COMPLETE, CS_EVENT_PRI_LOW);
-
-    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);
-	else
-	    client->PendingEvents |= CS_EVENT_CARD_INSERTION;
-    }
+		s->callback = c;
 
-    up(&s->skt_sem);
-    return CS_SUCCESS;
+		if ((s->state & (SOCKET_PRESENT|SOCKET_CARDBUS)) == SOCKET_PRESENT)
+			send_event(s, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW);
+	} else
+		s->callback = NULL;
+ err:
+	up(&s->skt_sem);
 
- out_no_resource:
-    up(&s->skt_sem);
-    return CS_OUT_OF_RESOURCE;
-} /* register_client */
+	return ret;
+}
+EXPORT_SYMBOL(pccard_register_pcmcia);
 
 /*====================================================================*/
 
@@ -1478,10 +1286,9 @@
     }
 
 #ifdef CONFIG_PCMCIA_PROBE
-    if (req->AssignedIRQ != s->pci_irq)
-	undo_irq(req->Attributes, req->AssignedIRQ);
+    pcmcia_used_irq[req->AssignedIRQ]--;
 #endif
-    
+
     return CS_SUCCESS;
 } /* cs_release_irq */
 
@@ -1685,14 +1492,12 @@
 	return CS_BAD_ATTRIBUTE;
 
     if (alloc_io_space(s, req->Attributes1, &req->BasePort1,
-		       req->NumPorts1, req->IOAddrLines,
-		       handle->dev_info))
+		       req->NumPorts1, req->IOAddrLines))
 	return CS_IN_USE;
 
     if (req->NumPorts2) {
 	if (alloc_io_space(s, req->Attributes2, &req->BasePort2,
-			   req->NumPorts2, req->IOAddrLines,
-			   handle->dev_info)) {
+			   req->NumPorts2, req->IOAddrLines)) {
 	    release_io_space(s, req->BasePort1, req->NumPorts1);
 	    return CS_IN_USE;
 	}
@@ -1715,71 +1520,96 @@
     
 ======================================================================*/
 
+#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;
-    
-    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;
+	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 match */
-	irq = s->irq.AssignedIRQ;
-	if (req->IRQInfo1 & IRQ_INFO2_VALID) {
-	    u_int mask = req->IRQInfo2 & s->irq_mask;
-	    ret = ((mask >> irq) & 1) ? 0 : CS_BAD_ARGS;
-	} else
-	    ret = ((req->IRQInfo1&IRQ_MASK) == irq) ? 0 : CS_BAD_ARGS;
-    } else {
-	if (req->IRQInfo1 & IRQ_INFO2_VALID) {
-	    u_int try, mask = req->IRQInfo2 & s->irq_mask;
-	    for (try = 0; try < 2; try++) {
-		for (irq = 0; irq < 32; irq++)
-		    if ((mask >> irq) & 1) {
-			ret = try_irq(req->Attributes, irq, try);
-			if (ret == 0) break;
-		    }
-		if (ret == 0) break;
-	    }
+	if (s->irq.AssignedIRQ != 0) {
+		/* If the interrupt is already assigned, it must be the same */
+		irq = s->irq.AssignedIRQ;
 	} else {
-	    irq = req->IRQInfo1 & IRQ_MASK;
-	    ret = try_irq(req->Attributes, irq, 1);
+		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 != 0) {
-	if (!s->pci_irq)
-	    return ret;
-	irq = s->pci_irq;
-    }
+	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++;
 
-    if (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,
-			    handle->dev_info, req->Instance))
-	    return CS_IN_USE;
-    }
+	c->state |= CONFIG_IRQ_REQ;
+	handle->state |= CLIENT_IRQ_REQ;
 
-    c->irq.Attributes = req->Attributes;
-    s->irq.AssignedIRQ = req->AssignedIRQ = irq;
-    s->irq.Config++;
-    
-    c->state |= CONFIG_IRQ_REQ;
-    handle->state |= CLIENT_IRQ_REQ;
-    return CS_SUCCESS;
+#ifdef CONFIG_PCMCIA_PROBE
+	pcmcia_used_irq[irq]++;
+#endif
+
+	return CS_SUCCESS;
 } /* pcmcia_request_irq */
 
 /*======================================================================
@@ -1832,8 +1662,7 @@
 
     if (!(s->features & SS_CAP_STATIC_MAP)) {
 	win->ctl.res = find_mem_region(req->Base, req->Size, align,
-				       (req->Attributes & WIN_MAP_BELOW_1MB),
-				       (*handle)->dev_info, s);
+				       (req->Attributes & WIN_MAP_BELOW_1MB), s);
 	if (!win->ctl.res)
 	    return CS_IN_USE;
     }
@@ -2022,47 +1851,16 @@
 
 /*======================================================================
 
-    Maybe this should send a CS_EVENT_CARD_INSERTION event if we
-    haven't sent one to this client yet?
-    
-======================================================================*/
-
-#ifdef CONFIG_PCMCIA_OBSOLETE
-int pcmcia_set_event_mask(client_handle_t handle, eventmask_t *mask)
-{
-    u_int events, bit;
-    if (CHECK_HANDLE(handle))
-	return CS_BAD_HANDLE;
-    if (handle->Attributes & CONF_EVENT_MASK_VALID)
-	return CS_BAD_SOCKET;
-    handle->EventMask = mask->EventMask;
-    events = handle->PendingEvents & handle->EventMask;
-    handle->PendingEvents -= events;
-    while (events != 0) {
-	bit = ((events ^ (events-1)) + 1) >> 1;
-	EVENT(handle, bit, CS_EVENT_PRI_LOW);
-	events -= bit;
-    }
-    return CS_SUCCESS;
-} /* set_event_mask */
-EXPORT_SYMBOL(pcmcia_set_event_mask);
-
-#endif /* CONFIG_PCMCIA_OBSOLETE */
-
-/*======================================================================
-
     OS-specific module glue goes here
     
 ======================================================================*/
 /* in alpha order */
-EXPORT_SYMBOL(pcmcia_deregister_client);
 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_register_client);
 EXPORT_SYMBOL(pcmcia_release_configuration);
 EXPORT_SYMBOL(pcmcia_release_io);
 EXPORT_SYMBOL(pcmcia_release_irq);
@@ -2100,7 +1898,6 @@
 static void __exit exit_pcmcia_cs(void)
 {
     printk(KERN_INFO "unloading Kernel Card Services\n");
-    release_resource_db();
     class_interface_unregister(&pccard_sysfs_interface);
     class_unregister(&pcmcia_socket_class);
 }
diff -Nru a/drivers/pcmcia/cs_internal.h b/drivers/pcmcia/cs_internal.h
--- a/drivers/pcmcia/cs_internal.h	2005-03-01 23:39:18 -08:00
+++ b/drivers/pcmcia/cs_internal.h	2005-03-01 23:39:18 -08:00
@@ -1,19 +1,15 @@
 /*
- * cs_internal.h 1.57 2002/10/24 06:11:43
+ * cs_internal.h
  *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License
- * at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and
- * limitations under the License. 
+ * 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.
+ * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
+ *
+ * (C) 1999		David A. Hinds
  */
 
 #ifndef _LINUX_CS_INTERNAL_H
@@ -22,19 +18,7 @@
 #include <linux/config.h>
 
 #define CLIENT_MAGIC 	0x51E6
-typedef struct client_t {
-    u_short		client_magic;
-    struct pcmcia_socket *Socket;
-    u_char		Function;
-    dev_info_t		dev_info;
-    u_int		Attributes;
-    u_int		state;
-    event_t		EventMask, PendingEvents;
-    int (*event_handler)(event_t event, int priority,
-			 event_callback_args_t *);
-    event_callback_args_t event_callback_args;
-    struct client_t 	*next;
-} client_t;
+typedef struct client_t client_t;
 
 /* Flags in client state */
 #define CLIENT_CONFIG_LOCKED	0x0001
@@ -151,15 +135,13 @@
 /* In rsrc_mgr */
 void pcmcia_validate_mem(struct pcmcia_socket *s);
 struct resource *find_io_region(unsigned long base, int num, unsigned long align,
-		   char *name, struct pcmcia_socket *s);
+		   struct pcmcia_socket *s);
 int 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,
-		    int low, char *name, struct pcmcia_socket *s);
-int try_irq(u_int Attributes, int irq, int specific);
-void undo_irq(u_int Attributes, int irq);
+		    int low, struct pcmcia_socket *s);
 int adjust_resource_info(client_handle_t handle, adjust_t *adj);
-void release_resource_db(void);
+void release_resource_db(struct pcmcia_socket *s);
 
 /* In socket_sysfs.c */
 extern struct class_interface pccard_sysfs_interface;
@@ -172,6 +154,14 @@
 int pccard_reset_card(struct pcmcia_socket *skt);
 int pccard_get_status(struct pcmcia_socket *s, unsigned int function, cs_status_t *status);
 int pccard_access_configuration_register(struct pcmcia_socket *s, unsigned int function, conf_reg_t *reg);
+
+
+struct pcmcia_callback{
+	struct module	*owner;
+	int		(*event) (struct pcmcia_socket *s, event_t event, int priority);
+};
+
+int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c);
 
 #define cs_socket_name(skt)	((skt)->dev.class_id)
 
diff -Nru a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
--- a/drivers/pcmcia/ds.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/pcmcia/ds.c	2005-03-01 23:39:08 -08:00
@@ -1,35 +1,17 @@
-/*======================================================================
-
-    PC Card Driver Services
-    
-    ds.c 1.112 2001/10/13 00:08:28
-    
-    The contents of this file are subject to the Mozilla Public
-    License Version 1.1 (the "License"); you may not use this file
-    except in compliance with the License. You may obtain a copy of
-    the License at http://www.mozilla.org/MPL/
-
-    Software distributed under the License is distributed on an "AS
-    IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-    implied. See the License for the specific language governing
-    rights and limitations under the License.
-
-    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.
-
-    Alternatively, the contents of this file may be used under the
-    terms of the GNU General Public License version 2 (the "GPL"), in
-    which case the provisions of the GPL are applicable instead of the
-    above.  If you wish to allow the use of your version of this file
-    only under the terms of the GPL and not to allow others to use
-    your version of this file under the MPL, indicate your decision
-    by deleting the provisions above and replace them with the notice
-    and other provisions required by the GPL.  If you do not delete
-    the provisions above, a recipient may use your version of this
-    file under either the MPL or the GPL.
-    
-======================================================================*/
+/*
+ * ds.c -- 16-bit PCMCIA core 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.
+ *
+ * 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
+ */
 
 #include <linux/config.h>
 #include <linux/module.h>
@@ -51,6 +33,7 @@
 #include <linux/pci.h>
 #include <linux/list.h>
 #include <linux/delay.h>
+#include <linux/kref.h>
 #include <linux/workqueue.h>
 
 #include <asm/atomic.h>
@@ -72,7 +55,7 @@
 
 MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
 MODULE_DESCRIPTION("PCMCIA Driver Services");
-MODULE_LICENSE("Dual MPL/GPL");
+MODULE_LICENSE("GPL");
 
 #ifdef DEBUG
 int ds_pc_debug;
@@ -89,13 +72,6 @@
 
 /*====================================================================*/
 
-typedef struct socket_bind_t {
-    struct pcmcia_driver	*driver;
-    u_char		function;
-    dev_link_t		*instance;
-    struct socket_bind_t *next;
-} socket_bind_t;
-
 /* Device user information */
 #define MAX_EVENTS	32
 #define USER_MAGIC	0x7ea4
@@ -111,16 +87,22 @@
 
 /* Socket state information */
 struct pcmcia_bus_socket {
-	atomic_t		refcount;
-	client_handle_t		handle;
+	struct kref		refcount;
+	struct pcmcia_callback	callback;
 	int			state;
 	user_info_t		*user;
 	int			req_pending, req_result;
 	wait_queue_head_t	queue, request;
-	struct work_struct	removal;
-	socket_bind_t		*bind;
 	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
@@ -129,89 +111,14 @@
 
 /*====================================================================*/
 
-/* Device driver ID passed to Card Services */
-static dev_info_t dev_info = "Driver Services";
-
 static int major_dev = -1;
 
+static int unbind_request(struct pcmcia_bus_socket *s);
+
 /*====================================================================*/
 
 /* code which was in cs.c before */
 
-/*======================================================================
-
-    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.
-    
-======================================================================*/
-
-static int pcmcia_bind_device(bind_req_t *req)
-{
-	client_t *client;
-	struct pcmcia_socket *s;
-
-	s = req->Socket;
-	if (!s)
-		return CS_BAD_SOCKET;
-
-	client = (client_t *) kmalloc(sizeof(client_t), GFP_KERNEL);
-	if (!client) 
-		return CS_OUT_OF_RESOURCE;
-	memset(client, '\0', sizeof(client_t));
-	client->client_magic = CLIENT_MAGIC;
-	strlcpy(client->dev_info, (char *)req->dev_info, DEV_NAME_LEN);
-	client->Socket = s;
-	client->Function = req->Function;
-	client->state = CLIENT_UNBOUND;
-	client->next = s->clients;
-	s->clients = client;
-	ds_dbg(1, "%s: bind_device(): client 0x%p, dev %s\n",
-		cs_socket_name(client->Socket), client, client->dev_info);
-	return CS_SUCCESS;
-} /* bind_device */
-
-
-/*======================================================================
-
-    Bind_mtd() associates a device driver with a particular memory
-    region.  It is normally called by Driver Services after it has
-    identified a memory device type.  An instance of the corresponding
-    driver will then be able to register to control this region.
-    
-======================================================================*/
-
-static int pcmcia_bind_mtd(mtd_bind_t *req)
-{
-	struct pcmcia_socket *s;
-	memory_handle_t region;
-
-	s = req->Socket;
-	if (!s)
-		return CS_BAD_SOCKET;
-    
-	if (req->Attributes & REGION_TYPE_AM)
-		region = s->a_region;
-	else
-		region = s->c_region;
-
-	while (region) {
-		if (region->info.CardOffset == req->CardOffset) 
-			break;
-		region = region->info.next;
-	}
-	if (!region || (region->mtd != NULL))
-		return CS_BAD_OFFSET;
-	strlcpy(region->dev_info, (char *)req->dev_info, DEV_NAME_LEN);
-
-	ds_dbg(1, "%s: bind_mtd: attr 0x%x, offset 0x%x, dev %s\n",
-	      cs_socket_name(s), req->Attributes, req->CardOffset,
-	      (char *)req->dev_info);
-	return CS_SUCCESS;
-} /* bind_mtd */
-
-
 /* String tables for error messages */
 
 typedef struct lookup_t {
@@ -314,8 +221,10 @@
 
 	if (CHECK_HANDLE(handle))
 		printk(KERN_NOTICE);
-	else
-		printk(KERN_NOTICE "%s: ", handle->dev_info);
+	else {
+		struct pcmcia_device *p_dev = handle_to_pdev(handle);
+		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)
@@ -353,22 +262,22 @@
 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_put_bus_socket(struct pcmcia_bus_socket *s)
+static void pcmcia_release_bus_socket(struct kref *refcount)
 {
-	if (atomic_dec_and_test(&s->refcount))
-		kfree(s);
+	struct pcmcia_bus_socket *s = container_of(refcount, struct pcmcia_bus_socket, refcount);
+	pcmcia_put_socket(s->parent);
+	kfree(s);
 }
 
-static struct pcmcia_bus_socket *pcmcia_get_bus_socket(int nr)
+static void pcmcia_put_bus_socket(struct pcmcia_bus_socket *s)
 {
-	struct pcmcia_bus_socket *s;
+	kref_put(&s->refcount, pcmcia_release_bus_socket);
+}
 
-	s = get_socket_info_by_nr(nr);
-	if (s) {
-		WARN_ON(atomic_read(&s->refcount) == 0);
-		atomic_inc(&s->refcount);
-	}
-	return s;
+static struct pcmcia_bus_socket *pcmcia_get_bus_socket(struct pcmcia_bus_socket *s)
+{
+	kref_get(&s->refcount);
+	return (s);
 }
 
 /**
@@ -381,8 +290,8 @@
 	if (!driver)
 		return -EINVAL;
 
- 	driver->use_count = 0;
 	driver->drv.bus = &pcmcia_bus_type;
+	driver->drv.owner = driver->owner;
 
 	return driver_register(&driver->drv);
 }
@@ -403,10 +312,16 @@
 static int proc_read_drivers_callback(struct device_driver *driver, void *d)
 {
 	char **p = d;
-	struct pcmcia_driver *p_dev = container_of(driver, 
+	struct pcmcia_driver *p_drv = container_of(driver,
 						   struct pcmcia_driver, drv);
 
-	*p += sprintf(*p, "%-24.24s 1 %d\n", driver->name, p_dev->use_count);
+	*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;
@@ -424,6 +339,31 @@
 }
 #endif
 
+/* pcmcia_device handling */
+
+static struct pcmcia_device * pcmcia_get_dev(struct pcmcia_device *p_dev)
+{
+	struct device *tmp_dev;
+	tmp_dev = get_device(&p_dev->dev);
+	if (!tmp_dev)
+		return NULL;
+	return to_pcmcia_dev(tmp_dev);
+}
+
+static void pcmcia_put_dev(struct pcmcia_device *p_dev)
+{
+	put_device(&p_dev->dev);
+}
+
+static void pcmcia_release_dev(struct device *dev)
+{
+	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);
+	kfree(p_dev);
+}
+
+
 /*======================================================================
 
     These manage a ring buffer of events pending for one user process
@@ -471,255 +411,494 @@
     return CS_SUCCESS;
 }
 
-static void handle_removal(void *data)
-{
-    struct pcmcia_bus_socket *s = data;
-    handle_event(s, CS_EVENT_CARD_REMOVAL);
-    s->state &= ~DS_SOCKET_REMOVAL_PENDING;
-}
-
 /*======================================================================
 
     The card status event handler.
     
 ======================================================================*/
 
-static int ds_event(event_t event, int priority,
-		    event_callback_args_t *args)
+struct send_event_data {
+	struct pcmcia_socket *skt;
+	event_t event;
+	int priority;
+};
+
+static int send_event_callback(struct device *dev, void * _data)
 {
-    struct pcmcia_bus_socket *s;
+	struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
+	struct send_event_data *data = _data;
 
-    ds_dbg(1, "ds_event(0x%06x, %d, 0x%p)\n",
-	  event, priority, args->client_handle);
-    s = args->client_data;
-    
-    switch (event) {
-	
-    case CS_EVENT_CARD_REMOVAL:
-	s->state &= ~DS_SOCKET_PRESENT;
-	if (!(s->state & DS_SOCKET_REMOVAL_PENDING)) {
-		s->state |= DS_SOCKET_REMOVAL_PENDING;
-		schedule_delayed_work(&s->removal,  HZ/10);
-	}
-	break;
-	
-    case CS_EVENT_CARD_INSERTION:
-	s->state |= DS_SOCKET_PRESENT;
-	handle_event(s, event);
-	break;
+	/* we get called for all sockets, but may only pass the event
+	 * for drivers _on the affected socket_ */
+	if (p_dev->socket != data->skt)
+		return 0;
 
-    case CS_EVENT_EJECTION_REQUEST:
-	return handle_request(s, event);
-	break;
-	
-    default:
-	handle_event(s, event);
-	break;
-    }
+	if (p_dev->client.state & (CLIENT_UNBOUND|CLIENT_STALE))
+		return 0;
 
-    return 0;
-} /* ds_event */
+	if (p_dev->client.EventMask & data->event)
+		return EVENT(&p_dev->client, data->event, data->priority);
 
-/*======================================================================
+	return 0;
+}
 
-    bind_mtd() connects a memory region with an MTD client.
-    
-======================================================================*/
+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);
 
-static int bind_mtd(struct pcmcia_bus_socket *bus_sock, mtd_info_t *mtd_info)
+	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;
+} /* send_event */
+
+
+/* Normally, the event is passed to individual drivers after
+ * informing userspace. Only for CS_EVENT_CARD_REMOVAL this
+ * is inversed to maintain historic compatibility.
+ */
+
+static int ds_event(struct pcmcia_socket *skt, event_t event, int priority)
 {
-    mtd_bind_t bind_req;
-    int ret;
+	struct pcmcia_bus_socket *s = skt->pcmcia;
+	int ret = 0;
 
-    bind_req.dev_info = &mtd_info->dev_info;
-    bind_req.Attributes = mtd_info->Attributes;
-    bind_req.Socket = bus_sock->parent;
-    bind_req.CardOffset = mtd_info->CardOffset;
-    ret = pcmcia_bind_mtd(&bind_req);
-    if (ret != CS_SUCCESS) {
-	cs_error(NULL, BindMTD, ret);
-	printk(KERN_NOTICE "ds: unable to bind MTD '%s' to socket %d"
-	       " offset 0x%x\n",
-	       (char *)bind_req.dev_info, bus_sock->parent->sock, bind_req.CardOffset);
-	return -ENODEV;
+	ds_dbg(1, "ds_event(0x%06x, %d, 0x%p)\n",
+	       event, priority, s);
+    
+	switch (event) {
+
+	case CS_EVENT_CARD_REMOVAL:
+		s->state &= ~DS_SOCKET_PRESENT;
+	    	send_event(skt, event, priority);
+		unbind_request(s);
+		handle_event(s, event);
+		break;
+	
+	case CS_EVENT_CARD_INSERTION:
+		s->state |= DS_SOCKET_PRESENT;
+		handle_event(s, event);
+		send_event(skt, event, priority);
+		break;
+
+	case CS_EVENT_EJECTION_REQUEST:
+		ret = handle_request(s, event);
+		if (ret)
+			break;
+		ret = send_event(skt, event, priority);
+		break;
+
+	default:
+		handle_event(s, event);
+		send_event(skt, event, priority);
+		break;
     }
+
     return 0;
-} /* bind_mtd */
+} /* 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)
 {
-    struct pcmcia_driver *driver;
-    socket_bind_t *b;
-    bind_req_t bind_req;
-    int ret;
+	struct pcmcia_driver *p_drv;
+	struct pcmcia_device *p_dev, *tmp_dev;
+	unsigned long flags;
+	int ret = 0;
 
-    if (!s)
-	    return -EINVAL;
+	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);
-    driver = get_pcmcia_driver(&bind_info->dev_info);
-    if (!driver)
-	    return -EINVAL;
-
-    for (b = s->bind; b; b = b->next)
-	if ((driver == b->driver) &&
-	    (bind_info->function == b->function))
-	    break;
-    if (b != NULL) {
-	bind_info->instance = b->instance;
-	return -EBUSY;
-    }
+	ds_dbg(2, "bind_request(%d, '%s')\n", s->parent->sock,
+	       (char *)bind_info->dev_info);
 
-    if (!try_module_get(driver->owner))
-	    return -EINVAL;
+	p_drv = get_pcmcia_driver(&bind_info->dev_info);
+	if (!p_drv) {
+		ret = -EINVAL;
+		goto err_put;
+	}
 
-    bind_req.Socket = s->parent;
-    bind_req.Function = bind_info->function;
-    bind_req.dev_info = (dev_info_t *) driver->drv.name;
-    ret = pcmcia_bind_device(&bind_req);
-    if (ret != CS_SUCCESS) {
-	cs_error(NULL, BindDevice, ret);
-	printk(KERN_NOTICE "ds: unable to bind '%s' to socket %d\n",
-	       (char *)dev_info, s->parent->sock);
-	module_put(driver->owner);
-	return -ENODEV;
-    }
+	if (!try_module_get(p_drv->owner)) {
+		ret = -EINVAL;
+		goto err_put_driver;
+	}
 
-    /* Add binding to list for this socket */
-    driver->use_count++;
-    b = kmalloc(sizeof(socket_bind_t), GFP_KERNEL);
-    if (!b) 
-    {
-    	driver->use_count--;
-	module_put(driver->owner);
-	return -ENOMEM;    
-    }
-    b->driver = driver;
-    b->function = bind_info->function;
-    b->instance = NULL;
-    b->next = s->bind;
-    s->bind = b;
-    
-    if (driver->attach) {
-	b->instance = driver->attach();
-	if (b->instance == NULL) {
-	    printk(KERN_NOTICE "ds: unable to create instance "
-		   "of '%s'!\n", (char *)bind_info->dev_info);
-	    module_put(driver->owner);
-	    return -ENODEV;
+	/* Currently, the userspace pcmcia cardmgr detects pcmcia devices.
+	 * Here this information is translated into a kernel
+	 * struct pcmcia_device.
+	 */
+
+	p_dev = kmalloc(sizeof(struct pcmcia_device), GFP_KERNEL);
+	if (!p_dev) {
+		ret = -ENOMEM;
+		goto err_put_module;
 	}
-    }
-    
-    return 0;
+	memset(p_dev, 0, sizeof(struct pcmcia_device));
+
+	p_dev->socket = s->parent;
+	p_dev->device_no = (s->device_count++);
+	p_dev->func   = bind_info->function;
+
+	p_dev->dev.bus = &pcmcia_bus_type;
+	p_dev->dev.parent = s->parent->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);
+	p_dev->dev.driver = &p_drv->drv;
+
+	/* compat */
+	p_dev->client.client_magic = CLIENT_MAGIC;
+	p_dev->client.Socket = s->parent;
+	p_dev->client.Function = bind_info->function;
+	p_dev->client.state = CLIENT_UNBOUND;
+
+	ret = device_register(&p_dev->dev);
+	if (ret) {
+		kfree(p_dev);
+		goto err_put_module;
+	}
+
+	/* Add to the list in pcmcia_bus_socket, but only if no device
+	 * with the same func _and_ driver exists */
+	spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
+	list_for_each_entry(tmp_dev, &s->devices_list, socket_device_list) {
+		if ((tmp_dev->func == bind_info->function) &&
+		    (tmp_dev->dev.driver == p_dev->dev.driver)){
+			spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
+			bind_info->instance = tmp_dev->instance;
+			ret = -EBUSY;
+			goto err_unregister;
+		}
+	}
+	list_add_tail(&p_dev->socket_device_list, &s->devices_list);
+	spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
+
+	if (p_drv->attach) {
+		p_dev->instance = p_drv->attach();
+		if ((!p_dev->instance) || (p_dev->client.state & CLIENT_UNBOUND)) {
+			printk(KERN_NOTICE "ds: unable to create instance "
+			       "of '%s'!\n", (char *)bind_info->dev_info);
+			ret = -ENODEV;
+			goto err_unregister;
+		}
+	}
+
+	put_driver(&p_drv->drv);
+
+	return 0;
+
+ err_unregister:
+	device_unregister(&p_dev->dev);
+	module_put(p_drv->owner);
+	put_driver(&p_drv->drv);
+	return (ret);
+
+ 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_device *p_dev = NULL;
+
+	/* Look for unbound client with matching dev_info */
+	down_read(&pcmcia_socket_list_rwsem);
+	list_for_each_entry(s, &pcmcia_socket_list, socket_list) {
+		unsigned long flags;
+
+		if (s->state & SOCKET_CARDBUS)
+			continue;
+
+		skt = s->pcmcia;
+		if (!skt)
+			continue;
+		skt = pcmcia_get_bus_socket(skt);
+		if (!skt)
+			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;
+			p_dev = pcmcia_get_dev(p_dev);
+			if (!p_dev)
+				continue;
+			if (!(p_dev->client.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);
+	}
+ found:
+	up_read(&pcmcia_socket_list_rwsem);
+	if (!p_dev || !client)
+		return -ENODEV;
+
+	pcmcia_put_bus_socket(skt); /* safe, as we already hold a reference from bind_device */
+
+	/*
+	 * Prevent this racing with a card insertion.
+	 */
+	down(&s->skt_sem);
+	*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;
+
+	if (s->state & SOCKET_CARDBUS)
+		client->state |= CLIENT_CARDBUS;
+
+	if ((!(s->state & SOCKET_CARDBUS)) && (s->functions == 0) &&
+	    (client->Function != BIND_FN_ALL)) {
+		cistpl_longlink_mfc_t mfc;
+		if (pccard_read_tuple(s, client->Function, CISTPL_LONGLINK_MFC, &mfc)
+		    == CS_SUCCESS)
+			s->functions = mfc.nfn;
+		else
+			s->functions = 1;
+		s->config = kmalloc(sizeof(config_t) * s->functions,
+				    GFP_KERNEL);
+		if (!s->config)
+			goto out_no_resource;
+		memset(s->config, 0, sizeof(config_t) * s->functions);
+	}
+
+	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);
+
+	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);
+	}
+
+	up(&s->skt_sem);
+	return CS_SUCCESS;
+
+ out_no_resource:
+	up(&s->skt_sem);
+	pcmcia_put_dev(p_dev);
+	return CS_OUT_OF_RESOURCE;
+} /* register_client */
+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)
 {
-    socket_bind_t *b;
-    dev_node_t *node;
+	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;
+	/*
+	 * 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;
+		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;
+				}
 
-			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;
 			}
-
-			/* 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
 
-    for (b = s->bind; b; b = b->next)
-	if ((strcmp((char *)b->driver->drv.name,
-		    (char *)bind_info->dev_info) == 0) &&
-	    (b->function == bind_info->function))
-	    break;
-    if (b == NULL) return -ENODEV;
-    if ((b->instance == NULL) ||
-	(b->instance->state & DEV_CONFIG_PENDING))
-	return -EAGAIN;
-    if (first)
-	node = b->instance->dev;
-    else
-	for (node = b->instance->dev; node; node = node->next)
-	    if (node == bind_info->next) break;
-    if (node == NULL) return -ENODEV;
-
-    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;
-    
-    return 0;
+	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 unbind_request(struct pcmcia_bus_socket *s, bind_info_t *bind_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)
 {
-    socket_bind_t **b, *c;
+	struct pcmcia_device	*p_dev;
+	struct pcmcia_driver	*p_drv;
+	unsigned long		flags;
+
+	ds_dbg(2, "unbind_request(%d)\n", s->parent->sock);
+
+	s->device_count = 0;
+
+	for (;;) {
+		/* unregister all pcmcia_devices registered with this socket*/
+		spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
+		if (list_empty(&s->devices_list)) {
+			spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
+ 			return 0;
+		}
+		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;
+		spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
+
+		/* detach the "instance" */
+		p_drv = to_pcmcia_drv(p_dev->dev.driver);
+		if (p_drv) {
+			if ((p_drv->detach) && (p_dev->instance))
+				p_drv->detach(p_dev->instance);
+			module_put(p_drv->owner);
+		}
 
-    ds_dbg(2, "unbind_request(%d, '%s')\n", s->parent->sock,
-	  (char *)bind_info->dev_info);
-    for (b = &s->bind; *b; b = &(*b)->next)
-	if ((strcmp((char *)(*b)->driver->drv.name,
-		    (char *)bind_info->dev_info) == 0) &&
-	    ((*b)->function == bind_info->function))
-	    break;
-    if (*b == NULL)
-	return -ENODEV;
-    
-    c = *b;
-    c->driver->use_count--;
-    if (c->driver->detach) {
-	if (c->instance)
-	    c->driver->detach(c->instance);
-    }
-    module_put(c->driver->owner);
-    *b = c->next;
-    kfree(c);
-    return 0;
+		device_unregister(&p_dev->dev);
+	}
+
+	return 0;
 } /* unbind_request */
 
+int pcmcia_deregister_client(client_handle_t handle)
+{
+	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);
+
+	if (handle->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))
+			goto warn_out;
+
+	if (handle->state & CLIENT_STALE) {
+		handle->client_magic = 0;
+		handle->state &= ~CLIENT_STALE;
+		pcmcia_put_dev(p_dev);
+	} else {
+		handle->state = CLIENT_UNBOUND;
+		handle->event_handler = NULL;
+	}
+
+	return CS_SUCCESS;
+ warn_out:
+	printk(KERN_WARNING "ds: deregister_client was called too early.\n");
+	return CS_IN_USE;
+} /* deregister_client */
+EXPORT_SYMBOL(pcmcia_deregister_client);
+
+
 /*======================================================================
 
     The user-mode PC Card device interface
@@ -734,19 +913,27 @@
 
     ds_dbg(0, "ds_open(socket %d)\n", i);
 
-    s = pcmcia_get_bus_socket(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)
-	    return -EBUSY;
+	    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) return -ENOMEM;
+    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;
@@ -883,8 +1070,6 @@
 /*====================================================================*/
 
 extern int pcmcia_adjust_resource_info(adjust_t *adj);
-extern int pccard_get_next_region(struct pcmcia_socket *s, region_info_t *rgn);
-extern int pccard_get_first_region(struct pcmcia_socket *s, region_info_t *rgn);
 
 static int ds_ioctl(struct inode * inode, struct file * file,
 		    u_int cmd, u_long arg)
@@ -893,7 +1078,7 @@
     void __user *uarg = (char __user *)arg;
     u_int size;
     int ret, err;
-    ds_ioctl_arg_t buf;
+    ds_ioctl_arg_t *buf;
     user_info_t *user;
 
     ds_dbg(2, "ds_ioctl(socket %d, %#x, %#lx)\n", iminor(inode), cmd, arg);
@@ -927,54 +1112,58 @@
 	    return err;
 	}
     }
+    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);
+    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);
+	ret = pcmcia_adjust_resource_info(&buf->adjust);
 	break;
     case DS_GET_CARD_SERVICES_INFO:
-	ret = pcmcia_get_card_services_info(&buf.servinfo);
+	ret = pcmcia_get_card_services_info(&buf->servinfo);
 	break;
     case DS_GET_CONFIGURATION_INFO:
-	if (buf.config.Function && 
-	   (buf.config.Function >= s->parent->functions))
+	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);
+	    ret = pccard_get_configuration_info(s->parent,
+			buf->config.Function, &buf->config);
 	break;
     case DS_GET_FIRST_TUPLE:
 	pcmcia_validate_mem(s->parent);
-	ret = pccard_get_first_tuple(s->parent, BIND_FN_ALL, &buf.tuple);
+	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);
+	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);
+	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);
+	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))
+	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);
+	ret = pccard_get_status(s->parent, buf->status.Function, &buf->status);
 	break;
     case DS_VALIDATE_CIS:
 	pcmcia_validate_mem(s->parent);
-	ret = pccard_validate_cis(s->parent, BIND_FN_ALL, &buf.cisinfo);
+	ret = pccard_validate_cis(s->parent, BIND_FN_ALL, &buf->cisinfo);
 	break;
     case DS_SUSPEND_CARD:
 	ret = pcmcia_suspend_card(s->parent);
@@ -989,49 +1178,64 @@
 	err = pcmcia_insert_card(s->parent);
 	break;
     case DS_ACCESS_CONFIGURATION_REGISTER:
-	if ((buf.conf_reg.Action == CS_WRITE) && !capable(CAP_SYS_ADMIN))
-	    return -EPERM;
-	if (buf.conf_reg.Function && 
-	   (buf.conf_reg.Function >= s->parent->functions))
+	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);
+	    ret = pccard_access_configuration_register(s->parent,
+			buf->conf_reg.Function, &buf->conf_reg);
 	break;
     case DS_GET_FIRST_REGION:
-        ret = pccard_get_first_region(s->parent, &buf.region);
-	break;
     case DS_GET_NEXT_REGION:
-	ret = pccard_get_next_region(s->parent, &buf.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++;
+		}
+	}
+	ret = -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);
+	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);
+	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);
+	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);
+	ret = pcmcia_replace_cis(s->parent, &buf->cisdump);
 	break;
     case DS_BIND_REQUEST:
-	if (!capable(CAP_SYS_ADMIN)) return -EPERM;
-	err = bind_request(s, &buf.bind_info);
+	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);
+	err = get_device_info(s, &buf->bind_info, 1);
 	break;
     case DS_GET_NEXT_DEVICE:
-	err = get_device_info(s, &buf.bind_info, 0);
+	err = get_device_info(s, &buf->bind_info, 0);
 	break;
     case DS_UNBIND_REQUEST:
-	err = unbind_request(s, &buf.bind_info);
-	break;
-    case DS_BIND_MTD:
-	if (!capable(CAP_SYS_ADMIN)) return -EPERM;
-	err = bind_mtd(s, &buf.mtd_info);
+	err = 0;
 	break;
     default:
 	err = -EINVAL;
@@ -1059,11 +1263,12 @@
     }
 
     if (cmd & IOC_OUT) {
-        if (__copy_to_user(uarg, (char *)&buf, size))
+        if (__copy_to_user(uarg, (char *)buf, size))
             err = -EFAULT;
     }
 
-
+free_out:
+    kfree(buf);
     return err;
 } /* ds_ioctl */
 
@@ -1081,9 +1286,7 @@
 
 static int __devinit pcmcia_bus_add_socket(struct class_device *class_dev)
 {
-	struct pcmcia_socket *socket = class_dev->class_data;
-	client_reg_t client_reg;
-	bind_req_t bind;
+	struct pcmcia_socket *socket = class_get_devdata(class_dev);
 	struct pcmcia_bus_socket *s;
 	int ret;
 
@@ -1091,7 +1294,16 @@
 	if(!s)
 		return -ENOMEM;
 	memset(s, 0, sizeof(struct pcmcia_bus_socket));
-	atomic_set(&s->refcount, 1);
+
+	/* get reference to parent socket */
+	s->parent = pcmcia_get_socket(socket);
+	if (!s->parent) {
+		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.
@@ -1101,55 +1313,33 @@
 
 	init_waitqueue_head(&s->queue);
 	init_waitqueue_head(&s->request);
-
-	/* initialize data */
-	INIT_WORK(&s->removal, handle_removal, s);
-	s->parent = socket;
+	INIT_LIST_HEAD(&s->devices_list);
 
 	/* Set up hotline to Card Services */
-	client_reg.dev_info = bind.dev_info = &dev_info;
-
-	bind.Socket = socket;
-	bind.Function = BIND_FN_ALL;
-	ret = pcmcia_bind_device(&bind);
-	if (ret != CS_SUCCESS) {
-		cs_error(NULL, BindDevice, ret);
-		kfree(s);
-		return -EINVAL;
-	}
+	s->callback.owner = THIS_MODULE;
+	s->callback.event = &ds_event;
+	socket->pcmcia = s;
 
-	client_reg.Attributes = INFO_MASTER_CLIENT;
-	client_reg.EventMask =
-		CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
-		CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
-		CS_EVENT_EJECTION_REQUEST | CS_EVENT_INSERTION_REQUEST |
-		CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
-	client_reg.event_handler = &ds_event;
-	client_reg.Version = 0x0210;
-	client_reg.event_callback_args.client_data = s;
-	ret = pcmcia_register_client(&s->handle, &client_reg);
-	if (ret != CS_SUCCESS) {
-		cs_error(NULL, RegisterClient, ret);
-		kfree(s);
-		return -EINVAL;
+	ret = pccard_register_pcmcia(socket, &s->callback);
+	if (ret) {
+		printk(KERN_ERR "PCMCIA registration PCCard core failed for socket %p\n", socket);
+		pcmcia_put_bus_socket(s);
+		socket->pcmcia = NULL;
+		return (ret);
 	}
 
-	socket->pcmcia = s;
-
 	return 0;
 }
 
 
 static void pcmcia_bus_remove_socket(struct class_device *class_dev)
 {
-	struct pcmcia_socket *socket = class_dev->class_data;
+	struct pcmcia_socket *socket = class_get_devdata(class_dev);
 
 	if (!socket || !socket->pcmcia)
 		return;
 
-	flush_scheduled_work();
-
-	pcmcia_deregister_client(socket->pcmcia->handle);
+	pccard_register_pcmcia(socket, NULL);
 
 	socket->pcmcia->state |= DS_SOCKET_DEAD;
 	pcmcia_put_bus_socket(socket->pcmcia);
@@ -1177,6 +1367,8 @@
 {
 	int i;
 
+	spin_lock_init(&pcmcia_dev_list_lock);
+
 	bus_register(&pcmcia_bus_type);
 	class_interface_register(&pcmcia_bus_interface);
 
@@ -1232,33 +1424,18 @@
 
 /* backwards-compatible accessing of driver --- by name! */
 
-struct cmp_data {
-	void *dev_info;
-	struct pcmcia_driver *drv;
-};
-
-static int cmp_drv_callback(struct device_driver *drv, void *data)
-{
-	struct cmp_data *cmp = data;
-	if (strncmp((char *)cmp->dev_info, (char *)drv->name,
-		    DEV_NAME_LEN) == 0) {
-		cmp->drv = container_of(drv, struct pcmcia_driver, drv);
-		return -EINVAL;
-	}
-	return 0;
-}
-
 static struct pcmcia_driver * get_pcmcia_driver (dev_info_t *dev_info)
 {
-	int ret;
-	struct cmp_data cmp = {
-		.dev_info = dev_info,
-	};
-	
-	ret = bus_for_each_drv(&pcmcia_bus_type, NULL, &cmp, cmp_drv_callback);
-	if (ret)
-		return cmp.drv;
-	return NULL;
+	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 -Nru a/drivers/pcmcia/hd64465_ss.c b/drivers/pcmcia/hd64465_ss.c
--- a/drivers/pcmcia/hd64465_ss.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/pcmcia/hd64465_ss.c	2005-03-01 23:38:58 -08:00
@@ -566,7 +566,7 @@
 	struct pccard_io_map *sio;
 	pgprot_t prot;
 
-    	DPRINTK("hs_set_io_map(sock=%d, map=%d, flags=0x%x, speed=%dns, start=0x%04x, stop=0x%04x)\n",
+    	DPRINTK("hs_set_io_map(sock=%d, map=%d, flags=0x%x, speed=%dns, start=%#lx, stop=%#lx)\n",
 	    sock, map, io->flags, io->speed, io->start, io->stop);
 	if (map >= MAX_IO_WIN)
 	    return -EINVAL;
@@ -922,6 +922,7 @@
 		hs_set_voltages(&hs_sockets[i], 0, 0);
 
 		hs_sockets[i].socket.features |=  SS_CAP_PCCARD | SS_CAP_STATIC_MAP;      /* mappings are fixed in host memory */
+		hs_sockets[i].socket.resource_ops = &pccard_static_ops;
 		hs_sockets[i].socket.irq_mask =  0xffde;/*0xffff*/	    /* IRQs mapped in s/w so can do any, really */
 		hs_sockets[i].socket.map_size = HD64465_PCC_WINDOW;     /* 16MB fixed window size */
 
diff -Nru a/drivers/pcmcia/i82092.c b/drivers/pcmcia/i82092.c
--- a/drivers/pcmcia/i82092.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/pcmcia/i82092.c	2005-03-01 23:39:18 -08:00
@@ -81,7 +81,7 @@
 				    1 = empty socket, 
 				    2 = card but not initialized,
 				    3 = operational card */
-	int 	io_base; 	/* base io address of the socket */
+	kio_addr_t io_base; 	/* base io address of the socket */
 	
 	struct pcmcia_socket socket;
 	struct pci_dev *dev;	/* The PCI device for the socket */
@@ -122,7 +122,7 @@
 	}
 	printk(KERN_INFO "i82092aa: configured as a %d socket device.\n", socket_count);
 
-	if (request_region(pci_resource_start(dev, 0), 2, "i82092aa")) {
+	if (!request_region(pci_resource_start(dev, 0), 2, "i82092aa")) {
 		ret = -EBUSY;
 		goto err_out_disable;
 	}
@@ -162,6 +162,7 @@
 	for (i = 0; i<socket_count; i++) {
 		sockets[i].socket.dev.dev = &dev->dev;
 		sockets[i].socket.ops = &i82092aa_operations;
+		sockets[i].socket.resource_ops = &pccard_nonstatic_ops;
 		ret = pcmcia_register_socket(&sockets[i].socket);
 		if (ret) {
 			goto err_out_free_sockets;
@@ -199,7 +200,7 @@
 	leave("i82092aa_pci_remove");
 }
 
-static spinlock_t port_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(port_lock);
 
 /* basic value read/write functions */
 
diff -Nru a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c
--- a/drivers/pcmcia/i82365.c	2005-03-01 23:39:10 -08:00
+++ b/drivers/pcmcia/i82365.c	2005-03-01 23:39:10 -08:00
@@ -96,7 +96,7 @@
 /* Parameters that can be set with 'insmod' */
 
 /* Default base address for i82365sl and other ISA chips */
-static int i365_base = 0x3e0;
+static unsigned long i365_base = 0x3e0;
 /* Should we probe at 0x3e2 for an extra ISA controller? */
 static int extra_sockets = 0;
 /* Specify a socket number to ignore */
@@ -130,7 +130,7 @@
 static int cable_mode = -1;
 static int wakeup = 0;
 
-module_param(i365_base, int, 0444);
+module_param(i365_base, ulong, 0444);
 module_param(ignore, int, 0444);
 module_param(extra_sockets, int, 0444);
 module_param(irq_mask, int, 0444);
@@ -167,7 +167,7 @@
     u_short		type, flags;
     struct pcmcia_socket	socket;
     unsigned int	number;
-    ioaddr_t		ioaddr;
+    kio_addr_t		ioaddr;
     u_short		psock;
     u_char		cs_irq, intr;
     union {
@@ -186,7 +186,7 @@
 #define I365_MASK	0xdeb8	/* irq 15,14,12,11,10,9,7,5,4,3 */
 
 static int grab_irq;
-static spinlock_t isa_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(isa_lock);
 #define ISA_LOCK(n, f) spin_lock_irqsave(&isa_lock, f)
 #define ISA_UNLOCK(n, f) spin_unlock_irqrestore(&isa_lock, f)
 
@@ -208,6 +208,7 @@
 #define IS_UNKNOWN	0x0400
 #define IS_VG_PWR	0x0800
 #define IS_DF_PWR	0x1000
+#define IS_REGISTERED	0x2000
 #define IS_ALIVE	0x8000
 
 typedef struct pcic_t {
@@ -233,14 +234,14 @@
 
 /*====================================================================*/
 
-static spinlock_t bus_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(bus_lock);
 
 static u_char i365_get(u_short sock, u_short reg)
 {
     unsigned long flags;
     spin_lock_irqsave(&bus_lock,flags);
     {
-	ioaddr_t port = socket[sock].ioaddr;
+	kio_addr_t port = socket[sock].ioaddr;
 	u_char val;
 	reg = I365_REG(socket[sock].psock, reg);
 	outb(reg, port); val = inb(port+1);
@@ -254,7 +255,7 @@
     unsigned long flags;
     spin_lock_irqsave(&bus_lock,flags);
     {
-	ioaddr_t port = socket[sock].ioaddr;
+	kio_addr_t port = socket[sock].ioaddr;
 	u_char val = I365_REG(socket[sock].psock, reg);
 	outb(val, port); outb(data, port+1);
 	spin_unlock_irqrestore(&bus_lock,flags);
@@ -589,7 +590,7 @@
 
 /*====================================================================*/
 
-static int __init identify(u_short port, u_short sock)
+static int __init identify(kio_addr_t port, u_short sock)
 {
     u_char val;
     int type = -1;
@@ -660,7 +661,7 @@
 static int __init is_alive(u_short sock)
 {
     u_char stat;
-    u_short start, stop;
+    kio_addr_t start, stop;
     
     stat = i365_get(sock, I365_STATUS);
     start = i365_get_pair(sock, I365_IO(0)+I365_W_START);
@@ -677,7 +678,7 @@
 
 /*====================================================================*/
 
-static void __init add_socket(u_short port, int psock, int type)
+static void __init add_socket(kio_addr_t port, int psock, int type)
 {
     socket[sockets].ioaddr = port;
     socket[sockets].psock = psock;
@@ -699,7 +700,7 @@
     
     if (base == 0) printk("\n");
     printk(KERN_INFO "  %s", pcic[type].name);
-    printk(" ISA-to-PCMCIA at port %#x ofs 0x%02x",
+    printk(" ISA-to-PCMCIA at port %#lx ofs 0x%02x",
 	       t->ioaddr, t->psock*0x40);
     printk(", %d socket%s\n", ns, ((ns > 1) ? "s" : ""));
 
@@ -773,7 +774,7 @@
 static void __init isa_probe(void)
 {
     int i, j, sock, k, ns, id;
-    ioaddr_t port;
+    kio_addr_t port;
 #ifdef CONFIG_PNP
     struct isapnp_device_id *devid;
     struct pnp_dev *dev;
@@ -804,7 +805,7 @@
 
     if (check_region(i365_base, 2) != 0) {
 	if (sockets == 0)
-	    printk("port conflict at %#x\n", i365_base);
+	    printk("port conflict at %#lx\n", i365_base);
 	return;
     }
 
@@ -1127,7 +1128,7 @@
     u_char map, ioctl;
     
     debug(1, "SetIOMap(%d, %d, %#2.2x, %d ns, "
-	  "%#4.4x-%#4.4x)\n", sock, io->map, io->flags,
+	  "%#lx-%#lx)\n", sock, io->map, io->flags,
 	  io->speed, io->start, io->stop);
     map = io->map;
     if ((map > 1) || (io->start > 0xffff) || (io->stop > 0xffff) ||
@@ -1156,8 +1157,8 @@
     u_short base, i;
     u_char map;
     
-    debug(1, "SetMemMap(%d, %d, %#2.2x, %d ns, %#5.5lx-%#5.5"
-	  "lx, %#5.5x)\n", sock, mem->map, mem->flags, mem->speed,
+    debug(1, "SetMemMap(%d, %d, %#2.2x, %d ns, %#lx-%#lx, "
+	  "%#x)\n", sock, mem->map, mem->flags, mem->speed,
 	  mem->res->start, mem->res->end, mem->card_start);
 
     map = mem->map;
@@ -1400,14 +1401,13 @@
     for (i = 0; i < sockets; i++) {
 	    socket[i].socket.dev.dev = &i82365_device.dev;
 	    socket[i].socket.ops = &pcic_operations;
+	    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);	    
-	    if (ret && i--) {
-		    for (; i>= 0; i--)
-			    pcmcia_unregister_socket(&socket[i].socket);
-		    break;
-	    }
+	    ret = pcmcia_register_socket(&socket[i].socket);
+	    if (!ret)
+		    socket[i].flags |= IS_REGISTERED;
+
 #if 0 /* driver model ordering issue */
 	   class_device_create_file(&socket[i].socket.dev,
 			   	    &class_device_attr_info);
@@ -1434,7 +1434,8 @@
     int i;
 
     for (i = 0; i < sockets; i++) {
-	    pcmcia_unregister_socket(&socket[i].socket);
+	    if (socket[i].flags & IS_REGISTERED)
+		    pcmcia_unregister_socket(&socket[i].socket);
     }
     platform_device_unregister(&i82365_device);
     if (poll_interval != 0)
@@ -1446,7 +1447,7 @@
 	i365_set(i, I365_CSCINT, 0);
 	release_region(socket[i].ioaddr, 2);
     }
-#ifdef __ISAPNP__
+#ifdef CONFIG_PNP
     if (i82365_pnpdev)
     		pnp_disable_dev(i82365_pnpdev);
 #endif
diff -Nru a/drivers/pcmcia/m32r_cfc.c b/drivers/pcmcia/m32r_cfc.c
--- a/drivers/pcmcia/m32r_cfc.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/pcmcia/m32r_cfc.c	2005-03-01 23:38:57 -08:00
@@ -61,7 +61,7 @@
 	u_short			type, flags;
 	struct pcmcia_socket	socket;
 	unsigned int		number;
- 	ioaddr_t		ioaddr;
+ 	kio_addr_t		ioaddr;
 	u_long			mapaddr;
 	u_long			base;	/* PCC register base */
 	u_char			cs_irq1, cs_irq2, intr;
@@ -86,7 +86,7 @@
 static unsigned int pcc_get(u_short, unsigned int);
 static void pcc_set(u_short, unsigned int , unsigned int );
 
-static spinlock_t pcc_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(pcc_lock);
 
 #if !defined(CONFIG_PLAT_USRV)
 static inline u_long pcc_port2addr(unsigned long port, int size) {
@@ -239,6 +239,7 @@
 
 /*====================================================================*/
 
+#define IS_REGISTERED		0x2000
 #define IS_ALIVE		0x8000
 
 typedef struct pcc_t {
@@ -300,7 +301,7 @@
 	return 0;
 }
 
-static void add_pcc_socket(ulong base, int irq, ulong mapaddr, ioaddr_t ioaddr)
+static void add_pcc_socket(ulong base, int irq, ulong mapaddr, kio_addr_t ioaddr)
 {
 	pcc_socket_t *t = &socket[pcc_sockets];
 
@@ -568,7 +569,7 @@
 	u_char map;
 
 	debug(3, "m32r_cfc: SetIOMap(%d, %d, %#2.2x, %d ns, "
-		  "%#4.4x-%#4.4x)\n", sock, io->map, io->flags,
+		  "%#lx-%#lx)\n", sock, io->map, io->flags,
 		  io->speed, io->start, io->stop);
 	map = io->map;
 
@@ -585,7 +586,7 @@
 	pcc_socket_t *t = &socket[sock];
 
 	debug(3, "m32r_cfc: SetMemMap(%d, %d, %#2.2x, %d ns, "
-		 "%#5.5lx, %#5.5x)\n", sock, map, mem->flags,
+		 "%#lx, %#x)\n", sock, map, mem->flags,
 		 mem->speed, mem->static_start, mem->card_start);
 
 	/*
@@ -807,7 +808,7 @@
 #else	/* CONFIG_PLAT_USRV */
 	{
 		ulong base, mapaddr;
-		ioaddr_t ioaddr;
+		kio_addr_t ioaddr;
 
 		for (i = 0 ; i < M32R_MAX_PCC ; i++) {
 			base = (ulong)PLD_CFRSTCR;
@@ -831,14 +832,13 @@
 	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.owner = THIS_MODULE;
 		socket[i].number = i;
 		ret = pcmcia_register_socket(&socket[i].socket);
-		if (ret && i--) {
-			for (; i>= 0; i--)
-				pcmcia_unregister_socket(&socket[i].socket);
-			break;
-		}
+		if (!ret)
+			socket[i].flags |= IS_REGISTERED;
+
 #if 0	/* driver model ordering issue */
 		class_device_create_file(&socket[i].socket.dev,
 					 &class_device_attr_info);
@@ -864,7 +864,8 @@
 	int i;
 
 	for (i = 0; i < pcc_sockets; i++)
-		pcmcia_unregister_socket(&socket[i].socket);
+		if (socket[i].flags & IS_REGISTERED)
+			pcmcia_unregister_socket(&socket[i].socket);
 
 	platform_device_unregister(&pcc_device);
 	if (poll_interval != 0)
diff -Nru a/drivers/pcmcia/m32r_pcc.c b/drivers/pcmcia/m32r_pcc.c
--- a/drivers/pcmcia/m32r_pcc.c	2005-03-01 23:38:44 -08:00
+++ b/drivers/pcmcia/m32r_pcc.c	2005-03-01 23:38:44 -08:00
@@ -68,7 +68,7 @@
 	u_short			type, flags;
 	struct pcmcia_socket	socket;
 	unsigned int		number;
- 	ioaddr_t		ioaddr;
+ 	kio_addr_t		ioaddr;
 	u_long			mapaddr;
 	u_long			base;	/* PCC register base */
 	u_char			cs_irq, intr;
@@ -96,7 +96,7 @@
 static unsigned int pcc_get(u_short, unsigned int);
 static void pcc_set(u_short, unsigned int , unsigned int );
 
-static spinlock_t pcc_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(pcc_lock);
 
 void pcc_iorw(int sock, unsigned long port, void *buf, size_t size, size_t nmemb, int wr, int flag)
 {
@@ -257,6 +257,7 @@
 
 /*====================================================================*/
 
+#define IS_REGISTERED		0x2000
 #define IS_ALIVE		0x8000
 
 typedef struct pcc_t {
@@ -312,7 +313,7 @@
 	return 0;
 }
 
-static void add_pcc_socket(ulong base, int irq, ulong mapaddr, ioaddr_t ioaddr)
+static void add_pcc_socket(ulong base, int irq, ulong mapaddr, kio_addr_t ioaddr)
 {
   	pcc_socket_t *t = &socket[pcc_sockets];
 
@@ -503,7 +504,7 @@
 	u_char map;
 
 	debug(3, "m32r-pcc: SetIOMap(%d, %d, %#2.2x, %d ns, "
-		  "%#4.4x-%#4.4x)\n", sock, io->map, io->flags,
+		  "%#lx-%#lx)\n", sock, io->map, io->flags,
 		  io->speed, io->start, io->stop);
 	map = io->map;
 
@@ -526,7 +527,7 @@
 #endif
 
 	debug(3, "m32r-pcc: SetMemMap(%d, %d, %#2.2x, %d ns, "
-		 "%#5.5lx,  %#5.5x)\n", sock, map, mem->flags,
+		 "%#lx,  %#x)\n", sock, map, mem->flags,
 		 mem->speed, mem->static_start, mem->card_start);
 
 	/*
@@ -768,14 +769,13 @@
 	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.owner = THIS_MODULE;
 		socket[i].number = i;
 		ret = pcmcia_register_socket(&socket[i].socket);
-		if (ret && i--) {
-			for (; i>= 0; i--)
-				pcmcia_unregister_socket(&socket[i].socket);
-			break;
-		}
+		if (!ret)
+			socket[i].flags |= IS_REGISTERED;
+
 #if 0	/* driver model ordering issue */
 		class_device_create_file(&socket[i].socket.dev,
 					 &class_device_attr_info);
@@ -801,7 +801,8 @@
 	int i;
 
 	for (i = 0; i < pcc_sockets; i++)
-		pcmcia_unregister_socket(&socket[i].socket);
+		if (socket[i].flags & IS_REGISTERED)
+			pcmcia_unregister_socket(&socket[i].socket);
 
 	platform_device_unregister(&pcc_device);
 	if (poll_interval != 0)
diff -Nru a/drivers/pcmcia/pcmcia_compat.c b/drivers/pcmcia/pcmcia_compat.c
--- a/drivers/pcmcia/pcmcia_compat.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/pcmcia/pcmcia_compat.c	2005-03-01 23:39:17 -08:00
@@ -123,23 +123,3 @@
 }
 EXPORT_SYMBOL(pcmcia_access_configuration_register);
 
-#ifdef CONFIG_PCMCIA_OBSOLETE
-
-int pcmcia_get_first_window(window_handle_t *win, win_req_t *req)
-{
-    if ((win == NULL) || ((*win)->magic != WINDOW_MAGIC))
-	return CS_BAD_HANDLE;
-
-    return pcmcia_get_window(((client_handle_t)*win)->Socket, win, 0, req);
-}
-EXPORT_SYMBOL(pcmcia_get_first_window);
-
-int pcmcia_get_next_window(window_handle_t *win, win_req_t *req)
-{
-    if ((win == NULL) || ((*win)->magic != WINDOW_MAGIC))
-	return CS_BAD_HANDLE;
-    return pcmcia_get_window((*win)->sock, win, (*win)->index+1, req);
-}
-EXPORT_SYMBOL(pcmcia_get_next_window);
-
-#endif
diff -Nru a/drivers/pcmcia/pd6729.c b/drivers/pcmcia/pd6729.c
--- a/drivers/pcmcia/pd6729.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/pcmcia/pd6729.c	2005-03-01 23:39:09 -08:00
@@ -29,7 +29,7 @@
 
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Driver for the Cirrus PD6729 PCI-PCMCIA bridge");
-MODULE_AUTHOR("Jun Komuro <komurojun@mbn.nifty.com>");
+MODULE_AUTHOR("Jun Komuro <komurojun-mbn@nifty.com>");
 
 #define MAX_SOCKETS 2
 
@@ -39,11 +39,40 @@
  */
 #define to_cycles(ns)	((ns)/120)
 
-static spinlock_t port_lock = SPIN_LOCK_UNLOCKED;
+#ifndef NO_IRQ
+#define NO_IRQ	((unsigned int)(0))
+#endif
+
+/*
+ * PARAMETERS
+ *  irq_mode=n
+ *     Specifies the interrupt delivery mode.  The default (1) is to use PCI
+ *     interrupts; a value of 0 selects ISA interrupts. This must be set for
+ *     correct operation of PCI card readers.
+ *
+ *  irq_list=i,j,...
+ *     This list limits the set of interrupts that can be used by PCMCIA
+ *     cards.
+ *     The default list is 3,4,5,7,9,10,11.
+ *     (irq_list parameter is not used, if irq_mode = 1)
+ */
+
+static int irq_mode = 1; /* 0 = ISA interrupt, 1 = PCI interrupt */
+static int irq_list[16];
+static int irq_list_count = 0;
+
+module_param(irq_mode, int, 0444);
+module_param_array(irq_list, int, &irq_list_count, 0444);
+MODULE_PARM_DESC(irq_mode,
+		"interrupt delivery mode. 0 = ISA, 1 = PCI. default is 1");
+MODULE_PARM_DESC(irq_list, "interrupts that can be used by PCMCIA cards");
+
+static DEFINE_SPINLOCK(port_lock);
 
 /* basic value read/write functions */
 
-static unsigned char indirect_read(struct pd6729_socket *socket, unsigned short reg)
+static unsigned char indirect_read(struct pd6729_socket *socket,
+				   unsigned short reg)
 {
 	unsigned long port;
 	unsigned char val;
@@ -59,7 +88,8 @@
 	return val;
 }
 
-static unsigned short indirect_read16(struct pd6729_socket *socket, unsigned short reg)
+static unsigned short indirect_read16(struct pd6729_socket *socket,
+				      unsigned short reg)
 {
 	unsigned long port;
 	unsigned short tmp;
@@ -78,7 +108,8 @@
 	return tmp;
 }
 
-static void indirect_write(struct pd6729_socket *socket, unsigned short reg, unsigned char value)
+static void indirect_write(struct pd6729_socket *socket, unsigned short reg,
+			   unsigned char value)
 {
 	unsigned long port;
 	unsigned long flags;
@@ -91,7 +122,8 @@
 	spin_unlock_irqrestore(&port_lock, flags);
 }
 
-static void indirect_setbit(struct pd6729_socket *socket, unsigned short reg, unsigned char mask)
+static void indirect_setbit(struct pd6729_socket *socket, unsigned short reg,
+			    unsigned char mask)
 {
 	unsigned long port;
 	unsigned char val;
@@ -108,7 +140,8 @@
 	spin_unlock_irqrestore(&port_lock, flags);
 }
 
-static void indirect_resetbit(struct pd6729_socket *socket, unsigned short reg, unsigned char mask)
+static void indirect_resetbit(struct pd6729_socket *socket, unsigned short reg,
+			      unsigned char mask)
 {
 	unsigned long port;
 	unsigned char val;
@@ -125,7 +158,8 @@
 	spin_unlock_irqrestore(&port_lock, flags);
 }
 
-static void indirect_write16(struct pd6729_socket *socket, unsigned short reg, unsigned short value)
+static void indirect_write16(struct pd6729_socket *socket, unsigned short reg,
+			     unsigned short value)
 {
 	unsigned long port;
 	unsigned char val;
@@ -160,7 +194,8 @@
 	while (1) {
 		loopcount++;
 		if (loopcount > 20) {
-			printk(KERN_ERR "pd6729: infinite eventloop in interrupt\n");
+			printk(KERN_ERR "pd6729: infinite eventloop "
+			       "in interrupt\n");
 			break;
 		}
 
@@ -182,14 +217,19 @@
 				dprintk("Card detected in socket %i!\n", i);
 			}
 
-			if (indirect_read(&socket[i], I365_INTCTL) & I365_PC_IOCARD) {
+			if (indirect_read(&socket[i], I365_INTCTL)
+						& I365_PC_IOCARD) {
 				/* For IO/CARDS, bit 0 means "read the card" */
-				events |= (csc & I365_CSC_STSCHG) ? SS_STSCHG : 0;
+				events |= (csc & I365_CSC_STSCHG)
+						? SS_STSCHG : 0;
 			} else {
 				/* Check for battery/ready events */
-				events |= (csc & I365_CSC_BVD1) ? SS_BATDEAD : 0;
-				events |= (csc & I365_CSC_BVD2) ? SS_BATWARN : 0;
-				events |= (csc & I365_CSC_READY) ? SS_READY : 0;
+				events |= (csc & I365_CSC_BVD1)
+						? SS_BATDEAD : 0;
+				events |= (csc & I365_CSC_BVD2)
+						? SS_BATWARN : 0;
+				events |= (csc & I365_CSC_READY)
+						? SS_READY : 0;
 			}
 
 			if (events) {
@@ -206,17 +246,18 @@
 
 /* socket functions */
 
-static void set_bridge_state(struct pd6729_socket *socket)
+static void pd6729_interrupt_wrapper(unsigned long data)
 {
-	indirect_write(socket, I365_GBLCTL, 0x00);
-	indirect_write(socket, I365_GENCTL, 0x00);
+	struct pd6729_socket *socket = (struct pd6729_socket *) data;
 
-	indirect_setbit(socket, I365_INTCTL, 0x08);
+	pd6729_interrupt(0, (void *)socket, NULL);
+	mod_timer(&socket->poll_timer, jiffies + HZ);
 }
 
 static int pd6729_get_status(struct pcmcia_socket *sock, u_int *value)
 {
-	struct pd6729_socket *socket = container_of(sock, struct pd6729_socket, socket);
+	struct pd6729_socket *socket
+			= container_of(sock, struct pd6729_socket, socket);
 	unsigned int status;
 	unsigned int data;
 	struct pd6729_socket *t;
@@ -265,7 +306,8 @@
 
 static int pd6729_get_socket(struct pcmcia_socket *sock, socket_state_t *state)
 {
-	struct pd6729_socket *socket = container_of(sock, struct pd6729_socket, socket);
+	struct pd6729_socket *socket
+			= container_of(sock, struct pd6729_socket, socket);
 	unsigned char reg, vcc, vpp;
 
 	state->flags    = 0;
@@ -274,10 +316,7 @@
 	state->io_irq   = 0;
 	state->csc_mask = 0;
 
-	/*
-	 * First the power status of the socket
-	 * PCTRL - Power Control Register
-	 */
+	/* First the power status of the socket */
 	reg = indirect_read(socket, I365_POWER);
 
 	if (reg & I365_PWR_AUTO)
@@ -302,10 +341,7 @@
 			state->Vpp = 120;
 	}
 
-	/*
-	 * Now the IO card, RESET flags and IO interrupt
-	 * IGENC, Interrupt and General Control
-	 */
+	/* Now the IO card, RESET flags and IO interrupt */
 	reg = indirect_read(socket, I365_INTCTL);
 
 	if ((reg & I365_PC_RESET) == 0)
@@ -314,12 +350,9 @@
 		state->flags |= SS_IOCARD; /* This is an IO card */
 
 	/* Set the IRQ number */
-	state->io_irq = socket->socket.pci_irq;
+	state->io_irq = socket->card_irq;
 
-	/*
-	 * Card status change
-	 * CSCICR, Card Status Change Interrupt Configuration
-	 */
+	/* Card status change */
 	reg = indirect_read(socket, I365_CSCINT);
 
 	if (reg & I365_CSC_DETECT)
@@ -342,21 +375,23 @@
 
 static int pd6729_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
 {
-	struct pd6729_socket *socket = container_of(sock, struct pd6729_socket, socket);
-	unsigned char reg;
+	struct pd6729_socket *socket
+			= container_of(sock, struct pd6729_socket, socket);
+	unsigned char reg, data;
 
 	/* First, set the global controller options */
-
-	set_bridge_state(socket);
+	indirect_write(socket, I365_GBLCTL, 0x00);
+	indirect_write(socket, I365_GENCTL, 0x00);
 
 	/* Values for the IGENC register */
+	socket->card_irq = state->io_irq;
 
 	reg = 0;
  	/* The reset bit has "inverse" logic */
 	if (!(state->flags & SS_RESET))
-		reg = reg | I365_PC_RESET;
+		reg |= I365_PC_RESET;
 	if (state->flags & SS_IOCARD)
-		reg = reg | I365_PC_IOCARD;
+		reg |= I365_PC_IOCARD;
 
 	/* IGENC, Interrupt and General Control Register */
 	indirect_write(socket, I365_INTCTL, reg);
@@ -390,7 +425,8 @@
 		indirect_resetbit(socket, PD67_MISC_CTL_1, PD67_MC1_VCC_3V);
 		break;
 	default:
-		dprintk("pd6729: pd6729_set_socket called with invalid VCC power value: %i\n",
+		dprintk("pd6729: pd6729_set_socket called with "
+				"invalid VCC power value: %i\n",
 			state->Vcc);
 		return -EINVAL;
 	}
@@ -418,9 +454,14 @@
 	if (reg != indirect_read(socket, I365_POWER))
 		indirect_write(socket, I365_POWER, reg);
 
-	/* Now, specifiy that all interrupts are to be done as PCI interrupts */
+	if (irq_mode == 1) {
+		 /* all interrupts are to be done as PCI interrupts */
+		data = PD67_EC1_INV_MGMT_IRQ | PD67_EC1_INV_CARD_IRQ;
+	} else
+		data = 0;
+
 	indirect_write(socket, PD67_EXT_INDEX, PD67_EXT_CTL_1);
-	indirect_write(socket, PD67_EXT_DATA, PD67_EC1_INV_MGMT_IRQ | PD67_EC1_INV_CARD_IRQ);
+	indirect_write(socket, PD67_EXT_DATA, data);
 
 	/* Enable specific interrupt events */
 
@@ -439,11 +480,15 @@
 		if (state->csc_mask & SS_READY)
 			reg |= I365_CSC_READY;
 	}
-	reg |= 0x30;	/* management IRQ: PCI INTA# = "irq 3" */
+	if (irq_mode == 1)
+		reg |= 0x30;	/* management IRQ: PCI INTA# = "irq 3" */
 	indirect_write(socket, I365_CSCINT, reg);
 
 	reg = indirect_read(socket, I365_INTCTL);
-	reg |= 0x03;	/* card IRQ: PCI INTA# = "irq 3" */
+	if (irq_mode == 1)
+		reg |= 0x03;	/* card IRQ: PCI INTA# = "irq 3" */
+	else
+		reg |= socket->card_irq;
 	indirect_write(socket, I365_INTCTL, reg);
 
 	/* now clear the (probably bogus) pending stuff by doing a dummy read */
@@ -452,9 +497,11 @@
 	return 0;
 }
 
-static int pd6729_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
+static int pd6729_set_io_map(struct pcmcia_socket *sock,
+			     struct pccard_io_map *io)
 {
-	struct pd6729_socket *socket = container_of(sock, struct pd6729_socket, socket);
+	struct pd6729_socket *socket
+			= container_of(sock, struct pd6729_socket, socket);
 	unsigned char map, ioctl;
 
 	map = io->map;
@@ -469,7 +516,8 @@
 	if (indirect_read(socket, I365_ADDRWIN) & I365_ENA_IO(map))
 		indirect_resetbit(socket, I365_ADDRWIN, I365_ENA_IO(map));
 
-/*	dprintk("set_io_map: Setting range to %x - %x\n", io->start, io->stop);*/
+	/* dprintk("set_io_map: Setting range to %x - %x\n",
+	   io->start, io->stop);*/
 
 	/* write the new values */
 	indirect_write16(socket, I365_IO(map)+I365_W_START, io->start);
@@ -490,9 +538,11 @@
 	return 0;
 }
 
-static int pd6729_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *mem)
+static int pd6729_set_mem_map(struct pcmcia_socket *sock,
+			      struct pccard_mem_map *mem)
 {
-	struct pd6729_socket *socket = container_of(sock, struct pd6729_socket, socket);
+	struct pd6729_socket *socket
+			 = container_of(sock, struct pd6729_socket, socket);
 	unsigned short base, i;
 	unsigned char map;
 
@@ -504,8 +554,6 @@
 
 	if ((mem->res->start > mem->res->end) || (mem->speed > 1000)) {
 		printk("pd6729_set_mem_map: invalid address / speed");
-		/* printk("invalid mem map for socket %i : %lx to %lx with a start of %x\n",
-			 sock, mem->res->start, mem->res->end, mem->card_start); */
 		return -EINVAL;
 	}
 
@@ -551,11 +599,11 @@
 	if (mem->flags & MAP_WRPROT)
 		i |= I365_MEM_WRPROT;
 	if (mem->flags & MAP_ATTRIB) {
-/*		dprintk("requesting attribute memory for socket %i\n",
+		/* dprintk("requesting attribute memory for socket %i\n",
 			socket->number);*/
 		i |= I365_MEM_REG;
 	} else {
-/*		dprintk("requesting normal memory for socket %i\n",
+		/* dprintk("requesting normal memory for socket %i\n",
 			socket->number);*/
 	}
 	indirect_write16(socket, base + I365_W_OFF, i);
@@ -604,13 +652,66 @@
 	.set_mem_map		= pd6729_set_mem_map,
 };
 
-static int __devinit pd6729_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
+static irqreturn_t pd6729_test(int irq, void *dev, struct pt_regs *regs)
+{
+	dprintk("-> hit on irq %d\n", irq);
+	return IRQ_HANDLED;
+}
+
+static int pd6729_check_irq(int irq, int flags)
+{
+	if (request_irq(irq, pd6729_test, flags, "x", pd6729_test) != 0)
+		return -1;
+	free_irq(irq, pd6729_test);
+	return 0;
+}
+
+static u_int __init pd6729_isa_scan(void)
+{
+	u_int mask0, mask = 0;
+	int i;
+
+	if (irq_mode == 1) {
+		printk(KERN_INFO "pd6729: PCI card interrupts, "
+						"PCI status changes\n");
+		return 0;
+	}
+
+	if (irq_list_count == 0)
+		mask0 = 0xffff;
+	else
+		for (i = mask0 = 0; i < irq_list_count; i++)
+			mask0 |= (1<<irq_list[i]);
+
+	mask0 &= PD67_MASK;
+
+	/* just find interrupts that aren't in use */
+	for (i = 0; i < 16; i++)
+		if ((mask0 & (1 << i)) && (pd6729_check_irq(i, 0) == 0))
+			mask |= (1 << i);
+
+	printk(KERN_INFO "pd6729: ISA irqs = ");
+	for (i = 0; i < 16; i++)
+		if (mask & (1<<i))
+			printk("%s%d", ((mask & ((1<<i)-1)) ? "," : ""), i);
+
+	if (mask == 0) printk("none!");
+
+	printk("  polling status changes.\n");
+
+	return mask;
+}
+
+static int __devinit pd6729_pci_probe(struct pci_dev *dev,
+				      const struct pci_device_id *id)
 {
 	int i, j, ret;
+	u_int mask;
 	char configbyte;
 	struct pd6729_socket *socket;
 
-	socket = kmalloc(sizeof(struct pd6729_socket) * MAX_SOCKETS, GFP_KERNEL);
+	socket = kmalloc(sizeof(struct pd6729_socket) * MAX_SOCKETS,
+			 GFP_KERNEL);
 	if (!socket)
 		return -ENOMEM;
 
@@ -619,13 +720,11 @@
 	if ((ret = pci_enable_device(dev)))
 		goto err_out_free_mem;
 
-	printk(KERN_INFO "pd6729: Cirrus PD6729 PCI to PCMCIA Bridge at 0x%lx on irq %d\n",
-		pci_resource_start(dev, 0), dev->irq);
-	printk(KERN_INFO "pd6729: configured as a %d socket device.\n", MAX_SOCKETS);
+	printk(KERN_INFO "pd6729: Cirrus PD6729 PCI to PCMCIA Bridge "
+		"at 0x%lx on irq %d\n",	pci_resource_start(dev, 0), dev->irq);
  	/*
-	 * Since we have no memory BARs some firmware we may not
-	 * have had PCI_COMMAND_MEM enabled, yet the device needs
-	 * it.
+	 * Since we have no memory BARs some firmware may not
+	 * have had PCI_COMMAND_MEMORY enabled, yet the device needs it.
 	 */
 	pci_read_config_byte(dev, PCI_COMMAND, &configbyte);
 	if (!(configbyte & PCI_COMMAND_MEMORY)) {
@@ -640,33 +739,54 @@
 		goto err_out_disable;
 	}
 
+	if (dev->irq == NO_IRQ)
+		irq_mode = 0;	/* fall back to ISA interrupt mode */
+
+	mask = pd6729_isa_scan();
+	if (irq_mode == 0 && mask == 0) {
+		printk(KERN_INFO "pd6729: no ISA interrupt is available.\n");
+		goto err_out_free_res;
+	}
+
 	for (i = 0; i < MAX_SOCKETS; i++) {
 		socket[i].io_base = pci_resource_start(dev, 0);
 		socket[i].socket.features |= SS_CAP_PCCARD;
 		socket[i].socket.map_size = 0x1000;
-		socket[i].socket.irq_mask = 0;
+		socket[i].socket.irq_mask = mask;
 		socket[i].socket.pci_irq  = dev->irq;
 		socket[i].socket.owner = THIS_MODULE;
 
 		socket[i].number = i;
 
 		socket[i].socket.ops = &pd6729_operations;
+		socket[i].socket.resource_ops = &pccard_nonstatic_ops;
 		socket[i].socket.dev.dev = &dev->dev;
 		socket[i].socket.driver_data = &socket[i];
 	}
 
 	pci_set_drvdata(dev, socket);
-
-	/* Register the interrupt handler */
-	if ((ret = request_irq(dev->irq, pd6729_interrupt, SA_SHIRQ, "pd6729", socket))) {
-		printk(KERN_ERR "pd6729: Failed to register irq %d, aborting\n", dev->irq);
-		goto err_out_free_res;
+	if (irq_mode == 1) {
+		/* Register the interrupt handler */
+		if ((ret = request_irq(dev->irq, pd6729_interrupt, SA_SHIRQ,
+							"pd6729", socket))) {
+			printk(KERN_ERR "pd6729: Failed to register irq %d, "
+							"aborting\n", dev->irq);
+			goto err_out_free_res;
+		}
+	} else {
+		/* poll Card status change */
+		init_timer(&socket->poll_timer);
+		socket->poll_timer.function = pd6729_interrupt_wrapper;
+		socket->poll_timer.data = (unsigned long)socket;
+		socket->poll_timer.expires = jiffies + HZ;
+		add_timer(&socket->poll_timer);
 	}
 
 	for (i = 0; i < MAX_SOCKETS; i++) {
 		ret = pcmcia_register_socket(&socket[i].socket);
 		if (ret) {
-			printk(KERN_INFO "pd6729: pcmcia_register_socket failed.\n");
+			printk(KERN_INFO "pd6729: pcmcia_register_socket "
+					       "failed.\n");
 			for (j = 0; j < i ; j++)
 				pcmcia_unregister_socket(&socket[j].socket);
 			goto err_out_free_res2;
@@ -676,7 +796,10 @@
 	return 0;
 
  err_out_free_res2:
-	free_irq(dev->irq, socket);
+	if (irq_mode == 1)
+		free_irq(dev->irq, socket);
+	else
+		del_timer_sync(&socket->poll_timer);
  err_out_free_res:
 	pci_release_regions(dev);
  err_out_disable:
@@ -692,10 +815,18 @@
 	int i;
 	struct pd6729_socket *socket = pci_get_drvdata(dev);
 
-	for (i = 0; i < MAX_SOCKETS; i++)
+	for (i = 0; i < MAX_SOCKETS; i++) {
+		/* Turn off all interrupt sources */
+		indirect_write(&socket[i], I365_CSCINT, 0);
+		indirect_write(&socket[i], I365_INTCTL, 0);
+
 		pcmcia_unregister_socket(&socket[i].socket);
+	}
 
-	free_irq(dev->irq, socket);
+	if (irq_mode == 1)
+		free_irq(dev->irq, socket);
+	else
+		del_timer_sync(&socket->poll_timer);
 	pci_release_regions(dev);
 	pci_disable_device(dev);
 
diff -Nru a/drivers/pcmcia/pd6729.h b/drivers/pcmcia/pd6729.h
--- a/drivers/pcmcia/pd6729.h	2005-03-01 23:38:51 -08:00
+++ b/drivers/pcmcia/pd6729.h	2005-03-01 23:38:51 -08:00
@@ -16,13 +16,15 @@
 #define PD67_EXD_VS1(s)		(0x01 << ((s) << 1))
 #define PD67_EXD_VS2(s)		(0x02 << ((s) << 1))
 
-
-
+/* Default ISA interrupt mask */
+#define PD67_MASK	0x0eb8	/* irq 11,10,9,7,5,4,3 */
 
 struct pd6729_socket {
 	int	number;
+	int	card_irq;
 	unsigned long io_base; 	/* base io address of the socket */
 	struct pcmcia_socket socket;
+	struct timer_list poll_timer;
 };
 
 #endif
diff -Nru a/drivers/pcmcia/pxa2xx_sharpsl.c b/drivers/pcmcia/pxa2xx_sharpsl.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/pcmcia/pxa2xx_sharpsl.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,264 @@
+/*
+ * Sharp SL-C7xx Series PCMCIA routines
+ *
+ * Copyright (c) 2004-2005 Richard Purdie
+ *
+ * Based on Sharp's 2.4 kernel patches and pxa2xx_mainstone.c
+ *
+ * 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/kernel.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/device.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+
+#include <asm/hardware/scoop.h>
+#include <asm/arch/corgi.h>
+#include <asm/arch/pxa-regs.h>
+
+#include "soc_common.h"
+
+#define	NO_KEEP_VS 0x0001
+
+static unsigned char keep_vs;
+static unsigned char keep_rd;
+
+static struct pcmcia_irqs irqs[] = {
+	{ 0, CORGI_IRQ_GPIO_CF_CD, "PCMCIA0 CD"},
+};
+
+static void sharpsl_pcmcia_init_reset(void)
+{
+	reset_scoop();
+	keep_vs = NO_KEEP_VS;
+	keep_rd = 0;
+}
+
+static int sharpsl_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
+{
+	int ret;
+
+	/*
+	 * Setup default state of GPIO outputs
+	 * before we enable them as outputs.
+	 */
+	GPSR(GPIO48_nPOE) =
+		GPIO_bit(GPIO48_nPOE) |
+		GPIO_bit(GPIO49_nPWE) |
+		GPIO_bit(GPIO50_nPIOR) |
+		GPIO_bit(GPIO51_nPIOW) |
+		GPIO_bit(GPIO52_nPCE_1) |
+		GPIO_bit(GPIO53_nPCE_2);
+
+	pxa_gpio_mode(GPIO48_nPOE_MD);
+	pxa_gpio_mode(GPIO49_nPWE_MD);
+	pxa_gpio_mode(GPIO50_nPIOR_MD);
+	pxa_gpio_mode(GPIO51_nPIOW_MD);
+	pxa_gpio_mode(GPIO52_nPCE_1_MD);
+	pxa_gpio_mode(GPIO53_nPCE_2_MD);
+	pxa_gpio_mode(GPIO54_pSKTSEL_MD);
+	pxa_gpio_mode(GPIO55_nPREG_MD);
+	pxa_gpio_mode(GPIO56_nPWAIT_MD);
+	pxa_gpio_mode(GPIO57_nIOIS16_MD);
+
+	/* Register interrupts */
+	ret = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
+
+	if (ret) {
+		printk(KERN_ERR "Request for Compact Flash IRQ failed\n");
+		return ret;
+	}
+
+	/* Enable interrupt */
+	write_scoop_reg(SCOOP_IMR, 0x00C0);
+	write_scoop_reg(SCOOP_MCR, 0x0101);
+	keep_vs = NO_KEEP_VS;
+
+	skt->irq = CORGI_IRQ_GPIO_CF_IRQ;
+
+	return 0;
+}
+
+static void sharpsl_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
+{
+	soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
+
+	/* CF_BUS_OFF */
+	sharpsl_pcmcia_init_reset();
+}
+
+
+static void sharpsl_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
+				    struct pcmcia_state *state)
+{
+	unsigned short cpr, csr;
+
+	cpr = read_scoop_reg(SCOOP_CPR);
+
+	write_scoop_reg(SCOOP_IRM, 0x00FF);
+	write_scoop_reg(SCOOP_ISR, 0x0000);
+	write_scoop_reg(SCOOP_IRM, 0x0000);
+	csr = read_scoop_reg(SCOOP_CSR);
+	if (csr & 0x0004) {
+		/* card eject */
+		write_scoop_reg(SCOOP_CDR, 0x0000);
+		keep_vs = NO_KEEP_VS;
+	}
+	else if (!(keep_vs & NO_KEEP_VS)) {
+		/* keep vs1,vs2 */
+		write_scoop_reg(SCOOP_CDR, 0x0000);
+		csr |= keep_vs;
+	}
+	else if (cpr & 0x0003) {
+		/* power on */
+		write_scoop_reg(SCOOP_CDR, 0x0000);
+		keep_vs = (csr & 0x00C0);
+	}
+	else {
+		/* card detect */
+		write_scoop_reg(SCOOP_CDR, 0x0002);
+	}
+
+	state->detect = (csr & 0x0004) ? 0 : 1;
+	state->ready  = (csr & 0x0002) ? 1 : 0;
+	state->bvd1   = (csr & 0x0010) ? 1 : 0;
+	state->bvd2   = (csr & 0x0020) ? 1 : 0;
+	state->wrprot = (csr & 0x0008) ? 1 : 0;
+	state->vs_3v  = (csr & 0x0040) ? 0 : 1;
+	state->vs_Xv  = (csr & 0x0080) ? 0 : 1;
+
+	if ((cpr & 0x0080) && ((cpr & 0x8040) != 0x8040)) {
+		printk(KERN_ERR "sharpsl_pcmcia_socket_state(): CPR=%04X, Low voltage!\n", cpr);
+	}
+
+}
+
+
+static int sharpsl_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
+				       const socket_state_t *state)
+{
+	unsigned long flags;
+
+	unsigned short cpr, ncpr, ccr, nccr, mcr, nmcr, imr, nimr;
+
+	switch (state->Vcc) {
+	case	0:  	break;
+	case 	33: 	break;
+	case	50: 	break;
+	default:
+		 printk(KERN_ERR "sharpsl_pcmcia_configure_socket(): bad Vcc %u\n", state->Vcc);
+		 return -1;
+	}
+
+	if ((state->Vpp!=state->Vcc) && (state->Vpp!=0)) {
+		printk(KERN_ERR "CF slot cannot support Vpp %u\n", state->Vpp);
+		return -1;
+	}
+
+	local_irq_save(flags);
+
+	nmcr = (mcr = read_scoop_reg(SCOOP_MCR)) & ~0x0010;
+	ncpr = (cpr = read_scoop_reg(SCOOP_CPR)) & ~0x0083;
+	nccr = (ccr = read_scoop_reg(SCOOP_CCR)) & ~0x0080;
+	nimr = (imr = read_scoop_reg(SCOOP_IMR)) & ~0x003E;
+
+	ncpr |= (state->Vcc == 33) ? 0x0001 :
+				(state->Vcc == 50) ? 0x0002 : 0;
+	nmcr |= (state->flags&SS_IOCARD) ? 0x0010 : 0;
+	ncpr |= (state->flags&SS_OUTPUT_ENA) ? 0x0080 : 0;
+	nccr |= (state->flags&SS_RESET)? 0x0080: 0;
+	nimr |=	((skt->status&SS_DETECT) ? 0x0004 : 0)|
+			((skt->status&SS_READY)  ? 0x0002 : 0)|
+			((skt->status&SS_BATDEAD)? 0x0010 : 0)|
+			((skt->status&SS_BATWARN)? 0x0020 : 0)|
+			((skt->status&SS_STSCHG) ? 0x0010 : 0)|
+			((skt->status&SS_WRPROT) ? 0x0008 : 0);
+
+	if (!(ncpr & 0x0003)) {
+		keep_rd = 0;
+	} else if (!keep_rd) {
+		if (nccr & 0x0080)
+			keep_rd = 1;
+		else
+			nccr |= 0x0080;
+	}
+
+	if (mcr != nmcr)
+		write_scoop_reg(SCOOP_MCR, nmcr);
+	if (cpr != ncpr)
+		write_scoop_reg(SCOOP_CPR, ncpr);
+	if (ccr != nccr)
+		write_scoop_reg(SCOOP_CCR, nccr);
+	if (imr != nimr)
+		write_scoop_reg(SCOOP_IMR, nimr);
+
+	local_irq_restore(flags);
+
+	return 0;
+}
+
+static void sharpsl_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
+{
+}
+
+static void sharpsl_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
+{
+}
+
+static struct pcmcia_low_level sharpsl_pcmcia_ops = {
+	.owner				= THIS_MODULE,
+	.hw_init			= sharpsl_pcmcia_hw_init,
+	.hw_shutdown		= sharpsl_pcmcia_hw_shutdown,
+	.socket_state		= sharpsl_pcmcia_socket_state,
+	.configure_socket	= sharpsl_pcmcia_configure_socket,
+	.socket_init		= sharpsl_pcmcia_socket_init,
+	.socket_suspend		= sharpsl_pcmcia_socket_suspend,
+	.first				= 0,
+	.nr					= 1,
+};
+
+static struct platform_device *sharpsl_pcmcia_device;
+
+static int __init sharpsl_pcmcia_init(void)
+{
+	int ret;
+
+	sharpsl_pcmcia_device = kmalloc(sizeof(*sharpsl_pcmcia_device), GFP_KERNEL);
+	if (!sharpsl_pcmcia_device)
+		return -ENOMEM;
+	memset(sharpsl_pcmcia_device, 0, sizeof(*sharpsl_pcmcia_device));
+	sharpsl_pcmcia_device->name = "pxa2xx-pcmcia";
+	sharpsl_pcmcia_device->dev.platform_data = &sharpsl_pcmcia_ops;
+
+	ret = platform_device_register(sharpsl_pcmcia_device);
+	if (ret)
+		kfree(sharpsl_pcmcia_device);
+
+	return ret;
+}
+
+static void __exit sharpsl_pcmcia_exit(void)
+{
+	/*
+	 * This call is supposed to free our sharpsl_pcmcia_device.
+	 * Unfortunately platform_device don't have a free method, and
+	 * we can't assume it's free of any reference at this point so we
+	 * can't free it either.
+	 */
+	platform_device_unregister(sharpsl_pcmcia_device);
+}
+
+module_init(sharpsl_pcmcia_init);
+module_exit(sharpsl_pcmcia_exit);
+
+MODULE_DESCRIPTION("Sharp SL Series PCMCIA Support");
+MODULE_LICENSE("GPL");
diff -Nru a/drivers/pcmcia/rsrc_mgr.c b/drivers/pcmcia/rsrc_mgr.c
--- a/drivers/pcmcia/rsrc_mgr.c	2005-03-01 23:38:59 -08:00
+++ b/drivers/pcmcia/rsrc_mgr.c	2005-03-01 23:38:59 -08:00
@@ -1,1007 +1,124 @@
-/*======================================================================
-
-    Resource management routines
-
-    rsrc_mgr.c 1.79 2000/08/30 20:23:58
-
-    The contents of this file are subject to the Mozilla Public
-    License Version 1.1 (the "License"); you may not use this file
-    except in compliance with the License. You may obtain a copy of
-    the License at http://www.mozilla.org/MPL/
-
-    Software distributed under the License is distributed on an "AS
-    IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-    implied. See the License for the specific language governing
-    rights and limitations under the License.
-
-    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.
-
-    Alternatively, the contents of this file may be used under the
-    terms of the GNU General Public License version 2 (the "GPL"), in which
-    case the provisions of the GPL are applicable instead of the
-    above.  If you wish to allow the use of your version of this file
-    only under the terms of the GPL and not to allow others to use
-    your version of this file under the MPL, indicate your decision
-    by deleting the provisions above and replace them with the notice
-    and other provisions required by the GPL.  If you do not delete
-    the provisions above, a recipient may use your version of this
-    file under either the MPL or the GPL.
-    
-======================================================================*/
+/*
+ * rsrc_mgr.c -- Resource management routines and/or wrappers
+ *
+ * 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
+ */
 
 #include <linux/config.h>
 #include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
 #include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/ioport.h>
-#include <linux/timer.h>
-#include <linux/pci.h>
-#include <asm/irq.h>
-#include <asm/io.h>
 
 #include <pcmcia/cs_types.h>
 #include <pcmcia/ss.h>
 #include <pcmcia/cs.h>
-#include <pcmcia/bulkmem.h>
-#include <pcmcia/cistpl.h>
 #include "cs_internal.h"
 
-/*====================================================================*/
-
-/* Parameters that can be set with 'insmod' */
-
-#define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0444)
 
-INT_MODULE_PARM(probe_mem,	1);		/* memory probe? */
 #ifdef CONFIG_PCMCIA_PROBE
-INT_MODULE_PARM(probe_io,	1);		/* IO port probe? */
-INT_MODULE_PARM(mem_limit,	0x10000);
-#endif
-
-/*======================================================================
-
-    The resource_map_t structures are used to track what resources are
-    available for allocation for PC Card devices.
-
-======================================================================*/
-
-typedef struct resource_map_t {
-    u_long			base, num;
-    struct resource_map_t	*next;
-} resource_map_t;
-
-/* Memory resource database */
-static resource_map_t mem_db = {
-	.next	= &mem_db,
-};
-
-/* IO port resource database */
-static resource_map_t io_db = {
-	.next	= &io_db,
-};
-
-static DECLARE_MUTEX(rsrc_sem);
-static unsigned int rsrc_mem_probe;
-#define MEM_PROBE_LOW	(1 << 0)
-#define MEM_PROBE_HIGH	(1 << 1)
-
-#ifdef CONFIG_PCMCIA_PROBE
-
-typedef struct irq_info_t {
-    u_int			Attributes;
-    int				time_share, dyn_share;
-    struct pcmcia_socket	*Socket;
-} irq_info_t;
-
-/* Table of IRQ assignments */
-static irq_info_t irq_table[NR_IRQS];
-
-#endif
-
-/*======================================================================
-
-    Linux resource management extensions
-
-======================================================================*/
-
-static struct resource *
-make_resource(unsigned long b, unsigned long n, int flags, char *name)
-{
-	struct resource *res = kmalloc(sizeof(*res), GFP_KERNEL);
-
-	if (res) {
-		memset(res, 0, sizeof(*res));
-		res->name = name;
-		res->start = b;
-		res->end = b + n - 1;
-		res->flags = flags;
-	}
-	return res;
-}
-
-static struct resource *
-claim_region(struct pcmcia_socket *s, unsigned long base, unsigned long size,
-	     int type, char *name)
-{
-	struct resource *res, *parent;
-
-	parent = type & IORESOURCE_MEM ? &iomem_resource : &ioport_resource;
-	res = make_resource(base, size, type | IORESOURCE_BUSY, name);
-
-	if (res) {
-#ifdef CONFIG_PCI
-		if (s && s->cb_dev)
-			parent = pci_find_parent_resource(s->cb_dev, res);
-#endif
-		if (!parent || request_resource(parent, res)) {
-			kfree(res);
-			res = NULL;
-		}
-	}
-	return res;
-}
-
-static void free_region(struct resource *res)
-{
-	if (res) {
-		release_resource(res);
-		kfree(res);
-	}
-}
-
-/*======================================================================
-
-    These manage the internal databases of available resources.
-    
-======================================================================*/
-
-static int add_interval(resource_map_t *map, u_long base, u_long num)
-{
-    resource_map_t *p, *q;
-
-    for (p = map; ; p = p->next) {
-	if ((p != map) && (p->base+p->num-1 >= base))
-	    return -1;
-	if ((p->next == map) || (p->next->base > base+num-1))
-	    break;
-    }
-    q = kmalloc(sizeof(resource_map_t), GFP_KERNEL);
-    if (!q) return CS_OUT_OF_RESOURCE;
-    q->base = base; q->num = num;
-    q->next = p->next; p->next = q;
-    return CS_SUCCESS;
-}
-
-/*====================================================================*/
 
-static int sub_interval(resource_map_t *map, u_long base, u_long num)
+static int adjust_irq(struct pcmcia_socket *s, adjust_t *adj)
 {
-    resource_map_t *p, *q;
+	int irq;
+	u32 mask;
 
-    for (p = map; ; p = q) {
-	q = p->next;
-	if (q == map)
-	    break;
-	if ((q->base+q->num > base) && (base+num > q->base)) {
-	    if (q->base >= base) {
-		if (q->base+q->num <= base+num) {
-		    /* Delete whole block */
-		    p->next = q->next;
-		    kfree(q);
-		    /* don't advance the pointer yet */
-		    q = p;
-		} else {
-		    /* Cut off bit from the front */
-		    q->num = q->base + q->num - base - num;
-		    q->base = base + num;
-		}
-	    } else if (q->base+q->num <= base+num) {
-		/* Cut off bit from the end */
-		q->num = base - q->base;
-	    } else {
-		/* Split the block into two pieces */
-		p = kmalloc(sizeof(resource_map_t), GFP_KERNEL);
-		if (!p) return CS_OUT_OF_RESOURCE;
-		p->base = base+num;
-		p->num = q->base+q->num - p->base;
-		q->num = base - q->base;
-		p->next = q->next ; q->next = p;
-	    }
-	}
-    }
-    return CS_SUCCESS;
-}
-
-/*======================================================================
-
-    These routines examine a region of IO or memory addresses to
-    determine what ranges might be genuinely available.
-    
-======================================================================*/
-
-#ifdef CONFIG_PCMCIA_PROBE
-static void do_io_probe(ioaddr_t base, ioaddr_t num)
-{
-    struct resource *res;
-    ioaddr_t i, j, bad, any;
-    u_char *b, hole, most;
-    
-    printk(KERN_INFO "cs: IO port probe 0x%04x-0x%04x:",
-	   base, base+num-1);
-    
-    /* First, what does a floating port look like? */
-    b = kmalloc(256, GFP_KERNEL);
-    if (!b) {
-            printk(KERN_ERR "do_io_probe: unable to kmalloc 256 bytes");
-            return;
-    }   
-    memset(b, 0, 256);
-    for (i = base, most = 0; i < base+num; i += 8) {
-	res = claim_region(NULL, i, 8, IORESOURCE_IO, "PCMCIA IO probe");
-	if (!res)
-	    continue;
-	hole = inb(i);
-	for (j = 1; j < 8; j++)
-	    if (inb(i+j) != hole) break;
-	free_region(res);
-	if ((j == 8) && (++b[hole] > b[most]))
-	    most = hole;
-	if (b[most] == 127) break;
-    }
-    kfree(b);
-
-    bad = any = 0;
-    for (i = base; i < base+num; i += 8) {
-	res = claim_region(NULL, i, 8, IORESOURCE_IO, "PCMCIA IO probe");
-	if (!res)
-	    continue;
-	for (j = 0; j < 8; j++)
-	    if (inb(i+j) != most) break;
-	free_region(res);
-	if (j < 8) {
-	    if (!any)
-		printk(" excluding");
-	    if (!bad)
-		bad = any = i;
-	} else {
-	    if (bad) {
-		sub_interval(&io_db, bad, i-bad);
-		printk(" %#04x-%#04x", bad, i-1);
-		bad = 0;
-	    }
-	}
-    }
-    if (bad) {
-	if ((num > 16) && (bad == base) && (i == base+num)) {
-	    printk(" nothing: probe failed.\n");
-	    return;
-	} else {
-	    sub_interval(&io_db, bad, i-bad);
-	    printk(" %#04x-%#04x", bad, i-1);
-	}
-    }
-    
-    printk(any ? "\n" : " clean.\n");
-}
-#endif
-
-/*======================================================================
-
-    This is tricky... when we set up CIS memory, we try to validate
-    the memory window space allocations.
-    
-======================================================================*/
+	irq = adj->resource.irq.IRQ;
+	if ((irq < 0) || (irq > 15))
+		return CS_BAD_IRQ;
 
-/* Validation function for cards with a valid CIS */
-static int readable(struct pcmcia_socket *s, struct resource *res, cisinfo_t *info)
-{
-	int ret = -1;
-
-	s->cis_mem.res = res;
-	s->cis_virt = ioremap(res->start, s->map_size);
-	if (s->cis_virt) {
-		ret = pccard_validate_cis(s, BIND_FN_ALL, info);
-		/* invalidate mapping and CIS cache */
-		iounmap(s->cis_virt);
-		s->cis_virt = NULL;
-		destroy_cis_cache(s);
-	}
-	s->cis_mem.res = NULL;
-	if ((ret != 0) || (info->Chains == 0))
+	if (adj->Action != REMOVE_MANAGED_RESOURCE)
 		return 0;
-	return 1;
-}
-
-/* Validation function for simple memory cards */
-static int checksum(struct pcmcia_socket *s, struct resource *res)
-{
-	pccard_mem_map map;
-	int i, a = 0, b = -1, d;
-	void __iomem *virt;
-
-	virt = ioremap(res->start, s->map_size);
-	if (virt) {
-		map.map = 0;
-		map.flags = MAP_ACTIVE;
-		map.speed = 0;
-		map.res = res;
-		map.card_start = 0;
-		s->ops->set_mem_map(s, &map);
-
-		/* Don't bother checking every word... */
-		for (i = 0; i < s->map_size; i += 44) {
-			d = readl(virt+i);
-			a += d;
-			b &= d;
-		}
 
-		map.flags = 0;
-		s->ops->set_mem_map(s, &map);
+	mask = 1 << irq;
 
-		iounmap(virt);
-	}
-
-	return (b == -1) ? -1 : (a>>1);
-}
-
-static int
-cis_readable(struct pcmcia_socket *s, unsigned long base, unsigned long size)
-{
-	struct resource *res1, *res2;
-	cisinfo_t info1, info2;
-	int ret = 0;
-
-	res1 = claim_region(s, base, size/2, IORESOURCE_MEM, "cs memory probe");
-	res2 = claim_region(s, base + size/2, size/2, IORESOURCE_MEM, "cs memory probe");
-
-	if (res1 && res2) {
-		ret = readable(s, res1, &info1);
-		ret += readable(s, res2, &info2);
-	}
+	if (!(s->irq_mask & mask))
+		return 0;
 
-	free_region(res2);
-	free_region(res1);
+	s->irq_mask &= ~mask;
 
-	return (ret == 2) && (info1.Chains == info2.Chains);
+	return 0;
 }
 
-static int
-checksum_match(struct pcmcia_socket *s, unsigned long base, unsigned long size)
-{
-	struct resource *res1, *res2;
-	int a = -1, b = -1;
-
-	res1 = claim_region(s, base, size/2, IORESOURCE_MEM, "cs memory probe");
-	res2 = claim_region(s, base + size/2, size/2, IORESOURCE_MEM, "cs memory probe");
-
-	if (res1 && res2) {
-		a = checksum(s, res1);
-		b = checksum(s, res2);
-	}
-
-	free_region(res2);
-	free_region(res1);
+#else
 
-	return (a == b) && (a >= 0);
+static inline int adjust_irq(struct pcmcia_socket *s, adjust_t *adj) {
+	return CS_SUCCESS;
 }
 
-/*======================================================================
+#endif
 
-    The memory probe.  If the memory list includes a 64K-aligned block
-    below 1MB, we probe in 64K chunks, and as soon as we accumulate at
-    least mem_limit free space, we quit.
-    
-======================================================================*/
 
-static int do_mem_probe(u_long base, u_long num, struct pcmcia_socket *s)
+int pcmcia_adjust_resource_info(adjust_t *adj)
 {
-    u_long i, j, bad, fail, step;
-
-    printk(KERN_INFO "cs: memory probe 0x%06lx-0x%06lx:",
-	   base, base+num-1);
-    bad = fail = 0;
-    step = (num < 0x20000) ? 0x2000 : ((num>>4) & ~0x1fff);
-    /* cis_readable wants to map 2x map_size */
-    if (step < 2 * s->map_size)
-	step = 2 * s->map_size;
-    for (i = j = base; i < base+num; i = j + step) {
-	if (!fail) {	
-	    for (j = i; j < base+num; j += step) {
-		if (cis_readable(s, j, step))
-		    break;
-	    }
-	    fail = ((i == base) && (j == base+num));
-	}
-	if (fail) {
-	    for (j = i; j < base+num; j += 2*step)
-		if (checksum_match(s, j, step) &&
-		    checksum_match(s, j + step, step))
-		    break;
-	}
-	if (i != j) {
-	    if (!bad) printk(" excluding");
-	    printk(" %#05lx-%#05lx", i, j-1);
-	    sub_interval(&mem_db, i, j-i);
-	    bad += j-i;
-	}
-    }
-    printk(bad ? "\n" : " clean.\n");
-    return (num - bad);
-}
+	struct pcmcia_socket *s;
+	int ret = CS_UNSUPPORTED_FUNCTION;
 
-#ifdef CONFIG_PCMCIA_PROBE
+	down_read(&pcmcia_socket_list_rwsem);
+	list_for_each_entry(s, &pcmcia_socket_list, socket_list) {
 
-static u_long inv_probe(resource_map_t *m, struct pcmcia_socket *s)
-{
-    u_long ok;
-    if (m == &mem_db)
-	return 0;
-    ok = inv_probe(m->next, s);
-    if (ok) {
-	if (m->base >= 0x100000)
-	    sub_interval(&mem_db, m->base, m->num);
-	return ok;
-    }
-    if (m->base < 0x100000)
-	return 0;
-    return do_mem_probe(m->base, m->num, s);
-}
+		if (adj->Resource == RES_IRQ)
+			ret = adjust_irq(s, adj);
 
-static void validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
-{
-    resource_map_t *m, mm;
-    static u_char order[] = { 0xd0, 0xe0, 0xc0, 0xf0 };
-    u_long b, i, ok = 0;
-
-    /* We do up to four passes through the list */
-    if (probe_mask & MEM_PROBE_HIGH) {
-	if (inv_probe(mem_db.next, s) > 0)
-	    return;
-	printk(KERN_NOTICE "cs: warning: no high memory space "
-	       "available!\n");
-    }
-    if ((probe_mask & MEM_PROBE_LOW) == 0)
-	return;
-    for (m = mem_db.next; m != &mem_db; m = mm.next) {
-	mm = *m;
-	/* Only probe < 1 MB */
-	if (mm.base >= 0x100000) continue;
-	if ((mm.base | mm.num) & 0xffff) {
-	    ok += do_mem_probe(mm.base, mm.num, s);
-	    continue;
-	}
-	/* Special probe for 64K-aligned block */
-	for (i = 0; i < 4; i++) {
-	    b = order[i] << 12;
-	    if ((b >= mm.base) && (b+0x10000 <= mm.base+mm.num)) {
-		if (ok >= mem_limit)
-		    sub_interval(&mem_db, b, 0x10000);
-		else
-		    ok += do_mem_probe(b, 0x10000, s);
-	    }
+		else if (s->resource_ops->adjust_resource)
+			ret = s->resource_ops->adjust_resource(s, adj);
 	}
-    }
-}
-
-#else /* CONFIG_PCMCIA_PROBE */
+	up_read(&pcmcia_socket_list_rwsem);
 
-static void validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
-{
-	resource_map_t *m, mm;
-    
-	for (m = mem_db.next; m != &mem_db; m = mm.next) {
-		mm = *m;
-		if (do_mem_probe(mm.base, mm.num, s))
-			break;
-	}
+	return (ret);
 }
+EXPORT_SYMBOL(pcmcia_adjust_resource_info);
 
-#endif /* CONFIG_PCMCIA_PROBE */
-
-/*
- * Locking note: this is the only place where we take
- * both rsrc_sem and skt_sem.
- */
 void pcmcia_validate_mem(struct pcmcia_socket *s)
 {
-	if (probe_mem) {
-		unsigned int probe_mask;
-
-		down(&rsrc_sem);
-
-		probe_mask = MEM_PROBE_LOW;
-		if (s->features & SS_CAP_PAGE_REGS)
-			probe_mask = MEM_PROBE_HIGH;
-
-		if (probe_mask & ~rsrc_mem_probe) {
-			rsrc_mem_probe |= probe_mask;
-
-			down(&s->skt_sem);
-
-			if (s->state & SOCKET_PRESENT)
-				validate_mem(s, probe_mask);
-
-			up(&s->skt_sem);
-		}
-
-		up(&rsrc_sem);
-	}
+	if (s->resource_ops->validate_mem)
+		s->resource_ops->validate_mem(s);
 }
-
 EXPORT_SYMBOL(pcmcia_validate_mem);
 
-struct pcmcia_align_data {
-	unsigned long	mask;
-	unsigned long	offset;
-	resource_map_t	*map;
-};
-
-static void
-pcmcia_common_align(void *align_data, struct resource *res,
-		    unsigned long size, unsigned long align)
-{
-	struct pcmcia_align_data *data = align_data;
-	unsigned long start;
-	/*
-	 * Ensure that we have the correct start address
-	 */
-	start = (res->start & ~data->mask) + data->offset;
-	if (start < res->start)
-		start += data->mask + 1;
-	res->start = start;
-}
-
-static void
-pcmcia_align(void *align_data, struct resource *res,
-	     unsigned long size, unsigned long align)
-{
-	struct pcmcia_align_data *data = align_data;
-	resource_map_t *m;
-
-	pcmcia_common_align(data, res, size, align);
-
-	for (m = data->map->next; m != data->map; m = m->next) {
-		unsigned long start = m->base;
-		unsigned long end = m->base + m->num - 1;
-
-		/*
-		 * If the lower resources are not available, try aligning
-		 * to this entry of the resource database to see if it'll
-		 * fit here.
-		 */
-		if (res->start < start) {
-			res->start = start;
-			pcmcia_common_align(data, res, size, align);
-		}
-
-		/*
-		 * If we're above the area which was passed in, there's
-		 * no point proceeding.
-		 */
-		if (res->start >= res->end)
-			break;
-
-		if ((res->start + size - 1) <= end)
-			break;
-	}
-
-	/*
-	 * If we failed to find something suitable, ensure we fail.
-	 */
-	if (m == data->map)
-		res->start = res->end;
-}
-
-/*
- * Adjust an existing IO region allocation, but making sure that we don't
- * encroach outside the resources which the user supplied.
- */
 int adjust_io_region(struct resource *res, unsigned long r_start,
 		     unsigned long r_end, struct pcmcia_socket *s)
 {
-	resource_map_t *m;
-	int ret = -ENOMEM;
-
-	down(&rsrc_sem);
-	for (m = io_db.next; m != &io_db; m = m->next) {
-		unsigned long start = m->base;
-		unsigned long end = m->base + m->num - 1;
-
-		if (start > r_start || r_end > end)
-			continue;
-
-		ret = adjust_resource(res, r_start, r_end - r_start + 1);
-		break;
-	}
-	up(&rsrc_sem);
-
-	return ret;
+	if (s->resource_ops->adjust_io_region)
+		return s->resource_ops->adjust_io_region(res, r_start, r_end, s);
+	return -ENOMEM;
 }
 
-/*======================================================================
-
-    These find ranges of I/O ports or memory addresses that are not
-    currently allocated by other devices.
-
-    The 'align' field should reflect the number of bits of address
-    that need to be preserved from the initial value of *base.  It
-    should be a power of two, greater than or equal to 'num'.  A value
-    of 0 means that all bits of *base are significant.  *base should
-    also be strictly less than 'align'.
-    
-======================================================================*/
-
 struct resource *find_io_region(unsigned long base, int num,
-		   unsigned long align, char *name, struct pcmcia_socket *s)
+		   unsigned long align, struct pcmcia_socket *s)
 {
-	struct resource *res = make_resource(0, num, IORESOURCE_IO, s->dev.class_id);
-	struct pcmcia_align_data data;
-	unsigned long min = base;
-	int ret;
-
-	if (align == 0)
-		align = 0x10000;
-
-	data.mask = align - 1;
-	data.offset = base & data.mask;
-	data.map = &io_db;
-
-	down(&rsrc_sem);
-#ifdef CONFIG_PCI
-	if (s->cb_dev) {
-		ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num, 1,
-					     min, 0, pcmcia_align, &data);
-	} else
-#endif
-		ret = allocate_resource(&ioport_resource, res, num, min, ~0UL,
-					1, pcmcia_align, &data);
-	up(&rsrc_sem);
-
-	if (ret != 0) {
-		kfree(res);
-		res = NULL;
-	}
-	return res;
+	if (s->resource_ops->find_io)
+		return s->resource_ops->find_io(base, num, align, s);
+	return NULL;
 }
 
 struct resource *find_mem_region(u_long base, u_long num, u_long align,
-				 int low, char *name, struct pcmcia_socket *s)
-{
-	struct resource *res = make_resource(0, num, IORESOURCE_MEM, s->dev.class_id);
-	struct pcmcia_align_data data;
-	unsigned long min, max;
-	int ret, i;
-
-	low = low || !(s->features & SS_CAP_PAGE_REGS);
-
-	data.mask = align - 1;
-	data.offset = base & data.mask;
-	data.map = &mem_db;
-
-	for (i = 0; i < 2; i++) {
-		if (low) {
-			max = 0x100000UL;
-			min = base < max ? base : 0;
-		} else {
-			max = ~0UL;
-			min = 0x100000UL + base;
-		}
-
-		down(&rsrc_sem);
-#ifdef CONFIG_PCI
-		if (s->cb_dev) {
-			ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num,
-						     1, min, 0,
-						     pcmcia_align, &data);
-		} else
-#endif
-			ret = allocate_resource(&iomem_resource, res, num, min,
-						max, 1, pcmcia_align, &data);
-		up(&rsrc_sem);
-		if (ret == 0 || low)
-			break;
-		low = 1;
-	}
-
-	if (ret != 0) {
-		kfree(res);
-		res = NULL;
-	}
-	return res;
-}
-
-/*======================================================================
-
-    This checks to see if an interrupt is available, with support
-    for interrupt sharing.  We don't support reserving interrupts
-    yet.  If the interrupt is available, we allocate it.
-    
-======================================================================*/
-
-#ifdef CONFIG_PCMCIA_PROBE
-
-static irqreturn_t fake_irq(int i, void *d, struct pt_regs *r) { return IRQ_NONE; }
-static inline int check_irq(int irq)
+				 int low, struct pcmcia_socket *s)
 {
-    if (request_irq(irq, fake_irq, 0, "bogus", NULL) != 0)
-	return -1;
-    free_irq(irq, NULL);
-    return 0;
+	if (s->resource_ops->find_mem)
+		return s->resource_ops->find_mem(base, num, align, low, s);
+	return NULL;
 }
 
-int try_irq(u_int Attributes, int irq, int specific)
+void release_resource_db(struct pcmcia_socket *s)
 {
-    irq_info_t *info = &irq_table[irq];
-    int ret = 0;
-
-    down(&rsrc_sem);
-    if (info->Attributes & RES_ALLOCATED) {
-	switch (Attributes & IRQ_TYPE) {
-	case IRQ_TYPE_EXCLUSIVE:
-	    ret = CS_IN_USE;
-	    break;
-	case IRQ_TYPE_TIME:
-	    if ((info->Attributes & RES_IRQ_TYPE)
-		!= RES_IRQ_TYPE_TIME) {
-		ret = CS_IN_USE;
-		break;
-	    }
-	    if (Attributes & IRQ_FIRST_SHARED) {
-		ret = CS_BAD_ATTRIBUTE;
-		break;
-	    }
-	    info->Attributes |= RES_IRQ_TYPE_TIME | RES_ALLOCATED;
-	    info->time_share++;
-	    break;
-	case IRQ_TYPE_DYNAMIC_SHARING:
-	    if ((info->Attributes & RES_IRQ_TYPE)
-		!= RES_IRQ_TYPE_DYNAMIC) {
-		ret = CS_IN_USE;
-		break;
-	    }
-	    if (Attributes & IRQ_FIRST_SHARED) {
-		ret = CS_BAD_ATTRIBUTE;
-		break;
-	    }
-	    info->Attributes |= RES_IRQ_TYPE_DYNAMIC | RES_ALLOCATED;
-	    info->dyn_share++;
-	    break;
-	}
-    } else {
-	if ((info->Attributes & RES_RESERVED) && !specific) {
-	    ret = CS_IN_USE;
-	    goto out;
-	}
-	if (check_irq(irq) != 0) {
-	    ret = CS_IN_USE;
-	    goto out;
-	}
-	switch (Attributes & IRQ_TYPE) {
-	case IRQ_TYPE_EXCLUSIVE:
-	    info->Attributes |= RES_ALLOCATED;
-	    break;
-	case IRQ_TYPE_TIME:
-	    if (!(Attributes & IRQ_FIRST_SHARED)) {
-		ret = CS_BAD_ATTRIBUTE;
-		break;
-	    }
-	    info->Attributes |= RES_IRQ_TYPE_TIME | RES_ALLOCATED;
-	    info->time_share = 1;
-	    break;
-	case IRQ_TYPE_DYNAMIC_SHARING:
-	    if (!(Attributes & IRQ_FIRST_SHARED)) {
-		ret = CS_BAD_ATTRIBUTE;
-		break;
-	    }
-	    info->Attributes |= RES_IRQ_TYPE_DYNAMIC | RES_ALLOCATED;
-	    info->dyn_share = 1;
-	    break;
-	}
-    }
- out:
-    up(&rsrc_sem);
-    return ret;
+	if (s->resource_ops->exit)
+		s->resource_ops->exit(s);
 }
 
-#endif
 
-/*====================================================================*/
-
-#ifdef CONFIG_PCMCIA_PROBE
-
-void undo_irq(u_int Attributes, int irq)
-{
-    irq_info_t *info;
-
-    info = &irq_table[irq];
-    down(&rsrc_sem);
-    switch (Attributes & IRQ_TYPE) {
-    case IRQ_TYPE_EXCLUSIVE:
-	info->Attributes &= RES_RESERVED;
-	break;
-    case IRQ_TYPE_TIME:
-	info->time_share--;
-	if (info->time_share == 0)
-	    info->Attributes &= RES_RESERVED;
-	break;
-    case IRQ_TYPE_DYNAMIC_SHARING:
-	info->dyn_share--;
-	if (info->dyn_share == 0)
-	    info->Attributes &= RES_RESERVED;
-	break;
-    }
-    up(&rsrc_sem);
-}
-
-#endif
-
-/*======================================================================
-
-    The various adjust_* calls form the external interface to the
-    resource database.
-    
-======================================================================*/
-
-static int adjust_memory(adjust_t *adj)
-{
-    u_long base, num;
-    int ret;
-
-    base = adj->resource.memory.Base;
-    num = adj->resource.memory.Size;
-    if ((num == 0) || (base+num-1 < base))
-	return CS_BAD_SIZE;
-
-    ret = CS_SUCCESS;
-
-    down(&rsrc_sem);
-    switch (adj->Action) {
-    case ADD_MANAGED_RESOURCE:
-	ret = add_interval(&mem_db, base, num);
-	break;
-    case REMOVE_MANAGED_RESOURCE:
-	ret = sub_interval(&mem_db, base, num);
-	if (ret == CS_SUCCESS) {
-		struct pcmcia_socket *socket;
-		down_read(&pcmcia_socket_list_rwsem);
-		list_for_each_entry(socket, &pcmcia_socket_list, socket_list)
-			release_cis_mem(socket);
-		up_read(&pcmcia_socket_list_rwsem);
-	}
-	break;
-    default:
-	ret = CS_UNSUPPORTED_FUNCTION;
-    }
-    up(&rsrc_sem);
-    
-    return ret;
-}
-
-/*====================================================================*/
-
-static int adjust_io(adjust_t *adj)
-{
-    int base, num, ret = CS_SUCCESS;
-    
-    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;
-
-    down(&rsrc_sem);
-    switch (adj->Action) {
-    case ADD_MANAGED_RESOURCE:
-	if (add_interval(&io_db, base, num) != 0) {
-	    ret = CS_IN_USE;
-	    break;
-	}
-#ifdef CONFIG_PCMCIA_PROBE
-	if (probe_io)
-	    do_io_probe(base, num);
-#endif
-	break;
-    case REMOVE_MANAGED_RESOURCE:
-	sub_interval(&io_db, base, num);
-	break;
-    default:
-	ret = CS_UNSUPPORTED_FUNCTION;
-	break;
-    }
-    up(&rsrc_sem);
-
-    return ret;
-}
-
-/*====================================================================*/
-
-static int adjust_irq(adjust_t *adj)
-{
-    int ret = CS_SUCCESS;
-#ifdef CONFIG_PCMCIA_PROBE
-    int irq;
-    irq_info_t *info;
-    
-    irq = adj->resource.irq.IRQ;
-    if ((irq < 0) || (irq > 15))
-	return CS_BAD_IRQ;
-    info = &irq_table[irq];
-
-    down(&rsrc_sem);
-    switch (adj->Action) {
-    case ADD_MANAGED_RESOURCE:
-	if (info->Attributes & RES_REMOVED)
-	    info->Attributes &= ~(RES_REMOVED|RES_ALLOCATED);
-	else
-	    if (adj->Attributes & RES_ALLOCATED) {
-		ret = CS_IN_USE;
-		break;
-	    }
-	if (adj->Attributes & RES_RESERVED)
-	    info->Attributes |= RES_RESERVED;
-	else
-	    info->Attributes &= ~RES_RESERVED;
-	break;
-    case REMOVE_MANAGED_RESOURCE:
-	if (info->Attributes & RES_REMOVED) {
-	    ret = 0;
-	    break;
-	}
-	if (info->Attributes & RES_ALLOCATED) {
-	    ret = CS_IN_USE;
-	    break;
-	}
-	info->Attributes |= RES_ALLOCATED|RES_REMOVED;
-	info->Attributes &= ~RES_RESERVED;
-	break;
-    default:
-	ret = CS_UNSUPPORTED_FUNCTION;
-	break;
-    }
-    up(&rsrc_sem);
-#endif
-    return ret;
-}
-
-/*====================================================================*/
-
-int pcmcia_adjust_resource_info(adjust_t *adj)
-{
-    switch (adj->Resource) {
-    case RES_MEMORY_RANGE:
-	return adjust_memory(adj);
-	break;
-    case RES_IO_RANGE:
-	return adjust_io(adj);
-	break;
-    case RES_IRQ:
-	return adjust_irq(adj);
-	break;
-    }
-    return CS_UNSUPPORTED_FUNCTION;
-}
-EXPORT_SYMBOL(pcmcia_adjust_resource_info);
-
-/*====================================================================*/
-
-void release_resource_db(void)
-{
-    resource_map_t *p, *q;
-    
-    for (p = mem_db.next; p != &mem_db; p = q) {
-	q = p->next;
-	kfree(p);
-    }
-    for (p = io_db.next; p != &io_db; p = q) {
-	q = p->next;
-	kfree(p);
-    }
-}
+struct pccard_resource_ops pccard_static_ops = {
+	.validate_mem = NULL,
+	.adjust_io_region = NULL,
+	.find_io = NULL,
+	.find_mem = NULL,
+	.adjust_resource = NULL,
+	.exit = NULL,
+};
+EXPORT_SYMBOL(pccard_static_ops);
diff -Nru a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/pcmcia/rsrc_nonstatic.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,818 @@
+/*
+ * rsrc_nonstatic.c -- Resource management routines for !SS_CAP_STATIC_MAP sockets
+ *
+ * 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
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/ioport.h>
+#include <linux/timer.h>
+#include <linux/pci.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+
+#include <pcmcia/cs_types.h>
+#include <pcmcia/ss.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/bulkmem.h>
+#include <pcmcia/cistpl.h>
+#include "cs_internal.h"
+
+MODULE_AUTHOR("David A. Hinds, Dominik Brodowski");
+MODULE_LICENSE("GPL");
+
+/* Parameters that can be set with 'insmod' */
+
+#define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0444)
+
+INT_MODULE_PARM(probe_mem,	1);		/* memory probe? */
+#ifdef CONFIG_PCMCIA_PROBE
+INT_MODULE_PARM(probe_io,	1);		/* IO port probe? */
+INT_MODULE_PARM(mem_limit,	0x10000);
+#endif
+
+/* for io_db and mem_db */
+struct resource_map {
+	u_long			base, num;
+	struct resource_map	*next;
+};
+
+struct socket_data {
+	struct resource_map		mem_db;
+	struct resource_map		io_db;
+	unsigned int			rsrc_mem_probe;
+};
+
+static DECLARE_MUTEX(rsrc_sem);
+#define MEM_PROBE_LOW	(1 << 0)
+#define MEM_PROBE_HIGH	(1 << 1)
+
+
+/*======================================================================
+
+    Linux resource management extensions
+
+======================================================================*/
+
+static struct resource *
+make_resource(unsigned long b, unsigned long n, int flags, char *name)
+{
+	struct resource *res = kmalloc(sizeof(*res), GFP_KERNEL);
+
+	if (res) {
+		memset(res, 0, sizeof(*res));
+		res->name = name;
+		res->start = b;
+		res->end = b + n - 1;
+		res->flags = flags;
+	}
+	return res;
+}
+
+static struct resource *
+claim_region(struct pcmcia_socket *s, unsigned long base, unsigned long size,
+	     int type, char *name)
+{
+	struct resource *res, *parent;
+
+	parent = type & IORESOURCE_MEM ? &iomem_resource : &ioport_resource;
+	res = make_resource(base, size, type | IORESOURCE_BUSY, name);
+
+	if (res) {
+#ifdef CONFIG_PCI
+		if (s && s->cb_dev)
+			parent = pci_find_parent_resource(s->cb_dev, res);
+#endif
+		if (!parent || request_resource(parent, res)) {
+			kfree(res);
+			res = NULL;
+		}
+	}
+	return res;
+}
+
+static void free_region(struct resource *res)
+{
+	if (res) {
+		release_resource(res);
+		kfree(res);
+	}
+}
+
+/*======================================================================
+
+    These manage the internal databases of available resources.
+
+======================================================================*/
+
+static int add_interval(struct resource_map *map, u_long base, u_long num)
+{
+    struct resource_map *p, *q;
+
+    for (p = map; ; p = p->next) {
+	if ((p != map) && (p->base+p->num-1 >= base))
+	    return -1;
+	if ((p->next == map) || (p->next->base > base+num-1))
+	    break;
+    }
+    q = kmalloc(sizeof(struct resource_map), GFP_KERNEL);
+    if (!q) return CS_OUT_OF_RESOURCE;
+    q->base = base; q->num = num;
+    q->next = p->next; p->next = q;
+    return CS_SUCCESS;
+}
+
+/*====================================================================*/
+
+static int sub_interval(struct resource_map *map, u_long base, u_long num)
+{
+    struct resource_map *p, *q;
+
+    for (p = map; ; p = q) {
+	q = p->next;
+	if (q == map)
+	    break;
+	if ((q->base+q->num > base) && (base+num > q->base)) {
+	    if (q->base >= base) {
+		if (q->base+q->num <= base+num) {
+		    /* Delete whole block */
+		    p->next = q->next;
+		    kfree(q);
+		    /* don't advance the pointer yet */
+		    q = p;
+		} else {
+		    /* Cut off bit from the front */
+		    q->num = q->base + q->num - base - num;
+		    q->base = base + num;
+		}
+	    } else if (q->base+q->num <= base+num) {
+		/* Cut off bit from the end */
+		q->num = base - q->base;
+	    } else {
+		/* Split the block into two pieces */
+		p = kmalloc(sizeof(struct resource_map), GFP_KERNEL);
+		if (!p) return CS_OUT_OF_RESOURCE;
+		p->base = base+num;
+		p->num = q->base+q->num - p->base;
+		q->num = base - q->base;
+		p->next = q->next ; q->next = p;
+	    }
+	}
+    }
+    return CS_SUCCESS;
+}
+
+/*======================================================================
+
+    These routines examine a region of IO or memory addresses to
+    determine what ranges might be genuinely available.
+
+======================================================================*/
+
+#ifdef CONFIG_PCMCIA_PROBE
+static void do_io_probe(struct pcmcia_socket *s, kio_addr_t base, kio_addr_t num)
+{
+    struct resource *res;
+    struct socket_data *s_data = s->resource_data;
+    kio_addr_t i, j, bad;
+    int any;
+    u_char *b, hole, most;
+
+    printk(KERN_INFO "cs: IO port probe %#lx-%#lx:",
+	   base, base+num-1);
+
+    /* First, what does a floating port look like? */
+    b = kmalloc(256, GFP_KERNEL);
+    if (!b) {
+            printk(KERN_ERR "do_io_probe: unable to kmalloc 256 bytes");
+            return;
+    }
+    memset(b, 0, 256);
+    for (i = base, most = 0; i < base+num; i += 8) {
+	res = claim_region(NULL, i, 8, IORESOURCE_IO, "PCMCIA IO probe");
+	if (!res)
+	    continue;
+	hole = inb(i);
+	for (j = 1; j < 8; j++)
+	    if (inb(i+j) != hole) break;
+	free_region(res);
+	if ((j == 8) && (++b[hole] > b[most]))
+	    most = hole;
+	if (b[most] == 127) break;
+    }
+    kfree(b);
+
+    bad = any = 0;
+    for (i = base; i < base+num; i += 8) {
+	res = claim_region(NULL, i, 8, IORESOURCE_IO, "PCMCIA IO probe");
+	if (!res)
+	    continue;
+	for (j = 0; j < 8; j++)
+	    if (inb(i+j) != most) break;
+	free_region(res);
+	if (j < 8) {
+	    if (!any)
+		printk(" excluding");
+	    if (!bad)
+		bad = any = i;
+	} else {
+	    if (bad) {
+		sub_interval(&s_data->io_db, bad, i-bad);
+		printk(" %#lx-%#lx", bad, i-1);
+		bad = 0;
+	    }
+	}
+    }
+    if (bad) {
+	if ((num > 16) && (bad == base) && (i == base+num)) {
+	    printk(" nothing: probe failed.\n");
+	    return;
+	} else {
+	    sub_interval(&s_data->io_db, bad, i-bad);
+	    printk(" %#lx-%#lx", bad, i-1);
+	}
+    }
+
+    printk(any ? "\n" : " clean.\n");
+}
+#endif
+
+/*======================================================================
+
+    This is tricky... when we set up CIS memory, we try to validate
+    the memory window space allocations.
+
+======================================================================*/
+
+/* Validation function for cards with a valid CIS */
+static int readable(struct pcmcia_socket *s, struct resource *res, cisinfo_t *info)
+{
+	int ret = -1;
+
+	s->cis_mem.res = res;
+	s->cis_virt = ioremap(res->start, s->map_size);
+	if (s->cis_virt) {
+		ret = pccard_validate_cis(s, BIND_FN_ALL, info);
+		/* invalidate mapping and CIS cache */
+		iounmap(s->cis_virt);
+		s->cis_virt = NULL;
+		destroy_cis_cache(s);
+	}
+	s->cis_mem.res = NULL;
+	if ((ret != 0) || (info->Chains == 0))
+		return 0;
+	return 1;
+}
+
+/* Validation function for simple memory cards */
+static int checksum(struct pcmcia_socket *s, struct resource *res)
+{
+	pccard_mem_map map;
+	int i, a = 0, b = -1, d;
+	void __iomem *virt;
+
+	virt = ioremap(res->start, s->map_size);
+	if (virt) {
+		map.map = 0;
+		map.flags = MAP_ACTIVE;
+		map.speed = 0;
+		map.res = res;
+		map.card_start = 0;
+		s->ops->set_mem_map(s, &map);
+
+		/* Don't bother checking every word... */
+		for (i = 0; i < s->map_size; i += 44) {
+			d = readl(virt+i);
+			a += d;
+			b &= d;
+		}
+
+		map.flags = 0;
+		s->ops->set_mem_map(s, &map);
+
+		iounmap(virt);
+	}
+
+	return (b == -1) ? -1 : (a>>1);
+}
+
+static int
+cis_readable(struct pcmcia_socket *s, unsigned long base, unsigned long size)
+{
+	struct resource *res1, *res2;
+	cisinfo_t info1, info2;
+	int ret = 0;
+
+	res1 = claim_region(s, base, size/2, IORESOURCE_MEM, "cs memory probe");
+	res2 = claim_region(s, base + size/2, size/2, IORESOURCE_MEM, "cs memory probe");
+
+	if (res1 && res2) {
+		ret = readable(s, res1, &info1);
+		ret += readable(s, res2, &info2);
+	}
+
+	free_region(res2);
+	free_region(res1);
+
+	return (ret == 2) && (info1.Chains == info2.Chains);
+}
+
+static int
+checksum_match(struct pcmcia_socket *s, unsigned long base, unsigned long size)
+{
+	struct resource *res1, *res2;
+	int a = -1, b = -1;
+
+	res1 = claim_region(s, base, size/2, IORESOURCE_MEM, "cs memory probe");
+	res2 = claim_region(s, base + size/2, size/2, IORESOURCE_MEM, "cs memory probe");
+
+	if (res1 && res2) {
+		a = checksum(s, res1);
+		b = checksum(s, res2);
+	}
+
+	free_region(res2);
+	free_region(res1);
+
+	return (a == b) && (a >= 0);
+}
+
+/*======================================================================
+
+    The memory probe.  If the memory list includes a 64K-aligned block
+    below 1MB, we probe in 64K chunks, and as soon as we accumulate at
+    least mem_limit free space, we quit.
+
+======================================================================*/
+
+static int do_mem_probe(u_long base, u_long num, struct pcmcia_socket *s)
+{
+    struct socket_data *s_data = s->resource_data;
+    u_long i, j, bad, fail, step;
+
+    printk(KERN_INFO "cs: memory probe 0x%06lx-0x%06lx:",
+	   base, base+num-1);
+    bad = fail = 0;
+    step = (num < 0x20000) ? 0x2000 : ((num>>4) & ~0x1fff);
+    /* cis_readable wants to map 2x map_size */
+    if (step < 2 * s->map_size)
+	step = 2 * s->map_size;
+    for (i = j = base; i < base+num; i = j + step) {
+	if (!fail) {
+	    for (j = i; j < base+num; j += step) {
+		if (cis_readable(s, j, step))
+		    break;
+	    }
+	    fail = ((i == base) && (j == base+num));
+	}
+	if (fail) {
+	    for (j = i; j < base+num; j += 2*step)
+		if (checksum_match(s, j, step) &&
+		    checksum_match(s, j + step, step))
+		    break;
+	}
+	if (i != j) {
+	    if (!bad) printk(" excluding");
+	    printk(" %#05lx-%#05lx", i, j-1);
+	    sub_interval(&s_data->mem_db, i, j-i);
+	    bad += j-i;
+	}
+    }
+    printk(bad ? "\n" : " clean.\n");
+    return (num - bad);
+}
+
+#ifdef CONFIG_PCMCIA_PROBE
+
+static u_long inv_probe(struct resource_map *m, struct pcmcia_socket *s)
+{
+    struct socket_data *s_data = s->resource_data;
+    u_long ok;
+    if (m == &s_data->mem_db)
+	return 0;
+    ok = inv_probe(m->next, s);
+    if (ok) {
+	if (m->base >= 0x100000)
+	    sub_interval(&s_data->mem_db, m->base, m->num);
+	return ok;
+    }
+    if (m->base < 0x100000)
+	return 0;
+    return do_mem_probe(m->base, m->num, s);
+}
+
+static void validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
+{
+    struct resource_map *m, mm;
+    static u_char order[] = { 0xd0, 0xe0, 0xc0, 0xf0 };
+    u_long b, i, ok = 0;
+    struct socket_data *s_data = s->resource_data;
+
+    /* We do up to four passes through the list */
+    if (probe_mask & MEM_PROBE_HIGH) {
+	if (inv_probe(s_data->mem_db.next, s) > 0)
+	    return;
+	printk(KERN_NOTICE "cs: warning: no high memory space "
+	       "available!\n");
+    }
+    if ((probe_mask & MEM_PROBE_LOW) == 0)
+	return;
+    for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) {
+	mm = *m;
+	/* Only probe < 1 MB */
+	if (mm.base >= 0x100000) continue;
+	if ((mm.base | mm.num) & 0xffff) {
+	    ok += do_mem_probe(mm.base, mm.num, s);
+	    continue;
+	}
+	/* Special probe for 64K-aligned block */
+	for (i = 0; i < 4; i++) {
+	    b = order[i] << 12;
+	    if ((b >= mm.base) && (b+0x10000 <= mm.base+mm.num)) {
+		if (ok >= mem_limit)
+		    sub_interval(&s_data->mem_db, b, 0x10000);
+		else
+		    ok += do_mem_probe(b, 0x10000, s);
+	    }
+	}
+    }
+}
+
+#else /* CONFIG_PCMCIA_PROBE */
+
+static void validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
+{
+	struct resource_map *m, mm;
+	struct socket_data *s_data = s->resource_data;
+
+	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;
+	}
+}
+
+#endif /* CONFIG_PCMCIA_PROBE */
+
+
+/*
+ * Locking note: this is the only place where we take
+ * both rsrc_sem and skt_sem.
+ */
+static void pcmcia_nonstatic_validate_mem(struct pcmcia_socket *s)
+{
+	struct socket_data *s_data = s->resource_data;
+	if (probe_mem) {
+		unsigned int probe_mask;
+
+		down(&rsrc_sem);
+
+		probe_mask = MEM_PROBE_LOW;
+		if (s->features & SS_CAP_PAGE_REGS)
+			probe_mask = MEM_PROBE_HIGH;
+
+		if (probe_mask & ~s_data->rsrc_mem_probe) {
+			s_data->rsrc_mem_probe |= probe_mask;
+
+			down(&s->skt_sem);
+
+			if (s->state & SOCKET_PRESENT)
+				validate_mem(s, probe_mask);
+
+			up(&s->skt_sem);
+		}
+
+		up(&rsrc_sem);
+	}
+}
+
+struct pcmcia_align_data {
+	unsigned long	mask;
+	unsigned long	offset;
+	struct resource_map	*map;
+};
+
+static void
+pcmcia_common_align(void *align_data, struct resource *res,
+		    unsigned long size, unsigned long align)
+{
+	struct pcmcia_align_data *data = align_data;
+	unsigned long start;
+	/*
+	 * Ensure that we have the correct start address
+	 */
+	start = (res->start & ~data->mask) + data->offset;
+	if (start < res->start)
+		start += data->mask + 1;
+	res->start = start;
+}
+
+static void
+pcmcia_align(void *align_data, struct resource *res,
+	     unsigned long size, unsigned long align)
+{
+	struct pcmcia_align_data *data = align_data;
+	struct resource_map *m;
+
+	pcmcia_common_align(data, res, size, align);
+
+	for (m = data->map->next; m != data->map; m = m->next) {
+		unsigned long start = m->base;
+		unsigned long end = m->base + m->num - 1;
+
+		/*
+		 * If the lower resources are not available, try aligning
+		 * to this entry of the resource database to see if it'll
+		 * fit here.
+		 */
+		if (res->start < start) {
+			res->start = start;
+			pcmcia_common_align(data, res, size, align);
+		}
+
+		/*
+		 * If we're above the area which was passed in, there's
+		 * no point proceeding.
+		 */
+		if (res->start >= res->end)
+			break;
+
+		if ((res->start + size - 1) <= end)
+			break;
+	}
+
+	/*
+	 * If we failed to find something suitable, ensure we fail.
+	 */
+	if (m == data->map)
+		res->start = res->end;
+}
+
+/*
+ * Adjust an existing IO region allocation, but making sure that we don't
+ * encroach outside the resources which the user supplied.
+ */
+static int nonstatic_adjust_io_region(struct resource *res, unsigned long r_start,
+				      unsigned long r_end, struct pcmcia_socket *s)
+{
+	struct resource_map *m;
+	struct socket_data *s_data = s->resource_data;
+	int ret = -ENOMEM;
+
+	down(&rsrc_sem);
+	for (m = s_data->io_db.next; m != &s_data->io_db; m = m->next) {
+		unsigned long start = m->base;
+		unsigned long end = m->base + m->num - 1;
+
+		if (start > r_start || r_end > end)
+			continue;
+
+		ret = adjust_resource(res, r_start, r_end - r_start + 1);
+		break;
+	}
+	up(&rsrc_sem);
+
+	return ret;
+}
+
+/*======================================================================
+
+    These find ranges of I/O ports or memory addresses that are not
+    currently allocated by other devices.
+
+    The 'align' field should reflect the number of bits of address
+    that need to be preserved from the initial value of *base.  It
+    should be a power of two, greater than or equal to 'num'.  A value
+    of 0 means that all bits of *base are significant.  *base should
+    also be strictly less than 'align'.
+
+======================================================================*/
+
+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);
+	struct socket_data *s_data = s->resource_data;
+	struct pcmcia_align_data data;
+	unsigned long min = base;
+	int ret;
+
+	if (align == 0)
+		align = 0x10000;
+
+	data.mask = align - 1;
+	data.offset = base & data.mask;
+	data.map = &s_data->io_db;
+
+	down(&rsrc_sem);
+#ifdef CONFIG_PCI
+	if (s->cb_dev) {
+		ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num, 1,
+					     min, 0, pcmcia_align, &data);
+	} else
+#endif
+		ret = allocate_resource(&ioport_resource, res, num, min, ~0UL,
+					1, pcmcia_align, &data);
+	up(&rsrc_sem);
+
+	if (ret != 0) {
+		kfree(res);
+		res = NULL;
+	}
+	return res;
+}
+
+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;
+	struct pcmcia_align_data data;
+	unsigned long min, max;
+	int ret, i;
+
+	low = low || !(s->features & SS_CAP_PAGE_REGS);
+
+	data.mask = align - 1;
+	data.offset = base & data.mask;
+	data.map = &s_data->mem_db;
+
+	for (i = 0; i < 2; i++) {
+		if (low) {
+			max = 0x100000UL;
+			min = base < max ? base : 0;
+		} else {
+			max = ~0UL;
+			min = 0x100000UL + base;
+		}
+
+		down(&rsrc_sem);
+#ifdef CONFIG_PCI
+		if (s->cb_dev) {
+			ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num,
+						     1, min, 0,
+						     pcmcia_align, &data);
+		} else
+#endif
+			ret = allocate_resource(&iomem_resource, res, num, min,
+						max, 1, pcmcia_align, &data);
+		up(&rsrc_sem);
+		if (ret == 0 || low)
+			break;
+		low = 1;
+	}
+
+	if (ret != 0) {
+		kfree(res);
+		res = NULL;
+	}
+	return res;
+}
+
+
+static int adjust_memory(struct pcmcia_socket *s, adjust_t *adj)
+{
+	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;
+
+	ret = CS_SUCCESS;
+
+	down(&rsrc_sem);
+	switch (adj->Action) {
+	case ADD_MANAGED_RESOURCE:
+		ret = add_interval(&data->mem_db, base, num);
+		break;
+	case REMOVE_MANAGED_RESOURCE:
+		ret = sub_interval(&data->mem_db, base, num);
+		if (ret == CS_SUCCESS) {
+			struct pcmcia_socket *socket;
+			down_read(&pcmcia_socket_list_rwsem);
+			list_for_each_entry(socket, &pcmcia_socket_list, socket_list)
+				release_cis_mem(socket);
+			up_read(&pcmcia_socket_list_rwsem);
+		}
+		break;
+	default:
+		ret = CS_UNSUPPORTED_FUNCTION;
+	}
+	up(&rsrc_sem);
+
+	return ret;
+}
+
+
+static int adjust_io(struct pcmcia_socket *s, adjust_t *adj)
+{
+	struct socket_data *data = s->resource_data;
+	kio_addr_t base, num;
+	int ret = CS_SUCCESS;
+
+	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;
+
+	down(&rsrc_sem);
+	switch (adj->Action) {
+	case ADD_MANAGED_RESOURCE:
+		if (add_interval(&data->io_db, base, num) != 0) {
+			ret = CS_IN_USE;
+			break;
+		}
+#ifdef CONFIG_PCMCIA_PROBE
+		if (probe_io)
+			do_io_probe(s, base, num);
+#endif
+		break;
+	case REMOVE_MANAGED_RESOURCE:
+		sub_interval(&data->io_db, base, num);
+		break;
+	default:
+		ret = CS_UNSUPPORTED_FUNCTION;
+		break;
+	}
+	up(&rsrc_sem);
+
+	return ret;
+}
+
+
+static int nonstatic_adjust_resource_info(struct pcmcia_socket *s, adjust_t *adj)
+{
+	switch (adj->Resource) {
+	case RES_MEMORY_RANGE:
+		return adjust_memory(s, adj);
+	case RES_IO_RANGE:
+		return adjust_io(s, adj);
+	}
+	return CS_UNSUPPORTED_FUNCTION;
+}
+
+static int nonstatic_init(struct pcmcia_socket *s)
+{
+	struct socket_data *data;
+
+	data = kmalloc(sizeof(struct socket_data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	data->mem_db.next = &data->mem_db;
+	data->io_db.next = &data->io_db;
+
+	s->resource_data = (void *) data;
+
+	return 0;
+}
+
+static void nonstatic_release_resource_db(struct pcmcia_socket *s)
+{
+	struct socket_data *data = s->resource_data;
+	struct resource_map *p, *q;
+
+	down(&rsrc_sem);
+	for (p = data->mem_db.next; p != &data->mem_db; p = q) {
+		q = p->next;
+		kfree(p);
+	}
+	for (p = data->io_db.next; p != &data->io_db; p = q) {
+		q = p->next;
+		kfree(p);
+	}
+	up(&rsrc_sem);
+}
+
+
+struct pccard_resource_ops pccard_nonstatic_ops = {
+	.validate_mem = pcmcia_nonstatic_validate_mem,
+	.adjust_io_region = nonstatic_adjust_io_region,
+	.find_io = nonstatic_find_io_region,
+	.find_mem = nonstatic_find_mem_region,
+	.adjust_resource = nonstatic_adjust_resource_info,
+	.init = nonstatic_init,
+	.exit = nonstatic_release_resource_db,
+};
+EXPORT_SYMBOL(pccard_nonstatic_ops);
diff -Nru a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c
--- a/drivers/pcmcia/soc_common.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/pcmcia/soc_common.c	2005-03-01 23:38:53 -08:00
@@ -208,7 +208,7 @@
 	return ret;
 }
 
-static spinlock_t status_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(status_lock);
 
 static void soc_common_check_status(struct soc_pcmcia_socket *skt)
 {
@@ -397,8 +397,8 @@
 		map->stop = PAGE_SIZE-1;
 
 	map->stop -= map->start;
-	map->stop += (unsigned long)skt->virt_io;
-	map->start = (unsigned long)skt->virt_io;
+	map->stop += skt->socket.io_offset;
+	map->start = skt->socket.io_offset;
 
 	return 0;
 }
@@ -758,6 +758,7 @@
 			goto out_err_6;
 
 		skt->socket.features = SS_CAP_STATIC_MAP|SS_CAP_PCCARD;
+		skt->socket.resource_ops = &pccard_static_ops;
 		skt->socket.irq_mask = 0;
 		skt->socket.map_size = PAGE_SIZE;
 		skt->socket.pci_irq = skt->irq;
diff -Nru a/drivers/pcmcia/soc_common.h b/drivers/pcmcia/soc_common.h
--- a/drivers/pcmcia/soc_common.h	2005-03-01 23:39:08 -08:00
+++ b/drivers/pcmcia/soc_common.h	2005-03-01 23:39:08 -08:00
@@ -53,7 +53,7 @@
 	struct resource		res_io;
 	struct resource		res_mem;
 	struct resource		res_attr;
-	void			*virt_io;
+	void __iomem		*virt_io;
 
 	unsigned int		irq_state;
 
diff -Nru a/drivers/pcmcia/socket_sysfs.c b/drivers/pcmcia/socket_sysfs.c
--- a/drivers/pcmcia/socket_sysfs.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/pcmcia/socket_sysfs.c	2005-03-01 23:38:53 -08:00
@@ -25,7 +25,6 @@
 #include <linux/pm.h>
 #include <linux/pci.h>
 #include <linux/device.h>
-#include <linux/suspend.h>
 #include <asm/system.h>
 #include <asm/irq.h>
 
@@ -122,6 +121,33 @@
 static CLASS_DEVICE_ATTR(card_eject, 0200, NULL, pccard_store_eject);
 
 
+static ssize_t pccard_show_irq_mask(struct class_device *dev, char *buf)
+{
+	struct pcmcia_socket *s = to_socket(dev);
+	return sprintf(buf, "0x%04x\n", s->irq_mask);
+}
+
+static ssize_t pccard_store_irq_mask(struct class_device *dev, const char *buf, size_t count)
+{
+	ssize_t ret;
+	struct pcmcia_socket *s = to_socket(dev);
+	u32 mask;
+
+	if (!count)
+		return -EINVAL;
+
+	ret = sscanf (buf, "0x%x\n", &mask);
+
+	if (ret == 1) {
+		s->irq_mask &= mask;
+		ret = 0;
+	}
+
+	return ret ? ret : count;
+}
+static CLASS_DEVICE_ATTR(card_irq_mask, 0600, pccard_show_irq_mask, pccard_store_irq_mask);
+
+
 static struct class_device_attribute *pccard_socket_attributes[] = {
 	&class_device_attr_card_type,
 	&class_device_attr_card_voltage,
@@ -129,6 +155,7 @@
 	&class_device_attr_card_vcc,
 	&class_device_attr_card_insert,
 	&class_device_attr_card_eject,
+	&class_device_attr_card_irq_mask,
 	NULL,
 };
 
diff -Nru a/drivers/pcmcia/tcic.c b/drivers/pcmcia/tcic.c
--- a/drivers/pcmcia/tcic.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/pcmcia/tcic.c	2005-03-01 23:38:58 -08:00
@@ -80,7 +80,7 @@
 /* Parameters that can be set with 'insmod' */
 
 /* The base port address of the TCIC-2 chip */
-static int tcic_base = TCIC_BASE;
+static unsigned long tcic_base = TCIC_BASE;
 
 /* Specify a socket number to ignore */
 static int ignore = -1;
@@ -105,7 +105,7 @@
 /* CCLK external clock time, in nanoseconds.  70 ns = 14.31818 MHz */
 static int cycle_time = 70;
 
-module_param(tcic_base, int, 0444);
+module_param(tcic_base, ulong, 0444);
 module_param(ignore, int, 0444);
 module_param(do_scan, int, 0444);
 module_param(irq_mask, int, 0444);
@@ -144,26 +144,26 @@
 static u_char tcic_getb(u_char reg)
 {
     u_char val = inb(tcic_base+reg);
-    printk(KERN_DEBUG "tcic_getb(%#x) = %#x\n", tcic_base+reg, val);
+    printk(KERN_DEBUG "tcic_getb(%#lx) = %#x\n", tcic_base+reg, val);
     return val;
 }
 
 static u_short tcic_getw(u_char reg)
 {
     u_short val = inw(tcic_base+reg);
-    printk(KERN_DEBUG "tcic_getw(%#x) = %#x\n", tcic_base+reg, val);
+    printk(KERN_DEBUG "tcic_getw(%#lx) = %#x\n", tcic_base+reg, val);
     return val;
 }
 
 static void tcic_setb(u_char reg, u_char data)
 {
-    printk(KERN_DEBUG "tcic_setb(%#x, %#x)\n", tcic_base+reg, data);
+    printk(KERN_DEBUG "tcic_setb(%#lx, %#x)\n", tcic_base+reg, data);
     outb(data, tcic_base+reg);
 }
 
 static void tcic_setw(u_char reg, u_short data)
 {
-    printk(KERN_DEBUG "tcic_setw(%#x, %#x)\n", tcic_base+reg, data);
+    printk(KERN_DEBUG "tcic_setw(%#lx, %#x)\n", tcic_base+reg, data);
     outw(data, tcic_base+reg);
 }
 #else
@@ -344,10 +344,14 @@
 
     if ((sstat & TCIC_SSTAT_CD) && (pwr & TCIC_PWR_VCC(s)) &&
 	(scf1 & TCIC_SCF1_IOSTS) && (ioctl & TCIC_ICTL_ENA) &&
-	(check_region(base, num) != 0) && ((base & 0xfeef) != 0x02e8))
-	return 1;
-    else
-	return 0;
+	((base & 0xfeef) != 0x02e8)) {
+	struct resource *res = request_region(base, num, "tcic-2");
+	if (!res) /* region is busy */
+	    return 1;
+	release_region(base, num);
+    }
+
+    return 0;
 }
 
 /*======================================================================
@@ -531,8 +535,9 @@
 
     for (i = 0; i < sockets; i++) {
 	    socket_table[i].socket.ops = &tcic_operations;
+	    socket_table[i].socket.resource_ops = &pccard_nonstatic_ops;
 	    socket_table[i].socket.dev.dev = &tcic_device.dev;
-	    ret = pcmcia_register_socket(&socket_table[i].socket);	    
+	    ret = pcmcia_register_socket(&socket_table[i].socket);
 	    if (ret && i)
 		    pcmcia_unregister_socket(&socket_table[0].socket);
     }
@@ -791,7 +796,7 @@
     u_short base, len, ioctl;
     
     debug(1, "SetIOMap(%d, %d, %#2.2x, %d ns, "
-	  "%#4.4x-%#4.4x)\n", psock, io->map, io->flags,
+	  "%#lx-%#lx)\n", psock, io->map, io->flags,
 	  io->speed, io->start, io->stop);
     if ((io->map > 1) || (io->start > 0xffff) || (io->stop > 0xffff) ||
 	(io->stop < io->start)) return -EINVAL;
@@ -828,7 +833,7 @@
     u_long base, len, mmap;
 
     debug(1, "SetMemMap(%d, %d, %#2.2x, %d ns, "
-	  "%#5.5lx-%#5.5lx, %#5.5x)\n", psock, mem->map, mem->flags,
+	  "%#lx-%#lx, %#x)\n", psock, mem->map, mem->flags,
 	  mem->speed, mem->res->start, mem->res->end, mem->card_start);
     if ((mem->map > 3) || (mem->card_start > 0x3ffffff) ||
 	(mem->res->start > 0xffffff) || (mem->res->end > 0xffffff) ||
diff -Nru a/drivers/pcmcia/ti113x.h b/drivers/pcmcia/ti113x.h
--- a/drivers/pcmcia/ti113x.h	2005-03-01 23:38:55 -08:00
+++ b/drivers/pcmcia/ti113x.h	2005-03-01 23:38:55 -08:00
@@ -592,15 +592,20 @@
 
 static int ti12xx_override(struct yenta_socket *socket)
 {
-	u32 val;
+	u32 val, val_orig;
 
 	/* make sure that memory burst is active */
-	val = config_readl(socket, TI113X_SYSTEM_CONTROL);
+	val_orig = val = config_readl(socket, TI113X_SYSTEM_CONTROL);
+	if (disable_clkrun && PCI_FUNC(socket->dev->devfn) == 0) {
+		printk(KERN_INFO "Yenta: Disabling CLKRUN feature\n");
+		val |= TI113X_SCR_KEEPCLK;
+	}
 	if (!(val & TI122X_SCR_MRBURSTUP)) {
 		printk(KERN_INFO "Yenta: Enabling burst memory read transactions\n");
 		val |= TI122X_SCR_MRBURSTUP;
-		config_writel(socket, TI113X_SYSTEM_CONTROL, val);
 	}
+	if (val_orig != val)
+		config_writel(socket, TI113X_SYSTEM_CONTROL, val);
 
 	/*
 	 * for EnE bridges only: clear testbit TLTEnable. this makes the
diff -Nru a/drivers/pcmcia/vrc4171_card.c b/drivers/pcmcia/vrc4171_card.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/pcmcia/vrc4171_card.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,744 @@
+/*
+ * vrc4171_card.c, NEC VRC4171 Card Controller driver for Socket Services.
+ *
+ * Copyright (C) 2003  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/init.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+
+#include <asm/io.h>
+#include <asm/vr41xx/vrc4171.h>
+
+#include <pcmcia/ss.h>
+
+#include "i82365.h"
+
+MODULE_DESCRIPTION("NEC VRC4171 Card Controllers driver for Socket Services");
+MODULE_AUTHOR("Yoichi Yuasa <yuasa@hh.iij4u.or.jp>");
+MODULE_LICENSE("GPL");
+
+#define CARD_MAX_SLOTS		2
+#define CARD_SLOTA		0
+#define CARD_SLOTB		1
+#define CARD_SLOTB_OFFSET	0x40
+
+#define CARD_MEM_START		0x10000000
+#define CARD_MEM_END		0x13ffffff
+#define CARD_MAX_MEM_OFFSET	0x3ffffff
+#define CARD_MAX_MEM_SPEED	1000
+
+#define CARD_CONTROLLER_INDEX	0x03e0
+#define CARD_CONTROLLER_DATA	0x03e1
+#define CARD_CONTROLLER_SIZE	2
+ /* Power register */
+  #define VPP_GET_VCC		0x01
+  #define POWER_ENABLE		0x10
+ #define CARD_VOLTAGE_SENSE	0x1f
+  #define VCC_3VORXV_CAPABLE	0x00
+  #define VCC_XV_ONLY		0x01
+  #define VCC_3V_CAPABLE	0x02
+  #define VCC_5V_ONLY		0x03
+ #define CARD_VOLTAGE_SELECT	0x2f
+  #define VCC_3V		0x01
+  #define VCC_5V		0x00
+  #define VCC_XV		0x02
+  #define VCC_STATUS_3V		0x02
+  #define VCC_STATUS_5V		0x01
+  #define VCC_STATUS_XV		0x03
+ #define GLOBAL_CONTROL		0x1e
+  #define EXWRBK		0x04
+  #define IRQPM_EN		0x08
+  #define CLRPMIRQ		0x10
+
+#define IO_MAX_MAPS	2
+#define MEM_MAX_MAPS	5
+
+enum {
+	SLOT_PROBE = 0,
+	SLOT_NOPROBE_IO,
+	SLOT_NOPROBE_MEM,
+	SLOT_NOPROBE_ALL
+};
+
+typedef struct vrc4171_socket {
+	int noprobe;
+	struct pcmcia_socket pcmcia_socket;
+	char name[24];
+	int csc_irq;
+	int io_irq;
+} vrc4171_socket_t;
+
+static vrc4171_socket_t vrc4171_sockets[CARD_MAX_SLOTS];
+static int vrc4171_slotb = SLOTB_IS_NONE;
+static unsigned int vrc4171_irq;
+static uint16_t vrc4171_irq_mask = 0xdeb8;
+
+static inline uint8_t exca_read_byte(int slot, uint8_t index)
+{
+	if (slot == CARD_SLOTB)
+		index += CARD_SLOTB_OFFSET;
+
+	outb(index, CARD_CONTROLLER_INDEX);
+	return inb(CARD_CONTROLLER_DATA);
+}
+
+static inline uint16_t exca_read_word(int slot, uint8_t index)
+{
+	uint16_t data;
+
+	if (slot == CARD_SLOTB)
+		index += CARD_SLOTB_OFFSET;
+
+	outb(index++, CARD_CONTROLLER_INDEX);
+	data = inb(CARD_CONTROLLER_DATA);
+
+	outb(index, CARD_CONTROLLER_INDEX);
+	data |= ((uint16_t)inb(CARD_CONTROLLER_DATA)) << 8;
+
+	return data;
+}
+
+static inline uint8_t exca_write_byte(int slot, uint8_t index, uint8_t data)
+{
+	if (slot == CARD_SLOTB)
+		index += CARD_SLOTB_OFFSET;
+
+	outb(index, CARD_CONTROLLER_INDEX);
+	outb(data, CARD_CONTROLLER_DATA);
+
+	return data;
+}
+
+static inline uint16_t exca_write_word(int slot, uint8_t index, uint16_t data)
+{
+	if (slot == CARD_SLOTB)
+		index += CARD_SLOTB_OFFSET;
+
+	outb(index++, CARD_CONTROLLER_INDEX);
+	outb(data, CARD_CONTROLLER_DATA);
+
+	outb(index, CARD_CONTROLLER_INDEX);
+	outb((uint8_t)(data >> 8), CARD_CONTROLLER_DATA);
+
+	return data;
+}
+
+static inline int search_nonuse_irq(void)
+{
+	int i;
+
+	for (i = 0; i < 16; i++) {
+		if (vrc4171_irq_mask & (1 << i)) {
+			vrc4171_irq_mask &= ~(1 << i);
+			return i;
+		}
+	}
+
+	return -1;
+}
+
+static int pccard_init(struct pcmcia_socket *sock)
+{
+	vrc4171_socket_t *socket;
+	unsigned int slot;
+
+	sock->features |= SS_CAP_PCCARD | SS_CAP_PAGE_REGS;
+	sock->irq_mask = 0;
+	sock->map_size = 0x1000;
+	sock->pci_irq = vrc4171_irq;
+
+	slot = sock->sock;
+	socket = &vrc4171_sockets[slot];
+	socket->csc_irq = search_nonuse_irq();
+	socket->io_irq = search_nonuse_irq();
+
+	return 0;
+}
+
+static int pccard_suspend(struct pcmcia_socket *sock)
+{
+	return -EINVAL;
+}
+
+static int pccard_get_status(struct pcmcia_socket *sock, u_int *value)
+{
+	unsigned int slot;
+	uint8_t status, sense;
+	u_int val = 0;
+
+	if (sock == NULL || sock->sock >= CARD_MAX_SLOTS || value == NULL)
+		return -EINVAL;
+
+	slot = sock->sock;
+
+	status = exca_read_byte(slot, I365_STATUS);
+	if (exca_read_byte(slot, I365_INTCTL) & I365_PC_IOCARD) {
+		if (status & I365_CS_STSCHG)
+			val |= SS_STSCHG;
+	} else {
+		if (!(status & I365_CS_BVD1))
+			val |= SS_BATDEAD;
+		else if ((status & (I365_CS_BVD1 | I365_CS_BVD2)) == I365_CS_BVD1)
+			val |= SS_BATWARN;
+	}
+	if ((status & I365_CS_DETECT) == I365_CS_DETECT)
+		val |= SS_DETECT;
+	if (status & I365_CS_WRPROT)
+		val |= SS_WRPROT;
+	if (status & I365_CS_READY)
+		val |= SS_READY;
+	if (status & I365_CS_POWERON)
+		val |= SS_POWERON;
+
+	sense = exca_read_byte(slot, CARD_VOLTAGE_SENSE);
+	switch (sense) {
+	case VCC_3VORXV_CAPABLE:
+		val |= SS_3VCARD | SS_XVCARD;
+		break;
+	case VCC_XV_ONLY:
+		val |= SS_XVCARD;
+		break;
+	case VCC_3V_CAPABLE:
+		val |= SS_3VCARD;
+		break;
+	default:
+		/* 5V only */
+		break;
+	}
+
+	*value = val;
+
+	return 0;
+}
+
+static inline u_char get_Vcc_value(uint8_t voltage)
+{
+	switch (voltage) {
+	case VCC_STATUS_3V:
+		return 33;
+	case VCC_STATUS_5V:
+		return 50;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+static inline u_char get_Vpp_value(uint8_t power, u_char Vcc)
+{
+	if ((power & 0x03) == 0x01 || (power & 0x03) == 0x02)
+		return Vcc;
+
+	return 0;
+}
+
+static int pccard_get_socket(struct pcmcia_socket *sock, socket_state_t *state)
+{
+	unsigned int slot;
+	uint8_t power, voltage, control, cscint;
+
+	if (sock == NULL || sock->sock >= CARD_MAX_SLOTS || state == NULL)
+		return -EINVAL;
+
+	slot = sock->sock;
+
+	power = exca_read_byte(slot, I365_POWER);
+	voltage = exca_read_byte(slot, CARD_VOLTAGE_SELECT);
+
+	state->Vcc = get_Vcc_value(voltage);
+	state->Vpp = get_Vpp_value(power, state->Vcc);
+
+	state->flags = 0;
+	if (power & POWER_ENABLE)
+		state->flags |= SS_PWR_AUTO;
+	if (power & I365_PWR_OUT)
+		state->flags |= SS_OUTPUT_ENA;
+
+	control = exca_read_byte(slot, I365_INTCTL);
+	if (control & I365_PC_IOCARD)
+		state->flags |= SS_IOCARD;
+	if (!(control & I365_PC_RESET))
+		state->flags |= SS_RESET;
+
+        cscint = exca_read_byte(slot, I365_CSCINT);
+	state->csc_mask = 0;
+	if (state->flags & SS_IOCARD) {
+		if (cscint & I365_CSC_STSCHG)
+			state->flags |= SS_STSCHG;
+	} else {
+		if (cscint & I365_CSC_BVD1)
+			state->csc_mask |= SS_BATDEAD;
+		if (cscint & I365_CSC_BVD2)
+			state->csc_mask |= SS_BATWARN;
+	}
+	if (cscint & I365_CSC_READY)
+		state->csc_mask |= SS_READY;
+	if (cscint & I365_CSC_DETECT)
+		state->csc_mask |= SS_DETECT;
+
+	return 0;
+}
+
+static inline uint8_t set_Vcc_value(u_char Vcc)
+{
+	switch (Vcc) {
+	case 33:
+		return VCC_3V;
+	case 50:
+		return VCC_5V;
+	}
+
+	/* Small voltage is chosen for safety. */
+	return VCC_3V;
+}
+
+static int pccard_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
+{
+	vrc4171_socket_t *socket;
+	unsigned int slot;
+	uint8_t voltage, power, control, cscint;
+
+	if (sock == NULL || sock->sock >= CARD_MAX_SLOTS ||
+	    (state->Vpp != state->Vcc && state->Vpp != 0) ||
+	    (state->Vcc != 50 && state->Vcc != 33 && state->Vcc != 0))
+		return -EINVAL;
+
+	slot = sock->sock;
+	socket = &vrc4171_sockets[slot];
+
+	spin_lock_irq(&sock->lock);
+
+	voltage = set_Vcc_value(state->Vcc);
+	exca_write_byte(slot, CARD_VOLTAGE_SELECT, voltage);
+
+	power = POWER_ENABLE;
+	if (state->Vpp == state->Vcc)
+		power |= VPP_GET_VCC;
+	if (state->flags & SS_OUTPUT_ENA)
+		power |= I365_PWR_OUT;
+	exca_write_byte(slot, I365_POWER, power);
+
+	control = 0;
+	if (state->io_irq != 0)
+		control |= socket->io_irq;
+	if (state->flags & SS_IOCARD)
+		control |= I365_PC_IOCARD;
+	if (state->flags & SS_RESET)
+		control	&= ~I365_PC_RESET;
+	else
+		control |= I365_PC_RESET;
+	exca_write_byte(slot, I365_INTCTL, control);
+
+        cscint = 0;
+        exca_write_byte(slot, I365_CSCINT, cscint);
+	exca_read_byte(slot, I365_CSC);	/* clear CardStatus change */
+	if (state->csc_mask != 0)
+		cscint |= socket->csc_irq << 8;
+	if (state->flags & SS_IOCARD) {
+		if (state->csc_mask & SS_STSCHG)
+			cscint |= I365_CSC_STSCHG;
+	} else {
+		if (state->csc_mask & SS_BATDEAD)
+			cscint |= I365_CSC_BVD1;
+		if (state->csc_mask & SS_BATWARN)
+			cscint |= I365_CSC_BVD2;
+	}
+	if (state->csc_mask & SS_READY)
+		cscint |= I365_CSC_READY;
+	if (state->csc_mask & SS_DETECT)
+		cscint |= I365_CSC_DETECT;
+        exca_write_byte(slot, I365_CSCINT, cscint);
+
+	spin_unlock_irq(&sock->lock);
+
+	return 0;
+}
+
+static int pccard_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
+{
+	unsigned int slot;
+	uint8_t ioctl, addrwin;
+	u_char map;
+
+	if (sock == NULL || sock->sock >= CARD_MAX_SLOTS ||
+	    io == NULL || io->map >= IO_MAX_MAPS ||
+	    io->start > 0xffff || io->stop > 0xffff || io->start > io->stop)
+		return -EINVAL;
+
+	slot = sock->sock;
+	map = io->map;
+
+	addrwin = exca_read_byte(slot, I365_ADDRWIN);
+	if (addrwin & I365_ENA_IO(map)) {
+		addrwin &= ~I365_ENA_IO(map);
+		exca_write_byte(slot, I365_ADDRWIN, addrwin);
+	}
+
+	exca_write_word(slot, I365_IO(map)+I365_W_START, io->start);
+	exca_write_word(slot, I365_IO(map)+I365_W_STOP, io->stop);
+
+	ioctl = 0;
+	if (io->speed > 0)
+		ioctl |= I365_IOCTL_WAIT(map);
+	if (io->flags & MAP_16BIT)
+		ioctl |= I365_IOCTL_16BIT(map);
+	if (io->flags & MAP_AUTOSZ)
+		ioctl |= I365_IOCTL_IOCS16(map);
+	if (io->flags & MAP_0WS)
+		ioctl |= I365_IOCTL_0WS(map);
+	exca_write_byte(slot, I365_IOCTL, ioctl);
+
+	if (io->flags & MAP_ACTIVE) {
+		addrwin |= I365_ENA_IO(map);
+		exca_write_byte(slot, I365_ADDRWIN, addrwin);
+	}
+
+	return 0;
+}
+
+static int pccard_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *mem)
+{
+	unsigned int slot;
+	uint16_t start, stop, offset;
+	uint8_t addrwin;
+	u_char map;
+
+	if (sock == NULL || sock->sock >= CARD_MAX_SLOTS ||
+	    mem == NULL || mem->map >= MEM_MAX_MAPS ||
+	    mem->sys_start < CARD_MEM_START || mem->sys_start > CARD_MEM_END ||
+	    mem->sys_stop < CARD_MEM_START || mem->sys_stop > CARD_MEM_END ||
+	    mem->sys_start > mem->sys_stop ||
+	    mem->card_start > CARD_MAX_MEM_OFFSET ||
+	    mem->speed > CARD_MAX_MEM_SPEED)
+		return -EINVAL;
+
+	slot = sock->sock;
+	map = mem->map;
+
+	addrwin = exca_read_byte(slot, I365_ADDRWIN);
+	if (addrwin & I365_ENA_MEM(map)) {
+		addrwin &= ~I365_ENA_MEM(map);
+		exca_write_byte(slot, I365_ADDRWIN, addrwin);
+	}
+
+	start = (mem->sys_start >> 12) & 0x3fff;
+	if (mem->flags & MAP_16BIT)
+		start |= I365_MEM_16BIT;
+	exca_write_word(slot, I365_MEM(map)+I365_W_START, start);
+
+	stop = (mem->sys_stop >> 12) & 0x3fff;
+	switch (mem->speed) {
+	case 0:
+		break;
+	case 1:
+		stop |= I365_MEM_WS0;
+		break;
+	case 2:
+		stop |= I365_MEM_WS1;
+		break;
+	default:
+		stop |= I365_MEM_WS0 | I365_MEM_WS1;
+		break;
+	}
+	exca_write_word(slot, I365_MEM(map)+I365_W_STOP, stop);
+
+	offset = (mem->card_start >> 12) & 0x3fff;
+	if (mem->flags & MAP_ATTRIB)
+		offset |= I365_MEM_REG;
+	if (mem->flags & MAP_WRPROT)
+		offset |= I365_MEM_WRPROT;
+	exca_write_word(slot, I365_MEM(map)+I365_W_OFF, offset);
+
+	if (mem->flags & MAP_ACTIVE) {
+		addrwin |= I365_ENA_MEM(map);
+		exca_write_byte(slot, I365_ADDRWIN, addrwin);
+	}
+
+	return 0;
+}
+
+static struct pccard_operations vrc4171_pccard_operations = {
+	.init			= pccard_init,
+	.suspend		= pccard_suspend,
+	.get_status		= pccard_get_status,
+	.get_socket		= pccard_get_socket,
+	.set_socket		= pccard_set_socket,
+	.set_io_map		= pccard_set_io_map,
+	.set_mem_map		= pccard_set_mem_map,
+};
+
+static inline unsigned int get_events(int slot)
+{
+	unsigned int events = 0;
+	uint8_t status, csc;
+
+	status = exca_read_byte(slot, I365_STATUS);
+	csc = exca_read_byte(slot, I365_CSC);
+
+	if (exca_read_byte(slot, I365_INTCTL) & I365_PC_IOCARD) {
+		if ((csc & I365_CSC_STSCHG) && (status & I365_CS_STSCHG))
+			events |= SS_STSCHG;
+	} else {
+		if (csc & (I365_CSC_BVD1 | I365_CSC_BVD2)) {
+			if (!(status & I365_CS_BVD1))
+				events |= SS_BATDEAD;
+			else if ((status & (I365_CS_BVD1 | I365_CS_BVD2)) == I365_CS_BVD1)
+				events |= SS_BATWARN;
+		}
+	}
+	if ((csc & I365_CSC_READY) && (status & I365_CS_READY))
+		events |= SS_READY;
+	if ((csc & I365_CSC_DETECT) && ((status & I365_CS_DETECT) == I365_CS_DETECT))
+		events |= SS_DETECT;
+
+	return events;
+}
+
+static irqreturn_t pccard_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	vrc4171_socket_t *socket;
+	unsigned int events;
+	irqreturn_t retval = IRQ_NONE;
+	uint16_t status;
+
+	status = vrc4171_get_irq_status();
+	if (status & IRQ_A) {
+		socket = &vrc4171_sockets[CARD_SLOTA];
+		if (socket->noprobe == SLOT_PROBE) {
+			if (status & (1 << socket->csc_irq)) {
+				events = get_events(CARD_SLOTA);
+				if (events != 0) {
+					pcmcia_parse_events(&socket->pcmcia_socket, events);
+					retval = IRQ_HANDLED;
+				}
+			}
+		}
+	}
+
+	if (status & IRQ_B) {
+		socket = &vrc4171_sockets[CARD_SLOTB];
+		if (socket->noprobe == SLOT_PROBE) {
+			if (status & (1 << socket->csc_irq)) {
+				events = get_events(CARD_SLOTB);
+				if (events != 0) {
+					pcmcia_parse_events(&socket->pcmcia_socket, events);
+					retval = IRQ_HANDLED;
+				}
+			}
+		}
+	}
+
+	return retval;
+}
+
+static inline void reserve_using_irq(int slot)
+{
+	unsigned int irq;
+
+	irq = exca_read_byte(slot, I365_INTCTL);
+	irq &= 0x0f;
+	vrc4171_irq_mask &= ~(1 << irq);
+
+	irq = exca_read_byte(slot, I365_CSCINT);
+	irq = (irq & 0xf0) >> 4;
+	vrc4171_irq_mask &= ~(1 << irq);
+}
+
+static int __devinit vrc4171_add_socket(int slot)
+{
+	vrc4171_socket_t *socket;
+	int retval;
+
+	if (slot >= CARD_MAX_SLOTS)
+		return -EINVAL;
+
+	socket = &vrc4171_sockets[slot];
+	if (socket->noprobe != SLOT_PROBE) {
+		uint8_t addrwin;
+
+		switch (socket->noprobe) {
+		case SLOT_NOPROBE_MEM:
+			addrwin = exca_read_byte(slot, I365_ADDRWIN);
+			addrwin &= 0x1f;
+			exca_write_byte(slot, I365_ADDRWIN, addrwin);
+			break;
+		case SLOT_NOPROBE_IO:
+			addrwin = exca_read_byte(slot, I365_ADDRWIN);
+			addrwin &= 0xc0;
+			exca_write_byte(slot, I365_ADDRWIN, addrwin);
+			break;
+		default:
+			break;
+		}
+
+		reserve_using_irq(slot);
+
+		return 0;
+	}
+
+	sprintf(socket->name, "NEC VRC4171 Card Slot %1c", 'A' + slot);
+
+	socket->pcmcia_socket.ops = &vrc4171_pccard_operations;
+
+	retval = pcmcia_register_socket(&socket->pcmcia_socket);
+	if (retval != 0)
+		return retval;
+
+	exca_write_byte(slot, I365_ADDRWIN, 0);
+
+	exca_write_byte(slot, GLOBAL_CONTROL, 0);
+
+	return 0;
+}
+
+static void vrc4171_remove_socket(int slot)
+{
+	vrc4171_socket_t *socket;
+
+	if (slot >= CARD_MAX_SLOTS)
+		return;
+
+	socket = &vrc4171_sockets[slot];
+
+	pcmcia_unregister_socket(&socket->pcmcia_socket);
+}
+
+static int __devinit vrc4171_card_setup(char *options)
+{
+	if (options == NULL || *options == '\0')
+		return 0;
+
+	if (strncmp(options, "irq:", 4) == 0) {
+		int irq;
+		options += 4;
+		irq = simple_strtoul(options, &options, 0);
+		if (irq >= 0 && irq < NR_IRQS)
+			vrc4171_irq = irq;
+
+		if (*options != ',')
+			return 0;
+		options++;
+	}
+
+	if (strncmp(options, "slota:", 6) == 0) {
+		options += 6;
+		if (*options != '\0') {
+			if (strncmp(options, "memnoprobe", 10) == 0) {
+				vrc4171_sockets[CARD_SLOTA].noprobe = SLOT_NOPROBE_MEM;
+				options += 10;
+			} else if (strncmp(options, "ionoprobe", 9) == 0) {
+				vrc4171_sockets[CARD_SLOTA].noprobe = SLOT_NOPROBE_IO;
+				options += 9;
+			} else if ( strncmp(options, "noprobe", 7) == 0) {
+				vrc4171_sockets[CARD_SLOTA].noprobe = SLOT_NOPROBE_ALL;
+				options += 7;
+			}
+
+			if (*options != ',')
+				return 0;
+			options++;
+		} else
+			return 0;
+
+	}
+
+	if (strncmp(options, "slotb:", 6) == 0) {
+		options += 6;
+		if (*options != '\0') {
+			if (strncmp(options, "pccard", 6) == 0) {
+				vrc4171_slotb = SLOTB_IS_PCCARD;
+				options += 6;
+			} else if (strncmp(options, "cf", 2) == 0) {
+				vrc4171_slotb = SLOTB_IS_CF;
+				options += 2;
+			} else if (strncmp(options, "flashrom", 8) == 0) {
+				vrc4171_slotb = SLOTB_IS_FLASHROM;
+				options += 8;
+			} else if (strncmp(options, "none", 4) == 0) {
+				vrc4171_slotb = SLOTB_IS_NONE;
+				options += 4;
+			}
+
+			if (*options != ',')
+				return 0;
+			options++;
+
+			if (strncmp(options, "memnoprobe", 10) == 0)
+				vrc4171_sockets[CARD_SLOTB].noprobe = SLOT_NOPROBE_MEM;
+			if (strncmp(options, "ionoprobe", 9) == 0)
+				vrc4171_sockets[CARD_SLOTB].noprobe = SLOT_NOPROBE_IO;
+			if (strncmp(options, "noprobe", 7) == 0)
+				vrc4171_sockets[CARD_SLOTB].noprobe = SLOT_NOPROBE_ALL;
+		}
+	}
+
+	return 0;
+}
+
+__setup("vrc4171_card=", vrc4171_card_setup);
+
+static int __devinit vrc4171_card_init(void)
+{
+	int retval, slot;
+
+	vrc4171_set_multifunction_pin(vrc4171_slotb);
+
+	if (request_region(CARD_CONTROLLER_INDEX, CARD_CONTROLLER_SIZE,
+	                       "NEC VRC4171 Card Controller") == NULL)
+		return -EBUSY;
+
+	for (slot = 0; slot < CARD_MAX_SLOTS; slot++) {
+		if (slot == CARD_SLOTB && vrc4171_slotb == SLOTB_IS_NONE)
+			break;
+
+		retval = vrc4171_add_socket(slot);
+		if (retval != 0)
+			return retval;
+	}
+
+	retval = request_irq(vrc4171_irq, pccard_interrupt, SA_SHIRQ,
+	                     "NEC VRC4171 Card Controller", vrc4171_sockets);
+	if (retval < 0) {
+		for (slot = 0; slot < CARD_MAX_SLOTS; slot++)
+			vrc4171_remove_socket(slot);
+
+		return retval;
+	}
+
+	printk(KERN_INFO "NEC VRC4171 Card Controller, connected to IRQ %d\n", vrc4171_irq);
+
+	return 0;
+}
+
+static void __devexit vrc4171_card_exit(void)
+{
+	int slot;
+
+	for (slot = 0; slot < CARD_MAX_SLOTS; slot++)
+		vrc4171_remove_socket(slot);
+
+	release_region(CARD_CONTROLLER_INDEX, CARD_CONTROLLER_SIZE);
+}
+
+module_init(vrc4171_card_init);
+module_exit(vrc4171_card_exit);
diff -Nru a/drivers/pcmcia/vrc4173_cardu.c b/drivers/pcmcia/vrc4173_cardu.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/pcmcia/vrc4173_cardu.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,622 @@
+/*
+ * FILE NAME
+ *	drivers/pcmcia/vrc4173_cardu.c
+ *
+ * BRIEF MODULE DESCRIPTION
+ * 	NEC VRC4173 CARDU driver for Socket Services
+ *	(This device doesn't support CardBus. it is supporting only 16bit PC Card.)
+ *
+ * Copyright 2002,2003 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 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/init.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+
+#include <asm/io.h>
+
+#include <pcmcia/ss.h>
+
+#include "vrc4173_cardu.h"
+
+MODULE_DESCRIPTION("NEC VRC4173 CARDU driver for Socket Services");
+MODULE_AUTHOR("Yoichi Yuasa <yuasa@hh.iij4u.or.jp>");
+MODULE_LICENSE("GPL");
+
+static int vrc4173_cardu_slots;
+
+static vrc4173_socket_t cardu_sockets[CARDU_MAX_SOCKETS];
+
+extern struct socket_info_t *pcmcia_register_socket (int slot,
+                                                     struct pccard_operations *vtable,
+                                                     int use_bus_pm);
+extern void pcmcia_unregister_socket(struct socket_info_t *s);
+
+static inline uint8_t exca_readb(vrc4173_socket_t *socket, uint16_t offset)
+{
+	return readb(socket->base + EXCA_REGS_BASE + offset);
+}
+
+static inline uint16_t exca_readw(vrc4173_socket_t *socket, uint16_t offset)
+{
+	uint16_t val;
+
+	val = readb(socket->base + EXCA_REGS_BASE + offset);
+	val |= (u16)readb(socket->base + EXCA_REGS_BASE + offset + 1) << 8;
+
+	return val;
+}
+
+static inline void exca_writeb(vrc4173_socket_t *socket, uint16_t offset, uint8_t val)
+{
+	writeb(val, socket->base + EXCA_REGS_BASE + offset);
+}
+
+static inline void exca_writew(vrc4173_socket_t *socket, uint8_t offset, uint16_t val)
+{
+	writeb((u8)val, socket->base + EXCA_REGS_BASE + offset);
+	writeb((u8)(val >> 8), socket->base + EXCA_REGS_BASE + offset + 1);
+}
+
+static inline uint32_t cardbus_socket_readl(vrc4173_socket_t *socket, u16 offset)
+{
+	return readl(socket->base + CARDBUS_SOCKET_REGS_BASE + offset);
+}
+
+static inline void cardbus_socket_writel(vrc4173_socket_t *socket, u16 offset, uint32_t val)
+{
+	writel(val, socket->base + CARDBUS_SOCKET_REGS_BASE + offset);
+}
+
+static void cardu_pciregs_init(struct pci_dev *dev)
+{
+	u32 syscnt;
+	u16 brgcnt;
+	u8 devcnt;
+
+	pci_write_config_dword(dev, 0x1c, 0x10000000);
+	pci_write_config_dword(dev, 0x20, 0x17fff000);
+	pci_write_config_dword(dev, 0x2c, 0);
+	pci_write_config_dword(dev, 0x30, 0xfffc);
+
+	pci_read_config_word(dev, BRGCNT, &brgcnt);
+	brgcnt &= ~IREQ_INT;
+	pci_write_config_word(dev, BRGCNT, brgcnt);
+
+	pci_read_config_dword(dev, SYSCNT, &syscnt);
+	syscnt &= ~(BAD_VCC_REQ_DISB|PCPCI_EN|CH_ASSIGN_MASK|SUB_ID_WR_EN|PCI_CLK_RIN);
+	syscnt |= (CH_ASSIGN_NODMA|ASYN_INT_MODE);
+	pci_write_config_dword(dev, SYSCNT, syscnt);
+
+	pci_read_config_byte(dev, DEVCNT, &devcnt);
+	devcnt &= ~(ZOOM_VIDEO_EN|SR_PCI_INT_SEL_MASK|PCI_INT_MODE|IRQ_MODE);
+	devcnt |= (SR_PCI_INT_SEL_NONE|IFG);
+	pci_write_config_byte(dev, DEVCNT, devcnt);
+
+	pci_write_config_byte(dev, CHIPCNT, S_PREF_DISB);
+
+	pci_write_config_byte(dev, SERRDIS, 0);
+}
+
+static int cardu_init(unsigned int slot)
+{
+	vrc4173_socket_t *socket = &cardu_sockets[slot];
+
+	cardu_pciregs_init(socket->dev);
+
+	/* CARD_SC bits are cleared by reading CARD_SC. */
+	exca_writeb(socket, GLO_CNT, 0);
+
+	socket->cap.features |= SS_CAP_PCCARD | SS_CAP_PAGE_REGS;
+	socket->cap.irq_mask = 0;
+	socket->cap.map_size = 0x1000;
+	socket->cap.pci_irq  = socket->dev->irq;
+	socket->events = 0;
+	spin_lock_init(socket->event_lock);
+
+	/* Enable PC Card status interrupts */
+	exca_writeb(socket, CARD_SCI, CARD_DT_EN|RDY_EN|BAT_WAR_EN|BAT_DEAD_EN);
+
+	return 0;
+}
+
+static int cardu_suspend(unsigned int slot)
+{
+	return -EINVAL;
+}
+
+static int cardu_register_callback(unsigned int sock,
+                                           void (*handler)(void *, unsigned int),
+                                           void * info)
+{
+	vrc4173_socket_t *socket = &cardu_sockets[sock];
+
+	socket->handler = handler;
+	socket->info = info;
+
+	return 0;
+}
+
+static int cardu_inquire_socket(unsigned int sock, socket_cap_t *cap)
+{
+	vrc4173_socket_t *socket = &cardu_sockets[sock];
+
+	*cap = socket->cap;
+
+	return 0;
+}
+
+static int cardu_get_status(unsigned int sock, u_int *value)
+{
+	vrc4173_socket_t *socket = &cardu_sockets[sock];
+	uint32_t state;
+	uint8_t status;
+	u_int val = 0;
+
+	status = exca_readb(socket, IF_STATUS);
+	if (status & CARD_PWR) val |= SS_POWERON;
+	if (status & READY) val |= SS_READY;
+	if (status & CARD_WP) val |= SS_WRPROT;
+	if ((status & (CARD_DETECT1|CARD_DETECT2)) == (CARD_DETECT1|CARD_DETECT2))
+		val |= SS_DETECT;
+	if (exca_readb(socket, INT_GEN_CNT) & CARD_TYPE_IO) {
+		if (status & STSCHG) val |= SS_STSCHG;
+	} else {
+		status &= BV_DETECT_MASK;
+		if (status != BV_DETECT_GOOD) {
+			if (status == BV_DETECT_WARN) val |= SS_BATWARN;
+			else val |= SS_BATDEAD;
+		}
+	}
+
+	state = cardbus_socket_readl(socket, SKT_PRE_STATE);
+	if (state & VOL_3V_CARD_DT) val |= SS_3VCARD;
+	if (state & VOL_XV_CARD_DT) val |= SS_XVCARD;
+	if (state & CB_CARD_DT) val |= SS_CARDBUS;
+	if (!(state &
+	      (VOL_YV_CARD_DT|VOL_XV_CARD_DT|VOL_3V_CARD_DT|VOL_5V_CARD_DT|CCD20|CCD10)))
+		val |= SS_PENDING;
+
+	*value = val;
+
+	return 0;
+}
+
+static inline u_char get_Vcc_value(uint8_t val)
+{
+	switch (val & VCC_MASK) {
+	case VCC_3V:
+		return 33;
+	case VCC_5V:
+		return 50;
+	}
+
+	return 0;
+}
+
+static inline u_char get_Vpp_value(uint8_t val)
+{
+	switch (val & VPP_MASK) {
+	case VPP_12V:
+		return 120;
+	case VPP_VCC:
+		return get_Vcc_value(val);
+	}
+
+	return 0;
+}
+
+static int cardu_get_socket(unsigned int sock, socket_state_t *state)
+{
+	vrc4173_socket_t *socket = &cardu_sockets[sock];
+	uint8_t val;
+
+	val = exca_readb(socket, PWR_CNT);
+	state->Vcc = get_Vcc_value(val);
+	state->Vpp = get_Vpp_value(val);
+	state->flags = 0;
+	if (val & CARD_OUT_EN) state->flags |= SS_OUTPUT_ENA;
+
+	val = exca_readb(socket, INT_GEN_CNT);
+	if (!(val & CARD_REST0)) state->flags |= SS_RESET;
+	if (val & CARD_TYPE_IO) state->flags |= SS_IOCARD;
+
+	return 0;
+}
+
+static inline uint8_t set_Vcc_value(u_char Vcc)
+{
+	switch (Vcc) {
+	case 33:
+		return VCC_3V;
+	case 50:
+		return VCC_5V;
+	}
+
+	return VCC_0V;
+}
+
+static inline uint8_t set_Vpp_value(u_char Vpp)
+{
+	switch (Vpp) {
+	case 33:
+	case 50:
+		return VPP_VCC;
+	case 120:
+		return VPP_12V;
+	}
+
+	return VPP_0V;
+}
+
+static int cardu_set_socket(unsigned int sock, socket_state_t *state)
+{
+	vrc4173_socket_t *socket = &cardu_sockets[sock];
+	uint8_t val;
+
+	if (((state->Vpp == 33) || (state->Vpp == 50)) && (state->Vpp != state->Vcc))
+			return -EINVAL;
+
+	val = set_Vcc_value(state->Vcc);
+	val |= set_Vpp_value(state->Vpp);
+	if (state->flags & SS_OUTPUT_ENA) val |= CARD_OUT_EN;
+	exca_writeb(socket, PWR_CNT, val);
+
+	val = exca_readb(socket, INT_GEN_CNT) & CARD_REST0;
+	if (state->flags & SS_RESET) val &= ~CARD_REST0;
+	else val |= CARD_REST0;
+	if (state->flags & SS_IOCARD) val |= CARD_TYPE_IO;
+	exca_writeb(socket, INT_GEN_CNT, val);
+
+	return 0;
+}
+
+static int cardu_get_io_map(unsigned int sock, struct pccard_io_map *io)
+{
+	vrc4173_socket_t *socket = &cardu_sockets[sock];
+	uint8_t ioctl, window;
+	u_char map;
+
+	map = io->map;
+	if (map > 1)
+		return -EINVAL;
+
+	io->start = exca_readw(socket, IO_WIN_SA(map));
+	io->stop = exca_readw(socket, IO_WIN_EA(map));
+
+	ioctl = exca_readb(socket, IO_WIN_CNT);
+	window = exca_readb(socket, ADR_WIN_EN);
+	io->flags  = (window & IO_WIN_EN(map)) ? MAP_ACTIVE : 0;
+	if (ioctl & IO_WIN_DATA_AUTOSZ(map))
+		io->flags |= MAP_AUTOSZ;
+	else if (ioctl & IO_WIN_DATA_16BIT(map))
+		io->flags |= MAP_16BIT;
+
+	return 0;
+}
+
+static int cardu_set_io_map(unsigned int sock, struct pccard_io_map *io)
+{
+	vrc4173_socket_t *socket = &cardu_sockets[sock];
+	uint16_t ioctl;
+	uint8_t window, enable;
+	u_char map;
+
+	map = io->map;
+	if (map > 1)
+		return -EINVAL;
+
+	window = exca_readb(socket, ADR_WIN_EN);
+	enable = IO_WIN_EN(map);
+
+	if (window & enable) {
+		window &= ~enable;
+		exca_writeb(socket, ADR_WIN_EN, window);
+	}
+
+	exca_writew(socket, IO_WIN_SA(map), io->start);
+	exca_writew(socket, IO_WIN_EA(map), io->stop);
+
+	ioctl = exca_readb(socket, IO_WIN_CNT) & ~IO_WIN_CNT_MASK(map);
+	if (io->flags & MAP_AUTOSZ) ioctl |= IO_WIN_DATA_AUTOSZ(map);
+	else if (io->flags & MAP_16BIT) ioctl |= IO_WIN_DATA_16BIT(map);
+	exca_writeb(socket, IO_WIN_CNT, ioctl);
+
+	if (io->flags & MAP_ACTIVE)
+		exca_writeb(socket, ADR_WIN_EN, window | enable);
+
+	return 0;
+}
+
+static int cardu_get_mem_map(unsigned int sock, struct pccard_mem_map *mem)
+{
+	vrc4173_socket_t *socket = &cardu_sockets[sock];
+	uint32_t start, stop, offset, page;
+	uint8_t window;
+	u_char map;
+
+	map = mem->map;
+	if (map > 4)
+		return -EINVAL;
+
+	window = exca_readb(socket, ADR_WIN_EN);
+	mem->flags = (window & MEM_WIN_EN(map)) ? MAP_ACTIVE : 0;
+
+	start = exca_readw(socket, MEM_WIN_SA(map));
+	mem->flags |= (start & MEM_WIN_DSIZE) ? MAP_16BIT : 0;
+	start = (start & 0x0fff) << 12;
+
+	stop = exca_readw(socket, MEM_WIN_EA(map));
+	stop = ((stop & 0x0fff) << 12) + 0x0fff;
+
+	offset = exca_readw(socket, MEM_WIN_OA(map));
+	mem->flags |= (offset & MEM_WIN_WP) ? MAP_WRPROT : 0;
+	mem->flags |= (offset & MEM_WIN_REGSET) ? MAP_ATTRIB : 0;
+	offset = ((offset & 0x3fff) << 12) + start;
+	mem->card_start = offset & 0x03ffffff;
+
+	page = exca_readb(socket, MEM_WIN_SAU(map)) << 24;
+	mem->sys_start = start + page;
+	mem->sys_stop = start + page;
+
+	return 0;
+}
+
+static int cardu_set_mem_map(unsigned int sock, struct pccard_mem_map *mem)
+{
+	vrc4173_socket_t *socket = &cardu_sockets[sock];
+	uint16_t value;
+	uint8_t window, enable;
+	u_long sys_start, sys_stop, card_start;
+	u_char map;
+
+	map = mem->map;
+	sys_start = mem->sys_start;
+	sys_stop = mem->sys_stop;
+	card_start = mem->card_start;
+
+	if (map > 4 || sys_start > sys_stop || ((sys_start ^ sys_stop) >> 24) ||
+	    (card_start >> 26))
+		return -EINVAL;
+
+	window = exca_readb(socket, ADR_WIN_EN);
+	enable = MEM_WIN_EN(map);
+	if (window & enable) {
+		window &= ~enable;
+		exca_writeb(socket, ADR_WIN_EN, window);
+	}
+
+	exca_writeb(socket, MEM_WIN_SAU(map), sys_start >> 24);
+
+	value = (sys_start >> 12) & 0x0fff;
+	if (mem->flags & MAP_16BIT) value |= MEM_WIN_DSIZE;
+	exca_writew(socket, MEM_WIN_SA(map), value);
+
+	value = (sys_stop >> 12) & 0x0fff;
+	exca_writew(socket, MEM_WIN_EA(map), value);
+
+	value = ((card_start - sys_start) >> 12) & 0x3fff;
+	if (mem->flags & MAP_WRPROT) value |= MEM_WIN_WP;
+	if (mem->flags & MAP_ATTRIB) value |= MEM_WIN_REGSET;
+	exca_writew(socket, MEM_WIN_OA(map), value);
+
+	if (mem->flags & MAP_ACTIVE)
+		exca_writeb(socket, ADR_WIN_EN, window | enable);
+
+	return 0;
+}
+
+static void cardu_proc_setup(unsigned int sock, struct proc_dir_entry *base)
+{
+}
+
+static struct pccard_operations cardu_operations = {
+	.init			= cardu_init,
+	.suspend		= cardu_suspend,
+	.register_callback	= cardu_register_callback,
+	.inquire_socket		= cardu_inquire_socket,
+	.get_status		= cardu_get_status,
+	.get_socket		= cardu_get_socket,
+	.set_socket		= cardu_set_socket,
+	.get_io_map		= cardu_get_io_map,
+	.set_io_map		= cardu_set_io_map,
+	.get_mem_map		= cardu_get_mem_map,
+	.set_mem_map		= cardu_set_mem_map,
+	.proc_setup		= cardu_proc_setup,
+};
+
+static void cardu_bh(void *data)
+{
+	vrc4173_socket_t *socket = (vrc4173_socket_t *)data;
+	uint16_t events;
+
+	spin_lock_irq(&socket->event_lock);
+	events = socket->events;
+	socket->events = 0;
+	spin_unlock_irq(&socket->event_lock);
+
+	if (socket->handler)
+		socket->handler(socket->info, events);
+}
+
+static uint16_t get_events(vrc4173_socket_t *socket)
+{
+	uint16_t events = 0;
+	uint8_t csc, status;
+
+	status = exca_readb(socket, IF_STATUS);
+	csc = exca_readb(socket, CARD_SC);
+	if ((csc & CARD_DT_CHG) &&
+	    ((status & (CARD_DETECT1|CARD_DETECT2)) == (CARD_DETECT1|CARD_DETECT2)))
+		events |= SS_DETECT;
+
+	if ((csc & RDY_CHG) && (status & READY))
+		events |= SS_READY;
+
+	if (exca_readb(socket, INT_GEN_CNT) & CARD_TYPE_IO) {
+		if ((csc & BAT_DEAD_ST_CHG) && (status & STSCHG))
+			events |= SS_STSCHG;
+	} else {
+		if (csc & (BAT_WAR_CHG|BAT_DEAD_ST_CHG)) {
+			if ((status & BV_DETECT_MASK) != BV_DETECT_GOOD) {
+				if (status == BV_DETECT_WARN) events |= SS_BATWARN;
+				else events |= SS_BATDEAD;
+			}
+		}
+	}
+
+	return events;
+}
+
+static void cardu_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	vrc4173_socket_t *socket = (vrc4173_socket_t *)dev_id;
+	uint16_t events;
+
+	INIT_WORK(&socket->tq_work, cardu_bh, socket);
+
+	events = get_events(socket);
+	if (events) {
+		spin_lock(&socket->event_lock);
+		socket->events |= events;
+		spin_unlock(&socket->event_lock);
+		schedule_work(&socket->tq_work);
+	}
+}
+
+static int __devinit vrc4173_cardu_probe(struct pci_dev *dev,
+                                         const struct pci_device_id *ent)
+{
+	vrc4173_socket_t *socket;
+	unsigned long start, len, flags;
+	int slot, err;
+
+	slot = vrc4173_cardu_slots++;
+	socket = &cardu_sockets[slot];
+	if (socket->noprobe != 0)
+		return -EBUSY;
+
+	sprintf(socket->name, "NEC VRC4173 CARDU%1d", slot+1);
+
+	if ((err = pci_enable_device(dev)) < 0)
+		return err;
+
+	start = pci_resource_start(dev, 0);
+	if (start == 0)
+		return -ENODEV;
+
+	len = pci_resource_len(dev, 0);
+	if (len == 0)
+		return -ENODEV;
+
+	if (((flags = pci_resource_flags(dev, 0)) & IORESOURCE_MEM) == 0)
+		return -EBUSY;
+
+	if ((err = pci_request_regions(dev, socket->name)) < 0)
+		return err;
+
+	socket->base = ioremap(start, len);
+	if (socket->base == NULL)
+		return -ENODEV;
+
+	socket->dev = dev;
+
+	socket->pcmcia_socket = pcmcia_register_socket(slot, &cardu_operations, 1);
+	if (socket->pcmcia_socket == NULL) {
+		iounmap(socket->base);
+		socket->base = NULL;
+		return -ENOMEM;
+	}
+
+	if (request_irq(dev->irq, cardu_interrupt, SA_SHIRQ, socket->name, socket) < 0) {
+		pcmcia_unregister_socket(socket->pcmcia_socket);
+		socket->pcmcia_socket = NULL;
+		iounmap(socket->base);
+		socket->base = NULL;
+		return -EBUSY;
+	}
+
+	printk(KERN_INFO "%s at %#08lx, IRQ %d\n", socket->name, start, dev->irq);
+
+	return 0;
+}
+
+static int __devinit vrc4173_cardu_setup(char *options)
+{
+	if (options == NULL || *options == '\0')
+		return 0;
+
+	if (strncmp(options, "cardu1:", 7) == 0) {
+		options += 7;
+		if (*options != '\0') {
+			if (strncmp(options, "noprobe", 7) == 0) {
+				cardu_sockets[CARDU1].noprobe = 1;
+				options += 7;
+			}
+
+			if (*options != ',')
+				return 0;
+		} else
+			return 0;
+	}
+
+	if (strncmp(options, "cardu2:", 7) == 0) {
+		options += 7;
+		if ((*options != '\0') && (strncmp(options, "noprobe", 7) == 0))
+			cardu_sockets[CARDU2].noprobe = 1;
+	}
+
+	return 0;
+}
+
+__setup("vrc4173_cardu=", vrc4173_cardu_setup);
+
+static struct pci_device_id vrc4173_cardu_id_table[] __devinitdata = {
+	{	.vendor		= PCI_VENDOR_ID_NEC,
+		.device		= PCI_DEVICE_ID_NEC_NAPCCARD,
+		.subvendor	= PCI_ANY_ID,
+		.subdevice	= PCI_ANY_ID, },
+        {0, }
+};
+
+static struct pci_driver vrc4173_cardu_driver = {
+	.name		= "NEC VRC4173 CARDU",
+	.probe		= vrc4173_cardu_probe,
+	.id_table	= vrc4173_cardu_id_table,
+};
+
+static int __devinit vrc4173_cardu_init(void)
+{
+	vrc4173_cardu_slots = 0;
+
+	return pci_module_init(&vrc4173_cardu_driver);
+}
+
+static void __devexit vrc4173_cardu_exit(void)
+{
+	pci_unregister_driver(&vrc4173_cardu_driver);
+}
+
+module_init(vrc4173_cardu_init);
+module_exit(vrc4173_cardu_exit);
diff -Nru a/drivers/pcmcia/vrc4173_cardu.h b/drivers/pcmcia/vrc4173_cardu.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/pcmcia/vrc4173_cardu.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,247 @@
+/*
+ * FILE NAME
+ *	drivers/pcmcia/vrc4173_cardu.h
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Include file for NEC VRC4173 CARDU.
+ *
+ * Copyright 2002 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 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 _VRC4173_CARDU_H
+#define _VRC4173_CARDU_H
+
+#include <linux/pci.h>
+
+#include <pcmcia/ss.h>
+
+#define CARDU_MAX_SOCKETS	2
+#define CARDU1			0
+#define CARDU2			1
+
+/*
+ * PCI Configuration Registers
+ */
+#define BRGCNT			0x3e
+ #define POST_WR_EN		0x0400
+ #define MEM1_PREF_EN		0x0200
+ #define MEM0_PREF_EN		0x0100
+ #define IREQ_INT		0x0080
+ #define CARD_RST		0x0040
+ #define MABORT_MODE		0x0020
+ #define VGA_EN			0x0008
+ #define ISA_EN			0x0004
+ #define SERR_EN		0x0002
+ #define PERR_EN		0x0001
+
+#define SYSCNT			0x80
+ #define BAD_VCC_REQ_DISB	0x00200000
+ #define PCPCI_EN		0x00080000
+ #define CH_ASSIGN_MASK		0x00070000
+ #define CH_ASSIGN_NODMA	0x00040000
+ #define SUB_ID_WR_EN		0x00000008
+ #define ASYN_INT_MODE		0x00000004
+ #define PCI_CLK_RIN		0x00000002
+
+#define DEVCNT			0x91
+ #define ZOOM_VIDEO_EN		0x40
+ #define SR_PCI_INT_SEL_MASK	0x18
+ #define SR_PCI_INT_SEL_NONE	0x00
+ #define PCI_INT_MODE		0x04
+ #define IRQ_MODE		0x02
+ #define IFG			0x01
+
+#define CHIPCNT			0x9c
+ #define S_PREF_DISB		0x10
+
+#define SERRDIS			0x9f
+ #define SERR_DIS_MAB		0x10
+ #define SERR_DIS_TAB		0x08
+ #define SERR_DIS_DT_PERR	0x04
+
+/*
+ * ExCA Registers
+ */
+#define EXCA_REGS_BASE		0x800
+#define EXCA_REGS_SIZE		0x800
+
+#define ID_REV			0x000
+ #define IF_TYPE_16BIT		0x80
+
+#define IF_STATUS		0x001
+ #define CARD_PWR		0x40
+ #define READY			0x20
+ #define CARD_WP		0x10
+ #define CARD_DETECT2		0x08
+ #define CARD_DETECT1		0x04
+ #define BV_DETECT_MASK		0x03
+ #define BV_DETECT_GOOD		0x03	/* Memory card */
+ #define BV_DETECT_WARN		0x02
+ #define BV_DETECT_BAD1		0x01
+ #define BV_DETECT_BAD0		0x00
+ #define STSCHG			0x02	/* I/O card */
+ #define SPKR			0x01
+
+#define PWR_CNT			0x002
+ #define CARD_OUT_EN		0x80
+ #define VCC_MASK		0x18
+ #define VCC_3V			0x18
+ #define VCC_5V			0x10
+ #define VCC_0V			0x00
+ #define VPP_MASK		0x03
+ #define VPP_12V		0x02
+ #define VPP_VCC		0x01
+ #define VPP_0V			0x00
+
+#define INT_GEN_CNT		0x003
+ #define CARD_REST0		0x40
+ #define CARD_TYPE_MASK		0x20
+ #define CARD_TYPE_IO		0x20
+ #define CARD_TYPE_MEM		0x00
+
+#define CARD_SC			0x004
+ #define CARD_DT_CHG		0x08
+ #define RDY_CHG		0x04
+ #define BAT_WAR_CHG		0x02
+ #define BAT_DEAD_ST_CHG	0x01
+
+#define CARD_SCI		0x005
+ #define CARD_DT_EN		0x08
+ #define RDY_EN			0x04
+ #define BAT_WAR_EN		0x02
+ #define BAT_DEAD_EN		0x01
+
+#define ADR_WIN_EN		0x006
+ #define IO_WIN_EN(x)		(0x40 << (x))
+ #define MEM_WIN_EN(x)		(0x01 << (x))
+
+#define IO_WIN_CNT		0x007
+ #define IO_WIN_CNT_MASK(x)	(0x03 << ((x) << 2))
+ #define IO_WIN_DATA_AUTOSZ(x)	(0x02 << ((x) << 2))
+ #define IO_WIN_DATA_16BIT(x)	(0x01 << ((x) << 2))
+
+#define IO_WIN_SA(x)		(0x008 + ((x) << 2))
+#define IO_WIN_EA(x)		(0x00a + ((x) << 2))
+
+#define MEM_WIN_SA(x)		(0x010 + ((x) << 3))
+ #define MEM_WIN_DSIZE		0x8000
+
+#define MEM_WIN_EA(x)		(0x012 + ((x) << 3))
+
+#define MEM_WIN_OA(x)		(0x014 + ((x) << 3))
+ #define MEM_WIN_WP		0x8000
+ #define MEM_WIN_REGSET		0x4000
+
+#define GEN_CNT			0x016
+ #define VS2_STATUS		0x80
+ #define VS1_STATUS		0x40
+ #define EXCA_REG_RST_EN	0x02
+
+#define GLO_CNT			0x01e
+ #define FUN_INT_LEV		0x08
+ #define INT_WB_CLR		0x04
+ #define CSC_INT_LEV		0x02
+
+#define IO_WIN_OAL(x)		(0x036 + ((x) << 1))
+#define IO_WIN_OAH(x)		(0x037 + ((x) << 1))
+
+#define MEM_WIN_SAU(x)		(0x040 + (x))
+
+#define IO_SETUP_TIM		0x080
+#define IO_CMD_TIM		0x081
+#define IO_HOLD_TIM		0x082
+#define MEM_SETUP_TIM(x)	(0x084 + ((x) << 2))
+#define MEM_CMD_TIM(x)		(0x085 + ((x) << 2))
+#define MEM_HOLD_TIM(x)		(0x086 + ((x) << 2))
+ #define TIM_CLOCKS(x)		((x) - 1)
+
+#define MEM_TIM_SEL1		0x08c
+#define MEM_TIM_SEL2		0x08d
+ #define MEM_WIN_TIMSEL1(x)	(0x03 << (((x) & 3) << 1))
+
+#define MEM_WIN_PWEN		0x091
+ #define POSTWEN		0x01
+
+/*
+ * CardBus Socket Registers
+ */
+#define CARDBUS_SOCKET_REGS_BASE	0x000
+#define CARDBUS_SOCKET_REGS_SIZE	0x800
+
+#define SKT_EV			0x000
+ #define POW_CYC_EV		0x00000008
+ #define CCD2_EV		0x00000004
+ #define CCD1_EV		0x00000002
+ #define CSTSCHG_EV		0x00000001
+
+#define SKT_MASK		0x004
+ #define POW_CYC_MASK		0x00000008
+ #define CCD_MASK		0x00000006
+ #define CSC_MASK		0x00000001
+
+#define SKT_PRE_STATE		0x008
+#define SKT_FORCE_EV		0x00c
+ #define VOL_3V_SKT		0x20000000
+ #define VOL_5V_SKT		0x10000000
+ #define CVS_TEST		0x00004000
+ #define VOL_YV_CARD_DT		0x00002000
+ #define VOL_XV_CARD_DT		0x00001000
+ #define VOL_3V_CARD_DT		0x00000800
+ #define VOL_5V_CARD_DT		0x00000400
+ #define BAD_VCC_REQ		0x00000200
+ #define DATA_LOST		0x00000100
+ #define NOT_A_CARD		0x00000080
+ #define CREADY			0x00000040
+ #define CB_CARD_DT		0x00000020
+ #define R2_CARD_DT		0x00000010
+ #define POW_UP			0x00000008
+ #define CCD20			0x00000004
+ #define CCD10			0x00000002
+ #define CSTSCHG		0x00000001
+
+#define SKT_CNT			0x010
+ #define STP_CLK_EN		0x00000080
+ #define VCC_CNT_MASK		0x00000070
+ #define VCC_CNT_3V		0x00000030
+ #define VCC_CNT_5V		0x00000020
+ #define VCC_CNT_0V		0x00000000
+ #define VPP_CNT_MASK		0x00000007
+ #define VPP_CNT_3V		0x00000003
+ #define VPP_CNT_5V		0x00000002
+ #define VPP_CNT_12V		0x00000001
+ #define VPP_CNT_0V		0x00000000
+
+typedef struct vrc4173_socket {
+	int noprobe;
+	struct pci_dev *dev;
+	void *base;
+	void (*handler)(void *, unsigned int);
+	void *info;
+	socket_cap_t cap;
+	spinlock_t event_lock;
+	uint16_t events;
+	struct socket_info_t *pcmcia_socket;
+	struct work_struct tq_work;
+	char name[20];
+} vrc4173_socket_t;
+
+#endif /* _VRC4173_CARDU_H */
diff -Nru a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c
--- a/drivers/pcmcia/yenta_socket.c	2005-03-01 23:38:59 -08:00
+++ b/drivers/pcmcia/yenta_socket.c	2005-03-01 23:38:59 -08:00
@@ -28,6 +28,9 @@
 #include "yenta_socket.h"
 #include "i82365.h"
 
+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");
 
 #if 0
 #define debug(x,args...) printk(KERN_DEBUG "%s: " x, __func__ , ##args)
@@ -42,6 +45,10 @@
 static int yenta_probe_cb_irq(struct yenta_socket *socket);
 
 
+static unsigned int override_bios;
+module_param(override_bios, uint, 0000);
+MODULE_PARM_DESC (override_bios, "yenta ignore bios resource allocation");
+
 /*
  * Generate easy-to-use ways of reading a cardbus sockets
  * regular memory space ("cb_xxx"), configuration space
@@ -551,7 +558,7 @@
 
 	start = config_readl(socket, offset) & mask;
 	end = config_readl(socket, offset+4) | ~mask;
-	if (start && end > start) {
+	if (start && end > start && !override_bios) {
 		res->start = start;
 		res->end = end;
 		if (request_resource(root, res) == 0)
@@ -914,6 +921,7 @@
 
 	/* prepare pcmcia_socket */
 	socket->socket.ops = &yenta_socket_operations;
+	socket->socket.resource_ops = &pccard_nonstatic_ops;
 	socket->socket.dev.dev = &dev->dev;
 	socket->socket.driver_data = socket;
 	socket->socket.owner = THIS_MODULE;
diff -Nru a/drivers/pnp/core.c b/drivers/pnp/core.c
--- a/drivers/pnp/core.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/pnp/core.c	2005-03-01 23:38:53 -08:00
@@ -20,7 +20,7 @@
 
 LIST_HEAD(pnp_protocols);
 LIST_HEAD(pnp_global);
-spinlock_t pnp_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(pnp_lock);
 
 void *pnp_alloc(long size)
 {
diff -Nru a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c
--- a/drivers/pnp/isapnp/core.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/pnp/isapnp/core.c	2005-03-01 23:38:58 -08:00
@@ -58,13 +58,13 @@
 
 MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
 MODULE_DESCRIPTION("Generic ISA Plug & Play support");
-MODULE_PARM(isapnp_disable, "i");
+module_param(isapnp_disable, int, 0);
 MODULE_PARM_DESC(isapnp_disable, "ISA Plug & Play disable");
-MODULE_PARM(isapnp_rdp, "i");
+module_param(isapnp_rdp, int, 0);
 MODULE_PARM_DESC(isapnp_rdp, "ISA Plug & Play read data port");
-MODULE_PARM(isapnp_reset, "i");
+module_param(isapnp_reset, int, 0);
 MODULE_PARM_DESC(isapnp_reset, "ISA Plug & Play reset all cards");
-MODULE_PARM(isapnp_verbose, "i");
+module_param(isapnp_verbose, int, 0);
 MODULE_PARM_DESC(isapnp_verbose, "ISA Plug & Play verbose mode");
 MODULE_LICENSE("GPL");
 
diff -Nru a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c
--- a/drivers/pnp/pnpacpi/core.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/pnp/pnpacpi/core.c	2005-03-01 23:38:57 -08:00
@@ -236,23 +236,34 @@
 
 	if (!acpi_bus_get_device(handle, &device))
 		pnpacpi_add_device(device);
+	else
+		return AE_CTRL_DEPTH;
 	return AE_OK;
 }
 
+int pnpacpi_disabled __initdata;
 int __init pnpacpi_init(void)
 {
-	if (acpi_disabled) {
-		pnp_info("PnP ACPI: ACPI disable");
+	if (acpi_disabled || pnpacpi_disabled) {
+		pnp_info("PnP ACPI: disabled");
 		return 0;
 	}
 	pnp_info("PnP ACPI init");
 	pnp_register_protocol(&pnpacpi_protocol);
-	acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
-			ACPI_UINT32_MAX, pnpacpi_add_device_handler,
-			NULL, NULL);
+	acpi_get_devices(NULL, pnpacpi_add_device_handler, NULL, NULL);
 	pnp_info("PnP ACPI: found %d devices", num);
 	return 0;
 }
 subsys_initcall(pnpacpi_init);
+
+static int __init pnpacpi_setup(char *str)
+{
+	if (str == NULL)
+		return 1;
+	if (!strncmp(str, "off", 3))
+		pnpacpi_disabled = 1;
+	return 1;
+}
+__setup("pnpacpi=", pnpacpi_setup);
 
 EXPORT_SYMBOL(pnpacpi_protocol);
diff -Nru a/drivers/pnp/pnpbios/Kconfig b/drivers/pnp/pnpbios/Kconfig
--- a/drivers/pnp/pnpbios/Kconfig	2005-03-01 23:39:08 -08:00
+++ b/drivers/pnp/pnpbios/Kconfig	2005-03-01 23:39:08 -08:00
@@ -30,7 +30,7 @@
 	  able to directly access the PNPBIOS.  This includes resource
 	  allocation, ESCD, and other PNPBIOS services.  Using this
 	  interface is potentially dangerous because the PNPBIOS driver will
-	  not be notified of any resource changes made by writting directly.
+	  not be notified of any resource changes made by writing directly.
 	  Also some buggy systems will fault when accessing certain features
 	  in the PNPBIOS /proc interface (e.g. "boot" configs).
 
diff -Nru a/drivers/pnp/pnpbios/core.c b/drivers/pnp/pnpbios/core.c
--- a/drivers/pnp/pnpbios/core.c	2005-03-01 23:38:51 -08:00
+++ b/drivers/pnp/pnpbios/core.c	2005-03-01 23:38:51 -08:00
@@ -61,6 +61,7 @@
 #include <linux/spinlock.h>
 #include <linux/dmi.h>
 #include <linux/delay.h>
+#include <linux/acpi.h>
 
 #include <asm/page.h>
 #include <asm/desc.h>
@@ -538,10 +539,10 @@
 		return -ENODEV;
 	}
 
-#ifdef CONFIG_ACPI
-	if (!acpi_disabled) {
+#ifdef CONFIG_PNPACPI
+	if (!acpi_disabled && !pnpacpi_disabled) {
 		pnpbios_disabled = 1;
-		printk(KERN_INFO "PnPBIOS: Disabled by ACPI\n");
+		printk(KERN_INFO "PnPBIOS: Disabled by ACPI PNP\n");
 		return -ENODEV;
 	}
 #endif /* CONFIG_ACPI */
diff -Nru a/drivers/pnp/pnpbios/rsparser.c b/drivers/pnp/pnpbios/rsparser.c
--- a/drivers/pnp/pnpbios/rsparser.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/pnp/pnpbios/rsparser.c	2005-03-01 23:38:55 -08:00
@@ -7,7 +7,12 @@
 #include <linux/ctype.h>
 #include <linux/pnp.h>
 #include <linux/pnpbios.h>
+
+#ifdef CONFIG_PCI
 #include <linux/pci.h>
+#else
+inline void pcibios_penalize_isa_irq(int irq) {}
+#endif /* CONFIG_PCI */
 
 #include "pnpbios.h"
 
diff -Nru a/drivers/s390/Kconfig b/drivers/s390/Kconfig
--- a/drivers/s390/Kconfig	2005-03-01 23:39:09 -08:00
+++ b/drivers/s390/Kconfig	2005-03-01 23:39:09 -08:00
@@ -162,7 +162,7 @@
 	  devices using the block device interface.  This interface is similar
 	  to CD-ROM devices on other platforms.  The tapes can only be
 	  accessed read-only when using this interface.  Have a look at
-	  Documentation/s390/TAPE for further information about creating
+	  <file:Documentation/s390/TAPE> for further information about creating
 	  volumes for and using this interface.  It is safe to say "Y" here.
 
 comment "S/390 tape hardware support"
diff -Nru a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
--- a/drivers/s390/block/dasd.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/s390/block/dasd.c	2005-03-01 23:38:56 -08:00
@@ -7,7 +7,7 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999-2001
  *
- * $Revision: 1.151 $
+ * $Revision: 1.156 $
  */
 
 #include <linux/config.h>
@@ -179,7 +179,7 @@
 	device->debug_area = debug_register(device->cdev->dev.bus_id, 0, 2,
 					    8 * sizeof (long));
 	debug_register_view(device->debug_area, &debug_sprintf_view);
-	debug_set_level(device->debug_area, DBF_ERR);
+	debug_set_level(device->debug_area, DBF_EMERG);
 	DBF_DEV_EVENT(DBF_EMERG, device, "%s", "debug area created");
 
 	device->state = DASD_STATE_BASIC;
@@ -520,10 +520,6 @@
 	if ( magic == NULL || datasize > PAGE_SIZE ||
 	     (cplength*sizeof(struct ccw1)) > PAGE_SIZE)
 		BUG();
-	debug_text_event ( dasd_debug_area, 1, "ALLC");
-	debug_text_event ( dasd_debug_area, 1, magic);
-	debug_int_event ( dasd_debug_area, 1, cplength);
-	debug_int_event ( dasd_debug_area, 1, datasize);
 
 	cqr = kmalloc(sizeof(struct dasd_ccw_req), GFP_ATOMIC);
 	if (cqr == NULL)
@@ -570,10 +566,6 @@
 	if ( magic == NULL || datasize > PAGE_SIZE ||
 	     (cplength*sizeof(struct ccw1)) > PAGE_SIZE)
 		BUG();
-	debug_text_event ( dasd_debug_area, 1, "ALLC");
-	debug_text_event ( dasd_debug_area, 1, magic);
-	debug_int_event ( dasd_debug_area, 1, cplength);
-	debug_int_event ( dasd_debug_area, 1, datasize);
 
 	size = (sizeof(struct dasd_ccw_req) + 7L) & -8L;
 	if (cplength > 0)
@@ -623,8 +615,6 @@
 		clear_normalized_cda(ccw);
 	} while (ccw++->flags & (CCW_FLAG_CC | CCW_FLAG_DC));
 #endif
-	debug_text_event ( dasd_debug_area, 1, "FREE");
-	debug_int_event ( dasd_debug_area, 1, (long) cqr);
 	if (cqr->cpaddr != NULL)
 		kfree(cqr->cpaddr);
 	if (cqr->data != NULL)
@@ -638,8 +628,6 @@
 {
 	unsigned long flags;
 
-	debug_text_event(dasd_debug_area, 1, "FREE");
-	debug_int_event(dasd_debug_area, 1, (long) cqr);
 	spin_lock_irqsave(&device->mem_lock, flags);
 	dasd_free_chunk(&device->ccw_chunks, cqr);
 	spin_unlock_irqrestore(&device->mem_lock, flags);
@@ -696,6 +684,9 @@
 			} else
 				cqr->status = DASD_CQR_FAILED;
 			cqr->stopclk = get_clock();
+			DBF_DEV_EVENT(DBF_DEBUG, device,
+				      "terminate cqr %p successful",
+				      cqr);
 			break;
 		case -ENODEV:
 			DBF_DEV_EVENT(DBF_ERR, device, "%s",
@@ -754,6 +745,9 @@
 	switch (rc) {
 	case 0:
 		cqr->status = DASD_CQR_IN_IO;
+		DBF_DEV_EVENT(DBF_DEBUG, device,
+			      "start_IO: request %p started successful",
+			      cqr);
 		break;
 	case -EBUSY:
 		DBF_DEV_EVENT(DBF_ERR, device, "%s",
@@ -964,8 +958,8 @@
 			cdev->dev.bus_id, cqr->status);
 		return;
 	}
-	DBF_DEV_EVENT(DBF_DEBUG, device, "Int: CS/DS 0x%04x",
-		      ((irb->scsw.cstat << 8) | irb->scsw.dstat));
+	DBF_DEV_EVENT(DBF_DEBUG, device, "Int: CS/DS 0x%04x for cqr %p",
+		      ((irb->scsw.cstat << 8) | irb->scsw.dstat), cqr);
 
  	/* Find out the appropriate era_action. */
 	if (irb->scsw.fctl & SCSW_FCTL_HALT_FUNC) 
@@ -1080,7 +1074,8 @@
 				cqr->stopclk = get_clock();
 			} else {
 				if (cqr->irb.esw.esw0.erw.cons) {
-					erp_fn = device->discipline->erp_action(cqr);
+					erp_fn = device->discipline->
+						erp_action(cqr);
 					erp_fn(cqr);
 				} else
 					dasd_default_erp_action(cqr);
@@ -1153,10 +1148,9 @@
 		req = elv_next_request(queue);
 		if (test_bit(DASD_FLAG_RO, &device->flags) &&
 		    rq_data_dir(req) == WRITE) {
-			DBF_EVENT(DBF_ERR,
-				  "(%s) Rejecting write request %p",
-				  device->cdev->dev.bus_id,
-				  req);
+			DBF_DEV_EVENT(DBF_ERR, device,
+				      "Rejecting write request %p",
+				      req);
 			blkdev_dequeue_request(req);
 			dasd_end_request(req, 0);
 			continue;
@@ -1170,10 +1164,10 @@
 		if (IS_ERR(cqr)) {
 			if (PTR_ERR(cqr) == -ENOMEM)
 				break;	/* terminate request queue loop */
-			DBF_EVENT(DBF_ERR,
-				  "(%s) CCW creation failed on request %p",
-				  device->cdev->dev.bus_id,
-				  req);
+			DBF_DEV_EVENT(DBF_ERR, device,
+				      "CCW creation failed (rc=%ld) "
+				      "on request %p",
+				      PTR_ERR(cqr), req);
 			blkdev_dequeue_request(req);
 			dasd_end_request(req, 0);
 			continue;
@@ -1586,25 +1580,26 @@
 }
 
 /*
- * Allocate and initialize request queue.
+ * Allocate and initialize request queue and default I/O scheduler.
  */
 static int
 dasd_alloc_queue(struct dasd_device * device)
 {
+	int rc;
+
 	device->request_queue = blk_init_queue(do_dasd_request,
 					       &device->request_queue_lock);
 	if (device->request_queue == NULL)
 		return -ENOMEM;
 
 	device->request_queue->queuedata = device;
-#if 0
+
 	elevator_exit(device->request_queue->elevator);
-	rc = elevator_init(device->request_queue, "noop");
+	rc = elevator_init(device->request_queue, "deadline");
 	if (rc) {
 		blk_cleanup_queue(device->request_queue);
 		return rc;
 	}
-#endif
 	return 0;
 }
 
@@ -1678,9 +1673,8 @@
 	}
 
 	if (dasd_probeonly) {
-		MESSAGE(KERN_INFO,
-			"No access to device %s due to probeonly mode",
-			disk->disk_name);
+		DEV_MESSAGE(KERN_INFO, device, "%s",
+			    "No access to device due to probeonly mode");
 		rc = -EPERM;
 		goto out;
 	}
@@ -1970,8 +1964,8 @@
 		rc = -ENOMEM;
 		goto failed;
 	}
-	debug_register_view(dasd_debug_area, &debug_hex_ascii_view);
-	debug_set_level(dasd_debug_area, DBF_ERR);
+	debug_register_view(dasd_debug_area, &debug_sprintf_view);
+	debug_set_level(dasd_debug_area, DBF_EMERG);
 
 	DBF_EVENT(DBF_EMERG, "%s", "debug area created");
 
diff -Nru a/drivers/s390/block/dasd_3990_erp.c b/drivers/s390/block/dasd_3990_erp.c
--- a/drivers/s390/block/dasd_3990_erp.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/s390/block/dasd_3990_erp.c	2005-03-01 23:39:09 -08:00
@@ -5,7 +5,7 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2000, 2001
  *
- * $Revision: 1.34 $
+ * $Revision: 1.36 $
  */
 
 #include <linux/timer.h>
@@ -20,9 +20,9 @@
 
 
 struct DCTL_data {
-	unsigned char subcommand;	/* e.g Inhibit Write, Enable Write,... */
-	unsigned char modifier;	/* Subcommand modifier		       */
-	unsigned short res;	/* reserved */
+	unsigned char subcommand;  /* e.g Inhibit Write, Enable Write,... */
+	unsigned char modifier;	   /* Subcommand modifier */
+	unsigned short res;	   /* reserved */
 } __attribute__ ((packed));
 
 /*
@@ -422,7 +422,8 @@
  *   Setup ERP to do the ERP action 4 (see Reference manual).
  *   Set the current request to PENDING to block the CQR queue for that device
  *   until the state change interrupt appears.
- *   Use a timer (20 seconds) to retry the cqr if the interrupt is still missing.
+ *   Use a timer (20 seconds) to retry the cqr if the interrupt is still
+ *   missing.
  *
  *  PARAMETER
  *   sense		sense data of the actual error
@@ -443,9 +444,8 @@
 	/* interrupt (this enables easier enqueing of the cqr)	    */
 	if (erp->function != dasd_3990_erp_action_4) {
 
-		DEV_MESSAGE(KERN_INFO, device,
-			    "dasd_3990_erp_action_4: first time retry"
-			    "%s", " ");
+		DEV_MESSAGE(KERN_INFO, device, "%s",
+			    "dasd_3990_erp_action_4: first time retry");
 
 		erp->retries = 256;
 		erp->function = dasd_3990_erp_action_4;
@@ -826,7 +826,7 @@
 		}
 		break;
 
-	case 0x50:		/* Format 5 - Data Check with displacement information */
+	case 0x50:  /* Format 5 - Data Check with displacement information */
 		switch (msg_no) {
 		case 0x00:
 			DEV_MESSAGE(KERN_WARNING, device, "%s",
@@ -871,7 +871,7 @@
 		}
 		break;
 
-	case 0x60:		/* Format 6 - Usage Statistics/Overrun Errors */
+	case 0x60:  /* Format 6 - Usage Statistics/Overrun Errors */
 		switch (msg_no) {
 		case 0x00:
 			DEV_MESSAGE(KERN_WARNING, device, "%s",
@@ -911,7 +911,7 @@
 		}
 		break;
 
-	case 0x70:		/* Format 7 - Device Connection Control Checks */
+	case 0x70:  /* Format 7 - Device Connection Control Checks */
 		switch (msg_no) {
 		case 0x00:
 			DEV_MESSAGE(KERN_WARNING, device, "%s",
@@ -988,7 +988,7 @@
 		}
 		break;
 
-	case 0x80:		/* Format 8 - Additional Device Equipment Checks */
+	case 0x80:  /* Format 8 - Additional Device Equipment Checks */
 		switch (msg_no) {
 		case 0x00:	/* No Message */
 		case 0x01:
@@ -1041,7 +1041,7 @@
 		}
 		break;
 
-	case 0x90:		/* Format 9 - Device Read, Write, and Seek Checks */
+	case 0x90:  /* Format 9 - Device Read, Write, and Seek Checks */
 		switch (msg_no) {
 		case 0x00:
 			break;	/* No Message */
@@ -2159,7 +2159,7 @@
 			erp = dasd_3990_erp_int_req(erp);
 			break;
 
-		case 0x0F:	/* length mismatch during update write command */
+		case 0x0F:  /* length mismatch during update write command */
 			DEV_MESSAGE(KERN_ERR, device, "%s",
 				    "update write command error - should not "
 				    "happen;\n"
@@ -2170,7 +2170,7 @@
 			erp = dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED);
 			break;
 
-		case 0x10:	/* logging required for other channel program */
+		case 0x10:  /* logging required for other channel program */
 			erp = dasd_3990_erp_action_10_32(erp, sense);
 			break;
 
@@ -2197,8 +2197,8 @@
 
 			/* not possible to handle this situation in Linux */
 			panic
-			    ("Invalid data - No way to inform appliction about "
-			     "the possibly incorret data");
+			    ("Invalid data - No way to inform application "
+			     "about the possibly incorrect data");
 			break;
 
 		case 0x1D:	/* state-change pending */
@@ -2263,11 +2263,10 @@
 		/* inspect the 32 byte sense data */
 		erp_new = dasd_3990_erp_inspect_32(erp, sense);
 
-	}			/* end distinguish between 24 and 32 byte sense data */
+	}	/* end distinguish between 24 and 32 byte sense data */
 
 	return erp_new;
-
-}				/* END dasd_3990_erp_inspect */
+}
 
 /*
  * DASD_3990_ERP_ADD_ERP
@@ -2520,7 +2519,8 @@
 		erp = dasd_3990_erp_compound(erp, sense);
 
 	} else {
-		/* no retry left and no additional special handling necessary */
+		/* No retry left and no additional special handling */
+		/*necessary */
 		DEV_MESSAGE(KERN_ERR, device,
 			    "no retries left for erp %p - "
 			    "set status to FAILED", erp);
diff -Nru a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c
--- a/drivers/s390/block/dasd_devmap.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/s390/block/dasd_devmap.c	2005-03-01 23:38:57 -08:00
@@ -11,7 +11,7 @@
  * functions may not be called from interrupt context. In particular
  * dasd_get_device is a no-no from interrupt context.
  *
- * $Revision: 1.34 $
+ * $Revision: 1.37 $
  */
 
 #include <linux/config.h>
@@ -70,11 +70,10 @@
  * strings when running as a module.
  */
 static char *dasd[256];
-
 /*
  * Single spinlock to protect devmap structures and lists.
  */
-static spinlock_t dasd_devmap_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(dasd_devmap_lock);
 
 /*
  * Hash lists for devmap structures.
@@ -485,7 +484,8 @@
 
 	devmap = dasd_find_busid(cdev->dev.bus_id);
 	if (IS_ERR(devmap))
-		devmap = dasd_add_busid(cdev->dev.bus_id, DASD_FEATURE_DEFAULT);
+		devmap = dasd_add_busid(cdev->dev.bus_id,
+					DASD_FEATURE_DEFAULT);
 	return devmap;
 }
 
@@ -553,6 +553,8 @@
 
 	/* First remove device pointer from devmap. */
 	devmap = dasd_find_busid(device->cdev->dev.bus_id);
+	if (IS_ERR(devmap))
+		BUG();
 	spin_lock(&dasd_devmap_lock);
 	if (devmap->device != device) {
 		spin_unlock(&dasd_devmap_lock);
@@ -626,8 +628,8 @@
 	struct dasd_devmap *devmap;
 	int ro_flag;
 
-	devmap = dev->driver_data;
-	if (devmap)
+	devmap = dasd_find_busid(dev->bus_id);
+	if (!IS_ERR(devmap))
 		ro_flag = (devmap->features & DASD_FEATURE_READONLY) != 0;
 	else
 		ro_flag = (DASD_FEATURE_DEFAULT & DASD_FEATURE_READONLY) != 0;
@@ -641,6 +643,8 @@
 	int ro_flag;
 
 	devmap = dasd_devmap_from_cdev(to_ccwdev(dev));
+	if (IS_ERR(devmap))
+		return PTR_ERR(devmap);
 	ro_flag = buf[0] == '1';
 	spin_lock(&dasd_devmap_lock);
 	if (ro_flag)
@@ -665,15 +669,14 @@
  * use_diag controls whether the driver should use diag rather than ssch
  * to talk to the device
  */
-/* TODO: Implement */
 static ssize_t 
 dasd_use_diag_show(struct device *dev, char *buf)
 {
 	struct dasd_devmap *devmap;
 	int use_diag;
 
-	devmap = dev->driver_data;
-	if (devmap)
+	devmap = dasd_find_busid(dev->bus_id);
+	if (!IS_ERR(devmap))
 		use_diag = (devmap->features & DASD_FEATURE_USEDIAG) != 0;
 	else
 		use_diag = (DASD_FEATURE_DEFAULT & DASD_FEATURE_USEDIAG) != 0;
@@ -684,21 +687,25 @@
 dasd_use_diag_store(struct device *dev, const char *buf, size_t count)
 {
 	struct dasd_devmap *devmap;
+	ssize_t rc;
 	int use_diag;
 
 	devmap = dasd_devmap_from_cdev(to_ccwdev(dev));
+	if (IS_ERR(devmap))
+		return PTR_ERR(devmap);
 	use_diag = buf[0] == '1';
 	spin_lock(&dasd_devmap_lock);
 	/* Changing diag discipline flag is only allowed in offline state. */
+	rc = count;
 	if (!devmap->device) {
 		if (use_diag)
 			devmap->features |= DASD_FEATURE_USEDIAG;
 		else
 			devmap->features &= ~DASD_FEATURE_USEDIAG;
 	} else
-		count = -EPERM;
+		rc = -EPERM;
 	spin_unlock(&dasd_devmap_lock);
-	return count;
+	return rc;
 }
 
 static
diff -Nru a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c
--- a/drivers/s390/block/dasd_diag.c	2005-03-01 23:38:51 -08:00
+++ b/drivers/s390/block/dasd_diag.c	2005-03-01 23:38:51 -08:00
@@ -6,7 +6,7 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
  *
- * $Revision: 1.39 $
+ * $Revision: 1.42 $
  */
 
 #include <linux/config.h>
@@ -138,7 +138,7 @@
 
 	rc = dia250(&private->iob, RW_BIO);
 	if (rc > 8) {
-		MESSAGE(KERN_WARNING, "dia250 returned CC %d", rc);
+		DEV_MESSAGE(KERN_WARNING, device, "dia250 returned CC %d", rc);
 		cqr->status = DASD_CQR_ERROR;
 	} else if (rc == 0) {
 		cqr->status = DASD_CQR_DONE;
@@ -201,8 +201,9 @@
 				if (dasd_start_diag(next) == 0)
 					expires = next->expires;
 				else
-					MESSAGE(KERN_WARNING, "%s",
-						"Interrupt fastpath failed!");
+					DEV_MESSAGE(KERN_WARNING, device, "%s",
+						    "Interrupt fastpath "
+						    "failed!");
 			}
 		}
 	} else 
@@ -231,7 +232,7 @@
 	if (private == NULL) {
 		private = kmalloc(sizeof(struct dasd_diag_private),GFP_KERNEL);
 		if (private == NULL) {
-			MESSAGE(KERN_WARNING, "%s",
+			DEV_MESSAGE(KERN_WARNING, device, "%s",
 				"memory allocation failed for private data");
 			return -ENOMEM;
 		}
@@ -258,11 +259,11 @@
 		return -ENOTSUPP;
 	}
 
-	DBF_EVENT(DBF_INFO,
-		  "%04X: %04X on real %04X/%02X",
-		  rdc_data->dev_nr,
-		  rdc_data->vdev_type,
-		  rdc_data->rdev_type, rdc_data->rdev_model);
+	DBF_DEV_EVENT(DBF_INFO, device,
+		      "%04X: %04X on real %04X/%02X",
+		      rdc_data->dev_nr,
+		      rdc_data->vdev_type,
+		      rdc_data->rdev_type, rdc_data->rdev_model);
 
 	/* terminate all outstanding operations */
 	mdsk_term_io(device);
@@ -270,10 +271,11 @@
 	/* figure out blocksize of device */
 	label = (long *) get_zeroed_page(GFP_KERNEL);
 	if (label == NULL)  {
-		MESSAGE(KERN_WARNING, "%s",
-			"No memory to allocate initialization request");
+		DEV_MESSAGE(KERN_WARNING, device, "%s",
+			    "No memory to allocate initialization request");
 		return -ENOMEM;
 	}
+	/* try all sizes - needed for ECKD devices */
 	for (bsize = 512; bsize <= PAGE_SIZE; bsize <<= 1) {
 		mdsk_init_io(device, bsize, 0, 64);
 		memset(&bio, 0, sizeof (struct dasd_diag_bio));
@@ -291,8 +293,9 @@
 			break;
 		mdsk_term_io(device);
 	}
-	if (bsize <= PAGE_SIZE && label[3] == bsize &&
-	    label[0] == 0xc3d4e2f1) {
+	if (bsize <= PAGE_SIZE && label[0] == 0xc3d4e2f1) {
+		/* get formatted blocksize from label block */
+		bsize = (int) label[3];
 		device->blocks = label[7];
 		device->bp_block = bsize;
 		device->s2b_shift = 0;	/* bits to shift 512 to get a block */
@@ -305,8 +308,12 @@
 			    (device->blocks << device->s2b_shift) >> 1);
 		rc = 0;
 	} else {
-		DEV_MESSAGE(KERN_WARNING, device, "%s",
-			    "volume has incompatible disk layout");
+		if (bsize > PAGE_SIZE)
+			DEV_MESSAGE(KERN_WARNING, device, "%s",
+				    "DIAG access failed");
+		else
+			DEV_MESSAGE(KERN_WARNING, device, "%s",
+				    "volume is not CMS formatted");
 		rc = -EMEDIUMTYPE;
 	}
 	free_page((long) label);
@@ -445,20 +452,8 @@
 dasd_diag_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req,
 		     struct irb *stat)
 {
-	char *page;
-
-	page = (char *) get_zeroed_page(GFP_KERNEL);
-	if (page == NULL) {
-		MESSAGE(KERN_ERR, "%s", "No memory to dump sense data");
-		return;
-	}
-	sprintf(page, KERN_WARNING PRINTK_HEADER
-		"device %s: I/O status report:\n",
-		device->cdev->dev.bus_id);
-
-	MESSAGE(KERN_ERR, "Sense data:\n%s", page);
-
-	free_page((unsigned long) page);
+	DEV_MESSAGE(KERN_ERR, device, "%s",
+		    "dump sense not available for DIAG data");
 }
 
 /*
@@ -494,9 +489,10 @@
 dasd_diag_init(void)
 {
 	if (!MACHINE_IS_VM) {
-		MESSAGE(KERN_INFO,
-			"Machine is not VM: %s discipline not initializing",
-			dasd_diag_discipline.name);
+		MESSAGE_LOG(KERN_INFO,
+			    "Machine is not VM: %s "
+			    "discipline not initializing",
+			    dasd_diag_discipline.name);
 		return -EINVAL;
 	}
 	ASCEBC(dasd_diag_discipline.ebcname, 4);
@@ -511,9 +507,10 @@
 dasd_diag_cleanup(void)
 {
 	if (!MACHINE_IS_VM) {
-		MESSAGE(KERN_INFO,
-			"Machine is not VM: %s discipline not initializing",
-			dasd_diag_discipline.name);
+		MESSAGE_LOG(KERN_INFO,
+			    "Machine is not VM: %s "
+			    "discipline not cleaned",
+			    dasd_diag_discipline.name);
 		return;
 	}
 	unregister_external_interrupt(0x2603, dasd_ext_handler);
diff -Nru a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
--- a/drivers/s390/block/dasd_eckd.c	2005-03-01 23:38:44 -08:00
+++ b/drivers/s390/block/dasd_eckd.c	2005-03-01 23:38:44 -08:00
@@ -7,7 +7,7 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
  *
- * $Revision: 1.65 $
+ * $Revision: 1.68 $
  */
 
 #include <linux/config.h>
@@ -37,9 +37,12 @@
 
 #define ECKD_C0(i) (i->home_bytes)
 #define ECKD_F(i) (i->formula)
-#define ECKD_F1(i) (ECKD_F(i)==0x01?(i->factors.f_0x01.f1):(i->factors.f_0x02.f1))
-#define ECKD_F2(i) (ECKD_F(i)==0x01?(i->factors.f_0x01.f2):(i->factors.f_0x02.f2))
-#define ECKD_F3(i) (ECKD_F(i)==0x01?(i->factors.f_0x01.f3):(i->factors.f_0x02.f3))
+#define ECKD_F1(i) (ECKD_F(i)==0x01?(i->factors.f_0x01.f1):\
+		    (i->factors.f_0x02.f1))
+#define ECKD_F2(i) (ECKD_F(i)==0x01?(i->factors.f_0x01.f2):\
+		    (i->factors.f_0x02.f2))
+#define ECKD_F3(i) (ECKD_F(i)==0x01?(i->factors.f_0x01.f3):\
+		    (i->factors.f_0x02.f3))
 #define ECKD_F4(i) (ECKD_F(i)==0x02?(i->factors.f_0x02.f4):0)
 #define ECKD_F5(i) (ECKD_F(i)==0x02?(i->factors.f_0x02.f5):0)
 #define ECKD_F6(i) (i->factor6)
@@ -151,7 +154,6 @@
 		bpr = fl1 + fl2;
 		break;
 	default:
-		MESSAGE(KERN_ERR, "unknown formula%d", rdc->formula);
 		bpr = 0;
 		break;
 	}
@@ -209,8 +211,8 @@
         /* switch on System Time Stamp - needed for XRC Support */
         if (private->rdc_data.facilities.XRC_supported) {
                 
-                data->ga_extended |= 0x08;   /* switch on 'Time Stamp Valid'   */
-                data->ga_extended |= 0x02;   /* switch on 'Extended Parameter' */
+                data->ga_extended |= 0x08; /* switch on 'Time Stamp Valid'   */
+                data->ga_extended |= 0x02; /* switch on 'Extended Parameter' */
                 
                 data->ep_sys_time = get_clock ();
                 
@@ -272,7 +274,7 @@
                 check_XRC (ccw, data, device);
 		break;
 	default:
-		MESSAGE(KERN_ERR, "unknown opcode 0x%x", cmd);
+		DEV_MESSAGE(KERN_ERR, device, "unknown opcode 0x%x", cmd);
 		break;
 	}
 
@@ -318,7 +320,7 @@
 				
 	private = (struct dasd_eckd_private *) device->private;
 
-	DBF_EVENT(DBF_INFO,
+	DBF_DEV_EVENT(DBF_INFO, device,
 		  "Locate: trk %d, rec %d, no_rec %d, cmd %d, reclen %d",
 		  trk, rec_on_trk, no_rec, cmd, reclen);
 
@@ -400,7 +402,7 @@
 		data->operation.operation = 0x0b;
 		break;
 	default:
-		MESSAGE(KERN_ERR, "unknown opcode 0x%x", cmd);
+		DEV_MESSAGE(KERN_ERR, device, "unknown opcode 0x%x", cmd);
 	}
 	data->seek_addr.cyl = data->search_arg.cyl =
 		trk / private->rdc_data.trk_per_cyl;
@@ -458,8 +460,9 @@
 		private = kmalloc(sizeof(struct dasd_eckd_private),
 				  GFP_KERNEL | GFP_DMA);
 		if (private == NULL) {
-			MESSAGE(KERN_WARNING, "%s",
-				"memory allocation failed for private data");
+			DEV_MESSAGE(KERN_WARNING, device, "%s",
+				    "memory allocation failed for private "
+				    "data");
 			return -ENOMEM;
 		}
 		device->private = (void *) private;
@@ -474,8 +477,9 @@
 	rdc_data = (void *) &(private->rdc_data);
 	rc = read_dev_chars(device->cdev, &rdc_data, 64);
 	if (rc) {
-		MESSAGE(KERN_WARNING,
-			"Read device characteristics returned error %d", rc);
+		DEV_MESSAGE(KERN_WARNING, device,
+			    "Read device characteristics returned error %d",
+			    rc);
 		return rc;
 	}
 
@@ -492,19 +496,20 @@
 	/* Read Configuration Data */
 	rc = read_conf_data(device->cdev, &conf_data, &conf_len);
 	if (rc && rc != -EOPNOTSUPP) {	/* -EOPNOTSUPP is ok */
-		MESSAGE(KERN_WARNING,
-			"Read configuration data returned error %d", rc);
+		DEV_MESSAGE(KERN_WARNING, device,
+			    "Read configuration data returned error %d", rc);
 		return rc;
 	}
 	if (conf_data == NULL) {
-		MESSAGE(KERN_WARNING, "%s", "No configuration data retrieved");
+		DEV_MESSAGE(KERN_WARNING, device, "%s",
+			    "No configuration data retrieved");
 		return 0;	/* no errror */
 	}
 	if (conf_len != sizeof (struct dasd_eckd_confdata)) {
-		MESSAGE(KERN_WARNING,
-			"sizes of configuration data mismatch"
-			"%d (read) vs %ld (expected)",
-			conf_len, sizeof (struct dasd_eckd_confdata));
+		DEV_MESSAGE(KERN_WARNING, device,
+			    "sizes of configuration data mismatch"
+			    "%d (read) vs %ld (expected)",
+			    conf_len, sizeof (struct dasd_eckd_confdata));
 
 		kfree(conf_data); /* allocated by read_conf_data() */
 		return 0;	/* no errror */
@@ -746,8 +751,9 @@
 		return ERR_PTR(-EINVAL);
 	}
 	if (dasd_check_blocksize(fdata->blksize) != 0) {
-		MESSAGE(KERN_WARNING, "Invalid blocksize %d...terminating!",
-			fdata->blksize);
+		DEV_MESSAGE(KERN_WARNING, device,
+			    "Invalid blocksize %d...terminating!",
+			    fdata->blksize);
 		return ERR_PTR(-EINVAL);
 	}
 
@@ -783,7 +789,8 @@
 			sizeof(struct eckd_count);
 		break;
 	default:
-		MESSAGE(KERN_WARNING, "Invalid flags 0x%x.", fdata->intensity);
+		DEV_MESSAGE(KERN_WARNING, device, "Invalid flags 0x%x.",
+			    fdata->intensity);
 		return ERR_PTR(-EINVAL);
 	}
 	/* Allocate the format ccw request. */
@@ -918,8 +925,8 @@
 		return dasd_9343_erp_examine(cqr, irb);
 	case 0x3880:
 	default:
-		MESSAGE(KERN_WARNING, "%s",
-			"default (unknown CU type) - RECOVERABLE return");
+		DEV_MESSAGE(KERN_WARNING, device, "%s",
+			    "default (unknown CU type) - RECOVERABLE return");
 		return dasd_era_recover;
 	}
 }
@@ -937,7 +944,6 @@
 	case 0x1750:
 		return dasd_3990_erp_action;
 	case 0x9343:
-		/* Return dasd_9343_erp_action; */
 	case 0x3880:
 	default:
 		return dasd_default_erp_action;
@@ -995,7 +1001,8 @@
 				return ERR_PTR(-EINVAL);
 			count += bv->bv_len >> (device->s2b_shift + 9);
 #if defined(CONFIG_ARCH_S390X)
-			if (idal_is_needed (page_address(bv->bv_page), bv->bv_len))
+			if (idal_is_needed (page_address(bv->bv_page),
+					    bv->bv_len))
 				cidaw += bv->bv_len >> (device->s2b_shift + 9);
 #endif
 		}
@@ -1192,10 +1199,10 @@
 
 	cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
 				   1, 32, device);
-	if (cqr == NULL) {
-		MESSAGE(KERN_WARNING, "%s",
-			"No memory to allocate initialization request");
-		return -ENOMEM;
+	if (IS_ERR(cqr)) {
+		DEV_MESSAGE(KERN_WARNING, device, "%s",
+			    "Could not allocate initialization request");
+		return PTR_ERR(cqr);
 	}
 	cqr->cpaddr->cmd_code = DASD_ECKD_CCW_RELEASE;
         cqr->cpaddr->flags |= CCW_FLAG_SLI;
@@ -1236,10 +1243,10 @@
 
 	cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
 				   1, 32, device);
-	if (cqr == NULL) {
-		MESSAGE(KERN_WARNING, "%s",
-			"No memory to allocate initialization request");
-		return -ENOMEM;
+	if (IS_ERR(cqr)) {
+		DEV_MESSAGE(KERN_WARNING, device, "%s",
+			    "Could not allocate initialization request");
+		return PTR_ERR(cqr);
 	}
 	cqr->cpaddr->cmd_code = DASD_ECKD_CCW_RESERVE;
         cqr->cpaddr->flags |= CCW_FLAG_SLI;
@@ -1279,10 +1286,10 @@
 
 	cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
 				   1, 32, device);
-	if (cqr == NULL) {
-		MESSAGE(KERN_WARNING, "%s",
-			"No memory to allocate initialization request");
-		return -ENOMEM;
+	if (IS_ERR(cqr)) {
+		DEV_MESSAGE(KERN_WARNING, device, "%s",
+			    "Could not allocate initialization request");
+		return PTR_ERR(cqr);
 	}
 	cqr->cpaddr->cmd_code = DASD_ECKD_CCW_SLCK;
         cqr->cpaddr->flags |= CCW_FLAG_SLI;
@@ -1323,10 +1330,10 @@
 				   (sizeof (struct dasd_psf_prssd_data) +
 				    sizeof (struct dasd_rssd_perf_stats_t)),
 				   device);
-	if (cqr == NULL) {
-		MESSAGE(KERN_WARNING, "%s",
-			"No memory to allocate initialization request");
-		return -ENOMEM;
+	if (IS_ERR(cqr)) {
+		DEV_MESSAGE(KERN_WARNING, device, "%s",
+			    "Could not allocate initialization request");
+		return PTR_ERR(cqr);
 	}
 	cqr->device = device;
 	cqr->retries = 0;
@@ -1422,58 +1429,47 @@
 			   sizeof (struct attrib_data_t))) {
 		return -EFAULT;
 	}
-
 	private = (struct dasd_eckd_private *) device->private;
-
 	private->attrib = attrib;
 
-	DBF_DEV_EVENT(DBF_ERR, device,
-		      "cache operation mode set to "
-		      "%x (%i cylinder prestage)",
-		      private->attrib.operation, private->attrib.nr_cyl);
-	
+	DEV_MESSAGE(KERN_INFO, device,
+		    "cache operation mode set to %x (%i cylinder prestage)",
+		    private->attrib.operation, private->attrib.nr_cyl);
 	return 0;
 }
 
+/*
+ * Print sense data and related channel program.
+ * Parts are printed because printk buffer is only 1024 bytes.
+ */
 static void
 dasd_eckd_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req,
 		     struct irb *irb)
 {
-
 	char *page;
-	struct ccw1 *act;
-	int len, sl, sct;
+	struct ccw1 *act, *end, *last;
+	int len, sl, sct, count;
 
 	page = (char *) get_zeroed_page(GFP_ATOMIC);
 	if (page == NULL) {
-		MESSAGE(KERN_ERR, "%s", "No memory to dump sense data");
+		DEV_MESSAGE(KERN_ERR, device, " %s",
+			    "No memory to dump sense data");
 		return;
 	}
 	len = sprintf(page, KERN_ERR PRINTK_HEADER
-		      "device %s: I/O status report:\n",
+		      " I/O status report for device %s:\n",
 		      device->cdev->dev.bus_id);
 	len += sprintf(page + len, KERN_ERR PRINTK_HEADER
-		       "in req: %p CS: 0x%02X DS: 0x%02X\n", req,
+		       " in req: %p CS: 0x%02X DS: 0x%02X\n", req,
 		       irb->scsw.cstat, irb->scsw.dstat);
 	len += sprintf(page + len, KERN_ERR PRINTK_HEADER
-		       "Failing CCW: %p\n", 
+		       " device %s: Failing CCW: %p\n",
+		       device->cdev->dev.bus_id,
 		       (void *) (addr_t) irb->scsw.cpa);
-	act = req->cpaddr;
-	do {
-		DBF_EVENT(DBF_INFO,
-			  "CCW %p: %08X %08X",
-			  act, ((int *) act)[0], ((int *) act)[1]);
-		DBF_EVENT(DBF_INFO,
-			  "DAT: %08X %08X %08X %08X",
-			  ((int *) (addr_t) act->cda)[0],
-			  ((int *) (addr_t) act->cda)[1],
-			  ((int *) (addr_t) act->cda)[2],
-			  ((int *) (addr_t) act->cda)[3]);
-	} while (act++->flags & (CCW_FLAG_CC | CCW_FLAG_DC));
 	if (irb->esw.esw0.erw.cons) {
 		for (sl = 0; sl < 4; sl++) {
 			len += sprintf(page + len, KERN_ERR PRINTK_HEADER
-				       "Sense(hex) %2d-%2d:",
+				       " Sense(hex) %2d-%2d:",
 				       (8 * sl), ((8 * sl) + 7));
 
 			for (sct = 0; sct < 8; sct++) {
@@ -1486,23 +1482,86 @@
 		if (irb->ecw[27] & DASD_SENSE_BIT_0) {
 			/* 24 Byte Sense Data */
 			len += sprintf(page + len, KERN_ERR PRINTK_HEADER
-				       "24 Byte: %x MSG %x, %s MSGb to SYSOP\n",
+				       " 24 Byte: %x MSG %x, "
+				       "%s MSGb to SYSOP\n",
 				       irb->ecw[7] >> 4, irb->ecw[7] & 0x0f,
 				       irb->ecw[1] & 0x10 ? "" : "no");
 		} else {
 			/* 32 Byte Sense Data */
 			len += sprintf(page + len, KERN_ERR PRINTK_HEADER
-				       "32 Byte: Format: %x "
+				       " 32 Byte: Format: %x "
 				       "Exception class %x\n",
 				       irb->ecw[6] & 0x0f, irb->ecw[22] >> 4);
 		}
 	} else {
 	        len += sprintf(page + len, KERN_ERR PRINTK_HEADER
-			       "SORRY - NO VALID SENSE AVAILABLE\n");
+			       " SORRY - NO VALID SENSE AVAILABLE\n");
 	}
+	MESSAGE_LOG(KERN_ERR, "%s",
+		    page + sizeof(KERN_ERR PRINTK_HEADER));
 
-	MESSAGE(KERN_ERR, "Sense data:\n%s", page);
-
+	/* dump the Channel Program */
+	/* print first CCWs (maximum 8) */
+	act = req->cpaddr;
+        for (last = act; last->flags & (CCW_FLAG_CC | CCW_FLAG_DC); last++);
+	end = min(act + 8, last);
+	len = sprintf(page, KERN_ERR PRINTK_HEADER
+		      " Related CP in req: %p\n", req);
+	while (act <= end) {
+		len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+			       " CCW %p: %08X %08X DAT:",
+			       act, ((int *) act)[0], ((int *) act)[1]);
+		for (count = 0; count < 32 && count < act->count;
+		     count += sizeof(int))
+			len += sprintf(page + len, " %08X",
+				       ((int *) (addr_t) act->cda)
+				       [(count>>2)]);
+		len += sprintf(page + len, "\n");
+		act++;
+	}
+	MESSAGE_LOG(KERN_ERR, "%s",
+		    page + sizeof(KERN_ERR PRINTK_HEADER));
+
+	/* print failing CCW area */
+	len = 0;
+	if (act <  ((struct ccw1 *)(addr_t) irb->scsw.cpa) - 2) {
+		act = ((struct ccw1 *)(addr_t) irb->scsw.cpa) - 2;
+		len += sprintf(page + len, KERN_ERR PRINTK_HEADER "......\n");
+	}
+	end = min((struct ccw1 *)(addr_t) irb->scsw.cpa + 2, last);
+	while (act <= end) {
+		len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+			       " CCW %p: %08X %08X DAT:",
+			       act, ((int *) act)[0], ((int *) act)[1]);
+		for (count = 0; count < 32 && count < act->count;
+		     count += sizeof(int))
+			len += sprintf(page + len, " %08X",
+				       ((int *) (addr_t) act->cda)
+				       [(count>>2)]);
+		len += sprintf(page + len, "\n");
+		act++;
+	}
+
+	/* print last CCWs */
+	if (act <  last - 2) {
+		act = last - 2;
+		len += sprintf(page + len, KERN_ERR PRINTK_HEADER "......\n");
+	}
+	while (act <= last) {
+		len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+			       " CCW %p: %08X %08X DAT:",
+			       act, ((int *) act)[0], ((int *) act)[1]);
+		for (count = 0; count < 32 && count < act->count;
+		     count += sizeof(int))
+			len += sprintf(page + len, " %08X",
+				       ((int *) (addr_t) act->cda)
+				       [(count>>2)]);
+		len += sprintf(page + len, "\n");
+		act++;
+	}
+	if (len > 0)
+		MESSAGE_LOG(KERN_ERR, "%s",
+			    page + sizeof(KERN_ERR PRINTK_HEADER));
 	free_page((unsigned long) page);
 }
 
diff -Nru a/drivers/s390/block/dasd_eckd.h b/drivers/s390/block/dasd_eckd.h
--- a/drivers/s390/block/dasd_eckd.h	2005-03-01 23:38:56 -08:00
+++ b/drivers/s390/block/dasd_eckd.h	2005-03-01 23:38:56 -08:00
@@ -5,15 +5,15 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
  *
- * $Revision: 1.8 $
+ * $Revision: 1.9 $
  */
 
 #ifndef DASD_ECKD_H
 #define DASD_ECKD_H
 
-/*******************************************************************************
+/*****************************************************************************
  * SECTION: CCW Definitions
- ******************************************************************************/
+ ****************************************************************************/
 #define DASD_ECKD_CCW_WRITE		 0x05
 #define DASD_ECKD_CCW_READ		 0x06
 #define DASD_ECKD_CCW_WRITE_HOME_ADDRESS 0x09
@@ -45,9 +45,9 @@
  */
 #define PSF_ORDER_PRSSD			 0x18
 
-/*******************************************************************************
+/*****************************************************************************
  * SECTION: Type Definitions
- ******************************************************************************/
+ ****************************************************************************/
 
 struct eckd_count {
 	__u16 cyl;
@@ -112,7 +112,7 @@
 	__u8 ga_extended;	/* Global Attributes Extended	*/
 	struct ch_t beg_ext;
 	struct ch_t end_ext;
-	unsigned long long ep_sys_time; /* Extended Parameter - System Time Stamp */
+	unsigned long long ep_sys_time; /* Ext Parameter - System Time Stamp */
 	__u8 ep_format;        /* Extended Parameter format byte       */
 	__u8 ep_prio;          /* Extended Parameter priority I/O byte */
 	__u8 ep_reserved[6];   /* Extended Parameter Reserved          */
diff -Nru a/drivers/s390/block/dasd_erp.c b/drivers/s390/block/dasd_erp.c
--- a/drivers/s390/block/dasd_erp.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/s390/block/dasd_erp.c	2005-03-01 23:38:52 -08:00
@@ -7,7 +7,7 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999-2001
  *
- * $Revision: 1.12 $
+ * $Revision: 1.13 $
  */
 
 #include <linux/config.h>
@@ -36,10 +36,6 @@
 	if ( magic == NULL || datasize > PAGE_SIZE ||
 	     (cplength*sizeof(struct ccw1)) > PAGE_SIZE)
 		BUG();
-	debug_text_event ( dasd_debug_area, 1, "ALLC");
-	debug_text_event ( dasd_debug_area, 1, magic);
-	debug_int_event ( dasd_debug_area, 1, cplength);
-	debug_int_event ( dasd_debug_area, 1, datasize);
 
 	size = (sizeof(struct dasd_ccw_req) + 7L) & -8L;
 	if (cplength > 0)
@@ -77,8 +73,6 @@
 {
 	unsigned long flags;
 
-	debug_text_event(dasd_debug_area, 1, "FREE");
-	debug_int_event(dasd_debug_area, 1, (long) cqr);
 	spin_lock_irqsave(&device->mem_lock, flags);
 	dasd_free_chunk(&device->erp_chunks, cqr);
 	spin_unlock_irqrestore(&device->mem_lock, flags);
@@ -105,7 +99,6 @@
         } else {
                 DEV_MESSAGE (KERN_WARNING, device, "%s",
 			     "default ERP called (NO retry left)");
-		
 		cqr->status = DASD_CQR_FAILED;
 		cqr->stopclk = get_clock ();
         }
diff -Nru a/drivers/s390/block/dasd_fba.c b/drivers/s390/block/dasd_fba.c
--- a/drivers/s390/block/dasd_fba.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/s390/block/dasd_fba.c	2005-03-01 23:39:07 -08:00
@@ -4,7 +4,7 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
  *
- * $Revision: 1.37 $
+ * $Revision: 1.39 $
  */
 
 #include <linux/config.h>
@@ -134,8 +134,9 @@
 	if (private == NULL) {
 		private = kmalloc(sizeof(struct dasd_fba_private), GFP_KERNEL);
 		if (private == NULL) {
-			MESSAGE(KERN_WARNING, "%s",
-				"memory allocation failed for private data");
+			DEV_MESSAGE(KERN_WARNING, device, "%s",
+				    "memory allocation failed for private "
+				    "data");
 			return -ENOMEM;
 		}
 		device->private = (void *) private;
@@ -144,8 +145,9 @@
 	rdc_data = (void *) &(private->rdc_data);
 	rc = read_dev_chars(device->cdev, &rdc_data, 32);
 	if (rc) {
-		MESSAGE(KERN_WARNING,
-			"Read device characteristics returned error %d", rc);
+		DEV_MESSAGE(KERN_WARNING, device,
+			    "Read device characteristics returned error %d",
+			    rc);
 		return rc;
 	}
 
@@ -227,8 +229,8 @@
 	if (cqr->function == dasd_default_erp_action)
 		return dasd_default_erp_postaction;
 
-	MESSAGE(KERN_WARNING, "unknown ERP action %p", cqr->function);
-
+	DEV_MESSAGE(KERN_WARNING, cqr->device, "unknown ERP action %p",
+		    cqr->function);
 	return NULL;
 }
 
@@ -270,7 +272,8 @@
 				return ERR_PTR(-EINVAL);
 			count += bv->bv_len >> (device->s2b_shift + 9);
 #if defined(CONFIG_ARCH_S390X)
-			if (idal_is_needed (page_address(bv->bv_page), bv->bv_len))
+			if (idal_is_needed (page_address(bv->bv_page),
+					    bv->bv_len))
 				cidaw += bv->bv_len / blksize;
 #endif
 		}
@@ -423,18 +426,107 @@
 		    struct irb *irb)
 {
 	char *page;
+	struct ccw1 *act, *end, *last;
+	int len, sl, sct, count;
 
-	page = (char *) get_zeroed_page(GFP_KERNEL);
+	page = (char *) get_zeroed_page(GFP_ATOMIC);
 	if (page == NULL) {
-		MESSAGE(KERN_ERR, "%s", "No memory to dump sense data");
+		DEV_MESSAGE(KERN_ERR, device, " %s",
+			    "No memory to dump sense data");
 		return;
 	}
-	sprintf(page, KERN_WARNING PRINTK_HEADER
-		"device %s: I/O status report:\n",
-		device->cdev->dev.bus_id);
+	len = sprintf(page, KERN_ERR PRINTK_HEADER
+		      " I/O status report for device %s:\n",
+		      device->cdev->dev.bus_id);
+	len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+		       " in req: %p CS: 0x%02X DS: 0x%02X\n", req,
+		       irb->scsw.cstat, irb->scsw.dstat);
+	len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+		       " device %s: Failing CCW: %p\n",
+		       device->cdev->dev.bus_id,
+		       (void *) (addr_t) irb->scsw.cpa);
+	if (irb->esw.esw0.erw.cons) {
+		for (sl = 0; sl < 4; sl++) {
+			len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+				       " Sense(hex) %2d-%2d:",
+				       (8 * sl), ((8 * sl) + 7));
+
+			for (sct = 0; sct < 8; sct++) {
+				len += sprintf(page + len, " %02x",
+					       irb->ecw[8 * sl + sct]);
+			}
+			len += sprintf(page + len, "\n");
+		}
+	} else {
+	        len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+			       " SORRY - NO VALID SENSE AVAILABLE\n");
+	}
+	MESSAGE_LOG(KERN_ERR, "%s",
+		    page + sizeof(KERN_ERR PRINTK_HEADER));
+
+	/* dump the Channel Program */
+	/* print first CCWs (maximum 8) */
+	act = req->cpaddr;
+        for (last = act; last->flags & (CCW_FLAG_CC | CCW_FLAG_DC); last++);
+	end = min(act + 8, last);
+	len = sprintf(page, KERN_ERR PRINTK_HEADER
+		      " Related CP in req: %p\n", req);
+	while (act <= end) {
+		len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+			       " CCW %p: %08X %08X DAT:",
+			       act, ((int *) act)[0], ((int *) act)[1]);
+		for (count = 0; count < 32 && count < act->count;
+		     count += sizeof(int))
+			len += sprintf(page + len, " %08X",
+				       ((int *) (addr_t) act->cda)
+				       [(count>>2)]);
+		len += sprintf(page + len, "\n");
+		act++;
+	}
+	MESSAGE_LOG(KERN_ERR, "%s",
+		    page + sizeof(KERN_ERR PRINTK_HEADER));
 
-	MESSAGE(KERN_ERR, "Sense data:\n%s", page);
 
+	/* print failing CCW area */
+	len = 0;
+	if (act <  ((struct ccw1 *)(addr_t) irb->scsw.cpa) - 2) {
+		act = ((struct ccw1 *)(addr_t) irb->scsw.cpa) - 2;
+		len += sprintf(page + len, KERN_ERR PRINTK_HEADER "......\n");
+	}
+	end = min((struct ccw1 *)(addr_t) irb->scsw.cpa + 2, last);
+	while (act <= end) {
+		len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+			       " CCW %p: %08X %08X DAT:",
+			       act, ((int *) act)[0], ((int *) act)[1]);
+		for (count = 0; count < 32 && count < act->count;
+		     count += sizeof(int))
+			len += sprintf(page + len, " %08X",
+				       ((int *) (addr_t) act->cda)
+				       [(count>>2)]);
+		len += sprintf(page + len, "\n");
+		act++;
+	}
+
+	/* print last CCWs */
+	if (act <  last - 2) {
+		act = last - 2;
+		len += sprintf(page + len, KERN_ERR PRINTK_HEADER "......\n");
+	}
+	while (act <= last) {
+		len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+			       " CCW %p: %08X %08X DAT:",
+			       act, ((int *) act)[0], ((int *) act)[1]);
+		for (count = 0; count < 32 && count < act->count;
+		     count += sizeof(int))
+			len += sprintf(page + len, " %08X",
+				       ((int *) (addr_t) act->cda)
+				       [(count>>2)]);
+		len += sprintf(page + len, "\n");
+		act++;
+	}
+	if (len > 0)
+		MESSAGE_LOG(KERN_ERR, "%s",
+			    page + sizeof(KERN_ERR PRINTK_HEADER));
 	free_page((unsigned long) page);
 }
 
diff -Nru a/drivers/s390/block/dasd_genhd.c b/drivers/s390/block/dasd_genhd.c
--- a/drivers/s390/block/dasd_genhd.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/s390/block/dasd_genhd.c	2005-03-01 23:39:08 -08:00
@@ -149,8 +149,8 @@
 	 * Can't call delete_partitions directly. Use ioctl.
 	 * The ioctl also does locking and invalidation.
 	 */
-	memset(&bpart, sizeof(struct blkpg_partition), 0);
-	memset(&barg, sizeof(struct blkpg_ioctl_arg), 0);
+	memset(&bpart, 0, sizeof(struct blkpg_partition));
+	memset(&barg, 0, sizeof(struct blkpg_ioctl_arg));
 	barg.data = &bpart;
 	barg.op = BLKPG_DEL_PARTITION;
 	for (bpart.pno = device->gdp->minors - 1; bpart.pno > 0; bpart.pno--)
diff -Nru a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h
--- a/drivers/s390/block/dasd_int.h	2005-03-01 23:39:08 -08:00
+++ b/drivers/s390/block/dasd_int.h	2005-03-01 23:39:08 -08:00
@@ -6,7 +6,7 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
  *
- * $Revision: 1.61 $
+ * $Revision: 1.63 $
  */
 
 #ifndef DASD_INT_H
@@ -150,6 +150,18 @@
 	DBF_EVENT(DBF_ALERT, d_string, d_args); \
 } while(0)
 
+/* messages to be written via klogd only */
+#define DEV_MESSAGE_LOG(d_loglevel,d_device,d_string,d_args...)\
+do { \
+	printk(d_loglevel PRINTK_HEADER " %s: " d_string "\n", \
+	       d_device->cdev->dev.bus_id, d_args); \
+} while(0)
+
+#define MESSAGE_LOG(d_loglevel,d_string,d_args...)\
+do { \
+	printk(d_loglevel PRINTK_HEADER " " d_string "\n", d_args); \
+} while(0)
+
 struct dasd_ccw_req {
 	unsigned int magic;		/* Eye catcher */
         struct list_head list;		/* list_head for request queueing. */
@@ -520,7 +532,8 @@
 /* externals in dasd_erp.c */
 struct dasd_ccw_req *dasd_default_erp_action(struct dasd_ccw_req *);
 struct dasd_ccw_req *dasd_default_erp_postaction(struct dasd_ccw_req *);
-struct dasd_ccw_req *dasd_alloc_erp_request(char *, int, int, struct dasd_device *);
+struct dasd_ccw_req *dasd_alloc_erp_request(char *, int, int,
+					    struct dasd_device *);
 void dasd_free_erp_request(struct dasd_ccw_req *, struct dasd_device *);
 void dasd_log_sense(struct dasd_ccw_req *, struct irb *);
 void dasd_log_ccw(struct dasd_ccw_req *, int, __u32);
diff -Nru a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c
--- a/drivers/s390/block/dasd_ioctl.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/s390/block/dasd_ioctl.c	2005-03-01 23:38:58 -08:00
@@ -257,8 +257,9 @@
 		      fdata->stop_unit, fdata->blksize, fdata->intensity);
 
 	/* Since dasdfmt keeps the device open after it was disabled,
-	 * there still exists an inode for this device. We must update i_blkbits,
-	 * otherwise we might get errors when enabling the device later.
+	 * there still exists an inode for this device.
+	 * We must update i_blkbits, otherwise we might get errors when
+	 * enabling the device later.
 	 */
 	if (fdata->start_unit == 0) {
 		struct block_device *bdev = bdget_disk(device->gdp, 0);
diff -Nru a/drivers/s390/block/dasd_proc.c b/drivers/s390/block/dasd_proc.c
--- a/drivers/s390/block/dasd_proc.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/s390/block/dasd_proc.c	2005-03-01 23:38:53 -08:00
@@ -9,7 +9,7 @@
  *
  * /proc interface for the dasd driver.
  *
- * $Revision: 1.27 $
+ * $Revision: 1.30 $
  */
 
 #include <linux/config.h>
@@ -248,7 +248,9 @@
 	if (user_len > 65536)
 		user_len = 65536;
 	buffer = dasd_get_user_string(user_buf, user_len);
-	MESSAGE(KERN_INFO, "/proc/dasd/statictics: '%s'", buffer);
+	if (IS_ERR(buffer))
+		return PTR_ERR(buffer);
+	MESSAGE_LOG(KERN_INFO, "/proc/dasd/statictics: '%s'", buffer);
 
 	/* check for valid verbs */
 	for (str = buffer; isspace(*str); str++);
@@ -258,20 +260,20 @@
 		if (strcmp(str, "on") == 0) {
 			/* switch on statistics profiling */
 			dasd_profile_level = DASD_PROFILE_ON;
-			MESSAGE(KERN_INFO, "%s", "Statictics switched on");
+			MESSAGE(KERN_INFO, "%s", "Statistics switched on");
 		} else if (strcmp(str, "off") == 0) {
 			/* switch off and reset statistics profiling */
 			memset(&dasd_global_profile,
 			       0, sizeof (struct dasd_profile_info_t));
 			dasd_profile_level = DASD_PROFILE_OFF;
-			MESSAGE(KERN_INFO, "%s", "Statictics switched off");
+			MESSAGE(KERN_INFO, "%s", "Statistics switched off");
 		} else
 			goto out_error;
 	} else if (strncmp(str, "reset", 5) == 0) {
 		/* reset the statistics */
 		memset(&dasd_global_profile, 0,
 		       sizeof (struct dasd_profile_info_t));
-		MESSAGE(KERN_INFO, "%s", "Statictics reset");
+		MESSAGE(KERN_INFO, "%s", "Statistics reset");
 	} else
 		goto out_error;
 	kfree(buffer);
diff -Nru a/drivers/s390/char/Makefile b/drivers/s390/char/Makefile
--- a/drivers/s390/char/Makefile	2005-03-01 23:38:56 -08:00
+++ b/drivers/s390/char/Makefile	2005-03-01 23:38:56 -08:00
@@ -11,7 +11,7 @@
 
 obj-$(CONFIG_TN3215) += con3215.o
 
-obj-$(CONFIG_SCLP) += sclp.o sclp_rw.o
+obj-$(CONFIG_SCLP) += sclp.o sclp_rw.o sclp_quiesce.o
 obj-$(CONFIG_SCLP_TTY) += sclp_tty.o
 obj-$(CONFIG_SCLP_CONSOLE) += sclp_con.o
 obj-$(CONFIG_SCLP_VT220_TTY) += sclp_vt220.o
diff -Nru a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c
--- a/drivers/s390/char/con3215.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/s390/char/con3215.c	2005-03-01 23:39:07 -08:00
@@ -102,7 +102,7 @@
 /* array of 3215 devices structures */
 static struct raw3215_info *raw3215[NR_3215];
 /* spinlock to protect the raw3215 array */
-static spinlock_t raw3215_device_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(raw3215_device_lock);
 /* list of free request structures */
 static struct raw3215_req *raw3215_freelist;
 /* spinlock to protect free list */
diff -Nru a/drivers/s390/char/con3270.c b/drivers/s390/char/con3270.c
--- a/drivers/s390/char/con3270.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/s390/char/con3270.c	2005-03-01 23:38:52 -08:00
@@ -73,10 +73,12 @@
 con3270_set_timer(struct con3270 *cp, int expires)
 {
 	if (expires == 0) {
-		del_timer(&cp->timer);
+		if (timer_pending(&cp->timer))
+			del_timer(&cp->timer);
 		return;
 	}
-	if (mod_timer(&cp->timer, jiffies + expires))
+	if (timer_pending(&cp->timer) &&
+	    mod_timer(&cp->timer, jiffies + expires))
 		return;
 	cp->timer.function = (void (*)(unsigned long)) con3270_update;
 	cp->timer.data = (unsigned long) cp;
diff -Nru a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c
--- a/drivers/s390/char/sclp.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/s390/char/sclp.c	2005-03-01 23:39:07 -08:00
@@ -8,82 +8,99 @@
  *		 Martin Schwidefsky <schwidefsky@de.ibm.com>
  */
 
-#include <linux/config.h>
 #include <linux/module.h>
-#include <linux/kmod.h>
-#include <linux/bootmem.h>
 #include <linux/err.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
 #include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/cpumask.h>
 #include <linux/reboot.h>
+#include <linux/jiffies.h>
+#include <asm/types.h>
 #include <asm/s390_ext.h>
-#include <asm/processor.h>
 
 #include "sclp.h"
 
-#define SCLP_CORE_PRINT_HEADER "sclp low level driver: "
+#define SCLP_HEADER		"sclp: "
 
 /* Structure for register_early_external_interrupt. */
 static ext_int_info_t ext_int_info_hwc;
 
-/* spinlock to protect global variables of sclp_core */
-static spinlock_t sclp_lock;
+/* Lock to protect internal data consistency. */
+static DEFINE_SPINLOCK(sclp_lock);
 
-/* Mask of valid sclp events */
+/* Mask of events that we can receive from the sclp interface. */
 static sccb_mask_t sclp_receive_mask;
+
+/* Mask of events that we can send to the sclp interface. */
 static sccb_mask_t sclp_send_mask;
 
-/* List of registered event types */
+/* List of registered event listeners and senders. */
 static struct list_head sclp_reg_list;
 
-/* sccb queue */
+/* List of queued requests. */
 static struct list_head sclp_req_queue;
 
-/* sccb for unconditional read */
+/* Data for read and and init requests. */
 static struct sclp_req sclp_read_req;
+static struct sclp_req sclp_init_req;
 static char sclp_read_sccb[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE)));
-/* sccb for write mask sccb */
 static char sclp_init_sccb[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE)));
 
-/* Timer for init mask retries. */
-static struct timer_list retry_timer;
+/* Timer for request retries. */
+static struct timer_list sclp_request_timer;
 
-/* Timer for busy retries. */
-static struct timer_list sclp_busy_timer;
+/* Internal state: is the driver initialized? */
+static volatile enum sclp_init_state_t {
+	sclp_init_state_uninitialized,
+	sclp_init_state_initializing,
+	sclp_init_state_initialized
+} sclp_init_state = sclp_init_state_uninitialized;
+
+/* Internal state: is a request active at the sclp? */
+static volatile enum sclp_running_state_t {
+	sclp_running_state_idle,
+	sclp_running_state_running
+} sclp_running_state = sclp_running_state_idle;
+
+/* Internal state: is a read request pending? */
+static volatile enum sclp_reading_state_t {
+	sclp_reading_state_idle,
+	sclp_reading_state_reading
+} sclp_reading_state = sclp_reading_state_idle;
+
+/* Internal state: is the driver currently serving requests? */
+static volatile enum sclp_activation_state_t {
+	sclp_activation_state_active,
+	sclp_activation_state_deactivating,
+	sclp_activation_state_inactive,
+	sclp_activation_state_activating
+} sclp_activation_state = sclp_activation_state_active;
+
+/* Internal state: is an init mask request pending? */
+static volatile enum sclp_mask_state_t {
+	sclp_mask_state_idle,
+	sclp_mask_state_initializing
+} sclp_mask_state = sclp_mask_state_idle;
+
+/* Maximum retry counts */
+#define SCLP_INIT_RETRY		3
+#define SCLP_MASK_RETRY		3
+#define SCLP_REQUEST_RETRY	3
+
+/* Timeout intervals in seconds.*/
+#define SCLP_BUSY_INTERVAL	2
+#define SCLP_RETRY_INTERVAL	5
+
+static void sclp_process_queue(void);
+static int sclp_init_mask(int calculate);
+static int sclp_init(void);
 
-static volatile unsigned long sclp_status = 0;
-/* some status flags */
-#define SCLP_INIT		0
-#define SCLP_RUNNING		1
-#define SCLP_READING		2
-#define SCLP_SHUTDOWN		3
-
-#define SCLP_INIT_POLL_INTERVAL	1
-#define SCLP_BUSY_POLL_INTERVAL	1
-
-#define SCLP_COMMAND_INITIATED	0
-#define SCLP_BUSY		2
-#define SCLP_NOT_OPERATIONAL	3
-
-/*
- * assembler instruction for Service Call
- */
+/* Perform service call. Return 0 on success, non-zero otherwise. */
 static int
-__service_call(sclp_cmdw_t command, void *sccb)
+service_call(sclp_cmdw_t command, void *sccb)
 {
 	int cc;
 
-	/*
-	 *  Mnemonic:	SERVC	Rx, Ry	[RRE]
-	 *
-	 *  Rx: SCLP command word
-	 *  Ry: address of SCCB
-	 */
 	__asm__ __volatile__(
 		"   .insn rre,0xb2200000,%1,%2\n"  /* servc %1,%2 */
 		"   ipm	  %0\n"
@@ -91,61 +108,94 @@
 		: "=&d" (cc)
 		: "d" (command), "a" (__pa(sccb))
 		: "cc", "memory" );
-	/*
-	 * cc == 0:   Service Call succesful initiated
-	 * cc == 2:   SCLP busy, new Service Call not initiated,
-	 *	      new SCCB unchanged
-	 * cc == 3:   SCLP function not operational
-	 */
-	if (cc == SCLP_NOT_OPERATIONAL)
+	if (cc == 3)
 		return -EIO;
-	if (cc == SCLP_BUSY)
+	if (cc == 2)
 		return -EBUSY;
 	return 0;
 }
 
+/* Request timeout handler. Restart the request queue. If DATA is non-zero,
+ * force restart of running request. */
+static void
+sclp_request_timeout(unsigned long data)
+{
+	unsigned long flags;
+
+	if (data) {
+		spin_lock_irqsave(&sclp_lock, flags);
+		sclp_running_state = sclp_running_state_idle;
+		spin_unlock_irqrestore(&sclp_lock, flags);
+	}
+	sclp_process_queue();
+}
+
+/* Set up request retry timer. Called while sclp_lock is locked. */
+static inline void
+__sclp_set_request_timer(unsigned long time, void (*function)(unsigned long),
+			 unsigned long data)
+{
+	del_timer(&sclp_request_timer);
+	sclp_request_timer.function = function;
+	sclp_request_timer.data = data;
+	sclp_request_timer.expires = jiffies + time;
+	add_timer(&sclp_request_timer);
+}
+
+/* Try to start a request. Return zero if the request was successfully
+ * started or if it will be started at a later time. Return non-zero otherwise.
+ * Called while sclp_lock is locked. */
+static int
+__sclp_start_request(struct sclp_req *req)
+{
+	int rc;
+
+	if (sclp_running_state != sclp_running_state_idle)
+		return 0;
+	del_timer(&sclp_request_timer);
+	if (req->start_count <= SCLP_REQUEST_RETRY) {
+		rc = service_call(req->command, req->sccb);
+		req->start_count++;
+	} else
+		rc = -EIO;
+	if (rc == 0) {
+		/* Sucessfully started request */
+		req->status = SCLP_REQ_RUNNING;
+		sclp_running_state = sclp_running_state_running;
+		__sclp_set_request_timer(SCLP_RETRY_INTERVAL * HZ,
+					 sclp_request_timeout, 1);
+		return 0;
+	} else if (rc == -EBUSY) {
+		/* Try again later */
+		__sclp_set_request_timer(SCLP_BUSY_INTERVAL * HZ,
+					 sclp_request_timeout, 0);
+		return 0;
+	}
+	/* Request failed */
+	req->status = SCLP_REQ_FAILED;
+	return rc;
+}
+
+/* Try to start queued requests. */
 static void
-sclp_start_request(void)
+sclp_process_queue(void)
 {
 	struct sclp_req *req;
 	int rc;
 	unsigned long flags;
 
 	spin_lock_irqsave(&sclp_lock, flags);
-	/* quick exit if sclp is already in use */
-	if (test_bit(SCLP_RUNNING, &sclp_status)) {
+	if (sclp_running_state != sclp_running_state_idle) {
 		spin_unlock_irqrestore(&sclp_lock, flags);
 		return;
 	}
-	/* Try to start requests from the request queue. */
+	del_timer(&sclp_request_timer);
 	while (!list_empty(&sclp_req_queue)) {
 		req = list_entry(sclp_req_queue.next, struct sclp_req, list);
-		rc = __service_call(req->command, req->sccb);
-		if (rc == 0) {
-			/* Sucessfully started request. */
-			req->status = SCLP_REQ_RUNNING;
-			/* Request active. Set running indication. */
-			set_bit(SCLP_RUNNING, &sclp_status);
-			break;
-		}
-		if (rc == -EBUSY) {
-			/**
-			 * SCLP is busy but no request is running.
-			 * Try again later.
-			 */
-			if (!timer_pending(&sclp_busy_timer) ||
-			    !mod_timer(&sclp_busy_timer,
-				       jiffies + SCLP_BUSY_POLL_INTERVAL*HZ)) {
-				sclp_busy_timer.function =
-					(void *) sclp_start_request;
-				sclp_busy_timer.expires =
-					jiffies + SCLP_BUSY_POLL_INTERVAL*HZ;
-				add_timer(&sclp_busy_timer);
-			}
+		rc = __sclp_start_request(req);
+		if (rc == 0)
 			break;
-		}
 		/* Request failed. */
-		req->status = SCLP_REQ_FAILED;
 		list_del(&req->list);
 		if (req->callback) {
 			spin_unlock_irqrestore(&sclp_lock, flags);
@@ -156,265 +206,258 @@
 	spin_unlock_irqrestore(&sclp_lock, flags);
 }
 
+/* Queue a new request. Return zero on success, non-zero otherwise. */
+int
+sclp_add_request(struct sclp_req *req)
+{
+	unsigned long flags;
+	int rc;
+
+	spin_lock_irqsave(&sclp_lock, flags);
+	if ((sclp_init_state != sclp_init_state_initialized ||
+	     sclp_activation_state != sclp_activation_state_active) &&
+	    req != &sclp_init_req) {
+		spin_unlock_irqrestore(&sclp_lock, flags);
+		return -EIO;
+	}
+	req->status = SCLP_REQ_QUEUED;
+	req->start_count = 0;
+	list_add_tail(&req->list, &sclp_req_queue);
+	rc = 0;
+	/* Start if request is first in list */
+	if (req->list.prev == &sclp_req_queue) {
+		rc = __sclp_start_request(req);
+		if (rc)
+			list_del(&req->list);
+	}
+	spin_unlock_irqrestore(&sclp_lock, flags);
+	return rc;
+}
+
+EXPORT_SYMBOL(sclp_add_request);
+
+/* Dispatch events found in request buffer to registered listeners. Return 0
+ * if all events were dispatched, non-zero otherwise. */
 static int
-sclp_process_evbufs(struct sccb_header *sccb)
+sclp_dispatch_evbufs(struct sccb_header *sccb)
 {
-	int result;
 	unsigned long flags;
 	struct evbuf_header *evbuf;
 	struct list_head *l;
-	struct sclp_register *t;
+	struct sclp_register *reg;
+	int offset;
+	int rc;
 
 	spin_lock_irqsave(&sclp_lock, flags);
-	evbuf = (struct evbuf_header *) (sccb + 1);
-	result = 0;
-	while ((addr_t) evbuf < (addr_t) sccb + sccb->length) {
-		/* check registered event */
-		t = NULL;
+	rc = 0;
+	for (offset = sizeof(struct sccb_header); offset < sccb->length;
+	     offset += evbuf->length) {
+		/* Search for event handler */
+		evbuf = (struct evbuf_header *) ((addr_t) sccb + offset);
+		reg = NULL;
 		list_for_each(l, &sclp_reg_list) {
-			t = list_entry(l, struct sclp_register, list);
-			if (t->receive_mask & (1 << (32 - evbuf->type))) {
-				if (t->receiver_fn != NULL) {
-					spin_unlock_irqrestore(&sclp_lock,
-							       flags);
-					t->receiver_fn(evbuf);
-					spin_lock_irqsave(&sclp_lock, flags);
-				}
+			reg = list_entry(l, struct sclp_register, list);
+			if (reg->receive_mask & (1 << (32 - evbuf->type)))
 				break;
-			}
 			else
-				t = NULL;
+				reg = NULL;
 		}
-		/* Check for unrequested event buffer */
-		if (t == NULL)
-			result = -ENOSYS;
-		evbuf = (struct evbuf_header *)
-				((addr_t) evbuf + evbuf->length);
+		if (reg && reg->receiver_fn) {
+			spin_unlock_irqrestore(&sclp_lock, flags);
+			reg->receiver_fn(evbuf);
+			spin_lock_irqsave(&sclp_lock, flags);
+		} else if (reg == NULL)
+			rc = -ENOSYS;
 	}
 	spin_unlock_irqrestore(&sclp_lock, flags);
-	return result;
+	return rc;
 }
 
-char *
-sclp_error_message(u16 rc)
-{
-	static struct {
-		u16 code; char *msg;
-	} sclp_errors[] = {
-		{ 0x0000, "No response code stored (machine malfunction)" },
-		{ 0x0020, "Normal Completion" },
-		{ 0x0040, "SCLP equipment check" },
-		{ 0x0100, "SCCB boundary violation" },
-		{ 0x01f0, "Invalid command" },
-		{ 0x0220, "Normal Completion; suppressed buffers pending" },
-		{ 0x0300, "Insufficient SCCB length" },
-		{ 0x0340, "Contained SCLP equipment check" },
-		{ 0x05f0, "Target resource in improper state" },
-		{ 0x40f0, "Invalid function code/not installed" },
-		{ 0x60f0, "No buffers stored" },
-		{ 0x62f0, "No buffers stored; suppressed buffers pending" },
-		{ 0x70f0, "Invalid selection mask" },
-		{ 0x71f0, "Event buffer exceeds available space" },
-		{ 0x72f0, "Inconsistent lengths" },
-		{ 0x73f0, "Event buffer syntax error" }
-	};
-	int i;
-	for (i = 0; i < sizeof(sclp_errors)/sizeof(sclp_errors[0]); i++)
-		if (rc == sclp_errors[i].code)
-			return sclp_errors[i].msg;
-	return "Invalid response code";
-}
-
-/*
- * postprocessing of unconditional read service call
- */
+/* Read event data request callback. */
 static void
-sclp_unconditional_read_cb(struct sclp_req *read_req, void *data)
+sclp_read_cb(struct sclp_req *req, void *data)
 {
+	unsigned long flags;
 	struct sccb_header *sccb;
 
-	sccb = read_req->sccb;
-	if (sccb->response_code == 0x0020 ||
-	    sccb->response_code == 0x0220) {
-		if (sclp_process_evbufs(sccb) != 0)
-			printk(KERN_WARNING SCLP_CORE_PRINT_HEADER
-			       "unconditional read: "
-			       "unrequested event buffer received.\n");
-	}
-
-	if (sccb->response_code != 0x0020)
-		printk(KERN_WARNING SCLP_CORE_PRINT_HEADER
-		       "unconditional read: %s (response code=0x%x).\n",
-		       sclp_error_message(sccb->response_code),
-		       sccb->response_code);
-
-	clear_bit(SCLP_READING, &sclp_status);
-}
-
-/*
- * Function to queue Read Event Data/Unconditional Read
- */
-static void
-__sclp_unconditional_read(void)
+	sccb = (struct sccb_header *) req->sccb;
+	if (req->status == SCLP_REQ_DONE && (sccb->response_code == 0x20 ||
+	    sccb->response_code == 0x220))
+		sclp_dispatch_evbufs(sccb);
+	spin_lock_irqsave(&sclp_lock, flags);
+	sclp_reading_state = sclp_reading_state_idle;
+	spin_unlock_irqrestore(&sclp_lock, flags);
+}
+
+/* Prepare read event data request. Called while sclp_lock is locked. */
+static inline void
+__sclp_make_read_req(void)
 {
 	struct sccb_header *sccb;
-	struct sclp_req *read_req;
 
-	/*
-	 * Don't try to initiate Unconditional Read if we are not able to
-	 * receive anything
-	 */
-	if (sclp_receive_mask == 0)
-		return;
-	/* Don't try reading if a read is already outstanding */
-	if (test_and_set_bit(SCLP_READING, &sclp_status))
-		return;
-	/* Initialize read sccb */
 	sccb = (struct sccb_header *) sclp_read_sccb;
 	clear_page(sccb);
+	memset(&sclp_read_req, 0, sizeof(struct sclp_req));
+	sclp_read_req.command = SCLP_CMDW_READDATA;
+	sclp_read_req.status = SCLP_REQ_QUEUED;
+	sclp_read_req.start_count = 0;
+	sclp_read_req.callback = sclp_read_cb;
+	sclp_read_req.sccb = sccb;
 	sccb->length = PAGE_SIZE;
-	sccb->function_code = 0;	/* unconditional read */
-	sccb->control_mask[2] = 0x80;	/* variable length response */
-	/* Initialize request structure */
-	read_req = &sclp_read_req;
-	read_req->command = SCLP_CMDW_READDATA;
-	read_req->status = SCLP_REQ_QUEUED;
-	read_req->callback = sclp_unconditional_read_cb;
-	read_req->sccb = sccb;
-	/* Add read request to the head of queue */
-	list_add(&read_req->list, &sclp_req_queue);
-}
-
-/* Bit masks to interpret external interruption parameter contents. */
-#define EXT_INT_SCCB_MASK		0xfffffff8
-#define EXT_INT_STATECHANGE_PENDING	0x00000002
-#define EXT_INT_EVBUF_PENDING		0x00000001
-
-/*
- * Handler for service-signal external interruptions
- */
+	sccb->function_code = 0;
+	sccb->control_mask[2] = 0x80;
+}
+
+/* Search request list for request with matching sccb. Return request if found,
+ * NULL otherwise. Called while sclp_lock is locked. */
+static inline struct sclp_req *
+__sclp_find_req(u32 sccb)
+{
+	struct list_head *l;
+	struct sclp_req *req;
+
+	list_for_each(l, &sclp_req_queue) {
+		req = list_entry(l, struct sclp_req, list);
+		if (sccb == (u32) (addr_t) req->sccb)
+				return req;
+	}
+	return NULL;
+}
+
+/* Handler for external interruption. Perform request post-processing.
+ * Prepare read event data request if necessary. Start processing of next
+ * request on queue. */
 static void
 sclp_interrupt_handler(struct pt_regs *regs, __u16 code)
 {
-	u32 ext_int_param, finished_sccb, evbuf_pending;
-	struct list_head *l;
-	struct sclp_req *req, *tmp;
+	struct sclp_req *req;
+	u32 finished_sccb;
+	u32 evbuf_pending;
 
 	spin_lock(&sclp_lock);
-	/*
-	 * Only process interrupt if sclp is initialized.
-	 * This avoids strange effects for a pending request
-	 * from before the last re-ipl.
-	 */
-	if (!test_bit(SCLP_INIT, &sclp_status)) {
-		/* Now clear the running bit */
-		clear_bit(SCLP_RUNNING, &sclp_status);
-		spin_unlock(&sclp_lock);
-		return;
-	}
-	ext_int_param = S390_lowcore.ext_params;
-	finished_sccb = ext_int_param & EXT_INT_SCCB_MASK;
-	evbuf_pending = ext_int_param & (EXT_INT_EVBUF_PENDING |
-					 EXT_INT_STATECHANGE_PENDING);
-	req = NULL;
-	if (finished_sccb != 0U) {
-		list_for_each(l, &sclp_req_queue) {
-			tmp = list_entry(l, struct sclp_req, list);
-			if (finished_sccb == (u32)(addr_t) tmp->sccb) {
-				list_del(&tmp->list);
-				req = tmp;
-				break;
+	finished_sccb = S390_lowcore.ext_params & 0xfffffff8;
+	evbuf_pending = S390_lowcore.ext_params & 0x3;
+	if (finished_sccb) {
+		req = __sclp_find_req(finished_sccb);
+		if (req) {
+			/* Request post-processing */
+			list_del(&req->list);
+			req->status = SCLP_REQ_DONE;
+			if (req->callback) {
+				spin_unlock(&sclp_lock);
+				req->callback(req, req->callback_data);
+				spin_lock(&sclp_lock);
 			}
 		}
+		sclp_running_state = sclp_running_state_idle;
 	}
-	spin_unlock(&sclp_lock);
-	/* Perform callback */
-	if (req != NULL) {
-		req->status = SCLP_REQ_DONE;
-		if (req->callback != NULL)
-			req->callback(req, req->callback_data);
+	if (evbuf_pending && sclp_receive_mask != 0 &&
+	    sclp_reading_state == sclp_reading_state_idle &&
+	    sclp_activation_state == sclp_activation_state_active ) {
+		sclp_reading_state = sclp_reading_state_reading;
+		__sclp_make_read_req();
+		/* Add request to head of queue */
+		list_add(&sclp_read_req.list, &sclp_req_queue);
 	}
-	spin_lock(&sclp_lock);
-	/* Head queue a read sccb if an event buffer is pending */
-	if (evbuf_pending)
-		__sclp_unconditional_read();
-	/* Now clear the running bit if SCLP indicated a finished SCCB */
-	if (finished_sccb != 0U)
-		clear_bit(SCLP_RUNNING, &sclp_status);
 	spin_unlock(&sclp_lock);
-	/* and start next request on the queue */
-	sclp_start_request();
+	sclp_process_queue();
+}
+
+/* Return current Time-Of-Day clock. */
+static inline u64
+sclp_get_clock(void)
+{
+	u64 result;
+
+	asm volatile ("STCK 0(%1)" : "=m" (result) : "a" (&(result)) : "cc");
+	return result;
+}
+
+/* Convert interval in jiffies to TOD ticks. */
+static inline u64
+sclp_tod_from_jiffies(unsigned long jiffies)
+{
+	return (u64) (jiffies / HZ) << 32;
 }
 
-/*
- * Wait synchronously for external interrupt of sclp. We may not receive
- * any other external interrupt, so we disable all other external interrupts
- * in control register 0.
- */
+/* Wait until a currently running request finished. Note: while this function
+ * is running, no timers are served on the calling CPU. */
 void
 sclp_sync_wait(void)
 {
 	unsigned long psw_mask;
 	unsigned long cr0, cr0_sync;
+	u64 timeout;
 
-	/* Prevent BH from executing. */
+	/* We'll be disabling timer interrupts, so we need a custom timeout
+	 * mechanism */
+	timeout = 0;
+	if (timer_pending(&sclp_request_timer)) {
+		/* Get timeout TOD value */
+		timeout = sclp_get_clock() +
+			  sclp_tod_from_jiffies(sclp_request_timer.expires -
+						jiffies);
+	}
+	/* Prevent bottom half from executing once we force interrupts open */
 	local_bh_disable();
-	/*
-	 * save cr0
-	 * enable service signal external interruption (cr0.22)
-	 * disable cr0.20-21, cr0.25, cr0.27, cr0.30-31
-	 * don't touch any other bit in cr0
-	 */
+	/* Enable service-signal interruption, disable timer interrupts */
 	__ctl_store(cr0, 0, 0);
 	cr0_sync = cr0;
 	cr0_sync |= 0x00000200;
 	cr0_sync &= 0xFFFFF3AC;
 	__ctl_load(cr0_sync, 0, 0);
-
-	/* enable external interruptions (PSW-mask.7) */
 	asm volatile ("STOSM 0(%1),0x01"
 		      : "=m" (psw_mask) : "a" (&psw_mask) : "memory");
-
-	/* wait until ISR signals receipt of interrupt */
-	while (test_bit(SCLP_RUNNING, &sclp_status)) {
+	/* Loop until driver state indicates finished request */
+	while (sclp_running_state != sclp_running_state_idle) {
+		/* Check for expired request timer */
+		if (timer_pending(&sclp_request_timer) &&
+		    sclp_get_clock() > timeout &&
+		    del_timer(&sclp_request_timer))
+			sclp_request_timer.function(sclp_request_timer.data);
 		barrier();
 		cpu_relax();
 	}
-
-	/* disable external interruptions */
+	/* Restore interrupt settings */
 	asm volatile ("SSM 0(%0)"
 		      : : "a" (&psw_mask) : "memory");
-
-	/* restore cr0 */
 	__ctl_load(cr0, 0, 0);
 	__local_bh_enable();
 }
 
-/*
- * Queue an SCLP request. Request will immediately be processed if queue is
- * empty.
- */
-void
-sclp_add_request(struct sclp_req *req)
+EXPORT_SYMBOL(sclp_sync_wait);
+
+/* Dispatch changes in send and receive mask to registered listeners. */
+static inline void
+sclp_dispatch_state_change(void)
 {
+	struct list_head *l;
+	struct sclp_register *reg;
 	unsigned long flags;
+	sccb_mask_t receive_mask;
+	sccb_mask_t send_mask;
 
-	if (!test_bit(SCLP_INIT, &sclp_status)) {
-		req->status = SCLP_REQ_FAILED;
-		if (req->callback != NULL)
-			req->callback(req, req->callback_data);
-		return;
-	}
-	spin_lock_irqsave(&sclp_lock, flags);
-	/* queue the request */
-	req->status = SCLP_REQ_QUEUED;
-	list_add_tail(&req->list, &sclp_req_queue);
-	spin_unlock_irqrestore(&sclp_lock, flags);
-	/* try to start the first request on the queue */
-	sclp_start_request();
+	do {
+		spin_lock_irqsave(&sclp_lock, flags);
+		reg = NULL;
+		list_for_each(l, &sclp_reg_list) {
+			reg = list_entry(l, struct sclp_register, list);
+			receive_mask = reg->receive_mask & sclp_receive_mask;
+			send_mask = reg->send_mask & sclp_send_mask;
+			if (reg->sclp_receive_mask != receive_mask ||
+			    reg->sclp_send_mask != send_mask) {
+				reg->sclp_receive_mask = receive_mask;
+				reg->sclp_send_mask = send_mask;
+				break;
+			} else
+				reg = NULL;
+		}
+		spin_unlock_irqrestore(&sclp_lock, flags);
+		if (reg && reg->state_change_fn)
+			reg->state_change_fn(reg);
+	} while (reg);
 }
 
-/* state change notification */
 struct sclp_statechangebuf {
 	struct evbuf_header	header;
 	u8		validity_sclp_active_facility_mask : 1;
@@ -429,148 +472,126 @@
 	u32		read_data_function_mask;
 } __attribute__((packed));
 
-static inline void
-__sclp_notify_state_change(void)
-{
-	struct list_head *l;
-	struct sclp_register *t;
-	sccb_mask_t receive_mask, send_mask;
-
-	list_for_each(l, &sclp_reg_list) {
-		t = list_entry(l, struct sclp_register, list);
-		receive_mask = t->receive_mask & sclp_receive_mask;
-		send_mask = t->send_mask & sclp_send_mask;
-		if (t->sclp_receive_mask != receive_mask ||
-		    t->sclp_send_mask != send_mask) {
-			t->sclp_receive_mask = receive_mask;
-			t->sclp_send_mask = send_mask;
-			if (t->state_change_fn != NULL)
-				t->state_change_fn(t);
-		}
-	}
-}
 
+/* State change event callback. Inform listeners of changes. */
 static void
-sclp_state_change(struct evbuf_header *evbuf)
+sclp_state_change_cb(struct evbuf_header *evbuf)
 {
 	unsigned long flags;
 	struct sclp_statechangebuf *scbuf;
 
-	spin_lock_irqsave(&sclp_lock, flags);
 	scbuf = (struct sclp_statechangebuf *) evbuf;
-
-	if (scbuf->validity_sclp_receive_mask) {
-		if (scbuf->mask_length != sizeof(sccb_mask_t))
-			printk(KERN_WARNING SCLP_CORE_PRINT_HEADER
-			       "state change event with mask length %i\n",
-			       scbuf->mask_length);
-		else
-			/* set new receive mask */
-			sclp_receive_mask = scbuf->sclp_receive_mask;
-	}
-
-	if (scbuf->validity_sclp_send_mask) {
-		if (scbuf->mask_length != sizeof(sccb_mask_t))
-			printk(KERN_WARNING SCLP_CORE_PRINT_HEADER
-			       "state change event with mask length %i\n",
-			       scbuf->mask_length);
-		else
-			/* set new send mask */
-			sclp_send_mask = scbuf->sclp_send_mask;
-	}
-
-	__sclp_notify_state_change();
+	if (scbuf->mask_length != sizeof(sccb_mask_t))
+		return;
+	spin_lock_irqsave(&sclp_lock, flags);
+	if (scbuf->validity_sclp_receive_mask)
+		sclp_receive_mask = scbuf->sclp_receive_mask;
+	if (scbuf->validity_sclp_send_mask)
+		sclp_send_mask = scbuf->sclp_send_mask;
 	spin_unlock_irqrestore(&sclp_lock, flags);
+	sclp_dispatch_state_change();
 }
 
 static struct sclp_register sclp_state_change_event = {
 	.receive_mask = EvTyp_StateChange_Mask,
-	.receiver_fn = sclp_state_change
+	.receiver_fn = sclp_state_change_cb
 };
 
-
-/*
- * SCLP quiesce event handler
- */
-#ifdef CONFIG_SMP
-static void
-do_load_quiesce_psw(void * __unused)
+/* Calculate receive and send mask of currently registered listeners.
+ * Called while sclp_lock is locked. */
+static inline void
+__sclp_get_mask(sccb_mask_t *receive_mask, sccb_mask_t *send_mask)
 {
-	static atomic_t cpuid = ATOMIC_INIT(-1);
-	psw_t quiesce_psw;
-	__u32 status;
-	int i;
-
-	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 */
-	i = 1;
-	while (i < NR_CPUS) {
-		if (!cpu_online(i)) {
-			i++;
-			continue;
-		}
-		switch (signal_processor_ps(&status, 0, i, sigp_sense)) {
-		case sigp_order_code_accepted:
-		case sigp_status_stored:
-			/* Check for stopped and check stop state */
-			if (status & 0x50)
-				i++;
-			break;
-		case sigp_busy:
-			break;
-		case sigp_not_operational:
-			i++;
-			break;
-		}
+	struct list_head *l;
+	struct sclp_register *t;
+
+	*receive_mask = 0;
+	*send_mask = 0;
+	list_for_each(l, &sclp_reg_list) {
+		t = list_entry(l, struct sclp_register, list);
+		*receive_mask |= t->receive_mask;
+		*send_mask |= t->send_mask;
 	}
-	/* Quiesce the last cpu with the special psw */
-	quiesce_psw.mask = PSW_BASE_BITS | PSW_MASK_WAIT;
-	quiesce_psw.addr = 0xfff;
-	__load_psw(quiesce_psw);
 }
 
-static void
-do_machine_quiesce(void)
+/* Register event listener. Return 0 on success, non-zero otherwise. */
+int
+sclp_register(struct sclp_register *reg)
 {
-	on_each_cpu(do_load_quiesce_psw, NULL, 0, 0);
+	unsigned long flags;
+	sccb_mask_t receive_mask;
+	sccb_mask_t send_mask;
+	int rc;
+
+	rc = sclp_init();
+	if (rc)
+		return rc;
+	spin_lock_irqsave(&sclp_lock, flags);
+	/* Check event mask for collisions */
+	__sclp_get_mask(&receive_mask, &send_mask);
+	if (reg->receive_mask & receive_mask || reg->send_mask & send_mask) {
+		spin_unlock_irqrestore(&sclp_lock, flags);
+		return -EBUSY;
+	}
+	/* Trigger initial state change callback */
+	reg->sclp_receive_mask = 0;
+	reg->sclp_send_mask = 0;
+	list_add(&reg->list, &sclp_reg_list);
+	spin_unlock_irqrestore(&sclp_lock, flags);
+	rc = sclp_init_mask(1);
+	if (rc) {
+		spin_lock_irqsave(&sclp_lock, flags);
+		list_del(&reg->list);
+		spin_unlock_irqrestore(&sclp_lock, flags);
+	}
+	return rc;
 }
-#else
-static void
-do_machine_quiesce(void)
+
+EXPORT_SYMBOL(sclp_register);
+
+/* Unregister event listener. */
+void
+sclp_unregister(struct sclp_register *reg)
 {
-	psw_t quiesce_psw;
+	unsigned long flags;
 
-	quiesce_psw.mask = PSW_BASE_BITS | PSW_MASK_WAIT;
-	quiesce_psw.addr = 0xfff;
-	__load_psw(quiesce_psw);
+	spin_lock_irqsave(&sclp_lock, flags);
+	list_del(&reg->list);
+	spin_unlock_irqrestore(&sclp_lock, flags);
+	sclp_init_mask(1);
 }
-#endif
 
-extern void ctrl_alt_del(void);
+EXPORT_SYMBOL(sclp_unregister);
 
-static void
-sclp_quiesce(struct evbuf_header *evbuf)
+/* Remove event buffers which are marked processed. Return the number of
+ * remaining event buffers. */
+int
+sclp_remove_processed(struct sccb_header *sccb)
 {
-	/*
-	 * We got a "shutdown" request.
-	 * Add a call to an appropriate "shutdown" routine here. This
-	 * routine should set all PSWs to 'disabled-wait', 'stopped'
-	 * or 'check-stopped' - except 1 PSW which needs to carry a
-	 * special bit pattern called 'quiesce PSW'.
-	 */
-	_machine_restart = (void *) do_machine_quiesce;
-	_machine_halt = do_machine_quiesce;
-	_machine_power_off = do_machine_quiesce;
-	ctrl_alt_del();
-}
-
-static struct sclp_register sclp_quiesce_event = {
-	.receive_mask = EvTyp_SigQuiesce_Mask,
-	.receiver_fn = sclp_quiesce
-};
+	struct evbuf_header *evbuf;
+	int unprocessed;
+	u16 remaining;
+
+	evbuf = (struct evbuf_header *) (sccb + 1);
+	unprocessed = 0;
+	remaining = sccb->length - sizeof(struct sccb_header);
+	while (remaining > 0) {
+		remaining -= evbuf->length;
+		if (evbuf->flags & 0x80) {
+			sccb->length -= evbuf->length;
+			memcpy(evbuf, (void *) ((addr_t) evbuf + evbuf->length),
+			       remaining);
+		} else {
+			unprocessed++;
+			evbuf = (struct evbuf_header *)
+					((addr_t) evbuf + evbuf->length);
+		}
+	}
+	return unprocessed;
+}
+
+EXPORT_SYMBOL(sclp_remove_processed);
 
-/* initialisation of SCLP */
 struct init_sccb {
 	struct sccb_header header;
 	u16 _reserved;
@@ -581,273 +602,314 @@
 	sccb_mask_t sclp_receive_mask;
 } __attribute__((packed));
 
-static void sclp_init_mask_retry(unsigned long);
-
-static int
-sclp_init_mask(void)
+/* Prepare init mask request. Called while sclp_lock is locked. */
+static inline void
+__sclp_make_init_req(u32 receive_mask, u32 send_mask)
 {
-	unsigned long flags;
 	struct init_sccb *sccb;
-	struct sclp_req *req;
-	struct list_head *l;
-	struct sclp_register *t;
-	int rc;
 
 	sccb = (struct init_sccb *) sclp_init_sccb;
-	/* stick the request structure to the end of the init sccb page */
-	req = (struct sclp_req *) ((addr_t) sccb + PAGE_SIZE) - 1;
-
-	/* SCLP setup concerning receiving and sending Event Buffers */
-	req->command = SCLP_CMDW_WRITEMASK;
-	req->status = SCLP_REQ_QUEUED;
-	req->callback = NULL;
-	req->sccb = sccb;
-	/* setup sccb for writemask command */
-	memset(sccb, 0, sizeof(struct init_sccb));
+	clear_page(sccb);
+	memset(&sclp_init_req, 0, sizeof(struct sclp_req));
+	sclp_init_req.command = SCLP_CMDW_WRITEMASK;
+	sclp_init_req.status = SCLP_REQ_FILLED;
+	sclp_init_req.start_count = 0;
+	sclp_init_req.callback = NULL;
+	sclp_init_req.callback_data = NULL;
+	sclp_init_req.sccb = sccb;
 	sccb->header.length = sizeof(struct init_sccb);
 	sccb->mask_length = sizeof(sccb_mask_t);
-	/* copy in the sccb mask of the registered event types */
-	spin_lock_irqsave(&sclp_lock, flags);
-	if (!test_bit(SCLP_SHUTDOWN, &sclp_status)) {
-		list_for_each(l, &sclp_reg_list) {
-			t = list_entry(l, struct sclp_register, list);
-			sccb->receive_mask |= t->receive_mask;
-			sccb->send_mask |= t->send_mask;
-		}
-	}
+	sccb->receive_mask = receive_mask;
+	sccb->send_mask = send_mask;
 	sccb->sclp_receive_mask = 0;
 	sccb->sclp_send_mask = 0;
-	if (test_bit(SCLP_INIT, &sclp_status)) {
-		/* add request to sclp queue */
-		list_add_tail(&req->list, &sclp_req_queue);
-		spin_unlock_irqrestore(&sclp_lock, flags);
-		/* and start if SCLP is idle */
-		sclp_start_request();
-		/* now wait for completion */
-		while (req->status != SCLP_REQ_DONE &&
-		       req->status != SCLP_REQ_FAILED)
+}
+
+/* Start init mask request. If calculate is non-zero, calculate the mask as
+ * requested by registered listeners. Use zero mask otherwise. Return 0 on
+ * success, non-zero otherwise. */
+static int
+sclp_init_mask(int calculate)
+{
+	unsigned long flags;
+	struct init_sccb *sccb = (struct init_sccb *) sclp_init_sccb;
+	sccb_mask_t receive_mask;
+	sccb_mask_t send_mask;
+	int retry;
+	int rc;
+	unsigned long wait;
+
+	spin_lock_irqsave(&sclp_lock, flags);
+	/* Check if interface is in appropriate state */
+	if (sclp_mask_state != sclp_mask_state_idle) {
+		spin_unlock_irqrestore(&sclp_lock, flags);
+		return -EBUSY;
+	}
+	if (sclp_activation_state == sclp_activation_state_inactive) {
+		spin_unlock_irqrestore(&sclp_lock, flags);
+		return -EINVAL;
+	}
+	sclp_mask_state = sclp_mask_state_initializing;
+	/* Determine mask */
+	if (calculate)
+		__sclp_get_mask(&receive_mask, &send_mask);
+	else {
+		receive_mask = 0;
+		send_mask = 0;
+	}
+	rc = -EIO;
+	for (retry = 0; retry <= SCLP_MASK_RETRY; retry++) {
+		/* Prepare request */
+		__sclp_make_init_req(receive_mask, send_mask);
+		spin_unlock_irqrestore(&sclp_lock, flags);
+		if (sclp_add_request(&sclp_init_req)) {
+			/* Try again later */
+			wait = jiffies + SCLP_BUSY_INTERVAL * HZ;
+			while (time_before(jiffies, wait))
+				sclp_sync_wait();
+			spin_lock_irqsave(&sclp_lock, flags);
+			continue;
+		}
+		while (sclp_init_req.status != SCLP_REQ_DONE &&
+		       sclp_init_req.status != SCLP_REQ_FAILED)
 			sclp_sync_wait();
 		spin_lock_irqsave(&sclp_lock, flags);
-	} else {
-		/*
-		 * Special case for the very first write mask command.
-		 * The interrupt handler is not removing request from
-		 * the request queue and doesn't call callbacks yet
-		 * because there might be an pending old interrupt
-		 * after a Re-IPL. We have to receive and ignore it.
-		 */
-		do {
-			rc = __service_call(req->command, req->sccb);
-			if (rc == 0)
-				set_bit(SCLP_RUNNING, &sclp_status);
+		if (sclp_init_req.status == SCLP_REQ_DONE &&
+		    sccb->header.response_code == 0x20) {
+			/* Successful request */
+			if (calculate) {
+				sclp_receive_mask = sccb->sclp_receive_mask;
+				sclp_send_mask = sccb->sclp_send_mask;
+			} else {
+				sclp_receive_mask = 0;
+				sclp_send_mask = 0;
+			}
 			spin_unlock_irqrestore(&sclp_lock, flags);
-			if (rc == -EIO)
-				return -ENOSYS;
-			sclp_sync_wait();
+			sclp_dispatch_state_change();
 			spin_lock_irqsave(&sclp_lock, flags);
-		} while (rc == -EBUSY);
-	}
-	if (sccb->header.response_code != 0x0020) {
-		/* WRITEMASK failed - we cannot rely on receiving a state
-		   change event, so initially, polling is the only alternative
-		   for us to ever become operational. */
-		if (!test_bit(SCLP_SHUTDOWN, &sclp_status) &&
-		    (!timer_pending(&retry_timer) ||
-		     !mod_timer(&retry_timer,
-			       jiffies + SCLP_INIT_POLL_INTERVAL*HZ))) {
-			retry_timer.function = sclp_init_mask_retry;
-			retry_timer.data = 0;
-			retry_timer.expires = jiffies +
-				SCLP_INIT_POLL_INTERVAL*HZ;
-			add_timer(&retry_timer);
+			rc = 0;
+			break;
 		}
-	} else {
-		sclp_receive_mask = sccb->sclp_receive_mask;
-		sclp_send_mask = sccb->sclp_send_mask;
-		__sclp_notify_state_change();
 	}
+	sclp_mask_state = sclp_mask_state_idle;
 	spin_unlock_irqrestore(&sclp_lock, flags);
-	return 0;
-}
-
-static void
-sclp_init_mask_retry(unsigned long data) 
-{
-	sclp_init_mask();
+	return rc;
 }
 
-/* Reboot event handler - reset send and receive mask to prevent pending SCLP
- * events from interfering with rebooted system. */
-static int
-sclp_reboot_event(struct notifier_block *this, unsigned long event, void *ptr)
+/* Deactivate SCLP interface. On success, new requests will be rejected,
+ * events will no longer be dispatched. Return 0 on success, non-zero
+ * otherwise. */
+int
+sclp_deactivate(void)
 {
 	unsigned long flags;
+	int rc;
 
-	/* Note: need spinlock to maintain atomicity when accessing global
-         * variables. */
 	spin_lock_irqsave(&sclp_lock, flags);
-	set_bit(SCLP_SHUTDOWN, &sclp_status);
+	/* Deactivate can only be called when active */
+	if (sclp_activation_state != sclp_activation_state_active) {
+		spin_unlock_irqrestore(&sclp_lock, flags);
+		return -EINVAL;
+	}
+	sclp_activation_state = sclp_activation_state_deactivating;
 	spin_unlock_irqrestore(&sclp_lock, flags);
-	sclp_init_mask();
-	return NOTIFY_DONE;
+	rc = sclp_init_mask(0);
+	spin_lock_irqsave(&sclp_lock, flags);
+	if (rc == 0)
+		sclp_activation_state = sclp_activation_state_inactive;
+	else
+		sclp_activation_state = sclp_activation_state_active;
+	spin_unlock_irqrestore(&sclp_lock, flags);
+	return rc;
 }
 
-static struct notifier_block sclp_reboot_notifier = {
-	.notifier_call = sclp_reboot_event
-};
+EXPORT_SYMBOL(sclp_deactivate);
 
-/*
- * sclp setup function. Called early (no kmalloc!) from sclp_console_init().
- */
-static int
-sclp_init(void)
+/* Reactivate SCLP interface after sclp_deactivate. On success, new
+ * requests will be accepted, events will be dispatched again. Return 0 on
+ * success, non-zero otherwise. */
+int
+sclp_reactivate(void)
 {
+	unsigned long flags;
 	int rc;
 
-	if (test_bit(SCLP_INIT, &sclp_status))
-		/* Already initialized. */
-		return 0;
-
-	spin_lock_init(&sclp_lock);
-	INIT_LIST_HEAD(&sclp_req_queue);
-
-	/* init event list */
-	INIT_LIST_HEAD(&sclp_reg_list);
-	list_add(&sclp_state_change_event.list, &sclp_reg_list);
-	list_add(&sclp_quiesce_event.list, &sclp_reg_list);
-
-	rc = register_reboot_notifier(&sclp_reboot_notifier);
-	if (rc)
-		return rc;
+	spin_lock_irqsave(&sclp_lock, flags);
+	/* Reactivate can only be called when inactive */
+	if (sclp_activation_state != sclp_activation_state_inactive) {
+		spin_unlock_irqrestore(&sclp_lock, flags);
+		return -EINVAL;
+	}
+	sclp_activation_state = sclp_activation_state_activating;
+	spin_unlock_irqrestore(&sclp_lock, flags);
+	rc = sclp_init_mask(1);
+	spin_lock_irqsave(&sclp_lock, flags);
+	if (rc == 0)
+		sclp_activation_state = sclp_activation_state_active;
+	else
+		sclp_activation_state = sclp_activation_state_inactive;
+	spin_unlock_irqrestore(&sclp_lock, flags);
+	return rc;
+}
 
-	/*
-	 * request the 0x2401 external interrupt
-	 * The sclp driver is initialized early (before kmalloc works). We
-	 * need to use register_early_external_interrupt.
-	 */
-	if (register_early_external_interrupt(0x2401, sclp_interrupt_handler,
-					      &ext_int_info_hwc) != 0)
-		return -EBUSY;
+EXPORT_SYMBOL(sclp_reactivate);
 
-	/* enable service-signal external interruptions,
-	 * Control Register 0 bit 22 := 1
-	 * (besides PSW bit 7 must be set to 1 sometimes for external
-	 * interruptions)
-	 */
-	ctl_set_bit(0, 9);
+/* Handler for external interruption used during initialization. Modify
+ * request state to done. */
+static void
+sclp_check_handler(struct pt_regs *regs, __u16 code)
+{
+	u32 finished_sccb;
 
-	init_timer(&retry_timer);
-	init_timer(&sclp_busy_timer);
-	/* do the initial write event mask */
-	rc = sclp_init_mask();
-	if (rc == 0) {
-		/* Ok, now everything is setup right. */
-		set_bit(SCLP_INIT, &sclp_status);
-		return 0;
+	finished_sccb = S390_lowcore.ext_params & 0xfffffff8;
+	/* Is this the interrupt we are waiting for? */
+	if (finished_sccb == 0)
+		return;
+	if (finished_sccb != (u32) (addr_t) sclp_init_sccb) {
+		printk(KERN_WARNING SCLP_HEADER "unsolicited interrupt "
+		       "for buffer at 0x%x\n", finished_sccb);
+		return;
 	}
-
-	/* The sclp_init_mask failed. SCLP is broken, unregister and exit. */
-	ctl_clear_bit(0,9);
-	unregister_early_external_interrupt(0x2401, sclp_interrupt_handler,
-					    &ext_int_info_hwc);
-
-	return rc;
+	spin_lock(&sclp_lock);
+	if (sclp_running_state == sclp_running_state_running) {
+		sclp_init_req.status = SCLP_REQ_DONE;
+		sclp_running_state = sclp_running_state_idle;
+	}
+	spin_unlock(&sclp_lock);
 }
 
-/*
- * Register the SCLP event listener identified by REG. Return 0 on success.
- * Some error codes and their meaning:
- *
- *  -ENODEV = SCLP interface is not supported on this machine
- *   -EBUSY = there is already a listener registered for the requested
- *            event type
- *     -EIO = SCLP interface is currently not operational
- */
-int
-sclp_register(struct sclp_register *reg)
+/* Initial init mask request timed out. Modify request state to failed. */
+static void
+sclp_check_timeout(unsigned long data)
 {
 	unsigned long flags;
-	struct list_head *l;
-	struct sclp_register *t;
-
-	if (!MACHINE_HAS_SCLP)
-		return -ENODEV;
 
-	if (!test_bit(SCLP_INIT, &sclp_status))
-		sclp_init();
 	spin_lock_irqsave(&sclp_lock, flags);
-	/* check already registered event masks for collisions */
-	list_for_each(l, &sclp_reg_list) {
-		t = list_entry(l, struct sclp_register, list);
-		if (t->receive_mask & reg->receive_mask ||
-		    t->send_mask & reg->send_mask) {
-			spin_unlock_irqrestore(&sclp_lock, flags);
-			return -EBUSY;
-		}
+	if (sclp_running_state == sclp_running_state_running) {
+		sclp_init_req.status = SCLP_REQ_FAILED;
+		sclp_running_state = sclp_running_state_idle;
 	}
-	/*
-	 * set present mask to 0 to trigger state change
-	 * callback in sclp_init_mask
-	 */
-	reg->sclp_receive_mask = 0;
-	reg->sclp_send_mask = 0;
-	list_add(&reg->list, &sclp_reg_list);
 	spin_unlock_irqrestore(&sclp_lock, flags);
-	sclp_init_mask();
-	return 0;
 }
 
-/*
- * Unregister the SCLP event listener identified by REG.
- */
-void
-sclp_unregister(struct sclp_register *reg)
+/* Perform a check of the SCLP interface. Return zero if the interface is
+ * available and there are no pending requests from a previous instance.
+ * Return non-zero otherwise. */
+static int
+sclp_check_interface(void)
 {
+	struct init_sccb *sccb;
 	unsigned long flags;
+	int retry;
+	int rc;
 
 	spin_lock_irqsave(&sclp_lock, flags);
-	list_del(&reg->list);
+	/* Prepare init mask command */
+	rc = register_early_external_interrupt(0x2401, sclp_check_handler,
+					       &ext_int_info_hwc);
+	if (rc) {
+		spin_unlock_irqrestore(&sclp_lock, flags);
+		return rc;
+	}
+	for (retry = 0; retry <= SCLP_INIT_RETRY; retry++) {
+		__sclp_make_init_req(0, 0);
+		sccb = (struct init_sccb *) sclp_init_req.sccb;
+		rc = service_call(sclp_init_req.command, sccb);
+		if (rc == -EIO)
+			break;
+		sclp_init_req.status = SCLP_REQ_RUNNING;
+		sclp_running_state = sclp_running_state_running;
+		__sclp_set_request_timer(SCLP_RETRY_INTERVAL * HZ,
+					 sclp_check_timeout, 0);
+		spin_unlock_irqrestore(&sclp_lock, flags);
+		/* Enable service-signal interruption - needs to happen
+		 * with IRQs enabled. */
+		ctl_set_bit(0, 9);
+		/* Wait for signal from interrupt or timeout */
+		sclp_sync_wait();
+		/* Disable service-signal interruption - needs to happen
+		 * with IRQs enabled. */
+		ctl_clear_bit(0,9);
+		spin_lock_irqsave(&sclp_lock, flags);
+		del_timer(&sclp_request_timer);
+		if (sclp_init_req.status == SCLP_REQ_DONE &&
+		    sccb->header.response_code == 0x20) {
+			rc = 0;
+			break;
+		} else
+			rc = -EBUSY;
+	}
+	unregister_early_external_interrupt(0x2401, sclp_check_handler,
+					    &ext_int_info_hwc);
 	spin_unlock_irqrestore(&sclp_lock, flags);
-	sclp_init_mask();
+	return rc;
+}
+
+/* Reboot event handler. Reset send and receive mask to prevent pending SCLP
+ * events from interfering with rebooted system. */
+static int
+sclp_reboot_event(struct notifier_block *this, unsigned long event, void *ptr)
+{
+	sclp_deactivate();
+	return NOTIFY_DONE;
 }
 
-#define	SCLP_EVBUF_PROCESSED	0x80
+static struct notifier_block sclp_reboot_notifier = {
+	.notifier_call = sclp_reboot_event
+};
 
-/*
- * Traverse array of event buffers contained in SCCB and remove all buffers
- * with a set "processed" flag. Return the number of unprocessed buffers.
- */
-int
-sclp_remove_processed(struct sccb_header *sccb)
+/* Initialize SCLP driver. Return zero if driver is operational, non-zero
+ * otherwise. */
+static int
+sclp_init(void)
 {
-	struct evbuf_header *evbuf;
-	int unprocessed;
-	u16 remaining;
+	unsigned long flags;
+	int rc;
 
-	evbuf = (struct evbuf_header *) (sccb + 1);
-	unprocessed = 0;
-	remaining = sccb->length - sizeof(struct sccb_header);
-	while (remaining > 0) {
-		remaining -= evbuf->length;
-		if (evbuf->flags & SCLP_EVBUF_PROCESSED) {
-			sccb->length -= evbuf->length;
-			memcpy((void *) evbuf,
-			       (void *) ((addr_t) evbuf + evbuf->length),
-			       remaining);
-		} else {
-			unprocessed++;
-			evbuf = (struct evbuf_header *)
-					((addr_t) evbuf + evbuf->length);
-		}
+	if (!MACHINE_HAS_SCLP)
+		return -ENODEV;
+	spin_lock_irqsave(&sclp_lock, flags);
+	/* Check for previous or running initialization */
+	if (sclp_init_state != sclp_init_state_uninitialized) {
+		spin_unlock_irqrestore(&sclp_lock, flags);
+		return 0;
 	}
-
-	return unprocessed;
+	sclp_init_state = sclp_init_state_initializing;
+	/* Set up variables */
+	INIT_LIST_HEAD(&sclp_req_queue);
+	INIT_LIST_HEAD(&sclp_reg_list);
+	list_add(&sclp_state_change_event.list, &sclp_reg_list);
+	init_timer(&sclp_request_timer);
+	/* Check interface */
+	spin_unlock_irqrestore(&sclp_lock, flags);
+	rc = sclp_check_interface();
+	spin_lock_irqsave(&sclp_lock, flags);
+	if (rc) {
+		sclp_init_state = sclp_init_state_uninitialized;
+		spin_unlock_irqrestore(&sclp_lock, flags);
+		return rc;
+	}
+	/* Register reboot handler */
+	rc = register_reboot_notifier(&sclp_reboot_notifier);
+	if (rc) {
+		sclp_init_state = sclp_init_state_uninitialized;
+		spin_unlock_irqrestore(&sclp_lock, flags);
+		return rc;
+	}
+	/* Register interrupt handler */
+	rc = register_early_external_interrupt(0x2401, sclp_interrupt_handler,
+					       &ext_int_info_hwc);
+	if (rc) {
+		unregister_reboot_notifier(&sclp_reboot_notifier);
+		sclp_init_state = sclp_init_state_uninitialized;
+		spin_unlock_irqrestore(&sclp_lock, flags);
+		return rc;
+	}
+	sclp_init_state = sclp_init_state_initialized;
+	spin_unlock_irqrestore(&sclp_lock, flags);
+	/* Enable service-signal external interruption - needs to happen with
+	 * IRQs enabled. */
+	ctl_set_bit(0, 9);
+	sclp_init_mask(1);
+	return 0;
 }
-
-module_init(sclp_init);
-
-EXPORT_SYMBOL(sclp_add_request);
-EXPORT_SYMBOL(sclp_sync_wait);
-EXPORT_SYMBOL(sclp_register);
-EXPORT_SYMBOL(sclp_unregister);
-EXPORT_SYMBOL(sclp_error_message);
diff -Nru a/drivers/s390/char/sclp.h b/drivers/s390/char/sclp.h
--- a/drivers/s390/char/sclp.h	2005-03-01 23:38:53 -08:00
+++ b/drivers/s390/char/sclp.h	2005-03-01 23:38:53 -08:00
@@ -95,6 +95,7 @@
 	sclp_cmdw_t command;		/* sclp command to execute */
 	void	*sccb;			/* pointer to the sccb to execute */
 	char	status;			/* status of this request */
+	int     start_count;		/* number of SVCs done for this req */
 	/* Callback that is called after reaching final status. */
 	void (*callback)(struct sclp_req *, void *data);
 	void *callback_data;
@@ -123,12 +124,13 @@
 };
 
 /* externals from sclp.c */
-void sclp_add_request(struct sclp_req *req);
+int sclp_add_request(struct sclp_req *req);
 void sclp_sync_wait(void);
 int sclp_register(struct sclp_register *reg);
 void sclp_unregister(struct sclp_register *reg);
-char *sclp_error_message(u16 response_code);
 int sclp_remove_processed(struct sccb_header *sccb);
+int sclp_deactivate(void);
+int sclp_reactivate(void);
 
 /* useful inlines */
 
diff -Nru a/drivers/s390/char/sclp_con.c b/drivers/s390/char/sclp_con.c
--- a/drivers/s390/char/sclp_con.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/s390/char/sclp_con.c	2005-03-01 23:38:57 -08:00
@@ -49,25 +49,22 @@
 sclp_conbuf_callback(struct sclp_buffer *buffer, int rc)
 {
 	unsigned long flags;
-	struct sclp_buffer *next;
 	void *page;
 
-	/* Ignore return code - because console-writes aren't critical,
-	   we do without a sophisticated error recovery mechanism.  */
-	page = sclp_unmake_buffer(buffer);
-	spin_lock_irqsave(&sclp_con_lock, flags);
-	/* Remove buffer from outqueue */
-	list_del(&buffer->list);
-	sclp_con_buffer_count--;
-	list_add_tail((struct list_head *) page, &sclp_con_pages);
-	/* Check if there is a pending buffer on the out queue. */
-	next = NULL;
-	if (!list_empty(&sclp_con_outqueue))
-		next = list_entry(sclp_con_outqueue.next,
-				  struct sclp_buffer, list);
-	spin_unlock_irqrestore(&sclp_con_lock, flags);
-	if (next != NULL)
-		sclp_emit_buffer(next, sclp_conbuf_callback);
+	do {
+		page = sclp_unmake_buffer(buffer);
+		spin_lock_irqsave(&sclp_con_lock, flags);
+		/* Remove buffer from outqueue */
+		list_del(&buffer->list);
+		sclp_con_buffer_count--;
+		list_add_tail((struct list_head *) page, &sclp_con_pages);
+		/* Check if there is a pending buffer on the out queue. */
+		buffer = NULL;
+		if (!list_empty(&sclp_con_outqueue))
+			buffer = list_entry(sclp_con_outqueue.next,
+					    struct sclp_buffer, list);
+		spin_unlock_irqrestore(&sclp_con_lock, flags);
+	} while (buffer && sclp_emit_buffer(buffer, sclp_conbuf_callback));
 }
 
 static inline void
@@ -76,6 +73,7 @@
 	struct sclp_buffer* buffer;
 	unsigned long flags;
 	int count;
+	int rc;
 
 	spin_lock_irqsave(&sclp_con_lock, flags);
 	buffer = sclp_conbuf;
@@ -87,8 +85,11 @@
 	list_add_tail(&buffer->list, &sclp_con_outqueue);
 	count = sclp_con_buffer_count++;
 	spin_unlock_irqrestore(&sclp_con_lock, flags);
-	if (count == 0)
-		sclp_emit_buffer(buffer, sclp_conbuf_callback);
+	if (count)
+		return;
+	rc = sclp_emit_buffer(buffer, sclp_conbuf_callback);
+	if (rc)
+		sclp_conbuf_callback(buffer, rc);
 }
 
 /*
diff -Nru a/drivers/s390/char/sclp_cpi.c b/drivers/s390/char/sclp_cpi.c
--- a/drivers/s390/char/sclp_cpi.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/s390/char/sclp_cpi.c	2005-03-01 23:38:57 -08:00
@@ -196,18 +196,20 @@
 	rc = sclp_register(&sclp_cpi_event);
 	if (rc) {
 		/* could not register sclp event. Die. */
-		printk("cpi: could not register to hardware console.\n");
+		printk(KERN_WARNING "cpi: could not register to hardware "
+		       "console.\n");
 		return -EINVAL;
 	}
 	if (!(sclp_cpi_event.sclp_send_mask & EvTyp_CtlProgIdent_Mask)) {
-		printk("cpi: no control program identification support\n");
+		printk(KERN_WARNING "cpi: no control program identification "
+		       "support\n");
 		sclp_unregister(&sclp_cpi_event);
 		return -ENOTSUPP;
 	}
 
 	req = cpi_prepare_req();
 	if (IS_ERR(req)) {
-		printk("cpi: couldn't allocate request\n");
+		printk(KERN_WARNING "cpi: couldn't allocate request\n");
 		sclp_unregister(&sclp_cpi_event);
 		return PTR_ERR(req);
 	}
@@ -216,13 +218,20 @@
 	sema_init(&sem, 0);
 	req->callback_data = &sem;
 	/* Add request to sclp queue */
-	sclp_add_request(req);
+	rc = sclp_add_request(req);
+	if (rc) {
+		printk(KERN_WARNING "cpi: could not start request\n");
+		cpi_free_req(req);
+		sclp_unregister(&sclp_cpi_event);
+		return rc;
+	}
 	/* make "insmod" sleep until callback arrives */
 	down(&sem);
 
 	rc = ((struct cpi_sccb *) req->sccb)->header.response_code;
 	if (rc != 0x0020) {
-		printk("cpi: failed with response code 0x%x\n", rc);
+		printk(KERN_WARNING "cpi: failed with response code 0x%x\n",
+		       rc);
 		rc = -ECOMM;
 	} else
 		rc = 0;
diff -Nru a/drivers/s390/char/sclp_quiesce.c b/drivers/s390/char/sclp_quiesce.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/s390/char/sclp_quiesce.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,114 @@
+/*
+ *  drivers/s390/char/sclp_quiesce.c
+ *     signal quiesce handler
+ *
+ *  (C) Copyright IBM Corp. 1999,2004
+ *  Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
+ *             Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/cpumask.h>
+#include <linux/smp.h>
+#include <linux/init.h>
+#include <asm/atomic.h>
+#include <asm/ptrace.h>
+#include <asm/sigp.h>
+
+#include "sclp.h"
+
+
+#ifdef CONFIG_SMP
+/* Signal completion of shutdown process. All CPUs except the first to enter
+ * this function: go to stopped state. First CPU: wait until all other
+ * CPUs are in stopped or check stop state. Afterwards, load special PSW
+ * to indicate completion. */
+static void
+do_load_quiesce_psw(void * __unused)
+{
+	static atomic_t cpuid = ATOMIC_INIT(-1);
+	psw_t quiesce_psw;
+	__u32 status;
+	int i;
+
+	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 */
+	i = 1;
+	while (i < NR_CPUS) {
+		if (!cpu_online(i)) {
+			i++;
+			continue;
+		}
+		switch (signal_processor_ps(&status, 0, i, sigp_sense)) {
+		case sigp_order_code_accepted:
+		case sigp_status_stored:
+			/* Check for stopped and check stop state */
+			if (status & 0x50)
+				i++;
+			break;
+		case sigp_busy:
+			break;
+		case sigp_not_operational:
+			i++;
+			break;
+		}
+	}
+	/* Quiesce the last cpu with the special psw */
+	quiesce_psw.mask = PSW_BASE_BITS | PSW_MASK_WAIT;
+	quiesce_psw.addr = 0xfff;
+	__load_psw(quiesce_psw);
+}
+
+/* Shutdown handler. Perform shutdown function on all CPUs. */
+static void
+do_machine_quiesce(void)
+{
+	on_each_cpu(do_load_quiesce_psw, NULL, 0, 0);
+}
+#else
+/* Shutdown handler. Signal completion of shutdown by loading special PSW. */
+static void
+do_machine_quiesce(void)
+{
+	psw_t quiesce_psw;
+
+	quiesce_psw.mask = PSW_BASE_BITS | PSW_MASK_WAIT;
+	quiesce_psw.addr = 0xfff;
+	__load_psw(quiesce_psw);
+}
+#endif
+
+extern void ctrl_alt_del(void);
+
+/* Handler for quiesce event. Start shutdown procedure. */
+static void
+sclp_quiesce_handler(struct evbuf_header *evbuf)
+{
+	_machine_restart = (void *) do_machine_quiesce;
+	_machine_halt = do_machine_quiesce;
+	_machine_power_off = do_machine_quiesce;
+	ctrl_alt_del();
+}
+
+static struct sclp_register sclp_quiesce_event = {
+	.receive_mask = EvTyp_SigQuiesce_Mask,
+	.receiver_fn = sclp_quiesce_handler
+};
+
+/* Initialize quiesce driver. */
+static int __init
+sclp_quiesce_init(void)
+{
+	int rc;
+
+	rc = sclp_register(&sclp_quiesce_event);
+	if (rc)
+		printk(KERN_WARNING "sclp: could not register quiesce handler "
+		       "(rc=%d)\n", rc);
+	return rc;
+}
+
+module_init(sclp_quiesce_init);
diff -Nru a/drivers/s390/char/sclp_rw.c b/drivers/s390/char/sclp_rw.c
--- a/drivers/s390/char/sclp_rw.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/s390/char/sclp_rw.c	2005-03-01 23:38:57 -08:00
@@ -54,7 +54,6 @@
 	buffer = ((struct sclp_buffer *) ((addr_t) sccb + PAGE_SIZE)) - 1;
 	buffer->sccb = sccb;
 	buffer->retry_count = 0;
-	init_timer(&buffer->retry_timer);
 	buffer->mto_number = 0;
 	buffer->mto_char_sum = 0;
 	buffer->current_line = NULL;
@@ -365,17 +364,7 @@
 	return rc;
 }
 
-static void
-sclp_buffer_retry(unsigned long data)
-{
-	struct sclp_buffer *buffer = (struct sclp_buffer *) data;
-	buffer->request.status = SCLP_REQ_FILLED;
-	buffer->sccb->header.response_code = 0x0000;
-	sclp_add_request(&buffer->request);
-}
-
-#define SCLP_BUFFER_MAX_RETRY		5
-#define	SCLP_BUFFER_RETRY_INTERVAL	2
+#define SCLP_BUFFER_MAX_RETRY		1
 
 /*
  * second half of Write Event Data-function that has to be done after
@@ -404,7 +393,7 @@
 		break;
 
 	case 0x0340: /* Contained SCLP equipment check */
-		if (buffer->retry_count++ > SCLP_BUFFER_MAX_RETRY) {
+		if (++buffer->retry_count > SCLP_BUFFER_MAX_RETRY) {
 			rc = -EIO;
 			break;
 		}
@@ -413,26 +402,26 @@
 			/* not all buffers were processed */
 			sccb->header.response_code = 0x0000;
 			buffer->request.status = SCLP_REQ_FILLED;
-			sclp_add_request(request);
-			return;
-		}
-		rc = 0;
+			rc = sclp_add_request(request);
+			if (rc == 0)
+				return;
+		} else
+			rc = 0;
 		break;
 
 	case 0x0040: /* SCLP equipment check */
 	case 0x05f0: /* Target resource in improper state */
-		if (buffer->retry_count++ > SCLP_BUFFER_MAX_RETRY) {
+		if (++buffer->retry_count > SCLP_BUFFER_MAX_RETRY) {
 			rc = -EIO;
 			break;
 		}
-		/* wait some time, then retry request */
-		buffer->retry_timer.function = sclp_buffer_retry;
-		buffer->retry_timer.data = (unsigned long) buffer;
-		buffer->retry_timer.expires = jiffies +
-						SCLP_BUFFER_RETRY_INTERVAL*HZ;
-		add_timer(&buffer->retry_timer);
-		return;
-
+		/* retry request */
+		sccb->header.response_code = 0x0000;
+		buffer->request.status = SCLP_REQ_FILLED;
+		rc = sclp_add_request(request);
+		if (rc == 0)
+			return;
+		break;
 	default:
 		if (sccb->header.response_code == 0x71f0)
 			rc = -ENOMEM;
@@ -446,9 +435,10 @@
 
 /*
  * Setup the request structure in the struct sclp_buffer to do SCLP Write
- * Event Data and pass the request to the core SCLP loop.
+ * Event Data and pass the request to the core SCLP loop. Return zero on
+ * success, non-zero otherwise.
  */
-void
+int
 sclp_emit_buffer(struct sclp_buffer *buffer,
 		 void (*callback)(struct sclp_buffer *, int))
 {
@@ -459,11 +449,8 @@
 		sclp_finalize_mto(buffer);
 
 	/* Are there messages in the output buffer ? */
-	if (buffer->mto_number == 0) {
-		if (callback != NULL)
-			callback(buffer, 0);
-		return;
-	}
+	if (buffer->mto_number == 0)
+		return -EIO;
 
 	sccb = buffer->sccb;
 	if (sclp_rw_event.sclp_send_mask & EvTyp_Msg_Mask)
@@ -472,16 +459,13 @@
 	else if (sclp_rw_event.sclp_send_mask & EvTyp_PMsgCmd_Mask)
 		/* Use write priority message */
 		sccb->msg_buf.header.type = EvTyp_PMsgCmd;
-	else {
-		if (callback != NULL)
-			callback(buffer, -ENOSYS);
-		return;
-	}
+	else
+		return -ENOSYS;
 	buffer->request.command = SCLP_CMDW_WRITEDATA;
 	buffer->request.status = SCLP_REQ_FILLED;
 	buffer->request.callback = sclp_writedata_callback;
 	buffer->request.callback_data = buffer;
 	buffer->request.sccb = sccb;
 	buffer->callback = callback;
-	sclp_add_request(&buffer->request);
+	return sclp_add_request(&buffer->request);
 }
diff -Nru a/drivers/s390/char/sclp_rw.h b/drivers/s390/char/sclp_rw.h
--- a/drivers/s390/char/sclp_rw.h	2005-03-01 23:39:18 -08:00
+++ b/drivers/s390/char/sclp_rw.h	2005-03-01 23:39:18 -08:00
@@ -12,7 +12,6 @@
 #define __SCLP_RW_H__
 
 #include <linux/list.h>
-#include <linux/timer.h>
 
 struct mto {
 	u16 length;
@@ -74,7 +73,6 @@
 	char *current_line;
 	int current_length;
 	int retry_count;
-	struct timer_list retry_timer;
 	/* output format settings */
 	unsigned short columns;
 	unsigned short htab;
@@ -90,7 +88,7 @@
 void *sclp_unmake_buffer(struct sclp_buffer *);
 int sclp_buffer_space(struct sclp_buffer *);
 int sclp_write(struct sclp_buffer *buffer, const unsigned char *, int);
-void sclp_emit_buffer(struct sclp_buffer *,void (*)(struct sclp_buffer *,int));
+int sclp_emit_buffer(struct sclp_buffer *,void (*)(struct sclp_buffer *,int));
 void sclp_set_columns(struct sclp_buffer *, unsigned short);
 void sclp_set_htab(struct sclp_buffer *, unsigned short);
 int sclp_chars_in_buffer(struct sclp_buffer *);
diff -Nru a/drivers/s390/char/sclp_tty.c b/drivers/s390/char/sclp_tty.c
--- a/drivers/s390/char/sclp_tty.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/s390/char/sclp_tty.c	2005-03-01 23:39:18 -08:00
@@ -255,25 +255,22 @@
 sclp_ttybuf_callback(struct sclp_buffer *buffer, int rc)
 {
 	unsigned long flags;
-	struct sclp_buffer *next;
 	void *page;
 
-	/* Ignore return code - because tty-writes aren't critical,
-	   we do without a sophisticated error recovery mechanism.  */
-	page = sclp_unmake_buffer(buffer);
-	spin_lock_irqsave(&sclp_tty_lock, flags);
-	/* Remove buffer from outqueue */
-	list_del(&buffer->list);
-	sclp_tty_buffer_count--;
-	list_add_tail((struct list_head *) page, &sclp_tty_pages);
-	/* Check if there is a pending buffer on the out queue. */
-	next = NULL;
-	if (!list_empty(&sclp_tty_outqueue))
-		next = list_entry(sclp_tty_outqueue.next,
-				  struct sclp_buffer, list);
-	spin_unlock_irqrestore(&sclp_tty_lock, flags);
-	if (next != NULL)
-		sclp_emit_buffer(next, sclp_ttybuf_callback);
+	do {
+		page = sclp_unmake_buffer(buffer);
+		spin_lock_irqsave(&sclp_tty_lock, flags);
+		/* Remove buffer from outqueue */
+		list_del(&buffer->list);
+		sclp_tty_buffer_count--;
+		list_add_tail((struct list_head *) page, &sclp_tty_pages);
+		/* Check if there is a pending buffer on the out queue. */
+		buffer = NULL;
+		if (!list_empty(&sclp_tty_outqueue))
+			buffer = list_entry(sclp_tty_outqueue.next,
+					    struct sclp_buffer, list);
+		spin_unlock_irqrestore(&sclp_tty_lock, flags);
+	} while (buffer && sclp_emit_buffer(buffer, sclp_ttybuf_callback));
 	wake_up(&sclp_tty_waitq);
 	/* check if the tty needs a wake up call */
 	if (sclp_tty != NULL) {
@@ -286,14 +283,17 @@
 {
 	unsigned long flags;
 	int count;
+	int rc;
 
 	spin_lock_irqsave(&sclp_tty_lock, flags);
 	list_add_tail(&buffer->list, &sclp_tty_outqueue);
 	count = sclp_tty_buffer_count++;
 	spin_unlock_irqrestore(&sclp_tty_lock, flags);
-
-	if (count == 0)
-		sclp_emit_buffer(buffer, sclp_ttybuf_callback);
+	if (count)
+		return;
+	rc = sclp_emit_buffer(buffer, sclp_ttybuf_callback);
+	if (rc)
+		sclp_ttybuf_callback(buffer, rc);
 }
 
 /*
diff -Nru a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c
--- a/drivers/s390/char/sclp_vt220.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/s390/char/sclp_vt220.c	2005-03-01 23:38:54 -08:00
@@ -42,7 +42,6 @@
 	struct list_head list;
 	struct sclp_req sclp_req;
 	int retry_count;
-	struct timer_list retry_timer;
 };
 
 /* VT220 SCCB */
@@ -96,7 +95,7 @@
 static int sclp_vt220_flush_later;
 
 static void sclp_vt220_receiver_fn(struct evbuf_header *evbuf);
-static void __sclp_vt220_emit(struct sclp_vt220_request *request);
+static int __sclp_vt220_emit(struct sclp_vt220_request *request);
 static void sclp_vt220_emit_current(void);
 
 /* Registration structure for our interest in SCLP event buffers */
@@ -116,25 +115,24 @@
 sclp_vt220_process_queue(struct sclp_vt220_request *request)
 {
 	unsigned long flags;
-	struct sclp_vt220_request *next;
 	void *page;
 
-	/* Put buffer back to list of empty buffers */
-	page = request->sclp_req.sccb;
-	spin_lock_irqsave(&sclp_vt220_lock, flags);
-	/* Move request from outqueue to empty queue */
-	list_del(&request->list);
-	sclp_vt220_outqueue_count--;
-	list_add_tail((struct list_head *) page, &sclp_vt220_empty);
-	/* Check if there is a pending buffer on the out queue. */
-	next = NULL;
-	if (!list_empty(&sclp_vt220_outqueue))
-		next = list_entry(sclp_vt220_outqueue.next,
-				  struct sclp_vt220_request, list);
-	spin_unlock_irqrestore(&sclp_vt220_lock, flags);
-	if (next != NULL)
-		__sclp_vt220_emit(next);
-	else if (sclp_vt220_flush_later)
+	do {
+		/* Put buffer back to list of empty buffers */
+		page = request->sclp_req.sccb;
+		spin_lock_irqsave(&sclp_vt220_lock, flags);
+		/* Move request from outqueue to empty queue */
+		list_del(&request->list);
+		sclp_vt220_outqueue_count--;
+		list_add_tail((struct list_head *) page, &sclp_vt220_empty);
+		/* Check if there is a pending buffer on the out queue. */
+		request = NULL;
+		if (!list_empty(&sclp_vt220_outqueue))
+			request = list_entry(sclp_vt220_outqueue.next,
+					     struct sclp_vt220_request, list);
+		spin_unlock_irqrestore(&sclp_vt220_lock, flags);
+	} while (request && __sclp_vt220_emit(request));
+	if (request == NULL && sclp_vt220_flush_later)
 		sclp_vt220_emit_current();
 	wake_up(&sclp_vt220_waitq);
 	/* Check if the tty needs a wake up call */
@@ -143,25 +141,7 @@
 	}
 }
 
-/*
- * Retry sclp write request after waiting some time for an sclp equipment
- * check to pass.
- */
-static void
-sclp_vt220_retry(unsigned long data)
-{
-	struct sclp_vt220_request *request;
-	struct sclp_vt220_sccb *sccb;
-
-	request = (struct sclp_vt220_request *) data;
-	request->sclp_req.status = SCLP_REQ_FILLED;
-	sccb = (struct sclp_vt220_sccb *) request->sclp_req.sccb;
-	sccb->header.response_code = 0x0000;
-	sclp_add_request(&request->sclp_req);
-}
-
-#define SCLP_BUFFER_MAX_RETRY		5
-#define	SCLP_BUFFER_RETRY_INTERVAL	2
+#define SCLP_BUFFER_MAX_RETRY		1
 
 /*
  * Callback through which the result of a write request is reported by the
@@ -189,29 +169,26 @@
 		break;
 
 	case 0x0340: /* Contained SCLP equipment check */
-		if (vt220_request->retry_count++ > SCLP_BUFFER_MAX_RETRY)
+		if (++vt220_request->retry_count > SCLP_BUFFER_MAX_RETRY)
 			break;
 		/* Remove processed buffers and requeue rest */
 		if (sclp_remove_processed((struct sccb_header *) sccb) > 0) {
 			/* Not all buffers were processed */
 			sccb->header.response_code = 0x0000;
 			vt220_request->sclp_req.status = SCLP_REQ_FILLED;
-			sclp_add_request(request);
-			return;
+			if (sclp_add_request(request) == 0)
+				return;
 		}
 		break;
 
 	case 0x0040: /* SCLP equipment check */
-		if (vt220_request->retry_count++ > SCLP_BUFFER_MAX_RETRY)
+		if (++vt220_request->retry_count > SCLP_BUFFER_MAX_RETRY)
 			break;
-		/* Wait some time, then retry request */
-		vt220_request->retry_timer.function = sclp_vt220_retry;
-		vt220_request->retry_timer.data =
-			(unsigned long) vt220_request;
-		vt220_request->retry_timer.expires =
-			jiffies + SCLP_BUFFER_RETRY_INTERVAL*HZ;
-		add_timer(&vt220_request->retry_timer);
-		return;
+		sccb->header.response_code = 0x0000;
+		vt220_request->sclp_req.status = SCLP_REQ_FILLED;
+		if (sclp_add_request(request) == 0)
+			return;
+		break;
 
 	default:
 		break;
@@ -220,22 +197,22 @@
 }
 
 /*
- * Emit vt220 request buffer to SCLP.
+ * Emit vt220 request buffer to SCLP. Return zero on success, non-zero
+ * otherwise.
  */
-static void
+static int
 __sclp_vt220_emit(struct sclp_vt220_request *request)
 {
 	if (!(sclp_vt220_register.sclp_send_mask & EvTyp_VT220Msg_Mask)) {
 		request->sclp_req.status = SCLP_REQ_FAILED;
-		sclp_vt220_callback(&request->sclp_req, (void *) request);
-		return;
+		return -EIO;
 	}
 	request->sclp_req.command = SCLP_CMDW_WRITEDATA;
 	request->sclp_req.status = SCLP_REQ_FILLED;
 	request->sclp_req.callback = sclp_vt220_callback;
 	request->sclp_req.callback_data = (void *) request;
 
-	sclp_add_request(&request->sclp_req);
+	return sclp_add_request(&request->sclp_req);
 }
 
 /*
@@ -253,12 +230,12 @@
 	spin_unlock_irqrestore(&sclp_vt220_lock, flags);
 	/* Emit only the first buffer immediately - callback takes care of
 	 * the rest */
-	if (count == 0)
-		__sclp_vt220_emit(request);
+	if (count == 0 && __sclp_vt220_emit(request))
+		sclp_vt220_process_queue(request);
 }
 
 /*
- * Queue and emit current request.
+ * Queue and emit current request. Return zero on success, non-zero otherwise.
  */
 static void
 sclp_vt220_emit_current(void)
@@ -300,7 +277,6 @@
 	/* Place request structure at end of page */
 	request = ((struct sclp_vt220_request *)
 			((addr_t) page + PAGE_SIZE)) - 1;
-	init_timer(&request->retry_timer);
 	request->retry_count = 0;
 	request->sclp_req.sccb = page;
 	/* SCCB goes at start of page */
diff -Nru a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c
--- a/drivers/s390/char/tape_core.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/s390/char/tape_core.c	2005-03-01 23:38:54 -08:00
@@ -36,7 +36,7 @@
  * The list is protected by the rwlock
  */
 static struct list_head tape_device_list = LIST_HEAD_INIT(tape_device_list);
-static rwlock_t tape_device_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(tape_device_lock);
 
 /*
  * Pointer to debug area.
@@ -349,6 +349,11 @@
 
 	/* Let the discipline have a go at the device. */
 	device->discipline = discipline;
+	if (!try_module_get(discipline->owner)) {
+		PRINT_ERR("Cannot get module. Module gone.\n");
+		return -EINVAL;
+	}
+
 	rc = discipline->setup_device(device);
 	if (rc)
 		goto out;
@@ -377,6 +382,7 @@
 out_minor:
 	tape_remove_minor(device);
 out:
+	module_put(discipline->owner);
 	return rc;
 }
 
@@ -386,6 +392,7 @@
 	tapeblock_cleanup_device(device);
 	tapechar_cleanup_device(device);
 	device->discipline->cleanup_device(device);
+	module_put(device->discipline->owner);
 	tape_remove_minor(device);
 	tape_med_state_set(device, MS_UNKNOWN);
 }
@@ -1184,7 +1191,7 @@
 #ifdef DBF_LIKE_HELL
 	debug_set_level(TAPE_DBF_AREA, 6);
 #endif
-	DBF_EVENT(3, "tape init: ($Revision: 1.50 $)\n");
+	DBF_EVENT(3, "tape init: ($Revision: 1.51 $)\n");
 	tape_proc_init();
 	tapechar_init ();
 	tapeblock_init ();
@@ -1209,7 +1216,7 @@
 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.50 $)");
+		   "tape device driver ($Revision: 1.51 $)");
 MODULE_LICENSE("GPL");
 
 module_init(tape_init);
diff -Nru a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c
--- a/drivers/s390/char/tty3270.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/s390/char/tty3270.c	2005-03-01 23:38:53 -08:00
@@ -124,11 +124,12 @@
 tty3270_set_timer(struct tty3270 *tp, int expires)
 {
 	if (expires == 0) {
-		if (del_timer(&tp->timer))
+		if (timer_pending(&tp->timer) && del_timer(&tp->timer))
 			raw3270_put_view(&tp->view);
 		return;
 	}
-	if (mod_timer(&tp->timer, jiffies + expires))
+	if (timer_pending(&tp->timer) &&
+	    mod_timer(&tp->timer, jiffies + expires))
 		return;
 	raw3270_get_view(&tp->view);
 	tp->timer.function = (void (*)(unsigned long)) tty3270_update;
@@ -705,6 +706,7 @@
 	if (!tp->freemem_pages)
 		goto out_tp;
 	INIT_LIST_HEAD(&tp->freemem);
+	init_timer(&tp->timer);
 	for (pages = 0; pages < TTY3270_STRING_PAGES; pages++) {
 		tp->freemem_pages[pages] = (void *)
 			__get_free_pages(GFP_KERNEL|GFP_DMA, 0);
diff -Nru a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c
--- a/drivers/s390/char/vmlogrdr.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/s390/char/vmlogrdr.c	2005-03-01 23:39:08 -08:00
@@ -403,7 +403,7 @@
 		goto not_connected;
 	}
 
-	return 0;
+ 	return nonseekable_open(inode, filp);
 
 not_connected:
 	iucv_unregister_program(logptr->iucv_handle);
diff -Nru a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c
--- a/drivers/s390/cio/cio.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/s390/cio/cio.c	2005-03-01 23:39:17 -08:00
@@ -1,7 +1,7 @@
 /*
  *  drivers/s390/cio/cio.c
  *   S/390 common I/O routines -- low level i/o calls
- *   $Revision: 1.128 $
+ *   $Revision: 1.130 $
  *
  *    Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH,
  *			      IBM Corporation
@@ -175,9 +175,10 @@
 }
 
 int
-cio_start (struct subchannel *sch,	/* subchannel structure */
-	   struct ccw1 * cpa,		/* logical channel prog addr */
-	   __u8 lpm)			/* logical path mask */
+cio_start_key (struct subchannel *sch,	/* subchannel structure */
+	       struct ccw1 * cpa,	/* logical channel prog addr */
+	       __u8 lpm,		/* logical path mask */
+	       __u8 key)                /* storage key */
 {
 	char dbf_txt[15];
 	int ccode;
@@ -200,12 +201,12 @@
 	sch->orb.c64 = 1;
 	sch->orb.i2k = 0;
 #endif
+	sch->orb.key = key >> 4;
+	/* issue "Start Subchannel" */
 	sch->orb.cpa = (__u32) __pa (cpa);
-
-	/*
-	 * Issue "Start subchannel" and process condition code
-	 */
 	ccode = ssch (sch->irq, &sch->orb);
+
+	/* process condition code */
 	sprintf (dbf_txt, "ccode:%d", ccode);
 	CIO_TRACE_EVENT (4, dbf_txt);
 
@@ -224,6 +225,12 @@
 	}
 }
 
+int
+cio_start (struct subchannel *sch, struct ccw1 *cpa, __u8 lpm)
+{
+	return cio_start_key(sch, cpa, lpm, default_storage_key);
+}
+
 /*
  * resume suspended I/O operation
  */
@@ -813,9 +820,10 @@
 }
 
 extern void do_reipl(unsigned long devno);
-/* Make sure all subchannels are quiet before we re-ipl an lpar. */
+
+/* Clear all subchannels. */
 void
-reipl(unsigned long devno)
+clear_all_subchannels(void)
 {
 	unsigned int schid;
 
@@ -823,7 +831,7 @@
 	for (schid=0;schid<=highest_subchannel;schid++) {
 		struct schib schib;
 		if (stsch(schid, &schib))
-			goto out;
+			break; /* break out of the loop */
 		if (!schib.pmcw.ena)
 			continue;
 		switch(__disable_subchannel_easy(schid, &schib)) {
@@ -832,11 +840,17 @@
 			break;
 		default: /* -EBUSY */
 			if (__clear_subchannel_easy(schid))
-				break; /* give up... */
+				break; /* give up... jump out of switch */
 			stsch(schid, &schib);
 			__disable_subchannel_easy(schid, &schib);
 		}
 	}
-out:
+}
+
+/* Make sure all subchannels are quiet before we re-ipl an lpar. */
+void
+reipl(unsigned long devno)
+{
+	clear_all_subchannels();
 	do_reipl(devno);
 }
diff -Nru a/drivers/s390/cio/cio.h b/drivers/s390/cio/cio.h
--- a/drivers/s390/cio/cio.h	2005-03-01 23:38:51 -08:00
+++ b/drivers/s390/cio/cio.h	2005-03-01 23:38:51 -08:00
@@ -122,6 +122,7 @@
 extern int cio_resume (struct subchannel *);
 extern int cio_halt (struct subchannel *);
 extern int cio_start (struct subchannel *, struct ccw1 *, __u8);
+extern int cio_start_key (struct subchannel *, struct ccw1 *, __u8, __u8);
 extern int cio_cancel (struct subchannel *);
 extern int cio_set_options (struct subchannel *, int);
 extern int cio_get_options (struct subchannel *);
diff -Nru a/drivers/s390/cio/cmf.c b/drivers/s390/cio/cmf.c
--- a/drivers/s390/cio/cmf.c	2005-03-01 23:38:44 -08:00
+++ b/drivers/s390/cio/cmf.c	2005-03-01 23:38:44 -08:00
@@ -526,7 +526,7 @@
 	time = get_clock() - cdev->private->cmb_start_time;
 	spin_unlock_irqrestore(cdev->ccwlock, flags);
 
-	memset(data, sizeof(struct cmbdata), 0);
+	memset(data, 0, sizeof(struct cmbdata));
 
 	/* we only know values before device_busy_time */
 	data->size = offsetof(struct cmbdata, device_busy_time);
@@ -736,7 +736,7 @@
 	time = get_clock() - cdev->private->cmb_start_time;
 	spin_unlock_irqrestore(cdev->ccwlock, flags);
 
-	memset (data, sizeof(struct cmbdata), 0);
+	memset (data, 0, sizeof(struct cmbdata));
 
 	/* we only know values before device_busy_time */
 	data->size = offsetof(struct cmbdata, device_busy_time);
diff -Nru a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
--- a/drivers/s390/cio/css.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/s390/cio/css.c	2005-03-01 23:39:18 -08:00
@@ -304,7 +304,7 @@
 };
 
 static LIST_HEAD(slow_subchannels_head);
-static spinlock_t slow_subchannel_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(slow_subchannel_lock);
 
 static void
 css_trigger_slow_path(void)
@@ -527,7 +527,7 @@
 	new_slow_sch = kmalloc(sizeof(struct slow_subchannel), GFP_ATOMIC);
 	if (!new_slow_sch)
 		return -ENOMEM;
-	memset(new_slow_sch, sizeof(struct slow_subchannel), 0);
+	memset(new_slow_sch, 0, sizeof(struct slow_subchannel));
 	new_slow_sch->schid = schid;
 	spin_lock_irqsave(&slow_subchannel_lock, flags);
 	list_add_tail(&new_slow_sch->slow_list, &slow_subchannels_head);
diff -Nru a/drivers/s390/cio/device_id.c b/drivers/s390/cio/device_id.c
--- a/drivers/s390/cio/device_id.c	2005-03-01 23:38:43 -08:00
+++ b/drivers/s390/cio/device_id.c	2005-03-01 23:38:43 -08:00
@@ -36,7 +36,7 @@
 	 * use a static data area to be sure
 	 */
 	static struct diag210 diag210_tmp;
-	static spinlock_t diag210_lock = SPIN_LOCK_UNLOCKED;
+	static DEFINE_SPINLOCK(diag210_lock);
 	unsigned long flags;
 	int ccode;
 
diff -Nru a/drivers/s390/cio/device_ops.c b/drivers/s390/cio/device_ops.c
--- a/drivers/s390/cio/device_ops.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/s390/cio/device_ops.c	2005-03-01 23:39:08 -08:00
@@ -1,7 +1,7 @@
 /*
  *  drivers/s390/cio/device_ops.c
  *
- *   $Revision: 1.50 $
+ *   $Revision: 1.53 $
  *
  *    Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
  *			 IBM Corporation
@@ -54,6 +54,7 @@
 	if (cdev->private->state == DEV_STATE_NOT_OPER)
 		return -ENODEV;
 	if (cdev->private->state != DEV_STATE_ONLINE &&
+	    cdev->private->state != DEV_STATE_WAIT4IO &&
 	    cdev->private->state != DEV_STATE_W4SENSE)
 		return -EINVAL;
 	sch = to_subchannel(cdev->dev.parent);
@@ -66,8 +67,9 @@
 }
 
 int
-ccw_device_start(struct ccw_device *cdev, struct ccw1 *cpa,
-		 unsigned long intparm, __u8 lpm, unsigned long flags)
+ccw_device_start_key(struct ccw_device *cdev, struct ccw1 *cpa,
+		     unsigned long intparm, __u8 lpm, __u8 key,
+		     unsigned long flags)
 {
 	struct subchannel *sch;
 	int ret;
@@ -87,29 +89,49 @@
 	ret = cio_set_options (sch, flags);
 	if (ret)
 		return ret;
-	ret = cio_start (sch, cpa, lpm);
+	ret = cio_start_key (sch, cpa, lpm, key);
 	if (ret == 0)
 		cdev->private->intparm = intparm;
 	return ret;
 }
 
+
 int
-ccw_device_start_timeout(struct ccw_device *cdev, struct ccw1 *cpa,
-			 unsigned long intparm, __u8 lpm, unsigned long flags,
-			 int expires)
+ccw_device_start_timeout_key(struct ccw_device *cdev, struct ccw1 *cpa,
+			     unsigned long intparm, __u8 lpm, __u8 key,
+			     unsigned long flags, int expires)
 {
 	int ret;
 
 	if (!cdev)
 		return -ENODEV;
 	ccw_device_set_timeout(cdev, expires);
-	ret = ccw_device_start(cdev, cpa, intparm, lpm, flags);
+	ret = ccw_device_start_key(cdev, cpa, intparm, lpm, key, flags);
 	if (ret != 0)
 		ccw_device_set_timeout(cdev, 0);
 	return ret;
 }
 
 int
+ccw_device_start(struct ccw_device *cdev, struct ccw1 *cpa,
+		 unsigned long intparm, __u8 lpm, unsigned long flags)
+{
+	return ccw_device_start_key(cdev, cpa, intparm, lpm,
+				    default_storage_key, flags);
+}
+
+int
+ccw_device_start_timeout(struct ccw_device *cdev, struct ccw1 *cpa,
+			 unsigned long intparm, __u8 lpm, unsigned long flags,
+			 int expires)
+{
+	return ccw_device_start_timeout_key(cdev, cpa, intparm, lpm,
+					    default_storage_key, flags,
+					    expires);
+}
+
+
+int
 ccw_device_halt(struct ccw_device *cdev, unsigned long intparm)
 {
 	struct subchannel *sch;
@@ -120,6 +142,7 @@
 	if (cdev->private->state == DEV_STATE_NOT_OPER)
 		return -ENODEV;
 	if (cdev->private->state != DEV_STATE_ONLINE &&
+	    cdev->private->state != DEV_STATE_WAIT4IO &&
 	    cdev->private->state != DEV_STATE_W4SENSE)
 		return -EINVAL;
 	sch = to_subchannel(cdev->dev.parent);
@@ -539,6 +562,8 @@
 EXPORT_SYMBOL(ccw_device_resume);
 EXPORT_SYMBOL(ccw_device_start_timeout);
 EXPORT_SYMBOL(ccw_device_start);
+EXPORT_SYMBOL(ccw_device_start_timeout_key);
+EXPORT_SYMBOL(ccw_device_start_key);
 EXPORT_SYMBOL(ccw_device_get_ciw);
 EXPORT_SYMBOL(ccw_device_get_path_mask);
 EXPORT_SYMBOL(read_conf_data);
diff -Nru a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c
--- a/drivers/s390/cio/qdio.c	2005-03-01 23:38:59 -08:00
+++ b/drivers/s390/cio/qdio.c	2005-03-01 23:38:59 -08:00
@@ -56,7 +56,7 @@
 #include "ioasm.h"
 #include "chsc.h"
 
-#define VERSION_QDIO_C "$Revision: 1.93 $"
+#define VERSION_QDIO_C "$Revision: 1.98 $"
 
 /****************** MODULE PARAMETER VARIABLES ********************/
 MODULE_AUTHOR("Utz Bacher <utz.bacher@de.ibm.com>");
@@ -95,7 +95,7 @@
 /* iQDIO stuff: */
 static volatile struct qdio_q *tiq_list=NULL; /* volatile as it could change
 						 during a while loop */
-static spinlock_t ttiq_list_lock=SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(ttiq_list_lock);
 static int register_thinint_result;
 static void tiqdio_tl(unsigned long);
 static DECLARE_TASKLET(tiqdio_tasklet,tiqdio_tl,0);
@@ -2043,6 +2043,7 @@
 				"installed.\n");
 		return -ENOENT;
 	}
+
 	/* Check for bits 107 and 108. */
 	if (!css_chsc_characteristics.scssc ||
 	    !css_chsc_characteristics.scsscf) {
@@ -2132,7 +2133,11 @@
 	/* enables the time delay disablement facility. Don't care
 	 * whether it is really there (i.e. we haven't checked for
 	 * it) */
-	scssc_area->word_with_d_bit = 0x10000000;
+	if (css_general_characteristics.aif_tdd)
+		scssc_area->word_with_d_bit = 0x10000000;
+	else
+		QDIO_PRINT_WARN("Time delay disablement facility " \
+				"not available\n");
 
 
 
@@ -2319,6 +2324,15 @@
 	}
 	if (rc == -ENODEV) {
 		/* No need to wait for device no longer present. */
+		qdio_set_state(irq_ptr, QDIO_IRQ_STATE_INACTIVE);
+		spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags);
+	} else if (((void *)cdev->handler != (void *)qdio_handler) && rc == 0) {
+		/*
+		 * Whoever put another handler there, has to cope with the
+		 * interrupt theirself. Might happen if qdio_shutdown was
+		 * called on already shutdown queues, but this shouldn't have
+		 * bad side effects.
+		 */
 		qdio_set_state(irq_ptr, QDIO_IRQ_STATE_INACTIVE);
 		spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags);
 	} else if (rc == 0) {
diff -Nru a/drivers/s390/net/ctcmain.c b/drivers/s390/net/ctcmain.c
--- a/drivers/s390/net/ctcmain.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/s390/net/ctcmain.c	2005-03-01 23:39:18 -08:00
@@ -1,5 +1,5 @@
 /*
- * $Id: ctcmain.c,v 1.65 2004/10/27 09:12:48 mschwide Exp $
+ * $Id: ctcmain.c,v 1.68 2004/12/27 09:25:27 heicarst Exp $
  *
  * CTC / ESCON network driver
  *
@@ -36,7 +36,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * RELEASE-TAG: CTC/ESCON network driver $Revision: 1.65 $
+ * RELEASE-TAG: CTC/ESCON network driver $Revision: 1.68 $
  *
  */
 
@@ -320,7 +320,7 @@
 print_banner(void)
 {
 	static int printed = 0;
-	char vbuf[] = "$Revision: 1.65 $";
+	char vbuf[] = "$Revision: 1.68 $";
 	char *version = vbuf;
 
 	if (printed)
@@ -1939,6 +1939,7 @@
 			   ch_fsm, CH_FSM_LEN, GFP_KERNEL);
 	if (ch->fsm == NULL) {
 		ctc_pr_warn("ctc: Could not create FSM in add_channel\n");
+		kfree(ch->ccw);
 		kfree(ch);
 		return -1;
 	}
@@ -1947,6 +1948,7 @@
 					      GFP_KERNEL)) == NULL) {
 		ctc_pr_warn("ctc: Out of memory in add_channel\n");
 		kfree_fsm(ch->fsm);
+		kfree(ch->ccw);
 		kfree(ch);
 		return -1;
 	}
@@ -1959,6 +1961,7 @@
 			"using old entry\n", (*c)->id);
 		kfree(ch->irb);
 		kfree_fsm(ch->fsm);
+		kfree(ch->ccw);
 		kfree(ch);
 		return 0;
 	}
@@ -2710,7 +2713,7 @@
 	struct net_device *ndev;
 	int bs1;
 
-	DBF_TEXT(trace, 5, __FUNCTION__);
+	DBF_TEXT(trace, 3, __FUNCTION__);
 	priv = dev->driver_data;
 	if (!priv)
 		return -ENODEV;
@@ -2835,7 +2838,7 @@
 static int
 ctc_add_attributes(struct device *dev)
 {
-	device_create_file(dev, &dev_attr_buffer);
+//	device_create_file(dev, &dev_attr_buffer);
 	device_create_file(dev, &dev_attr_loglevel);
 	device_create_file(dev, &dev_attr_stats);
 	return 0;
@@ -2846,7 +2849,7 @@
 {
 	device_remove_file(dev, &dev_attr_stats);
 	device_remove_file(dev, &dev_attr_loglevel);
-	device_remove_file(dev, &dev_attr_buffer);
+//	device_remove_file(dev, &dev_attr_buffer);
 }
 
 
@@ -2988,6 +2991,7 @@
 static struct attribute *ctc_attr[] = {
 	&dev_attr_protocol.attr,
 	&dev_attr_type.attr,
+	&dev_attr_buffer.attr,
 	NULL,
 };
 
diff -Nru a/drivers/s390/net/iucv.c b/drivers/s390/net/iucv.c
--- a/drivers/s390/net/iucv.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/s390/net/iucv.c	2005-03-01 23:38:52 -08:00
@@ -1,5 +1,5 @@
 /* 
- * $Id: iucv.c,v 1.41 2004/08/11 14:54:14 geraldsc Exp $
+ * $Id: iucv.c,v 1.42 2005/01/07 10:49:54 braunu Exp $
  *
  * IUCV network driver
  *
@@ -29,7 +29,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * RELEASE-TAG: IUCV lowlevel driver $Revision: 1.41 $
+ * RELEASE-TAG: IUCV lowlevel driver $Revision: 1.42 $
  *
  */
 
@@ -103,7 +103,7 @@
 
 /* Spin Lock declaration */
 
-static spinlock_t iucv_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(iucv_lock);
 
 static int messagesDisabled = 0;
 
@@ -115,7 +115,7 @@
 } iucv_irqdata;
 
 static struct list_head  iucv_irq_queue;
-static spinlock_t iucv_irq_queue_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(iucv_irq_queue_lock);
 
 /*
  *Internal function prototypes
@@ -355,7 +355,7 @@
 static void
 iucv_banner(void)
 {
-	char vbuf[] = "$Revision: 1.41 $";
+	char vbuf[] = "$Revision: 1.42 $";
 	char *version = vbuf;
 
 	if ((version = strchr(version, ':'))) {
@@ -2285,7 +2285,6 @@
 	irqdata = kmalloc(sizeof(iucv_irqdata), GFP_ATOMIC);
 	if (!irqdata) {
 		printk(KERN_WARNING "%s: out of memory\n", __FUNCTION__);
-		irq_exit();
 		return;
 	}
 
diff -Nru a/drivers/s390/net/qeth.h b/drivers/s390/net/qeth.h
--- a/drivers/s390/net/qeth.h	2005-03-01 23:38:44 -08:00
+++ b/drivers/s390/net/qeth.h	2005-03-01 23:38:44 -08:00
@@ -24,7 +24,7 @@
 
 #include "qeth_mpc.h"
 
-#define VERSION_QETH_H 		"$Revision: 1.124 $"
+#define VERSION_QETH_H 		"$Revision: 1.132 $"
 
 #ifdef CONFIG_QETH_IPV6
 #define QETH_VERSION_IPV6 	":IPv6"
@@ -669,7 +669,6 @@
 #define QETH_BROADCAST_WITHOUT_ECHO 2
 
 struct qeth_card_info {
-	char if_name[IF_NAME_LEN];
 	unsigned short unit_addr2;
 	unsigned short cula;
 	unsigned short chpid;
@@ -755,6 +754,8 @@
 	struct qeth_perf_stats perf_stats;
 #endif /* CONFIG_QETH_PERF_STATS */
 	int use_hard_stop;
+	int (*orig_hard_header)(struct sk_buff *,struct net_device *,
+				unsigned short,void *,void *,unsigned);
 };
 
 struct qeth_card_list_struct {
@@ -775,6 +776,8 @@
 
 /*some helper functions*/
 
+#define QETH_CARD_IFNAME(card) (((card)->dev)? (card)->dev->name : "")
+
 inline static __u8
 qeth_get_ipa_adp_type(enum qeth_link_types link_type)
 {
@@ -827,6 +830,17 @@
 #endif
 	}
 }
+static inline struct sk_buff *
+qeth_pskb_unshare(struct sk_buff *skb, int pri)
+{
+        struct sk_buff *nskb;
+        if (!skb_cloned(skb))
+                return skb;
+        nskb = skb_copy(skb, pri);
+        kfree_skb(skb); /* free our shared copy */
+        return nskb;
+}
+
 
 inline static int
 qeth_get_initial_mtu_for_card(struct qeth_card * card)
@@ -1069,4 +1083,5 @@
 
 extern int
 qeth_realloc_buffer_pool(struct qeth_card *, int);
+
 #endif /* __QETH_H__ */
diff -Nru a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c
--- a/drivers/s390/net/qeth_main.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/s390/net/qeth_main.c	2005-03-01 23:39:18 -08:00
@@ -1,6 +1,6 @@
 /*
  *
- * linux/drivers/s390/net/qeth_main.c ($Revision: 1.170 $)
+ * linux/drivers/s390/net/qeth_main.c ($Revision: 1.191 $)
  *
  * Linux on zSeries OSA Express and HiperSockets support
  *
@@ -12,7 +12,7 @@
  *			  Frank Pavlic (pavlic@de.ibm.com) and
  *		 	  Thomas Spatzier <tspat@de.ibm.com>
  *
- *    $Revision: 1.170 $	 $Date: 2004/11/17 09:54:06 $
+ *    $Revision: 1.191 $	 $Date: 2005/01/31 13:13: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
@@ -41,16 +41,9 @@
 #include <linux/config.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
-
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/mm.h>
-
-#include <asm/io.h>
-#include <asm/ebcdic.h>
-#include <linux/ctype.h>
-#include <asm/semaphore.h>
-#include <asm/timex.h>
 #include <linux/ip.h>
 #include <linux/inetdevice.h>
 #include <linux/netdevice.h>
@@ -62,23 +55,29 @@
 #include <linux/tcp.h>
 #include <linux/icmp.h>
 #include <linux/skbuff.h>
-#include <net/route.h>
-#include <net/arp.h>
 #include <linux/in.h>
 #include <linux/igmp.h>
-#include <net/ip.h>
-#include <asm/uaccess.h>
 #include <linux/init.h>
 #include <linux/reboot.h>
-#include <asm/qeth.h>
 #include <linux/mii.h>
 #include <linux/rcupdate.h>
 
+#include <net/arp.h>
+#include <net/ip.h>
+#include <net/route.h>
+
+#include <asm/ebcdic.h>
+#include <asm/io.h>
+#include <asm/qeth.h>
+#include <asm/timex.h>
+#include <asm/semaphore.h>
+#include <asm/uaccess.h>
+
 #include "qeth.h"
 #include "qeth_mpc.h"
 #include "qeth_fs.h"
 
-#define VERSION_QETH_C "$Revision: 1.170 $"
+#define VERSION_QETH_C "$Revision: 1.191 $"
 static const char *version = "qeth S/390 OSA-Express driver";
 
 /**
@@ -514,6 +513,7 @@
 qeth_set_offline(struct ccwgroup_device *cgdev)
 {
 	struct qeth_card *card = (struct qeth_card *) cgdev->dev.driver_data;
+	int rc = 0;
 	enum qeth_card_states recover_flag;
 
 	QETH_DBF_TEXT(setup, 3, "setoffl");
@@ -525,15 +525,21 @@
 			   CARD_BUS_ID(card));
 		return -ERESTARTSYS;
 	}
-	ccw_device_set_offline(CARD_DDEV(card));
-	ccw_device_set_offline(CARD_WDEV(card));
-	ccw_device_set_offline(CARD_RDEV(card));
+	if ((rc = ccw_device_set_offline(CARD_DDEV(card))) ||
+	    (rc = ccw_device_set_offline(CARD_WDEV(card))) ||
+	    (rc = ccw_device_set_offline(CARD_RDEV(card)))) {
+		QETH_DBF_TEXT_(setup, 2, "1err%d", rc);
+	}
 	if (recover_flag == CARD_STATE_UP)
 		card->state = CARD_STATE_RECOVER;
 	qeth_notify_processes();
 	return 0;
 }
 
+static int
+qeth_wait_for_threads(struct qeth_card *card, unsigned long threads);
+
+
 static void
 qeth_remove_device(struct ccwgroup_device *cgdev)
 {
@@ -546,6 +552,9 @@
 	if (!card)
 		return;
 
+	if (qeth_wait_for_threads(card, 0xffffffff))
+		return;
+
 	if (cgdev->state == CCWGROUP_ONLINE){
 		card->use_hard_stop = 1;
 		qeth_set_offline(cgdev);
@@ -621,7 +630,7 @@
 	if (todo->users > 0){
 		/* for VIPA and RXIP limit refcount to 1 */
 		if (todo->type != QETH_IP_TYPE_NORMAL)
-			addr->users = 1;
+			todo->users = 1;
 		return 1;
 	} else
 		return 0;
@@ -1311,6 +1320,7 @@
 	if (channel->state != CH_STATE_UP){
 		rc = -ETIME;
 		QETH_DBF_TEXT_(setup, 2, "3err%d", rc);
+		qeth_clear_cmd_buffers(channel);
 	} else
 		rc = 0;
 	return rc;
@@ -1377,6 +1387,7 @@
 	if (channel->state != CH_STATE_ACTIVATING) {
 		PRINT_WARN("qeth: IDX activate timed out!\n");
 		QETH_DBF_TEXT_(setup, 2, "2err%d", -ETIME);
+		qeth_clear_cmd_buffers(channel);
 		return -ETIME;
 	}
 	return qeth_idx_activate_get_answer(channel,idx_reply_cb);
@@ -1601,7 +1612,7 @@
 					   "there is a network problem or "
 					   "someone pulled the cable or "
 					   "disabled the port.\n",
-					   card->info.if_name,
+					   QETH_CARD_IFNAME(card),
 					   card->info.chpid);
 				card->lan_online = 0;
 				netif_carrier_off(card->dev);
@@ -1610,7 +1621,7 @@
 				PRINT_INFO("Link reestablished on %s "
 					   "(CHPID 0x%X). Scheduling "
 					   "IP address reset.\n",
-					   card->info.if_name,
+					   QETH_CARD_IFNAME(card),
 					   card->info.chpid);
 				card->lan_online = 1;
 				netif_carrier_on(card->dev);
@@ -1622,7 +1633,7 @@
 			case IPA_CMD_UNREGISTER_LOCAL_ADDR:
 				PRINT_WARN("probably problem on %s: "
 					   "received IPA command 0x%X\n",
-					   card->info.if_name,
+					   QETH_CARD_IFNAME(card),
 					   cmd->hdr.command);
 				break;
 			default:
@@ -2139,7 +2150,7 @@
 no_mem:
 	if (net_ratelimit()){
 		PRINT_WARN("No memory for packet received on %s.\n",
-			   card->info.if_name);
+			   QETH_CARD_IFNAME(card));
 		QETH_DBF_TEXT(trace,2,"noskbmem");
 		QETH_DBF_TEXT_(trace,2,"%s",CARD_BUS_ID(card));
 	}
@@ -2260,8 +2271,8 @@
 		skb->ip_summed = CHECKSUM_NONE;
 #ifdef CONFIG_QETH_VLAN
 	if (hdr->hdr.l2.flags[2] & (QETH_LAYER2_FLAG_VLAN)) {
-		skb_pull(skb, VLAN_HLEN);
 		vlan_id = hdr->hdr.l2.vlan_id;
+		skb_pull(skb, VLAN_HLEN);
 	}
 #endif
 	skb->protocol = qeth_type_trans(skb, skb->dev);
@@ -3260,13 +3271,15 @@
 
 	QETH_DBF_TEXT(trace,3,"qdioclr");
 	if (card->qdio.state == QETH_QDIO_ESTABLISHED){
-		qdio_cleanup(CARD_DDEV(card),
+		if ((rc = qdio_cleanup(CARD_DDEV(card),
 			     (card->info.type == QETH_CARD_TYPE_IQD) ?
 			     QDIO_FLAG_CLEANUP_USING_HALT :
-			     QDIO_FLAG_CLEANUP_USING_CLEAR);
+			     QDIO_FLAG_CLEANUP_USING_CLEAR)))
+			QETH_DBF_TEXT_(trace, 3, "1err%d", rc);
 		card->qdio.state = QETH_QDIO_ALLOCATED;
 	}
-	rc = qeth_clear_halt_card(card, use_halt);
+	if ((rc = qeth_clear_halt_card(card, use_halt)))
+		QETH_DBF_TEXT_(trace, 3, "2err%d", rc);
 	card->state = CARD_STATE_DOWN;
 	return rc;
 }
@@ -3368,6 +3381,26 @@
 	return dev;
 }
 
+/*hard_header fake function; used in case fake_ll is set */
+static int
+qeth_fake_header(struct sk_buff *skb, struct net_device *dev,
+		     unsigned short type, void *daddr, void *saddr,
+		     unsigned len)
+{
+	struct ethhdr *hdr;
+	struct qeth_card *card;
+
+	card = (struct qeth_card *)dev->priv;
+        hdr = (struct ethhdr *)skb_push(skb, QETH_FAKE_LL_LEN);
+	memcpy(hdr->h_source, card->dev->dev_addr, ETH_ALEN);
+        memcpy(hdr->h_dest, "FAKELL", ETH_ALEN);
+        if (type != ETH_P_802_3)
+                hdr->h_proto = htons(type);
+        else
+                hdr->h_proto = htons(len);
+	return QETH_FAKE_LL_LEN;
+}
+
 static inline int
 qeth_send_packet(struct qeth_card *, struct sk_buff *);
 
@@ -3397,6 +3430,14 @@
 	card->perf_stats.outbound_cnt++;
 	card->perf_stats.outbound_start_time = qeth_get_micros();
 #endif
+	if (dev->hard_header == qeth_fake_header) {
+               if ((skb = qeth_pskb_unshare(skb, GFP_ATOMIC)) == NULL) {
+                        card->stats.tx_dropped++;
+                        dev_kfree_skb_irq(skb);
+                        return 0;
+                }
+                skb_pull(skb, QETH_FAKE_LL_LEN);
+	}
 	/*
 	 * We only call netif_stop_queue in case of errors. Since we've
 	 * got our own synchronization on queues we can keep the stack's
@@ -3641,7 +3682,7 @@
 		if (!new_skb) {
 			PRINT_ERR("qeth_prepare_skb: could "
 				  "not realloc headroom for qeth_hdr "
-				  "on interface %s", card->info.if_name);
+				  "on interface %s", QETH_CARD_IFNAME(card));
 			return -ENOMEM;
 		}
 		*skb = new_skb;
@@ -3678,7 +3719,7 @@
 	      QETH_IP_HEADER_SIZE) & (~(PAGE_SIZE - 1)))) {
 		PRINT_ERR("qeth_prepare_skb: misaligned "
 			  "packet on interface %s. Discarded.",
-			  card->info.if_name);
+			  QETH_CARD_IFNAME(card));
 		return -EINVAL;
 	}
 	return 0;
@@ -4185,7 +4226,7 @@
 		return -EOPNOTSUPP;
 	if (!qeth_is_supported(card,IPA_ARP_PROCESSING)) {
 		PRINT_WARN("ARP processing not supported "
-			   "on %s!\n", card->info.if_name);
+			   "on %s!\n", QETH_CARD_IFNAME(card));
 		return -EOPNOTSUPP;
 	}
 	rc = qeth_send_simple_setassparms(card, IPA_ARP_PROCESSING,
@@ -4195,7 +4236,7 @@
 		tmp = rc;
 		PRINT_WARN("Could not set number of ARP entries on %s: "
 			   "%s (0x%x/%d)\n",
-			   card->info.if_name, qeth_arp_get_error_cause(&rc),
+			   QETH_CARD_IFNAME(card), qeth_arp_get_error_cause(&rc),
 			   tmp, tmp);
 	}
 	return rc;
@@ -4368,7 +4409,7 @@
 	if (!qeth_is_supported(card,/*IPA_QUERY_ARP_ADDR_INFO*/
 			       IPA_ARP_PROCESSING)) {
 		PRINT_WARN("ARP processing not supported "
-			   "on %s!\n", card->info.if_name);
+			   "on %s!\n", QETH_CARD_IFNAME(card));
 		return -EOPNOTSUPP;
 	}
 	/* get size of userspace buffer and mask_bits -> 6 bytes */
@@ -4389,7 +4430,7 @@
 		tmp = rc;
 		PRINT_WARN("Error while querying ARP cache on %s: %s "
 			   "(0x%x/%d)\n",
-			   card->info.if_name, qeth_arp_get_error_cause(&rc),
+			   QETH_CARD_IFNAME(card), qeth_arp_get_error_cause(&rc),
 			   tmp, tmp);
 		copy_to_user(udata, qinfo.udata, 4);
 	} else {
@@ -4503,9 +4544,11 @@
 
 	if (card->info.guestlan)
 		return -EOPNOTSUPP;
-	if (!qeth_adp_supported(card,IPA_SETADP_SET_SNMP_CONTROL)) {
+
+	if ((!qeth_adp_supported(card,IPA_SETADP_SET_SNMP_CONTROL)) &&
+	    (!card->options.layer2) ) {
 		PRINT_WARN("SNMP Query MIBS not supported "
-			   "on %s!\n", card->info.if_name);
+			   "on %s!\n", QETH_CARD_IFNAME(card));
 		return -EOPNOTSUPP;
 	}
 	/* skip 4 bytes (data_len struct member) to get req_len */
@@ -4537,7 +4580,7 @@
 				    qeth_snmp_command_cb, (void *)&qinfo);
 	if (rc)
 		PRINT_WARN("SNMP command failed on %s: (0x%x)\n",
-			   card->info.if_name, rc);
+			   QETH_CARD_IFNAME(card), rc);
 	 else
 		copy_to_user(udata, qinfo.udata, qinfo.udata_len);
 
@@ -4577,7 +4620,7 @@
 		return -EOPNOTSUPP;
 	if (!qeth_is_supported(card,IPA_ARP_PROCESSING)) {
 		PRINT_WARN("ARP processing not supported "
-			   "on %s!\n", card->info.if_name);
+			   "on %s!\n", QETH_CARD_IFNAME(card));
 		return -EOPNOTSUPP;
 	}
 
@@ -4594,7 +4637,7 @@
 		qeth_ipaddr4_to_string((u8 *)entry->ipaddr, buf);
 		PRINT_WARN("Could not add ARP entry for address %s on %s: "
 			   "%s (0x%x/%d)\n",
-			   buf, card->info.if_name,
+			   buf, QETH_CARD_IFNAME(card),
 			   qeth_arp_get_error_cause(&rc), tmp, tmp);
 	}
 	return rc;
@@ -4620,7 +4663,7 @@
 		return -EOPNOTSUPP;
 	if (!qeth_is_supported(card,IPA_ARP_PROCESSING)) {
 		PRINT_WARN("ARP processing not supported "
-			   "on %s!\n", card->info.if_name);
+			   "on %s!\n", QETH_CARD_IFNAME(card));
 		return -EOPNOTSUPP;
 	}
 	memcpy(buf, entry, 12);
@@ -4637,7 +4680,7 @@
 		qeth_ipaddr4_to_string((u8 *)entry->ipaddr, buf);
 		PRINT_WARN("Could not delete ARP entry for address %s on %s: "
 			   "%s (0x%x/%d)\n",
-			   buf, card->info.if_name,
+			   buf, QETH_CARD_IFNAME(card),
 			   qeth_arp_get_error_cause(&rc), tmp, tmp);
 	}
 	return rc;
@@ -4661,7 +4704,7 @@
 		return -EOPNOTSUPP;
 	if (!qeth_is_supported(card,IPA_ARP_PROCESSING)) {
 		PRINT_WARN("ARP processing not supported "
-			   "on %s!\n", card->info.if_name);
+			   "on %s!\n", QETH_CARD_IFNAME(card));
 		return -EOPNOTSUPP;
 	}
 	rc = qeth_send_simple_setassparms(card, IPA_ARP_PROCESSING,
@@ -4669,7 +4712,7 @@
 	if (rc){
 		tmp = rc;
 		PRINT_WARN("Could not flush ARP cache on %s: %s (0x%x/%d)\n",
-			   card->info.if_name, qeth_arp_get_error_cause(&rc),
+			   QETH_CARD_IFNAME(card), qeth_arp_get_error_cause(&rc),
 			   tmp, tmp);
 	}
 	return rc;
@@ -4940,7 +4983,7 @@
 	rc = qeth_send_ipa_cmd(card, iob, NULL, NULL);
         if (rc) {
                 PRINT_ERR("Error in processing VLAN %i on %s: 0x%x. "
-			  "Continuing\n",i, card->info.if_name, rc);
+			  "Continuing\n",i, QETH_CARD_IFNAME(card), rc);
 		QETH_DBF_TEXT_(trace, 2, "L2VL%4x", ipacmd);
 		QETH_DBF_TEXT_(trace, 2, "L2%s", CARD_BUS_ID(card));
 		QETH_DBF_TEXT_(trace, 2, "err%d", rc);
@@ -5029,27 +5072,6 @@
 	return 0;
 }
 
-#ifdef CONFIG_QETH_IPV6
-int
-qeth_ipv6_generate_eui64(u8 * eui, struct net_device *dev)
-{
-	switch (dev->type) {
-	case ARPHRD_ETHER:
-	case ARPHRD_FDDI:
-	case ARPHRD_IEEE802_TR:
-		if (dev->addr_len != ETH_ALEN)
-			return -1;
-		memcpy(eui, dev->dev_addr, 3);
-		memcpy(eui + 5, dev->dev_addr + 3, 3);
-		eui[3] = (dev->dev_id >> 8) & 0xff;
-		eui[4] = dev->dev_id & 0xff;
-		return 0;
-	}
-	return -1;
-
-}
-#endif
-
 static void
 qeth_get_mac_for_ipm(__u32 ipm, char *mac, struct net_device *dev)
 {
@@ -5236,7 +5258,10 @@
 
 static int
 qeth_layer2_send_setdelmac(struct qeth_card *card, __u8 *mac,
-			   enum qeth_ipa_cmds ipacmd)
+			   enum qeth_ipa_cmds ipacmd,
+			   int (*reply_cb) (struct qeth_card *,
+					    struct qeth_reply*,
+					    unsigned long))
 {
 	struct qeth_ipa_cmd *cmd;
 	struct qeth_cmd_buffer *iob;
@@ -5246,9 +5271,139 @@
 	cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
         cmd->data.setdelmac.mac_length = OSA_ADDR_LEN;
         memcpy(&cmd->data.setdelmac.mac, mac, OSA_ADDR_LEN);
-	return qeth_send_ipa_cmd(card, iob, NULL, NULL);
+	return qeth_send_ipa_cmd(card, iob, reply_cb, NULL);
+}
+
+static int
+qeth_layer2_send_setgroupmac_cb(struct qeth_card *card,
+				struct qeth_reply *reply,
+				unsigned long data)
+{
+	struct qeth_ipa_cmd *cmd;
+	__u8 *mac;
+
+	QETH_DBF_TEXT(trace, 2, "L2Sgmacb");
+	cmd = (struct qeth_ipa_cmd *) data;
+	mac = &cmd->data.setdelmac.mac[0];
+	/* MAC already registered, needed in couple/uncouple case */
+	if (cmd->hdr.return_code == 0x2005) {
+		PRINT_WARN("Group MAC %02x:%02x:%02x:%02x:%02x:%02x " \
+			  "already existing on %s \n",
+			  mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
+			  QETH_CARD_IFNAME(card));
+		cmd->hdr.return_code = 0;
+	}
+	if (cmd->hdr.return_code)
+		PRINT_ERR("Could not set group MAC " \
+			  "%02x:%02x:%02x:%02x:%02x:%02x on %s: %x\n",
+			  mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
+			  QETH_CARD_IFNAME(card),cmd->hdr.return_code);
+	return 0;
+}
+
+static int
+qeth_layer2_send_setgroupmac(struct qeth_card *card, __u8 *mac)
+{
+	QETH_DBF_TEXT(trace, 2, "L2Sgmac");
+	return qeth_layer2_send_setdelmac(card, mac, IPA_CMD_SETGMAC,
+					  qeth_layer2_send_setgroupmac_cb);
+}
+
+static int
+qeth_layer2_send_delgroupmac_cb(struct qeth_card *card,
+				struct qeth_reply *reply,
+				unsigned long data)
+{
+	struct qeth_ipa_cmd *cmd;
+	__u8 *mac;
+
+	QETH_DBF_TEXT(trace, 2, "L2Dgmacb");
+	cmd = (struct qeth_ipa_cmd *) data;
+	mac = &cmd->data.setdelmac.mac[0];
+	if (cmd->hdr.return_code)
+		PRINT_ERR("Could not delete group MAC " \
+			  "%02x:%02x:%02x:%02x:%02x:%02x on %s: %x\n",
+			  mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
+			  QETH_CARD_IFNAME(card), cmd->hdr.return_code);
+	return 0;
+}
+
+static int
+qeth_layer2_send_delgroupmac(struct qeth_card *card, __u8 *mac)
+{
+	QETH_DBF_TEXT(trace, 2, "L2Dgmac");
+	return qeth_layer2_send_setdelmac(card, mac, IPA_CMD_DELGMAC,
+					  qeth_layer2_send_delgroupmac_cb);
+}
+
+static int
+qeth_layer2_send_setmac_cb(struct qeth_card *card,
+			   struct qeth_reply *reply,
+			   unsigned long data)
+{
+	struct qeth_ipa_cmd *cmd;
+
+	QETH_DBF_TEXT(trace, 2, "L2Smaccb");
+	cmd = (struct qeth_ipa_cmd *) data;
+	if (cmd->hdr.return_code) {
+		QETH_DBF_TEXT_(trace, 2, "L2er%x", cmd->hdr.return_code);
+		PRINT_WARN("Error in registering MAC address on " \
+			   "device %s: x%x\n", CARD_BUS_ID(card),
+			   cmd->hdr.return_code);
+		card->info.layer2_mac_registered = 0;
+		cmd->hdr.return_code = -EIO;
+	} else {
+		card->info.layer2_mac_registered = 1;
+		memcpy(card->dev->dev_addr,cmd->data.setdelmac.mac,
+		       OSA_ADDR_LEN);
+		PRINT_INFO("MAC address %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x "
+			   "successfully registered on device %s\n",
+			   card->dev->dev_addr[0], card->dev->dev_addr[1],
+			   card->dev->dev_addr[2], card->dev->dev_addr[3],
+			   card->dev->dev_addr[4], card->dev->dev_addr[5],
+			   card->dev->name);
+	}
+	return 0;
 }
 
+static int
+qeth_layer2_send_setmac(struct qeth_card *card, __u8 *mac)
+{
+	QETH_DBF_TEXT(trace, 2, "L2Setmac");
+	return qeth_layer2_send_setdelmac(card, mac, IPA_CMD_SETVMAC,
+					  qeth_layer2_send_setmac_cb);
+}
+
+static int
+qeth_layer2_send_delmac_cb(struct qeth_card *card,
+			   struct qeth_reply *reply,
+			   unsigned long data)
+{
+	struct qeth_ipa_cmd *cmd;
+
+	QETH_DBF_TEXT(trace, 2, "L2Dmaccb");
+	cmd = (struct qeth_ipa_cmd *) data;
+	if (cmd->hdr.return_code) {
+		PRINT_WARN("Error in deregistering MAC address on " \
+			   "device %s: x%x\n", CARD_BUS_ID(card),
+			   cmd->hdr.return_code);
+		QETH_DBF_TEXT_(trace, 2, "err%d", cmd->hdr.return_code);
+		cmd->hdr.return_code = -EIO;
+		return 0;
+	}
+	card->info.layer2_mac_registered = 0;
+
+	return 0;
+}
+static int
+qeth_layer2_send_delmac(struct qeth_card *card, __u8 *mac)
+{
+	QETH_DBF_TEXT(trace, 2, "L2Delmac");
+	if (!card->info.layer2_mac_registered)
+		return 0;
+	return qeth_layer2_send_setdelmac(card, mac, IPA_CMD_DELVMAC,
+					  qeth_layer2_send_delmac_cb);
+}
 
 static int
 qeth_layer2_set_mac_address(struct net_device *dev, void *p)
@@ -5273,32 +5428,9 @@
 	}
 	QETH_DBF_TEXT_(trace, 3, "%s", CARD_BUS_ID(card));
 	QETH_DBF_HEX(trace, 3, addr->sa_data, OSA_ADDR_LEN);
-	if (card->info.layer2_mac_registered)
-		rc = qeth_layer2_send_setdelmac(card, &card->dev->dev_addr[0],
-						IPA_CMD_DELVMAC);
-	if (rc) {
-		PRINT_WARN("Error in deregistering MAC address on " \
-			   "device %s: x%x\n", CARD_BUS_ID(card), rc);
-		QETH_DBF_TEXT_(trace, 2, "err%d", rc);
-		return -EIO;
-	}
-	card->info.layer2_mac_registered = 0;
-
-	rc = qeth_layer2_send_setdelmac(card, addr->sa_data, IPA_CMD_SETVMAC);
-	if (rc) {
-		PRINT_WARN("Error in registering MAC address on " \
-			   "device %s: x%x\n", CARD_BUS_ID(card), rc);
-		QETH_DBF_TEXT_(trace, 2, "2err%d", rc);
-		return -EIO;
-	}
-	card->info.layer2_mac_registered = 1;
-	memcpy(dev->dev_addr, addr->sa_data, OSA_ADDR_LEN);
-	PRINT_INFO("MAC address %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x "
-		   "successfully registered on device %s\n",
-		   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->name);
-
+	rc = qeth_layer2_send_delmac(card, &card->dev->dev_addr[0]);
+	if (!rc)
+		rc = qeth_layer2_send_setmac(card, addr->sa_data);
 	return rc;
 }
 
@@ -5409,45 +5541,22 @@
 qeth_layer2_register_addr_entry(struct qeth_card *card,
 				struct qeth_ipaddr *addr)
 {
-	int rc = 0;
-
 	if (!addr->is_multicast)
 		return 0;
-
 	QETH_DBF_TEXT(trace, 2, "setgmac");
 	QETH_DBF_HEX(trace,3,&addr->mac[0],OSA_ADDR_LEN);
-	rc = qeth_layer2_send_setdelmac(card, &addr->mac[0],
-					IPA_CMD_SETGMAC);
-	if (rc)
-		PRINT_ERR("Could not set group MAC " \
-			  "%02x:%02x:%02x:%02x:%02x:%02x on %s: %x\n",
-			  addr->mac[0],addr->mac[1],addr->mac[2],
-			  addr->mac[3],addr->mac[4],addr->mac[5],
-			  card->info.if_name,rc);
-	return rc;
+	return qeth_layer2_send_setgroupmac(card, &addr->mac[0]);
 }
 
 static int
 qeth_layer2_deregister_addr_entry(struct qeth_card *card,
 				  struct qeth_ipaddr *addr)
 {
-	int rc = 0;
-
 	if (!addr->is_multicast)
 		return 0;
-
 	QETH_DBF_TEXT(trace, 2, "delgmac");
 	QETH_DBF_HEX(trace,3,&addr->mac[0],OSA_ADDR_LEN);
-	rc = qeth_layer2_send_setdelmac(card, &addr->mac[0],
-					IPA_CMD_DELGMAC);
-	if (rc)
-		PRINT_ERR("Could not delete group MAC " \
-			  "%02x:%02x:%02x:%02x:%02x:%02x on %s: %x\n",
-			  addr->mac[0],addr->mac[1],addr->mac[2],
-			  addr->mac[3],addr->mac[4],addr->mac[5],
-			  card->info.if_name,rc);
-	return rc;
-
+	return qeth_layer2_send_delgroupmac(card, &addr->mac[0]);
 }
 
 static int
@@ -5567,19 +5676,19 @@
 	dev->vlan_rx_kill_vid = qeth_vlan_rx_kill_vid;
 	dev->vlan_rx_add_vid = qeth_vlan_rx_add_vid;
 #endif
+	dev->hard_header = card->orig_hard_header;
 	if (qeth_get_netdev_flags(card) & IFF_NOARP) {
 		dev->rebuild_header = NULL;
 		dev->hard_header = NULL;
+		if (card->options.fake_ll)
+			dev->hard_header = qeth_fake_header;
 		dev->header_cache_update = NULL;
 		dev->hard_header_cache = NULL;
 	}
 #ifdef CONFIG_QETH_IPV6
 	/*IPv6 address autoconfiguration stuff*/
-	card->dev->dev_id = card->info.unique_id & 0xffff;
 	if (!(card->info.unique_id & UNIQUE_ID_NOT_BY_CARD))
-		card->dev->generate_eui64 = qeth_ipv6_generate_eui64;
-
-
+		card->dev->dev_id = card->info.unique_id & 0xffff;
 #endif
 	dev->hard_header_parse = NULL;
 	dev->set_mac_address = qeth_layer2_set_mac_address;
@@ -5680,22 +5789,26 @@
 		QETH_DBF_TEXT_(setup, 2, "5err%d", rc);
 		goto out;
 	}
+	/*network device will be recovered*/
+	if (card->dev) {
+		card->dev->hard_header = card->orig_hard_header;
+		return 0;
+	}
 	/* at first set_online allocate netdev */
+	card->dev = qeth_get_netdevice(card->info.type,
+				       card->info.link_type);
 	if (!card->dev){
-		card->dev = qeth_get_netdevice(card->info.type,
-					       card->info.link_type);
-		if (!card->dev){
-			qeth_qdio_clear_card(card, card->info.type ==
-					     QETH_CARD_TYPE_OSAE);
-			rc = -ENODEV;
-			QETH_DBF_TEXT_(setup, 2, "6err%d", rc);
-			goto out;
-		}
-		card->dev->priv = card;
-		card->dev->type = qeth_get_arphdr_type(card->info.type,
-						       card->info.link_type);
-		card->dev->init = qeth_netdev_init;
+		qeth_qdio_clear_card(card, card->info.type ==
+				     QETH_CARD_TYPE_OSAE);
+		rc = -ENODEV;
+		QETH_DBF_TEXT_(setup, 2, "6err%d", rc);
+		goto out;
 	}
+	card->dev->priv = card;
+	card->orig_hard_header = card->dev->hard_header;
+	card->dev->type = qeth_get_arphdr_type(card->info.type,
+					       card->info.link_type);
+	card->dev->init = qeth_netdev_init;
 	return 0;
 out:
 	PRINT_ERR("Initialization in hardsetup failed! rc=%d\n", rc);
@@ -5914,15 +6027,9 @@
         }
 	QETH_DBF_HEX(setup,2, card->dev->dev_addr, OSA_ADDR_LEN);
 
-	rc = qeth_layer2_send_setdelmac(card, &card->dev->dev_addr[0],
-					IPA_CMD_SETVMAC);
-        if (rc) {
-		card->info.layer2_mac_registered = 0;
-                PRINT_WARN("Error in processing MAC address on " \
-                           "device %s: x%x\n",CARD_BUS_ID(card),rc);
+	rc = qeth_layer2_send_setmac(card, &card->dev->dev_addr[0]);
+        if (rc)
 		QETH_DBF_TEXT_(setup, 2,"2err%d",rc);
-        } else
-		card->info.layer2_mac_registered = 1;
         return 0;
 }
 
@@ -6094,7 +6201,7 @@
 
 	if (!qeth_is_supported(card,IPA_ARP_PROCESSING)) {
 		PRINT_WARN("ARP processing not supported "
-			   "on %s!\n", card->info.if_name);
+			   "on %s!\n", QETH_CARD_IFNAME(card));
 		return 0;
 	}
 	rc = qeth_send_simple_setassparms(card,IPA_ARP_PROCESSING,
@@ -6102,7 +6209,7 @@
 	if (rc) {
 		PRINT_WARN("Could not start ARP processing "
 			   "assist on %s: 0x%x\n",
-			   card->info.if_name, rc);
+			   QETH_CARD_IFNAME(card), rc);
 	}
 	return rc;
 }
@@ -6116,7 +6223,7 @@
 
 	if (!qeth_is_supported(card, IPA_IP_FRAGMENTATION)) {
 		PRINT_INFO("Hardware IP fragmentation not supported on %s\n",
-			   card->info.if_name);
+			   QETH_CARD_IFNAME(card));
 		return  -EOPNOTSUPP;
 	}
 
@@ -6125,7 +6232,7 @@
 	if (rc) {
 		PRINT_WARN("Could not start Hardware IP fragmentation "
 			   "assist on %s: 0x%x\n",
-			   card->info.if_name, rc);
+			   QETH_CARD_IFNAME(card), rc);
 	} else
 		PRINT_INFO("Hardware IP fragmentation enabled \n");
 	return rc;
@@ -6143,7 +6250,7 @@
 
 	if (!qeth_is_supported(card, IPA_SOURCE_MAC)) {
 		PRINT_INFO("Inbound source address not "
-			   "supported on %s\n", card->info.if_name);
+			   "supported on %s\n", QETH_CARD_IFNAME(card));
 		return -EOPNOTSUPP;
 	}
 
@@ -6152,7 +6259,7 @@
 	if (rc)
 		PRINT_WARN("Could not start inbound source "
 			   "assist on %s: 0x%x\n",
-			   card->info.if_name, rc);
+			   QETH_CARD_IFNAME(card), rc);
 	return rc;
 }
 
@@ -6165,7 +6272,7 @@
 
 #ifdef CONFIG_QETH_VLAN
 	if (!qeth_is_supported(card, IPA_FULL_VLAN)) {
-		PRINT_WARN("VLAN not supported on %s\n", card->info.if_name);
+		PRINT_WARN("VLAN not supported on %s\n", QETH_CARD_IFNAME(card));
 		return -EOPNOTSUPP;
 	}
 
@@ -6174,7 +6281,7 @@
 	if (rc) {
 		PRINT_WARN("Could not start vlan "
 			   "assist on %s: 0x%x\n",
-			   card->info.if_name, rc);
+			   QETH_CARD_IFNAME(card), rc);
 	} else {
 		PRINT_INFO("VLAN enabled \n");
 		card->dev->features |=
@@ -6195,7 +6302,7 @@
 
 	if (!qeth_is_supported(card, IPA_MULTICASTING)) {
 		PRINT_WARN("Multicast not supported on %s\n",
-			   card->info.if_name);
+			   QETH_CARD_IFNAME(card));
 		return -EOPNOTSUPP;
 	}
 
@@ -6204,7 +6311,7 @@
 	if (rc) {
 		PRINT_WARN("Could not start multicast "
 			   "assist on %s: rc=%i\n",
-			   card->info.if_name, rc);
+			   QETH_CARD_IFNAME(card), rc);
 	} else {
 		PRINT_INFO("Multicast enabled\n");
 		card->dev->flags |= IFF_MULTICAST;
@@ -6224,14 +6331,14 @@
 	rc = qeth_send_startlan(card, QETH_PROT_IPV6);
 	if (rc) {
 		PRINT_ERR("IPv6 startlan failed on %s\n",
-			  card->info.if_name);
+			  QETH_CARD_IFNAME(card));
 		return rc;
 	}
 	netif_wake_queue(card->dev);
 	rc = qeth_query_ipassists(card,QETH_PROT_IPV6);
 	if (rc) {
 		PRINT_ERR("IPv6 query ipassist failed on %s\n",
-			  card->info.if_name);
+			  QETH_CARD_IFNAME(card));
 		return rc;
 	}
 	rc = qeth_send_simple_setassparms(card, IPA_IPV6,
@@ -6239,7 +6346,7 @@
 	if (rc) {
 		PRINT_WARN("IPv6 start assist (version 4) failed "
 			   "on %s: 0x%x\n",
-			   card->info.if_name, rc);
+			   QETH_CARD_IFNAME(card), rc);
 		return rc;
 	}
 	rc = qeth_send_simple_setassparms_ipv6(card, IPA_IPV6,
@@ -6247,7 +6354,7 @@
 	if (rc) {
 		PRINT_WARN("IPV6 start assist (version 6) failed  "
 			   "on %s: 0x%x\n",
-			   card->info.if_name, rc);
+			   QETH_CARD_IFNAME(card), rc);
 		return rc;
 	}
 	rc = qeth_send_simple_setassparms_ipv6(card, IPA_PASSTHRU,
@@ -6255,7 +6362,7 @@
 	if (rc) {
 		PRINT_WARN("Could not enable passthrough "
 			   "on %s: 0x%x\n",
-			   card->info.if_name, rc);
+			   QETH_CARD_IFNAME(card), rc);
 		return rc;
 	}
 	PRINT_INFO("IPV6 enabled \n");
@@ -6273,7 +6380,7 @@
 
 	if (!qeth_is_supported(card, IPA_IPV6)) {
 		PRINT_WARN("IPv6 not supported on %s\n",
-			   card->info.if_name);
+			   QETH_CARD_IFNAME(card));
 		return 0;
 	}
 	rc = qeth_softsetup_ipv6(card);
@@ -6290,7 +6397,7 @@
 	card->info.broadcast_capable = 0;
 	if (!qeth_is_supported(card, IPA_FILTERING)) {
 		PRINT_WARN("Broadcast not supported on %s\n",
-			   card->info.if_name);
+			   QETH_CARD_IFNAME(card));
 		rc = -EOPNOTSUPP;
 		goto out;
 	}
@@ -6299,7 +6406,7 @@
 	if (rc) {
 		PRINT_WARN("Could not enable broadcasting filtering "
 			   "on %s: 0x%x\n",
-			   card->info.if_name, rc);
+			   QETH_CARD_IFNAME(card), rc);
 		goto out;
 	}
 
@@ -6307,7 +6414,7 @@
 					  IPA_CMD_ASS_CONFIGURE, 1);
 	if (rc) {
 		PRINT_WARN("Could not set up broadcast filtering on %s: 0x%x\n",
-			   card->info.if_name, rc);
+			   QETH_CARD_IFNAME(card), rc);
 		goto out;
 	}
 	card->info.broadcast_capable = QETH_BROADCAST_WITH_ECHO;
@@ -6316,7 +6423,7 @@
 					  IPA_CMD_ASS_ENABLE, 1);
 	if (rc) {
 		PRINT_WARN("Could not set up broadcast echo filtering on "
-			   "%s: 0x%x\n", card->info.if_name, rc);
+			   "%s: 0x%x\n", QETH_CARD_IFNAME(card), rc);
 		goto out;
 	}
 	card->info.broadcast_capable = QETH_BROADCAST_WITHOUT_ECHO;
@@ -6338,7 +6445,7 @@
 	if (rc) {
 		PRINT_WARN("Starting Inbound HW Checksumming failed on %s: "
 			   "0x%x,\ncontinuing using Inbound SW Checksumming\n",
-			   card->info.if_name, rc);
+			   QETH_CARD_IFNAME(card), rc);
 		return rc;
 	}
 	rc = qeth_send_simple_setassparms(card, IPA_INBOUND_CHECKSUM,
@@ -6347,7 +6454,7 @@
 	if (rc) {
 		PRINT_WARN("Enabling Inbound HW Checksumming failed on %s: "
 			   "0x%x,\ncontinuing using Inbound SW Checksumming\n",
-			   card->info.if_name, rc);
+			   QETH_CARD_IFNAME(card), rc);
 		return rc;
 	}
 	return 0;
@@ -6362,19 +6469,19 @@
 
 	if (card->options.checksum_type == NO_CHECKSUMMING) {
 		PRINT_WARN("Using no checksumming on %s.\n",
-			   card->info.if_name);
+			   QETH_CARD_IFNAME(card));
 		return 0;
 	}
 	if (card->options.checksum_type == SW_CHECKSUMMING) {
 		PRINT_WARN("Using SW checksumming on %s.\n",
-			   card->info.if_name);
+			   QETH_CARD_IFNAME(card));
 		return 0;
 	}
 	if (!qeth_is_supported(card, IPA_INBOUND_CHECKSUM)) {
 		PRINT_WARN("Inbound HW Checksumming not "
 			   "supported on %s,\ncontinuing "
 			   "using Inbound SW Checksumming\n",
-			   card->info.if_name);
+			   QETH_CARD_IFNAME(card));
 		card->options.checksum_type = SW_CHECKSUMMING;
 		return 0;
 	}
@@ -6496,7 +6603,7 @@
  		card->options.route4.type = NO_ROUTER;
 		PRINT_WARN("Error (0x%04x) while setting routing type on %s. "
 			   "Type set to 'no router'.\n",
-			   rc, card->info.if_name);
+			   rc, QETH_CARD_IFNAME(card));
 	}
 	return rc;
 }
@@ -6523,7 +6630,7 @@
 	 	card->options.route6.type = NO_ROUTER;
 		PRINT_WARN("Error (0x%04x) while setting routing type on %s. "
 			   "Type set to 'no router'.\n",
-			   rc, card->info.if_name);
+			   rc, QETH_CARD_IFNAME(card));
 	}
 #endif
 	return rc;
@@ -6720,9 +6827,8 @@
 		rtnl_unlock();
 		if (!card->use_hard_stop) {
 			__u8 *mac = &card->dev->dev_addr[0];
-			if ((rc = qeth_layer2_send_setdelmac(card, mac,
-							    IPA_CMD_DELVMAC)));
-				QETH_DBF_TEXT_(setup, 2, "Lerr%d", rc);
+			rc = qeth_layer2_send_delmac(card, mac);
+			QETH_DBF_TEXT_(setup, 2, "Lerr%d", rc);
 			if ((rc = qeth_send_stoplan(card)))
 				QETH_DBF_TEXT_(setup, 2, "1err%d", rc);
 		}
@@ -6879,18 +6985,14 @@
 static int
 qeth_register_netdev(struct qeth_card *card)
 {
-	int rc;
-
 	QETH_DBF_TEXT(setup, 3, "regnetd");
-	if (card->dev->reg_state != NETREG_UNINITIALIZED)
+	if (card->dev->reg_state != NETREG_UNINITIALIZED) {
+		qeth_netdev_init(card->dev);
 		return 0;
+	}
 	/* sysfs magic */
 	SET_NETDEV_DEV(card->dev, &card->gdev->dev);
-	rc = register_netdev(card->dev);
-	if (!rc)
-		strcpy(card->info.if_name, card->dev->name);
-
-	return rc;
+	return register_netdev(card->dev);
 }
 
 static void
@@ -6975,9 +7077,9 @@
 	}
 
 	recover_flag = card->state;
-	if (ccw_device_set_online(CARD_RDEV(card)) ||
-	    ccw_device_set_online(CARD_WDEV(card)) ||
-	    ccw_device_set_online(CARD_DDEV(card))){
+	if ((rc = ccw_device_set_online(CARD_RDEV(card))) ||
+	    (rc = ccw_device_set_online(CARD_WDEV(card))) ||
+	    (rc = ccw_device_set_online(CARD_DDEV(card)))){
 		QETH_DBF_TEXT_(setup, 2, "1err%d", rc);
 		return -EIO;
 	}
@@ -7171,7 +7273,8 @@
 	card = qeth_get_card_from_dev(dev);
 	if (card == NULL)
 		goto out;
-	if(card->options.layer2)
+	if((card->options.layer2) ||
+	   (card->dev->hard_header == qeth_fake_header))
 		goto out;
 
 	rcu_read_lock();
diff -Nru a/drivers/s390/net/qeth_proc.c b/drivers/s390/net/qeth_proc.c
--- a/drivers/s390/net/qeth_proc.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/s390/net/qeth_proc.c	2005-03-01 23:38:58 -08:00
@@ -1,6 +1,6 @@
 /*
  *
- * linux/drivers/s390/net/qeth_fs.c ($Revision: 1.10 $)
+ * linux/drivers/s390/net/qeth_fs.c ($Revision: 1.13 $)
  *
  * Linux on zSeries OSA Express and HiperSockets support
  * This file contains code related to procfs.
@@ -21,7 +21,7 @@
 #include "qeth_mpc.h"
 #include "qeth_fs.h"
 
-const char *VERSION_QETH_PROC_C = "$Revision: 1.10 $";
+const char *VERSION_QETH_PROC_C = "$Revision: 1.13 $";
 
 /***** /proc/qeth *****/
 #define QETH_PROCFILE_NAME "qeth"
@@ -133,7 +133,7 @@
 				CARD_WDEV_ID(card),
 				CARD_DDEV_ID(card),
 				card->info.chpid,
-				card->info.if_name,
+				QETH_CARD_IFNAME(card),
 				qeth_get_cardname_short(card),
 				card->info.portno);
 		if (card->lan_online)
@@ -222,7 +222,7 @@
 			CARD_RDEV_ID(card),
 			CARD_WDEV_ID(card),
 			CARD_DDEV_ID(card),
-			card->info.if_name
+			QETH_CARD_IFNAME(card)
 		  );
 	seq_printf(s, "  Skb's/buffers received                 : %li/%i\n"
 		      "  Skb's/buffers sent                     : %li/%i\n\n",
diff -Nru a/drivers/s390/net/qeth_sys.c b/drivers/s390/net/qeth_sys.c
--- a/drivers/s390/net/qeth_sys.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/s390/net/qeth_sys.c	2005-03-01 23:38:58 -08:00
@@ -1,6 +1,6 @@
 /*
  *
- * linux/drivers/s390/net/qeth_sys.c ($Revision: 1.40 $)
+ * linux/drivers/s390/net/qeth_sys.c ($Revision: 1.49 $)
  *
  * Linux on zSeries OSA Express and HiperSockets support
  * This file contains code related to sysfs.
@@ -20,7 +20,7 @@
 #include "qeth_mpc.h"
 #include "qeth_fs.h"
 
-const char *VERSION_QETH_SYS_C = "$Revision: 1.40 $";
+const char *VERSION_QETH_SYS_C = "$Revision: 1.49 $";
 
 /*****************************************************************************/
 /*                                                                           */
@@ -75,8 +75,7 @@
 	struct qeth_card *card = dev->driver_data;
 	if (!card)
 		return -EINVAL;
-
-	return sprintf(buf, "%s\n", card->info.if_name);
+	return sprintf(buf, "%s\n", QETH_CARD_IFNAME(card));
 }
 
 static DEVICE_ATTR(if_name, 0444, qeth_dev_if_name_show, NULL);
@@ -440,7 +439,7 @@
 	if (!qeth_is_supported(card, IPA_IPV6)){
 		PRINT_WARN("IPv6 not supported for interface %s.\n"
 			   "Routing status no changed.\n",
-			   card->info.if_name);
+			   QETH_CARD_IFNAME(card));
 		return -ENOTSUPP;
 	}
 
@@ -515,12 +514,11 @@
 		return -EPERM;
 
 	i = simple_strtoul(buf, &tmp, 16);
-	if ((i == 0) || (i == 1))
-		card->options.fake_ll = i;
-	else {
+	if ((i != 0) && (i != 1)) {
 		PRINT_WARN("fake_ll: write 0 or 1 to this file!\n");
 		return -EINVAL;
 	}
+	card->options.fake_ll = i;
 	return count;
 }
 
@@ -715,8 +713,9 @@
 	if (!card)
 		return -EINVAL;
 
-	if ((card->state != CARD_STATE_DOWN) &&
-	    (card->state != CARD_STATE_RECOVER))
+	if (((card->state != CARD_STATE_DOWN) &&
+	     (card->state != CARD_STATE_RECOVER)) ||
+	    (card->info.type != QETH_CARD_TYPE_OSAE))
 		return -EPERM;
 
 	i = simple_strtoul(buf, &tmp, 16);
diff -Nru a/drivers/s390/net/smsgiucv.c b/drivers/s390/net/smsgiucv.c
--- a/drivers/s390/net/smsgiucv.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/s390/net/smsgiucv.c	2005-03-01 23:38:52 -08:00
@@ -41,7 +41,7 @@
 
 static iucv_handle_t smsg_handle;
 static unsigned short smsg_pathid;
-static spinlock_t smsg_list_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(smsg_list_lock);
 static struct list_head smsg_list = LIST_HEAD_INIT(smsg_list);
 
 static void
diff -Nru a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c
--- a/drivers/s390/scsi/zfcp_erp.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/s390/scsi/zfcp_erp.c	2005-03-01 23:39:18 -08:00
@@ -31,7 +31,7 @@
 
 #define ZFCP_LOG_AREA			ZFCP_LOG_AREA_ERP
 
-#define ZFCP_ERP_REVISION "$Revision: 1.85 $"
+#define ZFCP_ERP_REVISION "$Revision: 1.86 $"
 
 #include "zfcp_ext.h"
 
@@ -369,7 +369,7 @@
 		ZFCP_LOG_NORMAL("error: initiation of Send ELS failed for port "
 				"0x%08x on adapter %s\n", d_id,
 				zfcp_get_busid_by_adapter(adapter));
-		del_timer_sync(send_els->timer);
+		del_timer(send_els->timer);
 		goto freemem;
 	}
 
@@ -969,7 +969,7 @@
 		debug_event(adapter->erp_dbf, 2, &erp_action->action,
 			    sizeof (int));
 		if (!(set_mask & ZFCP_STATUS_ERP_TIMEDOUT))
-			del_timer_sync(&erp_action->timer);
+			del_timer(&erp_action->timer);
 		erp_action->status |= set_mask;
 		zfcp_erp_action_ready(erp_action);
 		retval = 0;
diff -Nru a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
--- a/drivers/s390/scsi/zfcp_fsf.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/s390/scsi/zfcp_fsf.c	2005-03-01 23:39:08 -08:00
@@ -30,7 +30,7 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#define ZFCP_FSF_C_REVISION "$Revision: 1.88 $"
+#define ZFCP_FSF_C_REVISION "$Revision: 1.92 $"
 
 #include "zfcp_ext.h"
 
@@ -3203,7 +3203,9 @@
 			      sizeof (union fsf_status_qual));
 		debug_text_event(adapter->erp_dbf, 2,
 				 "fsf_s_l_sh_vio");
-		zfcp_erp_unit_failed(unit);
+		zfcp_erp_unit_access_denied(unit);
+		atomic_clear_mask(ZFCP_STATUS_UNIT_SHARED, &unit->status);
+		atomic_clear_mask(ZFCP_STATUS_UNIT_READONLY, &unit->status);
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
 
@@ -4320,22 +4322,19 @@
 
 	/* check for underrun */
 	if (unlikely(fcp_rsp_iu->validity.bits.fcp_resid_under)) {
-		ZFCP_LOG_DEBUG("A data underrun was detected for a command. "
-			       "unit 0x%016Lx, port 0x%016Lx, adapter %s. "
-			       "The response data length is "
-			       "%d, the original length was %d.\n",
-			       unit->fcp_lun,
-			       unit->port->wwpn,
-			       zfcp_get_busid_by_unit(unit),
-			       fcp_rsp_iu->fcp_resid,
-			       (int) zfcp_get_fcp_dl(fcp_cmnd_iu));
-		/*
-		 * It may not have been possible to send all data and the
-		 * underrun on send may already be in scpnt->resid, so it's add
-		 * not equals in the below statement.
-		 */
-		scpnt->resid += fcp_rsp_iu->fcp_resid;
-		ZFCP_LOG_TRACE("scpnt->resid=0x%x\n", scpnt->resid);
+		ZFCP_LOG_INFO("A data underrun was detected for a command. "
+			      "unit 0x%016Lx, port 0x%016Lx, adapter %s. "
+			      "The response data length is "
+			      "%d, the original length was %d.\n",
+			      unit->fcp_lun,
+			      unit->port->wwpn,
+			      zfcp_get_busid_by_unit(unit),
+			      fcp_rsp_iu->fcp_resid,
+			      (int) zfcp_get_fcp_dl(fcp_cmnd_iu));
+
+		scpnt->resid = fcp_rsp_iu->fcp_resid;
+		if (scpnt->request_bufflen - scpnt->resid < scpnt->underflow)
+			scpnt->result |= DID_ERROR << 16;
 	}
 
  skip_fsfstatus:
@@ -5023,7 +5022,7 @@
 		 * timer might be expired (absolutely unlikely)
 		 */
 		if (timer)
-			del_timer_sync(timer);
+			del_timer(timer);
 		write_lock_irqsave(&adapter->fsf_req_list_lock, flags);
 		list_del(&fsf_req->list);
 		write_unlock_irqrestore(&adapter->fsf_req_list_lock, flags);
diff -Nru a/drivers/sbus/char/bpp.c b/drivers/sbus/char/bpp.c
--- a/drivers/sbus/char/bpp.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/sbus/char/bpp.c	2005-03-01 23:39:18 -08:00
@@ -432,7 +432,7 @@
       return 0;
 }
 
-static spinlock_t bpp_open_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(bpp_open_lock);
 
 /*
  * Allow only one process to open the device at a time.
diff -Nru a/drivers/sbus/char/flash.c b/drivers/sbus/char/flash.c
--- a/drivers/sbus/char/flash.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/sbus/char/flash.c	2005-03-01 23:38:58 -08:00
@@ -24,7 +24,7 @@
 #include <asm/ebus.h>
 #include <asm/upa.h>
 
-static spinlock_t flash_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(flash_lock);
 static struct {
 	unsigned long read_base;	/* Physical read address */
 	unsigned long write_base;	/* Physical write address */
diff -Nru a/drivers/sbus/char/jsflash.c b/drivers/sbus/char/jsflash.c
--- a/drivers/sbus/char/jsflash.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/sbus/char/jsflash.c	2005-03-01 23:38:56 -08:00
@@ -539,7 +539,7 @@
 
 static int jsfd_init(void)
 {
-	static spinlock_t lock = SPIN_LOCK_UNLOCKED;
+	static DEFINE_SPINLOCK(lock);
 	struct jsflash *jsf;
 	struct jsfd_part *jdp;
 	int err;
diff -Nru a/drivers/sbus/char/riowatchdog.c b/drivers/sbus/char/riowatchdog.c
--- a/drivers/sbus/char/riowatchdog.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/sbus/char/riowatchdog.c	2005-03-01 23:38:57 -08:00
@@ -52,7 +52,7 @@
 #define RIOWD_NAME	"pmc"
 #define RIOWD_MINOR	215
 
-static spinlock_t riowd_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(riowd_lock);
 
 static void __iomem *bbc_regs;
 static void __iomem *riowd_regs;
diff -Nru a/drivers/sbus/char/rtc.c b/drivers/sbus/char/rtc.c
--- a/drivers/sbus/char/rtc.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/sbus/char/rtc.c	2005-03-01 23:38:54 -08:00
@@ -20,6 +20,7 @@
 #include <linux/poll.h>
 #include <linux/init.h>
 #include <linux/smp_lock.h>
+#include <asm/io.h>
 #include <asm/mostek.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -30,7 +31,7 @@
 /* Retrieve the current date and time from the real time clock. */
 static void get_rtc_time(struct rtc_time *t)
 {
-	unsigned long regs = mstk48t02_regs;
+	void * __iomem regs = mstk48t02_regs;
 	u8 tmp;
 
 	spin_lock_irq(&mostek_lock);
@@ -57,7 +58,7 @@
 /* Set the current date and time inthe real time clock. */
 void set_rtc_time(struct rtc_time *t)
 {
-	unsigned long regs = mstk48t02_regs;
+	void * __iomem regs = mstk48t02_regs;
 	u8 tmp;
 
 	spin_lock_irq(&mostek_lock);
diff -Nru a/drivers/sbus/char/vfc_dev.c b/drivers/sbus/char/vfc_dev.c
--- a/drivers/sbus/char/vfc_dev.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/sbus/char/vfc_dev.c	2005-03-01 23:38:58 -08:00
@@ -178,7 +178,7 @@
 	return vfc_dev_lst[instance];
 }
 
-static spinlock_t vfc_dev_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(vfc_dev_lock);
 
 static int vfc_open(struct inode *inode, struct file *file) 
 {
diff -Nru a/drivers/sbus/sbus.c b/drivers/sbus/sbus.c
--- a/drivers/sbus/sbus.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/sbus/sbus.c	2005-03-01 23:39:18 -08:00
@@ -217,6 +217,8 @@
  * prom_sbus_ranges_init(), with all sun4d stuff cut away.
  * Ask DaveM what is going on here, how is sun4d supposed to work... XXX
  */
+/* added back sun4d patch from Thomas Bogendoerfer - should be OK (crn) */
+
 static void __init sbus_bus_ranges_init(int parent_node, struct sbus_bus *sbus)
 {
 	int len;
@@ -229,6 +231,20 @@
 		return;
 	}
 	sbus->num_sbus_ranges = len / sizeof(struct linux_prom_ranges);
+#ifdef CONFIG_SPARC32
+	if (sparc_cpu_model == sun4d) {
+		struct linux_prom_ranges iounit_ranges[PROMREG_MAX];
+		int num_iounit_ranges;
+
+		len = prom_getproperty(parent_node, "ranges",
+				       (char *) iounit_ranges,
+				       sizeof (iounit_ranges));
+		if (len != -1) {
+			num_iounit_ranges = (len/sizeof(struct linux_prom_ranges));
+			prom_adjust_ranges (sbus->sbus_ranges, sbus->num_sbus_ranges, iounit_ranges, num_iounit_ranges);
+		}
+	}
+#endif
 }
 
 static void __init __apply_ranges_to_regs(struct linux_prom_ranges *ranges,
diff -Nru a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c
--- a/drivers/scsi/53c700.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/scsi/53c700.c	2005-03-01 23:38:53 -08:00
@@ -176,6 +176,8 @@
 STATIC void NCR_700_chip_reset(struct Scsi_Host *host);
 STATIC int NCR_700_slave_configure(struct scsi_device *SDpnt);
 STATIC void NCR_700_slave_destroy(struct scsi_device *SDpnt);
+static int NCR_700_change_queue_depth(struct scsi_device *SDpnt, int depth);
+static int NCR_700_change_queue_type(struct scsi_device *SDpnt, int depth);
 
 STATIC struct device_attribute *NCR_700_dev_attrs[];
 
@@ -338,6 +340,8 @@
 	tpnt->use_clustering = ENABLE_CLUSTERING;
 	tpnt->slave_configure = NCR_700_slave_configure;
 	tpnt->slave_destroy = NCR_700_slave_destroy;
+	tpnt->change_queue_depth = NCR_700_change_queue_depth;
+	tpnt->change_queue_type = NCR_700_change_queue_type;
 	
 	if(tpnt->name == NULL)
 		tpnt->name = "53c700";
@@ -924,10 +928,11 @@
 				spi_offset(SCp->device->sdev_target) = 0;
 			NCR_700_set_flag(SCp->device, NCR_700_DEV_NEGOTIATED_SYNC);
 			NCR_700_clear_flag(SCp->device, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION);
-		} else if(SCp != NULL && NCR_700_is_flag_set(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING)) {
+		} else if(SCp != NULL && NCR_700_get_tag_neg_state(SCp->device) == NCR_700_DURING_TAG_NEGOTIATION) {
 			/* rejected our first simple tag message */
 			printk(KERN_WARNING "scsi%d (%d:%d) Rejected first tag queue attempt, turning off tag queueing\n", host->host_no, pun, lun);
-			NCR_700_clear_flag(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING);
+			/* we're done negotiating */
+			NCR_700_set_tag_neg_state(SCp->device, NCR_700_FINISHED_TAG_NEGOTIATION);
 			hostdata->tag_negotiated &= ~(1<<SCp->device->id);
 			SCp->device->tagged_supported = 0;
 			scsi_deactivate_tcq(SCp->device, host->cmd_per_lun);
@@ -989,8 +994,11 @@
 	if(dsps == A_GOOD_STATUS_AFTER_STATUS) {
 		DEBUG(("  COMMAND COMPLETE, status=%02x\n",
 		       hostdata->status[0]));
-		/* OK, if TCQ still on, we know it works */
-		NCR_700_clear_flag(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING);
+		/* OK, if TCQ still under negotiation, we now know it works */
+		if (NCR_700_get_tag_neg_state(SCp->device) == NCR_700_DURING_TAG_NEGOTIATION)
+			NCR_700_set_tag_neg_state(SCp->device,
+						  NCR_700_FINISHED_TAG_NEGOTIATION);
+			
 		/* check for contingent allegiance contitions */
 		if(status_byte(hostdata->status[0]) == CHECK_CONDITION ||
 		   status_byte(hostdata->status[0]) == COMMAND_TERMINATED) {
@@ -1811,23 +1819,12 @@
 	printk("53c700: scsi%d, command ", SCp->device->host->host_no);
 	scsi_print_command(SCp);
 #endif
-	if(SCp->device->tagged_supported && !SCp->device->simple_tags
-	   && (hostdata->tag_negotiated &(1<<SCp->device->id)) == 0
-	   && NCR_700_is_flag_clear(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING)) {
-		/* upper layer has indicated tags are supported.  We don't
-		 * necessarily believe it yet.
-		 *
-		 * NOTE: There is a danger here: the mid layer supports
-		 * tag queuing per LUN.  We only support it per PUN because
-		 * of potential reselection issues */
-		scsi_activate_tcq(SCp->device, NCR_700_DEFAULT_TAGS);
-	}
-
 	if(blk_rq_tagged(SCp->request)
-	   && (hostdata->tag_negotiated &(1<<SCp->device->id)) == 0) {
-		printk(KERN_INFO "scsi%d: (%d:%d) Enabling Tag Command Queuing\n", SCp->device->host->host_no, SCp->device->id, SCp->device->lun);
+	   && (hostdata->tag_negotiated &(1<<SCp->device->id)) == 0
+	   && NCR_700_get_tag_neg_state(SCp->device) == NCR_700_START_TAG_NEGOTIATION) {
+		printk(KERN_ERR "scsi%d: (%d:%d) Enabling Tag Command Queuing\n", SCp->device->host->host_no, SCp->device->id, SCp->device->lun);
 		hostdata->tag_negotiated |= (1<<SCp->device->id);
-		NCR_700_set_flag(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING);
+		NCR_700_set_tag_neg_state(SCp->device, NCR_700_DURING_TAG_NEGOTIATION);
 	}
 
 	/* here we may have to process an untagged command.  The gate
@@ -1842,7 +1839,8 @@
 		hostdata->tag_negotiated &= ~(1<<SCp->device->id);
 	}
 
-	if((hostdata->tag_negotiated &(1<<SCp->device->id))) {
+	if((hostdata->tag_negotiated &(1<<SCp->device->id))
+	   && scsi_get_tag_type(SCp->device)) {
 		slot->tag = SCp->request->tag;
 		DEBUG(("53c700 %d:%d:%d, sending out tag %d, slot %p\n",
 		       SCp->device->host->host_no, SCp->device->id, SCp->device->lun, slot->tag,
@@ -2080,7 +2078,9 @@
 
 	/* to do here: allocate memory; build a queue_full list */
 	if(SDp->tagged_supported) {
-		/* do TCQ stuff here */
+		scsi_set_tag_type(SDp, MSG_ORDERED_TAG);
+		scsi_activate_tcq(SDp, NCR_700_DEFAULT_TAGS);
+		NCR_700_set_tag_neg_state(SDp, NCR_700_START_TAG_NEGOTIATION);
 	} else {
 		/* initialise to default depth */
 		scsi_adjust_queue_depth(SDp, 0, SDp->host->cmd_per_lun);
@@ -2102,18 +2102,48 @@
 	/* to do here: deallocate memory */
 }
 
-static ssize_t
-NCR_700_store_queue_depth(struct device *dev, const char *buf, size_t count)
+static int
+NCR_700_change_queue_depth(struct scsi_device *SDp, int depth)
 {
-	int depth;
+	if (depth > NCR_700_MAX_TAGS)
+		depth = NCR_700_MAX_TAGS;
 
-	struct scsi_device *SDp = to_scsi_device(dev);
-	depth = simple_strtoul(buf, NULL, 0);
-	if(depth > NCR_700_MAX_TAGS)
-		return -EINVAL;
-	scsi_adjust_queue_depth(SDp, MSG_ORDERED_TAG, depth);
+	scsi_adjust_queue_depth(SDp, scsi_get_tag_type(SDp), depth);
+	return depth;
+}
 
-	return count;
+static int NCR_700_change_queue_type(struct scsi_device *SDp, int tag_type)
+{
+	int change_tag = ((tag_type ==0 &&  scsi_get_tag_type(SDp) != 0)
+			  || (tag_type != 0 && scsi_get_tag_type(SDp) == 0));
+	struct NCR_700_Host_Parameters *hostdata = 
+		(struct NCR_700_Host_Parameters *)SDp->host->hostdata[0];
+
+	scsi_set_tag_type(SDp, tag_type);
+
+	/* We have a global (per target) flag to track whether TCQ is
+	 * enabled, so we'll be turning it off for the entire target here.
+	 * our tag algorithm will fail if we mix tagged and untagged commands,
+	 * so quiesce the device before doing this */
+	if (change_tag)
+		scsi_target_quiesce(SDp->sdev_target);
+
+	if (!tag_type) {
+		/* shift back to the default unqueued number of commands
+		 * (the user can still raise this) */
+		scsi_deactivate_tcq(SDp, SDp->host->cmd_per_lun);
+		hostdata->tag_negotiated &= ~(1 << SDp->id);
+	} else {
+		/* Here, we cleared the negotiation flag above, so this
+		 * will force the driver to renegotiate */
+		scsi_activate_tcq(SDp, SDp->queue_depth);
+		if (change_tag)
+			NCR_700_set_tag_neg_state(SDp, NCR_700_START_TAG_NEGOTIATION);
+	}
+	if (change_tag)
+		scsi_target_resume(SDp->sdev_target);
+
+	return tag_type;
 }
 
 static ssize_t
@@ -2124,14 +2154,6 @@
 	return snprintf(buf, 20, "%d\n", NCR_700_get_depth(SDp));
 }
 
-static struct device_attribute NCR_700_queue_depth_attr = {
-	.attr = {
-		.name = 	"queue_depth",
-		.mode =		S_IWUSR,
-	},
-	.store = NCR_700_store_queue_depth,
-};
-
 static struct device_attribute NCR_700_active_tags_attr = {
 	.attr = {
 		.name =		"active_tags",
@@ -2141,7 +2163,6 @@
 };
 
 STATIC struct device_attribute *NCR_700_dev_attrs[] = {
-	&NCR_700_queue_depth_attr,
 	&NCR_700_active_tags_attr,
 	NULL,
 };
diff -Nru a/drivers/scsi/53c700.h b/drivers/scsi/53c700.h
--- a/drivers/scsi/53c700.h	2005-03-01 23:38:52 -08:00
+++ b/drivers/scsi/53c700.h	2005-03-01 23:38:52 -08:00
@@ -102,7 +102,6 @@
  * 18 device supports tag queueing */
 #define NCR_700_DEV_NEGOTIATED_SYNC	(1<<16)
 #define NCR_700_DEV_BEGIN_SYNC_NEGOTIATION	(1<<17)
-#define NCR_700_DEV_BEGIN_TAG_QUEUEING	(1<<18)
 #define NCR_700_DEV_PRINT_SYNC_NEGOTIATION (1<<19)
 
 static inline void
@@ -138,6 +137,27 @@
 NCR_700_clear_flag(struct scsi_device *SDp, __u32 flag)
 {
 	spi_flags(SDp->sdev_target) &= ~flag;
+}
+
+enum NCR_700_tag_neg_state {
+	NCR_700_START_TAG_NEGOTIATION = 0,
+	NCR_700_DURING_TAG_NEGOTIATION = 1,
+	NCR_700_FINISHED_TAG_NEGOTIATION = 2,
+};
+
+static inline enum NCR_700_tag_neg_state
+NCR_700_get_tag_neg_state(struct scsi_device *SDp)
+{
+	return (enum NCR_700_tag_neg_state)((spi_flags(SDp->sdev_target)>>20) & 0x3);
+}
+
+static inline void
+NCR_700_set_tag_neg_state(struct scsi_device *SDp,
+			  enum NCR_700_tag_neg_state state)
+{
+	/* clear the slot */
+	spi_flags(SDp->sdev_target) &= ~(0x3 << 20);
+	spi_flags(SDp->sdev_target) |= ((__u32)state) << 20;
 }
 
 struct NCR_700_command_slot {
diff -Nru a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
--- a/drivers/scsi/Kconfig	2005-03-01 23:39:16 -08:00
+++ b/drivers/scsi/Kconfig	2005-03-01 23:39:16 -08:00
@@ -203,6 +203,14 @@
 	  each attached FiberChannel device to sysfs, say Y.
 	  Otherwise, say N.
 
+config SCSI_ISCSI_ATTRS
+	tristate "iSCSI Transport Attributes"
+	depends on SCSI
+	help
+	  If you wish to export transport-specific information about
+	  each attached iSCSI device to sysfs, say Y.
+	  Otherwise, say N.
+
 endmenu
 
 menu "SCSI low-level drivers"
@@ -217,14 +225,14 @@
 
 config SCSI_DECNCR
 	tristate "DEC NCR53C94 Scsi Driver"
-	depends on DECSTATION && TC && SCSI
+	depends on MACH_DECSTATION && SCSI && TC
 	help
 	  Say Y here to support the NCR53C94 SCSI controller chips on IOASIC
 	  based TURBOchannel DECstations and TURBOchannel PMAZ-A cards.
 
 config SCSI_DECSII
 	tristate "DEC SII Scsi Driver"
-	depends on DECSTATION && SCSI
+	depends on MACH_DECSTATION && SCSI && MIPS32
 
 config BLK_DEV_3W_XXXX_RAID
 	tristate "3ware 5/6/7/8xxx ATA-RAID support"
@@ -449,6 +457,14 @@
 
 	  If unsure, say N.
 
+config SCSI_SATA_QSTOR
+	tristate "Pacific Digital SATA QStor support"
+	depends on SCSI_SATA && PCI
+	help
+	  This option enables support for Pacific Digital Serial ATA QStor.
+
+	  If unsure, say N.
+
 config SCSI_SATA_SX4
 	tristate "Promise SATA SX4 support"
 	depends on SCSI_SATA && PCI && EXPERIMENTAL
@@ -783,7 +799,7 @@
 	  See <http://www.developer.ibm.com/welcome/netfinity/serveraid.html>
 	  for more information.  If this driver does not work correctly
 	  without modification please contact the author by email at
-	  ipslinux@adaptec.com.
+	  <ipslinux@adaptec.com>.
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called ips.
@@ -1486,7 +1502,7 @@
 	  host adapter with one dummy SCSI disk. Each dummy disk uses kernel
 	  RAM as storage (i.e. it is a ramdisk). To save space when multiple
 	  dummy disks are simulated, they share the same kernel RAM for 
-	  their storage. See http://www.torque.net/sg/sdebug.html for more
+	  their storage. See <http://www.torque.net/sg/sdebug.html> for more
 	  information. This driver is primarily of use to those testing the
 	  SCSI and block subsystems. If unsure, say N.
 
@@ -1777,7 +1793,7 @@
 
           This driver is also available as a module. This module will be
           called zfcp. If you want to compile it as a module, say M here
-          and read Documentation/modules.txt.
+          and read <file:Documentation/modules.txt>.
 
 endmenu
 
diff -Nru a/drivers/scsi/Makefile b/drivers/scsi/Makefile
--- a/drivers/scsi/Makefile	2005-03-01 23:39:09 -08:00
+++ b/drivers/scsi/Makefile	2005-03-01 23:39:09 -08:00
@@ -28,7 +28,7 @@
 # --------------------------
 obj-$(CONFIG_SCSI_SPI_ATTRS)	+= scsi_transport_spi.o
 obj-$(CONFIG_SCSI_FC_ATTRS) 	+= scsi_transport_fc.o
-
+obj-$(CONFIG_SCSI_ISCSI_ATTRS)	+= scsi_transport_iscsi.o
 
 obj-$(CONFIG_SCSI_AMIGA7XX)	+= amiga7xx.o	53c7xx.o
 obj-$(CONFIG_A3000_SCSI)	+= a3000.o	wd33c93.o
@@ -125,6 +125,7 @@
 obj-$(CONFIG_SCSI_SATA_SVW)	+= libata.o sata_svw.o
 obj-$(CONFIG_SCSI_ATA_PIIX)	+= libata.o ata_piix.o
 obj-$(CONFIG_SCSI_SATA_PROMISE)	+= libata.o sata_promise.o
+obj-$(CONFIG_SCSI_SATA_QSTOR)	+= libata.o sata_qstor.o
 obj-$(CONFIG_SCSI_SATA_SIL)	+= libata.o sata_sil.o
 obj-$(CONFIG_SCSI_SATA_VIA)	+= libata.o sata_via.o
 obj-$(CONFIG_SCSI_SATA_VITESSE)	+= libata.o sata_vsc.o
@@ -143,7 +144,7 @@
 
 scsi_mod-y			+= scsi.o hosts.o scsi_ioctl.o constants.o \
 				   scsicam.o scsi_error.o scsi_lib.o \
-				   scsi_scan.o scsi_syms.o scsi_sysfs.o \
+				   scsi_scan.o scsi_sysfs.o \
 				   scsi_devinfo.o
 scsi_mod-$(CONFIG_SYSCTL)	+= scsi_sysctl.o
 scsi_mod-$(CONFIG_SCSI_PROC_FS)	+= scsi_proc.o
diff -Nru a/drivers/scsi/NCR53C9x.c b/drivers/scsi/NCR53C9x.c
--- a/drivers/scsi/NCR53C9x.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/scsi/NCR53C9x.c	2005-03-01 23:38:53 -08:00
@@ -100,7 +100,7 @@
 irqreturn_t esp_intr(int irq, void *dev_id, struct pt_regs *pregs);
 
 /* Debugging routines */
-struct esp_cmdstrings {
+static struct esp_cmdstrings {
 	unchar cmdchar;
 	char *text;
 } esp_cmd_strings[] = {
@@ -290,7 +290,7 @@
 #endif
 
 #ifdef DEBUG_ESP_CMDS
-inline void esp_cmd(struct NCR_ESP *esp, struct ESP_regs *eregs,
+static inline void esp_cmd(struct NCR_ESP *esp, struct ESP_regs *eregs,
 			   unchar cmd)
 {
 	esp->espcmdlog[esp->espcmdent] = cmd;
@@ -1269,17 +1269,6 @@
 		esp_exec_cmd(esp);
 
 	return 0;
-}
-
-/* Only queuing supported in this ESP driver. */
-int esp_command(Scsi_Cmnd *SCpnt)
-{
-#ifdef DEBUG_ESP
-	struct NCR_ESP *esp = (struct NCR_ESP *) SCpnt->device->host->hostdata;
-#endif
-
-	ESPLOG(("esp%d: esp_command() called...\n", esp->esp_id));
-	return -1;
 }
 
 /* Dump driver state. */
diff -Nru a/drivers/scsi/NCR53C9x.h b/drivers/scsi/NCR53C9x.h
--- a/drivers/scsi/NCR53C9x.h	2005-03-01 23:38:54 -08:00
+++ b/drivers/scsi/NCR53C9x.h	2005-03-01 23:38:54 -08:00
@@ -652,7 +652,7 @@
 
 
 /* External functions */
-extern void esp_cmd(struct NCR_ESP *esp, struct ESP_regs *eregs, unchar cmd);
+extern void esp_bootup_reset(struct NCR_ESP *esp, struct ESP_regs *eregs);
 extern struct NCR_ESP *esp_allocate(Scsi_Host_Template *, void *);
 extern void esp_deallocate(struct NCR_ESP *);
 extern void esp_release(void);
@@ -660,7 +660,6 @@
 extern irqreturn_t esp_intr(int, void *, struct pt_regs *);
 extern const char *esp_info(struct Scsi_Host *);
 extern int esp_queue(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-extern int esp_command(Scsi_Cmnd *);
 extern int esp_abort(Scsi_Cmnd *);
 extern int esp_reset(Scsi_Cmnd *);
 extern int esp_proc_info(struct Scsi_Host *shost, char *buffer, char **start, off_t offset, int length,
diff -Nru a/drivers/scsi/NCR_D700.c b/drivers/scsi/NCR_D700.c
--- a/drivers/scsi/NCR_D700.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/scsi/NCR_D700.c	2005-03-01 23:38:52 -08:00
@@ -111,7 +111,7 @@
 MODULE_AUTHOR("James Bottomley");
 MODULE_DESCRIPTION("NCR Dual700 SCSI Driver");
 MODULE_LICENSE("GPL");
-MODULE_PARM(NCR_D700, "s");
+module_param(NCR_D700, charp, 0);
 
 static __u8 __initdata id_array[2*(MCA_MAX_SLOT_NR + 1)] =
 	{ [0 ... 2*(MCA_MAX_SLOT_NR + 1)-1] = 7 };
diff -Nru a/drivers/scsi/NCR_Q720.c b/drivers/scsi/NCR_Q720.c
--- a/drivers/scsi/NCR_Q720.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/scsi/NCR_Q720.c	2005-03-01 23:38:52 -08:00
@@ -48,7 +48,7 @@
 	struct Scsi_Host	*hosts[4];
 };
 
-struct scsi_host_template NCR_Q720_tpnt = {
+static struct scsi_host_template NCR_Q720_tpnt = {
 	.module			= THIS_MODULE,
 	.proc_name		= "NCR_Q720",
 };
@@ -345,7 +345,7 @@
 
 static short NCR_Q720_id_table[] = { NCR_Q720_MCA_ID, 0 };
 
-struct mca_driver NCR_Q720_driver = {
+static struct mca_driver NCR_Q720_driver = {
 	.id_table = NCR_Q720_id_table,
 	.driver = {
 		.name		= "NCR_Q720",
diff -Nru a/drivers/scsi/aacraid/README b/drivers/scsi/aacraid/README
--- a/drivers/scsi/aacraid/README	2005-03-01 23:38:52 -08:00
+++ b/drivers/scsi/aacraid/README	2005-03-01 23:38:52 -08:00
@@ -42,7 +42,7 @@
 Christoph Hellwig <hch@infradead.org>	(updates for new-style PCI probing and SCSI host registration,
 					 small cleanups/fixes)
 Matt Domsch <matt_domsch@dell.com>	(revision ioctl, adapter messages)
-Deanna Bonds <deanna_bonds@adaptec.com> (non-DASD support, PAE fibs and 64 bit, added new adaptec controllers
+Deanna Bonds                            (non-DASD support, PAE fibs and 64 bit, added new adaptec controllers
 					 added new ioctls, changed scsi interface to use new error handler,
 					 increased the number of fibs and outstanding commands to a container)
 
diff -Nru a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
--- a/drivers/scsi/aacraid/aachba.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/scsi/aacraid/aachba.c	2005-03-01 23:38:56 -08:00
@@ -146,18 +146,18 @@
  *	Non dasd selection is handled entirely in aachba now
  */	
  
-MODULE_PARM(nondasd, "i");
-MODULE_PARM_DESC(nondasd, "Control scanning of hba for nondasd devices. 0=off, 1=on");
-MODULE_PARM(dacmode, "i");
-MODULE_PARM_DESC(dacmode, "Control whether dma addressing is using 64 bit DAC. 0=off, 1=on");
-MODULE_PARM(commit, "i");
-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");
-
 static int nondasd = -1;
 static int dacmode = -1;
 
 static int commit = -1;
 
+module_param(nondasd, int, 0);
+MODULE_PARM_DESC(nondasd, "Control scanning of hba for nondasd devices. 0=off, 1=on");
+module_param(dacmode, int, 0);
+MODULE_PARM_DESC(dacmode, "Control whether dma addressing is using 64 bit DAC. 0=off, 1=on");
+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");
+
 /**
  *	aac_get_config_status	-	check the adapter configuration
  *	@common: adapter to query
@@ -1029,6 +1029,114 @@
 	return 0;
 }
 
+static void synchronize_callback(void *context, struct fib *fibptr)
+{
+	struct aac_synchronize_reply *synchronizereply;
+	struct scsi_cmnd *cmd;
+
+	cmd = context;
+
+	dprintk((KERN_DEBUG "synchronize_callback[cpu %d]: t = %ld.\n", 
+				smp_processor_id(), jiffies));
+	BUG_ON(fibptr == NULL);
+
+
+	synchronizereply = fib_data(fibptr);
+	if (le32_to_cpu(synchronizereply->status) == CT_OK)
+		cmd->result = DID_OK << 16 | 
+			COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
+	else {
+		struct scsi_device *sdev = cmd->device;
+		struct aac_dev *dev = (struct aac_dev *)sdev->host->hostdata;
+		u32 cid = ID_LUN_TO_CONTAINER(sdev->id, sdev->lun);
+		printk(KERN_WARNING 
+		     "synchronize_callback: synchronize failed, status = %d\n",
+		     synchronizereply->status);
+		cmd->result = DID_OK << 16 | 
+			COMMAND_COMPLETE << 8 | SAM_STAT_CHECK_CONDITION;
+		set_sense((u8 *)&dev->fsa_dev[cid].sense_data,
+				    HARDWARE_ERROR,
+				    SENCODE_INTERNAL_TARGET_FAILURE,
+				    ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0,
+				    0, 0);
+		memcpy(cmd->sense_buffer, &dev->fsa_dev[cid].sense_data,
+		  min(sizeof(dev->fsa_dev[cid].sense_data), 
+			  sizeof(cmd->sense_buffer)));
+	}
+
+	fib_complete(fibptr);
+	fib_free(fibptr);
+	aac_io_done(cmd);
+}
+
+static int aac_synchronize(struct scsi_cmnd *scsicmd, int cid)
+{
+	int status;
+	struct fib *cmd_fibcontext;
+	struct aac_synchronize *synchronizecmd;
+	struct scsi_cmnd *cmd;
+	struct scsi_device *sdev = scsicmd->device;
+	int active = 0;
+	unsigned long flags;
+
+	/*
+	 * Wait for all commands to complete to this specific
+	 * target (block).
+	 */
+	spin_lock_irqsave(&sdev->list_lock, flags);
+	list_for_each_entry(cmd, &sdev->cmd_list, list)
+		if (cmd != scsicmd && cmd->serial_number != 0) {
+			++active;
+			break;
+		}
+
+	spin_unlock_irqrestore(&sdev->list_lock, flags);
+
+	/*
+	 *	Yield the processor (requeue for later)
+	 */
+	if (active)
+		return SCSI_MLQUEUE_DEVICE_BUSY;
+
+	/*
+	 *	Alocate and initialize a Fib
+	 */
+	if (!(cmd_fibcontext = 
+	    fib_alloc((struct aac_dev *)scsicmd->device->host->hostdata))) 
+		return SCSI_MLQUEUE_HOST_BUSY;
+
+	fib_init(cmd_fibcontext);
+
+	synchronizecmd = fib_data(cmd_fibcontext);
+	synchronizecmd->command = cpu_to_le32(VM_ContainerConfig);
+	synchronizecmd->type = cpu_to_le32(CT_FLUSH_CACHE);
+	synchronizecmd->cid = cpu_to_le32(cid);
+	synchronizecmd->count = 
+	     cpu_to_le32(sizeof(((struct aac_synchronize_reply *)NULL)->data));
+
+	/*
+	 *	Now send the Fib to the adapter
+	 */
+	status = fib_send(ContainerCommand,
+		  cmd_fibcontext,
+		  sizeof(struct aac_synchronize),
+		  FsaNormal,
+		  0, 1,
+		  (fib_callback)synchronize_callback,
+		  (void *)scsicmd);
+
+	/*
+	 *	Check that the command queued to the controller
+	 */
+	if (status == -EINPROGRESS)
+		return 0;
+
+	printk(KERN_WARNING 
+		"aac_synchronize: fib_send failed with status: %d.\n", status);
+	fib_complete(cmd_fibcontext);
+	fib_free(cmd_fibcontext);
+	return SCSI_MLQUEUE_HOST_BUSY;
+}
 
 /**
  *	aac_scsi_cmd()		-	Process SCSI command
@@ -1274,6 +1382,11 @@
 			ret = aac_write(scsicmd, cid);
 			spin_lock_irq(host->host_lock);
 			return ret;
+
+		case SYNCHRONIZE_CACHE:
+			/* Issue FIB to tell Firmware to flush it's cache */
+			return aac_synchronize(scsicmd, cid);
+			
 		default:
 			/*
 			 *	Unhandled commands
diff -Nru a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
--- a/drivers/scsi/aacraid/aacraid.h	2005-03-01 23:38:53 -08:00
+++ b/drivers/scsi/aacraid/aacraid.h	2005-03-01 23:38:53 -08:00
@@ -444,7 +444,24 @@
  * dma mask such that fib memory will be allocated where the
  * adapter firmware can get to it.
  */
-#define AAC_QUIRK_31BIT	1
+#define AAC_QUIRK_31BIT	0x0001
+
+/*
+ * Some adapter firmware, when the raid card's cache is turned off, can not
+ * split up scatter gathers in order to deal with the limits of the
+ * underlying CHIM. This limit is 34 scatter gather elements.
+ */
+#define AAC_QUIRK_34SG	0x0002
+
+/*
+ * This adapter is a slave (no Firmware)
+ */
+#define AAC_QUIRK_SLAVE 0x0004
+
+/*
+ * This adapter is a master.
+ */
+#define AAC_QUIRK_MASTER 0x0008
 
 /*
  *	The adapter interface specs all queues to be located in the same
@@ -1050,6 +1067,30 @@
 	u32		status;
 	u32 		count;
 	u32		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) */
+};
+
+struct aac_synchronize_reply {
+	u32		dummy0;
+	u32		dummy1;
+	u32		status;	/* CT_OK */
+	u32		parm1;
+	u32		parm2;
+	u32		parm3;
+	u32		parm4;
+	u32		parm5;
+	u8		data[16];
 };
 
 struct aac_srb
diff -Nru a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
--- a/drivers/scsi/aacraid/commsup.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/scsi/aacraid/commsup.c	2005-03-01 23:39:08 -08:00
@@ -768,28 +768,6 @@
 	memset(cp, 0,  256);
 }
 
-
-/**
- *	aac_handle_aif		-	Handle a message from the firmware
- *	@dev: Which adapter this fib is from
- *	@fibptr: Pointer to fibptr from adapter
- *
- *	This routine handles a driver notify fib from the adapter and
- *	dispatches it to the appropriate routine for handling.
- */
-
-static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
-{
-	struct hw_fib * hw_fib = fibptr->hw_fib;
-	/*
-	 * Set the status of this FIB to be Invalid parameter.
-	 *
-	 *	*(u32 *)fib->data = ST_INVAL;
-	 */
-	*(u32 *)hw_fib->data = cpu_to_le32(ST_OK);
-	fib_adapter_complete(fibptr, sizeof(u32));
-}
-
 /**
  *	aac_command_thread	-	command processing thread
  *	@dev: Adapter to monitor
@@ -859,7 +837,6 @@
 			aifcmd = (struct aac_aifcmd *) hw_fib->data;
 			if (aifcmd->command == cpu_to_le32(AifCmdDriverNotify)) {
 				/* Handle Driver Notify Events */
-				aac_handle_aif(dev, fib);
 				*(u32 *)hw_fib->data = cpu_to_le32(ST_OK);
 				fib_adapter_complete(fib, sizeof(u32));
 			} else {
@@ -869,10 +846,6 @@
 				   
 				u32 time_now, time_last;
 				unsigned long flagv;
-				
-				/* Sniff events */
-				if (aifcmd->command == cpu_to_le32(AifCmdEventNotify))
-					aac_handle_aif(dev, fib);
 				
 				time_now = jiffies/HZ;
 
diff -Nru a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
--- a/drivers/scsi/aacraid/linit.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/scsi/aacraid/linit.c	2005-03-01 23:38:55 -08:00
@@ -98,31 +98,35 @@
 	{ 0x9005, 0x0285, 0x9005, 0x028b, 0, 0, 19 }, /* ASR-2025ZCR SCSI SO-DIMM PCI-X ZCR (Terminator) */
 	{ 0x9005, 0x0286, 0x9005, 0x028c, 0, 0, 20 }, /* ASR-2230S + ASR-2230SLP PCI-X (Lancer) */
 	{ 0x9005, 0x0286, 0x9005, 0x028d, 0, 0, 21 }, /* ASR-2130S (Lancer) */
-	{ 0x9005, 0x0286, 0x9005, 0x0800, 0, 0, 22 }, /* Jupiter Platform */
-	{ 0x9005, 0x0285, 0x9005, 0x028e, 0, 0, 23 }, /* ASR-2020SA SATA PCI-X ZCR (Skyhawk) */
-	{ 0x9005, 0x0285, 0x9005, 0x028f, 0, 0, 24 }, /* ASR-2025SA SATA SO-DIMM PCI-X ZCR (Terminator) */
-	{ 0x9005, 0x0285, 0x9005, 0x0290, 0, 0, 25 }, /* AAR-2410SA PCI SATA 4ch (Jaguar II) */
-	{ 0x9005, 0x0285, 0x1028, 0x0291, 0, 0, 26 }, /* CERC SATA RAID 2 PCI SATA 6ch (DellCorsair) */
-	{ 0x9005, 0x0285, 0x9005, 0x0292, 0, 0, 27 }, /* AAR-2810SA PCI SATA 8ch (Corsair-8) */
-	{ 0x9005, 0x0285, 0x9005, 0x0293, 0, 0, 28 }, /* AAR-21610SA PCI SATA 16ch (Corsair-16) */
-	{ 0x9005, 0x0285, 0x9005, 0x0294, 0, 0, 29 }, /* ESD SO-DIMM PCI-X SATA ZCR (Prowler) */
-	{ 0x9005, 0x0285, 0x0E11, 0x0295, 0, 0, 30 }, /* AAR-2610SA PCI SATA 6ch */
-	{ 0x9005, 0x0285, 0x9005, 0x0296, 0, 0, 31 }, /* ASR-2240S */
-	{ 0x9005, 0x0285, 0x9005, 0x0296, 0, 0, 32 }, /* ASR-4005SAS */
-	{ 0x9005, 0x0285, 0x9005, 0x0296, 0, 0, 33 }, /* ASR-4000SAS */
-	{ 0x9005, 0x0285, 0x9005, 0x0296, 0, 0, 34 }, /* ASR-4800SAS */
-	{ 0x9005, 0x0285, 0x9005, 0x0296, 0, 0, 35 }, /* ASR-4805SAS */
-
-	{ 0x9005, 0x0285, 0x1028, 0x0287, 0, 0, 36 }, /* Perc 320/DC*/
-	{ 0x1011, 0x0046, 0x9005, 0x0365, 0, 0, 37 }, /* Adaptec 5400S (Mustang)*/
-	{ 0x1011, 0x0046, 0x9005, 0x0364, 0, 0, 38 }, /* Adaptec 5400S (Mustang)*/
-	{ 0x1011, 0x0046, 0x9005, 0x1364, 0, 0, 39 }, /* Dell PERC2/QC */
-	{ 0x1011, 0x0046, 0x103c, 0x10c2, 0, 0, 40 }, /* HP NetRAID-4M */
-
-	{ 0x9005, 0x0285, 0x1028, PCI_ANY_ID, 0, 0, 41 }, /* Dell Catchall */
-	{ 0x9005, 0x0285, 0x17aa, PCI_ANY_ID, 0, 0, 42 }, /* Legend Catchall */
-	{ 0x9005, 0x0285, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 43 }, /* Adaptec Catch All */
-	{ 0x9005, 0x0286, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 44 }, /* Adaptec Rocket Catch All */
+	{ 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 */
 	{ 0,}
 };
 MODULE_DEVICE_TABLE(pci, aac_pci_tbl);
@@ -133,22 +137,22 @@
  * for the card.  At that time we can remove the channels from here
  */
 static struct aac_driver_ident aac_drivers[] = {
-	{ aac_rx_init, "percraid", "DELL    ", "PERCRAID        ", 2, AAC_QUIRK_31BIT }, /* PERC 2/Si (Iguana/PERC2Si) */
-	{ aac_rx_init, "percraid", "DELL    ", "PERCRAID        ", 2, AAC_QUIRK_31BIT }, /* PERC 3/Di (Opal/PERC3Di) */
-	{ aac_rx_init, "percraid", "DELL    ", "PERCRAID        ", 2, AAC_QUIRK_31BIT }, /* PERC 3/Si (SlimFast/PERC3Si */
-	{ aac_rx_init, "percraid", "DELL    ", "PERCRAID        ", 2, AAC_QUIRK_31BIT }, /* PERC 3/Di (Iguana FlipChip/PERC3DiF */
-	{ aac_rx_init, "percraid", "DELL    ", "PERCRAID        ", 2, AAC_QUIRK_31BIT }, /* PERC 3/Di (Viper/PERC3DiV) */
-	{ aac_rx_init, "percraid", "DELL    ", "PERCRAID        ", 2, AAC_QUIRK_31BIT }, /* PERC 3/Di (Lexus/PERC3DiL) */
-	{ aac_rx_init, "percraid", "DELL    ", "PERCRAID        ", 1, AAC_QUIRK_31BIT }, /* PERC 3/Di (Jaguar/PERC3DiJ) */
-	{ aac_rx_init, "percraid", "DELL    ", "PERCRAID        ", 2, AAC_QUIRK_31BIT }, /* PERC 3/Di (Dagger/PERC3DiD) */
-	{ aac_rx_init, "percraid", "DELL    ", "PERCRAID        ", 2, AAC_QUIRK_31BIT }, /* PERC 3/Di (Boxster/PERC3DiB) */
-	{ aac_rx_init, "aacraid",  "ADAPTEC ", "catapult        ", 2, AAC_QUIRK_31BIT }, /* catapult */
-	{ aac_rx_init, "aacraid",  "ADAPTEC ", "tomcat          ", 2, AAC_QUIRK_31BIT }, /* tomcat */
-	{ aac_rx_init, "aacraid",  "ADAPTEC ", "Adaptec 2120S   ", 1, AAC_QUIRK_31BIT }, /* Adaptec 2120S (Crusader) */
-	{ aac_rx_init, "aacraid",  "ADAPTEC ", "Adaptec 2200S   ", 2, AAC_QUIRK_31BIT }, /* Adaptec 2200S (Vulcan) */
-	{ aac_rx_init, "aacraid",  "ADAPTEC ", "Adaptec 2200S   ", 2, AAC_QUIRK_31BIT }, /* Adaptec 2200S (Vulcan-2m) */
-	{ aac_rx_init, "aacraid",  "Legend  ", "Legend S220     ", 1, AAC_QUIRK_31BIT }, /* Legend S220 (Legend Crusader) */
-	{ aac_rx_init, "aacraid",  "Legend  ", "Legend S230     ", 2, AAC_QUIRK_31BIT }, /* Legend S230 (Legend Vulcan) */
+	{ aac_rx_init, "percraid", "DELL    ", "PERCRAID        ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* PERC 2/Si (Iguana/PERC2Si) */
+	{ aac_rx_init, "percraid", "DELL    ", "PERCRAID        ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* PERC 3/Di (Opal/PERC3Di) */
+	{ aac_rx_init, "percraid", "DELL    ", "PERCRAID        ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* PERC 3/Si (SlimFast/PERC3Si */
+	{ aac_rx_init, "percraid", "DELL    ", "PERCRAID        ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* PERC 3/Di (Iguana FlipChip/PERC3DiF */
+	{ aac_rx_init, "percraid", "DELL    ", "PERCRAID        ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* PERC 3/Di (Viper/PERC3DiV) */
+	{ aac_rx_init, "percraid", "DELL    ", "PERCRAID        ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* PERC 3/Di (Lexus/PERC3DiL) */
+	{ aac_rx_init, "percraid", "DELL    ", "PERCRAID        ", 1, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* PERC 3/Di (Jaguar/PERC3DiJ) */
+	{ aac_rx_init, "percraid", "DELL    ", "PERCRAID        ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* PERC 3/Di (Dagger/PERC3DiD) */
+	{ aac_rx_init, "percraid", "DELL    ", "PERCRAID        ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* PERC 3/Di (Boxster/PERC3DiB) */
+	{ aac_rx_init, "aacraid",  "ADAPTEC ", "catapult        ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* catapult */
+	{ aac_rx_init, "aacraid",  "ADAPTEC ", "tomcat          ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* tomcat */
+	{ aac_rx_init, "aacraid",  "ADAPTEC ", "Adaptec 2120S   ", 1, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* Adaptec 2120S (Crusader) */
+	{ aac_rx_init, "aacraid",  "ADAPTEC ", "Adaptec 2200S   ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* Adaptec 2200S (Vulcan) */
+	{ aac_rx_init, "aacraid",  "ADAPTEC ", "Adaptec 2200S   ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* Adaptec 2200S (Vulcan-2m) */
+	{ aac_rx_init, "aacraid",  "Legend  ", "Legend S220     ", 1, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* Legend S220 (Legend Crusader) */
+	{ aac_rx_init, "aacraid",  "Legend  ", "Legend S230     ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* Legend S230 (Legend Vulcan) */
 
 	{ aac_rx_init, "aacraid",  "ADAPTEC ", "Adaptec 3230S   ", 2 }, /* Adaptec 3230S (Harrier) */
 	{ aac_rx_init, "aacraid",  "ADAPTEC ", "Adaptec 3240S   ", 2 }, /* Adaptec 3240S (Tornado) */
@@ -156,30 +160,34 @@
 	{ aac_rx_init, "aacraid",  "ADAPTEC ", "ASR-2025ZCR     ", 2 }, /* ASR-2025ZCR SCSI SO-DIMM PCI-X ZCR (Terminator) */
 	{ aac_rkt_init, "aacraid",  "ADAPTEC ", "ASR-2230S PCI-X ", 2 }, /* ASR-2230S + ASR-2230SLP PCI-X (Lancer) */
 	{ aac_rkt_init, "aacraid",  "ADAPTEC ", "ASR-2130S PCI-X ", 1 }, /* ASR-2130S (Lancer) */
-	{ aac_rkt_init, "aacraid",  "ADAPTEC ", "Callisto        ", 2 }, /* Jupiter Platform */
+	{ 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",  "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) */
 	{ aac_rx_init, "aacraid",  "ADAPTEC ", "AAR-2410SA SATA ", 1 }, /* AAR-2410SA PCI SATA 4ch (Jaguar II) */
 	{ aac_rx_init, "aacraid",  "DELL    ", "CERC SR2        ", 1 }, /* CERC SATA RAID 2 PCI SATA 6ch (DellCorsair) */
 	{ aac_rx_init, "aacraid",  "ADAPTEC ", "AAR-2810SA SATA ", 1 }, /* AAR-2810SA PCI SATA 8ch (Corsair-8) */
 	{ aac_rx_init, "aacraid",  "ADAPTEC ", "AAR-21610SA SATA", 1 }, /* AAR-21610SA PCI SATA 16ch (Corsair-16) */
-	{ aac_rx_init, "aacraid",  "ADAPTEC ", "SO-DIMM SATA ZCR", 1 }, /* ESD SO-DIMM PCI-X SATA ZCR (Prowler) */
+	{ aac_rx_init, "aacraid",  "ADAPTEC ", "ASR-2026ZCR     ", 1 }, /* ESD SO-DIMM PCI-X SATA ZCR (Prowler) */
 	{ aac_rx_init, "aacraid",  "ADAPTEC ", "AAR-2610SA      ", 1 }, /* SATA 6Ch (Bearcat) */
-	{ aac_rx_init, "aacraid",  "ADAPTEC ", "ASR-2240S       ", 1 }, /* ASR-2240S */
+	{ 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",  "ADAPTEC ", "ASR-4000SAS     ", 1 }, /* ASR-4000SAS */
-	{ aac_rx_init, "aacraid",  "ADAPTEC ", "ASR-4800SAS     ", 1 }, /* ASR-4800SAS */
-	{ aac_rx_init, "aacraid",  "ADAPTEC ", "ASR-4805SAS     ", 1 }, /* ASR-4805SAS */
-
-	{ aac_rx_init, "percraid", "DELL    ", "PERC 320/DC     ", 2, AAC_QUIRK_31BIT }, /* Perc 320/DC*/
-	{ aac_sa_init, "aacraid",  "ADAPTEC ", "Adaptec 5400S   ", 4 }, /* Adaptec 5400S (Mustang)*/
-	{ aac_sa_init, "aacraid",  "ADAPTEC ", "AAC-364         ", 4 }, /* Adaptec 5400S (Mustang)*/
-	{ aac_sa_init, "percraid", "DELL    ", "PERCRAID        ", 4, AAC_QUIRK_31BIT }, /* Dell PERC2/QC */
-	{ aac_sa_init, "hpnraid",  "HP      ", "NetRAID         ", 4 }, /* HP NetRAID-4M */
-
-	{ aac_rx_init, "aacraid",  "DELL    ", "RAID            ", 2, AAC_QUIRK_31BIT }, /* Dell Catchall */
-	{ aac_rx_init, "aacraid",  "Legend  ", "RAID            ", 2, AAC_QUIRK_31BIT }, /* Legend Catchall */
-	{ aac_rx_init, "aacraid",  "ADAPTEC ", "RAID            ", 2, AAC_QUIRK_31BIT }, /* Adaptec Catch All */
+	{ aac_rx_init, "aacraid",  "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, "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)*/
+	{ aac_sa_init, "aacraid",  "ADAPTEC ", "AAC-364         ", 4, AAC_QUIRK_34SG }, /* Adaptec 5400S (Mustang)*/
+	{ aac_sa_init, "percraid", "DELL    ", "PERCRAID        ", 4, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* Dell PERC2/QC */
+	{ aac_sa_init, "hpnraid",  "HP      ", "NetRAID         ", 4, AAC_QUIRK_34SG }, /* HP NetRAID-4M */
+
+	{ aac_rx_init, "aacraid",  "DELL    ", "RAID            ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* Dell Catchall */
+	{ aac_rx_init, "aacraid",  "Legend  ", "RAID            ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* Legend Catchall */
+	{ aac_rx_init, "aacraid",  "ADAPTEC ", "RAID            ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* Adaptec Catch All */
 	{ aac_rkt_init, "aacraid", "ADAPTEC ", "RAID            ", 2 } /* Adaptec Rocket Catch All */
 };
 
@@ -350,7 +358,7 @@
 }
 
 /**
- *	aac_queuedepth		-	compute queue depths
+ *	aac_slave_configure		-	compute queue depths
  *	@sdev:	SCSI device we are considering
  *
  *	Selects queue depths for each target device based on the host adapter's
diff -Nru a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c
--- a/drivers/scsi/advansys.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/scsi/advansys.c	2005-03-01 23:38:54 -08:00
@@ -4322,12 +4322,12 @@
     int                 ioport = 0;
     int                 share_irq = FALSE;
     int                 iolen = 0;
+    struct device	*dev = NULL;
 #ifdef CONFIG_PCI
     int                 pci_init_search = 0;
     struct pci_dev      *pci_devicep[ASC_NUM_BOARD_SUPPORTED];
     int                 pci_card_cnt_max = 0;
     int                 pci_card_cnt = 0;
-    struct device	*dev = NULL;
     struct pci_dev      *pci_devp = NULL;
     int                 pci_device_id_cnt = 0;
     unsigned int        pci_device_id[ASC_PCI_DEVICE_ID_CNT] = {
@@ -8944,7 +8944,7 @@
 #ifdef CONFIG_PCI
     pci_write_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, byte_data);
 #else /* CONFIG_PCI */
-    return 0;
+    return;
 #endif /* CONFIG_PCI */
 }
 
@@ -12014,13 +12014,13 @@
     PortAddr            iop_base;
     ushort              cfg_msw;
     ushort              warn_code;
-    ushort              pci_device_id;
+    ushort              pci_device_id = 0;
 
     iop_base = asc_dvc->iop_base;
+#ifdef CONFIG_PCI
     if (asc_dvc->cfg->dev)
         pci_device_id = to_pci_dev(asc_dvc->cfg->dev)->device;
-    else
-	pci_device_id = 0;
+#endif
     warn_code = 0;
     cfg_msw = AscGetChipCfgMsw(iop_base);
     if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
diff -Nru a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c
--- a/drivers/scsi/aha152x.c	2005-03-01 23:38:51 -08:00
+++ b/drivers/scsi/aha152x.c	2005-03-01 23:38:51 -08:00
@@ -353,58 +353,58 @@
 
 #if !defined(PCMCIA)
 #if defined(MODULE)
-MODULE_PARM(io, "1-2i");
-MODULE_PARM_DESC(io,"base io address of controller");
 static int io[] = {0, 0};
+module_param_array(io, int, NULL, 0);
+MODULE_PARM_DESC(io,"base io address of controller");
 
-MODULE_PARM(irq, "1-2i");
-MODULE_PARM_DESC(irq,"interrupt for controller");
 static int irq[] = {0, 0};
+module_param_array(irq, int, NULL, 0);
+MODULE_PARM_DESC(irq,"interrupt for controller");
 
-MODULE_PARM(scsiid, "1-2i");
-MODULE_PARM_DESC(scsiid,"scsi id of controller");
 static int scsiid[] = {7, 7};
+module_param_array(scsiid, int, NULL, 0);
+MODULE_PARM_DESC(scsiid,"scsi id of controller");
 
-MODULE_PARM(reconnect, "1-2i");
-MODULE_PARM_DESC(reconnect,"allow targets to disconnect");
 static int reconnect[] = {1, 1};
+module_param_array(reconnect, int, NULL, 0);
+MODULE_PARM_DESC(reconnect,"allow targets to disconnect");
 
-MODULE_PARM(parity, "1-2i");
-MODULE_PARM_DESC(parity,"use scsi parity");
 static int parity[] = {1, 1};
+module_param_array(parity, int, NULL, 0);
+MODULE_PARM_DESC(parity,"use scsi parity");
 
-MODULE_PARM(sync, "1-2i");
-MODULE_PARM_DESC(sync,"use synchronous transfers");
 static int sync[] = {1, 1};
+module_param_array(sync, int, NULL, 0);
+MODULE_PARM_DESC(sync,"use synchronous transfers");
 
-MODULE_PARM(delay, "1-2i");
-MODULE_PARM_DESC(delay,"scsi reset delay");
 static int delay[] = {DELAY_DEFAULT, DELAY_DEFAULT};
+module_param_array(delay, int, NULL, 0);
+MODULE_PARM_DESC(delay,"scsi reset delay");
 
-MODULE_PARM(exttrans, "1-2i");
-MODULE_PARM_DESC(exttrans,"use extended translation");
 static int exttrans[] = {0, 0};
+module_param_array(exttrans, int, NULL, 0);
+MODULE_PARM_DESC(exttrans,"use extended translation");
 
 #if !defined(AHA152X_DEBUG)
-MODULE_PARM(aha152x, "1-8i");
-MODULE_PARM_DESC(aha152x, "parameters for first controller");
 static int aha152x[] = {0, 11, 7, 1, 1, 0, DELAY_DEFAULT, 0};
+module_param_array(aha152x, int, NULL, 0);
+MODULE_PARM_DESC(aha152x, "parameters for first controller");
 
-MODULE_PARM(aha152x1, "1-8i");
-MODULE_PARM_DESC(aha152x1, "parameters for second controller");
 static int aha152x1[] = {0, 11, 7, 1, 1, 0, DELAY_DEFAULT, 0};
+module_param_array(aha152x1, int, NULL, 0);
+MODULE_PARM_DESC(aha152x1, "parameters for second controller");
 #else
-MODULE_PARM(debug, "1-2i");
-MODULE_PARM_DESC(debug, "flags for driver debugging");
 static int debug[] = {DEBUG_DEFAULT, DEBUG_DEFAULT};
+module_param_array(debug, int, NULL, 0);
+MODULE_PARM_DESC(debug, "flags for driver debugging");
 
-MODULE_PARM(aha152x, "1-9i");
-MODULE_PARM_DESC(aha152x, "parameters for first controller");
 static int aha152x[]   = {0, 11, 7, 1, 1, 1, DELAY_DEFAULT, 0, DEBUG_DEFAULT};
+module_param_array(aha152x, int, NULL, 0);
+MODULE_PARM_DESC(aha152x, "parameters for first controller");
 
-MODULE_PARM(aha152x1, "1-9i");
-MODULE_PARM_DESC(aha152x1, "parameters for second controller");
 static int aha152x1[]  = {0, 11, 7, 1, 1, 1, DELAY_DEFAULT, 0, DEBUG_DEFAULT};
+module_param_array(aha152x1, int, NULL, 0);
+MODULE_PARM_DESC(aha152x1, "parameters for second controller");
 #endif /* !defined(AHA152X_DEBUG) */
 #endif /* MODULE */
 
diff -Nru a/drivers/scsi/aha1542.c b/drivers/scsi/aha1542.c
--- a/drivers/scsi/aha1542.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/scsi/aha1542.c	2005-03-01 23:38:57 -08:00
@@ -131,8 +131,8 @@
 #if defined(MODULE)
 static int isapnp = 0;
 static int aha1542[] = {0x330, 11, 4, -1};
-MODULE_PARM(aha1542, "1-4i");
-MODULE_PARM(isapnp, "i");
+module_param_array(aha1542, int, NULL, 0);
+module_param(isapnp, bool, 0);
 
 static struct isapnp_device_id id_table[] __initdata = {
 	{
@@ -167,7 +167,7 @@
 
 static struct Scsi_Host *aha_host[7];	/* One for each IRQ level (9-15) */
 
-static spinlock_t aha1542_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(aha1542_lock);
 
 
 
diff -Nru a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c
--- a/drivers/scsi/ahci.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/scsi/ahci.c	2005-03-01 23:38:53 -08:00
@@ -179,6 +179,7 @@
 static void ahci_host_stop(struct ata_host_set *host_set);
 static void ahci_qc_prep(struct ata_queued_cmd *qc);
 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 Scsi_Host_Template ahci_sht = {
@@ -204,6 +205,8 @@
 	.port_disable		= ata_port_disable,
 
 	.check_status		= ahci_check_status,
+	.check_altstatus	= ahci_check_status,
+	.check_err		= ahci_check_err,
 	.dev_select		= ata_noop_dev_select,
 
 	.phy_reset		= ahci_phy_reset,
@@ -239,9 +242,19 @@
 
 static struct pci_device_id ahci_pci_tbl[] = {
 	{ PCI_VENDOR_ID_INTEL, 0x2652, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-	  board_ahci },
+	  board_ahci }, /* ICH6 */
 	{ PCI_VENDOR_ID_INTEL, 0x2653, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-	  board_ahci },
+	  board_ahci }, /* ICH6M */
+	{ PCI_VENDOR_ID_INTEL, 0x27c1, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+	  board_ahci }, /* ICH7 */
+	{ PCI_VENDOR_ID_INTEL, 0x27c5, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+	  board_ahci }, /* ICH7M */
+	{ PCI_VENDOR_ID_INTEL, 0x27c2, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+	  board_ahci }, /* ICH7R */
+	{ PCI_VENDOR_ID_INTEL, 0x27c3, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+	  board_ahci }, /* ICH7R */
+	{ PCI_VENDOR_ID_AL, 0x5288, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+	  board_ahci }, /* ULi M5288 */
 	{ }	/* terminate list */
 };
 
@@ -442,6 +455,13 @@
 	return readl(mmio + PORT_TFDATA) & 0xFF;
 }
 
+static u8 ahci_check_err(struct ata_port *ap)
+{
+	void *mmio = (void *) ap->ioaddr.cmd_addr;
+
+	return (readl(mmio + PORT_TFDATA) >> 8) & 0xFF;
+}
+
 static void ahci_fill_sg(struct ata_queued_cmd *qc)
 {
 	struct ahci_port_priv *pp = qc->ap->private_data;
@@ -509,15 +529,6 @@
 	ahci_fill_sg(qc);
 }
 
-static inline void ahci_dma_complete (struct ata_port *ap,
-                                     struct ata_queued_cmd *qc,
-				     int have_err)
-{
-	/* get drive status; clear intr; complete txn */
-	ata_qc_complete(ata_qc_from_tag(ap, ap->active_tag),
-			have_err ? ATA_ERR : 0);
-}
-
 static void ahci_intr_error(struct ata_port *ap, u32 irq_stat)
 {
 	void *mmio = ap->host_set->mmio_base;
@@ -939,6 +950,7 @@
 	unsigned long base;
 	void *mmio_base;
 	unsigned int board_idx = (unsigned int) ent->driver_data;
+	int pci_dev_busy = 0;
 	int rc;
 
 	VPRINTK("ENTER\n");
@@ -951,8 +963,10 @@
 		return rc;
 
 	rc = pci_request_regions(pdev, DRV_NAME);
-	if (rc)
+	if (rc) {
+		pci_dev_busy = 1;
 		goto err_out;
+	}
 
 	pci_enable_intx(pdev);
 
@@ -1014,7 +1028,8 @@
 err_out_regions:
 	pci_release_regions(pdev);
 err_out:
-	pci_disable_device(pdev);
+	if (!pci_dev_busy)
+		pci_disable_device(pdev);
 	return rc;
 }
 
diff -Nru a/drivers/scsi/aic7xxx/aic7770_osm.c b/drivers/scsi/aic7xxx/aic7770_osm.c
--- a/drivers/scsi/aic7xxx/aic7770_osm.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/scsi/aic7xxx/aic7770_osm.c	2005-03-01 23:39:07 -08:00
@@ -125,14 +125,8 @@
 		uint32_t eisa_id;
 		size_t	 id_size;
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
-		if (check_region(eisaBase, AHC_EISA_IOSIZE) != 0)
-			continue;
-		request_region(eisaBase, AHC_EISA_IOSIZE, "aic7xxx");
-#else
 		if (request_region(eisaBase, AHC_EISA_IOSIZE, "aic7xxx") == 0)
 			continue;
-#endif
 
 		eisa_id = 0;
 		id_size = sizeof(eisa_id);
@@ -207,14 +201,8 @@
 	/*
 	 * Lock out other contenders for our i/o space.
 	 */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
-	if (check_region(port, AHC_EISA_IOSIZE) != 0)
-		return (ENOMEM);
-	request_region(port, AHC_EISA_IOSIZE, "aic7xxx");
-#else
 	if (request_region(port, AHC_EISA_IOSIZE, "aic7xxx") == 0)
 		return (ENOMEM);
-#endif
 	ahc->tag = BUS_SPACE_PIO;
 	ahc->bsh.ioport = port;
 	return (0);
diff -Nru a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c
--- a/drivers/scsi/aic7xxx/aic79xx_osm.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.c	2005-03-01 23:38:58 -08:00
@@ -407,18 +407,12 @@
  * Module information and settable options.
  */
 static char *aic79xx = NULL;
-/*
- * Just in case someone uses commas to separate items on the insmod
- * command line, we define a dummy buffer here to avoid having insmod
- * write wild stuff into our code segment
- */
-static char dummy_buffer[60] = "Please don't trounce on me insmod!!\n";
 
 MODULE_AUTHOR("Maintainer: Justin T. Gibbs <gibbs@scsiguy.com>");
 MODULE_DESCRIPTION("Adaptec Aic790X U320 SCSI Host Bus Adapter driver");
 MODULE_LICENSE("Dual BSD/GPL");
 MODULE_VERSION(AIC79XX_DRIVER_VERSION);
-MODULE_PARM(aic79xx, "s");
+module_param(aic79xx, charp, 0);
 MODULE_PARM_DESC(aic79xx,
 "period delimited, options string.\n"
 "	verbose			Enable verbose/diagnostic logging\n"
@@ -549,10 +543,6 @@
 static __inline void ahd_linux_run_device_queues(struct ahd_softc *ahd);
 static __inline void ahd_linux_unmap_scb(struct ahd_softc*, struct scb*);
 
-static __inline int ahd_linux_map_seg(struct ahd_softc *ahd, struct scb *scb,
-		 		      struct ahd_dma_seg *sg,
-				      dma_addr_t addr, bus_size_t len);
-
 static __inline void
 ahd_schedule_completeq(struct ahd_softc *ahd)
 {
@@ -711,28 +701,6 @@
 	}
 }
 
-static __inline int
-ahd_linux_map_seg(struct ahd_softc *ahd, struct scb *scb,
-		  struct ahd_dma_seg *sg, dma_addr_t addr, bus_size_t len)
-{
-	int	 consumed;
-
-	if ((scb->sg_count + 1) > AHD_NSEG)
-		panic("Too few segs for dma mapping.  "
-		      "Increase AHD_NSEG\n");
-
-	consumed = 1;
-	sg->addr = ahd_htole32(addr & 0xFFFFFFFF);
-	scb->platform_data->xfer_len += len;
-
-	if (sizeof(dma_addr_t) > 4
-	 && (ahd->flags & AHD_39BIT_ADDRESSING) != 0)
-		len |= (addr >> 8) & AHD_SG_HIGH_ADDR_MASK;
-
-	sg->len = ahd_htole32(len);
-	return (consumed);
-}
-
 /******************************** Macros **************************************/
 #define BUILD_SCSIID(ahd, cmd)						\
 	((((cmd)->device->id << TID_SHIFT) & TID) | (ahd)->our_id)
@@ -861,12 +829,6 @@
 	 */
 	if (aic79xx)
 		aic79xx_setup(aic79xx);
-	if (dummy_buffer[0] != 'P')
-		printk(KERN_WARNING
-"aic79xx: Please read the file /usr/src/linux/drivers/scsi/README.aic79xx\n"
-"aic79xx: to see the proper way to specify options to the aic79xx module\n"
-"aic79xx: Specifically, don't use any commas when passing arguments to\n"
-"aic79xx: insmod or else it might trash certain memory areas.\n");
 #endif
 
 	template->proc_name = "aic79xx";
diff -Nru a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c	2005-03-01 23:38:52 -08:00
@@ -427,12 +427,6 @@
  * Module information and settable options.
  */
 static char *aic7xxx = NULL;
-/*
- * Just in case someone uses commas to separate items on the insmod
- * command line, we define a dummy buffer here to avoid having insmod
- * write wild stuff into our code segment
- */
-static char dummy_buffer[60] = "Please don't trounce on me insmod!!\n";
 
 MODULE_AUTHOR("Maintainer: Justin T. Gibbs <gibbs@scsiguy.com>");
 MODULE_DESCRIPTION("Adaptec Aic77XX/78XX SCSI Host Bus Adapter driver");
@@ -850,12 +844,6 @@
 	 */
 	if (aic7xxx)
 		aic7xxx_setup(aic7xxx);
-	if (dummy_buffer[0] != 'P')
-		printk(KERN_WARNING
-"aic7xxx: Please read the file /usr/src/linux/drivers/scsi/README.aic7xxx\n"
-"aic7xxx: to see the proper way to specify options to the aic7xxx module\n"
-"aic7xxx: Specifically, don't use any commas when passing arguments to\n"
-"aic7xxx: insmod or else it might trash certain memory areas.\n");
 
 	template->proc_name = "aic7xxx";
 
diff -Nru a/drivers/scsi/aic7xxx/aic7xxx_osm.h b/drivers/scsi/aic7xxx/aic7xxx_osm.h
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.h	2005-03-01 23:38:55 -08:00
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.h	2005-03-01 23:38:55 -08:00
@@ -831,8 +831,6 @@
 
 /******************************* PCI Routines *********************************/
 #ifdef CONFIG_PCI
-void			 ahc_power_state_change(struct ahc_softc *ahc,
-						ahc_power_state new_state);
 int			 ahc_linux_pci_init(void);
 void			 ahc_linux_pci_exit(void);
 int			 ahc_pci_map_registers(struct ahc_softc *ahc);
diff -Nru a/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c b/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c
--- a/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c	2005-03-01 23:38:54 -08:00
@@ -42,12 +42,6 @@
 #include "aic7xxx_osm.h"
 #include "aic7xxx_pci.h"
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
-struct pci_device_id
-{
-};
-#endif
-
 static int	ahc_linux_pci_dev_probe(struct pci_dev *pdev,
 					const struct pci_device_id *ent);
 static int	ahc_linux_pci_reserve_io_region(struct ahc_softc *ahc,
@@ -55,7 +49,6 @@
 static int	ahc_linux_pci_reserve_mem_region(struct ahc_softc *ahc,
 						 u_long *bus_addr,
 						 uint8_t __iomem **maddr);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
 static void	ahc_linux_pci_dev_remove(struct pci_dev *pdev);
 
 /* Define the macro locally since it's different for different class of chips.
@@ -169,7 +162,6 @@
 	} else
 		ahc_list_unlock(&l);
 }
-#endif /* !LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) */
 
 static int
 ahc_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
@@ -219,7 +211,6 @@
 	ahc = ahc_alloc(NULL, name);
 	if (ahc == NULL)
 		return (-ENOMEM);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
 	if (pci_enable_device(pdev)) {
 		ahc_free(ahc);
 		return (-ENODEV);
@@ -238,14 +229,12 @@
 		}
 		ahc->platform_data->hw_dma_mask = DMA_32BIT_MASK;
 	}
-#endif
 	ahc->dev_softc = pci;
 	error = ahc_pci_config(ahc, entry);
 	if (error != 0) {
 		ahc_free(ahc);
 		return (-error);
 	}
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
 	pci_set_drvdata(pdev, ahc);
 	if (aic7xxx_detect_complete) {
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
@@ -256,39 +245,14 @@
 		return (-ENODEV);
 #endif
 	}
-#endif
 	return (0);
 }
 
 int
 ahc_linux_pci_init(void)
 {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
 	/* Translate error or zero return into zero or one */
 	return pci_module_init(&aic7xxx_pci_driver) ? 0 : 1;
-#else
-	struct pci_dev *pdev;
-	u_int class;
-	int found;
-
-	/* If we don't have a PCI bus, we can't find any adapters. */
-	if (pci_present() == 0)
-		return (0);
-
-	found = 0;
-	pdev = NULL;
-	class = PCI_CLASS_STORAGE_SCSI << 8;
-	while ((pdev = pci_find_class(class, pdev)) != NULL) {
-		ahc_dev_softc_t pci;
-		int error;
-
-		pci = pdev;
-		error = ahc_linux_pci_dev_probe(pdev, /*pci_devid*/NULL);
-		if (error == 0)
-			found++;
-	}
-	return (found);
-#endif
 }
 
 void
@@ -303,22 +267,11 @@
 	if (aic7xxx_allow_memio == 0)
 		return (ENOMEM);
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
 	*base = pci_resource_start(ahc->dev_softc, 0);
-#else
-	*base = ahc_pci_read_config(ahc->dev_softc, PCIR_MAPS, 4);
-	*base &= PCI_BASE_ADDRESS_IO_MASK;
-#endif
 	if (*base == 0)
 		return (ENOMEM);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
-	if (check_region(*base, 256) != 0)
-		return (ENOMEM);
-	request_region(*base, 256, "aic7xxx");
-#else
 	if (request_region(*base, 256, "aic7xxx") == 0)
 		return (ENOMEM);
-#endif
 	return (0);
 }
 
@@ -334,17 +287,13 @@
 	start = pci_resource_start(ahc->dev_softc, 1);
 	if (start != 0) {
 		*bus_addr = start;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
 		if (request_mem_region(start, 0x1000, "aic7xxx") == 0)
 			error = ENOMEM;
-#endif
 		if (error == 0) {
 			*maddr = ioremap_nocache(start, 256);
 			if (*maddr == NULL) {
 				error = ENOMEM;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
 				release_mem_region(start, 0x1000);
-#endif
 			}
 		}
 	} else
@@ -387,10 +336,8 @@
 			       ahc_get_pci_slot(ahc->dev_softc),
 			       ahc_get_pci_function(ahc->dev_softc));
 			iounmap(maddr);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
 			release_mem_region(ahc->platform_data->mem_busaddr,
 					   0x1000);
-#endif
 			ahc->bsh.maddr = NULL;
 			maddr = NULL;
 		} else
@@ -440,41 +387,3 @@
 	return (-error);
 }
 
-void
-ahc_power_state_change(struct ahc_softc *ahc, ahc_power_state new_state)
-{
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-	pci_set_power_state(ahc->dev_softc, new_state);
-#else
-	uint32_t cap;
-	u_int cap_offset;
-
-	/*
-	 * Traverse the capability list looking for
-	 * the power management capability.
-	 */
-	cap = 0;
-	cap_offset = ahc_pci_read_config(ahc->dev_softc,
-					 PCIR_CAP_PTR, /*bytes*/1);
-	while (cap_offset != 0) {
-
-		cap = ahc_pci_read_config(ahc->dev_softc,
-					  cap_offset, /*bytes*/4);
-		if ((cap & 0xFF) == 1
-		 && ((cap >> 16) & 0x3) > 0) {
-			uint32_t pm_control;
-
-			pm_control = ahc_pci_read_config(ahc->dev_softc,
-							 cap_offset + 4,
-							 /*bytes*/4);
-			pm_control &= ~0x3;
-			pm_control |= new_state;
-			ahc_pci_write_config(ahc->dev_softc,
-					     cap_offset + 4,
-					     pm_control, /*bytes*/2);
-			break;
-		}
-		cap_offset = (cap >> 8) & 0xFF;
-	}
-#endif 
-}
diff -Nru a/drivers/scsi/aic7xxx/aic7xxx_pci.c b/drivers/scsi/aic7xxx/aic7xxx_pci.c
--- a/drivers/scsi/aic7xxx/aic7xxx_pci.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/scsi/aic7xxx/aic7xxx_pci.c	2005-03-01 23:38:52 -08:00
@@ -721,7 +721,7 @@
 	ahc->chip |= AHC_PCI;
 	ahc->description = entry->name;
 
-	ahc_power_state_change(ahc, AHC_POWER_STATE_D0);
+	pci_set_power_state(ahc->dev_softc, AHC_POWER_STATE_D0);
 
 	error = ahc_pci_map_registers(ahc);
 	if (error != 0)
@@ -2016,7 +2016,7 @@
 ahc_pci_resume(struct ahc_softc *ahc)
 {
 
-	ahc_power_state_change(ahc, AHC_POWER_STATE_D0);
+	pci_set_power_state(ahc->dev_softc, AHC_POWER_STATE_D0);
 
 	/*
 	 * We assume that the OS has restored our register
diff -Nru a/drivers/scsi/aic7xxx_old/aic7xxx_proc.c b/drivers/scsi/aic7xxx_old/aic7xxx_proc.c
--- a/drivers/scsi/aic7xxx_old/aic7xxx_proc.c	2005-03-01 23:39:10 -08:00
+++ b/drivers/scsi/aic7xxx_old/aic7xxx_proc.c	2005-03-01 23:39:10 -08:00
@@ -64,7 +64,7 @@
  * Description:
  *   Set parameters for the driver from the /proc filesystem.
  *-F*************************************************************************/
-int
+static int
 aic7xxx_set_info(char *buffer, int length, struct Scsi_Host *HBAptr)
 {
   proc_debug("aic7xxx_set_info(): %s\n", buffer);
diff -Nru a/drivers/scsi/aic7xxx_old.c b/drivers/scsi/aic7xxx_old.c
--- a/drivers/scsi/aic7xxx_old.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/scsi/aic7xxx_old.c	2005-03-01 23:39:18 -08:00
@@ -224,7 +224,6 @@
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/byteorder.h>
-#include <linux/version.h>
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
@@ -1838,7 +1837,7 @@
  * Description:
  *   Return a string describing the driver.
  *-F*************************************************************************/
-const char *
+static const char *
 aic7xxx_info(struct Scsi_Host *dooh)
 {
   static char buffer[256];
@@ -10564,8 +10563,7 @@
 aic7xxx_panic_abort(struct aic7xxx_host *p, Scsi_Cmnd *cmd)
 {
 
-  printk("aic7xxx driver version %s/%s\n", AIC7XXX_C_VERSION,
-         UTS_RELEASE);
+  printk("aic7xxx driver version %s\n", AIC7XXX_C_VERSION);
   printk("Controller type:\n    %s\n", board_names[p->board_name_index]);
   printk("p->flags=0x%lx, p->chip=0x%x, p->features=0x%x, "
          "sequencer %s paused\n",
diff -Nru a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c
--- a/drivers/scsi/ata_piix.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/scsi/ata_piix.c	2005-03-01 23:39:18 -08:00
@@ -60,6 +60,7 @@
 	piix4_pata		= 2,
 	ich6_sata		= 3,
 	ich6_sata_rm		= 4,
+	ich7_sata		= 5,
 };
 
 static int piix_init_one (struct pci_dev *pdev,
@@ -90,6 +91,8 @@
 	{ 0x8086, 0x2651, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata },
 	{ 0x8086, 0x2652, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_rm },
 	{ 0x8086, 0x2653, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_rm },
+	{ 0x8086, 0x27c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich7_sata },
+	{ 0x8086, 0x27c4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich7_sata },
 
 	{ }	/* terminate list */
 };
@@ -135,6 +138,8 @@
 
 	.bmdma_setup		= ata_bmdma_setup,
 	.bmdma_start		= ata_bmdma_start,
+	.bmdma_stop		= ata_bmdma_stop,
+	.bmdma_status		= ata_bmdma_status,
 	.qc_prep		= ata_qc_prep,
 	.qc_issue		= ata_qc_issue_prot,
 
@@ -160,6 +165,8 @@
 
 	.bmdma_setup		= ata_bmdma_setup,
 	.bmdma_start		= ata_bmdma_start,
+	.bmdma_stop		= ata_bmdma_stop,
+	.bmdma_status		= ata_bmdma_status,
 	.qc_prep		= ata_qc_prep,
 	.qc_issue		= ata_qc_issue_prot,
 
@@ -226,6 +233,18 @@
 	},
 
 	/* ich6_sata_rm */
+	{
+		.sht		= &piix_sht,
+		.host_flags	= ATA_FLAG_SATA | ATA_FLAG_SRST |
+				  PIIX_FLAG_COMBINED | PIIX_FLAG_CHECKINTR |
+				  ATA_FLAG_SLAVE_POSS | PIIX_FLAG_AHCI,
+		.pio_mask	= 0x1f,	/* pio0-4 */
+		.mwdma_mask	= 0x07, /* mwdma0-2 */
+		.udma_mask	= 0x7f,	/* udma0-6 */
+		.port_ops	= &piix_sata_ops,
+	},
+
+	/* ich7_sata */
 	{
 		.sht		= &piix_sht,
 		.host_flags	= ATA_FLAG_SATA | ATA_FLAG_SRST |
diff -Nru a/drivers/scsi/constants.c b/drivers/scsi/constants.c
--- a/drivers/scsi/constants.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/scsi/constants.c	2005-03-01 23:39:08 -08:00
@@ -4,6 +4,7 @@
  * Additions for SCSI 2 and Linux 2.2.x by D. Gilbert (990422)
  * Additions for SCSI 3+ (SPC-3 T10/1416-D Rev 07 3 May 2002)
  *   by D. Gilbert and aeb (20020609)
+ * Additions for SPC-3 T10/1416-D Rev 21 22 Sept 2004, D. Gilbert 20041025
  */
 
 #include <linux/config.h>
@@ -15,96 +16,78 @@
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_request.h>
+#include <scsi/scsi_eh.h>
 
 
-#define CONST_COMMAND   0x01
-#define CONST_STATUS    0x02
-#define CONST_SENSE     0x04
-#define CONST_XSENSE    0x08
-#define CONST_CMND      0x10
-#define CONST_MSG       0x20
-#define CONST_HOST	0x40
-#define CONST_DRIVER	0x80
 
-static const char unknown[] = "UNKNOWN";
+/* Commands with service actions that change the command name */
+#define MAINTENANCE_IN 0xa3
+#define MAINTENANCE_OUT 0xa4
+#define SERVICE_ACTION_IN_12 0xab
+#define SERVICE_ACTION_OUT_12 0xa9
+#define SERVICE_ACTION_IN_16 0x9e
+#define SERVICE_ACTION_OUT_16 0x9f
+#define VARIABLE_LENGTH_CMD 0x7f
 
-#ifdef CONFIG_SCSI_CONSTANTS
-#ifdef CONSTANTS
-#undef CONSTANTS
-#endif
-#define CONSTANTS (CONST_COMMAND | CONST_STATUS | CONST_SENSE | CONST_XSENSE \
-		   | CONST_CMND | CONST_MSG | CONST_HOST | CONST_DRIVER)
-#else
-#define CONSTANTS 0
-#endif
-
-#if (CONSTANTS & CONST_COMMAND)
-static const char * group_0_commands[] = {
-/* 00-03 */ "Test Unit Ready", "Rezero Unit", unknown, "Request Sense",
-/* 04-07 */ "Format Unit", "Read Block Limits", unknown, "Reasssign Blocks",
-/* 08-0d */ "Read (6)", unknown, "Write (6)", "Seek (6)", unknown, unknown,
-/* 0e-12 */ unknown, "Read Reverse", "Write Filemarks", "Space", "Inquiry",  
-/* 13-16 */ "Verify", "Recover Buffered Data", "Mode Select", "Reserve",
-/* 17-1b */ "Release", "Copy", "Erase", "Mode Sense", "Start/Stop Unit",
-/* 1c-1d */ "Receive Diagnostic", "Send Diagnostic", 
-/* 1e-1f */ "Prevent/Allow Medium Removal", unknown,
-};
 
 
-static const char *group_1_commands[] = {
-/* 20-22 */  unknown, unknown, unknown,
-/* 23-28 */ unknown, "Define window parameters", "Read Capacity", 
-            unknown, unknown, "Read (10)", 
-/* 29-2d */ "Read Generation", "Write (10)", "Seek (10)", "Erase", 
+#ifdef CONFIG_SCSI_CONSTANTS
+static const char * cdb_byte0_names[] = {
+/* 00-03 */ "Test Unit Ready", "Rezero Unit/Rewind", NULL, "Request Sense",
+/* 04-07 */ "Format Unit/Medium", "Read Block Limits", NULL,
+	    "Reasssign Blocks",
+/* 08-0d */ "Read (6)", NULL, "Write (6)", "Seek (6)", NULL, NULL,
+/* 0e-12 */ NULL, "Read Reverse", "Write Filemarks", "Space", "Inquiry",  
+/* 13-16 */ "Verify (6)", "Recover Buffered Data", "Mode Select (6)",
+	    "Reserve (6)",
+/* 17-1a */ "Release (6)", "Copy", "Erase", "Mode Sense (6)", 
+/* 1b-1d */ "Start/Stop Unit", "Receive Diagnostic", "Send Diagnostic", 
+/* 1e-1f */ "Prevent/Allow Medium Removal", NULL,
+/* 20-22 */  NULL, NULL, NULL,
+/* 23-28 */ "Read Format Capacities", "Set Window",
+	    "Read Capacity (10)", NULL, NULL, "Read (10)", 
+/* 29-2d */ "Read Generation", "Write (10)", "Seek (10)", "Erase (10)", 
             "Read updated block", 
-/* 2e-31 */ "Write Verify","Verify", "Search High", "Search Equal", 
-/* 32-34 */ "Search Low", "Set Limits", "Prefetch or Read Position", 
-/* 35-37 */ "Synchronize Cache","Lock/Unlock Cache", "Read Defect Data", 
+/* 2e-31 */ "Write Verify (10)", "Verify (10)", "Search High", "Search Equal", 
+/* 32-34 */ "Search Low", "Set Limits", "Prefetch/Read Position", 
+/* 35-37 */ "Synchronize Cache (10)", "Lock/Unlock Cache (10)",
+	    "Read Defect Data(10)", 
 /* 38-3c */ "Medium Scan", "Compare", "Copy Verify", "Write Buffer", 
             "Read Buffer", 
-/* 3d-3f */ "Update Block", "Read Long",  "Write Long",
-};
-
-
-static const char *group_2_commands[] = {
-/* 40-41 */ "Change Definition", "Write Same",
-/* 42-48 */ "Read sub-channel", "Read TOC", "Read header",
+/* 3d-3f */ "Update Block", "Read Long (10)",  "Write Long (10)",
+/* 40-41 */ "Change Definition", "Write Same (10)",
+/* 42-48 */ "Read sub-channel", "Read TOC/PMA/ATIP", "Read density support",
             "Play audio (10)", "Get configuration", "Play audio msf",
             "Play audio track/index",
 /* 49-4f */ "Play track relative (10)", "Get event status notification",
             "Pause/resume", "Log Select", "Log Sense", "Stop play/scan",
-            unknown,
+            NULL,
 /* 50-55 */ "Xdwrite", "Xpwrite, Read disk info", "Xdread, Read track info",
-            "Reserve track", "Send OPC onfo", "Mode Select (10)",
+            "Reserve track", "Send OPC info", "Mode Select (10)",
 /* 56-5b */ "Reserve (10)", "Release (10)", "Repair track", "Read master cue",
             "Mode Sense (10)", "Close track/session",
 /* 5c-5f */ "Read buffer capacity", "Send cue sheet", "Persistent reserve in",
             "Persistent reserve out",
-};
-
-
-/* The following are 16 byte commands in group 4 */
-static const char *group_4_commands[] = {
+/* 60-67 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+/* 68-6f */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+/* 70-77 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+/* 78-7f */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, "Variable length",
 /* 80-84 */ "Xdwrite (16)", "Rebuild (16)", "Regenerate (16)", "Extended copy",
             "Receive copy results",
 /* 85-89 */ "Memory Export In (16)", "Access control in", "Access control out",
             "Read (16)", "Memory Export Out (16)",
-/* 8a-8f */ "Write (16)", unknown, "Read attributes", "Write attributes",
+/* 8a-8f */ "Write (16)", NULL, "Read attributes", "Write attributes",
             "Write and verify (16)", "Verify (16)",
 /* 90-94 */ "Pre-fetch (16)", "Synchronize cache (16)",
-            "Lock/unlock cache (16)", "Write same (16)", unknown,
-/* 95-99 */ unknown, unknown, unknown, unknown, unknown,
-/* 9a-9f */ unknown, unknown, unknown, unknown, "Service action in",
-            "Service action out",
-};
-
-/* The following are 12 byte commands in group 5 */
-static const char *group_5_commands[] = {
-/* a0-a5 */ "Report luns", "Blank", "Send event", "Maintenance (in)",
-            "Maintenance (out)", "Move medium/play audio(12)",
+            "Lock/unlock cache (16)", "Write same (16)", NULL,
+/* 95-99 */ NULL, NULL, NULL, NULL, NULL,
+/* 9a-9f */ NULL, NULL, NULL, NULL, "Service action in (16)",
+            "Service action out (16)",
+/* a0-a5 */ "Report luns", "Blank", "Send event", "Maintenance in",
+            "Maintenance out", "Move medium/play audio(12)",
 /* a6-a9 */ "Exchange medium", "Move medium attached", "Read(12)",
             "Play track relative(12)",
-/* aa-ae */ "Write(12)", unknown, "Erase(12), Get Performance",
+/* aa-ae */ "Write(12)", NULL, "Erase(12), Get Performance",
             "Read DVD structure", "Write and verify(12)",
 /* af-b1 */ "Verify(12)", "Search data high(12)", "Search data equal(12)",
 /* b2-b4 */ "Search data low(12)", "Set limits(12)",
@@ -112,57 +95,279 @@
 /* b5-b6 */ "Request volume element address", "Send volume tag, set streaming",
 /* b7-b9 */ "Read defect data(12)", "Read element status", "Read CD msf",
 /* ba-bc */ "Redundancy group (in), Scan",
-            "Redundancy group (out), Set cd-rom speed", "Spare (in), Play cd",
-/* bd-bf */ "Spare (out), Mechanism status", "Volume set (in), Read cd",
-            "Volume set (out), Send DVD structure",
+            "Redundancy group (out), Set cd-rom speed", "Spare in, Play cd",
+/* bd-bf */ "Spare out, Mechanism status", "Volume set in, Read cd",
+            "Volume set out, Send DVD structure",
 };
 
+struct value_name_pair {
+	int value;
+	const char * name;
+};
 
+static const struct value_name_pair maint_in_arr[] = {
+	{0x5, "Report device identifier"},
+	{0xa, "Report target port groups"},
+	{0xb, "Report aliases"},
+	{0xc, "Report supported operation codes"},
+	{0xd, "Report supported task management functions"},
+	{0xe, "Report priority"},
+};
+#define MAINT_IN_SZ \
+        (int)(sizeof(maint_in_arr) / sizeof(maint_in_arr[0]))
 
-#define group(opcode) (((opcode) >> 5) & 7)
+static const struct value_name_pair maint_out_arr[] = {
+	{0x6, "Set device identifier"},
+	{0xa, "Set target port groups"},
+	{0xb, "Change aliases"},
+	{0xe, "Set priority"},
+};
+#define MAINT_OUT_SZ \
+        (int)(sizeof(maint_out_arr) / sizeof(maint_out_arr[0]))
 
-#define RESERVED_GROUP  0
-#define VENDOR_GROUP    1
+static const struct value_name_pair serv_in12_arr[] = {
+	{0x1, "Read media serial number"},
+};
+#define SERV_IN12_SZ  \
+        (int)(sizeof(serv_in12_arr) / sizeof(serv_in12_arr[0]))
 
-static const char **commands[] = {
-    group_0_commands, group_1_commands, group_2_commands, 
-    (const char **) RESERVED_GROUP, group_4_commands, 
-    group_5_commands, (const char **) VENDOR_GROUP, 
-    (const char **) VENDOR_GROUP
+static const struct value_name_pair serv_out12_arr[] = {
+	{-1, "dummy entry"},
 };
+#define SERV_OUT12_SZ \
+        (int)(sizeof(serv_out12_arr) / sizeof(serv_in12_arr[0]))
 
-static const char reserved[] = "RESERVED";
-static const char vendor[] = "VENDOR SPECIFIC";
+static const struct value_name_pair serv_in16_arr[] = {
+	{0x10, "Read capacity(16)"},
+	{0x11, "Read long(16)"},
+};
+#define SERV_IN16_SZ  \
+        (int)(sizeof(serv_in16_arr) / sizeof(serv_in16_arr[0]))
 
-static void print_opcode(int opcode) {
-    const char **table = commands[ group(opcode) ];
-    switch ((unsigned long) table) {
-    case RESERVED_GROUP:
-	printk("%s(0x%02x) ", reserved, opcode); 
-	break;
-    case VENDOR_GROUP:
-	printk("%s(0x%02x) ", vendor, opcode); 
-	break;
-    default:
-	if (table[opcode & 0x1f] != unknown)
-	    printk("%s ",table[opcode & 0x1f]);
-	else
-	    printk("%s(0x%02x) ", unknown, opcode);
-	break;
-    }
+static const struct value_name_pair serv_out16_arr[] = {
+	{0x11, "Write long(16)"},
+	{0x1f, "Notify data transfer device(16)"},
+};
+#define SERV_OUT16_SZ \
+        (int)(sizeof(serv_out16_arr) / sizeof(serv_in16_arr[0]))
+
+static const struct value_name_pair variable_length_arr[] = {
+	{0x1, "Rebuild(32)"},
+	{0x2, "Regenerate(32)"},
+	{0x3, "Xdread(32)"},
+	{0x4, "Xdwrite(32)"},
+	{0x5, "Xdwrite extended(32)"},
+	{0x6, "Xpwrite(32)"},
+	{0x7, "Xdwriteread(32)"},
+	{0x8, "Xdwrite extended(64)"},
+	{0x9, "Read(32)"},
+	{0xa, "Verify(32)"},
+	{0xb, "Write(32)"},
+	{0xc, "Write an verify(32)"},
+	{0xd, "Write same(32)"},
+	{0x8801, "Format OSD"},
+	{0x8802, "Create (osd)"},
+	{0x8803, "List (osd)"},
+	{0x8805, "Read (osd)"},
+	{0x8806, "Write (osd)"},
+	{0x8807, "Append (osd)"},
+	{0x8808, "Flush (osd)"},
+	{0x880a, "Remove (osd)"},
+	{0x880b, "Create partition (osd)"},
+	{0x880c, "Remove partition (osd)"},
+	{0x880e, "Get attributes (osd)"},
+	{0x880f, "Set attributes (osd)"},
+	{0x8812, "Create and write (osd)"},
+	{0x8815, "Create collection (osd)"},
+	{0x8816, "Remove collection (osd)"},
+	{0x8817, "List collection (osd)"},
+	{0x8818, "Set key (osd)"},
+	{0x8819, "Set master key (osd)"},
+	{0x881a, "Flush collection (osd)"},
+	{0x881b, "Flush partition (osd)"},
+	{0x881c, "Flush OSD"},
+	{0x8f7e, "Perform SCSI command (osd)"},
+	{0x8f7f, "Perform task management function (osd)"},
+};
+#define VARIABLE_LENGTH_SZ \
+        (int)(sizeof(variable_length_arr) / sizeof(variable_length_arr[0]))
+
+static const char * get_sa_name(const struct value_name_pair * arr,
+			        int arr_sz, int service_action)
+{
+	int k;
+
+	for (k = 0; k < arr_sz; ++k, ++arr) {
+		if (service_action == arr->value)
+			break;
+	}
+	return (k < arr_sz) ? arr->name : NULL;
 }
-#else /* CONST & CONST_COMMAND */
-static void print_opcode(int opcode) {
-    printk("0x%02x ", opcode);
+
+/* attempt to guess cdb length if cdb_len==0 . No trailing linefeed. */
+static void print_opcode_name(unsigned char * cdbp, int cdb_len,
+			      int start_of_line)
+{
+	int sa, len, cdb0;
+	const char * name;
+	const char * leadin = start_of_line ? KERN_INFO : "";
+
+	cdb0 = cdbp[0];
+	switch(cdb0) {
+	case VARIABLE_LENGTH_CMD:
+		len = cdbp[7] + 8;
+		if (len < 10) {
+			printk("%sshort variable length command, "
+			       "len=%d ext_len=%d", leadin, len, cdb_len);
+			break;
+		}
+		sa = (cdbp[8] << 8) + cdbp[9];
+		name = get_sa_name(maint_in_arr, MAINT_IN_SZ, sa);
+		if (name) {
+			printk("%s%s", leadin, name);
+			if ((cdb_len > 0) && (len != cdb_len))
+				printk(", in_cdb_len=%d, ext_len=%d",
+				       len, cdb_len);
+		} else {
+			printk("%scdb[0]=0x%x, sa=0x%x", leadin, cdb0, sa);
+			if ((cdb_len > 0) && (len != cdb_len))
+				printk(", in_cdb_len=%d, ext_len=%d",
+				       len, cdb_len);
+		}
+		break;
+	case MAINTENANCE_IN:
+		sa = cdbp[1] & 0x1f;
+		name = get_sa_name(maint_in_arr, MAINT_IN_SZ, sa);
+		if (name)
+			printk("%s%s", leadin, name);
+		else
+			printk("%scdb[0]=0x%x, sa=0x%x", leadin, cdb0, sa);
+		break;
+	case MAINTENANCE_OUT:
+		sa = cdbp[1] & 0x1f;
+		name = get_sa_name(maint_out_arr, MAINT_OUT_SZ, sa);
+		if (name)
+			printk("%s%s", leadin, name);
+		else
+			printk("%scdb[0]=0x%x, sa=0x%x", leadin, cdb0, sa);
+		break;
+	case SERVICE_ACTION_IN_12:
+		sa = cdbp[1] & 0x1f;
+		name = get_sa_name(serv_in12_arr, SERV_IN12_SZ, sa);
+		if (name)
+			printk("%s%s", leadin, name);
+		else
+			printk("%scdb[0]=0x%x, sa=0x%x", leadin, cdb0, sa);
+		break;
+	case SERVICE_ACTION_OUT_12:
+		sa = cdbp[1] & 0x1f;
+		name = get_sa_name(serv_out12_arr, SERV_OUT12_SZ, sa);
+		if (name)
+			printk("%s%s", leadin, name);
+		else
+			printk("%scdb[0]=0x%x, sa=0x%x", leadin, cdb0, sa);
+		break;
+	case SERVICE_ACTION_IN_16:
+		sa = cdbp[1] & 0x1f;
+		name = get_sa_name(serv_in16_arr, SERV_IN16_SZ, sa);
+		if (name)
+			printk("%s%s", leadin, name);
+		else
+			printk("%scdb[0]=0x%x, sa=0x%x", leadin, cdb0, sa);
+		break;
+	case SERVICE_ACTION_OUT_16:
+		sa = cdbp[1] & 0x1f;
+		name = get_sa_name(serv_out16_arr, SERV_OUT16_SZ, sa);
+		if (name)
+			printk("%s%s", leadin, name);
+		else
+			printk("%scdb[0]=0x%x, sa=0x%x", leadin, cdb0, sa);
+		break;
+	default:
+		if (cdb0 < 0xc0) {
+			name = cdb_byte0_names[cdb0];
+			if (name)
+				printk("%s%s", leadin, name);
+			else
+				printk("%scdb[0]=0x%x (reserved)",
+				       leadin, cdb0);
+		} else
+			printk("%scdb[0]=0x%x (vendor)", leadin, cdb0);
+		break;
+	}
+}
+
+#else /* ifndef CONFIG_SCSI_CONSTANTS */
+
+static void print_opcode_name(unsigned char * cdbp, int cdb_len,
+			      int start_of_line)
+{
+	int sa, len, cdb0;
+	const char * leadin = start_of_line ? KERN_INFO : "";
+
+	cdb0 = cdbp[0];
+	switch(cdb0) {
+	case VARIABLE_LENGTH_CMD:
+		len = cdbp[7] + 8;
+		if (len < 10) {
+			printk("%sshort opcode=0x%x command, len=%d "
+			       "ext_len=%d", leadin, cdb0, len, cdb_len);
+			break;
+		}
+		sa = (cdbp[8] << 8) + cdbp[9];
+		printk("%scdb[0]=0x%x, sa=0x%x", leadin, cdb0, sa);
+		if (len != cdb_len)
+			printk(", in_cdb_len=%d, ext_len=%d", len, cdb_len);
+		break;
+	case MAINTENANCE_IN:
+	case MAINTENANCE_OUT:
+	case SERVICE_ACTION_IN_12:
+	case SERVICE_ACTION_OUT_12:
+	case SERVICE_ACTION_IN_16:
+	case SERVICE_ACTION_OUT_16:
+		sa = cdbp[1] & 0x1f;
+		printk("%scdb[0]=0x%x, sa=0x%x", leadin, cdb0, sa);
+		break;
+	default:
+		if (cdb0 < 0xc0)
+			printk("%scdb[0]=0x%x", leadin, cdb0);
+		else
+			printk("%scdb[0]=0x%x (vendor)", leadin, cdb0);
+		break;
+	}
 }
 #endif  
 
-void __scsi_print_command (unsigned char *command) {
-    int i,s;
-    print_opcode(command[0]);
-    for ( i = 1, s = COMMAND_SIZE(command[0]); i < s; ++i) 
-	printk("%02x ", command[i]);
-    printk("\n");
+void __scsi_print_command(unsigned char *command)
+{
+	int k, len;
+
+	print_opcode_name(command, 0, 1);
+	if (VARIABLE_LENGTH_CMD == command[0])
+		len = command[7] + 8;
+	else
+		len = COMMAND_SIZE(command[0]);
+	/* print out all bytes in cdb */
+	for (k = 0; k < len; ++k) 
+		printk(" %02x", command[k]);
+	printk("\n");
+}
+EXPORT_SYMBOL(__scsi_print_command);
+
+/* This function (perhaps with the addition of peripheral device type)
+ * is more approriate than __scsi_print_command(). Perhaps that static
+ * can be dropped later if it replaces the __scsi_print_command version.
+ */
+static void scsi_print_cdb(unsigned char *cdb, int cdb_len, int start_of_line)
+{
+	int k;
+
+	print_opcode_name(cdb, cdb_len, start_of_line);
+	/* print out all bytes in cdb */
+	printk(":");
+	for (k = 0; k < cdb_len; ++k) 
+		printk(" %02x", cdb[k]);
+	printk("\n");
 }
 
 /**
@@ -177,7 +382,7 @@
  **/
 void
 scsi_print_status(unsigned char scsi_status) {
-#if (CONSTANTS & CONST_STATUS)
+#ifdef CONFIG_SCSI_CONSTANTS
 	const char * ccp;
 
 	switch (scsi_status) {
@@ -194,13 +399,14 @@
 	case 0x40: ccp = "Task Aborted"; break;
 	default:   ccp = "Unknown status";
 	}
-	printk("%s", ccp);
+	printk(KERN_INFO "%s", ccp);
 #else
-	printk("0x%0x", scsi_status);
+	printk(KERN_INFO "0x%0x", scsi_status);
 #endif
 }
+EXPORT_SYMBOL(scsi_print_status);
 
-#if (CONSTANTS & CONST_XSENSE)
+#ifdef CONFIG_SCSI_CONSTANTS
 
 struct error_info {
 	unsigned short code12;	/* 0x0302 looks better than 0x03,0x02 */
@@ -253,6 +459,8 @@
 	{0x040C, "Logical unit not accessible, target port in unavailable "
 	 "state"},
 	{0x0410, "Logical unit not ready, auxiliary memory not accessible"},
+	{0x0411, "Logical unit not ready, notify (enable spinup) required"},
+	{0x0412, "Logical unit not ready, offline"},
 
 	{0x0500, "Logical unit does not respond to selection"},
 
@@ -300,7 +508,14 @@
 	{0x0D04, "Copy target device data underrun"},
 	{0x0D05, "Copy target device data overrun"},
 
+	{0x0E00, "Invalid information unit"},
+	{0x0E01, "Information unit too short"},
+	{0x0E02, "Information unit too long"},
+
 	{0x1000, "Id CRC or ECC error"},
+	{0x1001, "Data block guard check failed"},
+	{0x1002, "Data block application tag check failed"},
+	{0x1003, "Data block reference tag check failed"},
 
 	{0x1100, "Unrecovered read error"},
 	{0x1101, "Read retries exhausted"},
@@ -407,8 +622,10 @@
 
 	{0x2400, "Invalid field in cdb"},
 	{0x2401, "CDB decryption error"},
-	{0x2402, "Obsolete"},
-	{0x2403, "Obsolete"},
+	{0x2404, "Security audit value frozen"},
+	{0x2405, "Security working key frozen"},
+	{0x2406, "Nonce not unique"},
+	{0x2407, "Nonce timestamp out of range"},
 
 	{0x2500, "Logical unit not supported"},
 
@@ -426,6 +643,8 @@
 	{0x260B, "Inline data length exceeded"},
 	{0x260C, "Invalid operation for copy source or destination"},
 	{0x260D, "Copy segment granularity violation"},
+	{0x260E, "Invalid parameter while port is enabled"},
+	{0x260F, "Invalid data-out buffer integrity"},
 
 	{0x2700, "Write protected"},
 	{0x2701, "Hardware write protected"},
@@ -455,6 +674,8 @@
 	{0x2A05, "Registrations preempted"},
 	{0x2A06, "Asymmetric access state changed"},
 	{0x2A07, "Implicit asymmetric access state transition failed"},
+	{0x2A08, "Priority changed"},
+	{0x2A09, "Capacity data has changed"},
 
 	{0x2B00, "Copy cannot execute since host cannot disconnect"},
 
@@ -468,6 +689,8 @@
 	{0x2C07, "Previous busy status"},
 	{0x2C08, "Previous task set full status"},
 	{0x2C09, "Previous reservation conflict status"},
+	{0x2C0A, "Partition or collection contains user objects"},
+	{0x2C0B, "Not reserved"},
 
 	{0x2D00, "Overwrite error on update in place"},
 
@@ -485,6 +708,8 @@
 	{0x3007, "Cleaning failure"},
 	{0x3008, "Cannot write - application code mismatch"},
 	{0x3009, "Current session not fixated for append"},
+	{0x300A, "Cleaning request rejected"},
+	{0x300C, "WORM medium, overwrite attempted"},
 	{0x3010, "Medium not formatted"},
 
 	{0x3100, "Medium format corrupted"},
@@ -503,6 +728,7 @@
 	{0x3502, "Enclosure services unavailable"},
 	{0x3503, "Enclosure services transfer failure"},
 	{0x3504, "Enclosure services transfer refused"},
+	{0x3505, "Enclosure services checksum error"},
 
 	{0x3600, "Ribbon, ink, or toner failure"},
 
@@ -543,6 +769,7 @@
 	{0x3B14, "Medium magazine locked"},
 	{0x3B15, "Medium magazine unlocked"},
 	{0x3B16, "Mechanical positioning or changer error"},
+	{0x3B17, "Read past end of user object"},
 
 	{0x3D00, "Invalid bits in identify message"},
 
@@ -570,14 +797,12 @@
 	{0x3F0F, "Echo buffer overwritten"},
 	{0x3F10, "Medium loadable"},
 	{0x3F11, "Medium auxiliary memory accessible"},
-
-#if 0
-	{0x40NN, "Ram failure"},
-	{0x40NN, "Diagnostic failure on component nn"},
-	{0x41NN, "Data path failure"},
-	{0x42NN, "Power-on or self-test failure"},
-#endif
-
+/*
+ *	{0x40NN, "Ram failure"},
+ *	{0x40NN, "Diagnostic failure on component nn"},
+ *	{0x41NN, "Data path failure"},
+ *	{0x42NN, "Power-on or self-test failure"},
+ */
 	{0x4300, "Message error"},
 
 	{0x4400, "Internal target failure"},
@@ -592,6 +817,7 @@
 	{0x4703, "Information unit CRC error detected"},
 	{0x4704, "Asynchronous information protection error detected"},
 	{0x4705, "Protocol service CRC error"},
+	{0x477f, "Some commands cleared by iSCSI Protocol event"},
 
 	{0x4800, "Initiator detected error message received"},
 
@@ -600,13 +826,17 @@
 	{0x4A00, "Command phase error"},
 
 	{0x4B00, "Data phase error"},
+	{0x4B01, "Invalid target port transfer tag received"},
+	{0x4B02, "Too much write data"},
+	{0x4B03, "Ack/nak timeout"},
+	{0x4B04, "Nak received"},
+	{0x4B05, "Data offset error"},
+	{0x4B06, "Initiator response timeout"},
 
 	{0x4C00, "Logical unit failed self-configuration"},
-
-#if 0
-	{0x4DNN, "Tagged overlapped commands (nn = queue tag)"},
-#endif
-
+/*
+ *	{0x4DNN, "Tagged overlapped commands (nn = queue tag)"},
+ */
 	{0x4E00, "Overlapped commands attempted"},
 
 	{0x5000, "Write append error"},
@@ -631,6 +861,7 @@
 	{0x5504, "Insufficient registration resources"},
 	{0x5505, "Insufficient access control resources"},
 	{0x5506, "Auxiliary memory out of space"},
+	{0x5507, "Quota error"},
 
 	{0x5700, "Unable to recover table-of-contents"},
 
@@ -806,11 +1037,9 @@
 	{0x6F03, "Read of scrambled sector without authentication"},
 	{0x6F04, "Media region code is mismatched to logical unit region"},
 	{0x6F05, "Drive region must be permanent/region reset count error"},
-
-#if 0
-	{0x70NN, "Decompression exception short algorithm id of nn"},
-#endif
-
+/*
+ *	{0x70NN, "Decompression exception short algorithm id of nn"},
+ */
 	{0x7100, "Decompression exception long algorithm id"},
 
 	{0x7200, "Session fixation error"},
@@ -845,9 +1074,7 @@
 	{0x70,0x00,0xff,"Decompression exception short algorithm id of %x"},
 	{0, 0, 0, NULL}
 };
-#endif
 
-#if (CONSTANTS & CONST_SENSE)
 /* description of the sense key values */
 static const char *snstext[] = {
 	"No Sense",	    /* 0: There is no sense information */
@@ -858,11 +1085,11 @@
 	"Hardware Error",   /* 4: Controller or device failure */
 	"Illegal Request",  /* 5: Error in request */
 	"Unit Attention",   /* 6: Removable medium was changed, or
-				  the target has been reset */
+				  the target has been reset, or ... */
 	"Data Protect",	    /* 7: Access to the data is blocked */
 	"Blank Check",	    /* 8: Reached unexpected written or unwritten
 				  region of the medium */
-	"Vendor Specific",  /* 9: Vendor specific */
+	"Vendor Specific(9)",
 	"Copy Aborted",	    /* A: COPY or COMPARE was aborted */
 	"Aborted Command",  /* B: The target aborted the command */
 	"Equal",	    /* C: A SEARCH DATA command found data equal */
@@ -875,20 +1102,21 @@
 /* Get sense key string or NULL if not available */
 const char *
 scsi_sense_key_string(unsigned char key) {
-#if (CONSTANTS & CONST_SENSE)
+#ifdef CONFIG_SCSI_CONSTANTS
 	if (key <= 0xE)
 		return snstext[key];
 #endif
 	return NULL;
 }
+EXPORT_SYMBOL(scsi_sense_key_string);
 
 /*
- * Get extended sense key string or NULL if not available.
- * This string may contain a %x and must be printed with ascq as arg.
+ * Get additional sense code string or NULL if not available.
+ * This string may contain a "%x" and should be printed with ascq as arg.
  */
 const char *
 scsi_extd_sense_format(unsigned char asc, unsigned char ascq) {
-#if (CONSTANTS & CONST_XSENSE)
+#ifdef CONFIG_SCSI_CONSTANTS
 	int i;
 	unsigned short code = ((asc << 8) | ascq);
 
@@ -903,131 +1131,149 @@
 #endif
 	return NULL;
 }
+EXPORT_SYMBOL(scsi_extd_sense_format);
 
-/* Print extended sense information */
+/* Print extended sense information; no leadin, no linefeed */
 static void
-scsi_show_extd_sense(unsigned char asc, unsigned char ascq) {
+scsi_show_extd_sense(unsigned char asc, unsigned char ascq)
+{
 	const char *extd_sense_fmt = scsi_extd_sense_format(asc, ascq);
 
 	if (extd_sense_fmt) {
-		printk("Additional sense: ");
-		printk(extd_sense_fmt, ascq);
-		printk("\n");
+		if (strstr(extd_sense_fmt, "%x")) {
+			printk("Additional sense: ");
+			printk(extd_sense_fmt, ascq);
+		} else
+			printk("Additional sense: %s", extd_sense_fmt);
 	} else {
-		printk("ASC=%2x ASCQ=%2x\n", asc, ascq);
+		if (asc >= 0x80)
+			printk("<<vendor>> ASC=0x%x ASCQ=0x%x", asc, ascq);
+		if (ascq >= 0x80)
+			printk("ASC=0x%x <<vendor>> ASCQ=0x%x", asc, ascq);
+		else
+			printk("ASC=0x%x ASCQ=0x%x", asc, ascq);
 	}
 }
 
 /* Print sense information */
-static void
-print_sense_internal(const char *devclass, 
-		     const unsigned char *sense_buffer,
-		     struct request *req)
+void
+__scsi_print_sense(const char *name, const unsigned char *sense_buffer,
+		   int sense_len)
 {
-	int s, sense_class, valid, code, info;
-	const char *error = NULL;
-	unsigned char asc, ascq;
+	int k, num, res;
+	unsigned int info;
+	const char *error;
 	const char *sense_txt;
-	const char *name = req->rq_disk ? req->rq_disk->disk_name : devclass;
-    
-	sense_class = (sense_buffer[0] >> 4) & 0x07;
-	code = sense_buffer[0] & 0xf;
-	valid = sense_buffer[0] & 0x80;
+	struct scsi_sense_hdr ssh;
     
-	if (sense_class == 7) {	/* extended sense data */
-		s = sense_buffer[7] + 8;
-		if (s > SCSI_SENSE_BUFFERSIZE)
-			s = SCSI_SENSE_BUFFERSIZE;
-	
-		info = ((sense_buffer[3] << 24) | (sense_buffer[4] << 16) |
-			(sense_buffer[5] << 8) | sense_buffer[6]);
-		if (info || valid) {
-			printk("Info fld=0x%x", info);
-			if (!valid)	/* info data not according to standard */
-				printk(" (nonstd)");
-			printk(", ");
-		}
-		if (sense_buffer[2] & 0x80)
-			printk( "FMK ");	/* current command has read a filemark */
-		if (sense_buffer[2] & 0x40)
-			printk( "EOM ");	/* end-of-medium condition exists */
-		if (sense_buffer[2] & 0x20)
-			printk( "ILI ");	/* incorrect block length requested */
-	
-		switch (code) {
-		case 0x0:
-			error = "Current";	/* error concerns current command */
-			break;
-		case 0x1:
-			error = "Deferred";	/* error concerns some earlier command */
-			/* e.g., an earlier write to disk cache succeeded, but
-			   now the disk discovers that it cannot write the data */
-			break;
-		default:
-			error = "Invalid";
+	res = scsi_normalize_sense(sense_buffer, sense_len, &ssh);
+	if (0 == res) {
+		/* this may be SCSI-1 sense data */
+		num = (sense_len < 32) ? sense_len : 32;
+		printk(KERN_INFO "Unrecognized sense data (in hex):");
+		for (k = 0; k < num; ++k) {
+			if (0 == (k % 16)) {
+				printk("\n");
+				printk(KERN_INFO "        ");
+			}
+			printk("%02x ", sense_buffer[k]);
 		}
+		printk("\n");
+		return;
+	}
 
-		printk("%s ", error);
+	/* An example of deferred is when an earlier write to disk cache
+	 * succeeded, but now the disk discovers that it cannot write the
+	 * data to the magnetic media.
+	 */
+	error = scsi_sense_is_deferred(&ssh) ? 
+			"<<DEFERRED>>" : "Current";
+	printk(KERN_INFO "%s: %s", name, error);
+	if (ssh.response_code >= 0x72)
+		printk(" [descriptor]");
+
+	sense_txt = scsi_sense_key_string(ssh.sense_key);
+	if (sense_txt)
+		printk(": sense key: %s\n", sense_txt);
+	else
+		printk(": sense key=0x%x\n", ssh.sense_key);
+	printk(KERN_INFO "    ");
+	scsi_show_extd_sense(ssh.asc, ssh.ascq);
+	printk("\n");
 
-		sense_txt = scsi_sense_key_string(sense_buffer[2]);
-		if (sense_txt)
-			printk("%s: sense key %s\n", name, sense_txt);
-		else
-			printk("%s: sense = %2x %2x\n", name,
-			       sense_buffer[0], sense_buffer[2]);
+	if (ssh.response_code < 0x72) {
+		/* only decode extras for "fixed" format now */
+		char buff[80];
+		int blen, fixed_valid;
 
-		asc = ascq = 0;
-		if (sense_buffer[7] + 7 >= 13) {
-			asc = sense_buffer[12];
-			ascq = sense_buffer[13];
+		fixed_valid = sense_buffer[0] & 0x80;
+		info = ((sense_buffer[3] << 24) | (sense_buffer[4] << 16) |
+			(sense_buffer[5] << 8) | sense_buffer[6]);
+		res = 0;
+		memset(buff, 0, sizeof(buff));
+		blen = sizeof(buff) - 1;
+		if (fixed_valid)
+			res += snprintf(buff + res, blen - res,
+					"Info fld=0x%x", info);
+		if (sense_buffer[2] & 0x80) {
+			/* current command has read a filemark */
+			if (res > 0)
+				res += snprintf(buff + res, blen - res, ", ");
+			res += snprintf(buff + res, blen - res, "FMK");
 		}
-		if (asc || ascq)
-			scsi_show_extd_sense(asc, ascq);
-
-	} else {	/* non-extended sense data */
-
-		/*
-		 * Standard says:
-		 *    sense_buffer[0] & 0200 : address valid
-		 *    sense_buffer[0] & 0177 : vendor-specific error code
-		 *    sense_buffer[1] & 0340 : vendor-specific
-		 *    sense_buffer[1..3] : 21-bit logical block address
-		 */
-
-		sense_txt = scsi_sense_key_string(sense_buffer[0]);
-		if (sense_txt)
-			printk("%s: old sense key %s\n", name, sense_txt);
-		else
-			printk("%s: sense = %2x %2x\n", name,
-			       sense_buffer[0], sense_buffer[2]);
-
-		printk("Non-extended sense class %d code 0x%0x\n",
-		       sense_class, code);
-		s = 4;
-	}
-    
-#if !(CONSTANTS & CONST_SENSE)
-	{
-		int i;
-	printk("Raw sense data:");
-	for (i = 0; i < s; ++i) 
-		printk("0x%02x ", sense_buffer[i]);
-	printk("\n");
+		if (sense_buffer[2] & 0x40) {
+			/* end-of-medium condition exists */
+			if (res > 0)
+				res += snprintf(buff + res, blen - res, ", ");
+			res += snprintf(buff + res, blen - res, "EOM");
+		}
+		if (sense_buffer[2] & 0x20) {
+			/* incorrect block length requested */
+			if (res > 0)
+				res += snprintf(buff + res, blen - res, ", ");
+			res += snprintf(buff + res, blen - res, "ILI");
+		}
+		if (res > 0)
+			printk(KERN_INFO "%s\n", buff);
+	} else if (ssh.additional_length > 0) {
+		/* descriptor format with sense descriptors */
+		num = 8 + ssh.additional_length;
+		num = (sense_len < num) ? sense_len : num;
+		printk(KERN_INFO "Descriptor sense data with sense "
+		       "descriptors (in hex):");
+		for (k = 0; k < num; ++k) {
+			if (0 == (k % 16)) {
+				printk("\n");
+				printk(KERN_INFO "        ");
+			}
+			printk("%02x ", sense_buffer[k]);
+		}
+		printk("\n");
 	}
-#endif
 }
+EXPORT_SYMBOL(__scsi_print_sense);
 
 void scsi_print_sense(const char *devclass, struct scsi_cmnd *cmd)
 {
-	print_sense_internal(devclass, cmd->sense_buffer, cmd->request);
+	const char *name = devclass;
+
+	if (cmd->request->rq_disk)
+		name = cmd->request->rq_disk->disk_name;
+	__scsi_print_sense(name, cmd->sense_buffer, SCSI_SENSE_BUFFERSIZE);
 }
+EXPORT_SYMBOL(scsi_print_sense);
 
 void scsi_print_req_sense(const char *devclass, struct scsi_request *sreq)
 {
-	print_sense_internal(devclass, sreq->sr_sense_buffer, sreq->sr_request);
+	const char *name = devclass;
+
+	if (sreq->sr_request->rq_disk)
+		name = sreq->sr_request->rq_disk->disk_name;
+	__scsi_print_sense(name, sreq->sr_sense_buffer, SCSI_SENSE_BUFFERSIZE);
 }
+EXPORT_SYMBOL(scsi_print_req_sense);
 
-#if (CONSTANTS & CONST_MSG) 
+#ifdef CONFIG_SCSI_CONSTANTS
 static const char *one_byte_msgs[] = {
 /* 0x00 */ "Command Complete", NULL, "Save Pointers",
 /* 0x03 */ "Restore Pointers", "Disconnect", "Initiator Error", 
@@ -1036,161 +1282,167 @@
 /* 0x0c */ "Bus device reset", "Abort Tag", "Clear Queue", 
 /* 0x0f */ "Initiate Recovery", "Release Recovery"
 };
-
 #define NO_ONE_BYTE_MSGS (sizeof(one_byte_msgs)  / sizeof (const char *))
 
 static const char *two_byte_msgs[] = {
 /* 0x20 */ "Simple Queue Tag", "Head of Queue Tag", "Ordered Queue Tag"
 /* 0x23 */ "Ignore Wide Residue"
 };
-
 #define NO_TWO_BYTE_MSGS (sizeof(two_byte_msgs)  / sizeof (const char *))
 
 static const char *extended_msgs[] = {
 /* 0x00 */ "Modify Data Pointer", "Synchronous Data Transfer Request",
 /* 0x02 */ "SCSI-I Extended Identify", "Wide Data Transfer Request"
 };
-
 #define NO_EXTENDED_MSGS (sizeof(two_byte_msgs)  / sizeof (const char *))
-#endif /* (CONSTANTS & CONST_MSG) */
 
-int scsi_print_msg (const unsigned char *msg) {
-    int len = 0, i;
-    if (msg[0] == EXTENDED_MESSAGE) {
-	len = 3 + msg[1];
-#if (CONSTANTS & CONST_MSG)
-	if (msg[2] < NO_EXTENDED_MSGS)
-	    printk ("%s ", extended_msgs[msg[2]]); 
-	else 
-	    printk ("Extended Message, reserved code (0x%02x) ", (int) msg[2]);
-	switch (msg[2]) {
-	case EXTENDED_MODIFY_DATA_POINTER:
-	    printk("pointer = %d", (int) (msg[3] << 24) | (msg[4] << 16) | 
-		   (msg[5] << 8) | msg[6]);
-	    break;
-	case EXTENDED_SDTR:
-	    printk("period = %d ns, offset = %d", (int) msg[3] * 4, (int) 
-		   msg[4]);
-	    break;
-	case EXTENDED_WDTR:
-	    printk("width = 2^%d bytes", msg[3]);
-	    break;
-	default:
-	    for (i = 2; i < len; ++i) 
-		printk("%02x ", msg[i]);
-	}
-#else
-	for (i = 0; i < len; ++i)
-	    printk("%02x ", msg[i]);
-#endif
+
+int scsi_print_msg (const unsigned char *msg)
+{
+	int len = 0, i;
+	if (msg[0] == EXTENDED_MESSAGE) {
+		len = 3 + msg[1];
+		if (msg[2] < NO_EXTENDED_MSGS)
+			printk ("%s ", extended_msgs[msg[2]]); 
+		else 
+			printk ("Extended Message, reserved code (0x%02x) ",
+				(int) msg[2]);
+		switch (msg[2]) {
+		case EXTENDED_MODIFY_DATA_POINTER:
+			printk("pointer = %d", (int) (msg[3] << 24) |
+				(msg[4] << 16) | (msg[5] << 8) | msg[6]);
+			break;
+		case EXTENDED_SDTR:
+			printk("period = %d ns, offset = %d",
+				(int) msg[3] * 4, (int) msg[4]);
+			break;
+		case EXTENDED_WDTR:
+			printk("width = 2^%d bytes", msg[3]);
+			break;
+		default:
+		for (i = 2; i < len; ++i) 
+			printk("%02x ", msg[i]);
+		}
 	/* Identify */
-    } else if (msg[0] & 0x80) {
-#if (CONSTANTS & CONST_MSG)
-	printk("Identify disconnect %sallowed %s %d ",
-	       (msg[0] & 0x40) ? "" : "not ",
-	       (msg[0] & 0x20) ? "target routine" : "lun",
-	       msg[0] & 0x7);
-#else
-	printk("%02x ", msg[0]);
-#endif
-	len = 1;
+	} else if (msg[0] & 0x80) {
+		printk("Identify disconnect %sallowed %s %d ",
+			(msg[0] & 0x40) ? "" : "not ",
+			(msg[0] & 0x20) ? "target routine" : "lun",
+			msg[0] & 0x7);
+		len = 1;
 	/* Normal One byte */
-    } else if (msg[0] < 0x1f) {
-#if (CONSTANTS & CONST_MSG)
-	if (msg[0] < NO_ONE_BYTE_MSGS)
-	    printk(one_byte_msgs[msg[0]]);
-	else
-	    printk("reserved (%02x) ", msg[0]);
-#else
-	printk("%02x ", msg[0]);
-#endif
-	len = 1;
+	} else if (msg[0] < 0x1f) {
+		if (msg[0] < NO_ONE_BYTE_MSGS)
+			printk(one_byte_msgs[msg[0]]);
+		else
+			printk("reserved (%02x) ", msg[0]);
+		len = 1;
 	/* Two byte */
-    } else if (msg[0] <= 0x2f) {
-#if (CONSTANTS & CONST_MSG)
-	if ((msg[0] - 0x20) < NO_TWO_BYTE_MSGS)
-	    printk("%s %02x ", two_byte_msgs[msg[0] - 0x20], 
-		   msg[1]);
-	else 
-	    printk("reserved two byte (%02x %02x) ", 
-		   msg[0], msg[1]);
-#else
-	printk("%02x %02x", msg[0], msg[1]);
-#endif
-	len = 2;
-    } else 
-#if (CONSTANTS & CONST_MSG)
-	printk(reserved);
-#else
-    printk("%02x ", msg[0]);
-#endif
-    return len;
+	} else if (msg[0] <= 0x2f) {
+		if ((msg[0] - 0x20) < NO_TWO_BYTE_MSGS)
+			printk("%s %02x ", two_byte_msgs[msg[0] - 0x20], 
+				msg[1]);
+		else 
+			printk("reserved two byte (%02x %02x) ", 
+				msg[0], msg[1]);
+		len = 2;
+	} else 
+		printk("reserved");
+	return len;
+}
+EXPORT_SYMBOL(scsi_print_msg);
+
+#else  /* ifndef CONFIG_SCSI_CONSTANTS */
+
+int scsi_print_msg (const unsigned char *msg)
+{
+	int len = 0, i;
+
+	if (msg[0] == EXTENDED_MESSAGE) {
+		len = 3 + msg[1];
+		for (i = 0; i < len; ++i)
+			printk("%02x ", msg[i]);
+	/* Identify */
+	} else if (msg[0] & 0x80) {
+		printk("%02x ", msg[0]);
+		len = 1;
+	/* Normal One byte */
+	} else if (msg[0] < 0x1f) {
+		printk("%02x ", msg[0]);
+		len = 1;
+	/* Two byte */
+	} else if (msg[0] <= 0x2f) {
+		printk("%02x %02x", msg[0], msg[1]);
+		len = 2;
+	} else 
+		printk("%02x ", msg[0]);
+	return len;
 }
+EXPORT_SYMBOL(scsi_print_msg);
+#endif /* ! CONFIG_SCSI_CONSTANTS */
 
-void scsi_print_command(struct scsi_cmnd *cmd) {
-    printk("scsi%d : destination target %d, lun %d\n", 
-	   cmd->device->host->host_no, 
-	   cmd->device->id, 
-	   cmd->device->lun);
-    printk("        command = ");
-    __scsi_print_command(cmd->cmnd);
+void scsi_print_command(struct scsi_cmnd *cmd)
+{
+	/* Assume appended output (i.e. not at start of line) */
+	printk("scsi%d : destination target %d, lun %d\n", 
+		cmd->device->host->host_no, 
+		cmd->device->id, 
+		cmd->device->lun);
+	printk(KERN_INFO "        command: ");
+	scsi_print_cdb(cmd->cmnd, cmd->cmd_len, 0);
 }
+EXPORT_SYMBOL(scsi_print_command);
+
+#ifdef CONFIG_SCSI_CONSTANTS
 
-#if (CONSTANTS & CONST_HOST)
 static const char * hostbyte_table[]={
 "DID_OK", "DID_NO_CONNECT", "DID_BUS_BUSY", "DID_TIME_OUT", "DID_BAD_TARGET", 
 "DID_ABORT", "DID_PARITY", "DID_ERROR", "DID_RESET", "DID_BAD_INTR",
-"DID_PASSTHROUGH", "DID_SOFT_ERROR", "DID_IMM_RETRY", NULL};
+"DID_PASSTHROUGH", "DID_SOFT_ERROR", "DID_IMM_RETRY"};
+#define NUM_HOSTBYTE_STRS (sizeof(hostbyte_table) / sizeof(const char *))
 
 void scsi_print_hostbyte(int scsiresult)
-{   static int maxcode=0;
-    int i;
-   
-    if(!maxcode) {
-	for(i=0;hostbyte_table[i];i++) ;
-	maxcode=i-1;
-    }
-    printk("Hostbyte=0x%02x",host_byte(scsiresult));
-    if(host_byte(scsiresult)>maxcode) {
-	printk("is invalid "); 
-	return;
-    }
-    printk("(%s) ",hostbyte_table[host_byte(scsiresult)]);
+{
+	int hb = host_byte(scsiresult);
+
+	printk("Hostbyte=0x%02x", hb);
+	if (hb < NUM_HOSTBYTE_STRS)
+		printk("(%s) ", hostbyte_table[hb]);
+	else
+		printk("is invalid "); 
 }
 #else
 void scsi_print_hostbyte(int scsiresult)
-{   printk("Hostbyte=0x%02x ",host_byte(scsiresult));
+{
+	printk("Hostbyte=0x%02x ", host_byte(scsiresult));
 }
 #endif
 
-#if (CONSTANTS & CONST_DRIVER)
+#ifdef CONFIG_SCSI_CONSTANTS
+
 static const char * driverbyte_table[]={
 "DRIVER_OK", "DRIVER_BUSY", "DRIVER_SOFT",  "DRIVER_MEDIA", "DRIVER_ERROR", 
-"DRIVER_INVALID", "DRIVER_TIMEOUT", "DRIVER_HARD",NULL };
+"DRIVER_INVALID", "DRIVER_TIMEOUT", "DRIVER_HARD", "DRIVER_SENSE"};
+#define NUM_DRIVERBYTE_STRS (sizeof(driverbyte_table) / sizeof(const char *))
 
 static const char * driversuggest_table[]={"SUGGEST_OK",
 "SUGGEST_RETRY", "SUGGEST_ABORT", "SUGGEST_REMAP", "SUGGEST_DIE",
-unknown,unknown,unknown, "SUGGEST_SENSE",NULL};
-
+"SUGGEST_5", "SUGGEST_6", "SUGGEST_7", "SUGGEST_SENSE"};
+#define NUM_SUGGEST_STRS (sizeof(driversuggest_table) / sizeof(const char *))
 
 void scsi_print_driverbyte(int scsiresult)
-{   static int driver_max=0,suggest_max=0;
-    int i,dr=driver_byte(scsiresult)&DRIVER_MASK, 
-	su=(driver_byte(scsiresult)&SUGGEST_MASK)>>4;
-
-    if(!driver_max) {
-        for(i=0;driverbyte_table[i];i++) ;
-        driver_max=i;
-	for(i=0;driversuggest_table[i];i++) ;
-	suggest_max=i;
-    }
-    printk("Driverbyte=0x%02x",driver_byte(scsiresult));
-    printk("(%s,%s) ",
-	dr<driver_max  ? driverbyte_table[dr]:"invalid",
-	su<suggest_max ? driversuggest_table[su]:"invalid");
+{
+	int dr = (driver_byte(scsiresult) & DRIVER_MASK);
+	int su = ((driver_byte(scsiresult) & SUGGEST_MASK) >> 4);
+
+	printk("Driverbyte=0x%02x ", driver_byte(scsiresult));
+	printk("(%s,%s) ",
+	       (dr < NUM_DRIVERBYTE_STRS ? driverbyte_table[dr] : "invalid"),
+	       (su < NUM_SUGGEST_STRS ? driversuggest_table[su] : "invalid"));
 }
 #else
 void scsi_print_driverbyte(int scsiresult)
-{   printk("Driverbyte=0x%02x ",driver_byte(scsiresult));
+{
+	printk("Driverbyte=0x%02x ", driver_byte(scsiresult));
 }
 #endif
diff -Nru a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c
--- a/drivers/scsi/dc395x.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/scsi/dc395x.c	2005-03-01 23:38:52 -08:00
@@ -488,7 +488,7 @@
 	int def;		/* default value */
 	int safe;		/* safe value */
 };
-static struct ParameterData __initdata cfg_data[] = {
+static struct ParameterData __devinitdata cfg_data[] = {
 	{ /* adapter id */
 		CFG_PARAM_UNSET,
 		0,
@@ -573,7 +573,7 @@
  * set_safe_settings - if the use_safe_settings option is set then
  * set all values to the safe and slow values.
  **/
-static void __init set_safe_settings(void)
+static void __devinit set_safe_settings(void)
 {
 	if (use_safe_settings)
 	{
@@ -592,7 +592,7 @@
  * fix_settings - reset any boot parameters which are out of range
  * back to the default values.
  **/
-static void __init fix_settings(void)
+static void __devinit fix_settings(void)
 {
 	int i;
 
@@ -619,7 +619,7 @@
  * Mapping from the eeprom delay index value (index into this array)
  * to the the number of actual seconds that the delay should be for.
  */
-static char __initdata eeprom_index_to_delay_map[] = 
+static char __devinitdata eeprom_index_to_delay_map[] = 
 	{ 1, 3, 5, 10, 16, 30, 60, 120 };
 
 
@@ -629,7 +629,7 @@
  *
  * @eeprom: The eeprom structure in which we find the delay index to map.
  **/
-static void __init eeprom_index_to_delay(struct NvRamType *eeprom)
+static void __devinit eeprom_index_to_delay(struct NvRamType *eeprom)
 {
 	eeprom->delay_time = eeprom_index_to_delay_map[eeprom->delay_time];
 }
@@ -642,7 +642,7 @@
  *
  * @delay: The delay, in seconds, to find the eeprom index for.
  **/
-static int __init delay_to_eeprom_index(int delay)
+static int __devinit delay_to_eeprom_index(int delay)
 {
 	u8 idx = 0;
 	while (idx < 7 && eeprom_index_to_delay_map[idx] < delay)
@@ -658,7 +658,7 @@
  *
  * @eeprom: The eeprom data to override with command line options.
  **/
-static void __init eeprom_override(struct NvRamType *eeprom)
+static void __devinit eeprom_override(struct NvRamType *eeprom)
 {
 	u8 id;
 
@@ -3931,7 +3931,7 @@
  *
  * @io_port: base I/O address
  **/
-static void __init trms1040_wait_30us(unsigned long io_port)
+static void __devinit trms1040_wait_30us(unsigned long io_port)
 {
 	/* ScsiPortStallExecution(30); wait 30 us */
 	outb(5, io_port + TRM_S1040_GEN_TIMER);
@@ -3948,7 +3948,7 @@
  * @cmd:	SB + op code (command) to send
  * @addr:	address to send
  **/
-static void __init trms1040_write_cmd(unsigned long io_port, u8 cmd, u8 addr)
+static void __devinit trms1040_write_cmd(unsigned long io_port, u8 cmd, u8 addr)
 {
 	int i;
 	u8 send_data;
@@ -3993,7 +3993,7 @@
  * @addr:	offset into EEPROM
  * @byte:	bytes to write
  **/
-static void __init trms1040_set_data(unsigned long io_port, u8 addr, u8 byte)
+static void __devinit trms1040_set_data(unsigned long io_port, u8 addr, u8 byte)
 {
 	int i;
 	u8 send_data;
@@ -4047,7 +4047,7 @@
  * @eeprom:	the data to write
  * @io_port:	the base io port
  **/
-static void __init trms1040_write_all(struct NvRamType *eeprom, unsigned long io_port)
+static void __devinit trms1040_write_all(struct NvRamType *eeprom, unsigned long io_port)
 {
 	u8 *b_eeprom = (u8 *)eeprom;
 	u8 addr;
@@ -4087,7 +4087,7 @@
  *
  * Returns the the byte read.
  **/
-static u8 __init trms1040_get_data(unsigned long io_port, u8 addr)
+static u8 __devinit trms1040_get_data(unsigned long io_port, u8 addr)
 {
 	int i;
 	u8 read_byte;
@@ -4125,7 +4125,7 @@
  * @eeprom:	where to store the data
  * @io_port:	the base io port
  **/
-static void __init trms1040_read_all(struct NvRamType *eeprom, unsigned long io_port)
+static void __devinit trms1040_read_all(struct NvRamType *eeprom, unsigned long io_port)
 {
 	u8 *b_eeprom = (u8 *)eeprom;
 	u8 addr;
@@ -4155,7 +4155,7 @@
  * @eeprom:	caller allocated strcuture to read the eeprom data into
  * @io_port:	io port to read from
  **/
-static void __init check_eeprom(struct NvRamType *eeprom, unsigned long io_port)
+static void __devinit check_eeprom(struct NvRamType *eeprom, unsigned long io_port)
 {
 	u16 *w_eeprom = (u16 *)eeprom;
 	u16 w_addr;
@@ -4225,7 +4225,7 @@
  *
  * @eeprom: The eeprom data strucutre to show details for.
  **/
-static void __init print_eeprom_settings(struct NvRamType *eeprom)
+static void __devinit print_eeprom_settings(struct NvRamType *eeprom)
 {
 	dprintkl(KERN_INFO, "Used settings: AdapterID=%02i, Speed=%i(%02i.%01iMHz), dev_mode=0x%02x\n",
 		eeprom->scsi_id,
@@ -4254,7 +4254,7 @@
 /*
  * Allocate SG tables; as we have to pci_map them, an SG list (struct SGentry*)
  * should never cross a page boundary */
-static int __init adapter_sg_tables_alloc(struct AdapterCtlBlk *acb)
+static int __devinit adapter_sg_tables_alloc(struct AdapterCtlBlk *acb)
 {
 	const unsigned mem_needed = (DC395x_MAX_SRB_CNT+1)
 	                            *SEGMENTX_LEN;
@@ -4300,7 +4300,7 @@
  *
  * @acb: The adapter to print the information for.
  **/
-static void __init adapter_print_config(struct AdapterCtlBlk *acb)
+static void __devinit adapter_print_config(struct AdapterCtlBlk *acb)
 {
 	u8 bval;
 
@@ -4344,7 +4344,7 @@
  *
  * @acb: The adapter to initialize.
  **/
-static void __init adapter_init_params(struct AdapterCtlBlk *acb)
+static void __devinit adapter_init_params(struct AdapterCtlBlk *acb)
 {
 	struct NvRamType *eeprom = &acb->eeprom;
 	int i;
@@ -4406,7 +4406,7 @@
  *
  * @host: The scsi host instance to fill in the values for.
  **/
-static void __init adapter_init_scsi_host(struct Scsi_Host *host)
+static void __devinit adapter_init_scsi_host(struct Scsi_Host *host)
 {
         struct AdapterCtlBlk *acb = (struct AdapterCtlBlk *)host->hostdata;
 	struct NvRamType *eeprom = &acb->eeprom;
@@ -4447,7 +4447,7 @@
  *
  * @acb: The adapter which we are to init.
  **/
-static void __init adapter_init_chip(struct AdapterCtlBlk *acb)
+static void __devinit adapter_init_chip(struct AdapterCtlBlk *acb)
 {
         struct NvRamType *eeprom = &acb->eeprom;
         
@@ -4500,7 +4500,7 @@
  * Returns 0 if the initialization succeeds, any other value on
  * failure.
  **/
-static int __init adapter_init(struct AdapterCtlBlk *acb,
+static int __devinit adapter_init(struct AdapterCtlBlk *acb,
 	unsigned long io_port, u32 io_port_len, unsigned int irq)
 {
 	if (!request_region(io_port, io_port_len, DC395X_NAME)) {
diff -Nru a/drivers/scsi/dec_esp.c b/drivers/scsi/dec_esp.c
--- a/drivers/scsi/dec_esp.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/scsi/dec_esp.c	2005-03-01 23:39:08 -08:00
@@ -17,6 +17,8 @@
  *            data.
  * 20001005	- Initialization fixes for 2.4.0-test9
  * 			  Florian Lohoff <flo@rfc822.org>
+ *
+ *	Copyright (C) 2002, 2003  Maciej W. Rozycki
  */
 
 #include <linux/kernel.h>
@@ -26,59 +28,52 @@
 #include <linux/slab.h>
 #include <linux/blkdev.h>
 #include <linux/proc_fs.h>
+#include <linux/spinlock.h>
 #include <linux/stat.h>
 
-#include "scsi.h"
-#include <scsi/scsi_host.h>
-#include "NCR53C9x.h"
-
-#include <asm/irq.h>
-#include <asm/jazz.h>
-#include <asm/jazzdma.h>
 #include <asm/dma.h>
-
+#include <asm/irq.h>
 #include <asm/pgtable.h>
+#include <asm/system.h>
 
-#include <asm/dec/tc.h>
 #include <asm/dec/interrupts.h>
+#include <asm/dec/ioasic.h>
 #include <asm/dec/ioasic_addrs.h>
 #include <asm/dec/ioasic_ints.h>
 #include <asm/dec/machtype.h>
+#include <asm/dec/tc.h>
 
 #define DEC_SCSI_SREG 0
 #define DEC_SCSI_DMAREG 0x40000
 #define DEC_SCSI_SRAM 0x80000
 #define DEC_SCSI_DIAG 0xC0000
 
-/*
- * Once upon a time the pmaz code used to be working but
- * it hasn't been maintained for quite some time.
- * It isn't working anymore but I'll leave here as a
- * starting point. #define this an be prepared for tons
- * of warnings and errors :)
- */
+#include "scsi.h"
+#include <scsi/scsi_host.h>
+#include "NCR53C9x.h"
+
 static int  dma_bytes_sent(struct NCR_ESP *esp, int fifo_count);
 static void dma_drain(struct NCR_ESP *esp);
-static int  dma_can_transfer(struct NCR_ESP *esp, Scsi_Cmnd * sp);
+static int  dma_can_transfer(struct NCR_ESP *esp, struct scsi_cmnd *sp);
 static void dma_dump_state(struct NCR_ESP *esp);
-static void dma_init_read(struct NCR_ESP *esp, __u32 vaddress, int length);
-static void dma_init_write(struct NCR_ESP *esp, __u32 vaddress, int length);
+static void dma_init_read(struct NCR_ESP *esp, u32 vaddress, int length);
+static void dma_init_write(struct NCR_ESP *esp, u32 vaddress, int length);
 static void dma_ints_off(struct NCR_ESP *esp);
 static void dma_ints_on(struct NCR_ESP *esp);
 static int  dma_irq_p(struct NCR_ESP *esp);
 static int  dma_ports_p(struct NCR_ESP *esp);
-static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write);
-static void dma_mmu_get_scsi_one(struct NCR_ESP *esp, Scsi_Cmnd * sp);
-static void dma_mmu_get_scsi_sgl(struct NCR_ESP *esp, Scsi_Cmnd * sp);
-static void dma_advance_sg(Scsi_Cmnd * sp);
+static void dma_setup(struct NCR_ESP *esp, u32 addr, int count, int write);
+static void dma_mmu_get_scsi_one(struct NCR_ESP *esp, struct scsi_cmnd * sp);
+static void dma_mmu_get_scsi_sgl(struct NCR_ESP *esp, struct scsi_cmnd * sp);
+static void dma_advance_sg(struct scsi_cmnd * sp);
 
 static void pmaz_dma_drain(struct NCR_ESP *esp);
-static void pmaz_dma_init_read(struct NCR_ESP *esp, __u32 vaddress, int length);
-static void pmaz_dma_init_write(struct NCR_ESP *esp, __u32 vaddress, int length);
+static void pmaz_dma_init_read(struct NCR_ESP *esp, u32 vaddress, int length);
+static void pmaz_dma_init_write(struct NCR_ESP *esp, u32 vaddress, int length);
 static void pmaz_dma_ints_off(struct NCR_ESP *esp);
 static void pmaz_dma_ints_on(struct NCR_ESP *esp);
-static void pmaz_dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write);
-static void pmaz_dma_mmu_get_scsi_one(struct NCR_ESP *esp, Scsi_Cmnd * sp);
+static void pmaz_dma_setup(struct NCR_ESP *esp, u32 addr, int count, int write);
+static void pmaz_dma_mmu_get_scsi_one(struct NCR_ESP *esp, struct scsi_cmnd * sp);
 
 #define TC_ESP_RAM_SIZE 0x20000
 #define ESP_TGT_DMA_SIZE ((TC_ESP_RAM_SIZE/7) & ~(sizeof(int)-1))
@@ -88,7 +83,7 @@
 #define TC_ESP_DMAR_WRITE 0x80000000
 #define TC_ESP_DMA_ADDR(x) ((unsigned)(x) & TC_ESP_DMAR_MASK)
 
-__u32 esp_virt_buffer;
+u32 esp_virt_buffer;
 int scsi_current_length;
 
 volatile unsigned char cmd_buffer[16];
@@ -98,16 +93,11 @@
 				 * via PIO.
 				 */
 
-volatile unsigned long *scsi_dma_ptr;
-volatile unsigned long *scsi_next_ptr;
-volatile unsigned long *scsi_scr;
-volatile unsigned long *ioasic_ssr;
-volatile unsigned long *scsi_sdr0;
-volatile unsigned long *scsi_sdr1;
+static irqreturn_t scsi_dma_merr_int(int, void *, struct pt_regs *);
+static irqreturn_t scsi_dma_err_int(int, void *, struct pt_regs *);
+static irqreturn_t scsi_dma_int(int, void *, struct pt_regs *);
 
-static void scsi_dma_int(int, void *, struct pt_regs *);
-
-int dec_esp_detect(Scsi_Host_Template * tpnt);
+static int dec_esp_detect(struct scsi_host_template * tpnt);
 
 static int dec_esp_release(struct Scsi_Host *shost)
 {
@@ -119,9 +109,9 @@
 	return 0;
 }
 
-static Scsi_Host_Template driver_template = {
+static struct scsi_host_template driver_template = {
 	.proc_name		= "dec_esp",
-	.proc_info		= &esp_proc_info,
+	.proc_info		= esp_proc_info,
 	.name			= "NCR53C94",
 	.detect			= dec_esp_detect,
 	.slave_alloc		= esp_slave_alloc,
@@ -142,7 +132,7 @@
 #include "scsi_module.c"
 
 /***************************************************************** Detection */
-int dec_esp_detect(Scsi_Host_Template * tpnt)
+static int dec_esp_detect(Scsi_Host_Template * tpnt)
 {
 	struct NCR_ESP *esp;
 	struct ConfigDev *esp_dev;
@@ -152,17 +142,10 @@
 	if (IOASIC) {
 		esp_dev = 0;
 		esp = esp_allocate(tpnt, (void *) esp_dev);
-	
-		scsi_dma_ptr = (unsigned long *) (system_base + IOCTL + SCSI_DMA_P);
-		scsi_next_ptr = (unsigned long *) (system_base + IOCTL + SCSI_DMA_BP);
-		scsi_scr = (unsigned long *) (system_base + IOCTL + SCSI_SCR);
-		ioasic_ssr = (unsigned long *) (system_base + IOCTL + SSR);
-		scsi_sdr0 = (unsigned long *) (system_base + IOCTL + SCSI_SDR0);
-		scsi_sdr1 = (unsigned long *) (system_base + IOCTL + SCSI_SDR1);
 
 		/* Do command transfer with programmed I/O */
 		esp->do_pio_cmds = 1;
-	
+
 		/* Required functions */
 		esp->dma_bytes_sent = &dma_bytes_sent;
 		esp->dma_can_transfer = &dma_can_transfer;
@@ -185,7 +168,7 @@
 		esp->dma_reset = 0;
 		esp->dma_led_off = 0;
 		esp->dma_led_on = 0;
-		
+
 		/* virtual DMA functions */
 		esp->dma_mmu_get_scsi_one = &dma_mmu_get_scsi_one;
 		esp->dma_mmu_get_scsi_sgl = &dma_mmu_get_scsi_sgl;
@@ -197,38 +180,42 @@
 		/* SCSI chip speed */
 		esp->cfreq = 25000000;
 
-		/*
-		 * we don't give the address of DMA channel, but the number
-		 * of DMA channel, so we can use the jazz DMA functions
-		 *
-		 */
-		esp->dregs = JAZZ_SCSI_DMA;
-	
+		esp->dregs = 0;
+
 		/* ESP register base */
-		esp->eregs = (struct ESP_regs *) (system_base + SCSI);
-	
+		esp->eregs = (struct ESP_regs *) (system_base + IOASIC_SCSI);
+
 		/* Set the command buffer */
 		esp->esp_command = (volatile unsigned char *) cmd_buffer;
-	
+
 		/* get virtual dma address for command buffer */
-		esp->esp_command_dvma = (__u32) KSEG1ADDR((volatile unsigned char *) cmd_buffer);
-	
-		esp->irq = SCSI_INT;
+		esp->esp_command_dvma = virt_to_phys(cmd_buffer);
+
+		esp->irq = dec_interrupt[DEC_IRQ_ASC];
 
 		esp->scsi_id = 7;
-		
+
 		/* Check for differential SCSI-bus */
 		esp->diff = 0;
 
 		esp_initialize(esp);
 
-		if (request_irq(esp->irq, esp_intr, SA_INTERRUPT, 
-				"NCR 53C94 SCSI", esp->ehost))
+		if (request_irq(esp->irq, esp_intr, SA_INTERRUPT,
+				"ncr53c94", esp->ehost))
 			goto err_dealloc;
-		if (request_irq(SCSI_DMA_INT, scsi_dma_int, SA_INTERRUPT, 
-				"JUNKIO SCSI DMA", esp->ehost))
+		if (request_irq(dec_interrupt[DEC_IRQ_ASC_MERR],
+				scsi_dma_merr_int, SA_INTERRUPT,
+				"ncr53c94 error", esp->ehost))
 			goto err_free_irq;
- 			
+		if (request_irq(dec_interrupt[DEC_IRQ_ASC_ERR],
+				scsi_dma_err_int, SA_INTERRUPT,
+				"ncr53c94 overrun", esp->ehost))
+			goto err_free_irq_merr;
+		if (request_irq(dec_interrupt[DEC_IRQ_ASC_DMA],
+				scsi_dma_int, SA_INTERRUPT,
+				"ncr53c94 dma", esp->ehost))
+			goto err_free_irq_err;
+
 	}
 
 	if (TURBOCHANNEL) {
@@ -241,7 +228,7 @@
 			mem_start = get_tc_base_addr(slot);
 
 			/* Store base addr into esp struct */
-			esp->slot = mem_start;
+			esp->slot = PHYSADDR(mem_start);
 
 			esp->dregs = 0;
 			esp->eregs = (struct ESP_regs *) (mem_start + DEC_SCSI_SREG);
@@ -251,7 +238,7 @@
 			esp->esp_command = (volatile unsigned char *) pmaz_cmd_buffer;
 
 			/* get virtual dma address for command buffer */
-			esp->esp_command_dvma = (__u32) KSEG0ADDR((volatile unsigned char *) pmaz_cmd_buffer);
+			esp->esp_command_dvma = virt_to_phys(pmaz_cmd_buffer);
 
 			esp->cfreq = get_tc_speed();
 
@@ -286,7 +273,7 @@
 			esp->dma_mmu_release_scsi_sgl = 0;
 			esp->dma_advance_sg = 0;
 
- 			if (request_irq(esp->irq, esp_intr, SA_INTERRUPT, 
+ 			if (request_irq(esp->irq, esp_intr, SA_INTERRUPT,
  					 "PMAZ_AA", esp->ehost)) {
  				esp_deallocate(esp);
  				release_tc_card(slot);
@@ -305,231 +292,259 @@
 	}
 	return 0;
 
- err_free_irq:
+err_free_irq_err:
+	free_irq(dec_interrupt[DEC_IRQ_ASC_ERR], scsi_dma_err_int);
+err_free_irq_merr:
+	free_irq(dec_interrupt[DEC_IRQ_ASC_MERR], scsi_dma_merr_int);
+err_free_irq:
 	free_irq(esp->irq, esp_intr);
- err_dealloc:
+err_dealloc:
 	esp_deallocate(esp);
 	return 0;
 }
 
 /************************************************************* DMA Functions */
-static void scsi_dma_int(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t scsi_dma_merr_int(int irq, void *dev_id, struct pt_regs *regs)
 {
-	extern volatile unsigned int *isr;
-	unsigned int dummy;
+	printk("Got unexpected SCSI DMA Interrupt! < ");
+	printk("SCSI_DMA_MEMRDERR ");
+	printk(">\n");
 
-	if (*isr & SCSI_PTR_LOADED) {
-		/* next page */
-		*scsi_next_ptr = ((*scsi_dma_ptr + PAGE_SIZE) & PAGE_MASK) << 3;
-		*isr &= ~SCSI_PTR_LOADED;
-	} else {
-		if (*isr & SCSI_PAGOVRRUN)
-			*isr &= ~SCSI_PAGOVRRUN;
-		if (*isr & SCSI_DMA_MEMRDERR) {
-			printk("Got unexpected SCSI DMA Interrupt! < ");
-			printk("SCSI_DMA_MEMRDERR ");
-		printk(">\n");
-			*isr &= ~SCSI_DMA_MEMRDERR;
-		}
-	}
+	return IRQ_HANDLED;
+}
 
-	/*
-	 * This routine will only work on IOASIC machines
-	 * so we can avoid an indirect function call here
-	 * and flush the writeback buffer the fast way
-	 */
-	dummy = *isr;
-	dummy = *isr;
+static irqreturn_t scsi_dma_err_int(int irq, void *dev_id, struct pt_regs *regs)
+{
+	/* empty */
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t scsi_dma_int(int irq, void *dev_id, struct pt_regs *regs)
+{
+	u32 scsi_next_ptr;
+
+	scsi_next_ptr = ioasic_read(IO_REG_SCSI_DMA_P);
+
+	/* next page */
+	scsi_next_ptr = (((scsi_next_ptr >> 3) + PAGE_SIZE) & PAGE_MASK) << 3;
+	ioasic_write(IO_REG_SCSI_DMA_BP, scsi_next_ptr);
+	fast_iob();
+
+	return IRQ_HANDLED;
 }
 
 static int dma_bytes_sent(struct NCR_ESP *esp, int fifo_count)
 {
-    return fifo_count;
+	return fifo_count;
 }
 
 static void dma_drain(struct NCR_ESP *esp)
 {
-	unsigned long nw = *scsi_scr;
-	unsigned short *p = (unsigned short *)KSEG1ADDR((*scsi_dma_ptr) >> 3);
+	u32 nw, data0, data1, scsi_data_ptr;
+	u16 *p;
+
+	nw = ioasic_read(IO_REG_SCSI_SCR);
 
-    /*
+	/*
 	 * Is there something in the dma buffers left?
-     */
+	 */
 	if (nw) {
+		scsi_data_ptr = ioasic_read(IO_REG_SCSI_DMA_P) >> 3;
+		p = phys_to_virt(scsi_data_ptr);
 		switch (nw) {
 		case 1:
-			*p = (unsigned short) *scsi_sdr0;
+			data0 = ioasic_read(IO_REG_SCSI_SDR0);
+			p[0] = data0 & 0xffff;
 			break;
 		case 2:
-			*p++ = (unsigned short) (*scsi_sdr0);
-			*p = (unsigned short) ((*scsi_sdr0) >> 16);
+			data0 = ioasic_read(IO_REG_SCSI_SDR0);
+			p[0] = data0 & 0xffff;
+			p[1] = (data0 >> 16) & 0xffff;
 			break;
 		case 3:
-			*p++ = (unsigned short) (*scsi_sdr0);
-			*p++ = (unsigned short) ((*scsi_sdr0) >> 16);
-			*p = (unsigned short) (*scsi_sdr1);
+			data0 = ioasic_read(IO_REG_SCSI_SDR0);
+			data1 = ioasic_read(IO_REG_SCSI_SDR1);
+			p[0] = data0 & 0xffff;
+			p[1] = (data0 >> 16) & 0xffff;
+			p[2] = data1 & 0xffff;
 			break;
 		default:
-			printk("Strange: %d words in dma buffer left\n", (int) nw);
+			printk("Strange: %d words in dma buffer left\n", nw);
 			break;
 		}
 	}
 }
 
-static int dma_can_transfer(struct NCR_ESP *esp, Scsi_Cmnd * sp)
+static int dma_can_transfer(struct NCR_ESP *esp, struct scsi_cmnd * sp)
 {
 	return sp->SCp.this_residual;
 }
 
 static void dma_dump_state(struct NCR_ESP *esp)
 {
-/*
-    ESPLOG(("esp%d: dma -- enable <%08x> residue <%08x\n",
-	    esp->esp_id, vdma_get_enable((int)esp->dregs), vdma_get_resdiue((int)esp->dregs)));
- */
 }
 
-static void dma_init_read(struct NCR_ESP *esp, __u32 vaddress, int length)
+static void dma_init_read(struct NCR_ESP *esp, u32 vaddress, int length)
 {
-	extern volatile unsigned int *isr;
-	unsigned int dummy;
+	u32 scsi_next_ptr, ioasic_ssr;
+	unsigned long flags;
 
 	if (vaddress & 3)
-		panic("dec_efs.c: unable to handle partial word transfers, yet...");
+		panic("dec_esp.c: unable to handle partial word transfers, yet...");
 
 	dma_cache_wback_inv((unsigned long) phys_to_virt(vaddress), length);
 
-	*ioasic_ssr &= ~SCSI_DMA_EN;
-	*scsi_scr = 0;
-	*scsi_dma_ptr = vaddress << 3;
+	spin_lock_irqsave(&ioasic_ssr_lock, flags);
+
+	fast_mb();
+	ioasic_ssr = ioasic_read(IO_REG_SSR);
+
+	ioasic_ssr &= ~IO_SSR_SCSI_DMA_EN;
+	ioasic_write(IO_REG_SSR, ioasic_ssr);
+
+	fast_wmb();
+	ioasic_write(IO_REG_SCSI_SCR, 0);
+	ioasic_write(IO_REG_SCSI_DMA_P, vaddress << 3);
 
 	/* prepare for next page */
-	*scsi_next_ptr = ((vaddress + PAGE_SIZE) & PAGE_MASK) << 3;
-	*ioasic_ssr |= (SCSI_DMA_DIR | SCSI_DMA_EN);
+	scsi_next_ptr = ((vaddress + PAGE_SIZE) & PAGE_MASK) << 3;
+	ioasic_write(IO_REG_SCSI_DMA_BP, scsi_next_ptr);
 
-	/*
-	 * see above
-	 */
-	dummy = *isr;
-	dummy = *isr;
+	ioasic_ssr |= (IO_SSR_SCSI_DMA_DIR | IO_SSR_SCSI_DMA_EN);
+	fast_wmb();
+	ioasic_write(IO_REG_SSR, ioasic_ssr);
+
+	fast_iob();
+	spin_unlock_irqrestore(&ioasic_ssr_lock, flags);
 }
 
-static void dma_init_write(struct NCR_ESP *esp, __u32 vaddress, int length)
+static void dma_init_write(struct NCR_ESP *esp, u32 vaddress, int length)
 {
-	extern volatile unsigned int *isr;
-	unsigned int dummy;
+	u32 scsi_next_ptr, ioasic_ssr;
+	unsigned long flags;
 
 	if (vaddress & 3)
-		panic("dec_efs.c: unable to handle partial word transfers, yet...");
+		panic("dec_esp.c: unable to handle partial word transfers, yet...");
 
 	dma_cache_wback_inv((unsigned long) phys_to_virt(vaddress), length);
 
-	*ioasic_ssr &= ~(SCSI_DMA_DIR | SCSI_DMA_EN);
-	*scsi_scr = 0;
-	*scsi_dma_ptr = vaddress << 3;
+	spin_lock_irqsave(&ioasic_ssr_lock, flags);
+
+	fast_mb();
+	ioasic_ssr = ioasic_read(IO_REG_SSR);
+
+	ioasic_ssr &= ~(IO_SSR_SCSI_DMA_DIR | IO_SSR_SCSI_DMA_EN);
+	ioasic_write(IO_REG_SSR, ioasic_ssr);
+
+	fast_wmb();
+	ioasic_write(IO_REG_SCSI_SCR, 0);
+	ioasic_write(IO_REG_SCSI_DMA_P, vaddress << 3);
 
 	/* prepare for next page */
-	*scsi_next_ptr = ((vaddress + PAGE_SIZE) & PAGE_MASK) << 3;
-	*ioasic_ssr |= SCSI_DMA_EN;
+	scsi_next_ptr = ((vaddress + PAGE_SIZE) & PAGE_MASK) << 3;
+	ioasic_write(IO_REG_SCSI_DMA_BP, scsi_next_ptr);
 
-	/*
-	 * see above
-	 */
-	dummy = *isr;
-	dummy = *isr;
+	ioasic_ssr |= IO_SSR_SCSI_DMA_EN;
+	fast_wmb();
+	ioasic_write(IO_REG_SSR, ioasic_ssr);
+
+	fast_iob();
+	spin_unlock_irqrestore(&ioasic_ssr_lock, flags);
 }
 
 static void dma_ints_off(struct NCR_ESP *esp)
 {
-	disable_irq(SCSI_DMA_INT);
+	disable_irq(dec_interrupt[DEC_IRQ_ASC_DMA]);
 }
 
 static void dma_ints_on(struct NCR_ESP *esp)
 {
-	enable_irq(SCSI_DMA_INT);
+	enable_irq(dec_interrupt[DEC_IRQ_ASC_DMA]);
 }
 
 static int dma_irq_p(struct NCR_ESP *esp)
 {
-    return (esp->eregs->esp_status & ESP_STAT_INTR);
+	return (esp->eregs->esp_status & ESP_STAT_INTR);
 }
 
 static int dma_ports_p(struct NCR_ESP *esp)
 {
-/*
- * FIXME: what's this good for?
- */
+	/*
+	 * FIXME: what's this good for?
+	 */
 	return 1;
 }
 
-static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write)
+static void dma_setup(struct NCR_ESP *esp, u32 addr, int count, int write)
 {
-    /*
-     * On the Sparc, DMA_ST_WRITE means "move data from device to memory"
-     * so when (write) is true, it actually means READ!
-     */
-	if (write) {
-	dma_init_read(esp, addr, count);
-    } else {
-	dma_init_write(esp, addr, count);
-    }
+	/*
+	 * DMA_ST_WRITE means "move data from device to memory"
+	 * so when (write) is true, it actually means READ!
+	 */
+	if (write)
+		dma_init_read(esp, addr, count);
+	else
+		dma_init_write(esp, addr, count);
 }
 
-/*
- * These aren't used yet
- */
-static void dma_mmu_get_scsi_one(struct NCR_ESP *esp, Scsi_Cmnd * sp)
+static void dma_mmu_get_scsi_one(struct NCR_ESP *esp, struct scsi_cmnd * sp)
 {
-	sp->SCp.ptr = (char *)PHYSADDR(sp->SCp.buffer);
+	sp->SCp.ptr = (char *)virt_to_phys(sp->request_buffer);
 }
 
-static void dma_mmu_get_scsi_sgl(struct NCR_ESP *esp, Scsi_Cmnd * sp)
+static void dma_mmu_get_scsi_sgl(struct NCR_ESP *esp, struct scsi_cmnd * sp)
 {
-    int sz = sp->SCp.buffers_residual;
-    struct mmu_sglist *sg = (struct mmu_sglist *) sp->SCp.buffer;
+	int sz = sp->SCp.buffers_residual;
+	struct scatterlist *sg = sp->SCp.buffer;
 
-    while (sz >= 0) {
-		sg[sz].dvma_addr = PHYSADDR(sg[sz].addr);
-	sz--;
-    }
-	sp->SCp.ptr = (char *) ((unsigned long) sp->SCp.buffer->dvma_address);
+	while (sz >= 0) {
+		sg[sz].dma_address = page_to_phys(sg[sz].page) + sg[sz].offset;
+		sz--;
+	}
+	sp->SCp.ptr = (char *)(sp->SCp.buffer->dma_address);
 }
 
-static void dma_advance_sg(Scsi_Cmnd * sp)
+static void dma_advance_sg(struct scsi_cmnd * sp)
 {
-	sp->SCp.ptr = (char *) ((unsigned long) sp->SCp.buffer->dvma_address);
+	sp->SCp.ptr = (char *)(sp->SCp.buffer->dma_address);
 }
 
 static void pmaz_dma_drain(struct NCR_ESP *esp)
 {
-	memcpy((void *) (KSEG0ADDR(esp_virt_buffer)),
-		(void *) ( esp->slot + DEC_SCSI_SRAM + ESP_TGT_DMA_SIZE),
+	memcpy(phys_to_virt(esp_virt_buffer),
+		(void *)KSEG1ADDR(esp->slot + DEC_SCSI_SRAM + ESP_TGT_DMA_SIZE),
 		scsi_current_length);
 }
 
-static void pmaz_dma_init_read(struct NCR_ESP *esp, __u32 vaddress, int length)
+static void pmaz_dma_init_read(struct NCR_ESP *esp, u32 vaddress, int length)
 {
-	volatile int *dmareg = (volatile int *) (esp->slot + DEC_SCSI_DMAREG);
+	volatile u32 *dmareg =
+		(volatile u32 *)KSEG1ADDR(esp->slot + DEC_SCSI_DMAREG);
 
 	if (length > ESP_TGT_DMA_SIZE)
 		length = ESP_TGT_DMA_SIZE;
 
-	*dmareg = TC_ESP_DMA_ADDR(esp->slot + DEC_SCSI_SRAM + ESP_TGT_DMA_SIZE);
+	*dmareg = TC_ESP_DMA_ADDR(ESP_TGT_DMA_SIZE);
+
+	iob();
 
 	esp_virt_buffer = vaddress;
 	scsi_current_length = length;
 }
 
-static void pmaz_dma_init_write(struct NCR_ESP *esp, __u32 vaddress, int length)
+static void pmaz_dma_init_write(struct NCR_ESP *esp, u32 vaddress, int length)
 {
-	volatile int *dmareg = (volatile int *) ( esp->slot + DEC_SCSI_DMAREG );
+	volatile u32 *dmareg =
+		(volatile u32 *)KSEG1ADDR(esp->slot + DEC_SCSI_DMAREG);
 
-	memcpy((void *)(esp->slot + DEC_SCSI_SRAM + ESP_TGT_DMA_SIZE),
-	       (void *)KSEG0ADDR(vaddress), length);
+	memcpy((void *)KSEG1ADDR(esp->slot + DEC_SCSI_SRAM + ESP_TGT_DMA_SIZE),
+	       phys_to_virt(vaddress), length);
 
-	*dmareg = TC_ESP_DMAR_WRITE | 
-		TC_ESP_DMA_ADDR(esp->slot + DEC_SCSI_SRAM + ESP_TGT_DMA_SIZE);
+	wmb();
+	*dmareg = TC_ESP_DMAR_WRITE | TC_ESP_DMA_ADDR(ESP_TGT_DMA_SIZE);
 
+	iob();
 }
 
 static void pmaz_dma_ints_off(struct NCR_ESP *esp)
@@ -540,20 +555,19 @@
 {
 }
 
-static void pmaz_dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write)
+static void pmaz_dma_setup(struct NCR_ESP *esp, u32 addr, int count, int write)
 {
 	/*
-	 * On the Sparc, DMA_ST_WRITE means "move data from device to memory"
+	 * DMA_ST_WRITE means "move data from device to memory"
 	 * so when (write) is true, it actually means READ!
 	 */
-	if (write) {
+	if (write)
 		pmaz_dma_init_read(esp, addr, count);
-	} else {
+	else
 		pmaz_dma_init_write(esp, addr, count);
-	}
 }
 
-static void pmaz_dma_mmu_get_scsi_one(struct NCR_ESP *esp, Scsi_Cmnd * sp)
+static void pmaz_dma_mmu_get_scsi_one(struct NCR_ESP *esp, struct scsi_cmnd * sp)
 {
-	sp->SCp.ptr = (char *)KSEG0ADDR((sp->request_buffer));
+	sp->SCp.ptr = (char *)virt_to_phys(sp->request_buffer);
 }
diff -Nru a/drivers/scsi/dpt/dpt_osdutil.h b/drivers/scsi/dpt/dpt_osdutil.h
--- a/drivers/scsi/dpt/dpt_osdutil.h	2005-03-01 23:39:16 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,358 +0,0 @@
-/*	BSDI osd_util.h,v 1.8 1998/06/03 19:14:58 karels Exp	*/
-
-/*
- * Copyright (c) 1996-1999 Distributed Processing Technology Corporation
- * All rights reserved.
- *
- * Redistribution and use in source form, with or without modification, are
- * permitted provided that redistributions of source code must retain the
- * above copyright notice, this list of conditions and the following disclaimer.
- *
- * This software is provided `as is' by Distributed Processing Technology 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 Distributed Processing Technology 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
- * interruptions) 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 driver software, even if advised
- * of the possibility of such damage.
- *
- */
-
-#ifndef         __OSD_UTIL_H
-#define         __OSD_UTIL_H
-
-/*File - OSD_UTIL.H
- ****************************************************************************
- *
- *Description:
- *
- *      This file contains defines and function prototypes that are
- *operating system dependent.  The resources defined in this file
- *are not specific to any particular application.
- *
- *Copyright Distributed Processing Technology, Corp.
- *        140 Candace Dr.
- *        Maitland, Fl. 32751   USA
- *        Phone: (407) 830-5522  Fax: (407) 260-5366
- *        All Rights Reserved
- *
- *Author:       Doug Anderson
- *Date:         1/7/94
- *
- *Editors:
- *
- *Remarks:
- *
- *
- *****************************************************************************/
-
-
-/*Definitions - Defines & Constants ----------------------------------------- */
-
-/*----------------------------- */
-/* Operating system selections: */
-/*----------------------------- */
-
-/*#define               _DPT_MSDOS      */
-/*#define               _DPT_WIN_3X     */
-/*#define               _DPT_WIN_4X     */
-/*#define               _DPT_WIN_NT     */
-/*#define               _DPT_NETWARE    */
-/*#define               _DPT_OS2        */
-/*#define               _DPT_SCO        */
-/*#define               _DPT_UNIXWARE   */
-/*#define               _DPT_SOLARIS    */
-/*#define               _DPT_NEXTSTEP   */
-/*#define               _DPT_BANYAN     */
-
-/*-------------------------------- */
-/* Include the OS specific defines */
-/*-------------------------------- */
-
-/*#define       OS_SELECTION    From Above List */
-/*#define       SEMAPHORE_T     ??? */
-/*#define       DLL_HANDLE_T    ??? */
-
-#if (defined(KERNEL) && (defined(__FreeBSD__) || defined(__bsdi__)))
-# include        "i386/isa/dpt_osd_defs.h"
-#else
-# include        "osd_defs.h"
-#endif
-
-#ifndef DPT_UNALIGNED
-   #define      DPT_UNALIGNED
-#endif
-
-#ifndef DPT_EXPORT
-   #define      DPT_EXPORT
-#endif
-
-#ifndef DPT_IMPORT
-   #define      DPT_IMPORT
-#endif
-
-#ifndef DPT_RUNTIME_IMPORT
-   #define      DPT_RUNTIME_IMPORT  DPT_IMPORT
-#endif
-
-/*--------------------- */
-/* OS dependent defines */
-/*--------------------- */
-
-#if defined (_DPT_MSDOS) || defined (_DPT_WIN_3X)
-   #define      _DPT_16_BIT
-#else
-   #define      _DPT_32_BIT
-#endif
-
-#if defined (_DPT_SCO) || defined (_DPT_UNIXWARE) || defined (_DPT_SOLARIS) || defined (_DPT_AIX) || defined (SNI_MIPS) || defined (_DPT_BSDI) || defined (_DPT_FREE_BSD) || defined(_DPT_LINUX)
-   #define      _DPT_UNIX
-#endif
-
-#if defined (_DPT_WIN_3x) || defined (_DPT_WIN_4X) || defined (_DPT_WIN_NT) \
-	    || defined (_DPT_OS2)
-   #define      _DPT_DLL_SUPPORT
-#endif
-
-#if !defined (_DPT_MSDOS) && !defined (_DPT_WIN_3X) && !defined (_DPT_NETWARE)
-   #define      _DPT_PREEMPTIVE
-#endif
-
-#if !defined (_DPT_MSDOS) && !defined (_DPT_WIN_3X)
-   #define      _DPT_MULTI_THREADED
-#endif
-
-#if !defined (_DPT_MSDOS)
-   #define      _DPT_MULTI_TASKING
-#endif
-
-  /* These exist for platforms that   */
-  /* chunk when accessing mis-aligned */
-  /* data                             */
-#if defined (SNI_MIPS) || defined (_DPT_SOLARIS)
-   #if defined (_DPT_BIG_ENDIAN)
-	#if !defined (_DPT_STRICT_ALIGN)
-            #define _DPT_STRICT_ALIGN
-	#endif
-   #endif
-#endif
-
-  /* Determine if in C or C++ mode */
-#ifdef  __cplusplus
-   #define      _DPT_CPP
-#else
-   #define      _DPT_C
-#endif
-
-/*-------------------------------------------------------------------*/
-/* Under Solaris the compiler refuses to accept code like:           */
-/*   { {"DPT"}, 0, NULL .... },                                      */
-/* and complains about the {"DPT"} part by saying "cannot use { }    */
-/* to initialize char*".                                             */
-/*                                                                   */
-/* By defining these ugly macros we can get around this and also     */
-/* not have to copy and #ifdef large sections of code.  I know that  */
-/* these macros are *really* ugly, but they should help reduce       */
-/* maintenance in the long run.                                      */
-/*                                                                   */
-/*-------------------------------------------------------------------*/
-#if !defined (DPTSQO)
-   #if defined (_DPT_SOLARIS)
-      #define DPTSQO
-      #define DPTSQC
-   #else
-      #define DPTSQO {
-      #define DPTSQC }
-   #endif  /* solaris */
-#endif  /* DPTSQO */
-
-
-/*---------------------- */
-/* OS dependent typedefs */
-/*---------------------- */
-
-#if defined (_DPT_MSDOS) || defined (_DPT_SCO)
-   #define BYTE unsigned char
-   #define WORD unsigned short
-#endif
-
-#ifndef _DPT_TYPEDEFS
-   #define _DPT_TYPEDEFS
-   typedef unsigned char   uCHAR;
-   typedef unsigned short  uSHORT;
-   typedef unsigned int    uINT;
-   typedef unsigned long   uLONG;
-
-   typedef union {
-	 uCHAR        u8[4];
-	 uSHORT       u16[2];
-	 uLONG        u32;
-   } access_U;
-#endif
-
-#if !defined (NULL)
-   #define      NULL    0
-#endif
-
-
-/*Prototypes - function ----------------------------------------------------- */
-
-#ifdef  __cplusplus
-   extern "C" {         /* Declare all these functions as "C" functions */
-#endif
-
-/*------------------------ */
-/* Byte reversal functions */
-/*------------------------ */
-
-  /* Reverses the byte ordering of a 2 byte variable */
-#if (!defined(osdSwap2))
- uSHORT       osdSwap2(DPT_UNALIGNED uSHORT *);
-#endif  // !osdSwap2
-
-  /* Reverses the byte ordering of a 4 byte variable and shifts left 8 bits */
-#if (!defined(osdSwap3))
- uLONG        osdSwap3(DPT_UNALIGNED uLONG *);
-#endif  // !osdSwap3
-
-
-#ifdef  _DPT_NETWARE
-   #include "novpass.h" /* For DPT_Bswapl() prototype */
-	/* Inline the byte swap */
-   #ifdef __cplusplus
-	 inline uLONG osdSwap4(uLONG *inLong) {
-	 return *inLong = DPT_Bswapl(*inLong);
-	 }
-   #else
-	 #define osdSwap4(inLong)       DPT_Bswapl(inLong)
-   #endif  // cplusplus
-#else
-	/* Reverses the byte ordering of a 4 byte variable */
-# if (!defined(osdSwap4))
-   uLONG        osdSwap4(DPT_UNALIGNED uLONG *);
-# endif  // !osdSwap4
-
-  /* The following functions ALWAYS swap regardless of the *
-   * presence of DPT_BIG_ENDIAN                            */
-
-   uSHORT       trueSwap2(DPT_UNALIGNED uSHORT *);
-   uLONG        trueSwap4(DPT_UNALIGNED uLONG *);
-
-#endif  // netware
-
-
-/*-------------------------------------*
- * Network order swap functions        *
- *                                     *
- * These functions/macros will be used *
- * by the structure insert()/extract() *
- * functions.                          *
- *
- * We will enclose all structure       *
- * portability modifications inside    *
- * #ifdefs.  When we are ready, we     *
- * will #define DPT_PORTABLE to begin  *
- * using the modifications.            *
- *-------------------------------------*/
-uLONG	netSwap4(uLONG val);
-
-#if defined (_DPT_BIG_ENDIAN)
-
-// for big-endian we need to swap
-
-#ifndef NET_SWAP_2
-#define NET_SWAP_2(x) (((x) >> 8) | ((x) << 8))
-#endif  // NET_SWAP_2
-
-#ifndef NET_SWAP_4
-#define NET_SWAP_4(x) netSwap4((x))
-#endif  // NET_SWAP_4
-
-#else
-
-// for little-endian we don't need to do anything
-
-#ifndef NET_SWAP_2
-#define NET_SWAP_2(x) (x)
-#endif  // NET_SWAP_2
-
-#ifndef NET_SWAP_4
-#define NET_SWAP_4(x) (x)
-#endif  // NET_SWAP_4
-
-#endif  // big endian
-
-
-
-/*----------------------------------- */
-/* Run-time loadable module functions */
-/*----------------------------------- */
-
-  /* Loads the specified run-time loadable DLL */
-DLL_HANDLE_T    osdLoadModule(uCHAR *);
-  /* Unloads the specified run-time loadable DLL */
-uSHORT          osdUnloadModule(DLL_HANDLE_T);
-  /* Returns a pointer to a function inside a run-time loadable DLL */
-void *          osdGetFnAddr(DLL_HANDLE_T,uCHAR *);
-
-/*--------------------------------------- */
-/* Mutually exclusive semaphore functions */
-/*--------------------------------------- */
-
-  /* Create a named semaphore */
-SEMAPHORE_T     osdCreateNamedSemaphore(char *);
-  /* Create a mutually exlusive semaphore */
-SEMAPHORE_T     osdCreateSemaphore(void);
-	/* create an event semaphore */
-SEMAPHORE_T              osdCreateEventSemaphore(void);
-	/* create a named event semaphore */
-SEMAPHORE_T             osdCreateNamedEventSemaphore(char *);
-
-  /* Destroy the specified mutually exclusive semaphore object */
-uSHORT          osdDestroySemaphore(SEMAPHORE_T);
-  /* Request access to the specified mutually exclusive semaphore */
-uLONG           osdRequestSemaphore(SEMAPHORE_T,uLONG);
-  /* Release access to the specified mutually exclusive semaphore */
-uSHORT          osdReleaseSemaphore(SEMAPHORE_T);
-	/* wait for a event to happen */
-uLONG                            osdWaitForEventSemaphore(SEMAPHORE_T, uLONG);
-	/* signal an event */
-uLONG                            osdSignalEventSemaphore(SEMAPHORE_T);
-	/* reset the event */
-uLONG                            osdResetEventSemaphore(SEMAPHORE_T);
-
-/*----------------- */
-/* Thread functions */
-/*----------------- */
-
-  /* Releases control to the task switcher in non-preemptive */
-  /* multitasking operating systems. */
-void            osdSwitchThreads(void);
-
-  /* Starts a thread function */
-uLONG   osdStartThread(void *,void *);
-
-/* what is my thread id */
-uLONG osdGetThreadID(void);
-
-/* wakes up the specifed thread */
-void osdWakeThread(uLONG);
-
-/* osd sleep for x miliseconds */
-void osdSleep(uLONG);
-
-#define DPT_THREAD_PRIORITY_LOWEST 0x00
-#define DPT_THREAD_PRIORITY_NORMAL 0x01
-#define DPT_THREAD_PRIORITY_HIGHEST 0x02
-
-uCHAR osdSetThreadPriority(uLONG tid, uCHAR priority);
-
-#ifdef __cplusplus
-   }    /* end the xtern "C" declaration */
-#endif
-
-#endif  /* osd_util_h */
diff -Nru a/drivers/scsi/dpt/dpti_ioctl.h b/drivers/scsi/dpt/dpti_ioctl.h
--- a/drivers/scsi/dpt/dpti_ioctl.h	2005-03-01 23:38:56 -08:00
+++ b/drivers/scsi/dpt/dpti_ioctl.h	2005-03-01 23:38:56 -08:00
@@ -3,7 +3,6 @@
                              -------------------
     begin                : Thu Sep 7 2000
     copyright            : (C) 2001 by Adaptec
-    email                : deanna_bonds@adaptec.com
 
     See Documentation/scsi/dpti.txt for history, notes, license info
     and credits
diff -Nru a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c
--- a/drivers/scsi/dpt_i2o.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/scsi/dpt_i2o.c	2005-03-01 23:39:09 -08:00
@@ -3,7 +3,6 @@
                              -------------------
     begin                : Thu Sep 7 2000
     copyright            : (C) 2000 by Adaptec
-    email                : deanna_bonds@adaptec.com
 
 			   July 30, 2001 First version being submitted
 			   for inclusion in the kernel.  V2.4
@@ -146,7 +145,7 @@
 
 static struct adpt_i2o_post_wait_data *adpt_post_wait_queue = NULL;
 static u32 adpt_post_wait_id = 0;
-static spinlock_t adpt_post_wait_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(adpt_post_wait_lock);
 
 
 /*============================================================================
@@ -1179,7 +1178,6 @@
 				// dangerous.
 				status = -ETIME;
 			}
-			schedule_timeout(timeout*HZ);
 		}
 		if(pHba->host)
 			spin_lock_irq(pHba->host->host_lock);
diff -Nru a/drivers/scsi/dpti.h b/drivers/scsi/dpti.h
--- a/drivers/scsi/dpti.h	2005-03-01 23:38:44 -08:00
+++ b/drivers/scsi/dpti.h	2005-03-01 23:38:44 -08:00
@@ -3,7 +3,6 @@
                              -------------------
     begin                : Thu Sep 7 2000
     copyright            : (C) 2001 by Adaptec
-    email                : deanna_bonds@adaptec.com
 
     See Documentation/scsi/dpti.txt for history, notes, license info
     and credits
diff -Nru a/drivers/scsi/eata.c b/drivers/scsi/eata.c
--- a/drivers/scsi/eata.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/scsi/eata.c	2005-03-01 23:39:09 -08:00
@@ -505,28 +505,29 @@
 static int eata2x_detect(struct scsi_host_template *);
 static int eata2x_release(struct Scsi_Host *);
 static int eata2x_queuecommand(struct scsi_cmnd *,
-		void (*done)(struct scsi_cmnd *));
+			       void (*done) (struct scsi_cmnd *));
 static int eata2x_eh_abort(struct scsi_cmnd *);
 static int eata2x_eh_host_reset(struct scsi_cmnd *);
 static int eata2x_bios_param(struct scsi_device *, struct block_device *,
-                             sector_t, int *);
+			     sector_t, int *);
 static int eata2x_slave_configure(struct scsi_device *);
 
 static struct scsi_host_template driver_template = {
-                .name                    = "EATA/DMA 2.0x rev. 8.10.00 ",
-                .detect                  = eata2x_detect,
-                .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,
-                .this_id                 = 7,
-                .unchecked_isa_dma       = 1,
-                .use_clustering          = ENABLE_CLUSTERING
-                };
+	.name = "EATA/DMA 2.0x rev. 8.10.00 ",
+	.detect = eata2x_detect,
+	.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,
+	.this_id = 7,
+	.unchecked_isa_dma = 1,
+	.use_clustering = ENABLE_CLUSTERING
+};
+
 #if !defined(__BIG_ENDIAN_BITFIELD) && !defined(__LITTLE_ENDIAN_BITFIELD)
 #error "Adjust your <asm/byteorder.h> defines"
 #endif
@@ -618,221 +619,254 @@
 
 /* Board info structure */
 struct eata_info {
-   u_int32_t data_len;  /* Number of valid bytes after this field */
-   u_int32_t sign;      /* ASCII "EATA" signature */
+	u_int32_t data_len;	/* Number of valid bytes after this field */
+	u_int32_t sign;		/* ASCII "EATA" signature */
 
 #if defined(__BIG_ENDIAN_BITFIELD)
-   unchar version:4, :4;
-   unchar  haaval:1, ata:1, drqvld:1, dmasup:1, morsup:1, trnxfr:1, tarsup:1,
-           ocsena:1;
+	unchar version	: 4,
+	       		: 4;
+	unchar haaval	: 1,
+	       ata	: 1,
+	       drqvld	: 1,
+	       dmasup	: 1,
+	       morsup	: 1,
+	       trnxfr	: 1,
+	       tarsup	: 1,
+	       ocsena	: 1;
 #else
-   unchar        :4,    /* unused low nibble */
-          version:4;    /* EATA version, should be 0x1 */
-   unchar  ocsena:1,    /* Overlap Command Support Enabled */
-           tarsup:1,    /* Target Mode Supported */
-           trnxfr:1,    /* Truncate Transfer Cmd NOT Necessary */
-           morsup:1,    /* More Supported */
-           dmasup:1,    /* DMA Supported */
-           drqvld:1,    /* DRQ Index (DRQX) is valid */
-              ata:1,    /* This is an ATA device */
-           haaval:1;    /* Host Adapter Address Valid */
-#endif
-
-   ushort cp_pad_len;   /* Number of pad bytes after cp_len */
-   unchar host_addr[4]; /* Host Adapter SCSI ID for channels 3, 2, 1, 0 */
-   u_int32_t cp_len;    /* Number of valid bytes in cp */
-   u_int32_t sp_len;    /* Number of valid bytes in sp */
-   ushort queue_size;   /* Max number of cp that can be queued */
-   ushort unused;
-   ushort scatt_size;   /* Max number of entries in scatter/gather table */
+	unchar		: 4,	/* unused low nibble */
+	 	version	: 4;	/* EATA version, should be 0x1 */
+	unchar ocsena	: 1,	/* Overlap Command Support Enabled */
+	       tarsup	: 1,	/* Target Mode Supported */
+	       trnxfr	: 1,	/* Truncate Transfer Cmd NOT Necessary */
+	       morsup	: 1,	/* More Supported */
+	       dmasup	: 1,	/* DMA Supported */
+	       drqvld	: 1,	/* DRQ Index (DRQX) is valid */
+	       ata	: 1,	/* This is an ATA device */
+	       haaval	: 1;	/* Host Adapter Address Valid */
+#endif
+
+	ushort cp_pad_len;	/* Number of pad bytes after cp_len */
+	unchar host_addr[4];	/* Host Adapter SCSI ID for channels 3, 2, 1, 0 */
+	u_int32_t cp_len;	/* Number of valid bytes in cp */
+	u_int32_t sp_len;	/* Number of valid bytes in sp */
+	ushort queue_size;	/* Max number of cp that can be queued */
+	ushort unused;
+	ushort scatt_size;	/* Max number of entries in scatter/gather table */
 
 #if defined(__BIG_ENDIAN_BITFIELD)
-   unchar    drqx:2, second:1, irq_tr:1, irq:4;
-   unchar  sync;
-   unchar         :4, res1:1, large_sg:1, forcaddr:1, isaena:1;
-   unchar max_chan:3, max_id:5;
-   unchar   max_lun;
-   unchar     eisa:1, pci:1, idquest:1, m1:1, :4;
+	unchar drqx	: 2,
+	       second	: 1,
+	       irq_tr	: 1,
+	       irq	: 4;
+	unchar sync;
+	unchar		: 4,
+	       res1	: 1,
+	       large_sg	: 1,
+	       forcaddr	: 1,
+	       isaena	: 1;
+	unchar max_chan	: 3,
+	       max_id	: 5;
+	unchar max_lun;
+	unchar eisa	: 1,
+	       pci	: 1,
+	       idquest	: 1,
+	       m1	: 1,
+	       		: 4;
 #else
-   unchar     irq:4,    /* Interrupt Request assigned to this controller */
-           irq_tr:1,    /* 0 for edge triggered, 1 for level triggered */
-           second:1,    /* 1 if this is a secondary (not primary) controller */
-             drqx:2;    /* DRQ Index (0=DMA0, 1=DMA7, 2=DMA6, 3=DMA5) */
-   unchar  sync;        /* 1 if scsi target id 7...0 is running sync scsi */
-
-   /* Structure extension defined in EATA 2.0B */
-   unchar  isaena:1,    /* ISA i/o addressing is disabled/enabled */
-         forcaddr:1,    /* Port address has been forced */
-         large_sg:1,    /* 1 if large SG lists are supported */
-             res1:1,
-                 :4;
-   unchar  max_id:5,    /* Max SCSI target ID number */
-         max_chan:3;    /* Max SCSI channel number on this board */
-
-   /* Structure extension defined in EATA 2.0C */
-   unchar   max_lun;    /* Max SCSI LUN number */
-   unchar        :4,
-               m1:1,    /* This is a PCI with an M1 chip installed */
-          idquest:1,    /* RAIDNUM returned is questionable */
-              pci:1,    /* This board is PCI */
-             eisa:1;    /* This board is EISA */
+	unchar irq	: 4,	/* Interrupt Request assigned to this controller */
+	       irq_tr	: 1,	/* 0 for edge triggered, 1 for level triggered */
+	       second	: 1,	/* 1 if this is a secondary (not primary) controller */
+	       drqx	: 2;	/* DRQ Index (0=DMA0, 1=DMA7, 2=DMA6, 3=DMA5) */
+	unchar sync;		/* 1 if scsi target id 7...0 is running sync scsi */
+
+	/* Structure extension defined in EATA 2.0B */
+	unchar isaena	: 1,	/* ISA i/o addressing is disabled/enabled */
+	       forcaddr	: 1,	/* Port address has been forced */
+	       large_sg	: 1,	/* 1 if large SG lists are supported */
+	       res1	: 1,
+	       		: 4;
+	unchar max_id	: 5,	/* Max SCSI target ID number */
+	       max_chan	: 3;	/* Max SCSI channel number on this board */
+
+	/* Structure extension defined in EATA 2.0C */
+	unchar max_lun;		/* Max SCSI LUN number */
+	unchar
+			: 4,
+	       m1	: 1,	/* This is a PCI with an M1 chip installed */
+	       idquest	: 1,	/* RAIDNUM returned is questionable */
+	       pci	: 1,	/* This board is PCI */
+	       eisa	: 1;	/* This board is EISA */
 #endif
 
-   unchar   raidnum;    /* Uniquely identifies this HBA in a system */
-   unchar   notused;
+	unchar raidnum;		/* Uniquely identifies this HBA in a system */
+	unchar notused;
 
-   ushort ipad[247];
-   };
+	ushort ipad[247];
+};
 
 /* Board config structure */
 struct eata_config {
-   ushort len;          /* Number of bytes following this field */
+	ushort len;		/* Number of bytes following this field */
 
 #if defined(__BIG_ENDIAN_BITFIELD)
-   unchar     :4, tarena:1, mdpena:1, ocena:1, edis:1;
+	unchar		: 4,
+	       tarena	: 1,
+	       mdpena	: 1,
+	       ocena	: 1,
+	       edis	: 1;
 #else
-   unchar edis:1,       /* Disable EATA interface after config command */
-         ocena:1,       /* Overlapped Commands Enabled */
-        mdpena:1,       /* Transfer all Modified Data Pointer Messages */
-        tarena:1,       /* Target Mode Enabled for this controller */
-              :4;
+	unchar edis	: 1,	/* Disable EATA interface after config command */
+	       ocena	: 1,	/* Overlapped Commands Enabled */
+	       mdpena	: 1,	/* Transfer all Modified Data Pointer Messages */
+	       tarena	: 1,	/* Target Mode Enabled for this controller */
+	       		: 4;
 #endif
-
-   unchar cpad[511];
-   };
+	unchar cpad[511];
+};
 
 /* Returned status packet structure */
 struct mssp {
-
 #if defined(__BIG_ENDIAN_BITFIELD)
-   unchar            eoc:1, adapter_status:7;
+	unchar eoc	: 1,
+	       adapter_status : 7;
 #else
-   unchar adapter_status:7,    /* State related to current command */
-                     eoc:1;    /* End Of Command (1 = command completed) */
+	unchar adapter_status : 7,	/* State related to current command */
+	       eoc	: 1;		/* End Of Command (1 = command completed) */
 #endif
-
-   unchar target_status;       /* SCSI status received after data transfer */
-   unchar unused[2];
-   u_int32_t inv_res_len;      /* Number of bytes not transferred */
-   u_int32_t cpp_index;        /* Index of address set in cp */
-   char mess[12];
-   };
+	unchar target_status;	/* SCSI status received after data transfer */
+	unchar unused[2];
+	u_int32_t inv_res_len;	/* Number of bytes not transferred */
+	u_int32_t cpp_index;	/* Index of address set in cp */
+	char mess[12];
+};
 
 struct sg_list {
-   unsigned int address;                /* Segment Address */
-   unsigned int num_bytes;              /* Segment Length */
-   };
+	unsigned int address;	/* Segment Address */
+	unsigned int num_bytes;	/* Segment Length */
+};
 
 /* MailBox SCSI Command Packet */
 struct mscp {
-
 #if defined(__BIG_ENDIAN_BITFIELD)
-   unchar     din:1, dout:1, interp:1, :1, sg:1, reqsen:1, init:1, sreset:1;
-   unchar sense_len;
-   unchar unused[3];
-   unchar        :7, fwnest:1;
-   unchar        :5, hbaci:1, iat:1, phsunit:1;
-   unchar channel:3, target:5;
-   unchar     one:1, dispri:1, luntar:1, lun:5;
+	unchar din	: 1,
+	       dout	: 1,
+	       interp	: 1,
+	       		: 1,
+		sg	: 1,
+		reqsen	:1,
+		init	: 1,
+		sreset	: 1;
+	unchar sense_len;
+	unchar unused[3];
+	unchar		: 7,
+	       fwnest	: 1;
+	unchar		: 5,
+	       hbaci	: 1,
+	       iat	: 1,
+	       phsunit	: 1;
+	unchar channel	: 3,
+	       target	: 5;
+	unchar one	: 1,
+	       dispri	: 1,
+	       luntar	: 1,
+	       lun	: 5;
 #else
-   unchar  sreset:1,     /* SCSI Bus Reset Signal should be asserted */
-             init:1,     /* Re-initialize controller and self test */
-           reqsen:1,     /* Transfer Request Sense Data to addr using DMA */
-               sg:1,     /* Use Scatter/Gather */
-                 :1,
-           interp:1,     /* The controller interprets cp, not the target */
-             dout:1,     /* Direction of Transfer is Out (Host to Target) */
-              din:1;     /* Direction of Transfer is In (Target to Host) */
-   unchar sense_len;     /* Request Sense Length */
-   unchar unused[3];
-   unchar  fwnest:1,     /* Send command to a component of an Array Group */
-                 :7;
-   unchar phsunit:1,     /* Send to Target Physical Unit (bypass RAID) */
-              iat:1,     /* Inhibit Address Translation */
-            hbaci:1,     /* Inhibit HBA Caching for this command */
-                 :5;
-   unchar  target:5,     /* SCSI target ID */
-          channel:3;     /* SCSI channel number */
-   unchar     lun:5,     /* SCSI logical unit number */
-           luntar:1,     /* This cp is for Target (not LUN) */
-           dispri:1,     /* Disconnect Privilege granted */
-              one:1;     /* 1 */
-#endif
-
-   unchar mess[3];       /* Massage to/from Target */
-   unchar cdb[12];       /* Command Descriptor Block */
-   u_int32_t data_len;   /* If sg=0 Data Length, if sg=1 sglist length */
-   u_int32_t cpp_index;  /* Index of address to be returned in sp */
-   u_int32_t data_address; /* If sg=0 Data Address, if sg=1 sglist address */
-   u_int32_t sp_dma_addr;  /* Address where sp is DMA'ed when cp completes */
-   u_int32_t sense_addr; /* Address where Sense Data is DMA'ed on error */
-
-   /* Additional fields begin here. */
-   struct scsi_cmnd *SCpnt;
-
-   /* All the cp structure is zero filled by queuecommand except the
-      following CP_TAIL_SIZE bytes, initialized by detect */
-   dma_addr_t cp_dma_addr; /* dma handle for this cp structure */
-   struct sg_list *sglist; /* pointer to the allocated SG list */
-   };
+	unchar sreset	:1,	/* SCSI Bus Reset Signal should be asserted */
+	       init	:1,	/* Re-initialize controller and self test */
+	       reqsen	:1,	/* Transfer Request Sense Data to addr using DMA */
+	       sg	:1,	/* Use Scatter/Gather */
+	       		:1,
+	       interp	:1,	/* The controller interprets cp, not the target */
+	       dout	:1,	/* Direction of Transfer is Out (Host to Target) */
+	       din	:1;	/* Direction of Transfer is In (Target to Host) */
+	unchar sense_len;	/* Request Sense Length */
+	unchar unused[3];
+	unchar fwnest	: 1,	/* Send command to a component of an Array Group */
+			: 7;
+	unchar phsunit	: 1,	/* Send to Target Physical Unit (bypass RAID) */
+	       iat	: 1,	/* Inhibit Address Translation */
+	       hbaci	: 1,	/* Inhibit HBA Caching for this command */
+	       		: 5;
+	unchar target	: 5,	/* SCSI target ID */
+	       channel	: 3;	/* SCSI channel number */
+	unchar lun	: 5,	/* SCSI logical unit number */
+	       luntar	: 1,	/* This cp is for Target (not LUN) */
+	       dispri	: 1,	/* Disconnect Privilege granted */
+	       one	: 1;	/* 1 */
+#endif
+
+	unchar mess[3];		/* Massage to/from Target */
+	unchar cdb[12];		/* Command Descriptor Block */
+	u_int32_t data_len;	/* If sg=0 Data Length, if sg=1 sglist length */
+	u_int32_t cpp_index;	/* Index of address to be returned in sp */
+	u_int32_t data_address;	/* If sg=0 Data Address, if sg=1 sglist address */
+	u_int32_t sp_dma_addr;	/* Address where sp is DMA'ed when cp completes */
+	u_int32_t sense_addr;	/* Address where Sense Data is DMA'ed on error */
+
+	/* Additional fields begin here. */
+	struct scsi_cmnd *SCpnt;
+
+	/* All the cp structure is zero filled by queuecommand except the
+	   following CP_TAIL_SIZE bytes, initialized by detect */
+	dma_addr_t cp_dma_addr;	/* dma handle for this cp structure */
+	struct sg_list *sglist;	/* pointer to the allocated SG list */
+};
 
 #define CP_TAIL_SIZE (sizeof(struct sglist *) + sizeof(dma_addr_t))
 
 struct hostdata {
-   struct mscp cp[MAX_MAILBOXES];       /* Mailboxes for this board */
-   unsigned int cp_stat[MAX_MAILBOXES]; /* FREE, IN_USE, LOCKED, IN_RESET */
-   unsigned int last_cp_used;           /* Index of last mailbox used */
-   unsigned int iocount;                /* Total i/o done for this board */
-   int board_number;                    /* Number of this board */
-   char board_name[16];                 /* Name of this board */
-   int in_reset;                        /* True if board is doing a reset */
-   int target_to[MAX_TARGET][MAX_CHANNEL]; /* N. of timeout errors on target */
-   int target_redo[MAX_TARGET][MAX_CHANNEL]; /* If 1 redo i/o on target */
-   unsigned int retries;                /* Number of internal retries */
-   unsigned long last_retried_pid;      /* Pid of last retried command */
-   unsigned char subversion;            /* Bus type, either ISA or EISA/PCI */
-   unsigned char protocol_rev;          /* EATA 2.0 rev., 'A' or 'B' or 'C' */
-   unsigned char is_pci;                /* 1 is bus type is PCI */
-   struct pci_dev *pdev;                /* pdev for PCI bus, NULL otherwise */
-   struct mssp *sp_cpu_addr;            /* cpu addr for DMA buffer sp */
-   dma_addr_t sp_dma_addr;              /* dma handle for DMA buffer sp */
-   struct mssp sp;                      /* Local copy of sp buffer */
-   };
+	struct mscp cp[MAX_MAILBOXES];	/* Mailboxes for this board */
+	unsigned int cp_stat[MAX_MAILBOXES];	/* FREE, IN_USE, LOCKED, IN_RESET */
+	unsigned int last_cp_used;	/* Index of last mailbox used */
+	unsigned int iocount;	/* Total i/o done for this board */
+	int board_number;	/* Number of this board */
+	char board_name[16];	/* Name of this board */
+	int in_reset;		/* True if board is doing a reset */
+	int target_to[MAX_TARGET][MAX_CHANNEL];	/* N. of timeout errors on target */
+	int target_redo[MAX_TARGET][MAX_CHANNEL];	/* If 1 redo i/o on target */
+	unsigned int retries;	/* Number of internal retries */
+	unsigned long last_retried_pid;	/* Pid of last retried command */
+	unsigned char subversion;	/* Bus type, either ISA or EISA/PCI */
+	unsigned char protocol_rev;	/* EATA 2.0 rev., 'A' or 'B' or 'C' */
+	unsigned char is_pci;	/* 1 is bus type is PCI */
+	struct pci_dev *pdev;	/* pdev for PCI bus, NULL otherwise */
+	struct mssp *sp_cpu_addr;	/* cpu addr for DMA buffer sp */
+	dma_addr_t sp_dma_addr;	/* dma handle for DMA buffer sp */
+	struct mssp sp;		/* Local copy of sp buffer */
+};
 
-static struct Scsi_Host *sh[MAX_BOARDS + 1];
+static struct Scsi_Host *sh[MAX_BOARDS];
 static const char *driver_name = "EATA";
 static char sha[MAX_BOARDS];
-static spinlock_t driver_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(driver_lock);
 
 /* Initialize num_boards so that ihdlr can work while detect is in progress */
 static unsigned int num_boards = MAX_BOARDS;
 
 static unsigned long io_port[] = {
 
-   /* Space for MAX_INT_PARAM ports usable while loading as a module */
-   SKIP,    SKIP,   SKIP,   SKIP,   SKIP,   SKIP,   SKIP,   SKIP,
-   SKIP,    SKIP,
-
-   /* First ISA */
-   0x1f0,
-
-   /* Space for MAX_PCI ports possibly reported by PCI_BIOS */
-   SKIP,    SKIP,   SKIP,   SKIP,   SKIP,   SKIP,   SKIP,   SKIP,
-   SKIP,    SKIP,   SKIP,   SKIP,   SKIP,   SKIP,   SKIP,   SKIP,
-
-   /* MAX_EISA ports */
-   0x1c88, 0x2c88, 0x3c88, 0x4c88, 0x5c88, 0x6c88, 0x7c88, 0x8c88,
-   0x9c88, 0xac88, 0xbc88, 0xcc88, 0xdc88, 0xec88, 0xfc88,
-
-   /* Other (MAX_ISA - 1) ports */
-   0x170,  0x230,  0x330,
-
-   /* End of list */
-   0x0
-   };
-
-#define HD(board) ((struct hostdata *) &sh[board]->hostdata)
-#define BN(board) (HD(board)->board_name)
+	/* Space for MAX_INT_PARAM ports usable while loading as a module */
+	SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
+	SKIP, SKIP,
+
+	/* First ISA */
+	0x1f0,
+
+	/* Space for MAX_PCI ports possibly reported by PCI_BIOS */
+	SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
+	SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
+
+	/* MAX_EISA ports */
+	0x1c88, 0x2c88, 0x3c88, 0x4c88, 0x5c88, 0x6c88, 0x7c88, 0x8c88,
+	0x9c88, 0xac88, 0xbc88, 0xcc88, 0xdc88, 0xec88, 0xfc88,
+
+	/* Other (MAX_ISA - 1) ports */
+	0x170, 0x230, 0x330,
+
+	/* End of list */
+	0x0
+};
 
 /* Device is Big Endian */
 #define H2DEV(x)   cpu_to_be32(x)
@@ -844,7 +878,8 @@
 #define REG2H(x)   le16_to_cpu(x)
 
 static irqreturn_t do_interrupt_handler(int, void *, struct pt_regs *);
-static void flush_dev(struct scsi_device *, unsigned long, unsigned int, unsigned int);
+static void flush_dev(struct scsi_device *, unsigned long, struct hostdata *,
+		      unsigned int);
 static int do_trace = 0;
 static int setup_done = 0;
 static int link_statistics;
@@ -896,1531 +931,1691 @@
 #include <linux/moduleparam.h>
 
 module_param_string(eata, boot_options, MAX_BOOT_OPTIONS_SIZE, 0);
-MODULE_PARM_DESC(eata, " equivalent to the \"eata=...\" kernel boot option." \
-"            Example: modprobe eata \"eata=0x7410,0x230,lc:y,tm:0,mq:4,ep:n\"");
+MODULE_PARM_DESC(eata, " equivalent to the \"eata=...\" kernel boot option."
+		 "            Example: modprobe eata \"eata=0x7410,0x230,lc:y,tm:0,mq:4,ep:n\"");
 MODULE_AUTHOR("Dario Ballabio");
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("EATA/DMA SCSI Driver");
 
 #endif
 
-static int eata2x_slave_configure(struct scsi_device *dev) {
-   int j, tqd, utqd;
-   char *tag_suffix, *link_suffix;
-   struct Scsi_Host *host = dev->host;
-
-   j = ((struct hostdata *) host->hostdata)->board_number;
-
-   utqd = MAX_CMD_PER_LUN;
-   tqd = max_queue_depth;
-
-   if (TLDEV(dev->type) && dev->tagged_supported)
-
-      if (tag_mode == TAG_SIMPLE) {
-         scsi_adjust_queue_depth(dev, MSG_SIMPLE_TAG, tqd);
-         tag_suffix = ", simple tags";
-         }
-      else if (tag_mode == TAG_ORDERED) {
-         scsi_adjust_queue_depth(dev, MSG_ORDERED_TAG, tqd);
-         tag_suffix = ", ordered tags";
-         }
-      else {
-         scsi_adjust_queue_depth(dev, 0, tqd);
-         tag_suffix = ", no tags";
-         }
-
-   else if (TLDEV(dev->type) && linked_comm) {
-      scsi_adjust_queue_depth(dev, 0, tqd);
-      tag_suffix = ", untagged";
-      }
-
-   else {
-      scsi_adjust_queue_depth(dev, 0, utqd);
-      tag_suffix = "";
-      }
-
-   if (TLDEV(dev->type) && linked_comm && dev->queue_depth > 2)
-      link_suffix = ", sorted";
-   else if (TLDEV(dev->type))
-      link_suffix = ", unsorted";
-   else
-      link_suffix = "";
-
-   printk("%s: scsi%d, channel %d, id %d, lun %d, cmds/lun %d%s%s.\n",
-          BN(j), host->host_no, dev->channel, dev->id, dev->lun,
-          dev->queue_depth, link_suffix, tag_suffix);
-
-   return 0;
-}
-
-static int wait_on_busy(unsigned long iobase, unsigned int loop) {
-
-   while (inb(iobase + REG_AUX_STATUS) & ABSY_ASSERTED) {
-      udelay(1L);
-      if (--loop == 0) return 1;
-      }
-
-   return 0;
-}
-
-static int do_dma(unsigned long iobase, unsigned long addr, unchar cmd) {
-   unsigned char *byaddr;
-   unsigned long devaddr;
+static int eata2x_slave_configure(struct scsi_device *dev)
+{
+	int tqd, utqd;
+	char *tag_suffix, *link_suffix;
+	struct Scsi_Host *shost = dev->host;
+	struct hostdata *ha = (struct hostdata *)shost->hostdata;
+
+	utqd = MAX_CMD_PER_LUN;
+	tqd = max_queue_depth;
+
+	if (TLDEV(dev->type) && dev->tagged_supported) {
+		if (tag_mode == TAG_SIMPLE) {
+			scsi_adjust_queue_depth(dev, MSG_SIMPLE_TAG, tqd);
+			tag_suffix = ", simple tags";
+		} else if (tag_mode == TAG_ORDERED) {
+			scsi_adjust_queue_depth(dev, MSG_ORDERED_TAG, tqd);
+			tag_suffix = ", ordered tags";
+		} else {
+			scsi_adjust_queue_depth(dev, 0, tqd);
+			tag_suffix = ", no tags";
+		}
+	} else if (TLDEV(dev->type) && linked_comm) {
+		scsi_adjust_queue_depth(dev, 0, tqd);
+		tag_suffix = ", untagged";
+	} else {
+		scsi_adjust_queue_depth(dev, 0, utqd);
+		tag_suffix = "";
+	}
+
+	if (TLDEV(dev->type) && linked_comm && dev->queue_depth > 2)
+		link_suffix = ", sorted";
+	else if (TLDEV(dev->type))
+		link_suffix = ", unsorted";
+	else
+		link_suffix = "";
+
+	printk("%s: scsi%d, channel %d, id %d, lun %d, cmds/lun %d%s%s.\n",
+	       ha->board_name, shost->host_no, dev->channel, dev->id, dev->lun,
+	       dev->queue_depth, link_suffix, tag_suffix);
+
+	return 0;
+}
+
+static int wait_on_busy(unsigned long iobase, unsigned int loop)
+{
+	while (inb(iobase + REG_AUX_STATUS) & ABSY_ASSERTED) {
+		udelay(1L);
+		if (--loop == 0)
+			return 1;
+	}
+	return 0;
+}
+
+static int do_dma(unsigned long iobase, unsigned long addr, unchar cmd)
+{
+	unsigned char *byaddr;
+	unsigned long devaddr;
+
+	if (wait_on_busy(iobase, (addr ? MAXLOOP * 100 : MAXLOOP)))
+		return 1;
+
+	if (addr) {
+		devaddr = H2DEV(addr);
+		byaddr = (unsigned char *)&devaddr;
+		outb(byaddr[3], iobase + REG_LOW);
+		outb(byaddr[2], iobase + REG_LM);
+		outb(byaddr[1], iobase + REG_MID);
+		outb(byaddr[0], iobase + REG_MSB);
+	}
+
+	outb(cmd, iobase + REG_CMD);
+	return 0;
+}
+
+static int read_pio(unsigned long iobase, ushort * start, ushort * end)
+{
+	unsigned int loop = MAXLOOP;
+	ushort *p;
+
+	for (p = start; p <= end; p++) {
+		while (!(inb(iobase + REG_STATUS) & DRQ_ASSERTED)) {
+			udelay(1L);
+			if (--loop == 0)
+				return 1;
+		}
+		loop = MAXLOOP;
+		*p = REG2H(inw(iobase));
+	}
 
-   if (wait_on_busy(iobase, (addr ? MAXLOOP * 100 : MAXLOOP))) return 1;
-
-   if (addr) {
-      devaddr = H2DEV(addr);
-      byaddr = (unsigned char *) &devaddr;
-      outb(byaddr[3], iobase + REG_LOW);
-      outb(byaddr[2], iobase + REG_LM);
-      outb(byaddr[1], iobase + REG_MID);
-      outb(byaddr[0], iobase + REG_MSB);
-      }
-
-   outb(cmd, iobase + REG_CMD);
-   return 0;
+	return 0;
 }
 
-static int read_pio(unsigned long iobase, ushort *start, ushort *end) {
-   unsigned int loop = MAXLOOP;
-   ushort *p;
-
-   for (p = start; p <= end; p++) {
-
-      while (!(inb(iobase + REG_STATUS) & DRQ_ASSERTED)) {
-         udelay(1L);
-         if (--loop == 0) return 1;
-         }
-
-      loop = MAXLOOP;
-      *p = REG2H(inw(iobase));
-      }
-
-   return 0;
-}
-
-static struct pci_dev *get_pci_dev(unsigned long port_base) {
-
+static struct pci_dev *get_pci_dev(unsigned long port_base)
+{
 #if defined(CONFIG_PCI)
+	unsigned int addr;
+	struct pci_dev *dev = NULL;
 
-   unsigned int addr;
-   struct pci_dev *dev = NULL;
-
-   while((dev = pci_get_class(PCI_CLASS_STORAGE_SCSI << 8, dev))) {
-      addr = pci_resource_start (dev, 0);
+	while ((dev = pci_get_class(PCI_CLASS_STORAGE_SCSI << 8, dev))) {
+		addr = pci_resource_start(dev, 0);
 
 #if defined(DEBUG_PCI_DETECT)
-      printk("%s: get_pci_dev, bus %d, devfn 0x%x, addr 0x%x.\n",
-             driver_name, dev->bus->number, dev->devfn, addr);
+		printk("%s: get_pci_dev, bus %d, devfn 0x%x, addr 0x%x.\n",
+		       driver_name, dev->bus->number, dev->devfn, addr);
 #endif
 
-      /* we are in so much trouble for a pci hotplug system with this driver
-       * anyway, so doing this at least lets people unload the driver and not
-       * cause memory problems, but in general this is a bad thing to do (this
-       * driver needs to be converted to the proper PCI api someday... */
-      pci_dev_put(dev);
-      if (addr + PCI_BASE_ADDRESS_0 == port_base) return dev;
-      }
-
-#endif /* end CONFIG_PCI */
-
-   return NULL;
+		/* we are in so much trouble for a pci hotplug system with this driver
+		 * anyway, so doing this at least lets people unload the driver and not
+		 * cause memory problems, but in general this is a bad thing to do (this
+		 * driver needs to be converted to the proper PCI api someday... */
+		pci_dev_put(dev);
+		if (addr + PCI_BASE_ADDRESS_0 == port_base)
+			return dev;
+	}
+#endif				/* end CONFIG_PCI */
+	return NULL;
 }
 
-static void enable_pci_ports(void) {
-
+static void enable_pci_ports(void)
+{
 #if defined(CONFIG_PCI)
+	struct pci_dev *dev = NULL;
 
-   struct pci_dev *dev = NULL;
-
-   while((dev = pci_get_class(PCI_CLASS_STORAGE_SCSI << 8, dev))) {
-
+	while ((dev = pci_get_class(PCI_CLASS_STORAGE_SCSI << 8, dev))) {
 #if defined(DEBUG_PCI_DETECT)
-      printk("%s: enable_pci_ports, bus %d, devfn 0x%x.\n",
-             driver_name, dev->bus->number, dev->devfn);
+		printk("%s: enable_pci_ports, bus %d, devfn 0x%x.\n",
+		       driver_name, dev->bus->number, dev->devfn);
 #endif
 
-      if (pci_enable_device (dev))
-         printk("%s: warning, pci_enable_device failed, bus %d devfn 0x%x.\n",
-                driver_name, dev->bus->number, dev->devfn);
-      }
-
-#endif /* end CONFIG_PCI */
-}
-
-static int port_detect \
-      (unsigned long port_base, unsigned int j, struct scsi_host_template *tpnt) {
-   unsigned char irq, dma_channel, subversion, i, is_pci = 0;
-   unsigned char protocol_rev;
-   struct eata_info info;
-   char *bus_type, dma_name[16];
-   struct pci_dev *pdev;
-
-   /* Allowed DMA channels for ISA (0 indicates reserved) */
-   unsigned char dma_channel_table[4] = { 5, 6, 7, 0 };
+		if (pci_enable_device(dev))
+			printk
+			    ("%s: warning, pci_enable_device failed, bus %d devfn 0x%x.\n",
+			     driver_name, dev->bus->number, dev->devfn);
+	}
+
+#endif				/* end CONFIG_PCI */
+}
+
+static int port_detect(unsigned long port_base, unsigned int j,
+		struct scsi_host_template *tpnt)
+{
+	unsigned char irq, dma_channel, subversion, i, is_pci = 0;
+	unsigned char protocol_rev;
+	struct eata_info info;
+	char *bus_type, dma_name[16];
+	struct pci_dev *pdev;
+	/* Allowed DMA channels for ISA (0 indicates reserved) */
+	unsigned char dma_channel_table[4] = { 5, 6, 7, 0 };
+	struct Scsi_Host *shost;
+	struct hostdata *ha;
+	char name[16];
 
-   char name[16];
+	sprintf(name, "%s%d", driver_name, j);
 
-   sprintf(name, "%s%d", driver_name, j);
-
-   if (!request_region(port_base, REGION_SIZE, driver_name)) {
+	if (!request_region(port_base, REGION_SIZE, driver_name)) {
 #if defined(DEBUG_DETECT)
-      printk("%s: address 0x%03lx in use, skipping probe.\n", name, port_base);
+		printk("%s: address 0x%03lx in use, skipping probe.\n", name,
+		       port_base);
 #endif
-      goto fail;
-      }
+		goto fail;
+	}
 
-   spin_lock_irq(&driver_lock);
+	spin_lock_irq(&driver_lock);
 
-   if (do_dma(port_base, 0, READ_CONFIG_PIO)) {
+	if (do_dma(port_base, 0, READ_CONFIG_PIO)) {
 #if defined(DEBUG_DETECT)
-      printk("%s: detect, do_dma failed at 0x%03lx.\n", name, port_base);
+		printk("%s: detect, do_dma failed at 0x%03lx.\n", name,
+		       port_base);
 #endif
-      goto freelock;
-      }
+		goto freelock;
+	}
 
-   /* Read the info structure */
-   if (read_pio(port_base, (ushort *)&info, (ushort *)&info.ipad[0])) {
+	/* Read the info structure */
+	if (read_pio(port_base, (ushort *) & info, (ushort *) & info.ipad[0])) {
 #if defined(DEBUG_DETECT)
-      printk("%s: detect, read_pio failed at 0x%03lx.\n", name, port_base);
+		printk("%s: detect, read_pio failed at 0x%03lx.\n", name,
+		       port_base);
 #endif
-      goto freelock;
-      }
+		goto freelock;
+	}
 
-   info.data_len = DEV2H(info.data_len);
-   info.sign = DEV2H(info.sign);
-   info.cp_pad_len = DEV2H16(info.cp_pad_len);
-   info.cp_len = DEV2H(info.cp_len);
-   info.sp_len = DEV2H(info.sp_len);
-   info.scatt_size = DEV2H16(info.scatt_size);
-   info.queue_size = DEV2H16(info.queue_size);
+	info.data_len = DEV2H(info.data_len);
+	info.sign = DEV2H(info.sign);
+	info.cp_pad_len = DEV2H16(info.cp_pad_len);
+	info.cp_len = DEV2H(info.cp_len);
+	info.sp_len = DEV2H(info.sp_len);
+	info.scatt_size = DEV2H16(info.scatt_size);
+	info.queue_size = DEV2H16(info.queue_size);
 
-   /* Check the controller "EATA" signature */
-   if (info.sign != EATA_SIG_BE) {
+	/* Check the controller "EATA" signature */
+	if (info.sign != EATA_SIG_BE) {
 #if defined(DEBUG_DETECT)
-      printk("%s: signature 0x%04x discarded.\n", name, info.sign);
+		printk("%s: signature 0x%04x discarded.\n", name, info.sign);
 #endif
-      goto freelock;
-      }
-
-   if (info.data_len < EATA_2_0A_SIZE) {
-      printk("%s: config structure size (%d bytes) too short, detaching.\n",
-             name, info.data_len);
-      goto freelock;
-      }
-   else if (info.data_len == EATA_2_0A_SIZE)
-      protocol_rev = 'A';
-   else if (info.data_len == EATA_2_0B_SIZE)
-      protocol_rev = 'B';
-   else
-      protocol_rev = 'C';
-
-   if (protocol_rev != 'A' && info.forcaddr) {
-      printk("%s: warning, port address has been forced.\n", name);
-      bus_type = "PCI";
-      is_pci = 1;
-      subversion = ESA;
-      }
-   else if (port_base > MAX_EISA_ADDR || (protocol_rev == 'C' && info.pci)) {
-      bus_type = "PCI";
-      is_pci = 1;
-      subversion = ESA;
-      }
-   else if (port_base >= MIN_EISA_ADDR || (protocol_rev == 'C' && info.eisa)) {
-      bus_type = "EISA";
-      subversion = ESA;
-      }
-   else if (protocol_rev == 'C' && !info.eisa && !info.pci) {
-      bus_type = "ISA";
-      subversion = ISA;
-      }
-   else if (port_base > MAX_ISA_ADDR) {
-      bus_type = "PCI";
-      is_pci = 1;
-      subversion = ESA;
-      }
-   else {
-      bus_type = "ISA";
-      subversion = ISA;
-      }
-
-   if (!info.haaval || info.ata) {
-      printk("%s: address 0x%03lx, unusable %s board (%d%d), detaching.\n",
-             name, port_base, bus_type, info.haaval, info.ata);
-      goto freelock;
-      }
-
-   if (info.drqvld) {
-
-      if (subversion ==  ESA)
-         printk("%s: warning, weird %s board using DMA.\n", name, bus_type);
-
-      subversion = ISA;
-      dma_channel = dma_channel_table[3 - info.drqx];
-      }
-   else {
-
-      if (subversion ==  ISA)
-         printk("%s: warning, weird %s board not using DMA.\n", name, bus_type);
-
-      subversion = ESA;
-      dma_channel = NO_DMA;
-      }
-
-   if (!info.dmasup)
-      printk("%s: warning, DMA protocol support not asserted.\n", name);
-
-   irq = info.irq;
-
-   if (subversion == ESA && !info.irq_tr)
-      printk("%s: warning, LEVEL triggering is suggested for IRQ %u.\n",
-             name, irq);
-
-   if (is_pci) {
-      pdev = get_pci_dev(port_base);
-      if (!pdev)
-         printk("%s: warning, failed to get pci_dev structure.\n", name);
-      }
-   else
-      pdev = NULL;
-
-   if (pdev && (irq != pdev->irq)) {
-      printk("%s: IRQ %u mapped to IO-APIC IRQ %u.\n", name, irq, pdev->irq);
-      irq = pdev->irq;
-      }
-
-   /* Board detected, allocate its IRQ */
-   if (request_irq(irq, do_interrupt_handler,
-             SA_INTERRUPT | ((subversion == ESA) ? SA_SHIRQ : 0),
-             driver_name, (void *) &sha[j])) {
-      printk("%s: unable to allocate IRQ %u, detaching.\n", name, irq);
-      goto freelock;
-      }
-
-   if (subversion == ISA && request_dma(dma_channel, driver_name)) {
-      printk("%s: unable to allocate DMA channel %u, detaching.\n",
-             name, dma_channel);
-      goto freeirq;
-      }
+		goto freelock;
+	}
 
+	if (info.data_len < EATA_2_0A_SIZE) {
+		printk
+		    ("%s: config structure size (%d bytes) too short, detaching.\n",
+		     name, info.data_len);
+		goto freelock;
+	} else if (info.data_len == EATA_2_0A_SIZE)
+		protocol_rev = 'A';
+	else if (info.data_len == EATA_2_0B_SIZE)
+		protocol_rev = 'B';
+	else
+		protocol_rev = 'C';
+
+	if (protocol_rev != 'A' && info.forcaddr) {
+		printk("%s: warning, port address has been forced.\n", name);
+		bus_type = "PCI";
+		is_pci = 1;
+		subversion = ESA;
+	} else if (port_base > MAX_EISA_ADDR
+		   || (protocol_rev == 'C' && info.pci)) {
+		bus_type = "PCI";
+		is_pci = 1;
+		subversion = ESA;
+	} else if (port_base >= MIN_EISA_ADDR
+		   || (protocol_rev == 'C' && info.eisa)) {
+		bus_type = "EISA";
+		subversion = ESA;
+	} else if (protocol_rev == 'C' && !info.eisa && !info.pci) {
+		bus_type = "ISA";
+		subversion = ISA;
+	} else if (port_base > MAX_ISA_ADDR) {
+		bus_type = "PCI";
+		is_pci = 1;
+		subversion = ESA;
+	} else {
+		bus_type = "ISA";
+		subversion = ISA;
+	}
+
+	if (!info.haaval || info.ata) {
+		printk
+		    ("%s: address 0x%03lx, unusable %s board (%d%d), detaching.\n",
+		     name, port_base, bus_type, info.haaval, info.ata);
+		goto freelock;
+	}
+
+	if (info.drqvld) {
+		if (subversion == ESA)
+			printk("%s: warning, weird %s board using DMA.\n", name,
+			       bus_type);
+
+		subversion = ISA;
+		dma_channel = dma_channel_table[3 - info.drqx];
+	} else {
+		if (subversion == ISA)
+			printk("%s: warning, weird %s board not using DMA.\n",
+			       name, bus_type);
+
+		subversion = ESA;
+		dma_channel = NO_DMA;
+	}
+
+	if (!info.dmasup)
+		printk("%s: warning, DMA protocol support not asserted.\n",
+		       name);
+
+	irq = info.irq;
+
+	if (subversion == ESA && !info.irq_tr)
+		printk
+		    ("%s: warning, LEVEL triggering is suggested for IRQ %u.\n",
+		     name, irq);
+
+	if (is_pci) {
+		pdev = get_pci_dev(port_base);
+		if (!pdev)
+			printk
+			    ("%s: warning, failed to get pci_dev structure.\n",
+			     name);
+	} else
+		pdev = NULL;
+
+	if (pdev && (irq != pdev->irq)) {
+		printk("%s: IRQ %u mapped to IO-APIC IRQ %u.\n", name, irq,
+		       pdev->irq);
+		irq = pdev->irq;
+	}
+
+	/* Board detected, allocate its IRQ */
+	if (request_irq(irq, do_interrupt_handler,
+			SA_INTERRUPT | ((subversion == ESA) ? SA_SHIRQ : 0),
+			driver_name, (void *)&sha[j])) {
+		printk("%s: unable to allocate IRQ %u, detaching.\n", name,
+		       irq);
+		goto freelock;
+	}
+
+	if (subversion == ISA && request_dma(dma_channel, driver_name)) {
+		printk("%s: unable to allocate DMA channel %u, detaching.\n",
+		       name, dma_channel);
+		goto freeirq;
+	}
 #if defined(FORCE_CONFIG)
-   {
-   struct eata_config *cf;
-   dma_addr_t cf_dma_addr;
-
-   cf = pci_alloc_consistent(pdev, sizeof(struct eata_config), &cf_dma_addr);
-
-   if (!cf) {
-      printk("%s: config, pci_alloc_consistent failed, detaching.\n", name);
-      goto freedma;
-      }
-
-   /* Set board configuration */
-   memset((char *)cf, 0, sizeof(struct eata_config));
-   cf->len = (ushort) H2DEV16((ushort)510);
-   cf->ocena = 1;
-
-   if (do_dma(port_base, cf_dma_addr, SET_CONFIG_DMA)) {
-      printk("%s: busy timeout sending configuration, detaching.\n", name);
-      pci_free_consistent(pdev, sizeof(struct eata_config), cf, cf_dma_addr);
-      goto freedma;
-      }
-
-   }
-#endif
-
-   spin_unlock_irq(&driver_lock);
-   sh[j] = scsi_register(tpnt, sizeof(struct hostdata));
-   spin_lock_irq(&driver_lock);
-
-   if (sh[j] == NULL) {
-      printk("%s: unable to register host, detaching.\n", name);
-      goto freedma;
-      }
-
-   sh[j]->io_port = port_base;
-   sh[j]->unique_id = port_base;
-   sh[j]->n_io_port = REGION_SIZE;
-   sh[j]->dma_channel = dma_channel;
-   sh[j]->irq = irq;
-   sh[j]->sg_tablesize = (ushort) info.scatt_size;
-   sh[j]->this_id = (ushort) info.host_addr[3];
-   sh[j]->can_queue = (ushort) info.queue_size;
-   sh[j]->cmd_per_lun = MAX_CMD_PER_LUN;
-   memset(HD(j), 0, sizeof(struct hostdata));
-   HD(j)->subversion = subversion;
-   HD(j)->protocol_rev = protocol_rev;
-   HD(j)->is_pci = is_pci;
-   HD(j)->pdev = pdev;
-   HD(j)->board_number = j;
-
-   if (HD(j)->subversion == ESA)
-      sh[j]->unchecked_isa_dma = 0;
-   else {
-      unsigned long flags;
-      sh[j]->unchecked_isa_dma = 1;
-
-      flags=claim_dma_lock();
-      disable_dma(dma_channel);
-      clear_dma_ff(dma_channel);
-      set_dma_mode(dma_channel, DMA_MODE_CASCADE);
-      enable_dma(dma_channel);
-      release_dma_lock(flags);
-
-      }
-
-   strcpy(BN(j), name);
-
-   /* DPT PM2012 does not allow to detect sg_tablesize correctly */
-   if (sh[j]->sg_tablesize > MAX_SGLIST || sh[j]->sg_tablesize < 2) {
-      printk("%s: detect, wrong n. of SG lists %d, fixed.\n",
-             BN(j), sh[j]->sg_tablesize);
-      sh[j]->sg_tablesize = MAX_SGLIST;
-      }
-
-   /* DPT PM2012 does not allow to detect can_queue correctly */
-   if (sh[j]->can_queue > MAX_MAILBOXES || sh[j]->can_queue  < 2) {
-      printk("%s: detect, wrong n. of mbox %d, fixed.\n",
-             BN(j), sh[j]->can_queue);
-      sh[j]->can_queue = MAX_MAILBOXES;
-      }
-
-   if (protocol_rev != 'A') {
-
-      if (info.max_chan > 0 && info.max_chan < MAX_CHANNEL)
-         sh[j]->max_channel = info.max_chan;
-
-      if (info.max_id > 7 && info.max_id < MAX_TARGET)
-         sh[j]->max_id = info.max_id + 1;
-
-      if (info.large_sg && sh[j]->sg_tablesize == MAX_SGLIST)
-         sh[j]->sg_tablesize = MAX_LARGE_SGLIST;
-      }
-
-   if (protocol_rev == 'C') {
-
-      if (info.max_lun > 7 && info.max_lun < MAX_LUN)
-         sh[j]->max_lun = info.max_lun + 1;
-      }
-
-   if (dma_channel == NO_DMA) sprintf(dma_name, "%s", "BMST");
-   else                       sprintf(dma_name, "DMA %u", dma_channel);
-
-   spin_unlock_irq(&driver_lock);
-
-   for (i = 0; i < sh[j]->can_queue; i++)
-      HD(j)->cp[i].cp_dma_addr = pci_map_single(HD(j)->pdev,
-            &HD(j)->cp[i], sizeof(struct mscp), PCI_DMA_BIDIRECTIONAL);
-
-   for (i = 0; i < sh[j]->can_queue; i++)
-      if (! ((&HD(j)->cp[i])->sglist = kmalloc(
-            sh[j]->sg_tablesize * sizeof(struct sg_list),
-            (sh[j]->unchecked_isa_dma ? GFP_DMA : 0) | GFP_ATOMIC))) {
-         printk("%s: kmalloc SGlist failed, mbox %d, detaching.\n", BN(j), i);
-         goto release;
-         }
-
-   if (! (HD(j)->sp_cpu_addr = pci_alloc_consistent(HD(j)->pdev,
-         sizeof(struct mssp), &HD(j)->sp_dma_addr))) {
-      printk("%s: pci_alloc_consistent failed, detaching.\n", BN(j));
-      goto release;
-      }
-
-   if (max_queue_depth > MAX_TAGGED_CMD_PER_LUN)
-       max_queue_depth = MAX_TAGGED_CMD_PER_LUN;
-
-   if (max_queue_depth < MAX_CMD_PER_LUN) max_queue_depth = MAX_CMD_PER_LUN;
-
-   if (tag_mode != TAG_DISABLED && tag_mode != TAG_SIMPLE)
-      tag_mode = TAG_ORDERED;
-
-   if (j == 0) {
-      printk("EATA/DMA 2.0x: Copyright (C) 1994-2003 Dario Ballabio.\n");
-      printk("%s config options -> tm:%d, lc:%c, mq:%d, rs:%c, et:%c, "\
-             "ip:%c, ep:%c, pp:%c.\n", driver_name, tag_mode,
-             YESNO(linked_comm), max_queue_depth, YESNO(rev_scan),
-             YESNO(ext_tran), YESNO(isa_probe), YESNO(eisa_probe),
-             YESNO(pci_probe));
-      }
-
-   printk("%s: 2.0%c, %s 0x%03lx, IRQ %u, %s, SG %d, MB %d.\n",
-          BN(j), HD(j)->protocol_rev, bus_type, (unsigned long)sh[j]->io_port,
-          sh[j]->irq, dma_name, sh[j]->sg_tablesize, sh[j]->can_queue);
-
-   if (sh[j]->max_id > 8 || sh[j]->max_lun > 8)
-      printk("%s: wide SCSI support enabled, max_id %u, max_lun %u.\n",
-             BN(j), sh[j]->max_id, sh[j]->max_lun);
-
-   for (i = 0; i <= sh[j]->max_channel; i++)
-      printk("%s: SCSI channel %u enabled, host target ID %d.\n",
-             BN(j), i, info.host_addr[3 - i]);
+	{
+		struct eata_config *cf;
+		dma_addr_t cf_dma_addr;
+
+		cf = pci_alloc_consistent(pdev, sizeof(struct eata_config),
+					  &cf_dma_addr);
+
+		if (!cf) {
+			printk
+			    ("%s: config, pci_alloc_consistent failed, detaching.\n",
+			     name);
+			goto freedma;
+		}
+
+		/* Set board configuration */
+		memset((char *)cf, 0, sizeof(struct eata_config));
+		cf->len = (ushort) H2DEV16((ushort) 510);
+		cf->ocena = 1;
+
+		if (do_dma(port_base, cf_dma_addr, SET_CONFIG_DMA)) {
+			printk
+			    ("%s: busy timeout sending configuration, detaching.\n",
+			     name);
+			pci_free_consistent(pdev, sizeof(struct eata_config),
+					    cf, cf_dma_addr);
+			goto freedma;
+		}
+
+	}
+#endif
+
+	spin_unlock_irq(&driver_lock);
+	sh[j] = shost = scsi_register(tpnt, sizeof(struct hostdata));
+	spin_lock_irq(&driver_lock);
+
+	if (shost == NULL) {
+		printk("%s: unable to register host, detaching.\n", name);
+		goto freedma;
+	}
+
+	shost->io_port = port_base;
+	shost->unique_id = port_base;
+	shost->n_io_port = REGION_SIZE;
+	shost->dma_channel = dma_channel;
+	shost->irq = irq;
+	shost->sg_tablesize = (ushort) info.scatt_size;
+	shost->this_id = (ushort) info.host_addr[3];
+	shost->can_queue = (ushort) info.queue_size;
+	shost->cmd_per_lun = MAX_CMD_PER_LUN;
+
+	ha = (struct hostdata *)shost->hostdata;
+	
+	memset(ha, 0, sizeof(struct hostdata));
+	ha->subversion = subversion;
+	ha->protocol_rev = protocol_rev;
+	ha->is_pci = is_pci;
+	ha->pdev = pdev;
+	ha->board_number = j;
+
+	if (ha->subversion == ESA)
+		shost->unchecked_isa_dma = 0;
+	else {
+		unsigned long flags;
+		shost->unchecked_isa_dma = 1;
+
+		flags = claim_dma_lock();
+		disable_dma(dma_channel);
+		clear_dma_ff(dma_channel);
+		set_dma_mode(dma_channel, DMA_MODE_CASCADE);
+		enable_dma(dma_channel);
+		release_dma_lock(flags);
+
+	}
+
+	strcpy(ha->board_name, name);
+
+	/* DPT PM2012 does not allow to detect sg_tablesize correctly */
+	if (shost->sg_tablesize > MAX_SGLIST || shost->sg_tablesize < 2) {
+		printk("%s: detect, wrong n. of SG lists %d, fixed.\n",
+		       ha->board_name, shost->sg_tablesize);
+		shost->sg_tablesize = MAX_SGLIST;
+	}
+
+	/* DPT PM2012 does not allow to detect can_queue correctly */
+	if (shost->can_queue > MAX_MAILBOXES || shost->can_queue < 2) {
+		printk("%s: detect, wrong n. of mbox %d, fixed.\n",
+		       ha->board_name, shost->can_queue);
+		shost->can_queue = MAX_MAILBOXES;
+	}
+
+	if (protocol_rev != 'A') {
+		if (info.max_chan > 0 && info.max_chan < MAX_CHANNEL)
+			shost->max_channel = info.max_chan;
+
+		if (info.max_id > 7 && info.max_id < MAX_TARGET)
+			shost->max_id = info.max_id + 1;
+
+		if (info.large_sg && shost->sg_tablesize == MAX_SGLIST)
+			shost->sg_tablesize = MAX_LARGE_SGLIST;
+	}
+
+	if (protocol_rev == 'C') {
+		if (info.max_lun > 7 && info.max_lun < MAX_LUN)
+			shost->max_lun = info.max_lun + 1;
+	}
+
+	if (dma_channel == NO_DMA)
+		sprintf(dma_name, "%s", "BMST");
+	else
+		sprintf(dma_name, "DMA %u", dma_channel);
+
+	spin_unlock_irq(&driver_lock);
+
+	for (i = 0; i < shost->can_queue; i++)
+		ha->cp[i].cp_dma_addr = pci_map_single(ha->pdev,
+							  &ha->cp[i],
+							  sizeof(struct mscp),
+							  PCI_DMA_BIDIRECTIONAL);
+
+	for (i = 0; i < shost->can_queue; i++) {
+		size_t sz = shost->sg_tablesize *sizeof(struct sg_list);
+		unsigned int gfp_mask = (shost->unchecked_isa_dma ? GFP_DMA : 0) | GFP_ATOMIC;
+		ha->cp[i].sglist = kmalloc(sz, gfp_mask);
+		if (!ha->cp[i].sglist) {
+			printk
+			    ("%s: kmalloc SGlist failed, mbox %d, detaching.\n",
+			     ha->board_name, i);
+			goto release;
+		}
+	}
+
+	if (!(ha->sp_cpu_addr = pci_alloc_consistent(ha->pdev,
+							sizeof(struct mssp),
+							&ha->sp_dma_addr))) {
+		printk("%s: pci_alloc_consistent failed, detaching.\n", ha->board_name);
+		goto release;
+	}
+
+	if (max_queue_depth > MAX_TAGGED_CMD_PER_LUN)
+		max_queue_depth = MAX_TAGGED_CMD_PER_LUN;
+
+	if (max_queue_depth < MAX_CMD_PER_LUN)
+		max_queue_depth = MAX_CMD_PER_LUN;
+
+	if (tag_mode != TAG_DISABLED && tag_mode != TAG_SIMPLE)
+		tag_mode = TAG_ORDERED;
+
+	if (j == 0) {
+		printk
+		    ("EATA/DMA 2.0x: Copyright (C) 1994-2003 Dario Ballabio.\n");
+		printk
+		    ("%s config options -> tm:%d, lc:%c, mq:%d, rs:%c, et:%c, "
+		     "ip:%c, ep:%c, pp:%c.\n", driver_name, tag_mode,
+		     YESNO(linked_comm), max_queue_depth, YESNO(rev_scan),
+		     YESNO(ext_tran), YESNO(isa_probe), YESNO(eisa_probe),
+		     YESNO(pci_probe));
+	}
+
+	printk("%s: 2.0%c, %s 0x%03lx, IRQ %u, %s, SG %d, MB %d.\n",
+	       ha->board_name, ha->protocol_rev, bus_type,
+	       (unsigned long)shost->io_port, shost->irq, dma_name,
+	       shost->sg_tablesize, shost->can_queue);
+
+	if (shost->max_id > 8 || shost->max_lun > 8)
+		printk
+		    ("%s: wide SCSI support enabled, max_id %u, max_lun %u.\n",
+		     ha->board_name, shost->max_id, shost->max_lun);
+
+	for (i = 0; i <= shost->max_channel; i++)
+		printk("%s: SCSI channel %u enabled, host target ID %d.\n",
+		       ha->board_name, i, info.host_addr[3 - i]);
 
 #if defined(DEBUG_DETECT)
-   printk("%s: Vers. 0x%x, ocs %u, tar %u, trnxfr %u, more %u, SYNC 0x%x, "\
-          "sec. %u, infol %d, cpl %d spl %d.\n", name, info.version,
-          info.ocsena, info.tarsup, info.trnxfr, info.morsup, info.sync,
-          info.second, info.data_len, info.cp_len,
-          info.sp_len);
-
-   if (protocol_rev == 'B' || protocol_rev == 'C')
-      printk("%s: isaena %u, forcaddr %u, max_id %u, max_chan %u, "\
-             "large_sg %u, res1 %u.\n", name, info.isaena, info.forcaddr,
-             info.max_id, info.max_chan, info.large_sg, info.res1);
-
-   if (protocol_rev == 'C')
-      printk("%s: max_lun %u, m1 %u, idquest %u, pci %u, eisa %u, "\
-             "raidnum %u.\n", name, info.max_lun, info.m1, info.idquest,
-             info.pci, info.eisa, info.raidnum);
-#endif
-
-   if (HD(j)->pdev) {
-      pci_set_master(HD(j)->pdev);
-      if (pci_set_dma_mask(HD(j)->pdev, 0xffffffff))
-         printk("%s: warning, pci_set_dma_mask failed.\n", BN(j));
-      }
-
-   return 1;
-
-freedma:
-   if (subversion == ISA) free_dma(dma_channel);
-freeirq:
-   free_irq(irq, &sha[j]);
-freelock:
-   spin_unlock_irq(&driver_lock);
-   release_region(port_base, REGION_SIZE);
-fail:
-   return 0;
-
-release:
-   eata2x_release(sh[j]);
-   return 0;
-}
-
-static void internal_setup(char *str, int *ints) {
-   int i, argc = ints[0];
-   char *cur = str, *pc;
-
-   if (argc > 0) {
-
-      if (argc > MAX_INT_PARAM) argc = MAX_INT_PARAM;
-
-      for (i = 0; i < argc; i++) io_port[i] = ints[i + 1];
-
-      io_port[i] = 0;
-      setup_done = 1;
-      }
-
-   while (cur && (pc = strchr(cur, ':'))) {
-      int val = 0, c = *++pc;
-
-      if (c == 'n' || c == 'N') val = 0;
-      else if (c == 'y' || c == 'Y') val = 1;
-      else val = (int) simple_strtoul(pc, NULL, 0);
-
-      if (!strncmp(cur, "lc:", 3)) linked_comm = val;
-      else if (!strncmp(cur, "tm:", 3)) tag_mode = val;
-      else if (!strncmp(cur, "tc:", 3)) tag_mode = val;
-      else if (!strncmp(cur, "mq:", 3))  max_queue_depth = val;
-      else if (!strncmp(cur, "ls:", 3))  link_statistics = val;
-      else if (!strncmp(cur, "et:", 3))  ext_tran = val;
-      else if (!strncmp(cur, "rs:", 3))  rev_scan = val;
-      else if (!strncmp(cur, "ip:", 3))  isa_probe = val;
-      else if (!strncmp(cur, "ep:", 3))  eisa_probe = val;
-      else if (!strncmp(cur, "pp:", 3))  pci_probe = val;
-
-      if ((cur = strchr(cur, ','))) ++cur;
-      }
-
-   return;
-}
-
-static int option_setup(char *str) {
-   int ints[MAX_INT_PARAM];
-   char *cur = str;
-   int i = 1;
-
-   while (cur && isdigit(*cur) && i <= MAX_INT_PARAM) {
-      ints[i++] = simple_strtoul(cur, NULL, 0);
-
-      if ((cur = strchr(cur, ',')) != NULL) cur++;
-   }
-
-   ints[0] = i - 1;
-   internal_setup(cur, ints);
-   return 1;
+	printk("%s: Vers. 0x%x, ocs %u, tar %u, trnxfr %u, more %u, SYNC 0x%x, "
+	       "sec. %u, infol %d, cpl %d spl %d.\n", name, info.version,
+	       info.ocsena, info.tarsup, info.trnxfr, info.morsup, info.sync,
+	       info.second, info.data_len, info.cp_len, info.sp_len);
+
+	if (protocol_rev == 'B' || protocol_rev == 'C')
+		printk("%s: isaena %u, forcaddr %u, max_id %u, max_chan %u, "
+		       "large_sg %u, res1 %u.\n", name, info.isaena,
+		       info.forcaddr, info.max_id, info.max_chan, info.large_sg,
+		       info.res1);
+
+	if (protocol_rev == 'C')
+		printk("%s: max_lun %u, m1 %u, idquest %u, pci %u, eisa %u, "
+		       "raidnum %u.\n", name, info.max_lun, info.m1,
+		       info.idquest, info.pci, info.eisa, info.raidnum);
+#endif
+
+	if (ha->pdev) {
+		pci_set_master(ha->pdev);
+		if (pci_set_dma_mask(ha->pdev, 0xffffffff))
+			printk("%s: warning, pci_set_dma_mask failed.\n",
+			       ha->board_name);
+	}
+
+	return 1;
+
+      freedma:
+	if (subversion == ISA)
+		free_dma(dma_channel);
+      freeirq:
+	free_irq(irq, &sha[j]);
+      freelock:
+	spin_unlock_irq(&driver_lock);
+	release_region(port_base, REGION_SIZE);
+      fail:
+	return 0;
+
+      release:
+	eata2x_release(shost);
+	return 0;
+}
+
+static void internal_setup(char *str, int *ints)
+{
+	int i, argc = ints[0];
+	char *cur = str, *pc;
+
+	if (argc > 0) {
+		if (argc > MAX_INT_PARAM)
+			argc = MAX_INT_PARAM;
+
+		for (i = 0; i < argc; i++)
+			io_port[i] = ints[i + 1];
+
+		io_port[i] = 0;
+		setup_done = 1;
+	}
+
+	while (cur && (pc = strchr(cur, ':'))) {
+		int val = 0, c = *++pc;
+
+		if (c == 'n' || c == 'N')
+			val = 0;
+		else if (c == 'y' || c == 'Y')
+			val = 1;
+		else
+			val = (int)simple_strtoul(pc, NULL, 0);
+
+		if (!strncmp(cur, "lc:", 3))
+			linked_comm = val;
+		else if (!strncmp(cur, "tm:", 3))
+			tag_mode = val;
+		else if (!strncmp(cur, "tc:", 3))
+			tag_mode = val;
+		else if (!strncmp(cur, "mq:", 3))
+			max_queue_depth = val;
+		else if (!strncmp(cur, "ls:", 3))
+			link_statistics = val;
+		else if (!strncmp(cur, "et:", 3))
+			ext_tran = val;
+		else if (!strncmp(cur, "rs:", 3))
+			rev_scan = val;
+		else if (!strncmp(cur, "ip:", 3))
+			isa_probe = val;
+		else if (!strncmp(cur, "ep:", 3))
+			eisa_probe = val;
+		else if (!strncmp(cur, "pp:", 3))
+			pci_probe = val;
+
+		if ((cur = strchr(cur, ',')))
+			++cur;
+	}
+
+	return;
+}
+
+static int option_setup(char *str)
+{
+	int ints[MAX_INT_PARAM];
+	char *cur = str;
+	int i = 1;
+
+	while (cur && isdigit(*cur) && i <= MAX_INT_PARAM) {
+		ints[i++] = simple_strtoul(cur, NULL, 0);
+
+		if ((cur = strchr(cur, ',')) != NULL)
+			cur++;
+	}
+
+	ints[0] = i - 1;
+	internal_setup(cur, ints);
+	return 1;
 }
 
-static void add_pci_ports(void) {
-
+static void add_pci_ports(void)
+{
 #if defined(CONFIG_PCI)
+	unsigned int addr, k;
+	struct pci_dev *dev = NULL;
 
-   unsigned int addr, k;
-
-   struct pci_dev *dev = NULL;
-
-   for (k = 0; k < MAX_PCI; k++) {
-
-      if (!(dev = pci_get_class(PCI_CLASS_STORAGE_SCSI << 8, dev))) break;
+	for (k = 0; k < MAX_PCI; k++) {
 
-      if (pci_enable_device (dev)) {
+		if (!(dev = pci_get_class(PCI_CLASS_STORAGE_SCSI << 8, dev)))
+			break;
 
+		if (pci_enable_device(dev)) {
 #if defined(DEBUG_PCI_DETECT)
-         printk("%s: detect, bus %d, devfn 0x%x, pci_enable_device failed.\n",
-                driver_name, dev->bus->number, dev->devfn);
+			printk
+			    ("%s: detect, bus %d, devfn 0x%x, pci_enable_device failed.\n",
+			     driver_name, dev->bus->number, dev->devfn);
 #endif
 
-         continue;
-         }
+			continue;
+		}
 
-      addr = pci_resource_start (dev, 0);
+		addr = pci_resource_start(dev, 0);
 
 #if defined(DEBUG_PCI_DETECT)
-      printk("%s: detect, seq. %d, bus %d, devfn 0x%x, addr 0x%x.\n",
-             driver_name, k, dev->bus->number, dev->devfn, addr);
+		printk("%s: detect, seq. %d, bus %d, devfn 0x%x, addr 0x%x.\n",
+		       driver_name, k, dev->bus->number, dev->devfn, addr);
 #endif
 
-      /* Order addresses according to rev_scan value */
-      io_port[MAX_INT_PARAM + (rev_scan ? (MAX_PCI - k) : (1 + k))] =
-             addr + PCI_BASE_ADDRESS_0;
-      }
+		/* Order addresses according to rev_scan value */
+		io_port[MAX_INT_PARAM + (rev_scan ? (MAX_PCI - k) : (1 + k))] =
+		    addr + PCI_BASE_ADDRESS_0;
+	}
 
-   pci_dev_put(dev);
-#endif /* end CONFIG_PCI */
-
-   return;
+	pci_dev_put(dev);
+#endif				/* end CONFIG_PCI */
 }
 
-static int eata2x_detect(struct scsi_host_template *tpnt) {
-   unsigned int j = 0, k;
+static int eata2x_detect(struct scsi_host_template *tpnt)
+{
+	unsigned int j = 0, k;
 
-   tpnt->proc_name = "eata2x";
+	tpnt->proc_name = "eata2x";
 
-   if(strlen(boot_options)) option_setup(boot_options);
+	if (strlen(boot_options))
+		option_setup(boot_options);
 
 #if defined(MODULE)
-   /* io_port could have been modified when loading as a module */
-   if(io_port[0] != SKIP) {
-      setup_done = 1;
-      io_port[MAX_INT_PARAM] = 0;
-      }
-#endif
-
-   for (k = 0; k < MAX_BOARDS + 1; k++) sh[k] = NULL;
-
-   for (k = MAX_INT_PARAM; io_port[k]; k++)
-      if (io_port[k] == SKIP) continue;
-      else if (io_port[k] <= MAX_ISA_ADDR) {
-         if (!isa_probe) io_port[k] = SKIP;
-         }
-      else if (io_port[k] >= MIN_EISA_ADDR && io_port[k] <= MAX_EISA_ADDR) {
-         if (!eisa_probe) io_port[k] = SKIP;
-         }
-
-   if (pci_probe) {
-      if (!setup_done) add_pci_ports();
-      else          enable_pci_ports();
-      }
-
-   for (k = 0; io_port[k]; k++) {
-
-      if (io_port[k] == SKIP) continue;
-
-      if (j < MAX_BOARDS && port_detect(io_port[k], j, tpnt)) j++;
-      }
-
-   num_boards = j;
-   return j;
-}
-
-static void map_dma(unsigned int i, unsigned int j) {
-   unsigned int k, count, pci_dir;
-   struct scatterlist *sgpnt;
-   struct mscp *cpp;
-   struct scsi_cmnd *SCpnt;
-
-   cpp = &HD(j)->cp[i]; SCpnt = cpp->SCpnt;
-   pci_dir = SCpnt->sc_data_direction;
-
-   if (SCpnt->sense_buffer)
-      cpp->sense_addr = H2DEV(pci_map_single(HD(j)->pdev, SCpnt->sense_buffer,
-                           sizeof SCpnt->sense_buffer, PCI_DMA_FROMDEVICE));
-
-   cpp->sense_len = sizeof SCpnt->sense_buffer;
-
-   if (!SCpnt->use_sg) {
+	/* io_port could have been modified when loading as a module */
+	if (io_port[0] != SKIP) {
+		setup_done = 1;
+		io_port[MAX_INT_PARAM] = 0;
+	}
+#endif
+
+	for (k = MAX_INT_PARAM; io_port[k]; k++)
+		if (io_port[k] == SKIP)
+			continue;
+		else if (io_port[k] <= MAX_ISA_ADDR) {
+			if (!isa_probe)
+				io_port[k] = SKIP;
+		} else if (io_port[k] >= MIN_EISA_ADDR
+			   && io_port[k] <= MAX_EISA_ADDR) {
+			if (!eisa_probe)
+				io_port[k] = SKIP;
+		}
+
+	if (pci_probe) {
+		if (!setup_done)
+			add_pci_ports();
+		else
+			enable_pci_ports();
+	}
+
+	for (k = 0; io_port[k]; k++) {
+
+		if (io_port[k] == SKIP)
+			continue;
+
+		if (j < MAX_BOARDS && port_detect(io_port[k], j, tpnt))
+			j++;
+	}
+
+	num_boards = j;
+	return j;
+}
+
+static void map_dma(unsigned int i, struct hostdata *ha)
+{
+	unsigned int k, count, pci_dir;
+	struct scatterlist *sgpnt;
+	struct mscp *cpp;
+	struct scsi_cmnd *SCpnt;
+
+	cpp = &ha->cp[i];
+	SCpnt = cpp->SCpnt;
+	pci_dir = SCpnt->sc_data_direction;
+
+	if (SCpnt->sense_buffer)
+		cpp->sense_addr =
+		    H2DEV(pci_map_single(ha->pdev, SCpnt->sense_buffer,
+			   sizeof SCpnt->sense_buffer, PCI_DMA_FROMDEVICE));
+
+	cpp->sense_len = sizeof SCpnt->sense_buffer;
+
+	if (!SCpnt->use_sg) {
+
+		/* If we get here with PCI_DMA_NONE, pci_map_single triggers a BUG() */
+		if (!SCpnt->request_bufflen)
+			pci_dir = PCI_DMA_BIDIRECTIONAL;
+
+		if (SCpnt->request_buffer)
+			cpp->data_address = H2DEV(pci_map_single(ha->pdev,
+								 SCpnt->
+								 request_buffer,
+								 SCpnt->
+								 request_bufflen,
+								 pci_dir));
+
+		cpp->data_len = H2DEV(SCpnt->request_bufflen);
+		return;
+	}
+
+	sgpnt = (struct scatterlist *)SCpnt->request_buffer;
+	count = pci_map_sg(ha->pdev, sgpnt, SCpnt->use_sg, pci_dir);
+
+	for (k = 0; k < count; k++) {
+		cpp->sglist[k].address = H2DEV(sg_dma_address(&sgpnt[k]));
+		cpp->sglist[k].num_bytes = H2DEV(sg_dma_len(&sgpnt[k]));
+	}
+
+	cpp->sg = 1;
+	cpp->data_address = H2DEV(pci_map_single(ha->pdev, cpp->sglist,
+						 SCpnt->use_sg *
+						 sizeof(struct sg_list),
+						 pci_dir));
+	cpp->data_len = H2DEV((SCpnt->use_sg * sizeof(struct sg_list)));
+}
+
+static void unmap_dma(unsigned int i, struct hostdata *ha)
+{
+	unsigned int pci_dir;
+	struct mscp *cpp;
+	struct scsi_cmnd *SCpnt;
+
+	cpp = &ha->cp[i];
+	SCpnt = cpp->SCpnt;
+	pci_dir = SCpnt->sc_data_direction;
+
+	if (DEV2H(cpp->sense_addr))
+		pci_unmap_single(ha->pdev, DEV2H(cpp->sense_addr),
+				 DEV2H(cpp->sense_len), PCI_DMA_FROMDEVICE);
+
+	if (SCpnt->use_sg)
+		pci_unmap_sg(ha->pdev, SCpnt->request_buffer, SCpnt->use_sg,
+			     pci_dir);
+
+	if (!DEV2H(cpp->data_len))
+		pci_dir = PCI_DMA_BIDIRECTIONAL;
+
+	if (DEV2H(cpp->data_address))
+		pci_unmap_single(ha->pdev, DEV2H(cpp->data_address),
+				 DEV2H(cpp->data_len), pci_dir);
+}
+
+static void sync_dma(unsigned int i, struct hostdata *ha)
+{
+	unsigned int pci_dir;
+	struct mscp *cpp;
+	struct scsi_cmnd *SCpnt;
+
+	cpp = &ha->cp[i];
+	SCpnt = cpp->SCpnt;
+	pci_dir = SCpnt->sc_data_direction;
+
+	if (DEV2H(cpp->sense_addr))
+		pci_dma_sync_single_for_cpu(ha->pdev, DEV2H(cpp->sense_addr),
+					    DEV2H(cpp->sense_len),
+					    PCI_DMA_FROMDEVICE);
+
+	if (SCpnt->use_sg)
+		pci_dma_sync_sg_for_cpu(ha->pdev, SCpnt->request_buffer,
+					SCpnt->use_sg, pci_dir);
+
+	if (!DEV2H(cpp->data_len))
+		pci_dir = PCI_DMA_BIDIRECTIONAL;
+
+	if (DEV2H(cpp->data_address))
+		pci_dma_sync_single_for_cpu(ha->pdev,
+					    DEV2H(cpp->data_address),
+					    DEV2H(cpp->data_len), pci_dir);
+}
+
+static void scsi_to_dev_dir(unsigned int i, struct hostdata *ha)
+{
+	unsigned int k;
+
+	static const unsigned char data_out_cmds[] = {
+		0x0a, 0x2a, 0x15, 0x55, 0x04, 0x07, 0x18, 0x1d, 0x24, 0x2e,
+		0x30, 0x31, 0x32, 0x38, 0x39, 0x3a, 0x3b, 0x3d, 0x3f, 0x40,
+		0x41, 0x4c, 0xaa, 0xae, 0xb0, 0xb1, 0xb2, 0xb6, 0xea, 0x1b, 0x5d
+	};
+
+	static const unsigned char data_none_cmds[] = {
+		0x01, 0x0b, 0x10, 0x11, 0x13, 0x16, 0x17, 0x19, 0x2b, 0x1e,
+		0x2c, 0xac, 0x2f, 0xaf, 0x33, 0xb3, 0x35, 0x36, 0x45, 0x47,
+		0x48, 0x49, 0xa9, 0x4b, 0xa5, 0xa6, 0xb5, 0x00
+	};
+
+	struct mscp *cpp;
+	struct scsi_cmnd *SCpnt;
+
+	cpp = &ha->cp[i];
+	SCpnt = cpp->SCpnt;
+
+	if (SCpnt->sc_data_direction == DMA_FROM_DEVICE) {
+		cpp->din = 1;
+		cpp->dout = 0;
+		return;
+	} else if (SCpnt->sc_data_direction == DMA_TO_DEVICE) {
+		cpp->din = 0;
+		cpp->dout = 1;
+		return;
+	} else if (SCpnt->sc_data_direction == DMA_NONE) {
+		cpp->din = 0;
+		cpp->dout = 0;
+		return;
+	}
+
+	if (SCpnt->sc_data_direction != DMA_BIDIRECTIONAL)
+		panic("%s: qcomm, invalid SCpnt->sc_data_direction.\n",
+				ha->board_name);
+
+	for (k = 0; k < ARRAY_SIZE(data_out_cmds); k++)
+		if (SCpnt->cmnd[0] == data_out_cmds[k]) {
+			cpp->dout = 1;
+			break;
+		}
+
+	if ((cpp->din = !cpp->dout))
+		for (k = 0; k < ARRAY_SIZE(data_none_cmds); k++)
+			if (SCpnt->cmnd[0] == data_none_cmds[k]) {
+				cpp->din = 0;
+				break;
+			}
+
+}
+
+static int eata2x_queuecommand(struct scsi_cmnd *SCpnt,
+			       void (*done) (struct scsi_cmnd *))
+{
+	struct Scsi_Host *shost = SCpnt->device->host;
+	struct hostdata *ha = (struct hostdata *)shost->hostdata;
+	unsigned int i, k;
+	struct mscp *cpp;
+
+	if (SCpnt->host_scribble)
+		panic("%s: qcomm, pid %ld, SCpnt %p already active.\n",
+		      ha->board_name, SCpnt->pid, SCpnt);
+
+	/* i is the mailbox number, look for the first free mailbox
+	   starting from last_cp_used */
+	i = ha->last_cp_used + 1;
+
+	for (k = 0; k < shost->can_queue; k++, i++) {
+		if (i >= shost->can_queue)
+			i = 0;
+		if (ha->cp_stat[i] == FREE) {
+			ha->last_cp_used = i;
+			break;
+		}
+	}
+
+	if (k == shost->can_queue) {
+		printk("%s: qcomm, no free mailbox.\n", ha->board_name);
+		return 1;
+	}
+
+	/* Set pointer to control packet structure */
+	cpp = &ha->cp[i];
+
+	memset(cpp, 0, sizeof(struct mscp) - CP_TAIL_SIZE);
+
+	/* Set pointer to status packet structure, Big Endian format */
+	cpp->sp_dma_addr = H2DEV(ha->sp_dma_addr);
+
+	SCpnt->scsi_done = done;
+	cpp->cpp_index = i;
+	SCpnt->host_scribble = (unsigned char *)&cpp->cpp_index;
+
+	if (do_trace)
+		printk("%s: qcomm, mbox %d, target %d.%d:%d, pid %ld.\n",
+		       ha->board_name, i, SCpnt->device->channel, SCpnt->device->id,
+		       SCpnt->device->lun, SCpnt->pid);
 
-      /* If we get here with PCI_DMA_NONE, pci_map_single triggers a BUG() */
-      if (!SCpnt->request_bufflen) pci_dir = PCI_DMA_BIDIRECTIONAL;
-
-      if (SCpnt->request_buffer)
-         cpp->data_address = H2DEV(pci_map_single(HD(j)->pdev,
-                  SCpnt->request_buffer, SCpnt->request_bufflen, pci_dir));
-
-      cpp->data_len = H2DEV(SCpnt->request_bufflen);
-      return;
-      }
-
-   sgpnt = (struct scatterlist *) SCpnt->request_buffer;
-   count = pci_map_sg(HD(j)->pdev, sgpnt, SCpnt->use_sg, pci_dir);
-
-   for (k = 0; k < count; k++) {
-      cpp->sglist[k].address = H2DEV(sg_dma_address(&sgpnt[k]));
-      cpp->sglist[k].num_bytes = H2DEV(sg_dma_len(&sgpnt[k]));
-      }
-
-   cpp->sg = 1;
-   cpp->data_address = H2DEV(pci_map_single(HD(j)->pdev, cpp->sglist,
-                             SCpnt->use_sg * sizeof(struct sg_list), pci_dir));
-   cpp->data_len = H2DEV((SCpnt->use_sg * sizeof(struct sg_list)));
-}
-
-static void unmap_dma(unsigned int i, unsigned int j) {
-   unsigned int pci_dir;
-   struct mscp *cpp;
-   struct scsi_cmnd *SCpnt;
-
-   cpp = &HD(j)->cp[i]; SCpnt = cpp->SCpnt;
-   pci_dir = SCpnt->sc_data_direction;
-
-   if (DEV2H(cpp->sense_addr))
-      pci_unmap_single(HD(j)->pdev, DEV2H(cpp->sense_addr),
-                       DEV2H(cpp->sense_len), PCI_DMA_FROMDEVICE);
-
-   if (SCpnt->use_sg)
-      pci_unmap_sg(HD(j)->pdev, SCpnt->request_buffer, SCpnt->use_sg, pci_dir);
-
-   if (!DEV2H(cpp->data_len)) pci_dir = PCI_DMA_BIDIRECTIONAL;
-
-   if (DEV2H(cpp->data_address))
-      pci_unmap_single(HD(j)->pdev, DEV2H(cpp->data_address),
-                       DEV2H(cpp->data_len), pci_dir);
-}
-
-static void sync_dma(unsigned int i, unsigned int j) {
-   unsigned int pci_dir;
-   struct mscp *cpp;
-   struct scsi_cmnd *SCpnt;
-
-   cpp = &HD(j)->cp[i]; SCpnt = cpp->SCpnt;
-   pci_dir = SCpnt->sc_data_direction;
-
-   if (DEV2H(cpp->sense_addr))
-      pci_dma_sync_single_for_cpu(HD(j)->pdev, DEV2H(cpp->sense_addr),
-                          DEV2H(cpp->sense_len), PCI_DMA_FROMDEVICE);
-
-   if (SCpnt->use_sg)
-      pci_dma_sync_sg_for_cpu(HD(j)->pdev, SCpnt->request_buffer,
-                         SCpnt->use_sg, pci_dir);
-
-   if (!DEV2H(cpp->data_len)) pci_dir = PCI_DMA_BIDIRECTIONAL;
-
-   if (DEV2H(cpp->data_address))
-      pci_dma_sync_single_for_cpu(HD(j)->pdev, DEV2H(cpp->data_address),
-                       DEV2H(cpp->data_len), pci_dir);
-}
-
-static void scsi_to_dev_dir(unsigned int i, unsigned int j) {
-   unsigned int k;
-
-   static const unsigned char data_out_cmds[] = {
-      0x0a, 0x2a, 0x15, 0x55, 0x04, 0x07, 0x18, 0x1d, 0x24, 0x2e,
-      0x30, 0x31, 0x32, 0x38, 0x39, 0x3a, 0x3b, 0x3d, 0x3f, 0x40,
-      0x41, 0x4c, 0xaa, 0xae, 0xb0, 0xb1, 0xb2, 0xb6, 0xea, 0x1b, 0x5d
-      };
-
-   static const unsigned char data_none_cmds[] = {
-      0x01, 0x0b, 0x10, 0x11, 0x13, 0x16, 0x17, 0x19, 0x2b, 0x1e,
-      0x2c, 0xac, 0x2f, 0xaf, 0x33, 0xb3, 0x35, 0x36, 0x45, 0x47,
-      0x48, 0x49, 0xa9, 0x4b, 0xa5, 0xa6, 0xb5, 0x00
-      };
-
-   struct mscp *cpp;
-   struct scsi_cmnd *SCpnt;
-
-   cpp = &HD(j)->cp[i]; SCpnt = cpp->SCpnt;
-
-   if (SCpnt->sc_data_direction == DMA_FROM_DEVICE) {
-      cpp->din  = 1;
-      cpp->dout = 0;
-      return;
-      }
-   else if (SCpnt->sc_data_direction == DMA_TO_DEVICE) {
-      cpp->din  = 0;
-      cpp->dout = 1;
-      return;
-      }
-   else if (SCpnt->sc_data_direction == DMA_NONE) {
-      cpp->din  = 0;
-      cpp->dout = 0;
-      return;
-      }
-
-   if (SCpnt->sc_data_direction != DMA_BIDIRECTIONAL)
-      panic("%s: qcomm, invalid SCpnt->sc_data_direction.\n", BN(j));
-
-   for (k = 0; k < ARRAY_SIZE(data_out_cmds); k++)
-      if (SCpnt->cmnd[0] == data_out_cmds[k]) {
-         cpp->dout = 1;
-         break;
-         }
-
-   if ((cpp->din = !cpp->dout))
-      for (k = 0; k < ARRAY_SIZE(data_none_cmds); k++)
-         if (SCpnt->cmnd[0] == data_none_cmds[k]) {
-            cpp->din = 0;
-            break;
-            }
-
-}
-
-static int eata2x_queuecommand(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) {
-   unsigned int i, j, k;
-   struct mscp *cpp;
-
-   /* j is the board number */
-   j = ((struct hostdata *) SCpnt->device->host->hostdata)->board_number;
-
-   if (SCpnt->host_scribble)
-      panic("%s: qcomm, pid %ld, SCpnt %p already active.\n",
-            BN(j), SCpnt->pid, SCpnt);
-
-   /* i is the mailbox number, look for the first free mailbox
-      starting from last_cp_used */
-   i = HD(j)->last_cp_used + 1;
-
-   for (k = 0; k < sh[j]->can_queue; k++, i++) {
-
-      if (i >= sh[j]->can_queue) i = 0;
-
-      if (HD(j)->cp_stat[i] == FREE) {
-         HD(j)->last_cp_used = i;
-         break;
-         }
-      }
-
-   if (k == sh[j]->can_queue) {
-      printk("%s: qcomm, no free mailbox.\n", BN(j));
-      return 1;
-      }
-
-   /* Set pointer to control packet structure */
-   cpp = &HD(j)->cp[i];
-
-   memset(cpp, 0, sizeof(struct mscp) - CP_TAIL_SIZE);
-
-   /* Set pointer to status packet structure, Big Endian format */
-   cpp->sp_dma_addr = H2DEV(HD(j)->sp_dma_addr);
-
-   SCpnt->scsi_done = done;
-   cpp->cpp_index = i;
-   SCpnt->host_scribble = (unsigned char *) &cpp->cpp_index;
-
-   if (do_trace) printk("%s: qcomm, mbox %d, target %d.%d:%d, pid %ld.\n",
-                        BN(j), i, SCpnt->device->channel, SCpnt->device->id,
-                        SCpnt->device->lun, SCpnt->pid);
-
-   cpp->reqsen = 1;
-   cpp->dispri = 1;
+	cpp->reqsen = 1;
+	cpp->dispri = 1;
 #if 0
-   if (SCpnt->device->type == TYPE_TAPE) cpp->hbaci = 1;
+	if (SCpnt->device->type == TYPE_TAPE)
+		cpp->hbaci = 1;
 #endif
-   cpp->one = 1;
-   cpp->channel = SCpnt->device->channel;
-   cpp->target = SCpnt->device->id;
-   cpp->lun = SCpnt->device->lun;
-   cpp->SCpnt = SCpnt;
-   memcpy(cpp->cdb, SCpnt->cmnd, SCpnt->cmd_len);
-
-   /* Use data transfer direction SCpnt->sc_data_direction */
-   scsi_to_dev_dir(i, j);
-
-   /* Map DMA buffers and SG list */
-   map_dma(i, j);
-
-   if (linked_comm && SCpnt->device->queue_depth > 2
-                                     && TLDEV(SCpnt->device->type)) {
-      HD(j)->cp_stat[i] = READY;
-      flush_dev(SCpnt->device, SCpnt->request->sector, j, 0);
-      return 0;
-      }
-
-   /* Send control packet to the board */
-   if (do_dma(sh[j]->io_port, cpp->cp_dma_addr, SEND_CP_DMA)) {
-      unmap_dma(i, j);
-      SCpnt->host_scribble = NULL;
-      printk("%s: qcomm, target %d.%d:%d, pid %ld, adapter busy.\n",
-             BN(j), SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun, SCpnt->pid);
-      return 1;
-      }
-
-   HD(j)->cp_stat[i] = IN_USE;
-   return 0;
-}
-
-static int eata2x_eh_abort(struct scsi_cmnd *SCarg) {
-   unsigned int i, j;
-
-   j = ((struct hostdata *) SCarg->device->host->hostdata)->board_number;
-
-   if (SCarg->host_scribble == NULL) {
-      printk("%s: abort, target %d.%d:%d, pid %ld inactive.\n",
-             BN(j), SCarg->device->channel, SCarg->device->id, SCarg->device->lun, SCarg->pid);
-      return SUCCESS;
-      }
-
-   i = *(unsigned int *)SCarg->host_scribble;
-   printk("%s: abort, mbox %d, target %d.%d:%d, pid %ld.\n",
-          BN(j), i, SCarg->device->channel, SCarg->device->id, SCarg->device->lun, SCarg->pid);
-
-   if (i >= sh[j]->can_queue)
-      panic("%s: abort, invalid SCarg->host_scribble.\n", BN(j));
-
-   if (wait_on_busy(sh[j]->io_port, MAXLOOP)) {
-      printk("%s: abort, timeout error.\n", BN(j));
-      return FAILED;
-      }
-
-   if (HD(j)->cp_stat[i] == FREE) {
-      printk("%s: abort, mbox %d is free.\n", BN(j), i);
-      return SUCCESS;
-      }
-
-   if (HD(j)->cp_stat[i] == IN_USE) {
-      printk("%s: abort, mbox %d is in use.\n", BN(j), i);
-
-      if (SCarg != HD(j)->cp[i].SCpnt)
-         panic("%s: abort, mbox %d, SCarg %p, cp SCpnt %p.\n",
-               BN(j), i, SCarg, HD(j)->cp[i].SCpnt);
-
-      if (inb(sh[j]->io_port + REG_AUX_STATUS) & 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;
-      }
-
-   if (HD(j)->cp_stat[i] == IN_RESET) {
-      printk("%s: abort, mbox %d is in reset.\n", BN(j), i);
-      return FAILED;
-      }
-
-   if (HD(j)->cp_stat[i] == LOCKED) {
-      printk("%s: abort, mbox %d is locked.\n", BN(j), i);
-      return SUCCESS;
-      }
-
-   if (HD(j)->cp_stat[i] == READY || HD(j)->cp_stat[i] == ABORTING) {
-      unmap_dma(i, j);
-      SCarg->result = DID_ABORT << 16;
-      SCarg->host_scribble = NULL;
-      HD(j)->cp_stat[i] = FREE;
-      printk("%s, abort, mbox %d ready, DID_ABORT, pid %ld done.\n",
-             BN(j), i, SCarg->pid);
-      SCarg->scsi_done(SCarg);
-      return SUCCESS;
-      }
-
-   panic("%s: abort, mbox %d, invalid cp_stat.\n", BN(j), i);
-}
-
-static int eata2x_eh_host_reset(struct scsi_cmnd *SCarg) {
-   unsigned int i, j, time, k, c, limit = 0;
-   int arg_done = 0;
-   struct scsi_cmnd *SCpnt;
-
-   j = ((struct hostdata *) SCarg->device->host->hostdata)->board_number;
-   printk("%s: reset, enter, target %d.%d:%d, pid %ld.\n",
-          BN(j), SCarg->device->channel, SCarg->device->id, SCarg->device->lun, SCarg->pid);
-
-   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));
-      return FAILED;
-      }
-
-   if (wait_on_busy(sh[j]->io_port, MAXLOOP)) {
-      printk("%s: reset, exit, timeout error.\n", BN(j));
-      return FAILED;
-      }
-
-   HD(j)->retries = 0;
-
-   for (c = 0; c <= sh[j]->max_channel; c++)
-      for (k = 0; k < sh[j]->max_id; k++) {
-         HD(j)->target_redo[k][c] = 1;
-         HD(j)->target_to[k][c] = 0;
-         }
-
-   for (i = 0; i < sh[j]->can_queue; i++) {
-
-      if (HD(j)->cp_stat[i] == FREE) continue;
-
-      if (HD(j)->cp_stat[i] == LOCKED) {
-         HD(j)->cp_stat[i] = FREE;
-         printk("%s: reset, locked mbox %d forced free.\n", BN(j), i);
-         continue;
-         }
-
-      if (!(SCpnt = HD(j)->cp[i].SCpnt))
-         panic("%s: reset, mbox %d, SCpnt == NULL.\n", BN(j), i);
-
-      if (HD(j)->cp_stat[i] == READY || HD(j)->cp_stat[i] == ABORTING) {
-         HD(j)->cp_stat[i] = ABORTING;
-         printk("%s: reset, mbox %d aborting, pid %ld.\n",
-                BN(j), i, SCpnt->pid);
-         }
-
-      else {
-         HD(j)->cp_stat[i] = IN_RESET;
-         printk("%s: reset, mbox %d in reset, pid %ld.\n",
-                BN(j), i, SCpnt->pid);
-         }
-
-      if (SCpnt->host_scribble == NULL)
-         panic("%s: reset, mbox %d, garbled SCpnt.\n", BN(j), i);
-
-      if (*(unsigned int *)SCpnt->host_scribble != i)
-         panic("%s: reset, mbox %d, index mismatch.\n", BN(j), i);
-
-      if (SCpnt->scsi_done == NULL)
-         panic("%s: reset, mbox %d, SCpnt->scsi_done == NULL.\n", BN(j), i);
-
-      if (SCpnt == SCarg) arg_done = 1;
-      }
-
-   if (do_dma(sh[j]->io_port, 0, RESET_PIO)) {
-      printk("%s: reset, cannot reset, timeout error.\n", BN(j));
-      return FAILED;
-      }
+	cpp->one = 1;
+	cpp->channel = SCpnt->device->channel;
+	cpp->target = SCpnt->device->id;
+	cpp->lun = SCpnt->device->lun;
+	cpp->SCpnt = SCpnt;
+	memcpy(cpp->cdb, SCpnt->cmnd, SCpnt->cmd_len);
+
+	/* Use data transfer direction SCpnt->sc_data_direction */
+	scsi_to_dev_dir(i, ha);
+
+	/* Map DMA buffers and SG list */
+	map_dma(i, ha);
+
+	if (linked_comm && SCpnt->device->queue_depth > 2
+	    && TLDEV(SCpnt->device->type)) {
+		ha->cp_stat[i] = READY;
+		flush_dev(SCpnt->device, SCpnt->request->sector, ha, 0);
+		return 0;
+	}
+
+	/* Send control packet to the board */
+	if (do_dma(shost->io_port, cpp->cp_dma_addr, SEND_CP_DMA)) {
+		unmap_dma(i, ha);
+		SCpnt->host_scribble = NULL;
+		printk("%s: qcomm, target %d.%d:%d, pid %ld, adapter busy.\n",
+		       ha->board_name, SCpnt->device->channel, SCpnt->device->id,
+		       SCpnt->device->lun, SCpnt->pid);
+		return 1;
+	}
+
+	ha->cp_stat[i] = IN_USE;
+	return 0;
+}
+
+static int eata2x_eh_abort(struct scsi_cmnd *SCarg)
+{
+	struct Scsi_Host *shost = SCarg->device->host;
+	struct hostdata *ha = (struct hostdata *)shost->hostdata;
+	unsigned int i;
+
+	if (SCarg->host_scribble == NULL) {
+		printk("%s: abort, target %d.%d:%d, pid %ld inactive.\n",
+		       ha->board_name, SCarg->device->channel, SCarg->device->id,
+		       SCarg->device->lun, SCarg->pid);
+		return SUCCESS;
+	}
+
+	i = *(unsigned int *)SCarg->host_scribble;
+	printk("%s: abort, mbox %d, target %d.%d:%d, pid %ld.\n",
+	       ha->board_name, i, SCarg->device->channel, SCarg->device->id,
+	       SCarg->device->lun, SCarg->pid);
+
+	if (i >= shost->can_queue)
+		panic("%s: abort, invalid SCarg->host_scribble.\n", ha->board_name);
+
+	if (wait_on_busy(shost->io_port, MAXLOOP)) {
+		printk("%s: abort, timeout error.\n", ha->board_name);
+		return FAILED;
+	}
+
+	if (ha->cp_stat[i] == FREE) {
+		printk("%s: abort, mbox %d is free.\n", ha->board_name, i);
+		return SUCCESS;
+	}
+
+	if (ha->cp_stat[i] == IN_USE) {
+		printk("%s: abort, mbox %d is in use.\n", ha->board_name, i);
+
+		if (SCarg != ha->cp[i].SCpnt)
+			panic("%s: abort, mbox %d, SCarg %p, cp SCpnt %p.\n",
+			      ha->board_name, i, SCarg, ha->cp[i].SCpnt);
+
+		if (inb(shost->io_port + REG_AUX_STATUS) & IRQ_ASSERTED)
+			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;
+	}
+
+	if (ha->cp_stat[i] == IN_RESET) {
+		printk("%s: abort, mbox %d is in reset.\n", ha->board_name, i);
+		return FAILED;
+	}
+
+	if (ha->cp_stat[i] == LOCKED) {
+		printk("%s: abort, mbox %d is locked.\n", ha->board_name, i);
+		return SUCCESS;
+	}
+
+	if (ha->cp_stat[i] == READY || ha->cp_stat[i] == ABORTING) {
+		unmap_dma(i, ha);
+		SCarg->result = DID_ABORT << 16;
+		SCarg->host_scribble = NULL;
+		ha->cp_stat[i] = FREE;
+		printk("%s, abort, mbox %d ready, DID_ABORT, pid %ld done.\n",
+		       ha->board_name, i, SCarg->pid);
+		SCarg->scsi_done(SCarg);
+		return SUCCESS;
+	}
+
+	panic("%s: abort, mbox %d, invalid cp_stat.\n", ha->board_name, i);
+}
+
+static int eata2x_eh_host_reset(struct scsi_cmnd *SCarg)
+{
+	unsigned int i, time, k, c, limit = 0;
+	int arg_done = 0;
+	struct scsi_cmnd *SCpnt;
+	struct Scsi_Host *shost = SCarg->device->host;
+	struct hostdata *ha = (struct hostdata *)shost->hostdata;
+
+	printk("%s: reset, enter, target %d.%d:%d, pid %ld.\n",
+	       ha->board_name, SCarg->device->channel, SCarg->device->id,
+	       SCarg->device->lun, SCarg->pid);
+
+	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);
+		return FAILED;
+	}
+
+	if (wait_on_busy(shost->io_port, MAXLOOP)) {
+		printk("%s: reset, exit, timeout error.\n", ha->board_name);
+		return FAILED;
+	}
+
+	ha->retries = 0;
+
+	for (c = 0; c <= shost->max_channel; c++)
+		for (k = 0; k < shost->max_id; k++) {
+			ha->target_redo[k][c] = 1;
+			ha->target_to[k][c] = 0;
+		}
+
+	for (i = 0; i < shost->can_queue; i++) {
+
+		if (ha->cp_stat[i] == FREE)
+			continue;
+
+		if (ha->cp_stat[i] == LOCKED) {
+			ha->cp_stat[i] = FREE;
+			printk("%s: reset, locked mbox %d forced free.\n",
+			       ha->board_name, i);
+			continue;
+		}
+
+		if (!(SCpnt = ha->cp[i].SCpnt))
+			panic("%s: reset, mbox %d, SCpnt == NULL.\n", ha->board_name, i);
+
+		if (ha->cp_stat[i] == READY || ha->cp_stat[i] == ABORTING) {
+			ha->cp_stat[i] = ABORTING;
+			printk("%s: reset, mbox %d aborting, pid %ld.\n",
+			       ha->board_name, i, SCpnt->pid);
+		}
+
+		else {
+			ha->cp_stat[i] = IN_RESET;
+			printk("%s: reset, mbox %d in reset, pid %ld.\n",
+			       ha->board_name, i, SCpnt->pid);
+		}
+
+		if (SCpnt->host_scribble == NULL)
+			panic("%s: reset, mbox %d, garbled SCpnt.\n", ha->board_name, i);
+
+		if (*(unsigned int *)SCpnt->host_scribble != i)
+			panic("%s: reset, mbox %d, index mismatch.\n", ha->board_name, i);
+
+		if (SCpnt->scsi_done == NULL)
+			panic("%s: reset, mbox %d, SCpnt->scsi_done == NULL.\n",
+			      ha->board_name, i);
+
+		if (SCpnt == SCarg)
+			arg_done = 1;
+	}
+
+	if (do_dma(shost->io_port, 0, RESET_PIO)) {
+		printk("%s: reset, cannot reset, timeout error.\n", ha->board_name);
+		return FAILED;
+	}
 
-   printk("%s: reset, board reset done, enabling interrupts.\n", BN(j));
+	printk("%s: reset, board reset done, enabling interrupts.\n", ha->board_name);
 
 #if defined(DEBUG_RESET)
-   do_trace = 1;
+	do_trace = 1;
 #endif
 
-   HD(j)->in_reset = 1;
+	ha->in_reset = 1;
 
-   spin_unlock_irq(sh[j]->host_lock);
-   time = jiffies;
-   while ((jiffies - time) < (10 * HZ) && limit++ < 200000) udelay(100L);
-   spin_lock_irq(sh[j]->host_lock);
+	spin_unlock_irq(shost->host_lock);
+	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", BN(j), limit);
+	printk("%s: reset, interrupts disabled, loops %d.\n", ha->board_name, limit);
 
-   for (i = 0; i < sh[j]->can_queue; i++) {
+	for (i = 0; i < shost->can_queue; i++) {
 
-      if (HD(j)->cp_stat[i] == IN_RESET) {
-         SCpnt = HD(j)->cp[i].SCpnt;
-         unmap_dma(i, j);
-         SCpnt->result = DID_RESET << 16;
-         SCpnt->host_scribble = NULL;
+		if (ha->cp_stat[i] == IN_RESET) {
+			SCpnt = ha->cp[i].SCpnt;
+			unmap_dma(i, ha);
+			SCpnt->result = DID_RESET << 16;
+			SCpnt->host_scribble = NULL;
 
-         /* This mailbox is still waiting for its interrupt */
-         HD(j)->cp_stat[i] = LOCKED;
+			/* This mailbox is still waiting for its interrupt */
+			ha->cp_stat[i] = LOCKED;
 
-         printk("%s, reset, mbox %d locked, DID_RESET, pid %ld done.\n",
-                BN(j), i, SCpnt->pid);
-         }
+			printk
+			    ("%s, reset, mbox %d locked, DID_RESET, pid %ld done.\n",
+			     ha->board_name, i, SCpnt->pid);
+		}
 
-      else if (HD(j)->cp_stat[i] == ABORTING) {
-         SCpnt = HD(j)->cp[i].SCpnt;
-         unmap_dma(i, j);
-         SCpnt->result = DID_RESET << 16;
-         SCpnt->host_scribble = NULL;
+		else if (ha->cp_stat[i] == ABORTING) {
+			SCpnt = ha->cp[i].SCpnt;
+			unmap_dma(i, ha);
+			SCpnt->result = DID_RESET << 16;
+			SCpnt->host_scribble = NULL;
 
-         /* This mailbox was never queued to the adapter */
-         HD(j)->cp_stat[i] = FREE;
+			/* This mailbox was never queued to the adapter */
+			ha->cp_stat[i] = FREE;
 
-         printk("%s, reset, mbox %d aborting, DID_RESET, pid %ld done.\n",
-                BN(j), i, SCpnt->pid);
-         }
+			printk
+			    ("%s, reset, mbox %d aborting, DID_RESET, pid %ld done.\n",
+			     ha->board_name, i, SCpnt->pid);
+		}
 
-      else
+		else
+			/* Any other mailbox has already been set free by interrupt */
+			continue;
 
-         /* Any other mailbox has already been set free by interrupt */
-         continue;
+		SCpnt->scsi_done(SCpnt);
+	}
 
-      SCpnt->scsi_done(SCpnt);
-      }
+	ha->in_reset = 0;
+	do_trace = 0;
 
-   HD(j)->in_reset = 0;
-   do_trace = 0;
+	if (arg_done)
+		printk("%s: reset, exit, pid %ld done.\n", ha->board_name, SCarg->pid);
+	else
+		printk("%s: reset, exit.\n", ha->board_name);
 
-   if (arg_done) printk("%s: reset, exit, pid %ld done.\n", BN(j), SCarg->pid);
-   else          printk("%s: reset, exit.\n", BN(j));
-
-   return SUCCESS;
+	return SUCCESS;
 }
 
 int eata2x_bios_param(struct scsi_device *sdev, struct block_device *bdev,
-                      sector_t capacity, int *dkinfo) {
-   unsigned int size = capacity;
-
-   if (ext_tran || (scsicam_bios_param(bdev, capacity, dkinfo) < 0)) {
-      dkinfo[0] = 255;
-      dkinfo[1] = 63;
-      dkinfo[2] = size / (dkinfo[0] * dkinfo[1]);
-      }
-
+		      sector_t capacity, int *dkinfo)
+{
+	unsigned int size = capacity;
+
+	if (ext_tran || (scsicam_bios_param(bdev, capacity, dkinfo) < 0)) {
+		dkinfo[0] = 255;
+		dkinfo[1] = 63;
+		dkinfo[2] = size / (dkinfo[0] * dkinfo[1]);
+	}
 #if defined (DEBUG_GEOMETRY)
-   printk ("%s: bios_param, head=%d, sec=%d, cyl=%d.\n", driver_name,
-           dkinfo[0], dkinfo[1], dkinfo[2]);
+	printk("%s: bios_param, head=%d, sec=%d, cyl=%d.\n", driver_name,
+	       dkinfo[0], dkinfo[1], dkinfo[2]);
 #endif
 
-   return 0;
+	return 0;
 }
 
 static void sort(unsigned long sk[], unsigned int da[], unsigned int n,
-                 unsigned int rev) {
-   unsigned int i, j, k, y;
-   unsigned long x;
-
-   for (i = 0; i < n - 1; i++) {
-      k = i;
-
-      for (j = k + 1; j < n; j++)
-         if (rev) {
-            if (sk[j] > sk[k]) k = j;
-            }
-         else {
-            if (sk[j] < sk[k]) k = j;
-            }
-
-      if (k != i) {
-         x = sk[k]; sk[k] = sk[i]; sk[i] = x;
-         y = da[k]; da[k] = da[i]; da[i] = y;
-         }
-      }
-
-   return;
-   }
-
-static int reorder(unsigned int j, unsigned long cursec,
-                 unsigned int ihdlr, unsigned int il[], unsigned int n_ready) {
-   struct scsi_cmnd *SCpnt;
-   struct mscp *cpp;
-   unsigned int k, n;
-   unsigned int rev = 0, s = 1, r = 1;
-   unsigned int input_only = 1, overlap = 0;
-   unsigned long sl[n_ready], pl[n_ready], ll[n_ready];
-   unsigned long maxsec = 0, minsec = ULONG_MAX, seek = 0, iseek = 0;
-   unsigned long ioseek = 0;
-
-   static unsigned int flushcount = 0, batchcount = 0, sortcount = 0;
-   static unsigned int readycount = 0, ovlcount = 0, inputcount = 0;
-   static unsigned int readysorted = 0, revcount = 0;
-   static unsigned long seeksorted = 0, seeknosort = 0;
-
-   if (link_statistics && !(++flushcount % link_statistics))
-      printk("fc %d bc %d ic %d oc %d rc %d rs %d sc %d re %d"\
-             " av %ldK as %ldK.\n", flushcount, batchcount, inputcount,
-             ovlcount, readycount, readysorted, sortcount, revcount,
-             seeknosort / (readycount + 1),
-             seeksorted / (readycount + 1));
-
-   if (n_ready <= 1) return 0;
-
-   for (n = 0; n < n_ready; n++) {
-      k = il[n]; cpp = &HD(j)->cp[k]; SCpnt = cpp->SCpnt;
-
-      if (!cpp->din) input_only = 0;
-
-      if (SCpnt->request->sector < minsec) minsec = SCpnt->request->sector;
-      if (SCpnt->request->sector > maxsec) maxsec = SCpnt->request->sector;
-
-      sl[n] = SCpnt->request->sector;
-      ioseek += SCpnt->request->nr_sectors;
-
-      if (!n) continue;
-
-      if (sl[n] < sl[n - 1]) s = 0;
-      if (sl[n] > sl[n - 1]) r = 0;
-
-      if (link_statistics) {
-         if (sl[n] > sl[n - 1])
-            seek += sl[n] - sl[n - 1];
-         else
-            seek += sl[n - 1] - sl[n];
-         }
-
-      }
-
-   if (link_statistics) {
-      if (cursec > sl[0]) seek += cursec - sl[0]; else seek += sl[0] - cursec;
-      }
-
-   if (cursec > ((maxsec + minsec) / 2)) rev = 1;
-
-   if (ioseek > ((maxsec - minsec) / 2)) rev = 0;
-
-   if (!((rev && r) || (!rev && s))) sort(sl, il, n_ready, rev);
-
-   if (!input_only) for (n = 0; n < n_ready; n++) {
-      k = il[n]; cpp = &HD(j)->cp[k]; SCpnt = cpp->SCpnt;
-      ll[n] = SCpnt->request->nr_sectors; pl[n] = SCpnt->pid;
-
-      if (!n) continue;
-
-      if ((sl[n] == sl[n - 1]) || (!rev && ((sl[n - 1] + ll[n - 1]) > sl[n]))
-          || (rev && ((sl[n] + ll[n]) > sl[n - 1]))) overlap = 1;
-      }
-
-   if (overlap) sort(pl, il, n_ready, 0);
-
-   if (link_statistics) {
-      if (cursec > sl[0]) iseek = cursec - sl[0]; else iseek = sl[0] - cursec;
-      batchcount++; readycount += n_ready; seeknosort += seek / 1024;
-      if (input_only) inputcount++;
-      if (overlap) { ovlcount++; seeksorted += iseek / 1024; }
-      else seeksorted += (iseek + maxsec - minsec) / 1024;
-      if (rev && !r)     {  revcount++; readysorted += n_ready; }
-      if (!rev && !s)    { sortcount++; readysorted += n_ready; }
-      }
-
+		 unsigned int rev)
+{
+	unsigned int i, j, k, y;
+	unsigned long x;
+
+	for (i = 0; i < n - 1; i++) {
+		k = i;
+
+		for (j = k + 1; j < n; j++)
+			if (rev) {
+				if (sk[j] > sk[k])
+					k = j;
+			} else {
+				if (sk[j] < sk[k])
+					k = j;
+			}
+
+		if (k != i) {
+			x = sk[k];
+			sk[k] = sk[i];
+			sk[i] = x;
+			y = da[k];
+			da[k] = da[i];
+			da[i] = y;
+		}
+	}
+
+	return;
+}
+
+static int reorder(struct hostdata *ha, unsigned long cursec,
+		   unsigned int ihdlr, unsigned int il[], unsigned int n_ready)
+{
+	struct scsi_cmnd *SCpnt;
+	struct mscp *cpp;
+	unsigned int k, n;
+	unsigned int rev = 0, s = 1, r = 1;
+	unsigned int input_only = 1, overlap = 0;
+	unsigned long sl[n_ready], pl[n_ready], ll[n_ready];
+	unsigned long maxsec = 0, minsec = ULONG_MAX, seek = 0, iseek = 0;
+	unsigned long ioseek = 0;
+
+	static unsigned int flushcount = 0, batchcount = 0, sortcount = 0;
+	static unsigned int readycount = 0, ovlcount = 0, inputcount = 0;
+	static unsigned int readysorted = 0, revcount = 0;
+	static unsigned long seeksorted = 0, seeknosort = 0;
+
+	if (link_statistics && !(++flushcount % link_statistics))
+		printk("fc %d bc %d ic %d oc %d rc %d rs %d sc %d re %d"
+		       " av %ldK as %ldK.\n", flushcount, batchcount,
+		       inputcount, ovlcount, readycount, readysorted, sortcount,
+		       revcount, seeknosort / (readycount + 1),
+		       seeksorted / (readycount + 1));
+
+	if (n_ready <= 1)
+		return 0;
+
+	for (n = 0; n < n_ready; n++) {
+		k = il[n];
+		cpp = &ha->cp[k];
+		SCpnt = cpp->SCpnt;
+
+		if (!cpp->din)
+			input_only = 0;
+
+		if (SCpnt->request->sector < minsec)
+			minsec = SCpnt->request->sector;
+		if (SCpnt->request->sector > maxsec)
+			maxsec = SCpnt->request->sector;
+
+		sl[n] = SCpnt->request->sector;
+		ioseek += SCpnt->request->nr_sectors;
+
+		if (!n)
+			continue;
+
+		if (sl[n] < sl[n - 1])
+			s = 0;
+		if (sl[n] > sl[n - 1])
+			r = 0;
+
+		if (link_statistics) {
+			if (sl[n] > sl[n - 1])
+				seek += sl[n] - sl[n - 1];
+			else
+				seek += sl[n - 1] - sl[n];
+		}
+
+	}
+
+	if (link_statistics) {
+		if (cursec > sl[0])
+			seek += cursec - sl[0];
+		else
+			seek += sl[0] - cursec;
+	}
+
+	if (cursec > ((maxsec + minsec) / 2))
+		rev = 1;
+
+	if (ioseek > ((maxsec - minsec) / 2))
+		rev = 0;
+
+	if (!((rev && r) || (!rev && s)))
+		sort(sl, il, n_ready, rev);
+
+	if (!input_only)
+		for (n = 0; n < n_ready; n++) {
+			k = il[n];
+			cpp = &ha->cp[k];
+			SCpnt = cpp->SCpnt;
+			ll[n] = SCpnt->request->nr_sectors;
+			pl[n] = SCpnt->pid;
+
+			if (!n)
+				continue;
+
+			if ((sl[n] == sl[n - 1])
+			    || (!rev && ((sl[n - 1] + ll[n - 1]) > sl[n]))
+			    || (rev && ((sl[n] + ll[n]) > sl[n - 1])))
+				overlap = 1;
+		}
+
+	if (overlap)
+		sort(pl, il, n_ready, 0);
+
+	if (link_statistics) {
+		if (cursec > sl[0])
+			iseek = cursec - sl[0];
+		else
+			iseek = sl[0] - cursec;
+		batchcount++;
+		readycount += n_ready;
+		seeknosort += seek / 1024;
+		if (input_only)
+			inputcount++;
+		if (overlap) {
+			ovlcount++;
+			seeksorted += iseek / 1024;
+		} else
+			seeksorted += (iseek + maxsec - minsec) / 1024;
+		if (rev && !r) {
+			revcount++;
+			readysorted += n_ready;
+		}
+		if (!rev && !s) {
+			sortcount++;
+			readysorted += n_ready;
+		}
+	}
 #if defined(DEBUG_LINKED_COMMANDS)
-   if (link_statistics && (overlap || !(flushcount % link_statistics)))
-      for (n = 0; n < n_ready; n++) {
-         k = il[n]; cpp = &HD(j)->cp[k]; SCpnt = cpp->SCpnt;
-         printk("%s %d.%d:%d pid %ld mb %d fc %d nr %d sec %ld ns %ld"\
-                " cur %ld s:%c r:%c rev:%c in:%c ov:%c xd %d.\n",
-                (ihdlr ? "ihdlr" : "qcomm"), SCpnt->device->channel, SCpnt->device->id,
-                SCpnt->device->lun, SCpnt->pid, k, flushcount, n_ready,
-                SCpnt->request->sector, SCpnt->request->nr_sectors, cursec,
-                YESNO(s), YESNO(r), YESNO(rev), YESNO(input_only),
-                YESNO(overlap), cpp->din);
-         }
-#endif
-   return overlap;
-}
-
-static void flush_dev(struct scsi_device *dev, unsigned long cursec, unsigned int j,
-                      unsigned int ihdlr) {
-   struct scsi_cmnd *SCpnt;
-   struct mscp *cpp;
-   unsigned int k, n, n_ready = 0, il[MAX_MAILBOXES];
-
-   for (k = 0; k < sh[j]->can_queue; k++) {
+	if (link_statistics && (overlap || !(flushcount % link_statistics)))
+		for (n = 0; n < n_ready; n++) {
+			k = il[n];
+			cpp = &ha->cp[k];
+			SCpnt = cpp->SCpnt;
+			printk
+			    ("%s %d.%d:%d pid %ld mb %d fc %d nr %d sec %ld ns %ld"
+			     " cur %ld s:%c r:%c rev:%c in:%c ov:%c xd %d.\n",
+			     (ihdlr ? "ihdlr" : "qcomm"),
+			     SCpnt->device->channel, SCpnt->device->id,
+			     SCpnt->device->lun, SCpnt->pid, k, flushcount,
+			     n_ready, SCpnt->request->sector,
+			     SCpnt->request->nr_sectors, cursec, YESNO(s),
+			     YESNO(r), YESNO(rev), YESNO(input_only),
+			     YESNO(overlap), cpp->din);
+		}
+#endif
+	return overlap;
+}
+
+static void flush_dev(struct scsi_device *dev, unsigned long cursec,
+		      struct hostdata *ha, unsigned int ihdlr)
+{
+	struct scsi_cmnd *SCpnt;
+	struct mscp *cpp;
+	unsigned int k, n, n_ready = 0, il[MAX_MAILBOXES];
+
+	for (k = 0; k < dev->host->can_queue; k++) {
+
+		if (ha->cp_stat[k] != READY && ha->cp_stat[k] != IN_USE)
+			continue;
+
+		cpp = &ha->cp[k];
+		SCpnt = cpp->SCpnt;
+
+		if (SCpnt->device != dev)
+			continue;
+
+		if (ha->cp_stat[k] == IN_USE)
+			return;
+
+		il[n_ready++] = k;
+	}
+
+	if (reorder(ha, cursec, ihdlr, il, n_ready))
+		n_ready = 1;
+
+	for (n = 0; n < n_ready; n++) {
+		k = il[n];
+		cpp = &ha->cp[k];
+		SCpnt = cpp->SCpnt;
+
+		if (do_dma(dev->host->io_port, cpp->cp_dma_addr, SEND_CP_DMA)) {
+			printk
+			    ("%s: %s, target %d.%d:%d, pid %ld, mbox %d, adapter"
+			     " busy, will abort.\n", ha->board_name,
+			     (ihdlr ? "ihdlr" : "qcomm"),
+			     SCpnt->device->channel, SCpnt->device->id,
+			     SCpnt->device->lun, SCpnt->pid, k);
+			ha->cp_stat[k] = ABORTING;
+			continue;
+		}
+
+		ha->cp_stat[k] = IN_USE;
+	}
+}
+
+static irqreturn_t ihdlr(int irq, struct Scsi_Host *shost)
+{
+	struct scsi_cmnd *SCpnt;
+	unsigned int i, k, c, status, tstatus, reg;
+	struct mssp *spp;
+	struct mscp *cpp;
+	struct hostdata *ha = (struct hostdata *)shost->hostdata;
+
+	if (shost->irq != irq)
+		panic("%s: ihdlr, irq %d, shost->irq %d.\n", ha->board_name, irq,
+		      shost->irq);
+
+	/* Check if this board need to be serviced */
+	if (!(inb(shost->io_port + REG_AUX_STATUS) & IRQ_ASSERTED))
+		goto none;
+
+	ha->iocount++;
+
+	if (do_trace)
+		printk("%s: ihdlr, enter, irq %d, count %d.\n", ha->board_name, irq,
+		       ha->iocount);
+
+	/* Check if this board is still busy */
+	if (wait_on_busy(shost->io_port, 20 * MAXLOOP)) {
+		reg = inb(shost->io_port + REG_STATUS);
+		printk
+		    ("%s: ihdlr, busy timeout error,  irq %d, reg 0x%x, count %d.\n",
+		     ha->board_name, irq, reg, ha->iocount);
+		goto none;
+	}
+
+	spp = &ha->sp;
 
-      if (HD(j)->cp_stat[k] != READY && HD(j)->cp_stat[k] != IN_USE) continue;
-
-      cpp = &HD(j)->cp[k]; SCpnt = cpp->SCpnt;
-
-      if (SCpnt->device != dev) continue;
-
-      if (HD(j)->cp_stat[k] == IN_USE) return;
-
-      il[n_ready++] = k;
-      }
-
-   if (reorder(j, cursec, ihdlr, il, n_ready)) n_ready = 1;
-
-   for (n = 0; n < n_ready; n++) {
-      k = il[n]; cpp = &HD(j)->cp[k]; SCpnt = cpp->SCpnt;
-
-      if (do_dma(sh[j]->io_port, cpp->cp_dma_addr, SEND_CP_DMA)) {
-         printk("%s: %s, target %d.%d:%d, pid %ld, mbox %d, adapter"\
-                " busy, will abort.\n", BN(j), (ihdlr ? "ihdlr" : "qcomm"),
-                SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun, SCpnt->pid, k);
-         HD(j)->cp_stat[k] = ABORTING;
-         continue;
-         }
-
-      HD(j)->cp_stat[k] = IN_USE;
-      }
-
-}
+	/* Make a local copy just before clearing the interrupt indication */
+	memcpy(spp, ha->sp_cpu_addr, sizeof(struct mssp));
 
-static irqreturn_t ihdlr(int irq, unsigned int j) {
-   struct scsi_cmnd *SCpnt;
-   unsigned int i, k, c, status, tstatus, reg;
-   struct mssp *spp;
-   struct mscp *cpp;
+	/* Clear the completion flag and cp pointer on the dynamic copy of sp */
+	memset(ha->sp_cpu_addr, 0, sizeof(struct mssp));
 
-   if (sh[j]->irq != irq)
-       panic("%s: ihdlr, irq %d, sh[j]->irq %d.\n", BN(j), irq, sh[j]->irq);
-
-   /* Check if this board need to be serviced */
-   if (!(inb(sh[j]->io_port + REG_AUX_STATUS) & IRQ_ASSERTED)) goto none;
-
-   HD(j)->iocount++;
-
-   if (do_trace) printk("%s: ihdlr, enter, irq %d, count %d.\n", BN(j), irq,
-                        HD(j)->iocount);
-
-   /* Check if this board is still busy */
-   if (wait_on_busy(sh[j]->io_port, 20 * MAXLOOP)) {
-      reg = inb(sh[j]->io_port + REG_STATUS);
-      printk("%s: ihdlr, busy timeout error,  irq %d, reg 0x%x, count %d.\n",
-             BN(j), irq, reg, HD(j)->iocount);
-      goto none;
-      }
-
-   spp  = &HD(j)->sp;
-
-   /* Make a local copy just before clearing the interrupt indication */
-   memcpy(spp, HD(j)->sp_cpu_addr, sizeof(struct mssp));
-
-   /* Clear the completion flag and cp pointer on the dynamic copy of sp */
-   memset(HD(j)->sp_cpu_addr, 0, sizeof(struct mssp));
-
-   /* Read the status register to clear the interrupt indication */
-   reg = inb(sh[j]->io_port + REG_STATUS);
+	/* Read the status register to clear the interrupt indication */
+	reg = inb(shost->io_port + REG_STATUS);
 
 #if defined (DEBUG_INTERRUPT)
-   {
-   unsigned char *bytesp;
-   int cnt;
-   bytesp= (unsigned char *) spp;
-   if (HD(j)->iocount < 200) {
-      printk("sp[] =");
-      for (cnt=0; cnt < 15; cnt++) printk(" 0x%x", bytesp[cnt]);
-      printk("\n");
-      }
-   }
-#endif
-
-   /* Reject any sp with supspect data */
-   if (spp->eoc == 0 && HD(j)->iocount > 1)
-      printk("%s: ihdlr, spp->eoc == 0, irq %d, reg 0x%x, count %d.\n",
-             BN(j), irq, reg, HD(j)->iocount);
-   if (spp->cpp_index < 0 || spp->cpp_index >= sh[j]->can_queue)
-      printk("%s: ihdlr, bad spp->cpp_index %d, irq %d, reg 0x%x, count %d.\n",
-             BN(j), spp->cpp_index, irq, reg, HD(j)->iocount);
-   if (spp->eoc == 0 || spp->cpp_index < 0
-                         || spp->cpp_index >= sh[j]->can_queue) goto handled;
+	{
+		unsigned char *bytesp;
+		int cnt;
+		bytesp = (unsigned char *)spp;
+		if (ha->iocount < 200) {
+			printk("sp[] =");
+			for (cnt = 0; cnt < 15; cnt++)
+				printk(" 0x%x", bytesp[cnt]);
+			printk("\n");
+		}
+	}
+#endif
+
+	/* Reject any sp with supspect data */
+	if (spp->eoc == 0 && ha->iocount > 1)
+		printk
+		    ("%s: ihdlr, spp->eoc == 0, irq %d, reg 0x%x, count %d.\n",
+		     ha->board_name, irq, reg, ha->iocount);
+	if (spp->cpp_index < 0 || spp->cpp_index >= shost->can_queue)
+		printk
+		    ("%s: ihdlr, bad spp->cpp_index %d, irq %d, reg 0x%x, count %d.\n",
+		     ha->board_name, spp->cpp_index, irq, reg, ha->iocount);
+	if (spp->eoc == 0 || spp->cpp_index < 0
+	    || spp->cpp_index >= shost->can_queue)
+		goto handled;
 
-   /* Find the mailbox to be serviced on this board */
-   i = spp->cpp_index;
+	/* Find the mailbox to be serviced on this board */
+	i = spp->cpp_index;
 
-   cpp = &(HD(j)->cp[i]);
+	cpp = &(ha->cp[i]);
 
 #if defined(DEBUG_GENERATE_ABORTS)
-   if ((HD(j)->iocount > 500) && ((HD(j)->iocount % 500) < 3)) goto handled;
+	if ((ha->iocount > 500) && ((ha->iocount % 500) < 3))
+		goto handled;
 #endif
 
-   if (HD(j)->cp_stat[i] == IGNORE) {
-      HD(j)->cp_stat[i] = FREE;
-      goto handled;
-      }
-   else if (HD(j)->cp_stat[i] == LOCKED) {
-      HD(j)->cp_stat[i] = FREE;
-      printk("%s: ihdlr, mbox %d unlocked, count %d.\n", BN(j), i,
-             HD(j)->iocount);
-      goto handled;
-      }
-   else if (HD(j)->cp_stat[i] == FREE) {
-      printk("%s: ihdlr, mbox %d is free, count %d.\n", BN(j), i,
-             HD(j)->iocount);
-      goto handled;
-      }
-   else if (HD(j)->cp_stat[i] == IN_RESET)
-      printk("%s: ihdlr, mbox %d is in reset.\n", BN(j), i);
-   else if (HD(j)->cp_stat[i] != IN_USE)
-      panic("%s: ihdlr, mbox %d, invalid cp_stat: %d.\n",
-            BN(j), i, HD(j)->cp_stat[i]);
-
-   HD(j)->cp_stat[i] = FREE;
-   SCpnt = cpp->SCpnt;
-
-   if (SCpnt == NULL) panic("%s: ihdlr, mbox %d, SCpnt == NULL.\n", BN(j), i);
-
-   if (SCpnt->host_scribble == NULL)
-      panic("%s: ihdlr, mbox %d, pid %ld, SCpnt %p garbled.\n", BN(j), i,
-            SCpnt->pid, SCpnt);
-
-   if (*(unsigned int *)SCpnt->host_scribble != i)
-      panic("%s: ihdlr, mbox %d, pid %ld, index mismatch %d.\n",
-            BN(j), i, SCpnt->pid, *(unsigned int *)SCpnt->host_scribble);
-
-   sync_dma(i, j);
-
-   if (linked_comm && SCpnt->device->queue_depth > 2
-                                     && TLDEV(SCpnt->device->type))
-      flush_dev(SCpnt->device, SCpnt->request->sector, j, 1);
+	if (ha->cp_stat[i] == IGNORE) {
+		ha->cp_stat[i] = FREE;
+		goto handled;
+	} else if (ha->cp_stat[i] == LOCKED) {
+		ha->cp_stat[i] = FREE;
+		printk("%s: ihdlr, mbox %d unlocked, count %d.\n", ha->board_name, i,
+		       ha->iocount);
+		goto handled;
+	} else if (ha->cp_stat[i] == FREE) {
+		printk("%s: ihdlr, mbox %d is free, count %d.\n", ha->board_name, i,
+		       ha->iocount);
+		goto handled;
+	} else if (ha->cp_stat[i] == IN_RESET)
+		printk("%s: ihdlr, mbox %d is in reset.\n", ha->board_name, i);
+	else if (ha->cp_stat[i] != IN_USE)
+		panic("%s: ihdlr, mbox %d, invalid cp_stat: %d.\n",
+		      ha->board_name, i, ha->cp_stat[i]);
+
+	ha->cp_stat[i] = FREE;
+	SCpnt = cpp->SCpnt;
+
+	if (SCpnt == NULL)
+		panic("%s: ihdlr, mbox %d, SCpnt == NULL.\n", ha->board_name, i);
+
+	if (SCpnt->host_scribble == NULL)
+		panic("%s: ihdlr, mbox %d, pid %ld, SCpnt %p garbled.\n", ha->board_name,
+		      i, SCpnt->pid, SCpnt);
+
+	if (*(unsigned int *)SCpnt->host_scribble != i)
+		panic("%s: ihdlr, mbox %d, pid %ld, index mismatch %d.\n",
+		      ha->board_name, i, SCpnt->pid,
+		      *(unsigned int *)SCpnt->host_scribble);
+
+	sync_dma(i, ha);
+
+	if (linked_comm && SCpnt->device->queue_depth > 2
+	    && TLDEV(SCpnt->device->type))
+		flush_dev(SCpnt->device, SCpnt->request->sector, ha, 1);
 
-   tstatus = status_byte(spp->target_status);
+	tstatus = status_byte(spp->target_status);
 
 #if defined(DEBUG_GENERATE_ERRORS)
-   if ((HD(j)->iocount > 500) && ((HD(j)->iocount % 200) < 2))
-                                           spp->adapter_status = 0x01;
+	if ((ha->iocount > 500) && ((ha->iocount % 200) < 2))
+		spp->adapter_status = 0x01;
 #endif
 
-   switch (spp->adapter_status) {
-      case ASOK:     /* status OK */
+	switch (spp->adapter_status) {
+	case ASOK:		/* status OK */
 
-         /* Forces a reset if a disk drive keeps returning BUSY */
-         if (tstatus == BUSY && SCpnt->device->type != TYPE_TAPE)
-            status = DID_ERROR << 16;
-
-         /* If there was a bus reset, redo operation on each target */
-         else if (tstatus != GOOD && SCpnt->device->type == TYPE_DISK
-                  && HD(j)->target_redo[SCpnt->device->id][SCpnt->device->channel])
-            status = DID_BUS_BUSY << 16;
-
-         /* Works around a flaw in scsi.c */
-         else if (tstatus == CHECK_CONDITION
-                  && SCpnt->device->type == TYPE_DISK
-                  && (SCpnt->sense_buffer[2] & 0xf) == RECOVERED_ERROR)
-            status = DID_BUS_BUSY << 16;
-
-         else
-            status = DID_OK << 16;
-
-         if (tstatus == GOOD)
-            HD(j)->target_redo[SCpnt->device->id][SCpnt->device->channel] = 0;
-
-         if (spp->target_status && SCpnt->device->type == TYPE_DISK &&
-             (!(tstatus == CHECK_CONDITION && HD(j)->iocount <= 1000 &&
-               (SCpnt->sense_buffer[2] & 0xf) == NOT_READY)))
-            printk("%s: ihdlr, target %d.%d:%d, pid %ld, "\
-                   "target_status 0x%x, sense key 0x%x.\n", BN(j),
-                   SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun,
-                   SCpnt->pid, spp->target_status,
-                   SCpnt->sense_buffer[2]);
-
-         HD(j)->target_to[SCpnt->device->id][SCpnt->device->channel] = 0;
-
-         if (HD(j)->last_retried_pid == SCpnt->pid) HD(j)->retries = 0;
-
-         break;
-      case ASST:     /* Selection Time Out */
-      case 0x02:     /* Command Time Out   */
-
-         if (HD(j)->target_to[SCpnt->device->id][SCpnt->device->channel] > 1)
-            status = DID_ERROR << 16;
-         else {
-            status = DID_TIME_OUT << 16;
-            HD(j)->target_to[SCpnt->device->id][SCpnt->device->channel]++;
-            }
-
-         break;
-
-      /* Perform a limited number of internal retries */
-      case 0x03:     /* SCSI Bus Reset Received */
-      case 0x04:     /* Initial Controller Power-up */
-
-         for (c = 0; c <= sh[j]->max_channel; c++)
-            for (k = 0; k < sh[j]->max_id; k++)
-               HD(j)->target_redo[k][c] = 1;
+		/* Forces a reset if a disk drive keeps returning BUSY */
+		if (tstatus == BUSY && SCpnt->device->type != TYPE_TAPE)
+			status = DID_ERROR << 16;
+
+		/* If there was a bus reset, redo operation on each target */
+		else if (tstatus != GOOD && SCpnt->device->type == TYPE_DISK
+			 && ha->target_redo[SCpnt->device->id][SCpnt->
+								  device->
+								  channel])
+			status = DID_BUS_BUSY << 16;
+
+		/* Works around a flaw in scsi.c */
+		else if (tstatus == CHECK_CONDITION
+			 && SCpnt->device->type == TYPE_DISK
+			 && (SCpnt->sense_buffer[2] & 0xf) == RECOVERED_ERROR)
+			status = DID_BUS_BUSY << 16;
+
+		else
+			status = DID_OK << 16;
+
+		if (tstatus == GOOD)
+			ha->target_redo[SCpnt->device->id][SCpnt->device->
+							      channel] = 0;
+
+		if (spp->target_status && SCpnt->device->type == TYPE_DISK &&
+		    (!(tstatus == CHECK_CONDITION && ha->iocount <= 1000 &&
+		       (SCpnt->sense_buffer[2] & 0xf) == NOT_READY)))
+			printk("%s: ihdlr, target %d.%d:%d, pid %ld, "
+			       "target_status 0x%x, sense key 0x%x.\n",
+			       ha->board_name,
+			       SCpnt->device->channel, SCpnt->device->id,
+			       SCpnt->device->lun, SCpnt->pid,
+			       spp->target_status, SCpnt->sense_buffer[2]);
+
+		ha->target_to[SCpnt->device->id][SCpnt->device->channel] = 0;
+
+		if (ha->last_retried_pid == SCpnt->pid)
+			ha->retries = 0;
+
+		break;
+	case ASST:		/* Selection Time Out */
+	case 0x02:		/* Command Time Out   */
+
+		if (ha->target_to[SCpnt->device->id][SCpnt->device->channel] > 1)
+			status = DID_ERROR << 16;
+		else {
+			status = DID_TIME_OUT << 16;
+			ha->target_to[SCpnt->device->id][SCpnt->device->
+							    channel]++;
+		}
+
+		break;
+
+		/* Perform a limited number of internal retries */
+	case 0x03:		/* SCSI Bus Reset Received */
+	case 0x04:		/* Initial Controller Power-up */
+
+		for (c = 0; c <= shost->max_channel; c++)
+			for (k = 0; k < shost->max_id; k++)
+				ha->target_redo[k][c] = 1;
 
-         if (SCpnt->device->type != TYPE_TAPE
-             && HD(j)->retries < MAX_INTERNAL_RETRIES) {
+		if (SCpnt->device->type != TYPE_TAPE
+		    && ha->retries < MAX_INTERNAL_RETRIES) {
 
 #if defined(DID_SOFT_ERROR)
-            status = DID_SOFT_ERROR << 16;
+			status = DID_SOFT_ERROR << 16;
 #else
-            status = DID_BUS_BUSY << 16;
+			status = DID_BUS_BUSY << 16;
 #endif
 
-            HD(j)->retries++;
-            HD(j)->last_retried_pid = SCpnt->pid;
-            }
-         else
-            status = DID_ERROR << 16;
-
-         break;
-      case 0x05:     /* Unexpected Bus Phase */
-      case 0x06:     /* Unexpected Bus Free */
-      case 0x07:     /* Bus Parity Error */
-      case 0x08:     /* SCSI Hung */
-      case 0x09:     /* Unexpected Message Reject */
-      case 0x0a:     /* SCSI Bus Reset Stuck */
-      case 0x0b:     /* Auto Request-Sense Failed */
-      case 0x0c:     /* Controller Ram Parity Error */
-      default:
-         status = DID_ERROR << 16;
-         break;
-      }
+			ha->retries++;
+			ha->last_retried_pid = SCpnt->pid;
+		} else
+			status = DID_ERROR << 16;
+
+		break;
+	case 0x05:		/* Unexpected Bus Phase */
+	case 0x06:		/* Unexpected Bus Free */
+	case 0x07:		/* Bus Parity Error */
+	case 0x08:		/* SCSI Hung */
+	case 0x09:		/* Unexpected Message Reject */
+	case 0x0a:		/* SCSI Bus Reset Stuck */
+	case 0x0b:		/* Auto Request-Sense Failed */
+	case 0x0c:		/* Controller Ram Parity Error */
+	default:
+		status = DID_ERROR << 16;
+		break;
+	}
 
-   SCpnt->result = status | spp->target_status;
+	SCpnt->result = status | spp->target_status;
 
 #if defined(DEBUG_INTERRUPT)
-   if (SCpnt->result || do_trace)
+	if (SCpnt->result || do_trace)
 #else
-   if ((spp->adapter_status != ASOK && HD(j)->iocount >  1000) ||
-       (spp->adapter_status != ASOK &&
-        spp->adapter_status != ASST && HD(j)->iocount <= 1000) ||
-        do_trace || msg_byte(spp->target_status))
-#endif
-      printk("%s: ihdlr, mbox %2d, err 0x%x:%x,"\
-             " target %d.%d:%d, pid %ld, reg 0x%x, count %d.\n",
-             BN(j), i, spp->adapter_status, spp->target_status,
-             SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun, SCpnt->pid,
-             reg, HD(j)->iocount);
-
-   unmap_dma(i, j);
-
-   /* Set the command state to inactive */
-   SCpnt->host_scribble = NULL;
-
-   SCpnt->scsi_done(SCpnt);
-
-   if (do_trace) printk("%s: ihdlr, exit, irq %d, count %d.\n", BN(j), irq,
-                        HD(j)->iocount);
-
-handled:
-   return IRQ_HANDLED;
-none:
-   return IRQ_NONE;
+	if ((spp->adapter_status != ASOK && ha->iocount > 1000) ||
+	    (spp->adapter_status != ASOK &&
+	     spp->adapter_status != ASST && ha->iocount <= 1000) ||
+	    do_trace || msg_byte(spp->target_status))
+#endif
+		printk("%s: ihdlr, mbox %2d, err 0x%x:%x,"
+		       " target %d.%d:%d, pid %ld, reg 0x%x, count %d.\n",
+		       ha->board_name, i, spp->adapter_status, spp->target_status,
+		       SCpnt->device->channel, SCpnt->device->id,
+		       SCpnt->device->lun, SCpnt->pid, reg, ha->iocount);
+
+	unmap_dma(i, ha);
+
+	/* Set the command state to inactive */
+	SCpnt->host_scribble = NULL;
+
+	SCpnt->scsi_done(SCpnt);
+
+	if (do_trace)
+		printk("%s: ihdlr, exit, irq %d, count %d.\n", ha->board_name,
+				irq, ha->iocount);
+
+      handled:
+	return IRQ_HANDLED;
+      none:
+	return IRQ_NONE;
 }
 
 static irqreturn_t do_interrupt_handler(int irq, void *shap,
-                                        struct pt_regs *regs) {
-   unsigned int j;
-   unsigned long spin_flags;
-   irqreturn_t ret;
-
-   /* Check if the interrupt must be processed by this handler */
-   if ((j = (unsigned int)((char *)shap - sha)) >= num_boards) return IRQ_NONE;
-
-   spin_lock_irqsave(sh[j]->host_lock, spin_flags);
-   ret = ihdlr(irq, j);
-   spin_unlock_irqrestore(sh[j]->host_lock, spin_flags);
-   return ret;
-}
-
-static int eata2x_release(struct Scsi_Host *shpnt) {
-   unsigned int i, j;
-
-   for (j = 0; sh[j] != NULL && sh[j] != shpnt; j++);
-
-   if (sh[j] == NULL) panic("%s: release, invalid Scsi_Host pointer.\n",
-                            driver_name);
-
-   for (i = 0; i < sh[j]->can_queue; i++)
-      if ((&HD(j)->cp[i])->sglist) kfree((&HD(j)->cp[i])->sglist);
-
-   for (i = 0; i < sh[j]->can_queue; i++)
-      pci_unmap_single(HD(j)->pdev, HD(j)->cp[i].cp_dma_addr,
-                     sizeof(struct mscp), PCI_DMA_BIDIRECTIONAL);
-
-   if (HD(j)->sp_cpu_addr)
-      pci_free_consistent(HD(j)->pdev, sizeof(struct mssp),
-                          HD(j)->sp_cpu_addr, HD(j)->sp_dma_addr);
-
-   free_irq(sh[j]->irq, &sha[j]);
-
-   if (sh[j]->dma_channel != NO_DMA) free_dma(sh[j]->dma_channel);
-
-   release_region(sh[j]->io_port, sh[j]->n_io_port);
-   scsi_unregister(sh[j]);
-   return 0;
+					struct pt_regs *regs)
+{
+	struct Scsi_Host *shost;
+	unsigned int j;
+	unsigned long spin_flags;
+	irqreturn_t ret;
+
+	/* Check if the interrupt must be processed by this handler */
+	if ((j = (unsigned int)((char *)shap - sha)) >= num_boards)
+		return IRQ_NONE;
+	shost = sh[j];
+
+	spin_lock_irqsave(shost->host_lock, spin_flags);
+	ret = ihdlr(irq, shost);
+	spin_unlock_irqrestore(shost->host_lock, spin_flags);
+	return ret;
+}
+
+static int eata2x_release(struct Scsi_Host *shost)
+{
+	struct hostdata *ha = (struct hostdata *)shost->hostdata;
+	unsigned int i;
+
+	for (i = 0; i < shost->can_queue; i++)
+		if ((&ha->cp[i])->sglist)
+			kfree((&ha->cp[i])->sglist);
+
+	for (i = 0; i < shost->can_queue; i++)
+		pci_unmap_single(ha->pdev, ha->cp[i].cp_dma_addr,
+				 sizeof(struct mscp), PCI_DMA_BIDIRECTIONAL);
+
+	if (ha->sp_cpu_addr)
+		pci_free_consistent(ha->pdev, sizeof(struct mssp),
+				    ha->sp_cpu_addr, ha->sp_dma_addr);
+
+	free_irq(shost->irq, &sha[ha->board_number]);
+
+	if (shost->dma_channel != NO_DMA)
+		free_dma(shost->dma_channel);
+
+	release_region(shost->io_port, shost->n_io_port);
+	scsi_unregister(shost);
+	return 0;
 }
 
 #include "scsi_module.c"
 
 #ifndef MODULE
 __setup("eata=", option_setup);
-#endif /* end MODULE */
+#endif				/* end MODULE */
diff -Nru a/drivers/scsi/esp.c b/drivers/scsi/esp.c
--- a/drivers/scsi/esp.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/scsi/esp.c	2005-03-01 23:39:17 -08:00
@@ -185,7 +185,7 @@
 
 /* The master ring of all esp hosts we are managing in this driver. */
 static struct esp *espchain;
-static spinlock_t espchain_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(espchain_lock);
 static int esps_running = 0;
 
 /* Forward declarations. */
diff -Nru a/drivers/scsi/fd_mcs.c b/drivers/scsi/fd_mcs.c
--- a/drivers/scsi/fd_mcs.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/scsi/fd_mcs.c	2005-03-01 23:39:18 -08:00
@@ -96,7 +96,6 @@
 
 #include "scsi.h"
 #include <scsi/scsi_host.h>
-#include "fd_mcs.h"
 
 #define DRIVER_VERSION "v0.2 by ZP Gu<zpg@castle.net>"
 
@@ -104,14 +103,12 @@
 
 #define DEBUG            0	/* Enable debugging output */
 #define ENABLE_PARITY    1	/* Enable SCSI Parity */
-#define DO_DETECT        0	/* Do device detection here (see scsi.c) */
 
 /* END OF USER DEFINABLE OPTIONS */
 
 #if DEBUG
 #define EVERY_ACCESS     0	/* Write a line on every scsi access */
 #define ERRORS_ONLY      1	/* Only write a line if there is an error */
-#define DEBUG_DETECT     1	/* Debug fd_mcs_detect() */
 #define DEBUG_MESSAGES   1	/* Debug MESSAGE IN phase */
 #define DEBUG_ABORT      1	/* Debug abort() routine */
 #define DEBUG_RESET      1	/* Debug reset() routine */
@@ -119,7 +116,6 @@
 #else
 #define EVERY_ACCESS     0	/* LEAVE THESE ALONE--CHANGE THE ONES ABOVE */
 #define ERRORS_ONLY      0
-#define DEBUG_DETECT     0
 #define DEBUG_MESSAGES   0
 #define DEBUG_ABORT      0
 #define DEBUG_RESET      0
@@ -432,6 +428,7 @@
 				FIFO_COUNT = user_fifo_count ? user_fifo_count : fd_mcs_adapters[loop].fifo_count;
 				FIFO_Size = user_fifo_size ? user_fifo_size : fd_mcs_adapters[loop].fifo_size;
 
+/* FIXME: Do we need to keep this bit of code inside NOT_USED around at all? */
 #ifdef NOT_USED
 				/* *************************************************** */
 				/* Try to toggle 32-bit mode.  This only
@@ -510,59 +507,6 @@
 				outb(0, SCSI_Mode_Cntl_port);
 				outb(PARITY_MASK, TMC_Cntl_port);
 				/* done reset */
-
-#if DO_DETECT
-				/* scan devices attached */
-				{
-					const int buflen = 255;
-					int i, j, retcode;
-					Scsi_Cmnd SCinit;
-					unsigned char do_inquiry[] = { INQUIRY, 0, 0, 0, buflen, 0 };
-					unsigned char do_request_sense[] = { REQUEST_SENSE,
-						0, 0, 0, buflen, 0
-					};
-					unsigned char do_read_capacity[] = { READ_CAPACITY,
-						0, 0, 0, 0, 0, 0, 0, 0, 0
-					};
-					unsigned char buf[buflen];
-
-					SCinit.request_buffer = SCinit.buffer = buf;
-					SCinit.request_bufflen = SCinit.bufflen = sizeof(buf) - 1;
-					SCinit.use_sg = 0;
-					SCinit.lun = 0;
-					SCinit.host = shpnt;
-
-					printk("fd_mcs: detection routine scanning for devices:\n");
-					for (i = 0; i < 8; i++) {
-						if (i == shpnt->this_id)	/* Skip host adapter */
-							continue;
-						SCinit.target = i;
-						memcpy(SCinit.cmnd, do_request_sense, sizeof(do_request_sense));
-						retcode = fd_mcs_command(&SCinit);
-						if (!retcode) {
-							memcpy(SCinit.cmnd, do_inquiry, sizeof(do_inquiry));
-							retcode = fd_mcs_command(&SCinit);
-							if (!retcode) {
-								printk("     SCSI ID %d: ", i);
-								for (j = 8; j < (buf[4] < 32 ? buf[4] : 32); j++)
-									printk("%c", buf[j] >= 20 ? buf[j] : ' ');
-								memcpy(SCinit.cmnd, do_read_capacity, sizeof(do_read_capacity));
-								retcode = fd_mcs_command(&SCinit);
-								if (!retcode) {
-									unsigned long blocks, size, capacity;
-
-									blocks = (buf[0] << 24) | (buf[1] << 16)
-									    | (buf[2] << 8) | buf[3];
-									size = (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
-									capacity = +(+(blocks / 1024L) * +(size * 10L)) / 1024L;
-
-									printk("%lu MB (%lu byte blocks)\n", ((capacity + 5L) / 10L), size);
-								}
-							}
-						}
-					}
-				}
-#endif
 			}
 		}
 
diff -Nru a/drivers/scsi/fd_mcs.h b/drivers/scsi/fd_mcs.h
--- a/drivers/scsi/fd_mcs.h	2005-03-01 23:38:53 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,37 +0,0 @@
-/* fd_mcs.h -- Header for Future Domain MCS 600/700 (or IBM OEM) driver
- * 
- * fd_mcs.h v0.2 03/11/1998 ZP Gu (zpg@castle.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, or (at your option) any
- * later version.
-
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
-
- * You 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 _FD_MCS_H
-#define _FD_MCS_H
-
-static int fd_mcs_detect(Scsi_Host_Template *);
-static int fd_mcs_release(struct Scsi_Host *);
-static int fd_mcs_command(Scsi_Cmnd *);
-static int fd_mcs_abort(Scsi_Cmnd *);
-static int fd_mcs_bus_reset(Scsi_Cmnd *);
-static int fd_mcs_device_reset(Scsi_Cmnd *);
-static int fd_mcs_host_reset(Scsi_Cmnd *);
-static int fd_mcs_queue(Scsi_Cmnd *, void (*done) (Scsi_Cmnd *));
-static int fd_mcs_biosparam(struct scsi_device *, struct block_device *,
-			    sector_t, int *);
-static const char *fd_mcs_info(struct Scsi_Host *);
-
-#endif				/* _FD_MCS_H */
diff -Nru a/drivers/scsi/fdomain.c b/drivers/scsi/fdomain.c
--- a/drivers/scsi/fdomain.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/scsi/fdomain.c	2005-03-01 23:39:08 -08:00
@@ -409,7 +409,7 @@
 /* Allow insmod parameters to be like LILO parameters.  For example:
    insmod fdomain fdomain=0x140,11 */
 static char * fdomain = NULL;
-MODULE_PARM(fdomain, "s");
+module_param(fdomain, charp, 0);
 
 static unsigned long addresses[] = {
    0xc8000,
diff -Nru a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
--- a/drivers/scsi/g_NCR5380.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/scsi/g_NCR5380.c	2005-03-01 23:38:53 -08:00
@@ -920,13 +920,13 @@
 #include <linux/module.h>
 #include "scsi_module.c"
 
-MODULE_PARM(ncr_irq, "i");
-MODULE_PARM(ncr_dma, "i");
-MODULE_PARM(ncr_addr, "i");
-MODULE_PARM(ncr_5380, "i");
-MODULE_PARM(ncr_53c400, "i");
-MODULE_PARM(ncr_53c400a, "i");
-MODULE_PARM(dtc_3181e, "i");
+module_param(ncr_irq, int, 0);
+module_param(ncr_dma, int, 0);
+module_param(ncr_addr, int, 0);
+module_param(ncr_5380, int, 0);
+module_param(ncr_53c400, int, 0);
+module_param(ncr_53c400a, int, 0);
+module_param(dtc_3181e, int, 0);
 MODULE_LICENSE("GPL");
 
 
diff -Nru a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c
--- a/drivers/scsi/gdth.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/scsi/gdth.c	2005-03-01 23:39:07 -08:00
@@ -397,11 +397,7 @@
 #include <asm/system.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
 #include <linux/spinlock.h>
-#else
-#include <asm/spinlock.h>
-#endif
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
 #include <linux/blkdev.h>
 #else
@@ -412,14 +408,11 @@
 #include "scsi.h"
 #include <scsi/scsi_host.h>
 #include "gdth.h"
+#include "gdth_kcompat.h"
 
 static void gdth_delay(int milliseconds);
 static void gdth_eval_mapping(ulong32 size, ulong32 *cyls, int *heads, int *secs);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
 static irqreturn_t gdth_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-#else
-static void gdth_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-#endif
 static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp);
 static int gdth_async_event(int hanum);
 static void gdth_log_event(gdth_evt_data *dvr, char *buffer);
@@ -617,32 +610,6 @@
     DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN
 };
 
-/* __initfunc, __initdata macros */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-#define GDTH_INITFUNC(type, func)       type __init func 
-#include <linux/init.h>
-#else
-#define GDTH_INITFUNC(type, func)       __initfunc(type func)
-#include <linux/init.h>
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-#define GDTH_INIT_LOCK_HA(ha)           spin_lock_init(&(ha)->smp_lock)
-#define GDTH_LOCK_HA(ha,flags)          spin_lock_irqsave(&(ha)->smp_lock,flags)
-#define GDTH_UNLOCK_HA(ha,flags)        spin_unlock_irqrestore(&(ha)->smp_lock,flags)
-
-#define GDTH_LOCK_SCSI_DONE(dev, flags) spin_lock_irqsave(dev->host_lock,flags)
-#define GDTH_UNLOCK_SCSI_DONE(dev, flags) spin_unlock_irqrestore(dev->host_lock,flags)
-
-#else
-#define GDTH_INIT_LOCK_HA(ha)           spin_lock_init(&(ha)->smp_lock)
-#define GDTH_LOCK_HA(ha,flags)          spin_lock_irqsave(&(ha)->smp_lock,flags)
-#define GDTH_UNLOCK_HA(ha,flags)        spin_unlock_irqrestore(&(ha)->smp_lock,flags)
-
-#define GDTH_LOCK_SCSI_DONE(flags)      spin_lock_irqsave(&io_request_lock,flags)
-#define GDTH_UNLOCK_SCSI_DONE(flags)    spin_unlock_irqrestore(&io_request_lock,flags)
-#endif
-
 /* LILO and modprobe/insmod parameters */
 /* IRQ list for GDT3000/3020 EISA controllers */
 static int irq[MAXHA] __initdata = 
@@ -674,48 +641,29 @@
 /* 64 bit DMA mode, support for drives > 2 TB, if force_dma32 = 0 */
 static int force_dma32 = 0;
 
-#ifdef MODULE
 /* parameters for modprobe/insmod */
-MODULE_PARM(irq, "i");
-MODULE_PARM(disable, "i");
-MODULE_PARM(reserve_mode, "i");
-MODULE_PARM(reserve_list, "4-" __MODULE_STRING(MAX_RES_ARGS) "i");
-MODULE_PARM(reverse_scan, "i");
-MODULE_PARM(hdr_channel, "i");
-MODULE_PARM(max_ids, "i");
-MODULE_PARM(rescan, "i");
-MODULE_PARM(virt_ctr, "i");
-MODULE_PARM(shared_access, "i");
-MODULE_PARM(probe_eisa_isa, "i");
-MODULE_PARM(force_dma32, "i");
+module_param_array(irq, int, NULL, 0);
+module_param(disable, int, 0);
+module_param(reserve_mode, int, 0);
+module_param_array(reserve_list, int, NULL, 0);
+module_param(reverse_scan, int, 0);
+module_param(hdr_channel, int, 0);
+module_param(max_ids, int, 0);
+module_param(rescan, int, 0);
+module_param(virt_ctr, int, 0);
+module_param(shared_access, int, 0);
+module_param(probe_eisa_isa, int, 0);
+module_param(force_dma32, int, 0);
 MODULE_AUTHOR("Achim Leubner");
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,11)
 MODULE_LICENSE("GPL");
-#endif
-#endif
 
 /* ioctl interface */
 static struct file_operations gdth_fops = {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
     .ioctl   = gdth_ioctl,
     .open    = gdth_open,
     .release = gdth_close,
-#else
-    ioctl:gdth_ioctl,
-    open:gdth_open,
-    release:gdth_close,
-#endif
 };
 
-/* /proc support */
-#include <linux/stat.h> 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
-struct proc_dir_entry proc_scsi_gdth = {
-    PROC_SCSI_GDTH, 4, "gdth",
-    S_IFDIR | S_IRUGO | S_IXUGO, 2
-};
-#endif
-
 #include "gdth_proc.h"
 #include "gdth_proc.c"
 
@@ -755,7 +703,7 @@
 
 /* controller search and initialization functions */
 
-GDTH_INITFUNC(static int, gdth_search_eisa(ushort eisa_adr))
+static int __init gdth_search_eisa(ushort eisa_adr)
 {
     ulong32 id;
     
@@ -773,7 +721,7 @@
 }
 
 
-GDTH_INITFUNC(static int, gdth_search_isa(ulong32 bios_adr))
+static int __init gdth_search_isa(ulong32 bios_adr)
 {
     void __iomem *addr;
     ulong32 id;
@@ -789,7 +737,7 @@
 }
 
 
-GDTH_INITFUNC(static int, gdth_search_pci(gdth_pci_str *pcistr))
+static int __init gdth_search_pci(gdth_pci_str *pcistr)
 {
     ushort device, cnt;
     
@@ -812,21 +760,19 @@
     return cnt;
 }
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
 /* Vortex only makes RAID controllers.
  * We do not really want to specify all 550 ids here, so wildcard match.
  */
-static struct pci_device_id gdthtable[] __devinitdata = {
+static struct pci_device_id gdthtable[] __attribute_used__ = {
     {PCI_VENDOR_ID_VORTEX,PCI_ANY_ID,PCI_ANY_ID, PCI_ANY_ID},
     {PCI_VENDOR_ID_INTEL,PCI_DEVICE_ID_INTEL_SRC,PCI_ANY_ID,PCI_ANY_ID}, 
     {PCI_VENDOR_ID_INTEL,PCI_DEVICE_ID_INTEL_SRC_XSCALE,PCI_ANY_ID,PCI_ANY_ID}, 
     {0}
 };
 MODULE_DEVICE_TABLE(pci,gdthtable);
-#endif
 
-GDTH_INITFUNC(static void, gdth_search_dev(gdth_pci_str *pcistr, ushort *cnt,
-                                           ushort vendor, ushort device))
+static void __init gdth_search_dev(gdth_pci_str *pcistr, ushort *cnt,
+                                           ushort vendor, ushort device)
 {
     ulong base0, base1, base2;
     struct pci_dev *pdev;
@@ -834,7 +780,6 @@
     TRACE(("gdth_search_dev() cnt %d vendor %x device %x\n",
           *cnt, vendor, device));
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
     pdev = NULL;
     while ((pdev = pci_find_device(vendor, device, pdev)) 
            != NULL) {
@@ -872,52 +817,10 @@
                 pcistr[*cnt].irq, pcistr[*cnt].dpmem));
         (*cnt)++;
     }       
-#else
-    pdev = NULL;
-    while ((pdev = pci_find_device(vendor, device, pdev)) 
-           != NULL) {
-        if (*cnt >= MAXHA)
-            return;
-        /* GDT PCI controller found, resources are already in pdev */
-        pcistr[*cnt].pdev = pdev;
-        pcistr[*cnt].vendor_id = vendor;
-        pcistr[*cnt].device_id = device;
-        pcistr[*cnt].bus = pdev->bus->number;
-        pcistr[*cnt].device_fn = pdev->devfn;
-        pcibios_read_config_word(pcistr[*cnt].bus, pcistr[*cnt].device_fn,
-                                 PCI_SUBSYSTEM_ID, &pcistr[*cnt].subdevice_id);
-        pcistr[*cnt].irq = pdev->irq;
-        base0 = pdev->base_address[0];
-        base1 = pdev->base_address[1];
-        base2 = pdev->base_address[2];
-        if (device <= PCI_DEVICE_ID_VORTEX_GDT6000B ||   /* GDT6000/B */
-            device >= PCI_DEVICE_ID_VORTEX_GDT6x17RP) {  /* MPR */
-            if ((base0 & PCI_BASE_ADDRESS_SPACE) != 
-                PCI_BASE_ADDRESS_SPACE_MEMORY)
-                continue;
-            pcistr[*cnt].dpmem = base0 & PCI_BASE_ADDRESS_MEM_MASK;
-        } else {                                  /* GDT6110, GDT6120, .. */
-            if ((base0 & PCI_BASE_ADDRESS_SPACE) !=
-                PCI_BASE_ADDRESS_SPACE_MEMORY ||
-                (base2 & PCI_BASE_ADDRESS_SPACE) !=
-                PCI_BASE_ADDRESS_SPACE_MEMORY ||
-                (base1 & PCI_BASE_ADDRESS_SPACE) !=
-                PCI_BASE_ADDRESS_SPACE_IO)
-                continue;
-            pcistr[*cnt].dpmem = base2 & PCI_BASE_ADDRESS_MEM_MASK;
-            pcistr[*cnt].io_mm = base0 & PCI_BASE_ADDRESS_MEM_MASK;
-            pcistr[*cnt].io    = base1 & PCI_BASE_ADDRESS_IO_MASK;
-        }
-        TRACE2(("Controller found at %d/%d, irq %d, dpmem 0x%lx\n",
-                pcistr[*cnt].bus, PCI_SLOT(pcistr[*cnt].device_fn), 
-                pcistr[*cnt].irq, pcistr[*cnt].dpmem));
-        (*cnt)++;
-    }       
-#endif
 }   
 
 
-GDTH_INITFUNC(static void, gdth_sort_pci(gdth_pci_str *pcistr, int cnt))
+static void __init gdth_sort_pci(gdth_pci_str *pcistr, int cnt)
 {    
     gdth_pci_str temp;
     int i, changed;
@@ -955,7 +858,7 @@
 }
 
 
-GDTH_INITFUNC(static int, gdth_init_eisa(ushort eisa_adr,gdth_ha_str *ha))
+static int __init gdth_init_eisa(ushort eisa_adr,gdth_ha_str *ha)
 {
     ulong32 retries,id;
     unchar prot_ver,eisacf,i,irq_found;
@@ -1048,7 +951,7 @@
 }
 
        
-GDTH_INITFUNC(static int, gdth_init_isa(ulong32 bios_adr,gdth_ha_str *ha))
+static int __init gdth_init_isa(ulong32 bios_adr,gdth_ha_str *ha)
 {
     register gdt2_dpram_str __iomem *dp2_ptr;
     int i;
@@ -1148,7 +1051,7 @@
 }
 
 
-GDTH_INITFUNC(static int, gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha))
+static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha)
 {
     register gdt6_dpram_str __iomem *dp6_ptr;
     register gdt6c_dpram_str __iomem *dp6c_ptr;
@@ -1168,9 +1071,7 @@
     ha->stype = (ulong32)pcistr->device_id;
     ha->subdevice_id = pcistr->subdevice_id;
     ha->irq = pcistr->irq;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
     ha->pdev = pcistr->pdev;
-#endif
     
     if (ha->stype <= PCI_DEVICE_ID_VORTEX_GDT6000B) {  /* GDT6000/B */
         TRACE2(("init_pci() dpmem %lx irq %d\n",pcistr->dpmem,ha->irq));
@@ -1401,7 +1302,6 @@
         }
 
         /* manipulate config. space to enable DPMEM, start RP controller */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
         pci_read_config_word(pcistr->pdev, PCI_COMMAND, &command);
         command |= 6;
         pci_write_config_word(pcistr->pdev, PCI_COMMAND, command);
@@ -1412,18 +1312,6 @@
         gdth_delay(1);
         pci_write_config_dword(pcistr->pdev, PCI_ROM_ADDRESS,
                                pci_resource_start(pcistr->pdev, 8));
-#else
-        pci_read_config_word(pcistr->pdev, PCI_COMMAND, &command);
-        command |= 6;
-        pci_write_config_word(pcistr->pdev, PCI_COMMAND, command);
-        if (pcistr->pdev->rom_address == 1UL)
-            pcistr->pdev->rom_address = 0UL;
-        i = 0xFEFF0001UL;
-        pci_write_config_dword(pcistr->pdev, PCI_ROM_ADDRESS, i);
-        gdth_delay(1);
-        pci_write_config_dword(pcistr->pdev, PCI_ROM_ADDRESS,
-                               pcistr->pdev->rom_address);
-#endif
         
         dp6m_ptr = ha->brd;
 
@@ -1550,7 +1438,7 @@
 
 /* controller protocol functions */
 
-GDTH_INITFUNC(static void, gdth_enable_int(int hanum))
+static void __init gdth_enable_int(int hanum)
 {
     gdth_ha_str *ha;
     ulong flags;
@@ -1560,7 +1448,7 @@
 
     TRACE(("gdth_enable_int() hanum %d\n",hanum));
     ha = HADATA(gdth_ctr_tab[hanum]);
-    GDTH_LOCK_HA(ha, flags);
+    spin_lock_irqsave(&ha->smp_lock, flags);
 
     if (ha->type == GDT_EISA) {
         outb(0xff, ha->bmic + EDOORREG);
@@ -1585,7 +1473,7 @@
         gdth_writeb(gdth_readb(&dp6m_ptr->i960r.edoor_en_reg) & ~4,
                     &dp6m_ptr->i960r.edoor_en_reg);
     }
-    GDTH_UNLOCK_HA(ha, flags);
+    spin_unlock_irqrestore(&ha->smp_lock, flags);
 }
 
 
@@ -1897,7 +1785,7 @@
 
 /* search for devices */
 
-GDTH_INITFUNC(static int, gdth_search_drives(int hanum))
+static int __init gdth_search_drives(int hanum)
 {
     register gdth_ha_str *ha;
     ushort cdev_cnt, i;
@@ -2357,16 +2245,11 @@
 
     TRACE(("gdth_putq() priority %d\n",priority));
     ha = HADATA(gdth_ctr_tab[hanum]);
-    GDTH_LOCK_HA(ha, flags);
+    spin_lock_irqsave(&ha->smp_lock, flags);
 
     scp->SCp.this_residual = (int)priority;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
     b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel;
     t = scp->device->id;
-#else
-    b = virt_ctr ? NUMDATA(scp->host)->busnum : scp->channel;
-    t = scp->target;
-#endif
     if (priority >= DEFAULT_PRI) {
         if ((b != ha->virt_bus && ha->raw[BUS_L2P(ha,b)].lock) ||
             (b == ha->virt_bus && t < MAX_HDRIVES && ha->hdr[t].lock)) {
@@ -2389,7 +2272,7 @@
         pscp->SCp.ptr = (char *)scp;
         scp->SCp.ptr  = (char *)nscp;
     }
-    GDTH_UNLOCK_HA(ha, flags);
+    spin_unlock_irqrestore(&ha->smp_lock, flags);
 
 #ifdef GDTH_STATISTICS
     flags = 0;
@@ -2415,7 +2298,7 @@
     TRACE(("gdth_next() hanum %d\n",hanum));
     ha = HADATA(gdth_ctr_tab[hanum]);
     if (!gdth_polling) 
-        GDTH_LOCK_HA(ha, flags);
+        spin_lock_irqsave(&ha->smp_lock, flags);
 
     ha->cmd_cnt = ha->cmd_offs_dpmem = 0;
     this_cmd = firsttime = TRUE;
@@ -2425,15 +2308,9 @@
     for (nscp = pscp = ha->req_first; nscp; nscp = (Scsi_Cmnd *)nscp->SCp.ptr) {
         if (nscp != pscp && nscp != (Scsi_Cmnd *)pscp->SCp.ptr)
             pscp = (Scsi_Cmnd *)pscp->SCp.ptr;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
         b = virt_ctr ? NUMDATA(nscp->device->host)->busnum : nscp->device->channel;
         t = nscp->device->id;
         l = nscp->device->lun;
-#else
-        b = virt_ctr ? NUMDATA(nscp->host)->busnum : nscp->channel;
-        t = nscp->target;
-        l = nscp->lun;
-#endif
         if (nscp->SCp.this_residual >= DEFAULT_PRI) {
             if ((b != ha->virt_bus && ha->raw[BUS_L2P(ha,b)].lock) ||
                 (b == ha->virt_bus && t < MAX_HDRIVES && ha->hdr[t].lock)) 
@@ -2444,7 +2321,7 @@
             if (gdth_test_busy(hanum)) {        /* controller busy ? */
                 TRACE(("gdth_next() controller %d busy !\n",hanum));
                 if (!gdth_polling) {
-                    GDTH_UNLOCK_HA(ha, flags);
+                    spin_unlock_irqrestore(&ha->smp_lock, flags);
                     return;
                 }
                 while (gdth_test_busy(hanum))
@@ -2513,14 +2390,8 @@
                 nscp->result = (DID_OK << 16) | (CHECK_CONDITION << 1);
                 if (!nscp->SCp.have_data_in)
                     nscp->SCp.have_data_in++;
-                else {
-                    if (!gdth_polling) 
-                        GDTH_UNLOCK_HA(ha,flags);
-                    /* io_request_lock already active ! */
+                else
                     nscp->scsi_done(nscp);
-                    if (!gdth_polling) 
-                        GDTH_LOCK_HA(ha,flags);
-                }
             }
         } else if (nscp->done == gdth_scsi_done && nscp->cmnd[0] == 0xff) {
             if (!(cmd_index=gdth_special_cmd(hanum,nscp)))
@@ -2538,14 +2409,8 @@
             nscp->result = DID_BAD_TARGET << 16;
             if (!nscp->SCp.have_data_in)
                 nscp->SCp.have_data_in++;
-            else {
-                if (!gdth_polling) 
-                    GDTH_UNLOCK_HA(ha,flags);
-                /* io_request_lock already active ! */      
+            else
                 nscp->scsi_done(nscp);
-                if (!gdth_polling) 
-                    GDTH_LOCK_HA(ha,flags);
-            }
         } else {
             switch (nscp->cmnd[0]) {
               case TEST_UNIT_READY:
@@ -2555,9 +2420,7 @@
               case VERIFY:
               case START_STOP:
               case MODE_SENSE:
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
               case SERVICE_ACTION_IN:
-#endif
                 TRACE(("cache cmd %x/%x/%x/%x/%x/%x\n",nscp->cmnd[0],
                        nscp->cmnd[1],nscp->cmnd[2],nscp->cmnd[3],
                        nscp->cmnd[4],nscp->cmnd[5]));
@@ -2572,22 +2435,10 @@
                     nscp->result = (DID_OK << 16) | (CHECK_CONDITION << 1);
                     if (!nscp->SCp.have_data_in)
                         nscp->SCp.have_data_in++;
-                    else {
-                        if (!gdth_polling) 
-                            GDTH_UNLOCK_HA(ha,flags);
-                        /* io_request_lock already active ! */      
+                    else
                         nscp->scsi_done(nscp);
-                        if (!gdth_polling) 
-                            GDTH_LOCK_HA(ha,flags);
-                    }
-                } else if (gdth_internal_cache_cmd(hanum,nscp)) {
-                    if (!gdth_polling) 
-                        GDTH_UNLOCK_HA(ha,flags);
-                    /* io_request_lock already active ! */      
+                } else if (gdth_internal_cache_cmd(hanum,nscp))
                     nscp->scsi_done(nscp);
-                    if (!gdth_polling) 
-                        GDTH_LOCK_HA(ha,flags);
-                }
                 break;
 
               case ALLOW_MEDIUM_REMOVAL:
@@ -2600,14 +2451,8 @@
                     nscp->sense_buffer[0] = 0;
                     if (!nscp->SCp.have_data_in)
                         nscp->SCp.have_data_in++;
-                    else {
-                        if (!gdth_polling) 
-                            GDTH_UNLOCK_HA(ha,flags);
-                        /* io_request_lock already active ! */      
+                    else
                         nscp->scsi_done(nscp);
-                        if (!gdth_polling) 
-                            GDTH_LOCK_HA(ha,flags);
-                    }
                 } else {
                     nscp->cmnd[3] = (ha->hdr[t].devtype&1) ? 1:0;
                     TRACE(("Prevent/allow r. %d rem. drive %d\n",
@@ -2629,10 +2474,8 @@
               case WRITE_6:
               case READ_10:
               case WRITE_10:
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
               case READ_16:
               case WRITE_16:
-#endif
                 if (ha->hdr[t].media_changed) {
                     /* return UNIT_ATTENTION */
                     TRACE2(("cmd 0x%x target %d: UNIT_ATTENTION\n",
@@ -2644,14 +2487,8 @@
                     nscp->result = (DID_OK << 16) | (CHECK_CONDITION << 1);
                     if (!nscp->SCp.have_data_in)
                         nscp->SCp.have_data_in++;
-                    else {
-                        if (!gdth_polling) 
-                            GDTH_UNLOCK_HA(ha,flags);
-                        /* io_request_lock already active ! */      
+                    else
                         nscp->scsi_done(nscp);
-                        if (!gdth_polling) 
-                            GDTH_LOCK_HA(ha,flags);
-                    }
                 } else if (!(cmd_index=gdth_fill_cache_cmd(hanum,nscp,t)))
                     this_cmd = FALSE;
                 break;
@@ -2665,14 +2502,8 @@
                 nscp->result = DID_ABORT << 16;
                 if (!nscp->SCp.have_data_in)
                     nscp->SCp.have_data_in++;
-                else {
-                    if (!gdth_polling) 
-                        GDTH_UNLOCK_HA(ha,flags);
-                    /* io_request_lock already active ! */  
+                else
                     nscp->scsi_done(nscp);
-                    if (!gdth_polling) 
-                        GDTH_LOCK_HA(ha,flags);
-                }
                 break;
             }
         }
@@ -2692,7 +2523,7 @@
     }
 
     if (!gdth_polling) 
-        GDTH_UNLOCK_HA(ha, flags);
+        spin_unlock_irqrestore(&ha->smp_lock, flags);
 
     if (gdth_polling && ha->cmd_cnt > 0) {
         if (!gdth_wait(hanum,cmd_index,POLL_TIMEOUT))
@@ -2708,7 +2539,6 @@
     ushort cpsum,cpnow;
     struct scatterlist *sl;
     gdth_ha_str *ha;
-    int sgcnt;
     char *address;
 
     cpcount = count<=(ushort)scp->bufflen ? count:(ushort)scp->bufflen;
@@ -2716,10 +2546,9 @@
 
     if (scp->use_sg) {
         sl = (struct scatterlist *)scp->request_buffer;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,13)
-        sgcnt = pci_map_sg(ha->pdev,sl,scp->use_sg,PCI_DMA_FROMDEVICE);
-        for (i=0,cpsum=0; i<sgcnt; ++i,++sl) {
-            cpnow = (ushort)sg_dma_len(sl);
+        for (i=0,cpsum=0; i<scp->use_sg; ++i,++sl) {
+	    unsigned long flags;
+            cpnow = (ushort)sl->length;
             TRACE(("copy_internal() now %d sum %d count %d %d\n",
                           cpnow,cpsum,cpcount,(ushort)scp->bufflen));
             if (cpsum+cpnow > cpcount) 
@@ -2730,30 +2559,16 @@
                        hanum);
                 return;
             }
-            address = (char *)(page_address(sl->page) + sl->offset);
-            memcpy(address,buffer,cpnow);
-            if (cpsum == cpcount)
-                break;
-            buffer += cpnow;
-        }
-        pci_unmap_sg(ha->pdev,scp->request_buffer,
-                     scp->use_sg,PCI_DMA_FROMDEVICE);
-#else
-        sgcnt = scp->use_sg;
-        for (i=0,cpsum=0; i<sgcnt; ++i,++sl) {
-            cpnow = (ushort)sl->length;
-            TRACE(("copy_internal() now %d sum %d count %d %d\n",
-                          cpnow,cpsum,cpcount,(ushort)scp->bufflen));
-            if (cpsum+cpnow > cpcount) 
-               cpnow = cpcount - cpsum;
-            cpsum += cpnow;
-            address = (char *)sl->address;
+	    local_irq_save(flags);
+	    address = kmap_atomic(sl->page, KM_BIO_SRC_IRQ) + sl->offset;
             memcpy(address,buffer,cpnow);
+	    flush_dcache_page(sl->page);
+	    kunmap_atomic(address, KM_BIO_SRC_IRQ);
+	    local_irq_restore(flags);
             if (cpsum == cpcount)
                 break;
             buffer += cpnow;
         }
-#endif
     } else {
         TRACE(("copy_internal() count %d\n",cpcount));
         memcpy((char*)scp->request_buffer,buffer,cpcount);
@@ -2770,11 +2585,7 @@
     gdth_modep_data mpd;
 
     ha = HADATA(gdth_ctr_tab[hanum]);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
     t  = scp->device->id;
-#else
-    t  = scp->target;
-#endif
     TRACE(("gdth_internal_cache_cmd() cmd 0x%x hdrive %d\n",
            scp->cmnd[0],t));
 
@@ -2839,7 +2650,6 @@
         gdth_copy_internal_data(hanum,scp,(char*)&rdc,sizeof(gdth_rdcap_data));
         break;
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
       case SERVICE_ACTION_IN:
         if ((scp->cmnd[1] & 0x1f) == SAI_READ_CAPACITY_16 &&
             (ha->cache_feat & GDT_64BIT)) {
@@ -2853,7 +2663,6 @@
             scp->result = DID_ABORT << 16;
         }
         break;
-#endif
 
       default:
         TRACE2(("Internal cache cmd 0x%x unknown\n",scp->cmnd[0]));
@@ -2877,10 +2686,8 @@
     ulong64 no, blockno;
     dma_addr_t phys_addr;
     int i, cmd_index, read_write, sgcnt, mode64;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,13)
     struct page *page;
     ulong offset;
-#endif
 
     ha = HADATA(gdth_ctr_tab[hanum]);
     cmdp = ha->pccb;
@@ -2922,10 +2729,7 @@
         else
             cmdp->OpCode = GDT_FLUSH;
     } else if (scp->cmnd[0] == WRITE_6 || scp->cmnd[0] == WRITE_10 ||
-               scp->cmnd[0] == WRITE_12 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-               || scp->cmnd[0] == WRITE_16
-#endif
+               scp->cmnd[0] == WRITE_12 || scp->cmnd[0] == WRITE_16
     ) {
         read_write = 1;
         if (gdth_write_through || ((ha->hdr[hdrive].rw_attribs & 1) && 
@@ -2976,7 +2780,6 @@
         if (scp->use_sg) {
             sl = (struct scatterlist *)scp->request_buffer;
             sgcnt = scp->use_sg;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,13)
             scp->SCp.Status = GDTH_MAP_SG;
             scp->SCp.Message = (read_write == 1 ? 
                 PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE);   
@@ -3005,23 +2808,6 @@
                     cmdp->u.cache.sg_lst[i].sg_len = sg_dma_len(sl);
                 }
             }
-#else
-            if (mode64) {
-                cmdp->u.cache64.DestAddr= (ulong64)-1;
-                cmdp->u.cache64.sg_canz = sgcnt;
-                for (i=0; i<sgcnt; ++i,++sl) {
-                    cmdp->u.cache64.sg_lst[i].sg_ptr = virt_to_bus(sl->address);
-                    cmdp->u.cache64.sg_lst[i].sg_len = (ulong32)sl->length;
-                }
-            } else {
-                cmdp->u.cache.DestAddr= 0xffffffff;
-                cmdp->u.cache.sg_canz = sgcnt;
-                for (i=0; i<sgcnt; ++i,++sl) {
-                    cmdp->u.cache.sg_lst[i].sg_ptr = virt_to_bus(sl->address);
-                    cmdp->u.cache.sg_lst[i].sg_len = (ulong32)sl->length;
-                }
-            }
-#endif
 
 #ifdef GDTH_STATISTICS
             if (max_sg < (ulong32)sgcnt) {
@@ -3031,7 +2817,6 @@
 #endif
 
         } else {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,13)
             scp->SCp.Status = GDTH_MAP_SINGLE;
             scp->SCp.Message = (read_write == 1 ? 
                 PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE);
@@ -3040,9 +2825,6 @@
             phys_addr = pci_map_page(ha->pdev,page,offset,
                                      scp->request_bufflen,scp->SCp.Message);
             scp->SCp.dma_handle = phys_addr;
-#else
-            phys_addr = virt_to_bus(scp->request_buffer);
-#endif
             if (mode64) {
                 if (ha->cache_feat & SCATTER_GATHER) {
                     cmdp->u.cache64.DestAddr = (ulong64)-1;
@@ -3114,19 +2896,12 @@
     dma_addr_t phys_addr, sense_paddr;
     int cmd_index, sgcnt, mode64;
     unchar t,l;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,13)
     struct page *page;
     ulong offset;
-#endif
 
     ha = HADATA(gdth_ctr_tab[hanum]);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
     t = scp->device->id;
     l = scp->device->lun;
-#else
-    t = scp->target;
-    l = scp->lun;
-#endif
     cmdp = ha->pccb;
     TRACE(("gdth_fill_raw_cmd() cmd 0x%x bus %d ID %d LUN %d\n",
            scp->cmnd[0],b,t,l));
@@ -3166,7 +2941,6 @@
         }
 
     } else {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,13)
         page = virt_to_page(scp->sense_buffer);
         offset = (ulong)scp->sense_buffer & ~PAGE_MASK;
         sense_paddr = pci_map_page(ha->pdev,page,offset,
@@ -3174,9 +2948,6 @@
         scp->SCp.buffer = (struct scatterlist *)((ulong32)sense_paddr);
         /* high part, if 64bit */
         scp->host_scribble = (char *)(ulong32)((ulong64)sense_paddr >> 32);
-#else
-        sense_paddr = virt_to_bus(scp->sense_buffer);
-#endif
         cmdp->OpCode           = GDT_WRITE;             /* always */
         cmdp->BoardNode        = LOCALBOARD;
         if (mode64) { 
@@ -3215,7 +2986,6 @@
         if (scp->use_sg) {
             sl = (struct scatterlist *)scp->request_buffer;
             sgcnt = scp->use_sg;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,13)
             scp->SCp.Status = GDTH_MAP_SG;
             scp->SCp.Message = PCI_DMA_BIDIRECTIONAL; 
             sgcnt = pci_map_sg(ha->pdev,sl,scp->use_sg,scp->SCp.Message);
@@ -3243,23 +3013,6 @@
                     cmdp->u.raw.sg_lst[i].sg_len = sg_dma_len(sl);
                 }
             }
-#else
-            if (mode64) {
-                cmdp->u.raw64.sdata = (ulong64)-1;
-                cmdp->u.raw64.sg_ranz = sgcnt;
-                for (i=0; i<sgcnt; ++i,++sl) {
-                    cmdp->u.raw64.sg_lst[i].sg_ptr = virt_to_bus(sl->address);
-                    cmdp->u.raw64.sg_lst[i].sg_len = (ulong32)sl->length;
-                }
-            } else {
-                cmdp->u.raw.sdata = 0xffffffff;
-                cmdp->u.raw.sg_ranz = sgcnt;
-                for (i=0; i<sgcnt; ++i,++sl) {
-                    cmdp->u.raw.sg_lst[i].sg_ptr = virt_to_bus(sl->address);
-                    cmdp->u.raw.sg_lst[i].sg_len = (ulong32)sl->length;
-                }
-            }
-#endif
 
 #ifdef GDTH_STATISTICS
             if (max_sg < sgcnt) {
@@ -3269,7 +3022,6 @@
 #endif
 
         } else {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,13)
             scp->SCp.Status = GDTH_MAP_SINGLE;
             scp->SCp.Message = PCI_DMA_BIDIRECTIONAL; 
             page = virt_to_page(scp->request_buffer);
@@ -3277,9 +3029,7 @@
             phys_addr = pci_map_page(ha->pdev,page,offset,
                                      scp->request_bufflen,scp->SCp.Message);
             scp->SCp.dma_handle = phys_addr;
-#else
-            phys_addr = virt_to_bus(scp->request_buffer);
-#endif
+
             if (mode64) {
                 if (ha->raw_feat & SCATTER_GATHER) {
                     cmdp->u.raw64.sdata  = (ulong64)-1;
@@ -3461,7 +3211,7 @@
     ulong flags;
 
     TRACE2(("gdth_read_event() handle %d\n", handle));
-    GDTH_LOCK_HA(ha, flags);
+    spin_lock_irqsave(&ha->smp_lock, flags);
     if (handle == -1)
         eindex = eoldidx;
     else
@@ -3469,7 +3219,7 @@
     estr->event_source = 0;
 
     if (eindex >= MAX_EVENTS) {
-        GDTH_UNLOCK_HA(ha, flags);
+        spin_unlock_irqrestore(&ha->smp_lock, flags);
         return eindex;
     }
     e = &ebuffer[eindex];
@@ -3482,7 +3232,7 @@
         }
         memcpy(estr, e, sizeof(gdth_evt_str));
     }
-    GDTH_UNLOCK_HA(ha, flags);
+    spin_unlock_irqrestore(&ha->smp_lock, flags);
     return eindex;
 }
 
@@ -3495,7 +3245,7 @@
     unchar found = FALSE;
 
     TRACE2(("gdth_readapp_event() app. %d\n", application));
-    GDTH_LOCK_HA(ha, flags);
+    spin_lock_irqsave(&ha->smp_lock, flags);
     eindex = eoldidx;
     for (;;) {
         e = &ebuffer[eindex];
@@ -3515,7 +3265,7 @@
         memcpy(estr, e, sizeof(gdth_evt_str));
     else
         estr->event_source = 0;
-    GDTH_UNLOCK_HA(ha, flags);
+    spin_unlock_irqrestore(&ha->smp_lock, flags);
 }
 
 static void gdth_clear_events(void)
@@ -3529,12 +3279,9 @@
 
 /* SCSI interface functions */
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
 static irqreturn_t gdth_interrupt(int irq,void *dev_id,struct pt_regs *regs)
-#else
-static void gdth_interrupt(int irq,void *dev_id,struct pt_regs *regs)
-#endif
 {
+    gdth_ha_str *ha2 = (gdth_ha_str *)dev_id;
     register gdth_ha_str *ha;
     gdt6m_dpram_str __iomem *dp6m_ptr = NULL;
     gdt6_dpram_str __iomem *dp6_ptr;
@@ -3556,28 +3303,20 @@
     /* if polling and not from gdth_wait() -> return */
     if (gdth_polling) {
         if (!gdth_from_wait) {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
             return IRQ_HANDLED;
-#else
-            return;             
-#endif
         }
     }
 
     if (!gdth_polling)
-        GDTH_LOCK_HA((gdth_ha_str *)dev_id,flags);
+	spin_lock_irqsave(&ha2->smp_lock, flags);
     wait_index = 0;
 
     /* search controller */
     if ((hanum = gdth_get_status(&IStatus,irq)) == -1) {
         /* spurious interrupt */
         if (!gdth_polling)
-            GDTH_UNLOCK_HA((gdth_ha_str *)dev_id,flags);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+            spin_unlock_irqrestore(&ha2->smp_lock, flags);
             return IRQ_HANDLED;
-#else
-            return;             
-#endif
     }
     ha = HADATA(gdth_ctr_tab[hanum]);
 
@@ -3711,12 +3450,8 @@
         } else {
             TRACE2(("gdth_interrupt() unknown controller type\n"));
             if (!gdth_polling)
-                GDTH_UNLOCK_HA((gdth_ha_str *)dev_id,flags);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+                spin_unlock_irqrestore(&ha2->smp_lock, flags);
             return IRQ_HANDLED;
-#else
-            return;             
-#endif
         }
 
         TRACE(("gdth_interrupt() index %d stat %d info %d\n",
@@ -3731,13 +3466,9 @@
             TRACE2(("gdth_interrupt() async. event\n"));
             gdth_async_event(hanum);
             if (!gdth_polling)
-                GDTH_UNLOCK_HA((gdth_ha_str *)dev_id,flags);
+                spin_unlock_irqrestore(&ha2->smp_lock, flags);
             gdth_next(hanum);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
             return IRQ_HANDLED;
-#else
-            return;             
-#endif
         } 
 
         if (IStatus == SPEZINDEX) {
@@ -3746,12 +3477,8 @@
             ha->dvr.eu.driver.ionode = hanum;
             gdth_store_event(ha, ES_DRIVER, 4, &ha->dvr);
             if (!gdth_polling)
-                GDTH_UNLOCK_HA((gdth_ha_str *)dev_id,flags);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+                spin_unlock_irqrestore(&ha2->smp_lock, flags);
             return IRQ_HANDLED;
-#else
-            return;             
-#endif
         }
         scp     = ha->cmd_tab[IStatus-2].cmnd;
         Service = ha->cmd_tab[IStatus-2].service;
@@ -3763,40 +3490,24 @@
             ha->dvr.eu.driver.index = IStatus;
             gdth_store_event(ha, ES_DRIVER, 1, &ha->dvr);
             if (!gdth_polling)
-                GDTH_UNLOCK_HA((gdth_ha_str *)dev_id,flags);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+                spin_unlock_irqrestore(&ha2->smp_lock, flags);
             return IRQ_HANDLED;
-#else
-            return;             
-#endif
         }
         if (scp == INTERNAL_CMND) {
             TRACE(("gdth_interrupt() answer to internal command\n"));
             if (!gdth_polling)
-                GDTH_UNLOCK_HA((gdth_ha_str *)dev_id,flags);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+                spin_unlock_irqrestore(&ha2->smp_lock, flags);
             return IRQ_HANDLED;
-#else
-            return;             
-#endif
         }
 
         TRACE(("gdth_interrupt() sync. status\n"));
         rval = gdth_sync_event(hanum,Service,IStatus,scp);
         if (!gdth_polling)
-            GDTH_UNLOCK_HA((gdth_ha_str *)dev_id,flags);
+            spin_unlock_irqrestore(&ha2->smp_lock, flags);
         if (rval == 2) {
             gdth_putq(hanum,scp,scp->SCp.this_residual);
         } else if (rval == 1) {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-            GDTH_LOCK_SCSI_DONE(scp->device->host, flags);
-            scp->scsi_done(scp);
-            GDTH_UNLOCK_SCSI_DONE(scp->device->host, flags);
-#else
-            GDTH_LOCK_SCSI_DONE(flags);
             scp->scsi_done(scp);
-            GDTH_UNLOCK_SCSI_DONE(flags);
-#endif
         }
 
 #ifdef INT_COAL
@@ -3825,9 +3536,7 @@
 #endif
 
     gdth_next(hanum);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
     return IRQ_HANDLED;
-#endif
 }
 
 static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp)
@@ -3911,13 +3620,8 @@
         printk("\n");
 
     } else {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
         b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel;
         t = scp->device->id;
-#else
-        b = virt_ctr ? NUMDATA(scp->host)->busnum : scp->channel;
-        t = scp->target;
-#endif
         if (scp->SCp.sent_command == -1 && b != ha->virt_bus) {
             ha->raw[BUS_L2P(ha,b)].io_cnt[t]--;
         }
@@ -3929,7 +3633,6 @@
             /* retry */
             return 2;
         }
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,13)
         if (scp->SCp.Status == GDTH_MAP_SG) 
             pci_unmap_sg(ha->pdev,scp->request_buffer,
                          scp->use_sg,scp->SCp.Message);
@@ -3943,7 +3646,7 @@
                 addr += (dma_addr_t)((ulong64)(ulong32)scp->host_scribble << 32);               
             pci_unmap_page(ha->pdev,addr,16,PCI_DMA_FROMDEVICE);
         }
-#endif
+
         if (ha->status == S_OK) {
             scp->SCp.Status = S_OK;
             scp->SCp.Message = ha->info;
@@ -4340,7 +4043,7 @@
     int hanum = 0;
 
     ha = HADATA(gdth_ctr_tab[hanum]);
-    GDTH_LOCK_HA(ha, flags);
+    spin_lock_irqsave(&ha->smp_lock, flags);
 
     for (act_stats=0,i=0; i<GDTH_MAXCMDS; ++i) 
         if (ha->cmd_tab[i].cmnd != UNUSED_CMND)
@@ -4355,11 +4058,11 @@
 
     gdth_timer.expires = jiffies + 30 * HZ;
     add_timer(&gdth_timer);
-    GDTH_UNLOCK_HA(ha, flags);
+    spin_unlock_irqrestore(&ha->smp_lock, flags);
 }
 #endif
 
-GDTH_INITFUNC(void, internal_setup(char *str,int *ints))
+void __init internal_setup(char *str,int *ints)
 {
     int i, argc;
     char *cur_str, *argv;
@@ -4432,7 +4135,7 @@
     }
 }
 
-GDTH_INITFUNC(int, option_setup(char *str))
+int __init option_setup(char *str)
 {
     int ints[MAXHA];
     char *cur = str;
@@ -4450,7 +4153,7 @@
     return 1;
 }
 
-GDTH_INITFUNC(int, gdth_detect(Scsi_Host_Template *shtp))
+int __init gdth_detect(Scsi_Host_Template *shtp)
 {
     struct Scsi_Host *shp;
     gdth_pci_str pcistr[MAXHA];
@@ -4540,7 +4243,6 @@
 
                 ha->pccb = CMDDATA(shp);
                 ha->ccb_phys = 0L;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
                 ha->pdev = NULL;
                 ha->pscratch = pci_alloc_consistent(ha->pdev, GDTH_SCRATCH, 
                                                     &scratch_dma_handle);
@@ -4554,21 +4256,7 @@
                         MAXOFFSETS, &scratch_dma_handle);
                 ha->coal_stat_phys = scratch_dma_handle;
 #endif
-#else
-                ha->pscratch = scsi_init_malloc(GDTH_SCRATCH, GFP_ATOMIC | GFP_DMA);
-                if (ha->pscratch)
-                    ha->scratch_phys = virt_to_bus(ha->pscratch);
-                ha->pmsg = scsi_init_malloc(sizeof(gdth_msg_str), GFP_ATOMIC | GFP_DMA);
-                if (ha->pmsg)
-                    ha->msg_phys = virt_to_bus(ha->pmsg);
-#ifdef INT_COAL
-                ha->coal_stat = 
-                    scsi_init_malloc(sizeof(gdth_coal_status) * MAXOFFSETS, 
-                                     GFP_ATOMIC | GFP_DMA);
-                if (ha->coal_stat)
-                    ha->coal_stat_phys = virt_to_bus(ha->coal_stat);
-#endif
-#endif
+
                 ha->scratch_busy = FALSE;
                 ha->req_first = NULL;
                 ha->tid_cnt = MAX_HDRIVES;
@@ -4583,7 +4271,7 @@
                     printk("GDT-ISA: Error during device scan\n");
                     --gdth_ctr_count;
                     --gdth_ctr_vcount;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+
 #ifdef INT_COAL
                     if (ha->coal_stat)
                         pci_free_consistent(ha->pdev, sizeof(gdth_coal_status) *
@@ -4596,17 +4284,7 @@
                     if (ha->pmsg)
                         pci_free_consistent(ha->pdev, sizeof(gdth_msg_str), 
                                             ha->pmsg, ha->msg_phys);
-#else
-#ifdef INT_COAL
-                    if (ha->coal_stat)
-                        scsi_init_free((void *)ha->coal_stat, 
-                                       sizeof(gdth_coal_status) * MAXOFFSETS);
-#endif
-                    if (ha->pscratch)
-                        scsi_init_free((void *)ha->pscratch, GDTH_SCRATCH);
-                    if (ha->pmsg)
-                        scsi_init_free((void *)ha->pmsg, sizeof(gdth_msg_str));
-#endif
+
                     free_irq(ha->irq,ha);
                     scsi_unregister(shp);
                     continue;
@@ -4615,14 +4293,13 @@
                     hdr_channel = ha->bus_cnt;
                 ha->virt_bus = hdr_channel;
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20) && \
     LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
                 shp->highmem_io  = 0;
 #endif
                 if (ha->cache_feat & ha->raw_feat & ha->screen_feat & GDT_64BIT) 
                     shp->max_cmd_len = 16;
-#endif
+
                 shp->max_id      = ha->tid_cnt;
                 shp->max_lun     = MAXLUN;
                 shp->max_channel = virt_ctr ? 0 : ha->bus_cnt;
@@ -4640,7 +4317,7 @@
                     }
                 }  
 
-                GDTH_INIT_LOCK_HA(ha);
+                spin_lock_init(&ha->smp_lock);
                 gdth_enable_int(hanum);
 #endif /* !__ia64__ */
             }
@@ -4686,7 +4363,7 @@
 
                 ha->pccb = CMDDATA(shp);
                 ha->ccb_phys = 0L; 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+
                 ha->pdev = NULL;
                 ha->pscratch = pci_alloc_consistent(ha->pdev, GDTH_SCRATCH, 
                                                     &scratch_dma_handle);
@@ -4703,22 +4380,6 @@
                 ha->ccb_phys = 
                     pci_map_single(ha->pdev,ha->pccb,
                                    sizeof(gdth_cmd_str),PCI_DMA_BIDIRECTIONAL);
-#else
-                ha->pscratch = scsi_init_malloc(GDTH_SCRATCH, GFP_ATOMIC | GFP_DMA);
-                if (ha->pscratch)
-                    ha->scratch_phys = virt_to_bus(ha->pscratch);
-                ha->pmsg = scsi_init_malloc(sizeof(gdth_msg_str), GFP_ATOMIC | GFP_DMA);
-                if (ha->pmsg)
-                    ha->msg_phys = virt_to_bus(ha->pmsg);
-#ifdef INT_COAL
-                ha->coal_stat = 
-                    scsi_init_malloc(sizeof(gdth_coal_status) * MAXOFFSETS, 
-                                     GFP_ATOMIC | GFP_DMA);
-                if (ha->coal_stat)
-                    ha->coal_stat_phys = virt_to_bus(ha->coal_stat);
-#endif
-                ha->ccb_phys = virt_to_bus(ha->pccb);
-#endif
                 ha->scratch_busy = FALSE;
                 ha->req_first = NULL;
                 ha->tid_cnt = MAX_HDRIVES;
@@ -4733,7 +4394,6 @@
                     printk("GDT-EISA: Error during device scan\n");
                     --gdth_ctr_count;
                     --gdth_ctr_vcount;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
 #ifdef INT_COAL
                     if (ha->coal_stat)
                         pci_free_consistent(ha->pdev, sizeof(gdth_coal_status) *
@@ -4749,17 +4409,6 @@
                     if (ha->ccb_phys)
                         pci_unmap_single(ha->pdev,ha->ccb_phys,
                                         sizeof(gdth_cmd_str),PCI_DMA_BIDIRECTIONAL);
-#else
-#ifdef INT_COAL
-                    if (ha->coal_stat)
-                        scsi_init_free((void *)ha->coal_stat, 
-                                       sizeof(gdth_coal_status) * MAXOFFSETS);
-#endif
-                    if (ha->pscratch)
-                        scsi_init_free((void *)ha->pscratch, GDTH_SCRATCH);
-                    if (ha->pmsg)
-                        scsi_init_free((void *)ha->pmsg, sizeof(gdth_msg_str));
-#endif
                     free_irq(ha->irq,ha);
                     scsi_unregister(shp);
                     continue;
@@ -4768,14 +4417,13 @@
                     hdr_channel = ha->bus_cnt;
                 ha->virt_bus = hdr_channel;
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20) && \
     LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
                 shp->highmem_io  = 0;
 #endif
                 if (ha->cache_feat & ha->raw_feat & ha->screen_feat & GDT_64BIT) 
                     shp->max_cmd_len = 16;
-#endif
+
                 shp->max_id      = ha->tid_cnt;
                 shp->max_lun     = MAXLUN;
                 shp->max_channel = virt_ctr ? 0 : ha->bus_cnt;
@@ -4793,7 +4441,7 @@
                     }
                 }  
 
-                GDTH_INIT_LOCK_HA(ha);
+                spin_lock_init(&ha->smp_lock);
                 gdth_enable_int(hanum);
             }
         }
@@ -4841,7 +4489,7 @@
 
         ha->pccb = CMDDATA(shp);
         ha->ccb_phys = 0L;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+
         ha->pscratch = pci_alloc_consistent(ha->pdev, GDTH_SCRATCH, 
                                             &scratch_dma_handle);
         ha->scratch_phys = scratch_dma_handle;
@@ -4854,21 +4502,6 @@
                                  MAXOFFSETS, &scratch_dma_handle);
         ha->coal_stat_phys = scratch_dma_handle;
 #endif
-#else
-        ha->pscratch = scsi_init_malloc(GDTH_SCRATCH, GFP_ATOMIC | GFP_DMA);
-        if (ha->pscratch)
-            ha->scratch_phys = virt_to_bus(ha->pscratch);
-        ha->pmsg = scsi_init_malloc(sizeof(gdth_msg_str), GFP_ATOMIC | GFP_DMA);
-        if (ha->pmsg)
-            ha->msg_phys = virt_to_bus(ha->pmsg);
-#ifdef INT_COAL
-        ha->coal_stat = 
-            scsi_init_malloc(sizeof(gdth_coal_status) * MAXOFFSETS, 
-                             GFP_ATOMIC | GFP_DMA);
-        if (ha->coal_stat)
-            ha->coal_stat_phys = virt_to_bus(ha->coal_stat);
-#endif
-#endif
         ha->scratch_busy = FALSE;
         ha->req_first = NULL;
         ha->tid_cnt = pcistr[ctr].device_id >= 0x200 ? MAXID : MAX_HDRIVES;
@@ -4887,7 +4520,7 @@
                 hdr_channel = ha->bus_cnt;
             ha->virt_bus = hdr_channel;
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
             scsi_set_device(shp, &pcistr[ctr].pdev->dev);
 #else
@@ -4909,14 +4542,12 @@
                     err = TRUE;
                 }
             }
-#endif
         }
 
         if (err) {
             printk("GDT-PCI %d: Error during device scan\n", hanum);
             --gdth_ctr_count;
             --gdth_ctr_vcount;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
 #ifdef INT_COAL
             if (ha->coal_stat)
                 pci_free_consistent(ha->pdev, sizeof(gdth_coal_status) *
@@ -4929,17 +4560,6 @@
             if (ha->pmsg)
                 pci_free_consistent(ha->pdev, sizeof(gdth_msg_str), 
                                     ha->pmsg, ha->msg_phys);
-#else
-#ifdef INT_COAL
-            if (ha->coal_stat)
-                scsi_init_free((void *)ha->coal_stat, 
-                               sizeof(gdth_coal_status) * MAXOFFSETS);
-#endif
-            if (ha->pscratch)
-                scsi_init_free((void *)ha->pscratch, GDTH_SCRATCH);
-            if (ha->pmsg)
-                scsi_init_free((void *)ha->pmsg, sizeof(gdth_msg_str));
-#endif
             free_irq(ha->irq,ha);
             scsi_unregister(shp);
             continue;
@@ -4962,8 +4582,7 @@
             }
         }  
 
-
-        GDTH_INIT_LOCK_HA(ha);
+        spin_lock_init(&ha->smp_lock);
         gdth_enable_int(hanum);
     }
     
@@ -4994,12 +4613,10 @@
     if (NUMDATA(shp)->busnum == 0) {
         hanum = NUMDATA(shp)->hanum;
         ha    = HADATA(gdth_ctr_tab[hanum]);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
         if (ha->sdev) {
             scsi_free_host_dev(ha->sdev);
             ha->sdev = NULL;
         }
-#endif
         gdth_flush(hanum);
 
         if (shp->irq) {
@@ -5010,7 +4627,6 @@
             free_dma(shp->dma_channel);
         }
 #endif
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
 #ifdef INT_COAL
         if (ha->coal_stat)
             pci_free_consistent(ha->pdev, sizeof(gdth_coal_status) *
@@ -5025,17 +4641,6 @@
         if (ha->ccb_phys)
             pci_unmap_single(ha->pdev,ha->ccb_phys,
                              sizeof(gdth_cmd_str),PCI_DMA_BIDIRECTIONAL);
-#else
-#ifdef INT_COAL
-        if (ha->coal_stat)
-            scsi_init_free((void *)ha->coal_stat, 
-                           sizeof(gdth_coal_status) * MAXOFFSETS);
-#endif
-        if (ha->pscratch)
-            scsi_init_free((void *)ha->pscratch, GDTH_SCRATCH);
-        if (ha->pmsg)
-            scsi_init_free((void *)ha->pmsg, sizeof(gdth_msg_str));
-#endif
         gdth_ctr_released++;
         TRACE2(("gdth_release(): HA %d of %d\n", 
                 gdth_ctr_released, gdth_ctr_count));
@@ -5098,21 +4703,6 @@
     return ((const char *)ha->binfo.type_string);
 }
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
-/* old error handling */
-int gdth_abort(Scsi_Cmnd *scp)
-{
-    TRACE2(("gdth_abort() reason %d\n",scp->abort_reason));
-    return SCSI_ABORT_SNOOZE;
-}
-
-int gdth_reset(Scsi_Cmnd *scp, unsigned int reset_flags)
-{
-    TRACE2(("gdth_reset()\n"));
-    return SCSI_RESET_PUNT;
-}
-#endif
-
 /* new error handling */
 int gdth_eh_abort(Scsi_Cmnd *scp)
 {
@@ -5135,33 +4725,25 @@
     unchar b;
 
     TRACE2(("gdth_eh_bus_reset()\n"));
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+
     hanum = NUMDATA(scp->device->host)->hanum;
     b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel;
-#else
-    hanum = NUMDATA(scp->host)->hanum;
-    b = virt_ctr ? NUMDATA(scp->host)->busnum : scp->channel;
-#endif
     ha    = HADATA(gdth_ctr_tab[hanum]);
 
     /* clear command tab */
-    GDTH_LOCK_HA(ha, flags);
+    spin_lock_irqsave(&ha->smp_lock, flags);
     for (i = 0; i < GDTH_MAXCMDS; ++i) {
         cmnd = ha->cmd_tab[i].cmnd;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
         if (!SPECIAL_SCP(cmnd) && cmnd->device->channel == b)
-#else
-        if (!SPECIAL_SCP(cmnd) && cmnd->channel == b)
-#endif
             ha->cmd_tab[i].cmnd = UNUSED_CMND;
     }
-    GDTH_UNLOCK_HA(ha, flags);
+    spin_unlock_irqrestore(&ha->smp_lock, flags);
 
     if (b == ha->virt_bus) {
         /* host drives */
         for (i = 0; i < MAX_HDRIVES; ++i) {
             if (ha->hdr[i].present) {
-                GDTH_LOCK_HA(ha, flags);
+                spin_lock_irqsave(&ha->smp_lock, flags);
                 gdth_polling = TRUE;
                 while (gdth_test_busy(hanum))
                     gdth_delay(0);
@@ -5169,12 +4751,12 @@
                                       GDT_CLUST_RESET, i, 0, 0))
                     ha->hdr[i].cluster_type &= ~CLUSTER_RESERVED;
                 gdth_polling = FALSE;
-                GDTH_UNLOCK_HA(ha, flags);
+                spin_unlock_irqrestore(&ha->smp_lock, flags);
             }
         }
     } else {
         /* raw devices */
-        GDTH_LOCK_HA(ha, flags);
+        spin_lock_irqsave(&ha->smp_lock, flags);
         for (i = 0; i < MAXID; ++i)
             ha->raw[BUS_L2P(ha,b)].io_cnt[i] = 0;
         gdth_polling = TRUE;
@@ -5183,7 +4765,7 @@
         gdth_internal_cmd(hanum, SCSIRAWSERVICE, GDT_RESET_BUS,
                           BUS_L2P(ha,b), 0, 0);
         gdth_polling = FALSE;
-        GDTH_UNLOCK_HA(ha, flags);
+	spin_unlock_irqrestore(&ha->smp_lock, flags);
     }
     return SUCCESS;
 }
@@ -5249,11 +4831,8 @@
     scp->SCp.sent_command = -1;
     scp->SCp.Status = GDTH_MAP_NONE;
     scp->SCp.buffer = (struct scatterlist *)NULL;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+
     hanum = NUMDATA(scp->device->host)->hanum;
-#else
-    hanum = NUMDATA(scp->host)->hanum;
-#endif
 #ifdef GDTH_STATISTICS
     ++act_ios;
 #endif
@@ -5270,7 +4849,6 @@
 
 static int gdth_open(struct inode *inode, struct file *filep)
 {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
     gdth_ha_str *ha;
     int i;
 
@@ -5279,7 +4857,6 @@
         if (!ha->sdev)
             ha->sdev = scsi_get_host_dev(gdth_ctr_tab[i]);
     }
-#endif
 
     TRACE(("gdth_open()\n"));
     return 0;
@@ -5311,10 +4888,10 @@
             evt.event.event_data.size=sizeof(evt.event.event_data.eu.sync); 
         else
             evt.event.event_data.size=sizeof(evt.event.event_data.eu.async);
-        GDTH_LOCK_HA(ha, flags);
+        spin_lock_irqsave(&ha->smp_lock, flags);
         gdth_store_event(ha, evt.event.event_source, evt.event.event_idx,
                          &evt.event.event_data);
-        GDTH_UNLOCK_HA(ha, flags);
+        spin_unlock_irqrestore(&ha->smp_lock, flags);
     } else if (evt.erase == 0xfe) {
         gdth_clear_events();
     } else if (evt.erase == 0) {
@@ -5344,15 +4921,15 @@
         if (j >= MAX_HDRIVES || !ha->hdr[j].present)
             continue;
         if (ldrv.lock) {
-            GDTH_LOCK_HA(ha, flags);
+            spin_lock_irqsave(&ha->smp_lock, flags);
             ha->hdr[j].lock = 1;
-            GDTH_UNLOCK_HA(ha, flags);
+            spin_unlock_irqrestore(&ha->smp_lock, flags);
             gdth_wait_completion(ldrv.ionode, ha->bus_cnt, j); 
             gdth_stop_timeout(ldrv.ionode, ha->bus_cnt, j); 
         } else {
-            GDTH_LOCK_HA(ha, flags);
+            spin_lock_irqsave(&ha->smp_lock, flags);
             ha->hdr[j].lock = 0;
-            GDTH_UNLOCK_HA(ha, flags);
+            spin_unlock_irqrestore(&ha->smp_lock, flags);
             gdth_start_timeout(ldrv.ionode, ha->bus_cnt, j); 
             gdth_next(ldrv.ionode); 
         }
@@ -5367,11 +4944,9 @@
     int hanum;
     gdth_ha_str *ha;
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-        Scsi_Request *srp;
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-        Scsi_Cmnd *scp;
+    Scsi_Request *srp;
 #else
-        Scsi_Cmnd scp;
+    Scsi_Cmnd *scp;
 #endif
 
     if (copy_from_user(&res, arg, sizeof(gdth_ioctl_reset)) ||
@@ -5398,7 +4973,7 @@
     gdth_do_req(srp, &cmd, cmnd, 30);
     res.status = (ushort)srp->sr_command->SCp.Status;
     scsi_release_request(srp);
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+#else
     scp  = scsi_allocate_device(ha->sdev, 1, FALSE);
     if (!scp)
         return -ENOMEM;
@@ -5407,15 +4982,8 @@
     gdth_do_cmd(scp, &cmd, cmnd, 30);
     res.status = (ushort)scp->SCp.Status;
     scsi_release_command(scp);
-#else
-    memset(&ha->sdev,0,sizeof(Scsi_Device));
-    memset(&scp, 0,sizeof(Scsi_Cmnd));
-    ha->sdev.host = scp.host = gdth_ctr_tab[hanum];
-    ha->sdev.id = scp.target = ha->sdev.host->this_id;
-    scp.device = &ha->sdev;
-    gdth_do_cmd(&scp, &cmd, cmnd, 30);
-    res.status = (ushort)scp.SCp.Status;
 #endif
+
     if (copy_to_user(arg, &res, sizeof(gdth_ioctl_reset)))
         return -EFAULT;
     return 0;
@@ -5430,10 +4998,8 @@
         gdth_ha_str *ha; 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
         Scsi_Request *srp;
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-        Scsi_Cmnd *scp;
 #else
-        Scsi_Cmnd scp;
+        Scsi_Cmnd *scp;
 #endif
         
     if (copy_from_user(&gen, arg, sizeof(gdth_ioctl_general)) ||
@@ -5536,7 +5102,7 @@
     gen.status = srp->sr_command->SCp.Status;
     gen.info = srp->sr_command->SCp.Message;
     scsi_release_request(srp);
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+#else
     scp  = scsi_allocate_device(ha->sdev, 1, FALSE);
     if (!scp)
         return -ENOMEM;
@@ -5546,15 +5112,6 @@
     gen.status = scp->SCp.Status;
     gen.info = scp->SCp.Message;
     scsi_release_command(scp);
-#else
-    memset(&ha->sdev,0,sizeof(Scsi_Device));
-    memset(&scp, 0,sizeof(Scsi_Cmnd));
-    ha->sdev.host = scp.host = gdth_ctr_tab[hanum];
-    ha->sdev.id = scp.target = ha->sdev.host->this_id;
-    scp.device = &ha->sdev;
-    gdth_do_cmd(&scp, &gen.command, cmnd, gen.timeout);
-    gen.status = scp.SCp.Status;
-    gen.info = scp.SCp.Message;
 #endif
 
     if (copy_to_user(arg + sizeof(gdth_ioctl_general), buf, 
@@ -5573,185 +5130,183 @@
  
 static int ioc_hdrlist(void __user *arg, char *cmnd)
 {
-    gdth_ioctl_rescan rsc;
-    gdth_cmd_str cmd;
+    gdth_ioctl_rescan *rsc;
+    gdth_cmd_str *cmd;
     gdth_ha_str *ha;
     unchar i;
-    int hanum;
+    int hanum, rc = -ENOMEM;
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
     Scsi_Request *srp;
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-    Scsi_Cmnd *scp;
 #else
-    Scsi_Cmnd scp;
+    Scsi_Cmnd *scp;
 #endif
         
-    if (copy_from_user(&rsc, arg, sizeof(gdth_ioctl_rescan)) ||
-        rsc.ionode >= gdth_ctr_count)
-        return -EFAULT;
-    hanum = rsc.ionode;
+    rsc = kmalloc(sizeof(*rsc), GFP_KERNEL);
+    cmd = kmalloc(sizeof(*cmd), GFP_KERNEL);
+    if (!rsc || !cmd)
+	goto free_fail;
+
+    if (copy_from_user(rsc, arg, sizeof(gdth_ioctl_rescan)) ||
+        rsc->ionode >= gdth_ctr_count) {
+        rc = -EFAULT;
+	goto free_fail;
+    }
+    hanum = rsc->ionode;
     ha = HADATA(gdth_ctr_tab[hanum]);
-    memset(&cmd, 0, sizeof(gdth_cmd_str));
+    memset(cmd, 0, sizeof(gdth_cmd_str));
    
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
     srp  = scsi_allocate_request(ha->sdev, GFP_KERNEL);
     if (!srp)
-        return -ENOMEM;
+        goto free_fail;
     srp->sr_cmd_len = 12;
     srp->sr_use_sg = 0;
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+#else
     scp  = scsi_allocate_device(ha->sdev, 1, FALSE);
     if (!scp)
-        return -ENOMEM;
+        goto free_fail;
     scp->cmd_len = 12;
     scp->use_sg = 0;
-#else
-    memset(&ha->sdev,0,sizeof(Scsi_Device));
-    memset(&scp, 0,sizeof(Scsi_Cmnd));
-    ha->sdev.host = scp.host = gdth_ctr_tab[hanum];
-    ha->sdev.id = scp.target = ha->sdev.host->this_id;
-    scp.device = &ha->sdev;
 #endif
 
     for (i = 0; i < MAX_HDRIVES; ++i) { 
         if (!ha->hdr[i].present) {
-            rsc.hdr_list[i].bus = 0xff; 
+            rsc->hdr_list[i].bus = 0xff; 
             continue;
         } 
-        rsc.hdr_list[i].bus = ha->virt_bus;
-        rsc.hdr_list[i].target = i;
-        rsc.hdr_list[i].lun = 0;
-        rsc.hdr_list[i].cluster_type = ha->hdr[i].cluster_type;
+        rsc->hdr_list[i].bus = ha->virt_bus;
+        rsc->hdr_list[i].target = i;
+        rsc->hdr_list[i].lun = 0;
+        rsc->hdr_list[i].cluster_type = ha->hdr[i].cluster_type;
         if (ha->hdr[i].cluster_type & CLUSTER_DRIVE) { 
-            cmd.Service = CACHESERVICE;
-            cmd.OpCode = GDT_CLUST_INFO;
+            cmd->Service = CACHESERVICE;
+            cmd->OpCode = GDT_CLUST_INFO;
             if (ha->cache_feat & GDT_64BIT)
-                cmd.u.cache64.DeviceNo = i;
+                cmd->u.cache64.DeviceNo = i;
             else
-                cmd.u.cache.DeviceNo = i;
+                cmd->u.cache.DeviceNo = i;
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-            gdth_do_req(srp, &cmd, cmnd, 30);
+            gdth_do_req(srp, cmd, cmnd, 30);
             if (srp->sr_command->SCp.Status == S_OK)
-                rsc.hdr_list[i].cluster_type = srp->sr_command->SCp.Message;
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-            gdth_do_cmd(scp, &cmd, cmnd, 30);
-            if (scp->SCp.Status == S_OK)
-                rsc.hdr_list[i].cluster_type = scp->SCp.Message;
+                rsc->hdr_list[i].cluster_type = srp->sr_command->SCp.Message;
 #else
-            gdth_do_cmd(&scp, &cmd, cmnd, 30);
-            if (scp.SCp.Status == S_OK)
-                rsc.hdr_list[i].cluster_type = scp.SCp.Message;
+            gdth_do_cmd(scp, cmd, cmnd, 30);
+            if (scp->SCp.Status == S_OK)
+                rsc->hdr_list[i].cluster_type = scp->SCp.Message;
 #endif
         }
     } 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
     scsi_release_request(srp);
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+#else
     scsi_release_command(scp);
 #endif       
  
-    if (copy_to_user(arg, &rsc, sizeof(gdth_ioctl_rescan)))
-        return -EFAULT;
-    return 0;
+    if (copy_to_user(arg, rsc, sizeof(gdth_ioctl_rescan)))
+        rc = -EFAULT;
+    else
+	rc = 0;
+
+free_fail:
+    kfree(rsc);
+    kfree(cmd);
+    return rc;
 }
 
 static int ioc_rescan(void __user *arg, char *cmnd)
 {
-    gdth_ioctl_rescan rsc;
-    gdth_cmd_str cmd;
+    gdth_ioctl_rescan *rsc;
+    gdth_cmd_str *cmd;
     ushort i, status, hdr_cnt;
     ulong32 info;
     int hanum, cyls, hds, secs;
+    int rc = -ENOMEM;
     ulong flags;
     gdth_ha_str *ha; 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
     Scsi_Request *srp;
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-    Scsi_Cmnd *scp;
 #else
-    Scsi_Cmnd scp;
+    Scsi_Cmnd *scp;
 #endif
-        
-    if (copy_from_user(&rsc, arg, sizeof(gdth_ioctl_rescan)) ||
-        rsc.ionode >= gdth_ctr_count)
-        return -EFAULT;
-    hanum = rsc.ionode;
+
+    rsc = kmalloc(sizeof(*rsc), GFP_KERNEL);
+    cmd = kmalloc(sizeof(*cmd), GFP_KERNEL);
+    if (!cmd || !rsc)
+	goto free_fail;
+
+    if (copy_from_user(rsc, arg, sizeof(gdth_ioctl_rescan)) ||
+        rsc->ionode >= gdth_ctr_count) {
+	rc = -EFAULT;
+	goto free_fail;
+    }
+    hanum = rsc->ionode;
     ha = HADATA(gdth_ctr_tab[hanum]);
-    memset(&cmd, 0, sizeof(gdth_cmd_str));
+    memset(cmd, 0, sizeof(gdth_cmd_str));
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
     srp  = scsi_allocate_request(ha->sdev, GFP_KERNEL);
     if (!srp)
-        return -ENOMEM;
+        goto free_fail;
     srp->sr_cmd_len = 12;
     srp->sr_use_sg = 0;
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+#else
     scp  = scsi_allocate_device(ha->sdev, 1, FALSE);
     if (!scp)
-        return -ENOMEM;
+        goto free_fail;
     scp->cmd_len = 12;
     scp->use_sg = 0;
-#else
-    memset(&ha->sdev,0,sizeof(Scsi_Device));
-    memset(&scp, 0,sizeof(Scsi_Cmnd));
-    ha->sdev.host = scp.host = gdth_ctr_tab[hanum];
-    ha->sdev.id = scp.target = ha->sdev.host->this_id;
-    scp.device = &ha->sdev;
 #endif
      
-    if (rsc.flag == 0) {
+    if (rsc->flag == 0) {
         /* old method: re-init. cache service */
-        cmd.Service = CACHESERVICE;
+        cmd->Service = CACHESERVICE;
         if (ha->cache_feat & GDT_64BIT) {
-            cmd.OpCode = GDT_X_INIT_HOST;
-            cmd.u.cache64.DeviceNo = LINUX_OS;
+            cmd->OpCode = GDT_X_INIT_HOST;
+            cmd->u.cache64.DeviceNo = LINUX_OS;
         } else {
-            cmd.OpCode = GDT_INIT;
-            cmd.u.cache.DeviceNo = LINUX_OS;
+            cmd->OpCode = GDT_INIT;
+            cmd->u.cache.DeviceNo = LINUX_OS;
         }
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-        gdth_do_req(srp, &cmd, cmnd, 30);
+        gdth_do_req(srp, cmd, cmnd, 30);
         status = (ushort)srp->sr_command->SCp.Status;
         info = (ulong32)srp->sr_command->SCp.Message;
 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-        gdth_do_cmd(scp, &cmd, cmnd, 30);
+        gdth_do_cmd(scp, cmd, cmnd, 30);
         status = (ushort)scp->SCp.Status;
         info = (ulong32)scp->SCp.Message;
 #else
-        gdth_do_cmd(&scp, &cmd, cmnd, 30);
+        gdth_do_cmd(&scp, cmd, cmnd, 30);
         status = (ushort)scp.SCp.Status;
         info = (ulong32)scp.SCp.Message;
 #endif
         i = 0;
         hdr_cnt = (status == S_OK ? (ushort)info : 0);
     } else {
-        i = rsc.hdr_no;
+        i = rsc->hdr_no;
         hdr_cnt = i + 1;
     }
+
     for (; i < hdr_cnt && i < MAX_HDRIVES; ++i) {
-        cmd.Service = CACHESERVICE;
-        cmd.OpCode = GDT_INFO;
+        cmd->Service = CACHESERVICE;
+        cmd->OpCode = GDT_INFO;
         if (ha->cache_feat & GDT_64BIT) 
-            cmd.u.cache64.DeviceNo = i;
+            cmd->u.cache64.DeviceNo = i;
         else 
-            cmd.u.cache.DeviceNo = i;
+            cmd->u.cache.DeviceNo = i;
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-        gdth_do_req(srp, &cmd, cmnd, 30);
+        gdth_do_req(srp, cmd, cmnd, 30);
         status = (ushort)srp->sr_command->SCp.Status;
         info = (ulong32)srp->sr_command->SCp.Message;
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-        gdth_do_cmd(scp, &cmd, cmnd, 30);
+#else
+        gdth_do_cmd(scp, cmd, cmnd, 30);
         status = (ushort)scp->SCp.Status;
         info = (ulong32)scp->SCp.Message;
-#else
-        gdth_do_cmd(&scp, &cmd, cmnd, 30);
-        status = (ushort)scp.SCp.Status;
-        info = (ulong32)scp.SCp.Message;
 #endif
-        GDTH_LOCK_HA(ha, flags);
-        rsc.hdr_list[i].bus = ha->virt_bus;
-        rsc.hdr_list[i].target = i;
-        rsc.hdr_list[i].lun = 0;
+        spin_lock_irqsave(&ha->smp_lock, flags);
+        rsc->hdr_list[i].bus = ha->virt_bus;
+        rsc->hdr_list[i].target = i;
+        rsc->hdr_list[i].lun = 0;
         if (status != S_OK) {
             ha->hdr[i].present = FALSE;
         } else {
@@ -5765,7 +5320,7 @@
             /* round size */
             ha->hdr[i].size = cyls * hds * secs;
         }
-        GDTH_UNLOCK_HA(ha, flags);
+        spin_unlock_irqrestore(&ha->smp_lock, flags);
         if (status != S_OK)
             continue; 
         
@@ -5773,99 +5328,87 @@
         /* but we need ha->info2, not yet stored in scp->SCp */
 
         /* devtype, cluster info, R/W attribs */
-        cmd.Service = CACHESERVICE;
-        cmd.OpCode = GDT_DEVTYPE;
+        cmd->Service = CACHESERVICE;
+        cmd->OpCode = GDT_DEVTYPE;
         if (ha->cache_feat & GDT_64BIT) 
-            cmd.u.cache64.DeviceNo = i;
+            cmd->u.cache64.DeviceNo = i;
         else
-            cmd.u.cache.DeviceNo = i;
+            cmd->u.cache.DeviceNo = i;
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-        gdth_do_req(srp, &cmd, cmnd, 30);
+        gdth_do_req(srp, cmd, cmnd, 30);
         status = (ushort)srp->sr_command->SCp.Status;
         info = (ulong32)srp->sr_command->SCp.Message;
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-        gdth_do_cmd(scp, &cmd, cmnd, 30);
+#else
+        gdth_do_cmd(scp, cmd, cmnd, 30);
         status = (ushort)scp->SCp.Status;
         info = (ulong32)scp->SCp.Message;
-#else
-        gdth_do_cmd(&scp, &cmd, cmnd, 30);
-        status = (ushort)scp.SCp.Status;
-        info = (ulong32)scp.SCp.Message;
 #endif
-        GDTH_LOCK_HA(ha, flags);
+        spin_lock_irqsave(&ha->smp_lock, flags);
         ha->hdr[i].devtype = (status == S_OK ? (ushort)info : 0);
-        GDTH_UNLOCK_HA(ha, flags);
+        spin_unlock_irqrestore(&ha->smp_lock, flags);
 
-        cmd.Service = CACHESERVICE;
-        cmd.OpCode = GDT_CLUST_INFO;
+        cmd->Service = CACHESERVICE;
+        cmd->OpCode = GDT_CLUST_INFO;
         if (ha->cache_feat & GDT_64BIT) 
-            cmd.u.cache64.DeviceNo = i;
+            cmd->u.cache64.DeviceNo = i;
         else
-            cmd.u.cache.DeviceNo = i;
+            cmd->u.cache.DeviceNo = i;
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-        gdth_do_req(srp, &cmd, cmnd, 30);
+        gdth_do_req(srp, cmd, cmnd, 30);
         status = (ushort)srp->sr_command->SCp.Status;
         info = (ulong32)srp->sr_command->SCp.Message;
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-        gdth_do_cmd(scp, &cmd, cmnd, 30);
+#else
+        gdth_do_cmd(scp, cmd, cmnd, 30);
         status = (ushort)scp->SCp.Status;
         info = (ulong32)scp->SCp.Message;
-#else
-        gdth_do_cmd(&scp, &cmd, cmnd, 30);
-        status = (ushort)scp.SCp.Status;
-        info = (ulong32)scp.SCp.Message;
 #endif
-        GDTH_LOCK_HA(ha, flags);
+        spin_lock_irqsave(&ha->smp_lock, flags);
         ha->hdr[i].cluster_type = 
             ((status == S_OK && !shared_access) ? (ushort)info : 0);
-        GDTH_UNLOCK_HA(ha, flags);
-        rsc.hdr_list[i].cluster_type = ha->hdr[i].cluster_type;
+        spin_unlock_irqrestore(&ha->smp_lock, flags);
+        rsc->hdr_list[i].cluster_type = ha->hdr[i].cluster_type;
 
-        cmd.Service = CACHESERVICE;
-        cmd.OpCode = GDT_RW_ATTRIBS;
+        cmd->Service = CACHESERVICE;
+        cmd->OpCode = GDT_RW_ATTRIBS;
         if (ha->cache_feat & GDT_64BIT) 
-            cmd.u.cache64.DeviceNo = i;
+            cmd->u.cache64.DeviceNo = i;
         else
-            cmd.u.cache.DeviceNo = i;
+            cmd->u.cache.DeviceNo = i;
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-        gdth_do_req(srp, &cmd, cmnd, 30);
+        gdth_do_req(srp, cmd, cmnd, 30);
         status = (ushort)srp->sr_command->SCp.Status;
         info = (ulong32)srp->sr_command->SCp.Message;
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-        gdth_do_cmd(scp, &cmd, cmnd, 30);
+#else
+        gdth_do_cmd(scp, cmd, cmnd, 30);
         status = (ushort)scp->SCp.Status;
         info = (ulong32)scp->SCp.Message;
-#else
-        gdth_do_cmd(&scp, &cmd, cmnd, 30);
-        status = (ushort)scp.SCp.Status;
-        info = (ulong32)scp.SCp.Message;
 #endif
-        GDTH_LOCK_HA(ha, flags);
+        spin_lock_irqsave(&ha->smp_lock, flags);
         ha->hdr[i].rw_attribs = (status == S_OK ? (ushort)info : 0);
-        GDTH_UNLOCK_HA(ha, flags);
+        spin_unlock_irqrestore(&ha->smp_lock, flags);
     }
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
     scsi_release_request(srp);
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+#else
     scsi_release_command(scp);
 #endif       
  
-    if (copy_to_user(arg, &rsc, sizeof(gdth_ioctl_rescan)))
-        return -EFAULT;
-    return 0;
+    if (copy_to_user(arg, rsc, sizeof(gdth_ioctl_rescan)))
+        rc = -EFAULT;
+    else
+	rc = 0;
+
+free_fail:
+    kfree(rsc);
+    kfree(cmd);
+    return rc;
 }
   
 static int gdth_ioctl(struct inode *inode, struct file *filep,
                       unsigned int cmd, unsigned long arg)
 {
     gdth_ha_str *ha; 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-    Scsi_Cmnd *scp;
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
     Scsi_Cmnd *scp;
-#else
-    Scsi_Cmnd scp;
-#endif
     ulong flags;
     char cmnd[MAX_COMMAND_SIZE];   
     void __user *argp = (void __user *)arg;
@@ -5956,17 +5499,17 @@
         i = lchn.channel;
         if (i < ha->bus_cnt) {
             if (lchn.lock) {
-                GDTH_LOCK_HA(ha, flags);
+                spin_lock_irqsave(&ha->smp_lock, flags);
                 ha->raw[i].lock = 1;
-                GDTH_UNLOCK_HA(ha, flags);
+                spin_unlock_irqrestore(&ha->smp_lock, flags);
                 for (j = 0; j < ha->tid_cnt; ++j) {
                     gdth_wait_completion(lchn.ionode, i, j); 
                     gdth_stop_timeout(lchn.ionode, i, j); 
                 }
             } else {
-                GDTH_LOCK_HA(ha, flags);
+                spin_lock_irqsave(&ha->smp_lock, flags);
                 ha->raw[i].lock = 0;
-                GDTH_UNLOCK_HA(ha, flags);
+                spin_unlock_irqrestore(&ha->smp_lock, flags);
                 for (j = 0; j < ha->tid_cnt; ++j) {
                     gdth_start_timeout(lchn.ionode, i, j); 
                     gdth_next(lchn.ionode); 
@@ -6004,7 +5547,7 @@
         rval = gdth_eh_bus_reset(scp);
         res.status = (rval == SUCCESS ? S_OK : S_GENERR);
         scsi_put_command(scp);
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+#else
         scp  = scsi_allocate_device(ha->sdev, 1, FALSE);
         if (!scp)
             return -ENOMEM;
@@ -6014,15 +5557,6 @@
         rval = gdth_eh_bus_reset(scp);
         res.status = (rval == SUCCESS ? S_OK : S_GENERR);
         scsi_release_command(scp);
-#else 
-        memset(&ha->sdev,0,sizeof(Scsi_Device));
-        memset(&scp, 0,sizeof(Scsi_Cmnd));
-        ha->sdev.host = scp.host = gdth_ctr_tab[hanum];
-        ha->sdev.id = scp.target = ha->sdev.host->this_id;
-        scp.device = &ha->sdev;
-        scp.channel = virt_ctr ? 0 : res.number;
-        rval = gdth_eh_bus_reset(&scp);
-        res.status = (rval == SUCCESS ? S_OK : S_GENERR);
 #endif
         if (copy_to_user(argp, &res, sizeof(gdth_ioctl_reset)))
             return -EFAULT;
@@ -6047,14 +5581,10 @@
     gdth_cmd_str    gdtcmd;
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
     Scsi_Request    *srp;
-    Scsi_Device     *sdev;
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-    Scsi_Cmnd       *scp;
-    Scsi_Device     *sdev;
 #else
-    Scsi_Cmnd       scp;
-    Scsi_Device     sdev;
+    Scsi_Cmnd       *scp;
 #endif
+    Scsi_Device     *sdev;
     char            cmnd[MAX_COMMAND_SIZE];   
     memset(cmnd, 0xff, MAX_COMMAND_SIZE);
 
@@ -6068,19 +5598,13 @@
         return;
     srp->sr_cmd_len = 12;
     srp->sr_use_sg = 0;
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+#else
     sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
     scp  = scsi_allocate_device(sdev, 1, FALSE);
     if (!scp)
         return;
     scp->cmd_len = 12;
     scp->use_sg = 0;
-#else
-    memset(&sdev,0,sizeof(Scsi_Device));
-    memset(&scp, 0,sizeof(Scsi_Cmnd));
-    sdev.host = scp.host = gdth_ctr_tab[hanum];
-    sdev.id = scp.target = sdev.host->this_id;
-    scp.device = &sdev;
 #endif
 
     for (i = 0; i < MAX_HDRIVES; ++i) {
@@ -6100,17 +5624,15 @@
             TRACE2(("gdth_flush(): flush ha %d drive %d\n", hanum, i));
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
             gdth_do_req(srp, &gdtcmd, cmnd, 30);
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-            gdth_do_cmd(scp, &gdtcmd, cmnd, 30);
 #else
-            gdth_do_cmd(&scp, &gdtcmd, cmnd, 30);
+            gdth_do_cmd(scp, &gdtcmd, cmnd, 30);
 #endif
         }
     }
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
     scsi_release_request(srp);
     scsi_free_host_dev(sdev);
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+#else
     scsi_release_command(scp);
     scsi_free_host_dev(sdev);
 #endif
@@ -6125,12 +5647,9 @@
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
     Scsi_Request    *srp;
     Scsi_Device     *sdev;
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+#else
     Scsi_Cmnd       *scp;
     Scsi_Device     *sdev;
-#else
-    Scsi_Cmnd       scp;
-    Scsi_Device     sdev;
 #endif
     char            cmnd[MAX_COMMAND_SIZE];   
 #endif
@@ -6162,7 +5681,7 @@
         gdth_do_req(srp, &gdtcmd, cmnd, 10);
         scsi_release_request(srp);
         scsi_free_host_dev(sdev);
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+#else
         sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
         scp  = scsi_allocate_device(sdev, 1, FALSE);
         if (!scp) {
@@ -6174,13 +5693,6 @@
         gdth_do_cmd(scp, &gdtcmd, cmnd, 10);
         scsi_release_command(scp);
         scsi_free_host_dev(sdev);
-#else
-        memset(&sdev,0,sizeof(Scsi_Device));
-        memset(&scp, 0,sizeof(Scsi_Cmnd));
-        sdev.host = scp.host = gdth_ctr_tab[hanum];
-        sdev.id = scp.target = sdev.host->this_id;
-        scp.device = &sdev;
-        gdth_do_cmd(&scp, &gdtcmd, cmnd, 10);
 #endif
 #endif
     }
@@ -6193,19 +5705,6 @@
     return NOTIFY_OK;
 }
 
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) && !defined(MODULE)
-
-GDTH_INITFUNC(void, gdth_setup(char *str,int *ints)) 
-{    
-    TRACE2(("gdth_setup() str %s ints[0] %d\n", 
-            str ? str:"NULL", ints ? ints[0]:0));
-    internal_setup(str, ints);
-}
-
-#else
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
 static Scsi_Host_Template driver_template = {
         .proc_name              = "gdth", 
         .proc_info              = gdth_proc_info,
@@ -6232,13 +5731,8 @@
 #endif
 #endif
 };
-#else
-static Scsi_Host_Template driver_template = GDTH;
-#endif
 
 #include "scsi_module.c"
 #ifndef MODULE
 __setup("gdth=", option_setup);
-#endif
-
 #endif
diff -Nru a/drivers/scsi/gdth_kcompat.h b/drivers/scsi/gdth_kcompat.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/scsi/gdth_kcompat.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,21 @@
+
+
+#ifndef IRQ_HANDLED
+typedef void irqreturn_t;
+#define IRQ_NONE
+#define IRQ_HANDLED
+#endif
+
+#ifndef MODULE_LICENSE
+#define MODULE_LICENSE(x)
+#endif
+
+#ifndef SERVICE_ACTION_IN
+#define SERVICE_ACTION_IN	0x9e
+#endif
+#ifndef READ_16
+#define READ_16			0x88
+#endif
+#ifndef WRITE_16
+#define WRITE_16		0x8a
+#endif
diff -Nru a/drivers/scsi/gdth_proc.c b/drivers/scsi/gdth_proc.c
--- a/drivers/scsi/gdth_proc.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/scsi/gdth_proc.c	2005-03-01 23:38:57 -08:00
@@ -2,9 +2,7 @@
  * $Id: gdth_proc.c,v 1.42 2004/03/05 15:50:20 achim Exp $
  */
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,7)
 #include <linux/completion.h>
-#endif
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
 int gdth_proc_info(struct Scsi_Host *host, char *buffer,char **start,off_t offset,int length,   
@@ -57,12 +55,9 @@
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
     Scsi_Request    *scp;
     Scsi_Device     *sdev;
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+#else
     Scsi_Cmnd       *scp;
     Scsi_Device     *sdev;
-#else
-    Scsi_Cmnd       scp;
-    Scsi_Device     sdev;
 #endif
     TRACE2(("gdth_set_info() ha %d bus %d\n",hanum,busnum));
 
@@ -73,19 +68,13 @@
         return -ENOMEM;
     scp->sr_cmd_len = 12;
     scp->sr_use_sg = 0;
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+#else
     sdev = scsi_get_host_dev(host);
     scp  = scsi_allocate_device(sdev, 1, FALSE);
     if (!scp)
         return -ENOMEM;
     scp->cmd_len = 12;
     scp->use_sg = 0;
-#else
-    memset(&sdev,0,sizeof(Scsi_Device));
-    memset(&scp, 0,sizeof(Scsi_Cmnd));
-    sdev.host = scp.host = host;
-    sdev.id = scp.target = sdev.host->this_id;
-    scp.device = &sdev;
 #endif
 
     if (length >= 4) {
@@ -98,7 +87,7 @@
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
     scsi_release_request(scp);
     scsi_free_host_dev(sdev);
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+#else
     scsi_release_command(scp);
     scsi_free_host_dev(sdev);
 #endif
@@ -107,10 +96,8 @@
          
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
 static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Request *scp)
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Cmnd *scp)
 #else
-static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
+static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Cmnd *scp)
 #endif
 {
     int             orig_length, drive, wb_mode;
@@ -161,10 +148,8 @@
                 }
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
                 gdth_do_req(scp, &gdtcmd, cmnd, 30);
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-                gdth_do_cmd(scp, &gdtcmd, cmnd, 30);
 #else
-                gdth_do_cmd(&scp, &gdtcmd, cmnd, 30);
+                gdth_do_cmd(scp, &gdtcmd, cmnd, 30);
 #endif
             }
         }
@@ -219,10 +204,8 @@
         pcpar->write_back = wb_mode==1 ? 0:1;
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
         gdth_do_req(scp, &gdtcmd, cmnd, 30);
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-        gdth_do_cmd(scp, &gdtcmd, cmnd, 30);
 #else
-        gdth_do_cmd(&scp, &gdtcmd, cmnd, 30);
+        gdth_do_cmd(scp, &gdtcmd, cmnd, 30);
 #endif
         gdth_ioctl_free(hanum, GDTH_SCRATCH, ha->pscratch, paddr);
         printk("Done.\n");
@@ -243,18 +226,16 @@
     int no_mdrv = 0, drv_no, is_mirr;
     ulong32 cnt;
     ulong64 paddr;
+    int rc = -ENOMEM;
 
-    gdth_cmd_str gdtcmd;
-    gdth_evt_str estr;
+    gdth_cmd_str *gdtcmd;
+    gdth_evt_str *estr;
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
     Scsi_Request *scp;
     Scsi_Device *sdev; 
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+#else
     Scsi_Cmnd *scp;
     Scsi_Device *sdev;
-#else
-    Scsi_Cmnd scp;
-    Scsi_Device sdev;
 #endif
     char hrec[161];
     struct timeval tv;
@@ -266,10 +247,15 @@
     gdth_defcnt_str *pdef;
     gdth_cdrinfo_str *pcdi;
     gdth_hget_str *phg;
-
     char cmnd[MAX_COMMAND_SIZE];
+
+    gdtcmd = kmalloc(sizeof(*gdtcmd), GFP_KERNEL);
+    estr = kmalloc(sizeof(*estr), GFP_KERNEL);
+    if (!gdtcmd || !estr)
+	goto free_fail;
+
     memset(cmnd, 0xff, 12);
-    memset(&gdtcmd, 0, sizeof(gdth_cmd_str));
+    memset(gdtcmd, 0, sizeof(gdth_cmd_str));
 
     TRACE2(("gdth_get_info() ha %d bus %d\n",hanum,busnum));
     ha = HADATA(gdth_ctr_tab[hanum]);
@@ -278,14 +264,14 @@
     sdev = scsi_get_host_dev(host);
     scp  = scsi_allocate_request(sdev, GFP_KERNEL);
     if (!scp)
-        return -ENOMEM;
+        goto free_fail;
     scp->sr_cmd_len = 12;
     scp->sr_use_sg = 0;
 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
     sdev = scsi_get_host_dev(host);
     scp  = scsi_allocate_device(sdev, 1, FALSE);
     if (!scp)
-        return -ENOMEM;
+        goto free_fail;
     scp->cmd_len = 12;
     scp->use_sg = 0;
 #else
@@ -387,12 +373,12 @@
             /* 2.a statistics (and retries/reassigns) */
             TRACE2(("pdr_statistics() chn %d\n",i));                
             pds = (gdth_dskstat_str *)(buf + GDTH_SCRATCH/4);
-            gdtcmd.Service = CACHESERVICE;
-            gdtcmd.OpCode = GDT_IOCTL;
-            gdtcmd.u.ioctl.p_param = paddr + GDTH_SCRATCH/4;
-            gdtcmd.u.ioctl.param_size = 3*GDTH_SCRATCH/4;
-            gdtcmd.u.ioctl.subfunc = DSK_STATISTICS | L_CTRL_PATTERN;
-            gdtcmd.u.ioctl.channel = ha->raw[i].address | INVALID_CHANNEL;
+            gdtcmd->Service = CACHESERVICE;
+            gdtcmd->OpCode = GDT_IOCTL;
+            gdtcmd->u.ioctl.p_param = paddr + GDTH_SCRATCH/4;
+            gdtcmd->u.ioctl.param_size = 3*GDTH_SCRATCH/4;
+            gdtcmd->u.ioctl.subfunc = DSK_STATISTICS | L_CTRL_PATTERN;
+            gdtcmd->u.ioctl.channel = ha->raw[i].address | INVALID_CHANNEL;
             pds->bid = ha->raw[i].local_no;
             pds->first = 0;
             pds->entries = ha->raw[i].pdev_cnt;
@@ -401,14 +387,11 @@
             if (pds->entries > cnt)
                 pds->entries = cnt;
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-            gdth_do_req(scp, &gdtcmd, cmnd, 30);
+            gdth_do_req(scp, gdtcmd, cmnd, 30);
             if (scp->sr_command->SCp.Status != S_OK) 
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-            gdth_do_cmd(scp, &gdtcmd, cmnd, 30);
-            if (scp->SCp.Status != S_OK) 
 #else
-            gdth_do_cmd(&scp, &gdtcmd, cmnd, 30);
-            if (scp.SCp.Status != S_OK) 
+            gdth_do_cmd(scp, gdtcmd, cmnd, 30);
+            if (scp->SCp.Status != S_OK) 
 #endif
             { 
                 pds->count = 0;
@@ -420,22 +403,19 @@
                 TRACE2(("scsi_drv_info() chn %d dev %d\n",
                     i, ha->raw[i].id_list[j]));             
                 pdi = (gdth_diskinfo_str *)buf;
-                gdtcmd.Service = CACHESERVICE;
-                gdtcmd.OpCode = GDT_IOCTL;
-                gdtcmd.u.ioctl.p_param = paddr;
-                gdtcmd.u.ioctl.param_size = sizeof(gdth_diskinfo_str);
-                gdtcmd.u.ioctl.subfunc = SCSI_DR_INFO | L_CTRL_PATTERN;
-                gdtcmd.u.ioctl.channel = 
+                gdtcmd->Service = CACHESERVICE;
+                gdtcmd->OpCode = GDT_IOCTL;
+                gdtcmd->u.ioctl.p_param = paddr;
+                gdtcmd->u.ioctl.param_size = sizeof(gdth_diskinfo_str);
+                gdtcmd->u.ioctl.subfunc = SCSI_DR_INFO | L_CTRL_PATTERN;
+                gdtcmd->u.ioctl.channel = 
                     ha->raw[i].address | ha->raw[i].id_list[j];
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-                gdth_do_req(scp, &gdtcmd, cmnd, 30);
+                gdth_do_req(scp, gdtcmd, cmnd, 30);
                 if (scp->sr_command->SCp.Status == S_OK) 
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-                gdth_do_cmd(scp, &gdtcmd, cmnd, 30);
-                if (scp->SCp.Status == S_OK) 
 #else
-                gdth_do_cmd(&scp, &gdtcmd, cmnd, 30);
-                if (scp.SCp.Status == S_OK) 
+                gdth_do_cmd(scp, gdtcmd, cmnd, 30);
+                if (scp->SCp.Status == S_OK) 
 #endif
                 {
                     strncpy(hrec,pdi->vendor,8);
@@ -478,23 +458,20 @@
                     TRACE2(("scsi_drv_defcnt() chn %d dev %d\n",
                             i, ha->raw[i].id_list[j]));             
                     pdef = (gdth_defcnt_str *)buf;
-                    gdtcmd.Service = CACHESERVICE;
-                    gdtcmd.OpCode = GDT_IOCTL;
-                    gdtcmd.u.ioctl.p_param = paddr;
-                    gdtcmd.u.ioctl.param_size = sizeof(gdth_defcnt_str);
-                    gdtcmd.u.ioctl.subfunc = SCSI_DEF_CNT | L_CTRL_PATTERN;
-                    gdtcmd.u.ioctl.channel = 
+                    gdtcmd->Service = CACHESERVICE;
+                    gdtcmd->OpCode = GDT_IOCTL;
+                    gdtcmd->u.ioctl.p_param = paddr;
+                    gdtcmd->u.ioctl.param_size = sizeof(gdth_defcnt_str);
+                    gdtcmd->u.ioctl.subfunc = SCSI_DEF_CNT | L_CTRL_PATTERN;
+                    gdtcmd->u.ioctl.channel = 
                         ha->raw[i].address | ha->raw[i].id_list[j];
                     pdef->sddc_type = 0x08;
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-                    gdth_do_req(scp, &gdtcmd, cmnd, 30);
+                    gdth_do_req(scp, gdtcmd, cmnd, 30);
                     if (scp->sr_command->SCp.Status == S_OK) 
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-                    gdth_do_cmd(scp, &gdtcmd, cmnd, 30);
-                    if (scp->SCp.Status == S_OK) 
 #else
-                    gdth_do_cmd(&scp, &gdtcmd, cmnd, 30);
-                    if (scp.SCp.Status == S_OK) 
+                    gdth_do_cmd(scp, gdtcmd, cmnd, 30);
+                    if (scp->SCp.Status == S_OK) 
 #endif
                     {
                         size = sprintf(buffer+len,
@@ -536,21 +513,18 @@
                 /* 3.a log. drive info */
                 TRACE2(("cache_drv_info() drive no %d\n",drv_no));
                 pcdi = (gdth_cdrinfo_str *)buf;
-                gdtcmd.Service = CACHESERVICE;
-                gdtcmd.OpCode = GDT_IOCTL;
-                gdtcmd.u.ioctl.p_param = paddr;
-                gdtcmd.u.ioctl.param_size = sizeof(gdth_cdrinfo_str);
-                gdtcmd.u.ioctl.subfunc = CACHE_DRV_INFO;
-                gdtcmd.u.ioctl.channel = drv_no;
+                gdtcmd->Service = CACHESERVICE;
+                gdtcmd->OpCode = GDT_IOCTL;
+                gdtcmd->u.ioctl.p_param = paddr;
+                gdtcmd->u.ioctl.param_size = sizeof(gdth_cdrinfo_str);
+                gdtcmd->u.ioctl.subfunc = CACHE_DRV_INFO;
+                gdtcmd->u.ioctl.channel = drv_no;
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-                gdth_do_req(scp, &gdtcmd, cmnd, 30);
+                gdth_do_req(scp, gdtcmd, cmnd, 30);
                 if (scp->sr_command->SCp.Status != S_OK) 
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-                gdth_do_cmd(scp, &gdtcmd, cmnd, 30);
-                if (scp->SCp.Status != S_OK)
 #else
-                gdth_do_cmd(&scp, &gdtcmd, cmnd, 30);
-                if (scp.SCp.Status != S_OK)
+                gdth_do_cmd(scp, gdtcmd, cmnd, 30);
+                if (scp->SCp.Status != S_OK)
 #endif
                 {
                     break;
@@ -649,21 +623,18 @@
             /* 4.a array drive info */
             TRACE2(("array_info() drive no %d\n",i));
             pai = (gdth_arrayinf_str *)buf;
-            gdtcmd.Service = CACHESERVICE;
-            gdtcmd.OpCode = GDT_IOCTL;
-            gdtcmd.u.ioctl.p_param = paddr;
-            gdtcmd.u.ioctl.param_size = sizeof(gdth_arrayinf_str);
-            gdtcmd.u.ioctl.subfunc = ARRAY_INFO | LA_CTRL_PATTERN;
-            gdtcmd.u.ioctl.channel = i;
+            gdtcmd->Service = CACHESERVICE;
+            gdtcmd->OpCode = GDT_IOCTL;
+            gdtcmd->u.ioctl.p_param = paddr;
+            gdtcmd->u.ioctl.param_size = sizeof(gdth_arrayinf_str);
+            gdtcmd->u.ioctl.subfunc = ARRAY_INFO | LA_CTRL_PATTERN;
+            gdtcmd->u.ioctl.channel = i;
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-            gdth_do_req(scp, &gdtcmd, cmnd, 30);
+            gdth_do_req(scp, gdtcmd, cmnd, 30);
             if (scp->sr_command->SCp.Status == S_OK) 
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-            gdth_do_cmd(scp, &gdtcmd, cmnd, 30);
-            if (scp->SCp.Status == S_OK) 
 #else
-            gdth_do_cmd(&scp, &gdtcmd, cmnd, 30);
-            if (scp.SCp.Status == S_OK) 
+            gdth_do_cmd(scp, gdtcmd, cmnd, 30);
+            if (scp->SCp.Status == S_OK) 
 #endif
             {
                 if (pai->ai_state == 0)
@@ -731,23 +702,20 @@
             /* 5.a get host drive list */
             TRACE2(("host_get() drv_no %d\n",i));           
             phg = (gdth_hget_str *)buf;
-            gdtcmd.Service = CACHESERVICE;
-            gdtcmd.OpCode = GDT_IOCTL;
-            gdtcmd.u.ioctl.p_param = paddr;
-            gdtcmd.u.ioctl.param_size = sizeof(gdth_hget_str);
-            gdtcmd.u.ioctl.subfunc = HOST_GET | LA_CTRL_PATTERN;
-            gdtcmd.u.ioctl.channel = i;
+            gdtcmd->Service = CACHESERVICE;
+            gdtcmd->OpCode = GDT_IOCTL;
+            gdtcmd->u.ioctl.p_param = paddr;
+            gdtcmd->u.ioctl.param_size = sizeof(gdth_hget_str);
+            gdtcmd->u.ioctl.subfunc = HOST_GET | LA_CTRL_PATTERN;
+            gdtcmd->u.ioctl.channel = i;
             phg->entries = MAX_HDRIVES;
             phg->offset = GDTOFFSOF(gdth_hget_str, entry[0]); 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-            gdth_do_req(scp, &gdtcmd, cmnd, 30);
+            gdth_do_req(scp, gdtcmd, cmnd, 30);
             if (scp->sr_command->SCp.Status != S_OK) 
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-            gdth_do_cmd(scp, &gdtcmd, cmnd, 30);
-            if (scp->SCp.Status != S_OK) 
 #else
-            gdth_do_cmd(&scp, &gdtcmd, cmnd, 30);
-            if (scp.SCp.Status != S_OK) 
+            gdth_do_cmd(scp, gdtcmd, cmnd, 30);
+            if (scp->SCp.Status != S_OK) 
 #endif
             {
                 ha->hdr[i].ldr_no = i;
@@ -799,14 +767,14 @@
     len += size;  pos = begin + len;
 
     for (id = -1;;) {
-        id = gdth_read_event(ha, id, &estr);
-        if (estr.event_source == 0)
+        id = gdth_read_event(ha, id, estr);
+        if (estr->event_source == 0)
             break;
-        if (estr.event_data.eu.driver.ionode == hanum &&
-            estr.event_source == ES_ASYNC) { 
-            gdth_log_event(&estr.event_data, hrec);
+        if (estr->event_data.eu.driver.ionode == hanum &&
+            estr->event_source == ES_ASYNC) { 
+            gdth_log_event(&estr->event_data, hrec);
             do_gettimeofday(&tv);
-            sec = (int)(tv.tv_sec - estr.first_stamp);
+            sec = (int)(tv.tv_sec - estr->first_stamp);
             if (sec < 0) sec = 0;
             size = sprintf(buffer+len," date- %02d:%02d:%02d\t%s\n",
                            sec/3600, sec%3600/60, sec%60, hrec);
@@ -826,7 +794,7 @@
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
     scsi_release_request(scp);
     scsi_free_host_dev(sdev);
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+#else
     scsi_release_command(scp);
     scsi_free_host_dev(sdev);
 #endif
@@ -836,7 +804,12 @@
         len = length;
     TRACE2(("get_info() len %d pos %d begin %d offset %d length %d size %d\n",
             len,(int)pos,(int)begin,(int)offset,length,size));
-    return(len);
+    rc = len;
+
+free_fail:
+    kfree(gdtcmd);
+    kfree(estr);
+    return rc;
 }
 
 
@@ -864,13 +837,7 @@
                         char *cmnd, int timeout)
 {
     unsigned bufflen;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,7)
     DECLARE_COMPLETION(wait);
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-    DECLARE_MUTEX_LOCKED(sem);
-#else
-    struct semaphore sem = MUTEX_LOCKED;
-#endif
 
     TRACE2(("gdth_do_cmd()\n"));
     if (gdtcmd != NULL) { 
@@ -880,22 +847,11 @@
         scp->SCp.this_residual = DEFAULT_PRI;
         bufflen = 0;
     }
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,7)
+
     scp->request.rq_status = RQ_SCSI_BUSY;
     scp->request.waiting = &wait;
     scsi_do_cmd(scp, cmnd, gdtcmd, bufflen, gdth_scsi_done, timeout*HZ, 1);
     wait_for_completion(&wait);
-#else
-    scp->request.sem = &sem;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-    scsi_do_cmd(scp, cmnd, gdtcmd, bufflen, gdth_scsi_done, timeout*HZ, 1);
-#else
-    spin_lock_irq(&io_request_lock);
-    scsi_do_cmd(scp, cmnd, gdtcmd, bufflen, gdth_scsi_done, timeout*HZ, 1);
-    spin_unlock_irq(&io_request_lock);
-#endif
-    down(&sem);
-#endif
 }
 #endif
 
@@ -907,14 +863,10 @@
     scp->request->rq_status = RQ_SCSI_DONE;
     if (scp->request->waiting != NULL)
         complete(scp->request->waiting);
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,7)
+#else
     scp->request.rq_status = RQ_SCSI_DONE;
     if (scp->request.waiting != NULL)
         complete(scp->request.waiting);
-#else
-    scp->request.rq_status = RQ_SCSI_DONE;
-    if (scp->request.sem != NULL)
-        up(scp->request.sem);
 #endif
 }
 
@@ -929,7 +881,7 @@
         return NULL;
 
     ha = HADATA(gdth_ctr_tab[hanum]);
-    GDTH_LOCK_HA(ha, flags);
+    spin_lock_irqsave(&ha->smp_lock, flags);
 
     if (!ha->scratch_busy && size <= GDTH_SCRATCH) {
         ha->scratch_busy = TRUE;
@@ -938,19 +890,13 @@
     } else if (scratch) {
         ret_val = NULL;
     } else {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
         dma_addr_t dma_addr;
 
         ret_val = pci_alloc_consistent(ha->pdev, size, &dma_addr);
         *paddr = dma_addr;
-#else
-        ret_val = scsi_init_malloc(size, GFP_ATOMIC | GFP_DMA);
-        if (ret_val)
-            *paddr = virt_to_bus(ret_val);
-#endif
     }
 
-    GDTH_UNLOCK_HA(ha, flags);
+    spin_unlock_irqrestore(&ha->smp_lock, flags);
     return ret_val;
 }
 
@@ -960,19 +906,15 @@
     ulong flags;
 
     ha = HADATA(gdth_ctr_tab[hanum]);
-    GDTH_LOCK_HA(ha, flags);
+    spin_lock_irqsave(&ha->smp_lock, flags);
 
     if (buf == ha->pscratch) {
         ha->scratch_busy = FALSE;
     } else {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
         pci_free_consistent(ha->pdev, size, buf, paddr);
-#else
-        scsi_init_free((void *)buf, size);
-#endif
     }
 
-    GDTH_UNLOCK_HA(ha, flags);
+    spin_unlock_irqrestore(&ha->smp_lock, flags);
 }
 
 #ifdef GDTH_IOCTL_PROC
@@ -983,14 +925,14 @@
     int ret_val;
 
     ha = HADATA(gdth_ctr_tab[hanum]);
-    GDTH_LOCK_HA(ha, flags);
+    spin_lock_irqsave(&ha->smp_lock, flags);
 
     ret_val = FALSE;
     if (ha->scratch_busy) {
         if (((gdth_iord_str *)ha->pscratch)->size == (ulong32)size)
             ret_val = TRUE;
     }
-    GDTH_UNLOCK_HA(ha, flags);
+    spin_unlock_irqrestore(&ha->smp_lock, flags);
     return ret_val;
 }
 #endif
@@ -1004,36 +946,23 @@
     unchar b, t;
 
     ha = HADATA(gdth_ctr_tab[hanum]);
-    GDTH_LOCK_HA(ha, flags);
+    spin_lock_irqsave(&ha->smp_lock, flags);
 
     for (i = 0; i < GDTH_MAXCMDS; ++i) {
         scp = ha->cmd_tab[i].cmnd;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+
         b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel;
         t = scp->device->id;
-#else
-        b = virt_ctr ? NUMDATA(scp->host)->busnum : scp->channel;
-        t = scp->target;
-#endif
         if (!SPECIAL_SCP(scp) && t == (unchar)id && 
             b == (unchar)busnum) {
             scp->SCp.have_data_in = 0;
-            GDTH_UNLOCK_HA(ha, flags);
+            spin_unlock_irqrestore(&ha->smp_lock, flags);
             while (!scp->SCp.have_data_in)
                 barrier();
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-            GDTH_LOCK_SCSI_DONE(scp->device->host, flags);
-            scp->scsi_done(scp);
-            GDTH_UNLOCK_SCSI_DONE(scp->device->host, flags);
-#else
-            GDTH_LOCK_SCSI_DONE(flags);
-            scp->scsi_done(scp);
-            GDTH_UNLOCK_SCSI_DONE(flags);
-#endif
-        GDTH_LOCK_HA(ha, flags);
+            spin_lock_irqsave(&ha->smp_lock, flags);
         }
     }
-    GDTH_UNLOCK_HA(ha, flags);
+    spin_unlock_irqrestore(&ha->smp_lock, flags);
 }
 
 static void gdth_stop_timeout(int hanum, int busnum, int id)
@@ -1044,22 +973,17 @@
     unchar b, t;
 
     ha = HADATA(gdth_ctr_tab[hanum]);
-    GDTH_LOCK_HA(ha, flags);
+    spin_lock_irqsave(&ha->smp_lock, flags);
 
     for (scp = ha->req_first; scp; scp = (Scsi_Cmnd *)scp->SCp.ptr) {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
         b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel;
         t = scp->device->id;
-#else
-        b = virt_ctr ? NUMDATA(scp->host)->busnum : scp->channel;
-        t = scp->target;
-#endif
         if (t == (unchar)id && b == (unchar)busnum) {
             TRACE2(("gdth_stop_timeout(): update_timeout()\n"));
             scp->SCp.buffers_residual = gdth_update_timeout(hanum, scp, 0);
         }
     }
-    GDTH_UNLOCK_HA(ha, flags);
+    spin_unlock_irqrestore(&ha->smp_lock, flags);
 }
 
 static void gdth_start_timeout(int hanum, int busnum, int id)
@@ -1070,22 +994,17 @@
     unchar b, t;
 
     ha = HADATA(gdth_ctr_tab[hanum]);
-    GDTH_LOCK_HA(ha, flags);
+    spin_lock_irqsave(&ha->smp_lock, flags);
 
     for (scp = ha->req_first; scp; scp = (Scsi_Cmnd *)scp->SCp.ptr) {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
         b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel;
         t = scp->device->id;
-#else
-        b = virt_ctr ? NUMDATA(scp->host)->busnum : scp->channel;
-        t = scp->target;
-#endif
         if (t == (unchar)id && b == (unchar)busnum) {
             TRACE2(("gdth_start_timeout(): update_timeout()\n"));
             gdth_update_timeout(hanum, scp, scp->SCp.buffers_residual);
         }
     }
-    GDTH_UNLOCK_HA(ha, flags);
+    spin_unlock_irqrestore(&ha->smp_lock, flags);
 }
 
 static int gdth_update_timeout(int hanum, Scsi_Cmnd *scp, int timeout)
diff -Nru a/drivers/scsi/gdth_proc.h b/drivers/scsi/gdth_proc.h
--- a/drivers/scsi/gdth_proc.h	2005-03-01 23:39:08 -08:00
+++ b/drivers/scsi/gdth_proc.h	2005-03-01 23:39:08 -08:00
@@ -14,14 +14,10 @@
 static void gdth_do_req(Scsi_Request *srp, gdth_cmd_str *cmd, 
                         char *cmnd, int timeout);
 static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Request *scp);
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+#else
 static void gdth_do_cmd(Scsi_Cmnd *scp, gdth_cmd_str *cmd, 
                         char *cmnd, int timeout);
 static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Cmnd *scp);
-#else 
-static void gdth_do_cmd(Scsi_Cmnd *scp, gdth_cmd_str *cmd, 
-                        char *cmnd, int timeout);
-static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Cmnd scp);
 #endif
 
 static char *gdth_ioctl_alloc(int hanum, int size, int scratch,
diff -Nru a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
--- a/drivers/scsi/hosts.c	2005-03-01 23:38:51 -08:00
+++ b/drivers/scsi/hosts.c	2005-03-01 23:38:51 -08:00
@@ -28,6 +28,7 @@
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/completion.h>
+#include <linux/transport_class.h>
 
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_host.h>
@@ -79,11 +80,11 @@
 
 	set_bit(SHOST_DEL, &shost->shost_state);
 
+	transport_unregister_device(&shost->shost_gendev);
 	class_device_unregister(&shost->shost_classdev);
-	if (shost->transport_classdev.class)
-		class_device_unregister(&shost->transport_classdev);
 	device_del(&shost->shost_gendev);
 }
+EXPORT_SYMBOL(scsi_remove_host);
 
 /**
  * scsi_add_host - add a scsi host
@@ -128,16 +129,14 @@
 					 GFP_KERNEL)) == NULL)
 		goto out_del_classdev;
 
-	if (shost->transportt->host_setup)
-		shost->transportt->host_setup(shost);
-
 	error = scsi_sysfs_add_host(shost);
 	if (error)
-		goto out_del_classdev;
+		goto out_destroy_host;
 
 	scsi_proc_host_add(shost);
 	return error;
 
+ out_destroy_host:
  out_del_classdev:
 	class_device_del(&shost->shost_classdev);
  out_del_gendev:
@@ -145,6 +144,7 @@
  out:
 	return error;
 }
+EXPORT_SYMBOL(scsi_add_host);
 
 static void scsi_host_dev_release(struct device *dev)
 {
@@ -301,6 +301,7 @@
 	kfree(shost);
 	return NULL;
 }
+EXPORT_SYMBOL(scsi_host_alloc);
 
 struct Scsi_Host *scsi_register(struct scsi_host_template *sht, int privsize)
 {
@@ -316,12 +317,14 @@
 		list_add_tail(&shost->sht_legacy_list, &sht->legacy_hosts);
 	return shost;
 }
+EXPORT_SYMBOL(scsi_register);
 
 void scsi_unregister(struct Scsi_Host *shost)
 {
 	list_del(&shost->sht_legacy_list);
 	scsi_host_put(shost);
 }
+EXPORT_SYMBOL(scsi_unregister);
 
 /**
  * scsi_host_lookup - get a reference to a Scsi_Host by host no
@@ -349,6 +352,7 @@
 
 	return shost;
 }
+EXPORT_SYMBOL(scsi_host_lookup);
 
 /**
  * scsi_host_get - inc a Scsi_Host ref count
@@ -361,6 +365,7 @@
 		return NULL;
 	return shost;
 }
+EXPORT_SYMBOL(scsi_host_get);
 
 /**
  * scsi_host_put - dec a Scsi_Host ref count
@@ -370,6 +375,7 @@
 {
 	put_device(&shost->shost_gendev);
 }
+EXPORT_SYMBOL(scsi_host_put);
 
 int scsi_init_hosts(void)
 {
@@ -380,3 +386,9 @@
 {
 	class_unregister(&shost_class);
 }
+
+int scsi_is_host_device(const struct device *dev)
+{
+	return dev->release == scsi_host_dev_release;
+}
+EXPORT_SYMBOL(scsi_is_host_device);
diff -Nru a/drivers/scsi/ibmmca.c b/drivers/scsi/ibmmca.c
--- a/drivers/scsi/ibmmca.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/scsi/ibmmca.c	2005-03-01 23:38:52 -08:00
@@ -292,7 +292,7 @@
 #define INTEGRATED_SCSI          101
 
 /* List of possible IBM-SCSI-adapters */
-struct subsys_list_struct subsys_list[] = {
+static struct subsys_list_struct subsys_list[] = {
 	{0x8efc, "IBM SCSI-2 F/W Adapter"},	/* special = 0 */
 	{0x8efd, "IBM 7568 Industrial Computer SCSI Adapter w/Cache"},	/* special = 1 */
 	{0x8ef8, "IBM Expansion Unit SCSI Controller"},	/* special = 2 */
@@ -451,13 +451,16 @@
    (that is kernel version 2.1.x) */
 #if defined(MODULE)
 static char *boot_options = NULL;
-MODULE_PARM(boot_options, "s");
-MODULE_PARM(io_port, "1-" __MODULE_STRING(IM_MAX_HOSTS) "i");
-MODULE_PARM(scsi_id, "1-" __MODULE_STRING(IM_MAX_HOSTS) "i");
+module_param(boot_options, charp, 0);
+module_param_array(io_port, int, NULL, 0);
+module_param_array(scsi_id, int, NULL, 0);
+
+#if 0 /* FIXME: No longer exist? --RR */
 MODULE_PARM(display, "1i");
 MODULE_PARM(adisplay, "1i");
 MODULE_PARM(normal, "1i");
 MODULE_PARM(ansi, "1i");
+#endif
 #endif
 /*counter of concurrent disk read/writes, to turn on/off disk led */
 static int disk_rw_in_progress = 0;
diff -Nru a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c
--- a/drivers/scsi/ibmvscsi/ibmvscsi.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/scsi/ibmvscsi/ibmvscsi.c	2005-03-01 23:38:53 -08:00
@@ -69,6 +69,7 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/dma-mapping.h>
+#include <linux/delay.h>
 #include <asm/vio.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
@@ -86,7 +87,7 @@
 static int init_timeout = 5;
 static int max_requests = 50;
 
-#define IBMVSCSI_VERSION "1.5.1"
+#define IBMVSCSI_VERSION "1.5.5"
 
 MODULE_DESCRIPTION("IBM Virtual SCSI");
 MODULE_AUTHOR("Dave Boutcher");
@@ -255,6 +256,7 @@
 {
 	evt_struct->cmnd = NULL;
 	evt_struct->cmnd_done = NULL;
+	evt_struct->sync_srp = NULL;
 	evt_struct->crq.format = format;
 	evt_struct->crq.timeout = timeout;
 	evt_struct->done = done;
@@ -466,7 +468,7 @@
 static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct,
 				   struct ibmvscsi_host_data *hostdata)
 {
-	struct scsi_cmnd *cmnd = evt_struct->cmnd;
+	struct scsi_cmnd *cmnd;
 	u64 *crq_as_u64 = (u64 *) &evt_struct->crq;
 	int rc;
 
@@ -478,22 +480,15 @@
 	if ((evt_struct->crq.format == VIOSRP_SRP_FORMAT) &&
 	    (atomic_dec_if_positive(&hostdata->request_limit) < 0)) {
 		/* See if the adapter is disabled */
-		if (atomic_read(&hostdata->request_limit) < 0) {
-			if (cmnd)
-				cmnd->result = DID_ERROR << 16;
-			if (evt_struct->cmnd_done)
-				evt_struct->cmnd_done(cmnd);
-			unmap_cmd_data(&evt_struct->iu.srp.cmd,
-				       hostdata->dev);
-			free_event_struct(&hostdata->pool, evt_struct);
-			return 0;
-		} else {
-			printk("ibmvscsi: Warning, request_limit exceeded\n");
-			unmap_cmd_data(&evt_struct->iu.srp.cmd,
-				       hostdata->dev);
-			free_event_struct(&hostdata->pool, evt_struct);
-			return SCSI_MLQUEUE_HOST_BUSY;
-		}
+		if (atomic_read(&hostdata->request_limit) < 0)
+			goto send_error;
+	
+		printk(KERN_WARNING 
+		       "ibmvscsi: Warning, request_limit exceeded\n");
+		unmap_cmd_data(&evt_struct->iu.srp.cmd,
+			       hostdata->dev);
+		free_event_struct(&hostdata->pool, evt_struct);
+		return SCSI_MLQUEUE_HOST_BUSY;
 	}
 
 	/* Copy the IU into the transfer area */
@@ -510,18 +505,24 @@
 	     ibmvscsi_send_crq(hostdata, crq_as_u64[0], crq_as_u64[1])) != 0) {
 		list_del(&evt_struct->list);
 
-		cmnd = evt_struct->cmnd;
 		printk(KERN_ERR "ibmvscsi: failed to send event struct rc %d\n",
 		       rc);
-		unmap_cmd_data(&evt_struct->iu.srp.cmd, hostdata->dev);
-		free_event_struct(&hostdata->pool, evt_struct);
-		if (cmnd)
-			cmnd->result = DID_ERROR << 16;
-		if (evt_struct->cmnd_done)
-			evt_struct->cmnd_done(cmnd);
+		goto send_error;
 	}
 
 	return 0;
+
+ send_error:
+	unmap_cmd_data(&evt_struct->iu.srp.cmd, hostdata->dev);
+
+	if ((cmnd = evt_struct->cmnd) != NULL) {
+		cmnd->result = DID_ERROR << 16;
+		evt_struct->cmnd_done(cmnd);
+	} else if (evt_struct->done)
+		evt_struct->done(evt_struct);
+	
+	free_event_struct(&hostdata->pool, evt_struct);
+	return 0;
 }
 
 /**
@@ -536,6 +537,13 @@
 	struct srp_rsp *rsp = &evt_struct->xfer_iu->srp.rsp;
 	struct scsi_cmnd *cmnd = evt_struct->cmnd;
 
+	if (unlikely(rsp->type != SRP_RSP_TYPE)) {
+		if (printk_ratelimit())
+			printk(KERN_WARNING 
+			       "ibmvscsi: bad SRP RSP type %d\n",
+			       rsp->type);
+	}
+	
 	if (cmnd) {
 		cmnd->result = rsp->status;
 		if (((cmnd->result >> 1) & 0x1f) == CHECK_CONDITION)
@@ -640,11 +648,16 @@
 		       evt_struct->xfer_iu->mad.adapter_info.common.status);
 	} else {
 		printk("ibmvscsi: host srp version: %s, "
-		       "host partition %s (%d), OS %d\n",
+		       "host partition %s (%d), OS %d, max io %u\n",
 		       hostdata->madapter_info.srp_version,
 		       hostdata->madapter_info.partition_name,
 		       hostdata->madapter_info.partition_number,
-		       hostdata->madapter_info.os_type);
+		       hostdata->madapter_info.os_type,
+		       hostdata->madapter_info.port_max_txu[0]);
+		
+		if (hostdata->madapter_info.port_max_txu[0]) 
+			hostdata->host->max_sectors = 
+				hostdata->madapter_info.port_max_txu[0] >> 9;
 	}
 }
 
@@ -795,6 +808,10 @@
  */
 static void sync_completion(struct srp_event_struct *evt_struct)
 {
+	/* copy the response back */
+	if (evt_struct->sync_srp)
+		*evt_struct->sync_srp = *evt_struct->xfer_iu;
+	
 	complete(&evt_struct->comp);
 }
 
@@ -809,6 +826,8 @@
 	struct srp_tsk_mgmt *tsk_mgmt;
 	struct srp_event_struct *evt;
 	struct srp_event_struct *tmp_evt, *found_evt;
+	union viosrp_iu srp_rsp;
+	int rsp_rc;
 	u16 lun = lun_from_dev(cmd->device);
 
 	/* First, find this command in our sent list so we can figure
@@ -848,6 +867,7 @@
 	printk(KERN_INFO "ibmvscsi: aborting command. lun 0x%lx, tag 0x%lx\n",
 	       tsk_mgmt->lun, tsk_mgmt->managed_task_tag);
 
+	evt->sync_srp = &srp_rsp;
 	init_completion(&evt->comp);
 	if (ibmvscsi_send_srp_event(evt, hostdata) != 0) {
 		printk(KERN_ERR "ibmvscsi: failed to send abort() event\n");
@@ -858,6 +878,29 @@
 	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)) {
+		if (printk_ratelimit())
+			printk(KERN_WARNING 
+			       "ibmvscsi: abort bad SRP RSP type %d\n",
+			       srp_rsp.srp.generic.type);
+		return FAILED;
+	}
+
+	if (srp_rsp.srp.rsp.rspvalid)
+		rsp_rc = *((int *)srp_rsp.srp.rsp.sense_and_response_data);
+	else
+		rsp_rc = srp_rsp.srp.rsp.status;
+
+	if (rsp_rc) {
+		if (printk_ratelimit())
+			printk(KERN_WARNING 
+		       "ibmvscsi: abort code %d for task tag 0x%lx\n",
+			       rsp_rc,
+			       tsk_mgmt->managed_task_tag);
+		return FAILED;
+	}
+
 	/* Because we dropped the spinlock above, it's possible
 	 * The event is no longer in our list.  Make sure it didn't
 	 * complete while we were aborting
@@ -870,13 +913,17 @@
 		}
 	}
 
+	if (found_evt == NULL) {
+		printk(KERN_INFO
+		       "ibmvscsi: aborted task tag 0x%lx completed\n",
+		       tsk_mgmt->managed_task_tag);
+		return SUCCESS;
+	}
+
 	printk(KERN_INFO
 	       "ibmvscsi: successfully aborted task tag 0x%lx\n",
 	       tsk_mgmt->managed_task_tag);
 
-	if (found_evt == NULL)
-		return SUCCESS;
-
 	cmd->result = (DID_ABORT << 16);
 	list_del(&found_evt->list);
 	unmap_cmd_data(&found_evt->iu.srp.cmd, found_evt->hostdata->dev);
@@ -898,6 +945,8 @@
 	struct srp_tsk_mgmt *tsk_mgmt;
 	struct srp_event_struct *evt;
 	struct srp_event_struct *tmp_evt, *pos;
+	union viosrp_iu srp_rsp;
+	int rsp_rc;
 	u16 lun = lun_from_dev(cmd->device);
 
 	evt = get_event_struct(&hostdata->pool);
@@ -922,6 +971,7 @@
 	printk(KERN_INFO "ibmvscsi: resetting device. lun 0x%lx\n",
 	       tsk_mgmt->lun);
 
+	evt->sync_srp = &srp_rsp;
 	init_completion(&evt->comp);
 	if (ibmvscsi_send_srp_event(evt, hostdata) != 0) {
 		printk(KERN_ERR "ibmvscsi: failed to send reset event\n");
@@ -932,6 +982,29 @@
 	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)) {
+		if (printk_ratelimit())
+			printk(KERN_WARNING 
+			       "ibmvscsi: reset bad SRP RSP type %d\n",
+			       srp_rsp.srp.generic.type);
+		return FAILED;
+	}
+
+	if (srp_rsp.srp.rsp.rspvalid)
+		rsp_rc = *((int *)srp_rsp.srp.rsp.sense_and_response_data);
+	else
+		rsp_rc = srp_rsp.srp.rsp.status;
+
+	if (rsp_rc) {
+		if (printk_ratelimit())
+			printk(KERN_WARNING 
+			       "ibmvscsi: reset code %d for task tag 0x%lx\n",
+		       rsp_rc,
+			       tsk_mgmt->managed_task_tag);
+		return FAILED;
+	}
+
 	/* We need to find all commands for this LUN that have not yet been
 	 * responded to, and fail them with DID_RESET
 	 */
@@ -1047,6 +1120,13 @@
 		return;
 	}
 
+	if (atomic_read(&evt_struct->free)) {
+		printk(KERN_ERR
+		       "ibmvscsi: received duplicate  correlation_token 0x%p!\n",
+		       (void *)crq->IU_data_ptr);
+		return;
+	}
+
 	if (crq->format == VIOSRP_SRP_FORMAT)
 		atomic_add(evt_struct->xfer_iu->srp.rsp.request_limit_delta,
 			   &hostdata->request_limit);
@@ -1294,6 +1374,7 @@
 	hostdata->host = host;
 	hostdata->dev = dev;
 	atomic_set(&hostdata->request_limit, -1);
+	hostdata->host->max_sectors = 32 * 8; /* default max I/O 32 pages */
 
 	if (ibmvscsi_init_crq_queue(&hostdata->queue, hostdata,
 				    max_requests) != 0) {
@@ -1325,10 +1406,9 @@
 		 */
 		for (wait_switch = jiffies + (init_timeout * HZ);
 		     time_before(jiffies, wait_switch) &&
-		     atomic_read(&hostdata->request_limit) < 0;) {
+		     atomic_read(&hostdata->request_limit) < 2;) {
 
-			set_current_state(TASK_UNINTERRUPTIBLE);
-			schedule_timeout(HZ / 100);
+			msleep(10);
 		}
 
 		/* if we now have a valid request_limit, initiate a scan */
diff -Nru a/drivers/scsi/ibmvscsi/ibmvscsi.h b/drivers/scsi/ibmvscsi/ibmvscsi.h
--- a/drivers/scsi/ibmvscsi/ibmvscsi.h	2005-03-01 23:39:08 -08:00
+++ b/drivers/scsi/ibmvscsi/ibmvscsi.h	2005-03-01 23:39:08 -08:00
@@ -67,6 +67,7 @@
 	union viosrp_iu iu;
 	void (*cmnd_done) (struct scsi_cmnd *);
 	struct completion comp;
+	union viosrp_iu *sync_srp;
 };
 
 /* a pool of event structs for use */
diff -Nru a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
--- a/drivers/scsi/ide-scsi.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/scsi/ide-scsi.c	2005-03-01 23:39:07 -08:00
@@ -152,7 +152,7 @@
 		}
 		count = min(pc->sg->length - pc->b_count, bcount);
 		buf = page_address(pc->sg->page) + pc->sg->offset;
-		atapi_input_bytes (drive, buf + pc->b_count, count);
+		drive->hwif->atapi_input_bytes(drive, buf + pc->b_count, count);
 		bcount -= count; pc->b_count += count;
 		if (pc->b_count == pc->sg->length) {
 			pc->sg++;
@@ -174,7 +174,7 @@
 		}
 		count = min(pc->sg->length - pc->b_count, bcount);
 		buf = page_address(pc->sg->page) + pc->sg->offset;
-		atapi_output_bytes (drive, buf + pc->b_count, count);
+		drive->hwif->atapi_output_bytes(drive, buf + pc->b_count, count);
 		bcount -= count; pc->b_count += count;
 		if (pc->b_count == pc->sg->length) {
 			pc->sg++;
@@ -301,23 +301,9 @@
 	return ide_do_drive_cmd(drive, rq, ide_preempt);
 }
 
-ide_startstop_t idescsi_atapi_error (ide_drive_t *drive, const char *msg, byte stat)
+static ide_startstop_t
+idescsi_atapi_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err)
 {
-	struct request *rq;
-	byte err;
-
-	err = ide_dump_atapi_status(drive, msg, stat);
-
-	if (drive == NULL || (rq = HWGROUP(drive)->rq) == NULL)
-		return ide_stopped;
-
-	/* retry only "normal" I/O: */
-	if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK | REQ_DRIVE_TASKFILE)) {
-		rq->errors = 1;
-		ide_end_drive_cmd(drive, stat, err);
-		return ide_stopped;
-	}
-
 	if (HWIF(drive)->INB(IDE_STATUS_REG) & (BUSY_STAT|DRQ_STAT))
 		/* force an abort */
 		HWIF(drive)->OUTB(WIN_IDLEIMMEDIATE,IDE_COMMAND_REG);
@@ -327,20 +313,9 @@
 	return ide_stopped;
 }
 
-ide_startstop_t idescsi_atapi_abort (ide_drive_t *drive, const char *msg)
+static ide_startstop_t
+idescsi_atapi_abort(ide_drive_t *drive, struct request *rq)
 {
-	struct request *rq;
-
-	if (drive == NULL || (rq = HWGROUP(drive)->rq) == NULL)
-	       return ide_stopped;
-
-	/* retry only "normal" I/O: */
-	if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK | REQ_DRIVE_TASKFILE)) {
-		rq->errors = 1;
-		ide_end_drive_cmd(drive, BUSY_STAT, 0);
-		return ide_stopped;
-	}
-
 #if IDESCSI_DEBUG_LOG
 	printk(KERN_WARNING "idescsi_atapi_abort called for %lu\n",
 			((idescsi_pc_t *) rq->special)->scsi_cmd->serial_number);
@@ -506,7 +481,7 @@
 					if (pc->sg)
 						idescsi_input_buffers(drive, pc, temp);
 					else
-						atapi_input_bytes(drive, pc->current_position, temp);
+						drive->hwif->atapi_input_bytes(drive, pc->current_position, temp);
 					printk(KERN_ERR "ide-scsi: transferred %d of %d bytes\n", temp, bcount.all);
 				}
 				pc->actually_transferred += temp;
@@ -566,7 +541,7 @@
 	/* Set the interrupt routine */
 	ide_set_handler(drive, &idescsi_pc_intr, get_timeout(pc), idescsi_expiry);
 	/* Send the actual packet */
-	atapi_output_bytes(drive, scsi->pc->c, 12);
+	drive->hwif->atapi_output_bytes(drive, scsi->pc->c, 12);
 	if (test_bit (PC_DMA_OK, &pc->flags)) {
 		set_bit (PC_DMA_IN_PROGRESS, &pc->flags);
 		hwif->dma_start(drive);
diff -Nru a/drivers/scsi/imm.c b/drivers/scsi/imm.c
--- a/drivers/scsi/imm.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/scsi/imm.c	2005-03-01 23:39:17 -08:00
@@ -60,7 +60,7 @@
 	return *(imm_struct **)&host->hostdata;
 }
 
-static spinlock_t arbitration_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(arbitration_lock);
 
 static void got_it(imm_struct *dev)
 {
diff -Nru a/drivers/scsi/in2000.c b/drivers/scsi/in2000.c
--- a/drivers/scsi/in2000.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/scsi/in2000.c	2005-03-01 23:39:08 -08:00
@@ -186,7 +186,7 @@
 /* filled in by 'insmod' */
 static char *setup_strings;
 
-MODULE_PARM(setup_strings, "s");
+module_param(setup_strings, charp, 0);
 
 static inline uchar read_3393(struct IN2000_hostdata *hostdata, uchar reg_num)
 {
diff -Nru a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
--- a/drivers/scsi/ipr.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/scsi/ipr.c	2005-03-01 23:39:18 -08:00
@@ -89,7 +89,7 @@
 static unsigned int ipr_log_level = IPR_DEFAULT_LOG_LEVEL;
 static unsigned int ipr_max_speed = 1;
 static int ipr_testmode = 0;
-static spinlock_t ipr_driver_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(ipr_driver_lock);
 
 /* This table describes the differences between DMA controller chips */
 static const struct ipr_chip_cfg_t ipr_chip_cfg[] = {
@@ -312,6 +312,8 @@
 	"9041: Array protection temporarily suspended"},
 	{0x066B0200, 0, 1,
 	"9030: Array no longer protected due to missing or failed disk unit"},
+	{0x066B8200, 0, 1,
+	"9042: Corrupt array parity detected on specified device"},
 	{0x07270000, 0, 0,
 	"Failure due to other device"},
 	{0x07278000, 0, 1,
@@ -542,7 +544,7 @@
 		return -EIO;
 	}
 
-	if (pci_read_config_word(ioa_cfg->pdev, pcix_cmd_reg,
+	if (pci_read_config_word(ioa_cfg->pdev, pcix_cmd_reg + PCI_X_CMD,
 				 &ioa_cfg->saved_pcix_cmd_reg) != PCIBIOS_SUCCESSFUL) {
 		dev_err(&ioa_cfg->pdev->dev, "Failed to save PCI-X command register\n");
 		return -EIO;
@@ -564,7 +566,7 @@
 	int pcix_cmd_reg = pci_find_capability(ioa_cfg->pdev, PCI_CAP_ID_PCIX);
 
 	if (pcix_cmd_reg) {
-		if (pci_write_config_word(ioa_cfg->pdev, pcix_cmd_reg,
+		if (pci_write_config_word(ioa_cfg->pdev, pcix_cmd_reg + PCI_X_CMD,
 					  ioa_cfg->saved_pcix_cmd_reg) != PCIBIOS_SUCCESSFUL) {
 			dev_err(&ioa_cfg->pdev->dev, "Failed to setup PCI-X command register\n");
 			return -EIO;
@@ -2608,23 +2610,19 @@
 #endif
 
 /**
- * ipr_store_queue_depth - Change the device's queue depth
- * @dev:	device struct
- * @buf:	buffer
+ * ipr_change_queue_depth - Change the device's queue depth
+ * @sdev:	scsi device struct
+ * @qdepth:	depth to set
  *
  * Return value:
- * 	number of bytes printed to buffer
+ * 	actual depth set
  **/
-static ssize_t ipr_store_queue_depth(struct device *dev,
-				    const char *buf, size_t count)
+static int ipr_change_queue_depth(struct scsi_device *sdev, int qdepth)
 {
-	struct scsi_device *sdev = to_scsi_device(dev);
 	struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *)sdev->host->hostdata;
 	struct ipr_resource_entry *res;
-	int qdepth = simple_strtoul(buf, NULL, 10);
 	int tagged = 0;
 	unsigned long lock_flags = 0;
-	ssize_t len = -ENXIO;
 
 	spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
 	res = (struct ipr_resource_entry *)sdev->hostdata;
@@ -2633,23 +2631,13 @@
 
 		if (ipr_is_gscsi(res) && res->tcq_active)
 			tagged = MSG_ORDERED_TAG;
-
-		len = strlen(buf);
 	}
 
 	spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
 	scsi_adjust_queue_depth(sdev, tagged, qdepth);
-	return len;
+	return qdepth;
 }
 
-static struct device_attribute ipr_queue_depth_attr = {
-	.attr = {
-		.name = 	"queue_depth",
-		.mode =		S_IRUSR | S_IWUSR,
-	},
-	.store = ipr_store_queue_depth
-};
-
 /**
  * ipr_show_tcq_enable - Show if the device is enabled for tcqing
  * @dev:	device struct
@@ -2758,7 +2746,6 @@
 };
 
 static struct device_attribute *ipr_dev_attrs[] = {
-	&ipr_queue_depth_attr,
 	&ipr_tcqing_attr,
 	&ipr_adapter_handle_attr,
 	NULL,
@@ -3904,7 +3891,8 @@
 		ioarcb->cmd_pkt.flags_lo |= ipr_get_task_attributes(scsi_cmd);
 	}
 
-	if (!ipr_is_gscsi(res) && scsi_cmd->cmnd[0] >= 0xC0)
+	if (scsi_cmd->cmnd[0] >= 0xC0 &&
+	    (!ipr_is_gscsi(res) || scsi_cmd->cmnd[0] == IPR_QUERY_RSRC_STATE))
 		ioarcb->cmd_pkt.request_type = IPR_RQTYPE_IOACMD;
 
 	if (ipr_is_ioa_resource(res) && scsi_cmd->cmnd[0] == MODE_SELECT)
@@ -3958,6 +3946,7 @@
 	.slave_alloc = ipr_slave_alloc,
 	.slave_configure = ipr_slave_configure,
 	.slave_destroy = ipr_slave_destroy,
+	.change_queue_depth = ipr_change_queue_depth,
 	.bios_param = ipr_biosparam,
 	.can_queue = IPR_MAX_COMMANDS,
 	.this_id = -1,
diff -Nru a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h
--- a/drivers/scsi/ipr.h	2005-03-01 23:38:53 -08:00
+++ b/drivers/scsi/ipr.h	2005-03-01 23:38:53 -08:00
@@ -32,15 +32,12 @@
 #include <linux/kref.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
-#ifdef CONFIG_KDB
-#include <linux/kdb.h>
-#endif
 
 /*
  * Literals
  */
-#define IPR_DRIVER_VERSION "2.0.11"
-#define IPR_DRIVER_DATE "(August 3, 2004)"
+#define IPR_DRIVER_VERSION "2.0.12"
+#define IPR_DRIVER_DATE "(December 14, 2004)"
 
 /*
  * IPR_DBG_TRACE: Setting this to 1 will turn on some general function tracing
@@ -146,6 +143,7 @@
 /*
  * Adapter Commands
  */
+#define IPR_QUERY_RSRC_STATE				0xC2
 #define IPR_RESET_DEVICE				0xC3
 #define	IPR_RESET_TYPE_SELECT				0x80
 #define	IPR_LUN_RESET					0x40
@@ -1059,20 +1057,20 @@
 };
 
 struct ipr_software_inq_lid_info {
-    u32  load_id;
-    u32  timestamp[3];
+	u32 load_id;
+	u32 timestamp[3];
 }__attribute__((packed, aligned (4)));
 
 struct ipr_ucode_image_header {
-    u32 header_length;
-    u32 lid_table_offset;
-    u8 major_release;
-    u8 card_type;
-    u8 minor_release[2];
-    u8 reserved[20];
-    char eyecatcher[16];
-    u32 num_lids;
-    struct ipr_software_inq_lid_info lid[1];
+	u32 header_length;
+	u32 lid_table_offset;
+	u8 major_release;
+	u8 card_type;
+	u8 minor_release[2];
+	u8 reserved[20];
+	char eyecatcher[16];
+	u32 num_lids;
+	struct ipr_software_inq_lid_info lid[1];
 }__attribute__((packed, aligned (4)));
 
 /*
@@ -1082,18 +1080,6 @@
 #define IPR_DBG_CMD(CMD) do { CMD; } while (0)
 #else
 #define IPR_DBG_CMD(CMD)
-#endif
-
-#define ipr_breakpoint_data KERN_ERR IPR_NAME\
-": %s: %s: Line: %d ioa_cfg: %p\n", __FILE__, \
-__FUNCTION__, __LINE__, ioa_cfg
-
-#if defined(CONFIG_KDB) && !defined(CONFIG_PPC_ISERIES)
-#define ipr_breakpoint {printk(ipr_breakpoint_data); KDB_ENTER();}
-#define ipr_breakpoint_or_die {printk(ipr_breakpoint_data); KDB_ENTER();}
-#else
-#define ipr_breakpoint
-#define ipr_breakpoint_or_die panic(ipr_breakpoint_data)
 #endif
 
 #ifdef CONFIG_SCSI_IPR_TRACE
diff -Nru a/drivers/scsi/jazz_esp.c b/drivers/scsi/jazz_esp.c
--- a/drivers/scsi/jazz_esp.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/scsi/jazz_esp.c	2005-03-01 23:38:52 -08:00
@@ -6,6 +6,7 @@
  * jazz_esp is based on David S. Miller's ESP driver and cyber_esp
  */
 
+#include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/delay.h>
 #include <linux/types.h>
@@ -27,7 +28,7 @@
 #include <asm/pgtable.h>
 
 static int  dma_bytes_sent(struct NCR_ESP *esp, int fifo_count);
-static int  dma_can_transfer(struct NCR_ESP *esp, Scsi_Cmnd *sp);
+static int  dma_can_transfer(struct NCR_ESP *esp, struct scsi_cmnd *sp);
 static void dma_dump_state(struct NCR_ESP *esp);
 static void dma_init_read(struct NCR_ESP *esp, __u32 vaddress, int length);
 static void dma_init_write(struct NCR_ESP *esp, __u32 vaddress, int length);
@@ -36,11 +37,11 @@
 static int  dma_irq_p(struct NCR_ESP *esp);
 static int  dma_ports_p(struct NCR_ESP *esp);
 static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write);
-static void dma_mmu_get_scsi_one (struct NCR_ESP *esp, Scsi_Cmnd *sp);
-static void dma_mmu_get_scsi_sgl (struct NCR_ESP *esp, Scsi_Cmnd *sp);
-static void dma_mmu_release_scsi_one (struct NCR_ESP *esp, Scsi_Cmnd *sp);
-static void dma_mmu_release_scsi_sgl (struct NCR_ESP *esp, Scsi_Cmnd *sp);
-static void dma_advance_sg (Scsi_Cmnd *sp);
+static void dma_mmu_get_scsi_one (struct NCR_ESP *esp, struct scsi_cmnd *sp);
+static void dma_mmu_get_scsi_sgl (struct NCR_ESP *esp, struct scsi_cmnd *sp);
+static void dma_mmu_release_scsi_one (struct NCR_ESP *esp, struct scsi_cmnd *sp);
+static void dma_mmu_release_scsi_sgl (struct NCR_ESP *esp, struct scsi_cmnd *sp);
+static void dma_advance_sg (struct scsi_cmnd *sp);
 static void dma_led_off(struct NCR_ESP *);
 static void dma_led_on(struct NCR_ESP *);
 
@@ -51,8 +52,42 @@
 				 * via PIO.
 				 */
 
+int jazz_esp_detect(Scsi_Host_Template *tpnt);
+static int jazz_esp_release(struct Scsi_Host *shost)
+{
+	if (shost->irq)
+		free_irq(shost->irq, NULL);
+	if (shost->dma_channel != 0xff)
+		free_dma(shost->dma_channel);
+	if (shost->io_port && shost->n_io_port)
+		release_region(shost->io_port, shost->n_io_port);
+	scsi_unregister(shost);
+	return 0;
+}
+
+static Scsi_Host_Template driver_template = {
+	.proc_name		= "jazz_esp",
+	.proc_info		= &esp_proc_info,
+	.name			= "ESP 100/100a/200",
+	.detect			= jazz_esp_detect,
+	.slave_alloc		= esp_slave_alloc,
+	.slave_destroy		= esp_slave_destroy,
+	.release		= jazz_esp_release,
+	.info			= esp_info,
+	.queuecommand		= esp_queue,
+	.eh_abort_handler	= esp_abort,
+	.eh_bus_reset_handler	= esp_reset,
+	.can_queue		= 7,
+	.this_id		= 7,
+	.sg_tablesize		= SG_ALL,
+	.cmd_per_lun		= 1,
+	.use_clustering		= DISABLE_CLUSTERING,
+};
+
+#include "scsi_module.c"
+
 /***************************************************************** Detection */
-int jazz_esp_detect(Scsi_Host_Template *tpnt)
+static int jazz_esp_detect(struct scsi_host_template *tpnt)
 {
     struct NCR_ESP *esp;
     struct ConfigDev *esp_dev;
@@ -115,7 +150,7 @@
 	esp->esp_command = (volatile unsigned char *)cmd_buffer;
 	
 	/* get virtual dma address for command buffer */
-	esp->esp_command_dvma = vdma_alloc(PHYSADDR(cmd_buffer), sizeof (cmd_buffer));
+	esp->esp_command_dvma = vdma_alloc(CPHYSADDR(cmd_buffer), sizeof (cmd_buffer));
 	
 	esp->irq = JAZZ_SCSI_IRQ;
 	request_irq(JAZZ_SCSI_IRQ, esp_intr, SA_INTERRUPT, "JAZZ SCSI",
@@ -139,25 +174,13 @@
     return 0;
 }
 
-static int jazz_esp_release(struct Scsi_Host *shost)
-{
-	if (shost->irq)
-		free_irq(shost->irq, NULL);
-	if (shost->dma_channel != 0xff)
-		free_dma(shost->dma_channel);
-	if (shost->io_port && shost->n_io_port)
-		release_region(shost->io_port, shost->n_io_port);
-	scsi_unregister(shost);
-	return 0;
-}
-
 /************************************************************* DMA Functions */
 static int dma_bytes_sent(struct NCR_ESP *esp, int fifo_count)
 {
     return fifo_count;
 }
 
-static int dma_can_transfer(struct NCR_ESP *esp, Scsi_Cmnd *sp)
+static int dma_can_transfer(struct NCR_ESP *esp, struct scsi_cmnd *sp)
 {
     /*
      * maximum DMA size is 1MB
@@ -230,43 +253,43 @@
     }
 }
 
-static void dma_mmu_get_scsi_one (struct NCR_ESP *esp, Scsi_Cmnd *sp)
+static void dma_mmu_get_scsi_one (struct NCR_ESP *esp, struct scsi_cmnd *sp)
 {
-    sp->SCp.have_data_in = vdma_alloc(PHYSADDR(sp->SCp.buffer), sp->SCp.this_residual);
+    sp->SCp.have_data_in = vdma_alloc(CPHYSADDR(sp->SCp.buffer), sp->SCp.this_residual);
     sp->SCp.ptr = (char *)((unsigned long)sp->SCp.have_data_in);
 }
 
-static void dma_mmu_get_scsi_sgl (struct NCR_ESP *esp, Scsi_Cmnd *sp)
+static void dma_mmu_get_scsi_sgl (struct NCR_ESP *esp, struct scsi_cmnd *sp)
 {
     int sz = sp->SCp.buffers_residual;
-    struct mmu_sglist *sg = (struct mmu_sglist *) sp->SCp.buffer;
+    struct scatterlist *sg = (struct scatterlist *) sp->SCp.buffer;
     
     while (sz >= 0) {
-	sg[sz].dvma_addr = vdma_alloc(PHYSADDR(sg[sz].addr), sg[sz].len);
+	sg[sz].dma_address = vdma_alloc(CPHYSADDR(page_address(sg[sz].page) + sg[sz].offset), sg[sz].length);
 	sz--;
     }
-    sp->SCp.ptr=(char *)((unsigned long)sp->SCp.buffer->dvma_address);
+    sp->SCp.ptr=(char *)(sp->SCp.buffer->dma_address);
 }    
 
-static void dma_mmu_release_scsi_one (struct NCR_ESP *esp, Scsi_Cmnd *sp)
+static void dma_mmu_release_scsi_one (struct NCR_ESP *esp, struct scsi_cmnd *sp)
 {
     vdma_free(sp->SCp.have_data_in);
 }
 
-static void dma_mmu_release_scsi_sgl (struct NCR_ESP *esp, Scsi_Cmnd *sp)
+static void dma_mmu_release_scsi_sgl (struct NCR_ESP *esp, struct scsi_cmnd *sp)
 {
     int sz = sp->use_sg - 1;
-    struct mmu_sglist *sg = (struct mmu_sglist *)sp->buffer;
+    struct scatterlist *sg = (struct scatterlist *)sp->buffer;
 			
     while(sz >= 0) {
-	vdma_free(sg[sz].dvma_addr);
+	vdma_free(sg[sz].dma_address);
 	sz--;
     }
 }
 
-static void dma_advance_sg (Scsi_Cmnd *sp)
+static void dma_advance_sg (struct scsi_cmnd *sp)
 {
-    sp->SCp.ptr = (char *)((unsigned long)sp->SCp.buffer->dvma_address);
+    sp->SCp.ptr = (char *)(sp->SCp.buffer->dma_address);
 }
 
 #define JAZZ_HDC_LED   0xe000d100 /* FIXME, find correct address */
@@ -285,9 +308,9 @@
 #endif    
 }
 
-static Scsi_Host_Template driver_template = {
+static struct scsi_host_template driver_template = {
 	.proc_name		= "jazz_esp",
-	.proc_info		= &esp_proc_info,
+	.proc_info		= esp_proc_info,
 	.name			= "ESP 100/100a/200",
 	.detect			= jazz_esp_detect,
 	.slave_alloc		= esp_slave_alloc,
@@ -303,4 +326,4 @@
 	.cmd_per_lun		= 1,
 	.use_clustering		= DISABLE_CLUSTERING,
 };
-
+#include "scsi_module.c"
diff -Nru a/drivers/scsi/lasi700.c b/drivers/scsi/lasi700.c
--- a/drivers/scsi/lasi700.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/scsi/lasi700.c	2005-03-01 23:38:52 -08:00
@@ -54,12 +54,32 @@
 #include <scsi/scsi_transport.h>
 #include <scsi/scsi_transport_spi.h>
 
-#include "lasi700.h"
 #include "53c700.h"
 
 MODULE_AUTHOR("James Bottomley");
 MODULE_DESCRIPTION("lasi700 SCSI Driver");
 MODULE_LICENSE("GPL");
+
+#define LASI_700_SVERSION 0x00071
+#define LASI_710_SVERSION 0x00082
+
+#define LASI700_ID_TABLE {			\
+	.hw_type	= HPHW_FIO,		\
+	.sversion	= LASI_700_SVERSION,	\
+	.hversion	= HVERSION_ANY_ID,	\
+	.hversion_rev	= HVERSION_REV_ANY_ID,	\
+}
+
+#define LASI710_ID_TABLE {			\
+	.hw_type	= HPHW_FIO,		\
+	.sversion	= LASI_710_SVERSION,	\
+	.hversion	= HVERSION_ANY_ID,	\
+	.hversion_rev	= HVERSION_REV_ANY_ID,	\
+}
+
+#define LASI700_CLOCK	25
+#define LASI710_CLOCK	40
+#define LASI_SCSI_CORE_OFFSET 0x100
 
 static struct parisc_device_id lasi700_ids[] = {
 	LASI700_ID_TABLE,
diff -Nru a/drivers/scsi/lasi700.h b/drivers/scsi/lasi700.h
--- a/drivers/scsi/lasi700.h	2005-03-01 23:39:18 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,49 +0,0 @@
-/* -*- mode: c; c-basic-offset: 8 -*- */
-
-/* PARISC LASI driver for the 53c700 chip
- *
- * Copyright (C) 2001 by James.Bottomley@HansenPartnership.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 _LASI700_H
-#define _LASI700_H
-
-#define LASI_710_SVERSION	0x082
-#define LASI_700_SVERSION	0x071
-
-#define LASI700_ID_TABLE {			\
-	.hw_type	= HPHW_FIO,		\
-	.sversion	= LASI_700_SVERSION,	\
-	.hversion	= HVERSION_ANY_ID,	\
-	.hversion_rev	= HVERSION_REV_ANY_ID,	\
-}
-
-#define LASI710_ID_TABLE {			\
-	.hw_type	= HPHW_FIO,		\
-	.sversion	= LASI_710_SVERSION,	\
-	.hversion	= HVERSION_ANY_ID,	\
-	.hversion_rev	= HVERSION_REV_ANY_ID,	\
-}
-
-#define LASI700_CLOCK	25
-#define LASI710_CLOCK	40
-#define LASI_SCSI_CORE_OFFSET 0x100
-
-#endif
diff -Nru a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
--- a/drivers/scsi/libata-core.c	2005-03-01 23:38:44 -08:00
+++ b/drivers/scsi/libata-core.c	2005-03-01 23:38:44 -08:00
@@ -28,6 +28,7 @@
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/list.h>
+#include <linux/mm.h>
 #include <linux/highmem.h>
 #include <linux/spinlock.h>
 #include <linux/blkdev.h>
@@ -376,7 +377,7 @@
 }
 
 /**
- *	ata_check_status - Read device status reg & clear interrupt
+ *	ata_check_status_pio - Read device status reg & clear interrupt
  *	@ap: port where the device is
  *
  *	Reads ATA taskfile status register for currently-selected device
@@ -414,6 +415,27 @@
 	return ata_check_status_pio(ap);
 }
 
+u8 ata_altstatus(struct ata_port *ap)
+{
+	if (ap->ops->check_altstatus)
+		return ap->ops->check_altstatus(ap);
+
+	if (ap->flags & ATA_FLAG_MMIO)
+		return readb((void __iomem *)ap->ioaddr.altstatus_addr);
+	return inb(ap->ioaddr.altstatus_addr);
+}
+
+u8 ata_chk_err(struct ata_port *ap)
+{
+	if (ap->ops->check_err)
+		return ap->ops->check_err(ap);
+
+	if (ap->flags & ATA_FLAG_MMIO) {
+		return readb((void __iomem *) ap->ioaddr.error_addr);
+	}
+	return inb(ap->ioaddr.error_addr);
+}
+
 /**
  *	ata_tf_to_fis - Convert ATA taskfile to SATA FIS structure
  *	@tf: Taskfile to convert
@@ -1160,7 +1182,6 @@
 	printk(KERN_WARNING "ata%u: dev %u not supported, ignoring\n",
 	       ap->id, device);
 err_out:
-	ata_irq_on(ap);	/* re-enable interrupts */
 	dev->class++;	/* converts ATA_DEV_xxx into ATA_DEV_xxx_UNSUP */
 	DPRINTK("EXIT, err\n");
 }
@@ -1668,7 +1689,8 @@
 		ata_dev_try_classify(ap, 1);
 
 	/* re-enable interrupts */
-	ata_irq_on(ap);
+	if (ap->ioaddr.ctl_addr)	/* FIXME: hack. create a hook instead */
+		ata_irq_on(ap);
 
 	/* is double-select really necessary? */
 	if (ap->device[1].class != ATA_DEV_NONE)
@@ -1699,6 +1721,69 @@
 	DPRINTK("EXIT\n");
 }
 
+static void ata_pr_blacklisted(struct ata_port *ap, struct ata_device *dev)
+{
+	printk(KERN_WARNING "ata%u: dev %u is on DMA blacklist, disabling DMA\n",
+		ap->id, dev->devno);
+}
+
+static const char * ata_dma_blacklist [] = {
+	"WDC AC11000H",
+	"WDC AC22100H",
+	"WDC AC32500H",
+	"WDC AC33100H",
+	"WDC AC31600H",
+	"WDC AC32100H",
+	"WDC AC23200L",
+	"Compaq CRD-8241B",
+	"CRD-8400B",
+	"CRD-8480B",
+	"CRD-8482B",
+ 	"CRD-84",
+	"SanDisk SDP3B",
+	"SanDisk SDP3B-64",
+	"SANYO CD-ROM CRD",
+	"HITACHI CDR-8",
+	"HITACHI CDR-8335",
+	"HITACHI CDR-8435",
+	"Toshiba CD-ROM XM-6202B",
+	"CD-532E-A",
+	"E-IDE CD-ROM CR-840",
+	"CD-ROM Drive/F5A",
+	"WPI CDD-820",
+	"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",
+};
+
+static int ata_dma_blacklisted(struct ata_port *ap, struct ata_device *dev)
+{
+	unsigned char model_num[40];
+	char *s;
+	unsigned int len;
+	int i;
+
+	ata_dev_id_string(dev->id, model_num, ATA_ID_PROD_OFS,
+			  sizeof(model_num));
+	s = &model_num[0];
+	len = strnlen(s, sizeof(model_num));
+
+	/* ATAPI specifies that empty space is blank-filled; remove blanks */
+	while ((len > 0) && (s[len - 1] == ' ')) {
+		len--;
+		s[len] = 0;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(ata_dma_blacklist); i++)
+		if (!strncmp(ata_dma_blacklist[i], s, len))
+			return 1;
+
+	return 0;
+}
+
 static unsigned int ata_get_mode_mask(struct ata_port *ap, int shift)
 {
 	struct ata_device *master, *slave;
@@ -1711,17 +1796,37 @@
 
 	if (shift == ATA_SHIFT_UDMA) {
 		mask = ap->udma_mask;
-		if (ata_dev_present(master))
+		if (ata_dev_present(master)) {
 			mask &= (master->id[ATA_ID_UDMA_MODES] & 0xff);
-		if (ata_dev_present(slave))
+			if (ata_dma_blacklisted(ap, master)) {
+				mask = 0;
+				ata_pr_blacklisted(ap, master);
+			}
+		}
+		if (ata_dev_present(slave)) {
 			mask &= (slave->id[ATA_ID_UDMA_MODES] & 0xff);
+			if (ata_dma_blacklisted(ap, slave)) {
+				mask = 0;
+				ata_pr_blacklisted(ap, slave);
+			}
+		}
 	}
 	else if (shift == ATA_SHIFT_MWDMA) {
 		mask = ap->mwdma_mask;
-		if (ata_dev_present(master))
+		if (ata_dev_present(master)) {
 			mask &= (master->id[ATA_ID_MWDMA_MODES] & 0x07);
-		if (ata_dev_present(slave))
+			if (ata_dma_blacklisted(ap, master)) {
+				mask = 0;
+				ata_pr_blacklisted(ap, master);
+			}
+		}
+		if (ata_dev_present(slave)) {
 			mask &= (slave->id[ATA_ID_MWDMA_MODES] & 0x07);
+			if (ata_dma_blacklisted(ap, slave)) {
+				mask = 0;
+				ata_pr_blacklisted(ap, slave);
+			}
+		}
 	}
 	else if (shift == ATA_SHIFT_PIO) {
 		mask = ap->pio_mask;
@@ -1919,7 +2024,24 @@
 	if (idx)
 		ap->prd[idx - 1].flags_len |= cpu_to_le32(ATA_PRD_EOT);
 }
+/**
+ *	ata_check_atapi_dma - Check whether ATAPI DMA can be supported
+ *	@qc: Metadata associated with taskfile to check
+ *
+ *	LOCKING:
+ *	RETURNS: 0 when ATAPI DMA can be used
+ *               nonzero otherwise
+ */
+int ata_check_atapi_dma(struct ata_queued_cmd *qc)
+{
+	struct ata_port *ap = qc->ap;
+	int rc = 0; /* Assume ATAPI DMA is OK by default */
+
+	if (ap->ops->check_atapi_dma)
+		rc = ap->ops->check_atapi_dma(qc);
 
+	return rc;
+}
 /**
  *	ata_qc_prep - Prepare taskfile for submission
  *	@qc: Metadata associated with taskfile to be prepared
@@ -2369,6 +2491,9 @@
 	unsigned long timeout = 0;
 
 	switch (ap->pio_task_state) {
+	case PIO_ST_IDLE:
+		return;
+
 	case PIO_ST:
 		ata_pio_block(ap);
 		break;
@@ -2385,18 +2510,14 @@
 	case PIO_ST_TMOUT:
 	case PIO_ST_ERR:
 		ata_pio_error(ap);
-		break;
+		return;
 	}
 
-	if ((ap->pio_task_state != PIO_ST_IDLE) &&
-	    (ap->pio_task_state != PIO_ST_TMOUT) &&
-	    (ap->pio_task_state != PIO_ST_ERR)) {
-		if (timeout)
-			queue_delayed_work(ata_wq, &ap->pio_task,
-					   timeout);
-		else
-			queue_work(ata_wq, &ap->pio_task);
-	}
+	if (timeout)
+		queue_delayed_work(ata_wq, &ap->pio_task,
+				   timeout);
+	else
+		queue_work(ata_wq, &ap->pio_task);
 }
 
 static void atapi_request_sense(struct ata_port *ap, struct ata_device *dev,
@@ -2405,7 +2526,6 @@
 	DECLARE_COMPLETION(wait);
 	struct ata_queued_cmd *qc;
 	unsigned long flags;
-	int using_pio = dev->flags & ATA_DFLAG_PIO;
 	int rc;
 
 	DPRINTK("ATAPI request sense\n");
@@ -2426,16 +2546,10 @@
 	qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
 	qc->tf.command = ATA_CMD_PACKET;
 
-	if (using_pio) {
-		qc->tf.protocol = ATA_PROT_ATAPI;
-		qc->tf.lbam = (8 * 1024) & 0xff;
-		qc->tf.lbah = (8 * 1024) >> 8;
-
-		qc->nbytes = SCSI_SENSE_BUFFERSIZE;
-	} else {
-		qc->tf.protocol = ATA_PROT_ATAPI_DMA;
-		qc->tf.feature |= ATAPI_PKT_DMA;
-	}
+	qc->tf.protocol = ATA_PROT_ATAPI;
+	qc->tf.lbam = (8 * 1024) & 0xff;
+	qc->tf.lbah = (8 * 1024) >> 8;
+	qc->nbytes = SCSI_SENSE_BUFFERSIZE;
 
 	qc->waiting = &wait;
 	qc->complete_fn = ata_qc_complete_noop;
@@ -2508,10 +2622,10 @@
 
 	case ATA_PROT_DMA:
 	case ATA_PROT_ATAPI_DMA:
-		host_stat = ata_bmdma_status(ap);
+		host_stat = ap->ops->bmdma_status(ap);
 
 		/* before we do anything else, clear DMA-Start bit */
-		ata_bmdma_stop(ap);
+		ap->ops->bmdma_stop(ap);
 
 		/* fall through */
 
@@ -2520,7 +2634,7 @@
 		drv_stat = ata_chk_status(ap);
 
 		/* ack bmdma irq events */
-		ata_bmdma_ack_irq(ap);
+		ap->ops->irq_clear(ap);
 
 		printk(KERN_ERR "ata%u: command 0x%x timeout, stat 0x%x host_stat 0x%x\n",
 		       ap->id, qc->tf.command, drv_stat, host_stat);
@@ -2659,6 +2773,24 @@
 }
 
 /**
+ *	ata_qc_free - free unused ata_queued_cmd
+ *	@qc: Command to complete
+ *
+ *	Designed to free unused ata_queued_cmd object
+ *	in case something prevents using it.
+ *
+ *	LOCKING:
+ *
+ */
+void ata_qc_free(struct ata_queued_cmd *qc)
+{
+	assert(qc != NULL);	/* ata_qc_from_tag _might_ return NULL */
+	assert(qc->waiting == NULL);	/* nothing should be waiting */
+
+	__ata_qc_complete(qc);
+}
+
+/**
  *	ata_qc_complete - Complete an active ATA command
  *	@qc: Command to complete
  *	@drv_stat: ATA status register contents
@@ -2707,7 +2839,7 @@
 			return 1;
 
 		/* fall through */
-	
+
 	default:
 		return 0;
 	}
@@ -2949,7 +3081,43 @@
 
 void ata_bmdma_irq_clear(struct ata_port *ap)
 {
-	ata_bmdma_ack_irq(ap);
+    if (ap->flags & ATA_FLAG_MMIO) {
+        void __iomem *mmio = ((void __iomem *) ap->ioaddr.bmdma_addr) + ATA_DMA_STATUS;
+        writeb(readb(mmio), mmio);
+    } else {
+        unsigned long addr = ap->ioaddr.bmdma_addr + ATA_DMA_STATUS;
+        outb(inb(addr), addr);
+    }
+
+}
+
+u8 ata_bmdma_status(struct ata_port *ap)
+{
+	u8 host_stat;
+	if (ap->flags & ATA_FLAG_MMIO) {
+		void __iomem *mmio = (void __iomem *) ap->ioaddr.bmdma_addr;
+		host_stat = readb(mmio + ATA_DMA_STATUS);
+	} else
+	host_stat = inb(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
+	return host_stat;
+}
+
+void ata_bmdma_stop(struct ata_port *ap)
+{
+	if (ap->flags & ATA_FLAG_MMIO) {
+		void __iomem *mmio = (void __iomem *) ap->ioaddr.bmdma_addr;
+
+		/* clear start/stop bit */
+		writeb(readb(mmio + ATA_DMA_CMD) & ~ATA_DMA_START,
+			mmio + ATA_DMA_CMD);
+	} else {
+		/* clear start/stop bit */
+		outb(inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD) & ~ATA_DMA_START,
+			ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
+	}
+
+	/* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */
+	ata_altstatus(ap);        /* dummy read */
 }
 
 /**
@@ -2979,7 +3147,7 @@
 	case ATA_PROT_ATAPI_DMA:
 	case ATA_PROT_ATAPI:
 		/* check status of DMA engine */
-		host_stat = ata_bmdma_status(ap);
+		host_stat = ap->ops->bmdma_status(ap);
 		VPRINTK("ata%u: host_stat 0x%X\n", ap->id, host_stat);
 
 		/* if it's not our irq... */
@@ -2987,7 +3155,7 @@
 			goto idle_irq;
 
 		/* before we do anything else, clear DMA-Start bit */
-		ata_bmdma_stop(ap);
+		ap->ops->bmdma_stop(ap);
 
 		/* fall through */
 
@@ -3006,7 +3174,7 @@
 			ap->id, qc->tf.protocol, status);
 
 		/* ack bmdma irq events */
-		ata_bmdma_ack_irq(ap);
+		ap->ops->irq_clear(ap);
 
 		/* complete taskfile transaction */
 		ata_qc_complete(qc, status);
@@ -3442,32 +3610,28 @@
 }
 
 static struct ata_probe_ent *
-ata_probe_ent_alloc(int n, struct device *dev, struct ata_port_info **port)
+ata_probe_ent_alloc(struct device *dev, struct ata_port_info *port)
 {
 	struct ata_probe_ent *probe_ent;
-	int i;
 
-	probe_ent = kmalloc(sizeof(*probe_ent) * n, GFP_KERNEL);
+	probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL);
 	if (!probe_ent) {
 		printk(KERN_ERR DRV_NAME "(%s): out of memory\n",
 		       kobject_name(&(dev->kobj)));
 		return NULL;
 	}
 
-	memset(probe_ent, 0, sizeof(*probe_ent) * n);
+	memset(probe_ent, 0, sizeof(*probe_ent));
 
-	for (i = 0; i < n; i++) {
-		INIT_LIST_HEAD(&probe_ent[i].node);
-		probe_ent[i].dev = dev;
-
-		probe_ent[i].sht = port[i]->sht;
-		probe_ent[i].host_flags = port[i]->host_flags;
-		probe_ent[i].pio_mask = port[i]->pio_mask;
-		probe_ent[i].mwdma_mask = port[i]->mwdma_mask;
-		probe_ent[i].udma_mask = port[i]->udma_mask;
-		probe_ent[i].port_ops = port[i]->port_ops;
+	INIT_LIST_HEAD(&probe_ent->node);
+	probe_ent->dev = dev;
 
-	}
+	probe_ent->sht = port->sht;
+	probe_ent->host_flags = port->host_flags;
+	probe_ent->pio_mask = port->pio_mask;
+	probe_ent->mwdma_mask = port->mwdma_mask;
+	probe_ent->udma_mask = port->udma_mask;
+	probe_ent->port_ops = port->port_ops;
 
 	return probe_ent;
 }
@@ -3477,7 +3641,7 @@
 ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port)
 {
 	struct ata_probe_ent *probe_ent =
-		ata_probe_ent_alloc(1, pci_dev_to_dev(pdev), port);
+		ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[0]);
 	if (!probe_ent)
 		return NULL;
 
@@ -3503,39 +3667,47 @@
 	return probe_ent;
 }
 
-struct ata_probe_ent *
-ata_pci_init_legacy_mode(struct pci_dev *pdev, struct ata_port_info **port)
+static struct ata_probe_ent *
+ata_pci_init_legacy_mode(struct pci_dev *pdev, struct ata_port_info **port,
+    struct ata_probe_ent **ppe2)
 {
-	struct ata_probe_ent *probe_ent =
-		ata_probe_ent_alloc(2, pci_dev_to_dev(pdev), port);
+	struct ata_probe_ent *probe_ent, *probe_ent2;
+
+	probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[0]);
 	if (!probe_ent)
 		return NULL;
+	probe_ent2 = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[1]);
+	if (!probe_ent2) {
+		kfree(probe_ent);
+		return NULL;
+	}
 
-	probe_ent[0].n_ports = 1;
-	probe_ent[0].irq = 14;
+	probe_ent->n_ports = 1;
+	probe_ent->irq = 14;
 
-	probe_ent[0].hard_port_no = 0;
-	probe_ent[0].legacy_mode = 1;
+	probe_ent->hard_port_no = 0;
+	probe_ent->legacy_mode = 1;
 
-	probe_ent[1].n_ports = 1;
-	probe_ent[1].irq = 15;
+	probe_ent2->n_ports = 1;
+	probe_ent2->irq = 15;
 
-	probe_ent[1].hard_port_no = 1;
-	probe_ent[1].legacy_mode = 1;
-
-	probe_ent[0].port[0].cmd_addr = 0x1f0;
-	probe_ent[0].port[0].altstatus_addr =
-	probe_ent[0].port[0].ctl_addr = 0x3f6;
-	probe_ent[0].port[0].bmdma_addr = pci_resource_start(pdev, 4);
-
-	probe_ent[1].port[0].cmd_addr = 0x170;
-	probe_ent[1].port[0].altstatus_addr =
-	probe_ent[1].port[0].ctl_addr = 0x376;
-	probe_ent[1].port[0].bmdma_addr = pci_resource_start(pdev, 4)+8;
+	probe_ent2->hard_port_no = 1;
+	probe_ent2->legacy_mode = 1;
 
-	ata_std_ports(&probe_ent[0].port[0]);
-	ata_std_ports(&probe_ent[1].port[0]);
+	probe_ent->port[0].cmd_addr = 0x1f0;
+	probe_ent->port[0].altstatus_addr =
+	probe_ent->port[0].ctl_addr = 0x3f6;
+	probe_ent->port[0].bmdma_addr = pci_resource_start(pdev, 4);
+
+	probe_ent2->port[0].cmd_addr = 0x170;
+	probe_ent2->port[0].altstatus_addr =
+	probe_ent2->port[0].ctl_addr = 0x376;
+	probe_ent2->port[0].bmdma_addr = pci_resource_start(pdev, 4)+8;
+
+	ata_std_ports(&probe_ent->port[0]);
+	ata_std_ports(&probe_ent2->port[0]);
 
+	*ppe2 = probe_ent2;
 	return probe_ent;
 }
 
@@ -3559,6 +3731,7 @@
 	struct ata_port_info *port[2];
 	u8 tmp8, mask;
 	unsigned int legacy_mode = 0;
+	int disable_dev_on_err = 1;
 	int rc;
 
 	DPRINTK("ENTER\n");
@@ -3569,7 +3742,8 @@
 	else
 		port[1] = port[0];
 
-	if ((port[0]->host_flags & ATA_FLAG_NO_LEGACY) == 0) {
+	if ((port[0]->host_flags & ATA_FLAG_NO_LEGACY) == 0
+	    && (pdev->class >> 8) == PCI_CLASS_STORAGE_IDE) {
 		/* TODO: support transitioning to native mode? */
 		pci_read_config_byte(pdev, PCI_CLASS_PROG, &tmp8);
 		mask = (1 << 2) | (1 << 0);
@@ -3588,8 +3762,10 @@
 		return rc;
 
 	rc = pci_request_regions(pdev, DRV_NAME);
-	if (rc)
+	if (rc) {
+		disable_dev_on_err = 0;
 		goto err_out;
+	}
 
 	if (legacy_mode) {
 		if (!request_region(0x1f0, 8, "libata")) {
@@ -3599,8 +3775,10 @@
 			conflict = ____request_resource(&ioport_resource, &res);
 			if (!strcmp(conflict->name, "libata"))
 				legacy_mode |= (1 << 0);
-			else
+			else {
+				disable_dev_on_err = 0;
 				printk(KERN_WARNING "ata: 0x1f0 IDE port busy\n");
+			}
 		} else
 			legacy_mode |= (1 << 0);
 
@@ -3611,8 +3789,10 @@
 			conflict = ____request_resource(&ioport_resource, &res);
 			if (!strcmp(conflict->name, "libata"))
 				legacy_mode |= (1 << 1);
-			else
+			else {
+				disable_dev_on_err = 0;
 				printk(KERN_WARNING "ata: 0x170 IDE port busy\n");
+			}
 		} else
 			legacy_mode |= (1 << 1);
 	}
@@ -3631,9 +3811,7 @@
 		goto err_out_regions;
 
 	if (legacy_mode) {
-		probe_ent = ata_pci_init_legacy_mode(pdev, port);
-		if (probe_ent)
-			probe_ent2 = &probe_ent[1];
+		probe_ent = ata_pci_init_legacy_mode(pdev, port, &probe_ent2);
 	} else
 		probe_ent = ata_pci_init_native_mode(pdev, port);
 	if (!probe_ent) {
@@ -3649,10 +3827,11 @@
 			ata_device_add(probe_ent);
 		if (legacy_mode & (1 << 1))
 			ata_device_add(probe_ent2);
-	} else {
+	} else
 		ata_device_add(probe_ent);
-	}
+
 	kfree(probe_ent);
+	kfree(probe_ent2);
 
 	return 0;
 
@@ -3663,7 +3842,8 @@
 		release_region(0x170, 8);
 	pci_release_regions(pdev);
 err_out:
-	pci_disable_device(pdev);
+	if (disable_dev_on_err)
+		pci_disable_device(pdev);
 	return rc;
 }
 
@@ -3813,6 +3993,8 @@
 EXPORT_SYMBOL_GPL(ata_tf_to_fis);
 EXPORT_SYMBOL_GPL(ata_tf_from_fis);
 EXPORT_SYMBOL_GPL(ata_check_status);
+EXPORT_SYMBOL_GPL(ata_altstatus);
+EXPORT_SYMBOL_GPL(ata_chk_err);
 EXPORT_SYMBOL_GPL(ata_exec_command);
 EXPORT_SYMBOL_GPL(ata_port_start);
 EXPORT_SYMBOL_GPL(ata_port_stop);
@@ -3821,6 +4003,8 @@
 EXPORT_SYMBOL_GPL(ata_bmdma_setup);
 EXPORT_SYMBOL_GPL(ata_bmdma_start);
 EXPORT_SYMBOL_GPL(ata_bmdma_irq_clear);
+EXPORT_SYMBOL_GPL(ata_bmdma_status);
+EXPORT_SYMBOL_GPL(ata_bmdma_stop);
 EXPORT_SYMBOL_GPL(ata_port_probe);
 EXPORT_SYMBOL_GPL(sata_phy_reset);
 EXPORT_SYMBOL_GPL(__sata_phy_reset);
@@ -3838,7 +4022,6 @@
 
 #ifdef CONFIG_PCI
 EXPORT_SYMBOL_GPL(pci_test_config_bits);
-EXPORT_SYMBOL_GPL(ata_pci_init_legacy_mode);
 EXPORT_SYMBOL_GPL(ata_pci_init_native_mode);
 EXPORT_SYMBOL_GPL(ata_pci_init_one);
 EXPORT_SYMBOL_GPL(ata_pci_remove_one);
diff -Nru a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c
--- a/drivers/scsi/libata-scsi.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/scsi/libata-scsi.c	2005-03-01 23:38:56 -08:00
@@ -202,7 +202,7 @@
 		{0x40, 		MEDIUM_ERROR, 0x11, 0x04}, 	// Uncorrectable ECC error      Unrecovered read error
 		/* BBD - block marked bad */
 		{0x80, 		MEDIUM_ERROR, 0x11, 0x04}, 	// Block marked bad		  Medium error, unrecovered read error
-		{0xFF, 0xFF, 0xFF, 0xFF}, // END mark 
+		{0xFF, 0xFF, 0xFF, 0xFF}, // END mark
 	};
 	static unsigned char stat_table[][4] = {
 		/* Must be first because BUSY means no other bits valid */
@@ -210,22 +210,22 @@
 		{0x20, 		HARDWARE_ERROR,  0x00, 0x00}, 	// Device fault
 		{0x08, 		ABORTED_COMMAND, 0x47, 0x00},	// Timed out in xfer, fake parity for now
 		{0x04, 		RECOVERED_ERROR, 0x11, 0x00},	// Recovered ECC error	  Medium error, recovered
-		{0xFF, 0xFF, 0xFF, 0xFF}, // END mark 
+		{0xFF, 0xFF, 0xFF, 0xFF}, // END mark
 	};
 	int i = 0;
 
 	cmd->result = SAM_STAT_CHECK_CONDITION;
-	
+
 	/*
 	 *	Is this an error we can process/parse
 	 */
-	 
+
 	if(drv_stat & ATA_ERR)
 		/* Read the err bits */
 		err = ata_chk_err(qc->ap);
 
 	/* Display the ATA level error info */
-	
+
 	printk(KERN_WARNING "ata%u: status=0x%02x { ", qc->ap->id, drv_stat);
 	if(drv_stat & 0x80)
 	{
@@ -242,7 +242,7 @@
 		if(drv_stat & 0x01)	printk("Error ");
 	}
 	printk("}\n");
-	
+
 	if(err)
 	{
 		printk(KERN_WARNING "ata%u: error=0x%02x { ", qc->ap->id, err);
@@ -259,11 +259,11 @@
 		if(err & 0x02)		printk("TrackZeroNotFound ");
 		if(err & 0x01)		printk("AddrMarkNotFound ");
 		printk("}\n");
-		
+
 		/* Should we dump sector info here too ?? */
 	}
-		
-	
+
+
 	/* Look for err */
 	while(sense_table[i][0] != 0xFF)
 	{
@@ -282,7 +282,8 @@
 	/* No immediate match */
 	if(err)
 		printk(KERN_DEBUG "ata%u: no sense translation for 0x%02x\n", qc->ap->id, err);
-	
+
+	i = 0;
 	/* Fall back to interpreting status bits */
 	while(stat_table[i][0] != 0xFF)
 	{
@@ -300,7 +301,7 @@
 	/* No error ?? */
 	printk(KERN_ERR "ata%u: called with no error (%02X)!\n", qc->ap->id, drv_stat);
 	/* additional-sense-code[-qualifier] */
-	
+
 	sb[0] = 0x70;
 	sb[2] = MEDIUM_ERROR;
 	sb[7] = 0x0A;
@@ -487,19 +488,24 @@
 	}
 
 	if (lba48) {
+		tf->command = ATA_CMD_VERIFY_EXT;
+
 		tf->hob_nsect = (n_sect >> 8) & 0xff;
 
 		tf->hob_lbah = (sect >> 40) & 0xff;
 		tf->hob_lbam = (sect >> 32) & 0xff;
 		tf->hob_lbal = (sect >> 24) & 0xff;
-	} else
+	} else {
+		tf->command = ATA_CMD_VERIFY;
+
 		tf->device |= (sect >> 24) & 0xf;
+	}
 
 	tf->nsect = n_sect & 0xff;
 
-	tf->hob_lbah = (sect >> 16) & 0xff;
-	tf->hob_lbam = (sect >> 8) & 0xff;
-	tf->hob_lbal = sect & 0xff;
+	tf->lbah = (sect >> 16) & 0xff;
+	tf->lbam = (sect >> 8) & 0xff;
+	tf->lbal = sect & 0xff;
 
 	return 0;
 }
@@ -599,7 +605,7 @@
 				return 1;
 
 			/* stores LBA27:24 in lower 4 bits of device reg */
-			tf->device |= scsicmd[2];
+			tf->device |= scsicmd[6];
 
 			qc->nsect = scsicmd[13];
 		}
@@ -695,6 +701,7 @@
 	return;
 
 err_out:
+	ata_qc_free(qc);
 	ata_bad_cdb(cmd, done);
 	DPRINTK("EXIT - badcmd\n");
 }
@@ -1293,6 +1300,11 @@
 	struct ata_device *dev = qc->dev;
 	int using_pio = (dev->flags & ATA_DFLAG_PIO);
 	int nodata = (cmd->sc_data_direction == SCSI_DATA_NONE);
+
+	if (!using_pio)
+		/* Check whether ATAPI DMA is safe */
+		if (ata_check_atapi_dma(qc))
+			using_pio = 1;
 
 	memcpy(&qc->cdb, scsicmd, qc->ap->cdb_len);
 
diff -Nru a/drivers/scsi/libata.h b/drivers/scsi/libata.h
--- a/drivers/scsi/libata.h	2005-03-01 23:38:53 -08:00
+++ b/drivers/scsi/libata.h	2005-03-01 23:38:53 -08:00
@@ -37,7 +37,9 @@
 /* libata-core.c */
 extern struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap,
 				      struct ata_device *dev);
+extern void ata_qc_free(struct ata_queued_cmd *qc);
 extern int ata_qc_issue(struct ata_queued_cmd *qc);
+extern int ata_check_atapi_dma(struct ata_queued_cmd *qc);
 extern void ata_dev_select(struct ata_port *ap, unsigned int device,
                            unsigned int wait, unsigned int can_sleep);
 extern void ata_tf_to_host_nolock(struct ata_port *ap, struct ata_taskfile *tf);
diff -Nru a/drivers/scsi/mca_53c9x.c b/drivers/scsi/mca_53c9x.c
--- a/drivers/scsi/mca_53c9x.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/scsi/mca_53c9x.c	2005-03-01 23:38:54 -08:00
@@ -103,7 +103,7 @@
 static struct ESP_regs eregs;
 
 /***************************************************************** Detection */
-int mca_esp_detect(Scsi_Host_Template *tpnt)
+static int mca_esp_detect(Scsi_Host_Template *tpnt)
 {
 	struct NCR_ESP *esp;
 	static int io_port_by_pos[] = MCA_53C9X_IO_PORTS;
@@ -283,7 +283,7 @@
 
 /******************************************************************* Release */
 
-int mca_esp_release(struct Scsi_Host *host)
+static int mca_esp_release(struct Scsi_Host *host)
 {
 	struct NCR_ESP *esp = (struct NCR_ESP *)host->hostdata;
 	unsigned char tmp_byte;
diff -Nru a/drivers/scsi/megaraid/Kconfig.megaraid b/drivers/scsi/megaraid/Kconfig.megaraid
--- a/drivers/scsi/megaraid/Kconfig.megaraid	2005-03-01 23:38:53 -08:00
+++ b/drivers/scsi/megaraid/Kconfig.megaraid	2005-03-01 23:38:53 -08:00
@@ -59,6 +59,7 @@
 	INTEL RAID Controller SRCU51L	1000:1960:8086:0520
 	FSC MegaRAID PCI Express ROMB	1000:0408:1734:1065
 	ACER MegaRAID ROMB-2E		1000:0408:1025:004D
+	NEC MegaRAID PCI Express ROMB	1000:0408:1033:8287
 
 	To compile this driver as a module, choose M here: the
 	module will be called megaraid_mbox
diff -Nru a/drivers/scsi/megaraid/mega_common.h b/drivers/scsi/megaraid/mega_common.h
--- a/drivers/scsi/megaraid/mega_common.h	2005-03-01 23:38:58 -08:00
+++ b/drivers/scsi/megaraid/mega_common.h	2005-03-01 23:38:58 -08:00
@@ -221,6 +221,9 @@
 #define MRAID_IS_LOGICAL(adp, scp)	\
 	(SCP2CHANNEL(scp) == (adp)->max_channel) ? 1 : 0
 
+#define MRAID_IS_LOGICAL_SDEV(adp, sdev)	\
+	(sdev->channel == (adp)->max_channel) ? 1 : 0
+
 #define MRAID_GET_DEVICE_MAP(adp, scp, p_chan, target, islogical)	\
 	/*								\
 	 * Is the request coming for the virtual channel		\
diff -Nru a/drivers/scsi/megaraid/megaraid_ioctl.h b/drivers/scsi/megaraid/megaraid_ioctl.h
--- a/drivers/scsi/megaraid/megaraid_ioctl.h	2005-03-01 23:38:54 -08:00
+++ b/drivers/scsi/megaraid/megaraid_ioctl.h	2005-03-01 23:38:54 -08:00
@@ -291,5 +291,6 @@
 
 int mraid_mm_register_adp(mraid_mmadp_t *);
 int mraid_mm_unregister_adp(uint32_t);
+uint32_t mraid_mm_adapter_app_handle(uint32_t);
 
 #endif /* _MEGARAID_IOCTL_H_ */
diff -Nru a/drivers/scsi/megaraid/megaraid_mbox.c b/drivers/scsi/megaraid/megaraid_mbox.c
--- a/drivers/scsi/megaraid/megaraid_mbox.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/scsi/megaraid/megaraid_mbox.c	2005-03-01 23:38:55 -08:00
@@ -10,7 +10,7 @@
  *	   2 of the License, or (at your option) any later version.
  *
  * FILE		: megaraid_mbox.c
- * Version	: v2.20.4.1 (Nov 04 2004)
+ * Version	: v2.20.4.5 (Feb 03 2005)
  *
  * Authors:
  * 	Atul Mukker		<Atul.Mukker@lsil.com>
@@ -60,12 +60,11 @@
  * INTEL RAID Controller SROMBU42E	1000	0408	8086	3499
  * INTEL RAID Controller SRCU51L	1000	1960	8086	0520
  *
- *
  * FSC	MegaRAID PCI Express ROMB	1000	0408	1734	1065
  *
- *
  * ACER	MegaRAID ROMB-2E		1000	0408	1025	004D
  *
+ * NEC	MegaRAID PCI Express ROMB	1000	0408	1033	8287
  *
  * For history of changes, see Documentation/ChangeLog.megaraid
  */
@@ -91,6 +90,9 @@
 static int megaraid_mbox_setup_dma_pools(adapter_t *);
 static void megaraid_mbox_teardown_dma_pools(adapter_t *);
 
+static int megaraid_sysfs_alloc_resources(adapter_t *);
+static void megaraid_sysfs_free_resources(adapter_t *);
+
 static int megaraid_abort_handler(struct scsi_cmnd *);
 static int megaraid_reset_handler(struct scsi_cmnd *);
 
@@ -121,6 +123,9 @@
 
 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 int megaraid_cmm_register(adapter_t *);
 static int megaraid_cmm_unregister(adapter_t *);
 static int megaraid_mbox_mm_handler(unsigned long, uioc_t *, uint32_t);
@@ -197,7 +202,7 @@
  * ### global data ###
  */
 static uint8_t megaraid_mbox_version[8] =
-	{ 0x02, 0x20, 0x04, 0x00, 9, 27, 20, 4 };
+	{ 0x02, 0x20, 0x04, 0x05, 2, 3, 20, 5 };
 
 
 /*
@@ -301,6 +306,12 @@
 		PCI_SUBSYS_ID_PERC3_SC,
 	},
 	{
+		PCI_VENDOR_ID_AMI,
+		PCI_DEVICE_ID_AMI_MEGARAID3,
+		PCI_VENDOR_ID_AMI,
+		PCI_SUBSYS_ID_PERC3_DC,
+	},
+	{
 		PCI_VENDOR_ID_LSI_LOGIC,
 		PCI_DEVICE_ID_MEGARAID_SCSI_320_0,
 		PCI_VENDOR_ID_LSI_LOGIC,
@@ -438,6 +449,12 @@
 		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);
@@ -454,6 +471,29 @@
 };
 
 
+
+// definitions for the device attributes for exporting logical drive number
+// for a scsi address (Host, Channel, Id, Lun)
+
+CLASS_DEVICE_ATTR(megaraid_mbox_app_hndl, S_IRUSR, megaraid_sysfs_show_app_hndl,
+		NULL);
+
+// Host template initializer for megaraid mbox sysfs device attributes
+static struct class_device_attribute *megaraid_shost_attrs[] = {
+	&class_device_attr_megaraid_mbox_app_hndl,
+	NULL,
+};
+
+
+DEVICE_ATTR(megaraid_mbox_ld, S_IRUSR, megaraid_sysfs_show_ldnum, NULL);
+
+// Host template initializer for megaraid mbox sysfs device attributes
+static struct device_attribute *megaraid_sdev_attrs[] = {
+	&dev_attr_megaraid_mbox_ld,
+	NULL,
+};
+
+
 /*
  * Scsi host template for megaraid unified driver
  */
@@ -467,6 +507,8 @@
 	.eh_bus_reset_handler		= megaraid_reset_handler,
 	.eh_host_reset_handler		= megaraid_reset_handler,
 	.use_clustering			= ENABLE_CLUSTERING,
+	.sdev_attrs			= megaraid_sdev_attrs,
+	.shost_attrs			= megaraid_shost_attrs,
 };
 
 
@@ -953,6 +995,8 @@
 		}
 		adapter->device_ids[adapter->max_channel][adapter->init_id] =
 			0xFF;
+
+		raid_dev->random_del_supported = 1;
 	}
 
 	/*
@@ -977,6 +1021,14 @@
 	 */
 	adapter->cmd_per_lun = megaraid_cmd_per_lun;
 
+	/*
+	 * Allocate resources required to issue FW calls, when sysfs is
+	 * accessed
+	 */
+	if (megaraid_sysfs_alloc_resources(adapter) != 0) {
+		goto out_alloc_cmds;
+	}
+
 	// 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) {
@@ -984,7 +1036,7 @@
 		con_log(CL_ANN, (KERN_WARNING
 			"megaraid: could not set DMA mask for 64-bit.\n"));
 
-		goto out_alloc_cmds;
+		goto out_free_sysfs_res;
 	}
 
 	// setup tasklet for DPC
@@ -996,6 +1048,8 @@
 
 	return 0;
 
+out_free_sysfs_res:
+	megaraid_sysfs_free_resources(adapter);
 out_alloc_cmds:
 	megaraid_free_cmd_packets(adapter);
 out_free_irq:
@@ -1025,6 +1079,8 @@
 
 	tasklet_kill(&adapter->dpc_h);
 
+	megaraid_sysfs_free_resources(adapter);
+
 	megaraid_free_cmd_packets(adapter);
 
 	free_irq(adapter->irq, adapter);
@@ -1559,12 +1615,14 @@
 
 	if (scb->dma_direction == PCI_DMA_TODEVICE) {
 		if (!scb->scp->use_sg) {	// sg list not used
-			pci_dma_sync_single_for_device(adapter->pdev, ccb->buf_dma_h,
+			pci_dma_sync_single_for_device(adapter->pdev,
+					ccb->buf_dma_h,
 					scb->scp->request_bufflen,
 					PCI_DMA_TODEVICE);
 		}
 		else {
-			pci_dma_sync_sg_for_device(adapter->pdev, scb->scp->request_buffer,
+			pci_dma_sync_sg_for_device(adapter->pdev,
+				scb->scp->request_buffer,
 				scb->scp->use_sg, PCI_DMA_TODEVICE);
 		}
 	}
@@ -1600,7 +1658,7 @@
 	scp->scsi_done	= done;
 	scp->result	= 0;
 
-	ASSERT(spin_is_locked(adapter->host_lock));
+	assert_spin_locked(adapter->host_lock);
 
 	spin_unlock(adapter->host_lock);
 
@@ -2043,7 +2101,7 @@
 
 	while (!list_empty(&adapter->pend_list)) {
 
-		ASSERT(spin_is_locked(PENDING_LIST_LOCK(adapter)));
+		assert_spin_locked(PENDING_LIST_LOCK(adapter));
 
 		scb = list_entry(adapter->pend_list.next, scb_t, list);
 
@@ -2107,7 +2165,8 @@
 	channel	= scb->dev_channel;
 	target	= scb->dev_target;
 
-	pthru->timeout		= 1;	// 0=6sec, 1=60sec, 2=10min, 3=3hrs
+	// 0=6sec, 1=60sec, 2=10min, 3=3hrs, 4=NO timeout
+	pthru->timeout		= 4;	
 	pthru->ars		= 1;
 	pthru->islogical	= 0;
 	pthru->channel		= 0;
@@ -2155,7 +2214,8 @@
 	channel	= scb->dev_channel;
 	target	= scb->dev_target;
 
-	epthru->timeout		= 1;	// 0=6sec, 1=60sec, 2=10min, 3=3hrs
+	// 0=6sec, 1=60sec, 2=10min, 3=3hrs, 4=NO timeout
+	epthru->timeout		= 4;	
 	epthru->ars		= 1;
 	epthru->islogical	= 0;
 	epthru->channel		= 0;
@@ -2615,7 +2675,7 @@
 	adapter		= SCP2ADAPTER(scp);
 	raid_dev	= ADAP2RAIDDEV(adapter);
 
-	ASSERT(spin_is_locked(adapter->host_lock));
+	assert_spin_locked(adapter->host_lock);
 
 	con_log(CL_ANN, (KERN_WARNING
 		"megaraid: aborting-%ld cmd=%x <c=%d t=%d l=%d>\n",
@@ -2762,7 +2822,7 @@
 	adapter		= SCP2ADAPTER(scp);
 	raid_dev	= ADAP2RAIDDEV(adapter);
 
-	ASSERT(spin_is_locked(adapter->host_lock));
+	assert_spin_locked(adapter->host_lock);
 
 	con_log(CL_ANN, (KERN_WARNING "megaraid: reseting the host...\n"));
 
@@ -3306,7 +3366,7 @@
 	memset((caddr_t)raw_mbox, 0, sizeof(mbox_t));
 
 	raw_mbox[0] = FC_DEL_LOGDRV;
-	raw_mbox[0] = OP_SUP_DEL_LOGDRV;
+	raw_mbox[2] = OP_SUP_DEL_LOGDRV;
 
 	// Issue the command
 	rval = 0;
@@ -3719,8 +3779,9 @@
 
 	spin_unlock_irqrestore(USER_FREE_LIST_LOCK(adapter), flags);
 
-	scb->state	= SCB_ACTIVE;
-	scb->dma_type	= MRAID_DMA_NONE;
+	scb->state		= SCB_ACTIVE;
+	scb->dma_type		= MRAID_DMA_NONE;
+	scb->dma_direction	= PCI_DMA_NONE;
 
 	ccb		= (mbox_ccb_t *)scb->ccb;
 	mbox64		= (mbox64_t *)(unsigned long)kioc->cmdbuf;
@@ -3886,6 +3947,324 @@
 /*
  * END: Interface for the common management module
  */
+
+
+
+/**
+ * megaraid_sysfs_alloc_resources - allocate sysfs related resources
+ *
+ * Allocate packets required to issue FW calls whenever the sysfs attributes
+ * are read. These attributes would require up-to-date information from the
+ * FW. Also set up resources for mutual exclusion to share these resources and
+ * the wait queue.
+ *
+ * @param adapter : controller's soft state
+ *
+ * @return 0 on success
+ * @return -ERROR_CODE on failure
+ */
+static int
+megaraid_sysfs_alloc_resources(adapter_t *adapter)
+{
+	mraid_device_t	*raid_dev = ADAP2RAIDDEV(adapter);
+	int		rval = 0;
+
+	raid_dev->sysfs_uioc = kmalloc(sizeof(uioc_t), GFP_KERNEL);
+
+	raid_dev->sysfs_mbox64 = kmalloc(sizeof(mbox64_t), GFP_KERNEL);
+
+	raid_dev->sysfs_buffer = pci_alloc_consistent(adapter->pdev,
+			PAGE_SIZE, &raid_dev->sysfs_buffer_dma);
+
+	if (!raid_dev->sysfs_uioc || !raid_dev->sysfs_mbox64 ||
+		!raid_dev->sysfs_buffer) {
+
+		con_log(CL_ANN, (KERN_WARNING
+			"megaraid: out of memory, %s %d\n", __FUNCTION__,
+			__LINE__));
+
+		rval = -ENOMEM;
+
+		megaraid_sysfs_free_resources(adapter);
+	}
+
+	sema_init(&raid_dev->sysfs_sem, 1);
+
+	init_waitqueue_head(&raid_dev->sysfs_wait_q);
+
+	return rval;
+}
+
+
+/**
+ * megaraid_sysfs_free_resources - free sysfs related resources
+ *
+ * Free packets allocated for sysfs FW commands
+ *
+ * @param adapter : controller's soft state
+ */
+static void
+megaraid_sysfs_free_resources(adapter_t *adapter)
+{
+	mraid_device_t	*raid_dev = ADAP2RAIDDEV(adapter);
+
+	if (raid_dev->sysfs_uioc) kfree(raid_dev->sysfs_uioc);
+
+	if (raid_dev->sysfs_mbox64) kfree(raid_dev->sysfs_mbox64);
+
+	if (raid_dev->sysfs_buffer) {
+		pci_free_consistent(adapter->pdev, PAGE_SIZE,
+			raid_dev->sysfs_buffer, raid_dev->sysfs_buffer_dma);
+	}
+}
+
+
+/**
+ * megaraid_sysfs_get_ldmap_done - callback for get ldmap
+ *
+ * Callback routine called in the ISR/tasklet context for get ldmap call
+ *
+ * @param uioc : completed packet
+ */
+static void
+megaraid_sysfs_get_ldmap_done(uioc_t *uioc)
+{
+	adapter_t	*adapter = (adapter_t *)uioc->buf_vaddr;
+	mraid_device_t	*raid_dev = ADAP2RAIDDEV(adapter);
+
+	uioc->status = 0;
+
+	wake_up(&raid_dev->sysfs_wait_q);
+}
+
+
+/**
+ * megaraid_sysfs_get_ldmap_timeout - timeout handling for get ldmap
+ *
+ * Timeout routine to recover and return to application, in case the adapter
+ * has stopped responding. A timeout of 60 seconds for this command seem like
+ * a good value
+ *
+ * @param uioc : timed out packet
+ */
+static void
+megaraid_sysfs_get_ldmap_timeout(unsigned long data)
+{
+	uioc_t		*uioc = (uioc_t *)data;
+	adapter_t	*adapter = (adapter_t *)uioc->buf_vaddr;
+	mraid_device_t	*raid_dev = ADAP2RAIDDEV(adapter);
+
+	uioc->status = -ETIME;
+
+	wake_up(&raid_dev->sysfs_wait_q);
+}
+
+
+/**
+ * megaraid_sysfs_get_ldmap - get update logical drive map
+ *
+ * This routine will be called whenever user reads the logical drive
+ * attributes, go get the current logical drive mapping table from the
+ * firmware. We use the managment API's to issue commands to the controller.
+ *
+ * NOTE: The commands issuance functionality is not generalized and
+ * implemented in context of "get ld map" command only. If required, the
+ * command issuance logical can be trivially pulled out and implemented as a
+ * standalone libary. For now, this should suffice since there is no other
+ * user of this interface.
+ *
+ * @param adapter : controller's soft state
+ *
+ * @return 0 on success
+ * @return -1 on failure
+ */
+static int
+megaraid_sysfs_get_ldmap(adapter_t *adapter)
+{
+	mraid_device_t		*raid_dev = ADAP2RAIDDEV(adapter);
+	uioc_t			*uioc;
+	mbox64_t		*mbox64;
+	mbox_t			*mbox;
+	char			*raw_mbox;
+	struct timer_list	sysfs_timer;
+	struct timer_list	*timerp;
+	caddr_t			ldmap;
+	int			rval = 0;
+
+	/*
+	 * Allow only one read at a time to go through the sysfs attributes
+	 */
+	down(&raid_dev->sysfs_sem);
+
+	uioc	= raid_dev->sysfs_uioc;
+	mbox64	= raid_dev->sysfs_mbox64;
+	ldmap	= raid_dev->sysfs_buffer;
+
+	memset(uioc, 0, sizeof(uioc_t));
+	memset(mbox64, 0, sizeof(mbox64_t));
+	memset(ldmap, 0, sizeof(raid_dev->curr_ldmap));
+
+	mbox		= &mbox64->mbox32;
+	raw_mbox	= (char *)mbox;
+	uioc->cmdbuf    = (uint64_t)(unsigned long)mbox64;
+	uioc->buf_vaddr	= (caddr_t)adapter;
+	uioc->status	= -ENODATA;
+	uioc->done	= megaraid_sysfs_get_ldmap_done;
+
+	/*
+	 * Prepare the mailbox packet to get the current logical drive mapping
+	 * table
+	 */
+	mbox->xferaddr = (uint32_t)raid_dev->sysfs_buffer_dma;
+
+	raw_mbox[0] = FC_DEL_LOGDRV;
+	raw_mbox[2] = OP_GET_LDID_MAP;
+
+	/*
+	 * Setup a timer to recover from a non-responding controller
+	 */
+	timerp	= &sysfs_timer;
+	init_timer(timerp);
+
+	timerp->function	= megaraid_sysfs_get_ldmap_timeout;
+	timerp->data		= (unsigned long)uioc;
+	timerp->expires		= jiffies + 60 * HZ;
+
+	add_timer(timerp);
+
+	/*
+	 * Send the command to the firmware
+	 */
+	rval = megaraid_mbox_mm_command(adapter, uioc);
+
+	if (rval == 0) {	// command successfully issued
+		wait_event(raid_dev->sysfs_wait_q, (uioc->status != -ENODATA));
+
+		/*
+		 * Check if the command timed out
+		 */
+		if (uioc->status == -ETIME) {
+			con_log(CL_ANN, (KERN_NOTICE
+				"megaraid: sysfs get ld map timed out\n"));
+
+			rval = -ETIME;
+		}
+		else {
+			rval = mbox->status;
+		}
+
+		if (rval == 0) {
+			memcpy(raid_dev->curr_ldmap, ldmap,
+				sizeof(raid_dev->curr_ldmap));
+		}
+		else {
+			con_log(CL_ANN, (KERN_NOTICE
+				"megaraid: get ld map failed with %x\n", rval));
+		}
+	}
+	else {
+		con_log(CL_ANN, (KERN_NOTICE
+			"megaraid: could not issue ldmap command:%x\n", rval));
+	}
+
+
+	del_timer_sync(timerp);
+
+	up(&raid_dev->sysfs_sem);
+
+	return rval;
+}
+
+
+/**
+ * megaraid_sysfs_show_app_hndl - display application handle for this adapter
+ *
+ * Display the handle used by the applications while executing management
+ * tasks on the adapter. We invoke a management module API to get the adapter
+ * handle, since we do not interface with applications directly.
+ *
+ * @param cdev	: class device object representation for the host
+ * @param buf	: buffer to send data to
+ */
+static ssize_t
+megaraid_sysfs_show_app_hndl(struct class_device *cdev, char *buf)
+{
+	struct Scsi_Host *shost = class_to_shost(cdev);
+	adapter_t	*adapter = (adapter_t *)SCSIHOST2ADAP(shost);
+	uint32_t	app_hndl;
+
+	app_hndl = mraid_mm_adapter_app_handle(adapter->unique_id);
+
+	return snprintf(buf, 8, "%u\n", app_hndl);
+}
+
+
+/**
+ * megaraid_sysfs_show_ldnum - display the logical drive number for this device
+ *
+ * Display the logical drive number for the device in question, if it a valid
+ * logical drive. For physical devices, "-1" is returned
+ * The logical drive number is displayed in following format
+ *
+ * <SCSI ID> <LD NUM> <LD STICKY ID> <APP ADAPTER HANDLE>
+ *   <int>     <int>       <int>            <int>
+ *
+ * @param dev	: device object representation for the scsi device
+ * @param buf	: buffer to send data to
+ */
+static ssize_t
+megaraid_sysfs_show_ldnum(struct device *dev, char *buf)
+{
+	struct scsi_device *sdev = to_scsi_device(dev);
+	adapter_t	*adapter = (adapter_t *)SCSIHOST2ADAP(sdev->host);
+	mraid_device_t	*raid_dev = ADAP2RAIDDEV(adapter);
+	int		scsi_id = -1;
+	int		logical_drv = -1;
+	int		ldid_map = -1;
+	uint32_t	app_hndl = 0;
+	int		mapped_sdev_id;
+	int		rval;
+	int		i;
+
+	if (raid_dev->random_del_supported &&
+			MRAID_IS_LOGICAL_SDEV(adapter, sdev)) {
+
+		rval = megaraid_sysfs_get_ldmap(adapter);
+		if (rval == 0) {
+
+			for (i = 0; i < MAX_LOGICAL_DRIVES_40LD; i++) {
+
+				mapped_sdev_id = sdev->id;
+
+				if (sdev->id > adapter->init_id) {
+					mapped_sdev_id -= 1;
+				}
+
+				if (raid_dev->curr_ldmap[i] == mapped_sdev_id) {
+
+					scsi_id = sdev->id;
+
+					logical_drv = i;
+
+					ldid_map = raid_dev->curr_ldmap[i];
+
+					app_hndl = mraid_mm_adapter_app_handle(
+							adapter->unique_id);
+
+					break;
+				}
+			}
+		}
+		else {
+			con_log(CL_ANN, (KERN_NOTICE
+				"megaraid: sysfs get ld map failed: %x\n",
+				rval));
+		}
+	}
+
+	return snprintf(buf, 36, "%d %d %d %d\n", scsi_id, logical_drv,
+			ldid_map, app_hndl);
+}
 
 
 /*
diff -Nru a/drivers/scsi/megaraid/megaraid_mbox.h b/drivers/scsi/megaraid/megaraid_mbox.h
--- a/drivers/scsi/megaraid/megaraid_mbox.h	2005-03-01 23:38:55 -08:00
+++ b/drivers/scsi/megaraid/megaraid_mbox.h	2005-03-01 23:38:55 -08:00
@@ -21,8 +21,8 @@
 #include "megaraid_ioctl.h"
 
 
-#define MEGARAID_VERSION	"2.20.4.1"
-#define MEGARAID_EXT_VERSION	"(Release Date: Thu Nov  4 17:44:59 EST 2004)"
+#define MEGARAID_VERSION	"2.20.4.5"
+#define MEGARAID_EXT_VERSION	"(Release Date: Thu Feb 03 12:27:22 EST 2005)"
 
 
 /*
@@ -137,6 +137,9 @@
 #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
@@ -216,6 +219,14 @@
  * @param hw_error		: set if FW not responding
  * @param fast_load		: If set, skip physical device scanning
  * @channel_class		: channel class, RAID or SCSI
+ * @sysfs_sem			: semaphore to serialize access to sysfs res.
+ * @sysfs_uioc			: management packet to issue FW calls from sysfs
+ * @sysfs_mbox64		: mailbox packet to issue FW calls from sysfs
+ * @sysfs_buffer		: data buffer for FW commands issued from sysfs
+ * @sysfs_buffer_dma		: DMA buffer for FW commands issued from sysfs
+ * @sysfs_wait_q		: wait queue for sysfs operations
+ * @random_del_supported	: set if the random deletion is supported
+ * @curr_ldmap			: current LDID map
  *
  * Initialization structure for mailbox controllers: memory based and IO based
  * All the fields in this structure are LLD specific and may be discovered at
@@ -223,6 +234,7 @@
  *
  * NOTE: The fields of this structures are placed to minimize cache misses
  */
+#define MAX_LD_EXTENDED64	64
 typedef struct {
 	mbox64_t			*una_mbox64;
 	dma_addr_t			una_mbox64_dma;
@@ -247,6 +259,14 @@
 	int				hw_error;
 	int				fast_load;
 	uint8_t				channel_class;
+	struct semaphore		sysfs_sem;
+	uioc_t				*sysfs_uioc;
+	mbox64_t			*sysfs_mbox64;
+	caddr_t				sysfs_buffer;
+	dma_addr_t			sysfs_buffer_dma;
+	wait_queue_head_t		sysfs_wait_q;
+	int				random_del_supported;
+	uint16_t			curr_ldmap[MAX_LD_EXTENDED64];
 } mraid_device_t;
 
 // route to raid device from adapter
diff -Nru a/drivers/scsi/megaraid/megaraid_mm.c b/drivers/scsi/megaraid/megaraid_mm.c
--- a/drivers/scsi/megaraid/megaraid_mm.c	2005-03-01 23:39:06 -08:00
+++ b/drivers/scsi/megaraid/megaraid_mm.c	2005-03-01 23:39:06 -08:00
@@ -10,7 +10,7 @@
  *	   2 of the License, or (at your option) any later version.
  *
  * FILE		: megaraid_mm.c
- * Version	: v2.20.2.3 (Dec 09 2004)
+ * Version	: v2.20.2.5 (Jan 21 2005)
  *
  * Common management module
  */
@@ -58,6 +58,7 @@
 
 EXPORT_SYMBOL(mraid_mm_register_adp);
 EXPORT_SYMBOL(mraid_mm_unregister_adp);
+EXPORT_SYMBOL(mraid_mm_adapter_app_handle);
 
 static int majorno;
 static uint32_t drvr_ver	= 0x02200201;
@@ -65,7 +66,7 @@
 static int adapters_count_g;
 static struct list_head adapters_list_g;
 
-wait_queue_head_t wait_q;
+static wait_queue_head_t wait_q;
 
 static struct file_operations lsi_fops = {
 	.open	= mraid_mm_open,
@@ -1006,6 +1007,40 @@
 
 	return rval;
 }
+
+
+/**
+ * mraid_mm_adapter_app_handle - return the application handle for this adapter
+ *
+ * For the given driver data, locate the adadpter in our global list and
+ * return the corresponding handle, which is also used by applications to
+ * uniquely identify an adapter.
+ *
+ * @param unique_id : adapter unique identifier
+ *
+ * @return adapter handle if found in the list
+ * @return 0 if adapter could not be located, should never happen though
+ */
+uint32_t
+mraid_mm_adapter_app_handle(uint32_t unique_id)
+{
+	mraid_mmadp_t	*adapter;
+	mraid_mmadp_t	*tmp;
+	int		index = 0;
+
+	list_for_each_entry_safe(adapter, tmp, &adapters_list_g, list) {
+
+		if (adapter->unique_id == unique_id) {
+
+			return MKADAP(index);
+		}
+
+		index++;
+	}
+
+	return 0;
+}
+
 
 /**
  * mraid_mm_setup_dma_pools - Set up dma buffer pools per adapter
diff -Nru a/drivers/scsi/megaraid/megaraid_mm.h b/drivers/scsi/megaraid/megaraid_mm.h
--- a/drivers/scsi/megaraid/megaraid_mm.h	2005-03-01 23:38:51 -08:00
+++ b/drivers/scsi/megaraid/megaraid_mm.h	2005-03-01 23:38:51 -08:00
@@ -29,9 +29,10 @@
 #include "megaraid_ioctl.h"
 
 
-#define LSI_COMMON_MOD_VERSION	"2.20.2.3"
+#define LSI_COMMON_MOD_VERSION	"2.20.2.5"
 #define LSI_COMMON_MOD_EXT_VERSION	\
-		"(Release Date: Thu Dec  9 19:02:14 EST 2004)"
+		"(Release Date: Fri Jan 21 00:01:03 EST 2005)"
+
 
 #define LSI_DBGLVL			dbglevel
 
diff -Nru a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c
--- a/drivers/scsi/megaraid.c	2005-03-01 23:38:44 -08:00
+++ b/drivers/scsi/megaraid.c	2005-03-01 23:38:44 -08:00
@@ -5109,11 +5109,11 @@
 	 */
 	unregister_chrdev(major, "megadev");
 
+	pci_unregister_driver(&megaraid_pci_driver);
+
 #ifdef CONFIG_PROC_FS
 	remove_proc_entry("megaraid", &proc_root);
 #endif
-
-	pci_unregister_driver(&megaraid_pci_driver);
 }
 
 module_init(megaraid_init);
diff -Nru a/drivers/scsi/nsp32.c b/drivers/scsi/nsp32.c
--- a/drivers/scsi/nsp32.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/scsi/nsp32.c	2005-03-01 23:38:55 -08:00
@@ -60,17 +60,17 @@
  * Module parameters
  */
 static int       trans_mode = 0;	/* default: BIOS */
-MODULE_PARM     (trans_mode, "i");
+module_param     (trans_mode, int, 0);
 MODULE_PARM_DESC(trans_mode, "transfer mode (0: BIOS(default) 1: Async 2: Ultra20M");
 #define ASYNC_MODE    1
 #define ULTRA20M_MODE 2
 
 static int       auto_param = 0;	/* default: ON */
-MODULE_PARM     (auto_param, "i");
+module_param     (auto_param, bool, 0);
 MODULE_PARM_DESC(auto_param, "AutoParameter mode (0: ON(default) 1: OFF)");
 
 static int       disc_priv  = 1;	/* default: OFF */
-MODULE_PARM     (disc_priv,  "i");
+module_param     (disc_priv, bool, 0);
 MODULE_PARM_DESC(disc_priv,  "disconnection privilege mode (0: ON 1: OFF(default))");
 
 MODULE_AUTHOR("YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp>, GOTO Masanori <gotom@debian.or.jp>");
diff -Nru a/drivers/scsi/oktagon_esp.c b/drivers/scsi/oktagon_esp.c
--- a/drivers/scsi/oktagon_esp.c	2005-03-01 23:38:51 -08:00
+++ b/drivers/scsi/oktagon_esp.c	2005-03-01 23:38:51 -08:00
@@ -72,8 +72,6 @@
 static void dma_advance_sg(Scsi_Cmnd *);
 static int  oktagon_notify_reboot(struct notifier_block *this, unsigned long code, void *x);
 
-void esp_bootup_reset(struct NCR_ESP *esp,struct ESP_regs *eregs);
-
 #ifdef USE_BOTTOM_HALF
 static void dma_commit(void *opaque);
 
diff -Nru a/drivers/scsi/osst.c b/drivers/scsi/osst.c
--- a/drivers/scsi/osst.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/scsi/osst.c	2005-03-01 23:38:57 -08:00
@@ -13,18 +13,18 @@
   order) Klaus Ehrenfried, Wolfgang Denk, Steve Hirsch, Andreas Koppenh"ofer,
   Michael Leodolter, Eyal Lebedinsky, J"org Weule, and Eric Youngdale.
 
-  Copyright 1992 - 2002 Kai Makisara / Willem Riede
-	 email Kai.Makisara@metla.fi / osst@riede.org
+  Copyright 1992 - 2002 Kai Makisara / 2000 - 2004 Willem Riede
+	 email osst@riede.org
 
-  $Header: /cvsroot/osst/Driver/osst.c,v 1.70 2003/12/23 14:22:12 wriede Exp $
+  $Header: /cvsroot/osst/Driver/osst.c,v 1.73 2005/01/01 21:13:34 wriede Exp $
 
   Microscopic alterations - Rik Ling, 2000/12/21
   Last st.c sync: Tue Oct 15 22:01:04 2002 by makisara
   Some small formal changes - aeb, 950809
 */
 
-static const char * cvsid = "$Id: osst.c,v 1.70 2003/12/23 14:22:12 wriede Exp $";
-const char * osst_version = "0.99.1";
+static const char * cvsid = "$Id: osst.c,v 1.73 2005/01/01 21:13:34 wriede Exp $";
+const char * osst_version = "0.99.3";
 
 /* The "failure to reconnect" firmware bug */
 #define OSST_FW_NEED_POLL_MIN 10601 /*(107A)*/
@@ -36,6 +36,7 @@
 #include <linux/fs.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
+#include <linux/proc_fs.h>
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/string.h>
@@ -46,6 +47,7 @@
 #include <linux/spinlock.h>
 #include <linux/vmalloc.h>
 #include <linux/blkdev.h>
+#include <linux/moduleparam.h>
 #include <linux/devfs_fs_kernel.h>
 #include <linux/delay.h>
 #include <asm/uaccess.h>
@@ -61,10 +63,14 @@
    in the drivers are more widely classified, this may be changed to KERN_DEBUG. */
 #define OSST_DEB_MSG  KERN_NOTICE
 
-#include "scsi.h"
-#include <scsi/scsi_host.h>
+#include <scsi/scsi.h>
+#include <scsi/scsi_dbg.h>
+#include <scsi/scsi_device.h>
 #include <scsi/scsi_driver.h>
+#include <scsi/scsi_eh.h>
+#include <scsi/scsi_host.h>
 #include <scsi/scsi_ioctl.h>
+#include <scsi/scsi_request.h>
 
 #define ST_KILOBYTE 1024
 
@@ -82,13 +88,13 @@
 MODULE_DESCRIPTION("OnStream {DI-|FW-|SC-|USB}{30|50} Tape Driver");
 MODULE_LICENSE("GPL");
 
-module_param(max_dev, int, 0);
+module_param(max_dev, int, 0444);
 MODULE_PARM_DESC(max_dev, "Maximum number of OnStream Tape Drives to attach (4)");
 
-module_param(write_threshold_kbs, int, 0);
+module_param(write_threshold_kbs, int, 0644);
 MODULE_PARM_DESC(write_threshold_kbs, "Asynchronous write threshold (KB; 32)");
 
-module_param(max_sg_segs, int, 0);
+module_param(max_sg_segs, int, 0644);
 MODULE_PARM_DESC(max_sg_segs, "Maximum number of scatter/gather segments to use (9)");
 #else
 static struct osst_dev_parm {
@@ -119,10 +125,10 @@
 // #define OSST_INJECT_ERRORS 1 
 #endif
 
-#define MAX_RETRIES 2
-#define MAX_READ_RETRIES 0
-#define MAX_WRITE_RETRIES 0
-#define MAX_READY_RETRIES 0
+/* Do not retry! The drive firmware already retries when appropriate,
+   and when it tries to tell us something, we had better listen... */
+#define MAX_RETRIES 0
+
 #define NO_TAPE  NOT_READY
 
 #define OSST_WAIT_POSITION_COMPLETE   (HZ > 200 ? HZ / 200 : 1)
@@ -147,19 +153,19 @@
 static int osst_max_dev           = OSST_MAX_TAPES;
 static int osst_nr_dev;
 
-static OS_Scsi_Tape **os_scsi_tapes = NULL;
-static rwlock_t  os_scsi_tapes_lock = RW_LOCK_UNLOCKED;
+static struct osst_tape **os_scsi_tapes = NULL;
+static DEFINE_RWLOCK(os_scsi_tapes_lock);
 
-static int modes_defined = FALSE;
+static int modes_defined = 0;
 
-static OSST_buffer *new_tape_buffer(int, int, int);
-static int enlarge_buffer(OSST_buffer *, int);
-static void normalize_buffer(OSST_buffer *);
-static int append_to_buffer(const char __user *, OSST_buffer *, int);
-static int from_buffer(OSST_buffer *, char __user *, int);
-static int osst_zero_buffer_tail(OSST_buffer *);
-static int osst_copy_to_buffer(OSST_buffer *, unsigned char *);
-static int osst_copy_from_buffer(OSST_buffer *, unsigned char *);
+static struct osst_buffer *new_tape_buffer(int, int, int);
+static int enlarge_buffer(struct osst_buffer *, int);
+static void normalize_buffer(struct osst_buffer *);
+static int append_to_buffer(const char __user *, struct osst_buffer *, int);
+static int from_buffer(struct osst_buffer *, char __user *, int);
+static int osst_zero_buffer_tail(struct osst_buffer *);
+static int osst_copy_to_buffer(struct osst_buffer *, unsigned char *);
+static int osst_copy_from_buffer(struct osst_buffer *, unsigned char *);
 
 static int osst_probe(struct device *);
 static int osst_remove(struct device *);
@@ -173,17 +179,18 @@
 	}
 };
 
-static int osst_int_ioctl(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt, unsigned int cmd_in,unsigned long arg);
+static int osst_int_ioctl(struct osst_tape *STp, struct scsi_request ** aSRpnt,
+			    unsigned int cmd_in, unsigned long arg);
 
-static int osst_set_frame_position(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt, int frame, int skip);
+static int osst_set_frame_position(struct osst_tape *STp, struct scsi_request ** aSRpnt, int frame, int skip);
 
-static int osst_get_frame_position(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt);
+static int osst_get_frame_position(struct osst_tape *STp, struct scsi_request ** aSRpnt);
 
-static int osst_flush_write_buffer(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt);
+static int osst_flush_write_buffer(struct osst_tape *STp, struct scsi_request ** aSRpnt);
 
-static int osst_write_error_recovery(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int pending);
+static int osst_write_error_recovery(struct osst_tape * STp, struct scsi_request ** aSRpnt, int pending);
 
-static inline char *tape_name(OS_Scsi_Tape *tape)
+static inline char *tape_name(struct osst_tape *tape)
 {
 	return tape->drive->disk_name;
 }
@@ -191,7 +198,7 @@
 /* Routines that handle the interaction with mid-layer SCSI routines */
 
 /* Convert the result to success code */
-static int osst_chk_result(OS_Scsi_Tape * STp, Scsi_Request * SRpnt)
+static int osst_chk_result(struct osst_tape * STp, struct scsi_request * SRpnt)
 {
 	char *name = tape_name(STp);
 	int result = SRpnt->sr_result;
@@ -220,9 +227,9 @@
 		if (scode) printk(OSST_DEB_MSG "%s:D: Sense: %02x, ASC: %02x, ASCQ: %02x\n",
 			       	name, scode, sense[12], sense[13]);
 		if (driver_byte(result) & DRIVER_SENSE)
-			print_req_sense("osst ", SRpnt);
+			scsi_print_req_sense("osst ", SRpnt);
 	}
-//	else
+	else
 #endif
 	if (!(driver_byte(result) & DRIVER_SENSE) ||
 		((sense[0] & 0x70) == 0x70 &&
@@ -234,8 +241,8 @@
 		 SRpnt->sr_cmnd[0] != MODE_SENSE &&
 		 SRpnt->sr_cmnd[0] != TEST_UNIT_READY)) { /* Abnormal conditions for tape */
 		if (driver_byte(result) & DRIVER_SENSE) {
-			printk(KERN_WARNING "%s:W: Command with sense data: ", name);
-			print_req_sense("osst:", SRpnt);
+			printk(KERN_WARNING "%s:W: Command with sense data:\n", name);
+			scsi_print_req_sense("osst:", SRpnt);
 		}
 		else {
 			static	int	notyetprinted = 1;
@@ -279,9 +286,9 @@
 
 
 /* Wakeup from interrupt */
-static void osst_sleep_done (Scsi_Cmnd * SCpnt)
+static void osst_sleep_done (struct scsi_cmnd * SCpnt)
 {
-	OS_Scsi_Tape * STp = container_of(SCpnt->request->rq_disk->private_data, OS_Scsi_Tape, driver);
+	struct osst_tape * STp = container_of(SCpnt->request->rq_disk->private_data, struct osst_tape, driver);
 
 	if ((STp->buffer)->writing &&
 	    (SCpnt->sense_buffer[0] & 0x70) == 0x70 &&
@@ -307,7 +314,7 @@
 /* Do the scsi command. Waits until command performed if do_wait is true.
    Otherwise osst_write_behind_check() is used to check that the command
    has finished. */
-static	Scsi_Request * osst_do_scsi(Scsi_Request *SRpnt, OS_Scsi_Tape *STp, 
+static	struct scsi_request * osst_do_scsi(struct scsi_request *SRpnt, struct osst_tape *STp, 
 	unsigned char *cmd, int bytes, int direction, int timeout, int retries, int do_wait)
 {
 	unsigned char *bp;
@@ -366,9 +373,9 @@
 
 
 /* Handle the write-behind checking (downs the semaphore) */
-static void osst_write_behind_check(OS_Scsi_Tape *STp)
+static void osst_write_behind_check(struct osst_tape *STp)
 {
-	OSST_buffer * STbuffer;
+	struct osst_buffer * STbuffer;
 
 	STbuffer = STp->buffer;
 
@@ -406,7 +413,7 @@
 /*
  * Initialize the OnStream AUX
  */
-static void osst_init_aux(OS_Scsi_Tape * STp, int frame_type, int frame_seq_number,
+static void osst_init_aux(struct osst_tape * STp, int frame_type, int frame_seq_number,
 					 int logical_blk_num, int blk_sz, int blk_cnt)
 {
 	os_aux_t       *aux = STp->buffer->aux;
@@ -468,13 +475,13 @@
 /*
  * Verify that we have the correct tape frame
  */
-static int osst_verify_frame(OS_Scsi_Tape * STp, int frame_seq_number, int quiet)
+static int osst_verify_frame(struct osst_tape * STp, int frame_seq_number, int quiet)
 {
-	char           * name = tape_name(STp);
-	os_aux_t       * aux  = STp->buffer->aux;
-	os_partition_t * par  = &(aux->partition);
-	struct st_partstat    * STps = &(STp->ps[STp->partition]);
-	int		 blk_cnt, blk_sz, i;
+	char               * name = tape_name(STp);
+	os_aux_t           * aux  = STp->buffer->aux;
+	os_partition_t     * par  = &(aux->partition);
+	struct st_partstat * STps = &(STp->ps[STp->partition]);
+	int		     blk_cnt, blk_sz, i;
 
 	if (STp->raw) {
 		if (STp->buffer->syscall_result) {
@@ -602,14 +609,15 @@
 /*
  * Wait for the unit to become Ready
  */
-static int osst_wait_ready(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, unsigned timeout, int initial_delay)
+static int osst_wait_ready(struct osst_tape * STp, struct scsi_request ** aSRpnt,
+				 unsigned timeout, int initial_delay)
 {
-	unsigned char	cmd[MAX_COMMAND_SIZE];
-	Scsi_Request  * SRpnt;
-	unsigned long	startwait = jiffies;
+	unsigned char		cmd[MAX_COMMAND_SIZE];
+	struct scsi_request   * SRpnt;
+	unsigned long		startwait = jiffies;
 #if DEBUG
-	int		dbg  = debugging;
-	char          * name = tape_name(STp);
+	int			dbg  = debugging;
+	char    	      * name = tape_name(STp);
 
 	printk(OSST_DEB_MSG "%s:D: Reached onstream wait ready\n", name);
 #endif
@@ -620,7 +628,7 @@
 	memset(cmd, 0, MAX_COMMAND_SIZE);
 	cmd[0] = TEST_UNIT_READY;
 
-	SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_READY_RETRIES, TRUE);
+	SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
 	*aSRpnt = SRpnt;
 	if (!SRpnt) return (-EBUSY);
 
@@ -641,7 +649,7 @@
 	    memset(cmd, 0, MAX_COMMAND_SIZE);
 	    cmd[0] = TEST_UNIT_READY;
 
-	    SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_READY_RETRIES, TRUE);
+	    SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
 	}
 	*aSRpnt = SRpnt;
 #if DEBUG
@@ -666,14 +674,14 @@
 /*
  * Wait for a tape to be inserted in the unit
  */
-static int osst_wait_for_medium(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, unsigned timeout)
+static int osst_wait_for_medium(struct osst_tape * STp, struct scsi_request ** aSRpnt, unsigned timeout)
 {
-	unsigned char	cmd[MAX_COMMAND_SIZE];
-	Scsi_Request  * SRpnt;
-	unsigned long	startwait = jiffies;
+	unsigned char		cmd[MAX_COMMAND_SIZE];
+	struct scsi_request   * SRpnt;
+	unsigned long		startwait = jiffies;
 #if DEBUG
-	int		dbg = debugging;
-	char          * name = tape_name(STp);
+	int			dbg = debugging;
+	char    	      * name = tape_name(STp);
 
 	printk(OSST_DEB_MSG "%s:D: Reached onstream wait for medium\n", name);
 #endif
@@ -681,7 +689,7 @@
 	memset(cmd, 0, MAX_COMMAND_SIZE);
 	cmd[0] = TEST_UNIT_READY;
 
-	SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_READY_RETRIES, TRUE);
+	SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
 	*aSRpnt = SRpnt;
 	if (!SRpnt) return (-EBUSY);
 
@@ -700,7 +708,7 @@
 	    memset(cmd, 0, MAX_COMMAND_SIZE);
 	    cmd[0] = TEST_UNIT_READY;
 
-	    SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_READY_RETRIES, TRUE);
+	    SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
 	}
 	*aSRpnt = SRpnt;
 #if DEBUG
@@ -722,7 +730,7 @@
 	return 1;
 }
 
-static int osst_position_tape_and_confirm(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int frame)
+static int osst_position_tape_and_confirm(struct osst_tape * STp, struct scsi_request ** aSRpnt, int frame)
 {
 	int	retval;
 
@@ -736,15 +744,14 @@
 /*
  * Wait for write(s) to complete
  */
-static int osst_flush_drive_buffer(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt)
+static int osst_flush_drive_buffer(struct osst_tape * STp, struct scsi_request ** aSRpnt)
 {
-	unsigned char	cmd[MAX_COMMAND_SIZE];
-	Scsi_Request  * SRpnt;
-
-	int             result = 0;
-	int		delay  = OSST_WAIT_WRITE_COMPLETE;
+	unsigned char		cmd[MAX_COMMAND_SIZE];
+	struct scsi_request   * SRpnt;
+	int			result = 0;
+	int			delay  = OSST_WAIT_WRITE_COMPLETE;
 #if DEBUG
-	char          * name = tape_name(STp);
+	char		      * name = tape_name(STp);
 
 	printk(OSST_DEB_MSG "%s:D: Reached onstream flush drive buffer (write filemark)\n", name);
 #endif
@@ -753,7 +760,7 @@
 	cmd[0] = WRITE_FILEMARKS;
 	cmd[1] = 1;
 
-	SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_WRITE_RETRIES, TRUE);
+	SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
 	*aSRpnt = SRpnt;
 	if (!SRpnt) return (-EBUSY);
 	if (STp->buffer->syscall_result) {
@@ -771,12 +778,12 @@
 }
 
 #define OSST_POLL_PER_SEC 10
-static int osst_wait_frame(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int curr, int minlast, int to)
+static int osst_wait_frame(struct osst_tape * STp, struct scsi_request ** aSRpnt, int curr, int minlast, int to)
 {
-	unsigned long	startwait     = jiffies;
-	char	      * name          = tape_name(STp);
+	unsigned long	startwait = jiffies;
+	char	      * name      = tape_name(STp);
 #if DEBUG
-	char	notyetprinted = 1;
+	char	   notyetprinted  = 1;
 #endif
 	if (minlast >= 0 && STp->ps[STp->partition].rw != ST_READING)
 		printk(KERN_ERR "%s:A: Waiting for frame without having initialized read!\n", name);
@@ -784,7 +791,7 @@
 	while (time_before (jiffies, startwait + to*HZ))
 	{ 
 		int result;
-		result = osst_get_frame_position (STp, aSRpnt);
+		result = osst_get_frame_position(STp, aSRpnt);
 		if (result == -EIO)
 			if ((result = osst_write_error_recovery(STp, aSRpnt, 0)) == 0)
 				return 0;	/* successful recovery leaves drive ready for frame */
@@ -826,23 +833,79 @@
 	return -EBUSY;
 }
 
+static int osst_recover_wait_frame(struct osst_tape * STp, struct scsi_request ** aSRpnt, int writing)
+{
+	struct scsi_request   * SRpnt;
+	unsigned char		cmd[MAX_COMMAND_SIZE];
+	unsigned long   	startwait = jiffies;
+	int			retval    = 1;
+        char		      * name      = tape_name(STp);
+                                                                                                                                
+	if (writing) {
+		char	mybuf[24];
+		char  * olddata = STp->buffer->b_data;
+		int	oldsize = STp->buffer->buffer_size;
+
+		/* write zero fm then read pos - if shows write error, try to recover - if no progress, wait */
+
+		memset(cmd, 0, MAX_COMMAND_SIZE);
+		cmd[0] = WRITE_FILEMARKS;
+		cmd[1] = 1;
+		SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout,
+								MAX_RETRIES, 1);
+
+		while (retval && time_before (jiffies, startwait + 5*60*HZ)) {
+
+			if (STp->buffer->syscall_result && (SRpnt->sr_sense_buffer[2] & 0x0f) != 2) {
+
+				/* some failure - not just not-ready */
+				retval = osst_write_error_recovery(STp, aSRpnt, 0);
+				break;
+			}
+			set_current_state(TASK_INTERRUPTIBLE);
+			schedule_timeout (HZ / OSST_POLL_PER_SEC);
+
+			STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24;
+			memset(cmd, 0, MAX_COMMAND_SIZE);
+			cmd[0] = READ_POSITION;
+
+			SRpnt = osst_do_scsi(SRpnt, STp, cmd, 20, DMA_FROM_DEVICE, STp->timeout,
+										MAX_RETRIES, 1);
+
+			retval = ( STp->buffer->syscall_result || (STp->buffer)->b_data[15] > 25 );
+			STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize;
+		}
+		if (retval)
+			printk(KERN_ERR "%s:E: Device did not succeed to write buffered data\n", name);
+	} else
+		/* TODO - figure out which error conditions can be handled */
+		if (STp->buffer->syscall_result)
+			printk(KERN_WARNING
+				"%s:W: Recover_wait_frame(read) cannot handle %02x:%02x:%02x\n", name,
+					(*aSRpnt)->sr_sense_buffer[ 2] & 0x0f,
+					(*aSRpnt)->sr_sense_buffer[12],
+					(*aSRpnt)->sr_sense_buffer[13]);
+
+	return retval;
+}
+
 /*
  * Read the next OnStream tape frame at the current location
  */
-static int osst_read_frame(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int timeout)
+static int osst_read_frame(struct osst_tape * STp, struct scsi_request ** aSRpnt, int timeout)
 {
-	unsigned char	cmd[MAX_COMMAND_SIZE];
-	Scsi_Request  * SRpnt;
-	int		retval = 0;
+	unsigned char		cmd[MAX_COMMAND_SIZE];
+	struct scsi_request   * SRpnt;
+	int			retval = 0;
 #if DEBUG
-	os_aux_t      * aux    = STp->buffer->aux;
-	char          * name = tape_name(STp);
+	os_aux_t	      * aux    = STp->buffer->aux;
+	char		      * name   = tape_name(STp);
 #endif
 
-	/* TODO: Error handling */
 	if (STp->poll)
-		retval = osst_wait_frame (STp, aSRpnt, STp->first_frame_position, 0, timeout);
-	
+		if (osst_wait_frame (STp, aSRpnt, STp->first_frame_position, 0, timeout))
+			retval = osst_recover_wait_frame(STp, aSRpnt, 0);
+
 	memset(cmd, 0, MAX_COMMAND_SIZE);
 	cmd[0] = READ_6;
 	cmd[1] = 1;
@@ -850,13 +913,13 @@
 
 #if DEBUG
 	if (debugging)
-	    printk(OSST_DEB_MSG "%s:D: Reading frame from OnStream tape\n", name);
+		printk(OSST_DEB_MSG "%s:D: Reading frame from OnStream tape\n", name);
 #endif
-	SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, SCSI_DATA_READ,
-				      STp->timeout, MAX_READ_RETRIES, TRUE);
+	SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_FROM_DEVICE,
+				      STp->timeout, MAX_RETRIES, 1);
 	*aSRpnt = SRpnt;
 	if (!SRpnt)
-	    return (-EBUSY);
+		return (-EBUSY);
 
 	if ((STp->buffer)->syscall_result) {
 	    retval = 1;
@@ -900,15 +963,13 @@
 	return (retval);
 }
 
-static int osst_initiate_read(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt)
+static int osst_initiate_read(struct osst_tape * STp, struct scsi_request ** aSRpnt)
 {
-	struct st_partstat   * STps   = &(STp->ps[STp->partition]);
-	Scsi_Request  * SRpnt  ;
-	unsigned char	cmd[MAX_COMMAND_SIZE];
-	int		retval = 0;
-#if DEBUG
-	char          * name = tape_name(STp);
-#endif
+	struct st_partstat    * STps   = &(STp->ps[STp->partition]);
+	struct scsi_request   * SRpnt  ;
+	unsigned char		cmd[MAX_COMMAND_SIZE];
+	int			retval = 0;
+	char		      * name   = tape_name(STp);
 
 	if (STps->rw != ST_READING) {         /* Initialize read operation */
 		if (STps->rw == ST_WRITING || STp->dirty) {
@@ -930,23 +991,25 @@
 #if DEBUG
 		printk(OSST_DEB_MSG "%s:D: Start Read Ahead on OnStream tape\n", name);
 #endif
-		SRpnt   = osst_do_scsi(*aSRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_READ_RETRIES, TRUE);
+		SRpnt   = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
 		*aSRpnt = SRpnt;
-		retval  = STp->buffer->syscall_result;
+		if ((retval = STp->buffer->syscall_result))
+			printk(KERN_WARNING "%s:W: Error starting read ahead\n", name);
 	}
 
 	return retval;
 }
 
-static int osst_get_logical_frame(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int frame_seq_number, int quiet)
+static int osst_get_logical_frame(struct osst_tape * STp, struct scsi_request ** aSRpnt,
+						int frame_seq_number, int quiet)
 {
 	struct st_partstat * STps  = &(STp->ps[STp->partition]);
-	char        * name  = tape_name(STp);
-	int           cnt   = 0,
-		      bad   = 0,
-		      past  = 0,
-		      x,
-		      position;
+	char		   * name  = tape_name(STp);
+	int		     cnt   = 0,
+			     bad   = 0,
+			     past  = 0,
+			     x,
+			     position;
 
 	/*
 	 * If we want just any frame (-1) and there is a frame in the buffer, return it
@@ -971,6 +1034,7 @@
 						    name, STp->read_error_frame);
 #endif
 				STp->read_error_frame = 0;
+				STp->abort_count++;
 			}
 			return (-EIO);
 		}
@@ -988,10 +1052,11 @@
 				position = 0xbb8;
 			else if (position > STp->eod_frame_ppos || ++bad == 10) {
 				position = STp->read_error_frame - 1;
+				bad = 0;
 			}
 			else {
-				position += 39;
-				cnt += 20;
+				position += 29;
+				cnt      += 19;
 			}
 #if DEBUG
 			printk(OSST_DEB_MSG "%s:D: Bad frame detected, positioning tape to block %d\n",
@@ -1059,15 +1124,15 @@
 			"%s:D: Exit get logical frame (%d=>%d) from OnStream tape with code %d\n",
 			name, frame_seq_number, STp->frame_seq_number, STps->eof);
 #endif
-	STp->fast_open = FALSE;
+	STp->fast_open = 0;
 	STp->read_error_frame = 0;
 	return (STps->eof);
 }
 
-static int osst_seek_logical_blk(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int logical_blk_num)
+static int osst_seek_logical_blk(struct osst_tape * STp, struct scsi_request ** aSRpnt, int logical_blk_num)
 {
         struct st_partstat * STps = &(STp->ps[STp->partition]);
-	char        * name = tape_name(STp);
+	char		   * name = tape_name(STp);
 	int	retries    = 0;
 	int	frame_seq_estimate, ppos_estimate, move;
 	
@@ -1173,7 +1238,7 @@
 #define OSST_SECTOR_SHIFT 9
 #define OSST_SECTOR_MASK  0x03F
 
-static int osst_get_sector(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt)
+static int osst_get_sector(struct osst_tape * STp, struct scsi_request ** aSRpnt)
 {
 	int	sector;
 #if DEBUG
@@ -1203,12 +1268,12 @@
 	return sector;
 }
 
-static int osst_seek_sector(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int sector)
+static int osst_seek_sector(struct osst_tape * STp, struct scsi_request ** aSRpnt, int sector)
 {
-        struct st_partstat   * STps   = &(STp->ps[STp->partition]);
-	int		frame  = sector >> OSST_FRAME_SHIFT,
-			offset = (sector & OSST_SECTOR_MASK) << OSST_SECTOR_SHIFT, 
-			r;
+        struct st_partstat * STps   = &(STp->ps[STp->partition]);
+	int		     frame  = sector >> OSST_FRAME_SHIFT,
+			     offset = (sector & OSST_SECTOR_MASK) << OSST_SECTOR_SHIFT, 
+			     r;
 #if DEBUG
 	char          * name = tape_name(STp);
 
@@ -1266,23 +1331,23 @@
  * Precondition for this function to work: all frames in the
  * drive's buffer must be of one type (DATA, MARK or EOD)!
  */
-static int osst_read_back_buffer_and_rewrite(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt,
-					unsigned int frame, unsigned int skip, int pending)
+static int osst_read_back_buffer_and_rewrite(struct osst_tape * STp, struct scsi_request ** aSRpnt,
+						unsigned int frame, unsigned int skip, int pending)
 {
-	Scsi_Request  * SRpnt = * aSRpnt;
-	unsigned char * buffer, * p;
-	unsigned char	cmd[MAX_COMMAND_SIZE];
-	int		flag, new_frame, i;
-	int		nframes          = STp->cur_frames;
-	int		blks_per_frame   = ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
-	int		frame_seq_number = ntohl(STp->buffer->aux->frame_seq_num)
+	struct scsi_request   * SRpnt = * aSRpnt;
+	unsigned char	      * buffer, * p;
+	unsigned char		cmd[MAX_COMMAND_SIZE];
+	int			flag, new_frame, i;
+	int			nframes          = STp->cur_frames;
+	int			blks_per_frame   = ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
+	int			frame_seq_number = ntohl(STp->buffer->aux->frame_seq_num)
 						- (nframes + pending - 1);
-	int		logical_blk_num  = ntohl(STp->buffer->aux->logical_blk_num) 
+	int			logical_blk_num  = ntohl(STp->buffer->aux->logical_blk_num) 
 						- (nframes + pending - 1) * blks_per_frame;
-	char	      * name             = tape_name(STp);
-	unsigned long	startwait        = jiffies;
+	char		      * name             = tape_name(STp);
+	unsigned long		startwait        = jiffies;
 #if DEBUG
-	int		dbg              = debugging;
+	int			dbg              = debugging;
 #endif
 
 	if ((buffer = (unsigned char *)vmalloc((nframes + 1) * OS_DATA_SIZE)) == NULL)
@@ -1307,8 +1372,8 @@
 		cmd[7] = 32768 >> 8;
 		cmd[8] = 32768 & 0xff;
 
-		SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, SCSI_DATA_READ,
-					    STp->timeout, MAX_READ_RETRIES, TRUE);
+		SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, DMA_FROM_DEVICE,
+					    STp->timeout, MAX_RETRIES, 1);
 	
 		if ((STp->buffer)->syscall_result || !SRpnt) {
 			printk(KERN_ERR "%s:E: Failed to read frame back from OnStream buffer\n", name);
@@ -1357,8 +1422,8 @@
 				vfree((void *)buffer);
 				return (-EIO);
 			}
-			flag = 0;
 			if ( i >= nframes + pending ) break;
+			flag = 0;
 		}
 		osst_copy_to_buffer(STp->buffer, p);
 		/*
@@ -1379,8 +1444,8 @@
 				name, new_frame+i, frame_seq_number+i, logical_blk_num + i*blks_per_frame,
 				p[0], p[1], p[2], p[3]);
 #endif
-		SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, SCSI_DATA_WRITE,
-					    STp->timeout, MAX_WRITE_RETRIES, TRUE);
+		SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE,
+					    STp->timeout, MAX_RETRIES, 1);
 
 		if (STp->buffer->syscall_result)
 			flag = 1;
@@ -1395,8 +1460,8 @@
 				memset(cmd, 0, MAX_COMMAND_SIZE);
 				cmd[0] = WRITE_FILEMARKS;
 				cmd[1] = 1;
-				SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, SCSI_DATA_NONE,
-							    STp->timeout, MAX_WRITE_RETRIES, TRUE);
+				SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
+							    STp->timeout, MAX_RETRIES, 1);
 #if DEBUG
 				if (debugging) {
 					printk(OSST_DEB_MSG "%s:D: Sleeping in re-write wait ready\n", name);
@@ -1410,8 +1475,8 @@
 					memset(cmd, 0, MAX_COMMAND_SIZE);
 					cmd[0] = TEST_UNIT_READY;
 
-					SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout,
-									 MAX_READY_RETRIES, TRUE);
+					SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout,
+												MAX_RETRIES, 1);
 
 					if (SRpnt->sr_sense_buffer[2] == 2 && SRpnt->sr_sense_buffer[12] == 4 &&
 					    (SRpnt->sr_sense_buffer[13] == 1 || SRpnt->sr_sense_buffer[13] == 8)) {
@@ -1448,29 +1513,34 @@
 #endif
 			osst_get_frame_position(STp, aSRpnt);
 #if DEBUG
-			printk(OSST_DEB_MSG "%s:D: reported frame positions: host = %d, tape = %d\n",
-					  name, STp->first_frame_position, STp->last_frame_position);
+			printk(OSST_DEB_MSG "%s:D: reported frame positions: host = %d, tape = %d, buffer = %d\n",
+					  name, STp->first_frame_position, STp->last_frame_position, STp->cur_frames);
 #endif
 		}
-	}    
+	}
+	if (flag) {
+		/* error recovery did not successfully complete */
+		printk(KERN_ERR "%s:D: Write error recovery failed in %s\n", name,
+				STp->write_type == OS_WRITE_HEADER?"header":"body");
+	}
 	if (!pending)
 		osst_copy_to_buffer(STp->buffer, p);	/* so buffer content == at entry in all cases */
 	vfree((void *)buffer);
 	return 0;
 }
 
-static int osst_reposition_and_retry(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt,
+static int osst_reposition_and_retry(struct osst_tape * STp, struct scsi_request ** aSRpnt,
 					unsigned int frame, unsigned int skip, int pending)
 {
-	unsigned char	cmd[MAX_COMMAND_SIZE];
-	Scsi_Request  * SRpnt;
-	char	      * name      = tape_name(STp);
-	int		expected  = 0;
-	int		attempts  = 1000 / skip;
-	int		flag      = 1;
-	unsigned long	startwait = jiffies;
+	unsigned char		cmd[MAX_COMMAND_SIZE];
+	struct scsi_request   * SRpnt;
+	char		      * name      = tape_name(STp);
+	int			expected  = 0;
+	int			attempts  = 1000 / skip;
+	int			flag      = 1;
+	unsigned long		startwait = jiffies;
 #if DEBUG
-	int		dbg       = debugging;
+	int			dbg       = debugging;
 #endif
 
 	while (attempts && time_before(jiffies, startwait + 60*HZ)) {
@@ -1511,8 +1581,8 @@
 			printk(OSST_DEB_MSG "%s:D: About to write pending fseq %d at fppos %d\n",
 					  name, STp->frame_seq_number-1, STp->first_frame_position);
 #endif
-			SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, SCSI_DATA_WRITE,
-						      STp->timeout, MAX_WRITE_RETRIES, TRUE);
+			SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE,
+						      STp->timeout, MAX_RETRIES, 1);
 			*aSRpnt = SRpnt;
 
 			if (STp->buffer->syscall_result) {		/* additional write error */
@@ -1550,6 +1620,7 @@
 			debugging = 0;
 		}
 #endif
+		set_current_state(TASK_INTERRUPTIBLE);
 		schedule_timeout(HZ / 10);
 	}
 	printk(KERN_ERR "%s:E: Failed to find valid tape media\n", name);
@@ -1563,14 +1634,14 @@
  * Error recovery algorithm for the OnStream tape.
  */
 
-static int osst_write_error_recovery(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int pending)
+static int osst_write_error_recovery(struct osst_tape * STp, struct scsi_request ** aSRpnt, int pending)
 {
-	Scsi_Request * SRpnt  = * aSRpnt;
+	struct scsi_request * SRpnt  = * aSRpnt;
 	struct st_partstat  * STps   = & STp->ps[STp->partition];
-	char         * name   = tape_name(STp);
-	int            retval = 0;
-	int            rw_state;
-	unsigned int  frame, skip;
+	char		    * name   = tape_name(STp);
+	int		      retval = 0;
+	int		      rw_state;
+	unsigned int	      frame, skip;
 
 	rw_state = STps->rw;
 
@@ -1635,12 +1706,14 @@
 	if (retval == 0) {
 		STp->recover_count++;
 		STp->recover_erreg++;
-	}
+	} else
+		STp->abort_count++;
+
 	STps->rw = rw_state;
 	return retval;
 }
 
-static int osst_space_over_filemarks_backward(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt,
+static int osst_space_over_filemarks_backward(struct osst_tape * STp, struct scsi_request ** aSRpnt,
 								 int mt_op, int mt_count)
 {
 	char  * name = tape_name(STp);
@@ -1739,7 +1812,7 @@
  *
  * Just scans for the filemark sequentially.
  */
-static int osst_space_over_filemarks_forward_slow(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt,
+static int osst_space_over_filemarks_forward_slow(struct osst_tape * STp, struct scsi_request ** aSRpnt,
 								     int mt_op, int mt_count)
 {
 	int	cnt = 0;
@@ -1793,7 +1866,7 @@
 /*
  * Fast linux specific version of OnStream FSF
  */
-static int osst_space_over_filemarks_forward_fast(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt,
+static int osst_space_over_filemarks_forward_fast(struct osst_tape * STp, struct scsi_request ** aSRpnt,
 								     int mt_op, int mt_count)
 {
 	char  * name = tape_name(STp);
@@ -1944,11 +2017,11 @@
  * to test the error recovery mechanism.
  */
 #if DEBUG
-static void osst_set_retries(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int retries)
+static void osst_set_retries(struct osst_tape * STp, struct scsi_request ** aSRpnt, int retries)
 {
-	unsigned char	cmd[MAX_COMMAND_SIZE];
-	Scsi_Request  * SRpnt  = * aSRpnt;
-	char          * name   = tape_name(STp);
+	unsigned char		cmd[MAX_COMMAND_SIZE];
+	struct scsi_request   * SRpnt  = * aSRpnt;
+	char		      * name   = tape_name(STp);
 
 	memset(cmd, 0, MAX_COMMAND_SIZE);
 	cmd[0] = MODE_SELECT;
@@ -1967,7 +2040,7 @@
 	if (debugging)
 	    printk(OSST_DEB_MSG "%s:D: Setting number of retries on OnStream tape to %d\n", name, retries);
 
-	SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], SCSI_DATA_WRITE, STp->timeout, 0, TRUE);
+	SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1);
 	*aSRpnt = SRpnt;
 
 	if ((STp->buffer)->syscall_result)
@@ -1976,7 +2049,7 @@
 #endif
 
 
-static int osst_write_filemark(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt)
+static int osst_write_filemark(struct osst_tape * STp, struct scsi_request ** aSRpnt)
 {
 	int	result;
 	int	this_mark_ppos = STp->first_frame_position;
@@ -2004,7 +2077,7 @@
 	return result;
 }
 
-static int osst_write_eod(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt)
+static int osst_write_eod(struct osst_tape * STp, struct scsi_request ** aSRpnt)
 {
 	int	result;
 #if DEBUG
@@ -2027,7 +2100,7 @@
 	return result;
 }
 
-static int osst_write_filler(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int where, int count)
+static int osst_write_filler(struct osst_tape * STp, struct scsi_request ** aSRpnt, int where, int count)
 {
 	char * name = tape_name(STp);
 
@@ -2052,7 +2125,7 @@
 	return osst_flush_drive_buffer(STp, aSRpnt);
 }
 
-static int __osst_write_header(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int where, int count)
+static int __osst_write_header(struct osst_tape * STp, struct scsi_request ** aSRpnt, int where, int count)
 {
 	char * name = tape_name(STp);
 	int     result;
@@ -2079,7 +2152,7 @@
 	return result;
 }
 
-static int osst_write_header(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int locate_eod)
+static int osst_write_header(struct osst_tape * STp, struct scsi_request ** aSRpnt, int locate_eod)
 {
 	os_header_t * header;
 	int	      result;
@@ -2153,7 +2226,7 @@
 	return result;
 }
 
-static int osst_reset_header(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt)
+static int osst_reset_header(struct osst_tape * STp, struct scsi_request ** aSRpnt)
 {
 	if (STp->header_cache != NULL)
 		memset(STp->header_cache, 0, sizeof(os_header_t));
@@ -2166,7 +2239,7 @@
 	return osst_write_header(STp, aSRpnt, 1);
 }
 
-static int __osst_analyze_headers(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int ppos)
+static int __osst_analyze_headers(struct osst_tape * STp, struct scsi_request ** aSRpnt, int ppos)
 {
 	char        * name = tape_name(STp);
 	os_header_t * header;
@@ -2343,7 +2416,7 @@
 	return 1;
 }
 
-static int osst_analyze_headers(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt)
+static int osst_analyze_headers(struct osst_tape * STp, struct scsi_request ** aSRpnt)
 {
 	int	position, ppos;
 	int	first, last;
@@ -2398,7 +2471,7 @@
 	return 1;
 }
 
-static int osst_verify_position(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt)
+static int osst_verify_position(struct osst_tape * STp, struct scsi_request ** aSRpnt)
 {
 	int	frame_position  = STp->first_frame_position;
 	int	frame_seq_numbr = STp->frame_seq_number;
@@ -2474,11 +2547,11 @@
 /*
  * Configure the OnStream SCII tape drive for default operation
  */
-static int osst_configure_onstream(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt)
+static int osst_configure_onstream(struct osst_tape *STp, struct scsi_request ** aSRpnt)
 {
 	unsigned char                  cmd[MAX_COMMAND_SIZE];
 	char                         * name = tape_name(STp);
-	Scsi_Request                 * SRpnt = * aSRpnt;
+	struct scsi_request                 * SRpnt = * aSRpnt;
 	osst_mode_parameter_header_t * header;
 	osst_block_size_page_t       * bs;
 	osst_capabilities_page_t     * cp;
@@ -2507,7 +2580,7 @@
 	cmd[2] = BLOCK_SIZE_PAGE;
 	cmd[4] = BLOCK_SIZE_PAGE_LENGTH + MODE_HEADER_LENGTH;
 
-	SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], SCSI_DATA_READ, STp->timeout, 0, TRUE);
+	SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1);
 	if (SRpnt == NULL) {
 #if DEBUG
  	    printk(OSST_DEB_MSG "osst :D: Busy\n");
@@ -2544,7 +2617,7 @@
 	cmd[1] = 0x10;
 	cmd[4] = BLOCK_SIZE_PAGE_LENGTH + MODE_HEADER_LENGTH;
 
-	SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], SCSI_DATA_WRITE, STp->timeout, 0, TRUE);
+	SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1);
 	*aSRpnt = SRpnt;
 	if ((STp->buffer)->syscall_result != 0) {
 	    printk (KERN_ERR "%s:E: Couldn't set tape block size mode page\n", name);
@@ -2584,7 +2657,7 @@
 	(STp->buffer)->b_data[MODE_HEADER_LENGTH + 6] = 0;
 	(STp->buffer)->b_data[MODE_HEADER_LENGTH + 7] = 0;
 
-	SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], SCSI_DATA_WRITE, STp->timeout, 0, TRUE);
+	SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1);
 	*aSRpnt = SRpnt;
 
 	if ((STp->buffer)->syscall_result != 0) {
@@ -2599,7 +2672,7 @@
 	cmd[2] = CAPABILITIES_PAGE;
 	cmd[4] = CAPABILITIES_PAGE_LENGTH + MODE_HEADER_LENGTH;
 
-	SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], SCSI_DATA_READ, STp->timeout, 0, TRUE);
+	SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1);
 	*aSRpnt = SRpnt;
 
 	if ((STp->buffer)->syscall_result != 0) {
@@ -2619,7 +2692,7 @@
 	cmd[2] = TAPE_PARAMTR_PAGE;
 	cmd[4] = TAPE_PARAMTR_PAGE_LENGTH + MODE_HEADER_LENGTH;
 
-	SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], SCSI_DATA_READ, STp->timeout, 0, TRUE);
+	SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1);
 	*aSRpnt = SRpnt;
 
 	if ((STp->buffer)->syscall_result != 0) {
@@ -2645,7 +2718,7 @@
 
 /* Step over EOF if it has been inadvertently crossed (ioctl not used because
    it messes up the block number). */
-static int cross_eof(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt, int forward)
+static int cross_eof(struct osst_tape *STp, struct scsi_request ** aSRpnt, int forward)
 {
 	int	result;
 	char  * name = tape_name(STp);
@@ -2674,18 +2747,18 @@
 
 /* Get the tape position. */
 
-static int osst_get_frame_position(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt)
+static int osst_get_frame_position(struct osst_tape *STp, struct scsi_request ** aSRpnt)
 {
-	unsigned char	scmd[MAX_COMMAND_SIZE];
-	Scsi_Request  * SRpnt;
-	int		result = 0;
+	unsigned char		scmd[MAX_COMMAND_SIZE];
+	struct scsi_request   * SRpnt;
+	int			result = 0;
+	char    	      * name   = tape_name(STp);
 
 	/* KG: We want to be able to use it for checking Write Buffer availability
 	 *  and thus don't want to risk to overwrite anything. Exchange buffers ... */
 	char		mybuf[24];
 	char	      * olddata = STp->buffer->b_data;
 	int		oldsize = STp->buffer->buffer_size;
-	char          * name    = tape_name(STp);
 
 	if (STp->ready != ST_READY) return (-EIO);
 
@@ -2693,8 +2766,8 @@
 	scmd[0] = READ_POSITION;
 
 	STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24;
-	SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 20, SCSI_DATA_READ,
-				      STp->timeout, MAX_RETRIES, TRUE);
+	SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 20, DMA_FROM_DEVICE,
+				      STp->timeout, MAX_RETRIES, 1);
 	if (!SRpnt) {
 		STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize;
 		return (-EBUSY);
@@ -2702,22 +2775,28 @@
 	*aSRpnt = SRpnt;
 
 	if (STp->buffer->syscall_result)
-		result = ((SRpnt->sr_sense_buffer[2] & 0x0f) == 3) ? -EIO : -EINVAL;
+		result = ((SRpnt->sr_sense_buffer[2] & 0x0f) == 3) ? -EIO : -EINVAL;	/* 3: Write Error */
 
 	if (result == -EINVAL)
 		printk(KERN_ERR "%s:E: Can't read tape position.\n", name);
 	else {
-
-		if (result == -EIO) {	/* re-read position */
+		if (result == -EIO) {	/* re-read position - this needs to preserve media errors */
 			unsigned char mysense[16];
 			memcpy (mysense, SRpnt->sr_sense_buffer, 16);
 			memset (scmd, 0, MAX_COMMAND_SIZE);
 			scmd[0] = READ_POSITION;
 			STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24;
-			SRpnt = osst_do_scsi(SRpnt, STp, scmd, 20, SCSI_DATA_READ,
-						    STp->timeout, MAX_RETRIES, TRUE);
+			SRpnt = osst_do_scsi(SRpnt, STp, scmd, 20, DMA_FROM_DEVICE,
+						    STp->timeout, MAX_RETRIES, 1);
+#if DEBUG
+			printk(OSST_DEB_MSG "%s:D: Reread position, reason=[%02x:%02x:%02x], result=[%s%02x:%02x:%02x]\n",
+					name, mysense[2], mysense[12], mysense[13], STp->buffer->syscall_result?"":"ok:",
+					SRpnt->sr_sense_buffer[2],SRpnt->sr_sense_buffer[12],SRpnt->sr_sense_buffer[13]);
+#endif
 			if (!STp->buffer->syscall_result)
 				memcpy (SRpnt->sr_sense_buffer, mysense, 16);
+			else
+				printk(KERN_WARNING "%s:W: Double error in get position\n", name);
 		}
 		STp->first_frame_position = ((STp->buffer)->b_data[4] << 24)
 					  + ((STp->buffer)->b_data[5] << 16)
@@ -2739,7 +2818,7 @@
 #endif
 		if (STp->cur_frames == 0 && STp->first_frame_position != STp->last_frame_position) {
 #if DEBUG
-			printk(KERN_WARNING "%s:D: Correcting read position %d, %d, %d\n", name,
+			printk(OSST_DEB_MSG "%s:D: Correcting read position %d, %d, %d\n", name,
 					STp->first_frame_position, STp->last_frame_position, STp->cur_frames);
 #endif
 			STp->first_frame_position = STp->last_frame_position;
@@ -2752,14 +2831,14 @@
 
 
 /* Set the tape block */
-static int osst_set_frame_position(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt, int ppos, int skip)
+static int osst_set_frame_position(struct osst_tape *STp, struct scsi_request ** aSRpnt, int ppos, int skip)
 {
-	unsigned char	scmd[MAX_COMMAND_SIZE];
-	Scsi_Request  * SRpnt;
-	struct st_partstat   * STps;
-	int		result = 0;
-	int		pp     = (ppos == 3000 && !skip)? 0 : ppos;
-	char          * name   = tape_name(STp);
+	unsigned char		scmd[MAX_COMMAND_SIZE];
+	struct scsi_request   * SRpnt;
+	struct st_partstat    * STps;
+	int			result = 0;
+	int			pp     = (ppos == 3000 && !skip)? 0 : ppos;
+	char		      * name   = tape_name(STp);
 
 	if (STp->ready != ST_READY) return (-EIO);
 
@@ -2786,8 +2865,8 @@
 		if (skip)
 			scmd[9] = 0x80;
 
-		SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 0, SCSI_DATA_NONE, STp->long_timeout,
-								MAX_RETRIES, TRUE);
+		SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 0, DMA_NONE, STp->long_timeout,
+								MAX_RETRIES, 1);
 		if (!SRpnt)
 			return (-EBUSY);
 		*aSRpnt  = SRpnt;
@@ -2810,7 +2889,7 @@
 	return result;
 }
 
-static int osst_write_trailer(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt, int leave_at_EOT)
+static int osst_write_trailer(struct osst_tape *STp, struct scsi_request ** aSRpnt, int leave_at_EOT)
 {
 	struct st_partstat * STps = &(STp->ps[STp->partition]);
 	int result = 0;
@@ -2837,26 +2916,26 @@
 /* osst versions of st functions - augmented and stripped to suit OnStream only */
 
 /* Flush the write buffer (never need to write if variable blocksize). */
-static int osst_flush_write_buffer(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt)
+static int osst_flush_write_buffer(struct osst_tape *STp, struct scsi_request ** aSRpnt)
 {
-	int            offset, transfer, blks = 0;
-	int            result = 0;
-	unsigned char  cmd[MAX_COMMAND_SIZE];
-	Scsi_Request * SRpnt = *aSRpnt;
-	struct st_partstat  * STps;
-	char         * name = tape_name(STp);
+	int			offset, transfer, blks = 0;
+	int			result = 0;
+	unsigned char		cmd[MAX_COMMAND_SIZE];
+	struct scsi_request   * SRpnt = *aSRpnt;
+	struct st_partstat    * STps;
+	char		      * name = tape_name(STp);
 
 	if ((STp->buffer)->writing) {
 		if (SRpnt == (STp->buffer)->last_SRpnt)
 #if DEBUG
 			{ printk(OSST_DEB_MSG
-	 "%s:D: aSRpnt points to Scsi_Request that write_behind_check will release -- cleared\n", name);
+	 "%s:D: aSRpnt points to scsi_request that write_behind_check will release -- cleared\n", name);
 #endif
 			*aSRpnt = SRpnt = NULL;
 #if DEBUG
 			} else if (SRpnt)
 				printk(OSST_DEB_MSG
-	 "%s:D: aSRpnt does not point to Scsi_Request that write_behind_check will release -- strange\n", name);
+	 "%s:D: aSRpnt does not point to scsi_request that write_behind_check will release -- strange\n", name);
 #endif	
 		osst_write_behind_check(STp);
 		if ((STp->buffer)->syscall_result) {
@@ -2884,9 +2963,9 @@
 		if (offset < OS_DATA_SIZE)
 			osst_zero_buffer_tail(STp->buffer);
 
-		/* TODO: Error handling! */
 		if (STp->poll)
-			result = osst_wait_frame (STp, aSRpnt, STp->first_frame_position, -50, 120);
+			if (osst_wait_frame (STp, aSRpnt, STp->first_frame_position, -50, 120))
+				result = osst_recover_wait_frame(STp, aSRpnt, 1);
 
 		memset(cmd, 0, MAX_COMMAND_SIZE);
 		cmd[0] = WRITE_6;
@@ -2924,8 +3003,8 @@
 			  			 name, offset, transfer, blks);
 #endif
 
-		SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, transfer, SCSI_DATA_WRITE,
-					  STp->timeout, MAX_WRITE_RETRIES, TRUE);
+		SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, transfer, DMA_TO_DEVICE,
+					      STp->timeout, MAX_RETRIES, 1);
 		*aSRpnt = SRpnt;
 		if (!SRpnt)
 			return (-EBUSY);
@@ -2967,12 +3046,12 @@
 
 /* Flush the tape buffer. The tape will be positioned correctly unless
    seek_next is true. */
-static int osst_flush_buffer(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int seek_next)
+static int osst_flush_buffer(struct osst_tape * STp, struct scsi_request ** aSRpnt, int seek_next)
 {
 	struct st_partstat * STps;
-	int           backspace = 0, result = 0;
+	int    backspace = 0, result = 0;
 #if DEBUG
-	char        * name = tape_name(STp);
+	char * name = tape_name(STp);
 #endif
 
 	/*
@@ -3007,7 +3086,7 @@
 
 	if (!seek_next) {
 		if (STps->eof == ST_FM_HIT) {
-			result = cross_eof(STp, aSRpnt, FALSE); /* Back over the EOF hit */
+			result = cross_eof(STp, aSRpnt, 0); /* Back over the EOF hit */
 			if (!result)
 				STps->eof = ST_NOEOF;
 			else {
@@ -3029,13 +3108,13 @@
 	return result;
 }
 
-static int osst_write_frame(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int synchronous)
+static int osst_write_frame(struct osst_tape * STp, struct scsi_request ** aSRpnt, int synchronous)
 {
-	unsigned char	cmd[MAX_COMMAND_SIZE];
-	Scsi_Request  * SRpnt;
-	int		blks;
+	unsigned char		cmd[MAX_COMMAND_SIZE];
+	struct scsi_request   * SRpnt;
+	int			blks;
 #if DEBUG
-	char          * name = tape_name(STp);
+	char		      * name = tape_name(STp);
 #endif
 
 	if ((!STp-> raw) && (STp->first_frame_position == 0xbae)) { /* _must_ preserve buffer! */
@@ -3055,8 +3134,9 @@
 	}
 
 	if (STp->poll)
-		osst_wait_frame (STp, aSRpnt, STp->first_frame_position, -50, 60);
-	/* TODO: Check for an error ! */
+		if (osst_wait_frame (STp, aSRpnt, STp->first_frame_position, -48, 120))
+			if (osst_recover_wait_frame(STp, aSRpnt, 1))
+				return (-EIO);
 
 //	osst_build_stats(STp, &SRpnt);
 
@@ -3080,8 +3160,8 @@
 	if (!synchronous)
 		STp->write_pending = 1;
 #endif
-	SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, SCSI_DATA_WRITE, STp->timeout,
-							MAX_WRITE_RETRIES, synchronous);
+	SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE, STp->timeout,
+									MAX_RETRIES, synchronous);
 	if (!SRpnt)
 		return (-EBUSY);
 	*aSRpnt = SRpnt;
@@ -3111,8 +3191,8 @@
 	return 0;
 }
 
-/* Lock or unlock the drive door. Don't use when Scsi_Request allocated. */
-static int do_door_lock(OS_Scsi_Tape * STp, int do_lock)
+/* Lock or unlock the drive door. Don't use when struct scsi_request allocated. */
+static int do_door_lock(struct osst_tape * STp, int do_lock)
 {
 	int retval, cmd;
 
@@ -3131,7 +3211,7 @@
 }
 
 /* Set the internal state after reset */
-static void reset_state(OS_Scsi_Tape *STp)
+static void reset_state(struct osst_tape *STp)
 {
 	int i;
 	struct st_partstat *STps;
@@ -3142,7 +3222,7 @@
 		STps->rw = ST_IDLE;
 		STps->eof = ST_NOEOF;
 		STps->at_sm = 0;
-		STps->last_block_valid = FALSE;
+		STps->last_block_valid = 0;
 		STps->drv_block = -1;
 		STps->drv_file = -1;
 	}
@@ -3154,16 +3234,16 @@
 /* Write command */
 static ssize_t osst_write(struct file * filp, const char __user * buf, size_t count, loff_t *ppos)
 {
-	ssize_t        total, retval = 0;
-	ssize_t        i, do_count, blks, transfer;
-	int            write_threshold;
-	int            doing_write = 0;
+	ssize_t		      total, retval = 0;
+	ssize_t		      i, do_count, blks, transfer;
+	int		      write_threshold;
+	int		      doing_write = 0;
 	const char   __user * b_point;
-	Scsi_Request * SRpnt = NULL;
+	struct scsi_request * SRpnt = NULL;
 	struct st_modedef   * STm;
 	struct st_partstat  * STps;
-	OS_Scsi_Tape * STp  = filp->private_data;
-	char         * name = tape_name(STp);
+	struct osst_tape    * STp  = filp->private_data;
+	char		    * name = tape_name(STp);
 
 
 	if (down_interruptible(&STp->lock))
@@ -3296,7 +3376,7 @@
 #endif
 			}
 		}
-		STp->fast_open = FALSE;
+		STp->fast_open = 0;
 	}
 	if (!STp->header_ok) {
 #if DEBUG
@@ -3371,7 +3451,7 @@
 		blks = do_count / STp->block_size;
 		STp->logical_blk_num += blks;  /* logical_blk_num is incremented as data is moved from user */
   
-		i = osst_write_frame(STp, &SRpnt, TRUE);
+		i = osst_write_frame(STp, &SRpnt, 1);
 
 		if (i == (-ENOSPC)) {
 			transfer = STp->buffer->writing;	/* FIXME -- check this logic */
@@ -3452,7 +3532,7 @@
 		STp->dirty = !((STp->buffer)->writing ==
 				          (STp->buffer)->buffer_bytes);
 
-		i = osst_write_frame(STp, &SRpnt, FALSE);
+		i = osst_write_frame(STp, &SRpnt, 0);
 		if (i < 0) {
 			retval = (-EIO);
 			goto out;
@@ -3477,14 +3557,14 @@
 /* Read command */
 static ssize_t osst_read(struct file * filp, char __user * buf, size_t count, loff_t *ppos)
 {
-	ssize_t        total, retval = 0;
-	ssize_t        i, transfer;
-	int            special;
-	struct st_modedef      * STm;
+	ssize_t		      total, retval = 0;
+	ssize_t		      i, transfer;
+	int		      special;
+	struct st_modedef   * STm;
 	struct st_partstat  * STps;
-	Scsi_Request * SRpnt = NULL;
-	OS_Scsi_Tape * STp   = filp->private_data;
-	char         * name  = tape_name(STp);
+	struct scsi_request * SRpnt = NULL;
+	struct osst_tape    * STp   = filp->private_data;
+	char		    * name  = tape_name(STp);
 
 
 	if (down_interruptible(&STp->lock))
@@ -3660,8 +3740,7 @@
 
 
 /* Set the driver options */
-static void osst_log_options(OS_Scsi_Tape *STp, struct st_modedef *STm,
-			     char *name)
+static void osst_log_options(struct osst_tape *STp, struct st_modedef *STm, char *name)
 {
   printk(KERN_INFO
 "%s:I: Mode %d options: buffer writes: %d, async writes: %d, read ahead: %d\n",
@@ -3684,17 +3763,17 @@
 }
 
 
-static int osst_set_options(OS_Scsi_Tape *STp, long options)
+static int osst_set_options(struct osst_tape *STp, long options)
 {
-	int       value;
-	long      code;
+	int		    value;
+	long		    code;
 	struct st_modedef * STm;
-	char    * name = tape_name(STp);
+	char		  * name = tape_name(STp);
 
 	STm = &(STp->modes[STp->current_mode]);
 	if (!STm->defined) {
 		memcpy(STm, &(STp->modes[0]), sizeof(*STm));
-		modes_defined = TRUE;
+		modes_defined = 1;
 #if DEBUG
 		if (debugging)
 			printk(OSST_DEB_MSG "%s:D: Initialized mode %d definition from mode 0\n",
@@ -3840,18 +3919,19 @@
 
 
 /* Internal ioctl function */
-static int osst_int_ioctl(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, unsigned int cmd_in, unsigned long arg)
+static int osst_int_ioctl(struct osst_tape * STp, struct scsi_request ** aSRpnt,
+			     unsigned int cmd_in, unsigned long arg)
 {
-	int            timeout;
-	long           ltmp;
-	int            i, ioctl_result;
-	int            chg_eof = TRUE;
-	unsigned char  cmd[MAX_COMMAND_SIZE];
-	Scsi_Request * SRpnt = * aSRpnt;
-	struct st_partstat  * STps;
-	int            fileno, blkno, at_sm, frame_seq_numbr, logical_blk_num;
-	int            datalen = 0, direction = SCSI_DATA_NONE;
-	char         * name = tape_name(STp);
+	int			timeout;
+	long			ltmp;
+	int			i, ioctl_result;
+	int			chg_eof = 1;
+	unsigned char		cmd[MAX_COMMAND_SIZE];
+	struct scsi_request   * SRpnt = * aSRpnt;
+	struct st_partstat    * STps;
+	int			fileno, blkno, at_sm, frame_seq_numbr, logical_blk_num;
+	int			datalen = 0, direction = DMA_NONE;
+	char		      * name = tape_name(STp);
 
 	if (STp->ready != ST_READY && cmd_in != MTLOAD) {
 		if (STp->ready == ST_NO_TAPE)
@@ -3870,7 +3950,7 @@
 	memset(cmd, 0, MAX_COMMAND_SIZE);
 	switch (cmd_in) {
 	 case MTFSFM:
-		chg_eof = FALSE; /* Changed from the FSF after this */
+		chg_eof = 0; /* Changed from the FSF after this */
 	 case MTFSF:
 		if (STp->raw)
 		   return (-EIO);
@@ -3885,7 +3965,7 @@
 		goto os_bypass;
 
 	 case MTBSF:
-		chg_eof = FALSE; /* Changed from the FSF after this */
+		chg_eof = 0; /* Changed from the FSF after this */
 	 case MTBSFM:
 		if (STp->raw)
 		   return (-EIO);
@@ -4100,7 +4180,7 @@
 	 case MTSETDENSITY:       /* Set tape density */
 	 case MTSETDRVBUFFER:     /* Set drive buffering */
 	 case SET_DENS_AND_BLK:   /* Set density and block size */
-		 chg_eof = FALSE;
+		 chg_eof = 0;
 		 if (STp->dirty || (STp->buffer)->buffer_bytes != 0)
 			 return (-EIO);       /* Not allowed if data in buffer */
 		 if ((cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) &&
@@ -4117,7 +4197,7 @@
 		return (-ENOSYS);
 	}
 
-	SRpnt = osst_do_scsi(SRpnt, STp, cmd, datalen, direction, timeout, MAX_RETRIES, TRUE);
+	SRpnt = osst_do_scsi(SRpnt, STp, cmd, datalen, direction, timeout, MAX_RETRIES, 1);
 
 	ioctl_result = (STp->buffer)->syscall_result;
 
@@ -4173,7 +4253,7 @@
 		else if (cmd_in == MTLOAD) {
 			for (i=0; i < ST_NBR_PARTITIONS; i++) {
 			    STp->ps[i].rw = ST_IDLE;
-			    STp->ps[i].last_block_valid = FALSE;/* FIXME - where else is this field maintained? */
+			    STp->ps[i].last_block_valid = 0;/* FIXME - where else is this field maintained? */
 			}
 			STp->partition = 0;
 		}
@@ -4227,16 +4307,16 @@
 /* Open the device */
 static int os_scsi_tape_open(struct inode * inode, struct file * filp)
 {
-	unsigned short flags;
-	int            i, b_size, new_session = FALSE, retval = 0;
-	unsigned char  cmd[MAX_COMMAND_SIZE];
-	Scsi_Request * SRpnt = NULL;
-	OS_Scsi_Tape * STp;
-	struct st_modedef      * STm;
+	unsigned short	      flags;
+	int		      i, b_size, new_session = 0, retval = 0;
+	unsigned char	      cmd[MAX_COMMAND_SIZE];
+	struct scsi_request * SRpnt = NULL;
+	struct osst_tape    * STp;
+	struct st_modedef   * STm;
 	struct st_partstat  * STps;
-	char         * name;
-	int            dev  = TAPE_NR(inode);
-	int            mode = TAPE_MODE(inode);
+	char		    * name;
+	int		      dev  = TAPE_NR(inode);
+	int		      mode = TAPE_MODE(inode);
 
 	nonseekable_open(inode, filp);
 	write_lock(&os_scsi_tapes_lock);
@@ -4277,7 +4357,7 @@
 			printk(OSST_DEB_MSG "%s:D: Mode change from %d to %d.\n",
 					       name, STp->current_mode, mode);
 #endif
-		new_session = TRUE;
+		new_session = 1;
 		STp->current_mode = mode;
 	}
 	STm = &(STp->modes[STp->current_mode]);
@@ -4327,9 +4407,9 @@
 	memset (cmd, 0, MAX_COMMAND_SIZE);
 	cmd[0] = TEST_UNIT_READY;
 
-	SRpnt = osst_do_scsi(NULL, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_READY_RETRIES, TRUE);
+	SRpnt = osst_do_scsi(NULL, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
 	if (!SRpnt) {
-		retval = (STp->buffer)->syscall_result;
+		retval = (STp->buffer)->syscall_result;		/* FIXME - valid? */
 		goto err_out;
 	}
 	if ((SRpnt->sr_sense_buffer[0] & 0x70) == 0x70      &&
@@ -4347,8 +4427,8 @@
         		cmd[0] = START_STOP;
 			cmd[1] = 1;
 			cmd[4] = 1;
-			SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, SCSI_DATA_NONE,
-					     STp->timeout, MAX_READY_RETRIES, TRUE);
+			SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
+					     STp->timeout, MAX_RETRIES, 1);
 		}
 		osst_wait_ready(STp, &SRpnt, (SRpnt->sr_sense_buffer[13]==1?15:3) * 60, 0);
 	}
@@ -4364,8 +4444,8 @@
 			memset (cmd, 0, MAX_COMMAND_SIZE);
 			cmd[0] = TEST_UNIT_READY;
 
-			SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, SCSI_DATA_NONE,
-					     STp->timeout, MAX_READY_RETRIES, TRUE);
+			SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
+					     STp->timeout, MAX_RETRIES, 1);
 			if ((SRpnt->sr_sense_buffer[0] & 0x70) != 0x70 ||
 			    (SRpnt->sr_sense_buffer[2] & 0x0f) != UNIT_ATTENTION)
 				break;
@@ -4380,12 +4460,13 @@
 			STps->rw = ST_IDLE;		/* FIXME - seems to be redundant... */
 			STps->eof = ST_NOEOF;
 			STps->at_sm = 0;
-			STps->last_block_valid = FALSE;
+			STps->last_block_valid = 0;
 			STps->drv_block = 0;
 			STps->drv_file = 0 ;
 		}
-		new_session = TRUE;
+		new_session = 1;
 		STp->recover_count = 0;
+		STp->abort_count = 0;
 	}
 	/*
 	 * if we have valid headers from before, and the drive/tape seem untouched,
@@ -4400,7 +4481,7 @@
 		cmd[2] = VENDOR_IDENT_PAGE;
 		cmd[4] = VENDOR_IDENT_PAGE_LENGTH + MODE_HEADER_LENGTH;
 
-		SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], SCSI_DATA_READ, STp->timeout, 0, TRUE);
+		SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1);
 
 		if (STp->buffer->syscall_result                     ||
 		    STp->buffer->b_data[MODE_HEADER_LENGTH + 2] != 'L' ||
@@ -4430,7 +4511,7 @@
 				STp->buffer->buffer_bytes = STp->buffer->read_pointer = 0;
 			}
 			STp->buffer->buffer_blocks = OS_DATA_SIZE / STp->block_size;
-			STp->fast_open = TRUE;
+			STp->fast_open = 1;
 			scsi_release_request(SRpnt);
 			return 0;
 		}
@@ -4441,7 +4522,7 @@
 #endif
 		STp->header_ok = 0;
 	}
-	STp->fast_open = FALSE;
+	STp->fast_open = 0;
 
 	if ((STp->buffer)->syscall_result != 0 &&   /* in all error conditions except no medium */ 
 	    (SRpnt->sr_sense_buffer[2] != 2 || SRpnt->sr_sense_buffer[12] != 0x3A) ) {
@@ -4463,7 +4544,7 @@
 #if DEBUG
 		printk(OSST_DEB_MSG "%s:D: Applying soft reset\n", name);
 #endif
-		SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], SCSI_DATA_WRITE, STp->timeout, 0, TRUE);
+		SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1);
 
 		STp->header_ok = 0;
 
@@ -4472,8 +4553,8 @@
 			memset (cmd, 0, MAX_COMMAND_SIZE);
 			cmd[0] = TEST_UNIT_READY;
 
-			SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, SCSI_DATA_NONE,
-					     STp->timeout, MAX_READY_RETRIES, TRUE);
+			SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
+						    STp->timeout, MAX_RETRIES, 1);
 			if ((SRpnt->sr_sense_buffer[0] & 0x70) != 0x70 ||
 			    (SRpnt->sr_sense_buffer[2] & 0x0f) == NOT_READY)
 			break;
@@ -4488,11 +4569,11 @@
 					STps->rw = ST_IDLE;
 					STps->eof = ST_NOEOF;
 					STps->at_sm = 0;
-					STps->last_block_valid = FALSE;
+					STps->last_block_valid = 0;
 					STps->drv_block = 0;
 					STps->drv_file = 0 ;
 				}
-				new_session = TRUE;
+				new_session = 1;
 			}
 		}
 	}
@@ -4552,8 +4633,8 @@
 		if (debugging)
 	printk(OSST_DEB_MSG "%s:D: New Session\n", name);
 #endif
-		STp->density_changed = STp->blksize_changed = FALSE;
-		STp->compression_changed = FALSE;
+		STp->density_changed = STp->blksize_changed = 0;
+		STp->compression_changed = 0;
 	}
 
 	/*
@@ -4588,12 +4669,12 @@
 /* Flush the tape buffer before close */
 static int os_scsi_tape_flush(struct file * filp)
 {
-	int            result = 0, result2;
-	OS_Scsi_Tape * STp  = filp->private_data;
-	struct st_modedef      * STm  = &(STp->modes[STp->current_mode]);
-	struct st_partstat  * STps = &(STp->ps[STp->partition]);
-	Scsi_Request * SRpnt = NULL;
-	char         * name = tape_name(STp);
+	int		      result = 0, result2;
+	struct osst_tape    * STp    = filp->private_data;
+	struct st_modedef   * STm    = &(STp->modes[STp->current_mode]);
+	struct st_partstat  * STps   = &(STp->ps[STp->partition]);
+	struct scsi_request * SRpnt  = NULL;
+	char		    * name   = tape_name(STp);
 
 	if (file_count(filp) > 1)
 		return 0;
@@ -4627,7 +4708,7 @@
 			if (STp->can_bsr)
 				result = osst_flush_buffer(STp, &SRpnt, 0); /* this is the default path */
 			else if (STps->eof == ST_FM_HIT) {
-				result = cross_eof(STp, &SRpnt, FALSE);
+				result = cross_eof(STp, &SRpnt, 0);
 					if (result) {
 						if (STps->drv_file >= 0)
 							STps->drv_file++;
@@ -4639,7 +4720,7 @@
 			}
 		}
 		else if ((STps->eof == ST_NOEOF &&
-			  !(result = cross_eof(STp, &SRpnt, TRUE))) ||
+			  !(result = cross_eof(STp, &SRpnt, 1))) ||
 			 STps->eof == ST_FM_HIT) {
 			if (STps->drv_file >= 0)
 				STps->drv_file++;
@@ -4657,14 +4738,19 @@
 	}
 	if (SRpnt) scsi_release_request(SRpnt);
 
-	if (STp->recover_count) {
-		printk(KERN_INFO "%s:I: %d recovered errors in", name, STp->recover_count);
+	if (STp->abort_count || STp->recover_count) {
+		printk(KERN_INFO "%s:I:", name);
+		if (STp->abort_count)
+			printk(" %d unrecovered errors", STp->abort_count);
+		if (STp->recover_count)
+			printk(" %d recovered errors", STp->recover_count);
 		if (STp->write_count)
-			printk(" %d frames written", STp->write_count);
+			printk(" in %d frames written", STp->write_count);
 		if (STp->read_count)
-			printk(" %d frames read", STp->read_count);
+			printk(" in %d frames read", STp->read_count);
 		printk("\n");
 		STp->recover_count = 0;
+		STp->abort_count   = 0;
 	}
 	STp->write_count = 0;
 	STp->read_count  = 0;
@@ -4676,9 +4762,9 @@
 /* Close the device and release it */
 static int os_scsi_tape_close(struct inode * inode, struct file * filp)
 {
-	int result = 0;
-	OS_Scsi_Tape * STp = filp->private_data;
-	Scsi_Request * SRpnt = NULL;
+	int		      result = 0;
+	struct osst_tape    * STp    = filp->private_data;
+	struct scsi_request * SRpnt  = NULL;
 
 	if (SRpnt) scsi_release_request(SRpnt);
 
@@ -4703,14 +4789,14 @@
 static int osst_ioctl(struct inode * inode,struct file * file,
 	 unsigned int cmd_in, unsigned long arg)
 {
-	int            i, cmd_nr, cmd_type, retval = 0;
-	unsigned int   blk;
-	struct st_modedef      * STm;
+	int		      i, cmd_nr, cmd_type, retval = 0;
+	unsigned int	      blk;
+	struct st_modedef   * STm;
 	struct st_partstat  * STps;
-	Scsi_Request * SRpnt = NULL;
-	OS_Scsi_Tape * STp   = file->private_data;
-	char         * name  = tape_name(STp);
-	void __user *p = (void __user *)arg;
+	struct scsi_request * SRpnt = NULL;
+	struct osst_tape    * STp   = file->private_data;
+	char		    * name  = tape_name(STp);
+	void	    __user  * p     = (void __user *)arg;
 
 	if (down_interruptible(&STp->lock))
 		return -ERESTARTSYS;
@@ -4889,7 +4975,7 @@
 			for (i=0; i < ST_NBR_PARTITIONS; i++) {
 				STp->ps[i].rw = ST_IDLE;
 				STp->ps[i].at_sm = 0;
-				STp->ps[i].last_block_valid = FALSE;
+				STp->ps[i].last_block_valid = 0;
 			}
 			STp->partition = STp->new_partition = 0;
 			STp->nbr_partitions = 1;  /* Bad guess ?-) */
@@ -4915,7 +5001,7 @@
 		}
 
 		if (auto_weof)
-			cross_eof(STp, &SRpnt, FALSE);
+			cross_eof(STp, &SRpnt, 0);
 
 		if (mtc.mt_op == MTCOMPRESSION)
 			retval = -EINVAL;       /* OnStream drives don't have compression hardware */
@@ -4931,7 +5017,7 @@
 		goto out;
 	}
 
-	if ((i = osst_flush_buffer(STp, &SRpnt, FALSE)) < 0) {
+	if ((i = osst_flush_buffer(STp, &SRpnt, 0)) < 0) {
 		retval = i;
 		goto out;
 	}
@@ -5039,18 +5125,18 @@
 /* Memory handling routines */
 
 /* Try to allocate a new tape buffer skeleton. Caller must not hold os_scsi_tapes_lock */
-static OSST_buffer * new_tape_buffer( int from_initialization, int need_dma, int max_sg )
+static struct osst_buffer * new_tape_buffer( int from_initialization, int need_dma, int max_sg )
 {
 	int i, priority;
-	OSST_buffer *tb;
+	struct osst_buffer *tb;
 
 	if (from_initialization)
 		priority = GFP_ATOMIC;
 	else
 		priority = GFP_KERNEL;
 
-	i = sizeof(OSST_buffer) + (osst_max_sg_segs - 1) * sizeof(struct scatterlist);
-	tb = (OSST_buffer *)kmalloc(i, priority);
+	i = sizeof(struct osst_buffer) + (osst_max_sg_segs - 1) * sizeof(struct scatterlist);
+	tb = (struct osst_buffer *)kmalloc(i, priority);
 	if (!tb) {
 		printk(KERN_NOTICE "osst :I: Can't allocate new tape buffer.\n");
 		return NULL;
@@ -5058,7 +5144,7 @@
 	memset(tb, 0, i);
 	tb->sg_segs = tb->orig_sg_segs = 0;
 	tb->use_sg = max_sg;
-	tb->in_use = TRUE;
+	tb->in_use = 1;
 	tb->dma = need_dma;
 	tb->buffer_size = 0;
 #if DEBUG
@@ -5071,12 +5157,12 @@
 }
 
 /* Try to allocate a temporary (while a user has the device open) enlarged tape buffer */
-static int enlarge_buffer(OSST_buffer *STbuffer, int need_dma)
+static int enlarge_buffer(struct osst_buffer *STbuffer, int need_dma)
 {
 	int segs, nbr, max_segs, b_size, priority, order, got;
 
 	if (STbuffer->buffer_size >= OS_FRAME_SIZE)
-		return TRUE;
+		return 1;
 
 	if (STbuffer->sg_segs) {
 		printk(KERN_WARNING "osst :A: Buffer not previously normalized.\n");
@@ -5085,14 +5171,12 @@
 	/* See how many segments we can use -- need at least two */
 	nbr = max_segs = STbuffer->use_sg;
 	if (nbr <= 2)
-		return FALSE;
+		return 0;
 
-	priority = GFP_KERNEL;
+	priority = GFP_KERNEL /* | __GFP_NOWARN */;
 	if (need_dma)
 		priority |= GFP_DMA;
 
-	priority |= __GFP_NOWARN;
-
 	/* Try to allocate the first segment up to OS_DATA_SIZE and the others
 	   big enough to reach the goal (code assumes no segments in place) */
 	for (b_size = OS_DATA_SIZE, order = OSST_FIRST_ORDER; b_size >= PAGE_SIZE; order--, b_size /= 2) {
@@ -5106,7 +5190,7 @@
 	}
 	if (STbuffer->sg[0].page == NULL) {
 		printk(KERN_NOTICE "osst :I: Can't allocate tape buffer main segment.\n");
-		return FALSE;
+		return 0;
 	}
 	/* Got initial segment of 'bsize,order', continue with same size if possible, except for AUX */
 	for (segs=STbuffer->sg_segs=1, got=b_size;
@@ -5126,7 +5210,7 @@
 			STbuffer->buffer_size = got;
 #endif
 			normalize_buffer(STbuffer);
-			return FALSE;
+			return 0;
 		}
 		STbuffer->sg[segs].length = (OS_FRAME_SIZE - got <= PAGE_SIZE / 2) ? (OS_FRAME_SIZE - got) : b_size;
 		got += STbuffer->sg[segs].length;
@@ -5145,12 +5229,12 @@
 	}
 #endif
 
-	return TRUE;
+	return 1;
 }
 
 
 /* Release the segments */
-static void normalize_buffer(OSST_buffer *STbuffer)
+static void normalize_buffer(struct osst_buffer *STbuffer)
 {
   int i, order, b_size;
 
@@ -5174,7 +5258,7 @@
 
 /* Move data from the user buffer to the tape buffer. Returns zero (success) or
    negative error code. */
-static int append_to_buffer(const char __user *ubp, OSST_buffer *st_bp, int do_count)
+static int append_to_buffer(const char __user *ubp, struct osst_buffer *st_bp, int do_count)
 {
 	int i, cnt, res, offset;
 
@@ -5207,7 +5291,7 @@
 
 /* Move data from the tape buffer to the user buffer. Returns zero (success) or
    negative error code. */
-static int from_buffer(OSST_buffer *st_bp, char __user *ubp, int do_count)
+static int from_buffer(struct osst_buffer *st_bp, char __user *ubp, int do_count)
 {
 	int i, cnt, res, offset;
 
@@ -5239,7 +5323,7 @@
 
 /* Sets the tail of the buffer after fill point to zero.
    Returns zero (success) or negative error code.        */
-static int osst_zero_buffer_tail(OSST_buffer *st_bp)
+static int osst_zero_buffer_tail(struct osst_buffer *st_bp)
 {
 	int	i, offset, do_count, cnt;
 
@@ -5267,7 +5351,7 @@
 
 /* Copy a osst 32K chunk of memory into the buffer.
    Returns zero (success) or negative error code.  */
-static int osst_copy_to_buffer(OSST_buffer *st_bp, unsigned char *ptr)
+static int osst_copy_to_buffer(struct osst_buffer *st_bp, unsigned char *ptr)
 {
 	int	i, cnt, do_count = OS_DATA_SIZE;
 
@@ -5288,7 +5372,7 @@
 
 /* Copy a osst 32K chunk of memory from the buffer.
    Returns zero (success) or negative error code.  */
-static int osst_copy_from_buffer(OSST_buffer *st_bp, unsigned char *ptr)
+static int osst_copy_from_buffer(struct osst_buffer *st_bp, unsigned char *ptr)
 {
 	int	i, cnt, do_count = OS_DATA_SIZE;
 
@@ -5377,7 +5461,7 @@
 	.release =      os_scsi_tape_close,
 };
 
-static int osst_supports(Scsi_Device * SDp)
+static int osst_supports(struct scsi_device * SDp)
 {
 	struct	osst_support_data {
 		char *vendor;
@@ -5406,18 +5490,163 @@
 }
 
 /*
+ * sysfs support for osst driver parameter information
+ */
+
+static ssize_t osst_version_show(struct device_driver *ddd, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%s\n", osst_version);
+}
+
+static DRIVER_ATTR(version, S_IRUGO, osst_version_show, NULL);
+
+static void osst_create_driverfs_files(struct device_driver *driverfs)
+{
+	driver_create_file(driverfs, &driver_attr_version);
+}
+
+static void osst_remove_driverfs_files(struct device_driver *driverfs)
+{
+	driver_remove_file(driverfs, &driver_attr_version);
+}
+
+/*
+ * sysfs support for accessing ADR header information
+ */
+
+static ssize_t osst_adr_rev_show(struct class_device *class_dev, char *buf)
+{
+	struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev);
+	ssize_t l = 0;
+
+	if (STp && STp->header_ok && STp->linux_media)
+		l = snprintf(buf, PAGE_SIZE, "%d.%d\n", STp->header_cache->major_rev, STp->header_cache->minor_rev);
+	return l;
+}
+
+CLASS_DEVICE_ATTR(ADR_rev, S_IRUGO, osst_adr_rev_show, NULL);
+
+static ssize_t osst_linux_media_version_show(struct class_device *class_dev, char *buf)
+{
+	struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev);
+	ssize_t l = 0;
+
+	if (STp && STp->header_ok && STp->linux_media)
+		l = snprintf(buf, PAGE_SIZE, "LIN%d\n", STp->linux_media_version);
+	return l;
+}
+
+CLASS_DEVICE_ATTR(media_version, S_IRUGO, osst_linux_media_version_show, NULL);
+
+static ssize_t osst_capacity_show(struct class_device *class_dev, char *buf)
+{
+	struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev);
+	ssize_t l = 0;
+
+	if (STp && STp->header_ok && STp->linux_media)
+		l = snprintf(buf, PAGE_SIZE, "%d\n", STp->capacity);
+	return l;
+}
+
+CLASS_DEVICE_ATTR(capacity, S_IRUGO, osst_capacity_show, NULL);
+
+static ssize_t osst_first_data_ppos_show(struct class_device *class_dev, char *buf)
+{
+	struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev);
+	ssize_t l = 0;
+
+	if (STp && STp->header_ok && STp->linux_media)
+		l = snprintf(buf, PAGE_SIZE, "%d\n", STp->first_data_ppos);
+	return l;
+}
+
+CLASS_DEVICE_ATTR(BOT_frame, S_IRUGO, osst_first_data_ppos_show, NULL);
+
+static ssize_t osst_eod_frame_ppos_show(struct class_device *class_dev, char *buf)
+{
+	struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev);
+	ssize_t l = 0;
+
+	if (STp && STp->header_ok && STp->linux_media)
+		l = snprintf(buf, PAGE_SIZE, "%d\n", STp->eod_frame_ppos);
+	return l;
+}
+
+CLASS_DEVICE_ATTR(EOD_frame, S_IRUGO, osst_eod_frame_ppos_show, NULL);
+
+static ssize_t osst_filemark_cnt_show(struct class_device *class_dev, char *buf)
+{
+	struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev);
+	ssize_t l = 0;
+
+	if (STp && STp->header_ok && STp->linux_media)
+		l = snprintf(buf, PAGE_SIZE, "%d\n", STp->filemark_cnt);
+	return l;
+}
+
+CLASS_DEVICE_ATTR(file_count, S_IRUGO, osst_filemark_cnt_show, NULL);
+
+static struct class_simple * 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");
+	if ( IS_ERR(osst_sysfs_class) )
+		printk(KERN_WARNING "osst :W: Unable to register sysfs class\n");
+	else
+		osst_sysfs_valid = 1;
+}
+
+static void osst_sysfs_add(dev_t dev, struct device *device, struct osst_tape * STp, char * name)
+{
+	struct class_device *osst_class_member;
+
+	if (!osst_sysfs_valid) return;
+
+	osst_class_member = class_simple_device_add(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;
+	}
+	class_set_devdata(osst_class_member, STp);
+	class_device_create_file(osst_class_member, &class_device_attr_ADR_rev);
+	class_device_create_file(osst_class_member, &class_device_attr_media_version);
+	class_device_create_file(osst_class_member, &class_device_attr_capacity);
+	class_device_create_file(osst_class_member, &class_device_attr_BOT_frame);
+	class_device_create_file(osst_class_member, &class_device_attr_EOD_frame);
+	class_device_create_file(osst_class_member, &class_device_attr_file_count);
+}
+
+static void osst_sysfs_destroy(dev_t dev)
+{
+	if (!osst_sysfs_valid) return; 
+
+	class_simple_device_remove(dev);
+}
+
+static void osst_sysfs_cleanup(void)
+{
+	if (osst_sysfs_valid) {
+		class_simple_destroy(osst_sysfs_class);
+		osst_sysfs_valid = 0;
+	}
+}
+
+/*
  * osst startup / cleanup code
  */
 
 static int osst_probe(struct device *dev)
 {
-	Scsi_Device    * SDp = to_scsi_device(dev);
-	OS_Scsi_Tape   * tpnt;
-	struct st_modedef        * STm;
-	struct st_partstat    * STps;
-	OSST_buffer    * buffer;
-	struct gendisk * drive;
-	int              i, mode, dev_num;
+	struct scsi_device * SDp = to_scsi_device(dev);
+	struct osst_tape   * tpnt;
+	struct st_modedef  * STm;
+	struct st_partstat * STps;
+	struct osst_buffer * buffer;
+	struct gendisk	   * drive;
+	int		     i, mode, dev_num;
 
 	if (SDp->type != TYPE_TAPE || !osst_supports(SDp))
 		return -ENODEV;
@@ -5432,7 +5661,7 @@
 	write_lock(&os_scsi_tapes_lock);
 	if (os_scsi_tapes == NULL) {
 		os_scsi_tapes =
-			(OS_Scsi_Tape **)kmalloc(osst_max_dev * sizeof(OS_Scsi_Tape *),
+			(struct osst_tape **)kmalloc(osst_max_dev * sizeof(struct osst_tape *),
 				   GFP_ATOMIC);
 		if (os_scsi_tapes == NULL) {
 			write_unlock(&os_scsi_tapes_lock);
@@ -5453,20 +5682,20 @@
 	if(i >= osst_max_dev) panic ("Scsi_devices corrupt (osst)");
 	dev_num = i;
 
-	/* allocate a OS_Scsi_Tape for this device */
-	tpnt = (OS_Scsi_Tape *)kmalloc(sizeof(OS_Scsi_Tape), GFP_ATOMIC);
+	/* allocate a struct osst_tape for this device */
+	tpnt = (struct osst_tape *)kmalloc(sizeof(struct osst_tape), GFP_ATOMIC);
 	if (tpnt == NULL) {
 		write_unlock(&os_scsi_tapes_lock);
 		printk(KERN_ERR "osst :E: Can't allocate device descriptor, device not attached.\n");
 		goto out_put_disk;
 	}
-	memset(tpnt, 0, sizeof(OS_Scsi_Tape));
+	memset(tpnt, 0, sizeof(struct osst_tape));
 
 	/* allocate a buffer for this device */
 	i = SDp->host->sg_tablesize;
 	if (osst_max_sg_segs < i)
 		i = osst_max_sg_segs;
-	buffer = new_tape_buffer(TRUE, SDp->host->unchecked_isa_dma, i);
+	buffer = new_tape_buffer(1, SDp->host->unchecked_isa_dma, i);
 	if (buffer == NULL) {
 		write_unlock(&os_scsi_tapes_lock);
 		printk(KERN_ERR "osst :E: Unable to allocate a tape buffer, device not attached.\n");
@@ -5516,7 +5745,7 @@
 
 	for (i=0; i < ST_NBR_MODES; i++) {
 		STm = &(tpnt->modes[i]);
-		STm->defined = FALSE;
+		STm->defined = 0;
 		STm->sysv = OSST_SYSV;
 		STm->defaults_for_writes = 0;
 		STm->do_async_writes = OSST_ASYNC_WRITES;
@@ -5532,20 +5761,27 @@
 		STps->rw = ST_IDLE;
 		STps->eof = ST_NOEOF;
 		STps->at_sm = 0;
-		STps->last_block_valid = FALSE;
+		STps->last_block_valid = 0;
 		STps->drv_block = (-1);
 		STps->drv_file = (-1);
 	}
 
 	tpnt->current_mode = 0;
-	tpnt->modes[0].defined = TRUE;
-	tpnt->modes[2].defined = TRUE;
-	tpnt->density_changed = tpnt->compression_changed = tpnt->blksize_changed = FALSE;
+	tpnt->modes[0].defined = 1;
+	tpnt->modes[2].defined = 1;
+	tpnt->density_changed = tpnt->compression_changed = tpnt->blksize_changed = 0;
 
 	init_MUTEX(&tpnt->lock);
 	osst_nr_dev++;
 	write_unlock(&os_scsi_tapes_lock);
-
+	{
+		char name[8];
+		/*  Rewind entry  */
+		osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num), dev, tpnt, tape_name(tpnt));
+		/*  No-rewind entry  */
+		snprintf(name, 8, "%s%s", "n", tape_name(tpnt));
+		osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num + 128), dev, tpnt, name);
+	}
 	for (mode = 0; mode < ST_NBR_MODES; ++mode) {
 		/*  Rewind entry  */
 		devfs_mk_cdev(MKDEV(OSST_MAJOR, dev_num + (mode << 5)),
@@ -5572,8 +5808,8 @@
 
 static int osst_remove(struct device *dev)
 {
-	Scsi_Device  * SDp = to_scsi_device(dev);
-	OS_Scsi_Tape * tpnt;
+	struct scsi_device * SDp = to_scsi_device(dev);
+	struct osst_tape * tpnt;
 	int i, mode;
 
 	if ((SDp->type != TYPE_TAPE) || (osst_nr_dev <= 0))
@@ -5582,6 +5818,8 @@
 	write_lock(&os_scsi_tapes_lock);
 	for(i=0; i < osst_max_dev; i++) {
 		if((tpnt = os_scsi_tapes[i]) && (tpnt->device == SDp)) {
+			osst_sysfs_destroy(MKDEV(OSST_MAJOR, i));
+			osst_sysfs_destroy(MKDEV(OSST_MAJOR, i+128));
 			tpnt->device = NULL;
 			for (mode = 0; mode < ST_NBR_MODES; ++mode) {
 				devfs_remove("%s/ot%s", SDp->devfs_name, osst_formats[mode]);
@@ -5610,11 +5848,14 @@
 	printk(KERN_INFO "osst :I: Tape driver with OnStream support version %s\nosst :I: %s\n", osst_version, cvsid);
 
 	validate_options();
-	
+	osst_sysfs_init();
+
 	if ((register_chrdev(OSST_MAJOR,"osst", &osst_fops) < 0) || scsi_register_driver(&osst_template.gendrv)) {
 		printk(KERN_ERR "osst :E: Unable to register major %d for OnStream tapes\n", OSST_MAJOR);
+		osst_sysfs_cleanup();
 		return 1;
 	}
+	osst_create_driverfs_files(&osst_template.gendrv);
 
 	return 0;
 }
@@ -5622,10 +5863,12 @@
 static void __exit exit_osst (void)
 {
 	int i;
-	OS_Scsi_Tape * STp;
+	struct osst_tape * STp;
 
+	osst_remove_driverfs_files(&osst_template.gendrv);
 	scsi_unregister_driver(&osst_template.gendrv);
 	unregister_chrdev(OSST_MAJOR, "osst");
+	osst_sysfs_cleanup();
 
 	if (os_scsi_tapes) {
 		for (i=0; i < osst_max_dev; ++i) {
diff -Nru a/drivers/scsi/osst.h b/drivers/scsi/osst.h
--- a/drivers/scsi/osst.h	2005-03-01 23:39:07 -08:00
+++ b/drivers/scsi/osst.h	2005-03-01 23:39:07 -08:00
@@ -1,5 +1,5 @@
 /*
- *	$Header: /cvsroot/osst/Driver/osst.h,v 1.14 2003/12/14 14:34:38 wriede Exp $
+ *	$Header: /cvsroot/osst/Driver/osst.h,v 1.16 2005/01/01 21:13:35 wriede Exp $
  */
 
 #include <asm/byteorder.h>
@@ -70,7 +70,7 @@
 #define BLOCK_SIZE_PAGE_LENGTH     4
 
 #define BUFFER_FILLING_PAGE        0x33
-#define BUFFER_FILLING_PAGE_LENGTH 
+#define BUFFER_FILLING_PAGE_LENGTH 4
 
 #define VENDOR_IDENT_PAGE          0x36
 #define VENDOR_IDENT_PAGE_LENGTH   8
@@ -508,7 +508,7 @@
 //#define OSST_MAX_SG      2
 
 /* The OnStream tape buffer descriptor. */
-typedef struct {
+struct osst_buffer {
   unsigned char in_use;
   unsigned char dma;	/* DMA-able buffer */
   int buffer_size;
@@ -518,23 +518,23 @@
   int writing;
   int midlevel_result;
   int syscall_result;
-  Scsi_Request *last_SRpnt;
+  struct scsi_request *last_SRpnt;
   unsigned char *b_data;
   os_aux_t *aux;               /* onstream AUX structure at end of each block     */
   unsigned short use_sg;       /* zero or number of s/g segments for this adapter */
   unsigned short sg_segs;      /* number of segments in s/g list                  */
   unsigned short orig_sg_segs; /* number of segments allocated at first try       */
   struct scatterlist sg[1];    /* MUST BE last item                               */
-} OSST_buffer;
+} ;
 
 /* The OnStream tape drive descriptor */
-typedef struct {
+struct osst_tape {
   struct scsi_driver *driver;
   unsigned capacity;
-  Scsi_Device* device;
+  struct scsi_device *device;
   struct semaphore lock;       /* for serialization */
   struct completion wait;      /* for SCSI commands */
-  OSST_buffer * buffer;
+  struct osst_buffer * buffer;
 
   /* Drive characteristics */
   unsigned char omit_blklims;
@@ -577,6 +577,7 @@
   int min_block;
   int max_block;
   int recover_count;            /* from tape opening */
+  int abort_count;
   int write_count;
   int read_count;
   int recover_erreg;            /* from last status call */
@@ -623,7 +624,7 @@
   unsigned char last_sense[16];
 #endif
   struct gendisk *drive;
-} OS_Scsi_Tape;
+} ;
 
 /* Values of write_type */
 #define OS_WRITE_DATA      0
diff -Nru a/drivers/scsi/pcmcia/aha152x_stub.c b/drivers/scsi/pcmcia/aha152x_stub.c
--- a/drivers/scsi/pcmcia/aha152x_stub.c	2005-03-01 23:39:10 -08:00
+++ b/drivers/scsi/pcmcia/aha152x_stub.c	2005-03-01 23:39:10 -08:00
@@ -70,10 +70,6 @@
 
 /* Parameters that can be set with 'insmod' */
 
-/* Bit map of interrupts to choose from */
-static u_int irq_mask = 0xdeb8;
-static int irq_list[4] = { -1 };
-
 /* SCSI bus setup options */
 static int host_id = 7;
 static int reconnect = 1;
@@ -82,14 +78,12 @@
 static int reset_delay = 100;
 static int ext_trans = 0;
 
-MODULE_PARM(irq_mask, "i");
-MODULE_PARM(irq_list, "1-4i");
-MODULE_PARM(host_id, "i");
-MODULE_PARM(reconnect, "i");
-MODULE_PARM(parity, "i");
-MODULE_PARM(synchronous, "i");
-MODULE_PARM(reset_delay, "i");
-MODULE_PARM(ext_trans, "i");
+module_param(host_id, int, 0);
+module_param(reconnect, int, 0);
+module_param(parity, int, 0);
+module_param(synchronous, int, 0);
+module_param(reset_delay, int, 0);
+module_param(ext_trans, int, 0);
 
 MODULE_LICENSE("Dual MPL/GPL");
 
@@ -116,7 +110,7 @@
     scsi_info_t *info;
     client_reg_t client_reg;
     dev_link_t *link;
-    int i, ret;
+    int ret;
     
     DEBUG(0, "aha152x_attach()\n");
 
@@ -130,12 +124,7 @@
     link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
     link->io.IOAddrLines = 10;
     link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
-    link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
-    if (irq_list[0] == -1)
-	link->irq.IRQInfo2 = irq_mask;
-    else
-	for (i = 0; i < 4; i++)
-	    link->irq.IRQInfo2 |= 1 << irq_list[i];
+    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.Vcc = 50;
     link->conf.IntType = INT_MEMORY_AND_IO;
@@ -145,7 +134,6 @@
     link->next = dev_list;
     dev_list = link;
     client_reg.dev_info = &dev_info;
-    client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
     client_reg.event_handler = &aha152x_event;
     client_reg.EventMask =
 	CS_EVENT_RESET_REQUEST | CS_EVENT_CARD_RESET |
@@ -347,10 +335,7 @@
 static void __exit exit_aha152x_cs(void)
 {
 	pcmcia_unregister_driver(&aha152x_cs_driver);
-
-	/* XXX: this really needs to move into generic code.. */
-	while (dev_list != NULL)
-		aha152x_detach(dev_list);
+	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_aha152x_cs);
diff -Nru a/drivers/scsi/pcmcia/fdomain_stub.c b/drivers/scsi/pcmcia/fdomain_stub.c
--- a/drivers/scsi/pcmcia/fdomain_stub.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/scsi/pcmcia/fdomain_stub.c	2005-03-01 23:38:58 -08:00
@@ -61,15 +61,9 @@
 MODULE_DESCRIPTION("Future Domain PCMCIA SCSI driver");
 MODULE_LICENSE("Dual MPL/GPL");
 
-/* Bit map of interrupts to choose from */
-static int irq_mask = 0xdeb8;
-MODULE_PARM(irq_mask, "i");
-static int irq_list[4] = { -1 };
-MODULE_PARM(irq_list, "1-4i");
-
 #ifdef PCMCIA_DEBUG
 static int pc_debug = PCMCIA_DEBUG;
-MODULE_PARM(pc_debug, "i");
+module_param(pc_debug, int, 0);
 #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
 static char *version =
 "fdomain_cs.c 1.47 2001/10/13 00:08:52 (David Hinds)";
@@ -103,7 +97,7 @@
     scsi_info_t *info;
     client_reg_t client_reg;
     dev_link_t *link;
-    int i, ret;
+    int ret;
     
     DEBUG(0, "fdomain_attach()\n");
 
@@ -116,12 +110,7 @@
     link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
     link->io.IOAddrLines = 10;
     link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
-    link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
-    if (irq_list[0] == -1)
-	link->irq.IRQInfo2 = irq_mask;
-    else
-	for (i = 0; i < 4; i++)
-	    link->irq.IRQInfo2 |= 1 << irq_list[i];
+    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.Vcc = 50;
     link->conf.IntType = INT_MEMORY_AND_IO;
@@ -131,7 +120,6 @@
     link->next = dev_list;
     dev_list = link;
     client_reg.dev_info = &dev_info;
-    client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
     client_reg.event_handler = &fdomain_event;
     client_reg.EventMask =
 	CS_EVENT_RESET_REQUEST | CS_EVENT_CARD_RESET |
@@ -328,10 +316,7 @@
 static void __exit exit_fdomain_cs(void)
 {
 	pcmcia_unregister_driver(&fdomain_cs_driver);
-
-	/* XXX: this really needs to move into generic code.. */
-	while (dev_list != NULL)
-		fdomain_detach(dev_list);
+	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_fdomain_cs);
diff -Nru a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c
--- a/drivers/scsi/pcmcia/nsp_cs.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/scsi/pcmcia/nsp_cs.c	2005-03-01 23:39:17 -08:00
@@ -72,21 +72,13 @@
 /*====================================================================*/
 /* Parameters that can be set with 'insmod' */
 
-static unsigned int irq_mask = 0xffff;
-MODULE_PARM     (irq_mask, "i");
-MODULE_PARM_DESC(irq_mask, "IRQ mask bits (default: 0xffff)");
-
-static int       irq_list[4] = { -1 };
-MODULE_PARM     (irq_list, "1-4i");
-MODULE_PARM_DESC(irq_list, "Use specified IRQ number. (default: auto select)");
-
 static int       nsp_burst_mode = BURST_MEM32;
-MODULE_PARM     (nsp_burst_mode, "i");
+module_param(nsp_burst_mode, int, 0);
 MODULE_PARM_DESC(nsp_burst_mode, "Burst transfer mode (0=io8, 1=io32, 2=mem32(default))");
 
 /* Release IO ports after configuration? */
 static int       free_ports = 0;
-MODULE_PARM     (free_ports, "i");
+module_param(free_ports, bool, 0);
 MODULE_PARM_DESC(free_ports, "Release IO ports after configuration? (default: 0 (=no))");
 
 /* /usr/src/linux/drivers/scsi/hosts.h */
@@ -1625,7 +1617,7 @@
 	scsi_info_t  *info;
 	client_reg_t  client_reg;
 	dev_link_t   *link;
-	int	      ret, i;
+	int	      ret;
 	nsp_hw_data  *data = &nsp_data_base;
 
 	nsp_dbg(NSP_DEBUG_INIT, "in");
@@ -1647,14 +1639,7 @@
 
 	/* Interrupt setup */
 	link->irq.Attributes	 = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
-	link->irq.IRQInfo1	 = IRQ_INFO2_VALID    | IRQ_LEVEL_ID;
-	if (irq_list[0] == -1) {
-		link->irq.IRQInfo2 = irq_mask;
-	} else {
-		for (i = 0; i < 4; i++) {
-			link->irq.IRQInfo2 |= BIT(irq_list[i]);
-		}
-	}
+	link->irq.IRQInfo1	 = IRQ_LEVEL_ID;
 
 	/* Interrupt handler */
 	link->irq.Handler	 = &nspintr;
@@ -1672,7 +1657,6 @@
 	link->next               = dev_list;
 	dev_list                 = link;
 	client_reg.dev_info	 = &dev_info;
-	client_reg.Attributes	 = INFO_IO_CLIENT | INFO_CARD_SHARE;
 	client_reg.EventMask	 =
 		CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
 		CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET	|
@@ -2194,10 +2178,9 @@
 
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,68))
 	pcmcia_unregister_driver(&nsp_driver);
+	BUG_ON(dev_list != NULL);
 #else
 	unregister_pcmcia_driver(&dev_info);
-#endif
-
 	/* XXX: this really needs to move into generic code.. */
 	while (dev_list != NULL) {
 		if (dev_list->state & DEV_CONFIG) {
@@ -2205,6 +2188,7 @@
 		}
 		nsp_cs_detach(dev_list);
 	}
+#endif
 }
 
 
diff -Nru a/drivers/scsi/pcmcia/qlogic_stub.c b/drivers/scsi/pcmcia/qlogic_stub.c
--- a/drivers/scsi/pcmcia/qlogic_stub.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/scsi/pcmcia/qlogic_stub.c	2005-03-01 23:38:57 -08:00
@@ -93,17 +93,6 @@
 
 /*====================================================================*/
 
-/* Parameters that can be set with 'insmod' */
-
-/* Bit map of interrupts to choose from */
-static unsigned int irq_mask = 0xdeb8;
-static int irq_list[4] = { -1 };
-
-MODULE_PARM(irq_mask, "i");
-MODULE_PARM(irq_list, "1-4i");
-
-/*====================================================================*/
-
 typedef struct scsi_info_t {
 	dev_link_t link;
 	dev_node_t node;
@@ -182,7 +171,7 @@
 	scsi_info_t *info;
 	client_reg_t client_reg;
 	dev_link_t *link;
-	int i, ret;
+	int ret;
 
 	DEBUG(0, "qlogic_attach()\n");
 
@@ -197,12 +186,7 @@
 	link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
 	link->io.IOAddrLines = 10;
 	link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
-	link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
-	if (irq_list[0] == -1)
-		link->irq.IRQInfo2 = irq_mask;
-	else
-		for (i = 0; i < 4; i++)
-			link->irq.IRQInfo2 |= 1 << irq_list[i];
+	link->irq.IRQInfo1 = IRQ_LEVEL_ID;
 	link->conf.Attributes = CONF_ENABLE_IRQ;
 	link->conf.Vcc = 50;
 	link->conf.IntType = INT_MEMORY_AND_IO;
@@ -212,7 +196,6 @@
 	link->next = dev_list;
 	dev_list = link;
 	client_reg.dev_info = &dev_info;
-	client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
 	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;
@@ -432,10 +415,7 @@
 static void __exit exit_qlogic_cs(void)
 {
 	pcmcia_unregister_driver(&qlogic_cs_driver);
-
-	/* XXX: this really needs to move into generic code.. */
-	while (dev_list != NULL)
-		qlogic_detach(dev_list);
+	BUG_ON(dev_list != NULL);
 }
 
 MODULE_AUTHOR("Tom Zerucha, Michael Griffith");
diff -Nru a/drivers/scsi/pcmcia/sym53c500_cs.c b/drivers/scsi/pcmcia/sym53c500_cs.c
--- a/drivers/scsi/pcmcia/sym53c500_cs.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/scsi/pcmcia/sym53c500_cs.c	2005-03-01 23:39:08 -08:00
@@ -92,19 +92,6 @@
 
 /* ================================================================== */
 
-/* Parameters that can be set with 'insmod' */
-
-/* Bit map of interrupts to choose from */
-static unsigned int irq_mask = 0xdeb8;	/* 3-5, 7, 9-12, 14, 15 */
-static int irq_list[4] = { -1 };
-
-module_param(irq_mask, int, 0);
-MODULE_PARM_DESC(irq_mask, "IRQ mask bits (default: 0xdeb8)");
-module_param_array(irq_list, int, NULL, 0);
-MODULE_PARM_DESC(irq_list, "Comma-separated list of up to 4 IRQs to try (default: auto select).");
-
-/* ================================================================== */
-
 #define SYNC_MODE 0 		/* Synchronous transfer mode */
 
 /* Default configuration */
@@ -965,7 +952,7 @@
 	struct scsi_info_t *info;
 	client_reg_t client_reg;
 	dev_link_t *link;
-	int i, ret;
+	int ret;
 
 	DEBUG(0, "SYM53C500_attach()\n");
 
@@ -980,12 +967,7 @@
 	link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
 	link->io.IOAddrLines = 10;
 	link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
-	link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
-	if (irq_list[0] == -1)
-		link->irq.IRQInfo2 = irq_mask;
-	else
-		for (i = 0; i < 4; i++)
-			link->irq.IRQInfo2 |= 1 << irq_list[i];
+	link->irq.IRQInfo1 = IRQ_LEVEL_ID;
 	link->conf.Attributes = CONF_ENABLE_IRQ;
 	link->conf.Vcc = 50;
 	link->conf.IntType = INT_MEMORY_AND_IO;
@@ -995,7 +977,6 @@
 	link->next = dev_list;
 	dev_list = link;
 	client_reg.dev_info = &dev_info;
-	client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
 	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 |
diff -Nru a/drivers/scsi/ppa.c b/drivers/scsi/ppa.c
--- a/drivers/scsi/ppa.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/scsi/ppa.c	2005-03-01 23:39:18 -08:00
@@ -49,7 +49,7 @@
 	return *(ppa_struct **)&host->hostdata;
 }
 
-static spinlock_t arbitration_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(arbitration_lock);
 
 static void got_it(ppa_struct *dev)
 {
diff -Nru a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c
--- a/drivers/scsi/qla1280.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/scsi/qla1280.c	2005-03-01 23:39:17 -08:00
@@ -3400,7 +3400,8 @@
 	sp->flags |= SRB_SENT;
 	ha->actthreads++;
 	WRT_REG_WORD(&reg->mailbox4, ha->req_ring_index);
-	(void) RD_REG_WORD(&reg->mailbox4); /* PCI posted write flush */
+	/* Enforce mmio write ordering; see comment in qla1280_isp_cmd(). */
+	mmiowb();
 
  out:
 	if (status)
@@ -3668,7 +3669,8 @@
 	sp->flags |= SRB_SENT;
 	ha->actthreads++;
 	WRT_REG_WORD(&reg->mailbox4, ha->req_ring_index);
-	(void) RD_REG_WORD(&reg->mailbox4); /* PCI posted write flush */
+	/* Enforce mmio write ordering; see comment in qla1280_isp_cmd(). */
+	mmiowb();
 
 out:
 	if (status)
@@ -3778,9 +3780,21 @@
 	} else
 		ha->request_ring_ptr++;
 
-	/* Set chip new ring index. */
+	/*
+	 * Update request index to mailbox4 (Request Queue In).
+	 * The mmiowb() ensures that this write is ordered with writes by other
+	 * CPUs.  Without the mmiowb(), it is possible for the following:
+	 *    CPUA posts write of index 5 to mailbox4
+	 *    CPUA releases host lock
+	 *    CPUB acquires host lock
+	 *    CPUB posts write of index 6 to mailbox4
+	 *    On PCI bus, order reverses and write of 6 posts, then index 5,
+	 *       causing chip to issue full queue of stale commands
+	 * The mmiowb() prevents future writes from crossing the barrier.
+	 * See Documentation/DocBook/deviceiobook.tmpl for more information.
+	 */
 	WRT_REG_WORD(&reg->mailbox4, ha->req_ring_index);
-	(void) RD_REG_WORD(&reg->mailbox4); /* PCI posted write flush */
+	mmiowb();
 
 	LEAVE("qla1280_isp_cmd");
 }
diff -Nru a/drivers/scsi/qla2xxx/Kconfig b/drivers/scsi/qla2xxx/Kconfig
--- a/drivers/scsi/qla2xxx/Kconfig	2005-03-01 23:39:18 -08:00
+++ b/drivers/scsi/qla2xxx/Kconfig	2005-03-01 23:39:18 -08:00
@@ -22,7 +22,7 @@
 	depends on SCSI_QLA2XXX
         select SCSI_FC_ATTRS
 	---help---
-	This driver supports the QLogic 2300 (ISP2300, and ISP2312) host
+	This driver supports the QLogic 2300 (ISP2300 and ISP2312) host
 	adapter family.
 
 config SCSI_QLA2322
@@ -33,15 +33,9 @@
 	This driver supports the QLogic 2322 (ISP2322) host adapter family.
 
 config SCSI_QLA6312
-	tristate "QLogic ISP6312 host adapter family support"
+	tristate "QLogic ISP63xx host adapter family support"
 	depends on SCSI_QLA2XXX
         select SCSI_FC_ATTRS
 	---help---
-	This driver supports the QLogic 6312 (ISP6312) host adapter family.
-
-config SCSI_QLA6322
-	tristate "QLogic ISP6322 host adapter family support"
-	depends on SCSI_QLA2XXX
-        select SCSI_FC_ATTRS
-	---help---
-	This driver supports the QLogic 6322 (ISP6322) host adapter family.
+	This driver supports the QLogic 63xx (ISP6312 and ISP6322) host
+	adapter family.
diff -Nru a/drivers/scsi/qla2xxx/Makefile b/drivers/scsi/qla2xxx/Makefile
--- a/drivers/scsi/qla2xxx/Makefile	2005-03-01 23:38:51 -08:00
+++ b/drivers/scsi/qla2xxx/Makefile	2005-03-01 23:38:51 -08:00
@@ -8,11 +8,9 @@
 qla2300-y := ql2300.o ql2300_fw.o
 qla2322-y := ql2322.o ql2322_fw.o
 qla6312-y := ql6312.o ql6312_fw.o
-qla6322-y := ql6322.o ql6322_fw.o
 
 obj-$(CONFIG_SCSI_QLA21XX) += qla2xxx.o qla2100.o
 obj-$(CONFIG_SCSI_QLA22XX) += qla2xxx.o qla2200.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_QLA6322) += qla2xxx.o qla6322.o
diff -Nru a/drivers/scsi/qla2xxx/ql2300.c b/drivers/scsi/qla2xxx/ql2300.c
--- a/drivers/scsi/qla2xxx/ql2300.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/scsi/qla2xxx/ql2300.c	2005-03-01 23:39:17 -08:00
@@ -98,6 +98,6 @@
 module_exit(qla2300_exit);
 
 MODULE_AUTHOR("QLogic Corporation");
-MODULE_DESCRIPTION("QLogic ISP2300 FC-SCSI Host Bus Adapter driver");
+MODULE_DESCRIPTION("QLogic ISP23xx FC-SCSI Host Bus Adapter driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(QLA2XXX_VERSION);
diff -Nru a/drivers/scsi/qla2xxx/ql2300_fw.c b/drivers/scsi/qla2xxx/ql2300_fw.c
--- a/drivers/scsi/qla2xxx/ql2300_fw.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/scsi/qla2xxx/ql2300_fw.c	2005-03-01 23:38:57 -08:00
@@ -1,8 +1,8 @@
-/**************************************************************************
+/******************************************************************************
  *                  QLOGIC LINUX SOFTWARE
  *
  * QLogic ISP2x00 device driver for Linux 2.6.x
- * Copyright (C) 2003-2004 QLogic Corporation
+ * Copyright (C) 2003 QLogic Corporation
  * (www.qlogic.com)
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -15,10 +15,10 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * General Public License for more details.
  *
- *************************************************************************/
+ ******************************************************************************/
 
 /*
- *	Firmware Version 3.03.02 (16:50 Aug 10, 2004)
+ *	Firmware Version 3.03.08 (10:02 Nov 12, 2004)
  */
 
 #ifdef UNIQUE_FW_NAME
@@ -28,15 +28,15 @@
 #endif
 
 #ifdef UNIQUE_FW_NAME
-unsigned char fw2300ipx_version_str[] = {3, 3, 2};
+unsigned char fw2300ipx_version_str[] = {3, 3, 8};
 #else
-unsigned char firmware_version[] = {3, 3, 2};
+unsigned char firmware_version[] = {3, 3, 8};
 #endif
 
 #ifdef UNIQUE_FW_NAME
-#define fw2300ipx_VERSION_STRING "3.03.02"
+#define fw2300ipx_VERSION_STRING "3.03.08"
 #else
-#define FW_VERSION_STRING "3.03.02"
+#define FW_VERSION_STRING "3.03.08"
 #endif
 
 #ifdef UNIQUE_FW_NAME
@@ -50,12 +50,12 @@
 #else
 unsigned short risc_code01[] = { 
 #endif
-	0x0470, 0x0000, 0x0000, 0xea02, 0x0000, 0x0003, 0x0003, 0x0002,
+	0x0470, 0x0000, 0x0000, 0xeb57, 0x0000, 0x0003, 0x0003, 0x0008,
 	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, 0x3220, 0x2020, 0x2020, 0x2400, 0x20a9,
+	0x332e, 0x3033, 0x2e30, 0x3820, 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,175 +64,175 @@
 	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, 0x2d36, 0x2051, 0x1800, 0x2a70, 0x20e1,
+	0x7883, 0x0004, 0x2089, 0x2d88, 0x2051, 0x1800, 0x2a70, 0x20e1,
 	0x0001, 0x20e9, 0x0001, 0x2009, 0x0000, 0x080c, 0x0e51, 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, 0x1ac7, 0x2472, 0x00ee, 0x20a1, 0x1cd0, 0x7170,
+	0x00e6, 0x2071, 0x1aca, 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,
-	0x603b, 0x080c, 0xadf5, 0x080c, 0x10ce, 0x080c, 0x12ed, 0x080c,
-	0x1bb1, 0x080c, 0x0d69, 0x080c, 0x1053, 0x080c, 0x3432, 0x080c,
-	0x76ad, 0x080c, 0x69ad, 0x080c, 0x86fc, 0x080c, 0x8430, 0x080c,
-	0x2485, 0x080c, 0x8fa0, 0x080c, 0x7d78, 0x080c, 0x22be, 0x080c,
-	0x23f2, 0x080c, 0x247a, 0x2091, 0x3009, 0x7883, 0x0000, 0x1004,
+	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,
 	0x091f, 0x7880, 0x9086, 0x0002, 0x1190, 0x7883, 0x4000, 0x7837,
 	0x4000, 0x7833, 0x0010, 0x0e04, 0x0913, 0x2091, 0x5000, 0x2091,
 	0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x119b, 0x2071,
 	0x1800, 0x7003, 0x0000, 0x2071, 0x1800, 0x7000, 0x908e, 0x0003,
-	0x1178, 0x080c, 0x4be3, 0x080c, 0x3459, 0x080c, 0x771e, 0x080c,
-	0x6ede, 0x080c, 0x87da, 0x080c, 0x8459, 0x080c, 0x2ca0, 0x0c58,
+	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, 0x56f1,
+	0x8000, 0x7000, 0x9086, 0x0001, 0x1904, 0x0aba, 0x080c, 0x576c,
 	0x1130, 0x0026, 0x2011, 0x0080, 0x080c, 0x0edf, 0x002e, 0x080c,
-	0x73b3, 0x0150, 0x080c, 0x73d6, 0x15a0, 0x2079, 0x0100, 0x7828,
-	0x9085, 0x1800, 0x782a, 0x0468, 0x080c, 0x72e5, 0x7000, 0x9086,
+	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, 0x8428, 0x080c, 0x841a, 0x2001, 0x0161, 0x2003, 0x0001,
+	0x080c, 0x84d0, 0x080c, 0x84c2, 0x2001, 0x0161, 0x2003, 0x0001,
 	0x2079, 0x0100, 0x7827, 0xffff, 0x7a28, 0x9295, 0x5e2f, 0x7a2a,
-	0x2011, 0x7249, 0x080c, 0x84f9, 0x2011, 0x723c, 0x080c, 0x85d3,
-	0x2011, 0x5e96, 0x080c, 0x84f9, 0x2011, 0x8030, 0x901e, 0x7396,
-	0x04d0, 0x080c, 0x5743, 0x2079, 0x0100, 0x7844, 0x9005, 0x1904,
-	0x0aba, 0x2011, 0x5e96, 0x080c, 0x84f9, 0x2011, 0x7249, 0x080c,
-	0x84f9, 0x2011, 0x723c, 0x080c, 0x85d3, 0x2001, 0x0265, 0x2001,
+	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,
-	0x5fe3, 0x00ce, 0x0804, 0x0aba, 0x780f, 0x006b, 0x7a28, 0x080c,
-	0x73bb, 0x0118, 0x9295, 0x5e2f, 0x0010, 0x9295, 0x402f, 0x7a2a,
+	0x6063, 0x00ce, 0x0804, 0x0aba, 0x780f, 0x006b, 0x7a28, 0x080c,
+	0x7446, 0x0118, 0x9295, 0x5e2f, 0x0010, 0x9295, 0x402f, 0x7a2a,
 	0x2011, 0x8010, 0x73d8, 0x2001, 0x19a6, 0x2003, 0x0001, 0x080c,
-	0x2b66, 0x080c, 0x4b1e, 0x7248, 0xc284, 0x724a, 0x2001, 0x180c,
-	0x200c, 0xc1ac, 0xc1cc, 0x2102, 0x080c, 0xa52f, 0x2011, 0x0004,
-	0x080c, 0xcb6a, 0x080c, 0x6839, 0x080c, 0x73b3, 0x1120, 0x080c,
-	0x2baa, 0x02e0, 0x0400, 0x080c, 0x5fea, 0x0140, 0x7097, 0x0001,
-	0x70d3, 0x0000, 0x080c, 0x5910, 0x0804, 0x0aba, 0x080c, 0x56e2,
+	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,
-	0x56e6, 0xd0d4, 0x1118, 0x080c, 0x2baa, 0x1270, 0x2011, 0x180c,
-	0x2204, 0xc0bc, 0x00a8, 0x080c, 0x56e6, 0xd0d4, 0x1db8, 0x2011,
+	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, 0x6981, 0x1128, 0xd0a4, 0x0118, 0x2204, 0xc0fd,
-	0x2012, 0x080c, 0x6947, 0x0120, 0x7a0c, 0xc2b4, 0x7a0e, 0x00a8,
-	0x707f, 0x0000, 0x080c, 0x73b3, 0x1130, 0x70b0, 0x9005, 0x1168,
-	0x080c, 0xcfab, 0x0050, 0x080c, 0xcfab, 0x70dc, 0xd09c, 0x1128,
-	0x70b0, 0x9005, 0x0110, 0x080c, 0x5fc0, 0x70e7, 0x0000, 0x70e3,
-	0x0000, 0x70a7, 0x0000, 0x080c, 0x2bb2, 0x0228, 0x2011, 0x0101,
-	0x2204, 0xc0c4, 0x2012, 0x72dc, 0x080c, 0x73b3, 0x1178, 0x9016,
-	0x0016, 0x080c, 0x2963, 0x2019, 0x196c, 0x211a, 0x001e, 0x705f,
+	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, 0x73b3, 0x0118, 0x9296, 0x0004, 0x0548, 0x2011,
-	0x0001, 0x080c, 0xcb6a, 0x70ab, 0x0000, 0x70af, 0xffff, 0x7003,
+	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, 0x2fa3, 0x2011, 0x0005, 0x080c, 0xa63e,
-	0x080c, 0x96a6, 0x080c, 0x73b3, 0x0148, 0x00c6, 0x2061, 0x0100,
-	0x0016, 0x080c, 0x2963, 0x61e2, 0x001e, 0x00ce, 0x012e, 0x0420,
+	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, 0xa63e, 0x080c, 0x96a6, 0x080c, 0x73b3,
-	0x0148, 0x00c6, 0x2061, 0x0100, 0x0016, 0x080c, 0x2963, 0x61e2,
+	0x2011, 0x0005, 0x080c, 0xa722, 0x080c, 0x9763, 0x080c, 0x743e,
+	0x0148, 0x00c6, 0x2061, 0x0100, 0x0016, 0x080c, 0x2994, 0x61e2,
 	0x001e, 0x00ce, 0x00fe, 0x012e, 0x0005, 0x00c6, 0x00b6, 0x080c,
-	0x73b3, 0x1118, 0x20a9, 0x0800, 0x0010, 0x20a9, 0x0782, 0x080c,
-	0x73b3, 0x1110, 0x900e, 0x0010, 0x2009, 0x007e, 0x86ff, 0x0138,
+	0x743e, 0x1118, 0x20a9, 0x0800, 0x0010, 0x20a9, 0x0782, 0x080c,
+	0x743e, 0x1110, 0x900e, 0x0010, 0x2009, 0x007e, 0x86ff, 0x0138,
 	0x9180, 0x1000, 0x2004, 0x905d, 0x0110, 0xb800, 0xd0bc, 0x090c,
-	0x32c8, 0x8108, 0x1f04, 0x0ace, 0x707f, 0x0000, 0x7080, 0x9084,
+	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, 0x2fa3, 0x080c, 0x96a6,
+	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, 0x332b, 0x11d0, 0x70e0, 0x9086, 0xffff, 0x01b0,
-	0x080c, 0x3138, 0x080c, 0x96a6, 0x70dc, 0xd094, 0x1904, 0x0bab,
-	0x2011, 0x0001, 0x080c, 0xd25a, 0x0110, 0x2011, 0x0003, 0x901e,
-	0x080c, 0x3172, 0x080c, 0x96a6, 0x0804, 0x0bab, 0x70e4, 0x9005,
+	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, 0x6947, 0x1904, 0x0bab,
-	0x080c, 0x699a, 0x1904, 0x0bab, 0x080c, 0x6981, 0x01c0, 0x0156,
-	0x00c6, 0x20a9, 0x007f, 0x900e, 0x0016, 0x080c, 0x6616, 0x1118,
+	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, 0x56f1, 0x1130, 0x0026,
-	0x2011, 0x0040, 0x080c, 0x0edf, 0x002e, 0x9006, 0x080c, 0x27f7,
-	0x080c, 0x332b, 0x0118, 0x080c, 0x4cbb, 0x0050, 0x0036, 0x0046,
-	0x2019, 0xffff, 0x2021, 0x0006, 0x080c, 0x4cd5, 0x004e, 0x003e,
-	0x00f6, 0x2079, 0x0100, 0x080c, 0x73d6, 0x0150, 0x080c, 0x73b3,
+	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, 0xa63e, 0x2011, 0x0000, 0x080c, 0xa648, 0x080c,
-	0x96a6, 0x080c, 0x97d4, 0x012e, 0x00be, 0x0005, 0x0016, 0x0046,
+	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, 0x5fa9, 0x7940, 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,
-	0x2c2d, 0x1148, 0x2001, 0x0001, 0x080c, 0x2b95, 0x2001, 0x0001,
-	0x080c, 0x2b78, 0x00b8, 0x080c, 0x2c35, 0x1138, 0x9006, 0x080c,
-	0x2b95, 0x9006, 0x080c, 0x2b78, 0x0068, 0x080c, 0x2c3d, 0x1d50,
-	0x2001, 0x1997, 0x2004, 0xd0fc, 0x0108, 0x0020, 0x080c, 0x298f,
-	0x0804, 0x0d1a, 0x080c, 0x73c4, 0x0148, 0x080c, 0x73d6, 0x1118,
-	0x080c, 0x76a8, 0x0050, 0x080c, 0x73bb, 0x0dd0, 0x080c, 0x76a3,
-	0x080c, 0x7699, 0x080c, 0x72e5, 0x0058, 0x080c, 0x73b3, 0x0140,
-	0x2009, 0x00f8, 0x080c, 0x5fa9, 0x7843, 0x0090, 0x7843, 0x0010,
-	0x20a9, 0x09c4, 0x7820, 0xd09c, 0x1138, 0x080c, 0x73b3, 0x0138,
+	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, 0x73cd, 0x0118, 0xd0ac, 0x1904, 0x0d1f, 0x9084, 0x1800,
+	0x080c, 0x7458, 0x0118, 0xd0ac, 0x1904, 0x0d1f, 0x9084, 0x1800,
 	0x0d98, 0x7003, 0x0001, 0x0804, 0x0d1f, 0x2001, 0x0001, 0x080c,
-	0x27f7, 0x0804, 0x0d32, 0x2001, 0x19a6, 0x2004, 0x9005, 0x1518,
-	0x080c, 0x2c2d, 0x1148, 0x2001, 0x0001, 0x080c, 0x2b95, 0x2001,
-	0x0001, 0x080c, 0x2b78, 0x00b8, 0x080c, 0x2c35, 0x1138, 0x9006,
-	0x080c, 0x2b95, 0x9006, 0x080c, 0x2b78, 0x0068, 0x080c, 0x2c3d,
+	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,
-	0x298f, 0x0804, 0x0d1a, 0x7850, 0x9085, 0x0040, 0x7852, 0x7938,
-	0x7850, 0x9084, 0xfbcf, 0x7852, 0x080c, 0x2c45, 0x9085, 0x2000,
-	0x7852, 0x793a, 0x20a9, 0x0046, 0x1d04, 0x0c74, 0x080c, 0x85b3,
+	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, 0x73c4, 0x0148, 0x080c, 0x73d6, 0x1118, 0x080c,
-	0x76a8, 0x0050, 0x080c, 0x73bb, 0x0dd0, 0x080c, 0x76a3, 0x080c,
-	0x7699, 0x080c, 0x72e5, 0x0020, 0x2009, 0x00f8, 0x080c, 0x5fa9,
+	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, 0x73b3, 0x0120, 0x7843, 0x0090, 0x7843, 0x0010,
-	0x2021, 0xe678, 0x2019, 0xea60, 0x0d0c, 0x85b3, 0x7820, 0xd09c,
-	0x1580, 0x080c, 0x73b3, 0x0904, 0x0cff, 0x7824, 0xd0ac, 0x1904,
-	0x0d1f, 0x080c, 0x73d6, 0x1528, 0x0046, 0x2021, 0x0320, 0x8421,
-	0x1df0, 0x004e, 0x7827, 0x1800, 0x080c, 0x2c45, 0x7824, 0x9084,
+	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, 0x85b3, 0x080c, 0x76a3, 0x080c, 0x7699, 0x7003, 0x0001,
-	0x04f0, 0x8319, 0x1948, 0x1d04, 0x0ce7, 0x080c, 0x85b3, 0x2009,
+	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, 0x2c26, 0x7924,
-	0x080c, 0x2c45, 0xd19c, 0x0110, 0x080c, 0x2b66, 0x00d8, 0x080c,
-	0x73c4, 0x1140, 0x94a2, 0x03e8, 0x1128, 0x080c, 0x738b, 0x7003,
-	0x0001, 0x00a8, 0x7827, 0x1800, 0x080c, 0x2c45, 0x7824, 0x080c,
-	0x73cd, 0x0110, 0xd0ac, 0x1158, 0x9084, 0x1800, 0x0950, 0x7003,
-	0x0001, 0x0028, 0x2001, 0x0001, 0x080c, 0x27f7, 0x0078, 0x2009,
+	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, 0x56f1, 0x1110, 0x080c, 0x0e62,
+	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, 0x85b3, 0x015e, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be,
+	0x0d0c, 0x866a, 0x015e, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be,
 	0x004e, 0x003e, 0x001e, 0x000e, 0x0005, 0x00e6, 0x2071, 0x189e,
-	0x7004, 0x9086, 0x0001, 0x1110, 0x080c, 0x3459, 0x00ee, 0x0005,
+	0x7004, 0x9086, 0x0001, 0x1110, 0x080c, 0x34ab, 0x00ee, 0x0005,
 	0x0005, 0x2a70, 0x2061, 0x19aa, 0x2063, 0x0003, 0x6007, 0x0003,
-	0x600b, 0x0002, 0x600f, 0x0137, 0x2001, 0x197b, 0x900e, 0x2102,
+	0x600b, 0x0008, 0x600f, 0x0137, 0x2001, 0x197b, 0x900e, 0x2102,
 	0x7196, 0x2001, 0x0100, 0x2004, 0x9082, 0x0002, 0x0218, 0x705f,
 	0xffff, 0x0008, 0x715e, 0x7067, 0xffff, 0x717e, 0x7182, 0x080c,
-	0xcfab, 0x2061, 0x196b, 0x6003, 0x0909, 0x6106, 0x600b, 0x8800,
+	0xd0d9, 0x2061, 0x196b, 0x6003, 0x0909, 0x6106, 0x600b, 0x8800,
 	0x600f, 0x0200, 0x6013, 0x00ff, 0x6017, 0x001f, 0x611a, 0x601f,
 	0x07d0, 0x2061, 0x1973, 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, 0x6616,
+	0x2020, 0x2001, 0x182c, 0x2102, 0x0005, 0x9016, 0x080c, 0x6699,
 	0x1178, 0xb804, 0x90c4, 0x00ff, 0x98c6, 0x0006, 0x0128, 0x90c4,
 	0xff00, 0x98c6, 0x0600, 0x1120, 0x9186, 0x0080, 0x0108, 0x8210,
 	0x8108, 0x9186, 0x0800, 0x1d50, 0x2208, 0x0005, 0x2091, 0x8000,
@@ -240,22 +240,22 @@
 	0x0dd7, 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, 0x1aa1, 0x7a08,
-	0x226a, 0x2069, 0x1aa2, 0x7a18, 0x226a, 0x8d68, 0x7a1c, 0x226a,
-	0x782c, 0x2019, 0x1aaf, 0x201a, 0x2019, 0x1ab2, 0x9016, 0x7808,
-	0xd09c, 0x0168, 0x7820, 0x201a, 0x8210, 0x8318, 0x9386, 0x1ac7,
+	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,
-	0x1ab0, 0x782c, 0x201a, 0x8318, 0x221a, 0x7803, 0x0000, 0x2069,
-	0x1a81, 0x901e, 0x20a9, 0x0020, 0x7b26, 0x7a28, 0x226a, 0x8d68,
+	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, 0x56f1, 0x1110, 0x080c, 0x0e99, 0x0cd0,
+	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, 0x2c3d, 0x1150, 0x0006, 0x2001, 0x1997, 0x2004,
+	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,
@@ -266,8 +266,8 @@
 	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, 0x2c3d, 0x1118, 0x2011, 0x8484, 0x0058,
-	0x2011, 0x8282, 0x0040, 0x080c, 0x2c3d, 0x1118, 0x2011, 0xcdc5,
+	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,
@@ -315,7 +315,7 @@
 	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, 0x841a,
+	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,
@@ -380,15 +380,15 @@
 	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, 0x6c88, 0xa09f, 0x0000, 0xa0a3, 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,
-	0x6c88, 0x000e, 0x001e, 0xd1fc, 0x1138, 0xd1f4, 0x0128, 0x00c6,
-	0x2060, 0x080c, 0xae5f, 0x00ce, 0x7008, 0x2048, 0xa89f, 0x0000,
+	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,
@@ -397,47 +397,47 @@
 	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, 0x8a12, 0x2009, 0x188c, 0x2104, 0x9084, 0xfffc,
-	0x200a, 0x080c, 0x8885, 0x7007, 0x0000, 0x080c, 0x1119, 0x0005,
+	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, 0xea53, 0x2c0d, 0x7912, 0xe104, 0x9ce0, 0x0002,
+	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, 0x1a81, 0x781f, 0xff00, 0x781b, 0xb700, 0x2001, 0x0200,
-	0x2004, 0xd0dc, 0x0110, 0x781f, 0x0303, 0x2061, 0x1a81, 0x602f,
+	0x782b, 0x1a84, 0x781f, 0xff00, 0x781b, 0xb700, 0x2001, 0x0200,
+	0x2004, 0xd0dc, 0x0110, 0x781f, 0x0303, 0x2061, 0x1a84, 0x602f,
 	0x1cd0, 0x2001, 0x181a, 0x2004, 0x9082, 0x1cd0, 0x6032, 0x603b,
-	0x209d, 0x2001, 0x3332, 0xd0fc, 0x190c, 0x0dd5, 0x2001, 0x0003,
-	0x2004, 0xd0d4, 0x1118, 0x783f, 0x3332, 0x0020, 0x9084, 0xc000,
-	0x783f, 0xb332, 0x604f, 0x193c, 0x2001, 0x1927, 0x2004, 0x6042,
+	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, 0xcb48, 0x0180, 0x2260, 0x6000,
+	0x7820, 0x0026, 0x2010, 0x080c, 0xcc74, 0x0180, 0x2260, 0x6000,
 	0x9086, 0x0004, 0x1158, 0x0016, 0x6120, 0x9186, 0x0009, 0x0108,
-	0x0020, 0x2009, 0x004c, 0x080c, 0xaeda, 0x001e, 0x002e, 0x0005,
+	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, 0x1554, 0x155b, 0x13bb, 0x155c,
-	0x155d, 0x1568, 0x156f, 0x13bb, 0x13bb, 0x13bb, 0x13bb, 0x13bb,
+	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,
-	0x157a, 0x2009, 0x1a7a, 0x2104, 0x8000, 0x200a, 0x080c, 0x7e4c,
-	0x080c, 0x1abb, 0x0005, 0x2009, 0x0048, 0x2060, 0x080c, 0xaeda,
+	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, 0x157a, 0x080c, 0x16bd, 0x0005,
-	0x080c, 0x0dd5, 0x080c, 0x157a, 0x2060, 0x6014, 0x0096, 0x2048,
-	0xa83b, 0xffff, 0x009e, 0x2009, 0x0048, 0x080c, 0xaeda, 0x2001,
+	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, 0x157f, 0x2001, 0x0307, 0x2003, 0x8000, 0x0005,
-	0x7004, 0xc095, 0x7006, 0x0005, 0x080c, 0x157a, 0x2060, 0x6014,
+	0x1110, 0x080c, 0x158c, 0x2001, 0x0307, 0x2003, 0x8000, 0x0005,
+	0x7004, 0xc095, 0x7006, 0x0005, 0x080c, 0x1587, 0x2060, 0x6014,
 	0x0096, 0x2048, 0xa83b, 0xffff, 0x009e, 0x2009, 0x0048, 0x080c,
-	0xaeda, 0x0005, 0x080c, 0x157a, 0x080c, 0x0dd5, 0x080c, 0x157a,
+	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,
@@ -446,2151 +446,2167 @@
 	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, 0x1abb,
+	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, 0x7e4c, 0x080c, 0x1abb,
-	0x080c, 0xcb5a, 0x0158, 0xa9ac, 0xa936, 0xa9b0, 0xa93a, 0xa83f,
-	0xffff, 0xa843, 0xffff, 0xa880, 0xc0bd, 0xa882, 0x080c, 0xc77b,
+	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,
-	0xaeda, 0x0048, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc,
-	0x6024, 0x190c, 0xcf44, 0x2029, 0x00c8, 0x8529, 0x0128, 0x2001,
-	0x0201, 0x2004, 0x9005, 0x0dc8, 0x7dbc, 0x080c, 0xe9fc, 0xd5a4,
-	0x1118, 0x080c, 0x157f, 0x0005, 0x080c, 0x7e4c, 0x080c, 0x1abb,
+	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, 0x15f0, 0x00fe, 0x007e,
+	0x0003, 0x0120, 0x2001, 0x0016, 0x080c, 0x15fd, 0x00fe, 0x007e,
 	0x006e, 0x001e, 0x0005, 0x7004, 0xc09d, 0x7006, 0x0005, 0x7104,
-	0x9184, 0x0004, 0x190c, 0x0dd5, 0xd184, 0x1189, 0xd19c, 0x0158,
-	0xc19c, 0x7106, 0x2001, 0x020d, 0x2003, 0x0050, 0x2003, 0x0020,
-	0x080c, 0x157f, 0x0005, 0x81ff, 0x190c, 0x0dd5, 0x0005, 0xc184,
-	0xd1b4, 0xc1b4, 0x7106, 0x0016, 0x00e6, 0x15f0, 0x2071, 0x0200,
-	0x080c, 0x16aa, 0x05c8, 0x6014, 0x9005, 0x05b0, 0x0096, 0x2048,
-	0xa864, 0x009e, 0x9084, 0x00ff, 0x908e, 0x0029, 0x0160, 0x908e,
-	0x0048, 0x1550, 0x601c, 0xd084, 0x11e0, 0x00f6, 0x2c78, 0x080c,
-	0x1727, 0x00fe, 0x00b0, 0x00f6, 0x2c78, 0x080c, 0x18ae, 0x00fe,
-	0x2009, 0x01f4, 0x8109, 0x0168, 0x2001, 0x0201, 0x2004, 0x9005,
-	0x0dc8, 0x2001, 0x0218, 0x2004, 0xd0ec, 0x1118, 0x080c, 0x157f,
-	0x0040, 0x2001, 0x020d, 0x2003, 0x0020, 0x080c, 0x1313, 0x7803,
-	0x0001, 0x00ee, 0x001e, 0x0005, 0x2001, 0x020d, 0x2003, 0x0050,
-	0x2003, 0x0020, 0x0461, 0x0ca8, 0x0429, 0x2060, 0x2009, 0x0053,
-	0x080c, 0xaeda, 0x0005, 0x0005, 0x0005, 0x00e1, 0x2008, 0x00d1,
-	0x0006, 0x7004, 0xc09d, 0x7006, 0x000e, 0x080c, 0x8d71, 0x0005,
-	0x0089, 0x9005, 0x0118, 0x080c, 0x8972, 0x0cd0, 0x0005, 0x2001,
-	0x0036, 0x2009, 0x1820, 0x210c, 0x2011, 0x181f, 0x2214, 0x080c,
-	0x15f0, 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, 0x15e2, 0x6827, 0x0001, 0x8109, 0x1dd0, 0x04d9, 0x6827,
-	0x0002, 0x04c1, 0x6804, 0x9005, 0x1130, 0x682c, 0xd0e4, 0x1500,
-	0x6804, 0x9005, 0x0de8, 0x79b8, 0xd1ec, 0x1130, 0x08c0, 0x080c,
-	0x7e4c, 0x080c, 0x1abb, 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, 0x166e, 0x7a18, 0x9284, 0x0030, 0x0904,
-	0x1669, 0x9284, 0x0048, 0x9086, 0x0008, 0x1904, 0x1669, 0x2001,
-	0x0109, 0x2004, 0xd08c, 0x01f0, 0x0006, 0x01c6, 0x01d6, 0x0136,
-	0x0146, 0x0156, 0x0126, 0x2091, 0x2800, 0x00f6, 0x0026, 0x0016,
-	0x2009, 0x1a7c, 0x2104, 0x8000, 0x0208, 0x200a, 0x080c, 0x90aa,
-	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, 0x1a7d, 0x2104, 0x8000, 0x0208, 0x200a, 0x080c, 0x1ec1,
-	0x001e, 0x00fe, 0x015e, 0x014e, 0x013e, 0x01de, 0x01ce, 0x012e,
-	0x000e, 0x7818, 0xd0bc, 0x1904, 0x1619, 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,
-	0x1a7b, 0x2104, 0x8000, 0x0208, 0x200a, 0x080c, 0xa30d, 0x2009,
-	0x180c, 0x2104, 0xc0f5, 0x200a, 0x2009, 0xff00, 0x0804, 0x1619,
-	0x9085, 0x0001, 0x0005, 0x7832, 0x7936, 0x7a3a, 0x781b, 0x8080,
-	0x080c, 0x1612, 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, 0x00e6, 0x0016, 0x2071,
-	0x0200, 0x0c41, 0x6124, 0xd1dc, 0x01f8, 0x701c, 0xd08c, 0x0904,
-	0x171c, 0x7017, 0x0000, 0x2001, 0x0264, 0x2004, 0xd0bc, 0x0904,
-	0x171c, 0x2001, 0x0268, 0x00c6, 0x2064, 0x6104, 0x6038, 0x00ce,
-	0x918e, 0x0039, 0x1904, 0x171c, 0x9c06, 0x15f0, 0x0126, 0x2091,
-	0x2600, 0x080c, 0x7d93, 0x012e, 0x7358, 0x745c, 0x6014, 0x905d,
-	0x0598, 0x2b48, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc,
-	0x190c, 0xcf1f, 0xab42, 0xac3e, 0x2001, 0x1869, 0x2004, 0xd0b4,
-	0x1170, 0x601c, 0xd0e4, 0x1158, 0x6010, 0x00b6, 0x2058, 0xb800,
-	0x00be, 0xd0bc, 0x1120, 0xa83b, 0x7fff, 0xa837, 0xffff, 0x080c,
-	0x20bd, 0x1190, 0x080c, 0x1909, 0x2a00, 0xa816, 0x0130, 0x2800,
-	0xa80e, 0x2c05, 0xa80a, 0x2c00, 0xa812, 0x7037, 0x0020, 0x781f,
-	0x0300, 0x001e, 0x00ee, 0x0005, 0x7037, 0x0050, 0x7037, 0x0020,
-	0x001e, 0x00ee, 0x080c, 0x157f, 0x0005, 0x080c, 0x0dd5, 0x2ff0,
-	0x0126, 0x2091, 0x2200, 0x00c6, 0x3e60, 0x6014, 0x2048, 0x2940,
-	0x903e, 0x2730, 0xa864, 0x2068, 0xa81a, 0x9d84, 0x000f, 0x9088,
-	0x209d, 0x2165, 0x0002, 0x1752, 0x17c0, 0x1752, 0x1752, 0x1756,
-	0x17a1, 0x1752, 0x1776, 0x174b, 0x17b7, 0x1752, 0x1752, 0x175b,
-	0x18ac, 0x178a, 0x1780, 0xa964, 0x918c, 0x00ff, 0x918e, 0x0048,
-	0x0904, 0x17b7, 0x9085, 0x0001, 0x0804, 0x18a3, 0xa87c, 0xd0ac,
-	0x0dc8, 0x0804, 0x17c7, 0xa87c, 0xd0ac, 0x0da0, 0x0804, 0x1832,
-	0xa898, 0x901d, 0x1108, 0xab9c, 0x9016, 0xaab2, 0xaa3e, 0xaa42,
-	0x3e00, 0x9080, 0x0008, 0x2004, 0x9080, 0x8f38, 0x2005, 0x9005,
-	0x090c, 0x0dd5, 0x2004, 0xa8ae, 0x0804, 0x188b, 0xa87c, 0xd0bc,
-	0x09c8, 0xa890, 0xa842, 0xa88c, 0xa83e, 0xa888, 0x0804, 0x17c7,
-	0xa87c, 0xd0bc, 0x0978, 0xa890, 0xa842, 0xa88c, 0xa83e, 0xa888,
-	0x0804, 0x1832, 0xa87c, 0xd0bc, 0x0928, 0xa890, 0xa842, 0xa88c,
-	0xa83e, 0xa804, 0x9045, 0x090c, 0x0dd5, 0xa164, 0xa91a, 0x91ec,
-	0x000f, 0x9d80, 0x209d, 0x2065, 0xa888, 0xd19c, 0x1904, 0x1832,
-	0x0430, 0xa87c, 0xd0ac, 0x0904, 0x1752, 0xa804, 0x9045, 0x090c,
-	0x0dd5, 0xa164, 0xa91a, 0x91ec, 0x000f, 0x9d80, 0x209d, 0x2065,
-	0x9006, 0xa842, 0xa83e, 0xd19c, 0x1904, 0x1832, 0x0080, 0xa87c,
-	0xd0ac, 0x0904, 0x1752, 0x9006, 0xa842, 0xa83e, 0x0804, 0x1832,
-	0xa87c, 0xd0ac, 0x0904, 0x1752, 0x9006, 0xa842, 0xa83e, 0x2c05,
-	0x908a, 0x0036, 0x1a0c, 0x0dd5, 0x9082, 0x001b, 0x0002, 0x17ea,
-	0x17ea, 0x17ec, 0x17ea, 0x17ea, 0x17ea, 0x17f6, 0x17ea, 0x17ea,
-	0x17ea, 0x1800, 0x17ea, 0x17ea, 0x17ea, 0x180a, 0x17ea, 0x17ea,
-	0x17ea, 0x1814, 0x17ea, 0x17ea, 0x17ea, 0x181e, 0x17ea, 0x17ea,
-	0x17ea, 0x1828, 0x080c, 0x0dd5, 0xa574, 0xa478, 0x9d86, 0x0024,
-	0x0904, 0x1760, 0xa37c, 0xa280, 0x0804, 0x188b, 0xa584, 0xa488,
-	0x9d86, 0x0024, 0x0904, 0x1760, 0xa38c, 0xa290, 0x0804, 0x188b,
-	0xa594, 0xa498, 0x9d86, 0x0024, 0x0904, 0x1760, 0xa39c, 0xa2a0,
-	0x0804, 0x188b, 0xa5a4, 0xa4a8, 0x9d86, 0x0024, 0x0904, 0x1760,
-	0xa3ac, 0xa2b0, 0x0804, 0x188b, 0xa5b4, 0xa4b8, 0x9d86, 0x0024,
-	0x0904, 0x1760, 0xa3bc, 0xa2c0, 0x0804, 0x188b, 0xa5c4, 0xa4c8,
-	0x9d86, 0x0024, 0x0904, 0x1760, 0xa3cc, 0xa2d0, 0x0804, 0x188b,
-	0xa5d4, 0xa4d8, 0x9d86, 0x0024, 0x0904, 0x1760, 0xa3dc, 0xa2e0,
-	0x0804, 0x188b, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0dd5, 0x9082,
-	0x001b, 0x0002, 0x1855, 0x1853, 0x1853, 0x1853, 0x1853, 0x1853,
-	0x1860, 0x1853, 0x1853, 0x1853, 0x1853, 0x1853, 0x186b, 0x1853,
-	0x1853, 0x1853, 0x1853, 0x1853, 0x1876, 0x1853, 0x1853, 0x1853,
-	0x1853, 0x1853, 0x1881, 0x080c, 0x0dd5, 0xa56c, 0xa470, 0xa774,
-	0xa678, 0x9d86, 0x002c, 0x0904, 0x1760, 0xa37c, 0xa280, 0x0458,
-	0xa584, 0xa488, 0xa78c, 0xa690, 0x9d86, 0x002c, 0x0904, 0x1760,
-	0xa394, 0xa298, 0x0400, 0xa59c, 0xa4a0, 0xa7a4, 0xa6a8, 0x9d86,
-	0x002c, 0x0904, 0x1760, 0xa3ac, 0xa2b0, 0x00a8, 0xa5b4, 0xa4b8,
-	0xa7bc, 0xa6c0, 0x9d86, 0x002c, 0x0904, 0x1760, 0xa3c4, 0xa2c8,
-	0x0050, 0xa5cc, 0xa4d0, 0xa7d4, 0xa6d8, 0x9d86, 0x002c, 0x0904,
-	0x1760, 0xa3dc, 0xa2e0, 0xab2e, 0xaa32, 0xad1e, 0xac22, 0xaf26,
-	0xae2a, 0xa988, 0x8c60, 0x2c1d, 0xa8ac, 0xaab0, 0xa836, 0xaa3a,
-	0x8109, 0xa916, 0x1158, 0x3e60, 0x601c, 0xc085, 0x601e, 0xa87c,
-	0xc0dd, 0xa87e, 0x9006, 0x00ce, 0x012e, 0x0005, 0x2800, 0xa80e,
-	0xab0a, 0x2c00, 0xa812, 0x0c78, 0x0804, 0x1752, 0x2ff0, 0x0126,
-	0x2091, 0x2200, 0x00c6, 0x3e60, 0x6014, 0x2048, 0x2940, 0xa80e,
-	0x2061, 0x2098, 0xa813, 0x2098, 0x2c05, 0xa80a, 0xa964, 0xa91a,
+	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, 0x0078, 0x918a,
-	0x0002, 0xa916, 0x1158, 0x3e60, 0x601c, 0xc085, 0x601e, 0xa87c,
-	0xc0dd, 0xa87e, 0x9006, 0x00ce, 0x012e, 0x0005, 0xa804, 0x9045,
-	0x090c, 0x0dd5, 0xa80e, 0xa064, 0xa81a, 0x9084, 0x000f, 0x9080,
-	0x209d, 0x2015, 0x82ff, 0x090c, 0x0dd5, 0xaa12, 0x2205, 0xa80a,
-	0x0c10, 0x903e, 0x2730, 0xa880, 0xd0fc, 0x1190, 0x2d00, 0x0002,
-	0x1a33, 0x1960, 0x1960, 0x1a33, 0x1960, 0x1a2d, 0x1a33, 0x1960,
-	0x19d0, 0x19d0, 0x19d0, 0x1a33, 0x19d0, 0x1a33, 0x1a2a, 0x19d0,
-	0xc0fc, 0xa882, 0xab2c, 0xaa30, 0xad1c, 0xac20, 0xdd9c, 0x0904,
-	0x1a35, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0dd5, 0x9082, 0x001b,
-	0x0002, 0x194c, 0x194a, 0x194a, 0x194a, 0x194a, 0x194a, 0x1950,
-	0x194a, 0x194a, 0x194a, 0x194a, 0x194a, 0x1954, 0x194a, 0x194a,
-	0x194a, 0x194a, 0x194a, 0x1958, 0x194a, 0x194a, 0x194a, 0x194a,
-	0x194a, 0x195c, 0x080c, 0x0dd5, 0xa774, 0xa678, 0x0804, 0x1a35,
-	0xa78c, 0xa690, 0x0804, 0x1a35, 0xa7a4, 0xa6a8, 0x0804, 0x1a35,
-	0xa7bc, 0xa6c0, 0x0804, 0x1a35, 0xa7d4, 0xa6d8, 0x0804, 0x1a35,
-	0xa898, 0x901d, 0x1108, 0xab9c, 0x9016, 0x2c05, 0x908a, 0x0036,
-	0x1a0c, 0x0dd5, 0x9082, 0x001b, 0x0002, 0x1988, 0x1988, 0x198a,
-	0x1988, 0x1988, 0x1988, 0x1994, 0x1988, 0x1988, 0x1988, 0x199e,
-	0x1988, 0x1988, 0x1988, 0x19a8, 0x1988, 0x1988, 0x1988, 0x19b2,
-	0x1988, 0x1988, 0x1988, 0x19bc, 0x1988, 0x1988, 0x1988, 0x19c6,
-	0x080c, 0x0dd5, 0xa574, 0xa478, 0x9d86, 0x0004, 0x0904, 0x1a35,
-	0xa37c, 0xa280, 0x0804, 0x1a35, 0xa584, 0xa488, 0x9d86, 0x0004,
-	0x0904, 0x1a35, 0xa38c, 0xa290, 0x0804, 0x1a35, 0xa594, 0xa498,
-	0x9d86, 0x0004, 0x0904, 0x1a35, 0xa39c, 0xa2a0, 0x0804, 0x1a35,
-	0xa5a4, 0xa4a8, 0x9d86, 0x0004, 0x0904, 0x1a35, 0xa3ac, 0xa2b0,
-	0x0804, 0x1a35, 0xa5b4, 0xa4b8, 0x9d86, 0x0004, 0x0904, 0x1a35,
-	0xa3bc, 0xa2c0, 0x0804, 0x1a35, 0xa5c4, 0xa4c8, 0x9d86, 0x0004,
-	0x0904, 0x1a35, 0xa3cc, 0xa2d0, 0x0804, 0x1a35, 0xa5d4, 0xa4d8,
-	0x9d86, 0x0004, 0x0904, 0x1a35, 0xa3dc, 0xa2e0, 0x0804, 0x1a35,
-	0xa898, 0x901d, 0x1108, 0xab9c, 0x9016, 0x2c05, 0x908a, 0x0034,
-	0x1a0c, 0x0dd5, 0x9082, 0x001b, 0x0002, 0x19f8, 0x19f6, 0x19f6,
-	0x19f6, 0x19f6, 0x19f6, 0x1a02, 0x19f6, 0x19f6, 0x19f6, 0x19f6,
-	0x19f6, 0x1a0c, 0x19f6, 0x19f6, 0x19f6, 0x19f6, 0x19f6, 0x1a16,
-	0x19f6, 0x19f6, 0x19f6, 0x19f6, 0x19f6, 0x1a20, 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, 0x2055, 0x1904,
-	0x1909, 0x900e, 0x0050, 0x080c, 0x0dd5, 0xab2e, 0xaa32, 0xad1e,
-	0xac22, 0xaf26, 0xae2a, 0x080c, 0x2055, 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, 0xaeda, 0x0005, 0xa974, 0xd1dc, 0x1108, 0x0005,
-	0xa934, 0xa88c, 0x9106, 0x1158, 0xa938, 0xa890, 0x9106, 0x1138,
-	0x601c, 0xc084, 0x601e, 0x2009, 0x0048, 0x0804, 0xaeda, 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, 0x1b43, 0x7930, 0x9186, 0x0040,
-	0x0160, 0x9186, 0x0042, 0x190c, 0x0dd5, 0x2001, 0x001e, 0x8001,
-	0x1df0, 0x8631, 0x1d40, 0x080c, 0x1b52, 0x000e, 0x6022, 0x012e,
-	0x0005, 0x080c, 0x1b3f, 0x7827, 0x0015, 0x7828, 0x9c06, 0x1db8,
-	0x782b, 0x0000, 0x0ca0, 0x00f6, 0x2079, 0x0300, 0x7803, 0x0000,
-	0x78ab, 0x0004, 0x00fe, 0x080c, 0x73b3, 0x1188, 0x2001, 0x0138,
-	0x2003, 0x0000, 0x2001, 0x0160, 0x2003, 0x0000, 0x2011, 0x012c,
-	0xa001, 0xa001, 0x8211, 0x1de0, 0x0059, 0x0804, 0x7463, 0x0479,
-	0x0039, 0x2001, 0x0160, 0x2502, 0x2001, 0x0138, 0x2202, 0x0005,
-	0x00e6, 0x2071, 0x0200, 0x080c, 0x2c51, 0x2009, 0x003c, 0x080c,
-	0x23df, 0x2001, 0x015d, 0x2003, 0x0000, 0x7000, 0x9084, 0x003c,
-	0x1de0, 0x080c, 0x841a, 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, 0x73b3, 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, 0x15f0, 0x7930,
-	0x0005, 0x2c08, 0x621c, 0x080c, 0x169b, 0x7930, 0x0005, 0x8001,
-	0x1df0, 0x0005, 0x2031, 0x0005, 0x781c, 0x9084, 0x0007, 0x0170,
-	0x2001, 0x0038, 0x0c41, 0x9186, 0x0040, 0x0904, 0x1bb0, 0x2001,
-	0x001e, 0x0c69, 0x8631, 0x1d80, 0x080c, 0x0dd5, 0x781f, 0x0202,
-	0x2001, 0x015d, 0x2003, 0x0000, 0x2001, 0x0b10, 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, 0x1b49, 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, 0x1c52, 0xa964, 0x9184, 0x0007, 0x0002, 0x1bce, 0x1c3d,
-	0x1be5, 0x1be7, 0x1be5, 0x1c25, 0x1c05, 0x1bf4, 0x918c, 0x00ff,
-	0x9186, 0x0008, 0x1170, 0xa87c, 0xd0b4, 0x0904, 0x1e7c, 0x9006,
-	0xa842, 0xa83e, 0xa988, 0x2900, 0xa85a, 0xa813, 0x2098, 0x0804,
-	0x1c4e, 0x9186, 0x0048, 0x0904, 0x1c3d, 0x080c, 0x0dd5, 0x9184,
-	0x00ff, 0x9086, 0x0013, 0x0904, 0x1c3d, 0x9184, 0x00ff, 0x9086,
-	0x001b, 0x0904, 0x1c3d, 0x0c88, 0xa87c, 0xd0b4, 0x0904, 0x1e7c,
+	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, 0xa988, 0x0804, 0x1c45, 0xa864, 0x9084, 0x00ff,
-	0x9086, 0x001e, 0x19d0, 0xa87c, 0xd0b4, 0x0904, 0x1e7c, 0xa890,
-	0xa842, 0xa83a, 0xa88c, 0xa83e, 0xa836, 0xa8ac, 0xa846, 0xa8b0,
-	0xa84a, 0xa804, 0xa85a, 0x2040, 0xa064, 0x9084, 0x000f, 0x9080,
-	0x209d, 0x2005, 0xa812, 0xa988, 0x0448, 0x918c, 0x00ff, 0x9186,
-	0x0015, 0x1540, 0xa87c, 0xd0b4, 0x0904, 0x1e7c, 0xa804, 0xa85a,
-	0x2040, 0xa064, 0x9084, 0x000f, 0x9080, 0x209d, 0x2005, 0xa812,
-	0xa988, 0x9006, 0xa842, 0xa83e, 0x0088, 0xa87c, 0xd0b4, 0x0904,
-	0x1e7c, 0xa988, 0x9006, 0xa842, 0xa83e, 0x2900, 0xa85a, 0xa864,
-	0x9084, 0x000f, 0x9080, 0x209d, 0x2005, 0xa812, 0xa916, 0xa87c,
-	0xc0dd, 0xa87e, 0x0005, 0x00f6, 0x2079, 0x0090, 0x782c, 0xd0fc,
-	0x190c, 0x1ec1, 0x00e6, 0x2071, 0x1a65, 0x7000, 0x9005, 0x1904,
-	0x1cbb, 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, 0x20bd, 0x004e, 0x003e, 0x0d30, 0x0c98,
-	0x9085, 0x0001, 0x0c80, 0x2009, 0x0306, 0x200b, 0x4800, 0x7027,
-	0x0000, 0x0005, 0x0076, 0x0066, 0x0056, 0x0046, 0x0036, 0x0026,
-	0x8aff, 0x0904, 0x1e75, 0x700c, 0x7214, 0x923a, 0x7010, 0x7218,
-	0x9203, 0x0a04, 0x1e74, 0x9705, 0x0904, 0x1e74, 0x903e, 0x2730,
-	0xa880, 0xd0fc, 0x1190, 0x2d00, 0x0002, 0x1dfe, 0x1d3d, 0x1d3d,
-	0x1dfe, 0x1dfe, 0x1ddb, 0x1dfe, 0x1d3d, 0x1de2, 0x1d8c, 0x1d8c,
-	0x1dfe, 0x1dfe, 0x1dfe, 0x1dd5, 0x1d8c, 0xc0fc, 0xa882, 0xab2c,
-	0xaa30, 0xad1c, 0xac20, 0xdd9c, 0x0904, 0x1e0b, 0x2c05, 0x908a,
-	0x0034, 0x1a0c, 0x0dd5, 0x9082, 0x001b, 0x0002, 0x1d29, 0x1d27,
-	0x1d27, 0x1d27, 0x1d27, 0x1d27, 0x1d2d, 0x1d27, 0x1d27, 0x1d27,
-	0x1d27, 0x1d27, 0x1d31, 0x1d27, 0x1d27, 0x1d27, 0x1d27, 0x1d27,
-	0x1d35, 0x1d27, 0x1d27, 0x1d27, 0x1d27, 0x1d27, 0x1d39, 0x080c,
-	0x0dd5, 0xa774, 0xa678, 0x0804, 0x1e0b, 0xa78c, 0xa690, 0x0804,
-	0x1e0b, 0xa7a4, 0xa6a8, 0x0804, 0x1e0b, 0xa7bc, 0xa6c0, 0x0804,
-	0x1e0b, 0xa7d4, 0xa6d8, 0x0804, 0x1e0b, 0x2c05, 0x908a, 0x0036,
-	0x1a0c, 0x0dd5, 0x9082, 0x001b, 0x0002, 0x1d60, 0x1d60, 0x1d62,
-	0x1d60, 0x1d60, 0x1d60, 0x1d68, 0x1d60, 0x1d60, 0x1d60, 0x1d6e,
-	0x1d60, 0x1d60, 0x1d60, 0x1d74, 0x1d60, 0x1d60, 0x1d60, 0x1d7a,
-	0x1d60, 0x1d60, 0x1d60, 0x1d80, 0x1d60, 0x1d60, 0x1d60, 0x1d86,
-	0x080c, 0x0dd5, 0xa574, 0xa478, 0xa37c, 0xa280, 0x0804, 0x1e0b,
-	0xa584, 0xa488, 0xa38c, 0xa290, 0x0804, 0x1e0b, 0xa594, 0xa498,
-	0xa39c, 0xa2a0, 0x0804, 0x1e0b, 0xa5a4, 0xa4a8, 0xa3ac, 0xa2b0,
-	0x0804, 0x1e0b, 0xa5b4, 0xa4b8, 0xa3bc, 0xa2c0, 0x0804, 0x1e0b,
-	0xa5c4, 0xa4c8, 0xa3cc, 0xa2d0, 0x0804, 0x1e0b, 0xa5d4, 0xa4d8,
-	0xa3dc, 0xa2e0, 0x0804, 0x1e0b, 0x2c05, 0x908a, 0x0034, 0x1a0c,
-	0x0dd5, 0x9082, 0x001b, 0x0002, 0x1daf, 0x1dad, 0x1dad, 0x1dad,
-	0x1dad, 0x1dad, 0x1db7, 0x1dad, 0x1dad, 0x1dad, 0x1dad, 0x1dad,
-	0x1dbf, 0x1dad, 0x1dad, 0x1dad, 0x1dad, 0x1dad, 0x1dc7, 0x1dad,
-	0x1dad, 0x1dad, 0x1dad, 0x1dad, 0x1dce, 0x080c, 0x0dd5, 0xa56c,
-	0xa470, 0xa774, 0xa678, 0xa37c, 0xa280, 0x0804, 0x1e0b, 0xa584,
-	0xa488, 0xa78c, 0xa690, 0xa394, 0xa298, 0x0804, 0x1e0b, 0xa59c,
-	0xa4a0, 0xa7a4, 0xa6a8, 0xa3ac, 0xa2b0, 0x0804, 0x1e0b, 0xa5b4,
-	0xa4b8, 0xa7bc, 0xa6c0, 0xa3c4, 0xa2c8, 0x04e8, 0xa5cc, 0xa4d0,
-	0xa7d4, 0xa6d8, 0xa3dc, 0xa2e0, 0x04b0, 0xa864, 0x9084, 0x00ff,
-	0x9086, 0x001e, 0x1518, 0x080c, 0x2055, 0x1904, 0x1cd8, 0x900e,
-	0x0804, 0x1e75, 0xab64, 0x939c, 0x00ff, 0x9386, 0x0048, 0x1180,
-	0x00c6, 0x7004, 0x2060, 0x6004, 0x9086, 0x0043, 0x00ce, 0x0904,
-	0x1d8c, 0xab9c, 0x9016, 0xad8c, 0xac90, 0xaf94, 0xae98, 0x0098,
-	0x9386, 0x0008, 0x0904, 0x1d8c, 0x080c, 0x0dd5, 0xa964, 0x918c,
-	0x00ff, 0x9186, 0x0013, 0x0904, 0x1d3d, 0x9186, 0x001b, 0x0904,
-	0x1d8c, 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, 0x2055, 0x0428,
-	0x2031, 0x0080, 0x9584, 0x007f, 0x0108, 0x9632, 0x7124, 0x7000,
-	0x9086, 0x0000, 0x1198, 0xc185, 0x7126, 0x2009, 0x0306, 0x2104,
-	0xd0b4, 0x1904, 0x1e1b, 0x200b, 0x4040, 0x2009, 0x1a7e, 0x2104,
-	0x8000, 0x0a04, 0x1e1b, 0x200a, 0x0804, 0x1e1b, 0xc18d, 0x7126,
-	0xd184, 0x1d58, 0x0804, 0x1e1b, 0x9006, 0x002e, 0x003e, 0x004e,
-	0x005e, 0x006e, 0x007e, 0x0005, 0x080c, 0x0dd5, 0x0026, 0x2001,
-	0x0105, 0x2003, 0x0010, 0x782b, 0x0004, 0x7003, 0x0000, 0x7004,
-	0x0016, 0x080c, 0x1ccb, 0x001e, 0x2060, 0x6014, 0x2048, 0x080c,
-	0xcb5a, 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, 0xc77b, 0x00ce, 0x2001, 0x19f5, 0x2004,
-	0x9c06, 0x1160, 0x2009, 0x0040, 0x080c, 0x23df, 0x080c, 0xa7b7,
-	0x2011, 0x0000, 0x080c, 0xa648, 0x080c, 0x97d4, 0x002e, 0x0804,
-	0x2005, 0x0126, 0x2091, 0x2400, 0xa858, 0x2040, 0x792c, 0x782b,
-	0x0002, 0x9184, 0x0700, 0x1904, 0x1e7e, 0x7000, 0x0002, 0x2005,
-	0x1ed3, 0x1f53, 0x2003, 0x8001, 0x7002, 0x7027, 0x0000, 0xd19c,
-	0x1158, 0x8aff, 0x0904, 0x1f20, 0x080c, 0x1cd2, 0x0904, 0x2005,
-	0x080c, 0x1cd2, 0x0804, 0x2005, 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, 0x2070, 0xa880, 0xc0fd, 0xa882,
-	0x2a00, 0xa816, 0x2800, 0xa85a, 0x2c00, 0xa812, 0x7003, 0x0000,
-	0x2009, 0x0306, 0x200b, 0x4800, 0x7027, 0x0000, 0x0804, 0x2005,
-	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,
-	0x1ccb, 0x0804, 0x2005, 0x8001, 0x7002, 0x7024, 0x8004, 0x7026,
-	0xd194, 0x0170, 0x782c, 0xd0fc, 0x1904, 0x1ec6, 0xd19c, 0x1904,
-	0x2001, 0x8aff, 0x0904, 0x2005, 0x080c, 0x1cd2, 0x0804, 0x2005,
-	0x0026, 0x0036, 0xab3c, 0xaa40, 0x080c, 0x2070, 0xdd9c, 0x1904,
-	0x1fc0, 0x2c05, 0x908a, 0x0036, 0x1a0c, 0x0dd5, 0x9082, 0x001b,
-	0x0002, 0x1f94, 0x1f94, 0x1f96, 0x1f94, 0x1f94, 0x1f94, 0x1f9c,
-	0x1f94, 0x1f94, 0x1f94, 0x1fa2, 0x1f94, 0x1f94, 0x1f94, 0x1fa8,
-	0x1f94, 0x1f94, 0x1f94, 0x1fae, 0x1f94, 0x1f94, 0x1f94, 0x1fb4,
-	0x1f94, 0x1f94, 0x1f94, 0x1fba, 0x080c, 0x0dd5, 0xa07c, 0x931a,
-	0xa080, 0x9213, 0x0804, 0x1ef5, 0xa08c, 0x931a, 0xa090, 0x9213,
-	0x0804, 0x1ef5, 0xa09c, 0x931a, 0xa0a0, 0x9213, 0x0804, 0x1ef5,
-	0xa0ac, 0x931a, 0xa0b0, 0x9213, 0x0804, 0x1ef5, 0xa0bc, 0x931a,
-	0xa0c0, 0x9213, 0x0804, 0x1ef5, 0xa0cc, 0x931a, 0xa0d0, 0x9213,
-	0x0804, 0x1ef5, 0xa0dc, 0x931a, 0xa0e0, 0x9213, 0x0804, 0x1ef5,
-	0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0dd5, 0x9082, 0x001b, 0x0002,
-	0x1fe3, 0x1fe1, 0x1fe1, 0x1fe1, 0x1fe1, 0x1fe1, 0x1fe9, 0x1fe1,
-	0x1fe1, 0x1fe1, 0x1fe1, 0x1fe1, 0x1fef, 0x1fe1, 0x1fe1, 0x1fe1,
-	0x1fe1, 0x1fe1, 0x1ff5, 0x1fe1, 0x1fe1, 0x1fe1, 0x1fe1, 0x1fe1,
-	0x1ffb, 0x080c, 0x0dd5, 0xa07c, 0x931a, 0xa080, 0x9213, 0x0804,
-	0x1ef5, 0xa094, 0x931a, 0xa098, 0x9213, 0x0804, 0x1ef5, 0xa0ac,
-	0x931a, 0xa0b0, 0x9213, 0x0804, 0x1ef5, 0xa0c4, 0x931a, 0xa0c8,
-	0x9213, 0x0804, 0x1ef5, 0xa0dc, 0x931a, 0xa0e0, 0x9213, 0x0804,
-	0x1ef5, 0x0804, 0x1ef1, 0x080c, 0x0dd5, 0x012e, 0x0005, 0x00f6,
-	0x00e6, 0x2071, 0x1a65, 0x7000, 0x9086, 0x0000, 0x0904, 0x2050,
-	0x2079, 0x0090, 0x2009, 0x0207, 0x210c, 0xd194, 0x01b8, 0x2009,
-	0x020c, 0x210c, 0x9184, 0x0003, 0x0188, 0x080c, 0xea45, 0x2001,
-	0x0133, 0x2004, 0x9005, 0x090c, 0x0dd5, 0x0016, 0x2009, 0x0040,
-	0x080c, 0x23df, 0x001e, 0x2001, 0x020c, 0x2102, 0x2009, 0x0206,
-	0x2104, 0x2009, 0x0203, 0x210c, 0x9106, 0x1120, 0x2009, 0x0040,
-	0x080c, 0x23df, 0x782c, 0xd0fc, 0x09a8, 0x080c, 0x1ec1, 0x7000,
-	0x9086, 0x0000, 0x1978, 0x782b, 0x0004, 0x782c, 0xd0ac, 0x1de8,
-	0x2009, 0x0040, 0x080c, 0x23df, 0x782b, 0x0002, 0x7003, 0x0000,
-	0x080c, 0x1ccb, 0x00ee, 0x00fe, 0x0005, 0xa880, 0xd0fc, 0x11a8,
-	0x8c60, 0x2c05, 0x9005, 0x0110, 0x8a51, 0x0005, 0xa004, 0x9005,
-	0x0168, 0xa85a, 0x2040, 0xa064, 0x9084, 0x000f, 0x9080, 0x209d,
-	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, 0x20ad, 0x2065, 0x8cff,
-	0x090c, 0x0dd5, 0x0005, 0x0000, 0x001d, 0x0021, 0x0025, 0x0029,
-	0x002d, 0x0031, 0x0035, 0x0000, 0x001b, 0x0021, 0x0027, 0x002d,
-	0x0033, 0x0000, 0x0000, 0x0023, 0x0000, 0x0000, 0x2090, 0x208c,
-	0x2090, 0x2090, 0x209a, 0x0000, 0x2090, 0x2097, 0x2097, 0x2094,
-	0x2097, 0x2097, 0x0000, 0x209a, 0x2097, 0x0000, 0x2092, 0x2092,
-	0x0000, 0x2092, 0x209a, 0x0000, 0x2092, 0x2098, 0x2098, 0x2098,
-	0x0000, 0x2098, 0x0000, 0x209a, 0x2098, 0x00c6, 0x00d6, 0x0086,
-	0xab42, 0xac3e, 0xa888, 0x9055, 0x0904, 0x229c, 0x2940, 0xa064,
-	0x90ec, 0x000f, 0x9084, 0x00ff, 0x9086, 0x0008, 0x1118, 0x2061,
-	0x2098, 0x00d0, 0x9de0, 0x209d, 0x9d86, 0x0007, 0x0130, 0x9d86,
-	0x000e, 0x0118, 0x9d86, 0x000f, 0x1120, 0xa08c, 0x9422, 0xa090,
-	0x931b, 0x2c05, 0x9065, 0x1140, 0x0310, 0x0804, 0x229c, 0xa004,
-	0x9045, 0x0904, 0x229c, 0x08d8, 0x2c05, 0x9005, 0x0904, 0x2184,
-	0xdd9c, 0x1904, 0x2140, 0x908a, 0x0036, 0x1a0c, 0x0dd5, 0x9082,
-	0x001b, 0x0002, 0x2115, 0x2115, 0x2117, 0x2115, 0x2115, 0x2115,
-	0x211d, 0x2115, 0x2115, 0x2115, 0x2123, 0x2115, 0x2115, 0x2115,
-	0x2129, 0x2115, 0x2115, 0x2115, 0x212f, 0x2115, 0x2115, 0x2115,
-	0x2135, 0x2115, 0x2115, 0x2115, 0x213b, 0x080c, 0x0dd5, 0xa07c,
-	0x9422, 0xa080, 0x931b, 0x0804, 0x217a, 0xa08c, 0x9422, 0xa090,
-	0x931b, 0x0804, 0x217a, 0xa09c, 0x9422, 0xa0a0, 0x931b, 0x0804,
-	0x217a, 0xa0ac, 0x9422, 0xa0b0, 0x931b, 0x0804, 0x217a, 0xa0bc,
-	0x9422, 0xa0c0, 0x931b, 0x0804, 0x217a, 0xa0cc, 0x9422, 0xa0d0,
-	0x931b, 0x0804, 0x217a, 0xa0dc, 0x9422, 0xa0e0, 0x931b, 0x04d0,
-	0x908a, 0x0034, 0x1a0c, 0x0dd5, 0x9082, 0x001b, 0x0002, 0x2162,
-	0x2160, 0x2160, 0x2160, 0x2160, 0x2160, 0x2167, 0x2160, 0x2160,
-	0x2160, 0x2160, 0x2160, 0x216c, 0x2160, 0x2160, 0x2160, 0x2160,
-	0x2160, 0x2171, 0x2160, 0x2160, 0x2160, 0x2160, 0x2160, 0x2176,
-	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,
-	0x229c, 0x8c60, 0x0804, 0x20ec, 0xa004, 0x9045, 0x0904, 0x229c,
-	0x0804, 0x20c7, 0x8a51, 0x0904, 0x229c, 0x8c60, 0x2c05, 0x9005,
-	0x1158, 0xa004, 0x9045, 0x0904, 0x229c, 0xa064, 0x90ec, 0x000f,
-	0x9de0, 0x209d, 0x2c05, 0x2060, 0xa880, 0xc0fc, 0xa882, 0x0804,
-	0x2291, 0x2c05, 0x8422, 0x8420, 0x831a, 0x9399, 0x0000, 0xac2e,
-	0xab32, 0xdd9c, 0x1904, 0x222e, 0x9082, 0x001b, 0x0002, 0x21ca,
-	0x21ca, 0x21cc, 0x21ca, 0x21ca, 0x21ca, 0x21da, 0x21ca, 0x21ca,
-	0x21ca, 0x21e8, 0x21ca, 0x21ca, 0x21ca, 0x21f6, 0x21ca, 0x21ca,
-	0x21ca, 0x2204, 0x21ca, 0x21ca, 0x21ca, 0x2212, 0x21ca, 0x21ca,
-	0x21ca, 0x2220, 0x080c, 0x0dd5, 0xa17c, 0x2400, 0x9122, 0xa180,
-	0x2300, 0x911b, 0x0a0c, 0x0dd5, 0xa074, 0x9420, 0xa078, 0x9319,
-	0x0804, 0x228c, 0xa18c, 0x2400, 0x9122, 0xa190, 0x2300, 0x911b,
-	0x0a0c, 0x0dd5, 0xa084, 0x9420, 0xa088, 0x9319, 0x0804, 0x228c,
-	0xa19c, 0x2400, 0x9122, 0xa1a0, 0x2300, 0x911b, 0x0a0c, 0x0dd5,
-	0xa094, 0x9420, 0xa098, 0x9319, 0x0804, 0x228c, 0xa1ac, 0x2400,
-	0x9122, 0xa1b0, 0x2300, 0x911b, 0x0a0c, 0x0dd5, 0xa0a4, 0x9420,
-	0xa0a8, 0x9319, 0x0804, 0x228c, 0xa1bc, 0x2400, 0x9122, 0xa1c0,
+	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,
-	0x0804, 0x228c, 0xa1cc, 0x2400, 0x9122, 0xa1d0, 0x2300, 0x911b,
-	0x0a0c, 0x0dd5, 0xa0c4, 0x9420, 0xa0c8, 0x9319, 0x0804, 0x228c,
-	0xa1dc, 0x2400, 0x9122, 0xa1e0, 0x2300, 0x911b, 0x0a0c, 0x0dd5,
-	0xa0d4, 0x9420, 0xa0d8, 0x9319, 0x0804, 0x228c, 0x9082, 0x001b,
-	0x0002, 0x224c, 0x224a, 0x224a, 0x224a, 0x224a, 0x224a, 0x2259,
-	0x224a, 0x224a, 0x224a, 0x224a, 0x224a, 0x2266, 0x224a, 0x224a,
-	0x224a, 0x224a, 0x224a, 0x2273, 0x224a, 0x224a, 0x224a, 0x224a,
-	0x224a, 0x2280, 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, 0x22bd, 0x1ec1, 0x22bd, 0x22b3, 0x22b6,
-	0x22b9, 0x22b6, 0x22b9, 0x080c, 0x1ec1, 0x0005, 0x080c, 0x11a3,
-	0x0005, 0x080c, 0x1ec1, 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, 0x23dc, 0x7900, 0xd1dc, 0x1118, 0x9084, 0x0006,
-	0x001a, 0x9084, 0x000e, 0x0002, 0x2304, 0x22fc, 0x7d93, 0x22fc,
-	0x22fe, 0x22fe, 0x22fe, 0x22fe, 0x7d79, 0x22fc, 0x2300, 0x22fc,
-	0x22fe, 0x22fc, 0x22fe, 0x22fc, 0x080c, 0x0dd5, 0x0031, 0x0020,
-	0x080c, 0x7d79, 0x080c, 0x7d93, 0x0005, 0x0006, 0x0016, 0x0026,
-	0x080c, 0xea45, 0x7930, 0x9184, 0x0003, 0x01c0, 0x2001, 0x19f5,
-	0x2004, 0x9005, 0x0170, 0x2001, 0x0133, 0x2004, 0x9005, 0x090c,
-	0x0dd5, 0x00c6, 0x2001, 0x19f5, 0x2064, 0x080c, 0xc77b, 0x00ce,
-	0x00f8, 0x2009, 0x0040, 0x080c, 0x23df, 0x00d0, 0x9184, 0x0014,
-	0x01a0, 0x6a00, 0x9286, 0x0003, 0x0160, 0x080c, 0x73b3, 0x1138,
-	0x080c, 0x7699, 0x080c, 0x602d, 0x080c, 0x72e5, 0x0010, 0x080c,
-	0x5eec, 0x080c, 0x7e42, 0x0041, 0x0018, 0x9184, 0x9540, 0x1dc8,
-	0x002e, 0x001e, 0x000e, 0x0005, 0x00e6, 0x0036, 0x0046, 0x0056,
-	0x2071, 0x1a61, 0x080c, 0x1abb, 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, 0x2c4b, 0x080c, 0x2b66, 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, 0x2baa, 0x1238, 0x939d, 0x4003, 0x94a5, 0x8603,
-	0x230a, 0x2412, 0x0030, 0x939d, 0x0203, 0x94a5, 0x8603, 0x230a,
-	0x2412, 0x9006, 0x080c, 0x2b95, 0x9006, 0x080c, 0x2b78, 0x20a9,
-	0x0012, 0x1d04, 0x2431, 0x2091, 0x6000, 0x1f04, 0x2431, 0x602f,
-	0x0100, 0x602f, 0x0000, 0x6050, 0x9085, 0x0400, 0x9084, 0xdfff,
-	0x6052, 0x6024, 0x6026, 0x080c, 0x2884, 0x2009, 0x00ef, 0x6132,
-	0x6136, 0x080c, 0x2894, 0x60e7, 0x0000, 0x61ea, 0x60e3, 0x0008,
-	0x604b, 0xf7f7, 0x6043, 0x0000, 0x602f, 0x0080, 0x602f, 0x0000,
-	0x6007, 0x349f, 0x60bb, 0x0000, 0x20a9, 0x0018, 0x60bf, 0x0000,
-	0x1f04, 0x245e, 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, 0x24e1,
-	0x24c7, 0x24ca, 0x24cd, 0x24d2, 0x24d4, 0x24d8, 0x24dc, 0x080c,
-	0x8fdd, 0x00b8, 0x080c, 0x90aa, 0x00a0, 0x080c, 0x90aa, 0x080c,
-	0x8fdd, 0x0078, 0x0099, 0x0068, 0x080c, 0x8fdd, 0x0079, 0x0048,
-	0x080c, 0x90aa, 0x0059, 0x0028, 0x080c, 0x90aa, 0x080c, 0x8fdd,
-	0x0029, 0x002e, 0x001e, 0x000e, 0x012e, 0x0005, 0x00a6, 0x6124,
-	0x6028, 0xd09c, 0x0118, 0xd19c, 0x1904, 0x2749, 0xd1f4, 0x190c,
-	0x0dce, 0x080c, 0x73b3, 0x0904, 0x253c, 0x080c, 0xd25a, 0x1120,
-	0x7000, 0x9086, 0x0003, 0x0570, 0x6024, 0x9084, 0x1800, 0x0550,
-	0x080c, 0x73d6, 0x0118, 0x080c, 0x73c4, 0x1520, 0x6027, 0x0020,
-	0x6043, 0x0000, 0x080c, 0xd25a, 0x0168, 0x080c, 0x73d6, 0x1150,
-	0x2001, 0x19a6, 0x2003, 0x0001, 0x6027, 0x1800, 0x080c, 0x7249,
-	0x0804, 0x274c, 0x70a4, 0x9005, 0x1150, 0x70a7, 0x0001, 0x00d6,
-	0x2069, 0x0140, 0x080c, 0x740a, 0x00de, 0x1904, 0x274c, 0x080c,
-	0x76a3, 0x0428, 0x080c, 0x73d6, 0x1590, 0x6024, 0x9084, 0x1800,
-	0x1108, 0x0468, 0x080c, 0x76a3, 0x080c, 0x7699, 0x080c, 0x602d,
-	0x080c, 0x72e5, 0x0804, 0x2749, 0xd1ac, 0x1508, 0x6024, 0xd0dc,
-	0x1170, 0xd0e4, 0x1178, 0xd0d4, 0x1190, 0xd0cc, 0x0130, 0x7098,
-	0x9086, 0x0028, 0x1110, 0x080c, 0x7586, 0x0804, 0x2749, 0x080c,
-	0x769e, 0x0048, 0x2001, 0x197c, 0x2003, 0x0002, 0x0020, 0x080c,
-	0x74eb, 0x0804, 0x2749, 0x080c, 0x7621, 0x0804, 0x2749, 0x6220,
-	0xd1bc, 0x0138, 0xd2bc, 0x1904, 0x27bc, 0xd2b4, 0x1904, 0x27cf,
-	0x0000, 0xd1ac, 0x0904, 0x265e, 0x0036, 0x6328, 0xc3bc, 0x632a,
-	0x003e, 0x080c, 0x73b3, 0x11c0, 0x6027, 0x0020, 0x0006, 0x0026,
-	0x0036, 0x080c, 0x73cd, 0x1158, 0x080c, 0x7699, 0x080c, 0x602d,
-	0x080c, 0x72e5, 0x003e, 0x002e, 0x000e, 0x00ae, 0x0005, 0x003e,
-	0x002e, 0x000e, 0x080c, 0x738b, 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, 0x4b1e, 0x003e, 0x080c,
-	0xd253, 0x1904, 0x263b, 0x9196, 0xff00, 0x05a8, 0x7060, 0x9084,
-	0x00ff, 0x810f, 0x81ff, 0x0110, 0x9116, 0x0568, 0x7130, 0xd184,
-	0x1550, 0x080c, 0x3326, 0x0128, 0xc18d, 0x7132, 0x080c, 0x6981,
-	0x1510, 0x6240, 0x9294, 0x0010, 0x0130, 0x6248, 0x9294, 0xff00,
-	0x9296, 0xff00, 0x01c0, 0x7030, 0xd08c, 0x0904, 0x263b, 0x7038,
-	0xd08c, 0x1140, 0x2001, 0x180c, 0x200c, 0xd1ac, 0x1904, 0x263b,
-	0xc1ad, 0x2102, 0x0036, 0x73d8, 0x2011, 0x8013, 0x080c, 0x4b1e,
-	0x003e, 0x0804, 0x263b, 0x7038, 0xd08c, 0x1140, 0x2001, 0x180c,
-	0x200c, 0xd1ac, 0x1904, 0x263b, 0xc1ad, 0x2102, 0x0036, 0x73d8,
-	0x2011, 0x8013, 0x080c, 0x4b1e, 0x003e, 0x7130, 0xc185, 0x7132,
-	0x2011, 0x1848, 0x220c, 0xd1a4, 0x01f0, 0x0016, 0x2009, 0x0001,
-	0x2011, 0x0100, 0x080c, 0x86e3, 0x2019, 0x000e, 0x00c6, 0x2061,
-	0x0000, 0x080c, 0xe55d, 0x00ce, 0x9484, 0x00ff, 0x9080, 0x3332,
-	0x200d, 0x918c, 0xff00, 0x810f, 0x2120, 0x9006, 0x2009, 0x000e,
-	0x080c, 0xe5e9, 0x001e, 0x0016, 0x2009, 0x0002, 0x2019, 0x0004,
-	0x080c, 0x3197, 0x001e, 0x0078, 0x0156, 0x00b6, 0x20a9, 0x007f,
-	0x900e, 0x080c, 0x6616, 0x1110, 0x080c, 0x6047, 0x8108, 0x1f04,
-	0x2631, 0x00be, 0x015e, 0x00ce, 0x004e, 0x080c, 0xadd0, 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,
-	0x2749, 0x0016, 0x6220, 0xd2b4, 0x0904, 0x26e6, 0x080c, 0x857f,
-	0x080c, 0xa28f, 0x6027, 0x0004, 0x00f6, 0x2019, 0x19ef, 0x2304,
-	0x907d, 0x0904, 0x26b5, 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, 0x2d0c, 0x2001,
-	0x001e, 0x8001, 0x0240, 0x20a9, 0x0009, 0x080c, 0x2c26, 0x6904,
-	0xd1dc, 0x1140, 0x0cb0, 0x2001, 0x0100, 0x080c, 0x2cfc, 0x9006,
-	0x080c, 0x2cfc, 0x080c, 0x959a, 0x080c, 0x96a6, 0x7814, 0x2048,
-	0xa867, 0x0103, 0x2f60, 0x080c, 0xae5f, 0x009e, 0x00ee, 0x00ce,
-	0x00de, 0x00fe, 0x001e, 0x00ae, 0x0005, 0x00fe, 0x00d6, 0x2069,
-	0x0140, 0x6804, 0x9084, 0x4000, 0x0110, 0x080c, 0x2d0c, 0x00de,
-	0x00c6, 0x2061, 0x19e6, 0x6028, 0x080c, 0xd25a, 0x0120, 0x909a,
-	0x0003, 0x1258, 0x0018, 0x909a, 0x00c8, 0x1238, 0x8000, 0x602a,
-	0x00ce, 0x080c, 0xa26b, 0x0804, 0x2748, 0x2061, 0x0100, 0x62c0,
-	0x080c, 0xac56, 0x2019, 0x19ef, 0x2304, 0x9065, 0x0120, 0x2009,
-	0x0027, 0x080c, 0xaeda, 0x00ce, 0x0804, 0x2748, 0xd2bc, 0x0904,
-	0x272f, 0x080c, 0x858c, 0x6014, 0x9084, 0x1984, 0x9085, 0x0010,
-	0x6016, 0x6027, 0x0004, 0x00d6, 0x2069, 0x0140, 0x6804, 0x9084,
-	0x4000, 0x0110, 0x080c, 0x2d0c, 0x00de, 0x00c6, 0x2061, 0x19e6,
-	0x6044, 0x080c, 0xd25a, 0x0120, 0x909a, 0x0003, 0x1658, 0x0018,
-	0x909a, 0x00c8, 0x1638, 0x8000, 0x6046, 0x603c, 0x00ce, 0x9005,
-	0x05b8, 0x2009, 0x07d0, 0x080c, 0x8584, 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, 0xa5c8, 0x003e,
-	0x2019, 0x19f5, 0x2304, 0x9065, 0x0150, 0x2009, 0x004f, 0x6020,
-	0x9086, 0x0009, 0x1110, 0x2009, 0x004f, 0x080c, 0xaeda, 0x00ce,
-	0x001e, 0xd19c, 0x0904, 0x27b7, 0x7038, 0xd0ac, 0x1904, 0x2790,
-	0x0016, 0x0156, 0x6027, 0x0008, 0x6050, 0x9085, 0x0040, 0x6052,
-	0x6050, 0x9084, 0xfbcf, 0x6052, 0x080c, 0x2c45, 0x9085, 0x2000,
-	0x6052, 0x20a9, 0x0012, 0x1d04, 0x2763, 0x080c, 0x85b3, 0x1f04,
-	0x2763, 0x6050, 0x9085, 0x0400, 0x9084, 0xdfbf, 0x6052, 0x20a9,
-	0x0028, 0xa001, 0x1f04, 0x2771, 0x6150, 0x9185, 0x1400, 0x6052,
-	0x20a9, 0x0366, 0x1d04, 0x277a, 0x080c, 0x85b3, 0x6020, 0xd09c,
-	0x1130, 0x015e, 0x6152, 0x001e, 0x6027, 0x0008, 0x0480, 0x080c,
-	0x2c0d, 0x1f04, 0x277a, 0x015e, 0x6152, 0x001e, 0x6027, 0x0008,
-	0x0016, 0x6028, 0xc09c, 0x602a, 0x080c, 0xadd0, 0x60e3, 0x0000,
-	0x080c, 0xea24, 0x080c, 0xea3f, 0x080c, 0x56e6, 0xd0fc, 0x1138,
-	0x080c, 0xd253, 0x1120, 0x9085, 0x0001, 0x080c, 0x73fa, 0x9006,
-	0x080c, 0x2cfc, 0x2009, 0x0002, 0x080c, 0x2c4b, 0x2001, 0x1800,
-	0x2003, 0x0004, 0x6027, 0x0008, 0x080c, 0x0bae, 0x001e, 0x918c,
-	0xffd0, 0x6126, 0x00ae, 0x0005, 0x0016, 0x2001, 0x188b, 0x200c,
-	0xd184, 0x001e, 0x0904, 0x2569, 0x0016, 0x2009, 0x27c8, 0x00d0,
-	0x2001, 0x188b, 0x200c, 0xc184, 0x2102, 0x001e, 0x0c40, 0x0016,
-	0x2001, 0x188b, 0x200c, 0xd194, 0x001e, 0x0904, 0x2569, 0x0016,
-	0x2009, 0x27db, 0x0038, 0x2001, 0x188b, 0x200c, 0xc194, 0x2102,
-	0x001e, 0x08a8, 0x6028, 0xc0bc, 0x602a, 0x2001, 0x0156, 0x2003,
-	0xbc91, 0x8000, 0x2003, 0xffff, 0x6043, 0x0001, 0x080c, 0x2c45,
-	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, 0x2c4b, 0x2011, 0x8011, 0x2019, 0x010e,
-	0x231c, 0x939e, 0x0007, 0x1118, 0x2019, 0x0001, 0x0010, 0x2019,
-	0x0000, 0x080c, 0x4b1e, 0x0438, 0x2001, 0x19a7, 0x200c, 0x81ff,
-	0x1140, 0x2001, 0x0109, 0x2004, 0xd0b4, 0x0118, 0x2019, 0x0003,
-	0x0008, 0x2118, 0x2011, 0x8012, 0x080c, 0x4b1e, 0x080c, 0x56e6,
-	0xd0fc, 0x1188, 0x080c, 0xd253, 0x1170, 0x00c6, 0x080c, 0x28df,
-	0x080c, 0xa52f, 0x2061, 0x0100, 0x2019, 0x0028, 0x2009, 0x0002,
-	0x080c, 0x3197, 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, 0x80b4, 0x0048, 0x9584, 0x00ff, 0x9080, 0x3332,
-	0x200d, 0x918c, 0xff00, 0x810f, 0x9006, 0x0005, 0x9080, 0x3332,
-	0x200d, 0x918c, 0x00ff, 0x0005, 0x00d6, 0x2069, 0x0140, 0x2001,
-	0x1818, 0x2003, 0x00ef, 0x20a9, 0x0010, 0x9006, 0x6852, 0x6856,
-	0x1f04, 0x288f, 0x00de, 0x0005, 0x0006, 0x00d6, 0x0026, 0x2069,
-	0x0140, 0x2001, 0x1818, 0x2102, 0x8114, 0x8214, 0x8214, 0x8214,
-	0x20a9, 0x0010, 0x6853, 0x0000, 0x9006, 0x82ff, 0x1128, 0x9184,
-	0x000f, 0x9080, 0xf1f1, 0x2005, 0x6856, 0x8211, 0x1f04, 0x28a4,
-	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, 0x28d4, 0x680f,
-	0x0000, 0x000e, 0x001e, 0x002e, 0x00de, 0x015e, 0x0005, 0x080c,
-	0x56e2, 0xd0c4, 0x0150, 0xd0a4, 0x0140, 0x9006, 0x0046, 0x2020,
-	0x2009, 0x002e, 0x080c, 0xe5e9, 0x004e, 0x0005, 0x00f6, 0x0016,
-	0x0026, 0x2079, 0x0140, 0x78c4, 0xd0dc, 0x0904, 0x294b, 0x080c,
-	0x2baa, 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, 0x8f70, 0x928c, 0xff00, 0x0110, 0x2011,
-	0x00ff, 0x2200, 0x8007, 0x9085, 0x004c, 0x78c2, 0x2009, 0x0138,
-	0x220a, 0x080c, 0x73b3, 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, 0x29a9, 0x29c7, 0x29eb, 0x29ed, 0x2a16, 0x2a18,
-	0x2a1a, 0x2001, 0x0001, 0x080c, 0x27f7, 0x080c, 0x2c08, 0x2001,
-	0x1991, 0x2003, 0x0000, 0x7828, 0x9084, 0xe1d7, 0x782a, 0x9006,
-	0x20a9, 0x0009, 0x080c, 0x2bc6, 0x2001, 0x198f, 0x2003, 0x0006,
-	0x2009, 0x001e, 0x2011, 0x2a1b, 0x080c, 0x8591, 0x0005, 0x2009,
-	0x1994, 0x200b, 0x0000, 0x2001, 0x1999, 0x2003, 0x0036, 0x2001,
-	0x1998, 0x2003, 0x002a, 0x2001, 0x1991, 0x2003, 0x0001, 0x9006,
-	0x080c, 0x2b78, 0x2001, 0xffff, 0x20a9, 0x0009, 0x080c, 0x2bc6,
-	0x2001, 0x198f, 0x2003, 0x0006, 0x2009, 0x001e, 0x2011, 0x2a1b,
-	0x080c, 0x8591, 0x0005, 0x080c, 0x0dd5, 0x2001, 0x1999, 0x2003,
-	0x0036, 0x2001, 0x1991, 0x2003, 0x0003, 0x7a38, 0x9294, 0x0005,
+	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,
+	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,
+	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,
+	0x00ce, 0x00de, 0x00fe, 0x001e, 0x00ae, 0x0005, 0x00fe, 0x00d6,
+	0x2069, 0x0140, 0x6804, 0x9084, 0x4000, 0x0110, 0x080c, 0x2d5e,
+	0x00de, 0x00c6, 0x2061, 0x19e6, 0x6028, 0x080c, 0xd388, 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,
+	0x0010, 0x6016, 0x6027, 0x0004, 0x00d6, 0x2069, 0x0140, 0x6804,
+	0x9084, 0x4000, 0x0110, 0x080c, 0x2d5e, 0x00de, 0x00c6, 0x2061,
+	0x19e6, 0x6044, 0x080c, 0xd388, 0x0120, 0x909a, 0x0003, 0x1658,
+	0x0018, 0x909a, 0x00c8, 0x1638, 0x8000, 0x6046, 0x603c, 0x00ce,
+	0x9005, 0x05b8, 0x2009, 0x07d0, 0x080c, 0x863b, 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,
-	0x2b78, 0x2001, 0x1995, 0x2003, 0x0000, 0x2001, 0xffff, 0x20a9,
-	0x0009, 0x080c, 0x2bc6, 0x2001, 0x198f, 0x2003, 0x0006, 0x2009,
-	0x001e, 0x2011, 0x2a1b, 0x080c, 0x8591, 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, 0x2a3d, 0x2a5d,
-	0x2a9d, 0x2acd, 0x2af1, 0x2b01, 0x2b03, 0x080c, 0x2bba, 0x11b0,
-	0x7850, 0x9084, 0xefff, 0x7852, 0x2009, 0x1997, 0x2104, 0x7a38,
-	0x9294, 0x0005, 0x9296, 0x0004, 0x0110, 0xc08d, 0x0008, 0xc085,
-	0x200a, 0x2001, 0x198f, 0x2003, 0x0001, 0x0030, 0x080c, 0x2b27,
-	0x2001, 0xffff, 0x080c, 0x29b8, 0x0005, 0x080c, 0x2b05, 0x05e0,
-	0x2009, 0x1998, 0x2104, 0x8001, 0x200a, 0x080c, 0x2bba, 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,
-	0x2b0d, 0x00c0, 0x200b, 0x0000, 0x7a38, 0x9294, 0x0006, 0x9296,
-	0x0004, 0x0110, 0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x2b95,
-	0x2001, 0x1991, 0x2003, 0x0002, 0x0028, 0x2001, 0x198f, 0x2003,
-	0x0003, 0x0010, 0x080c, 0x29da, 0x0005, 0x080c, 0x2b05, 0x0560,
-	0x2009, 0x1998, 0x2104, 0x8001, 0x200a, 0x080c, 0x2bba, 0x1168,
-	0x7850, 0x9084, 0xefff, 0x7852, 0x2001, 0x198f, 0x2003, 0x0003,
-	0x2001, 0x1990, 0x2003, 0x0000, 0x00b8, 0x2009, 0x1998, 0x2104,
-	0x9005, 0x1118, 0x080c, 0x2b4a, 0x0010, 0x080c, 0x2b1a, 0x080c,
-	0x2b0d, 0x2009, 0x1994, 0x200b, 0x0000, 0x2001, 0x1991, 0x2003,
-	0x0001, 0x080c, 0x29da, 0x0000, 0x0005, 0x04b9, 0x0508, 0x080c,
-	0x2bba, 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, 0x2a05,
-	0x0005, 0x0099, 0x0168, 0x080c, 0x2bba, 0x1138, 0x7850, 0x9084,
-	0xefff, 0x7852, 0x080c, 0x29f1, 0x0018, 0x0079, 0x080c, 0x2a05,
-	0x0005, 0x080c, 0x0dd5, 0x080c, 0x0dd5, 0x2009, 0x1999, 0x2104,
-	0x8001, 0x200a, 0x090c, 0x2b66, 0x0005, 0x7a38, 0x9294, 0x0005,
-	0x9296, 0x0005, 0x0110, 0x9006, 0x0010, 0x2001, 0x0001, 0x080c,
-	0x2b95, 0x0005, 0x7a38, 0x9294, 0x0006, 0x9296, 0x0006, 0x0110,
-	0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x2b78, 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,
-	0x2b95, 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,
-	0x2b6c, 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, 0x2c45,
-	0xd09c, 0x1110, 0x1f04, 0x2bbd, 0x015e, 0x0005, 0x0126, 0x0016,
-	0x0006, 0x2091, 0x8000, 0x7850, 0x9085, 0x0040, 0x7852, 0x7850,
-	0x9084, 0xfbcf, 0x7852, 0x080c, 0x2c45, 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, 0x2bf3, 0x080c, 0x85b3, 0x1f04,
-	0x2bf3, 0x7850, 0x9085, 0x0400, 0x9084, 0xdfbf, 0x7852, 0x080c,
-	0x2c45, 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, 0x2c17, 0x0028, 0x7854, 0xd08c, 0x1110,
-	0x1f04, 0x2c1d, 0x00fe, 0x015e, 0x000e, 0x0005, 0x1d04, 0x2c26,
-	0x080c, 0x85b3, 0x1f04, 0x2c26, 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, 0x2000,
-	0x0118, 0x9186, 0x0100, 0x1588, 0x2009, 0x00a2, 0x080c, 0x0e51,
-	0x2019, 0x0160, 0x2324, 0x2011, 0x0003, 0x2009, 0x0169, 0x2104,
-	0x9084, 0x0007, 0x210c, 0x918c, 0x0007, 0x910e, 0x1db0, 0x9086,
-	0x0003, 0x11b8, 0x2304, 0x9402, 0x02a0, 0x1d60, 0x8211, 0x1d68,
-	0x84ff, 0x0170, 0x2001, 0x0141, 0x200c, 0x918c, 0xff00, 0x9186,
-	0x0100, 0x0130, 0x2009, 0x180c, 0x2104, 0xc0dd, 0x200a, 0x0008,
-	0x0419, 0x2009, 0x0000, 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, 0x73cd,
-	0x0108, 0xc0bc, 0x2009, 0x0140, 0x2114, 0x9294, 0x0001, 0x9215,
+	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, 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, 0x73cd, 0x0110, 0xc0bc,
-	0x0008, 0xc0bd, 0x200a, 0x001e, 0x000e, 0x0005, 0x2fa2, 0x2fa2,
-	0x2dc6, 0x2dc6, 0x2dd2, 0x2dd2, 0x2dde, 0x2dde, 0x2dec, 0x2dec,
-	0x2df8, 0x2df8, 0x2e06, 0x2e06, 0x2e14, 0x2e14, 0x2e26, 0x2e26,
-	0x2e32, 0x2e32, 0x2e40, 0x2e40, 0x2e5e, 0x2e5e, 0x2e7e, 0x2e7e,
-	0x2e4e, 0x2e4e, 0x2e6e, 0x2e6e, 0x2e8c, 0x2e8c, 0x2e24, 0x2e24,
-	0x2e24, 0x2e24, 0x2e24, 0x2e24, 0x2e24, 0x2e24, 0x2e24, 0x2e24,
-	0x2e24, 0x2e24, 0x2e24, 0x2e24, 0x2e24, 0x2e24, 0x2e24, 0x2e24,
-	0x2e24, 0x2e24, 0x2e24, 0x2e24, 0x2e24, 0x2e24, 0x2e24, 0x2e24,
-	0x2e24, 0x2e24, 0x2e24, 0x2e24, 0x2e24, 0x2e24, 0x2e9e, 0x2e9e,
-	0x2eaa, 0x2eaa, 0x2eb8, 0x2eb8, 0x2ec6, 0x2ec6, 0x2ed6, 0x2ed6,
-	0x2ee4, 0x2ee4, 0x2ef4, 0x2ef4, 0x2f04, 0x2f04, 0x2f16, 0x2f16,
-	0x2f24, 0x2f24, 0x2f34, 0x2f34, 0x2f56, 0x2f56, 0x2f78, 0x2f78,
-	0x2f44, 0x2f44, 0x2f67, 0x2f67, 0x2f87, 0x2f87, 0x2e24, 0x2e24,
-	0x2e24, 0x2e24, 0x2e24, 0x2e24, 0x2e24, 0x2e24, 0x2e24, 0x2e24,
-	0x2e24, 0x2e24, 0x2e24, 0x2e24, 0x2e24, 0x2e24, 0x2e24, 0x2e24,
-	0x2e24, 0x2e24, 0x2e24, 0x2e24, 0x2e24, 0x2e24, 0x2e24, 0x2e24,
-	0x2e24, 0x2e24, 0x2e24, 0x2e24, 0x2e24, 0x2e24, 0x2e24, 0x2e24,
-	0x2e24, 0x2e24, 0x2e24, 0x2e24, 0x2e24, 0x2e24, 0x2e24, 0x2e24,
-	0x2e24, 0x2e24, 0x2e24, 0x2e24, 0x2e24, 0x2e24, 0x0106, 0x0006,
-	0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x248e,
-	0x0804, 0x2f9a, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
-	0x0146, 0x0156, 0x080c, 0x22a2, 0x0804, 0x2f9a, 0x0106, 0x0006,
-	0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x22a2,
-	0x080c, 0x248e, 0x0804, 0x2f9a, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x22dd, 0x0804, 0x2f9a,
+	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, 0x248e, 0x080c, 0x22dd, 0x0804, 0x2f9a, 0x0106, 0x0006,
-	0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x22a2,
-	0x080c, 0x22dd, 0x0804, 0x2f9a, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x22a2, 0x080c, 0x248e,
-	0x080c, 0x22dd, 0x0804, 0x2f9a, 0xa001, 0x0cf0, 0x0106, 0x0006,
-	0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x1380,
-	0x0804, 0x2f9a, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
-	0x0146, 0x0156, 0x080c, 0x248e, 0x080c, 0x1380, 0x0804, 0x2f9a,
+	0x080c, 0x297f, 0x080c, 0x22d3, 0x080c, 0x24bf, 0x0804, 0x2fec,
 	0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156,
-	0x080c, 0x22a2, 0x080c, 0x1380, 0x0804, 0x2f9a, 0x0106, 0x0006,
-	0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x248e,
-	0x080c, 0x1380, 0x080c, 0x22dd, 0x0804, 0x2f9a, 0x0106, 0x0006,
-	0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x22a2,
-	0x080c, 0x248e, 0x080c, 0x1380, 0x0804, 0x2f9a, 0x0106, 0x0006,
-	0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x22a2,
-	0x080c, 0x1380, 0x080c, 0x22dd, 0x0804, 0x2f9a, 0x0106, 0x0006,
-	0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x1380,
-	0x080c, 0x22dd, 0x0804, 0x2f9a, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x22a2, 0x080c, 0x248e,
-	0x080c, 0x1380, 0x080c, 0x22dd, 0x0804, 0x2f9a, 0x0106, 0x0006,
-	0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x294e,
-	0x0804, 0x2f9a, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
-	0x0146, 0x0156, 0x080c, 0x294e, 0x080c, 0x248e, 0x0804, 0x2f9a,
+	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, 0x294e, 0x080c, 0x22a2, 0x0804, 0x2f9a, 0x0106, 0x0006,
-	0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x294e,
-	0x080c, 0x22a2, 0x080c, 0x248e, 0x0804, 0x2f9a, 0x0106, 0x0006,
-	0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x294e,
-	0x080c, 0x22dd, 0x0804, 0x2f9a, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x294e, 0x080c, 0x248e,
-	0x080c, 0x22dd, 0x0804, 0x2f9a, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x294e, 0x080c, 0x22a2,
-	0x080c, 0x22dd, 0x0804, 0x2f9a, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x294e, 0x080c, 0x22a2,
-	0x080c, 0x248e, 0x080c, 0x22dd, 0x0804, 0x2f9a, 0x0106, 0x0006,
-	0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x294e,
-	0x080c, 0x1380, 0x0804, 0x2f9a, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x294e, 0x080c, 0x248e,
-	0x080c, 0x1380, 0x0804, 0x2f9a, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x294e, 0x080c, 0x22a2,
-	0x080c, 0x1380, 0x0804, 0x2f9a, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x294e, 0x080c, 0x248e,
-	0x080c, 0x1380, 0x080c, 0x22dd, 0x0804, 0x2f9a, 0x0106, 0x0006,
-	0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x294e,
-	0x080c, 0x22a2, 0x080c, 0x248e, 0x080c, 0x1380, 0x0498, 0x0106,
-	0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
-	0x294e, 0x080c, 0x22a2, 0x080c, 0x1380, 0x080c, 0x22dd, 0x0410,
+	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, 0x294e, 0x080c, 0x1380, 0x080c, 0x22dd, 0x0098, 0x0106,
-	0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
-	0x294e, 0x080c, 0x22a2, 0x080c, 0x248e, 0x080c, 0x1380, 0x080c,
-	0x22dd, 0x0000, 0x015e, 0x014e, 0x013e, 0x01de, 0x01ce, 0x012e,
-	0x000e, 0x010e, 0x000d, 0x00b6, 0x00c6, 0x0026, 0x0046, 0x9026,
-	0x080c, 0x6947, 0x1904, 0x30b3, 0x72dc, 0x2001, 0x197b, 0x2004,
-	0x9005, 0x1110, 0xd29c, 0x0148, 0xd284, 0x1138, 0xd2bc, 0x1904,
-	0x30b3, 0x080c, 0x30b8, 0x0804, 0x30b3, 0xd2cc, 0x1904, 0x30b3,
-	0x080c, 0x73b3, 0x1120, 0x70af, 0xffff, 0x0804, 0x30b3, 0xd294,
-	0x0120, 0x70af, 0xffff, 0x0804, 0x30b3, 0x080c, 0x3321, 0x0160,
-	0x080c, 0xd25a, 0x0128, 0x2001, 0x1818, 0x203c, 0x0804, 0x3040,
-	0x70af, 0xffff, 0x0804, 0x30b3, 0x2001, 0x1818, 0x203c, 0x7294,
-	0xd284, 0x0904, 0x3040, 0xd28c, 0x1904, 0x3040, 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, 0x284b, 0x080c,
-	0x65b5, 0x1538, 0x9006, 0xb8bb, 0x0520, 0xb8ac, 0x9005, 0x0148,
-	0x00c6, 0x2060, 0x080c, 0x8987, 0x00ce, 0x090c, 0x8d2d, 0xb8af,
-	0x0000, 0x080c, 0x6989, 0x1168, 0x7030, 0xd08c, 0x0130, 0xb800,
-	0xd0bc, 0x0138, 0x080c, 0x6836, 0x0120, 0x080c, 0x30d1, 0x0148,
-	0x0028, 0x080c, 0x3211, 0x080c, 0x30fd, 0x0118, 0x8318, 0x0804,
-	0x2fed, 0x73ae, 0x0010, 0x70af, 0xffff, 0x003e, 0x0804, 0x30b3,
-	0x9780, 0x3332, 0x203d, 0x97bc, 0xff00, 0x873f, 0x2041, 0x007e,
-	0x70ac, 0x9096, 0xffff, 0x1118, 0x900e, 0x28a8, 0x0050, 0x9812,
-	0x0220, 0x2008, 0x9802, 0x20a8, 0x0020, 0x70af, 0xffff, 0x0804,
-	0x30b3, 0x2700, 0x0156, 0x0016, 0x9106, 0x0904, 0x30a8, 0xc484,
-	0x080c, 0x6616, 0x0148, 0x080c, 0xd25a, 0x1904, 0x30a8, 0x080c,
-	0x65b5, 0x1904, 0x30b0, 0x0008, 0xc485, 0xb8bb, 0x0520, 0xb8ac,
-	0x9005, 0x0148, 0x00c6, 0x2060, 0x080c, 0x8987, 0x00ce, 0x090c,
-	0x8d2d, 0xb8af, 0x0000, 0x080c, 0x6989, 0x1130, 0x7030, 0xd08c,
-	0x01f8, 0xb800, 0xd0bc, 0x11e0, 0x7294, 0xd28c, 0x0180, 0x080c,
-	0x6989, 0x9082, 0x0006, 0x02e0, 0xd484, 0x1118, 0x080c, 0x65da,
-	0x0028, 0x080c, 0x329d, 0x01a0, 0x080c, 0x32c8, 0x0088, 0x080c,
-	0x3211, 0x080c, 0xd25a, 0x1160, 0x080c, 0x30fd, 0x0188, 0x0040,
-	0x080c, 0xd25a, 0x1118, 0x080c, 0x329d, 0x0110, 0x0451, 0x0140,
-	0x001e, 0x8108, 0x015e, 0x1f04, 0x3059, 0x70af, 0xffff, 0x0018,
-	0x001e, 0x015e, 0x71ae, 0x004e, 0x002e, 0x00ce, 0x00be, 0x0005,
-	0x00c6, 0x0016, 0x70af, 0x0001, 0x2009, 0x007e, 0x080c, 0x65b5,
-	0x1168, 0xb813, 0x00ff, 0xb817, 0xfffe, 0x080c, 0x3211, 0x04a9,
-	0x0128, 0x70dc, 0xc0bd, 0x70de, 0x080c, 0xcfab, 0x001e, 0x00ce,
-	0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6, 0x2001, 0x184c, 0x2004,
-	0x9084, 0x00ff, 0xb842, 0x080c, 0xaead, 0x01d0, 0x2b00, 0x6012,
-	0x080c, 0xcfd4, 0x6023, 0x0001, 0x9006, 0x080c, 0x6552, 0x2001,
-	0x0000, 0x080c, 0x6566, 0x0126, 0x2091, 0x8000, 0x70a8, 0x8000,
-	0x70aa, 0x012e, 0x2009, 0x0004, 0x080c, 0xaeda, 0x9085, 0x0001,
-	0x00ce, 0x00de, 0x007e, 0x001e, 0x0005, 0x0016, 0x0076, 0x00d6,
-	0x00c6, 0x2001, 0x184c, 0x2004, 0x9084, 0x00ff, 0xb842, 0x080c,
-	0xaead, 0x0548, 0x2b00, 0x6012, 0xb800, 0xc0c4, 0xb802, 0xb8a0,
-	0x9086, 0x007e, 0x0140, 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006,
-	0x1110, 0x080c, 0x31cc, 0x080c, 0xcfd4, 0x6023, 0x0001, 0x9006,
-	0x080c, 0x6552, 0x2001, 0x0002, 0x080c, 0x6566, 0x0126, 0x2091,
-	0x8000, 0x70a8, 0x8000, 0x70aa, 0x012e, 0x2009, 0x0002, 0x080c,
-	0xaeda, 0x9085, 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e, 0x0005,
-	0x00b6, 0x00c6, 0x0026, 0x2009, 0x0080, 0x080c, 0x65b5, 0x1140,
-	0xb813, 0x00ff, 0xb817, 0xfffc, 0x0039, 0x0110, 0x70e3, 0xffff,
-	0x002e, 0x00ce, 0x00be, 0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6,
-	0x080c, 0xae09, 0x01d0, 0x2b00, 0x6012, 0x080c, 0xcfd4, 0x6023,
-	0x0001, 0x9006, 0x080c, 0x6552, 0x2001, 0x0002, 0x080c, 0x6566,
-	0x0126, 0x2091, 0x8000, 0x70e4, 0x8000, 0x70e6, 0x012e, 0x2009,
-	0x0002, 0x080c, 0xaeda, 0x9085, 0x0001, 0x00ce, 0x00de, 0x007e,
-	0x001e, 0x0005, 0x00c6, 0x00d6, 0x0126, 0x2091, 0x8000, 0x2009,
-	0x007f, 0x080c, 0x65b5, 0x11b8, 0xb813, 0x00ff, 0xb817, 0xfffd,
-	0xb8cf, 0x0004, 0x080c, 0xae09, 0x0170, 0x2b00, 0x6012, 0x6316,
-	0x6023, 0x0001, 0x620a, 0x080c, 0xcfd4, 0x2009, 0x0022, 0x080c,
-	0xaeda, 0x9085, 0x0001, 0x012e, 0x00de, 0x00ce, 0x0005, 0x00e6,
-	0x00c6, 0x0066, 0x0036, 0x0026, 0x00b6, 0x21f0, 0x080c, 0x92a8,
-	0x080c, 0x9228, 0x080c, 0xac9d, 0x080c, 0xbd87, 0x3e08, 0x2130,
-	0x81ff, 0x0120, 0x20a9, 0x007e, 0x900e, 0x0018, 0x20a9, 0x007f,
-	0x900e, 0x0016, 0x080c, 0x6616, 0x1140, 0x9686, 0x0002, 0x1118,
-	0xb800, 0xd0bc, 0x1110, 0x080c, 0x6047, 0x001e, 0x8108, 0x1f04,
-	0x31b1, 0x9686, 0x0001, 0x190c, 0x32f5, 0x00be, 0x002e, 0x003e,
-	0x006e, 0x00ce, 0x00ee, 0x0005, 0x00e6, 0x00c6, 0x0046, 0x0036,
-	0x0026, 0x0016, 0x00b6, 0x6210, 0x2258, 0xbaa0, 0x0026, 0x2019,
-	0x0029, 0x080c, 0x929d, 0x0076, 0x2039, 0x0000, 0x080c, 0x9170,
-	0x2c08, 0x080c, 0xe326, 0x007e, 0x001e, 0xba10, 0xbb14, 0xbcc0,
-	0x080c, 0x6047, 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, 0x56e2, 0xd0c4, 0x0140,
-	0xd0a4, 0x0130, 0x9006, 0x2020, 0x2009, 0x002d, 0x080c, 0xe5e9,
-	0x20a9, 0x0800, 0x9016, 0x0026, 0x928e, 0x007e, 0x0904, 0x327c,
-	0x928e, 0x007f, 0x0904, 0x327c, 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, 0x6953, 0x00ce, 0x00be,
-	0x2019, 0x0029, 0x080c, 0x929d, 0x0076, 0x2039, 0x0000, 0x080c,
-	0x9170, 0x00b6, 0x00c6, 0x0026, 0x2158, 0xba04, 0x9294, 0x00ff,
-	0x9286, 0x0006, 0x1118, 0xb807, 0x0404, 0x0028, 0x2001, 0x0004,
-	0x8007, 0x9215, 0xba06, 0x002e, 0x00ce, 0x00be, 0x0016, 0x2c08,
-	0x080c, 0xe326, 0x001e, 0x007e, 0x002e, 0x8210, 0x1f04, 0x3233,
-	0x015e, 0x001e, 0x002e, 0x003e, 0x004e, 0x00be, 0x00ce, 0x00ee,
-	0x00fe, 0x0005, 0x0046, 0x0026, 0x0016, 0x080c, 0x56e2, 0xd0c4,
-	0x0140, 0xd0a4, 0x0130, 0x9006, 0x2220, 0x2009, 0x0029, 0x080c,
-	0xe5e9, 0x001e, 0x002e, 0x004e, 0x0005, 0x0016, 0x0026, 0x0036,
-	0x00c6, 0x7294, 0x82ff, 0x01e8, 0x080c, 0x6981, 0x11d0, 0x2100,
-	0x080c, 0x287e, 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, 0x1aaf, 0x001e, 0x6112, 0x080c, 0x31cc, 0x001e,
-	0x080c, 0x65da, 0x012e, 0x00ce, 0x001e, 0x0005, 0x0016, 0x0026,
-	0x2110, 0x080c, 0xa7f8, 0x080c, 0xe952, 0x002e, 0x001e, 0x0005,
-	0x2001, 0x1837, 0x2004, 0xd0cc, 0x0005, 0x00c6, 0x00b6, 0x080c,
-	0x73b3, 0x1118, 0x20a9, 0x0800, 0x0010, 0x20a9, 0x0782, 0x080c,
-	0x73b3, 0x1110, 0x900e, 0x0010, 0x2009, 0x007e, 0x9180, 0x1000,
-	0x2004, 0x905d, 0x0130, 0x86ff, 0x0110, 0xb800, 0xd0bc, 0x090c,
-	0x65da, 0x8108, 0x1f04, 0x3306, 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,
+	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,
 	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, 0x3461, 0x3462, 0x3475,
-	0x3489, 0x0005, 0x1004, 0x3472, 0x0e04, 0x3472, 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, 0x355d, 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, 0x355a, 0x61d0, 0x0804, 0x34ef, 0x3531,
-	0x3569, 0x355a, 0x3573, 0x357d, 0x3583, 0x3587, 0x3597, 0x359b,
-	0x35b1, 0x35b7, 0x35bd, 0x35c8, 0x35d3, 0x35e2, 0x35f1, 0x35ff,
-	0x3616, 0x3631, 0x355a, 0x36da, 0x3718, 0x37be, 0x37cf, 0x37f2,
-	0x355a, 0x355a, 0x355a, 0x382a, 0x3846, 0x384f, 0x387e, 0x3884,
-	0x355a, 0x38ca, 0x355a, 0x355a, 0x355a, 0x355a, 0x355a, 0x38d5,
-	0x38de, 0x38e6, 0x38e8, 0x355a, 0x355a, 0x355a, 0x355a, 0x355a,
-	0x355a, 0x3914, 0x355a, 0x355a, 0x355a, 0x355a, 0x355a, 0x3931,
-	0x3992, 0x355a, 0x355a, 0x355a, 0x355a, 0x355a, 0x355a, 0x0002,
-	0x39bc, 0x39bf, 0x3a1e, 0x3a37, 0x3a67, 0x3d05, 0x355a, 0x52bb,
-	0x355a, 0x355a, 0x355a, 0x355a, 0x355a, 0x355a, 0x355a, 0x355a,
-	0x35b1, 0x35b7, 0x4226, 0x5706, 0x4244, 0x534a, 0x539b, 0x549e,
-	0x355a, 0x5500, 0x553c, 0x556d, 0x5671, 0x559a, 0x55f1, 0x355a,
-	0x4248, 0x4409, 0x441f, 0x4444, 0x44a9, 0x451d, 0x453d, 0x45b4,
-	0x4610, 0x466c, 0x466f, 0x4694, 0x4730, 0x4796, 0x479e, 0x48d0,
-	0x4a48, 0x4a7c, 0x4ce0, 0x355a, 0x4cfe, 0x4da3, 0x4e85, 0x4edf,
-	0x355a, 0x4f94, 0x355a, 0x4ffa, 0x5015, 0x479e, 0x525b, 0x714c,
-	0x0000, 0x2021, 0x4000, 0x080c, 0x4afa, 0x0126, 0x2091, 0x8000,
-	0x0e04, 0x353b, 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, 0x4b07, 0x2039, 0x0001, 0x902e, 0x2520, 0x7b88,
-	0x7a8c, 0x7884, 0x7990, 0x0804, 0x4b0a, 0x7984, 0x7888, 0x2114,
-	0x200a, 0x0804, 0x3531, 0x7984, 0x2114, 0x0804, 0x3531, 0x20e1,
-	0x0000, 0x2099, 0x0021, 0x20e9, 0x0000, 0x20a1, 0x0021, 0x20a9,
-	0x001f, 0x4003, 0x7984, 0x7a88, 0x7b8c, 0x0804, 0x3531, 0x7884,
-	0x2060, 0x0804, 0x35e4, 0x2009, 0x0003, 0x2011, 0x0003, 0x2019,
-	0x0002, 0x789b, 0x0137, 0x7893, 0xffff, 0x2001, 0x188f, 0x2004,
-	0x9005, 0x0118, 0x7896, 0x0804, 0x3531, 0x7897, 0x0001, 0x0804,
-	0x3531, 0x2039, 0x0001, 0x7d98, 0x7c9c, 0x0804, 0x356d, 0x2039,
-	0x0001, 0x7d98, 0x7c9c, 0x0804, 0x3577, 0x79a0, 0x9182, 0x0040,
-	0x0210, 0x0804, 0x3566, 0x2138, 0x7d98, 0x7c9c, 0x0804, 0x356d,
-	0x79a0, 0x9182, 0x0040, 0x0210, 0x0804, 0x3566, 0x2138, 0x7d98,
-	0x7c9c, 0x0804, 0x3577, 0x79a0, 0x9182, 0x0040, 0x0210, 0x0804,
-	0x3566, 0x21e8, 0x7984, 0x7888, 0x20a9, 0x0001, 0x21a0, 0x4004,
-	0x0804, 0x3531, 0x2061, 0x0800, 0xe10c, 0x9006, 0x2c15, 0x9200,
-	0x8c60, 0x8109, 0x1dd8, 0x2010, 0x9005, 0x0904, 0x3531, 0x0804,
-	0x3560, 0x79a0, 0x9182, 0x0040, 0x0210, 0x0804, 0x3566, 0x21e0,
-	0x20a9, 0x0001, 0x7984, 0x2198, 0x4012, 0x0804, 0x3531, 0x2069,
-	0x1847, 0x7884, 0x7990, 0x911a, 0x1a04, 0x3566, 0x8019, 0x0904,
-	0x3566, 0x684a, 0x6942, 0x788c, 0x6852, 0x7888, 0x6856, 0x9006,
-	0x685a, 0x685e, 0x080c, 0x76ca, 0x0804, 0x3531, 0x2069, 0x1847,
-	0x7884, 0x7994, 0x911a, 0x1a04, 0x3566, 0x8019, 0x0904, 0x3566,
-	0x684e, 0x6946, 0x788c, 0x6862, 0x7888, 0x6866, 0x9006, 0x686a,
-	0x686e, 0x0126, 0x2091, 0x8000, 0x080c, 0x69ef, 0x012e, 0x0804,
-	0x3531, 0x902e, 0x2520, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804,
-	0x3563, 0x7984, 0x7b88, 0x7a8c, 0x20a9, 0x0005, 0x20e9, 0x0001,
-	0x20a1, 0x18a6, 0x4101, 0x080c, 0x4abe, 0x1120, 0x2009, 0x0002,
-	0x0804, 0x3563, 0x2009, 0x0020, 0xa85c, 0x9080, 0x0019, 0xaf60,
-	0x080c, 0x4b07, 0x701f, 0x3655, 0x0005, 0xa864, 0x2008, 0x9084,
-	0x00ff, 0x9096, 0x0011, 0x0168, 0x9096, 0x0019, 0x0150, 0x9096,
-	0x0015, 0x0138, 0x9096, 0x0048, 0x0120, 0x9096, 0x0029, 0x1904,
-	0x3563, 0x810f, 0x918c, 0x00ff, 0x0904, 0x3563, 0x7112, 0x7010,
-	0x8001, 0x0560, 0x7012, 0x080c, 0x4abe, 0x1120, 0x2009, 0x0002,
-	0x0804, 0x3563, 0x2009, 0x0020, 0x7068, 0x2040, 0xa28c, 0xa390,
-	0xa494, 0xa598, 0x9290, 0x0040, 0x9399, 0x0000, 0x94a1, 0x0000,
-	0x95a9, 0x0000, 0xa85c, 0x9080, 0x0019, 0xaf60, 0x080c, 0x4b07,
-	0x701f, 0x3693, 0x0005, 0xa864, 0x9084, 0x00ff, 0x9096, 0x0002,
-	0x0120, 0x9096, 0x000a, 0x1904, 0x3563, 0x0888, 0x7014, 0x2048,
-	0xa868, 0xc0fd, 0xa86a, 0xa864, 0x9084, 0x00ff, 0x9096, 0x0029,
-	0x1160, 0xc2fd, 0xaa7a, 0x080c, 0x619e, 0x0150, 0x0126, 0x2091,
-	0x8000, 0xa87a, 0xa982, 0x012e, 0x0050, 0x080c, 0x64cb, 0x1128,
-	0x7007, 0x0003, 0x701f, 0x36bf, 0x0005, 0x080c, 0x6ec7, 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, 0x4b0a, 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, 0x3563, 0x7984, 0x080c, 0x6616, 0x1904, 0x3566,
-	0x7e98, 0x9684, 0x3fff, 0x9082, 0x4000, 0x1a04, 0x3566, 0x7c88,
-	0x7d8c, 0x080c, 0x6779, 0x080c, 0x6748, 0x0000, 0x1518, 0x2061,
+	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,
-	0x0150, 0x012e, 0x9ce0, 0x0018, 0x2001, 0x181a, 0x2004, 0x9c02,
-	0x1a04, 0x3563, 0x0c30, 0x080c, 0xc77b, 0x012e, 0x0904, 0x3563,
-	0x0804, 0x3531, 0x900e, 0x2001, 0x0005, 0x080c, 0x6ec7, 0x0126,
-	0x2091, 0x8000, 0x080c, 0xce54, 0x080c, 0x6c94, 0x012e, 0x0804,
-	0x3531, 0x00a6, 0x2950, 0xb198, 0x080c, 0x6616, 0x1904, 0x37ab,
-	0xb6a4, 0x9684, 0x3fff, 0x9082, 0x4000, 0x16e8, 0xb49c, 0xb5a0,
-	0x080c, 0x6779, 0x080c, 0x6748, 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, 0xc77b, 0x012e, 0x2009, 0x0003, 0x0178,
-	0x00e0, 0x900e, 0x2001, 0x0005, 0x080c, 0x6ec7, 0x0126, 0x2091,
-	0x8000, 0x080c, 0xce54, 0x080c, 0x6c88, 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,
-	0x3563, 0x080c, 0x4ad5, 0x0904, 0x3566, 0x080c, 0x66dd, 0x0904,
-	0x3563, 0x080c, 0x677f, 0x0904, 0x3563, 0x0804, 0x4534, 0x81ff,
-	0x1904, 0x3563, 0x080c, 0x4af1, 0x0904, 0x3566, 0x080c, 0x680d,
-	0x0904, 0x3563, 0x2019, 0x0005, 0x79a8, 0x080c, 0x679a, 0x0904,
-	0x3563, 0x7888, 0x908a, 0x1000, 0x1a04, 0x3566, 0x8003, 0x800b,
-	0x810b, 0x9108, 0x080c, 0x8507, 0x7984, 0xd184, 0x1904, 0x3531,
-	0x0804, 0x4534, 0x0126, 0x2091, 0x8000, 0x81ff, 0x0118, 0x2009,
-	0x0001, 0x0450, 0x2029, 0x07ff, 0x645c, 0x2400, 0x9506, 0x01f8,
-	0x2508, 0x080c, 0x6616, 0x11d8, 0x080c, 0x680d, 0x1128, 0x2009,
-	0x0002, 0x62c0, 0x2518, 0x00c0, 0x2019, 0x0004, 0x900e, 0x080c,
-	0x679a, 0x1118, 0x2009, 0x0006, 0x0078, 0x7884, 0x908a, 0x1000,
-	0x1270, 0x8003, 0x800b, 0x810b, 0x9108, 0x080c, 0x8507, 0x8529,
-	0x1ae0, 0x012e, 0x0804, 0x3531, 0x012e, 0x0804, 0x3563, 0x012e,
-	0x0804, 0x3566, 0x080c, 0x4ad5, 0x0904, 0x3566, 0x080c, 0x66dd,
-	0x0904, 0x3563, 0xbaa0, 0x2019, 0x0005, 0x00c6, 0x9066, 0x080c,
-	0x929d, 0x0076, 0x903e, 0x080c, 0x9170, 0x900e, 0x080c, 0xe326,
-	0x007e, 0x00ce, 0x080c, 0x6779, 0x0804, 0x3531, 0x080c, 0x4ad5,
-	0x0904, 0x3566, 0x080c, 0x6779, 0x2208, 0x0804, 0x3531, 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,
-	0x3860, 0x2300, 0x9218, 0x00ee, 0x00de, 0x015e, 0x0804, 0x3531,
-	0x00f6, 0x0016, 0x907d, 0x0138, 0x9006, 0x8000, 0x2f0c, 0x81ff,
-	0x0110, 0x2178, 0x0cd0, 0x001e, 0x00fe, 0x0005, 0x2069, 0x1910,
-	0x6910, 0x62bc, 0x0804, 0x3531, 0x81ff, 0x0120, 0x2009, 0x0001,
-	0x0804, 0x3563, 0x0126, 0x2091, 0x8000, 0x080c, 0x56f6, 0x0128,
-	0x2009, 0x0007, 0x012e, 0x0804, 0x3563, 0x012e, 0x615c, 0x9190,
-	0x3332, 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, 0x73b3, 0x1118, 0x2031, 0x0004, 0x0038, 0xd79c,
-	0x0120, 0x2009, 0x0005, 0x0804, 0x3563, 0x9036, 0x7e9a, 0x7f9e,
-	0x0804, 0x3531, 0x614c, 0x6250, 0x2019, 0x1985, 0x231c, 0x2001,
-	0x1986, 0x2004, 0x789a, 0x0804, 0x3531, 0x0126, 0x2091, 0x8000,
-	0x6138, 0x623c, 0x6340, 0x012e, 0x0804, 0x3531, 0x080c, 0x4af1,
-	0x0904, 0x3566, 0xba44, 0xbb38, 0x0804, 0x3531, 0x080c, 0x0dd5,
-	0x080c, 0x4af1, 0x2110, 0x0904, 0x3566, 0xb804, 0x908c, 0x00ff,
-	0x918e, 0x0006, 0x0140, 0x9084, 0xff00, 0x9086, 0x0600, 0x2009,
-	0x0009, 0x1904, 0x3563, 0x0126, 0x2091, 0x8000, 0x2019, 0x0005,
-	0x00c6, 0x9066, 0x080c, 0xa7f8, 0x080c, 0x929d, 0x0076, 0x903e,
-	0x080c, 0x9170, 0x900e, 0x080c, 0xe326, 0x007e, 0x00ce, 0xb807,
-	0x0407, 0x012e, 0x0804, 0x3531, 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,
-	0x3531, 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, 0x4226, 0x6040, 0xd0cc, 0x0120,
-	0x78b0, 0x2011, 0x0114, 0x2012, 0x012e, 0x0804, 0x3531, 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,
-	0x3566, 0x788c, 0x902d, 0x0904, 0x3566, 0x900e, 0x080c, 0x6616,
-	0x1120, 0xba44, 0xbb38, 0xbc46, 0xbd3a, 0x9186, 0x07ff, 0x0190,
-	0x8108, 0x0ca0, 0x080c, 0x4af1, 0x0904, 0x3566, 0x7888, 0x900d,
-	0x0904, 0x3566, 0x788c, 0x9005, 0x0904, 0x3566, 0xba44, 0xb946,
-	0xbb38, 0xb83a, 0x0804, 0x3531, 0x2011, 0xbc09, 0x0010, 0x2011,
-	0xbc05, 0x080c, 0x56f6, 0x1904, 0x3563, 0x00c6, 0x2061, 0x0100,
-	0x7984, 0x9186, 0x00ff, 0x1130, 0x2001, 0x1818, 0x2004, 0x9085,
-	0xff00, 0x0088, 0x9182, 0x007f, 0x16e0, 0x9188, 0x3332, 0x210d,
-	0x918c, 0x00ff, 0x2001, 0x1818, 0x2004, 0x0026, 0x9116, 0x002e,
-	0x0580, 0x810f, 0x9105, 0x0126, 0x2091, 0x8000, 0x0006, 0x080c,
-	0xae09, 0x000e, 0x0510, 0x602e, 0x620a, 0x7984, 0x00b6, 0x080c,
-	0x65bb, 0x2b08, 0x00be, 0x1500, 0x6112, 0x6023, 0x0001, 0x080c,
-	0x4abe, 0x01d0, 0x9006, 0xa866, 0x7007, 0x0003, 0xa832, 0xa868,
-	0xc0fd, 0xa86a, 0x701f, 0x3a17, 0x2900, 0x6016, 0x2009, 0x0032,
-	0x080c, 0xaeda, 0x012e, 0x00ce, 0x0005, 0x012e, 0x00ce, 0x0804,
-	0x3563, 0x00ce, 0x0804, 0x3566, 0x080c, 0xae5f, 0x0cb0, 0xa830,
-	0x9086, 0x0100, 0x0904, 0x3563, 0x0804, 0x3531, 0x2061, 0x1a70,
-	0x0126, 0x2091, 0x8000, 0x6000, 0xd084, 0x0170, 0x6104, 0x6208,
-	0x2061, 0x1800, 0x6354, 0x6074, 0x789a, 0x60c0, 0x789e, 0x60bc,
-	0x78aa, 0x012e, 0x0804, 0x3531, 0x900e, 0x2110, 0x0c88, 0x81ff,
-	0x1904, 0x3563, 0x080c, 0x73b3, 0x0904, 0x3563, 0x0126, 0x2091,
-	0x8000, 0x6254, 0x6074, 0x9202, 0x0248, 0x9085, 0x0001, 0x080c,
-	0x28b4, 0x080c, 0x5910, 0x012e, 0x0804, 0x3531, 0x012e, 0x0804,
-	0x3566, 0x0006, 0x0016, 0x00c6, 0x00e6, 0x2001, 0x19a8, 0x2070,
-	0x2061, 0x1847, 0x6008, 0x2072, 0x900e, 0x2011, 0x1400, 0x080c,
-	0x8f70, 0x7206, 0x00ee, 0x00ce, 0x001e, 0x000e, 0x0005, 0x0126,
-	0x2091, 0x8000, 0x81ff, 0x0128, 0x012e, 0x2021, 0x400b, 0x0804,
-	0x3533, 0x7884, 0xd0fc, 0x0148, 0x2001, 0x002a, 0x2004, 0x9082,
-	0x00e1, 0x0288, 0x012e, 0x0804, 0x3566, 0x2001, 0x002a, 0x2004,
-	0x2069, 0x1847, 0x6908, 0x9102, 0x1230, 0x012e, 0x0804, 0x3566,
-	0x012e, 0x0804, 0x3563, 0x080c, 0xadc9, 0x0dd0, 0x7884, 0xd0fc,
-	0x0904, 0x3ae2, 0x00c6, 0x080c, 0x4abe, 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, 0x3c68, 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, 0x4b07, 0x701f, 0x3ba5, 0x7023, 0x0001,
-	0x012e, 0x0005, 0x0046, 0x0086, 0x0096, 0x00a6, 0x00b6, 0x00c6,
-	0x00d6, 0x00e6, 0x00f6, 0x080c, 0x3a51, 0x2001, 0x199e, 0x2003,
-	0x0000, 0x2021, 0x000a, 0x2061, 0x0100, 0x6104, 0x0016, 0x60bb,
-	0x0000, 0x60bf, 0x32e1, 0x60bf, 0x0012, 0x080c, 0x3cd7, 0x080c,
-	0x3c96, 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, 0x406a, 0x008e, 0x00ee, 0x00fe, 0x080c,
-	0x3f97, 0x080c, 0x3e9c, 0x05b8, 0x2001, 0x020b, 0x2004, 0x9084,
-	0x0140, 0x1db8, 0x080c, 0x40de, 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, 0x3ea6, 0x080c, 0x3c91, 0x0058,
-	0x080c, 0x3c91, 0x080c, 0x4002, 0x080c, 0x3f8d, 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, 0x23df, 0x2001, 0x0227, 0x200c, 0x2102, 0x00fe,
-	0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae, 0x009e, 0x008e, 0x004e,
-	0x2001, 0x199e, 0x2004, 0x9005, 0x1118, 0x012e, 0x0804, 0x3531,
-	0x012e, 0x2021, 0x400c, 0x0804, 0x3533, 0x0016, 0x0026, 0x0036,
-	0x0046, 0x0056, 0x0076, 0x0086, 0x0096, 0x00d6, 0x0156, 0x7014,
-	0x2048, 0x7020, 0x20a8, 0x8000, 0x7022, 0xa804, 0x9005, 0x0904,
-	0x3c01, 0x2048, 0x1f04, 0x3bb5, 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, 0x4b07, 0x701f, 0x3ba5, 0x00b0,
-	0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080,
-	0x001b, 0x21a8, 0x27e0, 0x2098, 0x27e8, 0x20a0, 0x0006, 0x080c,
-	0x0f7c, 0x000e, 0x080c, 0x4b0a, 0x701f, 0x3ba5, 0x015e, 0x00de,
+	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,
-	0x0005, 0x7014, 0x2048, 0xa864, 0x9086, 0x0103, 0x1118, 0x701f,
-	0x3c66, 0x0450, 0x7014, 0x2048, 0xa868, 0xc0fd, 0xa86a, 0x2009,
-	0x007f, 0x080c, 0x65b5, 0x0110, 0x9006, 0x0030, 0xb813, 0x00ff,
-	0xb817, 0xfffd, 0x080c, 0xd023, 0x015e, 0x00de, 0x009e, 0x008e,
-	0x007e, 0x005e, 0x004e, 0x003e, 0x002e, 0x001e, 0x0904, 0x3563,
-	0x0016, 0x0026, 0x0036, 0x0046, 0x0056, 0x0076, 0x0086, 0x0096,
-	0x00d6, 0x0156, 0x701f, 0x3c38, 0x7007, 0x0003, 0x0804, 0x3bf6,
-	0xa830, 0x9086, 0x0100, 0x2021, 0x400c, 0x0904, 0x3533, 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, 0x4b0a,
-	0x007e, 0x701f, 0x3ba5, 0x7023, 0x0001, 0x0005, 0x0804, 0x3531,
-	0x0156, 0x00c6, 0xa814, 0x908a, 0x001e, 0x0218, 0xa833, 0x001e,
-	0x0010, 0xa832, 0x0078, 0x81ff, 0x0168, 0x0016, 0x080c, 0x4abe,
-	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, 0x4abe, 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, 0x23df, 0x2001, 0x002a, 0x2004, 0x9084,
-	0xfff8, 0xa86e, 0x601a, 0xa873, 0x0000, 0x601f, 0x0000, 0x78ca,
-	0x9006, 0x600a, 0x600e, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x00e6,
-	0x080c, 0x4abe, 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, 0x2c3d, 0x1130, 0x9006, 0x080c, 0x2b95,
-	0x9006, 0x080c, 0x2b78, 0x7884, 0x9084, 0x0007, 0x0002, 0x3d22,
-	0x3d2b, 0x3d34, 0x3d1f, 0x3d1f, 0x3d1f, 0x3d1f, 0x3d1f, 0x012e,
-	0x0804, 0x3566, 0x2009, 0x0114, 0x2104, 0x9085, 0x0800, 0x200a,
-	0x080c, 0x3ef0, 0x00c0, 0x2009, 0x0114, 0x2104, 0x9085, 0x4000,
-	0x200a, 0x080c, 0x3ef0, 0x0078, 0x080c, 0x73b3, 0x1128, 0x012e,
-	0x2009, 0x0016, 0x0804, 0x3563, 0x81ff, 0x0128, 0x012e, 0x2021,
-	0x400b, 0x0804, 0x3533, 0x0086, 0x0096, 0x00a6, 0x00b6, 0x00c6,
-	0x00d6, 0x00e6, 0x00f6, 0x080c, 0x3a51, 0x2009, 0x0101, 0x210c,
-	0x0016, 0x7ec8, 0x7dcc, 0x9006, 0x2068, 0x2060, 0x2058, 0x080c,
-	0x41b9, 0x080c, 0x4109, 0x903e, 0x2720, 0x00f6, 0x00e6, 0x0086,
-	0x2940, 0x2071, 0x1a65, 0x2079, 0x0090, 0x00d6, 0x2069, 0x0000,
-	0x6884, 0xd0b4, 0x0120, 0x68d4, 0x780e, 0x68d0, 0x780a, 0x00de,
-	0x2011, 0x0001, 0x080c, 0x406a, 0x080c, 0x2c45, 0x080c, 0x2c45,
-	0x080c, 0x2c45, 0x080c, 0x2c45, 0x080c, 0x406a, 0x008e, 0x00ee,
-	0x00fe, 0x080c, 0x3f97, 0x2009, 0x9c40, 0x8109, 0x11b0, 0x080c,
-	0x3ea6, 0x2001, 0x0004, 0x200c, 0x918c, 0xfffd, 0x2102, 0x001e,
-	0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae, 0x009e, 0x008e,
-	0x2009, 0x0017, 0x080c, 0x3563, 0x0cf8, 0x2001, 0x020b, 0x2004,
-	0x9084, 0x0140, 0x1d10, 0x00f6, 0x2079, 0x0000, 0x7884, 0x00fe,
-	0xd0bc, 0x0178, 0x2001, 0x0201, 0x200c, 0x81ff, 0x0150, 0x080c,
-	0x3f75, 0x2d00, 0x9c05, 0x9b05, 0x0120, 0x080c, 0x3ea6, 0x0804,
-	0x3e53, 0x080c, 0x40de, 0x080c, 0x4002, 0x080c, 0x3f58, 0x080c,
-	0x3f8d, 0x00f6, 0x2079, 0x0100, 0x7824, 0xd0ac, 0x0130, 0x8b58,
-	0x080c, 0x3ea6, 0x00fe, 0x0804, 0x3e53, 0x00fe, 0x080c, 0x3e9c,
-	0x1150, 0x8d68, 0x2001, 0x0032, 0x2602, 0x2001, 0x0033, 0x2502,
-	0x080c, 0x3ea6, 0x0080, 0x87ff, 0x0138, 0x2001, 0x0201, 0x2004,
-	0x9005, 0x1908, 0x8739, 0x0038, 0x2001, 0x1a61, 0x2004, 0x9086,
-	0x0000, 0x1904, 0x3da3, 0x2001, 0x032f, 0x2003, 0x00f6, 0x8631,
-	0x1208, 0x8529, 0x2500, 0x9605, 0x0904, 0x3e53, 0x7884, 0xd0bc,
-	0x0128, 0x2d00, 0x9c05, 0x9b05, 0x1904, 0x3e53, 0xa013, 0x0019,
-	0x2001, 0x032a, 0x2003, 0x0004, 0x7884, 0xd0ac, 0x1148, 0x2001,
-	0x1a61, 0x2003, 0x0003, 0x2001, 0x032a, 0x2003, 0x0009, 0x0030,
-	0xa017, 0x0001, 0x78b4, 0x9005, 0x0108, 0xa016, 0x2800, 0xa05a,
-	0x2009, 0x0040, 0x080c, 0x23df, 0x2900, 0xa85a, 0xa813, 0x0019,
-	0x7884, 0xd0a4, 0x1180, 0xa817, 0x0000, 0x00c6, 0x20a9, 0x0004,
-	0x2061, 0x0090, 0x602b, 0x0008, 0x2001, 0x0203, 0x2004, 0x1f04,
-	0x3e2a, 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, 0x3d5d, 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, 0x23df, 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, 0x3531, 0x012e,
-	0x2021, 0x400c, 0x0804, 0x3533, 0x9085, 0x0001, 0x1d04, 0x3ea5,
-	0x2091, 0x6000, 0x8420, 0x9486, 0x0064, 0x0005, 0x2001, 0x0105,
-	0x2003, 0x0010, 0x2001, 0x032a, 0x2003, 0x0004, 0x2001, 0x1a61,
-	0x2003, 0x0000, 0x0071, 0x2009, 0x0048, 0x080c, 0x23df, 0x2001,
-	0x0227, 0x2024, 0x2402, 0x2001, 0x0109, 0x2003, 0x4000, 0x9026,
-	0x0005, 0x00f6, 0x00e6, 0x2071, 0x1a65, 0x7000, 0x9086, 0x0000,
-	0x0520, 0x2079, 0x0090, 0x2009, 0x0206, 0x2104, 0x2009, 0x0203,
-	0x210c, 0x9106, 0x1120, 0x2009, 0x0040, 0x080c, 0x23df, 0x782c,
-	0xd0fc, 0x0d88, 0x080c, 0x40de, 0x7000, 0x9086, 0x0000, 0x1d58,
-	0x782b, 0x0004, 0x782c, 0xd0ac, 0x1de8, 0x2009, 0x0040, 0x080c,
-	0x23df, 0x782b, 0x0002, 0x7003, 0x0000, 0x00ee, 0x00fe, 0x0005,
-	0x00f6, 0x2079, 0x0100, 0x2001, 0x1818, 0x200c, 0x7932, 0x7936,
-	0x080c, 0x2894, 0x7850, 0x9084, 0xfbff, 0x9085, 0x0030, 0x7852,
-	0x2019, 0x01f4, 0x8319, 0x1df0, 0x9084, 0xffcf, 0x9085, 0x2000,
-	0x7852, 0x20a9, 0x0046, 0x1d04, 0x3f0b, 0x2091, 0x6000, 0x1f04,
-	0x3f0b, 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, 0x3f2b, 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, 0x2cfc, 0x7827, 0x0020, 0x7843,
-	0x0000, 0x9006, 0x080c, 0x2cfc, 0x7827, 0x0048, 0x00fe, 0x0005,
-	0x7884, 0xd0ac, 0x11c8, 0x00f6, 0x00e6, 0x2071, 0x1a61, 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, 0x3c87,
-	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, 0x40de, 0x00f6, 0x2071,
-	0x1a61, 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, 0x406a, 0x2011, 0x0001, 0x080c, 0x406a, 0x00fe,
-	0x00ee, 0x0005, 0x00f6, 0x00e6, 0x2071, 0x1a61, 0x2079, 0x0320,
-	0x792c, 0xd1fc, 0x0904, 0x4067, 0x782b, 0x0002, 0x9026, 0xd19c,
-	0x1904, 0x4063, 0x7000, 0x0002, 0x4067, 0x4018, 0x4048, 0x4063,
-	0xd1bc, 0x1170, 0xd1dc, 0x1190, 0x8001, 0x7002, 0x2011, 0x0001,
-	0x080c, 0x406a, 0x0904, 0x4067, 0x080c, 0x406a, 0x0804, 0x4067,
-	0x00f6, 0x2079, 0x0300, 0x78bf, 0x0000, 0x00fe, 0x7810, 0x7914,
-	0x782b, 0x0004, 0x7812, 0x7916, 0x2001, 0x0201, 0x200c, 0x81ff,
-	0x0de8, 0x080c, 0x3f75, 0x2009, 0x0001, 0x00f6, 0x2079, 0x0300,
-	0x78b8, 0x00fe, 0xd0ec, 0x0110, 0x2009, 0x0011, 0x792a, 0x00f8,
-	0x8001, 0x7002, 0x9184, 0x0880, 0x1140, 0x782c, 0xd0fc, 0x1904,
-	0x400c, 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, 0x4098, 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,
-	0x40d5, 0x40cc, 0x40c3, 0x40ba, 0x40b1, 0x40a8, 0x409f, 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, 0x1a65, 0x2079, 0x0090, 0x792c, 0xd1fc, 0x01e8,
-	0x782b, 0x0002, 0x2940, 0x9026, 0x7000, 0x0002, 0x4105, 0x40f1,
-	0x40fc, 0x8001, 0x7002, 0xd19c, 0x1180, 0x2011, 0x0001, 0x080c,
-	0x406a, 0x190c, 0x406a, 0x0048, 0x8001, 0x7002, 0x782c, 0xd0fc,
-	0x1d38, 0x2011, 0x0001, 0x080c, 0x406a, 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, 0x4abe, 0xa813, 0x0019, 0xaf16, 0x2900, 0xa85a, 0x978a,
-	0x0007, 0x0220, 0x2138, 0x2009, 0x0007, 0x0010, 0x2708, 0x903e,
-	0x0096, 0xa858, 0x2048, 0xa85c, 0x9080, 0x0019, 0x009e, 0x080c,
-	0x4181, 0x1d68, 0x2900, 0xa85a, 0x00d0, 0x080c, 0x4abe, 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, 0x23df, 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8,
+	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,
+	0x0101, 0x210c, 0x0016, 0x7ec8, 0x7dcc, 0x9006, 0x2068, 0x2060,
+	0x2058, 0x080c, 0x420b, 0x080c, 0x415b, 0x903e, 0x2720, 0x00f6,
+	0x00e6, 0x0086, 0x2940, 0x2071, 0x1a65, 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,
+	0x2102, 0x001e, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae,
+	0x009e, 0x008e, 0x2009, 0x0017, 0x080c, 0x35b5, 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,
+	0xa013, 0x0019, 0x2001, 0x032a, 0x2003, 0x0004, 0x7884, 0xd0ac,
+	0x1148, 0x2001, 0x1a61, 0x2003, 0x0003, 0x2001, 0x032a, 0x2003,
+	0x0009, 0x0030, 0xa017, 0x0001, 0x78b4, 0x9005, 0x0108, 0xa016,
+	0x2800, 0xa05a, 0x2009, 0x0040, 0x080c, 0x2410, 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,
+	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, 0x4abe, 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, 0x4abe,
-	0x2940, 0xa813, 0x0019, 0xaf16, 0x2900, 0xa85a, 0x978a, 0x0007,
-	0x0220, 0x2138, 0x2009, 0x0007, 0x0010, 0x2708, 0x903e, 0x0096,
-	0xa858, 0x2048, 0xa85c, 0x9080, 0x0019, 0x009e, 0x080c, 0x4181,
-	0x1d68, 0x2900, 0xa85a, 0x00d8, 0x080c, 0x4abe, 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, 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, 0x3531, 0x7d98, 0x7c9c, 0x0804, 0x3633,
-	0x080c, 0x73b3, 0x190c, 0x5ff2, 0x6040, 0x9084, 0x0020, 0x09b1,
-	0x2069, 0x1847, 0x2d00, 0x2009, 0x0030, 0x7a8c, 0x7b88, 0x7c9c,
-	0x7d98, 0x2039, 0x0001, 0x080c, 0x4b07, 0x701f, 0x4260, 0x0005,
-	0x080c, 0x56f1, 0x1130, 0x3b00, 0x3a08, 0xc194, 0xc095, 0x20d8,
-	0x21d0, 0x2069, 0x1847, 0x6800, 0x9005, 0x0904, 0x3566, 0x6804,
-	0xd0ac, 0x0118, 0xd0a4, 0x0904, 0x3566, 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, 0x3566, 0x9288, 0x3332, 0x210d, 0x918c, 0x00ff, 0x6166,
-	0xd0dc, 0x0130, 0x6828, 0x908a, 0x007f, 0x1a04, 0x3566, 0x605e,
-	0x6888, 0x9084, 0x0030, 0x8004, 0x8004, 0x8004, 0x8004, 0x0006,
-	0x2009, 0x19b0, 0x9080, 0x2987, 0x2005, 0x200a, 0x000e, 0x2009,
-	0x19b1, 0x9080, 0x298b, 0x2005, 0x200a, 0x6808, 0x908a, 0x0100,
-	0x0a04, 0x3566, 0x908a, 0x0841, 0x1a04, 0x3566, 0x9084, 0x0007,
-	0x1904, 0x3566, 0x680c, 0x9005, 0x0904, 0x3566, 0x6810, 0x9005,
-	0x0904, 0x3566, 0x6848, 0x6940, 0x910a, 0x1a04, 0x3566, 0x8001,
-	0x0904, 0x3566, 0x684c, 0x6944, 0x910a, 0x1a04, 0x3566, 0x8001,
-	0x0904, 0x3566, 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, 0x76ca, 0x080c, 0x69bb, 0x080c,
-	0x69ef, 0x6808, 0x602a, 0x080c, 0x2351, 0x2009, 0x0170, 0x200b,
-	0x0080, 0xa001, 0xa001, 0x200b, 0x0000, 0x0036, 0x6b08, 0x080c,
-	0x28ee, 0x003e, 0x6000, 0x9086, 0x0000, 0x1904, 0x43f7, 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,
-	0x85f5, 0x00c6, 0x900e, 0x20a9, 0x0001, 0x6b70, 0xd384, 0x0510,
-	0x0068, 0x2009, 0x0100, 0x210c, 0x918e, 0x0008, 0x1110, 0x839d,
-	0x0010, 0x83f5, 0x3e18, 0x12b0, 0x3508, 0x8109, 0x080c, 0x7c81,
-	0x6878, 0x6016, 0x6874, 0x2008, 0x9084, 0xff00, 0x8007, 0x600a,
-	0x9184, 0x00ff, 0x6006, 0x8108, 0x1118, 0x6003, 0x0003, 0x0010,
-	0x6003, 0x0001, 0x1f04, 0x4351, 0x00ce, 0x00c6, 0x2061, 0x199b,
-	0x6a88, 0x9284, 0xc000, 0x2010, 0x9286, 0x0000, 0x1158, 0x2063,
-	0x0000, 0x2001, 0x0001, 0x080c, 0x2b95, 0x2001, 0x0001, 0x080c,
-	0x2b78, 0x0088, 0x9286, 0x4000, 0x1148, 0x2063, 0x0001, 0x9006,
-	0x080c, 0x2b95, 0x9006, 0x080c, 0x2b78, 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, 0x2963, 0x2001, 0x196c, 0x2102, 0x0008, 0x2102, 0x00c6,
-	0x2061, 0x0100, 0x602f, 0x0040, 0x602f, 0x0000, 0x00ce, 0x080c,
-	0x73b3, 0x0128, 0x080c, 0x4fee, 0x0110, 0x080c, 0x28b4, 0x60d4,
-	0x9005, 0x01c0, 0x6003, 0x0001, 0x2009, 0x43df, 0x00e0, 0x080c,
-	0x73b3, 0x1168, 0x2011, 0x7249, 0x080c, 0x84f9, 0x2011, 0x723c,
-	0x080c, 0x85d3, 0x080c, 0x769e, 0x080c, 0x72e5, 0x0040, 0x080c,
-	0x5eec, 0x0028, 0x6003, 0x0004, 0x2009, 0x43f7, 0x0020, 0x080c,
-	0x68eb, 0x0804, 0x3531, 0x2001, 0x0170, 0x2004, 0x9084, 0x00ff,
-	0x9086, 0x004c, 0x1118, 0x2091, 0x30bd, 0x0817, 0x2091, 0x303d,
-	0x0817, 0x6000, 0x9086, 0x0000, 0x0904, 0x3563, 0x2069, 0x1847,
-	0x7890, 0x6842, 0x7894, 0x6846, 0x2d00, 0x2009, 0x0030, 0x7a8c,
-	0x7b88, 0x7c9c, 0x7d98, 0x2039, 0x0001, 0x0804, 0x4b0a, 0x9006,
-	0x080c, 0x28b4, 0x81ff, 0x1904, 0x3563, 0x080c, 0x73b3, 0x11b0,
-	0x080c, 0x7699, 0x080c, 0x602d, 0x080c, 0x3326, 0x0118, 0x6130,
-	0xc18d, 0x6132, 0x080c, 0xd25a, 0x0130, 0x080c, 0x73d6, 0x1118,
-	0x080c, 0x738b, 0x0038, 0x080c, 0x72e5, 0x0020, 0x080c, 0x5ff2,
-	0x080c, 0x5eec, 0x0804, 0x3531, 0x81ff, 0x1904, 0x3563, 0x080c,
-	0x73b3, 0x1110, 0x0804, 0x3563, 0x6194, 0x81ff, 0x01a8, 0x704f,
-	0x0000, 0x2001, 0x1c80, 0x2009, 0x0040, 0x7a8c, 0x7b88, 0x7c9c,
-	0x7d98, 0x0126, 0x2091, 0x8000, 0x2039, 0x0001, 0x080c, 0x4b0a,
-	0x701f, 0x352f, 0x012e, 0x0005, 0x704f, 0x0001, 0x00d6, 0x2069,
-	0x1c80, 0x20a9, 0x0040, 0x20e9, 0x0001, 0x20a1, 0x1c80, 0x2019,
-	0xffff, 0x4304, 0x655c, 0x9588, 0x3332, 0x210d, 0x918c, 0x00ff,
-	0x216a, 0x900e, 0x2011, 0x0002, 0x2100, 0x9506, 0x01a8, 0x080c,
-	0x6616, 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, 0x5f7d, 0x0804,
-	0x4451, 0x080c, 0x4af1, 0x0904, 0x3566, 0x080c, 0x4abe, 0x1120,
-	0x2009, 0x0002, 0x0804, 0x3563, 0x080c, 0x56e2, 0xd0b4, 0x0558,
-	0x7884, 0x908e, 0x007e, 0x0538, 0x908e, 0x007f, 0x0520, 0x908e,
-	0x0080, 0x0508, 0x080c, 0x3321, 0x1148, 0xb800, 0xd08c, 0x11d8,
-	0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, 0x11a8, 0xa867, 0x0000,
-	0xa868, 0xc0fd, 0xa86a, 0x080c, 0xcd23, 0x1120, 0x2009, 0x0003,
-	0x0804, 0x3563, 0x7007, 0x0003, 0x701f, 0x44df, 0x0005, 0x080c,
-	0x4af1, 0x0904, 0x3566, 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, 0x4b0a, 0x81ff, 0x1904, 0x3563,
-	0x080c, 0x4ad5, 0x0904, 0x3566, 0x080c, 0x6788, 0x0904, 0x3563,
-	0x0058, 0xa878, 0x9005, 0x0120, 0x2009, 0x0004, 0x0804, 0x3563,
-	0xa974, 0xaa94, 0x0804, 0x3531, 0x080c, 0x56ea, 0x0904, 0x3531,
-	0x701f, 0x4529, 0x7007, 0x0003, 0x0005, 0x81ff, 0x1904, 0x3563,
-	0x7888, 0x908a, 0x1000, 0x1a04, 0x3566, 0x080c, 0x4af1, 0x0904,
-	0x3566, 0x080c, 0x6989, 0x0120, 0x080c, 0x6991, 0x1904, 0x3566,
-	0x080c, 0x680d, 0x0904, 0x3563, 0x2019, 0x0004, 0x900e, 0x080c,
-	0x679a, 0x0904, 0x3563, 0x7984, 0x7a88, 0x04c9, 0x08a8, 0xa89c,
-	0x908a, 0x1000, 0x12f8, 0x080c, 0x4aef, 0x01e0, 0x080c, 0x6989,
-	0x0118, 0x080c, 0x6991, 0x11b0, 0x080c, 0x680d, 0x2009, 0x0002,
-	0x0168, 0x2009, 0x0002, 0x2019, 0x0004, 0x080c, 0x679a, 0x2009,
-	0x0003, 0x0120, 0xa998, 0xaa9c, 0x00d1, 0x0060, 0xa897, 0x4005,
-	0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001,
-	0x0030, 0x0005, 0xa897, 0x4000, 0x080c, 0x56ea, 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, 0x6616, 0x1138, 0x2200, 0x8003, 0x800b, 0x810b,
-	0x9108, 0x080c, 0x8507, 0x0005, 0x81ff, 0x1904, 0x3563, 0x798c,
-	0x2001, 0x197f, 0x918c, 0x8000, 0x2102, 0x080c, 0x4ad5, 0x0904,
-	0x3566, 0x080c, 0x6989, 0x0120, 0x080c, 0x6991, 0x1904, 0x3566,
-	0x080c, 0x66dd, 0x0904, 0x3563, 0x080c, 0x6791, 0x0904, 0x3563,
-	0x2001, 0x197f, 0x2004, 0xd0fc, 0x1904, 0x3531, 0x0804, 0x4534,
-	0xa9a0, 0x2001, 0x197f, 0x918c, 0x8000, 0xc18d, 0x2102, 0x080c,
-	0x4ae2, 0x01a0, 0x080c, 0x6989, 0x0118, 0x080c, 0x6991, 0x1170,
-	0x080c, 0x66dd, 0x2009, 0x0002, 0x0128, 0x080c, 0x6791, 0x1170,
-	0x2009, 0x0003, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006,
-	0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000,
-	0x2001, 0x197f, 0x2004, 0xd0fc, 0x1128, 0x080c, 0x56ea, 0x0110,
-	0x9006, 0x0018, 0x900e, 0x9085, 0x0001, 0x2001, 0x0000, 0x0005,
-	0x81ff, 0x1904, 0x3563, 0x798c, 0x2001, 0x197e, 0x918c, 0x8000,
-	0x2102, 0x080c, 0x4ad5, 0x0904, 0x3566, 0x080c, 0x6989, 0x0120,
-	0x080c, 0x6991, 0x1904, 0x3566, 0x080c, 0x66dd, 0x0904, 0x3563,
-	0x080c, 0x677f, 0x0904, 0x3563, 0x2001, 0x197e, 0x2004, 0xd0fc,
-	0x1904, 0x3531, 0x0804, 0x4534, 0xa9a0, 0x2001, 0x197e, 0x918c,
-	0x8000, 0xc18d, 0x2102, 0x080c, 0x4ae2, 0x01a0, 0x080c, 0x6989,
-	0x0118, 0x080c, 0x6991, 0x1170, 0x080c, 0x66dd, 0x2009, 0x0002,
-	0x0128, 0x080c, 0x677f, 0x1170, 0x2009, 0x0003, 0xa897, 0x4005,
-	0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001,
-	0x0030, 0x0005, 0xa897, 0x4000, 0x2001, 0x197e, 0x2004, 0xd0fc,
-	0x1128, 0x080c, 0x56ea, 0x0110, 0x9006, 0x0018, 0x900e, 0x9085,
-	0x0001, 0x2001, 0x0000, 0x0005, 0x6100, 0x0804, 0x3531, 0x080c,
-	0x4af1, 0x0904, 0x3566, 0x080c, 0x56f6, 0x1904, 0x3563, 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, 0x0200, 0x0804, 0x3531, 0x78a8, 0x909c, 0x0003, 0xd0ac,
-	0x1150, 0xd0b4, 0x1140, 0x939a, 0x0003, 0x1a04, 0x3563, 0x625c,
-	0x7884, 0x9206, 0x15e8, 0x080c, 0x85df, 0x2001, 0xffec, 0x7a8c,
-	0x7b88, 0x7c9c, 0x7d98, 0x2039, 0x0000, 0x0006, 0x78a8, 0x9084,
-	0x0080, 0x11c8, 0x0006, 0x0036, 0x2001, 0x1a7e, 0x201c, 0x7b9a,
-	0x2003, 0x0000, 0x2001, 0x1a7f, 0x201c, 0x7b9e, 0x2003, 0x0000,
-	0x2001, 0x1a80, 0x201c, 0x7ba2, 0x2003, 0x0000, 0x003e, 0x000e,
-	0x000e, 0x0804, 0x4b0a, 0x000e, 0x2031, 0x0000, 0x2061, 0x18b8,
-	0x2c44, 0xa66a, 0xa17a, 0xa772, 0xa076, 0xa28e, 0xa392, 0xa496,
-	0xa59a, 0x080c, 0x10e9, 0x7007, 0x0002, 0x701f, 0x4700, 0x0005,
-	0x81ff, 0x1904, 0x3563, 0x080c, 0x4af1, 0x0904, 0x3566, 0x080c,
-	0x6989, 0x1904, 0x3563, 0x00c6, 0x080c, 0x4abe, 0x00ce, 0x0904,
-	0x3563, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x7ea8, 0x080c,
-	0xccc9, 0x0904, 0x3563, 0x7007, 0x0003, 0x701f, 0x471a, 0x0005,
-	0x080c, 0x4226, 0x0006, 0x0036, 0x2001, 0x1a7e, 0x201c, 0x7b9a,
-	0x2003, 0x0000, 0x2001, 0x1a7f, 0x201c, 0x7b9e, 0x2003, 0x0000,
-	0x2001, 0x1a80, 0x201c, 0x7ba2, 0x2003, 0x0000, 0x003e, 0x000e,
-	0x0804, 0x3531, 0xa830, 0x9086, 0x0100, 0x0904, 0x3563, 0x8906,
-	0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x001b,
-	0x2009, 0x000c, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x0804, 0x4b0a,
-	0x9006, 0x080c, 0x28b4, 0x78a8, 0x9084, 0x00ff, 0x9086, 0x00ff,
-	0x0118, 0x81ff, 0x1904, 0x3563, 0x080c, 0x73b3, 0x0110, 0x080c,
-	0x5ff2, 0x7888, 0x908a, 0x1000, 0x1a04, 0x3566, 0x7984, 0x9186,
-	0x00ff, 0x0138, 0x9182, 0x007f, 0x1a04, 0x3566, 0x2100, 0x080c,
-	0x287e, 0x0026, 0x00c6, 0x0126, 0x2091, 0x8000, 0x2061, 0x19f9,
-	0x601b, 0x0000, 0x601f, 0x0000, 0x6073, 0x0000, 0x6077, 0x0000,
-	0x080c, 0x73b3, 0x1158, 0x080c, 0x7699, 0x080c, 0x602d, 0x9085,
-	0x0001, 0x080c, 0x73fa, 0x080c, 0x72e5, 0x00d0, 0x080c, 0xadd0,
-	0x2061, 0x0100, 0x2001, 0x1818, 0x2004, 0x9084, 0x00ff, 0x810f,
-	0x9105, 0x604a, 0x6043, 0x0090, 0x6043, 0x0010, 0x2009, 0x1998,
-	0x200b, 0x0000, 0x2009, 0x002d, 0x2011, 0x5f18, 0x080c, 0x8591,
-	0x7984, 0x080c, 0x73b3, 0x1110, 0x2009, 0x00ff, 0x7a88, 0x080c,
-	0x4597, 0x012e, 0x00ce, 0x002e, 0x0804, 0x3531, 0x7984, 0x080c,
-	0x65b5, 0x2b08, 0x1904, 0x3566, 0x0804, 0x3531, 0x81ff, 0x0120,
-	0x2009, 0x0001, 0x0804, 0x3563, 0x60dc, 0xd0ac, 0x1130, 0xd09c,
-	0x1120, 0x2009, 0x0005, 0x0804, 0x3563, 0x080c, 0x4abe, 0x1120,
-	0x2009, 0x0002, 0x0804, 0x3563, 0x7984, 0x9192, 0x0021, 0x1a04,
-	0x3566, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xa85c, 0x9080, 0x0019,
-	0x702a, 0xaf60, 0x7736, 0x080c, 0x4b07, 0x701f, 0x47ce, 0x7880,
-	0x9086, 0x006e, 0x0110, 0x701f, 0x51a0, 0x0005, 0x2009, 0x0080,
-	0x080c, 0x6616, 0x1118, 0x080c, 0x6989, 0x0120, 0x2021, 0x400a,
-	0x0804, 0x3533, 0x00d6, 0x0096, 0xa964, 0xaa6c, 0xab70, 0xac74,
-	0xad78, 0xae7c, 0xa884, 0x90be, 0x0100, 0x0904, 0x4867, 0x90be,
-	0x0112, 0x0904, 0x4867, 0x90be, 0x0113, 0x0904, 0x4867, 0x90be,
-	0x0114, 0x0904, 0x4867, 0x90be, 0x0117, 0x0904, 0x4867, 0x90be,
-	0x011a, 0x0904, 0x4867, 0x90be, 0x011c, 0x0904, 0x4867, 0x90be,
-	0x0121, 0x0904, 0x484e, 0x90be, 0x0131, 0x0904, 0x484e, 0x90be,
-	0x0171, 0x0904, 0x4867, 0x90be, 0x0173, 0x0904, 0x4867, 0x90be,
-	0x01a1, 0x1128, 0xa894, 0x8007, 0xa896, 0x0804, 0x4872, 0x90be,
-	0x0212, 0x0904, 0x485b, 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, 0x3566, 0x7028, 0x9080, 0x0010,
-	0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0007, 0x080c,
-	0x48b0, 0x7028, 0x9080, 0x000e, 0x2098, 0x20a0, 0x7034, 0x20e0,
-	0x20e8, 0x20a9, 0x0001, 0x080c, 0x48b0, 0x00c8, 0x7028, 0x9080,
-	0x000c, 0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0001,
-	0x080c, 0x48bd, 0x00b8, 0x7028, 0x9080, 0x000e, 0x2098, 0x20a0,
-	0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0001, 0x080c, 0x48bd, 0x7028,
+	0x78ca, 0x00ce, 0x00fe, 0x0804, 0x3daf, 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,
+	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,
+	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,
+	0x9086, 0x0000, 0x0520, 0x2079, 0x0090, 0x2009, 0x0206, 0x2104,
+	0x2009, 0x0203, 0x210c, 0x9106, 0x1120, 0x2009, 0x0040, 0x080c,
+	0x2410, 0x782c, 0xd0fc, 0x0d88, 0x080c, 0x4130, 0x7000, 0x9086,
+	0x0000, 0x1d58, 0x782b, 0x0004, 0x782c, 0xd0ac, 0x1de8, 0x2009,
+	0x0040, 0x080c, 0x2410, 0x782b, 0x0002, 0x7003, 0x0000, 0x00ee,
+	0x00fe, 0x0005, 0x00f6, 0x2079, 0x0100, 0x2001, 0x1818, 0x200c,
+	0x7932, 0x7936, 0x080c, 0x28c5, 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,
+	0x7852, 0x2001, 0x0021, 0x2004, 0x9084, 0x0003, 0x9086, 0x0001,
+	0x1120, 0x7850, 0x9084, 0xdfff, 0x7852, 0x784b, 0xf7f7, 0x7843,
+	0x0090, 0x7843, 0x0010, 0x20a9, 0x0028, 0xa001, 0x1f04, 0x3f7d,
+	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,
+	0x00fe, 0x0005, 0x7884, 0xd0ac, 0x11c8, 0x00f6, 0x00e6, 0x2071,
+	0x1a61, 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,
+	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,
+	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,
+	0x7810, 0x7914, 0x782b, 0x0004, 0x7812, 0x7916, 0x2001, 0x0201,
+	0x200c, 0x81ff, 0x0de8, 0x080c, 0x3fc7, 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,
+	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,
+	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,
+	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, 0x1a65, 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,
+	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, 0x4b1f, 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,
+	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,
+	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, 0x4b1f, 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,
+	0x978a, 0x0007, 0x0220, 0x2138, 0x2009, 0x0007, 0x0010, 0x2708,
+	0x903e, 0x0096, 0xa858, 0x2048, 0xa85c, 0x9080, 0x0019, 0x009e,
+	0x080c, 0x41d3, 0x1d68, 0x2900, 0xa85a, 0x00d8, 0x080c, 0x4b1f,
+	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, 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,
+	0x0020, 0x09b1, 0x2069, 0x1847, 0x2d00, 0x2009, 0x0030, 0x7a8c,
+	0x7b88, 0x7c9c, 0x7d98, 0x2039, 0x0001, 0x080c, 0x4b68, 0x701f,
+	0x42b2, 0x0005, 0x080c, 0x576c, 0x1130, 0x3b00, 0x3a08, 0xc194,
+	0xc095, 0x20d8, 0x21d0, 0x2069, 0x1847, 0x6800, 0x9005, 0x0904,
+	0x35b8, 0x6804, 0xd0ac, 0x0118, 0xd0a4, 0x0904, 0x35b8, 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,
+	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,
+	0x0170, 0x200b, 0x0080, 0xa001, 0xa001, 0x200b, 0x0000, 0x0036,
+	0x6b08, 0x080c, 0x291f, 0x003e, 0x6000, 0x9086, 0x0000, 0x1904,
+	0x4449, 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,
+	0xd384, 0x0510, 0x0068, 0x2009, 0x0100, 0x210c, 0x918e, 0x0008,
+	0x1110, 0x839d, 0x0010, 0x83f5, 0x3e18, 0x12b0, 0x3508, 0x8109,
+	0x080c, 0x7d0c, 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,
+	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,
+	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, 0x04f1, 0x00c6, 0x080c, 0x4abe, 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, 0xcce4, 0x1120, 0x2009,
-	0x0003, 0x0804, 0x3563, 0x7007, 0x0003, 0x701f, 0x48a7, 0x0005,
-	0x00ce, 0x009e, 0x00de, 0x2009, 0x0002, 0x0804, 0x3563, 0xa820,
-	0x9086, 0x8001, 0x1904, 0x3531, 0x2009, 0x0004, 0x0804, 0x3563,
-	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, 0x3563, 0x60dc, 0xd0ac,
-	0x1130, 0xd09c, 0x1120, 0x2009, 0x0005, 0x0804, 0x3563, 0x7984,
-	0x78a8, 0x2040, 0x080c, 0xadc9, 0x1120, 0x9182, 0x007f, 0x0a04,
-	0x3566, 0x9186, 0x00ff, 0x0904, 0x3566, 0x9182, 0x0800, 0x1a04,
-	0x3566, 0x7a8c, 0x7b88, 0x607c, 0x9306, 0x1158, 0x6080, 0x924e,
-	0x0904, 0x3566, 0x080c, 0xadc9, 0x1120, 0x99cc, 0xff00, 0x0904,
-	0x3566, 0x0126, 0x2091, 0x8000, 0x080c, 0x49d1, 0x0904, 0x4951,
-	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, 0x6989, 0x0110, 0xc89d, 0x0438,
-	0x900e, 0x080c, 0x6836, 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, 0x3533, 0x000e,
-	0x00ce, 0x2b00, 0x7026, 0x0016, 0x00b6, 0x00c6, 0x00e6, 0x2c70,
-	0x080c, 0xaead, 0x0904, 0x49a6, 0x2b00, 0x6012, 0x080c, 0xcfd4,
-	0x2e58, 0x00ee, 0x00e6, 0x00c6, 0x080c, 0x4abe, 0x00ce, 0x2b70,
-	0x1158, 0x080c, 0xae5f, 0x00ee, 0x00ce, 0x00be, 0x001e, 0x012e,
-	0x2009, 0x0002, 0x0804, 0x3563, 0x900e, 0xa966, 0xa96a, 0x2900,
-	0x6016, 0xa932, 0xa868, 0xc0fd, 0xd88c, 0x0108, 0xc0f5, 0xa86a,
-	0xd89c, 0x1110, 0x080c, 0x31cc, 0x6023, 0x0001, 0x9006, 0x080c,
-	0x6552, 0xd89c, 0x0138, 0x2001, 0x0004, 0x080c, 0x6566, 0x2009,
-	0x0003, 0x0030, 0x2001, 0x0002, 0x080c, 0x6566, 0x2009, 0x0002,
-	0x080c, 0xaeda, 0x78a8, 0xd094, 0x0138, 0x00ee, 0x7024, 0x00e6,
-	0x2058, 0xb8cc, 0xc08d, 0xb8ce, 0x9085, 0x0001, 0x00ee, 0x00ce,
-	0x00be, 0x001e, 0x012e, 0x1120, 0x2009, 0x0003, 0x0804, 0x3563,
-	0x7007, 0x0003, 0x701f, 0x49b5, 0x0005, 0xa830, 0x9086, 0x0100,
-	0x7024, 0x2058, 0x1138, 0x2009, 0x0004, 0xba04, 0x9294, 0x00ff,
-	0x0804, 0x563f, 0x900e, 0xa868, 0xd0f4, 0x1904, 0x3531, 0x080c,
-	0x6836, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x0804,
-	0x3531, 0x00e6, 0x00d6, 0x0096, 0x83ff, 0x0904, 0x4a20, 0x902e,
-	0x080c, 0xadc9, 0x0130, 0x9026, 0x20a9, 0x0800, 0x2071, 0x1000,
-	0x0030, 0x2021, 0x007f, 0x20a9, 0x0781, 0x2071, 0x107f, 0x2e04,
-	0x9005, 0x11b8, 0x2100, 0x9406, 0x1904, 0x4a31, 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, 0x6929, 0x1570, 0x2001, 0x4000, 0x0460, 0x080c,
-	0x6989, 0x1540, 0x2001, 0x4000, 0x0430, 0x2001, 0x4007, 0x0418,
-	0x2001, 0x4006, 0x0400, 0x2400, 0x9106, 0x1158, 0xbe14, 0x87ff,
-	0x1128, 0x86ff, 0x0918, 0x080c, 0xadc9, 0x1900, 0x2001, 0x4008,
-	0x0090, 0x8420, 0x8e70, 0x1f04, 0x49e7, 0x85ff, 0x1130, 0x2001,
-	0x4009, 0x0048, 0x2001, 0x0001, 0x0030, 0x080c, 0x65b5, 0x1dd0,
-	0xbb12, 0xba16, 0x9006, 0x9005, 0x009e, 0x00de, 0x00ee, 0x0005,
-	0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x3563, 0x080c, 0x4abe,
-	0x1120, 0x2009, 0x0002, 0x0804, 0x3563, 0xa867, 0x0000, 0xa868,
-	0xc0fd, 0xa86a, 0x7884, 0x9005, 0x0904, 0x3566, 0x9096, 0x00ff,
-	0x0120, 0x9092, 0x0004, 0x1a04, 0x3566, 0x2010, 0x2918, 0x080c,
-	0x3172, 0x1120, 0x2009, 0x0003, 0x0804, 0x3563, 0x7007, 0x0003,
-	0x701f, 0x4a73, 0x0005, 0xa830, 0x9086, 0x0100, 0x1904, 0x3531,
-	0x2009, 0x0004, 0x0804, 0x3563, 0x7984, 0x080c, 0xadc9, 0x1120,
-	0x9182, 0x007f, 0x0a04, 0x3566, 0x9186, 0x00ff, 0x0904, 0x3566,
-	0x9182, 0x0800, 0x1a04, 0x3566, 0x2001, 0x9000, 0x080c, 0x569a,
-	0x1904, 0x3563, 0x0804, 0x3531, 0xa998, 0x080c, 0xadc9, 0x1118,
-	0x9182, 0x007f, 0x0280, 0x9186, 0x00ff, 0x0168, 0x9182, 0x0800,
-	0x1250, 0x2001, 0x9000, 0x080c, 0x569a, 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, 0x0fff,
-	0x0198, 0x9006, 0xa802, 0x7014, 0x9005, 0x1120, 0x2900, 0x7016,
-	0x701a, 0x0040, 0x7018, 0xa802, 0x0086, 0x2040, 0x2900, 0xa006,
-	0x701a, 0x008e, 0x9085, 0x0001, 0x0005, 0x7984, 0x080c, 0x6616,
-	0x1130, 0x7e88, 0x9684, 0x3fff, 0x9082, 0x4000, 0x0208, 0x905e,
-	0x8bff, 0x0005, 0xa998, 0x080c, 0x6616, 0x1130, 0xae9c, 0x9684,
-	0x3fff, 0x9082, 0x4000, 0x0208, 0x905e, 0x8bff, 0x0005, 0xae98,
-	0x0008, 0x7e84, 0x2608, 0x080c, 0x6616, 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, 0x3531, 0x0005, 0x00f6, 0x0126,
-	0x2091, 0x8000, 0x2079, 0x0000, 0x2001, 0x18b0, 0x2004, 0x9005,
-	0x1190, 0x0e04, 0x4b3b, 0x7a36, 0x7833, 0x0012, 0x7a82, 0x7b86,
-	0x7c8a, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c,
-	0x119b, 0x0804, 0x4ba1, 0x0016, 0x0086, 0x0096, 0x00c6, 0x00e6,
-	0x2071, 0x189e, 0x7044, 0x9005, 0x1540, 0x7148, 0x9182, 0x0010,
-	0x0288, 0x7038, 0x2060, 0x080c, 0x0fff, 0x0904, 0x4b99, 0xa84b,
-	0x0000, 0x2900, 0x7046, 0x2001, 0x0002, 0x9080, 0x209d, 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, 0x209d, 0x2005, 0xa846,
-	0x0058, 0x2262, 0x6306, 0x640a, 0x00ee, 0x00ce, 0x009e, 0x008e,
-	0x001e, 0x012e, 0x00fe, 0x0005, 0x2c00, 0x9082, 0x001b, 0x0002,
-	0x4bc3, 0x4bc3, 0x4bc5, 0x4bc3, 0x4bc3, 0x4bc3, 0x4bc9, 0x4bc3,
-	0x4bc3, 0x4bc3, 0x4bcd, 0x4bc3, 0x4bc3, 0x4bc3, 0x4bd1, 0x4bc3,
-	0x4bc3, 0x4bc3, 0x4bd5, 0x4bc3, 0x4bc3, 0x4bc3, 0x4bd9, 0x4bc3,
-	0x4bc3, 0x4bc3, 0x4bde, 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, 0x4b9c, 0xa2d6, 0xa3da,
-	0xa4de, 0x0804, 0x4b9c, 0x00e6, 0x2071, 0x189e, 0x7048, 0x9005,
-	0x0904, 0x4c75, 0x0126, 0x2091, 0x8000, 0x0e04, 0x4c74, 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, 0x4c77, 0xa804, 0x9005, 0x090c, 0x0dd5, 0x7042,
-	0x2938, 0x2040, 0xa003, 0x0000, 0x2001, 0x0002, 0x9080, 0x209d,
-	0x2005, 0xa04a, 0x0804, 0x4c77, 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, 0x209d, 0x2005, 0xa84a, 0x0000, 0x007e,
-	0x008e, 0x009e, 0x00ce, 0x00fe, 0x012e, 0x00ee, 0x0005, 0x2c00,
-	0x9082, 0x001b, 0x0002, 0x4c96, 0x4c96, 0x4c98, 0x4c96, 0x4c96,
-	0x4c96, 0x4c9d, 0x4c96, 0x4c96, 0x4c96, 0x4ca2, 0x4c96, 0x4c96,
-	0x4c96, 0x4ca7, 0x4c96, 0x4c96, 0x4c96, 0x4cac, 0x4c96, 0x4c96,
-	0x4c96, 0x4cb1, 0x4c96, 0x4c96, 0x4c96, 0x4cb6, 0x080c, 0x0dd5,
-	0xaa74, 0xab78, 0xac7c, 0x0804, 0x4c22, 0xaa84, 0xab88, 0xac8c,
-	0x0804, 0x4c22, 0xaa94, 0xab98, 0xac9c, 0x0804, 0x4c22, 0xaaa4,
-	0xaba8, 0xacac, 0x0804, 0x4c22, 0xaab4, 0xabb8, 0xacbc, 0x0804,
-	0x4c22, 0xaac4, 0xabc8, 0xaccc, 0x0804, 0x4c22, 0xaad4, 0xabd8,
-	0xacdc, 0x0804, 0x4c22, 0x0016, 0x0026, 0x0036, 0x00b6, 0x00c6,
-	0x2009, 0x007e, 0x080c, 0x6616, 0x2019, 0x0001, 0xb85c, 0xd0ac,
-	0x0110, 0x2019, 0x0000, 0x2011, 0x801b, 0x080c, 0x4b1e, 0x00ce,
-	0x00be, 0x003e, 0x002e, 0x001e, 0x0005, 0x0026, 0x080c, 0x56e2,
-	0xd0c4, 0x0120, 0x2011, 0x8014, 0x080c, 0x4b1e, 0x002e, 0x0005,
-	0x81ff, 0x1904, 0x3563, 0x0126, 0x2091, 0x8000, 0x6030, 0xc08d,
-	0xc085, 0xc0ac, 0x6032, 0x080c, 0x73b3, 0x1158, 0x080c, 0x7699,
-	0x080c, 0x602d, 0x9085, 0x0001, 0x080c, 0x73fa, 0x080c, 0x72e5,
-	0x0010, 0x080c, 0x5eec, 0x012e, 0x0804, 0x3531, 0x81ff, 0x0120,
-	0x2009, 0x0001, 0x0804, 0x3563, 0x080c, 0x56f6, 0x0120, 0x2009,
-	0x0007, 0x0804, 0x3563, 0x080c, 0x6981, 0x0120, 0x2009, 0x0008,
-	0x0804, 0x3563, 0x7984, 0x080c, 0x65b5, 0x1904, 0x3566, 0x2b00,
-	0x7026, 0x080c, 0x6989, 0x7888, 0x1170, 0x9084, 0x0005, 0x1158,
-	0x900e, 0x080c, 0x6836, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108,
-	0xc18d, 0x0804, 0x3531, 0x080c, 0x4abe, 0x0904, 0x3563, 0x9006,
-	0xa866, 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xcd82, 0x0904,
-	0x3563, 0x7888, 0xd094, 0x0118, 0xb8cc, 0xc08d, 0xb8ce, 0x7007,
-	0x0003, 0x701f, 0x4d90, 0x0005, 0x2061, 0x1800, 0x080c, 0x56f6,
-	0x2009, 0x0007, 0x1578, 0x080c, 0x6981, 0x0118, 0x2009, 0x0008,
-	0x0448, 0x080c, 0x3321, 0x0120, 0xa998, 0x080c, 0x65b5, 0x1530,
-	0x080c, 0x4aef, 0x0518, 0x080c, 0x6989, 0xa89c, 0x1168, 0x9084,
-	0x0005, 0x1150, 0x900e, 0x080c, 0x6836, 0x1108, 0xc185, 0xb800,
-	0xd0bc, 0x0108, 0xc18d, 0x00d0, 0xa868, 0xc0fc, 0xa86a, 0x080c,
-	0xcd82, 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, 0x563f,
-	0x900e, 0x080c, 0x6836, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108,
-	0xc18d, 0x0804, 0x3531, 0x080c, 0x56f6, 0x0120, 0x2009, 0x0007,
-	0x0804, 0x3563, 0x7f84, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x080c,
-	0x4abe, 0x1120, 0x2009, 0x0002, 0x0804, 0x3563, 0x900e, 0x2130,
-	0x7126, 0x7132, 0xa860, 0x20e8, 0x7036, 0xa85c, 0x9080, 0x0005,
-	0x702a, 0x20a0, 0x080c, 0x6616, 0x1904, 0x4e32, 0x080c, 0x6989,
-	0x0138, 0x080c, 0x6991, 0x0120, 0x080c, 0x6929, 0x1904, 0x4e32,
-	0xd794, 0x1110, 0xd784, 0x01a8, 0xb8c4, 0x20e0, 0xb8c8, 0x9080,
-	0x0006, 0x2098, 0x3400, 0xd794, 0x0160, 0x20a9, 0x0008, 0x4003,
-	0x2098, 0x20a0, 0x3d00, 0x20e0, 0x20a9, 0x0002, 0x080c, 0x48bd,
-	0x0048, 0x20a9, 0x0004, 0x4003, 0x2098, 0x20a0, 0x3d00, 0x20e0,
-	0x080c, 0x48bd, 0x9186, 0x007e, 0x0170, 0x9186, 0x0080, 0x0158,
-	0x080c, 0x6989, 0x90c2, 0x0006, 0x1210, 0xc1fd, 0x0020, 0x080c,
-	0x6836, 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, 0x48b0, 0x9c80, 0x0026, 0x2098, 0xb8c4,
-	0x20e0, 0x20a9, 0x0002, 0x4003, 0xd794, 0x0110, 0x96b0, 0x000b,
-	0x96b0, 0x0005, 0x8108, 0x080c, 0xadc9, 0x0118, 0x9186, 0x0800,
-	0x0040, 0xd78c, 0x0120, 0x9186, 0x0800, 0x0170, 0x0018, 0x9186,
-	0x007e, 0x0150, 0xd794, 0x0118, 0x9686, 0x0020, 0x0010, 0x9686,
-	0x0028, 0x0150, 0x0804, 0x4dc2, 0x86ff, 0x1120, 0x7124, 0x810b,
-	0x0804, 0x3531, 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, 0x4e6e, 0x0005, 0x7030, 0x9005,
-	0x1180, 0x7120, 0x7028, 0x20a0, 0x772c, 0x9036, 0x7034, 0x20e8,
-	0x2061, 0x18b8, 0x2c44, 0xa28c, 0xa390, 0xa494, 0xa598, 0x0804,
-	0x4dc2, 0x7124, 0x810b, 0x0804, 0x3531, 0x2029, 0x007e, 0x7984,
-	0x7a88, 0x7b8c, 0x7c98, 0x9184, 0xff00, 0x8007, 0x90e2, 0x0020,
-	0x0a04, 0x3566, 0x9502, 0x0a04, 0x3566, 0x9184, 0x00ff, 0x90e2,
-	0x0020, 0x0a04, 0x3566, 0x9502, 0x0a04, 0x3566, 0x9284, 0xff00,
-	0x8007, 0x90e2, 0x0020, 0x0a04, 0x3566, 0x9502, 0x0a04, 0x3566,
-	0x9284, 0x00ff, 0x90e2, 0x0020, 0x0a04, 0x3566, 0x9502, 0x0a04,
-	0x3566, 0x9384, 0xff00, 0x8007, 0x90e2, 0x0020, 0x0a04, 0x3566,
-	0x9502, 0x0a04, 0x3566, 0x9384, 0x00ff, 0x90e2, 0x0020, 0x0a04,
-	0x3566, 0x9502, 0x0a04, 0x3566, 0x9484, 0xff00, 0x8007, 0x90e2,
-	0x0020, 0x0a04, 0x3566, 0x9502, 0x0a04, 0x3566, 0x9484, 0x00ff,
-	0x90e2, 0x0020, 0x0a04, 0x3566, 0x9502, 0x0a04, 0x3566, 0x2061,
-	0x1988, 0x6102, 0x6206, 0x630a, 0x640e, 0x0804, 0x3531, 0x080c,
-	0x4abe, 0x0904, 0x3563, 0x2009, 0x0016, 0x7a8c, 0x7b88, 0x7c9c,
-	0x7d98, 0xa85c, 0x9080, 0x0019, 0xaf60, 0x080c, 0x4b07, 0x701f,
-	0x4ef2, 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, 0x4f73, 0x6804, 0x2008, 0x918c, 0xfff8,
-	0x1904, 0x4f73, 0x680c, 0x9005, 0x0904, 0x4f73, 0x9082, 0xff01,
-	0x1a04, 0x4f73, 0x6810, 0x9082, 0x005c, 0x0a04, 0x4f73, 0x6824,
-	0x2008, 0x9082, 0x0008, 0x0a04, 0x4f73, 0x9182, 0x0400, 0x1a04,
-	0x4f73, 0x0056, 0x2029, 0x0000, 0x080c, 0x8b01, 0x005e, 0x6944,
-	0x6820, 0x9102, 0x06c0, 0x6820, 0x9082, 0x0019, 0x16a0, 0x6828,
-	0x6944, 0x810c, 0x9102, 0x0678, 0x6840, 0x9082, 0x000f, 0x1658,
-	0x080c, 0x1018, 0x2900, 0x0904, 0x4f8d, 0x684e, 0x00e6, 0x2071,
-	0x1930, 0x00b6, 0x2059, 0x0000, 0x080c, 0x89bd, 0x00be, 0x00ee,
-	0x0558, 0x080c, 0x8717, 0x080c, 0x875d, 0x11e0, 0x6857, 0x0000,
-	0x00c6, 0x2061, 0x0100, 0x6104, 0x918d, 0x2000, 0x6106, 0x6b10,
-	0x2061, 0x1a61, 0x630a, 0x00ce, 0x080c, 0x2963, 0x2001, 0x0138,
-	0x2102, 0x0804, 0x3531, 0x080c, 0x2963, 0x2001, 0x0138, 0x2102,
-	0x0804, 0x3566, 0x00e6, 0x2071, 0x1930, 0x080c, 0x8b92, 0x080c,
-	0x8ba1, 0x080c, 0x89ac, 0x00ee, 0x2001, 0x188a, 0x204c, 0x080c,
-	0x1031, 0x2001, 0x188a, 0x2003, 0x0000, 0x080c, 0x2963, 0x2001,
-	0x0138, 0x2102, 0x0804, 0x3563, 0x2001, 0x1924, 0x200c, 0x918e,
-	0x0000, 0x0904, 0x4fec, 0x080c, 0x89a7, 0x0904, 0x4fec, 0x2001,
-	0x0101, 0x200c, 0x918c, 0xdfff, 0x2102, 0x2001, 0x0138, 0x2003,
-	0x0000, 0x00e6, 0x2071, 0x0300, 0x701c, 0xd0a4, 0x1de8, 0x00ee,
-	0x080c, 0x89ac, 0x2001, 0x0035, 0x080c, 0x15f0, 0x00c6, 0x2061,
-	0x193c, 0x6004, 0x6100, 0x9106, 0x1de0, 0x00ce, 0x080c, 0x2963,
-	0x2001, 0x0138, 0x2102, 0x00e6, 0x00f6, 0x2071, 0x1923, 0x080c,
-	0x88e8, 0x0120, 0x2f00, 0x080c, 0x8972, 0x0cc8, 0x00fe, 0x00ee,
-	0x0126, 0x2091, 0x8000, 0x2001, 0x188a, 0x200c, 0x81ff, 0x0138,
-	0x2148, 0x080c, 0x1031, 0x2001, 0x188a, 0x2003, 0x0000, 0x2001,
-	0x183c, 0x2003, 0x0020, 0x00e6, 0x2071, 0x1930, 0x080c, 0x8b92,
-	0x080c, 0x8ba1, 0x00ee, 0x012e, 0x0804, 0x3531, 0x0006, 0x080c,
-	0x56e2, 0xd0cc, 0x000e, 0x0005, 0x0006, 0x080c, 0x56e6, 0xd0bc,
-	0x000e, 0x0005, 0x6174, 0x7a84, 0x6300, 0x82ff, 0x1118, 0x7986,
-	0x0804, 0x3531, 0x83ff, 0x1904, 0x3566, 0x2001, 0xfff0, 0x9200,
-	0x1a04, 0x3566, 0x2019, 0xffff, 0x6078, 0x9302, 0x9200, 0x0a04,
-	0x3566, 0x7986, 0x6276, 0x0804, 0x3531, 0x080c, 0x56f6, 0x1904,
-	0x3563, 0x7c88, 0x7d84, 0x7e98, 0x7f8c, 0x080c, 0x4abe, 0x0904,
-	0x3563, 0x900e, 0x901e, 0x7326, 0x7332, 0xa860, 0x20e8, 0x7036,
-	0xa85c, 0x9080, 0x0003, 0x702a, 0x20a0, 0x91d8, 0x1000, 0x2b5c,
-	0x8bff, 0x0178, 0x080c, 0x6989, 0x0118, 0x080c, 0x6991, 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,
-	0x8f70, 0x2208, 0x0804, 0x3531, 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, 0x506f, 0x0005, 0x7030,
-	0x9005, 0x1178, 0x7120, 0x7028, 0x20a0, 0x901e, 0x7034, 0x20e8,
-	0x2061, 0x18b8, 0x2c44, 0xa48c, 0xa590, 0xa694, 0xa798, 0x0804,
-	0x502d, 0x7224, 0x900e, 0x2001, 0x0003, 0x080c, 0x8f70, 0x2208,
-	0x0804, 0x3531, 0x00f6, 0x00e6, 0x080c, 0x56f6, 0x2009, 0x0007,
-	0x1904, 0x5102, 0x2071, 0x189e, 0x745c, 0x84ff, 0x2009, 0x000e,
-	0x1904, 0x5102, 0xac9c, 0xad98, 0xaea4, 0xafa0, 0x0096, 0x080c,
-	0x1018, 0x2009, 0x0002, 0x0904, 0x5102, 0x2900, 0x705e, 0x900e,
-	0x901e, 0x7356, 0x7362, 0xa860, 0x7066, 0xa85c, 0x9080, 0x0003,
-	0x705a, 0x20a0, 0x91d8, 0x1000, 0x2b5c, 0x8bff, 0x0178, 0x080c,
-	0x6989, 0x0118, 0x080c, 0x6991, 0x1148, 0xb814, 0x20a9, 0x0001,
+	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,
+	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,
 	0x4004, 0xb810, 0x4004, 0x4104, 0x9398, 0x0003, 0x8108, 0x9182,
-	0x0800, 0x0120, 0x9386, 0x003c, 0x01e8, 0x0c20, 0x83ff, 0x11c0,
-	0x7254, 0x900e, 0x2001, 0x0003, 0x080c, 0x8f70, 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, 0x510e, 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, 0x8f70, 0xaa9a, 0x715c, 0x81ff, 0x090c, 0x0dd5,
-	0x2148, 0x080c, 0x1031, 0x705f, 0x0000, 0xa0a0, 0x2048, 0x0126,
-	0x2091, 0x8000, 0x080c, 0x6c94, 0x012e, 0xa09f, 0x0000, 0xa0a3,
-	0x0000, 0x00ee, 0x00fe, 0x0005, 0x91d8, 0x1000, 0x2b5c, 0x8bff,
-	0x0178, 0x080c, 0x6989, 0x0118, 0x080c, 0x6991, 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, 0x0dd5, 0x2148, 0x080c, 0x1031, 0x9006, 0x705e,
-	0x918d, 0x0001, 0x2008, 0xa0a0, 0x2048, 0x0126, 0x2091, 0x8000,
-	0x080c, 0x6c94, 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, 0x3566, 0xa884, 0xa988,
-	0x080c, 0x284b, 0x1518, 0x080c, 0x65b5, 0x1500, 0x7126, 0xbe12,
-	0xbd16, 0xae7c, 0x080c, 0x4abe, 0x01c8, 0x080c, 0x4abe, 0x01b0,
-	0x009e, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0xa823, 0x0000,
-	0xa804, 0x2048, 0x080c, 0xcd04, 0x1120, 0x2009, 0x0003, 0x0804,
-	0x3563, 0x7007, 0x0003, 0x701f, 0x51db, 0x0005, 0x009e, 0x2009,
-	0x0002, 0x0804, 0x3563, 0x7124, 0x080c, 0x32c8, 0xa820, 0x9086,
-	0x8001, 0x1120, 0x2009, 0x0004, 0x0804, 0x3563, 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,
-	0x4b0a, 0x97c6, 0x7200, 0x11b8, 0x96c2, 0x0054, 0x02a0, 0x000e,
-	0x007e, 0x2061, 0x18b8, 0x2c44, 0xa076, 0xa772, 0xa07b, 0x002a,
-	0xa28e, 0xa392, 0xa496, 0xa59a, 0x080c, 0x10e9, 0x7007, 0x0002,
-	0x701f, 0x5237, 0x0005, 0x000e, 0x007e, 0x0804, 0x3566, 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, 0x4b0a, 0x81ff, 0x1904, 0x3563, 0x798c, 0x2001,
-	0x197d, 0x918c, 0x8000, 0x2102, 0x080c, 0x4ad5, 0x0904, 0x3566,
-	0x080c, 0x6989, 0x0120, 0x080c, 0x6991, 0x1904, 0x3566, 0x080c,
-	0x66dd, 0x0904, 0x3563, 0x0126, 0x2091, 0x8000, 0x080c, 0x67a3,
-	0x012e, 0x0904, 0x3563, 0x2001, 0x197d, 0x2004, 0xd0fc, 0x1904,
-	0x3531, 0x0804, 0x4534, 0xa9a0, 0x2001, 0x197d, 0x918c, 0x8000,
-	0xc18d, 0x2102, 0x080c, 0x4ae2, 0x01a0, 0x080c, 0x6989, 0x0118,
-	0x080c, 0x6991, 0x1170, 0x080c, 0x66dd, 0x2009, 0x0002, 0x0128,
-	0x080c, 0x67a3, 0x1170, 0x2009, 0x0003, 0xa897, 0x4005, 0xa99a,
-	0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030,
-	0x0005, 0xa897, 0x4000, 0x2001, 0x197d, 0x2004, 0xd0fc, 0x1128,
-	0x080c, 0x56ea, 0x0110, 0x9006, 0x0018, 0x900e, 0x9085, 0x0001,
-	0x2001, 0x0000, 0x0005, 0x78a8, 0xd08c, 0x1118, 0xd084, 0x0904,
-	0x44a9, 0x080c, 0x4af1, 0x0904, 0x3566, 0x080c, 0x4abe, 0x1120,
-	0x2009, 0x0002, 0x0804, 0x3563, 0x080c, 0x6989, 0x0130, 0x908e,
-	0x0004, 0x0118, 0x908e, 0x0005, 0x15a0, 0x78a8, 0xd08c, 0x0120,
-	0xb800, 0xc08c, 0xb802, 0x0028, 0x080c, 0x56e2, 0xd0b4, 0x0904,
-	0x44e3, 0x7884, 0x908e, 0x007e, 0x0904, 0x44e3, 0x908e, 0x007f,
-	0x0904, 0x44e3, 0x908e, 0x0080, 0x0904, 0x44e3, 0xb800, 0xd08c,
-	0x1904, 0x44e3, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x080c,
-	0xcd23, 0x1120, 0x2009, 0x0003, 0x0804, 0x3563, 0x7007, 0x0003,
-	0x701f, 0x5303, 0x0005, 0x080c, 0x4af1, 0x0904, 0x3566, 0x0804,
-	0x44e3, 0x080c, 0x3321, 0x0108, 0x0005, 0x2009, 0x1834, 0x210c,
-	0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x3563, 0x080c, 0x56f6,
-	0x0120, 0x2009, 0x0007, 0x0804, 0x3563, 0x080c, 0x6981, 0x0120,
-	0x2009, 0x0008, 0x0804, 0x3563, 0xb89c, 0xd0a4, 0x1118, 0xd0ac,
-	0x1904, 0x44e3, 0x9006, 0xa866, 0xa832, 0xa868, 0xc0fd, 0xa86a,
-	0x080c, 0xcd82, 0x1120, 0x2009, 0x0003, 0x0804, 0x3563, 0x7007,
-	0x0003, 0x701f, 0x533c, 0x0005, 0xa830, 0x9086, 0x0100, 0x1120,
-	0x2009, 0x0004, 0x0804, 0x563f, 0x080c, 0x4af1, 0x0904, 0x3566,
-	0x0804, 0x52d5, 0x81ff, 0x2009, 0x0001, 0x1904, 0x3563, 0x080c,
-	0x56f6, 0x2009, 0x0007, 0x1904, 0x3563, 0x080c, 0x6981, 0x0120,
-	0x2009, 0x0008, 0x0804, 0x3563, 0x080c, 0x4af1, 0x0904, 0x3566,
-	0x080c, 0x6989, 0x2009, 0x0009, 0x1904, 0x3563, 0x080c, 0x4abe,
-	0x2009, 0x0002, 0x0904, 0x3563, 0x9006, 0xa866, 0xa832, 0xa868,
-	0xc0fd, 0xa86a, 0x7988, 0x9194, 0xff00, 0x918c, 0x00ff, 0x9006,
-	0x82ff, 0x1128, 0xc0ed, 0xa952, 0x798c, 0xa956, 0x0038, 0x928e,
-	0x0100, 0x1904, 0x3566, 0xc0e5, 0xa952, 0xa956, 0xa83e, 0x080c,
-	0xcfd5, 0x2009, 0x0003, 0x0904, 0x3563, 0x7007, 0x0003, 0x701f,
-	0x5392, 0x0005, 0xa830, 0x9086, 0x0100, 0x2009, 0x0004, 0x0904,
-	0x3563, 0x0804, 0x3531, 0x7aa8, 0x9284, 0xc000, 0x0148, 0xd2ec,
-	0x01a0, 0x080c, 0x56f6, 0x1188, 0x2009, 0x0014, 0x0804, 0x3563,
-	0xd2dc, 0x1568, 0x81ff, 0x2009, 0x0001, 0x1904, 0x3563, 0x080c,
-	0x56f6, 0x2009, 0x0007, 0x1904, 0x3563, 0xd2f4, 0x0130, 0x9284,
-	0x5000, 0x080c, 0x56bd, 0x0804, 0x3531, 0xd2fc, 0x0158, 0x080c,
-	0x4af1, 0x0904, 0x3566, 0x7984, 0x9284, 0x9000, 0x080c, 0x569a,
-	0x0804, 0x3531, 0x080c, 0x4af1, 0x0904, 0x3566, 0xb804, 0x9084,
-	0x00ff, 0x9086, 0x0006, 0x2009, 0x0009, 0x1904, 0x547b, 0x080c,
-	0x4abe, 0x2009, 0x0002, 0x0904, 0x547b, 0xa85c, 0x9080, 0x001b,
+	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,
+	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,
 	0xaf60, 0x2009, 0x0008, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x080c,
-	0x4b07, 0x701f, 0x53ec, 0x0005, 0xa86c, 0x9086, 0x0500, 0x1138,
+	0x4b68, 0x701f, 0x5454, 0x0005, 0xa86c, 0x9086, 0x0500, 0x1138,
 	0xa870, 0x9005, 0x1120, 0xa874, 0x9084, 0xff00, 0x0110, 0x1904,
-	0x3566, 0xa866, 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0x4af1,
-	0x1110, 0x0804, 0x3566, 0x2009, 0x0043, 0x080c, 0xd03d, 0x2009,
-	0x0003, 0x0904, 0x547b, 0x7007, 0x0003, 0x701f, 0x5410, 0x0005,
-	0xa830, 0x9086, 0x0100, 0x2009, 0x0004, 0x0904, 0x547b, 0x7984,
-	0x7aa8, 0x9284, 0x1000, 0x080c, 0x569a, 0x0804, 0x3531, 0x00c6,
-	0xaab0, 0x9284, 0xc000, 0x0140, 0xd2ec, 0x0168, 0x080c, 0x56f6,
-	0x1150, 0x2009, 0x0014, 0x04f0, 0x2061, 0x1800, 0x080c, 0x56f6,
-	0x2009, 0x0007, 0x15b8, 0xd2f4, 0x0128, 0x9284, 0x5000, 0x080c,
-	0x56bd, 0x0050, 0xd2fc, 0x0178, 0x080c, 0x4aef, 0x0588, 0xa998,
-	0x9284, 0x9000, 0x080c, 0x569a, 0xa87b, 0x0000, 0xa883, 0x0000,
-	0xa897, 0x4000, 0x0438, 0x080c, 0x4aef, 0x0510, 0x080c, 0x6989,
-	0x2009, 0x0009, 0x11b8, 0xa8c4, 0x9086, 0x0500, 0x11c8, 0xa8c8,
-	0x9005, 0x11b0, 0xa8cc, 0x9084, 0xff00, 0x1190, 0x080c, 0x4aef,
-	0x1108, 0x0070, 0x2009, 0x004b, 0x080c, 0xd03d, 0x2009, 0x0003,
-	0x0108, 0x0078, 0x0429, 0x19c0, 0xa897, 0x4005, 0xa99a, 0x0010,
-	0xa897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x00ce,
-	0x0005, 0x9006, 0x0ce0, 0x7aa8, 0xd2dc, 0x0904, 0x3563, 0x0016,
-	0x7984, 0x9284, 0x1000, 0xc0fd, 0x080c, 0x569a, 0x001e, 0x1904,
-	0x3563, 0x0804, 0x3531, 0x00f6, 0x2d78, 0x0011, 0x00fe, 0x0005,
-	0xaab0, 0xd2dc, 0x0150, 0x0016, 0xa998, 0x9284, 0x1000, 0xc0fd,
-	0x080c, 0x569a, 0x001e, 0x9085, 0x0001, 0x0005, 0x81ff, 0x0120,
-	0x2009, 0x0001, 0x0804, 0x3563, 0x080c, 0x56f6, 0x0120, 0x2009,
-	0x0007, 0x0804, 0x3563, 0x7984, 0x7ea8, 0x96b4, 0x00ff, 0x080c,
-	0x6616, 0x1904, 0x3566, 0x9186, 0x007f, 0x0138, 0x080c, 0x6989,
-	0x0120, 0x2009, 0x0009, 0x0804, 0x3563, 0x080c, 0x4abe, 0x1120,
-	0x2009, 0x0002, 0x0804, 0x3563, 0xa867, 0x0000, 0xa868, 0xc0fd,
-	0xa86a, 0x2001, 0x0100, 0x8007, 0xa80a, 0x080c, 0xcd3d, 0x1120,
-	0x2009, 0x0003, 0x0804, 0x3563, 0x7007, 0x0003, 0x701f, 0x54d9,
-	0x0005, 0xa808, 0x8007, 0x9086, 0x0100, 0x1120, 0x2009, 0x0004,
-	0x0804, 0x3563, 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, 0x4b0a,
-	0x080c, 0x4abe, 0x1120, 0x2009, 0x0002, 0x0804, 0x3563, 0x7984,
-	0x9194, 0xff00, 0x918c, 0x00ff, 0x8217, 0x82ff, 0x1118, 0x7023,
-	0x19b2, 0x0040, 0x92c6, 0x0001, 0x1118, 0x7023, 0x19cc, 0x0010,
-	0x0804, 0x3566, 0x2009, 0x001a, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98,
-	0xa85c, 0x9080, 0x0019, 0xaf60, 0x080c, 0x4b07, 0x701f, 0x5529,
-	0x0005, 0x2001, 0x182e, 0x2003, 0x0001, 0xa85c, 0x9080, 0x0019,
-	0x2098, 0xa860, 0x20e0, 0x20a9, 0x001a, 0x7020, 0x20a0, 0x20e9,
-	0x0001, 0x4003, 0x0804, 0x3531, 0x080c, 0x4abe, 0x1120, 0x2009,
-	0x0002, 0x0804, 0x3563, 0x7984, 0x9194, 0xff00, 0x918c, 0x00ff,
-	0x8217, 0x82ff, 0x1118, 0x2099, 0x19b2, 0x0040, 0x92c6, 0x0001,
-	0x1118, 0x2099, 0x19cc, 0x0010, 0x0804, 0x3566, 0xa85c, 0x9080,
-	0x0019, 0x20a0, 0xa860, 0x20e8, 0x20a9, 0x001a, 0x20e1, 0x0001,
-	0x4003, 0x2009, 0x001a, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xa85c,
-	0x9080, 0x0019, 0xaf60, 0x0804, 0x4b0a, 0x7884, 0x908a, 0x1000,
-	0x1a04, 0x3566, 0x0126, 0x2091, 0x8000, 0x8003, 0x800b, 0x810b,
-	0x9108, 0x00c6, 0x2061, 0x19f9, 0x6142, 0x00ce, 0x012e, 0x0804,
-	0x3531, 0x00c6, 0x080c, 0x73b3, 0x1160, 0x080c, 0x7699, 0x080c,
-	0x602d, 0x9085, 0x0001, 0x080c, 0x73fa, 0x080c, 0x72e5, 0x080c,
-	0x0dd5, 0x2061, 0x1800, 0x6030, 0xc09d, 0x6032, 0x080c, 0x5eec,
-	0x00ce, 0x0005, 0x00c6, 0x2001, 0x1800, 0x2004, 0x908e, 0x0000,
-	0x0904, 0x3563, 0x7884, 0x9005, 0x0188, 0x7888, 0x2061, 0x199b,
-	0x2c0c, 0x2062, 0x080c, 0x2c2d, 0x01a0, 0x080c, 0x2c35, 0x0188,
-	0x080c, 0x2c3d, 0x0170, 0x2162, 0x0804, 0x3566, 0x2061, 0x0100,
-	0x6038, 0x9086, 0x0007, 0x1118, 0x2009, 0x0001, 0x0010, 0x2009,
-	0x0000, 0x7884, 0x9086, 0x0002, 0x1548, 0x2061, 0x0100, 0x6028,
-	0xc09c, 0x602a, 0x0026, 0x2011, 0x0003, 0x080c, 0xa63e, 0x2011,
-	0x0002, 0x080c, 0xa648, 0x002e, 0x080c, 0xa552, 0x0036, 0x901e,
-	0x080c, 0xa5c8, 0x003e, 0x60e3, 0x0000, 0x080c, 0xea24, 0x080c,
-	0xea3f, 0x9085, 0x0001, 0x080c, 0x73fa, 0x9006, 0x080c, 0x2cfc,
-	0x2001, 0x1800, 0x2003, 0x0004, 0x6027, 0x0008, 0x00ce, 0x0804,
-	0x3531, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x3563, 0x080c,
-	0x56f6, 0x0120, 0x2009, 0x0007, 0x0804, 0x3563, 0x7984, 0x7ea8,
-	0x96b4, 0x00ff, 0x080c, 0x6616, 0x1904, 0x3566, 0x9186, 0x007f,
-	0x0138, 0x080c, 0x6989, 0x0120, 0x2009, 0x0009, 0x0804, 0x3563,
-	0x080c, 0x4abe, 0x1120, 0x2009, 0x0002, 0x0804, 0x3563, 0xa867,
-	0x0000, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xcd40, 0x1120, 0x2009,
-	0x0003, 0x0804, 0x3563, 0x7007, 0x0003, 0x701f, 0x5628, 0x0005,
-	0xa830, 0x9086, 0x0100, 0x1120, 0x2009, 0x0004, 0x0804, 0x3563,
-	0xa8e0, 0xa866, 0xa834, 0x8007, 0x800c, 0xa85c, 0x9080, 0x000c,
-	0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xaf60, 0x0804, 0x4b0a, 0xa898,
-	0x9086, 0x000d, 0x1904, 0x3563, 0x2021, 0x4005, 0x0126, 0x2091,
-	0x8000, 0x0e04, 0x564c, 0x0010, 0x012e, 0x0cc0, 0x7c36, 0x9486,
-	0x4000, 0x0118, 0x7833, 0x0011, 0x0010, 0x7833, 0x0010, 0x7883,
-	0x4005, 0xa998, 0x7986, 0xa9a4, 0x799a, 0xa9a8, 0x799e, 0x080c,
-	0x4afa, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c,
-	0x119b, 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, 0xa07b, 0x0001,
-	0xa07f, 0x0002, 0xa06b, 0x0000, 0xa09f, 0x0000, 0x00ce, 0x012e,
-	0x0804, 0x3531, 0x0126, 0x2091, 0x8000, 0x00b6, 0x00c6, 0x90e4,
-	0xc000, 0x0128, 0x0006, 0x080c, 0xcba7, 0x000e, 0x1198, 0xd0e4,
-	0x0160, 0x9180, 0x1000, 0x2004, 0x905d, 0x0160, 0x080c, 0x6047,
-	0x080c, 0xadc9, 0x0110, 0xb817, 0x0000, 0x9006, 0x00ce, 0x00be,
-	0x012e, 0x0005, 0x9085, 0x0001, 0x0cc8, 0x0126, 0x2091, 0x8000,
-	0x0156, 0x2010, 0x900e, 0x20a9, 0x0800, 0x0016, 0x9180, 0x1000,
-	0x2004, 0x9005, 0x0180, 0x9186, 0x007e, 0x0168, 0x9186, 0x007f,
-	0x0150, 0x9186, 0x0080, 0x0138, 0x9186, 0x00ff, 0x0120, 0x0026,
-	0x2200, 0x0801, 0x002e, 0x001e, 0x8108, 0x1f04, 0x56c5, 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, 0x3566, 0x810c, 0x0016, 0x080c, 0x4abe, 0x080c,
-	0x0f07, 0x2100, 0x2238, 0x7d84, 0x7c88, 0x7b8c, 0x7a90, 0x001e,
-	0x080c, 0x4b07, 0x701f, 0x571d, 0x0005, 0x2079, 0x0000, 0x7d94,
+	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,
+	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,
+	0xa87b, 0x0000, 0xa883, 0x0000, 0xa897, 0x4000, 0x0438, 0x080c,
+	0x4b50, 0x0510, 0x080c, 0x6a0c, 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,
+	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,
+	0x2d78, 0xaab0, 0x0021, 0x00fe, 0x0005, 0xaab0, 0xc2d5, 0xd2dc,
+	0x0150, 0x0016, 0xa998, 0x9284, 0x1400, 0xc0fd, 0x080c, 0x570c,
+	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,
+	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,
+	0x2009, 0x001a, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xa85c, 0x9080,
+	0x0019, 0xaf60, 0x080c, 0x4b68, 0x701f, 0x5597, 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,
+	0xa860, 0x20e8, 0x20a9, 0x001a, 0x20e1, 0x0001, 0x4003, 0x2009,
+	0x001a, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xa85c, 0x9080, 0x0019,
+	0xaf60, 0x0804, 0x4b6b, 0x7884, 0x908a, 0x1000, 0x1a04, 0x35b8,
+	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,
+	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,
+	0x9080, 0x000c, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xaf60, 0x0804,
+	0x4b6b, 0xa898, 0x9086, 0x000d, 0x1904, 0x35b5, 0x2021, 0x4005,
+	0x0126, 0x2091, 0x8000, 0x0e04, 0x56be, 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,
+	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,
+	0xa07b, 0x0001, 0xa07f, 0x0002, 0xa06b, 0x0000, 0xa09f, 0x0000,
+	0x00ce, 0x012e, 0x0804, 0x3583, 0x0126, 0x2091, 0x8000, 0x00b6,
+	0x00c6, 0x90e4, 0xc000, 0x0168, 0x0006, 0xd0d4, 0x0130, 0x0036,
+	0x2019, 0x0029, 0x080c, 0x3338, 0x003e, 0x080c, 0xccd3, 0x000e,
+	0x1198, 0xd0e4, 0x0160, 0x9180, 0x1000, 0x2004, 0x905d, 0x0160,
+	0x080c, 0x60c7, 0x080c, 0xaead, 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,
+	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, 0x4b0a, 0x701f, 0x5731,
+	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, 0x3531, 0x0126, 0x0156, 0x0136, 0x0146, 0x01c6,
+	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, 0x58ec, 0x0068, 0xd08c, 0x0118, 0x080c, 0x57f5, 0x0040,
-	0xd094, 0x0118, 0x080c, 0x57c5, 0x0018, 0xd09c, 0x0108, 0x0099,
+	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,
@@ -2598,215 +2614,215 @@
 	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, 0x5fa9, 0x00f0, 0x6040, 0x9084,
+	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, 0x5e8f, 0x080c, 0x8591, 0x0005, 0x2001, 0x1869, 0x2004,
+	0x2011, 0x5f0f, 0x080c, 0x8648, 0x0005, 0x2001, 0x1869, 0x2004,
 	0xd08c, 0x0110, 0x705f, 0xffff, 0x7088, 0x9005, 0x1528, 0x2011,
-	0x5e8f, 0x080c, 0x84f9, 0x6040, 0x9094, 0x0010, 0x9285, 0x0020,
-	0x6042, 0x20a9, 0x00c8, 0x6044, 0xd08c, 0x1168, 0x1f04, 0x57db,
+	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, 0x6032, 0x0000, 0x0005, 0x708c, 0x908a, 0x0003,
-	0x1a0c, 0x0dd5, 0x000b, 0x0005, 0x57ff, 0x5850, 0x58eb, 0x00f6,
+	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, 0x580e, 0x080c, 0x0dd5, 0x68a0, 0x68a2,
+	0x00fc, 0x0120, 0x1f04, 0x588e, 0x080c, 0x0dd5, 0x68a0, 0x68a2,
 	0x689c, 0x689e, 0x6898, 0x689a, 0xa001, 0x918d, 0x1600, 0x6902,
-	0x001e, 0x6837, 0x0020, 0x080c, 0x600e, 0x2079, 0x1c00, 0x7833,
+	0x001e, 0x6837, 0x0020, 0x080c, 0x608e, 0x2079, 0x1c00, 0x7833,
 	0x1101, 0x7837, 0x0000, 0x20e1, 0x0001, 0x2099, 0x1805, 0x20e9,
-	0x0001, 0x20a1, 0x1c0e, 0x20a9, 0x0004, 0x4003, 0x080c, 0xab1a,
+	0x0001, 0x20a1, 0x1c0e, 0x20a9, 0x0004, 0x4003, 0x080c, 0xabfe,
 	0x20e1, 0x0001, 0x2099, 0x1c00, 0x20e9, 0x0000, 0x20a1, 0x0240,
 	0x20a9, 0x0014, 0x4003, 0x60c3, 0x000c, 0x600f, 0x0000, 0x080c,
-	0x5ec0, 0x00fe, 0x9006, 0x7092, 0x6043, 0x0008, 0x6042, 0x0005,
-	0x00f6, 0x7090, 0x7093, 0x0000, 0x9025, 0x0904, 0x58c8, 0x6020,
-	0xd0b4, 0x1904, 0x58c6, 0x71a0, 0x81ff, 0x0904, 0x58b4, 0x9486,
-	0x000c, 0x1904, 0x58c1, 0x9480, 0x0018, 0x8004, 0x20a8, 0x080c,
-	0x6007, 0x2011, 0x0260, 0x2019, 0x1c00, 0x220c, 0x2304, 0x9106,
-	0x11e8, 0x8210, 0x8318, 0x1f04, 0x586d, 0x6043, 0x0004, 0x2061,
+	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,
-	0x5e96, 0x080c, 0x8591, 0x080c, 0x600e, 0x04c0, 0x080c, 0x6007,
+	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, 0x6007, 0x2011, 0x026e, 0x2019, 0x1805, 0x20a9, 0x0004,
+	0x080c, 0x6087, 0x2011, 0x026e, 0x2019, 0x1805, 0x20a9, 0x0004,
 	0x220c, 0x2304, 0x9102, 0x0230, 0x11a0, 0x8210, 0x8318, 0x1f04,
-	0x58a8, 0x0078, 0x70a3, 0x0000, 0x080c, 0x6007, 0x20e1, 0x0000,
+	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,
-	0xab1a, 0x20e1, 0x0001, 0x2099, 0x1c00, 0x20e9, 0x0000, 0x20a1,
+	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, 0xa286, 0x08d8, 0x0005, 0x7098, 0x908a, 0x001d, 0x1a0c,
-	0x0dd5, 0x000b, 0x0005, 0x591d, 0x5930, 0x5959, 0x5979, 0x599f,
-	0x59ce, 0x59f4, 0x5a2c, 0x5a52, 0x5a80, 0x5abb, 0x5af3, 0x5b11,
-	0x5b3c, 0x5b5e, 0x5b79, 0x5b83, 0x5bb7, 0x5bdd, 0x5c0c, 0x5c32,
-	0x5c6a, 0x5cae, 0x5ceb, 0x5d0c, 0x5d65, 0x5d87, 0x5db5, 0x5db5,
+	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, 0x5e96, 0x080c, 0x8591, 0x0005,
+	0x0001, 0x2009, 0x07d0, 0x2011, 0x5f16, 0x080c, 0x8648, 0x0005,
 	0x00f6, 0x7090, 0x9086, 0x0014, 0x1510, 0x6042, 0x6020, 0xd0b4,
-	0x11f0, 0x080c, 0x6007, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1102,
+	0x11f0, 0x080c, 0x6087, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1102,
 	0x11a0, 0x7834, 0x9005, 0x1188, 0x7a38, 0xd2fc, 0x0128, 0x70c4,
-	0x9005, 0x1110, 0x70c7, 0x0001, 0x2011, 0x5e96, 0x080c, 0x84f9,
-	0x709b, 0x0010, 0x080c, 0x5b83, 0x0010, 0x7093, 0x0000, 0x00fe,
-	0x0005, 0x00f6, 0x709b, 0x0003, 0x6043, 0x0004, 0x2011, 0x5e96,
-	0x080c, 0x84f9, 0x080c, 0x5f8b, 0x2079, 0x0240, 0x7833, 0x1102,
+	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, 0x596e, 0x60c3, 0x0014, 0x080c, 0x5ec0, 0x00fe,
-	0x0005, 0x00f6, 0x7090, 0x9005, 0x0500, 0x2011, 0x5e96, 0x080c,
-	0x84f9, 0x9086, 0x0014, 0x11b8, 0x080c, 0x6007, 0x2079, 0x0260,
+	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, 0x5fe3, 0x00fe, 0x0005, 0x00f6,
-	0x709b, 0x0005, 0x080c, 0x5f8b, 0x2079, 0x0240, 0x7833, 0x1103,
-	0x7837, 0x0000, 0x080c, 0x6007, 0x080c, 0x5fea, 0x1170, 0x7084,
+	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, 0x5e43, 0x0168, 0x080c, 0x5fc0, 0x20a9, 0x0008, 0x20e1,
+	0x080c, 0x5ec3, 0x0168, 0x080c, 0x6040, 0x20a9, 0x0008, 0x20e1,
 	0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003,
-	0x60c3, 0x0014, 0x080c, 0x5ec0, 0x00fe, 0x0005, 0x00f6, 0x7090,
-	0x9005, 0x0500, 0x2011, 0x5e96, 0x080c, 0x84f9, 0x9086, 0x0014,
-	0x11b8, 0x080c, 0x6007, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1103,
+	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, 0x5fe3, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x0007, 0x080c,
-	0x5f8b, 0x2079, 0x0240, 0x7833, 0x1104, 0x7837, 0x0000, 0x080c,
-	0x6007, 0x080c, 0x5fea, 0x11b8, 0x7084, 0x9005, 0x11a0, 0x7164,
-	0x9186, 0xffff, 0x0180, 0x9180, 0x3332, 0x200d, 0x918c, 0xff00,
-	0x810f, 0x2011, 0x0008, 0x080c, 0x5e43, 0x0180, 0x080c, 0x4ff4,
-	0x0110, 0x080c, 0x28b4, 0x20a9, 0x0008, 0x20e1, 0x0000, 0x2099,
+	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, 0x5ec0, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, 0x0500,
-	0x2011, 0x5e96, 0x080c, 0x84f9, 0x9086, 0x0014, 0x11b8, 0x080c,
-	0x6007, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1104, 0x1178, 0x7834,
+	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, 0x5fe3,
-	0x00fe, 0x0005, 0x00f6, 0x709b, 0x0009, 0x080c, 0x5f8b, 0x2079,
-	0x0240, 0x7833, 0x1105, 0x7837, 0x0100, 0x080c, 0x5fea, 0x1150,
-	0x7084, 0x9005, 0x1138, 0x080c, 0x5db6, 0x1188, 0x9085, 0x0001,
-	0x080c, 0x28b4, 0x20a9, 0x0008, 0x080c, 0x6007, 0x20e1, 0x0000,
+	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,
 	0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3,
-	0x0014, 0x080c, 0x5ec0, 0x0010, 0x080c, 0x5910, 0x00fe, 0x0005,
-	0x00f6, 0x7090, 0x9005, 0x05a8, 0x2011, 0x5e96, 0x080c, 0x84f9,
-	0x9086, 0x0014, 0x1560, 0x080c, 0x6007, 0x2079, 0x0260, 0x7a30,
+	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, 0x5b5e, 0x0010, 0x080c,
-	0x5fe3, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x000b, 0x2011, 0x1c0e,
+	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, 0x5f8b, 0x2079, 0x0240, 0x7833, 0x1106, 0x7837, 0x0000,
-	0x080c, 0x5fea, 0x0118, 0x2013, 0x0000, 0x0020, 0x7060, 0x9085,
+	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, 0x5ae0, 0x60c3, 0x0084, 0x080c,
-	0x5ec0, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, 0x01c0, 0x2011,
-	0x5e96, 0x080c, 0x84f9, 0x9086, 0x0084, 0x1178, 0x080c, 0x6007,
+	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, 0x5fe3, 0x00fe,
-	0x0005, 0x00f6, 0x709b, 0x000d, 0x080c, 0x5f8b, 0x2079, 0x0240,
-	0x7833, 0x1107, 0x7837, 0x0000, 0x080c, 0x6007, 0x20a9, 0x0040,
+	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, 0x5b24, 0x60c3, 0x0084,
-	0x080c, 0x5ec0, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, 0x01e0,
-	0x2011, 0x5e96, 0x080c, 0x84f9, 0x9086, 0x0084, 0x1198, 0x080c,
-	0x6007, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1107, 0x1158, 0x7834,
-	0x9005, 0x1140, 0x7097, 0x0001, 0x080c, 0x5f5d, 0x709b, 0x000e,
-	0x0029, 0x0010, 0x080c, 0x5fe3, 0x00fe, 0x0005, 0x918d, 0x0001,
-	0x080c, 0x6032, 0x709b, 0x000f, 0x7093, 0x0000, 0x2061, 0x0140,
+	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, 0x5e96, 0x080c, 0x84ed,
-	0x0005, 0x7090, 0x9005, 0x0130, 0x2011, 0x5e96, 0x080c, 0x84f9,
-	0x709b, 0x0000, 0x0005, 0x709b, 0x0011, 0x080c, 0xab1a, 0x080c,
-	0x6007, 0x20e1, 0x0000, 0x2099, 0x0260, 0x20e9, 0x0000, 0x20a1,
+	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,
 	0x0240, 0x7490, 0x9480, 0x0018, 0x9080, 0x0007, 0x9084, 0x03f8,
-	0x8004, 0x20a8, 0x4003, 0x080c, 0x5fea, 0x11a0, 0x717c, 0x81ff,
-	0x0188, 0x900e, 0x7080, 0x9084, 0x00ff, 0x0160, 0x080c, 0x284b,
+	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, 0x5e43, 0x60c3, 0x0014, 0x080c, 0x5ec0, 0x0005, 0x00f6,
-	0x7090, 0x9005, 0x0500, 0x2011, 0x5e96, 0x080c, 0x84f9, 0x9086,
-	0x0014, 0x11b8, 0x080c, 0x6007, 0x2079, 0x0260, 0x7a30, 0x9296,
+	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, 0x5f99, 0x2079, 0x0240, 0x7833, 0x1103, 0x7837, 0x0000,
-	0x080c, 0x6007, 0x080c, 0x5fea, 0x1170, 0x7084, 0x9005, 0x1158,
-	0x715c, 0x9186, 0xffff, 0x0138, 0x2011, 0x0008, 0x080c, 0x5e43,
-	0x0168, 0x080c, 0x5fc0, 0x20a9, 0x0008, 0x20e1, 0x0000, 0x2099,
+	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, 0x5ec0, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, 0x0500,
-	0x2011, 0x5e96, 0x080c, 0x84f9, 0x9086, 0x0014, 0x11b8, 0x080c,
-	0x6007, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1104, 0x1178, 0x7834,
+	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, 0x5f99, 0x2079,
-	0x0240, 0x7833, 0x1104, 0x7837, 0x0000, 0x080c, 0x6007, 0x080c,
-	0x5fea, 0x11b8, 0x7084, 0x9005, 0x11a0, 0x7164, 0x9186, 0xffff,
-	0x0180, 0x9180, 0x3332, 0x200d, 0x918c, 0xff00, 0x810f, 0x2011,
-	0x0008, 0x080c, 0x5e43, 0x0180, 0x080c, 0x4ff4, 0x0110, 0x080c,
-	0x28b4, 0x20a9, 0x0008, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9,
-	0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x5ec0,
-	0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, 0x05f0, 0x2011, 0x5e96,
-	0x080c, 0x84f9, 0x9086, 0x0014, 0x15a8, 0x080c, 0x6007, 0x2079,
+	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, 0x6032,
+	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, 0x6032, 0x7097,
+	0x1110, 0x70c7, 0x0001, 0x9085, 0x0001, 0x080c, 0x60b2, 0x7097,
 	0x0000, 0x7a38, 0xd2f4, 0x0110, 0x70df, 0x0008, 0x709b, 0x0016,
-	0x0029, 0x0010, 0x7093, 0x0000, 0x00fe, 0x0005, 0x080c, 0xab1a,
-	0x080c, 0x6007, 0x20e1, 0x0000, 0x2099, 0x0260, 0x20e9, 0x0000,
+	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, 0x5fea, 0x1150, 0x7084, 0x9005, 0x1138, 0x080c,
-	0x5db6, 0x1188, 0x9085, 0x0001, 0x080c, 0x28b4, 0x20a9, 0x0008,
-	0x080c, 0x6007, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000,
-	0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x5ec0, 0x0010,
-	0x080c, 0x5910, 0x0005, 0x00f6, 0x7090, 0x9005, 0x01d8, 0x2011,
-	0x5e96, 0x080c, 0x84f9, 0x9086, 0x0084, 0x1190, 0x080c, 0x6007,
+	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, 0x6032, 0x709b, 0x0018, 0x0029, 0x0010,
+	0x1138, 0x9006, 0x080c, 0x60b2, 0x709b, 0x0018, 0x0029, 0x0010,
 	0x7093, 0x0000, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x0019, 0x080c,
-	0x5f99, 0x2079, 0x0240, 0x7833, 0x1106, 0x7837, 0x0000, 0x080c,
-	0x6007, 0x2009, 0x026e, 0x2039, 0x1c0e, 0x20a9, 0x0040, 0x213e,
+	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, 0x5d1f, 0x2039, 0x1c0e, 0x080c, 0x5fea,
+	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, 0x5d52, 0x60c3,
-	0x0084, 0x080c, 0x5ec0, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005,
-	0x01e0, 0x2011, 0x5e96, 0x080c, 0x84f9, 0x9086, 0x0084, 0x1198,
-	0x080c, 0x6007, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1107, 0x1158,
-	0x7834, 0x9005, 0x1140, 0x7097, 0x0001, 0x080c, 0x5f5d, 0x709b,
+	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, 0x6032, 0x709b, 0x001b, 0x080c, 0xab1a, 0x080c,
-	0x6007, 0x2011, 0x0260, 0x2009, 0x0240, 0x7490, 0x9480, 0x0018,
+	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, 0x5d9e,
-	0x60c3, 0x0084, 0x080c, 0x5ec0, 0x0005, 0x0005, 0x0086, 0x0096,
+	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, 0x6007, 0x20e1, 0x0000, 0x2099, 0x026e,
+	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, 0x5dd0, 0x0804, 0x5e3f, 0x82ff,
+	0x8210, 0x0008, 0x8211, 0x1f04, 0x5e50, 0x0804, 0x5ebf, 0x82ff,
 	0x1160, 0xd5d4, 0x0120, 0x91a6, 0x3fff, 0x0d90, 0x0020, 0x91a6,
-	0x3fff, 0x0904, 0x5e3f, 0x918d, 0xc000, 0x20a9, 0x0010, 0x2019,
+	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, 0x5df6, 0x04d8, 0x23a8, 0x2021, 0x0001, 0x8426,
-	0x8425, 0x1f04, 0x5e08, 0x2328, 0x8529, 0x92be, 0x0007, 0x0158,
+	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, 0x5e17, 0x755e, 0x95c8, 0x3332, 0x292d, 0x95ac,
-	0x00ff, 0x7582, 0x6532, 0x6536, 0x0016, 0x2508, 0x080c, 0x2894,
+	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,
@@ -2817,52 +2833,52 @@
 	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, 0x3332, 0x242d, 0x95ac, 0x00ff, 0x7582,
-	0x6532, 0x6536, 0x0016, 0x2508, 0x080c, 0x2894, 0x001e, 0x60e7,
+	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, 0x5f4c, 0x080c, 0xa28f,
-	0x7004, 0x9084, 0x4000, 0x0110, 0x080c, 0x2d0c, 0x0126, 0x2091,
+	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, 0x5fa9, 0x001e, 0x9094, 0x0010, 0x9285,
+	0x2009, 0x00f7, 0x080c, 0x6029, 0x001e, 0x9094, 0x0010, 0x9285,
 	0x0080, 0x7842, 0x7a42, 0x002e, 0x012e, 0x00fe, 0x00ee, 0x0005,
-	0x0126, 0x2091, 0x8000, 0x080c, 0x2bb2, 0x0228, 0x2011, 0x0101,
+	0x0126, 0x2091, 0x8000, 0x080c, 0x2be3, 0x0228, 0x2011, 0x0101,
 	0x2204, 0xc0c5, 0x2012, 0x2011, 0x19f0, 0x2013, 0x0000, 0x7093,
-	0x0000, 0x012e, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x080c, 0xa286,
+	0x0000, 0x012e, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x080c, 0xa34d,
 	0x6144, 0xd184, 0x0120, 0x7198, 0x918d, 0x2000, 0x0018, 0x718c,
 	0x918d, 0x1000, 0x2011, 0x1998, 0x2112, 0x2009, 0x07d0, 0x2011,
-	0x5e96, 0x080c, 0x8591, 0x0005, 0x0016, 0x0026, 0x00c6, 0x0126,
-	0x2091, 0x8000, 0x080c, 0xadd0, 0x2009, 0x00f7, 0x080c, 0x5fa9,
+	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,
-	0x5f18, 0x080c, 0x84ed, 0x012e, 0x00ce, 0x002e, 0x001e, 0x0005,
+	0x5f98, 0x080c, 0x85a4, 0x012e, 0x00ce, 0x002e, 0x001e, 0x0005,
 	0x00e6, 0x0006, 0x0126, 0x2091, 0x8000, 0x0471, 0x2071, 0x0100,
-	0x080c, 0xa28f, 0x2071, 0x0140, 0x7004, 0x9084, 0x4000, 0x0110,
-	0x080c, 0x2d0c, 0x080c, 0x73bb, 0x0188, 0x080c, 0x73d6, 0x1170,
-	0x080c, 0x76a3, 0x0016, 0x080c, 0x2963, 0x2001, 0x196c, 0x2102,
-	0x001e, 0x080c, 0x769e, 0x080c, 0x72e5, 0x0050, 0x2009, 0x0001,
-	0x080c, 0x2c4b, 0x2001, 0x0001, 0x080c, 0x27f7, 0x080c, 0x5eec,
+	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, 0x4b1e, 0x003e, 0x002e, 0x0005, 0x20a9, 0x0012, 0x20e9,
-	0x0001, 0x20a1, 0x1c80, 0x080c, 0x6007, 0x20e9, 0x0000, 0x2099,
-	0x026e, 0x0099, 0x20a9, 0x0020, 0x080c, 0x6001, 0x2099, 0x0260,
-	0x20a1, 0x1c92, 0x0051, 0x20a9, 0x000e, 0x080c, 0x6004, 0x2099,
+	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, 0x5f81,
-	0x002e, 0x001e, 0x0005, 0x080c, 0xab1a, 0x20e1, 0x0001, 0x2099,
+	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, 0xab1a, 0x080c, 0x6007, 0x20e1, 0x0000, 0x2099,
+	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, 0x6985, 0x0158, 0x9006, 0x2020, 0x2009,
-	0x002a, 0x080c, 0xe5e9, 0x2001, 0x180c, 0x200c, 0xc195, 0x2102,
-	0x2019, 0x002a, 0x900e, 0x080c, 0x3197, 0x080c, 0xd25a, 0x0140,
-	0x0036, 0x2019, 0xffff, 0x2021, 0x0007, 0x080c, 0x4cd5, 0x003e,
-	0x004e, 0x001e, 0x0005, 0x080c, 0x5eec, 0x709b, 0x0000, 0x7093,
+	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,
@@ -2874,11 +2890,11 @@
 	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, 0x6041, 0x015e, 0x0005, 0x00d6,
+	0x9006, 0x200a, 0x8108, 0x1f04, 0x60c1, 0x015e, 0x0005, 0x00d6,
 	0x0036, 0x0156, 0x0136, 0x0146, 0x2069, 0x1847, 0x9006, 0xb802,
-	0xb8ce, 0xb807, 0x0707, 0xb80a, 0xb80e, 0xb812, 0x9198, 0x3332,
+	0xb8ce, 0xb807, 0x0707, 0xb80a, 0xb80e, 0xb812, 0x9198, 0x3384,
 	0x231d, 0x939c, 0x00ff, 0xbb16, 0x0016, 0x0026, 0xb8c2, 0x080c,
-	0xadc9, 0x1120, 0x9192, 0x007e, 0x1208, 0xbbc2, 0x20a9, 0x0004,
+	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,
@@ -2888,17 +2904,17 @@
 	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, 0x8987, 0x00ce, 0x090c, 0x8d2d, 0xb8af, 0x0000, 0x6814,
+	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, 0x612f, 0x9182, 0x0800, 0x1a04, 0x6133,
-	0x2001, 0x180c, 0x2004, 0x9084, 0x0003, 0x1904, 0x6139, 0x9188,
+	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, 0x614b, 0xb850, 0x900d,
-	0x1148, 0xa802, 0x2900, 0xb852, 0xb84e, 0x080c, 0x9115, 0x9006,
+	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, 0xadc9,
+	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,
@@ -2906,3125 +2922,3138 @@
 	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, 0x6989, 0x1990, 0xb800, 0xd0bc,
-	0x0978, 0x0804, 0x60e2, 0x080c, 0x67b2, 0x0904, 0x60fb, 0x0804,
-	0x60e6, 0x00b6, 0x00e6, 0x0126, 0x2091, 0x8000, 0xa874, 0x908e,
+	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,
-	0x6929, 0x11d0, 0x080c, 0xae09, 0x0570, 0x2b00, 0x6012, 0x2900,
+	0x69ac, 0x11d0, 0x080c, 0xaeed, 0x0570, 0x2b00, 0x6012, 0x2900,
 	0x6016, 0x6023, 0x0009, 0x600b, 0x0000, 0xa874, 0x908e, 0x00ff,
-	0x1110, 0x600b, 0x8000, 0x2009, 0x0043, 0x080c, 0xaeda, 0x9006,
+	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, 0x6219,
-	0x9188, 0x1000, 0x2104, 0x905d, 0x0904, 0x61f1, 0xb8a0, 0x9086,
-	0x007f, 0x0178, 0x080c, 0x6991, 0x0160, 0xa994, 0x81ff, 0x0130,
-	0x908e, 0x0004, 0x0130, 0x908e, 0x0005, 0x0118, 0x080c, 0x6989,
-	0x1598, 0xa87c, 0xd0fc, 0x01e0, 0xa894, 0x9005, 0x01c8, 0x2060,
-	0x0026, 0x2010, 0x080c, 0xcb48, 0x002e, 0x1120, 0x2001, 0x0008,
-	0x0804, 0x621b, 0x6020, 0x9086, 0x000a, 0x0120, 0x2001, 0x0008,
-	0x0804, 0x621b, 0x601a, 0x6003, 0x0008, 0x2900, 0x6016, 0x0058,
-	0x080c, 0xae09, 0x05e8, 0x2b00, 0x6012, 0x2900, 0x6016, 0x600b,
-	0xffff, 0x6023, 0x000a, 0x2009, 0x0003, 0x080c, 0xaeda, 0x9006,
-	0x0458, 0x2001, 0x0028, 0x0438, 0x9082, 0x0006, 0x1290, 0x080c,
-	0xadc9, 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, 0x62b0, 0x626b, 0x6282, 0x62b0, 0x62b0,
-	0x62b0, 0x62b0, 0x62b0, 0x2100, 0x9082, 0x007e, 0x1278, 0x080c,
-	0x65b5, 0x0148, 0x9046, 0xb810, 0x9306, 0x1904, 0x62b8, 0xb814,
-	0x9206, 0x15f0, 0x0028, 0xbb12, 0xba16, 0x0010, 0x080c, 0x49d1,
-	0x0150, 0x04b0, 0x080c, 0x6616, 0x1598, 0xb810, 0x9306, 0x1580,
-	0xb814, 0x9206, 0x1568, 0x080c, 0xae09, 0x0530, 0x2b00, 0x6012,
-	0x080c, 0xcfd4, 0x2900, 0x6016, 0x600b, 0xffff, 0x6023, 0x000a,
-	0xa878, 0x9086, 0x0001, 0x1170, 0x080c, 0x31cc, 0x9006, 0x080c,
-	0x6552, 0x2001, 0x0002, 0x080c, 0x6566, 0x2001, 0x0200, 0xb86e,
-	0xb893, 0x0002, 0x2009, 0x0003, 0x080c, 0xaeda, 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, 0x64a3, 0x90c6, 0x0056, 0x0904, 0x64a7,
-	0x90c6, 0x0066, 0x0904, 0x64ab, 0x90c6, 0x0067, 0x0904, 0x64af,
-	0x90c6, 0x0068, 0x0904, 0x64b3, 0x90c6, 0x0071, 0x0904, 0x64b7,
-	0x90c6, 0x0074, 0x0904, 0x64bb, 0x90c6, 0x007c, 0x0904, 0x64bf,
-	0x90c6, 0x007e, 0x0904, 0x64c3, 0x90c6, 0x0037, 0x0904, 0x64c7,
-	0x9016, 0x2079, 0x1800, 0xa974, 0x9186, 0x00ff, 0x0904, 0x649e,
-	0x9182, 0x0800, 0x1a04, 0x649e, 0x080c, 0x6616, 0x1198, 0xb804,
-	0x9084, 0x00ff, 0x9082, 0x0006, 0x1268, 0xa894, 0x90c6, 0x006f,
-	0x0148, 0x080c, 0xadc9, 0x1904, 0x6487, 0xb8a0, 0x9084, 0xff80,
-	0x1904, 0x6487, 0xa894, 0x90c6, 0x006f, 0x0158, 0x90c6, 0x005e,
-	0x0904, 0x63e7, 0x90c6, 0x0064, 0x0904, 0x6410, 0x2008, 0x0804,
-	0x63a9, 0xa998, 0xa8b0, 0x2040, 0x080c, 0xadc9, 0x1120, 0x9182,
-	0x007f, 0x0a04, 0x63a9, 0x9186, 0x00ff, 0x0904, 0x63a9, 0x9182,
-	0x0800, 0x1a04, 0x63a9, 0xaaa0, 0xab9c, 0x787c, 0x9306, 0x11a8,
-	0x7880, 0x0096, 0x924e, 0x1128, 0x2208, 0x2310, 0x009e, 0x0804,
-	0x63a9, 0x080c, 0xadc9, 0x1140, 0x99cc, 0xff00, 0x009e, 0x1128,
-	0x2208, 0x2310, 0x0804, 0x63a9, 0x009e, 0x080c, 0x49d1, 0x0904,
-	0x63b3, 0x900e, 0x9016, 0x90c6, 0x4000, 0x15e0, 0x0006, 0x080c,
-	0x6836, 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, 0xae09, 0x1130, 0x2001, 0x4005,
-	0x2009, 0x0003, 0x9016, 0x0c78, 0x2b00, 0x6012, 0x080c, 0xcfd4,
-	0x2900, 0x6016, 0x6023, 0x0001, 0xa868, 0xd88c, 0x0108, 0xc0f5,
-	0xa86a, 0x0126, 0x2091, 0x8000, 0x080c, 0x31cc, 0x012e, 0x9006,
-	0x080c, 0x6552, 0x2001, 0x0002, 0x080c, 0x6566, 0x2009, 0x0002,
-	0x080c, 0xaeda, 0xa8b0, 0xd094, 0x0118, 0xb8cc, 0xc08d, 0xb8ce,
-	0x9006, 0x9005, 0x012e, 0x00ee, 0x00fe, 0x00be, 0x0005, 0x080c,
-	0x56f6, 0x0118, 0x2009, 0x0007, 0x00f8, 0xa998, 0xaeb0, 0x080c,
-	0x6616, 0x1904, 0x63a4, 0x9186, 0x007f, 0x0130, 0x080c, 0x6989,
-	0x0118, 0x2009, 0x0009, 0x0080, 0x0096, 0x080c, 0x0fff, 0x1120,
-	0x009e, 0x2009, 0x0002, 0x0040, 0x2900, 0x009e, 0xa806, 0x080c,
-	0xcd40, 0x19b0, 0x2009, 0x0003, 0x2001, 0x4005, 0x0804, 0x63ab,
-	0xa998, 0xaeb0, 0x080c, 0x6616, 0x1904, 0x63a4, 0x0096, 0x080c,
-	0x0fff, 0x1128, 0x009e, 0x2009, 0x0002, 0x0804, 0x6464, 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, 0x56e2, 0xd0b4,
-	0x1118, 0xa89b, 0x000b, 0x00e0, 0xb800, 0xd08c, 0x0118, 0xa89b,
-	0x000c, 0x00b0, 0x080c, 0x6989, 0x0118, 0xa89b, 0x0009, 0x0080,
-	0x080c, 0x56f6, 0x0118, 0xa89b, 0x0007, 0x0050, 0x080c, 0xcd23,
-	0x1904, 0x63e0, 0x2009, 0x0003, 0x2001, 0x4005, 0x0804, 0x63ab,
-	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, 0xb379, 0x1904, 0x63e0, 0x2009, 0x0002, 0x08e8, 0x2001,
-	0x0028, 0x900e, 0x0804, 0x63e1, 0x2009, 0x180c, 0x210c, 0xd18c,
-	0x0118, 0x2001, 0x0004, 0x0038, 0xd184, 0x0118, 0x2001, 0x0004,
-	0x0010, 0x2001, 0x0029, 0x900e, 0x0804, 0x63e1, 0x2001, 0x0029,
-	0x900e, 0x0804, 0x63e1, 0x080c, 0x3761, 0x0804, 0x63e2, 0x080c,
-	0x541f, 0x0804, 0x63e2, 0x080c, 0x455f, 0x0804, 0x63e2, 0x080c,
-	0x45d8, 0x0804, 0x63e2, 0x080c, 0x4634, 0x0804, 0x63e2, 0x080c,
-	0x4a94, 0x0804, 0x63e2, 0x080c, 0x4d44, 0x0804, 0x63e2, 0x080c,
-	0x508a, 0x0804, 0x63e2, 0x080c, 0x5283, 0x0804, 0x63e2, 0x080c,
-	0x3977, 0x0804, 0x63e2, 0x00b6, 0xa974, 0xae78, 0x9684, 0x3fff,
-	0x9082, 0x4000, 0x1618, 0x9182, 0x0800, 0x1268, 0x9188, 0x1000,
-	0x2104, 0x905d, 0x0140, 0x080c, 0x6989, 0x1148, 0x00e9, 0x080c,
-	0x6741, 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,
+	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, 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, 0x6985, 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, 0x2091, 0x8000, 0x6210,
-	0x2258, 0xba04, 0x0006, 0x9086, 0x0006, 0x1168, 0xb89c, 0xd0a4,
-	0x0150, 0x080c, 0x6981, 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, 0x6047, 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, 0xcb5a, 0x0110,
-	0x080c, 0x0fb1, 0x080c, 0xae5f, 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,
-	0x73b3, 0x1510, 0xb8a0, 0x9086, 0x007e, 0x0120, 0x080c, 0xadc9,
-	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, 0x67d2, 0xa807, 0x0001, 0xae12, 0x9085,
-	0x0001, 0x012e, 0x009e, 0x0005, 0x9006, 0x0cd8, 0x0126, 0x2091,
-	0x8000, 0x0096, 0xb8a4, 0x904d, 0x0188, 0xa800, 0x9005, 0x1150,
-	0x080c, 0x67e1, 0x1158, 0xa804, 0x908a, 0x0002, 0x0218, 0x8001,
-	0xa806, 0x0020, 0x080c, 0x1031, 0xb8a7, 0x0000, 0x009e, 0x012e,
-	0x0005, 0x0126, 0x2091, 0x8000, 0x080c, 0x9115, 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,
-	0xa67d, 0xaa00, 0xb84c, 0x9906, 0x1110, 0xba4e, 0x0020, 0x00a6,
-	0x2150, 0xb202, 0x00ae, 0x82ff, 0x1110, 0xb952, 0x89ff, 0x012e,
-	0x0005, 0x9016, 0x0489, 0x1110, 0x2011, 0x0001, 0x0005, 0x080c,
-	0x6836, 0x0128, 0x080c, 0xcc17, 0x0010, 0x9085, 0x0001, 0x0005,
-	0x080c, 0x6836, 0x0128, 0x080c, 0xcbbc, 0x0010, 0x9085, 0x0001,
-	0x0005, 0x080c, 0x6836, 0x0128, 0x080c, 0xcc14, 0x0010, 0x9085,
-	0x0001, 0x0005, 0x080c, 0x6836, 0x0128, 0x080c, 0xcbdb, 0x0010,
-	0x9085, 0x0001, 0x0005, 0x080c, 0x6836, 0x0128, 0x080c, 0xcc58,
-	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, 0x67d2, 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, 0x73b3, 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, 0x6616,
-	0x1168, 0xb804, 0x9084, 0xff00, 0x8007, 0x9096, 0x0004, 0x0118,
-	0x9086, 0x0006, 0x1118, 0xb800, 0xc0ed, 0xb802, 0x001e, 0x8108,
-	0x1f04, 0x685d, 0x015e, 0x080c, 0x6947, 0x0120, 0x2001, 0x1984,
-	0x200c, 0x0038, 0x2079, 0x1847, 0x7804, 0xd0a4, 0x0130, 0x2009,
-	0x07d0, 0x2011, 0x6888, 0x080c, 0x8591, 0x00fe, 0x00be, 0x0005,
-	0x00b6, 0x2011, 0x6888, 0x080c, 0x84f9, 0x080c, 0x6947, 0x01d8,
-	0x2001, 0x107e, 0x2004, 0x2058, 0xb900, 0xc1ec, 0xb902, 0x080c,
-	0x6985, 0x0130, 0x2009, 0x07d0, 0x2011, 0x6888, 0x080c, 0x8591,
-	0x00e6, 0x2071, 0x1800, 0x9006, 0x707e, 0x7060, 0x7082, 0x080c,
-	0x2fa3, 0x00ee, 0x04b0, 0x0156, 0x00c6, 0x20a9, 0x007f, 0x900e,
-	0x0016, 0x080c, 0x6616, 0x1538, 0xb800, 0xd0ec, 0x0520, 0x0046,
-	0xbaa0, 0x2220, 0x9006, 0x2009, 0x0029, 0x080c, 0xe5e9, 0xb800,
-	0xc0e5, 0xc0ec, 0xb802, 0x080c, 0x6981, 0x2001, 0x0707, 0x1128,
-	0xb804, 0x9084, 0x00ff, 0x9085, 0x0700, 0xb806, 0x2019, 0x0029,
-	0x080c, 0x929d, 0x0076, 0x903e, 0x080c, 0x9170, 0x900e, 0x080c,
-	0xe326, 0x007e, 0x004e, 0x001e, 0x8108, 0x1f04, 0x68b0, 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, 0x908c, 0xffc0, 0xb9ca,
-	0xb8af, 0x0000, 0x2009, 0x00ff, 0x080c, 0x6047, 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, 0xb800, 0x00be, 0xd0bc,
-	0x0005, 0x0006, 0x0016, 0x0026, 0xb804, 0x908c, 0x00ff, 0x9196,
-	0x0006, 0x0188, 0x9196, 0x0004, 0x0170, 0x9196, 0x0005, 0x0158,
-	0x908c, 0xff00, 0x810f, 0x9196, 0x0006, 0x0128, 0x9196, 0x0004,
-	0x0110, 0x9196, 0x0005, 0x002e, 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, 0x0dd5, 0x000e,
-	0xba00, 0x9005, 0x0110, 0xc2fd, 0x0008, 0xc2fc, 0xba02, 0x002e,
-	0x012e, 0x0005, 0x2011, 0x1837, 0x2204, 0xd0cc, 0x0138, 0x2001,
-	0x1982, 0x200c, 0x2011, 0x6977, 0x080c, 0x8591, 0x0005, 0x2011,
-	0x6977, 0x080c, 0x84f9, 0x2011, 0x1837, 0x2204, 0xc0cc, 0x2012,
-	0x0005, 0x080c, 0x56e2, 0xd0ac, 0x0005, 0x080c, 0x56e2, 0xd0a4,
-	0x0005, 0x0016, 0xb904, 0x9184, 0x00ff, 0x908e, 0x0006, 0x001e,
-	0x0005, 0x0016, 0xb904, 0x9184, 0xff00, 0x8007, 0x908e, 0x0006,
-	0x001e, 0x0005, 0x00b6, 0x00f6, 0x080c, 0xd25a, 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, 0x56e2, 0xd0fc, 0x1140, 0x080c, 0x56e2, 0x900e,
-	0xd09c, 0x0108, 0x8108, 0x7102, 0x00f8, 0x2001, 0x1867, 0x200c,
-	0x9184, 0x0007, 0x0002, 0x69c5, 0x69c5, 0x69c5, 0x69c5, 0x69c5,
-	0x69db, 0x69e9, 0x69c5, 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, 0x770b, 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, 0x6c99, 0x9286, 0x0003, 0x0904, 0x6b2f, 0x9286, 0x0005,
-	0x0904, 0x6b2f, 0x2071, 0x1877, 0xa87c, 0x9005, 0x0904, 0x6a90,
-	0x7140, 0xa868, 0x9102, 0x0a04, 0x6c99, 0xa878, 0xd084, 0x15d8,
-	0xa853, 0x0019, 0x2001, 0x8023, 0xa84e, 0x2071, 0x1910, 0x701c,
-	0x9005, 0x1904, 0x6e2f, 0x0e04, 0x6e9d, 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, 0x6b12, 0xa853, 0x001b, 0x2001, 0x8027, 0x0820,
-	0x7004, 0xd08c, 0x1904, 0x6c99, 0xa853, 0x001a, 0x2001, 0x8024,
-	0x0804, 0x6a54, 0x00e6, 0x0026, 0x2071, 0x1947, 0x7000, 0x9015,
-	0x0904, 0x6c99, 0x9286, 0x0003, 0x0904, 0x6b2f, 0x9286, 0x0005,
-	0x0904, 0x6b2f, 0xa84f, 0x8022, 0xa853, 0x0018, 0x0804, 0x6af7,
-	0xa868, 0xd0fc, 0x11d8, 0x00e6, 0x0026, 0x2001, 0x1947, 0x2004,
-	0x9005, 0x0904, 0x6c99, 0xa87c, 0xd0bc, 0x1904, 0x6c99, 0xa978,
-	0xa874, 0x9105, 0x1904, 0x6c99, 0x2001, 0x1947, 0x2004, 0x0002,
-	0x6c99, 0x6af3, 0x6b2f, 0x6b2f, 0x6c99, 0x6b2f, 0x0005, 0xa868,
-	0xd0fc, 0x1500, 0x00e6, 0x0026, 0x2009, 0x1947, 0x210c, 0x81ff,
-	0x0904, 0x6c99, 0xa87c, 0xd0cc, 0x0904, 0x6c99, 0xa880, 0x9084,
-	0x00ff, 0x9086, 0x0001, 0x1904, 0x6c99, 0x9186, 0x0003, 0x0904,
-	0x6b2f, 0x9186, 0x0005, 0x0904, 0x6b2f, 0xa84f, 0x8021, 0xa853,
-	0x0017, 0x0028, 0x0005, 0xa84f, 0x8020, 0xa853, 0x0016, 0x2071,
-	0x1910, 0x701c, 0x9005, 0x1904, 0x6e2f, 0x0e04, 0x6e9d, 0x2071,
-	0x0000, 0xa84c, 0x7082, 0xa850, 0x7032, 0xa86c, 0x7086, 0x7036,
-	0xa870, 0x708a, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084,
-	0x190c, 0x119b, 0x2071, 0x1800, 0x2011, 0x0001, 0xa804, 0x900d,
-	0x702c, 0x1158, 0xa802, 0x2900, 0x702e, 0x70c0, 0x9200, 0x70c2,
-	0x080c, 0x841a, 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, 0x6c1e, 0x782c, 0x908c, 0x0780, 0x190c,
-	0x6fe9, 0x8004, 0x8004, 0x8004, 0x9084, 0x0003, 0x0002, 0x6b4d,
-	0x6c1e, 0x6b72, 0x6bb9, 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,
-	0x841a, 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, 0x841a, 0x782c, 0x9094, 0x0780, 0x190c,
-	0x6fe9, 0xd0a4, 0x19f0, 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, 0x841a,
-	0x0800, 0x0096, 0x00e6, 0x7824, 0x2048, 0x2071, 0x1800, 0x702c,
-	0xa802, 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, 0x841a,
-	0x782c, 0x9094, 0x0780, 0x190c, 0x6fe9, 0xd0a4, 0x1d60, 0x00ee,
-	0x782c, 0x9094, 0x0780, 0x190c, 0x6fe9, 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, 0x841a, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x2908, 0x7010,
-	0x8000, 0x7012, 0x7018, 0x904d, 0x711a, 0x0110, 0xa902, 0x0008,
-	0x711e, 0x2148, 0xa804, 0x900d, 0x1904, 0x6c73, 0x782c, 0x9094,
-	0x0780, 0x190c, 0x6fe9, 0xd09c, 0x1198, 0x701c, 0x904d, 0x0180,
-	0x7010, 0x8001, 0x7012, 0x1108, 0x701a, 0xa800, 0x701e, 0x2900,
-	0x7822, 0x782c, 0x9094, 0x0780, 0x190c, 0x6fe9, 0xd09c, 0x0d68,
-	0x782c, 0x9094, 0x0780, 0x190c, 0x6fe9, 0xd0a4, 0x01b0, 0x00e6,
-	0x7824, 0x2048, 0x2071, 0x1800, 0x702c, 0xa802, 0x2900, 0x702e,
-	0x70c0, 0x8000, 0x70c2, 0x080c, 0x841a, 0x782c, 0x9094, 0x0780,
-	0x190c, 0x6fe9, 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, 0x841a, 0x00ee, 0x0804, 0x6c2e,
-	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, 0x6dad, 0x782c, 0x908c,
-	0x0780, 0x190c, 0x6fe9, 0x8004, 0x8004, 0x8004, 0x9084, 0x0003,
-	0x0002, 0x6cb8, 0x6dad, 0x6cd3, 0x6d40, 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, 0x841a, 0x0c60, 0x2071, 0x1800, 0x2900, 0x7822, 0xa804,
-	0x900d, 0x1904, 0x6d2f, 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,
-	0x841a, 0x782c, 0x9094, 0x0780, 0x190c, 0x6fe9, 0xd0a4, 0x19f0,
-	0x0e04, 0x6d26, 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, 0x00ee, 0x0005, 0x9016,
-	0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8,
-	0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x841a, 0x0804, 0x6ce6,
-	0x0096, 0x00e6, 0x7824, 0x2048, 0x2071, 0x1800, 0x702c, 0xa802,
-	0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, 0x841a, 0x782c,
-	0x9094, 0x0780, 0x190c, 0x6fe9, 0xd0a4, 0x1d60, 0x00ee, 0x0e04,
-	0x6d80, 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, 0x6fe9, 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,
-	0x841a, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x2908, 0x7010, 0x8000,
-	0x7012, 0x7018, 0x904d, 0x711a, 0x0110, 0xa902, 0x0008, 0x711e,
-	0x2148, 0xa804, 0x900d, 0x1904, 0x6e1a, 0x782c, 0x9094, 0x0780,
-	0x190c, 0x6fe9, 0xd09c, 0x11b0, 0x701c, 0x904d, 0x0198, 0xa84c,
-	0x9005, 0x1180, 0x7010, 0x8001, 0x7012, 0x1108, 0x701a, 0xa800,
-	0x701e, 0x2900, 0x7822, 0x782c, 0x9094, 0x0780, 0x190c, 0x6fe9,
-	0xd09c, 0x0d50, 0x782c, 0x9094, 0x0780, 0x190c, 0x6fe9, 0xd0a4,
-	0x05a8, 0x00e6, 0x7824, 0x2048, 0x2071, 0x1800, 0x702c, 0xa802,
-	0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, 0x841a, 0x782c,
-	0x9094, 0x0780, 0x190c, 0x6fe9, 0xd0a4, 0x1d60, 0x00ee, 0x0e04,
-	0x6e13, 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, 0x841a, 0x00ee, 0x0804, 0x6dbd, 0x2071,
-	0x1910, 0xa803, 0x0000, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018,
-	0x904d, 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804,
-	0x900d, 0x1128, 0x1e04, 0x6e5a, 0x002e, 0x00ee, 0x0005, 0x2071,
-	0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900,
-	0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x841a,
-	0x0e04, 0x6e44, 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, 0x119b, 0x2071,
-	0x1910, 0x080c, 0x6fd5, 0x002e, 0x00ee, 0x0005, 0xa850, 0x9082,
-	0x001c, 0x1e68, 0xa880, 0x708e, 0x7036, 0x0146, 0x01d6, 0x0136,
+	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,
+	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,
+	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,
+	0x2058, 0xb800, 0xc0ec, 0xb802, 0x00be, 0x0005, 0x00b6, 0x00c6,
+	0x0096, 0x080c, 0x1018, 0x090c, 0x0dd5, 0x2958, 0x009e, 0x2001,
+	0x196a, 0x2b02, 0x8b07, 0x8006, 0x8006, 0x908c, 0x003f, 0xb9c6,
+	0x908c, 0xffc0, 0xb9ca, 0xb8af, 0x0000, 0x2009, 0x00ff, 0x080c,
+	0x60c7, 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,
+	0xb800, 0x00be, 0xd0bc, 0x0005, 0x0006, 0x0016, 0x0026, 0xb804,
+	0x908c, 0x00ff, 0x9196, 0x0006, 0x0188, 0x9196, 0x0004, 0x0170,
+	0x9196, 0x0005, 0x0158, 0x908c, 0xff00, 0x810f, 0x9196, 0x0006,
+	0x0128, 0x9196, 0x0004, 0x0110, 0x9196, 0x0005, 0x002e, 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, 0x0dd5, 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,
+	0x908e, 0x0006, 0x001e, 0x0005, 0x0016, 0xb904, 0x9184, 0xff00,
+	0x8007, 0x908e, 0x0006, 0x001e, 0x0005, 0x00b6, 0x00f6, 0x080c,
+	0xd388, 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, 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,
+	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,
+	0xa84f, 0x8021, 0xa853, 0x0017, 0x0028, 0x0005, 0xa84f, 0x8020,
+	0xa853, 0x0016, 0x2071, 0x1910, 0x701c, 0x9005, 0x1904, 0x6eb2,
+	0x0e04, 0x6f20, 0x2071, 0x0000, 0xa84c, 0x7082, 0xa850, 0x7032,
+	0xa86c, 0x7086, 0x7036, 0xa870, 0x708a, 0x2091, 0x4080, 0x2001,
+	0x0089, 0x2004, 0xd084, 0x190c, 0x119b, 0x2071, 0x1800, 0x2011,
+	0x0001, 0xa804, 0x900d, 0x702c, 0x1158, 0xa802, 0x2900, 0x702e,
+	0x70c0, 0x9200, 0x70c2, 0x080c, 0x84c2, 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, 0x841a, 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, 0x6ee8, 0x6ee9, 0x6fd4, 0x6ee9, 0x0dd5, 0x6fd4,
-	0x0005, 0x2001, 0x1947, 0x2004, 0x0002, 0x6ef3, 0x6ef3, 0x6f6d,
-	0x6f6e, 0x6ef3, 0x6f6e, 0x0126, 0x2091, 0x8000, 0x1e0c, 0x6ff4,
-	0x701c, 0x904d, 0x0508, 0xa84c, 0x9005, 0x0904, 0x6f3e, 0x0e04,
-	0x6f1c, 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, 0x6fd5, 0x012e, 0x0804, 0x6f6c, 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, 0x6fe9, 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, 0x1ac7, 0x210c, 0x9102,
-	0x1500, 0x0126, 0x2091, 0x8000, 0x2069, 0x0050, 0x693c, 0x6838,
-	0x9106, 0x0190, 0x0e04, 0x6fa0, 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, 0x7055, 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, 0x6feb, 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,
+	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, 0x841a, 0x782c,
-	0x9094, 0x0780, 0x190c, 0x6fe9, 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,
+	0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, 0x84c2, 0x782c,
+	0x9094, 0x0780, 0x190c, 0x706e, 0xd0a4, 0x19f0, 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, 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,
-	0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x119b,
-	0x00fe, 0x0005, 0x782c, 0x9094, 0x0780, 0x190c, 0x6fe9, 0xd0a4,
-	0x0db8, 0x00e6, 0x2071, 0x1800, 0x7824, 0x2048, 0x702c, 0xa802,
-	0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, 0x841a, 0x782c,
-	0x9094, 0x0780, 0x190c, 0x6fe9, 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, 0x717d, 0x7103, 0x711f, 0x7149, 0x716c, 0x71ac, 0x71be,
-	0x711f, 0x7194, 0x70be, 0x70ec, 0x70bd, 0x0005, 0x00d6, 0x2069,
-	0x0200, 0x6804, 0x9005, 0x1180, 0x6808, 0x9005, 0x1518, 0x709b,
-	0x0028, 0x2069, 0x198e, 0x2d04, 0x7002, 0x080c, 0x74eb, 0x6028,
-	0x9085, 0x0600, 0x602a, 0x00b0, 0x709b, 0x0028, 0x2069, 0x198e,
-	0x2d04, 0x7002, 0x6028, 0x9085, 0x0600, 0x602a, 0x00e6, 0x0036,
-	0x0046, 0x0056, 0x2071, 0x1a61, 0x080c, 0x1abb, 0x005e, 0x004e,
-	0x003e, 0x00ee, 0x00de, 0x0005, 0x00d6, 0x2069, 0x0200, 0x6804,
-	0x9005, 0x1178, 0x6808, 0x9005, 0x1160, 0x709b, 0x0028, 0x2069,
-	0x198e, 0x2d04, 0x7002, 0x080c, 0x7586, 0x6028, 0x9085, 0x0600,
-	0x602a, 0x00de, 0x0005, 0x0006, 0x2001, 0x0090, 0x080c, 0x2cfc,
-	0x000e, 0x6124, 0xd1e4, 0x1190, 0x080c, 0x722b, 0xd1d4, 0x1160,
-	0xd1dc, 0x1138, 0xd1cc, 0x0150, 0x709b, 0x0020, 0x080c, 0x722b,
-	0x0028, 0x709b, 0x001d, 0x0010, 0x709b, 0x001f, 0x0005, 0x2001,
-	0x0088, 0x080c, 0x2cfc, 0x6124, 0xd1cc, 0x11e8, 0xd1dc, 0x11c0,
-	0xd1e4, 0x1198, 0x9184, 0x1e00, 0x11d8, 0x080c, 0x1ae0, 0x60e3,
-	0x0001, 0x600c, 0xc0b4, 0x600e, 0x080c, 0x73df, 0x2001, 0x0080,
-	0x080c, 0x2cfc, 0x709b, 0x0028, 0x0058, 0x709b, 0x001e, 0x0040,
-	0x709b, 0x001d, 0x0028, 0x709b, 0x0020, 0x0010, 0x709b, 0x001f,
-	0x0005, 0x080c, 0x1ae0, 0x60e3, 0x0001, 0x600c, 0xc0b4, 0x600e,
-	0x080c, 0x73df, 0x2001, 0x0080, 0x080c, 0x2cfc, 0x6124, 0xd1d4,
-	0x1180, 0xd1dc, 0x1158, 0xd1e4, 0x1130, 0x9184, 0x1e00, 0x1158,
-	0x709b, 0x0028, 0x0040, 0x709b, 0x001e, 0x0028, 0x709b, 0x001d,
-	0x0010, 0x709b, 0x001f, 0x0005, 0x2001, 0x00a0, 0x080c, 0x2cfc,
-	0x6124, 0xd1dc, 0x1138, 0xd1e4, 0x0138, 0x080c, 0x1ae0, 0x709b,
-	0x001e, 0x0010, 0x709b, 0x001d, 0x0005, 0x080c, 0x72ae, 0x6124,
-	0xd1dc, 0x1188, 0x080c, 0x722b, 0x0016, 0x080c, 0x1ae0, 0x001e,
-	0xd1d4, 0x1128, 0xd1e4, 0x0138, 0x709b, 0x001e, 0x0020, 0x709b,
-	0x001f, 0x080c, 0x722b, 0x0005, 0x0006, 0x2001, 0x00a0, 0x080c,
-	0x2cfc, 0x000e, 0x6124, 0xd1d4, 0x1160, 0xd1cc, 0x1150, 0xd1dc,
-	0x1128, 0xd1e4, 0x0140, 0x709b, 0x001e, 0x0028, 0x709b, 0x001d,
-	0x0010, 0x709b, 0x0021, 0x0005, 0x080c, 0x72ae, 0x6124, 0xd1d4,
-	0x1150, 0xd1dc, 0x1128, 0xd1e4, 0x0140, 0x709b, 0x001e, 0x0028,
-	0x709b, 0x001d, 0x0010, 0x709b, 0x001f, 0x0005, 0x0006, 0x2001,
-	0x0090, 0x080c, 0x2cfc, 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, 0x73b3,
-	0x11d8, 0x2001, 0x180c, 0x200c, 0xd1b4, 0x01b0, 0xc1b4, 0x2102,
-	0x6027, 0x0200, 0x080c, 0x2c45, 0x6024, 0xd0cc, 0x0148, 0x2001,
-	0x00a0, 0x080c, 0x2cfc, 0x080c, 0x7699, 0x080c, 0x602d, 0x0428,
-	0x6028, 0xc0cd, 0x602a, 0x0408, 0x080c, 0x73cd, 0x0150, 0x080c,
-	0x73c4, 0x1138, 0x2001, 0x0001, 0x080c, 0x27f7, 0x080c, 0x738b,
-	0x00a0, 0x080c, 0x72ab, 0x0178, 0x2001, 0x0001, 0x080c, 0x27f7,
-	0x7098, 0x9086, 0x001e, 0x0120, 0x7098, 0x9086, 0x0022, 0x1118,
-	0x709b, 0x0025, 0x0010, 0x709b, 0x0021, 0x012e, 0x00ee, 0x00de,
-	0x00ce, 0x001e, 0x0005, 0x0026, 0x2011, 0x723c, 0x080c, 0x85d3,
-	0x002e, 0x0016, 0x0026, 0x2009, 0x0064, 0x2011, 0x723c, 0x080c,
-	0x85ca, 0x002e, 0x001e, 0x0005, 0x00e6, 0x00f6, 0x0016, 0x080c,
-	0xa28f, 0x2071, 0x1800, 0x080c, 0x71d9, 0x001e, 0x00fe, 0x00ee,
-	0x0005, 0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6, 0x00f6,
-	0x0126, 0x080c, 0xa28f, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071,
-	0x1800, 0x2091, 0x8000, 0x6028, 0xc09c, 0x602a, 0x2011, 0x0003,
-	0x080c, 0xa63e, 0x2011, 0x0002, 0x080c, 0xa648, 0x080c, 0xa552,
-	0x080c, 0x857f, 0x0036, 0x901e, 0x080c, 0xa5c8, 0x003e, 0x60e3,
-	0x0000, 0x080c, 0xea24, 0x080c, 0xea3f, 0x2009, 0x0004, 0x080c,
-	0x2c4b, 0x080c, 0x2b66, 0x2001, 0x1800, 0x2003, 0x0004, 0x6027,
-	0x0008, 0x2011, 0x723c, 0x080c, 0x85d3, 0x080c, 0x73cd, 0x0118,
-	0x9006, 0x080c, 0x2cfc, 0x080c, 0x0bae, 0x2001, 0x0001, 0x080c,
-	0x27f7, 0x012e, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e,
-	0x001e, 0x0005, 0x0026, 0x00e6, 0x2011, 0x7249, 0x2071, 0x19f9,
-	0x701c, 0x9206, 0x1118, 0x7018, 0x9005, 0x0110, 0x9085, 0x0001,
-	0x00ee, 0x002e, 0x0005, 0x6020, 0xd09c, 0x0005, 0x6800, 0x9084,
-	0xfffe, 0x9086, 0x00c0, 0x0170, 0x2001, 0x00c0, 0x080c, 0x2cfc,
-	0x0156, 0x20a9, 0x002d, 0x1d04, 0x72bb, 0x2091, 0x6000, 0x1f04,
-	0x72bb, 0x015e, 0x0005, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100,
-	0x2069, 0x0140, 0x2071, 0x1800, 0x080c, 0x76a8, 0x2001, 0x196c,
-	0x2003, 0x0000, 0x9006, 0x709a, 0x60e2, 0x6886, 0x080c, 0x28bf,
-	0x9006, 0x080c, 0x2cfc, 0x080c, 0x5eec, 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, 0x737b, 0x709b,
-	0x0022, 0x0040, 0x709b, 0x0021, 0x0028, 0x709b, 0x0023, 0x0010,
-	0x709b, 0x0024, 0x60e3, 0x0000, 0x6887, 0x0001, 0x2001, 0x0001,
-	0x080c, 0x28bf, 0x0026, 0x080c, 0xadd0, 0x002e, 0x7000, 0x908e,
-	0x0004, 0x0118, 0x602b, 0x0028, 0x0010, 0x602b, 0x0020, 0x0156,
-	0x0126, 0x2091, 0x8000, 0x20a9, 0x0005, 0x6024, 0xd0ac, 0x0150,
-	0x012e, 0x015e, 0x080c, 0xd25a, 0x0118, 0x9006, 0x080c, 0x2d26,
-	0x0804, 0x7387, 0x6800, 0x9084, 0x00a1, 0xc0bd, 0x6802, 0x080c,
-	0x2c45, 0x6904, 0xd1d4, 0x1140, 0x2001, 0x0100, 0x080c, 0x2cfc,
-	0x1f04, 0x7325, 0x080c, 0x740a, 0x012e, 0x015e, 0x080c, 0x73c4,
-	0x01a8, 0x6044, 0x9005, 0x0168, 0x6050, 0x0006, 0x9085, 0x0020,
-	0x6052, 0x080c, 0x740a, 0x9006, 0x8001, 0x1df0, 0x000e, 0x6052,
-	0x0028, 0x6804, 0xd0d4, 0x1110, 0x080c, 0x740a, 0x080c, 0xd25a,
-	0x0118, 0x9006, 0x080c, 0x2d26, 0x0016, 0x0026, 0x7000, 0x908e,
-	0x0004, 0x0130, 0x2009, 0x00c8, 0x2011, 0x7249, 0x080c, 0x8591,
-	0x002e, 0x001e, 0x080c, 0x8411, 0x7034, 0xc085, 0x7036, 0x2001,
-	0x197c, 0x2003, 0x0004, 0x080c, 0x70a6, 0x080c, 0x73c4, 0x0138,
-	0x6804, 0xd0d4, 0x1120, 0xd0dc, 0x1100, 0x080c, 0x769e, 0x00ee,
-	0x00de, 0x00ce, 0x0005, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100,
-	0x2069, 0x0140, 0x2071, 0x1800, 0x080c, 0x8428, 0x080c, 0x841a,
-	0x080c, 0x76a8, 0x2001, 0x196c, 0x2003, 0x0000, 0x9006, 0x709a,
-	0x60e2, 0x6886, 0x080c, 0x28bf, 0x9006, 0x080c, 0x2cfc, 0x6043,
-	0x0090, 0x6043, 0x0010, 0x6027, 0xffff, 0x602b, 0x182f, 0x00ee,
-	0x00de, 0x00ce, 0x0005, 0x0006, 0x2001, 0x197b, 0x2004, 0x9086,
-	0xaaaa, 0x000e, 0x0005, 0x0006, 0x080c, 0x56e6, 0x9084, 0x0030,
-	0x9086, 0x0000, 0x000e, 0x0005, 0x0006, 0x080c, 0x56e6, 0x9084,
-	0x0030, 0x9086, 0x0030, 0x000e, 0x0005, 0x0006, 0x080c, 0x56e6,
-	0x9084, 0x0030, 0x9086, 0x0010, 0x000e, 0x0005, 0x0006, 0x080c,
-	0x56e6, 0x9084, 0x0030, 0x9086, 0x0020, 0x000e, 0x0005, 0x0036,
-	0x0016, 0x2001, 0x180c, 0x2004, 0x908c, 0x0013, 0x0180, 0x0020,
-	0x080c, 0x28df, 0x900e, 0x0028, 0x080c, 0x6981, 0x1dc8, 0x2009,
-	0x0002, 0x2019, 0x0028, 0x080c, 0x3197, 0x9006, 0x0019, 0x001e,
-	0x003e, 0x0005, 0x00e6, 0x2071, 0x180c, 0x2e04, 0x0130, 0x080c,
-	0xd253, 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,
-	0x741f, 0x2091, 0x6000, 0x1f04, 0x741f, 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, 0x28bf, 0x2001, 0x00a0, 0x0006,
-	0x080c, 0xd25a, 0x000e, 0x0130, 0x080c, 0x2d1a, 0x9006, 0x080c,
-	0x2d26, 0x0010, 0x080c, 0x2cfc, 0x000e, 0x6052, 0x6050, 0x0006,
-	0xc0e5, 0x6052, 0x00f6, 0x2079, 0x0100, 0x080c, 0x2bba, 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, 0x74dd, 0x2001, 0x180c, 0x200c, 0xc1c4, 0x2102,
-	0x6028, 0x9084, 0xe1ff, 0x602a, 0x6027, 0x0200, 0x2001, 0x0090,
-	0x080c, 0x2cfc, 0x20a9, 0x0366, 0x6024, 0xd0cc, 0x1518, 0x1d04,
-	0x748c, 0x2091, 0x6000, 0x1f04, 0x748c, 0x2011, 0x0003, 0x080c,
-	0xa63e, 0x2011, 0x0002, 0x080c, 0xa648, 0x080c, 0xa552, 0x901e,
-	0x080c, 0xa5c8, 0x2001, 0x00a0, 0x080c, 0x2cfc, 0x080c, 0x7699,
-	0x080c, 0x602d, 0x080c, 0xd25a, 0x0110, 0x080c, 0x0d45, 0x9085,
-	0x0001, 0x0488, 0x080c, 0x1ae0, 0x60e3, 0x0000, 0x2001, 0x196c,
-	0x2004, 0x080c, 0x28bf, 0x60e2, 0x2001, 0x0080, 0x080c, 0x2cfc,
-	0x20a9, 0x0366, 0x6027, 0x1e00, 0x2009, 0x1e00, 0x080c, 0x2c45,
-	0x6024, 0x910c, 0x0138, 0x1d04, 0x74c2, 0x2091, 0x6000, 0x1f04,
-	0x74c2, 0x0818, 0x6028, 0x9085, 0x1e00, 0x602a, 0x70b4, 0x9005,
-	0x1118, 0x6887, 0x0001, 0x0008, 0x6886, 0x080c, 0xd25a, 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,
-	0x7550, 0x2001, 0x0088, 0x080c, 0x2cfc, 0x9006, 0x60e2, 0x6886,
-	0x080c, 0x28bf, 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, 0x7532, 0x2091, 0x6000, 0x1f04, 0x7532,
-	0x0804, 0x757e, 0x2069, 0x0140, 0x20a9, 0x0384, 0x6027, 0x1e00,
-	0x2009, 0x1e00, 0x080c, 0x2c45, 0x6024, 0x910c, 0x0508, 0x9084,
-	0x1a00, 0x11f0, 0x1d04, 0x753e, 0x2091, 0x6000, 0x1f04, 0x753e,
-	0x2011, 0x0003, 0x080c, 0xa63e, 0x2011, 0x0002, 0x080c, 0xa648,
-	0x080c, 0xa552, 0x901e, 0x080c, 0xa5c8, 0x2001, 0x00a0, 0x080c,
-	0x2cfc, 0x080c, 0x7699, 0x080c, 0x602d, 0x9085, 0x0001, 0x00b0,
-	0x2001, 0x0080, 0x080c, 0x2cfc, 0x2069, 0x0140, 0x60e3, 0x0000,
-	0x70b4, 0x9005, 0x1118, 0x6887, 0x0001, 0x0008, 0x6886, 0x2001,
-	0x196c, 0x2004, 0x080c, 0x28bf, 0x60e2, 0x9006, 0x00ee, 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,
+	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,
+	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,
+	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,
+	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,
+	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,
+	0xd1d4, 0x1160, 0xd1cc, 0x1150, 0xd1dc, 0x1128, 0xd1e4, 0x0140,
+	0x709b, 0x001e, 0x0028, 0x709b, 0x001d, 0x0010, 0x709b, 0x0021,
+	0x0005, 0x080c, 0x7333, 0x6124, 0xd1d4, 0x1150, 0xd1dc, 0x1128,
+	0xd1e4, 0x0140, 0x709b, 0x001e, 0x0028, 0x709b, 0x001d, 0x0010,
+	0x709b, 0x001f, 0x0005, 0x0006, 0x2001, 0x0090, 0x080c, 0x2d4e,
+	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,
+	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,
+	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,
+	0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e, 0x0005, 0x0026,
+	0x00e6, 0x2011, 0x72ce, 0x2071, 0x19f9, 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, 0x6020, 0x9084, 0x00c0, 0x01c8, 0x2011, 0x0003, 0x080c,
-	0xa63e, 0x2011, 0x0002, 0x080c, 0xa648, 0x080c, 0xa552, 0x901e,
-	0x080c, 0xa5c8, 0x2069, 0x0140, 0x2001, 0x00a0, 0x080c, 0x2cfc,
-	0x080c, 0x7699, 0x080c, 0x602d, 0x0804, 0x7619, 0x2001, 0x180c,
-	0x200c, 0xd1b4, 0x1160, 0xc1b5, 0x2102, 0x080c, 0x7231, 0x2069,
-	0x0140, 0x2001, 0x0080, 0x080c, 0x2cfc, 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, 0x7619, 0x6027,
-	0x1e00, 0x2009, 0x1e00, 0x080c, 0x2c45, 0x6024, 0x910c, 0x01c8,
-	0x9084, 0x1c00, 0x11b0, 0x1d04, 0x75d7, 0x0006, 0x0016, 0x00c6,
-	0x00d6, 0x00e6, 0x080c, 0x8459, 0x00ee, 0x00de, 0x00ce, 0x001e,
-	0x000e, 0x00e6, 0x2071, 0x19f9, 0x7070, 0x00ee, 0x9005, 0x19f8,
-	0x0400, 0x0026, 0x2011, 0x7249, 0x080c, 0x84f9, 0x2011, 0x723c,
-	0x080c, 0x85d3, 0x002e, 0x2069, 0x0140, 0x60e3, 0x0000, 0x70b4,
-	0x9005, 0x1118, 0x6887, 0x0001, 0x0008, 0x6886, 0x2001, 0x196c,
-	0x2004, 0x080c, 0x28bf, 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, 0xd253, 0x1904, 0x7687,
-	0x7130, 0xd184, 0x1170, 0x080c, 0x3326, 0x0138, 0xc18d, 0x7132,
-	0x2011, 0x1848, 0x2214, 0xd2ac, 0x1120, 0x7030, 0xd08c, 0x0904,
-	0x7687, 0x2011, 0x1848, 0x220c, 0xd1a4, 0x0538, 0x0016, 0x2019,
-	0x000e, 0x080c, 0xe55d, 0x0156, 0x00b6, 0x20a9, 0x007f, 0x900e,
-	0x9186, 0x007e, 0x01a0, 0x9186, 0x0080, 0x0188, 0x080c, 0x6616,
-	0x1170, 0x2120, 0x9006, 0x0016, 0x2009, 0x000e, 0x080c, 0xe5e9,
-	0x2009, 0x0001, 0x2011, 0x0100, 0x080c, 0x86e3, 0x001e, 0x8108,
-	0x1f04, 0x7650, 0x00be, 0x015e, 0x001e, 0xd1ac, 0x1148, 0x0016,
-	0x2009, 0x0002, 0x2019, 0x0004, 0x080c, 0x3197, 0x001e, 0x0078,
-	0x0156, 0x00b6, 0x20a9, 0x007f, 0x900e, 0x080c, 0x6616, 0x1110,
-	0x080c, 0x6047, 0x8108, 0x1f04, 0x767d, 0x00be, 0x015e, 0x080c,
-	0x1ae0, 0x080c, 0xadd0, 0x60e3, 0x0000, 0x080c, 0x602d, 0x080c,
-	0x72e5, 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, 0x7c86,
-	0x9006, 0x00ee, 0x0005, 0x900e, 0x0156, 0x20a9, 0x0006, 0x8003,
-	0x2011, 0x0100, 0x2214, 0x9296, 0x0008, 0x1110, 0x818d, 0x0010,
-	0x81f5, 0x3e08, 0x1f04, 0x770f, 0x015e, 0x0005, 0x2079, 0x0040,
-	0x2071, 0x18fa, 0x7004, 0x0002, 0x772e, 0x772f, 0x7767, 0x77c2,
-	0x78d2, 0x772c, 0x772c, 0x78fc, 0x080c, 0x0dd5, 0x0005, 0x2079,
-	0x0040, 0x782c, 0x908c, 0x0780, 0x190c, 0x7d68, 0xd0a4, 0x01f8,
+	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, 0x0040, 0x0610, 0x00c0, 0x2001, 0x1800, 0x200c, 0x9186,
-	0x0003, 0x1168, 0x7004, 0x0002, 0x7757, 0x7731, 0x7757, 0x7755,
-	0x7757, 0x7757, 0x7757, 0x7757, 0x7757, 0x080c, 0x77c2, 0x782c,
-	0xd09c, 0x090c, 0x7c86, 0x0005, 0x9082, 0x005a, 0x1218, 0x2100,
-	0x003b, 0x0c10, 0x080c, 0x77f8, 0x0c90, 0x00e3, 0x08e8, 0x0005,
-	0x77f8, 0x77f8, 0x77f8, 0x77f8, 0x77f8, 0x77f8, 0x77f8, 0x77f8,
-	0x781a, 0x77f8, 0x77f8, 0x77f8, 0x77f8, 0x77f8, 0x77f8, 0x77f8,
-	0x77f8, 0x77f8, 0x77f8, 0x77f8, 0x77f8, 0x77f8, 0x77f8, 0x77f8,
-	0x77f8, 0x77f8, 0x77f8, 0x77f8, 0x7804, 0x77f8, 0x79ed, 0x77f8,
-	0x77f8, 0x77f8, 0x781a, 0x77f8, 0x7804, 0x7a2e, 0x7a6f, 0x7ab6,
-	0x7aca, 0x77f8, 0x77f8, 0x781a, 0x7804, 0x782e, 0x77f8, 0x78a6,
-	0x7b75, 0x7b90, 0x77f8, 0x781a, 0x77f8, 0x782e, 0x77f8, 0x77f8,
-	0x789c, 0x7b90, 0x77f8, 0x77f8, 0x77f8, 0x77f8, 0x77f8, 0x77f8,
-	0x77f8, 0x77f8, 0x77f8, 0x7842, 0x77f8, 0x77f8, 0x77f8, 0x77f8,
-	0x77f8, 0x77f8, 0x77f8, 0x77f8, 0x77f8, 0x7d0c, 0x77f8, 0x7cb6,
-	0x77f8, 0x7cb6, 0x77f8, 0x7857, 0x77f8, 0x77f8, 0x77f8, 0x77f8,
-	0x77f8, 0x77f8, 0x2079, 0x0040, 0x7004, 0x9086, 0x0003, 0x1198,
-	0x782c, 0x080c, 0x7caf, 0xd0a4, 0x0170, 0x7824, 0x2048, 0x9006,
-	0xa802, 0xa806, 0xa864, 0x9084, 0x00ff, 0x908a, 0x001a, 0x1210,
-	0x002b, 0x0c50, 0x00e9, 0x080c, 0x7c86, 0x0005, 0x77f8, 0x7804,
-	0x79d9, 0x77f8, 0x7804, 0x77f8, 0x7804, 0x7804, 0x77f8, 0x7804,
-	0x79d9, 0x7804, 0x7804, 0x7804, 0x7804, 0x7804, 0x77f8, 0x7804,
-	0x79d9, 0x77f8, 0x77f8, 0x7804, 0x77f8, 0x77f8, 0x77f8, 0x7804,
-	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, 0x6c94,
-	0x012e, 0x0005, 0xa864, 0x8007, 0x9084, 0x00ff, 0x0d08, 0x8001,
-	0x1120, 0x7007, 0x0001, 0x0804, 0x797b, 0x7007, 0x0003, 0x7012,
-	0x2900, 0x7016, 0x701a, 0x704b, 0x797b, 0x0005, 0xa864, 0x8007,
-	0x9084, 0x00ff, 0x0968, 0x8001, 0x1120, 0x7007, 0x0001, 0x0804,
-	0x7996, 0x7007, 0x0003, 0x7012, 0x2900, 0x7016, 0x701a, 0x704b,
-	0x7996, 0x0005, 0xa864, 0x8007, 0x9084, 0x00ff, 0x0904, 0x7800,
-	0x8001, 0x1120, 0x7007, 0x0001, 0x0804, 0x79b2, 0x7007, 0x0003,
-	0x7012, 0x2900, 0x7016, 0x701a, 0x704b, 0x79b2, 0x0005, 0xa864,
-	0x8007, 0x9084, 0x00ff, 0x9086, 0x0001, 0x1904, 0x7800, 0x7007,
-	0x0001, 0x2009, 0x1834, 0x210c, 0x81ff, 0x11a8, 0xa868, 0x9084,
-	0x00ff, 0xa86a, 0xa883, 0x0000, 0x080c, 0x62c1, 0x1108, 0x0005,
-	0x0126, 0x2091, 0x8000, 0xa867, 0x0139, 0xa87a, 0xa982, 0x080c,
-	0x6c94, 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, 0x7ba7, 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, 0x7808,
-	0xaab4, 0x928a, 0x0002, 0x1a04, 0x7808, 0x82ff, 0x1138, 0xa8b8,
-	0xa9bc, 0x9105, 0x0118, 0x2001, 0x7939, 0x0018, 0x9280, 0x792f,
-	0x2005, 0x7056, 0x7010, 0x9015, 0x0904, 0x791a, 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, 0x7808, 0x7020, 0x2048,
-	0x7018, 0xa802, 0xa807, 0x0000, 0x2908, 0x2048, 0xa906, 0x711a,
-	0x0804, 0x78d2, 0x7014, 0x2048, 0x7007, 0x0001, 0xa8b4, 0x9005,
-	0x1128, 0xa8b8, 0xa9bc, 0x9105, 0x0108, 0x00b9, 0xa864, 0x9084,
-	0x00ff, 0x9086, 0x001e, 0x0904, 0x7ba7, 0x0804, 0x797b, 0x7931,
-	0x7935, 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, 0x60c1, 0x1108, 0x0005, 0x080c, 0x6ec7, 0x0126, 0x2091,
-	0x8000, 0x080c, 0xce4e, 0x080c, 0x6c94, 0x012e, 0x0ca0, 0x080c,
-	0xd253, 0x1d70, 0x2001, 0x0028, 0x900e, 0x0c70, 0x2009, 0x1834,
-	0x210c, 0x81ff, 0x1188, 0xa888, 0x9005, 0x0188, 0xa883, 0x0000,
-	0x080c, 0x6151, 0x1108, 0x0005, 0xa87a, 0x0126, 0x2091, 0x8000,
-	0x080c, 0x6c94, 0x012e, 0x0cb8, 0x2001, 0x0028, 0x0ca8, 0x2001,
-	0x0000, 0x0c90, 0x2009, 0x1834, 0x210c, 0x81ff, 0x11d8, 0xa888,
-	0x9005, 0x01e0, 0xa883, 0x0000, 0xa87c, 0xd0f4, 0x0120, 0x080c,
-	0x6223, 0x1138, 0x0005, 0x9006, 0xa87a, 0x080c, 0x619e, 0x1108,
-	0x0005, 0x0126, 0x2091, 0x8000, 0xa87a, 0xa982, 0x080c, 0x6c94,
-	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, 0x6616, 0x11b8,
-	0x0066, 0xae80, 0x080c, 0x6726, 0x006e, 0x0088, 0x0046, 0x2011,
-	0x180c, 0x2224, 0xc484, 0x2412, 0x004e, 0x00c6, 0x080c, 0x6616,
-	0x1110, 0x080c, 0x6826, 0x8108, 0x1f04, 0x7a16, 0x00ce, 0xa87c,
-	0xd084, 0x1120, 0x080c, 0x1031, 0x00be, 0x0005, 0x0126, 0x2091,
-	0x8000, 0x080c, 0x6c94, 0x012e, 0x00be, 0x0005, 0x0126, 0x2091,
-	0x8000, 0x7007, 0x0001, 0x080c, 0x6985, 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, 0x7c70, 0x012e, 0x0804,
-	0x7c6a, 0x012e, 0x0804, 0x7c64, 0x012e, 0x0804, 0x7c67, 0x0126,
-	0x2091, 0x8000, 0x7007, 0x0001, 0x080c, 0x6985, 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, 0x7c70,
-	0x012e, 0x0804, 0x7c6d, 0x012e, 0x0804, 0x7c6a, 0x0126, 0x2091,
-	0x8000, 0x7007, 0x0001, 0x2061, 0x1a70, 0x6300, 0xd38c, 0x1120,
-	0x6308, 0x8318, 0x0220, 0x630a, 0x012e, 0x0804, 0x7c7e, 0x012e,
-	0x0804, 0x7c6d, 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, 0xae90, 0x0068, 0x6017, 0xf400, 0x605b, 0x0000, 0xa97c,
-	0xd1a4, 0x0110, 0xa980, 0x615a, 0x2009, 0x0041, 0x080c, 0xaeda,
-	0xa988, 0x918c, 0xff00, 0x9186, 0x2000, 0x1138, 0x0026, 0x900e,
-	0x2011, 0xfdff, 0x080c, 0x86e3, 0x002e, 0xa87c, 0xd0c4, 0x0148,
-	0x2061, 0x1a70, 0x6000, 0xd08c, 0x1120, 0x6008, 0x8000, 0x0208,
-	0x600a, 0x00ce, 0x012e, 0x00be, 0x0804, 0x7c70, 0x00ce, 0x012e,
-	0x00be, 0x0804, 0x7c6a, 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, 0x6616, 0x1968,
-	0xb800, 0xc0e4, 0xb802, 0x0848, 0xa88c, 0x9065, 0x09b8, 0x6007,
-	0x0024, 0x2001, 0x1985, 0x2004, 0x601a, 0x0804, 0x7b05, 0xa88c,
-	0x9065, 0x0960, 0x00e6, 0xa890, 0x9075, 0x2001, 0x1834, 0x2004,
-	0x9005, 0x0150, 0x080c, 0xae90, 0x8eff, 0x0118, 0x2e60, 0x080c,
-	0xae90, 0x00ee, 0x0804, 0x7b05, 0x6024, 0xc0dc, 0xc0d5, 0x6026,
-	0x2e60, 0x6007, 0x003a, 0xa8a0, 0x9005, 0x0130, 0x6007, 0x003b,
-	0xa8a4, 0x602e, 0xa8a8, 0x6016, 0x6003, 0x0001, 0x080c, 0x90f8,
-	0x080c, 0x96a6, 0x00ee, 0x0804, 0x7b05, 0x2061, 0x1a70, 0x6000,
-	0xd084, 0x0190, 0xd08c, 0x1904, 0x7c7e, 0x0126, 0x2091, 0x8000,
-	0x6204, 0x8210, 0x0220, 0x6206, 0x012e, 0x0804, 0x7c7e, 0x012e,
-	0xa883, 0x0016, 0x0804, 0x7c77, 0xa883, 0x0007, 0x0804, 0x7c77,
-	0xa864, 0x8007, 0x9084, 0x00ff, 0x0130, 0x8001, 0x1138, 0x7007,
-	0x0001, 0x0069, 0x0005, 0x080c, 0x7800, 0x0040, 0x7007, 0x0003,
-	0x7012, 0x2900, 0x7016, 0x701a, 0x704b, 0x7ba7, 0x0005, 0x00b6,
-	0x00e6, 0x0126, 0x2091, 0x8000, 0x903e, 0x2061, 0x1800, 0x61d0,
-	0x81ff, 0x1904, 0x7c29, 0x6130, 0xd194, 0x1904, 0x7c53, 0xa878,
-	0x2070, 0x9e82, 0x1cd0, 0x0a04, 0x7c1d, 0x6068, 0x9e02, 0x1a04,
-	0x7c1d, 0x7120, 0x9186, 0x0006, 0x1904, 0x7c0f, 0x7010, 0x905d,
-	0x0904, 0x7c29, 0xb800, 0xd0e4, 0x1904, 0x7c4d, 0x2061, 0x1a70,
-	0x6100, 0x9184, 0x0301, 0x9086, 0x0001, 0x15a0, 0x7024, 0xd0dc,
-	0x1904, 0x7c56, 0xa883, 0x0000, 0xa803, 0x0000, 0x2908, 0x7014,
-	0x9005, 0x1198, 0x7116, 0xa87c, 0xd0f4, 0x1904, 0x7c59, 0x080c,
-	0x56e2, 0xd09c, 0x1118, 0xa87c, 0xc0cc, 0xa87e, 0x2e60, 0x080c,
-	0x8603, 0x012e, 0x00ee, 0x00be, 0x0005, 0x2048, 0xa800, 0x9005,
-	0x1de0, 0xa902, 0x2148, 0xa87c, 0xd0f4, 0x1904, 0x7c59, 0x012e,
-	0x00ee, 0x00be, 0x0005, 0x012e, 0x00ee, 0xa883, 0x0006, 0x00be,
-	0x0804, 0x7c77, 0xd184, 0x0db8, 0xd1c4, 0x1190, 0x00a0, 0xa974,
-	0x080c, 0x6616, 0x15d0, 0xb800, 0xd0e4, 0x15b8, 0x7120, 0x9186,
-	0x0007, 0x1118, 0xa883, 0x0002, 0x0490, 0xa883, 0x0008, 0x0478,
-	0xa883, 0x000e, 0x0460, 0xa883, 0x0017, 0x0448, 0xa883, 0x0035,
-	0x0430, 0x080c, 0x56e6, 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, 0x7bb3, 0x7003, 0x0002,
-	0x0804, 0x7bb3, 0xa883, 0x0028, 0x0010, 0xa883, 0x0029, 0x012e,
-	0x00ee, 0x00be, 0x0420, 0xa883, 0x002a, 0x0cc8, 0xa883, 0x0045,
-	0x0cb0, 0x2e60, 0x2019, 0x0002, 0x601b, 0x0014, 0x080c, 0xe16f,
-	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, 0x6c94, 0x012e, 0x0005, 0x080c, 0x1031,
-	0x0005, 0x00d6, 0x080c, 0x85fa, 0x00de, 0x0005, 0x00d6, 0x00e6,
-	0x0126, 0x2091, 0x8000, 0x2071, 0x0040, 0x702c, 0xd084, 0x01d8,
-	0x908c, 0x0780, 0x190c, 0x7d68, 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, 0x7d68, 0x000e, 0x0005, 0xa898, 0x9084,
-	0x0003, 0x05a8, 0x080c, 0xae09, 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, 0x284b,
-	0x1540, 0x00b6, 0x080c, 0x6616, 0x2b00, 0x00be, 0x1510, 0x6012,
-	0x6023, 0x0001, 0x2009, 0x0040, 0xa864, 0x9084, 0x00ff, 0x9086,
-	0x0035, 0x0110, 0x2009, 0x0041, 0x080c, 0xaeda, 0x0005, 0xa87b,
-	0x0101, 0x0126, 0x2091, 0x8000, 0x080c, 0x6c94, 0x012e, 0x0005,
-	0xa87b, 0x002c, 0x0126, 0x2091, 0x8000, 0x080c, 0x6c94, 0x012e,
-	0x0005, 0xa87b, 0x0028, 0x0126, 0x2091, 0x8000, 0x080c, 0x6c94,
-	0x012e, 0x080c, 0xae5f, 0x0005, 0x00d6, 0x00c6, 0x0036, 0x0026,
-	0x0016, 0x00b6, 0x7007, 0x0001, 0xaa74, 0x9282, 0x0004, 0x1a04,
-	0x7d59, 0xa97c, 0x9188, 0x1000, 0x2104, 0x905d, 0xb804, 0xd284,
-	0x0140, 0x05e8, 0x8007, 0x9084, 0x00ff, 0x9084, 0x0006, 0x1108,
-	0x04b0, 0x2b10, 0x080c, 0xae09, 0x1118, 0x080c, 0xaead, 0x05a8,
-	0x6212, 0xa874, 0x0002, 0x7d37, 0x7d3c, 0x7d3f, 0x7d45, 0x2019,
-	0x0002, 0x080c, 0xe55d, 0x0060, 0x080c, 0xe4f9, 0x0048, 0x2019,
-	0x0002, 0xa980, 0x080c, 0xe514, 0x0018, 0xa980, 0x080c, 0xe4f9,
-	0x080c, 0xae5f, 0xa887, 0x0000, 0x0126, 0x2091, 0x8000, 0x080c,
-	0x6c94, 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, 0x7d6a, 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,
-	0x157f, 0x00fe, 0x0005, 0x2001, 0x020d, 0x2003, 0x0020, 0x781f,
-	0x0300, 0x00fe, 0x0005, 0x781c, 0xd08c, 0x0904, 0x7dea, 0x68c0,
-	0x90aa, 0x0005, 0x0a04, 0x8411, 0x7d44, 0x7c40, 0x9584, 0x00f6,
-	0x1510, 0x9484, 0x7000, 0x0140, 0x908a, 0x2000, 0x1260, 0x9584,
-	0x0700, 0x8007, 0x0804, 0x7df1, 0x7000, 0x9084, 0xff00, 0x9086,
-	0x8100, 0x0da8, 0x00b0, 0x9484, 0x0fff, 0x1130, 0x7000, 0x9084,
-	0xff00, 0x9086, 0x8100, 0x11c0, 0x080c, 0xe9fc, 0x080c, 0x82f6,
-	0x7817, 0x0140, 0x00a8, 0x9584, 0x0076, 0x1118, 0x080c, 0x8354,
-	0x19c0, 0xd5a4, 0x0148, 0x0046, 0x0056, 0x080c, 0x7e4c, 0x080c,
-	0x2344, 0x005e, 0x004e, 0x0020, 0x080c, 0xe9fc, 0x7817, 0x0140,
-	0x080c, 0x73b3, 0x0168, 0x2001, 0x0111, 0x2004, 0xd08c, 0x0140,
-	0x6893, 0x0000, 0x2001, 0x0110, 0x2003, 0x0008, 0x2003, 0x0000,
-	0x080c, 0x7e2d, 0x2001, 0x19ef, 0x2004, 0x9005, 0x090c, 0x96a6,
-	0x0005, 0x0002, 0x7e03, 0x8118, 0x7dfa, 0x7dfa, 0x7dfa, 0x7dfa,
-	0x7dfa, 0x7dfa, 0x7817, 0x0140, 0x2001, 0x19ef, 0x2004, 0x9005,
-	0x090c, 0x96a6, 0x0005, 0x7000, 0x908c, 0xff00, 0x9194, 0xf000,
-	0x810f, 0x9484, 0x0fff, 0x6892, 0x9286, 0x2000, 0x1150, 0x6800,
-	0x9086, 0x0001, 0x1118, 0x080c, 0x5743, 0x0070, 0x080c, 0x7e6c,
-	0x0058, 0x9286, 0x3000, 0x1118, 0x080c, 0x8053, 0x0028, 0x9286,
-	0x8000, 0x1110, 0x080c, 0x8226, 0x7817, 0x0140, 0x2001, 0x19ef,
-	0x2004, 0x9005, 0x090c, 0x96a6, 0x0005, 0x2001, 0x1810, 0x2004,
-	0xd08c, 0x0178, 0x2001, 0x1800, 0x2004, 0x9086, 0x0003, 0x1148,
-	0x0026, 0x0036, 0x2011, 0x8048, 0x2518, 0x080c, 0x4b1e, 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, 0x4b1e, 0x002e, 0x00fe,
-	0x005e, 0x004e, 0x003e, 0x0005, 0x00b6, 0x00c6, 0x7010, 0x9084,
-	0xff00, 0x8007, 0x9096, 0x0001, 0x0120, 0x9096, 0x0023, 0x1904,
-	0x8024, 0x9186, 0x0023, 0x15c0, 0x080c, 0x82bb, 0x0904, 0x8024,
-	0x6120, 0x9186, 0x0001, 0x0150, 0x9186, 0x0004, 0x0138, 0x9186,
-	0x0008, 0x0120, 0x9186, 0x000a, 0x1904, 0x8024, 0x7124, 0x610a,
-	0x7030, 0x908e, 0x0200, 0x1130, 0x2009, 0x0015, 0x080c, 0xaeda,
-	0x0804, 0x8024, 0x908e, 0x0214, 0x0118, 0x908e, 0x0210, 0x1130,
-	0x2009, 0x0015, 0x080c, 0xaeda, 0x0804, 0x8024, 0x908e, 0x0100,
-	0x1904, 0x8024, 0x7034, 0x9005, 0x1904, 0x8024, 0x2009, 0x0016,
-	0x080c, 0xaeda, 0x0804, 0x8024, 0x9186, 0x0022, 0x1904, 0x8024,
-	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, 0x2894, 0x7932, 0x7936, 0x001e, 0x000e, 0x00fe,
-	0x080c, 0x284b, 0x695e, 0x703c, 0x00e6, 0x2071, 0x0140, 0x7086,
-	0x2071, 0x1800, 0x70b6, 0x00ee, 0x7034, 0x9005, 0x1904, 0x8024,
-	0x2009, 0x0017, 0x0804, 0x7fd4, 0x908e, 0x0400, 0x1190, 0x7034,
-	0x9005, 0x1904, 0x8024, 0x080c, 0x73b3, 0x0120, 0x2009, 0x001d,
-	0x0804, 0x7fd4, 0x68dc, 0xc0a5, 0x68de, 0x2009, 0x0030, 0x0804,
-	0x7fd4, 0x908e, 0x0500, 0x1140, 0x7034, 0x9005, 0x1904, 0x8024,
-	0x2009, 0x0018, 0x0804, 0x7fd4, 0x908e, 0x2010, 0x1120, 0x2009,
-	0x0019, 0x0804, 0x7fd4, 0x908e, 0x2110, 0x1120, 0x2009, 0x001a,
-	0x0804, 0x7fd4, 0x908e, 0x5200, 0x1140, 0x7034, 0x9005, 0x1904,
-	0x8024, 0x2009, 0x001b, 0x0804, 0x7fd4, 0x908e, 0x5000, 0x1140,
-	0x7034, 0x9005, 0x1904, 0x8024, 0x2009, 0x001c, 0x0804, 0x7fd4,
-	0x908e, 0x1300, 0x1120, 0x2009, 0x0034, 0x0804, 0x7fd4, 0x908e,
-	0x1200, 0x1140, 0x7034, 0x9005, 0x1904, 0x8024, 0x2009, 0x0024,
-	0x0804, 0x7fd4, 0x908c, 0xff00, 0x918e, 0x2400, 0x1170, 0x2009,
-	0x002d, 0x2001, 0x1810, 0x2004, 0xd09c, 0x0904, 0x7fd4, 0x080c,
-	0xd934, 0x1904, 0x8024, 0x0804, 0x7fd2, 0x908c, 0xff00, 0x918e,
-	0x5300, 0x1120, 0x2009, 0x002a, 0x0804, 0x7fd4, 0x908e, 0x0f00,
-	0x1120, 0x2009, 0x0020, 0x0804, 0x7fd4, 0x908e, 0x6104, 0x1530,
-	0x2029, 0x0205, 0x2011, 0x026d, 0x8208, 0x2204, 0x9082, 0x0004,
-	0x8004, 0x8004, 0x20a8, 0x2011, 0x8015, 0x211c, 0x8108, 0x0046,
-	0x2124, 0x080c, 0x4b1e, 0x004e, 0x8108, 0x0f04, 0x7f88, 0x9186,
-	0x0280, 0x1d88, 0x2504, 0x8000, 0x202a, 0x2009, 0x0260, 0x0c58,
-	0x202b, 0x0000, 0x2009, 0x0023, 0x0804, 0x7fd4, 0x908e, 0x6000,
-	0x1120, 0x2009, 0x003f, 0x0804, 0x7fd4, 0x908e, 0x5400, 0x1138,
-	0x080c, 0x83c1, 0x1904, 0x8024, 0x2009, 0x0046, 0x04a8, 0x908e,
-	0x5500, 0x1148, 0x080c, 0x83e9, 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, 0x284b, 0x1904, 0x8027, 0x080c, 0x65b5,
-	0x1904, 0x8027, 0xbe12, 0xbd16, 0x001e, 0x0016, 0x080c, 0x73b3,
-	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, 0xae09, 0x01a8, 0x2b08, 0x6112, 0x6023, 0x0004,
-	0x7120, 0x610a, 0x001e, 0x9186, 0x004c, 0x1110, 0x6023, 0x000a,
-	0x0016, 0x001e, 0x080c, 0xaeda, 0x00ce, 0x00be, 0x0005, 0x001e,
-	0x0cd8, 0x2001, 0x180e, 0x2004, 0xd0ec, 0x0120, 0x2011, 0x8049,
-	0x080c, 0x4b1e, 0x080c, 0xaead, 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, 0x9140, 0x08a0, 0x080c, 0x32f0, 0x1140, 0x7010, 0x9084,
-	0xff00, 0x8007, 0x908e, 0x0008, 0x1108, 0x0009, 0x0005, 0x00b6,
-	0x00c6, 0x0046, 0x7000, 0x908c, 0xff00, 0x810f, 0x9186, 0x0033,
-	0x11e8, 0x080c, 0x82bb, 0x0904, 0x80b0, 0x7124, 0x610a, 0x7030,
-	0x908e, 0x0200, 0x1140, 0x7034, 0x9005, 0x15d0, 0x2009, 0x0015,
-	0x080c, 0xaeda, 0x04a8, 0x908e, 0x0100, 0x1590, 0x7034, 0x9005,
-	0x1578, 0x2009, 0x0016, 0x080c, 0xaeda, 0x0450, 0x9186, 0x0032,
-	0x1538, 0x7030, 0x908e, 0x1400, 0x1518, 0x2009, 0x0038, 0x0016,
-	0x2011, 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x284b, 0x11b8,
-	0x080c, 0x65b5, 0x11a0, 0xbe12, 0xbd16, 0x080c, 0xae09, 0x0178,
-	0x2b08, 0x6112, 0x080c, 0xcfd4, 0x6023, 0x0004, 0x7120, 0x610a,
-	0x001e, 0x080c, 0xaeda, 0x080c, 0x96a6, 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, 0x8112, 0x9596,
-	0xfffe, 0x1120, 0x2009, 0x007e, 0x0804, 0x8112, 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, 0x80e7, 0x82ff, 0x1118, 0x9085, 0x0001, 0x0018,
-	0xc2fc, 0x2208, 0x9006, 0x00de, 0x00ee, 0x004e, 0x00be, 0x0005,
-	0x7000, 0x908c, 0xff00, 0x810f, 0x9184, 0x000f, 0x0002, 0x812f,
-	0x812f, 0x812f, 0x82cd, 0x812f, 0x8138, 0x8163, 0x81f1, 0x812f,
-	0x812f, 0x812f, 0x812f, 0x812f, 0x812f, 0x812f, 0x812f, 0x7817,
-	0x0140, 0x2001, 0x19ef, 0x2004, 0x9005, 0x090c, 0x96a6, 0x0005,
-	0x00b6, 0x7110, 0xd1bc, 0x01e8, 0x7120, 0x2160, 0x9c8c, 0x0007,
-	0x11c0, 0x9c8a, 0x1cd0, 0x02a8, 0x6868, 0x9c02, 0x1290, 0x7008,
+	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,
 	0x9084, 0x00ff, 0x6110, 0x2158, 0xb910, 0x9106, 0x1150, 0x700c,
-	0xb914, 0x9106, 0x1130, 0x7124, 0x610a, 0x2009, 0x0046, 0x080c,
-	0xaeda, 0x7817, 0x0140, 0x2001, 0x19ef, 0x2004, 0x9005, 0x090c,
-	0x96a6, 0x00be, 0x0005, 0x00b6, 0x00c6, 0x9484, 0x0fff, 0x0904,
-	0x81c7, 0x7110, 0xd1bc, 0x1904, 0x81c7, 0x7108, 0x700c, 0x2028,
-	0x918c, 0x00ff, 0x2130, 0x9094, 0xff00, 0x15b0, 0x81ff, 0x15a0,
-	0x9080, 0x3332, 0x200d, 0x918c, 0xff00, 0x810f, 0x2001, 0x0080,
-	0x9106, 0x0904, 0x81c7, 0x080c, 0x65b5, 0x1904, 0x81c7, 0xbe12,
-	0xbd16, 0xb800, 0xd0ec, 0x15d8, 0xba04, 0x9294, 0xff00, 0x9286,
-	0x0600, 0x11a0, 0x080c, 0xae09, 0x05e8, 0x2b08, 0x7028, 0x604a,
-	0x702c, 0x6046, 0x6112, 0x6023, 0x0006, 0x7120, 0x610a, 0x7130,
-	0x6156, 0x2009, 0x0044, 0x080c, 0xdb94, 0x0408, 0x080c, 0x6989,
-	0x1138, 0xb807, 0x0606, 0x0c30, 0x190c, 0x80b4, 0x11c0, 0x0898,
-	0x080c, 0xae09, 0x2b08, 0x0198, 0x6112, 0x6023, 0x0004, 0x7120,
-	0x610a, 0x9286, 0x0400, 0x1118, 0x6007, 0x0005, 0x0010, 0x6007,
-	0x0001, 0x6003, 0x0001, 0x080c, 0x9140, 0x080c, 0x96a6, 0x7817,
-	0x0140, 0x2001, 0x19ef, 0x2004, 0x9005, 0x090c, 0x96a6, 0x00ce,
-	0x00be, 0x0005, 0x2001, 0x180e, 0x2004, 0xd0ec, 0x0120, 0x2011,
-	0x8049, 0x080c, 0x4b1e, 0x080c, 0xaead, 0x0d48, 0x2b08, 0x6112,
-	0x6023, 0x0006, 0x7120, 0x610a, 0x7130, 0x6156, 0x6017, 0xf300,
-	0x6003, 0x0001, 0x6007, 0x0041, 0x080c, 0x90f8, 0x080c, 0x96a6,
-	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, 0xaeda, 0x7817, 0x0140, 0x2001, 0x19ef, 0x2004, 0x9005,
-	0x090c, 0x96a6, 0x00be, 0x0005, 0x6120, 0x9186, 0x0002, 0x0128,
-	0x9186, 0x0005, 0x0110, 0x9085, 0x0001, 0x0005, 0x080c, 0x32f0,
-	0x1168, 0x7010, 0x9084, 0xff00, 0x8007, 0x9086, 0x0000, 0x1130,
-	0x9184, 0x000f, 0x908a, 0x0006, 0x1208, 0x000b, 0x0005, 0x823d,
-	0x823e, 0x823d, 0x823d, 0x829d, 0x82ac, 0x0005, 0x00b6, 0x7110,
-	0xd1bc, 0x0120, 0x702c, 0xd084, 0x0904, 0x829b, 0x700c, 0x7108,
-	0x080c, 0x284b, 0x1904, 0x829b, 0x080c, 0x65b5, 0x1904, 0x829b,
-	0xbe12, 0xbd16, 0x7110, 0xd1bc, 0x01d8, 0x080c, 0x6989, 0x0118,
-	0x9086, 0x0004, 0x1588, 0x00c6, 0x080c, 0x82bb, 0x00ce, 0x05d8,
-	0x080c, 0xae09, 0x2b08, 0x05b8, 0x6112, 0x080c, 0xcfd4, 0x6023,
-	0x0002, 0x7120, 0x610a, 0x2009, 0x0088, 0x080c, 0xaeda, 0x0458,
-	0x080c, 0x6989, 0x0148, 0x9086, 0x0004, 0x0130, 0x080c, 0x6991,
-	0x0118, 0x9086, 0x0004, 0x1180, 0x080c, 0xae09, 0x2b08, 0x01d8,
-	0x6112, 0x080c, 0xcfd4, 0x6023, 0x0005, 0x7120, 0x610a, 0x2009,
-	0x0088, 0x080c, 0xaeda, 0x0078, 0x080c, 0xae09, 0x2b08, 0x0158,
-	0x6112, 0x080c, 0xcfd4, 0x6023, 0x0004, 0x7120, 0x610a, 0x2009,
-	0x0001, 0x080c, 0xaeda, 0x00be, 0x0005, 0x7110, 0xd1bc, 0x0158,
-	0x00d1, 0x0148, 0x080c, 0x821c, 0x1130, 0x7124, 0x610a, 0x2009,
-	0x0089, 0x080c, 0xaeda, 0x0005, 0x7110, 0xd1bc, 0x0158, 0x0059,
-	0x0148, 0x080c, 0x821c, 0x1130, 0x7124, 0x610a, 0x2009, 0x008a,
-	0x080c, 0xaeda, 0x0005, 0x7020, 0x2060, 0x9c84, 0x0007, 0x1158,
+	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, 0xaeda, 0x7817, 0x0140, 0x2001, 0x19ef,
-	0x2004, 0x9005, 0x090c, 0x96a6, 0x00be, 0x0005, 0x2031, 0x0105,
+	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,
-	0xae09, 0x05b8, 0x0066, 0x00c6, 0x0046, 0x2011, 0x0263, 0x2204,
-	0x8211, 0x220c, 0x080c, 0x284b, 0x15a0, 0x080c, 0x65b5, 0x1588,
-	0xbe12, 0xbd16, 0x2b00, 0x004e, 0x00ce, 0x6012, 0x080c, 0xcfd4,
+	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, 0x9140, 0x080c,
-	0x96a6, 0x00fe, 0x009e, 0x00ce, 0x0005, 0x080c, 0xae5f, 0x006e,
+	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, 0x83ab, 0x9186,
-	0x0022, 0x15f0, 0x2001, 0x0111, 0x2004, 0x9005, 0x1904, 0x83ad,
-	0x7030, 0x908e, 0x0400, 0x0904, 0x83ad, 0x908e, 0x6000, 0x05e8,
+	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, 0x6947, 0x0588,
+	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, 0x82bb, 0x0128, 0x6004, 0x9086,
+	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, 0xbe19, 0x1178, 0xd48c, 0x0148, 0x20a9,
-	0x0004, 0x2019, 0x1801, 0x2011, 0x027e, 0x080c, 0xbe19, 0x1120,
+	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, 0xbe19, 0x1178, 0xd48c, 0x0148, 0x20a9,
-	0x0004, 0x2019, 0x1801, 0x2011, 0x0276, 0x080c, 0xbe19, 0x1120,
+	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,
-	0x2071, 0x19f9, 0x7003, 0x0003, 0x700f, 0x0361, 0x9006, 0x701a,
-	0x7072, 0x7012, 0x7017, 0x1cd0, 0x7007, 0x0000, 0x7026, 0x702b,
-	0xa2a5, 0x7032, 0x7037, 0xa30d, 0x703f, 0xffff, 0x7042, 0x7047,
-	0x5581, 0x704a, 0x705b, 0x859a, 0x080c, 0x1018, 0x090c, 0x0dd5,
-	0x2900, 0x703a, 0xa867, 0x0003, 0xa86f, 0x0100, 0xa8ab, 0xdcb0,
-	0x0005, 0x2071, 0x19f9, 0x1d04, 0x84e8, 0x2091, 0x6000, 0x700c,
-	0x8001, 0x700e, 0x1530, 0x2001, 0x013c, 0x2004, 0x9005, 0x190c,
-	0x85df, 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, 0xa42a,
-	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, 0x8510, 0x8511, 0x852d, 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, 0x6616, 0x1168, 0xb888, 0x8001,
-	0x0250, 0xb88a, 0x1140, 0x0126, 0x2091, 0x8000, 0x0016, 0x080c,
-	0x96a6, 0x001e, 0x012e, 0x8108, 0x9182, 0x0800, 0x0218, 0x900e,
-	0x7007, 0x0002, 0x7112, 0x00be, 0x0005, 0x7014, 0x2060, 0x0126,
-	0x2091, 0x8000, 0x6040, 0x9005, 0x0128, 0x8001, 0x6042, 0x1110,
-	0x080c, 0xce65, 0x6018, 0x9005, 0x0558, 0x8001, 0x601a, 0x1540,
-	0x6120, 0x9186, 0x0003, 0x0148, 0x9186, 0x0006, 0x0130, 0x9186,
-	0x0009, 0x11e0, 0x611c, 0xd1c4, 0x1100, 0x080c, 0xcb5a, 0x01b0,
-	0x6014, 0x2048, 0xa884, 0x908a, 0x199a, 0x0280, 0x9082, 0x1999,
-	0xa886, 0x908a, 0x199a, 0x0210, 0x2001, 0x1999, 0x8003, 0x800b,
-	0x810b, 0x9108, 0x611a, 0xa87c, 0xd0e4, 0x0110, 0x080c, 0xc846,
-	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, 0x8459, 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, 0x868d, 0xd0b4, 0x1168, 0xd0bc, 0x1904, 0x8666, 0x2009,
-	0x0006, 0x080c, 0x86ba, 0x0005, 0x900e, 0x0c60, 0x2001, 0x1999,
-	0x08b0, 0xd0fc, 0x0160, 0x908c, 0x0003, 0x0120, 0x918e, 0x0003,
-	0x1904, 0x86b4, 0x908c, 0x2020, 0x918e, 0x2020, 0x01a8, 0x6024,
-	0xd0d4, 0x11e8, 0x2009, 0x1869, 0x2104, 0xd084, 0x1138, 0x87ff,
-	0x1120, 0x2009, 0x0043, 0x0804, 0xaeda, 0x0005, 0x87ff, 0x1de8,
-	0x2009, 0x0042, 0x0804, 0xaeda, 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, 0x86b4, 0x908c,
-	0x2020, 0x918e, 0x2020, 0x0170, 0x0076, 0x00f6, 0x2c78, 0x080c,
-	0x1727, 0x00fe, 0x007e, 0x87ff, 0x1120, 0x2009, 0x0042, 0x080c,
-	0xaeda, 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, 0xaeda, 0x0005,
-	0x00b9, 0x0ce8, 0x87ff, 0x1dd8, 0x2009, 0x0043, 0x080c, 0xaeda,
-	0x0cb0, 0x6110, 0x00b6, 0x2158, 0xb900, 0x00be, 0xd1ac, 0x0d20,
-	0x6124, 0xc1cd, 0x6126, 0x0c00, 0x2009, 0x0004, 0x0019, 0x0005,
-	0x2009, 0x0001, 0x0096, 0x080c, 0xcb5a, 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,
-	0x6acf, 0x6014, 0x904d, 0x0076, 0x2039, 0x0000, 0x190c, 0x8603,
-	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, 0x0178, 0xc084, 0x7007,
-	0x0001, 0x700f, 0x0000, 0x0006, 0x2009, 0x181d, 0x2104, 0x9082,
-	0x0007, 0x2009, 0x1ac7, 0x200a, 0x000e, 0xc095, 0x7012, 0x2008,
-	0x2001, 0x003b, 0x080c, 0x15f0, 0x9006, 0x2071, 0x193c, 0x7002,
-	0x7006, 0x702a, 0x00ee, 0x009e, 0x0005, 0x00e6, 0x0126, 0x0156,
-	0x2091, 0x8000, 0x2071, 0x1800, 0x7154, 0x2001, 0x0008, 0x910a,
-	0x0638, 0x2001, 0x187d, 0x20ac, 0x9006, 0x9080, 0x0008, 0x1f04,
-	0x876d, 0x71c0, 0x9102, 0x02e0, 0x2071, 0x1877, 0x20a9, 0x0007,
-	0x00c6, 0x080c, 0xae09, 0x6023, 0x0009, 0x6003, 0x0004, 0x601f,
-	0x0101, 0x0089, 0x0126, 0x2091, 0x8000, 0x080c, 0x88f3, 0x012e,
-	0x1f04, 0x8779, 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, 0xa86a, 0xa87a, 0xa8aa, 0xa887,
-	0x0005, 0xa87f, 0x0020, 0x7008, 0xa89a, 0x7010, 0xa89e, 0xae8a,
-	0xa8af, 0xffff, 0xa8b3, 0x0000, 0x8109, 0x0160, 0x080c, 0x0fff,
-	0x090c, 0x0dd5, 0xad66, 0x2b00, 0xa802, 0x2900, 0xb806, 0x2058,
-	0x8109, 0x1da0, 0x002e, 0x004e, 0x005e, 0x008e, 0x009e, 0x00be,
-	0x00ee, 0x0005, 0x2079, 0x0000, 0x2071, 0x1923, 0x7004, 0x004b,
-	0x700c, 0x0002, 0x87e5, 0x87de, 0x87de, 0x0005, 0x87ef, 0x8850,
-	0x8850, 0x8850, 0x8851, 0x8862, 0x8862, 0x700c, 0x0cba, 0x0126,
-	0x2091, 0x8000, 0x78a0, 0x79a0, 0x9106, 0x0128, 0x78a0, 0x79a0,
-	0x9106, 0x1904, 0x8843, 0x2001, 0x0005, 0x2004, 0xd0bc, 0x0130,
-	0x2011, 0x0004, 0x2204, 0xc0c5, 0x2012, 0x0ca8, 0x012e, 0x7018,
-	0x910a, 0x1130, 0x7030, 0x9005, 0x05a8, 0x080c, 0x8891, 0x0490,
+	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,
+	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,
+	0x0009, 0x6003, 0x0004, 0x601f, 0x0101, 0x0089, 0x0126, 0x2091,
+	0x8000, 0x080c, 0x89a7, 0x012e, 0x1f04, 0x8835, 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,
+	0xa86a, 0xa87a, 0xa8aa, 0xa887, 0x0005, 0xa87f, 0x0020, 0x7008,
+	0xa89a, 0x7010, 0xa89e, 0xae8a, 0xa8af, 0xffff, 0xa8b3, 0x0000,
+	0x8109, 0x0160, 0x080c, 0x0fff, 0x090c, 0x0dd5, 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,
 	0x1210, 0x7114, 0x910a, 0x9192, 0x000a, 0x0210, 0x2009, 0x000a,
 	0x2001, 0x1888, 0x2014, 0x2001, 0x1935, 0x2004, 0x9100, 0x9202,
-	0x0e48, 0x080c, 0x89dd, 0x2200, 0x9102, 0x0208, 0x2208, 0x0096,
-	0x702c, 0x2048, 0xa873, 0x0001, 0xa976, 0x080c, 0x8ae6, 0x2100,
+	0x0e50, 0x080c, 0x8a9b, 0x2200, 0x9102, 0x0208, 0x2208, 0x0096,
+	0x702c, 0x2048, 0xa873, 0x0001, 0xa976, 0x080c, 0x8ba4, 0x2100,
 	0xa87e, 0xa86f, 0x0000, 0x009e, 0x0126, 0x2091, 0x8000, 0x2009,
 	0x1a17, 0x2104, 0xc085, 0x200a, 0x700f, 0x0002, 0x012e, 0x080c,
-	0x1108, 0x1de8, 0x0005, 0x2001, 0x0005, 0x2004, 0xd0bc, 0x0130,
-	0x2011, 0x0004, 0x2204, 0xc0c5, 0x2012, 0x0ca8, 0x012e, 0x0005,
-	0x0005, 0x700c, 0x0002, 0x8856, 0x8859, 0x8858, 0x080c, 0x87ed,
-	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, 0x8ae6, 0x2100, 0xaa8c, 0x9210, 0xaa8e,
-	0x1220, 0xa890, 0x9081, 0x0000, 0xa892, 0x000e, 0x009e, 0x2f08,
-	0x9188, 0x0028, 0x200a, 0x701a, 0x0005, 0x00e6, 0x2071, 0x1923,
-	0x700c, 0x0002, 0x888f, 0x888f, 0x888d, 0x700f, 0x0001, 0x00ee,
-	0x0005, 0x0126, 0x2091, 0x8000, 0x7030, 0x9005, 0x0508, 0x2078,
-	0x7814, 0x2048, 0xae88, 0x00b6, 0x2059, 0x0000, 0x080c, 0x88fc,
-	0x00be, 0x01b0, 0x00e6, 0x2071, 0x193c, 0x080c, 0x8943, 0x00ee,
-	0x0178, 0x0096, 0x080c, 0x1018, 0x2900, 0x009e, 0x0148, 0xa8aa,
-	0x04b9, 0x0041, 0x2001, 0x1946, 0x2003, 0x0000, 0x012e, 0x08c8,
-	0x012e, 0x0005, 0x00d6, 0x00c6, 0x0086, 0x00a6, 0x2940, 0x2650,
-	0x2600, 0x9005, 0x0180, 0xa864, 0x9084, 0x000f, 0x2068, 0x9d88,
-	0x209d, 0x2165, 0x0056, 0x2029, 0x0000, 0x080c, 0x8a6b, 0x080c,
-	0x2055, 0x1dd8, 0x005e, 0x00ae, 0x2001, 0x187f, 0x2004, 0xa88a,
-	0x080c, 0x1727, 0x781f, 0x0101, 0x7813, 0x0000, 0x0126, 0x2091,
-	0x8000, 0x080c, 0x8952, 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,
-	0x8bc5, 0x2005, 0x906d, 0x090c, 0x0dd5, 0x9b80, 0x8bbd, 0x2005,
-	0x9065, 0x090c, 0x0dd5, 0x6114, 0x2600, 0x9102, 0x0248, 0x6828,
-	0x9102, 0x02f0, 0x9085, 0x0001, 0x002e, 0x00ce, 0x00de, 0x0005,
-	0x6804, 0xd094, 0x0148, 0x6854, 0xd084, 0x1178, 0xc085, 0x6856,
-	0x2011, 0x8026, 0x080c, 0x4b1e, 0x684c, 0x0096, 0x904d, 0x090c,
-	0x0dd5, 0xa804, 0x8000, 0xa806, 0x009e, 0x9006, 0x2030, 0x0c20,
-	0x6854, 0xd08c, 0x1d08, 0xc08d, 0x6856, 0x2011, 0x8025, 0x080c,
-	0x4b1e, 0x684c, 0x0096, 0x904d, 0x090c, 0x0dd5, 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, 0x2069, 0x193c,
-	0x6804, 0x9080, 0x193e, 0x2f08, 0x2102, 0x6904, 0x8108, 0x9182,
-	0x0008, 0x0208, 0x900e, 0x6906, 0x9180, 0x193e, 0x2003, 0x0000,
-	0x00de, 0x0005, 0x0096, 0x00c6, 0x2060, 0x6014, 0x2048, 0xa8a8,
-	0x0096, 0x2048, 0x9005, 0x190c, 0x1031, 0x009e, 0xa8ab, 0x0000,
-	0x080c, 0x0fb1, 0x080c, 0xae5f, 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, 0x8cfa, 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, 0x15f0, 0x00ee, 0x0005, 0x0096, 0x00d6, 0x9006,
-	0x7006, 0x700e, 0x701a, 0x701e, 0x7022, 0x7016, 0x702a, 0x7026,
-	0x702f, 0x0000, 0x080c, 0x8b45, 0x0170, 0x080c, 0x8b7a, 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, 0x8b7a, 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, 0x8ae6, 0x810c, 0x2100, 0x9318, 0x8003, 0x2228, 0x2021,
-	0x0078, 0x9402, 0x9532, 0x0208, 0x2028, 0x2500, 0x8004, 0x20a8,
-	0x23a0, 0xa001, 0xa001, 0x4005, 0x2508, 0x080c, 0x8aef, 0x2130,
-	0x7014, 0x9600, 0x7016, 0x2600, 0x711c, 0x9102, 0x701e, 0x7004,
-	0x9600, 0x2008, 0x9082, 0x000a, 0x1190, 0x7000, 0x2048, 0xa800,
-	0x9005, 0x1148, 0x2009, 0x0001, 0x0026, 0x080c, 0x89dd, 0x002e,
-	0x7000, 0x2048, 0xa800, 0x7002, 0x7007, 0x0000, 0x0008, 0x7106,
-	0x2500, 0x9212, 0x1904, 0x8a1c, 0x012e, 0x00ee, 0x014e, 0x013e,
-	0x015e, 0x009e, 0x0005, 0x0016, 0x0026, 0x00e6, 0x0126, 0x2091,
-	0x8000, 0x9580, 0x8bbd, 0x2005, 0x9075, 0x090c, 0x0dd5, 0x080c,
-	0x8ac1, 0x012e, 0x9580, 0x8bb9, 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, 0x8aab, 0x8aab, 0x8aad, 0x8aab, 0x8aad,
-	0x8aab, 0x8aab, 0x8aab, 0x8aab, 0x8aab, 0x8ab3, 0x8aab, 0x8ab3,
-	0x8aab, 0x8aab, 0x8aab, 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, 0x8b89,
-	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, 0x690c, 0x6810, 0x2019, 0x0001,
-	0x2031, 0x8b2f, 0x9112, 0x0220, 0x0118, 0x8318, 0x2208, 0x0cd0,
-	0x6808, 0x9005, 0x0108, 0x8318, 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,
-	0x2d00, 0x90b8, 0x0007, 0x00e6, 0x2071, 0x1800, 0x7128, 0x6810,
-	0x2019, 0x0001, 0x910a, 0x0118, 0x0210, 0x8318, 0x0cd8, 0x2031,
-	0x8b42, 0x0870, 0x6c16, 0x00ee, 0x0005, 0x0096, 0x0046, 0x0126,
-	0x2091, 0x8000, 0x2b00, 0x9080, 0x8bc1, 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, 0x8ce5, 0xa067, 0x0023, 0x6010, 0x905d, 0x0904,
-	0x8cba, 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, 0x209d, 0x2c65, 0x9786,
-	0x0024, 0x2c05, 0x1590, 0x908a, 0x0036, 0x1a0c, 0x0dd5, 0x9082,
-	0x001b, 0x0002, 0x8c25, 0x8c25, 0x8c27, 0x8c25, 0x8c25, 0x8c25,
-	0x8c29, 0x8c25, 0x8c25, 0x8c25, 0x8c2b, 0x8c25, 0x8c25, 0x8c25,
-	0x8c2d, 0x8c25, 0x8c25, 0x8c25, 0x8c2f, 0x8c25, 0x8c25, 0x8c25,
-	0x8c31, 0x8c25, 0x8c25, 0x8c25, 0x8c33, 0x080c, 0x0dd5, 0xa180,
-	0x04b8, 0xa190, 0x04a8, 0xa1a0, 0x0498, 0xa1b0, 0x0488, 0xa1c0,
-	0x0478, 0xa1d0, 0x0468, 0xa1e0, 0x0458, 0x908a, 0x0034, 0x1a0c,
-	0x0dd5, 0x9082, 0x001b, 0x0002, 0x8c57, 0x8c55, 0x8c55, 0x8c55,
-	0x8c55, 0x8c55, 0x8c59, 0x8c55, 0x8c55, 0x8c55, 0x8c55, 0x8c55,
-	0x8c5b, 0x8c55, 0x8c55, 0x8c55, 0x8c55, 0x8c55, 0x8c5d, 0x8c55,
-	0x8c55, 0x8c55, 0x8c55, 0x8c55, 0x8c5f, 0x080c, 0x0dd5, 0xa180,
-	0x0038, 0xa198, 0x0028, 0xa1b0, 0x0018, 0xa1c8, 0x0008, 0xa1e0,
-	0x2600, 0x0002, 0x8c7b, 0x8c7d, 0x8c7f, 0x8c81, 0x8c83, 0x8c85,
-	0x8c87, 0x8c89, 0x8c8b, 0x8c8d, 0x8c8f, 0x8c91, 0x8c93, 0x8c95,
-	0x8c97, 0x8c99, 0x8c9b, 0x8c9d, 0x8c9f, 0x8ca1, 0x8ca3, 0x8ca5,
-	0x8ca7, 0x8ca9, 0x8cab, 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,
-	0x2055, 0x090c, 0x0dd5, 0x0804, 0x8bff, 0x00ae, 0x00be, 0x00ce,
-	0x00ee, 0x0005, 0xa86c, 0xa06e, 0xa870, 0xa072, 0xa077, 0x00ff,
-	0x9006, 0x0804, 0x8be1, 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, 0x4b1e, 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,
-	0x8d3a, 0x701b, 0x0202, 0xa001, 0xa001, 0x7018, 0xd094, 0x1d90,
-	0xb8ac, 0x9005, 0x01d0, 0x2060, 0x600c, 0xb8ae, 0x6003, 0x0004,
+	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,
+	0x009e, 0x0011, 0x0ca0, 0x0005, 0x0096, 0x702c, 0x2048, 0x7018,
+	0x9100, 0x7214, 0x921a, 0x1130, 0x701c, 0xa88e, 0x7020, 0xa892,
+	0x9006, 0x0068, 0x0006, 0x080c, 0x8ba4, 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,
+	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,
+	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,
+	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,
+	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,
+	0x009e, 0x9006, 0x2030, 0x0c20, 0x6854, 0xd08c, 0x1d08, 0xc08d,
+	0x6856, 0x2011, 0x8025, 0x080c, 0x4b7f, 0x684c, 0x0096, 0x904d,
+	0x090c, 0x0dd5, 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,
+	0x0096, 0x00c6, 0x2060, 0x6014, 0x2048, 0xa8a8, 0x0096, 0x2048,
+	0x9005, 0x190c, 0x1031, 0x009e, 0xa8ab, 0x0000, 0x080c, 0x0fb1,
+	0x080c, 0xaf43, 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, 0x88f3, 0x0c18, 0x2071, 0x0300, 0x701b,
+	0x080c, 0x1031, 0x080c, 0x89a7, 0x0c00, 0x2071, 0x0300, 0x701b,
 	0x0200, 0x015e, 0x012e, 0x003e, 0x00ce, 0x009e, 0x00de, 0x00ee,
-	0x0005, 0x00c6, 0x00b6, 0x0016, 0x0006, 0x0156, 0x080c, 0x284b,
-	0x015e, 0x11b0, 0x080c, 0x65b5, 0x190c, 0x0dd5, 0x000e, 0x001e,
-	0xb912, 0xb816, 0x080c, 0xae09, 0x0140, 0x2b00, 0x6012, 0x6023,
-	0x0001, 0x2009, 0x0001, 0x080c, 0xaeda, 0x00be, 0x00ce, 0x0005,
+	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, 0x8dac, 0x8dac, 0x8dac, 0x8dae,
-	0x8dff, 0x8dac, 0x8dac, 0x8dac, 0x8e62, 0x8dac, 0x8e9f, 0x8dac,
-	0x8dac, 0x8dac, 0x8dac, 0x8dac, 0x080c, 0x0dd5, 0x9182, 0x0040,
-	0x0002, 0x8dc1, 0x8dc1, 0x8dc1, 0x8dc1, 0x8dc1, 0x8dc1, 0x8dc1,
-	0x8dc1, 0x8dc1, 0x8dc3, 0x8dd8, 0x8dc1, 0x8dc1, 0x8dc1, 0x8dc1,
-	0x8deb, 0x080c, 0x0dd5, 0x0096, 0x080c, 0x9656, 0x080c, 0x97d4,
+	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, 0x6a9a, 0x080c, 0xae5f, 0x009e, 0x0005,
-	0x080c, 0x9656, 0x00d6, 0x6114, 0x080c, 0xcb5a, 0x0130, 0x0096,
-	0x6114, 0x2148, 0x080c, 0x6c94, 0x009e, 0x00de, 0x080c, 0xae5f,
-	0x080c, 0x97d4, 0x0005, 0x080c, 0x9656, 0x080c, 0x31cc, 0x6114,
-	0x0096, 0x2148, 0x080c, 0xcb5a, 0x0120, 0xa87b, 0x0029, 0x080c,
-	0x6c94, 0x009e, 0x080c, 0xae5f, 0x080c, 0x97d4, 0x0005, 0x601b,
-	0x0000, 0x9182, 0x0040, 0x0096, 0x0002, 0x8e1a, 0x8e1a, 0x8e1a,
-	0x8e1a, 0x8e1a, 0x8e1a, 0x8e1a, 0x8e1a, 0x8e1c, 0x8e1a, 0x8e1a,
-	0x8e1a, 0x8e5e, 0x8e1a, 0x8e1a, 0x8e1a, 0x8e1a, 0x8e1a, 0x8e1a,
-	0x8e22, 0x8e1a, 0x080c, 0x0dd5, 0x6114, 0x2148, 0xa938, 0x918e,
-	0xffff, 0x05e0, 0x00e6, 0x6114, 0x2148, 0x080c, 0x8bc9, 0x0096,
-	0xa8a8, 0x2048, 0x080c, 0x6a32, 0x009e, 0xa8ab, 0x0000, 0x6010,
-	0x9005, 0x0128, 0x00b6, 0x2058, 0x080c, 0x8cfa, 0x00be, 0xae88,
-	0x00b6, 0x2059, 0x0000, 0x080c, 0x88fc, 0x00be, 0x01e0, 0x2071,
-	0x193c, 0x080c, 0x8943, 0x01b8, 0x9086, 0x0001, 0x1128, 0x2001,
-	0x1946, 0x2004, 0x9005, 0x1178, 0x0096, 0x080c, 0x0fff, 0x2900,
-	0x009e, 0x0148, 0xa8aa, 0x00f6, 0x2c78, 0x080c, 0x88ba, 0x00fe,
-	0x00ee, 0x009e, 0x0005, 0x080c, 0x88f3, 0x0cd0, 0x080c, 0x8f0c,
-	0x009e, 0x0005, 0x9182, 0x0040, 0x0096, 0x0002, 0x8e76, 0x8e76,
-	0x8e76, 0x8e78, 0x8e76, 0x8e76, 0x8e76, 0x8e9d, 0x8e76, 0x8e76,
-	0x8e76, 0x8e76, 0x8e76, 0x8e76, 0x8e76, 0x8e76, 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, 0x1bba, 0x080c, 0x915d, 0x0126, 0x2091, 0x8000,
-	0x080c, 0x97d4, 0x012e, 0x009e, 0x0005, 0x080c, 0x0dd5, 0x080c,
-	0x9656, 0x080c, 0x97d4, 0x6114, 0x2148, 0xa87b, 0x0000, 0x6010,
-	0x00b6, 0x2058, 0xb8bb, 0x0500, 0x00be, 0x080c, 0x6c94, 0x080c,
-	0xae5f, 0x009e, 0x0005, 0x6000, 0x908a, 0x0016, 0x1a0c, 0x0dd5,
-	0x0096, 0x0013, 0x009e, 0x0005, 0x8ecc, 0x8ecc, 0x8ecc, 0x8ece,
-	0x8edf, 0x8ecc, 0x8ecc, 0x8ecc, 0x8ecc, 0x8ecc, 0x8ecc, 0x8ecc,
-	0x8ecc, 0x8ecc, 0x8ecc, 0x8ecc, 0x080c, 0x0dd5, 0x080c, 0xa7b7,
-	0x6114, 0x2148, 0xa87b, 0x0006, 0x6010, 0x00b6, 0x2058, 0xb8bb,
-	0x0500, 0x00be, 0x080c, 0x6c94, 0x080c, 0xae5f, 0x0005, 0x0461,
-	0x0005, 0x6000, 0x908a, 0x0016, 0x1a0c, 0x0dd5, 0x0096, 0x0013,
-	0x009e, 0x0005, 0x8efa, 0x8efa, 0x8efa, 0x8efc, 0x8f0c, 0x8efa,
-	0x8efa, 0x8efa, 0x8efa, 0x8efa, 0x8efa, 0x8efa, 0x8efa, 0x8efa,
-	0x8efa, 0x8efa, 0x080c, 0x0dd5, 0x0036, 0x00e6, 0x2071, 0x19e6,
-	0x703c, 0x9c06, 0x1120, 0x2019, 0x0000, 0x080c, 0xa5c8, 0x080c,
-	0xa7b7, 0x00ee, 0x003e, 0x0005, 0x00f6, 0x00e6, 0x601b, 0x0000,
-	0x6014, 0x2048, 0x6010, 0x9005, 0x0128, 0x00b6, 0x2058, 0x080c,
-	0x8cfa, 0x00be, 0x2071, 0x193c, 0x080c, 0x8943, 0x0160, 0x2001,
-	0x187f, 0x2004, 0xa88a, 0x2031, 0x0000, 0x2c78, 0x080c, 0x88ba,
-	0x00ee, 0x00fe, 0x0005, 0x0096, 0xa88b, 0x0000, 0xa8a8, 0x2048,
-	0x080c, 0x1031, 0x009e, 0xa8ab, 0x0000, 0x080c, 0x88f3, 0x0c80,
+	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,
-	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, 0x8f51, 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, 0x8f7b, 0x0028, 0x911a, 0x2308, 0x8210, 0x1f04,
-	0x8f7b, 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, 0xab1a, 0x0401, 0x080c, 0xab05, 0x00e9,
-	0x080c, 0xab08, 0x00d1, 0x080c, 0xab0b, 0x00b9, 0x080c, 0xab0e,
-	0x00a1, 0x080c, 0xab11, 0x0089, 0x080c, 0xab14, 0x0071, 0x080c,
-	0xab17, 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, 0x8fee, 0x9012, 0x9051, 0x8ff4,
-	0x9012, 0x8fee, 0x8fec, 0x8fec, 0x080c, 0x0dd5, 0x080c, 0x857f,
-	0x080c, 0x96a6, 0x00ce, 0x0005, 0x62c0, 0x82ff, 0x1110, 0x00ce,
-	0x0005, 0x2011, 0x5e96, 0x080c, 0x84f9, 0x7828, 0x9092, 0x00c8,
-	0x1228, 0x8000, 0x782a, 0x080c, 0x5ed6, 0x0c88, 0x62c0, 0x080c,
-	0xac56, 0x080c, 0x5e96, 0x7807, 0x0003, 0x7827, 0x0000, 0x782b,
-	0x0000, 0x0c28, 0x080c, 0x857f, 0x6220, 0xd2a4, 0x0160, 0x782b,
-	0x0000, 0x7824, 0x9065, 0x090c, 0x0dd5, 0x2009, 0x0013, 0x080c,
-	0xaeda, 0x00ce, 0x0005, 0x00c6, 0x7824, 0x9065, 0x090c, 0x0dd5,
-	0x7828, 0x9092, 0xc350, 0x12c0, 0x8000, 0x782a, 0x00ce, 0x080c,
-	0x2bb2, 0x0278, 0x00c6, 0x7924, 0x2160, 0x6010, 0x906d, 0x090c,
-	0x0dd5, 0x7807, 0x0000, 0x7827, 0x0000, 0x00ce, 0x080c, 0x96a6,
-	0x0c00, 0x080c, 0xa26b, 0x08e8, 0x2011, 0x0130, 0x2214, 0x080c,
-	0xac56, 0x080c, 0xea39, 0x2009, 0x0014, 0x080c, 0xaeda, 0x00ce,
-	0x0880, 0x2001, 0x1a02, 0x2003, 0x0000, 0x62c0, 0x82ff, 0x1160,
+	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, 0xaf2c, 0x00ce, 0x0005, 0x00b6, 0x00c6, 0x00d6, 0x7824,
-	0x9005, 0x090c, 0x0dd5, 0x7828, 0x9092, 0xc350, 0x1648, 0x8000,
-	0x782a, 0x00de, 0x00ce, 0x00be, 0x080c, 0x2bb2, 0x02f0, 0x00b6,
-	0x00c6, 0x00d6, 0x781c, 0x905d, 0x090c, 0x0dd5, 0xb800, 0xc0dc,
-	0xb802, 0x7924, 0x2160, 0x080c, 0xae5f, 0xb93c, 0x81ff, 0x090c,
-	0x0dd5, 0x8109, 0xb93e, 0x7807, 0x0000, 0x7827, 0x0000, 0x00de,
-	0x00ce, 0x00be, 0x080c, 0x96a6, 0x0868, 0x080c, 0xa26b, 0x0850,
-	0x2011, 0x0130, 0x2214, 0x080c, 0xac56, 0x080c, 0xea39, 0x7824,
-	0x9065, 0x2009, 0x0014, 0x080c, 0xaeda, 0x00de, 0x00ce, 0x00be,
-	0x0804, 0x9062, 0x00c6, 0x2001, 0x009b, 0x2004, 0xd0fc, 0x190c,
-	0x1ec1, 0x6024, 0x6027, 0x0002, 0xd0f4, 0x15b8, 0x62c8, 0x60c4,
-	0x9205, 0x1170, 0x783c, 0x9065, 0x0130, 0x2009, 0x0049, 0x080c,
-	0xaeda, 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, 0xaeda, 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, 0x96a6, 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,
-	0x91ec, 0x6010, 0x2058, 0xb8a0, 0x9206, 0x1904, 0x91e7, 0x87ff,
-	0x0120, 0x6054, 0x9106, 0x1904, 0x91e7, 0x703c, 0x9c06, 0x1178,
-	0x0036, 0x2019, 0x0001, 0x080c, 0xa5c8, 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, 0xcb5a, 0x01f0, 0x6014, 0x2048, 0x6020, 0x9086,
-	0x0003, 0x15b8, 0x6004, 0x9086, 0x0040, 0x090c, 0xa7a7, 0xa867,
-	0x0103, 0xab7a, 0xa877, 0x0000, 0x0016, 0x0036, 0x0076, 0x080c,
-	0xce4e, 0x080c, 0xe943, 0x080c, 0x6c94, 0x007e, 0x003e, 0x001e,
-	0x080c, 0xcd43, 0x080c, 0xae90, 0x00ce, 0x0804, 0x9186, 0x2c78,
-	0x600c, 0x2060, 0x0804, 0x9186, 0x85ff, 0x0120, 0x0036, 0x080c,
-	0x97d4, 0x003e, 0x012e, 0x000e, 0x001e, 0x002e, 0x003e, 0x005e,
-	0x006e, 0x007e, 0x009e, 0x00be, 0x00ce, 0x00de, 0x00ee, 0x00fe,
-	0x0005, 0x6020, 0x9086, 0x0006, 0x1158, 0x0016, 0x0036, 0x0076,
-	0x080c, 0xe943, 0x080c, 0xe58c, 0x007e, 0x003e, 0x001e, 0x0890,
-	0x6020, 0x9086, 0x0009, 0x1168, 0xa87b, 0x0006, 0x0016, 0x0036,
-	0x0076, 0x080c, 0x6c94, 0x080c, 0xae5f, 0x007e, 0x003e, 0x001e,
-	0x0818, 0x6020, 0x9086, 0x000a, 0x0904, 0x91d1, 0x0804, 0x91ca,
-	0x0006, 0x0066, 0x0096, 0x00c6, 0x00d6, 0x00f6, 0x9036, 0x0126,
-	0x2091, 0x8000, 0x2079, 0x19e6, 0x7838, 0x9065, 0x0904, 0x927d,
-	0x600c, 0x0006, 0x600f, 0x0000, 0x783c, 0x9c06, 0x1168, 0x0036,
-	0x2019, 0x0001, 0x080c, 0xa5c8, 0x7833, 0x0000, 0x901e, 0x7b3e,
-	0x7b42, 0x7b46, 0x7b4a, 0x003e, 0x080c, 0xcb5a, 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, 0xa7a7, 0xa867,
-	0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0x6c88, 0x080c, 0xcd43,
-	0x080c, 0xae90, 0x000e, 0x0804, 0x9235, 0x7e3a, 0x7e36, 0x012e,
-	0x00fe, 0x00de, 0x00ce, 0x009e, 0x006e, 0x000e, 0x0005, 0x6020,
-	0x9086, 0x0006, 0x1118, 0x080c, 0xe58c, 0x0c50, 0x6020, 0x9086,
-	0x0009, 0x1130, 0xab7a, 0x080c, 0x6c94, 0x080c, 0xae5f, 0x0c10,
-	0x6020, 0x9086, 0x000a, 0x09a8, 0x0868, 0x0016, 0x0026, 0x0086,
-	0x9046, 0x0099, 0x080c, 0x9386, 0x008e, 0x002e, 0x001e, 0x0005,
-	0x00f6, 0x0126, 0x2079, 0x19e6, 0x2091, 0x8000, 0x080c, 0x941d,
-	0x080c, 0x94ab, 0x012e, 0x00fe, 0x0005, 0x00b6, 0x0096, 0x00f6,
-	0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0016, 0x0006, 0x0126, 0x2091,
-	0x8000, 0x2071, 0x19e6, 0x7614, 0x2660, 0x2678, 0x8cff, 0x0904,
-	0x934b, 0x6010, 0x2058, 0xb8a0, 0x9206, 0x1904, 0x9346, 0x88ff,
-	0x0120, 0x6054, 0x9106, 0x1904, 0x9346, 0x7024, 0x9c06, 0x1558,
-	0x2069, 0x0100, 0x6820, 0xd0a4, 0x1508, 0x080c, 0x857f, 0x080c,
-	0xa28f, 0x68c3, 0x0000, 0x080c, 0xa7a7, 0x7027, 0x0000, 0x0036,
-	0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100,
-	0x080c, 0x2cfc, 0x9006, 0x080c, 0x2cfc, 0x2069, 0x0100, 0x6824,
-	0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x0028, 0x6003, 0x0009,
-	0x630a, 0x0804, 0x9346, 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,
-	0xcb5a, 0x01e8, 0x6020, 0x9086, 0x0003, 0x1580, 0x080c, 0xcd60,
-	0x1118, 0x080c, 0xb821, 0x0098, 0xa867, 0x0103, 0xab7a, 0xa877,
-	0x0000, 0x0016, 0x0036, 0x0086, 0x080c, 0xce4e, 0x080c, 0xe943,
-	0x080c, 0x6c94, 0x008e, 0x003e, 0x001e, 0x080c, 0xcd43, 0x080c,
-	0xae90, 0x080c, 0xa67d, 0x00ce, 0x0804, 0x92c6, 0x2c78, 0x600c,
-	0x2060, 0x0804, 0x92c6, 0x012e, 0x000e, 0x001e, 0x006e, 0x00ce,
-	0x00de, 0x00ee, 0x00fe, 0x009e, 0x00be, 0x0005, 0x6020, 0x9086,
-	0x0006, 0x1158, 0x0016, 0x0036, 0x0086, 0x080c, 0xe943, 0x080c,
-	0xe58c, 0x008e, 0x003e, 0x001e, 0x08d0, 0x080c, 0xb821, 0x6020,
-	0x9086, 0x0002, 0x1160, 0x6004, 0x0006, 0x9086, 0x0085, 0x000e,
-	0x0904, 0x932c, 0x9086, 0x008b, 0x0904, 0x932c, 0x0840, 0x6020,
-	0x9086, 0x0005, 0x1920, 0x6004, 0x0006, 0x9086, 0x0085, 0x000e,
-	0x09c8, 0x9086, 0x008b, 0x09b0, 0x0804, 0x933f, 0x00b6, 0x00a6,
-	0x0096, 0x00c6, 0x0006, 0x0126, 0x2091, 0x8000, 0x9280, 0x1000,
-	0x2004, 0x905d, 0x0904, 0x9416, 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, 0x6548, 0x0904, 0x9412, 0x7624, 0x86ff, 0x0904,
-	0x9401, 0x9680, 0x0005, 0x2004, 0x9906, 0x15d8, 0x00d6, 0x2069,
-	0x0100, 0x68c0, 0x9005, 0x0560, 0x080c, 0x857f, 0x080c, 0xa28f,
-	0x68c3, 0x0000, 0x080c, 0xa7a7, 0x7027, 0x0000, 0x0036, 0x2069,
-	0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c,
-	0x2cfc, 0x9006, 0x080c, 0x2cfc, 0x2069, 0x0100, 0x6824, 0xd084,
-	0x0110, 0x6827, 0x0001, 0x003e, 0x00de, 0x00c6, 0xb83c, 0x9005,
-	0x0110, 0x8001, 0xb83e, 0x2660, 0x080c, 0xae90, 0x00ce, 0x0048,
-	0x00de, 0x00c6, 0x2660, 0x6003, 0x0009, 0x630a, 0x00ce, 0x0804,
-	0x93b9, 0x89ff, 0x0158, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000,
-	0x080c, 0xce4e, 0x080c, 0xe943, 0x080c, 0x6c94, 0x080c, 0xa67d,
-	0x0804, 0x93b9, 0x006e, 0x00de, 0x00ee, 0x00fe, 0x012e, 0x000e,
-	0x00ce, 0x009e, 0x00ae, 0x00be, 0x0005, 0x0096, 0x0006, 0x0066,
-	0x00c6, 0x00d6, 0x9036, 0x7814, 0x9065, 0x0904, 0x947e, 0x600c,
-	0x0006, 0x600f, 0x0000, 0x7824, 0x9c06, 0x1570, 0x2069, 0x0100,
-	0x6820, 0xd0a4, 0x1508, 0x080c, 0x857f, 0x080c, 0xa28f, 0x68c3,
-	0x0000, 0x080c, 0xa7a7, 0x7827, 0x0000, 0x0036, 0x2069, 0x0140,
-	0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2cfc,
-	0x9006, 0x080c, 0x2cfc, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110,
-	0x6827, 0x0001, 0x003e, 0x0040, 0x080c, 0x6921, 0x1520, 0x6003,
-	0x0009, 0x630a, 0x2c30, 0x00f8, 0x6014, 0x2048, 0x080c, 0xcb58,
-	0x01b0, 0x6020, 0x9086, 0x0003, 0x1508, 0x080c, 0xcd60, 0x1118,
-	0x080c, 0xb821, 0x0060, 0x080c, 0x6921, 0x1168, 0xa867, 0x0103,
-	0xab7a, 0xa877, 0x0000, 0x080c, 0x6c94, 0x080c, 0xcd43, 0x080c,
-	0xae90, 0x080c, 0xa67d, 0x000e, 0x0804, 0x9424, 0x7e16, 0x7e12,
-	0x00de, 0x00ce, 0x006e, 0x000e, 0x009e, 0x0005, 0x6020, 0x9086,
-	0x0006, 0x1118, 0x080c, 0xe58c, 0x0c50, 0x080c, 0xb821, 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, 0x952b, 0xb854, 0x0006, 0x9006,
-	0xb856, 0xb85a, 0xb800, 0xc0d4, 0xc0dc, 0xb802, 0x080c, 0x6548,
-	0x0904, 0x9528, 0x7e24, 0x86ff, 0x0904, 0x951b, 0x9680, 0x0005,
-	0x2004, 0x9906, 0x1904, 0x951b, 0x00d6, 0x2069, 0x0100, 0x68c0,
-	0x9005, 0x0904, 0x9512, 0x080c, 0x857f, 0x080c, 0xa28f, 0x68c3,
-	0x0000, 0x080c, 0xa7a7, 0x7827, 0x0000, 0x0036, 0x2069, 0x0140,
-	0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2cfc,
-	0x9006, 0x080c, 0x2cfc, 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, 0xae90,
-	0x00ce, 0x0048, 0x00de, 0x00c6, 0x2660, 0x6003, 0x0009, 0x630a,
-	0x00ce, 0x0804, 0x94be, 0x89ff, 0x0138, 0xa867, 0x0103, 0xab7a,
-	0xa877, 0x0000, 0x080c, 0x6c94, 0x080c, 0xa67d, 0x0804, 0x94be,
-	0x000e, 0x0804, 0x94b2, 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, 0xa28f, 0x78c3, 0x0000, 0x080c, 0xa7a7, 0x7027,
-	0x0000, 0x0036, 0x2079, 0x0140, 0x7b04, 0x9384, 0x1000, 0x0138,
-	0x2001, 0x0100, 0x080c, 0x2cfc, 0x9006, 0x080c, 0x2cfc, 0x2079,
-	0x0100, 0x7824, 0xd084, 0x0110, 0x7827, 0x0001, 0x080c, 0xa7a7,
-	0x003e, 0x080c, 0x6548, 0x00c6, 0xb83c, 0x9005, 0x0110, 0x8001,
-	0xb83e, 0x2660, 0x080c, 0xae5f, 0x00ce, 0xa867, 0x0103, 0xab7a,
-	0xa877, 0x0000, 0x080c, 0xce4e, 0x080c, 0x6c94, 0x080c, 0xa67d,
-	0x00fe, 0x0005, 0x00b6, 0x00e6, 0x00c6, 0x2011, 0x0101, 0x2204,
-	0xc0c4, 0x2012, 0x2001, 0x180c, 0x2014, 0xc2e4, 0x2202, 0x2071,
-	0x19e6, 0x7004, 0x9084, 0x0007, 0x0002, 0x95b7, 0x95bb, 0x95d9,
-	0x9602, 0x9640, 0x95b7, 0x95d2, 0x95b5, 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, 0x6548, 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, 0x96a6, 0x0ca8,
-	0x7218, 0x721e, 0x080c, 0x96a6, 0x0c80, 0xc2ec, 0x2202, 0x080c,
-	0x97d4, 0x0c58, 0x7024, 0x9065, 0x05b8, 0x700c, 0x9c06, 0x1160,
-	0x080c, 0xa67d, 0x600c, 0x9015, 0x0120, 0x720e, 0x600f, 0x0000,
-	0x0448, 0x720e, 0x720a, 0x0430, 0x7014, 0x9c06, 0x1160, 0x080c,
-	0xa67d, 0x600c, 0x9015, 0x0120, 0x7216, 0x600f, 0x0000, 0x00d0,
-	0x7216, 0x7212, 0x00b8, 0x6020, 0x9086, 0x0003, 0x1198, 0x6010,
-	0x2058, 0x080c, 0x6548, 0xb800, 0xc0dc, 0xb802, 0x080c, 0xa67d,
-	0x701c, 0x9065, 0x0138, 0xb854, 0x9015, 0x0110, 0x721e, 0x0010,
-	0x7218, 0x721e, 0x7027, 0x0000, 0x00ce, 0x00ee, 0x00be, 0x0005,
-	0x7024, 0x9065, 0x0140, 0x080c, 0xa67d, 0x600c, 0x9015, 0x0158,
-	0x720e, 0x600f, 0x0000, 0x080c, 0xa7a7, 0x7027, 0x0000, 0x00ce,
-	0x00ee, 0x00be, 0x0005, 0x720e, 0x720a, 0x0ca8, 0x00d6, 0x2069,
-	0x19e6, 0x6830, 0x9084, 0x0003, 0x0002, 0x9663, 0x9665, 0x9689,
-	0x9661, 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, 0x97d4, 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, 0x97d4, 0x000e, 0x00de, 0x0005, 0x000e,
-	0x0002, 0x96e3, 0x97a2, 0x97a2, 0x97a2, 0x97a2, 0x97a4, 0x97a2,
-	0x96e1, 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, 0x73b3, 0x0138, 0x0006,
-	0x2009, 0x188b, 0x2104, 0xc095, 0x200a, 0x000e, 0x6807, 0x0004,
-	0x6826, 0x682b, 0x0000, 0x080c, 0x987d, 0x00ce, 0x00de, 0x0005,
-	0x6814, 0x9065, 0x0150, 0x6807, 0x0001, 0x6826, 0x682b, 0x0000,
-	0x080c, 0x987d, 0x00ce, 0x00de, 0x0005, 0x00b6, 0x00e6, 0x6a1c,
-	0x92dd, 0x0000, 0x0904, 0x978c, 0xb84c, 0x900d, 0x0118, 0xb888,
-	0x9005, 0x01a0, 0xb854, 0x905d, 0x0120, 0x920e, 0x0904, 0x978c,
-	0x0028, 0x6818, 0x920e, 0x0904, 0x978c, 0x2058, 0xb84c, 0x900d,
-	0x0d88, 0xb888, 0x9005, 0x1d70, 0x2b00, 0x681e, 0xbb3c, 0xb838,
-	0x9302, 0x1e40, 0x080c, 0xae36, 0x0904, 0x978c, 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, 0x9dca, 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, 0x6548, 0x080c, 0xac76, 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, 0x73b3, 0x0138, 0x0006, 0x2009, 0x188b, 0x2104, 0xc095,
-	0x200a, 0x000e, 0x6807, 0x0004, 0x6826, 0x682b, 0x0000, 0x080c,
-	0x987d, 0x00ce, 0x00de, 0x0005, 0x2001, 0x180c, 0x2014, 0xc2ed,
-	0x2202, 0x00de, 0x00fe, 0x0005, 0x00f6, 0x00d6, 0x2069, 0x19e6,
-	0x6830, 0x9086, 0x0000, 0x1570, 0x2001, 0x180c, 0x2014, 0xd2e4,
-	0x0130, 0xc2e4, 0x2202, 0x080c, 0x96b5, 0x2069, 0x19e6, 0x2001,
-	0x180c, 0x200c, 0xd1c4, 0x1508, 0x6838, 0x907d, 0x01d8, 0x6a04,
-	0x9296, 0x0000, 0x1904, 0x9871, 0x7920, 0x918e, 0x0009, 0x0568,
-	0x6833, 0x0001, 0x683e, 0x6847, 0x0000, 0x684b, 0x0000, 0x0126,
-	0x00f6, 0x2091, 0x2400, 0x002e, 0x080c, 0x1c53, 0x1158, 0x012e,
-	0x080c, 0xa0ec, 0x00de, 0x00fe, 0x0005, 0xc1c4, 0x2102, 0x080c,
-	0x7463, 0x08d0, 0x012e, 0x6843, 0x0000, 0x7803, 0x0002, 0x780c,
-	0x9015, 0x0140, 0x6a3a, 0x780f, 0x0000, 0x6833, 0x0000, 0x683f,
-	0x0000, 0x0c40, 0x683a, 0x6836, 0x0cc0, 0x7908, 0xd1fc, 0x1198,
+	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,
+	0x0006, 0x2009, 0x188b, 0x2104, 0xc095, 0x200a, 0x000e, 0x6807,
+	0x0004, 0x6826, 0x682b, 0x0000, 0x080c, 0x993a, 0x00ce, 0x00de,
+	0x0005, 0x2001, 0x180c, 0x2014, 0xc2ed, 0x2202, 0x00de, 0x00fe,
+	0x0005, 0x00f6, 0x00d6, 0x2069, 0x19e6, 0x6830, 0x9086, 0x0000,
+	0x1570, 0x2001, 0x180c, 0x2014, 0xd2e4, 0x0130, 0xc2e4, 0x2202,
+	0x080c, 0x9772, 0x2069, 0x19e6, 0x2001, 0x180c, 0x200c, 0xd1c4,
+	0x1508, 0x6838, 0x907d, 0x01d8, 0x6a04, 0x9296, 0x0000, 0x1904,
+	0x992e, 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,
+	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,
+	0x11f0, 0x2001, 0x188b, 0x200c, 0xc185, 0xc18c, 0x2102, 0x2f00,
 	0x6833, 0x0001, 0x683e, 0x6847, 0x0000, 0x684b, 0x0000, 0x0126,
-	0x00f6, 0x2091, 0x2400, 0x002e, 0x080c, 0x1c53, 0x19d8, 0x012e,
-	0x080c, 0xa06d, 0x0878, 0x2001, 0x1837, 0x2004, 0x9084, 0x0028,
-	0x1188, 0x2001, 0x197b, 0x2004, 0x9086, 0xaaaa, 0x0158, 0x2001,
-	0x19e7, 0x2004, 0x9005, 0x11f0, 0x2001, 0x188b, 0x200c, 0xc185,
-	0xc18c, 0x2102, 0x2f00, 0x6833, 0x0001, 0x683e, 0x6847, 0x0000,
-	0x684b, 0x0000, 0x0126, 0x00f6, 0x2091, 0x2400, 0x002e, 0x080c,
-	0x1c53, 0x1904, 0x9812, 0x012e, 0x6a3c, 0x2278, 0x080c, 0x9ff7,
-	0x0804, 0x980a, 0x2011, 0x188b, 0x2204, 0xc08d, 0x2012, 0x0804,
-	0x980a, 0x6a04, 0x9296, 0x0006, 0x1904, 0x97cc, 0x6a30, 0x9296,
-	0x0000, 0x0904, 0x97f4, 0x0804, 0x97cc, 0x6020, 0x9084, 0x000f,
-	0x000b, 0x0005, 0x9891, 0x9896, 0x9d04, 0x9d93, 0x9896, 0x9d04,
-	0x9d93, 0x9891, 0x9896, 0x9891, 0x9891, 0x9891, 0x9891, 0x9891,
-	0x9891, 0x080c, 0x959a, 0x080c, 0x96a6, 0x0005, 0x00b6, 0x0156,
-	0x0136, 0x0146, 0x01c6, 0x01d6, 0x00c6, 0x00d6, 0x00e6, 0x00f6,
-	0x2069, 0x0200, 0x2071, 0x0240, 0x6004, 0x908a, 0x0053, 0x1a0c,
-	0x0dd5, 0x6110, 0x2158, 0xb9c0, 0x2c78, 0x2061, 0x0100, 0x619a,
-	0x908a, 0x0040, 0x1a04, 0x9902, 0x005b, 0x00fe, 0x00ee, 0x00de,
-	0x00ce, 0x01de, 0x01ce, 0x014e, 0x013e, 0x015e, 0x00be, 0x0005,
-	0x9a87, 0x9ac2, 0x9aeb, 0x9b93, 0x9bb5, 0x9bbb, 0x9bc8, 0x9bd0,
-	0x9bdc, 0x9be2, 0x9bf3, 0x9be2, 0x9c4b, 0x9bd0, 0x9c57, 0x9c5d,
-	0x9bdc, 0x9c5d, 0x9c69, 0x9900, 0x9900, 0x9900, 0x9900, 0x9900,
-	0x9900, 0x9900, 0x9900, 0x9900, 0x9900, 0x9900, 0xa47f, 0xa4a2,
-	0xa4b3, 0xa4d3, 0xa505, 0x9bc8, 0x9900, 0x9bc8, 0x9be2, 0x9900,
-	0x9aeb, 0x9b93, 0x9900, 0xa89e, 0x9be2, 0x9900, 0xa8ba, 0x9be2,
-	0x9900, 0x9bdc, 0x9a81, 0x9923, 0x9900, 0xa8d6, 0xa943, 0xaa1e,
-	0x9900, 0xaa2b, 0x9bc5, 0xaa56, 0x9900, 0xa50f, 0xaa83, 0x9900,
-	0x080c, 0x0dd5, 0x2100, 0x005b, 0x00fe, 0x00ee, 0x00de, 0x00ce,
-	0x01de, 0x01ce, 0x014e, 0x013e, 0x015e, 0x00be, 0x0005, 0xab1e,
-	0xabd0, 0x9921, 0x994a, 0x99f6, 0x9a01, 0x9921, 0x9bc8, 0x9921,
-	0x9a48, 0x9a54, 0x9965, 0x9921, 0x9980, 0x99b4, 0xad3d, 0xad82,
-	0x9be2, 0x080c, 0x0dd5, 0x00d6, 0x0096, 0x080c, 0x9c7c, 0x7003,
-	0x2414, 0x7007, 0x0018, 0x700b, 0x0800, 0x7814, 0x2048, 0xa83c,
-	0x700e, 0xa850, 0x7022, 0xa854, 0x7026, 0x60c3, 0x0018, 0x080c,
-	0xa263, 0x009e, 0x00de, 0x0005, 0x7810, 0x00b6, 0x2058, 0xb8a0,
-	0x00be, 0x080c, 0xadc9, 0x1118, 0x9084, 0xff80, 0x0110, 0x9085,
-	0x0001, 0x0005, 0x00d6, 0x0096, 0x080c, 0x9c7c, 0x7003, 0x0500,
-	0x7814, 0x2048, 0xa874, 0x700a, 0xa878, 0x700e, 0xa87c, 0x7012,
-	0xa880, 0x7016, 0xa884, 0x701a, 0xa888, 0x701e, 0x60c3, 0x0010,
-	0x080c, 0xa263, 0x009e, 0x00de, 0x0005, 0x00d6, 0x0096, 0x080c,
-	0x9c7c, 0x7003, 0x0500, 0x7814, 0x2048, 0xa8cc, 0x700a, 0xa8d0,
-	0x700e, 0xa8d4, 0x7012, 0xa8d8, 0x7016, 0xa8dc, 0x701a, 0xa8e0,
-	0x701e, 0x60c3, 0x0010, 0x080c, 0xa263, 0x009e, 0x00de, 0x0005,
-	0x00d6, 0x0096, 0x0126, 0x2091, 0x8000, 0x080c, 0x9c7c, 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, 0x23c4, 0x080c, 0xd896, 0x9006, 0x080c, 0x23c4, 0x001e,
-	0xa804, 0x9005, 0x0110, 0x2048, 0x0c28, 0x04d9, 0x080c, 0xa263,
-	0x012e, 0x009e, 0x00de, 0x0005, 0x00d6, 0x0096, 0x0126, 0x2091,
-	0x8000, 0x080c, 0x9cc7, 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, 0xd896,
-	0x001e, 0xa804, 0x9005, 0x0110, 0x2048, 0x0c60, 0x0051, 0x7814,
-	0x2048, 0x080c, 0x0fb1, 0x080c, 0xa263, 0x012e, 0x009e, 0x00de,
-	0x0005, 0x60c0, 0x8004, 0x9084, 0x0003, 0x9005, 0x0130, 0x9082,
-	0x0004, 0x20a3, 0x0000, 0x8000, 0x1de0, 0x0005, 0x080c, 0x9c7c,
-	0x7003, 0x7800, 0x7808, 0x8007, 0x700a, 0x60c3, 0x0008, 0x0804,
-	0xa263, 0x00d6, 0x00e6, 0x080c, 0x9cc7, 0x7814, 0x9084, 0xff00,
-	0x2073, 0x0200, 0x8e70, 0x8e70, 0x9095, 0x0010, 0x2272, 0x8e70,
-	0x2073, 0x0034, 0x8e70, 0x2069, 0x1805, 0x20a9, 0x0004, 0x2d76,
-	0x8d68, 0x8e70, 0x1f04, 0x9a17, 0x2069, 0x1801, 0x20a9, 0x0004,
-	0x2d76, 0x8d68, 0x8e70, 0x1f04, 0x9a20, 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,
-	0x9a2e, 0x60c3, 0x004c, 0x080c, 0xa263, 0x00ee, 0x00de, 0x0005,
-	0x080c, 0x9c7c, 0x7003, 0x6300, 0x7007, 0x0028, 0x7808, 0x700e,
-	0x60c3, 0x0008, 0x0804, 0xa263, 0x00d6, 0x0026, 0x0016, 0x080c,
-	0x9cc7, 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, 0xa263, 0x001e, 0x002e, 0x00de,
-	0x0005, 0x2001, 0x1818, 0x2004, 0x609a, 0x0804, 0xa263, 0x080c,
-	0x9c7c, 0x7003, 0x5200, 0x2069, 0x1847, 0x6804, 0xd084, 0x0130,
-	0x6828, 0x0016, 0x080c, 0x287e, 0x710e, 0x001e, 0x20a9, 0x0004,
-	0x20e1, 0x0001, 0x2099, 0x1805, 0x20e9, 0x0000, 0x20a1, 0x0250,
-	0x4003, 0x20a9, 0x0004, 0x2099, 0x1801, 0x20a1, 0x0254, 0x4003,
-	0x080c, 0xadc9, 0x1120, 0xb8a0, 0x9082, 0x007f, 0x0248, 0x2001,
-	0x181f, 0x2004, 0x7032, 0x2001, 0x1820, 0x2004, 0x7036, 0x0030,
-	0x2001, 0x1818, 0x2004, 0x9084, 0x00ff, 0x7036, 0x60c3, 0x001c,
-	0x0804, 0xa263, 0x080c, 0x9c7c, 0x7003, 0x0500, 0x080c, 0xadc9,
-	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, 0xa263, 0x080c, 0x9c7c, 0x9006, 0x080c, 0x6953,
-	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, 0x9b5a, 0x00d6, 0x2069, 0x196b, 0x2001, 0x1837, 0x2004,
-	0xd0a4, 0x0188, 0x6800, 0x700a, 0x6808, 0x9084, 0x2000, 0x7012,
-	0x080c, 0xade0, 0x680c, 0x7016, 0x701f, 0x2710, 0x6818, 0x7022,
-	0x681c, 0x7026, 0x0090, 0x6800, 0x700a, 0x6804, 0x700e, 0x6808,
-	0x080c, 0x73b3, 0x1118, 0x9084, 0x37ff, 0x0010, 0x9084, 0x3fff,
-	0x7012, 0x080c, 0xade0, 0x680c, 0x7016, 0x00de, 0x20a9, 0x0004,
-	0x20e1, 0x0001, 0x2099, 0x1805, 0x20e9, 0x0000, 0x20a1, 0x0256,
-	0x4003, 0x20a9, 0x0004, 0x2099, 0x1801, 0x20a1, 0x025a, 0x4003,
-	0x00d6, 0x080c, 0xab05, 0x2069, 0x1973, 0x2071, 0x024e, 0x6800,
-	0xc0dd, 0x7002, 0x080c, 0x56e6, 0xd0e4, 0x0110, 0x680c, 0x700e,
-	0x00de, 0x04a8, 0x2001, 0x1837, 0x2004, 0xd0a4, 0x0170, 0x0016,
-	0x2001, 0x196c, 0x200c, 0x60e0, 0x9106, 0x0130, 0x2100, 0x60e3,
-	0x0000, 0x080c, 0x28bf, 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, 0xab05,
-	0x20a1, 0x024e, 0x20a9, 0x0008, 0x2099, 0x1973, 0x4003, 0x60c3,
-	0x0074, 0x0804, 0xa263, 0x080c, 0x9c7c, 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, 0x9c2c,
-	0x7026, 0x60c3, 0x0014, 0x0804, 0xa263, 0x080c, 0x9c7c, 0x7003,
-	0x5000, 0x0804, 0x9b05, 0x080c, 0x9c7c, 0x7003, 0x2110, 0x7007,
-	0x0014, 0x60c3, 0x0014, 0x0804, 0xa263, 0x080c, 0x9cbe, 0x0010,
-	0x080c, 0x9cc7, 0x7003, 0x0200, 0x60c3, 0x0004, 0x0804, 0xa263,
-	0x080c, 0x9cc7, 0x7003, 0x0100, 0x700b, 0x0003, 0x700f, 0x2a00,
-	0x60c3, 0x0008, 0x0804, 0xa263, 0x080c, 0x9cc7, 0x7003, 0x0200,
-	0x0804, 0x9b05, 0x080c, 0x9cc7, 0x7003, 0x0100, 0x782c, 0x9005,
-	0x0110, 0x700a, 0x0010, 0x700b, 0x0003, 0x7814, 0x700e, 0x60c3,
-	0x0008, 0x0804, 0xa263, 0x00d6, 0x080c, 0x9cc7, 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, 0xa263, 0x080c, 0x9cc7, 0x7003, 0x0210, 0x7007,
-	0x0014, 0x700f, 0x0100, 0x60c3, 0x0014, 0x0804, 0xa263, 0x080c,
-	0x9cc7, 0x7003, 0x0200, 0x0804, 0x9a8b, 0x080c, 0x9cc7, 0x7003,
+	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,
+	0x01d6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2069, 0x0200, 0x2071,
+	0x0240, 0x6004, 0x908a, 0x0053, 0x1a0c, 0x0dd5, 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,
+	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,
-	0xa263, 0x080c, 0x9cc7, 0x7003, 0x0100, 0x700b, 0x000b, 0x60c3,
-	0x0008, 0x0804, 0xa263, 0x0026, 0x00d6, 0x0036, 0x0046, 0x2019,
-	0x3200, 0x2021, 0x0800, 0x0040, 0x0026, 0x00d6, 0x0036, 0x0046,
-	0x2019, 0x2200, 0x2021, 0x0100, 0x080c, 0xab1a, 0xb810, 0x9305,
+	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,
+	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, 0x9485, 0x0029, 0x7012, 0x004e, 0x003e, 0x00de, 0x080c,
-	0xa251, 0x721a, 0x9f95, 0x0000, 0x7222, 0x7027, 0xffff, 0x2071,
-	0x024c, 0x002e, 0x0005, 0x0026, 0x080c, 0xab1a, 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,
-	0xab1a, 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, 0xa251,
-	0x721a, 0x7a08, 0x7222, 0x2f10, 0x7226, 0x2071, 0x024c, 0x002e,
-	0x0005, 0x080c, 0xa251, 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, 0x9d35, 0x9d44,
-	0x9d4f, 0x9d33, 0x9d33, 0x9d33, 0x9d35, 0x9d33, 0x9d33, 0x9d33,
-	0x9d33, 0x9d33, 0x9d33, 0x080c, 0x0dd5, 0x0411, 0x60c3, 0x0000,
-	0x0026, 0x080c, 0x2bb2, 0x0228, 0x2011, 0x0101, 0x2204, 0xc0c5,
-	0x2012, 0x002e, 0x0804, 0xa263, 0x0431, 0x7808, 0x700a, 0x7814,
-	0x700e, 0x7017, 0xffff, 0x60c3, 0x000c, 0x0804, 0xa263, 0x0479,
-	0x7003, 0x0003, 0x7007, 0x0300, 0x60c3, 0x0004, 0x0804, 0xa263,
-	0x0026, 0x080c, 0xab1a, 0xb810, 0x9085, 0x8100, 0x7002, 0xb814,
-	0x7006, 0x2069, 0x1800, 0x687c, 0x700a, 0x6880, 0x700e, 0x7013,
-	0x0009, 0x0804, 0x9c97, 0x0026, 0x080c, 0xab1a, 0xb810, 0x9085,
-	0x8400, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0x687c, 0x700a,
-	0x6880, 0x700e, 0x2001, 0x0099, 0x7012, 0x0804, 0x9cf9, 0x0026,
-	0x080c, 0xab1a, 0xb810, 0x9085, 0x8500, 0x7002, 0xb814, 0x7006,
-	0x2069, 0x1800, 0x687c, 0x700a, 0x6880, 0x700e, 0x2001, 0x0099,
-	0x7012, 0x0804, 0x9cf9, 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, 0x9dca, 0x9e86, 0x9e59,
-	0x9fa8, 0x9dc8, 0x9dc8, 0x9dc8, 0x9dc8, 0x9dc8, 0x9dc8, 0x9dc8,
-	0xa65a, 0xa662, 0xa66a, 0xa672, 0x9dc8, 0xaa62, 0x9dc8, 0xa652,
-	0x080c, 0x0dd5, 0x0096, 0x780b, 0xffff, 0x080c, 0x9e35, 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, 0x18ae, 0x0010, 0x080c, 0x1727, 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, 0x7a46, 0x7b14, 0x7b4a, 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, 0xa263, 0x6813, 0x0008, 0xb810, 0x9085,
-	0x0500, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0x687c, 0x700a,
-	0x6880, 0x700e, 0x7013, 0x0889, 0x080c, 0xa251, 0x721a, 0x7a08,
-	0x7222, 0x2f10, 0x7226, 0x2071, 0x024c, 0x0005, 0x00d6, 0x0096,
-	0x080c, 0x9f86, 0x7814, 0x2048, 0x080c, 0xcb58, 0x1130, 0x7814,
-	0x9084, 0x0700, 0x8007, 0x0033, 0x0010, 0x9006, 0x001b, 0x009e,
-	0x00de, 0x0005, 0x9ea4, 0x9f0d, 0x9f1d, 0x9f43, 0x9f4f, 0x9f60,
-	0x9f68, 0x9ea2, 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, 0xa263, 0xc3e5, 0x0c88,
-	0x9186, 0x0001, 0x190c, 0x0dd5, 0xaba8, 0x7824, 0xd0cc, 0x1904,
-	0x9f0a, 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, 0xa263, 0xc3e5, 0x0804, 0x9ec9, 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, 0xa263, 0x2011, 0x0028, 0x7824, 0xd0cc, 0x1128,
-	0x7216, 0x60c3, 0x0018, 0x0804, 0xa263, 0x0cd0, 0xc2e5, 0x2011,
-	0x0100, 0x7824, 0xd0cc, 0x0108, 0xc2e5, 0x7216, 0x702f, 0x0008,
-	0x7858, 0x9084, 0x00ff, 0x7036, 0x60c3, 0x0020, 0x0804, 0xa263,
-	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, 0xa251, 0x721a, 0x7a08, 0x7222, 0x2f10,
-	0x7226, 0x2071, 0x024c, 0x00de, 0x0005, 0x7013, 0x0889, 0x0c90,
-	0x0016, 0x7814, 0x9084, 0x0700, 0x8007, 0x0013, 0x001e, 0x0005,
-	0x9fb8, 0x9fb8, 0x9fba, 0x9fb8, 0x9fb8, 0x9fb8, 0x9fd4, 0x9fb8,
-	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, 0xa263, 0x2009, 0x0003, 0x0019, 0x7033,
-	0x7f00, 0x0cb0, 0x0016, 0x080c, 0xab1a, 0x001e, 0xb810, 0x9085,
-	0x0100, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0x6a7c, 0x720a,
-	0x6a80, 0x720e, 0x7013, 0x0888, 0x918d, 0x0008, 0x7116, 0x080c,
-	0xa251, 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,
+	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,
+	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, 0x2001, 0x1837, 0x2004, 0x9084, 0x0028,
-	0x0128, 0x609f, 0x0000, 0x2001, 0x0092, 0x0048, 0x6028, 0xc0bd,
-	0x602a, 0x609f, 0x00ff, 0x6027, 0xffff, 0x2001, 0x00b2, 0x6016,
-	0x2009, 0x07d0, 0x080c, 0x8584, 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, 0x3332, 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, 0x8584, 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, 0xa1c0, 0x90be, 0x000a, 0x1904,
-	0xa17c, 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, 0xaaff,
-	0x2009, 0x07d0, 0x60c4, 0x9084, 0xfff0, 0x9005, 0x0110, 0x2009,
-	0x1b58, 0x080c, 0x8584, 0x003e, 0x004e, 0x005e, 0x00ce, 0x00de,
-	0x00ee, 0x009e, 0x00be, 0x0005, 0x7804, 0x9086, 0x0040, 0x0904,
-	0xa1fc, 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, 0xaaff, 0x2009, 0x07d0, 0x60c4, 0x9084,
-	0xfff0, 0x9005, 0x0110, 0x2009, 0x1b58, 0x080c, 0x8584, 0x003e,
-	0x004e, 0x005e, 0x00ce, 0x00de, 0x00ee, 0x009e, 0x00be, 0x0005,
-	0x7814, 0x2048, 0xa87c, 0x9084, 0x0003, 0x9086, 0x0002, 0x0904,
-	0xa218, 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, 0xaadc, 0x0804, 0xa1ac, 0xb8cc, 0xd084, 0x0148, 0xb88c,
-	0x7814, 0x2048, 0xb88c, 0x7846, 0xa836, 0x2900, 0xa83a, 0xb04a,
-	0x9185, 0x0600, 0x6062, 0x6266, 0x636a, 0x646e, 0x6073, 0x0829,
-	0x6077, 0x0000, 0x60af, 0x9575, 0x60d7, 0x0000, 0x0804, 0xa18f,
-	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, 0xaaff, 0x0804, 0xa1ac, 0x080c, 0xaadc, 0x0804,
-	0xa1ac, 0x7a10, 0x00b6, 0x2258, 0xba8c, 0x8210, 0x9294, 0x00ff,
-	0xba8e, 0x00be, 0x8217, 0x0005, 0x00d6, 0x2069, 0x19e6, 0x6843,
-	0x0001, 0x00de, 0x0005, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x00f1,
-	0x080c, 0x8576, 0x0005, 0x0016, 0x2001, 0x180c, 0x200c, 0x9184,
-	0x0600, 0x9086, 0x0600, 0x0128, 0x0089, 0x080c, 0x8576, 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, 0x73b3, 0x11c0,
-	0x2001, 0x1a02, 0x2004, 0x9005, 0x15d0, 0x080c, 0x7463, 0x1160,
-	0x2061, 0x0100, 0x6020, 0xd0b4, 0x1120, 0x6024, 0xd084, 0x090c,
-	0x0dd5, 0x080c, 0x8576, 0x0458, 0x00c6, 0x2061, 0x19e6, 0x00c8,
-	0x6904, 0x9194, 0x4000, 0x0540, 0x0811, 0x080c, 0x2d0c, 0x00c6,
-	0x2061, 0x19e6, 0x6128, 0x9192, 0x0008, 0x1258, 0x8108, 0x612a,
-	0x6124, 0x00ce, 0x81ff, 0x0198, 0x080c, 0x8576, 0x080c, 0xa286,
-	0x0070, 0x6124, 0x91e5, 0x0000, 0x0140, 0x080c, 0xea39, 0x080c,
-	0x857f, 0x2009, 0x0014, 0x080c, 0xaeda, 0x00ce, 0x0000, 0x002e,
-	0x001e, 0x00de, 0x00ce, 0x0005, 0x2001, 0x1a02, 0x2004, 0x9005,
-	0x1db0, 0x00c6, 0x2061, 0x19e6, 0x6128, 0x9192, 0x0003, 0x1e08,
-	0x8108, 0x612a, 0x00ce, 0x080c, 0x8576, 0x080c, 0x5eec, 0x2009,
-	0x1846, 0x2114, 0x8210, 0x220a, 0x0c10, 0x0096, 0x00c6, 0x00d6,
-	0x00e6, 0x0016, 0x0026, 0x080c, 0x858c, 0x2071, 0x19e6, 0x713c,
-	0x81ff, 0x0904, 0xa38f, 0x2061, 0x0100, 0x2069, 0x0140, 0x080c,
-	0x73b3, 0x11e0, 0x0036, 0x2019, 0x0002, 0x080c, 0xa5c8, 0x003e,
-	0x713c, 0x2160, 0x080c, 0xea39, 0x2009, 0x004a, 0x6220, 0x9296,
-	0x0009, 0x1130, 0x6114, 0x2148, 0xa87b, 0x0006, 0x2009, 0x004a,
-	0x080c, 0xaeda, 0x080c, 0x7463, 0x0804, 0xa38f, 0x080c, 0xa39b,
-	0x0904, 0xa38f, 0x6904, 0xd1f4, 0x0904, 0xa396, 0x080c, 0x2d0c,
-	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, 0x2c5f, 0x6014, 0x9084, 0xe7fd, 0x9085, 0x0010, 0x6016,
-	0x703c, 0x2060, 0x2009, 0x0049, 0x080c, 0xaeda, 0x00c0, 0x0036,
-	0x2019, 0x0001, 0x080c, 0xa5c8, 0x003e, 0x713c, 0x2160, 0x080c,
-	0xea39, 0x2009, 0x004a, 0x6220, 0x9296, 0x0009, 0x1130, 0x6114,
-	0x2148, 0xa87b, 0x0006, 0x2009, 0x004a, 0x080c, 0xaeda, 0x002e,
-	0x001e, 0x00ee, 0x00de, 0x00ce, 0x009e, 0x0005, 0xd1ec, 0x1904,
-	0xa346, 0x0804, 0xa348, 0x00d6, 0x00c6, 0x0096, 0x703c, 0x9065,
-	0x090c, 0x0dd5, 0x2001, 0x1837, 0x2004, 0xd09c, 0x1904, 0xa427,
-	0x2001, 0x0306, 0x200c, 0x9184, 0x0030, 0x0904, 0xa427, 0x9184,
-	0x0048, 0x9086, 0x0008, 0x1904, 0xa427, 0x2001, 0x020b, 0x2004,
-	0xd0fc, 0x0904, 0xa427, 0xd08c, 0x0904, 0xa427, 0x2009, 0x1a7f,
-	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, 0x1bba, 0x0040, 0x6014, 0x2048, 0xaa3a,
-	0xa936, 0x6ac4, 0x69c8, 0xa946, 0xaa4a, 0x0126, 0x00c6, 0x2091,
-	0x2400, 0x002e, 0x080c, 0x1c53, 0x190c, 0x0dd5, 0x012e, 0x0090,
-	0x2009, 0x1a80, 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, 0x8584, 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, 0x6748, 0x0110, 0x9085, 0x0001, 0x012e, 0x000e, 0x004e,
-	0x005e, 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00be, 0x0005, 0x080c,
-	0x9c7c, 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, 0xa263, 0x080c, 0x9c7c, 0x7003, 0x0f00, 0x7808, 0xd09c,
-	0x0128, 0xb810, 0x9084, 0x00ff, 0x700a, 0xb814, 0x700e, 0x60c3,
-	0x0008, 0x0804, 0xa263, 0x0156, 0x080c, 0x9cc7, 0x7003, 0x0200,
-	0x080c, 0x85df, 0x20a9, 0x0006, 0x2011, 0xffec, 0x2019, 0xffed,
-	0x9ef0, 0x0002, 0x2305, 0x2072, 0x8e70, 0x2205, 0x2072, 0x8e70,
-	0x9398, 0x0002, 0x9290, 0x0002, 0x1f04, 0xa4c2, 0x60c3, 0x001c,
-	0x015e, 0x0804, 0xa263, 0x0016, 0x0026, 0x080c, 0x9ca3, 0x080c,
-	0x9cb5, 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, 0xa263,
-	0x002e, 0x001e, 0x0005, 0x20a9, 0x0010, 0x4003, 0x080c, 0xab05,
-	0x20a1, 0x0240, 0x22a8, 0x4003, 0x0c68, 0x080c, 0x9c7c, 0x7003,
-	0x6200, 0x7808, 0x700e, 0x60c3, 0x0008, 0x0804, 0xa263, 0x0016,
-	0x0026, 0x080c, 0x9c7c, 0x20e9, 0x0000, 0x20a1, 0x024c, 0x7814,
-	0x0096, 0x2048, 0xa800, 0x2048, 0xa860, 0x20e0, 0xa85c, 0x9080,
-	0x0023, 0x2098, 0x009e, 0x7808, 0x9088, 0x0002, 0x21a8, 0x4003,
-	0x8003, 0x60c2, 0x080c, 0xa263, 0x002e, 0x001e, 0x0005, 0x00e6,
-	0x00c6, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19e6, 0x700c,
-	0x2060, 0x8cff, 0x0178, 0x080c, 0xcd60, 0x1110, 0x080c, 0xb821,
-	0x600c, 0x0006, 0x080c, 0xcfcc, 0x080c, 0xae5f, 0x080c, 0xa67d,
-	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, 0xa28f,
-	0x6ac0, 0x68c3, 0x0000, 0x080c, 0x857f, 0x00c6, 0x2061, 0x0100,
-	0x080c, 0xac56, 0x00ce, 0x20a9, 0x01f4, 0x0461, 0x2009, 0x0013,
-	0x080c, 0xaeda, 0x000e, 0x001e, 0x002e, 0x006e, 0x00ce, 0x00de,
-	0x00ee, 0x00fe, 0x015e, 0x012e, 0x0005, 0x2001, 0x1800, 0x2004,
-	0x9096, 0x0001, 0x0d78, 0x9096, 0x0004, 0x0d60, 0x080c, 0x857f,
-	0x6814, 0x9084, 0x0001, 0x0110, 0x68a7, 0x95f5, 0x6817, 0x0008,
-	0x68c3, 0x0000, 0x2011, 0x5e96, 0x080c, 0x84f9, 0x20a9, 0x01f4,
-	0x0009, 0x08c0, 0x6824, 0xd094, 0x0140, 0x6827, 0x0004, 0x7804,
-	0x9084, 0x4000, 0x190c, 0x2d0c, 0x0090, 0xd084, 0x0118, 0x6827,
-	0x0001, 0x0010, 0x1f04, 0xa5aa, 0x7804, 0x9084, 0x1000, 0x0138,
-	0x2001, 0x0100, 0x080c, 0x2cfc, 0x9006, 0x080c, 0x2cfc, 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, 0xa633, 0x9386, 0x0002, 0x1128,
-	0x6814, 0x9084, 0x0002, 0x0904, 0xa633, 0x68af, 0x95f5, 0x6817,
-	0x0010, 0x2009, 0x00fa, 0x8109, 0x1df0, 0x69c6, 0x68cb, 0x0008,
-	0x080c, 0x858c, 0x080c, 0x2007, 0x2001, 0x0032, 0x6920, 0xd1bc,
-	0x0130, 0x8001, 0x1dd8, 0x692c, 0x918d, 0x0008, 0x692e, 0x20a9,
-	0x03e8, 0x6824, 0xd094, 0x0140, 0x6827, 0x0004, 0x7804, 0x9084,
-	0x4000, 0x190c, 0x2d0c, 0x0090, 0xd08c, 0x0118, 0x6827, 0x0002,
-	0x0010, 0x1f04, 0xa609, 0x7804, 0x9084, 0x1000, 0x0138, 0x2001,
-	0x0100, 0x080c, 0x2cfc, 0x9006, 0x080c, 0x2cfc, 0x6827, 0x4000,
-	0x6824, 0x83ff, 0x1140, 0x2009, 0x0049, 0x6020, 0x9086, 0x0009,
-	0x0110, 0x080c, 0xaeda, 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, 0x9e35, 0x7854, 0x7032, 0x7042, 0x7047,
-	0x1000, 0x00f8, 0x080c, 0x9e35, 0x7854, 0x7032, 0x7042, 0x7047,
-	0x4000, 0x00b8, 0x080c, 0x9e35, 0x7854, 0x7032, 0x7042, 0x7047,
-	0x2000, 0x0078, 0x080c, 0x9e35, 0x7854, 0x7032, 0x7042, 0x7047,
-	0x0400, 0x0038, 0x080c, 0x9e35, 0x7854, 0x7032, 0x7042, 0x7047,
-	0x0200, 0x60c3, 0x0020, 0x0804, 0xa263, 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, 0xa722, 0x8cff, 0x0904, 0xa722, 0x6020, 0x9086,
-	0x0006, 0x1904, 0xa71d, 0x88ff, 0x0138, 0x2800, 0x9c06, 0x1904,
-	0xa71d, 0x2039, 0x0000, 0x0050, 0x6010, 0x9b06, 0x1904, 0xa71d,
-	0x85ff, 0x0120, 0x6054, 0x9106, 0x1904, 0xa71d, 0x7024, 0x9c06,
-	0x15b0, 0x2069, 0x0100, 0x68c0, 0x9005, 0x1160, 0x6824, 0xd084,
-	0x0148, 0x6827, 0x0001, 0x080c, 0x857f, 0x080c, 0xa7a7, 0x7027,
-	0x0000, 0x0428, 0x080c, 0x857f, 0x6820, 0xd0b4, 0x0110, 0x68a7,
-	0x95f5, 0x6817, 0x0008, 0x68c3, 0x0000, 0x080c, 0xa7a7, 0x7027,
-	0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138,
-	0x2001, 0x0100, 0x080c, 0x2cfc, 0x9006, 0x080c, 0x2cfc, 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, 0xcb58,
-	0x0110, 0x080c, 0xe58c, 0x009e, 0x080c, 0xae90, 0x080c, 0xa67d,
-	0x88ff, 0x1190, 0x00ce, 0x0804, 0xa698, 0x2c78, 0x600c, 0x2060,
-	0x0804, 0xa698, 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, 0xa796, 0x6020, 0x9086, 0x0006,
-	0x1904, 0xa791, 0x87ff, 0x0128, 0x2700, 0x9c06, 0x1904, 0xa791,
-	0x0040, 0x6010, 0x9b06, 0x15e8, 0x85ff, 0x0118, 0x6054, 0x9106,
-	0x15c0, 0x703c, 0x9c06, 0x1168, 0x0036, 0x2019, 0x0001, 0x080c,
-	0xa5c8, 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, 0xcb58, 0x0110,
-	0x080c, 0xe58c, 0x080c, 0xae90, 0x87ff, 0x1198, 0x00ce, 0x0804,
-	0xa742, 0x2c78, 0x600c, 0x2060, 0x0804, 0xa742, 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,
-	0x959a, 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, 0xa88d, 0x6010, 0x00b6, 0x2058, 0xb8a0, 0x00be,
-	0x9206, 0x1904, 0xa888, 0x7024, 0x9c06, 0x1520, 0x2069, 0x0100,
-	0x68c0, 0x9005, 0x0904, 0xa85f, 0x080c, 0xa28f, 0x68c3, 0x0000,
-	0x080c, 0xa7a7, 0x7027, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04,
-	0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2cfc, 0x9006,
-	0x080c, 0x2cfc, 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, 0xcd4f, 0x1180, 0x080c,
-	0x31f5, 0x080c, 0xcd60, 0x1518, 0x080c, 0xb821, 0x0400, 0x080c,
-	0xa7a7, 0x6824, 0xd084, 0x09b0, 0x6827, 0x0001, 0x0898, 0x080c,
-	0xcd60, 0x1118, 0x080c, 0xb821, 0x0090, 0x6014, 0x2048, 0x080c,
-	0xcb58, 0x0168, 0x6020, 0x9086, 0x0003, 0x1508, 0xa867, 0x0103,
-	0xab7a, 0xa877, 0x0000, 0x080c, 0x6c88, 0x080c, 0xcd43, 0x080c,
-	0xcfcc, 0x080c, 0xae90, 0x080c, 0xa67d, 0x00ce, 0x0804, 0xa808,
-	0x2c78, 0x600c, 0x2060, 0x0804, 0xa808, 0x012e, 0x000e, 0x002e,
-	0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x009e, 0x0005, 0x6020,
-	0x9086, 0x0006, 0x1d20, 0x080c, 0xe58c, 0x0c08, 0x00d6, 0x080c,
-	0x9cc7, 0x7003, 0x0200, 0x7007, 0x0014, 0x60c3, 0x0014, 0x20e1,
-	0x0001, 0x2099, 0x1988, 0x20e9, 0x0000, 0x20a1, 0x0250, 0x20a9,
-	0x0004, 0x4003, 0x7023, 0x0004, 0x7027, 0x7878, 0x080c, 0xa263,
-	0x00de, 0x0005, 0x080c, 0x9cc7, 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, 0xa263, 0x00b6, 0x00d6,
-	0x0016, 0x00d6, 0x2f68, 0x2009, 0x0035, 0x080c, 0xd1d2, 0x00de,
-	0x1904, 0xa93b, 0x080c, 0x9c7c, 0x7003, 0x1300, 0x782c, 0x080c,
-	0xaa41, 0x2068, 0x6820, 0x9086, 0x0003, 0x0560, 0x7810, 0x2058,
-	0xbaa0, 0x080c, 0xadc9, 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, 0xadc9, 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,
-	0xa263, 0x00be, 0x0005, 0x781b, 0x0001, 0x7803, 0x0006, 0x001e,
-	0x00de, 0x00be, 0x0005, 0x792c, 0x9180, 0x0008, 0x200c, 0x9186,
-	0x0006, 0x01c0, 0x9186, 0x0003, 0x0904, 0xa9b6, 0x9186, 0x0005,
-	0x0904, 0xa99e, 0x9186, 0x0004, 0x05d8, 0x9186, 0x0008, 0x0904,
-	0xa9a7, 0x7807, 0x0037, 0x782f, 0x0003, 0x7817, 0x1700, 0x080c,
-	0xaa1e, 0x0005, 0x080c, 0xa9df, 0x00d6, 0x0026, 0x792c, 0x2168,
-	0x2009, 0x4000, 0x6800, 0x0002, 0xa97f, 0xa98a, 0xa981, 0xa98a,
-	0xa986, 0xa97f, 0xa97f, 0xa98a, 0xa98a, 0xa98a, 0xa98a, 0xa97f,
-	0xa97f, 0xa97f, 0xa97f, 0xa97f, 0xa98a, 0xa97f, 0xa98a, 0x080c,
-	0x0dd5, 0x6824, 0xd0e4, 0x0110, 0xd0cc, 0x0110, 0x900e, 0x0010,
-	0x2009, 0x2000, 0x682c, 0x7022, 0x6830, 0x7026, 0x0804, 0xa9d8,
-	0x080c, 0xa9df, 0x00d6, 0x0026, 0x792c, 0x2168, 0x2009, 0x4000,
-	0x6a00, 0x9286, 0x0002, 0x1108, 0x900e, 0x04d0, 0x080c, 0xa9df,
-	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, 0xa263, 0x00b6,
-	0x0036, 0x0046, 0x0056, 0x0066, 0x080c, 0x9cc7, 0x9006, 0x7003,
-	0x0200, 0x7938, 0x710a, 0x793c, 0x710e, 0x7810, 0x2058, 0xb8a0,
-	0x080c, 0xadc9, 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, 0x9cc7,
-	0x7003, 0x0100, 0x782c, 0x700a, 0x7814, 0x700e, 0x700e, 0x60c3,
-	0x0008, 0x0804, 0xa263, 0x080c, 0x9c73, 0x7003, 0x1400, 0x7838,
-	0x700a, 0x0079, 0x783c, 0x700e, 0x782c, 0x7012, 0x7830, 0x7016,
-	0x7834, 0x9084, 0x00ff, 0x8007, 0x701a, 0x60c3, 0x0010, 0x0804,
-	0xa263, 0x00e6, 0x2071, 0x0240, 0x0006, 0x00f6, 0x2078, 0x7810,
-	0x00b6, 0x2058, 0xb8cc, 0xd084, 0x0120, 0x7848, 0x702a, 0x7844,
-	0x702e, 0x00be, 0x00fe, 0x000e, 0x00ee, 0x0005, 0x080c, 0x9cbe,
-	0x7003, 0x0100, 0x782c, 0x700a, 0x7814, 0x700e, 0x60c3, 0x0008,
-	0x0804, 0xa263, 0x0021, 0x60c3, 0x0000, 0x0804, 0xa263, 0x00d6,
-	0x080c, 0xab1a, 0xb810, 0x9085, 0x0300, 0x7002, 0xb814, 0x7006,
-	0x2069, 0x1800, 0x687c, 0x700a, 0x6880, 0x700e, 0x7013, 0x0819,
-	0x080c, 0xa251, 0x721a, 0x2f10, 0x7222, 0x7a08, 0x7226, 0x2071,
-	0x024c, 0x00de, 0x0005, 0x00a9, 0x7914, 0x712a, 0x60c3, 0x0000,
-	0x60a7, 0x9575, 0x0026, 0x080c, 0x2bb2, 0x0228, 0x2011, 0x0101,
-	0x2204, 0xc0c5, 0x2012, 0x002e, 0x080c, 0xa286, 0x080c, 0x8576,
-	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, 0xab1a, 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, 0x9c7c,
-	0x0016, 0x0026, 0x0096, 0x00d6, 0x7814, 0x2048, 0x7013, 0x0138,
-	0x2001, 0x1837, 0x2004, 0x9084, 0x0028, 0x1138, 0x2001, 0x197b,
-	0x2004, 0x9086, 0xaaaa, 0x1904, 0xabbf, 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, 0xab50, 0x20a9, 0x0004,
-	0x2009, 0x1801, 0x2104, 0x2012, 0x8108, 0x8210, 0x1f04, 0xab5a,
-	0xa860, 0x20e0, 0xa85c, 0x9080, 0x0029, 0x2098, 0x2009, 0x0006,
-	0x20a9, 0x0001, 0x4002, 0x8007, 0x2012, 0x8210, 0x8109, 0x1dc0,
-	0x00d6, 0x2069, 0x0200, 0x080c, 0xab05, 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, 0x73b3, 0x0150, 0x6028, 0xc0bd, 0x602a, 0x6014,
-	0x9084, 0x1804, 0x9085, 0x0029, 0x6016, 0x0010, 0x080c, 0xa263,
-	0x080c, 0x8576, 0x00de, 0x009e, 0x002e, 0x001e, 0x0005, 0x00e6,
-	0x2071, 0x0240, 0x2001, 0x2200, 0x9085, 0x00ff, 0x7002, 0x7007,
-	0xffff, 0x2071, 0x0100, 0x709b, 0x00ff, 0x00ee, 0x0804, 0xab35,
-	0x080c, 0x9c7c, 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, 0xac11, 0x20a9,
-	0x0002, 0x2009, 0x1801, 0x2104, 0x2012, 0x8108, 0x8210, 0x1f04,
-	0xac1b, 0x00d6, 0x0016, 0x2069, 0x0200, 0x080c, 0xab05, 0x001e,
-	0x00de, 0x2071, 0x0240, 0x20a9, 0x0002, 0x2009, 0x1803, 0x2011,
-	0x0240, 0x2104, 0x2012, 0x8108, 0x8210, 0x1f04, 0xac31, 0x2009,
-	0x0008, 0x4002, 0x8007, 0x2012, 0x8210, 0x8109, 0x1dd0, 0x9006,
-	0x20a9, 0x0008, 0x2012, 0x8210, 0x1f04, 0xac42, 0x00ce, 0x60c3,
-	0x004c, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x080c, 0xa263, 0x080c,
-	0x8576, 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, 0x209b, 0x080c, 0x915d, 0x0126, 0x2091, 0x8000, 0x080c,
-	0x97d4, 0x012e, 0x009e, 0x00de, 0x0005, 0x00f6, 0x00e6, 0x00d6,
-	0x00c6, 0x00a6, 0x0096, 0x0066, 0x0126, 0x2091, 0x8000, 0x2071,
-	0x19e6, 0x760c, 0x2660, 0x2678, 0x8cff, 0x0904, 0xad29, 0x7024,
-	0x9c06, 0x1520, 0x2069, 0x0100, 0x68c0, 0x9005, 0x0904, 0xacfb,
-	0x080c, 0xa28f, 0x68c3, 0x0000, 0x080c, 0xa7a7, 0x7027, 0x0000,
+	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,
+	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,
 	0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001,
-	0x0100, 0x080c, 0x2cfc, 0x9006, 0x080c, 0x2cfc, 0x2069, 0x0100,
+	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, 0xcd4f, 0x1180, 0x080c, 0x31f5, 0x080c, 0xcd60, 0x1518,
-	0x080c, 0xb821, 0x0400, 0x080c, 0xa7a7, 0x6824, 0xd084, 0x09b0,
-	0x6827, 0x0001, 0x0898, 0x080c, 0xcd60, 0x1118, 0x080c, 0xb821,
-	0x0090, 0x6014, 0x2048, 0x080c, 0xcb58, 0x0168, 0x6020, 0x9086,
-	0x0003, 0x1520, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c,
-	0x6c94, 0x080c, 0xcd43, 0x080c, 0xcfcc, 0x080c, 0xae90, 0x080c,
-	0xa67d, 0x00ce, 0x0804, 0xacac, 0x2c78, 0x600c, 0x2060, 0x0804,
-	0xacac, 0x700f, 0x0000, 0x700b, 0x0000, 0x012e, 0x006e, 0x009e,
-	0x00ae, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x6020, 0x9086,
-	0x0006, 0x1d08, 0x080c, 0xe58c, 0x08f0, 0x00d6, 0x0156, 0x080c,
-	0x9cc7, 0x7a14, 0x82ff, 0x0138, 0x7003, 0x0100, 0x700b, 0x0003,
-	0x60c3, 0x0008, 0x0490, 0x7003, 0x0200, 0x7007, 0x0000, 0x2069,
-	0x1800, 0x901e, 0x6800, 0x9086, 0x0004, 0x1110, 0xc38d, 0x0060,
-	0x080c, 0x73b3, 0x1110, 0xc3ad, 0x0008, 0xc3a5, 0x6adc, 0xd29c,
-	0x1110, 0xd2ac, 0x0108, 0xc39d, 0x730e, 0x080c, 0x85df, 0x20a9,
-	0x0006, 0x2011, 0xffec, 0x2019, 0xffed, 0x2071, 0x0250, 0x2305,
-	0x2072, 0x8e70, 0x2205, 0x2072, 0x8e70, 0x9398, 0x0002, 0x9290,
-	0x0002, 0x1f04, 0xad6f, 0x60c3, 0x0020, 0x080c, 0xa263, 0x015e,
-	0x00de, 0x0005, 0x0156, 0x080c, 0x9cc7, 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,
-	0xa263, 0x0006, 0x2001, 0x1837, 0x2004, 0xd0ac, 0x000e, 0x0005,
-	0x2011, 0x0003, 0x080c, 0xa63e, 0x2011, 0x0002, 0x080c, 0xa648,
-	0x080c, 0xa552, 0x0036, 0x901e, 0x080c, 0xa5c8, 0x003e, 0x0005,
-	0x080c, 0x332b, 0x0188, 0x0016, 0x00b6, 0x00c6, 0x7010, 0x9085,
-	0x0020, 0x7012, 0x2009, 0x007e, 0x080c, 0x6616, 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, 0x96a6, 0x012e, 0x0cc0,
-	0x0006, 0x6000, 0x9086, 0x0000, 0x01b0, 0x601c, 0xd084, 0x190c,
-	0x1a70, 0x6017, 0x0000, 0x6023, 0x0007, 0x2001, 0x1985, 0x2004,
-	0x0006, 0x9082, 0x0051, 0x000e, 0x0208, 0x8004, 0x601a, 0x080c,
-	0xe846, 0x6043, 0x0000, 0x000e, 0x0005, 0x00e6, 0x0126, 0x2071,
-	0x1800, 0x2091, 0x8000, 0x7554, 0x9582, 0x0001, 0x0608, 0x7058,
+	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, 0x6020, 0x9084, 0x000f, 0x0002, 0xaeed, 0xaef6,
-	0xaf11, 0xaf2c, 0xd280, 0xd29d, 0xd2b8, 0xaeed, 0xaef6, 0x8d93,
-	0xaf48, 0xaeed, 0xaeed, 0xaeed, 0xaeed, 0x9186, 0x0013, 0x1128,
-	0x080c, 0x959a, 0x080c, 0x96a6, 0x0005, 0x0005, 0x0066, 0x6000,
-	0x90b2, 0x0016, 0x1a0c, 0x0dd5, 0x0013, 0x006e, 0x0005, 0xaf0f,
-	0xb68b, 0xb868, 0xaf0f, 0xb8fe, 0xb22b, 0xaf0f, 0xaf0f, 0xb60d,
-	0xbe65, 0xaf0f, 0xaf0f, 0xaf0f, 0xaf0f, 0xaf0f, 0xaf0f, 0x080c,
-	0x0dd5, 0x0066, 0x6000, 0x90b2, 0x0016, 0x1a0c, 0x0dd5, 0x0013,
-	0x006e, 0x0005, 0xaf2a, 0xc53c, 0xaf2a, 0xaf2a, 0xaf2a, 0xaf2a,
-	0xaf2a, 0xaf2a, 0xc4de, 0xc6be, 0xaf2a, 0xc57d, 0xc5fc, 0xc57d,
-	0xc5fc, 0xaf2a, 0x080c, 0x0dd5, 0x6000, 0x9082, 0x0016, 0x1a0c,
-	0x0dd5, 0x6000, 0x0002, 0xaf46, 0xbeac, 0xbf91, 0xc0c1, 0xc26c,
-	0xaf46, 0xaf46, 0xaf46, 0xbe80, 0xc46a, 0xc46d, 0xaf46, 0xaf46,
-	0xaf46, 0xaf46, 0xc49c, 0xaf46, 0xaf46, 0xaf46, 0x080c, 0x0dd5,
-	0x0066, 0x6000, 0x90b2, 0x0016, 0x1a0c, 0x0dd5, 0x0013, 0x006e,
-	0x0005, 0xaf61, 0xaf61, 0xafa4, 0xb043, 0xb0d8, 0xaf61, 0xaf61,
-	0xaf61, 0xaf63, 0xaf61, 0xaf61, 0xaf61, 0xaf61, 0xaf61, 0xaf61,
-	0xaf61, 0x080c, 0x0dd5, 0x9186, 0x004c, 0x0588, 0x9186, 0x0003,
-	0x190c, 0x0dd5, 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, 0x1bba, 0x080c, 0x915d,
-	0x0126, 0x2091, 0x8000, 0x080c, 0x97d4, 0x012e, 0x0005, 0x6010,
-	0x00b6, 0x2058, 0xbca0, 0x00be, 0x2c00, 0x080c, 0xb0fa, 0x080c,
-	0xd272, 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, 0xb00b, 0xb00b,
-	0xb006, 0xb009, 0xb00b, 0xb003, 0xaff6, 0xaff6, 0xaff6, 0xaff6,
-	0xaff6, 0xaff6, 0xaff6, 0xaff6, 0xaff6, 0xaff6, 0x00fe, 0x00ee,
-	0x00de, 0x00ce, 0x002e, 0x001e, 0x000e, 0x004e, 0x00fe, 0x009e,
-	0x00de, 0x080c, 0x0dd5, 0x080c, 0xbabd, 0x0028, 0x080c, 0xbba2,
-	0x0010, 0x080c, 0xbc98, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x002e,
-	0x001e, 0x2c00, 0xa896, 0x000e, 0x080c, 0xb1b8, 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, 0xb379,
-	0x0160, 0x000e, 0x9005, 0x0120, 0x00fe, 0x009e, 0x00de, 0x0005,
-	0x00fe, 0x009e, 0x00de, 0x0804, 0xae5f, 0x2001, 0x002c, 0x900e,
-	0x080c, 0xb21e, 0x0c70, 0x91b6, 0x0015, 0x0170, 0x91b6, 0x0016,
-	0x0158, 0x91b2, 0x0047, 0x0a0c, 0x0dd5, 0x91b2, 0x0050, 0x1a0c,
-	0x0dd5, 0x9182, 0x0047, 0x00ca, 0x2001, 0x0109, 0x2004, 0xd08c,
-	0x0198, 0x0126, 0x2091, 0x2800, 0x0006, 0x0016, 0x0026, 0x080c,
-	0x90aa, 0x002e, 0x001e, 0x000e, 0x012e, 0xa001, 0x6000, 0x9086,
-	0x0002, 0x1110, 0x0804, 0xafa4, 0x0005, 0xb076, 0xb076, 0xb078,
-	0xb0ae, 0xb076, 0xb076, 0xb076, 0xb076, 0xb0c1, 0x080c, 0x0dd5,
-	0x00d6, 0x0016, 0x0096, 0x080c, 0x9656, 0x080c, 0x97d4, 0x6003,
-	0x0004, 0x6114, 0x2148, 0xa87c, 0xd0fc, 0x01c0, 0xa878, 0xc0fc,
-	0x9005, 0x1158, 0xa894, 0x9005, 0x0140, 0x2001, 0x0000, 0x900e,
-	0x080c, 0xb21e, 0x080c, 0xae5f, 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, 0x9656,
-	0x00d6, 0x0096, 0x6114, 0x2148, 0x080c, 0xcb5a, 0x0120, 0xa87b,
-	0x0006, 0x080c, 0x6c94, 0x009e, 0x00de, 0x080c, 0xae5f, 0x0804,
-	0x97d4, 0x080c, 0x9656, 0x080c, 0x31cc, 0x080c, 0xd26f, 0x00d6,
-	0x0096, 0x6114, 0x2148, 0x080c, 0xcb5a, 0x0120, 0xa87b, 0x0029,
-	0x080c, 0x6c94, 0x009e, 0x00de, 0x080c, 0xae5f, 0x0804, 0x97d4,
-	0x9182, 0x0047, 0x0002, 0xb0e8, 0xb0ea, 0xb0e8, 0xb0e8, 0xb0e8,
-	0xb0e8, 0xb0e8, 0xb0e8, 0xb0e8, 0xb0e8, 0xb0e8, 0xb0e8, 0xb0ea,
-	0x080c, 0x0dd5, 0x00d6, 0x0096, 0x601f, 0x0000, 0x6114, 0x2148,
-	0xa87b, 0x0000, 0xa883, 0x0000, 0x080c, 0x6c94, 0x009e, 0x00de,
-	0x0804, 0xae5f, 0x0026, 0x0036, 0x0056, 0x0066, 0x0096, 0x00a6,
-	0x00f6, 0x0006, 0x080c, 0x0fff, 0x000e, 0x090c, 0x0dd5, 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, 0xc743, 0x04c0, 0x2130, 0x2009, 0x0034, 0x2011,
-	0x001f, 0x080c, 0xc743, 0x96b2, 0x0034, 0xb004, 0x904d, 0x0110,
-	0x080c, 0x0fb1, 0x080c, 0x0fff, 0x01d0, 0x8528, 0xa867, 0x0110,
-	0xa86b, 0x0000, 0x2920, 0xb406, 0x968a, 0x003d, 0x1230, 0x2608,
-	0x2011, 0x001b, 0x080c, 0xc743, 0x00b8, 0x96b2, 0x003c, 0x2009,
-	0x003c, 0x2950, 0x2011, 0x001b, 0x080c, 0xc743, 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, 0x6c94, 0x000e, 0x2048, 0x9005, 0x1db0,
-	0x00fe, 0x00ae, 0x009e, 0x006e, 0x005e, 0x003e, 0x002e, 0x0005,
-	0x00d6, 0x00f6, 0x0096, 0x0006, 0x080c, 0x0fff, 0x000e, 0x090c,
-	0x0dd5, 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, 0x6c94, 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, 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, 0xb1cd, 0x0804, 0xb1cf, 0x9085, 0x0001, 0x7817,
-	0x0000, 0x009e, 0x00fe, 0x00de, 0x001e, 0x0005, 0x00d6, 0x0036,
-	0x0096, 0x6314, 0x2348, 0xa87a, 0xa982, 0x080c, 0x6c88, 0x009e,
-	0x003e, 0x00de, 0x0005, 0x91b6, 0x0015, 0x1118, 0x080c, 0xae5f,
-	0x0030, 0x91b6, 0x0016, 0x190c, 0x0dd5, 0x080c, 0xae5f, 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, 0xcb5a, 0x0130,
-	0x6014, 0x2048, 0xa807, 0x0000, 0xa867, 0x0103, 0x009e, 0x0804,
-	0xae5f, 0x0096, 0x00d6, 0x0036, 0x7330, 0x9386, 0x0200, 0x11a8,
-	0x6010, 0x00b6, 0x2058, 0xb8cf, 0x0000, 0x00be, 0x6014, 0x9005,
-	0x0130, 0x2048, 0xa807, 0x0000, 0xa867, 0x0103, 0xab32, 0x080c,
-	0xae5f, 0x003e, 0x00de, 0x009e, 0x0005, 0x0011, 0x1d48, 0x0cc8,
-	0x0006, 0x0016, 0x080c, 0xd25a, 0x0188, 0x6014, 0x9005, 0x1170,
-	0x600b, 0x0003, 0x601b, 0x0000, 0x6043, 0x0000, 0x2009, 0x0022,
-	0x080c, 0xb663, 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,
+	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,
+	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,
+	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,
+	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, 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,
+	0x00ee, 0x00de, 0x00ce, 0x002e, 0x001e, 0x2c00, 0xa896, 0x000e,
+	0x080c, 0xb29c, 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,
+	0x00fe, 0x009e, 0x00de, 0x0005, 0x00fe, 0x009e, 0x00de, 0x0804,
+	0xaf43, 0x2001, 0x002c, 0x900e, 0x080c, 0xb302, 0x0c70, 0x91b6,
+	0x0015, 0x0170, 0x91b6, 0x0016, 0x0158, 0x91b2, 0x0047, 0x0a0c,
+	0x0dd5, 0x91b2, 0x0050, 0x1a0c, 0x0dd5, 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,
+	0xd0fc, 0x01c0, 0xa878, 0xc0fc, 0x9005, 0x1158, 0xa894, 0x9005,
+	0x0140, 0x2001, 0x0000, 0x900e, 0x080c, 0xb302, 0x080c, 0xaf43,
+	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,
+	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,
+	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,
+	0x01d0, 0x8528, 0xa867, 0x0110, 0xa86b, 0x0000, 0x2920, 0xb406,
+	0x968a, 0x003d, 0x1230, 0x2608, 0x2011, 0x001b, 0x080c, 0xc837,
+	0x00b8, 0x96b2, 0x003c, 0x2009, 0x003c, 0x2950, 0x2011, 0x001b,
+	0x080c, 0xc837, 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,
+	0x000e, 0x2048, 0x9005, 0x1db0, 0x00fe, 0x00ae, 0x009e, 0x006e,
+	0x005e, 0x003e, 0x002e, 0x0005, 0x00d6, 0x00f6, 0x0096, 0x0006,
+	0x080c, 0x0fff, 0x000e, 0x090c, 0x0dd5, 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,
+	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,
+	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,
+	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,
+	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, 0x0002, 0x2099, 0x0260, 0x20a9, 0x0020, 0x4003,
-	0x2003, 0x0000, 0x6014, 0x2048, 0xa800, 0x2048, 0xa867, 0x0103,
-	0x080c, 0xae5f, 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, 0xc743,
-	0x080c, 0xcb5a, 0x0140, 0x6014, 0x2048, 0xa807, 0x0000, 0xa864,
-	0xa8e2, 0xa867, 0x0103, 0x080c, 0xae5f, 0x001e, 0x009e, 0x0005,
-	0x0016, 0x2009, 0x0000, 0x7030, 0x9086, 0x0200, 0x0110, 0x2009,
-	0x0001, 0x0096, 0x6014, 0x904d, 0x090c, 0x0dd5, 0xa97a, 0x080c,
-	0x6c94, 0x009e, 0x080c, 0xae5f, 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, 0xc743, 0x009e,
-	0x080c, 0xcb5a, 0x0148, 0xa804, 0x9005, 0x1158, 0xa807, 0x0000,
-	0xa864, 0xa8e2, 0xa867, 0x0103, 0x080c, 0xae5f, 0x009e, 0x001e,
-	0x0005, 0x0086, 0x2040, 0xa030, 0x8007, 0x9086, 0x0100, 0x1118,
-	0x080c, 0xb821, 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, 0xd1d2, 0x001e, 0x1158, 0x622c, 0x2268,
-	0x2071, 0x026c, 0x6b20, 0x9386, 0x0003, 0x0130, 0x9386, 0x0006,
-	0x0128, 0x080c, 0xae5f, 0x0020, 0x0039, 0x0010, 0x080c, 0xb498,
-	0x002e, 0x00de, 0x00ee, 0x0005, 0x0096, 0x6814, 0x2048, 0x9186,
-	0x0015, 0x0904, 0xb480, 0x918e, 0x0016, 0x1904, 0xb496, 0x700c,
-	0x908c, 0xff00, 0x9186, 0x1700, 0x0120, 0x9186, 0x0300, 0x1904,
-	0xb45a, 0x89ff, 0x1138, 0x6800, 0x9086, 0x000f, 0x0904, 0xb43d,
-	0x0804, 0xb494, 0x6808, 0x9086, 0xffff, 0x1904, 0xb482, 0xa87c,
-	0x9084, 0x0060, 0x9086, 0x0020, 0x1128, 0xa83c, 0xa940, 0x9105,
-	0x1904, 0xb482, 0x6824, 0xd084, 0x1904, 0xb482, 0xd0b4, 0x0158,
-	0x0016, 0x2001, 0x1985, 0x200c, 0x6018, 0x9102, 0x9082, 0x0005,
-	0x001e, 0x1a04, 0xb482, 0x080c, 0xcd43, 0x685c, 0xa882, 0xa87c,
-	0xc0dc, 0xc0f4, 0xc0d4, 0xa87e, 0x0026, 0x900e, 0x6a18, 0x2001,
-	0x000a, 0x080c, 0x8f70, 0xa884, 0x920a, 0x0208, 0x8011, 0xaa86,
-	0x82ff, 0x002e, 0x1138, 0x00c6, 0x2d60, 0x080c, 0xc86d, 0x00ce,
-	0x0804, 0xb494, 0x00c6, 0xa868, 0xd0fc, 0x1118, 0x080c, 0x60c1,
-	0x0010, 0x080c, 0x64cb, 0x00ce, 0x1904, 0xb482, 0x00c6, 0x2d60,
-	0x080c, 0xae5f, 0x00ce, 0x0804, 0xb494, 0x00c6, 0x080c, 0xaead,
-	0x0198, 0x6017, 0x0000, 0x6810, 0x6012, 0x080c, 0xcfd4, 0x6023,
-	0x0003, 0x6904, 0x00c6, 0x2d60, 0x080c, 0xae5f, 0x00ce, 0x080c,
-	0xaeda, 0x00ce, 0x0804, 0xb494, 0x2001, 0x1987, 0x2004, 0x6842,
-	0x00ce, 0x04d0, 0x7008, 0x9086, 0x000b, 0x11c8, 0x6010, 0x00b6,
-	0x2058, 0xb900, 0xc1bc, 0xb902, 0x00be, 0x00c6, 0x2d60, 0xa87b,
-	0x0003, 0x080c, 0xd214, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023,
-	0x0002, 0x080c, 0x90f8, 0x080c, 0x96a6, 0x00ce, 0x00e8, 0x700c,
-	0x9086, 0x2a00, 0x1138, 0x2001, 0x1987, 0x2004, 0x6842, 0x00a0,
-	0x0479, 0x00a0, 0x89ff, 0x090c, 0x0dd5, 0x00c6, 0x00d6, 0x2d60,
-	0xa867, 0x0103, 0xa87b, 0x0003, 0x080c, 0x6ab0, 0x080c, 0xcd43,
-	0x080c, 0xae90, 0x00de, 0x00ce, 0x080c, 0xae5f, 0x009e, 0x0005,
-	0x9186, 0x0015, 0x1128, 0x2001, 0x1987, 0x2004, 0x6842, 0x0068,
-	0x918e, 0x0016, 0x1160, 0x00c6, 0x2d00, 0x2060, 0x080c, 0xe846,
-	0x080c, 0x86b8, 0x080c, 0xae5f, 0x00ce, 0x080c, 0xae5f, 0x0005,
-	0x0026, 0x0036, 0x0046, 0x7228, 0xacb0, 0xabac, 0xd2f4, 0x0130,
-	0x2001, 0x1987, 0x2004, 0x6842, 0x0804, 0xb512, 0x00c6, 0x2d60,
-	0x080c, 0xc76e, 0x00ce, 0x6804, 0x9086, 0x0050, 0x1168, 0x00c6,
-	0x2d00, 0x2060, 0x6003, 0x0001, 0x6007, 0x0050, 0x080c, 0x90f8,
-	0x080c, 0x96a6, 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, 0xcecb, 0x080c,
-	0x96a6, 0x0010, 0x080c, 0xae5f, 0x004e, 0x003e, 0x002e, 0x0005,
-	0x00e6, 0x00d6, 0x0026, 0x7008, 0x9084, 0x00ff, 0x6210, 0x00b6,
-	0x2258, 0xba10, 0x00be, 0x9206, 0x1904, 0xb57d, 0x700c, 0x6210,
-	0x00b6, 0x2258, 0xba14, 0x00be, 0x9206, 0x1904, 0xb57d, 0x6038,
-	0x2068, 0x6824, 0xc0dc, 0x6826, 0x6a20, 0x9286, 0x0007, 0x0904,
-	0xb57d, 0x9286, 0x0002, 0x0904, 0xb57d, 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, 0xcb5a, 0x090c, 0x0dd5, 0xa87b, 0x0003,
-	0x009e, 0x080c, 0xd214, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023,
-	0x0002, 0x080c, 0x90f8, 0x080c, 0x96a6, 0x00ce, 0x0030, 0x6038,
-	0x2070, 0x2001, 0x1987, 0x2004, 0x7042, 0x080c, 0xae5f, 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, 0xbe2d,
-	0x002e, 0x003e, 0x015e, 0x009e, 0x1904, 0xb5ec, 0x0096, 0x0156,
-	0x0036, 0x0026, 0x2b48, 0x9e90, 0x0014, 0x2019, 0x0006, 0x20a9,
-	0x0004, 0x080c, 0xbe2d, 0x002e, 0x003e, 0x015e, 0x009e, 0x15a0,
-	0x7238, 0xba0a, 0x733c, 0xbb0e, 0xbc00, 0xc48d, 0xbc02, 0xa804,
-	0x9005, 0x1128, 0x00fe, 0x009e, 0x00be, 0x0804, 0xb264, 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, 0xb379, 0x0130, 0x00fe, 0x009e, 0x080c, 0xae5f, 0x00be,
-	0x0005, 0x080c, 0xb821, 0x0cb8, 0x2b78, 0x00f6, 0x080c, 0x31cc,
-	0x080c, 0xd26f, 0x00fe, 0x00c6, 0x080c, 0xae09, 0x2f00, 0x6012,
-	0x6017, 0x0000, 0x6023, 0x0001, 0x6007, 0x0001, 0x6003, 0x0001,
-	0x2001, 0x0007, 0x080c, 0x6566, 0x080c, 0x6592, 0x080c, 0x9140,
-	0x080c, 0x96a6, 0x00ce, 0x0804, 0xb5bf, 0x2100, 0x91b2, 0x0053,
-	0x1a0c, 0x0dd5, 0x91b2, 0x0040, 0x1a04, 0xb675, 0x0002, 0xb663,
-	0xb663, 0xb659, 0xb663, 0xb663, 0xb663, 0xb657, 0xb657, 0xb657,
-	0xb657, 0xb657, 0xb657, 0xb657, 0xb657, 0xb657, 0xb657, 0xb657,
-	0xb657, 0xb657, 0xb657, 0xb657, 0xb657, 0xb657, 0xb657, 0xb657,
-	0xb657, 0xb657, 0xb657, 0xb657, 0xb657, 0xb657, 0xb663, 0xb657,
-	0xb663, 0xb663, 0xb657, 0xb657, 0xb657, 0xb657, 0xb657, 0xb659,
-	0xb657, 0xb657, 0xb657, 0xb657, 0xb657, 0xb657, 0xb657, 0xb657,
-	0xb657, 0xb663, 0xb663, 0xb657, 0xb657, 0xb657, 0xb657, 0xb657,
-	0xb657, 0xb657, 0xb657, 0xb657, 0xb663, 0xb657, 0xb657, 0x080c,
-	0x0dd5, 0x0066, 0x00b6, 0x6610, 0x2658, 0xb8cc, 0xc08c, 0xb8ce,
-	0x00be, 0x006e, 0x0000, 0x6003, 0x0001, 0x6106, 0x9186, 0x0032,
-	0x0118, 0x080c, 0x9140, 0x0010, 0x080c, 0x90f8, 0x0126, 0x2091,
-	0x8000, 0x080c, 0x96a6, 0x012e, 0x0005, 0x2600, 0x0002, 0xb663,
-	0xb663, 0xb689, 0xb663, 0xb663, 0xb689, 0xb689, 0xb689, 0xb689,
-	0xb663, 0xb689, 0xb663, 0xb689, 0xb663, 0xb689, 0xb689, 0xb689,
-	0xb689, 0x080c, 0x0dd5, 0x6004, 0x90b2, 0x0053, 0x1a0c, 0x0dd5,
-	0x91b6, 0x0013, 0x0904, 0xb74d, 0x91b6, 0x0027, 0x1904, 0xb708,
-	0x080c, 0x959a, 0x6004, 0x080c, 0xcd4f, 0x01b0, 0x080c, 0xcd60,
-	0x01a8, 0x908e, 0x0021, 0x0904, 0xb705, 0x908e, 0x0022, 0x1130,
-	0x080c, 0xb290, 0x0904, 0xb701, 0x0804, 0xb702, 0x908e, 0x003d,
-	0x0904, 0xb705, 0x0804, 0xb6fb, 0x080c, 0x31f5, 0x2001, 0x0007,
-	0x080c, 0x6566, 0x6010, 0x00b6, 0x2058, 0xb9a0, 0x00be, 0x080c,
-	0xb821, 0x9186, 0x007e, 0x1148, 0x2001, 0x1837, 0x2014, 0xc285,
-	0x080c, 0x73b3, 0x1108, 0xc2ad, 0x2202, 0x0036, 0x0026, 0x2019,
-	0x0028, 0x2110, 0x080c, 0xe952, 0x002e, 0x003e, 0x0016, 0x0026,
-	0x0036, 0x2110, 0x2019, 0x0028, 0x080c, 0x929d, 0x0076, 0x903e,
-	0x080c, 0x9170, 0x6010, 0x00b6, 0x905d, 0x0100, 0x00be, 0x2c08,
-	0x080c, 0xe326, 0x007e, 0x003e, 0x002e, 0x001e, 0x080c, 0xd26f,
-	0x0016, 0x080c, 0xcfcc, 0x080c, 0xae5f, 0x001e, 0x080c, 0x32c8,
-	0x080c, 0x96a6, 0x0030, 0x080c, 0xcfcc, 0x080c, 0xae5f, 0x080c,
-	0x96a6, 0x0005, 0x080c, 0xb821, 0x0cb0, 0x080c, 0xb85d, 0x0c98,
-	0x9186, 0x0014, 0x1db0, 0x080c, 0x959a, 0x6004, 0x908e, 0x0022,
-	0x1118, 0x080c, 0xb290, 0x0d68, 0x080c, 0x31cc, 0x080c, 0xd26f,
-	0x080c, 0xcd4f, 0x1190, 0x080c, 0x31f5, 0x6010, 0x00b6, 0x2058,
-	0xb9a0, 0x00be, 0x080c, 0xb821, 0x9186, 0x007e, 0x1128, 0x2001,
-	0x1837, 0x200c, 0xc185, 0x2102, 0x0870, 0x080c, 0xcd60, 0x1118,
-	0x080c, 0xb821, 0x0840, 0x6004, 0x908e, 0x0032, 0x1160, 0x00e6,
-	0x00f6, 0x2071, 0x189e, 0x2079, 0x0000, 0x080c, 0x3563, 0x00fe,
-	0x00ee, 0x0804, 0xb6fb, 0x6004, 0x908e, 0x0021, 0x0d48, 0x908e,
-	0x0022, 0x090c, 0xb821, 0x0804, 0xb6fb, 0x90b2, 0x0040, 0x1a04,
-	0xb7fd, 0x2008, 0x0002, 0xb795, 0xb796, 0xb799, 0xb79c, 0xb79f,
-	0xb7a2, 0xb793, 0xb793, 0xb793, 0xb793, 0xb793, 0xb793, 0xb793,
-	0xb793, 0xb793, 0xb793, 0xb793, 0xb793, 0xb793, 0xb793, 0xb793,
-	0xb793, 0xb793, 0xb793, 0xb793, 0xb793, 0xb793, 0xb793, 0xb793,
-	0xb793, 0xb7a5, 0xb7b2, 0xb793, 0xb7b4, 0xb7b2, 0xb793, 0xb793,
-	0xb793, 0xb793, 0xb793, 0xb7b2, 0xb7b2, 0xb793, 0xb793, 0xb793,
-	0xb793, 0xb793, 0xb793, 0xb793, 0xb793, 0xb7e4, 0xb7b2, 0xb793,
-	0xb7ae, 0xb793, 0xb793, 0xb793, 0xb7af, 0xb793, 0xb793, 0xb793,
-	0xb7b2, 0xb7db, 0xb793, 0x080c, 0x0dd5, 0x00e0, 0x2001, 0x000b,
-	0x0420, 0x2001, 0x0003, 0x0408, 0x2001, 0x0005, 0x00f0, 0x2001,
-	0x0001, 0x00d8, 0x2001, 0x0009, 0x00c0, 0x080c, 0x959a, 0x6003,
-	0x0005, 0x080c, 0xd272, 0x080c, 0x96a6, 0x0070, 0x0018, 0x0010,
-	0x080c, 0x6566, 0x0804, 0xb7f5, 0x080c, 0x959a, 0x080c, 0xd272,
-	0x6003, 0x0004, 0x080c, 0x96a6, 0x0005, 0x080c, 0x6566, 0x080c,
-	0x959a, 0x6003, 0x0002, 0x0036, 0x2019, 0x1852, 0x2304, 0x9084,
-	0xff00, 0x1120, 0x2001, 0x1985, 0x201c, 0x0040, 0x8007, 0x909a,
-	0x0004, 0x0ec0, 0x8003, 0x801b, 0x831b, 0x9318, 0x631a, 0x003e,
-	0x080c, 0x96a6, 0x0c08, 0x080c, 0x959a, 0x080c, 0xcfcc, 0x080c,
-	0xae5f, 0x080c, 0x96a6, 0x08c0, 0x00e6, 0x00f6, 0x2071, 0x189e,
-	0x2079, 0x0000, 0x080c, 0x3563, 0x00fe, 0x00ee, 0x080c, 0x959a,
-	0x080c, 0xae5f, 0x080c, 0x96a6, 0x0838, 0x080c, 0x959a, 0x6003,
-	0x0002, 0x080c, 0xd272, 0x0804, 0x96a6, 0x2600, 0x2008, 0x0002,
-	0xb814, 0xb7f5, 0xb812, 0xb7f5, 0xb7f5, 0xb812, 0xb812, 0xb812,
-	0xb812, 0xb7f5, 0xb812, 0xb7f5, 0xb812, 0xb7f5, 0xb812, 0xb812,
-	0xb812, 0xb812, 0x080c, 0x0dd5, 0x080c, 0x959a, 0x0096, 0x6014,
-	0x2048, 0x080c, 0x6c94, 0x009e, 0x080c, 0xae5f, 0x080c, 0x96a6,
-	0x0005, 0x00e6, 0x0096, 0x0026, 0x0016, 0x080c, 0xcb5a, 0x0568,
-	0x6014, 0x2048, 0xa864, 0x9086, 0x0139, 0x11a8, 0xa894, 0x9086,
-	0x0056, 0x1148, 0x080c, 0x548b, 0x0130, 0x2001, 0x0000, 0x900e,
-	0x2011, 0x4000, 0x0028, 0x2001, 0x0030, 0x900e, 0x2011, 0x4005,
-	0x080c, 0xd139, 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, 0xd058,
-	0x0804, 0xb8ed, 0x6604, 0x96b6, 0x0043, 0x1120, 0x080c, 0xd0a1,
-	0x0804, 0xb8ed, 0x6604, 0x96b6, 0x004b, 0x1120, 0x080c, 0xd0cd,
-	0x0804, 0xb8ed, 0x6604, 0x96b6, 0x0033, 0x1120, 0x080c, 0xcfee,
-	0x0804, 0xb8ed, 0x6604, 0x96b6, 0x0028, 0x1120, 0x080c, 0xcd9e,
-	0x0804, 0xb8ed, 0x6604, 0x96b6, 0x0029, 0x1120, 0x080c, 0xcddf,
-	0x0804, 0xb8ed, 0x6604, 0x96b6, 0x001f, 0x1120, 0x080c, 0xb238,
-	0x0804, 0xb8ed, 0x6604, 0x96b6, 0x0000, 0x1118, 0x080c, 0xb583,
-	0x04e0, 0x6604, 0x96b6, 0x0022, 0x1118, 0x080c, 0xb271, 0x04a8,
-	0x6604, 0x96b6, 0x0035, 0x1118, 0x080c, 0xb397, 0x0470, 0x6604,
-	0x96b6, 0x0039, 0x1118, 0x080c, 0xb518, 0x0438, 0x6604, 0x96b6,
-	0x003d, 0x1118, 0x080c, 0xb2a9, 0x0400, 0x6604, 0x96b6, 0x0044,
-	0x1118, 0x080c, 0xb2e5, 0x00c8, 0x6604, 0x96b6, 0x0049, 0x1118,
-	0x080c, 0xb326, 0x0090, 0x6604, 0x96b6, 0x0041, 0x1118, 0x080c,
-	0xb310, 0x0058, 0x91b6, 0x0015, 0x1110, 0x0063, 0x0030, 0x91b6,
-	0x0016, 0x1128, 0x00be, 0x0804, 0xbb49, 0x00be, 0x0005, 0x080c,
-	0xaef5, 0x0cd8, 0xb90a, 0xb90d, 0xb90a, 0xb954, 0xb90a, 0xbabd,
-	0xbb56, 0xb90a, 0xb90a, 0xbb1f, 0xb90a, 0xbb35, 0x0096, 0x601f,
-	0x0000, 0x6014, 0x2048, 0xa800, 0x2048, 0xa867, 0x0103, 0x009e,
-	0x0804, 0xae5f, 0xa001, 0xa001, 0x0005, 0x00e6, 0x2071, 0x1800,
-	0x7090, 0x9086, 0x0074, 0x1540, 0x080c, 0xe2f7, 0x11b0, 0x6010,
-	0x00b6, 0x2058, 0x7030, 0xd08c, 0x0128, 0xb800, 0xd0bc, 0x0110,
-	0xc0c5, 0xb802, 0x00f9, 0x00be, 0x2001, 0x0006, 0x080c, 0x6566,
-	0x080c, 0x31f5, 0x080c, 0xae5f, 0x0098, 0x2001, 0x000a, 0x080c,
-	0x6566, 0x080c, 0x31f5, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c,
-	0x9140, 0x080c, 0x96a6, 0x0020, 0x2001, 0x0001, 0x080c, 0xba8d,
-	0x00ee, 0x0005, 0x00d6, 0xb800, 0xd084, 0x0160, 0x9006, 0x080c,
-	0x6552, 0x2069, 0x1847, 0x6804, 0xd0a4, 0x0120, 0x2001, 0x0006,
-	0x080c, 0x6592, 0x00de, 0x0005, 0x00b6, 0x0096, 0x00d6, 0x2011,
-	0x1824, 0x2204, 0x9086, 0x0074, 0x1904, 0xba62, 0x6010, 0x2058,
-	0xbaa0, 0x9286, 0x007e, 0x1120, 0x080c, 0xbca3, 0x0804, 0xb9c6,
-	0x080c, 0xbc98, 0x6010, 0x2058, 0xbaa0, 0x9286, 0x0080, 0x1510,
-	0x6014, 0x9005, 0x01a8, 0x2048, 0xa864, 0x9084, 0x00ff, 0x9086,
-	0x0039, 0x1140, 0x2001, 0x0000, 0x900e, 0x2011, 0x4000, 0x080c,
-	0xd139, 0x0030, 0xa807, 0x0000, 0xa867, 0x0103, 0xa833, 0x0200,
-	0x2001, 0x0006, 0x080c, 0x6566, 0x080c, 0x31f5, 0x080c, 0xae5f,
-	0x0804, 0xba67, 0x080c, 0xba75, 0x6014, 0x9005, 0x0190, 0x2048,
-	0xa868, 0xd0f4, 0x01e8, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039,
-	0x1d08, 0x2001, 0x0000, 0x900e, 0x2011, 0x4000, 0x080c, 0xd139,
-	0x08f8, 0x080c, 0xba6b, 0x0160, 0x9006, 0x080c, 0x6552, 0x2001,
-	0x0004, 0x080c, 0x6592, 0x2001, 0x0007, 0x080c, 0x6566, 0x08a0,
-	0x2001, 0x0004, 0x080c, 0x6566, 0x6003, 0x0001, 0x6007, 0x0003,
-	0x080c, 0x9140, 0x080c, 0x96a6, 0x0804, 0xba67, 0xb85c, 0xd0e4,
-	0x01d8, 0x080c, 0xcf6e, 0x080c, 0x73b3, 0x0118, 0xd0dc, 0x1904,
-	0xb988, 0x2011, 0x1837, 0x2204, 0xc0ad, 0x2012, 0x2001, 0x196c,
-	0x2004, 0x00f6, 0x2079, 0x0100, 0x78e3, 0x0000, 0x080c, 0x28bf,
-	0x78e2, 0x00fe, 0x0804, 0xb988, 0x080c, 0xcfab, 0x2011, 0x1837,
-	0x2204, 0xc0a5, 0x2012, 0x0006, 0x080c, 0xe47c, 0x000e, 0x1904,
-	0xb988, 0xc0b5, 0x2012, 0x2001, 0x0006, 0x080c, 0x6566, 0x9006,
-	0x080c, 0x6552, 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, 0x2894, 0x00f6,
-	0x2100, 0x900e, 0x080c, 0x284b, 0x795e, 0x00fe, 0x9186, 0x0081,
-	0x01d8, 0x2009, 0x0081, 0x00c8, 0x2009, 0x00ef, 0x00f6, 0x2079,
-	0x0100, 0x79ea, 0x7932, 0x7936, 0x780c, 0xc0b5, 0x780e, 0x00fe,
-	0x080c, 0x2894, 0x00f6, 0x2079, 0x1800, 0x7982, 0x2100, 0x900e,
-	0x080c, 0x284b, 0x795e, 0x00fe, 0x8108, 0x080c, 0x65b5, 0x2b00,
-	0x00ce, 0x1904, 0xb988, 0x6012, 0x2009, 0x180f, 0x210c, 0xd19c,
-	0x0150, 0x2009, 0x027c, 0x210c, 0x918c, 0x00ff, 0xb912, 0x2009,
-	0x027d, 0x210c, 0xb916, 0x2001, 0x0002, 0x080c, 0x6566, 0x6023,
-	0x0001, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x9140, 0x080c,
-	0x96a6, 0x0028, 0x080c, 0xb821, 0x2001, 0x0001, 0x0431, 0x00de,
-	0x009e, 0x00be, 0x0005, 0x2001, 0x1810, 0x2004, 0xd0a4, 0x0120,
-	0x2001, 0x1848, 0x2004, 0xd0ac, 0x0005, 0x00e6, 0x080c, 0xe9ab,
-	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, 0x6566, 0x080c, 0x56f6, 0x1120, 0x2001,
-	0x0007, 0x080c, 0x6592, 0x2600, 0x9005, 0x11b0, 0x6014, 0x0096,
-	0x2048, 0xa868, 0x009e, 0xd0fc, 0x1178, 0x0036, 0x0046, 0x6010,
-	0x00b6, 0x2058, 0xbba0, 0x00be, 0x2021, 0x0004, 0x2011, 0x8014,
-	0x080c, 0x4b1e, 0x004e, 0x003e, 0x080c, 0x31f5, 0x6020, 0x9086,
-	0x000a, 0x1108, 0x0005, 0x0804, 0xae5f, 0x00b6, 0x00e6, 0x0026,
-	0x0016, 0x2071, 0x1800, 0x7090, 0x9086, 0x0014, 0x1904, 0xbb15,
-	0x080c, 0x56f6, 0x1170, 0x6014, 0x9005, 0x1158, 0x0036, 0x0046,
-	0x6010, 0x2058, 0xbba0, 0x2021, 0x0006, 0x080c, 0x4cd5, 0x004e,
-	0x003e, 0x00d6, 0x6010, 0x2058, 0x080c, 0x66b1, 0x080c, 0xb942,
-	0x00de, 0x080c, 0xbd69, 0x1588, 0x6010, 0x2058, 0xb890, 0x9005,
-	0x0560, 0x2001, 0x0006, 0x080c, 0x6566, 0x0096, 0x6014, 0x904d,
-	0x01d0, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x1140, 0x2001,
-	0x0000, 0x900e, 0x2011, 0x4000, 0x080c, 0xd139, 0x0060, 0xa864,
-	0x9084, 0x00ff, 0x9086, 0x0029, 0x0130, 0xa807, 0x0000, 0xa867,
-	0x0103, 0xa833, 0x0200, 0x009e, 0x080c, 0x31f5, 0x6020, 0x9086,
-	0x000a, 0x0140, 0x080c, 0xae5f, 0x0028, 0x080c, 0xb821, 0x9006,
-	0x080c, 0xba8d, 0x001e, 0x002e, 0x00ee, 0x00be, 0x0005, 0x2011,
-	0x1824, 0x2204, 0x9086, 0x0014, 0x1160, 0x2001, 0x0002, 0x080c,
-	0x6566, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x9140, 0x0804,
-	0x96a6, 0x2001, 0x0001, 0x0804, 0xba8d, 0x2030, 0x2011, 0x1824,
-	0x2204, 0x9086, 0x0004, 0x1148, 0x96b6, 0x000b, 0x1120, 0x2001,
-	0x0007, 0x080c, 0x6566, 0x0804, 0xae5f, 0x2001, 0x0001, 0x0804,
-	0xba8d, 0x0002, 0xb90a, 0xbb61, 0xb90a, 0xbba2, 0xb90a, 0xbc4f,
-	0xbb56, 0xb90a, 0xb90a, 0xbc63, 0xb90a, 0xbc75, 0x6604, 0x9686,
-	0x0003, 0x0904, 0xbabd, 0x96b6, 0x001e, 0x1110, 0x080c, 0xae5f,
-	0x0005, 0x00b6, 0x00d6, 0x00c6, 0x080c, 0xbc87, 0x11a0, 0x9006,
-	0x080c, 0x6552, 0x080c, 0x31cc, 0x080c, 0xd26f, 0x2001, 0x0002,
-	0x080c, 0x6566, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x9140,
-	0x080c, 0x96a6, 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, 0x31cc,
-	0x080c, 0xd26f, 0x2001, 0x0001, 0x080c, 0xba8d, 0x00ce, 0x00de,
-	0x00be, 0x0005, 0x0096, 0x00b6, 0x0026, 0x9016, 0x080c, 0xbc95,
-	0x00d6, 0x2069, 0x197b, 0x2d04, 0x9005, 0x0168, 0x6010, 0x2058,
-	0xb8a0, 0x9086, 0x007e, 0x1138, 0x2069, 0x1820, 0x2d04, 0x8000,
-	0x206a, 0x00de, 0x0010, 0x00de, 0x0088, 0x9006, 0x080c, 0x6552,
-	0x2001, 0x0002, 0x080c, 0x6566, 0x6003, 0x0001, 0x6007, 0x0002,
-	0x080c, 0x9140, 0x080c, 0x96a6, 0x0804, 0xbc1f, 0x080c, 0xcb5a,
-	0x01b0, 0x6014, 0x2048, 0xa864, 0x2010, 0x9086, 0x0139, 0x1138,
-	0x6007, 0x0016, 0x2001, 0x0002, 0x080c, 0xd193, 0x00b0, 0x6014,
-	0x2048, 0xa864, 0xd0fc, 0x0118, 0x2001, 0x0001, 0x0ca8, 0x2001,
-	0x180e, 0x2004, 0xd0dc, 0x0148, 0x6010, 0x2058, 0xb840, 0x9084,
-	0x00ff, 0x9005, 0x1110, 0x9006, 0x0c38, 0x080c, 0xb821, 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, 0x6566, 0x2001, 0x0028, 0x601a,
-	0x6007, 0x0052, 0x0020, 0x2001, 0x0001, 0x080c, 0xba8d, 0x002e,
-	0x00be, 0x009e, 0x0005, 0x9286, 0x0139, 0x0160, 0x6014, 0x2048,
-	0x080c, 0xcb5a, 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, 0x5fc0, 0x00ee, 0x0010, 0x080c, 0x31cc, 0x0860, 0x080c,
-	0xbc95, 0x1160, 0x2001, 0x0004, 0x080c, 0x6566, 0x6003, 0x0001,
-	0x6007, 0x0003, 0x080c, 0x9140, 0x0804, 0x96a6, 0x080c, 0xb821,
-	0x9006, 0x0804, 0xba8d, 0x0489, 0x1160, 0x2001, 0x0008, 0x080c,
-	0x6566, 0x6003, 0x0001, 0x6007, 0x0005, 0x080c, 0x9140, 0x0804,
-	0x96a6, 0x2001, 0x0001, 0x0804, 0xba8d, 0x00f9, 0x1160, 0x2001,
-	0x000a, 0x080c, 0x6566, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c,
-	0x9140, 0x0804, 0x96a6, 0x2001, 0x0001, 0x0804, 0xba8d, 0x2009,
-	0x026e, 0x2104, 0x9086, 0x0003, 0x1138, 0x2009, 0x026f, 0x2104,
-	0x9084, 0xff00, 0x9086, 0x2a00, 0x0005, 0x9085, 0x0001, 0x0005,
-	0x00b6, 0x00c6, 0x0016, 0x6110, 0x2158, 0x080c, 0x6625, 0x001e,
-	0x00ce, 0x00be, 0x0005, 0x00b6, 0x00f6, 0x00e6, 0x00d6, 0x0036,
-	0x0016, 0x6010, 0x2058, 0x2009, 0x1837, 0x2104, 0x9085, 0x0003,
-	0x200a, 0x080c, 0xbd3b, 0x0560, 0x2009, 0x1837, 0x2104, 0xc0cd,
-	0x200a, 0x080c, 0x6985, 0x0158, 0x9006, 0x2020, 0x2009, 0x002a,
-	0x080c, 0xe5e9, 0x2001, 0x180c, 0x200c, 0xc195, 0x2102, 0x2019,
-	0x002a, 0x2009, 0x0001, 0x080c, 0x3197, 0x00e6, 0x2071, 0x1800,
-	0x080c, 0x2fa3, 0x00ee, 0x00c6, 0x0156, 0x20a9, 0x0781, 0x2009,
-	0x007f, 0x080c, 0x32c8, 0x8108, 0x1f04, 0xbcd9, 0x015e, 0x00ce,
-	0x080c, 0xbc98, 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, 0x2894, 0x080c, 0x73b3, 0x0170, 0x2071, 0x0260, 0x2069,
-	0x1981, 0x7048, 0x206a, 0x704c, 0x6806, 0x7050, 0x680a, 0x7054,
-	0x680e, 0x080c, 0xcf6e, 0x0040, 0x2001, 0x0006, 0x080c, 0x6566,
-	0x080c, 0x31f5, 0x080c, 0xae5f, 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,
-	0xbe2d, 0x1148, 0x2011, 0x027a, 0x20a9, 0x0004, 0x2019, 0x0006,
-	0x080c, 0xbe2d, 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,
-	0xbdf9, 0x080c, 0x8987, 0x0904, 0xbdf2, 0x080c, 0xe61a, 0x0904,
-	0xbdf2, 0x6720, 0x9786, 0x0007, 0x0904, 0xbdf2, 0x2500, 0x9c06,
-	0x0904, 0xbdf2, 0x2400, 0x9c06, 0x05e8, 0x3e08, 0x9186, 0x0002,
-	0x1148, 0x6010, 0x9005, 0x0130, 0x00b6, 0x2058, 0xb800, 0x00be,
-	0xd0bc, 0x1580, 0x00c6, 0x6000, 0x9086, 0x0004, 0x1110, 0x080c,
-	0x1a70, 0x9786, 0x000a, 0x0148, 0x080c, 0xcd60, 0x1130, 0x00ce,
-	0x080c, 0xb821, 0x080c, 0xae90, 0x00e8, 0x6014, 0x2048, 0x080c,
-	0xcb5a, 0x01a8, 0x9786, 0x0003, 0x1530, 0xa867, 0x0103, 0xa87c,
-	0xd0cc, 0x0130, 0x0096, 0xa878, 0x2048, 0x080c, 0x0fb1, 0x009e,
-	0xab7a, 0xa877, 0x0000, 0x080c, 0x6c88, 0x080c, 0xcd43, 0x080c,
-	0xae90, 0x00ce, 0x9ce0, 0x0018, 0x7068, 0x9c02, 0x1210, 0x0804,
-	0xbd9c, 0x012e, 0x000e, 0x002e, 0x004e, 0x005e, 0x007e, 0x00ce,
-	0x009e, 0x00ee, 0x0005, 0x9786, 0x0006, 0x1118, 0x080c, 0xe58c,
-	0x0c30, 0x9786, 0x0009, 0x1148, 0x6000, 0x9086, 0x0004, 0x0d08,
-	0x2009, 0x004c, 0x080c, 0xaeda, 0x08e0, 0x9786, 0x000a, 0x0938,
-	0x0820, 0x220c, 0x2304, 0x9106, 0x1130, 0x8210, 0x8318, 0x1f04,
-	0xbe19, 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, 0xbe57,
-	0x9006, 0x0005, 0x918d, 0x0001, 0x0005, 0x6004, 0x908a, 0x0053,
-	0x1a0c, 0x0dd5, 0x080c, 0xcd4f, 0x0120, 0x080c, 0xcd60, 0x0168,
-	0x0028, 0x080c, 0x31f5, 0x080c, 0xcd60, 0x0138, 0x080c, 0x959a,
-	0x080c, 0xae5f, 0x080c, 0x96a6, 0x0005, 0x080c, 0xb821, 0x0cb0,
-	0x9182, 0x0054, 0x1220, 0x9182, 0x0040, 0x0208, 0x000a, 0x0005,
-	0xbe9c, 0xbe9c, 0xbe9c, 0xbe9c, 0xbe9c, 0xbe9c, 0xbe9c, 0xbe9c,
-	0xbe9c, 0xbe9c, 0xbe9c, 0xbe9e, 0xbe9e, 0xbe9e, 0xbe9e, 0xbe9c,
-	0xbe9c, 0xbe9c, 0xbe9e, 0xbe9c, 0x080c, 0x0dd5, 0x600b, 0xffff,
-	0x6003, 0x0001, 0x6106, 0x080c, 0x90f8, 0x0126, 0x2091, 0x8000,
-	0x080c, 0x96a6, 0x012e, 0x0005, 0x9186, 0x0013, 0x1128, 0x6004,
-	0x9082, 0x0040, 0x0804, 0xbf53, 0x9186, 0x0027, 0x1520, 0x080c,
-	0x959a, 0x080c, 0x31cc, 0x080c, 0xd26f, 0x0096, 0x6114, 0x2148,
-	0x080c, 0xcb5a, 0x0198, 0x080c, 0xcd60, 0x1118, 0x080c, 0xb821,
-	0x0068, 0xa867, 0x0103, 0xa87b, 0x0029, 0xa877, 0x0000, 0xa97c,
-	0xc1c5, 0xa97e, 0x080c, 0x6c94, 0x080c, 0xcd43, 0x009e, 0x080c,
-	0xae5f, 0x0804, 0x96a6, 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, 0x8fdd, 0x00ce, 0x00ee,
-	0x00fe, 0x003e, 0x002e, 0x001e, 0x000e, 0x012e, 0xa001, 0x6000,
-	0x9086, 0x0002, 0x1110, 0x0804, 0xbf91, 0x0005, 0x0002, 0xbf2d,
-	0xbf2b, 0xbf2b, 0xbf2b, 0xbf2b, 0xbf2b, 0xbf2b, 0xbf2b, 0xbf2b,
-	0xbf2b, 0xbf2b, 0xbf48, 0xbf48, 0xbf48, 0xbf48, 0xbf2b, 0xbf48,
-	0xbf2b, 0xbf48, 0xbf2b, 0x080c, 0x0dd5, 0x080c, 0x959a, 0x0096,
-	0x6114, 0x2148, 0x080c, 0xcb5a, 0x0168, 0xa867, 0x0103, 0xa87b,
-	0x0006, 0xa877, 0x0000, 0xa880, 0xc0ec, 0xa882, 0x080c, 0x6c94,
-	0x080c, 0xcd43, 0x009e, 0x080c, 0xae5f, 0x080c, 0x96a6, 0x0005,
-	0x080c, 0x959a, 0x080c, 0xcd60, 0x090c, 0xb821, 0x080c, 0xae5f,
-	0x080c, 0x96a6, 0x0005, 0x0002, 0xbf6a, 0xbf68, 0xbf68, 0xbf68,
-	0xbf68, 0xbf68, 0xbf68, 0xbf68, 0xbf68, 0xbf68, 0xbf68, 0xbf81,
-	0xbf81, 0xbf81, 0xbf81, 0xbf68, 0xbf8b, 0xbf68, 0xbf81, 0xbf68,
-	0x080c, 0x0dd5, 0x0096, 0x080c, 0x959a, 0x6014, 0x2048, 0x2001,
-	0x1987, 0x2004, 0x6042, 0xa97c, 0xd1ac, 0x0140, 0x6003, 0x0004,
-	0xa87c, 0x9085, 0x0400, 0xa87e, 0x009e, 0x0005, 0x6003, 0x0002,
-	0x0cb8, 0x080c, 0x959a, 0x080c, 0xd272, 0x080c, 0xd277, 0x6003,
-	0x000f, 0x0804, 0x96a6, 0x080c, 0x959a, 0x080c, 0xae5f, 0x0804,
-	0x96a6, 0x9182, 0x0054, 0x1220, 0x9182, 0x0040, 0x0208, 0x000a,
-	0x0005, 0xbfad, 0xbfad, 0xbfad, 0xbfad, 0xbfad, 0xbfaf, 0xc08c,
-	0xbfad, 0xc0c0, 0xbfad, 0xbfad, 0xbfad, 0xbfad, 0xbfad, 0xbfad,
-	0xbfad, 0xbfad, 0xbfad, 0xbfad, 0xc0c0, 0x080c, 0x0dd5, 0x00b6,
-	0x0096, 0x6114, 0x2148, 0x7644, 0x96b4, 0x0fff, 0x86ff, 0x1528,
-	0x6010, 0x2058, 0xb800, 0xd0bc, 0x1904, 0xc07b, 0xa87b, 0x0000,
-	0xa867, 0x0103, 0xae76, 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938,
-	0x9115, 0x190c, 0xc255, 0x080c, 0x6ab0, 0x6210, 0x2258, 0xba3c,
-	0x82ff, 0x0110, 0x8211, 0xba3e, 0x7044, 0xd0e4, 0x1904, 0xc05f,
-	0x080c, 0xae5f, 0x009e, 0x00be, 0x0005, 0x968c, 0x0c00, 0x0150,
-	0x6010, 0x2058, 0xb800, 0xd0bc, 0x1904, 0xc063, 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,
-	0xbfb6, 0x735c, 0xab86, 0x83ff, 0x0170, 0x938a, 0x0009, 0x0210,
-	0x2019, 0x0008, 0x0036, 0x2308, 0x2019, 0x0018, 0x2011, 0x0025,
-	0x080c, 0xc743, 0x003e, 0xd6cc, 0x0904, 0xbfcb, 0x7154, 0xa98a,
-	0x81ff, 0x0904, 0xbfcb, 0x9192, 0x0021, 0x1278, 0x8304, 0x9098,
-	0x0018, 0x2011, 0x0029, 0x080c, 0xc743, 0x2011, 0x0205, 0x2013,
-	0x0000, 0x080c, 0xd1ff, 0x0804, 0xbfcb, 0xa868, 0xd0fc, 0x0120,
-	0x2009, 0x0020, 0xa98a, 0x0c50, 0x00a6, 0x2950, 0x080c, 0xc6e2,
-	0x00ae, 0x080c, 0xd1ff, 0x080c, 0xc733, 0x0804, 0xbfcd, 0x080c,
-	0xce58, 0x0804, 0xbfda, 0xa87c, 0xd0ac, 0x0904, 0xbfe6, 0xa880,
-	0xd0bc, 0x1904, 0xbfe6, 0x7348, 0xa838, 0x9306, 0x11c8, 0x734c,
-	0xa834, 0x931e, 0x0904, 0xbfe6, 0xd6d4, 0x0190, 0xab38, 0x9305,
-	0x0904, 0xbfe6, 0x0068, 0xa87c, 0xd0ac, 0x0904, 0xbfbe, 0xa838,
-	0xa934, 0x9105, 0x0904, 0xbfbe, 0xa880, 0xd0bc, 0x1904, 0xbfbe,
-	0x080c, 0xce92, 0x0804, 0xbfda, 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, 0x1bba, 0x080c, 0x915d, 0x080c, 0x97d4, 0x009e, 0x0005,
-	0x0005, 0x9182, 0x0054, 0x1220, 0x9182, 0x0040, 0x0208, 0x000a,
-	0x0005, 0xc0dd, 0xc0dd, 0xc0dd, 0xc0dd, 0xc0dd, 0xc0df, 0xc175,
-	0xc0dd, 0xc0dd, 0xc18c, 0xc218, 0xc0dd, 0xc0dd, 0xc0dd, 0xc0dd,
-	0xc22d, 0xc0dd, 0xc0dd, 0xc0dd, 0xc0dd, 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, 0xc170, 0x9694, 0xff00, 0x9284, 0x0c00, 0x0120, 0x7048,
-	0xb092, 0x704c, 0xb08e, 0x9284, 0x0300, 0x0904, 0xc170, 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, 0xc743,
-	0x003e, 0xd6cc, 0x01e8, 0x7154, 0xa98a, 0x81ff, 0x01c8, 0x9192,
-	0x0021, 0x1260, 0x8304, 0x9098, 0x0018, 0x2011, 0x0029, 0x080c,
-	0xc743, 0x2011, 0x0205, 0x2013, 0x0000, 0x0050, 0xb068, 0xd0fc,
-	0x0120, 0x2009, 0x0020, 0xa98a, 0x0c68, 0x2950, 0x080c, 0xc6e2,
-	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, 0x1bba, 0x0804, 0xa25c, 0x6003, 0x0002, 0x6004, 0x9086,
-	0x0040, 0x11c8, 0x0096, 0x6014, 0x2048, 0xa87c, 0xd0ac, 0x0160,
-	0x601c, 0xd084, 0x1130, 0x00f6, 0x2c00, 0x2078, 0x080c, 0x1727,
-	0x00fe, 0x6003, 0x0004, 0x0010, 0x6003, 0x0002, 0x009e, 0x080c,
-	0x959a, 0x080c, 0x96a6, 0x0096, 0x2001, 0x1987, 0x2004, 0x6042,
-	0x080c, 0x9656, 0x080c, 0x97d4, 0x6114, 0x2148, 0xa97c, 0xd1e4,
-	0x0904, 0xc213, 0xd1cc, 0x05a8, 0xa978, 0xa868, 0xd0fc, 0x0538,
-	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, 0xa87e, 0x001e,
-	0xa874, 0x0006, 0x2148, 0x080c, 0x0fb1, 0x001e, 0x0440, 0x0016,
-	0x080c, 0x0fb1, 0x009e, 0xa974, 0x0016, 0x080c, 0xc733, 0x001e,
+	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,
+	0x0260, 0x6114, 0x2150, 0x7644, 0xb676, 0x96b4, 0x0fff, 0xb77c,
+	0xc7e5, 0xb77e, 0x6210, 0x00b6, 0x2258, 0xba3c, 0x82ff, 0x0110,
+	0x8211, 0xba3e, 0x00be, 0x86ff, 0x0904, 0xc254, 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, 0x6ab0, 0x001e, 0xd1e4,
-	0x1120, 0x080c, 0xae5f, 0x009e, 0x0005, 0x080c, 0xce58, 0x0cd8,
-	0x6004, 0x9086, 0x0040, 0x1120, 0x080c, 0x959a, 0x080c, 0x96a6,
-	0x2019, 0x0001, 0x080c, 0xa5c8, 0x6003, 0x0002, 0x080c, 0xd277,
-	0x080c, 0x9656, 0x080c, 0x97d4, 0x0005, 0x6004, 0x9086, 0x0040,
-	0x1120, 0x080c, 0x959a, 0x080c, 0x96a6, 0x2019, 0x0001, 0x080c,
-	0xa5c8, 0x080c, 0x9656, 0x080c, 0x31cc, 0x080c, 0xd26f, 0x0096,
-	0x6114, 0x2148, 0x080c, 0xcb5a, 0x0150, 0xa867, 0x0103, 0xa87b,
-	0x0029, 0xa877, 0x0000, 0x080c, 0x6c94, 0x080c, 0xcd43, 0x009e,
-	0x080c, 0xae5f, 0x080c, 0x97d4, 0x0005, 0xa87b, 0x0015, 0xd1fc,
+	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, 0xc288, 0xc288, 0xc288, 0xc288,
-	0xc288, 0xc28a, 0xc288, 0xc288, 0xc330, 0xc288, 0xc288, 0xc288,
-	0xc288, 0xc288, 0xc288, 0xc288, 0xc288, 0xc288, 0xc288, 0xc461,
+	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, 0xc329, 0x9694, 0xff00, 0x9284,
+	0xba3e, 0x00be, 0x86ff, 0x0904, 0xc411, 0x9694, 0xff00, 0x9284,
 	0x0c00, 0x0120, 0x7048, 0xb092, 0x704c, 0xb08e, 0x9284, 0x0300,
-	0x0904, 0xc329, 0x9686, 0x0100, 0x1130, 0x7064, 0x9005, 0x1118,
+	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,
@@ -6035,1514 +6064,1527 @@
 	0xaf7e, 0xb080, 0xa882, 0xb084, 0xa886, 0x901e, 0xd6c4, 0x0190,
 	0x735c, 0xab86, 0x83ff, 0x0170, 0x938a, 0x0009, 0x0210, 0x2019,
 	0x0008, 0x0036, 0x2308, 0x2019, 0x0018, 0x2011, 0x0025, 0x080c,
-	0xc743, 0x003e, 0xd6cc, 0x01e8, 0x7154, 0xa98a, 0x81ff, 0x01c8,
+	0xc837, 0x003e, 0xd6cc, 0x01e8, 0x7154, 0xa98a, 0x81ff, 0x01c8,
 	0x9192, 0x0021, 0x1260, 0x8304, 0x9098, 0x0018, 0x2011, 0x0029,
-	0x080c, 0xc743, 0x2011, 0x0205, 0x2013, 0x0000, 0x0050, 0xb068,
+	0x080c, 0xc837, 0x2011, 0x0205, 0x2013, 0x0000, 0x0050, 0xb068,
 	0xd0fc, 0x0120, 0x2009, 0x0020, 0xa98a, 0x0c68, 0x2950, 0x080c,
-	0xc6e2, 0x080c, 0x1a3e, 0x009e, 0x00ee, 0x00ae, 0x007e, 0x0005,
+	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, 0xc45c, 0x6043, 0x0000, 0x6010, 0x00b6,
-	0x2058, 0xb800, 0x00be, 0xd0bc, 0x1500, 0xd1cc, 0x0904, 0xc42b,
-	0xa978, 0xa868, 0xd0fc, 0x0904, 0xc3ec, 0x0016, 0xa87c, 0x0006,
+	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, 0xc3ba, 0x9086, 0x0028, 0x1904, 0xc3a6, 0xa87b,
-	0x001c, 0xb07b, 0x001c, 0x0804, 0xc3c2, 0x6024, 0xd0f4, 0x11d0,
+	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, 0xce92, 0x0804, 0xc45c, 0xd1dc, 0x0158,
-	0xa87b, 0x0015, 0xb07b, 0x0015, 0x080c, 0xd122, 0x0118, 0xb174,
+	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, 0xc255, 0xa87c, 0xb07e, 0xa890, 0xb092, 0xa88c, 0xb08e,
+	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,
-	0xa87e, 0x080c, 0xd1ff, 0x001e, 0xa874, 0x0006, 0x2148, 0x080c,
-	0x0fb1, 0x001e, 0x0804, 0xc458, 0x0016, 0x00a6, 0x2150, 0xb174,
-	0x9184, 0x00ff, 0x90b6, 0x0002, 0x01e0, 0x9086, 0x0028, 0x1128,
-	0xa87b, 0x001c, 0xb07b, 0x001c, 0x00e0, 0xd1dc, 0x0158, 0xa87b,
-	0x0015, 0xb07b, 0x0015, 0x080c, 0xd122, 0x0118, 0xb174, 0xc1dc,
-	0xb176, 0x0078, 0xd1d4, 0x0128, 0xa87b, 0x0007, 0xb07b, 0x0007,
-	0x0040, 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115, 0x190c,
-	0xc255, 0xa890, 0xb092, 0xa88c, 0xb08e, 0xa87c, 0xb07e, 0x00ae,
-	0x080c, 0x0fb1, 0x009e, 0x080c, 0xd1ff, 0xa974, 0x0016, 0x080c,
-	0xc733, 0x001e, 0x0468, 0xa867, 0x0103, 0xa974, 0x9184, 0x00ff,
-	0x90b6, 0x0002, 0x01b0, 0x9086, 0x0028, 0x1118, 0xa87b, 0x001c,
-	0x00d0, 0xd1dc, 0x0148, 0xa87b, 0x0015, 0x080c, 0xd122, 0x0118,
-	0xa974, 0xc1dc, 0xa976, 0x0078, 0xd1d4, 0x0118, 0xa87b, 0x0007,
-	0x0050, 0xa87b, 0x0000, 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938,
-	0x9115, 0x190c, 0xc255, 0xa974, 0x0016, 0x080c, 0x6ab0, 0x001e,
-	0xd1e4, 0x1120, 0x080c, 0xae5f, 0x009e, 0x0005, 0x080c, 0xce58,
-	0x0cd8, 0x6114, 0x0096, 0x2148, 0xa97c, 0xd1e4, 0x190c, 0x1a5c,
-	0x009e, 0x0005, 0x080c, 0x959a, 0x0010, 0x080c, 0x9656, 0x080c,
-	0xcb5a, 0x01f0, 0x0096, 0x6114, 0x2148, 0x080c, 0xcd60, 0x1118,
-	0x080c, 0xb821, 0x00a0, 0xa867, 0x0103, 0x2009, 0x180c, 0x210c,
-	0xd18c, 0x11b8, 0xd184, 0x1190, 0x6108, 0xa97a, 0x918e, 0x0029,
-	0x1110, 0x080c, 0xe943, 0xa877, 0x0000, 0x080c, 0x6c94, 0x009e,
-	0x080c, 0xae5f, 0x080c, 0x96a6, 0x0804, 0x97d4, 0xa87b, 0x0004,
-	0x0c90, 0xa87b, 0x0004, 0x0c78, 0x9182, 0x0054, 0x1220, 0x9182,
-	0x0040, 0x0208, 0x000a, 0x0005, 0xc4b8, 0xc4b8, 0xc4b8, 0xc4b8,
-	0xc4b8, 0xc4ba, 0xc4b8, 0xc4b8, 0xc4b8, 0xc4b8, 0xc4b8, 0xc4b8,
-	0xc4b8, 0xc4b8, 0xc4b8, 0xc4b8, 0xc4b8, 0xc4b8, 0xc4b8, 0xc4b8,
-	0x080c, 0x0dd5, 0x080c, 0x56ea, 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, 0x6c94, 0x009e, 0x0804, 0xae5f, 0x9182, 0x0085,
-	0x0002, 0xc4f0, 0xc4ee, 0xc4ee, 0xc4fc, 0xc4ee, 0xc4ee, 0xc4ee,
-	0xc4ee, 0xc4ee, 0xc4ee, 0xc4ee, 0xc4ee, 0xc4ee, 0x080c, 0x0dd5,
-	0x6003, 0x0001, 0x6106, 0x080c, 0x90f8, 0x0126, 0x2091, 0x8000,
-	0x080c, 0x96a6, 0x012e, 0x0005, 0x0026, 0x0056, 0x00d6, 0x00e6,
-	0x2071, 0x0260, 0x7224, 0x6216, 0x7220, 0x080c, 0xcb48, 0x01a0,
-	0x2268, 0x6800, 0x9086, 0x0000, 0x0178, 0x6010, 0x6d10, 0x952e,
-	0x1158, 0x00c6, 0x2d60, 0x080c, 0xc76e, 0x00ce, 0x0128, 0x6803,
-	0x0002, 0x6007, 0x0086, 0x0010, 0x6007, 0x0087, 0x6003, 0x0001,
-	0x080c, 0x90f8, 0x080c, 0x96a6, 0x7220, 0x080c, 0xcb48, 0x0178,
-	0x6810, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0140, 0x6824,
-	0xd0ec, 0x0128, 0x00c6, 0x2d60, 0x080c, 0xce92, 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, 0x959a, 0x0096, 0x6014, 0x2048, 0x080c,
-	0xcb5a, 0x0140, 0xa867, 0x0103, 0xa877, 0x0000, 0xa87b, 0x0029,
-	0x080c, 0x6c94, 0x009e, 0x080c, 0xae90, 0x0804, 0x96a6, 0xc574,
-	0xc576, 0xc576, 0xc574, 0xc574, 0xc574, 0xc574, 0xc574, 0xc574,
-	0xc574, 0xc574, 0xc574, 0xc574, 0x080c, 0x0dd5, 0x080c, 0x959a,
-	0x080c, 0xae90, 0x080c, 0x96a6, 0x0005, 0x9186, 0x0013, 0x1128,
-	0x6004, 0x9082, 0x0085, 0x2008, 0x04b8, 0x9186, 0x0027, 0x11f8,
-	0x080c, 0x959a, 0x080c, 0x31cc, 0x080c, 0xd26f, 0x0096, 0x6014,
-	0x2048, 0x080c, 0xcb5a, 0x0150, 0xa867, 0x0103, 0xa877, 0x0000,
-	0xa87b, 0x0029, 0x080c, 0x6c94, 0x080c, 0xcd43, 0x009e, 0x080c,
-	0xae5f, 0x080c, 0x96a6, 0x0005, 0x080c, 0xaef5, 0x0ce0, 0x9186,
-	0x0014, 0x1dd0, 0x080c, 0x959a, 0x0096, 0x6014, 0x2048, 0x080c,
-	0xcb5a, 0x0d60, 0xa867, 0x0103, 0xa877, 0x0000, 0xa87b, 0x0006,
-	0xa880, 0xc0ec, 0xa882, 0x08f0, 0x0002, 0xc5cc, 0xc5ca, 0xc5ca,
-	0xc5ca, 0xc5ca, 0xc5ca, 0xc5e4, 0xc5ca, 0xc5ca, 0xc5ca, 0xc5ca,
-	0xc5ca, 0xc5ca, 0x080c, 0x0dd5, 0x080c, 0x959a, 0x6034, 0x908c,
-	0xff00, 0x810f, 0x9186, 0x0039, 0x0118, 0x9186, 0x0035, 0x1118,
-	0x2001, 0x1985, 0x0010, 0x2001, 0x1986, 0x2004, 0x601a, 0x6003,
-	0x000c, 0x080c, 0x96a6, 0x0005, 0x080c, 0x959a, 0x6034, 0x908c,
-	0xff00, 0x810f, 0x9186, 0x0039, 0x0118, 0x9186, 0x0035, 0x1118,
-	0x2001, 0x1985, 0x0010, 0x2001, 0x1986, 0x2004, 0x601a, 0x6003,
-	0x000e, 0x080c, 0x96a6, 0x0005, 0x9182, 0x0092, 0x1220, 0x9182,
-	0x0085, 0x0208, 0x0012, 0x0804, 0xaef5, 0xc612, 0xc612, 0xc612,
-	0xc612, 0xc614, 0xc661, 0xc612, 0xc612, 0xc612, 0xc612, 0xc612,
-	0xc612, 0xc612, 0x080c, 0x0dd5, 0x0096, 0x6010, 0x00b6, 0x2058,
-	0xb800, 0x00be, 0xd0bc, 0x0168, 0x6034, 0x908c, 0xff00, 0x810f,
-	0x9186, 0x0039, 0x0118, 0x9186, 0x0035, 0x1118, 0x009e, 0x0804,
-	0xc675, 0x080c, 0xcb5a, 0x1118, 0x080c, 0xcd43, 0x0068, 0x6014,
-	0x2048, 0xa87c, 0xd0e4, 0x1110, 0x080c, 0xcd43, 0xa867, 0x0103,
-	0x080c, 0xd23a, 0x080c, 0x6c94, 0x00d6, 0x2c68, 0x080c, 0xae09,
-	0x01d0, 0x6003, 0x0001, 0x6007, 0x001e, 0x600b, 0xffff, 0x2009,
-	0x026e, 0x210c, 0x613a, 0x2009, 0x026f, 0x210c, 0x613e, 0x6910,
-	0x6112, 0x080c, 0xcfd4, 0x6954, 0x6156, 0x6023, 0x0001, 0x080c,
-	0x90f8, 0x080c, 0x96a6, 0x2d60, 0x00de, 0x080c, 0xae5f, 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,
-	0xd1d2, 0x11f0, 0x080c, 0xae09, 0x01d8, 0x6106, 0x6003, 0x0001,
-	0x6023, 0x0001, 0x6910, 0x6112, 0x692c, 0x612e, 0x6930, 0x6132,
-	0x6934, 0x918c, 0x00ff, 0x6136, 0x6938, 0x613a, 0x693c, 0x613e,
-	0x6954, 0x6156, 0x080c, 0xcfd4, 0x080c, 0x90f8, 0x080c, 0x96a6,
-	0x2d60, 0x00de, 0x0804, 0xae5f, 0x0096, 0x6014, 0x2048, 0x080c,
-	0xcb5a, 0x01c8, 0xa867, 0x0103, 0xa880, 0xd0b4, 0x0128, 0xc0ec,
-	0xa882, 0xa87b, 0x0006, 0x0048, 0xd0bc, 0x0118, 0xa87b, 0x0002,
-	0x0020, 0xa87b, 0x0005, 0x080c, 0xce54, 0xa877, 0x0000, 0x080c,
-	0x6c94, 0x080c, 0xcd43, 0x009e, 0x0804, 0xae5f, 0x0016, 0x0096,
-	0x6014, 0x2048, 0x080c, 0xcb5a, 0x0140, 0xa867, 0x0103, 0xa87b,
-	0x0028, 0xa877, 0x0000, 0x080c, 0x6c94, 0x009e, 0x001e, 0x9186,
-	0x0013, 0x0148, 0x9186, 0x0014, 0x0130, 0x9186, 0x0027, 0x0118,
-	0x080c, 0xaef5, 0x0030, 0x080c, 0x959a, 0x080c, 0xae90, 0x080c,
-	0x96a6, 0x0005, 0x0056, 0x0066, 0x0096, 0x00a6, 0x2029, 0x0001,
-	0x9182, 0x0101, 0x1208, 0x0010, 0x2009, 0x0100, 0x2130, 0x8304,
-	0x9098, 0x0018, 0x2009, 0x0020, 0x2011, 0x0029, 0x080c, 0xc743,
-	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, 0x6c94, 0x2a48, 0x0cb8, 0x080c,
-	0x6c94, 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, 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,
-	0xc7a9, 0xc7a9, 0xc7a4, 0xc7cb, 0xc797, 0xc7a4, 0xc7cb, 0xc7a4,
-	0xc797, 0x8ee1, 0xc7a4, 0xc7a4, 0xc7a4, 0xc797, 0xc797, 0x080c,
-	0x0dd5, 0x0036, 0x2019, 0x0010, 0x080c, 0xe16f, 0x6023, 0x0006,
-	0x6003, 0x0007, 0x003e, 0x0005, 0x9006, 0x0005, 0x9085, 0x0001,
-	0x0005, 0x0096, 0x86ff, 0x11d8, 0x6014, 0x2048, 0x080c, 0xcb5a,
-	0x01c0, 0xa864, 0x9086, 0x0139, 0x1128, 0xa87b, 0x0005, 0xa883,
-	0x0000, 0x0028, 0x900e, 0x2001, 0x0005, 0x080c, 0x6ec7, 0x080c,
-	0xce54, 0x080c, 0x6c88, 0x080c, 0xae90, 0x9085, 0x0001, 0x009e,
-	0x0005, 0x9006, 0x0ce0, 0x6000, 0x908a, 0x0016, 0x1a0c, 0x0dd5,
-	0x0002, 0xc7e1, 0xc80f, 0xc7e3, 0xc830, 0xc80a, 0xc7e1, 0xc7a4,
-	0xc7a9, 0xc7a9, 0xc7a4, 0xc7a4, 0xc7a4, 0xc7a4, 0xc7a4, 0xc7a4,
-	0xc7a4, 0x080c, 0x0dd5, 0x86ff, 0x1510, 0x6020, 0x9086, 0x0006,
-	0x01f0, 0x0096, 0x6014, 0x2048, 0x080c, 0xcb5a, 0x0158, 0xa87c,
-	0xd0cc, 0x0130, 0x0096, 0xa878, 0x2048, 0x080c, 0x0fb1, 0x009e,
-	0x080c, 0xce54, 0x009e, 0x080c, 0xd214, 0x6007, 0x0085, 0x6003,
-	0x000b, 0x6023, 0x0002, 0x080c, 0x90f8, 0x080c, 0x96a6, 0x9085,
-	0x0001, 0x0005, 0x0066, 0x080c, 0x1a70, 0x006e, 0x08a0, 0x00e6,
-	0x2071, 0x19e6, 0x7024, 0x9c06, 0x1120, 0x080c, 0xa552, 0x00ee,
-	0x0850, 0x6020, 0x9084, 0x000f, 0x9086, 0x0006, 0x1150, 0x0086,
-	0x0096, 0x2049, 0x0001, 0x2c40, 0x080c, 0xa687, 0x009e, 0x008e,
-	0x0010, 0x080c, 0xa44f, 0x00ee, 0x1904, 0xc7e3, 0x0804, 0xc7a4,
-	0x0036, 0x00e6, 0x2071, 0x19e6, 0x703c, 0x9c06, 0x1138, 0x901e,
-	0x080c, 0xa5c8, 0x00ee, 0x003e, 0x0804, 0xc7e3, 0x080c, 0xa7b7,
-	0x00ee, 0x003e, 0x1904, 0xc7e3, 0x0804, 0xc7a4, 0x00c6, 0x6020,
-	0x9084, 0x000f, 0x0013, 0x00ce, 0x0005, 0xc863, 0xc92e, 0xca98,
-	0xc86d, 0xae90, 0xc863, 0xe161, 0xd27c, 0xc92e, 0x8eb3, 0xcb24,
-	0xc85c, 0xc85c, 0xc85c, 0xc85c, 0x080c, 0x0dd5, 0x080c, 0xcd60,
-	0x1110, 0x080c, 0xb821, 0x0005, 0x080c, 0x959a, 0x080c, 0x96a6,
-	0x0804, 0xae5f, 0x601b, 0x0001, 0x0005, 0x080c, 0xcb5a, 0x0130,
-	0x6014, 0x0096, 0x2048, 0x2c00, 0xa896, 0x009e, 0x6000, 0x908a,
-	0x0016, 0x1a0c, 0x0dd5, 0x0002, 0xc88c, 0xc88e, 0xc8b2, 0xc8c6,
-	0xc8ec, 0xc88c, 0xc863, 0xc863, 0xc863, 0xc8c6, 0xc8c6, 0xc88c,
-	0xc88c, 0xc88c, 0xc88c, 0xc8d0, 0x080c, 0x0dd5, 0x00e6, 0x6014,
-	0x0096, 0x2048, 0xa880, 0xc0b5, 0xa882, 0x009e, 0x2071, 0x19e6,
-	0x7024, 0x9c06, 0x01a0, 0x080c, 0xa44f, 0x080c, 0xd214, 0x6007,
-	0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x2001, 0x1986, 0x2004,
-	0x601a, 0x080c, 0x90f8, 0x080c, 0x96a6, 0x00ee, 0x0005, 0x601b,
-	0x0001, 0x0cd8, 0x0096, 0x6014, 0x2048, 0xa880, 0xc0b5, 0xa882,
-	0x009e, 0x080c, 0xd214, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023,
-	0x0002, 0x080c, 0x90f8, 0x080c, 0x96a6, 0x0005, 0x0096, 0x601b,
-	0x0001, 0x6014, 0x2048, 0xa880, 0xc0b5, 0xa882, 0x009e, 0x0005,
-	0x080c, 0x56ea, 0x01b8, 0x6014, 0x0096, 0x904d, 0x0190, 0xa864,
-	0xa867, 0x0103, 0xa87b, 0x0006, 0x9086, 0x0139, 0x1150, 0xa867,
-	0x0139, 0xa87b, 0x0030, 0xa897, 0x4005, 0xa89b, 0x0004, 0x080c,
-	0x6c94, 0x009e, 0x0804, 0xae5f, 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, 0x15f0, 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, 0x15f0,
-	0x6000, 0x9086, 0x0004, 0x1120, 0x2009, 0x0048, 0x080c, 0xaeda,
-	0x0005, 0x009e, 0x080c, 0x1a70, 0x0804, 0xc8b2, 0x6000, 0x908a,
-	0x0016, 0x1a0c, 0x0dd5, 0x000b, 0x0005, 0xc945, 0xc86a, 0xc947,
-	0xc945, 0xc947, 0xc947, 0xc864, 0xc945, 0xc85e, 0xc85e, 0xc945,
-	0xc945, 0xc945, 0xc945, 0xc945, 0xc945, 0x080c, 0x0dd5, 0x6010,
-	0x00b6, 0x2058, 0xb804, 0x9084, 0x00ff, 0x00be, 0x908a, 0x000c,
-	0x1a0c, 0x0dd5, 0x00b6, 0x0013, 0x00be, 0x0005, 0xc962, 0xca2f,
-	0xc964, 0xc9a4, 0xc964, 0xc9a4, 0xc964, 0xc972, 0xc962, 0xc9a4,
-	0xc962, 0xc993, 0x080c, 0x0dd5, 0x6004, 0x908e, 0x0016, 0x05c0,
-	0x908e, 0x0004, 0x05a8, 0x908e, 0x0002, 0x0590, 0x908e, 0x0052,
-	0x0904, 0xca2b, 0x6004, 0x080c, 0xcd60, 0x0904, 0xca48, 0x908e,
-	0x0004, 0x1110, 0x080c, 0x31f5, 0x908e, 0x0021, 0x0904, 0xca4c,
-	0x908e, 0x0022, 0x0904, 0xca93, 0x908e, 0x003d, 0x0904, 0xca4c,
-	0x908e, 0x0039, 0x0904, 0xca50, 0x908e, 0x0035, 0x0904, 0xca50,
-	0x908e, 0x001e, 0x0178, 0x908e, 0x0001, 0x1140, 0x6010, 0x2058,
-	0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, 0x0110, 0x080c, 0x31cc,
-	0x080c, 0xb821, 0x0804, 0xae90, 0x00c6, 0x00d6, 0x6104, 0x9186,
-	0x0016, 0x0904, 0xca1c, 0x9186, 0x0002, 0x1904, 0xc9f1, 0x2001,
-	0x1837, 0x2004, 0xd08c, 0x11c8, 0x080c, 0x73b3, 0x11b0, 0x080c,
-	0xd25a, 0x0138, 0x080c, 0x73d6, 0x1120, 0x080c, 0x72c3, 0x0804,
-	0xca7c, 0x2001, 0x197c, 0x2003, 0x0001, 0x2001, 0x1800, 0x2003,
-	0x0001, 0x080c, 0x72e5, 0x0804, 0xca7c, 0x6010, 0x2058, 0x2001,
-	0x1837, 0x2004, 0xd0ac, 0x1904, 0xca7c, 0xb8a0, 0x9084, 0xff80,
-	0x1904, 0xca7c, 0xb840, 0x9084, 0x00ff, 0x9005, 0x0190, 0x8001,
-	0xb842, 0x6017, 0x0000, 0x6023, 0x0007, 0x601b, 0x0398, 0x6043,
-	0x0000, 0x080c, 0xae09, 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, 0x5fc0, 0x00ee,
-	0x080c, 0xb821, 0x0030, 0x080c, 0xb821, 0x080c, 0x31cc, 0x080c,
-	0xd26f, 0x00e6, 0x0126, 0x2091, 0x8000, 0x080c, 0x31f5, 0x012e,
-	0x00ee, 0x080c, 0xae90, 0x0005, 0x2001, 0x0002, 0x080c, 0x6566,
-	0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x9140, 0x080c, 0x96a6,
-	0x00de, 0x00ce, 0x0c80, 0x080c, 0x31f5, 0x0804, 0xc9a0, 0x00c6,
-	0x00d6, 0x6104, 0x9186, 0x0016, 0x0d38, 0x6010, 0x2058, 0xb840,
-	0x9084, 0x00ff, 0x9005, 0x0904, 0xc9f1, 0x8001, 0xb842, 0x6003,
-	0x0001, 0x080c, 0x9140, 0x080c, 0x96a6, 0x00de, 0x00ce, 0x0898,
-	0x080c, 0xb821, 0x0804, 0xc9a2, 0x080c, 0xb85d, 0x0804, 0xc9a2,
-	0x00d6, 0x2c68, 0x6104, 0x080c, 0xd1d2, 0x00de, 0x0118, 0x080c,
-	0xae5f, 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,
-	0x90f8, 0x080c, 0x96a6, 0x0005, 0x00de, 0x00ce, 0x080c, 0xb821,
-	0x080c, 0x31cc, 0x00e6, 0x0126, 0x2091, 0x8000, 0x080c, 0x31f5,
-	0x6017, 0x0000, 0x6023, 0x0007, 0x601b, 0x0398, 0x6043, 0x0000,
-	0x012e, 0x00ee, 0x0005, 0x080c, 0xb290, 0x1904, 0xca48, 0x0005,
-	0x6000, 0x908a, 0x0016, 0x1a0c, 0x0dd5, 0x0096, 0x00d6, 0x001b,
-	0x00de, 0x009e, 0x0005, 0xcab3, 0xcab3, 0xcab3, 0xcab3, 0xcab3,
-	0xcab3, 0xcab3, 0xcab3, 0xcab3, 0xc863, 0xcab3, 0xc86a, 0xcab5,
-	0xc86a, 0xcacf, 0xcab3, 0x080c, 0x0dd5, 0x6004, 0x9086, 0x008b,
-	0x01b0, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0035, 0x1130,
-	0x602c, 0x9080, 0x0009, 0x200c, 0xc185, 0x2102, 0x6007, 0x008b,
-	0x6003, 0x000d, 0x080c, 0x90f8, 0x080c, 0x96a6, 0x0005, 0x080c,
-	0xd24e, 0x0118, 0x080c, 0xd261, 0x0010, 0x080c, 0xd26f, 0x080c,
-	0xcd43, 0x080c, 0xcb5a, 0x0570, 0x080c, 0x31cc, 0x080c, 0xcb5a,
-	0x0168, 0x6014, 0x2048, 0xa867, 0x0103, 0xa87b, 0x0006, 0xa877,
-	0x0000, 0xa880, 0xc0ed, 0xa882, 0x080c, 0x6c94, 0x2c68, 0x080c,
-	0xae09, 0x0150, 0x6810, 0x6012, 0x080c, 0xcfd4, 0x00c6, 0x2d60,
-	0x080c, 0xae90, 0x00ce, 0x0008, 0x2d60, 0x6017, 0x0000, 0x6023,
-	0x0001, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x9140, 0x080c,
-	0x96a6, 0x00c8, 0x080c, 0xd24e, 0x0138, 0x6034, 0x9086, 0x4000,
-	0x1118, 0x080c, 0x31cc, 0x08d0, 0x6034, 0x908c, 0xff00, 0x810f,
-	0x9186, 0x0039, 0x0118, 0x9186, 0x0035, 0x1118, 0x080c, 0x31cc,
-	0x0868, 0x080c, 0xae90, 0x0005, 0x6000, 0x908a, 0x0016, 0x1a0c,
-	0x0dd5, 0x0002, 0xcb3a, 0xcb3a, 0xcb3c, 0xcb3c, 0xcb3c, 0xcb3a,
-	0xcb3a, 0xae90, 0xcb3a, 0xcb3a, 0xcb3a, 0xcb3a, 0xcb3a, 0xcb3a,
-	0xcb3a, 0xcb3a, 0x080c, 0x0dd5, 0x080c, 0xa7b7, 0x6114, 0x0096,
-	0x2148, 0xa87b, 0x0006, 0x080c, 0x6c94, 0x009e, 0x0804, 0xae5f,
-	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, 0xd25a, 0x0180, 0x9286,
-	0x0001, 0x1168, 0x6004, 0x9086, 0x0004, 0x1148, 0x080c, 0x31cc,
-	0x080c, 0xd26f, 0x00c6, 0x080c, 0xae90, 0x00ce, 0x0060, 0x080c,
-	0xcf4e, 0x0148, 0x080c, 0xcd60, 0x1110, 0x080c, 0xb821, 0x00c6,
-	0x080c, 0xae5f, 0x00ce, 0x9ce0, 0x0018, 0x7068, 0x9c02, 0x1208,
-	0x08a0, 0x012e, 0x000e, 0x003e, 0x00ce, 0x00ee, 0x0005, 0x00e6,
-	0x00c6, 0x0016, 0x9188, 0x1000, 0x210c, 0x81ff, 0x0128, 0x2061,
-	0x1aaf, 0x6112, 0x080c, 0x31cc, 0x9006, 0x0010, 0x9085, 0x0001,
-	0x001e, 0x00ce, 0x00ee, 0x0005, 0x00c6, 0x0126, 0x2091, 0x8000,
-	0x080c, 0xae09, 0x01b0, 0x6656, 0x2b00, 0x6012, 0x080c, 0x56ea,
-	0x0118, 0x080c, 0xcc87, 0x0168, 0x080c, 0xcfd4, 0x6023, 0x0003,
-	0x2009, 0x004b, 0x080c, 0xaeda, 0x9085, 0x0001, 0x012e, 0x00ce,
-	0x0005, 0x9006, 0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000, 0xbaa0,
-	0x080c, 0xaead, 0x0560, 0x6057, 0x0000, 0x2b00, 0x6012, 0x080c,
-	0xcfd4, 0x6023, 0x0003, 0x0016, 0x080c, 0x929d, 0x0076, 0x903e,
-	0x080c, 0x9170, 0x2c08, 0x080c, 0xe326, 0x007e, 0x001e, 0xd184,
-	0x0128, 0x080c, 0xae5f, 0x9085, 0x0001, 0x0070, 0x080c, 0x56ea,
-	0x0128, 0xd18c, 0x1170, 0x080c, 0xcc87, 0x0148, 0x2009, 0x004c,
-	0x080c, 0xaeda, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006,
-	0x0cd8, 0x2900, 0x6016, 0x0c90, 0x2009, 0x004d, 0x0010, 0x2009,
-	0x004e, 0x00f6, 0x00c6, 0x0046, 0x0016, 0x080c, 0xae09, 0x2c78,
-	0x0590, 0x7e56, 0x2b00, 0x7812, 0x7823, 0x0003, 0x2021, 0x0005,
-	0x080c, 0xcc99, 0x9186, 0x004d, 0x0118, 0x9186, 0x004e, 0x0148,
-	0x2001, 0x197f, 0x200c, 0xd1fc, 0x0168, 0x2f60, 0x080c, 0xae5f,
-	0x00d0, 0x2001, 0x197e, 0x200c, 0xd1fc, 0x0120, 0x2f60, 0x080c,
-	0xae5f, 0x0088, 0x2f60, 0x080c, 0x56ea, 0x0138, 0xd18c, 0x1118,
-	0x04f1, 0x0148, 0x0010, 0x2900, 0x7816, 0x001e, 0x0016, 0x080c,
-	0xaeda, 0x9085, 0x0001, 0x001e, 0x004e, 0x00ce, 0x00fe, 0x0005,
-	0x00f6, 0x00c6, 0x0046, 0x080c, 0xae09, 0x2c78, 0x0508, 0x7e56,
-	0x2b00, 0x7812, 0x7823, 0x0003, 0x0096, 0x2021, 0x0004, 0x0489,
-	0x009e, 0x2001, 0x197d, 0x200c, 0xd1fc, 0x0120, 0x2f60, 0x080c,
-	0xae5f, 0x0060, 0x2f60, 0x080c, 0x56ea, 0x0120, 0xd18c, 0x1160,
-	0x0071, 0x0130, 0x2009, 0x0052, 0x080c, 0xaeda, 0x9085, 0x0001,
-	0x004e, 0x00ce, 0x00fe, 0x0005, 0x2900, 0x7816, 0x0c98, 0x00c6,
-	0x080c, 0x4abe, 0x00ce, 0x1120, 0x080c, 0xae5f, 0x9006, 0x0005,
-	0xa867, 0x0000, 0xa86b, 0x8000, 0x2900, 0x6016, 0x9085, 0x0001,
-	0x0005, 0x0096, 0x0076, 0x0126, 0x2091, 0x8000, 0x080c, 0x674a,
-	0x0158, 0x2001, 0xcc9e, 0x0006, 0x900e, 0x2400, 0x080c, 0x6ec7,
-	0x080c, 0x6c94, 0x000e, 0x0807, 0x2418, 0x080c, 0x9534, 0xbaa0,
-	0x0086, 0x2041, 0x0001, 0x2039, 0x0001, 0x2608, 0x080c, 0x92b5,
-	0x008e, 0x080c, 0x9170, 0x2f08, 0x2648, 0x080c, 0xe326, 0xb93c,
-	0x81ff, 0x090c, 0x9386, 0x080c, 0x96a6, 0x012e, 0x007e, 0x009e,
-	0x0005, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xae09, 0x0190,
-	0x660a, 0x2b08, 0x6112, 0x080c, 0xcfd4, 0x6023, 0x0001, 0x2900,
-	0x6016, 0x2009, 0x001f, 0x080c, 0xaeda, 0x9085, 0x0001, 0x012e,
-	0x00ce, 0x0005, 0x9006, 0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000,
-	0x080c, 0xaead, 0x01b8, 0x660a, 0x2b08, 0x6112, 0x080c, 0xcfd4,
-	0x6023, 0x0008, 0x2900, 0x6016, 0x00f6, 0x2c78, 0x080c, 0x1727,
-	0x00fe, 0x2009, 0x0021, 0x080c, 0xaeda, 0x9085, 0x0001, 0x012e,
-	0x00ce, 0x0005, 0x9006, 0x0cd8, 0x2009, 0x003d, 0x00c6, 0x0126,
-	0x0016, 0x2091, 0x8000, 0x080c, 0xae09, 0x0198, 0x660a, 0x2b08,
-	0x6112, 0x080c, 0xcfd4, 0x6023, 0x0001, 0x2900, 0x6016, 0x001e,
-	0x0016, 0x080c, 0xaeda, 0x9085, 0x0001, 0x001e, 0x012e, 0x00ce,
-	0x0005, 0x9006, 0x0cd0, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c,
-	0xaead, 0x0188, 0x2b08, 0x6112, 0x080c, 0xcfd4, 0x6023, 0x0001,
-	0x2900, 0x6016, 0x2009, 0x0000, 0x080c, 0xaeda, 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, 0xcb5a, 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, 0xaead,
-	0x0198, 0x2b08, 0x6112, 0x080c, 0xcfd4, 0x6023, 0x0001, 0x2900,
-	0x6016, 0x080c, 0x31cc, 0x2009, 0x0028, 0x080c, 0xaeda, 0x9085,
-	0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x9186, 0x0015,
-	0x11a8, 0x2011, 0x1824, 0x2204, 0x9086, 0x0074, 0x1178, 0x00b6,
-	0x080c, 0xba75, 0x00be, 0x080c, 0xbc98, 0x6003, 0x0001, 0x6007,
-	0x0029, 0x080c, 0x9140, 0x080c, 0x96a6, 0x0078, 0x6014, 0x0096,
-	0x2048, 0xa868, 0x009e, 0xd0fc, 0x0148, 0x2001, 0x0001, 0x080c,
-	0xd193, 0x080c, 0xb821, 0x080c, 0xae5f, 0x0005, 0x0096, 0x6014,
-	0x904d, 0x090c, 0x0dd5, 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897,
-	0x4005, 0xa89b, 0x0004, 0xa867, 0x0139, 0x0126, 0x2091, 0x8000,
-	0x080c, 0x6c94, 0x012e, 0x009e, 0x080c, 0xae5f, 0x0c30, 0x0096,
-	0x9186, 0x0016, 0x1128, 0x2001, 0x0004, 0x080c, 0x6566, 0x00e8,
-	0x9186, 0x0015, 0x1510, 0x2011, 0x1824, 0x2204, 0x9086, 0x0014,
-	0x11e0, 0x6010, 0x00b6, 0x2058, 0x080c, 0x66b1, 0x00be, 0x080c,
-	0xbd69, 0x1198, 0x6010, 0x00b6, 0x2058, 0xb890, 0x00be, 0x9005,
-	0x0160, 0x2001, 0x0006, 0x080c, 0x6566, 0x6014, 0x2048, 0xa868,
-	0xd0fc, 0x0170, 0x080c, 0xb264, 0x0048, 0x6014, 0x2048, 0xa868,
-	0xd0fc, 0x0528, 0x080c, 0xb821, 0x080c, 0xae5f, 0x009e, 0x0005,
-	0x6014, 0x6310, 0x2358, 0x904d, 0x090c, 0x0dd5, 0xa87b, 0x0000,
-	0xa883, 0x0000, 0xa897, 0x4000, 0x900e, 0x080c, 0x6836, 0x1108,
-	0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0xa99a, 0x0126, 0x2091,
-	0x8000, 0x080c, 0x6c94, 0x012e, 0x080c, 0xae5f, 0x08f8, 0x6014,
-	0x904d, 0x090c, 0x0dd5, 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897,
-	0x4005, 0xa89b, 0x0004, 0xa867, 0x0139, 0x0126, 0x2091, 0x8000,
-	0x080c, 0x6c94, 0x012e, 0x080c, 0xae5f, 0x0840, 0xa878, 0x9086,
-	0x0005, 0x1108, 0x0009, 0x0005, 0xa880, 0xc0ad, 0xa882, 0x0005,
-	0x6043, 0x0000, 0x6017, 0x0000, 0x6003, 0x0001, 0x6007, 0x0050,
-	0x080c, 0x90f8, 0x080c, 0x96a6, 0x0005, 0x00c6, 0x6010, 0x00b6,
-	0x2058, 0xb800, 0x00be, 0xd0bc, 0x0120, 0x6020, 0x9084, 0x000f,
-	0x0013, 0x00ce, 0x0005, 0xc863, 0xce84, 0xce84, 0xce87, 0xe638,
-	0xe653, 0xe656, 0xc863, 0xc863, 0xc863, 0xc863, 0xc863, 0xc863,
-	0xc863, 0xc863, 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, 0xae09, 0x0508, 0x7810, 0x6012, 0x080c, 0xcfd4, 0x7820,
-	0x9086, 0x0003, 0x0128, 0x7808, 0x603a, 0x2f00, 0x603e, 0x0020,
-	0x7808, 0x603e, 0x2f00, 0x603a, 0x602e, 0x6023, 0x0001, 0x6007,
-	0x0035, 0x6003, 0x0001, 0x7954, 0x6156, 0x080c, 0x90f8, 0x080c,
-	0x96a6, 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, 0x90f8, 0x080c, 0x96a6, 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, 0x8f70, 0x2001, 0x1985, 0x82ff, 0x1110,
-	0x2011, 0x0014, 0x2202, 0x2001, 0x1983, 0x200c, 0x8000, 0x2014,
-	0x2071, 0x196b, 0x711a, 0x721e, 0x2001, 0x0064, 0x080c, 0x8f70,
-	0x2001, 0x1986, 0x82ff, 0x1110, 0x2011, 0x0014, 0x2202, 0x2001,
-	0x1987, 0x9288, 0x000a, 0x2102, 0x2001, 0x1a90, 0x2102, 0x2001,
-	0x0032, 0x080c, 0x15f0, 0x080c, 0x696a, 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, 0x1a90, 0x2102, 0x2001, 0x0032, 0x080c, 0x15f0,
-	0x00ee, 0x001e, 0x000e, 0x0005, 0x0096, 0x6058, 0x904d, 0x0110,
-	0x080c, 0x1031, 0x009e, 0x0005, 0x0005, 0x00c6, 0x0126, 0x2091,
-	0x8000, 0x080c, 0xae09, 0x0180, 0x2b08, 0x6112, 0x0ca9, 0x6023,
-	0x0001, 0x2900, 0x6016, 0x2009, 0x0033, 0x080c, 0xaeda, 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, 0x993c, 0x01d8, 0x707c, 0xaa50, 0x9206, 0x1160, 0x7080,
-	0xaa54, 0x9206, 0x1140, 0x6210, 0x00b6, 0x2258, 0xbaa0, 0x00be,
-	0x900e, 0x080c, 0x3215, 0x080c, 0xb264, 0x0020, 0x080c, 0xb821,
-	0x080c, 0xae5f, 0x00fe, 0x00ee, 0x009e, 0x0005, 0x7060, 0xaa54,
-	0x9206, 0x0d48, 0x0c80, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c,
-	0xae09, 0x0188, 0x2b08, 0x6112, 0x080c, 0xcfd4, 0x6023, 0x0001,
-	0x2900, 0x6016, 0x2009, 0x004d, 0x080c, 0xaeda, 0x9085, 0x0001,
-	0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x00c6, 0x0126, 0x2091,
-	0x8000, 0x0016, 0x080c, 0xae09, 0x0180, 0x2b08, 0x6112, 0x080c,
-	0xcfd4, 0x6023, 0x0001, 0x2900, 0x6016, 0x001e, 0x080c, 0xaeda,
-	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, 0xd84a,
-	0x001e, 0xa804, 0x9005, 0x0110, 0x2048, 0x0c38, 0x6014, 0x2048,
-	0xa867, 0x0103, 0x0010, 0x080c, 0xb821, 0x080c, 0xae5f, 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, 0x993c, 0x01a8, 0x707c, 0xaa74, 0x9206, 0x1130, 0x7080,
-	0xaa78, 0x9206, 0x1110, 0x080c, 0x31cc, 0x080c, 0xb264, 0x0020,
-	0x080c, 0xb821, 0x080c, 0xae5f, 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, 0x993c, 0x05f0, 0x707c,
-	0xaacc, 0x9206, 0x1180, 0x7080, 0xaad0, 0x9206, 0x1160, 0x080c,
-	0x31cc, 0x0016, 0xa998, 0xaab0, 0x9284, 0x1000, 0xc0fd, 0x080c,
-	0x569a, 0x001e, 0x0010, 0x080c, 0x548b, 0x080c, 0xcb5a, 0x0508,
-	0xa87b, 0x0000, 0xa883, 0x0000, 0xa897, 0x4000, 0x0080, 0x080c,
-	0xcb5a, 0x01b8, 0x6014, 0x2048, 0x080c, 0x548b, 0x1d70, 0xa87b,
-	0x0030, 0xa883, 0x0000, 0xa897, 0x4005, 0xa89b, 0x0004, 0x0126,
-	0x2091, 0x8000, 0xa867, 0x0139, 0x080c, 0x6c94, 0x012e, 0x080c,
-	0xae5f, 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, 0xcb5a, 0x0904, 0xd18f,
-	0x0096, 0x6314, 0x2348, 0xa87a, 0xa982, 0x929e, 0x4000, 0x1580,
-	0x6310, 0x00c6, 0x2358, 0x2009, 0x0000, 0xa868, 0xd0f4, 0x1140,
-	0x080c, 0x6836, 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, 0x6c88, 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, 0x284b,
-	0x2118, 0x831f, 0x939c, 0xff00, 0x7838, 0x9084, 0x00ff, 0x931d,
-	0x7c3c, 0x2011, 0x8018, 0x080c, 0x4b1e, 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, 0xcb48, 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, 0xc255, 0x0005, 0x0036, 0x2019, 0x0001, 0x0010,
-	0x0036, 0x901e, 0x0499, 0x01e0, 0x080c, 0xcb5a, 0x01c8, 0x080c,
-	0xcd43, 0x6037, 0x4000, 0x6014, 0x6017, 0x0000, 0x0096, 0x2048,
-	0xa87c, 0x080c, 0xcd60, 0x1118, 0x080c, 0xb821, 0x0040, 0xa867,
-	0x0103, 0xa877, 0x0000, 0x83ff, 0x1129, 0x080c, 0x6c94, 0x009e,
-	0x003e, 0x0005, 0xa880, 0xd0b4, 0x0128, 0xa87b, 0x0006, 0xc0ec,
-	0xa882, 0x0048, 0xd0bc, 0x0118, 0xa87b, 0x0002, 0x0020, 0xa87b,
-	0x0005, 0x080c, 0xce54, 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, 0x4cd5, 0x004e, 0x003e, 0x0005, 0x0c51,
-	0x1d81, 0x0005, 0x2001, 0x1985, 0x2004, 0x601a, 0x0005, 0x2001,
-	0x1987, 0x2004, 0x6042, 0x0005, 0x080c, 0xae5f, 0x0804, 0x96a6,
-	0x00b6, 0x0066, 0x6000, 0x90b2, 0x0016, 0x1a0c, 0x0dd5, 0x001b,
-	0x006e, 0x00be, 0x0005, 0xd29b, 0xd9a7, 0xdb04, 0xd29b, 0xd29b,
-	0xd29b, 0xd29b, 0xd29b, 0xd2d2, 0xdb88, 0xd29b, 0xd29b, 0xd29b,
-	0xd29b, 0xd29b, 0xd29b, 0x080c, 0x0dd5, 0x0066, 0x6000, 0x90b2,
-	0x0016, 0x1a0c, 0x0dd5, 0x0013, 0x006e, 0x0005, 0xd2b6, 0xe0fa,
-	0xd2b6, 0xd2b6, 0xd2b6, 0xd2b6, 0xd2b6, 0xd2b6, 0xe0a7, 0xe14e,
-	0xd2b6, 0xe773, 0xe7a9, 0xe773, 0xe7a9, 0xd2b6, 0x080c, 0x0dd5,
-	0x6000, 0x9082, 0x0016, 0x1a0c, 0x0dd5, 0x6000, 0x000a, 0x0005,
-	0xd2d0, 0xdd66, 0xde58, 0xde7b, 0xdf3b, 0xd2d0, 0xe01a, 0xdfc3,
-	0xdb94, 0xe07d, 0xe092, 0xd2d0, 0xd2d0, 0xd2d0, 0xd2d0, 0xd2d0,
-	0x080c, 0x0dd5, 0x91b2, 0x0053, 0x1a0c, 0x0dd5, 0x2100, 0x91b2,
-	0x0040, 0x1a04, 0xd71b, 0x0002, 0xd31c, 0xd50c, 0xd31c, 0xd31c,
-	0xd31c, 0xd515, 0xd31c, 0xd31c, 0xd31c, 0xd31c, 0xd31c, 0xd31c,
-	0xd31c, 0xd31c, 0xd31c, 0xd31c, 0xd31c, 0xd31c, 0xd31c, 0xd31c,
-	0xd31c, 0xd31c, 0xd31c, 0xd31e, 0xd381, 0xd390, 0xd3f4, 0xd41f,
-	0xd498, 0xd4f7, 0xd31c, 0xd31c, 0xd518, 0xd31c, 0xd31c, 0xd52d,
-	0xd53a, 0xd31c, 0xd31c, 0xd31c, 0xd31c, 0xd31c, 0xd5bd, 0xd31c,
-	0xd31c, 0xd5d1, 0xd31c, 0xd31c, 0xd58c, 0xd31c, 0xd31c, 0xd31c,
-	0xd5e9, 0xd31c, 0xd31c, 0xd31c, 0xd666, 0xd31c, 0xd31c, 0xd31c,
-	0xd31c, 0xd31c, 0xd31c, 0xd6e3, 0x080c, 0x0dd5, 0x080c, 0x6947,
-	0x1150, 0x2001, 0x1837, 0x2004, 0xd0cc, 0x1128, 0x9084, 0x0009,
-	0x9086, 0x0008, 0x1140, 0x6007, 0x0009, 0x602f, 0x0009, 0x6017,
-	0x0000, 0x0804, 0xd505, 0x080c, 0x68e3, 0x00e6, 0x00c6, 0x0036,
-	0x0026, 0x0016, 0x6210, 0x2258, 0xbaa0, 0x0026, 0x2019, 0x0029,
-	0x080c, 0x929d, 0x0076, 0x903e, 0x080c, 0x9170, 0x2c08, 0x080c,
-	0xe326, 0x007e, 0x001e, 0x001e, 0x002e, 0x003e, 0x00ce, 0x00ee,
-	0x6610, 0x2658, 0x080c, 0x6625, 0xbe04, 0x9684, 0x00ff, 0x9082,
-	0x0006, 0x1268, 0x0016, 0x0026, 0x6210, 0x00b6, 0x2258, 0xbaa0,
-	0x00be, 0x2c08, 0x080c, 0xe9d2, 0x002e, 0x001e, 0x1178, 0x080c,
-	0xe258, 0x1904, 0xd3ec, 0x080c, 0xe1f4, 0x1120, 0x6007, 0x0008,
-	0x0804, 0xd505, 0x6007, 0x0009, 0x0804, 0xd505, 0x080c, 0xe47c,
-	0x0128, 0x080c, 0xe258, 0x0d78, 0x0804, 0xd3ec, 0x6017, 0x1900,
-	0x0c88, 0x080c, 0x32f0, 0x1904, 0xd718, 0x6106, 0x080c, 0xe1a9,
-	0x6007, 0x0006, 0x0804, 0xd505, 0x6007, 0x0007, 0x0804, 0xd505,
-	0x080c, 0xe7e5, 0x1904, 0xd718, 0x080c, 0x32f0, 0x1904, 0xd718,
-	0x00d6, 0x6610, 0x2658, 0xbe04, 0x9684, 0x00ff, 0x9082, 0x0006,
-	0x1220, 0x2001, 0x0001, 0x080c, 0x6552, 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, 0xe2bc, 0x1190, 0x9686, 0x0006, 0x1140,
-	0x0026, 0x6210, 0x2258, 0xbaa0, 0x900e, 0x080c, 0x3215, 0x002e,
-	0x080c, 0x66b1, 0x6007, 0x000a, 0x00de, 0x0804, 0xd505, 0x6007,
-	0x000b, 0x00de, 0x0804, 0xd505, 0x080c, 0x31cc, 0x080c, 0xd26f,
-	0x6007, 0x0001, 0x0804, 0xd505, 0x080c, 0xe7e5, 0x1904, 0xd718,
-	0x080c, 0x32f0, 0x1904, 0xd718, 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, 0x3215, 0x002e, 0x6007,
-	0x000c, 0x2001, 0x0001, 0x080c, 0xe9b2, 0x0804, 0xd505, 0x080c,
-	0x6947, 0x1140, 0x2001, 0x1837, 0x2004, 0x9084, 0x0009, 0x9086,
-	0x0008, 0x1110, 0x0804, 0xd32b, 0x080c, 0x68e3, 0x6610, 0x2658,
-	0xbe04, 0x9684, 0x00ff, 0x9082, 0x0006, 0x06c8, 0x1138, 0x0026,
-	0x2001, 0x0006, 0x080c, 0x6592, 0x002e, 0x0050, 0x96b4, 0xff00,
-	0x8637, 0x9686, 0x0004, 0x0120, 0x9686, 0x0006, 0x1904, 0xd3ec,
-	0x080c, 0xe2c9, 0x1120, 0x6007, 0x000e, 0x0804, 0xd505, 0x0046,
-	0x6410, 0x2458, 0xbca0, 0x0046, 0x080c, 0x31cc, 0x080c, 0xd26f,
-	0x004e, 0x0016, 0x9006, 0x2009, 0x1848, 0x210c, 0xd1a4, 0x0148,
-	0x2009, 0x0029, 0x080c, 0xe5e9, 0x6010, 0x2058, 0xb800, 0xc0e5,
-	0xb802, 0x001e, 0x004e, 0x6007, 0x0001, 0x0804, 0xd505, 0x2001,
-	0x0001, 0x080c, 0x6552, 0x0156, 0x0016, 0x0026, 0x0036, 0x20a9,
-	0x0004, 0x2019, 0x1805, 0x2011, 0x0270, 0x080c, 0xbe19, 0x003e,
-	0x002e, 0x001e, 0x015e, 0x9005, 0x0168, 0x96b4, 0xff00, 0x8637,
-	0x9682, 0x0004, 0x0a04, 0xd3ec, 0x9682, 0x0007, 0x0a04, 0xd448,
-	0x0804, 0xd3ec, 0x6017, 0x1900, 0x6007, 0x0009, 0x0804, 0xd505,
-	0x080c, 0x6947, 0x1140, 0x2001, 0x1837, 0x2004, 0x9084, 0x0009,
-	0x9086, 0x0008, 0x1110, 0x0804, 0xd32b, 0x080c, 0x68e3, 0x6610,
-	0x2658, 0xbe04, 0x9684, 0x00ff, 0x0006, 0x9086, 0x0001, 0x000e,
-	0x0170, 0x9082, 0x0006, 0x0698, 0x0150, 0x96b4, 0xff00, 0x8637,
-	0x9686, 0x0004, 0x0120, 0x9686, 0x0006, 0x1904, 0xd3ec, 0x080c,
-	0xe2f7, 0x1130, 0x080c, 0xe1f4, 0x1118, 0x6007, 0x0010, 0x04e8,
-	0x0046, 0x6410, 0x2458, 0xbca0, 0x0046, 0x080c, 0x31cc, 0x080c,
-	0xd26f, 0x004e, 0x0016, 0x9006, 0x2009, 0x1848, 0x210c, 0xd1a4,
-	0x0148, 0x2009, 0x0029, 0x080c, 0xe5e9, 0x6010, 0x2058, 0xb800,
-	0xc0e5, 0xb802, 0x001e, 0x004e, 0x6007, 0x0001, 0x00f0, 0x080c,
-	0xe47c, 0x0140, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0006, 0x0978,
-	0x0804, 0xd3ec, 0x6017, 0x1900, 0x6007, 0x0009, 0x0070, 0x080c,
-	0x32f0, 0x1904, 0xd718, 0x080c, 0xe7e5, 0x1904, 0xd718, 0x080c,
-	0xd8e5, 0x1904, 0xd3ec, 0x6007, 0x0012, 0x6003, 0x0001, 0x080c,
-	0x9140, 0x080c, 0x96a6, 0x0005, 0x6007, 0x0001, 0x6003, 0x0001,
-	0x080c, 0x9140, 0x080c, 0x96a6, 0x0cb0, 0x6007, 0x0005, 0x0c68,
-	0x080c, 0xe7e5, 0x1904, 0xd718, 0x080c, 0x32f0, 0x1904, 0xd718,
-	0x080c, 0xd8e5, 0x1904, 0xd3ec, 0x6007, 0x0020, 0x6003, 0x0001,
-	0x080c, 0x9140, 0x080c, 0x96a6, 0x0005, 0x080c, 0x32f0, 0x1904,
-	0xd718, 0x6007, 0x0023, 0x6003, 0x0001, 0x080c, 0x9140, 0x080c,
-	0x96a6, 0x0005, 0x080c, 0xe7e5, 0x1904, 0xd718, 0x080c, 0x32f0,
-	0x1904, 0xd718, 0x080c, 0xd8e5, 0x1904, 0xd3ec, 0x0016, 0x0026,
-	0x00e6, 0x2071, 0x0260, 0x7244, 0x9286, 0xffff, 0x0180, 0x2c08,
-	0x080c, 0xcb48, 0x01b0, 0x2260, 0x7240, 0x6008, 0x9206, 0x1188,
-	0x6010, 0x9190, 0x0004, 0x2214, 0x9206, 0x01b8, 0x0050, 0x7240,
-	0x2c08, 0x9006, 0x080c, 0xe5b3, 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, 0xae5f, 0x2160,
-	0x6007, 0x0025, 0x6003, 0x0001, 0x080c, 0x9140, 0x080c, 0x96a6,
-	0x00ee, 0x002e, 0x001e, 0x0005, 0x2001, 0x0001, 0x080c, 0x6552,
-	0x0156, 0x0016, 0x0026, 0x0036, 0x20a9, 0x0004, 0x2019, 0x1805,
-	0x2011, 0x0276, 0x080c, 0xbe19, 0x003e, 0x002e, 0x001e, 0x015e,
-	0x0120, 0x6007, 0x0031, 0x0804, 0xd505, 0x080c, 0xba8d, 0x080c,
-	0x73b3, 0x1190, 0x0006, 0x0026, 0x0036, 0x080c, 0x73cd, 0x1138,
-	0x080c, 0x7699, 0x080c, 0x602d, 0x080c, 0x72e5, 0x0010, 0x080c,
-	0x738b, 0x003e, 0x002e, 0x000e, 0x0005, 0x080c, 0x32f0, 0x1904,
-	0xd718, 0x080c, 0xd8e5, 0x1904, 0xd3ec, 0x6106, 0x080c, 0xd901,
-	0x1120, 0x6007, 0x002b, 0x0804, 0xd505, 0x6007, 0x002c, 0x0804,
-	0xd505, 0x080c, 0xe7e5, 0x1904, 0xd718, 0x080c, 0x32f0, 0x1904,
-	0xd718, 0x080c, 0xd8e5, 0x1904, 0xd3ec, 0x6106, 0x080c, 0xd906,
-	0x1120, 0x6007, 0x002e, 0x0804, 0xd505, 0x6007, 0x002f, 0x0804,
-	0xd505, 0x080c, 0x32f0, 0x1904, 0xd718, 0x00e6, 0x00d6, 0x00c6,
-	0x6010, 0x2058, 0xb904, 0x9184, 0x00ff, 0x9086, 0x0006, 0x0158,
-	0x9184, 0xff00, 0x8007, 0x9086, 0x0006, 0x0128, 0x00ce, 0x00de,
-	0x00ee, 0x0804, 0xd50c, 0x080c, 0x56e6, 0xd0e4, 0x0904, 0xd663,
-	0x2071, 0x026c, 0x7010, 0x603a, 0x7014, 0x603e, 0x7108, 0x720c,
-	0x080c, 0x6985, 0x0140, 0x6010, 0x2058, 0xb810, 0x9106, 0x1118,
-	0xb814, 0x9206, 0x0510, 0x080c, 0x6981, 0x15b8, 0x2069, 0x1800,
-	0x6880, 0x9206, 0x1590, 0x687c, 0x9106, 0x1578, 0x7210, 0x080c,
-	0xcb48, 0x0590, 0x080c, 0xd7d0, 0x0578, 0x080c, 0xe665, 0x0560,
-	0x622e, 0x6007, 0x0036, 0x6003, 0x0001, 0x080c, 0x90f8, 0x080c,
-	0x96a6, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x7214, 0x9286, 0xffff,
-	0x0150, 0x080c, 0xcb48, 0x01c0, 0x9280, 0x0002, 0x2004, 0x7110,
-	0x9106, 0x1190, 0x08e0, 0x7210, 0x2c08, 0x9085, 0x0001, 0x080c,
-	0xe5b3, 0x2c10, 0x2160, 0x0140, 0x0890, 0x6007, 0x0037, 0x602f,
-	0x0009, 0x6017, 0x1500, 0x08b8, 0x6007, 0x0037, 0x602f, 0x0003,
-	0x6017, 0x1700, 0x0880, 0x6007, 0x0012, 0x0868, 0x080c, 0x32f0,
-	0x1904, 0xd718, 0x6010, 0x2058, 0xb804, 0x9084, 0xff00, 0x8007,
-	0x9086, 0x0006, 0x1904, 0xd50c, 0x00e6, 0x00d6, 0x00c6, 0x080c,
-	0x56e6, 0xd0e4, 0x0904, 0xd6db, 0x2069, 0x1800, 0x2071, 0x026c,
-	0x7008, 0x603a, 0x720c, 0x623e, 0x9286, 0xffff, 0x1150, 0x7208,
-	0x00c6, 0x2c08, 0x9085, 0x0001, 0x080c, 0xe5b3, 0x2c10, 0x00ce,
-	0x05e8, 0x080c, 0xcb48, 0x05d0, 0x7108, 0x9280, 0x0002, 0x2004,
-	0x9106, 0x15a0, 0x00c6, 0x0026, 0x2260, 0x080c, 0xc76e, 0x002e,
-	0x00ce, 0x7118, 0x918c, 0xff00, 0x810f, 0x9186, 0x0001, 0x0178,
-	0x9186, 0x0005, 0x0118, 0x9186, 0x0007, 0x1198, 0x9280, 0x0005,
-	0x2004, 0x9005, 0x0170, 0x080c, 0xd7d0, 0x0904, 0xd65c, 0x0056,
-	0x7510, 0x7614, 0x080c, 0xe67e, 0x005e, 0x00ce, 0x00de, 0x00ee,
-	0x0005, 0x6007, 0x003b, 0x602f, 0x0009, 0x6017, 0x2a00, 0x6003,
-	0x0001, 0x080c, 0x90f8, 0x080c, 0x96a6, 0x0c78, 0x6007, 0x003b,
-	0x602f, 0x0003, 0x6017, 0x0300, 0x6003, 0x0001, 0x080c, 0x90f8,
-	0x080c, 0x96a6, 0x0c10, 0x6007, 0x003b, 0x602f, 0x000b, 0x6017,
-	0x0000, 0x0804, 0xd633, 0x00e6, 0x0026, 0x080c, 0x6947, 0x0550,
-	0x080c, 0x68e3, 0x080c, 0xe857, 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, 0x6985, 0x0120, 0x2011,
-	0x19ff, 0x2013, 0x07d0, 0xd0ac, 0x1128, 0x080c, 0x2fa3, 0x0010,
-	0x080c, 0xe889, 0x002e, 0x00ee, 0x080c, 0xae5f, 0x0804, 0xd50b,
-	0x080c, 0xae5f, 0x0005, 0x2600, 0x0002, 0xd72f, 0xd760, 0xd771,
-	0xd72f, 0xd72f, 0xd731, 0xd782, 0xd72f, 0xd72f, 0xd72f, 0xd74e,
-	0xd72f, 0xd72f, 0xd72f, 0xd78d, 0xd79a, 0xd7cb, 0xd72f, 0x080c,
-	0x0dd5, 0x080c, 0xe7e5, 0x1d20, 0x080c, 0x32f0, 0x1d08, 0x080c,
-	0xd8e5, 0x1148, 0x7038, 0x6016, 0x6007, 0x0045, 0x6003, 0x0001,
-	0x080c, 0x9140, 0x0005, 0x080c, 0x31cc, 0x080c, 0xd26f, 0x6007,
-	0x0001, 0x6003, 0x0001, 0x080c, 0x9140, 0x0005, 0x080c, 0xe7e5,
-	0x1938, 0x080c, 0x32f0, 0x1920, 0x080c, 0xd8e5, 0x1d60, 0x703c,
-	0x6016, 0x6007, 0x004a, 0x6003, 0x0001, 0x080c, 0x9140, 0x0005,
-	0x080c, 0x32f0, 0x1904, 0xd718, 0x2009, 0x0041, 0x080c, 0xe892,
-	0x6007, 0x0047, 0x6003, 0x0001, 0x080c, 0x9140, 0x080c, 0x96a6,
-	0x0005, 0x080c, 0x32f0, 0x1904, 0xd718, 0x2009, 0x0042, 0x080c,
-	0xe892, 0x6007, 0x0047, 0x6003, 0x0001, 0x080c, 0x9140, 0x080c,
-	0x96a6, 0x0005, 0x080c, 0x32f0, 0x1904, 0xd718, 0x2009, 0x0046,
-	0x080c, 0xe892, 0x080c, 0xae5f, 0x0005, 0x080c, 0xd7ed, 0x0904,
-	0xd718, 0x6007, 0x004e, 0x6003, 0x0001, 0x080c, 0x9140, 0x080c,
-	0x96a6, 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, 0xbe2d,
-	0x009e, 0x0110, 0x6017, 0x0001, 0x6003, 0x0001, 0x080c, 0x9140,
-	0x080c, 0x96a6, 0x0005, 0x6007, 0x0050, 0x703c, 0x6016, 0x0ca0,
-	0x0016, 0x00e6, 0x2071, 0x0260, 0x00b6, 0x00c6, 0x2260, 0x6010,
-	0x2058, 0xb8cc, 0xd084, 0x0150, 0x7128, 0x6048, 0x9106, 0x1120,
-	0x712c, 0x6044, 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, 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, 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,
-	0x0fb1, 0x9006, 0x012e, 0x01de, 0x01ce, 0x00ee, 0x008e, 0x009e,
-	0x001e, 0x0005, 0x0006, 0x0016, 0x0026, 0x0036, 0x00c6, 0x918c,
-	0xffff, 0x11a8, 0x080c, 0x23b8, 0x2099, 0x026c, 0x2001, 0x0014,
-	0x3518, 0x9312, 0x1218, 0x23a8, 0x4003, 0x00f8, 0x20a8, 0x4003,
-	0x22a8, 0x8108, 0x080c, 0x23b8, 0x2099, 0x0260, 0x0ca8, 0x080c,
-	0x23b8, 0x2061, 0x199f, 0x6004, 0x2098, 0x6008, 0x3518, 0x9312,
-	0x1218, 0x23a8, 0x4003, 0x0048, 0x20a8, 0x4003, 0x22a8, 0x8108,
-	0x080c, 0x23b8, 0x2099, 0x0260, 0x0ca8, 0x2061, 0x199f, 0x2019,
-	0x0280, 0x3300, 0x931e, 0x0110, 0x6006, 0x0020, 0x2001, 0x0260,
+	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,
+	0x0005, 0x0026, 0x0036, 0x0046, 0x00b6, 0x0096, 0x00f6, 0x6214,
+	0x2248, 0x6210, 0x2258, 0x2079, 0x0260, 0x9096, 0x0000, 0x11a0,
+	0xb814, 0x9084, 0x00ff, 0x900e, 0x080c, 0x287c, 0x2118, 0x831f,
+	0x939c, 0xff00, 0x7838, 0x9084, 0x00ff, 0x931d, 0x7c3c, 0x2011,
+	0x8018, 0x080c, 0x4b7f, 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,
+	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,
+	0x4000, 0x6014, 0x6017, 0x0000, 0x0096, 0x2048, 0xa87c, 0x080c,
+	0xce8e, 0x1118, 0x080c, 0xb905, 0x0040, 0xa867, 0x0103, 0xa877,
+	0x0000, 0x83ff, 0x1129, 0x080c, 0x6d17, 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,
+	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,
+	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,
+	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, 0x0fb1, 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, 0x0006, 0x0016,
-	0x0026, 0x0036, 0x00c6, 0x81ff, 0x11b8, 0x080c, 0x23d0, 0x20a1,
-	0x024c, 0x2001, 0x0014, 0x3518, 0x9312, 0x1218, 0x23a8, 0x4003,
-	0x0418, 0x20a8, 0x4003, 0x82ff, 0x01f8, 0x22a8, 0x8108, 0x080c,
-	0x23d0, 0x20a1, 0x0240, 0x0c98, 0x080c, 0x23d0, 0x2061, 0x19a2,
-	0x6004, 0x20a0, 0x6008, 0x3518, 0x9312, 0x1218, 0x23a8, 0x4003,
-	0x0058, 0x20a8, 0x4003, 0x82ff, 0x0138, 0x22a8, 0x8108, 0x080c,
-	0x23d0, 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, 0xd97d, 0x00de, 0x0005, 0x00d6, 0x080c,
-	0xd98a, 0x1520, 0x680c, 0x908c, 0xff00, 0x6820, 0x9084, 0x00ff,
-	0x9115, 0x6216, 0x6824, 0x602e, 0xd1e4, 0x0130, 0x9006, 0x080c,
-	0xe9b2, 0x2009, 0x0001, 0x0078, 0xd1ec, 0x0180, 0x6920, 0x918c,
-	0x00ff, 0x6824, 0x080c, 0x284b, 0x1148, 0x2001, 0x0001, 0x080c,
-	0xe9b2, 0x2110, 0x900e, 0x080c, 0x3215, 0x0018, 0x9085, 0x0001,
-	0x0008, 0x9006, 0x00de, 0x0005, 0x00b6, 0x00c6, 0x080c, 0xaead,
-	0x05a8, 0x0016, 0x0026, 0x00c6, 0x2011, 0x0263, 0x2204, 0x8211,
-	0x220c, 0x080c, 0x284b, 0x1578, 0x080c, 0x65b5, 0x1560, 0xbe12,
-	0xbd16, 0x00ce, 0x002e, 0x001e, 0x2b00, 0x6012, 0x080c, 0xe7e5,
-	0x11d8, 0x080c, 0x32f0, 0x11c0, 0x080c, 0xd8e5, 0x0510, 0x2001,
-	0x0007, 0x080c, 0x6566, 0x2001, 0x0007, 0x080c, 0x6592, 0x6017,
-	0x0000, 0x6023, 0x0001, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c,
-	0x9140, 0x080c, 0x96a6, 0x0010, 0x080c, 0xae5f, 0x9085, 0x0001,
-	0x00ce, 0x00be, 0x0005, 0x080c, 0xae5f, 0x00ce, 0x002e, 0x001e,
-	0x0ca8, 0x080c, 0xae5f, 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, 0xdad4, 0x0092, 0x91b6, 0x0027, 0x0120,
-	0x91b6, 0x0014, 0x190c, 0x0dd5, 0x2001, 0x0007, 0x080c, 0x6592,
-	0x080c, 0x959a, 0x080c, 0xae90, 0x080c, 0x96a6, 0x0005, 0xda07,
-	0xda09, 0xda07, 0xda07, 0xda07, 0xda09, 0xda18, 0xdacd, 0xda6a,
-	0xdacd, 0xda7e, 0xdacd, 0xda18, 0xdacd, 0xdac5, 0xdacd, 0xdac5,
-	0xdacd, 0xdacd, 0xda07, 0xda07, 0xda07, 0xda07, 0xda07, 0xda07,
-	0xda07, 0xda07, 0xda07, 0xda07, 0xda07, 0xda09, 0xda07, 0xdacd,
-	0xda07, 0xda07, 0xdacd, 0xda07, 0xdaca, 0xdacd, 0xda07, 0xda07,
-	0xda07, 0xda07, 0xdacd, 0xdacd, 0xda07, 0xdacd, 0xdacd, 0xda07,
-	0xda13, 0xda07, 0xda07, 0xda07, 0xda07, 0xdac9, 0xdacd, 0xda07,
-	0xda07, 0xdacd, 0xdacd, 0xda07, 0xda07, 0xda07, 0xda07, 0x080c,
-	0x0dd5, 0x080c, 0x959a, 0x080c, 0xd272, 0x6003, 0x0002, 0x080c,
-	0x96a6, 0x0804, 0xdad3, 0x9006, 0x080c, 0x6552, 0x0804, 0xdacd,
-	0x080c, 0x6981, 0x1904, 0xdacd, 0x9006, 0x080c, 0x6552, 0x6010,
-	0x2058, 0xb810, 0x9086, 0x00ff, 0x1140, 0x00f6, 0x2079, 0x1800,
-	0x78a8, 0x8000, 0x78aa, 0x00fe, 0x0428, 0x6010, 0x2058, 0xb8c0,
-	0x9005, 0x1178, 0x080c, 0xd25a, 0x1904, 0xdacd, 0x0036, 0x0046,
-	0xbba0, 0x2021, 0x0007, 0x080c, 0x4cd5, 0x004e, 0x003e, 0x0804,
-	0xdacd, 0x080c, 0x3321, 0x1904, 0xdacd, 0x2001, 0x1800, 0x2004,
-	0x9086, 0x0002, 0x1138, 0x00f6, 0x2079, 0x1800, 0x78a8, 0x8000,
-	0x78aa, 0x00fe, 0x2001, 0x0002, 0x080c, 0x6566, 0x080c, 0x959a,
-	0x6023, 0x0001, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x9140,
-	0x080c, 0x96a6, 0x6110, 0x2158, 0x2009, 0x0001, 0x080c, 0x8507,
-	0x0804, 0xdad3, 0x6610, 0x2658, 0xbe04, 0x96b4, 0xff00, 0x8637,
-	0x9686, 0x0006, 0x0904, 0xdacd, 0x9686, 0x0004, 0x0904, 0xdacd,
-	0x080c, 0x8cc3, 0x2001, 0x0004, 0x0804, 0xdacb, 0x2001, 0x1800,
-	0x2004, 0x9086, 0x0003, 0x1158, 0x0036, 0x0046, 0x6010, 0x2058,
-	0xbba0, 0x2021, 0x0006, 0x080c, 0x4cd5, 0x004e, 0x003e, 0x2001,
-	0x0006, 0x080c, 0xdaf1, 0x6610, 0x2658, 0xbe04, 0x0066, 0x96b4,
-	0xff00, 0x8637, 0x9686, 0x0006, 0x006e, 0x0168, 0x2001, 0x0006,
-	0x080c, 0x6592, 0x9284, 0x00ff, 0x908e, 0x0007, 0x1120, 0x2001,
-	0x0006, 0x080c, 0x6566, 0x080c, 0x6981, 0x11f8, 0x2001, 0x1837,
-	0x2004, 0xd0a4, 0x01d0, 0xbe04, 0x96b4, 0x00ff, 0x9686, 0x0006,
-	0x01a0, 0x00f6, 0x2079, 0x1800, 0x78a8, 0x8000, 0x78aa, 0x00fe,
-	0x0804, 0xda52, 0x2001, 0x0004, 0x0030, 0x2001, 0x0006, 0x0449,
-	0x0020, 0x0018, 0x0010, 0x080c, 0x6592, 0x080c, 0x959a, 0x080c,
-	0xae5f, 0x080c, 0x96a6, 0x0005, 0x2600, 0x0002, 0xdae8, 0xdae8,
-	0xdae8, 0xdae8, 0xdae8, 0xdaea, 0xdae8, 0xdaea, 0xdae8, 0xdae8,
-	0xdaea, 0xdae8, 0xdae8, 0xdae8, 0xdaea, 0xdaea, 0xdaea, 0xdaea,
-	0x080c, 0x0dd5, 0x080c, 0x959a, 0x080c, 0xae5f, 0x080c, 0x96a6,
-	0x0005, 0x0016, 0x00b6, 0x00d6, 0x6110, 0x2158, 0xb900, 0xd184,
-	0x0138, 0x080c, 0x6566, 0x9006, 0x080c, 0x6552, 0x080c, 0x31f5,
-	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, 0xb90a, 0xb90a, 0xb90a, 0xb90a, 0xdb86, 0xb90a, 0xdb70,
-	0xdb31, 0xb90a, 0xb90a, 0xb90a, 0xb90a, 0xb90a, 0xb90a, 0xb90a,
-	0xb90a, 0xdb86, 0xb90a, 0xdb70, 0xdb77, 0xb90a, 0xb90a, 0xb90a,
-	0xb90a, 0x00f6, 0x080c, 0x6981, 0x11d8, 0x080c, 0xd25a, 0x11c0,
-	0x6010, 0x905d, 0x01a8, 0xb8c0, 0x9005, 0x0190, 0x9006, 0x080c,
-	0x6552, 0x2001, 0x0002, 0x080c, 0x6566, 0x6023, 0x0001, 0x6003,
-	0x0001, 0x6007, 0x0002, 0x080c, 0x9140, 0x080c, 0x96a6, 0x00f0,
-	0x2011, 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x284b, 0x11b0,
-	0x080c, 0x6616, 0x0118, 0x080c, 0xae5f, 0x0080, 0xb810, 0x0006,
-	0xb814, 0x0006, 0xb8c0, 0x0006, 0x080c, 0x6047, 0x000e, 0xb8c2,
-	0x000e, 0xb816, 0x000e, 0xb812, 0x080c, 0xae5f, 0x00fe, 0x0005,
-	0x6604, 0x96b6, 0x001e, 0x1110, 0x080c, 0xae5f, 0x0005, 0x080c,
-	0xbc95, 0x1148, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x9140,
-	0x080c, 0x96a6, 0x0010, 0x080c, 0xae5f, 0x0005, 0x0804, 0xae5f,
-	0x6004, 0x908a, 0x0053, 0x1a0c, 0x0dd5, 0x080c, 0x959a, 0x080c,
-	0xae90, 0x080c, 0x96a6, 0x0005, 0x9182, 0x0040, 0x0002, 0xdbab,
-	0xdbab, 0xdbab, 0xdbab, 0xdbad, 0xdbab, 0xdbab, 0xdbab, 0xdbab,
-	0xdbab, 0xdbab, 0xdbab, 0xdbab, 0xdbab, 0xdbab, 0xdbab, 0xdbab,
-	0xdbab, 0xdbab, 0xdbab, 0x080c, 0x0dd5, 0x0096, 0x00b6, 0x00d6,
-	0x00e6, 0x00f6, 0x0046, 0x0026, 0x6210, 0x2258, 0xb8bc, 0x9005,
-	0x11a8, 0x6106, 0x2071, 0x0260, 0x7444, 0x94a4, 0xff00, 0x0904,
-	0xdc13, 0x080c, 0xe9a6, 0x1170, 0x9486, 0x2000, 0x1158, 0x2009,
-	0x0001, 0x2011, 0x0200, 0x080c, 0x86e3, 0x0020, 0x9026, 0x080c,
-	0xe82a, 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,
-	0x6c94, 0x001e, 0x080c, 0xe9a6, 0x1904, 0xdc73, 0x9486, 0x2000,
-	0x1130, 0x2019, 0x0017, 0x080c, 0xe55d, 0x0804, 0xdc73, 0x9486,
-	0x0200, 0x1120, 0x080c, 0xe4f9, 0x0804, 0xdc73, 0x9486, 0x0400,
-	0x0120, 0x9486, 0x1000, 0x1904, 0xdc73, 0x2019, 0x0002, 0x080c,
-	0xe514, 0x0804, 0xdc73, 0x2069, 0x1a70, 0x6a00, 0xd284, 0x0904,
-	0xdcdd, 0x9284, 0x0300, 0x1904, 0xdcd6, 0x6804, 0x9005, 0x0904,
-	0xdcbe, 0x2d78, 0x6003, 0x0007, 0x080c, 0x1018, 0x0904, 0xdc7f,
-	0x7800, 0xd08c, 0x1118, 0x7804, 0x8001, 0x7806, 0x6017, 0x0000,
-	0x2001, 0x180f, 0x2004, 0xd084, 0x1904, 0xdce1, 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, 0xdc7b, 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, 0x6c94, 0x002e, 0x004e, 0x00fe, 0x00ee, 0x00de,
-	0x00be, 0x009e, 0x0005, 0x0000, 0x0080, 0x0040, 0x0000, 0x2001,
-	0x1810, 0x2004, 0xd084, 0x0120, 0x080c, 0x0fff, 0x1904, 0xdc28,
-	0x6017, 0xf100, 0x6003, 0x0001, 0x6007, 0x0041, 0x080c, 0x90f8,
-	0x080c, 0x96a6, 0x0c00, 0x2069, 0x0260, 0x6848, 0x9084, 0xff00,
-	0x9086, 0x1200, 0x1198, 0x686c, 0x9084, 0x00ff, 0x0016, 0x6114,
-	0x918c, 0xf700, 0x910d, 0x6116, 0x001e, 0x6003, 0x0001, 0x6007,
-	0x0043, 0x080c, 0x90f8, 0x080c, 0x96a6, 0x0828, 0x6868, 0x602e,
-	0x686c, 0x6032, 0x6017, 0xf200, 0x6003, 0x0001, 0x6007, 0x0041,
-	0x080c, 0x90f8, 0x080c, 0x96a6, 0x0804, 0xdc73, 0x2001, 0x180e,
-	0x2004, 0xd0ec, 0x0120, 0x2011, 0x8049, 0x080c, 0x4b1e, 0x6017,
-	0xf300, 0x0010, 0x6017, 0xf100, 0x6003, 0x0001, 0x6007, 0x0041,
-	0x080c, 0x90f8, 0x080c, 0x96a6, 0x0804, 0xdc73, 0x6017, 0xf500,
-	0x0c98, 0x6017, 0xf600, 0x0804, 0xdc93, 0x6017, 0xf200, 0x0804,
-	0xdc93, 0xa867, 0x0146, 0xa86b, 0x0000, 0x6008, 0xa886, 0x2c00,
-	0xa87a, 0x7044, 0x9084, 0x0003, 0x9080, 0xdc7b, 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, 0xdd5d, 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, 0xdc7f,
-	0x2548, 0x8847, 0x9885, 0x0046, 0xa866, 0x2009, 0x0205, 0x200b,
-	0x0000, 0x080c, 0xe58c, 0x0804, 0xdc73, 0x8010, 0x0004, 0x801a,
-	0x0006, 0x8018, 0x0008, 0x8016, 0x000a, 0x8014, 0x9186, 0x0013,
-	0x1160, 0x6004, 0x908a, 0x0054, 0x1a0c, 0x0dd5, 0x9082, 0x0040,
-	0x0a0c, 0x0dd5, 0x2008, 0x0804, 0xde0f, 0x9186, 0x0051, 0x0108,
-	0x00c0, 0x2001, 0x0109, 0x2004, 0xd084, 0x0904, 0xddbf, 0x0126,
-	0x2091, 0x2800, 0x0006, 0x0016, 0x0026, 0x080c, 0x8fdd, 0x002e,
-	0x001e, 0x000e, 0x012e, 0x6000, 0x9086, 0x0002, 0x1580, 0x0804,
-	0xde58, 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, 0x8fdd, 0x002e, 0x001e, 0x000e,
-	0x00ce, 0x012e, 0x00ce, 0x6000, 0x9086, 0x0004, 0x190c, 0x0dd5,
-	0x0804, 0xdf3b, 0x6004, 0x9082, 0x0040, 0x2008, 0x001a, 0x080c,
-	0xaef5, 0x0005, 0xddd6, 0xddd8, 0xddd8, 0xddff, 0xddd6, 0xddd6,
-	0xddd6, 0xddd6, 0xddd6, 0xddd6, 0xddd6, 0xddd6, 0xddd6, 0xddd6,
-	0xddd6, 0xddd6, 0xddd6, 0xddd6, 0xddd6, 0xddd6, 0x080c, 0x0dd5,
-	0x080c, 0x959a, 0x080c, 0x96a6, 0x0036, 0x0096, 0x6014, 0x904d,
-	0x01d8, 0x080c, 0xcb5a, 0x01c0, 0x6003, 0x0002, 0x6010, 0x00b6,
-	0x2058, 0xb800, 0x00be, 0xd0bc, 0x1178, 0x2019, 0x0004, 0x080c,
-	0xe58c, 0x6017, 0x0000, 0x6018, 0x9005, 0x1120, 0x2001, 0x1986,
-	0x2004, 0x601a, 0x6003, 0x0007, 0x009e, 0x003e, 0x0005, 0x0096,
-	0x080c, 0x959a, 0x080c, 0x96a6, 0x080c, 0xcb5a, 0x0120, 0x6014,
-	0x2048, 0x080c, 0x1031, 0x080c, 0xae90, 0x009e, 0x0005, 0x0002,
-	0xde24, 0xde3b, 0xde26, 0xde52, 0xde24, 0xde24, 0xde24, 0xde24,
-	0xde24, 0xde24, 0xde24, 0xde24, 0xde24, 0xde24, 0xde24, 0xde24,
-	0xde24, 0xde24, 0xde24, 0xde24, 0x080c, 0x0dd5, 0x0096, 0x080c,
-	0x959a, 0x6014, 0x2048, 0xa87c, 0xd0b4, 0x0138, 0x6003, 0x0007,
-	0x2009, 0x0043, 0x080c, 0xaeda, 0x0010, 0x6003, 0x0004, 0x080c,
-	0x96a6, 0x009e, 0x0005, 0x080c, 0x959a, 0x080c, 0xcb5a, 0x0138,
-	0x6114, 0x0096, 0x2148, 0xa97c, 0x009e, 0xd1ec, 0x1138, 0x080c,
-	0x86b8, 0x080c, 0xae5f, 0x080c, 0x96a6, 0x0005, 0x080c, 0xe7ee,
-	0x0db0, 0x0cc8, 0x080c, 0x959a, 0x2009, 0x0041, 0x0804, 0xdfc3,
-	0x9182, 0x0040, 0x0002, 0xde6f, 0xde71, 0xde6f, 0xde6f, 0xde6f,
-	0xde6f, 0xde6f, 0xde6f, 0xde6f, 0xde6f, 0xde6f, 0xde6f, 0xde6f,
-	0xde6f, 0xde6f, 0xde6f, 0xde6f, 0xde72, 0xde6f, 0xde6f, 0x080c,
-	0x0dd5, 0x0005, 0x00d6, 0x080c, 0x86b8, 0x00de, 0x080c, 0xe846,
-	0x080c, 0xae5f, 0x0005, 0x9182, 0x0040, 0x0002, 0xde92, 0xde92,
-	0xde92, 0xde92, 0xde92, 0xde92, 0xde92, 0xde92, 0xde92, 0xde94,
-	0xdf03, 0xde92, 0xde92, 0xde92, 0xde92, 0xdf03, 0xde92, 0xde92,
-	0xde92, 0xde92, 0x080c, 0x0dd5, 0x2001, 0x0105, 0x2004, 0x9084,
-	0x1800, 0x01c8, 0x2001, 0x0132, 0x200c, 0x2001, 0x0131, 0x2004,
-	0x9105, 0x1904, 0xdf03, 0x2009, 0x180c, 0x2104, 0xd0d4, 0x0904,
-	0xdf03, 0xc0d4, 0x200a, 0x2009, 0x0105, 0x2104, 0x9084, 0xe7fd,
-	0x9085, 0x0010, 0x200a, 0x2001, 0x1867, 0x2004, 0xd0e4, 0x1528,
-	0x603b, 0x0000, 0x080c, 0x9656, 0x6014, 0x0096, 0x2048, 0xa87c,
-	0xd0fc, 0x0188, 0x908c, 0x0003, 0x918e, 0x0002, 0x0508, 0x2001,
-	0x180c, 0x2004, 0xd0d4, 0x11e0, 0x080c, 0x97d4, 0x2009, 0x0041,
-	0x009e, 0x0804, 0xdfc3, 0x080c, 0x97d4, 0x6003, 0x0007, 0x601b,
-	0x0000, 0x080c, 0x86b8, 0x009e, 0x0005, 0x2001, 0x0100, 0x2004,
-	0x9082, 0x0005, 0x0aa8, 0x2001, 0x011f, 0x2004, 0x603a, 0x0890,
-	0x2001, 0x180c, 0x200c, 0xc1d4, 0x2102, 0xd1cc, 0x0110, 0x080c,
-	0x2c5f, 0x080c, 0x97d4, 0x6014, 0x2048, 0xa97c, 0xd1ec, 0x1130,
-	0x080c, 0x86b8, 0x080c, 0xae5f, 0x009e, 0x0005, 0x080c, 0xe7ee,
-	0x0db8, 0x009e, 0x0005, 0x2001, 0x180c, 0x200c, 0xc1d4, 0x2102,
-	0x0036, 0x080c, 0x9656, 0x080c, 0x97d4, 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, 0xe58c, 0x6018, 0x9005, 0x1128, 0x2001,
-	0x1986, 0x2004, 0x8003, 0x601a, 0x6017, 0x0000, 0x6003, 0x0007,
-	0x009e, 0x003e, 0x0005, 0x9182, 0x0040, 0x0002, 0xdf52, 0xdf52,
-	0xdf52, 0xdf52, 0xdf52, 0xdf52, 0xdf52, 0xdf52, 0xdf54, 0xdf52,
-	0xdf52, 0xdf52, 0xdf52, 0xdf52, 0xdf52, 0xdf52, 0xdf52, 0xdf52,
-	0xdf52, 0xdf9f, 0x080c, 0x0dd5, 0x6014, 0x0096, 0x2048, 0xa834,
-	0xaa38, 0x6110, 0x00b6, 0x2158, 0xb900, 0x00be, 0xd1bc, 0x1190,
-	0x920d, 0x1518, 0xa87c, 0xd0fc, 0x0128, 0x2009, 0x0041, 0x009e,
-	0x0804, 0xdfc3, 0x6003, 0x0007, 0x601b, 0x0000, 0x080c, 0x86b8,
-	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,
-	0x86ba, 0x009e, 0x0005, 0x6003, 0x0002, 0x009e, 0x0005, 0x6024,
-	0xd0f4, 0x0128, 0x080c, 0x15e7, 0x1904, 0xdf54, 0x0005, 0x6014,
-	0x0096, 0x2048, 0xa834, 0xa938, 0x009e, 0x9105, 0x1120, 0x080c,
-	0x15e7, 0x1904, 0xdf54, 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, 0xdfe7, 0xdff3, 0xdfff, 0xe00b, 0xdfe7,
-	0xdfe7, 0xdfe7, 0xdfe7, 0xdfee, 0xdfe9, 0xdfe9, 0xdfe7, 0xdfe7,
-	0xdfe7, 0xdfe7, 0xdfe9, 0xdfe7, 0xdfe9, 0xdfe7, 0xdfee, 0x080c,
-	0x0dd5, 0x6024, 0xd0dc, 0x090c, 0x0dd5, 0x0005, 0x6014, 0x9005,
-	0x190c, 0x0dd5, 0x0005, 0x6003, 0x0001, 0x6106, 0x080c, 0x90f8,
-	0x0126, 0x2091, 0x8000, 0x080c, 0x96a6, 0x012e, 0x0005, 0x6003,
-	0x0001, 0x6106, 0x080c, 0x90f8, 0x0126, 0x2091, 0x8000, 0x080c,
-	0x96a6, 0x012e, 0x0005, 0x6003, 0x0003, 0x6106, 0x2c10, 0x080c,
-	0x1bba, 0x0126, 0x2091, 0x8000, 0x080c, 0x915d, 0x080c, 0x97d4,
-	0x012e, 0x0005, 0x0126, 0x2091, 0x8000, 0x0036, 0x0096, 0x9182,
-	0x0040, 0x0023, 0x009e, 0x003e, 0x012e, 0x0005, 0xe03a, 0xe03c,
-	0xe04e, 0xe068, 0xe03a, 0xe03a, 0xe03a, 0xe03a, 0xe03a, 0xe03a,
-	0xe03a, 0xe03a, 0xe03a, 0xe03a, 0xe03a, 0xe03a, 0xe03a, 0xe03a,
-	0xe03a, 0xe03a, 0x080c, 0x0dd5, 0x6014, 0x2048, 0xa87c, 0xd0fc,
-	0x01f8, 0x909c, 0x0003, 0x939e, 0x0003, 0x01d0, 0x6003, 0x0001,
-	0x6106, 0x080c, 0x90f8, 0x080c, 0x96a6, 0x0470, 0x6014, 0x2048,
-	0xa87c, 0xd0fc, 0x0168, 0x909c, 0x0003, 0x939e, 0x0003, 0x0140,
-	0x6003, 0x0001, 0x6106, 0x080c, 0x90f8, 0x080c, 0x96a6, 0x00e0,
-	0x901e, 0x6316, 0x631a, 0x2019, 0x0004, 0x080c, 0xe58c, 0x00a0,
-	0x6014, 0x2048, 0xa87c, 0xd0fc, 0x0d98, 0x909c, 0x0003, 0x939e,
-	0x0003, 0x0d70, 0x6003, 0x0003, 0x6106, 0x2c10, 0x080c, 0x1bba,
-	0x080c, 0x915d, 0x080c, 0x97d4, 0x0005, 0x080c, 0x959a, 0x6114,
-	0x81ff, 0x0158, 0x0096, 0x2148, 0x080c, 0xe943, 0x0036, 0x2019,
-	0x0029, 0x080c, 0xe58c, 0x003e, 0x009e, 0x080c, 0xae90, 0x080c,
-	0x96a6, 0x0005, 0x080c, 0x9656, 0x6114, 0x81ff, 0x0158, 0x0096,
-	0x2148, 0x080c, 0xe943, 0x0036, 0x2019, 0x0029, 0x080c, 0xe58c,
-	0x003e, 0x009e, 0x080c, 0xae90, 0x080c, 0x97d4, 0x0005, 0x9182,
-	0x0085, 0x0002, 0xe0b9, 0xe0b7, 0xe0b7, 0xe0c5, 0xe0b7, 0xe0b7,
-	0xe0b7, 0xe0b7, 0xe0b7, 0xe0b7, 0xe0b7, 0xe0b7, 0xe0b7, 0x080c,
-	0x0dd5, 0x6003, 0x000b, 0x6106, 0x080c, 0x90f8, 0x0126, 0x2091,
-	0x8000, 0x080c, 0x96a6, 0x012e, 0x0005, 0x0026, 0x00e6, 0x080c,
-	0xe7e5, 0x0118, 0x080c, 0xae5f, 0x0450, 0x2071, 0x0260, 0x7224,
-	0x6216, 0x2001, 0x180e, 0x2004, 0xd0e4, 0x0150, 0x6010, 0x00b6,
-	0x2058, 0xbca0, 0x00be, 0x2c00, 0x2011, 0x014e, 0x080c, 0xb180,
-	0x7220, 0x080c, 0xe432, 0x0118, 0x6007, 0x0086, 0x0040, 0x6007,
-	0x0087, 0x7224, 0x9296, 0xffff, 0x1110, 0x6007, 0x0086, 0x6003,
-	0x0001, 0x080c, 0x90f8, 0x080c, 0x96a6, 0x080c, 0x97d4, 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,
-	0xaef5, 0x0050, 0x2001, 0x0007, 0x080c, 0x6592, 0x080c, 0x959a,
-	0x080c, 0xae90, 0x080c, 0x96a6, 0x0005, 0xe12a, 0xe12c, 0xe12c,
-	0xe12a, 0xe12a, 0xe12a, 0xe12a, 0xe12a, 0xe12a, 0xe12a, 0xe12a,
-	0xe12a, 0xe12a, 0x080c, 0x0dd5, 0x080c, 0x959a, 0x080c, 0xae90,
-	0x080c, 0x96a6, 0x0005, 0x9182, 0x0085, 0x0a0c, 0x0dd5, 0x9182,
-	0x0092, 0x1a0c, 0x0dd5, 0x9182, 0x0085, 0x0002, 0xe14b, 0xe14b,
-	0xe14b, 0xe14d, 0xe14b, 0xe14b, 0xe14b, 0xe14b, 0xe14b, 0xe14b,
-	0xe14b, 0xe14b, 0xe14b, 0x080c, 0x0dd5, 0x0005, 0x9186, 0x0013,
-	0x0148, 0x9186, 0x0014, 0x0130, 0x9186, 0x0027, 0x0118, 0x080c,
-	0xaef5, 0x0030, 0x080c, 0x959a, 0x080c, 0xae90, 0x080c, 0x96a6,
-	0x0005, 0x0036, 0x080c, 0xe846, 0x6043, 0x0000, 0x2019, 0x000b,
-	0x0031, 0x6023, 0x0006, 0x6003, 0x0007, 0x003e, 0x0005, 0x0126,
-	0x0036, 0x2091, 0x8000, 0x0086, 0x2c40, 0x0096, 0x904e, 0x080c,
-	0xa687, 0x009e, 0x008e, 0x1550, 0x0076, 0x2c38, 0x080c, 0xa732,
-	0x007e, 0x1520, 0x6000, 0x9086, 0x0000, 0x0500, 0x6020, 0x9086,
-	0x0007, 0x01e0, 0x0096, 0x601c, 0xd084, 0x0140, 0x080c, 0xe846,
-	0x080c, 0xd272, 0x080c, 0x1a70, 0x6023, 0x0007, 0x6014, 0x2048,
-	0x080c, 0xcb5a, 0x0110, 0x080c, 0xe58c, 0x009e, 0x6017, 0x0000,
-	0x080c, 0xe846, 0x6023, 0x0007, 0x080c, 0xd272, 0x003e, 0x012e,
-	0x0005, 0x00f6, 0x00c6, 0x00b6, 0x0036, 0x0156, 0x2079, 0x0260,
-	0x7938, 0x783c, 0x080c, 0x284b, 0x15c8, 0x0016, 0x00c6, 0x080c,
-	0x6616, 0x1590, 0x001e, 0x00c6, 0x2160, 0x080c, 0xd26f, 0x00ce,
-	0x002e, 0x0026, 0x0016, 0x2019, 0x0029, 0x080c, 0xa7f8, 0x080c,
-	0x929d, 0x0076, 0x903e, 0x080c, 0x9170, 0x007e, 0x001e, 0x0076,
-	0x903e, 0x080c, 0xe326, 0x007e, 0x0026, 0xba04, 0x9294, 0xff00,
-	0x8217, 0x9286, 0x0006, 0x0118, 0x9286, 0x0004, 0x1118, 0xbaa0,
-	0x080c, 0x328a, 0x002e, 0xbcc0, 0x001e, 0x080c, 0x6047, 0xbe12,
-	0xbd16, 0xbcc2, 0x9006, 0x0010, 0x00ce, 0x001e, 0x015e, 0x003e,
-	0x00be, 0x00ce, 0x00fe, 0x0005, 0x00c6, 0x00d6, 0x00b6, 0x0016,
-	0x2009, 0x1824, 0x2104, 0x9086, 0x0074, 0x1904, 0xe24d, 0x2069,
-	0x0260, 0x6944, 0x9182, 0x0100, 0x06e0, 0x6940, 0x9184, 0x8000,
-	0x0904, 0xe24a, 0x2001, 0x197b, 0x2004, 0x9005, 0x1140, 0x6010,
-	0x2058, 0xb8c0, 0x9005, 0x0118, 0x9184, 0x0800, 0x0598, 0x6948,
-	0x918a, 0x0001, 0x0648, 0x080c, 0xe9ab, 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, 0x6625, 0x0804, 0xe2b5, 0x2011, 0x0276, 0x20a9,
-	0x0004, 0x0096, 0x2b48, 0x2019, 0x000a, 0x080c, 0xbe2d, 0x009e,
-	0x15a8, 0x2011, 0x027a, 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019,
-	0x0006, 0x080c, 0xbe2d, 0x009e, 0x1548, 0x0046, 0x0016, 0xbaa0,
-	0x2220, 0x9006, 0x2009, 0x1848, 0x210c, 0xd1a4, 0x0138, 0x2009,
-	0x0029, 0x080c, 0xe5e9, 0xb800, 0xc0e5, 0xb802, 0x2019, 0x0029,
-	0x080c, 0x929d, 0x0076, 0x2039, 0x0000, 0x080c, 0x9170, 0x2c08,
-	0x080c, 0xe326, 0x007e, 0x2001, 0x0007, 0x080c, 0x6592, 0x2001,
-	0x0007, 0x080c, 0x6566, 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, 0x284b, 0x11d0, 0x080c, 0x6616,
-	0x11b8, 0x2011, 0x0270, 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019,
-	0x000a, 0x080c, 0xbe2d, 0x009e, 0x1158, 0x2011, 0x0274, 0x20a9,
-	0x0004, 0x0096, 0x2b48, 0x2019, 0x0006, 0x080c, 0xbe2d, 0x009e,
-	0x015e, 0x003e, 0x002e, 0x001e, 0x00fe, 0x00be, 0x0005, 0x00b6,
-	0x0006, 0x0016, 0x0026, 0x0036, 0x0156, 0x2011, 0x0263, 0x2204,
-	0x8211, 0x220c, 0x080c, 0x284b, 0x11d0, 0x080c, 0x6616, 0x11b8,
-	0x2011, 0x0276, 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x000a,
-	0x080c, 0xbe2d, 0x009e, 0x1158, 0x2011, 0x027a, 0x20a9, 0x0004,
-	0x0096, 0x2b48, 0x2019, 0x0006, 0x080c, 0xbe2d, 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, 0x1aaf, 0x000e, 0x0128, 0x8001, 0x9602, 0x1a04,
-	0xe3c3, 0x0018, 0x9606, 0x0904, 0xe3c3, 0x080c, 0x8987, 0x0904,
-	0xe3ba, 0x2100, 0x9c06, 0x0904, 0xe3ba, 0x080c, 0xe62a, 0x1904,
-	0xe3ba, 0x080c, 0xe9c8, 0x0904, 0xe3ba, 0x080c, 0xe61a, 0x0904,
-	0xe3ba, 0x6720, 0x9786, 0x0001, 0x1148, 0x080c, 0x3321, 0x0904,
-	0xe402, 0x6004, 0x9086, 0x0000, 0x1904, 0xe402, 0x9786, 0x0004,
-	0x0904, 0xe402, 0x9786, 0x0007, 0x0904, 0xe3ba, 0x2500, 0x9c06,
-	0x0904, 0xe3ba, 0x2400, 0x9c06, 0x05e8, 0x88ff, 0x0118, 0x6054,
-	0x9906, 0x15c0, 0x0096, 0x6000, 0x9086, 0x0004, 0x1120, 0x0016,
-	0x080c, 0x1a70, 0x001e, 0x9786, 0x000a, 0x0148, 0x080c, 0xcd60,
-	0x1130, 0x080c, 0xb821, 0x009e, 0x080c, 0xae90, 0x0418, 0x6014,
-	0x2048, 0x080c, 0xcb5a, 0x01d8, 0x9786, 0x0003, 0x1570, 0xa867,
-	0x0103, 0xa87c, 0xd0cc, 0x0130, 0x0096, 0xa878, 0x2048, 0x080c,
-	0x0fb1, 0x009e, 0xab7a, 0xa877, 0x0000, 0x080c, 0xe943, 0x0016,
-	0x080c, 0xce4e, 0x080c, 0x6c88, 0x001e, 0x080c, 0xcd43, 0x009e,
-	0x080c, 0xae90, 0x9ce0, 0x0018, 0x2001, 0x181a, 0x2004, 0x9c02,
-	0x1210, 0x0804, 0xe33a, 0x012e, 0x002e, 0x004e, 0x005e, 0x006e,
-	0x007e, 0x008e, 0x00ce, 0x00ee, 0x0005, 0x9786, 0x0006, 0x1150,
-	0x9386, 0x0005, 0x0128, 0x080c, 0xe943, 0x080c, 0xe58c, 0x08f8,
-	0x009e, 0x0c00, 0x9786, 0x0009, 0x11f8, 0x6000, 0x9086, 0x0004,
-	0x01c0, 0x6000, 0x9086, 0x0003, 0x11a0, 0x080c, 0x9656, 0x0096,
-	0x6114, 0x2148, 0x080c, 0xcb5a, 0x0118, 0x6010, 0x080c, 0x6c94,
-	0x009e, 0x00c6, 0x080c, 0xae5f, 0x00ce, 0x0036, 0x080c, 0x97d4,
-	0x003e, 0x009e, 0x0804, 0xe3ba, 0x9786, 0x000a, 0x0904, 0xe3a1,
-	0x0804, 0xe39f, 0x81ff, 0x0904, 0xe3ba, 0x9180, 0x0001, 0x2004,
-	0x9086, 0x0018, 0x0138, 0x9180, 0x0001, 0x2004, 0x9086, 0x002d,
-	0x1904, 0xe3ba, 0x6000, 0x9086, 0x0002, 0x1904, 0xe3ba, 0x080c,
-	0xcd4f, 0x0138, 0x080c, 0xcd60, 0x1904, 0xe3ba, 0x080c, 0xb821,
-	0x0038, 0x080c, 0x31f5, 0x080c, 0xcd60, 0x1110, 0x080c, 0xb821,
-	0x080c, 0xae90, 0x0804, 0xe3ba, 0xa864, 0x9084, 0x00ff, 0x9086,
-	0x0039, 0x0005, 0x00c6, 0x00e6, 0x0016, 0x2c08, 0x2170, 0x9006,
-	0x080c, 0xe5b3, 0x001e, 0x0120, 0x6020, 0x9084, 0x000f, 0x001b,
-	0x00ee, 0x00ce, 0x0005, 0xe451, 0xe451, 0xe451, 0xe451, 0xe451,
-	0xe451, 0xe453, 0xe451, 0xe451, 0xe451, 0xe451, 0xae90, 0xae90,
-	0xe451, 0x9006, 0x0005, 0x0036, 0x0046, 0x0016, 0x7010, 0x00b6,
-	0x2058, 0xbca0, 0x00be, 0x2c00, 0x2009, 0x0020, 0x080c, 0xe5e9,
-	0x001e, 0x004e, 0x2019, 0x0002, 0x080c, 0xe16f, 0x003e, 0x9085,
-	0x0001, 0x0005, 0x0096, 0x080c, 0xcb5a, 0x0140, 0x6014, 0x904d,
-	0x080c, 0xc77b, 0x687b, 0x0005, 0x080c, 0x6c94, 0x009e, 0x080c,
-	0xae90, 0x9085, 0x0001, 0x0005, 0x2001, 0x0001, 0x080c, 0x6552,
-	0x0156, 0x0016, 0x0026, 0x0036, 0x20a9, 0x0004, 0x2019, 0x1805,
-	0x2011, 0x0276, 0x080c, 0xbe19, 0x003e, 0x002e, 0x001e, 0x015e,
-	0x9005, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x0086, 0x0076, 0x0066,
-	0x00b6, 0x0126, 0x2091, 0x8000, 0x2740, 0x2061, 0x1cd0, 0x2079,
-	0x0001, 0x8fff, 0x0904, 0xe4ec, 0x2071, 0x1800, 0x7654, 0x7074,
-	0x8001, 0x9602, 0x1a04, 0xe4ec, 0x88ff, 0x0120, 0x2800, 0x9c06,
-	0x1590, 0x2078, 0x080c, 0xe61a, 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, 0xe846, 0x080c,
-	0xd272, 0x080c, 0x1a70, 0x6023, 0x0007, 0x6014, 0x2048, 0x080c,
-	0xcb5a, 0x0120, 0x0046, 0x080c, 0xe58c, 0x004e, 0x009e, 0x080c,
-	0xae90, 0x88ff, 0x1198, 0x9ce0, 0x0018, 0x2001, 0x181a, 0x2004,
-	0x9c02, 0x1210, 0x0804, 0xe4a1, 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,
-	0xa687, 0x009e, 0x008e, 0x903e, 0x080c, 0xa732, 0x080c, 0xe492,
-	0x005e, 0x007e, 0x00be, 0x0005, 0x00b6, 0x0046, 0x0056, 0x0076,
-	0x00c6, 0x0156, 0x2c20, 0x2128, 0x20a9, 0x007f, 0x900e, 0x0016,
-	0x0036, 0x080c, 0x6616, 0x1190, 0x0056, 0x0086, 0x9046, 0x2508,
-	0x2029, 0x0001, 0x0096, 0x904e, 0x080c, 0xa687, 0x009e, 0x008e,
-	0x903e, 0x080c, 0xa732, 0x080c, 0xe492, 0x005e, 0x003e, 0x001e,
-	0x8108, 0x1f04, 0xe51f, 0x015e, 0x00ce, 0x007e, 0x005e, 0x004e,
-	0x00be, 0x0005, 0x00b6, 0x0076, 0x0056, 0x6210, 0x2258, 0x0086,
-	0x9046, 0x2029, 0x0001, 0x2019, 0x0048, 0x0096, 0x904e, 0x080c,
-	0xa687, 0x009e, 0x008e, 0x903e, 0x080c, 0xa732, 0x2c20, 0x080c,
-	0xe492, 0x005e, 0x007e, 0x00be, 0x0005, 0x00b6, 0x0046, 0x0056,
-	0x0076, 0x00c6, 0x0156, 0x2c20, 0x20a9, 0x0800, 0x900e, 0x0016,
-	0x0036, 0x080c, 0x6616, 0x11a0, 0x0086, 0x9046, 0x2828, 0x0046,
-	0x2021, 0x0001, 0x080c, 0xe82a, 0x004e, 0x0096, 0x904e, 0x080c,
-	0xa687, 0x009e, 0x008e, 0x903e, 0x080c, 0xa732, 0x080c, 0xe492,
-	0x003e, 0x001e, 0x8108, 0x1f04, 0xe567, 0x015e, 0x00ce, 0x007e,
-	0x005e, 0x004e, 0x00be, 0x0005, 0x0016, 0x00f6, 0x080c, 0xcb58,
-	0x0198, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0046, 0x0180, 0xa800,
-	0x907d, 0x0138, 0xa803, 0x0000, 0xab82, 0x080c, 0x6c94, 0x2f48,
-	0x0cb0, 0xab82, 0x080c, 0x6c94, 0x00fe, 0x001e, 0x0005, 0xa800,
-	0x907d, 0x0130, 0xa803, 0x0000, 0x080c, 0x6c94, 0x2f48, 0x0cb8,
-	0x080c, 0x6c94, 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, 0xcb48,
-	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, 0x6c94, 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, 0x90f8, 0x080c,
-	0x96a6, 0x001e, 0x0005, 0xa001, 0xa001, 0x0005, 0x6024, 0xd0e4,
-	0x0158, 0xd0cc, 0x0118, 0x080c, 0xce92, 0x0030, 0x080c, 0xe846,
-	0x080c, 0x86b8, 0x080c, 0xae5f, 0x0005, 0x9280, 0x0008, 0x2004,
-	0x9084, 0x000f, 0x0002, 0xe679, 0xe679, 0xe679, 0xe67b, 0xe679,
-	0xe67b, 0xe67b, 0xe679, 0xe67b, 0xe679, 0xe679, 0xe679, 0xe679,
-	0xe679, 0x9006, 0x0005, 0x9085, 0x0001, 0x0005, 0x9280, 0x0008,
-	0x2004, 0x9084, 0x000f, 0x0002, 0xe692, 0xe692, 0xe692, 0xe692,
-	0xe692, 0xe692, 0xe69f, 0xe692, 0xe692, 0xe692, 0xe692, 0xe692,
-	0xe692, 0xe692, 0x6007, 0x003b, 0x602f, 0x0009, 0x6017, 0x2a00,
-	0x6003, 0x0001, 0x080c, 0x90f8, 0x080c, 0x96a6, 0x0005, 0x0096,
-	0x00c6, 0x2260, 0x080c, 0xe846, 0x6043, 0x0000, 0x6024, 0xc0f4,
-	0xc0e4, 0x6026, 0x603b, 0x0000, 0x00ce, 0x00d6, 0x2268, 0x9186,
-	0x0007, 0x1904, 0xe6f8, 0x6814, 0x9005, 0x0138, 0x2048, 0xa87c,
-	0xd0fc, 0x1118, 0x00de, 0x009e, 0x08a8, 0x6007, 0x003a, 0x6003,
-	0x0001, 0x080c, 0x90f8, 0x080c, 0x96a6, 0x00c6, 0x2d60, 0x6100,
-	0x9186, 0x0002, 0x1904, 0xe76f, 0x6014, 0x9005, 0x1138, 0x6000,
-	0x9086, 0x0007, 0x190c, 0x0dd5, 0x0804, 0xe76f, 0x2048, 0x080c,
-	0xcb5a, 0x1130, 0x0028, 0x2048, 0xa800, 0x9005, 0x1de0, 0x2900,
-	0x2048, 0xa87c, 0x9084, 0x0003, 0x9086, 0x0002, 0x1168, 0xa87c,
-	0xc0dc, 0xc0f4, 0xa87e, 0xa880, 0xc0fc, 0xa882, 0x2009, 0x0043,
-	0x080c, 0xdfc3, 0x0804, 0xe76f, 0x2009, 0x0041, 0x0804, 0xe769,
-	0x9186, 0x0005, 0x15a0, 0x6814, 0x2048, 0xa87c, 0xd0bc, 0x1120,
-	0x00de, 0x009e, 0x0804, 0xe692, 0xd0b4, 0x0128, 0xd0fc, 0x090c,
-	0x0dd5, 0x0804, 0xe6b3, 0x6007, 0x003a, 0x6003, 0x0001, 0x080c,
-	0x90f8, 0x080c, 0x96a6, 0x00c6, 0x2d60, 0x6100, 0x9186, 0x0002,
-	0x0120, 0x9186, 0x0004, 0x1904, 0xe76f, 0x6814, 0x2048, 0xa97c,
-	0xc1f4, 0xc1dc, 0xa97e, 0xa980, 0xc1fc, 0xc1bc, 0xa982, 0x00f6,
-	0x2c78, 0x080c, 0x1727, 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, 0x6c94,
-	0x2019, 0x0045, 0x6008, 0x2068, 0x080c, 0xe16f, 0x2d00, 0x600a,
-	0x6023, 0x0006, 0x6003, 0x0007, 0x901e, 0x631a, 0x6342, 0x003e,
-	0x0038, 0x6043, 0x0000, 0x6003, 0x0007, 0x080c, 0xdfc3, 0x00ce,
-	0x00de, 0x009e, 0x0005, 0x9186, 0x0013, 0x1128, 0x6004, 0x9082,
-	0x0085, 0x2008, 0x00c2, 0x9186, 0x0027, 0x1178, 0x080c, 0x959a,
-	0x0036, 0x0096, 0x6014, 0x2048, 0x2019, 0x0004, 0x080c, 0xe58c,
-	0x009e, 0x003e, 0x080c, 0x96a6, 0x0005, 0x9186, 0x0014, 0x0d70,
-	0x080c, 0xaef5, 0x0005, 0xe7a2, 0xe7a0, 0xe7a0, 0xe7a0, 0xe7a0,
-	0xe7a0, 0xe7a2, 0xe7a0, 0xe7a0, 0xe7a0, 0xe7a0, 0xe7a0, 0xe7a0,
-	0x080c, 0x0dd5, 0x080c, 0x959a, 0x6003, 0x000c, 0x080c, 0x96a6,
-	0x0005, 0x9182, 0x0092, 0x1220, 0x9182, 0x0085, 0x0208, 0x001a,
-	0x080c, 0xaef5, 0x0005, 0xe7c0, 0xe7c0, 0xe7c0, 0xe7c0, 0xe7c2,
-	0xe7e2, 0xe7c0, 0xe7c0, 0xe7c0, 0xe7c0, 0xe7c0, 0xe7c0, 0xe7c0,
-	0x080c, 0x0dd5, 0x00d6, 0x2c68, 0x080c, 0xae09, 0x01b0, 0x6003,
-	0x0001, 0x6007, 0x001e, 0x2009, 0x026e, 0x210c, 0x613a, 0x2009,
-	0x026f, 0x210c, 0x613e, 0x600b, 0xffff, 0x6910, 0x6112, 0x6023,
-	0x0004, 0x080c, 0x90f8, 0x080c, 0x96a6, 0x2d60, 0x080c, 0xae5f,
-	0x00de, 0x0005, 0x080c, 0xae5f, 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, 0x86b8, 0x080c, 0xae5f, 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, 0xbe2d, 0x009e, 0x1168,
-	0x2011, 0x0274, 0x20a9, 0x0004, 0x6010, 0x0096, 0x2048, 0x2019,
-	0x0006, 0x080c, 0xbe2d, 0x009e, 0x1100, 0x015e, 0x003e, 0x002e,
-	0x0005, 0x00e6, 0x2071, 0x1800, 0x080c, 0x5fc0, 0x080c, 0x2fa3,
-	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,
-	0x6c94, 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, 0xe61a, 0x01b8, 0x080c, 0xe62a, 0x11a0, 0x6000,
-	0x9086, 0x0004, 0x1120, 0x0016, 0x080c, 0x1a70, 0x001e, 0x080c,
-	0xcd4f, 0x1110, 0x080c, 0x31f5, 0x080c, 0xcd60, 0x1110, 0x080c,
-	0xb821, 0x080c, 0xae90, 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, 0xd25a, 0x0168,
-	0x2019, 0xffff, 0x9005, 0x0128, 0x6010, 0x00b6, 0x2058, 0xbba0,
-	0x00be, 0x2021, 0x0004, 0x080c, 0x4cd5, 0x004e, 0x003e, 0x000e,
-	0x6004, 0x9086, 0x0001, 0x1128, 0x080c, 0xa7f8, 0x080c, 0xae90,
-	0x9006, 0x0005, 0x00e6, 0x00c6, 0x00b6, 0x0046, 0x2061, 0x1cd0,
-	0x2071, 0x1800, 0x7454, 0x7074, 0x8001, 0x9402, 0x12b8, 0x2100,
-	0x9c06, 0x0148, 0x6000, 0x9086, 0x0000, 0x0128, 0x6010, 0x2058,
-	0xb8a0, 0x9206, 0x0140, 0x9ce0, 0x0018, 0x2001, 0x181a, 0x2004,
-	0x9c02, 0x1220, 0x0c60, 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, 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, 0x74b9
+	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,
+	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,
+	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
 };
 #ifdef UNIQUE_FW_NAME
-unsigned short fw2300ipx_length01 = 0xea02;
+unsigned short fw2300ipx_length01 = 0xeb57;
 #else
-unsigned short risc_code_length01 = 0xea02;
+unsigned short risc_code_length01 = 0xeb57;
 #endif
 
diff -Nru a/drivers/scsi/qla2xxx/ql2322_fw.c b/drivers/scsi/qla2xxx/ql2322_fw.c
--- a/drivers/scsi/qla2xxx/ql2322_fw.c	2005-03-01 23:38:44 -08:00
+++ b/drivers/scsi/qla2xxx/ql2322_fw.c	2005-03-01 23:38:44 -08:00
@@ -1,8 +1,8 @@
-/**************************************************************************
+/******************************************************************************
  *                  QLOGIC LINUX SOFTWARE
  *
  * QLogic ISP2x00 device driver for Linux 2.6.x
- * Copyright (C) 2003-2004 QLogic Corporation
+ * Copyright (C) 2003 QLogic Corporation
  * (www.qlogic.com)
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -15,10 +15,10 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * General Public License for more details.
  *
- *************************************************************************/
+ ******************************************************************************/
 
 /*
- *	Firmware Version 3.03.02 (16:54 Aug 10, 2004)
+ *	Firmware Version 3.03.08 (10:03 Nov 12, 2004)
  */
 
 #ifdef UNIQUE_FW_NAME
@@ -28,15 +28,15 @@
 #endif
 
 #ifdef UNIQUE_FW_NAME
-unsigned char fw2322ipx_version_str[] = {3, 3, 2};
+unsigned char fw2322ipx_version_str[] = {3, 3, 8};
 #else
-unsigned char firmware_version[] = {3, 3, 2};
+unsigned char firmware_version[] = {3, 3, 8};
 #endif
 
 #ifdef UNIQUE_FW_NAME
-#define fw2322ipx_VERSION_STRING "3.03.02"
+#define fw2322ipx_VERSION_STRING "3.03.08"
 #else
-#define FW_VERSION_STRING "3.03.02"
+#define FW_VERSION_STRING "3.03.08"
 #endif
 
 #ifdef UNIQUE_FW_NAME
@@ -50,12 +50,12 @@
 #else
 unsigned short risc_code01[] = { 
 #endif
-	0x0470, 0x0000, 0x0000, 0xdf8f, 0x0000, 0x0003, 0x0003, 0x0002,
+	0x0470, 0x0000, 0x0000, 0xe0c2, 0x0000, 0x0003, 0x0003, 0x0008,
 	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, 0x3220, 0x2020, 0x2020, 0x2400, 0x20a9,
+	0x332e, 0x3033, 0x2e30, 0x3820, 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,164 +64,164 @@
 	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, 0x2ae3, 0x2051, 0x1800, 0x2a70, 0x20e1,
+	0x7883, 0x0004, 0x2089, 0x2b14, 0x2051, 0x1800, 0x2a70, 0x20e1,
 	0x0001, 0x20e9, 0x0001, 0x2009, 0x0000, 0x080c, 0x0e62, 0x00f6,
-	0x7888, 0x9005, 0x11f8, 0x2061, 0xc000, 0x080c, 0x207f, 0x1170,
-	0x2079, 0x0300, 0x080c, 0x2095, 0x2061, 0xe000, 0x080c, 0x207f,
-	0x1128, 0x2079, 0x0380, 0x080c, 0x2095, 0x0060, 0x00fe, 0x7883,
+	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,
 	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, 0x1b4d, 0x2472,
+	0x7672, 0x776a, 0x7476, 0x747a, 0x00e6, 0x2071, 0x1b50, 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, 0x6052, 0x080c, 0xab86, 0x080c,
-	0x1116, 0x080c, 0x1340, 0x080c, 0x1bd5, 0x080c, 0x91a8, 0x080c,
-	0x0d0f, 0x080c, 0x109b, 0x080c, 0x3488, 0x080c, 0x7803, 0x080c,
-	0x6ab2, 0x080c, 0x891b, 0x080c, 0x857c, 0x080c, 0x2270, 0x080c,
-	0x7ed9, 0x080c, 0x20ae, 0x080c, 0x21ec, 0x080c, 0x2265, 0x2091,
+	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,
 	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, 0x4bee, 0x080c, 0x34af,
-	0x080c, 0x786b, 0x080c, 0x6fea, 0x080c, 0x89f9, 0x080c, 0x85a5,
+	0x7000, 0x908e, 0x0003, 0x1168, 0x080c, 0x4c17, 0x080c, 0x34e0,
+	0x080c, 0x78bc, 0x080c, 0x7039, 0x080c, 0x8a75, 0x080c, 0x861c,
 	0x0c68, 0x000b, 0x0c88, 0x096d, 0x096e, 0x0b09, 0x096b, 0x0bc3,
 	0x0d0e, 0x0d0e, 0x0d0e, 0x080c, 0x0d7d, 0x0005, 0x0126, 0x00f6,
 	0x2091, 0x8000, 0x7000, 0x9086, 0x0001, 0x1904, 0x0adc, 0x080c,
-	0x0eb2, 0x080c, 0x74ec, 0x0150, 0x080c, 0x750f, 0x15b0, 0x2079,
-	0x0100, 0x7828, 0x9085, 0x1800, 0x782a, 0x0478, 0x080c, 0x741d,
+	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, 0x8574, 0x080c, 0x8566, 0x2001, 0x0161,
-	0x2003, 0x0001, 0x2079, 0x0100, 0x2011, 0xffff, 0x080c, 0x2a83,
-	0x7a28, 0x9295, 0x5e2c, 0x7a2a, 0x2011, 0x7362, 0x080c, 0x8651,
-	0x2011, 0x7355, 0x080c, 0x875d, 0x2011, 0x5ea9, 0x080c, 0x8651,
-	0x2011, 0x8030, 0x901e, 0x7396, 0x04d0, 0x080c, 0x5756, 0x2079,
-	0x0100, 0x7844, 0x9005, 0x1904, 0x0adc, 0x2011, 0x5ea9, 0x080c,
-	0x8651, 0x2011, 0x7362, 0x080c, 0x8651, 0x2011, 0x7355, 0x080c,
-	0x875d, 0x2001, 0x0265, 0x2001, 0x0205, 0x2003, 0x0000, 0x7840,
+	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, 0x5ffa, 0x00ce, 0x0804, 0x0adc,
-	0x780f, 0x006b, 0x7a28, 0x080c, 0x74f4, 0x0118, 0x9295, 0x5e2c,
+	0x00c6, 0x2061, 0x0100, 0x080c, 0x6048, 0x00ce, 0x0804, 0x0adc,
+	0x780f, 0x006b, 0x7a28, 0x080c, 0x7545, 0x0118, 0x9295, 0x5e2c,
 	0x0010, 0x9295, 0x402c, 0x7a2a, 0x2011, 0x8010, 0x73d8, 0x2001,
-	0x19a6, 0x2003, 0x0001, 0x080c, 0x294b, 0x080c, 0x4b29, 0x7248,
+	0x19a6, 0x2003, 0x0001, 0x080c, 0x297c, 0x080c, 0x4b52, 0x7248,
 	0xc284, 0x724a, 0x2001, 0x180c, 0x200c, 0xc1ac, 0xc1cc, 0x2102,
-	0x2001, 0x0390, 0x2003, 0x0400, 0x080c, 0xa899, 0x080c, 0xa08e,
-	0x2011, 0x0004, 0x080c, 0xc875, 0x080c, 0xa8b5, 0x080c, 0x693a,
-	0x080c, 0x74ec, 0x1120, 0x080c, 0x29ac, 0x0600, 0x0420, 0x080c,
-	0x6001, 0x0140, 0x7097, 0x0001, 0x70d3, 0x0000, 0x080c, 0x5923,
-	0x0804, 0x0adc, 0x080c, 0x56f5, 0xd094, 0x01a8, 0x2001, 0x0390,
+	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,
-	0x56f9, 0xd0d4, 0x1118, 0x080c, 0x29ac, 0x1270, 0x2011, 0x180c,
-	0x2204, 0xc0bc, 0x00a8, 0x080c, 0x56f9, 0xd0d4, 0x1db8, 0x2011,
+	0x5742, 0xd0d4, 0x1118, 0x080c, 0x29dd, 0x1270, 0x2011, 0x180c,
+	0x2204, 0xc0bc, 0x00a8, 0x080c, 0x5742, 0xd0d4, 0x1db8, 0x2011,
 	0x180c, 0x2204, 0xc0bd, 0x0060, 0x2011, 0x180c, 0x2204, 0xc0bd,
-	0x2012, 0x080c, 0x6a86, 0x1128, 0xd0a4, 0x0118, 0x2204, 0xc0fd,
-	0x2012, 0x080c, 0x6a4c, 0x0120, 0x7a0c, 0xc2b4, 0x7a0e, 0x00a8,
-	0x707f, 0x0000, 0x080c, 0x74ec, 0x1130, 0x70b0, 0x9005, 0x1168,
-	0x080c, 0xccd1, 0x0050, 0x080c, 0xccd1, 0x70dc, 0xd09c, 0x1128,
-	0x70b0, 0x9005, 0x0110, 0x080c, 0x5fd7, 0x70e7, 0x0000, 0x70e3,
-	0x0000, 0x70a7, 0x0000, 0x080c, 0x29b4, 0x0228, 0x2011, 0x0101,
-	0x2204, 0xc0c4, 0x2012, 0x72dc, 0x080c, 0x74ec, 0x1178, 0x9016,
-	0x0016, 0x080c, 0x2748, 0x2019, 0x196c, 0x211a, 0x001e, 0x705f,
+	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,
 	0x201b, 0x0000, 0x2079, 0x1847, 0x7804, 0xd0ac, 0x0108, 0xc295,
-	0x72de, 0x080c, 0x74ec, 0x0118, 0x9296, 0x0004, 0x0518, 0x2011,
-	0x0001, 0x080c, 0xc875, 0x70ab, 0x0000, 0x70af, 0xffff, 0x7003,
-	0x0002, 0x00fe, 0x080c, 0x2fe0, 0x080c, 0xa899, 0x2011, 0x0005,
-	0x080c, 0xa1be, 0x080c, 0xa8b5, 0x080c, 0x74ec, 0x0148, 0x00c6,
-	0x2061, 0x0100, 0x0016, 0x080c, 0x2748, 0x61e2, 0x001e, 0x00ce,
+	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,
 	0x012e, 0x00e0, 0x70ab, 0x0000, 0x70af, 0xffff, 0x7003, 0x0002,
-	0x080c, 0xa899, 0x2011, 0x0005, 0x080c, 0xa1be, 0x080c, 0xa8b5,
-	0x080c, 0x74ec, 0x0148, 0x00c6, 0x2061, 0x0100, 0x0016, 0x080c,
-	0x2748, 0x61e2, 0x001e, 0x00ce, 0x00fe, 0x012e, 0x0005, 0x00c6,
-	0x00b6, 0x080c, 0x74ec, 0x1118, 0x20a9, 0x0800, 0x0010, 0x20a9,
-	0x0782, 0x080c, 0x74ec, 0x1110, 0x900e, 0x0010, 0x2009, 0x007e,
+	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,
 	0x86ff, 0x0138, 0x9180, 0x1000, 0x2004, 0x905d, 0x0110, 0xb800,
-	0xd0bc, 0x090c, 0x3318, 0x8108, 0x1f04, 0x0af0, 0x707f, 0x0000,
+	0xd0bc, 0x090c, 0x3349, 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, 0x2fe0,
+	0x1904, 0x0bc0, 0x70ac, 0x9086, 0xffff, 0x0120, 0x080c, 0x3011,
 	0x0804, 0x0bc0, 0x70dc, 0xd0ac, 0x1110, 0xd09c, 0x0538, 0xd084,
 	0x0528, 0x0006, 0x2001, 0x0103, 0x2003, 0x002b, 0x000e, 0xd08c,
-	0x01e8, 0x080c, 0x3381, 0x11b0, 0x70e0, 0x9086, 0xffff, 0x0190,
-	0x080c, 0x3175, 0x70dc, 0xd094, 0x1904, 0x0bc0, 0x2011, 0x0001,
-	0x080c, 0xcf84, 0x0110, 0x2011, 0x0003, 0x901e, 0x080c, 0x31af,
+	0x01e8, 0x080c, 0x33b2, 0x11b0, 0x70e0, 0x9086, 0xffff, 0x0190,
+	0x080c, 0x31a6, 0x70dc, 0xd094, 0x1904, 0x0bc0, 0x2011, 0x0001,
+	0x080c, 0xd09b, 0x0110, 0x2011, 0x0003, 0x901e, 0x080c, 0x31e0,
 	0x0804, 0x0bc0, 0x70e4, 0x9005, 0x1904, 0x0bc0, 0x70a8, 0x9005,
 	0x1904, 0x0bc0, 0x70dc, 0xd0a4, 0x0118, 0xd0b4, 0x0904, 0x0bc0,
-	0x080c, 0x6a4c, 0x1904, 0x0bc0, 0x080c, 0x6a9f, 0x1904, 0x0bc0,
-	0x080c, 0x6a86, 0x01c0, 0x0156, 0x00c6, 0x20a9, 0x007f, 0x900e,
-	0x0016, 0x080c, 0x6644, 0x1118, 0xb800, 0xd0ec, 0x1138, 0x001e,
+	0x080c, 0x6a9b, 0x1904, 0x0bc0, 0x080c, 0x6aee, 0x1904, 0x0bc0,
+	0x080c, 0x6ad5, 0x01c0, 0x0156, 0x00c6, 0x20a9, 0x007f, 0x900e,
+	0x0016, 0x080c, 0x6693, 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, 0x25d5, 0x080c, 0x3381, 0x0118,
-	0x080c, 0x4cc6, 0x0050, 0x0036, 0x0046, 0x2019, 0xffff, 0x2021,
-	0x0006, 0x080c, 0x4ce0, 0x004e, 0x003e, 0x00f6, 0x2079, 0x0100,
-	0x080c, 0x750f, 0x0150, 0x080c, 0x74ec, 0x7828, 0x0118, 0x9084,
-	0xe1ff, 0x0010, 0x9084, 0xffdf, 0x782a, 0x00fe, 0x080c, 0xa899,
+	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, 0xa1be, 0x2011, 0x0000, 0x080c, 0xa1c8, 0x080c, 0xa8b5,
+	0x080c, 0xa243, 0x2011, 0x0000, 0x080c, 0xa24d, 0x080c, 0xa93a,
 	0x012e, 0x00be, 0x0005, 0x0016, 0x0026, 0x0046, 0x00f6, 0x0126,
 	0x2091, 0x8000, 0x2079, 0x0100, 0x7904, 0x918c, 0xfffd, 0x7906,
-	0x2009, 0x00f7, 0x080c, 0x5fc0, 0x7940, 0x918c, 0x0010, 0x7942,
-	0x7924, 0xd1b4, 0x0120, 0x2011, 0x0040, 0x080c, 0x2a83, 0xd19c,
-	0x0120, 0x2011, 0x0008, 0x080c, 0x2a83, 0x0006, 0x0036, 0x0156,
-	0x0000, 0x2001, 0x19a6, 0x2004, 0x9005, 0x1518, 0x080c, 0x2a17,
-	0x1148, 0x2001, 0x0001, 0x080c, 0x297a, 0x2001, 0x0001, 0x080c,
-	0x295d, 0x00b8, 0x080c, 0x2a1f, 0x1138, 0x9006, 0x080c, 0x297a,
-	0x9006, 0x080c, 0x295d, 0x0068, 0x080c, 0x2a27, 0x1d50, 0x2001,
-	0x1997, 0x2004, 0xd0fc, 0x0108, 0x0020, 0x080c, 0x2774, 0x0804,
-	0x0cc1, 0x080c, 0x2aa6, 0x080c, 0x2ad9, 0x20a9, 0x003a, 0x1d04,
-	0x0c17, 0x080c, 0x873d, 0x1f04, 0x0c17, 0x080c, 0x74fd, 0x0148,
-	0x080c, 0x750f, 0x1118, 0x080c, 0x77fe, 0x0050, 0x080c, 0x74f4,
-	0x0dd0, 0x080c, 0x77f9, 0x080c, 0x77ef, 0x080c, 0x741d, 0x0020,
-	0x2009, 0x00f8, 0x080c, 0x5fc0, 0x7850, 0xc0e5, 0x7852, 0x080c,
-	0x74ec, 0x0120, 0x7843, 0x0090, 0x7843, 0x0010, 0x2021, 0xe678,
-	0x2019, 0xea60, 0x0d0c, 0x873d, 0x7820, 0xd09c, 0x15a0, 0x080c,
-	0x74ec, 0x0904, 0x0ca3, 0x7824, 0xd0ac, 0x1904, 0x0cc6, 0x080c,
-	0x750f, 0x1548, 0x0046, 0x2021, 0x0320, 0x8421, 0x1df0, 0x004e,
-	0x2011, 0x1800, 0x080c, 0x2a83, 0x080c, 0x2a2f, 0x7824, 0x9084,
+	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,
 	0x1800, 0x1168, 0x9484, 0x0fff, 0x1140, 0x2001, 0x1810, 0x2004,
 	0x9084, 0x9000, 0x0110, 0x080c, 0x0ce9, 0x8421, 0x1160, 0x1d04,
-	0x0c73, 0x080c, 0x873d, 0x080c, 0x77f9, 0x080c, 0x77ef, 0x7003,
+	0x0c73, 0x080c, 0x87b4, 0x080c, 0x784a, 0x080c, 0x7840, 0x7003,
 	0x0001, 0x0804, 0x0cc6, 0x8319, 0x1928, 0x2001, 0x1810, 0x2004,
 	0x9084, 0x9000, 0x0110, 0x080c, 0x0ce9, 0x1d04, 0x0c89, 0x080c,
-	0x873d, 0x2009, 0x199a, 0x2104, 0x9005, 0x0118, 0x8001, 0x200a,
-	0x1188, 0x200b, 0x000a, 0x2011, 0x0048, 0x080c, 0x2a83, 0x20a9,
-	0x0002, 0x080c, 0x2a10, 0x7924, 0x080c, 0x2a2f, 0xd19c, 0x0110,
-	0x080c, 0x294b, 0x00f0, 0x080c, 0x74fd, 0x1140, 0x94a2, 0x03e8,
-	0x1128, 0x080c, 0x74c0, 0x7003, 0x0001, 0x00c0, 0x2011, 0x1800,
-	0x080c, 0x2a83, 0x080c, 0x2a2f, 0x7824, 0x080c, 0x7506, 0x0110,
+	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, 0x25d5, 0x00a0, 0x7850, 0xc0e4,
+	0x0028, 0x2001, 0x0001, 0x080c, 0x2606, 0x00a0, 0x7850, 0xc0e4,
 	0x7852, 0x2009, 0x180c, 0x210c, 0xd19c, 0x1120, 0x7904, 0x918d,
-	0x0002, 0x7906, 0x2011, 0x0048, 0x080c, 0x2a83, 0x7828, 0x9085,
+	0x0002, 0x7906, 0x2011, 0x0048, 0x080c, 0x2ab4, 0x7828, 0x9085,
 	0x0028, 0x782a, 0x2001, 0x19a6, 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, 0x873d, 0x015e,
+	0x00d6, 0x00e6, 0x00f6, 0x0156, 0x0071, 0x0d0c, 0x87b4, 0x015e,
 	0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x004e, 0x003e, 0x002e,
 	0x001e, 0x000e, 0x0005, 0x00e6, 0x2071, 0x189e, 0x7004, 0x9086,
-	0x0001, 0x1110, 0x080c, 0x34af, 0x00ee, 0x0005, 0x0005, 0x2a70,
-	0x2061, 0x19aa, 0x2063, 0x0003, 0x6007, 0x0003, 0x600b, 0x0002,
+	0x0001, 0x1110, 0x080c, 0x34e0, 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, 0xccd1, 0x70ef,
+	0x715e, 0x7067, 0xffff, 0x717e, 0x7182, 0x080c, 0xcde8, 0x70ef,
 	0x00c0, 0x2061, 0x196b, 0x6003, 0x0909, 0x6106, 0x600b, 0x8800,
 	0x600f, 0x0200, 0x6013, 0x00ff, 0x6017, 0x001f, 0x611a, 0x601f,
 	0x07d0, 0x2061, 0x1973, 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, 0x6644,
+	0x2020, 0x2001, 0x182c, 0x2102, 0x0005, 0x9016, 0x080c, 0x6693,
 	0x1178, 0xb804, 0x90c4, 0x00ff, 0x98c6, 0x0006, 0x0128, 0x90c4,
 	0xff00, 0x98c6, 0x0600, 0x1120, 0x9186, 0x0080, 0x0108, 0x8210,
 	0x8108, 0x9186, 0x0800, 0x1d50, 0x2208, 0x0005, 0x2091, 0x8000,
@@ -229,30 +229,30 @@
 	0x0d7f, 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, 0x1b23, 0x7a08,
-	0x226a, 0x2069, 0x1b24, 0x7a18, 0x226a, 0x8d68, 0x7a1c, 0x226a,
-	0x782c, 0x2019, 0x1b31, 0x201a, 0x2019, 0x1b34, 0x9016, 0x7808,
-	0xd09c, 0x0168, 0x7820, 0x201a, 0x8210, 0x8318, 0x9386, 0x1b4d,
+	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,
-	0x1b32, 0x782c, 0x201a, 0x8318, 0x221a, 0x7803, 0x0000, 0x2069,
-	0x1a79, 0x901e, 0x20a9, 0x0020, 0x7b26, 0x7a28, 0x226a, 0x8d68,
-	0x8318, 0x1f04, 0x0dcc, 0x2069, 0x1a99, 0x2019, 0x0050, 0x20a9,
+	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, 0x5704, 0x1170, 0x080c, 0x0f20, 0x0110, 0x080c, 0x0e73,
-	0x080c, 0x5704, 0x1130, 0x2071, 0x1800, 0x2011, 0x8000, 0x080c,
+	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, 0xa88a, 0x2079,
-	0x0380, 0x2069, 0x1b03, 0x7818, 0x6802, 0x781c, 0x6806, 0x7840,
-	0x680a, 0x7844, 0x680e, 0x782c, 0x6812, 0x2019, 0x1b0e, 0x9016,
+	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, 0x1ac3, 0x901e, 0x20a9, 0x0020, 0x7b26, 0x7828, 0x206a,
-	0x8d68, 0x8318, 0x1f04, 0x0e4d, 0x2069, 0x1ae3, 0x2019, 0x00b0,
+	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,
@@ -263,11 +263,11 @@
 	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, 0x1128, 0x70f3, 0x0fa0, 0x080c, 0x0f25,
+	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, 0x2a27, 0x1118,
+	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,
@@ -324,7 +324,7 @@
 	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, 0x8566,
+	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,
@@ -390,15 +390,15 @@
 	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, 0x6d93, 0xa09f,
+	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, 0x6d93, 0x000e, 0x001e, 0xd1fc, 0x1138,
-	0xd1f4, 0x0128, 0x00c6, 0x2060, 0x080c, 0xabf0, 0x00ce, 0x7008,
+	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,
@@ -407,8 +407,8 @@
 	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, 0x8c34, 0x2009, 0x188c,
-	0x2104, 0x9084, 0xfffc, 0x200a, 0x080c, 0x8aa4, 0x7007, 0x0000,
+	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,
@@ -416,49 +416,49 @@
 	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, 0x1a79, 0x781f, 0xff00,
+	0x782b, 0x0400, 0x7827, 0x0031, 0x782b, 0x1a7c, 0x781f, 0xff00,
 	0x781b, 0xff00, 0x2001, 0x0200, 0x2004, 0xd0dc, 0x0110, 0x781f,
-	0x0303, 0x2061, 0x1a79, 0x602f, 0x1ddc, 0x2001, 0x181a, 0x2004,
-	0x9082, 0x1ddc, 0x6032, 0x603b, 0x1e7a, 0x602b, 0x1ab9, 0x6007,
-	0x1a99, 0x2061, 0x1a99, 0x606f, 0x193c, 0x2001, 0x1927, 0x2004,
-	0x607a, 0x783f, 0x3388, 0x00ce, 0x0005, 0x9086, 0x000d, 0x11d0,
-	0x7808, 0xd09c, 0x01b8, 0x7820, 0x0026, 0x2010, 0x080c, 0xc853,
+	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, 0xac8d,
+	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, 0x6bb5, 0x00b6, 0x6010, 0x2058, 0xba3c, 0x8211, 0x0208,
-	0xba3e, 0xb8d0, 0x9005, 0x190c, 0x676f, 0x00be, 0x6044, 0xd0fc,
-	0x190c, 0xa8c2, 0x080c, 0xac19, 0x7808, 0xd09c, 0x19b0, 0x012e,
+	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,
-	0x15f7, 0x15fe, 0x141f, 0x15ff, 0x1600, 0x160b, 0x1612, 0x141f,
+	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, 0x161d, 0x2009, 0x1a78, 0x2104,
-	0x8000, 0x200a, 0x080c, 0x7f9c, 0x080c, 0x1adf, 0x0005, 0x6044,
-	0xd0fc, 0x190c, 0xa8c2, 0x2009, 0x0055, 0x080c, 0xac8d, 0x012e,
-	0x0005, 0x080c, 0x161d, 0x2060, 0x6044, 0xd0fc, 0x190c, 0xa8c2,
-	0x2009, 0x0055, 0x080c, 0xac8d, 0x0005, 0x2009, 0x0048, 0x080c,
-	0x161d, 0x2060, 0x080c, 0xac8d, 0x0005, 0x2009, 0x0054, 0x080c,
-	0x161d, 0x2060, 0x6044, 0xd0fc, 0x190c, 0xa8c2, 0x080c, 0xac8d,
-	0x0005, 0x080c, 0x161d, 0x2060, 0x0056, 0x0066, 0x080c, 0x161d,
-	0x2028, 0x080c, 0x161d, 0x2030, 0x0036, 0x0046, 0x2021, 0x0000,
-	0x2418, 0x2009, 0x0056, 0x080c, 0xac8d, 0x004e, 0x003e, 0x006e,
-	0x005e, 0x0005, 0x080c, 0x161d, 0x0005, 0x7004, 0xc085, 0xc0b5,
-	0x7006, 0x0005, 0x7004, 0xc085, 0x7006, 0x0005, 0x080c, 0x161d,
-	0x080c, 0x16e1, 0x0005, 0x080c, 0x0d7d, 0x080c, 0x161d, 0x2060,
+	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, 0xac8d, 0x2001, 0x015d, 0x2003, 0x0000, 0x2009, 0x03e8,
+	0x080c, 0xad4d, 0x2001, 0x015d, 0x2003, 0x0000, 0x2009, 0x03e8,
 	0x8109, 0x0160, 0x2001, 0x0201, 0x2004, 0x9005, 0x0dc8, 0x2001,
-	0x0218, 0x2004, 0xd0ec, 0x1110, 0x080c, 0x1622, 0x2001, 0x0307,
+	0x0218, 0x2004, 0xd0ec, 0x1110, 0x080c, 0x162f, 0x2001, 0x0307,
 	0x2003, 0x8000, 0x0005, 0x7004, 0xc095, 0x7006, 0x0005, 0x080c,
-	0x161d, 0x2060, 0x6014, 0x0096, 0x2048, 0xa83b, 0xffff, 0x009e,
-	0x2009, 0x0048, 0x080c, 0xac8d, 0x0005, 0x080c, 0x161d, 0x080c,
-	0x0d7d, 0x080c, 0x161d, 0x080c, 0x1579, 0x7827, 0x0018, 0x79ac,
+	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,
@@ -467,4808 +467,4825 @@
 	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, 0x1adf, 0x080c, 0x1354, 0x7803, 0x0001, 0x0005,
+	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,
-	0x7f9c, 0x080c, 0x1adf, 0x080c, 0xc865, 0x0158, 0xa9ac, 0xa936,
+	0x7fed, 0x080c, 0x1b10, 0x080c, 0xc97a, 0x0158, 0xa9ac, 0xa936,
 	0xa9b0, 0xa93a, 0xa83f, 0xffff, 0xa843, 0xffff, 0xa880, 0xc0bd,
-	0xa882, 0x080c, 0xc453, 0x0005, 0x6020, 0x9086, 0x0009, 0x1128,
-	0x2009, 0x004c, 0x080c, 0xac8d, 0x0048, 0x6010, 0x00b6, 0x2058,
-	0xb800, 0x00be, 0xd0bc, 0x6024, 0x190c, 0xcc66, 0x2029, 0x00c8,
+	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, 0xe727, 0xd5a4, 0x1118, 0x080c, 0x1622, 0x0005, 0x080c,
-	0x7f9c, 0x080c, 0x1adf, 0x0005, 0x781f, 0x0300, 0x7803, 0x0001,
+	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,
-	0x1693, 0x00fe, 0x007e, 0x006e, 0x001e, 0x0005, 0x7004, 0xc09d,
+	0x16a0, 0x00fe, 0x007e, 0x006e, 0x001e, 0x0005, 0x7004, 0xc09d,
 	0x7006, 0x0005, 0x7104, 0x9184, 0x0004, 0x190c, 0x0d7d, 0xd184,
-	0x1189, 0xd19c, 0x0158, 0xc19c, 0x7106, 0x2001, 0x020d, 0x2003,
-	0x0050, 0x2003, 0x0020, 0x080c, 0x1622, 0x0005, 0x81ff, 0x190c,
-	0x0d7d, 0x0005, 0xc184, 0xd1b4, 0xc1b4, 0x7106, 0x0016, 0x00e6,
-	0x15f0, 0x2071, 0x0200, 0x080c, 0x16ce, 0x05c8, 0x6014, 0x9005,
-	0x05b0, 0x0096, 0x2048, 0xa864, 0x009e, 0x9084, 0x00ff, 0x908e,
-	0x0029, 0x0160, 0x908e, 0x0048, 0x1550, 0x601c, 0xd084, 0x11e0,
-	0x00f6, 0x2c78, 0x080c, 0x174b, 0x00fe, 0x00b0, 0x00f6, 0x2c78,
-	0x080c, 0x18d2, 0x00fe, 0x2009, 0x01f4, 0x8109, 0x0168, 0x2001,
-	0x0201, 0x2004, 0x9005, 0x0dc8, 0x2001, 0x0218, 0x2004, 0xd0ec,
-	0x1118, 0x080c, 0x1622, 0x0040, 0x2001, 0x020d, 0x2003, 0x0020,
-	0x080c, 0x1354, 0x7803, 0x0001, 0x00ee, 0x001e, 0x0005, 0x2001,
-	0x020d, 0x2003, 0x0050, 0x2003, 0x0020, 0x0461, 0x0ca8, 0x0429,
-	0x2060, 0x2009, 0x0053, 0x080c, 0xac8d, 0x0005, 0x0005, 0x0005,
-	0x00e1, 0x2008, 0x00d1, 0x0006, 0x7004, 0xc09d, 0x7006, 0x000e,
-	0x080c, 0x8f93, 0x0005, 0x0089, 0x9005, 0x0118, 0x080c, 0x8b94,
-	0x0cd0, 0x0005, 0x2001, 0x0036, 0x2009, 0x1820, 0x210c, 0x2011,
-	0x181f, 0x2214, 0x080c, 0x1693, 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, 0x1685, 0x6827, 0x0001, 0x8109,
-	0x1dd0, 0x04d9, 0x6827, 0x0002, 0x04c1, 0x6804, 0x9005, 0x1130,
-	0x682c, 0xd0e4, 0x1500, 0x6804, 0x9005, 0x0de8, 0x79b8, 0xd1ec,
-	0x1130, 0x08c0, 0x080c, 0x7f9c, 0x080c, 0x1adf, 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, 0x00e6, 0x0016, 0x2071, 0x0200, 0x0c41, 0x6124, 0xd1dc,
-	0x01f8, 0x701c, 0xd08c, 0x0904, 0x1740, 0x7017, 0x0000, 0x2001,
-	0x0264, 0x2004, 0xd0bc, 0x0904, 0x1740, 0x2001, 0x0268, 0x00c6,
-	0x2064, 0x6104, 0x6038, 0x00ce, 0x918e, 0x0039, 0x1904, 0x1740,
-	0x9c06, 0x15f0, 0x0126, 0x2091, 0x2600, 0x080c, 0x7ef4, 0x012e,
-	0x7358, 0x745c, 0x6014, 0x905d, 0x0598, 0x2b48, 0x6010, 0x00b6,
-	0x2058, 0xb800, 0x00be, 0xd0bc, 0x190c, 0xcc41, 0xab42, 0xac3e,
-	0x2001, 0x1869, 0x2004, 0xd0b4, 0x1170, 0x601c, 0xd0e4, 0x1158,
-	0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x1120, 0xa83b,
-	0x7fff, 0xa837, 0xffff, 0x080c, 0x1e9a, 0x1190, 0x080c, 0x192d,
-	0x2a00, 0xa816, 0x0130, 0x2800, 0xa80e, 0x2c05, 0xa80a, 0x2c00,
-	0xa812, 0x7037, 0x0020, 0x781f, 0x0300, 0x001e, 0x00ee, 0x0005,
-	0x7037, 0x0050, 0x7037, 0x0020, 0x001e, 0x00ee, 0x080c, 0x1622,
-	0x0005, 0x080c, 0x0d7d, 0x2cf0, 0x0126, 0x2091, 0x2200, 0x00c6,
-	0x3e60, 0x6014, 0x2048, 0x2940, 0x903e, 0x2730, 0xa864, 0x2068,
-	0xa81a, 0x9d84, 0x000f, 0x9088, 0x1e7a, 0x2165, 0x0002, 0x1776,
-	0x17e4, 0x1776, 0x1776, 0x177a, 0x17c5, 0x1776, 0x179a, 0x176f,
-	0x17db, 0x1776, 0x1776, 0x177f, 0x18d0, 0x17ae, 0x17a4, 0xa964,
-	0x918c, 0x00ff, 0x918e, 0x0048, 0x0904, 0x17db, 0x9085, 0x0001,
-	0x0804, 0x18c7, 0xa87c, 0xd0ac, 0x0dc8, 0x0804, 0x17eb, 0xa87c,
-	0xd0ac, 0x0da0, 0x0804, 0x1856, 0xa898, 0x901d, 0x1108, 0xab9c,
-	0x9016, 0xaab2, 0xaa3e, 0xaa42, 0x3e00, 0x9080, 0x0008, 0x2004,
-	0x9080, 0x915c, 0x2005, 0x9005, 0x090c, 0x0d7d, 0x2004, 0xa8ae,
-	0x0804, 0x18af, 0xa87c, 0xd0bc, 0x09c8, 0xa890, 0xa842, 0xa88c,
-	0xa83e, 0xa888, 0x0804, 0x17eb, 0xa87c, 0xd0bc, 0x0978, 0xa890,
-	0xa842, 0xa88c, 0xa83e, 0xa888, 0x0804, 0x1856, 0xa87c, 0xd0bc,
-	0x0928, 0xa890, 0xa842, 0xa88c, 0xa83e, 0xa804, 0x9045, 0x090c,
-	0x0d7d, 0xa164, 0xa91a, 0x91ec, 0x000f, 0x9d80, 0x1e7a, 0x2065,
-	0xa888, 0xd19c, 0x1904, 0x1856, 0x0430, 0xa87c, 0xd0ac, 0x0904,
-	0x1776, 0xa804, 0x9045, 0x090c, 0x0d7d, 0xa164, 0xa91a, 0x91ec,
-	0x000f, 0x9d80, 0x1e7a, 0x2065, 0x9006, 0xa842, 0xa83e, 0xd19c,
-	0x1904, 0x1856, 0x0080, 0xa87c, 0xd0ac, 0x0904, 0x1776, 0x9006,
-	0xa842, 0xa83e, 0x0804, 0x1856, 0xa87c, 0xd0ac, 0x0904, 0x1776,
-	0x9006, 0xa842, 0xa83e, 0x2c05, 0x908a, 0x0036, 0x1a0c, 0x0d7d,
-	0x9082, 0x001b, 0x0002, 0x180e, 0x180e, 0x1810, 0x180e, 0x180e,
-	0x180e, 0x181a, 0x180e, 0x180e, 0x180e, 0x1824, 0x180e, 0x180e,
-	0x180e, 0x182e, 0x180e, 0x180e, 0x180e, 0x1838, 0x180e, 0x180e,
-	0x180e, 0x1842, 0x180e, 0x180e, 0x180e, 0x184c, 0x080c, 0x0d7d,
-	0xa574, 0xa478, 0x9d86, 0x0024, 0x0904, 0x1784, 0xa37c, 0xa280,
-	0x0804, 0x18af, 0xa584, 0xa488, 0x9d86, 0x0024, 0x0904, 0x1784,
-	0xa38c, 0xa290, 0x0804, 0x18af, 0xa594, 0xa498, 0x9d86, 0x0024,
-	0x0904, 0x1784, 0xa39c, 0xa2a0, 0x0804, 0x18af, 0xa5a4, 0xa4a8,
-	0x9d86, 0x0024, 0x0904, 0x1784, 0xa3ac, 0xa2b0, 0x0804, 0x18af,
-	0xa5b4, 0xa4b8, 0x9d86, 0x0024, 0x0904, 0x1784, 0xa3bc, 0xa2c0,
-	0x0804, 0x18af, 0xa5c4, 0xa4c8, 0x9d86, 0x0024, 0x0904, 0x1784,
-	0xa3cc, 0xa2d0, 0x0804, 0x18af, 0xa5d4, 0xa4d8, 0x9d86, 0x0024,
-	0x0904, 0x1784, 0xa3dc, 0xa2e0, 0x0804, 0x18af, 0x2c05, 0x908a,
-	0x0034, 0x1a0c, 0x0d7d, 0x9082, 0x001b, 0x0002, 0x1879, 0x1877,
-	0x1877, 0x1877, 0x1877, 0x1877, 0x1884, 0x1877, 0x1877, 0x1877,
-	0x1877, 0x1877, 0x188f, 0x1877, 0x1877, 0x1877, 0x1877, 0x1877,
-	0x189a, 0x1877, 0x1877, 0x1877, 0x1877, 0x1877, 0x18a5, 0x080c,
-	0x0d7d, 0xa56c, 0xa470, 0xa774, 0xa678, 0x9d86, 0x002c, 0x0904,
-	0x1784, 0xa37c, 0xa280, 0x0458, 0xa584, 0xa488, 0xa78c, 0xa690,
-	0x9d86, 0x002c, 0x0904, 0x1784, 0xa394, 0xa298, 0x0400, 0xa59c,
-	0xa4a0, 0xa7a4, 0xa6a8, 0x9d86, 0x002c, 0x0904, 0x1784, 0xa3ac,
-	0xa2b0, 0x00a8, 0xa5b4, 0xa4b8, 0xa7bc, 0xa6c0, 0x9d86, 0x002c,
-	0x0904, 0x1784, 0xa3c4, 0xa2c8, 0x0050, 0xa5cc, 0xa4d0, 0xa7d4,
-	0xa6d8, 0x9d86, 0x002c, 0x0904, 0x1784, 0xa3dc, 0xa2e0, 0xab2e,
-	0xaa32, 0xad1e, 0xac22, 0xaf26, 0xae2a, 0xa988, 0x8c60, 0x2c1d,
-	0xa8ac, 0xaab0, 0xa836, 0xaa3a, 0x8109, 0xa916, 0x1158, 0x3e60,
-	0x601c, 0xc085, 0x601e, 0xa87c, 0xc0dd, 0xa87e, 0x9006, 0x00ce,
-	0x012e, 0x0005, 0x2800, 0xa80e, 0xab0a, 0x2c00, 0xa812, 0x0c78,
-	0x0804, 0x1776, 0x2ff0, 0x0126, 0x2091, 0x2200, 0x00c6, 0x3e60,
-	0x6014, 0x2048, 0x2940, 0xa80e, 0x2061, 0x1e75, 0xa813, 0x1e75,
+	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, 0x0078, 0x918a, 0x0002, 0xa916, 0x1158, 0x3e60,
+	0xa916, 0x0128, 0x0080, 0x918a, 0x0002, 0xa916, 0x1160, 0x3e60,
 	0x601c, 0xc085, 0x601e, 0xa87c, 0xc0dd, 0xa87e, 0x9006, 0x00ce,
-	0x012e, 0x0005, 0xa804, 0x9045, 0x090c, 0x0d7d, 0xa80e, 0xa064,
-	0xa81a, 0x9084, 0x000f, 0x9080, 0x1e7a, 0x2015, 0x82ff, 0x090c,
-	0x0d7d, 0xaa12, 0x2205, 0xa80a, 0x0c10, 0x903e, 0x2730, 0xa880,
-	0xd0fc, 0x1190, 0x2d00, 0x0002, 0x1a57, 0x1984, 0x1984, 0x1a57,
-	0x1984, 0x1a51, 0x1a57, 0x1984, 0x19f4, 0x19f4, 0x19f4, 0x1a57,
-	0x19f4, 0x1a57, 0x1a4e, 0x19f4, 0xc0fc, 0xa882, 0xab2c, 0xaa30,
-	0xad1c, 0xac20, 0xdd9c, 0x0904, 0x1a59, 0x2c05, 0x908a, 0x0034,
-	0x1a0c, 0x0d7d, 0x9082, 0x001b, 0x0002, 0x1970, 0x196e, 0x196e,
-	0x196e, 0x196e, 0x196e, 0x1974, 0x196e, 0x196e, 0x196e, 0x196e,
-	0x196e, 0x1978, 0x196e, 0x196e, 0x196e, 0x196e, 0x196e, 0x197c,
-	0x196e, 0x196e, 0x196e, 0x196e, 0x196e, 0x1980, 0x080c, 0x0d7d,
-	0xa774, 0xa678, 0x0804, 0x1a59, 0xa78c, 0xa690, 0x0804, 0x1a59,
-	0xa7a4, 0xa6a8, 0x0804, 0x1a59, 0xa7bc, 0xa6c0, 0x0804, 0x1a59,
-	0xa7d4, 0xa6d8, 0x0804, 0x1a59, 0xa898, 0x901d, 0x1108, 0xab9c,
-	0x9016, 0x2c05, 0x908a, 0x0036, 0x1a0c, 0x0d7d, 0x9082, 0x001b,
-	0x0002, 0x19ac, 0x19ac, 0x19ae, 0x19ac, 0x19ac, 0x19ac, 0x19b8,
-	0x19ac, 0x19ac, 0x19ac, 0x19c2, 0x19ac, 0x19ac, 0x19ac, 0x19cc,
-	0x19ac, 0x19ac, 0x19ac, 0x19d6, 0x19ac, 0x19ac, 0x19ac, 0x19e0,
-	0x19ac, 0x19ac, 0x19ac, 0x19ea, 0x080c, 0x0d7d, 0xa574, 0xa478,
-	0x9d86, 0x0004, 0x0904, 0x1a59, 0xa37c, 0xa280, 0x0804, 0x1a59,
-	0xa584, 0xa488, 0x9d86, 0x0004, 0x0904, 0x1a59, 0xa38c, 0xa290,
-	0x0804, 0x1a59, 0xa594, 0xa498, 0x9d86, 0x0004, 0x0904, 0x1a59,
-	0xa39c, 0xa2a0, 0x0804, 0x1a59, 0xa5a4, 0xa4a8, 0x9d86, 0x0004,
-	0x0904, 0x1a59, 0xa3ac, 0xa2b0, 0x0804, 0x1a59, 0xa5b4, 0xa4b8,
-	0x9d86, 0x0004, 0x0904, 0x1a59, 0xa3bc, 0xa2c0, 0x0804, 0x1a59,
-	0xa5c4, 0xa4c8, 0x9d86, 0x0004, 0x0904, 0x1a59, 0xa3cc, 0xa2d0,
-	0x0804, 0x1a59, 0xa5d4, 0xa4d8, 0x9d86, 0x0004, 0x0904, 0x1a59,
-	0xa3dc, 0xa2e0, 0x0804, 0x1a59, 0xa898, 0x901d, 0x1108, 0xab9c,
-	0x9016, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0d7d, 0x9082, 0x001b,
-	0x0002, 0x1a1c, 0x1a1a, 0x1a1a, 0x1a1a, 0x1a1a, 0x1a1a, 0x1a26,
-	0x1a1a, 0x1a1a, 0x1a1a, 0x1a1a, 0x1a1a, 0x1a30, 0x1a1a, 0x1a1a,
-	0x1a1a, 0x1a1a, 0x1a1a, 0x1a3a, 0x1a1a, 0x1a1a, 0x1a1a, 0x1a1a,
-	0x1a1a, 0x1a44, 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, 0x1e50, 0x1904, 0x192d, 0x900e, 0x0050, 0x080c,
-	0x0d7d, 0xab2e, 0xaa32, 0xad1e, 0xac22, 0xaf26, 0xae2a, 0x080c,
-	0x1e50, 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, 0xac8d, 0x0005,
-	0xa974, 0xd1dc, 0x1108, 0x0005, 0xa934, 0xa88c, 0x9106, 0x1158,
-	0xa938, 0xa890, 0x9106, 0x1138, 0x601c, 0xc084, 0x601e, 0x2009,
-	0x0048, 0x0804, 0xac8d, 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,
-	0x1b67, 0x7930, 0x9186, 0x0040, 0x0160, 0x9186, 0x0042, 0x190c,
-	0x0d7d, 0x2001, 0x001e, 0x8001, 0x1df0, 0x8631, 0x1d40, 0x080c,
-	0x1b76, 0x000e, 0x6022, 0x012e, 0x0005, 0x080c, 0x1b63, 0x7827,
-	0x0015, 0x7828, 0x9c06, 0x1db8, 0x782b, 0x0000, 0x0ca0, 0x00f6,
-	0x2079, 0x0300, 0x7803, 0x0000, 0x78ab, 0x0004, 0x00fe, 0x080c,
-	0x74ec, 0x1188, 0x2001, 0x0138, 0x2003, 0x0000, 0x2001, 0x0160,
-	0x2003, 0x0000, 0x2011, 0x012c, 0xa001, 0xa001, 0x8211, 0x1de0,
-	0x0059, 0x0804, 0x7591, 0x0479, 0x0039, 0x2001, 0x0160, 0x2502,
-	0x2001, 0x0138, 0x2202, 0x0005, 0x00e6, 0x2071, 0x0200, 0x080c,
-	0x2a3b, 0x2009, 0x003c, 0x080c, 0x21d9, 0x2001, 0x015d, 0x2003,
-	0x0000, 0x7000, 0x9084, 0x003c, 0x1de0, 0x080c, 0x8566, 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, 0x74ec, 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, 0x1693, 0x7930, 0x0005, 0x2c08, 0x621c, 0x080c,
-	0x16c0, 0x7930, 0x0005, 0x8001, 0x1df0, 0x0005, 0x2031, 0x0005,
-	0x781c, 0x9084, 0x0007, 0x0170, 0x2001, 0x0038, 0x0c41, 0x9186,
-	0x0040, 0x0904, 0x1bd4, 0x2001, 0x001e, 0x0c69, 0x8631, 0x1d80,
-	0x080c, 0x0d7d, 0x781f, 0x0202, 0x2001, 0x015d, 0x2003, 0x0000,
-	0x2001, 0x0b10, 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, 0x1b6d,
-	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, 0x1c09, 0x1c09, 0x1c09,
-	0x1c0b, 0x1c09, 0x1c09, 0x1c09, 0x1c09, 0x1bfd, 0x1c13, 0x1c09,
-	0x1c0f, 0x1c09, 0x1c09, 0x1c09, 0x1c09, 0x9086, 0x0008, 0x1148,
-	0xa87c, 0xd0b4, 0x0904, 0x1d83, 0x2011, 0x1e75, 0x2205, 0xab88,
-	0x00a8, 0x080c, 0x0d7d, 0x9186, 0x0013, 0x0128, 0x0cd0, 0x9186,
-	0x001b, 0x0108, 0x0cb0, 0xa87c, 0xd0b4, 0x0904, 0x1d83, 0x9184,
-	0x000f, 0x9080, 0x1e7a, 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, 0x1e7a, 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,
-	0x1d4d, 0xc1dd, 0xa97e, 0x9006, 0xa842, 0xa83e, 0xa988, 0x8109,
-	0xa916, 0xa964, 0xa91a, 0x9184, 0x000f, 0x9088, 0x1e7a, 0x2145,
-	0x0002, 0x1c81, 0x1c8f, 0x1c81, 0x1c81, 0x1c81, 0x1c83, 0x1c81,
-	0x1c81, 0x1ce4, 0x1ce4, 0x1c81, 0x1c81, 0x1c81, 0x1ce2, 0x1c81,
-	0x1c81, 0x080c, 0x0d7d, 0xa804, 0x2050, 0xb164, 0xa91a, 0x9184,
-	0x000f, 0x9080, 0x1e7a, 0x2045, 0xd19c, 0x1904, 0x1ce4, 0x9036,
-	0x2638, 0x2805, 0x908a, 0x0036, 0x1a0c, 0x0d7d, 0x9082, 0x001b,
-	0x0002, 0x1cb4, 0x1cb4, 0x1cb6, 0x1cb4, 0x1cb4, 0x1cb4, 0x1cbc,
-	0x1cb4, 0x1cb4, 0x1cb4, 0x1cc2, 0x1cb4, 0x1cb4, 0x1cb4, 0x1cc8,
-	0x1cb4, 0x1cb4, 0x1cb4, 0x1cce, 0x1cb4, 0x1cb4, 0x1cb4, 0x1cd4,
-	0x1cb4, 0x1cb4, 0x1cb4, 0x1cda, 0x080c, 0x0d7d, 0xb574, 0xb478,
-	0xb37c, 0xb280, 0x0804, 0x1d29, 0xb584, 0xb488, 0xb38c, 0xb290,
-	0x0804, 0x1d29, 0xb594, 0xb498, 0xb39c, 0xb2a0, 0x0804, 0x1d29,
-	0xb5a4, 0xb4a8, 0xb3ac, 0xb2b0, 0x0804, 0x1d29, 0xb5b4, 0xb4b8,
-	0xb3bc, 0xb2c0, 0x0804, 0x1d29, 0xb5c4, 0xb4c8, 0xb3cc, 0xb2d0,
-	0x0804, 0x1d29, 0xb5d4, 0xb4d8, 0xb3dc, 0xb2e0, 0x0804, 0x1d29,
-	0x0804, 0x1d29, 0x080c, 0x0d7d, 0x2805, 0x908a, 0x0034, 0x1a0c,
-	0x0d7d, 0x9082, 0x001b, 0x0002, 0x1d07, 0x1d05, 0x1d05, 0x1d05,
-	0x1d05, 0x1d05, 0x1d0e, 0x1d05, 0x1d05, 0x1d05, 0x1d05, 0x1d05,
-	0x1d15, 0x1d05, 0x1d05, 0x1d05, 0x1d05, 0x1d05, 0x1d1c, 0x1d05,
-	0x1d05, 0x1d05, 0x1d05, 0x1d05, 0x1d23, 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, 0x1e7a, 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, 0x1e9a,
-	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, 0x1d36, 0x2009, 0x8005, 0x3e60, 0x6044, 0x9105,
-	0x6046, 0x0804, 0x1d33, 0x080c, 0x0d7d, 0x00f6, 0x00e6, 0x0096,
-	0x00c6, 0x0026, 0x704c, 0x9c06, 0x190c, 0x0d7d, 0x2079, 0x0090,
-	0x2001, 0x0105, 0x2003, 0x0010, 0x782b, 0x0004, 0x7057, 0x0000,
-	0x6014, 0x2048, 0x080c, 0xc865, 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, 0xc453, 0x080c,
-	0xa899, 0x00ce, 0x704c, 0x9c06, 0x1150, 0x2009, 0x0040, 0x080c,
-	0x21d9, 0x080c, 0xa33e, 0x2011, 0x0000, 0x080c, 0xa1c8, 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, 0x1e4b, 0x2079, 0x0090,
-	0x2009, 0x0207, 0x210c, 0xd194, 0x01b8, 0x2009, 0x020c, 0x210c,
-	0x9184, 0x0003, 0x0188, 0x080c, 0xe770, 0x2001, 0x0133, 0x2004,
-	0x9005, 0x090c, 0x0d7d, 0x0016, 0x2009, 0x0040, 0x080c, 0x21d9,
-	0x001e, 0x2001, 0x020c, 0x2102, 0x2009, 0x0206, 0x2104, 0x2009,
-	0x0203, 0x210c, 0x9106, 0x1120, 0x2009, 0x0040, 0x080c, 0x21d9,
-	0x782c, 0xd0fc, 0x09a8, 0x080c, 0xa8b5, 0x782c, 0xd0fc, 0x1de8,
-	0x080c, 0xa899, 0x7054, 0x9086, 0x0000, 0x1950, 0x782b, 0x0004,
-	0x782c, 0xd0ac, 0x1de8, 0x2009, 0x0040, 0x080c, 0x21d9, 0x782b,
-	0x0002, 0x7057, 0x0000, 0x00ee, 0x00fe, 0x0005, 0x080c, 0x0d7d,
-	0x8c60, 0x2c05, 0x9005, 0x0110, 0x8a51, 0x0005, 0xa004, 0x9005,
-	0x0168, 0xa85a, 0x2040, 0xa064, 0x9084, 0x000f, 0x9080, 0x1e7a,
-	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, 0x1e6d, 0x1e69, 0x1e6d, 0x1e6d, 0x1e77,
-	0x0000, 0x1e6d, 0x1e74, 0x1e74, 0x1e71, 0x1e74, 0x1e74, 0x0000,
-	0x1e77, 0x1e74, 0x0000, 0x1e6f, 0x1e6f, 0x0000, 0x1e6f, 0x1e77,
-	0x0000, 0x1e6f, 0x1e75, 0x1e75, 0x1e75, 0x0000, 0x1e75, 0x0000,
-	0x1e77, 0x1e75, 0x00c6, 0x00d6, 0x0086, 0xab42, 0xac3e, 0xa888,
-	0x9055, 0x0904, 0x2079, 0x2940, 0xa064, 0x90ec, 0x000f, 0x9084,
-	0x00ff, 0x9086, 0x0008, 0x1118, 0x2061, 0x1e75, 0x00d0, 0x9de0,
-	0x1e7a, 0x9d86, 0x0007, 0x0130, 0x9d86, 0x000e, 0x0118, 0x9d86,
-	0x000f, 0x1120, 0xa08c, 0x9422, 0xa090, 0x931b, 0x2c05, 0x9065,
-	0x1140, 0x0310, 0x0804, 0x2079, 0xa004, 0x9045, 0x0904, 0x2079,
-	0x08d8, 0x2c05, 0x9005, 0x0904, 0x1f61, 0xdd9c, 0x1904, 0x1f1d,
-	0x908a, 0x0036, 0x1a0c, 0x0d7d, 0x9082, 0x001b, 0x0002, 0x1ef2,
-	0x1ef2, 0x1ef4, 0x1ef2, 0x1ef2, 0x1ef2, 0x1efa, 0x1ef2, 0x1ef2,
-	0x1ef2, 0x1f00, 0x1ef2, 0x1ef2, 0x1ef2, 0x1f06, 0x1ef2, 0x1ef2,
-	0x1ef2, 0x1f0c, 0x1ef2, 0x1ef2, 0x1ef2, 0x1f12, 0x1ef2, 0x1ef2,
-	0x1ef2, 0x1f18, 0x080c, 0x0d7d, 0xa07c, 0x9422, 0xa080, 0x931b,
-	0x0804, 0x1f57, 0xa08c, 0x9422, 0xa090, 0x931b, 0x0804, 0x1f57,
-	0xa09c, 0x9422, 0xa0a0, 0x931b, 0x0804, 0x1f57, 0xa0ac, 0x9422,
-	0xa0b0, 0x931b, 0x0804, 0x1f57, 0xa0bc, 0x9422, 0xa0c0, 0x931b,
-	0x0804, 0x1f57, 0xa0cc, 0x9422, 0xa0d0, 0x931b, 0x0804, 0x1f57,
-	0xa0dc, 0x9422, 0xa0e0, 0x931b, 0x04d0, 0x908a, 0x0034, 0x1a0c,
-	0x0d7d, 0x9082, 0x001b, 0x0002, 0x1f3f, 0x1f3d, 0x1f3d, 0x1f3d,
-	0x1f3d, 0x1f3d, 0x1f44, 0x1f3d, 0x1f3d, 0x1f3d, 0x1f3d, 0x1f3d,
-	0x1f49, 0x1f3d, 0x1f3d, 0x1f3d, 0x1f3d, 0x1f3d, 0x1f4e, 0x1f3d,
-	0x1f3d, 0x1f3d, 0x1f3d, 0x1f3d, 0x1f53, 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, 0x2079, 0x8c60, 0x0804,
-	0x1ec9, 0xa004, 0x9045, 0x0904, 0x2079, 0x0804, 0x1ea4, 0x8a51,
-	0x0904, 0x2079, 0x8c60, 0x2c05, 0x9005, 0x1158, 0xa004, 0x9045,
-	0x0904, 0x2079, 0xa064, 0x90ec, 0x000f, 0x9de0, 0x1e7a, 0x2c05,
-	0x2060, 0xa880, 0xc0fc, 0xa882, 0x0804, 0x206e, 0x2c05, 0x8422,
-	0x8420, 0x831a, 0x9399, 0x0000, 0xac2e, 0xab32, 0xdd9c, 0x1904,
-	0x200b, 0x9082, 0x001b, 0x0002, 0x1fa7, 0x1fa7, 0x1fa9, 0x1fa7,
-	0x1fa7, 0x1fa7, 0x1fb7, 0x1fa7, 0x1fa7, 0x1fa7, 0x1fc5, 0x1fa7,
-	0x1fa7, 0x1fa7, 0x1fd3, 0x1fa7, 0x1fa7, 0x1fa7, 0x1fe1, 0x1fa7,
-	0x1fa7, 0x1fa7, 0x1fef, 0x1fa7, 0x1fa7, 0x1fa7, 0x1ffd, 0x080c,
-	0x0d7d, 0xa17c, 0x2400, 0x9122, 0xa180, 0x2300, 0x911b, 0x0a0c,
-	0x0d7d, 0xa074, 0x9420, 0xa078, 0x9319, 0x0804, 0x2069, 0xa18c,
-	0x2400, 0x9122, 0xa190, 0x2300, 0x911b, 0x0a0c, 0x0d7d, 0xa084,
-	0x9420, 0xa088, 0x9319, 0x0804, 0x2069, 0xa19c, 0x2400, 0x9122,
-	0xa1a0, 0x2300, 0x911b, 0x0a0c, 0x0d7d, 0xa094, 0x9420, 0xa098,
-	0x9319, 0x0804, 0x2069, 0xa1ac, 0x2400, 0x9122, 0xa1b0, 0x2300,
-	0x911b, 0x0a0c, 0x0d7d, 0xa0a4, 0x9420, 0xa0a8, 0x9319, 0x0804,
-	0x2069, 0xa1bc, 0x2400, 0x9122, 0xa1c0, 0x2300, 0x911b, 0x0a0c,
-	0x0d7d, 0xa0b4, 0x9420, 0xa0b8, 0x9319, 0x0804, 0x2069, 0xa1cc,
-	0x2400, 0x9122, 0xa1d0, 0x2300, 0x911b, 0x0a0c, 0x0d7d, 0xa0c4,
-	0x9420, 0xa0c8, 0x9319, 0x0804, 0x2069, 0xa1dc, 0x2400, 0x9122,
-	0xa1e0, 0x2300, 0x911b, 0x0a0c, 0x0d7d, 0xa0d4, 0x9420, 0xa0d8,
-	0x9319, 0x0804, 0x2069, 0x9082, 0x001b, 0x0002, 0x2029, 0x2027,
-	0x2027, 0x2027, 0x2027, 0x2027, 0x2036, 0x2027, 0x2027, 0x2027,
-	0x2027, 0x2027, 0x2043, 0x2027, 0x2027, 0x2027, 0x2027, 0x2027,
-	0x2050, 0x2027, 0x2027, 0x2027, 0x2027, 0x2027, 0x205d, 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, 0x21d6, 0x7900, 0xd1dc, 0x1118, 0x9084, 0x0006,
-	0x001a, 0x9084, 0x000e, 0x0002, 0x20f4, 0x20ec, 0x7ef4, 0x20ec,
-	0x20ee, 0x20ee, 0x20ee, 0x20ee, 0x7eda, 0x20ec, 0x20f0, 0x20ec,
-	0x20ee, 0x20ec, 0x20ee, 0x20ec, 0x080c, 0x0d7d, 0x0031, 0x0020,
-	0x080c, 0x7eda, 0x080c, 0x7ef4, 0x0005, 0x0006, 0x0016, 0x0026,
-	0x080c, 0xe770, 0x7930, 0x9184, 0x0003, 0x0510, 0x080c, 0xa899,
-	0x2001, 0x19f9, 0x2004, 0x9005, 0x01a0, 0x2001, 0x0133, 0x2004,
-	0x9005, 0x090c, 0x0d7d, 0x00c6, 0x2001, 0x19f9, 0x2064, 0x080c,
-	0xa8b5, 0x080c, 0xc453, 0x2009, 0x0040, 0x080c, 0x21d9, 0x00ce,
-	0x0408, 0x2009, 0x0040, 0x080c, 0x21d9, 0x080c, 0xa8b5, 0x00d0,
-	0x9184, 0x0014, 0x01a0, 0x6a00, 0x9286, 0x0003, 0x0160, 0x080c,
-	0x74ec, 0x1138, 0x080c, 0x77ef, 0x080c, 0x6044, 0x080c, 0x741d,
-	0x0010, 0x080c, 0x5eff, 0x080c, 0x7f92, 0x0041, 0x0018, 0x9184,
-	0x9540, 0x1dc8, 0x002e, 0x001e, 0x000e, 0x0005, 0x00e6, 0x0036,
-	0x0046, 0x0056, 0x2071, 0x1a6a, 0x080c, 0x1adf, 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, 0x2a35, 0x080c,
-	0x294b, 0x2001, 0x199c, 0x2003, 0x0700, 0x2001, 0x199d, 0x2003,
-	0x0700, 0x080c, 0x2aa6, 0x9006, 0x080c, 0x297a, 0x9006, 0x080c,
-	0x295d, 0x20a9, 0x0012, 0x1d04, 0x220b, 0x2091, 0x6000, 0x1f04,
-	0x220b, 0x602f, 0x0100, 0x602f, 0x0000, 0x6050, 0x9085, 0x0400,
-	0x9084, 0xdfff, 0x6052, 0x6224, 0x080c, 0x2a83, 0x080c, 0x2669,
-	0x2009, 0x00ef, 0x6132, 0x6136, 0x080c, 0x2679, 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, 0x2249, 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, 0x22b7, 0x22b4, 0x22b4, 0x22b4,
-	0x22b6, 0x22b4, 0x22b4, 0x22b4, 0x080c, 0x0d7d, 0x0029, 0x002e,
-	0x001e, 0x000e, 0x012e, 0x0005, 0x00a6, 0x6124, 0x6028, 0xd09c,
-	0x0118, 0xd19c, 0x1904, 0x2531, 0xd1f4, 0x190c, 0x0d76, 0x080c,
-	0x74ec, 0x0904, 0x2314, 0x080c, 0xcf84, 0x1120, 0x7000, 0x9086,
-	0x0003, 0x0580, 0x6024, 0x9084, 0x1800, 0x0560, 0x080c, 0x750f,
-	0x0118, 0x080c, 0x74fd, 0x1530, 0x2011, 0x0020, 0x080c, 0x2a83,
-	0x6043, 0x0000, 0x080c, 0xcf84, 0x0168, 0x080c, 0x750f, 0x1150,
-	0x2001, 0x19a6, 0x2003, 0x0001, 0x6027, 0x1800, 0x080c, 0x7362,
-	0x0804, 0x2534, 0x70a4, 0x9005, 0x1150, 0x70a7, 0x0001, 0x00d6,
-	0x2069, 0x0140, 0x080c, 0x7543, 0x00de, 0x1904, 0x2534, 0x080c,
-	0x77f9, 0x0428, 0x080c, 0x750f, 0x1590, 0x6024, 0x9084, 0x1800,
-	0x1108, 0x0468, 0x080c, 0x77f9, 0x080c, 0x77ef, 0x080c, 0x6044,
-	0x080c, 0x741d, 0x0804, 0x2531, 0xd1ac, 0x1508, 0x6024, 0xd0dc,
-	0x1170, 0xd0e4, 0x1178, 0xd0d4, 0x1190, 0xd0cc, 0x0130, 0x7098,
-	0x9086, 0x0028, 0x1110, 0x080c, 0x76d0, 0x0804, 0x2531, 0x080c,
-	0x77f4, 0x0048, 0x2001, 0x197c, 0x2003, 0x0002, 0x0020, 0x080c,
-	0x762d, 0x0804, 0x2531, 0x080c, 0x7773, 0x0804, 0x2531, 0x6220,
-	0xd1bc, 0x0138, 0xd2bc, 0x1904, 0x259a, 0xd2b4, 0x1904, 0x25ac,
-	0x0000, 0xd1ac, 0x0904, 0x243e, 0x0036, 0x6328, 0xc3bc, 0x632a,
-	0x003e, 0x080c, 0x74ec, 0x11d0, 0x2011, 0x0020, 0x080c, 0x2a83,
-	0x0006, 0x0026, 0x0036, 0x080c, 0x7506, 0x1158, 0x080c, 0x77ef,
-	0x080c, 0x6044, 0x080c, 0x741d, 0x003e, 0x002e, 0x000e, 0x00ae,
-	0x0005, 0x003e, 0x002e, 0x000e, 0x080c, 0x74c0, 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, 0x4b29,
-	0x003e, 0x080c, 0xcf7d, 0x1904, 0x2415, 0x9196, 0xff00, 0x05a8,
-	0x7060, 0x9084, 0x00ff, 0x810f, 0x81ff, 0x0110, 0x9116, 0x0568,
-	0x7130, 0xd184, 0x1550, 0x080c, 0x337c, 0x0128, 0xc18d, 0x7132,
-	0x080c, 0x6a86, 0x1510, 0x6240, 0x9294, 0x0010, 0x0130, 0x6248,
-	0x9294, 0xff00, 0x9296, 0xff00, 0x01c0, 0x7030, 0xd08c, 0x0904,
-	0x2415, 0x7038, 0xd08c, 0x1140, 0x2001, 0x180c, 0x200c, 0xd1ac,
-	0x1904, 0x2415, 0xc1ad, 0x2102, 0x0036, 0x73d8, 0x2011, 0x8013,
-	0x080c, 0x4b29, 0x003e, 0x0804, 0x2415, 0x7038, 0xd08c, 0x1140,
-	0x2001, 0x180c, 0x200c, 0xd1ac, 0x1904, 0x2415, 0xc1ad, 0x2102,
-	0x0036, 0x73d8, 0x2011, 0x8013, 0x080c, 0x4b29, 0x003e, 0x7130,
-	0xc185, 0x7132, 0x2011, 0x1848, 0x220c, 0xd1a4, 0x01f0, 0x0016,
-	0x2009, 0x0001, 0x2011, 0x0100, 0x080c, 0x8902, 0x2019, 0x000e,
-	0x00c6, 0x2061, 0x0000, 0x080c, 0xe286, 0x00ce, 0x9484, 0x00ff,
-	0x9080, 0x3388, 0x200d, 0x918c, 0xff00, 0x810f, 0x2120, 0x9006,
-	0x2009, 0x000e, 0x080c, 0xe316, 0x001e, 0x0016, 0x2009, 0x0002,
-	0x2019, 0x0004, 0x080c, 0x31d4, 0x001e, 0x0078, 0x0156, 0x00b6,
-	0x20a9, 0x007f, 0x900e, 0x080c, 0x6644, 0x1110, 0x080c, 0x605e,
-	0x8108, 0x1f04, 0x240b, 0x00be, 0x015e, 0x00ce, 0x004e, 0x080c,
-	0xa899, 0x080c, 0xab61, 0x080c, 0xa8b5, 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, 0x2a83, 0xd194, 0x0904,
-	0x2531, 0x0016, 0x080c, 0xa899, 0x6220, 0xd2b4, 0x0904, 0x24cc,
-	0x080c, 0x8709, 0x080c, 0x9e4f, 0x2011, 0x0004, 0x080c, 0x2a83,
-	0x00f6, 0x2019, 0x19f2, 0x2304, 0x907d, 0x0904, 0x2499, 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, 0x2a59, 0x2001, 0x001e, 0x8001, 0x0240, 0x20a9,
-	0x0009, 0x080c, 0x2a10, 0x6904, 0xd1dc, 0x1140, 0x0cb0, 0x2001,
-	0x0100, 0x080c, 0x2a49, 0x9006, 0x080c, 0x2a49, 0x080c, 0x95ff,
-	0x080c, 0xa8b5, 0x7814, 0x2048, 0xa867, 0x0103, 0x2f60, 0x080c,
-	0xabf0, 0x009e, 0x00ee, 0x00ce, 0x00de, 0x00fe, 0x001e, 0x00ae,
-	0x0005, 0x00fe, 0x00d6, 0x2069, 0x0140, 0x6804, 0x9084, 0x4000,
-	0x0110, 0x080c, 0x2a59, 0x00de, 0x00c6, 0x2061, 0x19e6, 0x6034,
-	0x080c, 0xcf84, 0x0120, 0x909a, 0x0003, 0x1258, 0x0018, 0x909a,
-	0x00c8, 0x1238, 0x8000, 0x6036, 0x00ce, 0x080c, 0x9e27, 0x0804,
-	0x252e, 0x2061, 0x0100, 0x62c0, 0x080c, 0xa7ca, 0x2019, 0x19f2,
-	0x2304, 0x9065, 0x0130, 0x6003, 0x0001, 0x2009, 0x0027, 0x080c,
-	0xac8d, 0x00ce, 0x0804, 0x252e, 0xd2bc, 0x0904, 0x2511, 0x080c,
-	0x8716, 0x2011, 0x0004, 0x080c, 0x2a83, 0x00d6, 0x2069, 0x0140,
-	0x6804, 0x9084, 0x4000, 0x0110, 0x080c, 0x2a59, 0x00de, 0x00c6,
-	0x2061, 0x19e6, 0x6050, 0x080c, 0xcf84, 0x0120, 0x909a, 0x0003,
-	0x1668, 0x0018, 0x909a, 0x00c8, 0x1648, 0x8000, 0x6052, 0x604c,
-	0x00ce, 0x9005, 0x05d8, 0x2009, 0x07d0, 0x080c, 0x870e, 0x9080,
-	0x0008, 0x2004, 0x9086, 0x0006, 0x1138, 0x2009, 0x1984, 0x2011,
-	0x0012, 0x080c, 0x2a92, 0x0450, 0x9080, 0x0008, 0x2004, 0x9086,
-	0x0009, 0x0d98, 0x2009, 0x1984, 0x2011, 0x0016, 0x080c, 0x2a92,
-	0x00e8, 0x2011, 0x0004, 0x080c, 0x2a83, 0x00c0, 0x0036, 0x2019,
-	0x0001, 0x080c, 0xa133, 0x003e, 0x2019, 0x19f9, 0x2304, 0x9065,
-	0x0160, 0x2009, 0x004f, 0x6020, 0x9086, 0x0009, 0x1110, 0x2009,
-	0x004f, 0x6003, 0x0003, 0x080c, 0xac8d, 0x00ce, 0x080c, 0xa8b5,
-	0x001e, 0xd19c, 0x0904, 0x2593, 0x7038, 0xd0ac, 0x1558, 0x0016,
-	0x0156, 0x2011, 0x0008, 0x080c, 0x2a83, 0x080c, 0x2aa6, 0x080c,
-	0x2ad9, 0x6050, 0xc0e5, 0x6052, 0x20a9, 0x0367, 0x1f04, 0x2560,
-	0x1d04, 0x2548, 0x080c, 0x873d, 0x6020, 0xd09c, 0x1db8, 0x00f6,
-	0x2079, 0x0100, 0x080c, 0x29bc, 0x00fe, 0x1d80, 0x6050, 0xc0e4,
-	0x6052, 0x2011, 0x0008, 0x080c, 0x2a83, 0x015e, 0x001e, 0x0498,
-	0x015e, 0x001e, 0x0016, 0x6028, 0xc09c, 0x602a, 0x080c, 0xa899,
-	0x080c, 0xab61, 0x080c, 0xa8b5, 0x60e3, 0x0000, 0x080c, 0xe74f,
-	0x080c, 0xe76a, 0x080c, 0x56f9, 0xd0fc, 0x1138, 0x080c, 0xcf7d,
-	0x1120, 0x9085, 0x0001, 0x080c, 0x7533, 0x9006, 0x080c, 0x2a49,
-	0x2009, 0x0002, 0x080c, 0x2a35, 0x00e6, 0x2071, 0x1800, 0x7003,
-	0x0004, 0x080c, 0x0ec1, 0x00ee, 0x2011, 0x0008, 0x080c, 0x2a83,
-	0x080c, 0x0bc3, 0x001e, 0x918c, 0xffd0, 0x2110, 0x080c, 0x2a83,
-	0x00ae, 0x0005, 0x0016, 0x2001, 0x0387, 0x200c, 0xd1a4, 0x001e,
-	0x0904, 0x2341, 0x0016, 0x2009, 0x25a6, 0x00c0, 0x2001, 0x0387,
-	0x2003, 0x1000, 0x001e, 0x0c38, 0x0016, 0x2001, 0x0387, 0x200c,
-	0xd1b4, 0x001e, 0x0904, 0x2341, 0x0016, 0x2009, 0x25b8, 0x0030,
-	0x2001, 0x0387, 0x2003, 0x4000, 0x001e, 0x08a8, 0x6028, 0xc0bc,
-	0x602a, 0x2001, 0x0156, 0x2003, 0xbc91, 0x8000, 0x2003, 0xffff,
-	0x6043, 0x0001, 0x080c, 0x2a2f, 0x2011, 0x0080, 0x080c, 0x2a83,
-	0x6017, 0x0000, 0x6043, 0x0000, 0x0817, 0x0006, 0x0016, 0x0026,
-	0x0036, 0x00e6, 0x00f6, 0x0126, 0x2091, 0x8000, 0x2071, 0x1800,
-	0x71d0, 0x70d2, 0x9116, 0x0904, 0x2628, 0x81ff, 0x01a0, 0x2009,
-	0x0000, 0x080c, 0x2a35, 0x2011, 0x8011, 0x2019, 0x010e, 0x231c,
-	0x939e, 0x0007, 0x1118, 0x2019, 0x0001, 0x0010, 0x2019, 0x0000,
-	0x080c, 0x4b29, 0x0468, 0x2001, 0x19a7, 0x200c, 0x81ff, 0x1140,
-	0x2001, 0x0109, 0x2004, 0xd0b4, 0x0118, 0x2019, 0x0003, 0x0008,
-	0x2118, 0x2011, 0x8012, 0x080c, 0x4b29, 0x080c, 0x0ec1, 0x080c,
-	0x56f9, 0xd0fc, 0x11a8, 0x080c, 0xcf7d, 0x1190, 0x00c6, 0x080c,
-	0x26c4, 0x080c, 0xa899, 0x080c, 0xa08e, 0x080c, 0xa8b5, 0x2061,
-	0x0100, 0x2019, 0x0028, 0x2009, 0x0002, 0x080c, 0x31d4, 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, 0x8202,
-	0x0048, 0x9584, 0x00ff, 0x9080, 0x3388, 0x200d, 0x918c, 0xff00,
-	0x810f, 0x9006, 0x0005, 0x9080, 0x3388, 0x200d, 0x918c, 0x00ff,
-	0x0005, 0x00d6, 0x2069, 0x0140, 0x2001, 0x1818, 0x2003, 0x00ef,
-	0x20a9, 0x0010, 0x9006, 0x6852, 0x6856, 0x1f04, 0x2674, 0x00de,
-	0x0005, 0x0006, 0x00d6, 0x0026, 0x2069, 0x0140, 0x2001, 0x1818,
-	0x2102, 0x8114, 0x8214, 0x8214, 0x8214, 0x20a9, 0x0010, 0x6853,
-	0x0000, 0x9006, 0x82ff, 0x1128, 0x9184, 0x000f, 0x9080, 0xe77e,
-	0x2005, 0x6856, 0x8211, 0x1f04, 0x2689, 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, 0x26b9, 0x680f, 0x0000, 0x000e, 0x001e,
-	0x002e, 0x00de, 0x015e, 0x0005, 0x080c, 0x56f5, 0xd0c4, 0x0150,
-	0xd0a4, 0x0140, 0x9006, 0x0046, 0x2020, 0x2009, 0x002e, 0x080c,
-	0xe316, 0x004e, 0x0005, 0x00f6, 0x0016, 0x0026, 0x2079, 0x0140,
-	0x78c4, 0xd0dc, 0x0904, 0x2730, 0x080c, 0x29ac, 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,
-	0x9181, 0x928c, 0xff00, 0x0110, 0x2011, 0x00ff, 0x2200, 0x8007,
-	0x9085, 0x004c, 0x78c2, 0x2009, 0x0138, 0x220a, 0x080c, 0x74ec,
-	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, 0x278e,
-	0x27ac, 0x27d0, 0x27d2, 0x27fb, 0x27fd, 0x27ff, 0x2001, 0x0001,
-	0x080c, 0x25d5, 0x080c, 0x29fa, 0x2001, 0x1991, 0x2003, 0x0000,
-	0x7828, 0x9084, 0xe1d7, 0x782a, 0x9006, 0x20a9, 0x0009, 0x080c,
-	0x29c8, 0x2001, 0x198f, 0x2003, 0x0006, 0x2009, 0x001e, 0x2011,
-	0x2800, 0x080c, 0x871b, 0x0005, 0x2009, 0x1994, 0x200b, 0x0000,
-	0x2001, 0x1999, 0x2003, 0x0036, 0x2001, 0x1998, 0x2003, 0x002a,
-	0x2001, 0x1991, 0x2003, 0x0001, 0x9006, 0x080c, 0x295d, 0x2001,
-	0xffff, 0x20a9, 0x0009, 0x080c, 0x29c8, 0x2001, 0x198f, 0x2003,
-	0x0006, 0x2009, 0x001e, 0x2011, 0x2800, 0x080c, 0x871b, 0x0005,
-	0x080c, 0x0d7d, 0x2001, 0x1999, 0x2003, 0x0036, 0x2001, 0x1991,
-	0x2003, 0x0003, 0x7a38, 0x9294, 0x0005, 0x9296, 0x0004, 0x0110,
-	0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x295d, 0x2001, 0x1995,
-	0x2003, 0x0000, 0x2001, 0xffff, 0x20a9, 0x0009, 0x080c, 0x29c8,
-	0x2001, 0x198f, 0x2003, 0x0006, 0x2009, 0x001e, 0x2011, 0x2800,
-	0x080c, 0x871b, 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, 0x2822, 0x2842, 0x2882, 0x28b2, 0x28d6,
-	0x28e6, 0x28e8, 0x080c, 0x29bc, 0x11b0, 0x7850, 0x9084, 0xefff,
-	0x7852, 0x2009, 0x1997, 0x2104, 0x7a38, 0x9294, 0x0005, 0x9296,
-	0x0004, 0x0110, 0xc08d, 0x0008, 0xc085, 0x200a, 0x2001, 0x198f,
-	0x2003, 0x0001, 0x0030, 0x080c, 0x290c, 0x2001, 0xffff, 0x080c,
-	0x279d, 0x0005, 0x080c, 0x28ea, 0x05e0, 0x2009, 0x1998, 0x2104,
-	0x8001, 0x200a, 0x080c, 0x29bc, 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, 0x28f2, 0x00c0, 0x200b,
-	0x0000, 0x7a38, 0x9294, 0x0006, 0x9296, 0x0004, 0x0110, 0x9006,
-	0x0010, 0x2001, 0x0001, 0x080c, 0x297a, 0x2001, 0x1991, 0x2003,
-	0x0002, 0x0028, 0x2001, 0x198f, 0x2003, 0x0003, 0x0010, 0x080c,
-	0x27bf, 0x0005, 0x080c, 0x28ea, 0x0560, 0x2009, 0x1998, 0x2104,
-	0x8001, 0x200a, 0x080c, 0x29bc, 0x1168, 0x7850, 0x9084, 0xefff,
-	0x7852, 0x2001, 0x198f, 0x2003, 0x0003, 0x2001, 0x1990, 0x2003,
-	0x0000, 0x00b8, 0x2009, 0x1998, 0x2104, 0x9005, 0x1118, 0x080c,
-	0x292f, 0x0010, 0x080c, 0x28ff, 0x080c, 0x28f2, 0x2009, 0x1994,
-	0x200b, 0x0000, 0x2001, 0x1991, 0x2003, 0x0001, 0x080c, 0x27bf,
-	0x0000, 0x0005, 0x04b9, 0x0508, 0x080c, 0x29bc, 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, 0x27ea, 0x0005, 0x0099, 0x0168,
-	0x080c, 0x29bc, 0x1138, 0x7850, 0x9084, 0xefff, 0x7852, 0x080c,
-	0x27d6, 0x0018, 0x0079, 0x080c, 0x27ea, 0x0005, 0x080c, 0x0d7d,
-	0x080c, 0x0d7d, 0x2009, 0x1999, 0x2104, 0x8001, 0x200a, 0x090c,
-	0x294b, 0x0005, 0x7a38, 0x9294, 0x0005, 0x9296, 0x0005, 0x0110,
-	0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x297a, 0x0005, 0x7a38,
-	0x9294, 0x0006, 0x9296, 0x0006, 0x0110, 0x9006, 0x0010, 0x2001,
-	0x0001, 0x080c, 0x295d, 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, 0x297a, 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, 0x2951, 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, 0x2a2f, 0xd09c, 0x1110, 0x1f04, 0x29bf, 0x015e, 0x0005,
-	0x0126, 0x0016, 0x0006, 0x2091, 0x8000, 0x080c, 0x2aa6, 0x080c,
-	0x2ad9, 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, 0x29ec, 0x080c, 0x873d,
-	0x1f04, 0x29ec, 0x7850, 0x9085, 0x1000, 0x7852, 0x000e, 0x001e,
-	0x012e, 0x0005, 0x080c, 0x2ad9, 0x0005, 0x0006, 0x0156, 0x00f6,
-	0x2079, 0x0100, 0x20a9, 0x000a, 0x7854, 0xd0ac, 0x1100, 0x7854,
-	0xd08c, 0x1110, 0x1f04, 0x2a07, 0x00fe, 0x015e, 0x000e, 0x0005,
-	0x1d04, 0x2a10, 0x080c, 0x873d, 0x1f04, 0x2a10, 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, 0x7506, 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, 0x7506, 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, 0x2a10, 0x6050, 0x9085,
-	0x0400, 0x9084, 0xff9f, 0x6052, 0x20a9, 0x0005, 0x080c, 0x2a10,
-	0x6054, 0xd0bc, 0x090c, 0x0d7d, 0x20a9, 0x0005, 0x080c, 0x2a10,
-	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, 0x2fdf, 0x2fdf, 0x2be3, 0x2be3, 0x2bef,
-	0x2bef, 0x2bfb, 0x2bfb, 0x2c09, 0x2c09, 0x2c15, 0x2c15, 0x2c23,
-	0x2c23, 0x2c31, 0x2c31, 0x2c43, 0x2c43, 0x2c4f, 0x2c4f, 0x2c5d,
-	0x2c5d, 0x2c7b, 0x2c7b, 0x2c9b, 0x2c9b, 0x2c6b, 0x2c6b, 0x2c8b,
-	0x2c8b, 0x2ca9, 0x2ca9, 0x2c41, 0x2c41, 0x2c41, 0x2c41, 0x2c41,
-	0x2c41, 0x2c41, 0x2c41, 0x2c41, 0x2c41, 0x2c41, 0x2c41, 0x2c41,
-	0x2c41, 0x2c41, 0x2c41, 0x2c41, 0x2c41, 0x2c41, 0x2c41, 0x2c41,
-	0x2c41, 0x2c41, 0x2c41, 0x2c41, 0x2c41, 0x2c41, 0x2c41, 0x2c41,
-	0x2c41, 0x2c41, 0x2c41, 0x2cbb, 0x2cbb, 0x2cc7, 0x2cc7, 0x2cd5,
-	0x2cd5, 0x2ce3, 0x2ce3, 0x2cf3, 0x2cf3, 0x2d01, 0x2d01, 0x2d11,
-	0x2d11, 0x2d21, 0x2d21, 0x2d33, 0x2d33, 0x2d41, 0x2d41, 0x2d51,
-	0x2d51, 0x2d73, 0x2d73, 0x2d97, 0x2d97, 0x2d61, 0x2d61, 0x2d85,
-	0x2d85, 0x2da7, 0x2da7, 0x2c41, 0x2c41, 0x2c41, 0x2c41, 0x2c41,
-	0x2c41, 0x2c41, 0x2c41, 0x2c41, 0x2c41, 0x2c41, 0x2c41, 0x2c41,
-	0x2c41, 0x2c41, 0x2c41, 0x2c41, 0x2c41, 0x2c41, 0x2c41, 0x2c41,
-	0x2c41, 0x2c41, 0x2c41, 0x2c41, 0x2c41, 0x2c41, 0x2c41, 0x2c41,
-	0x2c41, 0x2c41, 0x2c41, 0x2dbb, 0x2dbb, 0x2dc7, 0x2dc7, 0x2dd5,
-	0x2dd5, 0x2de3, 0x2de3, 0x2df3, 0x2df3, 0x2e01, 0x2e01, 0x2e11,
-	0x2e11, 0x2e21, 0x2e21, 0x2e33, 0x2e33, 0x2e41, 0x2e41, 0x2e51,
-	0x2e51, 0x2e61, 0x2e61, 0x2e73, 0x2e73, 0x2e83, 0x2e83, 0x2e95,
-	0x2e95, 0x2ea7, 0x2ea7, 0x2c41, 0x2c41, 0x2c41, 0x2c41, 0x2c41,
-	0x2c41, 0x2c41, 0x2c41, 0x2c41, 0x2c41, 0x2c41, 0x2c41, 0x2c41,
-	0x2c41, 0x2c41, 0x2c41, 0x2c41, 0x2c41, 0x2c41, 0x2c41, 0x2c41,
-	0x2c41, 0x2c41, 0x2c41, 0x2c41, 0x2c41, 0x2c41, 0x2c41, 0x2c41,
-	0x2c41, 0x2c41, 0x2c41, 0x2ebb, 0x2ebb, 0x2ec9, 0x2ec9, 0x2ed9,
-	0x2ed9, 0x2ee9, 0x2ee9, 0x2efb, 0x2efb, 0x2f0b, 0x2f0b, 0x2f1d,
-	0x2f1d, 0x2f2f, 0x2f2f, 0x2f43, 0x2f43, 0x2f53, 0x2f53, 0x2f65,
-	0x2f65, 0x2f77, 0x2f77, 0x2f8b, 0x2f8b, 0x2f9c, 0x2f9c, 0x2faf,
-	0x2faf, 0x2fc2, 0x2fc2, 0x2c41, 0x2c41, 0x2c41, 0x2c41, 0x2c41,
-	0x2c41, 0x2c41, 0x2c41, 0x2c41, 0x2c41, 0x2c41, 0x2c41, 0x2c41,
-	0x2c41, 0x2c41, 0x2c41, 0x2c41, 0x2c41, 0x2c41, 0x2c41, 0x2c41,
-	0x2c41, 0x2c41, 0x2c41, 0x2c41, 0x2c41, 0x2c41, 0x2c41, 0x2c41,
-	0x2c41, 0x2c41, 0x2c41, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
-	0x0136, 0x0146, 0x0156, 0x080c, 0x2279, 0x0804, 0x2fd7, 0x0106,
-	0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
-	0x20a3, 0x0804, 0x2fd7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
-	0x0136, 0x0146, 0x0156, 0x080c, 0x20a3, 0x080c, 0x2279, 0x0804,
-	0x2fd7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
-	0x0156, 0x080c, 0x20cd, 0x0804, 0x2fd7, 0x0106, 0x0006, 0x0126,
-	0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2279, 0x080c,
-	0x20cd, 0x0804, 0x2fd7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
-	0x0136, 0x0146, 0x0156, 0x080c, 0x20a3, 0x080c, 0x20cd, 0x0804,
-	0x2fd7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
-	0x0156, 0x080c, 0x20a3, 0x080c, 0x2279, 0x080c, 0x20cd, 0x0804,
-	0x2fd7, 0xa001, 0x0cf0, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
-	0x0136, 0x0146, 0x0156, 0x080c, 0x13bb, 0x0804, 0x2fd7, 0x0106,
-	0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
-	0x2279, 0x080c, 0x13bb, 0x0804, 0x2fd7, 0x0106, 0x0006, 0x0126,
-	0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x20a3, 0x080c,
-	0x13bb, 0x0804, 0x2fd7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
-	0x0136, 0x0146, 0x0156, 0x080c, 0x2279, 0x080c, 0x13bb, 0x080c,
-	0x20cd, 0x0804, 0x2fd7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
-	0x0136, 0x0146, 0x0156, 0x080c, 0x20a3, 0x080c, 0x2279, 0x080c,
-	0x13bb, 0x0804, 0x2fd7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
-	0x0136, 0x0146, 0x0156, 0x080c, 0x20a3, 0x080c, 0x13bb, 0x080c,
-	0x20cd, 0x0804, 0x2fd7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
-	0x0136, 0x0146, 0x0156, 0x080c, 0x13bb, 0x080c, 0x20cd, 0x0804,
-	0x2fd7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
-	0x0156, 0x080c, 0x20a3, 0x080c, 0x2279, 0x080c, 0x13bb, 0x080c,
-	0x20cd, 0x0804, 0x2fd7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
-	0x0136, 0x0146, 0x0156, 0x080c, 0x2733, 0x0804, 0x2fd7, 0x0106,
-	0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
-	0x2733, 0x080c, 0x2279, 0x0804, 0x2fd7, 0x0106, 0x0006, 0x0126,
-	0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2733, 0x080c,
-	0x20a3, 0x0804, 0x2fd7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
-	0x0136, 0x0146, 0x0156, 0x080c, 0x2733, 0x080c, 0x20a3, 0x080c,
-	0x2279, 0x0804, 0x2fd7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
-	0x0136, 0x0146, 0x0156, 0x080c, 0x2733, 0x080c, 0x20cd, 0x0804,
-	0x2fd7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
-	0x0156, 0x080c, 0x2733, 0x080c, 0x2279, 0x080c, 0x20cd, 0x0804,
-	0x2fd7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
-	0x0156, 0x080c, 0x2733, 0x080c, 0x20a3, 0x080c, 0x20cd, 0x0804,
-	0x2fd7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
-	0x0156, 0x080c, 0x2733, 0x080c, 0x20a3, 0x080c, 0x2279, 0x080c,
-	0x20cd, 0x0804, 0x2fd7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
-	0x0136, 0x0146, 0x0156, 0x080c, 0x2733, 0x080c, 0x13bb, 0x0804,
-	0x2fd7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
-	0x0156, 0x080c, 0x2733, 0x080c, 0x2279, 0x080c, 0x13bb, 0x0804,
-	0x2fd7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
-	0x0156, 0x080c, 0x2733, 0x080c, 0x20a3, 0x080c, 0x13bb, 0x0804,
-	0x2fd7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
-	0x0156, 0x080c, 0x2733, 0x080c, 0x2279, 0x080c, 0x13bb, 0x080c,
-	0x20cd, 0x0804, 0x2fd7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
-	0x0136, 0x0146, 0x0156, 0x080c, 0x2733, 0x080c, 0x20a3, 0x080c,
-	0x2279, 0x080c, 0x13bb, 0x0804, 0x2fd7, 0x0106, 0x0006, 0x0126,
-	0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2733, 0x080c,
-	0x20a3, 0x080c, 0x13bb, 0x080c, 0x20cd, 0x0804, 0x2fd7, 0x0106,
-	0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
-	0x2733, 0x080c, 0x13bb, 0x080c, 0x20cd, 0x0804, 0x2fd7, 0x0106,
-	0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
-	0x2733, 0x080c, 0x20a3, 0x080c, 0x2279, 0x080c, 0x13bb, 0x080c,
-	0x20cd, 0x0804, 0x2fd7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
-	0x0136, 0x0146, 0x0156, 0x080c, 0xa8ff, 0x0804, 0x2fd7, 0x0106,
-	0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
-	0xa8ff, 0x080c, 0x2279, 0x0804, 0x2fd7, 0x0106, 0x0006, 0x0126,
-	0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x20a3, 0x080c,
-	0xa8ff, 0x0804, 0x2fd7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
-	0x0136, 0x0146, 0x0156, 0x080c, 0x20a3, 0x080c, 0xa8ff, 0x080c,
-	0x2279, 0x0804, 0x2fd7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
-	0x0136, 0x0146, 0x0156, 0x080c, 0xa8ff, 0x080c, 0x20cd, 0x0804,
-	0x2fd7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
-	0x0156, 0x080c, 0xa8ff, 0x080c, 0x2279, 0x080c, 0x20cd, 0x0804,
-	0x2fd7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
-	0x0156, 0x080c, 0x20a3, 0x080c, 0xa8ff, 0x080c, 0x20cd, 0x0804,
-	0x2fd7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
-	0x0156, 0x080c, 0x20a3, 0x080c, 0xa8ff, 0x080c, 0x2279, 0x080c,
-	0x20cd, 0x0804, 0x2fd7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
-	0x0136, 0x0146, 0x0156, 0x080c, 0xa8ff, 0x080c, 0x13bb, 0x0804,
-	0x2fd7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
-	0x0156, 0x080c, 0xa8ff, 0x080c, 0x2279, 0x080c, 0x13bb, 0x0804,
-	0x2fd7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
-	0x0156, 0x080c, 0x20a3, 0x080c, 0xa8ff, 0x080c, 0x13bb, 0x0804,
-	0x2fd7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
-	0x0156, 0x080c, 0x20a3, 0x080c, 0xa8ff, 0x080c, 0x2279, 0x080c,
-	0x13bb, 0x0804, 0x2fd7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
-	0x0136, 0x0146, 0x0156, 0x080c, 0xa8ff, 0x080c, 0x13bb, 0x080c,
-	0x20cd, 0x0804, 0x2fd7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
-	0x0136, 0x0146, 0x0156, 0x080c, 0xa8ff, 0x080c, 0x2279, 0x080c,
-	0x13bb, 0x080c, 0x20cd, 0x0804, 0x2fd7, 0x0106, 0x0006, 0x0126,
-	0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x20a3, 0x080c,
-	0xa8ff, 0x080c, 0x13bb, 0x080c, 0x20cd, 0x0804, 0x2fd7, 0x0106,
-	0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
-	0x20a3, 0x080c, 0xa8ff, 0x080c, 0x2279, 0x080c, 0x13bb, 0x080c,
-	0x20cd, 0x0804, 0x2fd7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
-	0x0136, 0x0146, 0x0156, 0x080c, 0x2733, 0x080c, 0xa8ff, 0x0804,
-	0x2fd7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
-	0x0156, 0x080c, 0x2733, 0x080c, 0xa8ff, 0x080c, 0x2279, 0x0804,
-	0x2fd7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
-	0x0156, 0x080c, 0x2733, 0x080c, 0x20a3, 0x080c, 0xa8ff, 0x0804,
-	0x2fd7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
-	0x0156, 0x080c, 0x2733, 0x080c, 0x20a3, 0x080c, 0xa8ff, 0x080c,
-	0x2279, 0x0804, 0x2fd7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
-	0x0136, 0x0146, 0x0156, 0x080c, 0x2733, 0x080c, 0xa8ff, 0x080c,
-	0x20cd, 0x0804, 0x2fd7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
-	0x0136, 0x0146, 0x0156, 0x080c, 0x2733, 0x080c, 0xa8ff, 0x080c,
-	0x2279, 0x080c, 0x20cd, 0x0804, 0x2fd7, 0x0106, 0x0006, 0x0126,
-	0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2733, 0x080c,
-	0x20a3, 0x080c, 0xa8ff, 0x080c, 0x20cd, 0x0804, 0x2fd7, 0x0106,
-	0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
-	0x2733, 0x080c, 0x20a3, 0x080c, 0xa8ff, 0x080c, 0x2279, 0x080c,
-	0x20cd, 0x0804, 0x2fd7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
-	0x0136, 0x0146, 0x0156, 0x080c, 0x2733, 0x080c, 0xa8ff, 0x080c,
-	0x13bb, 0x0804, 0x2fd7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
-	0x0136, 0x0146, 0x0156, 0x080c, 0x2733, 0x080c, 0xa8ff, 0x080c,
-	0x2279, 0x080c, 0x13bb, 0x0804, 0x2fd7, 0x0106, 0x0006, 0x0126,
-	0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2733, 0x080c,
-	0x20a3, 0x080c, 0xa8ff, 0x080c, 0x13bb, 0x0804, 0x2fd7, 0x0106,
-	0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
-	0x2733, 0x080c, 0x20a3, 0x080c, 0xa8ff, 0x080c, 0x2279, 0x080c,
-	0x13bb, 0x0804, 0x2fd7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
-	0x0136, 0x0146, 0x0156, 0x080c, 0x2733, 0x080c, 0xa8ff, 0x080c,
-	0x13bb, 0x080c, 0x20cd, 0x04d8, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2733, 0x080c, 0xa8ff,
-	0x080c, 0x2279, 0x080c, 0x13bb, 0x080c, 0x20cd, 0x0440, 0x0106,
-	0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
-	0x2733, 0x080c, 0x20a3, 0x080c, 0x13bb, 0x080c, 0xa8ff, 0x080c,
-	0x20cd, 0x00a8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
-	0x0146, 0x0156, 0x080c, 0x2733, 0x080c, 0x20a3, 0x080c, 0xa8ff,
-	0x080c, 0x2279, 0x080c, 0x13bb, 0x080c, 0x20cd, 0x0000, 0x015e,
-	0x014e, 0x013e, 0x01de, 0x01ce, 0x012e, 0x000e, 0x010e, 0x000d,
-	0x00b6, 0x00c6, 0x0026, 0x0046, 0x9026, 0x080c, 0x6a4c, 0x1904,
-	0x30f0, 0x72dc, 0x2001, 0x197b, 0x2004, 0x9005, 0x1110, 0xd29c,
-	0x0148, 0xd284, 0x1138, 0xd2bc, 0x1904, 0x30f0, 0x080c, 0x30f5,
-	0x0804, 0x30f0, 0xd2cc, 0x1904, 0x30f0, 0x080c, 0x74ec, 0x1120,
-	0x70af, 0xffff, 0x0804, 0x30f0, 0xd294, 0x0120, 0x70af, 0xffff,
-	0x0804, 0x30f0, 0x080c, 0x3377, 0x0160, 0x080c, 0xcf84, 0x0128,
-	0x2001, 0x1818, 0x203c, 0x0804, 0x307d, 0x70af, 0xffff, 0x0804,
-	0x30f0, 0x2001, 0x1818, 0x203c, 0x7294, 0xd284, 0x0904, 0x307d,
-	0xd28c, 0x1904, 0x307d, 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, 0x2630, 0x080c, 0x65e3, 0x1538, 0x9006,
-	0xb8bb, 0x0520, 0xb8ac, 0x9005, 0x0148, 0x00c6, 0x2060, 0x080c,
-	0x8ba9, 0x00ce, 0x090c, 0x8f4f, 0xb8af, 0x0000, 0x080c, 0x6a8e,
-	0x1168, 0x7030, 0xd08c, 0x0130, 0xb800, 0xd0bc, 0x0138, 0x080c,
-	0x6937, 0x0120, 0x080c, 0x310e, 0x0148, 0x0028, 0x080c, 0x325a,
-	0x080c, 0x313a, 0x0118, 0x8318, 0x0804, 0x302a, 0x73ae, 0x0010,
-	0x70af, 0xffff, 0x003e, 0x0804, 0x30f0, 0x9780, 0x3388, 0x203d,
-	0x97bc, 0xff00, 0x873f, 0x2041, 0x007e, 0x70ac, 0x9096, 0xffff,
-	0x1118, 0x900e, 0x28a8, 0x0050, 0x9812, 0x0220, 0x2008, 0x9802,
-	0x20a8, 0x0020, 0x70af, 0xffff, 0x0804, 0x30f0, 0x2700, 0x0156,
-	0x0016, 0x9106, 0x0904, 0x30e5, 0xc484, 0x080c, 0x6644, 0x0148,
-	0x080c, 0xcf84, 0x1904, 0x30e5, 0x080c, 0x65e3, 0x1904, 0x30ed,
-	0x0008, 0xc485, 0xb8bb, 0x0520, 0xb8ac, 0x9005, 0x0148, 0x00c6,
-	0x2060, 0x080c, 0x8ba9, 0x00ce, 0x090c, 0x8f4f, 0xb8af, 0x0000,
-	0x080c, 0x6a8e, 0x1130, 0x7030, 0xd08c, 0x01f8, 0xb800, 0xd0bc,
-	0x11e0, 0x7294, 0xd28c, 0x0180, 0x080c, 0x6a8e, 0x9082, 0x0006,
-	0x02e0, 0xd484, 0x1118, 0x080c, 0x6608, 0x0028, 0x080c, 0x32ed,
-	0x01a0, 0x080c, 0x3318, 0x0088, 0x080c, 0x325a, 0x080c, 0xcf84,
-	0x1160, 0x080c, 0x313a, 0x0188, 0x0040, 0x080c, 0xcf84, 0x1118,
-	0x080c, 0x32ed, 0x0110, 0x0451, 0x0140, 0x001e, 0x8108, 0x015e,
-	0x1f04, 0x3096, 0x70af, 0xffff, 0x0018, 0x001e, 0x015e, 0x71ae,
-	0x004e, 0x002e, 0x00ce, 0x00be, 0x0005, 0x00c6, 0x0016, 0x70af,
-	0x0001, 0x2009, 0x007e, 0x080c, 0x65e3, 0x1168, 0xb813, 0x00ff,
-	0xb817, 0xfffe, 0x080c, 0x325a, 0x04a9, 0x0128, 0x70dc, 0xc0bd,
-	0x70de, 0x080c, 0xccd1, 0x001e, 0x00ce, 0x0005, 0x0016, 0x0076,
-	0x00d6, 0x00c6, 0x2001, 0x184c, 0x2004, 0x9084, 0x00ff, 0xb842,
-	0x080c, 0xac60, 0x01d0, 0x2b00, 0x6012, 0x080c, 0xccfe, 0x6023,
-	0x0001, 0x9006, 0x080c, 0x6580, 0x2001, 0x0000, 0x080c, 0x6594,
-	0x0126, 0x2091, 0x8000, 0x70a8, 0x8000, 0x70aa, 0x012e, 0x2009,
-	0x0004, 0x080c, 0xac8d, 0x9085, 0x0001, 0x00ce, 0x00de, 0x007e,
-	0x001e, 0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6, 0x2001, 0x184c,
-	0x2004, 0x9084, 0x00ff, 0xb842, 0x080c, 0xac60, 0x0548, 0x2b00,
-	0x6012, 0xb800, 0xc0c4, 0xb802, 0xb8a0, 0x9086, 0x007e, 0x0140,
-	0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, 0x1110, 0x080c, 0x320f,
-	0x080c, 0xccfe, 0x6023, 0x0001, 0x9006, 0x080c, 0x6580, 0x2001,
-	0x0002, 0x080c, 0x6594, 0x0126, 0x2091, 0x8000, 0x70a8, 0x8000,
-	0x70aa, 0x012e, 0x2009, 0x0002, 0x080c, 0xac8d, 0x9085, 0x0001,
-	0x00ce, 0x00de, 0x007e, 0x001e, 0x0005, 0x00b6, 0x00c6, 0x0026,
-	0x2009, 0x0080, 0x080c, 0x65e3, 0x1140, 0xb813, 0x00ff, 0xb817,
-	0xfffc, 0x0039, 0x0110, 0x70e3, 0xffff, 0x002e, 0x00ce, 0x00be,
-	0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6, 0x080c, 0xab9a, 0x01d0,
-	0x2b00, 0x6012, 0x080c, 0xccfe, 0x6023, 0x0001, 0x9006, 0x080c,
-	0x6580, 0x2001, 0x0002, 0x080c, 0x6594, 0x0126, 0x2091, 0x8000,
-	0x70e4, 0x8000, 0x70e6, 0x012e, 0x2009, 0x0002, 0x080c, 0xac8d,
-	0x9085, 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e, 0x0005, 0x00c6,
-	0x00d6, 0x0126, 0x2091, 0x8000, 0x2009, 0x007f, 0x080c, 0x65e3,
-	0x11b8, 0xb813, 0x00ff, 0xb817, 0xfffd, 0xb8d7, 0x0004, 0x080c,
-	0xab9a, 0x0170, 0x2b00, 0x6012, 0x6316, 0x6023, 0x0001, 0x620a,
-	0x080c, 0xccfe, 0x2009, 0x0022, 0x080c, 0xac8d, 0x9085, 0x0001,
-	0x012e, 0x00de, 0x00ce, 0x0005, 0x00e6, 0x00c6, 0x0066, 0x0036,
-	0x0026, 0x00b6, 0x21f0, 0x080c, 0xa899, 0x0106, 0x080c, 0x93d1,
-	0x080c, 0x9342, 0x080c, 0xa7ea, 0x080c, 0xbb2c, 0x010e, 0x090c,
-	0xa8b5, 0x3e08, 0x2130, 0x81ff, 0x0120, 0x20a9, 0x007e, 0x900e,
-	0x0018, 0x20a9, 0x007f, 0x900e, 0x0016, 0x080c, 0x6644, 0x1140,
-	0x9686, 0x0002, 0x1118, 0xb800, 0xd0bc, 0x1110, 0x080c, 0x605e,
-	0x001e, 0x8108, 0x1f04, 0x31f4, 0x9686, 0x0001, 0x190c, 0x334b,
-	0x00be, 0x002e, 0x003e, 0x006e, 0x00ce, 0x00ee, 0x0005, 0x00e6,
-	0x00c6, 0x0046, 0x0036, 0x0026, 0x0016, 0x00b6, 0x080c, 0xa899,
-	0x0106, 0x6210, 0x2258, 0xbaa0, 0x0026, 0x2019, 0x0029, 0x080c,
-	0x93c6, 0x0076, 0x2039, 0x0000, 0x080c, 0x928f, 0x2c08, 0x080c,
-	0xe038, 0x007e, 0x001e, 0x010e, 0x090c, 0xa8b5, 0xba10, 0xbb14,
-	0xbc84, 0x080c, 0x605e, 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, 0xa899, 0x0106, 0x81ff, 0x1118, 0x20a9, 0x0001, 0x0078,
-	0x080c, 0x56f5, 0xd0c4, 0x0140, 0xd0a4, 0x0130, 0x9006, 0x2020,
-	0x2009, 0x002d, 0x080c, 0xe316, 0x20a9, 0x0800, 0x9016, 0x0026,
-	0x928e, 0x007e, 0x0904, 0x32c9, 0x928e, 0x007f, 0x0904, 0x32c9,
-	0x928e, 0x0080, 0x05f0, 0x9288, 0x1000, 0x210c, 0x81ff, 0x05c8,
-	0x8fff, 0x1150, 0x2001, 0x198d, 0x0006, 0x2003, 0x0001, 0x080c,
-	0x32da, 0x000e, 0x2003, 0x0000, 0x00b6, 0x00c6, 0x2158, 0x2001,
-	0x0001, 0x080c, 0x6a58, 0x00ce, 0x00be, 0x2019, 0x0029, 0x080c,
-	0x93c6, 0x0076, 0x2039, 0x0000, 0x080c, 0x928f, 0x00b6, 0x00c6,
-	0x0026, 0x2158, 0xba04, 0x9294, 0x00ff, 0x9286, 0x0006, 0x1118,
-	0xb807, 0x0404, 0x0028, 0x2001, 0x0004, 0x8007, 0x9215, 0xba06,
-	0x002e, 0x00ce, 0x00be, 0x0016, 0x2c08, 0x080c, 0xe038, 0x001e,
-	0x007e, 0x002e, 0x8210, 0x1f04, 0x327f, 0x010e, 0x090c, 0xa8b5,
-	0x015e, 0x001e, 0x002e, 0x003e, 0x004e, 0x00be, 0x00ce, 0x00ee,
-	0x00fe, 0x0005, 0x0046, 0x0026, 0x0016, 0x080c, 0x56f5, 0xd0c4,
-	0x0140, 0xd0a4, 0x0130, 0x9006, 0x2220, 0x2009, 0x0029, 0x080c,
-	0xe316, 0x001e, 0x002e, 0x004e, 0x0005, 0x0016, 0x0026, 0x0036,
-	0x00c6, 0x7294, 0x82ff, 0x01e8, 0x080c, 0x6a86, 0x11d0, 0x2100,
-	0x080c, 0x2663, 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, 0xa899, 0x0106,
-	0x0036, 0x2019, 0x0029, 0x00c1, 0x003e, 0x010e, 0x090c, 0xa8b5,
-	0x9180, 0x1000, 0x2004, 0x9065, 0x0158, 0x0016, 0x00c6, 0x2061,
-	0x1b31, 0x001e, 0x6112, 0x080c, 0x320f, 0x001e, 0x080c, 0x6608,
-	0x012e, 0x00ce, 0x001e, 0x0005, 0x0016, 0x0026, 0x2110, 0x080c,
-	0xa37f, 0x080c, 0xe67d, 0x002e, 0x001e, 0x0005, 0x2001, 0x1837,
-	0x2004, 0xd0cc, 0x0005, 0x00c6, 0x00b6, 0x080c, 0x74ec, 0x1118,
-	0x20a9, 0x0800, 0x0010, 0x20a9, 0x0782, 0x080c, 0x74ec, 0x1110,
-	0x900e, 0x0010, 0x2009, 0x007e, 0x9180, 0x1000, 0x2004, 0x905d,
-	0x0130, 0x86ff, 0x0110, 0xb800, 0xd0bc, 0x090c, 0x6608, 0x8108,
-	0x1f04, 0x335c, 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,
+	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,
+	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,
+	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,
+	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,
+	0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156,
+	0x080c, 0x2764, 0x080c, 0x13bb, 0x080c, 0x20fe, 0x0804, 0x3008,
+	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,
+	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,
+	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,
+	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,
+	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,
+	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,
+	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,
+	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,
+	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,
+	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,
+	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,
+	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,
+	0x007e, 0x001e, 0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6, 0x2001,
+	0x184c, 0x2004, 0x9084, 0x00ff, 0xb842, 0x080c, 0xad20, 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,
+	0x0001, 0x00ce, 0x00de, 0x007e, 0x001e, 0x0005, 0x00b6, 0x00c6,
+	0x0026, 0x2009, 0x0080, 0x080c, 0x6632, 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,
+	0x8000, 0x70e4, 0x8000, 0x70e6, 0x012e, 0x2009, 0x0002, 0x080c,
+	0xad4d, 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,
+	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,
+	0x1140, 0x9686, 0x0002, 0x1118, 0xb800, 0xd0bc, 0x1110, 0x080c,
+	0x60ac, 0x001e, 0x8108, 0x1f04, 0x3225, 0x9686, 0x0001, 0x190c,
+	0x337c, 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,
+	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,
+	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,
+	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,
+	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,
+	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,
+	0x1110, 0x900e, 0x0010, 0x2009, 0x007e, 0x9180, 0x1000, 0x2004,
+	0x905d, 0x0130, 0x86ff, 0x0110, 0xb800, 0xd0bc, 0x090c, 0x6657,
+	0x8108, 0x1f04, 0x338d, 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,
-	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, 0x34b7, 0x34b8, 0x34cb, 0x34df, 0x0005,
-	0x1004, 0x34c8, 0x0e04, 0x34c8, 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, 0x35b3,
-	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, 0x35b0, 0x61d0, 0x0804, 0x3545, 0x3587, 0x35bf, 0x35b0,
-	0x35c9, 0x35d3, 0x35d9, 0x35dd, 0x35ed, 0x35f1, 0x3607, 0x360d,
-	0x3613, 0x361e, 0x3629, 0x3638, 0x3647, 0x3655, 0x366c, 0x3687,
-	0x35b0, 0x3730, 0x376e, 0x3813, 0x3824, 0x3847, 0x35b0, 0x35b0,
-	0x35b0, 0x387f, 0x389f, 0x38a8, 0x38d4, 0x38da, 0x35b0, 0x3920,
-	0x35b0, 0x35b0, 0x35b0, 0x35b0, 0x35b0, 0x392b, 0x3934, 0x393c,
-	0x393e, 0x35b0, 0x35b0, 0x35b0, 0x35b0, 0x35b0, 0x35b0, 0x396e,
-	0x35b0, 0x35b0, 0x35b0, 0x35b0, 0x35b0, 0x398b, 0x39ef, 0x35b0,
-	0x35b0, 0x35b0, 0x35b0, 0x35b0, 0x35b0, 0x0002, 0x3a19, 0x3a1c,
-	0x3a7b, 0x3a94, 0x3ac4, 0x3d66, 0x35b0, 0x52c6, 0x35b0, 0x35b0,
-	0x35b0, 0x35b0, 0x35b0, 0x35b0, 0x35b0, 0x35b0, 0x3607, 0x360d,
-	0x4265, 0x5719, 0x4283, 0x5355, 0x53a6, 0x54a9, 0x35b0, 0x550b,
-	0x5547, 0x5578, 0x5684, 0x55a5, 0x5604, 0x35b0, 0x4287, 0x443c,
-	0x4452, 0x4477, 0x44dc, 0x4550, 0x4570, 0x45e7, 0x4643, 0x469f,
-	0x46a2, 0x46c7, 0x4737, 0x47a1, 0x47a9, 0x48db, 0x4a53, 0x4a87,
-	0x4ceb, 0x35b0, 0x4d09, 0x4dae, 0x4e90, 0x4eea, 0x35b0, 0x4f9f,
-	0x35b0, 0x5005, 0x5020, 0x47a9, 0x5266, 0x714c, 0x0000, 0x2021,
-	0x4000, 0x080c, 0x4b05, 0x0126, 0x2091, 0x8000, 0x0e04, 0x3591,
-	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, 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,
-	0x4b12, 0x2039, 0x0001, 0x902e, 0x2520, 0x7b88, 0x7a8c, 0x7884,
-	0x7990, 0x0804, 0x4b15, 0x7984, 0x7888, 0x2114, 0x200a, 0x0804,
-	0x3587, 0x7984, 0x2114, 0x0804, 0x3587, 0x20e1, 0x0000, 0x2099,
-	0x0021, 0x20e9, 0x0000, 0x20a1, 0x0021, 0x20a9, 0x001f, 0x4003,
-	0x7984, 0x7a88, 0x7b8c, 0x0804, 0x3587, 0x7884, 0x2060, 0x0804,
-	0x363a, 0x2009, 0x0003, 0x2011, 0x0003, 0x2019, 0x0002, 0x789b,
-	0x0137, 0x7893, 0xffff, 0x2001, 0x188f, 0x2004, 0x9005, 0x0118,
-	0x7896, 0x0804, 0x3587, 0x7897, 0x0001, 0x0804, 0x3587, 0x2039,
-	0x0001, 0x7d98, 0x7c9c, 0x0804, 0x35c3, 0x2039, 0x0001, 0x7d98,
-	0x7c9c, 0x0804, 0x35cd, 0x79a0, 0x9182, 0x0040, 0x0210, 0x0804,
-	0x35bc, 0x2138, 0x7d98, 0x7c9c, 0x0804, 0x35c3, 0x79a0, 0x9182,
-	0x0040, 0x0210, 0x0804, 0x35bc, 0x2138, 0x7d98, 0x7c9c, 0x0804,
-	0x35cd, 0x79a0, 0x9182, 0x0040, 0x0210, 0x0804, 0x35bc, 0x21e8,
-	0x7984, 0x7888, 0x20a9, 0x0001, 0x21a0, 0x4004, 0x0804, 0x3587,
-	0x2061, 0x0800, 0xe10c, 0x9006, 0x2c15, 0x9200, 0x8c60, 0x8109,
-	0x1dd8, 0x2010, 0x9005, 0x0904, 0x3587, 0x0804, 0x35b6, 0x79a0,
-	0x9182, 0x0040, 0x0210, 0x0804, 0x35bc, 0x21e0, 0x20a9, 0x0001,
-	0x7984, 0x2198, 0x4012, 0x0804, 0x3587, 0x2069, 0x1847, 0x7884,
-	0x7990, 0x911a, 0x1a04, 0x35bc, 0x8019, 0x0904, 0x35bc, 0x684a,
-	0x6942, 0x788c, 0x6852, 0x7888, 0x6856, 0x9006, 0x685a, 0x685e,
-	0x080c, 0x7820, 0x0804, 0x3587, 0x2069, 0x1847, 0x7884, 0x7994,
-	0x911a, 0x1a04, 0x35bc, 0x8019, 0x0904, 0x35bc, 0x684e, 0x6946,
-	0x788c, 0x6862, 0x7888, 0x6866, 0x9006, 0x686a, 0x686e, 0x0126,
-	0x2091, 0x8000, 0x080c, 0x6af4, 0x012e, 0x0804, 0x3587, 0x902e,
-	0x2520, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x35b9, 0x7984,
-	0x7b88, 0x7a8c, 0x20a9, 0x0005, 0x20e9, 0x0001, 0x20a1, 0x18a6,
-	0x4101, 0x080c, 0x4ac9, 0x1120, 0x2009, 0x0002, 0x0804, 0x35b9,
-	0x2009, 0x0020, 0xa85c, 0x9080, 0x0019, 0xaf60, 0x080c, 0x4b12,
-	0x701f, 0x36ab, 0x0005, 0xa864, 0x2008, 0x9084, 0x00ff, 0x9096,
-	0x0011, 0x0168, 0x9096, 0x0019, 0x0150, 0x9096, 0x0015, 0x0138,
-	0x9096, 0x0048, 0x0120, 0x9096, 0x0029, 0x1904, 0x35b9, 0x810f,
-	0x918c, 0x00ff, 0x0904, 0x35b9, 0x7112, 0x7010, 0x8001, 0x0560,
-	0x7012, 0x080c, 0x4ac9, 0x1120, 0x2009, 0x0002, 0x0804, 0x35b9,
-	0x2009, 0x0020, 0x7068, 0x2040, 0xa28c, 0xa390, 0xa494, 0xa598,
-	0x9290, 0x0040, 0x9399, 0x0000, 0x94a1, 0x0000, 0x95a9, 0x0000,
-	0xa85c, 0x9080, 0x0019, 0xaf60, 0x080c, 0x4b12, 0x701f, 0x36e9,
-	0x0005, 0xa864, 0x9084, 0x00ff, 0x9096, 0x0002, 0x0120, 0x9096,
-	0x000a, 0x1904, 0x35b9, 0x0888, 0x7014, 0x2048, 0xa868, 0xc0fd,
-	0xa86a, 0xa864, 0x9084, 0x00ff, 0x9096, 0x0029, 0x1160, 0xc2fd,
-	0xaa7a, 0x080c, 0x61b1, 0x0150, 0x0126, 0x2091, 0x8000, 0xa87a,
-	0xa982, 0x012e, 0x0050, 0x080c, 0x64de, 0x1128, 0x7007, 0x0003,
-	0x701f, 0x3715, 0x0005, 0x080c, 0x6fd3, 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, 0x4b15,
-	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,
-	0x35b9, 0x7984, 0x080c, 0x6644, 0x1904, 0x35bc, 0x7e98, 0x9684,
-	0x3fff, 0x9082, 0x4000, 0x1a04, 0x35bc, 0x7c88, 0x7d8c, 0x080c,
-	0x687a, 0x080c, 0x6807, 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, 0x35b9, 0x0c30,
-	0x080c, 0xc453, 0x012e, 0x0904, 0x35b9, 0x0804, 0x3587, 0x900e,
-	0x2001, 0x0005, 0x080c, 0x6fd3, 0x0126, 0x2091, 0x8000, 0x080c,
-	0xcb6e, 0x080c, 0x6d9f, 0x012e, 0x0804, 0x3587, 0x00a6, 0x2950,
-	0xb198, 0x080c, 0x6644, 0x1904, 0x3800, 0xb6a4, 0x9684, 0x3fff,
-	0x9082, 0x4000, 0x16e8, 0xb49c, 0xb5a0, 0x080c, 0x687a, 0x080c,
-	0x6824, 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,
-	0xc453, 0x012e, 0x2009, 0x0003, 0x0178, 0x00e0, 0x900e, 0x2001,
-	0x0005, 0x080c, 0x6fd3, 0x0126, 0x2091, 0x8000, 0x080c, 0xcb6e,
-	0x080c, 0x6d93, 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, 0x35b9, 0x080c, 0x4ae0,
-	0x0904, 0x35bc, 0x080c, 0x670b, 0x0904, 0x35b9, 0x080c, 0x6880,
-	0x0904, 0x35b9, 0x0804, 0x4567, 0x81ff, 0x1904, 0x35b9, 0x080c,
-	0x4afc, 0x0904, 0x35bc, 0x080c, 0x690e, 0x0904, 0x35b9, 0x2019,
-	0x0005, 0x79a8, 0x080c, 0x689b, 0x0904, 0x35b9, 0x7888, 0x908a,
-	0x1000, 0x1a04, 0x35bc, 0x8003, 0x800b, 0x810b, 0x9108, 0x080c,
-	0x865f, 0x7984, 0xd184, 0x1904, 0x3587, 0x0804, 0x4567, 0x0126,
-	0x2091, 0x8000, 0x81ff, 0x0118, 0x2009, 0x0001, 0x0450, 0x2029,
-	0x07ff, 0x645c, 0x2400, 0x9506, 0x01f8, 0x2508, 0x080c, 0x6644,
-	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, 0x865f, 0x8529, 0x1ae0, 0x012e, 0x0804,
-	0x3587, 0x012e, 0x0804, 0x35b9, 0x012e, 0x0804, 0x35bc, 0x080c,
-	0x4ae0, 0x0904, 0x35bc, 0x080c, 0x670b, 0x0904, 0x35b9, 0x080c,
-	0xa899, 0xbaa0, 0x2019, 0x0005, 0x00c6, 0x9066, 0x080c, 0x93c6,
-	0x0076, 0x903e, 0x080c, 0x928f, 0x900e, 0x080c, 0xe038, 0x007e,
-	0x00ce, 0x080c, 0xa8b5, 0x080c, 0x687a, 0x0804, 0x3587, 0x080c,
-	0x4ae0, 0x0904, 0x35bc, 0x080c, 0x687a, 0x2208, 0x0804, 0x3587,
-	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, 0x3587, 0x00f6, 0x0016,
-	0x907d, 0x0138, 0x9006, 0x8000, 0x2f0c, 0x81ff, 0x0110, 0x2178,
-	0x0cd0, 0x001e, 0x00fe, 0x0005, 0x2069, 0x1910, 0x6910, 0x62bc,
-	0x0804, 0x3587, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x35b9,
-	0x0126, 0x2091, 0x8000, 0x080c, 0x5709, 0x0128, 0x2009, 0x0007,
-	0x012e, 0x0804, 0x35b9, 0x012e, 0x615c, 0x9190, 0x3388, 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,
-	0x74ec, 0x1118, 0x2031, 0x0004, 0x0038, 0xd79c, 0x0120, 0x2009,
-	0x0005, 0x0804, 0x35b9, 0x9036, 0x7e9a, 0x7f9e, 0x0804, 0x3587,
-	0x614c, 0x6250, 0x2019, 0x1985, 0x231c, 0x2001, 0x1986, 0x2004,
-	0x789a, 0x0804, 0x3587, 0x0126, 0x2091, 0x8000, 0x6138, 0x623c,
-	0x6340, 0x012e, 0x0804, 0x3587, 0x080c, 0x4afc, 0x0904, 0x35bc,
-	0xba44, 0xbb38, 0x0804, 0x3587, 0x080c, 0x0d7d, 0x080c, 0x4afc,
-	0x2110, 0x0904, 0x35bc, 0xb804, 0x908c, 0x00ff, 0x918e, 0x0006,
-	0x0140, 0x9084, 0xff00, 0x9086, 0x0600, 0x2009, 0x0009, 0x1904,
-	0x35b9, 0x0126, 0x2091, 0x8000, 0x2019, 0x0005, 0x00c6, 0x9066,
-	0x080c, 0xa899, 0x080c, 0xa37f, 0x080c, 0x93c6, 0x0076, 0x903e,
-	0x080c, 0x928f, 0x900e, 0x080c, 0xe038, 0x007e, 0x00ce, 0x080c,
-	0xa8b5, 0xb807, 0x0407, 0x012e, 0x0804, 0x3587, 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, 0x3587, 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, 0x7888, 0x603e, 0x2011, 0x0116,
-	0x220c, 0x7888, 0xd08c, 0x0118, 0x918d, 0x0040, 0x0010, 0x918c,
-	0xff7f, 0x2112, 0x6140, 0x788c, 0x6042, 0x910e, 0xd1e4, 0x190c,
-	0x0ef4, 0x9084, 0x0020, 0x0130, 0x78b4, 0x6046, 0x9084, 0x0001,
-	0x090c, 0x4265, 0x6040, 0xd0cc, 0x0120, 0x78b0, 0x2011, 0x0114,
-	0x2012, 0x012e, 0x0804, 0x3587, 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, 0x35bc, 0x788c, 0x902d,
-	0x0904, 0x35bc, 0x900e, 0x080c, 0x6644, 0x1120, 0xba44, 0xbb38,
-	0xbc46, 0xbd3a, 0x9186, 0x07ff, 0x0190, 0x8108, 0x0ca0, 0x080c,
-	0x4afc, 0x0904, 0x35bc, 0x7888, 0x900d, 0x0904, 0x35bc, 0x788c,
-	0x9005, 0x0904, 0x35bc, 0xba44, 0xb946, 0xbb38, 0xb83a, 0x0804,
-	0x3587, 0x2011, 0xbc09, 0x0010, 0x2011, 0xbc05, 0x080c, 0x5709,
-	0x1904, 0x35b9, 0x00c6, 0x2061, 0x0100, 0x7984, 0x9186, 0x00ff,
-	0x1130, 0x2001, 0x1818, 0x2004, 0x9085, 0xff00, 0x0088, 0x9182,
-	0x007f, 0x16e0, 0x9188, 0x3388, 0x210d, 0x918c, 0x00ff, 0x2001,
-	0x1818, 0x2004, 0x0026, 0x9116, 0x002e, 0x0580, 0x810f, 0x9105,
-	0x0126, 0x2091, 0x8000, 0x0006, 0x080c, 0xab9a, 0x000e, 0x0510,
-	0x602e, 0x620a, 0x7984, 0x00b6, 0x080c, 0x65e9, 0x2b08, 0x00be,
-	0x1500, 0x6112, 0x6023, 0x0001, 0x080c, 0x4ac9, 0x01d0, 0x9006,
-	0xa866, 0x7007, 0x0003, 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x701f,
-	0x3a74, 0x2900, 0x6016, 0x2009, 0x0032, 0x080c, 0xac8d, 0x012e,
-	0x00ce, 0x0005, 0x012e, 0x00ce, 0x0804, 0x35b9, 0x00ce, 0x0804,
-	0x35bc, 0x080c, 0xabf0, 0x0cb0, 0xa830, 0x9086, 0x0100, 0x0904,
-	0x35b9, 0x0804, 0x3587, 0x2061, 0x1a6e, 0x0126, 0x2091, 0x8000,
-	0x6000, 0xd084, 0x0170, 0x6104, 0x6208, 0x2061, 0x1800, 0x6354,
-	0x6074, 0x789a, 0x60c0, 0x789e, 0x60bc, 0x78aa, 0x012e, 0x0804,
-	0x3587, 0x900e, 0x2110, 0x0c88, 0x81ff, 0x1904, 0x35b9, 0x080c,
-	0x74ec, 0x0904, 0x35b9, 0x0126, 0x2091, 0x8000, 0x6254, 0x6074,
-	0x9202, 0x0248, 0x9085, 0x0001, 0x080c, 0x2699, 0x080c, 0x5923,
-	0x012e, 0x0804, 0x3587, 0x012e, 0x0804, 0x35bc, 0x0006, 0x0016,
-	0x00c6, 0x00e6, 0x2001, 0x19a8, 0x2070, 0x2061, 0x1847, 0x6008,
-	0x2072, 0x900e, 0x2011, 0x1400, 0x080c, 0x9181, 0x7206, 0x00ee,
-	0x00ce, 0x001e, 0x000e, 0x0005, 0x0126, 0x2091, 0x8000, 0x81ff,
-	0x0128, 0x012e, 0x2021, 0x400b, 0x0804, 0x3589, 0x7884, 0xd0fc,
-	0x0148, 0x2001, 0x002a, 0x2004, 0x9082, 0x00e1, 0x0288, 0x012e,
-	0x0804, 0x35bc, 0x2001, 0x002a, 0x2004, 0x2069, 0x1847, 0x6908,
-	0x9102, 0x1230, 0x012e, 0x0804, 0x35bc, 0x012e, 0x0804, 0x35b9,
-	0x080c, 0xab5a, 0x0dd0, 0x7884, 0xd0fc, 0x0904, 0x3b3f, 0x00c6,
-	0x080c, 0x4ac9, 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, 0x3cc9, 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,
-	0x4b12, 0x701f, 0x3c06, 0x7023, 0x0001, 0x012e, 0x0005, 0x080c,
-	0xa899, 0x0046, 0x0086, 0x0096, 0x00a6, 0x00b6, 0x00c6, 0x00d6,
-	0x00e6, 0x00f6, 0x080c, 0x3aae, 0x2001, 0x199e, 0x2003, 0x0000,
-	0x2021, 0x000a, 0x2061, 0x0100, 0x6104, 0x0016, 0x60bb, 0x0000,
-	0x60bf, 0x32e1, 0x60bf, 0x0012, 0x080c, 0x3d38, 0x080c, 0x3cf7,
-	0x00f6, 0x00e6, 0x0086, 0x2940, 0x2071, 0x19e6, 0x2079, 0x0090,
-	0x00d6, 0x2069, 0x0000, 0x6884, 0xd0b4, 0x0140, 0x2001, 0x0035,
-	0x2004, 0x780e, 0x2001, 0x0034, 0x2004, 0x780a, 0x00de, 0x2011,
-	0x0001, 0x080c, 0x40a9, 0x008e, 0x00ee, 0x00fe, 0x080c, 0x3fd6,
-	0x080c, 0x3f03, 0x05b8, 0x2001, 0x020b, 0x2004, 0x9084, 0x0140,
-	0x1db8, 0x080c, 0x411d, 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, 0x3f0d, 0x080c, 0x3cf2, 0x0058, 0x080c,
-	0x3cf2, 0x080c, 0x4041, 0x080c, 0x3fcc, 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, 0x21d9, 0x2001, 0x0227, 0x200c, 0x2102, 0x080c, 0xa8b5,
-	0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae, 0x009e, 0x008e,
-	0x004e, 0x2001, 0x199e, 0x2004, 0x9005, 0x1118, 0x012e, 0x0804,
-	0x3587, 0x012e, 0x2021, 0x400c, 0x0804, 0x3589, 0x0016, 0x0026,
-	0x0036, 0x0046, 0x0056, 0x0076, 0x0086, 0x0096, 0x00d6, 0x0156,
-	0x7014, 0x2048, 0x7020, 0x20a8, 0x8000, 0x7022, 0xa804, 0x9005,
-	0x0904, 0x3c62, 0x2048, 0x1f04, 0x3c16, 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, 0x4b12, 0x701f, 0x3c06,
-	0x00b0, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0,
-	0x9080, 0x001b, 0x21a8, 0x27e0, 0x2098, 0x27e8, 0x20a0, 0x0006,
-	0x080c, 0x0fc4, 0x000e, 0x080c, 0x4b15, 0x701f, 0x3c06, 0x015e,
-	0x00de, 0x009e, 0x008e, 0x007e, 0x005e, 0x004e, 0x003e, 0x002e,
-	0x001e, 0x0005, 0x7014, 0x2048, 0xa864, 0x9086, 0x0103, 0x1118,
-	0x701f, 0x3cc7, 0x0450, 0x7014, 0x2048, 0xa868, 0xc0fd, 0xa86a,
-	0x2009, 0x007f, 0x080c, 0x65e3, 0x0110, 0x9006, 0x0030, 0xb813,
-	0x00ff, 0xb817, 0xfffd, 0x080c, 0xcd4d, 0x015e, 0x00de, 0x009e,
-	0x008e, 0x007e, 0x005e, 0x004e, 0x003e, 0x002e, 0x001e, 0x0904,
-	0x35b9, 0x0016, 0x0026, 0x0036, 0x0046, 0x0056, 0x0076, 0x0086,
-	0x0096, 0x00d6, 0x0156, 0x701f, 0x3c99, 0x7007, 0x0003, 0x0804,
-	0x3c57, 0xa830, 0x9086, 0x0100, 0x2021, 0x400c, 0x0904, 0x3589,
-	0x0076, 0xad10, 0xac0c, 0xab24, 0xaa20, 0xa930, 0xa808, 0xd0b4,
+	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,
+	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,
+	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,
+	0x7833, 0x0011, 0x0010, 0x7833, 0x0010, 0x7c82, 0x7986, 0x7a8a,
+	0x7b8e, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c,
+	0x11ee, 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,
+	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,
+	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,
+	0x2048, 0xad2c, 0xac28, 0xab1c, 0xaa18, 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,
-	0x4b15, 0x007e, 0x701f, 0x3c06, 0x7023, 0x0001, 0x0005, 0x0804,
-	0x3587, 0x0156, 0x00c6, 0xa814, 0x908a, 0x001e, 0x0218, 0xa833,
-	0x001e, 0x0010, 0xa832, 0x0078, 0x81ff, 0x0168, 0x0016, 0x080c,
-	0x4ac9, 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, 0x4ac9, 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, 0x21d9, 0x2001, 0x002a, 0x2004,
-	0x9084, 0xfff8, 0xa86e, 0x601a, 0xa873, 0x0000, 0x601f, 0x0000,
-	0x78ca, 0x9006, 0x600a, 0x600e, 0x00ce, 0x00ee, 0x00fe, 0x0005,
-	0x00e6, 0x080c, 0x4ac9, 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, 0x2a27, 0x1130, 0x9006, 0x080c,
-	0x297a, 0x9006, 0x080c, 0x295d, 0x7884, 0x9084, 0x0007, 0x0002,
-	0x3d83, 0x3d8c, 0x3d95, 0x3d80, 0x3d80, 0x3d80, 0x3d80, 0x3d80,
-	0x012e, 0x0804, 0x35bc, 0x2009, 0x0114, 0x2104, 0x9085, 0x0800,
-	0x200a, 0x080c, 0x3f57, 0x00c0, 0x2009, 0x0114, 0x2104, 0x9085,
-	0x4000, 0x200a, 0x080c, 0x3f57, 0x0078, 0x080c, 0x74ec, 0x1128,
-	0x012e, 0x2009, 0x0016, 0x0804, 0x35b9, 0x81ff, 0x0128, 0x012e,
-	0x2021, 0x400b, 0x0804, 0x3589, 0x080c, 0xa899, 0x0086, 0x0096,
-	0x00a6, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x080c, 0x3aae,
-	0x2009, 0x0101, 0x210c, 0x0016, 0x7ec8, 0x7dcc, 0x9006, 0x2068,
-	0x2060, 0x2058, 0x080c, 0x41f8, 0x080c, 0x4148, 0x903e, 0x2720,
-	0x00f6, 0x00e6, 0x0086, 0x2940, 0x2071, 0x19e6, 0x2079, 0x0090,
-	0x00d6, 0x2069, 0x0000, 0x6884, 0xd0b4, 0x0120, 0x68d4, 0x780e,
-	0x68d0, 0x780a, 0x00de, 0x2011, 0x0001, 0x080c, 0x40a9, 0x080c,
-	0x2a2f, 0x080c, 0x2a2f, 0x080c, 0x2a2f, 0x080c, 0x2a2f, 0x080c,
-	0x40a9, 0x008e, 0x00ee, 0x00fe, 0x080c, 0x3fd6, 0x2009, 0x9c40,
-	0x8109, 0x11b0, 0x080c, 0x3f0d, 0x2001, 0x0004, 0x200c, 0x918c,
-	0xfffd, 0x2102, 0x001e, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be,
-	0x00ae, 0x009e, 0x008e, 0x2009, 0x0017, 0x080c, 0x35b9, 0x0cf8,
-	0x2001, 0x020b, 0x2004, 0x9084, 0x0140, 0x1d10, 0x00f6, 0x2079,
-	0x0000, 0x7884, 0x00fe, 0xd0bc, 0x0178, 0x2001, 0x0201, 0x200c,
-	0x81ff, 0x0150, 0x080c, 0x3fb4, 0x2d00, 0x9c05, 0x9b05, 0x0120,
-	0x080c, 0x3f0d, 0x0804, 0x3eb6, 0x080c, 0x411d, 0x080c, 0x4041,
-	0x080c, 0x3f97, 0x080c, 0x3fcc, 0x00f6, 0x2079, 0x0100, 0x7824,
-	0xd0ac, 0x0130, 0x8b58, 0x080c, 0x3f0d, 0x00fe, 0x0804, 0x3eb6,
-	0x00fe, 0x080c, 0x3f03, 0x1150, 0x8d68, 0x2001, 0x0032, 0x2602,
-	0x2001, 0x0033, 0x2502, 0x080c, 0x3f0d, 0x0080, 0x87ff, 0x0138,
-	0x2001, 0x0201, 0x2004, 0x9005, 0x1908, 0x8739, 0x0038, 0x2001,
-	0x1a6a, 0x2004, 0x9086, 0x0000, 0x1904, 0x3e06, 0x2001, 0x032f,
-	0x2003, 0x00f6, 0x8631, 0x1208, 0x8529, 0x2500, 0x9605, 0x0904,
-	0x3eb6, 0x7884, 0xd0bc, 0x0128, 0x2d00, 0x9c05, 0x9b05, 0x1904,
-	0x3eb6, 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, 0x21d9, 0x2900,
-	0xa85a, 0xa813, 0x0019, 0x7884, 0xd0a4, 0x1180, 0xa817, 0x0000,
-	0x00c6, 0x20a9, 0x0004, 0x2061, 0x0090, 0x602b, 0x0008, 0x2001,
-	0x0203, 0x2004, 0x1f04, 0x3e8d, 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, 0x3dc0, 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, 0x21d9, 0x2001,
-	0x0227, 0x200c, 0x2102, 0x6050, 0x9084, 0xb7ff, 0x080c, 0x2ad9,
-	0x6052, 0x602f, 0x0000, 0x604b, 0xf7f7, 0x6043, 0x0090, 0x6043,
-	0x0010, 0x080c, 0xa8b5, 0x00ce, 0x2d08, 0x2c10, 0x2b18, 0x2b00,
-	0x9c05, 0x9d05, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae,
-	0x009e, 0x008e, 0x1118, 0x012e, 0x0804, 0x3587, 0x012e, 0x2021,
-	0x400c, 0x0804, 0x3589, 0x9085, 0x0001, 0x1d04, 0x3f0c, 0x2091,
-	0x6000, 0x8420, 0x9486, 0x0064, 0x0005, 0x2001, 0x0105, 0x2003,
-	0x0010, 0x2001, 0x032a, 0x2003, 0x0004, 0x2001, 0x1a6a, 0x2003,
-	0x0000, 0x0071, 0x2009, 0x0048, 0x080c, 0x21d9, 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, 0x21d9, 0x782c, 0xd0fc,
-	0x0d88, 0x080c, 0x411d, 0x7054, 0x9086, 0x0000, 0x1d58, 0x782b,
-	0x0004, 0x782c, 0xd0ac, 0x1de8, 0x2009, 0x0040, 0x080c, 0x21d9,
-	0x782b, 0x0002, 0x7057, 0x0000, 0x00ee, 0x00fe, 0x0005, 0x00f6,
-	0x2079, 0x0100, 0x2001, 0x1818, 0x200c, 0x7932, 0x7936, 0x080c,
-	0x2679, 0x080c, 0x2aa6, 0x080c, 0x2ad9, 0x784b, 0xf7f7, 0x7843,
-	0x0090, 0x7843, 0x0010, 0x7850, 0xc0e5, 0x7852, 0x2019, 0x61a8,
-	0x7820, 0xd09c, 0x0110, 0x8319, 0x1dd8, 0x7850, 0xc0e4, 0x7852,
-	0x2011, 0x0048, 0x080c, 0x2a83, 0x7843, 0x0040, 0x2019, 0x01f4,
-	0xa001, 0xa001, 0x8319, 0x1de0, 0x2001, 0x0100, 0x080c, 0x2a49,
-	0x2011, 0x0020, 0x080c, 0x2a83, 0x7843, 0x0000, 0x9006, 0x080c,
-	0x2a49, 0x2011, 0x0048, 0x080c, 0x2a83, 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, 0x3ce8, 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, 0x411d, 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, 0x40a9, 0x2011, 0x0001, 0x080c, 0x40a9, 0x00fe, 0x00ee,
-	0x0005, 0x00f6, 0x00e6, 0x2071, 0x1a6a, 0x2079, 0x0320, 0x792c,
-	0xd1fc, 0x0904, 0x40a6, 0x782b, 0x0002, 0x9026, 0xd19c, 0x1904,
-	0x40a2, 0x7000, 0x0002, 0x40a6, 0x4057, 0x4087, 0x40a2, 0xd1bc,
-	0x1170, 0xd1dc, 0x1190, 0x8001, 0x7002, 0x2011, 0x0001, 0x080c,
-	0x40a9, 0x0904, 0x40a6, 0x080c, 0x40a9, 0x0804, 0x40a6, 0x00f6,
-	0x2079, 0x0300, 0x78bf, 0x0000, 0x00fe, 0x7810, 0x7914, 0x782b,
-	0x0004, 0x7812, 0x7916, 0x2001, 0x0201, 0x200c, 0x81ff, 0x0de8,
-	0x080c, 0x3fb4, 0x2009, 0x0001, 0x00f6, 0x2079, 0x0300, 0x78b8,
-	0x00fe, 0xd0ec, 0x0110, 0x2009, 0x0011, 0x792a, 0x00f8, 0x8001,
-	0x7002, 0x9184, 0x0880, 0x1140, 0x782c, 0xd0fc, 0x1904, 0x404b,
-	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, 0x40d7, 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, 0x4114,
-	0x410b, 0x4102, 0x40f9, 0x40f0, 0x40e7, 0x40de, 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, 0x4144, 0x4130, 0x413b,
-	0x8001, 0x7056, 0xd19c, 0x1180, 0x2011, 0x0001, 0x080c, 0x40a9,
-	0x190c, 0x40a9, 0x0048, 0x8001, 0x7056, 0x782c, 0xd0fc, 0x1d38,
-	0x2011, 0x0001, 0x080c, 0x40a9, 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,
-	0x4ac9, 0xa813, 0x0019, 0xaf16, 0x2900, 0xa85a, 0x978a, 0x0007,
-	0x0220, 0x2138, 0x2009, 0x0007, 0x0010, 0x2708, 0x903e, 0x0096,
-	0xa858, 0x2048, 0xa85c, 0x9080, 0x0019, 0x009e, 0x080c, 0x41c0,
-	0x1d68, 0x2900, 0xa85a, 0x00d0, 0x080c, 0x4ac9, 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, 0x21d9, 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, 0x4ac9, 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, 0x4ac9, 0x2940,
-	0xa813, 0x0019, 0xaf16, 0x2900, 0xa85a, 0x978a, 0x0007, 0x0220,
-	0x2138, 0x2009, 0x0007, 0x0010, 0x2708, 0x903e, 0x0096, 0xa858,
-	0x2048, 0xa85c, 0x9080, 0x0019, 0x009e, 0x080c, 0x41c0, 0x1d68,
-	0x2900, 0xa85a, 0x00d8, 0x080c, 0x4ac9, 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,
+	0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x001b, 0x080c, 0x4b3b,
+	0x701f, 0x3c3d, 0x7023, 0x0001, 0x012e, 0x0005, 0x080c, 0xa91e,
+	0x0046, 0x0086, 0x0096, 0x00a6, 0x00b6, 0x00c6, 0x00d6, 0x00e6,
+	0x00f6, 0x080c, 0x3ae5, 0x2001, 0x199e, 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,
+	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,
+	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,
+	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,
+	0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae, 0x009e, 0x008e, 0x004e,
+	0x2001, 0x199e, 0x2004, 0x9005, 0x1118, 0x012e, 0x0804, 0x35b8,
+	0x012e, 0x2021, 0x400c, 0x0804, 0x35ba, 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,
+	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,
+	0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080,
+	0x001b, 0x21a8, 0x27e0, 0x2098, 0x27e8, 0x20a0, 0x0006, 0x080c,
+	0x0fc4, 0x000e, 0x080c, 0x4b3e, 0x701f, 0x3c3d, 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,
+	0x0016, 0x0026, 0x0036, 0x0046, 0x0056, 0x0076, 0x0086, 0x0096,
+	0x00d6, 0x0156, 0x701f, 0x3cd0, 0x7007, 0x0003, 0x0804, 0x3c8e,
+	0xa830, 0x9086, 0x0100, 0x2021, 0x400c, 0x0904, 0x35ba, 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,
+	0x0156, 0x00c6, 0xa814, 0x908a, 0x001e, 0x0218, 0xa833, 0x001e,
+	0x0010, 0xa832, 0x0078, 0x81ff, 0x0168, 0x0016, 0x080c, 0x4af2,
+	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,
+	0x2001, 0x002e, 0x2004, 0xa866, 0x2001, 0x002f, 0x2004, 0xa86a,
+	0x2061, 0x0090, 0x2079, 0x0100, 0x2001, 0x19a8, 0x2004, 0x6036,
+	0x2009, 0x0040, 0x080c, 0x220a, 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,
+	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,
-	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, 0x3587, 0x7d98, 0x7c9c, 0x0804, 0x3689, 0x080c,
-	0x74ec, 0x190c, 0x6009, 0x6040, 0x9084, 0x0020, 0x09b1, 0x2069,
-	0x1847, 0x2d00, 0x2009, 0x0030, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98,
-	0x2039, 0x0001, 0x080c, 0x4b12, 0x701f, 0x429f, 0x0005, 0x080c,
-	0x5704, 0x1130, 0x3b00, 0x3a08, 0xc194, 0xc095, 0x20d8, 0x21d0,
-	0x2069, 0x1847, 0x6800, 0x9005, 0x0904, 0x35bc, 0x6804, 0xd0ac,
-	0x0118, 0xd0a4, 0x0904, 0x35bc, 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,
-	0x35bc, 0x9288, 0x3388, 0x210d, 0x918c, 0x00ff, 0x6166, 0xd0dc,
-	0x0130, 0x6828, 0x908a, 0x007f, 0x1a04, 0x35bc, 0x605e, 0x6888,
-	0x9084, 0x0030, 0x8004, 0x8004, 0x8004, 0x8004, 0x0006, 0x2009,
-	0x19b0, 0x9080, 0x276c, 0x2005, 0x200a, 0x2008, 0x2001, 0x0018,
-	0x080c, 0xa88a, 0x2009, 0x0390, 0x200b, 0x0400, 0x000e, 0x2009,
-	0x19b1, 0x9080, 0x2770, 0x2005, 0x200a, 0x6808, 0x908a, 0x0100,
-	0x0a04, 0x35bc, 0x908a, 0x0841, 0x1a04, 0x35bc, 0x9084, 0x0007,
-	0x1904, 0x35bc, 0x680c, 0x9005, 0x0904, 0x35bc, 0x6810, 0x9005,
-	0x0904, 0x35bc, 0x6848, 0x6940, 0x910a, 0x1a04, 0x35bc, 0x8001,
-	0x0904, 0x35bc, 0x684c, 0x6944, 0x910a, 0x1a04, 0x35bc, 0x8001,
-	0x0904, 0x35bc, 0x6814, 0x908c, 0x00ff, 0x614e, 0x8007, 0x9084,
-	0x00ff, 0x6052, 0x080c, 0x7820, 0x080c, 0x6ac0, 0x080c, 0x6af4,
-	0x6808, 0x602a, 0x080c, 0x214b, 0x2009, 0x0170, 0x200b, 0x0080,
-	0xa001, 0xa001, 0x200b, 0x0000, 0x0036, 0x6b08, 0x080c, 0x26d3,
-	0x003e, 0x6000, 0x9086, 0x0000, 0x1904, 0x442a, 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, 0x87e4,
-	0x00c6, 0x900e, 0x20a9, 0x0001, 0x6b70, 0xd384, 0x01c8, 0x0020,
-	0x839d, 0x12b0, 0x3508, 0x8109, 0x080c, 0x7de2, 0x6878, 0x6016,
-	0x6874, 0x2008, 0x9084, 0xff00, 0x8007, 0x600a, 0x9184, 0x00ff,
-	0x6006, 0x8108, 0x1118, 0x6003, 0x0003, 0x0010, 0x6003, 0x0001,
-	0x1f04, 0x4388, 0x00ce, 0x00c6, 0x2061, 0x199b, 0x6a88, 0x9284,
-	0xc000, 0x2010, 0x9286, 0x0000, 0x1158, 0x2063, 0x0000, 0x2001,
-	0x0001, 0x080c, 0x297a, 0x2001, 0x0001, 0x080c, 0x295d, 0x0088,
-	0x9286, 0x4000, 0x1148, 0x2063, 0x0001, 0x9006, 0x080c, 0x297a,
-	0x9006, 0x080c, 0x295d, 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, 0x2748, 0x2001, 0x196c, 0x2102,
-	0x0008, 0x2102, 0x00c6, 0x2061, 0x0100, 0x602f, 0x0040, 0x602f,
-	0x0000, 0x00ce, 0x080c, 0x74ec, 0x0128, 0x080c, 0x4ff9, 0x0110,
-	0x080c, 0x2699, 0x60d4, 0x9005, 0x01c0, 0x6003, 0x0001, 0x2009,
-	0x4412, 0x00e0, 0x080c, 0x74ec, 0x1168, 0x2011, 0x7362, 0x080c,
-	0x8651, 0x2011, 0x7355, 0x080c, 0x875d, 0x080c, 0x77f4, 0x080c,
-	0x741d, 0x0040, 0x080c, 0x5eff, 0x0028, 0x6003, 0x0004, 0x2009,
-	0x442a, 0x0020, 0x080c, 0x69f0, 0x0804, 0x3587, 0x2001, 0x0170,
-	0x2004, 0x9084, 0x00ff, 0x9086, 0x004c, 0x1118, 0x2091, 0x31bd,
-	0x0817, 0x2091, 0x313d, 0x0817, 0x6000, 0x9086, 0x0000, 0x0904,
-	0x35b9, 0x2069, 0x1847, 0x7890, 0x6842, 0x7894, 0x6846, 0x2d00,
-	0x2009, 0x0030, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x2039, 0x0001,
-	0x0804, 0x4b15, 0x9006, 0x080c, 0x2699, 0x81ff, 0x1904, 0x35b9,
-	0x080c, 0x74ec, 0x11b0, 0x080c, 0x77ef, 0x080c, 0x6044, 0x080c,
-	0x337c, 0x0118, 0x6130, 0xc18d, 0x6132, 0x080c, 0xcf84, 0x0130,
-	0x080c, 0x750f, 0x1118, 0x080c, 0x74c0, 0x0038, 0x080c, 0x741d,
-	0x0020, 0x080c, 0x6009, 0x080c, 0x5eff, 0x0804, 0x3587, 0x81ff,
-	0x1904, 0x35b9, 0x080c, 0x74ec, 0x1110, 0x0804, 0x35b9, 0x6194,
-	0x81ff, 0x01a8, 0x704f, 0x0000, 0x2001, 0x1d80, 0x2009, 0x0040,
-	0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x0126, 0x2091, 0x8000, 0x2039,
-	0x0001, 0x080c, 0x4b15, 0x701f, 0x3585, 0x012e, 0x0005, 0x704f,
-	0x0001, 0x00d6, 0x2069, 0x1d80, 0x20a9, 0x0040, 0x20e9, 0x0001,
-	0x20a1, 0x1d80, 0x2019, 0xffff, 0x4304, 0x655c, 0x9588, 0x3388,
-	0x210d, 0x918c, 0x00ff, 0x216a, 0x900e, 0x2011, 0x0002, 0x2100,
-	0x9506, 0x01a8, 0x080c, 0x6644, 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, 0x5f94, 0x0804, 0x4484, 0x080c, 0x4afc, 0x0904, 0x35bc,
-	0x080c, 0x4ac9, 0x1120, 0x2009, 0x0002, 0x0804, 0x35b9, 0x080c,
-	0x56f5, 0xd0b4, 0x0558, 0x7884, 0x908e, 0x007e, 0x0538, 0x908e,
-	0x007f, 0x0520, 0x908e, 0x0080, 0x0508, 0x080c, 0x3377, 0x1148,
-	0xb800, 0xd08c, 0x11d8, 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006,
-	0x11a8, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xca34,
-	0x1120, 0x2009, 0x0003, 0x0804, 0x35b9, 0x7007, 0x0003, 0x701f,
-	0x4512, 0x0005, 0x080c, 0x4afc, 0x0904, 0x35bc, 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, 0x4b15,
-	0x81ff, 0x1904, 0x35b9, 0x080c, 0x4ae0, 0x0904, 0x35bc, 0x080c,
-	0x6889, 0x0904, 0x35b9, 0x0058, 0xa878, 0x9005, 0x0120, 0x2009,
-	0x0004, 0x0804, 0x35b9, 0xa974, 0xaa94, 0x0804, 0x3587, 0x080c,
-	0x56fd, 0x0904, 0x3587, 0x701f, 0x455c, 0x7007, 0x0003, 0x0005,
-	0x81ff, 0x1904, 0x35b9, 0x7888, 0x908a, 0x1000, 0x1a04, 0x35bc,
-	0x080c, 0x4afc, 0x0904, 0x35bc, 0x080c, 0x6a8e, 0x0120, 0x080c,
-	0x6a96, 0x1904, 0x35bc, 0x080c, 0x690e, 0x0904, 0x35b9, 0x2019,
-	0x0004, 0x900e, 0x080c, 0x689b, 0x0904, 0x35b9, 0x7984, 0x7a88,
-	0x04c9, 0x08a8, 0xa89c, 0x908a, 0x1000, 0x12f8, 0x080c, 0x4afa,
-	0x01e0, 0x080c, 0x6a8e, 0x0118, 0x080c, 0x6a96, 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,
-	0x56fd, 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, 0x6644, 0x1138, 0x2200,
-	0x8003, 0x800b, 0x810b, 0x9108, 0x080c, 0x865f, 0x0005, 0x81ff,
-	0x1904, 0x35b9, 0x798c, 0x2001, 0x197f, 0x918c, 0x8000, 0x2102,
-	0x080c, 0x4ae0, 0x0904, 0x35bc, 0x080c, 0x6a8e, 0x0120, 0x080c,
-	0x6a96, 0x1904, 0x35bc, 0x080c, 0x670b, 0x0904, 0x35b9, 0x080c,
-	0x6892, 0x0904, 0x35b9, 0x2001, 0x197f, 0x2004, 0xd0fc, 0x1904,
-	0x3587, 0x0804, 0x4567, 0xa9a0, 0x2001, 0x197f, 0x918c, 0x8000,
-	0xc18d, 0x2102, 0x080c, 0x4aed, 0x01a0, 0x080c, 0x6a8e, 0x0118,
-	0x080c, 0x6a96, 0x1170, 0x080c, 0x670b, 0x2009, 0x0002, 0x0128,
-	0x080c, 0x6892, 0x1170, 0x2009, 0x0003, 0xa897, 0x4005, 0xa99a,
-	0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030,
-	0x0005, 0xa897, 0x4000, 0x2001, 0x197f, 0x2004, 0xd0fc, 0x1128,
-	0x080c, 0x56fd, 0x0110, 0x9006, 0x0018, 0x900e, 0x9085, 0x0001,
-	0x2001, 0x0000, 0x0005, 0x81ff, 0x1904, 0x35b9, 0x798c, 0x2001,
-	0x197e, 0x918c, 0x8000, 0x2102, 0x080c, 0x4ae0, 0x0904, 0x35bc,
-	0x080c, 0x6a8e, 0x0120, 0x080c, 0x6a96, 0x1904, 0x35bc, 0x080c,
-	0x670b, 0x0904, 0x35b9, 0x080c, 0x6880, 0x0904, 0x35b9, 0x2001,
-	0x197e, 0x2004, 0xd0fc, 0x1904, 0x3587, 0x0804, 0x4567, 0xa9a0,
-	0x2001, 0x197e, 0x918c, 0x8000, 0xc18d, 0x2102, 0x080c, 0x4aed,
-	0x01a0, 0x080c, 0x6a8e, 0x0118, 0x080c, 0x6a96, 0x1170, 0x080c,
-	0x670b, 0x2009, 0x0002, 0x0128, 0x080c, 0x6880, 0x1170, 0x2009,
-	0x0003, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e,
-	0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0x2001,
-	0x197e, 0x2004, 0xd0fc, 0x1128, 0x080c, 0x56fd, 0x0110, 0x9006,
-	0x0018, 0x900e, 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, 0x6100,
-	0x0804, 0x3587, 0x080c, 0x4afc, 0x0904, 0x35bc, 0x080c, 0x5709,
-	0x1904, 0x35b9, 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, 0x0200, 0x0804, 0x3587, 0x78a8,
-	0x909c, 0x0003, 0xd0ac, 0x1150, 0xd0b4, 0x1140, 0x939a, 0x0003,
-	0x1a04, 0x35b9, 0x625c, 0x7884, 0x9206, 0x1538, 0x080c, 0x87ce,
-	0x2001, 0xffec, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x2039, 0x0000,
-	0x0006, 0x78a8, 0x9084, 0x0080, 0x1118, 0x000e, 0x0804, 0x4b15,
-	0x000e, 0x2031, 0x0000, 0x2061, 0x18b8, 0x2c44, 0xa66a, 0xa17a,
-	0xa772, 0xa076, 0xa28e, 0xa392, 0xa496, 0xa59a, 0x080c, 0x113c,
-	0x7007, 0x0002, 0x701f, 0x471d, 0x0005, 0x81ff, 0x1904, 0x35b9,
-	0x080c, 0x4afc, 0x0904, 0x35bc, 0x080c, 0x6a8e, 0x1904, 0x35b9,
-	0x00c6, 0x080c, 0x4ac9, 0x00ce, 0x0904, 0x35b9, 0xa867, 0x0000,
-	0xa868, 0xc0fd, 0xa86a, 0x7ea8, 0x080c, 0xc9da, 0x0904, 0x35b9,
-	0x7007, 0x0003, 0x701f, 0x4721, 0x0005, 0x080c, 0x4265, 0x0804,
-	0x3587, 0xa830, 0x9086, 0x0100, 0x0904, 0x35b9, 0x8906, 0x8006,
-	0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x001b, 0x2009,
-	0x000c, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x0804, 0x4b15, 0x9006,
-	0x080c, 0x2699, 0x78a8, 0x9084, 0x00ff, 0x9086, 0x00ff, 0x0118,
-	0x81ff, 0x1904, 0x35b9, 0x080c, 0x74ec, 0x0110, 0x080c, 0x6009,
-	0x7888, 0x908a, 0x1000, 0x1a04, 0x35bc, 0x7984, 0x9186, 0x00ff,
-	0x0138, 0x9182, 0x007f, 0x1a04, 0x35bc, 0x2100, 0x080c, 0x2663,
-	0x0026, 0x00c6, 0x0126, 0x2091, 0x8000, 0x2061, 0x1a02, 0x601b,
-	0x0000, 0x601f, 0x0000, 0x6073, 0x0000, 0x6077, 0x0000, 0x080c,
-	0x74ec, 0x1158, 0x080c, 0x77ef, 0x080c, 0x6044, 0x9085, 0x0001,
-	0x080c, 0x7533, 0x080c, 0x741d, 0x00f0, 0x080c, 0xa899, 0x080c,
-	0xab61, 0x080c, 0xa8b5, 0x2061, 0x0100, 0x2001, 0x1818, 0x2004,
-	0x9084, 0x00ff, 0x810f, 0x9105, 0x604a, 0x6043, 0x0090, 0x6043,
-	0x0010, 0x2009, 0x1998, 0x200b, 0x0000, 0x2009, 0x002d, 0x2011,
-	0x5f2f, 0x080c, 0x871b, 0x7984, 0x080c, 0x74ec, 0x1110, 0x2009,
-	0x00ff, 0x7a88, 0x080c, 0x45ca, 0x012e, 0x00ce, 0x002e, 0x0804,
-	0x3587, 0x7984, 0x080c, 0x65e3, 0x2b08, 0x1904, 0x35bc, 0x0804,
-	0x3587, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x35b9, 0x60dc,
-	0xd0ac, 0x1130, 0xd09c, 0x1120, 0x2009, 0x0005, 0x0804, 0x35b9,
-	0x080c, 0x4ac9, 0x1120, 0x2009, 0x0002, 0x0804, 0x35b9, 0x7984,
-	0x9192, 0x0021, 0x1a04, 0x35bc, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98,
-	0xa85c, 0x9080, 0x0019, 0x702a, 0xaf60, 0x7736, 0x080c, 0x4b12,
-	0x701f, 0x47d9, 0x7880, 0x9086, 0x006e, 0x0110, 0x701f, 0x51ab,
-	0x0005, 0x2009, 0x0080, 0x080c, 0x6644, 0x1118, 0x080c, 0x6a8e,
-	0x0120, 0x2021, 0x400a, 0x0804, 0x3589, 0x00d6, 0x0096, 0xa964,
-	0xaa6c, 0xab70, 0xac74, 0xad78, 0xae7c, 0xa884, 0x90be, 0x0100,
-	0x0904, 0x4872, 0x90be, 0x0112, 0x0904, 0x4872, 0x90be, 0x0113,
-	0x0904, 0x4872, 0x90be, 0x0114, 0x0904, 0x4872, 0x90be, 0x0117,
-	0x0904, 0x4872, 0x90be, 0x011a, 0x0904, 0x4872, 0x90be, 0x011c,
-	0x0904, 0x4872, 0x90be, 0x0121, 0x0904, 0x4859, 0x90be, 0x0131,
-	0x0904, 0x4859, 0x90be, 0x0171, 0x0904, 0x4872, 0x90be, 0x0173,
-	0x0904, 0x4872, 0x90be, 0x01a1, 0x1128, 0xa894, 0x8007, 0xa896,
-	0x0804, 0x487d, 0x90be, 0x0212, 0x0904, 0x4866, 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, 0x35bc,
-	0x7028, 0x9080, 0x0010, 0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8,
-	0x20a9, 0x0007, 0x080c, 0x48bb, 0x7028, 0x9080, 0x000e, 0x2098,
-	0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0001, 0x080c, 0x48bb,
-	0x00c8, 0x7028, 0x9080, 0x000c, 0x2098, 0x20a0, 0x7034, 0x20e0,
-	0x20e8, 0x20a9, 0x0001, 0x080c, 0x48c8, 0x00b8, 0x7028, 0x9080,
-	0x000e, 0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0001,
-	0x080c, 0x48c8, 0x7028, 0x9080, 0x000c, 0x2098, 0x20a0, 0x7034,
-	0x20e0, 0x20e8, 0x20a9, 0x0001, 0x04f1, 0x00c6, 0x080c, 0x4ac9,
-	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,
-	0xc9f5, 0x1120, 0x2009, 0x0003, 0x0804, 0x35b9, 0x7007, 0x0003,
-	0x701f, 0x48b2, 0x0005, 0x00ce, 0x009e, 0x00de, 0x2009, 0x0002,
-	0x0804, 0x35b9, 0xa820, 0x9086, 0x8001, 0x1904, 0x3587, 0x2009,
-	0x0004, 0x0804, 0x35b9, 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,
-	0x35b9, 0x60dc, 0xd0ac, 0x1130, 0xd09c, 0x1120, 0x2009, 0x0005,
-	0x0804, 0x35b9, 0x7984, 0x78a8, 0x2040, 0x080c, 0xab5a, 0x1120,
-	0x9182, 0x007f, 0x0a04, 0x35bc, 0x9186, 0x00ff, 0x0904, 0x35bc,
-	0x9182, 0x0800, 0x1a04, 0x35bc, 0x7a8c, 0x7b88, 0x607c, 0x9306,
-	0x1158, 0x6080, 0x924e, 0x0904, 0x35bc, 0x080c, 0xab5a, 0x1120,
-	0x99cc, 0xff00, 0x0904, 0x35bc, 0x0126, 0x2091, 0x8000, 0x080c,
-	0x49dc, 0x0904, 0x495c, 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, 0x6a8e,
-	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, 0x3589, 0x000e, 0x00ce, 0x2b00, 0x7026, 0x0016, 0x00b6,
-	0x00c6, 0x00e6, 0x2c70, 0x080c, 0xac60, 0x0904, 0x49b1, 0x2b00,
-	0x6012, 0x080c, 0xccfe, 0x2e58, 0x00ee, 0x00e6, 0x00c6, 0x080c,
-	0x4ac9, 0x00ce, 0x2b70, 0x1158, 0x080c, 0xabf0, 0x00ee, 0x00ce,
-	0x00be, 0x001e, 0x012e, 0x2009, 0x0002, 0x0804, 0x35b9, 0x900e,
-	0xa966, 0xa96a, 0x2900, 0x6016, 0xa932, 0xa868, 0xc0fd, 0xd88c,
-	0x0108, 0xc0f5, 0xa86a, 0xd89c, 0x1110, 0x080c, 0x320f, 0x6023,
-	0x0001, 0x9006, 0x080c, 0x6580, 0xd89c, 0x0138, 0x2001, 0x0004,
-	0x080c, 0x6594, 0x2009, 0x0003, 0x0030, 0x2001, 0x0002, 0x080c,
-	0x6594, 0x2009, 0x0002, 0x080c, 0xac8d, 0x78a8, 0xd094, 0x0138,
-	0x00ee, 0x7024, 0x00e6, 0x2058, 0xb8d4, 0xc08d, 0xb8d6, 0x9085,
-	0x0001, 0x00ee, 0x00ce, 0x00be, 0x001e, 0x012e, 0x1120, 0x2009,
-	0x0003, 0x0804, 0x35b9, 0x7007, 0x0003, 0x701f, 0x49c0, 0x0005,
-	0xa830, 0x9086, 0x0100, 0x7024, 0x2058, 0x1138, 0x2009, 0x0004,
-	0xba04, 0x9294, 0x00ff, 0x0804, 0x5652, 0x900e, 0xa868, 0xd0f4,
-	0x1904, 0x3587, 0x080c, 0x6937, 0x1108, 0xc185, 0xb800, 0xd0bc,
-	0x0108, 0xc18d, 0x0804, 0x3587, 0x00e6, 0x00d6, 0x0096, 0x83ff,
-	0x0904, 0x4a2b, 0x902e, 0x080c, 0xab5a, 0x0130, 0x9026, 0x20a9,
-	0x0800, 0x2071, 0x1000, 0x0030, 0x2021, 0x007f, 0x20a9, 0x0781,
-	0x2071, 0x107f, 0x2e04, 0x9005, 0x11b8, 0x2100, 0x9406, 0x1904,
-	0x4a3c, 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, 0x6a2e, 0x1570, 0x2001,
-	0x4000, 0x0460, 0x080c, 0x6a8e, 0x1540, 0x2001, 0x4000, 0x0430,
-	0x2001, 0x4007, 0x0418, 0x2001, 0x4006, 0x0400, 0x2400, 0x9106,
-	0x1158, 0xbe14, 0x87ff, 0x1128, 0x86ff, 0x0918, 0x080c, 0xab5a,
-	0x1900, 0x2001, 0x4008, 0x0090, 0x8420, 0x8e70, 0x1f04, 0x49f2,
-	0x85ff, 0x1130, 0x2001, 0x4009, 0x0048, 0x2001, 0x0001, 0x0030,
-	0x080c, 0x65e3, 0x1dd0, 0xbb12, 0xba16, 0x9006, 0x9005, 0x009e,
-	0x00de, 0x00ee, 0x0005, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804,
-	0x35b9, 0x080c, 0x4ac9, 0x1120, 0x2009, 0x0002, 0x0804, 0x35b9,
-	0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x7884, 0x9005, 0x0904,
-	0x35bc, 0x9096, 0x00ff, 0x0120, 0x9092, 0x0004, 0x1a04, 0x35bc,
-	0x2010, 0x2918, 0x080c, 0x31af, 0x1120, 0x2009, 0x0003, 0x0804,
-	0x35b9, 0x7007, 0x0003, 0x701f, 0x4a7e, 0x0005, 0xa830, 0x9086,
-	0x0100, 0x1904, 0x3587, 0x2009, 0x0004, 0x0804, 0x35b9, 0x7984,
-	0x080c, 0xab5a, 0x1120, 0x9182, 0x007f, 0x0a04, 0x35bc, 0x9186,
-	0x00ff, 0x0904, 0x35bc, 0x9182, 0x0800, 0x1a04, 0x35bc, 0x2001,
-	0x9000, 0x080c, 0x56ad, 0x1904, 0x35b9, 0x0804, 0x3587, 0xa998,
-	0x080c, 0xab5a, 0x1118, 0x9182, 0x007f, 0x0280, 0x9186, 0x00ff,
-	0x0168, 0x9182, 0x0800, 0x1250, 0x2001, 0x9000, 0x080c, 0x56ad,
-	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, 0x1047, 0x0198, 0x9006, 0xa802, 0x7014, 0x9005,
-	0x1120, 0x2900, 0x7016, 0x701a, 0x0040, 0x7018, 0xa802, 0x0086,
-	0x2040, 0x2900, 0xa006, 0x701a, 0x008e, 0x9085, 0x0001, 0x0005,
-	0x7984, 0x080c, 0x6644, 0x1130, 0x7e88, 0x9684, 0x3fff, 0x9082,
-	0x4000, 0x0208, 0x905e, 0x8bff, 0x0005, 0xa998, 0x080c, 0x6644,
-	0x1130, 0xae9c, 0x9684, 0x3fff, 0x9082, 0x4000, 0x0208, 0x905e,
-	0x8bff, 0x0005, 0xae98, 0x0008, 0x7e84, 0x2608, 0x080c, 0x6644,
-	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, 0x3587,
-	0x0005, 0x00f6, 0x0126, 0x2091, 0x8000, 0x2079, 0x0000, 0x2001,
-	0x18b0, 0x2004, 0x9005, 0x1190, 0x0e04, 0x4b46, 0x7a36, 0x7833,
-	0x0012, 0x7a82, 0x7b86, 0x7c8a, 0x2091, 0x4080, 0x2001, 0x0089,
-	0x2004, 0xd084, 0x190c, 0x11ee, 0x0804, 0x4bac, 0x0016, 0x0086,
-	0x0096, 0x00c6, 0x00e6, 0x2071, 0x189e, 0x7044, 0x9005, 0x1540,
-	0x7148, 0x9182, 0x0010, 0x0288, 0x7038, 0x2060, 0x080c, 0x1047,
-	0x0904, 0x4ba4, 0xa84b, 0x0000, 0x2900, 0x7046, 0x2001, 0x0002,
-	0x9080, 0x1e7a, 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,
-	0x1e7a, 0x2005, 0xa846, 0x0058, 0x2262, 0x6306, 0x640a, 0x00ee,
-	0x00ce, 0x009e, 0x008e, 0x001e, 0x012e, 0x00fe, 0x0005, 0x2c00,
-	0x9082, 0x001b, 0x0002, 0x4bce, 0x4bce, 0x4bd0, 0x4bce, 0x4bce,
-	0x4bce, 0x4bd4, 0x4bce, 0x4bce, 0x4bce, 0x4bd8, 0x4bce, 0x4bce,
-	0x4bce, 0x4bdc, 0x4bce, 0x4bce, 0x4bce, 0x4be0, 0x4bce, 0x4bce,
-	0x4bce, 0x4be4, 0x4bce, 0x4bce, 0x4bce, 0x4be9, 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,
-	0x4ba7, 0xa2d6, 0xa3da, 0xa4de, 0x0804, 0x4ba7, 0x00e6, 0x2071,
-	0x189e, 0x7048, 0x9005, 0x0904, 0x4c80, 0x0126, 0x2091, 0x8000,
-	0x0e04, 0x4c7f, 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, 0x4c82, 0xa804, 0x9005,
-	0x090c, 0x0d7d, 0x7042, 0x2938, 0x2040, 0xa003, 0x0000, 0x2001,
-	0x0002, 0x9080, 0x1e7a, 0x2005, 0xa04a, 0x0804, 0x4c82, 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, 0x1e7a, 0x2005,
-	0xa84a, 0x0000, 0x007e, 0x008e, 0x009e, 0x00ce, 0x00fe, 0x012e,
-	0x00ee, 0x0005, 0x2c00, 0x9082, 0x001b, 0x0002, 0x4ca1, 0x4ca1,
-	0x4ca3, 0x4ca1, 0x4ca1, 0x4ca1, 0x4ca8, 0x4ca1, 0x4ca1, 0x4ca1,
-	0x4cad, 0x4ca1, 0x4ca1, 0x4ca1, 0x4cb2, 0x4ca1, 0x4ca1, 0x4ca1,
-	0x4cb7, 0x4ca1, 0x4ca1, 0x4ca1, 0x4cbc, 0x4ca1, 0x4ca1, 0x4ca1,
-	0x4cc1, 0x080c, 0x0d7d, 0xaa74, 0xab78, 0xac7c, 0x0804, 0x4c2d,
-	0xaa84, 0xab88, 0xac8c, 0x0804, 0x4c2d, 0xaa94, 0xab98, 0xac9c,
-	0x0804, 0x4c2d, 0xaaa4, 0xaba8, 0xacac, 0x0804, 0x4c2d, 0xaab4,
-	0xabb8, 0xacbc, 0x0804, 0x4c2d, 0xaac4, 0xabc8, 0xaccc, 0x0804,
-	0x4c2d, 0xaad4, 0xabd8, 0xacdc, 0x0804, 0x4c2d, 0x0016, 0x0026,
-	0x0036, 0x00b6, 0x00c6, 0x2009, 0x007e, 0x080c, 0x6644, 0x2019,
-	0x0001, 0xb85c, 0xd0ac, 0x0110, 0x2019, 0x0000, 0x2011, 0x801b,
-	0x080c, 0x4b29, 0x00ce, 0x00be, 0x003e, 0x002e, 0x001e, 0x0005,
-	0x0026, 0x080c, 0x56f5, 0xd0c4, 0x0120, 0x2011, 0x8014, 0x080c,
-	0x4b29, 0x002e, 0x0005, 0x81ff, 0x1904, 0x35b9, 0x0126, 0x2091,
-	0x8000, 0x6030, 0xc08d, 0xc085, 0xc0ac, 0x6032, 0x080c, 0x74ec,
-	0x1158, 0x080c, 0x77ef, 0x080c, 0x6044, 0x9085, 0x0001, 0x080c,
-	0x7533, 0x080c, 0x741d, 0x0010, 0x080c, 0x5eff, 0x012e, 0x0804,
-	0x3587, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x35b9, 0x080c,
-	0x5709, 0x0120, 0x2009, 0x0007, 0x0804, 0x35b9, 0x080c, 0x6a86,
-	0x0120, 0x2009, 0x0008, 0x0804, 0x35b9, 0x7984, 0x080c, 0x65e3,
-	0x1904, 0x35bc, 0x2b00, 0x7026, 0x080c, 0x6a8e, 0x7888, 0x1170,
-	0x9084, 0x0005, 0x1158, 0x900e, 0x080c, 0x6937, 0x1108, 0xc185,
-	0xb800, 0xd0bc, 0x0108, 0xc18d, 0x0804, 0x3587, 0x080c, 0x4ac9,
-	0x0904, 0x35b9, 0x9006, 0xa866, 0xa832, 0xa868, 0xc0fd, 0xa86a,
-	0x080c, 0xca9c, 0x0904, 0x35b9, 0x7888, 0xd094, 0x0118, 0xb8d4,
-	0xc08d, 0xb8d6, 0x7007, 0x0003, 0x701f, 0x4d9b, 0x0005, 0x2061,
-	0x1800, 0x080c, 0x5709, 0x2009, 0x0007, 0x1578, 0x080c, 0x6a86,
-	0x0118, 0x2009, 0x0008, 0x0448, 0x080c, 0x3377, 0x0120, 0xa998,
-	0x080c, 0x65e3, 0x1530, 0x080c, 0x4afa, 0x0518, 0x080c, 0x6a8e,
-	0xa89c, 0x1168, 0x9084, 0x0005, 0x1150, 0x900e, 0x080c, 0x6937,
-	0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x00d0, 0xa868,
-	0xc0fc, 0xa86a, 0x080c, 0xca9c, 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, 0x5652, 0x900e, 0x080c, 0x6937, 0x1108, 0xc185,
-	0xb800, 0xd0bc, 0x0108, 0xc18d, 0x0804, 0x3587, 0x080c, 0x5709,
-	0x0120, 0x2009, 0x0007, 0x0804, 0x35b9, 0x7f84, 0x7a8c, 0x7b88,
-	0x7c9c, 0x7d98, 0x080c, 0x4ac9, 0x1120, 0x2009, 0x0002, 0x0804,
-	0x35b9, 0x900e, 0x2130, 0x7126, 0x7132, 0xa860, 0x20e8, 0x7036,
-	0xa85c, 0x9080, 0x0005, 0x702a, 0x20a0, 0x080c, 0x6644, 0x1904,
-	0x4e3d, 0x080c, 0x6a8e, 0x0138, 0x080c, 0x6a96, 0x0120, 0x080c,
-	0x6a2e, 0x1904, 0x4e3d, 0xd794, 0x1110, 0xd784, 0x01a8, 0xb8c4,
-	0x20e0, 0xb8c8, 0x9080, 0x0006, 0x2098, 0x3400, 0xd794, 0x0160,
-	0x20a9, 0x0008, 0x4003, 0x2098, 0x20a0, 0x3d00, 0x20e0, 0x20a9,
-	0x0002, 0x080c, 0x48c8, 0x0048, 0x20a9, 0x0004, 0x4003, 0x2098,
-	0x20a0, 0x3d00, 0x20e0, 0x080c, 0x48c8, 0x9186, 0x007e, 0x0170,
-	0x9186, 0x0080, 0x0158, 0x080c, 0x6a8e, 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, 0x48bb, 0x9c80,
-	0x0026, 0x2098, 0xb8c4, 0x20e0, 0x20a9, 0x0002, 0x4003, 0xd794,
-	0x0110, 0x96b0, 0x000b, 0x96b0, 0x0005, 0x8108, 0x080c, 0xab5a,
-	0x0118, 0x9186, 0x0800, 0x0040, 0xd78c, 0x0120, 0x9186, 0x0800,
-	0x0170, 0x0018, 0x9186, 0x007e, 0x0150, 0xd794, 0x0118, 0x9686,
-	0x0020, 0x0010, 0x9686, 0x0028, 0x0150, 0x0804, 0x4dcd, 0x86ff,
-	0x1120, 0x7124, 0x810b, 0x0804, 0x3587, 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, 0x4e79,
-	0x0005, 0x7030, 0x9005, 0x1180, 0x7120, 0x7028, 0x20a0, 0x772c,
-	0x9036, 0x7034, 0x20e8, 0x2061, 0x18b8, 0x2c44, 0xa28c, 0xa390,
-	0xa494, 0xa598, 0x0804, 0x4dcd, 0x7124, 0x810b, 0x0804, 0x3587,
-	0x2029, 0x007e, 0x7984, 0x7a88, 0x7b8c, 0x7c98, 0x9184, 0xff00,
-	0x8007, 0x90e2, 0x0020, 0x0a04, 0x35bc, 0x9502, 0x0a04, 0x35bc,
-	0x9184, 0x00ff, 0x90e2, 0x0020, 0x0a04, 0x35bc, 0x9502, 0x0a04,
-	0x35bc, 0x9284, 0xff00, 0x8007, 0x90e2, 0x0020, 0x0a04, 0x35bc,
-	0x9502, 0x0a04, 0x35bc, 0x9284, 0x00ff, 0x90e2, 0x0020, 0x0a04,
-	0x35bc, 0x9502, 0x0a04, 0x35bc, 0x9384, 0xff00, 0x8007, 0x90e2,
-	0x0020, 0x0a04, 0x35bc, 0x9502, 0x0a04, 0x35bc, 0x9384, 0x00ff,
-	0x90e2, 0x0020, 0x0a04, 0x35bc, 0x9502, 0x0a04, 0x35bc, 0x9484,
-	0xff00, 0x8007, 0x90e2, 0x0020, 0x0a04, 0x35bc, 0x9502, 0x0a04,
-	0x35bc, 0x9484, 0x00ff, 0x90e2, 0x0020, 0x0a04, 0x35bc, 0x9502,
-	0x0a04, 0x35bc, 0x2061, 0x1988, 0x6102, 0x6206, 0x630a, 0x640e,
-	0x0804, 0x3587, 0x080c, 0x4ac9, 0x0904, 0x35b9, 0x2009, 0x0016,
-	0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xa85c, 0x9080, 0x0019, 0xaf60,
-	0x080c, 0x4b12, 0x701f, 0x4efd, 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, 0x4f7e, 0x6804,
-	0x2008, 0x918c, 0xfff8, 0x1904, 0x4f7e, 0x680c, 0x9005, 0x0904,
-	0x4f7e, 0x9082, 0xff01, 0x1a04, 0x4f7e, 0x6810, 0x9082, 0x005c,
-	0x0a04, 0x4f7e, 0x6824, 0x2008, 0x9082, 0x0008, 0x0a04, 0x4f7e,
-	0x9182, 0x0400, 0x1a04, 0x4f7e, 0x0056, 0x2029, 0x0000, 0x080c,
-	0x8d23, 0x005e, 0x6944, 0x6820, 0x9102, 0x06c0, 0x6820, 0x9082,
-	0x0019, 0x16a0, 0x6828, 0x6944, 0x810c, 0x9102, 0x0678, 0x6840,
-	0x9082, 0x000f, 0x1658, 0x080c, 0x1060, 0x2900, 0x0904, 0x4f98,
-	0x684e, 0x00e6, 0x2071, 0x1930, 0x00b6, 0x2059, 0x0000, 0x080c,
-	0x8bdf, 0x00be, 0x00ee, 0x0558, 0x080c, 0x8936, 0x080c, 0x897c,
-	0x11e0, 0x6857, 0x0000, 0x00c6, 0x2061, 0x0100, 0x6104, 0x918d,
-	0x2000, 0x6106, 0x6b10, 0x2061, 0x1a6a, 0x630a, 0x00ce, 0x080c,
-	0x2748, 0x2001, 0x0138, 0x2102, 0x0804, 0x3587, 0x080c, 0x2748,
-	0x2001, 0x0138, 0x2102, 0x0804, 0x35bc, 0x00e6, 0x2071, 0x1930,
-	0x080c, 0x8db4, 0x080c, 0x8dc3, 0x080c, 0x8bce, 0x00ee, 0x2001,
-	0x188a, 0x204c, 0x080c, 0x1079, 0x2001, 0x188a, 0x2003, 0x0000,
-	0x080c, 0x2748, 0x2001, 0x0138, 0x2102, 0x0804, 0x35b9, 0x2001,
-	0x1924, 0x200c, 0x918e, 0x0000, 0x0904, 0x4ff7, 0x080c, 0x8bc9,
-	0x0904, 0x4ff7, 0x2001, 0x0101, 0x200c, 0x918c, 0xdfff, 0x2102,
-	0x2001, 0x0138, 0x2003, 0x0000, 0x00e6, 0x2071, 0x0300, 0x701c,
-	0xd0a4, 0x1de8, 0x00ee, 0x080c, 0x8bce, 0x2001, 0x0035, 0x080c,
-	0x1693, 0x00c6, 0x2061, 0x193c, 0x6004, 0x6100, 0x9106, 0x1de0,
-	0x00ce, 0x080c, 0x2748, 0x2001, 0x0138, 0x2102, 0x00e6, 0x00f6,
-	0x2071, 0x1923, 0x080c, 0x8b0a, 0x0120, 0x2f00, 0x080c, 0x8b94,
-	0x0cc8, 0x00fe, 0x00ee, 0x0126, 0x2091, 0x8000, 0x2001, 0x188a,
-	0x200c, 0x81ff, 0x0138, 0x2148, 0x080c, 0x1079, 0x2001, 0x188a,
-	0x2003, 0x0000, 0x2001, 0x183d, 0x2003, 0x0020, 0x00e6, 0x2071,
-	0x1930, 0x080c, 0x8db4, 0x080c, 0x8dc3, 0x00ee, 0x012e, 0x0804,
-	0x3587, 0x0006, 0x080c, 0x56f5, 0xd0cc, 0x000e, 0x0005, 0x0006,
-	0x080c, 0x56f9, 0xd0bc, 0x000e, 0x0005, 0x6174, 0x7a84, 0x6300,
-	0x82ff, 0x1118, 0x7986, 0x0804, 0x3587, 0x83ff, 0x1904, 0x35bc,
-	0x2001, 0xfff0, 0x9200, 0x1a04, 0x35bc, 0x2019, 0xffff, 0x6078,
-	0x9302, 0x9200, 0x0a04, 0x35bc, 0x7986, 0x6276, 0x0804, 0x3587,
-	0x080c, 0x5709, 0x1904, 0x35b9, 0x7c88, 0x7d84, 0x7e98, 0x7f8c,
-	0x080c, 0x4ac9, 0x0904, 0x35b9, 0x900e, 0x901e, 0x7326, 0x7332,
-	0xa860, 0x20e8, 0x7036, 0xa85c, 0x9080, 0x0003, 0x702a, 0x20a0,
-	0x91d8, 0x1000, 0x2b5c, 0x8bff, 0x0178, 0x080c, 0x6a8e, 0x0118,
-	0x080c, 0x6a96, 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, 0x9181, 0x2208, 0x0804, 0x3587, 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,
-	0x507a, 0x0005, 0x7030, 0x9005, 0x1178, 0x7120, 0x7028, 0x20a0,
-	0x901e, 0x7034, 0x20e8, 0x2061, 0x18b8, 0x2c44, 0xa48c, 0xa590,
-	0xa694, 0xa798, 0x0804, 0x5038, 0x7224, 0x900e, 0x2001, 0x0003,
-	0x080c, 0x9181, 0x2208, 0x0804, 0x3587, 0x00f6, 0x00e6, 0x080c,
-	0x5709, 0x2009, 0x0007, 0x1904, 0x510d, 0x2071, 0x189e, 0x745c,
-	0x84ff, 0x2009, 0x000e, 0x1904, 0x510d, 0xac9c, 0xad98, 0xaea4,
-	0xafa0, 0x0096, 0x080c, 0x1060, 0x2009, 0x0002, 0x0904, 0x510d,
-	0x2900, 0x705e, 0x900e, 0x901e, 0x7356, 0x7362, 0xa860, 0x7066,
-	0xa85c, 0x9080, 0x0003, 0x705a, 0x20a0, 0x91d8, 0x1000, 0x2b5c,
-	0x8bff, 0x0178, 0x080c, 0x6a8e, 0x0118, 0x080c, 0x6a96, 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,
-	0x9181, 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, 0x5119, 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, 0x9181, 0xaa9a, 0x715c,
-	0x81ff, 0x090c, 0x0d7d, 0x2148, 0x080c, 0x1079, 0x705f, 0x0000,
-	0xa0a0, 0x2048, 0x0126, 0x2091, 0x8000, 0x080c, 0x6d9f, 0x012e,
-	0xa09f, 0x0000, 0xa0a3, 0x0000, 0x00ee, 0x00fe, 0x0005, 0x91d8,
-	0x1000, 0x2b5c, 0x8bff, 0x0178, 0x080c, 0x6a8e, 0x0118, 0x080c,
-	0x6a96, 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, 0x6d9f, 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,
-	0x35bc, 0xa884, 0xa988, 0x080c, 0x2630, 0x1518, 0x080c, 0x65e3,
-	0x1500, 0x7126, 0xbe12, 0xbd16, 0xae7c, 0x080c, 0x4ac9, 0x01c8,
-	0x080c, 0x4ac9, 0x01b0, 0x009e, 0xa867, 0x0000, 0xa868, 0xc0fd,
-	0xa86a, 0xa823, 0x0000, 0xa804, 0x2048, 0x080c, 0xca15, 0x1120,
-	0x2009, 0x0003, 0x0804, 0x35b9, 0x7007, 0x0003, 0x701f, 0x51e6,
-	0x0005, 0x009e, 0x2009, 0x0002, 0x0804, 0x35b9, 0x7124, 0x080c,
-	0x3318, 0xa820, 0x9086, 0x8001, 0x1120, 0x2009, 0x0004, 0x0804,
-	0x35b9, 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, 0x4b15, 0x97c6, 0x7200, 0x11b8, 0x96c2,
-	0x0054, 0x02a0, 0x000e, 0x007e, 0x2061, 0x18b8, 0x2c44, 0xa076,
-	0xa772, 0xa07b, 0x002a, 0xa28e, 0xa392, 0xa496, 0xa59a, 0x080c,
-	0x113c, 0x7007, 0x0002, 0x701f, 0x5242, 0x0005, 0x000e, 0x007e,
-	0x0804, 0x35bc, 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, 0x4b15, 0x81ff, 0x1904,
-	0x35b9, 0x798c, 0x2001, 0x197d, 0x918c, 0x8000, 0x2102, 0x080c,
-	0x4ae0, 0x0904, 0x35bc, 0x080c, 0x6a8e, 0x0120, 0x080c, 0x6a96,
-	0x1904, 0x35bc, 0x080c, 0x670b, 0x0904, 0x35b9, 0x0126, 0x2091,
-	0x8000, 0x080c, 0x68a4, 0x012e, 0x0904, 0x35b9, 0x2001, 0x197d,
-	0x2004, 0xd0fc, 0x1904, 0x3587, 0x0804, 0x4567, 0xa9a0, 0x2001,
-	0x197d, 0x918c, 0x8000, 0xc18d, 0x2102, 0x080c, 0x4aed, 0x01a0,
-	0x080c, 0x6a8e, 0x0118, 0x080c, 0x6a96, 0x1170, 0x080c, 0x670b,
-	0x2009, 0x0002, 0x0128, 0x080c, 0x68a4, 0x1170, 0x2009, 0x0003,
+	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,
+	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, 0x197d,
-	0x2004, 0xd0fc, 0x1128, 0x080c, 0x56fd, 0x0110, 0x9006, 0x0018,
-	0x900e, 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, 0x78a8, 0xd08c,
-	0x1118, 0xd084, 0x0904, 0x44dc, 0x080c, 0x4afc, 0x0904, 0x35bc,
-	0x080c, 0x4ac9, 0x1120, 0x2009, 0x0002, 0x0804, 0x35b9, 0x080c,
-	0x6a8e, 0x0130, 0x908e, 0x0004, 0x0118, 0x908e, 0x0005, 0x15a0,
-	0x78a8, 0xd08c, 0x0120, 0xb800, 0xc08c, 0xb802, 0x0028, 0x080c,
-	0x56f5, 0xd0b4, 0x0904, 0x4516, 0x7884, 0x908e, 0x007e, 0x0904,
-	0x4516, 0x908e, 0x007f, 0x0904, 0x4516, 0x908e, 0x0080, 0x0904,
-	0x4516, 0xb800, 0xd08c, 0x1904, 0x4516, 0xa867, 0x0000, 0xa868,
-	0xc0fd, 0xa86a, 0x080c, 0xca34, 0x1120, 0x2009, 0x0003, 0x0804,
-	0x35b9, 0x7007, 0x0003, 0x701f, 0x530e, 0x0005, 0x080c, 0x4afc,
-	0x0904, 0x35bc, 0x0804, 0x4516, 0x080c, 0x3377, 0x0108, 0x0005,
-	0x2009, 0x1834, 0x210c, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804,
-	0x35b9, 0x080c, 0x5709, 0x0120, 0x2009, 0x0007, 0x0804, 0x35b9,
-	0x080c, 0x6a86, 0x0120, 0x2009, 0x0008, 0x0804, 0x35b9, 0xb89c,
-	0xd0a4, 0x1118, 0xd0ac, 0x1904, 0x4516, 0x9006, 0xa866, 0xa832,
-	0xa868, 0xc0fd, 0xa86a, 0x080c, 0xca9c, 0x1120, 0x2009, 0x0003,
-	0x0804, 0x35b9, 0x7007, 0x0003, 0x701f, 0x5347, 0x0005, 0xa830,
-	0x9086, 0x0100, 0x1120, 0x2009, 0x0004, 0x0804, 0x5652, 0x080c,
-	0x4afc, 0x0904, 0x35bc, 0x0804, 0x52e0, 0x81ff, 0x2009, 0x0001,
-	0x1904, 0x35b9, 0x080c, 0x5709, 0x2009, 0x0007, 0x1904, 0x35b9,
-	0x080c, 0x6a86, 0x0120, 0x2009, 0x0008, 0x0804, 0x35b9, 0x080c,
-	0x4afc, 0x0904, 0x35bc, 0x080c, 0x6a8e, 0x2009, 0x0009, 0x1904,
-	0x35b9, 0x080c, 0x4ac9, 0x2009, 0x0002, 0x0904, 0x35b9, 0x9006,
-	0xa866, 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x7988, 0x9194, 0xff00,
-	0x918c, 0x00ff, 0x9006, 0x82ff, 0x1128, 0xc0ed, 0xa952, 0x798c,
-	0xa956, 0x0038, 0x928e, 0x0100, 0x1904, 0x35bc, 0xc0e5, 0xa952,
-	0xa956, 0xa83e, 0x080c, 0xccff, 0x2009, 0x0003, 0x0904, 0x35b9,
-	0x7007, 0x0003, 0x701f, 0x539d, 0x0005, 0xa830, 0x9086, 0x0100,
-	0x2009, 0x0004, 0x0904, 0x35b9, 0x0804, 0x3587, 0x7aa8, 0x9284,
-	0xc000, 0x0148, 0xd2ec, 0x01a0, 0x080c, 0x5709, 0x1188, 0x2009,
-	0x0014, 0x0804, 0x35b9, 0xd2dc, 0x1568, 0x81ff, 0x2009, 0x0001,
-	0x1904, 0x35b9, 0x080c, 0x5709, 0x2009, 0x0007, 0x1904, 0x35b9,
-	0xd2f4, 0x0130, 0x9284, 0x5000, 0x080c, 0x56d0, 0x0804, 0x3587,
-	0xd2fc, 0x0158, 0x080c, 0x4afc, 0x0904, 0x35bc, 0x7984, 0x9284,
-	0x9000, 0x080c, 0x56ad, 0x0804, 0x3587, 0x080c, 0x4afc, 0x0904,
-	0x35bc, 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, 0x2009, 0x0009,
-	0x1904, 0x5486, 0x080c, 0x4ac9, 0x2009, 0x0002, 0x0904, 0x5486,
+	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,
+	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,
+	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,
+	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,
+	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,
 	0xa85c, 0x9080, 0x001b, 0xaf60, 0x2009, 0x0008, 0x7a8c, 0x7b88,
-	0x7c9c, 0x7d98, 0x080c, 0x4b12, 0x701f, 0x53f7, 0x0005, 0xa86c,
+	0x7c9c, 0x7d98, 0x080c, 0x4b3b, 0x701f, 0x5427, 0x0005, 0xa86c,
 	0x9086, 0x0500, 0x1138, 0xa870, 0x9005, 0x1120, 0xa874, 0x9084,
-	0xff00, 0x0110, 0x1904, 0x35bc, 0xa866, 0xa832, 0xa868, 0xc0fd,
-	0xa86a, 0x080c, 0x4afc, 0x1110, 0x0804, 0x35bc, 0x2009, 0x0043,
-	0x080c, 0xcd67, 0x2009, 0x0003, 0x0904, 0x5486, 0x7007, 0x0003,
-	0x701f, 0x541b, 0x0005, 0xa830, 0x9086, 0x0100, 0x2009, 0x0004,
-	0x0904, 0x5486, 0x7984, 0x7aa8, 0x9284, 0x1000, 0x080c, 0x56ad,
-	0x0804, 0x3587, 0x00c6, 0xaab0, 0x9284, 0xc000, 0x0140, 0xd2ec,
-	0x0168, 0x080c, 0x5709, 0x1150, 0x2009, 0x0014, 0x04f0, 0x2061,
-	0x1800, 0x080c, 0x5709, 0x2009, 0x0007, 0x15b8, 0xd2f4, 0x0128,
-	0x9284, 0x5000, 0x080c, 0x56d0, 0x0050, 0xd2fc, 0x0178, 0x080c,
-	0x4afa, 0x0588, 0xa998, 0x9284, 0x9000, 0x080c, 0x56ad, 0xa87b,
-	0x0000, 0xa883, 0x0000, 0xa897, 0x4000, 0x0438, 0x080c, 0x4afa,
-	0x0510, 0x080c, 0x6a8e, 0x2009, 0x0009, 0x11b8, 0xa8c4, 0x9086,
-	0x0500, 0x11c8, 0xa8c8, 0x9005, 0x11b0, 0xa8cc, 0x9084, 0xff00,
-	0x1190, 0x080c, 0x4afa, 0x1108, 0x0070, 0x2009, 0x004b, 0x080c,
-	0xcd67, 0x2009, 0x0003, 0x0108, 0x0078, 0x0429, 0x19c0, 0xa897,
-	0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001,
-	0x2001, 0x0030, 0x00ce, 0x0005, 0x9006, 0x0ce0, 0x7aa8, 0xd2dc,
-	0x0904, 0x35b9, 0x0016, 0x7984, 0x9284, 0x1000, 0xc0fd, 0x080c,
-	0x56ad, 0x001e, 0x1904, 0x35b9, 0x0804, 0x3587, 0x00f6, 0x2d78,
-	0x0011, 0x00fe, 0x0005, 0xaab0, 0xd2dc, 0x0150, 0x0016, 0xa998,
-	0x9284, 0x1000, 0xc0fd, 0x080c, 0x56ad, 0x001e, 0x9085, 0x0001,
-	0x0005, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x35b9, 0x080c,
-	0x5709, 0x0120, 0x2009, 0x0007, 0x0804, 0x35b9, 0x7984, 0x7ea8,
-	0x96b4, 0x00ff, 0x080c, 0x6644, 0x1904, 0x35bc, 0x9186, 0x007f,
-	0x0138, 0x080c, 0x6a8e, 0x0120, 0x2009, 0x0009, 0x0804, 0x35b9,
-	0x080c, 0x4ac9, 0x1120, 0x2009, 0x0002, 0x0804, 0x35b9, 0xa867,
-	0x0000, 0xa868, 0xc0fd, 0xa86a, 0x2001, 0x0100, 0x8007, 0xa80a,
-	0x080c, 0xca4e, 0x1120, 0x2009, 0x0003, 0x0804, 0x35b9, 0x7007,
-	0x0003, 0x701f, 0x54e4, 0x0005, 0xa808, 0x8007, 0x9086, 0x0100,
-	0x1120, 0x2009, 0x0004, 0x0804, 0x35b9, 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, 0x4b15, 0x080c, 0x4ac9, 0x1120, 0x2009, 0x0002,
-	0x0804, 0x35b9, 0x7984, 0x9194, 0xff00, 0x918c, 0x00ff, 0x8217,
-	0x82ff, 0x1118, 0x7023, 0x19b2, 0x0040, 0x92c6, 0x0001, 0x1118,
-	0x7023, 0x19cc, 0x0010, 0x0804, 0x35bc, 0x2009, 0x001a, 0x7a8c,
-	0x7b88, 0x7c9c, 0x7d98, 0xa85c, 0x9080, 0x0019, 0xaf60, 0x080c,
-	0x4b12, 0x701f, 0x5534, 0x0005, 0x2001, 0x182e, 0x2003, 0x0001,
-	0xa85c, 0x9080, 0x0019, 0x2098, 0xa860, 0x20e0, 0x20a9, 0x001a,
-	0x7020, 0x20a0, 0x20e9, 0x0001, 0x4003, 0x0804, 0x3587, 0x080c,
-	0x4ac9, 0x1120, 0x2009, 0x0002, 0x0804, 0x35b9, 0x7984, 0x9194,
-	0xff00, 0x918c, 0x00ff, 0x8217, 0x82ff, 0x1118, 0x2099, 0x19b2,
-	0x0040, 0x92c6, 0x0001, 0x1118, 0x2099, 0x19cc, 0x0010, 0x0804,
-	0x35bc, 0xa85c, 0x9080, 0x0019, 0x20a0, 0xa860, 0x20e8, 0x20a9,
-	0x001a, 0x20e1, 0x0001, 0x4003, 0x2009, 0x001a, 0x7a8c, 0x7b88,
-	0x7c9c, 0x7d98, 0xa85c, 0x9080, 0x0019, 0xaf60, 0x0804, 0x4b15,
-	0x7884, 0x908a, 0x1000, 0x1a04, 0x35bc, 0x0126, 0x2091, 0x8000,
-	0x8003, 0x800b, 0x810b, 0x9108, 0x00c6, 0x2061, 0x1a02, 0x6142,
-	0x00ce, 0x012e, 0x0804, 0x3587, 0x00c6, 0x080c, 0x74ec, 0x1160,
-	0x080c, 0x77ef, 0x080c, 0x6044, 0x9085, 0x0001, 0x080c, 0x7533,
-	0x080c, 0x741d, 0x080c, 0x0d7d, 0x2061, 0x1800, 0x6030, 0xc09d,
-	0x6032, 0x080c, 0x5eff, 0x00ce, 0x0005, 0x00c6, 0x2001, 0x1800,
-	0x2004, 0x908e, 0x0000, 0x0904, 0x35b9, 0x7884, 0x9005, 0x0188,
-	0x7888, 0x2061, 0x199b, 0x2c0c, 0x2062, 0x080c, 0x2a17, 0x01a0,
-	0x080c, 0x2a1f, 0x0188, 0x080c, 0x2a27, 0x0170, 0x2162, 0x0804,
-	0x35bc, 0x2061, 0x0100, 0x6038, 0x9086, 0x0007, 0x1118, 0x2009,
-	0x0001, 0x0010, 0x2009, 0x0000, 0x7884, 0x9086, 0x0002, 0x1588,
-	0x2061, 0x0100, 0x6028, 0xc09c, 0x602a, 0x080c, 0xa899, 0x0026,
-	0x2011, 0x0003, 0x080c, 0xa1be, 0x2011, 0x0002, 0x080c, 0xa1c8,
-	0x002e, 0x080c, 0xa0b3, 0x0036, 0x901e, 0x080c, 0xa133, 0x003e,
-	0x080c, 0xa8b5, 0x60e3, 0x0000, 0x080c, 0xe74f, 0x080c, 0xe76a,
-	0x9085, 0x0001, 0x080c, 0x7533, 0x9006, 0x080c, 0x2a49, 0x2001,
-	0x1800, 0x2003, 0x0004, 0x0026, 0x2011, 0x0008, 0x080c, 0x2a83,
-	0x002e, 0x00ce, 0x0804, 0x3587, 0x81ff, 0x0120, 0x2009, 0x0001,
-	0x0804, 0x35b9, 0x080c, 0x5709, 0x0120, 0x2009, 0x0007, 0x0804,
-	0x35b9, 0x7984, 0x7ea8, 0x96b4, 0x00ff, 0x080c, 0x6644, 0x1904,
-	0x35bc, 0x9186, 0x007f, 0x0138, 0x080c, 0x6a8e, 0x0120, 0x2009,
-	0x0009, 0x0804, 0x35b9, 0x080c, 0x4ac9, 0x1120, 0x2009, 0x0002,
-	0x0804, 0x35b9, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x080c,
-	0xca51, 0x1120, 0x2009, 0x0003, 0x0804, 0x35b9, 0x7007, 0x0003,
-	0x701f, 0x563b, 0x0005, 0xa830, 0x9086, 0x0100, 0x1120, 0x2009,
-	0x0004, 0x0804, 0x35b9, 0xa8e0, 0xa866, 0xa834, 0x8007, 0x800c,
-	0xa85c, 0x9080, 0x000c, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xaf60,
-	0x0804, 0x4b15, 0xa898, 0x9086, 0x000d, 0x1904, 0x35b9, 0x2021,
-	0x4005, 0x0126, 0x2091, 0x8000, 0x0e04, 0x565f, 0x0010, 0x012e,
-	0x0cc0, 0x7c36, 0x9486, 0x4000, 0x0118, 0x7833, 0x0011, 0x0010,
-	0x7833, 0x0010, 0x7883, 0x4005, 0xa998, 0x7986, 0xa9a4, 0x799a,
-	0xa9a8, 0x799e, 0x080c, 0x4b05, 0x2091, 0x4080, 0x2001, 0x0089,
-	0x2004, 0xd084, 0x190c, 0x11ee, 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, 0xa076, 0xa060,
-	0xa072, 0xa07b, 0x0001, 0xa07f, 0x0002, 0xa06b, 0x0000, 0xa09f,
-	0x0000, 0x00ce, 0x012e, 0x0804, 0x3587, 0x0126, 0x2091, 0x8000,
-	0x00b6, 0x00c6, 0x90e4, 0xc000, 0x0128, 0x0006, 0x080c, 0xc8b2,
+	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,
+	0x0009, 0x11b8, 0xa8c4, 0x9086, 0x0500, 0x11c8, 0xa8c8, 0x9005,
+	0x11b0, 0xa8cc, 0x9084, 0xff00, 0x1190, 0x080c, 0x4b23, 0x1108,
+	0x0070, 0x2009, 0x004b, 0x080c, 0xce7e, 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,
+	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,
+	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,
+	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,
+	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,
+	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,
+	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,
+	0x8007, 0x800c, 0xa85c, 0x9080, 0x000c, 0x7a8c, 0x7b88, 0x7c9c,
+	0x7d98, 0xaf60, 0x0804, 0x4b3e, 0xa898, 0x9086, 0x000d, 0x1904,
+	0x35ea, 0x2021, 0x4005, 0x0126, 0x2091, 0x8000, 0x0e04, 0x5699,
+	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,
+	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,
+	0xa076, 0xa060, 0xa072, 0xa07b, 0x0001, 0xa07f, 0x0002, 0xa06b,
+	0x0000, 0xa09f, 0x0000, 0x00ce, 0x012e, 0x0804, 0x35b8, 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,
 	0x000e, 0x1198, 0xd0e4, 0x0160, 0x9180, 0x1000, 0x2004, 0x905d,
-	0x0160, 0x080c, 0x605e, 0x080c, 0xab5a, 0x0110, 0xb817, 0x0000,
+	0x0160, 0x080c, 0x60ac, 0x080c, 0xabe2, 0x0110, 0xb817, 0x0000,
 	0x9006, 0x00ce, 0x00be, 0x012e, 0x0005, 0x9085, 0x0001, 0x0cc8,
 	0x0126, 0x2091, 0x8000, 0x0156, 0x2010, 0x900e, 0x20a9, 0x0800,
-	0x0016, 0x9180, 0x1000, 0x2004, 0x9005, 0x0180, 0x9186, 0x007e,
-	0x0168, 0x9186, 0x007f, 0x0150, 0x9186, 0x0080, 0x0138, 0x9186,
-	0x00ff, 0x0120, 0x0026, 0x2200, 0x0801, 0x002e, 0x001e, 0x8108,
-	0x1f04, 0x56d8, 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, 0x35bc, 0x810c, 0x0016,
-	0x080c, 0x4ac9, 0x080c, 0x0f4f, 0x2100, 0x2238, 0x7d84, 0x7c88,
-	0x7b8c, 0x7a90, 0x001e, 0x080c, 0x4b12, 0x701f, 0x5730, 0x0005,
-	0x2079, 0x0000, 0x7d94, 0x7c98, 0x7ba8, 0x7aac, 0x79a4, 0x810c,
-	0x2061, 0x18b8, 0x2c44, 0xa770, 0xa074, 0x2071, 0x189e, 0x080c,
-	0x4b15, 0x701f, 0x5744, 0x0005, 0x2061, 0x18b8, 0x2c44, 0x0016,
-	0x0026, 0xa270, 0xa174, 0x080c, 0x0f57, 0x002e, 0x001e, 0x080c,
-	0x1004, 0x9006, 0xa802, 0xa806, 0x0804, 0x3587, 0x0126, 0x0156,
-	0x0136, 0x0146, 0x01c6, 0x01d6, 0x00c6, 0x00d6, 0x00e6, 0x00f6,
-	0x2061, 0x0100, 0x2069, 0x0200, 0x2071, 0x1800, 0x6044, 0xd0a4,
-	0x11e8, 0xd084, 0x0118, 0x080c, 0x58ff, 0x0068, 0xd08c, 0x0118,
-	0x080c, 0x5808, 0x0040, 0xd094, 0x0118, 0x080c, 0x57d8, 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, 0x5fc0,
-	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, 0x5ea2, 0x080c, 0x871b, 0x0005,
-	0x2001, 0x1869, 0x2004, 0xd08c, 0x0110, 0x705f, 0xffff, 0x7088,
-	0x9005, 0x1528, 0x2011, 0x5ea2, 0x080c, 0x8651, 0x6040, 0x9094,
-	0x0010, 0x9285, 0x0020, 0x6042, 0x20a9, 0x00c8, 0x6044, 0xd08c,
-	0x1168, 0x1f04, 0x57ee, 0x6242, 0x709b, 0x0000, 0x6040, 0x9094,
-	0x0010, 0x9285, 0x0080, 0x6042, 0x6242, 0x0048, 0x6242, 0x709b,
-	0x0000, 0x708f, 0x0000, 0x9006, 0x080c, 0x6049, 0x0000, 0x0005,
-	0x708c, 0x908a, 0x0003, 0x1a0c, 0x0d7d, 0x000b, 0x0005, 0x5812,
-	0x5863, 0x58fe, 0x00f6, 0x0016, 0x6900, 0x918c, 0x0800, 0x708f,
-	0x0001, 0x2001, 0x015d, 0x2003, 0x0000, 0x6803, 0x00fc, 0x20a9,
-	0x0004, 0x6800, 0x9084, 0x00fc, 0x0120, 0x1f04, 0x5821, 0x080c,
-	0x0d7d, 0x68a0, 0x68a2, 0x689c, 0x689e, 0x6898, 0x689a, 0xa001,
-	0x918d, 0x1600, 0x6902, 0x001e, 0x6837, 0x0020, 0x080c, 0x6025,
-	0x2079, 0x1d00, 0x7833, 0x1101, 0x7837, 0x0000, 0x20e1, 0x0001,
-	0x2099, 0x1805, 0x20e9, 0x0001, 0x20a1, 0x1d0e, 0x20a9, 0x0004,
-	0x4003, 0x080c, 0xa68e, 0x20e1, 0x0001, 0x2099, 0x1d00, 0x20e9,
-	0x0000, 0x20a1, 0x0240, 0x20a9, 0x0014, 0x4003, 0x60c3, 0x000c,
-	0x600f, 0x0000, 0x080c, 0x5ed3, 0x00fe, 0x9006, 0x7092, 0x6043,
-	0x0008, 0x6042, 0x0005, 0x00f6, 0x7090, 0x7093, 0x0000, 0x9025,
-	0x0904, 0x58db, 0x6020, 0xd0b4, 0x1904, 0x58d9, 0x71a0, 0x81ff,
-	0x0904, 0x58c7, 0x9486, 0x000c, 0x1904, 0x58d4, 0x9480, 0x0018,
-	0x8004, 0x20a8, 0x080c, 0x601e, 0x2011, 0x0260, 0x2019, 0x1d00,
-	0x220c, 0x2304, 0x9106, 0x11e8, 0x8210, 0x8318, 0x1f04, 0x5880,
-	0x6043, 0x0004, 0x2061, 0x0140, 0x605b, 0xbc94, 0x605f, 0xf0f0,
-	0x2061, 0x0100, 0x6043, 0x0006, 0x708f, 0x0002, 0x709b, 0x0002,
-	0x2009, 0x07d0, 0x2011, 0x5ea9, 0x080c, 0x871b, 0x080c, 0x6025,
-	0x04c0, 0x080c, 0x601e, 0x2079, 0x0260, 0x7930, 0x918e, 0x1101,
-	0x1558, 0x7834, 0x9005, 0x1540, 0x7900, 0x918c, 0x00ff, 0x1118,
-	0x7804, 0x9005, 0x0190, 0x080c, 0x601e, 0x2011, 0x026e, 0x2019,
-	0x1805, 0x20a9, 0x0004, 0x220c, 0x2304, 0x9102, 0x0230, 0x11a0,
-	0x8210, 0x8318, 0x1f04, 0x58bb, 0x0078, 0x70a3, 0x0000, 0x080c,
-	0x601e, 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, 0xa68e, 0x20e1, 0x0001, 0x2099, 0x1d00,
-	0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x0014, 0x4003, 0x60c3,
-	0x000c, 0x2011, 0x19f3, 0x2013, 0x0000, 0x7093, 0x0000, 0x60a3,
-	0x0056, 0x60a7, 0x9575, 0x080c, 0x9e42, 0x08d8, 0x0005, 0x7098,
-	0x908a, 0x001d, 0x1a0c, 0x0d7d, 0x000b, 0x0005, 0x5930, 0x5943,
-	0x596c, 0x598c, 0x59b2, 0x59e1, 0x5a07, 0x5a3f, 0x5a65, 0x5a93,
-	0x5ace, 0x5b06, 0x5b24, 0x5b4f, 0x5b71, 0x5b8c, 0x5b96, 0x5bca,
-	0x5bf0, 0x5c1f, 0x5c45, 0x5c7d, 0x5cc1, 0x5cfe, 0x5d1f, 0x5d78,
-	0x5d9a, 0x5dc8, 0x5dc8, 0x00c6, 0x2061, 0x1800, 0x6003, 0x0007,
-	0x2061, 0x0100, 0x6004, 0x9084, 0xfff9, 0x6006, 0x00ce, 0x0005,
+	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,
+	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, 0x0002, 0x709b, 0x0001, 0x2009, 0x07d0, 0x2011, 0x5ea9,
-	0x080c, 0x871b, 0x0005, 0x00f6, 0x7090, 0x9086, 0x0014, 0x1510,
-	0x6042, 0x6020, 0xd0b4, 0x11f0, 0x080c, 0x601e, 0x2079, 0x0260,
-	0x7a30, 0x9296, 0x1102, 0x11a0, 0x7834, 0x9005, 0x1188, 0x7a38,
-	0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x2011,
-	0x5ea9, 0x080c, 0x8651, 0x709b, 0x0010, 0x080c, 0x5b96, 0x0010,
-	0x7093, 0x0000, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x0003, 0x6043,
-	0x0004, 0x2011, 0x5ea9, 0x080c, 0x8651, 0x080c, 0x5fa2, 0x2079,
-	0x0240, 0x7833, 0x1102, 0x7837, 0x0000, 0x20a9, 0x0008, 0x9f88,
-	0x000e, 0x200b, 0x0000, 0x8108, 0x1f04, 0x5981, 0x60c3, 0x0014,
-	0x080c, 0x5ed3, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, 0x0500,
-	0x2011, 0x5ea9, 0x080c, 0x8651, 0x9086, 0x0014, 0x11b8, 0x080c,
-	0x601e, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1102, 0x1178, 0x7834,
-	0x9005, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110,
-	0x70c7, 0x0001, 0x709b, 0x0004, 0x0029, 0x0010, 0x080c, 0x5ffa,
-	0x00fe, 0x0005, 0x00f6, 0x709b, 0x0005, 0x080c, 0x5fa2, 0x2079,
-	0x0240, 0x7833, 0x1103, 0x7837, 0x0000, 0x080c, 0x601e, 0x080c,
-	0x6001, 0x1170, 0x7084, 0x9005, 0x1158, 0x715c, 0x9186, 0xffff,
-	0x0138, 0x2011, 0x0008, 0x080c, 0x5e56, 0x0168, 0x080c, 0x5fd7,
-	0x20a9, 0x0008, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000,
-	0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x5ed3, 0x00fe,
-	0x0005, 0x00f6, 0x7090, 0x9005, 0x0500, 0x2011, 0x5ea9, 0x080c,
-	0x8651, 0x9086, 0x0014, 0x11b8, 0x080c, 0x601e, 0x2079, 0x0260,
-	0x7a30, 0x9296, 0x1103, 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38,
-	0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x709b,
-	0x0006, 0x0029, 0x0010, 0x080c, 0x5ffa, 0x00fe, 0x0005, 0x00f6,
-	0x709b, 0x0007, 0x080c, 0x5fa2, 0x2079, 0x0240, 0x7833, 0x1104,
-	0x7837, 0x0000, 0x080c, 0x601e, 0x080c, 0x6001, 0x11b8, 0x7084,
-	0x9005, 0x11a0, 0x7164, 0x9186, 0xffff, 0x0180, 0x9180, 0x3388,
-	0x200d, 0x918c, 0xff00, 0x810f, 0x2011, 0x0008, 0x080c, 0x5e56,
-	0x0180, 0x080c, 0x4fff, 0x0110, 0x080c, 0x2699, 0x20a9, 0x0008,
-	0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e,
-	0x4003, 0x60c3, 0x0014, 0x080c, 0x5ed3, 0x00fe, 0x0005, 0x00f6,
-	0x7090, 0x9005, 0x0500, 0x2011, 0x5ea9, 0x080c, 0x8651, 0x9086,
-	0x0014, 0x11b8, 0x080c, 0x601e, 0x2079, 0x0260, 0x7a30, 0x9296,
-	0x1104, 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc, 0x0128,
-	0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x709b, 0x0008, 0x0029,
-	0x0010, 0x080c, 0x5ffa, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x0009,
-	0x080c, 0x5fa2, 0x2079, 0x0240, 0x7833, 0x1105, 0x7837, 0x0100,
-	0x080c, 0x6001, 0x1150, 0x7084, 0x9005, 0x1138, 0x080c, 0x5dc9,
-	0x1188, 0x9085, 0x0001, 0x080c, 0x2699, 0x20a9, 0x0008, 0x080c,
-	0x601e, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1,
-	0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x5ed3, 0x0010, 0x080c,
-	0x5923, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, 0x05a8, 0x2011,
-	0x5ea9, 0x080c, 0x8651, 0x9086, 0x0014, 0x1560, 0x080c, 0x601e,
-	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,
-	0x5b71, 0x0010, 0x080c, 0x5ffa, 0x00fe, 0x0005, 0x00f6, 0x709b,
-	0x000b, 0x2011, 0x1d0e, 0x20e9, 0x0001, 0x22a0, 0x20a9, 0x0040,
-	0x2019, 0xffff, 0x4304, 0x080c, 0x5fa2, 0x2079, 0x0240, 0x7833,
-	0x1106, 0x7837, 0x0000, 0x080c, 0x6001, 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, 0x5af3,
-	0x60c3, 0x0084, 0x080c, 0x5ed3, 0x00fe, 0x0005, 0x00f6, 0x7090,
-	0x9005, 0x01c0, 0x2011, 0x5ea9, 0x080c, 0x8651, 0x9086, 0x0084,
-	0x1178, 0x080c, 0x601e, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1106,
-	0x1138, 0x7834, 0x9005, 0x1120, 0x709b, 0x000c, 0x0029, 0x0010,
-	0x080c, 0x5ffa, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x000d, 0x080c,
-	0x5fa2, 0x2079, 0x0240, 0x7833, 0x1107, 0x7837, 0x0000, 0x080c,
-	0x601e, 0x20a9, 0x0040, 0x2011, 0x026e, 0x2009, 0x024e, 0x220e,
-	0x8210, 0x8108, 0x9186, 0x0260, 0x1150, 0x6810, 0x8000, 0x6812,
-	0x2009, 0x0240, 0x6814, 0x8000, 0x6816, 0x2011, 0x0260, 0x1f04,
-	0x5b37, 0x60c3, 0x0084, 0x080c, 0x5ed3, 0x00fe, 0x0005, 0x00f6,
-	0x7090, 0x9005, 0x01e0, 0x2011, 0x5ea9, 0x080c, 0x8651, 0x9086,
-	0x0084, 0x1198, 0x080c, 0x601e, 0x2079, 0x0260, 0x7a30, 0x9296,
-	0x1107, 0x1158, 0x7834, 0x9005, 0x1140, 0x7097, 0x0001, 0x080c,
-	0x5f74, 0x709b, 0x000e, 0x0029, 0x0010, 0x080c, 0x5ffa, 0x00fe,
-	0x0005, 0x918d, 0x0001, 0x080c, 0x6049, 0x709b, 0x000f, 0x7093,
-	0x0000, 0x2061, 0x0140, 0x605b, 0xbc85, 0x605f, 0xb5b5, 0x2061,
-	0x0100, 0x6043, 0x0005, 0x6043, 0x0004, 0x2009, 0x07d0, 0x2011,
-	0x5ea9, 0x080c, 0x8645, 0x0005, 0x7090, 0x9005, 0x0130, 0x2011,
-	0x5ea9, 0x080c, 0x8651, 0x709b, 0x0000, 0x0005, 0x709b, 0x0011,
-	0x080c, 0xa68e, 0x080c, 0x601e, 0x20e1, 0x0000, 0x2099, 0x0260,
-	0x20e9, 0x0000, 0x20a1, 0x0240, 0x7490, 0x9480, 0x0018, 0x9080,
-	0x0007, 0x9084, 0x03f8, 0x8004, 0x20a8, 0x4003, 0x080c, 0x6001,
-	0x11a0, 0x717c, 0x81ff, 0x0188, 0x900e, 0x7080, 0x9084, 0x00ff,
-	0x0160, 0x080c, 0x2630, 0x9186, 0x007e, 0x0138, 0x9186, 0x0080,
-	0x0120, 0x2011, 0x0008, 0x080c, 0x5e56, 0x60c3, 0x0014, 0x080c,
-	0x5ed3, 0x0005, 0x00f6, 0x7090, 0x9005, 0x0500, 0x2011, 0x5ea9,
-	0x080c, 0x8651, 0x9086, 0x0014, 0x11b8, 0x080c, 0x601e, 0x2079,
-	0x0260, 0x7a30, 0x9296, 0x1103, 0x1178, 0x7834, 0x9005, 0x1160,
+	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, 0x0012, 0x0029, 0x0010, 0x7093, 0x0000, 0x00fe, 0x0005,
-	0x00f6, 0x709b, 0x0013, 0x080c, 0x5fb0, 0x2079, 0x0240, 0x7833,
-	0x1103, 0x7837, 0x0000, 0x080c, 0x601e, 0x080c, 0x6001, 0x1170,
+	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, 0x5e56, 0x0168, 0x080c, 0x5fd7, 0x20a9, 0x0008,
+	0x0008, 0x080c, 0x5ea4, 0x0168, 0x080c, 0x6025, 0x20a9, 0x0008,
 	0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e,
-	0x4003, 0x60c3, 0x0014, 0x080c, 0x5ed3, 0x00fe, 0x0005, 0x00f6,
-	0x7090, 0x9005, 0x0500, 0x2011, 0x5ea9, 0x080c, 0x8651, 0x9086,
-	0x0014, 0x11b8, 0x080c, 0x601e, 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, 0x5fb0, 0x2079, 0x0240, 0x7833, 0x1104, 0x7837, 0x0000,
-	0x080c, 0x601e, 0x080c, 0x6001, 0x11b8, 0x7084, 0x9005, 0x11a0,
-	0x7164, 0x9186, 0xffff, 0x0180, 0x9180, 0x3388, 0x200d, 0x918c,
-	0xff00, 0x810f, 0x2011, 0x0008, 0x080c, 0x5e56, 0x0180, 0x080c,
-	0x4fff, 0x0110, 0x080c, 0x2699, 0x20a9, 0x0008, 0x20e1, 0x0000,
+	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,
+	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, 0x5ed3, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005,
-	0x05f0, 0x2011, 0x5ea9, 0x080c, 0x8651, 0x9086, 0x0014, 0x15a8,
-	0x080c, 0x601e, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1105, 0x1568,
-	0x7834, 0x9084, 0x0100, 0x2011, 0x0100, 0x921e, 0x1168, 0x9085,
-	0x0001, 0x080c, 0x6049, 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005,
-	0x1110, 0x70c7, 0x0001, 0x0080, 0x9005, 0x11b8, 0x7a38, 0xd2fc,
-	0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x9085, 0x0001,
-	0x080c, 0x6049, 0x7097, 0x0000, 0x7a38, 0xd2f4, 0x0110, 0x70df,
-	0x0008, 0x709b, 0x0016, 0x0029, 0x0010, 0x7093, 0x0000, 0x00fe,
-	0x0005, 0x080c, 0xa68e, 0x080c, 0x601e, 0x20e1, 0x0000, 0x2099,
-	0x0260, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x000e, 0x4003,
-	0x2011, 0x026d, 0x2204, 0x9084, 0x0100, 0x2011, 0x024d, 0x2012,
-	0x2011, 0x026e, 0x709b, 0x0017, 0x080c, 0x6001, 0x1150, 0x7084,
-	0x9005, 0x1138, 0x080c, 0x5dc9, 0x1188, 0x9085, 0x0001, 0x080c,
-	0x2699, 0x20a9, 0x0008, 0x080c, 0x601e, 0x20e1, 0x0000, 0x2099,
-	0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014,
-	0x080c, 0x5ed3, 0x0010, 0x080c, 0x5923, 0x0005, 0x00f6, 0x7090,
-	0x9005, 0x01d8, 0x2011, 0x5ea9, 0x080c, 0x8651, 0x9086, 0x0084,
-	0x1190, 0x080c, 0x601e, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1106,
-	0x1150, 0x7834, 0x9005, 0x1138, 0x9006, 0x080c, 0x6049, 0x709b,
-	0x0018, 0x0029, 0x0010, 0x7093, 0x0000, 0x00fe, 0x0005, 0x00f6,
-	0x709b, 0x0019, 0x080c, 0x5fb0, 0x2079, 0x0240, 0x7833, 0x1106,
-	0x7837, 0x0000, 0x080c, 0x601e, 0x2009, 0x026e, 0x2039, 0x1d0e,
-	0x20a9, 0x0040, 0x213e, 0x8738, 0x8108, 0x9186, 0x0280, 0x1128,
-	0x6814, 0x8000, 0x6816, 0x2009, 0x0260, 0x1f04, 0x5d32, 0x2039,
-	0x1d0e, 0x080c, 0x6001, 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, 0x5d65, 0x60c3, 0x0084, 0x080c, 0x5ed3, 0x00fe, 0x0005,
-	0x00f6, 0x7090, 0x9005, 0x01e0, 0x2011, 0x5ea9, 0x080c, 0x8651,
-	0x9086, 0x0084, 0x1198, 0x080c, 0x601e, 0x2079, 0x0260, 0x7a30,
-	0x9296, 0x1107, 0x1158, 0x7834, 0x9005, 0x1140, 0x7097, 0x0001,
-	0x080c, 0x5f74, 0x709b, 0x001a, 0x0029, 0x0010, 0x7093, 0x0000,
-	0x00fe, 0x0005, 0x9085, 0x0001, 0x080c, 0x6049, 0x709b, 0x001b,
-	0x080c, 0xa68e, 0x080c, 0x601e, 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, 0x5db1, 0x60c3, 0x0084, 0x080c, 0x5ed3, 0x0005,
-	0x0005, 0x0086, 0x0096, 0x2029, 0x1848, 0x252c, 0x20a9, 0x0008,
-	0x2041, 0x1d0e, 0x20e9, 0x0001, 0x28a0, 0x080c, 0x601e, 0x20e1,
-	0x0000, 0x2099, 0x026e, 0x4003, 0x20a9, 0x0008, 0x2011, 0x0007,
-	0xd5d4, 0x0108, 0x9016, 0x2800, 0x9200, 0x200c, 0x91a6, 0xffff,
-	0x1148, 0xd5d4, 0x0110, 0x8210, 0x0008, 0x8211, 0x1f04, 0x5de3,
-	0x0804, 0x5e52, 0x82ff, 0x1160, 0xd5d4, 0x0120, 0x91a6, 0x3fff,
-	0x0d90, 0x0020, 0x91a6, 0x3fff, 0x0904, 0x5e52, 0x918d, 0xc000,
-	0x20a9, 0x0010, 0x2019, 0x0001, 0xd5d4, 0x0110, 0x2019, 0x0010,
-	0x2120, 0xd5d4, 0x0110, 0x8423, 0x0008, 0x8424, 0x1240, 0xd5d4,
-	0x0110, 0x8319, 0x0008, 0x8318, 0x1f04, 0x5e09, 0x04d8, 0x23a8,
-	0x2021, 0x0001, 0x8426, 0x8425, 0x1f04, 0x5e1b, 0x2328, 0x8529,
-	0x92be, 0x0007, 0x0158, 0x0006, 0x2039, 0x0007, 0x2200, 0x973a,
-	0x000e, 0x27a8, 0x95a8, 0x0010, 0x1f04, 0x5e2a, 0x755e, 0x95c8,
-	0x3388, 0x292d, 0x95ac, 0x00ff, 0x7582, 0x6532, 0x6536, 0x0016,
-	0x2508, 0x080c, 0x2679, 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, 0x3388, 0x242d,
+	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,
-	0x2679, 0x001e, 0x60e7, 0x0000, 0x65ea, 0x7087, 0x0001, 0x9084,
-	0x0000, 0x0005, 0x00e6, 0x2071, 0x1800, 0x708b, 0x0000, 0x00ee,
-	0x0005, 0x00e6, 0x00f6, 0x2079, 0x0100, 0x2071, 0x0140, 0x080c,
-	0x5f63, 0x080c, 0x9e4f, 0x7004, 0x9084, 0x4000, 0x0110, 0x080c,
-	0x2a59, 0x0126, 0x2091, 0x8000, 0x2071, 0x1826, 0x2073, 0x0000,
-	0x7840, 0x0026, 0x0016, 0x2009, 0x00f7, 0x080c, 0x5fc0, 0x001e,
-	0x9094, 0x0010, 0x9285, 0x0080, 0x7842, 0x7a42, 0x002e, 0x012e,
-	0x00fe, 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000, 0x080c, 0x29b4,
-	0x0228, 0x2011, 0x0101, 0x2204, 0xc0c5, 0x2012, 0x2011, 0x19f3,
-	0x2013, 0x0000, 0x7093, 0x0000, 0x012e, 0x60a3, 0x0056, 0x60a7,
-	0x9575, 0x080c, 0x9e42, 0x6144, 0xd184, 0x0120, 0x7198, 0x918d,
-	0x2000, 0x0018, 0x718c, 0x918d, 0x1000, 0x2011, 0x1998, 0x2112,
-	0x2009, 0x07d0, 0x2011, 0x5ea9, 0x080c, 0x871b, 0x0005, 0x0016,
-	0x0026, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xa899, 0x080c,
-	0xab61, 0x080c, 0xa8b5, 0x2009, 0x00f7, 0x080c, 0x5fc0, 0x2061,
-	0x1a02, 0x900e, 0x611a, 0x611e, 0x6172, 0x6176, 0x2061, 0x1800,
-	0x6003, 0x0001, 0x2061, 0x0100, 0x6043, 0x0090, 0x6043, 0x0010,
-	0x2009, 0x1998, 0x200b, 0x0000, 0x2009, 0x002d, 0x2011, 0x5f2f,
-	0x080c, 0x8645, 0x012e, 0x00ce, 0x002e, 0x001e, 0x0005, 0x00e6,
-	0x0006, 0x0126, 0x2091, 0x8000, 0x0471, 0x2071, 0x0100, 0x080c,
-	0x9e4f, 0x2071, 0x0140, 0x7004, 0x9084, 0x4000, 0x0110, 0x080c,
-	0x2a59, 0x080c, 0x74f4, 0x0188, 0x080c, 0x750f, 0x1170, 0x080c,
-	0x77f9, 0x0016, 0x080c, 0x2748, 0x2001, 0x196c, 0x2102, 0x001e,
-	0x080c, 0x77f4, 0x080c, 0x741d, 0x0050, 0x2009, 0x0001, 0x080c,
-	0x2a35, 0x2001, 0x0001, 0x080c, 0x25d5, 0x080c, 0x5eff, 0x012e,
-	0x000e, 0x00ee, 0x0005, 0x2001, 0x180e, 0x2004, 0xd0bc, 0x0158,
-	0x0026, 0x0036, 0x2011, 0x8017, 0x2001, 0x1998, 0x201c, 0x080c,
-	0x4b29, 0x003e, 0x002e, 0x0005, 0x20a9, 0x0012, 0x20e9, 0x0001,
-	0x20a1, 0x1d80, 0x080c, 0x601e, 0x20e9, 0x0000, 0x2099, 0x026e,
-	0x0099, 0x20a9, 0x0020, 0x080c, 0x6018, 0x2099, 0x0260, 0x20a1,
-	0x1d92, 0x0051, 0x20a9, 0x000e, 0x080c, 0x601b, 0x2099, 0x0260,
-	0x20a1, 0x1db2, 0x0009, 0x0005, 0x0016, 0x0026, 0x3410, 0x3308,
-	0x2104, 0x8007, 0x2012, 0x8108, 0x8210, 0x1f04, 0x5f98, 0x002e,
-	0x001e, 0x0005, 0x080c, 0xa68e, 0x20e1, 0x0001, 0x2099, 0x1d00,
-	0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x000c, 0x4003, 0x0005,
-	0x080c, 0xa68e, 0x080c, 0x601e, 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, 0x6a8a, 0x0158, 0x9006, 0x2020, 0x2009, 0x002a,
-	0x080c, 0xe316, 0x2001, 0x180c, 0x200c, 0xc195, 0x2102, 0x2019,
-	0x002a, 0x900e, 0x080c, 0x31d4, 0x080c, 0xcf84, 0x0140, 0x0036,
-	0x2019, 0xffff, 0x2021, 0x0007, 0x080c, 0x4ce0, 0x003e, 0x004e,
-	0x001e, 0x0005, 0x080c, 0x5eff, 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, 0x6058, 0x015e, 0x0005, 0x00d6, 0x0036,
-	0x0156, 0x0136, 0x0146, 0x2069, 0x1847, 0x9006, 0xb802, 0xb8d6,
-	0xb807, 0x0707, 0xb80a, 0xb80e, 0xb812, 0x9198, 0x3388, 0x231d,
-	0x939c, 0x00ff, 0xbb16, 0x0016, 0x0026, 0xb886, 0x080c, 0xab5a,
-	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, 0x8ba9, 0x00ce,
-	0x090c, 0x8f4f, 0xb8af, 0x0000, 0x6814, 0x9084, 0x00ff, 0xb842,
-	0x014e, 0x013e, 0x015e, 0x003e, 0x00de, 0x0005, 0x0126, 0x2091,
-	0x8000, 0xa974, 0xae78, 0x9684, 0x3fff, 0x9082, 0x4000, 0x1a04,
-	0x6134, 0x9182, 0x0800, 0x1a04, 0x6138, 0x2001, 0x180c, 0x2004,
-	0x9084, 0x0003, 0x1904, 0x613e, 0x9188, 0x1000, 0x2104, 0x905d,
-	0x0198, 0xb804, 0x9084, 0x00ff, 0x908e, 0x0006, 0x1188, 0xb8a4,
-	0x900d, 0x1904, 0x6150, 0x080c, 0x650d, 0x9006, 0x012e, 0x0005,
-	0x2001, 0x0005, 0x900e, 0x04b8, 0x2001, 0x0028, 0x900e, 0x0498,
-	0x9082, 0x0006, 0x1290, 0x080c, 0xab5a, 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, 0x6a8e, 0x1990, 0xb800, 0xd0bc, 0x0978, 0x0804, 0x60f7,
-	0x080c, 0x68b3, 0x0904, 0x6100, 0x0804, 0x60fb, 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, 0x6a2e, 0x11d0, 0x080c, 0xab9a, 0x0570,
-	0x2b00, 0x6012, 0x2900, 0x6016, 0x6023, 0x0009, 0x602b, 0x0000,
-	0xa874, 0x908e, 0x00ff, 0x1110, 0x602b, 0x8000, 0x2009, 0x0043,
-	0x080c, 0xac8d, 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, 0x622c, 0x9188, 0x1000, 0x2104, 0x905d, 0x0904,
-	0x6204, 0xb8a0, 0x9086, 0x007f, 0x0178, 0x080c, 0x6a96, 0x0160,
-	0xa994, 0x81ff, 0x0130, 0x908e, 0x0004, 0x0130, 0x908e, 0x0005,
-	0x0118, 0x080c, 0x6a8e, 0x1598, 0xa87c, 0xd0fc, 0x01e0, 0xa894,
-	0x9005, 0x01c8, 0x2060, 0x0026, 0x2010, 0x080c, 0xc853, 0x002e,
-	0x1120, 0x2001, 0x0008, 0x0804, 0x622e, 0x6020, 0x9086, 0x000a,
-	0x0120, 0x2001, 0x0008, 0x0804, 0x622e, 0x601a, 0x6003, 0x0008,
-	0x2900, 0x6016, 0x0058, 0x080c, 0xab9a, 0x05e8, 0x2b00, 0x6012,
-	0x2900, 0x6016, 0x600b, 0xffff, 0x6023, 0x000a, 0x2009, 0x0003,
-	0x080c, 0xac8d, 0x9006, 0x0458, 0x2001, 0x0028, 0x0438, 0x9082,
-	0x0006, 0x1290, 0x080c, 0xab5a, 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, 0x62c3, 0x627e,
-	0x6295, 0x62c3, 0x62c3, 0x62c3, 0x62c3, 0x62c3, 0x2100, 0x9082,
-	0x007e, 0x1278, 0x080c, 0x65e3, 0x0148, 0x9046, 0xb810, 0x9306,
-	0x1904, 0x62cb, 0xb814, 0x9206, 0x15f0, 0x0028, 0xbb12, 0xba16,
-	0x0010, 0x080c, 0x49dc, 0x0150, 0x04b0, 0x080c, 0x6644, 0x1598,
-	0xb810, 0x9306, 0x1580, 0xb814, 0x9206, 0x1568, 0x080c, 0xab9a,
-	0x0530, 0x2b00, 0x6012, 0x080c, 0xccfe, 0x2900, 0x6016, 0x600b,
-	0xffff, 0x6023, 0x000a, 0xa878, 0x9086, 0x0001, 0x1170, 0x080c,
-	0x320f, 0x9006, 0x080c, 0x6580, 0x2001, 0x0002, 0x080c, 0x6594,
-	0x2001, 0x0200, 0xb86e, 0xb893, 0x0002, 0x2009, 0x0003, 0x080c,
-	0xac8d, 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, 0x64b6, 0x90c6,
-	0x0056, 0x0904, 0x64ba, 0x90c6, 0x0066, 0x0904, 0x64be, 0x90c6,
-	0x0067, 0x0904, 0x64c2, 0x90c6, 0x0068, 0x0904, 0x64c6, 0x90c6,
-	0x0071, 0x0904, 0x64ca, 0x90c6, 0x0074, 0x0904, 0x64ce, 0x90c6,
-	0x007c, 0x0904, 0x64d2, 0x90c6, 0x007e, 0x0904, 0x64d6, 0x90c6,
-	0x0037, 0x0904, 0x64da, 0x9016, 0x2079, 0x1800, 0xa974, 0x9186,
-	0x00ff, 0x0904, 0x64b1, 0x9182, 0x0800, 0x1a04, 0x64b1, 0x080c,
-	0x6644, 0x1198, 0xb804, 0x9084, 0x00ff, 0x9082, 0x0006, 0x1268,
-	0xa894, 0x90c6, 0x006f, 0x0148, 0x080c, 0xab5a, 0x1904, 0x649a,
-	0xb8a0, 0x9084, 0xff80, 0x1904, 0x649a, 0xa894, 0x90c6, 0x006f,
-	0x0158, 0x90c6, 0x005e, 0x0904, 0x63fa, 0x90c6, 0x0064, 0x0904,
-	0x6423, 0x2008, 0x0804, 0x63bc, 0xa998, 0xa8b0, 0x2040, 0x080c,
-	0xab5a, 0x1120, 0x9182, 0x007f, 0x0a04, 0x63bc, 0x9186, 0x00ff,
-	0x0904, 0x63bc, 0x9182, 0x0800, 0x1a04, 0x63bc, 0xaaa0, 0xab9c,
-	0x787c, 0x9306, 0x11a8, 0x7880, 0x0096, 0x924e, 0x1128, 0x2208,
-	0x2310, 0x009e, 0x0804, 0x63bc, 0x080c, 0xab5a, 0x1140, 0x99cc,
-	0xff00, 0x009e, 0x1128, 0x2208, 0x2310, 0x0804, 0x63bc, 0x009e,
-	0x080c, 0x49dc, 0x0904, 0x63c6, 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, 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, 0xab9a,
-	0x1130, 0x2001, 0x4005, 0x2009, 0x0003, 0x9016, 0x0c78, 0x2b00,
-	0x6012, 0x080c, 0xccfe, 0x2900, 0x6016, 0x6023, 0x0001, 0xa868,
-	0xd88c, 0x0108, 0xc0f5, 0xa86a, 0x0126, 0x2091, 0x8000, 0x080c,
-	0x320f, 0x012e, 0x9006, 0x080c, 0x6580, 0x2001, 0x0002, 0x080c,
-	0x6594, 0x2009, 0x0002, 0x080c, 0xac8d, 0xa8b0, 0xd094, 0x0118,
-	0xb8d4, 0xc08d, 0xb8d6, 0x9006, 0x9005, 0x012e, 0x00ee, 0x00fe,
-	0x00be, 0x0005, 0x080c, 0x5709, 0x0118, 0x2009, 0x0007, 0x00f8,
-	0xa998, 0xaeb0, 0x080c, 0x6644, 0x1904, 0x63b7, 0x9186, 0x007f,
-	0x0130, 0x080c, 0x6a8e, 0x0118, 0x2009, 0x0009, 0x0080, 0x0096,
-	0x080c, 0x1047, 0x1120, 0x009e, 0x2009, 0x0002, 0x0040, 0x2900,
-	0x009e, 0xa806, 0x080c, 0xca51, 0x19b0, 0x2009, 0x0003, 0x2001,
-	0x4005, 0x0804, 0x63be, 0xa998, 0xaeb0, 0x080c, 0x6644, 0x1904,
-	0x63b7, 0x0096, 0x080c, 0x1047, 0x1128, 0x009e, 0x2009, 0x0002,
-	0x0804, 0x6477, 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, 0x56f5, 0xd0b4, 0x1118, 0xa89b, 0x000b, 0x00e0, 0xb800,
-	0xd08c, 0x0118, 0xa89b, 0x000c, 0x00b0, 0x080c, 0x6a8e, 0x0118,
-	0xa89b, 0x0009, 0x0080, 0x080c, 0x5709, 0x0118, 0xa89b, 0x0007,
-	0x0050, 0x080c, 0xca34, 0x1904, 0x63f3, 0x2009, 0x0003, 0x2001,
-	0x4005, 0x0804, 0x63be, 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, 0xb114, 0x1904, 0x63f3, 0x2009,
-	0x0002, 0x08e8, 0x2001, 0x0028, 0x900e, 0x0804, 0x63f4, 0x2009,
-	0x180c, 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004, 0x0038, 0xd184,
-	0x0118, 0x2001, 0x0004, 0x0010, 0x2001, 0x0029, 0x900e, 0x0804,
-	0x63f4, 0x2001, 0x0029, 0x900e, 0x0804, 0x63f4, 0x080c, 0x37b6,
-	0x0804, 0x63f5, 0x080c, 0x542a, 0x0804, 0x63f5, 0x080c, 0x4592,
-	0x0804, 0x63f5, 0x080c, 0x460b, 0x0804, 0x63f5, 0x080c, 0x4667,
-	0x0804, 0x63f5, 0x080c, 0x4a9f, 0x0804, 0x63f5, 0x080c, 0x4d4f,
-	0x0804, 0x63f5, 0x080c, 0x5095, 0x0804, 0x63f5, 0x080c, 0x528e,
-	0x0804, 0x63f5, 0x080c, 0x39d4, 0x0804, 0x63f5, 0x00b6, 0xa974,
-	0xae78, 0x9684, 0x3fff, 0x9082, 0x4000, 0x1608, 0x9182, 0x0800,
-	0x1258, 0x9188, 0x1000, 0x2104, 0x905d, 0x0130, 0x080c, 0x6a8e,
-	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, 0x6574, 0xb888, 0x9005, 0x1904, 0x6574, 0xb838,
-	0xb93c, 0x9102, 0x1a04, 0x6574, 0x2b10, 0x080c, 0xabc7, 0x0904,
-	0x6570, 0x8108, 0xb93e, 0x6212, 0x2900, 0x6016, 0x6023, 0x0003,
-	0x600b, 0xffff, 0x6007, 0x0040, 0xa878, 0x605e, 0xa880, 0x9084,
-	0x00ff, 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, 0x174b, 0x601c, 0xc0bd, 0x601e, 0x0c38,
-	0xd0b4, 0x190c, 0x1c55, 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, 0x6a8a, 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, 0x0126, 0x00c6, 0x2091, 0x8000, 0x6210, 0x2258, 0xba04,
-	0x0006, 0x9086, 0x0006, 0x1168, 0xb89c, 0xd0a4, 0x0150, 0x080c,
-	0x6a86, 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,
-	0x605e, 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, 0xc865, 0x0110, 0x080c, 0x0ff9,
-	0x080c, 0xabf0, 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, 0x74ec, 0x1510,
-	0xb8a0, 0x9086, 0x007e, 0x0120, 0x080c, 0xab5a, 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, 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, 0x1079, 0xb8a7, 0x0000, 0x009e, 0x012e, 0x0005, 0x0096,
-	0x00c6, 0xb888, 0x9005, 0x1904, 0x67c8, 0xb8d0, 0x904d, 0x0904,
-	0x67c8, 0x080c, 0xabc7, 0x0904, 0x67c4, 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, 0x1c55, 0x2001, 0x8004, 0x6003, 0x0002,
-	0x6046, 0x2001, 0x0010, 0x2c08, 0x080c, 0xa88a, 0xb838, 0xba3c,
-	0x9202, 0x0a04, 0x6775, 0x0020, 0x82ff, 0x1110, 0xb88b, 0x0001,
-	0x00ce, 0x009e, 0x0005, 0x080c, 0x174b, 0x601c, 0xc0bd, 0x601e,
-	0x08e0, 0x00b6, 0x0096, 0x0016, 0x20a9, 0x0800, 0x900e, 0x0016,
-	0x080c, 0x6644, 0x1158, 0xb8d0, 0x904d, 0x0140, 0x3e00, 0x9086,
-	0x0002, 0x1118, 0xb800, 0xd0bc, 0x1108, 0x0041, 0x001e, 0x8108,
-	0x1f04, 0x67d7, 0x001e, 0x00be, 0x009e, 0x0005, 0x0096, 0x0016,
-	0xb8d0, 0x904d, 0x0188, 0xa800, 0xb8d2, 0x9005, 0x1108, 0xb8ce,
-	0x9006, 0xa802, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c,
-	0xcb68, 0x080c, 0x6d9f, 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, 0x9fbd, 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, 0x6937, 0x0128, 0x080c, 0xc926, 0x0010, 0x9085, 0x0001,
-	0x0005, 0x080c, 0x6937, 0x0128, 0x080c, 0xc8c7, 0x0010, 0x9085,
-	0x0001, 0x0005, 0x080c, 0x6937, 0x0128, 0x080c, 0xc923, 0x0010,
-	0x9085, 0x0001, 0x0005, 0x080c, 0x6937, 0x0128, 0x080c, 0xc8e6,
-	0x0010, 0x9085, 0x0001, 0x0005, 0x080c, 0x6937, 0x0128, 0x080c,
-	0xc967, 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,
+	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,
+	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, 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, 0x68d3, 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, 0x74ec, 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,
-	0x6644, 0x1168, 0xb804, 0x9084, 0xff00, 0x8007, 0x9096, 0x0004,
-	0x0118, 0x9086, 0x0006, 0x1118, 0xb800, 0xc0ed, 0xb802, 0x001e,
-	0x8108, 0x1f04, 0x695e, 0x015e, 0x080c, 0x6a4c, 0x0120, 0x2001,
-	0x1984, 0x200c, 0x0038, 0x2079, 0x1847, 0x7804, 0xd0a4, 0x0130,
-	0x2009, 0x07d0, 0x2011, 0x6989, 0x080c, 0x871b, 0x00fe, 0x00be,
-	0x0005, 0x00b6, 0x2011, 0x6989, 0x080c, 0x8651, 0x080c, 0x6a4c,
-	0x01d8, 0x2001, 0x107e, 0x2004, 0x2058, 0xb900, 0xc1ec, 0xb902,
-	0x080c, 0x6a8a, 0x0130, 0x2009, 0x07d0, 0x2011, 0x6989, 0x080c,
-	0x871b, 0x00e6, 0x2071, 0x1800, 0x9006, 0x707e, 0x7060, 0x7082,
-	0x080c, 0x2fe0, 0x00ee, 0x04d0, 0x0156, 0x00c6, 0x20a9, 0x007f,
-	0x900e, 0x0016, 0x080c, 0x6644, 0x1558, 0xb800, 0xd0ec, 0x0540,
-	0x0046, 0xbaa0, 0x2220, 0x9006, 0x2009, 0x0029, 0x080c, 0xe316,
-	0xb800, 0xc0e5, 0xc0ec, 0xb802, 0x080c, 0x6a86, 0x2001, 0x0707,
-	0x1128, 0xb804, 0x9084, 0x00ff, 0x9085, 0x0700, 0xb806, 0x080c,
-	0xa899, 0x2019, 0x0029, 0x080c, 0x93c6, 0x0076, 0x903e, 0x080c,
-	0x928f, 0x900e, 0x080c, 0xe038, 0x007e, 0x004e, 0x080c, 0xa8b5,
-	0x001e, 0x8108, 0x1f04, 0x69b1, 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, 0xb9c6, 0x908c, 0xffc0, 0xb9ca, 0xb8af, 0x0000, 0x2009,
-	0x00ff, 0x080c, 0x605e, 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, 0xb800, 0x00be, 0xd0bc, 0x0005, 0x0006, 0x0016,
-	0x0026, 0xb804, 0x908c, 0x00ff, 0x9196, 0x0006, 0x0188, 0x9196,
-	0x0004, 0x0170, 0x9196, 0x0005, 0x0158, 0x908c, 0xff00, 0x810f,
-	0x9196, 0x0006, 0x0128, 0x9196, 0x0004, 0x0110, 0x9196, 0x0005,
-	0x002e, 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, 0x0008, 0xc2fc, 0xba02, 0x002e, 0x012e, 0x0005, 0x2011,
-	0x1837, 0x2204, 0xd0cc, 0x0138, 0x2001, 0x1982, 0x200c, 0x2011,
-	0x6a7c, 0x080c, 0x871b, 0x0005, 0x2011, 0x6a7c, 0x080c, 0x8651,
-	0x2011, 0x1837, 0x2204, 0xc0cc, 0x2012, 0x0005, 0x080c, 0x56f5,
-	0xd0ac, 0x0005, 0x080c, 0x56f5, 0xd0a4, 0x0005, 0x0016, 0xb904,
-	0x9184, 0x00ff, 0x908e, 0x0006, 0x001e, 0x0005, 0x0016, 0xb904,
-	0x9184, 0xff00, 0x8007, 0x908e, 0x0006, 0x001e, 0x0005, 0x00b6,
-	0x00f6, 0x080c, 0xcf84, 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, 0x56f5,
-	0xd0fc, 0x1140, 0x080c, 0x56f5, 0x900e, 0xd09c, 0x0108, 0x8108,
-	0x7102, 0x00f8, 0x2001, 0x1867, 0x200c, 0x9184, 0x0007, 0x0002,
-	0x6aca, 0x6aca, 0x6aca, 0x6aca, 0x6aca, 0x6ae0, 0x6aee, 0x6aca,
-	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,
-	0x7861, 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, 0x6da4, 0x9286,
-	0x0003, 0x0904, 0x6c34, 0x9286, 0x0005, 0x0904, 0x6c34, 0x2071,
-	0x1877, 0xa87c, 0x9005, 0x0904, 0x6b95, 0x7140, 0xa868, 0x9102,
-	0x0a04, 0x6da4, 0xa878, 0xd084, 0x15d8, 0xa853, 0x0019, 0x2001,
-	0x8023, 0xa84e, 0x2071, 0x1910, 0x701c, 0x9005, 0x1904, 0x6f3b,
-	0x0e04, 0x6fa9, 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, 0x6c17,
-	0xa853, 0x001b, 0x2001, 0x8027, 0x0820, 0x7004, 0xd08c, 0x1904,
-	0x6da4, 0xa853, 0x001a, 0x2001, 0x8024, 0x0804, 0x6b59, 0x00e6,
-	0x0026, 0x2071, 0x1947, 0x7000, 0x9015, 0x0904, 0x6da4, 0x9286,
-	0x0003, 0x0904, 0x6c34, 0x9286, 0x0005, 0x0904, 0x6c34, 0xa84f,
-	0x8022, 0xa853, 0x0018, 0x0804, 0x6bfc, 0xa868, 0xd0fc, 0x11d8,
-	0x00e6, 0x0026, 0x2001, 0x1947, 0x2004, 0x9005, 0x0904, 0x6da4,
-	0xa87c, 0xd0bc, 0x1904, 0x6da4, 0xa978, 0xa874, 0x9105, 0x1904,
-	0x6da4, 0x2001, 0x1947, 0x2004, 0x0002, 0x6da4, 0x6bf8, 0x6c34,
-	0x6c34, 0x6da4, 0x6c34, 0x0005, 0xa868, 0xd0fc, 0x1500, 0x00e6,
-	0x0026, 0x2009, 0x1947, 0x210c, 0x81ff, 0x0904, 0x6da4, 0xa87c,
-	0xd0cc, 0x0904, 0x6da4, 0xa880, 0x9084, 0x00ff, 0x9086, 0x0001,
-	0x1904, 0x6da4, 0x9186, 0x0003, 0x0904, 0x6c34, 0x9186, 0x0005,
-	0x0904, 0x6c34, 0xa84f, 0x8021, 0xa853, 0x0017, 0x0028, 0x0005,
-	0xa84f, 0x8020, 0xa853, 0x0016, 0x2071, 0x1910, 0x701c, 0x9005,
-	0x1904, 0x6f3b, 0x0e04, 0x6fa9, 0x2071, 0x0000, 0xa84c, 0x7082,
-	0xa850, 0x7032, 0xa86c, 0x7086, 0x7036, 0xa870, 0x708a, 0x2091,
-	0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11ee, 0x2071,
-	0x1800, 0x2011, 0x0001, 0xa804, 0x900d, 0x702c, 0x1158, 0xa802,
-	0x2900, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x8566, 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,
-	0x6d29, 0x782c, 0x908c, 0x0780, 0x190c, 0x70f5, 0x8004, 0x8004,
-	0x8004, 0x9084, 0x0003, 0x0002, 0x6c52, 0x6d29, 0x6c77, 0x6cc4,
-	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, 0x8566, 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, 0x8566, 0x782c, 0x9094,
-	0x0780, 0x190c, 0x70f5, 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, 0x8566, 0x0804, 0x6c7e, 0x0096, 0x00e6, 0x7824, 0x2048,
-	0x2071, 0x1800, 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000,
-	0x70c2, 0x080c, 0x8566, 0x782c, 0x9094, 0x0780, 0x190c, 0x70f5,
-	0xd0a4, 0x1d60, 0x00ee, 0x782c, 0x9094, 0x0780, 0x190c, 0x70f5,
-	0xd09c, 0x11a0, 0x009e, 0x2900, 0x7822, 0xa804, 0x900d, 0x1560,
+	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,
+	0x6010, 0x2058, 0xb800, 0xc0ec, 0xb802, 0x00be, 0x0005, 0x00b6,
+	0x00c6, 0x0096, 0x080c, 0x1060, 0x090c, 0x0d7d, 0x2958, 0x009e,
+	0x2001, 0x196a, 0x2b02, 0x8b07, 0x8006, 0x8006, 0x908c, 0x003f,
+	0xb9c6, 0x908c, 0xffc0, 0xb9ca, 0xb8af, 0x0000, 0x2009, 0x00ff,
+	0x080c, 0x60ac, 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, 0xb800, 0x00be, 0xd0bc, 0x0005, 0x0006, 0x0016, 0x0026,
+	0xb804, 0x908c, 0x00ff, 0x9196, 0x0006, 0x0188, 0x9196, 0x0004,
+	0x0170, 0x9196, 0x0005, 0x0158, 0x908c, 0xff00, 0x810f, 0x9196,
+	0x0006, 0x0128, 0x9196, 0x0004, 0x0110, 0x9196, 0x0005, 0x002e,
+	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,
+	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,
+	0x00ff, 0x908e, 0x0006, 0x001e, 0x0005, 0x0016, 0xb904, 0x9184,
+	0xff00, 0x8007, 0x908e, 0x0006, 0x001e, 0x0005, 0x00b6, 0x00f6,
+	0x080c, 0xd09b, 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,
+	0x8020, 0xa853, 0x0016, 0x2071, 0x1910, 0x701c, 0x9005, 0x1904,
+	0x6f8a, 0x0e04, 0x6ff8, 0x2071, 0x0000, 0xa84c, 0x7082, 0xa850,
+	0x7032, 0xa86c, 0x7086, 0x7036, 0xa870, 0x708a, 0x2091, 0x4080,
+	0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11ee, 0x2071, 0x1800,
+	0x2011, 0x0001, 0xa804, 0x900d, 0x702c, 0x1158, 0xa802, 0x2900,
+	0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x85ce, 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, 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,
+	0x8005, 0x703e, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x9016, 0x702c,
 	0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e,
-	0x70c0, 0x9200, 0x70c2, 0x080c, 0x8566, 0x00fe, 0x002e, 0x00ee,
-	0x0005, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, 0x711a,
-	0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, 0x1904,
-	0x6d7e, 0x782c, 0x9094, 0x0780, 0x190c, 0x70f5, 0xd09c, 0x1198,
-	0x701c, 0x904d, 0x0180, 0x7010, 0x8001, 0x7012, 0x1108, 0x701a,
-	0xa800, 0x701e, 0x2900, 0x7822, 0x782c, 0x9094, 0x0780, 0x190c,
-	0x70f5, 0xd09c, 0x0d68, 0x782c, 0x9094, 0x0780, 0x190c, 0x70f5,
-	0xd0a4, 0x01b0, 0x00e6, 0x7824, 0x2048, 0x2071, 0x1800, 0x702c,
-	0xa802, 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, 0x8566,
-	0x782c, 0x9094, 0x0780, 0x190c, 0x70f5, 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, 0x8566,
-	0x00ee, 0x0804, 0x6d39, 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,
-	0x6eb9, 0x782c, 0x908c, 0x0780, 0x190c, 0x70f5, 0x8004, 0x8004,
-	0x8004, 0x9084, 0x0003, 0x0002, 0x6dc3, 0x6eb9, 0x6dde, 0x6e4c,
-	0x080c, 0x0d7d, 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, 0x8566, 0x0c60, 0x2071, 0x1800,
-	0x2900, 0x7822, 0xa804, 0x900d, 0x1904, 0x6e3b, 0x7830, 0xd0dc,
-	0x1120, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x7824, 0x00e6, 0x2071,
+	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, 0x8566, 0x782c, 0x9094, 0x0780,
-	0x190c, 0x70f5, 0xd0a4, 0x19c8, 0x0e04, 0x6e32, 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, 0x8566, 0x0804, 0x6ded, 0x0096, 0x00e6, 0x7824, 0x2048,
-	0x2071, 0x1800, 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000,
-	0x70c2, 0x080c, 0x8566, 0x782c, 0x9094, 0x0780, 0x190c, 0x70f5,
-	0xd0a4, 0x1d60, 0x00ee, 0x0e04, 0x6e8c, 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, 0x70f5,
-	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, 0x8566, 0x00fe, 0x002e, 0x00ee,
-	0x0005, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, 0x711a,
-	0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, 0x1904,
-	0x6f26, 0x782c, 0x9094, 0x0780, 0x190c, 0x70f5, 0xd09c, 0x11b0,
-	0x701c, 0x904d, 0x0198, 0xa84c, 0x9005, 0x1180, 0x7010, 0x8001,
-	0x7012, 0x1108, 0x701a, 0xa800, 0x701e, 0x2900, 0x7822, 0x782c,
-	0x9094, 0x0780, 0x190c, 0x70f5, 0xd09c, 0x0d50, 0x782c, 0x9094,
-	0x0780, 0x190c, 0x70f5, 0xd0a4, 0x05a8, 0x00e6, 0x7824, 0x2048,
-	0x2071, 0x1800, 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000,
-	0x70c2, 0x080c, 0x8566, 0x782c, 0x9094, 0x0780, 0x190c, 0x70f5,
-	0xd0a4, 0x1d60, 0x00ee, 0x0e04, 0x6f1f, 0x7838, 0x7938, 0x910e,
+	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,
+	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,
+	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,
-	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, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900,
-	0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x8566,
-	0x00ee, 0x0804, 0x6ec9, 0x2071, 0x1910, 0xa803, 0x0000, 0x2908,
-	0x7010, 0x8000, 0x7012, 0x7018, 0x904d, 0x711a, 0x0110, 0xa902,
-	0x0008, 0x711e, 0x2148, 0xa804, 0x900d, 0x1128, 0x1e04, 0x6f66,
+	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, 0x8566, 0x0e04, 0x6f50, 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, 0x70e1, 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, 0x8566,
-	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, 0x6ff4, 0x6ff5,
-	0x70e0, 0x6ff5, 0x0d7d, 0x70e0, 0x0005, 0x2001, 0x1947, 0x2004,
-	0x0002, 0x6fff, 0x6fff, 0x7079, 0x707a, 0x6fff, 0x707a, 0x0126,
-	0x2091, 0x8000, 0x1e0c, 0x7100, 0x701c, 0x904d, 0x0508, 0xa84c,
-	0x9005, 0x0904, 0x704a, 0x0e04, 0x7028, 0xa94c, 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, 0x70e1,
-	0x012e, 0x0804, 0x7078, 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,
-	0x70f5, 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, 0x1b4d, 0x210c, 0x9102, 0x1500, 0x0126, 0x2091, 0x8000,
-	0x2069, 0x0050, 0x693c, 0x6838, 0x9106, 0x0190, 0x0e04, 0x70ac,
-	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, 0x7166, 0x701c, 0x904d, 0x0540, 0x2001, 0x005b,
-	0x2004, 0x9094, 0x0780, 0x15c9, 0xd09c, 0x1500, 0x2071, 0x1910,
+	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,
+	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,
+	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, 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,
+	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,
+	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, 0x701c, 0x2048, 0x7010, 0x8001,
-	0x7012, 0xa800, 0x701e, 0x9005, 0x1108, 0x701a, 0x012e, 0x0005,
-	0x0005, 0x0126, 0x2091, 0x8000, 0x701c, 0x904d, 0x0160, 0x7010,
+	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,
-	0x080c, 0x1079, 0x0005, 0x012e, 0x0005, 0x2091, 0x8000, 0x0e04,
-	0x70f7, 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, 0x8566,
-	0x782c, 0x9094, 0x0780, 0x190c, 0x70f5, 0xd0a4, 0x19c8, 0x7838,
+	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, 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, 0x70f5,
-	0xd0a4, 0x0db8, 0x00e6, 0x2071, 0x1800, 0x7824, 0x2048, 0x702c,
-	0xa802, 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, 0x8566,
-	0x782c, 0x9094, 0x0780, 0x190c, 0x70f5, 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, 0x2a83, 0x002e, 0x0005, 0x7292, 0x7218,
-	0x7234, 0x725e, 0x7281, 0x72c1, 0x72d3, 0x7234, 0x72a9, 0x71d3,
-	0x7201, 0x71d2, 0x0005, 0x00d6, 0x2069, 0x0200, 0x6804, 0x9005,
-	0x1180, 0x6808, 0x9005, 0x1518, 0x709b, 0x0028, 0x2069, 0x198e,
-	0x2d04, 0x7002, 0x080c, 0x762d, 0x6028, 0x9085, 0x0600, 0x602a,
-	0x00b0, 0x709b, 0x0028, 0x2069, 0x198e, 0x2d04, 0x7002, 0x6028,
-	0x9085, 0x0600, 0x602a, 0x00e6, 0x0036, 0x0046, 0x0056, 0x2071,
-	0x1a6a, 0x080c, 0x1adf, 0x005e, 0x004e, 0x003e, 0x00ee, 0x00de,
-	0x0005, 0x00d6, 0x2069, 0x0200, 0x6804, 0x9005, 0x1178, 0x6808,
-	0x9005, 0x1160, 0x709b, 0x0028, 0x2069, 0x198e, 0x2d04, 0x7002,
-	0x080c, 0x76d0, 0x6028, 0x9085, 0x0600, 0x602a, 0x00de, 0x0005,
-	0x0006, 0x2001, 0x0090, 0x080c, 0x2a49, 0x000e, 0x6124, 0xd1e4,
-	0x1190, 0x080c, 0x7344, 0xd1d4, 0x1160, 0xd1dc, 0x1138, 0xd1cc,
-	0x0150, 0x709b, 0x0020, 0x080c, 0x7344, 0x0028, 0x709b, 0x001d,
-	0x0010, 0x709b, 0x001f, 0x0005, 0x2001, 0x0088, 0x080c, 0x2a49,
-	0x6124, 0xd1cc, 0x11e8, 0xd1dc, 0x11c0, 0xd1e4, 0x1198, 0x9184,
-	0x1e00, 0x11d8, 0x080c, 0x1b04, 0x60e3, 0x0001, 0x600c, 0xc0b4,
-	0x600e, 0x080c, 0x7518, 0x2001, 0x0080, 0x080c, 0x2a49, 0x709b,
-	0x0028, 0x0058, 0x709b, 0x001e, 0x0040, 0x709b, 0x001d, 0x0028,
-	0x709b, 0x0020, 0x0010, 0x709b, 0x001f, 0x0005, 0x080c, 0x1b04,
-	0x60e3, 0x0001, 0x600c, 0xc0b4, 0x600e, 0x080c, 0x7518, 0x2001,
-	0x0080, 0x080c, 0x2a49, 0x6124, 0xd1d4, 0x1180, 0xd1dc, 0x1158,
-	0xd1e4, 0x1130, 0x9184, 0x1e00, 0x1158, 0x709b, 0x0028, 0x0040,
-	0x709b, 0x001e, 0x0028, 0x709b, 0x001d, 0x0010, 0x709b, 0x001f,
-	0x0005, 0x2001, 0x00a0, 0x080c, 0x2a49, 0x6124, 0xd1dc, 0x1138,
-	0xd1e4, 0x0138, 0x080c, 0x1b04, 0x709b, 0x001e, 0x0010, 0x709b,
-	0x001d, 0x0005, 0x080c, 0x73cd, 0x6124, 0xd1dc, 0x1188, 0x080c,
-	0x7344, 0x0016, 0x080c, 0x1b04, 0x001e, 0xd1d4, 0x1128, 0xd1e4,
-	0x0138, 0x709b, 0x001e, 0x0020, 0x709b, 0x001f, 0x080c, 0x7344,
-	0x0005, 0x0006, 0x2001, 0x00a0, 0x080c, 0x2a49, 0x000e, 0x6124,
-	0xd1d4, 0x1160, 0xd1cc, 0x1150, 0xd1dc, 0x1128, 0xd1e4, 0x0140,
-	0x709b, 0x001e, 0x0028, 0x709b, 0x001d, 0x0010, 0x709b, 0x0021,
-	0x0005, 0x080c, 0x73cd, 0x6124, 0xd1d4, 0x1150, 0xd1dc, 0x1128,
-	0xd1e4, 0x0140, 0x709b, 0x001e, 0x0028, 0x709b, 0x001d, 0x0010,
-	0x709b, 0x001f, 0x0005, 0x0006, 0x2001, 0x0090, 0x080c, 0x2a49,
-	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, 0x74ec, 0x11f8, 0x2001, 0x180c,
-	0x200c, 0xd1b4, 0x01d0, 0xc1b4, 0x2102, 0x0026, 0x2011, 0x0200,
-	0x080c, 0x2a83, 0x002e, 0x080c, 0x2a2f, 0x6024, 0xd0cc, 0x0148,
-	0x2001, 0x00a0, 0x080c, 0x2a49, 0x080c, 0x77ef, 0x080c, 0x6044,
-	0x0428, 0x6028, 0xc0cd, 0x602a, 0x0408, 0x080c, 0x7506, 0x0150,
-	0x080c, 0x74fd, 0x1138, 0x2001, 0x0001, 0x080c, 0x25d5, 0x080c,
-	0x74c0, 0x00a0, 0x080c, 0x73ca, 0x0178, 0x2001, 0x0001, 0x080c,
-	0x25d5, 0x7098, 0x9086, 0x001e, 0x0120, 0x7098, 0x9086, 0x0022,
-	0x1118, 0x709b, 0x0025, 0x0010, 0x709b, 0x0021, 0x012e, 0x00ee,
-	0x00de, 0x00ce, 0x001e, 0x0005, 0x0026, 0x2011, 0x7355, 0x080c,
-	0x875d, 0x002e, 0x0016, 0x0026, 0x2009, 0x0064, 0x2011, 0x7355,
-	0x080c, 0x8754, 0x002e, 0x001e, 0x0005, 0x00e6, 0x00f6, 0x0016,
-	0x080c, 0x9e4f, 0x2071, 0x1800, 0x080c, 0x72ee, 0x001e, 0x00fe,
-	0x00ee, 0x0005, 0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6,
-	0x00f6, 0x0126, 0x080c, 0x9e4f, 0x2061, 0x0100, 0x2069, 0x0140,
-	0x2071, 0x1800, 0x2091, 0x8000, 0x6028, 0xc09c, 0x602a, 0x080c,
-	0xa899, 0x2011, 0x0003, 0x080c, 0xa1be, 0x2011, 0x0002, 0x080c,
-	0xa1c8, 0x080c, 0xa0b3, 0x080c, 0x8709, 0x0036, 0x901e, 0x080c,
-	0xa133, 0x003e, 0x080c, 0xa8b5, 0x60e3, 0x0000, 0x080c, 0xe74f,
-	0x080c, 0xe76a, 0x2009, 0x0004, 0x080c, 0x2a35, 0x080c, 0x294b,
-	0x2001, 0x1800, 0x2003, 0x0004, 0x2011, 0x0008, 0x080c, 0x2a83,
-	0x2011, 0x7355, 0x080c, 0x875d, 0x080c, 0x7506, 0x0118, 0x9006,
-	0x080c, 0x2a49, 0x080c, 0x0bc3, 0x2001, 0x0001, 0x080c, 0x25d5,
-	0x012e, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e,
-	0x0005, 0x0026, 0x00e6, 0x2011, 0x7362, 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, 0x2a49, 0x0156,
-	0x20a9, 0x002d, 0x1d04, 0x73da, 0x2091, 0x6000, 0x1f04, 0x73da,
-	0x015e, 0x00d6, 0x2069, 0x1800, 0x689c, 0x8001, 0x0220, 0x0118,
-	0x689e, 0x00de, 0x0005, 0x689f, 0x0014, 0x68ec, 0xd0dc, 0x0dc8,
-	0x6800, 0x9086, 0x0001, 0x1da8, 0x080c, 0x8769, 0x0c90, 0x00c6,
-	0x00d6, 0x00e6, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0x1800,
-	0x080c, 0x77fe, 0x2001, 0x196c, 0x2003, 0x0000, 0x9006, 0x709a,
-	0x60e2, 0x6886, 0x080c, 0x26a4, 0x9006, 0x080c, 0x2a49, 0x080c,
-	0x5eff, 0x0026, 0x2011, 0xffff, 0x080c, 0x2a83, 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, 0x74b0, 0x709b,
-	0x0022, 0x0040, 0x709b, 0x0021, 0x0028, 0x709b, 0x0023, 0x0010,
-	0x709b, 0x0024, 0x60e3, 0x0000, 0x6887, 0x0001, 0x2001, 0x0001,
-	0x080c, 0x26a4, 0x080c, 0xa899, 0x0026, 0x080c, 0xab61, 0x002e,
-	0x080c, 0xa8b5, 0x7000, 0x908e, 0x0004, 0x0118, 0x602b, 0x0028,
-	0x0010, 0x602b, 0x0020, 0x0156, 0x0126, 0x2091, 0x8000, 0x20a9,
-	0x0005, 0x6024, 0xd0ac, 0x0150, 0x012e, 0x015e, 0x080c, 0xcf84,
-	0x0118, 0x9006, 0x080c, 0x2a73, 0x0804, 0x74bc, 0x6800, 0x9084,
-	0x00a1, 0xc0bd, 0x6802, 0x080c, 0x2a2f, 0x6904, 0xd1d4, 0x1140,
-	0x2001, 0x0100, 0x080c, 0x2a49, 0x1f04, 0x7461, 0x080c, 0x7543,
-	0x012e, 0x015e, 0x080c, 0x74fd, 0x0170, 0x6044, 0x9005, 0x0130,
-	0x080c, 0x7543, 0x9006, 0x8001, 0x1df0, 0x0028, 0x6804, 0xd0d4,
-	0x1110, 0x080c, 0x7543, 0x080c, 0xcf84, 0x0118, 0x9006, 0x080c,
-	0x2a73, 0x0016, 0x0026, 0x7000, 0x908e, 0x0004, 0x0130, 0x2009,
-	0x00c8, 0x2011, 0x7362, 0x080c, 0x871b, 0x002e, 0x001e, 0x080c,
-	0x855d, 0x7034, 0xc085, 0x7036, 0x2001, 0x197c, 0x2003, 0x0004,
-	0x080c, 0x71b7, 0x080c, 0x74fd, 0x0138, 0x6804, 0xd0d4, 0x1120,
-	0xd0dc, 0x1100, 0x080c, 0x77f4, 0x00ee, 0x00de, 0x00ce, 0x0005,
+	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,
+	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,
+	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, 0x8574, 0x080c, 0x8566, 0x080c, 0x77fe, 0x2001,
-	0x196c, 0x2003, 0x0000, 0x9006, 0x709a, 0x60e2, 0x6886, 0x080c,
-	0x26a4, 0x9006, 0x080c, 0x2a49, 0x6043, 0x0090, 0x6043, 0x0010,
-	0x0026, 0x2011, 0xffff, 0x080c, 0x2a83, 0x002e, 0x602b, 0x182c,
-	0x00ee, 0x00de, 0x00ce, 0x0005, 0x0006, 0x2001, 0x197b, 0x2004,
-	0x9086, 0xaaaa, 0x000e, 0x0005, 0x0006, 0x080c, 0x56f9, 0x9084,
-	0x0030, 0x9086, 0x0000, 0x000e, 0x0005, 0x0006, 0x080c, 0x56f9,
-	0x9084, 0x0030, 0x9086, 0x0030, 0x000e, 0x0005, 0x0006, 0x080c,
-	0x56f9, 0x9084, 0x0030, 0x9086, 0x0010, 0x000e, 0x0005, 0x0006,
-	0x080c, 0x56f9, 0x9084, 0x0030, 0x9086, 0x0020, 0x000e, 0x0005,
-	0x0036, 0x0016, 0x2001, 0x180c, 0x2004, 0x908c, 0x0013, 0x0180,
-	0x0020, 0x080c, 0x26c4, 0x900e, 0x0028, 0x080c, 0x6a86, 0x1dc8,
-	0x2009, 0x0002, 0x2019, 0x0028, 0x080c, 0x31d4, 0x9006, 0x0019,
-	0x001e, 0x003e, 0x0005, 0x00e6, 0x2071, 0x180c, 0x2e04, 0x0130,
-	0x080c, 0xcf7d, 0x1128, 0x9085, 0x0010, 0x0010, 0x9084, 0xffef,
-	0x2072, 0x00ee, 0x0005, 0x6050, 0x0006, 0x60ec, 0x0006, 0x600c,
-	0x0006, 0x6004, 0x0006, 0x6028, 0x0006, 0x080c, 0x2aa6, 0x080c,
-	0x2ad9, 0x602f, 0x0100, 0x602f, 0x0000, 0x602f, 0x0040, 0x602f,
-	0x0000, 0x20a9, 0x0002, 0x080c, 0x2a10, 0x0026, 0x2011, 0x0040,
-	0x080c, 0x2a83, 0x002e, 0x000e, 0x602a, 0x000e, 0x6006, 0x000e,
-	0x600e, 0x000e, 0x60ee, 0x60e3, 0x0000, 0x6887, 0x0001, 0x2001,
-	0x0001, 0x080c, 0x26a4, 0x2001, 0x00a0, 0x0006, 0x080c, 0xcf84,
-	0x000e, 0x0130, 0x080c, 0x2a67, 0x9006, 0x080c, 0x2a73, 0x0010,
-	0x080c, 0x2a49, 0x000e, 0x6052, 0x6050, 0x0006, 0xc0e5, 0x6052,
-	0x00f6, 0x2079, 0x0100, 0x080c, 0x29bc, 0x00fe, 0x000e, 0x6052,
+	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,
+	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,
+	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,
+	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,
+	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, 0x2069, 0x0140, 0x2071, 0x1800, 0x080c, 0xa8f7,
-	0x0158, 0x2001, 0x0386, 0x2004, 0xd0b4, 0x1130, 0x2001, 0x0016,
-	0x080c, 0xa88a, 0x0804, 0x761f, 0x2001, 0x180c, 0x200c, 0xc1c4,
-	0x2102, 0x6028, 0x9084, 0xe1ff, 0x602a, 0x2011, 0x0200, 0x080c,
-	0x2a83, 0x2001, 0x0090, 0x080c, 0x2a49, 0x20a9, 0x0366, 0x6024,
-	0xd0cc, 0x1558, 0x1d04, 0x75bf, 0x2091, 0x6000, 0x1f04, 0x75bf,
-	0x080c, 0xa899, 0x2011, 0x0003, 0x080c, 0xa1be, 0x2011, 0x0002,
-	0x080c, 0xa1c8, 0x080c, 0xa0b3, 0x901e, 0x080c, 0xa133, 0x2001,
-	0x0386, 0x2003, 0x7000, 0x080c, 0xa8b5, 0x2001, 0x00a0, 0x080c,
-	0x2a49, 0x080c, 0x77ef, 0x080c, 0x6044, 0x080c, 0xcf84, 0x0110,
-	0x080c, 0x0ce9, 0x9085, 0x0001, 0x04c0, 0x080c, 0x1b04, 0x60e3,
-	0x0000, 0x2001, 0x196c, 0x2004, 0x080c, 0x26a4, 0x60e2, 0x2001,
-	0x0080, 0x080c, 0x2a49, 0x20a9, 0x0366, 0x2011, 0x1e00, 0x080c,
-	0x2a83, 0x2009, 0x1e00, 0x080c, 0x2a2f, 0x6024, 0x910c, 0x0140,
-	0x1d04, 0x75fd, 0x2091, 0x6000, 0x1f04, 0x75fd, 0x0804, 0x75c8,
-	0x2001, 0x0386, 0x2003, 0x7000, 0x6028, 0x9085, 0x1e00, 0x602a,
-	0x70b4, 0x9005, 0x1118, 0x6887, 0x0001, 0x0008, 0x6886, 0x080c,
-	0xcf84, 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, 0x7696, 0x2001, 0x0088, 0x080c, 0x2a49, 0x9006,
-	0x60e2, 0x6886, 0x080c, 0x26a4, 0x2069, 0x0200, 0x6804, 0x9005,
-	0x1118, 0x6808, 0x9005, 0x01d0, 0x6028, 0x9084, 0xfbff, 0x602a,
-	0x2011, 0x0400, 0x080c, 0x2a83, 0x2069, 0x198e, 0x7000, 0x206a,
-	0x709b, 0x0026, 0x7003, 0x0001, 0x20a9, 0x0002, 0x1d04, 0x7676,
-	0x2091, 0x6000, 0x1f04, 0x7676, 0x0804, 0x76c8, 0x2069, 0x0140,
-	0x20a9, 0x0384, 0x2011, 0x1e00, 0x080c, 0x2a83, 0x2009, 0x1e00,
-	0x080c, 0x2a2f, 0x6024, 0x910c, 0x0528, 0x9084, 0x1a00, 0x1510,
-	0x1d04, 0x7682, 0x2091, 0x6000, 0x1f04, 0x7682, 0x080c, 0xa899,
-	0x2011, 0x0003, 0x080c, 0xa1be, 0x2011, 0x0002, 0x080c, 0xa1c8,
-	0x080c, 0xa0b3, 0x901e, 0x080c, 0xa133, 0x080c, 0xa8b5, 0x2001,
-	0x00a0, 0x080c, 0x2a49, 0x080c, 0x77ef, 0x080c, 0x6044, 0x9085,
-	0x0001, 0x00b0, 0x2001, 0x0080, 0x080c, 0x2a49, 0x2069, 0x0140,
+	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,
 	0x60e3, 0x0000, 0x70b4, 0x9005, 0x1118, 0x6887, 0x0001, 0x0008,
-	0x6886, 0x2001, 0x196c, 0x2004, 0x080c, 0x26a4, 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,
-	0xa899, 0x2011, 0x0003, 0x080c, 0xa1be, 0x2011, 0x0002, 0x080c,
-	0xa1c8, 0x080c, 0xa0b3, 0x901e, 0x080c, 0xa133, 0x080c, 0xa8b5,
-	0x2069, 0x0140, 0x2001, 0x00a0, 0x080c, 0x2a49, 0x080c, 0x77ef,
-	0x080c, 0x6044, 0x0804, 0x776b, 0x2001, 0x180c, 0x200c, 0xd1b4,
-	0x1160, 0xc1b5, 0x2102, 0x080c, 0x734a, 0x2069, 0x0140, 0x2001,
-	0x0080, 0x080c, 0x2a49, 0x60e3, 0x0000, 0x2069, 0x0200, 0x6804,
-	0x9005, 0x1118, 0x6808, 0x9005, 0x0190, 0x6028, 0x9084, 0xfdff,
-	0x602a, 0x2011, 0x0200, 0x080c, 0x2a83, 0x2069, 0x198e, 0x7000,
-	0x206a, 0x709b, 0x0027, 0x7003, 0x0001, 0x0804, 0x776b, 0x2011,
-	0x1e00, 0x080c, 0x2a83, 0x2009, 0x1e00, 0x080c, 0x2a2f, 0x6024,
-	0x910c, 0x01c8, 0x9084, 0x1c00, 0x11b0, 0x1d04, 0x7727, 0x0006,
-	0x0016, 0x00c6, 0x00d6, 0x00e6, 0x080c, 0x85a5, 0x00ee, 0x00de,
-	0x00ce, 0x001e, 0x000e, 0x00e6, 0x2071, 0x1a02, 0x7070, 0x00ee,
-	0x9005, 0x19e8, 0x0400, 0x0026, 0x2011, 0x7362, 0x080c, 0x8651,
-	0x2011, 0x7355, 0x080c, 0x875d, 0x002e, 0x2069, 0x0140, 0x60e3,
-	0x0000, 0x70b4, 0x9005, 0x1118, 0x6887, 0x0001, 0x0008, 0x6886,
-	0x2001, 0x196c, 0x2004, 0x080c, 0x26a4, 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, 0xcf7d,
-	0x1904, 0x77d9, 0x7130, 0xd184, 0x1170, 0x080c, 0x337c, 0x0138,
-	0xc18d, 0x7132, 0x2011, 0x1848, 0x2214, 0xd2ac, 0x1120, 0x7030,
-	0xd08c, 0x0904, 0x77d9, 0x2011, 0x1848, 0x220c, 0xd1a4, 0x0538,
-	0x0016, 0x2019, 0x000e, 0x080c, 0xe286, 0x0156, 0x00b6, 0x20a9,
-	0x007f, 0x900e, 0x9186, 0x007e, 0x01a0, 0x9186, 0x0080, 0x0188,
-	0x080c, 0x6644, 0x1170, 0x2120, 0x9006, 0x0016, 0x2009, 0x000e,
-	0x080c, 0xe316, 0x2009, 0x0001, 0x2011, 0x0100, 0x080c, 0x8902,
-	0x001e, 0x8108, 0x1f04, 0x77a2, 0x00be, 0x015e, 0x001e, 0xd1ac,
-	0x1148, 0x0016, 0x2009, 0x0002, 0x2019, 0x0004, 0x080c, 0x31d4,
-	0x001e, 0x0078, 0x0156, 0x00b6, 0x20a9, 0x007f, 0x900e, 0x080c,
-	0x6644, 0x1110, 0x080c, 0x605e, 0x8108, 0x1f04, 0x77cf, 0x00be,
-	0x015e, 0x080c, 0x1b04, 0x080c, 0xa899, 0x080c, 0xab61, 0x080c,
-	0xa8b5, 0x60e3, 0x0000, 0x080c, 0x6044, 0x080c, 0x741d, 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, 0x7de7, 0x9006, 0x00ee,
-	0x0005, 0x900e, 0x0156, 0x20a9, 0x0006, 0x8003, 0x818d, 0x1f04,
-	0x7865, 0x015e, 0x0005, 0x2079, 0x0040, 0x2071, 0x18fa, 0x7004,
-	0x0002, 0x787b, 0x787c, 0x78c8, 0x7923, 0x7a33, 0x7879, 0x7879,
-	0x7a5d, 0x080c, 0x0d7d, 0x0005, 0x2079, 0x0040, 0x2001, 0x1dc0,
-	0x2003, 0x0000, 0x782c, 0x908c, 0x0780, 0x190c, 0x7ec9, 0xd0a4,
-	0x0578, 0x2001, 0x1dc0, 0x2004, 0x9082, 0x0080, 0x1648, 0x1d04,
-	0x7899, 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, 0x78b8, 0x7882, 0x78b8,
-	0x78b6, 0x78b8, 0x78b8, 0x78b8, 0x78b8, 0x78b8, 0x080c, 0x7923,
-	0x782c, 0xd09c, 0x090c, 0x7de7, 0x0005, 0x9082, 0x005a, 0x1218,
-	0x2100, 0x003b, 0x0c10, 0x080c, 0x7959, 0x0c90, 0x00e3, 0x08e8,
-	0x0005, 0x7959, 0x7959, 0x7959, 0x7959, 0x7959, 0x7959, 0x7959,
-	0x7959, 0x797b, 0x7959, 0x7959, 0x7959, 0x7959, 0x7959, 0x7959,
-	0x7959, 0x7959, 0x7959, 0x7959, 0x7959, 0x7959, 0x7959, 0x7959,
-	0x7959, 0x7959, 0x7959, 0x7959, 0x7959, 0x7965, 0x7959, 0x7b4e,
-	0x7959, 0x7959, 0x7959, 0x797b, 0x7959, 0x7965, 0x7b8f, 0x7bd0,
-	0x7c17, 0x7c2b, 0x7959, 0x7959, 0x797b, 0x7965, 0x798f, 0x7959,
-	0x7a07, 0x7cd6, 0x7cf1, 0x7959, 0x797b, 0x7959, 0x798f, 0x7959,
-	0x7959, 0x79fd, 0x7cf1, 0x7959, 0x7959, 0x7959, 0x7959, 0x7959,
-	0x7959, 0x7959, 0x7959, 0x7959, 0x79a3, 0x7959, 0x7959, 0x7959,
-	0x7959, 0x7959, 0x7959, 0x7959, 0x7959, 0x7959, 0x7e6d, 0x7959,
-	0x7e17, 0x7959, 0x7e17, 0x7959, 0x79b8, 0x7959, 0x7959, 0x7959,
-	0x7959, 0x7959, 0x7959, 0x2079, 0x0040, 0x7004, 0x9086, 0x0003,
-	0x1198, 0x782c, 0x080c, 0x7e10, 0xd0a4, 0x0170, 0x7824, 0x2048,
-	0x9006, 0xa802, 0xa806, 0xa864, 0x9084, 0x00ff, 0x908a, 0x001a,
-	0x1210, 0x002b, 0x0c50, 0x00e9, 0x080c, 0x7de7, 0x0005, 0x7959,
-	0x7965, 0x7b3a, 0x7959, 0x7965, 0x7959, 0x7965, 0x7965, 0x7959,
-	0x7965, 0x7b3a, 0x7965, 0x7965, 0x7965, 0x7965, 0x7965, 0x7959,
-	0x7965, 0x7b3a, 0x7959, 0x7959, 0x7965, 0x7959, 0x7959, 0x7959,
-	0x7965, 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,
-	0x6d9f, 0x012e, 0x0005, 0xa864, 0x8007, 0x9084, 0x00ff, 0x0d08,
-	0x8001, 0x1120, 0x7007, 0x0001, 0x0804, 0x7adc, 0x7007, 0x0003,
-	0x7012, 0x2900, 0x7016, 0x701a, 0x704b, 0x7adc, 0x0005, 0xa864,
-	0x8007, 0x9084, 0x00ff, 0x0968, 0x8001, 0x1120, 0x7007, 0x0001,
-	0x0804, 0x7af7, 0x7007, 0x0003, 0x7012, 0x2900, 0x7016, 0x701a,
-	0x704b, 0x7af7, 0x0005, 0xa864, 0x8007, 0x9084, 0x00ff, 0x0904,
-	0x7961, 0x8001, 0x1120, 0x7007, 0x0001, 0x0804, 0x7b13, 0x7007,
-	0x0003, 0x7012, 0x2900, 0x7016, 0x701a, 0x704b, 0x7b13, 0x0005,
-	0xa864, 0x8007, 0x9084, 0x00ff, 0x9086, 0x0001, 0x1904, 0x7961,
-	0x7007, 0x0001, 0x2009, 0x1834, 0x210c, 0x81ff, 0x11a8, 0xa868,
-	0x9084, 0x00ff, 0xa86a, 0xa883, 0x0000, 0x080c, 0x62d4, 0x1108,
-	0x0005, 0x0126, 0x2091, 0x8000, 0xa867, 0x0139, 0xa87a, 0xa982,
-	0x080c, 0x6d9f, 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, 0x7d08, 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,
-	0x7969, 0xaab4, 0x928a, 0x0002, 0x1a04, 0x7969, 0x82ff, 0x1138,
-	0xa8b8, 0xa9bc, 0x9105, 0x0118, 0x2001, 0x7a9a, 0x0018, 0x9280,
-	0x7a90, 0x2005, 0x7056, 0x7010, 0x9015, 0x0904, 0x7a7b, 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, 0x7969, 0x7020,
-	0x2048, 0x7018, 0xa802, 0xa807, 0x0000, 0x2908, 0x2048, 0xa906,
-	0x711a, 0x0804, 0x7a33, 0x7014, 0x2048, 0x7007, 0x0001, 0xa8b4,
-	0x9005, 0x1128, 0xa8b8, 0xa9bc, 0x9105, 0x0108, 0x00b9, 0xa864,
-	0x9084, 0x00ff, 0x9086, 0x001e, 0x0904, 0x7d08, 0x0804, 0x7adc,
-	0x7a92, 0x7a96, 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, 0x60d6, 0x1108, 0x0005, 0x080c, 0x6fd3, 0x0126,
-	0x2091, 0x8000, 0x080c, 0xcb68, 0x080c, 0x6d9f, 0x012e, 0x0ca0,
-	0x080c, 0xcf7d, 0x1d70, 0x2001, 0x0028, 0x900e, 0x0c70, 0x2009,
-	0x1834, 0x210c, 0x81ff, 0x1188, 0xa888, 0x9005, 0x0188, 0xa883,
-	0x0000, 0x080c, 0x6164, 0x1108, 0x0005, 0xa87a, 0x0126, 0x2091,
-	0x8000, 0x080c, 0x6d9f, 0x012e, 0x0cb8, 0x2001, 0x0028, 0x0ca8,
-	0x2001, 0x0000, 0x0c90, 0x2009, 0x1834, 0x210c, 0x81ff, 0x11d8,
-	0xa888, 0x9005, 0x01e0, 0xa883, 0x0000, 0xa87c, 0xd0f4, 0x0120,
-	0x080c, 0x6236, 0x1138, 0x0005, 0x9006, 0xa87a, 0x080c, 0x61b1,
-	0x1108, 0x0005, 0x0126, 0x2091, 0x8000, 0xa87a, 0xa982, 0x080c,
-	0x6d9f, 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, 0x6644,
-	0x11b8, 0x0066, 0xae80, 0x080c, 0x6754, 0x006e, 0x0088, 0x0046,
-	0x2011, 0x180c, 0x2224, 0xc484, 0x2412, 0x004e, 0x00c6, 0x080c,
-	0x6644, 0x1110, 0x080c, 0x6927, 0x8108, 0x1f04, 0x7b77, 0x00ce,
-	0xa87c, 0xd084, 0x1120, 0x080c, 0x1079, 0x00be, 0x0005, 0x0126,
-	0x2091, 0x8000, 0x080c, 0x6d9f, 0x012e, 0x00be, 0x0005, 0x0126,
-	0x2091, 0x8000, 0x7007, 0x0001, 0x080c, 0x6a8a, 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, 0x7dd1, 0x012e,
-	0x0804, 0x7dcb, 0x012e, 0x0804, 0x7dc5, 0x012e, 0x0804, 0x7dc8,
-	0x0126, 0x2091, 0x8000, 0x7007, 0x0001, 0x080c, 0x6a8a, 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,
-	0x7dd1, 0x012e, 0x0804, 0x7dce, 0x012e, 0x0804, 0x7dcb, 0x0126,
-	0x2091, 0x8000, 0x7007, 0x0001, 0x2061, 0x1a6e, 0x6300, 0xd38c,
-	0x1120, 0x6308, 0x8318, 0x0220, 0x630a, 0x012e, 0x0804, 0x7ddf,
-	0x012e, 0x0804, 0x7dce, 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, 0xac2b, 0x0068, 0x6017, 0xf400, 0x6063, 0x0000,
-	0xa97c, 0xd1a4, 0x0110, 0xa980, 0x6162, 0x2009, 0x0041, 0x080c,
-	0xac8d, 0xa988, 0x918c, 0xff00, 0x9186, 0x2000, 0x1138, 0x0026,
-	0x900e, 0x2011, 0xfdff, 0x080c, 0x8902, 0x002e, 0xa87c, 0xd0c4,
-	0x0148, 0x2061, 0x1a6e, 0x6000, 0xd08c, 0x1120, 0x6008, 0x8000,
-	0x0208, 0x600a, 0x00ce, 0x012e, 0x00be, 0x0804, 0x7dd1, 0x00ce,
-	0x012e, 0x00be, 0x0804, 0x7dcb, 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, 0x6644,
-	0x1968, 0xb800, 0xc0e4, 0xb802, 0x0848, 0xa88c, 0x9065, 0x09b8,
-	0x6007, 0x0024, 0x2001, 0x1985, 0x2004, 0x601a, 0x0804, 0x7c66,
-	0xa88c, 0x9065, 0x0960, 0x00e6, 0xa890, 0x9075, 0x2001, 0x1834,
-	0x2004, 0x9005, 0x0150, 0x080c, 0xac2b, 0x8eff, 0x0118, 0x2e60,
-	0x080c, 0xac2b, 0x00ee, 0x0804, 0x7c66, 0x6024, 0xc0dc, 0xc0d5,
-	0x6026, 0x2e60, 0x6007, 0x003a, 0xa8a0, 0x9005, 0x0130, 0x6007,
-	0x003b, 0xa8a4, 0x602e, 0xa8a8, 0x6016, 0x6003, 0x0001, 0x2009,
-	0x8020, 0x080c, 0x9239, 0x00ee, 0x0804, 0x7c66, 0x2061, 0x1a6e,
-	0x6000, 0xd084, 0x0190, 0xd08c, 0x1904, 0x7ddf, 0x0126, 0x2091,
-	0x8000, 0x6204, 0x8210, 0x0220, 0x6206, 0x012e, 0x0804, 0x7ddf,
-	0x012e, 0xa883, 0x0016, 0x0804, 0x7dd8, 0xa883, 0x0007, 0x0804,
-	0x7dd8, 0xa864, 0x8007, 0x9084, 0x00ff, 0x0130, 0x8001, 0x1138,
-	0x7007, 0x0001, 0x0069, 0x0005, 0x080c, 0x7961, 0x0040, 0x7007,
-	0x0003, 0x7012, 0x2900, 0x7016, 0x701a, 0x704b, 0x7d08, 0x0005,
-	0x00b6, 0x00e6, 0x0126, 0x2091, 0x8000, 0x903e, 0x2061, 0x1800,
-	0x61d0, 0x81ff, 0x1904, 0x7d8a, 0x6130, 0xd194, 0x1904, 0x7db4,
-	0xa878, 0x2070, 0x9e82, 0x1ddc, 0x0a04, 0x7d7e, 0x6068, 0x9e02,
-	0x1a04, 0x7d7e, 0x7120, 0x9186, 0x0006, 0x1904, 0x7d70, 0x7010,
-	0x905d, 0x0904, 0x7d8a, 0xb800, 0xd0e4, 0x1904, 0x7dae, 0x2061,
-	0x1a6e, 0x6100, 0x9184, 0x0301, 0x9086, 0x0001, 0x15a0, 0x7024,
-	0xd0dc, 0x1904, 0x7db7, 0xa883, 0x0000, 0xa803, 0x0000, 0x2908,
-	0x7014, 0x9005, 0x1198, 0x7116, 0xa87c, 0xd0f4, 0x1904, 0x7dba,
-	0x080c, 0x56f5, 0xd09c, 0x1118, 0xa87c, 0xc0cc, 0xa87e, 0x2e60,
-	0x080c, 0x87f2, 0x012e, 0x00ee, 0x00be, 0x0005, 0x2048, 0xa800,
-	0x9005, 0x1de0, 0xa902, 0x2148, 0xa87c, 0xd0f4, 0x1904, 0x7dba,
-	0x012e, 0x00ee, 0x00be, 0x0005, 0x012e, 0x00ee, 0xa883, 0x0006,
-	0x00be, 0x0804, 0x7dd8, 0xd184, 0x0db8, 0xd1c4, 0x1190, 0x00a0,
-	0xa974, 0x080c, 0x6644, 0x15d0, 0xb800, 0xd0e4, 0x15b8, 0x7120,
-	0x9186, 0x0007, 0x1118, 0xa883, 0x0002, 0x0490, 0xa883, 0x0008,
-	0x0478, 0xa883, 0x000e, 0x0460, 0xa883, 0x0017, 0x0448, 0xa883,
-	0x0035, 0x0430, 0x080c, 0x56f9, 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, 0x7d14, 0x7003,
-	0x0002, 0x0804, 0x7d14, 0xa883, 0x0028, 0x0010, 0xa883, 0x0029,
-	0x012e, 0x00ee, 0x00be, 0x0420, 0xa883, 0x002a, 0x0cc8, 0xa883,
-	0x0045, 0x0cb0, 0x2e60, 0x2019, 0x0002, 0x601b, 0x0014, 0x080c,
-	0xde67, 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, 0x6d9f, 0x012e, 0x0005, 0x080c,
-	0x1079, 0x0005, 0x00d6, 0x080c, 0x87e9, 0x00de, 0x0005, 0x00d6,
-	0x00e6, 0x0126, 0x2091, 0x8000, 0x2071, 0x0040, 0x702c, 0xd084,
-	0x01d8, 0x908c, 0x0780, 0x190c, 0x7ec9, 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, 0x7ec9, 0x000e, 0x0005, 0xa898,
-	0x9084, 0x0003, 0x05a8, 0x080c, 0xab9a, 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,
-	0x2630, 0x1540, 0x00b6, 0x080c, 0x6644, 0x2b00, 0x00be, 0x1510,
-	0x6012, 0x6023, 0x0001, 0x2009, 0x0040, 0xa864, 0x9084, 0x00ff,
-	0x9086, 0x0035, 0x0110, 0x2009, 0x0041, 0x080c, 0xac8d, 0x0005,
-	0xa87b, 0x0101, 0x0126, 0x2091, 0x8000, 0x080c, 0x6d9f, 0x012e,
-	0x0005, 0xa87b, 0x002c, 0x0126, 0x2091, 0x8000, 0x080c, 0x6d9f,
-	0x012e, 0x0005, 0xa87b, 0x0028, 0x0126, 0x2091, 0x8000, 0x080c,
-	0x6d9f, 0x012e, 0x080c, 0xabf0, 0x0005, 0x00d6, 0x00c6, 0x0036,
-	0x0026, 0x0016, 0x00b6, 0x7007, 0x0001, 0xaa74, 0x9282, 0x0004,
-	0x1a04, 0x7eba, 0xa97c, 0x9188, 0x1000, 0x2104, 0x905d, 0xb804,
-	0xd284, 0x0140, 0x05e8, 0x8007, 0x9084, 0x00ff, 0x9084, 0x0006,
-	0x1108, 0x04b0, 0x2b10, 0x080c, 0xab9a, 0x1118, 0x080c, 0xac60,
-	0x05a8, 0x6212, 0xa874, 0x0002, 0x7e98, 0x7e9d, 0x7ea0, 0x7ea6,
-	0x2019, 0x0002, 0x080c, 0xe286, 0x0060, 0x080c, 0xe216, 0x0048,
-	0x2019, 0x0002, 0xa980, 0x080c, 0xe235, 0x0018, 0xa980, 0x080c,
-	0xe216, 0x080c, 0xabf0, 0xa887, 0x0000, 0x0126, 0x2091, 0x8000,
-	0x080c, 0x6d9f, 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, 0x7ecb, 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, 0x1622, 0x00fe, 0x0005, 0x2001, 0x020d, 0x2003, 0x0020,
-	0x781f, 0x0300, 0x00fe, 0x0005, 0x781c, 0xd08c, 0x0904, 0x7f4c,
-	0x68c0, 0x90aa, 0x0005, 0x0a04, 0x855d, 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,
-	0xe727, 0x080c, 0x8444, 0x7817, 0x0140, 0x00a8, 0x9584, 0x0076,
-	0x1118, 0x080c, 0x84a0, 0x19c8, 0xd5a4, 0x0148, 0x0046, 0x0056,
-	0x080c, 0x7f9c, 0x080c, 0x213e, 0x005e, 0x004e, 0x0020, 0x080c,
-	0xe727, 0x7817, 0x0140, 0x080c, 0x74ec, 0x0168, 0x2001, 0x0111,
-	0x2004, 0xd08c, 0x0140, 0x6893, 0x0000, 0x2001, 0x0110, 0x2003,
-	0x0008, 0x2003, 0x0000, 0x0489, 0x0005, 0x0002, 0x7f59, 0x8266,
-	0x7f56, 0x7f56, 0x7f56, 0x7f56, 0x7f56, 0x7f56, 0x7817, 0x0140,
-	0x0005, 0x7000, 0x908c, 0xff00, 0x9194, 0xf000, 0x810f, 0x9484,
-	0x0fff, 0x6892, 0x9286, 0x2000, 0x1150, 0x6800, 0x9086, 0x0001,
-	0x1118, 0x080c, 0x5756, 0x0070, 0x080c, 0x7fbc, 0x0058, 0x9286,
-	0x3000, 0x1118, 0x080c, 0x81a3, 0x0028, 0x9286, 0x8000, 0x1110,
-	0x080c, 0x837a, 0x7817, 0x0140, 0x0005, 0x2001, 0x1810, 0x2004,
-	0xd08c, 0x0178, 0x2001, 0x1800, 0x2004, 0x9086, 0x0003, 0x1148,
-	0x0026, 0x0036, 0x2011, 0x8048, 0x2518, 0x080c, 0x4b29, 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, 0x4b29, 0x002e, 0x00fe,
-	0x005e, 0x004e, 0x003e, 0x0005, 0x00b6, 0x00c6, 0x7010, 0x9084,
-	0xff00, 0x8007, 0x9096, 0x0001, 0x0120, 0x9096, 0x0023, 0x1904,
-	0x8174, 0x9186, 0x0023, 0x15c0, 0x080c, 0x840f, 0x0904, 0x8174,
-	0x6120, 0x9186, 0x0001, 0x0150, 0x9186, 0x0004, 0x0138, 0x9186,
-	0x0008, 0x0120, 0x9186, 0x000a, 0x1904, 0x8174, 0x7124, 0x610a,
-	0x7030, 0x908e, 0x0200, 0x1130, 0x2009, 0x0015, 0x080c, 0xac8d,
-	0x0804, 0x8174, 0x908e, 0x0214, 0x0118, 0x908e, 0x0210, 0x1130,
-	0x2009, 0x0015, 0x080c, 0xac8d, 0x0804, 0x8174, 0x908e, 0x0100,
-	0x1904, 0x8174, 0x7034, 0x9005, 0x1904, 0x8174, 0x2009, 0x0016,
-	0x080c, 0xac8d, 0x0804, 0x8174, 0x9186, 0x0022, 0x1904, 0x8174,
-	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, 0x2679, 0x7932, 0x7936, 0x001e, 0x000e, 0x00fe,
-	0x080c, 0x2630, 0x695e, 0x703c, 0x00e6, 0x2071, 0x0140, 0x7086,
-	0x2071, 0x1800, 0x70b6, 0x00ee, 0x7034, 0x9005, 0x1904, 0x8174,
-	0x2009, 0x0017, 0x0804, 0x8124, 0x908e, 0x0400, 0x1190, 0x7034,
-	0x9005, 0x1904, 0x8174, 0x080c, 0x74ec, 0x0120, 0x2009, 0x001d,
-	0x0804, 0x8124, 0x68dc, 0xc0a5, 0x68de, 0x2009, 0x0030, 0x0804,
-	0x8124, 0x908e, 0x0500, 0x1140, 0x7034, 0x9005, 0x1904, 0x8174,
-	0x2009, 0x0018, 0x0804, 0x8124, 0x908e, 0x2010, 0x1120, 0x2009,
-	0x0019, 0x0804, 0x8124, 0x908e, 0x2110, 0x1120, 0x2009, 0x001a,
-	0x0804, 0x8124, 0x908e, 0x5200, 0x1140, 0x7034, 0x9005, 0x1904,
-	0x8174, 0x2009, 0x001b, 0x0804, 0x8124, 0x908e, 0x5000, 0x1140,
-	0x7034, 0x9005, 0x1904, 0x8174, 0x2009, 0x001c, 0x0804, 0x8124,
-	0x908e, 0x1300, 0x1120, 0x2009, 0x0034, 0x0804, 0x8124, 0x908e,
-	0x1200, 0x1140, 0x7034, 0x9005, 0x1904, 0x8174, 0x2009, 0x0024,
-	0x0804, 0x8124, 0x908c, 0xff00, 0x918e, 0x2400, 0x1170, 0x2009,
-	0x002d, 0x2001, 0x1810, 0x2004, 0xd09c, 0x0904, 0x8124, 0x080c,
-	0xd68f, 0x1904, 0x8174, 0x0804, 0x8122, 0x908c, 0xff00, 0x918e,
-	0x5300, 0x1120, 0x2009, 0x002a, 0x0804, 0x8124, 0x908e, 0x0f00,
-	0x1120, 0x2009, 0x0020, 0x0804, 0x8124, 0x908e, 0x6104, 0x1530,
-	0x2029, 0x0205, 0x2011, 0x026d, 0x8208, 0x2204, 0x9082, 0x0004,
-	0x8004, 0x8004, 0x20a8, 0x2011, 0x8015, 0x211c, 0x8108, 0x0046,
-	0x2124, 0x080c, 0x4b29, 0x004e, 0x8108, 0x0f04, 0x80d8, 0x9186,
-	0x0280, 0x1d88, 0x2504, 0x8000, 0x202a, 0x2009, 0x0260, 0x0c58,
-	0x202b, 0x0000, 0x2009, 0x0023, 0x0804, 0x8124, 0x908e, 0x6000,
-	0x1120, 0x2009, 0x003f, 0x0804, 0x8124, 0x908e, 0x5400, 0x1138,
-	0x080c, 0x850d, 0x1904, 0x8174, 0x2009, 0x0046, 0x04a8, 0x908e,
-	0x5500, 0x1148, 0x080c, 0x8535, 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, 0x2630, 0x1904, 0x8177, 0x080c, 0x65e3,
-	0x1904, 0x8177, 0xbe12, 0xbd16, 0x001e, 0x0016, 0x080c, 0x74ec,
-	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, 0xab9a, 0x01a8, 0x2b08, 0x6112, 0x6023, 0x0004,
-	0x7120, 0x610a, 0x001e, 0x9186, 0x004c, 0x1110, 0x6023, 0x000a,
-	0x0016, 0x001e, 0x080c, 0xac8d, 0x00ce, 0x00be, 0x0005, 0x001e,
-	0x0cd8, 0x2001, 0x180e, 0x2004, 0xd0ec, 0x0120, 0x2011, 0x8049,
-	0x080c, 0x4b29, 0x080c, 0xac60, 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, 0x9240, 0x08a0, 0x080c, 0x3346, 0x1140, 0x7010, 0x9084,
-	0xff00, 0x8007, 0x908e, 0x0008, 0x1108, 0x0009, 0x0005, 0x00b6,
-	0x00c6, 0x0046, 0x7000, 0x908c, 0xff00, 0x810f, 0x9186, 0x0033,
-	0x11e8, 0x080c, 0x840f, 0x0904, 0x81fe, 0x7124, 0x610a, 0x7030,
-	0x908e, 0x0200, 0x1140, 0x7034, 0x9005, 0x15c0, 0x2009, 0x0015,
-	0x080c, 0xac8d, 0x0498, 0x908e, 0x0100, 0x1580, 0x7034, 0x9005,
-	0x1568, 0x2009, 0x0016, 0x080c, 0xac8d, 0x0440, 0x9186, 0x0032,
-	0x1528, 0x7030, 0x908e, 0x1400, 0x1508, 0x2009, 0x0038, 0x0016,
-	0x2011, 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x2630, 0x11a8,
-	0x080c, 0x65e3, 0x1190, 0xbe12, 0xbd16, 0x080c, 0xab9a, 0x0168,
-	0x2b08, 0x6112, 0x080c, 0xccfe, 0x6023, 0x0004, 0x7120, 0x610a,
-	0x001e, 0x080c, 0xac8d, 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, 0x8260, 0x9596, 0xfffe, 0x1120,
-	0x2009, 0x007e, 0x0804, 0x8260, 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,
-	0x8235, 0x82ff, 0x1118, 0x9085, 0x0001, 0x0018, 0xc2fc, 0x2208,
-	0x9006, 0x00de, 0x00ee, 0x004e, 0x00be, 0x0005, 0x7000, 0x908c,
-	0xff00, 0x810f, 0x9184, 0x000f, 0x0002, 0x827d, 0x827d, 0x827d,
-	0x8421, 0x827d, 0x8280, 0x82a5, 0x832e, 0x827d, 0x827d, 0x827d,
-	0x827d, 0x827d, 0x827d, 0x827d, 0x827d, 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,
-	0xac8d, 0x7817, 0x0140, 0x00be, 0x0005, 0x00b6, 0x00c6, 0x9484,
-	0x0fff, 0x0904, 0x830a, 0x7110, 0xd1bc, 0x1904, 0x830a, 0x7108,
-	0x700c, 0x2028, 0x918c, 0x00ff, 0x2130, 0x9094, 0xff00, 0x15c8,
-	0x81ff, 0x15b8, 0x9080, 0x3388, 0x200d, 0x918c, 0xff00, 0x810f,
-	0x2001, 0x0080, 0x9106, 0x0904, 0x830a, 0x9182, 0x0801, 0x1a04,
-	0x830a, 0x9190, 0x1000, 0x2204, 0x905d, 0x05e0, 0xbe12, 0xbd16,
-	0xb800, 0xd0ec, 0x15b8, 0xba04, 0x9294, 0xff00, 0x9286, 0x0600,
-	0x1190, 0x080c, 0xab9a, 0x0598, 0x2b08, 0x7028, 0x6052, 0x702c,
-	0x604e, 0x6112, 0x6023, 0x0006, 0x7120, 0x610a, 0x7130, 0x615e,
-	0x080c, 0xd8f8, 0x00f8, 0x080c, 0x6a8e, 0x1138, 0xb807, 0x0606,
-	0x0c40, 0x190c, 0x8202, 0x11b0, 0x0880, 0x080c, 0xab9a, 0x2b08,
-	0x0188, 0x6112, 0x6023, 0x0004, 0x7120, 0x610a, 0x9286, 0x0400,
-	0x1118, 0x6007, 0x0005, 0x0010, 0x6007, 0x0001, 0x6003, 0x0001,
-	0x080c, 0x9240, 0x7817, 0x0140, 0x00ce, 0x00be, 0x0005, 0x2001,
-	0x180e, 0x2004, 0xd0ec, 0x0120, 0x2011, 0x8049, 0x080c, 0x4b29,
-	0x080c, 0xac60, 0x0d78, 0x2b08, 0x6112, 0x6023, 0x0006, 0x7120,
-	0x610a, 0x7130, 0x615e, 0x6017, 0xf300, 0x6003, 0x0001, 0x6007,
-	0x0041, 0x2009, 0xa022, 0x080c, 0x9239, 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, 0xac8d, 0x7817, 0x0140, 0x00be, 0x0005,
-	0x6120, 0x9186, 0x0002, 0x0128, 0x9186, 0x0005, 0x0110, 0x9085,
-	0x0001, 0x0005, 0x080c, 0x3346, 0x1168, 0x7010, 0x9084, 0xff00,
-	0x8007, 0x9086, 0x0000, 0x1130, 0x9184, 0x000f, 0x908a, 0x0006,
-	0x1208, 0x000b, 0x0005, 0x8391, 0x8392, 0x8391, 0x8391, 0x83f1,
-	0x8400, 0x0005, 0x00b6, 0x7110, 0xd1bc, 0x0120, 0x702c, 0xd084,
-	0x0904, 0x83ef, 0x700c, 0x7108, 0x080c, 0x2630, 0x1904, 0x83ef,
-	0x080c, 0x65e3, 0x1904, 0x83ef, 0xbe12, 0xbd16, 0x7110, 0xd1bc,
-	0x01d8, 0x080c, 0x6a8e, 0x0118, 0x9086, 0x0004, 0x1588, 0x00c6,
-	0x080c, 0x840f, 0x00ce, 0x05d8, 0x080c, 0xab9a, 0x2b08, 0x05b8,
-	0x6112, 0x080c, 0xccfe, 0x6023, 0x0002, 0x7120, 0x610a, 0x2009,
-	0x0088, 0x080c, 0xac8d, 0x0458, 0x080c, 0x6a8e, 0x0148, 0x9086,
-	0x0004, 0x0130, 0x080c, 0x6a96, 0x0118, 0x9086, 0x0004, 0x1180,
-	0x080c, 0xab9a, 0x2b08, 0x01d8, 0x6112, 0x080c, 0xccfe, 0x6023,
-	0x0005, 0x7120, 0x610a, 0x2009, 0x0088, 0x080c, 0xac8d, 0x0078,
-	0x080c, 0xab9a, 0x2b08, 0x0158, 0x6112, 0x080c, 0xccfe, 0x6023,
-	0x0004, 0x7120, 0x610a, 0x2009, 0x0001, 0x080c, 0xac8d, 0x00be,
-	0x0005, 0x7110, 0xd1bc, 0x0158, 0x00d1, 0x0148, 0x080c, 0x8370,
-	0x1130, 0x7124, 0x610a, 0x2009, 0x0089, 0x080c, 0xac8d, 0x0005,
-	0x7110, 0xd1bc, 0x0158, 0x0059, 0x0148, 0x080c, 0x8370, 0x1130,
-	0x7124, 0x610a, 0x2009, 0x008a, 0x080c, 0xac8d, 0x0005, 0x7020,
+	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, 0xac8d,
+	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, 0xab9a, 0x05a8,
+	0x9084, 0xf000, 0x9086, 0xc000, 0x05c0, 0x080c, 0xac5a, 0x05a8,
 	0x0066, 0x00c6, 0x0046, 0x2011, 0x0263, 0x2204, 0x8211, 0x220c,
-	0x080c, 0x2630, 0x1590, 0x080c, 0x65e3, 0x1578, 0xbe12, 0xbd16,
-	0x2b00, 0x004e, 0x00ce, 0x6012, 0x080c, 0xccfe, 0x080c, 0x1047,
+	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, 0x9240, 0x00fe, 0x009e, 0x00ce,
-	0x0005, 0x080c, 0xabf0, 0x006e, 0x0cc0, 0x004e, 0x00ce, 0x0cc8,
+	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, 0x84f7, 0x9186, 0x0022, 0x15f0, 0x2001, 0x0111,
-	0x2004, 0x9005, 0x1904, 0x84f9, 0x7030, 0x908e, 0x0400, 0x0904,
-	0x84f9, 0x908e, 0x6000, 0x05e8, 0x908e, 0x5400, 0x05d0, 0x908e,
+	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, 0x6a4c, 0x0588, 0x68b0, 0x9084, 0x00ff, 0x7100,
+	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,
-	0x840f, 0x0128, 0x6004, 0x9086, 0x0002, 0x0118, 0x0000, 0x9006,
+	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, 0xbbc1,
+	0x20a9, 0x0004, 0x2019, 0x1805, 0x2011, 0x027a, 0x080c, 0xbc8e,
 	0x1178, 0xd48c, 0x0148, 0x20a9, 0x0004, 0x2019, 0x1801, 0x2011,
-	0x027e, 0x080c, 0xbbc1, 0x1120, 0xd494, 0x0110, 0x9085, 0x0001,
+	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, 0xbbc1,
+	0x20a9, 0x0004, 0x2019, 0x1805, 0x2011, 0x0272, 0x080c, 0xbc8e,
 	0x1178, 0xd48c, 0x0148, 0x20a9, 0x0004, 0x2019, 0x1801, 0x2011,
-	0x0276, 0x080c, 0xbbc1, 0x1120, 0xd494, 0x0110, 0x9085, 0x0001,
+	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, 0x2071, 0x1a02, 0x7003, 0x0003,
-	0x700f, 0x0361, 0x9006, 0x701a, 0x7072, 0x7012, 0x7017, 0x1ddc,
-	0x7007, 0x0000, 0x7026, 0x702b, 0x9e6f, 0x7032, 0x7037, 0x9eec,
-	0x703f, 0xffff, 0x7042, 0x7047, 0x558c, 0x704a, 0x705b, 0x8724,
-	0x080c, 0x1060, 0x090c, 0x0d7d, 0x2900, 0x703a, 0xa867, 0x0003,
-	0xa86f, 0x0100, 0xa8ab, 0xdcb0, 0x0005, 0x2071, 0x1a02, 0x1d04,
-	0x8640, 0x2091, 0x6000, 0x700c, 0x8001, 0x700e, 0x1590, 0x2001,
-	0x013c, 0x2004, 0x9005, 0x190c, 0x87ce, 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, 0x8792, 0x0010, 0x080c, 0x8769,
-	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, 0x9f88,
-	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, 0x8668, 0x8669, 0x8693, 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, 0x6644, 0x11a8,
-	0xb888, 0x8001, 0x0290, 0xb88a, 0x1180, 0x0126, 0x2091, 0x8000,
-	0x0066, 0xb8d0, 0x9005, 0x0138, 0x0026, 0xba3c, 0x0016, 0x080c,
-	0x676f, 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, 0xcb7f, 0x6018, 0x9005, 0x0904, 0x86eb, 0x00f6, 0x2079,
-	0x0300, 0x7918, 0xd1b4, 0x1904, 0x86fe, 0x781b, 0x2020, 0xa001,
-	0x7918, 0xd1b4, 0x0120, 0x781b, 0x2000, 0x0804, 0x86fe, 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, 0xc865, 0x01b0, 0x6014, 0x2048, 0xa884, 0x908a, 0x199a,
-	0x0280, 0x9082, 0x1999, 0xa886, 0x908a, 0x199a, 0x0210, 0x2001,
-	0x1999, 0x8003, 0x800b, 0x810b, 0x9108, 0x611a, 0x080c, 0xcfb0,
-	0x0110, 0x080c, 0xc546, 0x012e, 0x9c88, 0x001c, 0x7116, 0x2001,
-	0x181a, 0x2004, 0x9102, 0x1228, 0x8631, 0x0138, 0x2160, 0x0804,
-	0x8697, 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,
-	0x85a5, 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,
-	0x88ac, 0xd0b4, 0x1168, 0xd0bc, 0x1904, 0x8885, 0x2009, 0x0006,
-	0x080c, 0x88d9, 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, 0x1c28, 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,
-	0x88d3, 0x908c, 0x2020, 0x918e, 0x2020, 0x01a8, 0x6024, 0xd0d4,
-	0x11e8, 0x2009, 0x1869, 0x2104, 0xd084, 0x1138, 0x87ff, 0x1120,
-	0x2009, 0x0043, 0x0804, 0xac8d, 0x0005, 0x87ff, 0x1de8, 0x2009,
-	0x0042, 0x0804, 0xac8d, 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, 0x88d3, 0x908c, 0x2020,
-	0x918e, 0x2020, 0x0170, 0x0076, 0x00f6, 0x2c78, 0x080c, 0x174b,
-	0x00fe, 0x007e, 0x87ff, 0x1120, 0x2009, 0x0042, 0x080c, 0xac8d,
-	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, 0xac8d, 0x0005, 0x00b9,
-	0x0ce8, 0x87ff, 0x1dd8, 0x2009, 0x0043, 0x080c, 0xac8d, 0x0cb0,
-	0x6110, 0x00b6, 0x2158, 0xb900, 0x00be, 0xd1ac, 0x0d20, 0x6124,
-	0xc1cd, 0x6126, 0x0c00, 0x2009, 0x0004, 0x0019, 0x0005, 0x2009,
-	0x0001, 0x0096, 0x080c, 0xc865, 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, 0x6bd4,
-	0x6014, 0x904d, 0x0076, 0x2039, 0x0000, 0x190c, 0x87f2, 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, 0x0178, 0xc084, 0x7007, 0x0001,
-	0x700f, 0x0000, 0x0006, 0x2009, 0x181d, 0x2104, 0x9082, 0x0007,
-	0x2009, 0x1b4d, 0x200a, 0x000e, 0xc095, 0x7012, 0x2008, 0x2001,
-	0x003b, 0x080c, 0x1693, 0x9006, 0x2071, 0x193c, 0x7002, 0x7006,
-	0x702a, 0x00ee, 0x009e, 0x0005, 0x00e6, 0x0126, 0x0156, 0x2091,
-	0x8000, 0x2071, 0x1800, 0x7154, 0x2001, 0x0008, 0x910a, 0x0638,
-	0x2001, 0x187d, 0x20ac, 0x9006, 0x9080, 0x0008, 0x1f04, 0x898c,
-	0x71c0, 0x9102, 0x02e0, 0x2071, 0x1877, 0x20a9, 0x0007, 0x00c6,
-	0x080c, 0xab9a, 0x6023, 0x0009, 0x6003, 0x0004, 0x601f, 0x0101,
-	0x0089, 0x0126, 0x2091, 0x8000, 0x080c, 0x8b15, 0x012e, 0x1f04,
-	0x8998, 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, 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, 0x2900, 0xb806, 0x2058, 0x8109,
-	0x1da0, 0x002e, 0x004e, 0x005e, 0x008e, 0x009e, 0x00be, 0x00ee,
-	0x0005, 0x2079, 0x0000, 0x2071, 0x1923, 0x7004, 0x004b, 0x700c,
-	0x0002, 0x8a04, 0x89fd, 0x89fd, 0x0005, 0x8a0e, 0x8a6f, 0x8a6f,
-	0x8a6f, 0x8a70, 0x8a81, 0x8a81, 0x700c, 0x0cba, 0x0126, 0x2091,
-	0x8000, 0x78a0, 0x79a0, 0x9106, 0x0128, 0x78a0, 0x79a0, 0x9106,
-	0x1904, 0x8a62, 0x2001, 0x0005, 0x2004, 0xd0bc, 0x0130, 0x2011,
-	0x0004, 0x2204, 0xc0c5, 0x2012, 0x0ca8, 0x012e, 0x7018, 0x910a,
-	0x1130, 0x7030, 0x9005, 0x05a8, 0x080c, 0x8ab0, 0x0490, 0x1210,
+	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,
+	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,
+	0x6003, 0x0004, 0x601f, 0x0101, 0x0089, 0x0126, 0x2091, 0x8000,
+	0x080c, 0x8b89, 0x012e, 0x1f04, 0x8a14, 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,
+	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,
+	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,
+	0x700c, 0x0cba, 0x0126, 0x2091, 0x8000, 0x78a0, 0x79a0, 0x9106,
+	0x1904, 0x8ad2, 0x7814, 0xd0bc, 0x1904, 0x8adb, 0x012e, 0x7018,
+	0x910a, 0x1128, 0x7030, 0x9005, 0x1904, 0x8b24, 0x0005, 0x1210,
 	0x7114, 0x910a, 0x9192, 0x000a, 0x0210, 0x2009, 0x000a, 0x2001,
-	0x1888, 0x2014, 0x2001, 0x1935, 0x2004, 0x9100, 0x9202, 0x0e48,
-	0x080c, 0x8bff, 0x2200, 0x9102, 0x0208, 0x2208, 0x0096, 0x702c,
-	0x2048, 0xa873, 0x0001, 0xa976, 0x080c, 0x8d08, 0x2100, 0xa87e,
+	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, 0x2001, 0x0005, 0x2004, 0xd0bc, 0x0130, 0x2011,
-	0x0004, 0x2204, 0xc0c5, 0x2012, 0x0ca8, 0x012e, 0x0005, 0x0005,
-	0x700c, 0x0002, 0x8a75, 0x8a78, 0x8a77, 0x080c, 0x8a0c, 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, 0x8d08, 0x2100, 0xaa8c, 0x9210, 0xaa8e, 0x1220,
-	0xa890, 0x9081, 0x0000, 0xa892, 0x000e, 0x009e, 0x2f08, 0x9188,
-	0x0028, 0x200a, 0x701a, 0x0005, 0x00e6, 0x2071, 0x1923, 0x700c,
-	0x0002, 0x8aae, 0x8aae, 0x8aac, 0x700f, 0x0001, 0x00ee, 0x0005,
-	0x0126, 0x2091, 0x8000, 0x7030, 0x9005, 0x0508, 0x2078, 0x7814,
-	0x2048, 0xae88, 0x00b6, 0x2059, 0x0000, 0x080c, 0x8b1e, 0x00be,
-	0x01b0, 0x00e6, 0x2071, 0x193c, 0x080c, 0x8b65, 0x00ee, 0x0178,
-	0x0096, 0x080c, 0x1060, 0x2900, 0x009e, 0x0148, 0xa8aa, 0x04d1,
-	0x0041, 0x2001, 0x1946, 0x2003, 0x0000, 0x012e, 0x08c8, 0x012e,
-	0x0005, 0x00d6, 0x00c6, 0x0086, 0x00a6, 0x2940, 0x2650, 0x2600,
-	0x9005, 0x0180, 0xa864, 0x9084, 0x000f, 0x2068, 0x9d88, 0x1e7a,
-	0x2165, 0x0056, 0x2029, 0x0000, 0x080c, 0x8c8d, 0x080c, 0x1e50,
-	0x1dd8, 0x005e, 0x00ae, 0x2001, 0x187f, 0x2004, 0xa88a, 0x00c6,
-	0x2f60, 0x080c, 0x174b, 0x00ce, 0x781f, 0x0101, 0x7813, 0x0000,
-	0x0126, 0x2091, 0x8000, 0x080c, 0x8b74, 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, 0x8de7, 0x2005, 0x906d, 0x090c, 0x0d7d, 0x9b80,
-	0x8ddf, 0x2005, 0x9065, 0x090c, 0x0d7d, 0x6114, 0x2600, 0x9102,
-	0x0248, 0x6828, 0x9102, 0x02f0, 0x9085, 0x0001, 0x002e, 0x00ce,
-	0x00de, 0x0005, 0x6804, 0xd094, 0x0148, 0x6854, 0xd084, 0x1178,
-	0xc085, 0x6856, 0x2011, 0x8026, 0x080c, 0x4b29, 0x684c, 0x0096,
-	0x904d, 0x090c, 0x0d7d, 0xa804, 0x8000, 0xa806, 0x009e, 0x9006,
-	0x2030, 0x0c20, 0x6854, 0xd08c, 0x1d08, 0xc08d, 0x6856, 0x2011,
-	0x8025, 0x080c, 0x4b29, 0x684c, 0x0096, 0x904d, 0x090c, 0x0d7d,
-	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,
-	0x2069, 0x193c, 0x6804, 0x9080, 0x193e, 0x2f08, 0x2102, 0x6904,
-	0x8108, 0x9182, 0x0008, 0x0208, 0x900e, 0x6906, 0x9180, 0x193e,
-	0x2003, 0x0000, 0x00de, 0x0005, 0x0096, 0x00c6, 0x2060, 0x6014,
-	0x2048, 0xa8a8, 0x0096, 0x2048, 0x9005, 0x190c, 0x1079, 0x009e,
-	0xa8ab, 0x0000, 0x080c, 0x0ff9, 0x080c, 0xabf0, 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, 0x8f1c,
-	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, 0x1693, 0x00ee, 0x0005, 0x0096,
-	0x00d6, 0x9006, 0x7006, 0x700e, 0x701a, 0x701e, 0x7022, 0x7016,
-	0x702a, 0x7026, 0x702f, 0x0000, 0x080c, 0x8d67, 0x0170, 0x080c,
-	0x8d9c, 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, 0x8d9c, 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, 0x8d08, 0x810c, 0x2100, 0x9318, 0x8003,
-	0x2228, 0x2021, 0x0078, 0x9402, 0x9532, 0x0208, 0x2028, 0x2500,
-	0x8004, 0x20a8, 0x23a0, 0xa001, 0xa001, 0x4005, 0x2508, 0x080c,
-	0x8d11, 0x2130, 0x7014, 0x9600, 0x7016, 0x2600, 0x711c, 0x9102,
-	0x701e, 0x7004, 0x9600, 0x2008, 0x9082, 0x000a, 0x1190, 0x7000,
-	0x2048, 0xa800, 0x9005, 0x1148, 0x2009, 0x0001, 0x0026, 0x080c,
-	0x8bff, 0x002e, 0x7000, 0x2048, 0xa800, 0x7002, 0x7007, 0x0000,
-	0x0008, 0x7106, 0x2500, 0x9212, 0x1904, 0x8c3e, 0x012e, 0x00ee,
-	0x014e, 0x013e, 0x015e, 0x009e, 0x0005, 0x0016, 0x0026, 0x00e6,
-	0x0126, 0x2091, 0x8000, 0x9580, 0x8ddf, 0x2005, 0x9075, 0x090c,
-	0x0d7d, 0x080c, 0x8ce3, 0x012e, 0x9580, 0x8ddb, 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, 0x8ccd, 0x8ccd, 0x8ccf,
-	0x8ccd, 0x8ccf, 0x8ccd, 0x8ccd, 0x8ccd, 0x8ccd, 0x8ccd, 0x8cd5,
-	0x8ccd, 0x8cd5, 0x8ccd, 0x8ccd, 0x8ccd, 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, 0x8dab, 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, 0x690c, 0x6810,
-	0x2019, 0x0001, 0x2031, 0x8d51, 0x9112, 0x0220, 0x0118, 0x8318,
-	0x2208, 0x0cd0, 0x6808, 0x9005, 0x0108, 0x8318, 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, 0x2d00, 0x90b8, 0x0007, 0x00e6, 0x2071, 0x1800,
-	0x7128, 0x6810, 0x2019, 0x0001, 0x910a, 0x0118, 0x0210, 0x8318,
-	0x0cd8, 0x2031, 0x8d64, 0x0870, 0x6c16, 0x00ee, 0x0005, 0x0096,
-	0x0046, 0x0126, 0x2091, 0x8000, 0x2b00, 0x9080, 0x8de3, 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, 0x8f07, 0xa067, 0x0023, 0x6010,
-	0x905d, 0x0904, 0x8edc, 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, 0x1e7a,
-	0x2c65, 0x9786, 0x0024, 0x2c05, 0x1590, 0x908a, 0x0036, 0x1a0c,
-	0x0d7d, 0x9082, 0x001b, 0x0002, 0x8e47, 0x8e47, 0x8e49, 0x8e47,
-	0x8e47, 0x8e47, 0x8e4b, 0x8e47, 0x8e47, 0x8e47, 0x8e4d, 0x8e47,
-	0x8e47, 0x8e47, 0x8e4f, 0x8e47, 0x8e47, 0x8e47, 0x8e51, 0x8e47,
-	0x8e47, 0x8e47, 0x8e53, 0x8e47, 0x8e47, 0x8e47, 0x8e55, 0x080c,
-	0x0d7d, 0xa180, 0x04b8, 0xa190, 0x04a8, 0xa1a0, 0x0498, 0xa1b0,
-	0x0488, 0xa1c0, 0x0478, 0xa1d0, 0x0468, 0xa1e0, 0x0458, 0x908a,
-	0x0034, 0x1a0c, 0x0d7d, 0x9082, 0x001b, 0x0002, 0x8e79, 0x8e77,
-	0x8e77, 0x8e77, 0x8e77, 0x8e77, 0x8e7b, 0x8e77, 0x8e77, 0x8e77,
-	0x8e77, 0x8e77, 0x8e7d, 0x8e77, 0x8e77, 0x8e77, 0x8e77, 0x8e77,
-	0x8e7f, 0x8e77, 0x8e77, 0x8e77, 0x8e77, 0x8e77, 0x8e81, 0x080c,
-	0x0d7d, 0xa180, 0x0038, 0xa198, 0x0028, 0xa1b0, 0x0018, 0xa1c8,
-	0x0008, 0xa1e0, 0x2600, 0x0002, 0x8e9d, 0x8e9f, 0x8ea1, 0x8ea3,
-	0x8ea5, 0x8ea7, 0x8ea9, 0x8eab, 0x8ead, 0x8eaf, 0x8eb1, 0x8eb3,
-	0x8eb5, 0x8eb7, 0x8eb9, 0x8ebb, 0x8ebd, 0x8ebf, 0x8ec1, 0x8ec3,
-	0x8ec5, 0x8ec7, 0x8ec9, 0x8ecb, 0x8ecd, 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, 0x1e50, 0x090c, 0x0d7d, 0x0804, 0x8e21, 0x00ae,
-	0x00be, 0x00ce, 0x00ee, 0x0005, 0xa86c, 0xa06e, 0xa870, 0xa072,
-	0xa077, 0x00ff, 0x9006, 0x0804, 0x8e03, 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,
-	0x4b29, 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, 0x8f5c, 0x701b, 0x0202, 0xa001, 0xa001, 0x7018,
-	0xd094, 0x1d90, 0xb8ac, 0x9005, 0x01d0, 0x2060, 0x600c, 0xb8ae,
+	0x1de8, 0x0005, 0x78a0, 0x79a0, 0x9106, 0x0904, 0x8a92, 0x080c,
+	0x8c55, 0x012e, 0x0005, 0x7810, 0xc0c5, 0x7812, 0x0804, 0x8a92,
+	0x0005, 0x700c, 0x0002, 0x8ae6, 0x8ae9, 0x8ae8, 0x080c, 0x8a88,
+	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,
+	0x1220, 0xa890, 0x9081, 0x0000, 0xa892, 0x000e, 0x009e, 0x0126,
+	0x2091, 0x8000, 0x78a2, 0x701a, 0x080c, 0x8c55, 0x012e, 0x0005,
+	0x00e6, 0x2071, 0x1923, 0x700c, 0x0002, 0x8b22, 0x8b22, 0x8b20,
+	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, 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,
+	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,
+	0x9085, 0x0001, 0x002e, 0x00ce, 0x00de, 0x0005, 0x6804, 0xd094,
+	0x0148, 0x6854, 0xd084, 0x1178, 0xc085, 0x6856, 0x2011, 0x8026,
+	0x080c, 0x4b52, 0x684c, 0x0096, 0x904d, 0x090c, 0x0d7d, 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,
+	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,
+	0x00de, 0x0005, 0x0096, 0x00c6, 0x2060, 0x6014, 0x2048, 0xa8a8,
+	0x0096, 0x2048, 0x9005, 0x190c, 0x1079, 0x009e, 0xa8ab, 0x0000,
+	0x080c, 0x0ff9, 0x080c, 0xacb0, 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,
+	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, 0x8b15, 0x0c18, 0x2071,
+	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, 0x2630, 0x015e, 0x11b0, 0x080c, 0x65e3, 0x190c, 0x0d7d,
-	0x000e, 0x001e, 0xb912, 0xb816, 0x080c, 0xab9a, 0x0140, 0x2b00,
-	0x6012, 0x6023, 0x0001, 0x2009, 0x0001, 0x080c, 0xac8d, 0x00be,
+	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, 0x8fce, 0x8fce,
-	0x8fce, 0x8fd0, 0x9019, 0x8fce, 0x8fce, 0x8fce, 0x907c, 0x8fce,
-	0x90b4, 0x8fce, 0x8fce, 0x8fce, 0x8fce, 0x8fce, 0x080c, 0x0d7d,
-	0x9182, 0x0040, 0x0002, 0x8fe3, 0x8fe3, 0x8fe3, 0x8fe3, 0x8fe3,
-	0x8fe3, 0x8fe3, 0x8fe3, 0x8fe3, 0x8fe5, 0x8ff6, 0x8fe3, 0x8fe3,
-	0x8fe3, 0x8fe3, 0x9007, 0x080c, 0x0d7d, 0x0096, 0x6114, 0x2148,
-	0xa87b, 0x0000, 0x6010, 0x00b6, 0x2058, 0xb8bb, 0x0500, 0x00be,
-	0x080c, 0x6b9f, 0x080c, 0xabf0, 0x009e, 0x0005, 0x080c, 0x965a,
-	0x00d6, 0x6114, 0x080c, 0xc865, 0x0130, 0x0096, 0x6114, 0x2148,
-	0x080c, 0x6d9f, 0x009e, 0x00de, 0x080c, 0xabf0, 0x0005, 0x080c,
-	0x965a, 0x080c, 0x320f, 0x6114, 0x0096, 0x2148, 0x080c, 0xc865,
-	0x0120, 0xa87b, 0x0029, 0x080c, 0x6d9f, 0x009e, 0x080c, 0xabf0,
-	0x0005, 0x601b, 0x0000, 0x9182, 0x0040, 0x0096, 0x0002, 0x9034,
-	0x9034, 0x9034, 0x9034, 0x9034, 0x9034, 0x9034, 0x9034, 0x9036,
-	0x9034, 0x9034, 0x9034, 0x9078, 0x9034, 0x9034, 0x9034, 0x9034,
-	0x9034, 0x9034, 0x903c, 0x9034, 0x080c, 0x0d7d, 0x6114, 0x2148,
-	0xa938, 0x918e, 0xffff, 0x05e0, 0x00e6, 0x6114, 0x2148, 0x080c,
-	0x8deb, 0x0096, 0xa8a8, 0x2048, 0x080c, 0x6b37, 0x009e, 0xa8ab,
-	0x0000, 0x6010, 0x9005, 0x0128, 0x00b6, 0x2058, 0x080c, 0x8f1c,
-	0x00be, 0xae88, 0x00b6, 0x2059, 0x0000, 0x080c, 0x8b1e, 0x00be,
-	0x01e0, 0x2071, 0x193c, 0x080c, 0x8b65, 0x01b8, 0x9086, 0x0001,
-	0x1128, 0x2001, 0x1946, 0x2004, 0x9005, 0x1178, 0x0096, 0x080c,
-	0x1047, 0x2900, 0x009e, 0x0148, 0xa8aa, 0x00f6, 0x2c78, 0x080c,
-	0x8ad9, 0x00fe, 0x00ee, 0x009e, 0x0005, 0x080c, 0x8b15, 0x0cd0,
-	0x080c, 0x9130, 0x009e, 0x0005, 0x9182, 0x0040, 0x0096, 0x0002,
-	0x9090, 0x9090, 0x9090, 0x9092, 0x9090, 0x9090, 0x9090, 0x90b2,
-	0x9090, 0x9090, 0x9090, 0x9090, 0x9090, 0x9090, 0x9090, 0x9090,
-	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, 0x1bdf, 0x2009, 0x8030, 0x080c, 0x9280,
-	0x009e, 0x0005, 0x080c, 0x0d7d, 0x080c, 0x965a, 0x6114, 0x2148,
+	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,
 	0xa87b, 0x0000, 0x6010, 0x00b6, 0x2058, 0xb8bb, 0x0500, 0x00be,
-	0x080c, 0x6d9f, 0x080c, 0xabf0, 0x009e, 0x0005, 0x080c, 0xa899,
-	0x6144, 0xd1fc, 0x0120, 0xd1ac, 0x1110, 0x6003, 0x0003, 0x6000,
-	0x908a, 0x0016, 0x1a0c, 0x0d7d, 0x0096, 0x0023, 0x009e, 0x080c,
-	0xa8b5, 0x0005, 0x90ea, 0x90ea, 0x90ea, 0x90ec, 0x90fd, 0x90ea,
-	0x90ea, 0x90ea, 0x90ea, 0x90ea, 0x90ea, 0x90ea, 0x90ea, 0x90ea,
-	0x90ea, 0x90ea, 0x080c, 0x0d7d, 0x080c, 0xaa2d, 0x6114, 0x2148,
-	0xa87b, 0x0006, 0x6010, 0x00b6, 0x2058, 0xb8bb, 0x0500, 0x00be,
-	0x080c, 0x6d9f, 0x080c, 0xabf0, 0x0005, 0x0491, 0x0005, 0x080c,
-	0xa899, 0x6000, 0x6144, 0xd1fc, 0x0130, 0xd1ac, 0x1120, 0x6003,
-	0x0003, 0x2009, 0x0003, 0x908a, 0x0016, 0x1a0c, 0x0d7d, 0x0096,
-	0x0033, 0x009e, 0x0106, 0x080c, 0xa8b5, 0x010e, 0x0005, 0x9127,
-	0x9127, 0x9127, 0x9129, 0x9130, 0x9127, 0x9127, 0x9127, 0x9127,
-	0x9127, 0x9127, 0x9127, 0x9127, 0x9127, 0x9127, 0x9127, 0x080c,
-	0x0d7d, 0x0036, 0x00e6, 0x080c, 0xaa2d, 0x00ee, 0x003e, 0x0005,
-	0x00f6, 0x00e6, 0x601b, 0x0000, 0x6014, 0x2048, 0x6010, 0x9005,
-	0x0128, 0x00b6, 0x2058, 0x080c, 0x8f1c, 0x00be, 0x2071, 0x193c,
-	0x080c, 0x8b65, 0x0160, 0x2001, 0x187f, 0x2004, 0xa88a, 0x2031,
-	0x0000, 0x2c78, 0x080c, 0x8ad9, 0x00ee, 0x00fe, 0x0005, 0x0096,
-	0xa88b, 0x0000, 0xa8a8, 0x2048, 0x080c, 0x1079, 0x009e, 0xa8ab,
-	0x0000, 0x080c, 0x8b15, 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, 0x9175, 0x8086, 0x818e, 0x004e, 0x003e, 0x012e,
-	0x0005, 0x0126, 0x2091, 0x8000, 0x0076, 0x0156, 0x20a9, 0x0010,
-	0x9005, 0x01c8, 0x911a, 0x12b8, 0x8213, 0x818d, 0x0228, 0x911a,
-	0x1220, 0x1f04, 0x918c, 0x0028, 0x911a, 0x2308, 0x8210, 0x1f04,
-	0x918c, 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, 0xa68e, 0x04a9, 0x080c, 0xa679, 0x0491,
-	0x080c, 0xa67c, 0x0479, 0x080c, 0xa67f, 0x0461, 0x080c, 0xa682,
-	0x0449, 0x080c, 0xa685, 0x0431, 0x080c, 0xa688, 0x0419, 0x080c,
-	0xa68b, 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, 0x0005, 0x20a9, 0x0020, 0x20a1, 0x0240, 0x2001, 0x0000,
-	0x4004, 0x0005, 0x00c6, 0x7803, 0x0000, 0x9006, 0x7827, 0x0030,
-	0x782b, 0x0400, 0x7827, 0x0031, 0x782b, 0x1aee, 0x781f, 0xff00,
-	0x781b, 0xff00, 0x2061, 0x1ae3, 0x602f, 0x19e6, 0x6033, 0x1800,
-	0x6037, 0x1a02, 0x603b, 0x1e7a, 0x603f, 0x1e8a, 0x6042, 0x6047,
-	0x1ab9, 0x00ce, 0x0005, 0x2001, 0x0382, 0x2004, 0x9084, 0x0007,
-	0x9086, 0x0001, 0x01b0, 0x00c6, 0x6146, 0x600f, 0x0000, 0x2c08,
-	0x2061, 0x19e6, 0x602c, 0x8000, 0x602e, 0x601c, 0x9005, 0x0130,
-	0x9080, 0x0003, 0x2102, 0x611e, 0x00ce, 0x0005, 0x6122, 0x611e,
-	0x0cd8, 0x6146, 0x2c08, 0x2001, 0x0012, 0x080c, 0xa88a, 0x0005,
-	0x0016, 0x2009, 0x8020, 0x6146, 0x2c08, 0x2001, 0x0382, 0x2004,
-	0x9084, 0x0007, 0x9086, 0x0001, 0x1128, 0x2001, 0x0019, 0x080c,
-	0xa88a, 0x0088, 0x00c6, 0x2061, 0x19e6, 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, 0x2102, 0x6146, 0x00ce, 0x0005, 0x614a, 0x6146, 0x0cd8,
-	0x6146, 0x600f, 0x0000, 0x2c08, 0x2001, 0x0013, 0x080c, 0xa88a,
-	0x0005, 0x6044, 0xd0dc, 0x0110, 0x080c, 0xa327, 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, 0x930c,
-	0x6010, 0x2058, 0xb8a0, 0x9206, 0x1904, 0x9307, 0x87ff, 0x0120,
-	0x605c, 0x9106, 0x1904, 0x9307, 0x704c, 0x9c06, 0x1178, 0x0036,
-	0x2019, 0x0001, 0x080c, 0xa133, 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, 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f,
-	0x0000, 0x080c, 0xc865, 0x01f0, 0x6014, 0x2048, 0x6020, 0x9086,
-	0x0003, 0x1588, 0x6004, 0x9086, 0x0040, 0x090c, 0xa327, 0xa867,
-	0x0103, 0xab7a, 0xa877, 0x0000, 0x0016, 0x0036, 0x0076, 0x080c,
-	0xcb68, 0x080c, 0xe66e, 0x080c, 0x6d9f, 0x007e, 0x003e, 0x001e,
-	0x080c, 0xca54, 0x080c, 0xac2b, 0x00ce, 0x0804, 0x92a5, 0x2c78,
-	0x600c, 0x2060, 0x0804, 0x92a5, 0x012e, 0x000e, 0x001e, 0x002e,
-	0x003e, 0x005e, 0x006e, 0x007e, 0x009e, 0x00be, 0x00ce, 0x00de,
-	0x00ee, 0x00fe, 0x0005, 0x6020, 0x9086, 0x0006, 0x1158, 0x0016,
-	0x0036, 0x0076, 0x080c, 0xe66e, 0x080c, 0xe2b9, 0x007e, 0x003e,
-	0x001e, 0x08c0, 0x6020, 0x9086, 0x0009, 0x1168, 0xa87b, 0x0006,
-	0x0016, 0x0036, 0x0076, 0x080c, 0x6d9f, 0x080c, 0xabf0, 0x007e,
-	0x003e, 0x001e, 0x0848, 0x6020, 0x9086, 0x000a, 0x0904, 0x92f1,
-	0x0804, 0x92ea, 0x0006, 0x0066, 0x0096, 0x00c6, 0x00d6, 0x00f6,
-	0x9036, 0x0126, 0x2091, 0x8000, 0x2079, 0x19e6, 0x7848, 0x9065,
-	0x0904, 0x93a6, 0x600c, 0x0006, 0x600f, 0x0000, 0x784c, 0x9c06,
-	0x11a0, 0x0036, 0x2019, 0x0001, 0x080c, 0xa133, 0x783f, 0x0000,
-	0x901e, 0x7b4e, 0x7b6a, 0x7b52, 0x7b6e, 0x003e, 0x000e, 0x9005,
-	0x1118, 0x600c, 0x600f, 0x0000, 0x0006, 0x00e6, 0x2f70, 0x080c,
-	0x9289, 0x00ee, 0x080c, 0xc865, 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, 0xa327, 0xa867, 0x0103, 0xab7a,
-	0xa877, 0x0000, 0x080c, 0x6d93, 0x080c, 0xca54, 0x6044, 0xc0fc,
-	0x6046, 0x080c, 0xac2b, 0x000e, 0x0804, 0x934f, 0x7e4a, 0x7e46,
-	0x012e, 0x00fe, 0x00de, 0x00ce, 0x009e, 0x006e, 0x000e, 0x0005,
-	0x6020, 0x9086, 0x0006, 0x1118, 0x080c, 0xe2b9, 0x0c38, 0x6020,
-	0x9086, 0x0009, 0x1130, 0xab7a, 0x080c, 0x6d9f, 0x080c, 0xabf0,
-	0x0c10, 0x6020, 0x9086, 0x000a, 0x0990, 0x0850, 0x0016, 0x0026,
-	0x0086, 0x9046, 0x00a9, 0x080c, 0x94b7, 0x008e, 0x002e, 0x001e,
-	0x0005, 0x00f6, 0x0126, 0x2079, 0x19e6, 0x2091, 0x8000, 0x080c,
-	0x9500, 0x080c, 0x9594, 0x080c, 0x67d1, 0x012e, 0x00fe, 0x0005,
-	0x00b6, 0x0096, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0016,
-	0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19e6, 0x7620, 0x2660,
-	0x2678, 0x8cff, 0x0904, 0x947c, 0x6010, 0x2058, 0xb8a0, 0x9206,
-	0x1904, 0x9477, 0x88ff, 0x0120, 0x605c, 0x9106, 0x1904, 0x9477,
-	0x7030, 0x9c06, 0x1570, 0x2069, 0x0100, 0x6820, 0xd0a4, 0x1508,
-	0x080c, 0x8709, 0x080c, 0x9e4f, 0x68c3, 0x0000, 0x080c, 0xa327,
-	0x7033, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000,
-	0x0138, 0x2001, 0x0100, 0x080c, 0x2a49, 0x9006, 0x080c, 0x2a49,
-	0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e,
-	0x0040, 0x7008, 0xc0ad, 0x700a, 0x6003, 0x0009, 0x630a, 0x0804,
-	0x9477, 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, 0xc865, 0x01e8, 0x6020, 0x9086, 0x0003, 0x1580, 0x080c,
-	0xca7a, 0x1118, 0x080c, 0xb5c6, 0x0098, 0xa867, 0x0103, 0xab7a,
-	0xa877, 0x0000, 0x0016, 0x0036, 0x0086, 0x080c, 0xcb68, 0x080c,
-	0xe66e, 0x080c, 0x6d9f, 0x008e, 0x003e, 0x001e, 0x080c, 0xca54,
-	0x080c, 0xac2b, 0x080c, 0xa1fd, 0x00ce, 0x0804, 0x93f1, 0x2c78,
-	0x600c, 0x2060, 0x0804, 0x93f1, 0x012e, 0x000e, 0x001e, 0x006e,
-	0x00ce, 0x00de, 0x00ee, 0x00fe, 0x009e, 0x00be, 0x0005, 0x6020,
-	0x9086, 0x0006, 0x1158, 0x0016, 0x0036, 0x0086, 0x080c, 0xe66e,
-	0x080c, 0xe2b9, 0x008e, 0x003e, 0x001e, 0x08d0, 0x080c, 0xb5c6,
-	0x6020, 0x9086, 0x0002, 0x1160, 0x6004, 0x0006, 0x9086, 0x0085,
-	0x000e, 0x0904, 0x945d, 0x9086, 0x008b, 0x0904, 0x945d, 0x0840,
-	0x6020, 0x9086, 0x0005, 0x1920, 0x6004, 0x0006, 0x9086, 0x0085,
-	0x000e, 0x09c8, 0x9086, 0x008b, 0x09b0, 0x0804, 0x9470, 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, 0xaa78, 0x01d8, 0x610c, 0x0016, 0x080c,
-	0x9fbd, 0x6014, 0x2048, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000,
-	0x0016, 0x0036, 0x0086, 0x080c, 0xcb68, 0x080c, 0xe66e, 0x080c,
-	0x6d9f, 0x008e, 0x003e, 0x001e, 0x080c, 0xac2b, 0x00ce, 0x08d8,
-	0x2c30, 0x600c, 0x2060, 0x08b8, 0x080c, 0x67ee, 0x012e, 0x001e,
-	0x006e, 0x00ce, 0x00be, 0x009e, 0x00ee, 0x00fe, 0x000e, 0x0005,
-	0x0096, 0x0006, 0x0066, 0x00c6, 0x00d6, 0x9036, 0x7820, 0x9065,
-	0x0904, 0x9567, 0x600c, 0x0006, 0x6044, 0xc0fc, 0x6046, 0x600f,
-	0x0000, 0x7830, 0x9c06, 0x1588, 0x2069, 0x0100, 0x6820, 0xd0a4,
-	0x1508, 0x080c, 0x8709, 0x080c, 0x9e4f, 0x68c3, 0x0000, 0x080c,
-	0xa327, 0x7833, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384,
-	0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2a49, 0x9006, 0x080c,
-	0x2a49, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001,
-	0x003e, 0x0058, 0x080c, 0x6a26, 0x1538, 0x6003, 0x0009, 0x630a,
-	0x7808, 0xc0ad, 0x780a, 0x2c30, 0x00f8, 0x6014, 0x2048, 0x080c,
-	0xc863, 0x01b0, 0x6020, 0x9086, 0x0003, 0x1508, 0x080c, 0xca7a,
-	0x1118, 0x080c, 0xb5c6, 0x0060, 0x080c, 0x6a26, 0x1168, 0xa867,
-	0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0x6d9f, 0x080c, 0xca54,
-	0x080c, 0xac2b, 0x080c, 0xa1fd, 0x000e, 0x0804, 0x9507, 0x7e22,
-	0x7e1e, 0x00de, 0x00ce, 0x006e, 0x000e, 0x009e, 0x0005, 0x6020,
-	0x9086, 0x0006, 0x1118, 0x080c, 0xe2b9, 0x0c50, 0x080c, 0xb5c6,
-	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, 0xaa78, 0x0180, 0x610c, 0x080c, 0x9fbd,
-	0x6014, 0x2048, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c,
-	0x6d9f, 0x080c, 0xac2b, 0x000e, 0x08f0, 0x2c30, 0x0ce0, 0x006e,
-	0x00ce, 0x00be, 0x009e, 0x000e, 0x0005, 0x00e6, 0x00d6, 0x0096,
-	0x0066, 0x080c, 0x6156, 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, 0xaa78, 0x0178, 0x080c, 0x9fbd,
-	0x6014, 0x2048, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c,
-	0xcb68, 0x080c, 0x6d9f, 0x080c, 0xac2b, 0x00ce, 0x0005, 0x00b6,
-	0x00e6, 0x00c6, 0x080c, 0xa899, 0x0106, 0x2071, 0x0101, 0x2e04,
-	0xc0c4, 0x2072, 0x6044, 0xd0fc, 0x1138, 0x010e, 0x090c, 0xa8b5,
-	0x00ce, 0x00ee, 0x00be, 0x0005, 0x2071, 0x19e6, 0x7030, 0x9005,
-	0x0da0, 0x9c06, 0x190c, 0x0d7d, 0x7036, 0x080c, 0x8709, 0x7004,
-	0x9084, 0x0007, 0x0002, 0x962d, 0x962f, 0x9636, 0x9640, 0x964e,
-	0x962d, 0x963b, 0x962b, 0x080c, 0x0d7d, 0x0428, 0x0005, 0x080c,
-	0xaa63, 0x7007, 0x0000, 0x7033, 0x0000, 0x00e8, 0x0066, 0x9036,
-	0x080c, 0x9fbd, 0x006e, 0x7007, 0x0000, 0x7033, 0x0000, 0x0098,
-	0x080c, 0xaa4e, 0x0140, 0x080c, 0xaa63, 0x0128, 0x0066, 0x9036,
-	0x080c, 0x9fbd, 0x006e, 0x7033, 0x0000, 0x0028, 0x080c, 0xaa4e,
-	0x080c, 0xa327, 0x0000, 0x010e, 0x190c, 0xa8b5, 0x00ce, 0x00ee,
-	0x00be, 0x0005, 0x00d6, 0x00c6, 0x080c, 0xa899, 0x0106, 0x6044,
-	0xd0fc, 0x1130, 0x010e, 0x090c, 0xa8b5, 0x00ce, 0x00de, 0x0005,
-	0x2069, 0x19e6, 0x684c, 0x9005, 0x0da8, 0x9c06, 0x190c, 0x0d7d,
-	0x6852, 0x00e6, 0x2d70, 0x080c, 0x9289, 0x00ee, 0x080c, 0x8716,
-	0x0016, 0x2009, 0x0040, 0x080c, 0x21d9, 0x001e, 0x683c, 0x9084,
-	0x0003, 0x0002, 0x9688, 0x9689, 0x96a7, 0x9686, 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,
-	0x190c, 0xa8b5, 0x00ce, 0x00de, 0x0005, 0x0005, 0x6020, 0x9084,
-	0x000f, 0x000b, 0x0005, 0x96d3, 0x96d6, 0x9b44, 0x9bd3, 0x96d6,
-	0x9b44, 0x9bd3, 0x96d3, 0x96d6, 0x96d3, 0x96d3, 0x96d3, 0x96d3,
-	0x96d3, 0x96d3, 0x96d3, 0x080c, 0x95ff, 0x0005, 0x00b6, 0x0156,
-	0x0136, 0x0146, 0x01c6, 0x01d6, 0x00c6, 0x00d6, 0x00e6, 0x00f6,
-	0x2069, 0x0200, 0x2071, 0x0240, 0x6004, 0x908a, 0x0053, 0x1a0c,
+	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,
+	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,
+	0x00ce, 0x0005, 0x2001, 0x0382, 0x2004, 0x9084, 0x0007, 0x9086,
+	0x0001, 0x01b0, 0x00c6, 0x6146, 0x600f, 0x0000, 0x2c08, 0x2061,
+	0x19e6, 0x602c, 0x8000, 0x602e, 0x601c, 0x9005, 0x0130, 0x9080,
+	0x0003, 0x2102, 0x611e, 0x00ce, 0x0005, 0x6122, 0x611e, 0x0cd8,
+	0x6146, 0x2c08, 0x2001, 0x0012, 0x080c, 0xa90f, 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,
+	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,
+	0x2102, 0x6146, 0x00ce, 0x0005, 0x614a, 0x6146, 0x0cd8, 0x6146,
+	0x600f, 0x0000, 0x2c08, 0x2001, 0x0013, 0x080c, 0xa90f, 0x0005,
+	0x6044, 0xd0dc, 0x0110, 0x080c, 0xa3ac, 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,
+	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,
+	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,
+	0xff80, 0x0110, 0x9085, 0x0001, 0x0005, 0x00d6, 0x0096, 0x080c,
+	0x9b37, 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,
+	0xa8cc, 0x700a, 0xa8d0, 0x700e, 0xa8d4, 0x7012, 0xa8d8, 0x7016,
+	0xa8dc, 0x701a, 0xa8e0, 0x701e, 0x60c3, 0x0010, 0x080c, 0x9ea4,
+	0x009e, 0x00de, 0x0005, 0x00d6, 0x0096, 0x0126, 0x2091, 0x8000,
+	0x080c, 0x9b37, 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, 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,
+	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,
+	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,
-	0x908a, 0x0040, 0x1a04, 0x9742, 0x005b, 0x00fe, 0x00ee, 0x00de,
-	0x00ce, 0x01de, 0x01ce, 0x014e, 0x013e, 0x015e, 0x00be, 0x0005,
-	0x98c7, 0x9902, 0x992b, 0x99d3, 0x99f5, 0x99fb, 0x9a08, 0x9a10,
-	0x9a1c, 0x9a22, 0x9a33, 0x9a22, 0x9a8b, 0x9a10, 0x9a97, 0x9a9d,
-	0x9a1c, 0x9a9d, 0x9aa9, 0x9740, 0x9740, 0x9740, 0x9740, 0x9740,
-	0x9740, 0x9740, 0x9740, 0x9740, 0x9740, 0x9740, 0x9fde, 0xa001,
-	0xa012, 0xa032, 0xa064, 0x9a08, 0x9740, 0x9a08, 0x9a22, 0x9740,
-	0x992b, 0x99d3, 0x9740, 0xa425, 0x9a22, 0x9740, 0xa441, 0x9a22,
-	0x9740, 0x9a1c, 0x98c1, 0x9763, 0x9740, 0xa45d, 0xa4ca, 0xa5ae,
-	0x9740, 0xa5bb, 0x9a05, 0xa5e6, 0x9740, 0xa06e, 0xa5f2, 0x9740,
-	0x080c, 0x0d7d, 0x2100, 0x005b, 0x00fe, 0x00ee, 0x00de, 0x00ce,
-	0x01de, 0x01ce, 0x014e, 0x013e, 0x015e, 0x00be, 0x0005, 0xa692,
-	0xa744, 0x9761, 0x978a, 0x9836, 0x9841, 0x9761, 0x9a08, 0x9761,
-	0x9888, 0x9894, 0x97a5, 0x9761, 0x97c0, 0x97f4, 0xaace, 0xab13,
-	0x9a22, 0x080c, 0x0d7d, 0x00d6, 0x0096, 0x080c, 0x9abc, 0x7003,
-	0x2414, 0x7007, 0x0018, 0x700b, 0x0800, 0x7814, 0x2048, 0xa83c,
-	0x700e, 0xa850, 0x7022, 0xa854, 0x7026, 0x60c3, 0x0018, 0x080c,
-	0x9e1f, 0x009e, 0x00de, 0x0005, 0x7810, 0x00b6, 0x2058, 0xb8a0,
-	0x00be, 0x080c, 0xab5a, 0x1118, 0x9084, 0xff80, 0x0110, 0x9085,
-	0x0001, 0x0005, 0x00d6, 0x0096, 0x080c, 0x9abc, 0x7003, 0x0500,
-	0x7814, 0x2048, 0xa874, 0x700a, 0xa878, 0x700e, 0xa87c, 0x7012,
-	0xa880, 0x7016, 0xa884, 0x701a, 0xa888, 0x701e, 0x60c3, 0x0010,
-	0x080c, 0x9e1f, 0x009e, 0x00de, 0x0005, 0x00d6, 0x0096, 0x080c,
-	0x9abc, 0x7003, 0x0500, 0x7814, 0x2048, 0xa8cc, 0x700a, 0xa8d0,
-	0x700e, 0xa8d4, 0x7012, 0xa8d8, 0x7016, 0xa8dc, 0x701a, 0xa8e0,
-	0x701e, 0x60c3, 0x0010, 0x080c, 0x9e1f, 0x009e, 0x00de, 0x0005,
-	0x00d6, 0x0096, 0x0126, 0x2091, 0x8000, 0x080c, 0x9abc, 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, 0x21be, 0x080c, 0xd5f1, 0x9006, 0x080c, 0x21be, 0x001e,
-	0xa804, 0x9005, 0x0110, 0x2048, 0x0c28, 0x04d9, 0x080c, 0x9e1f,
-	0x012e, 0x009e, 0x00de, 0x0005, 0x00d6, 0x0096, 0x0126, 0x2091,
-	0x8000, 0x080c, 0x9b07, 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, 0xd5f1,
-	0x001e, 0xa804, 0x9005, 0x0110, 0x2048, 0x0c60, 0x0051, 0x7814,
-	0x2048, 0x080c, 0x0ff9, 0x080c, 0x9e1f, 0x012e, 0x009e, 0x00de,
-	0x0005, 0x60c0, 0x8004, 0x9084, 0x0003, 0x9005, 0x0130, 0x9082,
-	0x0004, 0x20a3, 0x0000, 0x8000, 0x1de0, 0x0005, 0x080c, 0x9abc,
-	0x7003, 0x7800, 0x7808, 0x8007, 0x700a, 0x60c3, 0x0008, 0x0804,
-	0x9e1f, 0x00d6, 0x00e6, 0x080c, 0x9b07, 0x7814, 0x9084, 0xff00,
-	0x2073, 0x0200, 0x8e70, 0x8e70, 0x9095, 0x0010, 0x2272, 0x8e70,
-	0x2073, 0x0034, 0x8e70, 0x2069, 0x1805, 0x20a9, 0x0004, 0x2d76,
-	0x8d68, 0x8e70, 0x1f04, 0x9857, 0x2069, 0x1801, 0x20a9, 0x0004,
-	0x2d76, 0x8d68, 0x8e70, 0x1f04, 0x9860, 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,
-	0x986e, 0x60c3, 0x004c, 0x080c, 0x9e1f, 0x00ee, 0x00de, 0x0005,
-	0x080c, 0x9abc, 0x7003, 0x6300, 0x7007, 0x0028, 0x7808, 0x700e,
-	0x60c3, 0x0008, 0x0804, 0x9e1f, 0x00d6, 0x0026, 0x0016, 0x080c,
-	0x9b07, 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, 0x9e1f, 0x001e, 0x002e, 0x00de,
-	0x0005, 0x2001, 0x1818, 0x2004, 0x609a, 0x0804, 0x9e1f, 0x080c,
-	0x9abc, 0x7003, 0x5200, 0x2069, 0x1847, 0x6804, 0xd084, 0x0130,
-	0x6828, 0x0016, 0x080c, 0x2663, 0x710e, 0x001e, 0x20a9, 0x0004,
-	0x20e1, 0x0001, 0x2099, 0x1805, 0x20e9, 0x0000, 0x20a1, 0x0250,
-	0x4003, 0x20a9, 0x0004, 0x2099, 0x1801, 0x20a1, 0x0254, 0x4003,
-	0x080c, 0xab5a, 0x1120, 0xb8a0, 0x9082, 0x007f, 0x0248, 0x2001,
-	0x181f, 0x2004, 0x7032, 0x2001, 0x1820, 0x2004, 0x7036, 0x0030,
-	0x2001, 0x1818, 0x2004, 0x9084, 0x00ff, 0x7036, 0x60c3, 0x001c,
-	0x0804, 0x9e1f, 0x080c, 0x9abc, 0x7003, 0x0500, 0x080c, 0xab5a,
-	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, 0x9e1f, 0x080c, 0x9abc, 0x9006, 0x080c, 0x6a58,
-	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, 0x999a, 0x00d6, 0x2069, 0x196b, 0x2001, 0x1837, 0x2004,
-	0xd0a4, 0x0188, 0x6800, 0x700a, 0x6808, 0x9084, 0x2000, 0x7012,
-	0x080c, 0xab71, 0x680c, 0x7016, 0x701f, 0x2710, 0x6818, 0x7022,
-	0x681c, 0x7026, 0x0090, 0x6800, 0x700a, 0x6804, 0x700e, 0x6808,
-	0x080c, 0x74ec, 0x1118, 0x9084, 0x37ff, 0x0010, 0x9084, 0x3fff,
-	0x7012, 0x080c, 0xab71, 0x680c, 0x7016, 0x00de, 0x20a9, 0x0004,
-	0x20e1, 0x0001, 0x2099, 0x1805, 0x20e9, 0x0000, 0x20a1, 0x0256,
-	0x4003, 0x20a9, 0x0004, 0x2099, 0x1801, 0x20a1, 0x025a, 0x4003,
-	0x00d6, 0x080c, 0xa679, 0x2069, 0x1973, 0x2071, 0x024e, 0x6800,
-	0xc0dd, 0x7002, 0x080c, 0x56f9, 0xd0e4, 0x0110, 0x680c, 0x700e,
-	0x00de, 0x04a8, 0x2001, 0x1837, 0x2004, 0xd0a4, 0x0170, 0x0016,
-	0x2001, 0x196c, 0x200c, 0x60e0, 0x9106, 0x0130, 0x2100, 0x60e3,
-	0x0000, 0x080c, 0x26a4, 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, 0xa679,
-	0x20a1, 0x024e, 0x20a9, 0x0008, 0x2099, 0x1973, 0x4003, 0x60c3,
-	0x0074, 0x0804, 0x9e1f, 0x080c, 0x9abc, 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, 0x9a6c,
-	0x7026, 0x60c3, 0x0014, 0x0804, 0x9e1f, 0x080c, 0x9abc, 0x7003,
-	0x5000, 0x0804, 0x9945, 0x080c, 0x9abc, 0x7003, 0x2110, 0x7007,
-	0x0014, 0x60c3, 0x0014, 0x0804, 0x9e1f, 0x080c, 0x9afe, 0x0010,
-	0x080c, 0x9b07, 0x7003, 0x0200, 0x60c3, 0x0004, 0x0804, 0x9e1f,
-	0x080c, 0x9b07, 0x7003, 0x0100, 0x700b, 0x0003, 0x700f, 0x2a00,
-	0x60c3, 0x0008, 0x0804, 0x9e1f, 0x080c, 0x9b07, 0x7003, 0x0200,
-	0x0804, 0x9945, 0x080c, 0x9b07, 0x7003, 0x0100, 0x782c, 0x9005,
-	0x0110, 0x700a, 0x0010, 0x700b, 0x0003, 0x7814, 0x700e, 0x60c3,
-	0x0008, 0x0804, 0x9e1f, 0x00d6, 0x080c, 0x9b07, 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, 0x9e1f, 0x080c, 0x9b07, 0x7003, 0x0210, 0x7007,
-	0x0014, 0x700f, 0x0100, 0x60c3, 0x0014, 0x0804, 0x9e1f, 0x080c,
-	0x9b07, 0x7003, 0x0200, 0x0804, 0x98cb, 0x080c, 0x9b07, 0x7003,
-	0x0100, 0x700b, 0x0003, 0x700f, 0x2a00, 0x60c3, 0x0008, 0x0804,
-	0x9e1f, 0x080c, 0x9b07, 0x7003, 0x0100, 0x700b, 0x000b, 0x60c3,
-	0x0008, 0x0804, 0x9e1f, 0x0026, 0x00d6, 0x0036, 0x0046, 0x2019,
-	0x3200, 0x2021, 0x0800, 0x0040, 0x0026, 0x00d6, 0x0036, 0x0046,
-	0x2019, 0x2200, 0x2021, 0x0100, 0x080c, 0xa68e, 0xb810, 0x9305,
-	0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0x687c, 0x700a, 0x6880,
-	0x700e, 0x9485, 0x0029, 0x7012, 0x004e, 0x003e, 0x00de, 0x080c,
-	0x9e13, 0x721a, 0x9f95, 0x0000, 0x7222, 0x7027, 0xffff, 0x2071,
-	0x024c, 0x002e, 0x0005, 0x0026, 0x080c, 0xa68e, 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,
-	0xa68e, 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, 0x9e13,
-	0x721a, 0x7a08, 0x7222, 0x2f10, 0x7226, 0x2071, 0x024c, 0x002e,
-	0x0005, 0x080c, 0x9e13, 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, 0x9b75, 0x9b84,
-	0x9b8f, 0x9b73, 0x9b73, 0x9b73, 0x9b75, 0x9b73, 0x9b73, 0x9b73,
-	0x9b73, 0x9b73, 0x9b73, 0x080c, 0x0d7d, 0x0411, 0x60c3, 0x0000,
-	0x0026, 0x080c, 0x29b4, 0x0228, 0x2011, 0x0101, 0x2204, 0xc0c5,
-	0x2012, 0x002e, 0x0804, 0x9e1f, 0x0431, 0x7808, 0x700a, 0x7814,
-	0x700e, 0x7017, 0xffff, 0x60c3, 0x000c, 0x0804, 0x9e1f, 0x0479,
-	0x7003, 0x0003, 0x7007, 0x0300, 0x60c3, 0x0004, 0x0804, 0x9e1f,
-	0x0026, 0x080c, 0xa68e, 0xb810, 0x9085, 0x8100, 0x7002, 0xb814,
-	0x7006, 0x2069, 0x1800, 0x687c, 0x700a, 0x6880, 0x700e, 0x7013,
-	0x0009, 0x0804, 0x9ad7, 0x0026, 0x080c, 0xa68e, 0xb810, 0x9085,
-	0x8400, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0x687c, 0x700a,
-	0x6880, 0x700e, 0x2001, 0x0099, 0x7012, 0x0804, 0x9b39, 0x0026,
-	0x080c, 0xa68e, 0xb810, 0x9085, 0x8500, 0x7002, 0xb814, 0x7006,
+	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,
-	0x7012, 0x0804, 0x9b39, 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, 0x9c08, 0x9c08, 0x9c08,
-	0x9c2e, 0x9c08, 0x9c08, 0x9c08, 0x9c08, 0x9c08, 0x9c08, 0x9c08,
-	0xa1da, 0xa1e2, 0xa1ea, 0xa1f2, 0x9c08, 0x9c08, 0x9c08, 0xa1d2,
-	0x080c, 0x0d7d, 0x6813, 0x0008, 0xba8c, 0x8210, 0xb8d4, 0xd084,
-	0x0128, 0x7a4e, 0x7b14, 0x7b52, 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, 0x9c3e, 0x9c3e,
-	0x9c40, 0x9c3e, 0x9c3e, 0x9c3e, 0x9c5a, 0x9c3e, 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, 0x9e1f, 0x2009, 0x0003, 0x0019, 0x7033, 0x7f00, 0x0cb0,
-	0x0016, 0x080c, 0xa68e, 0x001e, 0xb810, 0x9085, 0x0100, 0x7002,
-	0xb814, 0x7006, 0x2069, 0x1800, 0x6a7c, 0x720a, 0x6a80, 0x720e,
-	0x7013, 0x0888, 0x918d, 0x0008, 0x7116, 0x080c, 0x9e13, 0x721a,
-	0x7a08, 0x7222, 0x2f10, 0x7226, 0x0005, 0x00b6, 0x00e6, 0x00d6,
+	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, 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, 0x2a83, 0x2001, 0x00b2, 0x2010,
-	0x900e, 0x080c, 0x2a92, 0x2009, 0x07d0, 0x080c, 0x870e, 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, 0x3388, 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, 0x2a92, 0x2009, 0x07d0, 0x080c, 0x870e,
-	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, 0x9d9e,
-	0x9d9e, 0x9d9e, 0x9d9e, 0x9d9e, 0x9d9e, 0x9d9e, 0x9d9e, 0x9d9e,
-	0x9d9e, 0x9da0, 0x9d9e, 0x9d9e, 0x9d9e, 0x9d9e, 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, 0xa66e, 0x2009,
-	0x07d0, 0x60c4, 0x9084, 0xfff0, 0x9005, 0x0110, 0x2009, 0x1b58,
-	0x080c, 0x870e, 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, 0x8700, 0x0005, 0x0016,
-	0x2001, 0x180c, 0x200c, 0x9184, 0x0600, 0x9086, 0x0600, 0x0128,
-	0x0089, 0x080c, 0x8700, 0x001e, 0x0005, 0xc1e5, 0x2001, 0x180c,
-	0x2102, 0x2001, 0x19e7, 0x2003, 0x0000, 0x2001, 0x19f2, 0x2003,
-	0x0000, 0x0c88, 0x0006, 0x0016, 0x0026, 0x2009, 0x1804, 0x2011,
-	0x0009, 0x080c, 0x2a92, 0x002e, 0x001e, 0x000e, 0x0005, 0x0016,
-	0x00c6, 0x0006, 0x080c, 0xa899, 0x0106, 0x2061, 0x0100, 0x61a4,
-	0x60a7, 0x95f5, 0x0016, 0x0026, 0x2009, 0x1804, 0x2011, 0x0008,
-	0x080c, 0x2a92, 0x002e, 0x001e, 0x010e, 0x090c, 0xa8b5, 0x000e,
-	0xa001, 0xa001, 0xa001, 0x61a6, 0x00ce, 0x001e, 0x0005, 0x00c6,
-	0x00d6, 0x0016, 0x0026, 0x2061, 0x0100, 0x2069, 0x0140, 0x080c,
-	0x74ec, 0x1510, 0x2001, 0x1a0b, 0x2004, 0x9005, 0x1904, 0x9ece,
-	0x080c, 0x7591, 0x11a8, 0x2069, 0x0380, 0x6843, 0x0101, 0x6844,
-	0xd084, 0x1de8, 0x2061, 0x0100, 0x6020, 0xd0b4, 0x1120, 0x6024,
-	0xd084, 0x090c, 0x0d7d, 0x6843, 0x0100, 0x080c, 0x8700, 0x04b0,
-	0x00c6, 0x2061, 0x19e6, 0x00f0, 0x6904, 0x9194, 0x4000, 0x0598,
-	0x080c, 0x9e4f, 0x080c, 0x2a59, 0x00c6, 0x2061, 0x19e6, 0x6134,
-	0x9192, 0x0008, 0x1278, 0x8108, 0x6136, 0x080c, 0xa899, 0x6130,
-	0x080c, 0xa8b5, 0x00ce, 0x81ff, 0x01c8, 0x080c, 0x8700, 0x080c,
-	0x9e42, 0x00a0, 0x080c, 0xa899, 0x6130, 0x91e5, 0x0000, 0x0150,
-	0x080c, 0xe764, 0x080c, 0x8709, 0x6003, 0x0001, 0x2009, 0x0014,
-	0x080c, 0xac8d, 0x080c, 0xa8b5, 0x00ce, 0x0000, 0x002e, 0x001e,
-	0x00de, 0x00ce, 0x0005, 0x2001, 0x1a0b, 0x2004, 0x9005, 0x1db0,
-	0x00c6, 0x2061, 0x19e6, 0x6134, 0x9192, 0x0003, 0x1ad8, 0x8108,
-	0x6136, 0x00ce, 0x080c, 0x8700, 0x080c, 0x5eff, 0x2009, 0x1846,
-	0x2114, 0x8210, 0x220a, 0x0c10, 0x0096, 0x00c6, 0x00d6, 0x00e6,
-	0x0016, 0x0026, 0x080c, 0x8716, 0x080c, 0xa899, 0x2001, 0x0387,
-	0x2003, 0x0202, 0x2071, 0x19e6, 0x714c, 0x81ff, 0x0904, 0x9f76,
-	0x2061, 0x0100, 0x2069, 0x0140, 0x080c, 0x74ec, 0x1510, 0x0036,
-	0x2019, 0x0002, 0x080c, 0xa133, 0x003e, 0x714c, 0x2160, 0x080c,
-	0xe764, 0x2009, 0x004a, 0x6220, 0x9296, 0x0009, 0x1130, 0x6114,
-	0x2148, 0xa87b, 0x0006, 0x2009, 0x004a, 0x6003, 0x0003, 0x080c,
-	0xac8d, 0x2001, 0x0386, 0x2003, 0x5040, 0x080c, 0x7591, 0x0804,
-	0x9f76, 0x6904, 0xd1f4, 0x0904, 0x9f83, 0x080c, 0x2a59, 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, 0x965a, 0x2009,
-	0x0049, 0x080c, 0xac8d, 0x00d0, 0x0036, 0x2019, 0x0001, 0x080c,
-	0xa133, 0x003e, 0x714c, 0x2160, 0x080c, 0xe764, 0x2009, 0x004a,
+	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,
+	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, 0xac8d, 0x2001, 0x0387,
-	0x2003, 0x0200, 0x080c, 0xa8b5, 0x002e, 0x001e, 0x00ee, 0x00de,
-	0x00ce, 0x009e, 0x0005, 0xd1ec, 0x1904, 0x9f2d, 0x0804, 0x9f2f,
-	0x0026, 0x00e6, 0x2071, 0x19e6, 0x706c, 0xd084, 0x01e8, 0xc084,
-	0x706e, 0x714c, 0x81ff, 0x01c0, 0x2071, 0x0100, 0x9188, 0x0008,
-	0x2114, 0x928e, 0x0006, 0x1138, 0x2009, 0x1984, 0x2011, 0x0012,
-	0x080c, 0x2a92, 0x0048, 0x928e, 0x0009, 0x0db0, 0x2009, 0x1984,
-	0x2011, 0x0016, 0x080c, 0x2a92, 0x00ee, 0x002e, 0x0005, 0x9036,
-	0x2001, 0x19f0, 0x2004, 0x9005, 0x0128, 0x9c06, 0x0128, 0x2c30,
-	0x600c, 0x0cc8, 0x9085, 0x0001, 0x0005, 0x00f6, 0x2079, 0x19e6,
-	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, 0xa1fd, 0x080c, 0xca54, 0x00fe, 0x0005, 0x080c, 0x9abc,
-	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,
-	0x9e1f, 0x080c, 0x9abc, 0x7003, 0x0f00, 0x7808, 0xd09c, 0x0128,
-	0xb810, 0x9084, 0x00ff, 0x700a, 0xb814, 0x700e, 0x60c3, 0x0008,
-	0x0804, 0x9e1f, 0x0156, 0x080c, 0x9b07, 0x7003, 0x0200, 0x080c,
-	0x87ce, 0x20a9, 0x0006, 0x2011, 0xffec, 0x2019, 0xffed, 0x9ef0,
-	0x0002, 0x2305, 0x2072, 0x8e70, 0x2205, 0x2072, 0x8e70, 0x9398,
-	0x0002, 0x9290, 0x0002, 0x1f04, 0xa021, 0x60c3, 0x001c, 0x015e,
-	0x0804, 0x9e1f, 0x0016, 0x0026, 0x080c, 0x9ae3, 0x080c, 0x9af5,
-	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, 0x9e1f, 0x002e,
-	0x001e, 0x0005, 0x20a9, 0x0010, 0x4003, 0x080c, 0xa679, 0x20a1,
-	0x0240, 0x22a8, 0x4003, 0x0c68, 0x080c, 0x9abc, 0x7003, 0x6200,
-	0x7808, 0x700e, 0x60c3, 0x0008, 0x0804, 0x9e1f, 0x0016, 0x0026,
-	0x080c, 0x9abc, 0x20e9, 0x0000, 0x20a1, 0x024c, 0x7814, 0x0096,
-	0x2048, 0xa800, 0x2048, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0023,
-	0x2098, 0x009e, 0x7808, 0x9088, 0x0002, 0x21a8, 0x4003, 0x8003,
-	0x60c2, 0x080c, 0x9e1f, 0x002e, 0x001e, 0x0005, 0x00e6, 0x00c6,
-	0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19e6, 0x7010, 0x2060,
-	0x8cff, 0x0188, 0x080c, 0xca7a, 0x1110, 0x080c, 0xb5c6, 0x600c,
-	0x0006, 0x080c, 0xccf6, 0x600f, 0x0000, 0x080c, 0xabf0, 0x080c,
-	0xa1fd, 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,
-	0x9e4f, 0x6ac0, 0x68c3, 0x0000, 0x080c, 0x8709, 0x00c6, 0x2061,
-	0x0100, 0x080c, 0xa7ca, 0x00ce, 0x20a9, 0x01f4, 0x04b1, 0x080c,
-	0x95ff, 0x6044, 0xd0ac, 0x1128, 0x2001, 0x1987, 0x2004, 0x604a,
-	0x0020, 0x2009, 0x0013, 0x080c, 0xac8d, 0x000e, 0x001e, 0x002e,
-	0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x015e, 0x012e, 0x0005,
-	0x2001, 0x1800, 0x2004, 0x9096, 0x0001, 0x0d78, 0x9096, 0x0004,
-	0x0d60, 0x080c, 0x8709, 0x6814, 0x9084, 0x0001, 0x0110, 0x68a7,
-	0x95f5, 0x6817, 0x0008, 0x68c3, 0x0000, 0x2011, 0x5ea9, 0x080c,
-	0x8651, 0x20a9, 0x01f4, 0x0009, 0x08c0, 0x6824, 0xd094, 0x0140,
-	0x6827, 0x0004, 0x7804, 0x9084, 0x4000, 0x190c, 0x2a59, 0x0090,
-	0xd084, 0x0118, 0x6827, 0x0001, 0x0010, 0x1f04, 0xa115, 0x7804,
-	0x9084, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2a49, 0x9006,
-	0x080c, 0x2a49, 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, 0xa1ac, 0x9386, 0x0002,
-	0x1128, 0x6814, 0x9084, 0x0002, 0x0904, 0xa1ac, 0x68af, 0x95f5,
-	0x6817, 0x0010, 0x2009, 0x00fa, 0x8109, 0x1df0, 0x69c6, 0x68cb,
-	0x0008, 0x080c, 0x8716, 0x080c, 0x1dfd, 0x2001, 0x0032, 0x6920,
-	0xd1bc, 0x0130, 0x8001, 0x1dd8, 0x692c, 0x918d, 0x0008, 0x692e,
-	0x20a9, 0x03e8, 0x6824, 0xd094, 0x0140, 0x6827, 0x0004, 0x7804,
-	0x9084, 0x4000, 0x190c, 0x2a59, 0x0090, 0xd08c, 0x0118, 0x6827,
-	0x0002, 0x0010, 0x1f04, 0xa17a, 0x7804, 0x9084, 0x1000, 0x0138,
-	0x2001, 0x0100, 0x080c, 0x2a49, 0x9006, 0x080c, 0x2a49, 0x6827,
-	0x4000, 0x6824, 0x83ff, 0x1180, 0x2009, 0x0049, 0x6020, 0x9086,
-	0x0009, 0x0150, 0x080c, 0x965a, 0x6044, 0xd0ac, 0x1118, 0x6003,
-	0x0002, 0x0010, 0x080c, 0xac8d, 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, 0x9c0a, 0x785c, 0x7032, 0x7042, 0x7047,
-	0x1000, 0x00f8, 0x080c, 0x9c0a, 0x785c, 0x7032, 0x7042, 0x7047,
-	0x4000, 0x00b8, 0x080c, 0x9c0a, 0x785c, 0x7032, 0x7042, 0x7047,
-	0x2000, 0x0078, 0x080c, 0x9c0a, 0x785c, 0x7032, 0x7042, 0x7047,
-	0x0400, 0x0038, 0x080c, 0x9c0a, 0x785c, 0x7032, 0x7042, 0x7047,
-	0x0200, 0x60c3, 0x0020, 0x0804, 0x9e1f, 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, 0xa2a2, 0x8cff, 0x0904, 0xa2a2, 0x6020, 0x9086,
-	0x0006, 0x1904, 0xa29d, 0x88ff, 0x0138, 0x2800, 0x9c06, 0x1904,
-	0xa29d, 0x2039, 0x0000, 0x0050, 0x6010, 0x9b06, 0x1904, 0xa29d,
-	0x85ff, 0x0120, 0x605c, 0x9106, 0x1904, 0xa29d, 0x7030, 0x9c06,
-	0x15b0, 0x2069, 0x0100, 0x68c0, 0x9005, 0x1160, 0x6824, 0xd084,
-	0x0148, 0x6827, 0x0001, 0x080c, 0x8709, 0x080c, 0xa327, 0x7033,
-	0x0000, 0x0428, 0x080c, 0x8709, 0x6820, 0xd0b4, 0x0110, 0x68a7,
-	0x95f5, 0x6817, 0x0008, 0x68c3, 0x0000, 0x080c, 0xa327, 0x7033,
-	0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138,
-	0x2001, 0x0100, 0x080c, 0x2a49, 0x9006, 0x080c, 0x2a49, 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, 0xc863,
-	0x0110, 0x080c, 0xe2b9, 0x009e, 0x080c, 0xac2b, 0x080c, 0xa1fd,
-	0x88ff, 0x1190, 0x00ce, 0x0804, 0xa218, 0x2c78, 0x600c, 0x2060,
-	0x0804, 0xa218, 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, 0xa316, 0x6020, 0x9086, 0x0006,
-	0x1904, 0xa311, 0x87ff, 0x0128, 0x2700, 0x9c06, 0x1904, 0xa311,
-	0x0040, 0x6010, 0x9b06, 0x15e8, 0x85ff, 0x0118, 0x605c, 0x9106,
-	0x15c0, 0x704c, 0x9c06, 0x1168, 0x0036, 0x2019, 0x0001, 0x080c,
-	0xa133, 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, 0xc863, 0x0110,
-	0x080c, 0xe2b9, 0x080c, 0xac2b, 0x87ff, 0x1198, 0x00ce, 0x0804,
-	0xa2c2, 0x2c78, 0x600c, 0x2060, 0x0804, 0xa2c2, 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,
+	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,
+	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,
+	0x01c0, 0x2071, 0x0100, 0x9188, 0x0008, 0x2114, 0x928e, 0x0006,
+	0x1138, 0x2009, 0x1984, 0x2011, 0x0012, 0x080c, 0x2ac3, 0x0048,
+	0x928e, 0x0009, 0x0db0, 0x2009, 0x1984, 0x2011, 0x0016, 0x080c,
+	0x2ac3, 0x00ee, 0x002e, 0x0005, 0x9036, 0x2001, 0x19f0, 0x2004,
+	0x9005, 0x0128, 0x9c06, 0x0128, 0x2c30, 0x600c, 0x0cc8, 0x9085,
+	0x0001, 0x0005, 0x00f6, 0x2079, 0x19e6, 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,
+	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,
+	0x7003, 0x0f00, 0x7808, 0xd09c, 0x0128, 0xb810, 0x9084, 0x00ff,
+	0x700a, 0xb814, 0x700e, 0x60c3, 0x0008, 0x0804, 0x9ea4, 0x0156,
+	0x080c, 0x9b82, 0x7003, 0x0200, 0x080c, 0x8845, 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,
+	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,
+	0x0000, 0x20a1, 0x024c, 0x7814, 0x0096, 0x2048, 0xa800, 0x2048,
+	0xa860, 0x20e0, 0xa85c, 0x9080, 0x0023, 0x2098, 0x009e, 0x7808,
+	0x9088, 0x0002, 0x21a8, 0x4003, 0x8003, 0x60c2, 0x080c, 0x9ea4,
+	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,
+	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,
+	0x00ee, 0x00fe, 0x015e, 0x012e, 0x0005, 0x2001, 0x1800, 0x2004,
+	0x9096, 0x0001, 0x0d78, 0x9096, 0x0004, 0x0d60, 0x080c, 0x8780,
+	0x6814, 0x9084, 0x0001, 0x0110, 0x68a7, 0x95f5, 0x6817, 0x0008,
+	0x68c3, 0x0000, 0x2011, 0x5ef7, 0x080c, 0x86c8, 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,
+	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, 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, 0x95ff,
-	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, 0xa414, 0x6010, 0x00b6, 0x2058, 0xb8a0, 0x00be, 0x9206,
-	0x1904, 0xa40f, 0x7030, 0x9c06, 0x1520, 0x2069, 0x0100, 0x68c0,
-	0x9005, 0x0904, 0xa3e6, 0x080c, 0x9e4f, 0x68c3, 0x0000, 0x080c,
-	0xa327, 0x7033, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384,
-	0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2a49, 0x9006, 0x080c,
-	0x2a49, 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, 0xca69, 0x1180, 0x080c, 0x323e,
-	0x080c, 0xca7a, 0x1518, 0x080c, 0xb5c6, 0x0400, 0x080c, 0xa327,
-	0x6824, 0xd084, 0x09b0, 0x6827, 0x0001, 0x0898, 0x080c, 0xca7a,
-	0x1118, 0x080c, 0xb5c6, 0x0090, 0x6014, 0x2048, 0x080c, 0xc863,
-	0x0168, 0x6020, 0x9086, 0x0003, 0x1508, 0xa867, 0x0103, 0xab7a,
-	0xa877, 0x0000, 0x080c, 0x6d93, 0x080c, 0xca54, 0x080c, 0xccf6,
-	0x080c, 0xac2b, 0x080c, 0xa1fd, 0x00ce, 0x0804, 0xa38f, 0x2c78,
-	0x600c, 0x2060, 0x0804, 0xa38f, 0x012e, 0x000e, 0x002e, 0x006e,
-	0x00ce, 0x00de, 0x00ee, 0x00fe, 0x009e, 0x0005, 0x6020, 0x9086,
-	0x0006, 0x1d20, 0x080c, 0xe2b9, 0x0c08, 0x00d6, 0x080c, 0x9b07,
-	0x7003, 0x0200, 0x7007, 0x0014, 0x60c3, 0x0014, 0x20e1, 0x0001,
-	0x2099, 0x1988, 0x20e9, 0x0000, 0x20a1, 0x0250, 0x20a9, 0x0004,
-	0x4003, 0x7023, 0x0004, 0x7027, 0x7878, 0x080c, 0x9e1f, 0x00de,
-	0x0005, 0x080c, 0x9b07, 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, 0x9e1f, 0x00b6, 0x00d6, 0x0016,
-	0x00d6, 0x2f68, 0x2009, 0x0035, 0x080c, 0xcefc, 0x00de, 0x1904,
-	0xa4c2, 0x080c, 0x9abc, 0x7003, 0x1300, 0x782c, 0x080c, 0xa5d1,
-	0x2068, 0x6820, 0x9086, 0x0003, 0x0560, 0x7810, 0x2058, 0xbaa0,
-	0x080c, 0xab5a, 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, 0xab5a, 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, 0x9e1f,
-	0x00be, 0x0005, 0x781b, 0x0001, 0x7803, 0x0006, 0x001e, 0x00de,
-	0x00be, 0x0005, 0x792c, 0x9180, 0x0008, 0x200c, 0x9186, 0x0006,
-	0x01c0, 0x9186, 0x0003, 0x0904, 0xa541, 0x9186, 0x0005, 0x0904,
-	0xa529, 0x9186, 0x0004, 0x05f0, 0x9186, 0x0008, 0x0904, 0xa532,
-	0x7807, 0x0037, 0x782f, 0x0003, 0x7817, 0x1700, 0x080c, 0xa5ae,
-	0x0005, 0x080c, 0xa56f, 0x00d6, 0x0026, 0x792c, 0x2168, 0x2009,
-	0x4000, 0x6800, 0x6a44, 0xd2fc, 0x11f8, 0x0002, 0xa509, 0xa514,
-	0xa50b, 0xa514, 0xa510, 0xa509, 0xa509, 0xa514, 0xa514, 0xa514,
-	0xa514, 0xa509, 0xa509, 0xa509, 0xa509, 0xa509, 0xa514, 0xa509,
-	0xa514, 0x080c, 0x0d7d, 0x6824, 0xd0e4, 0x0110, 0xd0cc, 0x0110,
-	0x900e, 0x0010, 0x2009, 0x2000, 0x682c, 0x7022, 0x6830, 0x7026,
-	0x0804, 0xa568, 0x080c, 0xa56f, 0x00d6, 0x0026, 0x792c, 0x2168,
-	0x2009, 0x4000, 0x6a00, 0x9286, 0x0002, 0x1108, 0x900e, 0x0804,
-	0xa568, 0x080c, 0xa56f, 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, 0x9e1f, 0x00b6,
-	0x0036, 0x0046, 0x0056, 0x0066, 0x080c, 0x9b07, 0x9006, 0x7003,
-	0x0200, 0x7938, 0x710a, 0x793c, 0x710e, 0x7810, 0x2058, 0xb8a0,
-	0x080c, 0xab5a, 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, 0x9b07,
-	0x7003, 0x0100, 0x782c, 0x700a, 0x7814, 0x700e, 0x700e, 0x60c3,
-	0x0008, 0x0804, 0x9e1f, 0x080c, 0x9ab3, 0x7003, 0x1400, 0x7838,
-	0x700a, 0x0079, 0x783c, 0x700e, 0x782c, 0x7012, 0x7830, 0x7016,
-	0x7834, 0x9084, 0x00ff, 0x8007, 0x701a, 0x60c3, 0x0010, 0x0804,
-	0x9e1f, 0x00e6, 0x2071, 0x0240, 0x0006, 0x00f6, 0x2078, 0x7810,
-	0x00b6, 0x2058, 0xb8d4, 0xd084, 0x0120, 0x7850, 0x702a, 0x784c,
-	0x702e, 0x00be, 0x00fe, 0x000e, 0x00ee, 0x0005, 0x080c, 0x9afe,
-	0x7003, 0x0100, 0x782c, 0x700a, 0x7814, 0x700e, 0x60c3, 0x0008,
-	0x0804, 0x9e1f, 0x00a9, 0x7914, 0x712a, 0x60c3, 0x0000, 0x60a7,
-	0x9575, 0x0026, 0x080c, 0x29b4, 0x0228, 0x2011, 0x0101, 0x2204,
-	0xc0c5, 0x2012, 0x002e, 0x080c, 0x9e42, 0x080c, 0x8700, 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, 0xa68e, 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, 0x2a92, 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, 0x9abc, 0x0016, 0x0026, 0x0096, 0x00d6,
-	0x7814, 0x2048, 0x7013, 0x0138, 0x2001, 0x1837, 0x2004, 0x9084,
-	0x0028, 0x1138, 0x2001, 0x197b, 0x2004, 0x9086, 0xaaaa, 0x1904,
-	0xa733, 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, 0xa6c4, 0x20a9, 0x0004, 0x2009, 0x1801, 0x2104, 0x2012,
-	0x8108, 0x8210, 0x1f04, 0xa6ce, 0xa860, 0x20e0, 0xa85c, 0x9080,
-	0x0029, 0x2098, 0x2009, 0x0006, 0x20a9, 0x0001, 0x4002, 0x8007,
-	0x2012, 0x8210, 0x8109, 0x1dc0, 0x00d6, 0x2069, 0x0200, 0x080c,
-	0xa679, 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, 0x74ec, 0x0150,
-	0x6028, 0xc0bd, 0x602a, 0x2009, 0x1804, 0x2011, 0x0029, 0x080c,
-	0x2a92, 0x0010, 0x080c, 0x9e1f, 0x080c, 0x8700, 0x00de, 0x009e,
-	0x002e, 0x001e, 0x0005, 0x00e6, 0x2071, 0x0240, 0x2001, 0x2200,
-	0x9085, 0x00ff, 0x7002, 0x7007, 0xffff, 0x2071, 0x0100, 0x709b,
-	0x00ff, 0x00ee, 0x0804, 0xa6a9, 0x080c, 0x9abc, 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,
+	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, 0x20a9, 0x0004, 0x2009, 0x1805, 0x2104, 0x2012, 0x8108,
-	0x8210, 0x1f04, 0xa785, 0x20a9, 0x0002, 0x2009, 0x1801, 0x2104,
-	0x2012, 0x8108, 0x8210, 0x1f04, 0xa78f, 0x00d6, 0x0016, 0x2069,
-	0x0200, 0x080c, 0xa679, 0x001e, 0x00de, 0x2071, 0x0240, 0x20a9,
-	0x0002, 0x2009, 0x1803, 0x2011, 0x0240, 0x2104, 0x2012, 0x8108,
-	0x8210, 0x1f04, 0xa7a5, 0x2009, 0x0008, 0x4002, 0x8007, 0x2012,
-	0x8210, 0x8109, 0x1dd0, 0x9006, 0x20a9, 0x0008, 0x2012, 0x8210,
-	0x1f04, 0xa7b6, 0x00ce, 0x60c3, 0x004c, 0x60a3, 0x0056, 0x60a7,
-	0x9575, 0x080c, 0x9e1f, 0x080c, 0x8700, 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, 0xa876, 0x7030, 0x9c06, 0x1520, 0x2069,
-	0x0100, 0x68c0, 0x9005, 0x0904, 0xa848, 0x080c, 0x9e4f, 0x68c3,
-	0x0000, 0x080c, 0xa327, 0x7033, 0x0000, 0x0036, 0x2069, 0x0140,
-	0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2a49,
-	0x9006, 0x080c, 0x2a49, 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, 0xca69, 0x1180,
-	0x080c, 0x323e, 0x080c, 0xca7a, 0x1518, 0x080c, 0xb5c6, 0x0400,
-	0x080c, 0xa327, 0x6824, 0xd084, 0x09b0, 0x6827, 0x0001, 0x0898,
-	0x080c, 0xca7a, 0x1118, 0x080c, 0xb5c6, 0x0090, 0x6014, 0x2048,
-	0x080c, 0xc863, 0x0168, 0x6020, 0x9086, 0x0003, 0x1520, 0xa867,
-	0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0x6d9f, 0x080c, 0xca54,
-	0x080c, 0xccf6, 0x080c, 0xac2b, 0x080c, 0xa1fd, 0x00ce, 0x0804,
-	0xa7f9, 0x2c78, 0x600c, 0x2060, 0x0804, 0xa7f9, 0x7013, 0x0000,
-	0x700f, 0x0000, 0x012e, 0x006e, 0x009e, 0x00ae, 0x00ce, 0x00de,
-	0x00ee, 0x00fe, 0x0005, 0x6020, 0x9086, 0x0006, 0x1d08, 0x080c,
-	0xe2b9, 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, 0xa8d2, 0x080c,
-	0x0d7d, 0x080c, 0xa899, 0x6044, 0xd0fc, 0x0190, 0x7030, 0x9c06,
-	0x1148, 0x080c, 0x95ff, 0x6044, 0xd0dc, 0x0150, 0xc0dc, 0x6046,
-	0x700a, 0x7042, 0x704c, 0x9c06, 0x190c, 0x0d7d, 0x080c, 0x965a,
-	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, 0xa91f,
-	0xa95d, 0xa984, 0xa9bb, 0xa9cb, 0xa9dc, 0xa9eb, 0xa9f9, 0xaa26,
-	0xaa2a, 0xa91f, 0xa91f, 0xa91f, 0xa91f, 0xa91f, 0xa91f, 0x080c,
-	0x0d7d, 0x012e, 0x0005, 0x2060, 0x6044, 0xd0bc, 0x0140, 0xc0bc,
-	0x6046, 0x6000, 0x908a, 0x0016, 0x1a0c, 0x0d7d, 0x0012, 0x012e,
-	0x0005, 0xa944, 0xa946, 0xa944, 0xa94c, 0xa944, 0xa944, 0xa944,
-	0xa944, 0xa944, 0xa946, 0xa944, 0xa946, 0xa944, 0xa946, 0xa944,
-	0xa944, 0xa944, 0xa946, 0xa944, 0x080c, 0x0d7d, 0x2009, 0x0013,
-	0x080c, 0xac8d, 0x012e, 0x0005, 0x6014, 0x2048, 0xa87c, 0xd0dc,
-	0x0130, 0x080c, 0x88d7, 0x080c, 0xabf0, 0x012e, 0x0005, 0x2009,
-	0x0049, 0x080c, 0xac8d, 0x012e, 0x0005, 0x080c, 0xa899, 0x2001,
-	0x1a0b, 0x2003, 0x0000, 0x7030, 0x9065, 0x090c, 0x0d7d, 0x7034,
-	0x9092, 0x00c8, 0x1258, 0x8000, 0x7036, 0x7004, 0x9086, 0x0003,
-	0x0110, 0x7007, 0x0000, 0x781f, 0x0808, 0x0040, 0x080c, 0xe764,
-	0x6003, 0x0001, 0x2009, 0x0014, 0x080c, 0xac8d, 0x781f, 0x0100,
-	0x080c, 0xa8b5, 0x012e, 0x0005, 0x080c, 0xa899, 0x714c, 0x81ff,
+	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,
+	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, 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,
-	0xa8b5, 0x012e, 0x0005, 0x080c, 0xa899, 0x714c, 0x2160, 0x6003,
-	0x0003, 0x2009, 0x004a, 0x080c, 0xac8d, 0x781f, 0x0200, 0x080c,
-	0xa8b5, 0x012e, 0x0005, 0x7808, 0xd09c, 0x0de8, 0x7820, 0x2060,
-	0x6003, 0x0003, 0x080c, 0xa899, 0x080c, 0x1d85, 0x781f, 0x0400,
-	0x080c, 0xa8b5, 0x012e, 0x0005, 0x7808, 0xd09c, 0x0de8, 0x7820,
-	0x2060, 0x080c, 0xa899, 0x080c, 0x1dcd, 0x781f, 0x0400, 0x080c,
-	0xa8b5, 0x012e, 0x0005, 0x7030, 0x9065, 0x0148, 0x6044, 0xc0bc,
-	0x6046, 0x7104, 0x9186, 0x0003, 0x0110, 0x080c, 0x96be, 0x012e,
+	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, 0x9d79, 0x00c0, 0x7828, 0xd0fc, 0x1118, 0x080c, 0x9cf8,
+	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, 0x9c7d, 0x00fe, 0x012e, 0x0005, 0x080c, 0x7591,
+	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, 0xa133, 0x704f, 0x0000, 0x2001, 0x0109,
+	0x2019, 0x0001, 0x080c, 0xa1b8, 0x704f, 0x0000, 0x2001, 0x0109,
 	0x2004, 0xd08c, 0x1138, 0x2001, 0x0108, 0x2004, 0xd0bc, 0x1110,
-	0x703f, 0x0000, 0x080c, 0xa33e, 0x00ee, 0x0005, 0x0026, 0x7010,
-	0x9c06, 0x1178, 0x080c, 0xa1fd, 0x6044, 0xc0fc, 0x6046, 0x600c,
+	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,
-	0xa1fd, 0x6044, 0xc0fc, 0x6046, 0x600c, 0x9015, 0x0120, 0x7222,
+	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, 0x8709, 0x080c, 0x9e4f, 0x68c3, 0x0000,
-	0x080c, 0xa327, 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138,
-	0x2001, 0x0100, 0x080c, 0x2a49, 0x9006, 0x080c, 0x2a49, 0x2069,
+	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, 0xa8ff, 0x003e, 0x001e,
+	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, 0x9b07, 0x7a14, 0x82ff, 0x0138, 0x7003, 0x0100, 0x700b,
+	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, 0x74ec, 0x1110, 0xc3ad, 0x0008, 0xc3a5, 0x6adc,
-	0xd29c, 0x1110, 0xd2ac, 0x0108, 0xc39d, 0x730e, 0x080c, 0x87ce,
+	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, 0xab00, 0x60c3, 0x0020, 0x080c, 0x9e1f,
-	0x015e, 0x00de, 0x0005, 0x0156, 0x080c, 0x9b07, 0x7a14, 0x82ff,
+	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,
@@ -5277,12 +5294,19 @@
 	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, 0x9e1f, 0x0006, 0x2001, 0x1837, 0x2004, 0xd0ac, 0x000e,
-	0x0005, 0x2011, 0x0003, 0x080c, 0xa1be, 0x2011, 0x0002, 0x080c,
-	0xa1c8, 0x080c, 0xa0b3, 0x0036, 0x901e, 0x080c, 0xa133, 0x003e,
-	0x0005, 0x080c, 0x3381, 0x0188, 0x0016, 0x00b6, 0x00c6, 0x7010,
-	0x9085, 0x0020, 0x7012, 0x2009, 0x007e, 0x080c, 0x6644, 0xb85c,
-	0xc0ac, 0xb85e, 0x00ce, 0x00be, 0x001e, 0x0005, 0x2071, 0x188d,
+	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,
@@ -5304,43 +5328,43 @@
 	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, 0x1a94, 0x6023, 0x0007, 0x2001, 0x1985,
+	0x601c, 0xd084, 0x190c, 0x1ac5, 0x6023, 0x0007, 0x2001, 0x1985,
 	0x2004, 0x0006, 0x9082, 0x0051, 0x000e, 0x0208, 0x8004, 0x601a,
-	0x080c, 0xe571, 0x604b, 0x0000, 0x6044, 0xd0fc, 0x1129, 0x9006,
-	0x6046, 0x6016, 0x000e, 0x0005, 0x080c, 0xa899, 0x0106, 0x2001,
+	0x080c, 0xe6a0, 0x604b, 0x0000, 0x6044, 0xd0fc, 0x1129, 0x9006,
+	0x6046, 0x6016, 0x000e, 0x0005, 0x080c, 0xa91e, 0x0106, 0x2001,
 	0x19f9, 0x2004, 0x9c06, 0x1130, 0x0036, 0x2019, 0x0001, 0x080c,
-	0xa133, 0x003e, 0x080c, 0xa33e, 0x010e, 0x090c, 0xa8b5, 0x0005,
+	0xa1b8, 0x003e, 0x080c, 0xa3c3, 0x010e, 0x090c, 0xa93a, 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, 0xaca1, 0xacab, 0xacc6, 0xace1, 0xcfd7, 0xcff4, 0xd00f,
-	0xaca1, 0xacab, 0x8fb5, 0xacfd, 0xaca1, 0xaca1, 0xaca1, 0xaca1,
-	0xaca1, 0x9186, 0x0013, 0x1130, 0x6044, 0xd0fc, 0x0110, 0x080c,
-	0x95ff, 0x0005, 0x0005, 0x0066, 0x6000, 0x90b2, 0x0016, 0x1a0c,
-	0x0d7d, 0x0013, 0x006e, 0x0005, 0xacc4, 0xb430, 0xb60d, 0xacc4,
-	0xb6a3, 0xafc6, 0xacc4, 0xacc4, 0xb3b2, 0xbc0d, 0xacc4, 0xacc4,
-	0xacc4, 0xacc4, 0xacc4, 0xacc4, 0x080c, 0x0d7d, 0x0066, 0x6000,
-	0x90b2, 0x0016, 0x1a0c, 0x0d7d, 0x0013, 0x006e, 0x0005, 0xacdf,
-	0xc215, 0xacdf, 0xacdf, 0xacdf, 0xacdf, 0xacdf, 0xacdf, 0xc1b7,
-	0xc398, 0xacdf, 0xc252, 0xc2d6, 0xc252, 0xc2d6, 0xacdf, 0x080c,
+	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,
-	0xacfb, 0xbc57, 0xbcee, 0xbe6e, 0xbedd, 0xacfb, 0xacfb, 0xacfb,
-	0xbc26, 0xc138, 0xc13b, 0xacfb, 0xacfb, 0xacfb, 0xacfb, 0xc16b,
-	0xacfb, 0xacfb, 0xacfb, 0x080c, 0x0d7d, 0x0066, 0x6000, 0x90b2,
-	0x0016, 0x1a0c, 0x0d7d, 0x0013, 0x006e, 0x0005, 0xad16, 0xad16,
-	0xad54, 0xadf3, 0xae73, 0xad16, 0xad16, 0xad16, 0xad18, 0xad16,
-	0xad16, 0xad16, 0xad16, 0xad16, 0xad16, 0xad16, 0x080c, 0x0d7d,
+	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, 0x1bdf, 0x2009, 0x8030, 0x080c, 0x9280, 0x0005, 0x6010,
-	0x00b6, 0x2058, 0xbca0, 0x00be, 0x2c00, 0x080c, 0xae95, 0x080c,
-	0xcf9c, 0x6003, 0x0007, 0x0005, 0x00d6, 0x0096, 0x00f6, 0x2079,
+	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,
@@ -5348,54 +5372,54 @@
 	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, 0xadbb, 0xadbb,
-	0xadb6, 0xadb9, 0xadbb, 0xadb3, 0xada6, 0xada6, 0xada6, 0xada6,
-	0xada6, 0xada6, 0xada6, 0xada6, 0xada6, 0xada6, 0x00fe, 0x00ee,
+	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, 0xb862, 0x0028, 0x080c, 0xb947,
-	0x0010, 0x080c, 0xba3d, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x002e,
-	0x001e, 0x2c00, 0xa896, 0x000e, 0x080c, 0xaf53, 0x0530, 0xa804,
+	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, 0xb114,
+	0xacd4, 0xadd8, 0x2031, 0x0000, 0x2041, 0x12b0, 0x080c, 0xb1d4,
 	0x0160, 0x000e, 0x9005, 0x0120, 0x00fe, 0x009e, 0x00de, 0x0005,
-	0x00fe, 0x009e, 0x00de, 0x0804, 0xabf0, 0x2001, 0x002c, 0x900e,
-	0x080c, 0xafb9, 0x0c70, 0x91b6, 0x0015, 0x0170, 0x91b6, 0x0016,
+	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, 0xaaab, 0x0120, 0x9086,
-	0x0002, 0x0904, 0xad54, 0x0005, 0xae15, 0xae15, 0xae17, 0xae49,
-	0xae15, 0xae15, 0xae15, 0xae15, 0xae5c, 0x080c, 0x0d7d, 0x00d6,
+	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, 0xafb9, 0x080c, 0xabf0, 0x00a8,
+	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, 0x965a, 0x00d6, 0x0096, 0x6114, 0x2148, 0x080c,
-	0xc865, 0x0120, 0xa87b, 0x0006, 0x080c, 0x6d9f, 0x009e, 0x00de,
-	0x080c, 0xabf0, 0x0804, 0x96bd, 0x080c, 0x965a, 0x080c, 0x320f,
-	0x080c, 0xcf99, 0x00d6, 0x0096, 0x6114, 0x2148, 0x080c, 0xc865,
-	0x0120, 0xa87b, 0x0029, 0x080c, 0x6d9f, 0x009e, 0x00de, 0x080c,
-	0xabf0, 0x0804, 0x96bd, 0x9182, 0x0047, 0x0002, 0xae83, 0xae85,
-	0xae83, 0xae83, 0xae83, 0xae83, 0xae83, 0xae83, 0xae83, 0xae83,
-	0xae83, 0xae83, 0xae85, 0x080c, 0x0d7d, 0x00d6, 0x0096, 0x601f,
+	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,
-	0x6d9f, 0x009e, 0x00de, 0x0804, 0xabf0, 0x0026, 0x0036, 0x0056,
+	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, 0xc41b, 0x04c0, 0x2130,
-	0x2009, 0x0034, 0x2011, 0x001f, 0x080c, 0xc41b, 0x96b2, 0x0034,
+	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, 0xc41b, 0x00b8,
+	0x003d, 0x1230, 0x2608, 0x2011, 0x001b, 0x080c, 0xc4f8, 0x00b8,
 	0x96b2, 0x003c, 0x2009, 0x003c, 0x2950, 0x2011, 0x001b, 0x080c,
-	0xc41b, 0x0c18, 0x2001, 0x0205, 0x2003, 0x0000, 0x00ae, 0x852f,
+	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, 0x6d9f, 0x000e,
+	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,
@@ -5403,7 +5427,7 @@
 	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, 0x6d9f, 0x009e,
+	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,
@@ -5415,25 +5439,25 @@
 	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, 0xaf68, 0x0804, 0xaf6a,
+	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, 0x6d93, 0x009e, 0x003e, 0x00de, 0x0005, 0x91b6, 0x0015,
-	0x1118, 0x080c, 0xabf0, 0x0030, 0x91b6, 0x0016, 0x190c, 0x0d7d,
-	0x080c, 0xabf0, 0x0005, 0x20a9, 0x000e, 0x20e1, 0x0000, 0x2e98,
+	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, 0xc865, 0x0130, 0x6014, 0x2048, 0xa807, 0x0000, 0xa867,
-	0x0103, 0x009e, 0x0804, 0xabf0, 0x0096, 0x00d6, 0x0036, 0x7330,
+	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, 0xabf0, 0x003e, 0x00de, 0x009e, 0x0005,
-	0x0011, 0x1d48, 0x0cc8, 0x0006, 0x0016, 0x080c, 0xcf84, 0x0188,
+	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, 0xb408, 0x9006, 0x001e, 0x000e,
+	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,
@@ -5441,22 +5465,22 @@
 	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, 0xabf0, 0x001e, 0x009e, 0x0005,
+	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, 0xc41b, 0x080c, 0xc865, 0x0140, 0x6014, 0x2048,
-	0xa807, 0x0000, 0xa864, 0xa8e2, 0xa867, 0x0103, 0x080c, 0xabf0,
+	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, 0x6d9f, 0x009e, 0x080c, 0xabf0, 0x001e,
+	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, 0xc41b, 0x009e, 0x080c, 0xc865, 0x0148, 0xa804, 0x9005,
+	0x080c, 0xc4f8, 0x009e, 0x080c, 0xc97a, 0x0148, 0xa804, 0x9005,
 	0x1158, 0xa807, 0x0000, 0xa864, 0xa8e2, 0xa867, 0x0103, 0x080c,
-	0xabf0, 0x009e, 0x001e, 0x0005, 0x0086, 0x2040, 0xa030, 0x8007,
-	0x9086, 0x0100, 0x1118, 0x080c, 0xb5c6, 0x00e0, 0xa034, 0x8007,
+	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,
@@ -5467,399 +5491,401 @@
 	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, 0xcefc, 0x001e,
+	0x0000, 0x2c68, 0x0016, 0x2009, 0x0035, 0x080c, 0xd013, 0x001e,
 	0x1158, 0x622c, 0x2268, 0x2071, 0x026c, 0x6b20, 0x9386, 0x0003,
-	0x0130, 0x9386, 0x0006, 0x0128, 0x080c, 0xabf0, 0x0020, 0x0039,
-	0x0010, 0x080c, 0xb23d, 0x002e, 0x00de, 0x00ee, 0x0005, 0x0096,
-	0x6814, 0x2048, 0x9186, 0x0015, 0x0904, 0xb21c, 0x918e, 0x0016,
-	0x1904, 0xb23b, 0x700c, 0x908c, 0xff00, 0x9186, 0x1700, 0x0120,
-	0x9186, 0x0300, 0x1904, 0xb1f6, 0x89ff, 0x1138, 0x6800, 0x9086,
-	0x000f, 0x0904, 0xb1d8, 0x0804, 0xb239, 0x6808, 0x9086, 0xffff,
-	0x1904, 0xb21e, 0xa87c, 0x9084, 0x0060, 0x9086, 0x0020, 0x1128,
-	0xa83c, 0xa940, 0x9105, 0x1904, 0xb21e, 0x6824, 0xd084, 0x1904,
-	0xb21e, 0xd0b4, 0x0158, 0x0016, 0x2001, 0x1985, 0x200c, 0x6018,
-	0x9102, 0x9082, 0x0005, 0x001e, 0x1a04, 0xb21e, 0x080c, 0xca54,
-	0x6864, 0xa882, 0xa87c, 0xc0dc, 0xc0f4, 0xc0d4, 0xa87e, 0x0026,
-	0x900e, 0x6a18, 0x2001, 0x000a, 0x080c, 0x9181, 0xa884, 0x920a,
-	0x0208, 0x8011, 0xaa86, 0x82ff, 0x002e, 0x1138, 0x00c6, 0x2d60,
-	0x080c, 0xc56e, 0x00ce, 0x0804, 0xb239, 0x00c6, 0xa868, 0xd0fc,
-	0x1118, 0x080c, 0x60d6, 0x0010, 0x080c, 0x64de, 0x00ce, 0x1904,
-	0xb21e, 0x00c6, 0x2d60, 0x080c, 0xabf0, 0x00ce, 0x0804, 0xb239,
-	0x00c6, 0x080c, 0xac60, 0x0198, 0x6017, 0x0000, 0x6810, 0x6012,
-	0x080c, 0xccfe, 0x6023, 0x0003, 0x6904, 0x00c6, 0x2d60, 0x080c,
-	0xabf0, 0x00ce, 0x080c, 0xac8d, 0x00ce, 0x0804, 0xb239, 0x2001,
-	0x1987, 0x2004, 0x684a, 0x00ce, 0x0804, 0xb239, 0x7008, 0x9086,
-	0x000b, 0x11c8, 0x6010, 0x00b6, 0x2058, 0xb900, 0xc1bc, 0xb902,
-	0x00be, 0x00c6, 0x2d60, 0xa87b, 0x0003, 0x080c, 0xcf3e, 0x6007,
-	0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x2009, 0x8020, 0x080c,
-	0x9239, 0x00ce, 0x0430, 0x700c, 0x9086, 0x2a00, 0x1138, 0x2001,
-	0x1987, 0x2004, 0x684a, 0x00e8, 0x04c1, 0x00e8, 0x89ff, 0x090c,
-	0x0d7d, 0x00c6, 0x00d6, 0x2d60, 0xa867, 0x0103, 0xa87b, 0x0003,
-	0x080c, 0x6bb5, 0x080c, 0xca54, 0x080c, 0xac2b, 0x0026, 0x6010,
-	0x00b6, 0x2058, 0xba3c, 0x080c, 0x676f, 0x00be, 0x002e, 0x00de,
-	0x00ce, 0x080c, 0xabf0, 0x009e, 0x0005, 0x9186, 0x0015, 0x1128,
-	0x2001, 0x1987, 0x2004, 0x684a, 0x0068, 0x918e, 0x0016, 0x1160,
-	0x00c6, 0x2d00, 0x2060, 0x080c, 0xe571, 0x080c, 0x88d7, 0x080c,
-	0xabf0, 0x00ce, 0x080c, 0xabf0, 0x0005, 0x0026, 0x0036, 0x0046,
-	0x7228, 0xacb0, 0xabac, 0xd2f4, 0x0130, 0x2001, 0x1987, 0x2004,
-	0x684a, 0x0804, 0xb2b7, 0x00c6, 0x2d60, 0x080c, 0xc446, 0x00ce,
-	0x6804, 0x9086, 0x0050, 0x1168, 0x00c6, 0x2d00, 0x2060, 0x6003,
-	0x0001, 0x6007, 0x0050, 0x2009, 0x8023, 0x080c, 0x9239, 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, 0xcbe8, 0x080c, 0x96bd, 0x0010, 0x080c,
-	0xabf0, 0x004e, 0x003e, 0x002e, 0x0005, 0x00e6, 0x00d6, 0x0026,
-	0x7008, 0x9084, 0x00ff, 0x6210, 0x00b6, 0x2258, 0xba10, 0x00be,
-	0x9206, 0x1904, 0xb322, 0x700c, 0x6210, 0x00b6, 0x2258, 0xba14,
-	0x00be, 0x9206, 0x1904, 0xb322, 0x6038, 0x2068, 0x6824, 0xc0dc,
-	0x6826, 0x6a20, 0x9286, 0x0007, 0x0904, 0xb322, 0x9286, 0x0002,
-	0x0904, 0xb322, 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,
-	0xc865, 0x090c, 0x0d7d, 0xa87b, 0x0003, 0x009e, 0x080c, 0xcf3e,
-	0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x2009, 0x8020,
-	0x080c, 0x9239, 0x00ce, 0x0030, 0x6038, 0x2070, 0x2001, 0x1987,
-	0x2004, 0x704a, 0x080c, 0xabf0, 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, 0xbbd5, 0x002e, 0x003e, 0x015e,
-	0x009e, 0x1904, 0xb391, 0x0096, 0x0156, 0x0036, 0x0026, 0x2b48,
-	0x9e90, 0x0014, 0x2019, 0x0006, 0x20a9, 0x0004, 0x080c, 0xbbd5,
-	0x002e, 0x003e, 0x015e, 0x009e, 0x15a0, 0x7238, 0xba0a, 0x733c,
-	0xbb0e, 0xbc00, 0xc48d, 0xbc02, 0xa804, 0x9005, 0x1128, 0x00fe,
-	0x009e, 0x00be, 0x0804, 0xafff, 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, 0xb114, 0x0130,
-	0x00fe, 0x009e, 0x080c, 0xabf0, 0x00be, 0x0005, 0x080c, 0xb5c6,
-	0x0cb8, 0x2b78, 0x00f6, 0x080c, 0x320f, 0x080c, 0xcf99, 0x00fe,
-	0x00c6, 0x080c, 0xab9a, 0x2f00, 0x6012, 0x6017, 0x0000, 0x6023,
-	0x0001, 0x6007, 0x0001, 0x6003, 0x0001, 0x2001, 0x0007, 0x080c,
-	0x6594, 0x080c, 0x65c0, 0x080c, 0x9240, 0x080c, 0x96bd, 0x00ce,
-	0x0804, 0xb364, 0x2100, 0x91b2, 0x0053, 0x1a0c, 0x0d7d, 0x91b2,
-	0x0040, 0x1a04, 0xb41a, 0x0002, 0xb408, 0xb408, 0xb3fe, 0xb408,
-	0xb408, 0xb408, 0xb3fc, 0xb3fc, 0xb3fc, 0xb3fc, 0xb3fc, 0xb3fc,
-	0xb3fc, 0xb3fc, 0xb3fc, 0xb3fc, 0xb3fc, 0xb3fc, 0xb3fc, 0xb3fc,
-	0xb3fc, 0xb3fc, 0xb3fc, 0xb3fc, 0xb3fc, 0xb3fc, 0xb3fc, 0xb3fc,
-	0xb3fc, 0xb3fc, 0xb3fc, 0xb408, 0xb3fc, 0xb408, 0xb408, 0xb3fc,
-	0xb3fc, 0xb3fc, 0xb3fc, 0xb3fc, 0xb3fe, 0xb3fc, 0xb3fc, 0xb3fc,
-	0xb3fc, 0xb3fc, 0xb3fc, 0xb3fc, 0xb3fc, 0xb3fc, 0xb408, 0xb408,
-	0xb3fc, 0xb3fc, 0xb3fc, 0xb3fc, 0xb3fc, 0xb3fc, 0xb3fc, 0xb3fc,
-	0xb3fc, 0xb408, 0xb3fc, 0xb3fc, 0x080c, 0x0d7d, 0x0066, 0x00b6,
-	0x6610, 0x2658, 0xb8d4, 0xc08c, 0xb8d6, 0x00be, 0x006e, 0x0000,
-	0x6003, 0x0001, 0x6106, 0x9186, 0x0032, 0x0118, 0x080c, 0x9240,
-	0x0010, 0x080c, 0x9239, 0x0126, 0x2091, 0x8000, 0x080c, 0x96bd,
-	0x012e, 0x0005, 0x2600, 0x0002, 0xb408, 0xb408, 0xb42e, 0xb408,
-	0xb408, 0xb42e, 0xb42e, 0xb42e, 0xb42e, 0xb408, 0xb42e, 0xb408,
-	0xb42e, 0xb408, 0xb42e, 0xb42e, 0xb42e, 0xb42e, 0x080c, 0x0d7d,
-	0x6004, 0x90b2, 0x0053, 0x1a0c, 0x0d7d, 0x91b6, 0x0013, 0x0904,
-	0xb505, 0x91b6, 0x0027, 0x1904, 0xb4b1, 0x080c, 0x95ff, 0x6004,
-	0x080c, 0xca69, 0x01b0, 0x080c, 0xca7a, 0x01a8, 0x908e, 0x0021,
-	0x0904, 0xb4ae, 0x908e, 0x0022, 0x1130, 0x080c, 0xb02b, 0x0904,
-	0xb4aa, 0x0804, 0xb4ab, 0x908e, 0x003d, 0x0904, 0xb4ae, 0x0804,
-	0xb4a4, 0x080c, 0x323e, 0x2001, 0x0007, 0x080c, 0x6594, 0x6010,
-	0x00b6, 0x2058, 0xb9a0, 0x00be, 0x080c, 0xb5c6, 0x9186, 0x007e,
-	0x1148, 0x2001, 0x1837, 0x2014, 0xc285, 0x080c, 0x74ec, 0x1108,
-	0xc2ad, 0x2202, 0x080c, 0xa899, 0x0036, 0x0026, 0x2019, 0x0028,
-	0x2110, 0x080c, 0xe67d, 0x002e, 0x003e, 0x0016, 0x0026, 0x0036,
-	0x2110, 0x2019, 0x0028, 0x080c, 0x93c6, 0x0076, 0x903e, 0x080c,
-	0x928f, 0x6010, 0x00b6, 0x905d, 0x0100, 0x00be, 0x2c08, 0x080c,
-	0xe038, 0x007e, 0x003e, 0x002e, 0x001e, 0x080c, 0xa8b5, 0x080c,
-	0xcf99, 0x0016, 0x080c, 0xccf6, 0x080c, 0xabf0, 0x001e, 0x080c,
-	0x3318, 0x080c, 0x96bd, 0x0030, 0x080c, 0xccf6, 0x080c, 0xabf0,
-	0x080c, 0x96bd, 0x0005, 0x080c, 0xb5c6, 0x0cb0, 0x080c, 0xb602,
-	0x0c98, 0x9186, 0x0015, 0x0118, 0x9186, 0x0016, 0x1140, 0x080c,
-	0xaaab, 0x0d80, 0x9086, 0x0002, 0x0904, 0xb60d, 0x0c58, 0x9186,
-	0x0014, 0x1d40, 0x080c, 0x95ff, 0x6004, 0x908e, 0x0022, 0x1118,
-	0x080c, 0xb02b, 0x09f8, 0x080c, 0x320f, 0x080c, 0xcf99, 0x080c,
-	0xca69, 0x1190, 0x080c, 0x323e, 0x6010, 0x00b6, 0x2058, 0xb9a0,
-	0x00be, 0x080c, 0xb5c6, 0x9186, 0x007e, 0x1128, 0x2001, 0x1837,
-	0x200c, 0xc185, 0x2102, 0x0800, 0x080c, 0xca7a, 0x1120, 0x080c,
-	0xb5c6, 0x0804, 0xb4a4, 0x6004, 0x908e, 0x0032, 0x1160, 0x00e6,
-	0x00f6, 0x2071, 0x189e, 0x2079, 0x0000, 0x080c, 0x35b9, 0x00fe,
-	0x00ee, 0x0804, 0xb4a4, 0x6004, 0x908e, 0x0021, 0x0d40, 0x908e,
-	0x0022, 0x090c, 0xb5c6, 0x0804, 0xb4a4, 0x90b2, 0x0040, 0x1a04,
-	0xb5a6, 0x2008, 0x0002, 0xb54d, 0xb54e, 0xb551, 0xb554, 0xb557,
-	0xb55a, 0xb54b, 0xb54b, 0xb54b, 0xb54b, 0xb54b, 0xb54b, 0xb54b,
-	0xb54b, 0xb54b, 0xb54b, 0xb54b, 0xb54b, 0xb54b, 0xb54b, 0xb54b,
-	0xb54b, 0xb54b, 0xb54b, 0xb54b, 0xb54b, 0xb54b, 0xb54b, 0xb54b,
-	0xb54b, 0xb55d, 0xb568, 0xb54b, 0xb569, 0xb568, 0xb54b, 0xb54b,
-	0xb54b, 0xb54b, 0xb54b, 0xb568, 0xb568, 0xb54b, 0xb54b, 0xb54b,
-	0xb54b, 0xb54b, 0xb54b, 0xb54b, 0xb54b, 0xb591, 0xb568, 0xb54b,
-	0xb564, 0xb54b, 0xb54b, 0xb54b, 0xb565, 0xb54b, 0xb54b, 0xb54b,
-	0xb568, 0xb58c, 0xb54b, 0x080c, 0x0d7d, 0x00d0, 0x2001, 0x000b,
-	0x00f8, 0x2001, 0x0003, 0x00e0, 0x2001, 0x0005, 0x00c8, 0x2001,
-	0x0001, 0x00b0, 0x2001, 0x0009, 0x0098, 0x6003, 0x0005, 0x080c,
-	0xcf9c, 0x080c, 0x96bd, 0x0058, 0x0018, 0x0010, 0x080c, 0x6594,
-	0x04b8, 0x080c, 0xcf9c, 0x6003, 0x0004, 0x080c, 0x96bd, 0x0005,
-	0x080c, 0x6594, 0x6003, 0x0002, 0x0036, 0x2019, 0x1852, 0x2304,
-	0x9084, 0xff00, 0x1120, 0x2001, 0x1985, 0x201c, 0x0040, 0x8007,
-	0x909a, 0x0004, 0x0ec0, 0x8003, 0x801b, 0x831b, 0x9318, 0x631a,
-	0x003e, 0x080c, 0x96bd, 0x0c18, 0x080c, 0xccf6, 0x080c, 0xabf0,
-	0x08f0, 0x00e6, 0x00f6, 0x2071, 0x189e, 0x2079, 0x0000, 0x080c,
-	0x35b9, 0x00fe, 0x00ee, 0x080c, 0x95ff, 0x080c, 0xabf0, 0x0878,
-	0x6003, 0x0002, 0x080c, 0xcf9c, 0x0804, 0x96bd, 0x2600, 0x2008,
-	0x0002, 0xb5bd, 0xb5a0, 0xb5bb, 0xb5a0, 0xb5a0, 0xb5bb, 0xb5bb,
-	0xb5bb, 0xb5bb, 0xb5a0, 0xb5bb, 0xb5a0, 0xb5bb, 0xb5a0, 0xb5bb,
-	0xb5bb, 0xb5bb, 0xb5bb, 0x080c, 0x0d7d, 0x0096, 0x6014, 0x2048,
-	0x080c, 0x6d9f, 0x009e, 0x080c, 0xabf0, 0x0005, 0x00e6, 0x0096,
-	0x0026, 0x0016, 0x080c, 0xc865, 0x0568, 0x6014, 0x2048, 0xa864,
-	0x9086, 0x0139, 0x11a8, 0xa894, 0x9086, 0x0056, 0x1148, 0x080c,
-	0x5496, 0x0130, 0x2001, 0x0000, 0x900e, 0x2011, 0x4000, 0x0028,
-	0x2001, 0x0030, 0x900e, 0x2011, 0x4005, 0x080c, 0xce63, 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, 0xcd82, 0x0804, 0xb692, 0x6604,
-	0x96b6, 0x0043, 0x1120, 0x080c, 0xcdcb, 0x0804, 0xb692, 0x6604,
-	0x96b6, 0x004b, 0x1120, 0x080c, 0xcdf7, 0x0804, 0xb692, 0x6604,
-	0x96b6, 0x0033, 0x1120, 0x080c, 0xcd18, 0x0804, 0xb692, 0x6604,
-	0x96b6, 0x0028, 0x1120, 0x080c, 0xcab8, 0x0804, 0xb692, 0x6604,
-	0x96b6, 0x0029, 0x1120, 0x080c, 0xcaf9, 0x0804, 0xb692, 0x6604,
-	0x96b6, 0x001f, 0x1120, 0x080c, 0xafd3, 0x0804, 0xb692, 0x6604,
-	0x96b6, 0x0000, 0x1118, 0x080c, 0xb328, 0x04e0, 0x6604, 0x96b6,
-	0x0022, 0x1118, 0x080c, 0xb00c, 0x04a8, 0x6604, 0x96b6, 0x0035,
-	0x1118, 0x080c, 0xb132, 0x0470, 0x6604, 0x96b6, 0x0039, 0x1118,
-	0x080c, 0xb2bd, 0x0438, 0x6604, 0x96b6, 0x003d, 0x1118, 0x080c,
-	0xb044, 0x0400, 0x6604, 0x96b6, 0x0044, 0x1118, 0x080c, 0xb080,
-	0x00c8, 0x6604, 0x96b6, 0x0049, 0x1118, 0x080c, 0xb0c1, 0x0090,
-	0x6604, 0x96b6, 0x0041, 0x1118, 0x080c, 0xb0ab, 0x0058, 0x91b6,
-	0x0015, 0x1110, 0x0063, 0x0030, 0x91b6, 0x0016, 0x1128, 0x00be,
-	0x0804, 0xb8ee, 0x00be, 0x0005, 0x080c, 0xacaa, 0x0cd8, 0xb6af,
-	0xb6b2, 0xb6af, 0xb6f9, 0xb6af, 0xb862, 0xb8fb, 0xb6af, 0xb6af,
-	0xb8c4, 0xb6af, 0xb8da, 0x0096, 0x601f, 0x0000, 0x6014, 0x2048,
-	0xa800, 0x2048, 0xa867, 0x0103, 0x009e, 0x0804, 0xabf0, 0xa001,
-	0xa001, 0x0005, 0x00e6, 0x2071, 0x1800, 0x7090, 0x9086, 0x0074,
-	0x1540, 0x080c, 0xe009, 0x11b0, 0x6010, 0x00b6, 0x2058, 0x7030,
-	0xd08c, 0x0128, 0xb800, 0xd0bc, 0x0110, 0xc0c5, 0xb802, 0x00f9,
-	0x00be, 0x2001, 0x0006, 0x080c, 0x6594, 0x080c, 0x323e, 0x080c,
-	0xabf0, 0x0098, 0x2001, 0x000a, 0x080c, 0x6594, 0x080c, 0x323e,
-	0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x9240, 0x080c, 0x96bd,
-	0x0020, 0x2001, 0x0001, 0x080c, 0xb832, 0x00ee, 0x0005, 0x00d6,
-	0xb800, 0xd084, 0x0160, 0x9006, 0x080c, 0x6580, 0x2069, 0x1847,
-	0x6804, 0xd0a4, 0x0120, 0x2001, 0x0006, 0x080c, 0x65c0, 0x00de,
-	0x0005, 0x00b6, 0x0096, 0x00d6, 0x2011, 0x1824, 0x2204, 0x9086,
-	0x0074, 0x1904, 0xb807, 0x6010, 0x2058, 0xbaa0, 0x9286, 0x007e,
-	0x1120, 0x080c, 0xba48, 0x0804, 0xb76b, 0x080c, 0xba3d, 0x6010,
-	0x2058, 0xbaa0, 0x9286, 0x0080, 0x1510, 0x6014, 0x9005, 0x01a8,
-	0x2048, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x1140, 0x2001,
-	0x0000, 0x900e, 0x2011, 0x4000, 0x080c, 0xce63, 0x0030, 0xa807,
-	0x0000, 0xa867, 0x0103, 0xa833, 0x0200, 0x2001, 0x0006, 0x080c,
-	0x6594, 0x080c, 0x323e, 0x080c, 0xabf0, 0x0804, 0xb80c, 0x080c,
-	0xb81a, 0x6014, 0x9005, 0x0190, 0x2048, 0xa868, 0xd0f4, 0x01e8,
-	0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x1d08, 0x2001, 0x0000,
-	0x900e, 0x2011, 0x4000, 0x080c, 0xce63, 0x08f8, 0x080c, 0xb810,
-	0x0160, 0x9006, 0x080c, 0x6580, 0x2001, 0x0004, 0x080c, 0x65c0,
-	0x2001, 0x0007, 0x080c, 0x6594, 0x08a0, 0x2001, 0x0004, 0x080c,
-	0x6594, 0x6003, 0x0001, 0x6007, 0x0003, 0x080c, 0x9240, 0x080c,
-	0x96bd, 0x0804, 0xb80c, 0xb85c, 0xd0e4, 0x01d8, 0x080c, 0xcc90,
-	0x080c, 0x74ec, 0x0118, 0xd0dc, 0x1904, 0xb72d, 0x2011, 0x1837,
-	0x2204, 0xc0ad, 0x2012, 0x2001, 0x196c, 0x2004, 0x00f6, 0x2079,
-	0x0100, 0x78e3, 0x0000, 0x080c, 0x26a4, 0x78e2, 0x00fe, 0x0804,
-	0xb72d, 0x080c, 0xccd1, 0x2011, 0x1837, 0x2204, 0xc0a5, 0x2012,
-	0x0006, 0x080c, 0xe199, 0x000e, 0x1904, 0xb72d, 0xc0b5, 0x2012,
-	0x2001, 0x0006, 0x080c, 0x6594, 0x9006, 0x080c, 0x6580, 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, 0x2679, 0x00f6, 0x2100, 0x900e, 0x080c,
-	0x2630, 0x795e, 0x00fe, 0x9186, 0x0081, 0x01d8, 0x2009, 0x0081,
-	0x00c8, 0x2009, 0x00ef, 0x00f6, 0x2079, 0x0100, 0x79ea, 0x7932,
-	0x7936, 0x780c, 0xc0b5, 0x780e, 0x00fe, 0x080c, 0x2679, 0x00f6,
-	0x2079, 0x1800, 0x7982, 0x2100, 0x900e, 0x080c, 0x2630, 0x795e,
-	0x00fe, 0x8108, 0x080c, 0x65e3, 0x2b00, 0x00ce, 0x1904, 0xb72d,
-	0x6012, 0x2009, 0x180f, 0x210c, 0xd19c, 0x0150, 0x2009, 0x027c,
-	0x210c, 0x918c, 0x00ff, 0xb912, 0x2009, 0x027d, 0x210c, 0xb916,
-	0x2001, 0x0002, 0x080c, 0x6594, 0x6023, 0x0001, 0x6003, 0x0001,
-	0x6007, 0x0002, 0x080c, 0x9240, 0x080c, 0x96bd, 0x0028, 0x080c,
-	0xb5c6, 0x2001, 0x0001, 0x0431, 0x00de, 0x009e, 0x00be, 0x0005,
-	0x2001, 0x1810, 0x2004, 0xd0a4, 0x0120, 0x2001, 0x1848, 0x2004,
-	0xd0ac, 0x0005, 0x00e6, 0x080c, 0xe6d6, 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,
-	0x6594, 0x080c, 0x5709, 0x1120, 0x2001, 0x0007, 0x080c, 0x65c0,
-	0x2600, 0x9005, 0x11b0, 0x6014, 0x0096, 0x2048, 0xa868, 0x009e,
-	0xd0fc, 0x1178, 0x0036, 0x0046, 0x6010, 0x00b6, 0x2058, 0xbba0,
-	0x00be, 0x2021, 0x0004, 0x2011, 0x8014, 0x080c, 0x4b29, 0x004e,
-	0x003e, 0x080c, 0x323e, 0x6020, 0x9086, 0x000a, 0x1108, 0x0005,
-	0x0804, 0xabf0, 0x00b6, 0x00e6, 0x0026, 0x0016, 0x2071, 0x1800,
-	0x7090, 0x9086, 0x0014, 0x1904, 0xb8ba, 0x080c, 0x5709, 0x1170,
-	0x6014, 0x9005, 0x1158, 0x0036, 0x0046, 0x6010, 0x2058, 0xbba0,
-	0x2021, 0x0006, 0x080c, 0x4ce0, 0x004e, 0x003e, 0x00d6, 0x6010,
-	0x2058, 0x080c, 0x66df, 0x080c, 0xb6e7, 0x00de, 0x080c, 0xbb0e,
-	0x1588, 0x6010, 0x2058, 0xb890, 0x9005, 0x0560, 0x2001, 0x0006,
-	0x080c, 0x6594, 0x0096, 0x6014, 0x904d, 0x01d0, 0xa864, 0x9084,
+	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, 0xce63, 0x0060, 0xa864, 0x9084, 0x00ff, 0x9086,
-	0x0029, 0x0130, 0xa807, 0x0000, 0xa867, 0x0103, 0xa833, 0x0200,
-	0x009e, 0x080c, 0x323e, 0x6020, 0x9086, 0x000a, 0x0140, 0x080c,
-	0xabf0, 0x0028, 0x080c, 0xb5c6, 0x9006, 0x080c, 0xb832, 0x001e,
-	0x002e, 0x00ee, 0x00be, 0x0005, 0x2011, 0x1824, 0x2204, 0x9086,
-	0x0014, 0x1160, 0x2001, 0x0002, 0x080c, 0x6594, 0x6003, 0x0001,
-	0x6007, 0x0001, 0x080c, 0x9240, 0x0804, 0x96bd, 0x2001, 0x0001,
-	0x0804, 0xb832, 0x2030, 0x2011, 0x1824, 0x2204, 0x9086, 0x0004,
-	0x1148, 0x96b6, 0x000b, 0x1120, 0x2001, 0x0007, 0x080c, 0x6594,
-	0x0804, 0xabf0, 0x2001, 0x0001, 0x0804, 0xb832, 0x0002, 0xb6af,
-	0xb906, 0xb6af, 0xb947, 0xb6af, 0xb9f4, 0xb8fb, 0xb6af, 0xb6af,
-	0xba08, 0xb6af, 0xba1a, 0x6604, 0x9686, 0x0003, 0x0904, 0xb862,
-	0x96b6, 0x001e, 0x1110, 0x080c, 0xabf0, 0x0005, 0x00b6, 0x00d6,
-	0x00c6, 0x080c, 0xba2c, 0x11a0, 0x9006, 0x080c, 0x6580, 0x080c,
-	0x320f, 0x080c, 0xcf99, 0x2001, 0x0002, 0x080c, 0x6594, 0x6003,
-	0x0001, 0x6007, 0x0002, 0x080c, 0x9240, 0x080c, 0x96bd, 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, 0x320f, 0x080c, 0xcf99, 0x2001,
-	0x0001, 0x080c, 0xb832, 0x00ce, 0x00de, 0x00be, 0x0005, 0x0096,
-	0x00b6, 0x0026, 0x9016, 0x080c, 0xba3a, 0x00d6, 0x2069, 0x197b,
-	0x2d04, 0x9005, 0x0168, 0x6010, 0x2058, 0xb8a0, 0x9086, 0x007e,
-	0x1138, 0x2069, 0x1820, 0x2d04, 0x8000, 0x206a, 0x00de, 0x0010,
-	0x00de, 0x0088, 0x9006, 0x080c, 0x6580, 0x2001, 0x0002, 0x080c,
-	0x6594, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x9240, 0x080c,
-	0x96bd, 0x0804, 0xb9c4, 0x080c, 0xc865, 0x01b0, 0x6014, 0x2048,
-	0xa864, 0x2010, 0x9086, 0x0139, 0x1138, 0x6007, 0x0016, 0x2001,
-	0x0002, 0x080c, 0xcebd, 0x00b0, 0x6014, 0x2048, 0xa864, 0xd0fc,
-	0x0118, 0x2001, 0x0001, 0x0ca8, 0x2001, 0x180e, 0x2004, 0xd0dc,
-	0x0148, 0x6010, 0x2058, 0xb840, 0x9084, 0x00ff, 0x9005, 0x1110,
-	0x9006, 0x0c38, 0x080c, 0xb5c6, 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, 0x6594, 0x2001, 0x0028, 0x601a, 0x6007, 0x0052, 0x0020,
-	0x2001, 0x0001, 0x080c, 0xb832, 0x002e, 0x00be, 0x009e, 0x0005,
-	0x9286, 0x0139, 0x0160, 0x6014, 0x2048, 0x080c, 0xc865, 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, 0x5fd7, 0x00ee,
-	0x0010, 0x080c, 0x320f, 0x0860, 0x080c, 0xba3a, 0x1160, 0x2001,
-	0x0004, 0x080c, 0x6594, 0x6003, 0x0001, 0x6007, 0x0003, 0x080c,
-	0x9240, 0x0804, 0x96bd, 0x080c, 0xb5c6, 0x9006, 0x0804, 0xb832,
-	0x0489, 0x1160, 0x2001, 0x0008, 0x080c, 0x6594, 0x6003, 0x0001,
-	0x6007, 0x0005, 0x080c, 0x9240, 0x0804, 0x96bd, 0x2001, 0x0001,
-	0x0804, 0xb832, 0x00f9, 0x1160, 0x2001, 0x000a, 0x080c, 0x6594,
-	0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x9240, 0x0804, 0x96bd,
-	0x2001, 0x0001, 0x0804, 0xb832, 0x2009, 0x026e, 0x2104, 0x9086,
-	0x0003, 0x1138, 0x2009, 0x026f, 0x2104, 0x9084, 0xff00, 0x9086,
-	0x2a00, 0x0005, 0x9085, 0x0001, 0x0005, 0x00b6, 0x00c6, 0x0016,
-	0x6110, 0x2158, 0x080c, 0x6653, 0x001e, 0x00ce, 0x00be, 0x0005,
-	0x00b6, 0x00f6, 0x00e6, 0x00d6, 0x0036, 0x0016, 0x6010, 0x2058,
-	0x2009, 0x1837, 0x2104, 0x9085, 0x0003, 0x200a, 0x080c, 0xbae0,
-	0x0560, 0x2009, 0x1837, 0x2104, 0xc0cd, 0x200a, 0x080c, 0x6a8a,
-	0x0158, 0x9006, 0x2020, 0x2009, 0x002a, 0x080c, 0xe316, 0x2001,
-	0x180c, 0x200c, 0xc195, 0x2102, 0x2019, 0x002a, 0x2009, 0x0001,
-	0x080c, 0x31d4, 0x00e6, 0x2071, 0x1800, 0x080c, 0x2fe0, 0x00ee,
-	0x00c6, 0x0156, 0x20a9, 0x0781, 0x2009, 0x007f, 0x080c, 0x3318,
-	0x8108, 0x1f04, 0xba7e, 0x015e, 0x00ce, 0x080c, 0xba3d, 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, 0x2679, 0x080c,
-	0x74ec, 0x0170, 0x2071, 0x0260, 0x2069, 0x1981, 0x7048, 0x206a,
-	0x704c, 0x6806, 0x7050, 0x680a, 0x7054, 0x680e, 0x080c, 0xcc90,
-	0x0040, 0x2001, 0x0006, 0x080c, 0x6594, 0x080c, 0x323e, 0x080c,
-	0xabf0, 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, 0xbbd5, 0x1148, 0x2011,
-	0x027a, 0x20a9, 0x0004, 0x2019, 0x0006, 0x080c, 0xbbd5, 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, 0xbba1, 0x080c, 0x8ba9,
-	0x0904, 0xbb9a, 0x080c, 0xe347, 0x0904, 0xbb9a, 0x6720, 0x9786,
-	0x0007, 0x0904, 0xbb9a, 0x2500, 0x9c06, 0x0904, 0xbb9a, 0x2400,
-	0x9c06, 0x0904, 0xbb9a, 0x3e08, 0x9186, 0x0002, 0x1148, 0x6010,
-	0x9005, 0x0130, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x1590,
-	0x00c6, 0x6043, 0xffff, 0x6000, 0x9086, 0x0004, 0x1110, 0x080c,
-	0x1a94, 0x9786, 0x000a, 0x0148, 0x080c, 0xca7a, 0x1130, 0x00ce,
-	0x080c, 0xb5c6, 0x080c, 0xac2b, 0x00e8, 0x6014, 0x2048, 0x080c,
-	0xc865, 0x01a8, 0x9786, 0x0003, 0x1530, 0xa867, 0x0103, 0xa87c,
-	0xd0cc, 0x0130, 0x0096, 0xa878, 0x2048, 0x080c, 0x0ff9, 0x009e,
-	0xab7a, 0xa877, 0x0000, 0x080c, 0x6d93, 0x080c, 0xca54, 0x080c,
-	0xac2b, 0x00ce, 0x9ce0, 0x001c, 0x7068, 0x9c02, 0x1210, 0x0804,
-	0xbb41, 0x012e, 0x000e, 0x002e, 0x004e, 0x005e, 0x007e, 0x00ce,
-	0x009e, 0x00ee, 0x0005, 0x9786, 0x0006, 0x1118, 0x080c, 0xe2b9,
-	0x0c30, 0x9786, 0x0009, 0x1148, 0x6000, 0x9086, 0x0004, 0x0d08,
-	0x2009, 0x004c, 0x080c, 0xac8d, 0x08e0, 0x9786, 0x000a, 0x0938,
-	0x0820, 0x220c, 0x2304, 0x9106, 0x1130, 0x8210, 0x8318, 0x1f04,
-	0xbbc1, 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, 0xbbff,
-	0x9006, 0x0005, 0x918d, 0x0001, 0x0005, 0x6004, 0x908a, 0x0053,
-	0x1a0c, 0x0d7d, 0x080c, 0xca69, 0x0120, 0x080c, 0xca7a, 0x0158,
-	0x0028, 0x080c, 0x323e, 0x080c, 0xca7a, 0x0128, 0x080c, 0x95ff,
-	0x080c, 0xabf0, 0x0005, 0x080c, 0xb5c6, 0x0cc0, 0x9182, 0x0057,
-	0x1220, 0x9182, 0x0040, 0x0208, 0x000a, 0x0005, 0xbc45, 0xbc45,
-	0xbc45, 0xbc45, 0xbc45, 0xbc45, 0xbc45, 0xbc45, 0xbc45, 0xbc45,
-	0xbc45, 0xbc47, 0xbc47, 0xbc47, 0xbc47, 0xbc45, 0xbc45, 0xbc45,
-	0xbc47, 0xbc45, 0xbc45, 0xbc45, 0xbc45, 0x080c, 0x0d7d, 0x600b,
-	0xffff, 0x6003, 0x000f, 0x6106, 0x0126, 0x2091, 0x8000, 0x080c,
-	0xcf9c, 0x2009, 0x8000, 0x080c, 0x9239, 0x012e, 0x0005, 0x9186,
-	0x0013, 0x1128, 0x6004, 0x9082, 0x0040, 0x0804, 0xbccc, 0x9186,
-	0x0027, 0x1520, 0x080c, 0x95ff, 0x080c, 0x320f, 0x080c, 0xcf99,
-	0x0096, 0x6114, 0x2148, 0x080c, 0xc865, 0x0198, 0x080c, 0xca7a,
-	0x1118, 0x080c, 0xb5c6, 0x0068, 0xa867, 0x0103, 0xa87b, 0x0029,
-	0xa877, 0x0000, 0xa97c, 0xc1c5, 0xa97e, 0x080c, 0x6d9f, 0x080c,
-	0xca54, 0x009e, 0x080c, 0xabf0, 0x0804, 0x96bd, 0x9186, 0x0014,
-	0x1120, 0x6004, 0x9082, 0x0040, 0x0018, 0x080c, 0x0d7d, 0x0005,
-	0x0002, 0xbcaa, 0xbca8, 0xbca8, 0xbca8, 0xbca8, 0xbca8, 0xbca8,
-	0xbca8, 0xbca8, 0xbca8, 0xbca8, 0xbcc3, 0xbcc3, 0xbcc3, 0xbcc3,
-	0xbca8, 0xbcc3, 0xbca8, 0xbcc3, 0xbca8, 0xbca8, 0xbca8, 0xbca8,
-	0x080c, 0x0d7d, 0x080c, 0x95ff, 0x0096, 0x6114, 0x2148, 0x080c,
-	0xc865, 0x0168, 0xa867, 0x0103, 0xa87b, 0x0006, 0xa877, 0x0000,
-	0xa880, 0xc0ec, 0xa882, 0x080c, 0x6d9f, 0x080c, 0xca54, 0x009e,
-	0x080c, 0xabf0, 0x0005, 0x080c, 0x95ff, 0x080c, 0xca7a, 0x090c,
-	0xb5c6, 0x080c, 0xabf0, 0x0005, 0x0002, 0xbce6, 0xbce4, 0xbce4,
-	0xbce4, 0xbce4, 0xbce4, 0xbce4, 0xbce4, 0xbce4, 0xbce4, 0xbce4,
-	0xbce8, 0xbce8, 0xbce8, 0xbce8, 0xbce4, 0xbcea, 0xbce4, 0xbce8,
-	0xbce4, 0xbce4, 0xbce4, 0xbce4, 0x080c, 0x0d7d, 0x080c, 0x0d7d,
-	0x080c, 0x0d7d, 0x080c, 0xabf0, 0x0804, 0x96bd, 0x9182, 0x0057,
-	0x1220, 0x9182, 0x0040, 0x0208, 0x000a, 0x0005, 0xbd0d, 0xbd0d,
-	0xbd0d, 0xbd0d, 0xbd0d, 0xbd46, 0xbe35, 0xbd0d, 0xbe41, 0xbd0d,
-	0xbd0d, 0xbd0d, 0xbd0d, 0xbd0d, 0xbd0d, 0xbd0d, 0xbd0d, 0xbd0d,
-	0xbd0d, 0xbe41, 0xbd0f, 0xbd0d, 0xbe3f, 0x080c, 0x0d7d, 0x00b6,
+	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, 0xbec6, 0x080c, 0x6bb5,
+	0x0128, 0xa834, 0xa938, 0x9115, 0x190c, 0xbf96, 0x080c, 0x6c04,
 	0x6210, 0x2258, 0xba3c, 0x82ff, 0x0110, 0x8211, 0xba3e, 0xb8d0,
-	0x9005, 0x0110, 0x080c, 0x676f, 0x080c, 0xabf0, 0x009e, 0x00be,
+	0x9005, 0x0110, 0x080c, 0x67be, 0x080c, 0xacb0, 0x009e, 0x00be,
 	0x0005, 0xa87c, 0xd0ac, 0x09e0, 0xa838, 0xa934, 0x9105, 0x09c0,
-	0xa880, 0xd0bc, 0x19a8, 0x080c, 0xcbaf, 0x0c80, 0x00b6, 0x0096,
+	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, 0xbe24, 0xa87b, 0x0000, 0xa867, 0x0103, 0xae76, 0xa87c,
-	0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115, 0x190c, 0xbec6, 0x080c,
-	0x6bb5, 0x6210, 0x2258, 0xba3c, 0x82ff, 0x0110, 0x8211, 0xba3e,
-	0xb8d0, 0x9005, 0x0110, 0x080c, 0x676f, 0x601c, 0xd0fc, 0x1148,
-	0x7044, 0xd0e4, 0x1904, 0xbe08, 0x080c, 0xabf0, 0x009e, 0x00be,
+	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, 0xbe0c, 0x7348,
+	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,
@@ -5867,53 +5893,53 @@
 	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, 0xbd52, 0x735c, 0xab86, 0x83ff, 0x0170, 0x938a, 0x0009,
+	0x0804, 0xbe22, 0x735c, 0xab86, 0x83ff, 0x0170, 0x938a, 0x0009,
 	0x0210, 0x2019, 0x0008, 0x0036, 0x2308, 0x2019, 0x0018, 0x2011,
-	0x0025, 0x080c, 0xc41b, 0x003e, 0xd6cc, 0x0904, 0xbd67, 0x7154,
-	0xa98a, 0x81ff, 0x0904, 0xbd67, 0x9192, 0x0021, 0x1278, 0x8304,
-	0x9098, 0x0018, 0x2011, 0x0029, 0x080c, 0xc41b, 0x2011, 0x0205,
-	0x2013, 0x0000, 0x080c, 0xcf29, 0x0804, 0xbd67, 0xa868, 0xd0fc,
+	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,
-	0xc3ba, 0x00ae, 0x080c, 0xcf29, 0x080c, 0xc40b, 0x0804, 0xbd69,
-	0x080c, 0xcb72, 0x0804, 0xbd7e, 0xa87c, 0xd0ac, 0x0904, 0xbd8f,
-	0xa880, 0xd0bc, 0x1904, 0xbd8f, 0x7348, 0xa838, 0x9306, 0x11c8,
-	0x734c, 0xa834, 0x931e, 0x0904, 0xbd8f, 0xd6d4, 0x0190, 0xab38,
-	0x9305, 0x0904, 0xbd8f, 0x0068, 0xa87c, 0xd0ac, 0x0904, 0xbd5a,
-	0xa838, 0xa934, 0x9105, 0x0904, 0xbd5a, 0xa880, 0xd0bc, 0x1904,
-	0xbd5a, 0x080c, 0xcbaf, 0x0804, 0xbd7e, 0x00f6, 0x2079, 0x026c,
+	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, 0xa8c2, 0x604b, 0x0000, 0x080c, 0x1c55,
-	0x1118, 0x6144, 0x080c, 0x9265, 0x009e, 0x0005, 0x9182, 0x0057,
-	0x1220, 0x9182, 0x0040, 0x0208, 0x000a, 0x0005, 0xbe8d, 0xbe8d,
-	0xbe8d, 0xbe8d, 0xbe8d, 0xbe8d, 0xbe8d, 0xbe8d, 0xbe8d, 0xbe8d,
-	0xbe8f, 0xbe8d, 0xbe8d, 0xbe8d, 0xbe8d, 0xbea0, 0xbe8d, 0xbe8d,
-	0xbe8d, 0xbe8d, 0xbec4, 0xbe8d, 0xbe8d, 0x080c, 0x0d7d, 0x6004,
-	0x9086, 0x0040, 0x1110, 0x080c, 0x95ff, 0x2019, 0x0001, 0x080c,
-	0xa133, 0x6003, 0x0002, 0x080c, 0xcfa1, 0x080c, 0x965a, 0x0005,
-	0x6004, 0x9086, 0x0040, 0x1110, 0x080c, 0x95ff, 0x2019, 0x0001,
-	0x080c, 0xa133, 0x080c, 0x965a, 0x080c, 0x320f, 0x080c, 0xcf99,
-	0x0096, 0x6114, 0x2148, 0x080c, 0xc865, 0x0150, 0xa867, 0x0103,
-	0xa87b, 0x0029, 0xa877, 0x0000, 0x080c, 0x6d9f, 0x080c, 0xca54,
-	0x009e, 0x080c, 0xabf0, 0x0005, 0x080c, 0x0d7d, 0xa87b, 0x0015,
+	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, 0xbefc, 0xbefc, 0xbefc,
-	0xbefc, 0xbefc, 0xbefe, 0xbefc, 0xbefc, 0xbfbb, 0xbefc, 0xbefc,
-	0xbefc, 0xbefc, 0xbefc, 0xbefc, 0xbefc, 0xbefc, 0xbefc, 0xbefc,
-	0xc0f9, 0xbefc, 0xc103, 0xbefc, 0x080c, 0x0d7d, 0x601c, 0xd0bc,
+	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,
-	0xbcee, 0x6114, 0x0096, 0x2148, 0xa87c, 0xc0e5, 0xa87e, 0x009e,
+	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, 0xbfb4,
+	0x82ff, 0x0110, 0x8211, 0xba3e, 0x00be, 0x86ff, 0x0904, 0xc084,
 	0x9694, 0xff00, 0x9284, 0x0c00, 0x0120, 0x7048, 0xb092, 0x704c,
-	0xb08e, 0x9284, 0x0300, 0x0904, 0xbfb4, 0x9686, 0x0100, 0x1130,
+	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,
@@ -5924,19 +5950,19 @@
 	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, 0xc41b, 0x003e, 0xd6cc, 0x01e8, 0x7154,
+	0x2011, 0x0025, 0x080c, 0xc4f8, 0x003e, 0xd6cc, 0x01e8, 0x7154,
 	0xa98a, 0x81ff, 0x01c8, 0x9192, 0x0021, 0x1260, 0x8304, 0x9098,
-	0x0018, 0x2011, 0x0029, 0x080c, 0xc41b, 0x2011, 0x0205, 0x2013,
+	0x0018, 0x2011, 0x0029, 0x080c, 0xc4f8, 0x2011, 0x0205, 0x2013,
 	0x0000, 0x0050, 0xb068, 0xd0fc, 0x0120, 0x2009, 0x0020, 0xa98a,
-	0x0c68, 0x2950, 0x080c, 0xc3ba, 0x080c, 0x1a62, 0x009e, 0x00ee,
+	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, 0xcfaa, 0x0904, 0xc0f4, 0x604b,
+	0xa87e, 0x6003, 0x0002, 0x080c, 0xd0c1, 0x0904, 0xc1c6, 0x604b,
 	0x0000, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x1500,
-	0xd1cc, 0x0904, 0xc0b9, 0xa978, 0xa868, 0xd0fc, 0x0904, 0xc07a,
+	0xd1cc, 0x0904, 0xc18a, 0xa978, 0xa868, 0xd0fc, 0x0904, 0xc14b,
 	0x0016, 0xa87c, 0x0006, 0xa880, 0x0006, 0x00a6, 0x2150, 0xb174,
-	0x9184, 0x00ff, 0x90b6, 0x0002, 0x0904, 0xc048, 0x9086, 0x0028,
-	0x1904, 0xc034, 0xa87b, 0x001c, 0xb07b, 0x001c, 0x0804, 0xc050,
+	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,
@@ -5944,1271 +5970,1284 @@
 	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, 0xcbaf, 0x0804, 0xc0f4, 0xd1dc, 0x0158, 0xa87b, 0x0015,
-	0xb07b, 0x0015, 0x080c, 0xce4c, 0x0118, 0xb174, 0xc1dc, 0xb176,
+	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, 0xbec6,
+	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, 0xa87e, 0x080c,
-	0xcf29, 0x001e, 0xa874, 0x0006, 0x2148, 0x080c, 0x0ff9, 0x001e,
-	0x0804, 0xc0e6, 0x0016, 0x00a6, 0x2150, 0xb174, 0x9184, 0x00ff,
-	0x90b6, 0x0002, 0x01e0, 0x9086, 0x0028, 0x1128, 0xa87b, 0x001c,
-	0xb07b, 0x001c, 0x00e0, 0xd1dc, 0x0158, 0xa87b, 0x0015, 0xb07b,
-	0x0015, 0x080c, 0xce4c, 0x0118, 0xb174, 0xc1dc, 0xb176, 0x0078,
-	0xd1d4, 0x0128, 0xa87b, 0x0007, 0xb07b, 0x0007, 0x0040, 0xa87c,
-	0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115, 0x190c, 0xbec6, 0xa890,
-	0xb092, 0xa88c, 0xb08e, 0xa87c, 0xb07e, 0x00ae, 0x080c, 0x0ff9,
-	0x009e, 0x080c, 0xcf29, 0xa974, 0x0016, 0x080c, 0xc40b, 0x001e,
-	0x0468, 0xa867, 0x0103, 0xa974, 0x9184, 0x00ff, 0x90b6, 0x0002,
-	0x01b0, 0x9086, 0x0028, 0x1118, 0xa87b, 0x001c, 0x00d0, 0xd1dc,
-	0x0148, 0xa87b, 0x0015, 0x080c, 0xce4c, 0x0118, 0xa974, 0xc1dc,
-	0xa976, 0x0078, 0xd1d4, 0x0118, 0xa87b, 0x0007, 0x0050, 0xa87b,
-	0x0000, 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115, 0x190c,
-	0xbec6, 0xa974, 0x0016, 0x080c, 0x6bb5, 0x001e, 0x6010, 0x00b6,
-	0x2058, 0xb8d0, 0x0016, 0x9005, 0x190c, 0x676f, 0x001e, 0x00be,
-	0xd1e4, 0x1120, 0x080c, 0xabf0, 0x009e, 0x0005, 0x080c, 0xcb72,
-	0x0cd8, 0x6114, 0x0096, 0x2148, 0xa97c, 0x080c, 0xcfaa, 0x190c,
-	0x1a80, 0x009e, 0x0005, 0x0096, 0x6114, 0x2148, 0xa83c, 0xa940,
-	0x9105, 0x01e8, 0xa877, 0x0000, 0xa87b, 0x0000, 0xa867, 0x0103,
-	0x00b6, 0x6010, 0x2058, 0xa834, 0xa938, 0x9115, 0x11a0, 0x080c,
-	0x6bb5, 0xba3c, 0x8211, 0x0208, 0xba3e, 0xb8d0, 0x9005, 0x0110,
-	0x080c, 0x676f, 0x080c, 0xabf0, 0x00be, 0x009e, 0x0005, 0xa87c,
-	0xc0dc, 0xa87e, 0x08f8, 0xb800, 0xd0bc, 0x1120, 0xa834, 0x080c,
-	0xbec6, 0x0c28, 0xa880, 0xd0bc, 0x1dc8, 0x080c, 0xcbaf, 0x0c60,
-	0x080c, 0x95ff, 0x0010, 0x080c, 0x965a, 0x601c, 0xd084, 0x0110,
-	0x080c, 0x1a94, 0x080c, 0xc865, 0x01f0, 0x0096, 0x6114, 0x2148,
-	0x080c, 0xca7a, 0x1118, 0x080c, 0xb5c6, 0x00a0, 0xa867, 0x0103,
-	0x2009, 0x180c, 0x210c, 0xd18c, 0x1198, 0xd184, 0x1170, 0x6108,
-	0xa97a, 0x918e, 0x0029, 0x1110, 0x080c, 0xe66e, 0xa877, 0x0000,
-	0x080c, 0x6d9f, 0x009e, 0x0804, 0xac2b, 0xa87b, 0x0004, 0x0cb0,
-	0xa87b, 0x0004, 0x0c98, 0x9182, 0x0057, 0x1220, 0x9182, 0x0040,
-	0x0208, 0x000a, 0x0005, 0xc18a, 0xc18a, 0xc18a, 0xc18a, 0xc18a,
-	0xc18c, 0xc18a, 0xc18a, 0xc18a, 0xc18a, 0xc18a, 0xc18a, 0xc18a,
-	0xc18a, 0xc18a, 0xc18a, 0xc18a, 0xc18a, 0xc18a, 0xc18a, 0xc1b0,
-	0xc18a, 0xc18a, 0x080c, 0x0d7d, 0x080c, 0x56fd, 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, 0x6d9f, 0x009e, 0x0804, 0xabf0,
-	0x080c, 0x56fd, 0x0dd8, 0x6014, 0x900e, 0x9016, 0x0c10, 0x9182,
-	0x0085, 0x0002, 0xc1c9, 0xc1c7, 0xc1c7, 0xc1d5, 0xc1c7, 0xc1c7,
-	0xc1c7, 0xc1c7, 0xc1c7, 0xc1c7, 0xc1c7, 0xc1c7, 0xc1c7, 0x080c,
-	0x0d7d, 0x6003, 0x0001, 0x6106, 0x0126, 0x2091, 0x8000, 0x2009,
-	0x8020, 0x080c, 0x9239, 0x012e, 0x0005, 0x0026, 0x0056, 0x00d6,
-	0x00e6, 0x2071, 0x0260, 0x7224, 0x6216, 0x7220, 0x080c, 0xc853,
-	0x01a0, 0x2268, 0x6800, 0x9086, 0x0000, 0x0178, 0x6010, 0x6d10,
-	0x952e, 0x1158, 0x00c6, 0x2d60, 0x080c, 0xc446, 0x00ce, 0x0128,
-	0x6803, 0x0002, 0x6007, 0x0086, 0x0010, 0x6007, 0x0087, 0x6003,
-	0x0001, 0x2009, 0x8020, 0x080c, 0x9239, 0x7220, 0x080c, 0xc853,
-	0x0178, 0x6810, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0140,
-	0x6824, 0xd0ec, 0x0128, 0x00c6, 0x2d60, 0x080c, 0xcbaf, 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, 0x95ff, 0x0096, 0x6014, 0x2048,
-	0x080c, 0xc865, 0x0140, 0xa867, 0x0103, 0xa877, 0x0000, 0xa87b,
-	0x0029, 0x080c, 0x6d9f, 0x009e, 0x080c, 0xac2b, 0x0804, 0x96bd,
-	0xc24d, 0xc24f, 0xc24f, 0xc24d, 0xc24d, 0xc24d, 0xc24d, 0xc24d,
-	0xc24d, 0xc24d, 0xc24d, 0xc24d, 0xc24d, 0x080c, 0x0d7d, 0x080c,
-	0xac2b, 0x0005, 0x9186, 0x0013, 0x1130, 0x6004, 0x9082, 0x0085,
-	0x2008, 0x0804, 0xc29e, 0x9186, 0x0027, 0x1558, 0x080c, 0x95ff,
-	0x080c, 0x320f, 0x080c, 0xcf99, 0x0096, 0x6014, 0x2048, 0x080c,
-	0xc865, 0x0150, 0xa867, 0x0103, 0xa877, 0x0000, 0xa87b, 0x0029,
-	0x080c, 0x6d9f, 0x080c, 0xca54, 0x009e, 0x080c, 0xabf0, 0x0005,
-	0x9186, 0x0089, 0x0118, 0x9186, 0x008a, 0x1140, 0x080c, 0xaaab,
-	0x0128, 0x9086, 0x000c, 0x0904, 0xc2d6, 0x0000, 0x080c, 0xacaa,
-	0x0c70, 0x9186, 0x0014, 0x1d60, 0x080c, 0x95ff, 0x0096, 0x6014,
-	0x2048, 0x080c, 0xc865, 0x0d00, 0xa867, 0x0103, 0xa877, 0x0000,
-	0xa87b, 0x0006, 0xa880, 0xc0ec, 0xa882, 0x0890, 0x0002, 0xc2ae,
-	0xc2ac, 0xc2ac, 0xc2ac, 0xc2ac, 0xc2ac, 0xc2c2, 0xc2ac, 0xc2ac,
-	0xc2ac, 0xc2ac, 0xc2ac, 0xc2ac, 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, 0xacaa, 0xc2ec,
-	0xc2ec, 0xc2ec, 0xc2ec, 0xc2ee, 0xc33b, 0xc2ec, 0xc2ec, 0xc2ec,
-	0xc2ec, 0xc2ec, 0xc2ec, 0xc2ec, 0x080c, 0x0d7d, 0x0096, 0x6010,
-	0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0168, 0x6034, 0x908c,
-	0xff00, 0x810f, 0x9186, 0x0039, 0x0118, 0x9186, 0x0035, 0x1118,
-	0x009e, 0x0804, 0xc34f, 0x080c, 0xc865, 0x1118, 0x080c, 0xca54,
-	0x0068, 0x6014, 0x2048, 0x080c, 0xcfb0, 0x1110, 0x080c, 0xca54,
-	0xa867, 0x0103, 0x080c, 0xcf64, 0x080c, 0x6d9f, 0x00d6, 0x2c68,
-	0x080c, 0xab9a, 0x01d0, 0x6003, 0x0001, 0x6007, 0x001e, 0x600b,
-	0xffff, 0x2009, 0x026e, 0x210c, 0x613a, 0x2009, 0x026f, 0x210c,
-	0x613e, 0x6910, 0x6112, 0x080c, 0xccfe, 0x695c, 0x615e, 0x6023,
-	0x0001, 0x2009, 0x8020, 0x080c, 0x9239, 0x2d60, 0x00de, 0x080c,
-	0xabf0, 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, 0xcefc, 0x11f0, 0x080c, 0xab9a, 0x01d8, 0x6106,
-	0x6003, 0x0001, 0x6023, 0x0001, 0x6910, 0x6112, 0x692c, 0x612e,
-	0x6930, 0x6132, 0x6934, 0x918c, 0x00ff, 0x6136, 0x6938, 0x613a,
-	0x693c, 0x613e, 0x695c, 0x615e, 0x080c, 0xccfe, 0x2009, 0x8020,
-	0x080c, 0x9239, 0x2d60, 0x00de, 0x0804, 0xabf0, 0x0096, 0x6014,
-	0x2048, 0x080c, 0xc865, 0x01c8, 0xa867, 0x0103, 0xa880, 0xd0b4,
-	0x0128, 0xc0ec, 0xa882, 0xa87b, 0x0006, 0x0048, 0xd0bc, 0x0118,
-	0xa87b, 0x0002, 0x0020, 0xa87b, 0x0005, 0x080c, 0xcb6e, 0xa877,
-	0x0000, 0x080c, 0x6d9f, 0x080c, 0xca54, 0x009e, 0x0804, 0xabf0,
-	0x0016, 0x0096, 0x6014, 0x2048, 0x080c, 0xc865, 0x0140, 0xa867,
-	0x0103, 0xa87b, 0x0028, 0xa877, 0x0000, 0x080c, 0x6d9f, 0x009e,
-	0x001e, 0x9186, 0x0013, 0x0158, 0x9186, 0x0014, 0x0130, 0x9186,
-	0x0027, 0x0118, 0x080c, 0xacaa, 0x0020, 0x080c, 0x95ff, 0x080c,
-	0xac2b, 0x0005, 0x0056, 0x0066, 0x0096, 0x00a6, 0x2029, 0x0001,
-	0x9182, 0x0101, 0x1208, 0x0010, 0x2009, 0x0100, 0x2130, 0x8304,
-	0x9098, 0x0018, 0x2009, 0x0020, 0x2011, 0x0029, 0x080c, 0xc41b,
-	0x96b2, 0x0020, 0xb004, 0x904d, 0x0110, 0x080c, 0x0ff9, 0x080c,
-	0x1047, 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, 0x6d9f, 0x2a48, 0x0cb8, 0x080c,
-	0x6d9f, 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, 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,
-	0xc498, 0xc498, 0xc493, 0xc4bc, 0xc470, 0xc493, 0xc472, 0xc493,
-	0xc470, 0x90ff, 0xc493, 0xc493, 0xc493, 0xc470, 0xc470, 0xc470,
-	0x080c, 0x0d7d, 0x6010, 0x9080, 0x0000, 0x2004, 0xd0bc, 0x190c,
-	0xc4bc, 0x0036, 0x6014, 0x0096, 0x2048, 0xa880, 0x009e, 0xd0cc,
-	0x0118, 0x2019, 0x000c, 0x0038, 0xd094, 0x0118, 0x2019, 0x000d,
-	0x0010, 0x2019, 0x0010, 0x080c, 0xde67, 0x6023, 0x0006, 0x6003,
-	0x0007, 0x003e, 0x0005, 0x9006, 0x0005, 0x9085, 0x0001, 0x0005,
-	0x0096, 0x86ff, 0x11e8, 0x6014, 0x2048, 0x080c, 0xc865, 0x01d0,
-	0x6043, 0xffff, 0xa864, 0x9086, 0x0139, 0x1128, 0xa87b, 0x0005,
-	0xa883, 0x0000, 0x0028, 0x900e, 0x2001, 0x0005, 0x080c, 0x6fd3,
-	0x080c, 0xcb6e, 0x080c, 0x6d93, 0x080c, 0xac2b, 0x9085, 0x0001,
-	0x009e, 0x0005, 0x9006, 0x0ce0, 0x080c, 0xa899, 0x080c, 0xcfbe,
-	0x6000, 0x908a, 0x0016, 0x1a0c, 0x0d7d, 0x002b, 0x0106, 0x080c,
-	0xa8b5, 0x010e, 0x0005, 0xc4db, 0xc509, 0xc4dd, 0xc530, 0xc504,
-	0xc4db, 0xc493, 0xc498, 0xc498, 0xc493, 0xc493, 0xc493, 0xc493,
-	0xc493, 0xc493, 0xc493, 0x080c, 0x0d7d, 0x86ff, 0x1510, 0x6020,
-	0x9086, 0x0006, 0x01f0, 0x0096, 0x6014, 0x2048, 0x080c, 0xc865,
-	0x0158, 0xa87c, 0xd0cc, 0x0130, 0x0096, 0xa878, 0x2048, 0x080c,
-	0x0ff9, 0x009e, 0x080c, 0xcb6e, 0x009e, 0x080c, 0xcf3e, 0x6007,
-	0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x2009, 0x8020, 0x080c,
-	0x921b, 0x9085, 0x0001, 0x0005, 0x0066, 0x080c, 0x1a94, 0x006e,
-	0x08a0, 0x00e6, 0x2071, 0x19e6, 0x7030, 0x9c06, 0x1120, 0x080c,
-	0xa0b3, 0x00ee, 0x0850, 0x6020, 0x9084, 0x000f, 0x9086, 0x0006,
-	0x1150, 0x0086, 0x0096, 0x2049, 0x0001, 0x2c40, 0x080c, 0xa207,
-	0x009e, 0x008e, 0x0040, 0x0066, 0x080c, 0x9faf, 0x190c, 0x0d7d,
-	0x080c, 0x9fbd, 0x006e, 0x00ee, 0x1904, 0xc4dd, 0x0804, 0xc493,
-	0x0036, 0x00e6, 0x2071, 0x19e6, 0x704c, 0x9c06, 0x1138, 0x901e,
-	0x080c, 0xa133, 0x00ee, 0x003e, 0x0804, 0xc4dd, 0x080c, 0xa33e,
-	0x00ee, 0x003e, 0x1904, 0xc4dd, 0x0804, 0xc493, 0x00c6, 0x0066,
-	0x6020, 0x9084, 0x000f, 0x001b, 0x006e, 0x00ce, 0x0005, 0xc566,
-	0xc635, 0xc79f, 0xc56e, 0xac2b, 0xc566, 0xde59, 0xcfa6, 0xc635,
-	0x90c6, 0xc82b, 0xc55f, 0xc55f, 0xc55f, 0xc55f, 0xc55f, 0x080c,
-	0x0d7d, 0x080c, 0xca7a, 0x1110, 0x080c, 0xb5c6, 0x0005, 0x080c,
-	0x95ff, 0x0804, 0xabf0, 0x601b, 0x0001, 0x0005, 0x080c, 0xc865,
-	0x0130, 0x6014, 0x0096, 0x2048, 0x2c00, 0xa896, 0x009e, 0x080c,
-	0xa899, 0x080c, 0xcfbe, 0x6000, 0x908a, 0x0016, 0x1a0c, 0x0d7d,
-	0x0013, 0x0804, 0xa8b5, 0xc593, 0xc595, 0xc5bf, 0xc5d3, 0xc600,
-	0xc593, 0xc566, 0xc566, 0xc566, 0xc5da, 0xc5da, 0xc593, 0xc593,
-	0xc593, 0xc593, 0xc5e4, 0x080c, 0x0d7d, 0x00e6, 0x6014, 0x0096,
-	0x2048, 0xa880, 0xc0b5, 0xa882, 0x009e, 0x2071, 0x19e6, 0x7030,
-	0x9c06, 0x01d0, 0x0066, 0x080c, 0x9faf, 0x190c, 0x0d7d, 0x080c,
-	0x9fbd, 0x006e, 0x080c, 0xcf3e, 0x6007, 0x0085, 0x6003, 0x000b,
-	0x6023, 0x0002, 0x2001, 0x1986, 0x2004, 0x601a, 0x2009, 0x8020,
-	0x080c, 0x921b, 0x00ee, 0x0005, 0x601b, 0x0001, 0x0cd8, 0x0096,
-	0x6014, 0x2048, 0xa880, 0xc0b5, 0xa882, 0x009e, 0x080c, 0xcf3e,
-	0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x2009, 0x8020,
-	0x080c, 0x921b, 0x0005, 0x080c, 0xa899, 0x080c, 0xaa2d, 0x080c,
-	0xa8b5, 0x0c28, 0x0096, 0x601b, 0x0001, 0x6014, 0x2048, 0xa880,
-	0xc0b5, 0xa882, 0x009e, 0x0005, 0x080c, 0x56fd, 0x01b8, 0x6014,
-	0x0096, 0x904d, 0x0190, 0xa864, 0xa867, 0x0103, 0xa87b, 0x0006,
-	0x9086, 0x0139, 0x1150, 0xa867, 0x0139, 0xa87b, 0x0030, 0xa897,
-	0x4005, 0xa89b, 0x0004, 0x080c, 0x6d9f, 0x009e, 0x0804, 0xabf0,
-	0x6014, 0x0096, 0x904d, 0x0560, 0xa97c, 0xd1e4, 0x1158, 0x611c,
-	0xd1fc, 0x0530, 0x6110, 0x00b6, 0x2158, 0xb93c, 0x8109, 0x0208,
-	0xb93e, 0x00be, 0x080c, 0xa8b5, 0x2001, 0x180f, 0x2004, 0xd0c4,
-	0x0110, 0x009e, 0x0005, 0xa884, 0x009e, 0x8003, 0x800b, 0x810b,
-	0x9108, 0x611a, 0x2001, 0x0037, 0x2c08, 0x080c, 0x1693, 0x6000,
-	0x9086, 0x0004, 0x1120, 0x2009, 0x0048, 0x080c, 0xac8d, 0x0005,
-	0x009e, 0x080c, 0x1a94, 0x0804, 0xc5bf, 0x6000, 0x908a, 0x0016,
-	0x1a0c, 0x0d7d, 0x000b, 0x0005, 0xc64c, 0xc56b, 0xc64e, 0xc64c,
-	0xc64e, 0xc64e, 0xc567, 0xc64c, 0xc561, 0xc561, 0xc64c, 0xc64c,
-	0xc64c, 0xc64c, 0xc64c, 0xc64c, 0x080c, 0x0d7d, 0x6010, 0x00b6,
-	0x2058, 0xb804, 0x9084, 0x00ff, 0x00be, 0x908a, 0x000c, 0x1a0c,
-	0x0d7d, 0x00b6, 0x0013, 0x00be, 0x0005, 0xc669, 0xc736, 0xc66b,
-	0xc6ab, 0xc66b, 0xc6ab, 0xc66b, 0xc679, 0xc669, 0xc6ab, 0xc669,
-	0xc69a, 0x080c, 0x0d7d, 0x6004, 0x908e, 0x0016, 0x05c0, 0x908e,
-	0x0004, 0x05a8, 0x908e, 0x0002, 0x0590, 0x908e, 0x0052, 0x0904,
-	0xc732, 0x6004, 0x080c, 0xca7a, 0x0904, 0xc74f, 0x908e, 0x0004,
-	0x1110, 0x080c, 0x323e, 0x908e, 0x0021, 0x0904, 0xc753, 0x908e,
-	0x0022, 0x0904, 0xc79a, 0x908e, 0x003d, 0x0904, 0xc753, 0x908e,
-	0x0039, 0x0904, 0xc757, 0x908e, 0x0035, 0x0904, 0xc757, 0x908e,
-	0x001e, 0x0178, 0x908e, 0x0001, 0x1140, 0x6010, 0x2058, 0xb804,
-	0x9084, 0x00ff, 0x9086, 0x0006, 0x0110, 0x080c, 0x320f, 0x080c,
-	0xb5c6, 0x0804, 0xac2b, 0x00c6, 0x00d6, 0x6104, 0x9186, 0x0016,
-	0x0904, 0xc723, 0x9186, 0x0002, 0x1904, 0xc6f8, 0x2001, 0x1837,
-	0x2004, 0xd08c, 0x11c8, 0x080c, 0x74ec, 0x11b0, 0x080c, 0xcf84,
-	0x0138, 0x080c, 0x750f, 0x1120, 0x080c, 0x73f7, 0x0804, 0xc783,
-	0x2001, 0x197c, 0x2003, 0x0001, 0x2001, 0x1800, 0x2003, 0x0001,
-	0x080c, 0x741d, 0x0804, 0xc783, 0x6010, 0x2058, 0x2001, 0x1837,
-	0x2004, 0xd0ac, 0x1904, 0xc783, 0xb8a0, 0x9084, 0xff80, 0x1904,
-	0xc783, 0xb840, 0x9084, 0x00ff, 0x9005, 0x0190, 0x8001, 0xb842,
-	0x6017, 0x0000, 0x6023, 0x0007, 0x601b, 0x0398, 0x604b, 0x0000,
-	0x080c, 0xab9a, 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, 0x5fd7, 0x00ee, 0x080c,
-	0xb5c6, 0x0030, 0x080c, 0xb5c6, 0x080c, 0x320f, 0x080c, 0xcf99,
-	0x00e6, 0x0126, 0x2091, 0x8000, 0x080c, 0x323e, 0x012e, 0x00ee,
-	0x080c, 0xac2b, 0x0005, 0x2001, 0x0002, 0x080c, 0x6594, 0x6003,
-	0x0001, 0x6007, 0x0002, 0x080c, 0x9240, 0x080c, 0x96bd, 0x00de,
-	0x00ce, 0x0c80, 0x080c, 0x323e, 0x0804, 0xc6a7, 0x00c6, 0x00d6,
-	0x6104, 0x9186, 0x0016, 0x0d38, 0x6010, 0x2058, 0xb840, 0x9084,
-	0x00ff, 0x9005, 0x0904, 0xc6f8, 0x8001, 0xb842, 0x6003, 0x0001,
-	0x080c, 0x9240, 0x080c, 0x96bd, 0x00de, 0x00ce, 0x0898, 0x080c,
-	0xb5c6, 0x0804, 0xc6a9, 0x080c, 0xb602, 0x0804, 0xc6a9, 0x00d6,
-	0x2c68, 0x6104, 0x080c, 0xcefc, 0x00de, 0x0118, 0x080c, 0xabf0,
-	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, 0x9239, 0x0005, 0x00de, 0x00ce, 0x080c, 0xb5c6, 0x080c,
-	0x320f, 0x00e6, 0x0126, 0x2091, 0x8000, 0x080c, 0x323e, 0x6017,
-	0x0000, 0x6023, 0x0007, 0x601b, 0x0398, 0x604b, 0x0000, 0x012e,
-	0x00ee, 0x0005, 0x080c, 0xb02b, 0x1904, 0xc74f, 0x0005, 0x6000,
-	0x908a, 0x0016, 0x1a0c, 0x0d7d, 0x0096, 0x00d6, 0x001b, 0x00de,
-	0x009e, 0x0005, 0xc7ba, 0xc7ba, 0xc7ba, 0xc7ba, 0xc7ba, 0xc7ba,
-	0xc7ba, 0xc7ba, 0xc7ba, 0xc566, 0xc7ba, 0xc56b, 0xc7bc, 0xc56b,
-	0xc7d6, 0xc7ba, 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, 0x9239, 0x0005, 0x080c, 0xcf78,
-	0x0118, 0x080c, 0xcf8b, 0x0010, 0x080c, 0xcf99, 0x080c, 0xca54,
-	0x080c, 0xc865, 0x0570, 0x080c, 0x320f, 0x080c, 0xc865, 0x0168,
-	0x6014, 0x2048, 0xa867, 0x0103, 0xa87b, 0x0006, 0xa877, 0x0000,
-	0xa880, 0xc0ed, 0xa882, 0x080c, 0x6d9f, 0x2c68, 0x080c, 0xab9a,
-	0x0150, 0x6810, 0x6012, 0x080c, 0xccfe, 0x00c6, 0x2d60, 0x080c,
-	0xac2b, 0x00ce, 0x0008, 0x2d60, 0x6017, 0x0000, 0x6023, 0x0001,
-	0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x9240, 0x080c, 0x96bd,
-	0x00c8, 0x080c, 0xcf78, 0x0138, 0x6034, 0x9086, 0x4000, 0x1118,
-	0x080c, 0x320f, 0x08d0, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186,
-	0x0039, 0x0118, 0x9186, 0x0035, 0x1118, 0x080c, 0x320f, 0x0868,
-	0x080c, 0xac2b, 0x0005, 0x6000, 0x908a, 0x0016, 0x1a0c, 0x0d7d,
-	0x0002, 0xc841, 0xc841, 0xc843, 0xc843, 0xc843, 0xc841, 0xc841,
-	0xac2b, 0xc841, 0xc841, 0xc841, 0xc841, 0xc841, 0xc841, 0xc841,
-	0xc841, 0x080c, 0x0d7d, 0x080c, 0xa899, 0x080c, 0xaa2d, 0x080c,
-	0xa8b5, 0x6114, 0x0096, 0x2148, 0xa87b, 0x0006, 0x080c, 0x6d9f,
-	0x009e, 0x0804, 0xabf0, 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,
-	0xcf84, 0x0180, 0x9286, 0x0001, 0x1168, 0x6004, 0x9086, 0x0004,
-	0x1148, 0x080c, 0x320f, 0x080c, 0xcf99, 0x00c6, 0x080c, 0xac2b,
-	0x00ce, 0x0060, 0x080c, 0xcc70, 0x0148, 0x080c, 0xca7a, 0x1110,
-	0x080c, 0xb5c6, 0x00c6, 0x080c, 0xabf0, 0x00ce, 0x9ce0, 0x001c,
-	0x7068, 0x9c02, 0x1208, 0x08a0, 0x012e, 0x000e, 0x003e, 0x00ce,
-	0x00ee, 0x0005, 0x00e6, 0x00c6, 0x0016, 0x9188, 0x1000, 0x210c,
-	0x81ff, 0x0128, 0x2061, 0x1b31, 0x6112, 0x080c, 0x320f, 0x9006,
-	0x0010, 0x9085, 0x0001, 0x001e, 0x00ce, 0x00ee, 0x0005, 0x00c6,
-	0x0126, 0x2091, 0x8000, 0x080c, 0xab9a, 0x01b0, 0x665e, 0x2b00,
-	0x6012, 0x080c, 0x56fd, 0x0118, 0x080c, 0xc996, 0x0168, 0x080c,
-	0xccfe, 0x6023, 0x0003, 0x2009, 0x004b, 0x080c, 0xac8d, 0x9085,
+	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,
+	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, 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,
+	0x7080, 0xaa54, 0x9206, 0x1140, 0x6210, 0x00b6, 0x2258, 0xbaa0,
+	0x00be, 0x900e, 0x080c, 0x328f, 0x080c, 0xb0bf, 0x0020, 0x080c,
+	0xb693, 0x080c, 0xacb0, 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,
 	0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x00c6, 0x0126,
-	0x2091, 0x8000, 0xbaa0, 0x080c, 0xac60, 0x0580, 0x605f, 0x0000,
-	0x2b00, 0x6012, 0x080c, 0xccfe, 0x6023, 0x0003, 0x0016, 0x080c,
-	0xa899, 0x080c, 0x93c6, 0x0076, 0x903e, 0x080c, 0x928f, 0x2c08,
-	0x080c, 0xe038, 0x007e, 0x080c, 0xa8b5, 0x001e, 0xd184, 0x0128,
-	0x080c, 0xabf0, 0x9085, 0x0001, 0x0070, 0x080c, 0x56fd, 0x0128,
-	0xd18c, 0x1170, 0x080c, 0xc996, 0x0148, 0x2009, 0x004c, 0x080c,
-	0xac8d, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8,
-	0x2900, 0x6016, 0x0c90, 0x2009, 0x004d, 0x0010, 0x2009, 0x004e,
-	0x00f6, 0x00c6, 0x0046, 0x0016, 0x080c, 0xab9a, 0x2c78, 0x0590,
-	0x7e5e, 0x2b00, 0x7812, 0x7823, 0x0003, 0x2021, 0x0005, 0x080c,
-	0xc9a8, 0x9186, 0x004d, 0x0118, 0x9186, 0x004e, 0x0148, 0x2001,
-	0x197f, 0x200c, 0xd1fc, 0x0168, 0x2f60, 0x080c, 0xabf0, 0x00d0,
-	0x2001, 0x197e, 0x200c, 0xd1fc, 0x0120, 0x2f60, 0x080c, 0xabf0,
-	0x0088, 0x2f60, 0x080c, 0x56fd, 0x0138, 0xd18c, 0x1118, 0x04f1,
-	0x0148, 0x0010, 0x2900, 0x7816, 0x001e, 0x0016, 0x080c, 0xac8d,
-	0x9085, 0x0001, 0x001e, 0x004e, 0x00ce, 0x00fe, 0x0005, 0x00f6,
-	0x00c6, 0x0046, 0x080c, 0xab9a, 0x2c78, 0x0508, 0x7e5e, 0x2b00,
-	0x7812, 0x7823, 0x0003, 0x0096, 0x2021, 0x0004, 0x0489, 0x009e,
-	0x2001, 0x197d, 0x200c, 0xd1fc, 0x0120, 0x2f60, 0x080c, 0xabf0,
-	0x0060, 0x2f60, 0x080c, 0x56fd, 0x0120, 0xd18c, 0x1160, 0x0071,
-	0x0130, 0x2009, 0x0052, 0x080c, 0xac8d, 0x9085, 0x0001, 0x004e,
-	0x00ce, 0x00fe, 0x0005, 0x2900, 0x7816, 0x0c98, 0x00c6, 0x080c,
-	0x4ac9, 0x00ce, 0x1120, 0x080c, 0xabf0, 0x9006, 0x0005, 0xa867,
-	0x0000, 0xa86b, 0x8000, 0x2900, 0x6016, 0x9085, 0x0001, 0x0005,
-	0x0096, 0x0076, 0x0126, 0x2091, 0x8000, 0x080c, 0xa899, 0x080c,
-	0x6826, 0x0158, 0x2001, 0xc9af, 0x0006, 0x900e, 0x2400, 0x080c,
-	0x6fd3, 0x080c, 0x6d9f, 0x000e, 0x0807, 0x2418, 0x080c, 0x95c5,
-	0xbaa0, 0x0086, 0x2041, 0x0001, 0x2039, 0x0001, 0x2608, 0x080c,
-	0x93e0, 0x008e, 0x080c, 0x928f, 0x2f08, 0x2648, 0x080c, 0xe038,
-	0xb93c, 0x81ff, 0x090c, 0x94b7, 0x080c, 0xa8b5, 0x012e, 0x007e,
-	0x009e, 0x0005, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xab9a,
-	0x0190, 0x660a, 0x2b08, 0x6112, 0x080c, 0xccfe, 0x6023, 0x0001,
-	0x2900, 0x6016, 0x2009, 0x001f, 0x080c, 0xac8d, 0x9085, 0x0001,
-	0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x00c6, 0x0126, 0x2091,
-	0x8000, 0x080c, 0xac60, 0x01b8, 0x660a, 0x2b08, 0x6112, 0x080c,
-	0xccfe, 0x6023, 0x0008, 0x2900, 0x6016, 0x00f6, 0x2c78, 0x080c,
-	0x174b, 0x00fe, 0x2009, 0x0021, 0x080c, 0xac8d, 0x9085, 0x0001,
-	0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x2009, 0x003d, 0x00c6,
-	0x0126, 0x0016, 0x2091, 0x8000, 0x080c, 0xab9a, 0x0198, 0x660a,
-	0x2b08, 0x6112, 0x080c, 0xccfe, 0x6023, 0x0001, 0x2900, 0x6016,
-	0x001e, 0x0016, 0x080c, 0xac8d, 0x9085, 0x0001, 0x001e, 0x012e,
-	0x00ce, 0x0005, 0x9006, 0x0cd0, 0x00c6, 0x0126, 0x2091, 0x8000,
-	0x080c, 0xac60, 0x0188, 0x2b08, 0x6112, 0x080c, 0xccfe, 0x6023,
-	0x0001, 0x2900, 0x6016, 0x2009, 0x0000, 0x080c, 0xac8d, 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, 0xc865, 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, 0xac60, 0x0198, 0x2b08, 0x6112, 0x080c, 0xccfe, 0x6023,
-	0x0001, 0x2900, 0x6016, 0x080c, 0x320f, 0x2009, 0x0028, 0x080c,
-	0xac8d, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8,
-	0x9186, 0x0015, 0x11a8, 0x2011, 0x1824, 0x2204, 0x9086, 0x0074,
-	0x1178, 0x00b6, 0x080c, 0xb81a, 0x00be, 0x080c, 0xba3d, 0x6003,
-	0x0001, 0x6007, 0x0029, 0x080c, 0x9240, 0x080c, 0x96bd, 0x0078,
-	0x6014, 0x0096, 0x2048, 0xa868, 0x009e, 0xd0fc, 0x0148, 0x2001,
-	0x0001, 0x080c, 0xcebd, 0x080c, 0xb5c6, 0x080c, 0xabf0, 0x0005,
-	0x0096, 0x6014, 0x904d, 0x090c, 0x0d7d, 0xa87b, 0x0030, 0xa883,
-	0x0000, 0xa897, 0x4005, 0xa89b, 0x0004, 0xa867, 0x0139, 0x0126,
-	0x2091, 0x8000, 0x080c, 0x6d9f, 0x012e, 0x009e, 0x080c, 0xabf0,
-	0x0c30, 0x0096, 0x9186, 0x0016, 0x1128, 0x2001, 0x0004, 0x080c,
-	0x6594, 0x00e8, 0x9186, 0x0015, 0x1510, 0x2011, 0x1824, 0x2204,
-	0x9086, 0x0014, 0x11e0, 0x6010, 0x00b6, 0x2058, 0x080c, 0x66df,
-	0x00be, 0x080c, 0xbb0e, 0x1198, 0x6010, 0x00b6, 0x2058, 0xb890,
-	0x00be, 0x9005, 0x0160, 0x2001, 0x0006, 0x080c, 0x6594, 0x6014,
-	0x2048, 0xa868, 0xd0fc, 0x0170, 0x080c, 0xafff, 0x0048, 0x6014,
-	0x2048, 0xa868, 0xd0fc, 0x0528, 0x080c, 0xb5c6, 0x080c, 0xabf0,
-	0x009e, 0x0005, 0x6014, 0x6310, 0x2358, 0x904d, 0x090c, 0x0d7d,
-	0xa87b, 0x0000, 0xa883, 0x0000, 0xa897, 0x4000, 0x900e, 0x080c,
-	0x6937, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0xa99a,
-	0x0126, 0x2091, 0x8000, 0x080c, 0x6d9f, 0x012e, 0x080c, 0xabf0,
-	0x08f8, 0x6014, 0x904d, 0x090c, 0x0d7d, 0xa87b, 0x0030, 0xa883,
-	0x0000, 0xa897, 0x4005, 0xa89b, 0x0004, 0xa867, 0x0139, 0x0126,
-	0x2091, 0x8000, 0x080c, 0x6d9f, 0x012e, 0x080c, 0xabf0, 0x0840,
-	0xa878, 0x9086, 0x0005, 0x1108, 0x0009, 0x0005, 0xa880, 0xc0ad,
-	0xa882, 0x0005, 0x604b, 0x0000, 0x6017, 0x0000, 0x6003, 0x0001,
-	0x6007, 0x0050, 0x2009, 0x8023, 0x080c, 0x9239, 0x0005, 0x00c6,
-	0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0130, 0x0066,
-	0x6020, 0x9084, 0x000f, 0x001b, 0x006e, 0x00ce, 0x0005, 0xc566,
-	0xcba1, 0xcba1, 0xcba4, 0xe365, 0xe380, 0xe383, 0xc566, 0xc566,
-	0xc566, 0xc566, 0xc566, 0xc566, 0xc566, 0xc566, 0xc566, 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, 0xab9a, 0x0508,
-	0x7810, 0x6012, 0x080c, 0xccfe, 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, 0x9239, 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, 0x9239, 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, 0x9181, 0x2001, 0x1985,
-	0x82ff, 0x1110, 0x2011, 0x0014, 0x2202, 0x2001, 0x1983, 0x200c,
-	0x8000, 0x2014, 0x2071, 0x196b, 0x711a, 0x721e, 0x2001, 0x0064,
-	0x080c, 0x9181, 0x2001, 0x1986, 0x82ff, 0x1110, 0x2011, 0x0014,
-	0x2202, 0x2001, 0x1987, 0x9288, 0x000a, 0x2102, 0x2001, 0x0017,
-	0x080c, 0xa88a, 0x2001, 0x1a88, 0x2102, 0x2001, 0x0032, 0x080c,
-	0x1693, 0x080c, 0x6a6f, 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, 0xa88a, 0x2001, 0x1a88, 0x2102, 0x2001, 0x0032,
-	0x080c, 0x1693, 0x00ee, 0x001e, 0x000e, 0x0005, 0x0096, 0x6060,
-	0x904d, 0x0110, 0x080c, 0x1079, 0x009e, 0x0005, 0x0005, 0x00c6,
-	0x0126, 0x2091, 0x8000, 0x080c, 0xab9a, 0x0180, 0x2b08, 0x6112,
-	0x0ca9, 0x6023, 0x0001, 0x2900, 0x6016, 0x2009, 0x0033, 0x080c,
-	0xac8d, 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, 0x977c, 0x01d8, 0x707c, 0xaa50, 0x9206,
-	0x1160, 0x7080, 0xaa54, 0x9206, 0x1140, 0x6210, 0x00b6, 0x2258,
-	0xbaa0, 0x00be, 0x900e, 0x080c, 0x325e, 0x080c, 0xafff, 0x0020,
-	0x080c, 0xb5c6, 0x080c, 0xabf0, 0x00fe, 0x00ee, 0x009e, 0x0005,
-	0x7060, 0xaa54, 0x9206, 0x0d48, 0x0c80, 0x00c6, 0x0126, 0x2091,
-	0x8000, 0x080c, 0xab9a, 0x0188, 0x2b08, 0x6112, 0x080c, 0xccfe,
-	0x6023, 0x0001, 0x2900, 0x6016, 0x2009, 0x004d, 0x080c, 0xac8d,
-	0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x00c6,
-	0x0126, 0x2091, 0x8000, 0x0016, 0x080c, 0xab9a, 0x0180, 0x2b08,
-	0x6112, 0x080c, 0xccfe, 0x6023, 0x0001, 0x2900, 0x6016, 0x001e,
-	0x080c, 0xac8d, 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, 0xd5a5, 0x001e, 0xa804, 0x9005, 0x0110, 0x2048, 0x0c38,
-	0x6014, 0x2048, 0xa867, 0x0103, 0x0010, 0x080c, 0xb5c6, 0x080c,
-	0xabf0, 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, 0x977c, 0x01a8, 0x707c, 0xaa74, 0x9206,
-	0x1130, 0x7080, 0xaa78, 0x9206, 0x1110, 0x080c, 0x320f, 0x080c,
-	0xafff, 0x0020, 0x080c, 0xb5c6, 0x080c, 0xabf0, 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, 0x977c,
-	0x05f0, 0x707c, 0xaacc, 0x9206, 0x1180, 0x7080, 0xaad0, 0x9206,
-	0x1160, 0x080c, 0x320f, 0x0016, 0xa998, 0xaab0, 0x9284, 0x1000,
-	0xc0fd, 0x080c, 0x56ad, 0x001e, 0x0010, 0x080c, 0x5496, 0x080c,
-	0xc865, 0x0508, 0xa87b, 0x0000, 0xa883, 0x0000, 0xa897, 0x4000,
-	0x0080, 0x080c, 0xc865, 0x01b8, 0x6014, 0x2048, 0x080c, 0x5496,
-	0x1d70, 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, 0x4005, 0xa89b,
-	0x0004, 0x0126, 0x2091, 0x8000, 0xa867, 0x0139, 0x080c, 0x6d9f,
-	0x012e, 0x080c, 0xabf0, 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, 0xc865,
-	0x0904, 0xceb9, 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, 0x0fc4, 0x20a9, 0x0004, 0xa85c, 0x9080,
-	0x0035, 0x20a0, 0xb8c8, 0x9080, 0x000a, 0x2098, 0x080c, 0x0fc4,
-	0x00ce, 0x0090, 0xaa96, 0x3918, 0x9398, 0x0007, 0x231c, 0x6004,
-	0x9086, 0x0016, 0x0110, 0xa89b, 0x0004, 0xaba2, 0x6310, 0x2358,
-	0xb804, 0x9084, 0x00ff, 0xa89e, 0x080c, 0x6d93, 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, 0x2630, 0x2118, 0x831f, 0x939c, 0xff00, 0x7838, 0x9084,
-	0x00ff, 0x931d, 0x7c3c, 0x2011, 0x8018, 0x080c, 0x4b29, 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, 0xc853, 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, 0xbec6, 0x0005, 0x0036, 0x2019,
-	0x0001, 0x0010, 0x0036, 0x901e, 0x0499, 0x01e0, 0x080c, 0xc865,
-	0x01c8, 0x080c, 0xca54, 0x6037, 0x4000, 0x6014, 0x6017, 0x0000,
-	0x0096, 0x2048, 0xa87c, 0x080c, 0xca7a, 0x1118, 0x080c, 0xb5c6,
-	0x0040, 0xa867, 0x0103, 0xa877, 0x0000, 0x83ff, 0x1129, 0x080c,
-	0x6d9f, 0x009e, 0x003e, 0x0005, 0xa880, 0xd0b4, 0x0128, 0xa87b,
-	0x0006, 0xc0ec, 0xa882, 0x0048, 0xd0bc, 0x0118, 0xa87b, 0x0002,
-	0x0020, 0xa87b, 0x0005, 0x080c, 0xcb6e, 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, 0x4ce0, 0x004e, 0x003e,
-	0x0005, 0x0c51, 0x1d81, 0x0005, 0x2001, 0x1985, 0x2004, 0x601a,
-	0x0005, 0x2001, 0x1987, 0x2004, 0x604a, 0x0005, 0x080c, 0xabf0,
-	0x0804, 0x96bd, 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, 0xcff2, 0xd700, 0xd851, 0xcff2, 0xcff2, 0xcff2,
-	0xcff2, 0xcff2, 0xd029, 0xd8d5, 0xcff2, 0xcff2, 0xcff2, 0xcff2,
-	0xcff2, 0xcff2, 0x080c, 0x0d7d, 0x0066, 0x6000, 0x90b2, 0x0016,
-	0x1a0c, 0x0d7d, 0x0013, 0x006e, 0x0005, 0xd00d, 0xddf6, 0xd00d,
-	0xd00d, 0xd00d, 0xd00d, 0xd00d, 0xd00d, 0xdda5, 0xde48, 0xd00d,
-	0xe4a0, 0xe4d4, 0xe4a0, 0xe4d4, 0xd00d, 0x080c, 0x0d7d, 0x6000,
-	0x9082, 0x0016, 0x1a0c, 0x0d7d, 0x6000, 0x000a, 0x0005, 0xd027,
-	0xdab2, 0xdb7d, 0xdba0, 0xdc1c, 0xd027, 0xdd17, 0xdca4, 0xd8df,
-	0xdd7d, 0xdd92, 0xd027, 0xd027, 0xd027, 0xd027, 0xd027, 0x080c,
-	0x0d7d, 0x91b2, 0x0053, 0x1a0c, 0x0d7d, 0x2100, 0x91b2, 0x0040,
-	0x1a04, 0xd476, 0x0002, 0xd073, 0xd267, 0xd073, 0xd073, 0xd073,
-	0xd270, 0xd073, 0xd073, 0xd073, 0xd073, 0xd073, 0xd073, 0xd073,
-	0xd073, 0xd073, 0xd073, 0xd073, 0xd073, 0xd073, 0xd073, 0xd073,
-	0xd073, 0xd073, 0xd075, 0xd0dc, 0xd0eb, 0xd14f, 0xd17a, 0xd1f3,
-	0xd252, 0xd073, 0xd073, 0xd273, 0xd073, 0xd073, 0xd288, 0xd295,
-	0xd073, 0xd073, 0xd073, 0xd073, 0xd073, 0xd318, 0xd073, 0xd073,
-	0xd32c, 0xd073, 0xd073, 0xd2e7, 0xd073, 0xd073, 0xd073, 0xd344,
-	0xd073, 0xd073, 0xd073, 0xd3c1, 0xd073, 0xd073, 0xd073, 0xd073,
-	0xd073, 0xd073, 0xd43e, 0x080c, 0x0d7d, 0x080c, 0x6a4c, 0x1150,
-	0x2001, 0x1837, 0x2004, 0xd0cc, 0x1128, 0x9084, 0x0009, 0x9086,
-	0x0008, 0x1140, 0x6007, 0x0009, 0x602f, 0x0009, 0x6017, 0x0000,
-	0x0804, 0xd260, 0x080c, 0x69e8, 0x00e6, 0x00c6, 0x0036, 0x0026,
-	0x0016, 0x6210, 0x2258, 0xbaa0, 0x0026, 0x2019, 0x0029, 0x080c,
-	0xa899, 0x080c, 0x93c6, 0x0076, 0x903e, 0x080c, 0x928f, 0x2c08,
-	0x080c, 0xe038, 0x007e, 0x001e, 0x080c, 0xa8b5, 0x001e, 0x002e,
-	0x003e, 0x00ce, 0x00ee, 0x6610, 0x2658, 0x080c, 0x6653, 0xbe04,
-	0x9684, 0x00ff, 0x9082, 0x0006, 0x1268, 0x0016, 0x0026, 0x6210,
-	0x00b6, 0x2258, 0xbaa0, 0x00be, 0x2c08, 0x080c, 0xe6fd, 0x002e,
-	0x001e, 0x1178, 0x080c, 0xdf66, 0x1904, 0xd147, 0x080c, 0xdf02,
-	0x1120, 0x6007, 0x0008, 0x0804, 0xd260, 0x6007, 0x0009, 0x0804,
-	0xd260, 0x080c, 0xe199, 0x0128, 0x080c, 0xdf66, 0x0d78, 0x0804,
-	0xd147, 0x6017, 0x1900, 0x0c88, 0x080c, 0x3346, 0x1904, 0xd473,
-	0x6106, 0x080c, 0xdeb3, 0x6007, 0x0006, 0x0804, 0xd260, 0x6007,
-	0x0007, 0x0804, 0xd260, 0x080c, 0xe510, 0x1904, 0xd473, 0x080c,
-	0x3346, 0x1904, 0xd473, 0x00d6, 0x6610, 0x2658, 0xbe04, 0x9684,
-	0x00ff, 0x9082, 0x0006, 0x1220, 0x2001, 0x0001, 0x080c, 0x6580,
-	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, 0xdfce, 0x1190,
-	0x9686, 0x0006, 0x1140, 0x0026, 0x6210, 0x2258, 0xbaa0, 0x900e,
-	0x080c, 0x325e, 0x002e, 0x080c, 0x66df, 0x6007, 0x000a, 0x00de,
-	0x0804, 0xd260, 0x6007, 0x000b, 0x00de, 0x0804, 0xd260, 0x080c,
-	0x320f, 0x080c, 0xcf99, 0x6007, 0x0001, 0x0804, 0xd260, 0x080c,
-	0xe510, 0x1904, 0xd473, 0x080c, 0x3346, 0x1904, 0xd473, 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,
-	0x325e, 0x002e, 0x6007, 0x000c, 0x2001, 0x0001, 0x080c, 0xe6dd,
-	0x0804, 0xd260, 0x080c, 0x6a4c, 0x1140, 0x2001, 0x1837, 0x2004,
-	0x9084, 0x0009, 0x9086, 0x0008, 0x1110, 0x0804, 0xd082, 0x080c,
-	0x69e8, 0x6610, 0x2658, 0xbe04, 0x9684, 0x00ff, 0x9082, 0x0006,
-	0x06c8, 0x1138, 0x0026, 0x2001, 0x0006, 0x080c, 0x65c0, 0x002e,
-	0x0050, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0004, 0x0120, 0x9686,
-	0x0006, 0x1904, 0xd147, 0x080c, 0xdfdb, 0x1120, 0x6007, 0x000e,
-	0x0804, 0xd260, 0x0046, 0x6410, 0x2458, 0xbca0, 0x0046, 0x080c,
-	0x320f, 0x080c, 0xcf99, 0x004e, 0x0016, 0x9006, 0x2009, 0x1848,
-	0x210c, 0xd1a4, 0x0148, 0x2009, 0x0029, 0x080c, 0xe316, 0x6010,
-	0x2058, 0xb800, 0xc0e5, 0xb802, 0x001e, 0x004e, 0x6007, 0x0001,
-	0x0804, 0xd260, 0x2001, 0x0001, 0x080c, 0x6580, 0x0156, 0x0016,
-	0x0026, 0x0036, 0x20a9, 0x0004, 0x2019, 0x1805, 0x2011, 0x0270,
-	0x080c, 0xbbc1, 0x003e, 0x002e, 0x001e, 0x015e, 0x9005, 0x0168,
-	0x96b4, 0xff00, 0x8637, 0x9682, 0x0004, 0x0a04, 0xd147, 0x9682,
-	0x0007, 0x0a04, 0xd1a3, 0x0804, 0xd147, 0x6017, 0x1900, 0x6007,
-	0x0009, 0x0804, 0xd260, 0x080c, 0x6a4c, 0x1140, 0x2001, 0x1837,
-	0x2004, 0x9084, 0x0009, 0x9086, 0x0008, 0x1110, 0x0804, 0xd082,
-	0x080c, 0x69e8, 0x6610, 0x2658, 0xbe04, 0x9684, 0x00ff, 0x0006,
-	0x9086, 0x0001, 0x000e, 0x0170, 0x9082, 0x0006, 0x0698, 0x0150,
+	0x2091, 0x8000, 0x0016, 0x080c, 0xac5a, 0x0180, 0x2b08, 0x6112,
+	0x080c, 0xce15, 0x6023, 0x0001, 0x2900, 0x6016, 0x001e, 0x080c,
+	0xad4d, 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,
+	0xd6df, 0x001e, 0xa804, 0x9005, 0x0110, 0x2048, 0x0c38, 0x6014,
+	0x2048, 0xa867, 0x0103, 0x0010, 0x080c, 0xb693, 0x080c, 0xacb0,
+	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,
+	0x0005, 0x7060, 0xaa78, 0x9206, 0x0d78, 0x0c80, 0x0096, 0x00e6,
+	0x00f6, 0x2071, 0x1800, 0x9186, 0x0015, 0x1550, 0x7090, 0x9086,
+	0x0004, 0x1530, 0x6014, 0x2048, 0x2c78, 0x080c, 0x97f7, 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,
+	0x0508, 0xa87b, 0x0000, 0xa883, 0x0000, 0xa897, 0x4000, 0x0080,
+	0x080c, 0xc97a, 0x01b8, 0x6014, 0x2048, 0x080c, 0x54ca, 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,
+	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,
+	0x1580, 0x6310, 0x00c6, 0x2358, 0x2009, 0x0000, 0xa868, 0xd0f4,
+	0x1140, 0x080c, 0x6986, 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,
+	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, 0xd147, 0x080c, 0xe009, 0x1130, 0x080c, 0xdf02, 0x1118,
-	0x6007, 0x0010, 0x04e8, 0x0046, 0x6410, 0x2458, 0xbca0, 0x0046,
-	0x080c, 0x320f, 0x080c, 0xcf99, 0x004e, 0x0016, 0x9006, 0x2009,
-	0x1848, 0x210c, 0xd1a4, 0x0148, 0x2009, 0x0029, 0x080c, 0xe316,
-	0x6010, 0x2058, 0xb800, 0xc0e5, 0xb802, 0x001e, 0x004e, 0x6007,
-	0x0001, 0x00f0, 0x080c, 0xe199, 0x0140, 0x96b4, 0xff00, 0x8637,
-	0x9686, 0x0006, 0x0978, 0x0804, 0xd147, 0x6017, 0x1900, 0x6007,
-	0x0009, 0x0070, 0x080c, 0x3346, 0x1904, 0xd473, 0x080c, 0xe510,
-	0x1904, 0xd473, 0x080c, 0xd640, 0x1904, 0xd147, 0x6007, 0x0012,
-	0x6003, 0x0001, 0x080c, 0x9240, 0x080c, 0x96bd, 0x0005, 0x6007,
-	0x0001, 0x6003, 0x0001, 0x080c, 0x9240, 0x080c, 0x96bd, 0x0cb0,
-	0x6007, 0x0005, 0x0c68, 0x080c, 0xe510, 0x1904, 0xd473, 0x080c,
-	0x3346, 0x1904, 0xd473, 0x080c, 0xd640, 0x1904, 0xd147, 0x6007,
-	0x0020, 0x6003, 0x0001, 0x080c, 0x9240, 0x080c, 0x96bd, 0x0005,
-	0x080c, 0x3346, 0x1904, 0xd473, 0x6007, 0x0023, 0x6003, 0x0001,
-	0x080c, 0x9240, 0x080c, 0x96bd, 0x0005, 0x080c, 0xe510, 0x1904,
-	0xd473, 0x080c, 0x3346, 0x1904, 0xd473, 0x080c, 0xd640, 0x1904,
-	0xd147, 0x0016, 0x0026, 0x00e6, 0x2071, 0x0260, 0x7244, 0x9286,
-	0xffff, 0x0180, 0x2c08, 0x080c, 0xc853, 0x01b0, 0x2260, 0x7240,
-	0x6008, 0x9206, 0x1188, 0x6010, 0x9190, 0x0004, 0x2214, 0x9206,
-	0x01b8, 0x0050, 0x7240, 0x2c08, 0x9006, 0x080c, 0xe2e0, 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, 0xabf0, 0x2160, 0x6007, 0x0025, 0x6003, 0x0001, 0x080c,
-	0x9240, 0x080c, 0x96bd, 0x00ee, 0x002e, 0x001e, 0x0005, 0x2001,
-	0x0001, 0x080c, 0x6580, 0x0156, 0x0016, 0x0026, 0x0036, 0x20a9,
-	0x0004, 0x2019, 0x1805, 0x2011, 0x0276, 0x080c, 0xbbc1, 0x003e,
-	0x002e, 0x001e, 0x015e, 0x0120, 0x6007, 0x0031, 0x0804, 0xd260,
-	0x080c, 0xb832, 0x080c, 0x74ec, 0x1190, 0x0006, 0x0026, 0x0036,
-	0x080c, 0x7506, 0x1138, 0x080c, 0x77ef, 0x080c, 0x6044, 0x080c,
-	0x741d, 0x0010, 0x080c, 0x74c0, 0x003e, 0x002e, 0x000e, 0x0005,
-	0x080c, 0x3346, 0x1904, 0xd473, 0x080c, 0xd640, 0x1904, 0xd147,
-	0x6106, 0x080c, 0xd65c, 0x1120, 0x6007, 0x002b, 0x0804, 0xd260,
-	0x6007, 0x002c, 0x0804, 0xd260, 0x080c, 0xe510, 0x1904, 0xd473,
-	0x080c, 0x3346, 0x1904, 0xd473, 0x080c, 0xd640, 0x1904, 0xd147,
-	0x6106, 0x080c, 0xd661, 0x1120, 0x6007, 0x002e, 0x0804, 0xd260,
-	0x6007, 0x002f, 0x0804, 0xd260, 0x080c, 0x3346, 0x1904, 0xd473,
-	0x00e6, 0x00d6, 0x00c6, 0x6010, 0x2058, 0xb904, 0x9184, 0x00ff,
-	0x9086, 0x0006, 0x0158, 0x9184, 0xff00, 0x8007, 0x9086, 0x0006,
-	0x0128, 0x00ce, 0x00de, 0x00ee, 0x0804, 0xd267, 0x080c, 0x56f9,
-	0xd0e4, 0x0904, 0xd3be, 0x2071, 0x026c, 0x7010, 0x603a, 0x7014,
-	0x603e, 0x7108, 0x720c, 0x080c, 0x6a8a, 0x0140, 0x6010, 0x2058,
-	0xb810, 0x9106, 0x1118, 0xb814, 0x9206, 0x0510, 0x080c, 0x6a86,
-	0x15b8, 0x2069, 0x1800, 0x6880, 0x9206, 0x1590, 0x687c, 0x9106,
-	0x1578, 0x7210, 0x080c, 0xc853, 0x0590, 0x080c, 0xd52b, 0x0578,
-	0x080c, 0xe392, 0x0560, 0x622e, 0x6007, 0x0036, 0x6003, 0x0001,
-	0x2009, 0x8020, 0x080c, 0x9239, 0x00ce, 0x00de, 0x00ee, 0x0005,
-	0x7214, 0x9286, 0xffff, 0x0150, 0x080c, 0xc853, 0x01c0, 0x9280,
-	0x0002, 0x2004, 0x7110, 0x9106, 0x1190, 0x08e0, 0x7210, 0x2c08,
-	0x9085, 0x0001, 0x080c, 0xe2e0, 0x2c10, 0x2160, 0x0140, 0x0890,
-	0x6007, 0x0037, 0x602f, 0x0009, 0x6017, 0x1500, 0x08b8, 0x6007,
-	0x0037, 0x602f, 0x0003, 0x6017, 0x1700, 0x0880, 0x6007, 0x0012,
-	0x0868, 0x080c, 0x3346, 0x1904, 0xd473, 0x6010, 0x2058, 0xb804,
-	0x9084, 0xff00, 0x8007, 0x9086, 0x0006, 0x1904, 0xd267, 0x00e6,
-	0x00d6, 0x00c6, 0x080c, 0x56f9, 0xd0e4, 0x0904, 0xd436, 0x2069,
-	0x1800, 0x2071, 0x026c, 0x7008, 0x603a, 0x720c, 0x623e, 0x9286,
-	0xffff, 0x1150, 0x7208, 0x00c6, 0x2c08, 0x9085, 0x0001, 0x080c,
-	0xe2e0, 0x2c10, 0x00ce, 0x05e8, 0x080c, 0xc853, 0x05d0, 0x7108,
-	0x9280, 0x0002, 0x2004, 0x9106, 0x15a0, 0x00c6, 0x0026, 0x2260,
-	0x080c, 0xc446, 0x002e, 0x00ce, 0x7118, 0x918c, 0xff00, 0x810f,
-	0x9186, 0x0001, 0x0178, 0x9186, 0x0005, 0x0118, 0x9186, 0x0007,
-	0x1198, 0x9280, 0x0005, 0x2004, 0x9005, 0x0170, 0x080c, 0xd52b,
-	0x0904, 0xd3b7, 0x0056, 0x7510, 0x7614, 0x080c, 0xe3ab, 0x005e,
-	0x00ce, 0x00de, 0x00ee, 0x0005, 0x6007, 0x003b, 0x602f, 0x0009,
-	0x6017, 0x2a00, 0x6003, 0x0001, 0x2009, 0x8020, 0x080c, 0x9239,
-	0x0c78, 0x6007, 0x003b, 0x602f, 0x0003, 0x6017, 0x0300, 0x6003,
-	0x0001, 0x2009, 0x8020, 0x080c, 0x9239, 0x0c10, 0x6007, 0x003b,
-	0x602f, 0x000b, 0x6017, 0x0000, 0x0804, 0xd38e, 0x00e6, 0x0026,
-	0x080c, 0x6a4c, 0x0550, 0x080c, 0x69e8, 0x080c, 0xe582, 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,
-	0x6a8a, 0x0120, 0x2011, 0x1a08, 0x2013, 0x07d0, 0xd0ac, 0x1128,
-	0x080c, 0x2fe0, 0x0010, 0x080c, 0xe5b4, 0x002e, 0x00ee, 0x080c,
-	0xabf0, 0x0804, 0xd266, 0x080c, 0xabf0, 0x0005, 0x2600, 0x0002,
-	0xd48a, 0xd4bb, 0xd4cc, 0xd48a, 0xd48a, 0xd48c, 0xd4dd, 0xd48a,
-	0xd48a, 0xd48a, 0xd4a9, 0xd48a, 0xd48a, 0xd48a, 0xd4e8, 0xd4f5,
-	0xd526, 0xd48a, 0x080c, 0x0d7d, 0x080c, 0xe510, 0x1d20, 0x080c,
-	0x3346, 0x1d08, 0x080c, 0xd640, 0x1148, 0x7038, 0x6016, 0x6007,
-	0x0045, 0x6003, 0x0001, 0x080c, 0x9240, 0x0005, 0x080c, 0x320f,
-	0x080c, 0xcf99, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x9240,
-	0x0005, 0x080c, 0xe510, 0x1938, 0x080c, 0x3346, 0x1920, 0x080c,
-	0xd640, 0x1d60, 0x703c, 0x6016, 0x6007, 0x004a, 0x6003, 0x0001,
-	0x080c, 0x9240, 0x0005, 0x080c, 0x3346, 0x1904, 0xd473, 0x2009,
-	0x0041, 0x080c, 0xe5bd, 0x6007, 0x0047, 0x6003, 0x0001, 0x080c,
-	0x9240, 0x080c, 0x96bd, 0x0005, 0x080c, 0x3346, 0x1904, 0xd473,
-	0x2009, 0x0042, 0x080c, 0xe5bd, 0x6007, 0x0047, 0x6003, 0x0001,
-	0x080c, 0x9240, 0x080c, 0x96bd, 0x0005, 0x080c, 0x3346, 0x1904,
-	0xd473, 0x2009, 0x0046, 0x080c, 0xe5bd, 0x080c, 0xabf0, 0x0005,
-	0x080c, 0xd548, 0x0904, 0xd473, 0x6007, 0x004e, 0x6003, 0x0001,
-	0x080c, 0x9240, 0x080c, 0x96bd, 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, 0xbbd5, 0x009e, 0x0110, 0x6017, 0x0001, 0x6003,
-	0x0001, 0x080c, 0x9240, 0x080c, 0x96bd, 0x0005, 0x6007, 0x0050,
-	0x703c, 0x6016, 0x0ca0, 0x0016, 0x00e6, 0x2071, 0x0260, 0x00b6,
-	0x00c6, 0x2260, 0x6010, 0x2058, 0xb8d4, 0xd084, 0x0150, 0x7128,
-	0x6050, 0x9106, 0x1120, 0x712c, 0x604c, 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, 0x21b2, 0x2099,
-	0x026c, 0x2001, 0x0014, 0x3518, 0x9312, 0x1218, 0x23a8, 0x4003,
-	0x00f8, 0x20a8, 0x4003, 0x22a8, 0x8108, 0x080c, 0x21b2, 0x2099,
-	0x0260, 0x0ca8, 0x080c, 0x21b2, 0x2061, 0x199f, 0x6004, 0x2098,
-	0x6008, 0x3518, 0x9312, 0x1218, 0x23a8, 0x4003, 0x0048, 0x20a8,
-	0x4003, 0x22a8, 0x8108, 0x080c, 0x21b2, 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, 0x21ca, 0x20a1, 0x024c, 0x2001, 0x0014, 0x3518, 0x9312,
-	0x1218, 0x23a8, 0x4003, 0x0418, 0x20a8, 0x4003, 0x82ff, 0x01f8,
-	0x22a8, 0x8108, 0x080c, 0x21ca, 0x20a1, 0x0240, 0x0c98, 0x080c,
-	0x21ca, 0x2061, 0x19a2, 0x6004, 0x20a0, 0x6008, 0x3518, 0x9312,
-	0x1218, 0x23a8, 0x4003, 0x0058, 0x20a8, 0x4003, 0x82ff, 0x0138,
-	0x22a8, 0x8108, 0x080c, 0x21ca, 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, 0xd6d6, 0x00de,
-	0x0005, 0x00d6, 0x080c, 0xd6e3, 0x1520, 0x680c, 0x908c, 0xff00,
-	0x6820, 0x9084, 0x00ff, 0x9115, 0x6216, 0x6824, 0x602e, 0xd1e4,
-	0x0130, 0x9006, 0x080c, 0xe6dd, 0x2009, 0x0001, 0x0078, 0xd1ec,
-	0x0180, 0x6920, 0x918c, 0x00ff, 0x6824, 0x080c, 0x2630, 0x1148,
-	0x2001, 0x0001, 0x080c, 0xe6dd, 0x2110, 0x900e, 0x080c, 0x325e,
-	0x0018, 0x9085, 0x0001, 0x0008, 0x9006, 0x00de, 0x0005, 0x00b6,
-	0x00c6, 0x080c, 0xac60, 0x0598, 0x0016, 0x0026, 0x00c6, 0x2011,
-	0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x2630, 0x1568, 0x080c,
-	0x65e3, 0x1550, 0xbe12, 0xbd16, 0x00ce, 0x002e, 0x001e, 0x2b00,
-	0x6012, 0x080c, 0xe510, 0x11c8, 0x080c, 0x3346, 0x11b0, 0x080c,
-	0xd640, 0x0500, 0x2001, 0x0007, 0x080c, 0x6594, 0x2001, 0x0007,
-	0x080c, 0x65c0, 0x6017, 0x0000, 0x6023, 0x0001, 0x6007, 0x0001,
-	0x6003, 0x0001, 0x080c, 0x9240, 0x0010, 0x080c, 0xabf0, 0x9085,
-	0x0001, 0x00ce, 0x00be, 0x0005, 0x080c, 0xabf0, 0x00ce, 0x002e,
-	0x001e, 0x0ca8, 0x080c, 0xabf0, 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, 0xd825, 0x0092, 0x91b6, 0x0027,
-	0x0120, 0x91b6, 0x0014, 0x190c, 0x0d7d, 0x2001, 0x0007, 0x080c,
-	0x65c0, 0x080c, 0x95ff, 0x080c, 0xac2b, 0x080c, 0x96bd, 0x0005,
-	0xd760, 0xd762, 0xd760, 0xd760, 0xd760, 0xd762, 0xd76f, 0xd822,
-	0xd7bf, 0xd822, 0xd7d3, 0xd822, 0xd76f, 0xd822, 0xd81a, 0xd822,
-	0xd81a, 0xd822, 0xd822, 0xd760, 0xd760, 0xd760, 0xd760, 0xd760,
-	0xd760, 0xd760, 0xd760, 0xd760, 0xd760, 0xd760, 0xd762, 0xd760,
-	0xd822, 0xd760, 0xd760, 0xd822, 0xd760, 0xd81f, 0xd822, 0xd760,
-	0xd760, 0xd760, 0xd760, 0xd822, 0xd822, 0xd760, 0xd822, 0xd822,
-	0xd760, 0xd76a, 0xd760, 0xd760, 0xd760, 0xd760, 0xd81e, 0xd822,
-	0xd760, 0xd760, 0xd822, 0xd822, 0xd760, 0xd760, 0xd760, 0xd760,
-	0x080c, 0x0d7d, 0x080c, 0xcf9c, 0x6003, 0x0002, 0x080c, 0x96bd,
-	0x0804, 0xd824, 0x9006, 0x080c, 0x6580, 0x0804, 0xd822, 0x080c,
-	0x6a86, 0x1904, 0xd822, 0x9006, 0x080c, 0x6580, 0x6010, 0x2058,
-	0xb810, 0x9086, 0x00ff, 0x1140, 0x00f6, 0x2079, 0x1800, 0x78a8,
-	0x8000, 0x78aa, 0x00fe, 0x0428, 0x6010, 0x2058, 0xb884, 0x9005,
-	0x1178, 0x080c, 0xcf84, 0x1904, 0xd822, 0x0036, 0x0046, 0xbba0,
-	0x2021, 0x0007, 0x080c, 0x4ce0, 0x004e, 0x003e, 0x0804, 0xd822,
-	0x080c, 0x3377, 0x1904, 0xd822, 0x2001, 0x1800, 0x2004, 0x9086,
-	0x0002, 0x1138, 0x00f6, 0x2079, 0x1800, 0x78a8, 0x8000, 0x78aa,
-	0x00fe, 0x2001, 0x0002, 0x080c, 0x6594, 0x6023, 0x0001, 0x6003,
-	0x0001, 0x6007, 0x0002, 0x080c, 0x9240, 0x080c, 0x96bd, 0x6110,
-	0x2158, 0x2009, 0x0001, 0x080c, 0x865f, 0x0804, 0xd824, 0x6610,
-	0x2658, 0xbe04, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0006, 0x0904,
-	0xd822, 0x9686, 0x0004, 0x0904, 0xd822, 0x080c, 0x8ee5, 0x2001,
-	0x0004, 0x0804, 0xd820, 0x2001, 0x1800, 0x2004, 0x9086, 0x0003,
-	0x1158, 0x0036, 0x0046, 0x6010, 0x2058, 0xbba0, 0x2021, 0x0006,
-	0x080c, 0x4ce0, 0x004e, 0x003e, 0x2001, 0x0006, 0x080c, 0xd83e,
-	0x6610, 0x2658, 0xbe04, 0x0066, 0x96b4, 0xff00, 0x8637, 0x9686,
-	0x0006, 0x006e, 0x0168, 0x2001, 0x0006, 0x080c, 0x65c0, 0x9284,
-	0x00ff, 0x908e, 0x0007, 0x1120, 0x2001, 0x0006, 0x080c, 0x6594,
-	0x080c, 0x6a86, 0x11f8, 0x2001, 0x1837, 0x2004, 0xd0a4, 0x01d0,
-	0xbe04, 0x96b4, 0x00ff, 0x9686, 0x0006, 0x01a0, 0x00f6, 0x2079,
-	0x1800, 0x78a8, 0x8000, 0x78aa, 0x00fe, 0x0804, 0xd7a9, 0x2001,
-	0x0004, 0x0030, 0x2001, 0x0006, 0x0409, 0x0020, 0x0018, 0x0010,
-	0x080c, 0x65c0, 0x080c, 0xabf0, 0x0005, 0x2600, 0x0002, 0xd839,
-	0xd839, 0xd839, 0xd839, 0xd839, 0xd83b, 0xd839, 0xd83b, 0xd839,
-	0xd839, 0xd83b, 0xd839, 0xd839, 0xd839, 0xd83b, 0xd83b, 0xd83b,
-	0xd83b, 0x080c, 0x0d7d, 0x080c, 0xabf0, 0x0005, 0x0016, 0x00b6,
-	0x00d6, 0x6110, 0x2158, 0xb900, 0xd184, 0x0138, 0x080c, 0x6594,
-	0x9006, 0x080c, 0x6580, 0x080c, 0x323e, 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, 0xb6af, 0xb6af,
-	0xb6af, 0xb6af, 0xd8d3, 0xb6af, 0xd8bd, 0xd87e, 0xb6af, 0xb6af,
-	0xb6af, 0xb6af, 0xb6af, 0xb6af, 0xb6af, 0xb6af, 0xd8d3, 0xb6af,
-	0xd8bd, 0xd8c4, 0xb6af, 0xb6af, 0xb6af, 0xb6af, 0x00f6, 0x080c,
-	0x6a86, 0x11d8, 0x080c, 0xcf84, 0x11c0, 0x6010, 0x905d, 0x01a8,
-	0xb884, 0x9005, 0x0190, 0x9006, 0x080c, 0x6580, 0x2001, 0x0002,
-	0x080c, 0x6594, 0x6023, 0x0001, 0x6003, 0x0001, 0x6007, 0x0002,
-	0x080c, 0x9240, 0x080c, 0x96bd, 0x00f0, 0x2011, 0x0263, 0x2204,
-	0x8211, 0x220c, 0x080c, 0x2630, 0x11b0, 0x080c, 0x6644, 0x0118,
-	0x080c, 0xabf0, 0x0080, 0xb810, 0x0006, 0xb814, 0x0006, 0xb884,
-	0x0006, 0x080c, 0x605e, 0x000e, 0xb886, 0x000e, 0xb816, 0x000e,
-	0xb812, 0x080c, 0xabf0, 0x00fe, 0x0005, 0x6604, 0x96b6, 0x001e,
-	0x1110, 0x080c, 0xabf0, 0x0005, 0x080c, 0xba3a, 0x1148, 0x6003,
-	0x0001, 0x6007, 0x0001, 0x080c, 0x9240, 0x080c, 0x96bd, 0x0010,
-	0x080c, 0xabf0, 0x0005, 0x0804, 0xabf0, 0x6004, 0x908a, 0x0053,
-	0x1a0c, 0x0d7d, 0x080c, 0x95ff, 0x080c, 0xac2b, 0x0005, 0x9182,
-	0x0040, 0x0002, 0xd8f6, 0xd8f6, 0xd8f6, 0xd8f6, 0xd8f8, 0xd8f6,
-	0xd8f6, 0xd8f6, 0xd8f6, 0xd8f6, 0xd8f6, 0xd8f6, 0xd8f6, 0xd8f6,
-	0xd8f6, 0xd8f6, 0xd8f6, 0xd8f6, 0xd8f6, 0xd8f6, 0x080c, 0x0d7d,
-	0x0096, 0x00b6, 0x00d6, 0x00e6, 0x00f6, 0x0046, 0x0026, 0x6210,
-	0x2258, 0xb8bc, 0x9005, 0x11b0, 0x6007, 0x0044, 0x2071, 0x0260,
-	0x7444, 0x94a4, 0xff00, 0x0904, 0xd95f, 0x080c, 0xe6d1, 0x1170,
-	0x9486, 0x2000, 0x1158, 0x2009, 0x0001, 0x2011, 0x0200, 0x080c,
-	0x8902, 0x0020, 0x9026, 0x080c, 0xe555, 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, 0x6d9f, 0x001e, 0x080c, 0xe6d1,
-	0x1904, 0xd9bf, 0x9486, 0x2000, 0x1130, 0x2019, 0x0017, 0x080c,
-	0xe286, 0x0804, 0xd9bf, 0x9486, 0x0200, 0x1120, 0x080c, 0xe216,
-	0x0804, 0xd9bf, 0x9486, 0x0400, 0x0120, 0x9486, 0x1000, 0x1904,
-	0xd9bf, 0x2019, 0x0002, 0x080c, 0xe235, 0x0804, 0xd9bf, 0x2069,
-	0x1a6e, 0x6a00, 0xd284, 0x0904, 0xda29, 0x9284, 0x0300, 0x1904,
-	0xda22, 0x6804, 0x9005, 0x0904, 0xda0a, 0x2d78, 0x6003, 0x0007,
-	0x080c, 0x1060, 0x0904, 0xd9cb, 0x7800, 0xd08c, 0x1118, 0x7804,
-	0x8001, 0x7806, 0x6017, 0x0000, 0x2001, 0x180f, 0x2004, 0xd084,
-	0x1904, 0xda2d, 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, 0xd9c7,
-	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, 0x6da2, 0x002e,
-	0x004e, 0x00fe, 0x00ee, 0x00de, 0x00be, 0x009e, 0x0005, 0x0000,
-	0x0080, 0x0040, 0x0000, 0x2001, 0x1810, 0x2004, 0xd084, 0x0120,
-	0x080c, 0x1047, 0x1904, 0xd974, 0x6017, 0xf100, 0x6003, 0x0001,
-	0x6007, 0x0041, 0x2009, 0xa022, 0x080c, 0x9239, 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,
-	0x9239, 0x0828, 0x6868, 0x602e, 0x686c, 0x6032, 0x6017, 0xf200,
-	0x6003, 0x0001, 0x6007, 0x0041, 0x2009, 0xa022, 0x080c, 0x9239,
-	0x0804, 0xd9bf, 0x2001, 0x180e, 0x2004, 0xd0ec, 0x0120, 0x2011,
-	0x8049, 0x080c, 0x4b29, 0x6017, 0xf300, 0x0010, 0x6017, 0xf100,
-	0x6003, 0x0001, 0x6007, 0x0041, 0x2009, 0xa022, 0x080c, 0x9239,
-	0x0804, 0xd9bf, 0x6017, 0xf500, 0x0c98, 0x6017, 0xf600, 0x0804,
-	0xd9df, 0x6017, 0xf200, 0x0804, 0xd9df, 0xa867, 0x0146, 0xa86b,
-	0x0000, 0x6008, 0xa886, 0x2c00, 0xa87a, 0x7044, 0x9084, 0x0003,
-	0x9080, 0xd9c7, 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, 0xdaa9, 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, 0xd9cb, 0x2548, 0x8847, 0x9885, 0x0046,
-	0xa866, 0x2009, 0x0205, 0x200b, 0x0000, 0x080c, 0xe2b9, 0x0804,
-	0xd9bf, 0x8010, 0x0004, 0x801a, 0x0006, 0x8018, 0x0008, 0x8016,
-	0x000a, 0x8014, 0x9186, 0x0013, 0x1160, 0x6004, 0x908a, 0x0057,
-	0x1a0c, 0x0d7d, 0x9082, 0x0040, 0x0a0c, 0x0d7d, 0x2008, 0x0804,
-	0xdb35, 0x9186, 0x0051, 0x0108, 0x0040, 0x080c, 0xaaab, 0x01e8,
-	0x9086, 0x0002, 0x0904, 0xdb7d, 0x00c0, 0x9186, 0x0027, 0x0180,
-	0x9186, 0x0048, 0x0128, 0x9186, 0x0014, 0x0150, 0x190c, 0x0d7d,
-	0x080c, 0xaaab, 0x0150, 0x9086, 0x0004, 0x0904, 0xdc1c, 0x0028,
-	0x6004, 0x9082, 0x0040, 0x2008, 0x001a, 0x080c, 0xacaa, 0x0005,
-	0xdafc, 0xdafe, 0xdafe, 0xdb25, 0xdafc, 0xdafc, 0xdafc, 0xdafc,
-	0xdafc, 0xdafc, 0xdafc, 0xdafc, 0xdafc, 0xdafc, 0xdafc, 0xdafc,
-	0xdafc, 0xdafc, 0xdafc, 0xdafc, 0x080c, 0x0d7d, 0x080c, 0x95ff,
-	0x080c, 0x96bd, 0x0036, 0x0096, 0x6014, 0x904d, 0x01d8, 0x080c,
-	0xc865, 0x01c0, 0x6003, 0x0002, 0x6010, 0x00b6, 0x2058, 0xb800,
-	0x00be, 0xd0bc, 0x1178, 0x2019, 0x0004, 0x080c, 0xe2b9, 0x6017,
-	0x0000, 0x6018, 0x9005, 0x1120, 0x2001, 0x1986, 0x2004, 0x601a,
-	0x6003, 0x0007, 0x009e, 0x003e, 0x0005, 0x0096, 0x080c, 0x95ff,
-	0x080c, 0x96bd, 0x080c, 0xc865, 0x0120, 0x6014, 0x2048, 0x080c,
-	0x1079, 0x080c, 0xac2b, 0x009e, 0x0005, 0x0002, 0xdb4a, 0xdb5f,
-	0xdb4c, 0xdb74, 0xdb4a, 0xdb4a, 0xdb4a, 0xdb4a, 0xdb4a, 0xdb4a,
-	0xdb4a, 0xdb4a, 0xdb4a, 0xdb4a, 0xdb4a, 0xdb4a, 0xdb4a, 0xdb4a,
-	0xdb4a, 0xdb4a, 0x080c, 0x0d7d, 0x0096, 0x6014, 0x2048, 0xa87c,
-	0xd0b4, 0x0138, 0x6003, 0x0007, 0x2009, 0x0043, 0x080c, 0xac8d,
-	0x0010, 0x6003, 0x0004, 0x080c, 0x96bd, 0x009e, 0x0005, 0x080c,
-	0xc865, 0x0138, 0x6114, 0x0096, 0x2148, 0xa97c, 0x009e, 0xd1ec,
-	0x1138, 0x080c, 0x88d7, 0x080c, 0xabf0, 0x080c, 0x96bd, 0x0005,
-	0x080c, 0xe519, 0x0db0, 0x0cc8, 0x6003, 0x0001, 0x6007, 0x0041,
-	0x2009, 0xa022, 0x080c, 0x9239, 0x0005, 0x9182, 0x0040, 0x0002,
-	0xdb94, 0xdb96, 0xdb94, 0xdb94, 0xdb94, 0xdb94, 0xdb94, 0xdb94,
-	0xdb94, 0xdb94, 0xdb94, 0xdb94, 0xdb94, 0xdb94, 0xdb94, 0xdb94,
-	0xdb94, 0xdb97, 0xdb94, 0xdb94, 0x080c, 0x0d7d, 0x0005, 0x00d6,
-	0x080c, 0x88d7, 0x00de, 0x080c, 0xe571, 0x080c, 0xabf0, 0x0005,
-	0x9182, 0x0040, 0x0002, 0xdbb7, 0xdbb7, 0xdbb7, 0xdbb7, 0xdbb7,
-	0xdbb7, 0xdbb7, 0xdbb7, 0xdbb7, 0xdbb9, 0xdbe4, 0xdbb7, 0xdbb7,
-	0xdbb7, 0xdbb7, 0xdbe4, 0xdbb7, 0xdbb7, 0xdbb7, 0xdbb7, 0x080c,
-	0x0d7d, 0x6014, 0x0096, 0x2048, 0xa87c, 0xd0fc, 0x0168, 0x908c,
-	0x0003, 0x918e, 0x0002, 0x0180, 0x6144, 0xd1e4, 0x1168, 0x2009,
-	0x0041, 0x009e, 0x0804, 0xdca4, 0x6003, 0x0007, 0x601b, 0x0000,
-	0x080c, 0x88d7, 0x009e, 0x0005, 0x6014, 0x2048, 0xa97c, 0xd1ec,
-	0x1130, 0x080c, 0x88d7, 0x080c, 0xabf0, 0x009e, 0x0005, 0x080c,
-	0xe519, 0x0db8, 0x009e, 0x0005, 0x2001, 0x180c, 0x200c, 0xc1d4,
-	0x2102, 0x0036, 0x080c, 0x965a, 0x080c, 0x96bd, 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, 0xe2b9, 0x6018, 0x9005, 0x1128,
-	0x2001, 0x1986, 0x2004, 0x8003, 0x601a, 0x6017, 0x0000, 0x6003,
-	0x0007, 0x009e, 0x003e, 0x0005, 0x9182, 0x0040, 0x0002, 0xdc33,
-	0xdc33, 0xdc33, 0xdc33, 0xdc33, 0xdc33, 0xdc33, 0xdc33, 0xdc35,
-	0xdc33, 0xdc33, 0xdc33, 0xdc33, 0xdc33, 0xdc33, 0xdc33, 0xdc33,
-	0xdc33, 0xdc33, 0xdc80, 0x080c, 0x0d7d, 0x6014, 0x0096, 0x2048,
-	0xa834, 0xaa38, 0x6110, 0x00b6, 0x2158, 0xb900, 0x00be, 0xd1bc,
-	0x1190, 0x920d, 0x1518, 0xa87c, 0xd0fc, 0x0128, 0x2009, 0x0041,
-	0x009e, 0x0804, 0xdca4, 0x6003, 0x0007, 0x601b, 0x0000, 0x080c,
-	0x88d7, 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, 0x88d9, 0x009e, 0x0005, 0x6003, 0x0002, 0x009e, 0x0005,
-	0x6024, 0xd0f4, 0x0128, 0x080c, 0x168a, 0x1904, 0xdc35, 0x0005,
-	0x6014, 0x0096, 0x2048, 0xa834, 0xa938, 0x009e, 0x9105, 0x1120,
-	0x080c, 0x168a, 0x1904, 0xdc35, 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, 0xdcc8, 0xdcd4, 0xdce0, 0xdcec,
-	0xdcc8, 0xdcc8, 0xdcc8, 0xdcc8, 0xdccf, 0xdcca, 0xdcca, 0xdcc8,
-	0xdcc8, 0xdcc8, 0xdcc8, 0xdcca, 0xdcc8, 0xdcca, 0xdcc8, 0xdccf,
-	0x080c, 0x0d7d, 0x6024, 0xd0dc, 0x090c, 0x0d7d, 0x0005, 0x6014,
-	0x9005, 0x190c, 0x0d7d, 0x0005, 0x6003, 0x0001, 0x6106, 0x0126,
-	0x2091, 0x8000, 0x2009, 0xa022, 0x080c, 0x921b, 0x012e, 0x0005,
-	0x6003, 0x0004, 0x6106, 0x0126, 0x2091, 0x8000, 0x2009, 0xa001,
-	0x080c, 0x9239, 0x012e, 0x0005, 0x6003, 0x0003, 0x6106, 0x080c,
-	0x1c28, 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,
-	0x9280, 0x012e, 0x0005, 0x6144, 0x918d, 0xa032, 0x0cb8, 0x0126,
-	0x2091, 0x8000, 0x0036, 0x0096, 0x9182, 0x0040, 0x0023, 0x009e,
-	0x003e, 0x012e, 0x0005, 0xdd37, 0xdd39, 0xdd4e, 0xdd68, 0xdd37,
-	0xdd37, 0xdd37, 0xdd37, 0xdd37, 0xdd37, 0xdd37, 0xdd37, 0xdd37,
-	0xdd37, 0xdd37, 0xdd37, 0xdd37, 0xdd37, 0xdd37, 0xdd37, 0x080c,
-	0x0d7d, 0x6014, 0x2048, 0xa87c, 0xd0fc, 0x0510, 0x909c, 0x0003,
-	0x939e, 0x0003, 0x01e8, 0x6003, 0x0001, 0x6106, 0x0126, 0x2091,
-	0x8000, 0x2009, 0xa022, 0x080c, 0x9239, 0x0470, 0x6014, 0x2048,
-	0xa87c, 0xd0fc, 0x0168, 0x909c, 0x0003, 0x939e, 0x0003, 0x0140,
-	0x6003, 0x0001, 0x6106, 0x2009, 0xa001, 0x080c, 0x9239, 0x00e0,
-	0x901e, 0x6316, 0x631a, 0x2019, 0x0004, 0x080c, 0xe2b9, 0x00a0,
-	0x6014, 0x2048, 0xa87c, 0xd0fc, 0x0d98, 0x909c, 0x0003, 0x939e,
-	0x0003, 0x0d70, 0x6003, 0x0003, 0x6106, 0x080c, 0x1c28, 0x6144,
-	0x918d, 0xa035, 0x080c, 0x9280, 0x0005, 0x080c, 0x95ff, 0x6114,
-	0x81ff, 0x0158, 0x0096, 0x2148, 0x080c, 0xe66e, 0x0036, 0x2019,
-	0x0029, 0x080c, 0xe2b9, 0x003e, 0x009e, 0x080c, 0xac2b, 0x080c,
-	0x96bd, 0x0005, 0x080c, 0x965a, 0x6114, 0x81ff, 0x0158, 0x0096,
-	0x2148, 0x080c, 0xe66e, 0x0036, 0x2019, 0x0029, 0x080c, 0xe2b9,
-	0x003e, 0x009e, 0x080c, 0xac2b, 0x0005, 0x9182, 0x0085, 0x0002,
-	0xddb7, 0xddb5, 0xddb5, 0xddc3, 0xddb5, 0xddb5, 0xddb5, 0xddb5,
-	0xddb5, 0xddb5, 0xddb5, 0xddb5, 0xddb5, 0x080c, 0x0d7d, 0x6003,
-	0x000b, 0x6106, 0x0126, 0x2091, 0x8000, 0x2009, 0x8020, 0x080c,
-	0x9239, 0x012e, 0x0005, 0x0026, 0x00e6, 0x080c, 0xe510, 0x0118,
-	0x080c, 0xabf0, 0x0440, 0x2071, 0x0260, 0x7224, 0x6216, 0x2001,
-	0x180e, 0x2004, 0xd0e4, 0x0150, 0x6010, 0x00b6, 0x2058, 0xbca0,
-	0x00be, 0x2c00, 0x2011, 0x014e, 0x080c, 0xaf1b, 0x7220, 0x080c,
-	0xe14f, 0x0118, 0x6007, 0x0086, 0x0040, 0x6007, 0x0087, 0x7224,
-	0x9296, 0xffff, 0x1110, 0x6007, 0x0086, 0x6003, 0x0001, 0x2009,
-	0x8020, 0x080c, 0x9239, 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, 0xacaa, 0x0050, 0x2001, 0x0007,
-	0x080c, 0x65c0, 0x080c, 0x95ff, 0x080c, 0xac2b, 0x080c, 0x96bd,
-	0x0005, 0xde26, 0xde28, 0xde28, 0xde26, 0xde26, 0xde26, 0xde26,
-	0xde26, 0xde26, 0xde26, 0xde26, 0xde26, 0xde26, 0x080c, 0x0d7d,
-	0x080c, 0xac2b, 0x080c, 0x96bd, 0x0005, 0x9182, 0x0085, 0x0a0c,
-	0x0d7d, 0x9182, 0x0092, 0x1a0c, 0x0d7d, 0x9182, 0x0085, 0x0002,
-	0xde45, 0xde45, 0xde45, 0xde47, 0xde45, 0xde45, 0xde45, 0xde45,
-	0xde45, 0xde45, 0xde45, 0xde45, 0xde45, 0x080c, 0x0d7d, 0x0005,
-	0x9186, 0x0013, 0x0148, 0x9186, 0x0014, 0x0130, 0x9186, 0x0027,
-	0x0118, 0x080c, 0xacaa, 0x0020, 0x080c, 0x95ff, 0x080c, 0xac2b,
-	0x0005, 0x0036, 0x080c, 0xe571, 0x604b, 0x0000, 0x2019, 0x000b,
-	0x0031, 0x6023, 0x0006, 0x6003, 0x0007, 0x003e, 0x0005, 0x0126,
-	0x0036, 0x2091, 0x8000, 0x2001, 0x0382, 0x2004, 0x9084, 0x0007,
-	0x0006, 0x9086, 0x0003, 0x0110, 0x080c, 0xa899, 0x0086, 0x2c40,
-	0x0096, 0x904e, 0x080c, 0xa207, 0x009e, 0x008e, 0x1558, 0x0076,
-	0x2c38, 0x080c, 0xa2b2, 0x007e, 0x1528, 0x6000, 0x9086, 0x0000,
-	0x0508, 0x6020, 0x9086, 0x0007, 0x01e8, 0x0096, 0x601c, 0xd084,
-	0x0140, 0x080c, 0xe571, 0x080c, 0xcf9c, 0x080c, 0x1a94, 0x6023,
-	0x0007, 0x6014, 0x2048, 0x080c, 0xc865, 0x0110, 0x080c, 0xe2b9,
-	0x009e, 0x9006, 0x6046, 0x6016, 0x080c, 0xe571, 0x6023, 0x0007,
-	0x080c, 0xcf9c, 0x000e, 0x9086, 0x0003, 0x0110, 0x080c, 0xa8b5,
-	0x003e, 0x012e, 0x0005, 0x00f6, 0x00c6, 0x00b6, 0x0036, 0x0156,
-	0x2079, 0x0260, 0x7938, 0x783c, 0x080c, 0x2630, 0x15e8, 0x0016,
-	0x00c6, 0x080c, 0x6644, 0x15b0, 0x001e, 0x00c6, 0x2160, 0x080c,
-	0xcf99, 0x00ce, 0x002e, 0x0026, 0x0016, 0x080c, 0xa899, 0x2019,
-	0x0029, 0x080c, 0xa37f, 0x080c, 0x93c6, 0x0076, 0x903e, 0x080c,
-	0x928f, 0x007e, 0x001e, 0x0076, 0x903e, 0x080c, 0xe038, 0x007e,
-	0x080c, 0xa8b5, 0x0026, 0xba04, 0x9294, 0xff00, 0x8217, 0x9286,
-	0x0006, 0x0118, 0x9286, 0x0004, 0x1118, 0xbaa0, 0x080c, 0x32da,
-	0x002e, 0xbc84, 0x001e, 0x080c, 0x605e, 0xbe12, 0xbd16, 0xbc86,
-	0x9006, 0x0010, 0x00ce, 0x001e, 0x015e, 0x003e, 0x00be, 0x00ce,
-	0x00fe, 0x0005, 0x00c6, 0x00d6, 0x00b6, 0x0016, 0x2009, 0x1824,
-	0x2104, 0x9086, 0x0074, 0x1904, 0xdf5b, 0x2069, 0x0260, 0x6944,
-	0x9182, 0x0100, 0x06e0, 0x6940, 0x9184, 0x8000, 0x0904, 0xdf58,
-	0x2001, 0x197b, 0x2004, 0x9005, 0x1140, 0x6010, 0x2058, 0xb884,
-	0x9005, 0x0118, 0x9184, 0x0800, 0x0598, 0x6948, 0x918a, 0x0001,
-	0x0648, 0x080c, 0xe6d6, 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,
-	0x6653, 0x0804, 0xdfc7, 0x2011, 0x0276, 0x20a9, 0x0004, 0x0096,
-	0x2b48, 0x2019, 0x000a, 0x080c, 0xbbd5, 0x009e, 0x15c8, 0x2011,
-	0x027a, 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x0006, 0x080c,
-	0xbbd5, 0x009e, 0x1568, 0x0046, 0x0016, 0xbaa0, 0x2220, 0x9006,
-	0x2009, 0x1848, 0x210c, 0xd1a4, 0x0138, 0x2009, 0x0029, 0x080c,
-	0xe316, 0xb800, 0xc0e5, 0xb802, 0x080c, 0xa899, 0x2019, 0x0029,
-	0x080c, 0x93c6, 0x0076, 0x2039, 0x0000, 0x080c, 0x928f, 0x2c08,
-	0x080c, 0xe038, 0x007e, 0x080c, 0xa8b5, 0x2001, 0x0007, 0x080c,
-	0x65c0, 0x2001, 0x0007, 0x080c, 0x6594, 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, 0x2630, 0x11d0,
-	0x080c, 0x6644, 0x11b8, 0x2011, 0x0270, 0x20a9, 0x0004, 0x0096,
-	0x2b48, 0x2019, 0x000a, 0x080c, 0xbbd5, 0x009e, 0x1158, 0x2011,
-	0x0274, 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x0006, 0x080c,
-	0xbbd5, 0x009e, 0x015e, 0x003e, 0x002e, 0x001e, 0x00fe, 0x00be,
-	0x0005, 0x00b6, 0x0006, 0x0016, 0x0026, 0x0036, 0x0156, 0x2011,
-	0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x2630, 0x11d0, 0x080c,
-	0x6644, 0x11b8, 0x2011, 0x0276, 0x20a9, 0x0004, 0x0096, 0x2b48,
-	0x2019, 0x000a, 0x080c, 0xbbd5, 0x009e, 0x1158, 0x2011, 0x027a,
-	0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x0006, 0x080c, 0xbbd5,
-	0x009e, 0x015e, 0x003e, 0x002e, 0x001e, 0x000e, 0x00be, 0x0005,
-	0x00e6, 0x00c6, 0x0086, 0x0076, 0x0066, 0x0056, 0x0046, 0x0026,
-	0x0126, 0x2091, 0x8000, 0x080c, 0xa8f7, 0x0106, 0x190c, 0xa899,
-	0x2740, 0x2029, 0x19f2, 0x252c, 0x2021, 0x19f9, 0x2424, 0x2061,
-	0x1ddc, 0x2071, 0x1800, 0x7654, 0x7074, 0x81ff, 0x0150, 0x0006,
-	0x9186, 0x1b31, 0x000e, 0x0128, 0x8001, 0x9602, 0x1a04, 0xe0dd,
-	0x0018, 0x9606, 0x0904, 0xe0dd, 0x080c, 0x8ba9, 0x0904, 0xe0d4,
-	0x2100, 0x9c06, 0x0904, 0xe0d4, 0x080c, 0xe357, 0x1904, 0xe0d4,
-	0x080c, 0xe6f3, 0x0904, 0xe0d4, 0x080c, 0xe347, 0x0904, 0xe0d4,
-	0x6720, 0x9786, 0x0001, 0x1148, 0x080c, 0x3377, 0x0904, 0xe11f,
-	0x6004, 0x9086, 0x0000, 0x1904, 0xe11f, 0x9786, 0x0004, 0x0904,
-	0xe11f, 0x9786, 0x0007, 0x0904, 0xe0d4, 0x2500, 0x9c06, 0x0904,
-	0xe0d4, 0x2400, 0x9c06, 0x0904, 0xe0d4, 0x88ff, 0x0118, 0x605c,
-	0x9906, 0x15d0, 0x0096, 0x6043, 0xffff, 0x6000, 0x9086, 0x0004,
-	0x1120, 0x0016, 0x080c, 0x1a94, 0x001e, 0x9786, 0x000a, 0x0148,
-	0x080c, 0xca7a, 0x1130, 0x080c, 0xb5c6, 0x009e, 0x080c, 0xac2b,
-	0x0418, 0x6014, 0x2048, 0x080c, 0xc865, 0x01d8, 0x9786, 0x0003,
-	0x1588, 0xa867, 0x0103, 0xa87c, 0xd0cc, 0x0130, 0x0096, 0xa878,
-	0x2048, 0x080c, 0x0ff9, 0x009e, 0xab7a, 0xa877, 0x0000, 0x080c,
-	0xe66e, 0x0016, 0x080c, 0xcb68, 0x080c, 0x6d93, 0x001e, 0x080c,
-	0xca54, 0x009e, 0x080c, 0xac2b, 0x9ce0, 0x001c, 0x2001, 0x181a,
-	0x2004, 0x9c02, 0x1210, 0x0804, 0xe051, 0x010e, 0x190c, 0xa8b5,
-	0x012e, 0x002e, 0x004e, 0x005e, 0x006e, 0x007e, 0x008e, 0x00ce,
-	0x00ee, 0x0005, 0x9786, 0x0006, 0x1150, 0x9386, 0x0005, 0x0128,
-	0x080c, 0xe66e, 0x080c, 0xe2b9, 0x08e0, 0x009e, 0x08e8, 0x9786,
-	0x0009, 0x11f8, 0x6000, 0x9086, 0x0004, 0x01c0, 0x6000, 0x9086,
-	0x0003, 0x11a0, 0x080c, 0x965a, 0x0096, 0x6114, 0x2148, 0x080c,
-	0xc865, 0x0118, 0x6010, 0x080c, 0x6d9f, 0x009e, 0x00c6, 0x080c,
-	0xabf0, 0x00ce, 0x0036, 0x080c, 0x96bd, 0x003e, 0x009e, 0x0804,
-	0xe0d4, 0x9786, 0x000a, 0x0904, 0xe0bb, 0x0804, 0xe0b9, 0x81ff,
-	0x0904, 0xe0d4, 0x9180, 0x0001, 0x2004, 0x9086, 0x0018, 0x0138,
-	0x9180, 0x0001, 0x2004, 0x9086, 0x002d, 0x1904, 0xe0d4, 0x6000,
-	0x9086, 0x0002, 0x1904, 0xe0d4, 0x080c, 0xca69, 0x0138, 0x080c,
-	0xca7a, 0x1904, 0xe0d4, 0x080c, 0xb5c6, 0x0038, 0x080c, 0x323e,
-	0x080c, 0xca7a, 0x1110, 0x080c, 0xb5c6, 0x080c, 0xac2b, 0x0804,
-	0xe0d4, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x0005, 0x00c6,
-	0x00e6, 0x0016, 0x2c08, 0x2170, 0x9006, 0x080c, 0xe2e0, 0x001e,
-	0x0120, 0x6020, 0x9084, 0x000f, 0x001b, 0x00ee, 0x00ce, 0x0005,
-	0xe16e, 0xe16e, 0xe16e, 0xe16e, 0xe16e, 0xe16e, 0xe170, 0xe16e,
-	0xe16e, 0xe16e, 0xe16e, 0xac2b, 0xac2b, 0xe16e, 0x9006, 0x0005,
-	0x0036, 0x0046, 0x0016, 0x7010, 0x00b6, 0x2058, 0xbca0, 0x00be,
-	0x2c00, 0x2009, 0x0020, 0x080c, 0xe316, 0x001e, 0x004e, 0x2019,
-	0x0002, 0x080c, 0xde67, 0x003e, 0x9085, 0x0001, 0x0005, 0x0096,
-	0x080c, 0xc865, 0x0140, 0x6014, 0x904d, 0x080c, 0xc453, 0x687b,
-	0x0005, 0x080c, 0x6d9f, 0x009e, 0x080c, 0xac2b, 0x9085, 0x0001,
-	0x0005, 0x2001, 0x0001, 0x080c, 0x6580, 0x0156, 0x0016, 0x0026,
+	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,
-	0xbbc1, 0x003e, 0x002e, 0x001e, 0x015e, 0x9005, 0x0005, 0x00f6,
-	0x00e6, 0x00c6, 0x0086, 0x0076, 0x0066, 0x00b6, 0x0126, 0x2091,
-	0x8000, 0x2740, 0x2061, 0x1ddc, 0x2079, 0x0001, 0x8fff, 0x0904,
-	0xe209, 0x2071, 0x1800, 0x7654, 0x7074, 0x8001, 0x9602, 0x1a04,
-	0xe209, 0x88ff, 0x0120, 0x2800, 0x9c06, 0x1590, 0x2078, 0x080c,
-	0xe347, 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, 0xe571, 0x080c, 0xcf9c, 0x080c, 0x1a94,
-	0x6023, 0x0007, 0x6014, 0x2048, 0x080c, 0xc865, 0x0120, 0x0046,
-	0x080c, 0xe2b9, 0x004e, 0x009e, 0x080c, 0xac2b, 0x88ff, 0x1198,
-	0x9ce0, 0x001c, 0x2001, 0x181a, 0x2004, 0x9c02, 0x1210, 0x0804,
-	0xe1be, 0x9006, 0x012e, 0x00be, 0x006e, 0x007e, 0x008e, 0x00ce,
-	0x00ee, 0x00fe, 0x0005, 0x98c5, 0x0001, 0x0ca0, 0x080c, 0xa899,
-	0x00b6, 0x0076, 0x0056, 0x0086, 0x9046, 0x2029, 0x0001, 0x2c20,
-	0x2019, 0x0002, 0x6210, 0x2258, 0x0096, 0x904e, 0x080c, 0xa207,
-	0x009e, 0x008e, 0x903e, 0x080c, 0xa2b2, 0x080c, 0xe1af, 0x005e,
-	0x007e, 0x00be, 0x080c, 0xa8b5, 0x0005, 0x080c, 0xa899, 0x00b6,
-	0x0046, 0x0056, 0x0076, 0x00c6, 0x0156, 0x2c20, 0x2128, 0x20a9,
-	0x007f, 0x900e, 0x0016, 0x0036, 0x080c, 0x6644, 0x1190, 0x0056,
-	0x0086, 0x9046, 0x2508, 0x2029, 0x0001, 0x0096, 0x904e, 0x080c,
-	0xa207, 0x009e, 0x008e, 0x903e, 0x080c, 0xa2b2, 0x080c, 0xe1af,
-	0x005e, 0x003e, 0x001e, 0x8108, 0x1f04, 0xe242, 0x015e, 0x00ce,
-	0x007e, 0x005e, 0x004e, 0x00be, 0x080c, 0xa8b5, 0x0005, 0x080c,
-	0xa899, 0x00b6, 0x0076, 0x0056, 0x6210, 0x2258, 0x0086, 0x9046,
-	0x2029, 0x0001, 0x2019, 0x0048, 0x0096, 0x904e, 0x080c, 0xa207,
-	0x009e, 0x008e, 0x903e, 0x080c, 0xa2b2, 0x2c20, 0x080c, 0xe1af,
-	0x005e, 0x007e, 0x00be, 0x080c, 0xa8b5, 0x0005, 0x080c, 0xa899,
-	0x00b6, 0x0046, 0x0056, 0x0076, 0x00c6, 0x0156, 0x2c20, 0x20a9,
-	0x0800, 0x900e, 0x0016, 0x0036, 0x080c, 0x6644, 0x11a0, 0x0086,
-	0x9046, 0x2828, 0x0046, 0x2021, 0x0001, 0x080c, 0xe555, 0x004e,
-	0x0096, 0x904e, 0x080c, 0xa207, 0x009e, 0x008e, 0x903e, 0x080c,
-	0xa2b2, 0x080c, 0xe1af, 0x003e, 0x001e, 0x8108, 0x1f04, 0xe292,
-	0x015e, 0x00ce, 0x007e, 0x005e, 0x004e, 0x00be, 0x080c, 0xa8b5,
-	0x0005, 0x0016, 0x00f6, 0x080c, 0xc863, 0x0198, 0xa864, 0x9084,
-	0x00ff, 0x9086, 0x0046, 0x0180, 0xa800, 0x907d, 0x0138, 0xa803,
-	0x0000, 0xab82, 0x080c, 0x6d9f, 0x2f48, 0x0cb0, 0xab82, 0x080c,
-	0x6d9f, 0x00fe, 0x001e, 0x0005, 0xa800, 0x907d, 0x0130, 0xa803,
-	0x0000, 0x080c, 0x6d9f, 0x2f48, 0x0cb8, 0x080c, 0x6d9f, 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, 0xc853, 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, 0x6d9f, 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, 0x9239, 0x001e, 0x0005,
-	0xa001, 0xa001, 0x0005, 0x6024, 0xd0e4, 0x0158, 0xd0cc, 0x0118,
-	0x080c, 0xcbaf, 0x0030, 0x080c, 0xe571, 0x080c, 0x88d7, 0x080c,
-	0xabf0, 0x0005, 0x9280, 0x0008, 0x2004, 0x9084, 0x000f, 0x0002,
-	0xe3a6, 0xe3a6, 0xe3a6, 0xe3a8, 0xe3a6, 0xe3a8, 0xe3a8, 0xe3a6,
-	0xe3a8, 0xe3a6, 0xe3a6, 0xe3a6, 0xe3a6, 0xe3a6, 0x9006, 0x0005,
-	0x9085, 0x0001, 0x0005, 0x9280, 0x0008, 0x2004, 0x9084, 0x000f,
-	0x0002, 0xe3bf, 0xe3bf, 0xe3bf, 0xe3bf, 0xe3bf, 0xe3bf, 0xe3cc,
-	0xe3bf, 0xe3bf, 0xe3bf, 0xe3bf, 0xe3bf, 0xe3bf, 0xe3bf, 0x6007,
-	0x003b, 0x602f, 0x0009, 0x6017, 0x2a00, 0x6003, 0x0001, 0x2009,
-	0x8020, 0x080c, 0x9239, 0x0005, 0x0096, 0x00c6, 0x2260, 0x080c,
-	0xe571, 0x604b, 0x0000, 0x6024, 0xc0f4, 0xc0e4, 0x6026, 0x603b,
-	0x0000, 0x00ce, 0x00d6, 0x2268, 0x9186, 0x0007, 0x1904, 0xe425,
-	0x6814, 0x9005, 0x0138, 0x2048, 0xa87c, 0xd0fc, 0x1118, 0x00de,
-	0x009e, 0x08a8, 0x6007, 0x003a, 0x6003, 0x0001, 0x2009, 0x8020,
-	0x080c, 0x9239, 0x00c6, 0x2d60, 0x6100, 0x9186, 0x0002, 0x1904,
-	0xe49c, 0x6014, 0x9005, 0x1138, 0x6000, 0x9086, 0x0007, 0x190c,
-	0x0d7d, 0x0804, 0xe49c, 0x2048, 0x080c, 0xc865, 0x1130, 0x0028,
-	0x2048, 0xa800, 0x9005, 0x1de0, 0x2900, 0x2048, 0xa87c, 0x9084,
-	0x0003, 0x9086, 0x0002, 0x1168, 0xa87c, 0xc0dc, 0xc0f4, 0xa87e,
-	0xa880, 0xc0fc, 0xa882, 0x2009, 0x0043, 0x080c, 0xdca4, 0x0804,
-	0xe49c, 0x2009, 0x0041, 0x0804, 0xe496, 0x9186, 0x0005, 0x15a0,
-	0x6814, 0x2048, 0xa87c, 0xd0bc, 0x1120, 0x00de, 0x009e, 0x0804,
-	0xe3bf, 0xd0b4, 0x0128, 0xd0fc, 0x090c, 0x0d7d, 0x0804, 0xe3e0,
-	0x6007, 0x003a, 0x6003, 0x0001, 0x2009, 0x8020, 0x080c, 0x9239,
-	0x00c6, 0x2d60, 0x6100, 0x9186, 0x0002, 0x0120, 0x9186, 0x0004,
-	0x1904, 0xe49c, 0x6814, 0x2048, 0xa97c, 0xc1f4, 0xc1dc, 0xa97e,
-	0xa980, 0xc1fc, 0xc1bc, 0xa982, 0x00f6, 0x2c78, 0x080c, 0x174b,
-	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, 0x6d9f, 0x2019, 0x0045, 0x6008,
-	0x2068, 0x080c, 0xde67, 0x2d00, 0x600a, 0x6023, 0x0006, 0x6003,
-	0x0007, 0x901e, 0x631a, 0x634a, 0x003e, 0x0038, 0x604b, 0x0000,
-	0x6003, 0x0007, 0x080c, 0xdca4, 0x00ce, 0x00de, 0x009e, 0x0005,
-	0x9186, 0x0013, 0x1128, 0x6004, 0x9082, 0x0085, 0x2008, 0x00c2,
-	0x9186, 0x0027, 0x1178, 0x080c, 0x95ff, 0x0036, 0x0096, 0x6014,
-	0x2048, 0x2019, 0x0004, 0x080c, 0xe2b9, 0x009e, 0x003e, 0x080c,
-	0x96bd, 0x0005, 0x9186, 0x0014, 0x0d70, 0x080c, 0xacaa, 0x0005,
-	0xe4cf, 0xe4cd, 0xe4cd, 0xe4cd, 0xe4cd, 0xe4cd, 0xe4cf, 0xe4cd,
-	0xe4cd, 0xe4cd, 0xe4cd, 0xe4cd, 0xe4cd, 0x080c, 0x0d7d, 0x6003,
-	0x000c, 0x080c, 0x96bd, 0x0005, 0x9182, 0x0092, 0x1220, 0x9182,
-	0x0085, 0x0208, 0x001a, 0x080c, 0xacaa, 0x0005, 0xe4eb, 0xe4eb,
-	0xe4eb, 0xe4eb, 0xe4ed, 0xe50d, 0xe4eb, 0xe4eb, 0xe4eb, 0xe4eb,
-	0xe4eb, 0xe4eb, 0xe4eb, 0x080c, 0x0d7d, 0x00d6, 0x2c68, 0x080c,
-	0xab9a, 0x01b0, 0x6003, 0x0001, 0x6007, 0x001e, 0x2009, 0x026e,
-	0x210c, 0x613a, 0x2009, 0x026f, 0x210c, 0x613e, 0x600b, 0xffff,
-	0x6910, 0x6112, 0x6023, 0x0004, 0x2009, 0x8020, 0x080c, 0x9239,
-	0x2d60, 0x080c, 0xabf0, 0x00de, 0x0005, 0x080c, 0xabf0, 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, 0x88d7, 0x080c, 0xabf0,
-	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,
-	0xbbd5, 0x009e, 0x1168, 0x2011, 0x0274, 0x20a9, 0x0004, 0x6010,
-	0x0096, 0x2048, 0x2019, 0x0006, 0x080c, 0xbbd5, 0x009e, 0x1100,
-	0x015e, 0x003e, 0x002e, 0x0005, 0x00e6, 0x2071, 0x1800, 0x080c,
-	0x5fd7, 0x080c, 0x2fe0, 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, 0x6d9f, 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, 0xe347, 0x01b8, 0x080c,
-	0xe357, 0x11a0, 0x6000, 0x9086, 0x0004, 0x1120, 0x0016, 0x080c,
-	0x1a94, 0x001e, 0x080c, 0xca69, 0x1110, 0x080c, 0x323e, 0x080c,
-	0xca7a, 0x1110, 0x080c, 0xb5c6, 0x080c, 0xac2b, 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, 0xcf84, 0x0168, 0x2019, 0xffff, 0x9005, 0x0128, 0x6010,
-	0x00b6, 0x2058, 0xbba0, 0x00be, 0x2021, 0x0004, 0x080c, 0x4ce0,
-	0x004e, 0x003e, 0x000e, 0x6004, 0x9086, 0x0001, 0x1128, 0x080c,
-	0xa37f, 0x080c, 0xac2b, 0x9006, 0x0005, 0x00e6, 0x00c6, 0x00b6,
-	0x0046, 0x2061, 0x1ddc, 0x2071, 0x1800, 0x7454, 0x7074, 0x8001,
-	0x9402, 0x12b8, 0x2100, 0x9c06, 0x0148, 0x6000, 0x9086, 0x0000,
-	0x0128, 0x6010, 0x2058, 0xb8a0, 0x9206, 0x0140, 0x9ce0, 0x001c,
-	0x2001, 0x181a, 0x2004, 0x9c02, 0x1220, 0x0c60, 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, 0x97f5
+	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
 };
 #ifdef UNIQUE_FW_NAME
-unsigned short fw2322ipx_length01 = 0xdf8f;
+unsigned short fw2322ipx_length01 = 0xe0c2;
 #else
-unsigned short risc_code_length01 = 0xdf8f;
+unsigned short risc_code_length01 = 0xe0c2;
 #endif
 
 /*
@@ -7853,7 +7892,7 @@
 	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, 0x0000, 0xb7b0, 0x0000, 0xb9b1,
+	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,
@@ -8080,6 +8119,6 @@
 	0x000b, 0x885c, 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, 0xa307, 0x24ad
+	0x0000, 0xb838, 0x0017, 0x4000, 0xa2e7, 0x24ad
 };
 unsigned short xseqipx_code_length01 = 0x10d6;
diff -Nru a/drivers/scsi/qla2xxx/ql6312.c b/drivers/scsi/qla2xxx/ql6312.c
--- a/drivers/scsi/qla2xxx/ql6312.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/scsi/qla2xxx/ql6312.c	2005-03-01 23:39:17 -08:00
@@ -35,6 +35,11 @@
 		.isp_name	= "ISP6312",
 		.fw_info	= qla_fw_tbl,
 	},
+	{
+		.drv_name	= qla_driver_name,
+		.isp_name	= "ISP6322",
+		.fw_info	= qla_fw_tbl,
+	},
 };
 
 static struct pci_device_id qla6312_pci_tbl[] = {
@@ -45,6 +50,13 @@
 		.subdevice	= PCI_ANY_ID,
 		.driver_data	= (unsigned long)&qla_board_tbl[0],
 	},
+	{
+		.vendor		= PCI_VENDOR_ID_QLOGIC,
+		.device		= PCI_DEVICE_ID_QLOGIC_ISP6322,
+		.subvendor	= PCI_ANY_ID,
+		.subdevice	= PCI_ANY_ID,
+		.driver_data	= (unsigned long)&qla_board_tbl[1],
+	},
 	{0, 0},
 };
 MODULE_DEVICE_TABLE(pci, qla6312_pci_tbl);
@@ -85,6 +97,6 @@
 module_exit(qla6312_exit);
 
 MODULE_AUTHOR("QLogic Corporation");
-MODULE_DESCRIPTION("QLogic ISP6312 FC-SCSI Host Bus Adapter driver");
+MODULE_DESCRIPTION("QLogic ISP63xx FC-SCSI Host Bus Adapter driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(QLA2XXX_VERSION);
diff -Nru a/drivers/scsi/qla2xxx/ql6312_fw.c b/drivers/scsi/qla2xxx/ql6312_fw.c
--- a/drivers/scsi/qla2xxx/ql6312_fw.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/scsi/qla2xxx/ql6312_fw.c	2005-03-01 23:38:53 -08:00
@@ -1,8 +1,8 @@
-/**************************************************************************
+/******************************************************************************
  *                  QLOGIC LINUX SOFTWARE
  *
  * QLogic ISP2x00 device driver for Linux 2.6.x
- * Copyright (C) 2003-2004 QLogic Corporation
+ * Copyright (C) 2003 QLogic Corporation
  * (www.qlogic.com)
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -15,10 +15,10 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * General Public License for more details.
  *
- *************************************************************************/
+ ******************************************************************************/
 
 /*
- *	Firmware Version 3.03.02 (16:50 Aug 10, 2004)
+ *	Firmware Version 3.03.08 (10:02 Nov 12, 2004)
  */
 
 #ifdef UNIQUE_FW_NAME
@@ -28,15 +28,15 @@
 #endif
 
 #ifdef UNIQUE_FW_NAME
-unsigned char fw2300flx_version_str[] = {3, 3, 2};
+unsigned char fw2300flx_version_str[] = {3, 3, 8};
 #else
-unsigned char firmware_version[] = {3, 3, 2};
+unsigned char firmware_version[] = {3, 3, 8};
 #endif
 
 #ifdef UNIQUE_FW_NAME
-#define fw2300flx_VERSION_STRING "3.03.02"
+#define fw2300flx_VERSION_STRING "3.03.08"
 #else
-#define FW_VERSION_STRING "3.03.02"
+#define FW_VERSION_STRING "3.03.08"
 #endif
 
 #ifdef UNIQUE_FW_NAME
@@ -50,12 +50,12 @@
 #else
 unsigned short risc_code01[] = { 
 #endif
-	0x0470, 0x0000, 0x0000, 0xd5d4, 0x0000, 0x0003, 0x0003, 0x0002,
+	0x0470, 0x0000, 0x0000, 0xdd79, 0x0000, 0x0003, 0x0003, 0x0008,
 	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, 0x3220, 0x2020, 0x2020, 0x2400, 0x20a9,
+	0x332e, 0x3033, 0x2e30, 0x3820, 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,3407 +64,3486 @@
 	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, 0x2b5b, 0x2051, 0x1800, 0x2a70, 0x20e1,
-	0x0001, 0x20e9, 0x0001, 0x2009, 0x0000, 0x080c, 0x0e2f, 0x2029,
+	0x7883, 0x0004, 0x2089, 0x2cff, 0x2051, 0x1800, 0x2a70, 0x20e1,
+	0x0001, 0x20e9, 0x0001, 0x2009, 0x0000, 0x080c, 0x0e75, 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,
 	0x20a8, 0x4104, 0x2001, 0x0000, 0x9086, 0x0000, 0x0120, 0x21a8,
 	0x4104, 0x8001, 0x1de0, 0x756a, 0x766e, 0x7766, 0x7472, 0x7476,
-	0x00e6, 0x2071, 0x1a9f, 0x2472, 0x00ee, 0x20a1, 0x1cd0, 0x716c,
+	0x00e6, 0x2071, 0x1aa2, 0x2472, 0x00ee, 0x20a1, 0x1cd0, 0x716c,
 	0x810d, 0x810d, 0x810d, 0x810d, 0x918c, 0x000f, 0x2001, 0x0001,
 	0x9112, 0x900e, 0x21a8, 0x4104, 0x8211, 0x1de0, 0x716c, 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, 0x0f03, 0x080c,
-	0x5cf3, 0x080c, 0x9dc5, 0x080c, 0x10ba, 0x080c, 0x129f, 0x080c,
-	0x1a60, 0x080c, 0x0d46, 0x080c, 0x103f, 0x080c, 0x3245, 0x080c,
-	0x72a0, 0x080c, 0x6635, 0x080c, 0x7f7a, 0x080c, 0x2317, 0x080c,
-	0x82a7, 0x080c, 0x792a, 0x080c, 0x2154, 0x080c, 0x2288, 0x080c,
-	0x230c, 0x2091, 0x3009, 0x7883, 0x0000, 0x1004, 0x091d, 0x7880,
+	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,
 	0x9086, 0x0002, 0x1190, 0x7883, 0x4000, 0x7837, 0x4000, 0x7833,
 	0x0010, 0x0e04, 0x0911, 0x2091, 0x5000, 0x2091, 0x4080, 0x2001,
-	0x0089, 0x2004, 0xd084, 0x190c, 0x1187, 0x2071, 0x1800, 0x7003,
+	0x0089, 0x2004, 0xd084, 0x190c, 0x11e0, 0x2071, 0x1800, 0x7003,
 	0x0000, 0x2071, 0x1800, 0x7000, 0x908e, 0x0003, 0x1168, 0x080c,
-	0x49b9, 0x080c, 0x326c, 0x080c, 0x7311, 0x080c, 0x6ae5, 0x080c,
-	0x7fa3, 0x080c, 0x2ac5, 0x0c68, 0x000b, 0x0c88, 0x0940, 0x0941,
-	0x0ad8, 0x093e, 0x0b8f, 0x0d45, 0x0d45, 0x0d45, 0x080c, 0x0db4,
+	0x4be4, 0x080c, 0x3410, 0x080c, 0x7580, 0x080c, 0x6d2e, 0x080c,
+	0x823e, 0x080c, 0x2c2c, 0x0c68, 0x000b, 0x0c88, 0x0940, 0x0941,
+	0x0ad8, 0x093e, 0x0b8f, 0x0d8b, 0x0d8b, 0x0d8b, 0x080c, 0x0dfa,
 	0x0005, 0x0126, 0x00f6, 0x2091, 0x8000, 0x7000, 0x9086, 0x0001,
-	0x1904, 0x0aab, 0x080c, 0x0e71, 0x080c, 0x6faa, 0x0150, 0x080c,
-	0x6fcd, 0x15a0, 0x2079, 0x0100, 0x7828, 0x9085, 0x1800, 0x782a,
-	0x0468, 0x080c, 0x6edc, 0x7000, 0x9086, 0x0001, 0x1904, 0x0aab,
-	0x7094, 0x9086, 0x0028, 0x1904, 0x0aab, 0x080c, 0x7f72, 0x080c,
-	0x7f64, 0x2001, 0x0161, 0x2003, 0x0001, 0x2079, 0x0100, 0x7827,
-	0xffff, 0x7a28, 0x9295, 0x5e2f, 0x7a2a, 0x2011, 0x6e2b, 0x080c,
-	0x803f, 0x2011, 0x6e1e, 0x080c, 0x8113, 0x2011, 0x5b4e, 0x080c,
-	0x803f, 0x2011, 0x8030, 0x901e, 0x7392, 0x04d0, 0x080c, 0x53fb,
-	0x2079, 0x0100, 0x7844, 0x9005, 0x1904, 0x0aab, 0x2011, 0x5b4e,
-	0x080c, 0x803f, 0x2011, 0x6e2b, 0x080c, 0x803f, 0x2011, 0x6e1e,
-	0x080c, 0x8113, 0x2001, 0x0265, 0x2001, 0x0205, 0x2003, 0x0000,
+	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, 0x5c9b, 0x00ce, 0x0804,
-	0x0aab, 0x780f, 0x006b, 0x7a28, 0x080c, 0x6fb2, 0x0118, 0x9295,
+	0x1140, 0x00c6, 0x2061, 0x0100, 0x080c, 0x5ee1, 0x00ce, 0x0804,
+	0x0aab, 0x780f, 0x006b, 0x7a28, 0x080c, 0x720f, 0x0118, 0x9295,
 	0x5e2f, 0x0010, 0x9295, 0x402f, 0x7a2a, 0x2011, 0x8010, 0x73d4,
-	0x2001, 0x197f, 0x2003, 0x0001, 0x080c, 0x298b, 0x080c, 0x48f4,
+	0x2001, 0x197f, 0x2003, 0x0001, 0x080c, 0x2a89, 0x080c, 0x4b1f,
 	0x7244, 0xc284, 0x7246, 0x2001, 0x180c, 0x200c, 0xc1ac, 0xc1cc,
-	0x2102, 0x080c, 0x9650, 0x2011, 0x0004, 0x080c, 0xbb4b, 0x080c,
-	0x6479, 0x080c, 0x6faa, 0x1120, 0x080c, 0x29cf, 0x02e0, 0x0400,
-	0x080c, 0x5ca2, 0x0140, 0x7093, 0x0001, 0x70cf, 0x0000, 0x080c,
-	0x55c8, 0x0804, 0x0aab, 0x080c, 0x539a, 0xd094, 0x0188, 0x2011,
-	0x180c, 0x2204, 0xc0cd, 0x2012, 0x080c, 0x539e, 0xd0d4, 0x1118,
-	0x080c, 0x29cf, 0x1270, 0x2011, 0x180c, 0x2204, 0xc0bc, 0x0088,
-	0x080c, 0x539e, 0xd0d4, 0x1db8, 0x2011, 0x180c, 0x2204, 0xc0bd,
-	0x0040, 0x2011, 0x180c, 0x2204, 0xc0bd, 0x2012, 0x080c, 0x6572,
-	0x0008, 0x2012, 0x080c, 0x6538, 0x0120, 0x7a0c, 0xc2b4, 0x7a0e,
-	0x00a8, 0x707b, 0x0000, 0x080c, 0x6faa, 0x1130, 0x70ac, 0x9005,
-	0x1168, 0x080c, 0xbf8c, 0x0050, 0x080c, 0xbf8c, 0x70d8, 0xd09c,
-	0x1128, 0x70ac, 0x9005, 0x0110, 0x080c, 0x5c78, 0x70e3, 0x0000,
-	0x70df, 0x0000, 0x70a3, 0x0000, 0x080c, 0x29d7, 0x0228, 0x2011,
-	0x0101, 0x2204, 0xc0c4, 0x2012, 0x72d8, 0x080c, 0x6faa, 0x1178,
+	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,
 	0x705b, 0xffff, 0x705f, 0x00ef, 0x707f, 0x0000, 0x0020, 0x2019,
 	0x1945, 0x201b, 0x0000, 0x2079, 0x185b, 0x7804, 0xd0ac, 0x0108,
-	0xc295, 0x72da, 0x080c, 0x6faa, 0x0118, 0x9296, 0x0004, 0x0548,
-	0x2011, 0x0001, 0x080c, 0xbb4b, 0x70a7, 0x0000, 0x70ab, 0xffff,
+	0xc295, 0x72da, 0x080c, 0x7207, 0x0118, 0x9296, 0x0004, 0x0548,
+	0x2011, 0x0001, 0x080c, 0xbe47, 0x70a7, 0x0000, 0x70ab, 0xffff,
 	0x7003, 0x0002, 0x2079, 0x0100, 0x7827, 0x0003, 0x7828, 0x9085,
-	0x0003, 0x782a, 0x00fe, 0x080c, 0x2dc8, 0x2011, 0x0005, 0x080c,
-	0x975b, 0x080c, 0x898b, 0x080c, 0x6faa, 0x0148, 0x00c6, 0x2061,
+	0x0003, 0x782a, 0x00fe, 0x080c, 0x2f6c, 0x2011, 0x0005, 0x080c,
+	0x9a0f, 0x080c, 0x8c10, 0x080c, 0x7207, 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, 0x975b, 0x080c, 0x898b, 0x080c,
-	0x6faa, 0x0148, 0x00c6, 0x2061, 0x0100, 0x0016, 0x2009, 0x0002,
+	0x00fe, 0x2011, 0x0005, 0x080c, 0x9a0f, 0x080c, 0x8c10, 0x080c,
+	0x7207, 0x0148, 0x00c6, 0x2061, 0x0100, 0x0016, 0x2009, 0x0002,
 	0x61e2, 0x001e, 0x00ce, 0x00fe, 0x012e, 0x0005, 0x00c6, 0x00b6,
-	0x080c, 0x6faa, 0x1118, 0x20a9, 0x0800, 0x0010, 0x20a9, 0x0782,
-	0x080c, 0x6faa, 0x1110, 0x900e, 0x0010, 0x2009, 0x007e, 0x86ff,
+	0x080c, 0x7207, 0x1118, 0x20a9, 0x0800, 0x0010, 0x20a9, 0x0782,
+	0x080c, 0x7207, 0x1110, 0x900e, 0x0010, 0x2009, 0x007e, 0x86ff,
 	0x0138, 0x9180, 0x1000, 0x2004, 0x905d, 0x0110, 0xb800, 0xd0bc,
-	0x090c, 0x30e2, 0x8108, 0x1f04, 0x0abf, 0x707b, 0x0000, 0x707c,
+	0x090c, 0x3286, 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, 0x2dc8, 0x080c,
-	0x898b, 0x0804, 0x0b8c, 0x70d8, 0xd0ac, 0x1110, 0xd09c, 0x0540,
+	0x0b8c, 0x70a8, 0x9086, 0xffff, 0x0130, 0x080c, 0x2f6c, 0x080c,
+	0x8c10, 0x0804, 0x0b8c, 0x70d8, 0xd0ac, 0x1110, 0xd09c, 0x0540,
 	0xd084, 0x0530, 0x0006, 0x2001, 0x0103, 0x2003, 0x002b, 0x000e,
-	0xd08c, 0x01f0, 0x70dc, 0x9086, 0xffff, 0x01b0, 0x080c, 0x2f53,
-	0x080c, 0x898b, 0x70d8, 0xd094, 0x1904, 0x0b8c, 0x2011, 0x0001,
-	0x080c, 0xc23b, 0x0110, 0x2011, 0x0003, 0x901e, 0x080c, 0x2f8d,
-	0x080c, 0x898b, 0x0804, 0x0b8c, 0x70e0, 0x9005, 0x1904, 0x0b8c,
+	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,
 	0x70a4, 0x9005, 0x1904, 0x0b8c, 0x70d8, 0xd0a4, 0x0118, 0xd0b4,
-	0x0904, 0x0b8c, 0x080c, 0x6538, 0x1904, 0x0b8c, 0x080c, 0x658b,
-	0x1904, 0x0b8c, 0x080c, 0x6572, 0x01c0, 0x0156, 0x00c6, 0x20a9,
-	0x007f, 0x900e, 0x0016, 0x080c, 0x6256, 0x1118, 0xb800, 0xd0ec,
+	0x0904, 0x0b8c, 0x080c, 0x6781, 0x1904, 0x0b8c, 0x080c, 0x67d4,
+	0x1904, 0x0b8c, 0x080c, 0x67bb, 0x01c0, 0x0156, 0x00c6, 0x20a9,
+	0x007f, 0x900e, 0x0016, 0x080c, 0x649f, 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, 0x0f73, 0x2011,
-	0x19a5, 0x080c, 0x0f73, 0x7030, 0xc08c, 0x7032, 0x7003, 0x0003,
-	0x70ab, 0xffff, 0x080c, 0x0e53, 0x9006, 0x080c, 0x2619, 0x0036,
-	0x0046, 0x2019, 0xffff, 0x2021, 0x0006, 0x080c, 0x4a91, 0x004e,
-	0x003e, 0x00f6, 0x2079, 0x0100, 0x080c, 0x6fcd, 0x0150, 0x080c,
-	0x6faa, 0x7828, 0x0118, 0x9084, 0xe1ff, 0x0010, 0x9084, 0xffdf,
+	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, 0x975b, 0x2011, 0x0000, 0x080c, 0x9765,
-	0x080c, 0x898b, 0x080c, 0x8a68, 0x012e, 0x00be, 0x0005, 0x0016,
+	0x2011, 0x0000, 0x080c, 0x9a0f, 0x2011, 0x0000, 0x080c, 0x9a19,
+	0x080c, 0x8c10, 0x080c, 0x8ced, 0x012e, 0x00be, 0x0005, 0x0016,
 	0x0046, 0x00f6, 0x0126, 0x2091, 0x8000, 0x2079, 0x0100, 0x7904,
-	0x918c, 0xfffd, 0x7906, 0x2009, 0x00f7, 0x080c, 0x5c61, 0x7940,
+	0x918c, 0xfffd, 0x7906, 0x2009, 0x00f7, 0x080c, 0x5ea7, 0x7940,
 	0x918c, 0x0010, 0x7942, 0x7924, 0xd1b4, 0x0110, 0x7827, 0x0040,
-	0xd19c, 0x0110, 0x7827, 0x0008, 0x0006, 0x0036, 0x0156, 0x7954,
-	0xd1ac, 0x1904, 0x0c1c, 0x2001, 0x197f, 0x2004, 0x9005, 0x1518,
-	0x080c, 0x2a52, 0x1148, 0x2001, 0x0001, 0x080c, 0x29ba, 0x2001,
-	0x0001, 0x080c, 0x299d, 0x00b8, 0x080c, 0x2a5a, 0x1138, 0x9006,
-	0x080c, 0x29ba, 0x9006, 0x080c, 0x299d, 0x0068, 0x080c, 0x2a62,
+	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,
-	0x27b4, 0x0804, 0x0cfc, 0x080c, 0x6fbb, 0x0148, 0x080c, 0x6fcd,
-	0x1118, 0x080c, 0x729b, 0x0050, 0x080c, 0x6fb2, 0x0dd0, 0x080c,
-	0x7296, 0x080c, 0x728c, 0x080c, 0x6edc, 0x0058, 0x080c, 0x6faa,
-	0x0140, 0x2009, 0x00f8, 0x080c, 0x5c61, 0x7843, 0x0090, 0x7843,
-	0x0010, 0x20a9, 0x09c4, 0x7820, 0xd09c, 0x1138, 0x080c, 0x6faa,
-	0x0138, 0x7824, 0xd0ac, 0x1904, 0x0d01, 0x1f04, 0x0bfb, 0x0070,
-	0x7824, 0x080c, 0x6fc4, 0x0118, 0xd0ac, 0x1904, 0x0d01, 0x9084,
-	0x1800, 0x0d98, 0x7003, 0x0001, 0x0804, 0x0d01, 0x2001, 0x0001,
-	0x080c, 0x2619, 0x0804, 0x0d14, 0x2001, 0x197f, 0x2004, 0x9005,
-	0x1518, 0x080c, 0x2a52, 0x1148, 0x2001, 0x0001, 0x080c, 0x29ba,
-	0x2001, 0x0001, 0x080c, 0x299d, 0x00b8, 0x080c, 0x2a5a, 0x1138,
-	0x9006, 0x080c, 0x29ba, 0x9006, 0x080c, 0x299d, 0x0068, 0x080c,
-	0x2a62, 0x1d50, 0x2001, 0x1970, 0x2004, 0xd0fc, 0x0108, 0x0020,
-	0x080c, 0x27b4, 0x0804, 0x0cfc, 0x7850, 0x9085, 0x0040, 0x7852,
-	0x7938, 0x7850, 0x9084, 0xfbcf, 0x7852, 0x080c, 0x2a6a, 0x9085,
-	0x2000, 0x7852, 0x793a, 0x20a9, 0x0046, 0x1d04, 0x0c55, 0x080c,
-	0x80f3, 0x1f04, 0x0c55, 0x7850, 0x9085, 0x0400, 0x9084, 0xdfbf,
-	0x7852, 0x793a, 0x080c, 0x6fbb, 0x0148, 0x080c, 0x6fcd, 0x1118,
-	0x080c, 0x729b, 0x0050, 0x080c, 0x6fb2, 0x0dd0, 0x080c, 0x7296,
-	0x080c, 0x728c, 0x080c, 0x6edc, 0x0020, 0x2009, 0x00f8, 0x080c,
-	0x5c61, 0x20a9, 0x0028, 0xa001, 0x1f04, 0x0c7b, 0x7850, 0x9085,
-	0x1400, 0x7852, 0x080c, 0x6faa, 0x0120, 0x7843, 0x0090, 0x7843,
-	0x0010, 0x2021, 0xe678, 0x2019, 0xea60, 0x0d0c, 0x80f3, 0x7820,
-	0xd09c, 0x1588, 0x080c, 0x6faa, 0x0904, 0x0ce1, 0x7824, 0xd0ac,
-	0x1904, 0x0d01, 0x080c, 0x6fcd, 0x1530, 0x0046, 0x2021, 0x0320,
-	0x8421, 0x1df0, 0x004e, 0x7827, 0x1800, 0x080c, 0x2a6a, 0x7824,
-	0x9084, 0x1800, 0x1168, 0x9484, 0x0fff, 0x1140, 0x2001, 0x1810,
-	0x2004, 0x9084, 0x9000, 0x0110, 0x080c, 0x0d22, 0x8421, 0x1158,
-	0x1d04, 0x0cbc, 0x080c, 0x80f3, 0x080c, 0x7296, 0x080c, 0x728c,
-	0x7003, 0x0001, 0x04f0, 0x8319, 0x1940, 0x1d04, 0x0cc9, 0x080c,
-	0x80f3, 0x2009, 0x1973, 0x2104, 0x9005, 0x0118, 0x8001, 0x200a,
-	0x1178, 0x200b, 0x000a, 0x7827, 0x0048, 0x20a9, 0x0002, 0x080c,
-	0x2a4b, 0x7924, 0x080c, 0x2a6a, 0xd19c, 0x0110, 0x080c, 0x298b,
-	0x00d8, 0x080c, 0x6fbb, 0x1140, 0x94a2, 0x03e8, 0x1128, 0x080c,
-	0x6f82, 0x7003, 0x0001, 0x00a8, 0x7827, 0x1800, 0x080c, 0x2a6a,
-	0x7824, 0x080c, 0x6fc4, 0x0110, 0xd0ac, 0x1158, 0x9084, 0x1800,
-	0x0950, 0x7003, 0x0001, 0x0028, 0x2001, 0x0001, 0x080c, 0x2619,
-	0x0078, 0x2009, 0x180c, 0x210c, 0xd19c, 0x1120, 0x7904, 0x918d,
+	0x28b2, 0x0804, 0x0d33, 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,
+	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,
+	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,
+	0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x1118, 0x7850, 0xc0e4,
+	0x7852, 0x2009, 0x180c, 0x210c, 0xd19c, 0x1120, 0x7904, 0x918d,
 	0x0002, 0x7906, 0x7827, 0x0048, 0x7828, 0x9085, 0x0028, 0x782a,
-	0x7850, 0x9085, 0x0400, 0x7852, 0x2001, 0x197f, 0x2003, 0x0000,
-	0x9006, 0x78f2, 0x015e, 0x003e, 0x000e, 0x012e, 0x00fe, 0x004e,
-	0x001e, 0x0005, 0x0006, 0x0016, 0x0036, 0x0046, 0x00b6, 0x00c6,
-	0x00d6, 0x00e6, 0x00f6, 0x0156, 0x0069, 0x0d0c, 0x80f3, 0x015e,
-	0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x004e, 0x003e, 0x001e,
-	0x000e, 0x0005, 0x00e6, 0x2071, 0x189c, 0x7004, 0x9086, 0x0001,
-	0x1110, 0x080c, 0x326c, 0x00ee, 0x0005, 0x0005, 0x2a70, 0x2061,
-	0x1983, 0x2063, 0x0003, 0x6007, 0x0003, 0x600b, 0x0002, 0x600f,
-	0x0317, 0x2001, 0x1954, 0x900e, 0x2102, 0x7192, 0x2001, 0x0100,
-	0x2004, 0x9082, 0x0002, 0x0218, 0x705b, 0xffff, 0x0008, 0x715a,
-	0x7063, 0xffff, 0x717a, 0x717e, 0x080c, 0xbf8c, 0x70e7, 0x00c0,
-	0x2061, 0x1944, 0x6003, 0x0909, 0x6106, 0x600b, 0x8800, 0x600f,
-	0x0200, 0x6013, 0x00ff, 0x6017, 0x000f, 0x611a, 0x601f, 0x07d0,
-	0x2061, 0x194c, 0x6003, 0x8000, 0x6106, 0x610a, 0x600f, 0x0200,
-	0x6013, 0x00ff, 0x6116, 0x601b, 0x0001, 0x611e, 0x2061, 0x1961,
-	0x6003, 0x514c, 0x6007, 0x4f47, 0x600b, 0x4943, 0x600f, 0x2020,
-	0x2001, 0x182b, 0x2102, 0x0005, 0x9016, 0x080c, 0x6256, 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, 0x0db6,
-	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, 0x1a79, 0x7a08, 0x226a,
-	0x2069, 0x1a7a, 0x7a18, 0x226a, 0x8d68, 0x7a1c, 0x226a, 0x782c,
-	0x2019, 0x1a87, 0x201a, 0x2019, 0x1a8a, 0x9016, 0x7808, 0xd09c,
-	0x0168, 0x7820, 0x201a, 0x8210, 0x8318, 0x9386, 0x1a9f, 0x0108,
-	0x0ca8, 0x7808, 0xd09c, 0x0110, 0x2011, 0xdead, 0x2019, 0x1a88,
-	0x782c, 0x201a, 0x8318, 0x221a, 0x7803, 0x0000, 0x2069, 0x1a59,
-	0x901e, 0x20a9, 0x0020, 0x7b26, 0x7a28, 0x226a, 0x8d68, 0x8318,
-	0x1f04, 0x0e03, 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, 0x53a9, 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, 0x0ecb, 0x20a9, 0x0900,
-	0x080c, 0x0eec, 0x2011, 0x0040, 0x080c, 0x0ecb, 0x20a9, 0x0900,
-	0x080c, 0x0eec, 0x0c78, 0x0026, 0x080c, 0x0ed8, 0x1118, 0x2011,
-	0x0040, 0x0098, 0x2011, 0x010e, 0x2214, 0x9294, 0x0007, 0x9296,
-	0x0007, 0x0118, 0x2011, 0xa880, 0x0010, 0x2011, 0x6840, 0xd0e4,
-	0x70eb, 0x0000, 0x1128, 0x70eb, 0x0fa0, 0x080c, 0x0edd, 0x002e,
-	0x0005, 0x0026, 0x080c, 0x0ed8, 0x0128, 0xd0a4, 0x1138, 0x2011,
-	0xcdd5, 0x0010, 0x2011, 0x0080, 0x080c, 0x0edd, 0x002e, 0x0005,
-	0x0026, 0x70eb, 0x0000, 0x080c, 0x0ed8, 0x1148, 0x080c, 0x2a62,
-	0x1118, 0x2011, 0x8484, 0x0058, 0x2011, 0x8282, 0x0040, 0x080c,
-	0x2a62, 0x1118, 0x2011, 0xcdc5, 0x0010, 0x2011, 0xcac2, 0x080c,
-	0x0edd, 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, 0x0e9a, 0x0e71, 0x0e71, 0x0e53, 0x0e80,
-	0x0e71, 0x0e71, 0x0e80, 0x0016, 0x3b08, 0x3a00, 0x9104, 0x918d,
-	0x00c0, 0x21d8, 0x9084, 0xff3f, 0x9205, 0x20d0, 0x001e, 0x0005,
-	0x2001, 0x1839, 0x2004, 0xd0dc, 0x0005, 0x9e86, 0x1800, 0x190c,
-	0x0db4, 0x70e4, 0xd0e4, 0x0108, 0xc2e5, 0x72e6, 0xd0e4, 0x1118,
-	0x9294, 0x00c0, 0x0c01, 0x0005, 0x1d04, 0x0eec, 0x2091, 0x6000,
-	0x1f04, 0x0eec, 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,
-	0x0ef3, 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, 0x0d94, 0x2001, 0x0000,
-	0x810f, 0x20a9, 0x0002, 0x4001, 0x0005, 0x89ff, 0x0140, 0xa804,
-	0xa807, 0x0000, 0x0006, 0x080c, 0x101d, 0x009e, 0x0cb0, 0x0005,
-	0x00e6, 0x2071, 0x1800, 0x080c, 0x1096, 0x090c, 0x0db4, 0x00ee,
-	0x0005, 0x0086, 0x00e6, 0x0006, 0x0026, 0x0036, 0x0126, 0x2091,
-	0x8000, 0x00c9, 0x2071, 0x1800, 0x73bc, 0x702c, 0x9016, 0x9045,
-	0x0158, 0x8210, 0x9906, 0x090c, 0x0db4, 0x2300, 0x9202, 0x0120,
-	0x1a0c, 0x0db4, 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, 0x0db4, 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, 0x7f64, 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, 0x20a9, 0x0040, 0x7022, 0x1f04,
-	0x10ce, 0x702b, 0x0020, 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000,
-	0x00e6, 0xa06f, 0x0000, 0x2071, 0x19f0, 0x701c, 0x9088, 0x19fa,
-	0x280a, 0x8000, 0x9084, 0x003f, 0x701e, 0x7120, 0x9106, 0x090c,
-	0x0db4, 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, 0x1117, 0x1115, 0x1115,
-	0x1115, 0x128e, 0x128e, 0x128e, 0x128e, 0x080c, 0x0db4, 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, 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, 0x10f4, 0x0005, 0x0016,
-	0x00e6, 0x2071, 0x19f0, 0x00f6, 0x2079, 0x0080, 0x792c, 0xd1bc,
-	0x190c, 0x0dad, 0x782b, 0x0002, 0xd1fc, 0x0120, 0x918c, 0x0700,
-	0x7004, 0x0023, 0x00fe, 0x00ee, 0x001e, 0x0005, 0x1105, 0x11ad,
-	0x11e1, 0x0db4, 0x0db4, 0x129a, 0x0db4, 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, 0x114a, 0x0005, 0x7008,
-	0x0096, 0x2048, 0xa86f, 0x0100, 0x009e, 0x7007, 0x0000, 0x080c,
-	0x1105, 0x0005, 0x7008, 0x0096, 0x2048, 0xa86f, 0x0200, 0x009e,
-	0x0ca0, 0x918c, 0x0700, 0x1150, 0x700c, 0x9005, 0x0180, 0x7800,
-	0x7802, 0x7804, 0x7806, 0x080c, 0x115f, 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, 0x10f4, 0x0005, 0x00de,
-	0x009e, 0x080c, 0x10f4, 0x0005, 0xa8a8, 0xd08c, 0x0005, 0x0096,
-	0xa0a0, 0x904d, 0x090c, 0x0db4, 0xa06c, 0x908e, 0x0100, 0x0130,
-	0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, 0x4002, 0x080c, 0x6893,
-	0xa09f, 0x0000, 0xa0a3, 0x0000, 0x2848, 0x080c, 0x101d, 0x009e,
-	0x0005, 0x00a6, 0xa0a0, 0x904d, 0x090c, 0x0db4, 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, 0x10d5, 0x00e8, 0xa97c,
-	0xa894, 0x0016, 0x0006, 0x080c, 0x6893, 0x000e, 0x001e, 0xd1fc,
-	0x1138, 0xd1f4, 0x0128, 0x00c6, 0x2060, 0x080c, 0x9e2f, 0x00ce,
-	0x7008, 0x2048, 0xa89f, 0x0000, 0xa8a3, 0x0000, 0x080c, 0x101d,
-	0x7007, 0x0000, 0x080c, 0x10f4, 0x00ae, 0x0005, 0x0126, 0x2091,
-	0x8000, 0x782b, 0x1001, 0x7007, 0x0005, 0x7000, 0xc094, 0x7002,
-	0x012e, 0x0005, 0x7007, 0x0000, 0x080c, 0x1105, 0x0005, 0x0126,
-	0x2091, 0x2200, 0x2079, 0x0300, 0x2071, 0x1a3a, 0x7003, 0x0000,
-	0x78bf, 0x00f6, 0x781b, 0x4800, 0x00c1, 0x7803, 0x0003, 0x780f,
-	0x0000, 0x20a9, 0x0254, 0x2061, 0xd91d, 0x2c0d, 0x7912, 0xe104,
-	0x9ce0, 0x0002, 0x7916, 0x1f04, 0x12b5, 0x7807, 0x0007, 0x7803,
-	0x0000, 0x7803, 0x0001, 0x012e, 0x0005, 0x00c6, 0x7803, 0x0000,
-	0x7808, 0xd09c, 0x0110, 0x7820, 0x0cd8, 0x2001, 0x1a3b, 0x2003,
-	0x0000, 0x78ab, 0x0004, 0x78ac, 0xd0ac, 0x1de8, 0x78ab, 0x0002,
-	0x7807, 0x0007, 0x7827, 0x0030, 0x782b, 0x0400, 0x7827, 0x0031,
-	0x782b, 0x1a59, 0x781f, 0xff00, 0x781b, 0xb700, 0x2001, 0x0200,
-	0x2004, 0xd0dc, 0x0110, 0x781f, 0x0303, 0x2061, 0x1a59, 0x602f,
-	0x1cd0, 0x2001, 0x1819, 0x2004, 0x9082, 0x1cd0, 0x6032, 0x603b,
-	0x1f33, 0x2001, 0x3145, 0xd0fc, 0x190c, 0x0db4, 0x2001, 0x0003,
-	0x2004, 0xd0d4, 0x1118, 0x783f, 0x3145, 0x0020, 0x9084, 0xc000,
-	0x783f, 0xb145, 0x00ce, 0x0005, 0x0126, 0x2091, 0x2200, 0x7908,
-	0x9184, 0x0070, 0x190c, 0x0dad, 0xd19c, 0x0158, 0x7820, 0x908c,
-	0xf000, 0x15e8, 0x908a, 0x0024, 0x1a0c, 0x0db4, 0x0023, 0x012e,
-	0x0005, 0x012e, 0x0005, 0x1347, 0x1347, 0x135e, 0x1363, 0x1367,
-	0x136c, 0x1394, 0x1398, 0x13a6, 0x13aa, 0x1347, 0x1436, 0x143a,
-	0x149d, 0x1347, 0x1347, 0x1347, 0x1347, 0x1347, 0x1347, 0x1347,
-	0x1347, 0x1347, 0x1347, 0x1347, 0x1347, 0x1347, 0x136e, 0x1347,
-	0x1347, 0x1347, 0x1347, 0x1347, 0x1347, 0x134b, 0x1349, 0x080c,
-	0x0db4, 0x080c, 0x0dad, 0x080c, 0x14a4, 0x2009, 0x1a52, 0x2104,
-	0x8000, 0x200a, 0x080c, 0x79fe, 0x080c, 0x196a, 0x0005, 0x2009,
-	0x0048, 0x2060, 0x080c, 0x9ea9, 0x012e, 0x0005, 0x7004, 0xc085,
-	0xc0b5, 0x7006, 0x0005, 0x7004, 0xc085, 0x7006, 0x0005, 0x080c,
-	0x14a4, 0x080c, 0x15e0, 0x0005, 0x080c, 0x0db4, 0x080c, 0x14a4,
-	0x2060, 0x6014, 0x0096, 0x2048, 0xa83b, 0xffff, 0x009e, 0x2009,
-	0x0048, 0x080c, 0x9ea9, 0x2001, 0x015d, 0x2003, 0x0000, 0x2009,
-	0x03e8, 0x8109, 0x0160, 0x2001, 0x0201, 0x2004, 0x9005, 0x0dc8,
-	0x2001, 0x0218, 0x2004, 0xd0ec, 0x1110, 0x080c, 0x14a9, 0x2001,
-	0x0307, 0x2003, 0x8000, 0x0005, 0x7004, 0xc095, 0x7006, 0x0005,
-	0x080c, 0x14a4, 0x2060, 0x6014, 0x0096, 0x2048, 0xa83b, 0xffff,
-	0x009e, 0x2009, 0x0048, 0x080c, 0x9ea9, 0x0005, 0x080c, 0x14a4,
-	0x080c, 0x0db4, 0x080c, 0x14a4, 0x080c, 0x1421, 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, 0x0db4, 0x2001, 0x020d, 0x2003,
-	0x0050, 0x2003, 0x0020, 0x0490, 0x78ab, 0x0004, 0x7803, 0x0001,
-	0x080c, 0x143a, 0x0005, 0x7828, 0x782b, 0x0000, 0x9065, 0x090c,
-	0x0db4, 0x6014, 0x2048, 0x78ab, 0x0004, 0x918c, 0x0700, 0x01a8,
-	0x080c, 0x79fe, 0x080c, 0x196a, 0x080c, 0xbb3b, 0x0158, 0xa9ac,
-	0xa936, 0xa9b0, 0xa93a, 0xa83f, 0xffff, 0xa843, 0xffff, 0xa880,
-	0xc0bd, 0xa882, 0x080c, 0xb75c, 0x0005, 0x6010, 0x00b6, 0x2058,
-	0xb800, 0x00be, 0xd0bc, 0x6024, 0x190c, 0xbf25, 0x2029, 0x00c8,
-	0x8529, 0x0128, 0x2001, 0x0201, 0x2004, 0x9005, 0x0dc8, 0x7dbc,
-	0x080c, 0xd8c6, 0xd5a4, 0x1118, 0x080c, 0x14a9, 0x0005, 0x080c,
-	0x79fe, 0x080c, 0x196a, 0x0005, 0x781f, 0x0300, 0x7803, 0x0001,
-	0x0005, 0x0016, 0x0066, 0x0076, 0x00f6, 0x2079, 0x0300, 0x7908,
-	0x918c, 0x0007, 0x9186, 0x0003, 0x0120, 0x2001, 0x0016, 0x080c,
-	0x151a, 0x00fe, 0x007e, 0x006e, 0x001e, 0x0005, 0x7004, 0xc09d,
-	0x7006, 0x0005, 0x7104, 0x9184, 0x0004, 0x190c, 0x0db4, 0xd184,
-	0x1189, 0xd19c, 0x0158, 0xc19c, 0x7106, 0x2001, 0x020d, 0x2003,
-	0x0050, 0x2003, 0x0020, 0x080c, 0x14a9, 0x0005, 0x81ff, 0x190c,
-	0x0db4, 0x0005, 0xc184, 0xd1b4, 0xc1b4, 0x7106, 0x0016, 0x00e6,
-	0x15e0, 0x2071, 0x0200, 0x080c, 0x15d4, 0x6014, 0x9005, 0x05a8,
-	0x0096, 0x2048, 0xa864, 0x009e, 0x9084, 0x00ff, 0x908e, 0x0029,
-	0x0160, 0x908e, 0x0048, 0x1548, 0x601c, 0xd084, 0x11d8, 0x00f6,
-	0x2c78, 0x080c, 0x164a, 0x00fe, 0x00a8, 0x00f6, 0x2c78, 0x080c,
-	0x1792, 0x00fe, 0x2009, 0x01f4, 0x8109, 0x0160, 0x2001, 0x0201,
-	0x2004, 0x9005, 0x0dc8, 0x2001, 0x0218, 0x2004, 0xd0ec, 0x1110,
-	0x0401, 0x0040, 0x2001, 0x020d, 0x2003, 0x0020, 0x080c, 0x12c5,
-	0x7803, 0x0001, 0x00ee, 0x001e, 0x0005, 0x2001, 0x020d, 0x2003,
-	0x0050, 0x2003, 0x0020, 0x0069, 0x0ca8, 0x0031, 0x2060, 0x2009,
-	0x0053, 0x080c, 0x9ea9, 0x0005, 0x7808, 0xd09c, 0x0de8, 0x7820,
-	0x0005, 0x080c, 0x1421, 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, 0x150c, 0x6827, 0x0001, 0x8109, 0x1dd0,
-	0x04d9, 0x6827, 0x0002, 0x04c1, 0x6804, 0x9005, 0x1130, 0x682c,
-	0xd0e4, 0x1500, 0x6804, 0x9005, 0x0de8, 0x79b8, 0xd1ec, 0x1130,
-	0x08c0, 0x080c, 0x79fe, 0x080c, 0x196a, 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, 0x130c, 0x00ce, 0x002e,
-	0x001e, 0x000e, 0x0006, 0x7832, 0x7936, 0x7a3a, 0x781b, 0x8080,
-	0x0059, 0x1118, 0x000e, 0x00fe, 0x0005, 0x000e, 0x792c, 0x3900,
-	0x8000, 0x2004, 0x080c, 0x0db4, 0x2009, 0x180c, 0x2104, 0xc0f4,
-	0x200a, 0x2009, 0xff00, 0x8109, 0x0904, 0x1598, 0x7a18, 0x9284,
-	0x0030, 0x0904, 0x1593, 0x9284, 0x0048, 0x9086, 0x0008, 0x1904,
-	0x1593, 0x2001, 0x0109, 0x2004, 0xd08c, 0x01f0, 0x0006, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x0126, 0x2091, 0x2800, 0x00f6,
-	0x0026, 0x0016, 0x2009, 0x1a54, 0x2104, 0x8000, 0x0208, 0x200a,
-	0x080c, 0x83b1, 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, 0x1a55, 0x2104, 0x8000, 0x0208, 0x200a,
-	0x080c, 0x1d57, 0x001e, 0x00fe, 0x015e, 0x014e, 0x013e, 0x01de,
-	0x01ce, 0x012e, 0x000e, 0x7818, 0xd0bc, 0x1904, 0x1543, 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, 0x1a53, 0x2104, 0x8000, 0x0208, 0x200a, 0x080c,
-	0x9445, 0x2009, 0x180c, 0x2104, 0xc0f5, 0x200a, 0x2009, 0xff00,
-	0x0804, 0x1543, 0x9085, 0x0001, 0x0005, 0x7832, 0x7936, 0x7a3a,
-	0x781b, 0x8080, 0x080c, 0x153c, 0x1108, 0x0005, 0x792c, 0x3900,
-	0x8000, 0x2004, 0x080c, 0x0db4, 0x7037, 0x0001, 0x7150, 0x7037,
-	0x0002, 0x7050, 0x2060, 0xd1bc, 0x1110, 0x7054, 0x2060, 0x0005,
-	0x00e6, 0x0016, 0x2071, 0x0200, 0x0c79, 0x6124, 0xd1dc, 0x01f8,
-	0x701c, 0xd08c, 0x0904, 0x163f, 0x7017, 0x0000, 0x2001, 0x0264,
-	0x2004, 0xd0bc, 0x0904, 0x163f, 0x2001, 0x0268, 0x00c6, 0x2064,
-	0x6104, 0x6038, 0x00ce, 0x918e, 0x0039, 0x1904, 0x163f, 0x9c06,
-	0x15f0, 0x0126, 0x2091, 0x2600, 0x080c, 0x7945, 0x012e, 0x7358,
-	0x745c, 0x6014, 0x905d, 0x0598, 0x2b48, 0x6010, 0x00b6, 0x2058,
-	0xb800, 0x00be, 0xd0bc, 0x190c, 0xbf00, 0xab42, 0xac3e, 0x2001,
-	0x187d, 0x2004, 0xd0b4, 0x1170, 0x601c, 0xd0e4, 0x1158, 0x6010,
-	0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x1120, 0xa83b, 0x7fff,
-	0xa837, 0xffff, 0x080c, 0x1f53, 0x1190, 0x080c, 0x17ed, 0x2a00,
-	0xa816, 0x0130, 0x2800, 0xa80e, 0x2c05, 0xa80a, 0x2c00, 0xa812,
-	0x7037, 0x0020, 0x781f, 0x0300, 0x001e, 0x00ee, 0x0005, 0x7037,
-	0x0050, 0x7037, 0x0020, 0x001e, 0x00ee, 0x080c, 0x14a9, 0x0005,
-	0x080c, 0x0db4, 0x0016, 0x2009, 0x00a0, 0x8109, 0xa001, 0xa001,
-	0xa001, 0x1dd8, 0x001e, 0x2ff0, 0x0126, 0x2091, 0x2200, 0x00c6,
-	0x3e60, 0x6014, 0x2048, 0x2940, 0x903e, 0x2730, 0xa864, 0x2068,
-	0xa81a, 0x9d84, 0x000f, 0x9088, 0x1f33, 0x2165, 0x0002, 0x167e,
-	0x16cb, 0x167e, 0x167e, 0x167e, 0x16ad, 0x167e, 0x1682, 0x1677,
-	0x16c2, 0x167e, 0x167e, 0x167e, 0x1787, 0x1696, 0x168c, 0xa964,
-	0x918c, 0x00ff, 0x918e, 0x0048, 0x0904, 0x16c2, 0x9085, 0x0001,
-	0x0804, 0x177e, 0xa87c, 0xd0bc, 0x0dc8, 0xa890, 0xa842, 0xa88c,
-	0xa83e, 0xa888, 0x0804, 0x16d2, 0xa87c, 0xd0bc, 0x0d78, 0xa890,
-	0xa842, 0xa88c, 0xa83e, 0xa888, 0x0804, 0x1721, 0xa87c, 0xd0bc,
-	0x0d28, 0xa890, 0xa842, 0xa88c, 0xa83e, 0xa804, 0x9045, 0x090c,
-	0x0db4, 0xa164, 0xa91a, 0x91ec, 0x000f, 0x9d80, 0x1f33, 0x2065,
-	0xa888, 0xd19c, 0x1904, 0x1721, 0x0428, 0xa87c, 0xd0ac, 0x0970,
-	0xa804, 0x9045, 0x090c, 0x0db4, 0xa164, 0xa91a, 0x91ec, 0x000f,
-	0x9d80, 0x1f33, 0x2065, 0x9006, 0xa842, 0xa83e, 0xd19c, 0x1904,
-	0x1721, 0x0080, 0xa87c, 0xd0ac, 0x0904, 0x167e, 0x9006, 0xa842,
-	0xa83e, 0x0804, 0x1721, 0xa87c, 0xd0ac, 0x0904, 0x167e, 0x9006,
-	0xa842, 0xa83e, 0x2c05, 0x908a, 0x0036, 0x1a0c, 0x0db4, 0x9082,
-	0x001b, 0x0002, 0x16f5, 0x16f5, 0x16f7, 0x16f5, 0x16f5, 0x16f5,
-	0x16fd, 0x16f5, 0x16f5, 0x16f5, 0x1703, 0x16f5, 0x16f5, 0x16f5,
-	0x1709, 0x16f5, 0x16f5, 0x16f5, 0x170f, 0x16f5, 0x16f5, 0x16f5,
-	0x1715, 0x16f5, 0x16f5, 0x16f5, 0x171b, 0x080c, 0x0db4, 0xa574,
-	0xa478, 0xa37c, 0xa280, 0x0804, 0x1766, 0xa584, 0xa488, 0xa38c,
-	0xa290, 0x0804, 0x1766, 0xa594, 0xa498, 0xa39c, 0xa2a0, 0x0804,
-	0x1766, 0xa5a4, 0xa4a8, 0xa3ac, 0xa2b0, 0x0804, 0x1766, 0xa5b4,
-	0xa4b8, 0xa3bc, 0xa2c0, 0x0804, 0x1766, 0xa5c4, 0xa4c8, 0xa3cc,
-	0xa2d0, 0x0804, 0x1766, 0xa5d4, 0xa4d8, 0xa3dc, 0xa2e0, 0x0804,
-	0x1766, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0db4, 0x9082, 0x001b,
-	0x0002, 0x1744, 0x1742, 0x1742, 0x1742, 0x1742, 0x1742, 0x174b,
-	0x1742, 0x1742, 0x1742, 0x1742, 0x1742, 0x1752, 0x1742, 0x1742,
-	0x1742, 0x1742, 0x1742, 0x1759, 0x1742, 0x1742, 0x1742, 0x1742,
-	0x1742, 0x1760, 0x080c, 0x0db4, 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, 0x1158, 0x3e60, 0x601c,
-	0xc085, 0x601e, 0xa87c, 0xc0dd, 0xa87e, 0x9006, 0x00ce, 0x012e,
-	0x0005, 0x2800, 0xa80e, 0xab0a, 0x2c00, 0xa812, 0x0c78, 0x0804,
-	0x167e, 0x0016, 0x2009, 0x00a0, 0x8109, 0xa001, 0xa001, 0xa001,
-	0x1dd8, 0x001e, 0x2ff0, 0x0126, 0x2091, 0x2200, 0x00c6, 0x3e60,
-	0x6014, 0x2048, 0x2940, 0xa80e, 0x2061, 0x1f2e, 0xa813, 0x1f2e,
-	0x2c05, 0xa80a, 0xa964, 0xa91a, 0xa87c, 0xd0ac, 0x090c, 0x0db4,
-	0x9006, 0xa842, 0xa83e, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0db4,
-	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, 0x0078, 0x918a, 0x0002, 0xa916, 0x1158, 0x3e60,
-	0x601c, 0xc085, 0x601e, 0xa87c, 0xc0dd, 0xa87e, 0x9006, 0x00ce,
-	0x012e, 0x0005, 0xa804, 0x9045, 0x090c, 0x0db4, 0xa80e, 0xa064,
-	0xa81a, 0x9084, 0x000f, 0x9080, 0x1f33, 0x2015, 0x82ff, 0x090c,
-	0x0db4, 0xaa12, 0x2205, 0xa80a, 0x0c10, 0x903e, 0x2730, 0xa880,
-	0xd0fc, 0x1190, 0x2d00, 0x0002, 0x18e2, 0x1844, 0x1844, 0x18e2,
-	0x18e2, 0x18dc, 0x18e2, 0x1844, 0x1893, 0x1893, 0x1893, 0x18e2,
-	0x18e2, 0x18e2, 0x18d9, 0x1893, 0xc0fc, 0xa882, 0xab2c, 0xaa30,
-	0xad1c, 0xac20, 0xdd9c, 0x0904, 0x18e4, 0x2c05, 0x908a, 0x0034,
-	0x1a0c, 0x0db4, 0x9082, 0x001b, 0x0002, 0x1830, 0x182e, 0x182e,
-	0x182e, 0x182e, 0x182e, 0x1834, 0x182e, 0x182e, 0x182e, 0x182e,
-	0x182e, 0x1838, 0x182e, 0x182e, 0x182e, 0x182e, 0x182e, 0x183c,
-	0x182e, 0x182e, 0x182e, 0x182e, 0x182e, 0x1840, 0x080c, 0x0db4,
-	0xa774, 0xa678, 0x0804, 0x18e4, 0xa78c, 0xa690, 0x0804, 0x18e4,
-	0xa7a4, 0xa6a8, 0x0804, 0x18e4, 0xa7bc, 0xa6c0, 0x0804, 0x18e4,
-	0xa7d4, 0xa6d8, 0x0804, 0x18e4, 0x2c05, 0x908a, 0x0036, 0x1a0c,
-	0x0db4, 0x9082, 0x001b, 0x0002, 0x1867, 0x1867, 0x1869, 0x1867,
-	0x1867, 0x1867, 0x186f, 0x1867, 0x1867, 0x1867, 0x1875, 0x1867,
-	0x1867, 0x1867, 0x187b, 0x1867, 0x1867, 0x1867, 0x1881, 0x1867,
-	0x1867, 0x1867, 0x1887, 0x1867, 0x1867, 0x1867, 0x188d, 0x080c,
-	0x0db4, 0xa574, 0xa478, 0xa37c, 0xa280, 0x0804, 0x18e4, 0xa584,
-	0xa488, 0xa38c, 0xa290, 0x0804, 0x18e4, 0xa594, 0xa498, 0xa39c,
-	0xa2a0, 0x0804, 0x18e4, 0xa5a4, 0xa4a8, 0xa3ac, 0xa2b0, 0x0804,
-	0x18e4, 0xa5b4, 0xa4b8, 0xa3bc, 0xa2c0, 0x0804, 0x18e4, 0xa5c4,
-	0xa4c8, 0xa3cc, 0xa2d0, 0x0804, 0x18e4, 0xa5d4, 0xa4d8, 0xa3dc,
-	0xa2e0, 0x0804, 0x18e4, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0db4,
-	0x9082, 0x001b, 0x0002, 0x18b6, 0x18b4, 0x18b4, 0x18b4, 0x18b4,
-	0x18b4, 0x18bd, 0x18b4, 0x18b4, 0x18b4, 0x18b4, 0x18b4, 0x18c4,
-	0x18b4, 0x18b4, 0x18b4, 0x18b4, 0x18b4, 0x18cb, 0x18b4, 0x18b4,
-	0x18b4, 0x18b4, 0x18b4, 0x18d2, 0x080c, 0x0db4, 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, 0x1eeb, 0x1904, 0x17ed,
-	0x900e, 0x0050, 0x080c, 0x0db4, 0xab2e, 0xaa32, 0xad1e, 0xac22,
-	0xaf26, 0xae2a, 0x080c, 0x1eeb, 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, 0x9ea9, 0x0005, 0xa974, 0xd1dc, 0x1108, 0x0005, 0xa934,
-	0xa88c, 0x9106, 0x1158, 0xa938, 0xa890, 0x9106, 0x1138, 0x601c,
-	0xc084, 0x601e, 0x2009, 0x0048, 0x0804, 0x9ea9, 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, 0x130c, 0x8631, 0x1db8, 0x00ce, 0x781f, 0x0800,
-	0x2031, 0x0168, 0x00c6, 0x7808, 0xd09c, 0x190c, 0x130c, 0x00ce,
-	0x2001, 0x0038, 0x080c, 0x19f2, 0x7930, 0x9186, 0x0040, 0x0160,
-	0x9186, 0x0042, 0x190c, 0x0db4, 0x2001, 0x001e, 0x8001, 0x1df0,
-	0x8631, 0x1d40, 0x080c, 0x1a01, 0x000e, 0x6022, 0x012e, 0x0005,
-	0x080c, 0x19ee, 0x7827, 0x0015, 0x7828, 0x9c06, 0x1db8, 0x782b,
-	0x0000, 0x0ca0, 0x00f6, 0x2079, 0x0300, 0x7803, 0x0000, 0x78ab,
-	0x0004, 0x00fe, 0x080c, 0x6faa, 0x1188, 0x2001, 0x0138, 0x2003,
-	0x0000, 0x2001, 0x0160, 0x2003, 0x0000, 0x2011, 0x012c, 0xa001,
-	0xa001, 0x8211, 0x1de0, 0x0059, 0x0804, 0x705a, 0x0479, 0x0039,
-	0x2001, 0x0160, 0x2502, 0x2001, 0x0138, 0x2202, 0x0005, 0x00e6,
-	0x2071, 0x0200, 0x080c, 0x2a76, 0x2009, 0x003c, 0x080c, 0x2275,
-	0x2001, 0x015d, 0x2003, 0x0000, 0x7000, 0x9084, 0x003c, 0x1de0,
-	0x080c, 0x7f64, 0x70a0, 0x70a2, 0x7098, 0x709a, 0x709c, 0x709e,
-	0x2001, 0x020d, 0x2003, 0x0020, 0x00f6, 0x2079, 0x0300, 0x080c,
-	0x12c5, 0x7803, 0x0001, 0x00fe, 0x00ee, 0x0005, 0x2001, 0x0138,
-	0x2014, 0x2003, 0x0000, 0x2001, 0x0160, 0x202c, 0x2003, 0x0000,
-	0x080c, 0x6faa, 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, 0x151a, 0x7930, 0x0005,
-	0x2c08, 0x621c, 0x080c, 0x15c5, 0x7930, 0x0005, 0x8001, 0x1df0,
-	0x0005, 0x2031, 0x0005, 0x781c, 0x9084, 0x0007, 0x0170, 0x2001,
-	0x0038, 0x0c41, 0x9186, 0x0040, 0x0904, 0x1a5f, 0x2001, 0x001e,
-	0x0c69, 0x8631, 0x1d80, 0x080c, 0x0db4, 0x781f, 0x0202, 0x2001,
-	0x015d, 0x2003, 0x0000, 0x2001, 0x0b10, 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, 0x19f8, 0x9186, 0x0040, 0x190c, 0x0db4, 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, 0x0db4, 0xa001, 0xa001, 0x781f, 0x0200, 0x0005,
-	0x0126, 0x2091, 0x2400, 0x2071, 0x1a3d, 0x2079, 0x0090, 0x012e,
-	0x0005, 0x9280, 0x0005, 0x2004, 0x2048, 0xa97c, 0xd1dc, 0x1904,
-	0x1af4, 0xa964, 0x9184, 0x0007, 0x0002, 0x1a7d, 0x1adf, 0x1a94,
-	0x1a94, 0x1a94, 0x1ac7, 0x1aa7, 0x1a96, 0x918c, 0x00ff, 0x9186,
-	0x0008, 0x1170, 0xa87c, 0xd0b4, 0x0904, 0x1d12, 0x9006, 0xa842,
-	0xa83e, 0xa988, 0x2900, 0xa85a, 0xa813, 0x1f2e, 0x0804, 0x1af0,
-	0x9186, 0x0048, 0x0904, 0x1adf, 0x080c, 0x0db4, 0xa87c, 0xd0b4,
-	0x0904, 0x1d12, 0xa890, 0xa842, 0xa83a, 0xa88c, 0xa83e, 0xa836,
-	0xa8ac, 0xa846, 0xa8b0, 0xa84a, 0xa988, 0x0804, 0x1ae7, 0xa864,
-	0x9084, 0x00ff, 0x9086, 0x001e, 0x1d38, 0xa87c, 0xd0b4, 0x0904,
-	0x1d12, 0xa890, 0xa842, 0xa83a, 0xa88c, 0xa83e, 0xa836, 0xa8ac,
-	0xa846, 0xa8b0, 0xa84a, 0xa804, 0xa85a, 0x2040, 0xa064, 0x9084,
-	0x000f, 0x9080, 0x1f33, 0x2005, 0xa812, 0xa988, 0x0448, 0x918c,
-	0x00ff, 0x9186, 0x0015, 0x1540, 0xa87c, 0xd0b4, 0x0904, 0x1d12,
-	0xa804, 0xa85a, 0x2040, 0xa064, 0x9084, 0x000f, 0x9080, 0x1f33,
-	0x2005, 0xa812, 0xa988, 0x9006, 0xa842, 0xa83e, 0x0088, 0xa87c,
-	0xd0b4, 0x0904, 0x1d12, 0xa988, 0x9006, 0xa842, 0xa83e, 0x2900,
-	0xa85a, 0xa864, 0x9084, 0x000f, 0x9080, 0x1f33, 0x2005, 0xa812,
-	0xa916, 0xa87c, 0xc0dd, 0xa87e, 0x0005, 0x00f6, 0x2079, 0x0090,
-	0x782c, 0xd0fc, 0x190c, 0x1d57, 0x00e6, 0x2071, 0x1a3d, 0x7000,
-	0x9005, 0x1904, 0x1b5d, 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, 0x1f53, 0x004e, 0x003e,
-	0x0d30, 0x0c98, 0x9085, 0x0001, 0x0c80, 0x2009, 0x0306, 0x200b,
-	0x4800, 0x7027, 0x0000, 0x0005, 0x0076, 0x0066, 0x0056, 0x0046,
-	0x0036, 0x0026, 0x8aff, 0x0904, 0x1d0b, 0x700c, 0x7214, 0x923a,
-	0x7010, 0x7218, 0x9203, 0x0a04, 0x1d0a, 0x9705, 0x0904, 0x1d0a,
-	0x903e, 0x2730, 0xa880, 0xd0fc, 0x1190, 0x2d00, 0x0002, 0x1c9f,
-	0x1bdf, 0x1bdf, 0x1c9f, 0x1c9f, 0x1c7c, 0x1c9f, 0x1bdf, 0x1c83,
-	0x1c2e, 0x1c2e, 0x1c9f, 0x1c9f, 0x1c9f, 0x1c76, 0x1c2e, 0xc0fc,
-	0xa882, 0xab2c, 0xaa30, 0xad1c, 0xac20, 0xdd9c, 0x0904, 0x1ca1,
-	0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0db4, 0x9082, 0x001b, 0x0002,
-	0x1bcb, 0x1bc9, 0x1bc9, 0x1bc9, 0x1bc9, 0x1bc9, 0x1bcf, 0x1bc9,
-	0x1bc9, 0x1bc9, 0x1bc9, 0x1bc9, 0x1bd3, 0x1bc9, 0x1bc9, 0x1bc9,
-	0x1bc9, 0x1bc9, 0x1bd7, 0x1bc9, 0x1bc9, 0x1bc9, 0x1bc9, 0x1bc9,
-	0x1bdb, 0x080c, 0x0db4, 0xa774, 0xa678, 0x0804, 0x1ca1, 0xa78c,
-	0xa690, 0x0804, 0x1ca1, 0xa7a4, 0xa6a8, 0x0804, 0x1ca1, 0xa7bc,
-	0xa6c0, 0x0804, 0x1ca1, 0xa7d4, 0xa6d8, 0x0804, 0x1ca1, 0x2c05,
-	0x908a, 0x0036, 0x1a0c, 0x0db4, 0x9082, 0x001b, 0x0002, 0x1c02,
-	0x1c02, 0x1c04, 0x1c02, 0x1c02, 0x1c02, 0x1c0a, 0x1c02, 0x1c02,
-	0x1c02, 0x1c10, 0x1c02, 0x1c02, 0x1c02, 0x1c16, 0x1c02, 0x1c02,
-	0x1c02, 0x1c1c, 0x1c02, 0x1c02, 0x1c02, 0x1c22, 0x1c02, 0x1c02,
-	0x1c02, 0x1c28, 0x080c, 0x0db4, 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, 0x0db4, 0x9082, 0x001b, 0x0002, 0x1c51, 0x1c4f,
-	0x1c4f, 0x1c4f, 0x1c4f, 0x1c4f, 0x1c59, 0x1c4f, 0x1c4f, 0x1c4f,
-	0x1c4f, 0x1c4f, 0x1c61, 0x1c4f, 0x1c4f, 0x1c4f, 0x1c4f, 0x1c4f,
-	0x1c68, 0x1c4f, 0x1c4f, 0x1c4f, 0x1c4f, 0x1c4f, 0x1c6f, 0x080c,
-	0x0db4, 0xa56c, 0xa470, 0xa774, 0xa678, 0xa37c, 0xa280, 0x0804,
-	0x1ca1, 0xa584, 0xa488, 0xa78c, 0xa690, 0xa394, 0xa298, 0x0804,
-	0x1ca1, 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, 0x1eeb, 0x1904, 0x1b7a,
-	0x900e, 0x0804, 0x1d0b, 0xab64, 0x939c, 0x00ff, 0x9386, 0x0048,
-	0x1180, 0x00c6, 0x7004, 0x2060, 0x6004, 0x9086, 0x0043, 0x00ce,
-	0x0904, 0x1c2e, 0xab9c, 0x9016, 0xad8c, 0xac90, 0xaf94, 0xae98,
-	0x0040, 0x9386, 0x0008, 0x0904, 0x1c2e, 0x080c, 0x0db4, 0x080c,
-	0x0db4, 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, 0x1eeb, 0x0428, 0x2031, 0x0080,
-	0x9584, 0x007f, 0x0108, 0x9632, 0x7124, 0x7000, 0x9086, 0x0000,
-	0x1198, 0xc185, 0x7126, 0x2009, 0x0306, 0x2104, 0xd0b4, 0x1904,
-	0x1cb1, 0x200b, 0x4040, 0x2009, 0x1a56, 0x2104, 0x8000, 0x0a04,
-	0x1cb1, 0x200a, 0x0804, 0x1cb1, 0xc18d, 0x7126, 0xd184, 0x1d58,
-	0x0804, 0x1cb1, 0x9006, 0x002e, 0x003e, 0x004e, 0x005e, 0x006e,
-	0x007e, 0x0005, 0x080c, 0x0db4, 0x0026, 0x2001, 0x0105, 0x2003,
-	0x0010, 0x782b, 0x0004, 0x7003, 0x0000, 0x7004, 0x0016, 0x080c,
-	0x1b6d, 0x001e, 0x2060, 0x6014, 0x2048, 0x080c, 0xbb3b, 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, 0xb75c, 0x00ce, 0x2001, 0x19ce, 0x2004, 0x9c06, 0x1160,
-	0x2009, 0x0040, 0x080c, 0x2275, 0x080c, 0x98d4, 0x2011, 0x0000,
-	0x080c, 0x9765, 0x080c, 0x8a68, 0x002e, 0x0804, 0x1e9b, 0x0126,
-	0x2091, 0x2400, 0xa858, 0x2040, 0x792c, 0x782b, 0x0002, 0x9184,
-	0x0700, 0x1904, 0x1d14, 0x7000, 0x0002, 0x1e9b, 0x1d69, 0x1de9,
-	0x1e99, 0x8001, 0x7002, 0x7027, 0x0000, 0xd19c, 0x1158, 0x8aff,
-	0x0904, 0x1db6, 0x080c, 0x1b74, 0x0904, 0x1e9b, 0x080c, 0x1b74,
-	0x0804, 0x1e9b, 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, 0x1f06, 0xa880, 0xc0fd, 0xa882, 0x2a00, 0xa816,
-	0x2800, 0xa85a, 0x2c00, 0xa812, 0x7003, 0x0000, 0x2009, 0x0306,
-	0x200b, 0x4800, 0x7027, 0x0000, 0x0804, 0x1e9b, 0x00f6, 0x0026,
-	0x781c, 0x0006, 0x7818, 0x0006, 0x2079, 0x0100, 0x7a14, 0x9284,
-	0x1984, 0x9085, 0x0012, 0x7816, 0x0036, 0x2019, 0x1000, 0x8319,
-	0x090c, 0x0db4, 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, 0x1b6d, 0x0804,
-	0x1e9b, 0x8001, 0x7002, 0x7024, 0x8004, 0x7026, 0xd194, 0x0170,
-	0x782c, 0xd0fc, 0x1904, 0x1d5c, 0xd19c, 0x1904, 0x1e97, 0x8aff,
-	0x0904, 0x1e9b, 0x080c, 0x1b74, 0x0804, 0x1e9b, 0x0026, 0x0036,
-	0xab3c, 0xaa40, 0x080c, 0x1f06, 0xdd9c, 0x1904, 0x1e56, 0x2c05,
-	0x908a, 0x0036, 0x1a0c, 0x0db4, 0x9082, 0x001b, 0x0002, 0x1e2a,
-	0x1e2a, 0x1e2c, 0x1e2a, 0x1e2a, 0x1e2a, 0x1e32, 0x1e2a, 0x1e2a,
-	0x1e2a, 0x1e38, 0x1e2a, 0x1e2a, 0x1e2a, 0x1e3e, 0x1e2a, 0x1e2a,
-	0x1e2a, 0x1e44, 0x1e2a, 0x1e2a, 0x1e2a, 0x1e4a, 0x1e2a, 0x1e2a,
-	0x1e2a, 0x1e50, 0x080c, 0x0db4, 0xa07c, 0x931a, 0xa080, 0x9213,
-	0x0804, 0x1d8b, 0xa08c, 0x931a, 0xa090, 0x9213, 0x0804, 0x1d8b,
-	0xa09c, 0x931a, 0xa0a0, 0x9213, 0x0804, 0x1d8b, 0xa0ac, 0x931a,
-	0xa0b0, 0x9213, 0x0804, 0x1d8b, 0xa0bc, 0x931a, 0xa0c0, 0x9213,
-	0x0804, 0x1d8b, 0xa0cc, 0x931a, 0xa0d0, 0x9213, 0x0804, 0x1d8b,
-	0xa0dc, 0x931a, 0xa0e0, 0x9213, 0x0804, 0x1d8b, 0x2c05, 0x908a,
-	0x0034, 0x1a0c, 0x0db4, 0x9082, 0x001b, 0x0002, 0x1e79, 0x1e77,
-	0x1e77, 0x1e77, 0x1e77, 0x1e77, 0x1e7f, 0x1e77, 0x1e77, 0x1e77,
-	0x1e77, 0x1e77, 0x1e85, 0x1e77, 0x1e77, 0x1e77, 0x1e77, 0x1e77,
-	0x1e8b, 0x1e77, 0x1e77, 0x1e77, 0x1e77, 0x1e77, 0x1e91, 0x080c,
-	0x0db4, 0xa07c, 0x931a, 0xa080, 0x9213, 0x0804, 0x1d8b, 0xa094,
-	0x931a, 0xa098, 0x9213, 0x0804, 0x1d8b, 0xa0ac, 0x931a, 0xa0b0,
-	0x9213, 0x0804, 0x1d8b, 0xa0c4, 0x931a, 0xa0c8, 0x9213, 0x0804,
-	0x1d8b, 0xa0dc, 0x931a, 0xa0e0, 0x9213, 0x0804, 0x1d8b, 0x0804,
-	0x1d87, 0x080c, 0x0db4, 0x012e, 0x0005, 0x00f6, 0x00e6, 0x2071,
-	0x1a3d, 0x7000, 0x9086, 0x0000, 0x0904, 0x1ee6, 0x2079, 0x0090,
-	0x2009, 0x0207, 0x210c, 0xd194, 0x01b8, 0x2009, 0x020c, 0x210c,
-	0x9184, 0x0003, 0x0188, 0x080c, 0xd90f, 0x2001, 0x0133, 0x2004,
-	0x9005, 0x090c, 0x0db4, 0x0016, 0x2009, 0x0040, 0x080c, 0x2275,
-	0x001e, 0x2001, 0x020c, 0x2102, 0x2009, 0x0206, 0x2104, 0x2009,
-	0x0203, 0x210c, 0x9106, 0x1120, 0x2009, 0x0040, 0x080c, 0x2275,
-	0x782c, 0xd0fc, 0x09a8, 0x080c, 0x1d57, 0x7000, 0x9086, 0x0000,
-	0x1978, 0x782b, 0x0004, 0x782c, 0xd0ac, 0x1de8, 0x2009, 0x0040,
-	0x080c, 0x2275, 0x782b, 0x0002, 0x7003, 0x0000, 0x080c, 0x1b6d,
-	0x00ee, 0x00fe, 0x0005, 0xa880, 0xd0fc, 0x11a8, 0x8c60, 0x2c05,
-	0x9005, 0x0110, 0x8a51, 0x0005, 0xa004, 0x9005, 0x0168, 0xa85a,
-	0x2040, 0xa064, 0x9084, 0x000f, 0x9080, 0x1f33, 0x2065, 0x8cff,
-	0x090c, 0x0db4, 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, 0x1f43, 0x2065, 0x8cff, 0x090c, 0x0db4,
-	0x0005, 0x0000, 0x001d, 0x0021, 0x0025, 0x0029, 0x002d, 0x0031,
-	0x0035, 0x0000, 0x001b, 0x0021, 0x0027, 0x002d, 0x0033, 0x0000,
-	0x0000, 0x0023, 0x0000, 0x0000, 0x1f26, 0x1f22, 0x0000, 0x0000,
-	0x1f30, 0x0000, 0x1f26, 0x1f2d, 0x1f2d, 0x1f2a, 0x0000, 0x0000,
-	0x0000, 0x1f30, 0x1f2d, 0x0000, 0x1f28, 0x1f28, 0x0000, 0x0000,
-	0x1f30, 0x0000, 0x1f28, 0x1f2e, 0x1f2e, 0x1f2e, 0x0000, 0x0000,
-	0x0000, 0x1f30, 0x1f2e, 0x00c6, 0x00d6, 0x0086, 0xab42, 0xac3e,
-	0xa888, 0x9055, 0x0904, 0x2132, 0x2940, 0xa064, 0x90ec, 0x000f,
-	0x9084, 0x00ff, 0x9086, 0x0008, 0x1118, 0x2061, 0x1f2e, 0x00d0,
-	0x9de0, 0x1f33, 0x9d86, 0x0007, 0x0130, 0x9d86, 0x000e, 0x0118,
-	0x9d86, 0x000f, 0x1120, 0xa08c, 0x9422, 0xa090, 0x931b, 0x2c05,
-	0x9065, 0x1140, 0x0310, 0x0804, 0x2132, 0xa004, 0x9045, 0x0904,
-	0x2132, 0x08d8, 0x2c05, 0x9005, 0x0904, 0x201a, 0xdd9c, 0x1904,
-	0x1fd6, 0x908a, 0x0036, 0x1a0c, 0x0db4, 0x9082, 0x001b, 0x0002,
-	0x1fab, 0x1fab, 0x1fad, 0x1fab, 0x1fab, 0x1fab, 0x1fb3, 0x1fab,
-	0x1fab, 0x1fab, 0x1fb9, 0x1fab, 0x1fab, 0x1fab, 0x1fbf, 0x1fab,
-	0x1fab, 0x1fab, 0x1fc5, 0x1fab, 0x1fab, 0x1fab, 0x1fcb, 0x1fab,
-	0x1fab, 0x1fab, 0x1fd1, 0x080c, 0x0db4, 0xa07c, 0x9422, 0xa080,
-	0x931b, 0x0804, 0x2010, 0xa08c, 0x9422, 0xa090, 0x931b, 0x0804,
-	0x2010, 0xa09c, 0x9422, 0xa0a0, 0x931b, 0x0804, 0x2010, 0xa0ac,
-	0x9422, 0xa0b0, 0x931b, 0x0804, 0x2010, 0xa0bc, 0x9422, 0xa0c0,
-	0x931b, 0x0804, 0x2010, 0xa0cc, 0x9422, 0xa0d0, 0x931b, 0x0804,
-	0x2010, 0xa0dc, 0x9422, 0xa0e0, 0x931b, 0x04d0, 0x908a, 0x0034,
-	0x1a0c, 0x0db4, 0x9082, 0x001b, 0x0002, 0x1ff8, 0x1ff6, 0x1ff6,
-	0x1ff6, 0x1ff6, 0x1ff6, 0x1ffd, 0x1ff6, 0x1ff6, 0x1ff6, 0x1ff6,
-	0x1ff6, 0x2002, 0x1ff6, 0x1ff6, 0x1ff6, 0x1ff6, 0x1ff6, 0x2007,
-	0x1ff6, 0x1ff6, 0x1ff6, 0x1ff6, 0x1ff6, 0x200c, 0x080c, 0x0db4,
-	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, 0x2132, 0x8c60,
-	0x0804, 0x1f82, 0xa004, 0x9045, 0x0904, 0x2132, 0x0804, 0x1f5d,
-	0x8a51, 0x0904, 0x2132, 0x8c60, 0x2c05, 0x9005, 0x1158, 0xa004,
-	0x9045, 0x0904, 0x2132, 0xa064, 0x90ec, 0x000f, 0x9de0, 0x1f33,
-	0x2c05, 0x2060, 0xa880, 0xc0fc, 0xa882, 0x0804, 0x2127, 0x2c05,
-	0x8422, 0x8420, 0x831a, 0x9399, 0x0000, 0xac2e, 0xab32, 0xdd9c,
-	0x1904, 0x20c4, 0x9082, 0x001b, 0x0002, 0x2060, 0x2060, 0x2062,
-	0x2060, 0x2060, 0x2060, 0x2070, 0x2060, 0x2060, 0x2060, 0x207e,
-	0x2060, 0x2060, 0x2060, 0x208c, 0x2060, 0x2060, 0x2060, 0x209a,
-	0x2060, 0x2060, 0x2060, 0x20a8, 0x2060, 0x2060, 0x2060, 0x20b6,
-	0x080c, 0x0db4, 0xa17c, 0x2400, 0x9122, 0xa180, 0x2300, 0x911b,
-	0x0a0c, 0x0db4, 0xa074, 0x9420, 0xa078, 0x9319, 0x0804, 0x2122,
-	0xa18c, 0x2400, 0x9122, 0xa190, 0x2300, 0x911b, 0x0a0c, 0x0db4,
-	0xa084, 0x9420, 0xa088, 0x9319, 0x0804, 0x2122, 0xa19c, 0x2400,
-	0x9122, 0xa1a0, 0x2300, 0x911b, 0x0a0c, 0x0db4, 0xa094, 0x9420,
-	0xa098, 0x9319, 0x0804, 0x2122, 0xa1ac, 0x2400, 0x9122, 0xa1b0,
-	0x2300, 0x911b, 0x0a0c, 0x0db4, 0xa0a4, 0x9420, 0xa0a8, 0x9319,
-	0x0804, 0x2122, 0xa1bc, 0x2400, 0x9122, 0xa1c0, 0x2300, 0x911b,
-	0x0a0c, 0x0db4, 0xa0b4, 0x9420, 0xa0b8, 0x9319, 0x0804, 0x2122,
-	0xa1cc, 0x2400, 0x9122, 0xa1d0, 0x2300, 0x911b, 0x0a0c, 0x0db4,
-	0xa0c4, 0x9420, 0xa0c8, 0x9319, 0x0804, 0x2122, 0xa1dc, 0x2400,
-	0x9122, 0xa1e0, 0x2300, 0x911b, 0x0a0c, 0x0db4, 0xa0d4, 0x9420,
-	0xa0d8, 0x9319, 0x0804, 0x2122, 0x9082, 0x001b, 0x0002, 0x20e2,
-	0x20e0, 0x20e0, 0x20e0, 0x20e0, 0x20e0, 0x20ef, 0x20e0, 0x20e0,
-	0x20e0, 0x20e0, 0x20e0, 0x20fc, 0x20e0, 0x20e0, 0x20e0, 0x20e0,
-	0x20e0, 0x2109, 0x20e0, 0x20e0, 0x20e0, 0x20e0, 0x20e0, 0x2116,
-	0x080c, 0x0db4, 0xa17c, 0x2400, 0x9122, 0xa180, 0x2300, 0x911b,
-	0x0a0c, 0x0db4, 0xa06c, 0x9420, 0xa070, 0x9319, 0x0498, 0xa194,
-	0x2400, 0x9122, 0xa198, 0x2300, 0x911b, 0x0a0c, 0x0db4, 0xa084,
-	0x9420, 0xa088, 0x9319, 0x0430, 0xa1ac, 0x2400, 0x9122, 0xa1b0,
-	0x2300, 0x911b, 0x0a0c, 0x0db4, 0xa09c, 0x9420, 0xa0a0, 0x9319,
-	0x00c8, 0xa1c4, 0x2400, 0x9122, 0xa1c8, 0x2300, 0x911b, 0x0a0c,
-	0x0db4, 0xa0b4, 0x9420, 0xa0b8, 0x9319, 0x0060, 0xa1dc, 0x2400,
-	0x9122, 0xa1e0, 0x2300, 0x911b, 0x0a0c, 0x0db4, 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, 0x0dad, 0x9084, 0x0007,
-	0x0002, 0x2153, 0x1d57, 0x2153, 0x2149, 0x214c, 0x214f, 0x214c,
-	0x214f, 0x080c, 0x1d57, 0x0005, 0x080c, 0x118f, 0x0005, 0x080c,
-	0x1d57, 0x080c, 0x118f, 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,
-	0x2272, 0x7900, 0xd1dc, 0x1118, 0x9084, 0x0006, 0x001a, 0x9084,
-	0x000e, 0x0002, 0x219a, 0x2192, 0x7945, 0x2192, 0x2194, 0x2194,
-	0x2194, 0x2194, 0x792b, 0x2192, 0x2196, 0x2192, 0x2194, 0x2192,
-	0x2194, 0x2192, 0x080c, 0x0db4, 0x0031, 0x0020, 0x080c, 0x792b,
-	0x080c, 0x7945, 0x0005, 0x0006, 0x0016, 0x0026, 0x080c, 0xd90f,
-	0x7930, 0x9184, 0x0003, 0x01c0, 0x2001, 0x19ce, 0x2004, 0x9005,
-	0x0170, 0x2001, 0x0133, 0x2004, 0x9005, 0x090c, 0x0db4, 0x00c6,
-	0x2001, 0x19ce, 0x2064, 0x080c, 0xb75c, 0x00ce, 0x00f8, 0x2009,
-	0x0040, 0x080c, 0x2275, 0x00d0, 0x9184, 0x0014, 0x01a0, 0x6a00,
-	0x9286, 0x0003, 0x0160, 0x080c, 0x6faa, 0x1138, 0x080c, 0x728c,
-	0x080c, 0x5ce5, 0x080c, 0x6edc, 0x0010, 0x080c, 0x5ba4, 0x080c,
-	0x79f4, 0x0041, 0x0018, 0x9184, 0x9540, 0x1dc8, 0x002e, 0x001e,
-	0x000e, 0x0005, 0x00e6, 0x0036, 0x0046, 0x0056, 0x2071, 0x1a3a,
-	0x080c, 0x196a, 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, 0x0dad, 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, 0x2a70, 0x080c, 0x298b, 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,
-	0x29cf, 0x1238, 0x939d, 0x4003, 0x94a5, 0x8603, 0x230a, 0x2412,
-	0x0030, 0x939d, 0x0203, 0x94a5, 0x8603, 0x230a, 0x2412, 0x9006,
-	0x080c, 0x29ba, 0x9006, 0x080c, 0x299d, 0x20a9, 0x0012, 0x1d04,
-	0x22c7, 0x2091, 0x6000, 0x1f04, 0x22c7, 0x602f, 0x0100, 0x602f,
-	0x0000, 0x6050, 0x9085, 0x0400, 0x9084, 0xdfff, 0x6052, 0x6024,
-	0x6026, 0x080c, 0x26a9, 0x2009, 0x00ef, 0x6132, 0x6136, 0x080c,
-	0x26b9, 0x60e7, 0x0000, 0x61ea, 0x60e3, 0x0002, 0x604b, 0xf7f7,
-	0x6043, 0x0000, 0x602f, 0x0080, 0x602f, 0x0000, 0x6007, 0x149f,
-	0x60bb, 0x0000, 0x20a9, 0x0018, 0x60bf, 0x0000, 0x1f04, 0x22f4,
-	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, 0x2354, 0x233a, 0x233d, 0x2340, 0x2345, 0x2347,
-	0x234b, 0x234f, 0x080c, 0x82e4, 0x00b8, 0x080c, 0x83b1, 0x00a0,
-	0x080c, 0x83b1, 0x080c, 0x82e4, 0x0078, 0x0099, 0x0068, 0x080c,
-	0x82e4, 0x0079, 0x0048, 0x080c, 0x83b1, 0x0059, 0x0028, 0x080c,
-	0x83b1, 0x080c, 0x82e4, 0x0029, 0x002e, 0x001e, 0x000e, 0x012e,
-	0x0005, 0x00a6, 0x6124, 0x6028, 0xd09c, 0x0118, 0xd19c, 0x1904,
-	0x25a2, 0xd1f4, 0x190c, 0x0dad, 0x080c, 0x6faa, 0x0904, 0x23af,
-	0x080c, 0xc23b, 0x1120, 0x7000, 0x9086, 0x0003, 0x0570, 0x6024,
-	0x9084, 0x1800, 0x0550, 0x080c, 0x6fcd, 0x0118, 0x080c, 0x6fbb,
-	0x1520, 0x6027, 0x0020, 0x6043, 0x0000, 0x080c, 0xc23b, 0x0168,
-	0x080c, 0x6fcd, 0x1150, 0x2001, 0x197f, 0x2003, 0x0001, 0x6027,
-	0x1800, 0x080c, 0x6e2b, 0x0804, 0x25a5, 0x70a0, 0x9005, 0x1150,
-	0x70a3, 0x0001, 0x00d6, 0x2069, 0x0140, 0x080c, 0x7001, 0x00de,
-	0x1904, 0x25a5, 0x080c, 0x7296, 0x0428, 0x080c, 0x6fcd, 0x1590,
-	0x6024, 0x9084, 0x1800, 0x1108, 0x0468, 0x080c, 0x7296, 0x080c,
-	0x728c, 0x080c, 0x5ce5, 0x080c, 0x6edc, 0x0804, 0x25a2, 0xd1ac,
-	0x1508, 0x6024, 0xd0dc, 0x1170, 0xd0e4, 0x1178, 0xd0d4, 0x1190,
-	0xd0cc, 0x0130, 0x7094, 0x9086, 0x0028, 0x1110, 0x080c, 0x717b,
-	0x0804, 0x25a2, 0x080c, 0x7291, 0x0048, 0x2001, 0x1955, 0x2003,
-	0x0002, 0x0020, 0x080c, 0x70e1, 0x0804, 0x25a2, 0x080c, 0x7215,
-	0x0804, 0x25a2, 0xd1ac, 0x0904, 0x24c3, 0x080c, 0x6faa, 0x11c0,
-	0x6027, 0x0020, 0x0006, 0x0026, 0x0036, 0x080c, 0x6fc4, 0x1158,
-	0x080c, 0x728c, 0x080c, 0x5ce5, 0x080c, 0x6edc, 0x003e, 0x002e,
-	0x000e, 0x00ae, 0x0005, 0x003e, 0x002e, 0x000e, 0x080c, 0x6f82,
-	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, 0x48f4, 0x003e, 0x080c, 0xc234, 0x1904, 0x24a0, 0x9196,
-	0xff00, 0x05a8, 0x705c, 0x9084, 0x00ff, 0x810f, 0x81ff, 0x0110,
-	0x9116, 0x0568, 0x7130, 0xd184, 0x1550, 0x080c, 0x3140, 0x0128,
-	0xc18d, 0x7132, 0x080c, 0x6572, 0x1510, 0x6240, 0x9294, 0x0010,
-	0x0130, 0x6248, 0x9294, 0xff00, 0x9296, 0xff00, 0x01c0, 0x7030,
-	0xd08c, 0x0904, 0x24a0, 0x7038, 0xd08c, 0x1140, 0x2001, 0x180c,
-	0x200c, 0xd1ac, 0x1904, 0x24a0, 0xc1ad, 0x2102, 0x0036, 0x73d4,
-	0x2011, 0x8013, 0x080c, 0x48f4, 0x003e, 0x0804, 0x24a0, 0x7038,
-	0xd08c, 0x1140, 0x2001, 0x180c, 0x200c, 0xd1ac, 0x1904, 0x24a0,
-	0xc1ad, 0x2102, 0x0036, 0x73d4, 0x2011, 0x8013, 0x080c, 0x48f4,
-	0x003e, 0x7130, 0xc185, 0x7132, 0x2011, 0x185c, 0x220c, 0x00f0,
-	0x0016, 0x2009, 0x0001, 0x2011, 0x0100, 0x080c, 0x8236, 0x2019,
-	0x000e, 0x00c6, 0x2061, 0x0000, 0x080c, 0xd4e0, 0x00ce, 0x9484,
-	0x00ff, 0x9080, 0x3145, 0x200d, 0x918c, 0xff00, 0x810f, 0x2120,
-	0x9006, 0x2009, 0x000e, 0x080c, 0xd564, 0x001e, 0xd1ac, 0x1148,
-	0x0016, 0x2009, 0x0002, 0x2019, 0x0004, 0x080c, 0x2fb2, 0x001e,
-	0x0078, 0x0156, 0x00b6, 0x20a9, 0x007f, 0x900e, 0x080c, 0x6256,
-	0x1110, 0x080c, 0x5cff, 0x8108, 0x1f04, 0x2496, 0x00be, 0x015e,
-	0x00ce, 0x004e, 0x080c, 0x9db5, 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, 0x25a2, 0x0016, 0x6220,
-	0xd2b4, 0x0904, 0x254b, 0x080c, 0x80bf, 0x080c, 0x93c7, 0x6027,
-	0x0004, 0x00f6, 0x2019, 0x19c8, 0x2304, 0x907d, 0x0904, 0x251a,
-	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, 0x2b31, 0x2001, 0x001e, 0x8001, 0x0240,
-	0x20a9, 0x0009, 0x080c, 0x2a4b, 0x6904, 0xd1dc, 0x1140, 0x0cb0,
-	0x2001, 0x0100, 0x080c, 0x2b21, 0x9006, 0x080c, 0x2b21, 0x080c,
-	0x887f, 0x080c, 0x898b, 0x7814, 0x2048, 0xa867, 0x0103, 0x2f60,
-	0x080c, 0x9e2f, 0x009e, 0x00ee, 0x00ce, 0x00de, 0x00fe, 0x001e,
-	0x00ae, 0x0005, 0x00fe, 0x00d6, 0x2069, 0x0140, 0x6804, 0x9084,
-	0x4000, 0x0110, 0x080c, 0x2b31, 0x00de, 0x00c6, 0x2061, 0x19bf,
-	0x6028, 0x080c, 0xc23b, 0x0120, 0x909a, 0x0003, 0x1258, 0x0018,
-	0x909a, 0x00c8, 0x1238, 0x8000, 0x602a, 0x00ce, 0x080c, 0x93a3,
-	0x0804, 0x25a1, 0x2061, 0x0100, 0x62c0, 0x080c, 0x9c3b, 0x2019,
-	0x19c8, 0x2304, 0x9065, 0x0120, 0x2009, 0x0027, 0x080c, 0x9ea9,
-	0x00ce, 0x0804, 0x25a1, 0xd2bc, 0x0904, 0x258e, 0x080c, 0x80cc,
-	0x6014, 0x9084, 0x1984, 0x9085, 0x0010, 0x6016, 0x6027, 0x0004,
-	0x00d6, 0x2069, 0x0140, 0x6804, 0x9084, 0x4000, 0x0110, 0x080c,
-	0x2b31, 0x00de, 0x00c6, 0x2061, 0x19bf, 0x6044, 0x080c, 0xc23b,
-	0x0120, 0x909a, 0x0003, 0x1628, 0x0018, 0x909a, 0x00c8, 0x1608,
-	0x8000, 0x6046, 0x603c, 0x00ce, 0x9005, 0x0558, 0x2009, 0x07d0,
-	0x080c, 0x80c4, 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, 0x96e9, 0x003e, 0x2019,
-	0x19ce, 0x2304, 0x9065, 0x0120, 0x2009, 0x004f, 0x080c, 0x9ea9,
-	0x00ce, 0x001e, 0xd19c, 0x0904, 0x2614, 0x7038, 0xd0ac, 0x1904,
-	0x25e9, 0x0016, 0x0156, 0x6027, 0x0008, 0x6050, 0x9085, 0x0040,
-	0x6052, 0x6050, 0x9084, 0xfbcf, 0x6052, 0x080c, 0x2a6a, 0x9085,
-	0x2000, 0x6052, 0x20a9, 0x0012, 0x1d04, 0x25bc, 0x080c, 0x80f3,
-	0x1f04, 0x25bc, 0x6050, 0x9085, 0x0400, 0x9084, 0xdfbf, 0x6052,
-	0x20a9, 0x0028, 0xa001, 0x1f04, 0x25ca, 0x6150, 0x9185, 0x1400,
-	0x6052, 0x20a9, 0x0366, 0x1d04, 0x25d3, 0x080c, 0x80f3, 0x6020,
-	0xd09c, 0x1130, 0x015e, 0x6152, 0x001e, 0x6027, 0x0008, 0x04a0,
-	0x080c, 0x2a32, 0x1f04, 0x25d3, 0x015e, 0x6152, 0x001e, 0x6027,
-	0x0008, 0x0016, 0x6028, 0xc09c, 0x602a, 0x080c, 0x9db5, 0x60e3,
-	0x0000, 0x080c, 0xd8ee, 0x080c, 0xd909, 0x080c, 0x539e, 0xd0fc,
-	0x1138, 0x080c, 0xc234, 0x1120, 0x9085, 0x0001, 0x080c, 0x6ff1,
-	0x9006, 0x080c, 0x2b21, 0x2009, 0x0002, 0x080c, 0x2a70, 0x00e6,
-	0x2071, 0x1800, 0x7003, 0x0004, 0x080c, 0x0e80, 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,
-	0x2668, 0x81ff, 0x01a0, 0x2009, 0x0000, 0x080c, 0x2a70, 0x2011,
-	0x8011, 0x2019, 0x010e, 0x231c, 0x939e, 0x0007, 0x1118, 0x2019,
-	0x0001, 0x0010, 0x2019, 0x0000, 0x080c, 0x48f4, 0x0448, 0x2001,
-	0x1980, 0x200c, 0x81ff, 0x1140, 0x2001, 0x0109, 0x2004, 0xd0b4,
-	0x0118, 0x2019, 0x0003, 0x0008, 0x2118, 0x2011, 0x8012, 0x080c,
-	0x48f4, 0x080c, 0x0e80, 0x080c, 0x539e, 0xd0fc, 0x1188, 0x080c,
-	0xc234, 0x1170, 0x00c6, 0x080c, 0x2704, 0x080c, 0x9650, 0x2061,
-	0x0100, 0x2019, 0x0028, 0x2009, 0x0002, 0x080c, 0x2fb2, 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, 0x7c4e,
-	0x0048, 0x9584, 0x00ff, 0x9080, 0x3145, 0x200d, 0x918c, 0xff00,
-	0x810f, 0x9006, 0x0005, 0x9080, 0x3145, 0x200d, 0x918c, 0x00ff,
-	0x0005, 0x00d6, 0x2069, 0x0140, 0x2001, 0x1817, 0x2003, 0x00ef,
-	0x20a9, 0x0010, 0x9006, 0x6852, 0x6856, 0x1f04, 0x26b4, 0x00de,
-	0x0005, 0x0006, 0x00d6, 0x0026, 0x2069, 0x0140, 0x2001, 0x1817,
-	0x2102, 0x8114, 0x8214, 0x8214, 0x8214, 0x20a9, 0x0010, 0x6853,
-	0x0000, 0x9006, 0x82ff, 0x1128, 0x9184, 0x000f, 0x9080, 0xddc3,
-	0x2005, 0x6856, 0x8211, 0x1f04, 0x26c9, 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, 0x26f9, 0x680f, 0x0000, 0x000e, 0x001e,
-	0x002e, 0x00de, 0x015e, 0x0005, 0x080c, 0x539a, 0xd0c4, 0x0150,
-	0xd0a4, 0x0140, 0x9006, 0x0046, 0x2020, 0x2009, 0x002e, 0x080c,
-	0xd564, 0x004e, 0x0005, 0x00f6, 0x0016, 0x0026, 0x2079, 0x0140,
-	0x78c4, 0xd0dc, 0x0904, 0x2770, 0x080c, 0x29cf, 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,
-	0x8277, 0x928c, 0xff00, 0x0110, 0x2011, 0x00ff, 0x2200, 0x8007,
-	0x9085, 0x004c, 0x78c2, 0x2009, 0x0138, 0x220a, 0x080c, 0x6faa,
-	0x1118, 0x2009, 0x1945, 0x220a, 0x002e, 0x001e, 0x00fe, 0x0005,
-	0x78c3, 0x0000, 0x0cc8, 0x0126, 0x2091, 0x2800, 0x0006, 0x0016,
-	0x0026, 0x2001, 0x0170, 0x200c, 0x8000, 0x2014, 0x9184, 0x0003,
-	0x0110, 0x080c, 0x0dad, 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, 0x0db4,
-	0x0033, 0x00ee, 0x002e, 0x001e, 0x000e, 0x015e, 0x0005, 0x27ce,
-	0x27ec, 0x2810, 0x2812, 0x283b, 0x283d, 0x283f, 0x2001, 0x0001,
-	0x080c, 0x2619, 0x080c, 0x2a2d, 0x2001, 0x196a, 0x2003, 0x0000,
-	0x7828, 0x9084, 0xe1d7, 0x782a, 0x9006, 0x20a9, 0x0009, 0x080c,
-	0x29eb, 0x2001, 0x1968, 0x2003, 0x0006, 0x2009, 0x001e, 0x2011,
-	0x2840, 0x080c, 0x80d1, 0x0005, 0x2009, 0x196d, 0x200b, 0x0000,
-	0x2001, 0x1972, 0x2003, 0x0036, 0x2001, 0x1971, 0x2003, 0x002a,
-	0x2001, 0x196a, 0x2003, 0x0001, 0x9006, 0x080c, 0x299d, 0x2001,
-	0xffff, 0x20a9, 0x0009, 0x080c, 0x29eb, 0x2001, 0x1968, 0x2003,
-	0x0006, 0x2009, 0x001e, 0x2011, 0x2840, 0x080c, 0x80d1, 0x0005,
-	0x080c, 0x0db4, 0x2001, 0x1972, 0x2003, 0x0036, 0x2001, 0x196a,
-	0x2003, 0x0003, 0x7a38, 0x9294, 0x0005, 0x9296, 0x0004, 0x0110,
-	0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x299d, 0x2001, 0x196e,
-	0x2003, 0x0000, 0x2001, 0xffff, 0x20a9, 0x0009, 0x080c, 0x29eb,
-	0x2001, 0x1968, 0x2003, 0x0006, 0x2009, 0x001e, 0x2011, 0x2840,
-	0x080c, 0x80d1, 0x0005, 0x080c, 0x0db4, 0x080c, 0x0db4, 0x0005,
-	0x0006, 0x0016, 0x0026, 0x00e6, 0x00f6, 0x0156, 0x0126, 0x2091,
-	0x8000, 0x2079, 0x0100, 0x2001, 0x196a, 0x2004, 0x908a, 0x0007,
-	0x1a0c, 0x0db4, 0x0043, 0x012e, 0x015e, 0x00fe, 0x00ee, 0x002e,
-	0x001e, 0x000e, 0x0005, 0x2862, 0x2882, 0x28c2, 0x28f2, 0x2916,
-	0x2926, 0x2928, 0x080c, 0x29df, 0x11b0, 0x7850, 0x9084, 0xefff,
-	0x7852, 0x2009, 0x1970, 0x2104, 0x7a38, 0x9294, 0x0005, 0x9296,
-	0x0004, 0x0110, 0xc08d, 0x0008, 0xc085, 0x200a, 0x2001, 0x1968,
-	0x2003, 0x0001, 0x0030, 0x080c, 0x294c, 0x2001, 0xffff, 0x080c,
-	0x27dd, 0x0005, 0x080c, 0x292a, 0x05e0, 0x2009, 0x1971, 0x2104,
-	0x8001, 0x200a, 0x080c, 0x29df, 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, 0x2932, 0x00c0, 0x200b,
-	0x0000, 0x7a38, 0x9294, 0x0006, 0x9296, 0x0004, 0x0110, 0x9006,
-	0x0010, 0x2001, 0x0001, 0x080c, 0x29ba, 0x2001, 0x196a, 0x2003,
-	0x0002, 0x0028, 0x2001, 0x1968, 0x2003, 0x0003, 0x0010, 0x080c,
-	0x27ff, 0x0005, 0x080c, 0x292a, 0x0560, 0x2009, 0x1971, 0x2104,
-	0x8001, 0x200a, 0x080c, 0x29df, 0x1168, 0x7850, 0x9084, 0xefff,
-	0x7852, 0x2001, 0x1968, 0x2003, 0x0003, 0x2001, 0x1969, 0x2003,
-	0x0000, 0x00b8, 0x2009, 0x1971, 0x2104, 0x9005, 0x1118, 0x080c,
-	0x296f, 0x0010, 0x080c, 0x293f, 0x080c, 0x2932, 0x2009, 0x196d,
-	0x200b, 0x0000, 0x2001, 0x196a, 0x2003, 0x0001, 0x080c, 0x27ff,
-	0x0000, 0x0005, 0x04b9, 0x0508, 0x080c, 0x29df, 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, 0x282a, 0x0005, 0x0099, 0x0168,
-	0x080c, 0x29df, 0x1138, 0x7850, 0x9084, 0xefff, 0x7852, 0x080c,
-	0x2816, 0x0018, 0x0079, 0x080c, 0x282a, 0x0005, 0x080c, 0x0db4,
-	0x080c, 0x0db4, 0x2009, 0x1972, 0x2104, 0x8001, 0x200a, 0x090c,
-	0x298b, 0x0005, 0x7a38, 0x9294, 0x0005, 0x9296, 0x0005, 0x0110,
-	0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x29ba, 0x0005, 0x7a38,
-	0x9294, 0x0006, 0x9296, 0x0006, 0x0110, 0x9006, 0x0010, 0x2001,
-	0x0001, 0x080c, 0x299d, 0x0005, 0x2009, 0x196d, 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, 0x29ba, 0x0005, 0x0086,
-	0x2001, 0x1970, 0x2004, 0x9084, 0x7fff, 0x090c, 0x0db4, 0x2009,
-	0x196f, 0x2144, 0x8846, 0x280a, 0x9844, 0x0dd8, 0xd08c, 0x1120,
-	0xd084, 0x1120, 0x080c, 0x0db4, 0x9006, 0x0010, 0x2001, 0x0001,
-	0x00a1, 0x008e, 0x0005, 0x0006, 0x0156, 0x2001, 0x1968, 0x20a9,
-	0x0009, 0x2003, 0x0000, 0x8000, 0x1f04, 0x2991, 0x2001, 0x196f,
-	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, 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, 0x2a6a, 0xd09c, 0x1110, 0x1f04,
-	0x29e2, 0x015e, 0x0005, 0x0126, 0x0016, 0x0006, 0x2091, 0x8000,
-	0x7850, 0x9085, 0x0040, 0x7852, 0x7850, 0x9084, 0xfbcf, 0x7852,
-	0x080c, 0x2a6a, 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, 0x2a18, 0x080c, 0x80f3, 0x1f04, 0x2a18, 0x7850, 0x9085,
-	0x0400, 0x9084, 0xdfbf, 0x7852, 0x080c, 0x2a6a, 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,
-	0x2a3c, 0x0028, 0x7854, 0xd08c, 0x1110, 0x1f04, 0x2a42, 0x00fe,
-	0x015e, 0x000e, 0x0005, 0x1d04, 0x2a4b, 0x080c, 0x80f3, 0x1f04,
-	0x2a4b, 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, 0xa001, 0xa001, 0xa001, 0xa001, 0xa001, 0x0005,
-	0x0006, 0x2001, 0x1980, 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, 0x2000, 0x0118, 0x9186, 0x0100,
-	0x1588, 0x2009, 0x00a2, 0x080c, 0x0e2f, 0x2019, 0x0160, 0x2324,
-	0x2011, 0x0003, 0x2009, 0x0169, 0x2104, 0x9084, 0x0007, 0x210c,
-	0x918c, 0x0007, 0x910e, 0x1db0, 0x9086, 0x0003, 0x11b8, 0x2304,
-	0x9402, 0x02a0, 0x1d60, 0x8211, 0x1d68, 0x84ff, 0x0170, 0x2001,
-	0x0141, 0x200c, 0x918c, 0xff00, 0x9186, 0x0100, 0x0130, 0x2009,
-	0x180c, 0x2104, 0xc0dd, 0x200a, 0x0008, 0x0419, 0x2009, 0x0000,
-	0x080c, 0x0e2f, 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, 0x6fc4, 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, 0x6fc4, 0x0110, 0xc0bc, 0x0008, 0xc0bd, 0x200a,
-	0x001e, 0x000e, 0x0005, 0x2dc7, 0x2dc7, 0x2beb, 0x2beb, 0x2bf7,
-	0x2bf7, 0x2c03, 0x2c03, 0x2c11, 0x2c11, 0x2c1d, 0x2c1d, 0x2c2b,
-	0x2c2b, 0x2c39, 0x2c39, 0x2c4b, 0x2c4b, 0x2c57, 0x2c57, 0x2c65,
-	0x2c65, 0x2c83, 0x2c83, 0x2ca3, 0x2ca3, 0x2c73, 0x2c73, 0x2c93,
-	0x2c93, 0x2cb1, 0x2cb1, 0x2c49, 0x2c49, 0x2c49, 0x2c49, 0x2c49,
-	0x2c49, 0x2c49, 0x2c49, 0x2c49, 0x2c49, 0x2c49, 0x2c49, 0x2c49,
-	0x2c49, 0x2c49, 0x2c49, 0x2c49, 0x2c49, 0x2c49, 0x2c49, 0x2c49,
-	0x2c49, 0x2c49, 0x2c49, 0x2c49, 0x2c49, 0x2c49, 0x2c49, 0x2c49,
-	0x2c49, 0x2c49, 0x2c49, 0x2cc3, 0x2cc3, 0x2ccf, 0x2ccf, 0x2cdd,
-	0x2cdd, 0x2ceb, 0x2ceb, 0x2cfb, 0x2cfb, 0x2d09, 0x2d09, 0x2d19,
-	0x2d19, 0x2d29, 0x2d29, 0x2d3b, 0x2d3b, 0x2d49, 0x2d49, 0x2d59,
-	0x2d59, 0x2d7b, 0x2d7b, 0x2d9d, 0x2d9d, 0x2d69, 0x2d69, 0x2d8c,
-	0x2d8c, 0x2dac, 0x2dac, 0x2c49, 0x2c49, 0x2c49, 0x2c49, 0x2c49,
-	0x2c49, 0x2c49, 0x2c49, 0x2c49, 0x2c49, 0x2c49, 0x2c49, 0x2c49,
-	0x2c49, 0x2c49, 0x2c49, 0x2c49, 0x2c49, 0x2c49, 0x2c49, 0x2c49,
-	0x2c49, 0x2c49, 0x2c49, 0x2c49, 0x2c49, 0x2c49, 0x2c49, 0x2c49,
-	0x2c49, 0x2c49, 0x2c49, 0x2c49, 0x2c49, 0x2c49, 0x2c49, 0x2c49,
-	0x2c49, 0x2c49, 0x2c49, 0x2c49, 0x2c49, 0x2c49, 0x2c49, 0x2c49,
-	0x2c49, 0x2c49, 0x2c49, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
-	0x0136, 0x0146, 0x0156, 0x080c, 0x2320, 0x0804, 0x2dbf, 0x0106,
+	0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x0120, 0x7850, 0x9085,
+	0x0400, 0x7852, 0x2001, 0x197f, 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,
+	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,
+	0x0002, 0x0218, 0x705b, 0xffff, 0x0008, 0x715a, 0x7063, 0xffff,
+	0x717a, 0x717e, 0x080c, 0xc28a, 0x70e7, 0x00c0, 0x2061, 0x1944,
+	0x6003, 0x0909, 0x6106, 0x600b, 0x8800, 0x600f, 0x0200, 0x6013,
+	0x00ff, 0x6017, 0x000f, 0x611a, 0x601f, 0x07d0, 0x2061, 0x194c,
+	0x6003, 0x8000, 0x6106, 0x610a, 0x600f, 0x0200, 0x6013, 0x00ff,
+	0x6116, 0x601b, 0x0001, 0x611e, 0x2061, 0x1961, 0x6003, 0x514c,
+	0x6007, 0x4f47, 0x600b, 0x4943, 0x600f, 0x2020, 0x2001, 0x182b,
+	0x2102, 0x0005, 0x9016, 0x080c, 0x649f, 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,
+	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,
+	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,
+	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,
+	0x0005, 0x00c6, 0x7803, 0x0000, 0x7808, 0xd09c, 0x0110, 0x7820,
+	0x0cd8, 0x2001, 0x1a3b, 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,
+	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,
+	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,
+	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,
+	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,
+	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,
+	0x1984, 0x9085, 0x0010, 0x6016, 0x6027, 0x0004, 0x00d6, 0x2069,
+	0x0140, 0x6804, 0x9084, 0x4000, 0x0110, 0x080c, 0x2c98, 0x00de,
+	0x00c6, 0x2061, 0x19bf, 0x6044, 0x080c, 0xc539, 0x0120, 0x909a,
+	0x0003, 0x1628, 0x0018, 0x909a, 0x00c8, 0x1608, 0x8000, 0x6046,
+	0x603c, 0x00ce, 0x9005, 0x0558, 0x2009, 0x07d0, 0x080c, 0x835f,
+	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,
+	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,
+	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,
+	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,
+	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,
+	0x010e, 0x231c, 0x939e, 0x0007, 0x1118, 0x2019, 0x0001, 0x0010,
+	0x2019, 0x0000, 0x080c, 0x4b1f, 0x0448, 0x2001, 0x1980, 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,
+	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,
+	0x2069, 0x0140, 0x2001, 0x1817, 0x2003, 0x00ef, 0x20a9, 0x0010,
+	0x9006, 0x6852, 0x6856, 0x1f04, 0x27b2, 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,
+	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,
+	0x0005, 0x00f6, 0x0016, 0x0026, 0x2079, 0x0140, 0x78c4, 0xd0dc,
+	0x0904, 0x286e, 0x080c, 0x2af6, 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,
+	0xff00, 0x0110, 0x2011, 0x00ff, 0x2200, 0x8007, 0x9085, 0x004c,
+	0x78c2, 0x2009, 0x0138, 0x220a, 0x080c, 0x7207, 0x1118, 0x2009,
+	0x1945, 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,
+	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,
+	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,
+	0x0026, 0x00e6, 0x00f6, 0x0156, 0x0126, 0x2091, 0x8000, 0x2079,
+	0x0100, 0x2001, 0x196a, 0x2004, 0x908a, 0x0007, 0x1a0c, 0x0dfa,
+	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,
+	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,
+	0x7a38, 0x9294, 0x0005, 0x9296, 0x0005, 0x0110, 0x9006, 0x0010,
+	0x2001, 0x0001, 0x080c, 0x2ab8, 0x0005, 0x7a38, 0x9294, 0x0006,
+	0x9296, 0x0006, 0x0110, 0x9006, 0x0010, 0x2001, 0x0001, 0x080c,
+	0x2a9b, 0x0005, 0x2009, 0x196d, 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,
+	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,
+	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,
+	0x00f6, 0x2079, 0x0100, 0x9085, 0x0000, 0x0188, 0x7838, 0x9084,
+	0xfffa, 0x9085, 0x0004, 0x783a, 0x2001, 0x0100, 0x2004, 0x9086,
+	0x000a, 0x1120, 0x7850, 0x9084, 0xfff0, 0x7852, 0x0428, 0x7838,
+	0x9084, 0xfffb, 0x9085, 0x0005, 0x783a, 0x2001, 0x0100, 0x2004,
+	0x9086, 0x000a, 0x11c8, 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, 0x2bb0, 0xd09c, 0x1110, 0x1f04, 0x2b09,
+	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,
+	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,
+	0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x0160, 0x7850, 0x9085,
+	0x0400, 0x9084, 0xdfbf, 0x7852, 0x080c, 0x2bb0, 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,
+	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,
+	0xa001, 0xa001, 0xa001, 0xa001, 0xa001, 0x0005, 0x0006, 0x2001,
+	0x1980, 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,
+	0x8000, 0x0208, 0x200a, 0x001e, 0x04f0, 0x2009, 0x00a2, 0x080c,
+	0x0e75, 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,
+	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,
+	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, 0x7221, 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,
+	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,
+	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,
+	0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
+	0x23c6, 0x0804, 0x2f63, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
+	0x0136, 0x0146, 0x0156, 0x080c, 0x21cd, 0x0804, 0x2f63, 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,
+	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,
+	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,
+	0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
+	0x23c6, 0x080c, 0x1370, 0x080c, 0x2208, 0x0804, 0x2f63, 0x0106,
+	0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
+	0x21cd, 0x080c, 0x23c6, 0x080c, 0x1370, 0x0804, 0x2f63, 0x0106,
+	0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
+	0x21cd, 0x080c, 0x1370, 0x080c, 0x2208, 0x0804, 0x2f63, 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,
 	0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
-	0x2138, 0x0804, 0x2dbf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
-	0x0136, 0x0146, 0x0156, 0x080c, 0x2138, 0x080c, 0x2320, 0x0804,
-	0x2dbf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
-	0x0156, 0x080c, 0x2173, 0x0804, 0x2dbf, 0x0106, 0x0006, 0x0126,
-	0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2320, 0x080c,
-	0x2173, 0x0804, 0x2dbf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
-	0x0136, 0x0146, 0x0156, 0x080c, 0x2138, 0x080c, 0x2173, 0x0804,
-	0x2dbf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
-	0x0156, 0x080c, 0x2138, 0x080c, 0x2320, 0x080c, 0x2173, 0x0804,
-	0x2dbf, 0xa001, 0x0cf0, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
-	0x0136, 0x0146, 0x0156, 0x080c, 0x130c, 0x0804, 0x2dbf, 0x0106,
+	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,
 	0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
-	0x2320, 0x080c, 0x130c, 0x0804, 0x2dbf, 0x0106, 0x0006, 0x0126,
-	0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2138, 0x080c,
-	0x130c, 0x0804, 0x2dbf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
-	0x0136, 0x0146, 0x0156, 0x080c, 0x2320, 0x080c, 0x130c, 0x080c,
-	0x2173, 0x0804, 0x2dbf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
-	0x0136, 0x0146, 0x0156, 0x080c, 0x2138, 0x080c, 0x2320, 0x080c,
-	0x130c, 0x0804, 0x2dbf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
-	0x0136, 0x0146, 0x0156, 0x080c, 0x2138, 0x080c, 0x130c, 0x080c,
-	0x2173, 0x0804, 0x2dbf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
-	0x0136, 0x0146, 0x0156, 0x080c, 0x130c, 0x080c, 0x2173, 0x0804,
-	0x2dbf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
-	0x0156, 0x080c, 0x2138, 0x080c, 0x2320, 0x080c, 0x130c, 0x080c,
-	0x2173, 0x0804, 0x2dbf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
-	0x0136, 0x0146, 0x0156, 0x080c, 0x2773, 0x0804, 0x2dbf, 0x0106,
+	0x2871, 0x080c, 0x21cd, 0x080c, 0x23c6, 0x0804, 0x2f63, 0x0106,
 	0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
-	0x2773, 0x080c, 0x2320, 0x0804, 0x2dbf, 0x0106, 0x0006, 0x0126,
-	0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2773, 0x080c,
-	0x2138, 0x0804, 0x2dbf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
-	0x0136, 0x0146, 0x0156, 0x080c, 0x2773, 0x080c, 0x2138, 0x080c,
-	0x2320, 0x0804, 0x2dbf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
-	0x0136, 0x0146, 0x0156, 0x080c, 0x2773, 0x080c, 0x2173, 0x0804,
-	0x2dbf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
-	0x0156, 0x080c, 0x2773, 0x080c, 0x2320, 0x080c, 0x2173, 0x0804,
-	0x2dbf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
-	0x0156, 0x080c, 0x2773, 0x080c, 0x2138, 0x080c, 0x2173, 0x0804,
-	0x2dbf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
-	0x0156, 0x080c, 0x2773, 0x080c, 0x2138, 0x080c, 0x2320, 0x080c,
-	0x2173, 0x0804, 0x2dbf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
-	0x0136, 0x0146, 0x0156, 0x080c, 0x2773, 0x080c, 0x130c, 0x0804,
-	0x2dbf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
-	0x0156, 0x080c, 0x2773, 0x080c, 0x2320, 0x080c, 0x130c, 0x0804,
-	0x2dbf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
-	0x0156, 0x080c, 0x2773, 0x080c, 0x2138, 0x080c, 0x130c, 0x0804,
-	0x2dbf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
-	0x0156, 0x080c, 0x2773, 0x080c, 0x2320, 0x080c, 0x130c, 0x080c,
-	0x2173, 0x0804, 0x2dbf, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
-	0x0136, 0x0146, 0x0156, 0x080c, 0x2773, 0x080c, 0x2138, 0x080c,
-	0x2320, 0x080c, 0x130c, 0x0498, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2773, 0x080c, 0x2138,
-	0x080c, 0x130c, 0x080c, 0x2173, 0x0410, 0x0106, 0x0006, 0x0126,
-	0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2773, 0x080c,
-	0x130c, 0x080c, 0x2173, 0x0098, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2773, 0x080c, 0x2138,
-	0x080c, 0x2320, 0x080c, 0x130c, 0x080c, 0x2173, 0x0000, 0x015e,
-	0x014e, 0x013e, 0x01de, 0x01ce, 0x012e, 0x000e, 0x010e, 0x000d,
-	0x00b6, 0x00c6, 0x0026, 0x0046, 0x9026, 0x080c, 0x6538, 0x1904,
-	0x2ece, 0x72d8, 0x2001, 0x1954, 0x2004, 0x9005, 0x1110, 0xd29c,
-	0x0148, 0xd284, 0x1138, 0xd2bc, 0x1904, 0x2ece, 0x080c, 0x2ed3,
-	0x0804, 0x2ece, 0xd2cc, 0x1904, 0x2ece, 0x080c, 0x6faa, 0x1120,
-	0x70ab, 0xffff, 0x0804, 0x2ece, 0xd294, 0x0120, 0x70ab, 0xffff,
-	0x0804, 0x2ece, 0x080c, 0x313b, 0x0160, 0x080c, 0xc23b, 0x0128,
-	0x2001, 0x1817, 0x203c, 0x0804, 0x2e60, 0x70ab, 0xffff, 0x0804,
-	0x2ece, 0x2001, 0x1817, 0x203c, 0x7290, 0xd284, 0x0904, 0x2e60,
-	0xd28c, 0x1904, 0x2e60, 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, 0x659e, 0x002e, 0x0118,
-	0x70ab, 0xffff, 0x0410, 0x900e, 0x080c, 0x2670, 0x080c, 0x61f6,
-	0x11c0, 0x080c, 0x657a, 0x1168, 0x7030, 0xd08c, 0x0130, 0xb800,
-	0xd0bc, 0x0138, 0x080c, 0x6476, 0x0120, 0x080c, 0x2eec, 0x0148,
-	0x0028, 0x080c, 0x302c, 0x080c, 0x2f18, 0x0118, 0x8318, 0x0804,
-	0x2e12, 0x73aa, 0x0010, 0x70ab, 0xffff, 0x003e, 0x0804, 0x2ece,
-	0x9780, 0x3145, 0x203d, 0x97bc, 0xff00, 0x873f, 0x2041, 0x007e,
-	0x70a8, 0x9096, 0xffff, 0x1118, 0x900e, 0x28a8, 0x0050, 0x9812,
-	0x0220, 0x2008, 0x9802, 0x20a8, 0x0020, 0x70ab, 0xffff, 0x0804,
-	0x2ece, 0x2700, 0x0156, 0x0016, 0x9106, 0x0904, 0x2ec3, 0x0026,
-	0x2011, 0x0010, 0x080c, 0x659e, 0x002e, 0x0120, 0x2009, 0xffff,
-	0x0804, 0x2ecb, 0xc484, 0x080c, 0x6256, 0x0138, 0x080c, 0xc23b,
-	0x1590, 0x080c, 0x61f6, 0x15b8, 0x0008, 0xc485, 0x080c, 0x657a,
-	0x1130, 0x7030, 0xd08c, 0x01f8, 0xb800, 0xd0bc, 0x11e0, 0x7290,
-	0xd28c, 0x0180, 0x080c, 0x657a, 0x9082, 0x0006, 0x02e0, 0xd484,
-	0x1118, 0x080c, 0x621a, 0x0028, 0x080c, 0x30b7, 0x01a0, 0x080c,
-	0x30e2, 0x0088, 0x080c, 0x302c, 0x080c, 0xc23b, 0x1160, 0x080c,
-	0x2f18, 0x0188, 0x0040, 0x080c, 0xc23b, 0x1118, 0x080c, 0x30b7,
-	0x0110, 0x0451, 0x0140, 0x001e, 0x8108, 0x015e, 0x1f04, 0x2e79,
-	0x70ab, 0xffff, 0x0018, 0x001e, 0x015e, 0x71aa, 0x004e, 0x002e,
-	0x00ce, 0x00be, 0x0005, 0x00c6, 0x0016, 0x70ab, 0x0001, 0x2009,
-	0x007e, 0x080c, 0x61f6, 0x1168, 0xb813, 0x00ff, 0xb817, 0xfffe,
-	0x080c, 0x302c, 0x04a9, 0x0128, 0x70d8, 0xc0bd, 0x70da, 0x080c,
-	0xbf8c, 0x001e, 0x00ce, 0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6,
-	0x2001, 0x1860, 0x2004, 0x9084, 0x00ff, 0xb842, 0x080c, 0x9e7c,
-	0x01d0, 0x2b00, 0x6012, 0x080c, 0xbfb5, 0x6023, 0x0001, 0x9006,
-	0x080c, 0x6193, 0x2001, 0x0000, 0x080c, 0x61a7, 0x0126, 0x2091,
-	0x8000, 0x70a4, 0x8000, 0x70a6, 0x012e, 0x2009, 0x0004, 0x080c,
-	0x9ea9, 0x9085, 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e, 0x0005,
+	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,
+	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,
+	0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
+	0x2871, 0x080c, 0x21cd, 0x080c, 0x23c6, 0x080c, 0x1370, 0x0498,
+	0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156,
+	0x080c, 0x2871, 0x080c, 0x21cd, 0x080c, 0x1370, 0x080c, 0x2208,
+	0x0410, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
+	0x0156, 0x080c, 0x2871, 0x080c, 0x1370, 0x080c, 0x2208, 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,
+	0x012e, 0x000e, 0x010e, 0x000d, 0x00b6, 0x00c6, 0x0026, 0x0046,
+	0x9026, 0x080c, 0x6781, 0x1904, 0x3072, 0x72d8, 0x2001, 0x1954,
+	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,
+	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,
+	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,
+	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, 0x0076, 0x00d6, 0x00c6, 0x2001, 0x1860, 0x2004, 0x9084,
-	0x00ff, 0xb842, 0x080c, 0x9e7c, 0x0548, 0x2b00, 0x6012, 0xb800,
-	0xc0c4, 0xb802, 0xb8a0, 0x9086, 0x007e, 0x0140, 0xb804, 0x9084,
-	0x00ff, 0x9086, 0x0006, 0x1110, 0x080c, 0x2fe7, 0x080c, 0xbfb5,
-	0x6023, 0x0001, 0x9006, 0x080c, 0x6193, 0x2001, 0x0002, 0x080c,
-	0x61a7, 0x0126, 0x2091, 0x8000, 0x70a4, 0x8000, 0x70a6, 0x012e,
-	0x2009, 0x0002, 0x080c, 0x9ea9, 0x9085, 0x0001, 0x00ce, 0x00de,
-	0x007e, 0x001e, 0x0005, 0x00b6, 0x00c6, 0x0026, 0x2009, 0x0080,
-	0x080c, 0x61f6, 0x1140, 0xb813, 0x00ff, 0xb817, 0xfffc, 0x0039,
-	0x0110, 0x70df, 0xffff, 0x002e, 0x00ce, 0x00be, 0x0005, 0x0016,
-	0x0076, 0x00d6, 0x00c6, 0x080c, 0x9dd9, 0x01d0, 0x2b00, 0x6012,
-	0x080c, 0xbfb5, 0x6023, 0x0001, 0x9006, 0x080c, 0x6193, 0x2001,
-	0x0002, 0x080c, 0x61a7, 0x0126, 0x2091, 0x8000, 0x70e0, 0x8000,
-	0x70e2, 0x012e, 0x2009, 0x0002, 0x080c, 0x9ea9, 0x9085, 0x0001,
-	0x00ce, 0x00de, 0x007e, 0x001e, 0x0005, 0x00c6, 0x00d6, 0x0126,
-	0x2091, 0x8000, 0x2009, 0x007f, 0x080c, 0x61f6, 0x11b8, 0xb813,
-	0x00ff, 0xb817, 0xfffd, 0xb8bf, 0x0004, 0x080c, 0x9dd9, 0x0170,
-	0x2b00, 0x6012, 0x6316, 0x6023, 0x0001, 0x620a, 0x080c, 0xbfb5,
-	0x2009, 0x0022, 0x080c, 0x9ea9, 0x9085, 0x0001, 0x012e, 0x00de,
-	0x00ce, 0x0005, 0x00e6, 0x00c6, 0x0066, 0x0036, 0x0026, 0x00b6,
-	0x21f0, 0x080c, 0x858d, 0x080c, 0x8517, 0x080c, 0x9c82, 0x080c,
-	0xad86, 0x3e08, 0x2130, 0x81ff, 0x0120, 0x20a9, 0x007e, 0x900e,
-	0x0018, 0x20a9, 0x007f, 0x900e, 0x0016, 0x080c, 0x6256, 0x1140,
-	0x9686, 0x0002, 0x1118, 0xb800, 0xd0bc, 0x1110, 0x080c, 0x5cff,
-	0x001e, 0x8108, 0x1f04, 0x2fcc, 0x9686, 0x0001, 0x190c, 0x310f,
-	0x00be, 0x002e, 0x003e, 0x006e, 0x00ce, 0x00ee, 0x0005, 0x00e6,
-	0x00c6, 0x0046, 0x0036, 0x0026, 0x0016, 0x00b6, 0x6210, 0x2258,
-	0xbaa0, 0x0026, 0x2019, 0x0029, 0x080c, 0x8582, 0x0076, 0x2039,
-	0x0000, 0x080c, 0x8470, 0x2c08, 0x080c, 0xd2d5, 0x007e, 0x001e,
-	0xba10, 0xbb14, 0xbcb0, 0x080c, 0x5cff, 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,
-	0x539a, 0xd0c4, 0x0138, 0x0030, 0x9006, 0x2020, 0x2009, 0x002d,
-	0x080c, 0xd564, 0x20a9, 0x0800, 0x9016, 0x0026, 0x928e, 0x007e,
-	0x0904, 0x3096, 0x928e, 0x007f, 0x0904, 0x3096, 0x928e, 0x0080,
-	0x05e8, 0x9288, 0x1000, 0x210c, 0x81ff, 0x05c0, 0x8fff, 0x1148,
-	0x2001, 0x1966, 0x0006, 0x2003, 0x0001, 0x04f1, 0x000e, 0x2003,
-	0x0000, 0x00b6, 0x00c6, 0x2158, 0x2001, 0x0001, 0x080c, 0x6544,
-	0x00ce, 0x00be, 0x2019, 0x0029, 0x080c, 0x8582, 0x0076, 0x2039,
-	0x0000, 0x080c, 0x8470, 0x00b6, 0x00c6, 0x0026, 0x2158, 0xba04,
-	0x9294, 0x00ff, 0x9286, 0x0006, 0x1118, 0xb807, 0x0404, 0x0028,
-	0x2001, 0x0004, 0x8007, 0x9215, 0xba06, 0x002e, 0x00ce, 0x00be,
-	0x0016, 0x2c08, 0x080c, 0xd2d5, 0x001e, 0x007e, 0x002e, 0x8210,
-	0x1f04, 0x304d, 0x015e, 0x001e, 0x002e, 0x003e, 0x004e, 0x00be,
-	0x00ce, 0x00ee, 0x00fe, 0x0005, 0x0046, 0x0026, 0x0016, 0x080c,
-	0x539a, 0xd0c4, 0x0140, 0xd0a4, 0x0130, 0x9006, 0x2220, 0x2009,
-	0x0029, 0x080c, 0xd564, 0x001e, 0x002e, 0x004e, 0x0005, 0x0016,
-	0x0026, 0x0036, 0x00c6, 0x7290, 0x82ff, 0x01e8, 0x080c, 0x6572,
-	0x11d0, 0x2100, 0x080c, 0x26a3, 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, 0x1a87, 0x001e, 0x6112, 0x080c,
-	0x2fe7, 0x001e, 0x080c, 0x621a, 0x012e, 0x00ce, 0x001e, 0x0005,
-	0x0016, 0x0026, 0x2110, 0x080c, 0x9915, 0x080c, 0xd81c, 0x002e,
-	0x001e, 0x0005, 0x2001, 0x1836, 0x2004, 0xd0cc, 0x0005, 0x00c6,
-	0x00b6, 0x080c, 0x6faa, 0x1118, 0x20a9, 0x0800, 0x0010, 0x20a9,
-	0x0782, 0x080c, 0x6faa, 0x1110, 0x900e, 0x0010, 0x2009, 0x007e,
-	0x9180, 0x1000, 0x2004, 0x905d, 0x0130, 0x86ff, 0x0110, 0xb800,
-	0xd0bc, 0x090c, 0x621a, 0x8108, 0x1f04, 0x3120, 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, 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,
+	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,
+	0x00de, 0x007e, 0x001e, 0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6,
+	0x2001, 0x1860, 0x2004, 0x9084, 0x00ff, 0xb842, 0x080c, 0xa130,
+	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,
+	0x9085, 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e, 0x0005, 0x00b6,
+	0x00c6, 0x0026, 0x2009, 0x0080, 0x080c, 0x643f, 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,
+	0x2091, 0x8000, 0x70e0, 0x8000, 0x70e2, 0x012e, 0x2009, 0x0002,
+	0x080c, 0xa15d, 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,
+	0x9085, 0x0001, 0x012e, 0x00de, 0x00ce, 0x0005, 0x00e6, 0x00c6,
+	0x0066, 0x0036, 0x0026, 0x00b6, 0x21f0, 0x080c, 0x880e, 0x080c,
+	0x8798, 0x080c, 0x9f36, 0x080c, 0xb03a, 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,
+	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,
+	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,
+	0x0001, 0x04f1, 0x000e, 0x2003, 0x0000, 0x00b6, 0x00c6, 0x2158,
+	0x2001, 0x0001, 0x080c, 0x678d, 0x00ce, 0x00be, 0x2019, 0x0029,
+	0x080c, 0x8803, 0x0076, 0x2039, 0x0000, 0x080c, 0x86f1, 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,
+	0x002e, 0x003e, 0x004e, 0x00be, 0x00ce, 0x00ee, 0x00fe, 0x0005,
+	0x0046, 0x0026, 0x0016, 0x080c, 0x55db, 0xd0c4, 0x0140, 0xd0a4,
+	0x0130, 0x9006, 0x2220, 0x2009, 0x0029, 0x080c, 0xd885, 0x001e,
+	0x002e, 0x004e, 0x0005, 0x0016, 0x0026, 0x0036, 0x00c6, 0x7290,
+	0x82ff, 0x01e8, 0x080c, 0x67bb, 0x11d0, 0x2100, 0x080c, 0x27a1,
+	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,
+	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,
+	0x900e, 0x0010, 0x2009, 0x007e, 0x9180, 0x1000, 0x2004, 0x905d,
+	0x0130, 0x86ff, 0x0110, 0xb800, 0xd0bc, 0x090c, 0x6463, 0x8108,
+	0x1f04, 0x32c4, 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,
+	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, 0x8000, 0x2071, 0x189c, 0x7003,
-	0x0002, 0x9006, 0x7016, 0x701a, 0x704a, 0x704e, 0x700e, 0x7042,
-	0x7046, 0x703b, 0x18b8, 0x703f, 0x18b8, 0x7007, 0x0001, 0x080c,
-	0x1004, 0x090c, 0x0db4, 0x2900, 0x706a, 0xa867, 0x0002, 0xa8ab,
-	0xdcb0, 0x080c, 0x1004, 0x090c, 0x0db4, 0x2900, 0x706e, 0xa867,
-	0x0002, 0xa8ab, 0xdcb0, 0x0005, 0x2071, 0x189c, 0x7004, 0x0002,
-	0x3274, 0x3275, 0x3288, 0x329c, 0x0005, 0x1004, 0x3285, 0x0e04,
-	0x3285, 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, 0x3370, 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, 0x336d, 0x61cc,
-	0x0804, 0x3302, 0x3344, 0x337c, 0x336d, 0x3386, 0x3390, 0x3396,
-	0x339a, 0x33aa, 0x33ae, 0x33c4, 0x33ca, 0x33d0, 0x33db, 0x33e6,
-	0x33f5, 0x3404, 0x3412, 0x3429, 0x3444, 0x336d, 0x34ed, 0x352b,
-	0x35d1, 0x35e2, 0x3605, 0x336d, 0x336d, 0x336d, 0x363d, 0x3659,
-	0x3662, 0x3691, 0x3697, 0x336d, 0x36dd, 0x336d, 0x336d, 0x336d,
-	0x336d, 0x336d, 0x36e8, 0x36f1, 0x36f9, 0x36fb, 0x336d, 0x336d,
-	0x336d, 0x336d, 0x336d, 0x336d, 0x3727, 0x336d, 0x336d, 0x336d,
-	0x336d, 0x336d, 0x3744, 0x379f, 0x336d, 0x336d, 0x336d, 0x336d,
-	0x336d, 0x336d, 0x0002, 0x37c9, 0x37cc, 0x382b, 0x3844, 0x3874,
-	0x3b12, 0x336d, 0x4f73, 0x336d, 0x336d, 0x336d, 0x336d, 0x336d,
-	0x336d, 0x336d, 0x336d, 0x33c4, 0x33ca, 0x4033, 0x53be, 0x4049,
-	0x5002, 0x5053, 0x5156, 0x336d, 0x51b8, 0x51f4, 0x5225, 0x5329,
-	0x5252, 0x52a9, 0x336d, 0x404d, 0x41ee, 0x4204, 0x4229, 0x428e,
-	0x4302, 0x4322, 0x4399, 0x43f5, 0x4451, 0x4454, 0x4479, 0x4519,
-	0x457f, 0x4587, 0x46b9, 0x481e, 0x4852, 0x4a9c, 0x336d, 0x4aba,
-	0x4b76, 0x4c4c, 0x336d, 0x336d, 0x336d, 0x336d, 0x4cb2, 0x4ccd,
-	0x4587, 0x4f13, 0x714c, 0x0000, 0x2021, 0x4000, 0x080c, 0x48d0,
-	0x0126, 0x2091, 0x8000, 0x0e04, 0x334e, 0x0010, 0x012e, 0x0cc0,
-	0x7c36, 0x9486, 0x4000, 0x0118, 0x7833, 0x0011, 0x0010, 0x7833,
-	0x0010, 0x7c82, 0x7986, 0x7a8a, 0x7b8e, 0x2091, 0x4080, 0x2001,
-	0x0089, 0x2004, 0xd084, 0x190c, 0x1187, 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, 0x48dd, 0x2039, 0x0001,
-	0x902e, 0x2520, 0x7b88, 0x7a8c, 0x7884, 0x7990, 0x0804, 0x48e0,
-	0x7984, 0x7888, 0x2114, 0x200a, 0x0804, 0x3344, 0x7984, 0x2114,
-	0x0804, 0x3344, 0x20e1, 0x0000, 0x2099, 0x0021, 0x20e9, 0x0000,
-	0x20a1, 0x0021, 0x20a9, 0x001f, 0x4003, 0x7984, 0x7a88, 0x7b8c,
-	0x0804, 0x3344, 0x7884, 0x2060, 0x0804, 0x33f7, 0x2009, 0x0003,
-	0x2011, 0x0003, 0x2019, 0x0002, 0x789b, 0x0317, 0x7893, 0xffff,
-	0x2001, 0x188d, 0x2004, 0x9005, 0x0118, 0x7896, 0x0804, 0x3344,
-	0x7897, 0x0001, 0x0804, 0x3344, 0x2039, 0x0001, 0x7d98, 0x7c9c,
-	0x0804, 0x3380, 0x2039, 0x0001, 0x7d98, 0x7c9c, 0x0804, 0x338a,
-	0x79a0, 0x9182, 0x0040, 0x0210, 0x0804, 0x3379, 0x2138, 0x7d98,
-	0x7c9c, 0x0804, 0x3380, 0x79a0, 0x9182, 0x0040, 0x0210, 0x0804,
-	0x3379, 0x2138, 0x7d98, 0x7c9c, 0x0804, 0x338a, 0x79a0, 0x9182,
-	0x0040, 0x0210, 0x0804, 0x3379, 0x21e8, 0x7984, 0x7888, 0x20a9,
-	0x0001, 0x21a0, 0x4004, 0x0804, 0x3344, 0x2061, 0x0800, 0xe10c,
-	0x9006, 0x2c15, 0x9200, 0x8c60, 0x8109, 0x1dd8, 0x2010, 0x9005,
-	0x0904, 0x3344, 0x0804, 0x3373, 0x79a0, 0x9182, 0x0040, 0x0210,
-	0x0804, 0x3379, 0x21e0, 0x20a9, 0x0001, 0x7984, 0x2198, 0x4012,
-	0x0804, 0x3344, 0x2069, 0x185b, 0x7884, 0x7990, 0x911a, 0x1a04,
-	0x3379, 0x8019, 0x0904, 0x3379, 0x684a, 0x6942, 0x788c, 0x6852,
-	0x7888, 0x6856, 0x9006, 0x685a, 0x685e, 0x080c, 0x72bd, 0x0804,
-	0x3344, 0x2069, 0x185b, 0x7884, 0x7994, 0x911a, 0x1a04, 0x3379,
-	0x8019, 0x0904, 0x3379, 0x684e, 0x6946, 0x788c, 0x6862, 0x7888,
-	0x6866, 0x9006, 0x686a, 0x686e, 0x0126, 0x2091, 0x8000, 0x080c,
-	0x6678, 0x012e, 0x0804, 0x3344, 0x902e, 0x2520, 0x81ff, 0x0120,
-	0x2009, 0x0001, 0x0804, 0x3376, 0x7984, 0x7b88, 0x7a8c, 0x20a9,
-	0x0005, 0x20e9, 0x0001, 0x20a1, 0x18a4, 0x4101, 0x080c, 0x4894,
-	0x1120, 0x2009, 0x0002, 0x0804, 0x3376, 0x2009, 0x0020, 0xa85c,
-	0x9080, 0x0019, 0xaf60, 0x080c, 0x48dd, 0x701f, 0x3468, 0x0005,
-	0xa864, 0x2008, 0x9084, 0x00ff, 0x9096, 0x0011, 0x0168, 0x9096,
-	0x0019, 0x0150, 0x9096, 0x0015, 0x0138, 0x9096, 0x0048, 0x0120,
-	0x9096, 0x0029, 0x1904, 0x3376, 0x810f, 0x918c, 0x00ff, 0x0904,
-	0x3376, 0x7112, 0x7010, 0x8001, 0x0560, 0x7012, 0x080c, 0x4894,
-	0x1120, 0x2009, 0x0002, 0x0804, 0x3376, 0x2009, 0x0020, 0x7068,
-	0x2040, 0xa28c, 0xa390, 0xa494, 0xa598, 0x9290, 0x0040, 0x9399,
-	0x0000, 0x94a1, 0x0000, 0x95a9, 0x0000, 0xa85c, 0x9080, 0x0019,
-	0xaf60, 0x080c, 0x48dd, 0x701f, 0x34a6, 0x0005, 0xa864, 0x9084,
-	0x00ff, 0x9096, 0x0002, 0x0120, 0x9096, 0x000a, 0x1904, 0x3376,
-	0x0888, 0x7014, 0x2048, 0xa868, 0xc0fd, 0xa86a, 0xa864, 0x9084,
-	0x00ff, 0x9096, 0x0029, 0x1160, 0xc2fd, 0xaa7a, 0x080c, 0x5df1,
-	0x0150, 0x0126, 0x2091, 0x8000, 0xa87a, 0xa982, 0x012e, 0x0050,
-	0x080c, 0x610c, 0x1128, 0x7007, 0x0003, 0x701f, 0x34d2, 0x0005,
-	0x080c, 0x6ace, 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, 0x48e0, 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, 0x3376, 0x7984, 0x080c,
-	0x6256, 0x1904, 0x3379, 0x7e98, 0x9684, 0x3fff, 0x9082, 0x4000,
-	0x1a04, 0x3379, 0x7c88, 0x7d8c, 0x080c, 0x63b9, 0x080c, 0x6388,
-	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, 0x3376, 0x0c30, 0x080c, 0xb75c,
-	0x012e, 0x0904, 0x3376, 0x0804, 0x3344, 0x900e, 0x2001, 0x0005,
-	0x080c, 0x6ace, 0x0126, 0x2091, 0x8000, 0x080c, 0xbe35, 0x080c,
-	0x68a0, 0x012e, 0x0804, 0x3344, 0x00a6, 0x2950, 0xb198, 0x080c,
-	0x6256, 0x1904, 0x35be, 0xb6a4, 0x9684, 0x3fff, 0x9082, 0x4000,
-	0x16e8, 0xb49c, 0xb5a0, 0x080c, 0x63b9, 0x080c, 0x6388, 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, 0xb75c, 0x012e,
-	0x2009, 0x0003, 0x0178, 0x00e0, 0x900e, 0x2001, 0x0005, 0x080c,
-	0x6ace, 0x0126, 0x2091, 0x8000, 0x080c, 0xbe35, 0x080c, 0x6893,
-	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, 0x3376, 0x080c, 0x48ab, 0x0904, 0x3379,
-	0x080c, 0x631d, 0x0904, 0x3376, 0x080c, 0x63bf, 0x0904, 0x3376,
-	0x0804, 0x4319, 0x81ff, 0x1904, 0x3376, 0x080c, 0x48c7, 0x0904,
-	0x3379, 0x080c, 0x644d, 0x0904, 0x3376, 0x2019, 0x0005, 0x79a8,
-	0x080c, 0x63da, 0x0904, 0x3376, 0x7888, 0x908a, 0x1000, 0x1a04,
-	0x3379, 0x8003, 0x800b, 0x810b, 0x9108, 0x080c, 0x804d, 0x7984,
-	0xd184, 0x1904, 0x3344, 0x0804, 0x4319, 0x0126, 0x2091, 0x8000,
-	0x81ff, 0x0118, 0x2009, 0x0001, 0x0450, 0x2029, 0x07ff, 0x6458,
-	0x2400, 0x9506, 0x01f8, 0x2508, 0x080c, 0x6256, 0x11d8, 0x080c,
-	0x644d, 0x1128, 0x2009, 0x0002, 0x62bc, 0x2518, 0x00c0, 0x2019,
-	0x0004, 0x900e, 0x080c, 0x63da, 0x1118, 0x2009, 0x0006, 0x0078,
-	0x7884, 0x908a, 0x1000, 0x1270, 0x8003, 0x800b, 0x810b, 0x9108,
-	0x080c, 0x804d, 0x8529, 0x1ae0, 0x012e, 0x0804, 0x3344, 0x012e,
-	0x0804, 0x3376, 0x012e, 0x0804, 0x3379, 0x080c, 0x48ab, 0x0904,
-	0x3379, 0x080c, 0x631d, 0x0904, 0x3376, 0xbaa0, 0x2019, 0x0005,
-	0x00c6, 0x9066, 0x080c, 0x8582, 0x0076, 0x903e, 0x080c, 0x8470,
-	0x900e, 0x080c, 0xd2d5, 0x007e, 0x00ce, 0x080c, 0x63b9, 0x0804,
-	0x3344, 0x080c, 0x48ab, 0x0904, 0x3379, 0x080c, 0x63b9, 0x2208,
-	0x0804, 0x3344, 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, 0x3673, 0x2300, 0x9218, 0x00ee, 0x00de,
-	0x015e, 0x0804, 0x3344, 0x00f6, 0x0016, 0x907d, 0x0138, 0x9006,
-	0x8000, 0x2f0c, 0x81ff, 0x0110, 0x2178, 0x0cd0, 0x001e, 0x00fe,
-	0x0005, 0x2069, 0x190e, 0x6910, 0x62b8, 0x0804, 0x3344, 0x81ff,
-	0x0120, 0x2009, 0x0001, 0x0804, 0x3376, 0x0126, 0x2091, 0x8000,
-	0x080c, 0x53ae, 0x0128, 0x2009, 0x0007, 0x012e, 0x0804, 0x3376,
-	0x012e, 0x6158, 0x9190, 0x3145, 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, 0x6faa, 0x1118, 0x2031,
-	0x0004, 0x0038, 0xd79c, 0x0120, 0x2009, 0x0005, 0x0804, 0x3376,
-	0x9036, 0x7e9a, 0x7f9e, 0x0804, 0x3344, 0x6148, 0x624c, 0x2019,
-	0x195e, 0x231c, 0x2001, 0x195f, 0x2004, 0x789a, 0x0804, 0x3344,
-	0x0126, 0x2091, 0x8000, 0x6138, 0x623c, 0x6340, 0x012e, 0x0804,
-	0x3344, 0x080c, 0x48c7, 0x0904, 0x3379, 0xba44, 0xbb38, 0x0804,
-	0x3344, 0x080c, 0x0db4, 0x080c, 0x48c7, 0x2110, 0x0904, 0x3379,
-	0xb804, 0x908c, 0x00ff, 0x918e, 0x0006, 0x0140, 0x9084, 0xff00,
-	0x9086, 0x0600, 0x2009, 0x0009, 0x1904, 0x3376, 0x0126, 0x2091,
-	0x8000, 0x2019, 0x0005, 0x00c6, 0x9066, 0x080c, 0x9915, 0x080c,
-	0x8582, 0x0076, 0x903e, 0x080c, 0x8470, 0x900e, 0x080c, 0xd2d5,
-	0x007e, 0x00ce, 0xb807, 0x0407, 0x012e, 0x0804, 0x3344, 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, 0x3344, 0x0126, 0x2091, 0x8000, 0x6138,
-	0x7884, 0x603a, 0x910e, 0xd1b4, 0x190c, 0x0e9b, 0xd0c4, 0x01a8,
-	0x00d6, 0x78a8, 0x2009, 0x1975, 0x200a, 0x78ac, 0x2011, 0x1976,
-	0x2012, 0x2069, 0x0100, 0x6838, 0x9086, 0x0007, 0x1118, 0x2214,
-	0x6a5a, 0x0010, 0x210c, 0x695a, 0x00de, 0x7888, 0x603e, 0x2011,
+	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,
+	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,
+	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,
+	0x7833, 0x0011, 0x0010, 0x7833, 0x0010, 0x7c82, 0x7986, 0x7a8a,
+	0x7b8e, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c,
+	0x11e0, 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,
+	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, 0x6140, 0x788c, 0x6042, 0x910e, 0xd1e4,
-	0x190c, 0x0eb1, 0x6040, 0xd0cc, 0x0120, 0x78b0, 0x2011, 0x0114,
-	0x2012, 0x012e, 0x0804, 0x3344, 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, 0x3379, 0x788c, 0x902d,
-	0x0904, 0x3379, 0x900e, 0x080c, 0x6256, 0x1120, 0xba44, 0xbb38,
-	0xbc46, 0xbd3a, 0x9186, 0x07ff, 0x0190, 0x8108, 0x0ca0, 0x080c,
-	0x48c7, 0x0904, 0x3379, 0x7888, 0x900d, 0x0904, 0x3379, 0x788c,
-	0x9005, 0x0904, 0x3379, 0xba44, 0xb946, 0xbb38, 0xb83a, 0x0804,
-	0x3344, 0x2011, 0xbc09, 0x0010, 0x2011, 0xbc05, 0x080c, 0x53ae,
-	0x1904, 0x3376, 0x00c6, 0x2061, 0x0100, 0x7984, 0x9186, 0x00ff,
-	0x1130, 0x2001, 0x1817, 0x2004, 0x9085, 0xff00, 0x0088, 0x9182,
-	0x007f, 0x16e0, 0x9188, 0x3145, 0x210d, 0x918c, 0x00ff, 0x2001,
-	0x1817, 0x2004, 0x0026, 0x9116, 0x002e, 0x0580, 0x810f, 0x9105,
-	0x0126, 0x2091, 0x8000, 0x0006, 0x080c, 0x9dd9, 0x000e, 0x0510,
-	0x602e, 0x620a, 0x7984, 0x00b6, 0x080c, 0x61fc, 0x2b08, 0x00be,
-	0x1500, 0x6112, 0x6023, 0x0001, 0x080c, 0x4894, 0x01d0, 0x9006,
-	0xa866, 0x7007, 0x0003, 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x701f,
-	0x3824, 0x2900, 0x6016, 0x2009, 0x0032, 0x080c, 0x9ea9, 0x012e,
-	0x00ce, 0x0005, 0x012e, 0x00ce, 0x0804, 0x3376, 0x00ce, 0x0804,
-	0x3379, 0x080c, 0x9e2f, 0x0cb0, 0xa830, 0x9086, 0x0100, 0x0904,
-	0x3376, 0x0804, 0x3344, 0x2061, 0x1a48, 0x0126, 0x2091, 0x8000,
-	0x6000, 0xd084, 0x0170, 0x6104, 0x6208, 0x2061, 0x1800, 0x6350,
-	0x6070, 0x789a, 0x60bc, 0x789e, 0x60b8, 0x78aa, 0x012e, 0x0804,
-	0x3344, 0x900e, 0x2110, 0x0c88, 0x81ff, 0x1904, 0x3376, 0x080c,
-	0x6faa, 0x0904, 0x3376, 0x0126, 0x2091, 0x8000, 0x6250, 0x6070,
-	0x9202, 0x0248, 0x9085, 0x0001, 0x080c, 0x26d9, 0x080c, 0x55c8,
-	0x012e, 0x0804, 0x3344, 0x012e, 0x0804, 0x3379, 0x0006, 0x0016,
-	0x00c6, 0x00e6, 0x2001, 0x1981, 0x2070, 0x2061, 0x185b, 0x6008,
-	0x2072, 0x900e, 0x2011, 0x1400, 0x080c, 0x8277, 0x7206, 0x00ee,
-	0x00ce, 0x001e, 0x000e, 0x0005, 0x0126, 0x2091, 0x8000, 0x81ff,
-	0x0128, 0x012e, 0x2021, 0x400b, 0x0804, 0x3346, 0x7884, 0xd0fc,
-	0x0148, 0x2001, 0x002a, 0x2004, 0x9082, 0x00e1, 0x0288, 0x012e,
-	0x0804, 0x3379, 0x2001, 0x002a, 0x2004, 0x2069, 0x185b, 0x6908,
-	0x9102, 0x1230, 0x012e, 0x0804, 0x3379, 0x012e, 0x0804, 0x3376,
-	0x080c, 0x9dae, 0x0dd0, 0x7884, 0xd0fc, 0x0904, 0x38ef, 0x00c6,
-	0x080c, 0x4894, 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, 0x3a75, 0x0928,
-	0x7014, 0x2048, 0xad2c, 0xac28, 0xab1c, 0xaa18, 0xa930, 0xa808,
+	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,
+	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, 0x080c,
-	0x48dd, 0x701f, 0x39b2, 0x7023, 0x0001, 0x012e, 0x0005, 0x0046,
-	0x0086, 0x0096, 0x00a6, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6,
-	0x080c, 0x385e, 0x2001, 0x1977, 0x2003, 0x0000, 0x2021, 0x000a,
-	0x2061, 0x0100, 0x6104, 0x0016, 0x60bb, 0x0000, 0x60bf, 0x32e1,
-	0x60bf, 0x0012, 0x080c, 0x3ae4, 0x080c, 0x3aa3, 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,
-	0x3e77, 0x008e, 0x00ee, 0x00fe, 0x080c, 0x3da4, 0x080c, 0x3ca9,
-	0x05b8, 0x2001, 0x020b, 0x2004, 0x9084, 0x0140, 0x1db8, 0x080c,
-	0x3eeb, 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, 0x3cb3, 0x080c, 0x3a9e, 0x0058, 0x080c, 0x3a9e, 0x080c,
-	0x3e0f, 0x080c, 0x3d9a, 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, 0x129f, 0x2009, 0x0028, 0x080c, 0x2275,
-	0x2001, 0x0227, 0x200c, 0x2102, 0x00fe, 0x00ee, 0x00de, 0x00ce,
-	0x00be, 0x00ae, 0x009e, 0x008e, 0x004e, 0x2001, 0x1977, 0x2004,
-	0x9005, 0x1118, 0x012e, 0x0804, 0x3344, 0x012e, 0x2021, 0x400c,
-	0x0804, 0x3346, 0x0016, 0x0026, 0x0036, 0x0046, 0x0056, 0x0076,
-	0x0086, 0x0096, 0x00d6, 0x0156, 0x7014, 0x2048, 0x7020, 0x20a8,
-	0x8000, 0x7022, 0xa804, 0x9005, 0x0904, 0x3a0e, 0x2048, 0x1f04,
-	0x39c2, 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, 0x48dd, 0x701f, 0x39b2, 0x00b0, 0x8906, 0x8006, 0x8007,
-	0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x001b, 0x21a8, 0x27e0,
-	0x2098, 0x27e8, 0x20a0, 0x0006, 0x080c, 0x0f68, 0x000e, 0x080c,
-	0x48e0, 0x701f, 0x39b2, 0x015e, 0x00de, 0x009e, 0x008e, 0x007e,
-	0x005e, 0x004e, 0x003e, 0x002e, 0x001e, 0x0005, 0x7014, 0x2048,
-	0xa864, 0x9086, 0x0103, 0x1118, 0x701f, 0x3a73, 0x0450, 0x7014,
-	0x2048, 0xa868, 0xc0fd, 0xa86a, 0x2009, 0x007f, 0x080c, 0x61f6,
-	0x0110, 0x9006, 0x0030, 0xb813, 0x00ff, 0xb817, 0xfffd, 0x080c,
-	0xc004, 0x015e, 0x00de, 0x009e, 0x008e, 0x007e, 0x005e, 0x004e,
-	0x003e, 0x002e, 0x001e, 0x0904, 0x3376, 0x0016, 0x0026, 0x0036,
-	0x0046, 0x0056, 0x0076, 0x0086, 0x0096, 0x00d6, 0x0156, 0x701f,
-	0x3a45, 0x7007, 0x0003, 0x0804, 0x3a03, 0xa830, 0x9086, 0x0100,
-	0x2021, 0x400c, 0x0904, 0x3346, 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, 0x0f68, 0x000e, 0x080c, 0x48e0, 0x007e, 0x701f, 0x39b2,
-	0x7023, 0x0001, 0x0005, 0x0804, 0x3344, 0x0156, 0x00c6, 0xa814,
-	0x908a, 0x001e, 0x0218, 0xa833, 0x001e, 0x0010, 0xa832, 0x0078,
-	0x81ff, 0x0168, 0x0016, 0x080c, 0x4894, 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, 0x4894, 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,
-	0x2275, 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8, 0xa86e, 0x601a,
-	0xa873, 0x0000, 0x601f, 0x0000, 0x78ca, 0x9006, 0x600a, 0x600e,
-	0x00ce, 0x00ee, 0x00fe, 0x0005, 0x00e6, 0x080c, 0x4894, 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,
-	0x2a62, 0x1130, 0x9006, 0x080c, 0x29ba, 0x9006, 0x080c, 0x299d,
-	0x7884, 0x9084, 0x0007, 0x0002, 0x3b2f, 0x3b38, 0x3b41, 0x3b2c,
-	0x3b2c, 0x3b2c, 0x3b2c, 0x3b2c, 0x012e, 0x0804, 0x3379, 0x2009,
-	0x0114, 0x2104, 0x9085, 0x0800, 0x200a, 0x080c, 0x3cfd, 0x00c0,
-	0x2009, 0x0114, 0x2104, 0x9085, 0x4000, 0x200a, 0x080c, 0x3cfd,
-	0x0078, 0x080c, 0x6faa, 0x1128, 0x012e, 0x2009, 0x0016, 0x0804,
-	0x3376, 0x81ff, 0x0128, 0x012e, 0x2021, 0x400b, 0x0804, 0x3346,
-	0x0086, 0x0096, 0x00a6, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6,
-	0x080c, 0x385e, 0x2009, 0x0101, 0x210c, 0x0016, 0x7ec8, 0x7dcc,
-	0x9006, 0x2068, 0x2060, 0x2058, 0x080c, 0x3fc6, 0x080c, 0x3f16,
-	0x903e, 0x2720, 0x00f6, 0x00e6, 0x0086, 0x2940, 0x2071, 0x1a3d,
-	0x2079, 0x0090, 0x00d6, 0x2069, 0x0000, 0x6884, 0xd0b4, 0x0120,
-	0x68d4, 0x780e, 0x68d0, 0x780a, 0x00de, 0x2011, 0x0001, 0x080c,
-	0x3e77, 0x080c, 0x2a6a, 0x080c, 0x2a6a, 0x080c, 0x2a6a, 0x080c,
-	0x2a6a, 0x080c, 0x3e77, 0x008e, 0x00ee, 0x00fe, 0x080c, 0x3da4,
-	0x2009, 0x9c40, 0x8109, 0x11b0, 0x080c, 0x3cb3, 0x2001, 0x0004,
-	0x200c, 0x918c, 0xfffd, 0x2102, 0x001e, 0x00fe, 0x00ee, 0x00de,
-	0x00ce, 0x00be, 0x00ae, 0x009e, 0x008e, 0x2009, 0x0017, 0x080c,
-	0x3376, 0x0cf8, 0x2001, 0x020b, 0x2004, 0x9084, 0x0140, 0x1d10,
-	0x00f6, 0x2079, 0x0000, 0x7884, 0x00fe, 0xd0bc, 0x0178, 0x2001,
-	0x0201, 0x200c, 0x81ff, 0x0150, 0x080c, 0x3d82, 0x2d00, 0x9c05,
-	0x9b05, 0x0120, 0x080c, 0x3cb3, 0x0804, 0x3c60, 0x080c, 0x3eeb,
-	0x080c, 0x3e0f, 0x080c, 0x3d65, 0x080c, 0x3d9a, 0x00f6, 0x2079,
-	0x0100, 0x7824, 0xd0ac, 0x0130, 0x8b58, 0x080c, 0x3cb3, 0x00fe,
-	0x0804, 0x3c60, 0x00fe, 0x080c, 0x3ca9, 0x1150, 0x8d68, 0x2001,
-	0x0032, 0x2602, 0x2001, 0x0033, 0x2502, 0x080c, 0x3cb3, 0x0080,
-	0x87ff, 0x0138, 0x2001, 0x0201, 0x2004, 0x9005, 0x1908, 0x8739,
-	0x0038, 0x2001, 0x1a3a, 0x2004, 0x9086, 0x0000, 0x1904, 0x3bb0,
-	0x2001, 0x032f, 0x2003, 0x00f6, 0x8631, 0x1208, 0x8529, 0x2500,
-	0x9605, 0x0904, 0x3c60, 0x7884, 0xd0bc, 0x0128, 0x2d00, 0x9c05,
-	0x9b05, 0x1904, 0x3c60, 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,
-	0x2275, 0x2900, 0xa85a, 0xa813, 0x0019, 0x7884, 0xd0a4, 0x1180,
-	0xa817, 0x0000, 0x00c6, 0x20a9, 0x0004, 0x2061, 0x0090, 0x602b,
-	0x0008, 0x2001, 0x0203, 0x2004, 0x1f04, 0x3c37, 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, 0x3b6a,
-	0x001e, 0x00c6, 0x2001, 0x032a, 0x2003, 0x0004, 0x2061, 0x0100,
-	0x6027, 0x0002, 0x6106, 0x2011, 0x020d, 0x2013, 0x0020, 0x2001,
-	0x0004, 0x200c, 0x918c, 0xfffd, 0x2102, 0x080c, 0x129f, 0x7884,
-	0x9084, 0x0003, 0x9086, 0x0002, 0x01a0, 0x2009, 0x0028, 0x080c,
-	0x2275, 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, 0x3344, 0x012e, 0x2021, 0x400c, 0x0804,
-	0x3346, 0x9085, 0x0001, 0x1d04, 0x3cb2, 0x2091, 0x6000, 0x8420,
-	0x9486, 0x0064, 0x0005, 0x2001, 0x0105, 0x2003, 0x0010, 0x2001,
-	0x032a, 0x2003, 0x0004, 0x2001, 0x1a3a, 0x2003, 0x0000, 0x0071,
-	0x2009, 0x0048, 0x080c, 0x2275, 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, 0x2275, 0x782c, 0xd0fc, 0x0d88, 0x080c,
-	0x3eeb, 0x7000, 0x9086, 0x0000, 0x1d58, 0x782b, 0x0004, 0x782c,
-	0xd0ac, 0x1de8, 0x2009, 0x0040, 0x080c, 0x2275, 0x782b, 0x0002,
-	0x7003, 0x0000, 0x00ee, 0x00fe, 0x0005, 0x00f6, 0x2079, 0x0100,
-	0x2001, 0x1817, 0x200c, 0x7932, 0x7936, 0x080c, 0x26b9, 0x7850,
-	0x9084, 0xfbff, 0x9085, 0x0030, 0x7852, 0x2019, 0x01f4, 0x8319,
-	0x1df0, 0x9084, 0xffcf, 0x9085, 0x2000, 0x7852, 0x20a9, 0x0046,
-	0x1d04, 0x3d18, 0x2091, 0x6000, 0x1f04, 0x3d18, 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, 0x3d38, 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, 0x2b21, 0x7827, 0x0020, 0x7843, 0x0000, 0x9006, 0x080c,
-	0x2b21, 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, 0x3a94, 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, 0x3eeb, 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, 0x3e77,
-	0x2011, 0x0001, 0x080c, 0x3e77, 0x00fe, 0x00ee, 0x0005, 0x00f6,
-	0x00e6, 0x2071, 0x1a3a, 0x2079, 0x0320, 0x792c, 0xd1fc, 0x0904,
-	0x3e74, 0x782b, 0x0002, 0x9026, 0xd19c, 0x1904, 0x3e70, 0x7000,
-	0x0002, 0x3e74, 0x3e25, 0x3e55, 0x3e70, 0xd1bc, 0x1170, 0xd1dc,
-	0x1190, 0x8001, 0x7002, 0x2011, 0x0001, 0x080c, 0x3e77, 0x0904,
-	0x3e74, 0x080c, 0x3e77, 0x0804, 0x3e74, 0x00f6, 0x2079, 0x0300,
-	0x78bf, 0x0000, 0x00fe, 0x7810, 0x7914, 0x782b, 0x0004, 0x7812,
-	0x7916, 0x2001, 0x0201, 0x200c, 0x81ff, 0x0de8, 0x080c, 0x3d82,
-	0x2009, 0x0001, 0x00f6, 0x2079, 0x0300, 0x78b8, 0x00fe, 0xd0ec,
-	0x0110, 0x2009, 0x0011, 0x792a, 0x00f8, 0x8001, 0x7002, 0x9184,
-	0x0880, 0x1140, 0x782c, 0xd0fc, 0x1904, 0x3e19, 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, 0x0db4, 0x9398, 0x3ea5, 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, 0x3ee2, 0x3ed9, 0x3ed0,
-	0x3ec7, 0x3ebe, 0x3eb5, 0x3eac, 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, 0x3f12, 0x3efe, 0x3f09, 0x8001, 0x7002,
-	0xd19c, 0x1180, 0x2011, 0x0001, 0x080c, 0x3e77, 0x190c, 0x3e77,
-	0x0048, 0x8001, 0x7002, 0x782c, 0xd0fc, 0x1d38, 0x2011, 0x0001,
-	0x080c, 0x3e77, 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, 0x4894, 0xa813,
-	0x0019, 0xaf16, 0x2900, 0xa85a, 0x978a, 0x0007, 0x0220, 0x2138,
-	0x2009, 0x0007, 0x0010, 0x2708, 0x903e, 0x0096, 0xa858, 0x2048,
-	0xa85c, 0x9080, 0x0019, 0x009e, 0x080c, 0x3f8e, 0x1d68, 0x2900,
-	0xa85a, 0x00d0, 0x080c, 0x4894, 0xa813, 0x0019, 0xa817, 0x0001,
+	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, 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8, 0xa86e,
-	0x2001, 0x002b, 0x2004, 0xa872, 0x2061, 0x0090, 0x2079, 0x0100,
-	0x2001, 0x1981, 0x2004, 0x6036, 0x2009, 0x0040, 0x080c, 0x2275,
-	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, 0x4894,
-	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, 0x4894, 0x2940, 0xa813, 0x0019,
-	0xaf16, 0x2900, 0xa85a, 0x978a, 0x0007, 0x0220, 0x2138, 0x2009,
-	0x0007, 0x0010, 0x2708, 0x903e, 0x0096, 0xa858, 0x2048, 0xa85c,
-	0x9080, 0x0019, 0x009e, 0x080c, 0x3f8e, 0x1d68, 0x2900, 0xa85a,
-	0x00d8, 0x080c, 0x4894, 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,
-	0x3344, 0x7d98, 0x7c9c, 0x0804, 0x3446, 0x080c, 0x6faa, 0x190c,
-	0x5caa, 0x2069, 0x185b, 0x2d00, 0x2009, 0x0030, 0x7a8c, 0x7b88,
-	0x7c9c, 0x7d98, 0x2039, 0x0001, 0x080c, 0x48dd, 0x701f, 0x4061,
-	0x0005, 0x080c, 0x53a9, 0x1130, 0x3b00, 0x3a08, 0xc194, 0xc095,
-	0x20d8, 0x21d0, 0x2069, 0x185b, 0x6800, 0x9005, 0x0904, 0x3379,
-	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, 0x3379, 0x9288, 0x3145,
-	0x210d, 0x918c, 0x00ff, 0x6162, 0xd0dc, 0x0130, 0x6828, 0x908a,
-	0x007f, 0x1a04, 0x3379, 0x605a, 0x6888, 0x9084, 0x0030, 0x8004,
-	0x8004, 0x8004, 0x8004, 0x0006, 0x2009, 0x1989, 0x9080, 0x27ac,
-	0x2005, 0x200a, 0x000e, 0x2009, 0x198a, 0x9080, 0x27b0, 0x2005,
-	0x200a, 0x6808, 0x908a, 0x0100, 0x0a04, 0x3379, 0x908a, 0x0841,
-	0x1a04, 0x3379, 0x9084, 0x0007, 0x1904, 0x3379, 0x680c, 0x9005,
-	0x0904, 0x3379, 0x6810, 0x9005, 0x0904, 0x3379, 0x6848, 0x6940,
-	0x910a, 0x1a04, 0x3379, 0x8001, 0x0904, 0x3379, 0x684c, 0x6944,
-	0x910a, 0x1a04, 0x3379, 0x8001, 0x0904, 0x3379, 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,
-	0x72bd, 0x080c, 0x6643, 0x080c, 0x6678, 0x6808, 0x602a, 0x080c,
-	0x21e7, 0x2009, 0x0170, 0x200b, 0x0080, 0xa001, 0xa001, 0x200b,
-	0x0000, 0x0036, 0x6b08, 0x080c, 0x2713, 0x003e, 0x6000, 0x9086,
-	0x0000, 0x1904, 0x41de, 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, 0x8148, 0x00c6, 0x900e, 0x20a9,
-	0x0001, 0x6b70, 0xd384, 0x0510, 0x0068, 0x2009, 0x0100, 0x210c,
-	0x918e, 0x0008, 0x1110, 0x839d, 0x0010, 0x83f5, 0x3e18, 0x12b0,
-	0x3508, 0x8109, 0x080c, 0x7889, 0x6878, 0x6016, 0x6874, 0x2008,
-	0x9084, 0xff00, 0x8007, 0x600a, 0x9184, 0x00ff, 0x6006, 0x8108,
-	0x1118, 0x6003, 0x0003, 0x0010, 0x6003, 0x0001, 0x1f04, 0x414d,
-	0x00ce, 0x00c6, 0x2061, 0x1974, 0x2063, 0x0001, 0x9006, 0x080c,
-	0x29ba, 0x9006, 0x080c, 0x299d, 0x0000, 0x00ce, 0x00e6, 0x2c70,
-	0x080c, 0x0e80, 0x00ee, 0x6888, 0xd0ec, 0x0130, 0x2011, 0x0114,
-	0x2204, 0x9085, 0x0100, 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,
-	0x2788, 0x2001, 0x1945, 0x2102, 0x0008, 0x2102, 0x00c6, 0x2061,
-	0x0100, 0x602f, 0x0040, 0x602f, 0x0000, 0x00ce, 0x080c, 0x6faa,
-	0x0128, 0x080c, 0x4ca6, 0x0110, 0x080c, 0x26d9, 0x60d0, 0x9005,
-	0x01c0, 0x6003, 0x0001, 0x2009, 0x41c6, 0x00d0, 0x080c, 0x6faa,
-	0x1168, 0x2011, 0x6e2b, 0x080c, 0x803f, 0x2011, 0x6e1e, 0x080c,
-	0x8113, 0x080c, 0x7291, 0x080c, 0x6edc, 0x0040, 0x080c, 0x5ba4,
-	0x0028, 0x6003, 0x0004, 0x2009, 0x41de, 0x0010, 0x0804, 0x3344,
-	0x2001, 0x0170, 0x2004, 0x9084, 0x00ff, 0x9086, 0x004c, 0x1118,
-	0x2091, 0x30bd, 0x0817, 0x2091, 0x303d, 0x0817, 0x6000, 0x9086,
-	0x0000, 0x0904, 0x3376, 0x2069, 0x185b, 0x7890, 0x6842, 0x7894,
-	0x6846, 0x2d00, 0x2009, 0x0030, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98,
-	0x2039, 0x0001, 0x0804, 0x48e0, 0x9006, 0x080c, 0x26d9, 0x81ff,
-	0x1904, 0x3376, 0x080c, 0x6faa, 0x11b0, 0x080c, 0x728c, 0x080c,
-	0x5ce5, 0x080c, 0x3140, 0x0118, 0x6130, 0xc18d, 0x6132, 0x080c,
-	0xc23b, 0x0130, 0x080c, 0x6fcd, 0x1118, 0x080c, 0x6f82, 0x0038,
-	0x080c, 0x6edc, 0x0020, 0x080c, 0x5caa, 0x080c, 0x5ba4, 0x0804,
-	0x3344, 0x81ff, 0x1904, 0x3376, 0x080c, 0x6faa, 0x1110, 0x0804,
-	0x3376, 0x6190, 0x81ff, 0x01a8, 0x704f, 0x0000, 0x2001, 0x1c80,
-	0x2009, 0x0040, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x0126, 0x2091,
-	0x8000, 0x2039, 0x0001, 0x080c, 0x48e0, 0x701f, 0x3342, 0x012e,
-	0x0005, 0x704f, 0x0001, 0x00d6, 0x2069, 0x1c80, 0x20a9, 0x0040,
-	0x20e9, 0x0001, 0x20a1, 0x1c80, 0x2019, 0xffff, 0x4304, 0x6558,
-	0x9588, 0x3145, 0x210d, 0x918c, 0x00ff, 0x216a, 0x900e, 0x2011,
-	0x0002, 0x2100, 0x9506, 0x01a8, 0x080c, 0x6256, 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, 0x5c35, 0x0804, 0x4236, 0x080c, 0x48c7,
-	0x0904, 0x3379, 0x080c, 0x4894, 0x1120, 0x2009, 0x0002, 0x0804,
-	0x3376, 0x080c, 0x539a, 0xd0b4, 0x0558, 0x7884, 0x908e, 0x007e,
-	0x0538, 0x908e, 0x007f, 0x0520, 0x908e, 0x0080, 0x0508, 0x080c,
-	0x313b, 0x1148, 0xb800, 0xd08c, 0x11d8, 0xb804, 0x9084, 0x00ff,
-	0x9086, 0x0006, 0x11a8, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a,
-	0x080c, 0xbd04, 0x1120, 0x2009, 0x0003, 0x0804, 0x3376, 0x7007,
-	0x0003, 0x701f, 0x42c4, 0x0005, 0x080c, 0x48c7, 0x0904, 0x3379,
-	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, 0x0f68, 0x0070, 0x20a9, 0x0004, 0xa85c, 0x9080, 0x000a,
-	0x20a0, 0xb8b4, 0x20e0, 0xb8b8, 0x9080, 0x000a, 0x2098, 0x080c,
-	0x0f68, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0,
-	0x9080, 0x0002, 0x2009, 0x002b, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98,
-	0x0804, 0x48e0, 0x81ff, 0x1904, 0x3376, 0x080c, 0x48ab, 0x0904,
-	0x3379, 0x080c, 0x63c8, 0x0904, 0x3376, 0x0058, 0xa878, 0x9005,
-	0x0120, 0x2009, 0x0004, 0x0804, 0x3376, 0xa974, 0xaa94, 0x0804,
-	0x3344, 0x080c, 0x53a2, 0x0904, 0x3344, 0x701f, 0x430e, 0x7007,
-	0x0003, 0x0005, 0x81ff, 0x1904, 0x3376, 0x7888, 0x908a, 0x1000,
-	0x1a04, 0x3379, 0x080c, 0x48c7, 0x0904, 0x3379, 0x080c, 0x657a,
-	0x0120, 0x080c, 0x6582, 0x1904, 0x3379, 0x080c, 0x644d, 0x0904,
-	0x3376, 0x2019, 0x0004, 0x900e, 0x080c, 0x63da, 0x0904, 0x3376,
-	0x7984, 0x7a88, 0x04c9, 0x08a8, 0xa89c, 0x908a, 0x1000, 0x12f8,
-	0x080c, 0x48c5, 0x01e0, 0x080c, 0x657a, 0x0118, 0x080c, 0x6582,
-	0x11b0, 0x080c, 0x644d, 0x2009, 0x0002, 0x0168, 0x2009, 0x0002,
-	0x2019, 0x0004, 0x080c, 0x63da, 0x2009, 0x0003, 0x0120, 0xa998,
-	0xaa9c, 0x00d1, 0x0060, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897,
-	0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897,
-	0x4000, 0x080c, 0x53a2, 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, 0x6256,
-	0x1138, 0x2200, 0x8003, 0x800b, 0x810b, 0x9108, 0x080c, 0x804d,
-	0x0005, 0x81ff, 0x1904, 0x3376, 0x798c, 0x2001, 0x1958, 0x918c,
-	0x8000, 0x2102, 0x080c, 0x48ab, 0x0904, 0x3379, 0x080c, 0x657a,
-	0x0120, 0x080c, 0x6582, 0x1904, 0x3379, 0x080c, 0x631d, 0x0904,
-	0x3376, 0x080c, 0x63d1, 0x0904, 0x3376, 0x2001, 0x1958, 0x2004,
-	0xd0fc, 0x1904, 0x3344, 0x0804, 0x4319, 0xa9a0, 0x2001, 0x1958,
-	0x918c, 0x8000, 0xc18d, 0x2102, 0x080c, 0x48b8, 0x01a0, 0x080c,
-	0x657a, 0x0118, 0x080c, 0x6582, 0x1170, 0x080c, 0x631d, 0x2009,
-	0x0002, 0x0128, 0x080c, 0x63d1, 0x1170, 0x2009, 0x0003, 0xa897,
-	0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001,
-	0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0x2001, 0x1958, 0x2004,
-	0xd0fc, 0x1128, 0x080c, 0x53a2, 0x0110, 0x9006, 0x0018, 0x900e,
-	0x9085, 0x0001, 0x2001, 0x0000, 0x0005, 0x81ff, 0x1904, 0x3376,
-	0x798c, 0x2001, 0x1957, 0x918c, 0x8000, 0x2102, 0x080c, 0x48ab,
-	0x0904, 0x3379, 0x080c, 0x657a, 0x0120, 0x080c, 0x6582, 0x1904,
-	0x3379, 0x080c, 0x631d, 0x0904, 0x3376, 0x080c, 0x63bf, 0x0904,
-	0x3376, 0x2001, 0x1957, 0x2004, 0xd0fc, 0x1904, 0x3344, 0x0804,
-	0x4319, 0xa9a0, 0x2001, 0x1957, 0x918c, 0x8000, 0xc18d, 0x2102,
-	0x080c, 0x48b8, 0x01a0, 0x080c, 0x657a, 0x0118, 0x080c, 0x6582,
-	0x1170, 0x080c, 0x631d, 0x2009, 0x0002, 0x0128, 0x080c, 0x63bf,
-	0x1170, 0x2009, 0x0003, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897,
-	0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897,
-	0x4000, 0x2001, 0x1957, 0x2004, 0xd0fc, 0x1128, 0x080c, 0x53a2,
-	0x0110, 0x9006, 0x0018, 0x900e, 0x9085, 0x0001, 0x2001, 0x0000,
-	0x0005, 0x6100, 0x0804, 0x3344, 0x080c, 0x48c7, 0x0904, 0x3379,
-	0x080c, 0x53ae, 0x1904, 0x3376, 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, 0x0200, 0x0804,
-	0x3344, 0x78a8, 0x909c, 0x0003, 0xd0ac, 0x1158, 0xd0b4, 0x1148,
-	0x939a, 0x0003, 0x1a04, 0x3376, 0x6258, 0x7884, 0x9206, 0x1904,
-	0x44c9, 0x2031, 0x1848, 0x2009, 0x013c, 0x2136, 0x2001, 0x1840,
-	0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x2039, 0x0001, 0x0006, 0x78a8,
-	0x9084, 0x0080, 0x11c8, 0x0006, 0x0036, 0x2001, 0x1a56, 0x201c,
-	0x7b9a, 0x2003, 0x0000, 0x2001, 0x1a57, 0x201c, 0x7b9e, 0x2003,
-	0x0000, 0x2001, 0x1a58, 0x201c, 0x7ba2, 0x2003, 0x0000, 0x003e,
-	0x000e, 0x000e, 0x0804, 0x48e0, 0x000e, 0x2031, 0x0000, 0x2061,
-	0x18b6, 0x2c44, 0xa66a, 0xa17a, 0xa772, 0xa076, 0xa28e, 0xa392,
-	0xa496, 0xa59a, 0x080c, 0x10d5, 0x7007, 0x0002, 0x701f, 0x44e9,
-	0x0005, 0x81ff, 0x1904, 0x3376, 0x080c, 0x48c7, 0x0904, 0x3379,
-	0x080c, 0x657a, 0x1904, 0x3376, 0x00c6, 0x080c, 0x4894, 0x00ce,
-	0x0904, 0x3376, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x7ea8,
-	0x080c, 0xbcaa, 0x0904, 0x3376, 0x7007, 0x0003, 0x701f, 0x4503,
-	0x0005, 0x080c, 0x4033, 0x0006, 0x0036, 0x2001, 0x1a56, 0x201c,
-	0x7b9a, 0x2003, 0x0000, 0x2001, 0x1a57, 0x201c, 0x7b9e, 0x2003,
-	0x0000, 0x2001, 0x1a58, 0x201c, 0x7ba2, 0x2003, 0x0000, 0x003e,
-	0x000e, 0x0804, 0x3344, 0xa830, 0x9086, 0x0100, 0x0904, 0x3376,
+	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,
+	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,
+	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,
+	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,
-	0x48e0, 0x9006, 0x080c, 0x26d9, 0x78a8, 0x9084, 0x00ff, 0x9086,
-	0x00ff, 0x0118, 0x81ff, 0x1904, 0x3376, 0x080c, 0x6faa, 0x0110,
-	0x080c, 0x5caa, 0x7888, 0x908a, 0x1000, 0x1a04, 0x3379, 0x7984,
-	0x9186, 0x00ff, 0x0138, 0x9182, 0x007f, 0x1a04, 0x3379, 0x2100,
-	0x080c, 0x26a3, 0x0026, 0x00c6, 0x0126, 0x2091, 0x8000, 0x2061,
+	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, 0x6faa, 0x1158, 0x080c, 0x728c, 0x080c, 0x5ce5,
-	0x9085, 0x0001, 0x080c, 0x6ff1, 0x080c, 0x6edc, 0x00d0, 0x080c,
-	0x9db5, 0x2061, 0x0100, 0x2001, 0x1817, 0x2004, 0x9084, 0x00ff,
+	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, 0x5bd0, 0x080c,
-	0x80d1, 0x7984, 0x080c, 0x6faa, 0x1110, 0x2009, 0x00ff, 0x7a88,
-	0x080c, 0x437c, 0x012e, 0x00ce, 0x002e, 0x0804, 0x3344, 0x7984,
-	0x080c, 0x61f6, 0x2b08, 0x1904, 0x3379, 0x0804, 0x3344, 0x81ff,
-	0x0120, 0x2009, 0x0001, 0x0804, 0x3376, 0x60d8, 0xd0ac, 0x1130,
-	0xd09c, 0x1120, 0x2009, 0x0005, 0x0804, 0x3376, 0x080c, 0x4894,
-	0x1120, 0x2009, 0x0002, 0x0804, 0x3376, 0x7984, 0x9192, 0x0021,
-	0x1a04, 0x3379, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xa85c, 0x9080,
-	0x0019, 0x702a, 0xaf60, 0x7736, 0x080c, 0x48dd, 0x701f, 0x45b7,
-	0x7880, 0x9086, 0x006e, 0x0110, 0x701f, 0x4e58, 0x0005, 0x2009,
-	0x0080, 0x080c, 0x6256, 0x1118, 0x080c, 0x657a, 0x0120, 0x2021,
-	0x400a, 0x0804, 0x3346, 0x00d6, 0x0096, 0xa964, 0xaa6c, 0xab70,
-	0xac74, 0xad78, 0xae7c, 0xa884, 0x90be, 0x0100, 0x0904, 0x4650,
-	0x90be, 0x0112, 0x0904, 0x4650, 0x90be, 0x0113, 0x0904, 0x4650,
-	0x90be, 0x0114, 0x0904, 0x4650, 0x90be, 0x0117, 0x0904, 0x4650,
-	0x90be, 0x011a, 0x0904, 0x4650, 0x90be, 0x011c, 0x0904, 0x4650,
-	0x90be, 0x0121, 0x0904, 0x4637, 0x90be, 0x0131, 0x0904, 0x4637,
-	0x90be, 0x0171, 0x0904, 0x4650, 0x90be, 0x0173, 0x0904, 0x4650,
-	0x90be, 0x01a1, 0x1128, 0xa894, 0x8007, 0xa896, 0x0804, 0x465b,
-	0x90be, 0x0212, 0x0904, 0x4644, 0x90be, 0x0213, 0x05e8, 0x90be,
+	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, 0x3379, 0x7028, 0x9080,
+	0x0300, 0x05b0, 0x009e, 0x00de, 0x0804, 0x351d, 0x7028, 0x9080,
 	0x0010, 0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0007,
-	0x080c, 0x4699, 0x7028, 0x9080, 0x000e, 0x2098, 0x20a0, 0x7034,
-	0x20e0, 0x20e8, 0x20a9, 0x0001, 0x080c, 0x4699, 0x00c8, 0x7028,
+	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, 0x46a6, 0x00b8, 0x7028, 0x9080, 0x000e, 0x2098,
-	0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0001, 0x080c, 0x46a6,
+	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, 0x4894, 0x0550, 0xa868,
+	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, 0xbcc5, 0x1120,
-	0x2009, 0x0003, 0x0804, 0x3376, 0x7007, 0x0003, 0x701f, 0x4690,
-	0x0005, 0x00ce, 0x009e, 0x00de, 0x2009, 0x0002, 0x0804, 0x3376,
-	0xa820, 0x9086, 0x8001, 0x1904, 0x3344, 0x2009, 0x0004, 0x0804,
-	0x3376, 0x0016, 0x0026, 0x3510, 0x20a9, 0x0002, 0x4002, 0x4104,
+	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, 0x3376, 0x60d8,
-	0xd0ac, 0x1160, 0xd09c, 0x0120, 0x2009, 0x0016, 0x0804, 0x3376,
-	0xd09c, 0x1120, 0x2009, 0x0005, 0x0804, 0x3376, 0x7984, 0x78a8,
-	0x2040, 0x080c, 0x9dae, 0x1120, 0x9182, 0x007f, 0x0a04, 0x3379,
-	0x9186, 0x00ff, 0x0904, 0x3379, 0x9182, 0x0800, 0x1a04, 0x3379,
+	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,
-	0x3379, 0x080c, 0x9dae, 0x1120, 0x99cc, 0xff00, 0x0904, 0x3379,
-	0x0126, 0x2091, 0x8000, 0x0026, 0x2011, 0x8008, 0x080c, 0x659e,
-	0x002e, 0x0140, 0x918d, 0x8000, 0x080c, 0x65e8, 0x1118, 0x2001,
-	0x4009, 0x0458, 0x080c, 0x47ae, 0x0560, 0x90c6, 0x4000, 0x1170,
-	0x00c6, 0x0006, 0x900e, 0x080c, 0x6476, 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,
-	0x3346, 0x2b00, 0x7026, 0x0016, 0x00b6, 0x00c6, 0x00e6, 0x2c70,
-	0x080c, 0x9e7c, 0x0904, 0x477b, 0x2b00, 0x6012, 0x080c, 0xbfb5,
-	0x2e58, 0x00ee, 0x00e6, 0x00c6, 0x080c, 0x4894, 0x00ce, 0x2b70,
-	0x1158, 0x080c, 0x9e2f, 0x00ee, 0x00ce, 0x00be, 0x001e, 0x012e,
-	0x2009, 0x0002, 0x0804, 0x3376, 0x900e, 0xa966, 0xa96a, 0x2900,
-	0x6016, 0xa932, 0xa868, 0xc0fd, 0xd88c, 0x0108, 0xc0f5, 0xa86a,
-	0x080c, 0x2fe7, 0x6023, 0x0001, 0x9006, 0x080c, 0x6193, 0x2001,
-	0x0002, 0x080c, 0x61a7, 0x2009, 0x0002, 0x080c, 0x9ea9, 0x78a8,
-	0xd094, 0x0138, 0x00ee, 0x7024, 0x00e6, 0x2058, 0xb8bc, 0xc08d,
-	0xb8be, 0x9085, 0x0001, 0x00ee, 0x00ce, 0x00be, 0x001e, 0x012e,
-	0x1120, 0x2009, 0x0003, 0x0804, 0x3376, 0x7007, 0x0003, 0x701f,
-	0x478a, 0x0005, 0xa830, 0x2008, 0x918e, 0xdead, 0x1120, 0x2021,
-	0x4009, 0x0804, 0x3346, 0x9086, 0x0100, 0x7024, 0x2058, 0x1138,
-	0x2009, 0x0004, 0xba04, 0x9294, 0x00ff, 0x0804, 0x52f7, 0x900e,
-	0xa868, 0xd0f4, 0x1904, 0x3344, 0x080c, 0x6476, 0x1108, 0xc185,
-	0xb800, 0xd0bc, 0x0108, 0xc18d, 0x0804, 0x3344, 0x00e6, 0x00d6,
-	0x0096, 0x83ff, 0x0904, 0x47f6, 0x902e, 0x080c, 0x9dae, 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, 0x657a, 0x1540,
-	0x2001, 0x4000, 0x0430, 0x2001, 0x4007, 0x0418, 0x2001, 0x4006,
-	0x0400, 0x2400, 0x9106, 0x1158, 0xbe14, 0x87ff, 0x1128, 0x86ff,
-	0x0948, 0x080c, 0x9dae, 0x1930, 0x2001, 0x4008, 0x0090, 0x8420,
-	0x8e70, 0x1f04, 0x47c4, 0x85ff, 0x1130, 0x2001, 0x4009, 0x0048,
-	0x2001, 0x0001, 0x0030, 0x080c, 0x61f6, 0x1dd0, 0xbb12, 0xba16,
-	0x9006, 0x9005, 0x009e, 0x00de, 0x00ee, 0x0005, 0x81ff, 0x0120,
-	0x2009, 0x0001, 0x0804, 0x3376, 0x080c, 0x4894, 0x1120, 0x2009,
-	0x0002, 0x0804, 0x3376, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a,
-	0x7884, 0x9005, 0x0904, 0x3379, 0x9096, 0x00ff, 0x0120, 0x9092,
-	0x0004, 0x1a04, 0x3379, 0x2010, 0x2918, 0x080c, 0x2f8d, 0x1120,
-	0x2009, 0x0003, 0x0804, 0x3376, 0x7007, 0x0003, 0x701f, 0x4849,
-	0x0005, 0xa830, 0x9086, 0x0100, 0x1904, 0x3344, 0x2009, 0x0004,
-	0x0804, 0x3376, 0x7984, 0x080c, 0x9dae, 0x1120, 0x9182, 0x007f,
-	0x0a04, 0x3379, 0x9186, 0x00ff, 0x0904, 0x3379, 0x9182, 0x0800,
-	0x1a04, 0x3379, 0x2001, 0x9000, 0x080c, 0x5352, 0x1904, 0x3376,
-	0x0804, 0x3344, 0xa998, 0x080c, 0x9dae, 0x1118, 0x9182, 0x007f,
-	0x0280, 0x9186, 0x00ff, 0x0168, 0x9182, 0x0800, 0x1250, 0x2001,
-	0x9000, 0x080c, 0x5352, 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, 0x0feb, 0x0198, 0x9006,
-	0xa802, 0x7014, 0x9005, 0x1120, 0x2900, 0x7016, 0x701a, 0x0040,
-	0x7018, 0xa802, 0x0086, 0x2040, 0x2900, 0xa006, 0x701a, 0x008e,
-	0x9085, 0x0001, 0x0005, 0x7984, 0x080c, 0x6256, 0x1130, 0x7e88,
+	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,
+	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,
-	0xa998, 0x080c, 0x6256, 0x1130, 0xae9c, 0x9684, 0x3fff, 0x9082,
-	0x4000, 0x0208, 0x905e, 0x8bff, 0x0005, 0xae98, 0x0008, 0x7e84,
-	0x2608, 0x080c, 0x6256, 0x1108, 0x0008, 0x905e, 0x8bff, 0x0005,
-	0x0016, 0x7114, 0x81ff, 0x0128, 0x2148, 0xa904, 0x080c, 0x101d,
-	0x0cc8, 0x7116, 0x711a, 0x001e, 0x0005, 0x2031, 0x0001, 0x0010,
-	0x2031, 0x0000, 0x2061, 0x18b6, 0x2c44, 0xa66a, 0xa17a, 0xa772,
-	0xa076, 0xa28e, 0xa392, 0xa496, 0xa59a, 0x080c, 0x10d5, 0x7007,
-	0x0002, 0x701f, 0x3344, 0x0005, 0x00f6, 0x0126, 0x2091, 0x8000,
-	0x2079, 0x0000, 0x2001, 0x18ae, 0x2004, 0x9005, 0x1190, 0x0e04,
-	0x4911, 0x7a36, 0x7833, 0x0012, 0x7a82, 0x7b86, 0x7c8a, 0x2091,
-	0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x1187, 0x0804,
-	0x4977, 0x0016, 0x0086, 0x0096, 0x00c6, 0x00e6, 0x2071, 0x189c,
-	0x7044, 0x9005, 0x1540, 0x7148, 0x9182, 0x0010, 0x0288, 0x7038,
-	0x2060, 0x080c, 0x0feb, 0x0904, 0x496f, 0xa84b, 0x0000, 0x2900,
-	0x7046, 0x2001, 0x0002, 0x9080, 0x1f33, 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, 0x0db4, 0x2060,
-	0x001e, 0x8108, 0x2105, 0x9005, 0xa146, 0x1520, 0x080c, 0x0feb,
-	0x1130, 0x8109, 0xa946, 0x7148, 0x8109, 0x714a, 0x00d8, 0x9006,
-	0xa806, 0xa84a, 0xa046, 0x2800, 0xa802, 0x2900, 0xa006, 0x7046,
-	0x2001, 0x0002, 0x9080, 0x1f33, 0x2005, 0xa846, 0x0058, 0x2262,
-	0x6306, 0x640a, 0x00ee, 0x00ce, 0x009e, 0x008e, 0x001e, 0x012e,
-	0x00fe, 0x0005, 0x2c00, 0x9082, 0x001b, 0x0002, 0x4999, 0x4999,
-	0x499b, 0x4999, 0x4999, 0x4999, 0x499f, 0x4999, 0x4999, 0x4999,
-	0x49a3, 0x4999, 0x4999, 0x4999, 0x49a7, 0x4999, 0x4999, 0x4999,
-	0x49ab, 0x4999, 0x4999, 0x4999, 0x49af, 0x4999, 0x4999, 0x4999,
-	0x49b4, 0x080c, 0x0db4, 0xa276, 0xa37a, 0xa47e, 0x0898, 0xa286,
-	0xa38a, 0xa48e, 0x0878, 0xa296, 0xa39a, 0xa49e, 0x0858, 0xa2a6,
-	0xa3aa, 0xa4ae, 0x0838, 0xa2b6, 0xa3ba, 0xa4be, 0x0818, 0xa2c6,
-	0xa3ca, 0xa4ce, 0x0804, 0x4972, 0xa2d6, 0xa3da, 0xa4de, 0x0804,
-	0x4972, 0x00e6, 0x2071, 0x189c, 0x7048, 0x9005, 0x0904, 0x4a4b,
-	0x0126, 0x2091, 0x8000, 0x0e04, 0x4a4a, 0x00f6, 0x2079, 0x0000,
-	0x00c6, 0x0096, 0x0086, 0x0076, 0x9006, 0x2038, 0x7040, 0x2048,
-	0x9005, 0x0500, 0xa948, 0x2105, 0x0016, 0x908a, 0x0036, 0x1a0c,
-	0x0db4, 0x2060, 0x001e, 0x8108, 0x2105, 0x9005, 0xa94a, 0x1904,
-	0x4a4d, 0xa804, 0x9005, 0x090c, 0x0db4, 0x7042, 0x2938, 0x2040,
-	0xa003, 0x0000, 0x2001, 0x0002, 0x9080, 0x1f33, 0x2005, 0xa04a,
-	0x0804, 0x4a4d, 0x703c, 0x2060, 0x2c14, 0x6304, 0x6408, 0x650c,
-	0x2200, 0x7836, 0x7833, 0x0012, 0x7882, 0x2300, 0x7886, 0x2400,
-	0x788a, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c,
-	0x1187, 0x87ff, 0x0118, 0x2748, 0x080c, 0x101d, 0x7048, 0x8001,
-	0x704a, 0x9005, 0x1170, 0x7040, 0x2048, 0x9005, 0x0128, 0x080c,
-	0x101d, 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, 0x0db4,
-	0x2048, 0xa800, 0x9005, 0x1de0, 0x2900, 0x7042, 0x2001, 0x0002,
-	0x9080, 0x1f33, 0x2005, 0xa84a, 0x0000, 0x007e, 0x008e, 0x009e,
-	0x00ce, 0x00fe, 0x012e, 0x00ee, 0x0005, 0x2c00, 0x9082, 0x001b,
-	0x0002, 0x4a6c, 0x4a6c, 0x4a6e, 0x4a6c, 0x4a6c, 0x4a6c, 0x4a73,
-	0x4a6c, 0x4a6c, 0x4a6c, 0x4a78, 0x4a6c, 0x4a6c, 0x4a6c, 0x4a7d,
-	0x4a6c, 0x4a6c, 0x4a6c, 0x4a82, 0x4a6c, 0x4a6c, 0x4a6c, 0x4a87,
-	0x4a6c, 0x4a6c, 0x4a6c, 0x4a8c, 0x080c, 0x0db4, 0xaa74, 0xab78,
-	0xac7c, 0x0804, 0x49f8, 0xaa84, 0xab88, 0xac8c, 0x0804, 0x49f8,
-	0xaa94, 0xab98, 0xac9c, 0x0804, 0x49f8, 0xaaa4, 0xaba8, 0xacac,
-	0x0804, 0x49f8, 0xaab4, 0xabb8, 0xacbc, 0x0804, 0x49f8, 0xaac4,
-	0xabc8, 0xaccc, 0x0804, 0x49f8, 0xaad4, 0xabd8, 0xacdc, 0x0804,
-	0x49f8, 0x0026, 0x080c, 0x539a, 0xd0c4, 0x0120, 0x2011, 0x8014,
-	0x080c, 0x48f4, 0x002e, 0x0005, 0x81ff, 0x1904, 0x3376, 0x0126,
-	0x2091, 0x8000, 0x6030, 0xc08d, 0xc085, 0xc0ac, 0x6032, 0x080c,
-	0x6faa, 0x1158, 0x080c, 0x728c, 0x080c, 0x5ce5, 0x9085, 0x0001,
-	0x080c, 0x6ff1, 0x080c, 0x6edc, 0x0010, 0x080c, 0x5ba4, 0x012e,
-	0x0804, 0x3344, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x3376,
-	0x080c, 0x53ae, 0x0120, 0x2009, 0x0007, 0x0804, 0x3376, 0x080c,
-	0x6572, 0x0120, 0x2009, 0x0008, 0x0804, 0x3376, 0x0026, 0x2011,
-	0x0010, 0x080c, 0x659e, 0x002e, 0x0140, 0x7984, 0x080c, 0x65e8,
-	0x1120, 0x2009, 0x4009, 0x0804, 0x3376, 0x7984, 0x080c, 0x61f6,
-	0x1904, 0x3379, 0x2b00, 0x7026, 0x080c, 0x657a, 0x7888, 0x1170,
-	0x9084, 0x0005, 0x1158, 0x900e, 0x080c, 0x6476, 0x1108, 0xc185,
-	0xb800, 0xd0bc, 0x0108, 0xc18d, 0x0804, 0x3344, 0x080c, 0x4894,
-	0x0904, 0x3376, 0x9006, 0xa866, 0xa832, 0xa868, 0xc0fd, 0xa86a,
-	0x080c, 0xbd63, 0x0904, 0x3376, 0x7888, 0xd094, 0x0118, 0xb8bc,
-	0xc08d, 0xb8be, 0x7007, 0x0003, 0x701f, 0x4b5b, 0x0005, 0x2061,
-	0x1800, 0x080c, 0x53ae, 0x2009, 0x0007, 0x1578, 0x080c, 0x6572,
-	0x0118, 0x2009, 0x0008, 0x0448, 0x080c, 0x313b, 0x0120, 0xa998,
-	0x080c, 0x61f6, 0x1530, 0x080c, 0x48c5, 0x0518, 0x080c, 0x657a,
-	0xa89c, 0x1168, 0x9084, 0x0005, 0x1150, 0x900e, 0x080c, 0x6476,
-	0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x00d0, 0xa868,
-	0xc0fc, 0xa86a, 0x080c, 0xbd63, 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, 0x3346, 0x9086, 0x0100, 0x7024, 0x2058,
-	0x1110, 0x0804, 0x52f7, 0x900e, 0x080c, 0x6476, 0x1108, 0xc185,
-	0xb800, 0xd0bc, 0x0108, 0xc18d, 0x0804, 0x3344, 0x080c, 0x53ae,
-	0x0120, 0x2009, 0x0007, 0x0804, 0x3376, 0x7f84, 0x7a8c, 0x7b88,
-	0x7c9c, 0x7d98, 0x080c, 0x4894, 0x1120, 0x2009, 0x0002, 0x0804,
-	0x3376, 0x900e, 0x2130, 0x7126, 0x7132, 0xa860, 0x20e8, 0x7036,
-	0xa85c, 0x9080, 0x0005, 0x702a, 0x20a0, 0x080c, 0x6256, 0x1904,
-	0x4bf9, 0x080c, 0x657a, 0x0120, 0x080c, 0x6582, 0x1904, 0x4bf9,
-	0x080c, 0x6572, 0x1130, 0x080c, 0x6476, 0x1118, 0xd79c, 0x0904,
-	0x4bf9, 0xd794, 0x1110, 0xd784, 0x01a8, 0xb8b4, 0x20e0, 0xb8b8,
-	0x9080, 0x0006, 0x2098, 0x3400, 0xd794, 0x0160, 0x20a9, 0x0008,
-	0x4003, 0x2098, 0x20a0, 0x3d00, 0x20e0, 0x20a9, 0x0002, 0x080c,
-	0x46a6, 0x0048, 0x20a9, 0x0004, 0x4003, 0x2098, 0x20a0, 0x3d00,
-	0x20e0, 0x080c, 0x46a6, 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, 0x4699, 0x9c80, 0x0026, 0x2098, 0xb8b4, 0x20e0,
-	0x20a9, 0x0002, 0x4003, 0xd794, 0x0110, 0x96b0, 0x000b, 0x96b0,
-	0x0005, 0x8108, 0x080c, 0x9dae, 0x0118, 0x9186, 0x0800, 0x0040,
-	0xd78c, 0x0120, 0x9186, 0x0800, 0x0170, 0x0018, 0x9186, 0x007e,
-	0x0150, 0xd794, 0x0118, 0x9686, 0x0020, 0x0010, 0x9686, 0x0028,
-	0x0150, 0x0804, 0x4b95, 0x86ff, 0x1120, 0x7124, 0x810b, 0x0804,
-	0x3344, 0x7033, 0x0001, 0x7122, 0x7024, 0x9600, 0x7026, 0x772e,
-	0x2061, 0x18b6, 0x2c44, 0xa06b, 0x0000, 0xa67a, 0x7034, 0xa072,
-	0x7028, 0xa076, 0xa28e, 0xa392, 0xa496, 0xa59a, 0x080c, 0x10d5,
-	0x7007, 0x0002, 0x701f, 0x4c35, 0x0005, 0x7030, 0x9005, 0x1180,
-	0x7120, 0x7028, 0x20a0, 0x772c, 0x9036, 0x7034, 0x20e8, 0x2061,
-	0x18b6, 0x2c44, 0xa28c, 0xa390, 0xa494, 0xa598, 0x0804, 0x4b95,
-	0x7124, 0x810b, 0x0804, 0x3344, 0x2029, 0x007e, 0x7984, 0x7a88,
-	0x7b8c, 0x7c98, 0x9184, 0xff00, 0x8007, 0x90e2, 0x0020, 0x0a04,
-	0x3379, 0x9502, 0x0a04, 0x3379, 0x9184, 0x00ff, 0x90e2, 0x0020,
-	0x0a04, 0x3379, 0x9502, 0x0a04, 0x3379, 0x9284, 0xff00, 0x8007,
-	0x90e2, 0x0020, 0x0a04, 0x3379, 0x9502, 0x0a04, 0x3379, 0x9284,
-	0x00ff, 0x90e2, 0x0020, 0x0a04, 0x3379, 0x9502, 0x0a04, 0x3379,
-	0x9384, 0xff00, 0x8007, 0x90e2, 0x0020, 0x0a04, 0x3379, 0x9502,
-	0x0a04, 0x3379, 0x9384, 0x00ff, 0x90e2, 0x0020, 0x0a04, 0x3379,
-	0x9502, 0x0a04, 0x3379, 0x9484, 0xff00, 0x8007, 0x90e2, 0x0020,
-	0x0a04, 0x3379, 0x9502, 0x0a04, 0x3379, 0x9484, 0x00ff, 0x90e2,
-	0x0020, 0x0a04, 0x3379, 0x9502, 0x0a04, 0x3379, 0x2061, 0x1961,
-	0x6102, 0x6206, 0x630a, 0x640e, 0x0804, 0x3344, 0x0006, 0x080c,
-	0x539a, 0xd0cc, 0x000e, 0x0005, 0x0006, 0x080c, 0x539e, 0xd0bc,
-	0x000e, 0x0005, 0x6170, 0x7a84, 0x6300, 0x82ff, 0x1118, 0x7986,
-	0x0804, 0x3344, 0x83ff, 0x1904, 0x3379, 0x2001, 0xfff0, 0x9200,
-	0x1a04, 0x3379, 0x2019, 0xffff, 0x6074, 0x9302, 0x9200, 0x0a04,
-	0x3379, 0x7986, 0x6272, 0x0804, 0x3344, 0x080c, 0x53ae, 0x1904,
-	0x3376, 0x7c88, 0x7d84, 0x7e98, 0x7f8c, 0x080c, 0x4894, 0x0904,
-	0x3376, 0x900e, 0x901e, 0x7326, 0x7332, 0xa860, 0x20e8, 0x7036,
-	0xa85c, 0x9080, 0x0003, 0x702a, 0x20a0, 0x91d8, 0x1000, 0x2b5c,
-	0x8bff, 0x0178, 0x080c, 0x657a, 0x0118, 0x080c, 0x6582, 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,
-	0x8277, 0x2208, 0x0804, 0x3344, 0x7033, 0x0001, 0x7122, 0x7024,
-	0x9300, 0x7026, 0x2061, 0x18b6, 0x2c44, 0xa06b, 0x0000, 0xa37a,
-	0x7028, 0xa076, 0x7034, 0xa072, 0xa48e, 0xa592, 0xa696, 0xa79a,
-	0x080c, 0x10d5, 0x7007, 0x0002, 0x701f, 0x4d27, 0x0005, 0x7030,
-	0x9005, 0x1178, 0x7120, 0x7028, 0x20a0, 0x901e, 0x7034, 0x20e8,
-	0x2061, 0x18b6, 0x2c44, 0xa48c, 0xa590, 0xa694, 0xa798, 0x0804,
-	0x4ce5, 0x7224, 0x900e, 0x2001, 0x0003, 0x080c, 0x8277, 0x2208,
-	0x0804, 0x3344, 0x00f6, 0x00e6, 0x080c, 0x53ae, 0x2009, 0x0007,
-	0x1904, 0x4dba, 0x2071, 0x189c, 0x745c, 0x84ff, 0x2009, 0x000e,
-	0x1904, 0x4dba, 0xac9c, 0xad98, 0xaea4, 0xafa0, 0x0096, 0x080c,
-	0x1004, 0x2009, 0x0002, 0x0904, 0x4dba, 0x2900, 0x705e, 0x900e,
-	0x901e, 0x7356, 0x7362, 0xa860, 0x7066, 0xa85c, 0x9080, 0x0003,
-	0x705a, 0x20a0, 0x91d8, 0x1000, 0x2b5c, 0x8bff, 0x0178, 0x080c,
-	0x657a, 0x0118, 0x080c, 0x6582, 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, 0x8277, 0x2208, 0x009e,
-	0xa897, 0x4000, 0xa99a, 0x715c, 0x81ff, 0x090c, 0x0db4, 0x2148,
-	0x080c, 0x101d, 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, 0x4dc6, 0x000e, 0xa0a2, 0x080c, 0x10d5,
-	0x9006, 0x0048, 0x009e, 0xa897, 0x4005, 0xa99a, 0x900e, 0x9085,
-	0x0001, 0x2001, 0x0030, 0x00ee, 0x00fe, 0x0005, 0x00f6, 0xa0a0,
-	0x904d, 0x090c, 0x0db4, 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, 0x8277, 0xaa9a, 0x715c, 0x81ff, 0x090c, 0x0db4,
-	0x2148, 0x080c, 0x101d, 0x705f, 0x0000, 0xa0a0, 0x2048, 0x0126,
-	0x2091, 0x8000, 0x080c, 0x68a0, 0x012e, 0xa09f, 0x0000, 0xa0a3,
-	0x0000, 0x00ee, 0x00fe, 0x0005, 0x91d8, 0x1000, 0x2b5c, 0x8bff,
-	0x0178, 0x080c, 0x657a, 0x0118, 0x080c, 0x6582, 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, 0x0db4, 0x2148, 0x080c, 0x101d, 0x9006, 0x705e,
-	0x918d, 0x0001, 0x2008, 0xa0a0, 0x2048, 0x0126, 0x2091, 0x8000,
-	0x080c, 0x68a0, 0x012e, 0xa09f, 0x0000, 0xa0a3, 0x0000, 0x0070,
-	0x7063, 0x0001, 0x7152, 0x7054, 0x9300, 0x7056, 0xa37a, 0xa48e,
-	0xa592, 0xa696, 0xa79a, 0x080c, 0x10d5, 0x9006, 0x00ee, 0x0005,
-	0x0096, 0xa88c, 0x90be, 0x7000, 0x0148, 0x90be, 0x7100, 0x0130,
-	0x90be, 0x7200, 0x0118, 0x009e, 0x0804, 0x3379, 0xa884, 0xa988,
-	0x080c, 0x2670, 0x1518, 0x080c, 0x61f6, 0x1500, 0x7126, 0xbe12,
-	0xbd16, 0xae7c, 0x080c, 0x4894, 0x01c8, 0x080c, 0x4894, 0x01b0,
-	0x009e, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0xa823, 0x0000,
-	0xa804, 0x2048, 0x080c, 0xbce5, 0x1120, 0x2009, 0x0003, 0x0804,
-	0x3376, 0x7007, 0x0003, 0x701f, 0x4e93, 0x0005, 0x009e, 0x2009,
-	0x0002, 0x0804, 0x3376, 0x7124, 0x080c, 0x30e2, 0xa820, 0x9086,
-	0x8001, 0x1120, 0x2009, 0x0004, 0x0804, 0x3376, 0x2900, 0x7022,
-	0xa804, 0x0096, 0x2048, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f,
-	0x9084, 0xffc0, 0x009e, 0x9080, 0x0002, 0x0076, 0x0006, 0x2098,
-	0x20a0, 0x27e0, 0x27e8, 0x20a9, 0x002a, 0x080c, 0x0f68, 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,
-	0x48e0, 0x97c6, 0x7200, 0x11b8, 0x96c2, 0x0054, 0x02a0, 0x000e,
-	0x007e, 0x2061, 0x18b6, 0x2c44, 0xa076, 0xa772, 0xa07b, 0x002a,
-	0xa28e, 0xa392, 0xa496, 0xa59a, 0x080c, 0x10d5, 0x7007, 0x0002,
-	0x701f, 0x4eef, 0x0005, 0x000e, 0x007e, 0x0804, 0x3379, 0x7020,
-	0x2048, 0xa804, 0x2048, 0xa804, 0x2048, 0x8906, 0x8006, 0x8007,
-	0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0002, 0x2098, 0x20a0,
-	0x27e0, 0x27e8, 0x20a9, 0x002a, 0x080c, 0x0f68, 0x2100, 0x2238,
-	0x2061, 0x18b6, 0x2c44, 0xa28c, 0xa390, 0xa494, 0xa598, 0x2009,
-	0x002a, 0x0804, 0x48e0, 0x81ff, 0x1904, 0x3376, 0x798c, 0x2001,
-	0x1956, 0x918c, 0x8000, 0x2102, 0x080c, 0x48ab, 0x0904, 0x3379,
-	0x080c, 0x657a, 0x0120, 0x080c, 0x6582, 0x1904, 0x3379, 0x080c,
-	0x631d, 0x0904, 0x3376, 0x0126, 0x2091, 0x8000, 0x080c, 0x63e3,
-	0x012e, 0x0904, 0x3376, 0x2001, 0x1956, 0x2004, 0xd0fc, 0x1904,
-	0x3344, 0x0804, 0x4319, 0xa9a0, 0x2001, 0x1956, 0x918c, 0x8000,
-	0xc18d, 0x2102, 0x080c, 0x48b8, 0x01a0, 0x080c, 0x657a, 0x0118,
-	0x080c, 0x6582, 0x1170, 0x080c, 0x631d, 0x2009, 0x0002, 0x0128,
-	0x080c, 0x63e3, 0x1170, 0x2009, 0x0003, 0xa897, 0x4005, 0xa99a,
-	0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030,
-	0x0005, 0xa897, 0x4000, 0x2001, 0x1956, 0x2004, 0xd0fc, 0x1128,
-	0x080c, 0x53a2, 0x0110, 0x9006, 0x0018, 0x900e, 0x9085, 0x0001,
-	0x2001, 0x0000, 0x0005, 0x78a8, 0xd08c, 0x1118, 0xd084, 0x0904,
-	0x428e, 0x080c, 0x48c7, 0x0904, 0x3379, 0x080c, 0x4894, 0x1120,
-	0x2009, 0x0002, 0x0804, 0x3376, 0x080c, 0x657a, 0x0130, 0x908e,
-	0x0004, 0x0118, 0x908e, 0x0005, 0x15a0, 0x78a8, 0xd08c, 0x0120,
-	0xb800, 0xc08c, 0xb802, 0x0028, 0x080c, 0x539a, 0xd0b4, 0x0904,
-	0x42c8, 0x7884, 0x908e, 0x007e, 0x0904, 0x42c8, 0x908e, 0x007f,
-	0x0904, 0x42c8, 0x908e, 0x0080, 0x0904, 0x42c8, 0xb800, 0xd08c,
-	0x1904, 0x42c8, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x080c,
-	0xbd04, 0x1120, 0x2009, 0x0003, 0x0804, 0x3376, 0x7007, 0x0003,
-	0x701f, 0x4fbb, 0x0005, 0x080c, 0x48c7, 0x0904, 0x3379, 0x0804,
-	0x42c8, 0x080c, 0x313b, 0x0108, 0x0005, 0x2009, 0x1833, 0x210c,
-	0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x3376, 0x080c, 0x53ae,
-	0x0120, 0x2009, 0x0007, 0x0804, 0x3376, 0x080c, 0x6572, 0x0120,
-	0x2009, 0x0008, 0x0804, 0x3376, 0xb89c, 0xd0a4, 0x1118, 0xd0ac,
-	0x1904, 0x42c8, 0x9006, 0xa866, 0xa832, 0xa868, 0xc0fd, 0xa86a,
-	0x080c, 0xbd63, 0x1120, 0x2009, 0x0003, 0x0804, 0x3376, 0x7007,
-	0x0003, 0x701f, 0x4ff4, 0x0005, 0xa830, 0x9086, 0x0100, 0x1120,
-	0x2009, 0x0004, 0x0804, 0x52f7, 0x080c, 0x48c7, 0x0904, 0x3379,
-	0x0804, 0x4f8d, 0x81ff, 0x2009, 0x0001, 0x1904, 0x3376, 0x080c,
-	0x53ae, 0x2009, 0x0007, 0x1904, 0x3376, 0x080c, 0x6572, 0x0120,
-	0x2009, 0x0008, 0x0804, 0x3376, 0x080c, 0x48c7, 0x0904, 0x3379,
-	0x080c, 0x657a, 0x2009, 0x0009, 0x1904, 0x3376, 0x080c, 0x4894,
-	0x2009, 0x0002, 0x0904, 0x3376, 0x9006, 0xa866, 0xa832, 0xa868,
-	0xc0fd, 0xa86a, 0x7988, 0x9194, 0xff00, 0x918c, 0x00ff, 0x9006,
-	0x82ff, 0x1128, 0xc0ed, 0xa952, 0x798c, 0xa956, 0x0038, 0x928e,
-	0x0100, 0x1904, 0x3379, 0xc0e5, 0xa952, 0xa956, 0xa83e, 0x080c,
-	0xbfb6, 0x2009, 0x0003, 0x0904, 0x3376, 0x7007, 0x0003, 0x701f,
-	0x504a, 0x0005, 0xa830, 0x9086, 0x0100, 0x2009, 0x0004, 0x0904,
-	0x3376, 0x0804, 0x3344, 0x7aa8, 0x9284, 0xc000, 0x0148, 0xd2ec,
-	0x01a0, 0x080c, 0x53ae, 0x1188, 0x2009, 0x0014, 0x0804, 0x3376,
-	0xd2dc, 0x1568, 0x81ff, 0x2009, 0x0001, 0x1904, 0x3376, 0x080c,
-	0x53ae, 0x2009, 0x0007, 0x1904, 0x3376, 0xd2f4, 0x0130, 0x9284,
-	0x5000, 0x080c, 0x5375, 0x0804, 0x3344, 0xd2fc, 0x0158, 0x080c,
-	0x48c7, 0x0904, 0x3379, 0x7984, 0x9284, 0x9000, 0x080c, 0x5352,
-	0x0804, 0x3344, 0x080c, 0x48c7, 0x0904, 0x3379, 0xb804, 0x9084,
-	0x00ff, 0x9086, 0x0006, 0x2009, 0x0009, 0x1904, 0x5133, 0x080c,
-	0x4894, 0x2009, 0x0002, 0x0904, 0x5133, 0xa85c, 0x9080, 0x001b,
-	0xaf60, 0x2009, 0x0008, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x080c,
-	0x48dd, 0x701f, 0x50a4, 0x0005, 0xa86c, 0x9086, 0x0500, 0x1138,
-	0xa870, 0x9005, 0x1120, 0xa874, 0x9084, 0xff00, 0x0110, 0x1904,
-	0x3379, 0xa866, 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0x48c7,
-	0x1110, 0x0804, 0x3379, 0x2009, 0x0043, 0x080c, 0xc01e, 0x2009,
-	0x0003, 0x0904, 0x5133, 0x7007, 0x0003, 0x701f, 0x50c8, 0x0005,
-	0xa830, 0x9086, 0x0100, 0x2009, 0x0004, 0x0904, 0x5133, 0x7984,
-	0x7aa8, 0x9284, 0x1000, 0x080c, 0x5352, 0x0804, 0x3344, 0x00c6,
-	0xaab0, 0x9284, 0xc000, 0x0140, 0xd2ec, 0x0168, 0x080c, 0x53ae,
-	0x1150, 0x2009, 0x0014, 0x04f0, 0x2061, 0x1800, 0x080c, 0x53ae,
-	0x2009, 0x0007, 0x15b8, 0xd2f4, 0x0128, 0x9284, 0x5000, 0x080c,
-	0x5375, 0x0050, 0xd2fc, 0x0178, 0x080c, 0x48c5, 0x0588, 0xa998,
-	0x9284, 0x9000, 0x080c, 0x5352, 0xa87b, 0x0000, 0xa883, 0x0000,
-	0xa897, 0x4000, 0x0438, 0x080c, 0x48c5, 0x0510, 0x080c, 0x657a,
-	0x2009, 0x0009, 0x11b8, 0xa8c4, 0x9086, 0x0500, 0x11c8, 0xa8c8,
-	0x9005, 0x11b0, 0xa8cc, 0x9084, 0xff00, 0x1190, 0x080c, 0x48c5,
-	0x1108, 0x0070, 0x2009, 0x004b, 0x080c, 0xc01e, 0x2009, 0x0003,
-	0x0108, 0x0078, 0x0429, 0x19c0, 0xa897, 0x4005, 0xa99a, 0x0010,
-	0xa897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x00ce,
-	0x0005, 0x9006, 0x0ce0, 0x7aa8, 0xd2dc, 0x0904, 0x3376, 0x0016,
-	0x7984, 0x9284, 0x1000, 0xc0fd, 0x080c, 0x5352, 0x001e, 0x1904,
-	0x3376, 0x0804, 0x3344, 0x00f6, 0x2d78, 0x0011, 0x00fe, 0x0005,
-	0xaab0, 0xd2dc, 0x0150, 0x0016, 0xa998, 0x9284, 0x1000, 0xc0fd,
-	0x080c, 0x5352, 0x001e, 0x9085, 0x0001, 0x0005, 0x81ff, 0x0120,
-	0x2009, 0x0001, 0x0804, 0x3376, 0x080c, 0x53ae, 0x0120, 0x2009,
-	0x0007, 0x0804, 0x3376, 0x7984, 0x7ea8, 0x96b4, 0x00ff, 0x080c,
-	0x6256, 0x1904, 0x3379, 0x9186, 0x007f, 0x0138, 0x080c, 0x657a,
-	0x0120, 0x2009, 0x0009, 0x0804, 0x3376, 0x080c, 0x4894, 0x1120,
-	0x2009, 0x0002, 0x0804, 0x3376, 0xa867, 0x0000, 0xa868, 0xc0fd,
-	0xa86a, 0x2001, 0x0100, 0x8007, 0xa80a, 0x080c, 0xbd1e, 0x1120,
-	0x2009, 0x0003, 0x0804, 0x3376, 0x7007, 0x0003, 0x701f, 0x5191,
-	0x0005, 0xa808, 0x8007, 0x9086, 0x0100, 0x1120, 0x2009, 0x0004,
-	0x0804, 0x3376, 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, 0x48e0,
-	0x080c, 0x4894, 0x1120, 0x2009, 0x0002, 0x0804, 0x3376, 0x7984,
-	0x9194, 0xff00, 0x918c, 0x00ff, 0x8217, 0x82ff, 0x1118, 0x7023,
-	0x198b, 0x0040, 0x92c6, 0x0001, 0x1118, 0x7023, 0x19a5, 0x0010,
-	0x0804, 0x3379, 0x2009, 0x001a, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98,
-	0xa85c, 0x9080, 0x0019, 0xaf60, 0x080c, 0x48dd, 0x701f, 0x51e1,
-	0x0005, 0x2001, 0x182d, 0x2003, 0x0001, 0xa85c, 0x9080, 0x0019,
-	0x2098, 0xa860, 0x20e0, 0x20a9, 0x001a, 0x7020, 0x20a0, 0x20e9,
-	0x0001, 0x4003, 0x0804, 0x3344, 0x080c, 0x4894, 0x1120, 0x2009,
-	0x0002, 0x0804, 0x3376, 0x7984, 0x9194, 0xff00, 0x918c, 0x00ff,
-	0x8217, 0x82ff, 0x1118, 0x2099, 0x198b, 0x0040, 0x92c6, 0x0001,
-	0x1118, 0x2099, 0x19a5, 0x0010, 0x0804, 0x3379, 0xa85c, 0x9080,
-	0x0019, 0x20a0, 0xa860, 0x20e8, 0x20a9, 0x001a, 0x20e1, 0x0001,
-	0x4003, 0x2009, 0x001a, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xa85c,
-	0x9080, 0x0019, 0xaf60, 0x0804, 0x48e0, 0x7884, 0x908a, 0x1000,
-	0x1a04, 0x3379, 0x0126, 0x2091, 0x8000, 0x8003, 0x800b, 0x810b,
-	0x9108, 0x00c6, 0x2061, 0x19d2, 0x6142, 0x00ce, 0x012e, 0x0804,
-	0x3344, 0x00c6, 0x080c, 0x6faa, 0x1160, 0x080c, 0x728c, 0x080c,
-	0x5ce5, 0x9085, 0x0001, 0x080c, 0x6ff1, 0x080c, 0x6edc, 0x080c,
-	0x0db4, 0x2061, 0x1800, 0x6030, 0xc09d, 0x6032, 0x080c, 0x5ba4,
-	0x00ce, 0x0005, 0x00c6, 0x2001, 0x1800, 0x2004, 0x908e, 0x0000,
-	0x0904, 0x3376, 0x7884, 0x9005, 0x0188, 0x7888, 0x2061, 0x1974,
-	0x2c0c, 0x2062, 0x080c, 0x2a52, 0x01a0, 0x080c, 0x2a5a, 0x0188,
-	0x080c, 0x2a62, 0x0170, 0x2162, 0x0804, 0x3379, 0x2061, 0x0100,
-	0x6038, 0x9086, 0x0007, 0x1118, 0x2009, 0x0001, 0x0010, 0x2009,
-	0x0000, 0x7884, 0x9086, 0x0002, 0x1548, 0x2061, 0x0100, 0x6028,
-	0xc09c, 0x602a, 0x0026, 0x2011, 0x0003, 0x080c, 0x975b, 0x2011,
-	0x0002, 0x080c, 0x9765, 0x002e, 0x080c, 0x9673, 0x0036, 0x901e,
-	0x080c, 0x96e9, 0x003e, 0x60e3, 0x0000, 0x080c, 0xd8ee, 0x080c,
-	0xd909, 0x9085, 0x0001, 0x080c, 0x6ff1, 0x9006, 0x080c, 0x2b21,
-	0x2001, 0x1800, 0x2003, 0x0004, 0x6027, 0x0008, 0x00ce, 0x0804,
-	0x3344, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x3376, 0x080c,
-	0x53ae, 0x0120, 0x2009, 0x0007, 0x0804, 0x3376, 0x7984, 0x7ea8,
-	0x96b4, 0x00ff, 0x080c, 0x6256, 0x1904, 0x3379, 0x9186, 0x007f,
-	0x0138, 0x080c, 0x657a, 0x0120, 0x2009, 0x0009, 0x0804, 0x3376,
-	0x080c, 0x4894, 0x1120, 0x2009, 0x0002, 0x0804, 0x3376, 0xa867,
-	0x0000, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xbd21, 0x1120, 0x2009,
-	0x0003, 0x0804, 0x3376, 0x7007, 0x0003, 0x701f, 0x52e0, 0x0005,
-	0xa830, 0x9086, 0x0100, 0x1120, 0x2009, 0x0004, 0x0804, 0x3376,
+	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,
+	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,
+	0x0026, 0x2098, 0xb8b4, 0x20e0, 0x20a9, 0x0002, 0x4003, 0xd794,
+	0x0110, 0x96b0, 0x000b, 0x96b0, 0x0005, 0x8108, 0x080c, 0xa062,
+	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,
+	0x7024, 0x9600, 0x7026, 0x772e, 0x2061, 0x18b6, 0x2c44, 0xa06b,
+	0x0000, 0xa67a, 0x7034, 0xa072, 0x7028, 0xa076, 0xa28e, 0xa392,
+	0xa496, 0xa59a, 0x080c, 0x112e, 0x7007, 0x0002, 0x701f, 0x4e61,
+	0x0005, 0x7030, 0x9005, 0x1180, 0x7120, 0x7028, 0x20a0, 0x772c,
+	0x9036, 0x7034, 0x20e8, 0x2061, 0x18b6, 0x2c44, 0xa28c, 0xa390,
+	0xa494, 0xa598, 0x0804, 0x4dc1, 0x7124, 0x810b, 0x0804, 0x34e8,
+	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,
+	0x7332, 0xa860, 0x20e8, 0x7036, 0xa85c, 0x9080, 0x0003, 0x702a,
+	0x20a0, 0x91d8, 0x1000, 0x2b5c, 0x8bff, 0x0178, 0x080c, 0x67c3,
+	0x0118, 0x080c, 0x67cb, 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,
+	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,
+	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,
+	0x7066, 0xa85c, 0x9080, 0x0003, 0x705a, 0x20a0, 0x91d8, 0x1000,
+	0x2b5c, 0x8bff, 0x0178, 0x080c, 0x67c3, 0x0118, 0x080c, 0x67cb,
+	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,
+	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,
+	0x4005, 0xa99a, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x00ee,
+	0x00fe, 0x0005, 0x00f6, 0xa0a0, 0x904d, 0x090c, 0x0dfa, 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,
+	0x012e, 0xa09f, 0x0000, 0xa0a3, 0x0000, 0x00ee, 0x00fe, 0x0005,
+	0x91d8, 0x1000, 0x2b5c, 0x8bff, 0x0178, 0x080c, 0x67c3, 0x0118,
+	0x080c, 0x67cb, 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,
+	0x0000, 0xa0a3, 0x0000, 0x0070, 0x7063, 0x0001, 0x7152, 0x7054,
+	0x9300, 0x7056, 0xa37a, 0xa48e, 0xa592, 0xa696, 0xa79a, 0x080c,
+	0x112e, 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,
+	0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x009e, 0x9080,
+	0x0002, 0x0076, 0x0006, 0x2098, 0x20a0, 0x27e0, 0x27e8, 0x20a9,
+	0x002a, 0x080c, 0x0fae, 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,
+	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,
+	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,
+	0x0003, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e,
+	0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0x2001,
+	0x1956, 0x2004, 0xd0fc, 0x1128, 0x080c, 0x55e3, 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,
+	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,
+	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,
+	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, 0x48e0, 0xa898,
-	0x9086, 0x000d, 0x1904, 0x3376, 0x2021, 0x4005, 0x0126, 0x2091,
-	0x8000, 0x0e04, 0x5304, 0x0010, 0x012e, 0x0cc0, 0x7c36, 0x9486,
+	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,
-	0x48d0, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c,
-	0x1187, 0x7007, 0x0001, 0x2091, 0x5000, 0x700f, 0x0000, 0x012e,
+	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, 0x3344, 0x0126, 0x2091, 0x8000, 0x00b6, 0x00c6, 0x90e4,
-	0xc000, 0x0128, 0x0006, 0x080c, 0xbb88, 0x000e, 0x1198, 0xd0e4,
-	0x0160, 0x9180, 0x1000, 0x2004, 0x905d, 0x0160, 0x080c, 0x5cff,
-	0x080c, 0x9dae, 0x0110, 0xb817, 0x0000, 0x9006, 0x00ce, 0x00be,
+	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, 0x0180, 0x9186, 0x007e, 0x0168, 0x9186, 0x007f,
-	0x0150, 0x9186, 0x0080, 0x0138, 0x9186, 0x00ff, 0x0120, 0x0026,
-	0x2200, 0x0801, 0x002e, 0x001e, 0x8108, 0x1f04, 0x537d, 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, 0x3379, 0x810c, 0x0016, 0x080c, 0x4894, 0x080c,
-	0x0ef3, 0x2100, 0x2238, 0x7d84, 0x7c88, 0x7b8c, 0x7a90, 0x001e,
-	0x080c, 0x48dd, 0x701f, 0x53d5, 0x0005, 0x2079, 0x0000, 0x7d94,
-	0x7c98, 0x7ba8, 0x7aac, 0x79a4, 0x810c, 0x2061, 0x18b6, 0x2c44,
-	0xa770, 0xa074, 0x2071, 0x189c, 0x080c, 0x48e0, 0x701f, 0x53e9,
-	0x0005, 0x2061, 0x18b6, 0x2c44, 0x0016, 0x0026, 0xa270, 0xa174,
-	0x080c, 0x0efb, 0x002e, 0x001e, 0x080c, 0x0fa8, 0x9006, 0xa802,
-	0xa806, 0x0804, 0x3344, 0x0126, 0x0156, 0x0136, 0x0146, 0x01c6,
-	0x01d6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2061, 0x0100, 0x2069,
-	0x0200, 0x2071, 0x1800, 0x6044, 0xd0a4, 0x11e8, 0xd084, 0x0118,
-	0x080c, 0x55a4, 0x0068, 0xd08c, 0x0118, 0x080c, 0x54ad, 0x0040,
-	0xd094, 0x0118, 0x080c, 0x547d, 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, 0x5c61, 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, 0x5b47, 0x080c, 0x80d1, 0x0005, 0x2001, 0x187d, 0x2004,
-	0xd08c, 0x0110, 0x705b, 0xffff, 0x7084, 0x9005, 0x1528, 0x2011,
-	0x5b47, 0x080c, 0x803f, 0x6040, 0x9094, 0x0010, 0x9285, 0x0020,
-	0x6042, 0x20a9, 0x00c8, 0x6044, 0xd08c, 0x1168, 0x1f04, 0x5493,
-	0x6242, 0x7097, 0x0000, 0x6040, 0x9094, 0x0010, 0x9285, 0x0080,
-	0x6042, 0x6242, 0x0048, 0x6242, 0x7097, 0x0000, 0x708b, 0x0000,
-	0x9006, 0x080c, 0x5cea, 0x0000, 0x0005, 0x7088, 0x908a, 0x0003,
-	0x1a0c, 0x0db4, 0x000b, 0x0005, 0x54b7, 0x5508, 0x55a3, 0x00f6,
-	0x0016, 0x6900, 0x918c, 0x0800, 0x708b, 0x0001, 0x2001, 0x015d,
-	0x2003, 0x0000, 0x6803, 0x00fc, 0x20a9, 0x0004, 0x6800, 0x9084,
-	0x00fc, 0x0120, 0x1f04, 0x54c6, 0x080c, 0x0db4, 0x68a0, 0x68a2,
-	0x689c, 0x689e, 0x6898, 0x689a, 0xa001, 0x918d, 0x1600, 0x6902,
-	0x001e, 0x6837, 0x0020, 0x080c, 0x5cc6, 0x2079, 0x1c00, 0x7833,
-	0x1101, 0x7837, 0x0000, 0x20e1, 0x0001, 0x2099, 0x1805, 0x20e9,
-	0x0001, 0x20a1, 0x1c0e, 0x20a9, 0x0004, 0x4003, 0x080c, 0x9c37,
-	0x20e1, 0x0001, 0x2099, 0x1c00, 0x20e9, 0x0000, 0x20a1, 0x0240,
-	0x20a9, 0x0014, 0x4003, 0x60c3, 0x000c, 0x600f, 0x0000, 0x080c,
-	0x5b78, 0x00fe, 0x9006, 0x708e, 0x6043, 0x0008, 0x6042, 0x0005,
-	0x00f6, 0x708c, 0x708f, 0x0000, 0x9025, 0x0904, 0x5580, 0x6020,
-	0xd0b4, 0x1904, 0x557e, 0x719c, 0x81ff, 0x0904, 0x556c, 0x9486,
-	0x000c, 0x1904, 0x5579, 0x9480, 0x0018, 0x8004, 0x20a8, 0x080c,
-	0x5cbf, 0x2011, 0x0260, 0x2019, 0x1c00, 0x220c, 0x2304, 0x9106,
-	0x11e8, 0x8210, 0x8318, 0x1f04, 0x5525, 0x6043, 0x0004, 0x2061,
-	0x0140, 0x605b, 0xbc94, 0x605f, 0xf0f0, 0x2061, 0x0100, 0x6043,
-	0x0006, 0x708b, 0x0002, 0x7097, 0x0002, 0x2009, 0x07d0, 0x2011,
-	0x5b4e, 0x080c, 0x80d1, 0x080c, 0x5cc6, 0x04c0, 0x080c, 0x5cbf,
-	0x2079, 0x0260, 0x7930, 0x918e, 0x1101, 0x1558, 0x7834, 0x9005,
-	0x1540, 0x7900, 0x918c, 0x00ff, 0x1118, 0x7804, 0x9005, 0x0190,
-	0x080c, 0x5cbf, 0x2011, 0x026e, 0x2019, 0x1805, 0x20a9, 0x0004,
-	0x220c, 0x2304, 0x9102, 0x0230, 0x11a0, 0x8210, 0x8318, 0x1f04,
-	0x5560, 0x0078, 0x709f, 0x0000, 0x080c, 0x5cbf, 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,
-	0x9c37, 0x20e1, 0x0001, 0x2099, 0x1c00, 0x20e9, 0x0000, 0x20a1,
-	0x0240, 0x20a9, 0x0014, 0x4003, 0x60c3, 0x000c, 0x2011, 0x19c9,
-	0x2013, 0x0000, 0x708f, 0x0000, 0x60a3, 0x0056, 0x60a7, 0x9575,
-	0x080c, 0x93be, 0x08d8, 0x0005, 0x7094, 0x908a, 0x001d, 0x1a0c,
-	0x0db4, 0x000b, 0x0005, 0x55d5, 0x55e8, 0x5611, 0x5631, 0x5657,
-	0x5686, 0x56ac, 0x56e4, 0x570a, 0x5738, 0x5773, 0x57ab, 0x57c9,
-	0x57f4, 0x5816, 0x5831, 0x583b, 0x586f, 0x5895, 0x58c4, 0x58ea,
-	0x5922, 0x5966, 0x59a3, 0x59c4, 0x5a1d, 0x5a3f, 0x5a6d, 0x5a6d,
-	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, 0x5b4e, 0x080c, 0x80d1, 0x0005,
-	0x00f6, 0x708c, 0x9086, 0x0014, 0x1510, 0x6042, 0x6020, 0xd0b4,
-	0x11f0, 0x080c, 0x5cbf, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1102,
-	0x11a0, 0x7834, 0x9005, 0x1188, 0x7a38, 0xd2fc, 0x0128, 0x70c0,
-	0x9005, 0x1110, 0x70c3, 0x0001, 0x2011, 0x5b4e, 0x080c, 0x803f,
-	0x7097, 0x0010, 0x080c, 0x583b, 0x0010, 0x708f, 0x0000, 0x00fe,
-	0x0005, 0x00f6, 0x7097, 0x0003, 0x6043, 0x0004, 0x2011, 0x5b4e,
-	0x080c, 0x803f, 0x080c, 0x5c43, 0x2079, 0x0240, 0x7833, 0x1102,
-	0x7837, 0x0000, 0x20a9, 0x0008, 0x9f88, 0x000e, 0x200b, 0x0000,
-	0x8108, 0x1f04, 0x5626, 0x60c3, 0x0014, 0x080c, 0x5b78, 0x00fe,
-	0x0005, 0x00f6, 0x708c, 0x9005, 0x0500, 0x2011, 0x5b4e, 0x080c,
-	0x803f, 0x9086, 0x0014, 0x11b8, 0x080c, 0x5cbf, 0x2079, 0x0260,
-	0x7a30, 0x9296, 0x1102, 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38,
-	0xd2fc, 0x0128, 0x70c0, 0x9005, 0x1110, 0x70c3, 0x0001, 0x7097,
-	0x0004, 0x0029, 0x0010, 0x080c, 0x5c9b, 0x00fe, 0x0005, 0x00f6,
-	0x7097, 0x0005, 0x080c, 0x5c43, 0x2079, 0x0240, 0x7833, 0x1103,
-	0x7837, 0x0000, 0x080c, 0x5cbf, 0x080c, 0x5ca2, 0x1170, 0x7080,
-	0x9005, 0x1158, 0x7158, 0x9186, 0xffff, 0x0138, 0x2011, 0x0008,
-	0x080c, 0x5afb, 0x0168, 0x080c, 0x5c78, 0x20a9, 0x0008, 0x20e1,
-	0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003,
-	0x60c3, 0x0014, 0x080c, 0x5b78, 0x00fe, 0x0005, 0x00f6, 0x708c,
-	0x9005, 0x0500, 0x2011, 0x5b4e, 0x080c, 0x803f, 0x9086, 0x0014,
-	0x11b8, 0x080c, 0x5cbf, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1103,
-	0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c0,
-	0x9005, 0x1110, 0x70c3, 0x0001, 0x7097, 0x0006, 0x0029, 0x0010,
-	0x080c, 0x5c9b, 0x00fe, 0x0005, 0x00f6, 0x7097, 0x0007, 0x080c,
-	0x5c43, 0x2079, 0x0240, 0x7833, 0x1104, 0x7837, 0x0000, 0x080c,
-	0x5cbf, 0x080c, 0x5ca2, 0x11b8, 0x7080, 0x9005, 0x11a0, 0x7160,
-	0x9186, 0xffff, 0x0180, 0x9180, 0x3145, 0x200d, 0x918c, 0xff00,
-	0x810f, 0x2011, 0x0008, 0x080c, 0x5afb, 0x0180, 0x080c, 0x4cac,
-	0x0110, 0x080c, 0x26d9, 0x20a9, 0x0008, 0x20e1, 0x0000, 0x2099,
+	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, 0x5b78, 0x00fe, 0x0005, 0x00f6, 0x708c, 0x9005, 0x0500,
-	0x2011, 0x5b4e, 0x080c, 0x803f, 0x9086, 0x0014, 0x11b8, 0x080c,
-	0x5cbf, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1104, 0x1178, 0x7834,
+	0x080c, 0x5dbe, 0x00fe, 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, 0x0008, 0x0029, 0x0010, 0x080c, 0x5c9b,
-	0x00fe, 0x0005, 0x00f6, 0x7097, 0x0009, 0x080c, 0x5c43, 0x2079,
-	0x0240, 0x7833, 0x1105, 0x7837, 0x0100, 0x080c, 0x5ca2, 0x1150,
-	0x7080, 0x9005, 0x1138, 0x080c, 0x5a6e, 0x1188, 0x9085, 0x0001,
-	0x080c, 0x26d9, 0x20a9, 0x0008, 0x080c, 0x5cbf, 0x20e1, 0x0000,
-	0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3,
-	0x0014, 0x080c, 0x5b78, 0x0010, 0x080c, 0x55c8, 0x00fe, 0x0005,
-	0x00f6, 0x708c, 0x9005, 0x05a8, 0x2011, 0x5b4e, 0x080c, 0x803f,
-	0x9086, 0x0014, 0x1560, 0x080c, 0x5cbf, 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,
+	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,
-	0x7093, 0x0000, 0x7097, 0x000e, 0x080c, 0x5816, 0x0010, 0x080c,
-	0x5c9b, 0x00fe, 0x0005, 0x00f6, 0x7097, 0x000b, 0x2011, 0x1c0e,
-	0x20e9, 0x0001, 0x22a0, 0x20a9, 0x0040, 0x2019, 0xffff, 0x4304,
-	0x080c, 0x5c43, 0x2079, 0x0240, 0x7833, 0x1106, 0x7837, 0x0000,
-	0x080c, 0x5ca2, 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, 0x5798, 0x60c3, 0x0084, 0x080c,
-	0x5b78, 0x00fe, 0x0005, 0x00f6, 0x708c, 0x9005, 0x01c0, 0x2011,
-	0x5b4e, 0x080c, 0x803f, 0x9086, 0x0084, 0x1178, 0x080c, 0x5cbf,
-	0x2079, 0x0260, 0x7a30, 0x9296, 0x1106, 0x1138, 0x7834, 0x9005,
-	0x1120, 0x7097, 0x000c, 0x0029, 0x0010, 0x080c, 0x5c9b, 0x00fe,
-	0x0005, 0x00f6, 0x7097, 0x000d, 0x080c, 0x5c43, 0x2079, 0x0240,
-	0x7833, 0x1107, 0x7837, 0x0000, 0x080c, 0x5cbf, 0x20a9, 0x0040,
-	0x2011, 0x026e, 0x2009, 0x024e, 0x220e, 0x8210, 0x8108, 0x9186,
-	0x0260, 0x1150, 0x6810, 0x8000, 0x6812, 0x2009, 0x0240, 0x6814,
-	0x8000, 0x6816, 0x2011, 0x0260, 0x1f04, 0x57dc, 0x60c3, 0x0084,
-	0x080c, 0x5b78, 0x00fe, 0x0005, 0x00f6, 0x708c, 0x9005, 0x01e0,
-	0x2011, 0x5b4e, 0x080c, 0x803f, 0x9086, 0x0084, 0x1198, 0x080c,
-	0x5cbf, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1107, 0x1158, 0x7834,
-	0x9005, 0x1140, 0x7093, 0x0001, 0x080c, 0x5c15, 0x7097, 0x000e,
-	0x0029, 0x0010, 0x080c, 0x5c9b, 0x00fe, 0x0005, 0x918d, 0x0001,
-	0x080c, 0x5cea, 0x7097, 0x000f, 0x708f, 0x0000, 0x2061, 0x0140,
-	0x605b, 0xbc85, 0x605f, 0xb5b5, 0x2061, 0x0100, 0x6043, 0x0005,
-	0x6043, 0x0004, 0x2009, 0x07d0, 0x2011, 0x5b4e, 0x080c, 0x8033,
-	0x0005, 0x708c, 0x9005, 0x0130, 0x2011, 0x5b4e, 0x080c, 0x803f,
-	0x7097, 0x0000, 0x0005, 0x7097, 0x0011, 0x080c, 0x9c37, 0x080c,
-	0x5cbf, 0x20e1, 0x0000, 0x2099, 0x0260, 0x20e9, 0x0000, 0x20a1,
-	0x0240, 0x748c, 0x9480, 0x0018, 0x9080, 0x0007, 0x9084, 0x03f8,
-	0x8004, 0x20a8, 0x4003, 0x080c, 0x5ca2, 0x11a0, 0x7178, 0x81ff,
-	0x0188, 0x900e, 0x707c, 0x9084, 0x00ff, 0x0160, 0x080c, 0x2670,
-	0x9186, 0x007e, 0x0138, 0x9186, 0x0080, 0x0120, 0x2011, 0x0008,
-	0x080c, 0x5afb, 0x60c3, 0x0014, 0x080c, 0x5b78, 0x0005, 0x00f6,
-	0x708c, 0x9005, 0x0500, 0x2011, 0x5b4e, 0x080c, 0x803f, 0x9086,
-	0x0014, 0x11b8, 0x080c, 0x5cbf, 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, 0x5c51, 0x2079, 0x0240, 0x7833, 0x1103, 0x7837, 0x0000,
-	0x080c, 0x5cbf, 0x080c, 0x5ca2, 0x1170, 0x7080, 0x9005, 0x1158,
-	0x7158, 0x9186, 0xffff, 0x0138, 0x2011, 0x0008, 0x080c, 0x5afb,
-	0x0168, 0x080c, 0x5c78, 0x20a9, 0x0008, 0x20e1, 0x0000, 0x2099,
-	0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014,
-	0x080c, 0x5b78, 0x00fe, 0x0005, 0x00f6, 0x708c, 0x9005, 0x0500,
-	0x2011, 0x5b4e, 0x080c, 0x803f, 0x9086, 0x0014, 0x11b8, 0x080c,
-	0x5cbf, 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, 0x5c51, 0x2079,
-	0x0240, 0x7833, 0x1104, 0x7837, 0x0000, 0x080c, 0x5cbf, 0x080c,
-	0x5ca2, 0x11b8, 0x7080, 0x9005, 0x11a0, 0x7160, 0x9186, 0xffff,
-	0x0180, 0x9180, 0x3145, 0x200d, 0x918c, 0xff00, 0x810f, 0x2011,
-	0x0008, 0x080c, 0x5afb, 0x0180, 0x080c, 0x4cac, 0x0110, 0x080c,
-	0x26d9, 0x20a9, 0x0008, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9,
-	0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x5b78,
-	0x00fe, 0x0005, 0x00f6, 0x708c, 0x9005, 0x05f0, 0x2011, 0x5b4e,
-	0x080c, 0x803f, 0x9086, 0x0014, 0x15a8, 0x080c, 0x5cbf, 0x2079,
-	0x0260, 0x7a30, 0x9296, 0x1105, 0x1568, 0x7834, 0x9084, 0x0100,
-	0x2011, 0x0100, 0x921e, 0x1168, 0x9085, 0x0001, 0x080c, 0x5cea,
+	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,
-	0x0080, 0x9005, 0x11b8, 0x7a38, 0xd2fc, 0x0128, 0x70c0, 0x9005,
-	0x1110, 0x70c3, 0x0001, 0x9085, 0x0001, 0x080c, 0x5cea, 0x7093,
-	0x0000, 0x7a38, 0xd2f4, 0x0110, 0x70db, 0x0008, 0x7097, 0x0016,
-	0x0029, 0x0010, 0x708f, 0x0000, 0x00fe, 0x0005, 0x080c, 0x9c37,
-	0x080c, 0x5cbf, 0x20e1, 0x0000, 0x2099, 0x0260, 0x20e9, 0x0000,
-	0x20a1, 0x0240, 0x20a9, 0x000e, 0x4003, 0x2011, 0x026d, 0x2204,
-	0x9084, 0x0100, 0x2011, 0x024d, 0x2012, 0x2011, 0x026e, 0x7097,
-	0x0017, 0x080c, 0x5ca2, 0x1150, 0x7080, 0x9005, 0x1138, 0x080c,
-	0x5a6e, 0x1188, 0x9085, 0x0001, 0x080c, 0x26d9, 0x20a9, 0x0008,
-	0x080c, 0x5cbf, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000,
-	0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x5b78, 0x0010,
-	0x080c, 0x55c8, 0x0005, 0x00f6, 0x708c, 0x9005, 0x01d8, 0x2011,
-	0x5b4e, 0x080c, 0x803f, 0x9086, 0x0084, 0x1190, 0x080c, 0x5cbf,
-	0x2079, 0x0260, 0x7a30, 0x9296, 0x1106, 0x1150, 0x7834, 0x9005,
-	0x1138, 0x9006, 0x080c, 0x5cea, 0x7097, 0x0018, 0x0029, 0x0010,
-	0x708f, 0x0000, 0x00fe, 0x0005, 0x00f6, 0x7097, 0x0019, 0x080c,
-	0x5c51, 0x2079, 0x0240, 0x7833, 0x1106, 0x7837, 0x0000, 0x080c,
-	0x5cbf, 0x2009, 0x026e, 0x2039, 0x1c0e, 0x20a9, 0x0040, 0x213e,
-	0x8738, 0x8108, 0x9186, 0x0280, 0x1128, 0x6814, 0x8000, 0x6816,
-	0x2009, 0x0260, 0x1f04, 0x59d7, 0x2039, 0x1c0e, 0x080c, 0x5ca2,
-	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, 0x5a0a, 0x60c3,
-	0x0084, 0x080c, 0x5b78, 0x00fe, 0x0005, 0x00f6, 0x708c, 0x9005,
-	0x01e0, 0x2011, 0x5b4e, 0x080c, 0x803f, 0x9086, 0x0084, 0x1198,
-	0x080c, 0x5cbf, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1107, 0x1158,
-	0x7834, 0x9005, 0x1140, 0x7093, 0x0001, 0x080c, 0x5c15, 0x7097,
-	0x001a, 0x0029, 0x0010, 0x708f, 0x0000, 0x00fe, 0x0005, 0x9085,
-	0x0001, 0x080c, 0x5cea, 0x7097, 0x001b, 0x080c, 0x9c37, 0x080c,
-	0x5cbf, 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, 0x5a56,
-	0x60c3, 0x0084, 0x080c, 0x5b78, 0x0005, 0x0005, 0x0086, 0x0096,
-	0x2029, 0x185c, 0x252c, 0x20a9, 0x0008, 0x2041, 0x1c0e, 0x20e9,
-	0x0001, 0x28a0, 0x080c, 0x5cbf, 0x20e1, 0x0000, 0x2099, 0x026e,
-	0x4003, 0x20a9, 0x0008, 0x2011, 0x0007, 0xd5d4, 0x0108, 0x9016,
-	0x2800, 0x9200, 0x200c, 0x91a6, 0xffff, 0x1148, 0xd5d4, 0x0110,
-	0x8210, 0x0008, 0x8211, 0x1f04, 0x5a88, 0x0804, 0x5af7, 0x82ff,
-	0x1160, 0xd5d4, 0x0120, 0x91a6, 0x3fff, 0x0d90, 0x0020, 0x91a6,
-	0x3fff, 0x0904, 0x5af7, 0x918d, 0xc000, 0x20a9, 0x0010, 0x2019,
-	0x0001, 0xd5d4, 0x0110, 0x2019, 0x0010, 0x2120, 0xd5d4, 0x0110,
-	0x8423, 0x0008, 0x8424, 0x1240, 0xd5d4, 0x0110, 0x8319, 0x0008,
-	0x8318, 0x1f04, 0x5aae, 0x04d8, 0x23a8, 0x2021, 0x0001, 0x8426,
-	0x8425, 0x1f04, 0x5ac0, 0x2328, 0x8529, 0x92be, 0x0007, 0x0158,
-	0x0006, 0x2039, 0x0007, 0x2200, 0x973a, 0x000e, 0x27a8, 0x95a8,
-	0x0010, 0x1f04, 0x5acf, 0x755a, 0x95c8, 0x3145, 0x292d, 0x95ac,
-	0x00ff, 0x757e, 0x6532, 0x6536, 0x0016, 0x2508, 0x080c, 0x26b9,
-	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, 0x3145, 0x242d, 0x95ac, 0x00ff, 0x757e,
-	0x6532, 0x6536, 0x0016, 0x2508, 0x080c, 0x26b9, 0x001e, 0x60e7,
-	0x0000, 0x65ea, 0x7083, 0x0001, 0x9084, 0x0000, 0x0005, 0x00e6,
-	0x2071, 0x1800, 0x7087, 0x0000, 0x00ee, 0x0005, 0x00e6, 0x00f6,
-	0x2079, 0x0100, 0x2071, 0x0140, 0x080c, 0x5c04, 0x080c, 0x93c7,
-	0x7004, 0x9084, 0x4000, 0x0110, 0x080c, 0x2b31, 0x0126, 0x2091,
-	0x8000, 0x2071, 0x1825, 0x2073, 0x0000, 0x7840, 0x0026, 0x0016,
-	0x2009, 0x00f7, 0x080c, 0x5c61, 0x001e, 0x9094, 0x0010, 0x9285,
-	0x0080, 0x7842, 0x7a42, 0x002e, 0x012e, 0x00fe, 0x00ee, 0x0005,
-	0x0126, 0x2091, 0x8000, 0x080c, 0x29d7, 0x0228, 0x2011, 0x0101,
-	0x2204, 0xc0c5, 0x2012, 0x2011, 0x19c9, 0x2013, 0x0000, 0x708f,
-	0x0000, 0x012e, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x080c, 0x93be,
-	0x6144, 0xd184, 0x0120, 0x7194, 0x918d, 0x2000, 0x0018, 0x7188,
-	0x918d, 0x1000, 0x2011, 0x1971, 0x2112, 0x2009, 0x07d0, 0x2011,
-	0x5b4e, 0x080c, 0x80d1, 0x0005, 0x0016, 0x0026, 0x00c6, 0x0126,
-	0x2091, 0x8000, 0x080c, 0x9db5, 0x2009, 0x00f7, 0x080c, 0x5c61,
-	0x2061, 0x19d2, 0x900e, 0x611a, 0x611e, 0x6172, 0x6176, 0x2061,
-	0x1800, 0x6003, 0x0001, 0x2061, 0x0100, 0x6043, 0x0090, 0x6043,
-	0x0010, 0x2009, 0x1971, 0x200b, 0x0000, 0x2009, 0x002d, 0x2011,
-	0x5bd0, 0x080c, 0x8033, 0x012e, 0x00ce, 0x002e, 0x001e, 0x0005,
-	0x00e6, 0x0006, 0x0126, 0x2091, 0x8000, 0x0471, 0x2071, 0x0100,
-	0x080c, 0x93c7, 0x2071, 0x0140, 0x7004, 0x9084, 0x4000, 0x0110,
-	0x080c, 0x2b31, 0x080c, 0x6fb2, 0x0188, 0x080c, 0x6fcd, 0x1170,
-	0x080c, 0x7296, 0x0016, 0x080c, 0x2788, 0x2001, 0x1945, 0x2102,
-	0x001e, 0x080c, 0x7291, 0x080c, 0x6edc, 0x0050, 0x2009, 0x0001,
-	0x080c, 0x2a70, 0x2001, 0x0001, 0x080c, 0x2619, 0x080c, 0x5ba4,
-	0x012e, 0x000e, 0x00ee, 0x0005, 0x2001, 0x180e, 0x2004, 0xd0bc,
-	0x0158, 0x0026, 0x0036, 0x2011, 0x8017, 0x2001, 0x1971, 0x201c,
-	0x080c, 0x48f4, 0x003e, 0x002e, 0x0005, 0x20a9, 0x0012, 0x20e9,
-	0x0001, 0x20a1, 0x1c80, 0x080c, 0x5cbf, 0x20e9, 0x0000, 0x2099,
-	0x026e, 0x0099, 0x20a9, 0x0020, 0x080c, 0x5cb9, 0x2099, 0x0260,
-	0x20a1, 0x1c92, 0x0051, 0x20a9, 0x000e, 0x080c, 0x5cbc, 0x2099,
-	0x0260, 0x20a1, 0x1cb2, 0x0009, 0x0005, 0x0016, 0x0026, 0x3410,
-	0x3308, 0x2104, 0x8007, 0x2012, 0x8108, 0x8210, 0x1f04, 0x5c39,
-	0x002e, 0x001e, 0x0005, 0x080c, 0x9c37, 0x20e1, 0x0001, 0x2099,
-	0x1c00, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x000c, 0x4003,
-	0x0005, 0x080c, 0x9c37, 0x080c, 0x5cbf, 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, 0x6576, 0x0158, 0x9006, 0x2020, 0x2009,
-	0x002a, 0x080c, 0xd564, 0x2001, 0x180c, 0x200c, 0xc195, 0x2102,
-	0x2019, 0x002a, 0x900e, 0x080c, 0x2fb2, 0x080c, 0xc23b, 0x0140,
-	0x0036, 0x2019, 0xffff, 0x2021, 0x0007, 0x080c, 0x4a91, 0x003e,
-	0x004e, 0x001e, 0x0005, 0x080c, 0x5ba4, 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, 0x5cf9, 0x015e, 0x0005, 0x00d6,
-	0x0036, 0x0156, 0x0136, 0x0146, 0x2069, 0x185b, 0x9006, 0xb802,
-	0xb8be, 0xb807, 0x0707, 0xb80a, 0xb80e, 0xb812, 0x9198, 0x3145,
-	0x231d, 0x939c, 0x00ff, 0xbb16, 0x0016, 0x0026, 0xb8b2, 0x080c,
-	0x9dae, 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, 0x101d, 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, 0x5dcf, 0x9182, 0x0800, 0x1a04, 0x5dd3,
-	0x2001, 0x180c, 0x2004, 0x9084, 0x0003, 0x1904, 0x5dd9, 0x9188,
-	0x1000, 0x2104, 0x905d, 0x0518, 0xb804, 0x9084, 0x00ff, 0x908e,
-	0x0006, 0x1508, 0xb8a4, 0x900d, 0x1904, 0x5deb, 0xb850, 0x900d,
-	0x1148, 0xa802, 0x2900, 0xb852, 0xb84e, 0x080c, 0x8415, 0x9006,
-	0x012e, 0x0005, 0x00a6, 0x2150, 0x2900, 0xb002, 0xa803, 0x0000,
-	0x00ae, 0xb852, 0x0c90, 0x2001, 0x0005, 0x900e, 0x04b8, 0x2001,
-	0x0028, 0x900e, 0x0498, 0x9082, 0x0006, 0x1290, 0x080c, 0x9dae,
-	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, 0x657a, 0x1990, 0xb800, 0xd0bc,
-	0x0978, 0x0804, 0x5d82, 0x080c, 0x63f2, 0x0904, 0x5d9b, 0x0804,
-	0x5d86, 0x00b6, 0x00e6, 0x0126, 0x2091, 0x8000, 0xa974, 0x9182,
-	0x0800, 0x1a04, 0x5e6c, 0x9188, 0x1000, 0x2104, 0x905d, 0x0904,
-	0x5e44, 0xb8a0, 0x9086, 0x007f, 0x0178, 0x080c, 0x6582, 0x0160,
-	0xa994, 0x81ff, 0x0130, 0x908e, 0x0004, 0x0130, 0x908e, 0x0005,
-	0x0118, 0x080c, 0x657a, 0x1598, 0xa87c, 0xd0fc, 0x01e0, 0xa894,
-	0x9005, 0x01c8, 0x2060, 0x0026, 0x2010, 0x080c, 0xbb29, 0x002e,
-	0x1120, 0x2001, 0x0008, 0x0804, 0x5e6e, 0x6020, 0x9086, 0x000a,
-	0x0120, 0x2001, 0x0008, 0x0804, 0x5e6e, 0x601a, 0x6003, 0x0008,
-	0x2900, 0x6016, 0x0058, 0x080c, 0x9dd9, 0x05e8, 0x2b00, 0x6012,
-	0x2900, 0x6016, 0x600b, 0xffff, 0x6023, 0x000a, 0x2009, 0x0003,
-	0x080c, 0x9ea9, 0x9006, 0x0458, 0x2001, 0x0028, 0x0438, 0x9082,
-	0x0006, 0x1290, 0x080c, 0x9dae, 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, 0x5f03, 0x5ebe,
-	0x5ed5, 0x5f03, 0x5f03, 0x5f03, 0x5f03, 0x5f03, 0x2100, 0x9082,
-	0x007e, 0x1278, 0x080c, 0x61f6, 0x0148, 0x9046, 0xb810, 0x9306,
-	0x1904, 0x5f0b, 0xb814, 0x9206, 0x15f0, 0x0028, 0xbb12, 0xba16,
-	0x0010, 0x080c, 0x47ae, 0x0150, 0x04b0, 0x080c, 0x6256, 0x1598,
-	0xb810, 0x9306, 0x1580, 0xb814, 0x9206, 0x1568, 0x080c, 0x9dd9,
-	0x0530, 0x2b00, 0x6012, 0x080c, 0xbfb5, 0x2900, 0x6016, 0x600b,
-	0xffff, 0x6023, 0x000a, 0xa878, 0x9086, 0x0001, 0x1170, 0x080c,
-	0x2fe7, 0x9006, 0x080c, 0x6193, 0x2001, 0x0002, 0x080c, 0x61a7,
-	0x2001, 0x0200, 0xb86e, 0xb893, 0x0002, 0x2009, 0x0003, 0x080c,
-	0x9ea9, 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, 0x60e4, 0x90c6,
-	0x0056, 0x0904, 0x60e8, 0x90c6, 0x0066, 0x0904, 0x60ec, 0x90c6,
-	0x0067, 0x0904, 0x60f0, 0x90c6, 0x0068, 0x0904, 0x60f4, 0x90c6,
-	0x0071, 0x0904, 0x60f8, 0x90c6, 0x0074, 0x0904, 0x60fc, 0x90c6,
-	0x007c, 0x0904, 0x6100, 0x90c6, 0x007e, 0x0904, 0x6104, 0x90c6,
-	0x0037, 0x0904, 0x6108, 0x9016, 0x2079, 0x1800, 0xa974, 0x9186,
-	0x00ff, 0x0904, 0x60df, 0x9182, 0x0800, 0x1a04, 0x60df, 0x080c,
-	0x6256, 0x1198, 0xb804, 0x9084, 0x00ff, 0x9082, 0x0006, 0x1268,
-	0xa894, 0x90c6, 0x006f, 0x0148, 0x080c, 0x9dae, 0x1904, 0x60c8,
-	0xb8a0, 0x9084, 0xff80, 0x1904, 0x60c8, 0xa894, 0x90c6, 0x006f,
-	0x0158, 0x90c6, 0x005e, 0x0904, 0x6028, 0x90c6, 0x0064, 0x0904,
-	0x6051, 0x2008, 0x0804, 0x5feb, 0xa998, 0xa8b0, 0x2040, 0x080c,
-	0x9dae, 0x1120, 0x9182, 0x007f, 0x0a04, 0x5feb, 0x9186, 0x00ff,
-	0x0904, 0x5feb, 0x9182, 0x0800, 0x1a04, 0x5feb, 0xaaa0, 0xab9c,
-	0x7878, 0x9306, 0x11a8, 0x787c, 0x0096, 0x924e, 0x1128, 0x2208,
-	0x2310, 0x009e, 0x0804, 0x5feb, 0x080c, 0x9dae, 0x1140, 0x99cc,
-	0xff00, 0x009e, 0x1128, 0x2208, 0x2310, 0x0804, 0x5feb, 0x009e,
-	0x080c, 0x47ae, 0x0904, 0x5ff4, 0x900e, 0x9016, 0x90c6, 0x4000,
-	0x1558, 0x0006, 0x080c, 0x6476, 0x1108, 0xc185, 0xb800, 0xd0bc,
-	0x0108, 0xc18d, 0x20a9, 0x0004, 0xa860, 0x20e8, 0xa85c, 0x9080,
-	0x0031, 0x20a0, 0xb8b4, 0x20e0, 0xb8b8, 0x9080, 0x0006, 0x2098,
-	0x080c, 0x0f68, 0x20a9, 0x0004, 0xa860, 0x20e8, 0xa85c, 0x9080,
-	0x0035, 0x20a0, 0xb8b4, 0x20e0, 0xb8b8, 0x9080, 0x000a, 0x2098,
-	0x080c, 0x0f68, 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, 0x9dd9, 0x1130, 0x2001,
-	0x4005, 0x2009, 0x0003, 0x9016, 0x0c80, 0x2b00, 0x6012, 0x080c,
-	0xbfb5, 0x2900, 0x6016, 0x6023, 0x0001, 0xa868, 0xd88c, 0x0108,
-	0xc0f5, 0xa86a, 0x0126, 0x2091, 0x8000, 0x080c, 0x2fe7, 0x012e,
-	0x9006, 0x080c, 0x6193, 0x2001, 0x0002, 0x080c, 0x61a7, 0x2009,
-	0x0002, 0x080c, 0x9ea9, 0xa8b0, 0xd094, 0x0118, 0xb8bc, 0xc08d,
-	0xb8be, 0x9006, 0x9005, 0x012e, 0x00ee, 0x00fe, 0x00be, 0x0005,
-	0x080c, 0x53ae, 0x0118, 0x2009, 0x0007, 0x00f8, 0xa998, 0xaeb0,
-	0x080c, 0x6256, 0x1904, 0x5fe6, 0x9186, 0x007f, 0x0130, 0x080c,
-	0x657a, 0x0118, 0x2009, 0x0009, 0x0080, 0x0096, 0x080c, 0x0feb,
-	0x1120, 0x009e, 0x2009, 0x0002, 0x0040, 0x2900, 0x009e, 0xa806,
-	0x080c, 0xbd21, 0x19b0, 0x2009, 0x0003, 0x2001, 0x4005, 0x0804,
-	0x5fed, 0xa998, 0xaeb0, 0x080c, 0x6256, 0x1904, 0x5fe6, 0x0096,
-	0x080c, 0x0feb, 0x1128, 0x009e, 0x2009, 0x0002, 0x0804, 0x60a5,
-	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, 0x0f68, 0x009e, 0xa87b, 0x0000,
-	0xa883, 0x0000, 0xa897, 0x4000, 0xd684, 0x1168, 0x080c, 0x539a,
-	0xd0b4, 0x1118, 0xa89b, 0x000b, 0x00e0, 0xb800, 0xd08c, 0x0118,
-	0xa89b, 0x000c, 0x00b0, 0x080c, 0x657a, 0x0118, 0xa89b, 0x0009,
-	0x0080, 0x080c, 0x53ae, 0x0118, 0xa89b, 0x0007, 0x0050, 0x080c,
-	0xbd04, 0x1904, 0x6021, 0x2009, 0x0003, 0x2001, 0x4005, 0x0804,
-	0x5fed, 0xa87b, 0x0030, 0xa897, 0x4005, 0xa804, 0x8006, 0x8006,
-	0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0002, 0x2009,
-	0x002b, 0xaaa0, 0xab9c, 0xaca8, 0xada4, 0x2031, 0x0000, 0x2041,
-	0x122f, 0x080c, 0xa332, 0x1904, 0x6021, 0x2009, 0x0002, 0x08e8,
-	0x2001, 0x0028, 0x900e, 0x0804, 0x6022, 0x2009, 0x180c, 0x210c,
-	0xd18c, 0x0118, 0x2001, 0x0004, 0x0038, 0xd184, 0x0118, 0x2001,
-	0x0004, 0x0010, 0x2001, 0x0029, 0x900e, 0x0804, 0x6022, 0x2001,
-	0x0029, 0x900e, 0x0804, 0x6022, 0x080c, 0x3574, 0x0804, 0x6023,
-	0x080c, 0x50d7, 0x0804, 0x6023, 0x080c, 0x4344, 0x0804, 0x6023,
-	0x080c, 0x43bd, 0x0804, 0x6023, 0x080c, 0x4419, 0x0804, 0x6023,
-	0x080c, 0x486a, 0x0804, 0x6023, 0x080c, 0x4b0f, 0x0804, 0x6023,
-	0x080c, 0x4d42, 0x0804, 0x6023, 0x080c, 0x4f3b, 0x0804, 0x6023,
-	0x080c, 0x3784, 0x0804, 0x6023, 0x00b6, 0xa974, 0xae78, 0x9684,
-	0x3fff, 0x9082, 0x4000, 0x1618, 0x9182, 0x0800, 0x1268, 0x9188,
-	0x1000, 0x2104, 0x905d, 0x0140, 0x080c, 0x657a, 0x1148, 0x00e9,
-	0x080c, 0x6381, 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, 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, 0x6576,
-	0x0140, 0x9284, 0xff00, 0x8007, 0x9086, 0x0007, 0x1110, 0x2011,
-	0x0600, 0x000e, 0x9294, 0xff00, 0x9215, 0xba06, 0x0006, 0x9086,
-	0x0006, 0x1120, 0xba90, 0x82ff, 0x090c, 0x0db4, 0x000e, 0x00ce,
-	0x012e, 0x00be, 0x0005, 0x00b6, 0x0126, 0x00c6, 0x2091, 0x8000,
-	0x6210, 0x2258, 0xba04, 0x0006, 0x9086, 0x0006, 0x1168, 0xb89c,
-	0xd0a4, 0x0150, 0x080c, 0x6572, 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, 0x0feb, 0x2958, 0x009e,
-	0x0160, 0x2b00, 0x2012, 0xb85c, 0xb8ba, 0xb860, 0xb8b6, 0x9006,
-	0xb8a6, 0x080c, 0x5cff, 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, 0x101d, 0x00d6, 0x00c6, 0xb8ac, 0x2060, 0x8cff,
-	0x0168, 0x600c, 0x0006, 0x6014, 0x2048, 0x080c, 0xbb3b, 0x0110,
-	0x080c, 0x0f9d, 0x080c, 0x9e2f, 0x00ce, 0x0c88, 0x00ce, 0x00de,
-	0x2b48, 0xb8b8, 0xb85e, 0xb8b4, 0xb862, 0x080c, 0x102d, 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,
-	0x6faa, 0x1510, 0xb8a0, 0x9086, 0x007e, 0x0120, 0x080c, 0x9dae,
-	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, 0x0db4, 0x3c00, 0x20e8,
-	0x3300, 0x8001, 0x20a0, 0x4604, 0x8210, 0xaa06, 0x01de, 0x01ce,
-	0x014e, 0x013e, 0x0060, 0x080c, 0x0feb, 0x0170, 0x2900, 0xb8a6,
-	0xa803, 0x0000, 0x080c, 0x6412, 0xa807, 0x0001, 0xae12, 0x9085,
-	0x0001, 0x012e, 0x009e, 0x0005, 0x9006, 0x0cd8, 0x0126, 0x2091,
-	0x8000, 0x0096, 0xb8a4, 0x904d, 0x0188, 0xa800, 0x9005, 0x1150,
-	0x080c, 0x6421, 0x1158, 0xa804, 0x908a, 0x0002, 0x0218, 0x8001,
-	0xa806, 0x0020, 0x080c, 0x101d, 0xb8a7, 0x0000, 0x009e, 0x012e,
-	0x0005, 0x0126, 0x2091, 0x8000, 0x080c, 0x8415, 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,
-	0x979a, 0xaa00, 0xb84c, 0x9906, 0x1110, 0xba4e, 0x0020, 0x00a6,
-	0x2150, 0xb202, 0x00ae, 0x82ff, 0x1110, 0xb952, 0x89ff, 0x012e,
-	0x0005, 0x9016, 0x0489, 0x1110, 0x2011, 0x0001, 0x0005, 0x080c,
-	0x6476, 0x0128, 0x080c, 0xbbf8, 0x0010, 0x9085, 0x0001, 0x0005,
-	0x080c, 0x6476, 0x0128, 0x080c, 0xbb9d, 0x0010, 0x9085, 0x0001,
-	0x0005, 0x080c, 0x6476, 0x0128, 0x080c, 0xbbf5, 0x0010, 0x9085,
-	0x0001, 0x0005, 0x080c, 0x6476, 0x0128, 0x080c, 0xbbbc, 0x0010,
-	0x9085, 0x0001, 0x0005, 0x080c, 0x6476, 0x0128, 0x080c, 0xbc39,
-	0x0010, 0x9085, 0x0001, 0x0005, 0xb8a4, 0x900d, 0x1118, 0x9085,
-	0x0001, 0x0005, 0x0136, 0x01c6, 0xa800, 0x9005, 0x11b8, 0x890e,
+	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,
+	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,
+	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,
+	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, 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, 0x0feb, 0x0168, 0x2900,
-	0xb8a6, 0x080c, 0x6412, 0xa803, 0x0001, 0xa807, 0x0000, 0x9085,
-	0x0001, 0x012e, 0x009e, 0x0005, 0x9006, 0x0cd8, 0x0096, 0x0126,
-	0x2091, 0x8000, 0xb8a4, 0x904d, 0x0130, 0xb8a7, 0x0000, 0x080c,
-	0x101d, 0x9085, 0x0001, 0x012e, 0x009e, 0x0005, 0xb89c, 0xd0a4,
-	0x0005, 0x00b6, 0x00f6, 0x080c, 0x6faa, 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, 0x6256, 0x1168,
-	0xb804, 0x9084, 0xff00, 0x8007, 0x9096, 0x0004, 0x0118, 0x9086,
-	0x0006, 0x1118, 0xb800, 0xc0ed, 0xb802, 0x001e, 0x8108, 0x1f04,
-	0x649c, 0x015e, 0x080c, 0x6538, 0x0120, 0x2001, 0x195d, 0x200c,
-	0x0030, 0x2079, 0x185b, 0x7804, 0x0030, 0x2009, 0x07d0, 0x2011,
-	0x64c6, 0x080c, 0x80d1, 0x00fe, 0x00be, 0x0005, 0x00b6, 0x2011,
-	0x64c6, 0x080c, 0x803f, 0x080c, 0x6538, 0x01d8, 0x2001, 0x107e,
-	0x2004, 0x2058, 0xb900, 0xc1ec, 0xb902, 0x080c, 0x6576, 0x0130,
-	0x2009, 0x07d0, 0x2011, 0x64c6, 0x080c, 0x80d1, 0x00e6, 0x2071,
-	0x1800, 0x9006, 0x707a, 0x705c, 0x707e, 0x080c, 0x2dc8, 0x00ee,
-	0x04b0, 0x0156, 0x00c6, 0x20a9, 0x007f, 0x900e, 0x0016, 0x080c,
-	0x6256, 0x1538, 0xb800, 0xd0ec, 0x0520, 0x0046, 0xbaa0, 0x2220,
-	0x9006, 0x2009, 0x0029, 0x080c, 0xd564, 0xb800, 0xc0e5, 0xc0ec,
-	0xb802, 0x080c, 0x6572, 0x2001, 0x0707, 0x1128, 0xb804, 0x9084,
-	0x00ff, 0x9085, 0x0700, 0xb806, 0x2019, 0x0029, 0x080c, 0x8582,
-	0x0076, 0x903e, 0x080c, 0x8470, 0x900e, 0x080c, 0xd2d5, 0x007e,
-	0x004e, 0x001e, 0x8108, 0x1f04, 0x64ee, 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, 0x0db4,
-	0x000e, 0xba00, 0x9005, 0x0110, 0xc2fd, 0x0008, 0xc2fc, 0xba02,
-	0x002e, 0x012e, 0x0005, 0x2011, 0x1836, 0x2204, 0xd0cc, 0x0138,
-	0x2001, 0x195b, 0x200c, 0x2011, 0x6568, 0x080c, 0x80d1, 0x0005,
-	0x2011, 0x6568, 0x080c, 0x803f, 0x2011, 0x1836, 0x2204, 0xc0cc,
-	0x2012, 0x0005, 0x080c, 0x539a, 0xd0ac, 0x0005, 0x080c, 0x539a,
-	0xd0a4, 0x0005, 0x0016, 0xb904, 0x9184, 0x00ff, 0x908e, 0x0006,
-	0x001e, 0x0005, 0x0016, 0xb904, 0x9184, 0xff00, 0x8007, 0x908e,
-	0x0006, 0x001e, 0x0005, 0x00b6, 0x00f6, 0x080c, 0xc23b, 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,
-	0x3145, 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, 0x3145, 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, 0x539a, 0xd0fc, 0x1140, 0x080c, 0x539a, 0x900e,
-	0xd09c, 0x0108, 0x8108, 0x7102, 0x0400, 0x2001, 0x187b, 0x200c,
-	0x9184, 0x0007, 0x9006, 0x0002, 0x664d, 0x664d, 0x664d, 0x664d,
-	0x664d, 0x6664, 0x6672, 0x664d, 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, 0x72fe, 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, 0x68a5, 0xa87c, 0xd0bc,
-	0x1904, 0x68a5, 0xa978, 0xa874, 0x9105, 0x1904, 0x68a5, 0x2001,
-	0x1921, 0x2004, 0x0002, 0x68a5, 0x66fe, 0x673a, 0x673a, 0x68a5,
-	0x673a, 0x0005, 0xa868, 0xd0fc, 0x1500, 0x00e6, 0x0026, 0x2009,
-	0x1921, 0x210c, 0x81ff, 0x0904, 0x68a5, 0xa87c, 0xd0cc, 0x0904,
-	0x68a5, 0xa880, 0x9084, 0x00ff, 0x9086, 0x0001, 0x1904, 0x68a5,
-	0x9186, 0x0003, 0x0904, 0x673a, 0x9186, 0x0005, 0x0904, 0x673a,
-	0xa84f, 0x8021, 0xa853, 0x0017, 0x0028, 0x0005, 0xa84f, 0x8020,
-	0xa853, 0x0016, 0x2071, 0x190e, 0x701c, 0x9005, 0x1904, 0x6a59,
-	0x0e04, 0x6aa4, 0x2071, 0x0000, 0xa84c, 0x7082, 0xa850, 0x7032,
-	0xa86c, 0x7086, 0x7036, 0xa870, 0x708a, 0x2091, 0x4080, 0x2001,
-	0x0089, 0x2004, 0xd084, 0x190c, 0x1187, 0x2071, 0x1800, 0x2011,
-	0x0001, 0xa804, 0x900d, 0x702c, 0x1158, 0xa802, 0x2900, 0x702e,
-	0x70bc, 0x9200, 0x70be, 0x080c, 0x7f64, 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, 0x6829, 0x782c,
-	0x908c, 0x0780, 0x190c, 0x6bcb, 0x8004, 0x8004, 0x8004, 0x9084,
-	0x0003, 0x0002, 0x6758, 0x6829, 0x677d, 0x67c4, 0x080c, 0x0db4,
-	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, 0x7f64, 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, 0x7f64, 0x782c,
-	0x9094, 0x0780, 0x190c, 0x6bcb, 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, 0x7f64, 0x0800, 0x0096, 0x00e6, 0x7824, 0x2048,
-	0x2071, 0x1800, 0x702c, 0xa802, 0x2900, 0x702e, 0x70bc, 0x8000,
-	0x70be, 0x080c, 0x7f64, 0x782c, 0x9094, 0x0780, 0x190c, 0x6bcb,
-	0xd0a4, 0x1d60, 0x00ee, 0x782c, 0x9094, 0x0780, 0x190c, 0x6bcb,
-	0xd09c, 0x11a0, 0x009e, 0x2900, 0x7822, 0xa804, 0x900d, 0x1560,
+	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, 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,
+	0x8005, 0x703e, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x9016, 0x702c,
 	0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e,
-	0x70bc, 0x9200, 0x70be, 0x080c, 0x7f64, 0x00fe, 0x002e, 0x00ee,
-	0x0005, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, 0x711a,
-	0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, 0x1904,
-	0x687e, 0x782c, 0x9094, 0x0780, 0x190c, 0x6bcb, 0xd09c, 0x1198,
-	0x701c, 0x904d, 0x0180, 0x7010, 0x8001, 0x7012, 0x1108, 0x701a,
-	0xa800, 0x701e, 0x2900, 0x7822, 0x782c, 0x9094, 0x0780, 0x190c,
-	0x6bcb, 0xd09c, 0x0d68, 0x782c, 0x9094, 0x0780, 0x190c, 0x6bcb,
-	0xd0a4, 0x01b0, 0x00e6, 0x7824, 0x2048, 0x2071, 0x1800, 0x702c,
-	0xa802, 0x2900, 0x702e, 0x70bc, 0x8000, 0x70be, 0x080c, 0x7f64,
-	0x782c, 0x9094, 0x0780, 0x190c, 0x6bcb, 0xd0a4, 0x1d60, 0x00ee,
-	0x2071, 0x19d2, 0x703c, 0x9005, 0x1328, 0x2001, 0x1922, 0x2004,
-	0x8005, 0x703e, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x00e6, 0x2071,
-	0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900,
-	0x81ff, 0x1dc8, 0x702e, 0x70bc, 0x9200, 0x70be, 0x080c, 0x7f64,
-	0x00ee, 0x0804, 0x6839, 0xa868, 0xd0fc, 0x1904, 0x68e1, 0x0096,
-	0xa804, 0xa807, 0x0000, 0x904d, 0x190c, 0x0f9d, 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, 0x69d7,
-	0x782c, 0x908c, 0x0780, 0x190c, 0x6bcb, 0x8004, 0x8004, 0x8004,
-	0x9084, 0x0003, 0x0002, 0x68e2, 0x69d7, 0x68fd, 0x696a, 0x080c,
-	0x0db4, 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,
+	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, 0x7f64, 0x0c60, 0x2071, 0x1800, 0x2900,
-	0x7822, 0xa804, 0x900d, 0x1904, 0x6959, 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, 0x7f64, 0x782c, 0x9094, 0x0780, 0x190c, 0x6bcb,
-	0xd0a4, 0x19f0, 0x0e04, 0x6950, 0x7838, 0x7938, 0x910e, 0x1de0,
-	0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, 0x2001,
-	0x191f, 0x200c, 0xc184, 0x2102, 0x2091, 0x4080, 0x2001, 0x0089,
-	0x2004, 0xd084, 0x190c, 0x1187, 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, 0x7f64,
-	0x0804, 0x6910, 0x0096, 0x00e6, 0x7824, 0x2048, 0x2071, 0x1800,
-	0x702c, 0xa802, 0x2900, 0x702e, 0x70bc, 0x8000, 0x70be, 0x080c,
-	0x7f64, 0x782c, 0x9094, 0x0780, 0x190c, 0x6bcb, 0xd0a4, 0x1d60,
-	0x00ee, 0x0e04, 0x69aa, 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6,
-	0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, 0x7044, 0xc084,
-	0x7046, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c,
-	0x1187, 0x782c, 0x9094, 0x0780, 0x190c, 0x6bcb, 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, 0x7f64, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x2908,
-	0x7010, 0x8000, 0x7012, 0x7018, 0x904d, 0x711a, 0x0110, 0xa902,
-	0x0008, 0x711e, 0x2148, 0xa804, 0x900d, 0x1904, 0x6a44, 0x782c,
-	0x9094, 0x0780, 0x190c, 0x6bcb, 0xd09c, 0x11b0, 0x701c, 0x904d,
-	0x0198, 0xa84c, 0x9005, 0x1180, 0x7010, 0x8001, 0x7012, 0x1108,
+	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, 0x6bcb, 0xd09c, 0x0d50, 0x782c, 0x9094, 0x0780, 0x190c,
-	0x6bcb, 0xd0a4, 0x05a8, 0x00e6, 0x7824, 0x2048, 0x2071, 0x1800,
+	0x190c, 0x6e16, 0xd09c, 0x0d68, 0x782c, 0x9094, 0x0780, 0x190c,
+	0x6e16, 0xd0a4, 0x01b0, 0x00e6, 0x7824, 0x2048, 0x2071, 0x1800,
 	0x702c, 0xa802, 0x2900, 0x702e, 0x70bc, 0x8000, 0x70be, 0x080c,
-	0x7f64, 0x782c, 0x9094, 0x0780, 0x190c, 0x6bcb, 0xd0a4, 0x1d60,
-	0x00ee, 0x0e04, 0x6a3d, 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6,
-	0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, 0x7044, 0xc084,
-	0x7046, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c,
-	0x1187, 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, 0x7f64, 0x00ee, 0x0804,
-	0x69e7, 0x2071, 0x190e, 0xa803, 0x0000, 0x2908, 0x7010, 0x8000,
-	0x7012, 0x7018, 0x904d, 0x711a, 0x0110, 0xa902, 0x0008, 0x711e,
-	0x2148, 0xa804, 0x900d, 0x1128, 0x1e04, 0x6a84, 0x002e, 0x00ee,
-	0x0005, 0x2071, 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802,
-	0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70bc, 0x9200, 0x70be,
-	0x080c, 0x7f64, 0x0e04, 0x6a6e, 0x2071, 0x190e, 0x701c, 0x2048,
-	0xa84c, 0x900d, 0x0d18, 0x2071, 0x0000, 0x7182, 0xa850, 0x7032,
-	0xa86c, 0x7086, 0x7036, 0xa870, 0x708a, 0x2091, 0x4080, 0x2001,
-	0x0089, 0x2004, 0xd084, 0x190c, 0x1187, 0x2071, 0x190e, 0x080c,
-	0x6bb7, 0x002e, 0x00ee, 0x0005, 0x2071, 0x190e, 0xa803, 0x0000,
+	0x81f0, 0x782c, 0x9094, 0x0780, 0x190c, 0x6e16, 0xd0a4, 0x1d60,
+	0x00ee, 0x2071, 0x19d2, 0x703c, 0x9005, 0x1328, 0x2001, 0x1922,
+	0x2004, 0x8005, 0x703e, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x00e6,
+	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,
+	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, 0x1118, 0x002e,
+	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,
+	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, 0x7f64, 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, 0x6aef, 0x6af0, 0x6bb6, 0x6af0, 0x0db4, 0x6bb6, 0x0005,
-	0x2001, 0x1921, 0x2004, 0x0002, 0x6afa, 0x6afa, 0x6b4f, 0x6b50,
-	0x6afa, 0x6b50, 0x0126, 0x2091, 0x8000, 0x1e0c, 0x6bd6, 0x701c,
-	0x904d, 0x01e0, 0xa84c, 0x9005, 0x01d8, 0x0e04, 0x6b1e, 0xa94c,
-	0x2071, 0x0000, 0x7182, 0xa850, 0x7032, 0xa86c, 0x7086, 0x7036,
-	0xa870, 0x708a, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084,
-	0x190c, 0x1187, 0x2071, 0x190e, 0x080c, 0x6bb7, 0x012e, 0x0470,
-	0x2001, 0x005b, 0x2004, 0x9094, 0x0780, 0x190c, 0x6bcb, 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, 0x1a9f,
-	0x210c, 0x9102, 0x1500, 0x0126, 0x2091, 0x8000, 0x2069, 0x0050,
-	0x693c, 0x6838, 0x9106, 0x0190, 0x0e04, 0x6b82, 0x2069, 0x0000,
-	0x6837, 0x8040, 0x6833, 0x0012, 0x6883, 0x8040, 0x2091, 0x4080,
-	0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x1187, 0x2069, 0x19d2,
-	0x683f, 0xffff, 0x012e, 0x00de, 0x0126, 0x2091, 0x8000, 0x1e0c,
-	0x6c37, 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, 0x101d,
-	0x0005, 0x012e, 0x0005, 0x2091, 0x8000, 0x0e04, 0x6bcd, 0x0006,
-	0x0016, 0x2001, 0x8004, 0x0006, 0x0804, 0x0dbd, 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, 0x1187, 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,
-	0x7f64, 0x782c, 0x9094, 0x0780, 0x190c, 0x6bcb, 0xd0a4, 0x19f0,
-	0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836,
-	0x6833, 0x0013, 0x00de, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004,
-	0xd084, 0x190c, 0x1187, 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, 0x1187, 0x00fe, 0x0005, 0x782c, 0x9094, 0x0780, 0x190c,
-	0x6bcb, 0xd0a4, 0x0db8, 0x00e6, 0x2071, 0x1800, 0x7824, 0x2048,
-	0x702c, 0xa802, 0x2900, 0x702e, 0x70bc, 0x8000, 0x70be, 0x080c,
-	0x7f64, 0x782c, 0x9094, 0x0780, 0x190c, 0x6bcb, 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, 0x0db4, 0x9082, 0x001d, 0x001b,
-	0x6027, 0x1e00, 0x0005, 0x6d5f, 0x6ce5, 0x6d01, 0x6d2b, 0x6d4e,
-	0x6d8e, 0x6da0, 0x6d01, 0x6d76, 0x6ca0, 0x6cce, 0x6c9f, 0x0005,
-	0x00d6, 0x2069, 0x0200, 0x6804, 0x9005, 0x1180, 0x6808, 0x9005,
-	0x1518, 0x7097, 0x0028, 0x2069, 0x1967, 0x2d04, 0x7002, 0x080c,
-	0x70e1, 0x6028, 0x9085, 0x0600, 0x602a, 0x00b0, 0x7097, 0x0028,
-	0x2069, 0x1967, 0x2d04, 0x7002, 0x6028, 0x9085, 0x0600, 0x602a,
-	0x00e6, 0x0036, 0x0046, 0x0056, 0x2071, 0x1a3a, 0x080c, 0x196a,
-	0x005e, 0x004e, 0x003e, 0x00ee, 0x00de, 0x0005, 0x00d6, 0x2069,
-	0x0200, 0x6804, 0x9005, 0x1178, 0x6808, 0x9005, 0x1160, 0x7097,
-	0x0028, 0x2069, 0x1967, 0x2d04, 0x7002, 0x080c, 0x717b, 0x6028,
-	0x9085, 0x0600, 0x602a, 0x00de, 0x0005, 0x0006, 0x2001, 0x0090,
-	0x080c, 0x2b21, 0x000e, 0x6124, 0xd1e4, 0x1190, 0x080c, 0x6e0d,
-	0xd1d4, 0x1160, 0xd1dc, 0x1138, 0xd1cc, 0x0150, 0x7097, 0x0020,
-	0x080c, 0x6e0d, 0x0028, 0x7097, 0x001d, 0x0010, 0x7097, 0x001f,
-	0x0005, 0x2001, 0x0088, 0x080c, 0x2b21, 0x6124, 0xd1cc, 0x11e8,
-	0xd1dc, 0x11c0, 0xd1e4, 0x1198, 0x9184, 0x1e00, 0x11d8, 0x080c,
-	0x198f, 0x60e3, 0x0001, 0x600c, 0xc0b4, 0x600e, 0x080c, 0x6fd6,
-	0x2001, 0x0080, 0x080c, 0x2b21, 0x7097, 0x0028, 0x0058, 0x7097,
-	0x001e, 0x0040, 0x7097, 0x001d, 0x0028, 0x7097, 0x0020, 0x0010,
-	0x7097, 0x001f, 0x0005, 0x080c, 0x198f, 0x60e3, 0x0001, 0x600c,
-	0xc0b4, 0x600e, 0x080c, 0x6fd6, 0x2001, 0x0080, 0x080c, 0x2b21,
-	0x6124, 0xd1d4, 0x1180, 0xd1dc, 0x1158, 0xd1e4, 0x1130, 0x9184,
-	0x1e00, 0x1158, 0x7097, 0x0028, 0x0040, 0x7097, 0x001e, 0x0028,
-	0x7097, 0x001d, 0x0010, 0x7097, 0x001f, 0x0005, 0x2001, 0x00a0,
-	0x080c, 0x2b21, 0x6124, 0xd1dc, 0x1138, 0xd1e4, 0x0138, 0x080c,
-	0x198f, 0x7097, 0x001e, 0x0010, 0x7097, 0x001d, 0x0005, 0x080c,
-	0x6e90, 0x6124, 0xd1dc, 0x1188, 0x080c, 0x6e0d, 0x0016, 0x080c,
-	0x198f, 0x001e, 0xd1d4, 0x1128, 0xd1e4, 0x0138, 0x7097, 0x001e,
-	0x0020, 0x7097, 0x001f, 0x080c, 0x6e0d, 0x0005, 0x0006, 0x2001,
-	0x00a0, 0x080c, 0x2b21, 0x000e, 0x6124, 0xd1d4, 0x1160, 0xd1cc,
-	0x1150, 0xd1dc, 0x1128, 0xd1e4, 0x0140, 0x7097, 0x001e, 0x0028,
-	0x7097, 0x001d, 0x0010, 0x7097, 0x0021, 0x0005, 0x080c, 0x6e90,
-	0x6124, 0xd1d4, 0x1150, 0xd1dc, 0x1128, 0xd1e4, 0x0140, 0x7097,
-	0x001e, 0x0028, 0x7097, 0x001d, 0x0010, 0x7097, 0x001f, 0x0005,
-	0x0006, 0x2001, 0x0090, 0x080c, 0x2b21, 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,
+	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,
+	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,
+	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,
+	0xd1d4, 0x1160, 0xd1cc, 0x1150, 0xd1dc, 0x1128, 0xd1e4, 0x0140,
+	0x7097, 0x001e, 0x0028, 0x7097, 0x001d, 0x0010, 0x7097, 0x0021,
+	0x0005, 0x080c, 0x70db, 0x6124, 0xd1d4, 0x1150, 0xd1dc, 0x1128,
+	0xd1e4, 0x0140, 0x7097, 0x001e, 0x0028, 0x7097, 0x001d, 0x0010,
+	0x7097, 0x001f, 0x0005, 0x0006, 0x2001, 0x0090, 0x080c, 0x2c88,
+	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,
+	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,
+	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,
-	0x080c, 0x6faa, 0x11d8, 0x2001, 0x180c, 0x200c, 0xd1b4, 0x01b0,
-	0xc1b4, 0x2102, 0x6027, 0x0200, 0x080c, 0x2a6a, 0x6024, 0xd0cc,
-	0x0148, 0x2001, 0x00a0, 0x080c, 0x2b21, 0x080c, 0x728c, 0x080c,
-	0x5ce5, 0x0428, 0x6028, 0xc0cd, 0x602a, 0x0408, 0x080c, 0x6fc4,
-	0x0150, 0x080c, 0x6fbb, 0x1138, 0x2001, 0x0001, 0x080c, 0x2619,
-	0x080c, 0x6f82, 0x00a0, 0x080c, 0x6e8d, 0x0178, 0x2001, 0x0001,
-	0x080c, 0x2619, 0x7094, 0x9086, 0x001e, 0x0120, 0x7094, 0x9086,
-	0x0022, 0x1118, 0x7097, 0x0025, 0x0010, 0x7097, 0x0021, 0x012e,
-	0x00ee, 0x00de, 0x00ce, 0x001e, 0x0005, 0x0026, 0x2011, 0x6e1e,
-	0x080c, 0x8113, 0x002e, 0x0016, 0x0026, 0x2009, 0x0064, 0x2011,
-	0x6e1e, 0x080c, 0x810a, 0x002e, 0x001e, 0x0005, 0x00e6, 0x00f6,
-	0x0016, 0x080c, 0x93c7, 0x2071, 0x1800, 0x080c, 0x6dbb, 0x001e,
-	0x00fe, 0x00ee, 0x0005, 0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6,
-	0x00e6, 0x00f6, 0x0126, 0x080c, 0x93c7, 0x2061, 0x0100, 0x2069,
-	0x0140, 0x2071, 0x1800, 0x2091, 0x8000, 0x6028, 0xc09c, 0x602a,
-	0x2011, 0x0003, 0x080c, 0x975b, 0x2011, 0x0002, 0x080c, 0x9765,
-	0x080c, 0x9673, 0x080c, 0x80bf, 0x0036, 0x901e, 0x080c, 0x96e9,
-	0x003e, 0x60e3, 0x0000, 0x080c, 0xd8ee, 0x080c, 0xd909, 0x2009,
-	0x0004, 0x080c, 0x2a70, 0x080c, 0x298b, 0x2001, 0x1800, 0x2003,
-	0x0004, 0x6027, 0x0008, 0x2011, 0x6e1e, 0x080c, 0x8113, 0x080c,
-	0x6fc4, 0x0118, 0x9006, 0x080c, 0x2b21, 0x080c, 0x0b8f, 0x2001,
-	0x0001, 0x080c, 0x2619, 0x012e, 0x00fe, 0x00ee, 0x00de, 0x00ce,
-	0x003e, 0x002e, 0x001e, 0x0005, 0x0026, 0x00e6, 0x2011, 0x6e2b,
-	0x2071, 0x19d2, 0x701c, 0x9206, 0x1118, 0x7018, 0x9005, 0x0110,
-	0x9085, 0x0001, 0x00ee, 0x002e, 0x0005, 0x6020, 0xd09c, 0x0005,
-	0x6800, 0x9084, 0xfffe, 0x9086, 0x00c0, 0x01b8, 0x2001, 0x00c0,
-	0x080c, 0x2b21, 0x0156, 0x20a9, 0x002d, 0x1d04, 0x6e9d, 0x2091,
-	0x6000, 0x1f04, 0x6e9d, 0x015e, 0x00d6, 0x2069, 0x1800, 0x6898,
-	0x8001, 0x0220, 0x0118, 0x689a, 0x00de, 0x0005, 0x689b, 0x0014,
-	0x68e4, 0xd0dc, 0x0dc8, 0x6800, 0x9086, 0x0001, 0x1da8, 0x080c,
-	0x811f, 0x0c90, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2069,
-	0x0140, 0x2071, 0x1800, 0x080c, 0x729b, 0x2001, 0x1945, 0x2003,
-	0x0000, 0x9006, 0x7096, 0x60e2, 0x6886, 0x080c, 0x26e4, 0x9006,
-	0x080c, 0x2b21, 0x080c, 0x5ba4, 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, 0x0158, 0x9186, 0x0002,
-	0x0158, 0x9186, 0x0003, 0x0158, 0x0804, 0x6f72, 0x7097, 0x0022,
-	0x0040, 0x7097, 0x0021, 0x0028, 0x7097, 0x0023, 0x0010, 0x7097,
-	0x0024, 0x60e3, 0x0000, 0x6887, 0x0001, 0x2001, 0x0001, 0x080c,
-	0x26e4, 0x0026, 0x080c, 0x9db5, 0x002e, 0x7000, 0x908e, 0x0004,
-	0x0118, 0x602b, 0x0028, 0x0010, 0x602b, 0x0020, 0x0156, 0x0126,
-	0x2091, 0x8000, 0x20a9, 0x0005, 0x6024, 0xd0ac, 0x0150, 0x012e,
-	0x015e, 0x080c, 0xc23b, 0x0118, 0x9006, 0x080c, 0x2b4b, 0x0804,
-	0x6f7e, 0x6800, 0x9084, 0x00a1, 0xc0bd, 0x6802, 0x080c, 0x2a6a,
-	0x6904, 0xd1d4, 0x1140, 0x2001, 0x0100, 0x080c, 0x2b21, 0x1f04,
-	0x6f1c, 0x080c, 0x7001, 0x012e, 0x015e, 0x080c, 0x6fbb, 0x01a8,
-	0x6044, 0x9005, 0x0168, 0x6050, 0x0006, 0x9085, 0x0020, 0x6052,
-	0x080c, 0x7001, 0x9006, 0x8001, 0x1df0, 0x000e, 0x6052, 0x0028,
-	0x6804, 0xd0d4, 0x1110, 0x080c, 0x7001, 0x080c, 0xc23b, 0x0118,
-	0x9006, 0x080c, 0x2b4b, 0x0016, 0x0026, 0x7000, 0x908e, 0x0004,
-	0x0130, 0x2009, 0x00c8, 0x2011, 0x6e2b, 0x080c, 0x80d1, 0x002e,
-	0x001e, 0x080c, 0x7f5b, 0x7034, 0xc085, 0x7036, 0x2001, 0x1955,
-	0x2003, 0x0004, 0x080c, 0x6c88, 0x080c, 0x6fbb, 0x0138, 0x6804,
-	0xd0d4, 0x1120, 0xd0dc, 0x1100, 0x080c, 0x7291, 0x00ee, 0x00de,
-	0x00ce, 0x0005, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2069,
-	0x0140, 0x2071, 0x1800, 0x080c, 0x7f72, 0x080c, 0x7f64, 0x080c,
-	0x729b, 0x2001, 0x1945, 0x2003, 0x0000, 0x9006, 0x7096, 0x60e2,
-	0x6886, 0x080c, 0x26e4, 0x9006, 0x080c, 0x2b21, 0x6043, 0x0090,
-	0x6043, 0x0010, 0x6027, 0xffff, 0x602b, 0x182f, 0x00ee, 0x00de,
-	0x00ce, 0x0005, 0x0006, 0x2001, 0x1954, 0x2004, 0x9086, 0xaaaa,
-	0x000e, 0x0005, 0x0006, 0x080c, 0x539e, 0x9084, 0x0030, 0x9086,
-	0x0000, 0x000e, 0x0005, 0x0006, 0x080c, 0x539e, 0x9084, 0x0030,
-	0x9086, 0x0030, 0x000e, 0x0005, 0x0006, 0x080c, 0x539e, 0x9084,
-	0x0030, 0x9086, 0x0010, 0x000e, 0x0005, 0x0006, 0x080c, 0x539e,
-	0x9084, 0x0030, 0x9086, 0x0020, 0x000e, 0x0005, 0x0036, 0x0016,
-	0x2001, 0x180c, 0x2004, 0x908c, 0x0013, 0x0180, 0x0020, 0x080c,
-	0x2704, 0x900e, 0x0028, 0x080c, 0x6572, 0x1dc8, 0x2009, 0x0002,
-	0x2019, 0x0028, 0x080c, 0x2fb2, 0x9006, 0x0019, 0x001e, 0x003e,
-	0x0005, 0x00e6, 0x2071, 0x180c, 0x2e04, 0x0130, 0x080c, 0xc234,
-	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, 0x7016,
-	0x2091, 0x6000, 0x1f04, 0x7016, 0x602f, 0x0100, 0x602f, 0x0000,
-	0x6050, 0x9085, 0x0400, 0x9084, 0xdfff, 0x6052, 0x613a, 0x001e,
-	0x602f, 0x0040, 0x602f, 0x0000, 0x000e, 0x602a, 0x000e, 0x6006,
+	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,
+	0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e, 0x0005, 0x0026,
+	0x00e6, 0x2011, 0x7076, 0x2071, 0x19d2, 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,
+	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,
+	0xffff, 0x602b, 0x182f, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x00c6,
+	0x00d6, 0x00e6, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0x1800,
+	0x2001, 0x1955, 0x200c, 0x9186, 0x0000, 0x0158, 0x9186, 0x0001,
+	0x0158, 0x9186, 0x0002, 0x0158, 0x9186, 0x0003, 0x0158, 0x0804,
+	0x71cf, 0x7097, 0x0022, 0x0040, 0x7097, 0x0021, 0x0028, 0x7097,
+	0x0023, 0x0010, 0x7097, 0x0024, 0x60e3, 0x0000, 0x6887, 0x0001,
+	0x2001, 0x0001, 0x080c, 0x27e2, 0x0026, 0x080c, 0xa069, 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,
+	0x2004, 0x9086, 0x000a, 0x0158, 0x2011, 0x0114, 0x2204, 0x9085,
+	0x0100, 0x2012, 0x6050, 0x0006, 0x9085, 0x0020, 0x6052, 0x080c,
+	0x725e, 0x9006, 0x8001, 0x1df0, 0x2001, 0x0100, 0x2004, 0x9086,
+	0x000a, 0x0140, 0x000e, 0x6052, 0x0028, 0x6804, 0xd0d4, 0x1110,
+	0x080c, 0x725e, 0x080c, 0xc539, 0x0118, 0x9006, 0x080c, 0x2cb2,
+	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,
+	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,
+	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,
+	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, 0x26e4, 0x2001, 0x00a0, 0x0006, 0x080c,
-	0xc23b, 0x000e, 0x0130, 0x080c, 0x2b3f, 0x9006, 0x080c, 0x2b4b,
-	0x0010, 0x080c, 0x2b21, 0x000e, 0x6052, 0x6050, 0x0006, 0xc0e5,
-	0x6052, 0x00f6, 0x2079, 0x0100, 0x080c, 0x29df, 0x00fe, 0x000e,
+	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, 0x70d3, 0x2001, 0x180c, 0x200c, 0xc1c4, 0x2102, 0x6028,
+	0x0804, 0x734b, 0x2001, 0x180c, 0x200c, 0xc1c4, 0x2102, 0x6028,
 	0x9084, 0xe1ff, 0x602a, 0x6027, 0x0200, 0x2001, 0x0090, 0x080c,
-	0x2b21, 0x20a9, 0x0366, 0x6024, 0xd0cc, 0x1518, 0x1d04, 0x7083,
-	0x2091, 0x6000, 0x1f04, 0x7083, 0x2011, 0x0003, 0x080c, 0x975b,
-	0x2011, 0x0002, 0x080c, 0x9765, 0x080c, 0x9673, 0x901e, 0x080c,
-	0x96e9, 0x2001, 0x00a0, 0x080c, 0x2b21, 0x080c, 0x728c, 0x080c,
-	0x5ce5, 0x080c, 0xc23b, 0x0110, 0x080c, 0x0d22, 0x9085, 0x0001,
-	0x0480, 0x080c, 0x198f, 0x60e3, 0x0000, 0x2001, 0x0002, 0x080c,
-	0x26e4, 0x60e2, 0x2001, 0x0080, 0x080c, 0x2b21, 0x20a9, 0x0366,
-	0x6027, 0x1e00, 0x2009, 0x1e00, 0x080c, 0x2a6a, 0x6024, 0x910c,
-	0x0138, 0x1d04, 0x70b8, 0x2091, 0x6000, 0x1f04, 0x70b8, 0x0820,
+	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, 0xc23b, 0x0110, 0x080c, 0x0d22,
+	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, 0x7146, 0x2001,
-	0x0088, 0x080c, 0x2b21, 0x9006, 0x60e2, 0x6886, 0x080c, 0x26e4,
+	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, 0x7128, 0x2091, 0x6000, 0x1f04, 0x7128, 0x0804, 0x7173,
+	0x1d04, 0x73a0, 0x2091, 0x6000, 0x1f04, 0x73a0, 0x0804, 0x73eb,
 	0x2069, 0x0140, 0x20a9, 0x0384, 0x6027, 0x1e00, 0x2009, 0x1e00,
-	0x080c, 0x2a6a, 0x6024, 0x910c, 0x0508, 0x9084, 0x1a00, 0x11f0,
-	0x1d04, 0x7134, 0x2091, 0x6000, 0x1f04, 0x7134, 0x2011, 0x0003,
-	0x080c, 0x975b, 0x2011, 0x0002, 0x080c, 0x9765, 0x080c, 0x9673,
-	0x901e, 0x080c, 0x96e9, 0x2001, 0x00a0, 0x080c, 0x2b21, 0x080c,
-	0x728c, 0x080c, 0x5ce5, 0x9085, 0x0001, 0x00a8, 0x2001, 0x0080,
-	0x080c, 0x2b21, 0x2069, 0x0140, 0x60e3, 0x0000, 0x70b0, 0x9005,
+	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,
-	0x26e4, 0x60e2, 0x9006, 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e,
+	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, 0x975b, 0x2011, 0x0002,
-	0x080c, 0x9765, 0x080c, 0x9673, 0x901e, 0x080c, 0x96e9, 0x2069,
-	0x0140, 0x2001, 0x00a0, 0x080c, 0x2b21, 0x080c, 0x728c, 0x080c,
-	0x5ce5, 0x0804, 0x720d, 0x2001, 0x180c, 0x200c, 0xd1b4, 0x1160,
-	0xc1b5, 0x2102, 0x080c, 0x6e13, 0x2069, 0x0140, 0x2001, 0x0080,
-	0x080c, 0x2b21, 0x60e3, 0x0000, 0x2069, 0x0200, 0x6804, 0x9005,
+	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, 0x720d, 0x6027, 0x1e00, 0x2009, 0x1e00,
-	0x080c, 0x2a6a, 0x6024, 0x910c, 0x01c8, 0x9084, 0x1c00, 0x11b0,
-	0x1d04, 0x71cc, 0x0006, 0x0016, 0x00c6, 0x00d6, 0x00e6, 0x080c,
-	0x7fa3, 0x00ee, 0x00de, 0x00ce, 0x001e, 0x000e, 0x00e6, 0x2071,
+	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,
-	0x6e2b, 0x080c, 0x803f, 0x2011, 0x6e1e, 0x080c, 0x8113, 0x002e,
+	0x7076, 0x080c, 0x82da, 0x2011, 0x7069, 0x080c, 0x83ae, 0x002e,
 	0x2069, 0x0140, 0x60e3, 0x0000, 0x70b0, 0x9005, 0x1118, 0x6887,
-	0x0001, 0x0008, 0x6886, 0x2001, 0x0002, 0x080c, 0x26e4, 0x60e2,
+	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, 0xc234, 0x1904, 0x727a, 0x7130, 0xd184, 0x1170, 0x080c,
-	0x3140, 0x0138, 0xc18d, 0x7132, 0x2011, 0x185c, 0x2214, 0xd2ac,
-	0x1120, 0x7030, 0xd08c, 0x0904, 0x727a, 0x2011, 0x185c, 0x220c,
-	0x0438, 0x0016, 0x2019, 0x000e, 0x080c, 0xd4e0, 0x0156, 0x00b6,
+	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, 0x6256, 0x1170, 0x2120, 0x9006, 0x0016, 0x2009,
-	0x000e, 0x080c, 0xd564, 0x2009, 0x0001, 0x2011, 0x0100, 0x080c,
-	0x8236, 0x001e, 0x8108, 0x1f04, 0x7243, 0x00be, 0x015e, 0x001e,
+	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,
-	0x2fb2, 0x001e, 0x0078, 0x0156, 0x00b6, 0x20a9, 0x007f, 0x900e,
-	0x080c, 0x6256, 0x1110, 0x080c, 0x5cff, 0x8108, 0x1f04, 0x7270,
-	0x00be, 0x015e, 0x080c, 0x198f, 0x080c, 0x9db5, 0x60e3, 0x0000,
-	0x080c, 0x5ce5, 0x080c, 0x6edc, 0x00ee, 0x00ce, 0x004e, 0x003e,
+	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, 0x1004,
-	0x090c, 0x0db4, 0xa8ab, 0xdcb0, 0x2900, 0x704e, 0x080c, 0x1004,
-	0x090c, 0x0db4, 0xa8ab, 0xdcb0, 0x2900, 0x7052, 0xa867, 0x0000,
+	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,
@@ -3473,2043 +3552,2051 @@
 	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, 0x788e, 0x9006, 0x00ee, 0x0005, 0x900e, 0x0156,
-	0x20a9, 0x0006, 0x8003, 0x2011, 0x0100, 0x2214, 0x9296, 0x0008,
-	0x1110, 0x818d, 0x0010, 0x81f5, 0x3e08, 0x1f04, 0x7302, 0x015e,
-	0x0005, 0x2079, 0x0040, 0x2071, 0x18f8, 0x7004, 0x0002, 0x7321,
-	0x7322, 0x735a, 0x73b5, 0x74f6, 0x731f, 0x731f, 0x7520, 0x080c,
-	0x0db4, 0x0005, 0x2079, 0x0040, 0x782c, 0x908c, 0x0780, 0x190c,
-	0x791a, 0xd0a4, 0x01f8, 0x7824, 0x2048, 0x9006, 0xa802, 0xa806,
-	0xa864, 0x9084, 0x00ff, 0x908a, 0x0040, 0x0610, 0x00c0, 0x2001,
-	0x1800, 0x200c, 0x9186, 0x0003, 0x1168, 0x7004, 0x0002, 0x734a,
-	0x7324, 0x734a, 0x7348, 0x734a, 0x734a, 0x734a, 0x734a, 0x734a,
-	0x080c, 0x73b5, 0x782c, 0xd09c, 0x090c, 0x788e, 0x0005, 0x9082,
-	0x005a, 0x1218, 0x2100, 0x003b, 0x0c10, 0x080c, 0x73eb, 0x0c90,
-	0x00e3, 0x08e8, 0x0005, 0x73eb, 0x73eb, 0x73eb, 0x73eb, 0x73eb,
-	0x73eb, 0x73eb, 0x73eb, 0x740d, 0x73eb, 0x73eb, 0x73eb, 0x73eb,
-	0x73eb, 0x73eb, 0x73eb, 0x73eb, 0x73eb, 0x73eb, 0x73eb, 0x73eb,
-	0x73eb, 0x73eb, 0x73eb, 0x73eb, 0x73eb, 0x73eb, 0x73eb, 0x73f7,
-	0x73eb, 0x75f5, 0x73eb, 0x73eb, 0x73eb, 0x740d, 0x73eb, 0x73f7,
-	0x7636, 0x7677, 0x76be, 0x76d2, 0x73eb, 0x73eb, 0x740d, 0x73f7,
-	0x73eb, 0x73eb, 0x74ca, 0x777d, 0x7798, 0x73eb, 0x740d, 0x73eb,
-	0x73eb, 0x73eb, 0x73eb, 0x74c0, 0x7798, 0x73eb, 0x73eb, 0x73eb,
-	0x73eb, 0x73eb, 0x73eb, 0x73eb, 0x73eb, 0x73eb, 0x7421, 0x73eb,
-	0x73eb, 0x73eb, 0x73eb, 0x73eb, 0x73eb, 0x73eb, 0x73eb, 0x73eb,
-	0x78be, 0x73eb, 0x73eb, 0x73eb, 0x73eb, 0x73eb, 0x7435, 0x73eb,
-	0x73eb, 0x73eb, 0x73eb, 0x73eb, 0x73eb, 0x2079, 0x0040, 0x7004,
-	0x9086, 0x0003, 0x1198, 0x782c, 0x080c, 0x78b7, 0xd0a4, 0x0170,
-	0x7824, 0x2048, 0x9006, 0xa802, 0xa806, 0xa864, 0x9084, 0x00ff,
-	0x908a, 0x001a, 0x1210, 0x002b, 0x0c50, 0x00e9, 0x080c, 0x788e,
-	0x0005, 0x73eb, 0x73f7, 0x75e1, 0x73eb, 0x73f7, 0x73eb, 0x73f7,
-	0x73f7, 0x73eb, 0x73f7, 0x75e1, 0x73f7, 0x73f7, 0x73f7, 0x73f7,
-	0x73f7, 0x73eb, 0x73f7, 0x75e1, 0x73eb, 0x73eb, 0x73f7, 0x73eb,
-	0x73eb, 0x73eb, 0x73f7, 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, 0x68a0, 0x012e, 0x0005, 0xa864, 0x8007, 0x9084,
-	0x00ff, 0x0d08, 0x8001, 0x1120, 0x7007, 0x0001, 0x0804, 0x759f,
-	0x7007, 0x0003, 0x7012, 0x2900, 0x7016, 0x701a, 0x704b, 0x759f,
-	0x0005, 0xa864, 0x8007, 0x9084, 0x00ff, 0x0968, 0x8001, 0x1120,
-	0x7007, 0x0001, 0x0804, 0x75ba, 0x7007, 0x0003, 0x7012, 0x2900,
-	0x7016, 0x701a, 0x704b, 0x75ba, 0x0005, 0xa864, 0x8007, 0x9084,
-	0x00ff, 0x9086, 0x0001, 0x1904, 0x73f3, 0x7007, 0x0001, 0x2009,
-	0x1833, 0x210c, 0x81ff, 0x1904, 0x7497, 0xa994, 0x9186, 0x006f,
-	0x0188, 0x9186, 0x0074, 0x15b0, 0x0026, 0x2011, 0x0010, 0x080c,
-	0x659e, 0x002e, 0x0578, 0x0016, 0xa998, 0x080c, 0x65e8, 0x001e,
-	0x1548, 0x0400, 0x080c, 0x6faa, 0x0140, 0xa897, 0x4005, 0xa89b,
-	0x0016, 0x2001, 0x0030, 0x900e, 0x0438, 0x0026, 0x2011, 0x8008,
-	0x080c, 0x659e, 0x002e, 0x01b0, 0x0016, 0x0026, 0x0036, 0xa998,
-	0xaaa0, 0xab9c, 0x918d, 0x8000, 0x080c, 0x65e8, 0x003e, 0x002e,
-	0x001e, 0x1140, 0xa897, 0x4005, 0xa89b, 0x4009, 0x2001, 0x0030,
-	0x900e, 0x0050, 0xa868, 0x9084, 0x00ff, 0xa86a, 0xa883, 0x0000,
-	0x080c, 0x5f14, 0x1108, 0x0005, 0x0126, 0x2091, 0x8000, 0xa867,
-	0x0139, 0xa87a, 0xa982, 0x080c, 0x68a0, 0x012e, 0x0ca0, 0xa994,
-	0x9186, 0x0071, 0x0904, 0x7445, 0x9186, 0x0064, 0x0904, 0x7445,
-	0x9186, 0x007c, 0x0904, 0x7445, 0x9186, 0x0028, 0x0904, 0x7445,
-	0x9186, 0x0038, 0x0904, 0x7445, 0x9186, 0x0078, 0x0904, 0x7445,
-	0x9186, 0x005f, 0x0904, 0x7445, 0x9186, 0x0056, 0x0904, 0x7445,
-	0xa897, 0x4005, 0xa89b, 0x0001, 0x2001, 0x0030, 0x900e, 0x0860,
-	0xa87c, 0x9084, 0x00c0, 0x9086, 0x00c0, 0x1120, 0x7007, 0x0001,
-	0x0804, 0x77af, 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, 0x73fb, 0xaab4, 0x928a, 0x0002, 0x1a04,
-	0x73fb, 0x82ff, 0x1138, 0xa8b8, 0xa9bc, 0x9105, 0x0118, 0x2001,
-	0x755d, 0x0018, 0x9280, 0x7553, 0x2005, 0x7056, 0x7010, 0x9015,
-	0x0904, 0x753e, 0x080c, 0x1004, 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, 0x10d5,
-	0xa06c, 0x908e, 0x0100, 0x0170, 0x9086, 0x0200, 0x0118, 0x7007,
-	0x0007, 0x0005, 0x7020, 0x2048, 0x080c, 0x101d, 0x7014, 0x2048,
-	0x0804, 0x73fb, 0x7020, 0x2048, 0x7018, 0xa802, 0xa807, 0x0000,
-	0x2908, 0x2048, 0xa906, 0x711a, 0x0804, 0x74f6, 0x7014, 0x2048,
-	0x7007, 0x0001, 0xa8b4, 0x9005, 0x1128, 0xa8b8, 0xa9bc, 0x9105,
-	0x0108, 0x00b9, 0xa864, 0x9084, 0x00ff, 0x9086, 0x001e, 0x0904,
-	0x77af, 0x0804, 0x759f, 0x7555, 0x7559, 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, 0x5d61, 0x1108, 0x0005,
-	0x080c, 0x6ace, 0x0126, 0x2091, 0x8000, 0x080c, 0xbe2f, 0x080c,
-	0x68a0, 0x012e, 0x0ca0, 0x080c, 0xc234, 0x1d70, 0x2001, 0x0028,
-	0x900e, 0x0c70, 0x2009, 0x1833, 0x210c, 0x81ff, 0x11d8, 0xa888,
-	0x9005, 0x01e0, 0xa883, 0x0000, 0xa87c, 0xd0f4, 0x0120, 0x080c,
-	0x5e76, 0x1138, 0x0005, 0x9006, 0xa87a, 0x080c, 0x5df1, 0x1108,
-	0x0005, 0x0126, 0x2091, 0x8000, 0xa87a, 0xa982, 0x080c, 0x68a0,
-	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, 0x6256, 0x11b8,
-	0x0066, 0xae80, 0x080c, 0x6366, 0x006e, 0x0088, 0x0046, 0x2011,
-	0x180c, 0x2224, 0xc484, 0x2412, 0x004e, 0x00c6, 0x080c, 0x6256,
-	0x1110, 0x080c, 0x6466, 0x8108, 0x1f04, 0x761e, 0x00ce, 0xa87c,
-	0xd084, 0x1120, 0x080c, 0x101d, 0x00be, 0x0005, 0x0126, 0x2091,
-	0x8000, 0x080c, 0x68a0, 0x012e, 0x00be, 0x0005, 0x0126, 0x2091,
-	0x8000, 0x7007, 0x0001, 0x080c, 0x6576, 0x0580, 0x2061, 0x1a48,
-	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, 0x7878, 0x012e, 0x0804,
-	0x7872, 0x012e, 0x0804, 0x786c, 0x012e, 0x0804, 0x786f, 0x0126,
-	0x2091, 0x8000, 0x7007, 0x0001, 0x080c, 0x6576, 0x05e0, 0x2061,
-	0x1a48, 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, 0x7878,
-	0x012e, 0x0804, 0x7875, 0x012e, 0x0804, 0x7872, 0x0126, 0x2091,
-	0x8000, 0x7007, 0x0001, 0x2061, 0x1a48, 0x6300, 0xd38c, 0x1120,
-	0x6308, 0x8318, 0x0220, 0x630a, 0x012e, 0x0804, 0x7886, 0x012e,
-	0x0804, 0x7875, 0x00b6, 0x0126, 0x00c6, 0x2091, 0x8000, 0x7007,
-	0x0001, 0xa87c, 0xd0ac, 0x0148, 0x00c6, 0x2061, 0x1a48, 0x6000,
-	0x9084, 0xfcff, 0x6002, 0x00ce, 0x0440, 0xa888, 0x9005, 0x05d8,
-	0xa88c, 0x9065, 0x0598, 0x2001, 0x1833, 0x2004, 0x9005, 0x0118,
-	0x080c, 0x9e5f, 0x0068, 0x6017, 0xf400, 0x605b, 0x0000, 0xa97c,
-	0xd1a4, 0x0110, 0xa980, 0x615a, 0x2009, 0x0041, 0x080c, 0x9ea9,
-	0xa988, 0x918c, 0xff00, 0x9186, 0x2000, 0x1138, 0x0026, 0x900e,
-	0x2011, 0xfdff, 0x080c, 0x8236, 0x002e, 0xa87c, 0xd0c4, 0x0148,
-	0x2061, 0x1a48, 0x6000, 0xd08c, 0x1120, 0x6008, 0x8000, 0x0208,
-	0x600a, 0x00ce, 0x012e, 0x00be, 0x0804, 0x7878, 0x00ce, 0x012e,
-	0x00be, 0x0804, 0x7872, 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, 0x6256, 0x1968,
-	0xb800, 0xc0e4, 0xb802, 0x0848, 0xa88c, 0x9065, 0x09b8, 0x6007,
-	0x0024, 0x2001, 0x195e, 0x2004, 0x601a, 0x0804, 0x770d, 0xa88c,
-	0x9065, 0x0960, 0x00e6, 0xa890, 0x9075, 0x2001, 0x1833, 0x2004,
-	0x9005, 0x0150, 0x080c, 0x9e5f, 0x8eff, 0x0118, 0x2e60, 0x080c,
-	0x9e5f, 0x00ee, 0x0804, 0x770d, 0x6024, 0xc0dc, 0xc0d5, 0x6026,
-	0x2e60, 0x6007, 0x003a, 0xa8a0, 0x9005, 0x0130, 0x6007, 0x003b,
-	0xa8a4, 0x602e, 0xa8a8, 0x6016, 0x6003, 0x0001, 0x080c, 0x83f8,
-	0x080c, 0x898b, 0x00ee, 0x0804, 0x770d, 0x2061, 0x1a48, 0x6000,
-	0xd084, 0x0190, 0xd08c, 0x1904, 0x7886, 0x0126, 0x2091, 0x8000,
-	0x6204, 0x8210, 0x0220, 0x6206, 0x012e, 0x0804, 0x7886, 0x012e,
-	0xa883, 0x0016, 0x0804, 0x787f, 0xa883, 0x0007, 0x0804, 0x787f,
-	0xa864, 0x8007, 0x9084, 0x00ff, 0x0130, 0x8001, 0x1138, 0x7007,
-	0x0001, 0x0069, 0x0005, 0x080c, 0x73f3, 0x0040, 0x7007, 0x0003,
-	0x7012, 0x2900, 0x7016, 0x701a, 0x704b, 0x77af, 0x0005, 0x00b6,
-	0x00e6, 0x0126, 0x2091, 0x8000, 0x903e, 0x2061, 0x1800, 0x61cc,
-	0x81ff, 0x1904, 0x7831, 0x6130, 0xd194, 0x1904, 0x785b, 0xa878,
-	0x2070, 0x9e82, 0x1cd0, 0x0a04, 0x7825, 0x6064, 0x9e02, 0x1a04,
-	0x7825, 0x7120, 0x9186, 0x0006, 0x1904, 0x7817, 0x7010, 0x905d,
-	0x0904, 0x7831, 0xb800, 0xd0e4, 0x1904, 0x7855, 0x2061, 0x1a48,
-	0x6100, 0x9184, 0x0301, 0x9086, 0x0001, 0x15a0, 0x7024, 0xd0dc,
-	0x1904, 0x785e, 0xa883, 0x0000, 0xa803, 0x0000, 0x2908, 0x7014,
-	0x9005, 0x1198, 0x7116, 0xa87c, 0xd0f4, 0x1904, 0x7861, 0x080c,
-	0x539a, 0xd09c, 0x1118, 0xa87c, 0xc0cc, 0xa87e, 0x2e60, 0x080c,
-	0x8156, 0x012e, 0x00ee, 0x00be, 0x0005, 0x2048, 0xa800, 0x9005,
-	0x1de0, 0xa902, 0x2148, 0xa87c, 0xd0f4, 0x1904, 0x7861, 0x012e,
-	0x00ee, 0x00be, 0x0005, 0x012e, 0x00ee, 0xa883, 0x0006, 0x00be,
-	0x0804, 0x787f, 0xd184, 0x0db8, 0xd1c4, 0x1190, 0x00a0, 0xa974,
-	0x080c, 0x6256, 0x15d0, 0xb800, 0xd0e4, 0x15b8, 0x7120, 0x9186,
-	0x0007, 0x1118, 0xa883, 0x0002, 0x0490, 0xa883, 0x0008, 0x0478,
-	0xa883, 0x000e, 0x0460, 0xa883, 0x0017, 0x0448, 0xa883, 0x0035,
-	0x0430, 0x080c, 0x539e, 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, 0x77bb, 0x7003, 0x0002,
-	0x0804, 0x77bb, 0xa883, 0x0028, 0x0010, 0xa883, 0x0029, 0x012e,
-	0x00ee, 0x00be, 0x0420, 0xa883, 0x002a, 0x0cc8, 0xa883, 0x0045,
-	0x0cb0, 0x2e60, 0x2019, 0x0002, 0x601b, 0x0014, 0x080c, 0xd11f,
-	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, 0x68a0, 0x012e, 0x0005, 0x080c, 0x101d,
-	0x0005, 0x00d6, 0x080c, 0x814d, 0x00de, 0x0005, 0x00d6, 0x00e6,
-	0x0126, 0x2091, 0x8000, 0x2071, 0x0040, 0x702c, 0xd084, 0x01d8,
-	0x908c, 0x0780, 0x190c, 0x791a, 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, 0x791a, 0x000e, 0x0005, 0x00d6, 0x00c6,
-	0x0036, 0x0026, 0x0016, 0x00b6, 0x7007, 0x0001, 0xaa74, 0x9282,
-	0x0004, 0x1a04, 0x790b, 0xa97c, 0x9188, 0x1000, 0x2104, 0x905d,
-	0xb804, 0xd284, 0x0140, 0x05e8, 0x8007, 0x9084, 0x00ff, 0x9084,
-	0x0006, 0x1108, 0x04b0, 0x2b10, 0x080c, 0x9dd9, 0x1118, 0x080c,
-	0x9e7c, 0x05a8, 0x6212, 0xa874, 0x0002, 0x78e9, 0x78ee, 0x78f1,
-	0x78f7, 0x2019, 0x0002, 0x080c, 0xd4e0, 0x0060, 0x080c, 0xd47c,
-	0x0048, 0x2019, 0x0002, 0xa980, 0x080c, 0xd497, 0x0018, 0xa980,
-	0x080c, 0xd47c, 0x080c, 0x9e2f, 0xa887, 0x0000, 0x0126, 0x2091,
-	0x8000, 0x080c, 0x68a0, 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, 0x791c, 0x0006, 0x0016,
-	0x2001, 0x8003, 0x0006, 0x0804, 0x0dbd, 0x2001, 0x1833, 0x2004,
-	0x9005, 0x0005, 0x0005, 0x00f6, 0x2079, 0x0300, 0x2001, 0x0200,
-	0x200c, 0xc1e5, 0xc1dc, 0x2102, 0x2009, 0x0218, 0x210c, 0xd1ec,
-	0x1120, 0x080c, 0x14a9, 0x00fe, 0x0005, 0x2001, 0x020d, 0x2003,
-	0x0020, 0x781f, 0x0300, 0x00fe, 0x0005, 0x781c, 0xd08c, 0x0904,
-	0x799c, 0x68bc, 0x90aa, 0x0005, 0x0a04, 0x7f5b, 0x7d44, 0x7c40,
-	0x9584, 0x00f6, 0x1510, 0x9484, 0x7000, 0x0140, 0x908a, 0x2000,
-	0x1260, 0x9584, 0x0700, 0x8007, 0x0804, 0x79a3, 0x7000, 0x9084,
-	0xff00, 0x9086, 0x8100, 0x0da8, 0x00b0, 0x9484, 0x0fff, 0x1130,
-	0x7000, 0x9084, 0xff00, 0x9086, 0x8100, 0x11c0, 0x080c, 0xd8c6,
-	0x080c, 0x7e90, 0x7817, 0x0140, 0x00a8, 0x9584, 0x0076, 0x1118,
-	0x080c, 0x7eee, 0x19c0, 0xd5a4, 0x0148, 0x0046, 0x0056, 0x080c,
-	0x79fe, 0x080c, 0x21da, 0x005e, 0x004e, 0x0020, 0x080c, 0xd8c6,
-	0x7817, 0x0140, 0x080c, 0x6faa, 0x0168, 0x2001, 0x0111, 0x2004,
-	0xd08c, 0x0140, 0x688f, 0x0000, 0x2001, 0x0110, 0x2003, 0x0008,
-	0x2003, 0x0000, 0x080c, 0x79df, 0x2001, 0x19c8, 0x2004, 0x9005,
-	0x090c, 0x898b, 0x0005, 0x0002, 0x79b5, 0x7cb2, 0x79ac, 0x79ac,
-	0x79ac, 0x79ac, 0x79ac, 0x79ac, 0x7817, 0x0140, 0x2001, 0x19c8,
-	0x2004, 0x9005, 0x090c, 0x898b, 0x0005, 0x7000, 0x908c, 0xff00,
-	0x9194, 0xf000, 0x810f, 0x9484, 0x0fff, 0x688e, 0x9286, 0x2000,
-	0x1150, 0x6800, 0x9086, 0x0001, 0x1118, 0x080c, 0x53fb, 0x0070,
-	0x080c, 0x7a1e, 0x0058, 0x9286, 0x3000, 0x1118, 0x080c, 0x7bed,
-	0x0028, 0x9286, 0x8000, 0x1110, 0x080c, 0x7dc0, 0x7817, 0x0140,
-	0x2001, 0x19c8, 0x2004, 0x9005, 0x090c, 0x898b, 0x0005, 0x2001,
-	0x1810, 0x2004, 0xd08c, 0x0178, 0x2001, 0x1800, 0x2004, 0x9086,
-	0x0003, 0x1148, 0x0026, 0x0036, 0x2011, 0x8048, 0x2518, 0x080c,
-	0x48f4, 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, 0x48f4,
-	0x002e, 0x00fe, 0x005e, 0x004e, 0x003e, 0x0005, 0x00b6, 0x00c6,
-	0x7010, 0x9084, 0xff00, 0x8007, 0x9096, 0x0001, 0x0120, 0x9096,
-	0x0023, 0x1904, 0x7bbe, 0x9186, 0x0023, 0x15c0, 0x080c, 0x7e55,
-	0x0904, 0x7bbe, 0x6120, 0x9186, 0x0001, 0x0150, 0x9186, 0x0004,
-	0x0138, 0x9186, 0x0008, 0x0120, 0x9186, 0x000a, 0x1904, 0x7bbe,
-	0x7124, 0x610a, 0x7030, 0x908e, 0x0200, 0x1130, 0x2009, 0x0015,
-	0x080c, 0x9ea9, 0x0804, 0x7bbe, 0x908e, 0x0214, 0x0118, 0x908e,
-	0x0210, 0x1130, 0x2009, 0x0015, 0x080c, 0x9ea9, 0x0804, 0x7bbe,
-	0x908e, 0x0100, 0x1904, 0x7bbe, 0x7034, 0x9005, 0x1904, 0x7bbe,
-	0x2009, 0x0016, 0x080c, 0x9ea9, 0x0804, 0x7bbe, 0x9186, 0x0022,
-	0x1904, 0x7bbe, 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, 0x26b9, 0x7932, 0x7936, 0x001e,
-	0x000e, 0x00fe, 0x080c, 0x2670, 0x695a, 0x703c, 0x00e6, 0x2071,
-	0x0140, 0x7086, 0x2071, 0x1800, 0x70b2, 0x00ee, 0x7034, 0x9005,
-	0x1904, 0x7bbe, 0x2009, 0x0017, 0x0804, 0x7b6e, 0x908e, 0x0400,
-	0x1190, 0x7034, 0x9005, 0x1904, 0x7bbe, 0x080c, 0x6faa, 0x0120,
-	0x2009, 0x001d, 0x0804, 0x7b6e, 0x68d8, 0xc0a5, 0x68da, 0x2009,
-	0x0030, 0x0804, 0x7b6e, 0x908e, 0x0500, 0x1140, 0x7034, 0x9005,
-	0x1904, 0x7bbe, 0x2009, 0x0018, 0x0804, 0x7b6e, 0x908e, 0x2010,
-	0x1120, 0x2009, 0x0019, 0x0804, 0x7b6e, 0x908e, 0x2110, 0x1120,
-	0x2009, 0x001a, 0x0804, 0x7b6e, 0x908e, 0x5200, 0x1140, 0x7034,
-	0x9005, 0x1904, 0x7bbe, 0x2009, 0x001b, 0x0804, 0x7b6e, 0x908e,
-	0x5000, 0x1140, 0x7034, 0x9005, 0x1904, 0x7bbe, 0x2009, 0x001c,
-	0x0804, 0x7b6e, 0x908e, 0x1300, 0x1120, 0x2009, 0x0034, 0x0804,
-	0x7b6e, 0x908e, 0x1200, 0x1140, 0x7034, 0x9005, 0x1904, 0x7bbe,
-	0x2009, 0x0024, 0x0804, 0x7b6e, 0x908c, 0xff00, 0x918e, 0x2400,
-	0x1170, 0x2009, 0x002d, 0x2001, 0x1810, 0x2004, 0xd09c, 0x0904,
-	0x7b6e, 0x080c, 0xc8e6, 0x1904, 0x7bbe, 0x0804, 0x7b6c, 0x908c,
-	0xff00, 0x918e, 0x5300, 0x1120, 0x2009, 0x002a, 0x0804, 0x7b6e,
-	0x908e, 0x0f00, 0x1120, 0x2009, 0x0020, 0x0804, 0x7b6e, 0x908e,
-	0x6104, 0x1528, 0x2029, 0x0205, 0x2011, 0x026d, 0x8208, 0x2204,
-	0x9082, 0x0004, 0x8004, 0x8004, 0x20a8, 0x2011, 0x8015, 0x211c,
-	0x8108, 0x0046, 0x2124, 0x080c, 0x48f4, 0x004e, 0x8108, 0x0f04,
-	0x7b3a, 0x9186, 0x0280, 0x1d88, 0x2504, 0x8000, 0x202a, 0x2009,
-	0x0260, 0x0c58, 0x202b, 0x0000, 0x2009, 0x0023, 0x0478, 0x908e,
-	0x6000, 0x1118, 0x2009, 0x003f, 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, 0x2670, 0x1904, 0x7bc1,
-	0x080c, 0x61f6, 0x1904, 0x7bc1, 0xbe12, 0xbd16, 0x001e, 0x0016,
-	0x080c, 0x6faa, 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, 0x9dd9, 0x01a8, 0x2b08, 0x6112,
-	0x6023, 0x0004, 0x7120, 0x610a, 0x001e, 0x9186, 0x004c, 0x1110,
-	0x6023, 0x000a, 0x0016, 0x001e, 0x080c, 0x9ea9, 0x00ce, 0x00be,
-	0x0005, 0x001e, 0x0cd8, 0x2001, 0x180e, 0x2004, 0xd0ec, 0x0120,
-	0x2011, 0x8049, 0x080c, 0x48f4, 0x080c, 0x9e7c, 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, 0x8440, 0x08a0, 0x080c, 0x310a, 0x1140,
-	0x7010, 0x9084, 0xff00, 0x8007, 0x908e, 0x0008, 0x1108, 0x0009,
-	0x0005, 0x00b6, 0x00c6, 0x0046, 0x7000, 0x908c, 0xff00, 0x810f,
-	0x9186, 0x0033, 0x11e8, 0x080c, 0x7e55, 0x0904, 0x7c4a, 0x7124,
-	0x610a, 0x7030, 0x908e, 0x0200, 0x1140, 0x7034, 0x9005, 0x15d0,
-	0x2009, 0x0015, 0x080c, 0x9ea9, 0x04a8, 0x908e, 0x0100, 0x1590,
-	0x7034, 0x9005, 0x1578, 0x2009, 0x0016, 0x080c, 0x9ea9, 0x0450,
-	0x9186, 0x0032, 0x1538, 0x7030, 0x908e, 0x1400, 0x1518, 0x2009,
-	0x0038, 0x0016, 0x2011, 0x0263, 0x2204, 0x8211, 0x220c, 0x080c,
-	0x2670, 0x11b8, 0x080c, 0x61f6, 0x11a0, 0xbe12, 0xbd16, 0x080c,
-	0x9dd9, 0x0178, 0x2b08, 0x6112, 0x080c, 0xbfb5, 0x6023, 0x0004,
-	0x7120, 0x610a, 0x001e, 0x080c, 0x9ea9, 0x080c, 0x898b, 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,
-	0x7cac, 0x9596, 0xfffe, 0x1120, 0x2009, 0x007e, 0x0804, 0x7cac,
-	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, 0x7c81, 0x82ff, 0x1118, 0x9085,
-	0x0001, 0x0018, 0xc2fc, 0x2208, 0x9006, 0x00de, 0x00ee, 0x004e,
-	0x00be, 0x0005, 0x7000, 0x908c, 0xff00, 0x810f, 0x9184, 0x000f,
-	0x0002, 0x7cc9, 0x7cc9, 0x7cc9, 0x7e67, 0x7cc9, 0x7cd2, 0x7cfd,
-	0x7d8b, 0x7cc9, 0x7cc9, 0x7cc9, 0x7cc9, 0x7cc9, 0x7cc9, 0x7cc9,
-	0x7cc9, 0x7817, 0x0140, 0x2001, 0x19c8, 0x2004, 0x9005, 0x090c,
-	0x898b, 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, 0x9ea9, 0x7817, 0x0140, 0x2001, 0x19c8, 0x2004,
-	0x9005, 0x090c, 0x898b, 0x00be, 0x0005, 0x00b6, 0x00c6, 0x9484,
-	0x0fff, 0x0904, 0x7d61, 0x7110, 0xd1bc, 0x1904, 0x7d61, 0x7108,
-	0x700c, 0x2028, 0x918c, 0x00ff, 0x2130, 0x9094, 0xff00, 0x15b0,
-	0x81ff, 0x15a0, 0x9080, 0x3145, 0x200d, 0x918c, 0xff00, 0x810f,
-	0x2001, 0x0080, 0x9106, 0x0904, 0x7d61, 0x080c, 0x61f6, 0x1904,
-	0x7d61, 0xbe12, 0xbd16, 0xb800, 0xd0ec, 0x15d8, 0xba04, 0x9294,
-	0xff00, 0x9286, 0x0600, 0x11a0, 0x080c, 0x9dd9, 0x05e8, 0x2b08,
-	0x7028, 0x604a, 0x702c, 0x6046, 0x6112, 0x6023, 0x0006, 0x7120,
-	0x610a, 0x7130, 0x6156, 0x2009, 0x0044, 0x080c, 0xcb44, 0x0408,
-	0x080c, 0x657a, 0x1138, 0xb807, 0x0606, 0x0c30, 0x190c, 0x7c4e,
-	0x11c0, 0x0898, 0x080c, 0x9dd9, 0x2b08, 0x0198, 0x6112, 0x6023,
-	0x0004, 0x7120, 0x610a, 0x9286, 0x0400, 0x1118, 0x6007, 0x0005,
-	0x0010, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x8440, 0x080c,
-	0x898b, 0x7817, 0x0140, 0x2001, 0x19c8, 0x2004, 0x9005, 0x090c,
-	0x898b, 0x00ce, 0x00be, 0x0005, 0x2001, 0x180e, 0x2004, 0xd0ec,
-	0x0120, 0x2011, 0x8049, 0x080c, 0x48f4, 0x080c, 0x9e7c, 0x0d48,
-	0x2b08, 0x6112, 0x6023, 0x0006, 0x7120, 0x610a, 0x7130, 0x6156,
-	0x6017, 0xf300, 0x6003, 0x0001, 0x6007, 0x0041, 0x080c, 0x83f8,
-	0x080c, 0x898b, 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, 0x9ea9, 0x7817, 0x0140, 0x2001, 0x19c8,
-	0x2004, 0x9005, 0x090c, 0x898b, 0x00be, 0x0005, 0x6120, 0x9186,
-	0x0002, 0x0128, 0x9186, 0x0005, 0x0110, 0x9085, 0x0001, 0x0005,
-	0x080c, 0x310a, 0x1168, 0x7010, 0x9084, 0xff00, 0x8007, 0x9086,
-	0x0000, 0x1130, 0x9184, 0x000f, 0x908a, 0x0006, 0x1208, 0x000b,
-	0x0005, 0x7dd7, 0x7dd8, 0x7dd7, 0x7dd7, 0x7e37, 0x7e46, 0x0005,
-	0x00b6, 0x7110, 0xd1bc, 0x0120, 0x702c, 0xd084, 0x0904, 0x7e35,
-	0x700c, 0x7108, 0x080c, 0x2670, 0x1904, 0x7e35, 0x080c, 0x61f6,
-	0x1904, 0x7e35, 0xbe12, 0xbd16, 0x7110, 0xd1bc, 0x01d8, 0x080c,
-	0x657a, 0x0118, 0x9086, 0x0004, 0x1588, 0x00c6, 0x080c, 0x7e55,
-	0x00ce, 0x05d8, 0x080c, 0x9dd9, 0x2b08, 0x05b8, 0x6112, 0x080c,
-	0xbfb5, 0x6023, 0x0002, 0x7120, 0x610a, 0x2009, 0x0088, 0x080c,
-	0x9ea9, 0x0458, 0x080c, 0x657a, 0x0148, 0x9086, 0x0004, 0x0130,
-	0x080c, 0x6582, 0x0118, 0x9086, 0x0004, 0x1180, 0x080c, 0x9dd9,
-	0x2b08, 0x01d8, 0x6112, 0x080c, 0xbfb5, 0x6023, 0x0005, 0x7120,
-	0x610a, 0x2009, 0x0088, 0x080c, 0x9ea9, 0x0078, 0x080c, 0x9dd9,
-	0x2b08, 0x0158, 0x6112, 0x080c, 0xbfb5, 0x6023, 0x0004, 0x7120,
-	0x610a, 0x2009, 0x0001, 0x080c, 0x9ea9, 0x00be, 0x0005, 0x7110,
-	0xd1bc, 0x0158, 0x00d1, 0x0148, 0x080c, 0x7db6, 0x1130, 0x7124,
-	0x610a, 0x2009, 0x0089, 0x080c, 0x9ea9, 0x0005, 0x7110, 0xd1bc,
-	0x0158, 0x0059, 0x0148, 0x080c, 0x7db6, 0x1130, 0x7124, 0x610a,
-	0x2009, 0x008a, 0x080c, 0x9ea9, 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, 0x9ea9, 0x7817, 0x0140,
-	0x2001, 0x19c8, 0x2004, 0x9005, 0x090c, 0x898b, 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, 0x9dd9, 0x05b8, 0x0066, 0x00c6, 0x0046, 0x2011,
-	0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x2670, 0x15a0, 0x080c,
-	0x61f6, 0x1588, 0xbe12, 0xbd16, 0x2b00, 0x004e, 0x00ce, 0x6012,
-	0x080c, 0xbfb5, 0x080c, 0x0feb, 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,
-	0x8440, 0x080c, 0x898b, 0x00fe, 0x009e, 0x00ce, 0x0005, 0x080c,
-	0x9e2f, 0x006e, 0x0cc0, 0x004e, 0x00ce, 0x0cc8, 0x00c6, 0x7000,
-	0x908c, 0xff00, 0x9184, 0xf000, 0x810f, 0x9086, 0x2000, 0x1904,
-	0x7f45, 0x9186, 0x0022, 0x15f0, 0x2001, 0x0111, 0x2004, 0x9005,
-	0x1904, 0x7f47, 0x7030, 0x908e, 0x0400, 0x0904, 0x7f47, 0x908e,
-	0x6000, 0x05e8, 0x908e, 0x5400, 0x05d0, 0x908e, 0x0300, 0x11d8,
-	0x2009, 0x1836, 0x210c, 0xd18c, 0x1590, 0xd1a4, 0x1580, 0x080c,
-	0x6538, 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, 0x7e55, 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, 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, 0x2071, 0x19d2, 0x7003, 0x0003, 0x700f, 0x0361,
-	0x9006, 0x701a, 0x7072, 0x7012, 0x7017, 0x1cd0, 0x7007, 0x0000,
-	0x7026, 0x702b, 0x93dd, 0x7032, 0x7037, 0x9445, 0x703f, 0xffff,
-	0x7042, 0x7047, 0x5239, 0x704a, 0x705b, 0x80da, 0x080c, 0x1004,
-	0x090c, 0x0db4, 0x2900, 0x703a, 0xa867, 0x0003, 0xa86f, 0x0100,
-	0xa8ab, 0xdcb0, 0x0005, 0x2071, 0x19d2, 0x1d04, 0x802e, 0x2091,
-	0x6000, 0x700c, 0x8001, 0x700e, 0x1510, 0x2001, 0x187d, 0x2004,
-	0xd0c4, 0x0158, 0x3a00, 0xd08c, 0x1140, 0x20d1, 0x0000, 0x20d1,
-	0x0001, 0x20d1, 0x0000, 0x080c, 0x0db4, 0x700f, 0x0361, 0x7007,
-	0x0001, 0x0126, 0x2091, 0x8000, 0x080c, 0x811f, 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, 0x954e, 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,
-	0x8056, 0x8057, 0x8073, 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, 0x6256, 0x1168, 0xb888, 0x8001, 0x0250, 0xb88a,
-	0x1140, 0x0126, 0x2091, 0x8000, 0x0016, 0x080c, 0x898b, 0x001e,
-	0x012e, 0x8108, 0x9182, 0x0800, 0x0218, 0x900e, 0x7007, 0x0002,
-	0x7112, 0x00be, 0x0005, 0x7014, 0x2060, 0x0126, 0x2091, 0x8000,
-	0x6040, 0x9005, 0x0128, 0x8001, 0x6042, 0x1110, 0x080c, 0xbe46,
-	0x6018, 0x9005, 0x0528, 0x8001, 0x601a, 0x1510, 0x6120, 0x9186,
-	0x0003, 0x0118, 0x9186, 0x0006, 0x11c8, 0x080c, 0xbb3b, 0x01b0,
-	0x6014, 0x2048, 0xa884, 0x908a, 0x199a, 0x0280, 0x9082, 0x1999,
-	0xa886, 0x908a, 0x199a, 0x0210, 0x2001, 0x1999, 0x8003, 0x800b,
-	0x810b, 0x9108, 0x611a, 0xa87c, 0xd0e4, 0x0110, 0x080c, 0xb827,
-	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, 0x10d5,
-	0x002e, 0x008e, 0x0005, 0x0006, 0x0016, 0x0096, 0x00a6, 0x00b6,
-	0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x0156, 0x080c, 0x7fa3, 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, 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, 0x0ecb, 0x002e, 0x0005,
-	0x00c6, 0x2061, 0x1a48, 0x00ce, 0x0005, 0x9184, 0x000f, 0x8003,
-	0x8003, 0x8003, 0x9080, 0x1a48, 0x2060, 0x0005, 0xa884, 0x908a,
-	0x199a, 0x1638, 0x9005, 0x1150, 0x00c6, 0x2061, 0x1a48, 0x6014,
-	0x00ce, 0x9005, 0x1130, 0x2001, 0x001e, 0x0018, 0x908e, 0xffff,
-	0x01b0, 0x8003, 0x800b, 0x810b, 0x9108, 0x611a, 0xa87c, 0x908c,
-	0x00c0, 0x918e, 0x00c0, 0x0904, 0x81e0, 0xd0b4, 0x1168, 0xd0bc,
-	0x1904, 0x81b9, 0x2009, 0x0006, 0x080c, 0x820d, 0x0005, 0x900e,
-	0x0c60, 0x2001, 0x1999, 0x08b0, 0xd0fc, 0x0160, 0x908c, 0x0003,
-	0x0120, 0x918e, 0x0003, 0x1904, 0x8207, 0x908c, 0x2020, 0x918e,
-	0x2020, 0x01a8, 0x6024, 0xd0d4, 0x11e8, 0x2009, 0x187d, 0x2104,
-	0xd084, 0x1138, 0x87ff, 0x1120, 0x2009, 0x0043, 0x0804, 0x9ea9,
-	0x0005, 0x87ff, 0x1de8, 0x2009, 0x0042, 0x0804, 0x9ea9, 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, 0x8207, 0x908c, 0x2020, 0x918e, 0x2020, 0x0170, 0x0076,
-	0x00f6, 0x2c78, 0x080c, 0x164a, 0x00fe, 0x007e, 0x87ff, 0x1120,
-	0x2009, 0x0042, 0x080c, 0x9ea9, 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, 0x9ea9, 0x0005, 0x00b9, 0x0ce8, 0x87ff, 0x1dd8, 0x2009,
-	0x0043, 0x080c, 0x9ea9, 0x0cb0, 0x6110, 0x00b6, 0x2158, 0xb900,
-	0x00be, 0xd1ac, 0x0d20, 0x6124, 0xc1cd, 0x6126, 0x0c00, 0x2009,
-	0x0004, 0x0019, 0x0005, 0x2009, 0x0001, 0x0096, 0x080c, 0xbb3b,
-	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, 0x66da, 0x6014, 0x904d, 0x0076, 0x2039,
-	0x0000, 0x190c, 0x8156, 0x007e, 0x009e, 0x0005, 0x0156, 0x00c6,
-	0x2061, 0x1a48, 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,
-	0x2019, 0x0100, 0x231c, 0x93a6, 0x0008, 0x1118, 0x8086, 0x818e,
-	0x0020, 0x80f6, 0x3e00, 0x81f6, 0x3e08, 0x1208, 0x9200, 0x1f04,
-	0x8258, 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, 0x8282, 0x0028, 0x911a, 0x2308, 0x8210, 0x1f04, 0x8282,
-	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, 0x0005, 0x0156, 0x0146, 0x01d6, 0x20e9, 0x0000, 0x2069,
-	0x0200, 0x080c, 0x9c37, 0x0401, 0x080c, 0x9c22, 0x00e9, 0x080c,
-	0x9c25, 0x00d1, 0x080c, 0x9c28, 0x00b9, 0x080c, 0x9c2b, 0x00a1,
-	0x080c, 0x9c2e, 0x0089, 0x080c, 0x9c31, 0x0071, 0x080c, 0x9c34,
-	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, 0x82f5, 0x8319, 0x8358, 0x82fb, 0x8319,
-	0x82f5, 0x82f3, 0x82f3, 0x080c, 0x0db4, 0x080c, 0x80bf, 0x080c,
-	0x898b, 0x00ce, 0x0005, 0x62c0, 0x82ff, 0x1110, 0x00ce, 0x0005,
-	0x2011, 0x5b4e, 0x080c, 0x803f, 0x7828, 0x9092, 0x00c8, 0x1228,
-	0x8000, 0x782a, 0x080c, 0x5b8e, 0x0c88, 0x62c0, 0x080c, 0x9c3b,
-	0x080c, 0x5b4e, 0x7807, 0x0003, 0x7827, 0x0000, 0x782b, 0x0000,
-	0x0c28, 0x080c, 0x80bf, 0x6220, 0xd2a4, 0x0160, 0x782b, 0x0000,
-	0x7824, 0x9065, 0x090c, 0x0db4, 0x2009, 0x0013, 0x080c, 0x9ea9,
-	0x00ce, 0x0005, 0x00c6, 0x7824, 0x9065, 0x090c, 0x0db4, 0x7828,
-	0x9092, 0xc350, 0x12c0, 0x8000, 0x782a, 0x00ce, 0x080c, 0x29d7,
-	0x0278, 0x00c6, 0x7924, 0x2160, 0x6010, 0x906d, 0x090c, 0x0db4,
-	0x7807, 0x0000, 0x7827, 0x0000, 0x00ce, 0x080c, 0x898b, 0x0c00,
-	0x080c, 0x93a3, 0x08e8, 0x2011, 0x0130, 0x2214, 0x080c, 0x9c3b,
-	0x080c, 0xd903, 0x2009, 0x0014, 0x080c, 0x9ea9, 0x00ce, 0x0880,
-	0x2001, 0x19db, 0x2003, 0x0000, 0x62c0, 0x82ff, 0x1160, 0x782b,
-	0x0000, 0x7824, 0x9065, 0x090c, 0x0db4, 0x2009, 0x0013, 0x080c,
-	0x9efb, 0x00ce, 0x0005, 0x00b6, 0x00c6, 0x00d6, 0x7824, 0x9005,
-	0x090c, 0x0db4, 0x7828, 0x9092, 0xc350, 0x1648, 0x8000, 0x782a,
-	0x00de, 0x00ce, 0x00be, 0x080c, 0x29d7, 0x02f0, 0x00b6, 0x00c6,
-	0x00d6, 0x781c, 0x905d, 0x090c, 0x0db4, 0xb800, 0xc0dc, 0xb802,
-	0x7924, 0x2160, 0x080c, 0x9e2f, 0xb93c, 0x81ff, 0x090c, 0x0db4,
-	0x8109, 0xb93e, 0x7807, 0x0000, 0x7827, 0x0000, 0x00de, 0x00ce,
-	0x00be, 0x080c, 0x898b, 0x0868, 0x080c, 0x93a3, 0x0850, 0x2011,
-	0x0130, 0x2214, 0x080c, 0x9c3b, 0x080c, 0xd903, 0x7824, 0x9065,
-	0x2009, 0x0014, 0x080c, 0x9ea9, 0x00de, 0x00ce, 0x00be, 0x0804,
-	0x8369, 0x00c6, 0x2001, 0x009b, 0x2004, 0xd0fc, 0x190c, 0x1d57,
-	0x6024, 0x6027, 0x0002, 0xd0f4, 0x1580, 0x62c8, 0x60c4, 0x9205,
-	0x1170, 0x783c, 0x9065, 0x0130, 0x2009, 0x0049, 0x080c, 0x9ea9,
-	0x00ce, 0x0005, 0x2011, 0x19de, 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, 0x9ea9, 0x08a0, 0x7848, 0xc085, 0x784a, 0x0880,
-	0x0006, 0x0016, 0x00c6, 0x0126, 0x2091, 0x8000, 0x600f, 0x0000,
-	0x2c08, 0x2061, 0x19bf, 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, 0x898b, 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, 0x08d8,
-	0x0006, 0x0016, 0x00c6, 0x0126, 0x2091, 0x8000, 0x600f, 0x0000,
-	0x2c08, 0x2061, 0x19bf, 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, 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,
-	0x84ec, 0x6010, 0x2058, 0xb8a0, 0x9206, 0x1904, 0x84e7, 0x87ff,
-	0x0120, 0x6054, 0x9106, 0x1904, 0x84e7, 0x703c, 0x9c06, 0x1178,
-	0x0036, 0x2019, 0x0001, 0x080c, 0x96e9, 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, 0xbb3b, 0x01f0, 0x6014, 0x2048, 0x6020, 0x9086,
-	0x0003, 0x15b8, 0x6004, 0x9086, 0x0040, 0x090c, 0x98c4, 0xa867,
-	0x0103, 0xab7a, 0xa877, 0x0000, 0x0016, 0x0036, 0x0076, 0x080c,
-	0xbe2f, 0x080c, 0xd80d, 0x080c, 0x68a0, 0x007e, 0x003e, 0x001e,
-	0x080c, 0xbd24, 0x080c, 0x9e5f, 0x00ce, 0x0804, 0x8486, 0x2c78,
-	0x600c, 0x2060, 0x0804, 0x8486, 0x85ff, 0x0120, 0x0036, 0x080c,
-	0x8a68, 0x003e, 0x012e, 0x000e, 0x001e, 0x002e, 0x003e, 0x005e,
-	0x006e, 0x007e, 0x009e, 0x00be, 0x00ce, 0x00de, 0x00ee, 0x00fe,
-	0x0005, 0x6020, 0x9086, 0x0006, 0x1158, 0x0016, 0x0036, 0x0076,
-	0x080c, 0xd80d, 0x080c, 0xd50f, 0x007e, 0x003e, 0x001e, 0x0890,
-	0x6020, 0x9086, 0x000a, 0x0904, 0x84d1, 0x0804, 0x84ca, 0x0006,
-	0x0066, 0x0096, 0x00c6, 0x00d6, 0x00f6, 0x9036, 0x0126, 0x2091,
-	0x8000, 0x2079, 0x19bf, 0x7838, 0x9065, 0x0904, 0x856c, 0x600c,
-	0x0006, 0x600f, 0x0000, 0x783c, 0x9c06, 0x1168, 0x0036, 0x2019,
-	0x0001, 0x080c, 0x96e9, 0x7833, 0x0000, 0x901e, 0x7b3e, 0x7b42,
-	0x7b46, 0x7b4a, 0x003e, 0x080c, 0xbb3b, 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, 0x98c4, 0xa867, 0x0103,
-	0xab7a, 0xa877, 0x0000, 0x080c, 0x6893, 0x080c, 0xbd24, 0x080c,
-	0x9e5f, 0x000e, 0x0804, 0x8524, 0x7e3a, 0x7e36, 0x012e, 0x00fe,
-	0x00de, 0x00ce, 0x009e, 0x006e, 0x000e, 0x0005, 0x6020, 0x9086,
-	0x0006, 0x1118, 0x080c, 0xd50f, 0x0c50, 0x6020, 0x9086, 0x000a,
-	0x09f8, 0x08b8, 0x0016, 0x0026, 0x0086, 0x9046, 0x0099, 0x080c,
-	0x866b, 0x008e, 0x002e, 0x001e, 0x0005, 0x00f6, 0x0126, 0x2079,
-	0x19bf, 0x2091, 0x8000, 0x080c, 0x8702, 0x080c, 0x8790, 0x012e,
-	0x00fe, 0x0005, 0x00b6, 0x0096, 0x00f6, 0x00e6, 0x00d6, 0x00c6,
-	0x0066, 0x0016, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19bf,
-	0x7614, 0x2660, 0x2678, 0x8cff, 0x0904, 0x8630, 0x6010, 0x2058,
-	0xb8a0, 0x9206, 0x1904, 0x862b, 0x88ff, 0x0120, 0x6054, 0x9106,
-	0x1904, 0x862b, 0x7024, 0x9c06, 0x1558, 0x2069, 0x0100, 0x6820,
-	0xd0a4, 0x1508, 0x080c, 0x80bf, 0x080c, 0x93c7, 0x68c3, 0x0000,
-	0x080c, 0x98c4, 0x7027, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04,
-	0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2b21, 0x9006,
-	0x080c, 0x2b21, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827,
-	0x0001, 0x003e, 0x0028, 0x6003, 0x0009, 0x630a, 0x0804, 0x862b,
+	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,
+	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, 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,
+	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,
+	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,
+	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,
+	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,
+	0x0d18, 0x9186, 0x0045, 0x0510, 0x9186, 0x002a, 0x1130, 0x2001,
+	0x180c, 0x200c, 0xc194, 0x2102, 0x08b8, 0x9186, 0x0020, 0x0158,
+	0x9186, 0x0029, 0x1d10, 0xa974, 0x080c, 0x649f, 0x1968, 0xb800,
+	0xc0e4, 0xb802, 0x0848, 0xa88c, 0x9065, 0x09b8, 0x6007, 0x0024,
+	0x2001, 0x195e, 0x2004, 0x601a, 0x0804, 0x797c, 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,
+	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,
+	0x8007, 0x9084, 0x00ff, 0x0130, 0x8001, 0x1138, 0x7007, 0x0001,
+	0x0069, 0x0005, 0x080c, 0x7662, 0x0040, 0x7007, 0x0003, 0x7012,
+	0x2900, 0x7016, 0x701a, 0x704b, 0x7a1e, 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,
+	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,
+	0x012e, 0x00ee, 0x00be, 0x0005, 0x2048, 0xa800, 0x9005, 0x1de0,
+	0xa902, 0x2148, 0xa87c, 0xd0f4, 0x1904, 0x7ad0, 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,
+	0x1118, 0xa883, 0x0002, 0x0490, 0xa883, 0x0008, 0x0478, 0xa883,
+	0x000e, 0x0460, 0xa883, 0x0017, 0x0448, 0xa883, 0x0035, 0x0430,
+	0x080c, 0x55df, 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,
+	0x00be, 0x0420, 0xa883, 0x002a, 0x0cc8, 0xa883, 0x0045, 0x0cb0,
+	0x2e60, 0x2019, 0x0002, 0x601b, 0x0014, 0x080c, 0xd440, 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,
+	0x2091, 0x8000, 0x2071, 0x0040, 0x702c, 0xd084, 0x01d8, 0x908c,
+	0x0780, 0x190c, 0x7b89, 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,
+	0x0026, 0x0016, 0x00b6, 0x7007, 0x0001, 0xaa74, 0x9282, 0x0004,
+	0x1a04, 0x7b7a, 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,
+	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,
+	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,
+	0x00f6, 0x1510, 0x9484, 0x7000, 0x0140, 0x908a, 0x2000, 0x1260,
+	0x9584, 0x0700, 0x8007, 0x0804, 0x7c12, 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,
+	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,
+	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,
+	0x2004, 0xd08c, 0x0178, 0x2001, 0x1800, 0x2004, 0x9086, 0x0003,
+	0x1148, 0x0026, 0x0036, 0x2011, 0x8048, 0x2518, 0x080c, 0x4b1f,
+	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,
+	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,
+	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,
+	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,
+	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,
+	0x1528, 0x2029, 0x0205, 0x2011, 0x026d, 0x8208, 0x2204, 0x9082,
+	0x0004, 0x8004, 0x8004, 0x20a8, 0x2011, 0x8015, 0x211c, 0x8108,
+	0x0046, 0x2124, 0x080c, 0x4b1f, 0x004e, 0x8108, 0x0f04, 0x7da9,
+	0x9186, 0x0280, 0x1d88, 0x2504, 0x8000, 0x202a, 0x2009, 0x0260,
+	0x0c58, 0x202b, 0x0000, 0x2009, 0x0023, 0x0478, 0x908e, 0x6000,
+	0x1118, 0x2009, 0x003f, 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, 0x276e, 0x1904, 0x7e30, 0x080c,
+	0x643f, 0x1904, 0x7e30, 0xbe12, 0xbd16, 0x001e, 0x0016, 0x080c,
+	0x7207, 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,
+	0x0004, 0x7120, 0x610a, 0x001e, 0x9186, 0x004c, 0x1110, 0x6023,
+	0x000a, 0x0016, 0x001e, 0x080c, 0xa15d, 0x00ce, 0x00be, 0x0005,
+	0x001e, 0x0cd8, 0x2001, 0x180e, 0x2004, 0xd0ec, 0x0120, 0x2011,
+	0x8049, 0x080c, 0x4b1f, 0x080c, 0xa130, 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,
+	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,
+	0x0100, 0x1590, 0x7034, 0x9005, 0x1578, 0x2009, 0x0016, 0x080c,
+	0xa15d, 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,
+	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,
+	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,
+	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,
+	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,
+	0x15d8, 0xba04, 0x9294, 0xff00, 0x9286, 0x0600, 0x11a0, 0x080c,
+	0xa08d, 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,
+	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,
+	0x610a, 0x7130, 0x6156, 0x6017, 0xf300, 0x6003, 0x0001, 0x6007,
+	0x0041, 0x080c, 0x8679, 0x080c, 0x8c10, 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,
+	0x0005, 0x6120, 0x9186, 0x0002, 0x0128, 0x9186, 0x0005, 0x0110,
+	0x9085, 0x0001, 0x0005, 0x080c, 0x8206, 0x1180, 0x080c, 0x32ae,
+	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,
+	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,
+	0x2031, 0x0206, 0x0049, 0x0005, 0x2031, 0x0207, 0x0029, 0x0005,
+	0x2031, 0x0213, 0x0009, 0x0005, 0x00c6, 0x0096, 0x00f6, 0x7000,
+	0x9084, 0xf000, 0x9086, 0xc000, 0x05d0, 0x080c, 0xa08d, 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,
+	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,
+	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,
+	0x05d0, 0x908e, 0x0300, 0x11d8, 0x2009, 0x1836, 0x210c, 0xd18c,
+	0x1590, 0xd1a4, 0x1580, 0x080c, 0x6781, 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,
+	0x0000, 0x9006, 0x0010, 0x9085, 0x0001, 0x00ce, 0x0005, 0x7030,
+	0x908e, 0x0300, 0x0118, 0x908e, 0x5200, 0x1d98, 0x2001, 0x1836,
+	0x2004, 0x9084, 0x0009, 0x9086, 0x0008, 0x0d68, 0x0c50, 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,
+	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,
+	0x2001, 0x187d, 0x2004, 0xd0c4, 0x0158, 0x3a00, 0xd08c, 0x1140,
+	0x20d1, 0x0000, 0x20d1, 0x0001, 0x20d1, 0x0000, 0x080c, 0x0dfa,
+	0x700f, 0x0361, 0x7007, 0x0001, 0x0126, 0x2091, 0x8000, 0x080c,
+	0x83ba, 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,
+	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,
+	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,
+	0x8001, 0x0250, 0xb88a, 0x1140, 0x0126, 0x2091, 0x8000, 0x0016,
+	0x080c, 0x8c10, 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,
+	0x1510, 0x6120, 0x9186, 0x0003, 0x0118, 0x9186, 0x0006, 0x11c8,
+	0x080c, 0xbe37, 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,
+	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,
+	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,
+	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,
+	0x0005, 0xa884, 0x908a, 0x199a, 0x1638, 0x9005, 0x1150, 0x00c6,
+	0x2061, 0x1a48, 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,
+	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,
+	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,
+	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,
+	0x00b6, 0x2158, 0xb900, 0x00be, 0xd1ac, 0x0d20, 0x6124, 0xc1cd,
+	0x6126, 0x0c00, 0x2009, 0x0004, 0x0019, 0x0005, 0x2009, 0x0001,
+	0x0096, 0x080c, 0xbe37, 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,
+	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,
+	0x2091, 0x8000, 0x0076, 0x0156, 0x20a9, 0x0010, 0x9005, 0x01c8,
+	0x911a, 0x12b8, 0x8213, 0x818d, 0x0228, 0x911a, 0x1220, 0x1f04,
+	0x850a, 0x0028, 0x911a, 0x2308, 0x8210, 0x1f04, 0x850a, 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,
+	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,
+	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,
+	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,
+	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,
+	0x9205, 0x1170, 0x783c, 0x9065, 0x0130, 0x2009, 0x0049, 0x080c,
+	0xa15d, 0x00ce, 0x0005, 0x2011, 0x19de, 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,
+	0x0880, 0x0006, 0x0016, 0x00c6, 0x0126, 0x2091, 0x8000, 0x600f,
+	0x0000, 0x2c08, 0x2061, 0x19bf, 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,
+	0x0005, 0xc0d5, 0xb802, 0x6818, 0x9005, 0x0168, 0xb856, 0xb85b,
+	0x0000, 0x0086, 0x0006, 0x2b00, 0x681a, 0x008e, 0xa05a, 0x008e,
+	0x2069, 0x19bf, 0x0c08, 0xb856, 0xb85a, 0x2b00, 0x681a, 0x681e,
+	0x08d8, 0x0006, 0x0016, 0x00c6, 0x0126, 0x2091, 0x8000, 0x600f,
+	0x0000, 0x2c08, 0x2061, 0x19bf, 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,
+	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,
+	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,
+	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,
+	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,
+	0x0006, 0x0066, 0x0096, 0x00c6, 0x00d6, 0x00f6, 0x9036, 0x0126,
+	0x2091, 0x8000, 0x2079, 0x19bf, 0x7838, 0x9065, 0x0904, 0x87ed,
+	0x600c, 0x0006, 0x600f, 0x0000, 0x783c, 0x9c06, 0x1168, 0x0036,
+	0x2019, 0x0001, 0x080c, 0x999d, 0x7833, 0x0000, 0x901e, 0x7b3e,
+	0x7b42, 0x7b46, 0x7b4a, 0x003e, 0x080c, 0xbe37, 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,
+	0x00fe, 0x00de, 0x00ce, 0x009e, 0x006e, 0x000e, 0x0005, 0x6020,
+	0x9086, 0x0006, 0x1118, 0x080c, 0xd830, 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,
+	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,
+	0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100,
+	0x080c, 0x2c88, 0x9006, 0x080c, 0x2c88, 0x2069, 0x0100, 0x6824,
+	0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x0028, 0x6003, 0x0009,
+	0x630a, 0x0804, 0x88ae, 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,
+	0x00de, 0x00ee, 0x00fe, 0x009e, 0x00be, 0x0005, 0x6020, 0x9086,
+	0x0006, 0x1158, 0x0016, 0x0036, 0x0086, 0x080c, 0xdb2e, 0x080c,
+	0xd830, 0x008e, 0x003e, 0x001e, 0x08d0, 0x080c, 0xaa81, 0x6020,
+	0x9086, 0x0002, 0x1160, 0x6004, 0x0006, 0x9086, 0x0085, 0x000e,
+	0x0904, 0x8894, 0x9086, 0x008b, 0x0904, 0x8894, 0x0840, 0x6020,
+	0x9086, 0x0005, 0x1920, 0x6004, 0x0006, 0x9086, 0x0085, 0x000e,
+	0x09c8, 0x9086, 0x008b, 0x09b0, 0x0804, 0x88a7, 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,
+	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,
+	0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c,
+	0x2c88, 0x9006, 0x080c, 0x2c88, 0x2069, 0x0100, 0x6824, 0xd084,
+	0x0110, 0x6827, 0x0001, 0x003e, 0x00de, 0x00c6, 0xb83c, 0x9005,
+	0x0110, 0x8001, 0xb83e, 0x2660, 0x080c, 0xa113, 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,
+	0x00ce, 0x009e, 0x00ae, 0x00be, 0x0005, 0x0096, 0x0006, 0x0066,
+	0x00c6, 0x00d6, 0x9036, 0x7814, 0x9065, 0x0904, 0x89e8, 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,
+	0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100,
+	0x080c, 0x2c88, 0x9006, 0x080c, 0x2c88, 0x2069, 0x0100, 0x6824,
+	0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x0040, 0x080c, 0x6779,
+	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,
+	0x7e16, 0x7e12, 0x00de, 0x00ce, 0x006e, 0x000e, 0x009e, 0x0005,
+	0x6020, 0x9086, 0x0006, 0x1118, 0x080c, 0xd830, 0x0c50, 0x080c,
+	0xaa81, 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,
+	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,
+	0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100,
+	0x080c, 0x2c88, 0x9006, 0x080c, 0x2c88, 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,
+	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,
+	0x00ce, 0x00be, 0x009e, 0x006e, 0x000e, 0x0005, 0x00e6, 0x00d6,
+	0x0096, 0x0066, 0xb800, 0xd0dc, 0x01a0, 0xb84c, 0x904d, 0x0188,
+	0xa878, 0x9606, 0x1170, 0x2071, 0x19bf, 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,
+	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,
+	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,
+	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,
+	0x600f, 0x0000, 0x0448, 0x720e, 0x720a, 0x0430, 0x7014, 0x9c06,
+	0x1160, 0x080c, 0x9a4e, 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,
+	0x721e, 0x0010, 0x7218, 0x721e, 0x7027, 0x0000, 0x00ce, 0x00ee,
+	0x00be, 0x0005, 0x7024, 0x9065, 0x0140, 0x080c, 0x9a4e, 0x600c,
+	0x9015, 0x0158, 0x720e, 0x600f, 0x0000, 0x080c, 0x9b78, 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,
+	0x6840, 0x9086, 0x0001, 0x01b8, 0x683c, 0x9065, 0x0130, 0x600c,
+	0x9015, 0x0170, 0x6a3a, 0x600f, 0x0000, 0x6833, 0x0000, 0x683f,
+	0x0000, 0x2011, 0x19de, 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,
+	0x6820, 0x9005, 0x1110, 0x00de, 0x0005, 0x00c6, 0x680c, 0x9065,
+	0x0150, 0x6807, 0x0004, 0x6826, 0x682b, 0x0000, 0x080c, 0x8d44,
+	0x00ce, 0x00de, 0x0005, 0x6814, 0x9065, 0x0150, 0x6807, 0x0001,
+	0x6826, 0x682b, 0x0000, 0x080c, 0x8d44, 0x00ce, 0x00de, 0x0005,
+	0x00b6, 0x00e6, 0x6a1c, 0x92dd, 0x0000, 0x0904, 0x8cbf, 0xb84c,
+	0x900d, 0x0118, 0xb888, 0x9005, 0x01a0, 0xb854, 0x905d, 0x0120,
+	0x920e, 0x0904, 0x8cbf, 0x0028, 0x6818, 0x920e, 0x0904, 0x8cbf,
+	0x2058, 0xb84c, 0x900d, 0x0d88, 0xb888, 0x9005, 0x1d70, 0x2b00,
+	0x681e, 0xbb3c, 0xb838, 0x9302, 0x1e40, 0x080c, 0xa0ba, 0x0904,
+	0x8cbf, 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,
+	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,
+	0x00ee, 0x00be, 0x00ce, 0x00de, 0x0005, 0x00de, 0x0005, 0x00c6,
+	0x680c, 0x9065, 0x0138, 0x6807, 0x0004, 0x6826, 0x682b, 0x0000,
+	0x080c, 0x8d44, 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,
+	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,
+	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,
+	0x0146, 0x01c6, 0x01d6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2069,
+	0x0200, 0x2071, 0x0240, 0x6004, 0x908a, 0x0053, 0x1a0c, 0x0dfa,
+	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,
+	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,
+	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,
-	0x600f, 0x0000, 0x6014, 0x2048, 0x080c, 0xbb3b, 0x01e8, 0x6020,
-	0x9086, 0x0003, 0x1580, 0x080c, 0xbd41, 0x1118, 0x080c, 0xa7cd,
-	0x0098, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x0016, 0x0036,
-	0x0086, 0x080c, 0xbe2f, 0x080c, 0xd80d, 0x080c, 0x68a0, 0x008e,
-	0x003e, 0x001e, 0x080c, 0xbd24, 0x080c, 0x9e5f, 0x080c, 0x979a,
-	0x00ce, 0x0804, 0x85ab, 0x2c78, 0x600c, 0x2060, 0x0804, 0x85ab,
-	0x012e, 0x000e, 0x001e, 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe,
-	0x009e, 0x00be, 0x0005, 0x6020, 0x9086, 0x0006, 0x1158, 0x0016,
-	0x0036, 0x0086, 0x080c, 0xd80d, 0x080c, 0xd50f, 0x008e, 0x003e,
-	0x001e, 0x08d0, 0x080c, 0xa7cd, 0x6020, 0x9086, 0x0002, 0x1160,
-	0x6004, 0x0006, 0x9086, 0x0085, 0x000e, 0x0904, 0x8611, 0x9086,
-	0x008b, 0x0904, 0x8611, 0x0840, 0x6020, 0x9086, 0x0005, 0x1920,
-	0x6004, 0x0006, 0x9086, 0x0085, 0x000e, 0x09c8, 0x9086, 0x008b,
-	0x09b0, 0x0804, 0x8624, 0x00b6, 0x00a6, 0x0096, 0x00c6, 0x0006,
-	0x0126, 0x2091, 0x8000, 0x9280, 0x1000, 0x2004, 0x905d, 0x0904,
-	0x86fb, 0x00f6, 0x00e6, 0x00d6, 0x0066, 0x2071, 0x19bf, 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, 0x6189,
-	0x0904, 0x86f7, 0x7624, 0x86ff, 0x0904, 0x86e6, 0x9680, 0x0005,
-	0x2004, 0x9906, 0x15d8, 0x00d6, 0x2069, 0x0100, 0x68c0, 0x9005,
-	0x0560, 0x080c, 0x80bf, 0x080c, 0x93c7, 0x68c3, 0x0000, 0x080c,
-	0x98c4, 0x7027, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384,
-	0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2b21, 0x9006, 0x080c,
-	0x2b21, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001,
-	0x003e, 0x00de, 0x00c6, 0xb83c, 0x9005, 0x0110, 0x8001, 0xb83e,
-	0x2660, 0x080c, 0x9e5f, 0x00ce, 0x0048, 0x00de, 0x00c6, 0x2660,
-	0x6003, 0x0009, 0x630a, 0x00ce, 0x0804, 0x869e, 0x89ff, 0x0158,
-	0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0xbe2f, 0x080c,
-	0xd80d, 0x080c, 0x68a0, 0x080c, 0x979a, 0x0804, 0x869e, 0x006e,
-	0x00de, 0x00ee, 0x00fe, 0x012e, 0x000e, 0x00ce, 0x009e, 0x00ae,
-	0x00be, 0x0005, 0x0096, 0x0006, 0x0066, 0x00c6, 0x00d6, 0x9036,
-	0x7814, 0x9065, 0x0904, 0x8763, 0x600c, 0x0006, 0x600f, 0x0000,
-	0x7824, 0x9c06, 0x1570, 0x2069, 0x0100, 0x6820, 0xd0a4, 0x1508,
-	0x080c, 0x80bf, 0x080c, 0x93c7, 0x68c3, 0x0000, 0x080c, 0x98c4,
-	0x7827, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000,
-	0x0138, 0x2001, 0x0100, 0x080c, 0x2b21, 0x9006, 0x080c, 0x2b21,
-	0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e,
-	0x0040, 0x080c, 0x6530, 0x1520, 0x6003, 0x0009, 0x630a, 0x2c30,
-	0x00f8, 0x6014, 0x2048, 0x080c, 0xbb39, 0x01b0, 0x6020, 0x9086,
-	0x0003, 0x1508, 0x080c, 0xbd41, 0x1118, 0x080c, 0xa7cd, 0x0060,
-	0x080c, 0x6530, 0x1168, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000,
-	0x080c, 0x68a0, 0x080c, 0xbd24, 0x080c, 0x9e5f, 0x080c, 0x979a,
-	0x000e, 0x0804, 0x8709, 0x7e16, 0x7e12, 0x00de, 0x00ce, 0x006e,
-	0x000e, 0x009e, 0x0005, 0x6020, 0x9086, 0x0006, 0x1118, 0x080c,
-	0xd50f, 0x0c50, 0x080c, 0xa7cd, 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, 0x8810, 0xb854, 0x0006, 0x9006, 0xb856, 0xb85a, 0xb800,
-	0xc0d4, 0xc0dc, 0xb802, 0x080c, 0x6189, 0x0904, 0x880d, 0x7e24,
-	0x86ff, 0x0904, 0x8800, 0x9680, 0x0005, 0x2004, 0x9906, 0x1904,
-	0x8800, 0x00d6, 0x2069, 0x0100, 0x68c0, 0x9005, 0x0904, 0x87f7,
-	0x080c, 0x80bf, 0x080c, 0x93c7, 0x68c3, 0x0000, 0x080c, 0x98c4,
-	0x7827, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000,
-	0x0138, 0x2001, 0x0100, 0x080c, 0x2b21, 0x9006, 0x080c, 0x2b21,
-	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, 0xb83c, 0x9005, 0x0110, 0x8001, 0xb83e,
-	0x2660, 0x600f, 0x0000, 0x080c, 0x9e5f, 0x00ce, 0x0048, 0x00de,
-	0x00c6, 0x2660, 0x6003, 0x0009, 0x630a, 0x00ce, 0x0804, 0x87a3,
-	0x89ff, 0x0138, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c,
-	0x68a0, 0x080c, 0x979a, 0x0804, 0x87a3, 0x000e, 0x0804, 0x8797,
-	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, 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, 0x93c7,
-	0x78c3, 0x0000, 0x080c, 0x98c4, 0x7027, 0x0000, 0x0036, 0x2079,
-	0x0140, 0x7b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c,
-	0x2b21, 0x9006, 0x080c, 0x2b21, 0x2079, 0x0100, 0x7824, 0xd084,
-	0x0110, 0x7827, 0x0001, 0x080c, 0x98c4, 0x003e, 0x080c, 0x6189,
-	0x00c6, 0xb83c, 0x9005, 0x0110, 0x8001, 0xb83e, 0x2660, 0x080c,
-	0x9e2f, 0x00ce, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c,
-	0xbe2f, 0x080c, 0x68a0, 0x080c, 0x979a, 0x00fe, 0x0005, 0x00b6,
-	0x00e6, 0x00c6, 0x2011, 0x0101, 0x2204, 0xc0c4, 0x2012, 0x2001,
-	0x180c, 0x2014, 0xc2e4, 0x2202, 0x2071, 0x19bf, 0x7004, 0x9084,
-	0x0007, 0x0002, 0x889c, 0x88a0, 0x88be, 0x88e7, 0x8925, 0x889c,
-	0x88b7, 0x889a, 0x080c, 0x0db4, 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, 0x6189, 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, 0x898b, 0x0ca8, 0x7218, 0x721e, 0x080c,
-	0x898b, 0x0c80, 0xc2ec, 0x2202, 0x080c, 0x8a68, 0x0c58, 0x7024,
-	0x9065, 0x05b8, 0x700c, 0x9c06, 0x1160, 0x080c, 0x979a, 0x600c,
-	0x9015, 0x0120, 0x720e, 0x600f, 0x0000, 0x0448, 0x720e, 0x720a,
-	0x0430, 0x7014, 0x9c06, 0x1160, 0x080c, 0x979a, 0x600c, 0x9015,
-	0x0120, 0x7216, 0x600f, 0x0000, 0x00d0, 0x7216, 0x7212, 0x00b8,
-	0x6020, 0x9086, 0x0003, 0x1198, 0x6010, 0x2058, 0x080c, 0x6189,
-	0xb800, 0xc0dc, 0xb802, 0x080c, 0x979a, 0x701c, 0x9065, 0x0138,
-	0xb854, 0x9015, 0x0110, 0x721e, 0x0010, 0x7218, 0x721e, 0x7027,
-	0x0000, 0x00ce, 0x00ee, 0x00be, 0x0005, 0x7024, 0x9065, 0x0140,
-	0x080c, 0x979a, 0x600c, 0x9015, 0x0158, 0x720e, 0x600f, 0x0000,
-	0x080c, 0x98c4, 0x7027, 0x0000, 0x00ce, 0x00ee, 0x00be, 0x0005,
-	0x720e, 0x720a, 0x0ca8, 0x00d6, 0x2069, 0x19bf, 0x6830, 0x9084,
-	0x0003, 0x0002, 0x8948, 0x894a, 0x896e, 0x8946, 0x080c, 0x0db4,
-	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, 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, 0x8a68, 0x2001, 0x19cb, 0x2004, 0x9086,
-	0x0001, 0x0d58, 0x00d6, 0x2069, 0x19bf, 0x6804, 0x9084, 0x0007,
-	0x0002, 0x89ab, 0x8a50, 0x8a50, 0x8a50, 0x8a50, 0x8a52, 0x8a50,
-	0x89a9, 0x080c, 0x0db4, 0x6820, 0x9005, 0x1110, 0x00de, 0x0005,
-	0x00c6, 0x680c, 0x9065, 0x0150, 0x6807, 0x0004, 0x6826, 0x682b,
-	0x0000, 0x080c, 0x8abf, 0x00ce, 0x00de, 0x0005, 0x6814, 0x9065,
-	0x0150, 0x6807, 0x0001, 0x6826, 0x682b, 0x0000, 0x080c, 0x8abf,
-	0x00ce, 0x00de, 0x0005, 0x00b6, 0x00e6, 0x6a1c, 0x92dd, 0x0000,
-	0x0904, 0x8a3a, 0xb84c, 0x900d, 0x0118, 0xb888, 0x9005, 0x01a0,
-	0xb854, 0x905d, 0x0120, 0x920e, 0x0904, 0x8a3a, 0x0028, 0x6818,
-	0x920e, 0x0904, 0x8a3a, 0x2058, 0xb84c, 0x900d, 0x0d88, 0xb888,
-	0x9005, 0x1d70, 0x2b00, 0x681e, 0xbb3c, 0xb838, 0x9302, 0x1e40,
-	0x080c, 0x9e06, 0x0904, 0x8a3a, 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, 0x8ff7, 0x2069, 0x19bf, 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,
-	0x6189, 0x080c, 0x9c5b, 0x00ee, 0x00be, 0x00ce, 0x00de, 0x0005,
-	0x00de, 0x0005, 0x00c6, 0x680c, 0x9065, 0x0138, 0x6807, 0x0004,
-	0x6826, 0x682b, 0x0000, 0x080c, 0x8abf, 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,
-	0x899a, 0x2069, 0x19bf, 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, 0x1af5, 0x1158, 0x012e, 0x080c,
-	0x9224, 0x00de, 0x00fe, 0x0005, 0xc1c4, 0x2102, 0x080c, 0x705a,
-	0x08f8, 0x012e, 0x6843, 0x0000, 0x7803, 0x0002, 0x780c, 0x9015,
-	0x0140, 0x6a3a, 0x780f, 0x0000, 0x6833, 0x0000, 0x683f, 0x0000,
-	0x0c40, 0x683a, 0x6836, 0x0cc0, 0x6a04, 0x9296, 0x0006, 0x1904,
-	0x8a60, 0x6a30, 0x9296, 0x0000, 0x0950, 0x0804, 0x8a60, 0x6020,
-	0x9084, 0x000f, 0x000b, 0x0005, 0x8ad3, 0x8ad8, 0x8f31, 0x8fc0,
-	0x8ad8, 0x8f31, 0x8fc0, 0x8ad3, 0x8ad8, 0x8ad3, 0x8ad3, 0x8ad3,
-	0x8ad3, 0x8ad3, 0x8ad3, 0x080c, 0x887f, 0x080c, 0x898b, 0x0005,
-	0x00b6, 0x0156, 0x0136, 0x0146, 0x01c6, 0x01d6, 0x00c6, 0x00d6,
-	0x00e6, 0x00f6, 0x2069, 0x0200, 0x2071, 0x0240, 0x6004, 0x908a,
-	0x0053, 0x1a0c, 0x0db4, 0x6110, 0x2158, 0xb9b0, 0x2c78, 0x2061,
-	0x0100, 0x619a, 0x908a, 0x0040, 0x1a04, 0x8b44, 0x005b, 0x00fe,
-	0x00ee, 0x00de, 0x00ce, 0x01de, 0x01ce, 0x014e, 0x013e, 0x015e,
-	0x00be, 0x0005, 0x8cbb, 0x8cf6, 0x8d1f, 0x8dc2, 0x8de3, 0x8de9,
-	0x8df6, 0x8dfe, 0x8e0a, 0x8e10, 0x8e21, 0x8e10, 0x8e78, 0x8dfe,
-	0x8e84, 0x8e8a, 0x8e0a, 0x8e8a, 0x8e96, 0x8b42, 0x8b42, 0x8b42,
-	0x8b42, 0x8b42, 0x8b42, 0x8b42, 0x8b42, 0x8b42, 0x8b42, 0x8b42,
-	0x95a0, 0x95c3, 0x95d4, 0x95f4, 0x9626, 0x8df6, 0x8b42, 0x8df6,
-	0x8e10, 0x8b42, 0x8d1f, 0x8dc2, 0x8b42, 0x99bb, 0x8e10, 0x8b42,
-	0x99d7, 0x8e10, 0x8b42, 0x8e0a, 0x8cb5, 0x8b65, 0x8b42, 0x99f3,
-	0x9a60, 0x9b3b, 0x8b42, 0x9b48, 0x8df3, 0x9b73, 0x8b42, 0x9630,
-	0x9ba0, 0x8b42, 0x080c, 0x0db4, 0x2100, 0x005b, 0x00fe, 0x00ee,
-	0x00de, 0x00ce, 0x01de, 0x01ce, 0x014e, 0x013e, 0x015e, 0x00be,
-	0x0005, 0x8b63, 0x8b63, 0x8b63, 0x8b8c, 0x8c38, 0x8c43, 0x8b63,
-	0x8b63, 0x8b63, 0x8c8a, 0x8c96, 0x8ba7, 0x8b63, 0x8bc2, 0x8bf6,
-	0x9d22, 0x9d67, 0x8e10, 0x080c, 0x0db4, 0x00d6, 0x0096, 0x080c,
-	0x8ea9, 0x7003, 0x2414, 0x7007, 0x0018, 0x700b, 0x0800, 0x7814,
-	0x2048, 0xa83c, 0x700e, 0xa850, 0x7022, 0xa854, 0x7026, 0x60c3,
-	0x0018, 0x080c, 0x939b, 0x009e, 0x00de, 0x0005, 0x7810, 0x00b6,
-	0x2058, 0xb8a0, 0x00be, 0x080c, 0x9dae, 0x1118, 0x9084, 0xff80,
-	0x0110, 0x9085, 0x0001, 0x0005, 0x00d6, 0x0096, 0x080c, 0x8ea9,
-	0x7003, 0x0500, 0x7814, 0x2048, 0xa874, 0x700a, 0xa878, 0x700e,
-	0xa87c, 0x7012, 0xa880, 0x7016, 0xa884, 0x701a, 0xa888, 0x701e,
-	0x60c3, 0x0010, 0x080c, 0x939b, 0x009e, 0x00de, 0x0005, 0x00d6,
-	0x0096, 0x080c, 0x8ea9, 0x7003, 0x0500, 0x7814, 0x2048, 0xa8cc,
-	0x700a, 0xa8d0, 0x700e, 0xa8d4, 0x7012, 0xa8d8, 0x7016, 0xa8dc,
-	0x701a, 0xa8e0, 0x701e, 0x60c3, 0x0010, 0x080c, 0x939b, 0x009e,
-	0x00de, 0x0005, 0x00d6, 0x0096, 0x0126, 0x2091, 0x8000, 0x080c,
-	0x8ea9, 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, 0x225a, 0x080c, 0xc848, 0x9006, 0x080c,
-	0x225a, 0x001e, 0xa804, 0x9005, 0x0110, 0x2048, 0x0c28, 0x04d9,
-	0x080c, 0x939b, 0x012e, 0x009e, 0x00de, 0x0005, 0x00d6, 0x0096,
-	0x0126, 0x2091, 0x8000, 0x080c, 0x8ef4, 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, 0xc848, 0x001e, 0xa804, 0x9005, 0x0110, 0x2048, 0x0c60,
-	0x0051, 0x7814, 0x2048, 0x080c, 0x0f9d, 0x080c, 0x939b, 0x012e,
-	0x009e, 0x00de, 0x0005, 0x60c0, 0x8004, 0x9084, 0x0003, 0x9005,
-	0x0130, 0x9082, 0x0004, 0x20a3, 0x0000, 0x8000, 0x1de0, 0x0005,
-	0x080c, 0x8ea9, 0x7003, 0x7800, 0x7808, 0x8007, 0x700a, 0x60c3,
-	0x0008, 0x0804, 0x939b, 0x00d6, 0x00e6, 0x080c, 0x8ef4, 0x7814,
-	0x9084, 0xff00, 0x2073, 0x0200, 0x8e70, 0x8e70, 0x9095, 0x0010,
-	0x2272, 0x8e70, 0x2073, 0x0034, 0x8e70, 0x2069, 0x1805, 0x20a9,
-	0x0004, 0x2d76, 0x8d68, 0x8e70, 0x1f04, 0x8c59, 0x2069, 0x1801,
-	0x20a9, 0x0004, 0x2d76, 0x8d68, 0x8e70, 0x1f04, 0x8c62, 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, 0x8c70, 0x60c3, 0x004c, 0x080c, 0x939b, 0x00ee,
-	0x00de, 0x0005, 0x080c, 0x8ea9, 0x7003, 0x6300, 0x7007, 0x0028,
-	0x7808, 0x700e, 0x60c3, 0x0008, 0x0804, 0x939b, 0x00d6, 0x0026,
-	0x0016, 0x080c, 0x8ef4, 0x7003, 0x0200, 0x7814, 0x700e, 0x00e6,
-	0x9ef0, 0x0004, 0x2009, 0x0001, 0x2011, 0x000c, 0x2073, 0x0800,
-	0x8e70, 0x2073, 0x0000, 0x00ee, 0x7206, 0x710a, 0x62c2, 0x080c,
-	0x939b, 0x001e, 0x002e, 0x00de, 0x0005, 0x2001, 0x1817, 0x2004,
-	0x609a, 0x0804, 0x939b, 0x080c, 0x8ea9, 0x7003, 0x5200, 0x2069,
-	0x185b, 0x6804, 0xd084, 0x0130, 0x6828, 0x0016, 0x080c, 0x26a3,
-	0x710e, 0x001e, 0x20a9, 0x0004, 0x20e1, 0x0001, 0x2099, 0x1805,
-	0x20e9, 0x0000, 0x20a1, 0x0250, 0x4003, 0x20a9, 0x0004, 0x2099,
-	0x1801, 0x20a1, 0x0254, 0x4003, 0x080c, 0x9dae, 0x1120, 0xb8a0,
-	0x9082, 0x007f, 0x0248, 0x2001, 0x181e, 0x2004, 0x7032, 0x2001,
-	0x181f, 0x2004, 0x7036, 0x0030, 0x2001, 0x1817, 0x2004, 0x9084,
-	0x00ff, 0x7036, 0x60c3, 0x001c, 0x0804, 0x939b, 0x080c, 0x8ea9,
-	0x7003, 0x0500, 0x080c, 0x9dae, 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, 0x939b, 0x080c,
-	0x8ea9, 0x9006, 0x080c, 0x6544, 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, 0x8d8a, 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, 0x6faa, 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, 0x9c22, 0x2069, 0x194c, 0x2071, 0x024e, 0x6800,
-	0xc0dd, 0x7002, 0x080c, 0x539e, 0xd0e4, 0x0110, 0x680c, 0x700e,
-	0x00de, 0x04a0, 0x2001, 0x1836, 0x2004, 0xd0a4, 0x0168, 0x0016,
-	0x2009, 0x0002, 0x60e0, 0x9106, 0x0130, 0x2100, 0x60e3, 0x0000,
-	0x080c, 0x26e4, 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, 0x9c22, 0x20a1,
-	0x024e, 0x20a9, 0x0008, 0x2099, 0x194c, 0x4003, 0x60c3, 0x0074,
-	0x0804, 0x939b, 0x080c, 0x8ea9, 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, 0x8e59, 0x7026, 0x60c3,
-	0x0014, 0x0804, 0x939b, 0x080c, 0x8ea9, 0x7003, 0x5000, 0x0804,
-	0x8d39, 0x080c, 0x8ea9, 0x7003, 0x2110, 0x7007, 0x0014, 0x60c3,
-	0x0014, 0x0804, 0x939b, 0x080c, 0x8eeb, 0x0010, 0x080c, 0x8ef4,
-	0x7003, 0x0200, 0x60c3, 0x0004, 0x0804, 0x939b, 0x080c, 0x8ef4,
-	0x7003, 0x0100, 0x700b, 0x0003, 0x700f, 0x2a00, 0x60c3, 0x0008,
-	0x0804, 0x939b, 0x080c, 0x8ef4, 0x7003, 0x0200, 0x0804, 0x8d39,
-	0x080c, 0x8ef4, 0x7003, 0x0100, 0x782c, 0x9005, 0x0110, 0x700a,
-	0x0010, 0x700b, 0x0003, 0x7814, 0x700e, 0x60c3, 0x0008, 0x0804,
-	0x939b, 0x00d6, 0x080c, 0x8ef4, 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, 0x939b,
-	0x080c, 0x8ef4, 0x7003, 0x0210, 0x7007, 0x0014, 0x700f, 0x0100,
-	0x60c3, 0x0014, 0x0804, 0x939b, 0x080c, 0x8ef4, 0x7003, 0x0200,
-	0x0804, 0x8cbf, 0x080c, 0x8ef4, 0x7003, 0x0100, 0x700b, 0x0003,
-	0x700f, 0x2a00, 0x60c3, 0x0008, 0x0804, 0x939b, 0x080c, 0x8ef4,
-	0x7003, 0x0100, 0x700b, 0x000b, 0x60c3, 0x0008, 0x0804, 0x939b,
-	0x0026, 0x00d6, 0x0036, 0x0046, 0x2019, 0x3200, 0x2021, 0x0800,
-	0x0040, 0x0026, 0x00d6, 0x0036, 0x0046, 0x2019, 0x2200, 0x2021,
-	0x0100, 0x080c, 0x9c37, 0xb810, 0x9305, 0x7002, 0xb814, 0x7006,
-	0x2069, 0x1800, 0x6878, 0x700a, 0x687c, 0x700e, 0x9485, 0x0029,
-	0x7012, 0x004e, 0x003e, 0x00de, 0x080c, 0x9389, 0x721a, 0x9f95,
-	0x0000, 0x7222, 0x7027, 0xffff, 0x2071, 0x024c, 0x002e, 0x0005,
-	0x0026, 0x080c, 0x9c37, 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, 0x9c37, 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, 0x9389, 0x721a, 0x7a08, 0x7222,
-	0x2f10, 0x7226, 0x2071, 0x024c, 0x002e, 0x0005, 0x080c, 0x9389,
-	0x721a, 0x7a08, 0x7222, 0x7814, 0x7026, 0x2071, 0x024c, 0x002e,
-	0x0005, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2069, 0x0200,
-	0x2071, 0x0240, 0x6004, 0x908a, 0x0085, 0x0a0c, 0x0db4, 0x908a,
-	0x0092, 0x1a0c, 0x0db4, 0x6110, 0x2158, 0xb9b0, 0x2c78, 0x2061,
-	0x0100, 0x619a, 0x9082, 0x0085, 0x0033, 0x00fe, 0x00ee, 0x00de,
-	0x00ce, 0x00be, 0x0005, 0x8f62, 0x8f71, 0x8f7c, 0x8f60, 0x8f60,
-	0x8f60, 0x8f62, 0x8f60, 0x8f60, 0x8f60, 0x8f60, 0x8f60, 0x8f60,
-	0x080c, 0x0db4, 0x0411, 0x60c3, 0x0000, 0x0026, 0x080c, 0x29d7,
-	0x0228, 0x2011, 0x0101, 0x2204, 0xc0c5, 0x2012, 0x002e, 0x0804,
-	0x939b, 0x0431, 0x7808, 0x700a, 0x7814, 0x700e, 0x7017, 0xffff,
-	0x60c3, 0x000c, 0x0804, 0x939b, 0x0479, 0x7003, 0x0003, 0x7007,
-	0x0300, 0x60c3, 0x0004, 0x0804, 0x939b, 0x0026, 0x080c, 0x9c37,
-	0xb810, 0x9085, 0x8100, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800,
-	0x6878, 0x700a, 0x687c, 0x700e, 0x7013, 0x0009, 0x0804, 0x8ec4,
-	0x0026, 0x080c, 0x9c37, 0xb810, 0x9085, 0x8400, 0x7002, 0xb814,
-	0x7006, 0x2069, 0x1800, 0x6878, 0x700a, 0x687c, 0x700e, 0x2001,
-	0x0099, 0x7012, 0x0804, 0x8f26, 0x0026, 0x080c, 0x9c37, 0xb810,
-	0x9085, 0x8500, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0x6878,
-	0x700a, 0x687c, 0x700e, 0x2001, 0x0099, 0x7012, 0x0804, 0x8f26,
-	0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2c78, 0x2069, 0x0200,
-	0x2071, 0x0240, 0x7804, 0x908a, 0x0040, 0x0a0c, 0x0db4, 0x908a,
-	0x0054, 0x1a0c, 0x0db4, 0x7910, 0x2158, 0xb9b0, 0x2061, 0x0100,
-	0x619a, 0x9082, 0x0040, 0x0033, 0x00fe, 0x00ee, 0x00de, 0x00ce,
-	0x00be, 0x0005, 0x8ff7, 0x90b3, 0x9086, 0x91d5, 0x8ff5, 0x8ff5,
-	0x8ff5, 0x8ff5, 0x8ff5, 0x8ff5, 0x8ff5, 0x9777, 0x977f, 0x9787,
-	0x978f, 0x8ff5, 0x9b7f, 0x8ff5, 0x976f, 0x080c, 0x0db4, 0x0096,
-	0x780b, 0xffff, 0x080c, 0x9062, 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, 0x1789, 0x0010,
-	0x080c, 0x164a, 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, 0x7a46, 0x7b14, 0x7b4a, 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,
-	0x939b, 0x6813, 0x0008, 0xb810, 0x9085, 0x0500, 0x7002, 0xb814,
+	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,
+	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,
-	0x0889, 0x080c, 0x9389, 0x721a, 0x7a08, 0x7222, 0x2f10, 0x7226,
-	0x2071, 0x024c, 0x0005, 0x00d6, 0x0096, 0x080c, 0x91b3, 0x7814,
-	0x2048, 0x080c, 0xbb39, 0x1130, 0x7814, 0x9084, 0x0700, 0x8007,
-	0x0033, 0x0010, 0x9006, 0x001b, 0x009e, 0x00de, 0x0005, 0x90d1,
-	0x913a, 0x914a, 0x9170, 0x917c, 0x918d, 0x9195, 0x90cf, 0x080c,
-	0x0db4, 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, 0x939b, 0xc3e5, 0x0c88, 0x9186, 0x0001, 0x190c,
-	0x0db4, 0xaba8, 0x7824, 0xd0cc, 0x1904, 0x9137, 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, 0x939b, 0xc3e5,
-	0x0804, 0x90f6, 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, 0x939b,
-	0x2011, 0x0028, 0x7824, 0xd0cc, 0x1128, 0x7216, 0x60c3, 0x0018,
-	0x0804, 0x939b, 0x0cd0, 0xc2e5, 0x2011, 0x0100, 0x7824, 0xd0cc,
-	0x0108, 0xc2e5, 0x7216, 0x702f, 0x0008, 0x7858, 0x9084, 0x00ff,
-	0x7036, 0x60c3, 0x0020, 0x0804, 0x939b, 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,
-	0x9389, 0x721a, 0x7a08, 0x7222, 0x2f10, 0x7226, 0x2071, 0x024c,
-	0x00de, 0x0005, 0x7013, 0x0889, 0x0c90, 0x0016, 0x7814, 0x9084,
-	0x0700, 0x8007, 0x0013, 0x001e, 0x0005, 0x91e5, 0x91e5, 0x91e7,
-	0x91e5, 0x91e5, 0x91e5, 0x9201, 0x91e5, 0x080c, 0x0db4, 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,
-	0x939b, 0x2009, 0x0003, 0x0019, 0x7033, 0x7f00, 0x0cb0, 0x0016,
-	0x080c, 0x9c37, 0x001e, 0xb810, 0x9085, 0x0100, 0x7002, 0xb814,
-	0x7006, 0x2069, 0x1800, 0x6a78, 0x720a, 0x6a7c, 0x720e, 0x7013,
-	0x0888, 0x918d, 0x0008, 0x7116, 0x080c, 0x9389, 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, 0x92f8, 0x90be, 0x000a, 0x1904,
-	0x92b4, 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, 0x9c1c,
-	0x2009, 0x07d0, 0x60c4, 0x9084, 0xfff0, 0x9005, 0x0110, 0x2009,
-	0x1b58, 0x080c, 0x80c4, 0x003e, 0x004e, 0x005e, 0x00ce, 0x00de,
-	0x00ee, 0x009e, 0x00be, 0x0005, 0x7804, 0x9086, 0x0040, 0x0904,
-	0x9334, 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, 0x9c1c, 0x2009, 0x07d0, 0x60c4, 0x9084,
-	0xfff0, 0x9005, 0x0110, 0x2009, 0x1b58, 0x080c, 0x80c4, 0x003e,
-	0x004e, 0x005e, 0x00ce, 0x00de, 0x00ee, 0x009e, 0x00be, 0x0005,
-	0x7814, 0x2048, 0xa87c, 0x9084, 0x0003, 0x9086, 0x0002, 0x0904,
-	0x9350, 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, 0x9bf9, 0x0804, 0x92e4, 0xb8bc, 0xd084, 0x0148, 0xb88c,
-	0x7814, 0x2048, 0xb88c, 0x7846, 0xa836, 0x2900, 0xa83a, 0xb04a,
-	0x9185, 0x0600, 0x6062, 0x6266, 0x636a, 0x646e, 0x6073, 0x0829,
-	0x6077, 0x0000, 0x60af, 0x9575, 0x60d7, 0x0000, 0x0804, 0x92c7,
-	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, 0x9c1c, 0x0804, 0x92e4, 0x080c, 0x9bf9, 0x0804,
-	0x92e4, 0x7a10, 0x00b6, 0x2258, 0xba8c, 0x8210, 0x9294, 0x00ff,
-	0xba8e, 0x00be, 0x8217, 0x0005, 0x00d6, 0x2069, 0x19bf, 0x6843,
-	0x0001, 0x00de, 0x0005, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x00f1,
-	0x080c, 0x80b6, 0x0005, 0x0016, 0x2001, 0x180c, 0x200c, 0x9184,
-	0x0600, 0x9086, 0x0600, 0x0128, 0x0089, 0x080c, 0x80b6, 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, 0x6faa, 0x11c0,
-	0x2001, 0x19db, 0x2004, 0x9005, 0x15d0, 0x080c, 0x705a, 0x1160,
-	0x2061, 0x0100, 0x6020, 0xd0b4, 0x1120, 0x6024, 0xd084, 0x090c,
-	0x0db4, 0x080c, 0x80b6, 0x0458, 0x00c6, 0x2061, 0x19bf, 0x00c8,
-	0x6904, 0x9194, 0x4000, 0x0540, 0x0811, 0x080c, 0x2b31, 0x00c6,
-	0x2061, 0x19bf, 0x6128, 0x9192, 0x0008, 0x1258, 0x8108, 0x612a,
-	0x6124, 0x00ce, 0x81ff, 0x0198, 0x080c, 0x80b6, 0x080c, 0x93be,
-	0x0070, 0x6124, 0x91e5, 0x0000, 0x0140, 0x080c, 0xd903, 0x080c,
-	0x80bf, 0x2009, 0x0014, 0x080c, 0x9ea9, 0x00ce, 0x0000, 0x002e,
-	0x001e, 0x00de, 0x00ce, 0x0005, 0x2001, 0x19db, 0x2004, 0x9005,
-	0x1db0, 0x00c6, 0x2061, 0x19bf, 0x6128, 0x9192, 0x0003, 0x1e08,
-	0x8108, 0x612a, 0x00ce, 0x080c, 0x80b6, 0x080c, 0x5ba4, 0x2009,
-	0x185a, 0x2114, 0x8210, 0x220a, 0x0c10, 0x0096, 0x00c6, 0x00d6,
-	0x00e6, 0x0016, 0x0026, 0x080c, 0x80cc, 0x2071, 0x19bf, 0x713c,
-	0x81ff, 0x0904, 0x94b3, 0x2061, 0x0100, 0x2069, 0x0140, 0x080c,
-	0x6faa, 0x1190, 0x0036, 0x2019, 0x0002, 0x080c, 0x96e9, 0x003e,
-	0x713c, 0x2160, 0x080c, 0xd903, 0x2009, 0x004a, 0x080c, 0x9ea9,
-	0x080c, 0x705a, 0x0804, 0x94b3, 0x080c, 0x94bf, 0x0904, 0x94b3,
-	0x6904, 0xd1f4, 0x0904, 0x94ba, 0x080c, 0x2b31, 0x00c6, 0x703c,
-	0x9065, 0x090c, 0x0db4, 0x6020, 0x00ce, 0x9086, 0x0006, 0x1528,
-	0x61c8, 0x60c4, 0x9105, 0x1508, 0x2009, 0x180c, 0x2104, 0xd0d4,
-	0x01e0, 0x6214, 0x9294, 0x1800, 0x1128, 0x6224, 0x9294, 0x0002,
-	0x1510, 0x0030, 0xc0d4, 0x200a, 0xd0cc, 0x0110, 0x080c, 0x2a84,
-	0x6014, 0x9084, 0xe7fd, 0x9085, 0x0010, 0x6016, 0x703c, 0x2060,
-	0x2009, 0x0049, 0x080c, 0x9ea9, 0x0070, 0x0036, 0x2019, 0x0001,
-	0x080c, 0x96e9, 0x003e, 0x713c, 0x2160, 0x080c, 0xd903, 0x2009,
-	0x004a, 0x080c, 0x9ea9, 0x002e, 0x001e, 0x00ee, 0x00de, 0x00ce,
-	0x009e, 0x0005, 0xd1ec, 0x1904, 0x9474, 0x0804, 0x9476, 0x00d6,
-	0x00c6, 0x0096, 0x703c, 0x9065, 0x090c, 0x0db4, 0x2001, 0x1836,
-	0x2004, 0xd09c, 0x1904, 0x954b, 0x2001, 0x0306, 0x200c, 0x9184,
-	0x0030, 0x0904, 0x954b, 0x9184, 0x0048, 0x9086, 0x0008, 0x1904,
-	0x954b, 0x2001, 0x020b, 0x2004, 0xd0fc, 0x0904, 0x954b, 0xd08c,
-	0x0904, 0x954b, 0x2009, 0x1a57, 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, 0x1a69,
-	0x0040, 0x6014, 0x2048, 0xaa3a, 0xa936, 0x6ac4, 0x69c8, 0xa946,
-	0xaa4a, 0x0126, 0x00c6, 0x2091, 0x2400, 0x002e, 0x080c, 0x1af5,
-	0x190c, 0x0db4, 0x012e, 0x0090, 0x2009, 0x1a58, 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, 0x80c4, 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, 0x6388, 0x0110, 0x9085, 0x0001, 0x012e, 0x000e,
-	0x004e, 0x005e, 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00be, 0x0005,
-	0x080c, 0x8ea9, 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, 0x939b, 0x080c, 0x8ea9, 0x7003, 0x0f00, 0x7808,
-	0xd09c, 0x0128, 0xb810, 0x9084, 0x00ff, 0x700a, 0xb814, 0x700e,
-	0x60c3, 0x0008, 0x0804, 0x939b, 0x0156, 0x080c, 0x8ef4, 0x7003,
-	0x0200, 0x2011, 0x1848, 0x63f0, 0x2312, 0x20a9, 0x0006, 0x2011,
-	0x1840, 0x2019, 0x1841, 0x9ef0, 0x0002, 0x2376, 0x8e70, 0x2276,
-	0x8e70, 0x9398, 0x0002, 0x9290, 0x0002, 0x1f04, 0x95e5, 0x60c3,
-	0x001c, 0x015e, 0x0804, 0x939b, 0x0016, 0x0026, 0x080c, 0x8ed0,
-	0x080c, 0x8ee2, 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,
-	0x939b, 0x002e, 0x001e, 0x0005, 0x20a9, 0x0010, 0x4003, 0x080c,
-	0x9c22, 0x20a1, 0x0240, 0x22a8, 0x4003, 0x0c68, 0x080c, 0x8ea9,
-	0x7003, 0x6200, 0x7808, 0x700e, 0x60c3, 0x0008, 0x0804, 0x939b,
-	0x0016, 0x0026, 0x080c, 0x8ea9, 0x20e9, 0x0000, 0x20a1, 0x024c,
-	0x7814, 0x0096, 0x2048, 0xa800, 0x2048, 0xa860, 0x20e0, 0xa85c,
-	0x9080, 0x0023, 0x2098, 0x009e, 0x7808, 0x9088, 0x0002, 0x21a8,
-	0x4003, 0x8003, 0x60c2, 0x080c, 0x939b, 0x002e, 0x001e, 0x0005,
-	0x00e6, 0x00c6, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19bf,
-	0x700c, 0x2060, 0x8cff, 0x0178, 0x080c, 0xbd41, 0x1110, 0x080c,
-	0xa7cd, 0x600c, 0x0006, 0x080c, 0xbfad, 0x080c, 0x9e2f, 0x080c,
-	0x979a, 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,
-	0x93c7, 0x6ac0, 0x68c3, 0x0000, 0x080c, 0x80bf, 0x00c6, 0x2061,
-	0x0100, 0x080c, 0x9c3b, 0x00ce, 0x20a9, 0x01f4, 0x0461, 0x2009,
-	0x0013, 0x080c, 0x9ea9, 0x000e, 0x001e, 0x002e, 0x006e, 0x00ce,
-	0x00de, 0x00ee, 0x00fe, 0x015e, 0x012e, 0x0005, 0x2001, 0x1800,
-	0x2004, 0x9096, 0x0001, 0x0d78, 0x9096, 0x0004, 0x0d60, 0x080c,
-	0x80bf, 0x6814, 0x9084, 0x0001, 0x0110, 0x68a7, 0x95f5, 0x6817,
-	0x0008, 0x68c3, 0x0000, 0x2011, 0x5b4e, 0x080c, 0x803f, 0x20a9,
-	0x01f4, 0x0009, 0x08c0, 0x6824, 0xd094, 0x0140, 0x6827, 0x0004,
-	0x7804, 0x9084, 0x4000, 0x190c, 0x2b31, 0x0090, 0xd084, 0x0118,
-	0x6827, 0x0001, 0x0010, 0x1f04, 0x96cb, 0x7804, 0x9084, 0x1000,
-	0x0138, 0x2001, 0x0100, 0x080c, 0x2b21, 0x9006, 0x080c, 0x2b21,
-	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, 0x9750, 0x9386, 0x0002,
-	0x1128, 0x6814, 0x9084, 0x0002, 0x0904, 0x9750, 0x68af, 0x95f5,
-	0x6817, 0x0010, 0x2009, 0x00fa, 0x8109, 0x1df0, 0x69c6, 0x68cb,
-	0x0008, 0x080c, 0x80cc, 0x080c, 0x1e9d, 0x2001, 0x0032, 0x6920,
-	0xd1bc, 0x0130, 0x8001, 0x1dd8, 0x692c, 0x918d, 0x0008, 0x692e,
-	0x20a9, 0x03e8, 0x6824, 0xd094, 0x0140, 0x6827, 0x0004, 0x7804,
-	0x9084, 0x4000, 0x190c, 0x2b31, 0x0090, 0xd08c, 0x0118, 0x6827,
-	0x0002, 0x0010, 0x1f04, 0x972a, 0x7804, 0x9084, 0x1000, 0x0138,
-	0x2001, 0x0100, 0x080c, 0x2b21, 0x9006, 0x080c, 0x2b21, 0x6827,
-	0x4000, 0x6824, 0x83ff, 0x1120, 0x2009, 0x0049, 0x080c, 0x9ea9,
-	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,
-	0x9062, 0x7854, 0x7032, 0x7042, 0x7047, 0x1000, 0x00f8, 0x080c,
-	0x9062, 0x7854, 0x7032, 0x7042, 0x7047, 0x4000, 0x00b8, 0x080c,
-	0x9062, 0x7854, 0x7032, 0x7042, 0x7047, 0x2000, 0x0078, 0x080c,
-	0x9062, 0x7854, 0x7032, 0x7042, 0x7047, 0x0400, 0x0038, 0x080c,
-	0x9062, 0x7854, 0x7032, 0x7042, 0x7047, 0x0200, 0x60c3, 0x0020,
-	0x0804, 0x939b, 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, 0x983f,
-	0x8cff, 0x0904, 0x983f, 0x6020, 0x9086, 0x0006, 0x1904, 0x983a,
-	0x88ff, 0x0138, 0x2800, 0x9c06, 0x1904, 0x983a, 0x2039, 0x0000,
-	0x0050, 0x6010, 0x9b06, 0x1904, 0x983a, 0x85ff, 0x0120, 0x6054,
-	0x9106, 0x1904, 0x983a, 0x7024, 0x9c06, 0x15b0, 0x2069, 0x0100,
-	0x68c0, 0x9005, 0x1160, 0x6824, 0xd084, 0x0148, 0x6827, 0x0001,
-	0x080c, 0x80bf, 0x080c, 0x98c4, 0x7027, 0x0000, 0x0428, 0x080c,
-	0x80bf, 0x6820, 0xd0b4, 0x0110, 0x68a7, 0x95f5, 0x6817, 0x0008,
-	0x68c3, 0x0000, 0x080c, 0x98c4, 0x7027, 0x0000, 0x0036, 0x2069,
-	0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c,
-	0x2b21, 0x9006, 0x080c, 0x2b21, 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, 0xbb39, 0x0110, 0x080c, 0xd50f,
-	0x009e, 0x080c, 0x9e5f, 0x080c, 0x979a, 0x88ff, 0x1190, 0x00ce,
-	0x0804, 0x97b5, 0x2c78, 0x600c, 0x2060, 0x0804, 0x97b5, 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, 0x98b3, 0x6020, 0x9086, 0x0006, 0x1904, 0x98ae, 0x87ff,
-	0x0128, 0x2700, 0x9c06, 0x1904, 0x98ae, 0x0040, 0x6010, 0x9b06,
-	0x15e8, 0x85ff, 0x0118, 0x6054, 0x9106, 0x15c0, 0x703c, 0x9c06,
-	0x1168, 0x0036, 0x2019, 0x0001, 0x080c, 0x96e9, 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, 0xbb39, 0x0110, 0x080c, 0xd50f, 0x080c,
-	0x9e5f, 0x87ff, 0x1198, 0x00ce, 0x0804, 0x985f, 0x2c78, 0x600c,
-	0x2060, 0x0804, 0x985f, 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, 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, 0x887f, 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, 0x99aa,
-	0x6010, 0x00b6, 0x2058, 0xb8a0, 0x00be, 0x9206, 0x1904, 0x99a5,
+	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,
-	0x997c, 0x080c, 0x93c7, 0x68c3, 0x0000, 0x080c, 0x98c4, 0x7027,
+	0x9f94, 0x080c, 0x9656, 0x68c3, 0x0000, 0x080c, 0x9b78, 0x7027,
 	0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138,
-	0x2001, 0x0100, 0x080c, 0x2b21, 0x9006, 0x080c, 0x2b21, 0x2069,
+	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, 0xbd30, 0x1180, 0x080c, 0x3010, 0x080c, 0xbd41,
-	0x1518, 0x080c, 0xa7cd, 0x0400, 0x080c, 0x98c4, 0x6824, 0xd084,
-	0x09b0, 0x6827, 0x0001, 0x0898, 0x080c, 0xbd41, 0x1118, 0x080c,
-	0xa7cd, 0x0090, 0x6014, 0x2048, 0x080c, 0xbb39, 0x0168, 0x6020,
-	0x9086, 0x0003, 0x1508, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000,
-	0x080c, 0x6893, 0x080c, 0xbd24, 0x080c, 0xbfad, 0x080c, 0x9e5f,
-	0x080c, 0x979a, 0x00ce, 0x0804, 0x9925, 0x2c78, 0x600c, 0x2060,
-	0x0804, 0x9925, 0x012e, 0x000e, 0x002e, 0x006e, 0x00ce, 0x00de,
-	0x00ee, 0x00fe, 0x009e, 0x0005, 0x6020, 0x9086, 0x0006, 0x1d20,
-	0x080c, 0xd50f, 0x0c08, 0x00d6, 0x080c, 0x8ef4, 0x7003, 0x0200,
-	0x7007, 0x0014, 0x60c3, 0x0014, 0x20e1, 0x0001, 0x2099, 0x1961,
-	0x20e9, 0x0000, 0x20a1, 0x0250, 0x20a9, 0x0004, 0x4003, 0x7023,
-	0x0004, 0x7027, 0x7878, 0x080c, 0x939b, 0x00de, 0x0005, 0x080c,
-	0x8ef4, 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, 0x939b, 0x00b6, 0x00d6, 0x0016, 0x00d6, 0x2f68,
-	0x2009, 0x0035, 0x080c, 0xc1b3, 0x00de, 0x1904, 0x9a58, 0x080c,
-	0x8ea9, 0x7003, 0x1300, 0x782c, 0x080c, 0x9b5e, 0x2068, 0x6820,
-	0x9086, 0x0003, 0x0560, 0x7810, 0x2058, 0xbaa0, 0x080c, 0x9dae,
-	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,
-	0x9dae, 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, 0x939b, 0x00be, 0x0005,
-	0x781b, 0x0001, 0x7803, 0x0006, 0x001e, 0x00de, 0x00be, 0x0005,
-	0x792c, 0x9180, 0x0008, 0x200c, 0x9186, 0x0006, 0x01c0, 0x9186,
-	0x0003, 0x0904, 0x9ad3, 0x9186, 0x0005, 0x0904, 0x9abb, 0x9186,
-	0x0004, 0x05d8, 0x9186, 0x0008, 0x0904, 0x9ac4, 0x7807, 0x0037,
-	0x782f, 0x0003, 0x7817, 0x1700, 0x080c, 0x9b3b, 0x0005, 0x080c,
-	0x9afc, 0x00d6, 0x0026, 0x792c, 0x2168, 0x2009, 0x4000, 0x6800,
-	0x0002, 0x9a9c, 0x9aa7, 0x9a9e, 0x9aa7, 0x9aa3, 0x9a9c, 0x9a9c,
-	0x9aa7, 0x9aa7, 0x9aa7, 0x9aa7, 0x9a9c, 0x9a9c, 0x9a9c, 0x9a9c,
-	0x9a9c, 0x9aa7, 0x9a9c, 0x9aa7, 0x080c, 0x0db4, 0x6824, 0xd0e4,
-	0x0110, 0xd0cc, 0x0110, 0x900e, 0x0010, 0x2009, 0x2000, 0x682c,
-	0x7022, 0x6830, 0x7026, 0x0804, 0x9af5, 0x080c, 0x9afc, 0x00d6,
-	0x0026, 0x792c, 0x2168, 0x2009, 0x4000, 0x6a00, 0x9286, 0x0002,
-	0x1108, 0x900e, 0x04d0, 0x080c, 0x9afc, 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, 0x939b, 0x00b6, 0x0036, 0x0046, 0x0056,
-	0x0066, 0x080c, 0x8ef4, 0x9006, 0x7003, 0x0200, 0x7938, 0x710a,
-	0x793c, 0x710e, 0x7810, 0x2058, 0xb8a0, 0x080c, 0x9dae, 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, 0x8ef4, 0x7003, 0x0100, 0x782c,
-	0x700a, 0x7814, 0x700e, 0x700e, 0x60c3, 0x0008, 0x0804, 0x939b,
-	0x080c, 0x8ea0, 0x7003, 0x1400, 0x7838, 0x700a, 0x0079, 0x783c,
-	0x700e, 0x782c, 0x7012, 0x7830, 0x7016, 0x7834, 0x9084, 0x00ff,
-	0x8007, 0x701a, 0x60c3, 0x0010, 0x0804, 0x939b, 0x00e6, 0x2071,
-	0x0240, 0x0006, 0x00f6, 0x2078, 0x7810, 0x00b6, 0x2058, 0xb8bc,
-	0xd084, 0x0120, 0x7848, 0x702a, 0x7844, 0x702e, 0x00be, 0x00fe,
-	0x000e, 0x00ee, 0x0005, 0x080c, 0x8eeb, 0x7003, 0x0100, 0x782c,
-	0x700a, 0x7814, 0x700e, 0x60c3, 0x0008, 0x0804, 0x939b, 0x0021,
-	0x60c3, 0x0000, 0x0804, 0x939b, 0x00d6, 0x080c, 0x9c37, 0xb810,
-	0x9085, 0x0300, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0x6878,
-	0x700a, 0x687c, 0x700e, 0x7013, 0x0819, 0x080c, 0x9389, 0x721a,
-	0x2f10, 0x7222, 0x7a08, 0x7226, 0x2071, 0x024c, 0x00de, 0x0005,
-	0x00a9, 0x7914, 0x712a, 0x60c3, 0x0000, 0x60a7, 0x9575, 0x0026,
-	0x080c, 0x29d7, 0x0228, 0x2011, 0x0101, 0x2204, 0xc0c5, 0x2012,
-	0x002e, 0x080c, 0x93be, 0x080c, 0x80b6, 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, 0x9c37, 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, 0x1f31, 0x080c,
-	0x845d, 0x0126, 0x2091, 0x8000, 0x080c, 0x8a68, 0x012e, 0x009e,
-	0x00de, 0x0005, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x00a6, 0x0096,
-	0x0066, 0x0126, 0x2091, 0x8000, 0x2071, 0x19bf, 0x760c, 0x2660,
-	0x2678, 0x8cff, 0x0904, 0x9d0e, 0x7024, 0x9c06, 0x1520, 0x2069,
-	0x0100, 0x68c0, 0x9005, 0x0904, 0x9ce0, 0x080c, 0x93c7, 0x68c3,
-	0x0000, 0x080c, 0x98c4, 0x7027, 0x0000, 0x0036, 0x2069, 0x0140,
-	0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2b21,
-	0x9006, 0x080c, 0x2b21, 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, 0xbd30, 0x1180,
-	0x080c, 0x3010, 0x080c, 0xbd41, 0x1518, 0x080c, 0xa7cd, 0x0400,
-	0x080c, 0x98c4, 0x6824, 0xd084, 0x09b0, 0x6827, 0x0001, 0x0898,
-	0x080c, 0xbd41, 0x1118, 0x080c, 0xa7cd, 0x0090, 0x6014, 0x2048,
-	0x080c, 0xbb39, 0x0168, 0x6020, 0x9086, 0x0003, 0x1520, 0xa867,
-	0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0x68a0, 0x080c, 0xbd24,
-	0x080c, 0xbfad, 0x080c, 0x9e5f, 0x080c, 0x979a, 0x00ce, 0x0804,
-	0x9c91, 0x2c78, 0x600c, 0x2060, 0x0804, 0x9c91, 0x700f, 0x0000,
-	0x700b, 0x0000, 0x012e, 0x006e, 0x009e, 0x00ae, 0x00ce, 0x00de,
-	0x00ee, 0x00fe, 0x0005, 0x6020, 0x9086, 0x0006, 0x1d08, 0x080c,
-	0xd50f, 0x08f0, 0x00d6, 0x0156, 0x080c, 0x8ef4, 0x7a14, 0x82ff,
-	0x0138, 0x7003, 0x0100, 0x700b, 0x0003, 0x60c3, 0x0008, 0x0490,
-	0x7003, 0x0200, 0x7007, 0x0000, 0x2069, 0x1800, 0x901e, 0x6800,
-	0x9086, 0x0004, 0x1110, 0xc38d, 0x0060, 0x080c, 0x6faa, 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, 0x9d56,
-	0x60c3, 0x0020, 0x080c, 0x939b, 0x015e, 0x00de, 0x0005, 0x0156,
-	0x080c, 0x8ef4, 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, 0x939b, 0x0006, 0x2001,
-	0x1836, 0x2004, 0xd0ac, 0x000e, 0x0005, 0x2011, 0x0003, 0x080c,
-	0x975b, 0x2011, 0x0002, 0x080c, 0x9765, 0x080c, 0x9673, 0x0036,
-	0x901e, 0x080c, 0x96e9, 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, 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, 0x0db4, 0x2001, 0x1819, 0x2004, 0x9c02, 0x1a0c,
-	0x0db4, 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, 0x898b, 0x012e, 0x0cc0, 0x0006,
-	0x6000, 0x9086, 0x0000, 0x01b0, 0x601c, 0xd084, 0x190c, 0x191f,
-	0x6017, 0x0000, 0x6023, 0x0007, 0x2001, 0x195e, 0x2004, 0x0006,
-	0x9082, 0x0051, 0x000e, 0x0208, 0x8004, 0x601a, 0x080c, 0xd7c1,
-	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, 0x9ebc, 0x9ec5, 0x9ee0,
-	0x9efb, 0xc261, 0xc27e, 0xc299, 0x9ebc, 0x9ec5, 0x9ebc, 0x9f17,
-	0x9ebc, 0x9ebc, 0x9ebc, 0x9ebc, 0x9186, 0x0013, 0x1128, 0x080c,
-	0x887f, 0x080c, 0x898b, 0x0005, 0x0005, 0x0066, 0x6000, 0x90b2,
-	0x0016, 0x1a0c, 0x0db4, 0x0013, 0x006e, 0x0005, 0x9ede, 0xa644,
-	0xa814, 0x9ede, 0xa8a2, 0xa1fa, 0x9ede, 0x9ede, 0xa5c6, 0xae46,
-	0x9ede, 0x9ede, 0x9ede, 0x9ede, 0x9ede, 0x9ede, 0x080c, 0x0db4,
-	0x0066, 0x6000, 0x90b2, 0x0016, 0x1a0c, 0x0db4, 0x0013, 0x006e,
-	0x0005, 0x9ef9, 0xb51d, 0x9ef9, 0x9ef9, 0x9ef9, 0x9ef9, 0x9ef9,
-	0x9ef9, 0xb4bf, 0xb69f, 0x9ef9, 0xb55e, 0xb5dd, 0xb55e, 0xb5dd,
-	0x9ef9, 0x080c, 0x0db4, 0x6000, 0x9082, 0x0016, 0x1a0c, 0x0db4,
-	0x6000, 0x0002, 0x9f15, 0xae8d, 0xaf72, 0xb0a2, 0xb24d, 0x9f15,
-	0x9f15, 0x9f15, 0xae61, 0xb44b, 0xb44e, 0x9f15, 0x9f15, 0x9f15,
-	0x9f15, 0xb47d, 0x9f15, 0x9f15, 0x9f15, 0x080c, 0x0db4, 0x0066,
-	0x6000, 0x90b2, 0x0016, 0x1a0c, 0x0db4, 0x0013, 0x006e, 0x0005,
-	0x9f30, 0x9f30, 0x9f73, 0xa012, 0xa0a7, 0x9f30, 0x9f30, 0x9f30,
-	0x9f32, 0x9f30, 0x9f30, 0x9f30, 0x9f30, 0x9f30, 0x9f30, 0x9f30,
-	0x080c, 0x0db4, 0x9186, 0x004c, 0x0588, 0x9186, 0x0003, 0x190c,
-	0x0db4, 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, 0x1a69, 0x080c, 0x845d, 0x0126,
-	0x2091, 0x8000, 0x080c, 0x8a68, 0x012e, 0x0005, 0x6010, 0x00b6,
-	0x2058, 0xbca0, 0x00be, 0x2c00, 0x080c, 0xa0c9, 0x080c, 0xc253,
-	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, 0x9fda, 0x9fda, 0x9fd5,
-	0x9fd8, 0x9fda, 0x9fd2, 0x9fc5, 0x9fc5, 0x9fc5, 0x9fc5, 0x9fc5,
-	0x9fc5, 0x9fc5, 0x9fc5, 0x9fc5, 0x9fc5, 0x00fe, 0x00ee, 0x00de,
-	0x00ce, 0x002e, 0x001e, 0x000e, 0x004e, 0x00fe, 0x009e, 0x00de,
-	0x080c, 0x0db4, 0x080c, 0xaa85, 0x0028, 0x080c, 0xaba8, 0x0010,
-	0x080c, 0xac97, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x002e, 0x001e,
-	0x2c00, 0xa896, 0x000e, 0x080c, 0xa187, 0x0530, 0xa804, 0xa80e,
-	0x00a6, 0x2050, 0xb100, 0x00ae, 0x8006, 0x8006, 0x8007, 0x90bc,
-	0x003f, 0x9084, 0xffc0, 0x9080, 0x0002, 0xaacc, 0xabd0, 0xacd4,
-	0xadd8, 0x2031, 0x0000, 0x2041, 0x1249, 0x080c, 0xa332, 0x0160,
-	0x000e, 0x9005, 0x0120, 0x00fe, 0x009e, 0x00de, 0x0005, 0x00fe,
-	0x009e, 0x00de, 0x0804, 0x9e2f, 0x2001, 0x002c, 0x900e, 0x080c,
-	0xa1ed, 0x0c70, 0x91b6, 0x0015, 0x0170, 0x91b6, 0x0016, 0x0158,
-	0x91b2, 0x0047, 0x0a0c, 0x0db4, 0x91b2, 0x0050, 0x1a0c, 0x0db4,
-	0x9182, 0x0047, 0x00ca, 0x2001, 0x0109, 0x2004, 0xd08c, 0x0198,
-	0x0126, 0x2091, 0x2800, 0x0006, 0x0016, 0x0026, 0x080c, 0x83b1,
-	0x002e, 0x001e, 0x000e, 0x012e, 0xa001, 0x6000, 0x9086, 0x0002,
-	0x1110, 0x0804, 0x9f73, 0x0005, 0xa045, 0xa045, 0xa047, 0xa07d,
-	0xa045, 0xa045, 0xa045, 0xa045, 0xa090, 0x080c, 0x0db4, 0x00d6,
-	0x0016, 0x0096, 0x080c, 0x893b, 0x080c, 0x8a68, 0x6003, 0x0004,
-	0x6114, 0x2148, 0xa87c, 0xd0fc, 0x01c0, 0xa878, 0xc0fc, 0x9005,
-	0x1158, 0xa894, 0x9005, 0x0140, 0x2001, 0x0000, 0x900e, 0x080c,
-	0xa1ed, 0x080c, 0x9e2f, 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, 0x893b, 0x00d6,
-	0x0096, 0x6114, 0x2148, 0x080c, 0xbb3b, 0x0120, 0xa87b, 0x0006,
-	0x080c, 0x68a0, 0x009e, 0x00de, 0x080c, 0x9e2f, 0x0804, 0x8a68,
-	0x080c, 0x893b, 0x080c, 0x2fe7, 0x080c, 0xc250, 0x00d6, 0x0096,
-	0x6114, 0x2148, 0x080c, 0xbb3b, 0x0120, 0xa87b, 0x0029, 0x080c,
-	0x68a0, 0x009e, 0x00de, 0x080c, 0x9e2f, 0x0804, 0x8a68, 0x9182,
-	0x0047, 0x0002, 0xa0b7, 0xa0b9, 0xa0b7, 0xa0b7, 0xa0b7, 0xa0b7,
-	0xa0b7, 0xa0b7, 0xa0b7, 0xa0b7, 0xa0b7, 0xa0b7, 0xa0b9, 0x080c,
-	0x0db4, 0x00d6, 0x0096, 0x080c, 0x1511, 0x6114, 0x2148, 0xa87b,
-	0x0000, 0xa883, 0x0000, 0x080c, 0x68a0, 0x009e, 0x00de, 0x0804,
-	0x9e2f, 0x0026, 0x0036, 0x0056, 0x0066, 0x0096, 0x00a6, 0x00f6,
-	0x0006, 0x080c, 0x0feb, 0x000e, 0x090c, 0x0db4, 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, 0xb724, 0x04c0, 0x2130, 0x2009, 0x0034, 0x2011, 0x001f,
-	0x080c, 0xb724, 0x96b2, 0x0034, 0xb004, 0x904d, 0x0110, 0x080c,
-	0x0f9d, 0x080c, 0x0feb, 0x01d0, 0x8528, 0xa867, 0x0110, 0xa86b,
-	0x0000, 0x2920, 0xb406, 0x968a, 0x003d, 0x1230, 0x2608, 0x2011,
-	0x001b, 0x080c, 0xb724, 0x00b8, 0x96b2, 0x003c, 0x2009, 0x003c,
-	0x2950, 0x2011, 0x001b, 0x080c, 0xb724, 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, 0x68a0, 0x000e, 0x2048, 0x9005, 0x1db0, 0x00fe,
-	0x00ae, 0x009e, 0x006e, 0x005e, 0x003e, 0x002e, 0x0005, 0x00d6,
-	0x00f6, 0x0096, 0x0006, 0x080c, 0x0feb, 0x000e, 0x090c, 0x0db4,
-	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, 0x68a0, 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, 0x0feb, 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, 0xa19c, 0x0804, 0xa19e, 0x9085, 0x0001, 0x7817, 0x0000,
-	0x009e, 0x00fe, 0x00de, 0x001e, 0x0005, 0x00d6, 0x0036, 0x0096,
-	0x6314, 0x2348, 0xa87a, 0xa982, 0x080c, 0x6893, 0x009e, 0x003e,
-	0x00de, 0x0005, 0x91b6, 0x0015, 0x1118, 0x080c, 0x9e2f, 0x0030,
-	0x91b6, 0x0016, 0x190c, 0x0db4, 0x080c, 0x9e2f, 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, 0xbb3b, 0x0130, 0x6014,
-	0x2048, 0xa807, 0x0000, 0xa867, 0x0103, 0x009e, 0x0804, 0x9e2f,
-	0x0096, 0x00d6, 0x0036, 0x7330, 0x9386, 0x0200, 0x11a8, 0x6010,
-	0x00b6, 0x2058, 0xb8bf, 0x0000, 0x00be, 0x6014, 0x9005, 0x0130,
-	0x2048, 0xa807, 0x0000, 0xa867, 0x0103, 0xab32, 0x080c, 0x9e2f,
-	0x003e, 0x00de, 0x009e, 0x0005, 0x0011, 0x1d48, 0x0cc8, 0x0006,
-	0x0016, 0x080c, 0xc23b, 0x0188, 0x6014, 0x9005, 0x1170, 0x600b,
-	0x0003, 0x601b, 0x0000, 0x6043, 0x0000, 0x2009, 0x0022, 0x080c,
-	0xa61c, 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,
+	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,
+	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, 0x0002, 0x2099, 0x0260, 0x20a9, 0x0020, 0x4003, 0x2003,
-	0x0000, 0x6014, 0x2048, 0xa800, 0x2048, 0xa867, 0x0103, 0x080c,
-	0x9e2f, 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, 0xb724, 0x080c,
-	0xbb3b, 0x0140, 0x6014, 0x2048, 0xa807, 0x0000, 0xa864, 0xa8e2,
-	0xa867, 0x0103, 0x080c, 0x9e2f, 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, 0xb724,
-	0x009e, 0x080c, 0xbb3b, 0x0148, 0xa804, 0x9005, 0x1158, 0xa807,
-	0x0000, 0xa864, 0xa8e2, 0xa867, 0x0103, 0x080c, 0x9e2f, 0x009e,
-	0x001e, 0x0005, 0x0086, 0x2040, 0xa030, 0x8007, 0x9086, 0x0100,
-	0x1118, 0x080c, 0xa7cd, 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, 0x122f, 0x0019, 0x0d08,
-	0x008e, 0x0898, 0x0096, 0x0006, 0x080c, 0x0feb, 0x000e, 0x01b0,
-	0xa8ab, 0x0dcb, 0xa876, 0x000e, 0xa8a2, 0x0006, 0xae6a, 0x2800,
-	0xa89e, 0xa97a, 0xaf72, 0xaa8e, 0xab92, 0xac96, 0xad9a, 0x0086,
-	0x2940, 0x080c, 0x10d5, 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, 0xc1b3, 0x001e, 0x1158, 0x622c,
-	0x2268, 0x2071, 0x026c, 0x6b20, 0x9386, 0x0003, 0x0130, 0x9386,
-	0x0006, 0x0128, 0x080c, 0x9e2f, 0x0020, 0x0039, 0x0010, 0x080c,
-	0xa451, 0x002e, 0x00de, 0x00ee, 0x0005, 0x0096, 0x6814, 0x2048,
-	0x9186, 0x0015, 0x0904, 0xa439, 0x918e, 0x0016, 0x1904, 0xa44f,
-	0x700c, 0x908c, 0xff00, 0x9186, 0x1700, 0x0120, 0x9186, 0x0300,
-	0x1904, 0xa413, 0x89ff, 0x1138, 0x6800, 0x9086, 0x000f, 0x0904,
-	0xa3f6, 0x0804, 0xa44d, 0x6808, 0x9086, 0xffff, 0x1904, 0xa43b,
-	0xa87c, 0x9084, 0x0060, 0x9086, 0x0020, 0x1128, 0xa83c, 0xa940,
-	0x9105, 0x1904, 0xa43b, 0x6824, 0xd084, 0x1904, 0xa43b, 0xd0b4,
-	0x0158, 0x0016, 0x2001, 0x195e, 0x200c, 0x6018, 0x9102, 0x9082,
-	0x0005, 0x001e, 0x1a04, 0xa43b, 0x080c, 0xbd24, 0x685c, 0xa882,
-	0xa87c, 0xc0dc, 0xc0f4, 0xc0d4, 0xa87e, 0x0026, 0x900e, 0x6a18,
-	0x2001, 0x000a, 0x080c, 0x8277, 0xa884, 0x920a, 0x0208, 0x8011,
-	0xaa86, 0x82ff, 0x002e, 0x1138, 0x00c6, 0x2d60, 0x080c, 0xb84e,
-	0x00ce, 0x0804, 0xa44d, 0x00c6, 0xa868, 0xd0fc, 0x1118, 0x080c,
-	0x5d61, 0x0010, 0x080c, 0x610c, 0x00ce, 0x1904, 0xa43b, 0x00c6,
-	0x2d60, 0x080c, 0x9e2f, 0x00ce, 0x0804, 0xa44d, 0x00c6, 0x080c,
-	0x9e7c, 0x0198, 0x6017, 0x0000, 0x6810, 0x6012, 0x080c, 0xbfb5,
-	0x6023, 0x0003, 0x6904, 0x00c6, 0x2d60, 0x080c, 0x9e2f, 0x00ce,
-	0x080c, 0x9ea9, 0x00ce, 0x0804, 0xa44d, 0x2001, 0x1960, 0x2004,
-	0x6842, 0x00ce, 0x04d0, 0x7008, 0x9086, 0x000b, 0x11c8, 0x6010,
-	0x00b6, 0x2058, 0xb900, 0xc1bc, 0xb902, 0x00be, 0x00c6, 0x2d60,
-	0xa87b, 0x0003, 0x080c, 0xc1f5, 0x6007, 0x0085, 0x6003, 0x000b,
-	0x6023, 0x0002, 0x080c, 0x83f8, 0x080c, 0x898b, 0x00ce, 0x00e8,
-	0x700c, 0x9086, 0x2a00, 0x1138, 0x2001, 0x1960, 0x2004, 0x6842,
-	0x00a0, 0x0479, 0x00a0, 0x89ff, 0x090c, 0x0db4, 0x00c6, 0x00d6,
-	0x2d60, 0xa867, 0x0103, 0xa87b, 0x0003, 0x080c, 0x66bb, 0x080c,
-	0xbd24, 0x080c, 0x9e5f, 0x00de, 0x00ce, 0x080c, 0x9e2f, 0x009e,
-	0x0005, 0x9186, 0x0015, 0x1128, 0x2001, 0x1960, 0x2004, 0x6842,
-	0x0068, 0x918e, 0x0016, 0x1160, 0x00c6, 0x2d00, 0x2060, 0x080c,
-	0xd7c1, 0x080c, 0x820b, 0x080c, 0x9e2f, 0x00ce, 0x080c, 0x9e2f,
-	0x0005, 0x0026, 0x0036, 0x0046, 0x7228, 0xacb0, 0xabac, 0xd2f4,
-	0x0130, 0x2001, 0x1960, 0x2004, 0x6842, 0x0804, 0xa4cb, 0x00c6,
-	0x2d60, 0x080c, 0xb74f, 0x00ce, 0x6804, 0x9086, 0x0050, 0x1168,
-	0x00c6, 0x2d00, 0x2060, 0x6003, 0x0001, 0x6007, 0x0050, 0x080c,
-	0x83f8, 0x080c, 0x898b, 0x00ce, 0x04f0, 0x6800, 0x9086, 0x000f,
-	0x01a8, 0x89ff, 0x090c, 0x0db4, 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, 0xbeac,
-	0x080c, 0x898b, 0x0010, 0x080c, 0x9e2f, 0x004e, 0x003e, 0x002e,
-	0x0005, 0x00e6, 0x00d6, 0x0026, 0x7008, 0x9084, 0x00ff, 0x6210,
-	0x00b6, 0x2258, 0xba10, 0x00be, 0x9206, 0x1904, 0xa536, 0x700c,
-	0x6210, 0x00b6, 0x2258, 0xba14, 0x00be, 0x9206, 0x1904, 0xa536,
-	0x6038, 0x2068, 0x6824, 0xc0dc, 0x6826, 0x6a20, 0x9286, 0x0007,
-	0x0904, 0xa536, 0x9286, 0x0002, 0x0904, 0xa536, 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, 0xbb3b, 0x090c, 0x0db4, 0xa87b,
-	0x0003, 0x009e, 0x080c, 0xc1f5, 0x6007, 0x0085, 0x6003, 0x000b,
-	0x6023, 0x0002, 0x080c, 0x83f8, 0x080c, 0x898b, 0x00ce, 0x0030,
-	0x6038, 0x2070, 0x2001, 0x1960, 0x2004, 0x7042, 0x080c, 0x9e2f,
-	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,
-	0xae1c, 0x002e, 0x003e, 0x015e, 0x009e, 0x1904, 0xa5a5, 0x0096,
-	0x0156, 0x0036, 0x0026, 0x2b48, 0x9e90, 0x0014, 0x2019, 0x0006,
-	0x20a9, 0x0004, 0x080c, 0xae1c, 0x002e, 0x003e, 0x015e, 0x009e,
-	0x15a0, 0x7238, 0xba0a, 0x733c, 0xbb0e, 0xbc00, 0xc48d, 0xbc02,
-	0xa804, 0x9005, 0x1128, 0x00fe, 0x009e, 0x00be, 0x0804, 0xa233,
-	0x0096, 0x2048, 0xaa12, 0xab16, 0xac0a, 0x009e, 0x8006, 0x8006,
-	0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0002, 0x2009,
-	0x002b, 0xaaa0, 0xab9c, 0xaca8, 0xada4, 0x2031, 0x0000, 0x2041,
-	0x122f, 0x080c, 0xa332, 0x0130, 0x00fe, 0x009e, 0x080c, 0x9e2f,
-	0x00be, 0x0005, 0x080c, 0xa7cd, 0x0cb8, 0x2b78, 0x00f6, 0x080c,
-	0x2fe7, 0x080c, 0xc250, 0x00fe, 0x00c6, 0x080c, 0x9dd9, 0x2f00,
-	0x6012, 0x6017, 0x0000, 0x6023, 0x0001, 0x6007, 0x0001, 0x6003,
-	0x0001, 0x2001, 0x0007, 0x080c, 0x61a7, 0x080c, 0x61d3, 0x080c,
-	0x8440, 0x080c, 0x898b, 0x00ce, 0x0804, 0xa578, 0x2100, 0x91b2,
-	0x0053, 0x1a0c, 0x0db4, 0x91b2, 0x0040, 0x1a04, 0xa62e, 0x0002,
-	0xa61c, 0xa61c, 0xa612, 0xa61c, 0xa61c, 0xa61c, 0xa610, 0xa610,
-	0xa610, 0xa610, 0xa610, 0xa610, 0xa610, 0xa610, 0xa610, 0xa610,
-	0xa610, 0xa610, 0xa610, 0xa610, 0xa610, 0xa610, 0xa610, 0xa610,
-	0xa610, 0xa610, 0xa610, 0xa610, 0xa610, 0xa610, 0xa610, 0xa61c,
-	0xa610, 0xa61c, 0xa61c, 0xa610, 0xa610, 0xa610, 0xa610, 0xa610,
-	0xa612, 0xa610, 0xa610, 0xa610, 0xa610, 0xa610, 0xa610, 0xa610,
-	0xa610, 0xa610, 0xa61c, 0xa61c, 0xa610, 0xa610, 0xa610, 0xa610,
-	0xa610, 0xa610, 0xa610, 0xa610, 0xa610, 0xa61c, 0xa610, 0xa610,
-	0x080c, 0x0db4, 0x0066, 0x00b6, 0x6610, 0x2658, 0xb8bc, 0xc08c,
-	0xb8be, 0x00be, 0x006e, 0x0000, 0x6003, 0x0001, 0x6106, 0x9186,
-	0x0032, 0x0118, 0x080c, 0x8440, 0x0010, 0x080c, 0x83f8, 0x0126,
-	0x2091, 0x8000, 0x080c, 0x898b, 0x012e, 0x0005, 0x2600, 0x0002,
-	0xa642, 0xa642, 0xa642, 0xa61c, 0xa61c, 0xa642, 0xa642, 0xa642,
-	0xa642, 0xa61c, 0xa642, 0xa61c, 0xa642, 0xa61c, 0xa642, 0xa642,
-	0xa642, 0xa642, 0x080c, 0x0db4, 0x6004, 0x90b2, 0x0053, 0x1a0c,
-	0x0db4, 0x91b6, 0x0013, 0x0904, 0xa706, 0x91b6, 0x0027, 0x1904,
-	0xa6c1, 0x080c, 0x887f, 0x6004, 0x080c, 0xbd30, 0x01b0, 0x080c,
-	0xbd41, 0x01a8, 0x908e, 0x0021, 0x0904, 0xa6be, 0x908e, 0x0022,
-	0x1130, 0x080c, 0xa25f, 0x0904, 0xa6ba, 0x0804, 0xa6bb, 0x908e,
-	0x003d, 0x0904, 0xa6be, 0x0804, 0xa6b4, 0x080c, 0x3010, 0x2001,
-	0x0007, 0x080c, 0x61a7, 0x6010, 0x00b6, 0x2058, 0xb9a0, 0x00be,
-	0x080c, 0xa7cd, 0x9186, 0x007e, 0x1148, 0x2001, 0x1836, 0x2014,
-	0xc285, 0x080c, 0x6faa, 0x1108, 0xc2ad, 0x2202, 0x0036, 0x0026,
-	0x2019, 0x0028, 0x2110, 0x080c, 0xd81c, 0x002e, 0x003e, 0x0016,
-	0x0026, 0x0036, 0x2110, 0x2019, 0x0028, 0x080c, 0x8582, 0x0076,
-	0x903e, 0x080c, 0x8470, 0x6010, 0x00b6, 0x905d, 0x0100, 0x00be,
-	0x2c08, 0x080c, 0xd2d5, 0x007e, 0x003e, 0x002e, 0x001e, 0x080c,
-	0xc250, 0x0016, 0x080c, 0xbfad, 0x080c, 0x9e2f, 0x001e, 0x080c,
-	0x30e2, 0x080c, 0x898b, 0x0030, 0x080c, 0xbfad, 0x080c, 0x9e2f,
-	0x080c, 0x898b, 0x0005, 0x080c, 0xa7cd, 0x0cb0, 0x080c, 0xa809,
-	0x0c98, 0x9186, 0x0014, 0x1db0, 0x080c, 0x887f, 0x6004, 0x908e,
-	0x0022, 0x1118, 0x080c, 0xa25f, 0x0d68, 0x080c, 0x2fe7, 0x080c,
-	0xc250, 0x080c, 0xbd30, 0x1190, 0x080c, 0x3010, 0x6010, 0x00b6,
-	0x2058, 0xb9a0, 0x00be, 0x080c, 0xa7cd, 0x9186, 0x007e, 0x1128,
-	0x2001, 0x1836, 0x200c, 0xc185, 0x2102, 0x0870, 0x080c, 0xbd41,
-	0x1118, 0x080c, 0xa7cd, 0x0840, 0x6004, 0x908e, 0x0032, 0x1160,
-	0x00e6, 0x00f6, 0x2071, 0x189c, 0x2079, 0x0000, 0x080c, 0x3376,
-	0x00fe, 0x00ee, 0x0804, 0xa6b4, 0x6004, 0x908e, 0x0021, 0x0d48,
-	0x908e, 0x0022, 0x090c, 0xa7cd, 0x0804, 0xa6b4, 0x90b2, 0x0040,
-	0x1a04, 0xa7b6, 0x2008, 0x0002, 0xa74e, 0xa74f, 0xa752, 0xa755,
-	0xa758, 0xa75b, 0xa74c, 0xa74c, 0xa74c, 0xa74c, 0xa74c, 0xa74c,
-	0xa74c, 0xa74c, 0xa74c, 0xa74c, 0xa74c, 0xa74c, 0xa74c, 0xa74c,
-	0xa74c, 0xa74c, 0xa74c, 0xa74c, 0xa74c, 0xa74c, 0xa74c, 0xa74c,
-	0xa74c, 0xa74c, 0xa75e, 0xa76b, 0xa74c, 0xa76d, 0xa76b, 0xa74c,
-	0xa74c, 0xa74c, 0xa74c, 0xa74c, 0xa76b, 0xa76b, 0xa74c, 0xa74c,
-	0xa74c, 0xa74c, 0xa74c, 0xa74c, 0xa74c, 0xa74c, 0xa79d, 0xa76b,
-	0xa74c, 0xa767, 0xa74c, 0xa74c, 0xa74c, 0xa768, 0xa74c, 0xa74c,
-	0xa74c, 0xa76b, 0xa794, 0xa74c, 0x080c, 0x0db4, 0x00e0, 0x2001,
-	0x000b, 0x0420, 0x2001, 0x0003, 0x0408, 0x2001, 0x0005, 0x00f0,
-	0x2001, 0x0001, 0x00d8, 0x2001, 0x0009, 0x00c0, 0x080c, 0x887f,
-	0x6003, 0x0005, 0x080c, 0xc253, 0x080c, 0x898b, 0x0070, 0x0018,
-	0x0010, 0x080c, 0x61a7, 0x0804, 0xa7ae, 0x080c, 0x887f, 0x080c,
-	0xc253, 0x6003, 0x0004, 0x080c, 0x898b, 0x0005, 0x080c, 0x61a7,
-	0x080c, 0x887f, 0x6003, 0x0002, 0x0036, 0x2019, 0x1866, 0x2304,
-	0x9084, 0xff00, 0x1120, 0x2001, 0x195e, 0x201c, 0x0040, 0x8007,
-	0x909a, 0x0004, 0x0ec0, 0x8003, 0x801b, 0x831b, 0x9318, 0x631a,
-	0x003e, 0x080c, 0x898b, 0x0c08, 0x080c, 0x887f, 0x080c, 0xbfad,
-	0x080c, 0x9e2f, 0x080c, 0x898b, 0x08c0, 0x00e6, 0x00f6, 0x2071,
-	0x189c, 0x2079, 0x0000, 0x080c, 0x3376, 0x00fe, 0x00ee, 0x080c,
-	0x887f, 0x080c, 0x9e2f, 0x080c, 0x898b, 0x0838, 0x080c, 0x887f,
-	0x6003, 0x0002, 0x080c, 0xc253, 0x0804, 0x898b, 0x2600, 0x2008,
-	0x0002, 0xa7cb, 0xa7cb, 0xa7cb, 0xa7ae, 0xa7ae, 0xa7cb, 0xa7cb,
-	0xa7cb, 0xa7cb, 0xa7ae, 0xa7cb, 0xa7ae, 0xa7cb, 0xa7ae, 0xa7cb,
-	0xa7cb, 0xa7cb, 0xa7cb, 0x080c, 0x0db4, 0x00e6, 0x0096, 0x0026,
-	0x0016, 0x080c, 0xbb3b, 0x0568, 0x6014, 0x2048, 0xa864, 0x9086,
-	0x0139, 0x11a8, 0xa894, 0x9086, 0x0056, 0x1148, 0x080c, 0x5143,
-	0x0130, 0x2001, 0x0000, 0x900e, 0x2011, 0x4000, 0x0028, 0x2001,
-	0x0030, 0x900e, 0x2011, 0x4005, 0x080c, 0xc11a, 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, 0x0db4, 0x6604, 0x96b6,
-	0x004d, 0x1120, 0x080c, 0xc039, 0x0804, 0xa891, 0x6604, 0x96b6,
-	0x0043, 0x1120, 0x080c, 0xc082, 0x0804, 0xa891, 0x6604, 0x96b6,
-	0x004b, 0x1120, 0x080c, 0xc0ae, 0x0804, 0xa891, 0x6604, 0x96b6,
-	0x0033, 0x1120, 0x080c, 0xbfcf, 0x0804, 0xa891, 0x6604, 0x96b6,
-	0x0028, 0x1120, 0x080c, 0xbd7f, 0x0804, 0xa891, 0x6604, 0x96b6,
-	0x0029, 0x1120, 0x080c, 0xbdc0, 0x0804, 0xa891, 0x6604, 0x96b6,
-	0x001f, 0x1118, 0x080c, 0xa207, 0x04e0, 0x6604, 0x96b6, 0x0000,
-	0x1118, 0x080c, 0xa53c, 0x04a8, 0x6604, 0x96b6, 0x0022, 0x1118,
-	0x080c, 0xa240, 0x0470, 0x6604, 0x96b6, 0x0035, 0x1118, 0x080c,
-	0xa350, 0x0438, 0x6604, 0x96b6, 0x0039, 0x1118, 0x080c, 0xa4d1,
-	0x0400, 0x6604, 0x96b6, 0x003d, 0x1118, 0x080c, 0xa278, 0x00c8,
-	0x6604, 0x96b6, 0x0044, 0x1118, 0x080c, 0xa2b4, 0x0090, 0x6604,
-	0x96b6, 0x0049, 0x1118, 0x080c, 0xa2df, 0x0058, 0x91b6, 0x0015,
-	0x1110, 0x0063, 0x0030, 0x91b6, 0x0016, 0x1128, 0x00be, 0x0804,
-	0xab51, 0x00be, 0x0005, 0x080c, 0x9ec4, 0x0cd8, 0xa8ae, 0xa8b1,
-	0xa8ae, 0xa8f5, 0xa8ae, 0xaa85, 0xab5e, 0xa8ae, 0xa8ae, 0xab2b,
-	0xa8ae, 0xab3f, 0x0096, 0x080c, 0x1511, 0x6014, 0x2048, 0xa800,
-	0x2048, 0xa867, 0x0103, 0x009e, 0x0804, 0x9e2f, 0xa001, 0xa001,
-	0x0005, 0x00e6, 0x2071, 0x1800, 0x708c, 0x9086, 0x0074, 0x1540,
-	0x080c, 0xd2a6, 0x11b0, 0x6010, 0x00b6, 0x2058, 0x7030, 0xd08c,
-	0x0128, 0xb800, 0xd0bc, 0x0110, 0xc0c5, 0xb802, 0x00e9, 0x00be,
-	0x2001, 0x0006, 0x080c, 0x61a7, 0x080c, 0x3010, 0x080c, 0x9e2f,
-	0x0088, 0x2001, 0x000a, 0x080c, 0x61a7, 0x080c, 0x3010, 0x6003,
-	0x0001, 0x6007, 0x0001, 0x080c, 0x8440, 0x080c, 0x898b, 0x0010,
-	0x080c, 0xaa70, 0x00ee, 0x0005, 0x00d6, 0xb800, 0xd084, 0x0158,
-	0x9006, 0x080c, 0x6193, 0x2069, 0x185b, 0x6804, 0x0020, 0x2001,
-	0x0006, 0x080c, 0x61d3, 0x00de, 0x0005, 0x00b6, 0x0096, 0x00d6,
-	0x2011, 0x1823, 0x2204, 0x9086, 0x0074, 0x1904, 0xaa47, 0x6010,
-	0x2058, 0xbaa0, 0x9286, 0x007e, 0x1120, 0x080c, 0xaca2, 0x0804,
-	0xa9ac, 0x00d6, 0x080c, 0x6faa, 0x0198, 0x0026, 0x2011, 0x0010,
-	0x080c, 0x659e, 0x002e, 0x05c8, 0x080c, 0x53ae, 0x1540, 0x6014,
-	0x2048, 0xa807, 0x0000, 0xa867, 0x0103, 0xa833, 0xdead, 0x00f8,
-	0x0026, 0x2011, 0x8008, 0x080c, 0x659e, 0x002e, 0x0530, 0x6014,
-	0x2048, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x1140, 0x2001,
-	0x0030, 0x900e, 0x2011, 0x4009, 0x080c, 0xc11a, 0x0040, 0x6014,
-	0x2048, 0xa807, 0x0000, 0xa867, 0x0103, 0xa833, 0xdead, 0x6010,
-	0x2058, 0xb9a0, 0x0016, 0x080c, 0x3010, 0x080c, 0x9e2f, 0x001e,
-	0x080c, 0x30e2, 0x00de, 0x0804, 0xaa4a, 0x00de, 0x080c, 0xac97,
-	0x6010, 0x2058, 0xbaa0, 0x9286, 0x0080, 0x1510, 0x6014, 0x9005,
-	0x01a8, 0x2048, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x1140,
-	0x2001, 0x0000, 0x900e, 0x2011, 0x4000, 0x080c, 0xc11a, 0x0030,
-	0xa807, 0x0000, 0xa867, 0x0103, 0xa833, 0x0200, 0x2001, 0x0006,
-	0x080c, 0x61a7, 0x080c, 0x3010, 0x080c, 0x9e2f, 0x0804, 0xaa4a,
-	0x080c, 0xaa58, 0x6014, 0x9005, 0x0190, 0x2048, 0xa868, 0xd0f4,
-	0x01e8, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x1d08, 0x2001,
-	0x0000, 0x900e, 0x2011, 0x4000, 0x080c, 0xc11a, 0x08f8, 0x080c,
-	0xaa4e, 0x0160, 0x9006, 0x080c, 0x6193, 0x2001, 0x0004, 0x080c,
-	0x61d3, 0x2001, 0x0007, 0x080c, 0x61a7, 0x08a0, 0x2001, 0x0004,
-	0x080c, 0x61a7, 0x6003, 0x0001, 0x6007, 0x0003, 0x080c, 0x8440,
-	0x080c, 0x898b, 0x0804, 0xaa4a, 0xb85c, 0xd0e4, 0x01d0, 0x080c,
-	0xbf4f, 0x080c, 0x6faa, 0x0118, 0xd0dc, 0x1904, 0xa96e, 0x2011,
-	0x1836, 0x2204, 0xc0ad, 0x2012, 0x2001, 0x0002, 0x00f6, 0x2079,
-	0x0100, 0x78e3, 0x0000, 0x080c, 0x26e4, 0x78e2, 0x00fe, 0x0804,
-	0xa96e, 0x080c, 0xbf8c, 0x2011, 0x1836, 0x2204, 0xc0a5, 0x2012,
-	0x0006, 0x080c, 0xd3ff, 0x000e, 0x1904, 0xa96e, 0xc0b5, 0x2012,
-	0x2001, 0x0006, 0x080c, 0x61a7, 0x9006, 0x080c, 0x6193, 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, 0x26b9, 0x00f6, 0x2100, 0x900e, 0x080c,
-	0x2670, 0x795a, 0x00fe, 0x9186, 0x0081, 0x01d8, 0x2009, 0x0081,
-	0x00c8, 0x2009, 0x00ef, 0x00f6, 0x2079, 0x0100, 0x79ea, 0x7932,
-	0x7936, 0x780c, 0xc0b5, 0x780e, 0x00fe, 0x080c, 0x26b9, 0x00f6,
-	0x2079, 0x1800, 0x797e, 0x2100, 0x900e, 0x080c, 0x2670, 0x795a,
-	0x00fe, 0x8108, 0x080c, 0x61f6, 0x2b00, 0x00ce, 0x1904, 0xa96e,
-	0x6012, 0x2009, 0x180f, 0x210c, 0xd19c, 0x0150, 0x2009, 0x027c,
-	0x210c, 0x918c, 0x00ff, 0xb912, 0x2009, 0x027d, 0x210c, 0xb916,
-	0x2001, 0x0002, 0x080c, 0x61a7, 0x6023, 0x0001, 0x6003, 0x0001,
-	0x6007, 0x0002, 0x080c, 0x8440, 0x080c, 0x898b, 0x0018, 0x080c,
-	0xa7cd, 0x0431, 0x00de, 0x009e, 0x00be, 0x0005, 0x2001, 0x1810,
-	0x2004, 0xd0a4, 0x0120, 0x2001, 0x185c, 0x2004, 0xd0ac, 0x0005,
-	0x00e6, 0x080c, 0xd875, 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, 0x61a7, 0x080c, 0x53ae, 0x1120,
-	0x2001, 0x0007, 0x080c, 0x61d3, 0x080c, 0x3010, 0x6020, 0x9086,
-	0x000a, 0x1108, 0x0005, 0x0804, 0x9e2f, 0x00b6, 0x00e6, 0x0026,
-	0x0016, 0x2071, 0x1800, 0x708c, 0x9086, 0x0014, 0x1904, 0xab22,
-	0x00d6, 0x080c, 0x6faa, 0x0198, 0x0026, 0x2011, 0x0010, 0x080c,
-	0x659e, 0x002e, 0x05c8, 0x080c, 0x53ae, 0x1540, 0x6014, 0x2048,
-	0xa807, 0x0000, 0xa867, 0x0103, 0xa833, 0xdead, 0x00f8, 0x0026,
-	0x2011, 0x8008, 0x080c, 0x659e, 0x002e, 0x0530, 0x6014, 0x2048,
-	0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x1140, 0x2001, 0x0030,
-	0x900e, 0x2011, 0x4009, 0x080c, 0xc11a, 0x0040, 0x6014, 0x2048,
-	0xa807, 0x0000, 0xa867, 0x0103, 0xa833, 0xdead, 0x6010, 0x2058,
-	0xb9a0, 0x0016, 0x080c, 0x3010, 0x080c, 0x9e2f, 0x001e, 0x080c,
-	0x30e2, 0x00de, 0x0804, 0xab26, 0x00de, 0x080c, 0x53ae, 0x1170,
-	0x6014, 0x9005, 0x1158, 0x0036, 0x0046, 0x6010, 0x2058, 0xbba0,
-	0x2021, 0x0006, 0x080c, 0x4a91, 0x004e, 0x003e, 0x00d6, 0x6010,
-	0x2058, 0x080c, 0x62f1, 0x080c, 0xa8e4, 0x00de, 0x080c, 0xad68,
-	0x1588, 0x6010, 0x2058, 0xb890, 0x9005, 0x0560, 0x2001, 0x0006,
-	0x080c, 0x61a7, 0x0096, 0x6014, 0x904d, 0x01d0, 0xa864, 0x9084,
+	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,
+	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, 0xc11a, 0x0060, 0xa864, 0x9084, 0x00ff, 0x9086,
-	0x0029, 0x0130, 0xa807, 0x0000, 0xa867, 0x0103, 0xa833, 0x0200,
-	0x009e, 0x080c, 0x3010, 0x6020, 0x9086, 0x000a, 0x0138, 0x080c,
-	0x9e2f, 0x0020, 0x080c, 0xa7cd, 0x080c, 0xaa70, 0x001e, 0x002e,
-	0x00ee, 0x00be, 0x0005, 0x2011, 0x1823, 0x2204, 0x9086, 0x0014,
-	0x1160, 0x2001, 0x0002, 0x080c, 0x61a7, 0x6003, 0x0001, 0x6007,
-	0x0001, 0x080c, 0x8440, 0x0804, 0x898b, 0x0804, 0xaa70, 0x2030,
-	0x2011, 0x1823, 0x2204, 0x9086, 0x0004, 0x1148, 0x96b6, 0x000b,
-	0x1120, 0x2001, 0x0007, 0x080c, 0x61a7, 0x0804, 0x9e2f, 0x0804,
-	0xaa70, 0x0002, 0xa8ae, 0xab69, 0xa8ae, 0xaba8, 0xa8ae, 0xac53,
-	0xab5e, 0xa8ae, 0xa8ae, 0xac66, 0xa8ae, 0xac76, 0x6604, 0x9686,
-	0x0003, 0x0904, 0xaa85, 0x96b6, 0x001e, 0x1110, 0x080c, 0x9e2f,
-	0x0005, 0x00b6, 0x00d6, 0x00c6, 0x080c, 0xac86, 0x11a0, 0x9006,
-	0x080c, 0x6193, 0x080c, 0x2fe7, 0x080c, 0xc250, 0x2001, 0x0002,
-	0x080c, 0x61a7, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x8440,
-	0x080c, 0x898b, 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, 0x2fe7,
-	0x080c, 0xc250, 0x080c, 0xaa70, 0x00ce, 0x00de, 0x00be, 0x0005,
-	0x0096, 0x00b6, 0x0026, 0x9016, 0x080c, 0xac94, 0x00d6, 0x2069,
-	0x1954, 0x2d04, 0x9005, 0x0168, 0x6010, 0x2058, 0xb8a0, 0x9086,
-	0x007e, 0x1138, 0x2069, 0x181f, 0x2d04, 0x8000, 0x206a, 0x00de,
-	0x0010, 0x00de, 0x0088, 0x9006, 0x080c, 0x6193, 0x2001, 0x0002,
-	0x080c, 0x61a7, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x8440,
-	0x080c, 0x898b, 0x0804, 0xac23, 0x080c, 0xbb3b, 0x01b0, 0x6014,
-	0x2048, 0xa864, 0x2010, 0x9086, 0x0139, 0x1138, 0x6007, 0x0016,
-	0x2001, 0x0002, 0x080c, 0xc174, 0x00b0, 0x6014, 0x2048, 0xa864,
-	0xd0fc, 0x0118, 0x2001, 0x0001, 0x0ca8, 0x2001, 0x180e, 0x2004,
-	0xd0dc, 0x0148, 0x6010, 0x2058, 0xb840, 0x9084, 0x00ff, 0x9005,
-	0x1110, 0x9006, 0x0c38, 0x080c, 0xa7cd, 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, 0x61a7, 0x2001, 0x0028, 0x601a, 0x6007, 0x0052,
-	0x0010, 0x080c, 0xaa70, 0x002e, 0x00be, 0x009e, 0x0005, 0x9286,
-	0x0139, 0x0160, 0x6014, 0x2048, 0x080c, 0xbb3b, 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, 0x5c78, 0x00ee, 0x0010,
-	0x080c, 0x2fe7, 0x0870, 0x080c, 0xac94, 0x1160, 0x2001, 0x0004,
-	0x080c, 0x61a7, 0x6003, 0x0001, 0x6007, 0x0003, 0x080c, 0x8440,
-	0x0804, 0x898b, 0x080c, 0xa7cd, 0x0804, 0xaa70, 0x0469, 0x1160,
-	0x2001, 0x0008, 0x080c, 0x61a7, 0x6003, 0x0001, 0x6007, 0x0005,
-	0x080c, 0x8440, 0x0804, 0x898b, 0x0804, 0xaa70, 0x00e9, 0x1160,
-	0x2001, 0x000a, 0x080c, 0x61a7, 0x6003, 0x0001, 0x6007, 0x0001,
-	0x080c, 0x8440, 0x0804, 0x898b, 0x0804, 0xaa70, 0x2009, 0x026e,
-	0x2104, 0x9086, 0x0003, 0x1138, 0x2009, 0x026f, 0x2104, 0x9084,
-	0xff00, 0x9086, 0x2a00, 0x0005, 0x9085, 0x0001, 0x0005, 0x00b6,
-	0x00c6, 0x0016, 0x6110, 0x2158, 0x080c, 0x6265, 0x001e, 0x00ce,
-	0x00be, 0x0005, 0x00b6, 0x00f6, 0x00e6, 0x00d6, 0x0036, 0x0016,
-	0x6010, 0x2058, 0x2009, 0x1836, 0x2104, 0x9085, 0x0003, 0x200a,
-	0x080c, 0xad3a, 0x0560, 0x2009, 0x1836, 0x2104, 0xc0cd, 0x200a,
-	0x080c, 0x6576, 0x0158, 0x9006, 0x2020, 0x2009, 0x002a, 0x080c,
-	0xd564, 0x2001, 0x180c, 0x200c, 0xc195, 0x2102, 0x2019, 0x002a,
-	0x2009, 0x0001, 0x080c, 0x2fb2, 0x00e6, 0x2071, 0x1800, 0x080c,
-	0x2dc8, 0x00ee, 0x00c6, 0x0156, 0x20a9, 0x0781, 0x2009, 0x007f,
-	0x080c, 0x30e2, 0x8108, 0x1f04, 0xacd8, 0x015e, 0x00ce, 0x080c,
-	0xac97, 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,
-	0x26b9, 0x080c, 0x6faa, 0x0170, 0x2071, 0x0260, 0x2069, 0x195a,
-	0x7048, 0x206a, 0x704c, 0x6806, 0x7050, 0x680a, 0x7054, 0x680e,
-	0x080c, 0xbf4f, 0x0040, 0x2001, 0x0006, 0x080c, 0x61a7, 0x080c,
-	0x3010, 0x080c, 0x9e2f, 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, 0xae1c,
-	0x1148, 0x2011, 0x027a, 0x20a9, 0x0004, 0x2019, 0x0006, 0x080c,
-	0xae1c, 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, 0xadf4,
-	0x080c, 0xd595, 0x0904, 0xaded, 0x6720, 0x9786, 0x0007, 0x0904,
-	0xaded, 0x2500, 0x9c06, 0x0904, 0xaded, 0x2400, 0x9c06, 0x05e8,
-	0x3e08, 0x9186, 0x0002, 0x1148, 0x6010, 0x9005, 0x0130, 0x00b6,
-	0x2058, 0xb800, 0x00be, 0xd0bc, 0x1580, 0x00c6, 0x6000, 0x9086,
-	0x0004, 0x1110, 0x080c, 0x191f, 0x9786, 0x000a, 0x0148, 0x080c,
-	0xbd41, 0x1130, 0x00ce, 0x080c, 0xa7cd, 0x080c, 0x9e5f, 0x00e8,
-	0x6014, 0x2048, 0x080c, 0xbb3b, 0x01a8, 0x9786, 0x0003, 0x1530,
-	0xa867, 0x0103, 0xa87c, 0xd0cc, 0x0130, 0x0096, 0xa878, 0x2048,
-	0x080c, 0x0f9d, 0x009e, 0xab7a, 0xa877, 0x0000, 0x080c, 0x6893,
-	0x080c, 0xbd24, 0x080c, 0x9e5f, 0x00ce, 0x9ce0, 0x0018, 0x7064,
-	0x9c02, 0x1210, 0x0804, 0xad9b, 0x012e, 0x000e, 0x002e, 0x004e,
-	0x005e, 0x007e, 0x00ce, 0x009e, 0x00ee, 0x0005, 0x9786, 0x0006,
-	0x1118, 0x080c, 0xd50f, 0x0c30, 0x9786, 0x000a, 0x0998, 0x0880,
-	0x220c, 0x2304, 0x9106, 0x1130, 0x8210, 0x8318, 0x1f04, 0xae08,
-	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, 0x0db4, 0x080c, 0xbd30, 0x0120, 0x080c, 0xbd41,
-	0x0168, 0x0028, 0x080c, 0x3010, 0x080c, 0xbd41, 0x0138, 0x080c,
-	0x887f, 0x080c, 0x9e2f, 0x080c, 0x898b, 0x0005, 0x080c, 0xa7cd,
-	0x0cb0, 0x9182, 0x0054, 0x1220, 0x9182, 0x0040, 0x0208, 0x000a,
-	0x0005, 0xae7d, 0xae7d, 0xae7d, 0xae7d, 0xae7d, 0xae7d, 0xae7d,
-	0xae7d, 0xae7d, 0xae7d, 0xae7d, 0xae7f, 0xae7f, 0xae7f, 0xae7f,
-	0xae7d, 0xae7d, 0xae7d, 0xae7f, 0xae7d, 0x080c, 0x0db4, 0x600b,
-	0xffff, 0x6003, 0x0001, 0x6106, 0x080c, 0x83f8, 0x0126, 0x2091,
-	0x8000, 0x080c, 0x898b, 0x012e, 0x0005, 0x9186, 0x0013, 0x1128,
-	0x6004, 0x9082, 0x0040, 0x0804, 0xaf34, 0x9186, 0x0027, 0x1520,
-	0x080c, 0x887f, 0x080c, 0x2fe7, 0x080c, 0xc250, 0x0096, 0x6114,
-	0x2148, 0x080c, 0xbb3b, 0x0198, 0x080c, 0xbd41, 0x1118, 0x080c,
-	0xa7cd, 0x0068, 0xa867, 0x0103, 0xa87b, 0x0029, 0xa877, 0x0000,
-	0xa97c, 0xc1c5, 0xa97e, 0x080c, 0x68a0, 0x080c, 0xbd24, 0x009e,
-	0x080c, 0x9e2f, 0x0804, 0x898b, 0x9186, 0x0014, 0x1120, 0x6004,
-	0x9082, 0x0040, 0x04a0, 0x9186, 0x0046, 0x0150, 0x9186, 0x0045,
-	0x0138, 0x9186, 0x0053, 0x0120, 0x9186, 0x0048, 0x190c, 0x0db4,
-	0x2001, 0x0109, 0x2004, 0xd084, 0x0508, 0x0126, 0x2091, 0x2800,
-	0x0006, 0x0016, 0x0026, 0x0036, 0x00f6, 0x00e6, 0x00c6, 0x2079,
-	0x19bf, 0x2071, 0x1800, 0x2061, 0x0100, 0x080c, 0x82e4, 0x00ce,
-	0x00ee, 0x00fe, 0x003e, 0x002e, 0x001e, 0x000e, 0x012e, 0xa001,
-	0x6000, 0x9086, 0x0002, 0x1110, 0x0804, 0xaf72, 0x0005, 0x0002,
-	0xaf0e, 0xaf0c, 0xaf0c, 0xaf0c, 0xaf0c, 0xaf0c, 0xaf0c, 0xaf0c,
-	0xaf0c, 0xaf0c, 0xaf0c, 0xaf29, 0xaf29, 0xaf29, 0xaf29, 0xaf0c,
-	0xaf29, 0xaf0c, 0xaf29, 0xaf0c, 0x080c, 0x0db4, 0x080c, 0x887f,
-	0x0096, 0x6114, 0x2148, 0x080c, 0xbb3b, 0x0168, 0xa867, 0x0103,
-	0xa87b, 0x0006, 0xa877, 0x0000, 0xa880, 0xc0ec, 0xa882, 0x080c,
-	0x68a0, 0x080c, 0xbd24, 0x009e, 0x080c, 0x9e2f, 0x080c, 0x898b,
-	0x0005, 0x080c, 0x887f, 0x080c, 0xbd41, 0x090c, 0xa7cd, 0x080c,
-	0x9e2f, 0x080c, 0x898b, 0x0005, 0x0002, 0xaf4b, 0xaf49, 0xaf49,
-	0xaf49, 0xaf49, 0xaf49, 0xaf49, 0xaf49, 0xaf49, 0xaf49, 0xaf49,
-	0xaf62, 0xaf62, 0xaf62, 0xaf62, 0xaf49, 0xaf6c, 0xaf49, 0xaf62,
-	0xaf49, 0x080c, 0x0db4, 0x0096, 0x080c, 0x887f, 0x6014, 0x2048,
-	0x2001, 0x1960, 0x2004, 0x6042, 0xa97c, 0xd1ac, 0x0140, 0x6003,
-	0x0004, 0xa87c, 0x9085, 0x0400, 0xa87e, 0x009e, 0x0005, 0x6003,
-	0x0002, 0x0cb8, 0x080c, 0x887f, 0x080c, 0xc253, 0x080c, 0xc258,
-	0x6003, 0x000f, 0x0804, 0x898b, 0x080c, 0x887f, 0x080c, 0x9e2f,
-	0x0804, 0x898b, 0x9182, 0x0054, 0x1220, 0x9182, 0x0040, 0x0208,
-	0x000a, 0x0005, 0xaf8e, 0xaf8e, 0xaf8e, 0xaf8e, 0xaf8e, 0xaf90,
-	0xb06d, 0xaf8e, 0xb0a1, 0xaf8e, 0xaf8e, 0xaf8e, 0xaf8e, 0xaf8e,
-	0xaf8e, 0xaf8e, 0xaf8e, 0xaf8e, 0xaf8e, 0xb0a1, 0x080c, 0x0db4,
-	0x00b6, 0x0096, 0x6114, 0x2148, 0x7644, 0x96b4, 0x0fff, 0x86ff,
-	0x1528, 0x6010, 0x2058, 0xb800, 0xd0bc, 0x1904, 0xb05c, 0xa87b,
-	0x0000, 0xa867, 0x0103, 0xae76, 0xa87c, 0xd0ac, 0x0128, 0xa834,
-	0xa938, 0x9115, 0x190c, 0xb236, 0x080c, 0x66bb, 0x6210, 0x2258,
-	0xba3c, 0x82ff, 0x0110, 0x8211, 0xba3e, 0x7044, 0xd0e4, 0x1904,
-	0xb040, 0x080c, 0x9e2f, 0x009e, 0x00be, 0x0005, 0x968c, 0x0c00,
-	0x0150, 0x6010, 0x2058, 0xb800, 0xd0bc, 0x1904, 0xb044, 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, 0xaf97, 0x735c, 0xab86, 0x83ff, 0x0170, 0x938a, 0x0009,
-	0x0210, 0x2019, 0x0008, 0x0036, 0x2308, 0x2019, 0x0018, 0x2011,
-	0x0025, 0x080c, 0xb724, 0x003e, 0xd6cc, 0x0904, 0xafac, 0x7154,
-	0xa98a, 0x81ff, 0x0904, 0xafac, 0x9192, 0x0021, 0x1278, 0x8304,
-	0x9098, 0x0018, 0x2011, 0x0029, 0x080c, 0xb724, 0x2011, 0x0205,
-	0x2013, 0x0000, 0x080c, 0xc1e0, 0x0804, 0xafac, 0xa868, 0xd0fc,
-	0x0120, 0x2009, 0x0020, 0xa98a, 0x0c50, 0x00a6, 0x2950, 0x080c,
-	0xb6c3, 0x00ae, 0x080c, 0xc1e0, 0x080c, 0xb714, 0x0804, 0xafae,
-	0x080c, 0xbe39, 0x0804, 0xafbb, 0xa87c, 0xd0ac, 0x0904, 0xafc7,
-	0xa880, 0xd0bc, 0x1904, 0xafc7, 0x7348, 0xa838, 0x9306, 0x11c8,
-	0x734c, 0xa834, 0x931e, 0x0904, 0xafc7, 0xd6d4, 0x0190, 0xab38,
-	0x9305, 0x0904, 0xafc7, 0x0068, 0xa87c, 0xd0ac, 0x0904, 0xaf9f,
-	0xa838, 0xa934, 0x9105, 0x0904, 0xaf9f, 0xa880, 0xd0bc, 0x1904,
-	0xaf9f, 0x080c, 0xbe73, 0x0804, 0xafbb, 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, 0x1a69, 0x080c, 0x845d, 0x080c, 0x8a68, 0x009e,
-	0x0005, 0x0005, 0x9182, 0x0054, 0x1220, 0x9182, 0x0040, 0x0208,
-	0x000a, 0x0005, 0xb0be, 0xb0be, 0xb0be, 0xb0be, 0xb0be, 0xb0c0,
-	0xb156, 0xb0be, 0xb0be, 0xb16d, 0xb1f9, 0xb0be, 0xb0be, 0xb0be,
-	0xb0be, 0xb20e, 0xb0be, 0xb0be, 0xb0be, 0xb0be, 0x080c, 0x0db4,
-	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, 0xb151, 0x9694, 0xff00, 0x9284, 0x0c00, 0x0120,
-	0x7048, 0xb092, 0x704c, 0xb08e, 0x9284, 0x0300, 0x0904, 0xb151,
-	0x080c, 0x0feb, 0x090c, 0x0db4, 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,
-	0xb724, 0x003e, 0xd6cc, 0x01e8, 0x7154, 0xa98a, 0x81ff, 0x01c8,
-	0x9192, 0x0021, 0x1260, 0x8304, 0x9098, 0x0018, 0x2011, 0x0029,
-	0x080c, 0xb724, 0x2011, 0x0205, 0x2013, 0x0000, 0x0050, 0xb068,
-	0xd0fc, 0x0120, 0x2009, 0x0020, 0xa98a, 0x0c68, 0x2950, 0x080c,
-	0xb6c3, 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, 0x1a69, 0x0804, 0x9394, 0x6003, 0x0002, 0x6004,
-	0x9086, 0x0040, 0x11c8, 0x0096, 0x6014, 0x2048, 0xa87c, 0xd0ac,
-	0x0160, 0x601c, 0xd084, 0x1130, 0x00f6, 0x2c00, 0x2078, 0x080c,
-	0x164a, 0x00fe, 0x6003, 0x0004, 0x0010, 0x6003, 0x0002, 0x009e,
-	0x080c, 0x887f, 0x080c, 0x898b, 0x0096, 0x2001, 0x1960, 0x2004,
-	0x6042, 0x080c, 0x893b, 0x080c, 0x8a68, 0x6114, 0x2148, 0xa97c,
-	0xd1e4, 0x0904, 0xb1f4, 0xd1cc, 0x05a8, 0xa978, 0xa868, 0xd0fc,
-	0x0538, 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, 0xa87e,
-	0x001e, 0xa874, 0x0006, 0x2148, 0x080c, 0x0f9d, 0x001e, 0x0440,
-	0x0016, 0x080c, 0x0f9d, 0x009e, 0xa974, 0x0016, 0x080c, 0xb714,
+	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,
+	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, 0x66bb, 0x001e,
-	0xd1e4, 0x1120, 0x080c, 0x9e2f, 0x009e, 0x0005, 0x080c, 0xbe39,
-	0x0cd8, 0x6004, 0x9086, 0x0040, 0x1120, 0x080c, 0x887f, 0x080c,
-	0x898b, 0x2019, 0x0001, 0x080c, 0x96e9, 0x6003, 0x0002, 0x080c,
-	0xc258, 0x080c, 0x893b, 0x080c, 0x8a68, 0x0005, 0x6004, 0x9086,
-	0x0040, 0x1120, 0x080c, 0x887f, 0x080c, 0x898b, 0x2019, 0x0001,
-	0x080c, 0x96e9, 0x080c, 0x893b, 0x080c, 0x2fe7, 0x080c, 0xc250,
-	0x0096, 0x6114, 0x2148, 0x080c, 0xbb3b, 0x0150, 0xa867, 0x0103,
-	0xa87b, 0x0029, 0xa877, 0x0000, 0x080c, 0x68a0, 0x080c, 0xbd24,
-	0x009e, 0x080c, 0x9e2f, 0x080c, 0x8a68, 0x0005, 0xa87b, 0x0015,
+	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, 0xb269, 0xb269, 0xb269,
-	0xb269, 0xb269, 0xb26b, 0xb269, 0xb269, 0xb311, 0xb269, 0xb269,
-	0xb269, 0xb269, 0xb269, 0xb269, 0xb269, 0xb269, 0xb269, 0xb269,
-	0xb442, 0x080c, 0x0db4, 0x0076, 0x00a6, 0x00e6, 0x0096, 0x2071,
+	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, 0xb30a, 0x9694, 0xff00,
+	0x8211, 0xba3e, 0x00be, 0x86ff, 0x0904, 0xb5c2, 0x9694, 0xff00,
 	0x9284, 0x0c00, 0x0120, 0x7048, 0xb092, 0x704c, 0xb08e, 0x9284,
-	0x0300, 0x0904, 0xb30a, 0x9686, 0x0100, 0x1130, 0x7064, 0x9005,
-	0x1118, 0xc6c4, 0xb676, 0x0c38, 0x080c, 0x0feb, 0x090c, 0x0db4,
+	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,
@@ -5519,1384 +5606,1542 @@
 	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, 0xb724, 0x003e, 0xd6cc, 0x01e8, 0x7154, 0xa98a, 0x81ff,
+	0x080c, 0xb9e8, 0x003e, 0xd6cc, 0x01e8, 0x7154, 0xa98a, 0x81ff,
 	0x01c8, 0x9192, 0x0021, 0x1260, 0x8304, 0x9098, 0x0018, 0x2011,
-	0x0029, 0x080c, 0xb724, 0x2011, 0x0205, 0x2013, 0x0000, 0x0050,
+	0x0029, 0x080c, 0xb9e8, 0x2011, 0x0205, 0x2013, 0x0000, 0x0050,
 	0xb068, 0xd0fc, 0x0120, 0x2009, 0x0020, 0xa98a, 0x0c68, 0x2950,
-	0x080c, 0xb6c3, 0x080c, 0x18ed, 0x009e, 0x00ee, 0x00ae, 0x007e,
+	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, 0xb43d, 0x6043, 0x0000, 0x6010,
+	0x0002, 0xa97c, 0xd1e4, 0x0904, 0xb6f6, 0x6043, 0x0000, 0x6010,
 	0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x1500, 0xd1cc, 0x0904,
-	0xb40c, 0xa978, 0xa868, 0xd0fc, 0x0904, 0xb3cd, 0x0016, 0xa87c,
+	0xb6c5, 0xa978, 0xa868, 0xd0fc, 0x0904, 0xb686, 0x0016, 0xa87c,
 	0x0006, 0xa880, 0x0006, 0x00a6, 0x2150, 0xb174, 0x9184, 0x00ff,
-	0x90b6, 0x0002, 0x0904, 0xb39b, 0x9086, 0x0028, 0x1904, 0xb387,
-	0xa87b, 0x001c, 0xb07b, 0x001c, 0x0804, 0xb3a3, 0x6024, 0xd0f4,
+	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, 0x0f9d, 0x009e, 0x080c, 0xbe73, 0x0804, 0xb43d, 0xd1dc,
-	0x0158, 0xa87b, 0x0015, 0xb07b, 0x0015, 0x080c, 0xc103, 0x0118,
+	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, 0xb236, 0xa87c, 0xb07e, 0xa890, 0xb092, 0xa88c,
+	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, 0xa87e, 0x080c, 0xc1e0, 0x001e, 0xa874, 0x0006, 0x2148,
-	0x080c, 0x0f9d, 0x001e, 0x0804, 0xb439, 0x0016, 0x00a6, 0x2150,
-	0xb174, 0x9184, 0x00ff, 0x90b6, 0x0002, 0x01e0, 0x9086, 0x0028,
-	0x1128, 0xa87b, 0x001c, 0xb07b, 0x001c, 0x00e0, 0xd1dc, 0x0158,
-	0xa87b, 0x0015, 0xb07b, 0x0015, 0x080c, 0xc103, 0x0118, 0xb174,
-	0xc1dc, 0xb176, 0x0078, 0xd1d4, 0x0128, 0xa87b, 0x0007, 0xb07b,
-	0x0007, 0x0040, 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115,
-	0x190c, 0xb236, 0xa890, 0xb092, 0xa88c, 0xb08e, 0xa87c, 0xb07e,
-	0x00ae, 0x080c, 0x0f9d, 0x009e, 0x080c, 0xc1e0, 0xa974, 0x0016,
-	0x080c, 0xb714, 0x001e, 0x0468, 0xa867, 0x0103, 0xa974, 0x9184,
-	0x00ff, 0x90b6, 0x0002, 0x01b0, 0x9086, 0x0028, 0x1118, 0xa87b,
-	0x001c, 0x00d0, 0xd1dc, 0x0148, 0xa87b, 0x0015, 0x080c, 0xc103,
-	0x0118, 0xa974, 0xc1dc, 0xa976, 0x0078, 0xd1d4, 0x0118, 0xa87b,
-	0x0007, 0x0050, 0xa87b, 0x0000, 0xa87c, 0xd0ac, 0x0128, 0xa834,
-	0xa938, 0x9115, 0x190c, 0xb236, 0xa974, 0x0016, 0x080c, 0x66bb,
-	0x001e, 0xd1e4, 0x1120, 0x080c, 0x9e2f, 0x009e, 0x0005, 0x080c,
-	0xbe39, 0x0cd8, 0x6114, 0x0096, 0x2148, 0xa97c, 0xd1e4, 0x190c,
-	0x190b, 0x009e, 0x0005, 0x080c, 0x887f, 0x0010, 0x080c, 0x893b,
-	0x080c, 0xbb3b, 0x01f0, 0x0096, 0x6114, 0x2148, 0x080c, 0xbd41,
-	0x1118, 0x080c, 0xa7cd, 0x00a0, 0xa867, 0x0103, 0x2009, 0x180c,
-	0x210c, 0xd18c, 0x11b8, 0xd184, 0x1190, 0x6108, 0xa97a, 0x918e,
-	0x0029, 0x1110, 0x080c, 0xd80d, 0xa877, 0x0000, 0x080c, 0x68a0,
-	0x009e, 0x080c, 0x9e2f, 0x080c, 0x898b, 0x0804, 0x8a68, 0xa87b,
-	0x0004, 0x0c90, 0xa87b, 0x0004, 0x0c78, 0x9182, 0x0054, 0x1220,
-	0x9182, 0x0040, 0x0208, 0x000a, 0x0005, 0xb499, 0xb499, 0xb499,
-	0xb499, 0xb499, 0xb49b, 0xb499, 0xb499, 0xb499, 0xb499, 0xb499,
-	0xb499, 0xb499, 0xb499, 0xb499, 0xb499, 0xb499, 0xb499, 0xb499,
-	0xb499, 0x080c, 0x0db4, 0x080c, 0x53a2, 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, 0x68a0, 0x009e, 0x0804, 0x9e2f, 0x9182,
-	0x0085, 0x0002, 0xb4d1, 0xb4cf, 0xb4cf, 0xb4dd, 0xb4cf, 0xb4cf,
-	0xb4cf, 0xb4cf, 0xb4cf, 0xb4cf, 0xb4cf, 0xb4cf, 0xb4cf, 0x080c,
-	0x0db4, 0x6003, 0x0001, 0x6106, 0x080c, 0x83f8, 0x0126, 0x2091,
-	0x8000, 0x080c, 0x898b, 0x012e, 0x0005, 0x0026, 0x0056, 0x00d6,
-	0x00e6, 0x2071, 0x0260, 0x7224, 0x6216, 0x7220, 0x080c, 0xbb29,
-	0x01a0, 0x2268, 0x6800, 0x9086, 0x0000, 0x0178, 0x6010, 0x6d10,
-	0x952e, 0x1158, 0x00c6, 0x2d60, 0x080c, 0xb74f, 0x00ce, 0x0128,
-	0x6803, 0x0002, 0x6007, 0x0086, 0x0010, 0x6007, 0x0087, 0x6003,
-	0x0001, 0x080c, 0x83f8, 0x080c, 0x898b, 0x7220, 0x080c, 0xbb29,
-	0x0178, 0x6810, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0140,
-	0x6824, 0xd0ec, 0x0128, 0x00c6, 0x2d60, 0x080c, 0xbe73, 0x00ce,
-	0x00ee, 0x00de, 0x005e, 0x002e, 0x0005, 0x9186, 0x0013, 0x1160,
-	0x6004, 0x908a, 0x0085, 0x0a0c, 0x0db4, 0x908a, 0x0092, 0x1a0c,
-	0x0db4, 0x9082, 0x0085, 0x00e2, 0x9186, 0x0027, 0x0120, 0x9186,
-	0x0014, 0x190c, 0x0db4, 0x080c, 0x887f, 0x0096, 0x6014, 0x2048,
-	0x080c, 0xbb3b, 0x0140, 0xa867, 0x0103, 0xa877, 0x0000, 0xa87b,
-	0x0029, 0x080c, 0x68a0, 0x009e, 0x080c, 0x9e5f, 0x0804, 0x898b,
-	0xb555, 0xb557, 0xb557, 0xb555, 0xb555, 0xb555, 0xb555, 0xb555,
-	0xb555, 0xb555, 0xb555, 0xb555, 0xb555, 0x080c, 0x0db4, 0x080c,
-	0x887f, 0x080c, 0x9e5f, 0x080c, 0x898b, 0x0005, 0x9186, 0x0013,
-	0x1128, 0x6004, 0x9082, 0x0085, 0x2008, 0x04b8, 0x9186, 0x0027,
-	0x11f8, 0x080c, 0x887f, 0x080c, 0x2fe7, 0x080c, 0xc250, 0x0096,
-	0x6014, 0x2048, 0x080c, 0xbb3b, 0x0150, 0xa867, 0x0103, 0xa877,
-	0x0000, 0xa87b, 0x0029, 0x080c, 0x68a0, 0x080c, 0xbd24, 0x009e,
-	0x080c, 0x9e2f, 0x080c, 0x898b, 0x0005, 0x080c, 0x9ec4, 0x0ce0,
-	0x9186, 0x0014, 0x1dd0, 0x080c, 0x887f, 0x0096, 0x6014, 0x2048,
-	0x080c, 0xbb3b, 0x0d60, 0xa867, 0x0103, 0xa877, 0x0000, 0xa87b,
-	0x0006, 0xa880, 0xc0ec, 0xa882, 0x08f0, 0x0002, 0xb5ad, 0xb5ab,
-	0xb5ab, 0xb5ab, 0xb5ab, 0xb5ab, 0xb5c5, 0xb5ab, 0xb5ab, 0xb5ab,
-	0xb5ab, 0xb5ab, 0xb5ab, 0x080c, 0x0db4, 0x080c, 0x887f, 0x6034,
-	0x908c, 0xff00, 0x810f, 0x9186, 0x0039, 0x0118, 0x9186, 0x0035,
-	0x1118, 0x2001, 0x195e, 0x0010, 0x2001, 0x195f, 0x2004, 0x601a,
-	0x6003, 0x000c, 0x080c, 0x898b, 0x0005, 0x080c, 0x887f, 0x6034,
-	0x908c, 0xff00, 0x810f, 0x9186, 0x0039, 0x0118, 0x9186, 0x0035,
-	0x1118, 0x2001, 0x195e, 0x0010, 0x2001, 0x195f, 0x2004, 0x601a,
-	0x6003, 0x000e, 0x080c, 0x898b, 0x0005, 0x9182, 0x0092, 0x1220,
-	0x9182, 0x0085, 0x0208, 0x0012, 0x0804, 0x9ec4, 0xb5f3, 0xb5f3,
-	0xb5f3, 0xb5f3, 0xb5f5, 0xb642, 0xb5f3, 0xb5f3, 0xb5f3, 0xb5f3,
-	0xb5f3, 0xb5f3, 0xb5f3, 0x080c, 0x0db4, 0x0096, 0x6010, 0x00b6,
-	0x2058, 0xb800, 0x00be, 0xd0bc, 0x0168, 0x6034, 0x908c, 0xff00,
-	0x810f, 0x9186, 0x0039, 0x0118, 0x9186, 0x0035, 0x1118, 0x009e,
-	0x0804, 0xb656, 0x080c, 0xbb3b, 0x1118, 0x080c, 0xbd24, 0x0068,
-	0x6014, 0x2048, 0xa87c, 0xd0e4, 0x1110, 0x080c, 0xbd24, 0xa867,
-	0x0103, 0x080c, 0xc21b, 0x080c, 0x68a0, 0x00d6, 0x2c68, 0x080c,
-	0x9dd9, 0x01d0, 0x6003, 0x0001, 0x6007, 0x001e, 0x600b, 0xffff,
-	0x2009, 0x026e, 0x210c, 0x613a, 0x2009, 0x026f, 0x210c, 0x613e,
-	0x6910, 0x6112, 0x080c, 0xbfb5, 0x6954, 0x6156, 0x6023, 0x0001,
-	0x080c, 0x83f8, 0x080c, 0x898b, 0x2d60, 0x00de, 0x080c, 0x9e2f,
-	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, 0xc1b3, 0x11f0, 0x080c, 0x9dd9, 0x01d8, 0x6106, 0x6003,
-	0x0001, 0x6023, 0x0001, 0x6910, 0x6112, 0x692c, 0x612e, 0x6930,
-	0x6132, 0x6934, 0x918c, 0x00ff, 0x6136, 0x6938, 0x613a, 0x693c,
-	0x613e, 0x6954, 0x6156, 0x080c, 0xbfb5, 0x080c, 0x83f8, 0x080c,
-	0x898b, 0x2d60, 0x00de, 0x0804, 0x9e2f, 0x0096, 0x6014, 0x2048,
-	0x080c, 0xbb3b, 0x01c8, 0xa867, 0x0103, 0xa880, 0xd0b4, 0x0128,
-	0xc0ec, 0xa882, 0xa87b, 0x0006, 0x0048, 0xd0bc, 0x0118, 0xa87b,
-	0x0002, 0x0020, 0xa87b, 0x0005, 0x080c, 0xbe35, 0xa877, 0x0000,
-	0x080c, 0x68a0, 0x080c, 0xbd24, 0x009e, 0x0804, 0x9e2f, 0x0016,
-	0x0096, 0x6014, 0x2048, 0x080c, 0xbb3b, 0x0140, 0xa867, 0x0103,
-	0xa87b, 0x0028, 0xa877, 0x0000, 0x080c, 0x68a0, 0x009e, 0x001e,
-	0x9186, 0x0013, 0x0148, 0x9186, 0x0014, 0x0130, 0x9186, 0x0027,
-	0x0118, 0x080c, 0x9ec4, 0x0030, 0x080c, 0x887f, 0x080c, 0x9e5f,
-	0x080c, 0x898b, 0x0005, 0x0056, 0x0066, 0x0096, 0x00a6, 0x2029,
-	0x0001, 0x9182, 0x0101, 0x1208, 0x0010, 0x2009, 0x0100, 0x2130,
-	0x8304, 0x9098, 0x0018, 0x2009, 0x0020, 0x2011, 0x0029, 0x080c,
-	0xb724, 0x96b2, 0x0020, 0xb004, 0x904d, 0x0110, 0x080c, 0x0f9d,
-	0x080c, 0x0feb, 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,
+	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,
-	0x009e, 0x006e, 0x005e, 0x0005, 0x00a6, 0x89ff, 0x0158, 0xa804,
-	0x9055, 0x0130, 0xa807, 0x0000, 0x080c, 0x68a0, 0x2a48, 0x0cb8,
-	0x080c, 0x68a0, 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, 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, 0xb78a, 0xb78a, 0xb785, 0xb7ac, 0xb778, 0xb785, 0xb7ac,
-	0xb785, 0xb778, 0xb778, 0xb785, 0xb785, 0xb785, 0xb778, 0xb778,
-	0x080c, 0x0db4, 0x0036, 0x2019, 0x0010, 0x080c, 0xd11f, 0x6023,
-	0x0006, 0x6003, 0x0007, 0x003e, 0x0005, 0x9006, 0x0005, 0x9085,
-	0x0001, 0x0005, 0x0096, 0x86ff, 0x11d8, 0x6014, 0x2048, 0x080c,
-	0xbb3b, 0x01c0, 0xa864, 0x9086, 0x0139, 0x1128, 0xa87b, 0x0005,
-	0xa883, 0x0000, 0x0028, 0x900e, 0x2001, 0x0005, 0x080c, 0x6ace,
-	0x080c, 0xbe35, 0x080c, 0x6893, 0x080c, 0x9e5f, 0x9085, 0x0001,
-	0x009e, 0x0005, 0x9006, 0x0ce0, 0x6000, 0x908a, 0x0016, 0x1a0c,
-	0x0db4, 0x0002, 0xb7c2, 0xb7f0, 0xb7c4, 0xb811, 0xb7eb, 0xb7c2,
-	0xb785, 0xb78a, 0xb78a, 0xb785, 0xb785, 0xb785, 0xb785, 0xb785,
-	0xb785, 0xb785, 0x080c, 0x0db4, 0x86ff, 0x1510, 0x6020, 0x9086,
-	0x0006, 0x01f0, 0x0096, 0x6014, 0x2048, 0x080c, 0xbb3b, 0x0158,
-	0xa87c, 0xd0cc, 0x0130, 0x0096, 0xa878, 0x2048, 0x080c, 0x0f9d,
-	0x009e, 0x080c, 0xbe35, 0x009e, 0x080c, 0xc1f5, 0x6007, 0x0085,
-	0x6003, 0x000b, 0x6023, 0x0002, 0x080c, 0x83f8, 0x080c, 0x898b,
-	0x9085, 0x0001, 0x0005, 0x0066, 0x080c, 0x191f, 0x006e, 0x08a0,
-	0x00e6, 0x2071, 0x19bf, 0x7024, 0x9c06, 0x1120, 0x080c, 0x9673,
-	0x00ee, 0x0850, 0x6020, 0x9084, 0x000f, 0x9086, 0x0006, 0x1150,
-	0x0086, 0x0096, 0x2049, 0x0001, 0x2c40, 0x080c, 0x97a4, 0x009e,
-	0x008e, 0x0010, 0x080c, 0x9570, 0x00ee, 0x1904, 0xb7c4, 0x0804,
-	0xb785, 0x0036, 0x00e6, 0x2071, 0x19bf, 0x703c, 0x9c06, 0x1138,
-	0x901e, 0x080c, 0x96e9, 0x00ee, 0x003e, 0x0804, 0xb7c4, 0x080c,
-	0x98d4, 0x00ee, 0x003e, 0x1904, 0xb7c4, 0x0804, 0xb785, 0x00c6,
-	0x6020, 0x9084, 0x000f, 0x0013, 0x00ce, 0x0005, 0xb844, 0xb90f,
-	0xba79, 0xb84e, 0x9e5f, 0xb844, 0xd111, 0xc25d, 0xb90f, 0xb83d,
-	0xbb05, 0xb83d, 0xb83d, 0xb83d, 0xb83d, 0x080c, 0x0db4, 0x080c,
-	0xbd41, 0x1110, 0x080c, 0xa7cd, 0x0005, 0x080c, 0x887f, 0x080c,
-	0x898b, 0x0804, 0x9e2f, 0x601b, 0x0001, 0x0005, 0x080c, 0xbb3b,
-	0x0130, 0x6014, 0x0096, 0x2048, 0x2c00, 0xa896, 0x009e, 0x6000,
-	0x908a, 0x0016, 0x1a0c, 0x0db4, 0x0002, 0xb86d, 0xb86f, 0xb893,
-	0xb8a7, 0xb8cd, 0xb86d, 0xb844, 0xb844, 0xb844, 0xb8a7, 0xb8a7,
-	0xb86d, 0xb86d, 0xb86d, 0xb86d, 0xb8b1, 0x080c, 0x0db4, 0x00e6,
-	0x6014, 0x0096, 0x2048, 0xa880, 0xc0b5, 0xa882, 0x009e, 0x2071,
-	0x19bf, 0x7024, 0x9c06, 0x01a0, 0x080c, 0x9570, 0x080c, 0xc1f5,
-	0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x2001, 0x195f,
-	0x2004, 0x601a, 0x080c, 0x83f8, 0x080c, 0x898b, 0x00ee, 0x0005,
-	0x601b, 0x0001, 0x0cd8, 0x0096, 0x6014, 0x2048, 0xa880, 0xc0b5,
-	0xa882, 0x009e, 0x080c, 0xc1f5, 0x6007, 0x0085, 0x6003, 0x000b,
-	0x6023, 0x0002, 0x080c, 0x83f8, 0x080c, 0x898b, 0x0005, 0x0096,
-	0x601b, 0x0001, 0x6014, 0x2048, 0xa880, 0xc0b5, 0xa882, 0x009e,
-	0x0005, 0x080c, 0x53a2, 0x01b8, 0x6014, 0x0096, 0x904d, 0x0190,
-	0xa864, 0xa867, 0x0103, 0xa87b, 0x0006, 0x9086, 0x0139, 0x1150,
-	0xa867, 0x0139, 0xa87b, 0x0030, 0xa897, 0x4005, 0xa89b, 0x0004,
-	0x080c, 0x68a0, 0x009e, 0x0804, 0x9e2f, 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, 0x151a, 0x2001,
-	0x030c, 0x2004, 0x9086, 0x0041, 0x11a0, 0x6014, 0x0096, 0x904d,
-	0x090c, 0x0db4, 0xa880, 0xd0f4, 0x1130, 0xc0f5, 0xa882, 0x009e,
-	0x601b, 0x0002, 0x0070, 0x009e, 0x2001, 0x0037, 0x2c08, 0x080c,
-	0x151a, 0x6000, 0x9086, 0x0004, 0x1120, 0x2009, 0x0048, 0x080c,
-	0x9ea9, 0x0005, 0x009e, 0x080c, 0x191f, 0x0804, 0xb893, 0x6000,
-	0x908a, 0x0016, 0x1a0c, 0x0db4, 0x000b, 0x0005, 0xb926, 0xb84b,
-	0xb928, 0xb926, 0xb928, 0xb928, 0xb845, 0xb926, 0xb83f, 0xb83f,
-	0xb926, 0xb926, 0xb926, 0xb926, 0xb926, 0xb926, 0x080c, 0x0db4,
-	0x6010, 0x00b6, 0x2058, 0xb804, 0x9084, 0x00ff, 0x00be, 0x908a,
-	0x000c, 0x1a0c, 0x0db4, 0x00b6, 0x0013, 0x00be, 0x0005, 0xb943,
-	0xba10, 0xb945, 0xb985, 0xb945, 0xb985, 0xb945, 0xb953, 0xb943,
-	0xb985, 0xb943, 0xb974, 0x080c, 0x0db4, 0x6004, 0x908e, 0x0016,
-	0x05c0, 0x908e, 0x0004, 0x05a8, 0x908e, 0x0002, 0x0590, 0x908e,
-	0x0052, 0x0904, 0xba0c, 0x6004, 0x080c, 0xbd41, 0x0904, 0xba29,
-	0x908e, 0x0004, 0x1110, 0x080c, 0x3010, 0x908e, 0x0021, 0x0904,
-	0xba2d, 0x908e, 0x0022, 0x0904, 0xba74, 0x908e, 0x003d, 0x0904,
-	0xba2d, 0x908e, 0x0039, 0x0904, 0xba31, 0x908e, 0x0035, 0x0904,
-	0xba31, 0x908e, 0x001e, 0x0178, 0x908e, 0x0001, 0x1140, 0x6010,
-	0x2058, 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, 0x0110, 0x080c,
-	0x2fe7, 0x080c, 0xa7cd, 0x0804, 0x9e5f, 0x00c6, 0x00d6, 0x6104,
-	0x9186, 0x0016, 0x0904, 0xb9fd, 0x9186, 0x0002, 0x1904, 0xb9d2,
-	0x2001, 0x1836, 0x2004, 0xd08c, 0x11c8, 0x080c, 0x6faa, 0x11b0,
-	0x080c, 0xc23b, 0x0138, 0x080c, 0x6fcd, 0x1120, 0x080c, 0x6eba,
-	0x0804, 0xba5d, 0x2001, 0x1955, 0x2003, 0x0001, 0x2001, 0x1800,
-	0x2003, 0x0001, 0x080c, 0x6edc, 0x0804, 0xba5d, 0x6010, 0x2058,
-	0x2001, 0x1836, 0x2004, 0xd0ac, 0x1904, 0xba5d, 0xb8a0, 0x9084,
-	0xff80, 0x1904, 0xba5d, 0xb840, 0x9084, 0x00ff, 0x9005, 0x0190,
-	0x8001, 0xb842, 0x6017, 0x0000, 0x6023, 0x0007, 0x601b, 0x0398,
-	0x6043, 0x0000, 0x080c, 0x9dd9, 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, 0x5c78,
-	0x00ee, 0x080c, 0xa7cd, 0x0030, 0x080c, 0xa7cd, 0x080c, 0x2fe7,
-	0x080c, 0xc250, 0x00e6, 0x0126, 0x2091, 0x8000, 0x080c, 0x3010,
-	0x012e, 0x00ee, 0x080c, 0x9e5f, 0x0005, 0x2001, 0x0002, 0x080c,
-	0x61a7, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x8440, 0x080c,
-	0x898b, 0x00de, 0x00ce, 0x0c80, 0x080c, 0x3010, 0x0804, 0xb981,
-	0x00c6, 0x00d6, 0x6104, 0x9186, 0x0016, 0x0d38, 0x6010, 0x2058,
-	0xb840, 0x9084, 0x00ff, 0x9005, 0x0904, 0xb9d2, 0x8001, 0xb842,
-	0x6003, 0x0001, 0x080c, 0x8440, 0x080c, 0x898b, 0x00de, 0x00ce,
-	0x0898, 0x080c, 0xa7cd, 0x0804, 0xb983, 0x080c, 0xa809, 0x0804,
-	0xb983, 0x00d6, 0x2c68, 0x6104, 0x080c, 0xc1b3, 0x00de, 0x0118,
-	0x080c, 0x9e2f, 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, 0x83f8, 0x080c, 0x898b, 0x0005, 0x00de, 0x00ce, 0x080c,
-	0xa7cd, 0x080c, 0x2fe7, 0x00e6, 0x0126, 0x2091, 0x8000, 0x080c,
-	0x3010, 0x6017, 0x0000, 0x6023, 0x0007, 0x601b, 0x0398, 0x6043,
-	0x0000, 0x012e, 0x00ee, 0x0005, 0x080c, 0xa25f, 0x1904, 0xba29,
-	0x0005, 0x6000, 0x908a, 0x0016, 0x1a0c, 0x0db4, 0x0096, 0x00d6,
-	0x001b, 0x00de, 0x009e, 0x0005, 0xba94, 0xba94, 0xba94, 0xba94,
-	0xba94, 0xba94, 0xba94, 0xba94, 0xba94, 0xb844, 0xba94, 0xb84b,
-	0xba96, 0xb84b, 0xbab0, 0xba94, 0x080c, 0x0db4, 0x6004, 0x9086,
-	0x008b, 0x01b0, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0035,
-	0x1130, 0x602c, 0x9080, 0x0009, 0x200c, 0xc185, 0x2102, 0x6007,
-	0x008b, 0x6003, 0x000d, 0x080c, 0x83f8, 0x080c, 0x898b, 0x0005,
-	0x080c, 0xc22f, 0x0118, 0x080c, 0xc242, 0x0010, 0x080c, 0xc250,
-	0x080c, 0xbd24, 0x080c, 0xbb3b, 0x0570, 0x080c, 0x2fe7, 0x080c,
-	0xbb3b, 0x0168, 0x6014, 0x2048, 0xa867, 0x0103, 0xa87b, 0x0006,
-	0xa877, 0x0000, 0xa880, 0xc0ed, 0xa882, 0x080c, 0x68a0, 0x2c68,
-	0x080c, 0x9dd9, 0x0150, 0x6810, 0x6012, 0x080c, 0xbfb5, 0x00c6,
-	0x2d60, 0x080c, 0x9e5f, 0x00ce, 0x0008, 0x2d60, 0x6017, 0x0000,
-	0x6023, 0x0001, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x8440,
-	0x080c, 0x898b, 0x00c8, 0x080c, 0xc22f, 0x0138, 0x6034, 0x9086,
-	0x4000, 0x1118, 0x080c, 0x2fe7, 0x08d0, 0x6034, 0x908c, 0xff00,
-	0x810f, 0x9186, 0x0039, 0x0118, 0x9186, 0x0035, 0x1118, 0x080c,
-	0x2fe7, 0x0868, 0x080c, 0x9e5f, 0x0005, 0x6000, 0x908a, 0x0016,
-	0x1a0c, 0x0db4, 0x0002, 0xbb1b, 0xbb1b, 0xbb1d, 0xbb1d, 0xbb1d,
-	0xbb1b, 0xbb1b, 0x9e5f, 0xbb1b, 0xbb1b, 0xbb1b, 0xbb1b, 0xbb1b,
-	0xbb1b, 0xbb1b, 0xbb1b, 0x080c, 0x0db4, 0x080c, 0x98d4, 0x6114,
-	0x0096, 0x2148, 0xa87b, 0x0006, 0x080c, 0x68a0, 0x009e, 0x0804,
-	0x9e2f, 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, 0x1096,
-	0x000e, 0x009e, 0x0005, 0x00e6, 0x00c6, 0x0036, 0x0006, 0x0126,
-	0x2091, 0x8000, 0x2061, 0x1cd0, 0x2071, 0x1800, 0x7350, 0x7070,
-	0x9302, 0x1640, 0x6020, 0x9206, 0x11f8, 0x080c, 0xc23b, 0x0180,
-	0x9286, 0x0001, 0x1168, 0x6004, 0x9086, 0x0004, 0x1148, 0x080c,
-	0x2fe7, 0x080c, 0xc250, 0x00c6, 0x080c, 0x9e5f, 0x00ce, 0x0060,
-	0x080c, 0xbf2f, 0x0148, 0x080c, 0xbd41, 0x1110, 0x080c, 0xa7cd,
-	0x00c6, 0x080c, 0x9e2f, 0x00ce, 0x9ce0, 0x0018, 0x7064, 0x9c02,
-	0x1208, 0x08a0, 0x012e, 0x000e, 0x003e, 0x00ce, 0x00ee, 0x0005,
-	0x00e6, 0x00c6, 0x0016, 0x9188, 0x1000, 0x210c, 0x81ff, 0x0128,
-	0x2061, 0x1a87, 0x6112, 0x080c, 0x2fe7, 0x9006, 0x0010, 0x9085,
-	0x0001, 0x001e, 0x00ce, 0x00ee, 0x0005, 0x00c6, 0x0126, 0x2091,
-	0x8000, 0x080c, 0x9dd9, 0x01b0, 0x6656, 0x2b00, 0x6012, 0x080c,
-	0x53a2, 0x0118, 0x080c, 0xbc68, 0x0168, 0x080c, 0xbfb5, 0x6023,
-	0x0003, 0x2009, 0x004b, 0x080c, 0x9ea9, 0x9085, 0x0001, 0x012e,
+	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,
+	0x11e0, 0x6014, 0x2048, 0xaa3c, 0xd2e4, 0x1160, 0x2c78, 0x080c,
+	0x8e03, 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,
 	0x00ce, 0x0005, 0x9006, 0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000,
-	0xbaa0, 0x080c, 0x9e7c, 0x0560, 0x6057, 0x0000, 0x2b00, 0x6012,
-	0x080c, 0xbfb5, 0x6023, 0x0003, 0x0016, 0x080c, 0x8582, 0x0076,
-	0x903e, 0x080c, 0x8470, 0x2c08, 0x080c, 0xd2d5, 0x007e, 0x001e,
-	0xd184, 0x0128, 0x080c, 0x9e2f, 0x9085, 0x0001, 0x0070, 0x080c,
-	0x53a2, 0x0128, 0xd18c, 0x1170, 0x080c, 0xbc68, 0x0148, 0x2009,
-	0x004c, 0x080c, 0x9ea9, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005,
-	0x9006, 0x0cd8, 0x2900, 0x6016, 0x0c90, 0x2009, 0x004d, 0x0010,
-	0x2009, 0x004e, 0x00f6, 0x00c6, 0x0046, 0x0016, 0x080c, 0x9dd9,
-	0x2c78, 0x0590, 0x7e56, 0x2b00, 0x7812, 0x7823, 0x0003, 0x2021,
-	0x0005, 0x080c, 0xbc7a, 0x9186, 0x004d, 0x0118, 0x9186, 0x004e,
-	0x0148, 0x2001, 0x1958, 0x200c, 0xd1fc, 0x0168, 0x2f60, 0x080c,
-	0x9e2f, 0x00d0, 0x2001, 0x1957, 0x200c, 0xd1fc, 0x0120, 0x2f60,
-	0x080c, 0x9e2f, 0x0088, 0x2f60, 0x080c, 0x53a2, 0x0138, 0xd18c,
-	0x1118, 0x04f1, 0x0148, 0x0010, 0x2900, 0x7816, 0x001e, 0x0016,
-	0x080c, 0x9ea9, 0x9085, 0x0001, 0x001e, 0x004e, 0x00ce, 0x00fe,
-	0x0005, 0x00f6, 0x00c6, 0x0046, 0x080c, 0x9dd9, 0x2c78, 0x0508,
-	0x7e56, 0x2b00, 0x7812, 0x7823, 0x0003, 0x0096, 0x2021, 0x0004,
-	0x0489, 0x009e, 0x2001, 0x1956, 0x200c, 0xd1fc, 0x0120, 0x2f60,
-	0x080c, 0x9e2f, 0x0060, 0x2f60, 0x080c, 0x53a2, 0x0120, 0xd18c,
-	0x1160, 0x0071, 0x0130, 0x2009, 0x0052, 0x080c, 0x9ea9, 0x9085,
-	0x0001, 0x004e, 0x00ce, 0x00fe, 0x0005, 0x2900, 0x7816, 0x0c98,
-	0x00c6, 0x080c, 0x4894, 0x00ce, 0x1120, 0x080c, 0x9e2f, 0x9006,
-	0x0005, 0xa867, 0x0000, 0xa86b, 0x8000, 0x2900, 0x6016, 0x9085,
-	0x0001, 0x0005, 0x0096, 0x0076, 0x0126, 0x2091, 0x8000, 0x080c,
-	0x638a, 0x0158, 0x2001, 0xbc7f, 0x0006, 0x900e, 0x2400, 0x080c,
-	0x6ace, 0x080c, 0x68a0, 0x000e, 0x0807, 0x2418, 0x080c, 0x8819,
-	0xbaa0, 0x0086, 0x2041, 0x0001, 0x2039, 0x0001, 0x2608, 0x080c,
-	0x859a, 0x008e, 0x080c, 0x8470, 0x2f08, 0x2648, 0x080c, 0xd2d5,
-	0xb93c, 0x81ff, 0x090c, 0x866b, 0x080c, 0x898b, 0x012e, 0x007e,
-	0x009e, 0x0005, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0x9dd9,
-	0x0190, 0x660a, 0x2b08, 0x6112, 0x080c, 0xbfb5, 0x6023, 0x0001,
-	0x2900, 0x6016, 0x2009, 0x001f, 0x080c, 0x9ea9, 0x9085, 0x0001,
-	0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x00c6, 0x0126, 0x2091,
-	0x8000, 0x080c, 0x9e7c, 0x01b8, 0x660a, 0x2b08, 0x6112, 0x080c,
-	0xbfb5, 0x6023, 0x0008, 0x2900, 0x6016, 0x00f6, 0x2c78, 0x080c,
-	0x164a, 0x00fe, 0x2009, 0x0021, 0x080c, 0x9ea9, 0x9085, 0x0001,
-	0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x2009, 0x003d, 0x00c6,
-	0x0126, 0x0016, 0x2091, 0x8000, 0x080c, 0x9dd9, 0x0198, 0x660a,
-	0x2b08, 0x6112, 0x080c, 0xbfb5, 0x6023, 0x0001, 0x2900, 0x6016,
-	0x001e, 0x0016, 0x080c, 0x9ea9, 0x9085, 0x0001, 0x001e, 0x012e,
-	0x00ce, 0x0005, 0x9006, 0x0cd0, 0x00c6, 0x0126, 0x2091, 0x8000,
-	0x080c, 0x9e7c, 0x0188, 0x2b08, 0x6112, 0x080c, 0xbfb5, 0x6023,
-	0x0001, 0x2900, 0x6016, 0x2009, 0x0000, 0x080c, 0x9ea9, 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, 0xbb3b, 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,
-	0x9e7c, 0x0198, 0x2b08, 0x6112, 0x080c, 0xbfb5, 0x6023, 0x0001,
-	0x2900, 0x6016, 0x080c, 0x2fe7, 0x2009, 0x0028, 0x080c, 0x9ea9,
-	0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x9186,
-	0x0015, 0x11a8, 0x2011, 0x1823, 0x2204, 0x9086, 0x0074, 0x1178,
-	0x00b6, 0x080c, 0xaa58, 0x00be, 0x080c, 0xac97, 0x6003, 0x0001,
-	0x6007, 0x0029, 0x080c, 0x8440, 0x080c, 0x898b, 0x0078, 0x6014,
-	0x0096, 0x2048, 0xa868, 0x009e, 0xd0fc, 0x0148, 0x2001, 0x0001,
-	0x080c, 0xc174, 0x080c, 0xa7cd, 0x080c, 0x9e2f, 0x0005, 0x0096,
-	0x6014, 0x904d, 0x090c, 0x0db4, 0xa87b, 0x0030, 0xa883, 0x0000,
-	0xa897, 0x4005, 0xa89b, 0x0004, 0xa867, 0x0139, 0x0126, 0x2091,
-	0x8000, 0x080c, 0x68a0, 0x012e, 0x009e, 0x080c, 0x9e2f, 0x0c30,
-	0x0096, 0x9186, 0x0016, 0x1128, 0x2001, 0x0004, 0x080c, 0x61a7,
-	0x00e8, 0x9186, 0x0015, 0x1510, 0x2011, 0x1823, 0x2204, 0x9086,
-	0x0014, 0x11e0, 0x6010, 0x00b6, 0x2058, 0x080c, 0x62f1, 0x00be,
-	0x080c, 0xad68, 0x1198, 0x6010, 0x00b6, 0x2058, 0xb890, 0x00be,
-	0x9005, 0x0160, 0x2001, 0x0006, 0x080c, 0x61a7, 0x6014, 0x2048,
-	0xa868, 0xd0fc, 0x0170, 0x080c, 0xa233, 0x0048, 0x6014, 0x2048,
-	0xa868, 0xd0fc, 0x0528, 0x080c, 0xa7cd, 0x080c, 0x9e2f, 0x009e,
-	0x0005, 0x6014, 0x6310, 0x2358, 0x904d, 0x090c, 0x0db4, 0xa87b,
-	0x0000, 0xa883, 0x0000, 0xa897, 0x4000, 0x900e, 0x080c, 0x6476,
-	0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0xa99a, 0x0126,
-	0x2091, 0x8000, 0x080c, 0x68a0, 0x012e, 0x080c, 0x9e2f, 0x08f8,
-	0x6014, 0x904d, 0x090c, 0x0db4, 0xa87b, 0x0030, 0xa883, 0x0000,
-	0xa897, 0x4005, 0xa89b, 0x0004, 0xa867, 0x0139, 0x0126, 0x2091,
-	0x8000, 0x080c, 0x68a0, 0x012e, 0x080c, 0x9e2f, 0x0840, 0xa878,
-	0x9086, 0x0005, 0x1108, 0x0009, 0x0005, 0xa880, 0xc0ad, 0xa882,
-	0x0005, 0x6043, 0x0000, 0x6017, 0x0000, 0x6003, 0x0001, 0x6007,
-	0x0050, 0x080c, 0x83f8, 0x080c, 0x898b, 0x0005, 0x00c6, 0x6010,
-	0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0120, 0x6020, 0x9084,
-	0x000f, 0x0013, 0x00ce, 0x0005, 0xb844, 0xbe65, 0xbe65, 0xbe68,
-	0xd5b3, 0xd5ce, 0xd5d1, 0xb844, 0xb844, 0xb844, 0xb844, 0xb844,
-	0xb844, 0xb844, 0xb844, 0x080c, 0x0db4, 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, 0x9dd9, 0x0508, 0x7810, 0x6012, 0x080c, 0xbfb5,
-	0x7820, 0x9086, 0x0003, 0x0128, 0x7808, 0x603a, 0x2f00, 0x603e,
-	0x0020, 0x7808, 0x603e, 0x2f00, 0x603a, 0x602e, 0x6023, 0x0001,
-	0x6007, 0x0035, 0x6003, 0x0001, 0x7954, 0x6156, 0x080c, 0x83f8,
-	0x080c, 0x898b, 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, 0x0f9d, 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, 0x83f8, 0x080c, 0x898b, 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, 0x8277, 0x2001, 0x195e, 0x82ff,
-	0x1110, 0x2011, 0x0014, 0x2202, 0x2001, 0x195c, 0x200c, 0x8000,
-	0x2014, 0x2071, 0x1944, 0x711a, 0x721e, 0x2001, 0x0064, 0x080c,
-	0x8277, 0x2001, 0x195f, 0x82ff, 0x1110, 0x2011, 0x0014, 0x2202,
-	0x2001, 0x1960, 0x9288, 0x000a, 0x2102, 0x2001, 0x1a68, 0x2102,
-	0x2001, 0x0032, 0x080c, 0x151a, 0x080c, 0x655b, 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, 0x1a68, 0x2102, 0x2001, 0x0032, 0x080c,
-	0x151a, 0x00ee, 0x001e, 0x000e, 0x0005, 0x0096, 0x6058, 0x904d,
-	0x0110, 0x080c, 0x101d, 0x009e, 0x0005, 0x0005, 0x00c6, 0x0126,
-	0x2091, 0x8000, 0x080c, 0x9dd9, 0x0180, 0x2b08, 0x6112, 0x0ca9,
-	0x6023, 0x0001, 0x2900, 0x6016, 0x2009, 0x0033, 0x080c, 0x9ea9,
-	0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x0096,
-	0x00e6, 0x00f6, 0x2071, 0x1800, 0x9186, 0x0015, 0x1500, 0x708c,
-	0x9086, 0x0018, 0x11e0, 0x6014, 0x2048, 0xaa3c, 0xd2e4, 0x1160,
-	0x2c78, 0x080c, 0x8b7e, 0x01d8, 0x7078, 0xaa50, 0x9206, 0x1160,
-	0x707c, 0xaa54, 0x9206, 0x1140, 0x6210, 0x00b6, 0x2258, 0xbaa0,
-	0x00be, 0x900e, 0x080c, 0x3030, 0x080c, 0xa233, 0x0020, 0x080c,
-	0xa7cd, 0x080c, 0x9e2f, 0x00fe, 0x00ee, 0x009e, 0x0005, 0x705c,
-	0xaa54, 0x9206, 0x0d48, 0x0c80, 0x00c6, 0x0126, 0x2091, 0x8000,
-	0x080c, 0x9dd9, 0x0188, 0x2b08, 0x6112, 0x080c, 0xbfb5, 0x6023,
-	0x0001, 0x2900, 0x6016, 0x2009, 0x004d, 0x080c, 0x9ea9, 0x9085,
-	0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x00c6, 0x0126,
-	0x2091, 0x8000, 0x0016, 0x080c, 0x9dd9, 0x0180, 0x2b08, 0x6112,
-	0x080c, 0xbfb5, 0x6023, 0x0001, 0x2900, 0x6016, 0x001e, 0x080c,
-	0x9ea9, 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, 0x2003, 0x0000, 0x6014, 0x2048, 0xa830, 0x20a8,
-	0x8906, 0x8006, 0x8007, 0x9094, 0x003f, 0x22e8, 0x9084, 0xffc0,
-	0x9080, 0x001b, 0x20a0, 0x2001, 0x1978, 0x0016, 0x200c, 0x080c,
-	0xc7fc, 0x001e, 0xa804, 0x9005, 0x0110, 0x2048, 0x0c38, 0x6014,
-	0x2048, 0xa867, 0x0103, 0x0010, 0x080c, 0xa7cd, 0x080c, 0x9e2f,
-	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, 0x8b7e, 0x01a8, 0x7078, 0xaa74, 0x9206, 0x1130,
-	0x707c, 0xaa78, 0x9206, 0x1110, 0x080c, 0x2fe7, 0x080c, 0xa233,
-	0x0020, 0x080c, 0xa7cd, 0x080c, 0x9e2f, 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, 0x8b7e, 0x05f0,
-	0x7078, 0xaacc, 0x9206, 0x1180, 0x707c, 0xaad0, 0x9206, 0x1160,
-	0x080c, 0x2fe7, 0x0016, 0xa998, 0xaab0, 0x9284, 0x1000, 0xc0fd,
-	0x080c, 0x5352, 0x001e, 0x0010, 0x080c, 0x5143, 0x080c, 0xbb3b,
-	0x0508, 0xa87b, 0x0000, 0xa883, 0x0000, 0xa897, 0x4000, 0x0080,
-	0x080c, 0xbb3b, 0x01b8, 0x6014, 0x2048, 0x080c, 0x5143, 0x1d70,
-	0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, 0x4005, 0xa89b, 0x0004,
-	0x0126, 0x2091, 0x8000, 0xa867, 0x0139, 0x080c, 0x68a0, 0x012e,
-	0x080c, 0x9e2f, 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, 0xbb3b, 0x0904,
-	0xc170, 0x0096, 0x6314, 0x2348, 0xa87a, 0xa982, 0x929e, 0x4000,
-	0x1580, 0x6310, 0x00c6, 0x2358, 0x2009, 0x0000, 0xa868, 0xd0f4,
-	0x1140, 0x080c, 0x6476, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108,
-	0xc18d, 0xaa96, 0xa99a, 0x20a9, 0x0004, 0xa860, 0x20e8, 0xa85c,
-	0x9080, 0x0031, 0x20a0, 0xb8b4, 0x20e0, 0xb8b8, 0x9080, 0x0006,
-	0x2098, 0x080c, 0x0f68, 0x20a9, 0x0004, 0xa85c, 0x9080, 0x0035,
-	0x20a0, 0xb8b8, 0x9080, 0x000a, 0x2098, 0x080c, 0x0f68, 0x00ce,
-	0x0090, 0xaa96, 0x3918, 0x9398, 0x0007, 0x231c, 0x6004, 0x9086,
-	0x0016, 0x0110, 0xa89b, 0x0004, 0xaba2, 0x6310, 0x2358, 0xb804,
-	0x9084, 0x00ff, 0xa89e, 0x080c, 0x6893, 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,
-	0x2670, 0x2118, 0x831f, 0x939c, 0xff00, 0x7838, 0x9084, 0x00ff,
-	0x931d, 0x7c3c, 0x2011, 0x8018, 0x080c, 0x48f4, 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, 0xbb29, 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, 0xb236, 0x0005, 0x0036, 0x2019, 0x0001,
-	0x0010, 0x0036, 0x901e, 0x0499, 0x01e0, 0x080c, 0xbb3b, 0x01c8,
-	0x080c, 0xbd24, 0x6037, 0x4000, 0x6014, 0x6017, 0x0000, 0x0096,
-	0x2048, 0xa87c, 0x080c, 0xbd41, 0x1118, 0x080c, 0xa7cd, 0x0040,
-	0xa867, 0x0103, 0xa877, 0x0000, 0x83ff, 0x1129, 0x080c, 0x68a0,
-	0x009e, 0x003e, 0x0005, 0xa880, 0xd0b4, 0x0128, 0xa87b, 0x0006,
-	0xc0ec, 0xa882, 0x0048, 0xd0bc, 0x0118, 0xa87b, 0x0002, 0x0020,
-	0xa87b, 0x0005, 0x080c, 0xbe35, 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, 0x4a91, 0x004e, 0x003e, 0x0005,
-	0x0c51, 0x1d81, 0x0005, 0x2001, 0x195e, 0x2004, 0x601a, 0x0005,
-	0x2001, 0x1960, 0x2004, 0x6042, 0x0005, 0x080c, 0x9e2f, 0x0804,
-	0x898b, 0x00b6, 0x0066, 0x6000, 0x90b2, 0x0016, 0x1a0c, 0x0db4,
-	0x001b, 0x006e, 0x00be, 0x0005, 0xc27c, 0xc959, 0xcab4, 0xc27c,
-	0xc27c, 0xc27c, 0xc27c, 0xc27c, 0xc2b3, 0xcb38, 0xc27c, 0xc27c,
-	0xc27c, 0xc27c, 0xc27c, 0xc27c, 0x080c, 0x0db4, 0x0066, 0x6000,
-	0x90b2, 0x0016, 0x1a0c, 0x0db4, 0x0013, 0x006e, 0x0005, 0xc297,
-	0xd0aa, 0xc297, 0xc297, 0xc297, 0xc297, 0xc297, 0xc297, 0xd057,
-	0xd0fe, 0xc297, 0xd6ee, 0xd724, 0xd6ee, 0xd724, 0xc297, 0x080c,
-	0x0db4, 0x6000, 0x9082, 0x0016, 0x1a0c, 0x0db4, 0x6000, 0x000a,
-	0x0005, 0xc2b1, 0xcd16, 0xce08, 0xce2b, 0xceeb, 0xc2b1, 0xcfca,
-	0xcf73, 0xcb44, 0xd02d, 0xd042, 0xc2b1, 0xc2b1, 0xc2b1, 0xc2b1,
-	0xc2b1, 0x080c, 0x0db4, 0x91b2, 0x0053, 0x1a0c, 0x0db4, 0x2100,
-	0x91b2, 0x0040, 0x1a04, 0xc6fa, 0x0002, 0xc2fd, 0xc4eb, 0xc2fd,
-	0xc2fd, 0xc2fd, 0xc4f4, 0xc2fd, 0xc2fd, 0xc2fd, 0xc2fd, 0xc2fd,
-	0xc2fd, 0xc2fd, 0xc2fd, 0xc2fd, 0xc2fd, 0xc2fd, 0xc2fd, 0xc2fd,
-	0xc2fd, 0xc2fd, 0xc2fd, 0xc2fd, 0xc2ff, 0xc362, 0xc371, 0xc3d5,
-	0xc400, 0xc478, 0xc4d6, 0xc2fd, 0xc2fd, 0xc4f7, 0xc2fd, 0xc2fd,
-	0xc50c, 0xc519, 0xc2fd, 0xc2fd, 0xc2fd, 0xc2fd, 0xc2fd, 0xc59c,
-	0xc2fd, 0xc2fd, 0xc5b0, 0xc2fd, 0xc2fd, 0xc56b, 0xc2fd, 0xc2fd,
-	0xc2fd, 0xc5c8, 0xc2fd, 0xc2fd, 0xc2fd, 0xc645, 0xc2fd, 0xc2fd,
-	0xc2fd, 0xc2fd, 0xc2fd, 0xc2fd, 0xc6c2, 0x080c, 0x0db4, 0x080c,
-	0x6538, 0x1150, 0x2001, 0x1836, 0x2004, 0xd0cc, 0x1128, 0x9084,
-	0x0009, 0x9086, 0x0008, 0x1140, 0x6007, 0x0009, 0x602f, 0x0009,
-	0x6017, 0x0000, 0x0804, 0xc4e4, 0x080c, 0x6521, 0x00e6, 0x00c6,
-	0x0036, 0x0026, 0x0016, 0x6210, 0x2258, 0xbaa0, 0x0026, 0x2019,
-	0x0029, 0x080c, 0x8582, 0x0076, 0x903e, 0x080c, 0x8470, 0x2c08,
-	0x080c, 0xd2d5, 0x007e, 0x001e, 0x001e, 0x002e, 0x003e, 0x00ce,
-	0x00ee, 0x6610, 0x2658, 0x080c, 0x6265, 0xbe04, 0x9684, 0x00ff,
-	0x9082, 0x0006, 0x1268, 0x0016, 0x0026, 0x6210, 0x00b6, 0x2258,
-	0xbaa0, 0x00be, 0x2c08, 0x080c, 0xd89c, 0x002e, 0x001e, 0x1178,
-	0x080c, 0xd208, 0x1904, 0xc3cd, 0x080c, 0xd1a4, 0x1120, 0x6007,
-	0x0008, 0x0804, 0xc4e4, 0x6007, 0x0009, 0x0804, 0xc4e4, 0x080c,
-	0xd3ff, 0x0128, 0x080c, 0xd208, 0x0d78, 0x0804, 0xc3cd, 0x6017,
-	0x1900, 0x0c88, 0x080c, 0x310a, 0x1904, 0xc6f7, 0x6106, 0x080c,
-	0xd159, 0x6007, 0x0006, 0x0804, 0xc4e4, 0x6007, 0x0007, 0x0804,
-	0xc4e4, 0x080c, 0xd760, 0x1904, 0xc6f7, 0x080c, 0x310a, 0x1904,
-	0xc6f7, 0x00d6, 0x6610, 0x2658, 0xbe04, 0x9684, 0x00ff, 0x9082,
-	0x0006, 0x1220, 0x2001, 0x0001, 0x080c, 0x6193, 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, 0xd26b, 0x1190, 0x9686, 0x0006,
-	0x1140, 0x0026, 0x6210, 0x2258, 0xbaa0, 0x900e, 0x080c, 0x3030,
-	0x002e, 0x080c, 0x62f1, 0x6007, 0x000a, 0x00de, 0x0804, 0xc4e4,
-	0x6007, 0x000b, 0x00de, 0x0804, 0xc4e4, 0x080c, 0x2fe7, 0x080c,
-	0xc250, 0x6007, 0x0001, 0x0804, 0xc4e4, 0x080c, 0xd760, 0x1904,
-	0xc6f7, 0x080c, 0x310a, 0x1904, 0xc6f7, 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, 0x3030, 0x002e,
-	0x6007, 0x000c, 0x2001, 0x0001, 0x080c, 0xd87c, 0x0804, 0xc4e4,
-	0x080c, 0x6538, 0x1140, 0x2001, 0x1836, 0x2004, 0x9084, 0x0009,
-	0x9086, 0x0008, 0x1110, 0x0804, 0xc30c, 0x080c, 0x6521, 0x6610,
-	0x2658, 0xbe04, 0x9684, 0x00ff, 0x9082, 0x0006, 0x06c0, 0x1138,
-	0x0026, 0x2001, 0x0006, 0x080c, 0x61d3, 0x002e, 0x0050, 0x96b4,
-	0xff00, 0x8637, 0x9686, 0x0004, 0x0120, 0x9686, 0x0006, 0x1904,
-	0xc3cd, 0x080c, 0xd278, 0x1120, 0x6007, 0x000e, 0x0804, 0xc4e4,
-	0x0046, 0x6410, 0x2458, 0xbca0, 0x0046, 0x080c, 0x2fe7, 0x080c,
-	0xc250, 0x004e, 0x0016, 0x9006, 0x2009, 0x185c, 0x210c, 0x0048,
-	0x2009, 0x0029, 0x080c, 0xd564, 0x6010, 0x2058, 0xb800, 0xc0e5,
-	0xb802, 0x001e, 0x004e, 0x6007, 0x0001, 0x0804, 0xc4e4, 0x2001,
-	0x0001, 0x080c, 0x6193, 0x0156, 0x0016, 0x0026, 0x0036, 0x20a9,
-	0x0004, 0x2019, 0x1805, 0x2011, 0x0270, 0x080c, 0xae08, 0x003e,
-	0x002e, 0x001e, 0x015e, 0x9005, 0x0168, 0x96b4, 0xff00, 0x8637,
-	0x9682, 0x0004, 0x0a04, 0xc3cd, 0x9682, 0x0007, 0x0a04, 0xc429,
-	0x0804, 0xc3cd, 0x6017, 0x1900, 0x6007, 0x0009, 0x0804, 0xc4e4,
-	0x080c, 0x6538, 0x1140, 0x2001, 0x1836, 0x2004, 0x9084, 0x0009,
-	0x9086, 0x0008, 0x1110, 0x0804, 0xc30c, 0x080c, 0x6521, 0x6610,
-	0x2658, 0xbe04, 0x9684, 0x00ff, 0x0006, 0x9086, 0x0001, 0x000e,
-	0x0170, 0x9082, 0x0006, 0x0690, 0x0150, 0x96b4, 0xff00, 0x8637,
-	0x9686, 0x0004, 0x0120, 0x9686, 0x0006, 0x1904, 0xc3cd, 0x080c,
-	0xd2a6, 0x1130, 0x080c, 0xd1a4, 0x1118, 0x6007, 0x0010, 0x04e0,
-	0x0046, 0x6410, 0x2458, 0xbca0, 0x0046, 0x080c, 0x2fe7, 0x080c,
-	0xc250, 0x004e, 0x0016, 0x9006, 0x2009, 0x185c, 0x210c, 0x0048,
-	0x2009, 0x0029, 0x080c, 0xd564, 0x6010, 0x2058, 0xb800, 0xc0e5,
-	0xb802, 0x001e, 0x004e, 0x6007, 0x0001, 0x00f0, 0x080c, 0xd3ff,
-	0x0140, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0006, 0x0980, 0x0804,
-	0xc3cd, 0x6017, 0x1900, 0x6007, 0x0009, 0x0070, 0x080c, 0x310a,
-	0x1904, 0xc6f7, 0x080c, 0xd760, 0x1904, 0xc6f7, 0x080c, 0xc897,
-	0x1904, 0xc3cd, 0x6007, 0x0012, 0x6003, 0x0001, 0x080c, 0x8440,
-	0x080c, 0x898b, 0x0005, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c,
-	0x8440, 0x080c, 0x898b, 0x0cb0, 0x6007, 0x0005, 0x0c68, 0x080c,
-	0xd760, 0x1904, 0xc6f7, 0x080c, 0x310a, 0x1904, 0xc6f7, 0x080c,
-	0xc897, 0x1904, 0xc3cd, 0x6007, 0x0020, 0x6003, 0x0001, 0x080c,
-	0x8440, 0x080c, 0x898b, 0x0005, 0x080c, 0x310a, 0x1904, 0xc6f7,
-	0x6007, 0x0023, 0x6003, 0x0001, 0x080c, 0x8440, 0x080c, 0x898b,
-	0x0005, 0x080c, 0xd760, 0x1904, 0xc6f7, 0x080c, 0x310a, 0x1904,
-	0xc6f7, 0x080c, 0xc897, 0x1904, 0xc3cd, 0x0016, 0x0026, 0x00e6,
-	0x2071, 0x0260, 0x7244, 0x9286, 0xffff, 0x0180, 0x2c08, 0x080c,
-	0xbb29, 0x01b0, 0x2260, 0x7240, 0x6008, 0x9206, 0x1188, 0x6010,
-	0x9190, 0x0004, 0x2214, 0x9206, 0x01b8, 0x0050, 0x7240, 0x2c08,
-	0x9006, 0x080c, 0xd536, 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, 0x9e2f, 0x2160, 0x6007,
-	0x0025, 0x6003, 0x0001, 0x080c, 0x8440, 0x080c, 0x898b, 0x00ee,
-	0x002e, 0x001e, 0x0005, 0x2001, 0x0001, 0x080c, 0x6193, 0x0156,
-	0x0016, 0x0026, 0x0036, 0x20a9, 0x0004, 0x2019, 0x1805, 0x2011,
-	0x0276, 0x080c, 0xae08, 0x003e, 0x002e, 0x001e, 0x015e, 0x0120,
-	0x6007, 0x0031, 0x0804, 0xc4e4, 0x080c, 0xaa70, 0x080c, 0x6faa,
-	0x1190, 0x0006, 0x0026, 0x0036, 0x080c, 0x6fc4, 0x1138, 0x080c,
-	0x728c, 0x080c, 0x5ce5, 0x080c, 0x6edc, 0x0010, 0x080c, 0x6f82,
-	0x003e, 0x002e, 0x000e, 0x0005, 0x080c, 0x310a, 0x1904, 0xc6f7,
-	0x080c, 0xc897, 0x1904, 0xc3cd, 0x6106, 0x080c, 0xc8b3, 0x1120,
-	0x6007, 0x002b, 0x0804, 0xc4e4, 0x6007, 0x002c, 0x0804, 0xc4e4,
-	0x080c, 0xd760, 0x1904, 0xc6f7, 0x080c, 0x310a, 0x1904, 0xc6f7,
-	0x080c, 0xc897, 0x1904, 0xc3cd, 0x6106, 0x080c, 0xc8b8, 0x1120,
-	0x6007, 0x002e, 0x0804, 0xc4e4, 0x6007, 0x002f, 0x0804, 0xc4e4,
-	0x080c, 0x310a, 0x1904, 0xc6f7, 0x00e6, 0x00d6, 0x00c6, 0x6010,
-	0x2058, 0xb904, 0x9184, 0x00ff, 0x9086, 0x0006, 0x0158, 0x9184,
-	0xff00, 0x8007, 0x9086, 0x0006, 0x0128, 0x00ce, 0x00de, 0x00ee,
-	0x0804, 0xc4eb, 0x080c, 0x539e, 0xd0e4, 0x0904, 0xc642, 0x2071,
-	0x026c, 0x7010, 0x603a, 0x7014, 0x603e, 0x7108, 0x720c, 0x080c,
-	0x6576, 0x0140, 0x6010, 0x2058, 0xb810, 0x9106, 0x1118, 0xb814,
-	0x9206, 0x0510, 0x080c, 0x6572, 0x15b8, 0x2069, 0x1800, 0x687c,
-	0x9206, 0x1590, 0x6878, 0x9106, 0x1578, 0x7210, 0x080c, 0xbb29,
-	0x0590, 0x080c, 0xc782, 0x0578, 0x080c, 0xd5e0, 0x0560, 0x622e,
-	0x6007, 0x0036, 0x6003, 0x0001, 0x080c, 0x83f8, 0x080c, 0x898b,
-	0x00ce, 0x00de, 0x00ee, 0x0005, 0x7214, 0x9286, 0xffff, 0x0150,
-	0x080c, 0xbb29, 0x01c0, 0x9280, 0x0002, 0x2004, 0x7110, 0x9106,
-	0x1190, 0x08e0, 0x7210, 0x2c08, 0x9085, 0x0001, 0x080c, 0xd536,
-	0x2c10, 0x2160, 0x0140, 0x0890, 0x6007, 0x0037, 0x602f, 0x0009,
-	0x6017, 0x1500, 0x08b8, 0x6007, 0x0037, 0x602f, 0x0003, 0x6017,
-	0x1700, 0x0880, 0x6007, 0x0012, 0x0868, 0x080c, 0x310a, 0x1904,
-	0xc6f7, 0x6010, 0x2058, 0xb804, 0x9084, 0xff00, 0x8007, 0x9086,
-	0x0006, 0x1904, 0xc4eb, 0x00e6, 0x00d6, 0x00c6, 0x080c, 0x539e,
-	0xd0e4, 0x0904, 0xc6ba, 0x2069, 0x1800, 0x2071, 0x026c, 0x7008,
-	0x603a, 0x720c, 0x623e, 0x9286, 0xffff, 0x1150, 0x7208, 0x00c6,
-	0x2c08, 0x9085, 0x0001, 0x080c, 0xd536, 0x2c10, 0x00ce, 0x05e8,
-	0x080c, 0xbb29, 0x05d0, 0x7108, 0x9280, 0x0002, 0x2004, 0x9106,
-	0x15a0, 0x00c6, 0x0026, 0x2260, 0x080c, 0xb74f, 0x002e, 0x00ce,
-	0x7118, 0x918c, 0xff00, 0x810f, 0x9186, 0x0001, 0x0178, 0x9186,
-	0x0005, 0x0118, 0x9186, 0x0007, 0x1198, 0x9280, 0x0005, 0x2004,
-	0x9005, 0x0170, 0x080c, 0xc782, 0x0904, 0xc63b, 0x0056, 0x7510,
-	0x7614, 0x080c, 0xd5f9, 0x005e, 0x00ce, 0x00de, 0x00ee, 0x0005,
-	0x6007, 0x003b, 0x602f, 0x0009, 0x6017, 0x2a00, 0x6003, 0x0001,
-	0x080c, 0x83f8, 0x080c, 0x898b, 0x0c78, 0x6007, 0x003b, 0x602f,
-	0x0003, 0x6017, 0x0300, 0x6003, 0x0001, 0x080c, 0x83f8, 0x080c,
-	0x898b, 0x0c10, 0x6007, 0x003b, 0x602f, 0x000b, 0x6017, 0x0000,
-	0x0804, 0xc612, 0x00e6, 0x0026, 0x080c, 0x6538, 0x0550, 0x080c,
-	0x6521, 0x080c, 0xd7d2, 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, 0x6576, 0x0120, 0x2011, 0x19d8,
-	0x2013, 0x07d0, 0xd0ac, 0x1128, 0x080c, 0x2dc8, 0x0010, 0x080c,
-	0xd804, 0x002e, 0x00ee, 0x080c, 0x9e2f, 0x0804, 0xc4ea, 0x080c,
-	0x9e2f, 0x0005, 0x2600, 0x0002, 0xc70e, 0xc70e, 0xc70e, 0xc70e,
-	0xc70e, 0xc710, 0xc70e, 0xc70e, 0xc70e, 0xc70e, 0xc72d, 0xc70e,
-	0xc70e, 0xc70e, 0xc73f, 0xc74c, 0xc77d, 0xc70e, 0x080c, 0x0db4,
-	0x080c, 0xd760, 0x1d20, 0x080c, 0x310a, 0x1d08, 0x080c, 0xc897,
-	0x1148, 0x7038, 0x6016, 0x6007, 0x0045, 0x6003, 0x0001, 0x080c,
-	0x8440, 0x0005, 0x080c, 0x2fe7, 0x080c, 0xc250, 0x6007, 0x0001,
-	0x6003, 0x0001, 0x080c, 0x8440, 0x0005, 0x080c, 0xd760, 0x1938,
-	0x080c, 0x310a, 0x1920, 0x080c, 0xc897, 0x1d60, 0x703c, 0x6016,
-	0x6007, 0x004a, 0x6003, 0x0001, 0x080c, 0x8440, 0x0005, 0x080c,
-	0xc79f, 0x0904, 0xc6f7, 0x6007, 0x004e, 0x6003, 0x0001, 0x080c,
-	0x8440, 0x080c, 0x898b, 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, 0xae1c, 0x009e, 0x0110, 0x6017, 0x0001, 0x6003, 0x0001,
-	0x080c, 0x8440, 0x080c, 0x898b, 0x0005, 0x6007, 0x0050, 0x703c,
-	0x6016, 0x0ca0, 0x0016, 0x00e6, 0x2071, 0x0260, 0x00b6, 0x00c6,
-	0x2260, 0x6010, 0x2058, 0xb8bc, 0xd084, 0x0150, 0x7128, 0x6048,
-	0x9106, 0x1120, 0x712c, 0x6044, 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, 0x1004, 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, 0x1004, 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, 0x0f9d, 0x9006, 0x012e, 0x01de, 0x01ce, 0x00ee,
-	0x008e, 0x009e, 0x001e, 0x0005, 0x0006, 0x0016, 0x0026, 0x0036,
-	0x00c6, 0x918c, 0xffff, 0x11a8, 0x080c, 0x224e, 0x2099, 0x026c,
-	0x2001, 0x0014, 0x3518, 0x9312, 0x1218, 0x23a8, 0x4003, 0x00f8,
-	0x20a8, 0x4003, 0x22a8, 0x8108, 0x080c, 0x224e, 0x2099, 0x0260,
-	0x0ca8, 0x080c, 0x224e, 0x2061, 0x1978, 0x6004, 0x2098, 0x6008,
-	0x3518, 0x9312, 0x1218, 0x23a8, 0x4003, 0x0048, 0x20a8, 0x4003,
-	0x22a8, 0x8108, 0x080c, 0x224e, 0x2099, 0x0260, 0x0ca8, 0x2061,
-	0x1978, 0x2019, 0x0280, 0x3300, 0x931e, 0x0110, 0x6006, 0x0020,
-	0x2001, 0x0260, 0x6006, 0x8108, 0x2162, 0x9292, 0x0021, 0x9296,
+	0x0016, 0x080c, 0xa08d, 0x0180, 0x2b08, 0x6112, 0x080c, 0xc2b3,
+	0x6023, 0x0001, 0x2900, 0x6016, 0x001e, 0x080c, 0xa15d, 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,
+	0x2003, 0x0000, 0x6014, 0x2048, 0xa830, 0x20a8, 0x8906, 0x8006,
+	0x8007, 0x9094, 0x003f, 0x22e8, 0x9084, 0xffc0, 0x9080, 0x001b,
+	0x20a0, 0x2001, 0x1978, 0x0016, 0x200c, 0x080c, 0xcb1d, 0x001e,
+	0xa804, 0x9005, 0x0110, 0x2048, 0x0c38, 0x6014, 0x2048, 0xa867,
+	0x0103, 0x0010, 0x080c, 0xaa81, 0x080c, 0xa0e3, 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,
+	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,
+	0xa883, 0x0000, 0xa897, 0x4005, 0xa89b, 0x0004, 0x0126, 0x2091,
+	0x8000, 0xa867, 0x0139, 0x080c, 0x6ae9, 0x012e, 0x080c, 0xa0e3,
+	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,
+	0x6314, 0x2348, 0xa87a, 0xa982, 0x929e, 0x4000, 0x1580, 0x6310,
+	0x00c6, 0x2358, 0x2009, 0x0000, 0xa868, 0xd0f4, 0x1140, 0x080c,
+	0x66bf, 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,
+	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,
-	0x0006, 0x0016, 0x0026, 0x0036, 0x00c6, 0x81ff, 0x11b8, 0x080c,
-	0x2266, 0x20a1, 0x024c, 0x2001, 0x0014, 0x3518, 0x9312, 0x1218,
-	0x23a8, 0x4003, 0x0418, 0x20a8, 0x4003, 0x82ff, 0x01f8, 0x22a8,
-	0x8108, 0x080c, 0x2266, 0x20a1, 0x0240, 0x0c98, 0x080c, 0x2266,
-	0x2061, 0x197b, 0x6004, 0x20a0, 0x6008, 0x3518, 0x9312, 0x1218,
-	0x23a8, 0x4003, 0x0058, 0x20a8, 0x4003, 0x82ff, 0x0138, 0x22a8,
-	0x8108, 0x080c, 0x2266, 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, 0xc92f, 0x00de, 0x0005,
-	0x00d6, 0x080c, 0xc93c, 0x1520, 0x680c, 0x908c, 0xff00, 0x6820,
-	0x9084, 0x00ff, 0x9115, 0x6216, 0x6824, 0x602e, 0xd1e4, 0x0130,
-	0x9006, 0x080c, 0xd87c, 0x2009, 0x0001, 0x0078, 0xd1ec, 0x0180,
-	0x6920, 0x918c, 0x00ff, 0x6824, 0x080c, 0x2670, 0x1148, 0x2001,
-	0x0001, 0x080c, 0xd87c, 0x2110, 0x900e, 0x080c, 0x3030, 0x0018,
-	0x9085, 0x0001, 0x0008, 0x9006, 0x00de, 0x0005, 0x00b6, 0x00c6,
-	0x080c, 0x9e7c, 0x05a8, 0x0016, 0x0026, 0x00c6, 0x2011, 0x0263,
-	0x2204, 0x8211, 0x220c, 0x080c, 0x2670, 0x1578, 0x080c, 0x61f6,
-	0x1560, 0xbe12, 0xbd16, 0x00ce, 0x002e, 0x001e, 0x2b00, 0x6012,
-	0x080c, 0xd760, 0x11d8, 0x080c, 0x310a, 0x11c0, 0x080c, 0xc897,
-	0x0510, 0x2001, 0x0007, 0x080c, 0x61a7, 0x2001, 0x0007, 0x080c,
-	0x61d3, 0x6017, 0x0000, 0x6023, 0x0001, 0x6007, 0x0001, 0x6003,
-	0x0001, 0x080c, 0x8440, 0x080c, 0x898b, 0x0010, 0x080c, 0x9e2f,
-	0x9085, 0x0001, 0x00ce, 0x00be, 0x0005, 0x080c, 0x9e2f, 0x00ce,
-	0x002e, 0x001e, 0x0ca8, 0x080c, 0x9e2f, 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, 0x0db4, 0x91b6, 0x0013,
-	0x1130, 0x2008, 0x91b2, 0x0040, 0x1a04, 0xca84, 0x0092, 0x91b6,
-	0x0027, 0x0120, 0x91b6, 0x0014, 0x190c, 0x0db4, 0x2001, 0x0007,
-	0x080c, 0x61d3, 0x080c, 0x887f, 0x080c, 0x9e5f, 0x080c, 0x898b,
-	0x0005, 0xc9b9, 0xc9bb, 0xc9b9, 0xc9b9, 0xc9b9, 0xc9bb, 0xc9ca,
-	0xca7d, 0xca1c, 0xca7d, 0xca2e, 0xca7d, 0xc9ca, 0xca7d, 0xca75,
-	0xca7d, 0xca75, 0xca7d, 0xca7d, 0xc9b9, 0xc9b9, 0xc9b9, 0xc9b9,
-	0xc9b9, 0xc9b9, 0xc9b9, 0xc9b9, 0xc9b9, 0xc9b9, 0xc9b9, 0xc9bb,
-	0xc9b9, 0xca7d, 0xc9b9, 0xc9b9, 0xca7d, 0xc9b9, 0xca7a, 0xca7d,
-	0xc9b9, 0xc9b9, 0xc9b9, 0xc9b9, 0xca7d, 0xca7d, 0xc9b9, 0xca7d,
-	0xca7d, 0xc9b9, 0xc9c5, 0xc9b9, 0xc9b9, 0xc9b9, 0xc9b9, 0xca79,
-	0xca7d, 0xc9b9, 0xc9b9, 0xca7d, 0xca7d, 0xc9b9, 0xc9b9, 0xc9b9,
-	0xc9b9, 0x080c, 0x0db4, 0x080c, 0x887f, 0x080c, 0xc253, 0x6003,
-	0x0002, 0x080c, 0x898b, 0x0804, 0xca83, 0x9006, 0x080c, 0x6193,
-	0x0804, 0xca7d, 0x080c, 0x6572, 0x1904, 0xca7d, 0x9006, 0x080c,
-	0x6193, 0x6010, 0x2058, 0xb810, 0x9086, 0x00ff, 0x1140, 0x00f6,
-	0x2079, 0x1800, 0x78a4, 0x8000, 0x78a6, 0x00fe, 0x0428, 0x6010,
-	0x2058, 0xb8b0, 0x9005, 0x1178, 0x080c, 0xc23b, 0x1904, 0xca7d,
-	0x0036, 0x0046, 0xbba0, 0x2021, 0x0007, 0x080c, 0x4a91, 0x004e,
-	0x003e, 0x0804, 0xca7d, 0x080c, 0x313b, 0x1904, 0xca7d, 0x2001,
-	0x1800, 0x2004, 0x9086, 0x0002, 0x1138, 0x00f6, 0x2079, 0x1800,
-	0x78a4, 0x8000, 0x78a6, 0x00fe, 0x2001, 0x0002, 0x080c, 0x61a7,
-	0x080c, 0x887f, 0x6023, 0x0001, 0x6003, 0x0001, 0x6007, 0x0002,
-	0x080c, 0x8440, 0x080c, 0x898b, 0x6110, 0x2158, 0x2009, 0x0001,
-	0x080c, 0x804d, 0x0804, 0xca83, 0x6610, 0x2658, 0xbe04, 0x96b4,
-	0xff00, 0x8637, 0x9686, 0x0006, 0x0904, 0xca7d, 0x9686, 0x0004,
-	0x0904, 0xca7d, 0x2001, 0x0004, 0x0804, 0xca7b, 0x2001, 0x1800,
-	0x2004, 0x9086, 0x0003, 0x1158, 0x0036, 0x0046, 0x6010, 0x2058,
-	0xbba0, 0x2021, 0x0006, 0x080c, 0x4a91, 0x004e, 0x003e, 0x2001,
-	0x0006, 0x080c, 0xcaa1, 0x6610, 0x2658, 0xbe04, 0x0066, 0x96b4,
-	0xff00, 0x8637, 0x9686, 0x0006, 0x006e, 0x0168, 0x2001, 0x0006,
-	0x080c, 0x61d3, 0x9284, 0x00ff, 0x908e, 0x0007, 0x1120, 0x2001,
-	0x0006, 0x080c, 0x61a7, 0x080c, 0x6572, 0x11f8, 0x2001, 0x1836,
-	0x2004, 0xd0a4, 0x01d0, 0xbe04, 0x96b4, 0x00ff, 0x9686, 0x0006,
-	0x01a0, 0x00f6, 0x2079, 0x1800, 0x78a4, 0x8000, 0x78a6, 0x00fe,
-	0x0804, 0xca04, 0x2001, 0x0004, 0x0030, 0x2001, 0x0006, 0x0449,
-	0x0020, 0x0018, 0x0010, 0x080c, 0x61d3, 0x080c, 0x887f, 0x080c,
-	0x9e2f, 0x080c, 0x898b, 0x0005, 0x2600, 0x0002, 0xca98, 0xca98,
-	0xca98, 0xca98, 0xca98, 0xca9a, 0xca98, 0xca98, 0xca98, 0xca98,
-	0xca9a, 0xca98, 0xca98, 0xca98, 0xca9a, 0xca9a, 0xca9a, 0xca9a,
-	0x080c, 0x0db4, 0x080c, 0x887f, 0x080c, 0x9e2f, 0x080c, 0x898b,
-	0x0005, 0x0016, 0x00b6, 0x00d6, 0x6110, 0x2158, 0xb900, 0xd184,
-	0x0138, 0x080c, 0x61a7, 0x9006, 0x080c, 0x6193, 0x080c, 0x3010,
-	0x00de, 0x00be, 0x001e, 0x0005, 0x6610, 0x2658, 0xb804, 0x9084,
-	0xff00, 0x8007, 0x90b2, 0x000c, 0x1a0c, 0x0db4, 0x91b6, 0x0015,
-	0x1110, 0x003b, 0x0028, 0x91b6, 0x0016, 0x190c, 0x0db4, 0x006b,
-	0x0005, 0xa8ae, 0xa8ae, 0xa8ae, 0xa8ae, 0xcb36, 0xa8ae, 0xcb20,
-	0xcae1, 0xa8ae, 0xa8ae, 0xa8ae, 0xa8ae, 0xa8ae, 0xa8ae, 0xa8ae,
-	0xa8ae, 0xcb36, 0xa8ae, 0xcb20, 0xcb27, 0xa8ae, 0xa8ae, 0xa8ae,
-	0xa8ae, 0x00f6, 0x080c, 0x6572, 0x11d8, 0x080c, 0xc23b, 0x11c0,
-	0x6010, 0x905d, 0x01a8, 0xb8b0, 0x9005, 0x0190, 0x9006, 0x080c,
-	0x6193, 0x2001, 0x0002, 0x080c, 0x61a7, 0x6023, 0x0001, 0x6003,
-	0x0001, 0x6007, 0x0002, 0x080c, 0x8440, 0x080c, 0x898b, 0x00f0,
-	0x2011, 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x2670, 0x11b0,
-	0x080c, 0x6256, 0x0118, 0x080c, 0x9e2f, 0x0080, 0xb810, 0x0006,
-	0xb814, 0x0006, 0xb8b0, 0x0006, 0x080c, 0x5cff, 0x000e, 0xb8b2,
-	0x000e, 0xb816, 0x000e, 0xb812, 0x080c, 0x9e2f, 0x00fe, 0x0005,
-	0x6604, 0x96b6, 0x001e, 0x1110, 0x080c, 0x9e2f, 0x0005, 0x080c,
-	0xac94, 0x1148, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x8440,
-	0x080c, 0x898b, 0x0010, 0x080c, 0x9e2f, 0x0005, 0x0804, 0x9e2f,
-	0x6004, 0x908a, 0x0053, 0x1a0c, 0x0db4, 0x080c, 0x887f, 0x080c,
-	0x9e5f, 0x080c, 0x898b, 0x0005, 0x9182, 0x0040, 0x0002, 0xcb5b,
-	0xcb5b, 0xcb5b, 0xcb5b, 0xcb5d, 0xcb5b, 0xcb5b, 0xcb5b, 0xcb5b,
-	0xcb5b, 0xcb5b, 0xcb5b, 0xcb5b, 0xcb5b, 0xcb5b, 0xcb5b, 0xcb5b,
-	0xcb5b, 0xcb5b, 0xcb5b, 0x080c, 0x0db4, 0x0096, 0x00b6, 0x00d6,
-	0x00e6, 0x00f6, 0x0046, 0x0026, 0x6210, 0x2258, 0xb8ac, 0x9005,
-	0x11a8, 0x6106, 0x2071, 0x0260, 0x7444, 0x94a4, 0xff00, 0x0904,
-	0xcbc3, 0x080c, 0xd870, 0x1170, 0x9486, 0x2000, 0x1158, 0x2009,
-	0x0001, 0x2011, 0x0200, 0x080c, 0x8236, 0x0020, 0x9026, 0x080c,
-	0xd7a5, 0x0c38, 0x080c, 0x0feb, 0x090c, 0x0db4, 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,
-	0x68a0, 0x001e, 0x080c, 0xd870, 0x1904, 0xcc23, 0x9486, 0x2000,
-	0x1130, 0x2019, 0x0017, 0x080c, 0xd4e0, 0x0804, 0xcc23, 0x9486,
-	0x0200, 0x1120, 0x080c, 0xd47c, 0x0804, 0xcc23, 0x9486, 0x0400,
-	0x0120, 0x9486, 0x1000, 0x1904, 0xcc23, 0x2019, 0x0002, 0x080c,
-	0xd497, 0x0804, 0xcc23, 0x2069, 0x1a48, 0x6a00, 0xd284, 0x0904,
-	0xcc8d, 0x9284, 0x0300, 0x1904, 0xcc86, 0x6804, 0x9005, 0x0904,
-	0xcc6e, 0x2d78, 0x6003, 0x0007, 0x080c, 0x1004, 0x0904, 0xcc2f,
-	0x7800, 0xd08c, 0x1118, 0x7804, 0x8001, 0x7806, 0x6017, 0x0000,
-	0x2001, 0x180f, 0x2004, 0xd084, 0x1904, 0xcc91, 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, 0xcc2b, 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, 0x68a0, 0x002e, 0x004e, 0x00fe, 0x00ee, 0x00de,
-	0x00be, 0x009e, 0x0005, 0x0000, 0x0080, 0x0040, 0x0000, 0x2001,
-	0x1810, 0x2004, 0xd084, 0x0120, 0x080c, 0x0feb, 0x1904, 0xcbd8,
-	0x6017, 0xf100, 0x6003, 0x0001, 0x6007, 0x0041, 0x080c, 0x83f8,
-	0x080c, 0x898b, 0x0c00, 0x2069, 0x0260, 0x6848, 0x9084, 0xff00,
-	0x9086, 0x1200, 0x1198, 0x686c, 0x9084, 0x00ff, 0x0016, 0x6114,
-	0x918c, 0xf700, 0x910d, 0x6116, 0x001e, 0x6003, 0x0001, 0x6007,
-	0x0043, 0x080c, 0x83f8, 0x080c, 0x898b, 0x0828, 0x6868, 0x602e,
-	0x686c, 0x6032, 0x6017, 0xf200, 0x6003, 0x0001, 0x6007, 0x0041,
-	0x080c, 0x83f8, 0x080c, 0x898b, 0x0804, 0xcc23, 0x2001, 0x180e,
-	0x2004, 0xd0ec, 0x0120, 0x2011, 0x8049, 0x080c, 0x48f4, 0x6017,
-	0xf300, 0x0010, 0x6017, 0xf100, 0x6003, 0x0001, 0x6007, 0x0041,
-	0x080c, 0x83f8, 0x080c, 0x898b, 0x0804, 0xcc23, 0x6017, 0xf500,
-	0x0c98, 0x6017, 0xf600, 0x0804, 0xcc43, 0x6017, 0xf200, 0x0804,
-	0xcc43, 0xa867, 0x0146, 0xa86b, 0x0000, 0x6008, 0xa886, 0x2c00,
-	0xa87a, 0x7044, 0x9084, 0x0003, 0x9080, 0xcc2b, 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,
-	0x0db4, 0x8210, 0x821c, 0x2001, 0x026c, 0x2098, 0xa860, 0x20e8,
-	0xa85c, 0x9080, 0x0029, 0x20a0, 0x2011, 0xcd0d, 0x2041, 0x0001,
-	0x223d, 0x9784, 0x00ff, 0x9322, 0x1208, 0x2300, 0x20a8, 0x4003,
-	0x931a, 0x0530, 0x8210, 0xd7fc, 0x1130, 0x8d68, 0x2d0a, 0x2001,
-	0x0260, 0x2098, 0x0c68, 0x2950, 0x080c, 0x1004, 0x0170, 0x2900,
-	0xb002, 0xa867, 0x0147, 0xa86b, 0x0000, 0xa860, 0x20e8, 0xa85c,
-	0x9080, 0x001b, 0x20a0, 0x8840, 0x08d8, 0x2548, 0xa800, 0x902d,
-	0x0118, 0x080c, 0x101d, 0x0cc8, 0x080c, 0x101d, 0x0804, 0xcc2f,
-	0x2548, 0x8847, 0x9885, 0x0046, 0xa866, 0x2009, 0x0205, 0x200b,
-	0x0000, 0x080c, 0xd50f, 0x0804, 0xcc23, 0x8010, 0x0004, 0x801a,
-	0x0006, 0x8018, 0x0008, 0x8016, 0x000a, 0x8014, 0x9186, 0x0013,
-	0x1160, 0x6004, 0x908a, 0x0054, 0x1a0c, 0x0db4, 0x9082, 0x0040,
-	0x0a0c, 0x0db4, 0x2008, 0x0804, 0xcdbf, 0x9186, 0x0051, 0x0108,
-	0x00c0, 0x2001, 0x0109, 0x2004, 0xd084, 0x0904, 0xcd6f, 0x0126,
-	0x2091, 0x2800, 0x0006, 0x0016, 0x0026, 0x080c, 0x82e4, 0x002e,
-	0x001e, 0x000e, 0x012e, 0x6000, 0x9086, 0x0002, 0x1580, 0x0804,
-	0xce08, 0x9186, 0x0027, 0x0530, 0x9186, 0x0048, 0x0128, 0x9186,
-	0x0014, 0x0500, 0x190c, 0x0db4, 0x2001, 0x0109, 0x2004, 0xd084,
-	0x01f0, 0x00c6, 0x0126, 0x2091, 0x2800, 0x00c6, 0x2061, 0x0100,
-	0x0006, 0x0016, 0x0026, 0x080c, 0x82e4, 0x002e, 0x001e, 0x000e,
-	0x00ce, 0x012e, 0x00ce, 0x6000, 0x9086, 0x0004, 0x190c, 0x0db4,
-	0x0804, 0xceeb, 0x6004, 0x9082, 0x0040, 0x2008, 0x001a, 0x080c,
-	0x9ec4, 0x0005, 0xcd86, 0xcd88, 0xcd88, 0xcdaf, 0xcd86, 0xcd86,
-	0xcd86, 0xcd86, 0xcd86, 0xcd86, 0xcd86, 0xcd86, 0xcd86, 0xcd86,
-	0xcd86, 0xcd86, 0xcd86, 0xcd86, 0xcd86, 0xcd86, 0x080c, 0x0db4,
-	0x080c, 0x887f, 0x080c, 0x898b, 0x0036, 0x0096, 0x6014, 0x904d,
-	0x01d8, 0x080c, 0xbb3b, 0x01c0, 0x6003, 0x0002, 0x6010, 0x00b6,
-	0x2058, 0xb800, 0x00be, 0xd0bc, 0x1178, 0x2019, 0x0004, 0x080c,
-	0xd50f, 0x6017, 0x0000, 0x6018, 0x9005, 0x1120, 0x2001, 0x195f,
-	0x2004, 0x601a, 0x6003, 0x0007, 0x009e, 0x003e, 0x0005, 0x0096,
-	0x080c, 0x887f, 0x080c, 0x898b, 0x080c, 0xbb3b, 0x0120, 0x6014,
-	0x2048, 0x080c, 0x101d, 0x080c, 0x9e5f, 0x009e, 0x0005, 0x0002,
-	0xcdd4, 0xcdeb, 0xcdd6, 0xce02, 0xcdd4, 0xcdd4, 0xcdd4, 0xcdd4,
-	0xcdd4, 0xcdd4, 0xcdd4, 0xcdd4, 0xcdd4, 0xcdd4, 0xcdd4, 0xcdd4,
-	0xcdd4, 0xcdd4, 0xcdd4, 0xcdd4, 0x080c, 0x0db4, 0x0096, 0x080c,
-	0x887f, 0x6014, 0x2048, 0xa87c, 0xd0b4, 0x0138, 0x6003, 0x0007,
-	0x2009, 0x0043, 0x080c, 0x9ea9, 0x0010, 0x6003, 0x0004, 0x080c,
-	0x898b, 0x009e, 0x0005, 0x080c, 0x887f, 0x080c, 0xbb3b, 0x0138,
-	0x6114, 0x0096, 0x2148, 0xa97c, 0x009e, 0xd1ec, 0x1138, 0x080c,
-	0x820b, 0x080c, 0x9e2f, 0x080c, 0x898b, 0x0005, 0x080c, 0xd769,
-	0x0db0, 0x0cc8, 0x080c, 0x887f, 0x2009, 0x0041, 0x0804, 0xcf73,
-	0x9182, 0x0040, 0x0002, 0xce1f, 0xce21, 0xce1f, 0xce1f, 0xce1f,
-	0xce1f, 0xce1f, 0xce1f, 0xce1f, 0xce1f, 0xce1f, 0xce1f, 0xce1f,
-	0xce1f, 0xce1f, 0xce1f, 0xce1f, 0xce22, 0xce1f, 0xce1f, 0x080c,
-	0x0db4, 0x0005, 0x00d6, 0x080c, 0x820b, 0x00de, 0x080c, 0xd7c1,
-	0x080c, 0x9e2f, 0x0005, 0x9182, 0x0040, 0x0002, 0xce42, 0xce42,
-	0xce42, 0xce42, 0xce42, 0xce42, 0xce42, 0xce42, 0xce42, 0xce44,
-	0xceb3, 0xce42, 0xce42, 0xce42, 0xce42, 0xceb3, 0xce42, 0xce42,
-	0xce42, 0xce42, 0x080c, 0x0db4, 0x2001, 0x0105, 0x2004, 0x9084,
-	0x1800, 0x01c8, 0x2001, 0x0132, 0x200c, 0x2001, 0x0131, 0x2004,
-	0x9105, 0x1904, 0xceb3, 0x2009, 0x180c, 0x2104, 0xd0d4, 0x0904,
-	0xceb3, 0xc0d4, 0x200a, 0x2009, 0x0105, 0x2104, 0x9084, 0xe7fd,
-	0x9085, 0x0010, 0x200a, 0x2001, 0x187b, 0x2004, 0xd0e4, 0x1528,
-	0x603b, 0x0000, 0x080c, 0x893b, 0x6014, 0x0096, 0x2048, 0xa87c,
-	0xd0fc, 0x0188, 0x908c, 0x0003, 0x918e, 0x0002, 0x0508, 0x2001,
-	0x180c, 0x2004, 0xd0d4, 0x11e0, 0x080c, 0x8a68, 0x2009, 0x0041,
-	0x009e, 0x0804, 0xcf73, 0x080c, 0x8a68, 0x6003, 0x0007, 0x601b,
-	0x0000, 0x080c, 0x820b, 0x009e, 0x0005, 0x2001, 0x0100, 0x2004,
-	0x9082, 0x0005, 0x0aa8, 0x2001, 0x011f, 0x2004, 0x603a, 0x0890,
-	0x2001, 0x180c, 0x200c, 0xc1d4, 0x2102, 0xd1cc, 0x0110, 0x080c,
-	0x2a84, 0x080c, 0x8a68, 0x6014, 0x2048, 0xa97c, 0xd1ec, 0x1130,
-	0x080c, 0x820b, 0x080c, 0x9e2f, 0x009e, 0x0005, 0x080c, 0xd769,
-	0x0db8, 0x009e, 0x0005, 0x2001, 0x180c, 0x200c, 0xc1d4, 0x2102,
-	0x0036, 0x080c, 0x893b, 0x080c, 0x8a68, 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, 0xd50f, 0x6018, 0x9005, 0x1128, 0x2001,
-	0x195f, 0x2004, 0x8003, 0x601a, 0x6017, 0x0000, 0x6003, 0x0007,
-	0x009e, 0x003e, 0x0005, 0x9182, 0x0040, 0x0002, 0xcf02, 0xcf02,
-	0xcf02, 0xcf02, 0xcf02, 0xcf02, 0xcf02, 0xcf02, 0xcf04, 0xcf02,
-	0xcf02, 0xcf02, 0xcf02, 0xcf02, 0xcf02, 0xcf02, 0xcf02, 0xcf02,
-	0xcf02, 0xcf4f, 0x080c, 0x0db4, 0x6014, 0x0096, 0x2048, 0xa834,
-	0xaa38, 0x6110, 0x00b6, 0x2158, 0xb900, 0x00be, 0xd1bc, 0x1190,
-	0x920d, 0x1518, 0xa87c, 0xd0fc, 0x0128, 0x2009, 0x0041, 0x009e,
-	0x0804, 0xcf73, 0x6003, 0x0007, 0x601b, 0x0000, 0x080c, 0x820b,
-	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,
-	0x820d, 0x009e, 0x0005, 0x6003, 0x0002, 0x009e, 0x0005, 0x6024,
-	0xd0f4, 0x0128, 0x080c, 0x1511, 0x1904, 0xcf04, 0x0005, 0x6014,
-	0x0096, 0x2048, 0xa834, 0xa938, 0x009e, 0x9105, 0x1120, 0x080c,
-	0x1511, 0x1904, 0xcf04, 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, 0x0db4, 0x6024, 0xd0dc,
-	0x090c, 0x0db4, 0x0005, 0xcf97, 0xcfa3, 0xcfaf, 0xcfbb, 0xcf97,
-	0xcf97, 0xcf97, 0xcf97, 0xcf9e, 0xcf99, 0xcf99, 0xcf97, 0xcf97,
-	0xcf97, 0xcf97, 0xcf99, 0xcf97, 0xcf99, 0xcf97, 0xcf9e, 0x080c,
-	0x0db4, 0x6024, 0xd0dc, 0x090c, 0x0db4, 0x0005, 0x6014, 0x9005,
-	0x190c, 0x0db4, 0x0005, 0x6003, 0x0001, 0x6106, 0x080c, 0x83f8,
-	0x0126, 0x2091, 0x8000, 0x080c, 0x898b, 0x012e, 0x0005, 0x6003,
-	0x0001, 0x6106, 0x080c, 0x83f8, 0x0126, 0x2091, 0x8000, 0x080c,
-	0x898b, 0x012e, 0x0005, 0x6003, 0x0003, 0x6106, 0x2c10, 0x080c,
-	0x1a69, 0x0126, 0x2091, 0x8000, 0x080c, 0x845d, 0x080c, 0x8a68,
-	0x012e, 0x0005, 0x0126, 0x2091, 0x8000, 0x0036, 0x0096, 0x9182,
-	0x0040, 0x0023, 0x009e, 0x003e, 0x012e, 0x0005, 0xcfea, 0xcfec,
-	0xcffe, 0xd018, 0xcfea, 0xcfea, 0xcfea, 0xcfea, 0xcfea, 0xcfea,
-	0xcfea, 0xcfea, 0xcfea, 0xcfea, 0xcfea, 0xcfea, 0xcfea, 0xcfea,
-	0xcfea, 0xcfea, 0x080c, 0x0db4, 0x6014, 0x2048, 0xa87c, 0xd0fc,
-	0x01f8, 0x909c, 0x0003, 0x939e, 0x0003, 0x01d0, 0x6003, 0x0001,
-	0x6106, 0x080c, 0x83f8, 0x080c, 0x898b, 0x0470, 0x6014, 0x2048,
-	0xa87c, 0xd0fc, 0x0168, 0x909c, 0x0003, 0x939e, 0x0003, 0x0140,
-	0x6003, 0x0001, 0x6106, 0x080c, 0x83f8, 0x080c, 0x898b, 0x00e0,
-	0x901e, 0x6316, 0x631a, 0x2019, 0x0004, 0x080c, 0xd50f, 0x00a0,
-	0x6014, 0x2048, 0xa87c, 0xd0fc, 0x0d98, 0x909c, 0x0003, 0x939e,
-	0x0003, 0x0d70, 0x6003, 0x0003, 0x6106, 0x2c10, 0x080c, 0x1a69,
-	0x080c, 0x845d, 0x080c, 0x8a68, 0x0005, 0x080c, 0x887f, 0x6114,
-	0x81ff, 0x0158, 0x0096, 0x2148, 0x080c, 0xd80d, 0x0036, 0x2019,
-	0x0029, 0x080c, 0xd50f, 0x003e, 0x009e, 0x080c, 0x9e5f, 0x080c,
-	0x898b, 0x0005, 0x080c, 0x893b, 0x6114, 0x81ff, 0x0158, 0x0096,
-	0x2148, 0x080c, 0xd80d, 0x0036, 0x2019, 0x0029, 0x080c, 0xd50f,
-	0x003e, 0x009e, 0x080c, 0x9e5f, 0x080c, 0x8a68, 0x0005, 0x9182,
-	0x0085, 0x0002, 0xd069, 0xd067, 0xd067, 0xd075, 0xd067, 0xd067,
-	0xd067, 0xd067, 0xd067, 0xd067, 0xd067, 0xd067, 0xd067, 0x080c,
-	0x0db4, 0x6003, 0x000b, 0x6106, 0x080c, 0x83f8, 0x0126, 0x2091,
-	0x8000, 0x080c, 0x898b, 0x012e, 0x0005, 0x0026, 0x00e6, 0x080c,
-	0xd760, 0x0118, 0x080c, 0x9e2f, 0x0450, 0x2071, 0x0260, 0x7224,
-	0x6216, 0x2001, 0x180e, 0x2004, 0xd0e4, 0x0150, 0x6010, 0x00b6,
-	0x2058, 0xbca0, 0x00be, 0x2c00, 0x2011, 0x014e, 0x080c, 0xa14f,
-	0x7220, 0x080c, 0xd3b5, 0x0118, 0x6007, 0x0086, 0x0040, 0x6007,
-	0x0087, 0x7224, 0x9296, 0xffff, 0x1110, 0x6007, 0x0086, 0x6003,
-	0x0001, 0x080c, 0x83f8, 0x080c, 0x898b, 0x080c, 0x8a68, 0x00ee,
-	0x002e, 0x0005, 0x9186, 0x0013, 0x1160, 0x6004, 0x908a, 0x0085,
-	0x0a0c, 0x0db4, 0x908a, 0x0092, 0x1a0c, 0x0db4, 0x9082, 0x0085,
-	0x00a2, 0x9186, 0x0027, 0x0130, 0x9186, 0x0014, 0x0118, 0x080c,
-	0x9ec4, 0x0050, 0x2001, 0x0007, 0x080c, 0x61d3, 0x080c, 0x887f,
-	0x080c, 0x9e5f, 0x080c, 0x898b, 0x0005, 0xd0da, 0xd0dc, 0xd0dc,
-	0xd0da, 0xd0da, 0xd0da, 0xd0da, 0xd0da, 0xd0da, 0xd0da, 0xd0da,
-	0xd0da, 0xd0da, 0x080c, 0x0db4, 0x080c, 0x887f, 0x080c, 0x9e5f,
-	0x080c, 0x898b, 0x0005, 0x9182, 0x0085, 0x0a0c, 0x0db4, 0x9182,
-	0x0092, 0x1a0c, 0x0db4, 0x9182, 0x0085, 0x0002, 0xd0fb, 0xd0fb,
-	0xd0fb, 0xd0fd, 0xd0fb, 0xd0fb, 0xd0fb, 0xd0fb, 0xd0fb, 0xd0fb,
-	0xd0fb, 0xd0fb, 0xd0fb, 0x080c, 0x0db4, 0x0005, 0x9186, 0x0013,
-	0x0148, 0x9186, 0x0014, 0x0130, 0x9186, 0x0027, 0x0118, 0x080c,
-	0x9ec4, 0x0030, 0x080c, 0x887f, 0x080c, 0x9e5f, 0x080c, 0x898b,
-	0x0005, 0x0036, 0x080c, 0xd7c1, 0x6043, 0x0000, 0x2019, 0x000b,
-	0x0031, 0x6023, 0x0006, 0x6003, 0x0007, 0x003e, 0x0005, 0x0126,
-	0x0036, 0x2091, 0x8000, 0x0086, 0x2c40, 0x0096, 0x904e, 0x080c,
-	0x97a4, 0x009e, 0x008e, 0x1550, 0x0076, 0x2c38, 0x080c, 0x984f,
-	0x007e, 0x1520, 0x6000, 0x9086, 0x0000, 0x0500, 0x6020, 0x9086,
-	0x0007, 0x01e0, 0x0096, 0x601c, 0xd084, 0x0140, 0x080c, 0xd7c1,
-	0x080c, 0xc253, 0x080c, 0x191f, 0x6023, 0x0007, 0x6014, 0x2048,
-	0x080c, 0xbb3b, 0x0110, 0x080c, 0xd50f, 0x009e, 0x6017, 0x0000,
-	0x080c, 0xd7c1, 0x6023, 0x0007, 0x080c, 0xc253, 0x003e, 0x012e,
-	0x0005, 0x00f6, 0x00c6, 0x00b6, 0x0036, 0x0156, 0x2079, 0x0260,
-	0x7938, 0x783c, 0x080c, 0x2670, 0x15c8, 0x0016, 0x00c6, 0x080c,
-	0x6256, 0x1590, 0x001e, 0x00c6, 0x2160, 0x080c, 0xc250, 0x00ce,
-	0x002e, 0x0026, 0x0016, 0x2019, 0x0029, 0x080c, 0x9915, 0x080c,
-	0x8582, 0x0076, 0x903e, 0x080c, 0x8470, 0x007e, 0x001e, 0x0076,
-	0x903e, 0x080c, 0xd2d5, 0x007e, 0x0026, 0xba04, 0x9294, 0xff00,
-	0x8217, 0x9286, 0x0006, 0x0118, 0x9286, 0x0004, 0x1118, 0xbaa0,
-	0x080c, 0x30a4, 0x002e, 0xbcb0, 0x001e, 0x080c, 0x5cff, 0xbe12,
-	0xbd16, 0xbcb2, 0x9006, 0x0010, 0x00ce, 0x001e, 0x015e, 0x003e,
-	0x00be, 0x00ce, 0x00fe, 0x0005, 0x00c6, 0x00d6, 0x00b6, 0x0016,
-	0x2009, 0x1823, 0x2104, 0x9086, 0x0074, 0x1904, 0xd1fd, 0x2069,
-	0x0260, 0x6944, 0x9182, 0x0100, 0x06e0, 0x6940, 0x9184, 0x8000,
-	0x0904, 0xd1fa, 0x2001, 0x1954, 0x2004, 0x9005, 0x1140, 0x6010,
-	0x2058, 0xb8b0, 0x9005, 0x0118, 0x9184, 0x0800, 0x0598, 0x6948,
-	0x918a, 0x0001, 0x0648, 0x080c, 0xd875, 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, 0x6265, 0x0804, 0xd264, 0x2011, 0x0276, 0x20a9,
-	0x0004, 0x0096, 0x2b48, 0x2019, 0x000a, 0x080c, 0xae1c, 0x009e,
-	0x15a0, 0x2011, 0x027a, 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019,
-	0x0006, 0x080c, 0xae1c, 0x009e, 0x1540, 0x0046, 0x0016, 0xbaa0,
-	0x2220, 0x9006, 0x2009, 0x185c, 0x210c, 0x0038, 0x2009, 0x0029,
-	0x080c, 0xd564, 0xb800, 0xc0e5, 0xb802, 0x2019, 0x0029, 0x080c,
-	0x8582, 0x0076, 0x2039, 0x0000, 0x080c, 0x8470, 0x2c08, 0x080c,
-	0xd2d5, 0x007e, 0x2001, 0x0007, 0x080c, 0x61d3, 0x2001, 0x0007,
-	0x080c, 0x61a7, 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, 0x2670, 0x11d0, 0x080c, 0x6256, 0x11b8,
-	0x2011, 0x0270, 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x000a,
-	0x080c, 0xae1c, 0x009e, 0x1158, 0x2011, 0x0274, 0x20a9, 0x0004,
-	0x0096, 0x2b48, 0x2019, 0x0006, 0x080c, 0xae1c, 0x009e, 0x015e,
-	0x003e, 0x002e, 0x001e, 0x00fe, 0x00be, 0x0005, 0x00b6, 0x0006,
-	0x0016, 0x0026, 0x0036, 0x0156, 0x2011, 0x0263, 0x2204, 0x8211,
-	0x220c, 0x080c, 0x2670, 0x11d0, 0x080c, 0x6256, 0x11b8, 0x2011,
-	0x0276, 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x000a, 0x080c,
-	0xae1c, 0x009e, 0x1158, 0x2011, 0x027a, 0x20a9, 0x0004, 0x0096,
-	0x2b48, 0x2019, 0x0006, 0x080c, 0xae1c, 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, 0x1a87, 0x000e, 0x0128, 0x8001, 0x9602, 0x1a04, 0xd36e,
-	0x0018, 0x9606, 0x0904, 0xd36e, 0x2100, 0x9c06, 0x0904, 0xd365,
-	0x080c, 0xd5a5, 0x1904, 0xd365, 0x080c, 0xd892, 0x0904, 0xd365,
-	0x080c, 0xd595, 0x0904, 0xd365, 0x6720, 0x9786, 0x0001, 0x1148,
-	0x080c, 0x313b, 0x0904, 0xd389, 0x6004, 0x9086, 0x0000, 0x1904,
-	0xd389, 0x9786, 0x0004, 0x0904, 0xd389, 0x9786, 0x0007, 0x0904,
-	0xd365, 0x2500, 0x9c06, 0x0904, 0xd365, 0x2400, 0x9c06, 0x05e8,
-	0x88ff, 0x0118, 0x6054, 0x9906, 0x15c0, 0x0096, 0x6000, 0x9086,
-	0x0004, 0x1120, 0x0016, 0x080c, 0x191f, 0x001e, 0x9786, 0x000a,
-	0x0148, 0x080c, 0xbd41, 0x1130, 0x080c, 0xa7cd, 0x009e, 0x080c,
-	0x9e5f, 0x0418, 0x6014, 0x2048, 0x080c, 0xbb3b, 0x01d8, 0x9786,
-	0x0003, 0x1570, 0xa867, 0x0103, 0xa87c, 0xd0cc, 0x0130, 0x0096,
-	0xa878, 0x2048, 0x080c, 0x0f9d, 0x009e, 0xab7a, 0xa877, 0x0000,
-	0x080c, 0xd80d, 0x0016, 0x080c, 0xbe2f, 0x080c, 0x6893, 0x001e,
-	0x080c, 0xbd24, 0x009e, 0x080c, 0x9e5f, 0x9ce0, 0x0018, 0x2001,
-	0x1819, 0x2004, 0x9c02, 0x1210, 0x0804, 0xd2e9, 0x012e, 0x002e,
-	0x004e, 0x005e, 0x006e, 0x007e, 0x008e, 0x00ce, 0x00ee, 0x0005,
-	0x9786, 0x0006, 0x1150, 0x9386, 0x0005, 0x0128, 0x080c, 0xd80d,
-	0x080c, 0xd50f, 0x08f8, 0x009e, 0x0c00, 0x9786, 0x000a, 0x0920,
-	0x0808, 0x81ff, 0x09d0, 0x9180, 0x0001, 0x2004, 0x9086, 0x0018,
-	0x0130, 0x9180, 0x0001, 0x2004, 0x9086, 0x002d, 0x1970, 0x6000,
-	0x9086, 0x0002, 0x1950, 0x080c, 0xbd30, 0x0130, 0x080c, 0xbd41,
-	0x1920, 0x080c, 0xa7cd, 0x0038, 0x080c, 0x3010, 0x080c, 0xbd41,
-	0x1110, 0x080c, 0xa7cd, 0x080c, 0x9e5f, 0x0804, 0xd365, 0xa864,
-	0x9084, 0x00ff, 0x9086, 0x0039, 0x0005, 0x00c6, 0x00e6, 0x0016,
-	0x2c08, 0x2170, 0x9006, 0x080c, 0xd536, 0x001e, 0x0120, 0x6020,
-	0x9084, 0x000f, 0x001b, 0x00ee, 0x00ce, 0x0005, 0xd3d4, 0xd3d4,
-	0xd3d4, 0xd3d4, 0xd3d4, 0xd3d4, 0xd3d6, 0xd3d4, 0xd3d4, 0xd3d4,
-	0xd3d4, 0x9e5f, 0x9e5f, 0xd3d4, 0x9006, 0x0005, 0x0036, 0x0046,
-	0x0016, 0x7010, 0x00b6, 0x2058, 0xbca0, 0x00be, 0x2c00, 0x2009,
-	0x0020, 0x080c, 0xd564, 0x001e, 0x004e, 0x2019, 0x0002, 0x080c,
-	0xd11f, 0x003e, 0x9085, 0x0001, 0x0005, 0x0096, 0x080c, 0xbb3b,
-	0x0140, 0x6014, 0x904d, 0x080c, 0xb75c, 0x687b, 0x0005, 0x080c,
-	0x68a0, 0x009e, 0x080c, 0x9e5f, 0x9085, 0x0001, 0x0005, 0x2001,
-	0x0001, 0x080c, 0x6193, 0x0156, 0x0016, 0x0026, 0x0036, 0x20a9,
-	0x0004, 0x2019, 0x1805, 0x2011, 0x0276, 0x080c, 0xae08, 0x003e,
-	0x002e, 0x001e, 0x015e, 0x9005, 0x0005, 0x00f6, 0x00e6, 0x00c6,
-	0x0086, 0x0076, 0x0066, 0x00b6, 0x0126, 0x2091, 0x8000, 0x2740,
-	0x2061, 0x1cd0, 0x2079, 0x0001, 0x8fff, 0x0904, 0xd46f, 0x2071,
-	0x1800, 0x7650, 0x7070, 0x8001, 0x9602, 0x1a04, 0xd46f, 0x88ff,
-	0x0120, 0x2800, 0x9c06, 0x1590, 0x2078, 0x080c, 0xd595, 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, 0xd7c1, 0x080c, 0xc253, 0x080c, 0x191f, 0x6023, 0x0007,
-	0x6014, 0x2048, 0x080c, 0xbb3b, 0x0120, 0x0046, 0x080c, 0xd50f,
-	0x004e, 0x009e, 0x080c, 0x9e5f, 0x88ff, 0x1198, 0x9ce0, 0x0018,
-	0x2001, 0x1819, 0x2004, 0x9c02, 0x1210, 0x0804, 0xd424, 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, 0x97a4, 0x009e, 0x008e, 0x903e, 0x080c,
-	0x984f, 0x080c, 0xd415, 0x005e, 0x007e, 0x00be, 0x0005, 0x00b6,
-	0x0046, 0x0056, 0x0076, 0x00c6, 0x0156, 0x2c20, 0x2128, 0x20a9,
-	0x007f, 0x900e, 0x0016, 0x0036, 0x080c, 0x6256, 0x1190, 0x0056,
-	0x0086, 0x9046, 0x2508, 0x2029, 0x0001, 0x0096, 0x904e, 0x080c,
-	0x97a4, 0x009e, 0x008e, 0x903e, 0x080c, 0x984f, 0x080c, 0xd415,
-	0x005e, 0x003e, 0x001e, 0x8108, 0x1f04, 0xd4a2, 0x015e, 0x00ce,
-	0x007e, 0x005e, 0x004e, 0x00be, 0x0005, 0x00b6, 0x0076, 0x0056,
-	0x6210, 0x2258, 0x0086, 0x9046, 0x2029, 0x0001, 0x2019, 0x0048,
-	0x0096, 0x904e, 0x080c, 0x97a4, 0x009e, 0x008e, 0x903e, 0x080c,
-	0x984f, 0x2c20, 0x080c, 0xd415, 0x005e, 0x007e, 0x00be, 0x0005,
-	0x00b6, 0x0046, 0x0056, 0x0076, 0x00c6, 0x0156, 0x2c20, 0x20a9,
-	0x0800, 0x900e, 0x0016, 0x0036, 0x080c, 0x6256, 0x11a0, 0x0086,
-	0x9046, 0x2828, 0x0046, 0x2021, 0x0001, 0x080c, 0xd7a5, 0x004e,
-	0x0096, 0x904e, 0x080c, 0x97a4, 0x009e, 0x008e, 0x903e, 0x080c,
-	0x984f, 0x080c, 0xd415, 0x003e, 0x001e, 0x8108, 0x1f04, 0xd4ea,
-	0x015e, 0x00ce, 0x007e, 0x005e, 0x004e, 0x00be, 0x0005, 0x0016,
-	0x00f6, 0x080c, 0xbb39, 0x0198, 0xa864, 0x9084, 0x00ff, 0x9086,
-	0x0046, 0x0180, 0xa800, 0x907d, 0x0138, 0xa803, 0x0000, 0xab82,
-	0x080c, 0x68a0, 0x2f48, 0x0cb0, 0xab82, 0x080c, 0x68a0, 0x00fe,
-	0x001e, 0x0005, 0xa800, 0x907d, 0x0130, 0xa803, 0x0000, 0x080c,
-	0x68a0, 0x2f48, 0x0cb8, 0x080c, 0x68a0, 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, 0x0feb,
-	0x000e, 0x090c, 0x0db4, 0xaae2, 0xa867, 0x010d, 0xa88e, 0x0026,
-	0x2010, 0x080c, 0xbb29, 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, 0x68a0, 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, 0x83f8, 0x080c, 0x898b, 0x001e, 0x0005, 0xa001, 0xa001,
-	0x0005, 0x6024, 0xd0e4, 0x0158, 0xd0cc, 0x0118, 0x080c, 0xbe73,
-	0x0030, 0x080c, 0xd7c1, 0x080c, 0x820b, 0x080c, 0x9e2f, 0x0005,
-	0x9280, 0x0008, 0x2004, 0x9084, 0x000f, 0x0002, 0xd5f4, 0xd5f4,
-	0xd5f4, 0xd5f6, 0xd5f4, 0xd5f6, 0xd5f6, 0xd5f4, 0xd5f6, 0xd5f4,
-	0xd5f4, 0xd5f4, 0xd5f4, 0xd5f4, 0x9006, 0x0005, 0x9085, 0x0001,
-	0x0005, 0x9280, 0x0008, 0x2004, 0x9084, 0x000f, 0x0002, 0xd60d,
-	0xd60d, 0xd60d, 0xd60d, 0xd60d, 0xd60d, 0xd61a, 0xd60d, 0xd60d,
-	0xd60d, 0xd60d, 0xd60d, 0xd60d, 0xd60d, 0x6007, 0x003b, 0x602f,
-	0x0009, 0x6017, 0x2a00, 0x6003, 0x0001, 0x080c, 0x83f8, 0x080c,
-	0x898b, 0x0005, 0x0096, 0x00c6, 0x2260, 0x080c, 0xd7c1, 0x6043,
-	0x0000, 0x6024, 0xc0f4, 0xc0e4, 0x6026, 0x603b, 0x0000, 0x00ce,
-	0x00d6, 0x2268, 0x9186, 0x0007, 0x1904, 0xd673, 0x6814, 0x9005,
-	0x0138, 0x2048, 0xa87c, 0xd0fc, 0x1118, 0x00de, 0x009e, 0x08a8,
-	0x6007, 0x003a, 0x6003, 0x0001, 0x080c, 0x83f8, 0x080c, 0x898b,
-	0x00c6, 0x2d60, 0x6100, 0x9186, 0x0002, 0x1904, 0xd6ea, 0x6014,
-	0x9005, 0x1138, 0x6000, 0x9086, 0x0007, 0x190c, 0x0db4, 0x0804,
-	0xd6ea, 0x2048, 0x080c, 0xbb3b, 0x1130, 0x0028, 0x2048, 0xa800,
-	0x9005, 0x1de0, 0x2900, 0x2048, 0xa87c, 0x9084, 0x0003, 0x9086,
-	0x0002, 0x1168, 0xa87c, 0xc0dc, 0xc0f4, 0xa87e, 0xa880, 0xc0fc,
-	0xa882, 0x2009, 0x0043, 0x080c, 0xcf73, 0x0804, 0xd6ea, 0x2009,
-	0x0041, 0x0804, 0xd6e4, 0x9186, 0x0005, 0x15a0, 0x6814, 0x2048,
-	0xa87c, 0xd0bc, 0x1120, 0x00de, 0x009e, 0x0804, 0xd60d, 0xd0b4,
-	0x0128, 0xd0fc, 0x090c, 0x0db4, 0x0804, 0xd62e, 0x6007, 0x003a,
-	0x6003, 0x0001, 0x080c, 0x83f8, 0x080c, 0x898b, 0x00c6, 0x2d60,
-	0x6100, 0x9186, 0x0002, 0x0120, 0x9186, 0x0004, 0x1904, 0xd6ea,
-	0x6814, 0x2048, 0xa97c, 0xc1f4, 0xc1dc, 0xa97e, 0xa980, 0xc1fc,
-	0xc1bc, 0xa982, 0x00f6, 0x2c78, 0x080c, 0x164a, 0x00fe, 0x2009,
-	0x0042, 0x04d0, 0x0036, 0x080c, 0x0feb, 0x090c, 0x0db4, 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, 0x68a0, 0x2019, 0x0045, 0x6008, 0x2068, 0x080c,
-	0xd11f, 0x2d00, 0x600a, 0x6023, 0x0006, 0x6003, 0x0007, 0x901e,
-	0x631a, 0x6342, 0x003e, 0x0038, 0x6043, 0x0000, 0x6003, 0x0007,
-	0x080c, 0xcf73, 0x00ce, 0x00de, 0x009e, 0x0005, 0x9186, 0x0013,
-	0x1128, 0x6004, 0x9082, 0x0085, 0x2008, 0x00c2, 0x9186, 0x0027,
-	0x1178, 0x080c, 0x887f, 0x0036, 0x0096, 0x6014, 0x2048, 0x2019,
-	0x0004, 0x080c, 0xd50f, 0x009e, 0x003e, 0x080c, 0x898b, 0x0005,
-	0x9186, 0x0014, 0x0d70, 0x080c, 0x9ec4, 0x0005, 0xd71d, 0xd71b,
-	0xd71b, 0xd71b, 0xd71b, 0xd71b, 0xd71d, 0xd71b, 0xd71b, 0xd71b,
-	0xd71b, 0xd71b, 0xd71b, 0x080c, 0x0db4, 0x080c, 0x887f, 0x6003,
-	0x000c, 0x080c, 0x898b, 0x0005, 0x9182, 0x0092, 0x1220, 0x9182,
-	0x0085, 0x0208, 0x001a, 0x080c, 0x9ec4, 0x0005, 0xd73b, 0xd73b,
-	0xd73b, 0xd73b, 0xd73d, 0xd75d, 0xd73b, 0xd73b, 0xd73b, 0xd73b,
-	0xd73b, 0xd73b, 0xd73b, 0x080c, 0x0db4, 0x00d6, 0x2c68, 0x080c,
-	0x9dd9, 0x01b0, 0x6003, 0x0001, 0x6007, 0x001e, 0x2009, 0x026e,
-	0x210c, 0x613a, 0x2009, 0x026f, 0x210c, 0x613e, 0x600b, 0xffff,
-	0x6910, 0x6112, 0x6023, 0x0004, 0x080c, 0x83f8, 0x080c, 0x898b,
-	0x2d60, 0x080c, 0x9e2f, 0x00de, 0x0005, 0x080c, 0x9e2f, 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, 0x820b, 0x080c, 0x9e2f,
-	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,
-	0xae1c, 0x009e, 0x1168, 0x2011, 0x0274, 0x20a9, 0x0004, 0x6010,
-	0x0096, 0x2048, 0x2019, 0x0006, 0x080c, 0xae1c, 0x009e, 0x1100,
-	0x015e, 0x003e, 0x002e, 0x0005, 0x00e6, 0x2071, 0x1800, 0x080c,
-	0x5c78, 0x080c, 0x2dc8, 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, 0xd595, 0x01b8, 0x080c, 0xd5a5,
-	0x11a0, 0x6000, 0x9086, 0x0004, 0x1120, 0x0016, 0x080c, 0x191f,
-	0x001e, 0x080c, 0xbd30, 0x1110, 0x080c, 0x3010, 0x080c, 0xbd41,
-	0x1110, 0x080c, 0xa7cd, 0x080c, 0x9e5f, 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,
-	0xc23b, 0x0168, 0x2019, 0xffff, 0x9005, 0x0128, 0x6010, 0x00b6,
-	0x2058, 0xbba0, 0x00be, 0x2021, 0x0004, 0x080c, 0x4a91, 0x004e,
-	0x003e, 0x000e, 0x6004, 0x9086, 0x0001, 0x1128, 0x080c, 0x9915,
-	0x080c, 0x9e5f, 0x9006, 0x0005, 0x00e6, 0x00c6, 0x00b6, 0x0046,
-	0x2061, 0x1cd0, 0x2071, 0x1800, 0x7450, 0x7070, 0x8001, 0x9402,
-	0x12b8, 0x2100, 0x9c06, 0x0148, 0x6000, 0x9086, 0x0000, 0x0128,
-	0x6010, 0x2058, 0xb8a0, 0x9206, 0x0140, 0x9ce0, 0x0018, 0x2001,
-	0x1819, 0x2004, 0x9c02, 0x1220, 0x0c60, 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, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010,
-	0x0020, 0x0040, 0x0080, 0x0100, 0x0200, 0x0400, 0x0800, 0x1000,
-	0x2000, 0x4000, 0x8000, 0x2a9a
+	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,
+	0x1800, 0x2004, 0x9086, 0x0003, 0x1158, 0x0036, 0x0046, 0x6010,
+	0x2058, 0xbba0, 0x2021, 0x0006, 0x080c, 0x4cbc, 0x004e, 0x003e,
+	0x2001, 0x0006, 0x080c, 0xcdc2, 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,
+	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,
+	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,
+	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,
+	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,
+	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,
+	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,
+	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,
+	0xff00, 0x9086, 0x1200, 0x1198, 0x686c, 0x9084, 0x00ff, 0x0016,
+	0x6114, 0x918c, 0xf700, 0x910d, 0x6116, 0x001e, 0x6003, 0x0001,
+	0x6007, 0x0043, 0x080c, 0x8679, 0x080c, 0x8c10, 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,
+	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,
+	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,
+	0x0001, 0x223d, 0x9784, 0x00ff, 0x9322, 0x1208, 0x2300, 0x20a8,
+	0x4003, 0x931a, 0x0530, 0x8210, 0xd7fc, 0x1130, 0x8d68, 0x2d0a,
+	0x2001, 0x0260, 0x2098, 0x0c68, 0x2950, 0x080c, 0x104a, 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,
+	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,
+	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,
+	0x00b6, 0x0046, 0x0056, 0x0076, 0x00c6, 0x0156, 0x2c20, 0x2128,
+	0x20a9, 0x007f, 0x900e, 0x0016, 0x0036, 0x080c, 0x649f, 0x1190,
+	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,
+	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,
+	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
 };
 #ifdef UNIQUE_FW_NAME
-unsigned short fw2300flx_length01 = 0xd5d4;
+unsigned short fw2300flx_length01 = 0xdd79;
 #else
-unsigned short risc_code_length01 = 0xd5d4;
+unsigned short risc_code_length01 = 0xdd79;
 #endif
 
diff -Nru a/drivers/scsi/qla2xxx/ql6322.c b/drivers/scsi/qla2xxx/ql6322.c
--- a/drivers/scsi/qla2xxx/ql6322.c	2005-03-01 23:39:16 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,108 +0,0 @@
-/*
- * QLogic ISP6322 device driver for Linux 2.6.x
- * Copyright (C) 2003-2004 QLogic Corporation (www.qlogic.com)
- *
- * Released under GPL v2.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-
-#include "qla_def.h"
-
-static char qla_driver_name[] = "qla6322";
-
-extern unsigned char  fw2322flx_version[];
-extern unsigned char  fw2322flx_version_str[];
-extern unsigned short fw2322flx_addr01;
-extern unsigned short fw2322flx_code01[];
-extern unsigned short fw2322flx_length01;
-extern unsigned long rseqflx_code_addr01;
-extern unsigned short rseqflx_code01[];
-extern unsigned short rseqflx_code_length01;
-extern unsigned long xseqflx_code_addr01;
-extern unsigned short xseqflx_code01[];
-extern unsigned short xseqflx_code_length01;
-
-static struct qla_fw_info qla_fw_tbl[] = {
-	{
-		.addressing	= FW_INFO_ADDR_NORMAL,
-		.fwcode		= &fw2322flx_code01[0],
-		.fwlen		= &fw2322flx_length01,
-		.fwstart	= &fw2322flx_addr01,
-	},
-	{
-		.addressing	= FW_INFO_ADDR_EXTENDED,
-		.fwcode		= &rseqflx_code01[0],
-		.fwlen		= &rseqflx_code_length01,
-		.lfwstart	= &rseqflx_code_addr01,
-	},
-	{
-		.addressing	= FW_INFO_ADDR_EXTENDED,
-		.fwcode		= &xseqflx_code01[0],
-		.fwlen		= &xseqflx_code_length01,
-		.lfwstart	= &xseqflx_code_addr01,
-	},
-	{ FW_INFO_ADDR_NOMORE, },
-};
-
-static struct qla_board_info qla_board_tbl[] = {
-	{
-		.drv_name	= qla_driver_name,
-		.isp_name	= "ISP6322",
-		.fw_info	= qla_fw_tbl,
-	},
-};
-
-static struct pci_device_id qla6322_pci_tbl[] = {
-	{
-		.vendor		= PCI_VENDOR_ID_QLOGIC,
-		.device		= PCI_DEVICE_ID_QLOGIC_ISP6322,
-		.subvendor	= PCI_ANY_ID,
-		.subdevice	= PCI_ANY_ID,
-		.driver_data	= (unsigned long)&qla_board_tbl[0],
-	},
-	{0, 0},
-};
-MODULE_DEVICE_TABLE(pci, qla6322_pci_tbl);
-
-static int __devinit
-qla6322_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
-qla6322_remove_one(struct pci_dev *pdev)
-{
-	qla2x00_remove_one(pdev);
-}
-
-static struct pci_driver qla6322_pci_driver = {
-	.name		= "qla6322",
-	.id_table	= qla6322_pci_tbl,
-	.probe		= qla6322_probe_one,
-	.remove		= __devexit_p(qla6322_remove_one),
-};
-
-static int __init
-qla6322_init(void)
-{
-	return pci_module_init(&qla6322_pci_driver);
-}
-
-static void __exit
-qla6322_exit(void)
-{
-	pci_unregister_driver(&qla6322_pci_driver);
-}
-
-module_init(qla6322_init);
-module_exit(qla6322_exit);
-
-MODULE_AUTHOR("QLogic Corporation");
-MODULE_DESCRIPTION("QLogic ISP6322 FC-SCSI Host Bus Adapter driver");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(QLA2XXX_VERSION);
diff -Nru a/drivers/scsi/qla2xxx/ql6322_fw.c b/drivers/scsi/qla2xxx/ql6322_fw.c
--- a/drivers/scsi/qla2xxx/ql6322_fw.c	2005-03-01 23:39:17 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,7433 +0,0 @@
-/**************************************************************************
- *                  QLOGIC LINUX SOFTWARE
- *
- * QLogic ISP2x00 device driver for Linux 2.6.x
- * Copyright (C) 2003-2004 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.
- *
- *************************************************************************/
-
-/*
- *	Firmware Version 3.03.02 (16:54 Aug 10, 2004)
- */
-
-#ifdef UNIQUE_FW_NAME
-unsigned short fw2322flx_version = 3*1024+3;
-#else
-unsigned short risc_code_version = 3*1024+3;
-#endif
-
-#ifdef UNIQUE_FW_NAME
-unsigned char fw2322flx_version_str[] = {3, 3, 2};
-#else
-unsigned char firmware_version[] = {3, 3, 2};
-#endif
-
-#ifdef UNIQUE_FW_NAME
-#define fw2322flx_VERSION_STRING "3.03.02"
-#else
-#define FW_VERSION_STRING "3.03.02"
-#endif
-
-#ifdef UNIQUE_FW_NAME
-unsigned short fw2322flx_addr01 = 0x0800 ;
-#else
-unsigned short risc_code_addr01 = 0x0800 ;
-#endif
-
-#ifdef UNIQUE_FW_NAME
-unsigned short fw2322flx_code01[] = { 
-#else
-unsigned short risc_code01[] = { 
-#endif
-	0x0470, 0x0000, 0x0000, 0xce84, 0x0000, 0x0003, 0x0003, 0x0002,
-	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, 0x3220, 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,
-	0x400f, 0x2091, 0x2800, 0x20a9, 0x000f, 0x2001, 0x0000, 0x400f,
-	0x2091, 0x2a00, 0x20a9, 0x000f, 0x2001, 0x0000, 0x400f, 0x2091,
-	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, 0x290c, 0x2051, 0x1800, 0x2a70, 0x20e1,
-	0x0001, 0x20e9, 0x0001, 0x2009, 0x0000, 0x080c, 0x0e4a, 0x00f6,
-	0x7888, 0x9005, 0x11f8, 0x2061, 0xc000, 0x080c, 0x1f21, 0x1170,
-	0x2079, 0x0300, 0x080c, 0x1f37, 0x2061, 0xe000, 0x080c, 0x1f21,
-	0x1128, 0x2079, 0x0380, 0x080c, 0x1f37, 0x0060, 0x00fe, 0x7883,
-	0x4010, 0x7837, 0x4010, 0x7833, 0x0010, 0x2091, 0x5000, 0x2091,
-	0x4080, 0x0cf8, 0x00fe, 0x2029, 0x26c0, 0x2031, 0xffff, 0x2039,
-	0x269c, 0x2021, 0x0050, 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, 0x756a,
-	0x766e, 0x7766, 0x7472, 0x7476, 0x00e6, 0x2071, 0x1b25, 0x2472,
-	0x00ee, 0x20a1, 0x1ddc, 0x716c, 0x810d, 0x810d, 0x810d, 0x810d,
-	0x918c, 0x000f, 0x2001, 0x0001, 0x9112, 0x900e, 0x21a8, 0x4104,
-	0x8211, 0x1de0, 0x716c, 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, 0x0f47, 0x080c, 0x5d05, 0x080c, 0x9b7c, 0x080c,
-	0x10fe, 0x080c, 0x12ee, 0x080c, 0x1a7f, 0x080c, 0x8456, 0x080c,
-	0x0cf7, 0x080c, 0x1083, 0x080c, 0x329f, 0x080c, 0x73cd, 0x080c,
-	0x6745, 0x080c, 0x809d, 0x080c, 0x210e, 0x080c, 0x7a62, 0x080c,
-	0x1f50, 0x080c, 0x208e, 0x080c, 0x2103, 0x2091, 0x3009, 0x7883,
-	0x0000, 0x1004, 0x0941, 0x7880, 0x9086, 0x0002, 0x1190, 0x7883,
-	0x4000, 0x7837, 0x4000, 0x7833, 0x0010, 0x0e04, 0x0935, 0x2091,
-	0x5000, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c,
-	0x11d6, 0x2071, 0x1800, 0x7003, 0x0000, 0x2071, 0x1800, 0x7000,
-	0x908e, 0x0003, 0x1158, 0x080c, 0x49bf, 0x080c, 0x32c6, 0x080c,
-	0x7435, 0x080c, 0x6bdd, 0x080c, 0x80c6, 0x0c78, 0x000b, 0x0c98,
-	0x0962, 0x0963, 0x0afa, 0x0960, 0x0bab, 0x0cf6, 0x0cf6, 0x0cf6,
-	0x080c, 0x0d65, 0x0005, 0x0126, 0x00f6, 0x2091, 0x8000, 0x7000,
-	0x9086, 0x0001, 0x1904, 0x0acd, 0x080c, 0x0e9a, 0x080c, 0x70ba,
-	0x0150, 0x080c, 0x70dd, 0x15b0, 0x2079, 0x0100, 0x7828, 0x9085,
-	0x1800, 0x782a, 0x0478, 0x080c, 0x6feb, 0x7000, 0x9086, 0x0001,
-	0x1904, 0x0acd, 0x7094, 0x9086, 0x0028, 0x1904, 0x0acd, 0x080c,
-	0x8095, 0x080c, 0x8087, 0x2001, 0x0161, 0x2003, 0x0001, 0x2079,
-	0x0100, 0x2011, 0xffff, 0x080c, 0x28ac, 0x7a28, 0x9295, 0x5e2c,
-	0x7a2a, 0x2011, 0x6f30, 0x080c, 0x816c, 0x2011, 0x6f23, 0x080c,
-	0x8272, 0x2011, 0x5b5c, 0x080c, 0x816c, 0x2011, 0x8030, 0x901e,
-	0x7392, 0x04d0, 0x080c, 0x5409, 0x2079, 0x0100, 0x7844, 0x9005,
-	0x1904, 0x0acd, 0x2011, 0x5b5c, 0x080c, 0x816c, 0x2011, 0x6f30,
-	0x080c, 0x816c, 0x2011, 0x6f23, 0x080c, 0x8272, 0x2001, 0x0265,
-	0x2001, 0x0205, 0x2003, 0x0000, 0x7840, 0x9084, 0xfffb, 0x7842,
-	0x2001, 0x197e, 0x2004, 0x9005, 0x1140, 0x00c6, 0x2061, 0x0100,
-	0x080c, 0x5cad, 0x00ce, 0x0804, 0x0acd, 0x780f, 0x006b, 0x7a28,
-	0x080c, 0x70c2, 0x0118, 0x9295, 0x5e2c, 0x0010, 0x9295, 0x402c,
-	0x7a2a, 0x2011, 0x8010, 0x73d4, 0x2001, 0x197f, 0x2003, 0x0001,
-	0x080c, 0x2774, 0x080c, 0x48fa, 0x7244, 0xc284, 0x7246, 0x2001,
-	0x180c, 0x200c, 0xc1ac, 0xc1cc, 0x2102, 0x2001, 0x0390, 0x2003,
-	0x0400, 0x080c, 0x98c7, 0x080c, 0x91f8, 0x2011, 0x0004, 0x080c,
-	0xb880, 0x080c, 0x98e3, 0x080c, 0x6585, 0x080c, 0x70ba, 0x1120,
-	0x080c, 0x27d5, 0x0600, 0x0420, 0x080c, 0x5cb4, 0x0140, 0x7093,
-	0x0001, 0x70cf, 0x0000, 0x080c, 0x55d6, 0x0804, 0x0acd, 0x080c,
-	0x53a8, 0xd094, 0x01a8, 0x2001, 0x0390, 0x2003, 0x0404, 0x2011,
-	0x180c, 0x2204, 0xc0cd, 0x2012, 0x080c, 0x53ac, 0xd0d4, 0x1118,
-	0x080c, 0x27d5, 0x1270, 0x2011, 0x180c, 0x2204, 0xc0bc, 0x0088,
-	0x080c, 0x53ac, 0xd0d4, 0x1db8, 0x2011, 0x180c, 0x2204, 0xc0bd,
-	0x0040, 0x2011, 0x180c, 0x2204, 0xc0bd, 0x2012, 0x080c, 0x6682,
-	0x0008, 0x2012, 0x080c, 0x6648, 0x0120, 0x7a0c, 0xc2b4, 0x7a0e,
-	0x00a8, 0x707b, 0x0000, 0x080c, 0x70ba, 0x1130, 0x70ac, 0x9005,
-	0x1168, 0x080c, 0xbcdc, 0x0050, 0x080c, 0xbcdc, 0x70d8, 0xd09c,
-	0x1128, 0x70ac, 0x9005, 0x0110, 0x080c, 0x5c8a, 0x70e3, 0x0000,
-	0x70df, 0x0000, 0x70a3, 0x0000, 0x080c, 0x27dd, 0x0228, 0x2011,
-	0x0101, 0x2204, 0xc0c4, 0x2012, 0x72d8, 0x080c, 0x70ba, 0x1178,
-	0x9016, 0x0016, 0x2009, 0x0002, 0x2019, 0x1945, 0x211a, 0x001e,
-	0x705b, 0xffff, 0x705f, 0x00ef, 0x707f, 0x0000, 0x0020, 0x2019,
-	0x1945, 0x201b, 0x0000, 0x2079, 0x185b, 0x7804, 0xd0ac, 0x0108,
-	0xc295, 0x72da, 0x080c, 0x70ba, 0x0118, 0x9296, 0x0004, 0x0518,
-	0x2011, 0x0001, 0x080c, 0xb880, 0x70a7, 0x0000, 0x70ab, 0xffff,
-	0x7003, 0x0002, 0x00fe, 0x080c, 0x2e09, 0x080c, 0x98c7, 0x2011,
-	0x0005, 0x080c, 0x9324, 0x080c, 0x98e3, 0x080c, 0x70ba, 0x0148,
-	0x00c6, 0x2061, 0x0100, 0x0016, 0x2009, 0x0002, 0x61e2, 0x001e,
-	0x00ce, 0x012e, 0x00e0, 0x70a7, 0x0000, 0x70ab, 0xffff, 0x7003,
-	0x0002, 0x080c, 0x98c7, 0x2011, 0x0005, 0x080c, 0x9324, 0x080c,
-	0x98e3, 0x080c, 0x70ba, 0x0148, 0x00c6, 0x2061, 0x0100, 0x0016,
-	0x2009, 0x0002, 0x61e2, 0x001e, 0x00ce, 0x00fe, 0x012e, 0x0005,
-	0x00c6, 0x00b6, 0x080c, 0x70ba, 0x1118, 0x20a9, 0x0800, 0x0010,
-	0x20a9, 0x0782, 0x080c, 0x70ba, 0x1110, 0x900e, 0x0010, 0x2009,
-	0x007e, 0x86ff, 0x0138, 0x9180, 0x1000, 0x2004, 0x905d, 0x0110,
-	0xb800, 0xd0bc, 0x090c, 0x3136, 0x8108, 0x1f04, 0x0ae1, 0x707b,
-	0x0000, 0x707c, 0x9084, 0x00ff, 0x707e, 0x70af, 0x0000, 0x00be,
-	0x00ce, 0x0005, 0x00b6, 0x0126, 0x2091, 0x8000, 0x7000, 0x9086,
-	0x0002, 0x1904, 0x0ba8, 0x70a8, 0x9086, 0xffff, 0x0120, 0x080c,
-	0x2e09, 0x0804, 0x0ba8, 0x70d8, 0xd0ac, 0x1110, 0xd09c, 0x0520,
-	0xd084, 0x0510, 0x0006, 0x2001, 0x0103, 0x2003, 0x002b, 0x000e,
-	0xd08c, 0x01d0, 0x70dc, 0x9086, 0xffff, 0x0190, 0x080c, 0x2f94,
-	0x70d8, 0xd094, 0x1904, 0x0ba8, 0x2011, 0x0001, 0x080c, 0xbf8f,
-	0x0110, 0x2011, 0x0003, 0x901e, 0x080c, 0x2fce, 0x0804, 0x0ba8,
-	0x70e0, 0x9005, 0x1904, 0x0ba8, 0x70a4, 0x9005, 0x1904, 0x0ba8,
-	0x70d8, 0xd0a4, 0x0118, 0xd0b4, 0x0904, 0x0ba8, 0x080c, 0x6648,
-	0x1904, 0x0ba8, 0x080c, 0x669b, 0x1904, 0x0ba8, 0x080c, 0x6682,
-	0x01c0, 0x0156, 0x00c6, 0x20a9, 0x007f, 0x900e, 0x0016, 0x080c,
-	0x628f, 0x1118, 0xb800, 0xd0ec, 0x1138, 0x001e, 0x8108, 0x1f04,
-	0x0b4e, 0x00ce, 0x015e, 0x0028, 0x001e, 0x00ce, 0x015e, 0x0804,
-	0x0ba8, 0x0006, 0x2001, 0x0103, 0x2003, 0x006b, 0x000e, 0x2011,
-	0x198b, 0x080c, 0x0fb7, 0x2011, 0x19a5, 0x080c, 0x0fb7, 0x7030,
-	0xc08c, 0x7032, 0x7003, 0x0003, 0x70ab, 0xffff, 0x080c, 0x0e6e,
-	0x9006, 0x080c, 0x23fe, 0x0036, 0x0046, 0x2019, 0xffff, 0x2021,
-	0x0006, 0x080c, 0x4a97, 0x004e, 0x003e, 0x00f6, 0x2079, 0x0100,
-	0x080c, 0x70dd, 0x0150, 0x080c, 0x70ba, 0x7828, 0x0118, 0x9084,
-	0xe1ff, 0x0010, 0x9084, 0xffdf, 0x782a, 0x00fe, 0x080c, 0x98c7,
-	0x2001, 0x19c0, 0x2004, 0x9086, 0x0005, 0x1120, 0x2011, 0x0000,
-	0x080c, 0x9324, 0x2011, 0x0000, 0x080c, 0x932e, 0x080c, 0x98e3,
-	0x012e, 0x00be, 0x0005, 0x0016, 0x0026, 0x0046, 0x00f6, 0x0126,
-	0x2091, 0x8000, 0x2079, 0x0100, 0x7904, 0x918c, 0xfffd, 0x7906,
-	0x2009, 0x00f7, 0x080c, 0x5c73, 0x7940, 0x918c, 0x0010, 0x7942,
-	0x7924, 0xd1b4, 0x0120, 0x2011, 0x0040, 0x080c, 0x28ac, 0xd19c,
-	0x0120, 0x2011, 0x0008, 0x080c, 0x28ac, 0x0006, 0x0036, 0x0156,
-	0x0000, 0x2001, 0x197f, 0x2004, 0x9005, 0x1518, 0x080c, 0x2840,
-	0x1148, 0x2001, 0x0001, 0x080c, 0x27a3, 0x2001, 0x0001, 0x080c,
-	0x2786, 0x00b8, 0x080c, 0x2848, 0x1138, 0x9006, 0x080c, 0x27a3,
-	0x9006, 0x080c, 0x2786, 0x0068, 0x080c, 0x2850, 0x1d50, 0x2001,
-	0x1970, 0x2004, 0xd0fc, 0x0108, 0x0020, 0x080c, 0x259d, 0x0804,
-	0x0ca9, 0x080c, 0x28cf, 0x080c, 0x2902, 0x20a9, 0x003a, 0x1d04,
-	0x0bff, 0x080c, 0x8252, 0x1f04, 0x0bff, 0x080c, 0x70cb, 0x0148,
-	0x080c, 0x70dd, 0x1118, 0x080c, 0x73c8, 0x0050, 0x080c, 0x70c2,
-	0x0dd0, 0x080c, 0x73c3, 0x080c, 0x73b9, 0x080c, 0x6feb, 0x0020,
-	0x2009, 0x00f8, 0x080c, 0x5c73, 0x7850, 0xc0e5, 0x7852, 0x080c,
-	0x70ba, 0x0120, 0x7843, 0x0090, 0x7843, 0x0010, 0x2021, 0xe678,
-	0x2019, 0xea60, 0x0d0c, 0x8252, 0x7820, 0xd09c, 0x15a0, 0x080c,
-	0x70ba, 0x0904, 0x0c8b, 0x7824, 0xd0ac, 0x1904, 0x0cae, 0x080c,
-	0x70dd, 0x1548, 0x0046, 0x2021, 0x0320, 0x8421, 0x1df0, 0x004e,
-	0x2011, 0x1800, 0x080c, 0x28ac, 0x080c, 0x2858, 0x7824, 0x9084,
-	0x1800, 0x1168, 0x9484, 0x0fff, 0x1140, 0x2001, 0x1810, 0x2004,
-	0x9084, 0x9000, 0x0110, 0x080c, 0x0cd1, 0x8421, 0x1160, 0x1d04,
-	0x0c5b, 0x080c, 0x8252, 0x080c, 0x73c3, 0x080c, 0x73b9, 0x7003,
-	0x0001, 0x0804, 0x0cae, 0x8319, 0x1928, 0x2001, 0x1810, 0x2004,
-	0x9084, 0x9000, 0x0110, 0x080c, 0x0cd1, 0x1d04, 0x0c71, 0x080c,
-	0x8252, 0x2009, 0x1973, 0x2104, 0x9005, 0x0118, 0x8001, 0x200a,
-	0x1188, 0x200b, 0x000a, 0x2011, 0x0048, 0x080c, 0x28ac, 0x20a9,
-	0x0002, 0x080c, 0x2839, 0x7924, 0x080c, 0x2858, 0xd19c, 0x0110,
-	0x080c, 0x2774, 0x00f0, 0x080c, 0x70cb, 0x1140, 0x94a2, 0x03e8,
-	0x1128, 0x080c, 0x708e, 0x7003, 0x0001, 0x00c0, 0x2011, 0x1800,
-	0x080c, 0x28ac, 0x080c, 0x2858, 0x7824, 0x080c, 0x70d4, 0x0110,
-	0xd0ac, 0x1160, 0x9084, 0x1800, 0x0904, 0x0c63, 0x7003, 0x0001,
-	0x0028, 0x2001, 0x0001, 0x080c, 0x23fe, 0x00a0, 0x7850, 0xc0e4,
-	0x7852, 0x2009, 0x180c, 0x210c, 0xd19c, 0x1120, 0x7904, 0x918d,
-	0x0002, 0x7906, 0x2011, 0x0048, 0x080c, 0x28ac, 0x7828, 0x9085,
-	0x0028, 0x782a, 0x2001, 0x197f, 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, 0x8252, 0x015e,
-	0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x004e, 0x003e, 0x002e,
-	0x001e, 0x000e, 0x0005, 0x00e6, 0x2071, 0x189c, 0x7004, 0x9086,
-	0x0001, 0x1110, 0x080c, 0x32c6, 0x00ee, 0x0005, 0x0005, 0x2a70,
-	0x2061, 0x1983, 0x2063, 0x0003, 0x6007, 0x0003, 0x600b, 0x0002,
-	0x600f, 0x0317, 0x2001, 0x1954, 0x900e, 0x2102, 0x7192, 0x2001,
-	0x0100, 0x2004, 0x9082, 0x0002, 0x0218, 0x705b, 0xffff, 0x0008,
-	0x715a, 0x7063, 0xffff, 0x717a, 0x717e, 0x080c, 0xbcdc, 0x70eb,
-	0x00c0, 0x2061, 0x1944, 0x6003, 0x0909, 0x6106, 0x600b, 0x8800,
-	0x600f, 0x0200, 0x6013, 0x00ff, 0x6017, 0x000f, 0x611a, 0x601f,
-	0x07d0, 0x2061, 0x194c, 0x6003, 0x8000, 0x6106, 0x610a, 0x600f,
-	0x0200, 0x6013, 0x00ff, 0x6116, 0x601b, 0x0001, 0x611e, 0x2061,
-	0x1961, 0x6003, 0x514c, 0x6007, 0x4f47, 0x600b, 0x4943, 0x600f,
-	0x2020, 0x2001, 0x182b, 0x2102, 0x0005, 0x9016, 0x080c, 0x628f,
-	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,
-	0x0d67, 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, 0x1afb, 0x7a08,
-	0x226a, 0x2069, 0x1afc, 0x7a18, 0x226a, 0x8d68, 0x7a1c, 0x226a,
-	0x782c, 0x2019, 0x1b09, 0x201a, 0x2019, 0x1b0c, 0x9016, 0x7808,
-	0xd09c, 0x0168, 0x7820, 0x201a, 0x8210, 0x8318, 0x9386, 0x1b25,
-	0x0108, 0x0ca8, 0x7808, 0xd09c, 0x0110, 0x2011, 0xdead, 0x2019,
-	0x1b0a, 0x782c, 0x201a, 0x8318, 0x221a, 0x7803, 0x0000, 0x2069,
-	0x1a51, 0x901e, 0x20a9, 0x0020, 0x7b26, 0x7a28, 0x226a, 0x8d68,
-	0x8318, 0x1f04, 0x0db4, 0x2069, 0x1a71, 0x2019, 0x0050, 0x20a9,
-	0x0020, 0x7b26, 0x7a28, 0x226a, 0x8d68, 0x8318, 0x1f04, 0x0dc1,
-	0x0491, 0x002e, 0x003e, 0x00de, 0x015e, 0x2079, 0x1800, 0x7803,
-	0x0005, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x0180,
-	0x2001, 0x19fa, 0x2004, 0x9005, 0x0128, 0x2001, 0x008b, 0x2004,
-	0xd0fc, 0x0dd8, 0x2001, 0x008a, 0x2003, 0x0002, 0x2003, 0x1001,
-	0x080c, 0x53b7, 0x1170, 0x080c, 0x0f08, 0x0110, 0x080c, 0x0e5b,
-	0x080c, 0x53b7, 0x1130, 0x2071, 0x1800, 0x2011, 0x8000, 0x080c,
-	0x0f1c, 0x0c70, 0x0005, 0x2001, 0x0382, 0x2004, 0x9084, 0x0007,
-	0x9086, 0x0001, 0x1120, 0x2001, 0x0015, 0x080c, 0x98b8, 0x2079,
-	0x0380, 0x2069, 0x1adb, 0x7818, 0x6802, 0x781c, 0x6806, 0x7840,
-	0x680a, 0x7844, 0x680e, 0x782c, 0x6812, 0x2019, 0x1ae6, 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, 0x1a9b, 0x901e, 0x20a9, 0x0020, 0x7b26, 0x7828, 0x206a,
-	0x8d68, 0x8318, 0x1f04, 0x0e35, 0x2069, 0x1abb, 0x2019, 0x00b0,
-	0x20a9, 0x0020, 0x7b26, 0x7828, 0x206a, 0x8d68, 0x8318, 0x1f04,
-	0x0e42, 0x0005, 0x918c, 0x03ff, 0x2001, 0x0003, 0x2004, 0x9084,
-	0x0600, 0x1118, 0x918d, 0x6c00, 0x0010, 0x918d, 0x6400, 0x2001,
-	0x017f, 0x2102, 0x0005, 0x0026, 0x0126, 0x2011, 0x0080, 0x080c,
-	0x0efa, 0x20a9, 0x0900, 0x080c, 0x0f30, 0x2011, 0x0040, 0x080c,
-	0x0efa, 0x20a9, 0x0900, 0x080c, 0x0f30, 0x0c78, 0x0026, 0x080c,
-	0x0f08, 0x1188, 0x2011, 0x010e, 0x2214, 0x9294, 0x0007, 0x9296,
-	0x0007, 0x0118, 0x2011, 0x0947, 0x0010, 0x2011, 0x1b47, 0x080c,
-	0x0f1c, 0x002e, 0x0005, 0x2011, 0x010e, 0x2214, 0x9294, 0x0007,
-	0x9296, 0x0007, 0x0118, 0x2011, 0xa880, 0x0010, 0x2011, 0x6840,
-	0xd0e4, 0x70ef, 0x0000, 0x1128, 0x70ef, 0x0fa0, 0x080c, 0x0f0d,
-	0x002e, 0x0005, 0x0026, 0x080c, 0x0f08, 0x0148, 0xd0a4, 0x1138,
-	0x2011, 0xcdd5, 0x0010, 0x2011, 0x0080, 0x080c, 0x0f0d, 0x002e,
-	0x0005, 0x0026, 0x70ef, 0x0000, 0x080c, 0x0f08, 0x1130, 0x2011,
-	0x8040, 0x080c, 0x0f1c, 0x002e, 0x0005, 0x080c, 0x2850, 0x1118,
-	0x2011, 0xcdc5, 0x0010, 0x2011, 0xcac2, 0x080c, 0x0f0d, 0x002e,
-	0x0005, 0x00e6, 0x0016, 0x0006, 0x2071, 0x1800, 0xd0b4, 0x70e8,
-	0x71e4, 0x1118, 0xc0e4, 0xc1f4, 0x0050, 0x0006, 0x3b00, 0x9084,
-	0xff3e, 0x20d8, 0x000e, 0x70ef, 0x0000, 0xc0e5, 0xc1f5, 0x0099,
-	0x000e, 0x001e, 0x00ee, 0x0005, 0x00e6, 0x2071, 0x1800, 0xd0e4,
-	0x70e8, 0x1110, 0xc0dc, 0x0008, 0xc0dd, 0x0016, 0x71e4, 0x0019,
-	0x001e, 0x00ee, 0x0005, 0x70ea, 0x71e6, 0x7000, 0x9084, 0x0007,
-	0x000b, 0x0005, 0x0ec0, 0x0e9a, 0x0e9a, 0x0e6e, 0x0ea9, 0x0e9a,
-	0x0e9a, 0x0ea9, 0xc284, 0x0016, 0x3b08, 0x3a00, 0x9104, 0x918d,
-	0x00c1, 0x21d8, 0x9084, 0xff3e, 0x9205, 0x20d0, 0x001e, 0x0005,
-	0x2001, 0x183a, 0x2004, 0xd0dc, 0x0005, 0x9e86, 0x1800, 0x190c,
-	0x0d65, 0x70e8, 0xd0e4, 0x0108, 0xc2e5, 0x72ea, 0xd0e4, 0x1118,
-	0x9294, 0x00c1, 0x08f9, 0x0005, 0x9e86, 0x1800, 0x190c, 0x0d65,
-	0x70e4, 0xd0f4, 0x0108, 0xc2f5, 0x72e6, 0xd0f4, 0x1140, 0x9284,
-	0x8000, 0x8005, 0xc284, 0x9215, 0x9294, 0x00c1, 0x0861, 0x0005,
-	0x1d04, 0x0f30, 0x2091, 0x6000, 0x1f04, 0x0f30, 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, 0x0f37, 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, 0x0d45, 0x2001, 0x0000, 0x810f, 0x20a9, 0x0002, 0x4001,
-	0x0005, 0x89ff, 0x0140, 0xa804, 0xa807, 0x0000, 0x0006, 0x080c,
-	0x1061, 0x009e, 0x0cb0, 0x0005, 0x00e6, 0x2071, 0x1800, 0x080c,
-	0x10da, 0x090c, 0x0d65, 0x00ee, 0x0005, 0x0086, 0x00e6, 0x0006,
-	0x0026, 0x0036, 0x0126, 0x2091, 0x8000, 0x00c9, 0x2071, 0x1800,
-	0x73bc, 0x702c, 0x9016, 0x9045, 0x0158, 0x8210, 0x9906, 0x090c,
-	0x0d65, 0x2300, 0x9202, 0x0120, 0x1a0c, 0x0d65, 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, 0x0d65,
-	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, 0x8087,
-	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,
-	0x049b, 0xa802, 0x2048, 0x2009, 0x26c0, 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, 0x049b, 0x0288, 0x9982, 0x0800, 0x1270, 0x0040, 0x9982,
-	0x0800, 0x0250, 0x2071, 0x188b, 0x7010, 0x9902, 0x1228, 0x9085,
-	0x0001, 0x001e, 0x00ee, 0x0005, 0x9006, 0x0cd8, 0x00e6, 0x2071,
-	0x19f9, 0x7007, 0x0000, 0x9006, 0x701e, 0x7022, 0x7002, 0x2071,
-	0x0000, 0x7010, 0x9085, 0x8044, 0x7012, 0x2071, 0x0080, 0x9006,
-	0x702b, 0x0060, 0x20a9, 0x0040, 0x7022, 0x1f04, 0x1114, 0x702b,
-	0x0060, 0x702b, 0x0020, 0x20a9, 0x0040, 0x7022, 0x1f04, 0x111d,
-	0x702b, 0x0020, 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000, 0x00e6,
-	0xa06f, 0x0000, 0x2071, 0x19f9, 0x701c, 0x9088, 0x1a03, 0x280a,
-	0x8000, 0x9084, 0x003f, 0x701e, 0x7120, 0x9106, 0x090c, 0x0d65,
-	0x7004, 0x9005, 0x1128, 0x00f6, 0x2079, 0x0080, 0x00a9, 0x00fe,
-	0x00ee, 0x012e, 0x0005, 0x0126, 0x2091, 0x8000, 0x00e6, 0x2071,
-	0x19f9, 0x7004, 0x9005, 0x1128, 0x00f6, 0x2079, 0x0080, 0x0021,
-	0x00fe, 0x00ee, 0x012e, 0x0005, 0x7004, 0x9086, 0x0000, 0x1110,
-	0x7007, 0x0006, 0x7000, 0x0002, 0x1166, 0x1164, 0x1164, 0x1164,
-	0x12dd, 0x12dd, 0x12dd, 0x12dd, 0x080c, 0x0d65, 0x701c, 0x7120,
-	0x9106, 0x1148, 0x792c, 0x9184, 0x0001, 0x1120, 0xd1fc, 0x1110,
-	0x7007, 0x0000, 0x0005, 0x0096, 0x9180, 0x1a03, 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, 0x19f9,
-	0x2104, 0xc095, 0x200a, 0x080c, 0x1143, 0x0005, 0x0016, 0x00e6,
-	0x2071, 0x19f9, 0x00f6, 0x2079, 0x0080, 0x792c, 0xd1bc, 0x190c,
-	0x0d5e, 0x782b, 0x0002, 0xd1fc, 0x0120, 0x918c, 0x0700, 0x7004,
-	0x0023, 0x00fe, 0x00ee, 0x001e, 0x0005, 0x1154, 0x11fc, 0x1230,
-	0x0d65, 0x0d65, 0x12e9, 0x0d65, 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, 0x1199, 0x0005, 0x7008, 0x0096,
-	0x2048, 0xa86f, 0x0100, 0x009e, 0x7007, 0x0000, 0x080c, 0x1154,
-	0x0005, 0x7008, 0x0096, 0x2048, 0xa86f, 0x0200, 0x009e, 0x0ca0,
-	0x918c, 0x0700, 0x1150, 0x700c, 0x9005, 0x0180, 0x7800, 0x7802,
-	0x7804, 0x7806, 0x080c, 0x11ae, 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, 0x1143, 0x0005, 0x00de, 0x009e,
-	0x080c, 0x1143, 0x0005, 0xa8a8, 0xd08c, 0x0005, 0x0096, 0xa0a0,
-	0x904d, 0x090c, 0x0d65, 0xa06c, 0x908e, 0x0100, 0x0130, 0xa87b,
-	0x0030, 0xa883, 0x0000, 0xa897, 0x4002, 0x080c, 0x69a9, 0xa09f,
-	0x0000, 0xa0a3, 0x0000, 0x2848, 0x080c, 0x1061, 0x009e, 0x0005,
-	0x00a6, 0xa0a0, 0x904d, 0x090c, 0x0d65, 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, 0x1124, 0x00e8, 0xa97c, 0xa894,
-	0x0016, 0x0006, 0x080c, 0x69a9, 0x000e, 0x001e, 0xd1fc, 0x1138,
-	0xd1f4, 0x0128, 0x00c6, 0x2060, 0x080c, 0x9be6, 0x00ce, 0x7008,
-	0x2048, 0xa89f, 0x0000, 0xa8a3, 0x0000, 0x080c, 0x1061, 0x7007,
-	0x0000, 0x080c, 0x1143, 0x00ae, 0x0005, 0x0126, 0x2091, 0x8000,
-	0x782b, 0x1001, 0x7007, 0x0005, 0x7000, 0xc094, 0x7002, 0x012e,
-	0x0005, 0x7007, 0x0000, 0x080c, 0x1154, 0x0005, 0x0126, 0x2091,
-	0x2200, 0x2079, 0x0300, 0x2071, 0x1a43, 0x7003, 0x0000, 0x78bf,
-	0x00f6, 0x0041, 0x7807, 0x0007, 0x7803, 0x0000, 0x7803, 0x0001,
-	0x012e, 0x0005, 0x00c6, 0x7803, 0x0000, 0x2001, 0x0165, 0x2003,
-	0x4198, 0x7808, 0xd09c, 0x0110, 0x7820, 0x0cd8, 0x2001, 0x1a44,
-	0x2003, 0x0000, 0x78ab, 0x0004, 0x78ac, 0xd0ac, 0x1de8, 0x78ab,
-	0x0002, 0x7807, 0x0007, 0x7827, 0x0030, 0x782b, 0x0400, 0x7827,
-	0x0031, 0x782b, 0x1a51, 0x781f, 0xff00, 0x781b, 0xff00, 0x2001,
-	0x0200, 0x2004, 0xd0dc, 0x0110, 0x781f, 0x0303, 0x2061, 0x1a51,
-	0x602f, 0x1ddc, 0x2001, 0x1819, 0x2004, 0x9082, 0x1ddc, 0x6032,
-	0x603b, 0x1d1c, 0x602b, 0x1a91, 0x6007, 0x1a71, 0x2061, 0x1a71,
-	0x00ce, 0x0005, 0x0126, 0x2091, 0x2200, 0x7908, 0x9184, 0x0070,
-	0x190c, 0x0d5e, 0xd19c, 0x05a0, 0x7820, 0x908c, 0xf000, 0x0540,
-	0x2060, 0x6020, 0x9086, 0x0003, 0x1550, 0x6000, 0x9086, 0x0004,
-	0x1530, 0x6114, 0x2148, 0xa876, 0xa87a, 0xa867, 0x0103, 0x080c,
-	0x67cb, 0x00b6, 0x6010, 0x2058, 0xba3c, 0x8211, 0x0208, 0xba3e,
-	0xb8c0, 0x9005, 0x190c, 0x63ba, 0x00be, 0x6044, 0xd0fc, 0x190c,
-	0x98f0, 0x080c, 0x9c0e, 0x7808, 0xd09c, 0x19b0, 0x012e, 0x0005,
-	0x908a, 0x0024, 0x1a0c, 0x0d65, 0x002b, 0x012e, 0x0005, 0x04b0,
-	0x012e, 0x0005, 0x13a6, 0x13cc, 0x13fc, 0x1401, 0x1405, 0x140a,
-	0x1432, 0x1436, 0x1444, 0x1448, 0x13a6, 0x14d4, 0x14d8, 0x153b,
-	0x13a6, 0x13a6, 0x13a6, 0x13a6, 0x13a6, 0x13a6, 0x13a6, 0x13a6,
-	0x13a6, 0x13a6, 0x13a6, 0x13a6, 0x13a6, 0x140c, 0x13a6, 0x13d4,
-	0x13f9, 0x13c0, 0x13a6, 0x13e0, 0x13aa, 0x13a8, 0x080c, 0x0d65,
-	0x080c, 0x0d5e, 0x080c, 0x1542, 0x2009, 0x1a50, 0x2104, 0x8000,
-	0x200a, 0x080c, 0x7b25, 0x080c, 0x1989, 0x0005, 0x6044, 0xd0fc,
-	0x190c, 0x98f0, 0x2009, 0x0055, 0x080c, 0x9c82, 0x012e, 0x0005,
-	0x080c, 0x1542, 0x2060, 0x6044, 0xd0fc, 0x190c, 0x98f0, 0x2009,
-	0x0055, 0x080c, 0x9c82, 0x0005, 0x2009, 0x0048, 0x080c, 0x1542,
-	0x2060, 0x080c, 0x9c82, 0x0005, 0x2009, 0x0054, 0x080c, 0x1542,
-	0x2060, 0x6044, 0xd0fc, 0x190c, 0x98f0, 0x080c, 0x9c82, 0x0005,
-	0x080c, 0x1542, 0x2060, 0x0056, 0x0066, 0x080c, 0x1542, 0x2028,
-	0x080c, 0x1542, 0x2030, 0x0036, 0x0046, 0x2021, 0x0000, 0x2418,
-	0x2009, 0x0056, 0x080c, 0x9c82, 0x004e, 0x003e, 0x006e, 0x005e,
-	0x0005, 0x080c, 0x1542, 0x0005, 0x7004, 0xc085, 0xc0b5, 0x7006,
-	0x0005, 0x7004, 0xc085, 0x7006, 0x0005, 0x080c, 0x1542, 0x080c,
-	0x15ff, 0x0005, 0x080c, 0x0d65, 0x080c, 0x1542, 0x2060, 0x6014,
-	0x0096, 0x2048, 0xa83b, 0xffff, 0x009e, 0x2009, 0x0048, 0x080c,
-	0x9c82, 0x2001, 0x015d, 0x2003, 0x0000, 0x2009, 0x03e8, 0x8109,
-	0x0160, 0x2001, 0x0201, 0x2004, 0x9005, 0x0dc8, 0x2001, 0x0218,
-	0x2004, 0xd0ec, 0x1110, 0x080c, 0x1547, 0x2001, 0x0307, 0x2003,
-	0x8000, 0x0005, 0x7004, 0xc095, 0x7006, 0x0005, 0x080c, 0x1542,
-	0x2060, 0x6014, 0x0096, 0x2048, 0xa83b, 0xffff, 0x009e, 0x2009,
-	0x0048, 0x080c, 0x9c82, 0x0005, 0x080c, 0x1542, 0x080c, 0x0d65,
-	0x080c, 0x1542, 0x080c, 0x14bf, 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, 0x0d65, 0x2001, 0x020d, 0x2003, 0x0050, 0x2003,
-	0x0020, 0x0490, 0x78ab, 0x0004, 0x7803, 0x0001, 0x080c, 0x14d8,
-	0x0005, 0x7828, 0x782b, 0x0000, 0x9065, 0x090c, 0x0d65, 0x6014,
-	0x2048, 0x78ab, 0x0004, 0x918c, 0x0700, 0x01a8, 0x080c, 0x7b25,
-	0x080c, 0x1989, 0x080c, 0xb870, 0x0158, 0xa9ac, 0xa936, 0xa9b0,
-	0xa93a, 0xa83f, 0xffff, 0xa843, 0xffff, 0xa880, 0xc0bd, 0xa882,
-	0x080c, 0xb45e, 0x0005, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be,
-	0xd0bc, 0x6024, 0x190c, 0xbc71, 0x2029, 0x00c8, 0x8529, 0x0128,
-	0x2001, 0x0201, 0x2004, 0x9005, 0x0dc8, 0x7dbc, 0x080c, 0xd61c,
-	0xd5a4, 0x1118, 0x080c, 0x1547, 0x0005, 0x080c, 0x7b25, 0x080c,
-	0x1989, 0x0005, 0x781f, 0x0300, 0x7803, 0x0001, 0x0005, 0x0016,
-	0x0066, 0x0076, 0x00f6, 0x2079, 0x0300, 0x7908, 0x918c, 0x0007,
-	0x9186, 0x0003, 0x0120, 0x2001, 0x0016, 0x080c, 0x15b8, 0x00fe,
-	0x007e, 0x006e, 0x001e, 0x0005, 0x7004, 0xc09d, 0x7006, 0x0005,
-	0x7104, 0x9184, 0x0004, 0x190c, 0x0d65, 0xd184, 0x1189, 0xd19c,
-	0x0158, 0xc19c, 0x7106, 0x2001, 0x020d, 0x2003, 0x0050, 0x2003,
-	0x0020, 0x080c, 0x1547, 0x0005, 0x81ff, 0x190c, 0x0d65, 0x0005,
-	0xc184, 0xd1b4, 0xc1b4, 0x7106, 0x0016, 0x00e6, 0x15e0, 0x2071,
-	0x0200, 0x080c, 0x15f3, 0x6014, 0x9005, 0x05a8, 0x0096, 0x2048,
-	0xa864, 0x009e, 0x9084, 0x00ff, 0x908e, 0x0029, 0x0160, 0x908e,
-	0x0048, 0x1548, 0x601c, 0xd084, 0x11d8, 0x00f6, 0x2c78, 0x080c,
-	0x1669, 0x00fe, 0x00a8, 0x00f6, 0x2c78, 0x080c, 0x17b1, 0x00fe,
-	0x2009, 0x01f4, 0x8109, 0x0160, 0x2001, 0x0201, 0x2004, 0x9005,
-	0x0dc8, 0x2001, 0x0218, 0x2004, 0xd0ec, 0x1110, 0x0401, 0x0040,
-	0x2001, 0x020d, 0x2003, 0x0020, 0x080c, 0x1302, 0x7803, 0x0001,
-	0x00ee, 0x001e, 0x0005, 0x2001, 0x020d, 0x2003, 0x0050, 0x2003,
-	0x0020, 0x0069, 0x0ca8, 0x0031, 0x2060, 0x2009, 0x0053, 0x080c,
-	0x9c82, 0x0005, 0x7808, 0xd09c, 0x0de8, 0x7820, 0x0005, 0x080c,
-	0x14bf, 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, 0x15aa, 0x6827, 0x0001, 0x8109, 0x1dd0, 0x04d9, 0x6827,
-	0x0002, 0x04c1, 0x6804, 0x9005, 0x1130, 0x682c, 0xd0e4, 0x1500,
-	0x6804, 0x9005, 0x0de8, 0x79b8, 0xd1ec, 0x1130, 0x08c0, 0x080c,
-	0x7b25, 0x080c, 0x1989, 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, 0x1342, 0x00ce, 0x002e, 0x001e, 0x000e,
-	0x0006, 0x7832, 0x7936, 0x7a3a, 0x781b, 0x8080, 0x0059, 0x1118,
-	0x000e, 0x00fe, 0x0005, 0x000e, 0x792c, 0x3900, 0x8000, 0x2004,
-	0x080c, 0x0d65, 0x2009, 0xff00, 0x8109, 0x0120, 0x7818, 0xd0bc,
-	0x1dd8, 0x0005, 0x9085, 0x0001, 0x0005, 0x7832, 0x7936, 0x7a3a,
-	0x781b, 0x8080, 0x0c79, 0x1108, 0x0005, 0x792c, 0x3900, 0x8000,
-	0x2004, 0x080c, 0x0d65, 0x7037, 0x0001, 0x7150, 0x7037, 0x0002,
-	0x7050, 0x2060, 0xd1bc, 0x1110, 0x7054, 0x2060, 0x0005, 0x00e6,
-	0x0016, 0x2071, 0x0200, 0x0c79, 0x6124, 0xd1dc, 0x01f8, 0x701c,
-	0xd08c, 0x0904, 0x165e, 0x7017, 0x0000, 0x2001, 0x0264, 0x2004,
-	0xd0bc, 0x0904, 0x165e, 0x2001, 0x0268, 0x00c6, 0x2064, 0x6104,
-	0x6038, 0x00ce, 0x918e, 0x0039, 0x1904, 0x165e, 0x9c06, 0x15f0,
-	0x0126, 0x2091, 0x2600, 0x080c, 0x7a7d, 0x012e, 0x7358, 0x745c,
-	0x6014, 0x905d, 0x0598, 0x2b48, 0x6010, 0x00b6, 0x2058, 0xb800,
-	0x00be, 0xd0bc, 0x190c, 0xbc4c, 0xab42, 0xac3e, 0x2001, 0x187d,
-	0x2004, 0xd0b4, 0x1170, 0x601c, 0xd0e4, 0x1158, 0x6010, 0x00b6,
-	0x2058, 0xb800, 0x00be, 0xd0bc, 0x1120, 0xa83b, 0x7fff, 0xa837,
-	0xffff, 0x080c, 0x1d3c, 0x1190, 0x080c, 0x180c, 0x2a00, 0xa816,
-	0x0130, 0x2800, 0xa80e, 0x2c05, 0xa80a, 0x2c00, 0xa812, 0x7037,
-	0x0020, 0x781f, 0x0300, 0x001e, 0x00ee, 0x0005, 0x7037, 0x0050,
-	0x7037, 0x0020, 0x001e, 0x00ee, 0x080c, 0x1547, 0x0005, 0x080c,
-	0x0d65, 0x0016, 0x2009, 0x00a0, 0x8109, 0xa001, 0xa001, 0xa001,
-	0x1dd8, 0x001e, 0x2cf0, 0x0126, 0x2091, 0x2200, 0x00c6, 0x3e60,
-	0x6014, 0x2048, 0x2940, 0x903e, 0x2730, 0xa864, 0x2068, 0xa81a,
-	0x9d84, 0x000f, 0x9088, 0x1d1c, 0x2165, 0x0002, 0x169d, 0x16ea,
-	0x169d, 0x169d, 0x169d, 0x16cc, 0x169d, 0x16a1, 0x1696, 0x16e1,
-	0x169d, 0x169d, 0x169d, 0x17a6, 0x16b5, 0x16ab, 0xa964, 0x918c,
-	0x00ff, 0x918e, 0x0048, 0x0904, 0x16e1, 0x9085, 0x0001, 0x0804,
-	0x179d, 0xa87c, 0xd0bc, 0x0dc8, 0xa890, 0xa842, 0xa88c, 0xa83e,
-	0xa888, 0x0804, 0x16f1, 0xa87c, 0xd0bc, 0x0d78, 0xa890, 0xa842,
-	0xa88c, 0xa83e, 0xa888, 0x0804, 0x1740, 0xa87c, 0xd0bc, 0x0d28,
-	0xa890, 0xa842, 0xa88c, 0xa83e, 0xa804, 0x9045, 0x090c, 0x0d65,
-	0xa164, 0xa91a, 0x91ec, 0x000f, 0x9d80, 0x1d1c, 0x2065, 0xa888,
-	0xd19c, 0x1904, 0x1740, 0x0428, 0xa87c, 0xd0ac, 0x0970, 0xa804,
-	0x9045, 0x090c, 0x0d65, 0xa164, 0xa91a, 0x91ec, 0x000f, 0x9d80,
-	0x1d1c, 0x2065, 0x9006, 0xa842, 0xa83e, 0xd19c, 0x1904, 0x1740,
-	0x0080, 0xa87c, 0xd0ac, 0x0904, 0x169d, 0x9006, 0xa842, 0xa83e,
-	0x0804, 0x1740, 0xa87c, 0xd0ac, 0x0904, 0x169d, 0x9006, 0xa842,
-	0xa83e, 0x2c05, 0x908a, 0x0036, 0x1a0c, 0x0d65, 0x9082, 0x001b,
-	0x0002, 0x1714, 0x1714, 0x1716, 0x1714, 0x1714, 0x1714, 0x171c,
-	0x1714, 0x1714, 0x1714, 0x1722, 0x1714, 0x1714, 0x1714, 0x1728,
-	0x1714, 0x1714, 0x1714, 0x172e, 0x1714, 0x1714, 0x1714, 0x1734,
-	0x1714, 0x1714, 0x1714, 0x173a, 0x080c, 0x0d65, 0xa574, 0xa478,
-	0xa37c, 0xa280, 0x0804, 0x1785, 0xa584, 0xa488, 0xa38c, 0xa290,
-	0x0804, 0x1785, 0xa594, 0xa498, 0xa39c, 0xa2a0, 0x0804, 0x1785,
-	0xa5a4, 0xa4a8, 0xa3ac, 0xa2b0, 0x0804, 0x1785, 0xa5b4, 0xa4b8,
-	0xa3bc, 0xa2c0, 0x0804, 0x1785, 0xa5c4, 0xa4c8, 0xa3cc, 0xa2d0,
-	0x0804, 0x1785, 0xa5d4, 0xa4d8, 0xa3dc, 0xa2e0, 0x0804, 0x1785,
-	0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0d65, 0x9082, 0x001b, 0x0002,
-	0x1763, 0x1761, 0x1761, 0x1761, 0x1761, 0x1761, 0x176a, 0x1761,
-	0x1761, 0x1761, 0x1761, 0x1761, 0x1771, 0x1761, 0x1761, 0x1761,
-	0x1761, 0x1761, 0x1778, 0x1761, 0x1761, 0x1761, 0x1761, 0x1761,
-	0x177f, 0x080c, 0x0d65, 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, 0x1158, 0x3e60, 0x601c, 0xc085,
-	0x601e, 0xa87c, 0xc0dd, 0xa87e, 0x9006, 0x00ce, 0x012e, 0x0005,
-	0x2800, 0xa80e, 0xab0a, 0x2c00, 0xa812, 0x0c78, 0x0804, 0x169d,
-	0x0016, 0x2009, 0x00a0, 0x8109, 0xa001, 0xa001, 0xa001, 0x1dd8,
-	0x001e, 0x2ff0, 0x0126, 0x2091, 0x2200, 0x00c6, 0x3e60, 0x6014,
-	0x2048, 0x2940, 0xa80e, 0x2061, 0x1d17, 0xa813, 0x1d17, 0x2c05,
-	0xa80a, 0xa964, 0xa91a, 0xa87c, 0xd0ac, 0x090c, 0x0d65, 0x9006,
-	0xa842, 0xa83e, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0d65, 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, 0x0078, 0x918a, 0x0002, 0xa916, 0x1158, 0x3e60, 0x601c,
-	0xc085, 0x601e, 0xa87c, 0xc0dd, 0xa87e, 0x9006, 0x00ce, 0x012e,
-	0x0005, 0xa804, 0x9045, 0x090c, 0x0d65, 0xa80e, 0xa064, 0xa81a,
-	0x9084, 0x000f, 0x9080, 0x1d1c, 0x2015, 0x82ff, 0x090c, 0x0d65,
-	0xaa12, 0x2205, 0xa80a, 0x0c10, 0x903e, 0x2730, 0xa880, 0xd0fc,
-	0x1190, 0x2d00, 0x0002, 0x1901, 0x1863, 0x1863, 0x1901, 0x1901,
-	0x18fb, 0x1901, 0x1863, 0x18b2, 0x18b2, 0x18b2, 0x1901, 0x1901,
-	0x1901, 0x18f8, 0x18b2, 0xc0fc, 0xa882, 0xab2c, 0xaa30, 0xad1c,
-	0xac20, 0xdd9c, 0x0904, 0x1903, 0x2c05, 0x908a, 0x0034, 0x1a0c,
-	0x0d65, 0x9082, 0x001b, 0x0002, 0x184f, 0x184d, 0x184d, 0x184d,
-	0x184d, 0x184d, 0x1853, 0x184d, 0x184d, 0x184d, 0x184d, 0x184d,
-	0x1857, 0x184d, 0x184d, 0x184d, 0x184d, 0x184d, 0x185b, 0x184d,
-	0x184d, 0x184d, 0x184d, 0x184d, 0x185f, 0x080c, 0x0d65, 0xa774,
-	0xa678, 0x0804, 0x1903, 0xa78c, 0xa690, 0x0804, 0x1903, 0xa7a4,
-	0xa6a8, 0x0804, 0x1903, 0xa7bc, 0xa6c0, 0x0804, 0x1903, 0xa7d4,
-	0xa6d8, 0x0804, 0x1903, 0x2c05, 0x908a, 0x0036, 0x1a0c, 0x0d65,
-	0x9082, 0x001b, 0x0002, 0x1886, 0x1886, 0x1888, 0x1886, 0x1886,
-	0x1886, 0x188e, 0x1886, 0x1886, 0x1886, 0x1894, 0x1886, 0x1886,
-	0x1886, 0x189a, 0x1886, 0x1886, 0x1886, 0x18a0, 0x1886, 0x1886,
-	0x1886, 0x18a6, 0x1886, 0x1886, 0x1886, 0x18ac, 0x080c, 0x0d65,
-	0xa574, 0xa478, 0xa37c, 0xa280, 0x0804, 0x1903, 0xa584, 0xa488,
-	0xa38c, 0xa290, 0x0804, 0x1903, 0xa594, 0xa498, 0xa39c, 0xa2a0,
-	0x0804, 0x1903, 0xa5a4, 0xa4a8, 0xa3ac, 0xa2b0, 0x0804, 0x1903,
-	0xa5b4, 0xa4b8, 0xa3bc, 0xa2c0, 0x0804, 0x1903, 0xa5c4, 0xa4c8,
-	0xa3cc, 0xa2d0, 0x0804, 0x1903, 0xa5d4, 0xa4d8, 0xa3dc, 0xa2e0,
-	0x0804, 0x1903, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0d65, 0x9082,
-	0x001b, 0x0002, 0x18d5, 0x18d3, 0x18d3, 0x18d3, 0x18d3, 0x18d3,
-	0x18dc, 0x18d3, 0x18d3, 0x18d3, 0x18d3, 0x18d3, 0x18e3, 0x18d3,
-	0x18d3, 0x18d3, 0x18d3, 0x18d3, 0x18ea, 0x18d3, 0x18d3, 0x18d3,
-	0x18d3, 0x18d3, 0x18f1, 0x080c, 0x0d65, 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, 0x1cf2, 0x1904, 0x180c, 0x900e,
-	0x0050, 0x080c, 0x0d65, 0xab2e, 0xaa32, 0xad1e, 0xac22, 0xaf26,
-	0xae2a, 0x080c, 0x1cf2, 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,
-	0x9c82, 0x0005, 0xa974, 0xd1dc, 0x1108, 0x0005, 0xa934, 0xa88c,
-	0x9106, 0x1158, 0xa938, 0xa890, 0x9106, 0x1138, 0x601c, 0xc084,
-	0x601e, 0x2009, 0x0048, 0x0804, 0x9c82, 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, 0x1342, 0x8631, 0x1db8, 0x00ce, 0x781f, 0x0800, 0x2031,
-	0x0168, 0x00c6, 0x7808, 0xd09c, 0x190c, 0x1342, 0x00ce, 0x2001,
-	0x0038, 0x080c, 0x1a11, 0x7930, 0x9186, 0x0040, 0x0160, 0x9186,
-	0x0042, 0x190c, 0x0d65, 0x2001, 0x001e, 0x8001, 0x1df0, 0x8631,
-	0x1d40, 0x080c, 0x1a20, 0x000e, 0x6022, 0x012e, 0x0005, 0x080c,
-	0x1a0d, 0x7827, 0x0015, 0x7828, 0x9c06, 0x1db8, 0x782b, 0x0000,
-	0x0ca0, 0x00f6, 0x2079, 0x0300, 0x7803, 0x0000, 0x78ab, 0x0004,
-	0x00fe, 0x080c, 0x70ba, 0x1188, 0x2001, 0x0138, 0x2003, 0x0000,
-	0x2001, 0x0160, 0x2003, 0x0000, 0x2011, 0x012c, 0xa001, 0xa001,
-	0x8211, 0x1de0, 0x0059, 0x0804, 0x715f, 0x0479, 0x0039, 0x2001,
-	0x0160, 0x2502, 0x2001, 0x0138, 0x2202, 0x0005, 0x00e6, 0x2071,
-	0x0200, 0x080c, 0x2864, 0x2009, 0x003c, 0x080c, 0x207b, 0x2001,
-	0x015d, 0x2003, 0x0000, 0x7000, 0x9084, 0x003c, 0x1de0, 0x080c,
-	0x8087, 0x70a0, 0x70a2, 0x7098, 0x709a, 0x709c, 0x709e, 0x2001,
-	0x020d, 0x2003, 0x0020, 0x00f6, 0x2079, 0x0300, 0x080c, 0x1302,
-	0x7803, 0x0001, 0x00fe, 0x00ee, 0x0005, 0x2001, 0x0138, 0x2014,
-	0x2003, 0x0000, 0x2001, 0x0160, 0x202c, 0x2003, 0x0000, 0x080c,
-	0x70ba, 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, 0x15b8, 0x7930, 0x0005, 0x2c08,
-	0x621c, 0x080c, 0x15e5, 0x7930, 0x0005, 0x8001, 0x1df0, 0x0005,
-	0x2031, 0x0005, 0x781c, 0x9084, 0x0007, 0x0170, 0x2001, 0x0038,
-	0x0c41, 0x9186, 0x0040, 0x0904, 0x1a7e, 0x2001, 0x001e, 0x0c69,
-	0x8631, 0x1d80, 0x080c, 0x0d65, 0x781f, 0x0202, 0x2001, 0x015d,
-	0x2003, 0x0000, 0x2001, 0x0b10, 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, 0x1a17, 0x9186, 0x0040, 0x190c, 0x0d65, 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, 0x0d65, 0xa001, 0xa001, 0x781f, 0x0200, 0x0005, 0x0126,
-	0x2091, 0x2400, 0x2079, 0x0380, 0x2001, 0x19bf, 0x2070, 0x012e,
-	0x0005, 0x2cf0, 0x0126, 0x2091, 0x2400, 0x3e60, 0x6014, 0x2048,
-	0xa964, 0xa91a, 0x918c, 0x00ff, 0x9184, 0x000f, 0x0002, 0x1ab3,
-	0x1ab3, 0x1ab3, 0x1ab3, 0x1ab3, 0x1ab3, 0x1ab3, 0x1ab3, 0x1aa7,
-	0x1ab5, 0x1ab3, 0x1ab3, 0x1ab3, 0x1ab3, 0x1ab3, 0x1ab3, 0x9086,
-	0x0008, 0x1148, 0xa87c, 0xd0b4, 0x0904, 0x1c25, 0x2011, 0x1d17,
-	0x2205, 0xab88, 0x0068, 0x080c, 0x0d65, 0xa87c, 0xd0b4, 0x0904,
-	0x1c25, 0x9184, 0x000f, 0x9080, 0x1d1c, 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, 0x1d1c,
-	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, 0x1bef, 0xc1dd, 0xa97e, 0x9006, 0xa842, 0xa83e,
-	0xa988, 0x8109, 0xa916, 0xa964, 0xa91a, 0x9184, 0x000f, 0x9088,
-	0x1d1c, 0x2145, 0x0002, 0x1b23, 0x1b31, 0x1b23, 0x1b23, 0x1b23,
-	0x1b25, 0x1b23, 0x1b23, 0x1b86, 0x1b86, 0x1b23, 0x1b23, 0x1b23,
-	0x1b84, 0x1b23, 0x1b23, 0x080c, 0x0d65, 0xa804, 0x2050, 0xb164,
-	0xa91a, 0x9184, 0x000f, 0x9080, 0x1d1c, 0x2045, 0xd19c, 0x1904,
-	0x1b86, 0x9036, 0x2638, 0x2805, 0x908a, 0x0036, 0x1a0c, 0x0d65,
-	0x9082, 0x001b, 0x0002, 0x1b56, 0x1b56, 0x1b58, 0x1b56, 0x1b56,
-	0x1b56, 0x1b5e, 0x1b56, 0x1b56, 0x1b56, 0x1b64, 0x1b56, 0x1b56,
-	0x1b56, 0x1b6a, 0x1b56, 0x1b56, 0x1b56, 0x1b70, 0x1b56, 0x1b56,
-	0x1b56, 0x1b76, 0x1b56, 0x1b56, 0x1b56, 0x1b7c, 0x080c, 0x0d65,
-	0xb574, 0xb478, 0xb37c, 0xb280, 0x0804, 0x1bcb, 0xb584, 0xb488,
-	0xb38c, 0xb290, 0x0804, 0x1bcb, 0xb594, 0xb498, 0xb39c, 0xb2a0,
-	0x0804, 0x1bcb, 0xb5a4, 0xb4a8, 0xb3ac, 0xb2b0, 0x0804, 0x1bcb,
-	0xb5b4, 0xb4b8, 0xb3bc, 0xb2c0, 0x0804, 0x1bcb, 0xb5c4, 0xb4c8,
-	0xb3cc, 0xb2d0, 0x0804, 0x1bcb, 0xb5d4, 0xb4d8, 0xb3dc, 0xb2e0,
-	0x0804, 0x1bcb, 0x0804, 0x1bcb, 0x080c, 0x0d65, 0x2805, 0x908a,
-	0x0034, 0x1a0c, 0x0d65, 0x9082, 0x001b, 0x0002, 0x1ba9, 0x1ba7,
-	0x1ba7, 0x1ba7, 0x1ba7, 0x1ba7, 0x1bb0, 0x1ba7, 0x1ba7, 0x1ba7,
-	0x1ba7, 0x1ba7, 0x1bb7, 0x1ba7, 0x1ba7, 0x1ba7, 0x1ba7, 0x1ba7,
-	0x1bbe, 0x1ba7, 0x1ba7, 0x1ba7, 0x1ba7, 0x1ba7, 0x1bc5, 0x080c,
-	0x0d65, 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, 0x0d65,
-	0x2050, 0xb164, 0xa91a, 0x9184, 0x000f, 0x9080, 0x1d1c, 0x2045,
-	0x2805, 0x2810, 0x2a08, 0xa80a, 0xa90e, 0xaa12, 0x0c30, 0x3e60,
-	0x6344, 0xd3fc, 0x190c, 0x0d65, 0xa93c, 0xaa40, 0xa844, 0x9106,
-	0x1118, 0xa848, 0x9206, 0x0508, 0x2958, 0xab48, 0xac44, 0x2940,
-	0x080c, 0x1d3c, 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, 0x1bd8, 0x2009, 0x8005, 0x3e60,
-	0x6044, 0x9105, 0x6046, 0x0804, 0x1bd5, 0x080c, 0x0d65, 0x00f6,
-	0x00e6, 0x0096, 0x00c6, 0x0026, 0x704c, 0x9c06, 0x190c, 0x0d65,
-	0x2079, 0x0090, 0x2001, 0x0105, 0x2003, 0x0010, 0x782b, 0x0004,
-	0x7057, 0x0000, 0x6014, 0x2048, 0x080c, 0xb870, 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,
-	0xb45e, 0x080c, 0x98c7, 0x00ce, 0x704c, 0x9c06, 0x1150, 0x2009,
-	0x0040, 0x080c, 0x207b, 0x080c, 0x94a4, 0x2011, 0x0000, 0x080c,
-	0x932e, 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, 0x0d65, 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, 0x19bf, 0x7054, 0x9086, 0x0000, 0x0904, 0x1ced,
-	0x2079, 0x0090, 0x2009, 0x0207, 0x210c, 0xd194, 0x01b8, 0x2009,
-	0x020c, 0x210c, 0x9184, 0x0003, 0x0188, 0x080c, 0xd665, 0x2001,
-	0x0133, 0x2004, 0x9005, 0x090c, 0x0d65, 0x0016, 0x2009, 0x0040,
-	0x080c, 0x207b, 0x001e, 0x2001, 0x020c, 0x2102, 0x2009, 0x0206,
-	0x2104, 0x2009, 0x0203, 0x210c, 0x9106, 0x1120, 0x2009, 0x0040,
-	0x080c, 0x207b, 0x782c, 0xd0fc, 0x09a8, 0x080c, 0x98e3, 0x782c,
-	0xd0fc, 0x1de8, 0x080c, 0x98c7, 0x7054, 0x9086, 0x0000, 0x1950,
-	0x782b, 0x0004, 0x782c, 0xd0ac, 0x1de8, 0x2009, 0x0040, 0x080c,
-	0x207b, 0x782b, 0x0002, 0x7057, 0x0000, 0x00ee, 0x00fe, 0x0005,
-	0x080c, 0x0d65, 0x8c60, 0x2c05, 0x9005, 0x0110, 0x8a51, 0x0005,
-	0xa004, 0x9005, 0x0168, 0xa85a, 0x2040, 0xa064, 0x9084, 0x000f,
-	0x9080, 0x1d1c, 0x2065, 0x8cff, 0x090c, 0x0d65, 0x8a51, 0x0005,
-	0x2050, 0x0005, 0x0000, 0x001d, 0x0021, 0x0025, 0x0029, 0x002d,
-	0x0031, 0x0035, 0x0000, 0x001b, 0x0021, 0x0027, 0x002d, 0x0033,
-	0x0000, 0x0000, 0x0023, 0x0000, 0x0000, 0x1d0f, 0x1d0b, 0x0000,
-	0x0000, 0x1d19, 0x0000, 0x1d0f, 0x1d16, 0x1d16, 0x1d13, 0x0000,
-	0x0000, 0x0000, 0x1d19, 0x1d16, 0x0000, 0x1d11, 0x1d11, 0x0000,
-	0x0000, 0x1d19, 0x0000, 0x1d11, 0x1d17, 0x1d17, 0x1d17, 0x0000,
-	0x0000, 0x0000, 0x1d19, 0x1d17, 0x00c6, 0x00d6, 0x0086, 0xab42,
-	0xac3e, 0xa888, 0x9055, 0x0904, 0x1f1b, 0x2940, 0xa064, 0x90ec,
-	0x000f, 0x9084, 0x00ff, 0x9086, 0x0008, 0x1118, 0x2061, 0x1d17,
-	0x00d0, 0x9de0, 0x1d1c, 0x9d86, 0x0007, 0x0130, 0x9d86, 0x000e,
-	0x0118, 0x9d86, 0x000f, 0x1120, 0xa08c, 0x9422, 0xa090, 0x931b,
-	0x2c05, 0x9065, 0x1140, 0x0310, 0x0804, 0x1f1b, 0xa004, 0x9045,
-	0x0904, 0x1f1b, 0x08d8, 0x2c05, 0x9005, 0x0904, 0x1e03, 0xdd9c,
-	0x1904, 0x1dbf, 0x908a, 0x0036, 0x1a0c, 0x0d65, 0x9082, 0x001b,
-	0x0002, 0x1d94, 0x1d94, 0x1d96, 0x1d94, 0x1d94, 0x1d94, 0x1d9c,
-	0x1d94, 0x1d94, 0x1d94, 0x1da2, 0x1d94, 0x1d94, 0x1d94, 0x1da8,
-	0x1d94, 0x1d94, 0x1d94, 0x1dae, 0x1d94, 0x1d94, 0x1d94, 0x1db4,
-	0x1d94, 0x1d94, 0x1d94, 0x1dba, 0x080c, 0x0d65, 0xa07c, 0x9422,
-	0xa080, 0x931b, 0x0804, 0x1df9, 0xa08c, 0x9422, 0xa090, 0x931b,
-	0x0804, 0x1df9, 0xa09c, 0x9422, 0xa0a0, 0x931b, 0x0804, 0x1df9,
-	0xa0ac, 0x9422, 0xa0b0, 0x931b, 0x0804, 0x1df9, 0xa0bc, 0x9422,
-	0xa0c0, 0x931b, 0x0804, 0x1df9, 0xa0cc, 0x9422, 0xa0d0, 0x931b,
-	0x0804, 0x1df9, 0xa0dc, 0x9422, 0xa0e0, 0x931b, 0x04d0, 0x908a,
-	0x0034, 0x1a0c, 0x0d65, 0x9082, 0x001b, 0x0002, 0x1de1, 0x1ddf,
-	0x1ddf, 0x1ddf, 0x1ddf, 0x1ddf, 0x1de6, 0x1ddf, 0x1ddf, 0x1ddf,
-	0x1ddf, 0x1ddf, 0x1deb, 0x1ddf, 0x1ddf, 0x1ddf, 0x1ddf, 0x1ddf,
-	0x1df0, 0x1ddf, 0x1ddf, 0x1ddf, 0x1ddf, 0x1ddf, 0x1df5, 0x080c,
-	0x0d65, 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, 0x1f1b,
-	0x8c60, 0x0804, 0x1d6b, 0xa004, 0x9045, 0x0904, 0x1f1b, 0x0804,
-	0x1d46, 0x8a51, 0x0904, 0x1f1b, 0x8c60, 0x2c05, 0x9005, 0x1158,
-	0xa004, 0x9045, 0x0904, 0x1f1b, 0xa064, 0x90ec, 0x000f, 0x9de0,
-	0x1d1c, 0x2c05, 0x2060, 0xa880, 0xc0fc, 0xa882, 0x0804, 0x1f10,
-	0x2c05, 0x8422, 0x8420, 0x831a, 0x9399, 0x0000, 0xac2e, 0xab32,
-	0xdd9c, 0x1904, 0x1ead, 0x9082, 0x001b, 0x0002, 0x1e49, 0x1e49,
-	0x1e4b, 0x1e49, 0x1e49, 0x1e49, 0x1e59, 0x1e49, 0x1e49, 0x1e49,
-	0x1e67, 0x1e49, 0x1e49, 0x1e49, 0x1e75, 0x1e49, 0x1e49, 0x1e49,
-	0x1e83, 0x1e49, 0x1e49, 0x1e49, 0x1e91, 0x1e49, 0x1e49, 0x1e49,
-	0x1e9f, 0x080c, 0x0d65, 0xa17c, 0x2400, 0x9122, 0xa180, 0x2300,
-	0x911b, 0x0a0c, 0x0d65, 0xa074, 0x9420, 0xa078, 0x9319, 0x0804,
-	0x1f0b, 0xa18c, 0x2400, 0x9122, 0xa190, 0x2300, 0x911b, 0x0a0c,
-	0x0d65, 0xa084, 0x9420, 0xa088, 0x9319, 0x0804, 0x1f0b, 0xa19c,
-	0x2400, 0x9122, 0xa1a0, 0x2300, 0x911b, 0x0a0c, 0x0d65, 0xa094,
-	0x9420, 0xa098, 0x9319, 0x0804, 0x1f0b, 0xa1ac, 0x2400, 0x9122,
-	0xa1b0, 0x2300, 0x911b, 0x0a0c, 0x0d65, 0xa0a4, 0x9420, 0xa0a8,
-	0x9319, 0x0804, 0x1f0b, 0xa1bc, 0x2400, 0x9122, 0xa1c0, 0x2300,
-	0x911b, 0x0a0c, 0x0d65, 0xa0b4, 0x9420, 0xa0b8, 0x9319, 0x0804,
-	0x1f0b, 0xa1cc, 0x2400, 0x9122, 0xa1d0, 0x2300, 0x911b, 0x0a0c,
-	0x0d65, 0xa0c4, 0x9420, 0xa0c8, 0x9319, 0x0804, 0x1f0b, 0xa1dc,
-	0x2400, 0x9122, 0xa1e0, 0x2300, 0x911b, 0x0a0c, 0x0d65, 0xa0d4,
-	0x9420, 0xa0d8, 0x9319, 0x0804, 0x1f0b, 0x9082, 0x001b, 0x0002,
-	0x1ecb, 0x1ec9, 0x1ec9, 0x1ec9, 0x1ec9, 0x1ec9, 0x1ed8, 0x1ec9,
-	0x1ec9, 0x1ec9, 0x1ec9, 0x1ec9, 0x1ee5, 0x1ec9, 0x1ec9, 0x1ec9,
-	0x1ec9, 0x1ec9, 0x1ef2, 0x1ec9, 0x1ec9, 0x1ec9, 0x1ec9, 0x1ec9,
-	0x1eff, 0x080c, 0x0d65, 0xa17c, 0x2400, 0x9122, 0xa180, 0x2300,
-	0x911b, 0x0a0c, 0x0d65, 0xa06c, 0x9420, 0xa070, 0x9319, 0x0498,
-	0xa194, 0x2400, 0x9122, 0xa198, 0x2300, 0x911b, 0x0a0c, 0x0d65,
-	0xa084, 0x9420, 0xa088, 0x9319, 0x0430, 0xa1ac, 0x2400, 0x9122,
-	0xa1b0, 0x2300, 0x911b, 0x0a0c, 0x0d65, 0xa09c, 0x9420, 0xa0a0,
-	0x9319, 0x00c8, 0xa1c4, 0x2400, 0x9122, 0xa1c8, 0x2300, 0x911b,
-	0x0a0c, 0x0d65, 0xa0b4, 0x9420, 0xa0b8, 0x9319, 0x0060, 0xa1dc,
-	0x2400, 0x9122, 0xa1e0, 0x2300, 0x911b, 0x0a0c, 0x0d65, 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, 0x0d5e, 0xd094, 0x0110, 0x080c, 0x11de, 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, 0x2078, 0x7900, 0xd1dc, 0x1118,
-	0x9084, 0x0006, 0x001a, 0x9084, 0x000e, 0x0002, 0x1f96, 0x1f8e,
-	0x7a7d, 0x1f8e, 0x1f90, 0x1f90, 0x1f90, 0x1f90, 0x7a63, 0x1f8e,
-	0x1f92, 0x1f8e, 0x1f90, 0x1f8e, 0x1f90, 0x1f8e, 0x080c, 0x0d65,
-	0x0031, 0x0020, 0x080c, 0x7a63, 0x080c, 0x7a7d, 0x0005, 0x0006,
-	0x0016, 0x0026, 0x080c, 0xd665, 0x7930, 0x9184, 0x0003, 0x0510,
-	0x080c, 0x98c7, 0x2001, 0x19d2, 0x2004, 0x9005, 0x01a0, 0x2001,
-	0x0133, 0x2004, 0x9005, 0x090c, 0x0d65, 0x00c6, 0x2001, 0x19d2,
-	0x2064, 0x080c, 0x98e3, 0x080c, 0xb45e, 0x2009, 0x0040, 0x080c,
-	0x207b, 0x00ce, 0x0408, 0x2009, 0x0040, 0x080c, 0x207b, 0x080c,
-	0x98e3, 0x00d0, 0x9184, 0x0014, 0x01a0, 0x6a00, 0x9286, 0x0003,
-	0x0160, 0x080c, 0x70ba, 0x1138, 0x080c, 0x73b9, 0x080c, 0x5cf7,
-	0x080c, 0x6feb, 0x0010, 0x080c, 0x5bb2, 0x080c, 0x7b1b, 0x0041,
-	0x0018, 0x9184, 0x9540, 0x1dc8, 0x002e, 0x001e, 0x000e, 0x0005,
-	0x00e6, 0x0036, 0x0046, 0x0056, 0x2071, 0x1a43, 0x080c, 0x1989,
-	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, 0x0d5e, 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,
-	0x285e, 0x080c, 0x2774, 0x2001, 0x1975, 0x2003, 0x0700, 0x2001,
-	0x1976, 0x2003, 0x0700, 0x080c, 0x28cf, 0x9006, 0x080c, 0x27a3,
-	0x9006, 0x080c, 0x2786, 0x20a9, 0x0012, 0x1d04, 0x20ad, 0x2091,
-	0x6000, 0x1f04, 0x20ad, 0x602f, 0x0100, 0x602f, 0x0000, 0x6050,
-	0x9085, 0x0400, 0x9084, 0xdfff, 0x6052, 0x6224, 0x080c, 0x28ac,
-	0x080c, 0x2492, 0x2009, 0x00ef, 0x6132, 0x6136, 0x080c, 0x24a2,
-	0x60e7, 0x0000, 0x61ea, 0x60e3, 0x0002, 0x604b, 0xf7f7, 0x6043,
-	0x0000, 0x602f, 0x0080, 0x602f, 0x0000, 0x6007, 0x149f, 0x00c6,
-	0x2061, 0x0140, 0x608b, 0x000b, 0x608f, 0x10b8, 0x6093, 0x0000,
-	0x6097, 0x0198, 0x00ce, 0x6004, 0x9085, 0x8000, 0x6006, 0x60bb,
-	0x0000, 0x20a9, 0x0018, 0x60bf, 0x0000, 0x1f04, 0x20eb, 0x60bb,
-	0x0000, 0x60bf, 0x0108, 0x60bf, 0x0012, 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, 0x1834,
-	0x2003, 0x0000, 0x2001, 0x1833, 0x2003, 0x0001, 0x0005, 0x0126,
-	0x2091, 0x2800, 0x0006, 0x0016, 0x0026, 0x6124, 0x6028, 0x910c,
-	0x9184, 0x5e2c, 0x1118, 0x9184, 0x0007, 0x002a, 0x9195, 0x0004,
-	0x9284, 0x0007, 0x0002, 0x2136, 0x2133, 0x2133, 0x2133, 0x2135,
-	0x2133, 0x2133, 0x2133, 0x080c, 0x0d65, 0x0029, 0x002e, 0x001e,
-	0x000e, 0x012e, 0x0005, 0x00a6, 0x6124, 0x6028, 0xd09c, 0x0118,
-	0xd19c, 0x1904, 0x2395, 0xd1f4, 0x190c, 0x0d5e, 0x080c, 0x70ba,
-	0x0904, 0x2193, 0x080c, 0xbf8f, 0x1120, 0x7000, 0x9086, 0x0003,
-	0x0580, 0x6024, 0x9084, 0x1800, 0x0560, 0x080c, 0x70dd, 0x0118,
-	0x080c, 0x70cb, 0x1530, 0x2011, 0x0020, 0x080c, 0x28ac, 0x6043,
-	0x0000, 0x080c, 0xbf8f, 0x0168, 0x080c, 0x70dd, 0x1150, 0x2001,
-	0x197f, 0x2003, 0x0001, 0x6027, 0x1800, 0x080c, 0x6f30, 0x0804,
-	0x2398, 0x70a0, 0x9005, 0x1150, 0x70a3, 0x0001, 0x00d6, 0x2069,
-	0x0140, 0x080c, 0x7111, 0x00de, 0x1904, 0x2398, 0x080c, 0x73c3,
-	0x0428, 0x080c, 0x70dd, 0x1590, 0x6024, 0x9084, 0x1800, 0x1108,
-	0x0468, 0x080c, 0x73c3, 0x080c, 0x73b9, 0x080c, 0x5cf7, 0x080c,
-	0x6feb, 0x0804, 0x2395, 0xd1ac, 0x1508, 0x6024, 0xd0dc, 0x1170,
-	0xd0e4, 0x1178, 0xd0d4, 0x1190, 0xd0cc, 0x0130, 0x7094, 0x9086,
-	0x0028, 0x1110, 0x080c, 0x729c, 0x0804, 0x2395, 0x080c, 0x73be,
-	0x0048, 0x2001, 0x1955, 0x2003, 0x0002, 0x0020, 0x080c, 0x71fa,
-	0x0804, 0x2395, 0x080c, 0x733e, 0x0804, 0x2395, 0xd1ac, 0x0904,
-	0x22af, 0x080c, 0x70ba, 0x11d0, 0x2011, 0x0020, 0x080c, 0x28ac,
-	0x0006, 0x0026, 0x0036, 0x080c, 0x70d4, 0x1158, 0x080c, 0x73b9,
-	0x080c, 0x5cf7, 0x080c, 0x6feb, 0x003e, 0x002e, 0x000e, 0x00ae,
-	0x0005, 0x003e, 0x002e, 0x000e, 0x080c, 0x708e, 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, 0x48fa,
-	0x003e, 0x080c, 0xbf88, 0x1904, 0x2286, 0x9196, 0xff00, 0x05a8,
-	0x705c, 0x9084, 0x00ff, 0x810f, 0x81ff, 0x0110, 0x9116, 0x0568,
-	0x7130, 0xd184, 0x1550, 0x080c, 0x319a, 0x0128, 0xc18d, 0x7132,
-	0x080c, 0x6682, 0x1510, 0x6240, 0x9294, 0x0010, 0x0130, 0x6248,
-	0x9294, 0xff00, 0x9296, 0xff00, 0x01c0, 0x7030, 0xd08c, 0x0904,
-	0x2286, 0x7038, 0xd08c, 0x1140, 0x2001, 0x180c, 0x200c, 0xd1ac,
-	0x1904, 0x2286, 0xc1ad, 0x2102, 0x0036, 0x73d4, 0x2011, 0x8013,
-	0x080c, 0x48fa, 0x003e, 0x0804, 0x2286, 0x7038, 0xd08c, 0x1140,
-	0x2001, 0x180c, 0x200c, 0xd1ac, 0x1904, 0x2286, 0xc1ad, 0x2102,
-	0x0036, 0x73d4, 0x2011, 0x8013, 0x080c, 0x48fa, 0x003e, 0x7130,
-	0xc185, 0x7132, 0x2011, 0x185c, 0x220c, 0x00f0, 0x0016, 0x2009,
-	0x0001, 0x2011, 0x0100, 0x080c, 0x8401, 0x2019, 0x000e, 0x00c6,
-	0x2061, 0x0000, 0x080c, 0xd234, 0x00ce, 0x9484, 0x00ff, 0x9080,
-	0x319f, 0x200d, 0x918c, 0xff00, 0x810f, 0x2120, 0x9006, 0x2009,
-	0x000e, 0x080c, 0xd2bc, 0x001e, 0xd1ac, 0x1148, 0x0016, 0x2009,
-	0x0002, 0x2019, 0x0004, 0x080c, 0x2ff3, 0x001e, 0x0078, 0x0156,
-	0x00b6, 0x20a9, 0x007f, 0x900e, 0x080c, 0x628f, 0x1110, 0x080c,
-	0x5d11, 0x8108, 0x1f04, 0x227c, 0x00be, 0x015e, 0x00ce, 0x004e,
-	0x080c, 0x98c7, 0x080c, 0x9b6c, 0x080c, 0x98e3, 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,
-	0x1825, 0x2003, 0x0000, 0x2011, 0x0020, 0x080c, 0x28ac, 0xd194,
-	0x0904, 0x2395, 0x0016, 0x080c, 0x98c7, 0x6220, 0xd2b4, 0x0904,
-	0x233d, 0x080c, 0x821e, 0x080c, 0x8fd0, 0x2011, 0x0004, 0x080c,
-	0x28ac, 0x00f6, 0x2019, 0x19cb, 0x2304, 0x907d, 0x0904, 0x230a,
-	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, 0x2882, 0x2001, 0x001e, 0x8001, 0x0240,
-	0x20a9, 0x0009, 0x080c, 0x2839, 0x6904, 0xd1dc, 0x1140, 0x0cb0,
-	0x2001, 0x0100, 0x080c, 0x2872, 0x9006, 0x080c, 0x2872, 0x080c,
-	0x8891, 0x080c, 0x98e3, 0x7814, 0x2048, 0xa867, 0x0103, 0x2f60,
-	0x080c, 0x9be6, 0x009e, 0x00ee, 0x00ce, 0x00de, 0x00fe, 0x001e,
-	0x00ae, 0x0005, 0x00fe, 0x00d6, 0x2069, 0x0140, 0x6804, 0x9084,
-	0x4000, 0x0110, 0x080c, 0x2882, 0x00de, 0x00c6, 0x2061, 0x19bf,
-	0x6034, 0x080c, 0xbf8f, 0x0120, 0x909a, 0x0003, 0x1258, 0x0018,
-	0x909a, 0x00c8, 0x1238, 0x8000, 0x6036, 0x00ce, 0x080c, 0x8fa8,
-	0x0804, 0x2392, 0x2061, 0x0100, 0x62c0, 0x080c, 0x97f8, 0x2019,
-	0x19cb, 0x2304, 0x9065, 0x0130, 0x6003, 0x0001, 0x2009, 0x0027,
-	0x080c, 0x9c82, 0x00ce, 0x0804, 0x2392, 0xd2bc, 0x05e0, 0x080c,
-	0x822b, 0x2011, 0x0004, 0x080c, 0x28ac, 0x00d6, 0x2069, 0x0140,
-	0x6804, 0x9084, 0x4000, 0x0110, 0x080c, 0x2882, 0x00de, 0x00c6,
-	0x2061, 0x19bf, 0x6050, 0x080c, 0xbf8f, 0x0120, 0x909a, 0x0003,
-	0x1638, 0x0018, 0x909a, 0x00c8, 0x1618, 0x8000, 0x6052, 0x604c,
-	0x00ce, 0x9005, 0x0578, 0x2009, 0x07d0, 0x080c, 0x8223, 0x9080,
-	0x0008, 0x2004, 0x9086, 0x0006, 0x1138, 0x2009, 0x1984, 0x2011,
-	0x0012, 0x080c, 0x28bb, 0x00f0, 0x2009, 0x1984, 0x2011, 0x0016,
-	0x080c, 0x28bb, 0x00b8, 0x2011, 0x0004, 0x080c, 0x28ac, 0x0090,
-	0x0036, 0x2019, 0x0001, 0x080c, 0x929d, 0x003e, 0x2019, 0x19d2,
-	0x2304, 0x9065, 0x0130, 0x2009, 0x004f, 0x6003, 0x0003, 0x080c,
-	0x9c82, 0x00ce, 0x080c, 0x98e3, 0x001e, 0xd19c, 0x0904, 0x23f7,
-	0x7038, 0xd0ac, 0x1558, 0x0016, 0x0156, 0x2011, 0x0008, 0x080c,
-	0x28ac, 0x080c, 0x28cf, 0x080c, 0x2902, 0x6050, 0xc0e5, 0x6052,
-	0x20a9, 0x0367, 0x1f04, 0x23c4, 0x1d04, 0x23ac, 0x080c, 0x8252,
-	0x6020, 0xd09c, 0x1db8, 0x00f6, 0x2079, 0x0100, 0x080c, 0x27e5,
-	0x00fe, 0x1d80, 0x6050, 0xc0e4, 0x6052, 0x2011, 0x0008, 0x080c,
-	0x28ac, 0x015e, 0x001e, 0x0498, 0x015e, 0x001e, 0x0016, 0x6028,
-	0xc09c, 0x602a, 0x080c, 0x98c7, 0x080c, 0x9b6c, 0x080c, 0x98e3,
-	0x60e3, 0x0000, 0x080c, 0xd644, 0x080c, 0xd65f, 0x080c, 0x53ac,
-	0xd0fc, 0x1138, 0x080c, 0xbf88, 0x1120, 0x9085, 0x0001, 0x080c,
-	0x7101, 0x9006, 0x080c, 0x2872, 0x2009, 0x0002, 0x080c, 0x285e,
-	0x00e6, 0x2071, 0x1800, 0x7003, 0x0004, 0x080c, 0x0ea9, 0x00ee,
-	0x2011, 0x0008, 0x080c, 0x28ac, 0x080c, 0x0bab, 0x001e, 0x918c,
-	0xffd0, 0x2110, 0x080c, 0x28ac, 0x00ae, 0x0005, 0x0006, 0x0016,
-	0x0026, 0x0036, 0x00e6, 0x00f6, 0x0126, 0x2091, 0x8000, 0x2071,
-	0x1800, 0x71cc, 0x70ce, 0x9116, 0x0904, 0x2451, 0x81ff, 0x01a0,
-	0x2009, 0x0000, 0x080c, 0x285e, 0x2011, 0x8011, 0x2019, 0x010e,
-	0x231c, 0x939e, 0x0007, 0x1118, 0x2019, 0x0001, 0x0010, 0x2019,
-	0x0000, 0x080c, 0x48fa, 0x0468, 0x2001, 0x1980, 0x200c, 0x81ff,
-	0x1140, 0x2001, 0x0109, 0x2004, 0xd0b4, 0x0118, 0x2019, 0x0003,
-	0x0008, 0x2118, 0x2011, 0x8012, 0x080c, 0x48fa, 0x080c, 0x0ea9,
-	0x080c, 0x53ac, 0xd0fc, 0x11a8, 0x080c, 0xbf88, 0x1190, 0x00c6,
-	0x080c, 0x24ed, 0x080c, 0x98c7, 0x080c, 0x91f8, 0x080c, 0x98e3,
-	0x2061, 0x0100, 0x2019, 0x0028, 0x2009, 0x0002, 0x080c, 0x2ff3,
-	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,
-	0x7d73, 0x0048, 0x9584, 0x00ff, 0x9080, 0x319f, 0x200d, 0x918c,
-	0xff00, 0x810f, 0x9006, 0x0005, 0x9080, 0x319f, 0x200d, 0x918c,
-	0x00ff, 0x0005, 0x00d6, 0x2069, 0x0140, 0x2001, 0x1817, 0x2003,
-	0x00ef, 0x20a9, 0x0010, 0x9006, 0x6852, 0x6856, 0x1f04, 0x249d,
-	0x00de, 0x0005, 0x0006, 0x00d6, 0x0026, 0x2069, 0x0140, 0x2001,
-	0x1817, 0x2102, 0x8114, 0x8214, 0x8214, 0x8214, 0x20a9, 0x0010,
-	0x6853, 0x0000, 0x9006, 0x82ff, 0x1128, 0x9184, 0x000f, 0x9080,
-	0xd673, 0x2005, 0x6856, 0x8211, 0x1f04, 0x24b2, 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, 0x24e2, 0x680f, 0x0000, 0x000e,
-	0x001e, 0x002e, 0x00de, 0x015e, 0x0005, 0x080c, 0x53a8, 0xd0c4,
-	0x0150, 0xd0a4, 0x0140, 0x9006, 0x0046, 0x2020, 0x2009, 0x002e,
-	0x080c, 0xd2bc, 0x004e, 0x0005, 0x00f6, 0x0016, 0x0026, 0x2079,
-	0x0140, 0x78c4, 0xd0dc, 0x0904, 0x2559, 0x080c, 0x27d5, 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, 0x842f, 0x928c, 0xff00, 0x0110, 0x2011, 0x00ff, 0x2200,
-	0x8007, 0x9085, 0x004c, 0x78c2, 0x2009, 0x0138, 0x220a, 0x080c,
-	0x70ba, 0x1118, 0x2009, 0x1945, 0x220a, 0x002e, 0x001e, 0x00fe,
-	0x0005, 0x78c3, 0x0000, 0x0cc8, 0x0126, 0x2091, 0x2800, 0x0006,
-	0x0016, 0x0026, 0x2001, 0x0170, 0x200c, 0x8000, 0x2014, 0x9184,
-	0x0003, 0x0110, 0x080c, 0x0d5e, 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,
-	0x0d65, 0x0033, 0x00ee, 0x002e, 0x001e, 0x000e, 0x015e, 0x0005,
-	0x25b7, 0x25d5, 0x25f9, 0x25fb, 0x2624, 0x2626, 0x2628, 0x2001,
-	0x0001, 0x080c, 0x23fe, 0x080c, 0x2823, 0x2001, 0x196a, 0x2003,
-	0x0000, 0x7828, 0x9084, 0xe1d7, 0x782a, 0x9006, 0x20a9, 0x0009,
-	0x080c, 0x27f1, 0x2001, 0x1968, 0x2003, 0x0006, 0x2009, 0x001e,
-	0x2011, 0x2629, 0x080c, 0x8230, 0x0005, 0x2009, 0x196d, 0x200b,
-	0x0000, 0x2001, 0x1972, 0x2003, 0x0036, 0x2001, 0x1971, 0x2003,
-	0x002a, 0x2001, 0x196a, 0x2003, 0x0001, 0x9006, 0x080c, 0x2786,
-	0x2001, 0xffff, 0x20a9, 0x0009, 0x080c, 0x27f1, 0x2001, 0x1968,
-	0x2003, 0x0006, 0x2009, 0x001e, 0x2011, 0x2629, 0x080c, 0x8230,
-	0x0005, 0x080c, 0x0d65, 0x2001, 0x1972, 0x2003, 0x0036, 0x2001,
-	0x196a, 0x2003, 0x0003, 0x7a38, 0x9294, 0x0005, 0x9296, 0x0004,
-	0x0110, 0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x2786, 0x2001,
-	0x196e, 0x2003, 0x0000, 0x2001, 0xffff, 0x20a9, 0x0009, 0x080c,
-	0x27f1, 0x2001, 0x1968, 0x2003, 0x0006, 0x2009, 0x001e, 0x2011,
-	0x2629, 0x080c, 0x8230, 0x0005, 0x080c, 0x0d65, 0x080c, 0x0d65,
-	0x0005, 0x0006, 0x0016, 0x0026, 0x00e6, 0x00f6, 0x0156, 0x0126,
-	0x2091, 0x8000, 0x2079, 0x0100, 0x2001, 0x196a, 0x2004, 0x908a,
-	0x0007, 0x1a0c, 0x0d65, 0x0043, 0x012e, 0x015e, 0x00fe, 0x00ee,
-	0x002e, 0x001e, 0x000e, 0x0005, 0x264b, 0x266b, 0x26ab, 0x26db,
-	0x26ff, 0x270f, 0x2711, 0x080c, 0x27e5, 0x11b0, 0x7850, 0x9084,
-	0xefff, 0x7852, 0x2009, 0x1970, 0x2104, 0x7a38, 0x9294, 0x0005,
-	0x9296, 0x0004, 0x0110, 0xc08d, 0x0008, 0xc085, 0x200a, 0x2001,
-	0x1968, 0x2003, 0x0001, 0x0030, 0x080c, 0x2735, 0x2001, 0xffff,
-	0x080c, 0x25c6, 0x0005, 0x080c, 0x2713, 0x05e0, 0x2009, 0x1971,
-	0x2104, 0x8001, 0x200a, 0x080c, 0x27e5, 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, 0x271b, 0x00c0,
-	0x200b, 0x0000, 0x7a38, 0x9294, 0x0006, 0x9296, 0x0004, 0x0110,
-	0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x27a3, 0x2001, 0x196a,
-	0x2003, 0x0002, 0x0028, 0x2001, 0x1968, 0x2003, 0x0003, 0x0010,
-	0x080c, 0x25e8, 0x0005, 0x080c, 0x2713, 0x0560, 0x2009, 0x1971,
-	0x2104, 0x8001, 0x200a, 0x080c, 0x27e5, 0x1168, 0x7850, 0x9084,
-	0xefff, 0x7852, 0x2001, 0x1968, 0x2003, 0x0003, 0x2001, 0x1969,
-	0x2003, 0x0000, 0x00b8, 0x2009, 0x1971, 0x2104, 0x9005, 0x1118,
-	0x080c, 0x2758, 0x0010, 0x080c, 0x2728, 0x080c, 0x271b, 0x2009,
-	0x196d, 0x200b, 0x0000, 0x2001, 0x196a, 0x2003, 0x0001, 0x080c,
-	0x25e8, 0x0000, 0x0005, 0x04b9, 0x0508, 0x080c, 0x27e5, 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, 0x2613, 0x0005, 0x0099,
-	0x0168, 0x080c, 0x27e5, 0x1138, 0x7850, 0x9084, 0xefff, 0x7852,
-	0x080c, 0x25ff, 0x0018, 0x0079, 0x080c, 0x2613, 0x0005, 0x080c,
-	0x0d65, 0x080c, 0x0d65, 0x2009, 0x1972, 0x2104, 0x8001, 0x200a,
-	0x090c, 0x2774, 0x0005, 0x7a38, 0x9294, 0x0005, 0x9296, 0x0005,
-	0x0110, 0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x27a3, 0x0005,
-	0x7a38, 0x9294, 0x0006, 0x9296, 0x0006, 0x0110, 0x9006, 0x0010,
-	0x2001, 0x0001, 0x080c, 0x2786, 0x0005, 0x2009, 0x196d, 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, 0x27a3, 0x0005,
-	0x0086, 0x2001, 0x1970, 0x2004, 0x9084, 0x7fff, 0x090c, 0x0d65,
-	0x2009, 0x196f, 0x2144, 0x8846, 0x280a, 0x9844, 0x0dd8, 0xd08c,
-	0x1120, 0xd084, 0x1120, 0x080c, 0x0d65, 0x9006, 0x0010, 0x2001,
-	0x0001, 0x00a1, 0x008e, 0x0005, 0x0006, 0x0156, 0x2001, 0x1968,
-	0x20a9, 0x0009, 0x2003, 0x0000, 0x8000, 0x1f04, 0x277a, 0x2001,
-	0x196f, 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, 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, 0x2858, 0xd09c, 0x1110, 0x1f04, 0x27e8, 0x015e,
-	0x0005, 0x0126, 0x0016, 0x0006, 0x2091, 0x8000, 0x080c, 0x28cf,
-	0x080c, 0x2902, 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, 0x2815, 0x080c,
-	0x8252, 0x1f04, 0x2815, 0x7850, 0x9085, 0x1000, 0x7852, 0x000e,
-	0x001e, 0x012e, 0x0005, 0x080c, 0x2902, 0x0005, 0x0006, 0x0156,
-	0x00f6, 0x2079, 0x0100, 0x20a9, 0x000a, 0x7854, 0xd0ac, 0x1100,
-	0x7854, 0xd08c, 0x1110, 0x1f04, 0x2830, 0x00fe, 0x015e, 0x000e,
-	0x0005, 0x1d04, 0x2839, 0x080c, 0x8252, 0x1f04, 0x2839, 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,
-	0xa001, 0xa001, 0xa001, 0xa001, 0xa001, 0x0005, 0x0006, 0x2001,
-	0x1980, 0x2102, 0x000e, 0x0005, 0x2009, 0x0171, 0x2104, 0xd0dc,
-	0x0140, 0x2009, 0x0170, 0x2104, 0x200b, 0x0080, 0xa001, 0xa001,
-	0x200a, 0x0005, 0x0016, 0x0026, 0x080c, 0x70d4, 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, 0x70d4, 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, 0x2839, 0x6050,
-	0x9085, 0x0400, 0x9084, 0xff9f, 0x6052, 0x20a9, 0x0005, 0x080c,
-	0x2839, 0x6054, 0xd0bc, 0x090c, 0x0d65, 0x20a9, 0x0005, 0x080c,
-	0x2839, 0x6054, 0xd0ac, 0x090c, 0x0d65, 0x2009, 0x1987, 0x9084,
-	0x7e00, 0x8007, 0x8004, 0x8004, 0x200a, 0x00ce, 0x003e, 0x002e,
-	0x001e, 0x0005, 0x0006, 0x00c6, 0x2061, 0x0100, 0x6050, 0xc0cd,
-	0x6052, 0x00ce, 0x000e, 0x0005, 0x2e08, 0x2e08, 0x2a0c, 0x2a0c,
-	0x2a18, 0x2a18, 0x2a24, 0x2a24, 0x2a32, 0x2a32, 0x2a3e, 0x2a3e,
-	0x2a4c, 0x2a4c, 0x2a5a, 0x2a5a, 0x2a6c, 0x2a6c, 0x2a78, 0x2a78,
-	0x2a86, 0x2a86, 0x2aa4, 0x2aa4, 0x2ac4, 0x2ac4, 0x2a94, 0x2a94,
-	0x2ab4, 0x2ab4, 0x2ad2, 0x2ad2, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a,
-	0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a,
-	0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a,
-	0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a,
-	0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2ae4, 0x2ae4, 0x2af0, 0x2af0,
-	0x2afe, 0x2afe, 0x2b0c, 0x2b0c, 0x2b1c, 0x2b1c, 0x2b2a, 0x2b2a,
-	0x2b3a, 0x2b3a, 0x2b4a, 0x2b4a, 0x2b5c, 0x2b5c, 0x2b6a, 0x2b6a,
-	0x2b7a, 0x2b7a, 0x2b9c, 0x2b9c, 0x2bc0, 0x2bc0, 0x2b8a, 0x2b8a,
-	0x2bae, 0x2bae, 0x2bd0, 0x2bd0, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a,
-	0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a,
-	0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a,
-	0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a,
-	0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2be4, 0x2be4, 0x2bf0, 0x2bf0,
-	0x2bfe, 0x2bfe, 0x2c0c, 0x2c0c, 0x2c1c, 0x2c1c, 0x2c2a, 0x2c2a,
-	0x2c3a, 0x2c3a, 0x2c4a, 0x2c4a, 0x2c5c, 0x2c5c, 0x2c6a, 0x2c6a,
-	0x2c7a, 0x2c7a, 0x2c8a, 0x2c8a, 0x2c9c, 0x2c9c, 0x2cac, 0x2cac,
-	0x2cbe, 0x2cbe, 0x2cd0, 0x2cd0, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a,
-	0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a,
-	0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a,
-	0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a,
-	0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2ce4, 0x2ce4, 0x2cf2, 0x2cf2,
-	0x2d02, 0x2d02, 0x2d12, 0x2d12, 0x2d24, 0x2d24, 0x2d34, 0x2d34,
-	0x2d46, 0x2d46, 0x2d58, 0x2d58, 0x2d6c, 0x2d6c, 0x2d7c, 0x2d7c,
-	0x2d8e, 0x2d8e, 0x2da0, 0x2da0, 0x2db4, 0x2db4, 0x2dc5, 0x2dc5,
-	0x2dd8, 0x2dd8, 0x2deb, 0x2deb, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a,
-	0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a,
-	0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a,
-	0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a,
-	0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2117, 0x0804, 0x2e00,
-	0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156,
-	0x080c, 0x1f45, 0x0804, 0x2e00, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x1f45, 0x080c, 0x2117,
-	0x0804, 0x2e00, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
-	0x0146, 0x0156, 0x080c, 0x1f6f, 0x0804, 0x2e00, 0x0106, 0x0006,
-	0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2117,
-	0x080c, 0x1f6f, 0x0804, 0x2e00, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x1f45, 0x080c, 0x1f6f,
-	0x0804, 0x2e00, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
-	0x0146, 0x0156, 0x080c, 0x1f45, 0x080c, 0x2117, 0x080c, 0x1f6f,
-	0x0804, 0x2e00, 0xa001, 0x0cf0, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x1342, 0x0804, 0x2e00,
-	0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156,
-	0x080c, 0x2117, 0x080c, 0x1342, 0x0804, 0x2e00, 0x0106, 0x0006,
-	0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x1f45,
-	0x080c, 0x1342, 0x0804, 0x2e00, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2117, 0x080c, 0x1342,
-	0x080c, 0x1f6f, 0x0804, 0x2e00, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x1f45, 0x080c, 0x2117,
-	0x080c, 0x1342, 0x0804, 0x2e00, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x1f45, 0x080c, 0x1342,
-	0x080c, 0x1f6f, 0x0804, 0x2e00, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x1342, 0x080c, 0x1f6f,
-	0x0804, 0x2e00, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
-	0x0146, 0x0156, 0x080c, 0x1f45, 0x080c, 0x2117, 0x080c, 0x1342,
-	0x080c, 0x1f6f, 0x0804, 0x2e00, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x255c, 0x0804, 0x2e00,
-	0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156,
-	0x080c, 0x255c, 0x080c, 0x2117, 0x0804, 0x2e00, 0x0106, 0x0006,
-	0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x255c,
-	0x080c, 0x1f45, 0x0804, 0x2e00, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x255c, 0x080c, 0x1f45,
-	0x080c, 0x2117, 0x0804, 0x2e00, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x255c, 0x080c, 0x1f6f,
-	0x0804, 0x2e00, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
-	0x0146, 0x0156, 0x080c, 0x255c, 0x080c, 0x2117, 0x080c, 0x1f6f,
-	0x0804, 0x2e00, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
-	0x0146, 0x0156, 0x080c, 0x255c, 0x080c, 0x1f45, 0x080c, 0x1f6f,
-	0x0804, 0x2e00, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
-	0x0146, 0x0156, 0x080c, 0x255c, 0x080c, 0x1f45, 0x080c, 0x2117,
-	0x080c, 0x1f6f, 0x0804, 0x2e00, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x255c, 0x080c, 0x1342,
-	0x0804, 0x2e00, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
-	0x0146, 0x0156, 0x080c, 0x255c, 0x080c, 0x2117, 0x080c, 0x1342,
-	0x0804, 0x2e00, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
-	0x0146, 0x0156, 0x080c, 0x255c, 0x080c, 0x1f45, 0x080c, 0x1342,
-	0x0804, 0x2e00, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
-	0x0146, 0x0156, 0x080c, 0x255c, 0x080c, 0x2117, 0x080c, 0x1342,
-	0x080c, 0x1f6f, 0x0804, 0x2e00, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x255c, 0x080c, 0x1f45,
-	0x080c, 0x2117, 0x080c, 0x1342, 0x0804, 0x2e00, 0x0106, 0x0006,
-	0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x255c,
-	0x080c, 0x1f45, 0x080c, 0x1342, 0x080c, 0x1f6f, 0x0804, 0x2e00,
-	0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156,
-	0x080c, 0x255c, 0x080c, 0x1342, 0x080c, 0x1f6f, 0x0804, 0x2e00,
-	0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156,
-	0x080c, 0x255c, 0x080c, 0x1f45, 0x080c, 0x2117, 0x080c, 0x1342,
-	0x080c, 0x1f6f, 0x0804, 0x2e00, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x992d, 0x0804, 0x2e00,
-	0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156,
-	0x080c, 0x992d, 0x080c, 0x2117, 0x0804, 0x2e00, 0x0106, 0x0006,
-	0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x1f45,
-	0x080c, 0x992d, 0x0804, 0x2e00, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x1f45, 0x080c, 0x992d,
-	0x080c, 0x2117, 0x0804, 0x2e00, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x992d, 0x080c, 0x1f6f,
-	0x0804, 0x2e00, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
-	0x0146, 0x0156, 0x080c, 0x992d, 0x080c, 0x2117, 0x080c, 0x1f6f,
-	0x0804, 0x2e00, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
-	0x0146, 0x0156, 0x080c, 0x1f45, 0x080c, 0x992d, 0x080c, 0x1f6f,
-	0x0804, 0x2e00, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
-	0x0146, 0x0156, 0x080c, 0x1f45, 0x080c, 0x992d, 0x080c, 0x2117,
-	0x080c, 0x1f6f, 0x0804, 0x2e00, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x992d, 0x080c, 0x1342,
-	0x0804, 0x2e00, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
-	0x0146, 0x0156, 0x080c, 0x992d, 0x080c, 0x2117, 0x080c, 0x1342,
-	0x0804, 0x2e00, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
-	0x0146, 0x0156, 0x080c, 0x1f45, 0x080c, 0x992d, 0x080c, 0x1342,
-	0x0804, 0x2e00, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
-	0x0146, 0x0156, 0x080c, 0x1f45, 0x080c, 0x992d, 0x080c, 0x2117,
-	0x080c, 0x1342, 0x0804, 0x2e00, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x992d, 0x080c, 0x1342,
-	0x080c, 0x1f6f, 0x0804, 0x2e00, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x992d, 0x080c, 0x2117,
-	0x080c, 0x1342, 0x080c, 0x1f6f, 0x0804, 0x2e00, 0x0106, 0x0006,
-	0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x1f45,
-	0x080c, 0x992d, 0x080c, 0x1342, 0x080c, 0x1f6f, 0x0804, 0x2e00,
-	0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156,
-	0x080c, 0x1f45, 0x080c, 0x992d, 0x080c, 0x2117, 0x080c, 0x1342,
-	0x080c, 0x1f6f, 0x0804, 0x2e00, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x255c, 0x080c, 0x992d,
-	0x0804, 0x2e00, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
-	0x0146, 0x0156, 0x080c, 0x255c, 0x080c, 0x992d, 0x080c, 0x2117,
-	0x0804, 0x2e00, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
-	0x0146, 0x0156, 0x080c, 0x255c, 0x080c, 0x1f45, 0x080c, 0x992d,
-	0x0804, 0x2e00, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
-	0x0146, 0x0156, 0x080c, 0x255c, 0x080c, 0x1f45, 0x080c, 0x992d,
-	0x080c, 0x2117, 0x0804, 0x2e00, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x255c, 0x080c, 0x992d,
-	0x080c, 0x1f6f, 0x0804, 0x2e00, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x255c, 0x080c, 0x992d,
-	0x080c, 0x2117, 0x080c, 0x1f6f, 0x0804, 0x2e00, 0x0106, 0x0006,
-	0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x255c,
-	0x080c, 0x1f45, 0x080c, 0x992d, 0x080c, 0x1f6f, 0x0804, 0x2e00,
-	0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156,
-	0x080c, 0x255c, 0x080c, 0x1f45, 0x080c, 0x992d, 0x080c, 0x2117,
-	0x080c, 0x1f6f, 0x0804, 0x2e00, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x255c, 0x080c, 0x992d,
-	0x080c, 0x1342, 0x0804, 0x2e00, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x255c, 0x080c, 0x992d,
-	0x080c, 0x2117, 0x080c, 0x1342, 0x0804, 0x2e00, 0x0106, 0x0006,
-	0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x255c,
-	0x080c, 0x1f45, 0x080c, 0x992d, 0x080c, 0x1342, 0x0804, 0x2e00,
-	0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156,
-	0x080c, 0x255c, 0x080c, 0x1f45, 0x080c, 0x992d, 0x080c, 0x2117,
-	0x080c, 0x1342, 0x0804, 0x2e00, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x255c, 0x080c, 0x992d,
-	0x080c, 0x1342, 0x080c, 0x1f6f, 0x04d8, 0x0106, 0x0006, 0x0126,
-	0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x255c, 0x080c,
-	0x992d, 0x080c, 0x2117, 0x080c, 0x1342, 0x080c, 0x1f6f, 0x0440,
-	0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156,
-	0x080c, 0x255c, 0x080c, 0x1f45, 0x080c, 0x1342, 0x080c, 0x992d,
-	0x080c, 0x1f6f, 0x00a8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
-	0x0136, 0x0146, 0x0156, 0x080c, 0x255c, 0x080c, 0x1f45, 0x080c,
-	0x992d, 0x080c, 0x2117, 0x080c, 0x1342, 0x080c, 0x1f6f, 0x0000,
-	0x015e, 0x014e, 0x013e, 0x01de, 0x01ce, 0x012e, 0x000e, 0x010e,
-	0x000d, 0x00b6, 0x00c6, 0x0026, 0x0046, 0x9026, 0x080c, 0x6648,
-	0x1904, 0x2f0f, 0x72d8, 0x2001, 0x1954, 0x2004, 0x9005, 0x1110,
-	0xd29c, 0x0148, 0xd284, 0x1138, 0xd2bc, 0x1904, 0x2f0f, 0x080c,
-	0x2f14, 0x0804, 0x2f0f, 0xd2cc, 0x1904, 0x2f0f, 0x080c, 0x70ba,
-	0x1120, 0x70ab, 0xffff, 0x0804, 0x2f0f, 0xd294, 0x0120, 0x70ab,
-	0xffff, 0x0804, 0x2f0f, 0x080c, 0x3195, 0x0160, 0x080c, 0xbf8f,
-	0x0128, 0x2001, 0x1817, 0x203c, 0x0804, 0x2ea1, 0x70ab, 0xffff,
-	0x0804, 0x2f0f, 0x2001, 0x1817, 0x203c, 0x7290, 0xd284, 0x0904,
-	0x2ea1, 0xd28c, 0x1904, 0x2ea1, 0x0036, 0x73a8, 0x938e, 0xffff,
-	0x1110, 0x2019, 0x0001, 0x8314, 0x92e0, 0x1d80, 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, 0x66ae, 0x002e,
-	0x0118, 0x70ab, 0xffff, 0x0410, 0x900e, 0x080c, 0x2459, 0x080c,
-	0x622f, 0x11c0, 0x080c, 0x668a, 0x1168, 0x7030, 0xd08c, 0x0130,
-	0xb800, 0xd0bc, 0x0138, 0x080c, 0x6582, 0x0120, 0x080c, 0x2f2d,
-	0x0148, 0x0028, 0x080c, 0x3079, 0x080c, 0x2f59, 0x0118, 0x8318,
-	0x0804, 0x2e53, 0x73aa, 0x0010, 0x70ab, 0xffff, 0x003e, 0x0804,
-	0x2f0f, 0x9780, 0x319f, 0x203d, 0x97bc, 0xff00, 0x873f, 0x2041,
-	0x007e, 0x70a8, 0x9096, 0xffff, 0x1118, 0x900e, 0x28a8, 0x0050,
-	0x9812, 0x0220, 0x2008, 0x9802, 0x20a8, 0x0020, 0x70ab, 0xffff,
-	0x0804, 0x2f0f, 0x2700, 0x0156, 0x0016, 0x9106, 0x0904, 0x2f04,
-	0x0026, 0x2011, 0x0010, 0x080c, 0x66ae, 0x002e, 0x0120, 0x2009,
-	0xffff, 0x0804, 0x2f0c, 0xc484, 0x080c, 0x628f, 0x0138, 0x080c,
-	0xbf8f, 0x1590, 0x080c, 0x622f, 0x15b8, 0x0008, 0xc485, 0x080c,
-	0x668a, 0x1130, 0x7030, 0xd08c, 0x01f8, 0xb800, 0xd0bc, 0x11e0,
-	0x7290, 0xd28c, 0x0180, 0x080c, 0x668a, 0x9082, 0x0006, 0x02e0,
-	0xd484, 0x1118, 0x080c, 0x6253, 0x0028, 0x080c, 0x310b, 0x01a0,
-	0x080c, 0x3136, 0x0088, 0x080c, 0x3079, 0x080c, 0xbf8f, 0x1160,
-	0x080c, 0x2f59, 0x0188, 0x0040, 0x080c, 0xbf8f, 0x1118, 0x080c,
-	0x310b, 0x0110, 0x0451, 0x0140, 0x001e, 0x8108, 0x015e, 0x1f04,
-	0x2eba, 0x70ab, 0xffff, 0x0018, 0x001e, 0x015e, 0x71aa, 0x004e,
-	0x002e, 0x00ce, 0x00be, 0x0005, 0x00c6, 0x0016, 0x70ab, 0x0001,
-	0x2009, 0x007e, 0x080c, 0x622f, 0x1168, 0xb813, 0x00ff, 0xb817,
-	0xfffe, 0x080c, 0x3079, 0x04a9, 0x0128, 0x70d8, 0xc0bd, 0x70da,
-	0x080c, 0xbcdc, 0x001e, 0x00ce, 0x0005, 0x0016, 0x0076, 0x00d6,
-	0x00c6, 0x2001, 0x1860, 0x2004, 0x9084, 0x00ff, 0xb842, 0x080c,
-	0x9c55, 0x01d0, 0x2b00, 0x6012, 0x080c, 0xbd09, 0x6023, 0x0001,
-	0x9006, 0x080c, 0x61cc, 0x2001, 0x0000, 0x080c, 0x61e0, 0x0126,
-	0x2091, 0x8000, 0x70a4, 0x8000, 0x70a6, 0x012e, 0x2009, 0x0004,
-	0x080c, 0x9c82, 0x9085, 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e,
-	0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6, 0x2001, 0x1860, 0x2004,
-	0x9084, 0x00ff, 0xb842, 0x080c, 0x9c55, 0x0548, 0x2b00, 0x6012,
-	0xb800, 0xc0c4, 0xb802, 0xb8a0, 0x9086, 0x007e, 0x0140, 0xb804,
-	0x9084, 0x00ff, 0x9086, 0x0006, 0x1110, 0x080c, 0x302e, 0x080c,
-	0xbd09, 0x6023, 0x0001, 0x9006, 0x080c, 0x61cc, 0x2001, 0x0002,
-	0x080c, 0x61e0, 0x0126, 0x2091, 0x8000, 0x70a4, 0x8000, 0x70a6,
-	0x012e, 0x2009, 0x0002, 0x080c, 0x9c82, 0x9085, 0x0001, 0x00ce,
-	0x00de, 0x007e, 0x001e, 0x0005, 0x00b6, 0x00c6, 0x0026, 0x2009,
-	0x0080, 0x080c, 0x622f, 0x1140, 0xb813, 0x00ff, 0xb817, 0xfffc,
-	0x0039, 0x0110, 0x70df, 0xffff, 0x002e, 0x00ce, 0x00be, 0x0005,
-	0x0016, 0x0076, 0x00d6, 0x00c6, 0x080c, 0x9b90, 0x01d0, 0x2b00,
-	0x6012, 0x080c, 0xbd09, 0x6023, 0x0001, 0x9006, 0x080c, 0x61cc,
-	0x2001, 0x0002, 0x080c, 0x61e0, 0x0126, 0x2091, 0x8000, 0x70e0,
-	0x8000, 0x70e2, 0x012e, 0x2009, 0x0002, 0x080c, 0x9c82, 0x9085,
-	0x0001, 0x00ce, 0x00de, 0x007e, 0x001e, 0x0005, 0x00c6, 0x00d6,
-	0x0126, 0x2091, 0x8000, 0x2009, 0x007f, 0x080c, 0x622f, 0x11b8,
-	0xb813, 0x00ff, 0xb817, 0xfffd, 0xb8c7, 0x0004, 0x080c, 0x9b90,
-	0x0170, 0x2b00, 0x6012, 0x6316, 0x6023, 0x0001, 0x620a, 0x080c,
-	0xbd09, 0x2009, 0x0022, 0x080c, 0x9c82, 0x9085, 0x0001, 0x012e,
-	0x00de, 0x00ce, 0x0005, 0x00e6, 0x00c6, 0x0066, 0x0036, 0x0026,
-	0x00b6, 0x21f0, 0x080c, 0x98c7, 0x0106, 0x080c, 0x8663, 0x080c,
-	0x85de, 0x080c, 0x9818, 0x080c, 0xab55, 0x010e, 0x090c, 0x98e3,
-	0x3e08, 0x2130, 0x81ff, 0x0120, 0x20a9, 0x007e, 0x900e, 0x0018,
-	0x20a9, 0x007f, 0x900e, 0x0016, 0x080c, 0x628f, 0x1140, 0x9686,
-	0x0002, 0x1118, 0xb800, 0xd0bc, 0x1110, 0x080c, 0x5d11, 0x001e,
-	0x8108, 0x1f04, 0x3013, 0x9686, 0x0001, 0x190c, 0x3169, 0x00be,
-	0x002e, 0x003e, 0x006e, 0x00ce, 0x00ee, 0x0005, 0x00e6, 0x00c6,
-	0x0046, 0x0036, 0x0026, 0x0016, 0x00b6, 0x080c, 0x98c7, 0x0106,
-	0x6210, 0x2258, 0xbaa0, 0x0026, 0x2019, 0x0029, 0x080c, 0x8658,
-	0x0076, 0x2039, 0x0000, 0x080c, 0x853d, 0x2c08, 0x080c, 0xd011,
-	0x007e, 0x001e, 0x010e, 0x090c, 0x98e3, 0xba10, 0xbb14, 0xbc84,
-	0x080c, 0x5d11, 0xba12, 0xbb16, 0xbc86, 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, 0x080c,
-	0x98c7, 0x0106, 0x81ff, 0x1118, 0x20a9, 0x0001, 0x0070, 0x080c,
-	0x53a8, 0xd0c4, 0x0138, 0x0030, 0x9006, 0x2020, 0x2009, 0x002d,
-	0x080c, 0xd2bc, 0x20a9, 0x0800, 0x9016, 0x0026, 0x928e, 0x007e,
-	0x0904, 0x30e7, 0x928e, 0x007f, 0x0904, 0x30e7, 0x928e, 0x0080,
-	0x05f0, 0x9288, 0x1000, 0x210c, 0x81ff, 0x05c8, 0x8fff, 0x1150,
-	0x2001, 0x1966, 0x0006, 0x2003, 0x0001, 0x080c, 0x30f8, 0x000e,
-	0x2003, 0x0000, 0x00b6, 0x00c6, 0x2158, 0x2001, 0x0001, 0x080c,
-	0x6654, 0x00ce, 0x00be, 0x2019, 0x0029, 0x080c, 0x8658, 0x0076,
-	0x2039, 0x0000, 0x080c, 0x853d, 0x00b6, 0x00c6, 0x0026, 0x2158,
-	0xba04, 0x9294, 0x00ff, 0x9286, 0x0006, 0x1118, 0xb807, 0x0404,
-	0x0028, 0x2001, 0x0004, 0x8007, 0x9215, 0xba06, 0x002e, 0x00ce,
-	0x00be, 0x0016, 0x2c08, 0x080c, 0xd011, 0x001e, 0x007e, 0x002e,
-	0x8210, 0x1f04, 0x309d, 0x010e, 0x090c, 0x98e3, 0x015e, 0x001e,
-	0x002e, 0x003e, 0x004e, 0x00be, 0x00ce, 0x00ee, 0x00fe, 0x0005,
-	0x0046, 0x0026, 0x0016, 0x080c, 0x53a8, 0xd0c4, 0x0140, 0xd0a4,
-	0x0130, 0x9006, 0x2220, 0x2009, 0x0029, 0x080c, 0xd2bc, 0x001e,
-	0x002e, 0x004e, 0x0005, 0x0016, 0x0026, 0x0036, 0x00c6, 0x7290,
-	0x82ff, 0x01e8, 0x080c, 0x6682, 0x11d0, 0x2100, 0x080c, 0x248c,
-	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, 0x98c7, 0x0106, 0x0036, 0x2019,
-	0x0029, 0x00c1, 0x003e, 0x010e, 0x090c, 0x98e3, 0x9180, 0x1000,
-	0x2004, 0x9065, 0x0158, 0x0016, 0x00c6, 0x2061, 0x1b09, 0x001e,
-	0x6112, 0x080c, 0x302e, 0x001e, 0x080c, 0x6253, 0x012e, 0x00ce,
-	0x001e, 0x0005, 0x0016, 0x0026, 0x2110, 0x080c, 0x94e5, 0x080c,
-	0xd572, 0x002e, 0x001e, 0x0005, 0x2001, 0x1836, 0x2004, 0xd0cc,
-	0x0005, 0x00c6, 0x00b6, 0x080c, 0x70ba, 0x1118, 0x20a9, 0x0800,
-	0x0010, 0x20a9, 0x0782, 0x080c, 0x70ba, 0x1110, 0x900e, 0x0010,
-	0x2009, 0x007e, 0x9180, 0x1000, 0x2004, 0x905d, 0x0130, 0x86ff,
-	0x0110, 0xb800, 0xd0bc, 0x090c, 0x6253, 0x8108, 0x1f04, 0x317a,
-	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, 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, 0x2071,
-	0x189c, 0x7003, 0x0002, 0x9006, 0x7016, 0x701a, 0x704a, 0x704e,
-	0x700e, 0x7042, 0x7046, 0x703b, 0x18b8, 0x703f, 0x18b8, 0x7007,
-	0x0001, 0x080c, 0x1048, 0x090c, 0x0d65, 0x2900, 0x706a, 0xa867,
-	0x0002, 0xa8ab, 0xdcb0, 0x080c, 0x1048, 0x090c, 0x0d65, 0x2900,
-	0x706e, 0xa867, 0x0002, 0xa8ab, 0xdcb0, 0x0005, 0x2071, 0x189c,
-	0x7004, 0x0002, 0x32ce, 0x32cf, 0x32e2, 0x32f6, 0x0005, 0x1004,
-	0x32df, 0x0e04, 0x32df, 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, 0x33ca, 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,
-	0x33c7, 0x61cc, 0x0804, 0x335c, 0x339e, 0x33d6, 0x33c7, 0x33e0,
-	0x33ea, 0x33f0, 0x33f4, 0x3404, 0x3408, 0x341e, 0x3424, 0x342a,
-	0x3435, 0x3440, 0x344f, 0x345e, 0x346c, 0x3483, 0x349e, 0x33c7,
-	0x3547, 0x3585, 0x362a, 0x363b, 0x365e, 0x33c7, 0x33c7, 0x33c7,
-	0x3696, 0x36b6, 0x36bf, 0x36eb, 0x36f1, 0x33c7, 0x3737, 0x33c7,
-	0x33c7, 0x33c7, 0x33c7, 0x33c7, 0x3742, 0x374b, 0x3753, 0x3755,
-	0x33c7, 0x33c7, 0x33c7, 0x33c7, 0x33c7, 0x33c7, 0x3785, 0x33c7,
-	0x33c7, 0x33c7, 0x33c7, 0x33c7, 0x37a2, 0x37fd, 0x33c7, 0x33c7,
-	0x33c7, 0x33c7, 0x33c7, 0x33c7, 0x0002, 0x3827, 0x382a, 0x3889,
-	0x38a2, 0x38d2, 0x3b74, 0x33c7, 0x4f79, 0x33c7, 0x33c7, 0x33c7,
-	0x33c7, 0x33c7, 0x33c7, 0x33c7, 0x33c7, 0x341e, 0x3424, 0x4073,
-	0x53cc, 0x4089, 0x5008, 0x5059, 0x515c, 0x33c7, 0x51be, 0x51fa,
-	0x522b, 0x5337, 0x5258, 0x52b7, 0x33c7, 0x408d, 0x421d, 0x4233,
-	0x4258, 0x42bd, 0x4331, 0x4351, 0x43c8, 0x4424, 0x4480, 0x4483,
-	0x44a8, 0x451b, 0x4585, 0x458d, 0x46bf, 0x4824, 0x4858, 0x4aa2,
-	0x33c7, 0x4ac0, 0x4b7c, 0x4c52, 0x33c7, 0x33c7, 0x33c7, 0x33c7,
-	0x4cb8, 0x4cd3, 0x458d, 0x4f19, 0x714c, 0x0000, 0x2021, 0x4000,
-	0x080c, 0x48d6, 0x0126, 0x2091, 0x8000, 0x0e04, 0x33a8, 0x0010,
-	0x012e, 0x0cc0, 0x7c36, 0x9486, 0x4000, 0x0118, 0x7833, 0x0011,
-	0x0010, 0x7833, 0x0010, 0x7c82, 0x7986, 0x7a8a, 0x7b8e, 0x2091,
-	0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11d6, 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, 0x48e3,
-	0x2039, 0x0001, 0x902e, 0x2520, 0x7b88, 0x7a8c, 0x7884, 0x7990,
-	0x0804, 0x48e6, 0x7984, 0x7888, 0x2114, 0x200a, 0x0804, 0x339e,
-	0x7984, 0x2114, 0x0804, 0x339e, 0x20e1, 0x0000, 0x2099, 0x0021,
-	0x20e9, 0x0000, 0x20a1, 0x0021, 0x20a9, 0x001f, 0x4003, 0x7984,
-	0x7a88, 0x7b8c, 0x0804, 0x339e, 0x7884, 0x2060, 0x0804, 0x3451,
-	0x2009, 0x0003, 0x2011, 0x0003, 0x2019, 0x0002, 0x789b, 0x0317,
-	0x7893, 0xffff, 0x2001, 0x188d, 0x2004, 0x9005, 0x0118, 0x7896,
-	0x0804, 0x339e, 0x7897, 0x0001, 0x0804, 0x339e, 0x2039, 0x0001,
-	0x7d98, 0x7c9c, 0x0804, 0x33da, 0x2039, 0x0001, 0x7d98, 0x7c9c,
-	0x0804, 0x33e4, 0x79a0, 0x9182, 0x0040, 0x0210, 0x0804, 0x33d3,
-	0x2138, 0x7d98, 0x7c9c, 0x0804, 0x33da, 0x79a0, 0x9182, 0x0040,
-	0x0210, 0x0804, 0x33d3, 0x2138, 0x7d98, 0x7c9c, 0x0804, 0x33e4,
-	0x79a0, 0x9182, 0x0040, 0x0210, 0x0804, 0x33d3, 0x21e8, 0x7984,
-	0x7888, 0x20a9, 0x0001, 0x21a0, 0x4004, 0x0804, 0x339e, 0x2061,
-	0x0800, 0xe10c, 0x9006, 0x2c15, 0x9200, 0x8c60, 0x8109, 0x1dd8,
-	0x2010, 0x9005, 0x0904, 0x339e, 0x0804, 0x33cd, 0x79a0, 0x9182,
-	0x0040, 0x0210, 0x0804, 0x33d3, 0x21e0, 0x20a9, 0x0001, 0x7984,
-	0x2198, 0x4012, 0x0804, 0x339e, 0x2069, 0x185b, 0x7884, 0x7990,
-	0x911a, 0x1a04, 0x33d3, 0x8019, 0x0904, 0x33d3, 0x684a, 0x6942,
-	0x788c, 0x6852, 0x7888, 0x6856, 0x9006, 0x685a, 0x685e, 0x080c,
-	0x73ea, 0x0804, 0x339e, 0x2069, 0x185b, 0x7884, 0x7994, 0x911a,
-	0x1a04, 0x33d3, 0x8019, 0x0904, 0x33d3, 0x684e, 0x6946, 0x788c,
-	0x6862, 0x7888, 0x6866, 0x9006, 0x686a, 0x686e, 0x0126, 0x2091,
-	0x8000, 0x080c, 0x6788, 0x012e, 0x0804, 0x339e, 0x902e, 0x2520,
-	0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x33d0, 0x7984, 0x7b88,
-	0x7a8c, 0x20a9, 0x0005, 0x20e9, 0x0001, 0x20a1, 0x18a4, 0x4101,
-	0x080c, 0x489a, 0x1120, 0x2009, 0x0002, 0x0804, 0x33d0, 0x2009,
-	0x0020, 0xa85c, 0x9080, 0x0019, 0xaf60, 0x080c, 0x48e3, 0x701f,
-	0x34c2, 0x0005, 0xa864, 0x2008, 0x9084, 0x00ff, 0x9096, 0x0011,
-	0x0168, 0x9096, 0x0019, 0x0150, 0x9096, 0x0015, 0x0138, 0x9096,
-	0x0048, 0x0120, 0x9096, 0x0029, 0x1904, 0x33d0, 0x810f, 0x918c,
-	0x00ff, 0x0904, 0x33d0, 0x7112, 0x7010, 0x8001, 0x0560, 0x7012,
-	0x080c, 0x489a, 0x1120, 0x2009, 0x0002, 0x0804, 0x33d0, 0x2009,
-	0x0020, 0x7068, 0x2040, 0xa28c, 0xa390, 0xa494, 0xa598, 0x9290,
-	0x0040, 0x9399, 0x0000, 0x94a1, 0x0000, 0x95a9, 0x0000, 0xa85c,
-	0x9080, 0x0019, 0xaf60, 0x080c, 0x48e3, 0x701f, 0x3500, 0x0005,
-	0xa864, 0x9084, 0x00ff, 0x9096, 0x0002, 0x0120, 0x9096, 0x000a,
-	0x1904, 0x33d0, 0x0888, 0x7014, 0x2048, 0xa868, 0xc0fd, 0xa86a,
-	0xa864, 0x9084, 0x00ff, 0x9096, 0x0029, 0x1160, 0xc2fd, 0xaa7a,
-	0x080c, 0x5dff, 0x0150, 0x0126, 0x2091, 0x8000, 0xa87a, 0xa982,
-	0x012e, 0x0050, 0x080c, 0x611a, 0x1128, 0x7007, 0x0003, 0x701f,
-	0x352c, 0x0005, 0x080c, 0x6bc6, 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, 0x48e6, 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, 0x19fa, 0x2004, 0x9005, 0x0128, 0x2001, 0x008b,
-	0x2004, 0xd0fc, 0x0dd8, 0x2001, 0x008a, 0x2003, 0x0002, 0x2003,
-	0x1001, 0x2071, 0x0080, 0x0804, 0x0427, 0x81ff, 0x1904, 0x33d0,
-	0x7984, 0x080c, 0x628f, 0x1904, 0x33d3, 0x7e98, 0x9684, 0x3fff,
-	0x9082, 0x4000, 0x1a04, 0x33d3, 0x7c88, 0x7d8c, 0x080c, 0x64c5,
-	0x080c, 0x6452, 0x1518, 0x2061, 0x1ddc, 0x0126, 0x2091, 0x8000,
-	0x6000, 0x9086, 0x0000, 0x0148, 0x6014, 0x904d, 0x0130, 0xa86c,
-	0x9406, 0x1118, 0xa870, 0x9506, 0x0150, 0x012e, 0x9ce0, 0x001c,
-	0x2001, 0x1819, 0x2004, 0x9c02, 0x1a04, 0x33d0, 0x0c30, 0x080c,
-	0xb45e, 0x012e, 0x0904, 0x33d0, 0x0804, 0x339e, 0x900e, 0x2001,
-	0x0005, 0x080c, 0x6bc6, 0x0126, 0x2091, 0x8000, 0x080c, 0xbb79,
-	0x080c, 0x69b5, 0x012e, 0x0804, 0x339e, 0x00a6, 0x2950, 0xb198,
-	0x080c, 0x628f, 0x1904, 0x3617, 0xb6a4, 0x9684, 0x3fff, 0x9082,
-	0x4000, 0x16e8, 0xb49c, 0xb5a0, 0x080c, 0x64c5, 0x080c, 0x646f,
-	0x1520, 0x2061, 0x1ddc, 0x0126, 0x2091, 0x8000, 0x6000, 0x9086,
-	0x0000, 0x0148, 0x6014, 0x904d, 0x0130, 0xa86c, 0x9406, 0x1118,
-	0xa870, 0x9506, 0x0158, 0x012e, 0x9ce0, 0x001c, 0x2001, 0x1819,
-	0x2004, 0x9c02, 0x2009, 0x000d, 0x12b0, 0x0c28, 0x080c, 0xb45e,
-	0x012e, 0x2009, 0x0003, 0x0178, 0x00e0, 0x900e, 0x2001, 0x0005,
-	0x080c, 0x6bc6, 0x0126, 0x2091, 0x8000, 0x080c, 0xbb79, 0x080c,
-	0x69a9, 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, 0x33d0, 0x080c, 0x48b1, 0x0904,
-	0x33d3, 0x080c, 0x6356, 0x0904, 0x33d0, 0x080c, 0x64cb, 0x0904,
-	0x33d0, 0x0804, 0x4348, 0x81ff, 0x1904, 0x33d0, 0x080c, 0x48cd,
-	0x0904, 0x33d3, 0x080c, 0x6559, 0x0904, 0x33d0, 0x2019, 0x0005,
-	0x79a8, 0x080c, 0x64e6, 0x0904, 0x33d0, 0x7888, 0x908a, 0x1000,
-	0x1a04, 0x33d3, 0x8003, 0x800b, 0x810b, 0x9108, 0x080c, 0x817a,
-	0x7984, 0xd184, 0x1904, 0x339e, 0x0804, 0x4348, 0x0126, 0x2091,
-	0x8000, 0x81ff, 0x0118, 0x2009, 0x0001, 0x0450, 0x2029, 0x07ff,
-	0x6458, 0x2400, 0x9506, 0x01f8, 0x2508, 0x080c, 0x628f, 0x11d8,
-	0x080c, 0x6559, 0x1128, 0x2009, 0x0002, 0x62bc, 0x2518, 0x00c0,
-	0x2019, 0x0004, 0x900e, 0x080c, 0x64e6, 0x1118, 0x2009, 0x0006,
-	0x0078, 0x7884, 0x908a, 0x1000, 0x1270, 0x8003, 0x800b, 0x810b,
-	0x9108, 0x080c, 0x817a, 0x8529, 0x1ae0, 0x012e, 0x0804, 0x339e,
-	0x012e, 0x0804, 0x33d0, 0x012e, 0x0804, 0x33d3, 0x080c, 0x48b1,
-	0x0904, 0x33d3, 0x080c, 0x6356, 0x0904, 0x33d0, 0x080c, 0x98c7,
-	0xbaa0, 0x2019, 0x0005, 0x00c6, 0x9066, 0x080c, 0x8658, 0x0076,
-	0x903e, 0x080c, 0x853d, 0x900e, 0x080c, 0xd011, 0x007e, 0x00ce,
-	0x080c, 0x98e3, 0x080c, 0x64c5, 0x0804, 0x339e, 0x080c, 0x48b1,
-	0x0904, 0x33d3, 0x080c, 0x64c5, 0x2208, 0x0804, 0x339e, 0x0156,
-	0x00d6, 0x00e6, 0x00c6, 0x2069, 0x190e, 0x6810, 0x6914, 0x910a,
-	0x1208, 0x900e, 0x6816, 0x9016, 0x901e, 0x2071, 0x19bf, 0x7028,
-	0x9065, 0x0118, 0x8210, 0x600c, 0x0cd8, 0x2300, 0x9218, 0x00ce,
-	0x00ee, 0x00de, 0x015e, 0x0804, 0x339e, 0x00f6, 0x0016, 0x907d,
-	0x0138, 0x9006, 0x8000, 0x2f0c, 0x81ff, 0x0110, 0x2178, 0x0cd0,
-	0x001e, 0x00fe, 0x0005, 0x2069, 0x190e, 0x6910, 0x62b8, 0x0804,
-	0x339e, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x33d0, 0x0126,
-	0x2091, 0x8000, 0x080c, 0x53bc, 0x0128, 0x2009, 0x0007, 0x012e,
-	0x0804, 0x33d0, 0x012e, 0x6158, 0x9190, 0x319f, 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, 0x70ba,
-	0x1118, 0x2031, 0x0004, 0x0038, 0xd79c, 0x0120, 0x2009, 0x0005,
-	0x0804, 0x33d0, 0x9036, 0x7e9a, 0x7f9e, 0x0804, 0x339e, 0x6148,
-	0x624c, 0x2019, 0x195e, 0x231c, 0x2001, 0x195f, 0x2004, 0x789a,
-	0x0804, 0x339e, 0x0126, 0x2091, 0x8000, 0x6138, 0x623c, 0x6340,
-	0x012e, 0x0804, 0x339e, 0x080c, 0x48cd, 0x0904, 0x33d3, 0xba44,
-	0xbb38, 0x0804, 0x339e, 0x080c, 0x0d65, 0x080c, 0x48cd, 0x2110,
-	0x0904, 0x33d3, 0xb804, 0x908c, 0x00ff, 0x918e, 0x0006, 0x0140,
-	0x9084, 0xff00, 0x9086, 0x0600, 0x2009, 0x0009, 0x1904, 0x33d0,
-	0x0126, 0x2091, 0x8000, 0x2019, 0x0005, 0x00c6, 0x9066, 0x080c,
-	0x98c7, 0x080c, 0x94e5, 0x080c, 0x8658, 0x0076, 0x903e, 0x080c,
-	0x853d, 0x900e, 0x080c, 0xd011, 0x007e, 0x00ce, 0x080c, 0x98e3,
-	0xb807, 0x0407, 0x012e, 0x0804, 0x339e, 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, 0x339e, 0x0126, 0x2091, 0x8000, 0x6138, 0x7884, 0x603a,
-	0x910e, 0xd1b4, 0x190c, 0x0ec1, 0xd0c4, 0x01a8, 0x00d6, 0x78a8,
-	0x2009, 0x1975, 0x200a, 0x78ac, 0x2011, 0x1976, 0x2012, 0x2069,
-	0x0100, 0x6838, 0x9086, 0x0007, 0x1118, 0x2214, 0x6a5a, 0x0010,
-	0x210c, 0x695a, 0x00de, 0x7888, 0x603e, 0x2011, 0x0116, 0x220c,
-	0x7888, 0xd08c, 0x0118, 0x918d, 0x0040, 0x0010, 0x918c, 0xff7f,
-	0x2112, 0x6140, 0x788c, 0x6042, 0x910e, 0xd1e4, 0x190c, 0x0edc,
-	0x6040, 0xd0cc, 0x0120, 0x78b0, 0x2011, 0x0114, 0x2012, 0x012e,
-	0x0804, 0x339e, 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, 0x33d3, 0x788c, 0x902d, 0x0904, 0x33d3,
-	0x900e, 0x080c, 0x628f, 0x1120, 0xba44, 0xbb38, 0xbc46, 0xbd3a,
-	0x9186, 0x07ff, 0x0190, 0x8108, 0x0ca0, 0x080c, 0x48cd, 0x0904,
-	0x33d3, 0x7888, 0x900d, 0x0904, 0x33d3, 0x788c, 0x9005, 0x0904,
-	0x33d3, 0xba44, 0xb946, 0xbb38, 0xb83a, 0x0804, 0x339e, 0x2011,
-	0xbc09, 0x0010, 0x2011, 0xbc05, 0x080c, 0x53bc, 0x1904, 0x33d0,
-	0x00c6, 0x2061, 0x0100, 0x7984, 0x9186, 0x00ff, 0x1130, 0x2001,
-	0x1817, 0x2004, 0x9085, 0xff00, 0x0088, 0x9182, 0x007f, 0x16e0,
-	0x9188, 0x319f, 0x210d, 0x918c, 0x00ff, 0x2001, 0x1817, 0x2004,
-	0x0026, 0x9116, 0x002e, 0x0580, 0x810f, 0x9105, 0x0126, 0x2091,
-	0x8000, 0x0006, 0x080c, 0x9b90, 0x000e, 0x0510, 0x602e, 0x620a,
-	0x7984, 0x00b6, 0x080c, 0x6235, 0x2b08, 0x00be, 0x1500, 0x6112,
-	0x6023, 0x0001, 0x080c, 0x489a, 0x01d0, 0x9006, 0xa866, 0x7007,
-	0x0003, 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x701f, 0x3882, 0x2900,
-	0x6016, 0x2009, 0x0032, 0x080c, 0x9c82, 0x012e, 0x00ce, 0x0005,
-	0x012e, 0x00ce, 0x0804, 0x33d0, 0x00ce, 0x0804, 0x33d3, 0x080c,
-	0x9be6, 0x0cb0, 0xa830, 0x9086, 0x0100, 0x0904, 0x33d0, 0x0804,
-	0x339e, 0x2061, 0x1a46, 0x0126, 0x2091, 0x8000, 0x6000, 0xd084,
-	0x0170, 0x6104, 0x6208, 0x2061, 0x1800, 0x6350, 0x6070, 0x789a,
-	0x60bc, 0x789e, 0x60b8, 0x78aa, 0x012e, 0x0804, 0x339e, 0x900e,
-	0x2110, 0x0c88, 0x81ff, 0x1904, 0x33d0, 0x080c, 0x70ba, 0x0904,
-	0x33d0, 0x0126, 0x2091, 0x8000, 0x6250, 0x6070, 0x9202, 0x0248,
-	0x9085, 0x0001, 0x080c, 0x24c2, 0x080c, 0x55d6, 0x012e, 0x0804,
-	0x339e, 0x012e, 0x0804, 0x33d3, 0x0006, 0x0016, 0x00c6, 0x00e6,
-	0x2001, 0x1981, 0x2070, 0x2061, 0x185b, 0x6008, 0x2072, 0x900e,
-	0x2011, 0x1400, 0x080c, 0x842f, 0x7206, 0x00ee, 0x00ce, 0x001e,
-	0x000e, 0x0005, 0x0126, 0x2091, 0x8000, 0x81ff, 0x0128, 0x012e,
-	0x2021, 0x400b, 0x0804, 0x33a0, 0x7884, 0xd0fc, 0x0148, 0x2001,
-	0x002a, 0x2004, 0x9082, 0x00e1, 0x0288, 0x012e, 0x0804, 0x33d3,
-	0x2001, 0x002a, 0x2004, 0x2069, 0x185b, 0x6908, 0x9102, 0x1230,
-	0x012e, 0x0804, 0x33d3, 0x012e, 0x0804, 0x33d0, 0x080c, 0x9b65,
-	0x0dd0, 0x7884, 0xd0fc, 0x0904, 0x394d, 0x00c6, 0x080c, 0x489a,
-	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, 0x3ad7, 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, 0x48e3, 0x701f,
-	0x3a14, 0x7023, 0x0001, 0x012e, 0x0005, 0x080c, 0x98c7, 0x0046,
-	0x0086, 0x0096, 0x00a6, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6,
-	0x080c, 0x38bc, 0x2001, 0x1977, 0x2003, 0x0000, 0x2021, 0x000a,
-	0x2061, 0x0100, 0x6104, 0x0016, 0x60bb, 0x0000, 0x60bf, 0x32e1,
-	0x60bf, 0x0012, 0x080c, 0x3b46, 0x080c, 0x3b05, 0x00f6, 0x00e6,
-	0x0086, 0x2940, 0x2071, 0x19bf, 0x2079, 0x0090, 0x00d6, 0x2069,
-	0x0000, 0x6884, 0xd0b4, 0x0140, 0x2001, 0x0035, 0x2004, 0x780e,
-	0x2001, 0x0034, 0x2004, 0x780a, 0x00de, 0x2011, 0x0001, 0x080c,
-	0x3eb7, 0x008e, 0x00ee, 0x00fe, 0x080c, 0x3de4, 0x080c, 0x3d11,
-	0x05b8, 0x2001, 0x020b, 0x2004, 0x9084, 0x0140, 0x1db8, 0x080c,
-	0x3f2b, 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, 0x3d1b, 0x080c, 0x3b00, 0x0058, 0x080c, 0x3b00, 0x080c,
-	0x3e4f, 0x080c, 0x3dda, 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, 0x12ee, 0x2009, 0x0028, 0x080c, 0x207b,
-	0x2001, 0x0227, 0x200c, 0x2102, 0x080c, 0x98e3, 0x00fe, 0x00ee,
-	0x00de, 0x00ce, 0x00be, 0x00ae, 0x009e, 0x008e, 0x004e, 0x2001,
-	0x1977, 0x2004, 0x9005, 0x1118, 0x012e, 0x0804, 0x339e, 0x012e,
-	0x2021, 0x400c, 0x0804, 0x33a0, 0x0016, 0x0026, 0x0036, 0x0046,
-	0x0056, 0x0076, 0x0086, 0x0096, 0x00d6, 0x0156, 0x7014, 0x2048,
-	0x7020, 0x20a8, 0x8000, 0x7022, 0xa804, 0x9005, 0x0904, 0x3a70,
-	0x2048, 0x1f04, 0x3a24, 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, 0x48e3, 0x701f, 0x3a14, 0x00b0, 0x8906,
-	0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x001b,
-	0x21a8, 0x27e0, 0x2098, 0x27e8, 0x20a0, 0x0006, 0x080c, 0x0fac,
-	0x000e, 0x080c, 0x48e6, 0x701f, 0x3a14, 0x015e, 0x00de, 0x009e,
-	0x008e, 0x007e, 0x005e, 0x004e, 0x003e, 0x002e, 0x001e, 0x0005,
-	0x7014, 0x2048, 0xa864, 0x9086, 0x0103, 0x1118, 0x701f, 0x3ad5,
-	0x0450, 0x7014, 0x2048, 0xa868, 0xc0fd, 0xa86a, 0x2009, 0x007f,
-	0x080c, 0x622f, 0x0110, 0x9006, 0x0030, 0xb813, 0x00ff, 0xb817,
-	0xfffd, 0x080c, 0xbd58, 0x015e, 0x00de, 0x009e, 0x008e, 0x007e,
-	0x005e, 0x004e, 0x003e, 0x002e, 0x001e, 0x0904, 0x33d0, 0x0016,
-	0x0026, 0x0036, 0x0046, 0x0056, 0x0076, 0x0086, 0x0096, 0x00d6,
-	0x0156, 0x701f, 0x3aa7, 0x7007, 0x0003, 0x0804, 0x3a65, 0xa830,
-	0x9086, 0x0100, 0x2021, 0x400c, 0x0904, 0x33a0, 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, 0x0fac, 0x000e, 0x080c, 0x48e6, 0x007e,
-	0x701f, 0x3a14, 0x7023, 0x0001, 0x0005, 0x0804, 0x339e, 0x0156,
-	0x00c6, 0xa814, 0x908a, 0x001e, 0x0218, 0xa833, 0x001e, 0x0010,
-	0xa832, 0x0078, 0x81ff, 0x0168, 0x0016, 0x080c, 0x489a, 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,
-	0x489a, 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, 0x207b, 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8,
-	0xa86e, 0x601a, 0xa873, 0x0000, 0x601f, 0x0000, 0x78ca, 0x9006,
-	0x600a, 0x600e, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x00e6, 0x080c,
-	0x489a, 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, 0x2850, 0x1130, 0x9006, 0x080c, 0x27a3, 0x9006,
-	0x080c, 0x2786, 0x7884, 0x9084, 0x0007, 0x0002, 0x3b91, 0x3b9a,
-	0x3ba3, 0x3b8e, 0x3b8e, 0x3b8e, 0x3b8e, 0x3b8e, 0x012e, 0x0804,
-	0x33d3, 0x2009, 0x0114, 0x2104, 0x9085, 0x0800, 0x200a, 0x080c,
-	0x3d65, 0x00c0, 0x2009, 0x0114, 0x2104, 0x9085, 0x4000, 0x200a,
-	0x080c, 0x3d65, 0x0078, 0x080c, 0x70ba, 0x1128, 0x012e, 0x2009,
-	0x0016, 0x0804, 0x33d0, 0x81ff, 0x0128, 0x012e, 0x2021, 0x400b,
-	0x0804, 0x33a0, 0x080c, 0x98c7, 0x0086, 0x0096, 0x00a6, 0x00b6,
-	0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x080c, 0x38bc, 0x2009, 0x0101,
-	0x210c, 0x0016, 0x7ec8, 0x7dcc, 0x9006, 0x2068, 0x2060, 0x2058,
-	0x080c, 0x4006, 0x080c, 0x3f56, 0x903e, 0x2720, 0x00f6, 0x00e6,
-	0x0086, 0x2940, 0x2071, 0x19bf, 0x2079, 0x0090, 0x00d6, 0x2069,
-	0x0000, 0x6884, 0xd0b4, 0x0120, 0x68d4, 0x780e, 0x68d0, 0x780a,
-	0x00de, 0x2011, 0x0001, 0x080c, 0x3eb7, 0x080c, 0x2858, 0x080c,
-	0x2858, 0x080c, 0x2858, 0x080c, 0x2858, 0x080c, 0x3eb7, 0x008e,
-	0x00ee, 0x00fe, 0x080c, 0x3de4, 0x2009, 0x9c40, 0x8109, 0x11b0,
-	0x080c, 0x3d1b, 0x2001, 0x0004, 0x200c, 0x918c, 0xfffd, 0x2102,
-	0x001e, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae, 0x009e,
-	0x008e, 0x2009, 0x0017, 0x080c, 0x33d0, 0x0cf8, 0x2001, 0x020b,
-	0x2004, 0x9084, 0x0140, 0x1d10, 0x00f6, 0x2079, 0x0000, 0x7884,
-	0x00fe, 0xd0bc, 0x0178, 0x2001, 0x0201, 0x200c, 0x81ff, 0x0150,
-	0x080c, 0x3dc2, 0x2d00, 0x9c05, 0x9b05, 0x0120, 0x080c, 0x3d1b,
-	0x0804, 0x3cc4, 0x080c, 0x3f2b, 0x080c, 0x3e4f, 0x080c, 0x3da5,
-	0x080c, 0x3dda, 0x00f6, 0x2079, 0x0100, 0x7824, 0xd0ac, 0x0130,
-	0x8b58, 0x080c, 0x3d1b, 0x00fe, 0x0804, 0x3cc4, 0x00fe, 0x080c,
-	0x3d11, 0x1150, 0x8d68, 0x2001, 0x0032, 0x2602, 0x2001, 0x0033,
-	0x2502, 0x080c, 0x3d1b, 0x0080, 0x87ff, 0x0138, 0x2001, 0x0201,
-	0x2004, 0x9005, 0x1908, 0x8739, 0x0038, 0x2001, 0x1a43, 0x2004,
-	0x9086, 0x0000, 0x1904, 0x3c14, 0x2001, 0x032f, 0x2003, 0x00f6,
-	0x8631, 0x1208, 0x8529, 0x2500, 0x9605, 0x0904, 0x3cc4, 0x7884,
-	0xd0bc, 0x0128, 0x2d00, 0x9c05, 0x9b05, 0x1904, 0x3cc4, 0xa013,
-	0x0019, 0x2001, 0x032a, 0x2003, 0x0004, 0x7884, 0xd0ac, 0x1148,
-	0x2001, 0x1a43, 0x2003, 0x0003, 0x2001, 0x032a, 0x2003, 0x0009,
-	0x0030, 0xa017, 0x0001, 0x78b4, 0x9005, 0x0108, 0xa016, 0x2800,
-	0xa05a, 0x2009, 0x0040, 0x080c, 0x207b, 0x2900, 0xa85a, 0xa813,
-	0x0019, 0x7884, 0xd0a4, 0x1180, 0xa817, 0x0000, 0x00c6, 0x20a9,
-	0x0004, 0x2061, 0x0090, 0x602b, 0x0008, 0x2001, 0x0203, 0x2004,
-	0x1f04, 0x3c9b, 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, 0x3bce, 0x001e, 0x00c6, 0x2001, 0x032a,
-	0x2003, 0x0004, 0x2061, 0x0100, 0x6027, 0x0002, 0x6106, 0x2011,
-	0x020d, 0x2013, 0x0020, 0x2001, 0x0004, 0x200c, 0x918c, 0xfffd,
-	0x2102, 0x080c, 0x12ee, 0x7884, 0x9084, 0x0003, 0x9086, 0x0002,
-	0x01b0, 0x2009, 0x0028, 0x080c, 0x207b, 0x2001, 0x0227, 0x200c,
-	0x2102, 0x6050, 0x9084, 0xb7ff, 0x080c, 0x2902, 0x6052, 0x602f,
-	0x0000, 0x604b, 0xf7f7, 0x6043, 0x0090, 0x6043, 0x0010, 0x080c,
-	0x98e3, 0x00ce, 0x2d08, 0x2c10, 0x2b18, 0x2b00, 0x9c05, 0x9d05,
-	0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae, 0x009e, 0x008e,
-	0x1118, 0x012e, 0x0804, 0x339e, 0x012e, 0x2021, 0x400c, 0x0804,
-	0x33a0, 0x9085, 0x0001, 0x1d04, 0x3d1a, 0x2091, 0x6000, 0x8420,
-	0x9486, 0x0064, 0x0005, 0x2001, 0x0105, 0x2003, 0x0010, 0x2001,
-	0x032a, 0x2003, 0x0004, 0x2001, 0x1a43, 0x2003, 0x0000, 0x0071,
-	0x2009, 0x0048, 0x080c, 0x207b, 0x2001, 0x0227, 0x2024, 0x2402,
-	0x2001, 0x0109, 0x2003, 0x4000, 0x9026, 0x0005, 0x00f6, 0x00e6,
-	0x2071, 0x19bf, 0x7054, 0x9086, 0x0000, 0x0520, 0x2079, 0x0090,
-	0x2009, 0x0206, 0x2104, 0x2009, 0x0203, 0x210c, 0x9106, 0x1120,
-	0x2009, 0x0040, 0x080c, 0x207b, 0x782c, 0xd0fc, 0x0d88, 0x080c,
-	0x3f2b, 0x7054, 0x9086, 0x0000, 0x1d58, 0x782b, 0x0004, 0x782c,
-	0xd0ac, 0x1de8, 0x2009, 0x0040, 0x080c, 0x207b, 0x782b, 0x0002,
-	0x7057, 0x0000, 0x00ee, 0x00fe, 0x0005, 0x00f6, 0x2079, 0x0100,
-	0x2001, 0x1817, 0x200c, 0x7932, 0x7936, 0x080c, 0x24a2, 0x080c,
-	0x28cf, 0x080c, 0x2902, 0x784b, 0xf7f7, 0x7843, 0x0090, 0x7843,
-	0x0010, 0x7850, 0xc0e5, 0x7852, 0x2019, 0x61a8, 0x7820, 0xd09c,
-	0x0110, 0x8319, 0x1dd8, 0x7850, 0xc0e4, 0x7852, 0x2011, 0x0048,
-	0x080c, 0x28ac, 0x7843, 0x0040, 0x2019, 0x01f4, 0xa001, 0xa001,
-	0x8319, 0x1de0, 0x2001, 0x0100, 0x080c, 0x2872, 0x2011, 0x0020,
-	0x080c, 0x28ac, 0x7843, 0x0000, 0x9006, 0x080c, 0x2872, 0x2011,
-	0x0048, 0x080c, 0x28ac, 0x00fe, 0x0005, 0x7884, 0xd0ac, 0x11c8,
-	0x00f6, 0x00e6, 0x2071, 0x1a43, 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, 0x3af6, 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, 0x3f2b, 0x00f6, 0x2071, 0x1a43, 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, 0x3eb7,
-	0x2011, 0x0001, 0x080c, 0x3eb7, 0x00fe, 0x00ee, 0x0005, 0x00f6,
-	0x00e6, 0x2071, 0x1a43, 0x2079, 0x0320, 0x792c, 0xd1fc, 0x0904,
-	0x3eb4, 0x782b, 0x0002, 0x9026, 0xd19c, 0x1904, 0x3eb0, 0x7000,
-	0x0002, 0x3eb4, 0x3e65, 0x3e95, 0x3eb0, 0xd1bc, 0x1170, 0xd1dc,
-	0x1190, 0x8001, 0x7002, 0x2011, 0x0001, 0x080c, 0x3eb7, 0x0904,
-	0x3eb4, 0x080c, 0x3eb7, 0x0804, 0x3eb4, 0x00f6, 0x2079, 0x0300,
-	0x78bf, 0x0000, 0x00fe, 0x7810, 0x7914, 0x782b, 0x0004, 0x7812,
-	0x7916, 0x2001, 0x0201, 0x200c, 0x81ff, 0x0de8, 0x080c, 0x3dc2,
-	0x2009, 0x0001, 0x00f6, 0x2079, 0x0300, 0x78b8, 0x00fe, 0xd0ec,
-	0x0110, 0x2009, 0x0011, 0x792a, 0x00f8, 0x8001, 0x7002, 0x9184,
-	0x0880, 0x1140, 0x782c, 0xd0fc, 0x1904, 0x3e59, 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, 0x0d65, 0x9398, 0x3ee5, 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, 0x3f22, 0x3f19, 0x3f10,
-	0x3f07, 0x3efe, 0x3ef5, 0x3eec, 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, 0x19bf,
-	0x2079, 0x0090, 0x792c, 0xd1fc, 0x01e8, 0x782b, 0x0002, 0x2940,
-	0x9026, 0x7054, 0x0002, 0x3f52, 0x3f3e, 0x3f49, 0x8001, 0x7056,
-	0xd19c, 0x1180, 0x2011, 0x0001, 0x080c, 0x3eb7, 0x190c, 0x3eb7,
-	0x0048, 0x8001, 0x7056, 0x782c, 0xd0fc, 0x1d38, 0x2011, 0x0001,
-	0x080c, 0x3eb7, 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, 0x489a, 0xa813,
-	0x0019, 0xaf16, 0x2900, 0xa85a, 0x978a, 0x0007, 0x0220, 0x2138,
-	0x2009, 0x0007, 0x0010, 0x2708, 0x903e, 0x0096, 0xa858, 0x2048,
-	0xa85c, 0x9080, 0x0019, 0x009e, 0x080c, 0x3fce, 0x1d68, 0x2900,
-	0xa85a, 0x00d0, 0x080c, 0x489a, 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, 0x207b,
-	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, 0x489a,
-	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, 0x489a, 0x2940, 0xa813, 0x0019,
-	0xaf16, 0x2900, 0xa85a, 0x978a, 0x0007, 0x0220, 0x2138, 0x2009,
-	0x0007, 0x0010, 0x2708, 0x903e, 0x0096, 0xa858, 0x2048, 0xa85c,
-	0x9080, 0x0019, 0x009e, 0x080c, 0x3fce, 0x1d68, 0x2900, 0xa85a,
-	0x00d8, 0x080c, 0x489a, 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, 0x1a43, 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,
-	0x339e, 0x7d98, 0x7c9c, 0x0804, 0x34a0, 0x080c, 0x70ba, 0x190c,
-	0x5cbc, 0x2069, 0x185b, 0x2d00, 0x2009, 0x0030, 0x7a8c, 0x7b88,
-	0x7c9c, 0x7d98, 0x2039, 0x0001, 0x080c, 0x48e3, 0x701f, 0x40a1,
-	0x0005, 0x080c, 0x53b7, 0x1130, 0x3b00, 0x3a08, 0xc194, 0xc095,
-	0x20d8, 0x21d0, 0x2069, 0x185b, 0x6800, 0x9005, 0x0904, 0x33d3,
-	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, 0x33d3, 0x9288, 0x319f,
-	0x210d, 0x918c, 0x00ff, 0x6162, 0xd0dc, 0x0130, 0x6828, 0x908a,
-	0x007f, 0x1a04, 0x33d3, 0x605a, 0x6888, 0x9084, 0x0030, 0x8004,
-	0x8004, 0x8004, 0x8004, 0x0006, 0x2009, 0x1989, 0x9080, 0x2595,
-	0x2005, 0x200a, 0x2008, 0x2001, 0x0018, 0x080c, 0x98b8, 0x2009,
-	0x0390, 0x200b, 0x0400, 0x000e, 0x2009, 0x198a, 0x9080, 0x2599,
-	0x2005, 0x200a, 0x6808, 0x908a, 0x0100, 0x0a04, 0x33d3, 0x908a,
-	0x0841, 0x1a04, 0x33d3, 0x9084, 0x0007, 0x1904, 0x33d3, 0x680c,
-	0x9005, 0x0904, 0x33d3, 0x6810, 0x9005, 0x0904, 0x33d3, 0x6848,
-	0x6940, 0x910a, 0x1a04, 0x33d3, 0x8001, 0x0904, 0x33d3, 0x684c,
-	0x6944, 0x910a, 0x1a04, 0x33d3, 0x8001, 0x0904, 0x33d3, 0x6814,
-	0x908c, 0x00ff, 0x614a, 0x8007, 0x9084, 0x00ff, 0x604e, 0x080c,
-	0x73ea, 0x080c, 0x6753, 0x080c, 0x6788, 0x6808, 0x602a, 0x080c,
-	0x1fed, 0x2009, 0x0170, 0x200b, 0x0080, 0xa001, 0xa001, 0x200b,
-	0x0000, 0x0036, 0x6b08, 0x080c, 0x24fc, 0x003e, 0x6000, 0x9086,
-	0x0000, 0x1904, 0x420d, 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, 0x82e3, 0x00c6, 0x900e, 0x20a9,
-	0x0001, 0x6b70, 0xd384, 0x01c8, 0x0020, 0x839d, 0x12b0, 0x3508,
-	0x8109, 0x080c, 0x79c1, 0x6878, 0x6016, 0x6874, 0x2008, 0x9084,
-	0xff00, 0x8007, 0x600a, 0x9184, 0x00ff, 0x6006, 0x8108, 0x1118,
-	0x6003, 0x0003, 0x0010, 0x6003, 0x0001, 0x1f04, 0x4185, 0x00ce,
-	0x00c6, 0x2061, 0x1974, 0x2063, 0x0001, 0x9006, 0x080c, 0x27a3,
-	0x9006, 0x080c, 0x2786, 0x0000, 0x00ce, 0x00e6, 0x2c70, 0x080c,
-	0x0ea9, 0x00ee, 0x6888, 0xd0ec, 0x0130, 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, 0x2571,
-	0x2001, 0x1945, 0x2102, 0x0008, 0x2102, 0x00c6, 0x2061, 0x0100,
-	0x602f, 0x0040, 0x602f, 0x0000, 0x00ce, 0x080c, 0x70ba, 0x0128,
-	0x080c, 0x4cac, 0x0110, 0x080c, 0x24c2, 0x60d0, 0x9005, 0x01c0,
-	0x6003, 0x0001, 0x2009, 0x41f5, 0x00d0, 0x080c, 0x70ba, 0x1168,
-	0x2011, 0x6f30, 0x080c, 0x816c, 0x2011, 0x6f23, 0x080c, 0x8272,
-	0x080c, 0x73be, 0x080c, 0x6feb, 0x0040, 0x080c, 0x5bb2, 0x0028,
-	0x6003, 0x0004, 0x2009, 0x420d, 0x0010, 0x0804, 0x339e, 0x2001,
-	0x0170, 0x2004, 0x9084, 0x00ff, 0x9086, 0x004c, 0x1118, 0x2091,
-	0x31bd, 0x0817, 0x2091, 0x313d, 0x0817, 0x6000, 0x9086, 0x0000,
-	0x0904, 0x33d0, 0x2069, 0x185b, 0x7890, 0x6842, 0x7894, 0x6846,
-	0x2d00, 0x2009, 0x0030, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x2039,
-	0x0001, 0x0804, 0x48e6, 0x9006, 0x080c, 0x24c2, 0x81ff, 0x1904,
-	0x33d0, 0x080c, 0x70ba, 0x11b0, 0x080c, 0x73b9, 0x080c, 0x5cf7,
-	0x080c, 0x319a, 0x0118, 0x6130, 0xc18d, 0x6132, 0x080c, 0xbf8f,
-	0x0130, 0x080c, 0x70dd, 0x1118, 0x080c, 0x708e, 0x0038, 0x080c,
-	0x6feb, 0x0020, 0x080c, 0x5cbc, 0x080c, 0x5bb2, 0x0804, 0x339e,
-	0x81ff, 0x1904, 0x33d0, 0x080c, 0x70ba, 0x1110, 0x0804, 0x33d0,
-	0x6190, 0x81ff, 0x01a8, 0x704f, 0x0000, 0x2001, 0x1d80, 0x2009,
-	0x0040, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x0126, 0x2091, 0x8000,
-	0x2039, 0x0001, 0x080c, 0x48e6, 0x701f, 0x339c, 0x012e, 0x0005,
-	0x704f, 0x0001, 0x00d6, 0x2069, 0x1d80, 0x20a9, 0x0040, 0x20e9,
-	0x0001, 0x20a1, 0x1d80, 0x2019, 0xffff, 0x4304, 0x6558, 0x9588,
-	0x319f, 0x210d, 0x918c, 0x00ff, 0x216a, 0x900e, 0x2011, 0x0002,
-	0x2100, 0x9506, 0x01a8, 0x080c, 0x628f, 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, 0x5c47, 0x0804, 0x4265, 0x080c, 0x48cd, 0x0904,
-	0x33d3, 0x080c, 0x489a, 0x1120, 0x2009, 0x0002, 0x0804, 0x33d0,
-	0x080c, 0x53a8, 0xd0b4, 0x0558, 0x7884, 0x908e, 0x007e, 0x0538,
-	0x908e, 0x007f, 0x0520, 0x908e, 0x0080, 0x0508, 0x080c, 0x3195,
-	0x1148, 0xb800, 0xd08c, 0x11d8, 0xb804, 0x9084, 0x00ff, 0x9086,
-	0x0006, 0x11a8, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x080c,
-	0xba3f, 0x1120, 0x2009, 0x0003, 0x0804, 0x33d0, 0x7007, 0x0003,
-	0x701f, 0x42f3, 0x0005, 0x080c, 0x48cd, 0x0904, 0x33d3, 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,
-	0x0fac, 0x0070, 0x20a9, 0x0004, 0xa85c, 0x9080, 0x000a, 0x20a0,
-	0xb8b4, 0x20e0, 0xb8b8, 0x9080, 0x000a, 0x2098, 0x080c, 0x0fac,
-	0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080,
-	0x0002, 0x2009, 0x002b, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x0804,
-	0x48e6, 0x81ff, 0x1904, 0x33d0, 0x080c, 0x48b1, 0x0904, 0x33d3,
-	0x080c, 0x64d4, 0x0904, 0x33d0, 0x0058, 0xa878, 0x9005, 0x0120,
-	0x2009, 0x0004, 0x0804, 0x33d0, 0xa974, 0xaa94, 0x0804, 0x339e,
-	0x080c, 0x53b0, 0x0904, 0x339e, 0x701f, 0x433d, 0x7007, 0x0003,
-	0x0005, 0x81ff, 0x1904, 0x33d0, 0x7888, 0x908a, 0x1000, 0x1a04,
-	0x33d3, 0x080c, 0x48cd, 0x0904, 0x33d3, 0x080c, 0x668a, 0x0120,
-	0x080c, 0x6692, 0x1904, 0x33d3, 0x080c, 0x6559, 0x0904, 0x33d0,
-	0x2019, 0x0004, 0x900e, 0x080c, 0x64e6, 0x0904, 0x33d0, 0x7984,
-	0x7a88, 0x04c9, 0x08a8, 0xa89c, 0x908a, 0x1000, 0x12f8, 0x080c,
-	0x48cb, 0x01e0, 0x080c, 0x668a, 0x0118, 0x080c, 0x6692, 0x11b0,
-	0x080c, 0x6559, 0x2009, 0x0002, 0x0168, 0x2009, 0x0002, 0x2019,
-	0x0004, 0x080c, 0x64e6, 0x2009, 0x0003, 0x0120, 0xa998, 0xaa9c,
-	0x00d1, 0x0060, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006,
-	0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000,
-	0x080c, 0x53b0, 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, 0x628f, 0x1138,
-	0x2200, 0x8003, 0x800b, 0x810b, 0x9108, 0x080c, 0x817a, 0x0005,
-	0x81ff, 0x1904, 0x33d0, 0x798c, 0x2001, 0x1958, 0x918c, 0x8000,
-	0x2102, 0x080c, 0x48b1, 0x0904, 0x33d3, 0x080c, 0x668a, 0x0120,
-	0x080c, 0x6692, 0x1904, 0x33d3, 0x080c, 0x6356, 0x0904, 0x33d0,
-	0x080c, 0x64dd, 0x0904, 0x33d0, 0x2001, 0x1958, 0x2004, 0xd0fc,
-	0x1904, 0x339e, 0x0804, 0x4348, 0xa9a0, 0x2001, 0x1958, 0x918c,
-	0x8000, 0xc18d, 0x2102, 0x080c, 0x48be, 0x01a0, 0x080c, 0x668a,
-	0x0118, 0x080c, 0x6692, 0x1170, 0x080c, 0x6356, 0x2009, 0x0002,
-	0x0128, 0x080c, 0x64dd, 0x1170, 0x2009, 0x0003, 0xa897, 0x4005,
-	0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001,
-	0x0030, 0x0005, 0xa897, 0x4000, 0x2001, 0x1958, 0x2004, 0xd0fc,
-	0x1128, 0x080c, 0x53b0, 0x0110, 0x9006, 0x0018, 0x900e, 0x9085,
-	0x0001, 0x2001, 0x0000, 0x0005, 0x81ff, 0x1904, 0x33d0, 0x798c,
-	0x2001, 0x1957, 0x918c, 0x8000, 0x2102, 0x080c, 0x48b1, 0x0904,
-	0x33d3, 0x080c, 0x668a, 0x0120, 0x080c, 0x6692, 0x1904, 0x33d3,
-	0x080c, 0x6356, 0x0904, 0x33d0, 0x080c, 0x64cb, 0x0904, 0x33d0,
-	0x2001, 0x1957, 0x2004, 0xd0fc, 0x1904, 0x339e, 0x0804, 0x4348,
-	0xa9a0, 0x2001, 0x1957, 0x918c, 0x8000, 0xc18d, 0x2102, 0x080c,
-	0x48be, 0x01a0, 0x080c, 0x668a, 0x0118, 0x080c, 0x6692, 0x1170,
-	0x080c, 0x6356, 0x2009, 0x0002, 0x0128, 0x080c, 0x64cb, 0x1170,
-	0x2009, 0x0003, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006,
-	0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000,
-	0x2001, 0x1957, 0x2004, 0xd0fc, 0x1128, 0x080c, 0x53b0, 0x0110,
-	0x9006, 0x0018, 0x900e, 0x9085, 0x0001, 0x2001, 0x0000, 0x0005,
-	0x6100, 0x0804, 0x339e, 0x080c, 0x48cd, 0x0904, 0x33d3, 0x080c,
-	0x53bc, 0x1904, 0x33d0, 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, 0x0200, 0x0804, 0x339e,
-	0x78a8, 0x909c, 0x0003, 0xd0ac, 0x1150, 0xd0b4, 0x1140, 0x939a,
-	0x0003, 0x1a04, 0x33d0, 0x6258, 0x7884, 0x9206, 0x1550, 0x2031,
-	0x1848, 0x2009, 0x013c, 0x2136, 0x2001, 0x1840, 0x7a8c, 0x7b88,
-	0x7c9c, 0x7d98, 0x2039, 0x0001, 0x0006, 0x78a8, 0x9084, 0x0080,
-	0x1118, 0x000e, 0x0804, 0x48e6, 0x000e, 0x2031, 0x0000, 0x2061,
-	0x18b6, 0x2c44, 0xa66a, 0xa17a, 0xa772, 0xa076, 0xa28e, 0xa392,
-	0xa496, 0xa59a, 0x080c, 0x1124, 0x7007, 0x0002, 0x701f, 0x4501,
-	0x0005, 0x81ff, 0x1904, 0x33d0, 0x080c, 0x48cd, 0x0904, 0x33d3,
-	0x080c, 0x668a, 0x1904, 0x33d0, 0x00c6, 0x080c, 0x489a, 0x00ce,
-	0x0904, 0x33d0, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x7ea8,
-	0x080c, 0xb9e5, 0x0904, 0x33d0, 0x7007, 0x0003, 0x701f, 0x4505,
-	0x0005, 0x080c, 0x4073, 0x0804, 0x339e, 0xa830, 0x9086, 0x0100,
-	0x0904, 0x33d0, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084,
-	0xffc0, 0x9080, 0x001b, 0x2009, 0x000c, 0x7a8c, 0x7b88, 0x7c9c,
-	0x7d98, 0x0804, 0x48e6, 0x9006, 0x080c, 0x24c2, 0x78a8, 0x9084,
-	0x00ff, 0x9086, 0x00ff, 0x0118, 0x81ff, 0x1904, 0x33d0, 0x080c,
-	0x70ba, 0x0110, 0x080c, 0x5cbc, 0x7888, 0x908a, 0x1000, 0x1a04,
-	0x33d3, 0x7984, 0x9186, 0x00ff, 0x0138, 0x9182, 0x007f, 0x1a04,
-	0x33d3, 0x2100, 0x080c, 0x248c, 0x0026, 0x00c6, 0x0126, 0x2091,
-	0x8000, 0x2061, 0x19db, 0x601b, 0x0000, 0x601f, 0x0000, 0x6073,
-	0x0000, 0x6077, 0x0000, 0x080c, 0x70ba, 0x1158, 0x080c, 0x73b9,
-	0x080c, 0x5cf7, 0x9085, 0x0001, 0x080c, 0x7101, 0x080c, 0x6feb,
-	0x00f0, 0x080c, 0x98c7, 0x080c, 0x9b6c, 0x080c, 0x98e3, 0x2061,
-	0x0100, 0x2001, 0x1817, 0x2004, 0x9084, 0x00ff, 0x810f, 0x9105,
-	0x604a, 0x6043, 0x0090, 0x6043, 0x0010, 0x2009, 0x1971, 0x200b,
-	0x0000, 0x2009, 0x002d, 0x2011, 0x5be2, 0x080c, 0x8230, 0x7984,
-	0x080c, 0x70ba, 0x1110, 0x2009, 0x00ff, 0x7a88, 0x080c, 0x43ab,
-	0x012e, 0x00ce, 0x002e, 0x0804, 0x339e, 0x7984, 0x080c, 0x622f,
-	0x2b08, 0x1904, 0x33d3, 0x0804, 0x339e, 0x81ff, 0x0120, 0x2009,
-	0x0001, 0x0804, 0x33d0, 0x60d8, 0xd0ac, 0x1130, 0xd09c, 0x1120,
-	0x2009, 0x0005, 0x0804, 0x33d0, 0x080c, 0x489a, 0x1120, 0x2009,
-	0x0002, 0x0804, 0x33d0, 0x7984, 0x9192, 0x0021, 0x1a04, 0x33d3,
-	0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xa85c, 0x9080, 0x0019, 0x702a,
-	0xaf60, 0x7736, 0x080c, 0x48e3, 0x701f, 0x45bd, 0x7880, 0x9086,
-	0x006e, 0x0110, 0x701f, 0x4e5e, 0x0005, 0x2009, 0x0080, 0x080c,
-	0x628f, 0x1118, 0x080c, 0x668a, 0x0120, 0x2021, 0x400a, 0x0804,
-	0x33a0, 0x00d6, 0x0096, 0xa964, 0xaa6c, 0xab70, 0xac74, 0xad78,
-	0xae7c, 0xa884, 0x90be, 0x0100, 0x0904, 0x4656, 0x90be, 0x0112,
-	0x0904, 0x4656, 0x90be, 0x0113, 0x0904, 0x4656, 0x90be, 0x0114,
-	0x0904, 0x4656, 0x90be, 0x0117, 0x0904, 0x4656, 0x90be, 0x011a,
-	0x0904, 0x4656, 0x90be, 0x011c, 0x0904, 0x4656, 0x90be, 0x0121,
-	0x0904, 0x463d, 0x90be, 0x0131, 0x0904, 0x463d, 0x90be, 0x0171,
-	0x0904, 0x4656, 0x90be, 0x0173, 0x0904, 0x4656, 0x90be, 0x01a1,
-	0x1128, 0xa894, 0x8007, 0xa896, 0x0804, 0x4661, 0x90be, 0x0212,
-	0x0904, 0x464a, 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, 0x33d3, 0x7028, 0x9080, 0x0010, 0x2098,
-	0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0007, 0x080c, 0x469f,
-	0x7028, 0x9080, 0x000e, 0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8,
-	0x20a9, 0x0001, 0x080c, 0x469f, 0x00c8, 0x7028, 0x9080, 0x000c,
-	0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0001, 0x080c,
-	0x46ac, 0x00b8, 0x7028, 0x9080, 0x000e, 0x2098, 0x20a0, 0x7034,
-	0x20e0, 0x20e8, 0x20a9, 0x0001, 0x080c, 0x46ac, 0x7028, 0x9080,
-	0x000c, 0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0001,
-	0x04f1, 0x00c6, 0x080c, 0x489a, 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, 0xba00, 0x1120, 0x2009, 0x0003,
-	0x0804, 0x33d0, 0x7007, 0x0003, 0x701f, 0x4696, 0x0005, 0x00ce,
-	0x009e, 0x00de, 0x2009, 0x0002, 0x0804, 0x33d0, 0xa820, 0x9086,
-	0x8001, 0x1904, 0x339e, 0x2009, 0x0004, 0x0804, 0x33d0, 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, 0x33d0, 0x60d8, 0xd0ac, 0x1160,
-	0xd09c, 0x0120, 0x2009, 0x0016, 0x0804, 0x33d0, 0xd09c, 0x1120,
-	0x2009, 0x0005, 0x0804, 0x33d0, 0x7984, 0x78a8, 0x2040, 0x080c,
-	0x9b65, 0x1120, 0x9182, 0x007f, 0x0a04, 0x33d3, 0x9186, 0x00ff,
-	0x0904, 0x33d3, 0x9182, 0x0800, 0x1a04, 0x33d3, 0x7a8c, 0x7b88,
-	0x6078, 0x9306, 0x1158, 0x607c, 0x924e, 0x0904, 0x33d3, 0x080c,
-	0x9b65, 0x1120, 0x99cc, 0xff00, 0x0904, 0x33d3, 0x0126, 0x2091,
-	0x8000, 0x0026, 0x2011, 0x8008, 0x080c, 0x66ae, 0x002e, 0x0140,
-	0x918d, 0x8000, 0x080c, 0x66f8, 0x1118, 0x2001, 0x4009, 0x0458,
-	0x080c, 0x47b4, 0x0560, 0x90c6, 0x4000, 0x1170, 0x00c6, 0x0006,
-	0x900e, 0x080c, 0x6582, 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, 0x33a0, 0x2b00,
-	0x7026, 0x0016, 0x00b6, 0x00c6, 0x00e6, 0x2c70, 0x080c, 0x9c55,
-	0x0904, 0x4781, 0x2b00, 0x6012, 0x080c, 0xbd09, 0x2e58, 0x00ee,
-	0x00e6, 0x00c6, 0x080c, 0x489a, 0x00ce, 0x2b70, 0x1158, 0x080c,
-	0x9be6, 0x00ee, 0x00ce, 0x00be, 0x001e, 0x012e, 0x2009, 0x0002,
-	0x0804, 0x33d0, 0x900e, 0xa966, 0xa96a, 0x2900, 0x6016, 0xa932,
-	0xa868, 0xc0fd, 0xd88c, 0x0108, 0xc0f5, 0xa86a, 0x080c, 0x302e,
-	0x6023, 0x0001, 0x9006, 0x080c, 0x61cc, 0x2001, 0x0002, 0x080c,
-	0x61e0, 0x2009, 0x0002, 0x080c, 0x9c82, 0x78a8, 0xd094, 0x0138,
-	0x00ee, 0x7024, 0x00e6, 0x2058, 0xb8c4, 0xc08d, 0xb8c6, 0x9085,
-	0x0001, 0x00ee, 0x00ce, 0x00be, 0x001e, 0x012e, 0x1120, 0x2009,
-	0x0003, 0x0804, 0x33d0, 0x7007, 0x0003, 0x701f, 0x4790, 0x0005,
-	0xa830, 0x2008, 0x918e, 0xdead, 0x1120, 0x2021, 0x4009, 0x0804,
-	0x33a0, 0x9086, 0x0100, 0x7024, 0x2058, 0x1138, 0x2009, 0x0004,
-	0xba04, 0x9294, 0x00ff, 0x0804, 0x5305, 0x900e, 0xa868, 0xd0f4,
-	0x1904, 0x339e, 0x080c, 0x6582, 0x1108, 0xc185, 0xb800, 0xd0bc,
-	0x0108, 0xc18d, 0x0804, 0x339e, 0x00e6, 0x00d6, 0x0096, 0x83ff,
-	0x0904, 0x47fc, 0x902e, 0x080c, 0x9b65, 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, 0x668a, 0x1540, 0x2001, 0x4000,
-	0x0430, 0x2001, 0x4007, 0x0418, 0x2001, 0x4006, 0x0400, 0x2400,
-	0x9106, 0x1158, 0xbe14, 0x87ff, 0x1128, 0x86ff, 0x0948, 0x080c,
-	0x9b65, 0x1930, 0x2001, 0x4008, 0x0090, 0x8420, 0x8e70, 0x1f04,
-	0x47ca, 0x85ff, 0x1130, 0x2001, 0x4009, 0x0048, 0x2001, 0x0001,
-	0x0030, 0x080c, 0x622f, 0x1dd0, 0xbb12, 0xba16, 0x9006, 0x9005,
-	0x009e, 0x00de, 0x00ee, 0x0005, 0x81ff, 0x0120, 0x2009, 0x0001,
-	0x0804, 0x33d0, 0x080c, 0x489a, 0x1120, 0x2009, 0x0002, 0x0804,
-	0x33d0, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x7884, 0x9005,
-	0x0904, 0x33d3, 0x9096, 0x00ff, 0x0120, 0x9092, 0x0004, 0x1a04,
-	0x33d3, 0x2010, 0x2918, 0x080c, 0x2fce, 0x1120, 0x2009, 0x0003,
-	0x0804, 0x33d0, 0x7007, 0x0003, 0x701f, 0x484f, 0x0005, 0xa830,
-	0x9086, 0x0100, 0x1904, 0x339e, 0x2009, 0x0004, 0x0804, 0x33d0,
-	0x7984, 0x080c, 0x9b65, 0x1120, 0x9182, 0x007f, 0x0a04, 0x33d3,
-	0x9186, 0x00ff, 0x0904, 0x33d3, 0x9182, 0x0800, 0x1a04, 0x33d3,
-	0x2001, 0x9000, 0x080c, 0x5360, 0x1904, 0x33d0, 0x0804, 0x339e,
-	0xa998, 0x080c, 0x9b65, 0x1118, 0x9182, 0x007f, 0x0280, 0x9186,
-	0x00ff, 0x0168, 0x9182, 0x0800, 0x1250, 0x2001, 0x9000, 0x080c,
-	0x5360, 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, 0x102f, 0x0198, 0x9006, 0xa802, 0x7014,
-	0x9005, 0x1120, 0x2900, 0x7016, 0x701a, 0x0040, 0x7018, 0xa802,
-	0x0086, 0x2040, 0x2900, 0xa006, 0x701a, 0x008e, 0x9085, 0x0001,
-	0x0005, 0x7984, 0x080c, 0x628f, 0x1130, 0x7e88, 0x9684, 0x3fff,
-	0x9082, 0x4000, 0x0208, 0x905e, 0x8bff, 0x0005, 0xa998, 0x080c,
-	0x628f, 0x1130, 0xae9c, 0x9684, 0x3fff, 0x9082, 0x4000, 0x0208,
-	0x905e, 0x8bff, 0x0005, 0xae98, 0x0008, 0x7e84, 0x2608, 0x080c,
-	0x628f, 0x1108, 0x0008, 0x905e, 0x8bff, 0x0005, 0x0016, 0x7114,
-	0x81ff, 0x0128, 0x2148, 0xa904, 0x080c, 0x1061, 0x0cc8, 0x7116,
-	0x711a, 0x001e, 0x0005, 0x2031, 0x0001, 0x0010, 0x2031, 0x0000,
-	0x2061, 0x18b6, 0x2c44, 0xa66a, 0xa17a, 0xa772, 0xa076, 0xa28e,
-	0xa392, 0xa496, 0xa59a, 0x080c, 0x1124, 0x7007, 0x0002, 0x701f,
-	0x339e, 0x0005, 0x00f6, 0x0126, 0x2091, 0x8000, 0x2079, 0x0000,
-	0x2001, 0x18ae, 0x2004, 0x9005, 0x1190, 0x0e04, 0x4917, 0x7a36,
-	0x7833, 0x0012, 0x7a82, 0x7b86, 0x7c8a, 0x2091, 0x4080, 0x2001,
-	0x0089, 0x2004, 0xd084, 0x190c, 0x11d6, 0x0804, 0x497d, 0x0016,
-	0x0086, 0x0096, 0x00c6, 0x00e6, 0x2071, 0x189c, 0x7044, 0x9005,
-	0x1540, 0x7148, 0x9182, 0x0010, 0x0288, 0x7038, 0x2060, 0x080c,
-	0x102f, 0x0904, 0x4975, 0xa84b, 0x0000, 0x2900, 0x7046, 0x2001,
-	0x0002, 0x9080, 0x1d1c, 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, 0x0d65, 0x2060, 0x001e, 0x8108,
-	0x2105, 0x9005, 0xa146, 0x1520, 0x080c, 0x102f, 0x1130, 0x8109,
-	0xa946, 0x7148, 0x8109, 0x714a, 0x00d8, 0x9006, 0xa806, 0xa84a,
-	0xa046, 0x2800, 0xa802, 0x2900, 0xa006, 0x7046, 0x2001, 0x0002,
-	0x9080, 0x1d1c, 0x2005, 0xa846, 0x0058, 0x2262, 0x6306, 0x640a,
-	0x00ee, 0x00ce, 0x009e, 0x008e, 0x001e, 0x012e, 0x00fe, 0x0005,
-	0x2c00, 0x9082, 0x001b, 0x0002, 0x499f, 0x499f, 0x49a1, 0x499f,
-	0x499f, 0x499f, 0x49a5, 0x499f, 0x499f, 0x499f, 0x49a9, 0x499f,
-	0x499f, 0x499f, 0x49ad, 0x499f, 0x499f, 0x499f, 0x49b1, 0x499f,
-	0x499f, 0x499f, 0x49b5, 0x499f, 0x499f, 0x499f, 0x49ba, 0x080c,
-	0x0d65, 0xa276, 0xa37a, 0xa47e, 0x0898, 0xa286, 0xa38a, 0xa48e,
-	0x0878, 0xa296, 0xa39a, 0xa49e, 0x0858, 0xa2a6, 0xa3aa, 0xa4ae,
-	0x0838, 0xa2b6, 0xa3ba, 0xa4be, 0x0818, 0xa2c6, 0xa3ca, 0xa4ce,
-	0x0804, 0x4978, 0xa2d6, 0xa3da, 0xa4de, 0x0804, 0x4978, 0x00e6,
-	0x2071, 0x189c, 0x7048, 0x9005, 0x0904, 0x4a51, 0x0126, 0x2091,
-	0x8000, 0x0e04, 0x4a50, 0x00f6, 0x2079, 0x0000, 0x00c6, 0x0096,
-	0x0086, 0x0076, 0x9006, 0x2038, 0x7040, 0x2048, 0x9005, 0x0500,
-	0xa948, 0x2105, 0x0016, 0x908a, 0x0036, 0x1a0c, 0x0d65, 0x2060,
-	0x001e, 0x8108, 0x2105, 0x9005, 0xa94a, 0x1904, 0x4a53, 0xa804,
-	0x9005, 0x090c, 0x0d65, 0x7042, 0x2938, 0x2040, 0xa003, 0x0000,
-	0x2001, 0x0002, 0x9080, 0x1d1c, 0x2005, 0xa04a, 0x0804, 0x4a53,
-	0x703c, 0x2060, 0x2c14, 0x6304, 0x6408, 0x650c, 0x2200, 0x7836,
-	0x7833, 0x0012, 0x7882, 0x2300, 0x7886, 0x2400, 0x788a, 0x2091,
-	0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11d6, 0x87ff,
-	0x0118, 0x2748, 0x080c, 0x1061, 0x7048, 0x8001, 0x704a, 0x9005,
-	0x1170, 0x7040, 0x2048, 0x9005, 0x0128, 0x080c, 0x1061, 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, 0x0d65, 0x2048, 0xa800,
-	0x9005, 0x1de0, 0x2900, 0x7042, 0x2001, 0x0002, 0x9080, 0x1d1c,
-	0x2005, 0xa84a, 0x0000, 0x007e, 0x008e, 0x009e, 0x00ce, 0x00fe,
-	0x012e, 0x00ee, 0x0005, 0x2c00, 0x9082, 0x001b, 0x0002, 0x4a72,
-	0x4a72, 0x4a74, 0x4a72, 0x4a72, 0x4a72, 0x4a79, 0x4a72, 0x4a72,
-	0x4a72, 0x4a7e, 0x4a72, 0x4a72, 0x4a72, 0x4a83, 0x4a72, 0x4a72,
-	0x4a72, 0x4a88, 0x4a72, 0x4a72, 0x4a72, 0x4a8d, 0x4a72, 0x4a72,
-	0x4a72, 0x4a92, 0x080c, 0x0d65, 0xaa74, 0xab78, 0xac7c, 0x0804,
-	0x49fe, 0xaa84, 0xab88, 0xac8c, 0x0804, 0x49fe, 0xaa94, 0xab98,
-	0xac9c, 0x0804, 0x49fe, 0xaaa4, 0xaba8, 0xacac, 0x0804, 0x49fe,
-	0xaab4, 0xabb8, 0xacbc, 0x0804, 0x49fe, 0xaac4, 0xabc8, 0xaccc,
-	0x0804, 0x49fe, 0xaad4, 0xabd8, 0xacdc, 0x0804, 0x49fe, 0x0026,
-	0x080c, 0x53a8, 0xd0c4, 0x0120, 0x2011, 0x8014, 0x080c, 0x48fa,
-	0x002e, 0x0005, 0x81ff, 0x1904, 0x33d0, 0x0126, 0x2091, 0x8000,
-	0x6030, 0xc08d, 0xc085, 0xc0ac, 0x6032, 0x080c, 0x70ba, 0x1158,
-	0x080c, 0x73b9, 0x080c, 0x5cf7, 0x9085, 0x0001, 0x080c, 0x7101,
-	0x080c, 0x6feb, 0x0010, 0x080c, 0x5bb2, 0x012e, 0x0804, 0x339e,
-	0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x33d0, 0x080c, 0x53bc,
-	0x0120, 0x2009, 0x0007, 0x0804, 0x33d0, 0x080c, 0x6682, 0x0120,
-	0x2009, 0x0008, 0x0804, 0x33d0, 0x0026, 0x2011, 0x0010, 0x080c,
-	0x66ae, 0x002e, 0x0140, 0x7984, 0x080c, 0x66f8, 0x1120, 0x2009,
-	0x4009, 0x0804, 0x33d0, 0x7984, 0x080c, 0x622f, 0x1904, 0x33d3,
-	0x2b00, 0x7026, 0x080c, 0x668a, 0x7888, 0x1170, 0x9084, 0x0005,
-	0x1158, 0x900e, 0x080c, 0x6582, 0x1108, 0xc185, 0xb800, 0xd0bc,
-	0x0108, 0xc18d, 0x0804, 0x339e, 0x080c, 0x489a, 0x0904, 0x33d0,
-	0x9006, 0xa866, 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xbaa7,
-	0x0904, 0x33d0, 0x7888, 0xd094, 0x0118, 0xb8c4, 0xc08d, 0xb8c6,
-	0x7007, 0x0003, 0x701f, 0x4b61, 0x0005, 0x2061, 0x1800, 0x080c,
-	0x53bc, 0x2009, 0x0007, 0x1578, 0x080c, 0x6682, 0x0118, 0x2009,
-	0x0008, 0x0448, 0x080c, 0x3195, 0x0120, 0xa998, 0x080c, 0x622f,
-	0x1530, 0x080c, 0x48cb, 0x0518, 0x080c, 0x668a, 0xa89c, 0x1168,
-	0x9084, 0x0005, 0x1150, 0x900e, 0x080c, 0x6582, 0x1108, 0xc185,
-	0xb800, 0xd0bc, 0x0108, 0xc18d, 0x00d0, 0xa868, 0xc0fc, 0xa86a,
-	0x080c, 0xbaa7, 0x11e0, 0xa89c, 0xd094, 0x0118, 0xb8c4, 0xc08d,
-	0xb8c6, 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, 0x33a0, 0x9086, 0x0100, 0x7024, 0x2058, 0x1110, 0x0804,
-	0x5305, 0x900e, 0x080c, 0x6582, 0x1108, 0xc185, 0xb800, 0xd0bc,
-	0x0108, 0xc18d, 0x0804, 0x339e, 0x080c, 0x53bc, 0x0120, 0x2009,
-	0x0007, 0x0804, 0x33d0, 0x7f84, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98,
-	0x080c, 0x489a, 0x1120, 0x2009, 0x0002, 0x0804, 0x33d0, 0x900e,
-	0x2130, 0x7126, 0x7132, 0xa860, 0x20e8, 0x7036, 0xa85c, 0x9080,
-	0x0005, 0x702a, 0x20a0, 0x080c, 0x628f, 0x1904, 0x4bff, 0x080c,
-	0x668a, 0x0120, 0x080c, 0x6692, 0x1904, 0x4bff, 0x080c, 0x6682,
-	0x1130, 0x080c, 0x6582, 0x1118, 0xd79c, 0x0904, 0x4bff, 0xd794,
-	0x1110, 0xd784, 0x01a8, 0xb8b4, 0x20e0, 0xb8b8, 0x9080, 0x0006,
-	0x2098, 0x3400, 0xd794, 0x0160, 0x20a9, 0x0008, 0x4003, 0x2098,
-	0x20a0, 0x3d00, 0x20e0, 0x20a9, 0x0002, 0x080c, 0x46ac, 0x0048,
-	0x20a9, 0x0004, 0x4003, 0x2098, 0x20a0, 0x3d00, 0x20e0, 0x080c,
-	0x46ac, 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,
-	0x469f, 0x9c80, 0x0026, 0x2098, 0xb8b4, 0x20e0, 0x20a9, 0x0002,
-	0x4003, 0xd794, 0x0110, 0x96b0, 0x000b, 0x96b0, 0x0005, 0x8108,
-	0x080c, 0x9b65, 0x0118, 0x9186, 0x0800, 0x0040, 0xd78c, 0x0120,
-	0x9186, 0x0800, 0x0170, 0x0018, 0x9186, 0x007e, 0x0150, 0xd794,
-	0x0118, 0x9686, 0x0020, 0x0010, 0x9686, 0x0028, 0x0150, 0x0804,
-	0x4b9b, 0x86ff, 0x1120, 0x7124, 0x810b, 0x0804, 0x339e, 0x7033,
-	0x0001, 0x7122, 0x7024, 0x9600, 0x7026, 0x772e, 0x2061, 0x18b6,
-	0x2c44, 0xa06b, 0x0000, 0xa67a, 0x7034, 0xa072, 0x7028, 0xa076,
-	0xa28e, 0xa392, 0xa496, 0xa59a, 0x080c, 0x1124, 0x7007, 0x0002,
-	0x701f, 0x4c3b, 0x0005, 0x7030, 0x9005, 0x1180, 0x7120, 0x7028,
-	0x20a0, 0x772c, 0x9036, 0x7034, 0x20e8, 0x2061, 0x18b6, 0x2c44,
-	0xa28c, 0xa390, 0xa494, 0xa598, 0x0804, 0x4b9b, 0x7124, 0x810b,
-	0x0804, 0x339e, 0x2029, 0x007e, 0x7984, 0x7a88, 0x7b8c, 0x7c98,
-	0x9184, 0xff00, 0x8007, 0x90e2, 0x0020, 0x0a04, 0x33d3, 0x9502,
-	0x0a04, 0x33d3, 0x9184, 0x00ff, 0x90e2, 0x0020, 0x0a04, 0x33d3,
-	0x9502, 0x0a04, 0x33d3, 0x9284, 0xff00, 0x8007, 0x90e2, 0x0020,
-	0x0a04, 0x33d3, 0x9502, 0x0a04, 0x33d3, 0x9284, 0x00ff, 0x90e2,
-	0x0020, 0x0a04, 0x33d3, 0x9502, 0x0a04, 0x33d3, 0x9384, 0xff00,
-	0x8007, 0x90e2, 0x0020, 0x0a04, 0x33d3, 0x9502, 0x0a04, 0x33d3,
-	0x9384, 0x00ff, 0x90e2, 0x0020, 0x0a04, 0x33d3, 0x9502, 0x0a04,
-	0x33d3, 0x9484, 0xff00, 0x8007, 0x90e2, 0x0020, 0x0a04, 0x33d3,
-	0x9502, 0x0a04, 0x33d3, 0x9484, 0x00ff, 0x90e2, 0x0020, 0x0a04,
-	0x33d3, 0x9502, 0x0a04, 0x33d3, 0x2061, 0x1961, 0x6102, 0x6206,
-	0x630a, 0x640e, 0x0804, 0x339e, 0x0006, 0x080c, 0x53a8, 0xd0cc,
-	0x000e, 0x0005, 0x0006, 0x080c, 0x53ac, 0xd0bc, 0x000e, 0x0005,
-	0x6170, 0x7a84, 0x6300, 0x82ff, 0x1118, 0x7986, 0x0804, 0x339e,
-	0x83ff, 0x1904, 0x33d3, 0x2001, 0xfff0, 0x9200, 0x1a04, 0x33d3,
-	0x2019, 0xffff, 0x6074, 0x9302, 0x9200, 0x0a04, 0x33d3, 0x7986,
-	0x6272, 0x0804, 0x339e, 0x080c, 0x53bc, 0x1904, 0x33d0, 0x7c88,
-	0x7d84, 0x7e98, 0x7f8c, 0x080c, 0x489a, 0x0904, 0x33d0, 0x900e,
-	0x901e, 0x7326, 0x7332, 0xa860, 0x20e8, 0x7036, 0xa85c, 0x9080,
-	0x0003, 0x702a, 0x20a0, 0x91d8, 0x1000, 0x2b5c, 0x8bff, 0x0178,
-	0x080c, 0x668a, 0x0118, 0x080c, 0x6692, 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, 0x842f, 0x2208,
-	0x0804, 0x339e, 0x7033, 0x0001, 0x7122, 0x7024, 0x9300, 0x7026,
-	0x2061, 0x18b6, 0x2c44, 0xa06b, 0x0000, 0xa37a, 0x7028, 0xa076,
-	0x7034, 0xa072, 0xa48e, 0xa592, 0xa696, 0xa79a, 0x080c, 0x1124,
-	0x7007, 0x0002, 0x701f, 0x4d2d, 0x0005, 0x7030, 0x9005, 0x1178,
-	0x7120, 0x7028, 0x20a0, 0x901e, 0x7034, 0x20e8, 0x2061, 0x18b6,
-	0x2c44, 0xa48c, 0xa590, 0xa694, 0xa798, 0x0804, 0x4ceb, 0x7224,
-	0x900e, 0x2001, 0x0003, 0x080c, 0x842f, 0x2208, 0x0804, 0x339e,
-	0x00f6, 0x00e6, 0x080c, 0x53bc, 0x2009, 0x0007, 0x1904, 0x4dc0,
-	0x2071, 0x189c, 0x745c, 0x84ff, 0x2009, 0x000e, 0x1904, 0x4dc0,
-	0xac9c, 0xad98, 0xaea4, 0xafa0, 0x0096, 0x080c, 0x1048, 0x2009,
-	0x0002, 0x0904, 0x4dc0, 0x2900, 0x705e, 0x900e, 0x901e, 0x7356,
-	0x7362, 0xa860, 0x7066, 0xa85c, 0x9080, 0x0003, 0x705a, 0x20a0,
-	0x91d8, 0x1000, 0x2b5c, 0x8bff, 0x0178, 0x080c, 0x668a, 0x0118,
-	0x080c, 0x6692, 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, 0x842f, 0x2208, 0x009e, 0xa897, 0x4000,
-	0xa99a, 0x715c, 0x81ff, 0x090c, 0x0d65, 0x2148, 0x080c, 0x1061,
-	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, 0x4dcc, 0x000e, 0xa0a2, 0x080c, 0x1124, 0x9006, 0x0048,
-	0x009e, 0xa897, 0x4005, 0xa99a, 0x900e, 0x9085, 0x0001, 0x2001,
-	0x0030, 0x00ee, 0x00fe, 0x0005, 0x00f6, 0xa0a0, 0x904d, 0x090c,
-	0x0d65, 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,
-	0x842f, 0xaa9a, 0x715c, 0x81ff, 0x090c, 0x0d65, 0x2148, 0x080c,
-	0x1061, 0x705f, 0x0000, 0xa0a0, 0x2048, 0x0126, 0x2091, 0x8000,
-	0x080c, 0x69b5, 0x012e, 0xa09f, 0x0000, 0xa0a3, 0x0000, 0x00ee,
-	0x00fe, 0x0005, 0x91d8, 0x1000, 0x2b5c, 0x8bff, 0x0178, 0x080c,
-	0x668a, 0x0118, 0x080c, 0x6692, 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,
-	0x0d65, 0x2148, 0x080c, 0x1061, 0x9006, 0x705e, 0x918d, 0x0001,
-	0x2008, 0xa0a0, 0x2048, 0x0126, 0x2091, 0x8000, 0x080c, 0x69b5,
-	0x012e, 0xa09f, 0x0000, 0xa0a3, 0x0000, 0x0070, 0x7063, 0x0001,
-	0x7152, 0x7054, 0x9300, 0x7056, 0xa37a, 0xa48e, 0xa592, 0xa696,
-	0xa79a, 0x080c, 0x1124, 0x9006, 0x00ee, 0x0005, 0x0096, 0xa88c,
-	0x90be, 0x7000, 0x0148, 0x90be, 0x7100, 0x0130, 0x90be, 0x7200,
-	0x0118, 0x009e, 0x0804, 0x33d3, 0xa884, 0xa988, 0x080c, 0x2459,
-	0x1518, 0x080c, 0x622f, 0x1500, 0x7126, 0xbe12, 0xbd16, 0xae7c,
-	0x080c, 0x489a, 0x01c8, 0x080c, 0x489a, 0x01b0, 0x009e, 0xa867,
-	0x0000, 0xa868, 0xc0fd, 0xa86a, 0xa823, 0x0000, 0xa804, 0x2048,
-	0x080c, 0xba20, 0x1120, 0x2009, 0x0003, 0x0804, 0x33d0, 0x7007,
-	0x0003, 0x701f, 0x4e99, 0x0005, 0x009e, 0x2009, 0x0002, 0x0804,
-	0x33d0, 0x7124, 0x080c, 0x3136, 0xa820, 0x9086, 0x8001, 0x1120,
-	0x2009, 0x0004, 0x0804, 0x33d0, 0x2900, 0x7022, 0xa804, 0x0096,
-	0x2048, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0,
-	0x009e, 0x9080, 0x0002, 0x0076, 0x0006, 0x2098, 0x20a0, 0x27e0,
-	0x27e8, 0x20a9, 0x002a, 0x080c, 0x0fac, 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, 0x48e6, 0x97c6,
-	0x7200, 0x11b8, 0x96c2, 0x0054, 0x02a0, 0x000e, 0x007e, 0x2061,
-	0x18b6, 0x2c44, 0xa076, 0xa772, 0xa07b, 0x002a, 0xa28e, 0xa392,
-	0xa496, 0xa59a, 0x080c, 0x1124, 0x7007, 0x0002, 0x701f, 0x4ef5,
-	0x0005, 0x000e, 0x007e, 0x0804, 0x33d3, 0x7020, 0x2048, 0xa804,
-	0x2048, 0xa804, 0x2048, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f,
-	0x9084, 0xffc0, 0x9080, 0x0002, 0x2098, 0x20a0, 0x27e0, 0x27e8,
-	0x20a9, 0x002a, 0x080c, 0x0fac, 0x2100, 0x2238, 0x2061, 0x18b6,
-	0x2c44, 0xa28c, 0xa390, 0xa494, 0xa598, 0x2009, 0x002a, 0x0804,
-	0x48e6, 0x81ff, 0x1904, 0x33d0, 0x798c, 0x2001, 0x1956, 0x918c,
-	0x8000, 0x2102, 0x080c, 0x48b1, 0x0904, 0x33d3, 0x080c, 0x668a,
-	0x0120, 0x080c, 0x6692, 0x1904, 0x33d3, 0x080c, 0x6356, 0x0904,
-	0x33d0, 0x0126, 0x2091, 0x8000, 0x080c, 0x64ef, 0x012e, 0x0904,
-	0x33d0, 0x2001, 0x1956, 0x2004, 0xd0fc, 0x1904, 0x339e, 0x0804,
-	0x4348, 0xa9a0, 0x2001, 0x1956, 0x918c, 0x8000, 0xc18d, 0x2102,
-	0x080c, 0x48be, 0x01a0, 0x080c, 0x668a, 0x0118, 0x080c, 0x6692,
-	0x1170, 0x080c, 0x6356, 0x2009, 0x0002, 0x0128, 0x080c, 0x64ef,
-	0x1170, 0x2009, 0x0003, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897,
-	0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897,
-	0x4000, 0x2001, 0x1956, 0x2004, 0xd0fc, 0x1128, 0x080c, 0x53b0,
-	0x0110, 0x9006, 0x0018, 0x900e, 0x9085, 0x0001, 0x2001, 0x0000,
-	0x0005, 0x78a8, 0xd08c, 0x1118, 0xd084, 0x0904, 0x42bd, 0x080c,
-	0x48cd, 0x0904, 0x33d3, 0x080c, 0x489a, 0x1120, 0x2009, 0x0002,
-	0x0804, 0x33d0, 0x080c, 0x668a, 0x0130, 0x908e, 0x0004, 0x0118,
-	0x908e, 0x0005, 0x15a0, 0x78a8, 0xd08c, 0x0120, 0xb800, 0xc08c,
-	0xb802, 0x0028, 0x080c, 0x53a8, 0xd0b4, 0x0904, 0x42f7, 0x7884,
-	0x908e, 0x007e, 0x0904, 0x42f7, 0x908e, 0x007f, 0x0904, 0x42f7,
-	0x908e, 0x0080, 0x0904, 0x42f7, 0xb800, 0xd08c, 0x1904, 0x42f7,
-	0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xba3f, 0x1120,
-	0x2009, 0x0003, 0x0804, 0x33d0, 0x7007, 0x0003, 0x701f, 0x4fc1,
-	0x0005, 0x080c, 0x48cd, 0x0904, 0x33d3, 0x0804, 0x42f7, 0x080c,
-	0x3195, 0x0108, 0x0005, 0x2009, 0x1833, 0x210c, 0x81ff, 0x0120,
-	0x2009, 0x0001, 0x0804, 0x33d0, 0x080c, 0x53bc, 0x0120, 0x2009,
-	0x0007, 0x0804, 0x33d0, 0x080c, 0x6682, 0x0120, 0x2009, 0x0008,
-	0x0804, 0x33d0, 0xb89c, 0xd0a4, 0x1118, 0xd0ac, 0x1904, 0x42f7,
-	0x9006, 0xa866, 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xbaa7,
-	0x1120, 0x2009, 0x0003, 0x0804, 0x33d0, 0x7007, 0x0003, 0x701f,
-	0x4ffa, 0x0005, 0xa830, 0x9086, 0x0100, 0x1120, 0x2009, 0x0004,
-	0x0804, 0x5305, 0x080c, 0x48cd, 0x0904, 0x33d3, 0x0804, 0x4f93,
-	0x81ff, 0x2009, 0x0001, 0x1904, 0x33d0, 0x080c, 0x53bc, 0x2009,
-	0x0007, 0x1904, 0x33d0, 0x080c, 0x6682, 0x0120, 0x2009, 0x0008,
-	0x0804, 0x33d0, 0x080c, 0x48cd, 0x0904, 0x33d3, 0x080c, 0x668a,
-	0x2009, 0x0009, 0x1904, 0x33d0, 0x080c, 0x489a, 0x2009, 0x0002,
-	0x0904, 0x33d0, 0x9006, 0xa866, 0xa832, 0xa868, 0xc0fd, 0xa86a,
-	0x7988, 0x9194, 0xff00, 0x918c, 0x00ff, 0x9006, 0x82ff, 0x1128,
-	0xc0ed, 0xa952, 0x798c, 0xa956, 0x0038, 0x928e, 0x0100, 0x1904,
-	0x33d3, 0xc0e5, 0xa952, 0xa956, 0xa83e, 0x080c, 0xbd0a, 0x2009,
-	0x0003, 0x0904, 0x33d0, 0x7007, 0x0003, 0x701f, 0x5050, 0x0005,
-	0xa830, 0x9086, 0x0100, 0x2009, 0x0004, 0x0904, 0x33d0, 0x0804,
-	0x339e, 0x7aa8, 0x9284, 0xc000, 0x0148, 0xd2ec, 0x01a0, 0x080c,
-	0x53bc, 0x1188, 0x2009, 0x0014, 0x0804, 0x33d0, 0xd2dc, 0x1568,
-	0x81ff, 0x2009, 0x0001, 0x1904, 0x33d0, 0x080c, 0x53bc, 0x2009,
-	0x0007, 0x1904, 0x33d0, 0xd2f4, 0x0130, 0x9284, 0x5000, 0x080c,
-	0x5383, 0x0804, 0x339e, 0xd2fc, 0x0158, 0x080c, 0x48cd, 0x0904,
-	0x33d3, 0x7984, 0x9284, 0x9000, 0x080c, 0x5360, 0x0804, 0x339e,
-	0x080c, 0x48cd, 0x0904, 0x33d3, 0xb804, 0x9084, 0x00ff, 0x9086,
-	0x0006, 0x2009, 0x0009, 0x1904, 0x5139, 0x080c, 0x489a, 0x2009,
-	0x0002, 0x0904, 0x5139, 0xa85c, 0x9080, 0x001b, 0xaf60, 0x2009,
-	0x0008, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x080c, 0x48e3, 0x701f,
-	0x50aa, 0x0005, 0xa86c, 0x9086, 0x0500, 0x1138, 0xa870, 0x9005,
-	0x1120, 0xa874, 0x9084, 0xff00, 0x0110, 0x1904, 0x33d3, 0xa866,
-	0xa832, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0x48cd, 0x1110, 0x0804,
-	0x33d3, 0x2009, 0x0043, 0x080c, 0xbd72, 0x2009, 0x0003, 0x0904,
-	0x5139, 0x7007, 0x0003, 0x701f, 0x50ce, 0x0005, 0xa830, 0x9086,
-	0x0100, 0x2009, 0x0004, 0x0904, 0x5139, 0x7984, 0x7aa8, 0x9284,
-	0x1000, 0x080c, 0x5360, 0x0804, 0x339e, 0x00c6, 0xaab0, 0x9284,
-	0xc000, 0x0140, 0xd2ec, 0x0168, 0x080c, 0x53bc, 0x1150, 0x2009,
-	0x0014, 0x04f0, 0x2061, 0x1800, 0x080c, 0x53bc, 0x2009, 0x0007,
-	0x15b8, 0xd2f4, 0x0128, 0x9284, 0x5000, 0x080c, 0x5383, 0x0050,
-	0xd2fc, 0x0178, 0x080c, 0x48cb, 0x0588, 0xa998, 0x9284, 0x9000,
-	0x080c, 0x5360, 0xa87b, 0x0000, 0xa883, 0x0000, 0xa897, 0x4000,
-	0x0438, 0x080c, 0x48cb, 0x0510, 0x080c, 0x668a, 0x2009, 0x0009,
-	0x11b8, 0xa8c4, 0x9086, 0x0500, 0x11c8, 0xa8c8, 0x9005, 0x11b0,
-	0xa8cc, 0x9084, 0xff00, 0x1190, 0x080c, 0x48cb, 0x1108, 0x0070,
-	0x2009, 0x004b, 0x080c, 0xbd72, 0x2009, 0x0003, 0x0108, 0x0078,
-	0x0429, 0x19c0, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006,
-	0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x00ce, 0x0005, 0x9006,
-	0x0ce0, 0x7aa8, 0xd2dc, 0x0904, 0x33d0, 0x0016, 0x7984, 0x9284,
-	0x1000, 0xc0fd, 0x080c, 0x5360, 0x001e, 0x1904, 0x33d0, 0x0804,
-	0x339e, 0x00f6, 0x2d78, 0x0011, 0x00fe, 0x0005, 0xaab0, 0xd2dc,
-	0x0150, 0x0016, 0xa998, 0x9284, 0x1000, 0xc0fd, 0x080c, 0x5360,
-	0x001e, 0x9085, 0x0001, 0x0005, 0x81ff, 0x0120, 0x2009, 0x0001,
-	0x0804, 0x33d0, 0x080c, 0x53bc, 0x0120, 0x2009, 0x0007, 0x0804,
-	0x33d0, 0x7984, 0x7ea8, 0x96b4, 0x00ff, 0x080c, 0x628f, 0x1904,
-	0x33d3, 0x9186, 0x007f, 0x0138, 0x080c, 0x668a, 0x0120, 0x2009,
-	0x0009, 0x0804, 0x33d0, 0x080c, 0x489a, 0x1120, 0x2009, 0x0002,
-	0x0804, 0x33d0, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x2001,
-	0x0100, 0x8007, 0xa80a, 0x080c, 0xba59, 0x1120, 0x2009, 0x0003,
-	0x0804, 0x33d0, 0x7007, 0x0003, 0x701f, 0x5197, 0x0005, 0xa808,
-	0x8007, 0x9086, 0x0100, 0x1120, 0x2009, 0x0004, 0x0804, 0x33d0,
-	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, 0x48e6, 0x080c, 0x489a,
-	0x1120, 0x2009, 0x0002, 0x0804, 0x33d0, 0x7984, 0x9194, 0xff00,
-	0x918c, 0x00ff, 0x8217, 0x82ff, 0x1118, 0x7023, 0x198b, 0x0040,
-	0x92c6, 0x0001, 0x1118, 0x7023, 0x19a5, 0x0010, 0x0804, 0x33d3,
-	0x2009, 0x001a, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xa85c, 0x9080,
-	0x0019, 0xaf60, 0x080c, 0x48e3, 0x701f, 0x51e7, 0x0005, 0x2001,
-	0x182d, 0x2003, 0x0001, 0xa85c, 0x9080, 0x0019, 0x2098, 0xa860,
-	0x20e0, 0x20a9, 0x001a, 0x7020, 0x20a0, 0x20e9, 0x0001, 0x4003,
-	0x0804, 0x339e, 0x080c, 0x489a, 0x1120, 0x2009, 0x0002, 0x0804,
-	0x33d0, 0x7984, 0x9194, 0xff00, 0x918c, 0x00ff, 0x8217, 0x82ff,
-	0x1118, 0x2099, 0x198b, 0x0040, 0x92c6, 0x0001, 0x1118, 0x2099,
-	0x19a5, 0x0010, 0x0804, 0x33d3, 0xa85c, 0x9080, 0x0019, 0x20a0,
-	0xa860, 0x20e8, 0x20a9, 0x001a, 0x20e1, 0x0001, 0x4003, 0x2009,
-	0x001a, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xa85c, 0x9080, 0x0019,
-	0xaf60, 0x0804, 0x48e6, 0x7884, 0x908a, 0x1000, 0x1a04, 0x33d3,
-	0x0126, 0x2091, 0x8000, 0x8003, 0x800b, 0x810b, 0x9108, 0x00c6,
-	0x2061, 0x19db, 0x6142, 0x00ce, 0x012e, 0x0804, 0x339e, 0x00c6,
-	0x080c, 0x70ba, 0x1160, 0x080c, 0x73b9, 0x080c, 0x5cf7, 0x9085,
-	0x0001, 0x080c, 0x7101, 0x080c, 0x6feb, 0x080c, 0x0d65, 0x2061,
-	0x1800, 0x6030, 0xc09d, 0x6032, 0x080c, 0x5bb2, 0x00ce, 0x0005,
-	0x00c6, 0x2001, 0x1800, 0x2004, 0x908e, 0x0000, 0x0904, 0x33d0,
-	0x7884, 0x9005, 0x0188, 0x7888, 0x2061, 0x1974, 0x2c0c, 0x2062,
-	0x080c, 0x2840, 0x01a0, 0x080c, 0x2848, 0x0188, 0x080c, 0x2850,
-	0x0170, 0x2162, 0x0804, 0x33d3, 0x2061, 0x0100, 0x6038, 0x9086,
-	0x0007, 0x1118, 0x2009, 0x0001, 0x0010, 0x2009, 0x0000, 0x7884,
-	0x9086, 0x0002, 0x1588, 0x2061, 0x0100, 0x6028, 0xc09c, 0x602a,
-	0x080c, 0x98c7, 0x0026, 0x2011, 0x0003, 0x080c, 0x9324, 0x2011,
-	0x0002, 0x080c, 0x932e, 0x002e, 0x080c, 0x921d, 0x0036, 0x901e,
-	0x080c, 0x929d, 0x003e, 0x080c, 0x98e3, 0x60e3, 0x0000, 0x080c,
-	0xd644, 0x080c, 0xd65f, 0x9085, 0x0001, 0x080c, 0x7101, 0x9006,
-	0x080c, 0x2872, 0x2001, 0x1800, 0x2003, 0x0004, 0x0026, 0x2011,
-	0x0008, 0x080c, 0x28ac, 0x002e, 0x00ce, 0x0804, 0x339e, 0x81ff,
-	0x0120, 0x2009, 0x0001, 0x0804, 0x33d0, 0x080c, 0x53bc, 0x0120,
-	0x2009, 0x0007, 0x0804, 0x33d0, 0x7984, 0x7ea8, 0x96b4, 0x00ff,
-	0x080c, 0x628f, 0x1904, 0x33d3, 0x9186, 0x007f, 0x0138, 0x080c,
-	0x668a, 0x0120, 0x2009, 0x0009, 0x0804, 0x33d0, 0x080c, 0x489a,
-	0x1120, 0x2009, 0x0002, 0x0804, 0x33d0, 0xa867, 0x0000, 0xa868,
-	0xc0fd, 0xa86a, 0x080c, 0xba5c, 0x1120, 0x2009, 0x0003, 0x0804,
-	0x33d0, 0x7007, 0x0003, 0x701f, 0x52ee, 0x0005, 0xa830, 0x9086,
-	0x0100, 0x1120, 0x2009, 0x0004, 0x0804, 0x33d0, 0xa8e0, 0xa866,
-	0xa834, 0x8007, 0x800c, 0xa85c, 0x9080, 0x000c, 0x7a8c, 0x7b88,
-	0x7c9c, 0x7d98, 0xaf60, 0x0804, 0x48e6, 0xa898, 0x9086, 0x000d,
-	0x1904, 0x33d0, 0x2021, 0x4005, 0x0126, 0x2091, 0x8000, 0x0e04,
-	0x5312, 0x0010, 0x012e, 0x0cc0, 0x7c36, 0x9486, 0x4000, 0x0118,
-	0x7833, 0x0011, 0x0010, 0x7833, 0x0010, 0x7883, 0x4005, 0xa998,
-	0x7986, 0xa9a4, 0x799a, 0xa9a8, 0x799e, 0x080c, 0x48d6, 0x2091,
-	0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11d6, 0x7007,
-	0x0001, 0x2091, 0x5000, 0x700f, 0x0000, 0x012e, 0x0005, 0x0126,
-	0x2091, 0x8000, 0x00c6, 0x2061, 0x19db, 0x7984, 0x6152, 0x614e,
-	0x6057, 0x0000, 0x604b, 0x0009, 0x7898, 0x606a, 0x789c, 0x6066,
-	0x7888, 0x6062, 0x788c, 0x605e, 0x2001, 0x19e9, 0x2044, 0x2001,
-	0x19f0, 0xa076, 0xa060, 0xa072, 0xa07b, 0x0001, 0xa07f, 0x0002,
-	0xa06b, 0x0000, 0xa09f, 0x0000, 0x00ce, 0x012e, 0x0804, 0x339e,
-	0x0126, 0x2091, 0x8000, 0x00b6, 0x00c6, 0x90e4, 0xc000, 0x0128,
-	0x0006, 0x080c, 0xb8bd, 0x000e, 0x1198, 0xd0e4, 0x0160, 0x9180,
-	0x1000, 0x2004, 0x905d, 0x0160, 0x080c, 0x5d11, 0x080c, 0x9b65,
-	0x0110, 0xb817, 0x0000, 0x9006, 0x00ce, 0x00be, 0x012e, 0x0005,
-	0x9085, 0x0001, 0x0cc8, 0x0126, 0x2091, 0x8000, 0x0156, 0x2010,
-	0x900e, 0x20a9, 0x0800, 0x0016, 0x9180, 0x1000, 0x2004, 0x9005,
-	0x0180, 0x9186, 0x007e, 0x0168, 0x9186, 0x007f, 0x0150, 0x9186,
-	0x0080, 0x0138, 0x9186, 0x00ff, 0x0120, 0x0026, 0x2200, 0x0801,
-	0x002e, 0x001e, 0x8108, 0x1f04, 0x538b, 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,
-	0x33d3, 0x810c, 0x0016, 0x080c, 0x489a, 0x080c, 0x0f37, 0x2100,
-	0x2238, 0x7d84, 0x7c88, 0x7b8c, 0x7a90, 0x001e, 0x080c, 0x48e3,
-	0x701f, 0x53e3, 0x0005, 0x2079, 0x0000, 0x7d94, 0x7c98, 0x7ba8,
-	0x7aac, 0x79a4, 0x810c, 0x2061, 0x18b6, 0x2c44, 0xa770, 0xa074,
-	0x2071, 0x189c, 0x080c, 0x48e6, 0x701f, 0x53f7, 0x0005, 0x2061,
-	0x18b6, 0x2c44, 0x0016, 0x0026, 0xa270, 0xa174, 0x080c, 0x0f3f,
-	0x002e, 0x001e, 0x080c, 0x0fec, 0x9006, 0xa802, 0xa806, 0x0804,
-	0x339e, 0x0126, 0x0156, 0x0136, 0x0146, 0x01c6, 0x01d6, 0x00c6,
-	0x00d6, 0x00e6, 0x00f6, 0x2061, 0x0100, 0x2069, 0x0200, 0x2071,
-	0x1800, 0x6044, 0xd0a4, 0x11e8, 0xd084, 0x0118, 0x080c, 0x55b2,
-	0x0068, 0xd08c, 0x0118, 0x080c, 0x54bb, 0x0040, 0xd094, 0x0118,
-	0x080c, 0x548b, 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, 0x5c73, 0x00f0, 0x6040, 0x9084, 0x0010, 0x9085,
-	0x0140, 0x6042, 0x6043, 0x0000, 0x7083, 0x0000, 0x709f, 0x0001,
-	0x70c3, 0x0000, 0x70db, 0x0000, 0x2009, 0x1d80, 0x200b, 0x0000,
-	0x7093, 0x0000, 0x7087, 0x000f, 0x2009, 0x000f, 0x2011, 0x5b55,
-	0x080c, 0x8230, 0x0005, 0x2001, 0x187d, 0x2004, 0xd08c, 0x0110,
-	0x705b, 0xffff, 0x7084, 0x9005, 0x1528, 0x2011, 0x5b55, 0x080c,
-	0x816c, 0x6040, 0x9094, 0x0010, 0x9285, 0x0020, 0x6042, 0x20a9,
-	0x00c8, 0x6044, 0xd08c, 0x1168, 0x1f04, 0x54a1, 0x6242, 0x7097,
-	0x0000, 0x6040, 0x9094, 0x0010, 0x9285, 0x0080, 0x6042, 0x6242,
-	0x0048, 0x6242, 0x7097, 0x0000, 0x708b, 0x0000, 0x9006, 0x080c,
-	0x5cfc, 0x0000, 0x0005, 0x7088, 0x908a, 0x0003, 0x1a0c, 0x0d65,
-	0x000b, 0x0005, 0x54c5, 0x5516, 0x55b1, 0x00f6, 0x0016, 0x6900,
-	0x918c, 0x0800, 0x708b, 0x0001, 0x2001, 0x015d, 0x2003, 0x0000,
-	0x6803, 0x00fc, 0x20a9, 0x0004, 0x6800, 0x9084, 0x00fc, 0x0120,
-	0x1f04, 0x54d4, 0x080c, 0x0d65, 0x68a0, 0x68a2, 0x689c, 0x689e,
-	0x6898, 0x689a, 0xa001, 0x918d, 0x1600, 0x6902, 0x001e, 0x6837,
-	0x0020, 0x080c, 0x5cd8, 0x2079, 0x1d00, 0x7833, 0x1101, 0x7837,
-	0x0000, 0x20e1, 0x0001, 0x2099, 0x1805, 0x20e9, 0x0001, 0x20a1,
-	0x1d0e, 0x20a9, 0x0004, 0x4003, 0x080c, 0x97f4, 0x20e1, 0x0001,
-	0x2099, 0x1d00, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x0014,
-	0x4003, 0x60c3, 0x000c, 0x600f, 0x0000, 0x080c, 0x5b86, 0x00fe,
-	0x9006, 0x708e, 0x6043, 0x0008, 0x6042, 0x0005, 0x00f6, 0x708c,
-	0x708f, 0x0000, 0x9025, 0x0904, 0x558e, 0x6020, 0xd0b4, 0x1904,
-	0x558c, 0x719c, 0x81ff, 0x0904, 0x557a, 0x9486, 0x000c, 0x1904,
-	0x5587, 0x9480, 0x0018, 0x8004, 0x20a8, 0x080c, 0x5cd1, 0x2011,
-	0x0260, 0x2019, 0x1d00, 0x220c, 0x2304, 0x9106, 0x11e8, 0x8210,
-	0x8318, 0x1f04, 0x5533, 0x6043, 0x0004, 0x2061, 0x0140, 0x605b,
-	0xbc94, 0x605f, 0xf0f0, 0x2061, 0x0100, 0x6043, 0x0006, 0x708b,
-	0x0002, 0x7097, 0x0002, 0x2009, 0x07d0, 0x2011, 0x5b5c, 0x080c,
-	0x8230, 0x080c, 0x5cd8, 0x04c0, 0x080c, 0x5cd1, 0x2079, 0x0260,
-	0x7930, 0x918e, 0x1101, 0x1558, 0x7834, 0x9005, 0x1540, 0x7900,
-	0x918c, 0x00ff, 0x1118, 0x7804, 0x9005, 0x0190, 0x080c, 0x5cd1,
-	0x2011, 0x026e, 0x2019, 0x1805, 0x20a9, 0x0004, 0x220c, 0x2304,
-	0x9102, 0x0230, 0x11a0, 0x8210, 0x8318, 0x1f04, 0x556e, 0x0078,
-	0x709f, 0x0000, 0x080c, 0x5cd1, 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, 0x97f4, 0x20e1,
-	0x0001, 0x2099, 0x1d00, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9,
-	0x0014, 0x4003, 0x60c3, 0x000c, 0x2011, 0x19cc, 0x2013, 0x0000,
-	0x708f, 0x0000, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x080c, 0x8fc3,
-	0x08d8, 0x0005, 0x7094, 0x908a, 0x001d, 0x1a0c, 0x0d65, 0x000b,
-	0x0005, 0x55e3, 0x55f6, 0x561f, 0x563f, 0x5665, 0x5694, 0x56ba,
-	0x56f2, 0x5718, 0x5746, 0x5781, 0x57b9, 0x57d7, 0x5802, 0x5824,
-	0x583f, 0x5849, 0x587d, 0x58a3, 0x58d2, 0x58f8, 0x5930, 0x5974,
-	0x59b1, 0x59d2, 0x5a2b, 0x5a4d, 0x5a7b, 0x5a7b, 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, 0x5b5c, 0x080c, 0x8230, 0x0005, 0x00f6, 0x708c,
-	0x9086, 0x0014, 0x1510, 0x6042, 0x6020, 0xd0b4, 0x11f0, 0x080c,
-	0x5cd1, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1102, 0x11a0, 0x7834,
-	0x9005, 0x1188, 0x7a38, 0xd2fc, 0x0128, 0x70c0, 0x9005, 0x1110,
-	0x70c3, 0x0001, 0x2011, 0x5b5c, 0x080c, 0x816c, 0x7097, 0x0010,
-	0x080c, 0x5849, 0x0010, 0x708f, 0x0000, 0x00fe, 0x0005, 0x00f6,
-	0x7097, 0x0003, 0x6043, 0x0004, 0x2011, 0x5b5c, 0x080c, 0x816c,
-	0x080c, 0x5c55, 0x2079, 0x0240, 0x7833, 0x1102, 0x7837, 0x0000,
-	0x20a9, 0x0008, 0x9f88, 0x000e, 0x200b, 0x0000, 0x8108, 0x1f04,
-	0x5634, 0x60c3, 0x0014, 0x080c, 0x5b86, 0x00fe, 0x0005, 0x00f6,
-	0x708c, 0x9005, 0x0500, 0x2011, 0x5b5c, 0x080c, 0x816c, 0x9086,
-	0x0014, 0x11b8, 0x080c, 0x5cd1, 0x2079, 0x0260, 0x7a30, 0x9296,
-	0x1102, 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc, 0x0128,
-	0x70c0, 0x9005, 0x1110, 0x70c3, 0x0001, 0x7097, 0x0004, 0x0029,
-	0x0010, 0x080c, 0x5cad, 0x00fe, 0x0005, 0x00f6, 0x7097, 0x0005,
-	0x080c, 0x5c55, 0x2079, 0x0240, 0x7833, 0x1103, 0x7837, 0x0000,
-	0x080c, 0x5cd1, 0x080c, 0x5cb4, 0x1170, 0x7080, 0x9005, 0x1158,
-	0x7158, 0x9186, 0xffff, 0x0138, 0x2011, 0x0008, 0x080c, 0x5b09,
-	0x0168, 0x080c, 0x5c8a, 0x20a9, 0x0008, 0x20e1, 0x0000, 0x2099,
-	0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014,
-	0x080c, 0x5b86, 0x00fe, 0x0005, 0x00f6, 0x708c, 0x9005, 0x0500,
-	0x2011, 0x5b5c, 0x080c, 0x816c, 0x9086, 0x0014, 0x11b8, 0x080c,
-	0x5cd1, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1103, 0x1178, 0x7834,
-	0x9005, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c0, 0x9005, 0x1110,
-	0x70c3, 0x0001, 0x7097, 0x0006, 0x0029, 0x0010, 0x080c, 0x5cad,
-	0x00fe, 0x0005, 0x00f6, 0x7097, 0x0007, 0x080c, 0x5c55, 0x2079,
-	0x0240, 0x7833, 0x1104, 0x7837, 0x0000, 0x080c, 0x5cd1, 0x080c,
-	0x5cb4, 0x11b8, 0x7080, 0x9005, 0x11a0, 0x7160, 0x9186, 0xffff,
-	0x0180, 0x9180, 0x319f, 0x200d, 0x918c, 0xff00, 0x810f, 0x2011,
-	0x0008, 0x080c, 0x5b09, 0x0180, 0x080c, 0x4cb2, 0x0110, 0x080c,
-	0x24c2, 0x20a9, 0x0008, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9,
-	0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x5b86,
-	0x00fe, 0x0005, 0x00f6, 0x708c, 0x9005, 0x0500, 0x2011, 0x5b5c,
-	0x080c, 0x816c, 0x9086, 0x0014, 0x11b8, 0x080c, 0x5cd1, 0x2079,
-	0x0260, 0x7a30, 0x9296, 0x1104, 0x1178, 0x7834, 0x9005, 0x1160,
-	0x7a38, 0xd2fc, 0x0128, 0x70c0, 0x9005, 0x1110, 0x70c3, 0x0001,
-	0x7097, 0x0008, 0x0029, 0x0010, 0x080c, 0x5cad, 0x00fe, 0x0005,
-	0x00f6, 0x7097, 0x0009, 0x080c, 0x5c55, 0x2079, 0x0240, 0x7833,
-	0x1105, 0x7837, 0x0100, 0x080c, 0x5cb4, 0x1150, 0x7080, 0x9005,
-	0x1138, 0x080c, 0x5a7c, 0x1188, 0x9085, 0x0001, 0x080c, 0x24c2,
-	0x20a9, 0x0008, 0x080c, 0x5cd1, 0x20e1, 0x0000, 0x2099, 0x026e,
-	0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c,
-	0x5b86, 0x0010, 0x080c, 0x55d6, 0x00fe, 0x0005, 0x00f6, 0x708c,
-	0x9005, 0x05a8, 0x2011, 0x5b5c, 0x080c, 0x816c, 0x9086, 0x0014,
-	0x1560, 0x080c, 0x5cd1, 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, 0x5824, 0x0010, 0x080c, 0x5cad, 0x00fe,
-	0x0005, 0x00f6, 0x7097, 0x000b, 0x2011, 0x1d0e, 0x20e9, 0x0001,
-	0x22a0, 0x20a9, 0x0040, 0x2019, 0xffff, 0x4304, 0x080c, 0x5c55,
-	0x2079, 0x0240, 0x7833, 0x1106, 0x7837, 0x0000, 0x080c, 0x5cb4,
-	0x0118, 0x2013, 0x0000, 0x0020, 0x705c, 0x9085, 0x0100, 0x2012,
-	0x20a9, 0x0040, 0x2009, 0x024e, 0x2011, 0x1d0e, 0x220e, 0x8210,
-	0x8108, 0x9186, 0x0260, 0x1128, 0x6810, 0x8000, 0x6812, 0x2009,
-	0x0240, 0x1f04, 0x57a6, 0x60c3, 0x0084, 0x080c, 0x5b86, 0x00fe,
-	0x0005, 0x00f6, 0x708c, 0x9005, 0x01c0, 0x2011, 0x5b5c, 0x080c,
-	0x816c, 0x9086, 0x0084, 0x1178, 0x080c, 0x5cd1, 0x2079, 0x0260,
-	0x7a30, 0x9296, 0x1106, 0x1138, 0x7834, 0x9005, 0x1120, 0x7097,
-	0x000c, 0x0029, 0x0010, 0x080c, 0x5cad, 0x00fe, 0x0005, 0x00f6,
-	0x7097, 0x000d, 0x080c, 0x5c55, 0x2079, 0x0240, 0x7833, 0x1107,
-	0x7837, 0x0000, 0x080c, 0x5cd1, 0x20a9, 0x0040, 0x2011, 0x026e,
-	0x2009, 0x024e, 0x220e, 0x8210, 0x8108, 0x9186, 0x0260, 0x1150,
-	0x6810, 0x8000, 0x6812, 0x2009, 0x0240, 0x6814, 0x8000, 0x6816,
-	0x2011, 0x0260, 0x1f04, 0x57ea, 0x60c3, 0x0084, 0x080c, 0x5b86,
-	0x00fe, 0x0005, 0x00f6, 0x708c, 0x9005, 0x01e0, 0x2011, 0x5b5c,
-	0x080c, 0x816c, 0x9086, 0x0084, 0x1198, 0x080c, 0x5cd1, 0x2079,
-	0x0260, 0x7a30, 0x9296, 0x1107, 0x1158, 0x7834, 0x9005, 0x1140,
-	0x7093, 0x0001, 0x080c, 0x5c27, 0x7097, 0x000e, 0x0029, 0x0010,
-	0x080c, 0x5cad, 0x00fe, 0x0005, 0x918d, 0x0001, 0x080c, 0x5cfc,
-	0x7097, 0x000f, 0x708f, 0x0000, 0x2061, 0x0140, 0x605b, 0xbc85,
-	0x605f, 0xb5b5, 0x2061, 0x0100, 0x6043, 0x0005, 0x6043, 0x0004,
-	0x2009, 0x07d0, 0x2011, 0x5b5c, 0x080c, 0x8160, 0x0005, 0x708c,
-	0x9005, 0x0130, 0x2011, 0x5b5c, 0x080c, 0x816c, 0x7097, 0x0000,
-	0x0005, 0x7097, 0x0011, 0x080c, 0x97f4, 0x080c, 0x5cd1, 0x20e1,
-	0x0000, 0x2099, 0x0260, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x748c,
-	0x9480, 0x0018, 0x9080, 0x0007, 0x9084, 0x03f8, 0x8004, 0x20a8,
-	0x4003, 0x080c, 0x5cb4, 0x11a0, 0x7178, 0x81ff, 0x0188, 0x900e,
-	0x707c, 0x9084, 0x00ff, 0x0160, 0x080c, 0x2459, 0x9186, 0x007e,
-	0x0138, 0x9186, 0x0080, 0x0120, 0x2011, 0x0008, 0x080c, 0x5b09,
-	0x60c3, 0x0014, 0x080c, 0x5b86, 0x0005, 0x00f6, 0x708c, 0x9005,
-	0x0500, 0x2011, 0x5b5c, 0x080c, 0x816c, 0x9086, 0x0014, 0x11b8,
-	0x080c, 0x5cd1, 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, 0x5c63,
-	0x2079, 0x0240, 0x7833, 0x1103, 0x7837, 0x0000, 0x080c, 0x5cd1,
-	0x080c, 0x5cb4, 0x1170, 0x7080, 0x9005, 0x1158, 0x7158, 0x9186,
-	0xffff, 0x0138, 0x2011, 0x0008, 0x080c, 0x5b09, 0x0168, 0x080c,
-	0x5c8a, 0x20a9, 0x0008, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9,
-	0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x5b86,
-	0x00fe, 0x0005, 0x00f6, 0x708c, 0x9005, 0x0500, 0x2011, 0x5b5c,
-	0x080c, 0x816c, 0x9086, 0x0014, 0x11b8, 0x080c, 0x5cd1, 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, 0x5c63, 0x2079, 0x0240, 0x7833,
-	0x1104, 0x7837, 0x0000, 0x080c, 0x5cd1, 0x080c, 0x5cb4, 0x11b8,
-	0x7080, 0x9005, 0x11a0, 0x7160, 0x9186, 0xffff, 0x0180, 0x9180,
-	0x319f, 0x200d, 0x918c, 0xff00, 0x810f, 0x2011, 0x0008, 0x080c,
-	0x5b09, 0x0180, 0x080c, 0x4cb2, 0x0110, 0x080c, 0x24c2, 0x20a9,
-	0x0008, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1,
-	0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x5b86, 0x00fe, 0x0005,
-	0x00f6, 0x708c, 0x9005, 0x05f0, 0x2011, 0x5b5c, 0x080c, 0x816c,
-	0x9086, 0x0014, 0x15a8, 0x080c, 0x5cd1, 0x2079, 0x0260, 0x7a30,
-	0x9296, 0x1105, 0x1568, 0x7834, 0x9084, 0x0100, 0x2011, 0x0100,
-	0x921e, 0x1168, 0x9085, 0x0001, 0x080c, 0x5cfc, 0x7a38, 0xd2fc,
-	0x0128, 0x70c0, 0x9005, 0x1110, 0x70c3, 0x0001, 0x0080, 0x9005,
-	0x11b8, 0x7a38, 0xd2fc, 0x0128, 0x70c0, 0x9005, 0x1110, 0x70c3,
-	0x0001, 0x9085, 0x0001, 0x080c, 0x5cfc, 0x7093, 0x0000, 0x7a38,
-	0xd2f4, 0x0110, 0x70db, 0x0008, 0x7097, 0x0016, 0x0029, 0x0010,
-	0x708f, 0x0000, 0x00fe, 0x0005, 0x080c, 0x97f4, 0x080c, 0x5cd1,
-	0x20e1, 0x0000, 0x2099, 0x0260, 0x20e9, 0x0000, 0x20a1, 0x0240,
-	0x20a9, 0x000e, 0x4003, 0x2011, 0x026d, 0x2204, 0x9084, 0x0100,
-	0x2011, 0x024d, 0x2012, 0x2011, 0x026e, 0x7097, 0x0017, 0x080c,
-	0x5cb4, 0x1150, 0x7080, 0x9005, 0x1138, 0x080c, 0x5a7c, 0x1188,
-	0x9085, 0x0001, 0x080c, 0x24c2, 0x20a9, 0x0008, 0x080c, 0x5cd1,
-	0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e,
-	0x4003, 0x60c3, 0x0014, 0x080c, 0x5b86, 0x0010, 0x080c, 0x55d6,
-	0x0005, 0x00f6, 0x708c, 0x9005, 0x01d8, 0x2011, 0x5b5c, 0x080c,
-	0x816c, 0x9086, 0x0084, 0x1190, 0x080c, 0x5cd1, 0x2079, 0x0260,
-	0x7a30, 0x9296, 0x1106, 0x1150, 0x7834, 0x9005, 0x1138, 0x9006,
-	0x080c, 0x5cfc, 0x7097, 0x0018, 0x0029, 0x0010, 0x708f, 0x0000,
-	0x00fe, 0x0005, 0x00f6, 0x7097, 0x0019, 0x080c, 0x5c63, 0x2079,
-	0x0240, 0x7833, 0x1106, 0x7837, 0x0000, 0x080c, 0x5cd1, 0x2009,
-	0x026e, 0x2039, 0x1d0e, 0x20a9, 0x0040, 0x213e, 0x8738, 0x8108,
-	0x9186, 0x0280, 0x1128, 0x6814, 0x8000, 0x6816, 0x2009, 0x0260,
-	0x1f04, 0x59e5, 0x2039, 0x1d0e, 0x080c, 0x5cb4, 0x11e8, 0x2728,
-	0x2514, 0x8207, 0x9084, 0x00ff, 0x8000, 0x2018, 0x9294, 0x00ff,
-	0x8007, 0x9205, 0x202a, 0x705c, 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, 0x5a18, 0x60c3, 0x0084, 0x080c,
-	0x5b86, 0x00fe, 0x0005, 0x00f6, 0x708c, 0x9005, 0x01e0, 0x2011,
-	0x5b5c, 0x080c, 0x816c, 0x9086, 0x0084, 0x1198, 0x080c, 0x5cd1,
-	0x2079, 0x0260, 0x7a30, 0x9296, 0x1107, 0x1158, 0x7834, 0x9005,
-	0x1140, 0x7093, 0x0001, 0x080c, 0x5c27, 0x7097, 0x001a, 0x0029,
-	0x0010, 0x708f, 0x0000, 0x00fe, 0x0005, 0x9085, 0x0001, 0x080c,
-	0x5cfc, 0x7097, 0x001b, 0x080c, 0x97f4, 0x080c, 0x5cd1, 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, 0x5a64, 0x60c3, 0x0084,
-	0x080c, 0x5b86, 0x0005, 0x0005, 0x0086, 0x0096, 0x2029, 0x185c,
-	0x252c, 0x20a9, 0x0008, 0x2041, 0x1d0e, 0x20e9, 0x0001, 0x28a0,
-	0x080c, 0x5cd1, 0x20e1, 0x0000, 0x2099, 0x026e, 0x4003, 0x20a9,
-	0x0008, 0x2011, 0x0007, 0xd5d4, 0x0108, 0x9016, 0x2800, 0x9200,
-	0x200c, 0x91a6, 0xffff, 0x1148, 0xd5d4, 0x0110, 0x8210, 0x0008,
-	0x8211, 0x1f04, 0x5a96, 0x0804, 0x5b05, 0x82ff, 0x1160, 0xd5d4,
-	0x0120, 0x91a6, 0x3fff, 0x0d90, 0x0020, 0x91a6, 0x3fff, 0x0904,
-	0x5b05, 0x918d, 0xc000, 0x20a9, 0x0010, 0x2019, 0x0001, 0xd5d4,
-	0x0110, 0x2019, 0x0010, 0x2120, 0xd5d4, 0x0110, 0x8423, 0x0008,
-	0x8424, 0x1240, 0xd5d4, 0x0110, 0x8319, 0x0008, 0x8318, 0x1f04,
-	0x5abc, 0x04d8, 0x23a8, 0x2021, 0x0001, 0x8426, 0x8425, 0x1f04,
-	0x5ace, 0x2328, 0x8529, 0x92be, 0x0007, 0x0158, 0x0006, 0x2039,
-	0x0007, 0x2200, 0x973a, 0x000e, 0x27a8, 0x95a8, 0x0010, 0x1f04,
-	0x5add, 0x755a, 0x95c8, 0x319f, 0x292d, 0x95ac, 0x00ff, 0x757e,
-	0x6532, 0x6536, 0x0016, 0x2508, 0x080c, 0x24a2, 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, 0x319f, 0x242d, 0x95ac, 0x00ff, 0x757e, 0x6532, 0x6536,
-	0x0016, 0x2508, 0x080c, 0x24a2, 0x001e, 0x60e7, 0x0000, 0x65ea,
-	0x7083, 0x0001, 0x9084, 0x0000, 0x0005, 0x00e6, 0x2071, 0x1800,
-	0x7087, 0x0000, 0x00ee, 0x0005, 0x00e6, 0x00f6, 0x2079, 0x0100,
-	0x2071, 0x0140, 0x080c, 0x5c16, 0x080c, 0x8fd0, 0x7004, 0x9084,
-	0x4000, 0x0110, 0x080c, 0x2882, 0x0126, 0x2091, 0x8000, 0x2071,
-	0x1825, 0x2073, 0x0000, 0x7840, 0x0026, 0x0016, 0x2009, 0x00f7,
-	0x080c, 0x5c73, 0x001e, 0x9094, 0x0010, 0x9285, 0x0080, 0x7842,
-	0x7a42, 0x002e, 0x012e, 0x00fe, 0x00ee, 0x0005, 0x0126, 0x2091,
-	0x8000, 0x080c, 0x27dd, 0x0228, 0x2011, 0x0101, 0x2204, 0xc0c5,
-	0x2012, 0x2011, 0x19cc, 0x2013, 0x0000, 0x708f, 0x0000, 0x012e,
-	0x60a3, 0x0056, 0x60a7, 0x9575, 0x080c, 0x8fc3, 0x6144, 0xd184,
-	0x0120, 0x7194, 0x918d, 0x2000, 0x0018, 0x7188, 0x918d, 0x1000,
-	0x2011, 0x1971, 0x2112, 0x2009, 0x07d0, 0x2011, 0x5b5c, 0x080c,
-	0x8230, 0x0005, 0x0016, 0x0026, 0x00c6, 0x0126, 0x2091, 0x8000,
-	0x080c, 0x98c7, 0x080c, 0x9b6c, 0x080c, 0x98e3, 0x2009, 0x00f7,
-	0x080c, 0x5c73, 0x2061, 0x19db, 0x900e, 0x611a, 0x611e, 0x6172,
-	0x6176, 0x2061, 0x1800, 0x6003, 0x0001, 0x2061, 0x0100, 0x6043,
-	0x0090, 0x6043, 0x0010, 0x2009, 0x1971, 0x200b, 0x0000, 0x2009,
-	0x002d, 0x2011, 0x5be2, 0x080c, 0x8160, 0x012e, 0x00ce, 0x002e,
-	0x001e, 0x0005, 0x00e6, 0x0006, 0x0126, 0x2091, 0x8000, 0x0471,
-	0x2071, 0x0100, 0x080c, 0x8fd0, 0x2071, 0x0140, 0x7004, 0x9084,
-	0x4000, 0x0110, 0x080c, 0x2882, 0x080c, 0x70c2, 0x0188, 0x080c,
-	0x70dd, 0x1170, 0x080c, 0x73c3, 0x0016, 0x080c, 0x2571, 0x2001,
-	0x1945, 0x2102, 0x001e, 0x080c, 0x73be, 0x080c, 0x6feb, 0x0050,
-	0x2009, 0x0001, 0x080c, 0x285e, 0x2001, 0x0001, 0x080c, 0x23fe,
-	0x080c, 0x5bb2, 0x012e, 0x000e, 0x00ee, 0x0005, 0x2001, 0x180e,
-	0x2004, 0xd0bc, 0x0158, 0x0026, 0x0036, 0x2011, 0x8017, 0x2001,
-	0x1971, 0x201c, 0x080c, 0x48fa, 0x003e, 0x002e, 0x0005, 0x20a9,
-	0x0012, 0x20e9, 0x0001, 0x20a1, 0x1d80, 0x080c, 0x5cd1, 0x20e9,
-	0x0000, 0x2099, 0x026e, 0x0099, 0x20a9, 0x0020, 0x080c, 0x5ccb,
-	0x2099, 0x0260, 0x20a1, 0x1d92, 0x0051, 0x20a9, 0x000e, 0x080c,
-	0x5cce, 0x2099, 0x0260, 0x20a1, 0x1db2, 0x0009, 0x0005, 0x0016,
-	0x0026, 0x3410, 0x3308, 0x2104, 0x8007, 0x2012, 0x8108, 0x8210,
-	0x1f04, 0x5c4b, 0x002e, 0x001e, 0x0005, 0x080c, 0x97f4, 0x20e1,
-	0x0001, 0x2099, 0x1d00, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9,
-	0x000c, 0x4003, 0x0005, 0x080c, 0x97f4, 0x080c, 0x5cd1, 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, 0x6686, 0x0158, 0x9006,
-	0x2020, 0x2009, 0x002a, 0x080c, 0xd2bc, 0x2001, 0x180c, 0x200c,
-	0xc195, 0x2102, 0x2019, 0x002a, 0x900e, 0x080c, 0x2ff3, 0x080c,
-	0xbf8f, 0x0140, 0x0036, 0x2019, 0xffff, 0x2021, 0x0007, 0x080c,
-	0x4a97, 0x003e, 0x004e, 0x001e, 0x0005, 0x080c, 0x5bb2, 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, 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, 0x197e, 0x0118, 0x2003,
-	0x0001, 0x0010, 0x2003, 0x0000, 0x0005, 0x0156, 0x20a9, 0x0800,
-	0x2009, 0x1000, 0x9006, 0x200a, 0x8108, 0x1f04, 0x5d0b, 0x015e,
-	0x0005, 0x00d6, 0x0036, 0x0156, 0x0136, 0x0146, 0x2069, 0x185b,
-	0x9006, 0xb802, 0xb8c6, 0xb807, 0x0707, 0xb80a, 0xb80e, 0xb812,
-	0x9198, 0x319f, 0x231d, 0x939c, 0x00ff, 0xbb16, 0x0016, 0x0026,
-	0xb886, 0x080c, 0x9b65, 0x1120, 0x9192, 0x007e, 0x1208, 0xbb86,
-	0x20a9, 0x0004, 0xb8b4, 0x20e8, 0xb9b8, 0x9198, 0x0006, 0x9006,
-	0x23a0, 0x4004, 0x20a9, 0x0004, 0x9198, 0x000a, 0x23a0, 0x4004,
-	0x002e, 0x001e, 0xb83e, 0xb842, 0xb8be, 0xb8c2, 0xb85e, 0xb862,
-	0xb866, 0xb86a, 0xb86f, 0x0100, 0xb872, 0xb876, 0xb87a, 0xb88a,
-	0xb88e, 0xb893, 0x0008, 0xb896, 0xb89a, 0xb89e, 0xb8ae, 0xb9a2,
-	0x0096, 0xb8a4, 0x904d, 0x0110, 0x080c, 0x1061, 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, 0x5dcf, 0x9182, 0x0800, 0x1a04, 0x5dd3,
-	0x2001, 0x180c, 0x2004, 0x9084, 0x0003, 0x1904, 0x5dd9, 0x9188,
-	0x1000, 0x2104, 0x905d, 0x0198, 0xb804, 0x9084, 0x00ff, 0x908e,
-	0x0006, 0x1188, 0xb8a4, 0x900d, 0x1904, 0x5deb, 0x080c, 0x6149,
-	0x9006, 0x012e, 0x0005, 0x2001, 0x0005, 0x900e, 0x04b8, 0x2001,
-	0x0028, 0x900e, 0x0498, 0x9082, 0x0006, 0x1290, 0x080c, 0x9b65,
-	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, 0x668a, 0x1990, 0xb800, 0xd0bc,
-	0x0978, 0x0804, 0x5d92, 0x080c, 0x64fe, 0x0904, 0x5d9b, 0x0804,
-	0x5d96, 0x00e6, 0x2071, 0x19bf, 0x7004, 0x9086, 0x0002, 0x1128,
-	0x7030, 0x9080, 0x0004, 0x2004, 0x9b06, 0x00ee, 0x0005, 0x00b6,
-	0x00e6, 0x0126, 0x2091, 0x8000, 0xa974, 0x9182, 0x0800, 0x1a04,
-	0x5e7a, 0x9188, 0x1000, 0x2104, 0x905d, 0x0904, 0x5e52, 0xb8a0,
-	0x9086, 0x007f, 0x0178, 0x080c, 0x6692, 0x0160, 0xa994, 0x81ff,
-	0x0130, 0x908e, 0x0004, 0x0130, 0x908e, 0x0005, 0x0118, 0x080c,
-	0x668a, 0x1598, 0xa87c, 0xd0fc, 0x01e0, 0xa894, 0x9005, 0x01c8,
-	0x2060, 0x0026, 0x2010, 0x080c, 0xb85e, 0x002e, 0x1120, 0x2001,
-	0x0008, 0x0804, 0x5e7c, 0x6020, 0x9086, 0x000a, 0x0120, 0x2001,
-	0x0008, 0x0804, 0x5e7c, 0x601a, 0x6003, 0x0008, 0x2900, 0x6016,
-	0x0058, 0x080c, 0x9b90, 0x05e8, 0x2b00, 0x6012, 0x2900, 0x6016,
-	0x600b, 0xffff, 0x6023, 0x000a, 0x2009, 0x0003, 0x080c, 0x9c82,
-	0x9006, 0x0458, 0x2001, 0x0028, 0x0438, 0x9082, 0x0006, 0x1290,
-	0x080c, 0x9b65, 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, 0x5f11, 0x5ecc, 0x5ee3, 0x5f11,
-	0x5f11, 0x5f11, 0x5f11, 0x5f11, 0x2100, 0x9082, 0x007e, 0x1278,
-	0x080c, 0x622f, 0x0148, 0x9046, 0xb810, 0x9306, 0x1904, 0x5f19,
-	0xb814, 0x9206, 0x15f0, 0x0028, 0xbb12, 0xba16, 0x0010, 0x080c,
-	0x47b4, 0x0150, 0x04b0, 0x080c, 0x628f, 0x1598, 0xb810, 0x9306,
-	0x1580, 0xb814, 0x9206, 0x1568, 0x080c, 0x9b90, 0x0530, 0x2b00,
-	0x6012, 0x080c, 0xbd09, 0x2900, 0x6016, 0x600b, 0xffff, 0x6023,
-	0x000a, 0xa878, 0x9086, 0x0001, 0x1170, 0x080c, 0x302e, 0x9006,
-	0x080c, 0x61cc, 0x2001, 0x0002, 0x080c, 0x61e0, 0x2001, 0x0200,
-	0xb86e, 0xb893, 0x0002, 0x2009, 0x0003, 0x080c, 0x9c82, 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, 0x60f2, 0x90c6, 0x0056, 0x0904,
-	0x60f6, 0x90c6, 0x0066, 0x0904, 0x60fa, 0x90c6, 0x0067, 0x0904,
-	0x60fe, 0x90c6, 0x0068, 0x0904, 0x6102, 0x90c6, 0x0071, 0x0904,
-	0x6106, 0x90c6, 0x0074, 0x0904, 0x610a, 0x90c6, 0x007c, 0x0904,
-	0x610e, 0x90c6, 0x007e, 0x0904, 0x6112, 0x90c6, 0x0037, 0x0904,
-	0x6116, 0x9016, 0x2079, 0x1800, 0xa974, 0x9186, 0x00ff, 0x0904,
-	0x60ed, 0x9182, 0x0800, 0x1a04, 0x60ed, 0x080c, 0x628f, 0x1198,
-	0xb804, 0x9084, 0x00ff, 0x9082, 0x0006, 0x1268, 0xa894, 0x90c6,
-	0x006f, 0x0148, 0x080c, 0x9b65, 0x1904, 0x60d6, 0xb8a0, 0x9084,
-	0xff80, 0x1904, 0x60d6, 0xa894, 0x90c6, 0x006f, 0x0158, 0x90c6,
-	0x005e, 0x0904, 0x6036, 0x90c6, 0x0064, 0x0904, 0x605f, 0x2008,
-	0x0804, 0x5ff9, 0xa998, 0xa8b0, 0x2040, 0x080c, 0x9b65, 0x1120,
-	0x9182, 0x007f, 0x0a04, 0x5ff9, 0x9186, 0x00ff, 0x0904, 0x5ff9,
-	0x9182, 0x0800, 0x1a04, 0x5ff9, 0xaaa0, 0xab9c, 0x7878, 0x9306,
-	0x11a8, 0x787c, 0x0096, 0x924e, 0x1128, 0x2208, 0x2310, 0x009e,
-	0x0804, 0x5ff9, 0x080c, 0x9b65, 0x1140, 0x99cc, 0xff00, 0x009e,
-	0x1128, 0x2208, 0x2310, 0x0804, 0x5ff9, 0x009e, 0x080c, 0x47b4,
-	0x0904, 0x6002, 0x900e, 0x9016, 0x90c6, 0x4000, 0x1558, 0x0006,
-	0x080c, 0x6582, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d,
-	0x20a9, 0x0004, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0031, 0x20a0,
-	0xb8b4, 0x20e0, 0xb8b8, 0x9080, 0x0006, 0x2098, 0x080c, 0x0fac,
-	0x20a9, 0x0004, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0035, 0x20a0,
-	0xb8b4, 0x20e0, 0xb8b8, 0x9080, 0x000a, 0x2098, 0x080c, 0x0fac,
-	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, 0x9b90, 0x1130, 0x2001, 0x4005, 0x2009,
-	0x0003, 0x9016, 0x0c80, 0x2b00, 0x6012, 0x080c, 0xbd09, 0x2900,
-	0x6016, 0x6023, 0x0001, 0xa868, 0xd88c, 0x0108, 0xc0f5, 0xa86a,
-	0x0126, 0x2091, 0x8000, 0x080c, 0x302e, 0x012e, 0x9006, 0x080c,
-	0x61cc, 0x2001, 0x0002, 0x080c, 0x61e0, 0x2009, 0x0002, 0x080c,
-	0x9c82, 0xa8b0, 0xd094, 0x0118, 0xb8c4, 0xc08d, 0xb8c6, 0x9006,
-	0x9005, 0x012e, 0x00ee, 0x00fe, 0x00be, 0x0005, 0x080c, 0x53bc,
-	0x0118, 0x2009, 0x0007, 0x00f8, 0xa998, 0xaeb0, 0x080c, 0x628f,
-	0x1904, 0x5ff4, 0x9186, 0x007f, 0x0130, 0x080c, 0x668a, 0x0118,
-	0x2009, 0x0009, 0x0080, 0x0096, 0x080c, 0x102f, 0x1120, 0x009e,
-	0x2009, 0x0002, 0x0040, 0x2900, 0x009e, 0xa806, 0x080c, 0xba5c,
-	0x19b0, 0x2009, 0x0003, 0x2001, 0x4005, 0x0804, 0x5ffb, 0xa998,
-	0xaeb0, 0x080c, 0x628f, 0x1904, 0x5ff4, 0x0096, 0x080c, 0x102f,
-	0x1128, 0x009e, 0x2009, 0x0002, 0x0804, 0x60b3, 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, 0x0fac, 0x009e, 0xa87b, 0x0000, 0xa883, 0x0000,
-	0xa897, 0x4000, 0xd684, 0x1168, 0x080c, 0x53a8, 0xd0b4, 0x1118,
-	0xa89b, 0x000b, 0x00e0, 0xb800, 0xd08c, 0x0118, 0xa89b, 0x000c,
-	0x00b0, 0x080c, 0x668a, 0x0118, 0xa89b, 0x0009, 0x0080, 0x080c,
-	0x53bc, 0x0118, 0xa89b, 0x0007, 0x0050, 0x080c, 0xba3f, 0x1904,
-	0x602f, 0x2009, 0x0003, 0x2001, 0x4005, 0x0804, 0x5ffb, 0xa87b,
-	0x0030, 0xa897, 0x4005, 0xa804, 0x8006, 0x8006, 0x8007, 0x90bc,
-	0x003f, 0x9084, 0xffc0, 0x9080, 0x0002, 0x2009, 0x002b, 0xaaa0,
-	0xab9c, 0xaca8, 0xada4, 0x2031, 0x0000, 0x2041, 0x127e, 0x080c,
-	0xa0f3, 0x1904, 0x602f, 0x2009, 0x0002, 0x08e8, 0x2001, 0x0028,
-	0x900e, 0x0804, 0x6030, 0x2009, 0x180c, 0x210c, 0xd18c, 0x0118,
-	0x2001, 0x0004, 0x0038, 0xd184, 0x0118, 0x2001, 0x0004, 0x0010,
-	0x2001, 0x0029, 0x900e, 0x0804, 0x6030, 0x2001, 0x0029, 0x900e,
-	0x0804, 0x6030, 0x080c, 0x35cd, 0x0804, 0x6031, 0x080c, 0x50dd,
-	0x0804, 0x6031, 0x080c, 0x4373, 0x0804, 0x6031, 0x080c, 0x43ec,
-	0x0804, 0x6031, 0x080c, 0x4448, 0x0804, 0x6031, 0x080c, 0x4870,
-	0x0804, 0x6031, 0x080c, 0x4b15, 0x0804, 0x6031, 0x080c, 0x4d48,
-	0x0804, 0x6031, 0x080c, 0x4f41, 0x0804, 0x6031, 0x080c, 0x37e2,
-	0x0804, 0x6031, 0x00b6, 0xa974, 0xae78, 0x9684, 0x3fff, 0x9082,
-	0x4000, 0x1608, 0x9182, 0x0800, 0x1258, 0x9188, 0x1000, 0x2104,
-	0x905d, 0x0130, 0x080c, 0x668a, 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, 0xb8c0, 0x9005, 0x1904, 0x61c0, 0xb888,
-	0x9005, 0x1904, 0x61c0, 0xb838, 0xb93c, 0x9102, 0x1a04, 0x61c0,
-	0x2b10, 0x080c, 0x9bbd, 0x0904, 0x61bc, 0x8108, 0xb93e, 0x6212,
-	0x2900, 0x6016, 0x6023, 0x0003, 0x600b, 0xffff, 0x6007, 0x0040,
-	0xa878, 0x605e, 0xa880, 0x9084, 0x00ff, 0x6066, 0xa883, 0x0000,
-	0xa87c, 0xd0ac, 0x05c0, 0xc0dd, 0xa87e, 0xa888, 0x8001, 0x1568,
-	0x2001, 0x00f8, 0x8001, 0xa001, 0xa001, 0xa001, 0x1dd8, 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, 0x1669, 0x601c,
-	0xc0bd, 0x601e, 0x0c38, 0x0006, 0x2001, 0x00e8, 0x8001, 0xa001,
-	0xa001, 0xa001, 0x1dd8, 0x000e, 0xd0b4, 0x190c, 0x1af7, 0x2001,
-	0x8004, 0x6003, 0x0002, 0x08d0, 0x81ff, 0x1110, 0xb88b, 0x0001,
-	0x2908, 0xb8bc, 0xb9be, 0x9005, 0x1110, 0xb9c2, 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,
-	0x6686, 0x0140, 0x9284, 0xff00, 0x8007, 0x9086, 0x0007, 0x1110,
-	0x2011, 0x0600, 0x000e, 0x9294, 0xff00, 0x9215, 0xba06, 0x0006,
-	0x9086, 0x0006, 0x1120, 0xba90, 0x82ff, 0x090c, 0x0d65, 0x000e,
-	0x00ce, 0x012e, 0x00be, 0x0005, 0x00b6, 0x0126, 0x00c6, 0x2091,
-	0x8000, 0x6210, 0x2258, 0xba04, 0x0006, 0x9086, 0x0006, 0x1168,
-	0xb89c, 0xd0a4, 0x0150, 0x080c, 0x6682, 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, 0x102f, 0x2958,
-	0x009e, 0x0160, 0x2b00, 0x2012, 0xb85c, 0xb8ba, 0xb860, 0xb8b6,
-	0x9006, 0xb8a6, 0x080c, 0x5d11, 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, 0x1061, 0x00d6, 0x00c6, 0xb8ac, 0x2060,
-	0x8cff, 0x0168, 0x600c, 0x0006, 0x6014, 0x2048, 0x080c, 0xb870,
-	0x0110, 0x080c, 0x0fe1, 0x080c, 0x9be6, 0x00ce, 0x0c88, 0x00ce,
-	0x00de, 0x2b48, 0xb8b8, 0xb85e, 0xb8b4, 0xb862, 0x080c, 0x1071,
-	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, 0x70ba, 0x1510, 0xb8a0, 0x9086, 0x007e, 0x0120, 0x080c,
-	0x9b65, 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, 0xbbc4, 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,
-	0xbbc6, 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, 0x0d65, 0x3c00,
-	0x20e8, 0x3300, 0x8001, 0x20a0, 0x4604, 0x8210, 0xaa06, 0x01de,
-	0x01ce, 0x014e, 0x013e, 0x0060, 0x080c, 0x102f, 0x0170, 0x2900,
-	0xb8a6, 0xa803, 0x0000, 0x080c, 0x651e, 0xa807, 0x0001, 0xae12,
-	0x9085, 0x0001, 0x012e, 0x009e, 0x0005, 0x9006, 0x0cd8, 0x0126,
-	0x2091, 0x8000, 0x0096, 0xb8a4, 0x904d, 0x0188, 0xa800, 0x9005,
-	0x1150, 0x080c, 0x652d, 0x1158, 0xa804, 0x908a, 0x0002, 0x0218,
-	0x8001, 0xa806, 0x0020, 0x080c, 0x1061, 0xb8a7, 0x0000, 0x009e,
-	0x012e, 0x0005, 0x0096, 0x00c6, 0xb888, 0x9005, 0x1904, 0x6413,
-	0xb8c0, 0x904d, 0x0904, 0x6413, 0x080c, 0x9bbd, 0x0904, 0x640f,
-	0x8210, 0xba3e, 0xa800, 0xb8c2, 0x9005, 0x1108, 0xb8be, 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, 0x1af7, 0x2001,
-	0x8004, 0x6003, 0x0002, 0x6046, 0x2001, 0x0010, 0x2c08, 0x080c,
-	0x98b8, 0xb838, 0xba3c, 0x9202, 0x0a04, 0x63c0, 0x0020, 0x82ff,
-	0x1110, 0xb88b, 0x0001, 0x00ce, 0x009e, 0x0005, 0x080c, 0x1669,
-	0x601c, 0xc0bd, 0x601e, 0x08e0, 0x00b6, 0x0096, 0x0016, 0x20a9,
-	0x0800, 0x900e, 0x0016, 0x080c, 0x628f, 0x1158, 0xb8c0, 0x904d,
-	0x0140, 0x3e00, 0x9086, 0x0002, 0x1118, 0xb800, 0xd0bc, 0x1108,
-	0x0041, 0x001e, 0x8108, 0x1f04, 0x6422, 0x001e, 0x00be, 0x009e,
-	0x0005, 0x0096, 0x0016, 0xb8c0, 0x904d, 0x0188, 0xa800, 0xb8c2,
-	0x9005, 0x1108, 0xb8be, 0x9006, 0xa802, 0xa867, 0x0103, 0xab7a,
-	0xa877, 0x0000, 0x080c, 0xbb73, 0x080c, 0x69b5, 0x0c60, 0x001e,
-	0x009e, 0x0005, 0x0086, 0x9046, 0xb8c0, 0x904d, 0x01b0, 0xa86c,
-	0x9406, 0x1118, 0xa870, 0x9506, 0x0128, 0x2940, 0xa800, 0x904d,
-	0x0160, 0x0ca8, 0xa800, 0x88ff, 0x1128, 0xb8c2, 0x9005, 0x1118,
-	0xb8be, 0x0008, 0xa002, 0xa803, 0x0000, 0x008e, 0x0005, 0x901e,
-	0x0010, 0x2019, 0x0001, 0x0126, 0x2091, 0x8000, 0x00e6, 0x0096,
-	0x00c6, 0x0086, 0x0026, 0x2071, 0x19bf, 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,
-	0x9127, 0x006e, 0x000e, 0x83ff, 0x0508, 0x0c08, 0x9046, 0xb8c0,
-	0x904d, 0x01e0, 0x83ff, 0x0120, 0xa878, 0x9606, 0x0158, 0x0030,
-	0xa86c, 0x9406, 0x1118, 0xa870, 0x9506, 0x0120, 0x2940, 0xa800,
-	0x2048, 0x0c70, 0xb8c0, 0xaa00, 0x0026, 0x9906, 0x1110, 0xbac2,
-	0x0008, 0xa202, 0x000e, 0x83ff, 0x0108, 0x0c10, 0x002e, 0x008e,
-	0x00ce, 0x009e, 0x00ee, 0x012e, 0x0005, 0x9016, 0x0489, 0x1110,
-	0x2011, 0x0001, 0x0005, 0x080c, 0x6582, 0x0128, 0x080c, 0xb931,
-	0x0010, 0x9085, 0x0001, 0x0005, 0x080c, 0x6582, 0x0128, 0x080c,
-	0xb8d2, 0x0010, 0x9085, 0x0001, 0x0005, 0x080c, 0x6582, 0x0128,
-	0x080c, 0xb92e, 0x0010, 0x9085, 0x0001, 0x0005, 0x080c, 0x6582,
-	0x0128, 0x080c, 0xb8f1, 0x0010, 0x9085, 0x0001, 0x0005, 0x080c,
-	0x6582, 0x0128, 0x080c, 0xb972, 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, 0x102f, 0x0168, 0x2900, 0xb8a6, 0x080c, 0x651e, 0xa803,
-	0x0001, 0xa807, 0x0000, 0x9085, 0x0001, 0x012e, 0x009e, 0x0005,
-	0x9006, 0x0cd8, 0x0096, 0x0126, 0x2091, 0x8000, 0xb8a4, 0x904d,
-	0x0130, 0xb8a7, 0x0000, 0x080c, 0x1061, 0x9085, 0x0001, 0x012e,
-	0x009e, 0x0005, 0xb89c, 0xd0a4, 0x0005, 0x00b6, 0x00f6, 0x080c,
-	0x70ba, 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, 0x628f, 0x1168, 0xb804, 0x9084, 0xff00, 0x8007,
-	0x9096, 0x0004, 0x0118, 0x9086, 0x0006, 0x1118, 0xb800, 0xc0ed,
-	0xb802, 0x001e, 0x8108, 0x1f04, 0x65a8, 0x015e, 0x080c, 0x6648,
-	0x0120, 0x2001, 0x195d, 0x200c, 0x0030, 0x2079, 0x185b, 0x7804,
-	0x0030, 0x2009, 0x07d0, 0x2011, 0x65d2, 0x080c, 0x8230, 0x00fe,
-	0x00be, 0x0005, 0x00b6, 0x2011, 0x65d2, 0x080c, 0x816c, 0x080c,
-	0x6648, 0x01d8, 0x2001, 0x107e, 0x2004, 0x2058, 0xb900, 0xc1ec,
-	0xb902, 0x080c, 0x6686, 0x0130, 0x2009, 0x07d0, 0x2011, 0x65d2,
-	0x080c, 0x8230, 0x00e6, 0x2071, 0x1800, 0x9006, 0x707a, 0x705c,
-	0x707e, 0x080c, 0x2e09, 0x00ee, 0x04d0, 0x0156, 0x00c6, 0x20a9,
-	0x007f, 0x900e, 0x0016, 0x080c, 0x628f, 0x1558, 0xb800, 0xd0ec,
-	0x0540, 0x0046, 0xbaa0, 0x2220, 0x9006, 0x2009, 0x0029, 0x080c,
-	0xd2bc, 0xb800, 0xc0e5, 0xc0ec, 0xb802, 0x080c, 0x6682, 0x2001,
-	0x0707, 0x1128, 0xb804, 0x9084, 0x00ff, 0x9085, 0x0700, 0xb806,
-	0x080c, 0x98c7, 0x2019, 0x0029, 0x080c, 0x8658, 0x0076, 0x903e,
-	0x080c, 0x853d, 0x900e, 0x080c, 0xd011, 0x007e, 0x004e, 0x080c,
-	0x98e3, 0x001e, 0x8108, 0x1f04, 0x65fa, 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, 0x0d65,
-	0x000e, 0xba00, 0x9005, 0x0110, 0xc2fd, 0x0008, 0xc2fc, 0xba02,
-	0x002e, 0x012e, 0x0005, 0x2011, 0x1836, 0x2204, 0xd0cc, 0x0138,
-	0x2001, 0x195b, 0x200c, 0x2011, 0x6678, 0x080c, 0x8230, 0x0005,
-	0x2011, 0x6678, 0x080c, 0x816c, 0x2011, 0x1836, 0x2204, 0xc0cc,
-	0x2012, 0x0005, 0x080c, 0x53a8, 0xd0ac, 0x0005, 0x080c, 0x53a8,
-	0xd0a4, 0x0005, 0x0016, 0xb904, 0x9184, 0x00ff, 0x908e, 0x0006,
-	0x001e, 0x0005, 0x0016, 0xb904, 0x9184, 0xff00, 0x8007, 0x908e,
-	0x0006, 0x001e, 0x0005, 0x00b6, 0x00f6, 0x080c, 0xbf8f, 0x0158,
-	0x70d8, 0x9084, 0x0028, 0x0138, 0x2001, 0x107f, 0x2004, 0x905d,
-	0x0110, 0xb8c4, 0xd094, 0x00fe, 0x00be, 0x0005, 0x0006, 0x0016,
-	0x0036, 0x0046, 0x0076, 0x00b6, 0x2001, 0x1817, 0x203c, 0x9780,
-	0x319f, 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, 0x319f, 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, 0x53a8, 0xd0fc, 0x1140, 0x080c, 0x53a8, 0x900e,
-	0xd09c, 0x0108, 0x8108, 0x7102, 0x0400, 0x2001, 0x187b, 0x200c,
-	0x9184, 0x0007, 0x9006, 0x0002, 0x675d, 0x675d, 0x675d, 0x675d,
-	0x675d, 0x6774, 0x6782, 0x675d, 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, 0x742b, 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, 0x69ba, 0xa87c, 0xd0bc,
-	0x1904, 0x69ba, 0xa978, 0xa874, 0x9105, 0x1904, 0x69ba, 0x2001,
-	0x1921, 0x2004, 0x0002, 0x69ba, 0x680e, 0x684a, 0x684a, 0x69ba,
-	0x684a, 0x0005, 0xa868, 0xd0fc, 0x1500, 0x00e6, 0x0026, 0x2009,
-	0x1921, 0x210c, 0x81ff, 0x0904, 0x69ba, 0xa87c, 0xd0cc, 0x0904,
-	0x69ba, 0xa880, 0x9084, 0x00ff, 0x9086, 0x0001, 0x1904, 0x69ba,
-	0x9186, 0x0003, 0x0904, 0x684a, 0x9186, 0x0005, 0x0904, 0x684a,
-	0xa84f, 0x8021, 0xa853, 0x0017, 0x0028, 0x0005, 0xa84f, 0x8020,
-	0xa853, 0x0016, 0x2071, 0x190e, 0x701c, 0x9005, 0x1904, 0x6b51,
-	0x0e04, 0x6b9c, 0x2071, 0x0000, 0xa84c, 0x7082, 0xa850, 0x7032,
-	0xa86c, 0x7086, 0x7036, 0xa870, 0x708a, 0x2091, 0x4080, 0x2001,
-	0x0089, 0x2004, 0xd084, 0x190c, 0x11d6, 0x2071, 0x1800, 0x2011,
-	0x0001, 0xa804, 0x900d, 0x702c, 0x1158, 0xa802, 0x2900, 0x702e,
-	0x70bc, 0x9200, 0x70be, 0x080c, 0x8087, 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, 0x693f, 0x782c,
-	0x908c, 0x0780, 0x190c, 0x6cc3, 0x8004, 0x8004, 0x8004, 0x9084,
-	0x0003, 0x0002, 0x6868, 0x693f, 0x688d, 0x68da, 0x080c, 0x0d65,
-	0x2071, 0x1800, 0x2900, 0x7822, 0xa804, 0x900d, 0x1170, 0x2071,
-	0x19db, 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, 0x8087, 0x0c10, 0x2071, 0x1800, 0x2900,
-	0x7822, 0xa804, 0x900d, 0x15a8, 0x7824, 0x00e6, 0x2071, 0x0040,
-	0x712c, 0xd19c, 0x1170, 0x2009, 0x182f, 0x210c, 0x918a, 0x0040,
-	0x0240, 0x7022, 0x2001, 0x1dc0, 0x200c, 0x8108, 0x2102, 0x00ee,
-	0x0058, 0x00ee, 0x2048, 0x702c, 0xa802, 0x2900, 0x702e, 0x70bc,
-	0x8000, 0x70be, 0x080c, 0x8087, 0x782c, 0x9094, 0x0780, 0x190c,
-	0x6cc3, 0xd0a4, 0x19c8, 0x2071, 0x19db, 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, 0x8087,
-	0x0804, 0x6894, 0x0096, 0x00e6, 0x7824, 0x2048, 0x2071, 0x1800,
-	0x702c, 0xa802, 0x2900, 0x702e, 0x70bc, 0x8000, 0x70be, 0x080c,
-	0x8087, 0x782c, 0x9094, 0x0780, 0x190c, 0x6cc3, 0xd0a4, 0x1d60,
-	0x00ee, 0x782c, 0x9094, 0x0780, 0x190c, 0x6cc3, 0xd09c, 0x11a0,
-	0x009e, 0x2900, 0x7822, 0xa804, 0x900d, 0x1560, 0x2071, 0x19db,
-	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, 0x19db, 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, 0x8087, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x2908,
-	0x7010, 0x8000, 0x7012, 0x7018, 0x904d, 0x711a, 0x0110, 0xa902,
-	0x0008, 0x711e, 0x2148, 0xa804, 0x900d, 0x1904, 0x6994, 0x782c,
-	0x9094, 0x0780, 0x190c, 0x6cc3, 0xd09c, 0x1198, 0x701c, 0x904d,
-	0x0180, 0x7010, 0x8001, 0x7012, 0x1108, 0x701a, 0xa800, 0x701e,
-	0x2900, 0x7822, 0x782c, 0x9094, 0x0780, 0x190c, 0x6cc3, 0xd09c,
-	0x0d68, 0x782c, 0x9094, 0x0780, 0x190c, 0x6cc3, 0xd0a4, 0x01b0,
-	0x00e6, 0x7824, 0x2048, 0x2071, 0x1800, 0x702c, 0xa802, 0x2900,
-	0x702e, 0x70bc, 0x8000, 0x70be, 0x080c, 0x8087, 0x782c, 0x9094,
-	0x0780, 0x190c, 0x6cc3, 0xd0a4, 0x1d60, 0x00ee, 0x2071, 0x19db,
-	0x703c, 0x9005, 0x1328, 0x2001, 0x1922, 0x2004, 0x8005, 0x703e,
-	0x00fe, 0x002e, 0x00ee, 0x0005, 0x00e6, 0x2071, 0x1800, 0x9016,
-	0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8,
-	0x702e, 0x70bc, 0x9200, 0x70be, 0x080c, 0x8087, 0x00ee, 0x0804,
-	0x694f, 0xa868, 0xd0fc, 0x1560, 0x0096, 0xa804, 0xa807, 0x0000,
-	0x904d, 0x190c, 0x0fe1, 0x009e, 0x0018, 0xa868, 0xd0fc, 0x1500,
-	0x00e6, 0x0026, 0xa84f, 0x0000, 0x00f6, 0x2079, 0x0050, 0x2071,
-	0x190e, 0xa803, 0x0000, 0x7010, 0x9005, 0x1904, 0x6acf, 0x782c,
-	0x908c, 0x0780, 0x190c, 0x6cc3, 0x8004, 0x8004, 0x8004, 0x9084,
-	0x0003, 0x0002, 0x69d9, 0x6acf, 0x69f4, 0x6a62, 0x080c, 0x0d65,
-	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, 0x8087, 0x0c60, 0x2071, 0x1800, 0x2900, 0x7822,
-	0xa804, 0x900d, 0x1904, 0x6a51, 0x7830, 0xd0dc, 0x1120, 0x00fe,
-	0x002e, 0x00ee, 0x0005, 0x7824, 0x00e6, 0x2071, 0x0040, 0x712c,
-	0xd19c, 0x1170, 0x2009, 0x182f, 0x210c, 0x918a, 0x0040, 0x0240,
-	0x7022, 0x2001, 0x1dc0, 0x200c, 0x8108, 0x2102, 0x00ee, 0x0058,
-	0x00ee, 0x2048, 0x702c, 0xa802, 0x2900, 0x702e, 0x70bc, 0x8000,
-	0x70be, 0x080c, 0x8087, 0x782c, 0x9094, 0x0780, 0x190c, 0x6cc3,
-	0xd0a4, 0x19c8, 0x0e04, 0x6a48, 0x7838, 0x7938, 0x910e, 0x1de0,
-	0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, 0x2001,
-	0x191f, 0x200c, 0xc184, 0x2102, 0x2091, 0x4080, 0x2001, 0x0089,
-	0x2004, 0xd084, 0x190c, 0x11d6, 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, 0x8087,
-	0x0804, 0x6a03, 0x0096, 0x00e6, 0x7824, 0x2048, 0x2071, 0x1800,
-	0x702c, 0xa802, 0x2900, 0x702e, 0x70bc, 0x8000, 0x70be, 0x080c,
-	0x8087, 0x782c, 0x9094, 0x0780, 0x190c, 0x6cc3, 0xd0a4, 0x1d60,
-	0x00ee, 0x0e04, 0x6aa2, 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6,
-	0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, 0x7044, 0xc084,
-	0x7046, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c,
-	0x11d6, 0x782c, 0x9094, 0x0780, 0x190c, 0x6cc3, 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, 0x8087, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x2908,
-	0x7010, 0x8000, 0x7012, 0x7018, 0x904d, 0x711a, 0x0110, 0xa902,
-	0x0008, 0x711e, 0x2148, 0xa804, 0x900d, 0x1904, 0x6b3c, 0x782c,
-	0x9094, 0x0780, 0x190c, 0x6cc3, 0xd09c, 0x11b0, 0x701c, 0x904d,
-	0x0198, 0xa84c, 0x9005, 0x1180, 0x7010, 0x8001, 0x7012, 0x1108,
-	0x701a, 0xa800, 0x701e, 0x2900, 0x7822, 0x782c, 0x9094, 0x0780,
-	0x190c, 0x6cc3, 0xd09c, 0x0d50, 0x782c, 0x9094, 0x0780, 0x190c,
-	0x6cc3, 0xd0a4, 0x05a8, 0x00e6, 0x7824, 0x2048, 0x2071, 0x1800,
-	0x702c, 0xa802, 0x2900, 0x702e, 0x70bc, 0x8000, 0x70be, 0x080c,
-	0x8087, 0x782c, 0x9094, 0x0780, 0x190c, 0x6cc3, 0xd0a4, 0x1d60,
-	0x00ee, 0x0e04, 0x6b35, 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6,
-	0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, 0x7044, 0xc084,
-	0x7046, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c,
-	0x11d6, 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, 0x8087, 0x00ee, 0x0804,
-	0x6adf, 0x2071, 0x190e, 0xa803, 0x0000, 0x2908, 0x7010, 0x8000,
-	0x7012, 0x7018, 0x904d, 0x711a, 0x0110, 0xa902, 0x0008, 0x711e,
-	0x2148, 0xa804, 0x900d, 0x1128, 0x1e04, 0x6b7c, 0x002e, 0x00ee,
-	0x0005, 0x2071, 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802,
-	0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70bc, 0x9200, 0x70be,
-	0x080c, 0x8087, 0x0e04, 0x6b66, 0x2071, 0x190e, 0x701c, 0x2048,
-	0xa84c, 0x900d, 0x0d18, 0x2071, 0x0000, 0x7182, 0xa850, 0x7032,
-	0xa86c, 0x7086, 0x7036, 0xa870, 0x708a, 0x2091, 0x4080, 0x2001,
-	0x0089, 0x2004, 0xd084, 0x190c, 0x11d6, 0x2071, 0x190e, 0x080c,
-	0x6caf, 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, 0x8087, 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, 0x6be7, 0x6be8, 0x6cae, 0x6be8, 0x0d65, 0x6cae, 0x0005,
-	0x2001, 0x1921, 0x2004, 0x0002, 0x6bf2, 0x6bf2, 0x6c47, 0x6c48,
-	0x6bf2, 0x6c48, 0x0126, 0x2091, 0x8000, 0x1e0c, 0x6cce, 0x701c,
-	0x904d, 0x01e0, 0xa84c, 0x9005, 0x01d8, 0x0e04, 0x6c16, 0xa94c,
-	0x2071, 0x0000, 0x7182, 0xa850, 0x7032, 0xa86c, 0x7086, 0x7036,
-	0xa870, 0x708a, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084,
-	0x190c, 0x11d6, 0x2071, 0x190e, 0x080c, 0x6caf, 0x012e, 0x0470,
-	0x2001, 0x005b, 0x2004, 0x9094, 0x0780, 0x190c, 0x6cc3, 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, 0x19db, 0x683c, 0x9005, 0x0760, 0x0158,
-	0x9186, 0x0003, 0x0540, 0x2001, 0x1814, 0x2004, 0x2009, 0x1b25,
-	0x210c, 0x9102, 0x1500, 0x0126, 0x2091, 0x8000, 0x2069, 0x0050,
-	0x693c, 0x6838, 0x9106, 0x0190, 0x0e04, 0x6c7a, 0x2069, 0x0000,
-	0x6837, 0x8040, 0x6833, 0x0012, 0x6883, 0x8040, 0x2091, 0x4080,
-	0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11d6, 0x2069, 0x19db,
-	0x683f, 0xffff, 0x012e, 0x00de, 0x0126, 0x2091, 0x8000, 0x1e0c,
-	0x6d34, 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, 0x1061,
-	0x0005, 0x012e, 0x0005, 0x2091, 0x8000, 0x0e04, 0x6cc5, 0x0006,
-	0x0016, 0x2001, 0x8004, 0x0006, 0x0804, 0x0d6e, 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, 0x11d6, 0x00fe, 0x009e, 0x0005, 0x782c, 0x9094, 0x0780,
-	0x1991, 0xd0a4, 0x0db8, 0x00e6, 0x2071, 0x1800, 0x7824, 0x00e6,
-	0x2071, 0x0040, 0x712c, 0xd19c, 0x1170, 0x2009, 0x182f, 0x210c,
-	0x918a, 0x0040, 0x0240, 0x7022, 0x2001, 0x1dc0, 0x200c, 0x8108,
-	0x2102, 0x00ee, 0x0058, 0x00ee, 0x2048, 0x702c, 0xa802, 0x2900,
-	0x702e, 0x70bc, 0x8000, 0x70be, 0x080c, 0x8087, 0x782c, 0x9094,
-	0x0780, 0x190c, 0x6cc3, 0xd0a4, 0x19c8, 0x7838, 0x7938, 0x910e,
-	0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de,
-	0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11d6,
-	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, 0x11d6, 0x00fe,
-	0x0005, 0x782c, 0x9094, 0x0780, 0x190c, 0x6cc3, 0xd0a4, 0x0db8,
-	0x00e6, 0x2071, 0x1800, 0x7824, 0x2048, 0x702c, 0xa802, 0x2900,
-	0x702e, 0x70bc, 0x8000, 0x70be, 0x080c, 0x8087, 0x782c, 0x9094,
-	0x0780, 0x190c, 0x6cc3, 0xd0a4, 0x1d70, 0x00d6, 0x2069, 0x0050,
-	0x693c, 0x2069, 0x1921, 0x6808, 0x690a, 0x2069, 0x19db, 0x9102,
-	0x1118, 0x683c, 0x9005, 0x1328, 0x2001, 0x1922, 0x200c, 0x810d,
-	0x693e, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x7094, 0x908a, 0x0029,
-	0x1a0c, 0x0d65, 0x9082, 0x001d, 0x003b, 0x0026, 0x2011, 0x1e00,
-	0x080c, 0x28ac, 0x002e, 0x0005, 0x6e60, 0x6de6, 0x6e02, 0x6e2c,
-	0x6e4f, 0x6e8f, 0x6ea1, 0x6e02, 0x6e77, 0x6da1, 0x6dcf, 0x6da0,
-	0x0005, 0x00d6, 0x2069, 0x0200, 0x6804, 0x9005, 0x1180, 0x6808,
-	0x9005, 0x1518, 0x7097, 0x0028, 0x2069, 0x1967, 0x2d04, 0x7002,
-	0x080c, 0x71fa, 0x6028, 0x9085, 0x0600, 0x602a, 0x00b0, 0x7097,
-	0x0028, 0x2069, 0x1967, 0x2d04, 0x7002, 0x6028, 0x9085, 0x0600,
-	0x602a, 0x00e6, 0x0036, 0x0046, 0x0056, 0x2071, 0x1a43, 0x080c,
-	0x1989, 0x005e, 0x004e, 0x003e, 0x00ee, 0x00de, 0x0005, 0x00d6,
-	0x2069, 0x0200, 0x6804, 0x9005, 0x1178, 0x6808, 0x9005, 0x1160,
-	0x7097, 0x0028, 0x2069, 0x1967, 0x2d04, 0x7002, 0x080c, 0x729c,
-	0x6028, 0x9085, 0x0600, 0x602a, 0x00de, 0x0005, 0x0006, 0x2001,
-	0x0090, 0x080c, 0x2872, 0x000e, 0x6124, 0xd1e4, 0x1190, 0x080c,
-	0x6f12, 0xd1d4, 0x1160, 0xd1dc, 0x1138, 0xd1cc, 0x0150, 0x7097,
-	0x0020, 0x080c, 0x6f12, 0x0028, 0x7097, 0x001d, 0x0010, 0x7097,
-	0x001f, 0x0005, 0x2001, 0x0088, 0x080c, 0x2872, 0x6124, 0xd1cc,
-	0x11e8, 0xd1dc, 0x11c0, 0xd1e4, 0x1198, 0x9184, 0x1e00, 0x11d8,
-	0x080c, 0x19ae, 0x60e3, 0x0001, 0x600c, 0xc0b4, 0x600e, 0x080c,
-	0x70e6, 0x2001, 0x0080, 0x080c, 0x2872, 0x7097, 0x0028, 0x0058,
-	0x7097, 0x001e, 0x0040, 0x7097, 0x001d, 0x0028, 0x7097, 0x0020,
-	0x0010, 0x7097, 0x001f, 0x0005, 0x080c, 0x19ae, 0x60e3, 0x0001,
-	0x600c, 0xc0b4, 0x600e, 0x080c, 0x70e6, 0x2001, 0x0080, 0x080c,
-	0x2872, 0x6124, 0xd1d4, 0x1180, 0xd1dc, 0x1158, 0xd1e4, 0x1130,
-	0x9184, 0x1e00, 0x1158, 0x7097, 0x0028, 0x0040, 0x7097, 0x001e,
-	0x0028, 0x7097, 0x001d, 0x0010, 0x7097, 0x001f, 0x0005, 0x2001,
-	0x00a0, 0x080c, 0x2872, 0x6124, 0xd1dc, 0x1138, 0xd1e4, 0x0138,
-	0x080c, 0x19ae, 0x7097, 0x001e, 0x0010, 0x7097, 0x001d, 0x0005,
-	0x080c, 0x6f9b, 0x6124, 0xd1dc, 0x1188, 0x080c, 0x6f12, 0x0016,
-	0x080c, 0x19ae, 0x001e, 0xd1d4, 0x1128, 0xd1e4, 0x0138, 0x7097,
-	0x001e, 0x0020, 0x7097, 0x001f, 0x080c, 0x6f12, 0x0005, 0x0006,
-	0x2001, 0x00a0, 0x080c, 0x2872, 0x000e, 0x6124, 0xd1d4, 0x1160,
-	0xd1cc, 0x1150, 0xd1dc, 0x1128, 0xd1e4, 0x0140, 0x7097, 0x001e,
-	0x0028, 0x7097, 0x001d, 0x0010, 0x7097, 0x0021, 0x0005, 0x080c,
-	0x6f9b, 0x6124, 0xd1d4, 0x1150, 0xd1dc, 0x1128, 0xd1e4, 0x0140,
-	0x7097, 0x001e, 0x0028, 0x7097, 0x001d, 0x0010, 0x7097, 0x001f,
-	0x0005, 0x0006, 0x2001, 0x0090, 0x080c, 0x2872, 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, 0x70ba, 0x11f8, 0x2001, 0x180c, 0x200c, 0xd1b4,
-	0x01d0, 0xc1b4, 0x2102, 0x0026, 0x2011, 0x0200, 0x080c, 0x28ac,
-	0x002e, 0x080c, 0x2858, 0x6024, 0xd0cc, 0x0148, 0x2001, 0x00a0,
-	0x080c, 0x2872, 0x080c, 0x73b9, 0x080c, 0x5cf7, 0x0428, 0x6028,
-	0xc0cd, 0x602a, 0x0408, 0x080c, 0x70d4, 0x0150, 0x080c, 0x70cb,
-	0x1138, 0x2001, 0x0001, 0x080c, 0x23fe, 0x080c, 0x708e, 0x00a0,
-	0x080c, 0x6f98, 0x0178, 0x2001, 0x0001, 0x080c, 0x23fe, 0x7094,
-	0x9086, 0x001e, 0x0120, 0x7094, 0x9086, 0x0022, 0x1118, 0x7097,
-	0x0025, 0x0010, 0x7097, 0x0021, 0x012e, 0x00ee, 0x00de, 0x00ce,
-	0x001e, 0x0005, 0x0026, 0x2011, 0x6f23, 0x080c, 0x8272, 0x002e,
-	0x0016, 0x0026, 0x2009, 0x0064, 0x2011, 0x6f23, 0x080c, 0x8269,
-	0x002e, 0x001e, 0x0005, 0x00e6, 0x00f6, 0x0016, 0x080c, 0x8fd0,
-	0x2071, 0x1800, 0x080c, 0x6ebc, 0x001e, 0x00fe, 0x00ee, 0x0005,
-	0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x0126,
-	0x080c, 0x8fd0, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0x1800,
-	0x2091, 0x8000, 0x6028, 0xc09c, 0x602a, 0x080c, 0x98c7, 0x2011,
-	0x0003, 0x080c, 0x9324, 0x2011, 0x0002, 0x080c, 0x932e, 0x080c,
-	0x921d, 0x080c, 0x821e, 0x0036, 0x901e, 0x080c, 0x929d, 0x003e,
-	0x080c, 0x98e3, 0x60e3, 0x0000, 0x080c, 0xd644, 0x080c, 0xd65f,
-	0x2009, 0x0004, 0x080c, 0x285e, 0x080c, 0x2774, 0x2001, 0x1800,
-	0x2003, 0x0004, 0x2011, 0x0008, 0x080c, 0x28ac, 0x2011, 0x6f23,
-	0x080c, 0x8272, 0x080c, 0x70d4, 0x0118, 0x9006, 0x080c, 0x2872,
-	0x080c, 0x0bab, 0x2001, 0x0001, 0x080c, 0x23fe, 0x012e, 0x00fe,
-	0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e, 0x0005, 0x0026,
-	0x00e6, 0x2011, 0x6f30, 0x2071, 0x19db, 0x701c, 0x9206, 0x1118,
-	0x7018, 0x9005, 0x0110, 0x9085, 0x0001, 0x00ee, 0x002e, 0x0005,
-	0x6020, 0xd09c, 0x0005, 0x6800, 0x9084, 0xfffe, 0x9086, 0x00c0,
-	0x01b8, 0x2001, 0x00c0, 0x080c, 0x2872, 0x0156, 0x20a9, 0x002d,
-	0x1d04, 0x6fa8, 0x2091, 0x6000, 0x1f04, 0x6fa8, 0x015e, 0x00d6,
-	0x2069, 0x1800, 0x6898, 0x8001, 0x0220, 0x0118, 0x689a, 0x00de,
-	0x0005, 0x689b, 0x0014, 0x68e8, 0xd0dc, 0x0dc8, 0x6800, 0x9086,
-	0x0001, 0x1da8, 0x080c, 0x827e, 0x0c90, 0x00c6, 0x00d6, 0x00e6,
-	0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0x1800, 0x080c, 0x73c8,
-	0x2001, 0x1945, 0x2003, 0x0000, 0x9006, 0x7096, 0x60e2, 0x6886,
-	0x080c, 0x24cd, 0x9006, 0x080c, 0x2872, 0x080c, 0x5bb2, 0x0026,
-	0x2011, 0xffff, 0x080c, 0x28ac, 0x002e, 0x602b, 0x182c, 0x00ee,
-	0x00de, 0x00ce, 0x0005, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100,
-	0x2069, 0x0140, 0x2071, 0x1800, 0x2001, 0x1955, 0x200c, 0x9186,
-	0x0000, 0x0158, 0x9186, 0x0001, 0x0158, 0x9186, 0x0002, 0x0158,
-	0x9186, 0x0003, 0x0158, 0x0804, 0x707e, 0x7097, 0x0022, 0x0040,
-	0x7097, 0x0021, 0x0028, 0x7097, 0x0023, 0x0010, 0x7097, 0x0024,
-	0x60e3, 0x0000, 0x6887, 0x0001, 0x2001, 0x0001, 0x080c, 0x24cd,
-	0x080c, 0x98c7, 0x0026, 0x080c, 0x9b6c, 0x002e, 0x080c, 0x98e3,
-	0x7000, 0x908e, 0x0004, 0x0118, 0x602b, 0x0028, 0x0010, 0x602b,
-	0x0020, 0x0156, 0x0126, 0x2091, 0x8000, 0x20a9, 0x0005, 0x6024,
-	0xd0ac, 0x0150, 0x012e, 0x015e, 0x080c, 0xbf8f, 0x0118, 0x9006,
-	0x080c, 0x289c, 0x0804, 0x708a, 0x6800, 0x9084, 0x00a1, 0xc0bd,
-	0x6802, 0x080c, 0x2858, 0x6904, 0xd1d4, 0x1140, 0x2001, 0x0100,
-	0x080c, 0x2872, 0x1f04, 0x702f, 0x080c, 0x7111, 0x012e, 0x015e,
-	0x080c, 0x70cb, 0x0170, 0x6044, 0x9005, 0x0130, 0x080c, 0x7111,
-	0x9006, 0x8001, 0x1df0, 0x0028, 0x6804, 0xd0d4, 0x1110, 0x080c,
-	0x7111, 0x080c, 0xbf8f, 0x0118, 0x9006, 0x080c, 0x289c, 0x0016,
-	0x0026, 0x7000, 0x908e, 0x0004, 0x0130, 0x2009, 0x00c8, 0x2011,
-	0x6f30, 0x080c, 0x8230, 0x002e, 0x001e, 0x080c, 0x807e, 0x7034,
-	0xc085, 0x7036, 0x2001, 0x1955, 0x2003, 0x0004, 0x080c, 0x6d85,
-	0x080c, 0x70cb, 0x0138, 0x6804, 0xd0d4, 0x1120, 0xd0dc, 0x1100,
-	0x080c, 0x73be, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x00c6, 0x00d6,
-	0x00e6, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0x1800, 0x080c,
-	0x8095, 0x080c, 0x8087, 0x080c, 0x73c8, 0x2001, 0x1945, 0x2003,
-	0x0000, 0x9006, 0x7096, 0x60e2, 0x6886, 0x080c, 0x24cd, 0x9006,
-	0x080c, 0x2872, 0x6043, 0x0090, 0x6043, 0x0010, 0x0026, 0x2011,
-	0xffff, 0x080c, 0x28ac, 0x002e, 0x602b, 0x182c, 0x00ee, 0x00de,
-	0x00ce, 0x0005, 0x0006, 0x2001, 0x1954, 0x2004, 0x9086, 0xaaaa,
-	0x000e, 0x0005, 0x0006, 0x080c, 0x53ac, 0x9084, 0x0030, 0x9086,
-	0x0000, 0x000e, 0x0005, 0x0006, 0x080c, 0x53ac, 0x9084, 0x0030,
-	0x9086, 0x0030, 0x000e, 0x0005, 0x0006, 0x080c, 0x53ac, 0x9084,
-	0x0030, 0x9086, 0x0010, 0x000e, 0x0005, 0x0006, 0x080c, 0x53ac,
-	0x9084, 0x0030, 0x9086, 0x0020, 0x000e, 0x0005, 0x0036, 0x0016,
-	0x2001, 0x180c, 0x2004, 0x908c, 0x0013, 0x0180, 0x0020, 0x080c,
-	0x24ed, 0x900e, 0x0028, 0x080c, 0x6682, 0x1dc8, 0x2009, 0x0002,
-	0x2019, 0x0028, 0x080c, 0x2ff3, 0x9006, 0x0019, 0x001e, 0x003e,
-	0x0005, 0x00e6, 0x2071, 0x180c, 0x2e04, 0x0130, 0x080c, 0xbf88,
-	0x1128, 0x9085, 0x0010, 0x0010, 0x9084, 0xffef, 0x2072, 0x00ee,
-	0x0005, 0x6050, 0x0006, 0x60ec, 0x0006, 0x600c, 0x0006, 0x6004,
-	0x0006, 0x6028, 0x0006, 0x080c, 0x28cf, 0x080c, 0x2902, 0x602f,
-	0x0100, 0x602f, 0x0000, 0x602f, 0x0040, 0x602f, 0x0000, 0x20a9,
-	0x0002, 0x080c, 0x2839, 0x0026, 0x2011, 0x0040, 0x080c, 0x28ac,
-	0x002e, 0x000e, 0x602a, 0x000e, 0x6006, 0x000e, 0x600e, 0x000e,
-	0x60ee, 0x60e3, 0x0000, 0x6887, 0x0001, 0x2001, 0x0001, 0x080c,
-	0x24cd, 0x2001, 0x00a0, 0x0006, 0x080c, 0xbf8f, 0x000e, 0x0130,
-	0x080c, 0x2890, 0x9006, 0x080c, 0x289c, 0x0010, 0x080c, 0x2872,
-	0x000e, 0x6052, 0x6050, 0x0006, 0xc0e5, 0x6052, 0x00f6, 0x2079,
-	0x0100, 0x080c, 0x27e5, 0x00fe, 0x000e, 0x6052, 0x0005, 0x0156,
-	0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100,
-	0x2069, 0x0140, 0x2071, 0x1800, 0x080c, 0x9925, 0x0158, 0x2001,
-	0x0386, 0x2004, 0xd0b4, 0x1130, 0x2001, 0x0016, 0x080c, 0x98b8,
-	0x0804, 0x71ec, 0x2001, 0x180c, 0x200c, 0xc1c4, 0x2102, 0x6028,
-	0x9084, 0xe1ff, 0x602a, 0x2011, 0x0200, 0x080c, 0x28ac, 0x2001,
-	0x0090, 0x080c, 0x2872, 0x20a9, 0x0366, 0x6024, 0xd0cc, 0x1558,
-	0x1d04, 0x718d, 0x2091, 0x6000, 0x1f04, 0x718d, 0x080c, 0x98c7,
-	0x2011, 0x0003, 0x080c, 0x9324, 0x2011, 0x0002, 0x080c, 0x932e,
-	0x080c, 0x921d, 0x901e, 0x080c, 0x929d, 0x2001, 0x0386, 0x2003,
-	0x7000, 0x080c, 0x98e3, 0x2001, 0x00a0, 0x080c, 0x2872, 0x080c,
-	0x73b9, 0x080c, 0x5cf7, 0x080c, 0xbf8f, 0x0110, 0x080c, 0x0cd1,
-	0x9085, 0x0001, 0x04b8, 0x080c, 0x19ae, 0x60e3, 0x0000, 0x2001,
-	0x0002, 0x080c, 0x24cd, 0x60e2, 0x2001, 0x0080, 0x080c, 0x2872,
-	0x20a9, 0x0366, 0x2011, 0x1e00, 0x080c, 0x28ac, 0x2009, 0x1e00,
-	0x080c, 0x2858, 0x6024, 0x910c, 0x0140, 0x1d04, 0x71ca, 0x2091,
-	0x6000, 0x1f04, 0x71ca, 0x0804, 0x7196, 0x2001, 0x0386, 0x2003,
-	0x7000, 0x6028, 0x9085, 0x1e00, 0x602a, 0x70b0, 0x9005, 0x1118,
-	0x6887, 0x0001, 0x0008, 0x6886, 0x080c, 0xbf8f, 0x0110, 0x080c,
-	0x0cd1, 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, 0x1a4e, 0x2d04, 0x8000, 0x206a, 0x2069, 0x0140,
-	0x6020, 0x9084, 0x00c0, 0x0120, 0x6884, 0x9005, 0x1904, 0x7263,
-	0x2001, 0x0088, 0x080c, 0x2872, 0x9006, 0x60e2, 0x6886, 0x080c,
-	0x24cd, 0x2069, 0x0200, 0x6804, 0x9005, 0x1118, 0x6808, 0x9005,
-	0x01d0, 0x6028, 0x9084, 0xfbff, 0x602a, 0x2011, 0x0400, 0x080c,
-	0x28ac, 0x2069, 0x1967, 0x7000, 0x206a, 0x7097, 0x0026, 0x7003,
-	0x0001, 0x20a9, 0x0002, 0x1d04, 0x7243, 0x2091, 0x6000, 0x1f04,
-	0x7243, 0x0804, 0x7294, 0x2069, 0x0140, 0x20a9, 0x0384, 0x2011,
-	0x1e00, 0x080c, 0x28ac, 0x2009, 0x1e00, 0x080c, 0x2858, 0x6024,
-	0x910c, 0x0528, 0x9084, 0x1a00, 0x1510, 0x1d04, 0x724f, 0x2091,
-	0x6000, 0x1f04, 0x724f, 0x080c, 0x98c7, 0x2011, 0x0003, 0x080c,
-	0x9324, 0x2011, 0x0002, 0x080c, 0x932e, 0x080c, 0x921d, 0x901e,
-	0x080c, 0x929d, 0x080c, 0x98e3, 0x2001, 0x00a0, 0x080c, 0x2872,
-	0x080c, 0x73b9, 0x080c, 0x5cf7, 0x9085, 0x0001, 0x00a8, 0x2001,
-	0x0080, 0x080c, 0x2872, 0x2069, 0x0140, 0x60e3, 0x0000, 0x70b0,
-	0x9005, 0x1118, 0x6887, 0x0001, 0x0008, 0x6886, 0x2001, 0x0002,
-	0x080c, 0x24cd, 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, 0x98c7, 0x2011, 0x0003, 0x080c,
-	0x9324, 0x2011, 0x0002, 0x080c, 0x932e, 0x080c, 0x921d, 0x901e,
-	0x080c, 0x929d, 0x080c, 0x98e3, 0x2069, 0x0140, 0x2001, 0x00a0,
-	0x080c, 0x2872, 0x080c, 0x73b9, 0x080c, 0x5cf7, 0x0804, 0x7336,
-	0x2001, 0x180c, 0x200c, 0xd1b4, 0x1160, 0xc1b5, 0x2102, 0x080c,
-	0x6f18, 0x2069, 0x0140, 0x2001, 0x0080, 0x080c, 0x2872, 0x60e3,
-	0x0000, 0x2069, 0x0200, 0x6804, 0x9005, 0x1118, 0x6808, 0x9005,
-	0x0190, 0x6028, 0x9084, 0xfdff, 0x602a, 0x2011, 0x0200, 0x080c,
-	0x28ac, 0x2069, 0x1967, 0x7000, 0x206a, 0x7097, 0x0027, 0x7003,
-	0x0001, 0x0804, 0x7336, 0x2011, 0x1e00, 0x080c, 0x28ac, 0x2009,
-	0x1e00, 0x080c, 0x2858, 0x6024, 0x910c, 0x01c8, 0x9084, 0x1c00,
-	0x11b0, 0x1d04, 0x72f3, 0x0006, 0x0016, 0x00c6, 0x00d6, 0x00e6,
-	0x080c, 0x80c6, 0x00ee, 0x00de, 0x00ce, 0x001e, 0x000e, 0x00e6,
-	0x2071, 0x19db, 0x7070, 0x00ee, 0x9005, 0x19e8, 0x00f8, 0x0026,
-	0x2011, 0x6f30, 0x080c, 0x816c, 0x2011, 0x6f23, 0x080c, 0x8272,
-	0x002e, 0x2069, 0x0140, 0x60e3, 0x0000, 0x70b0, 0x9005, 0x1118,
-	0x6887, 0x0001, 0x0008, 0x6886, 0x2001, 0x0002, 0x080c, 0x24cd,
-	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, 0xbf88, 0x1904, 0x73a3, 0x7130, 0xd184, 0x1170,
-	0x080c, 0x319a, 0x0138, 0xc18d, 0x7132, 0x2011, 0x185c, 0x2214,
-	0xd2ac, 0x1120, 0x7030, 0xd08c, 0x0904, 0x73a3, 0x2011, 0x185c,
-	0x220c, 0x0438, 0x0016, 0x2019, 0x000e, 0x080c, 0xd234, 0x0156,
-	0x00b6, 0x20a9, 0x007f, 0x900e, 0x9186, 0x007e, 0x01a0, 0x9186,
-	0x0080, 0x0188, 0x080c, 0x628f, 0x1170, 0x2120, 0x9006, 0x0016,
-	0x2009, 0x000e, 0x080c, 0xd2bc, 0x2009, 0x0001, 0x2011, 0x0100,
-	0x080c, 0x8401, 0x001e, 0x8108, 0x1f04, 0x736c, 0x00be, 0x015e,
-	0x001e, 0xd1ac, 0x1148, 0x0016, 0x2009, 0x0002, 0x2019, 0x0004,
-	0x080c, 0x2ff3, 0x001e, 0x0078, 0x0156, 0x00b6, 0x20a9, 0x007f,
-	0x900e, 0x080c, 0x628f, 0x1110, 0x080c, 0x5d11, 0x8108, 0x1f04,
-	0x7399, 0x00be, 0x015e, 0x080c, 0x19ae, 0x080c, 0x98c7, 0x080c,
-	0x9b6c, 0x080c, 0x98e3, 0x60e3, 0x0000, 0x080c, 0x5cf7, 0x080c,
-	0x6feb, 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, 0x1048, 0x090c, 0x0d65, 0xa8ab,
-	0xdcb0, 0x2900, 0x704e, 0x080c, 0x1048, 0x090c, 0x0d65, 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, 0x79c6,
-	0x9006, 0x00ee, 0x0005, 0x900e, 0x0156, 0x20a9, 0x0006, 0x8003,
-	0x818d, 0x1f04, 0x742f, 0x015e, 0x0005, 0x2079, 0x0040, 0x2071,
-	0x18f8, 0x7004, 0x0002, 0x7445, 0x7446, 0x7492, 0x74ed, 0x762e,
-	0x7443, 0x7443, 0x7658, 0x080c, 0x0d65, 0x0005, 0x2079, 0x0040,
-	0x2001, 0x1dc0, 0x2003, 0x0000, 0x782c, 0x908c, 0x0780, 0x190c,
-	0x7a52, 0xd0a4, 0x0578, 0x2001, 0x1dc0, 0x2004, 0x9082, 0x0080,
-	0x1648, 0x1d04, 0x7463, 0x2001, 0x19de, 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, 0x7482,
-	0x744c, 0x7482, 0x7480, 0x7482, 0x7482, 0x7482, 0x7482, 0x7482,
-	0x080c, 0x74ed, 0x782c, 0xd09c, 0x090c, 0x79c6, 0x0005, 0x9082,
-	0x005a, 0x1218, 0x2100, 0x003b, 0x0c10, 0x080c, 0x7523, 0x0c90,
-	0x00e3, 0x08e8, 0x0005, 0x7523, 0x7523, 0x7523, 0x7523, 0x7523,
-	0x7523, 0x7523, 0x7523, 0x7545, 0x7523, 0x7523, 0x7523, 0x7523,
-	0x7523, 0x7523, 0x7523, 0x7523, 0x7523, 0x7523, 0x7523, 0x7523,
-	0x7523, 0x7523, 0x7523, 0x7523, 0x7523, 0x7523, 0x7523, 0x752f,
-	0x7523, 0x772d, 0x7523, 0x7523, 0x7523, 0x7545, 0x7523, 0x752f,
-	0x776e, 0x77af, 0x77f6, 0x780a, 0x7523, 0x7523, 0x7545, 0x752f,
-	0x7523, 0x7523, 0x7602, 0x78b5, 0x78d0, 0x7523, 0x7545, 0x7523,
-	0x7523, 0x7523, 0x7523, 0x75f8, 0x78d0, 0x7523, 0x7523, 0x7523,
-	0x7523, 0x7523, 0x7523, 0x7523, 0x7523, 0x7523, 0x7559, 0x7523,
-	0x7523, 0x7523, 0x7523, 0x7523, 0x7523, 0x7523, 0x7523, 0x7523,
-	0x79f6, 0x7523, 0x7523, 0x7523, 0x7523, 0x7523, 0x756d, 0x7523,
-	0x7523, 0x7523, 0x7523, 0x7523, 0x7523, 0x2079, 0x0040, 0x7004,
-	0x9086, 0x0003, 0x1198, 0x782c, 0x080c, 0x79ef, 0xd0a4, 0x0170,
-	0x7824, 0x2048, 0x9006, 0xa802, 0xa806, 0xa864, 0x9084, 0x00ff,
-	0x908a, 0x001a, 0x1210, 0x002b, 0x0c50, 0x00e9, 0x080c, 0x79c6,
-	0x0005, 0x7523, 0x752f, 0x7719, 0x7523, 0x752f, 0x7523, 0x752f,
-	0x752f, 0x7523, 0x752f, 0x7719, 0x752f, 0x752f, 0x752f, 0x752f,
-	0x752f, 0x7523, 0x752f, 0x7719, 0x7523, 0x7523, 0x752f, 0x7523,
-	0x7523, 0x7523, 0x752f, 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, 0x69b5, 0x012e, 0x0005, 0xa864, 0x8007, 0x9084,
-	0x00ff, 0x0d08, 0x8001, 0x1120, 0x7007, 0x0001, 0x0804, 0x76d7,
-	0x7007, 0x0003, 0x7012, 0x2900, 0x7016, 0x701a, 0x704b, 0x76d7,
-	0x0005, 0xa864, 0x8007, 0x9084, 0x00ff, 0x0968, 0x8001, 0x1120,
-	0x7007, 0x0001, 0x0804, 0x76f2, 0x7007, 0x0003, 0x7012, 0x2900,
-	0x7016, 0x701a, 0x704b, 0x76f2, 0x0005, 0xa864, 0x8007, 0x9084,
-	0x00ff, 0x9086, 0x0001, 0x1904, 0x752b, 0x7007, 0x0001, 0x2009,
-	0x1833, 0x210c, 0x81ff, 0x1904, 0x75cf, 0xa994, 0x9186, 0x006f,
-	0x0188, 0x9186, 0x0074, 0x15b0, 0x0026, 0x2011, 0x0010, 0x080c,
-	0x66ae, 0x002e, 0x0578, 0x0016, 0xa998, 0x080c, 0x66f8, 0x001e,
-	0x1548, 0x0400, 0x080c, 0x70ba, 0x0140, 0xa897, 0x4005, 0xa89b,
-	0x0016, 0x2001, 0x0030, 0x900e, 0x0438, 0x0026, 0x2011, 0x8008,
-	0x080c, 0x66ae, 0x002e, 0x01b0, 0x0016, 0x0026, 0x0036, 0xa998,
-	0xaaa0, 0xab9c, 0x918d, 0x8000, 0x080c, 0x66f8, 0x003e, 0x002e,
-	0x001e, 0x1140, 0xa897, 0x4005, 0xa89b, 0x4009, 0x2001, 0x0030,
-	0x900e, 0x0050, 0xa868, 0x9084, 0x00ff, 0xa86a, 0xa883, 0x0000,
-	0x080c, 0x5f22, 0x1108, 0x0005, 0x0126, 0x2091, 0x8000, 0xa867,
-	0x0139, 0xa87a, 0xa982, 0x080c, 0x69b5, 0x012e, 0x0ca0, 0xa994,
-	0x9186, 0x0071, 0x0904, 0x757d, 0x9186, 0x0064, 0x0904, 0x757d,
-	0x9186, 0x007c, 0x0904, 0x757d, 0x9186, 0x0028, 0x0904, 0x757d,
-	0x9186, 0x0038, 0x0904, 0x757d, 0x9186, 0x0078, 0x0904, 0x757d,
-	0x9186, 0x005f, 0x0904, 0x757d, 0x9186, 0x0056, 0x0904, 0x757d,
-	0xa897, 0x4005, 0xa89b, 0x0001, 0x2001, 0x0030, 0x900e, 0x0860,
-	0xa87c, 0x9084, 0x00c0, 0x9086, 0x00c0, 0x1120, 0x7007, 0x0001,
-	0x0804, 0x78e7, 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, 0x7533, 0xaab4, 0x928a, 0x0002, 0x1a04,
-	0x7533, 0x82ff, 0x1138, 0xa8b8, 0xa9bc, 0x9105, 0x0118, 0x2001,
-	0x7695, 0x0018, 0x9280, 0x768b, 0x2005, 0x7056, 0x7010, 0x9015,
-	0x0904, 0x7676, 0x080c, 0x1048, 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, 0x1124,
-	0xa06c, 0x908e, 0x0100, 0x0170, 0x9086, 0x0200, 0x0118, 0x7007,
-	0x0007, 0x0005, 0x7020, 0x2048, 0x080c, 0x1061, 0x7014, 0x2048,
-	0x0804, 0x7533, 0x7020, 0x2048, 0x7018, 0xa802, 0xa807, 0x0000,
-	0x2908, 0x2048, 0xa906, 0x711a, 0x0804, 0x762e, 0x7014, 0x2048,
-	0x7007, 0x0001, 0xa8b4, 0x9005, 0x1128, 0xa8b8, 0xa9bc, 0x9105,
-	0x0108, 0x00b9, 0xa864, 0x9084, 0x00ff, 0x9086, 0x001e, 0x0904,
-	0x78e7, 0x0804, 0x76d7, 0x768d, 0x7691, 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, 0x5d71, 0x1108, 0x0005,
-	0x080c, 0x6bc6, 0x0126, 0x2091, 0x8000, 0x080c, 0xbb73, 0x080c,
-	0x69b5, 0x012e, 0x0ca0, 0x080c, 0xbf88, 0x1d70, 0x2001, 0x0028,
-	0x900e, 0x0c70, 0x2009, 0x1833, 0x210c, 0x81ff, 0x11d8, 0xa888,
-	0x9005, 0x01e0, 0xa883, 0x0000, 0xa87c, 0xd0f4, 0x0120, 0x080c,
-	0x5e84, 0x1138, 0x0005, 0x9006, 0xa87a, 0x080c, 0x5dff, 0x1108,
-	0x0005, 0x0126, 0x2091, 0x8000, 0xa87a, 0xa982, 0x080c, 0x69b5,
-	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, 0x628f, 0x11b8,
-	0x0066, 0xae80, 0x080c, 0x639f, 0x006e, 0x0088, 0x0046, 0x2011,
-	0x180c, 0x2224, 0xc484, 0x2412, 0x004e, 0x00c6, 0x080c, 0x628f,
-	0x1110, 0x080c, 0x6572, 0x8108, 0x1f04, 0x7756, 0x00ce, 0xa87c,
-	0xd084, 0x1120, 0x080c, 0x1061, 0x00be, 0x0005, 0x0126, 0x2091,
-	0x8000, 0x080c, 0x69b5, 0x012e, 0x00be, 0x0005, 0x0126, 0x2091,
-	0x8000, 0x7007, 0x0001, 0x080c, 0x6686, 0x0580, 0x2061, 0x1a46,
-	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, 0x79b0, 0x012e, 0x0804,
-	0x79aa, 0x012e, 0x0804, 0x79a4, 0x012e, 0x0804, 0x79a7, 0x0126,
-	0x2091, 0x8000, 0x7007, 0x0001, 0x080c, 0x6686, 0x05e0, 0x2061,
-	0x1a46, 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, 0x79b0,
-	0x012e, 0x0804, 0x79ad, 0x012e, 0x0804, 0x79aa, 0x0126, 0x2091,
-	0x8000, 0x7007, 0x0001, 0x2061, 0x1a46, 0x6300, 0xd38c, 0x1120,
-	0x6308, 0x8318, 0x0220, 0x630a, 0x012e, 0x0804, 0x79be, 0x012e,
-	0x0804, 0x79ad, 0x00b6, 0x0126, 0x00c6, 0x2091, 0x8000, 0x7007,
-	0x0001, 0xa87c, 0xd0ac, 0x0148, 0x00c6, 0x2061, 0x1a46, 0x6000,
-	0x9084, 0xfcff, 0x6002, 0x00ce, 0x0440, 0xa888, 0x9005, 0x05d8,
-	0xa88c, 0x9065, 0x0598, 0x2001, 0x1833, 0x2004, 0x9005, 0x0118,
-	0x080c, 0x9c20, 0x0068, 0x6017, 0xf400, 0x6063, 0x0000, 0xa97c,
-	0xd1a4, 0x0110, 0xa980, 0x6162, 0x2009, 0x0041, 0x080c, 0x9c82,
-	0xa988, 0x918c, 0xff00, 0x9186, 0x2000, 0x1138, 0x0026, 0x900e,
-	0x2011, 0xfdff, 0x080c, 0x8401, 0x002e, 0xa87c, 0xd0c4, 0x0148,
-	0x2061, 0x1a46, 0x6000, 0xd08c, 0x1120, 0x6008, 0x8000, 0x0208,
-	0x600a, 0x00ce, 0x012e, 0x00be, 0x0804, 0x79b0, 0x00ce, 0x012e,
-	0x00be, 0x0804, 0x79aa, 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, 0x628f, 0x1968,
-	0xb800, 0xc0e4, 0xb802, 0x0848, 0xa88c, 0x9065, 0x09b8, 0x6007,
-	0x0024, 0x2001, 0x195e, 0x2004, 0x601a, 0x0804, 0x7845, 0xa88c,
-	0x9065, 0x0960, 0x00e6, 0xa890, 0x9075, 0x2001, 0x1833, 0x2004,
-	0x9005, 0x0150, 0x080c, 0x9c20, 0x8eff, 0x0118, 0x2e60, 0x080c,
-	0x9c20, 0x00ee, 0x0804, 0x7845, 0x6024, 0xc0dc, 0xc0d5, 0x6026,
-	0x2e60, 0x6007, 0x003a, 0xa8a0, 0x9005, 0x0130, 0x6007, 0x003b,
-	0xa8a4, 0x602e, 0xa8a8, 0x6016, 0x6003, 0x0001, 0x2009, 0x8020,
-	0x080c, 0x84e7, 0x00ee, 0x0804, 0x7845, 0x2061, 0x1a46, 0x6000,
-	0xd084, 0x0190, 0xd08c, 0x1904, 0x79be, 0x0126, 0x2091, 0x8000,
-	0x6204, 0x8210, 0x0220, 0x6206, 0x012e, 0x0804, 0x79be, 0x012e,
-	0xa883, 0x0016, 0x0804, 0x79b7, 0xa883, 0x0007, 0x0804, 0x79b7,
-	0xa864, 0x8007, 0x9084, 0x00ff, 0x0130, 0x8001, 0x1138, 0x7007,
-	0x0001, 0x0069, 0x0005, 0x080c, 0x752b, 0x0040, 0x7007, 0x0003,
-	0x7012, 0x2900, 0x7016, 0x701a, 0x704b, 0x78e7, 0x0005, 0x00b6,
-	0x00e6, 0x0126, 0x2091, 0x8000, 0x903e, 0x2061, 0x1800, 0x61cc,
-	0x81ff, 0x1904, 0x7969, 0x6130, 0xd194, 0x1904, 0x7993, 0xa878,
-	0x2070, 0x9e82, 0x1ddc, 0x0a04, 0x795d, 0x6064, 0x9e02, 0x1a04,
-	0x795d, 0x7120, 0x9186, 0x0006, 0x1904, 0x794f, 0x7010, 0x905d,
-	0x0904, 0x7969, 0xb800, 0xd0e4, 0x1904, 0x798d, 0x2061, 0x1a46,
-	0x6100, 0x9184, 0x0301, 0x9086, 0x0001, 0x15a0, 0x7024, 0xd0dc,
-	0x1904, 0x7996, 0xa883, 0x0000, 0xa803, 0x0000, 0x2908, 0x7014,
-	0x9005, 0x1198, 0x7116, 0xa87c, 0xd0f4, 0x1904, 0x7999, 0x080c,
-	0x53a8, 0xd09c, 0x1118, 0xa87c, 0xc0cc, 0xa87e, 0x2e60, 0x080c,
-	0x82f1, 0x012e, 0x00ee, 0x00be, 0x0005, 0x2048, 0xa800, 0x9005,
-	0x1de0, 0xa902, 0x2148, 0xa87c, 0xd0f4, 0x1904, 0x7999, 0x012e,
-	0x00ee, 0x00be, 0x0005, 0x012e, 0x00ee, 0xa883, 0x0006, 0x00be,
-	0x0804, 0x79b7, 0xd184, 0x0db8, 0xd1c4, 0x1190, 0x00a0, 0xa974,
-	0x080c, 0x628f, 0x15d0, 0xb800, 0xd0e4, 0x15b8, 0x7120, 0x9186,
-	0x0007, 0x1118, 0xa883, 0x0002, 0x0490, 0xa883, 0x0008, 0x0478,
-	0xa883, 0x000e, 0x0460, 0xa883, 0x0017, 0x0448, 0xa883, 0x0035,
-	0x0430, 0x080c, 0x53ac, 0xd0fc, 0x01e8, 0xa878, 0x2070, 0x9e82,
-	0x1ddc, 0x02c0, 0x6064, 0x9e02, 0x12a8, 0x7120, 0x9186, 0x0006,
-	0x1188, 0x7010, 0x905d, 0x0170, 0xb800, 0xd0bc, 0x0158, 0x2039,
-	0x0001, 0x7000, 0x9086, 0x0007, 0x1904, 0x78f3, 0x7003, 0x0002,
-	0x0804, 0x78f3, 0xa883, 0x0028, 0x0010, 0xa883, 0x0029, 0x012e,
-	0x00ee, 0x00be, 0x0420, 0xa883, 0x002a, 0x0cc8, 0xa883, 0x0045,
-	0x0cb0, 0x2e60, 0x2019, 0x0002, 0x601b, 0x0014, 0x080c, 0xce41,
-	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, 0x69b5, 0x012e, 0x0005, 0x080c, 0x1061,
-	0x0005, 0x00d6, 0x080c, 0x82e8, 0x00de, 0x0005, 0x00d6, 0x00e6,
-	0x0126, 0x2091, 0x8000, 0x2071, 0x0040, 0x702c, 0xd084, 0x01d8,
-	0x908c, 0x0780, 0x190c, 0x7a52, 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, 0x7a52, 0x000e, 0x0005, 0x00d6, 0x00c6,
-	0x0036, 0x0026, 0x0016, 0x00b6, 0x7007, 0x0001, 0xaa74, 0x9282,
-	0x0004, 0x1a04, 0x7a43, 0xa97c, 0x9188, 0x1000, 0x2104, 0x905d,
-	0xb804, 0xd284, 0x0140, 0x05e8, 0x8007, 0x9084, 0x00ff, 0x9084,
-	0x0006, 0x1108, 0x04b0, 0x2b10, 0x080c, 0x9b90, 0x1118, 0x080c,
-	0x9c55, 0x05a8, 0x6212, 0xa874, 0x0002, 0x7a21, 0x7a26, 0x7a29,
-	0x7a2f, 0x2019, 0x0002, 0x080c, 0xd234, 0x0060, 0x080c, 0xd1c4,
-	0x0048, 0x2019, 0x0002, 0xa980, 0x080c, 0xd1e3, 0x0018, 0xa980,
-	0x080c, 0xd1c4, 0x080c, 0x9be6, 0xa887, 0x0000, 0x0126, 0x2091,
-	0x8000, 0x080c, 0x69b5, 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, 0x7a54, 0x0006, 0x0016,
-	0x2001, 0x8003, 0x0006, 0x0804, 0x0d6e, 0x2001, 0x1833, 0x2004,
-	0x9005, 0x0005, 0x0005, 0x00f6, 0x2079, 0x0300, 0x2001, 0x0200,
-	0x200c, 0xc1e5, 0xc1dc, 0x2102, 0x2009, 0x0218, 0x210c, 0xd1ec,
-	0x1120, 0x080c, 0x1547, 0x00fe, 0x0005, 0x2001, 0x020d, 0x2003,
-	0x0020, 0x781f, 0x0300, 0x00fe, 0x0005, 0x781c, 0xd08c, 0x0904,
-	0x7ad5, 0x68bc, 0x90aa, 0x0005, 0x0a04, 0x807e, 0x7d44, 0x7c40,
-	0xd59c, 0x190c, 0x0d65, 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, 0xd61c, 0x080c, 0x7fb5, 0x7817, 0x0140, 0x00a8, 0x9584,
-	0x0076, 0x1118, 0x080c, 0x8011, 0x19c8, 0xd5a4, 0x0148, 0x0046,
-	0x0056, 0x080c, 0x7b25, 0x080c, 0x1fe0, 0x005e, 0x004e, 0x0020,
-	0x080c, 0xd61c, 0x7817, 0x0140, 0x080c, 0x70ba, 0x0168, 0x2001,
-	0x0111, 0x2004, 0xd08c, 0x0140, 0x688f, 0x0000, 0x2001, 0x0110,
-	0x2003, 0x0008, 0x2003, 0x0000, 0x0489, 0x0005, 0x0002, 0x7ae2,
-	0x7dd7, 0x7adf, 0x7adf, 0x7adf, 0x7adf, 0x7adf, 0x7adf, 0x7817,
-	0x0140, 0x0005, 0x7000, 0x908c, 0xff00, 0x9194, 0xf000, 0x810f,
-	0x9484, 0x0fff, 0x688e, 0x9286, 0x2000, 0x1150, 0x6800, 0x9086,
-	0x0001, 0x1118, 0x080c, 0x5409, 0x0070, 0x080c, 0x7b45, 0x0058,
-	0x9286, 0x3000, 0x1118, 0x080c, 0x7d14, 0x0028, 0x9286, 0x8000,
-	0x1110, 0x080c, 0x7eeb, 0x7817, 0x0140, 0x0005, 0x2001, 0x1810,
-	0x2004, 0xd08c, 0x0178, 0x2001, 0x1800, 0x2004, 0x9086, 0x0003,
-	0x1148, 0x0026, 0x0036, 0x2011, 0x8048, 0x2518, 0x080c, 0x48fa,
-	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, 0x48fa, 0x002e,
-	0x00fe, 0x005e, 0x004e, 0x003e, 0x0005, 0x00b6, 0x00c6, 0x7010,
-	0x9084, 0xff00, 0x8007, 0x9096, 0x0001, 0x0120, 0x9096, 0x0023,
-	0x1904, 0x7ce5, 0x9186, 0x0023, 0x15c0, 0x080c, 0x7f80, 0x0904,
-	0x7ce5, 0x6120, 0x9186, 0x0001, 0x0150, 0x9186, 0x0004, 0x0138,
-	0x9186, 0x0008, 0x0120, 0x9186, 0x000a, 0x1904, 0x7ce5, 0x7124,
-	0x610a, 0x7030, 0x908e, 0x0200, 0x1130, 0x2009, 0x0015, 0x080c,
-	0x9c82, 0x0804, 0x7ce5, 0x908e, 0x0214, 0x0118, 0x908e, 0x0210,
-	0x1130, 0x2009, 0x0015, 0x080c, 0x9c82, 0x0804, 0x7ce5, 0x908e,
-	0x0100, 0x1904, 0x7ce5, 0x7034, 0x9005, 0x1904, 0x7ce5, 0x2009,
-	0x0016, 0x080c, 0x9c82, 0x0804, 0x7ce5, 0x9186, 0x0022, 0x1904,
-	0x7ce5, 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, 0x24a2, 0x7932, 0x7936, 0x001e, 0x000e,
-	0x00fe, 0x080c, 0x2459, 0x695a, 0x703c, 0x00e6, 0x2071, 0x0140,
-	0x7086, 0x2071, 0x1800, 0x70b2, 0x00ee, 0x7034, 0x9005, 0x1904,
-	0x7ce5, 0x2009, 0x0017, 0x0804, 0x7c95, 0x908e, 0x0400, 0x1190,
-	0x7034, 0x9005, 0x1904, 0x7ce5, 0x080c, 0x70ba, 0x0120, 0x2009,
-	0x001d, 0x0804, 0x7c95, 0x68d8, 0xc0a5, 0x68da, 0x2009, 0x0030,
-	0x0804, 0x7c95, 0x908e, 0x0500, 0x1140, 0x7034, 0x9005, 0x1904,
-	0x7ce5, 0x2009, 0x0018, 0x0804, 0x7c95, 0x908e, 0x2010, 0x1120,
-	0x2009, 0x0019, 0x0804, 0x7c95, 0x908e, 0x2110, 0x1120, 0x2009,
-	0x001a, 0x0804, 0x7c95, 0x908e, 0x5200, 0x1140, 0x7034, 0x9005,
-	0x1904, 0x7ce5, 0x2009, 0x001b, 0x0804, 0x7c95, 0x908e, 0x5000,
-	0x1140, 0x7034, 0x9005, 0x1904, 0x7ce5, 0x2009, 0x001c, 0x0804,
-	0x7c95, 0x908e, 0x1300, 0x1120, 0x2009, 0x0034, 0x0804, 0x7c95,
-	0x908e, 0x1200, 0x1140, 0x7034, 0x9005, 0x1904, 0x7ce5, 0x2009,
-	0x0024, 0x0804, 0x7c95, 0x908c, 0xff00, 0x918e, 0x2400, 0x1170,
-	0x2009, 0x002d, 0x2001, 0x1810, 0x2004, 0xd09c, 0x0904, 0x7c95,
-	0x080c, 0xc66b, 0x1904, 0x7ce5, 0x0804, 0x7c93, 0x908c, 0xff00,
-	0x918e, 0x5300, 0x1120, 0x2009, 0x002a, 0x0804, 0x7c95, 0x908e,
-	0x0f00, 0x1120, 0x2009, 0x0020, 0x0804, 0x7c95, 0x908e, 0x6104,
-	0x1528, 0x2029, 0x0205, 0x2011, 0x026d, 0x8208, 0x2204, 0x9082,
-	0x0004, 0x8004, 0x8004, 0x20a8, 0x2011, 0x8015, 0x211c, 0x8108,
-	0x0046, 0x2124, 0x080c, 0x48fa, 0x004e, 0x8108, 0x0f04, 0x7c61,
-	0x9186, 0x0280, 0x1d88, 0x2504, 0x8000, 0x202a, 0x2009, 0x0260,
-	0x0c58, 0x202b, 0x0000, 0x2009, 0x0023, 0x0478, 0x908e, 0x6000,
-	0x1118, 0x2009, 0x003f, 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, 0x2459, 0x1904, 0x7ce8, 0x080c,
-	0x622f, 0x1904, 0x7ce8, 0xbe12, 0xbd16, 0x001e, 0x0016, 0x080c,
-	0x70ba, 0x01c0, 0x68d8, 0xd08c, 0x1148, 0x7000, 0x9084, 0x00ff,
-	0x1188, 0x7004, 0x9084, 0xff00, 0x1168, 0x0040, 0x6878, 0x9606,
-	0x1148, 0x687c, 0x9506, 0x9084, 0xff00, 0x1120, 0x9584, 0x00ff,
-	0xb886, 0x0080, 0xb884, 0x9005, 0x1168, 0x9186, 0x0046, 0x1150,
-	0x6878, 0x9606, 0x1138, 0x687c, 0x9506, 0x9084, 0xff00, 0x1110,
-	0x001e, 0x0098, 0x080c, 0x9b90, 0x01a8, 0x2b08, 0x6112, 0x6023,
-	0x0004, 0x7120, 0x610a, 0x001e, 0x9186, 0x004c, 0x1110, 0x6023,
-	0x000a, 0x0016, 0x001e, 0x080c, 0x9c82, 0x00ce, 0x00be, 0x0005,
-	0x001e, 0x0cd8, 0x2001, 0x180e, 0x2004, 0xd0ec, 0x0120, 0x2011,
-	0x8049, 0x080c, 0x48fa, 0x080c, 0x9c55, 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, 0x84ee, 0x08a0, 0x080c, 0x3164, 0x1140, 0x7010,
-	0x9084, 0xff00, 0x8007, 0x908e, 0x0008, 0x1108, 0x0009, 0x0005,
-	0x00b6, 0x00c6, 0x0046, 0x7000, 0x908c, 0xff00, 0x810f, 0x9186,
-	0x0033, 0x11e8, 0x080c, 0x7f80, 0x0904, 0x7d6f, 0x7124, 0x610a,
-	0x7030, 0x908e, 0x0200, 0x1140, 0x7034, 0x9005, 0x15c0, 0x2009,
-	0x0015, 0x080c, 0x9c82, 0x0498, 0x908e, 0x0100, 0x1580, 0x7034,
-	0x9005, 0x1568, 0x2009, 0x0016, 0x080c, 0x9c82, 0x0440, 0x9186,
-	0x0032, 0x1528, 0x7030, 0x908e, 0x1400, 0x1508, 0x2009, 0x0038,
-	0x0016, 0x2011, 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x2459,
-	0x11a8, 0x080c, 0x622f, 0x1190, 0xbe12, 0xbd16, 0x080c, 0x9b90,
-	0x0168, 0x2b08, 0x6112, 0x080c, 0xbd09, 0x6023, 0x0004, 0x7120,
-	0x610a, 0x001e, 0x080c, 0x9c82, 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, 0x7dd1, 0x9596, 0xfffe,
-	0x1120, 0x2009, 0x007e, 0x0804, 0x7dd1, 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, 0x7da6, 0x82ff, 0x1118, 0x9085, 0x0001, 0x0018, 0xc2fc,
-	0x2208, 0x9006, 0x00de, 0x00ee, 0x004e, 0x00be, 0x0005, 0x7000,
-	0x908c, 0xff00, 0x810f, 0x9184, 0x000f, 0x0002, 0x7dee, 0x7dee,
-	0x7dee, 0x7f92, 0x7dee, 0x7df1, 0x7e16, 0x7e9f, 0x7dee, 0x7dee,
-	0x7dee, 0x7dee, 0x7dee, 0x7dee, 0x7dee, 0x7dee, 0x7817, 0x0140,
-	0x0005, 0x00b6, 0x7110, 0xd1bc, 0x01e8, 0x7120, 0x2160, 0x9c8c,
-	0x0003, 0x11c0, 0x9c8a, 0x1ddc, 0x02a8, 0x6864, 0x9c02, 0x1290,
-	0x7008, 0x9084, 0x00ff, 0x6110, 0x2158, 0xb910, 0x9106, 0x1150,
-	0x700c, 0xb914, 0x9106, 0x1130, 0x7124, 0x610a, 0x2009, 0x0046,
-	0x080c, 0x9c82, 0x7817, 0x0140, 0x00be, 0x0005, 0x00b6, 0x00c6,
-	0x9484, 0x0fff, 0x0904, 0x7e7b, 0x7110, 0xd1bc, 0x1904, 0x7e7b,
-	0x7108, 0x700c, 0x2028, 0x918c, 0x00ff, 0x2130, 0x9094, 0xff00,
-	0x15c8, 0x81ff, 0x15b8, 0x9080, 0x319f, 0x200d, 0x918c, 0xff00,
-	0x810f, 0x2001, 0x0080, 0x9106, 0x0904, 0x7e7b, 0x9182, 0x0801,
-	0x1a04, 0x7e7b, 0x9190, 0x1000, 0x2204, 0x905d, 0x05e0, 0xbe12,
-	0xbd16, 0xb800, 0xd0ec, 0x15b8, 0xba04, 0x9294, 0xff00, 0x9286,
-	0x0600, 0x1190, 0x080c, 0x9b90, 0x0598, 0x2b08, 0x7028, 0x6052,
-	0x702c, 0x604e, 0x6112, 0x6023, 0x0006, 0x7120, 0x610a, 0x7130,
-	0x615e, 0x080c, 0xc8d2, 0x00f8, 0x080c, 0x668a, 0x1138, 0xb807,
-	0x0606, 0x0c40, 0x190c, 0x7d73, 0x11b0, 0x0880, 0x080c, 0x9b90,
-	0x2b08, 0x0188, 0x6112, 0x6023, 0x0004, 0x7120, 0x610a, 0x9286,
-	0x0400, 0x1118, 0x6007, 0x0005, 0x0010, 0x6007, 0x0001, 0x6003,
-	0x0001, 0x080c, 0x84ee, 0x7817, 0x0140, 0x00ce, 0x00be, 0x0005,
-	0x2001, 0x180e, 0x2004, 0xd0ec, 0x0120, 0x2011, 0x8049, 0x080c,
-	0x48fa, 0x080c, 0x9c55, 0x0d78, 0x2b08, 0x6112, 0x6023, 0x0006,
-	0x7120, 0x610a, 0x7130, 0x615e, 0x6017, 0xf300, 0x6003, 0x0001,
-	0x6007, 0x0041, 0x2009, 0xa022, 0x080c, 0x84e7, 0x08e0, 0x00b6,
-	0x7110, 0xd1bc, 0x05d0, 0x7020, 0x2060, 0x9c84, 0x0003, 0x15a8,
-	0x9c82, 0x1ddc, 0x0690, 0x6864, 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, 0x9c82, 0x7817, 0x0140, 0x00be,
-	0x0005, 0x6120, 0x9186, 0x0002, 0x0128, 0x9186, 0x0005, 0x0110,
-	0x9085, 0x0001, 0x0005, 0x080c, 0x3164, 0x1168, 0x7010, 0x9084,
-	0xff00, 0x8007, 0x9086, 0x0000, 0x1130, 0x9184, 0x000f, 0x908a,
-	0x0006, 0x1208, 0x000b, 0x0005, 0x7f02, 0x7f03, 0x7f02, 0x7f02,
-	0x7f62, 0x7f71, 0x0005, 0x00b6, 0x7110, 0xd1bc, 0x0120, 0x702c,
-	0xd084, 0x0904, 0x7f60, 0x700c, 0x7108, 0x080c, 0x2459, 0x1904,
-	0x7f60, 0x080c, 0x622f, 0x1904, 0x7f60, 0xbe12, 0xbd16, 0x7110,
-	0xd1bc, 0x01d8, 0x080c, 0x668a, 0x0118, 0x9086, 0x0004, 0x1588,
-	0x00c6, 0x080c, 0x7f80, 0x00ce, 0x05d8, 0x080c, 0x9b90, 0x2b08,
-	0x05b8, 0x6112, 0x080c, 0xbd09, 0x6023, 0x0002, 0x7120, 0x610a,
-	0x2009, 0x0088, 0x080c, 0x9c82, 0x0458, 0x080c, 0x668a, 0x0148,
-	0x9086, 0x0004, 0x0130, 0x080c, 0x6692, 0x0118, 0x9086, 0x0004,
-	0x1180, 0x080c, 0x9b90, 0x2b08, 0x01d8, 0x6112, 0x080c, 0xbd09,
-	0x6023, 0x0005, 0x7120, 0x610a, 0x2009, 0x0088, 0x080c, 0x9c82,
-	0x0078, 0x080c, 0x9b90, 0x2b08, 0x0158, 0x6112, 0x080c, 0xbd09,
-	0x6023, 0x0004, 0x7120, 0x610a, 0x2009, 0x0001, 0x080c, 0x9c82,
-	0x00be, 0x0005, 0x7110, 0xd1bc, 0x0158, 0x00d1, 0x0148, 0x080c,
-	0x7ee1, 0x1130, 0x7124, 0x610a, 0x2009, 0x0089, 0x080c, 0x9c82,
-	0x0005, 0x7110, 0xd1bc, 0x0158, 0x0059, 0x0148, 0x080c, 0x7ee1,
-	0x1130, 0x7124, 0x610a, 0x2009, 0x008a, 0x080c, 0x9c82, 0x0005,
-	0x7020, 0x2060, 0x9c84, 0x0003, 0x1158, 0x9c82, 0x1ddc, 0x0240,
-	0x2001, 0x1819, 0x2004, 0x9c02, 0x1218, 0x9085, 0x0001, 0x0005,
-	0x9006, 0x0ce8, 0x00b6, 0x7110, 0xd1bc, 0x11d8, 0x7024, 0x2060,
-	0x9c84, 0x0003, 0x11b0, 0x9c82, 0x1ddc, 0x0298, 0x6864, 0x9c02,
-	0x1280, 0x7008, 0x9084, 0x00ff, 0x6110, 0x2158, 0xb910, 0x9106,
-	0x1140, 0x700c, 0xb914, 0x9106, 0x1120, 0x2009, 0x0051, 0x080c,
-	0x9c82, 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, 0x9b90,
-	0x05a8, 0x0066, 0x00c6, 0x0046, 0x2011, 0x0263, 0x2204, 0x8211,
-	0x220c, 0x080c, 0x2459, 0x1590, 0x080c, 0x622f, 0x1578, 0xbe12,
-	0xbd16, 0x2b00, 0x004e, 0x00ce, 0x6012, 0x080c, 0xbd09, 0x080c,
-	0x102f, 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, 0x84ee, 0x00fe, 0x009e,
-	0x00ce, 0x0005, 0x080c, 0x9be6, 0x006e, 0x0cc0, 0x004e, 0x00ce,
-	0x0cc8, 0x00c6, 0x7000, 0x908c, 0xff00, 0x9184, 0xf000, 0x810f,
-	0x9086, 0x2000, 0x1904, 0x8068, 0x9186, 0x0022, 0x15f0, 0x2001,
-	0x0111, 0x2004, 0x9005, 0x1904, 0x806a, 0x7030, 0x908e, 0x0400,
-	0x0904, 0x806a, 0x908e, 0x6000, 0x05e8, 0x908e, 0x5400, 0x05d0,
-	0x908e, 0x0300, 0x11d8, 0x2009, 0x1836, 0x210c, 0xd18c, 0x1590,
-	0xd1a4, 0x1580, 0x080c, 0x6648, 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, 0x7f80, 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, 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, 0x2071, 0x19db, 0x7003,
-	0x0003, 0x700f, 0x0361, 0x9006, 0x701a, 0x7072, 0x7012, 0x7017,
-	0x1ddc, 0x7007, 0x0000, 0x7026, 0x702b, 0x8ff0, 0x7032, 0x7037,
-	0x906d, 0x703f, 0xffff, 0x7042, 0x7047, 0x523f, 0x704a, 0x705b,
-	0x8239, 0x080c, 0x1048, 0x090c, 0x0d65, 0x2900, 0x703a, 0xa867,
-	0x0003, 0xa86f, 0x0100, 0xa8ab, 0xdcb0, 0x0005, 0x2071, 0x19db,
-	0x1d04, 0x815b, 0x2091, 0x6000, 0x700c, 0x8001, 0x700e, 0x1560,
-	0x2001, 0x187d, 0x2004, 0xd0c4, 0x0158, 0x3a00, 0xd08c, 0x1140,
-	0x20d1, 0x0000, 0x20d1, 0x0001, 0x20d1, 0x0000, 0x080c, 0x0d65,
-	0x700f, 0x0361, 0x7007, 0x0001, 0x0126, 0x2091, 0x8000, 0x2069,
-	0x1800, 0x69e8, 0xd1e4, 0x1138, 0xd1dc, 0x1118, 0x080c, 0x82a7,
-	0x0010, 0x080c, 0x827e, 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, 0x90f5, 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, 0x8183, 0x8184, 0x81ae,
-	0x00e6, 0x2071, 0x19db, 0x7018, 0x9005, 0x1120, 0x711a, 0x721e,
-	0x700b, 0x0009, 0x00ee, 0x0005, 0x00e6, 0x0006, 0x2071, 0x19db,
-	0x701c, 0x9206, 0x1120, 0x701a, 0x701e, 0x7072, 0x7076, 0x000e,
-	0x00ee, 0x0005, 0x00e6, 0x2071, 0x19db, 0xb888, 0x9102, 0x0208,
-	0xb98a, 0x00ee, 0x0005, 0x0005, 0x00b6, 0x2031, 0x0010, 0x7110,
-	0x080c, 0x628f, 0x11a8, 0xb888, 0x8001, 0x0290, 0xb88a, 0x1180,
-	0x0126, 0x2091, 0x8000, 0x0066, 0xb8c0, 0x9005, 0x0138, 0x0026,
-	0xba3c, 0x0016, 0x080c, 0x63ba, 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, 0xbb8a, 0x6018, 0x9005, 0x0904,
-	0x8200, 0x00f6, 0x2079, 0x0300, 0x7918, 0xd1b4, 0x1904, 0x8213,
-	0x781b, 0x2020, 0xa001, 0x7918, 0xd1b4, 0x0120, 0x781b, 0x2000,
-	0x0804, 0x8213, 0x8001, 0x601a, 0x0106, 0x781b, 0x2000, 0xa001,
-	0x7918, 0xd1ac, 0x1dd0, 0x010e, 0x00fe, 0x1510, 0x6120, 0x9186,
-	0x0003, 0x0118, 0x9186, 0x0006, 0x11c8, 0x080c, 0xb870, 0x01b0,
-	0x6014, 0x2048, 0xa884, 0x908a, 0x199a, 0x0280, 0x9082, 0x1999,
-	0xa886, 0x908a, 0x199a, 0x0210, 0x2001, 0x1999, 0x8003, 0x800b,
-	0x810b, 0x9108, 0x611a, 0x080c, 0xbfbb, 0x0110, 0x080c, 0xb551,
-	0x012e, 0x9c88, 0x001c, 0x7116, 0x2001, 0x1819, 0x2004, 0x9102,
-	0x1228, 0x8631, 0x0138, 0x2160, 0x0804, 0x81b2, 0x7017, 0x1ddc,
-	0x7007, 0x0000, 0x0005, 0x00fe, 0x0c58, 0x00e6, 0x2071, 0x19db,
-	0x7027, 0x07d0, 0x7023, 0x0009, 0x00ee, 0x0005, 0x2001, 0x19e4,
-	0x2003, 0x0000, 0x0005, 0x00e6, 0x2071, 0x19db, 0x7132, 0x702f,
-	0x0009, 0x00ee, 0x0005, 0x2011, 0x19e7, 0x2013, 0x0000, 0x0005,
-	0x00e6, 0x2071, 0x19db, 0x711a, 0x721e, 0x700b, 0x0009, 0x00ee,
-	0x0005, 0x0086, 0x0026, 0x7054, 0x8000, 0x7056, 0x2001, 0x19e9,
-	0x2044, 0xa06c, 0x9086, 0x0000, 0x0150, 0x7068, 0xa09a, 0x7064,
-	0xa096, 0x7060, 0xa092, 0x705c, 0xa08e, 0x080c, 0x1124, 0x002e,
-	0x008e, 0x0005, 0x0006, 0x0016, 0x0096, 0x00a6, 0x00b6, 0x00c6,
-	0x00d6, 0x00e6, 0x00f6, 0x0156, 0x080c, 0x80c6, 0x015e, 0x00fe,
-	0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae, 0x009e, 0x001e, 0x000e,
-	0x0005, 0x00e6, 0x2071, 0x19db, 0x7172, 0x7276, 0x706f, 0x0009,
-	0x00ee, 0x0005, 0x00e6, 0x0006, 0x2071, 0x19db, 0x7074, 0x9206,
-	0x1110, 0x7072, 0x7076, 0x000e, 0x00ee, 0x0005, 0x2069, 0x1800,
-	0x69e8, 0xd1e4, 0x1518, 0x0026, 0xd1ec, 0x0140, 0x6a50, 0x6870,
-	0x9202, 0x0288, 0x8117, 0x9294, 0x00c1, 0x0088, 0x9184, 0x0007,
-	0x01a0, 0x8109, 0x9184, 0x0007, 0x0110, 0x69ea, 0x0070, 0x8107,
-	0x9084, 0x0007, 0x910d, 0x8107, 0x9106, 0x9094, 0x00c1, 0x9184,
-	0xff3e, 0x9205, 0x68ea, 0x080c, 0x0efa, 0x002e, 0x0005, 0x69e4,
-	0x9184, 0x003f, 0x05b8, 0x8109, 0x9184, 0x003f, 0x01a8, 0x6a50,
-	0x6870, 0x9202, 0x0220, 0xd1bc, 0x0168, 0xc1bc, 0x0018, 0xd1bc,
-	0x1148, 0xc1bd, 0x2110, 0x00e6, 0x2071, 0x1800, 0x080c, 0x0f1c,
-	0x00ee, 0x0400, 0x69e6, 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, 0x0f1c,
-	0x00ee, 0x002e, 0x0005, 0x00c6, 0x2061, 0x1a46, 0x00ce, 0x0005,
-	0x9184, 0x000f, 0x8003, 0x8003, 0x8003, 0x9080, 0x1a46, 0x2060,
-	0x0005, 0xa884, 0x908a, 0x199a, 0x1638, 0x9005, 0x1150, 0x00c6,
-	0x2061, 0x1a46, 0x6014, 0x00ce, 0x9005, 0x1130, 0x2001, 0x001e,
-	0x0018, 0x908e, 0xffff, 0x01b0, 0x8003, 0x800b, 0x810b, 0x9108,
-	0x611a, 0xa87c, 0x908c, 0x00c0, 0x918e, 0x00c0, 0x0904, 0x83ab,
-	0xd0b4, 0x1168, 0xd0bc, 0x1904, 0x8384, 0x2009, 0x0006, 0x080c,
-	0x83d8, 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, 0x187d, 0x210c, 0xd184, 0x11d8, 0x6003, 0x0003,
-	0x6007, 0x0043, 0x6047, 0xb035, 0x080c, 0x1aca, 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, 0x83d2,
-	0x908c, 0x2020, 0x918e, 0x2020, 0x01a8, 0x6024, 0xd0d4, 0x11e8,
-	0x2009, 0x187d, 0x2104, 0xd084, 0x1138, 0x87ff, 0x1120, 0x2009,
-	0x0043, 0x0804, 0x9c82, 0x0005, 0x87ff, 0x1de8, 0x2009, 0x0042,
-	0x0804, 0x9c82, 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, 0x83d2, 0x908c, 0x2020, 0x918e,
-	0x2020, 0x0170, 0x0076, 0x00f6, 0x2c78, 0x080c, 0x1669, 0x00fe,
-	0x007e, 0x87ff, 0x1120, 0x2009, 0x0042, 0x080c, 0x9c82, 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, 0x9c82, 0x0005, 0x00b9, 0x0ce8,
-	0x87ff, 0x1dd8, 0x2009, 0x0043, 0x080c, 0x9c82, 0x0cb0, 0x6110,
-	0x00b6, 0x2158, 0xb900, 0x00be, 0xd1ac, 0x0d20, 0x6124, 0xc1cd,
-	0x6126, 0x0c00, 0x2009, 0x0004, 0x0019, 0x0005, 0x2009, 0x0001,
-	0x0096, 0x080c, 0xb870, 0x0518, 0x6014, 0x2048, 0xa982, 0xa800,
-	0x6016, 0x9186, 0x0001, 0x1188, 0xa97c, 0x918c, 0x8100, 0x918e,
-	0x8100, 0x1158, 0x00c6, 0x2061, 0x1a46, 0x6200, 0xd28c, 0x1120,
-	0x6204, 0x8210, 0x0208, 0x6206, 0x00ce, 0x080c, 0x67ea, 0x6014,
-	0x904d, 0x0076, 0x2039, 0x0000, 0x190c, 0x82f1, 0x007e, 0x009e,
-	0x0005, 0x0156, 0x00c6, 0x2061, 0x1a46, 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,
-	0x8423, 0x8086, 0x818e, 0x004e, 0x003e, 0x012e, 0x0005, 0x0126,
-	0x2091, 0x8000, 0x0076, 0x0156, 0x20a9, 0x0010, 0x9005, 0x01c8,
-	0x911a, 0x12b8, 0x8213, 0x818d, 0x0228, 0x911a, 0x1220, 0x1f04,
-	0x843a, 0x0028, 0x911a, 0x2308, 0x8210, 0x1f04, 0x843a, 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,
-	0x0005, 0x0156, 0x0146, 0x01d6, 0x20e9, 0x0000, 0x2069, 0x0200,
-	0x080c, 0x97f4, 0x04a9, 0x080c, 0x97df, 0x0491, 0x080c, 0x97e2,
-	0x0479, 0x080c, 0x97e5, 0x0461, 0x080c, 0x97e8, 0x0449, 0x080c,
-	0x97eb, 0x0431, 0x080c, 0x97ee, 0x0419, 0x080c, 0x97f1, 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, 0x0005,
-	0x20a9, 0x0020, 0x20a1, 0x0240, 0x2001, 0x0000, 0x4004, 0x0005,
-	0x00c6, 0x7803, 0x0000, 0x9006, 0x7827, 0x0030, 0x782b, 0x0400,
-	0x7827, 0x0031, 0x782b, 0x1ac6, 0x781f, 0xff00, 0x781b, 0xff00,
-	0x2061, 0x1abb, 0x602f, 0x19bf, 0x6033, 0x1800, 0x6037, 0x19db,
-	0x603b, 0x1d1c, 0x603f, 0x1d2c, 0x6042, 0x6047, 0x1a91, 0x00ce,
-	0x0005, 0x2001, 0x0382, 0x2004, 0x9084, 0x0007, 0x9086, 0x0001,
-	0x01b0, 0x00c6, 0x6146, 0x600f, 0x0000, 0x2c08, 0x2061, 0x19bf,
-	0x602c, 0x8000, 0x602e, 0x601c, 0x9005, 0x0130, 0x9080, 0x0003,
-	0x2102, 0x611e, 0x00ce, 0x0005, 0x6122, 0x611e, 0x0cd8, 0x6146,
-	0x2c08, 0x2001, 0x0012, 0x080c, 0x98b8, 0x0005, 0x0016, 0x2009,
-	0x8020, 0x6146, 0x2c08, 0x2001, 0x0382, 0x2004, 0x9084, 0x0007,
-	0x9086, 0x0001, 0x1128, 0x2001, 0x0019, 0x080c, 0x98b8, 0x0088,
-	0x00c6, 0x2061, 0x19bf, 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, 0x19bf, 0x6044, 0x9005, 0x0130, 0x9080, 0x0003, 0x2102,
-	0x6146, 0x00ce, 0x0005, 0x614a, 0x6146, 0x0cd8, 0x6146, 0x600f,
-	0x0000, 0x2c08, 0x2001, 0x0013, 0x080c, 0x98b8, 0x0005, 0x6044,
-	0xd0dc, 0x0110, 0x080c, 0x948d, 0x0005, 0x00f6, 0x00e6, 0x00d6,
-	0x00c6, 0x00b6, 0x0096, 0x0076, 0x0066, 0x0056, 0x0036, 0x0026,
-	0x0016, 0x0006, 0x0126, 0x902e, 0x2071, 0x19bf, 0x7648, 0x2660,
-	0x2678, 0x2091, 0x8000, 0x8cff, 0x0904, 0x85ba, 0x6010, 0x2058,
-	0xb8a0, 0x9206, 0x1904, 0x85b5, 0x87ff, 0x0120, 0x605c, 0x9106,
-	0x1904, 0x85b5, 0x704c, 0x9c06, 0x1178, 0x0036, 0x2019, 0x0001,
-	0x080c, 0x929d, 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, 0x2c00,
-	0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x080c,
-	0xb870, 0x01f0, 0x6014, 0x2048, 0x6020, 0x9086, 0x0003, 0x1588,
-	0x6004, 0x9086, 0x0040, 0x090c, 0x948d, 0xa867, 0x0103, 0xab7a,
-	0xa877, 0x0000, 0x0016, 0x0036, 0x0076, 0x080c, 0xbb73, 0x080c,
-	0xd563, 0x080c, 0x69b5, 0x007e, 0x003e, 0x001e, 0x080c, 0xba5f,
-	0x080c, 0x9c20, 0x00ce, 0x0804, 0x8553, 0x2c78, 0x600c, 0x2060,
-	0x0804, 0x8553, 0x012e, 0x000e, 0x001e, 0x002e, 0x003e, 0x005e,
-	0x006e, 0x007e, 0x009e, 0x00be, 0x00ce, 0x00de, 0x00ee, 0x00fe,
-	0x0005, 0x6020, 0x9086, 0x0006, 0x1158, 0x0016, 0x0036, 0x0076,
-	0x080c, 0xd563, 0x080c, 0xd267, 0x007e, 0x003e, 0x001e, 0x08c0,
-	0x6020, 0x9086, 0x000a, 0x0918, 0x0804, 0x8598, 0x0006, 0x0066,
-	0x0096, 0x00c6, 0x00d6, 0x00f6, 0x9036, 0x0126, 0x2091, 0x8000,
-	0x2079, 0x19bf, 0x7848, 0x9065, 0x0904, 0x8642, 0x600c, 0x0006,
-	0x600f, 0x0000, 0x784c, 0x9c06, 0x11a0, 0x0036, 0x2019, 0x0001,
-	0x080c, 0x929d, 0x783f, 0x0000, 0x901e, 0x7b4e, 0x7b6a, 0x7b52,
-	0x7b6e, 0x003e, 0x000e, 0x9005, 0x1118, 0x600c, 0x600f, 0x0000,
-	0x0006, 0x00e6, 0x2f70, 0x080c, 0x8537, 0x00ee, 0x080c, 0xb870,
-	0x0548, 0x6014, 0x2048, 0x6020, 0x9086, 0x0003, 0x15a8, 0x3e08,
-	0x918e, 0x0002, 0x1188, 0x6010, 0x9005, 0x0170, 0x00b6, 0x2058,
-	0xb800, 0x00be, 0xd0bc, 0x0140, 0x6048, 0x9005, 0x11c0, 0x2001,
-	0x1960, 0x2004, 0x604a, 0x0098, 0x6004, 0x9086, 0x0040, 0x090c,
-	0x948d, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0x69a9,
-	0x080c, 0xba5f, 0x6044, 0xc0fc, 0x6046, 0x080c, 0x9c20, 0x000e,
-	0x0804, 0x85eb, 0x7e4a, 0x7e46, 0x012e, 0x00fe, 0x00de, 0x00ce,
-	0x009e, 0x006e, 0x000e, 0x0005, 0x6020, 0x9086, 0x0006, 0x1118,
-	0x080c, 0xd267, 0x0c38, 0x6020, 0x9086, 0x000a, 0x09e0, 0x08a0,
-	0x0016, 0x0026, 0x0086, 0x9046, 0x00a9, 0x080c, 0x8749, 0x008e,
-	0x002e, 0x001e, 0x0005, 0x00f6, 0x0126, 0x2079, 0x19bf, 0x2091,
-	0x8000, 0x080c, 0x8792, 0x080c, 0x8826, 0x080c, 0x641c, 0x012e,
-	0x00fe, 0x0005, 0x00b6, 0x0096, 0x00f6, 0x00e6, 0x00d6, 0x00c6,
-	0x0066, 0x0016, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19bf,
-	0x7620, 0x2660, 0x2678, 0x8cff, 0x0904, 0x870e, 0x6010, 0x2058,
-	0xb8a0, 0x9206, 0x1904, 0x8709, 0x88ff, 0x0120, 0x605c, 0x9106,
-	0x1904, 0x8709, 0x7030, 0x9c06, 0x1570, 0x2069, 0x0100, 0x6820,
-	0xd0a4, 0x1508, 0x080c, 0x821e, 0x080c, 0x8fd0, 0x68c3, 0x0000,
-	0x080c, 0x948d, 0x7033, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04,
-	0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2872, 0x9006,
-	0x080c, 0x2872, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827,
-	0x0001, 0x003e, 0x0040, 0x7008, 0xc0ad, 0x700a, 0x6003, 0x0009,
-	0x630a, 0x0804, 0x8709, 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, 0xb870, 0x01e8, 0x6020, 0x9086, 0x0003,
-	0x1580, 0x080c, 0xba85, 0x1118, 0x080c, 0xa59c, 0x0098, 0xa867,
-	0x0103, 0xab7a, 0xa877, 0x0000, 0x0016, 0x0036, 0x0086, 0x080c,
-	0xbb73, 0x080c, 0xd563, 0x080c, 0x69b5, 0x008e, 0x003e, 0x001e,
-	0x080c, 0xba5f, 0x080c, 0x9c20, 0x080c, 0x9363, 0x00ce, 0x0804,
-	0x8683, 0x2c78, 0x600c, 0x2060, 0x0804, 0x8683, 0x012e, 0x000e,
-	0x001e, 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x009e, 0x00be,
-	0x0005, 0x6020, 0x9086, 0x0006, 0x1158, 0x0016, 0x0036, 0x0086,
-	0x080c, 0xd563, 0x080c, 0xd267, 0x008e, 0x003e, 0x001e, 0x08d0,
-	0x080c, 0xa59c, 0x6020, 0x9086, 0x0002, 0x1160, 0x6004, 0x0006,
-	0x9086, 0x0085, 0x000e, 0x0904, 0x86ef, 0x9086, 0x008b, 0x0904,
-	0x86ef, 0x0840, 0x6020, 0x9086, 0x0005, 0x1920, 0x6004, 0x0006,
-	0x9086, 0x0085, 0x000e, 0x09c8, 0x9086, 0x008b, 0x09b0, 0x0804,
-	0x8702, 0x0006, 0x00f6, 0x00e6, 0x0096, 0x00b6, 0x00c6, 0x0066,
-	0x0016, 0x0126, 0x2091, 0x8000, 0x9280, 0x1000, 0x2004, 0x905d,
-	0x2079, 0x19bf, 0x9036, 0x7828, 0x2060, 0x8cff, 0x0538, 0x6010,
-	0x9b06, 0x1500, 0x6043, 0xffff, 0x080c, 0x9a83, 0x01d8, 0x610c,
-	0x0016, 0x080c, 0x9127, 0x6014, 0x2048, 0xa867, 0x0103, 0xab7a,
-	0xa877, 0x0000, 0x0016, 0x0036, 0x0086, 0x080c, 0xbb73, 0x080c,
-	0xd563, 0x080c, 0x69b5, 0x008e, 0x003e, 0x001e, 0x080c, 0x9c20,
-	0x00ce, 0x08d8, 0x2c30, 0x600c, 0x2060, 0x08b8, 0x080c, 0x6439,
-	0x012e, 0x001e, 0x006e, 0x00ce, 0x00be, 0x009e, 0x00ee, 0x00fe,
-	0x000e, 0x0005, 0x0096, 0x0006, 0x0066, 0x00c6, 0x00d6, 0x9036,
-	0x7820, 0x9065, 0x0904, 0x87f9, 0x600c, 0x0006, 0x6044, 0xc0fc,
-	0x6046, 0x600f, 0x0000, 0x7830, 0x9c06, 0x1588, 0x2069, 0x0100,
-	0x6820, 0xd0a4, 0x1508, 0x080c, 0x821e, 0x080c, 0x8fd0, 0x68c3,
-	0x0000, 0x080c, 0x948d, 0x7833, 0x0000, 0x0036, 0x2069, 0x0140,
-	0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2872,
-	0x9006, 0x080c, 0x2872, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110,
-	0x6827, 0x0001, 0x003e, 0x0058, 0x080c, 0x6640, 0x1538, 0x6003,
-	0x0009, 0x630a, 0x7808, 0xc0ad, 0x780a, 0x2c30, 0x00f8, 0x6014,
-	0x2048, 0x080c, 0xb86e, 0x01b0, 0x6020, 0x9086, 0x0003, 0x1508,
-	0x080c, 0xba85, 0x1118, 0x080c, 0xa59c, 0x0060, 0x080c, 0x6640,
-	0x1168, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0x69b5,
-	0x080c, 0xba5f, 0x080c, 0x9c20, 0x080c, 0x9363, 0x000e, 0x0804,
-	0x8799, 0x7e22, 0x7e1e, 0x00de, 0x00ce, 0x006e, 0x000e, 0x009e,
-	0x0005, 0x6020, 0x9086, 0x0006, 0x1118, 0x080c, 0xd267, 0x0c50,
-	0x080c, 0xa59c, 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, 0x9a83, 0x0180, 0x610c,
-	0x080c, 0x9127, 0x6014, 0x2048, 0xa867, 0x0103, 0xab7a, 0xa877,
-	0x0000, 0x080c, 0x69b5, 0x080c, 0x9c20, 0x000e, 0x08f0, 0x2c30,
-	0x0ce0, 0x006e, 0x00ce, 0x00be, 0x009e, 0x000e, 0x0005, 0x00e6,
-	0x00d6, 0x0096, 0x0066, 0x080c, 0x5df1, 0x11b0, 0x2071, 0x19bf,
-	0x7030, 0x9080, 0x0005, 0x2004, 0x904d, 0x0170, 0xa878, 0x9606,
-	0x1158, 0x2071, 0x19bf, 0x7030, 0x9035, 0x0130, 0x9080, 0x0005,
-	0x2004, 0x9906, 0x1108, 0x0029, 0x006e, 0x009e, 0x00de, 0x00ee,
-	0x0005, 0x00c6, 0x2660, 0x6043, 0xffff, 0x080c, 0x9a83, 0x0178,
-	0x080c, 0x9127, 0x6014, 0x2048, 0xa867, 0x0103, 0xab7a, 0xa877,
-	0x0000, 0x080c, 0xbb73, 0x080c, 0x69b5, 0x080c, 0x9c20, 0x00ce,
-	0x0005, 0x00b6, 0x00e6, 0x00c6, 0x080c, 0x98c7, 0x0106, 0x2071,
-	0x0101, 0x2e04, 0xc0c4, 0x2072, 0x6044, 0xd0fc, 0x1138, 0x010e,
-	0x090c, 0x98e3, 0x00ce, 0x00ee, 0x00be, 0x0005, 0x2071, 0x19bf,
-	0x7030, 0x9005, 0x0da0, 0x9c06, 0x190c, 0x0d65, 0x7036, 0x080c,
-	0x821e, 0x7004, 0x9084, 0x0007, 0x0002, 0x88bf, 0x88c1, 0x88c8,
-	0x88d2, 0x88e0, 0x88bf, 0x88cd, 0x88bd, 0x080c, 0x0d65, 0x0428,
-	0x0005, 0x080c, 0x9a6e, 0x7007, 0x0000, 0x7033, 0x0000, 0x00e8,
-	0x0066, 0x9036, 0x080c, 0x9127, 0x006e, 0x7007, 0x0000, 0x7033,
-	0x0000, 0x0098, 0x080c, 0x9a59, 0x0140, 0x080c, 0x9a6e, 0x0128,
-	0x0066, 0x9036, 0x080c, 0x9127, 0x006e, 0x7033, 0x0000, 0x0028,
-	0x080c, 0x9a59, 0x080c, 0x948d, 0x0000, 0x010e, 0x190c, 0x98e3,
-	0x00ce, 0x00ee, 0x00be, 0x0005, 0x00d6, 0x00c6, 0x080c, 0x98c7,
-	0x0106, 0x6044, 0xd0fc, 0x1130, 0x010e, 0x090c, 0x98e3, 0x00ce,
-	0x00de, 0x0005, 0x2069, 0x19bf, 0x684c, 0x9005, 0x0da8, 0x9c06,
-	0x190c, 0x0d65, 0x6852, 0x00e6, 0x2d70, 0x080c, 0x8537, 0x00ee,
-	0x080c, 0x822b, 0x0016, 0x2009, 0x0040, 0x080c, 0x207b, 0x001e,
-	0x683c, 0x9084, 0x0003, 0x0002, 0x891a, 0x891b, 0x8939, 0x8918,
-	0x080c, 0x0d65, 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, 0x190c, 0x98e3, 0x00ce, 0x00de, 0x0005, 0x0005,
-	0x6020, 0x9084, 0x000f, 0x000b, 0x0005, 0x8965, 0x8968, 0x8dc1,
-	0x8e50, 0x8968, 0x8dc1, 0x8e50, 0x8965, 0x8968, 0x8965, 0x8965,
-	0x8965, 0x8965, 0x8965, 0x8965, 0x8965, 0x080c, 0x8891, 0x0005,
-	0x00b6, 0x0156, 0x0136, 0x0146, 0x01c6, 0x01d6, 0x00c6, 0x00d6,
-	0x00e6, 0x00f6, 0x2069, 0x0200, 0x2071, 0x0240, 0x6004, 0x908a,
-	0x0053, 0x1a0c, 0x0d65, 0x6110, 0x2158, 0xb984, 0x2c78, 0x2061,
-	0x0100, 0x619a, 0x908a, 0x0040, 0x1a04, 0x89d4, 0x005b, 0x00fe,
-	0x00ee, 0x00de, 0x00ce, 0x01de, 0x01ce, 0x014e, 0x013e, 0x015e,
-	0x00be, 0x0005, 0x8b4b, 0x8b86, 0x8baf, 0x8c52, 0x8c73, 0x8c79,
-	0x8c86, 0x8c8e, 0x8c9a, 0x8ca0, 0x8cb1, 0x8ca0, 0x8d08, 0x8c8e,
-	0x8d14, 0x8d1a, 0x8c9a, 0x8d1a, 0x8d26, 0x89d2, 0x89d2, 0x89d2,
-	0x89d2, 0x89d2, 0x89d2, 0x89d2, 0x89d2, 0x89d2, 0x89d2, 0x89d2,
-	0x9148, 0x916b, 0x917c, 0x919c, 0x91ce, 0x8c86, 0x89d2, 0x8c86,
-	0x8ca0, 0x89d2, 0x8baf, 0x8c52, 0x89d2, 0x958b, 0x8ca0, 0x89d2,
-	0x95a7, 0x8ca0, 0x89d2, 0x8c9a, 0x8b45, 0x89f5, 0x89d2, 0x95c3,
-	0x9630, 0x9714, 0x89d2, 0x9721, 0x8c83, 0x974c, 0x89d2, 0x91d8,
-	0x9758, 0x89d2, 0x080c, 0x0d65, 0x2100, 0x005b, 0x00fe, 0x00ee,
-	0x00de, 0x00ce, 0x01de, 0x01ce, 0x014e, 0x013e, 0x015e, 0x00be,
-	0x0005, 0x89f3, 0x89f3, 0x89f3, 0x8a1c, 0x8ac8, 0x8ad3, 0x89f3,
-	0x89f3, 0x89f3, 0x8b1a, 0x8b26, 0x8a37, 0x89f3, 0x8a52, 0x8a86,
-	0x9ad9, 0x9b1e, 0x8ca0, 0x080c, 0x0d65, 0x00d6, 0x0096, 0x080c,
-	0x8d39, 0x7003, 0x2414, 0x7007, 0x0018, 0x700b, 0x0800, 0x7814,
-	0x2048, 0xa83c, 0x700e, 0xa850, 0x7022, 0xa854, 0x7026, 0x60c3,
-	0x0018, 0x080c, 0x8fa0, 0x009e, 0x00de, 0x0005, 0x7810, 0x00b6,
-	0x2058, 0xb8a0, 0x00be, 0x080c, 0x9b65, 0x1118, 0x9084, 0xff80,
-	0x0110, 0x9085, 0x0001, 0x0005, 0x00d6, 0x0096, 0x080c, 0x8d39,
-	0x7003, 0x0500, 0x7814, 0x2048, 0xa874, 0x700a, 0xa878, 0x700e,
-	0xa87c, 0x7012, 0xa880, 0x7016, 0xa884, 0x701a, 0xa888, 0x701e,
-	0x60c3, 0x0010, 0x080c, 0x8fa0, 0x009e, 0x00de, 0x0005, 0x00d6,
-	0x0096, 0x080c, 0x8d39, 0x7003, 0x0500, 0x7814, 0x2048, 0xa8cc,
-	0x700a, 0xa8d0, 0x700e, 0xa8d4, 0x7012, 0xa8d8, 0x7016, 0xa8dc,
-	0x701a, 0xa8e0, 0x701e, 0x60c3, 0x0010, 0x080c, 0x8fa0, 0x009e,
-	0x00de, 0x0005, 0x00d6, 0x0096, 0x0126, 0x2091, 0x8000, 0x080c,
-	0x8d39, 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, 0x2060, 0x080c, 0xc5cd, 0x9006, 0x080c,
-	0x2060, 0x001e, 0xa804, 0x9005, 0x0110, 0x2048, 0x0c28, 0x04d9,
-	0x080c, 0x8fa0, 0x012e, 0x009e, 0x00de, 0x0005, 0x00d6, 0x0096,
-	0x0126, 0x2091, 0x8000, 0x080c, 0x8d84, 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, 0xc5cd, 0x001e, 0xa804, 0x9005, 0x0110, 0x2048, 0x0c60,
-	0x0051, 0x7814, 0x2048, 0x080c, 0x0fe1, 0x080c, 0x8fa0, 0x012e,
-	0x009e, 0x00de, 0x0005, 0x60c0, 0x8004, 0x9084, 0x0003, 0x9005,
-	0x0130, 0x9082, 0x0004, 0x20a3, 0x0000, 0x8000, 0x1de0, 0x0005,
-	0x080c, 0x8d39, 0x7003, 0x7800, 0x7808, 0x8007, 0x700a, 0x60c3,
-	0x0008, 0x0804, 0x8fa0, 0x00d6, 0x00e6, 0x080c, 0x8d84, 0x7814,
-	0x9084, 0xff00, 0x2073, 0x0200, 0x8e70, 0x8e70, 0x9095, 0x0010,
-	0x2272, 0x8e70, 0x2073, 0x0034, 0x8e70, 0x2069, 0x1805, 0x20a9,
-	0x0004, 0x2d76, 0x8d68, 0x8e70, 0x1f04, 0x8ae9, 0x2069, 0x1801,
-	0x20a9, 0x0004, 0x2d76, 0x8d68, 0x8e70, 0x1f04, 0x8af2, 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, 0x8b00, 0x60c3, 0x004c, 0x080c, 0x8fa0, 0x00ee,
-	0x00de, 0x0005, 0x080c, 0x8d39, 0x7003, 0x6300, 0x7007, 0x0028,
-	0x7808, 0x700e, 0x60c3, 0x0008, 0x0804, 0x8fa0, 0x00d6, 0x0026,
-	0x0016, 0x080c, 0x8d84, 0x7003, 0x0200, 0x7814, 0x700e, 0x00e6,
-	0x9ef0, 0x0004, 0x2009, 0x0001, 0x2011, 0x000c, 0x2073, 0x0800,
-	0x8e70, 0x2073, 0x0000, 0x00ee, 0x7206, 0x710a, 0x62c2, 0x080c,
-	0x8fa0, 0x001e, 0x002e, 0x00de, 0x0005, 0x2001, 0x1817, 0x2004,
-	0x609a, 0x0804, 0x8fa0, 0x080c, 0x8d39, 0x7003, 0x5200, 0x2069,
-	0x185b, 0x6804, 0xd084, 0x0130, 0x6828, 0x0016, 0x080c, 0x248c,
-	0x710e, 0x001e, 0x20a9, 0x0004, 0x20e1, 0x0001, 0x2099, 0x1805,
-	0x20e9, 0x0000, 0x20a1, 0x0250, 0x4003, 0x20a9, 0x0004, 0x2099,
-	0x1801, 0x20a1, 0x0254, 0x4003, 0x080c, 0x9b65, 0x1120, 0xb8a0,
-	0x9082, 0x007f, 0x0248, 0x2001, 0x181e, 0x2004, 0x7032, 0x2001,
-	0x181f, 0x2004, 0x7036, 0x0030, 0x2001, 0x1817, 0x2004, 0x9084,
-	0x00ff, 0x7036, 0x60c3, 0x001c, 0x0804, 0x8fa0, 0x080c, 0x8d39,
-	0x7003, 0x0500, 0x080c, 0x9b65, 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, 0x8fa0, 0x080c,
-	0x8d39, 0x9006, 0x080c, 0x6654, 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, 0x8c1a, 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, 0x70ba, 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, 0x97df, 0x2069, 0x194c, 0x2071, 0x024e, 0x6800,
-	0xc0dd, 0x7002, 0x080c, 0x53ac, 0xd0e4, 0x0110, 0x680c, 0x700e,
-	0x00de, 0x04a0, 0x2001, 0x1836, 0x2004, 0xd0a4, 0x0168, 0x0016,
-	0x2009, 0x0002, 0x60e0, 0x9106, 0x0130, 0x2100, 0x60e3, 0x0000,
-	0x080c, 0x24cd, 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, 0x97df, 0x20a1,
-	0x024e, 0x20a9, 0x0008, 0x2099, 0x194c, 0x4003, 0x60c3, 0x0074,
-	0x0804, 0x8fa0, 0x080c, 0x8d39, 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, 0x8ce9, 0x7026, 0x60c3,
-	0x0014, 0x0804, 0x8fa0, 0x080c, 0x8d39, 0x7003, 0x5000, 0x0804,
-	0x8bc9, 0x080c, 0x8d39, 0x7003, 0x2110, 0x7007, 0x0014, 0x60c3,
-	0x0014, 0x0804, 0x8fa0, 0x080c, 0x8d7b, 0x0010, 0x080c, 0x8d84,
-	0x7003, 0x0200, 0x60c3, 0x0004, 0x0804, 0x8fa0, 0x080c, 0x8d84,
-	0x7003, 0x0100, 0x700b, 0x0003, 0x700f, 0x2a00, 0x60c3, 0x0008,
-	0x0804, 0x8fa0, 0x080c, 0x8d84, 0x7003, 0x0200, 0x0804, 0x8bc9,
-	0x080c, 0x8d84, 0x7003, 0x0100, 0x782c, 0x9005, 0x0110, 0x700a,
-	0x0010, 0x700b, 0x0003, 0x7814, 0x700e, 0x60c3, 0x0008, 0x0804,
-	0x8fa0, 0x00d6, 0x080c, 0x8d84, 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,
-	0xbac4, 0xd28c, 0x1108, 0xc0cd, 0x9094, 0x0030, 0x9296, 0x0010,
-	0x0140, 0xd1ec, 0x0130, 0x9094, 0x0030, 0x9296, 0x0010, 0x0108,
-	0xc0bd, 0x002e, 0x7026, 0x60c3, 0x0014, 0x00de, 0x0804, 0x8fa0,
-	0x080c, 0x8d84, 0x7003, 0x0210, 0x7007, 0x0014, 0x700f, 0x0100,
-	0x60c3, 0x0014, 0x0804, 0x8fa0, 0x080c, 0x8d84, 0x7003, 0x0200,
-	0x0804, 0x8b4f, 0x080c, 0x8d84, 0x7003, 0x0100, 0x700b, 0x0003,
-	0x700f, 0x2a00, 0x60c3, 0x0008, 0x0804, 0x8fa0, 0x080c, 0x8d84,
-	0x7003, 0x0100, 0x700b, 0x000b, 0x60c3, 0x0008, 0x0804, 0x8fa0,
-	0x0026, 0x00d6, 0x0036, 0x0046, 0x2019, 0x3200, 0x2021, 0x0800,
-	0x0040, 0x0026, 0x00d6, 0x0036, 0x0046, 0x2019, 0x2200, 0x2021,
-	0x0100, 0x080c, 0x97f4, 0xb810, 0x9305, 0x7002, 0xb814, 0x7006,
-	0x2069, 0x1800, 0x6878, 0x700a, 0x687c, 0x700e, 0x9485, 0x0029,
-	0x7012, 0x004e, 0x003e, 0x00de, 0x080c, 0x8f94, 0x721a, 0x9f95,
-	0x0000, 0x7222, 0x7027, 0xffff, 0x2071, 0x024c, 0x002e, 0x0005,
-	0x0026, 0x080c, 0x97f4, 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, 0x97f4, 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, 0x8f94, 0x721a, 0x7a08, 0x7222,
-	0x2f10, 0x7226, 0x2071, 0x024c, 0x002e, 0x0005, 0x080c, 0x8f94,
-	0x721a, 0x7a08, 0x7222, 0x7814, 0x7026, 0x2071, 0x024c, 0x002e,
-	0x0005, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2069, 0x0200,
-	0x2071, 0x0240, 0x6004, 0x908a, 0x0085, 0x0a0c, 0x0d65, 0x908a,
-	0x0092, 0x1a0c, 0x0d65, 0x6110, 0x2158, 0xb984, 0x2c78, 0x2061,
-	0x0100, 0x619a, 0x9082, 0x0085, 0x0033, 0x00fe, 0x00ee, 0x00de,
-	0x00ce, 0x00be, 0x0005, 0x8df2, 0x8e01, 0x8e0c, 0x8df0, 0x8df0,
-	0x8df0, 0x8df2, 0x8df0, 0x8df0, 0x8df0, 0x8df0, 0x8df0, 0x8df0,
-	0x080c, 0x0d65, 0x0411, 0x60c3, 0x0000, 0x0026, 0x080c, 0x27dd,
-	0x0228, 0x2011, 0x0101, 0x2204, 0xc0c5, 0x2012, 0x002e, 0x0804,
-	0x8fa0, 0x0431, 0x7808, 0x700a, 0x7814, 0x700e, 0x7017, 0xffff,
-	0x60c3, 0x000c, 0x0804, 0x8fa0, 0x0479, 0x7003, 0x0003, 0x7007,
-	0x0300, 0x60c3, 0x0004, 0x0804, 0x8fa0, 0x0026, 0x080c, 0x97f4,
-	0xb810, 0x9085, 0x8100, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800,
-	0x6878, 0x700a, 0x687c, 0x700e, 0x7013, 0x0009, 0x0804, 0x8d54,
-	0x0026, 0x080c, 0x97f4, 0xb810, 0x9085, 0x8400, 0x7002, 0xb814,
-	0x7006, 0x2069, 0x1800, 0x6878, 0x700a, 0x687c, 0x700e, 0x2001,
-	0x0099, 0x7012, 0x0804, 0x8db6, 0x0026, 0x080c, 0x97f4, 0xb810,
-	0x9085, 0x8500, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0x6878,
-	0x700a, 0x687c, 0x700e, 0x2001, 0x0099, 0x7012, 0x0804, 0x8db6,
-	0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2c78, 0x2069, 0x0200,
-	0x2071, 0x0240, 0x7804, 0x908a, 0x0040, 0x0a0c, 0x0d65, 0x908a,
-	0x0057, 0x1a0c, 0x0d65, 0x7910, 0x2158, 0xb984, 0x2061, 0x0100,
-	0x619a, 0x9082, 0x0040, 0x0033, 0x00fe, 0x00ee, 0x00de, 0x00ce,
-	0x00be, 0x0005, 0x8e85, 0x8e85, 0x8e85, 0x8eab, 0x8e85, 0x8e85,
-	0x8e85, 0x8e85, 0x8e85, 0x8e85, 0x8e85, 0x9340, 0x9348, 0x9350,
-	0x9358, 0x8e85, 0x8e85, 0x8e85, 0x9338, 0x080c, 0x0d65, 0x6813,
-	0x0008, 0xba8c, 0x8210, 0xb8c4, 0xd084, 0x0128, 0x7a4e, 0x7b14,
-	0x7b52, 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, 0x0016, 0x7814, 0x9084, 0x0700, 0x8007,
-	0x0013, 0x001e, 0x0005, 0x8ebb, 0x8ebb, 0x8ebd, 0x8ebb, 0x8ebb,
-	0x8ebb, 0x8ed7, 0x8ebb, 0x080c, 0x0d65, 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, 0x8fa0, 0x2009,
-	0x0003, 0x0019, 0x7033, 0x7f00, 0x0cb0, 0x0016, 0x080c, 0x97f4,
-	0x001e, 0xb810, 0x9085, 0x0100, 0x7002, 0xb814, 0x7006, 0x2069,
-	0x1800, 0x6a78, 0x720a, 0x6a7c, 0x720e, 0x7013, 0x0888, 0x918d,
-	0x0008, 0x7116, 0x080c, 0x8f94, 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, 0x0002,
-	0x8f1f, 0x8f1f, 0x8f1f, 0x8f1f, 0x8f1f, 0x8f1f, 0x8f1f, 0x8f1f,
-	0x8f1f, 0x8f1f, 0x8f21, 0x8f1f, 0x8f1f, 0x8f1f, 0x8f1f, 0x080c,
-	0x0d65, 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, 0x97d4,
-	0x2009, 0x07d0, 0x60c4, 0x9084, 0xfff0, 0x9005, 0x0110, 0x2009,
-	0x1b58, 0x080c, 0x8223, 0x003e, 0x004e, 0x005e, 0x00ce, 0x00de,
-	0x00ee, 0x009e, 0x00be, 0x0005, 0x7a40, 0x9294, 0x00ff, 0x8217,
-	0x0005, 0x00d6, 0x2069, 0x19bf, 0x686b, 0x0001, 0x00de, 0x0005,
-	0x60a3, 0x0056, 0x60a7, 0x9575, 0x00f1, 0x080c, 0x8215, 0x0005,
-	0x0016, 0x2001, 0x180c, 0x200c, 0x9184, 0x0600, 0x9086, 0x0600,
-	0x0128, 0x0089, 0x080c, 0x8215, 0x001e, 0x0005, 0xc1e5, 0x2001,
-	0x180c, 0x2102, 0x2001, 0x19c0, 0x2003, 0x0000, 0x2001, 0x19cb,
-	0x2003, 0x0000, 0x0c88, 0x0006, 0x0016, 0x0026, 0x2009, 0x1804,
-	0x2011, 0x0009, 0x080c, 0x28bb, 0x002e, 0x001e, 0x000e, 0x0005,
-	0x0016, 0x00c6, 0x0006, 0x080c, 0x98c7, 0x0106, 0x2061, 0x0100,
-	0x61a4, 0x60a7, 0x95f5, 0x0016, 0x0026, 0x2009, 0x1804, 0x2011,
-	0x0008, 0x080c, 0x28bb, 0x002e, 0x001e, 0x010e, 0x090c, 0x98e3,
-	0x000e, 0xa001, 0xa001, 0xa001, 0x61a6, 0x00ce, 0x001e, 0x0005,
-	0x00c6, 0x00d6, 0x0016, 0x0026, 0x2061, 0x0100, 0x2069, 0x0140,
-	0x080c, 0x70ba, 0x1510, 0x2001, 0x19e4, 0x2004, 0x9005, 0x1904,
-	0x904f, 0x080c, 0x715f, 0x11a8, 0x2069, 0x0380, 0x6843, 0x0101,
-	0x6844, 0xd084, 0x1de8, 0x2061, 0x0100, 0x6020, 0xd0b4, 0x1120,
-	0x6024, 0xd084, 0x090c, 0x0d65, 0x6843, 0x0100, 0x080c, 0x8215,
-	0x04b0, 0x00c6, 0x2061, 0x19bf, 0x00f0, 0x6904, 0x9194, 0x4000,
-	0x0598, 0x080c, 0x8fd0, 0x080c, 0x2882, 0x00c6, 0x2061, 0x19bf,
-	0x6134, 0x9192, 0x0008, 0x1278, 0x8108, 0x6136, 0x080c, 0x98c7,
-	0x6130, 0x080c, 0x98e3, 0x00ce, 0x81ff, 0x01c8, 0x080c, 0x8215,
-	0x080c, 0x8fc3, 0x00a0, 0x080c, 0x98c7, 0x6130, 0x91e5, 0x0000,
-	0x0150, 0x080c, 0xd659, 0x080c, 0x821e, 0x6003, 0x0001, 0x2009,
-	0x0014, 0x080c, 0x9c82, 0x080c, 0x98e3, 0x00ce, 0x0000, 0x002e,
-	0x001e, 0x00de, 0x00ce, 0x0005, 0x2001, 0x19e4, 0x2004, 0x9005,
-	0x1db0, 0x00c6, 0x2061, 0x19bf, 0x6134, 0x9192, 0x0003, 0x1ad8,
-	0x8108, 0x6136, 0x00ce, 0x080c, 0x8215, 0x080c, 0x5bb2, 0x2009,
-	0x185a, 0x2114, 0x8210, 0x220a, 0x0c10, 0x0096, 0x00c6, 0x00d6,
-	0x00e6, 0x0016, 0x0026, 0x080c, 0x822b, 0x080c, 0x98c7, 0x2001,
-	0x0387, 0x2003, 0x0202, 0x2071, 0x19bf, 0x714c, 0x81ff, 0x0904,
-	0x90e3, 0x2061, 0x0100, 0x2069, 0x0140, 0x080c, 0x70ba, 0x11c0,
-	0x0036, 0x2019, 0x0002, 0x080c, 0x929d, 0x003e, 0x714c, 0x2160,
-	0x080c, 0xd659, 0x2009, 0x004a, 0x6003, 0x0003, 0x080c, 0x9c82,
-	0x2001, 0x0386, 0x2003, 0x5040, 0x080c, 0x715f, 0x0804, 0x90e3,
-	0x6904, 0xd1f4, 0x0904, 0x90f0, 0x080c, 0x2882, 0x00c6, 0x704c,
-	0x9065, 0x090c, 0x0d65, 0x6020, 0x00ce, 0x9086, 0x0006, 0x1518,
-	0x61c8, 0x60c4, 0x9105, 0x11f8, 0x2009, 0x180c, 0x2104, 0xd0d4,
-	0x01d0, 0x6214, 0x9294, 0x1800, 0x1128, 0x6224, 0x9294, 0x0002,
-	0x1510, 0x0010, 0xc0d4, 0x200a, 0x6014, 0x9084, 0xe7fd, 0x9085,
-	0x0010, 0x6016, 0x704c, 0x2060, 0x080c, 0x88ec, 0x2009, 0x0049,
-	0x080c, 0x9c82, 0x0080, 0x0036, 0x2019, 0x0001, 0x080c, 0x929d,
-	0x003e, 0x714c, 0x2160, 0x080c, 0xd659, 0x2009, 0x004a, 0x6003,
-	0x0003, 0x080c, 0x9c82, 0x2001, 0x0387, 0x2003, 0x0200, 0x080c,
-	0x98e3, 0x002e, 0x001e, 0x00ee, 0x00de, 0x00ce, 0x009e, 0x0005,
-	0xd1ec, 0x1904, 0x90a4, 0x0804, 0x90a6, 0x0026, 0x00e6, 0x2071,
-	0x19bf, 0x706c, 0xd084, 0x01d0, 0xc084, 0x706e, 0x714c, 0x81ff,
-	0x01a8, 0x2071, 0x0100, 0x9188, 0x0008, 0x2114, 0x928e, 0x0006,
-	0x1138, 0x2009, 0x1984, 0x2011, 0x0012, 0x080c, 0x28bb, 0x0030,
-	0x2009, 0x1984, 0x2011, 0x0016, 0x080c, 0x28bb, 0x00ee, 0x002e,
-	0x0005, 0x9036, 0x2001, 0x19c9, 0x2004, 0x9005, 0x0128, 0x9c06,
-	0x0128, 0x2c30, 0x600c, 0x0cc8, 0x9085, 0x0001, 0x0005, 0x00f6,
-	0x2079, 0x19bf, 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, 0x9363, 0x080c, 0xba5f, 0x00fe, 0x0005,
-	0x080c, 0x8d39, 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, 0x8fa0, 0x080c, 0x8d39, 0x7003, 0x0f00, 0x7808,
-	0xd09c, 0x0128, 0xb810, 0x9084, 0x00ff, 0x700a, 0xb814, 0x700e,
-	0x60c3, 0x0008, 0x0804, 0x8fa0, 0x0156, 0x080c, 0x8d84, 0x7003,
-	0x0200, 0x2011, 0x1848, 0x63f0, 0x2312, 0x20a9, 0x0006, 0x2011,
-	0x1840, 0x2019, 0x1841, 0x9ef0, 0x0002, 0x2376, 0x8e70, 0x2276,
-	0x8e70, 0x9398, 0x0002, 0x9290, 0x0002, 0x1f04, 0x918d, 0x60c3,
-	0x001c, 0x015e, 0x0804, 0x8fa0, 0x0016, 0x0026, 0x080c, 0x8d60,
-	0x080c, 0x8d72, 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,
-	0x8fa0, 0x002e, 0x001e, 0x0005, 0x20a9, 0x0010, 0x4003, 0x080c,
-	0x97df, 0x20a1, 0x0240, 0x22a8, 0x4003, 0x0c68, 0x080c, 0x8d39,
-	0x7003, 0x6200, 0x7808, 0x700e, 0x60c3, 0x0008, 0x0804, 0x8fa0,
-	0x0016, 0x0026, 0x080c, 0x8d39, 0x20e9, 0x0000, 0x20a1, 0x024c,
-	0x7814, 0x0096, 0x2048, 0xa800, 0x2048, 0xa860, 0x20e0, 0xa85c,
-	0x9080, 0x0023, 0x2098, 0x009e, 0x7808, 0x9088, 0x0002, 0x21a8,
-	0x4003, 0x8003, 0x60c2, 0x080c, 0x8fa0, 0x002e, 0x001e, 0x0005,
-	0x00e6, 0x00c6, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19bf,
-	0x7010, 0x2060, 0x8cff, 0x0188, 0x080c, 0xba85, 0x1110, 0x080c,
-	0xa59c, 0x600c, 0x0006, 0x080c, 0xbd01, 0x600f, 0x0000, 0x080c,
-	0x9be6, 0x080c, 0x9363, 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, 0x19bf, 0x7030, 0x2060, 0x8cff,
-	0x0548, 0x080c, 0x8fd0, 0x6ac0, 0x68c3, 0x0000, 0x080c, 0x821e,
-	0x00c6, 0x2061, 0x0100, 0x080c, 0x97f8, 0x00ce, 0x20a9, 0x01f4,
-	0x04b1, 0x080c, 0x8891, 0x6044, 0xd0ac, 0x1128, 0x2001, 0x1960,
-	0x2004, 0x604a, 0x0020, 0x2009, 0x0013, 0x080c, 0x9c82, 0x000e,
-	0x001e, 0x002e, 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x015e,
-	0x012e, 0x0005, 0x2001, 0x1800, 0x2004, 0x9096, 0x0001, 0x0d78,
-	0x9096, 0x0004, 0x0d60, 0x080c, 0x821e, 0x6814, 0x9084, 0x0001,
-	0x0110, 0x68a7, 0x95f5, 0x6817, 0x0008, 0x68c3, 0x0000, 0x2011,
-	0x5b5c, 0x080c, 0x816c, 0x20a9, 0x01f4, 0x0009, 0x08c0, 0x6824,
-	0xd094, 0x0140, 0x6827, 0x0004, 0x7804, 0x9084, 0x4000, 0x190c,
-	0x2882, 0x0090, 0xd084, 0x0118, 0x6827, 0x0001, 0x0010, 0x1f04,
-	0x927f, 0x7804, 0x9084, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c,
-	0x2872, 0x9006, 0x080c, 0x2872, 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, 0x19bf, 0x704c, 0x2060, 0x8cff, 0x0904, 0x9312,
-	0x9386, 0x0002, 0x1128, 0x6814, 0x9084, 0x0002, 0x0904, 0x9312,
-	0x68af, 0x95f5, 0x6817, 0x0010, 0x2009, 0x00fa, 0x8109, 0x1df0,
-	0x69c6, 0x68cb, 0x0008, 0x080c, 0x822b, 0x080c, 0x1c9f, 0x2001,
-	0x0032, 0x6920, 0xd1bc, 0x0130, 0x8001, 0x1dd8, 0x692c, 0x918d,
-	0x0008, 0x692e, 0x20a9, 0x03e8, 0x6824, 0xd094, 0x0140, 0x6827,
-	0x0004, 0x7804, 0x9084, 0x4000, 0x190c, 0x2882, 0x0090, 0xd08c,
-	0x0118, 0x6827, 0x0002, 0x0010, 0x1f04, 0x92e4, 0x7804, 0x9084,
-	0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2872, 0x9006, 0x080c,
-	0x2872, 0x6827, 0x4000, 0x6824, 0x83ff, 0x1160, 0x2009, 0x0049,
-	0x080c, 0x88ec, 0x6044, 0xd0ac, 0x1118, 0x6003, 0x0002, 0x0010,
-	0x080c, 0x9c82, 0x000e, 0x2071, 0x0380, 0xd08c, 0x1110, 0x701f,
-	0x0200, 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, 0x6a3e, 0x012e, 0x00de, 0x0005,
-	0x080c, 0x8e87, 0x785c, 0x7032, 0x7042, 0x7047, 0x1000, 0x00f8,
-	0x080c, 0x8e87, 0x785c, 0x7032, 0x7042, 0x7047, 0x4000, 0x00b8,
-	0x080c, 0x8e87, 0x785c, 0x7032, 0x7042, 0x7047, 0x2000, 0x0078,
-	0x080c, 0x8e87, 0x785c, 0x7032, 0x7042, 0x7047, 0x0400, 0x0038,
-	0x080c, 0x8e87, 0x785c, 0x7032, 0x7042, 0x7047, 0x0200, 0x60c3,
-	0x0020, 0x0804, 0x8fa0, 0x00e6, 0x2071, 0x19bf, 0x702c, 0x9005,
-	0x0110, 0x8001, 0x702e, 0x00ee, 0x0005, 0x00f6, 0x00e6, 0x00d6,
-	0x00c6, 0x0076, 0x0066, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071,
-	0x19bf, 0x7620, 0x2660, 0x2678, 0x2039, 0x0001, 0x87ff, 0x0904,
-	0x9408, 0x8cff, 0x0904, 0x9408, 0x6020, 0x9086, 0x0006, 0x1904,
-	0x9403, 0x88ff, 0x0138, 0x2800, 0x9c06, 0x1904, 0x9403, 0x2039,
-	0x0000, 0x0050, 0x6010, 0x9b06, 0x1904, 0x9403, 0x85ff, 0x0120,
-	0x605c, 0x9106, 0x1904, 0x9403, 0x7030, 0x9c06, 0x15b0, 0x2069,
-	0x0100, 0x68c0, 0x9005, 0x1160, 0x6824, 0xd084, 0x0148, 0x6827,
-	0x0001, 0x080c, 0x821e, 0x080c, 0x948d, 0x7033, 0x0000, 0x0428,
-	0x080c, 0x821e, 0x6820, 0xd0b4, 0x0110, 0x68a7, 0x95f5, 0x6817,
-	0x0008, 0x68c3, 0x0000, 0x080c, 0x948d, 0x7033, 0x0000, 0x0036,
-	0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100,
-	0x080c, 0x2872, 0x9006, 0x080c, 0x2872, 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, 0xb86e, 0x0110, 0x080c,
-	0xd267, 0x009e, 0x080c, 0x9c20, 0x080c, 0x9363, 0x88ff, 0x1190,
-	0x00ce, 0x0804, 0x937e, 0x2c78, 0x600c, 0x2060, 0x0804, 0x937e,
-	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, 0x7648, 0x2660, 0x2678,
-	0x8cff, 0x0904, 0x947c, 0x6020, 0x9086, 0x0006, 0x1904, 0x9477,
-	0x87ff, 0x0128, 0x2700, 0x9c06, 0x1904, 0x9477, 0x0040, 0x6010,
-	0x9b06, 0x15e8, 0x85ff, 0x0118, 0x605c, 0x9106, 0x15c0, 0x704c,
-	0x9c06, 0x1168, 0x0036, 0x2019, 0x0001, 0x080c, 0x929d, 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, 0xb86e, 0x0110, 0x080c, 0xd267,
-	0x080c, 0x9c20, 0x87ff, 0x1198, 0x00ce, 0x0804, 0x9428, 0x2c78,
-	0x600c, 0x2060, 0x0804, 0x9428, 0x9006, 0x012e, 0x000e, 0x002e,
-	0x006e, 0x00ce, 0x009e, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x601b,
-	0x0000, 0x00ce, 0x97bd, 0x0001, 0x0c80, 0x00e6, 0x2071, 0x19bf,
-	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, 0x19bf, 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, 0x8891, 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, 0x7610, 0x2660, 0x2678, 0x8cff, 0x0904, 0x957a,
-	0x6010, 0x00b6, 0x2058, 0xb8a0, 0x00be, 0x9206, 0x1904, 0x9575,
-	0x7030, 0x9c06, 0x1520, 0x2069, 0x0100, 0x68c0, 0x9005, 0x0904,
-	0x954c, 0x080c, 0x8fd0, 0x68c3, 0x0000, 0x080c, 0x948d, 0x7033,
-	0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138,
-	0x2001, 0x0100, 0x080c, 0x2872, 0x9006, 0x080c, 0x2872, 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, 0xba74, 0x1180, 0x080c, 0x305d, 0x080c, 0xba85,
-	0x1518, 0x080c, 0xa59c, 0x0400, 0x080c, 0x948d, 0x6824, 0xd084,
-	0x09b0, 0x6827, 0x0001, 0x0898, 0x080c, 0xba85, 0x1118, 0x080c,
-	0xa59c, 0x0090, 0x6014, 0x2048, 0x080c, 0xb86e, 0x0168, 0x6020,
-	0x9086, 0x0003, 0x1508, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000,
-	0x080c, 0x69a9, 0x080c, 0xba5f, 0x080c, 0xbd01, 0x080c, 0x9c20,
-	0x080c, 0x9363, 0x00ce, 0x0804, 0x94f5, 0x2c78, 0x600c, 0x2060,
-	0x0804, 0x94f5, 0x012e, 0x000e, 0x002e, 0x006e, 0x00ce, 0x00de,
-	0x00ee, 0x00fe, 0x009e, 0x0005, 0x6020, 0x9086, 0x0006, 0x1d20,
-	0x080c, 0xd267, 0x0c08, 0x00d6, 0x080c, 0x8d84, 0x7003, 0x0200,
-	0x7007, 0x0014, 0x60c3, 0x0014, 0x20e1, 0x0001, 0x2099, 0x1961,
-	0x20e9, 0x0000, 0x20a1, 0x0250, 0x20a9, 0x0004, 0x4003, 0x7023,
-	0x0004, 0x7027, 0x7878, 0x080c, 0x8fa0, 0x00de, 0x0005, 0x080c,
-	0x8d84, 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, 0x8fa0, 0x00b6, 0x00d6, 0x0016, 0x00d6, 0x2f68,
-	0x2009, 0x0035, 0x080c, 0xbf07, 0x00de, 0x1904, 0x9628, 0x080c,
-	0x8d39, 0x7003, 0x1300, 0x782c, 0x080c, 0x9737, 0x2068, 0x6820,
-	0x9086, 0x0003, 0x0560, 0x7810, 0x2058, 0xbaa0, 0x080c, 0x9b65,
-	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,
-	0x9b65, 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, 0x8fa0, 0x00be, 0x0005,
-	0x781b, 0x0001, 0x7803, 0x0006, 0x001e, 0x00de, 0x00be, 0x0005,
-	0x792c, 0x9180, 0x0008, 0x200c, 0x9186, 0x0006, 0x01c0, 0x9186,
-	0x0003, 0x0904, 0x96a7, 0x9186, 0x0005, 0x0904, 0x968f, 0x9186,
-	0x0004, 0x05f0, 0x9186, 0x0008, 0x0904, 0x9698, 0x7807, 0x0037,
-	0x782f, 0x0003, 0x7817, 0x1700, 0x080c, 0x9714, 0x0005, 0x080c,
-	0x96d5, 0x00d6, 0x0026, 0x792c, 0x2168, 0x2009, 0x4000, 0x6800,
-	0x6a44, 0xd2fc, 0x11f8, 0x0002, 0x966f, 0x967a, 0x9671, 0x967a,
-	0x9676, 0x966f, 0x966f, 0x967a, 0x967a, 0x967a, 0x967a, 0x966f,
-	0x966f, 0x966f, 0x966f, 0x966f, 0x967a, 0x966f, 0x967a, 0x080c,
-	0x0d65, 0x6824, 0xd0e4, 0x0110, 0xd0cc, 0x0110, 0x900e, 0x0010,
-	0x2009, 0x2000, 0x682c, 0x7022, 0x6830, 0x7026, 0x0804, 0x96ce,
-	0x080c, 0x96d5, 0x00d6, 0x0026, 0x792c, 0x2168, 0x2009, 0x4000,
-	0x6a00, 0x9286, 0x0002, 0x1108, 0x900e, 0x0804, 0x96ce, 0x080c,
-	0x96d5, 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, 0x8fa0, 0x00b6, 0x0036, 0x0046,
-	0x0056, 0x0066, 0x080c, 0x8d84, 0x9006, 0x7003, 0x0200, 0x7938,
-	0x710a, 0x793c, 0x710e, 0x7810, 0x2058, 0xb8a0, 0x080c, 0x9b65,
-	0x1118, 0x9092, 0x007e, 0x0268, 0x00d6, 0x2069, 0x181e, 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, 0x8d84, 0x7003, 0x0100,
-	0x782c, 0x700a, 0x7814, 0x700e, 0x700e, 0x60c3, 0x0008, 0x0804,
-	0x8fa0, 0x080c, 0x8d30, 0x7003, 0x1400, 0x7838, 0x700a, 0x0079,
-	0x783c, 0x700e, 0x782c, 0x7012, 0x7830, 0x7016, 0x7834, 0x9084,
-	0x00ff, 0x8007, 0x701a, 0x60c3, 0x0010, 0x0804, 0x8fa0, 0x00e6,
-	0x2071, 0x0240, 0x0006, 0x00f6, 0x2078, 0x7810, 0x00b6, 0x2058,
-	0xb8c4, 0xd084, 0x0120, 0x7850, 0x702a, 0x784c, 0x702e, 0x00be,
-	0x00fe, 0x000e, 0x00ee, 0x0005, 0x080c, 0x8d7b, 0x7003, 0x0100,
-	0x782c, 0x700a, 0x7814, 0x700e, 0x60c3, 0x0008, 0x0804, 0x8fa0,
-	0x00a9, 0x7914, 0x712a, 0x60c3, 0x0000, 0x60a7, 0x9575, 0x0026,
-	0x080c, 0x27dd, 0x0228, 0x2011, 0x0101, 0x2204, 0xc0c5, 0x2012,
-	0x002e, 0x080c, 0x8fc3, 0x080c, 0x8215, 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, 0x97f4, 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,
-	0x0026, 0x2110, 0x900e, 0x080c, 0x28bb, 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,
-	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, 0x19bf, 0x7610, 0x2660, 0x2678, 0x8cff,
-	0x0904, 0x98a4, 0x7030, 0x9c06, 0x1520, 0x2069, 0x0100, 0x68c0,
-	0x9005, 0x0904, 0x9876, 0x080c, 0x8fd0, 0x68c3, 0x0000, 0x080c,
-	0x948d, 0x7033, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384,
-	0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2872, 0x9006, 0x080c,
-	0x2872, 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, 0xba74, 0x1180, 0x080c, 0x305d,
-	0x080c, 0xba85, 0x1518, 0x080c, 0xa59c, 0x0400, 0x080c, 0x948d,
-	0x6824, 0xd084, 0x09b0, 0x6827, 0x0001, 0x0898, 0x080c, 0xba85,
-	0x1118, 0x080c, 0xa59c, 0x0090, 0x6014, 0x2048, 0x080c, 0xb86e,
-	0x0168, 0x6020, 0x9086, 0x0003, 0x1520, 0xa867, 0x0103, 0xab7a,
-	0xa877, 0x0000, 0x080c, 0x69b5, 0x080c, 0xba5f, 0x080c, 0xbd01,
-	0x080c, 0x9c20, 0x080c, 0x9363, 0x00ce, 0x0804, 0x9827, 0x2c78,
-	0x600c, 0x2060, 0x0804, 0x9827, 0x7013, 0x0000, 0x700f, 0x0000,
-	0x012e, 0x006e, 0x009e, 0x00ae, 0x00ce, 0x00de, 0x00ee, 0x00fe,
-	0x0005, 0x6020, 0x9086, 0x0006, 0x1d08, 0x080c, 0xd267, 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,
-	0x0d65, 0x001e, 0x0005, 0x2001, 0x0382, 0x2004, 0x9084, 0x0007,
-	0x9086, 0x0003, 0x1120, 0x2001, 0x0380, 0x2003, 0x0001, 0x0005,
-	0x0156, 0x0016, 0x0026, 0x00e6, 0x900e, 0x2071, 0x19bf, 0x0469,
-	0x0106, 0x0190, 0x7004, 0x9086, 0x0003, 0x0148, 0x20a9, 0x1000,
-	0x6044, 0xd0fc, 0x01d8, 0x1f04, 0x9900, 0x080c, 0x0d65, 0x080c,
-	0x98c7, 0x6044, 0xd0fc, 0x0190, 0x7030, 0x9c06, 0x1148, 0x080c,
-	0x8891, 0x6044, 0xd0dc, 0x0150, 0xc0dc, 0x6046, 0x700a, 0x7042,
-	0x704c, 0x9c06, 0x190c, 0x0d65, 0x080c, 0x88ec, 0x010e, 0x1919,
-	0x00ee, 0x002e, 0x001e, 0x015e, 0x0005, 0x2001, 0x0382, 0x2004,
-	0x9084, 0x0007, 0x9086, 0x0003, 0x0005, 0x0126, 0x2091, 0x2400,
-	0x7808, 0xd0a4, 0x190c, 0x0d5e, 0xd09c, 0x0128, 0x7820, 0x908c,
-	0xf000, 0x11b8, 0x0012, 0x012e, 0x0005, 0x994d, 0x998b, 0x99b2,
-	0x99e2, 0x99f2, 0x9a03, 0x9a12, 0x9a20, 0x9a31, 0x9a35, 0x994d,
-	0x994d, 0x994d, 0x994d, 0x994d, 0x994d, 0x080c, 0x0d65, 0x012e,
-	0x0005, 0x2060, 0x6044, 0xd0bc, 0x0140, 0xc0bc, 0x6046, 0x6000,
-	0x908a, 0x0016, 0x1a0c, 0x0d65, 0x0012, 0x012e, 0x0005, 0x9972,
-	0x9974, 0x9972, 0x997a, 0x9972, 0x9972, 0x9972, 0x9972, 0x9972,
-	0x9974, 0x9972, 0x9974, 0x9972, 0x9974, 0x9972, 0x9972, 0x9972,
-	0x9974, 0x9972, 0x080c, 0x0d65, 0x2009, 0x0013, 0x080c, 0x9c82,
-	0x012e, 0x0005, 0x6014, 0x2048, 0xa87c, 0xd0dc, 0x0130, 0x080c,
-	0x83d6, 0x080c, 0x9be6, 0x012e, 0x0005, 0x2009, 0x0049, 0x080c,
-	0x9c82, 0x012e, 0x0005, 0x080c, 0x98c7, 0x2001, 0x19e4, 0x2003,
-	0x0000, 0x7030, 0x9065, 0x090c, 0x0d65, 0x7034, 0x9092, 0x00c8,
-	0x1258, 0x8000, 0x7036, 0x7004, 0x9086, 0x0003, 0x0110, 0x7007,
-	0x0000, 0x781f, 0x0808, 0x0040, 0x080c, 0xd659, 0x6003, 0x0001,
-	0x2009, 0x0014, 0x080c, 0x9c82, 0x781f, 0x0100, 0x080c, 0x98e3,
-	0x012e, 0x0005, 0x080c, 0x98c7, 0x714c, 0x81ff, 0x1128, 0x2011,
-	0x19e7, 0x2013, 0x0000, 0x0400, 0x2061, 0x0100, 0x7150, 0x9192,
-	0x7530, 0x12b8, 0x8108, 0x7152, 0x714c, 0x9188, 0x0008, 0x210c,
-	0x918e, 0x0006, 0x1138, 0x6014, 0x9084, 0x1984, 0x9085, 0x0012,
-	0x6016, 0x0050, 0x6014, 0x9084, 0x1984, 0x9085, 0x0016, 0x6016,
-	0x0018, 0x706c, 0xc085, 0x706e, 0x781f, 0x0200, 0x080c, 0x98e3,
-	0x012e, 0x0005, 0x080c, 0x98c7, 0x714c, 0x2160, 0x6003, 0x0003,
-	0x2009, 0x004a, 0x080c, 0x9c82, 0x781f, 0x0200, 0x080c, 0x98e3,
-	0x012e, 0x0005, 0x7808, 0xd09c, 0x0de8, 0x7820, 0x2060, 0x6003,
-	0x0003, 0x080c, 0x98c7, 0x080c, 0x1c27, 0x781f, 0x0400, 0x080c,
-	0x98e3, 0x012e, 0x0005, 0x7808, 0xd09c, 0x0de8, 0x7820, 0x2060,
-	0x080c, 0x98c7, 0x080c, 0x1c6f, 0x781f, 0x0400, 0x080c, 0x98e3,
-	0x012e, 0x0005, 0x7030, 0x9065, 0x0148, 0x6044, 0xc0bc, 0x6046,
-	0x7104, 0x9186, 0x0003, 0x0110, 0x080c, 0x8950, 0x012e, 0x0005,
-	0x00f6, 0x703c, 0x9086, 0x0002, 0x0148, 0x704c, 0x907d, 0x0130,
-	0x7844, 0xc0bc, 0x7846, 0x080c, 0x8efa, 0x0000, 0x00fe, 0x012e,
-	0x0005, 0x080c, 0x715f, 0x012e, 0x0005, 0x080c, 0x0d65, 0x0005,
-	0x00e6, 0x2071, 0x19bf, 0x6044, 0xc0bc, 0x6046, 0xd0fc, 0x01b8,
-	0x704c, 0x9c06, 0x1190, 0x2019, 0x0001, 0x080c, 0x929d, 0x704f,
-	0x0000, 0x2001, 0x0109, 0x2004, 0xd08c, 0x1138, 0x2001, 0x0108,
-	0x2004, 0xd0bc, 0x1110, 0x703f, 0x0000, 0x080c, 0x94a4, 0x00ee,
-	0x0005, 0x0026, 0x7010, 0x9c06, 0x1178, 0x080c, 0x9363, 0x6044,
-	0xc0fc, 0x6046, 0x600c, 0x9015, 0x0120, 0x7212, 0x600f, 0x0000,
-	0x0010, 0x7212, 0x720e, 0x9006, 0x002e, 0x0005, 0x0026, 0x7020,
-	0x9c06, 0x1178, 0x080c, 0x9363, 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, 0x821e, 0x080c,
-	0x8fd0, 0x68c3, 0x0000, 0x080c, 0x948d, 0x2069, 0x0140, 0x6b04,
-	0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2872, 0x9006,
-	0x080c, 0x2872, 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,
-	0x992d, 0x003e, 0x001e, 0x012e, 0x00ce, 0x6200, 0x2200, 0x9106,
-	0x0d58, 0x2200, 0x0010, 0x8319, 0x1d38, 0x003e, 0x002e, 0x001e,
-	0x0005, 0x00d6, 0x0156, 0x080c, 0x8d84, 0x7a14, 0x82ff, 0x0138,
-	0x7003, 0x0100, 0x700b, 0x0003, 0x60c3, 0x0008, 0x0490, 0x7003,
-	0x0200, 0x7007, 0x0000, 0x2069, 0x1800, 0x901e, 0x6800, 0x9086,
-	0x0004, 0x1110, 0xc38d, 0x0060, 0x080c, 0x70ba, 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, 0x9b0d, 0x60c3,
-	0x0020, 0x080c, 0x8fa0, 0x015e, 0x00de, 0x0005, 0x0156, 0x080c,
-	0x8d84, 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, 0x8fa0, 0x0006, 0x2001, 0x1836,
-	0x2004, 0xd0ac, 0x000e, 0x0005, 0x2011, 0x0003, 0x080c, 0x9324,
-	0x2011, 0x0002, 0x080c, 0x932e, 0x080c, 0x921d, 0x0036, 0x901e,
-	0x080c, 0x929d, 0x003e, 0x0005, 0x2071, 0x188b, 0x7000, 0x9005,
-	0x0140, 0x2001, 0x0812, 0x2071, 0x1800, 0x7072, 0x7076, 0x7067,
-	0xffd4, 0x2071, 0x1800, 0x7070, 0x7052, 0x7057, 0x1ddc, 0x0005,
-	0x00e6, 0x0126, 0x2071, 0x1800, 0x2091, 0x8000, 0x7550, 0x9582,
-	0x0010, 0x0608, 0x7054, 0x2060, 0x6000, 0x9086, 0x0000, 0x0148,
-	0x9ce0, 0x001c, 0x7064, 0x9c02, 0x1208, 0x0cb0, 0x2061, 0x1ddc,
-	0x0c98, 0x6003, 0x0008, 0x8529, 0x7552, 0x9ca8, 0x001c, 0x7064,
-	0x9502, 0x1230, 0x7556, 0x9085, 0x0001, 0x012e, 0x00ee, 0x0005,
-	0x7057, 0x1ddc, 0x0cc0, 0x9006, 0x0cc0, 0x00e6, 0x2071, 0x1800,
-	0x7550, 0x9582, 0x0010, 0x0600, 0x7054, 0x2060, 0x6000, 0x9086,
-	0x0000, 0x0148, 0x9ce0, 0x001c, 0x7064, 0x9c02, 0x1208, 0x0cb0,
-	0x2061, 0x1ddc, 0x0c98, 0x6003, 0x0008, 0x8529, 0x7552, 0x9ca8,
-	0x001c, 0x7064, 0x9502, 0x1228, 0x7556, 0x9085, 0x0001, 0x00ee,
-	0x0005, 0x7057, 0x1ddc, 0x0cc8, 0x9006, 0x0cc8, 0x9c82, 0x1ddc,
-	0x0a0c, 0x0d65, 0x2001, 0x1819, 0x2004, 0x9c02, 0x1a0c, 0x0d65,
-	0x9006, 0x6006, 0x600a, 0x600e, 0x6016, 0x601a, 0x6012, 0x6023,
-	0x0000, 0x6003, 0x0000, 0x601e, 0x605e, 0x6062, 0x6026, 0x602a,
-	0x602e, 0x6032, 0x6036, 0x603a, 0x603e, 0x604a, 0x6046, 0x6042,
-	0x2061, 0x1800, 0x6050, 0x8000, 0x6052, 0x0005, 0x9006, 0x600e,
-	0x6016, 0x601a, 0x6012, 0x6022, 0x6002, 0x601e, 0x605e, 0x6062,
-	0x604a, 0x6046, 0x2061, 0x1800, 0x6050, 0x8000, 0x6052, 0x0005,
-	0x0006, 0x6000, 0x9086, 0x0000, 0x01d0, 0x601c, 0xd084, 0x190c,
-	0x193e, 0x6023, 0x0007, 0x2001, 0x195e, 0x2004, 0x0006, 0x9082,
-	0x0051, 0x000e, 0x0208, 0x8004, 0x601a, 0x080c, 0xd517, 0x604b,
-	0x0000, 0x6044, 0xd0fc, 0x1129, 0x9006, 0x6046, 0x6016, 0x000e,
-	0x0005, 0x080c, 0x98c7, 0x0106, 0x2001, 0x19d2, 0x2004, 0x9c06,
-	0x1130, 0x0036, 0x2019, 0x0001, 0x080c, 0x929d, 0x003e, 0x080c,
-	0x94a4, 0x010e, 0x090c, 0x98e3, 0x0005, 0x00e6, 0x0126, 0x2071,
-	0x1800, 0x2091, 0x8000, 0x7550, 0x9582, 0x0001, 0x0608, 0x7054,
-	0x2060, 0x6000, 0x9086, 0x0000, 0x0148, 0x9ce0, 0x001c, 0x7064,
-	0x9c02, 0x1208, 0x0cb0, 0x2061, 0x1ddc, 0x0c98, 0x6003, 0x0008,
-	0x8529, 0x7552, 0x9ca8, 0x001c, 0x7064, 0x9502, 0x1230, 0x7556,
-	0x9085, 0x0001, 0x012e, 0x00ee, 0x0005, 0x7057, 0x1ddc, 0x0cc0,
-	0x9006, 0x0cc0, 0x6020, 0x9084, 0x000f, 0x0002, 0x9c96, 0x9ca0,
-	0x9cbb, 0x9cd6, 0xbfe2, 0xbfff, 0xc01a, 0x9c96, 0x9ca0, 0x9c96,
-	0x9cf2, 0x9c96, 0x9c96, 0x9c96, 0x9c96, 0x9c96, 0x9186, 0x0013,
-	0x1130, 0x6044, 0xd0fc, 0x0110, 0x080c, 0x8891, 0x0005, 0x0005,
-	0x0066, 0x6000, 0x90b2, 0x0016, 0x1a0c, 0x0d65, 0x0013, 0x006e,
-	0x0005, 0x9cb9, 0xa40f, 0xa5e3, 0x9cb9, 0xa671, 0x9fbb, 0x9cb9,
-	0x9cb9, 0xa391, 0xac18, 0x9cb9, 0x9cb9, 0x9cb9, 0x9cb9, 0x9cb9,
-	0x9cb9, 0x080c, 0x0d65, 0x0066, 0x6000, 0x90b2, 0x0016, 0x1a0c,
-	0x0d65, 0x0013, 0x006e, 0x0005, 0x9cd4, 0xb220, 0x9cd4, 0x9cd4,
-	0x9cd4, 0x9cd4, 0x9cd4, 0x9cd4, 0xb1c2, 0xb3a3, 0x9cd4, 0xb25d,
-	0xb2e1, 0xb25d, 0xb2e1, 0x9cd4, 0x080c, 0x0d65, 0x6000, 0x9082,
-	0x0016, 0x1a0c, 0x0d65, 0x6000, 0x0002, 0x9cf0, 0xac62, 0xacf9,
-	0xae79, 0xaee8, 0x9cf0, 0x9cf0, 0x9cf0, 0xac31, 0xb143, 0xb146,
-	0x9cf0, 0x9cf0, 0x9cf0, 0x9cf0, 0xb176, 0x9cf0, 0x9cf0, 0x9cf0,
-	0x080c, 0x0d65, 0x0066, 0x6000, 0x90b2, 0x0016, 0x1a0c, 0x0d65,
-	0x0013, 0x006e, 0x0005, 0x9d0b, 0x9d0b, 0x9d49, 0x9de8, 0x9e68,
-	0x9d0b, 0x9d0b, 0x9d0b, 0x9d0d, 0x9d0b, 0x9d0b, 0x9d0b, 0x9d0b,
-	0x9d0b, 0x9d0b, 0x9d0b, 0x080c, 0x0d65, 0x9186, 0x004c, 0x0560,
-	0x9186, 0x0003, 0x190c, 0x0d65, 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, 0x1a89, 0x2009,
-	0x8030, 0x080c, 0x852e, 0x0005, 0x6010, 0x00b6, 0x2058, 0xbca0,
-	0x00be, 0x2c00, 0x080c, 0x9e8a, 0x080c, 0xbfa7, 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, 0x9db0, 0x9db0, 0x9dab, 0x9dae, 0x9db0,
-	0x9da8, 0x9d9b, 0x9d9b, 0x9d9b, 0x9d9b, 0x9d9b, 0x9d9b, 0x9d9b,
-	0x9d9b, 0x9d9b, 0x9d9b, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x002e,
-	0x001e, 0x000e, 0x004e, 0x00fe, 0x009e, 0x00de, 0x080c, 0x0d65,
-	0x080c, 0xa854, 0x0028, 0x080c, 0xa977, 0x0010, 0x080c, 0xaa66,
-	0x00fe, 0x00ee, 0x00de, 0x00ce, 0x002e, 0x001e, 0x2c00, 0xa896,
-	0x000e, 0x080c, 0x9f48, 0x0530, 0xa804, 0xa80e, 0x00a6, 0x2050,
-	0xb100, 0x00ae, 0x8006, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084,
-	0xffc0, 0x9080, 0x0002, 0xaacc, 0xabd0, 0xacd4, 0xadd8, 0x2031,
-	0x0000, 0x2041, 0x1298, 0x080c, 0xa0f3, 0x0160, 0x000e, 0x9005,
-	0x0120, 0x00fe, 0x009e, 0x00de, 0x0005, 0x00fe, 0x009e, 0x00de,
-	0x0804, 0x9be6, 0x2001, 0x002c, 0x900e, 0x080c, 0x9fae, 0x0c70,
-	0x91b6, 0x0015, 0x0170, 0x91b6, 0x0016, 0x0158, 0x91b2, 0x0047,
-	0x0a0c, 0x0d65, 0x91b2, 0x0050, 0x1a0c, 0x0d65, 0x9182, 0x0047,
-	0x0042, 0x080c, 0x9ab6, 0x0120, 0x9086, 0x0002, 0x0904, 0x9d49,
-	0x0005, 0x9e0a, 0x9e0a, 0x9e0c, 0x9e3e, 0x9e0a, 0x9e0a, 0x9e0a,
-	0x9e0a, 0x9e51, 0x080c, 0x0d65, 0x00d6, 0x0016, 0x0096, 0x6003,
-	0x0004, 0x6114, 0x2148, 0xa87c, 0xd0fc, 0x01c0, 0xa878, 0xc0fc,
-	0x9005, 0x1158, 0xa894, 0x9005, 0x0140, 0x2001, 0x0000, 0x900e,
-	0x080c, 0x9fae, 0x080c, 0x9be6, 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, 0x88ec,
-	0x00d6, 0x0096, 0x6114, 0x2148, 0x080c, 0xb870, 0x0120, 0xa87b,
-	0x0006, 0x080c, 0x69b5, 0x009e, 0x00de, 0x080c, 0x9be6, 0x0804,
-	0x894f, 0x080c, 0x88ec, 0x080c, 0x302e, 0x080c, 0xbfa4, 0x00d6,
-	0x0096, 0x6114, 0x2148, 0x080c, 0xb870, 0x0120, 0xa87b, 0x0029,
-	0x080c, 0x69b5, 0x009e, 0x00de, 0x080c, 0x9be6, 0x0804, 0x894f,
-	0x9182, 0x0047, 0x0002, 0x9e78, 0x9e7a, 0x9e78, 0x9e78, 0x9e78,
-	0x9e78, 0x9e78, 0x9e78, 0x9e78, 0x9e78, 0x9e78, 0x9e78, 0x9e7a,
-	0x080c, 0x0d65, 0x00d6, 0x0096, 0x080c, 0x15af, 0x6114, 0x2148,
-	0xa87b, 0x0000, 0xa883, 0x0000, 0x080c, 0x69b5, 0x009e, 0x00de,
-	0x0804, 0x9be6, 0x0026, 0x0036, 0x0056, 0x0066, 0x0096, 0x00a6,
-	0x00f6, 0x0006, 0x080c, 0x102f, 0x000e, 0x090c, 0x0d65, 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, 0xb426, 0x04c0, 0x2130, 0x2009, 0x0034, 0x2011,
-	0x001f, 0x080c, 0xb426, 0x96b2, 0x0034, 0xb004, 0x904d, 0x0110,
-	0x080c, 0x0fe1, 0x080c, 0x102f, 0x01d0, 0x8528, 0xa867, 0x0110,
-	0xa86b, 0x0000, 0x2920, 0xb406, 0x968a, 0x003d, 0x1230, 0x2608,
-	0x2011, 0x001b, 0x080c, 0xb426, 0x00b8, 0x96b2, 0x003c, 0x2009,
-	0x003c, 0x2950, 0x2011, 0x001b, 0x080c, 0xb426, 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, 0x69b5, 0x000e, 0x2048, 0x9005, 0x1db0,
-	0x00fe, 0x00ae, 0x009e, 0x006e, 0x005e, 0x003e, 0x002e, 0x0005,
-	0x00d6, 0x00f6, 0x0096, 0x0006, 0x080c, 0x102f, 0x000e, 0x090c,
-	0x0d65, 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, 0x69b5, 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, 0x102f, 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, 0x9f5d, 0x0804, 0x9f5f, 0x9085, 0x0001, 0x7817,
-	0x0000, 0x009e, 0x00fe, 0x00de, 0x001e, 0x0005, 0x00d6, 0x0036,
-	0x0096, 0x6314, 0x2348, 0xa87a, 0xa982, 0x080c, 0x69a9, 0x009e,
-	0x003e, 0x00de, 0x0005, 0x91b6, 0x0015, 0x1118, 0x080c, 0x9be6,
-	0x0030, 0x91b6, 0x0016, 0x190c, 0x0d65, 0x080c, 0x9be6, 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, 0xb870, 0x0130,
-	0x6014, 0x2048, 0xa807, 0x0000, 0xa867, 0x0103, 0x009e, 0x0804,
-	0x9be6, 0x0096, 0x00d6, 0x0036, 0x7330, 0x9386, 0x0200, 0x11a8,
-	0x6010, 0x00b6, 0x2058, 0xb8c7, 0x0000, 0x00be, 0x6014, 0x9005,
-	0x0130, 0x2048, 0xa807, 0x0000, 0xa867, 0x0103, 0xab32, 0x080c,
-	0x9be6, 0x003e, 0x00de, 0x009e, 0x0005, 0x0011, 0x1d48, 0x0cc8,
-	0x0006, 0x0016, 0x080c, 0xbf8f, 0x0188, 0x6014, 0x9005, 0x1170,
-	0x600b, 0x0003, 0x601b, 0x0000, 0x604b, 0x0000, 0x2009, 0x0022,
-	0x080c, 0xa3e7, 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, 0x9be6, 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, 0xb426,
-	0x080c, 0xb870, 0x0140, 0x6014, 0x2048, 0xa807, 0x0000, 0xa864,
-	0xa8e2, 0xa867, 0x0103, 0x080c, 0x9be6, 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,
-	0xb426, 0x009e, 0x080c, 0xb870, 0x0148, 0xa804, 0x9005, 0x1158,
-	0xa807, 0x0000, 0xa864, 0xa8e2, 0xa867, 0x0103, 0x080c, 0x9be6,
-	0x009e, 0x001e, 0x0005, 0x0086, 0x2040, 0xa030, 0x8007, 0x9086,
-	0x0100, 0x1118, 0x080c, 0xa59c, 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, 0x127e, 0x0019,
-	0x0d08, 0x008e, 0x0898, 0x0096, 0x0006, 0x080c, 0x102f, 0x000e,
-	0x01b0, 0xa8ab, 0x0dcb, 0xa876, 0x000e, 0xa8a2, 0x0006, 0xae6a,
-	0x2800, 0xa89e, 0xa97a, 0xaf72, 0xaa8e, 0xab92, 0xac96, 0xad9a,
-	0x0086, 0x2940, 0x080c, 0x1124, 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, 0xbf07, 0x001e, 0x1158,
-	0x622c, 0x2268, 0x2071, 0x026c, 0x6b20, 0x9386, 0x0003, 0x0130,
-	0x9386, 0x0006, 0x0128, 0x080c, 0x9be6, 0x0020, 0x0039, 0x0010,
-	0x080c, 0xa21c, 0x002e, 0x00de, 0x00ee, 0x0005, 0x0096, 0x6814,
-	0x2048, 0x9186, 0x0015, 0x0904, 0xa1fb, 0x918e, 0x0016, 0x1904,
-	0xa21a, 0x700c, 0x908c, 0xff00, 0x9186, 0x1700, 0x0120, 0x9186,
-	0x0300, 0x1904, 0xa1d5, 0x89ff, 0x1138, 0x6800, 0x9086, 0x000f,
-	0x0904, 0xa1b7, 0x0804, 0xa218, 0x6808, 0x9086, 0xffff, 0x1904,
-	0xa1fd, 0xa87c, 0x9084, 0x0060, 0x9086, 0x0020, 0x1128, 0xa83c,
-	0xa940, 0x9105, 0x1904, 0xa1fd, 0x6824, 0xd084, 0x1904, 0xa1fd,
-	0xd0b4, 0x0158, 0x0016, 0x2001, 0x195e, 0x200c, 0x6018, 0x9102,
-	0x9082, 0x0005, 0x001e, 0x1a04, 0xa1fd, 0x080c, 0xba5f, 0x6864,
-	0xa882, 0xa87c, 0xc0dc, 0xc0f4, 0xc0d4, 0xa87e, 0x0026, 0x900e,
-	0x6a18, 0x2001, 0x000a, 0x080c, 0x842f, 0xa884, 0x920a, 0x0208,
-	0x8011, 0xaa86, 0x82ff, 0x002e, 0x1138, 0x00c6, 0x2d60, 0x080c,
-	0xb579, 0x00ce, 0x0804, 0xa218, 0x00c6, 0xa868, 0xd0fc, 0x1118,
-	0x080c, 0x5d71, 0x0010, 0x080c, 0x611a, 0x00ce, 0x1904, 0xa1fd,
-	0x00c6, 0x2d60, 0x080c, 0x9be6, 0x00ce, 0x0804, 0xa218, 0x00c6,
-	0x080c, 0x9c55, 0x0198, 0x6017, 0x0000, 0x6810, 0x6012, 0x080c,
-	0xbd09, 0x6023, 0x0003, 0x6904, 0x00c6, 0x2d60, 0x080c, 0x9be6,
-	0x00ce, 0x080c, 0x9c82, 0x00ce, 0x0804, 0xa218, 0x2001, 0x1960,
-	0x2004, 0x684a, 0x00ce, 0x0804, 0xa218, 0x7008, 0x9086, 0x000b,
-	0x11c8, 0x6010, 0x00b6, 0x2058, 0xb900, 0xc1bc, 0xb902, 0x00be,
-	0x00c6, 0x2d60, 0xa87b, 0x0003, 0x080c, 0xbf49, 0x6007, 0x0085,
-	0x6003, 0x000b, 0x6023, 0x0002, 0x2009, 0x8020, 0x080c, 0x84e7,
-	0x00ce, 0x0430, 0x700c, 0x9086, 0x2a00, 0x1138, 0x2001, 0x1960,
-	0x2004, 0x684a, 0x00e8, 0x04c1, 0x00e8, 0x89ff, 0x090c, 0x0d65,
-	0x00c6, 0x00d6, 0x2d60, 0xa867, 0x0103, 0xa87b, 0x0003, 0x080c,
-	0x67cb, 0x080c, 0xba5f, 0x080c, 0x9c20, 0x0026, 0x6010, 0x00b6,
-	0x2058, 0xba3c, 0x080c, 0x63ba, 0x00be, 0x002e, 0x00de, 0x00ce,
-	0x080c, 0x9be6, 0x009e, 0x0005, 0x9186, 0x0015, 0x1128, 0x2001,
-	0x1960, 0x2004, 0x684a, 0x0068, 0x918e, 0x0016, 0x1160, 0x00c6,
-	0x2d00, 0x2060, 0x080c, 0xd517, 0x080c, 0x83d6, 0x080c, 0x9be6,
-	0x00ce, 0x080c, 0x9be6, 0x0005, 0x0026, 0x0036, 0x0046, 0x7228,
-	0xacb0, 0xabac, 0xd2f4, 0x0130, 0x2001, 0x1960, 0x2004, 0x684a,
-	0x0804, 0xa296, 0x00c6, 0x2d60, 0x080c, 0xb451, 0x00ce, 0x6804,
-	0x9086, 0x0050, 0x1168, 0x00c6, 0x2d00, 0x2060, 0x6003, 0x0001,
-	0x6007, 0x0050, 0x2009, 0x8023, 0x080c, 0x84e7, 0x00ce, 0x04f0,
-	0x6800, 0x9086, 0x000f, 0x01a8, 0x89ff, 0x090c, 0x0d65, 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, 0xbbf3, 0x080c, 0x894f, 0x0010, 0x080c, 0x9be6,
-	0x004e, 0x003e, 0x002e, 0x0005, 0x00e6, 0x00d6, 0x0026, 0x7008,
-	0x9084, 0x00ff, 0x6210, 0x00b6, 0x2258, 0xba10, 0x00be, 0x9206,
-	0x1904, 0xa301, 0x700c, 0x6210, 0x00b6, 0x2258, 0xba14, 0x00be,
-	0x9206, 0x1904, 0xa301, 0x6038, 0x2068, 0x6824, 0xc0dc, 0x6826,
-	0x6a20, 0x9286, 0x0007, 0x0904, 0xa301, 0x9286, 0x0002, 0x0904,
-	0xa301, 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, 0xb870,
-	0x090c, 0x0d65, 0xa87b, 0x0003, 0x009e, 0x080c, 0xbf49, 0x6007,
-	0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x2009, 0x8020, 0x080c,
-	0x84e7, 0x00ce, 0x0030, 0x6038, 0x2070, 0x2001, 0x1960, 0x2004,
-	0x704a, 0x080c, 0x9be6, 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, 0xabee, 0x002e, 0x003e, 0x015e, 0x009e,
-	0x1904, 0xa370, 0x0096, 0x0156, 0x0036, 0x0026, 0x2b48, 0x9e90,
-	0x0014, 0x2019, 0x0006, 0x20a9, 0x0004, 0x080c, 0xabee, 0x002e,
-	0x003e, 0x015e, 0x009e, 0x15a0, 0x7238, 0xba0a, 0x733c, 0xbb0e,
-	0xbc00, 0xc48d, 0xbc02, 0xa804, 0x9005, 0x1128, 0x00fe, 0x009e,
-	0x00be, 0x0804, 0x9ff4, 0x0096, 0x2048, 0xaa12, 0xab16, 0xac0a,
-	0x009e, 0x8006, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0,
-	0x9080, 0x0002, 0x2009, 0x002b, 0xaaa0, 0xab9c, 0xaca8, 0xada4,
-	0x2031, 0x0000, 0x2041, 0x127e, 0x080c, 0xa0f3, 0x0130, 0x00fe,
-	0x009e, 0x080c, 0x9be6, 0x00be, 0x0005, 0x080c, 0xa59c, 0x0cb8,
-	0x2b78, 0x00f6, 0x080c, 0x302e, 0x080c, 0xbfa4, 0x00fe, 0x00c6,
-	0x080c, 0x9b90, 0x2f00, 0x6012, 0x6017, 0x0000, 0x6023, 0x0001,
-	0x6007, 0x0001, 0x6003, 0x0001, 0x2001, 0x0007, 0x080c, 0x61e0,
-	0x080c, 0x620c, 0x080c, 0x84ee, 0x080c, 0x894f, 0x00ce, 0x0804,
-	0xa343, 0x2100, 0x91b2, 0x0053, 0x1a0c, 0x0d65, 0x91b2, 0x0040,
-	0x1a04, 0xa3f9, 0x0002, 0xa3e7, 0xa3e7, 0xa3dd, 0xa3e7, 0xa3e7,
-	0xa3e7, 0xa3db, 0xa3db, 0xa3db, 0xa3db, 0xa3db, 0xa3db, 0xa3db,
-	0xa3db, 0xa3db, 0xa3db, 0xa3db, 0xa3db, 0xa3db, 0xa3db, 0xa3db,
-	0xa3db, 0xa3db, 0xa3db, 0xa3db, 0xa3db, 0xa3db, 0xa3db, 0xa3db,
-	0xa3db, 0xa3db, 0xa3e7, 0xa3db, 0xa3e7, 0xa3e7, 0xa3db, 0xa3db,
-	0xa3db, 0xa3db, 0xa3db, 0xa3dd, 0xa3db, 0xa3db, 0xa3db, 0xa3db,
-	0xa3db, 0xa3db, 0xa3db, 0xa3db, 0xa3db, 0xa3e7, 0xa3e7, 0xa3db,
-	0xa3db, 0xa3db, 0xa3db, 0xa3db, 0xa3db, 0xa3db, 0xa3db, 0xa3db,
-	0xa3e7, 0xa3db, 0xa3db, 0x080c, 0x0d65, 0x0066, 0x00b6, 0x6610,
-	0x2658, 0xb8c4, 0xc08c, 0xb8c6, 0x00be, 0x006e, 0x0000, 0x6003,
-	0x0001, 0x6106, 0x9186, 0x0032, 0x0118, 0x080c, 0x84ee, 0x0010,
-	0x080c, 0x84e7, 0x0126, 0x2091, 0x8000, 0x080c, 0x894f, 0x012e,
-	0x0005, 0x2600, 0x0002, 0xa40d, 0xa40d, 0xa40d, 0xa3e7, 0xa3e7,
-	0xa40d, 0xa40d, 0xa40d, 0xa40d, 0xa3e7, 0xa40d, 0xa3e7, 0xa40d,
-	0xa3e7, 0xa40d, 0xa40d, 0xa40d, 0xa40d, 0x080c, 0x0d65, 0x6004,
-	0x90b2, 0x0053, 0x1a0c, 0x0d65, 0x91b6, 0x0013, 0x0904, 0xa4e4,
-	0x91b6, 0x0027, 0x1904, 0xa490, 0x080c, 0x8891, 0x6004, 0x080c,
-	0xba74, 0x01b0, 0x080c, 0xba85, 0x01a8, 0x908e, 0x0021, 0x0904,
-	0xa48d, 0x908e, 0x0022, 0x1130, 0x080c, 0xa020, 0x0904, 0xa489,
-	0x0804, 0xa48a, 0x908e, 0x003d, 0x0904, 0xa48d, 0x0804, 0xa483,
-	0x080c, 0x305d, 0x2001, 0x0007, 0x080c, 0x61e0, 0x6010, 0x00b6,
-	0x2058, 0xb9a0, 0x00be, 0x080c, 0xa59c, 0x9186, 0x007e, 0x1148,
-	0x2001, 0x1836, 0x2014, 0xc285, 0x080c, 0x70ba, 0x1108, 0xc2ad,
-	0x2202, 0x080c, 0x98c7, 0x0036, 0x0026, 0x2019, 0x0028, 0x2110,
-	0x080c, 0xd572, 0x002e, 0x003e, 0x0016, 0x0026, 0x0036, 0x2110,
-	0x2019, 0x0028, 0x080c, 0x8658, 0x0076, 0x903e, 0x080c, 0x853d,
-	0x6010, 0x00b6, 0x905d, 0x0100, 0x00be, 0x2c08, 0x080c, 0xd011,
-	0x007e, 0x003e, 0x002e, 0x001e, 0x080c, 0x98e3, 0x080c, 0xbfa4,
-	0x0016, 0x080c, 0xbd01, 0x080c, 0x9be6, 0x001e, 0x080c, 0x3136,
-	0x080c, 0x894f, 0x0030, 0x080c, 0xbd01, 0x080c, 0x9be6, 0x080c,
-	0x894f, 0x0005, 0x080c, 0xa59c, 0x0cb0, 0x080c, 0xa5d8, 0x0c98,
-	0x9186, 0x0015, 0x0118, 0x9186, 0x0016, 0x1140, 0x080c, 0x9ab6,
-	0x0d80, 0x9086, 0x0002, 0x0904, 0xa5e3, 0x0c58, 0x9186, 0x0014,
-	0x1d40, 0x080c, 0x8891, 0x6004, 0x908e, 0x0022, 0x1118, 0x080c,
-	0xa020, 0x09f8, 0x080c, 0x302e, 0x080c, 0xbfa4, 0x080c, 0xba74,
-	0x1190, 0x080c, 0x305d, 0x6010, 0x00b6, 0x2058, 0xb9a0, 0x00be,
-	0x080c, 0xa59c, 0x9186, 0x007e, 0x1128, 0x2001, 0x1836, 0x200c,
-	0xc185, 0x2102, 0x0800, 0x080c, 0xba85, 0x1120, 0x080c, 0xa59c,
-	0x0804, 0xa483, 0x6004, 0x908e, 0x0032, 0x1160, 0x00e6, 0x00f6,
-	0x2071, 0x189c, 0x2079, 0x0000, 0x080c, 0x33d0, 0x00fe, 0x00ee,
-	0x0804, 0xa483, 0x6004, 0x908e, 0x0021, 0x0d40, 0x908e, 0x0022,
-	0x090c, 0xa59c, 0x0804, 0xa483, 0x90b2, 0x0040, 0x1a04, 0xa585,
-	0x2008, 0x0002, 0xa52c, 0xa52d, 0xa530, 0xa533, 0xa536, 0xa539,
-	0xa52a, 0xa52a, 0xa52a, 0xa52a, 0xa52a, 0xa52a, 0xa52a, 0xa52a,
-	0xa52a, 0xa52a, 0xa52a, 0xa52a, 0xa52a, 0xa52a, 0xa52a, 0xa52a,
-	0xa52a, 0xa52a, 0xa52a, 0xa52a, 0xa52a, 0xa52a, 0xa52a, 0xa52a,
-	0xa53c, 0xa547, 0xa52a, 0xa548, 0xa547, 0xa52a, 0xa52a, 0xa52a,
-	0xa52a, 0xa52a, 0xa547, 0xa547, 0xa52a, 0xa52a, 0xa52a, 0xa52a,
-	0xa52a, 0xa52a, 0xa52a, 0xa52a, 0xa570, 0xa547, 0xa52a, 0xa543,
-	0xa52a, 0xa52a, 0xa52a, 0xa544, 0xa52a, 0xa52a, 0xa52a, 0xa547,
-	0xa56b, 0xa52a, 0x080c, 0x0d65, 0x00d0, 0x2001, 0x000b, 0x00f8,
-	0x2001, 0x0003, 0x00e0, 0x2001, 0x0005, 0x00c8, 0x2001, 0x0001,
-	0x00b0, 0x2001, 0x0009, 0x0098, 0x6003, 0x0005, 0x080c, 0xbfa7,
-	0x080c, 0x894f, 0x0058, 0x0018, 0x0010, 0x080c, 0x61e0, 0x04b8,
-	0x080c, 0xbfa7, 0x6003, 0x0004, 0x080c, 0x894f, 0x0005, 0x080c,
-	0x61e0, 0x6003, 0x0002, 0x0036, 0x2019, 0x1866, 0x2304, 0x9084,
-	0xff00, 0x1120, 0x2001, 0x195e, 0x201c, 0x0040, 0x8007, 0x909a,
-	0x0004, 0x0ec0, 0x8003, 0x801b, 0x831b, 0x9318, 0x631a, 0x003e,
-	0x080c, 0x894f, 0x0c18, 0x080c, 0xbd01, 0x080c, 0x9be6, 0x08f0,
-	0x00e6, 0x00f6, 0x2071, 0x189c, 0x2079, 0x0000, 0x080c, 0x33d0,
-	0x00fe, 0x00ee, 0x080c, 0x8891, 0x080c, 0x9be6, 0x0878, 0x6003,
-	0x0002, 0x080c, 0xbfa7, 0x0804, 0x894f, 0x2600, 0x2008, 0x0002,
-	0xa59a, 0xa59a, 0xa59a, 0xa57f, 0xa57f, 0xa59a, 0xa59a, 0xa59a,
-	0xa59a, 0xa57f, 0xa59a, 0xa57f, 0xa59a, 0xa57f, 0xa59a, 0xa59a,
-	0xa59a, 0xa59a, 0x080c, 0x0d65, 0x00e6, 0x0096, 0x0026, 0x0016,
-	0x080c, 0xb870, 0x0568, 0x6014, 0x2048, 0xa864, 0x9086, 0x0139,
-	0x11a8, 0xa894, 0x9086, 0x0056, 0x1148, 0x080c, 0x5149, 0x0130,
-	0x2001, 0x0000, 0x900e, 0x2011, 0x4000, 0x0028, 0x2001, 0x0030,
-	0x900e, 0x2011, 0x4005, 0x080c, 0xbe6e, 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, 0x0d65, 0x6604, 0x96b6, 0x004d,
-	0x1120, 0x080c, 0xbd8d, 0x0804, 0xa660, 0x6604, 0x96b6, 0x0043,
-	0x1120, 0x080c, 0xbdd6, 0x0804, 0xa660, 0x6604, 0x96b6, 0x004b,
-	0x1120, 0x080c, 0xbe02, 0x0804, 0xa660, 0x6604, 0x96b6, 0x0033,
-	0x1120, 0x080c, 0xbd23, 0x0804, 0xa660, 0x6604, 0x96b6, 0x0028,
-	0x1120, 0x080c, 0xbac3, 0x0804, 0xa660, 0x6604, 0x96b6, 0x0029,
-	0x1120, 0x080c, 0xbb04, 0x0804, 0xa660, 0x6604, 0x96b6, 0x001f,
-	0x1118, 0x080c, 0x9fc8, 0x04e0, 0x6604, 0x96b6, 0x0000, 0x1118,
-	0x080c, 0xa307, 0x04a8, 0x6604, 0x96b6, 0x0022, 0x1118, 0x080c,
-	0xa001, 0x0470, 0x6604, 0x96b6, 0x0035, 0x1118, 0x080c, 0xa111,
-	0x0438, 0x6604, 0x96b6, 0x0039, 0x1118, 0x080c, 0xa29c, 0x0400,
-	0x6604, 0x96b6, 0x003d, 0x1118, 0x080c, 0xa039, 0x00c8, 0x6604,
-	0x96b6, 0x0044, 0x1118, 0x080c, 0xa075, 0x0090, 0x6604, 0x96b6,
-	0x0049, 0x1118, 0x080c, 0xa0a0, 0x0058, 0x91b6, 0x0015, 0x1110,
-	0x0063, 0x0030, 0x91b6, 0x0016, 0x1128, 0x00be, 0x0804, 0xa920,
-	0x00be, 0x0005, 0x080c, 0x9c9f, 0x0cd8, 0xa67d, 0xa680, 0xa67d,
-	0xa6c4, 0xa67d, 0xa854, 0xa92d, 0xa67d, 0xa67d, 0xa8fa, 0xa67d,
-	0xa90e, 0x0096, 0x080c, 0x15af, 0x6014, 0x2048, 0xa800, 0x2048,
-	0xa867, 0x0103, 0x009e, 0x0804, 0x9be6, 0xa001, 0xa001, 0x0005,
-	0x00e6, 0x2071, 0x1800, 0x708c, 0x9086, 0x0074, 0x1540, 0x080c,
-	0xcfe2, 0x11b0, 0x6010, 0x00b6, 0x2058, 0x7030, 0xd08c, 0x0128,
-	0xb800, 0xd0bc, 0x0110, 0xc0c5, 0xb802, 0x00e9, 0x00be, 0x2001,
-	0x0006, 0x080c, 0x61e0, 0x080c, 0x305d, 0x080c, 0x9be6, 0x0088,
-	0x2001, 0x000a, 0x080c, 0x61e0, 0x080c, 0x305d, 0x6003, 0x0001,
-	0x6007, 0x0001, 0x080c, 0x84ee, 0x080c, 0x894f, 0x0010, 0x080c,
-	0xa83f, 0x00ee, 0x0005, 0x00d6, 0xb800, 0xd084, 0x0158, 0x9006,
-	0x080c, 0x61cc, 0x2069, 0x185b, 0x6804, 0x0020, 0x2001, 0x0006,
-	0x080c, 0x620c, 0x00de, 0x0005, 0x00b6, 0x0096, 0x00d6, 0x2011,
-	0x1823, 0x2204, 0x9086, 0x0074, 0x1904, 0xa816, 0x6010, 0x2058,
-	0xbaa0, 0x9286, 0x007e, 0x1120, 0x080c, 0xaa71, 0x0804, 0xa77b,
-	0x00d6, 0x080c, 0x70ba, 0x0198, 0x0026, 0x2011, 0x0010, 0x080c,
-	0x66ae, 0x002e, 0x05c8, 0x080c, 0x53bc, 0x1540, 0x6014, 0x2048,
-	0xa807, 0x0000, 0xa867, 0x0103, 0xa833, 0xdead, 0x00f8, 0x0026,
-	0x2011, 0x8008, 0x080c, 0x66ae, 0x002e, 0x0530, 0x6014, 0x2048,
-	0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x1140, 0x2001, 0x0030,
-	0x900e, 0x2011, 0x4009, 0x080c, 0xbe6e, 0x0040, 0x6014, 0x2048,
-	0xa807, 0x0000, 0xa867, 0x0103, 0xa833, 0xdead, 0x6010, 0x2058,
-	0xb9a0, 0x0016, 0x080c, 0x305d, 0x080c, 0x9be6, 0x001e, 0x080c,
-	0x3136, 0x00de, 0x0804, 0xa819, 0x00de, 0x080c, 0xaa66, 0x6010,
-	0x2058, 0xbaa0, 0x9286, 0x0080, 0x1510, 0x6014, 0x9005, 0x01a8,
-	0x2048, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x1140, 0x2001,
-	0x0000, 0x900e, 0x2011, 0x4000, 0x080c, 0xbe6e, 0x0030, 0xa807,
-	0x0000, 0xa867, 0x0103, 0xa833, 0x0200, 0x2001, 0x0006, 0x080c,
-	0x61e0, 0x080c, 0x305d, 0x080c, 0x9be6, 0x0804, 0xa819, 0x080c,
-	0xa827, 0x6014, 0x9005, 0x0190, 0x2048, 0xa868, 0xd0f4, 0x01e8,
-	0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x1d08, 0x2001, 0x0000,
-	0x900e, 0x2011, 0x4000, 0x080c, 0xbe6e, 0x08f8, 0x080c, 0xa81d,
-	0x0160, 0x9006, 0x080c, 0x61cc, 0x2001, 0x0004, 0x080c, 0x620c,
-	0x2001, 0x0007, 0x080c, 0x61e0, 0x08a0, 0x2001, 0x0004, 0x080c,
-	0x61e0, 0x6003, 0x0001, 0x6007, 0x0003, 0x080c, 0x84ee, 0x080c,
-	0x894f, 0x0804, 0xa819, 0xb85c, 0xd0e4, 0x01d0, 0x080c, 0xbc9b,
-	0x080c, 0x70ba, 0x0118, 0xd0dc, 0x1904, 0xa73d, 0x2011, 0x1836,
-	0x2204, 0xc0ad, 0x2012, 0x2001, 0x0002, 0x00f6, 0x2079, 0x0100,
-	0x78e3, 0x0000, 0x080c, 0x24cd, 0x78e2, 0x00fe, 0x0804, 0xa73d,
-	0x080c, 0xbcdc, 0x2011, 0x1836, 0x2204, 0xc0a5, 0x2012, 0x0006,
-	0x080c, 0xd147, 0x000e, 0x1904, 0xa73d, 0xc0b5, 0x2012, 0x2001,
-	0x0006, 0x080c, 0x61e0, 0x9006, 0x080c, 0x61cc, 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, 0x24a2, 0x00f6, 0x2100, 0x900e, 0x080c, 0x2459,
-	0x795a, 0x00fe, 0x9186, 0x0081, 0x01d8, 0x2009, 0x0081, 0x00c8,
-	0x2009, 0x00ef, 0x00f6, 0x2079, 0x0100, 0x79ea, 0x7932, 0x7936,
-	0x780c, 0xc0b5, 0x780e, 0x00fe, 0x080c, 0x24a2, 0x00f6, 0x2079,
-	0x1800, 0x797e, 0x2100, 0x900e, 0x080c, 0x2459, 0x795a, 0x00fe,
-	0x8108, 0x080c, 0x622f, 0x2b00, 0x00ce, 0x1904, 0xa73d, 0x6012,
-	0x2009, 0x180f, 0x210c, 0xd19c, 0x0150, 0x2009, 0x027c, 0x210c,
-	0x918c, 0x00ff, 0xb912, 0x2009, 0x027d, 0x210c, 0xb916, 0x2001,
-	0x0002, 0x080c, 0x61e0, 0x6023, 0x0001, 0x6003, 0x0001, 0x6007,
-	0x0002, 0x080c, 0x84ee, 0x080c, 0x894f, 0x0018, 0x080c, 0xa59c,
-	0x0431, 0x00de, 0x009e, 0x00be, 0x0005, 0x2001, 0x1810, 0x2004,
-	0xd0a4, 0x0120, 0x2001, 0x185c, 0x2004, 0xd0ac, 0x0005, 0x00e6,
-	0x080c, 0xd5cb, 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, 0x61e0, 0x080c, 0x53bc, 0x1120, 0x2001,
-	0x0007, 0x080c, 0x620c, 0x080c, 0x305d, 0x6020, 0x9086, 0x000a,
-	0x1108, 0x0005, 0x0804, 0x9be6, 0x00b6, 0x00e6, 0x0026, 0x0016,
-	0x2071, 0x1800, 0x708c, 0x9086, 0x0014, 0x1904, 0xa8f1, 0x00d6,
-	0x080c, 0x70ba, 0x0198, 0x0026, 0x2011, 0x0010, 0x080c, 0x66ae,
-	0x002e, 0x05c8, 0x080c, 0x53bc, 0x1540, 0x6014, 0x2048, 0xa807,
-	0x0000, 0xa867, 0x0103, 0xa833, 0xdead, 0x00f8, 0x0026, 0x2011,
-	0x8008, 0x080c, 0x66ae, 0x002e, 0x0530, 0x6014, 0x2048, 0xa864,
-	0x9084, 0x00ff, 0x9086, 0x0039, 0x1140, 0x2001, 0x0030, 0x900e,
-	0x2011, 0x4009, 0x080c, 0xbe6e, 0x0040, 0x6014, 0x2048, 0xa807,
-	0x0000, 0xa867, 0x0103, 0xa833, 0xdead, 0x6010, 0x2058, 0xb9a0,
-	0x0016, 0x080c, 0x305d, 0x080c, 0x9be6, 0x001e, 0x080c, 0x3136,
-	0x00de, 0x0804, 0xa8f5, 0x00de, 0x080c, 0x53bc, 0x1170, 0x6014,
-	0x9005, 0x1158, 0x0036, 0x0046, 0x6010, 0x2058, 0xbba0, 0x2021,
-	0x0006, 0x080c, 0x4a97, 0x004e, 0x003e, 0x00d6, 0x6010, 0x2058,
-	0x080c, 0x632a, 0x080c, 0xa6b3, 0x00de, 0x080c, 0xab37, 0x1588,
-	0x6010, 0x2058, 0xb890, 0x9005, 0x0560, 0x2001, 0x0006, 0x080c,
-	0x61e0, 0x0096, 0x6014, 0x904d, 0x01d0, 0xa864, 0x9084, 0x00ff,
-	0x9086, 0x0039, 0x1140, 0x2001, 0x0000, 0x900e, 0x2011, 0x4000,
-	0x080c, 0xbe6e, 0x0060, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0029,
-	0x0130, 0xa807, 0x0000, 0xa867, 0x0103, 0xa833, 0x0200, 0x009e,
-	0x080c, 0x305d, 0x6020, 0x9086, 0x000a, 0x0138, 0x080c, 0x9be6,
-	0x0020, 0x080c, 0xa59c, 0x080c, 0xa83f, 0x001e, 0x002e, 0x00ee,
-	0x00be, 0x0005, 0x2011, 0x1823, 0x2204, 0x9086, 0x0014, 0x1160,
-	0x2001, 0x0002, 0x080c, 0x61e0, 0x6003, 0x0001, 0x6007, 0x0001,
-	0x080c, 0x84ee, 0x0804, 0x894f, 0x0804, 0xa83f, 0x2030, 0x2011,
-	0x1823, 0x2204, 0x9086, 0x0004, 0x1148, 0x96b6, 0x000b, 0x1120,
-	0x2001, 0x0007, 0x080c, 0x61e0, 0x0804, 0x9be6, 0x0804, 0xa83f,
-	0x0002, 0xa67d, 0xa938, 0xa67d, 0xa977, 0xa67d, 0xaa22, 0xa92d,
-	0xa67d, 0xa67d, 0xaa35, 0xa67d, 0xaa45, 0x6604, 0x9686, 0x0003,
-	0x0904, 0xa854, 0x96b6, 0x001e, 0x1110, 0x080c, 0x9be6, 0x0005,
-	0x00b6, 0x00d6, 0x00c6, 0x080c, 0xaa55, 0x11a0, 0x9006, 0x080c,
-	0x61cc, 0x080c, 0x302e, 0x080c, 0xbfa4, 0x2001, 0x0002, 0x080c,
-	0x61e0, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x84ee, 0x080c,
-	0x894f, 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, 0x302e, 0x080c,
-	0xbfa4, 0x080c, 0xa83f, 0x00ce, 0x00de, 0x00be, 0x0005, 0x0096,
-	0x00b6, 0x0026, 0x9016, 0x080c, 0xaa63, 0x00d6, 0x2069, 0x1954,
-	0x2d04, 0x9005, 0x0168, 0x6010, 0x2058, 0xb8a0, 0x9086, 0x007e,
-	0x1138, 0x2069, 0x181f, 0x2d04, 0x8000, 0x206a, 0x00de, 0x0010,
-	0x00de, 0x0088, 0x9006, 0x080c, 0x61cc, 0x2001, 0x0002, 0x080c,
-	0x61e0, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x84ee, 0x080c,
-	0x894f, 0x0804, 0xa9f2, 0x080c, 0xb870, 0x01b0, 0x6014, 0x2048,
-	0xa864, 0x2010, 0x9086, 0x0139, 0x1138, 0x6007, 0x0016, 0x2001,
-	0x0002, 0x080c, 0xbec8, 0x00b0, 0x6014, 0x2048, 0xa864, 0xd0fc,
-	0x0118, 0x2001, 0x0001, 0x0ca8, 0x2001, 0x180e, 0x2004, 0xd0dc,
-	0x0148, 0x6010, 0x2058, 0xb840, 0x9084, 0x00ff, 0x9005, 0x1110,
-	0x9006, 0x0c38, 0x080c, 0xa59c, 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, 0x61e0, 0x2001, 0x0028, 0x601a, 0x6007, 0x0052, 0x0010,
-	0x080c, 0xa83f, 0x002e, 0x00be, 0x009e, 0x0005, 0x9286, 0x0139,
-	0x0160, 0x6014, 0x2048, 0x080c, 0xb870, 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, 0x5c8a, 0x00ee, 0x0010, 0x080c,
-	0x302e, 0x0870, 0x080c, 0xaa63, 0x1160, 0x2001, 0x0004, 0x080c,
-	0x61e0, 0x6003, 0x0001, 0x6007, 0x0003, 0x080c, 0x84ee, 0x0804,
-	0x894f, 0x080c, 0xa59c, 0x0804, 0xa83f, 0x0469, 0x1160, 0x2001,
-	0x0008, 0x080c, 0x61e0, 0x6003, 0x0001, 0x6007, 0x0005, 0x080c,
-	0x84ee, 0x0804, 0x894f, 0x0804, 0xa83f, 0x00e9, 0x1160, 0x2001,
-	0x000a, 0x080c, 0x61e0, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c,
-	0x84ee, 0x0804, 0x894f, 0x0804, 0xa83f, 0x2009, 0x026e, 0x2104,
-	0x9086, 0x0003, 0x1138, 0x2009, 0x026f, 0x2104, 0x9084, 0xff00,
-	0x9086, 0x2a00, 0x0005, 0x9085, 0x0001, 0x0005, 0x00b6, 0x00c6,
-	0x0016, 0x6110, 0x2158, 0x080c, 0x629e, 0x001e, 0x00ce, 0x00be,
-	0x0005, 0x00b6, 0x00f6, 0x00e6, 0x00d6, 0x0036, 0x0016, 0x6010,
-	0x2058, 0x2009, 0x1836, 0x2104, 0x9085, 0x0003, 0x200a, 0x080c,
-	0xab09, 0x0560, 0x2009, 0x1836, 0x2104, 0xc0cd, 0x200a, 0x080c,
-	0x6686, 0x0158, 0x9006, 0x2020, 0x2009, 0x002a, 0x080c, 0xd2bc,
-	0x2001, 0x180c, 0x200c, 0xc195, 0x2102, 0x2019, 0x002a, 0x2009,
-	0x0001, 0x080c, 0x2ff3, 0x00e6, 0x2071, 0x1800, 0x080c, 0x2e09,
-	0x00ee, 0x00c6, 0x0156, 0x20a9, 0x0781, 0x2009, 0x007f, 0x080c,
-	0x3136, 0x8108, 0x1f04, 0xaaa7, 0x015e, 0x00ce, 0x080c, 0xaa66,
-	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, 0x24a2,
-	0x080c, 0x70ba, 0x0170, 0x2071, 0x0260, 0x2069, 0x195a, 0x7048,
-	0x206a, 0x704c, 0x6806, 0x7050, 0x680a, 0x7054, 0x680e, 0x080c,
-	0xbc9b, 0x0040, 0x2001, 0x0006, 0x080c, 0x61e0, 0x080c, 0x305d,
-	0x080c, 0x9be6, 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, 0xabee, 0x1148,
-	0x2011, 0x027a, 0x20a9, 0x0004, 0x2019, 0x0006, 0x080c, 0xabee,
-	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, 0x19d2, 0x2424, 0x2061, 0x1ddc,
-	0x2071, 0x1800, 0x7250, 0x7070, 0x9202, 0x1a04, 0xabc6, 0x080c,
-	0xd2ed, 0x0904, 0xabbf, 0x6720, 0x9786, 0x0007, 0x0904, 0xabbf,
-	0x2500, 0x9c06, 0x0904, 0xabbf, 0x2400, 0x9c06, 0x0904, 0xabbf,
-	0x3e08, 0x9186, 0x0002, 0x1148, 0x6010, 0x9005, 0x0130, 0x00b6,
-	0x2058, 0xb800, 0x00be, 0xd0bc, 0x1590, 0x00c6, 0x6043, 0xffff,
-	0x6000, 0x9086, 0x0004, 0x1110, 0x080c, 0x193e, 0x9786, 0x000a,
-	0x0148, 0x080c, 0xba85, 0x1130, 0x00ce, 0x080c, 0xa59c, 0x080c,
-	0x9c20, 0x00e8, 0x6014, 0x2048, 0x080c, 0xb870, 0x01a8, 0x9786,
-	0x0003, 0x1530, 0xa867, 0x0103, 0xa87c, 0xd0cc, 0x0130, 0x0096,
-	0xa878, 0x2048, 0x080c, 0x0fe1, 0x009e, 0xab7a, 0xa877, 0x0000,
-	0x080c, 0x69a9, 0x080c, 0xba5f, 0x080c, 0x9c20, 0x00ce, 0x9ce0,
-	0x001c, 0x7064, 0x9c02, 0x1210, 0x0804, 0xab6a, 0x012e, 0x000e,
-	0x002e, 0x004e, 0x005e, 0x007e, 0x00ce, 0x009e, 0x00ee, 0x0005,
-	0x9786, 0x0006, 0x1118, 0x080c, 0xd267, 0x0c30, 0x9786, 0x000a,
-	0x0998, 0x0880, 0x220c, 0x2304, 0x9106, 0x1130, 0x8210, 0x8318,
-	0x1f04, 0xabda, 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, 0x0d65, 0x080c, 0xba74, 0x0120,
-	0x080c, 0xba85, 0x0158, 0x0028, 0x080c, 0x305d, 0x080c, 0xba85,
-	0x0128, 0x080c, 0x8891, 0x080c, 0x9be6, 0x0005, 0x080c, 0xa59c,
-	0x0cc0, 0x9182, 0x0057, 0x1220, 0x9182, 0x0040, 0x0208, 0x000a,
-	0x0005, 0xac50, 0xac50, 0xac50, 0xac50, 0xac50, 0xac50, 0xac50,
-	0xac50, 0xac50, 0xac50, 0xac50, 0xac52, 0xac52, 0xac52, 0xac52,
-	0xac50, 0xac50, 0xac50, 0xac52, 0xac50, 0xac50, 0xac50, 0xac50,
-	0x080c, 0x0d65, 0x600b, 0xffff, 0x6003, 0x000f, 0x6106, 0x0126,
-	0x2091, 0x8000, 0x080c, 0xbfa7, 0x2009, 0x8000, 0x080c, 0x84e7,
-	0x012e, 0x0005, 0x9186, 0x0013, 0x1128, 0x6004, 0x9082, 0x0040,
-	0x0804, 0xacd7, 0x9186, 0x0027, 0x1520, 0x080c, 0x8891, 0x080c,
-	0x302e, 0x080c, 0xbfa4, 0x0096, 0x6114, 0x2148, 0x080c, 0xb870,
-	0x0198, 0x080c, 0xba85, 0x1118, 0x080c, 0xa59c, 0x0068, 0xa867,
-	0x0103, 0xa87b, 0x0029, 0xa877, 0x0000, 0xa97c, 0xc1c5, 0xa97e,
-	0x080c, 0x69b5, 0x080c, 0xba5f, 0x009e, 0x080c, 0x9be6, 0x0804,
-	0x894f, 0x9186, 0x0014, 0x1120, 0x6004, 0x9082, 0x0040, 0x0018,
-	0x080c, 0x0d65, 0x0005, 0x0002, 0xacb5, 0xacb3, 0xacb3, 0xacb3,
-	0xacb3, 0xacb3, 0xacb3, 0xacb3, 0xacb3, 0xacb3, 0xacb3, 0xacce,
-	0xacce, 0xacce, 0xacce, 0xacb3, 0xacce, 0xacb3, 0xacce, 0xacb3,
-	0xacb3, 0xacb3, 0xacb3, 0x080c, 0x0d65, 0x080c, 0x8891, 0x0096,
-	0x6114, 0x2148, 0x080c, 0xb870, 0x0168, 0xa867, 0x0103, 0xa87b,
-	0x0006, 0xa877, 0x0000, 0xa880, 0xc0ec, 0xa882, 0x080c, 0x69b5,
-	0x080c, 0xba5f, 0x009e, 0x080c, 0x9be6, 0x0005, 0x080c, 0x8891,
-	0x080c, 0xba85, 0x090c, 0xa59c, 0x080c, 0x9be6, 0x0005, 0x0002,
-	0xacf1, 0xacef, 0xacef, 0xacef, 0xacef, 0xacef, 0xacef, 0xacef,
-	0xacef, 0xacef, 0xacef, 0xacf3, 0xacf3, 0xacf3, 0xacf3, 0xacef,
-	0xacf5, 0xacef, 0xacf3, 0xacef, 0xacef, 0xacef, 0xacef, 0x080c,
-	0x0d65, 0x080c, 0x0d65, 0x080c, 0x0d65, 0x080c, 0x9be6, 0x0804,
-	0x894f, 0x9182, 0x0057, 0x1220, 0x9182, 0x0040, 0x0208, 0x000a,
-	0x0005, 0xad18, 0xad18, 0xad18, 0xad18, 0xad18, 0xad51, 0xae40,
-	0xad18, 0xae4c, 0xad18, 0xad18, 0xad18, 0xad18, 0xad18, 0xad18,
-	0xad18, 0xad18, 0xad18, 0xad18, 0xae4c, 0xad1a, 0xad18, 0xae4a,
-	0x080c, 0x0d65, 0x00b6, 0x0096, 0x6114, 0x2148, 0x6010, 0x2058,
-	0xb800, 0xd0bc, 0x1508, 0xa87b, 0x0000, 0xa867, 0x0103, 0xa877,
-	0x0000, 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115, 0x190c,
-	0xaed1, 0x080c, 0x67cb, 0x6210, 0x2258, 0xba3c, 0x82ff, 0x0110,
-	0x8211, 0xba3e, 0xb8c0, 0x9005, 0x0110, 0x080c, 0x63ba, 0x080c,
-	0x9be6, 0x009e, 0x00be, 0x0005, 0xa87c, 0xd0ac, 0x09e0, 0xa838,
-	0xa934, 0x9105, 0x09c0, 0xa880, 0xd0bc, 0x19a8, 0x080c, 0xbbba,
-	0x0c80, 0x00b6, 0x0096, 0x6114, 0x2148, 0x601c, 0xd0fc, 0x1110,
-	0x7644, 0x0008, 0x9036, 0x96b4, 0x0fff, 0x86ff, 0x1590, 0x6010,
-	0x2058, 0xb800, 0xd0bc, 0x1904, 0xae2f, 0xa87b, 0x0000, 0xa867,
-	0x0103, 0xae76, 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115,
-	0x190c, 0xaed1, 0x080c, 0x67cb, 0x6210, 0x2258, 0xba3c, 0x82ff,
-	0x0110, 0x8211, 0xba3e, 0xb8c0, 0x9005, 0x0110, 0x080c, 0x63ba,
-	0x601c, 0xd0fc, 0x1148, 0x7044, 0xd0e4, 0x1904, 0xae13, 0x080c,
-	0x9be6, 0x009e, 0x00be, 0x0005, 0x2009, 0x0211, 0x210c, 0x080c,
-	0x0d65, 0x968c, 0x0c00, 0x0150, 0x6010, 0x2058, 0xb800, 0xd0bc,
-	0x1904, 0xae17, 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, 0xad5d, 0x735c, 0xab86, 0x83ff,
-	0x0170, 0x938a, 0x0009, 0x0210, 0x2019, 0x0008, 0x0036, 0x2308,
-	0x2019, 0x0018, 0x2011, 0x0025, 0x080c, 0xb426, 0x003e, 0xd6cc,
-	0x0904, 0xad72, 0x7154, 0xa98a, 0x81ff, 0x0904, 0xad72, 0x9192,
-	0x0021, 0x1278, 0x8304, 0x9098, 0x0018, 0x2011, 0x0029, 0x080c,
-	0xb426, 0x2011, 0x0205, 0x2013, 0x0000, 0x080c, 0xbf34, 0x0804,
-	0xad72, 0xa868, 0xd0fc, 0x0120, 0x2009, 0x0020, 0xa98a, 0x0c50,
-	0x00a6, 0x2950, 0x080c, 0xb3c5, 0x00ae, 0x080c, 0xbf34, 0x080c,
-	0xb416, 0x0804, 0xad74, 0x080c, 0xbb7d, 0x0804, 0xad89, 0xa87c,
-	0xd0ac, 0x0904, 0xad9a, 0xa880, 0xd0bc, 0x1904, 0xad9a, 0x7348,
-	0xa838, 0x9306, 0x11c8, 0x734c, 0xa834, 0x931e, 0x0904, 0xad9a,
-	0xd6d4, 0x0190, 0xab38, 0x9305, 0x0904, 0xad9a, 0x0068, 0xa87c,
-	0xd0ac, 0x0904, 0xad65, 0xa838, 0xa934, 0x9105, 0x0904, 0xad65,
-	0xa880, 0xd0bc, 0x1904, 0xad65, 0x080c, 0xbbba, 0x0804, 0xad89,
-	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, 0x98f0, 0x604b,
-	0x0000, 0x080c, 0x1af7, 0x1118, 0x6144, 0x080c, 0x8513, 0x009e,
-	0x0005, 0x9182, 0x0057, 0x1220, 0x9182, 0x0040, 0x0208, 0x000a,
-	0x0005, 0xae98, 0xae98, 0xae98, 0xae98, 0xae98, 0xae98, 0xae98,
-	0xae98, 0xae98, 0xae98, 0xae9a, 0xae98, 0xae98, 0xae98, 0xae98,
-	0xaeab, 0xae98, 0xae98, 0xae98, 0xae98, 0xaecf, 0xae98, 0xae98,
-	0x080c, 0x0d65, 0x6004, 0x9086, 0x0040, 0x1110, 0x080c, 0x8891,
-	0x2019, 0x0001, 0x080c, 0x929d, 0x6003, 0x0002, 0x080c, 0xbfac,
-	0x080c, 0x88ec, 0x0005, 0x6004, 0x9086, 0x0040, 0x1110, 0x080c,
-	0x8891, 0x2019, 0x0001, 0x080c, 0x929d, 0x080c, 0x88ec, 0x080c,
-	0x302e, 0x080c, 0xbfa4, 0x0096, 0x6114, 0x2148, 0x080c, 0xb870,
-	0x0150, 0xa867, 0x0103, 0xa87b, 0x0029, 0xa877, 0x0000, 0x080c,
-	0x69b5, 0x080c, 0xba5f, 0x009e, 0x080c, 0x9be6, 0x0005, 0x080c,
-	0x0d65, 0xa87b, 0x0015, 0xd1fc, 0x0180, 0xa87b, 0x0007, 0x8002,
-	0x8000, 0x810a, 0x9189, 0x0000, 0x0006, 0x0016, 0x2009, 0x1a4f,
-	0x2104, 0x8000, 0x200a, 0x001e, 0x000e, 0xa992, 0xa88e, 0x0005,
-	0x9182, 0x0057, 0x1220, 0x9182, 0x0040, 0x0208, 0x000a, 0x0005,
-	0xaf07, 0xaf07, 0xaf07, 0xaf07, 0xaf07, 0xaf09, 0xaf07, 0xaf07,
-	0xafc6, 0xaf07, 0xaf07, 0xaf07, 0xaf07, 0xaf07, 0xaf07, 0xaf07,
-	0xaf07, 0xaf07, 0xaf07, 0xb104, 0xaf07, 0xb10e, 0xaf07, 0x080c,
-	0x0d65, 0x601c, 0xd0bc, 0x0178, 0xd084, 0x0168, 0xd0f4, 0x0120,
-	0xc084, 0x601e, 0x0804, 0xacf9, 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, 0xafbf, 0x9694, 0xff00, 0x9284, 0x0c00, 0x0120,
-	0x7048, 0xb092, 0x704c, 0xb08e, 0x9284, 0x0300, 0x0904, 0xafbf,
-	0x9686, 0x0100, 0x1130, 0x7064, 0x9005, 0x1118, 0xc6c4, 0xb676,
-	0x0c38, 0x080c, 0x102f, 0x090c, 0x0d65, 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, 0xb426, 0x003e,
-	0xd6cc, 0x01e8, 0x7154, 0xa98a, 0x81ff, 0x01c8, 0x9192, 0x0021,
-	0x1260, 0x8304, 0x9098, 0x0018, 0x2011, 0x0029, 0x080c, 0xb426,
-	0x2011, 0x0205, 0x2013, 0x0000, 0x0050, 0xb068, 0xd0fc, 0x0120,
-	0x2009, 0x0020, 0xa98a, 0x0c68, 0x2950, 0x080c, 0xb3c5, 0x080c,
-	0x190c, 0x009e, 0x00ee, 0x00ae, 0x007e, 0x0005, 0x2001, 0x1960,
-	0x2004, 0x604a, 0x0096, 0x6114, 0x2148, 0xa83c, 0xa940, 0x9105,
-	0x1118, 0xa87c, 0xc0dc, 0xa87e, 0x6003, 0x0002, 0x080c, 0xbfb5,
-	0x0904, 0xb0ff, 0x604b, 0x0000, 0x6010, 0x00b6, 0x2058, 0xb800,
-	0x00be, 0xd0bc, 0x1500, 0xd1cc, 0x0904, 0xb0c4, 0xa978, 0xa868,
-	0xd0fc, 0x0904, 0xb085, 0x0016, 0xa87c, 0x0006, 0xa880, 0x0006,
-	0x00a6, 0x2150, 0xb174, 0x9184, 0x00ff, 0x90b6, 0x0002, 0x0904,
-	0xb053, 0x9086, 0x0028, 0x1904, 0xb03f, 0xa87b, 0x001c, 0xb07b,
-	0x001c, 0x0804, 0xb05b, 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, 0x0fe1, 0x009e, 0x080c, 0xbbba, 0x0804, 0xb0ff, 0xd1dc,
-	0x0158, 0xa87b, 0x0015, 0xb07b, 0x0015, 0x080c, 0xbe57, 0x0118,
-	0xb174, 0xc1dc, 0xb176, 0x0078, 0xd1d4, 0x0128, 0xa87b, 0x0007,
-	0xb07b, 0x0007, 0x0040, 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938,
-	0x9115, 0x190c, 0xaed1, 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, 0xa87e, 0x080c, 0xbf34, 0x001e, 0xa874, 0x0006, 0x2148,
-	0x080c, 0x0fe1, 0x001e, 0x0804, 0xb0f1, 0x0016, 0x00a6, 0x2150,
-	0xb174, 0x9184, 0x00ff, 0x90b6, 0x0002, 0x01e0, 0x9086, 0x0028,
-	0x1128, 0xa87b, 0x001c, 0xb07b, 0x001c, 0x00e0, 0xd1dc, 0x0158,
-	0xa87b, 0x0015, 0xb07b, 0x0015, 0x080c, 0xbe57, 0x0118, 0xb174,
-	0xc1dc, 0xb176, 0x0078, 0xd1d4, 0x0128, 0xa87b, 0x0007, 0xb07b,
-	0x0007, 0x0040, 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115,
-	0x190c, 0xaed1, 0xa890, 0xb092, 0xa88c, 0xb08e, 0xa87c, 0xb07e,
-	0x00ae, 0x080c, 0x0fe1, 0x009e, 0x080c, 0xbf34, 0xa974, 0x0016,
-	0x080c, 0xb416, 0x001e, 0x0468, 0xa867, 0x0103, 0xa974, 0x9184,
-	0x00ff, 0x90b6, 0x0002, 0x01b0, 0x9086, 0x0028, 0x1118, 0xa87b,
-	0x001c, 0x00d0, 0xd1dc, 0x0148, 0xa87b, 0x0015, 0x080c, 0xbe57,
-	0x0118, 0xa974, 0xc1dc, 0xa976, 0x0078, 0xd1d4, 0x0118, 0xa87b,
-	0x0007, 0x0050, 0xa87b, 0x0000, 0xa87c, 0xd0ac, 0x0128, 0xa834,
-	0xa938, 0x9115, 0x190c, 0xaed1, 0xa974, 0x0016, 0x080c, 0x67cb,
-	0x001e, 0x6010, 0x00b6, 0x2058, 0xb8c0, 0x0016, 0x9005, 0x190c,
-	0x63ba, 0x001e, 0x00be, 0xd1e4, 0x1120, 0x080c, 0x9be6, 0x009e,
-	0x0005, 0x080c, 0xbb7d, 0x0cd8, 0x6114, 0x0096, 0x2148, 0xa97c,
-	0x080c, 0xbfb5, 0x190c, 0x192a, 0x009e, 0x0005, 0x0096, 0x6114,
-	0x2148, 0xa83c, 0xa940, 0x9105, 0x01e8, 0xa877, 0x0000, 0xa87b,
-	0x0000, 0xa867, 0x0103, 0x00b6, 0x6010, 0x2058, 0xa834, 0xa938,
-	0x9115, 0x11a0, 0x080c, 0x67cb, 0xba3c, 0x8211, 0x0208, 0xba3e,
-	0xb8c0, 0x9005, 0x0110, 0x080c, 0x63ba, 0x080c, 0x9be6, 0x00be,
-	0x009e, 0x0005, 0xa87c, 0xc0dc, 0xa87e, 0x08f8, 0xb800, 0xd0bc,
-	0x1120, 0xa834, 0x080c, 0xaed1, 0x0c28, 0xa880, 0xd0bc, 0x1dc8,
-	0x080c, 0xbbba, 0x0c60, 0x080c, 0x8891, 0x0010, 0x080c, 0x88ec,
-	0x601c, 0xd084, 0x0110, 0x080c, 0x193e, 0x080c, 0xb870, 0x01f0,
-	0x0096, 0x6114, 0x2148, 0x080c, 0xba85, 0x1118, 0x080c, 0xa59c,
-	0x00a0, 0xa867, 0x0103, 0x2009, 0x180c, 0x210c, 0xd18c, 0x1198,
-	0xd184, 0x1170, 0x6108, 0xa97a, 0x918e, 0x0029, 0x1110, 0x080c,
-	0xd563, 0xa877, 0x0000, 0x080c, 0x69b5, 0x009e, 0x0804, 0x9c20,
-	0xa87b, 0x0004, 0x0cb0, 0xa87b, 0x0004, 0x0c98, 0x9182, 0x0057,
-	0x1220, 0x9182, 0x0040, 0x0208, 0x000a, 0x0005, 0xb195, 0xb195,
-	0xb195, 0xb195, 0xb195, 0xb197, 0xb195, 0xb195, 0xb195, 0xb195,
-	0xb195, 0xb195, 0xb195, 0xb195, 0xb195, 0xb195, 0xb195, 0xb195,
-	0xb195, 0xb195, 0xb1bb, 0xb195, 0xb195, 0x080c, 0x0d65, 0x080c,
-	0x53b0, 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, 0x69b5,
-	0x009e, 0x0804, 0x9be6, 0x080c, 0x53b0, 0x0dd8, 0x6014, 0x900e,
-	0x9016, 0x0c10, 0x9182, 0x0085, 0x0002, 0xb1d4, 0xb1d2, 0xb1d2,
-	0xb1e0, 0xb1d2, 0xb1d2, 0xb1d2, 0xb1d2, 0xb1d2, 0xb1d2, 0xb1d2,
-	0xb1d2, 0xb1d2, 0x080c, 0x0d65, 0x6003, 0x0001, 0x6106, 0x0126,
-	0x2091, 0x8000, 0x2009, 0x8020, 0x080c, 0x84e7, 0x012e, 0x0005,
-	0x0026, 0x0056, 0x00d6, 0x00e6, 0x2071, 0x0260, 0x7224, 0x6216,
-	0x7220, 0x080c, 0xb85e, 0x01a0, 0x2268, 0x6800, 0x9086, 0x0000,
-	0x0178, 0x6010, 0x6d10, 0x952e, 0x1158, 0x00c6, 0x2d60, 0x080c,
-	0xb451, 0x00ce, 0x0128, 0x6803, 0x0002, 0x6007, 0x0086, 0x0010,
-	0x6007, 0x0087, 0x6003, 0x0001, 0x2009, 0x8020, 0x080c, 0x84e7,
-	0x7220, 0x080c, 0xb85e, 0x0178, 0x6810, 0x00b6, 0x2058, 0xb800,
-	0x00be, 0xd0bc, 0x0140, 0x6824, 0xd0ec, 0x0128, 0x00c6, 0x2d60,
-	0x080c, 0xbbba, 0x00ce, 0x00ee, 0x00de, 0x005e, 0x002e, 0x0005,
-	0x9186, 0x0013, 0x1160, 0x6004, 0x908a, 0x0085, 0x0a0c, 0x0d65,
-	0x908a, 0x0092, 0x1a0c, 0x0d65, 0x9082, 0x0085, 0x00e2, 0x9186,
-	0x0027, 0x0120, 0x9186, 0x0014, 0x190c, 0x0d65, 0x080c, 0x8891,
-	0x0096, 0x6014, 0x2048, 0x080c, 0xb870, 0x0140, 0xa867, 0x0103,
-	0xa877, 0x0000, 0xa87b, 0x0029, 0x080c, 0x69b5, 0x009e, 0x080c,
-	0x9c20, 0x0804, 0x894f, 0xb258, 0xb25a, 0xb25a, 0xb258, 0xb258,
-	0xb258, 0xb258, 0xb258, 0xb258, 0xb258, 0xb258, 0xb258, 0xb258,
-	0x080c, 0x0d65, 0x080c, 0x9c20, 0x0005, 0x9186, 0x0013, 0x1130,
-	0x6004, 0x9082, 0x0085, 0x2008, 0x0804, 0xb2a9, 0x9186, 0x0027,
-	0x1558, 0x080c, 0x8891, 0x080c, 0x302e, 0x080c, 0xbfa4, 0x0096,
-	0x6014, 0x2048, 0x080c, 0xb870, 0x0150, 0xa867, 0x0103, 0xa877,
-	0x0000, 0xa87b, 0x0029, 0x080c, 0x69b5, 0x080c, 0xba5f, 0x009e,
-	0x080c, 0x9be6, 0x0005, 0x9186, 0x0089, 0x0118, 0x9186, 0x008a,
-	0x1140, 0x080c, 0x9ab6, 0x0128, 0x9086, 0x000c, 0x0904, 0xb2e1,
-	0x0000, 0x080c, 0x9c9f, 0x0c70, 0x9186, 0x0014, 0x1d60, 0x080c,
-	0x8891, 0x0096, 0x6014, 0x2048, 0x080c, 0xb870, 0x0d00, 0xa867,
-	0x0103, 0xa877, 0x0000, 0xa87b, 0x0006, 0xa880, 0xc0ec, 0xa882,
-	0x0890, 0x0002, 0xb2b9, 0xb2b7, 0xb2b7, 0xb2b7, 0xb2b7, 0xb2b7,
-	0xb2cd, 0xb2b7, 0xb2b7, 0xb2b7, 0xb2b7, 0xb2b7, 0xb2b7, 0x080c,
-	0x0d65, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0039, 0x0118,
-	0x9186, 0x0035, 0x1118, 0x2001, 0x195e, 0x0010, 0x2001, 0x195f,
-	0x2004, 0x601a, 0x6003, 0x000c, 0x0005, 0x6034, 0x908c, 0xff00,
-	0x810f, 0x9186, 0x0039, 0x0118, 0x9186, 0x0035, 0x1118, 0x2001,
-	0x195e, 0x0010, 0x2001, 0x195f, 0x2004, 0x601a, 0x6003, 0x000e,
-	0x0005, 0x9182, 0x0092, 0x1220, 0x9182, 0x0085, 0x0208, 0x0012,
-	0x0804, 0x9c9f, 0xb2f7, 0xb2f7, 0xb2f7, 0xb2f7, 0xb2f9, 0xb346,
-	0xb2f7, 0xb2f7, 0xb2f7, 0xb2f7, 0xb2f7, 0xb2f7, 0xb2f7, 0x080c,
-	0x0d65, 0x0096, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc,
-	0x0168, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0039, 0x0118,
-	0x9186, 0x0035, 0x1118, 0x009e, 0x0804, 0xb35a, 0x080c, 0xb870,
-	0x1118, 0x080c, 0xba5f, 0x0068, 0x6014, 0x2048, 0x080c, 0xbfbb,
-	0x1110, 0x080c, 0xba5f, 0xa867, 0x0103, 0x080c, 0xbf6f, 0x080c,
-	0x69b5, 0x00d6, 0x2c68, 0x080c, 0x9b90, 0x01d0, 0x6003, 0x0001,
-	0x6007, 0x001e, 0x600b, 0xffff, 0x2009, 0x026e, 0x210c, 0x613a,
-	0x2009, 0x026f, 0x210c, 0x613e, 0x6910, 0x6112, 0x080c, 0xbd09,
-	0x695c, 0x615e, 0x6023, 0x0001, 0x2009, 0x8020, 0x080c, 0x84e7,
-	0x2d60, 0x00de, 0x080c, 0x9be6, 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, 0xbf07, 0x11f0, 0x080c,
-	0x9b90, 0x01d8, 0x6106, 0x6003, 0x0001, 0x6023, 0x0001, 0x6910,
-	0x6112, 0x692c, 0x612e, 0x6930, 0x6132, 0x6934, 0x918c, 0x00ff,
-	0x6136, 0x6938, 0x613a, 0x693c, 0x613e, 0x695c, 0x615e, 0x080c,
-	0xbd09, 0x2009, 0x8020, 0x080c, 0x84e7, 0x2d60, 0x00de, 0x0804,
-	0x9be6, 0x0096, 0x6014, 0x2048, 0x080c, 0xb870, 0x01c8, 0xa867,
-	0x0103, 0xa880, 0xd0b4, 0x0128, 0xc0ec, 0xa882, 0xa87b, 0x0006,
-	0x0048, 0xd0bc, 0x0118, 0xa87b, 0x0002, 0x0020, 0xa87b, 0x0005,
-	0x080c, 0xbb79, 0xa877, 0x0000, 0x080c, 0x69b5, 0x080c, 0xba5f,
-	0x009e, 0x0804, 0x9be6, 0x0016, 0x0096, 0x6014, 0x2048, 0x080c,
-	0xb870, 0x0140, 0xa867, 0x0103, 0xa87b, 0x0028, 0xa877, 0x0000,
-	0x080c, 0x69b5, 0x009e, 0x001e, 0x9186, 0x0013, 0x0158, 0x9186,
-	0x0014, 0x0130, 0x9186, 0x0027, 0x0118, 0x080c, 0x9c9f, 0x0020,
-	0x080c, 0x8891, 0x080c, 0x9c20, 0x0005, 0x0056, 0x0066, 0x0096,
-	0x00a6, 0x2029, 0x0001, 0x9182, 0x0101, 0x1208, 0x0010, 0x2009,
-	0x0100, 0x2130, 0x8304, 0x9098, 0x0018, 0x2009, 0x0020, 0x2011,
-	0x0029, 0x080c, 0xb426, 0x96b2, 0x0020, 0xb004, 0x904d, 0x0110,
-	0x080c, 0x0fe1, 0x080c, 0x102f, 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, 0x69b5,
-	0x2a48, 0x0cb8, 0x080c, 0x69b5, 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, 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, 0xb4a3, 0xb4a3, 0xb49e, 0xb4c7, 0xb47b,
-	0xb49e, 0xb47d, 0xb49e, 0xb47b, 0xb47b, 0xb49e, 0xb49e, 0xb49e,
-	0xb47b, 0xb47b, 0xb47b, 0x080c, 0x0d65, 0x6010, 0x9080, 0x0000,
-	0x2004, 0xd0bc, 0x190c, 0xb4c7, 0x0036, 0x6014, 0x0096, 0x2048,
-	0xa880, 0x009e, 0xd0cc, 0x0118, 0x2019, 0x000c, 0x0038, 0xd094,
-	0x0118, 0x2019, 0x000d, 0x0010, 0x2019, 0x0010, 0x080c, 0xce41,
-	0x6023, 0x0006, 0x6003, 0x0007, 0x003e, 0x0005, 0x9006, 0x0005,
-	0x9085, 0x0001, 0x0005, 0x0096, 0x86ff, 0x11e8, 0x6014, 0x2048,
-	0x080c, 0xb870, 0x01d0, 0x6043, 0xffff, 0xa864, 0x9086, 0x0139,
-	0x1128, 0xa87b, 0x0005, 0xa883, 0x0000, 0x0028, 0x900e, 0x2001,
-	0x0005, 0x080c, 0x6bc6, 0x080c, 0xbb79, 0x080c, 0x69a9, 0x080c,
-	0x9c20, 0x9085, 0x0001, 0x009e, 0x0005, 0x9006, 0x0ce0, 0x080c,
-	0x98c7, 0x080c, 0xbfc9, 0x6000, 0x908a, 0x0016, 0x1a0c, 0x0d65,
-	0x002b, 0x0106, 0x080c, 0x98e3, 0x010e, 0x0005, 0xb4e6, 0xb514,
-	0xb4e8, 0xb53b, 0xb50f, 0xb4e6, 0xb49e, 0xb4a3, 0xb4a3, 0xb49e,
-	0xb49e, 0xb49e, 0xb49e, 0xb49e, 0xb49e, 0xb49e, 0x080c, 0x0d65,
-	0x86ff, 0x1510, 0x6020, 0x9086, 0x0006, 0x01f0, 0x0096, 0x6014,
-	0x2048, 0x080c, 0xb870, 0x0158, 0xa87c, 0xd0cc, 0x0130, 0x0096,
-	0xa878, 0x2048, 0x080c, 0x0fe1, 0x009e, 0x080c, 0xbb79, 0x009e,
-	0x080c, 0xbf49, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002,
-	0x2009, 0x8020, 0x080c, 0x84c9, 0x9085, 0x0001, 0x0005, 0x0066,
-	0x080c, 0x193e, 0x006e, 0x08a0, 0x00e6, 0x2071, 0x19bf, 0x7030,
-	0x9c06, 0x1120, 0x080c, 0x921d, 0x00ee, 0x0850, 0x6020, 0x9084,
-	0x000f, 0x9086, 0x0006, 0x1150, 0x0086, 0x0096, 0x2049, 0x0001,
-	0x2c40, 0x080c, 0x936d, 0x009e, 0x008e, 0x0040, 0x0066, 0x080c,
-	0x9119, 0x190c, 0x0d65, 0x080c, 0x9127, 0x006e, 0x00ee, 0x1904,
-	0xb4e8, 0x0804, 0xb49e, 0x0036, 0x00e6, 0x2071, 0x19bf, 0x704c,
-	0x9c06, 0x1138, 0x901e, 0x080c, 0x929d, 0x00ee, 0x003e, 0x0804,
-	0xb4e8, 0x080c, 0x94a4, 0x00ee, 0x003e, 0x1904, 0xb4e8, 0x0804,
-	0xb49e, 0x00c6, 0x0066, 0x6020, 0x9084, 0x000f, 0x001b, 0x006e,
-	0x00ce, 0x0005, 0xb571, 0xb640, 0xb7aa, 0xb579, 0x9c20, 0xb571,
-	0xce33, 0xbfb1, 0xb640, 0xb56a, 0xb836, 0xb56a, 0xb56a, 0xb56a,
-	0xb56a, 0xb56a, 0x080c, 0x0d65, 0x080c, 0xba85, 0x1110, 0x080c,
-	0xa59c, 0x0005, 0x080c, 0x8891, 0x0804, 0x9be6, 0x601b, 0x0001,
-	0x0005, 0x080c, 0xb870, 0x0130, 0x6014, 0x0096, 0x2048, 0x2c00,
-	0xa896, 0x009e, 0x080c, 0x98c7, 0x080c, 0xbfc9, 0x6000, 0x908a,
-	0x0016, 0x1a0c, 0x0d65, 0x0013, 0x0804, 0x98e3, 0xb59e, 0xb5a0,
-	0xb5ca, 0xb5de, 0xb60b, 0xb59e, 0xb571, 0xb571, 0xb571, 0xb5e5,
-	0xb5e5, 0xb59e, 0xb59e, 0xb59e, 0xb59e, 0xb5ef, 0x080c, 0x0d65,
-	0x00e6, 0x6014, 0x0096, 0x2048, 0xa880, 0xc0b5, 0xa882, 0x009e,
-	0x2071, 0x19bf, 0x7030, 0x9c06, 0x01d0, 0x0066, 0x080c, 0x9119,
-	0x190c, 0x0d65, 0x080c, 0x9127, 0x006e, 0x080c, 0xbf49, 0x6007,
-	0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x2001, 0x195f, 0x2004,
-	0x601a, 0x2009, 0x8020, 0x080c, 0x84c9, 0x00ee, 0x0005, 0x601b,
-	0x0001, 0x0cd8, 0x0096, 0x6014, 0x2048, 0xa880, 0xc0b5, 0xa882,
-	0x009e, 0x080c, 0xbf49, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023,
-	0x0002, 0x2009, 0x8020, 0x080c, 0x84c9, 0x0005, 0x080c, 0x98c7,
-	0x080c, 0x9a38, 0x080c, 0x98e3, 0x0c28, 0x0096, 0x601b, 0x0001,
-	0x6014, 0x2048, 0xa880, 0xc0b5, 0xa882, 0x009e, 0x0005, 0x080c,
-	0x53b0, 0x01b8, 0x6014, 0x0096, 0x904d, 0x0190, 0xa864, 0xa867,
-	0x0103, 0xa87b, 0x0006, 0x9086, 0x0139, 0x1150, 0xa867, 0x0139,
-	0xa87b, 0x0030, 0xa897, 0x4005, 0xa89b, 0x0004, 0x080c, 0x69b5,
-	0x009e, 0x0804, 0x9be6, 0x6014, 0x0096, 0x904d, 0x0560, 0xa97c,
-	0xd1e4, 0x1158, 0x611c, 0xd1fc, 0x0530, 0x6110, 0x00b6, 0x2158,
-	0xb93c, 0x8109, 0x0208, 0xb93e, 0x00be, 0x080c, 0x98e3, 0x2001,
-	0x180f, 0x2004, 0xd0c4, 0x0110, 0x009e, 0x0005, 0xa884, 0x009e,
-	0x8003, 0x800b, 0x810b, 0x9108, 0x611a, 0x2001, 0x0037, 0x2c08,
-	0x080c, 0x15b8, 0x6000, 0x9086, 0x0004, 0x1120, 0x2009, 0x0048,
-	0x080c, 0x9c82, 0x0005, 0x009e, 0x080c, 0x193e, 0x0804, 0xb5ca,
-	0x6000, 0x908a, 0x0016, 0x1a0c, 0x0d65, 0x000b, 0x0005, 0xb657,
-	0xb576, 0xb659, 0xb657, 0xb659, 0xb659, 0xb572, 0xb657, 0xb56c,
-	0xb56c, 0xb657, 0xb657, 0xb657, 0xb657, 0xb657, 0xb657, 0x080c,
-	0x0d65, 0x6010, 0x00b6, 0x2058, 0xb804, 0x9084, 0x00ff, 0x00be,
-	0x908a, 0x000c, 0x1a0c, 0x0d65, 0x00b6, 0x0013, 0x00be, 0x0005,
-	0xb674, 0xb741, 0xb676, 0xb6b6, 0xb676, 0xb6b6, 0xb676, 0xb684,
-	0xb674, 0xb6b6, 0xb674, 0xb6a5, 0x080c, 0x0d65, 0x6004, 0x908e,
-	0x0016, 0x05c0, 0x908e, 0x0004, 0x05a8, 0x908e, 0x0002, 0x0590,
-	0x908e, 0x0052, 0x0904, 0xb73d, 0x6004, 0x080c, 0xba85, 0x0904,
-	0xb75a, 0x908e, 0x0004, 0x1110, 0x080c, 0x305d, 0x908e, 0x0021,
-	0x0904, 0xb75e, 0x908e, 0x0022, 0x0904, 0xb7a5, 0x908e, 0x003d,
-	0x0904, 0xb75e, 0x908e, 0x0039, 0x0904, 0xb762, 0x908e, 0x0035,
-	0x0904, 0xb762, 0x908e, 0x001e, 0x0178, 0x908e, 0x0001, 0x1140,
-	0x6010, 0x2058, 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, 0x0110,
-	0x080c, 0x302e, 0x080c, 0xa59c, 0x0804, 0x9c20, 0x00c6, 0x00d6,
-	0x6104, 0x9186, 0x0016, 0x0904, 0xb72e, 0x9186, 0x0002, 0x1904,
-	0xb703, 0x2001, 0x1836, 0x2004, 0xd08c, 0x11c8, 0x080c, 0x70ba,
-	0x11b0, 0x080c, 0xbf8f, 0x0138, 0x080c, 0x70dd, 0x1120, 0x080c,
-	0x6fc5, 0x0804, 0xb78e, 0x2001, 0x1955, 0x2003, 0x0001, 0x2001,
-	0x1800, 0x2003, 0x0001, 0x080c, 0x6feb, 0x0804, 0xb78e, 0x6010,
-	0x2058, 0x2001, 0x1836, 0x2004, 0xd0ac, 0x1904, 0xb78e, 0xb8a0,
-	0x9084, 0xff80, 0x1904, 0xb78e, 0xb840, 0x9084, 0x00ff, 0x9005,
-	0x0190, 0x8001, 0xb842, 0x6017, 0x0000, 0x6023, 0x0007, 0x601b,
-	0x0398, 0x604b, 0x0000, 0x080c, 0x9b90, 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,
-	0x5c8a, 0x00ee, 0x080c, 0xa59c, 0x0030, 0x080c, 0xa59c, 0x080c,
-	0x302e, 0x080c, 0xbfa4, 0x00e6, 0x0126, 0x2091, 0x8000, 0x080c,
-	0x305d, 0x012e, 0x00ee, 0x080c, 0x9c20, 0x0005, 0x2001, 0x0002,
-	0x080c, 0x61e0, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x84ee,
-	0x080c, 0x894f, 0x00de, 0x00ce, 0x0c80, 0x080c, 0x305d, 0x0804,
-	0xb6b2, 0x00c6, 0x00d6, 0x6104, 0x9186, 0x0016, 0x0d38, 0x6010,
-	0x2058, 0xb840, 0x9084, 0x00ff, 0x9005, 0x0904, 0xb703, 0x8001,
-	0xb842, 0x6003, 0x0001, 0x080c, 0x84ee, 0x080c, 0x894f, 0x00de,
-	0x00ce, 0x0898, 0x080c, 0xa59c, 0x0804, 0xb6b4, 0x080c, 0xa5d8,
-	0x0804, 0xb6b4, 0x00d6, 0x2c68, 0x6104, 0x080c, 0xbf07, 0x00de,
-	0x0118, 0x080c, 0x9be6, 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, 0x2009, 0x8020, 0x080c, 0x84e7, 0x0005, 0x00de, 0x00ce,
-	0x080c, 0xa59c, 0x080c, 0x302e, 0x00e6, 0x0126, 0x2091, 0x8000,
-	0x080c, 0x305d, 0x6017, 0x0000, 0x6023, 0x0007, 0x601b, 0x0398,
-	0x604b, 0x0000, 0x012e, 0x00ee, 0x0005, 0x080c, 0xa020, 0x1904,
-	0xb75a, 0x0005, 0x6000, 0x908a, 0x0016, 0x1a0c, 0x0d65, 0x0096,
-	0x00d6, 0x001b, 0x00de, 0x009e, 0x0005, 0xb7c5, 0xb7c5, 0xb7c5,
-	0xb7c5, 0xb7c5, 0xb7c5, 0xb7c5, 0xb7c5, 0xb7c5, 0xb571, 0xb7c5,
-	0xb576, 0xb7c7, 0xb576, 0xb7e1, 0xb7c5, 0x080c, 0x0d65, 0x6004,
-	0x9086, 0x008b, 0x01b0, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186,
-	0x0035, 0x1130, 0x602c, 0x9080, 0x0009, 0x200c, 0xc185, 0x2102,
-	0x6007, 0x008b, 0x6003, 0x000d, 0x2009, 0x8020, 0x080c, 0x84e7,
-	0x0005, 0x080c, 0xbf83, 0x0118, 0x080c, 0xbf96, 0x0010, 0x080c,
-	0xbfa4, 0x080c, 0xba5f, 0x080c, 0xb870, 0x0570, 0x080c, 0x302e,
-	0x080c, 0xb870, 0x0168, 0x6014, 0x2048, 0xa867, 0x0103, 0xa87b,
-	0x0006, 0xa877, 0x0000, 0xa880, 0xc0ed, 0xa882, 0x080c, 0x69b5,
-	0x2c68, 0x080c, 0x9b90, 0x0150, 0x6810, 0x6012, 0x080c, 0xbd09,
-	0x00c6, 0x2d60, 0x080c, 0x9c20, 0x00ce, 0x0008, 0x2d60, 0x6017,
-	0x0000, 0x6023, 0x0001, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c,
-	0x84ee, 0x080c, 0x894f, 0x00c8, 0x080c, 0xbf83, 0x0138, 0x6034,
-	0x9086, 0x4000, 0x1118, 0x080c, 0x302e, 0x08d0, 0x6034, 0x908c,
-	0xff00, 0x810f, 0x9186, 0x0039, 0x0118, 0x9186, 0x0035, 0x1118,
-	0x080c, 0x302e, 0x0868, 0x080c, 0x9c20, 0x0005, 0x6000, 0x908a,
-	0x0016, 0x1a0c, 0x0d65, 0x0002, 0xb84c, 0xb84c, 0xb84e, 0xb84e,
-	0xb84e, 0xb84c, 0xb84c, 0x9c20, 0xb84c, 0xb84c, 0xb84c, 0xb84c,
-	0xb84c, 0xb84c, 0xb84c, 0xb84c, 0x080c, 0x0d65, 0x080c, 0x98c7,
-	0x080c, 0x9a38, 0x080c, 0x98e3, 0x6114, 0x0096, 0x2148, 0xa87b,
-	0x0006, 0x080c, 0x69b5, 0x009e, 0x0804, 0x9be6, 0x9284, 0x0003,
-	0x1158, 0x9282, 0x1ddc, 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, 0x10da, 0x000e, 0x009e, 0x0005,
-	0x00e6, 0x00c6, 0x0036, 0x0006, 0x0126, 0x2091, 0x8000, 0x2061,
-	0x1ddc, 0x2071, 0x1800, 0x7350, 0x7070, 0x9302, 0x1640, 0x6020,
-	0x9206, 0x11f8, 0x080c, 0xbf8f, 0x0180, 0x9286, 0x0001, 0x1168,
-	0x6004, 0x9086, 0x0004, 0x1148, 0x080c, 0x302e, 0x080c, 0xbfa4,
-	0x00c6, 0x080c, 0x9c20, 0x00ce, 0x0060, 0x080c, 0xbc7b, 0x0148,
-	0x080c, 0xba85, 0x1110, 0x080c, 0xa59c, 0x00c6, 0x080c, 0x9be6,
-	0x00ce, 0x9ce0, 0x001c, 0x7064, 0x9c02, 0x1208, 0x08a0, 0x012e,
-	0x000e, 0x003e, 0x00ce, 0x00ee, 0x0005, 0x00e6, 0x00c6, 0x0016,
-	0x9188, 0x1000, 0x210c, 0x81ff, 0x0128, 0x2061, 0x1b09, 0x6112,
-	0x080c, 0x302e, 0x9006, 0x0010, 0x9085, 0x0001, 0x001e, 0x00ce,
-	0x00ee, 0x0005, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0x9b90,
-	0x01b0, 0x665e, 0x2b00, 0x6012, 0x080c, 0x53b0, 0x0118, 0x080c,
-	0xb9a1, 0x0168, 0x080c, 0xbd09, 0x6023, 0x0003, 0x2009, 0x004b,
-	0x080c, 0x9c82, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006,
-	0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000, 0xbaa0, 0x080c, 0x9c55,
-	0x0580, 0x605f, 0x0000, 0x2b00, 0x6012, 0x080c, 0xbd09, 0x6023,
-	0x0003, 0x0016, 0x080c, 0x98c7, 0x080c, 0x8658, 0x0076, 0x903e,
-	0x080c, 0x853d, 0x2c08, 0x080c, 0xd011, 0x007e, 0x080c, 0x98e3,
-	0x001e, 0xd184, 0x0128, 0x080c, 0x9be6, 0x9085, 0x0001, 0x0070,
-	0x080c, 0x53b0, 0x0128, 0xd18c, 0x1170, 0x080c, 0xb9a1, 0x0148,
-	0x2009, 0x004c, 0x080c, 0x9c82, 0x9085, 0x0001, 0x012e, 0x00ce,
-	0x0005, 0x9006, 0x0cd8, 0x2900, 0x6016, 0x0c90, 0x2009, 0x004d,
-	0x0010, 0x2009, 0x004e, 0x00f6, 0x00c6, 0x0046, 0x0016, 0x080c,
-	0x9b90, 0x2c78, 0x0590, 0x7e5e, 0x2b00, 0x7812, 0x7823, 0x0003,
-	0x2021, 0x0005, 0x080c, 0xb9b3, 0x9186, 0x004d, 0x0118, 0x9186,
-	0x004e, 0x0148, 0x2001, 0x1958, 0x200c, 0xd1fc, 0x0168, 0x2f60,
-	0x080c, 0x9be6, 0x00d0, 0x2001, 0x1957, 0x200c, 0xd1fc, 0x0120,
-	0x2f60, 0x080c, 0x9be6, 0x0088, 0x2f60, 0x080c, 0x53b0, 0x0138,
-	0xd18c, 0x1118, 0x04f1, 0x0148, 0x0010, 0x2900, 0x7816, 0x001e,
-	0x0016, 0x080c, 0x9c82, 0x9085, 0x0001, 0x001e, 0x004e, 0x00ce,
-	0x00fe, 0x0005, 0x00f6, 0x00c6, 0x0046, 0x080c, 0x9b90, 0x2c78,
-	0x0508, 0x7e5e, 0x2b00, 0x7812, 0x7823, 0x0003, 0x0096, 0x2021,
-	0x0004, 0x0489, 0x009e, 0x2001, 0x1956, 0x200c, 0xd1fc, 0x0120,
-	0x2f60, 0x080c, 0x9be6, 0x0060, 0x2f60, 0x080c, 0x53b0, 0x0120,
-	0xd18c, 0x1160, 0x0071, 0x0130, 0x2009, 0x0052, 0x080c, 0x9c82,
-	0x9085, 0x0001, 0x004e, 0x00ce, 0x00fe, 0x0005, 0x2900, 0x7816,
-	0x0c98, 0x00c6, 0x080c, 0x489a, 0x00ce, 0x1120, 0x080c, 0x9be6,
-	0x9006, 0x0005, 0xa867, 0x0000, 0xa86b, 0x8000, 0x2900, 0x6016,
-	0x9085, 0x0001, 0x0005, 0x0096, 0x0076, 0x0126, 0x2091, 0x8000,
-	0x080c, 0x98c7, 0x080c, 0x6471, 0x0158, 0x2001, 0xb9ba, 0x0006,
-	0x900e, 0x2400, 0x080c, 0x6bc6, 0x080c, 0x69b5, 0x000e, 0x0807,
-	0x2418, 0x080c, 0x8857, 0xbaa0, 0x0086, 0x2041, 0x0001, 0x2039,
-	0x0001, 0x2608, 0x080c, 0x8672, 0x008e, 0x080c, 0x853d, 0x2f08,
-	0x2648, 0x080c, 0xd011, 0xb93c, 0x81ff, 0x090c, 0x8749, 0x080c,
-	0x98e3, 0x012e, 0x007e, 0x009e, 0x0005, 0x00c6, 0x0126, 0x2091,
-	0x8000, 0x080c, 0x9b90, 0x0190, 0x660a, 0x2b08, 0x6112, 0x080c,
-	0xbd09, 0x6023, 0x0001, 0x2900, 0x6016, 0x2009, 0x001f, 0x080c,
-	0x9c82, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8,
-	0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0x9c55, 0x01b8, 0x660a,
-	0x2b08, 0x6112, 0x080c, 0xbd09, 0x6023, 0x0008, 0x2900, 0x6016,
-	0x00f6, 0x2c78, 0x080c, 0x1669, 0x00fe, 0x2009, 0x0021, 0x080c,
-	0x9c82, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8,
-	0x2009, 0x003d, 0x00c6, 0x0126, 0x0016, 0x2091, 0x8000, 0x080c,
-	0x9b90, 0x0198, 0x660a, 0x2b08, 0x6112, 0x080c, 0xbd09, 0x6023,
-	0x0001, 0x2900, 0x6016, 0x001e, 0x0016, 0x080c, 0x9c82, 0x9085,
-	0x0001, 0x001e, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd0, 0x00c6,
-	0x0126, 0x2091, 0x8000, 0x080c, 0x9c55, 0x0188, 0x2b08, 0x6112,
-	0x080c, 0xbd09, 0x6023, 0x0001, 0x2900, 0x6016, 0x2009, 0x0000,
-	0x080c, 0x9c82, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006,
-	0x0cd8, 0x2009, 0x0044, 0x0830, 0x2009, 0x0049, 0x0818, 0x0026,
-	0x00b6, 0x6210, 0x2258, 0xba3c, 0x82ff, 0x0118, 0x8211, 0xba3e,
-	0x1140, 0xb8c0, 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, 0xb870,
-	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, 0x9c55, 0x0198, 0x2b08, 0x6112,
-	0x080c, 0xbd09, 0x6023, 0x0001, 0x2900, 0x6016, 0x080c, 0x302e,
-	0x2009, 0x0028, 0x080c, 0x9c82, 0x9085, 0x0001, 0x012e, 0x00ce,
-	0x0005, 0x9006, 0x0cd8, 0x9186, 0x0015, 0x11a8, 0x2011, 0x1823,
-	0x2204, 0x9086, 0x0074, 0x1178, 0x00b6, 0x080c, 0xa827, 0x00be,
-	0x080c, 0xaa66, 0x6003, 0x0001, 0x6007, 0x0029, 0x080c, 0x84ee,
-	0x080c, 0x894f, 0x0078, 0x6014, 0x0096, 0x2048, 0xa868, 0x009e,
-	0xd0fc, 0x0148, 0x2001, 0x0001, 0x080c, 0xbec8, 0x080c, 0xa59c,
-	0x080c, 0x9be6, 0x0005, 0x0096, 0x6014, 0x904d, 0x090c, 0x0d65,
-	0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, 0x4005, 0xa89b, 0x0004,
-	0xa867, 0x0139, 0x0126, 0x2091, 0x8000, 0x080c, 0x69b5, 0x012e,
-	0x009e, 0x080c, 0x9be6, 0x0c30, 0x0096, 0x9186, 0x0016, 0x1128,
-	0x2001, 0x0004, 0x080c, 0x61e0, 0x00e8, 0x9186, 0x0015, 0x1510,
-	0x2011, 0x1823, 0x2204, 0x9086, 0x0014, 0x11e0, 0x6010, 0x00b6,
-	0x2058, 0x080c, 0x632a, 0x00be, 0x080c, 0xab37, 0x1198, 0x6010,
-	0x00b6, 0x2058, 0xb890, 0x00be, 0x9005, 0x0160, 0x2001, 0x0006,
-	0x080c, 0x61e0, 0x6014, 0x2048, 0xa868, 0xd0fc, 0x0170, 0x080c,
-	0x9ff4, 0x0048, 0x6014, 0x2048, 0xa868, 0xd0fc, 0x0528, 0x080c,
-	0xa59c, 0x080c, 0x9be6, 0x009e, 0x0005, 0x6014, 0x6310, 0x2358,
-	0x904d, 0x090c, 0x0d65, 0xa87b, 0x0000, 0xa883, 0x0000, 0xa897,
-	0x4000, 0x900e, 0x080c, 0x6582, 0x1108, 0xc185, 0xb800, 0xd0bc,
-	0x0108, 0xc18d, 0xa99a, 0x0126, 0x2091, 0x8000, 0x080c, 0x69b5,
-	0x012e, 0x080c, 0x9be6, 0x08f8, 0x6014, 0x904d, 0x090c, 0x0d65,
-	0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, 0x4005, 0xa89b, 0x0004,
-	0xa867, 0x0139, 0x0126, 0x2091, 0x8000, 0x080c, 0x69b5, 0x012e,
-	0x080c, 0x9be6, 0x0840, 0xa878, 0x9086, 0x0005, 0x1108, 0x0009,
-	0x0005, 0xa880, 0xc0ad, 0xa882, 0x0005, 0x604b, 0x0000, 0x6017,
-	0x0000, 0x6003, 0x0001, 0x6007, 0x0050, 0x2009, 0x8023, 0x080c,
-	0x84e7, 0x0005, 0x00c6, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be,
-	0xd0bc, 0x0130, 0x0066, 0x6020, 0x9084, 0x000f, 0x001b, 0x006e,
-	0x00ce, 0x0005, 0xb571, 0xbbac, 0xbbac, 0xbbaf, 0xd30b, 0xd326,
-	0xd329, 0xb571, 0xb571, 0xb571, 0xb571, 0xb571, 0xb571, 0xb571,
-	0xb571, 0xb571, 0x080c, 0x0d65, 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, 0x9b90, 0x0508, 0x7810, 0x6012, 0x080c, 0xbd09, 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,
-	0x84e7, 0x2f60, 0x00fe, 0x0005, 0x2f60, 0x00fe, 0x2001, 0x1960,
-	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, 0x0fe1, 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,
-	0x84e7, 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,
-	0x842f, 0x2001, 0x195e, 0x82ff, 0x1110, 0x2011, 0x0014, 0x2202,
-	0x2001, 0x195c, 0x200c, 0x8000, 0x2014, 0x2071, 0x1944, 0x711a,
-	0x721e, 0x2001, 0x0064, 0x080c, 0x842f, 0x2001, 0x195f, 0x82ff,
-	0x1110, 0x2011, 0x0014, 0x2202, 0x2001, 0x1960, 0x9288, 0x000a,
-	0x2102, 0x2001, 0x0017, 0x080c, 0x98b8, 0x2001, 0x1a60, 0x2102,
-	0x2001, 0x0032, 0x080c, 0x15b8, 0x080c, 0x666b, 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, 0x0017, 0x080c, 0x98b8, 0x2001, 0x1a60,
-	0x2102, 0x2001, 0x0032, 0x080c, 0x15b8, 0x00ee, 0x001e, 0x000e,
-	0x0005, 0x0096, 0x6060, 0x904d, 0x0110, 0x080c, 0x1061, 0x009e,
-	0x0005, 0x0005, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0x9b90,
-	0x0180, 0x2b08, 0x6112, 0x0ca9, 0x6023, 0x0001, 0x2900, 0x6016,
-	0x2009, 0x0033, 0x080c, 0x9c82, 0x9085, 0x0001, 0x012e, 0x00ce,
-	0x0005, 0x9006, 0x0cd8, 0x0096, 0x00e6, 0x00f6, 0x2071, 0x1800,
-	0x9186, 0x0015, 0x1500, 0x708c, 0x9086, 0x0018, 0x11e0, 0x6014,
-	0x2048, 0xaa3c, 0xd2e4, 0x1160, 0x2c78, 0x080c, 0x8a0e, 0x01d8,
-	0x7078, 0xaa50, 0x9206, 0x1160, 0x707c, 0xaa54, 0x9206, 0x1140,
-	0x6210, 0x00b6, 0x2258, 0xbaa0, 0x00be, 0x900e, 0x080c, 0x307d,
-	0x080c, 0x9ff4, 0x0020, 0x080c, 0xa59c, 0x080c, 0x9be6, 0x00fe,
-	0x00ee, 0x009e, 0x0005, 0x705c, 0xaa54, 0x9206, 0x0d48, 0x0c80,
-	0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0x9b90, 0x0188, 0x2b08,
-	0x6112, 0x080c, 0xbd09, 0x6023, 0x0001, 0x2900, 0x6016, 0x2009,
-	0x004d, 0x080c, 0x9c82, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005,
-	0x9006, 0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000, 0x0016, 0x080c,
-	0x9b90, 0x0180, 0x2b08, 0x6112, 0x080c, 0xbd09, 0x6023, 0x0001,
-	0x2900, 0x6016, 0x001e, 0x080c, 0x9c82, 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, 0x2003, 0x0000,
-	0x6014, 0x2048, 0xa830, 0x20a8, 0x8906, 0x8006, 0x8007, 0x9094,
-	0x003f, 0x22e8, 0x9084, 0xffc0, 0x9080, 0x001b, 0x20a0, 0x2001,
-	0x1978, 0x0016, 0x200c, 0x080c, 0xc581, 0x001e, 0xa804, 0x9005,
-	0x0110, 0x2048, 0x0c38, 0x6014, 0x2048, 0xa867, 0x0103, 0x0010,
-	0x080c, 0xa59c, 0x080c, 0x9be6, 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, 0x8a0e, 0x01a8,
-	0x7078, 0xaa74, 0x9206, 0x1130, 0x707c, 0xaa78, 0x9206, 0x1110,
-	0x080c, 0x302e, 0x080c, 0x9ff4, 0x0020, 0x080c, 0xa59c, 0x080c,
-	0x9be6, 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, 0x8a0e, 0x05f0, 0x7078, 0xaacc, 0x9206, 0x1180,
-	0x707c, 0xaad0, 0x9206, 0x1160, 0x080c, 0x302e, 0x0016, 0xa998,
-	0xaab0, 0x9284, 0x1000, 0xc0fd, 0x080c, 0x5360, 0x001e, 0x0010,
-	0x080c, 0x5149, 0x080c, 0xb870, 0x0508, 0xa87b, 0x0000, 0xa883,
-	0x0000, 0xa897, 0x4000, 0x0080, 0x080c, 0xb870, 0x01b8, 0x6014,
-	0x2048, 0x080c, 0x5149, 0x1d70, 0xa87b, 0x0030, 0xa883, 0x0000,
-	0xa897, 0x4005, 0xa89b, 0x0004, 0x0126, 0x2091, 0x8000, 0xa867,
-	0x0139, 0x080c, 0x69b5, 0x012e, 0x080c, 0x9be6, 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, 0xb870, 0x0904, 0xbec4, 0x0096, 0x6314, 0x2348,
-	0xa87a, 0xa982, 0x929e, 0x4000, 0x1580, 0x6310, 0x00c6, 0x2358,
-	0x2009, 0x0000, 0xa868, 0xd0f4, 0x1140, 0x080c, 0x6582, 0x1108,
-	0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0xaa96, 0xa99a, 0x20a9,
-	0x0004, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0031, 0x20a0, 0xb8b4,
-	0x20e0, 0xb8b8, 0x9080, 0x0006, 0x2098, 0x080c, 0x0fac, 0x20a9,
-	0x0004, 0xa85c, 0x9080, 0x0035, 0x20a0, 0xb8b8, 0x9080, 0x000a,
-	0x2098, 0x080c, 0x0fac, 0x00ce, 0x0090, 0xaa96, 0x3918, 0x9398,
-	0x0007, 0x231c, 0x6004, 0x9086, 0x0016, 0x0110, 0xa89b, 0x0004,
-	0xaba2, 0x6310, 0x2358, 0xb804, 0x9084, 0x00ff, 0xa89e, 0x080c,
-	0x69a9, 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, 0x2459, 0x2118, 0x831f, 0x939c,
-	0xff00, 0x7838, 0x9084, 0x00ff, 0x931d, 0x7c3c, 0x2011, 0x8018,
-	0x080c, 0x48fa, 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, 0xb85e, 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, 0xaed1,
-	0x0005, 0x0036, 0x2019, 0x0001, 0x0010, 0x0036, 0x901e, 0x0499,
-	0x01e0, 0x080c, 0xb870, 0x01c8, 0x080c, 0xba5f, 0x6037, 0x4000,
-	0x6014, 0x6017, 0x0000, 0x0096, 0x2048, 0xa87c, 0x080c, 0xba85,
-	0x1118, 0x080c, 0xa59c, 0x0040, 0xa867, 0x0103, 0xa877, 0x0000,
-	0x83ff, 0x1129, 0x080c, 0x69b5, 0x009e, 0x003e, 0x0005, 0xa880,
-	0xd0b4, 0x0128, 0xa87b, 0x0006, 0xc0ec, 0xa882, 0x0048, 0xd0bc,
-	0x0118, 0xa87b, 0x0002, 0x0020, 0xa87b, 0x0005, 0x080c, 0xbb79,
-	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,
-	0x4a97, 0x004e, 0x003e, 0x0005, 0x0c51, 0x1d81, 0x0005, 0x2001,
-	0x195e, 0x2004, 0x601a, 0x0005, 0x2001, 0x1960, 0x2004, 0x604a,
-	0x0005, 0x080c, 0x9be6, 0x0804, 0x894f, 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,
-	0x0d65, 0x001b, 0x006e, 0x00be, 0x0005, 0xbffd, 0xc6dc, 0xc82b,
-	0xbffd, 0xbffd, 0xbffd, 0xbffd, 0xbffd, 0xc034, 0xc8af, 0xbffd,
-	0xbffd, 0xbffd, 0xbffd, 0xbffd, 0xbffd, 0x080c, 0x0d65, 0x0066,
-	0x6000, 0x90b2, 0x0016, 0x1a0c, 0x0d65, 0x0013, 0x006e, 0x0005,
-	0xc018, 0xcdd0, 0xc018, 0xc018, 0xc018, 0xc018, 0xc018, 0xc018,
-	0xcd7f, 0xce22, 0xc018, 0xd446, 0xd47a, 0xd446, 0xd47a, 0xc018,
-	0x080c, 0x0d65, 0x6000, 0x9082, 0x0016, 0x1a0c, 0x0d65, 0x6000,
-	0x000a, 0x0005, 0xc032, 0xca8c, 0xcb57, 0xcb7a, 0xcbf6, 0xc032,
-	0xccf1, 0xcc7e, 0xc8b9, 0xcd57, 0xcd6c, 0xc032, 0xc032, 0xc032,
-	0xc032, 0xc032, 0x080c, 0x0d65, 0x91b2, 0x0053, 0x1a0c, 0x0d65,
-	0x2100, 0x91b2, 0x0040, 0x1a04, 0xc47f, 0x0002, 0xc07e, 0xc270,
-	0xc07e, 0xc07e, 0xc07e, 0xc279, 0xc07e, 0xc07e, 0xc07e, 0xc07e,
-	0xc07e, 0xc07e, 0xc07e, 0xc07e, 0xc07e, 0xc07e, 0xc07e, 0xc07e,
-	0xc07e, 0xc07e, 0xc07e, 0xc07e, 0xc07e, 0xc080, 0xc0e7, 0xc0f6,
-	0xc15a, 0xc185, 0xc1fd, 0xc25b, 0xc07e, 0xc07e, 0xc27c, 0xc07e,
-	0xc07e, 0xc291, 0xc29e, 0xc07e, 0xc07e, 0xc07e, 0xc07e, 0xc07e,
-	0xc321, 0xc07e, 0xc07e, 0xc335, 0xc07e, 0xc07e, 0xc2f0, 0xc07e,
-	0xc07e, 0xc07e, 0xc34d, 0xc07e, 0xc07e, 0xc07e, 0xc3ca, 0xc07e,
-	0xc07e, 0xc07e, 0xc07e, 0xc07e, 0xc07e, 0xc447, 0x080c, 0x0d65,
-	0x080c, 0x6648, 0x1150, 0x2001, 0x1836, 0x2004, 0xd0cc, 0x1128,
-	0x9084, 0x0009, 0x9086, 0x0008, 0x1140, 0x6007, 0x0009, 0x602f,
-	0x0009, 0x6017, 0x0000, 0x0804, 0xc269, 0x080c, 0x6631, 0x00e6,
-	0x00c6, 0x0036, 0x0026, 0x0016, 0x6210, 0x2258, 0xbaa0, 0x0026,
-	0x2019, 0x0029, 0x080c, 0x98c7, 0x080c, 0x8658, 0x0076, 0x903e,
-	0x080c, 0x853d, 0x2c08, 0x080c, 0xd011, 0x007e, 0x001e, 0x080c,
-	0x98e3, 0x001e, 0x002e, 0x003e, 0x00ce, 0x00ee, 0x6610, 0x2658,
-	0x080c, 0x629e, 0xbe04, 0x9684, 0x00ff, 0x9082, 0x0006, 0x1268,
-	0x0016, 0x0026, 0x6210, 0x00b6, 0x2258, 0xbaa0, 0x00be, 0x2c08,
-	0x080c, 0xd5f2, 0x002e, 0x001e, 0x1178, 0x080c, 0xcf40, 0x1904,
-	0xc152, 0x080c, 0xcedc, 0x1120, 0x6007, 0x0008, 0x0804, 0xc269,
-	0x6007, 0x0009, 0x0804, 0xc269, 0x080c, 0xd147, 0x0128, 0x080c,
-	0xcf40, 0x0d78, 0x0804, 0xc152, 0x6017, 0x1900, 0x0c88, 0x080c,
-	0x3164, 0x1904, 0xc47c, 0x6106, 0x080c, 0xce8d, 0x6007, 0x0006,
-	0x0804, 0xc269, 0x6007, 0x0007, 0x0804, 0xc269, 0x080c, 0xd4b6,
-	0x1904, 0xc47c, 0x080c, 0x3164, 0x1904, 0xc47c, 0x00d6, 0x6610,
-	0x2658, 0xbe04, 0x9684, 0x00ff, 0x9082, 0x0006, 0x1220, 0x2001,
-	0x0001, 0x080c, 0x61cc, 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, 0xcfa7, 0x1190, 0x9686, 0x0006, 0x1140, 0x0026, 0x6210,
-	0x2258, 0xbaa0, 0x900e, 0x080c, 0x307d, 0x002e, 0x080c, 0x632a,
-	0x6007, 0x000a, 0x00de, 0x0804, 0xc269, 0x6007, 0x000b, 0x00de,
-	0x0804, 0xc269, 0x080c, 0x302e, 0x080c, 0xbfa4, 0x6007, 0x0001,
-	0x0804, 0xc269, 0x080c, 0xd4b6, 0x1904, 0xc47c, 0x080c, 0x3164,
-	0x1904, 0xc47c, 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, 0x307d, 0x002e, 0x6007, 0x000c, 0x2001,
-	0x0001, 0x080c, 0xd5d2, 0x0804, 0xc269, 0x080c, 0x6648, 0x1140,
-	0x2001, 0x1836, 0x2004, 0x9084, 0x0009, 0x9086, 0x0008, 0x1110,
-	0x0804, 0xc08d, 0x080c, 0x6631, 0x6610, 0x2658, 0xbe04, 0x9684,
-	0x00ff, 0x9082, 0x0006, 0x06c0, 0x1138, 0x0026, 0x2001, 0x0006,
-	0x080c, 0x620c, 0x002e, 0x0050, 0x96b4, 0xff00, 0x8637, 0x9686,
-	0x0004, 0x0120, 0x9686, 0x0006, 0x1904, 0xc152, 0x080c, 0xcfb4,
-	0x1120, 0x6007, 0x000e, 0x0804, 0xc269, 0x0046, 0x6410, 0x2458,
-	0xbca0, 0x0046, 0x080c, 0x302e, 0x080c, 0xbfa4, 0x004e, 0x0016,
-	0x9006, 0x2009, 0x185c, 0x210c, 0x0048, 0x2009, 0x0029, 0x080c,
-	0xd2bc, 0x6010, 0x2058, 0xb800, 0xc0e5, 0xb802, 0x001e, 0x004e,
-	0x6007, 0x0001, 0x0804, 0xc269, 0x2001, 0x0001, 0x080c, 0x61cc,
-	0x0156, 0x0016, 0x0026, 0x0036, 0x20a9, 0x0004, 0x2019, 0x1805,
-	0x2011, 0x0270, 0x080c, 0xabda, 0x003e, 0x002e, 0x001e, 0x015e,
-	0x9005, 0x0168, 0x96b4, 0xff00, 0x8637, 0x9682, 0x0004, 0x0a04,
-	0xc152, 0x9682, 0x0007, 0x0a04, 0xc1ae, 0x0804, 0xc152, 0x6017,
-	0x1900, 0x6007, 0x0009, 0x0804, 0xc269, 0x080c, 0x6648, 0x1140,
-	0x2001, 0x1836, 0x2004, 0x9084, 0x0009, 0x9086, 0x0008, 0x1110,
-	0x0804, 0xc08d, 0x080c, 0x6631, 0x6610, 0x2658, 0xbe04, 0x9684,
-	0x00ff, 0x0006, 0x9086, 0x0001, 0x000e, 0x0170, 0x9082, 0x0006,
-	0x0690, 0x0150, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0004, 0x0120,
-	0x9686, 0x0006, 0x1904, 0xc152, 0x080c, 0xcfe2, 0x1130, 0x080c,
-	0xcedc, 0x1118, 0x6007, 0x0010, 0x04e0, 0x0046, 0x6410, 0x2458,
-	0xbca0, 0x0046, 0x080c, 0x302e, 0x080c, 0xbfa4, 0x004e, 0x0016,
-	0x9006, 0x2009, 0x185c, 0x210c, 0x0048, 0x2009, 0x0029, 0x080c,
-	0xd2bc, 0x6010, 0x2058, 0xb800, 0xc0e5, 0xb802, 0x001e, 0x004e,
-	0x6007, 0x0001, 0x00f0, 0x080c, 0xd147, 0x0140, 0x96b4, 0xff00,
-	0x8637, 0x9686, 0x0006, 0x0980, 0x0804, 0xc152, 0x6017, 0x1900,
-	0x6007, 0x0009, 0x0070, 0x080c, 0x3164, 0x1904, 0xc47c, 0x080c,
-	0xd4b6, 0x1904, 0xc47c, 0x080c, 0xc61c, 0x1904, 0xc152, 0x6007,
-	0x0012, 0x6003, 0x0001, 0x080c, 0x84ee, 0x080c, 0x894f, 0x0005,
-	0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x84ee, 0x080c, 0x894f,
-	0x0cb0, 0x6007, 0x0005, 0x0c68, 0x080c, 0xd4b6, 0x1904, 0xc47c,
-	0x080c, 0x3164, 0x1904, 0xc47c, 0x080c, 0xc61c, 0x1904, 0xc152,
-	0x6007, 0x0020, 0x6003, 0x0001, 0x080c, 0x84ee, 0x080c, 0x894f,
-	0x0005, 0x080c, 0x3164, 0x1904, 0xc47c, 0x6007, 0x0023, 0x6003,
-	0x0001, 0x080c, 0x84ee, 0x080c, 0x894f, 0x0005, 0x080c, 0xd4b6,
-	0x1904, 0xc47c, 0x080c, 0x3164, 0x1904, 0xc47c, 0x080c, 0xc61c,
-	0x1904, 0xc152, 0x0016, 0x0026, 0x00e6, 0x2071, 0x0260, 0x7244,
-	0x9286, 0xffff, 0x0180, 0x2c08, 0x080c, 0xb85e, 0x01b0, 0x2260,
-	0x7240, 0x6008, 0x9206, 0x1188, 0x6010, 0x9190, 0x0004, 0x2214,
-	0x9206, 0x01b8, 0x0050, 0x7240, 0x2c08, 0x9006, 0x080c, 0xd28e,
-	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, 0x9be6, 0x2160, 0x6007, 0x0025, 0x6003, 0x0001,
-	0x080c, 0x84ee, 0x080c, 0x894f, 0x00ee, 0x002e, 0x001e, 0x0005,
-	0x2001, 0x0001, 0x080c, 0x61cc, 0x0156, 0x0016, 0x0026, 0x0036,
-	0x20a9, 0x0004, 0x2019, 0x1805, 0x2011, 0x0276, 0x080c, 0xabda,
-	0x003e, 0x002e, 0x001e, 0x015e, 0x0120, 0x6007, 0x0031, 0x0804,
-	0xc269, 0x080c, 0xa83f, 0x080c, 0x70ba, 0x1190, 0x0006, 0x0026,
-	0x0036, 0x080c, 0x70d4, 0x1138, 0x080c, 0x73b9, 0x080c, 0x5cf7,
-	0x080c, 0x6feb, 0x0010, 0x080c, 0x708e, 0x003e, 0x002e, 0x000e,
-	0x0005, 0x080c, 0x3164, 0x1904, 0xc47c, 0x080c, 0xc61c, 0x1904,
-	0xc152, 0x6106, 0x080c, 0xc638, 0x1120, 0x6007, 0x002b, 0x0804,
-	0xc269, 0x6007, 0x002c, 0x0804, 0xc269, 0x080c, 0xd4b6, 0x1904,
-	0xc47c, 0x080c, 0x3164, 0x1904, 0xc47c, 0x080c, 0xc61c, 0x1904,
-	0xc152, 0x6106, 0x080c, 0xc63d, 0x1120, 0x6007, 0x002e, 0x0804,
-	0xc269, 0x6007, 0x002f, 0x0804, 0xc269, 0x080c, 0x3164, 0x1904,
-	0xc47c, 0x00e6, 0x00d6, 0x00c6, 0x6010, 0x2058, 0xb904, 0x9184,
-	0x00ff, 0x9086, 0x0006, 0x0158, 0x9184, 0xff00, 0x8007, 0x9086,
-	0x0006, 0x0128, 0x00ce, 0x00de, 0x00ee, 0x0804, 0xc270, 0x080c,
-	0x53ac, 0xd0e4, 0x0904, 0xc3c7, 0x2071, 0x026c, 0x7010, 0x603a,
-	0x7014, 0x603e, 0x7108, 0x720c, 0x080c, 0x6686, 0x0140, 0x6010,
-	0x2058, 0xb810, 0x9106, 0x1118, 0xb814, 0x9206, 0x0510, 0x080c,
-	0x6682, 0x15b8, 0x2069, 0x1800, 0x687c, 0x9206, 0x1590, 0x6878,
-	0x9106, 0x1578, 0x7210, 0x080c, 0xb85e, 0x0590, 0x080c, 0xc507,
-	0x0578, 0x080c, 0xd338, 0x0560, 0x622e, 0x6007, 0x0036, 0x6003,
-	0x0001, 0x2009, 0x8020, 0x080c, 0x84e7, 0x00ce, 0x00de, 0x00ee,
-	0x0005, 0x7214, 0x9286, 0xffff, 0x0150, 0x080c, 0xb85e, 0x01c0,
-	0x9280, 0x0002, 0x2004, 0x7110, 0x9106, 0x1190, 0x08e0, 0x7210,
-	0x2c08, 0x9085, 0x0001, 0x080c, 0xd28e, 0x2c10, 0x2160, 0x0140,
-	0x0890, 0x6007, 0x0037, 0x602f, 0x0009, 0x6017, 0x1500, 0x08b8,
-	0x6007, 0x0037, 0x602f, 0x0003, 0x6017, 0x1700, 0x0880, 0x6007,
-	0x0012, 0x0868, 0x080c, 0x3164, 0x1904, 0xc47c, 0x6010, 0x2058,
-	0xb804, 0x9084, 0xff00, 0x8007, 0x9086, 0x0006, 0x1904, 0xc270,
-	0x00e6, 0x00d6, 0x00c6, 0x080c, 0x53ac, 0xd0e4, 0x0904, 0xc43f,
-	0x2069, 0x1800, 0x2071, 0x026c, 0x7008, 0x603a, 0x720c, 0x623e,
-	0x9286, 0xffff, 0x1150, 0x7208, 0x00c6, 0x2c08, 0x9085, 0x0001,
-	0x080c, 0xd28e, 0x2c10, 0x00ce, 0x05e8, 0x080c, 0xb85e, 0x05d0,
-	0x7108, 0x9280, 0x0002, 0x2004, 0x9106, 0x15a0, 0x00c6, 0x0026,
-	0x2260, 0x080c, 0xb451, 0x002e, 0x00ce, 0x7118, 0x918c, 0xff00,
-	0x810f, 0x9186, 0x0001, 0x0178, 0x9186, 0x0005, 0x0118, 0x9186,
-	0x0007, 0x1198, 0x9280, 0x0005, 0x2004, 0x9005, 0x0170, 0x080c,
-	0xc507, 0x0904, 0xc3c0, 0x0056, 0x7510, 0x7614, 0x080c, 0xd351,
-	0x005e, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x6007, 0x003b, 0x602f,
-	0x0009, 0x6017, 0x2a00, 0x6003, 0x0001, 0x2009, 0x8020, 0x080c,
-	0x84e7, 0x0c78, 0x6007, 0x003b, 0x602f, 0x0003, 0x6017, 0x0300,
-	0x6003, 0x0001, 0x2009, 0x8020, 0x080c, 0x84e7, 0x0c10, 0x6007,
-	0x003b, 0x602f, 0x000b, 0x6017, 0x0000, 0x0804, 0xc397, 0x00e6,
-	0x0026, 0x080c, 0x6648, 0x0550, 0x080c, 0x6631, 0x080c, 0xd528,
-	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, 0x6686, 0x0120, 0x2011, 0x19e1, 0x2013, 0x07d0, 0xd0ac,
-	0x1128, 0x080c, 0x2e09, 0x0010, 0x080c, 0xd55a, 0x002e, 0x00ee,
-	0x080c, 0x9be6, 0x0804, 0xc26f, 0x080c, 0x9be6, 0x0005, 0x2600,
-	0x0002, 0xc493, 0xc493, 0xc493, 0xc493, 0xc493, 0xc495, 0xc493,
-	0xc493, 0xc493, 0xc493, 0xc4b2, 0xc493, 0xc493, 0xc493, 0xc4c4,
-	0xc4d1, 0xc502, 0xc493, 0x080c, 0x0d65, 0x080c, 0xd4b6, 0x1d20,
-	0x080c, 0x3164, 0x1d08, 0x080c, 0xc61c, 0x1148, 0x7038, 0x6016,
-	0x6007, 0x0045, 0x6003, 0x0001, 0x080c, 0x84ee, 0x0005, 0x080c,
-	0x302e, 0x080c, 0xbfa4, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c,
-	0x84ee, 0x0005, 0x080c, 0xd4b6, 0x1938, 0x080c, 0x3164, 0x1920,
-	0x080c, 0xc61c, 0x1d60, 0x703c, 0x6016, 0x6007, 0x004a, 0x6003,
-	0x0001, 0x080c, 0x84ee, 0x0005, 0x080c, 0xc524, 0x0904, 0xc47c,
-	0x6007, 0x004e, 0x6003, 0x0001, 0x080c, 0x84ee, 0x080c, 0x894f,
-	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, 0xabee, 0x009e,
-	0x0110, 0x6017, 0x0001, 0x6003, 0x0001, 0x080c, 0x84ee, 0x080c,
-	0x894f, 0x0005, 0x6007, 0x0050, 0x703c, 0x6016, 0x0ca0, 0x0016,
-	0x00e6, 0x2071, 0x0260, 0x00b6, 0x00c6, 0x2260, 0x6010, 0x2058,
-	0xb8c4, 0xd084, 0x0150, 0x7128, 0x6050, 0x9106, 0x1120, 0x712c,
-	0x604c, 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, 0x1048, 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, 0x1048, 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, 0x0fe1,
-	0x9006, 0x012e, 0x01de, 0x01ce, 0x00ee, 0x008e, 0x009e, 0x001e,
-	0x0005, 0x0006, 0x0016, 0x0026, 0x0036, 0x00c6, 0x918c, 0xffff,
-	0x11a8, 0x080c, 0x2054, 0x2099, 0x026c, 0x2001, 0x0014, 0x3518,
-	0x9312, 0x1218, 0x23a8, 0x4003, 0x00f8, 0x20a8, 0x4003, 0x22a8,
-	0x8108, 0x080c, 0x2054, 0x2099, 0x0260, 0x0ca8, 0x080c, 0x2054,
-	0x2061, 0x1978, 0x6004, 0x2098, 0x6008, 0x3518, 0x9312, 0x1218,
-	0x23a8, 0x4003, 0x0048, 0x20a8, 0x4003, 0x22a8, 0x8108, 0x080c,
-	0x2054, 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, 0x206c, 0x20a1, 0x024c,
-	0x2001, 0x0014, 0x3518, 0x9312, 0x1218, 0x23a8, 0x4003, 0x0418,
-	0x20a8, 0x4003, 0x82ff, 0x01f8, 0x22a8, 0x8108, 0x080c, 0x206c,
-	0x20a1, 0x0240, 0x0c98, 0x080c, 0x206c, 0x2061, 0x197b, 0x6004,
-	0x20a0, 0x6008, 0x3518, 0x9312, 0x1218, 0x23a8, 0x4003, 0x0058,
-	0x20a8, 0x4003, 0x82ff, 0x0138, 0x22a8, 0x8108, 0x080c, 0x206c,
-	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, 0xc6b2, 0x00de, 0x0005, 0x00d6, 0x080c, 0xc6bf,
-	0x1520, 0x680c, 0x908c, 0xff00, 0x6820, 0x9084, 0x00ff, 0x9115,
-	0x6216, 0x6824, 0x602e, 0xd1e4, 0x0130, 0x9006, 0x080c, 0xd5d2,
-	0x2009, 0x0001, 0x0078, 0xd1ec, 0x0180, 0x6920, 0x918c, 0x00ff,
-	0x6824, 0x080c, 0x2459, 0x1148, 0x2001, 0x0001, 0x080c, 0xd5d2,
-	0x2110, 0x900e, 0x080c, 0x307d, 0x0018, 0x9085, 0x0001, 0x0008,
-	0x9006, 0x00de, 0x0005, 0x00b6, 0x00c6, 0x080c, 0x9c55, 0x0598,
-	0x0016, 0x0026, 0x00c6, 0x2011, 0x0263, 0x2204, 0x8211, 0x220c,
-	0x080c, 0x2459, 0x1568, 0x080c, 0x622f, 0x1550, 0xbe12, 0xbd16,
-	0x00ce, 0x002e, 0x001e, 0x2b00, 0x6012, 0x080c, 0xd4b6, 0x11c8,
-	0x080c, 0x3164, 0x11b0, 0x080c, 0xc61c, 0x0500, 0x2001, 0x0007,
-	0x080c, 0x61e0, 0x2001, 0x0007, 0x080c, 0x620c, 0x6017, 0x0000,
-	0x6023, 0x0001, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x84ee,
-	0x0010, 0x080c, 0x9be6, 0x9085, 0x0001, 0x00ce, 0x00be, 0x0005,
-	0x080c, 0x9be6, 0x00ce, 0x002e, 0x001e, 0x0ca8, 0x080c, 0x9be6,
-	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,
-	0x0d65, 0x91b6, 0x0013, 0x1130, 0x2008, 0x91b2, 0x0040, 0x1a04,
-	0xc7ff, 0x0092, 0x91b6, 0x0027, 0x0120, 0x91b6, 0x0014, 0x190c,
-	0x0d65, 0x2001, 0x0007, 0x080c, 0x620c, 0x080c, 0x8891, 0x080c,
-	0x9c20, 0x080c, 0x894f, 0x0005, 0xc73c, 0xc73e, 0xc73c, 0xc73c,
-	0xc73c, 0xc73e, 0xc74b, 0xc7fc, 0xc79b, 0xc7fc, 0xc7ad, 0xc7fc,
-	0xc74b, 0xc7fc, 0xc7f4, 0xc7fc, 0xc7f4, 0xc7fc, 0xc7fc, 0xc73c,
-	0xc73c, 0xc73c, 0xc73c, 0xc73c, 0xc73c, 0xc73c, 0xc73c, 0xc73c,
-	0xc73c, 0xc73c, 0xc73e, 0xc73c, 0xc7fc, 0xc73c, 0xc73c, 0xc7fc,
-	0xc73c, 0xc7f9, 0xc7fc, 0xc73c, 0xc73c, 0xc73c, 0xc73c, 0xc7fc,
-	0xc7fc, 0xc73c, 0xc7fc, 0xc7fc, 0xc73c, 0xc746, 0xc73c, 0xc73c,
-	0xc73c, 0xc73c, 0xc7f8, 0xc7fc, 0xc73c, 0xc73c, 0xc7fc, 0xc7fc,
-	0xc73c, 0xc73c, 0xc73c, 0xc73c, 0x080c, 0x0d65, 0x080c, 0xbfa7,
-	0x6003, 0x0002, 0x080c, 0x894f, 0x0804, 0xc7fe, 0x9006, 0x080c,
-	0x61cc, 0x0804, 0xc7fc, 0x080c, 0x6682, 0x1904, 0xc7fc, 0x9006,
-	0x080c, 0x61cc, 0x6010, 0x2058, 0xb810, 0x9086, 0x00ff, 0x1140,
-	0x00f6, 0x2079, 0x1800, 0x78a4, 0x8000, 0x78a6, 0x00fe, 0x0428,
-	0x6010, 0x2058, 0xb884, 0x9005, 0x1178, 0x080c, 0xbf8f, 0x1904,
-	0xc7fc, 0x0036, 0x0046, 0xbba0, 0x2021, 0x0007, 0x080c, 0x4a97,
-	0x004e, 0x003e, 0x0804, 0xc7fc, 0x080c, 0x3195, 0x1904, 0xc7fc,
-	0x2001, 0x1800, 0x2004, 0x9086, 0x0002, 0x1138, 0x00f6, 0x2079,
-	0x1800, 0x78a4, 0x8000, 0x78a6, 0x00fe, 0x2001, 0x0002, 0x080c,
-	0x61e0, 0x6023, 0x0001, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c,
-	0x84ee, 0x080c, 0x894f, 0x6110, 0x2158, 0x2009, 0x0001, 0x080c,
-	0x817a, 0x0804, 0xc7fe, 0x6610, 0x2658, 0xbe04, 0x96b4, 0xff00,
-	0x8637, 0x9686, 0x0006, 0x0904, 0xc7fc, 0x9686, 0x0004, 0x0904,
-	0xc7fc, 0x2001, 0x0004, 0x0804, 0xc7fa, 0x2001, 0x1800, 0x2004,
-	0x9086, 0x0003, 0x1158, 0x0036, 0x0046, 0x6010, 0x2058, 0xbba0,
-	0x2021, 0x0006, 0x080c, 0x4a97, 0x004e, 0x003e, 0x2001, 0x0006,
-	0x080c, 0xc818, 0x6610, 0x2658, 0xbe04, 0x0066, 0x96b4, 0xff00,
-	0x8637, 0x9686, 0x0006, 0x006e, 0x0168, 0x2001, 0x0006, 0x080c,
-	0x620c, 0x9284, 0x00ff, 0x908e, 0x0007, 0x1120, 0x2001, 0x0006,
-	0x080c, 0x61e0, 0x080c, 0x6682, 0x11f8, 0x2001, 0x1836, 0x2004,
-	0xd0a4, 0x01d0, 0xbe04, 0x96b4, 0x00ff, 0x9686, 0x0006, 0x01a0,
-	0x00f6, 0x2079, 0x1800, 0x78a4, 0x8000, 0x78a6, 0x00fe, 0x0804,
-	0xc785, 0x2001, 0x0004, 0x0030, 0x2001, 0x0006, 0x0409, 0x0020,
-	0x0018, 0x0010, 0x080c, 0x620c, 0x080c, 0x9be6, 0x0005, 0x2600,
-	0x0002, 0xc813, 0xc813, 0xc813, 0xc813, 0xc813, 0xc815, 0xc813,
-	0xc813, 0xc813, 0xc813, 0xc815, 0xc813, 0xc813, 0xc813, 0xc815,
-	0xc815, 0xc815, 0xc815, 0x080c, 0x0d65, 0x080c, 0x9be6, 0x0005,
-	0x0016, 0x00b6, 0x00d6, 0x6110, 0x2158, 0xb900, 0xd184, 0x0138,
-	0x080c, 0x61e0, 0x9006, 0x080c, 0x61cc, 0x080c, 0x305d, 0x00de,
-	0x00be, 0x001e, 0x0005, 0x6610, 0x2658, 0xb804, 0x9084, 0xff00,
-	0x8007, 0x90b2, 0x000c, 0x1a0c, 0x0d65, 0x91b6, 0x0015, 0x1110,
-	0x003b, 0x0028, 0x91b6, 0x0016, 0x190c, 0x0d65, 0x006b, 0x0005,
-	0xa67d, 0xa67d, 0xa67d, 0xa67d, 0xc8ad, 0xa67d, 0xc897, 0xc858,
-	0xa67d, 0xa67d, 0xa67d, 0xa67d, 0xa67d, 0xa67d, 0xa67d, 0xa67d,
-	0xc8ad, 0xa67d, 0xc897, 0xc89e, 0xa67d, 0xa67d, 0xa67d, 0xa67d,
-	0x00f6, 0x080c, 0x6682, 0x11d8, 0x080c, 0xbf8f, 0x11c0, 0x6010,
-	0x905d, 0x01a8, 0xb884, 0x9005, 0x0190, 0x9006, 0x080c, 0x61cc,
-	0x2001, 0x0002, 0x080c, 0x61e0, 0x6023, 0x0001, 0x6003, 0x0001,
-	0x6007, 0x0002, 0x080c, 0x84ee, 0x080c, 0x894f, 0x00f0, 0x2011,
-	0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x2459, 0x11b0, 0x080c,
-	0x628f, 0x0118, 0x080c, 0x9be6, 0x0080, 0xb810, 0x0006, 0xb814,
-	0x0006, 0xb884, 0x0006, 0x080c, 0x5d11, 0x000e, 0xb886, 0x000e,
-	0xb816, 0x000e, 0xb812, 0x080c, 0x9be6, 0x00fe, 0x0005, 0x6604,
-	0x96b6, 0x001e, 0x1110, 0x080c, 0x9be6, 0x0005, 0x080c, 0xaa63,
-	0x1148, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x84ee, 0x080c,
-	0x894f, 0x0010, 0x080c, 0x9be6, 0x0005, 0x0804, 0x9be6, 0x6004,
-	0x908a, 0x0053, 0x1a0c, 0x0d65, 0x080c, 0x8891, 0x080c, 0x9c20,
-	0x0005, 0x9182, 0x0040, 0x0002, 0xc8d0, 0xc8d0, 0xc8d0, 0xc8d0,
-	0xc8d2, 0xc8d0, 0xc8d0, 0xc8d0, 0xc8d0, 0xc8d0, 0xc8d0, 0xc8d0,
-	0xc8d0, 0xc8d0, 0xc8d0, 0xc8d0, 0xc8d0, 0xc8d0, 0xc8d0, 0xc8d0,
-	0x080c, 0x0d65, 0x0096, 0x00b6, 0x00d6, 0x00e6, 0x00f6, 0x0046,
-	0x0026, 0x6210, 0x2258, 0xb8ac, 0x9005, 0x11b0, 0x6007, 0x0044,
-	0x2071, 0x0260, 0x7444, 0x94a4, 0xff00, 0x0904, 0xc939, 0x080c,
-	0xd5c6, 0x1170, 0x9486, 0x2000, 0x1158, 0x2009, 0x0001, 0x2011,
-	0x0200, 0x080c, 0x8401, 0x0020, 0x9026, 0x080c, 0xd4fb, 0x0c30,
-	0x080c, 0x102f, 0x090c, 0x0d65, 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, 0x69b5, 0x001e,
-	0x080c, 0xd5c6, 0x1904, 0xc999, 0x9486, 0x2000, 0x1130, 0x2019,
-	0x0017, 0x080c, 0xd234, 0x0804, 0xc999, 0x9486, 0x0200, 0x1120,
-	0x080c, 0xd1c4, 0x0804, 0xc999, 0x9486, 0x0400, 0x0120, 0x9486,
-	0x1000, 0x1904, 0xc999, 0x2019, 0x0002, 0x080c, 0xd1e3, 0x0804,
-	0xc999, 0x2069, 0x1a46, 0x6a00, 0xd284, 0x0904, 0xca03, 0x9284,
-	0x0300, 0x1904, 0xc9fc, 0x6804, 0x9005, 0x0904, 0xc9e4, 0x2d78,
-	0x6003, 0x0007, 0x080c, 0x1048, 0x0904, 0xc9a5, 0x7800, 0xd08c,
-	0x1118, 0x7804, 0x8001, 0x7806, 0x6017, 0x0000, 0x2001, 0x180f,
-	0x2004, 0xd084, 0x1904, 0xca07, 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, 0xc9a1, 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,
-	0x69b8, 0x002e, 0x004e, 0x00fe, 0x00ee, 0x00de, 0x00be, 0x009e,
-	0x0005, 0x0000, 0x0080, 0x0040, 0x0000, 0x2001, 0x1810, 0x2004,
-	0xd084, 0x0120, 0x080c, 0x102f, 0x1904, 0xc94e, 0x6017, 0xf100,
-	0x6003, 0x0001, 0x6007, 0x0041, 0x2009, 0xa022, 0x080c, 0x84e7,
-	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, 0x84e7, 0x0828, 0x6868, 0x602e, 0x686c, 0x6032,
-	0x6017, 0xf200, 0x6003, 0x0001, 0x6007, 0x0041, 0x2009, 0xa022,
-	0x080c, 0x84e7, 0x0804, 0xc999, 0x2001, 0x180e, 0x2004, 0xd0ec,
-	0x0120, 0x2011, 0x8049, 0x080c, 0x48fa, 0x6017, 0xf300, 0x0010,
-	0x6017, 0xf100, 0x6003, 0x0001, 0x6007, 0x0041, 0x2009, 0xa022,
-	0x080c, 0x84e7, 0x0804, 0xc999, 0x6017, 0xf500, 0x0c98, 0x6017,
-	0xf600, 0x0804, 0xc9b9, 0x6017, 0xf200, 0x0804, 0xc9b9, 0xa867,
-	0x0146, 0xa86b, 0x0000, 0x6008, 0xa886, 0x2c00, 0xa87a, 0x7044,
-	0x9084, 0x0003, 0x9080, 0xc9a1, 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, 0x0d65, 0x8210,
-	0x821c, 0x2001, 0x026c, 0x2098, 0xa860, 0x20e8, 0xa85c, 0x9080,
-	0x0029, 0x20a0, 0x2011, 0xca83, 0x2041, 0x0001, 0x223d, 0x9784,
-	0x00ff, 0x9322, 0x1208, 0x2300, 0x20a8, 0x4003, 0x931a, 0x0530,
-	0x8210, 0xd7fc, 0x1130, 0x8d68, 0x2d0a, 0x2001, 0x0260, 0x2098,
-	0x0c68, 0x2950, 0x080c, 0x1048, 0x0170, 0x2900, 0xb002, 0xa867,
-	0x0147, 0xa86b, 0x0000, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x001b,
-	0x20a0, 0x8840, 0x08d8, 0x2548, 0xa800, 0x902d, 0x0118, 0x080c,
-	0x1061, 0x0cc8, 0x080c, 0x1061, 0x0804, 0xc9a5, 0x2548, 0x8847,
-	0x9885, 0x0046, 0xa866, 0x2009, 0x0205, 0x200b, 0x0000, 0x080c,
-	0xd267, 0x0804, 0xc999, 0x8010, 0x0004, 0x801a, 0x0006, 0x8018,
-	0x0008, 0x8016, 0x000a, 0x8014, 0x9186, 0x0013, 0x1160, 0x6004,
-	0x908a, 0x0057, 0x1a0c, 0x0d65, 0x9082, 0x0040, 0x0a0c, 0x0d65,
-	0x2008, 0x0804, 0xcb0f, 0x9186, 0x0051, 0x0108, 0x0040, 0x080c,
-	0x9ab6, 0x01e8, 0x9086, 0x0002, 0x0904, 0xcb57, 0x00c0, 0x9186,
-	0x0027, 0x0180, 0x9186, 0x0048, 0x0128, 0x9186, 0x0014, 0x0150,
-	0x190c, 0x0d65, 0x080c, 0x9ab6, 0x0150, 0x9086, 0x0004, 0x0904,
-	0xcbf6, 0x0028, 0x6004, 0x9082, 0x0040, 0x2008, 0x001a, 0x080c,
-	0x9c9f, 0x0005, 0xcad6, 0xcad8, 0xcad8, 0xcaff, 0xcad6, 0xcad6,
-	0xcad6, 0xcad6, 0xcad6, 0xcad6, 0xcad6, 0xcad6, 0xcad6, 0xcad6,
-	0xcad6, 0xcad6, 0xcad6, 0xcad6, 0xcad6, 0xcad6, 0x080c, 0x0d65,
-	0x080c, 0x8891, 0x080c, 0x894f, 0x0036, 0x0096, 0x6014, 0x904d,
-	0x01d8, 0x080c, 0xb870, 0x01c0, 0x6003, 0x0002, 0x6010, 0x00b6,
-	0x2058, 0xb800, 0x00be, 0xd0bc, 0x1178, 0x2019, 0x0004, 0x080c,
-	0xd267, 0x6017, 0x0000, 0x6018, 0x9005, 0x1120, 0x2001, 0x195f,
-	0x2004, 0x601a, 0x6003, 0x0007, 0x009e, 0x003e, 0x0005, 0x0096,
-	0x080c, 0x8891, 0x080c, 0x894f, 0x080c, 0xb870, 0x0120, 0x6014,
-	0x2048, 0x080c, 0x1061, 0x080c, 0x9c20, 0x009e, 0x0005, 0x0002,
-	0xcb24, 0xcb39, 0xcb26, 0xcb4e, 0xcb24, 0xcb24, 0xcb24, 0xcb24,
-	0xcb24, 0xcb24, 0xcb24, 0xcb24, 0xcb24, 0xcb24, 0xcb24, 0xcb24,
-	0xcb24, 0xcb24, 0xcb24, 0xcb24, 0x080c, 0x0d65, 0x0096, 0x6014,
-	0x2048, 0xa87c, 0xd0b4, 0x0138, 0x6003, 0x0007, 0x2009, 0x0043,
-	0x080c, 0x9c82, 0x0010, 0x6003, 0x0004, 0x080c, 0x894f, 0x009e,
-	0x0005, 0x080c, 0xb870, 0x0138, 0x6114, 0x0096, 0x2148, 0xa97c,
-	0x009e, 0xd1ec, 0x1138, 0x080c, 0x83d6, 0x080c, 0x9be6, 0x080c,
-	0x894f, 0x0005, 0x080c, 0xd4bf, 0x0db0, 0x0cc8, 0x6003, 0x0001,
-	0x6007, 0x0041, 0x2009, 0xa022, 0x080c, 0x84e7, 0x0005, 0x9182,
-	0x0040, 0x0002, 0xcb6e, 0xcb70, 0xcb6e, 0xcb6e, 0xcb6e, 0xcb6e,
-	0xcb6e, 0xcb6e, 0xcb6e, 0xcb6e, 0xcb6e, 0xcb6e, 0xcb6e, 0xcb6e,
-	0xcb6e, 0xcb6e, 0xcb6e, 0xcb71, 0xcb6e, 0xcb6e, 0x080c, 0x0d65,
-	0x0005, 0x00d6, 0x080c, 0x83d6, 0x00de, 0x080c, 0xd517, 0x080c,
-	0x9be6, 0x0005, 0x9182, 0x0040, 0x0002, 0xcb91, 0xcb91, 0xcb91,
-	0xcb91, 0xcb91, 0xcb91, 0xcb91, 0xcb91, 0xcb91, 0xcb93, 0xcbbe,
-	0xcb91, 0xcb91, 0xcb91, 0xcb91, 0xcbbe, 0xcb91, 0xcb91, 0xcb91,
-	0xcb91, 0x080c, 0x0d65, 0x6014, 0x0096, 0x2048, 0xa87c, 0xd0fc,
-	0x0168, 0x908c, 0x0003, 0x918e, 0x0002, 0x0180, 0x6144, 0xd1e4,
-	0x1168, 0x2009, 0x0041, 0x009e, 0x0804, 0xcc7e, 0x6003, 0x0007,
-	0x601b, 0x0000, 0x080c, 0x83d6, 0x009e, 0x0005, 0x6014, 0x2048,
-	0xa97c, 0xd1ec, 0x1130, 0x080c, 0x83d6, 0x080c, 0x9be6, 0x009e,
-	0x0005, 0x080c, 0xd4bf, 0x0db8, 0x009e, 0x0005, 0x2001, 0x180c,
-	0x200c, 0xc1d4, 0x2102, 0x0036, 0x080c, 0x88ec, 0x080c, 0x894f,
-	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, 0xd267, 0x6018,
-	0x9005, 0x1128, 0x2001, 0x195f, 0x2004, 0x8003, 0x601a, 0x6017,
-	0x0000, 0x6003, 0x0007, 0x009e, 0x003e, 0x0005, 0x9182, 0x0040,
-	0x0002, 0xcc0d, 0xcc0d, 0xcc0d, 0xcc0d, 0xcc0d, 0xcc0d, 0xcc0d,
-	0xcc0d, 0xcc0f, 0xcc0d, 0xcc0d, 0xcc0d, 0xcc0d, 0xcc0d, 0xcc0d,
-	0xcc0d, 0xcc0d, 0xcc0d, 0xcc0d, 0xcc5a, 0x080c, 0x0d65, 0x6014,
-	0x0096, 0x2048, 0xa834, 0xaa38, 0x6110, 0x00b6, 0x2158, 0xb900,
-	0x00be, 0xd1bc, 0x1190, 0x920d, 0x1518, 0xa87c, 0xd0fc, 0x0128,
-	0x2009, 0x0041, 0x009e, 0x0804, 0xcc7e, 0x6003, 0x0007, 0x601b,
-	0x0000, 0x080c, 0x83d6, 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, 0x83d8, 0x009e, 0x0005, 0x6003, 0x0002,
-	0x009e, 0x0005, 0x6024, 0xd0f4, 0x0128, 0x080c, 0x15af, 0x1904,
-	0xcc0f, 0x0005, 0x6014, 0x0096, 0x2048, 0xa834, 0xa938, 0x009e,
-	0x9105, 0x1120, 0x080c, 0x15af, 0x1904, 0xcc0f, 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,
-	0x0d65, 0x6024, 0xd0dc, 0x090c, 0x0d65, 0x0005, 0xcca2, 0xccae,
-	0xccba, 0xccc6, 0xcca2, 0xcca2, 0xcca2, 0xcca2, 0xcca9, 0xcca4,
-	0xcca4, 0xcca2, 0xcca2, 0xcca2, 0xcca2, 0xcca4, 0xcca2, 0xcca4,
-	0xcca2, 0xcca9, 0x080c, 0x0d65, 0x6024, 0xd0dc, 0x090c, 0x0d65,
-	0x0005, 0x6014, 0x9005, 0x190c, 0x0d65, 0x0005, 0x6003, 0x0001,
-	0x6106, 0x0126, 0x2091, 0x8000, 0x2009, 0xa022, 0x080c, 0x84c9,
-	0x012e, 0x0005, 0x6003, 0x0004, 0x6106, 0x0126, 0x2091, 0x8000,
-	0x2009, 0xa001, 0x080c, 0x84e7, 0x012e, 0x0005, 0x6003, 0x0003,
-	0x6106, 0x080c, 0x1aca, 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, 0x852e, 0x012e, 0x0005, 0x6144, 0x918d, 0xa032,
-	0x0cb8, 0x0126, 0x2091, 0x8000, 0x0036, 0x0096, 0x9182, 0x0040,
-	0x0023, 0x009e, 0x003e, 0x012e, 0x0005, 0xcd11, 0xcd13, 0xcd28,
-	0xcd42, 0xcd11, 0xcd11, 0xcd11, 0xcd11, 0xcd11, 0xcd11, 0xcd11,
-	0xcd11, 0xcd11, 0xcd11, 0xcd11, 0xcd11, 0xcd11, 0xcd11, 0xcd11,
-	0xcd11, 0x080c, 0x0d65, 0x6014, 0x2048, 0xa87c, 0xd0fc, 0x0510,
-	0x909c, 0x0003, 0x939e, 0x0003, 0x01e8, 0x6003, 0x0001, 0x6106,
-	0x0126, 0x2091, 0x8000, 0x2009, 0xa022, 0x080c, 0x84e7, 0x0470,
-	0x6014, 0x2048, 0xa87c, 0xd0fc, 0x0168, 0x909c, 0x0003, 0x939e,
-	0x0003, 0x0140, 0x6003, 0x0001, 0x6106, 0x2009, 0xa001, 0x080c,
-	0x84e7, 0x00e0, 0x901e, 0x6316, 0x631a, 0x2019, 0x0004, 0x080c,
-	0xd267, 0x00a0, 0x6014, 0x2048, 0xa87c, 0xd0fc, 0x0d98, 0x909c,
-	0x0003, 0x939e, 0x0003, 0x0d70, 0x6003, 0x0003, 0x6106, 0x080c,
-	0x1aca, 0x6144, 0x918d, 0xa035, 0x080c, 0x852e, 0x0005, 0x080c,
-	0x8891, 0x6114, 0x81ff, 0x0158, 0x0096, 0x2148, 0x080c, 0xd563,
-	0x0036, 0x2019, 0x0029, 0x080c, 0xd267, 0x003e, 0x009e, 0x080c,
-	0x9c20, 0x080c, 0x894f, 0x0005, 0x080c, 0x88ec, 0x6114, 0x81ff,
-	0x0158, 0x0096, 0x2148, 0x080c, 0xd563, 0x0036, 0x2019, 0x0029,
-	0x080c, 0xd267, 0x003e, 0x009e, 0x080c, 0x9c20, 0x0005, 0x9182,
-	0x0085, 0x0002, 0xcd91, 0xcd8f, 0xcd8f, 0xcd9d, 0xcd8f, 0xcd8f,
-	0xcd8f, 0xcd8f, 0xcd8f, 0xcd8f, 0xcd8f, 0xcd8f, 0xcd8f, 0x080c,
-	0x0d65, 0x6003, 0x000b, 0x6106, 0x0126, 0x2091, 0x8000, 0x2009,
-	0x8020, 0x080c, 0x84e7, 0x012e, 0x0005, 0x0026, 0x00e6, 0x080c,
-	0xd4b6, 0x0118, 0x080c, 0x9be6, 0x0440, 0x2071, 0x0260, 0x7224,
-	0x6216, 0x2001, 0x180e, 0x2004, 0xd0e4, 0x0150, 0x6010, 0x00b6,
-	0x2058, 0xbca0, 0x00be, 0x2c00, 0x2011, 0x014e, 0x080c, 0x9f10,
-	0x7220, 0x080c, 0xd0fd, 0x0118, 0x6007, 0x0086, 0x0040, 0x6007,
-	0x0087, 0x7224, 0x9296, 0xffff, 0x1110, 0x6007, 0x0086, 0x6003,
-	0x0001, 0x2009, 0x8020, 0x080c, 0x84e7, 0x00ee, 0x002e, 0x0005,
-	0x9186, 0x0013, 0x1160, 0x6004, 0x908a, 0x0085, 0x0a0c, 0x0d65,
-	0x908a, 0x0092, 0x1a0c, 0x0d65, 0x9082, 0x0085, 0x00a2, 0x9186,
-	0x0027, 0x0130, 0x9186, 0x0014, 0x0118, 0x080c, 0x9c9f, 0x0050,
-	0x2001, 0x0007, 0x080c, 0x620c, 0x080c, 0x8891, 0x080c, 0x9c20,
-	0x080c, 0x894f, 0x0005, 0xce00, 0xce02, 0xce02, 0xce00, 0xce00,
-	0xce00, 0xce00, 0xce00, 0xce00, 0xce00, 0xce00, 0xce00, 0xce00,
-	0x080c, 0x0d65, 0x080c, 0x9c20, 0x080c, 0x894f, 0x0005, 0x9182,
-	0x0085, 0x0a0c, 0x0d65, 0x9182, 0x0092, 0x1a0c, 0x0d65, 0x9182,
-	0x0085, 0x0002, 0xce1f, 0xce1f, 0xce1f, 0xce21, 0xce1f, 0xce1f,
-	0xce1f, 0xce1f, 0xce1f, 0xce1f, 0xce1f, 0xce1f, 0xce1f, 0x080c,
-	0x0d65, 0x0005, 0x9186, 0x0013, 0x0148, 0x9186, 0x0014, 0x0130,
-	0x9186, 0x0027, 0x0118, 0x080c, 0x9c9f, 0x0020, 0x080c, 0x8891,
-	0x080c, 0x9c20, 0x0005, 0x0036, 0x080c, 0xd517, 0x604b, 0x0000,
-	0x2019, 0x000b, 0x0031, 0x6023, 0x0006, 0x6003, 0x0007, 0x003e,
-	0x0005, 0x0126, 0x0036, 0x2091, 0x8000, 0x2001, 0x0382, 0x2004,
-	0x9084, 0x0007, 0x0006, 0x9086, 0x0003, 0x0110, 0x080c, 0x98c7,
-	0x0086, 0x2c40, 0x0096, 0x904e, 0x080c, 0x936d, 0x009e, 0x008e,
-	0x1558, 0x0076, 0x2c38, 0x080c, 0x9418, 0x007e, 0x1528, 0x6000,
-	0x9086, 0x0000, 0x0508, 0x6020, 0x9086, 0x0007, 0x01e8, 0x0096,
-	0x601c, 0xd084, 0x0140, 0x080c, 0xd517, 0x080c, 0xbfa7, 0x080c,
-	0x193e, 0x6023, 0x0007, 0x6014, 0x2048, 0x080c, 0xb870, 0x0110,
-	0x080c, 0xd267, 0x009e, 0x9006, 0x6046, 0x6016, 0x080c, 0xd517,
-	0x6023, 0x0007, 0x080c, 0xbfa7, 0x000e, 0x9086, 0x0003, 0x0110,
-	0x080c, 0x98e3, 0x003e, 0x012e, 0x0005, 0x00f6, 0x00c6, 0x00b6,
-	0x0036, 0x0156, 0x2079, 0x0260, 0x7938, 0x783c, 0x080c, 0x2459,
-	0x15e8, 0x0016, 0x00c6, 0x080c, 0x628f, 0x15b0, 0x001e, 0x00c6,
-	0x2160, 0x080c, 0xbfa4, 0x00ce, 0x002e, 0x0026, 0x0016, 0x080c,
-	0x98c7, 0x2019, 0x0029, 0x080c, 0x94e5, 0x080c, 0x8658, 0x0076,
-	0x903e, 0x080c, 0x853d, 0x007e, 0x001e, 0x0076, 0x903e, 0x080c,
-	0xd011, 0x007e, 0x080c, 0x98e3, 0x0026, 0xba04, 0x9294, 0xff00,
-	0x8217, 0x9286, 0x0006, 0x0118, 0x9286, 0x0004, 0x1118, 0xbaa0,
-	0x080c, 0x30f8, 0x002e, 0xbc84, 0x001e, 0x080c, 0x5d11, 0xbe12,
-	0xbd16, 0xbc86, 0x9006, 0x0010, 0x00ce, 0x001e, 0x015e, 0x003e,
-	0x00be, 0x00ce, 0x00fe, 0x0005, 0x00c6, 0x00d6, 0x00b6, 0x0016,
-	0x2009, 0x1823, 0x2104, 0x9086, 0x0074, 0x1904, 0xcf35, 0x2069,
-	0x0260, 0x6944, 0x9182, 0x0100, 0x06e0, 0x6940, 0x9184, 0x8000,
-	0x0904, 0xcf32, 0x2001, 0x1954, 0x2004, 0x9005, 0x1140, 0x6010,
-	0x2058, 0xb884, 0x9005, 0x0118, 0x9184, 0x0800, 0x0598, 0x6948,
-	0x918a, 0x0001, 0x0648, 0x080c, 0xd5cb, 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, 0x629e, 0x0804, 0xcfa0, 0x2011, 0x0276, 0x20a9,
-	0x0004, 0x0096, 0x2b48, 0x2019, 0x000a, 0x080c, 0xabee, 0x009e,
-	0x15c0, 0x2011, 0x027a, 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019,
-	0x0006, 0x080c, 0xabee, 0x009e, 0x1560, 0x0046, 0x0016, 0xbaa0,
-	0x2220, 0x9006, 0x2009, 0x185c, 0x210c, 0x0038, 0x2009, 0x0029,
-	0x080c, 0xd2bc, 0xb800, 0xc0e5, 0xb802, 0x080c, 0x98c7, 0x2019,
-	0x0029, 0x080c, 0x8658, 0x0076, 0x2039, 0x0000, 0x080c, 0x853d,
-	0x2c08, 0x080c, 0xd011, 0x007e, 0x080c, 0x98e3, 0x2001, 0x0007,
-	0x080c, 0x620c, 0x2001, 0x0007, 0x080c, 0x61e0, 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, 0x2459,
-	0x11d0, 0x080c, 0x628f, 0x11b8, 0x2011, 0x0270, 0x20a9, 0x0004,
-	0x0096, 0x2b48, 0x2019, 0x000a, 0x080c, 0xabee, 0x009e, 0x1158,
-	0x2011, 0x0274, 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x0006,
-	0x080c, 0xabee, 0x009e, 0x015e, 0x003e, 0x002e, 0x001e, 0x00fe,
-	0x00be, 0x0005, 0x00b6, 0x0006, 0x0016, 0x0026, 0x0036, 0x0156,
-	0x2011, 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x2459, 0x11d0,
-	0x080c, 0x628f, 0x11b8, 0x2011, 0x0276, 0x20a9, 0x0004, 0x0096,
-	0x2b48, 0x2019, 0x000a, 0x080c, 0xabee, 0x009e, 0x1158, 0x2011,
-	0x027a, 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x0006, 0x080c,
-	0xabee, 0x009e, 0x015e, 0x003e, 0x002e, 0x001e, 0x000e, 0x00be,
-	0x0005, 0x00e6, 0x00c6, 0x0086, 0x0076, 0x0066, 0x0056, 0x0046,
-	0x0026, 0x0126, 0x2091, 0x8000, 0x080c, 0x9925, 0x0106, 0x190c,
-	0x98c7, 0x2740, 0x2029, 0x19cb, 0x252c, 0x2021, 0x19d2, 0x2424,
-	0x2061, 0x1ddc, 0x2071, 0x1800, 0x7650, 0x7070, 0x81ff, 0x0150,
-	0x0006, 0x9186, 0x1b09, 0x000e, 0x0128, 0x8001, 0x9602, 0x1a04,
-	0xd0b2, 0x0018, 0x9606, 0x0904, 0xd0b2, 0x2100, 0x9c06, 0x0904,
-	0xd0a9, 0x080c, 0xd2fd, 0x1904, 0xd0a9, 0x080c, 0xd5e8, 0x0904,
-	0xd0a9, 0x080c, 0xd2ed, 0x0904, 0xd0a9, 0x6720, 0x9786, 0x0001,
-	0x1148, 0x080c, 0x3195, 0x0904, 0xd0d1, 0x6004, 0x9086, 0x0000,
-	0x1904, 0xd0d1, 0x9786, 0x0004, 0x0904, 0xd0d1, 0x9786, 0x0007,
-	0x0904, 0xd0a9, 0x2500, 0x9c06, 0x0904, 0xd0a9, 0x2400, 0x9c06,
-	0x0904, 0xd0a9, 0x88ff, 0x0118, 0x605c, 0x9906, 0x15d0, 0x0096,
-	0x6043, 0xffff, 0x6000, 0x9086, 0x0004, 0x1120, 0x0016, 0x080c,
-	0x193e, 0x001e, 0x9786, 0x000a, 0x0148, 0x080c, 0xba85, 0x1130,
-	0x080c, 0xa59c, 0x009e, 0x080c, 0x9c20, 0x0418, 0x6014, 0x2048,
-	0x080c, 0xb870, 0x01d8, 0x9786, 0x0003, 0x1588, 0xa867, 0x0103,
-	0xa87c, 0xd0cc, 0x0130, 0x0096, 0xa878, 0x2048, 0x080c, 0x0fe1,
-	0x009e, 0xab7a, 0xa877, 0x0000, 0x080c, 0xd563, 0x0016, 0x080c,
-	0xbb73, 0x080c, 0x69a9, 0x001e, 0x080c, 0xba5f, 0x009e, 0x080c,
-	0x9c20, 0x9ce0, 0x001c, 0x2001, 0x1819, 0x2004, 0x9c02, 0x1210,
-	0x0804, 0xd02a, 0x010e, 0x190c, 0x98e3, 0x012e, 0x002e, 0x004e,
-	0x005e, 0x006e, 0x007e, 0x008e, 0x00ce, 0x00ee, 0x0005, 0x9786,
-	0x0006, 0x1150, 0x9386, 0x0005, 0x0128, 0x080c, 0xd563, 0x080c,
-	0xd267, 0x08e0, 0x009e, 0x08e8, 0x9786, 0x000a, 0x0908, 0x0804,
-	0xd08e, 0x81ff, 0x09b0, 0x9180, 0x0001, 0x2004, 0x9086, 0x0018,
-	0x0130, 0x9180, 0x0001, 0x2004, 0x9086, 0x002d, 0x1950, 0x6000,
-	0x9086, 0x0002, 0x1930, 0x080c, 0xba74, 0x0130, 0x080c, 0xba85,
-	0x1900, 0x080c, 0xa59c, 0x0038, 0x080c, 0x305d, 0x080c, 0xba85,
-	0x1110, 0x080c, 0xa59c, 0x080c, 0x9c20, 0x0804, 0xd0a9, 0xa864,
-	0x9084, 0x00ff, 0x9086, 0x0039, 0x0005, 0x00c6, 0x00e6, 0x0016,
-	0x2c08, 0x2170, 0x9006, 0x080c, 0xd28e, 0x001e, 0x0120, 0x6020,
-	0x9084, 0x000f, 0x001b, 0x00ee, 0x00ce, 0x0005, 0xd11c, 0xd11c,
-	0xd11c, 0xd11c, 0xd11c, 0xd11c, 0xd11e, 0xd11c, 0xd11c, 0xd11c,
-	0xd11c, 0x9c20, 0x9c20, 0xd11c, 0x9006, 0x0005, 0x0036, 0x0046,
-	0x0016, 0x7010, 0x00b6, 0x2058, 0xbca0, 0x00be, 0x2c00, 0x2009,
-	0x0020, 0x080c, 0xd2bc, 0x001e, 0x004e, 0x2019, 0x0002, 0x080c,
-	0xce41, 0x003e, 0x9085, 0x0001, 0x0005, 0x0096, 0x080c, 0xb870,
-	0x0140, 0x6014, 0x904d, 0x080c, 0xb45e, 0x687b, 0x0005, 0x080c,
-	0x69b5, 0x009e, 0x080c, 0x9c20, 0x9085, 0x0001, 0x0005, 0x2001,
-	0x0001, 0x080c, 0x61cc, 0x0156, 0x0016, 0x0026, 0x0036, 0x20a9,
-	0x0004, 0x2019, 0x1805, 0x2011, 0x0276, 0x080c, 0xabda, 0x003e,
-	0x002e, 0x001e, 0x015e, 0x9005, 0x0005, 0x00f6, 0x00e6, 0x00c6,
-	0x0086, 0x0076, 0x0066, 0x00b6, 0x0126, 0x2091, 0x8000, 0x2740,
-	0x2061, 0x1ddc, 0x2079, 0x0001, 0x8fff, 0x0904, 0xd1b7, 0x2071,
-	0x1800, 0x7650, 0x7070, 0x8001, 0x9602, 0x1a04, 0xd1b7, 0x88ff,
-	0x0120, 0x2800, 0x9c06, 0x1590, 0x2078, 0x080c, 0xd2ed, 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, 0xd517, 0x080c, 0xbfa7, 0x080c, 0x193e, 0x6023, 0x0007,
-	0x6014, 0x2048, 0x080c, 0xb870, 0x0120, 0x0046, 0x080c, 0xd267,
-	0x004e, 0x009e, 0x080c, 0x9c20, 0x88ff, 0x1198, 0x9ce0, 0x001c,
-	0x2001, 0x1819, 0x2004, 0x9c02, 0x1210, 0x0804, 0xd16c, 0x9006,
-	0x012e, 0x00be, 0x006e, 0x007e, 0x008e, 0x00ce, 0x00ee, 0x00fe,
-	0x0005, 0x98c5, 0x0001, 0x0ca0, 0x080c, 0x98c7, 0x00b6, 0x0076,
-	0x0056, 0x0086, 0x9046, 0x2029, 0x0001, 0x2c20, 0x2019, 0x0002,
-	0x6210, 0x2258, 0x0096, 0x904e, 0x080c, 0x936d, 0x009e, 0x008e,
-	0x903e, 0x080c, 0x9418, 0x080c, 0xd15d, 0x005e, 0x007e, 0x00be,
-	0x080c, 0x98e3, 0x0005, 0x080c, 0x98c7, 0x00b6, 0x0046, 0x0056,
-	0x0076, 0x00c6, 0x0156, 0x2c20, 0x2128, 0x20a9, 0x007f, 0x900e,
-	0x0016, 0x0036, 0x080c, 0x628f, 0x1190, 0x0056, 0x0086, 0x9046,
-	0x2508, 0x2029, 0x0001, 0x0096, 0x904e, 0x080c, 0x936d, 0x009e,
-	0x008e, 0x903e, 0x080c, 0x9418, 0x080c, 0xd15d, 0x005e, 0x003e,
-	0x001e, 0x8108, 0x1f04, 0xd1f0, 0x015e, 0x00ce, 0x007e, 0x005e,
-	0x004e, 0x00be, 0x080c, 0x98e3, 0x0005, 0x080c, 0x98c7, 0x00b6,
-	0x0076, 0x0056, 0x6210, 0x2258, 0x0086, 0x9046, 0x2029, 0x0001,
-	0x2019, 0x0048, 0x0096, 0x904e, 0x080c, 0x936d, 0x009e, 0x008e,
-	0x903e, 0x080c, 0x9418, 0x2c20, 0x080c, 0xd15d, 0x005e, 0x007e,
-	0x00be, 0x080c, 0x98e3, 0x0005, 0x080c, 0x98c7, 0x00b6, 0x0046,
-	0x0056, 0x0076, 0x00c6, 0x0156, 0x2c20, 0x20a9, 0x0800, 0x900e,
-	0x0016, 0x0036, 0x080c, 0x628f, 0x11a0, 0x0086, 0x9046, 0x2828,
-	0x0046, 0x2021, 0x0001, 0x080c, 0xd4fb, 0x004e, 0x0096, 0x904e,
-	0x080c, 0x936d, 0x009e, 0x008e, 0x903e, 0x080c, 0x9418, 0x080c,
-	0xd15d, 0x003e, 0x001e, 0x8108, 0x1f04, 0xd240, 0x015e, 0x00ce,
-	0x007e, 0x005e, 0x004e, 0x00be, 0x080c, 0x98e3, 0x0005, 0x0016,
-	0x00f6, 0x080c, 0xb86e, 0x0198, 0xa864, 0x9084, 0x00ff, 0x9086,
-	0x0046, 0x0180, 0xa800, 0x907d, 0x0138, 0xa803, 0x0000, 0xab82,
-	0x080c, 0x69b5, 0x2f48, 0x0cb0, 0xab82, 0x080c, 0x69b5, 0x00fe,
-	0x001e, 0x0005, 0xa800, 0x907d, 0x0130, 0xa803, 0x0000, 0x080c,
-	0x69b5, 0x2f48, 0x0cb8, 0x080c, 0x69b5, 0x0c88, 0x00e6, 0x0046,
-	0x0036, 0x2061, 0x1ddc, 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, 0x001c, 0x2001, 0x1819,
-	0x2004, 0x9c02, 0x1220, 0x0c40, 0x9085, 0x0001, 0x0008, 0x9006,
-	0x003e, 0x004e, 0x00ee, 0x0005, 0x0096, 0x0006, 0x080c, 0x102f,
-	0x000e, 0x090c, 0x0d65, 0xaae2, 0xa867, 0x010d, 0xa88e, 0x0026,
-	0x2010, 0x080c, 0xb85e, 0x2001, 0x0000, 0x0120, 0x2200, 0x9080,
-	0x0017, 0x2004, 0x002e, 0xa87a, 0x9186, 0x0020, 0x0110, 0xa8e3,
-	0xffff, 0xa986, 0xac76, 0xa87f, 0x0000, 0x2001, 0x1966, 0x2004,
-	0xa882, 0x9006, 0xa802, 0xa86a, 0xa88a, 0x0126, 0x2091, 0x8000,
-	0x080c, 0x69b5, 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,
-	0x2009, 0x8020, 0x080c, 0x84e7, 0x001e, 0x0005, 0xa001, 0xa001,
-	0x0005, 0x6024, 0xd0e4, 0x0158, 0xd0cc, 0x0118, 0x080c, 0xbbba,
-	0x0030, 0x080c, 0xd517, 0x080c, 0x83d6, 0x080c, 0x9be6, 0x0005,
-	0x9280, 0x0008, 0x2004, 0x9084, 0x000f, 0x0002, 0xd34c, 0xd34c,
-	0xd34c, 0xd34e, 0xd34c, 0xd34e, 0xd34e, 0xd34c, 0xd34e, 0xd34c,
-	0xd34c, 0xd34c, 0xd34c, 0xd34c, 0x9006, 0x0005, 0x9085, 0x0001,
-	0x0005, 0x9280, 0x0008, 0x2004, 0x9084, 0x000f, 0x0002, 0xd365,
-	0xd365, 0xd365, 0xd365, 0xd365, 0xd365, 0xd372, 0xd365, 0xd365,
-	0xd365, 0xd365, 0xd365, 0xd365, 0xd365, 0x6007, 0x003b, 0x602f,
-	0x0009, 0x6017, 0x2a00, 0x6003, 0x0001, 0x2009, 0x8020, 0x080c,
-	0x84e7, 0x0005, 0x0096, 0x00c6, 0x2260, 0x080c, 0xd517, 0x604b,
-	0x0000, 0x6024, 0xc0f4, 0xc0e4, 0x6026, 0x603b, 0x0000, 0x00ce,
-	0x00d6, 0x2268, 0x9186, 0x0007, 0x1904, 0xd3cb, 0x6814, 0x9005,
-	0x0138, 0x2048, 0xa87c, 0xd0fc, 0x1118, 0x00de, 0x009e, 0x08a8,
-	0x6007, 0x003a, 0x6003, 0x0001, 0x2009, 0x8020, 0x080c, 0x84e7,
-	0x00c6, 0x2d60, 0x6100, 0x9186, 0x0002, 0x1904, 0xd442, 0x6014,
-	0x9005, 0x1138, 0x6000, 0x9086, 0x0007, 0x190c, 0x0d65, 0x0804,
-	0xd442, 0x2048, 0x080c, 0xb870, 0x1130, 0x0028, 0x2048, 0xa800,
-	0x9005, 0x1de0, 0x2900, 0x2048, 0xa87c, 0x9084, 0x0003, 0x9086,
-	0x0002, 0x1168, 0xa87c, 0xc0dc, 0xc0f4, 0xa87e, 0xa880, 0xc0fc,
-	0xa882, 0x2009, 0x0043, 0x080c, 0xcc7e, 0x0804, 0xd442, 0x2009,
-	0x0041, 0x0804, 0xd43c, 0x9186, 0x0005, 0x15a0, 0x6814, 0x2048,
-	0xa87c, 0xd0bc, 0x1120, 0x00de, 0x009e, 0x0804, 0xd365, 0xd0b4,
-	0x0128, 0xd0fc, 0x090c, 0x0d65, 0x0804, 0xd386, 0x6007, 0x003a,
-	0x6003, 0x0001, 0x2009, 0x8020, 0x080c, 0x84e7, 0x00c6, 0x2d60,
-	0x6100, 0x9186, 0x0002, 0x0120, 0x9186, 0x0004, 0x1904, 0xd442,
-	0x6814, 0x2048, 0xa97c, 0xc1f4, 0xc1dc, 0xa97e, 0xa980, 0xc1fc,
-	0xc1bc, 0xa982, 0x00f6, 0x2c78, 0x080c, 0x1669, 0x00fe, 0x2009,
-	0x0042, 0x04d0, 0x0036, 0x080c, 0x102f, 0x090c, 0x0d65, 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, 0x69b5, 0x2019, 0x0045, 0x6008, 0x2068, 0x080c,
-	0xce41, 0x2d00, 0x600a, 0x6023, 0x0006, 0x6003, 0x0007, 0x901e,
-	0x631a, 0x634a, 0x003e, 0x0038, 0x604b, 0x0000, 0x6003, 0x0007,
-	0x080c, 0xcc7e, 0x00ce, 0x00de, 0x009e, 0x0005, 0x9186, 0x0013,
-	0x1128, 0x6004, 0x9082, 0x0085, 0x2008, 0x00c2, 0x9186, 0x0027,
-	0x1178, 0x080c, 0x8891, 0x0036, 0x0096, 0x6014, 0x2048, 0x2019,
-	0x0004, 0x080c, 0xd267, 0x009e, 0x003e, 0x080c, 0x894f, 0x0005,
-	0x9186, 0x0014, 0x0d70, 0x080c, 0x9c9f, 0x0005, 0xd475, 0xd473,
-	0xd473, 0xd473, 0xd473, 0xd473, 0xd475, 0xd473, 0xd473, 0xd473,
-	0xd473, 0xd473, 0xd473, 0x080c, 0x0d65, 0x6003, 0x000c, 0x080c,
-	0x894f, 0x0005, 0x9182, 0x0092, 0x1220, 0x9182, 0x0085, 0x0208,
-	0x001a, 0x080c, 0x9c9f, 0x0005, 0xd491, 0xd491, 0xd491, 0xd491,
-	0xd493, 0xd4b3, 0xd491, 0xd491, 0xd491, 0xd491, 0xd491, 0xd491,
-	0xd491, 0x080c, 0x0d65, 0x00d6, 0x2c68, 0x080c, 0x9b90, 0x01b0,
-	0x6003, 0x0001, 0x6007, 0x001e, 0x2009, 0x026e, 0x210c, 0x613a,
-	0x2009, 0x026f, 0x210c, 0x613e, 0x600b, 0xffff, 0x6910, 0x6112,
-	0x6023, 0x0004, 0x2009, 0x8020, 0x080c, 0x84e7, 0x2d60, 0x080c,
-	0x9be6, 0x00de, 0x0005, 0x080c, 0x9be6, 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, 0x604a, 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,
-	0x604a, 0x6010, 0x00b6, 0x2058, 0xb8ac, 0x00be, 0x0008, 0x2104,
-	0x9005, 0x0118, 0x9088, 0x0003, 0x0cd0, 0x2c0a, 0x600f, 0x0000,
-	0x9085, 0x0001, 0x0005, 0x0016, 0x00c6, 0x00e6, 0x615c, 0xb8ac,
-	0x2060, 0x8cff, 0x0180, 0x84ff, 0x1118, 0x605c, 0x9106, 0x1138,
-	0x600c, 0x2072, 0x080c, 0x83d6, 0x080c, 0x9be6, 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, 0xabee, 0x009e,
-	0x1168, 0x2011, 0x0274, 0x20a9, 0x0004, 0x6010, 0x0096, 0x2048,
-	0x2019, 0x0006, 0x080c, 0xabee, 0x009e, 0x1100, 0x015e, 0x003e,
-	0x002e, 0x0005, 0x00e6, 0x2071, 0x1800, 0x080c, 0x5c8a, 0x080c,
-	0x2e09, 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, 0x19d2, 0x2424, 0x2061, 0x1ddc, 0x2071, 0x1800,
-	0x7650, 0x7070, 0x9606, 0x0578, 0x6720, 0x9786, 0x0001, 0x0118,
-	0x9786, 0x0008, 0x1500, 0x2500, 0x9c06, 0x01e8, 0x2400, 0x9c06,
-	0x01d0, 0x080c, 0xd2ed, 0x01b8, 0x080c, 0xd2fd, 0x11a0, 0x6000,
-	0x9086, 0x0004, 0x1120, 0x0016, 0x080c, 0x193e, 0x001e, 0x080c,
-	0xba74, 0x1110, 0x080c, 0x305d, 0x080c, 0xba85, 0x1110, 0x080c,
-	0xa59c, 0x080c, 0x9c20, 0x9ce0, 0x001c, 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, 0xbf8f, 0x0168,
-	0x2019, 0xffff, 0x9005, 0x0128, 0x6010, 0x00b6, 0x2058, 0xbba0,
-	0x00be, 0x2021, 0x0004, 0x080c, 0x4a97, 0x004e, 0x003e, 0x000e,
-	0x6004, 0x9086, 0x0001, 0x1128, 0x080c, 0x94e5, 0x080c, 0x9c20,
-	0x9006, 0x0005, 0x00e6, 0x00c6, 0x00b6, 0x0046, 0x2061, 0x1ddc,
-	0x2071, 0x1800, 0x7450, 0x7070, 0x8001, 0x9402, 0x12b8, 0x2100,
-	0x9c06, 0x0148, 0x6000, 0x9086, 0x0000, 0x0128, 0x6010, 0x2058,
-	0xb8a0, 0x9206, 0x0140, 0x9ce0, 0x001c, 0x2001, 0x1819, 0x2004,
-	0x9c02, 0x1220, 0x0c60, 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, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010,
-	0x0020, 0x0040, 0x0080, 0x0100, 0x0200, 0x0400, 0x0800, 0x1000,
-	0x2000, 0x4000, 0x8000, 0x8c0a
-};
-#ifdef UNIQUE_FW_NAME
-unsigned short fw2322flx_length01 = 0xce84;
-#else
-unsigned short risc_code_length01 = 0xce84;
-#endif
-
-/*
- *
- */
-
-unsigned long rseqflx_code_addr01 = 0x0001c000 ;
-unsigned short rseqflx_code01[] = { 
-0x000b, 0x0003, 0x0000, 0x072a, 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, 0x000b, 0x60af,
-	0x0003, 0x5817, 0x0003, 0x7ac9, 0x0003, 0x5209, 0x000b, 0xc813,
-	0x0009, 0xbac0, 0x0000, 0x008a, 0x0003, 0x8813, 0x0000, 0x15fc,
-	0x000b, 0xb013, 0x0009, 0xc4c0, 0x0000, 0x7000, 0x0001, 0xffa0,
-	0x0000, 0x2000, 0x0003, 0x936d, 0x0008, 0x808c, 0x0000, 0x0001,
-	0x0007, 0x0000, 0x0007, 0x0000, 0x000a, 0x4047, 0x0008, 0x808c,
-	0x0000, 0x0002, 0x0007, 0x0000, 0x0003, 0x082d, 0x0000, 0x4022,
-	0x000b, 0x002e, 0x0008, 0x4122, 0x0002, 0x4447, 0x0003, 0x8b91,
-	0x0008, 0x0bfe, 0x0001, 0x11a0, 0x000b, 0x1373, 0x0001, 0x0ca0,
-	0x000b, 0x1373, 0x0001, 0x9180, 0x0000, 0x0004, 0x0000, 0x8060,
-	0x0000, 0x0400, 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x0009,
-	0x000b, 0xc03c, 0x0008, 0x808c, 0x0008, 0x0000, 0x0008, 0x0060,
-	0x0008, 0x8062, 0x0000, 0x0004, 0x0000, 0x8066, 0x0000, 0x0411,
-	0x000b, 0xc044, 0x0000, 0x03fe, 0x0001, 0x43e0, 0x0003, 0x8b70,
-	0x0009, 0xc2c0, 0x0008, 0x00ff, 0x0001, 0x02e0, 0x0003, 0x8b70,
-	0x0001, 0x9180, 0x0008, 0x0005, 0x0000, 0x8060, 0x0000, 0x0400,
-	0x0008, 0x7f62, 0x0000, 0x8066, 0x0000, 0x0019, 0x000b, 0xc053,
-	0x0002, 0x0240, 0x000b, 0x0b6d, 0x0008, 0x00fc, 0x0003, 0x3370,
-	0x000a, 0x0244, 0x0003, 0x0865, 0x000c, 0x01e2, 0x0001, 0x9180,
-	0x0000, 0x0007, 0x0008, 0x7f62, 0x0000, 0x8060, 0x0000, 0x0400,
-	0x0002, 0x0234, 0x0008, 0x7f04, 0x0000, 0x8066, 0x0000, 0x040a,
-	0x0003, 0xc064, 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, 0xc071, 0x0008, 0x01fe, 0x0009, 0x42e0,
-	0x0003, 0x8b62, 0x0000, 0x00fe, 0x0001, 0x43e0, 0x0003, 0x8b62,
-	0x0000, 0x1734, 0x0000, 0x1530, 0x0008, 0x1632, 0x0008, 0x0d2a,
-	0x0001, 0x9880, 0x0008, 0x0012, 0x0000, 0x8060, 0x0000, 0x0400,
-	0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x1e0a, 0x0003, 0xc083,
-	0x0008, 0x808a, 0x0008, 0x0003, 0x0000, 0x1a60, 0x0008, 0x8062,
-	0x0000, 0x0002, 0x000b, 0x5889, 0x0000, 0x8066, 0x0000, 0x3679,
-	0x0003, 0xc08c, 0x0003, 0x588d, 0x0008, 0x8054, 0x0008, 0x0011,
-	0x0000, 0x8074, 0x0008, 0x1010, 0x0008, 0x1efc, 0x0003, 0x3013,
-	0x0004, 0x0096, 0x0003, 0x0013, 0x0000, 0x1c60, 0x0000, 0x1b62,
-	0x0000, 0x8066, 0x0008, 0x0231, 0x000b, 0xc09a, 0x000b, 0x589b,
-	0x0008, 0x0140, 0x0000, 0x0242, 0x0002, 0x1f43, 0x000b, 0x88a5,
-	0x0000, 0x0d44, 0x0008, 0x0d46, 0x0008, 0x0348, 0x0008, 0x044a,
-	0x000b, 0x00a9, 0x0008, 0x0344, 0x0008, 0x0446, 0x0008, 0x0548,
-	0x0000, 0x064a, 0x0003, 0x58a9, 0x0008, 0x8054, 0x0000, 0x0001,
-	0x0000, 0x8074, 0x0008, 0x2020, 0x000f, 0x4000, 0x0000, 0x4820,
-	0x0008, 0x0bfe, 0x0009, 0x10a0, 0x0003, 0x1110, 0x0001, 0x0ca0,
-	0x0003, 0x1110, 0x0000, 0x8060, 0x0000, 0x0400, 0x0009, 0x9080,
-	0x0000, 0x0008, 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x0009,
-	0x0003, 0xc0bc, 0x0001, 0x80e0, 0x0008, 0x0003, 0x000b, 0x8910,
-	0x0000, 0x49b4, 0x0002, 0x4b4e, 0x000b, 0x8919, 0x0008, 0x808a,
-	0x0000, 0x0004, 0x0000, 0x18fe, 0x0001, 0x10e0, 0x000b, 0x88ca,
-	0x0002, 0x192f, 0x0008, 0x7f32, 0x0008, 0x15fe, 0x0001, 0x10e0,
-	0x000b, 0x88cf, 0x0002, 0x162f, 0x0008, 0x7f2c, 0x0000, 0x8060,
-	0x0000, 0x0400, 0x0009, 0x9080, 0x0000, 0x0007, 0x0008, 0x7f62,
-	0x0000, 0x8066, 0x0008, 0x0009, 0x0003, 0xc0d6, 0x000a, 0x004f,
-	0x000b, 0x8907, 0x000a, 0x0040, 0x000b, 0x08f1, 0x0002, 0x004e,
-	0x000b, 0x08f1, 0x0002, 0x0030, 0x0002, 0x7f2f, 0x0000, 0x7f00,
-	0x0000, 0x8066, 0x0008, 0x000a, 0x000b, 0xc0e2, 0x0008, 0x1010,
-	0x000c, 0x01c9, 0x000b, 0xb0ea, 0x0004, 0x0336, 0x0004, 0x01b3,
-	0x000b, 0x7814, 0x0003, 0x0013, 0x0000, 0x0806, 0x0008, 0x8010,
-	0x0000, 0x001f, 0x0004, 0x0336, 0x0000, 0x0310, 0x0004, 0x0336,
-	0x000b, 0x00e8, 0x000a, 0x002f, 0x0000, 0x7f00, 0x0000, 0x8066,
-	0x0008, 0x000a, 0x000b, 0xc0f5, 0x0004, 0x018c, 0x000a, 0x0040,
-	0x000b, 0x090a, 0x000c, 0x01f9, 0x0000, 0x8000, 0x0000, 0x0002,
-	0x0000, 0x8060, 0x0000, 0x0400, 0x0009, 0x9080, 0x0008, 0x0006,
-	0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x000a, 0x0003, 0xc103,
-	0x0000, 0x8072, 0x0000, 0x4000, 0x000b, 0x00e8, 0x0008, 0x8010,
-	0x0008, 0x001e, 0x0003, 0x010c, 0x0008, 0x8010, 0x0008, 0x001d,
-	0x0004, 0x0336, 0x0008, 0x1010, 0x0004, 0x0336, 0x000b, 0x0014,
-	0x0002, 0x4b4e, 0x0003, 0x0916, 0x0008, 0x808a, 0x0000, 0x0004,
-	0x000b, 0x6116, 0x000f, 0x8000, 0x0008, 0x808a, 0x0000, 0x0004,
-	0x000b, 0x0014, 0x0000, 0x8060, 0x0000, 0x0400, 0x0009, 0x9080,
-	0x0008, 0x0011, 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x0009,
-	0x000b, 0xc120, 0x000a, 0x004f, 0x0003, 0x897d, 0x0000, 0x8060,
-	0x0000, 0x0400, 0x0009, 0x9080, 0x0008, 0x0005, 0x0008, 0x7f62,
-	0x0000, 0x8066, 0x0008, 0x0009, 0x000b, 0xc12a, 0x0008, 0x0060,
-	0x0008, 0x8062, 0x0000, 0x001f, 0x0000, 0x8066, 0x0000, 0x0209,
-	0x0003, 0xc130, 0x000a, 0x014b, 0x000b, 0x097d, 0x0008, 0x8062,
-	0x0008, 0x000f, 0x0000, 0x8066, 0x0000, 0x0211, 0x000b, 0xc137,
-	0x0008, 0x01fe, 0x0001, 0x02d0, 0x0003, 0x897d, 0x000c, 0x0195,
-	0x000b, 0x097d, 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,
-	0x000b, 0xc14c, 0x000b, 0xe14d, 0x0008, 0x4908, 0x0008, 0x480a,
-	0x0008, 0x808a, 0x0000, 0x0004, 0x0008, 0x0060, 0x0008, 0x8062,
-	0x0008, 0x002b, 0x0000, 0x8066, 0x0000, 0x0411, 0x000b, 0xc157,
-	0x0008, 0x04fe, 0x0009, 0x02a0, 0x000b, 0x915e, 0x0002, 0x0500,
-	0x0003, 0x097a, 0x0003, 0x015f, 0x0000, 0x05fe, 0x0001, 0x03a0,
-	0x0003, 0x117a, 0x0000, 0x0d0c, 0x0008, 0x0d0e, 0x0008, 0x0d10,
-	0x0000, 0x0d12, 0x0008, 0x0060, 0x0008, 0x8062, 0x0000, 0x000d,
-	0x0000, 0x8066, 0x0008, 0x0832, 0x0003, 0xc16a, 0x0000, 0x800a,
-	0x0000, 0x8005, 0x0000, 0x8060, 0x0000, 0x0400, 0x0009, 0x9080,
-	0x0008, 0x0011, 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x0a12,
-	0x0003, 0xc174, 0x0008, 0x5006, 0x0008, 0x100e, 0x000c, 0x01a0,
-	0x000b, 0x7814, 0x0003, 0x0013, 0x0008, 0x0208, 0x0008, 0x030a,
-	0x000b, 0x0161, 0x0004, 0x018c, 0x0008, 0x808a, 0x0000, 0x0004,
-	0x0008, 0x8010, 0x0008, 0x0021, 0x0004, 0x0336, 0x0008, 0x1010,
-	0x0004, 0x0336, 0x0000, 0x4810, 0x0004, 0x0336, 0x0008, 0x4910,
-	0x0004, 0x0336, 0x0008, 0x808a, 0x0000, 0x0004, 0x000b, 0x0014,
-	0x0000, 0x8060, 0x0000, 0x0400, 0x0009, 0x9080, 0x0000, 0x0002,
-	0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0xb40a, 0x0003, 0xc193,
-	0x000f, 0x4000, 0x0000, 0x8060, 0x0000, 0x0400, 0x0000, 0x0a62,
-	0x0000, 0x8066, 0x0000, 0x0411, 0x0003, 0xc19a, 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,
-	0x000b, 0xc1a8, 0x0002, 0x0300, 0x0001, 0xffc0, 0x0000, 0x0007,
-	0x0000, 0x7f06, 0x0002, 0x0a00, 0x0008, 0x7f62, 0x0000, 0x8066,
-	0x0008, 0x060a, 0x0003, 0xc1b1, 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, 0x000b, 0xc1c1, 0x0009, 0x8880, 0x0008, 0x0009,
-	0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0xa03a, 0x000b, 0xc1c7,
-	0x000f, 0x4000, 0x0009, 0x8880, 0x0008, 0x0005, 0x0000, 0x8060,
-	0x0000, 0x0400, 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x0009,
-	0x000b, 0xc1d0, 0x0008, 0x0060, 0x0008, 0x8062, 0x0000, 0x000d,
-	0x0000, 0x8066, 0x0008, 0x0021, 0x000b, 0xc1d6, 0x0000, 0x00fe,
-	0x0001, 0x01d0, 0x000b, 0x89df, 0x0008, 0x02fe, 0x0009, 0x03d0,
-	0x0003, 0x09df, 0x0000, 0x0d06, 0x000f, 0x4000, 0x0000, 0x8006,
-	0x0000, 0x0001, 0x000f, 0x4000, 0x0008, 0x0060, 0x0008, 0x8062,
-	0x0008, 0x002b, 0x0000, 0x8066, 0x0008, 0xa041, 0x0003, 0xc1e7,
-	0x0002, 0x0243, 0x0003, 0x89ee, 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, 0x000b, 0xc1f7,
-	0x000f, 0x4000, 0x000a, 0x3945, 0x0003, 0x8a03, 0x0000, 0x8072,
-	0x0008, 0x4040, 0x0007, 0x0000, 0x000a, 0x3945, 0x000b, 0x8a01,
-	0x000f, 0x4000, 0x0000, 0x8072, 0x0000, 0x4000, 0x0007, 0x0000,
-	0x0007, 0x0000, 0x0007, 0x0000, 0x000a, 0x3945, 0x0003, 0x09fb,
-	0x0003, 0x0203, 0x000a, 0x3a40, 0x000b, 0x8817, 0x0001, 0xabd0,
-	0x0008, 0x0000, 0x0000, 0x7f24, 0x0003, 0x5a0e, 0x0008, 0x8054,
-	0x0000, 0x0002, 0x0002, 0x1242, 0x0003, 0x0a54, 0x000a, 0x3a45,
-	0x0003, 0x0a43, 0x000a, 0x1e10, 0x0000, 0x7f3c, 0x0003, 0x0a40,
-	0x0002, 0x1d00, 0x0000, 0x7f3a, 0x0000, 0x0d60, 0x0008, 0x7f62,
-	0x0000, 0x8066, 0x0008, 0x0009, 0x0003, 0xc21e, 0x0008, 0x00fc,
-	0x0003, 0xb23d, 0x0000, 0x1c60, 0x0008, 0x8062, 0x0000, 0x0001,
-	0x0000, 0x8066, 0x0008, 0x0009, 0x000b, 0xc226, 0x0008, 0x00fc,
-	0x000b, 0x334b, 0x0000, 0x0038, 0x0008, 0x0060, 0x0008, 0x8062,
-	0x0000, 0x0019, 0x0000, 0x8066, 0x0008, 0x0009, 0x000b, 0xc22f,
-	0x0009, 0x80c0, 0x0008, 0x00ff, 0x0008, 0x7f3e, 0x0000, 0x0d60,
-	0x0008, 0x0efe, 0x0001, 0x1f80, 0x0008, 0x7f62, 0x0000, 0x8066,
-	0x0008, 0x0009, 0x0003, 0xc239, 0x0008, 0x003a, 0x0000, 0x1dfe,
-	0x000b, 0x021a, 0x0008, 0x0036, 0x0004, 0x0096, 0x000b, 0x0254,
-	0x0000, 0x8074, 0x0000, 0x2000, 0x000b, 0x0254, 0x0002, 0x3a44,
-	0x000b, 0x0b76, 0x0000, 0x8074, 0x0000, 0x1000, 0x0001, 0xadd0,
-	0x0008, 0x0000, 0x0008, 0x7f0e, 0x0003, 0xb348, 0x0001, 0xa7d0,
-	0x0008, 0x0000, 0x0000, 0x7f00, 0x0009, 0xa6d0, 0x0008, 0x0000,
-	0x0009, 0x00d0, 0x000b, 0x8a64, 0x0000, 0x8074, 0x0008, 0x4040,
-	0x0003, 0x5a54, 0x0003, 0x5209, 0x000a, 0x3a46, 0x000b, 0x8a64,
-	0x0002, 0x3a47, 0x000b, 0x0a5f, 0x0008, 0x8054, 0x0000, 0x0004,
-	0x0000, 0x8074, 0x0000, 0x8000, 0x0003, 0x02bd, 0x0009, 0x92c0,
-	0x0000, 0x0fc8, 0x000b, 0x0813, 0x000a, 0x1246, 0x000b, 0x8b42,
-	0x0000, 0x1a60, 0x0008, 0x8062, 0x0000, 0x0002, 0x0000, 0x8066,
-	0x0000, 0x367a, 0x0003, 0xc269, 0x0009, 0x92c0, 0x0008, 0x0780,
-	0x000b, 0x8b5c, 0x0002, 0x124b, 0x000b, 0x0a72, 0x0002, 0x2e4d,
-	0x0002, 0x2e4d, 0x0003, 0x0b48, 0x000a, 0x3a46, 0x000b, 0x8a7f,
-	0x000b, 0x5a74, 0x0008, 0x8054, 0x0000, 0x0004, 0x000a, 0x1243,
-	0x000b, 0x0abb, 0x0008, 0x8010, 0x0000, 0x000d, 0x0004, 0x0336,
-	0x0000, 0x1810, 0x0004, 0x0336, 0x0003, 0x02bb, 0x000a, 0x194d,
-	0x0003, 0x0a83, 0x000a, 0x1243, 0x000b, 0x0b52, 0x0003, 0x5a83,
-	0x0008, 0x8054, 0x0000, 0x0004, 0x000a, 0x192e, 0x0008, 0x7f32,
-	0x000a, 0x1947, 0x0003, 0x0ab5, 0x0002, 0x194f, 0x000b, 0x0a93,
-	0x0004, 0x032b, 0x0000, 0x1810, 0x000c, 0x01c9, 0x0003, 0xb2ae,
-	0x0004, 0x0336, 0x0004, 0x01b3, 0x0003, 0x02bb, 0x0000, 0x1a60,
-	0x0008, 0x8062, 0x0000, 0x001f, 0x0000, 0x8066, 0x0008, 0x0009,
-	0x000b, 0xc298, 0x000a, 0x004c, 0x000b, 0x8ab5, 0x0000, 0x8060,
-	0x0000, 0x0400, 0x0001, 0x9880, 0x0000, 0x0007, 0x0008, 0x7f62,
-	0x0000, 0x8066, 0x0000, 0x320a, 0x000b, 0xc2a2, 0x0000, 0x8060,
-	0x0000, 0x0400, 0x0001, 0x9880, 0x0008, 0x0012, 0x0008, 0x7f62,
-	0x0000, 0x8066, 0x0008, 0x1e0a, 0x0003, 0xc2aa, 0x0000, 0x1826,
-	0x0000, 0x1928, 0x0003, 0x02bb, 0x0000, 0x0806, 0x0008, 0x8010,
-	0x0000, 0x001f, 0x0004, 0x0336, 0x0000, 0x0310, 0x0004, 0x0336,
-	0x0003, 0x02bb, 0x0004, 0x032b, 0x0008, 0x8010, 0x0000, 0x0001,
-	0x0004, 0x0336, 0x0000, 0x1810, 0x0004, 0x0336, 0x0000, 0x8074,
-	0x0008, 0xf000, 0x0000, 0x0d30, 0x0002, 0x3a42, 0x0003, 0x8ac3,
-	0x0000, 0x15fc, 0x0003, 0xb06a, 0x0003, 0x0013, 0x0000, 0x8074,
-	0x0000, 0x0501, 0x0008, 0x8010, 0x0008, 0x000c, 0x0004, 0x0336,
-	0x0003, 0x0013, 0x0009, 0xbbe0, 0x0008, 0x0030, 0x000b, 0x8adf,
-	0x0000, 0x18fe, 0x0009, 0x3ce0, 0x0003, 0x0adc, 0x0008, 0x15fe,
-	0x0009, 0x3ce0, 0x0003, 0x0adc, 0x0008, 0x13fe, 0x0009, 0x3ce0,
-	0x0003, 0x8ad8, 0x0004, 0x0324, 0x0008, 0x0d26, 0x000b, 0x02d9,
-	0x000c, 0x0326, 0x0008, 0x8076, 0x0000, 0x0040, 0x000b, 0x0321,
-	0x0008, 0x8076, 0x0008, 0x0041, 0x000b, 0x0321, 0x0009, 0xbbe0,
-	0x0000, 0x0032, 0x0003, 0x8ae4, 0x0008, 0x3c1e, 0x000b, 0x0321,
-	0x0009, 0xbbe0, 0x0000, 0x0037, 0x000b, 0x8b06, 0x0000, 0x18fe,
-	0x0009, 0x3ce0, 0x000b, 0x8adc, 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, 0x000b, 0xc2fd, 0x0004, 0x032b, 0x0008, 0x8054,
-	0x0000, 0x0004, 0x0000, 0x8074, 0x0008, 0xf000, 0x0000, 0x8072,
-	0x0000, 0x8000, 0x0003, 0x02bd, 0x0009, 0xbbe0, 0x0000, 0x0038,
-	0x000b, 0x8b18, 0x0000, 0x18fe, 0x0009, 0x3ce0, 0x000b, 0x0b15,
-	0x0008, 0x15fe, 0x0009, 0x3ce0, 0x0003, 0x8ad2, 0x000c, 0x0326,
-	0x0008, 0x8076, 0x0000, 0x0040, 0x0000, 0x8072, 0x0000, 0x8000,
-	0x0003, 0x036d, 0x0008, 0x8076, 0x0008, 0x0042, 0x000b, 0x0321,
-	0x0009, 0xbbe0, 0x0000, 0x0016, 0x000b, 0x8b21, 0x0002, 0x3a44,
-	0x0003, 0x8816, 0x0000, 0x8072, 0x0000, 0x8000, 0x000f, 0x8000,
-	0x0003, 0x0013, 0x0000, 0x8072, 0x0000, 0x8000, 0x0003, 0x0013,
-	0x0002, 0x1430, 0x000b, 0x0327, 0x000a, 0x3d30, 0x0000, 0x7f00,
-	0x0001, 0xbc80, 0x0000, 0x0007, 0x0003, 0x032f, 0x000a, 0x1930,
-	0x0000, 0x7f00, 0x0001, 0x9880, 0x0000, 0x0007, 0x0000, 0x8060,
-	0x0000, 0x0400, 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x000a,
-	0x0003, 0xc334, 0x000f, 0x4000, 0x0003, 0x2336, 0x0008, 0x0870,
-	0x000f, 0x4000, 0x0009, 0xbac0, 0x0008, 0x0090, 0x0003, 0x0b3f,
-	0x0000, 0x8074, 0x0000, 0x0706, 0x000b, 0x0341, 0x0000, 0x8074,
-	0x0000, 0x0703, 0x000f, 0x4000, 0x0008, 0x8010, 0x0000, 0x0023,
-	0x000b, 0x037b, 0x0008, 0x8010, 0x0000, 0x0008, 0x000b, 0x037b,
-	0x0008, 0x8010, 0x0008, 0x0022, 0x000b, 0x037b, 0x0004, 0x032b,
-	0x0008, 0x8010, 0x0000, 0x0007, 0x0004, 0x0336, 0x0000, 0x1810,
-	0x0004, 0x0336, 0x0003, 0x0385, 0x0004, 0x032b, 0x0008, 0x8010,
-	0x0008, 0x001b, 0x0004, 0x0336, 0x0000, 0x1810, 0x0004, 0x0336,
-	0x0000, 0x8074, 0x0000, 0xf080, 0x0000, 0x0d30, 0x0003, 0x0013,
-	0x0008, 0x8010, 0x0008, 0x0009, 0x000b, 0x037b, 0x0008, 0x8010,
-	0x0008, 0x0005, 0x000b, 0x037b, 0x0008, 0x808c, 0x0000, 0x0001,
-	0x0007, 0x0000, 0x0008, 0x8010, 0x0000, 0x0004, 0x000a, 0x4143,
-	0x0003, 0x0878, 0x0002, 0x3a44, 0x0003, 0x8813, 0x0008, 0x0d2a,
-	0x000b, 0x037b, 0x0008, 0x8010, 0x0008, 0x0003, 0x000b, 0x037d,
-	0x0008, 0x8010, 0x0000, 0x000b, 0x000b, 0x037d, 0x0008, 0x8010,
-	0x0000, 0x0002, 0x000b, 0x037d, 0x0002, 0x3a47, 0x000b, 0x8a54,
-	0x0008, 0x8010, 0x0008, 0x0006, 0x000b, 0x037d, 0x0000, 0x8074,
-	0x0008, 0xf000, 0x0004, 0x0336, 0x0004, 0x0339, 0x000a, 0x3a40,
-	0x000b, 0x0813, 0x0008, 0x8010, 0x0008, 0x000c, 0x0004, 0x0336,
-	0x0003, 0x0013, 0x0000, 0x8074, 0x0000, 0xf080, 0x0000, 0x0d30,
-	0x0002, 0x2e4d, 0x0002, 0x2e4d, 0x0003, 0x0b8e, 0x0008, 0x8054,
-	0x0000, 0x0019, 0x0003, 0x0013, 0x0008, 0x8054, 0x0008, 0x0009,
-	0x0003, 0x0013, 0x0002, 0x3a44, 0x0003, 0x8813, 0x0003, 0x0370,
-	0xed0b, 0x60bf
-};
-unsigned short rseqflx_code_length01 = 0x072a;
-/*
- *
- */
-
-unsigned long xseqflx_code_addr01 = 0x0001e000 ;
-unsigned short xseqflx_code01[] = { 
-0x0013, 0x0003, 0x0000, 0x1036, 0x0001, 0xe000, 0x0005, 0x0032,
-	0x0000, 0x0010, 0x0015, 0x0033, 0x0010, 0xbb39, 0x000b, 0x8007,
-	0x0004, 0x0107, 0x0004, 0x0119, 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,
-	0x0010, 0xc0c3, 0x0000, 0xc0c4, 0x0010, 0xc0c5, 0x0010, 0xc0c6,
-	0x0000, 0xc0c7, 0x0000, 0xc0c8, 0x0010, 0xc0c9, 0x0010, 0xc0ca,
-	0x0000, 0xc0cb, 0x0010, 0xc0cc, 0x0000, 0xc0cd, 0x0000, 0xc0ce,
-	0x0010, 0xc0cf, 0x0015, 0x0039, 0x0010, 0xff00, 0x0015, 0x003a,
-	0x0010, 0xff00, 0x0005, 0x00d0, 0x0010, 0xff00, 0x0015, 0x00d1,
-	0x0010, 0xff00, 0x0012, 0x3a40, 0x000b, 0x1031, 0x0002, 0x7940,
-	0x000b, 0x112b, 0x0002, 0x3a42, 0x001b, 0x1035, 0x0003, 0xb035,
-	0x0003, 0xa1d1, 0x0002, 0x3a41, 0x001b, 0x1039, 0x0012, 0x7941,
-	0x001b, 0x1306, 0x0013, 0xe051, 0x0012, 0xd042, 0x0003, 0x103f,
-	0x0000, 0x75ff, 0x0002, 0xff41, 0x000b, 0x1051, 0x0000, 0x0cfe,
-	0x0013, 0x6047, 0x0011, 0x02e8, 0x0010, 0x0000, 0x0003, 0x1390,
-	0x0011, 0x02e8, 0x0010, 0x0005, 0x0013, 0x141d, 0x0012, 0xd042,
-	0x0013, 0x104c, 0x0000, 0x75ff, 0x0012, 0xff40, 0x000b, 0x1051,
-	0x0000, 0x12fe, 0x0003, 0x6051, 0x0001, 0x0fe8, 0x0010, 0x0000,
-	0x0013, 0x160e, 0x0015, 0x0030, 0x0000, 0x0400, 0x0010, 0xc131,
-	0x0015, 0x0033, 0x0010, 0xb211, 0x001b, 0x8056, 0x0010, 0xb2ff,
-	0x0001, 0xb3e0, 0x000c, 0x10c9, 0x000b, 0xf02d, 0x0011, 0x3be8,
-	0x0000, 0x0010, 0x000b, 0x106e, 0x0000, 0x0afe, 0x001b, 0x6062,
-	0x0000, 0x3c0b, 0x0013, 0x006a, 0x0015, 0x0030, 0x0000, 0x0400,
-	0x0001, 0x0a88, 0x0010, 0x0003, 0x0000, 0xff31, 0x0015, 0x0033,
-	0x0010, 0x3c0a, 0x001b, 0x8069, 0x0010, 0x3c0a, 0x0002, 0x0c00,
-	0x0010, 0xff0c, 0x0013, 0x00c6, 0x0011, 0x3be8, 0x0010, 0x0012,
-	0x001b, 0x1081, 0x0010, 0x08fe, 0x001b, 0x6075, 0x0010, 0x3c09,
-	0x0013, 0x007d, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0888,
-	0x0010, 0x0003, 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0x3c0a,
-	0x000b, 0x807c, 0x0000, 0x3c08, 0x0002, 0x0c00, 0x0010, 0xff0c,
-	0x0013, 0x00c6, 0x0011, 0x3be8, 0x0000, 0x0013, 0x001b, 0x1087,
-	0x0000, 0x3cb0, 0x0014, 0x00d9, 0x0013, 0x00c6, 0x0011, 0x3be8,
-	0x0000, 0x0019, 0x001b, 0x109a, 0x0010, 0x04fe, 0x000b, 0x608e,
-	0x0010, 0x3c05, 0x0013, 0x0096, 0x0015, 0x0030, 0x0000, 0x0400,
-	0x0011, 0x0488, 0x0010, 0x0003, 0x0000, 0xff31, 0x0015, 0x0033,
-	0x0010, 0x3c0a, 0x001b, 0x8095, 0x0000, 0x3c04, 0x0002, 0x0c00,
-	0x0010, 0xff0c, 0x0013, 0x00c6, 0x0011, 0x3be8, 0x0000, 0x0015,
-	0x001b, 0x10a6, 0x0004, 0x0110, 0x0014, 0x0122, 0x0015, 0x0039,
-	0x0000, 0x8000, 0x0017, 0x8000, 0x0004, 0x0107, 0x0004, 0x0119,
-	0x0014, 0x00f2, 0x0013, 0x002d, 0x0011, 0x3be8, 0x0000, 0x0016,
-	0x001b, 0x10b8, 0x0001, 0x0fe8, 0x0010, 0x0000, 0x0003, 0x10b2,
-	0x0001, 0x0fe8, 0x0000, 0x0002, 0x0003, 0x10b2, 0x0015, 0x0039,
-	0x0010, 0x1010, 0x0013, 0x00c6, 0x0015, 0x0039, 0x0000, 0x5040,
-	0x0015, 0x00b8, 0x0000, 0x0008, 0x0014, 0x0817, 0x0013, 0x00c6,
-	0x0011, 0x3be8, 0x0010, 0x0017, 0x001b, 0x10bd, 0x0010, 0x3cc3,
-	0x0013, 0x00c6, 0x0011, 0x3be8, 0x0010, 0x0018, 0x000b, 0x10c2,
-	0x0000, 0x3cc2, 0x0013, 0x00c6, 0x0005, 0x00ce, 0x0000, 0x0001,
-	0x0000, 0x3bcf, 0x0004, 0x07d9, 0x0015, 0x0039, 0x0000, 0x8000,
-	0x0013, 0x002d, 0x0001, 0xb288, 0x0000, 0x0002, 0x0001, 0xc180,
-	0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x80cf,
-	0x0002, 0xb200, 0x0011, 0xffc8, 0x0000, 0x0007, 0x0010, 0xffb2,
-	0x0010, 0xc131, 0x0015, 0x0033, 0x0010, 0xb20a, 0x0001, 0xb0d0,
-	0x001b, 0x80d8, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0xb088,
-	0x0000, 0x0010, 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xb109,
-	0x000b, 0x80e0, 0x0001, 0xb1e8, 0x0010, 0xffff, 0x0013, 0x10f1,
-	0x0000, 0x11fe, 0x000b, 0x60e8, 0x0000, 0xb012, 0x0013, 0x00f0,
-	0x0015, 0x0030, 0x0000, 0x0400, 0x0001, 0x1188, 0x0010, 0x0003,
-	0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb00a, 0x000b, 0x80ef,
-	0x0000, 0xb011, 0x0017, 0x4000, 0x0015, 0x0030, 0x0000, 0x0400,
-	0x0011, 0xbc88, 0x0010, 0x001e, 0x0000, 0xff31, 0x0015, 0x0033,
-	0x0000, 0xc411, 0x001b, 0x80f9, 0x0011, 0xbc88, 0x0010, 0x0017,
-	0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xc609, 0x001b, 0x80ff,
-	0x0011, 0xbc88, 0x0010, 0x0036, 0x0000, 0xff31, 0x0015, 0x0033,
-	0x0000, 0xc709, 0x000b, 0x8105, 0x0017, 0x4000, 0x0015, 0x0030,
-	0x0000, 0x0400, 0x0001, 0xbb88, 0x0000, 0x0001, 0x0000, 0xff31,
-	0x0015, 0x0033, 0x0000, 0x0269, 0x001b, 0x810e, 0x0017, 0x4000,
-	0x0015, 0x0030, 0x0000, 0x0400, 0x0001, 0xbb88, 0x0000, 0x0001,
-	0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0x026a, 0x000b, 0x8117,
-	0x0017, 0x4000, 0x0015, 0x0030, 0x0000, 0x0400, 0x0001, 0xbb88,
-	0x0010, 0x000f, 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0x0f59,
-	0x001b, 0x8120, 0x0017, 0x4000, 0x0015, 0x0030, 0x0000, 0x0400,
-	0x0001, 0xbb88, 0x0010, 0x000f, 0x0000, 0xff31, 0x0015, 0x0033,
-	0x0010, 0x0f5a, 0x001b, 0x8129, 0x0017, 0x4000, 0x0000, 0xd0ff,
-	0x0012, 0xff40, 0x000b, 0x1031, 0x0015, 0x00d1, 0x0010, 0x0101,
-	0x0003, 0x9130, 0x0005, 0x0079, 0x0000, 0x0001, 0x0003, 0x9133,
-	0x0015, 0x00d1, 0x0000, 0x0100, 0x0011, 0x02e8, 0x0000, 0x0002,
-	0x0013, 0x1156, 0x0011, 0x02e8, 0x0000, 0x0001, 0x0003, 0x116e,
-	0x0011, 0x02e8, 0x0000, 0x0004, 0x0003, 0x118c, 0x0011, 0x02e8,
-	0x0010, 0x0003, 0x0013, 0x11bd, 0x0005, 0x0002, 0x0010, 0x0000,
-	0x0000, 0xc00e, 0x0000, 0xc00d, 0x0010, 0xc003, 0x0015, 0x0030,
-	0x0000, 0x0400, 0x0001, 0xbd88, 0x0010, 0x0009, 0x0000, 0xff31,
-	0x0015, 0x0033, 0x0010, 0xc00a, 0x000b, 0x814e, 0x0000, 0xff31,
-	0x0015, 0x0033, 0x0010, 0xc00a, 0x001b, 0x8152, 0x0012, 0xd042,
-	0x0013, 0x1031, 0x0003, 0x004c, 0x0012, 0x7849, 0x0003, 0x11cb,
-	0x0010, 0x0dfe, 0x0003, 0x6144, 0x0012, 0x0c10, 0x0010, 0xff0c,
-	0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88, 0x0010, 0x0003,
-	0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb309, 0x000b, 0x8163,
-	0x0010, 0xb3fe, 0x0013, 0x616b, 0x0010, 0xb30b, 0x0015, 0x0033,
-	0x0010, 0xc00a, 0x000b, 0x8169, 0x0003, 0x01c0, 0x0000, 0xc00b,
-	0x0010, 0xc00a, 0x0003, 0x01c0, 0x0000, 0x78b0, 0x0012, 0xb044,
-	0x0003, 0x11cb, 0x0002, 0xb049, 0x0003, 0x11cb, 0x0010, 0x71ff,
-	0x0012, 0xff38, 0x0010, 0xff71, 0x0010, 0x0dfe, 0x0003, 0x6142,
-	0x0012, 0x0c10, 0x0010, 0xff0c, 0x0015, 0x0030, 0x0000, 0x0400,
-	0x0011, 0x0d88, 0x0010, 0x0003, 0x0000, 0xff31, 0x0015, 0x0033,
-	0x0000, 0xb309, 0x000b, 0x8181, 0x0010, 0xb3fe, 0x0013, 0x6189,
-	0x0000, 0xb309, 0x0015, 0x0033, 0x0010, 0xc00a, 0x000b, 0x8187,
-	0x0003, 0x01c0, 0x0010, 0xc009, 0x0000, 0xc008, 0x0003, 0x01c0,
-	0x0000, 0x78b0, 0x0012, 0xb044, 0x0003, 0x11cb, 0x0002, 0xb049,
-	0x0003, 0x11cb, 0x0010, 0x71ff, 0x0012, 0xff38, 0x0010, 0xff71,
-	0x0010, 0x0dfe, 0x0003, 0x6142, 0x0012, 0x0c10, 0x0010, 0xff0c,
-	0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88, 0x0010, 0x0003,
-	0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb309, 0x000b, 0x819f,
-	0x0010, 0xb3fe, 0x0013, 0x61a7, 0x0000, 0xb305, 0x0015, 0x0033,
-	0x0010, 0xc00a, 0x000b, 0x81a5, 0x0003, 0x01a9, 0x0010, 0xc005,
-	0x0000, 0xc004, 0x0002, 0x033f, 0x0002, 0xff27, 0x0000, 0x0db8,
-	0x0014, 0x0385, 0x0000, 0x0db8, 0x0014, 0x0817, 0x0015, 0x0030,
-	0x0000, 0x0400, 0x0011, 0xbc88, 0x0010, 0x0000, 0x0000, 0xff31,
-	0x0015, 0x0033, 0x0000, 0xb309, 0x001b, 0x81b6, 0x0011, 0xb3e8,
-	0x0000, 0x0002, 0x000b, 0x1142, 0x0005, 0x0002, 0x0010, 0x0005,
-	0x0003, 0x0144, 0x0012, 0x7849, 0x0003, 0x11cb, 0x0003, 0x0144,
-	0x0000, 0x0db8, 0x0012, 0x0345, 0x000b, 0x11c6, 0x0002, 0x033f,
-	0x0014, 0x0385, 0x0003, 0x0142, 0x0002, 0x033f, 0x0002, 0xff27,
-	0x0014, 0x0385, 0x0014, 0x0817, 0x0003, 0x0142, 0x0015, 0x00b8,
-	0x0000, 0x0001, 0x0015, 0x003a, 0x0010, 0x0101, 0x0014, 0x0817,
-	0x0003, 0x0153, 0x0001, 0x2bd8, 0x0010, 0x0000, 0x0000, 0xffba,
-	0x0013, 0xb1d4, 0x0005, 0x002a, 0x0000, 0x0002, 0x0001, 0xbac8,
-	0x0000, 0x0700, 0x001b, 0x12c1, 0x0011, 0x15e8, 0x0000, 0x0002,
-	0x0003, 0x1237, 0x0011, 0x15e8, 0x0000, 0x0001, 0x0003, 0x11e3,
-	0x0005, 0x0015, 0x0010, 0x0000, 0x0013, 0x021a, 0x0005, 0x0015,
-	0x0010, 0x0000, 0x0002, 0xba43, 0x0013, 0x121b, 0x0013, 0xb1e7,
-	0x0005, 0x002a, 0x0000, 0x0004, 0x0012, 0xba42, 0x0013, 0x1221,
-	0x0012, 0x104b, 0x001b, 0x121a, 0x0000, 0x1a30, 0x0005, 0x0031,
-	0x0000, 0x0002, 0x0015, 0x0033, 0x0000, 0x1b2a, 0x000b, 0x81f3,
-	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, 0x000b, 0x8211, 0x0000, 0x1a30, 0x0005, 0x0031,
-	0x0010, 0x000f, 0x0015, 0x0033, 0x0010, 0xb812, 0x000b, 0x8217,
-	0x0005, 0x0015, 0x0010, 0x0000, 0x0013, 0x0035, 0x0000, 0x1efe,
-	0x0013, 0x622f, 0x0014, 0x0266, 0x0000, 0x1efe, 0x000c, 0x6266,
-	0x0013, 0x021a, 0x0000, 0x1a30, 0x0005, 0x0031, 0x0000, 0x0020,
-	0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x8226, 0x0002, 0xb02f,
-	0x0000, 0xffb0, 0x0005, 0x0031, 0x0000, 0x0020, 0x0015, 0x0033,
-	0x0000, 0xb00a, 0x000b, 0x822d, 0x0003, 0x01ee, 0x0015, 0x00b8,
-	0x0010, 0x0005, 0x0014, 0x0817, 0x0000, 0x13b8, 0x0015, 0x003a,
-	0x0010, 0x0404, 0x0014, 0x0817, 0x0013, 0x021a, 0x0005, 0x0015,
-	0x0000, 0x0001, 0x0012, 0xba42, 0x0003, 0x1245, 0x0003, 0xb23b,
-	0x0001, 0x2bd8, 0x0010, 0x0000, 0x0012, 0xff4f, 0x000b, 0x11d1,
-	0x0002, 0xba43, 0x000b, 0x1221, 0x0000, 0x1efe, 0x000c, 0x6266,
-	0x0013, 0x021a, 0x0001, 0x28d8, 0x0010, 0x0000, 0x0010, 0xffb8,
-	0x0011, 0x29d8, 0x0010, 0x0000, 0x0000, 0xffb9, 0x0014, 0x02d7,
-	0x0002, 0x3a42, 0x001b, 0x121a, 0x0000, 0x1c30, 0x0015, 0x00ff,
-	0x0000, 0x0002, 0x0002, 0x1f43, 0x000b, 0x1256, 0x0001, 0xff88,
-	0x0000, 0x0002, 0x0013, 0x0258, 0x0001, 0xff88, 0x0000, 0x0004,
-	0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb011, 0x001b, 0x825b,
-	0x0000, 0xb0ff, 0x0011, 0x16a0, 0x0000, 0xff16, 0x001b, 0x2262,
-	0x0002, 0xb100, 0x0003, 0x0263, 0x0010, 0xb1ff, 0x0001, 0x17a0,
-	0x0010, 0xff17, 0x0003, 0x0221, 0x0000, 0x16ff, 0x0001, 0x18a0,
-	0x0010, 0xff00, 0x001b, 0x226d, 0x0002, 0x1700, 0x0013, 0x12c0,
-	0x0013, 0x026e, 0x0010, 0x17ff, 0x0011, 0x19a0, 0x0013, 0x22c0,
-	0x0011, 0x00d0, 0x0013, 0x12c0, 0x0000, 0x1c30, 0x0000, 0x1b31,
-	0x0015, 0x0033, 0x0000, 0xb131, 0x001b, 0x8276, 0x0013, 0xb277,
-	0x0000, 0xb120, 0x0010, 0xb221, 0x0002, 0x1f43, 0x001b, 0x1283,
-	0x0010, 0xc022, 0x0000, 0xc023, 0x0000, 0xb324, 0x0000, 0xb425,
-	0x0010, 0xb3b5, 0x0000, 0xb4b6, 0x0003, 0x0287, 0x0000, 0xb322,
-	0x0000, 0xb423, 0x0000, 0xb524, 0x0010, 0xb625, 0x0013, 0xb287,
-	0x0005, 0x002a, 0x0000, 0x0001, 0x0012, 0x1500, 0x0000, 0xff15,
-	0x0000, 0x16ff, 0x0001, 0xb580, 0x0000, 0xff16, 0x001b, 0x2292,
-	0x0002, 0x1700, 0x0003, 0x0293, 0x0010, 0x17ff, 0x0001, 0xb680,
-	0x0010, 0xff17, 0x0012, 0x1e10, 0x0010, 0xff1e, 0x0003, 0x62c0,
-	0x0002, 0x1d00, 0x0010, 0xff1d, 0x0010, 0xc030, 0x0000, 0xff31,
-	0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x829e, 0x0010, 0xb0fe,
-	0x000b, 0x62bf, 0x0000, 0x1c30, 0x0005, 0x0031, 0x0000, 0x0001,
-	0x0015, 0x0033, 0x0000, 0xb009, 0x000b, 0x82a6, 0x0010, 0xb0fe,
-	0x001b, 0x62ac, 0x0005, 0x00ce, 0x0010, 0x0005, 0x0013, 0x07d9,
-	0x0010, 0xb01c, 0x0000, 0x1c30, 0x0005, 0x0031, 0x0000, 0x0019,
-	0x0015, 0x0033, 0x0000, 0xb009, 0x000b, 0x82b2, 0x0001, 0xb0c8,
-	0x0010, 0x00ff, 0x0000, 0xff1f, 0x0010, 0xc030, 0x0011, 0xbe80,
-	0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009, 0x000b, 0x82bb,
-	0x0000, 0xb01d, 0x0010, 0x1dff, 0x0003, 0x029a, 0x0000, 0xb01b,
-	0x0017, 0x4000, 0x0002, 0x3a41, 0x0013, 0x12c9, 0x0013, 0xb2c3,
-	0x0005, 0x002a, 0x0000, 0x0004, 0x0005, 0x0015, 0x0010, 0x0000,
-	0x0013, 0x021a, 0x0000, 0x1a30, 0x0005, 0x0031, 0x0000, 0x0002,
-	0x0015, 0x0033, 0x0000, 0x1b2a, 0x001b, 0x82ce, 0x0015, 0x00b8,
-	0x0000, 0x0004, 0x0014, 0x0817, 0x0000, 0x13b8, 0x0015, 0x003a,
-	0x0010, 0x0404, 0x0014, 0x0817, 0x0013, 0x0039, 0x0002, 0x1e00,
-	0x0010, 0xff1e, 0x0012, 0x1d10, 0x0010, 0xff1d, 0x0010, 0xc030,
-	0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x82df,
-	0x0010, 0xb0fe, 0x001b, 0x6304, 0x0000, 0x1cff, 0x0001, 0x1ae0,
-	0x0013, 0x12ee, 0x0000, 0x1c30, 0x0005, 0x0031, 0x0010, 0x0000,
-	0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x82ea, 0x0010, 0xb0fe,
-	0x001b, 0x62ee, 0x0000, 0x1aff, 0x0000, 0xff1c, 0x0000, 0x1c30,
-	0x0005, 0x0031, 0x0000, 0x0019, 0x0015, 0x0033, 0x0000, 0xb009,
-	0x001b, 0x82f4, 0x0001, 0xb0c8, 0x0010, 0x000f, 0x0000, 0xff1f,
-	0x0001, 0xbf80, 0x0010, 0xff1d, 0x0010, 0xc030, 0x0000, 0xff31,
-	0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x82fe, 0x0010, 0xb0fe,
-	0x001b, 0x6304, 0x0005, 0x00ce, 0x0010, 0x0006, 0x0013, 0x07d9,
-	0x0000, 0xb01b, 0x0017, 0x4000, 0x0010, 0x79b0, 0x0000, 0xd0ff,
-	0x0012, 0xff40, 0x001b, 0x1039, 0x0015, 0x00d1, 0x0010, 0x0101,
-	0x0013, 0x930c, 0x0005, 0x0079, 0x0000, 0x0002, 0x0013, 0x930f,
-	0x0015, 0x00d1, 0x0000, 0x0100, 0x0010, 0x13fe, 0x0013, 0x6344,
-	0x0012, 0xb04e, 0x000b, 0x135d, 0x0012, 0x784a, 0x0003, 0x1363,
-	0x0000, 0x75ff, 0x0011, 0xffc8, 0x0010, 0x1800, 0x001b, 0x1363,
-	0x0001, 0x0fe8, 0x0000, 0x0001, 0x001b, 0x1328, 0x0015, 0x0030,
-	0x0000, 0x0400, 0x0011, 0x1388, 0x0000, 0x000e, 0x0000, 0xff31,
-	0x0015, 0x0033, 0x0000, 0x8f0a, 0x000b, 0x8326, 0x0013, 0x0369,
-	0x0001, 0x0fe8, 0x0000, 0x0002, 0x001b, 0x1333, 0x0015, 0x0030,
-	0x0000, 0x0400, 0x0005, 0x0031, 0x0000, 0x001a, 0x0015, 0x0033,
-	0x0010, 0xc00a, 0x000b, 0x8331, 0x0013, 0x0369, 0x0001, 0x0fe8,
-	0x0010, 0x0000, 0x0003, 0x133a, 0x0005, 0x00ce, 0x0000, 0x0007,
-	0x0010, 0x0fcf, 0x0013, 0x07d3, 0x0000, 0x13b8, 0x0002, 0x1045,
-	0x0003, 0x1342, 0x0012, 0x103f, 0x0002, 0xff27, 0x0014, 0x0385,
-	0x0014, 0x0817, 0x0013, 0x0344, 0x0012, 0x103f, 0x0014, 0x0385,
-	0x0015, 0x000f, 0x0010, 0x0000, 0x0002, 0x3944, 0x0003, 0x134d,
-	0x0015, 0x0039, 0x0000, 0x5040, 0x0015, 0x00b8, 0x0000, 0x0008,
-	0x0014, 0x0817, 0x0015, 0x0030, 0x0000, 0x0400, 0x0001, 0xbd88,
-	0x0010, 0x000c, 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xc00a,
-	0x000b, 0x8354, 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xc00a,
-	0x000b, 0x8358, 0x0010, 0xc014, 0x0000, 0xc013, 0x0000, 0xc010,
-	0x0013, 0x0039, 0x0015, 0x00b8, 0x0010, 0x0003, 0x0015, 0x003a,
-	0x0010, 0x0202, 0x0014, 0x0817, 0x0013, 0x035c, 0x0015, 0x00b8,
-	0x0000, 0x0002, 0x0015, 0x003a, 0x0010, 0x0202, 0x0014, 0x0817,
-	0x0013, 0x035c, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x1388,
-	0x0010, 0x0003, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009,
-	0x000b, 0x8370, 0x0011, 0x1388, 0x0010, 0x0003, 0x0000, 0xff31,
-	0x0015, 0x0033, 0x0010, 0xc00a, 0x000b, 0x8376, 0x0010, 0xb0fe,
-	0x0013, 0x637b, 0x0000, 0xb012, 0x0013, 0x037d, 0x0010, 0xc012,
-	0x0010, 0xc011, 0x0012, 0x104b, 0x0003, 0x133a, 0x0002, 0x103b,
-	0x0010, 0xff03, 0x0005, 0x0002, 0x0010, 0x0000, 0x0000, 0xc00d,
-	0x0013, 0x033a, 0x0000, 0xffb0, 0x0010, 0xc3b1, 0x0015, 0x0030,
-	0x0000, 0x0400, 0x0001, 0xb888, 0x0010, 0x0011, 0x0000, 0xff31,
-	0x0015, 0x0033, 0x0000, 0xb012, 0x001b, 0x838e, 0x0017, 0x4000,
-	0x0012, 0x3a43, 0x0003, 0x139f, 0x0015, 0x003a, 0x0000, 0x0800,
-	0x0010, 0x0db0, 0x0013, 0x639f, 0x0000, 0x0bff, 0x0001, 0xb0e0,
-	0x0003, 0x13c5, 0x0010, 0x09ff, 0x0001, 0xb0e0, 0x0003, 0x13a9,
-	0x0010, 0x05ff, 0x0001, 0xb0e0, 0x0003, 0x13a3, 0x0000, 0xc00e,
-	0x0000, 0x05fe, 0x0013, 0x63a6, 0x0000, 0x050d, 0x0005, 0x0002,
-	0x0000, 0x0004, 0x0013, 0x03c0, 0x0000, 0x09fe, 0x0003, 0x63c2,
-	0x0000, 0x090d, 0x0005, 0x0002, 0x0000, 0x0001, 0x0014, 0x0424,
-	0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88, 0x0000, 0x0004,
-	0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xba09, 0x000b, 0x83b3,
-	0x0011, 0x03c8, 0x0010, 0x000f, 0x0000, 0xffb6, 0x0011, 0xb6e8,
-	0x0000, 0x0001, 0x0013, 0x14bb, 0x0011, 0xb6e8, 0x0000, 0x0002,
-	0x0013, 0x14dd, 0x0011, 0xb6e8, 0x0010, 0x0003, 0x0003, 0x15cc,
-	0x0014, 0x07de, 0x0013, 0x0423, 0x0010, 0x0bfe, 0x0013, 0x6423,
-	0x0010, 0x0b0d, 0x0005, 0x0002, 0x0000, 0x0002, 0x0014, 0x0424,
-	0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88, 0x0000, 0x0004,
-	0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xba09, 0x001b, 0x83cf,
-	0x0000, 0xb930, 0x0005, 0x0031, 0x0010, 0x0021, 0x0015, 0x0033,
-	0x0000, 0xb009, 0x000b, 0x83d5, 0x0001, 0xb0a8, 0x0000, 0x199a,
-	0x0003, 0x23db, 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,
-	0x001b, 0x83e8, 0x0000, 0xb930, 0x0005, 0x0031, 0x0000, 0x0019,
-	0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x83ee, 0x0001, 0xb0c8,
-	0x0010, 0x00ff, 0x0001, 0xffe8, 0x0010, 0x0048, 0x000b, 0x1433,
-	0x0005, 0x0002, 0x0010, 0x0006, 0x0012, 0x0c10, 0x0010, 0xff0c,
-	0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88, 0x0010, 0x0003,
-	0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xb109, 0x001b, 0x83ff,
-	0x0000, 0xb10b, 0x001b, 0x6403, 0x0010, 0xb10a, 0x0015, 0x0033,
-	0x0010, 0xc00a, 0x000b, 0x8405, 0x0002, 0x032b, 0x0010, 0xff03,
-	0x0011, 0x0d88, 0x0010, 0x0011, 0x0000, 0xff31, 0x0015, 0x0033,
-	0x0010, 0x030a, 0x001b, 0x840d, 0x0000, 0x11fe, 0x001b, 0x6412,
-	0x0000, 0x0d12, 0x0003, 0x041b, 0x0015, 0x0030, 0x0000, 0x0400,
-	0x0001, 0x1188, 0x0010, 0x0003, 0x0000, 0xff31, 0x0010, 0x0db0,
-	0x0015, 0x0033, 0x0000, 0xb00a, 0x001b, 0x841a, 0x0000, 0x0d11,
-	0x0013, 0x0423, 0x0000, 0x05fe, 0x0013, 0x6423, 0x0005, 0x0002,
-	0x0000, 0x0004, 0x0000, 0x050d, 0x0014, 0x07de, 0x0013, 0x0047,
-	0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88, 0x0010, 0x0011,
-	0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0x0309, 0x000b, 0x842b,
-	0x0011, 0x0d88, 0x0010, 0x0005, 0x0000, 0xff31, 0x0015, 0x0033,
-	0x0000, 0xb909, 0x001b, 0x8431, 0x0017, 0x4000, 0x0005, 0x00b6,
-	0x0010, 0x0600, 0x0004, 0x05fc, 0x0014, 0x04a5, 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, 0x8443,
-	0x0000, 0xb05c, 0x0005, 0x0031, 0x0000, 0x001f, 0x0015, 0x0033,
-	0x0000, 0xb009, 0x001b, 0x8449, 0x0001, 0xb0c8, 0x0010, 0x000f,
-	0x000b, 0x1450, 0x0015, 0x00ff, 0x0010, 0x0005, 0x0013, 0x0458,
-	0x0002, 0xb040, 0x0013, 0x1455, 0x0015, 0x00ff, 0x0000, 0x0004,
-	0x0013, 0x0458, 0x0001, 0xb0c8, 0x0010, 0x0006, 0x0002, 0xff60,
-	0x0010, 0xffb2, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88,
-	0x0000, 0x0019, 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xb109,
-	0x000b, 0x8460, 0x0012, 0xb170, 0x0011, 0xffc8, 0x0010, 0xff00,
-	0x0011, 0xb2d0, 0x0010, 0xff60, 0x0002, 0xb045, 0x0003, 0x146b,
-	0x0015, 0x00b2, 0x0000, 0x0002, 0x0013, 0x0475, 0x0002, 0xb046,
-	0x0003, 0x1470, 0x0015, 0x00b2, 0x0000, 0x0001, 0x0013, 0x0475,
-	0x0015, 0x00b2, 0x0010, 0x0000, 0x0000, 0xc0b0, 0x0010, 0xc0b1,
-	0x0003, 0x047b, 0x0000, 0xb930, 0x0005, 0x0031, 0x0010, 0x002b,
-	0x0015, 0x0033, 0x0000, 0xb011, 0x001b, 0x847a, 0x0010, 0xb16a,
-	0x0010, 0xb06b, 0x0000, 0xb261, 0x0015, 0x0044, 0x0010, 0x0018,
-	0x0000, 0xb930, 0x0005, 0x0031, 0x0000, 0x0023, 0x0015, 0x0033,
-	0x0000, 0x6241, 0x001b, 0x8485, 0x0013, 0x9486, 0x0015, 0x00a0,
-	0x0000, 0x0020, 0x0012, 0xd041, 0x001b, 0x1489, 0x0015, 0x00d1,
-	0x0010, 0x0202, 0x0003, 0x948d, 0x0000, 0x75ff, 0x0011, 0xffc8,
-	0x0000, 0x1804, 0x0001, 0xffd8, 0x0010, 0x0009, 0x0003, 0x9493,
-	0x0000, 0xff75, 0x0003, 0x9495, 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, 0x84a3,
-	0x0013, 0x0423, 0x0000, 0xba30, 0x0005, 0x0031, 0x0000, 0x0031,
-	0x0015, 0x0033, 0x0000, 0xb009, 0x000b, 0x84aa, 0x0002, 0xb040,
-	0x0013, 0x14b8, 0x0000, 0xb7b0, 0x0000, 0xb9b1, 0x0015, 0x0030,
-	0x0000, 0x0400, 0x0011, 0x0d88, 0x0000, 0x0013, 0x0000, 0xff31,
-	0x0015, 0x0033, 0x0000, 0xb012, 0x001b, 0x84b6, 0x0013, 0x04ba,
-	0x0010, 0xc0b1, 0x0000, 0xc0b0, 0x0017, 0x4000, 0x0005, 0x00b6,
-	0x0010, 0x0500, 0x0004, 0x05fc, 0x0005, 0x0054, 0x0010, 0x0889,
-	0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88, 0x0000, 0x0002,
-	0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x84c7,
-	0x0010, 0xb058, 0x0000, 0x0d59, 0x0000, 0xb930, 0x0005, 0x0031,
-	0x0000, 0x0023, 0x0015, 0x0033, 0x0000, 0xb011, 0x000b, 0x84cf,
-	0x0010, 0xb15c, 0x0010, 0xb05d, 0x0005, 0x0031, 0x0010, 0x002b,
-	0x0015, 0x0033, 0x0000, 0xb011, 0x001b, 0x84d6, 0x0000, 0xb15e,
-	0x0000, 0xb05f, 0x0013, 0x94d9, 0x0015, 0x00a0, 0x0010, 0x000c,
-	0x0013, 0x05e1, 0x0005, 0x00b6, 0x0000, 0x0700, 0x0004, 0x05fc,
-	0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88, 0x0010, 0x0009,
-	0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xb709, 0x000b, 0x84e7,
-	0x0012, 0xb749, 0x0013, 0x14ed, 0x0005, 0x0054, 0x0010, 0x0889,
-	0x0013, 0x04ef, 0x0005, 0x0054, 0x0010, 0x0898, 0x0015, 0x0030,
-	0x0000, 0x0400, 0x0011, 0x0d88, 0x0000, 0x0002, 0x0000, 0xff31,
-	0x0015, 0x0033, 0x0000, 0xb009, 0x000b, 0x84f6, 0x0010, 0xb058,
-	0x0000, 0x0d59, 0x0001, 0xb9a8, 0x0010, 0x00f0, 0x001b, 0x251d,
-	0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88, 0x0010, 0x0005,
-	0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x8503,
-	0x0001, 0xb0c8, 0x0000, 0xf700, 0x0000, 0xffb0, 0x0011, 0xb0e8,
-	0x0000, 0xf100, 0x0013, 0x1564, 0x0011, 0xb0e8, 0x0000, 0xf200,
-	0x0003, 0x1569, 0x0011, 0xb0e8, 0x0010, 0xf300, 0x0003, 0x158e,
-	0x0011, 0xb0e8, 0x0000, 0xf400, 0x0003, 0x1593, 0x0011, 0xb0e8,
-	0x0010, 0xf500, 0x0013, 0x1564, 0x0011, 0xb0e8, 0x0010, 0xf600,
-	0x0013, 0x15a4, 0x0005, 0x00ce, 0x0010, 0x0009, 0x0000, 0xb0cf,
-	0x0013, 0x07d3, 0x0000, 0xb930, 0x0005, 0x0031, 0x0000, 0x0025,
-	0x0015, 0x0033, 0x0000, 0xb039, 0x001b, 0x8522, 0x0012, 0xb749,
-	0x0003, 0x1527, 0x0002, 0xb52c, 0x0000, 0xffb5, 0x0000, 0xb162,
-	0x0000, 0xb063, 0x0005, 0x0031, 0x0000, 0x001f, 0x0015, 0x0033,
-	0x0000, 0xb309, 0x001b, 0x852d, 0x0001, 0xb3c8, 0x0010, 0x0003,
-	0x0003, 0x1535, 0x0010, 0xffb2, 0x0001, 0xffe8, 0x0010, 0x0003,
-	0x000b, 0x1537, 0x0000, 0xc2b7, 0x0013, 0x05c0, 0x0001, 0xb2e8,
-	0x0000, 0x0001, 0x0013, 0x153e, 0x0005, 0x00ce, 0x0010, 0x000a,
-	0x0010, 0xb2cf, 0x0013, 0x07d3, 0x0010, 0xb465, 0x0010, 0xb667,
-	0x0015, 0x00b7, 0x0010, 0x0018, 0x0001, 0xb5c8, 0x0010, 0x0300,
-	0x0003, 0x1563, 0x0012, 0xb548, 0x0013, 0x154a, 0x0000, 0xb6ff,
-	0x0011, 0xb780, 0x0010, 0xffb7, 0x0002, 0xb549, 0x0013, 0x154f,
-	0x0010, 0xb4ff, 0x0011, 0xb780, 0x0010, 0xffb7, 0x0015, 0x0044,
-	0x0010, 0x0018, 0x0005, 0x0031, 0x0000, 0x002c, 0x0015, 0x0033,
-	0x0000, 0x6841, 0x001b, 0x8555, 0x0015, 0x0044, 0x0000, 0x0019,
-	0x0005, 0x0031, 0x0000, 0x0034, 0x0015, 0x0033, 0x0000, 0x5029,
-	0x001b, 0x855c, 0x0015, 0x0044, 0x0000, 0x0008, 0x0011, 0xb7c8,
-	0x0010, 0x0003, 0x0003, 0x1563, 0x0010, 0xff55, 0x0013, 0x05c0,
-	0x0005, 0x00b5, 0x0000, 0x0008, 0x0015, 0x00b7, 0x0010, 0x0018,
-	0x0013, 0x05c0, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88,
-	0x0000, 0x000b, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb011,
-	0x000b, 0x8570, 0x0010, 0xb1ff, 0x0001, 0xb0d0, 0x0013, 0x1579,
-	0x0005, 0x00b5, 0x0010, 0x0b02, 0x0010, 0xb062, 0x0010, 0xb163,
-	0x0013, 0x057b, 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, 0x05c0, 0x0005, 0x00b5, 0x0010, 0x0028,
-	0x0015, 0x00b7, 0x0010, 0x0018, 0x0013, 0x05c0, 0x0005, 0x00b5,
-	0x0000, 0x0100, 0x0005, 0x0067, 0x0000, 0x0008, 0x0015, 0x0030,
-	0x0000, 0x0400, 0x0011, 0x0d88, 0x0010, 0x0018, 0x0000, 0xff31,
-	0x0015, 0x0033, 0x0000, 0xb009, 0x000b, 0x859e, 0x0001, 0xb0c8,
-	0x0010, 0x00ff, 0x0015, 0x00b7, 0x0000, 0x0020, 0x0013, 0x05c0,
-	0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88, 0x0010, 0x0005,
-	0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb609, 0x000b, 0x85ab,
-	0x0001, 0xb6c8, 0x0010, 0xff00, 0x0000, 0xffb0, 0x0015, 0x0033,
-	0x0000, 0xb00a, 0x001b, 0x85b1, 0x0001, 0xb6c8, 0x0010, 0x00ff,
-	0x0012, 0xff10, 0x000b, 0x15ba, 0x0000, 0xffb5, 0x0015, 0x00b7,
-	0x0010, 0x0018, 0x0013, 0x05c0, 0x0010, 0xff63, 0x0005, 0x00b5,
-	0x0000, 0x0800, 0x0015, 0x00b7, 0x0010, 0x0018, 0x0013, 0x05c0,
-	0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88, 0x0010, 0x0009,
-	0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009, 0x000b, 0x85c7,
-	0x0010, 0xb561, 0x0013, 0x95c9, 0x0010, 0xb7a0, 0x0013, 0x05e1,
-	0x0005, 0x00b6, 0x0010, 0x0300, 0x0004, 0x05fc, 0x0005, 0x0054,
-	0x0010, 0x0819, 0x0010, 0x0d58, 0x0015, 0x0030, 0x0000, 0x0400,
-	0x0011, 0x0d88, 0x0000, 0x0002, 0x0000, 0xff31, 0x0015, 0x0033,
-	0x0000, 0xb009, 0x000b, 0x85d9, 0x0000, 0xb059, 0x0013, 0x95db,
-	0x0010, 0xc0a0, 0x0010, 0x71ff, 0x0002, 0xff28, 0x0010, 0xff71,
-	0x0013, 0x05e1, 0x0012, 0xd041, 0x001b, 0x15e1, 0x0015, 0x00d1,
-	0x0010, 0x0202, 0x0000, 0x75ff, 0x0011, 0xffc8, 0x0000, 0x1804,
-	0x0001, 0xffd8, 0x0010, 0x0009, 0x0003, 0x95ea, 0x0000, 0xff75,
-	0x0003, 0x95ec, 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, 0x85fa, 0x0013, 0x0423,
-	0x0015, 0x0044, 0x0000, 0x0008, 0x0005, 0x0098, 0x0010, 0x0056,
-	0x0015, 0x0099, 0x0000, 0x9575, 0x0014, 0x079a, 0x0000, 0xb096,
-	0x0012, 0xb270, 0x0010, 0xff56, 0x0004, 0x07bc, 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, 0x8615, 0x0015, 0x000f, 0x0000, 0x0001,
-	0x0010, 0xc014, 0x0000, 0x1213, 0x0015, 0x0030, 0x0000, 0x0400,
-	0x0011, 0x1388, 0x0000, 0x0004, 0x0000, 0xff31, 0x0015, 0x0033,
-	0x0000, 0xba09, 0x001b, 0x8621, 0x0015, 0x0030, 0x0000, 0x0400,
-	0x0011, 0x1388, 0x0010, 0x0005, 0x0000, 0xff31, 0x0015, 0x0033,
-	0x0000, 0x1a09, 0x000b, 0x8629, 0x0012, 0x104b, 0x000b, 0x1632,
-	0x0000, 0x1a30, 0x0005, 0x0031, 0x0000, 0x000b, 0x0015, 0x0033,
-	0x0000, 0x1621, 0x000b, 0x8631, 0x0010, 0x15fe, 0x001b, 0x663b,
-	0x0004, 0x0659, 0x0002, 0x3a42, 0x000b, 0x1658, 0x0001, 0x10c8,
-	0x0010, 0x000f, 0x001b, 0x16bb, 0x0003, 0x0657, 0x0015, 0x0030,
-	0x0000, 0x0400, 0x0011, 0x1388, 0x0010, 0x0003, 0x0000, 0xff31,
-	0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x8642, 0x0015, 0x0033,
-	0x0010, 0xc00a, 0x000b, 0x8645, 0x0010, 0xb0fe, 0x0003, 0x664a,
-	0x0000, 0xb012, 0x0003, 0x064c, 0x0010, 0xc012, 0x0010, 0xc011,
-	0x0015, 0x000f, 0x0010, 0x0000, 0x0002, 0x3944, 0x0003, 0x1655,
-	0x0015, 0x0039, 0x0000, 0x5040, 0x0015, 0x00b8, 0x0000, 0x0008,
-	0x0014, 0x0817, 0x0000, 0xc013, 0x0003, 0x0658, 0x0014, 0x0803,
-	0x0003, 0x0051, 0x0003, 0xb659, 0x0005, 0x002a, 0x0000, 0x0004,
-	0x0000, 0xba30, 0x0005, 0x0031, 0x0010, 0x001b, 0x0015, 0x0033,
-	0x0000, 0xb009, 0x000b, 0x8661, 0x0000, 0xc02c, 0x0000, 0xb02d,
-	0x0012, 0x104b, 0x0013, 0x167c, 0x0000, 0x1a30, 0x0005, 0x0031,
-	0x0000, 0x0023, 0x0015, 0x0033, 0x0000, 0xb129, 0x000b, 0x866b,
-	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, 0x06b2,
-	0x0012, 0x1044, 0x0003, 0x16ac, 0x0002, 0x1034, 0x0000, 0xff10,
-	0x0000, 0x1a30, 0x0005, 0x0031, 0x0000, 0x0002, 0x0015, 0x0033,
-	0x0000, 0x1b29, 0x000b, 0x8685, 0x0000, 0x1c30, 0x0000, 0x1b31,
-	0x0015, 0x0033, 0x0000, 0xb131, 0x000b, 0x868a, 0x0002, 0x1f43,
-	0x000b, 0x1691, 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, 0x86a0, 0x0000, 0xb028, 0x0000, 0xb129, 0x0012, 0x1e10,
-	0x0010, 0xff1e, 0x0013, 0x66b2, 0x0002, 0x1d00, 0x0010, 0xff1d,
-	0x0014, 0x029a, 0x0002, 0x3a42, 0x0003, 0x16b2, 0x0003, 0x06ba,
-	0x0000, 0x1a30, 0x0005, 0x0031, 0x0000, 0x0002, 0x0015, 0x0033,
-	0x0000, 0x1b79, 0x001b, 0x86b1, 0x0003, 0xb6b2, 0x0005, 0x002a,
-	0x0000, 0x0001, 0x0005, 0x0015, 0x0000, 0x0001, 0x0000, 0x1efe,
-	0x0003, 0x66ba, 0x0003, 0x0266, 0x0017, 0x4000, 0x0000, 0xba30,
-	0x0005, 0x0031, 0x0010, 0x001b, 0x0015, 0x0033, 0x0010, 0xb051,
-	0x001b, 0x86c0, 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, 0x86cd, 0x0004, 0x07bc, 0x0004, 0x07ab,
-	0x0012, 0xb470, 0x0010, 0xffb4, 0x0010, 0xb48e, 0x0010, 0xb08a,
-	0x0010, 0xb18b, 0x0012, 0x104d, 0x0003, 0x16d8, 0x0003, 0x0705,
-	0x0012, 0x104b, 0x0003, 0x16eb, 0x0005, 0x008c, 0x0010, 0x0829,
-	0x0010, 0xc08d, 0x0001, 0xb2d8, 0x0010, 0x0600, 0x0010, 0xff88,
-	0x0010, 0xb389, 0x0000, 0x1390, 0x0010, 0xb591, 0x0000, 0xc08f,
-	0x0010, 0x1ab9, 0x0014, 0x04a5, 0x0003, 0x96e6, 0x0010, 0xb092,
-	0x0010, 0xb193, 0x0003, 0x96e9, 0x0003, 0x0700, 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, 0x86fb,
-	0x0013, 0x96fc, 0x0000, 0xb192, 0x0000, 0xb093, 0x0013, 0x96ff,
-	0x0010, 0x19a1, 0x0000, 0x18a2, 0x0015, 0x00b1, 0x0010, 0x0096,
-	0x0013, 0x0776, 0x0000, 0xb590, 0x0010, 0x1391, 0x0001, 0x10c8,
-	0x0010, 0x000f, 0x0001, 0xffe8, 0x0010, 0x0005, 0x0003, 0x172c,
-	0x0001, 0xb2d8, 0x0000, 0x0700, 0x0010, 0xff88, 0x0010, 0xb389,
-	0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x1388, 0x0010, 0x0009,
-	0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009, 0x000b, 0x8717,
-	0x0002, 0xb049, 0x0003, 0x171f, 0x0005, 0x008c, 0x0010, 0x0889,
-	0x0015, 0x00b1, 0x0010, 0x0096, 0x0013, 0x0723, 0x0005, 0x008c,
-	0x0010, 0x0898, 0x0015, 0x00b1, 0x0000, 0x0092, 0x0010, 0xc08d,
-	0x0000, 0xc08f, 0x0013, 0x9725, 0x0000, 0xc092, 0x0010, 0xc093,
-	0x0003, 0x9728, 0x0010, 0x19a1, 0x0000, 0x18a2, 0x0013, 0x0776,
-	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, 0x873b,
-	0x0010, 0xb08f, 0x0000, 0xb590, 0x0010, 0x1391, 0x0000, 0x1a30,
-	0x0005, 0x0031, 0x0000, 0x000d, 0x0015, 0x0033, 0x0000, 0xb021,
-	0x000b, 0x8744, 0x0013, 0x9745, 0x0010, 0xb392, 0x0010, 0xb293,
-	0x0003, 0x9748, 0x0000, 0xb1a1, 0x0010, 0xb0a2, 0x0015, 0x0030,
-	0x0000, 0x0400, 0x0011, 0x1388, 0x0000, 0x000b, 0x0000, 0xff31,
-	0x0015, 0x0033, 0x0010, 0xb211, 0x001b, 0x8752, 0x0000, 0xb3ff,
-	0x0001, 0xb080, 0x0000, 0xffb3, 0x000b, 0x2759, 0x0002, 0xb200,
-	0x0003, 0x075a, 0x0010, 0xb2ff, 0x0011, 0xb180, 0x0010, 0xffb2,
-	0x0011, 0x1388, 0x0000, 0x000b, 0x0000, 0xff31, 0x0015, 0x0033,
-	0x0010, 0xb212, 0x001b, 0x8761, 0x0015, 0x00b1, 0x0000, 0x0092,
-	0x0002, 0x104c, 0x0013, 0x1774, 0x0011, 0xc2e8, 0x0010, 0x000c,
-	0x000b, 0x176c, 0x0015, 0x00ff, 0x0000, 0x0800, 0x0003, 0x0774,
-	0x0011, 0xc2e8, 0x0000, 0x0020, 0x000b, 0x1772, 0x0015, 0x00ff,
-	0x0010, 0x1800, 0x0003, 0x0774, 0x0015, 0x00ff, 0x0000, 0x1000,
-	0x0011, 0xb1d0, 0x0010, 0xffb1, 0x0015, 0x009a, 0x0010, 0x0036,
-	0x0005, 0x009b, 0x0000, 0x95d5, 0x0012, 0xd041, 0x001b, 0x177a,
-	0x0015, 0x00d1, 0x0010, 0x0202, 0x0003, 0x977e, 0x0012, 0x104e,
-	0x0003, 0x1783, 0x0012, 0xb12f, 0x0010, 0xffb1, 0x0000, 0xb175,
-	0x0003, 0x9784, 0x0015, 0x00d1, 0x0000, 0x0200, 0x0001, 0x19c8,
-	0x0010, 0xfff0, 0x000b, 0x178d, 0x0015, 0x00b1, 0x0010, 0x07d0,
-	0x0013, 0x078f, 0x0015, 0x00b1, 0x0000, 0x1b58, 0x0005, 0x00b0,
-	0x0010, 0x0009, 0x0015, 0x0030, 0x0000, 0x0400, 0x0001, 0xbd88,
-	0x0000, 0x000b, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb012,
-	0x001b, 0x8798, 0x0003, 0x0658, 0x0000, 0xba30, 0x0005, 0x0031,
-	0x0010, 0x0021, 0x0015, 0x0033, 0x0010, 0xb019, 0x000b, 0x879f,
-	0x0002, 0xb200, 0x0011, 0xffc8, 0x0010, 0x00ff, 0x0010, 0xffb2,
-	0x0010, 0xb2b7, 0x0005, 0x0031, 0x0000, 0x0023, 0x0015, 0x0033,
-	0x0010, 0xb20a, 0x000b, 0x87a9, 0x0017, 0x4000, 0x0000, 0xba30,
-	0x0005, 0x0031, 0x0000, 0x0023, 0x0015, 0x0033, 0x0010, 0xb409,
-	0x001b, 0x87b0, 0x0002, 0xb400, 0x0011, 0xffc8, 0x0010, 0x00ff,
-	0x0010, 0xffb4, 0x0010, 0xb4b7, 0x0005, 0x0031, 0x0000, 0x0023,
-	0x0015, 0x0033, 0x0010, 0xb40a, 0x001b, 0x87ba, 0x0017, 0x4000,
-	0x0000, 0xba30, 0x0001, 0xc7c8, 0x0000, 0x0020, 0x001b, 0x17c8,
-	0x0005, 0x0031, 0x0010, 0x0028, 0x0015, 0x0033, 0x0010, 0xb209,
-	0x001b, 0x87c4, 0x0011, 0xb2c8, 0x0000, 0xff80, 0x0003, 0x17cb,
-	0x0010, 0xc4b0, 0x0010, 0xc5b1, 0x0013, 0x07cd, 0x0010, 0xc6b1,
-	0x0000, 0xc0b0, 0x0005, 0x0031, 0x0000, 0x0004, 0x0015, 0x0033,
-	0x0010, 0xb211, 0x000b, 0x87d1, 0x0017, 0x4000, 0x0015, 0x00b8,
-	0x0010, 0x0009, 0x0015, 0x003a, 0x0010, 0x0707, 0x0014, 0x0817,
-	0x0013, 0x002d, 0x0015, 0x00b8, 0x0010, 0x0009, 0x0015, 0x003a,
-	0x0010, 0x0707, 0x0003, 0x0817, 0x0004, 0x0110, 0x0015, 0x0030,
-	0x0000, 0x0400, 0x0011, 0x0d88, 0x0000, 0x0004, 0x0000, 0xff31,
-	0x0015, 0x0033, 0x0000, 0xba09, 0x001b, 0x87e6, 0x0014, 0x079a,
-	0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88, 0x0000, 0x0010,
-	0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xb20a, 0x001b, 0x87ef,
-	0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88, 0x0010, 0x0011,
-	0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0x0309, 0x001b, 0x87f7,
-	0x0002, 0x0327, 0x0010, 0xffb2, 0x0011, 0x0d88, 0x0010, 0x0011,
-	0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xb20a, 0x000b, 0x87ff,
-	0x0015, 0x00b8, 0x0010, 0x0006, 0x0003, 0x0817, 0x0014, 0x0122,
-	0x0014, 0x079a, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x1388,
-	0x0000, 0x0010, 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xb20a,
-	0x000b, 0x880c, 0x0012, 0x1027, 0x0010, 0xffb2, 0x0011, 0x1388,
-	0x0010, 0x0011, 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xb20a,
-	0x000b, 0x8814, 0x0015, 0x00b8, 0x0000, 0x0007, 0x0013, 0x4817,
-	0x0000, 0xb838, 0x0017, 0x4000, 0xa595, 0x1d35
-};
-unsigned short xseqflx_code_length01 = 0x1036;
diff -Nru a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
--- a/drivers/scsi/qla2xxx/qla_def.h	2005-03-01 23:38:58 -08:00
+++ b/drivers/scsi/qla2xxx/qla_def.h	2005-03-01 23:38:58 -08:00
@@ -89,13 +89,9 @@
 
 #if defined(CONFIG_SCSI_QLA6312) || defined(CONFIG_SCSI_QLA6312_MODULE)
 #define IS_QLA6312(ha)	((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP6312)
-#else
-#define IS_QLA6312(ha)	0
-#endif
-
-#if defined(CONFIG_SCSI_QLA6322) || defined(CONFIG_SCSI_QLA6322_MODULE)
 #define IS_QLA6322(ha)	((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP6322)
 #else
+#define IS_QLA6312(ha)	0
 #define IS_QLA6322(ha)	0
 #endif
 
@@ -346,6 +342,8 @@
 	volatile uint16_t nvram;	/* NVRAM register. */
 #define NVR_DESELECT		0
 #define NVR_BUSY		BIT_15
+#define NVR_WRT_ENABLE		BIT_14	/* Write enable */
+#define NVR_PR_ENABLE		BIT_13	/* Protection register enable */
 #define NVR_DATA_IN		BIT_3
 #define NVR_DATA_OUT		BIT_2
 #define NVR_SELECT		BIT_1
@@ -1026,9 +1024,27 @@
 	uint8_t	 special_options[2];
 
 	/* Reserved for expanded RISC parameter block */
-	uint8_t reserved_2[24];
+	uint8_t reserved_2[22];
 
 	/*
+	 * LSB BIT 0 = Tx Sensitivity 1G bit 0
+	 * LSB BIT 1 = Tx Sensitivity 1G bit 1
+	 * LSB BIT 2 = Tx Sensitivity 1G bit 2
+	 * LSB BIT 3 = Tx Sensitivity 1G bit 3
+	 * LSB BIT 4 = Rx Sensitivity 1G bit 0
+	 * 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
+	 * MSB BIT 3 = Tx Sensitivity 2G bit 3
+	 * MSB BIT 4 = Rx Sensitivity 2G bit 0
+	 * MSB BIT 5 = Rx Sensitivity 2G bit 1
+	 * MSB BIT 6 = Rx Sensitivity 2G bit 2
+	 * MSB BIT 7 = Rx Sensitivity 2G bit 3
+	 *
 	 * LSB BIT 0 = Output Swing 1G bit 0
 	 * LSB BIT 1 = Output Swing 1G bit 1
 	 * LSB BIT 2 = Output Swing 1G bit 2
@@ -1047,7 +1063,7 @@
 	 * MSB BIT 6 =
 	 * MSB BIT 7 =
 	 */
-	uint8_t seriallink_options[2];
+	uint8_t seriallink_options[4];
 
 	/*
 	 * NVRAM host parameter block
@@ -1083,13 +1099,13 @@
 	uint8_t alternate_node_name[WWN_SIZE];
 
 	/*
-	 * BIT 0 = Boot Zoning
+	 * BIT 0 = Selective Login
 	 * BIT 1 = Alt-Boot Enable
-	 * BIT 2 = Report SCSI Path
-	 * BIT 3 = unused
-	 * BIT 4 = unused
-	 * BIT 5 = unused
-	 * BIT 6 = unused
+	 * BIT 2 =
+	 * BIT 3 = Boot Order List
+	 * BIT 4 =
+	 * BIT 5 = Selective LUN
+	 * BIT 6 =
 	 * BIT 7 = unused
 	 */
 	uint8_t efi_parameters;
@@ -1359,6 +1375,7 @@
 /*
  * Status entry status flags
  */
+#define SF_ABTS_TERMINATED	BIT_10
 #define SF_LOGOUT_SENT		BIT_13
 
 /*
@@ -1617,6 +1634,7 @@
     	spinlock_t q_lock;		/* Lun Lock */
 
 	unsigned long q_flag;
+#define LUN_MPIO_RESET_CNTS	1	/* Lun */
 #define LUN_MPIO_BUSY		2	/* Lun is changing paths  */
 #define LUN_EXEC_DELAYED	7	/* Lun execution is delayed */
 
@@ -1739,6 +1757,8 @@
 #define FCF_MSA_PORT_ACTIVE	BIT_20
 #define FCF_FAILBACK_DISABLE	BIT_21
 #define FCF_FAILOVER_DISABLE	BIT_22
+#define FCF_DSXXX_DEVICE	BIT_23
+#define FCF_AA_EVA_DEVICE	BIT_24
 
 /* No loop ID flag. */
 #define FC_NO_LOOP_ID		0x1000
@@ -2070,6 +2090,7 @@
 		uint32_t	enable_lip_reset	:1;
 		uint32_t	enable_lip_full_login	:1;
 		uint32_t	enable_target_reset	:1;
+		uint32_t	enable_led_scheme	:1;
 	} flags;
 
 	atomic_t	loop_state;
@@ -2105,6 +2126,7 @@
 #define FCPORT_RESCAN_NEEDED	21      /* IO descriptor processing needed */
 #define IODESC_PROCESS_NEEDED	22      /* IO descriptor processing needed */
 #define IOCTL_ERROR_RECOVERY	23      
+#define LOOP_RESET_NEEDED	24
 
 	uint32_t	device_flags;
 #define DFLG_LOCAL_DEVICES		BIT_0
@@ -2347,7 +2369,7 @@
 	uint32_t	fw_transfer_size;
 
 	uint16_t	fw_options[16];		/* slots: 1,2,3,10,11 */
-	uint8_t		fw_seriallink_options[2];
+	uint8_t		fw_seriallink_options[4];
 
 	/* Firmware dump information. */
 	void		*fw_dump;
diff -Nru a/drivers/scsi/qla2xxx/qla_devtbl.h b/drivers/scsi/qla2xxx/qla_devtbl.h
--- a/drivers/scsi/qla2xxx/qla_devtbl.h	2005-03-01 23:38:58 -08:00
+++ b/drivers/scsi/qla2xxx/qla_devtbl.h	2005-03-01 23:38:58 -08:00
@@ -1,9 +1,9 @@
-#define QLA_MODEL_NAMES         0x21
+#define QLA_MODEL_NAMES         0x32
 
 /*
  * Adapter model names.
  */
-char	*qla2x00_model_name[QLA_MODEL_NAMES] = {
+static char *qla2x00_model_name[QLA_MODEL_NAMES] = {
 	"QLA2340",	/* 0x100 */
 	"QLA2342",	/* 0x101 */
 	"QLA2344",	/* 0x102 */
@@ -19,27 +19,44 @@
 	"QLA2350",	/* 0x10c */
 	"QLA2352",	/* 0x10d */
 	"QLA2352",	/* 0x10e */
-	"HPQSVS ",	/* 0x10f */
-	"HPQSVS ",	/* 0x110 */
-	"QLA4010",	/* 0x111 */
-	"QLA4010",	/* 0x112 */
-	"QLA4010C",	/* 0x113 */
-	"QLA4010C",	/* 0x114 */
+	"HPQ SVS",	/* 0x10f */
+	"HPQ SVS",	/* 0x110 */
+	" ",		/* 0x111 */
+	" ",		/* 0x112 */
+	" ",		/* 0x113 */
+	" ",		/* 0x114 */
 	"QLA2360",	/* 0x115 */
 	"QLA2362",	/* 0x116 */
-	" ",		/* 0x117 */
-	" ",		/* 0x118 */
+	"QLE2360",	/* 0x117 */
+	"QLE2362",	/* 0x118 */
 	"QLA200",	/* 0x119 */
-	"QLA200C"	/* 0x11A */
-	"QLA200P"	/* 0x11B */
-	"QLA200P"	/* 0x11C */
-	"QLA4040"	/* 0x11D */
-	"QLA4040"	/* 0x11E */
-	"QLA4040C"	/* 0x11F */
-	"QLA4040C"	/* 0x120 */
+	"QLA200C",	/* 0x11a */
+	"QLA200P",	/* 0x11b */
+	"QLA200P",	/* 0x11c */
+	" ",		/* 0x11d */
+	" ",		/* 0x11e */
+	" ",		/* 0x11f */
+	" ",		/* 0x120 */
+	" ",		/* 0x121 */
+	" ",		/* 0x122 */
+	" ",		/* 0x123 */
+	" ",		/* 0x124 */
+	" ",		/* 0x125 */
+	" ",		/* 0x126 */
+	" ",		/* 0x127 */
+	" ",		/* 0x128 */
+	" ",		/* 0x129 */
+	" ",		/* 0x12a */
+	" ",		/* 0x12b */
+	" ",		/* 0x12c */
+	" ",		/* 0x12d */
+	" ",		/* 0x12e */
+	"QLA210",	/* 0x12f */
+	"EMC 250",	/* 0x130 */
+	"HP A7538A"	/* 0x131 */
 };
 
-char	*qla2x00_model_desc[QLA_MODEL_NAMES] = {
+static char *qla2x00_model_desc[QLA_MODEL_NAMES] = {
 	"133MHz PCI-X to 2Gb FC, Single Channel",	/* 0x100 */
 	"133MHz PCI-X to 2Gb FC, Dual Channel",		/* 0x101 */
 	"133MHz PCI-X to 2Gb FC, Quad Channel",		/* 0x102 */
@@ -57,20 +74,37 @@
 	" ",						/* 0x10e */
 	"HPQ SVS HBA- Initiator device",		/* 0x10f */
 	"HPQ SVS HBA- Target device",			/* 0x110 */
-	"Optical- 133MHz to 1Gb iSCSI- networking",	/* 0x111 */
-	"Optical- 133MHz to 1Gb iSCSI- storage",	/* 0x112 */
-	"Copper- 133MHz to 1Gb iSCSI- networking",	/* 0x113 */
-	"Copper- 133MHz to 1Gb iSCSI- storage",		/* 0x114 */
+	" ",						/* 0x111 */
+	" ",						/* 0x112 */
+	" ",						/* 0x113 */
+	" ",						/* 0x114 */
 	"133MHz PCI-X to 2Gb FC Single Channel",	/* 0x115 */
 	"133MHz PCI-X to 2Gb FC Dual Channel",		/* 0x116 */
-	" ",						/* 0x117 */
-	" ",						/* 0x118 */
+	"PCI-Express to 2Gb FC, Single Channel",	/* 0x117 */
+	"PCI-Express to 2Gb FC, Dual Channel",		/* 0x118 */
 	"133MHz PCI-X to 2Gb FC Optical",		/* 0x119 */
-	"133MHz PCI-X to 2Gb FC Copper"			/* 0x11A */
-	"133MHz PCI-X to 2Gb FC SFP"			/* 0x11B */
-	"133MHz PCI-X to 2Gb FC SFP"			/* 0x11C */
-	"Optical- 133MHz to 1Gb NIC with IPSEC",	/* 0x11D */
-	"Optical- 133MHz to 1Gb iSCSI with IPSEC",	/* 0x11E */
-	"Copper- 133MHz to 1Gb NIC with IPSEC",		/* 0x11F */
-	"Copper- 133MHz to 1Gb iSCSI with IPSEC",	/* 0x120 */
+	"133MHz PCI-X to 2Gb FC Copper",		/* 0x11a */
+	"133MHz PCI-X to 2Gb FC SFP",			/* 0x11b */
+	"133MHz PCI-X to 2Gb FC SFP",			/* 0x11c */
+	" ",						/* 0x11d */
+	" ",						/* 0x11e */
+	" ",						/* 0x11f */
+	" ",						/* 0x120 */
+	" ",						/* 0x121 */
+	" ",						/* 0x122 */
+	" ",						/* 0x123 */
+	" ",						/* 0x124 */
+	" ",						/* 0x125 */
+	" ",						/* 0x126 */
+	" ",						/* 0x127 */
+	" ",						/* 0x128 */
+	" ",						/* 0x129 */
+	" ",						/* 0x12a */
+	" ",						/* 0x12b */
+	" ",						/* 0x12c */
+	" ",						/* 0x12d */
+	" ",						/* 0x12e */
+	"133MHz PCI-X to 2Gb FC SFF",			/* 0x12f */
+	"133MHz PCI-X to 2Gb FC SFF",			/* 0x130 */
+	"HP 1p2g QLA2340"				/* 0x131 */
 };
diff -Nru a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
--- a/drivers/scsi/qla2xxx/qla_gbl.h	2005-03-01 23:39:18 -08:00
+++ b/drivers/scsi/qla2xxx/qla_gbl.h	2005-03-01 23:39:18 -08:00
@@ -45,12 +45,9 @@
 extern void qla2x00_rescan_fcports(scsi_qla_host_t *);
 
 extern void qla2x00_tgt_free(scsi_qla_host_t *ha, uint16_t t);
-extern os_tgt_t *qla2x00_tgt_alloc(scsi_qla_host_t *, uint16_t);
-extern os_lun_t * qla2x00_lun_alloc(scsi_qla_host_t *, uint16_t, uint16_t);
 
 extern int qla2x00_abort_isp(scsi_qla_host_t *);
 
-
 /*
  * Global Data in qla_os.c source file.
  */
@@ -82,9 +79,6 @@
 
 extern void qla2x00_cmd_timeout(srb_t *);
 
-extern int qla2x00_queuecommand(struct scsi_cmnd *,
-    void (*)(struct scsi_cmnd *));
-
 extern int __qla2x00_suspend_lun(scsi_qla_host_t *, os_lun_t *, int, int, int);
 
 extern void qla2x00_done(scsi_qla_host_t *);
@@ -92,17 +86,11 @@
 extern void qla2x00_flush_failover_q(scsi_qla_host_t *, os_lun_t *);
 extern void qla2x00_reset_lun_fo_counts(scsi_qla_host_t *, os_lun_t *);
 
-extern int qla2x00_check_tgt_status(scsi_qla_host_t *, struct scsi_cmnd *);
-extern int qla2x00_check_port_status(scsi_qla_host_t *, fc_port_t *);
-
 extern void qla2x00_extend_timeout(struct scsi_cmnd *, int);
-extern srb_t * qla2x00_get_new_sp (scsi_qla_host_t *ha);
 
 extern void qla2x00_mark_device_lost(scsi_qla_host_t *, fc_port_t *, int);
 extern void qla2x00_mark_all_devices_lost(scsi_qla_host_t *);
 
-extern int qla2x00_get_prop_xstr(scsi_qla_host_t *, char *, uint8_t *, int);
-
 extern void qla2x00_abort_queues(scsi_qla_host_t *, uint8_t);
 
 extern void qla2x00_blink_led(scsi_qla_host_t *);
@@ -112,8 +100,6 @@
 /*
  * Global Function Prototypes in qla_iocb.c source file.
  */
-extern request_t *qla2x00_req_pkt(scsi_qla_host_t *);
-extern request_t *qla2x00_ms_req_pkt(scsi_qla_host_t *, srb_t *);
 extern void qla2x00_isp_cmd(scsi_qla_host_t *);
 
 extern uint16_t qla2x00_calc_iocbs_32(uint16_t);
@@ -128,9 +114,6 @@
  * Global Function Prototypes in qla_mbx.c source file.
  */
 extern int
-qla2x00_mailbox_command(scsi_qla_host_t *, mbx_cmd_t *);
-
-extern int
 qla2x00_load_ram(scsi_qla_host_t *, dma_addr_t, uint16_t, uint16_t);
 
 extern int
@@ -150,13 +133,6 @@
 qla2x00_set_fw_options(scsi_qla_host_t *, uint16_t *);
 
 extern int
-qla2x00_read_ram_word(scsi_qla_host_t *, uint16_t, uint16_t *);
-extern int
-qla2x00_write_ram_word(scsi_qla_host_t *, uint16_t, uint16_t);
-extern int
-qla2x00_write_ram_word_ext(scsi_qla_host_t *, uint32_t, uint16_t);
-
-extern int
 qla2x00_mbx_reg_test(scsi_qla_host_t *);
 
 extern int
@@ -168,9 +144,6 @@
 extern int
 qla2x00_abort_command(scsi_qla_host_t *, srb_t *);
 
-extern int
-qla2x00_abort_device(scsi_qla_host_t *, uint16_t, uint16_t);
-
 #if USE_ABORT_TGT
 extern int
 qla2x00_abort_target(fc_port_t *fcport);
@@ -198,9 +171,6 @@
 extern int
 qla2x00_get_port_name(scsi_qla_host_t *, uint16_t, uint8_t *, uint8_t);
 
-extern uint8_t
-qla2x00_get_link_status(scsi_qla_host_t *, uint16_t, link_stat_t *, uint16_t *);
-
 extern int
 qla2x00_lip_reset(scsi_qla_host_t *);
 
@@ -224,19 +194,6 @@
 qla2x00_get_id_list(scsi_qla_host_t *, void *, dma_addr_t, uint16_t *);
 
 extern int
-qla2x00_lun_reset(scsi_qla_host_t *, uint16_t, uint16_t);
-
-extern int
-qla2x00_send_rnid_mbx(scsi_qla_host_t *, uint16_t, uint8_t, dma_addr_t,
-    size_t, uint16_t *);
-
-extern int
-qla2x00_set_rnid_params_mbx(scsi_qla_host_t *, dma_addr_t, size_t, uint16_t *);
-
-extern int
-qla2x00_get_rnid_params_mbx(scsi_qla_host_t *, dma_addr_t, size_t, uint16_t *);
-
-extern int
 qla2x00_get_resource_cnts(scsi_qla_host_t *, uint16_t *, uint16_t *, uint16_t *,
     uint16_t *);
 
@@ -255,6 +212,7 @@
  */
 extern void qla2x00_lock_nvram_access(scsi_qla_host_t *);
 extern void qla2x00_unlock_nvram_access(scsi_qla_host_t *);
+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);
 /*
diff -Nru a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
--- a/drivers/scsi/qla2xxx/qla_init.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/scsi/qla2xxx/qla_init.c	2005-03-01 23:39:16 -08:00
@@ -68,23 +68,10 @@
     fc_lun_t *);
 static void qla2x00_lun_free(scsi_qla_host_t *, uint16_t, uint16_t);
 
-static int qla2x00_bstr_to_hex(char *, uint8_t *, int);
-static int qla2x00_find_propname(scsi_qla_host_t *,
-    char *, char *, char *, int);
-#if 0
-static void qla2x00_get_lun_mask_from_config(scsi_qla_host_t *, fc_port_t *,
-    uint16_t, uint16_t);
-static int qla2x00_get_prop_16chars(scsi_qla_host_t *,
-    char *, char *, char *);
-static void qla2x00_get_properties(scsi_qla_host_t *, char *);
-
-static void qla2x00_cfg_persistent_binding(scsi_qla_host_t *);
-static os_tgt_t *qla2x00_persistent_bind(scsi_qla_host_t *, uint8_t *,
-    uint8_t *, port_id_t *, uint16_t);
-#endif
-
 static int qla2x00_restart_isp(scsi_qla_host_t *);
 static void qla2x00_reset_adapter(scsi_qla_host_t *);
+static os_tgt_t *qla2x00_tgt_alloc(scsi_qla_host_t *, uint16_t);
+static os_lun_t *qla2x00_lun_alloc(scsi_qla_host_t *, uint16_t, uint16_t);
 
 /****************************************************************************/
 /*                QLogic ISP2x00 Hardware Support Functions.                */
@@ -140,18 +127,6 @@
 
 	qla_printk(KERN_INFO, ha, "Verifying loaded RISC code...\n");
 
-#if 0
-	/*
-	 * If the user specified a device configuration on the command line
-	 * then use it as the configuration.  Otherwise, we scan for all
-	 * devices.
-	 */
-	if (ql2xdevconf) {
-		ha->cmdline = ql2xdevconf;
-		qla2x00_get_properties(ha, ql2xdevconf);
-	}
-#endif
-
 	retry = 10;
 	/*
 	 * Try to configure the loop.
@@ -853,7 +828,7 @@
 static void
 qla2x00_update_fw_options(scsi_qla_host_t *ha)
 {
-	uint16_t swing, emphasis;
+	uint16_t swing, emphasis, tx_sens, rx_sens;
 
 	memset(ha->fw_options, 0, sizeof(ha->fw_options));
 	qla2x00_get_fw_options(ha, ha->fw_options);
@@ -868,24 +843,54 @@
 	    sizeof(ha->fw_seriallink_options)));
 
 	ha->fw_options[1] &= ~FO1_SET_EMPHASIS_SWING;
-	if (ha->fw_seriallink_options[1] & BIT_2)
+	if (ha->fw_seriallink_options[3] & BIT_2) {
 		ha->fw_options[1] |= FO1_SET_EMPHASIS_SWING;
 
-	/*  1G settings */
-	swing = ha->fw_seriallink_options[0] & (BIT_2 | BIT_1 | BIT_0);
-	emphasis = ha->fw_seriallink_options[0] & (BIT_4 | BIT_3);
-	emphasis >>= 3;
-	ha->fw_options[10] = (emphasis << 14) | (swing << 8) | 0x3;
-	/*  2G settings */
-	swing = ha->fw_seriallink_options[0] & (BIT_7 | BIT_6 | BIT_5);
-	swing >>= 5;
-	emphasis = ha->fw_seriallink_options[1] & (BIT_1 | BIT_0);
-	ha->fw_options[11] = (emphasis << 14) | (swing << 8) | 0x3;
+		/*  1G settings */
+		swing = ha->fw_seriallink_options[2] & (BIT_2 | BIT_1 | BIT_0);
+		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); 
+		rx_sens = (ha->fw_seriallink_options[0] &
+		    (BIT_7 | BIT_6 | BIT_5 | BIT_4)) >> 4;
+		ha->fw_options[10] = (emphasis << 14) | (swing << 8);
+		if (IS_QLA2300(ha) || IS_QLA2312(ha) || IS_QLA6312(ha)) {
+			if (rx_sens == 0x0)
+				rx_sens = 0x3;
+			ha->fw_options[10] |= (tx_sens << 4) | rx_sens;
+		} else if (IS_QLA2322(ha) || IS_QLA6322(ha))
+			ha->fw_options[10] |= BIT_5 |
+			    ((rx_sens & (BIT_1 | BIT_0)) << 2) |
+			    (tx_sens & (BIT_1 | BIT_0));
+
+		/*  2G settings */
+		swing = (ha->fw_seriallink_options[2] &
+		    (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); 
+		rx_sens = (ha->fw_seriallink_options[1] &
+		    (BIT_7 | BIT_6 | BIT_5 | BIT_4)) >> 4;
+		ha->fw_options[11] = (emphasis << 14) | (swing << 8);
+		if (IS_QLA2300(ha) || IS_QLA2312(ha) || IS_QLA6312(ha)) {
+			if (rx_sens == 0x0)
+				rx_sens = 0x3;
+			ha->fw_options[11] |= (tx_sens << 4) | rx_sens;
+		} else if (IS_QLA2322(ha) || IS_QLA6322(ha))
+			ha->fw_options[11] |= BIT_5 |
+			    ((rx_sens & (BIT_1 | BIT_0)) << 2) |
+			    (tx_sens & (BIT_1 | BIT_0));
+	}
 
 	/* FCP2 options. */
 	/*  Return command IOCBs without waiting for an ABTS to complete. */
 	ha->fw_options[3] |= BIT_13;
 
+	/* LED scheme. */
+	if (ha->flags.enable_led_scheme)
+		ha->fw_options[2] |= BIT_12;
+
 	/* Update firmware options. */
 	qla2x00_set_fw_options(ha, ha->fw_options);
 }
@@ -1094,6 +1099,7 @@
 	if (rval != QLA_SUCCESS) {
 		qla_printk(KERN_WARNING, ha,
 		    "ERROR -- Unable to get host loop ID.\n");
+		set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
 		return (rval);
 	}
 
@@ -1394,12 +1400,13 @@
 	ha->flags.enable_lip_reset = ((nv->host_p[1] & BIT_1) ? 1 : 0);
 	ha->flags.enable_lip_full_login = ((nv->host_p[1] & BIT_2) ? 1 : 0);
 	ha->flags.enable_target_reset = ((nv->host_p[1] & BIT_3) ? 1 : 0);
+	ha->flags.enable_led_scheme = ((nv->efi_parameters & BIT_3) ? 1 : 0);
 
 	ha->operating_mode =
 	    (icb->add_firmware_options[0] & (BIT_6 | BIT_5 | BIT_4)) >> 4;
 
-	ha->fw_seriallink_options[0] = nv->seriallink_options[0];
-	ha->fw_seriallink_options[1] = nv->seriallink_options[1];
+	memcpy(ha->fw_seriallink_options, nv->seriallink_options,
+	    sizeof(ha->fw_seriallink_options));
 
 	/* save HBA serial number */
 	ha->serial0 = icb->port_name[5];
@@ -1947,6 +1954,9 @@
 		return;
 	}
 
+	/* Always add a fc_lun_t structure for lun 0 -- mid-layer requirement */
+	qla2x00_add_lun(fcport, 0);
+
 	/* If report LUN works, exit. */
 	if (qla2x00_rpt_lun_discovery(ha, fcport, inq, inq_dma) !=
 	    QLA_SUCCESS) {
@@ -1992,9 +2002,6 @@
 	if (rval != QLA_SUCCESS)
 		return (rval);
 
-	/* Always add a fc_lun_t structure for lun 0 -- mid-layer requirement */
-	qla2x00_add_lun(fcport, 0);
-
 	/* Configure LUN list. */
 	len = be32_to_cpu(ha->rlc_rsp->list.hdr.len);
 	len /= 8;
@@ -2130,6 +2137,7 @@
     inq_cmd_rsp_t *inq, dma_addr_t inq_dma) 
 {
 	fc_lun_t *fclun;
+	uint8_t	  device_type;
 
 	/* Bypass LUNs that failed. */
 	if (qla2x00_inquiry(ha, fcport, lun, inq, inq_dma) != QLA_SUCCESS) {
@@ -2138,8 +2146,8 @@
 
 		return (NULL);
 	}
-
-	switch (inq->inq[0]) {
+	device_type = (inq->inq[0] & 0x1f);
+	switch (device_type) {
 	case TYPE_DISK:
 	case TYPE_PROCESSOR:
 	case TYPE_WORM:
@@ -2157,11 +2165,11 @@
 	default:
 		DEBUG2(printk("scsi(%ld): Unsupported lun type -- "
 		    "loop id=0x%04x lun=%d type=%x\n",
-		    ha->host_no, fcport->loop_id, lun, inq->inq[0]));
+		    ha->host_no, fcport->loop_id, lun, device_type));
 		return (NULL);
 	}
 
-	fcport->device_type = inq->inq[0];
+	fcport->device_type = device_type;
 	fclun = qla2x00_add_lun(fcport, lun);
 
 	if (fclun != NULL) {
@@ -2520,7 +2528,7 @@
 {
 	int		rval;
 	uint16_t	loop_id;
-	fc_port_t	*fcport, *new_fcport;
+	fc_port_t	*fcport, *new_fcport, *fcptemp;
 	int		found;
 
 	sw_info_t	*swl;
@@ -2594,6 +2602,15 @@
 			/* Send GA_NXT to the switch */
 			rval = qla2x00_ga_nxt(ha, new_fcport);
 			if (rval != QLA_SUCCESS) {
+				qla_printk(KERN_WARNING, ha,
+				    "SNS scan failed -- assuming zero-entry "
+				    "result...\n");
+				list_for_each_entry_safe(fcport, fcptemp,
+				    new_fcports, list) {
+					list_del(&fcport->list);
+					kfree(fcport);
+				}
+				rval = QLA_SUCCESS;
 				break;
 			}
 		}
@@ -3024,9 +3041,9 @@
 			 */
 			*next_loopid = fcport->loop_id;
 			qla2x00_fabric_logout(ha, fcport->loop_id);
-			fcport->loop_id = FC_NO_LOOP_ID;
+			qla2x00_mark_device_lost(ha, fcport, 1);
 
-			rval = 3;
+			rval = 1;
 			break;
 		} else {
 			/*
@@ -3043,7 +3060,7 @@
 			fcport->loop_id = FC_NO_LOOP_ID;
 			atomic_set(&fcport->state, FCS_DEVICE_DEAD);
 
-			rval = 1;
+			rval = 3;
 			break;
 		}
 	}
@@ -3391,10 +3408,6 @@
 		tq->fcport = fcport;
 		set_bit(TQF_ONLINE, &tq->flags);
 		tq->port_down_retry_count = ha->port_down_retry_count;
-
-#if 0
-		qla2x00_get_lun_mask_from_config(ha, fcport, tgt, 0);
-#endif
 	}
 
 	if (tgt == MAX_TARGETS) {
@@ -3467,7 +3480,7 @@
  * Context:
  *	Kernel context.
  */
-os_tgt_t *
+static os_tgt_t *
 qla2x00_tgt_alloc(scsi_qla_host_t *ha, uint16_t tgt) 
 {
 	os_tgt_t	*tq;
@@ -3561,7 +3574,7 @@
  * Context:
  *	Kernel context.
  */
-os_lun_t *
+static os_lun_t *
 qla2x00_lun_alloc(scsi_qla_host_t *ha, uint16_t tgt, uint16_t lun) 
 {
 	os_lun_t	*lq;
@@ -3583,7 +3596,7 @@
 			DEBUG2(printk("scsi(%ld): Alloc Lun %d @ tgt %d.\n",
 			    ha->host_no, lun, tgt));
 
-			memset(lq, 0, sizeof (os_lun_t));
+			memset(lq, 0, sizeof(os_lun_t));
 			LUN_Q(ha, tgt, lun) = lq;
 
 			/*
@@ -3636,482 +3649,6 @@
 
 	return;
 }
-
-
-#if 0
-/*
- * qla2x00_get_lun_mask_from_config
- *      Get lun mask from the configuration parameters.
- *      Bit order is little endian.
- *
- * Input:
- * ha  -- Host adapter
- * tgt  -- target/device number
- * port -- pointer to port
- */
-static void
-qla2x00_get_lun_mask_from_config(scsi_qla_host_t *ha,
-    fc_port_t *fcport, uint16_t tgt, uint16_t dev_no) 
-{
-	char		propbuf[60]; /* size of search string */
-	int		rval, lun, bit;
-	lun_bit_mask_t	lun_mask, *mask_ptr = &lun_mask;
-
-	/* Get "target-N-device-N-lun-mask" as a 256 bit lun_mask*/
-	sprintf(propbuf, "scsi-qla%ld-tgt-%d-di-%d-lun-disabled",
-	    ha->instance, tgt, dev_no);
-
-	rval = qla2x00_get_prop_xstr(ha, propbuf,
-	    (uint8_t *)&lun_mask, sizeof(lun_bit_mask_t));
-	if (rval == sizeof(lun_bit_mask_t)) {
-		memset(&fcport->lun_mask, 0, sizeof(lun_bit_mask_t));
-		for (lun = 8 * sizeof(lun_bit_mask_t) - 1, bit = 0;
-		    lun >= 0; lun--, bit++) {
-			if (EXT_IS_LUN_BIT_SET(mask_ptr, lun))
-				EXT_SET_LUN_BIT((&fcport->lun_mask), bit);
-		}
-
-		DEBUG3(printk("scsi(%ld): returning lun mask for fcport "
-		    "%02x%02x%02x%02x%02x%02x%02x%02x:\n",
-		    ha->host_no,
-		    fcport->port_name[0], fcport->port_name[1],
-		    fcport->port_name[2], fcport->port_name[3],
-		    fcport->port_name[4], fcport->port_name[5],
-		    fcport->port_name[6], fcport->port_name[7]));
-		DEBUG3(qla2x00_dump_buffer((uint8_t *)&fcport->lun_mask,
-		    sizeof(lun_bit_mask_t));)
-	}
-}
-#endif
-
-/*
- * qla2x00_bstr_to_hex
- *	Convert hex byte string to number.
- *
- * Input:
- *	s = byte string pointer.
- *	bp = byte pointer for number.
- *	size = number of bytes.
- *
- * Context:
- *	Kernel/Interrupt context.
- */
-static int
-qla2x00_bstr_to_hex(char *s, uint8_t *bp, int size) 
-{
-	int		cnt;
-	uint8_t		n;
-
-	for (cnt = 0; *s != '\0' && cnt / 2 < size; cnt++) {
-		if (*s >= 'A' && *s <= 'F') {
-			n = (*s++ - 'A') + 10;
-		} else if (*s >= 'a' && *s <= 'f') {
-			n = (*s++ - 'a') + 10;
-		} else if (*s >= '0' && *s <= '9') {
-			n = *s++ - '0';
-		} else {
-			cnt = 0;
-			break;
-		}
-
-		if (cnt & BIT_0)
-			*bp++ |= n;
-		else
-			*bp = n << 4;
-	}
-
-	/* fixme(dg) Need to swap data little endian */
-
-	return (cnt / 2);
-}
-
-/*
- * qla2x00_get_prop_xstr
- *      Get a string property value for the specified property name and
- *      convert from the property string found in the configuration file,
- *      which are ASCII characters representing nibbles, 2 characters represent
- *      the hexdecimal value for a byte in the byte array.
- *      The byte array is initialized to zero.
- *      The resulting converted value is in big endian format (MSB at byte0).
- *
- * Input:
- *      ha = adapter state pointer.
- *      propname = property name pointer.
- *      propval  = pointer where to store converted property val.
- *      size = max or expected size of 'propval' array.
- *
- * Returns:
- *      0 = empty value string or invalid character in string
- *      >0 = count of characters converted
- *      -1 = property not found
- *
- * Context:
- *      Kernel context.
- */
-int
-qla2x00_get_prop_xstr(scsi_qla_host_t *ha, 
-		char *propname, uint8_t *propval, int size) 
-{
-	char		*propstr;
-	int		rval = -1;
-	static char	buf[LINESIZE];
-
-	/* Get the requested property string */
-	rval = qla2x00_find_propname(ha, propname, buf, ha->cmdline, size*2);
-	DEBUG3(printk("%s(): Ret rval from find propname = %d\n",
-			__func__,
-			rval);)
-
-	propstr = &buf[0];
-	if (*propstr == '=')
-		propstr++;   /* ignore equal sign */
-
-	if (rval == 0) {  /* not found */
-		return (-1);
-	}
-
-	rval = qla2x00_bstr_to_hex(propstr, (uint8_t *)propval, size);
-	if (rval == 0) {
-		/* Invalid character in value string */
-		qla_printk(KERN_INFO, ha,
-			"%s(): %s Invalid hex string for property\n",
-			__func__,
-			propname);
-		qla_printk(KERN_INFO, ha,
-			" Invalid string - %s\n", 
-			propstr);
-	}
-
-	return (rval);
-}
-
-/*
- * qla2x00_find_propname
- *	Get property in database.
- *
- * Input:
- *	ha = adapter structure pointer.
- *      db = pointer to database
- *      propstr = pointer to dest array for string
- *	propname = name of property to search for.
- *	siz = size of property
- *
- * Returns:
- *	0 = no property
- *      size = index of property
- *
- * Context:
- *	Kernel context.
- */
-static int
-qla2x00_find_propname(scsi_qla_host_t *ha, 
-			char *propname, char *propstr, 
-			char *db, int siz) 
-{
-	char	*cp;
-
-	/* find the specified string */
-	if (db) {
-		/* find the property name */
-		if ((cp = strstr(db,propname)) != NULL) {
-			while ((*cp)  && *cp != '=')
-				cp++;
-			if (*cp) {
-				strncpy(propstr, cp, siz+1);
-				propstr[siz+1] = '\0';
-				DEBUG(printk("qla2x00_find_propname: found "
-						"property = {%s}\n",
-						propstr);)
-				return (siz);   /* match */
-			}
-		}
-	}
-
-	return (0);
-}
-
-#if 0
-/*
- * qla2x00_get_prop_16chars
- *	Get an 8-byte property value for the specified property name by
- *      converting from the property string found in the configuration file.
- *      The resulting converted value is in big endian format (MSB at byte0).
- *
- * Input:
- *	ha = adapter state pointer.
- *	propname = property name pointer.
- *	propval  = pointer to location for the converted property val.
- *      db = pointer to database
- *
- * Returns:
- *	0 = value returned successfully.
- *
- * Context:
- *	Kernel context.
- */
-static int
-qla2x00_get_prop_16chars(scsi_qla_host_t *ha,
-				char *propname, char *propval, char *db) 
-{
-	char		*propstr;
-	int		i, k;
-	int		rval;
-	uint8_t		nval;
-	uint8_t		*pchar;
-	uint8_t		*ret_byte;
-	uint8_t		*tmp_byte;
-	uint8_t		*retval = (uint8_t*)propval;
-	uint8_t		tmpval[8] = {0, 0, 0, 0, 0, 0, 0, 0};
-	uint16_t	max_byte_cnt = 8; /* 16 chars = 8 bytes */
-	uint16_t	max_strlen = 16;
-	static char	buf[LINESIZE];
-
-	rval = qla2x00_find_propname(ha, propname, buf, db, max_strlen);
-
-	propstr = &buf[0];
-	if (*propstr == '=')
-		propstr++;   /* ignore equal sign */
-
-	if (rval == 0) {
-		return (1);
-	}
-
-	/* Convert string to numbers. */
-	pchar = (uint8_t *)propstr;
-	tmp_byte = (uint8_t *)tmpval;
-
-	rval = 0;
-	for (i = 0; i < max_strlen; i++) {
-		/*
-		 * Check for invalid character, two at a time,
-		 * then convert them starting with first byte.
-		 */
-
-		if ((pchar[i] >= '0') && (pchar[i] <= '9')) {
-			nval = pchar[i] - '0';
-		} else if ((pchar[i] >= 'A') && (pchar[i] <= 'F')) {
-			nval = pchar[i] - 'A' + 10;
-		} else if ((pchar[i] >= 'a') && (pchar[i] <= 'f')) {
-			nval = pchar[i] - 'a' + 10;
-		} else {
-			/* invalid character */
-			rval = 1;
-			break;
-		}
-
-		if (i & BIT_0) {
-			*tmp_byte = *tmp_byte | nval;
-			tmp_byte++;
-		} else {
-			*tmp_byte = *tmp_byte | nval << 4;
-		}
-	}
-
-	if (rval != 0) {
-		/* Encountered invalid character. */
-		return (rval);
-	}
-
-	/* Copy over the converted value. */
-	ret_byte = retval;
-	tmp_byte = tmpval;
-
-	i = max_byte_cnt;
-	k = 0;
-	while (i--) {
-		*ret_byte++ = *tmp_byte++;
-	}
-
-	/* big endian retval[0]; */
-	return (0);
-}
-
-/*
-* qla2x00_get_properties
-*	Find all properties for the specified adapeter in
-*      command line.
-*
-* Input:
-*	ha = adapter block pointer.
-*	cmdline = pointer to command line string
-*
-* Context:
-*	Kernel context.
-*/
-static void
-qla2x00_get_properties(scsi_qla_host_t *ha, char *cmdline) 
-{
-	int	rval;
-	static char propbuf[LINESIZE];
-	uint8_t fc_name[8];
-
-	/* Adapter FC node names. */
-	sprintf(propbuf, "scsi-qla%d-adapter-node", (int) ha->instance);
-	rval = qla2x00_get_prop_16chars(ha, propbuf, fc_name, cmdline);
-	if (rval == QLA_SUCCESS)
-		memcpy(ha->init_cb->node_name, fc_name, WWN_SIZE);
-
-	/* DG 04/07 check portname of adapter */
-	sprintf(propbuf, "scsi-qla%d-adapter-port", (int)ha->instance);
-	rval = qla2x00_get_prop_16chars(ha, propbuf, fc_name, cmdline);
-	if (rval == QLA_SUCCESS &&
-	    memcmp(ha->init_cb->port_name, fc_name, WWN_SIZE)) {
-		/*
-		 * Adapter port name is WWN, and cannot be changed.
-		 * Inform users of the mismatch, then just continue driver
-		 * loading using the original adapter port name in NVRAM.
-		 */
-		qla_printk(KERN_WARNING, ha,
-		    "Found mismatch in adapter port names.\n");
-		qla_printk(KERN_INFO, ha,
-		    "       qla%ld port name found in NVRAM -> "
-		    "%02x%02x%02x%02x%02x%02x%02x%02x\n",
-		    ha->instance,
-		    ha->init_cb->port_name[0],
-		    ha->init_cb->port_name[1],
-		    ha->init_cb->port_name[2],
-		    ha->init_cb->port_name[3],
-		    ha->init_cb->port_name[4],
-		    ha->init_cb->port_name[5],
-		    ha->init_cb->port_name[6],
-		    ha->init_cb->port_name[7]);
-		qla_printk(KERN_INFO, ha,
-		    "      qla%ld port name found on command line -> "
-		    "%02x%02x%02x%02x%02x%02x%02x%02x\n",
-		    ha->instance,
-		    fc_name[0], fc_name[1], fc_name[2], fc_name[3],
-		    fc_name[4], fc_name[5], fc_name[6], fc_name[7]);
-		qla_printk(KERN_INFO, ha,
-		    "      Using port name from NVRAM.\n");
-	}
-
-	qla2x00_cfg_persistent_binding(ha);
-}
-
-/*
- * qla2x00_cfg_persistent_binding
- *	Get driver configuration file target persistent binding entries.
- *
- * Input:
- *	ha = adapter block pointer.
- *
- * Context:
- *	Kernel context.
- */
-static void
-qla2x00_cfg_persistent_binding(scsi_qla_host_t *ha) 
-{
-	int		rval;
-	static char	propbuf[LINESIZE];
-	char		*cmdline = ha->cmdline;
-	uint16_t	tgt;
-	port_id_t	d_id;
-	uint8_t		portid[3];
-	uint8_t		port_name[8];
-
-	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
-		if (ha->binding_type == BIND_BY_PORT_ID) {
-			sprintf(propbuf, "scsi-qla%d-tgt-%d-di-0-pid",
-			    (int)ha->instance, tgt);
-			rval = qla2x00_get_prop_xstr(ha,
-			    propbuf, portid, sizeof(portid));
-			if (rval != sizeof(portid))
-				continue;
-			
-			memset(&d_id, 0, sizeof(port_id_t));
-			d_id.r.d_id[0] = portid[2];
-			d_id.r.d_id[1] = portid[1];
-			d_id.r.d_id[2] = portid[0];
-		} else {
-			sprintf(propbuf, "scsi-qla%d-tgt-%d-di-0-port",
-			    (int)ha->instance, tgt);
-			rval = qla2x00_get_prop_16chars(ha,
-			    propbuf, port_name, cmdline);
-			if (rval != QLA_SUCCESS)
-				continue;
-
-			/* Fallthru since port_name already populated */
-		}
-
-		/*
-		 * Create target context for device.
-		 */
-		if (ha->binding_type == BIND_BY_PORT_ID) {
-			qla2x00_persistent_bind(ha, NULL, NULL, &d_id, tgt);
-		} else {
-			qla2x00_persistent_bind(ha, NULL, port_name, NULL, tgt);
-		}
-	}
-}
-
-/*
- * qla2x00_persistent_bind
- *	Allocates target and fcport.
- *
- * Input:
- *	ha:		adapter state pointer.
- *	node_name:	node name pointer.
- *	port_name:	port name pointer.
- *	d_id:		port ID pointer.
- *	tgt:		OS target number.
- *
- * Returns:
- *	success = target queue pointer.
- *	failure = NULL.
- *
- * Context:
- *	Kernel context.
- */
-static os_tgt_t *
-qla2x00_persistent_bind(scsi_qla_host_t *ha, uint8_t *node_name,
-    uint8_t *port_name, port_id_t *d_id, uint16_t tgt)
-{
-	os_tgt_t	*tq;
-	uint16_t	tgt2;
-
-	/*
-	 * Check for duplicates.
-	 */
-	for (tgt2 = 0; tgt2 < MAX_TARGETS; tgt2++) {
-		if ((tq = TGT_Q(ha, tgt2)) == NULL) {
-			continue;
-		}
-
-		if (ha->binding_type == BIND_BY_PORT_ID) {
-			if (tq->d_id.b24 != d_id->b24) {
-				continue;
-			}
-		} else if (memcmp(tq->port_name, port_name, WWN_SIZE) != 0) {
-			continue;
-		}
-
-		qla_printk(KERN_WARNING, ha,
-		    "Duplicate persistent bindings found for "
-		    "WWPN: %02x%02x%02x%02x%02x%02x%02x%02x.\n", 
-		    port_name[0], port_name[1], port_name[2], port_name[3],
-		    port_name[4], port_name[5], port_name[6], port_name[7]);
-
-		return (tq);
-	}
-
-	tq = qla2x00_tgt_alloc(ha, tgt);
-	if (tq == NULL) {
-		return (NULL);
-	}
-
-	if (node_name != NULL) {
-		memcpy(tq->node_name, node_name, WWN_SIZE);
-	}
-	if (port_name != NULL) {
-		memcpy(tq->port_name, port_name, WWN_SIZE);
-	}
-	if (d_id != NULL) {
-		tq->d_id.b24 = d_id->b24;
-	}
-
-	return (tq);
-}
-#endif
 
 /*
 *  qla2x00_abort_isp
diff -Nru a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c
--- a/drivers/scsi/qla2xxx/qla_iocb.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/scsi/qla2xxx/qla_iocb.c	2005-03-01 23:39:07 -08:00
@@ -27,6 +27,7 @@
 static inline uint16_t qla2x00_get_cmd_direction(struct scsi_cmnd *cmd);
 static inline cont_entry_t *qla2x00_prep_cont_type0_iocb(scsi_qla_host_t *);
 static inline cont_a64_entry_t *qla2x00_prep_cont_type1_iocb(scsi_qla_host_t *);
+static request_t *qla2x00_req_pkt(scsi_qla_host_t *ha);
 
 /**
  * qla2x00_get_cmd_direction() - Determine control_flag data direction.
@@ -544,7 +545,7 @@
  *
  * Returns NULL if function failed, else, a pointer to the request packet.
  */
-request_t *
+static request_t *
 qla2x00_req_pkt(scsi_qla_host_t *ha)
 {
 	device_reg_t __iomem *reg = ha->iobase;
@@ -593,100 +594,6 @@
 		/* During init we issue marker directly */
 		if (!ha->marker_needed)
 			qla2x00_poll(ha);
-
-		spin_lock_irq(&ha->hardware_lock);
-	}
-	if (!pkt) {
-		DEBUG2_3(printk("%s(): **** FAILED ****\n", __func__));
-	}
-
-	return (pkt);
-}
-
-/**
- * qla2x00_ms_req_pkt() - Retrieve a Management Server request packet from
- * 				the request ring.
- * @ha: HA context
- * @sp: pointer to handle post function call
- *
- * Note: The caller must hold the hardware lock before calling this routine.
- *
- * Returns NULL if function failed, else, a pointer to the request packet.
- */
-request_t *
-qla2x00_ms_req_pkt(scsi_qla_host_t *ha, srb_t  *sp)
-{
-	device_reg_t __iomem *reg = ha->iobase;
-	request_t	*pkt = NULL;
-	uint16_t	cnt, i, index;
-	uint32_t	*dword_ptr;
-	uint32_t	timer;
-	uint8_t		found = 0;
-	uint16_t	req_cnt = 1;
-
-	/* Wait 1 second for slot. */
-	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 (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);
-			}
-		}
-
-		/* Check for room in outstanding command list. */
-		cnt = ha->current_outstanding_cmd;
-		for (index = 1; index < MAX_OUTSTANDING_COMMANDS; index++) {
-			cnt++;
-			if (cnt == MAX_OUTSTANDING_COMMANDS)
-				cnt = 1;
-
-			if (ha->outstanding_cmds[cnt] == 0) {
-				found = 1;
-				ha->current_outstanding_cmd = cnt;
-				break;
-			}
-		}
-
-		/* If room for request in request ring. */
-		if (found && (req_cnt + 2) < ha->req_q_cnt) {
-			pkt = ha->request_ring_ptr;
-
-			/* Zero out packet. */
-			dword_ptr = (uint32_t *)pkt;
-			for (i = 0; i < REQUEST_ENTRY_SIZE / 4; i++ )
-				*dword_ptr++ = 0;
-
-			DEBUG5(printk("%s(): putting sp=%p in "
-			    "outstanding_cmds[%x]\n",
-			    __func__,
-			    sp, cnt));
-
-			ha->outstanding_cmds[cnt] = sp;
-
-			/* save the handle */
-			sp->cmd->host_scribble = (unsigned char *) (u_long) cnt;
-			CMD_SP(sp->cmd) = (void *)sp;
-
-			ha->req_q_cnt--;
-			pkt->handle = (uint32_t)cnt;
-
-			/* Set system defined field. */
-			pkt->sys_define = (uint8_t)ha->req_ring_index;
-			pkt->entry_status = 0;
-
-			break;
-		}
-
-		/* Release ring specific lock */
-		spin_unlock(&ha->hardware_lock);
-		udelay(20);
-
-		/* Check for pending interrupts. */
-		qla2x00_poll(ha);
 
 		spin_lock_irq(&ha->hardware_lock);
 	}
diff -Nru a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
--- a/drivers/scsi/qla2xxx/qla_isr.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/scsi/qla2xxx/qla_isr.c	2005-03-01 23:39:18 -08:00
@@ -94,7 +94,7 @@
 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
 
 	qla2x00_next(ha);
-	ha->last_irq_cpu = smp_processor_id();
+	ha->last_irq_cpu = _smp_processor_id();
 	ha->total_isr_cnt++;
 
 	if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
@@ -207,7 +207,7 @@
 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
 
 	qla2x00_next(ha);
-	ha->last_irq_cpu = smp_processor_id();
+	ha->last_irq_cpu = _smp_processor_id();
 	ha->total_isr_cnt++;
 
 	if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
@@ -376,7 +376,14 @@
 			qla2100_fw_dump(ha, 1);
 		else
 	    		qla2300_fw_dump(ha, 1);
-		set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
+
+		if (mb[1] == 0) {
+			qla_printk(KERN_INFO, ha,
+			    "Unrecoverable Hardware Error: adapter marked "
+			    "OFFLINE!\n");
+			ha->flags.online = 0;
+		} else
+			set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
 		break;
 
 	case MBA_REQ_TRANSFER_ERR:	/* Request Transfer Error */
@@ -561,8 +568,8 @@
 			rscn_fcport = qla2x00_alloc_rscn_fcport(ha, GFP_ATOMIC);
 			if (rscn_fcport) {
 				DEBUG14(printk("scsi(%ld): Port Update -- "
-				    "creating RSCN fcport %p for login.\n",
-				    ha->host_no, rscn_fcport));
+				    "creating RSCN fcport %p for %x/%x.\n",
+				    ha->host_no, rscn_fcport, mb[1], mb[2]));
 
 				rscn_fcport->loop_id = mb[1];
 				rscn_fcport->d_id.b24 = INVALID_PORT_ID;
@@ -583,11 +590,13 @@
 		}
 
 		/*
-		 * If PORT UPDATE is global (received LIP_OCCURRED/LIP_RESET
+		 * If PORT UPDATE is global (recieved LIP_OCCURED/LIP_RESET
 		 * event etc. earlier indicating loop is down) then process
 		 * it.  Otherwise ignore it and Wait for RSCN to come in.
 		 */
-		if (atomic_read(&ha->loop_state) != LOOP_DOWN) {
+		atomic_set(&ha->loop_down_timer, 0);
+		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));
 			break;
@@ -604,7 +613,6 @@
 		 */
 		atomic_set(&ha->loop_state, LOOP_UP);
 
-		atomic_set(&ha->loop_down_timer, 0);
 		qla2x00_mark_all_devices_lost(ha);
 
 		ha->flags.rscn_queue_overflow = 1;
@@ -1196,8 +1204,9 @@
 
 	case CS_TIMEOUT:
 		DEBUG2(printk(KERN_INFO
-		    "scsi(%ld:%d:%d:%d): TIMEOUT status detected 0x%x-0x%x.\n",
-		    ha->host_no, b, t, l, comp_status, scsi_status));
+		    "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)));
 
 		cp->result = DID_BUS_BUSY << 16;
 
diff -Nru a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
--- a/drivers/scsi/qla2xxx/qla_mbx.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/scsi/qla2xxx/qla_mbx.c	2005-03-01 23:38:57 -08:00
@@ -53,7 +53,7 @@
  * Context:
  *	Kernel context.
  */
-int
+static int
 qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp)
 {
 	int		rval;
@@ -676,135 +676,6 @@
 }
 
 /*
- * qla2x00_read_ram_word
- *
- * Input:
- *	ha = adapter block pointer.
- *
- * Returns:
- *	qla2x00 local function return status code.
- *
- * Context:
- *	Kernel context.
- */
-int
-qla2x00_read_ram_word(scsi_qla_host_t *ha, uint16_t addr, uint16_t *data)
-{
-	int rval;
-	mbx_cmd_t mc;
-	mbx_cmd_t *mcp = &mc;
-
-	DEBUG11(printk("qla2x00_read_ram_word(%ld): entered.\n", ha->host_no);)
-
-	mcp->mb[0] = MBC_READ_RAM_WORD;
-	mcp->mb[1] = addr;
-	mcp->out_mb = MBX_1|MBX_0;
-	mcp->in_mb = MBX_0|MBX_2;
-	mcp->tov = 30;
-	mcp->flags = 0;
-	rval = qla2x00_mailbox_command(ha, mcp);
-
-	if (rval != QLA_SUCCESS) {
-		/*EMPTY*/
-		DEBUG2_3_11(printk("qla2x00_read_ram_word(%ld): failed=%x.\n",
-		    ha->host_no, rval);)
-	} else {
-		*data = mcp->mb[2];
-		DEBUG11(printk("qla2x00_read_ram_word(%ld): done.\n",
-		    ha->host_no);)
-	}
-
-	return rval;
-}
-
-/*
- * qla2x00_write_ram_word
- *
- * Input:
- *	ha = adapter block pointer.
- *
- * Returns:
- *	qla2x00 local function return status code.
- *
- * Context:
- *	Kernel context.
- */
-int
-qla2x00_write_ram_word(scsi_qla_host_t *ha, uint16_t addr, uint16_t data)
-{
-	int rval;
-	mbx_cmd_t mc;
-	mbx_cmd_t *mcp = &mc;
-
-	DEBUG11(printk("qla2x00_write_ram_word(%ld): entered.\n",
-	    ha->host_no);)
-
-	mcp->mb[0] = MBC_WRITE_RAM_WORD;
-	mcp->mb[1] = addr;
-	mcp->mb[2] = data;
-	mcp->out_mb = 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("qla2x00_write_ram_word(%ld): failed=%x.\n",
-		    ha->host_no, rval);)
-	} else {
-		/*EMPTY*/
-		DEBUG11(printk("qla2x00_write_ram_word(%ld): done.\n",
-		    ha->host_no);)
-	}
-
-	return rval;
-}
-
-/*
- * qla2x00_write_ram_word_ext
- *
- * Input:
- *	ha = adapter block pointer.
- *
- * Returns:
- *	qla2x00 local function return status code.
- *
- * Context:
- *	Kernel context.
- */
-int
-qla2x00_write_ram_word_ext(scsi_qla_host_t *ha, uint32_t addr, uint16_t data)
-{
-	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_WRITE_RAM_WORD_EXTENDED;
-	mcp->mb[1] = LSW(addr);
-	mcp->mb[2] = data;
-	mcp->mb[8] = MSW(addr);
-	mcp->out_mb = MBX_8|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.\n", __func__,
-		    ha->host_no, rval));
-	} else {
-		/*EMPTY*/
-		DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no));
-	}
-
-	return rval;
-}
-
-/*
  * qla2x00_mbx_reg_test
  *	Mailbox register wrap test.
  *
@@ -1032,62 +903,6 @@
 	return rval;
 }
 
-/*
- * qla2x00_abort_device
- *
- * Input:
- *	ha = adapter block pointer.
- *      loop_id  = FC loop ID
- *      lun  = SCSI LUN.
- *
- * Returns:
- *	qla2x00 local function return status code.
- *
- * Context:
- *	Kernel context.
- */
-int
-qla2x00_abort_device(scsi_qla_host_t *ha, uint16_t loop_id, uint16_t lun)
-{
-	int rval;
-	mbx_cmd_t mc;
-	mbx_cmd_t *mcp = &mc;
-
-	DEBUG11(printk("qla2x00_abort_device(%ld): entered.\n", ha->host_no);)
-
-	mcp->mb[0] = MBC_ABORT_DEVICE;
-	if (HAS_EXTENDED_IDS(ha))
-		mcp->mb[1] = loop_id;
-	else
-		mcp->mb[1] = loop_id << 8;
-	mcp->mb[2] = lun;
-	mcp->out_mb = MBX_2|MBX_1|MBX_0;
-	mcp->in_mb = MBX_0;
-	mcp->tov = 30;
-	mcp->flags = 0;
-	rval = qla2x00_mailbox_command(ha, mcp);
-
-	/* Issue marker command. */
-	qla2x00_marker(ha, loop_id, lun, MK_SYNC_ID_LUN);
-
-	if (rval != QLA_SUCCESS) {
-		qla_printk(KERN_WARNING, ha,
-		    "Failed Abort Device Mailbox command. Scheduling ISP "
-		    "abort.\n");
-		set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
-		if (ha->dpc_wait && !ha->dpc_active) 
-			up(ha->dpc_wait);
-		DEBUG2_3_11(printk("qla2x00_abort_device(%ld): failed=%x.\n",
-		    ha->host_no, rval);)
-	} else {
-		/*EMPTY*/
-		DEBUG11(printk("qla2x00_abort_device(%ld): done.\n",
-		    ha->host_no);)
-	}
-
-	return rval;
-}
-
 #if USE_ABORT_TGT
 /*
  * qla2x00_abort_target
@@ -1599,101 +1414,6 @@
 }
 
 /*
- * qla2x00_get_link_status
- *
- * Input:
- *	ha = adapter block pointer.
- *	loop_id = device loop ID.
- *	ret_buf = pointer to link status return buffer.
- *
- * Returns:
- *	0 = success.
- *	BIT_0 = mem alloc error.
- *	BIT_1 = mailbox error.
- */
-uint8_t
-qla2x00_get_link_status(scsi_qla_host_t *ha, uint16_t loop_id,
-    link_stat_t *ret_buf, uint16_t *status)
-{
-	int rval;
-	mbx_cmd_t mc;
-	mbx_cmd_t *mcp = &mc;
-	link_stat_t *stat_buf;
-	dma_addr_t stat_buf_dma;
-
-	DEBUG11(printk("qla2x00_get_link_status(%ld): entered.\n",
-	    ha->host_no);)
-
-	stat_buf = dma_pool_alloc(ha->s_dma_pool, GFP_ATOMIC, &stat_buf_dma);
-	if (stat_buf == NULL) {
-		DEBUG2_3_11(printk("qla2x00_get_link_status(%ld): Failed to "
-		    "allocate memory.\n", ha->host_no));
-		return BIT_0;
-	}
-	memset(stat_buf, 0, sizeof(link_stat_t));
-
-	mcp->mb[0] = MBC_GET_LINK_STATUS;
-	mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
-	if (HAS_EXTENDED_IDS(ha)) {
-		mcp->mb[1] = loop_id;
-		mcp->mb[10] = 0;
-		mcp->out_mb |= MBX_10;
-	} else {
-		mcp->mb[1] = loop_id << 8;
-	}
-	mcp->mb[2] = MSW(stat_buf_dma);
-	mcp->mb[3] = LSW(stat_buf_dma);
-	mcp->mb[6] = MSW(MSD(stat_buf_dma));
-	mcp->mb[7] = LSW(MSD(stat_buf_dma));
-
-	mcp->in_mb = 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("qla2x00_get_link_status(%ld): cmd "
-			    "failed. mbx0=%x.\n", ha->host_no, mcp->mb[0]);)
-			status[0] = mcp->mb[0];
-			rval = BIT_1;
-		} else {
-			/* copy over data -- firmware data is LE. */
-			ret_buf->link_fail_cnt =
-			    le32_to_cpu(stat_buf->link_fail_cnt);
-			ret_buf->loss_sync_cnt =
-			    le32_to_cpu(stat_buf->loss_sync_cnt);
-			ret_buf->loss_sig_cnt =
-			    le32_to_cpu(stat_buf->loss_sig_cnt);
-			ret_buf->prim_seq_err_cnt =
-			    le32_to_cpu(stat_buf->prim_seq_err_cnt);
-			ret_buf->inval_xmit_word_cnt =
-			    le32_to_cpu(stat_buf->inval_xmit_word_cnt);
-			ret_buf->inval_crc_cnt =
-			    le32_to_cpu(stat_buf->inval_crc_cnt);
-
-			DEBUG11(printk("qla2x00_get_link_status(%ld): stat "
-			    "dump: fail_cnt=%d loss_sync=%d loss_sig=%d "
-			    "seq_err=%d inval_xmt_word=%d inval_crc=%d.\n",
-			    ha->host_no,
-			    stat_buf->link_fail_cnt, stat_buf->loss_sync_cnt,
-			    stat_buf->loss_sig_cnt, stat_buf->prim_seq_err_cnt,
-			    stat_buf->inval_xmit_word_cnt,
-			    stat_buf->inval_crc_cnt);)
-		}
-	} else {
-		/* Failed. */
-		DEBUG2_3_11(printk("qla2x00_get_link_status(%ld): failed=%x.\n",
-		    ha->host_no, rval);)
-		rval = BIT_1;
-	}
-
-	dma_pool_free(ha->s_dma_pool, stat_buf, stat_buf_dma);
-
-	return rval;
-}
-
-/*
  * qla2x00_lip_reset
  *	Issue LIP reset mailbox command.
  *
@@ -2108,227 +1828,6 @@
 	}
 
 	return rval;
-}
-
-/*
- * qla2x00_lun_reset
- *	Issue lun reset mailbox command.
- *
- * Input:
- *	ha = adapter block pointer.
- *	loop_id = device loop ID.
- *      lun = lun to be reset.
- *	TARGET_QUEUE_LOCK must be released.
- *	ADAPTER_STATE_LOCK must be released.
- *
- * Returns:
- *	qla2x00 local function return status code.
- *
- * Context:
- *	Kernel context.
- */
-int
-qla2x00_lun_reset(scsi_qla_host_t *ha, uint16_t loop_id, uint16_t lun)
-{
-	int		rval;
-	mbx_cmd_t	mc;
-	mbx_cmd_t	*mcp = &mc;
-
-	mcp->mb[0] = MBC_LUN_RESET;
-	if (HAS_EXTENDED_IDS(ha))
-		mcp->mb[1] = loop_id;
-	else
-		mcp->mb[1] = loop_id << 8;
-	mcp->mb[2] = lun;
-	mcp->out_mb = 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*/
-		printk(KERN_WARNING "qla2x00_lun_reset(%d): failed = %d",
-		    (int)ha->instance, rval);
-	} else {
-		/*EMPTY*/
-	}
-
-	return rval;
-}
-
-/*
- * qla2x00_send_rnid_mbx
- *	Issue RNID ELS using mailbox command
- *
- * Input:
- *	ha = adapter state pointer.
- *	loop_id = loop ID of the target device.
- *	data_fmt = currently supports only 0xDF.
- *	buffer = buffer pointer.
- *	buf_size = size of buffer.
- *	mb_reg = pointer to return mailbox registers.
- *
- * Returns:
- *	qla2x00 local function return status code.
- *
- * Context:
- *	Kernel context.
- */
-int
-qla2x00_send_rnid_mbx(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t data_fmt,
-    dma_addr_t buf_phys_addr, size_t buf_size, uint16_t *mb_reg)
-{
-	int		rval;
-	mbx_cmd_t	mc;
-	mbx_cmd_t	*mcp = &mc;
-
-	DEBUG11(printk("qla2x00_send_rnid_mbx(%ld): entered.\n",
-	    ha->host_no);)
-
-	mcp->mb[0] = MBC_SEND_RNID_ELS;
-	mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
-	if (HAS_EXTENDED_IDS(ha)) {
-		mcp->mb[1] = loop_id;
-		mcp->mb[10] = data_fmt;
-		mcp->out_mb |= MBX_10;
-	} else {
-		mcp->mb[1] = (loop_id << 8) | data_fmt;
-	}
-	mcp->mb[2] = MSW(buf_phys_addr);
-	mcp->mb[3] = LSW(buf_phys_addr);
-	mcp->mb[6] = MSW(MSD(buf_phys_addr));
-	mcp->mb[7] = LSW(MSD(buf_phys_addr));
-
-	mcp->in_mb = MBX_1|MBX_0;
-	mcp->buf_size = buf_size;
-	mcp->flags = MBX_DMA_IN;
-	mcp->tov = 30;
-	rval = qla2x00_mailbox_command(ha, mcp);
-
-	if (rval != QLA_SUCCESS) {
-		memcpy(mb_reg, mcp->mb, 2 * 2); /* 2 status regs */
-
-		DEBUG2_3_11(printk("qla2x00_send_rnid_mbx(%ld): failed=%x "
-		    "mb[1]=%x.\n",
-		    ha->host_no, mcp->mb[0], mcp->mb[1]);)
-	} else {
-		/*EMPTY*/
-	 	DEBUG11(printk("qla2x00_send_rnid_mbx(%ld): done.\n",
-		     ha->host_no);)
-	}
-
-	return (rval);
-}
-
-/*
- * qla2x00_set_rnid_params_mbx
- *	Set RNID parameters using mailbox command
- *
- * Input:
- *	ha = adapter state pointer.
- *	buffer = buffer pointer.
- *	buf_size = size of buffer.
- *	mb_reg = pointer to return mailbox registers.
- *
- * Returns:
- *	qla2x00 local function return status code.
- *
- * Context:
- *	Kernel context.
- */
-int
-qla2x00_set_rnid_params_mbx(scsi_qla_host_t *ha, dma_addr_t buf_phys_addr,
-    size_t buf_size, uint16_t *mb_reg)
-{
-	int		rval;
-	mbx_cmd_t	mc;
-	mbx_cmd_t	*mcp = &mc;
-
-	DEBUG11(printk("qla2x00_set_rnid_params_mbx(%ld): entered.\n",
-	    ha->host_no);)
-
-	mcp->mb[0] = MBC_SET_RNID_PARAMS;
-	mcp->mb[1] = 0;
-	mcp->mb[2] = MSW(buf_phys_addr);
-	mcp->mb[3] = LSW(buf_phys_addr);
-	mcp->mb[6] = MSW(MSD(buf_phys_addr));
-	mcp->mb[7] = LSW(MSD(buf_phys_addr));
-	mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
-	mcp->in_mb = MBX_1|MBX_0;
-	mcp->buf_size = buf_size;
-	mcp->flags = MBX_DMA_OUT;
-	mcp->tov = 30;
-	rval = qla2x00_mailbox_command(ha, mcp);
-
-	if (rval != QLA_SUCCESS) {
-		memcpy(mb_reg, mcp->mb, 2 * 2); /* 2 status regs */
-
-		DEBUG2_3_11(printk("qla2x00_set_rnid_params_mbx(%ld): "
-		    "failed=%x mb[1]=%x.\n", ha->host_no, mcp->mb[0],
-		    mcp->mb[1]);)
-	} else {
-		/*EMPTY*/
-		DEBUG11(printk("qla2x00_set_rnid_params_mbx(%ld): done.\n",
-		    ha->host_no);)
-	}
-
-	return (rval);
-}
-
-/*
- * qla2x00_get_rnid_params_mbx
- *	Get RNID parameters using mailbox command
- *
- * Input:
- *	ha = adapter state pointer.
- *	buffer = buffer pointer.
- *	buf_size = size of buffer.
- *	mb_reg = pointer to return mailbox registers.
- *
- * Returns:
- *	qla2x00 local function return status code.
- *
- * Context:
- *	Kernel context.
- */
-int
-qla2x00_get_rnid_params_mbx(scsi_qla_host_t *ha, dma_addr_t buf_phys_addr,
-    size_t buf_size, uint16_t *mb_reg)
-{
-	int		rval;
-	mbx_cmd_t	mc;
-	mbx_cmd_t	*mcp = &mc;
-
-	DEBUG11(printk("qla2x00_get_rnid_params_mbx(%ld): entered.\n",
-	    ha->host_no);)
-
-	mcp->mb[0] = MBC_GET_RNID_PARAMS;
-	mcp->mb[1] = 0;
-	mcp->mb[2] = MSW(buf_phys_addr);
-	mcp->mb[3] = LSW(buf_phys_addr);
-	mcp->mb[6] = MSW(MSD(buf_phys_addr));
-	mcp->mb[7] = LSW(MSD(buf_phys_addr));
-	mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
-	mcp->in_mb = MBX_1|MBX_0;
-	mcp->buf_size = buf_size;
-	mcp->flags = MBX_DMA_IN;
-	mcp->tov = 30;
-	rval = qla2x00_mailbox_command(ha, mcp);
-
-	if (rval != QLA_SUCCESS) {
-		memcpy(mb_reg, mcp->mb, 2 * 2); /* 2 status regs */
-
-		DEBUG2_3_11(printk("qla2x00_get_rnid_params_mbx(%ld): "
-		    "failed=%x mb[1]=%x.\n", ha->host_no, mcp->mb[0],
-		    mcp->mb[1]);)
-	} else {
-		/*EMPTY*/
-		DEBUG11(printk("qla2x00_get_rnid_params_mbx(%ld): done.\n",
-		    ha->host_no);)
-	}
-
-	return (rval);
 }
 
 /*
diff -Nru a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
--- a/drivers/scsi/qla2xxx/qla_os.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/scsi/qla2xxx/qla_os.c	2005-03-01 23:39:17 -08:00
@@ -151,6 +151,8 @@
  * SCSI host template entry points 
  */
 static int qla2xxx_slave_configure(struct scsi_device * device);
+static int qla2x00_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 *);
@@ -396,8 +398,9 @@
 
 static uint8_t qla2x00_mem_alloc(scsi_qla_host_t *);
 static void qla2x00_mem_free(scsi_qla_host_t *ha);
-int qla2x00_allocate_sp_pool( scsi_qla_host_t *ha);
-void qla2x00_free_sp_pool(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 *ha);
 
 static ssize_t qla2x00_sysfs_read_fw_dump(struct kobject *, char *, loff_t,
     size_t);
@@ -428,13 +431,6 @@
 	.write = qla2x00_sysfs_write_nvram,
 };
 
-
-int
-qla2x00_set_info(char *buffer, int length, struct Scsi_Host *shost)
-{
-	return (-ENOSYS);  /* Currently this is a no-op */
-}
-
 /* -------------------------------------------------------------------------- */
 
 
@@ -570,6 +566,7 @@
 	/* 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,
@@ -583,7 +580,7 @@
 }
 
 /* -------------------------------------------------------------------------- */
-char *
+static char *
 qla2x00_get_pci_info_str(struct scsi_qla_host *ha, char *str)
 {
 	static char *pci_bus_modes[] = {
@@ -663,7 +660,7 @@
 * interrupt handler may call this routine as part of request-completion
 * handling).
 **************************************************************************/
-int
+static int
 qla2x00_queuecommand(struct scsi_cmnd *cmd, void (*fn)(struct scsi_cmnd *))
 {
 	fc_port_t	*fcport;
@@ -754,7 +751,7 @@
 	cmd->host_scribble = (unsigned char *)handle;
 
 	/* Bookkeeping information */
-	sp->r_start = jiffies;       /* time the request was received */
+	sp->r_start = jiffies;		/* Time the request was recieved. */
 	sp->u_start = 0;
 
 	/* Setup device queue pointers. */
@@ -794,7 +791,6 @@
 	} else
 		sp->flags |= SRB_TAPE;
 
-
 	DEBUG5(printk("scsi(%ld:%2d:%2d): (queuecmd) queue sp = %p, "
 	    "flags=0x%x fo retry=%d, pid=%ld\n",
 	    ha->host_no, t, l, sp, sp->flags, sp->fo_retry_cnt,
@@ -836,6 +832,7 @@
 		spin_lock_irq(ha->host->host_lock);
 		return (0);
 	}
+
 	if (tq && test_bit(TQF_SUSPENDED, &tq->flags) &&
 	    (sp->flags & SRB_TAPE) == 0) {
 		/* If target suspended put incoming I/O in retry_q. */
@@ -862,7 +859,7 @@
 	 * In all other cases we'll let an irq pick up our IO and submit it
 	 * to the controller to improve affinity.
 	 */
-	if (smp_processor_id() == ha->last_irq_cpu || was_empty)
+	if (_smp_processor_id() == ha->last_irq_cpu || was_empty)
 		qla2x00_next(ha);
 
 	spin_lock_irq(ha->host->host_lock);
@@ -956,7 +953,7 @@
  *    Success (Adapter is online) : 0
  *    Failed  (Adapter is offline/disabled) : 1
  */
-int 
+static int 
 qla2x00_wait_for_hba_online(scsi_qla_host_t *ha)
 {
 	int 	 return_status;
@@ -1290,7 +1287,7 @@
 *
 * Note:
 **************************************************************************/
-int
+static int
 qla2x00_eh_wait_for_pending_target_commands(scsi_qla_host_t *ha, unsigned int t)
 {
 	int	cnt;
@@ -1502,7 +1499,7 @@
 *
 * Note:
 **************************************************************************/
-int
+static int
 qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *ha)
 {
 	int	cnt;
@@ -2322,7 +2319,7 @@
 		    "%s: has data been written to the file. \n",
 		    __func__);)
 
-		return (qla2x00_set_info(buffer, length, shost));
+		return -ENOSYS;
 	}
 
 	if (start) {
@@ -2342,8 +2339,6 @@
 
 	copy_info(&info, "Driver version %s\n", qla2x00_version_str);
 
-	copy_info(&info, "Entry address = %p\n", qla2x00_set_info);
-
 	tmp_sn = ((ha->serial0 & 0x1f) << 16) | (ha->serial2 << 8) | 
 	    ha->serial1;
 	copy_info(&info, "ISP: %s, Serial# %c%05d\n",
@@ -3146,7 +3141,7 @@
  * 
  * Note: Sets the ref_count for non Null sp to one.
  */
-int
+static int
 qla2x00_allocate_sp_pool(scsi_qla_host_t *ha) 
 {
 	int      rval;
@@ -3165,7 +3160,7 @@
  *  This routine frees all adapter allocated memory.
  *  
  */
-void
+static void
 qla2x00_free_sp_pool( scsi_qla_host_t *ha) 
 {
 	if (ha->srb_mempool) {
@@ -3626,7 +3621,7 @@
  * output:
  *        srb_t * or NULL
  */
-srb_t *
+static srb_t *
 qla2x00_get_new_sp(scsi_qla_host_t *ha)
 {
 	srb_t *sp;
@@ -3911,9 +3906,9 @@
 	if (sp->state == SRB_PENDING_STATE) {
 		__del_from_pending_queue(vis_ha, sp);
 		DEBUG2(printk("scsi(%ld): Found in Pending queue pid %ld, "
-		    "State = %x., fcport state=%d jiffies=%lx\n",
+		    "State = %x., fcport state=%d sjiffs=%lx njiffs=%lx\n",
 		    vis_ha->host_no, cmd->serial_number, sp->state,
-		    atomic_read(&fcport->state), jiffies));
+		    atomic_read(&fcport->state), sp->r_start, jiffies));
 
 		/*
 		 * If FC_DEVICE is marked as dead return the cmd with
@@ -3980,8 +3975,7 @@
 
 	if (processed) {
 		qla2x00_done(dest_ha);
-
-		 return;
+		return;
 	}
 
 	spin_lock_irqsave(&dest_ha->list_lock, cpu_flags);
@@ -4146,13 +4140,13 @@
 
 			default:
 				DEBUG2(printk("scsi(%ld:%d:%d) %s: did_error "
-				    "= %d, comp-scsi= 0x%x-0x%x.\n",
+				    "= %d, comp-scsi= 0x%x-0x%x pid=%ld.\n",
 				    vis_ha->host_no,
 				    cmd->device->id, cmd->device->lun,
 				    __func__,
 				    host_byte(cmd->result),
 				    CMD_COMPL_STATUS(cmd),
-				    CMD_SCSI_STATUS(cmd)));
+				    CMD_SCSI_STATUS(cmd), cmd->serial_number));
 				break;
 		}
 
@@ -4273,11 +4267,10 @@
 			test_bit(ABORT_ISP_ACTIVE, &dest_ha->dpc_flags) ||
 			atomic_read(&dest_ha->loop_state) != LOOP_READY)) {
 
-			DEBUG3(printk("scsi(%ld): port=(0x%x) retry_q(%d) "
-			    "loop state = %d, loop counter = 0x%x dpc flags "
-			    "= 0x%lx\n",
-			    dest_ha->host_no,
-			    fcport->loop_id,
+			DEBUG3(printk("scsi(%ld): pid=%ld port=0x%x state=%d "
+			    "loop state=%d, loop counter=0x%x "
+			    "dpc_flags=0x%lx\n", sp->cmd->serial_number,
+			    dest_ha->host_no, fcport->loop_id,
 			    atomic_read(&fcport->state),
 			    atomic_read(&dest_ha->loop_state),
 			    atomic_read(&dest_ha->loop_down_timer),
@@ -4327,105 +4320,6 @@
 	}
 }
 
-
-/**************************************************************************
-*   qla2x00_check_tgt_status
-*
-* Description:
-*     Checks to see if the target or loop is down.
-*
-* Input:
-*     cmd - pointer to Scsi cmd structure
-*
-* Returns:
-*   1 - if target is present
-*   0 - if target is not present
-*
-**************************************************************************/
-int
-qla2x00_check_tgt_status(scsi_qla_host_t *ha, struct scsi_cmnd *cmd)
-{
-	os_lun_t        *lq;
-	unsigned int	b, t, l;
-	fc_port_t	*fcport;
-
-	/* Generate LU queue on bus, target, LUN */
-	b = cmd->device->channel;
-	t = cmd->device->id;
-	l = cmd->device->lun;
-
-	if ((lq = GET_LU_Q(ha,t,l)) == NULL) {
-		return (QLA_FUNCTION_FAILED);
-	}
-
-	fcport = lq->fclun->fcport;
-
-	if (TGT_Q(ha, t) == NULL ||
-	    l >= ha->max_luns ||
-	    atomic_read(&fcport->state) == FCS_DEVICE_DEAD ||
-	    atomic_read(&ha->loop_state) == LOOP_DEAD ||
-	    (!atomic_read(&ha->loop_down_timer) &&
-		atomic_read(&ha->loop_state) == LOOP_DOWN) ||
-	    test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags) ||
-	    test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags) ||
-	    atomic_read(&ha->loop_state) != LOOP_READY) {
-
-		DEBUG(printk(KERN_INFO
-		    "scsi(%ld:%2d:%2d:%2d): %s connection is down\n",
-		    ha->host_no,
-		    b, t, l,
-		    __func__));
-
-		cmd->result = DID_NO_CONNECT << 16;
-		return (QLA_FUNCTION_FAILED);
-	}
-	return (QLA_SUCCESS);
-}
-
-/**************************************************************************
-*   qla2x00_check_port_status
-*
-* Description:
-*     Checks to see if the port or loop is down.
-*
-* Input:
-*     fcport - pointer to fc_port_t structure.
-*
-* Returns:
-*   1 - if port is present
-*   0 - if port is not present
-*
-**************************************************************************/
-int
-qla2x00_check_port_status(scsi_qla_host_t *ha, fc_port_t *fcport)
-{
-	if (fcport == NULL) {
-		return (QLA_FUNCTION_FAILED);
-	}
-
-	if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD ||
-	    atomic_read(&ha->loop_state) == LOOP_DEAD) {
-		return (QLA_FUNCTION_FAILED);
-	}
-
-	if ((atomic_read(&fcport->state) != FCS_ONLINE) || 
-	    (!atomic_read(&ha->loop_down_timer) &&
-		atomic_read(&ha->loop_state) == LOOP_DOWN) ||
-	    (test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags)) ||
-	    test_bit(CFG_ACTIVE, &ha->cfg_flags) ||
-	    test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags) ||
-	    atomic_read(&ha->loop_state) != LOOP_READY) {
-
-		DEBUG(printk(KERN_INFO
-		    "scsi(%ld): Connection is down. fcport=%p.\n",
-		    ha->host_no, fcport));
-
-		return (QLA_BUSY);
-	}
-
-	return (QLA_SUCCESS);
-}
-
 /* XXX(hch): crude hack to emulate a down_timeout() */
 int
 qla2x00_down_timeout(struct semaphore *sema, unsigned long timeout)
@@ -4530,9 +4424,7 @@
 	if (!qla2xxx_transport_template)
 		return -ENODEV;
 
-	printk(KERN_INFO
-	    "QLogic Fibre Channel HBA Driver (%p)\n", qla2x00_set_info);
-
+	printk(KERN_INFO "QLogic Fibre Channel HBA Driver\n");
 	return 0;
 }
 
diff -Nru a/drivers/scsi/qla2xxx/qla_rscn.c b/drivers/scsi/qla2xxx/qla_rscn.c
--- a/drivers/scsi/qla2xxx/qla_rscn.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/scsi/qla2xxx/qla_rscn.c	2005-03-01 23:38:55 -08:00
@@ -85,7 +85,7 @@
 /** 
  * Mailbox IOCB callback array.
  **/
-int (*iocb_function_cb_list[LAST_IOCB_CB])
+static int (*iocb_function_cb_list[LAST_IOCB_CB])
 	(scsi_qla_host_t *, struct io_descriptor *, struct mbx_entry *) = {
 
 	qla2x00_send_abort_iocb_cb,
diff -Nru a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c
--- a/drivers/scsi/qla2xxx/qla_sup.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/scsi/qla2xxx/qla_sup.c	2005-03-01 23:38:52 -08:00
@@ -26,7 +26,6 @@
 static void qla2x00_nv_deselect(scsi_qla_host_t *);
 static void qla2x00_nv_write(scsi_qla_host_t *, uint16_t);
 
-
 /*
  * NVRAM support routines
  */
@@ -80,6 +79,56 @@
 }
 
 /**
+ * qla2x00_release_nvram_protection() - 
+ * @ha: HA context
+ */
+void
+qla2x00_release_nvram_protection(scsi_qla_host_t *ha)
+{
+	device_reg_t *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
@@ -123,29 +172,6 @@
 
 	qla2x00_nv_deselect(ha);
 
-	/* Erase Location */
-	nv_cmd = (addr << 16) | NV_ERASE_OP;
-	nv_cmd <<= 5;
-	for (count = 0; count < 11; 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 Erase to Finish */
-	WRT_REG_WORD(&reg->nvram, NVR_SELECT);
-	do {
-		NVRAM_DELAY();
-		word = RD_REG_WORD(&reg->nvram);
-	} while ((word & NVR_DATA_IN) == 0);
-
-	qla2x00_nv_deselect(ha);
-
 	/* Write data */
 	nv_cmd = (addr << 16) | NV_WRITE_OP;
 	nv_cmd |= data;
@@ -220,14 +246,14 @@
 		if (reg_data & NVR_DATA_IN)
 			data |= BIT_0;
 		WRT_REG_WORD(&reg->nvram, NVR_SELECT);
-		NVRAM_DELAY();
 		RD_REG_WORD(&reg->nvram);	/* PCI Posting. */
+		NVRAM_DELAY();
 	}
 
 	/* Deselect chip. */
 	WRT_REG_WORD(&reg->nvram, NVR_DESELECT);
-	NVRAM_DELAY();
 	RD_REG_WORD(&reg->nvram);		/* PCI Posting. */
+	NVRAM_DELAY();
 
 	return (data);
 }
@@ -236,14 +262,14 @@
  * qla2x00_nv_write() - Clean NVRAM operations.
  * @ha: HA context
  */
-void
+static void
 qla2x00_nv_deselect(scsi_qla_host_t *ha)
 {
 	device_reg_t __iomem *reg = ha->iobase;
 
 	WRT_REG_WORD(&reg->nvram, NVR_DESELECT);
-	NVRAM_DELAY();
 	RD_REG_WORD(&reg->nvram);		/* PCI Posting. */
+	NVRAM_DELAY();
 }
 
 /**
@@ -251,19 +277,20 @@
  * @ha: HA context
  * @data: Serial interface selector
  */
-void
+static void
 qla2x00_nv_write(scsi_qla_host_t *ha, uint16_t data)
 {
 	device_reg_t __iomem *reg = ha->iobase;
 
-	WRT_REG_WORD(&reg->nvram, data | NVR_SELECT);
-	NVRAM_DELAY();
+	WRT_REG_WORD(&reg->nvram, data | NVR_SELECT | NVR_WRT_ENABLE);
 	RD_REG_WORD(&reg->nvram);		/* PCI Posting. */
-	WRT_REG_WORD(&reg->nvram, data | NVR_SELECT | NVR_CLOCK);
 	NVRAM_DELAY();
+	WRT_REG_WORD(&reg->nvram, data | NVR_SELECT| NVR_CLOCK |
+	    NVR_WRT_ENABLE);
 	RD_REG_WORD(&reg->nvram);		/* PCI Posting. */
-	WRT_REG_WORD(&reg->nvram, data | NVR_SELECT);
 	NVRAM_DELAY();
+	WRT_REG_WORD(&reg->nvram, data | NVR_SELECT | NVR_WRT_ENABLE);
 	RD_REG_WORD(&reg->nvram);		/* PCI Posting. */
+	NVRAM_DELAY();
 }
 
diff -Nru a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h
--- a/drivers/scsi/qla2xxx/qla_version.h	2005-03-01 23:38:56 -08:00
+++ b/drivers/scsi/qla2xxx/qla_version.h	2005-03-01 23:38:56 -08:00
@@ -19,9 +19,9 @@
 /*
  * Driver version 
  */
-#define QLA2XXX_VERSION      "8.00.00b21-k"
+#define QLA2XXX_VERSION      "8.00.02b4-k"
 
 #define QLA_DRIVER_MAJOR_VER	8
 #define QLA_DRIVER_MINOR_VER	0
-#define QLA_DRIVER_PATCH_VER	0
-#define QLA_DRIVER_BETA_VER	21
+#define QLA_DRIVER_PATCH_VER	2
+#define QLA_DRIVER_BETA_VER	4
diff -Nru a/drivers/scsi/qlogicfas.c b/drivers/scsi/qlogicfas.c
--- a/drivers/scsi/qlogicfas.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/scsi/qlogicfas.c	2005-03-01 23:39:17 -08:00
@@ -137,8 +137,8 @@
 static struct qlogicfas408_priv *cards;
 static int iobase[MAX_QLOGICFAS];
 static int irq[MAX_QLOGICFAS] = { [0 ... MAX_QLOGICFAS-1] = -1 };
-MODULE_PARM(iobase, "1-" __MODULE_STRING(MAX_QLOGICFAS) "i");
-MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_QLOGICFAS) "i");
+module_param_array(iobase, int, NULL, 0);
+module_param_array(irq, int, NULL, 0);
 MODULE_PARM_DESC(iobase, "I/O address");
 MODULE_PARM_DESC(irq, "IRQ");
 
diff -Nru a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c
--- a/drivers/scsi/qlogicpti.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/scsi/qlogicpti.c	2005-03-01 23:39:07 -08:00
@@ -56,7 +56,7 @@
 #include "qlogicpti_asm.c"
 
 static struct qlogicpti *qptichain = NULL;
-static spinlock_t qptichain_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(qptichain_lock);
 static int qptis_running = 0;
 
 #define PACKB(a, b)			(((a)<<4)|(b))
diff -Nru a/drivers/scsi/sata_nv.c b/drivers/scsi/sata_nv.c
--- a/drivers/scsi/sata_nv.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/scsi/sata_nv.c	2005-03-01 23:38:53 -08:00
@@ -20,6 +20,10 @@
  *  If you do not delete the provisions above, a recipient may use your
  *  version of this file under either the OSL or the GPL.
  *
+ *  0.06
+ *     - Added generic SATA support by using a pci_device_id that filters on
+ *       the IDE storage class code.
+ *
  *  0.03
  *     - Fixed a bug where the hotplug handlers for non-CK804/MCP04 were using
  *       mmio_base, which is only set for the CK804/MCP04 case.
@@ -44,7 +48,7 @@
 #include <linux/libata.h>
 
 #define DRV_NAME			"sata_nv"
-#define DRV_VERSION			"0.5"
+#define DRV_VERSION			"0.6"
 
 #define NV_PORTS			2
 #define NV_PIO_MASK			0x1f
@@ -108,6 +112,7 @@
 
 enum nv_host_type
 {
+	GENERIC,
 	NFORCE2,
 	NFORCE3,
 	CK804
@@ -128,6 +133,9 @@
 		PCI_ANY_ID, PCI_ANY_ID, 0, 0, CK804 },
 	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA2,
 		PCI_ANY_ID, PCI_ANY_ID, 0, 0, CK804 },
+	{ PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID,
+		PCI_ANY_ID, PCI_ANY_ID,
+		PCI_CLASS_STORAGE_IDE<<8, 0xffff00, GENERIC },
 	{ 0, } /* terminate list */
 };
 
@@ -136,7 +144,6 @@
 struct nv_host_desc
 {
 	enum nv_host_type	host_type;
-	unsigned long		host_flags;
 	void			(*enable_hotplug)(struct ata_probe_ent *probe_ent);
 	void			(*disable_hotplug)(struct ata_host_set *host_set);
 	void			(*check_hotplug)(struct ata_host_set *host_set);
@@ -144,21 +151,24 @@
 };
 static struct nv_host_desc nv_device_tbl[] = {
 	{
+		.host_type	= GENERIC,
+		.enable_hotplug	= NULL,
+		.disable_hotplug= NULL,
+		.check_hotplug	= NULL,
+	},
+	{
 		.host_type	= NFORCE2,
-		.host_flags	= 0x00000000,
 		.enable_hotplug	= nv_enable_hotplug,
 		.disable_hotplug= nv_disable_hotplug,
 		.check_hotplug	= nv_check_hotplug,
 	},
 	{
 		.host_type	= NFORCE3,
-		.host_flags	= 0x00000000,
 		.enable_hotplug	= nv_enable_hotplug,
 		.disable_hotplug= nv_disable_hotplug,
 		.check_hotplug	= nv_check_hotplug,
 	},
 	{	.host_type	= CK804,
-		.host_flags	= NV_HOST_FLAGS_SCR_MMIO,
 		.enable_hotplug	= nv_enable_hotplug_ck804,
 		.disable_hotplug= nv_disable_hotplug_ck804,
 		.check_hotplug	= nv_check_hotplug_ck804,
@@ -168,6 +178,7 @@
 struct nv_host
 {
 	struct nv_host_desc	*host_desc;
+	unsigned long		host_flags;
 };
 
 static struct pci_driver nv_pci_driver = {
@@ -206,6 +217,8 @@
 	.phy_reset		= sata_phy_reset,
 	.bmdma_setup		= ata_bmdma_setup,
 	.bmdma_start		= ata_bmdma_start,
+	.bmdma_stop		= ata_bmdma_stop,
+	.bmdma_status		= ata_bmdma_status,
 	.qc_prep		= ata_qc_prep,
 	.qc_issue		= ata_qc_issue_prot,
 	.eng_timeout		= ata_eng_timeout,
@@ -284,8 +297,8 @@
 	if (sc_reg > SCR_CONTROL)
 		return 0xffffffffU;
 
-	if (host->host_desc->host_flags & NV_HOST_FLAGS_SCR_MMIO)
-		return readl(ap->ioaddr.scr_addr + (sc_reg * 4));
+	if (host->host_flags & NV_HOST_FLAGS_SCR_MMIO)
+		return readl((void*)ap->ioaddr.scr_addr + (sc_reg * 4));
 	else
 		return inl(ap->ioaddr.scr_addr + (sc_reg * 4));
 }
@@ -298,8 +311,8 @@
 	if (sc_reg > SCR_CONTROL)
 		return;
 
-	if (host->host_desc->host_flags & NV_HOST_FLAGS_SCR_MMIO)
-		writel(val, ap->ioaddr.scr_addr + (sc_reg * 4));
+	if (host->host_flags & NV_HOST_FLAGS_SCR_MMIO)
+		writel(val, (void*)ap->ioaddr.scr_addr + (sc_reg * 4));
 	else
 		outl(val, ap->ioaddr.scr_addr + (sc_reg * 4));
 }
@@ -321,7 +334,16 @@
 	struct nv_host *host;
 	struct ata_port_info *ppi;
 	struct ata_probe_ent *probe_ent;
+	int pci_dev_busy = 0;
 	int rc;
+	u32 bar;
+
+        // Make sure this is a SATA controller by counting the number of bars
+        // (NVIDIA SATA controllers will always have six bars).  Otherwise,
+        // it's an IDE controller and we ignore it.
+	for (bar=0; bar<6; bar++)
+		if (pci_resource_start(pdev, bar) == 0)
+			return -ENODEV;
 
 	if (!printed_version++)
 		printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
@@ -331,8 +353,10 @@
 		goto err_out;
 
 	rc = pci_request_regions(pdev, DRV_NAME);
-	if (rc)
+	if (rc) {
+		pci_dev_busy = 1;
 		goto err_out_disable;
+	}
 
 	rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
 	if (rc)
@@ -352,11 +376,15 @@
 	if (!host)
 		goto err_out_free_ent;
 
+	memset(host, 0, sizeof(struct nv_host));
 	host->host_desc = &nv_device_tbl[ent->driver_data];
 
 	probe_ent->private_data = host;
 
-	if (host->host_desc->host_flags & NV_HOST_FLAGS_SCR_MMIO) {
+	if (pci_resource_flags(pdev, 5) & IORESOURCE_MEM)
+		host->host_flags |= NV_HOST_FLAGS_SCR_MMIO;
+
+	if (host->host_flags & NV_HOST_FLAGS_SCR_MMIO) {
 		unsigned long base;
 
 		probe_ent->mmio_base = ioremap(pci_resource_start(pdev, 5),
@@ -395,7 +423,7 @@
 	return 0;
 
 err_out_iounmap:
-	if (host->host_desc->host_flags & NV_HOST_FLAGS_SCR_MMIO)
+	if (host->host_flags & NV_HOST_FLAGS_SCR_MMIO)
 		iounmap(probe_ent->mmio_base);
 err_out_free_host:
 	kfree(host);
@@ -404,7 +432,8 @@
 err_out_regions:
 	pci_release_regions(pdev);
 err_out_disable:
-	pci_disable_device(pdev);
+	if (!pci_dev_busy)
+		pci_disable_device(pdev);
 err_out:
 	return rc;
 }
diff -Nru a/drivers/scsi/sata_promise.c b/drivers/scsi/sata_promise.c
--- a/drivers/scsi/sata_promise.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/scsi/sata_promise.c	2005-03-01 23:39:08 -08:00
@@ -156,10 +156,18 @@
 	  board_2037x },
 	{ PCI_VENDOR_ID_PROMISE, 0x3376, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 	  board_2037x },
+	{ PCI_VENDOR_ID_PROMISE, 0x3574, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+	  board_2037x },
+	{ PCI_VENDOR_ID_PROMISE, 0x3d75, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+	  board_2037x },
+
 	{ PCI_VENDOR_ID_PROMISE, 0x3318, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 	  board_20319 },
 	{ PCI_VENDOR_ID_PROMISE, 0x3319, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 	  board_20319 },
+	{ PCI_VENDOR_ID_PROMISE, 0x3d18, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+	  board_20319 },
+
 	{ }	/* terminate list */
 };
 
@@ -406,9 +414,11 @@
 		return IRQ_NONE;
 	}
 
-        spin_lock(&host_set->lock);
+	spin_lock(&host_set->lock);
 
-        for (i = 0; i < host_set->n_ports; i++) {
+	writel(mask, mmio_base + PDC_INT_SEQMASK);
+
+	for (i = 0; i < host_set->n_ports; i++) {
 		VPRINTK("port %u\n", i);
 		ap = host_set->ports[i];
 		tmp = mask & (1 << (i + 1));
@@ -546,6 +556,7 @@
 	unsigned long base;
 	void *mmio_base;
 	unsigned int board_idx = (unsigned int) ent->driver_data;
+	int pci_dev_busy = 0;
 	int rc;
 
 	if (!printed_version++)
@@ -560,8 +571,10 @@
 		return rc;
 
 	rc = pci_request_regions(pdev, DRV_NAME);
-	if (rc)
+	if (rc) {
+		pci_dev_busy = 1;
 		goto err_out;
+	}
 
 	rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
 	if (rc)
@@ -640,7 +653,8 @@
 err_out_regions:
 	pci_release_regions(pdev);
 err_out:
-	pci_disable_device(pdev);
+	if (!pci_dev_busy)
+		pci_disable_device(pdev);
 	return rc;
 }
 
diff -Nru a/drivers/scsi/sata_qstor.c b/drivers/scsi/sata_qstor.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/scsi/sata_qstor.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,700 @@
+/*
+ *  sata_qstor.c - Pacific Digital Corporation QStor SATA
+ *
+ *  Maintained by:  Mark Lord <mlord@pobox.com>
+ *
+ *  Copyright 2005 Pacific Digital Corporation.
+ *  (OSL/GPL code release authorized by Jalil Fadavi).
+ *
+ *  The contents of this file are subject to the Open
+ *  Software License version 1.1 that can be found at
+ *  http://www.opensource.org/licenses/osl-1.1.txt and is included herein
+ *  by reference.
+ *
+ *  Alternatively, the contents of this file may be used under the terms
+ *  of the GNU General Public License version 2 (the "GPL") as distributed
+ *  in the kernel source COPYING file, in which case the provisions of
+ *  the GPL are applicable instead of the above.  If you wish to allow
+ *  the use of your version of this file only under the terms of the
+ *  GPL and not to allow others to use your version of this file under
+ *  the OSL, indicate your decision by deleting the provisions above and
+ *  replace them with the notice and other provisions required by the GPL.
+ *  If you do not delete the provisions above, a recipient may use your
+ *  version of this file under either the OSL or the GPL.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/blkdev.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include "scsi.h"
+#include <scsi/scsi_host.h>
+#include <asm/io.h>
+#include <linux/libata.h>
+
+#define DRV_NAME	"sata_qstor"
+#define DRV_VERSION	"0.03"
+
+enum {
+	QS_PORTS		= 4,
+	QS_MAX_PRD		= LIBATA_MAX_PRD,
+	QS_CPB_ORDER		= 6,
+	QS_CPB_BYTES		= (1 << QS_CPB_ORDER),
+	QS_PRD_BYTES		= QS_MAX_PRD * 16,
+	QS_PKT_BYTES		= QS_CPB_BYTES + QS_PRD_BYTES,
+
+	QS_DMA_BOUNDARY		= ~0UL,
+
+	/* global register offsets */
+	QS_HCF_CNFG3		= 0x0003, /* host configuration offset */
+	QS_HID_HPHY		= 0x0004, /* host physical interface info */
+	QS_HCT_CTRL		= 0x00e4, /* global interrupt mask offset */
+	QS_HST_SFF		= 0x0100, /* host status fifo offset */
+	QS_HVS_SERD3		= 0x0393, /* PHY enable offset */
+
+	/* global control bits */
+	QS_HPHY_64BIT		= (1 << 1), /* 64-bit bus detected */
+	QS_CNFG3_GSRST		= 0x01,     /* global chip reset */
+	QS_SERD3_PHY_ENA	= 0xf0,     /* PHY detection ENAble*/
+
+	/* per-channel register offsets */
+	QS_CCF_CPBA		= 0x0710, /* chan CPB base address */
+	QS_CCF_CSEP		= 0x0718, /* chan CPB separation factor */
+	QS_CFC_HUFT		= 0x0800, /* host upstream fifo threshold */
+	QS_CFC_HDFT		= 0x0804, /* host downstream fifo threshold */
+	QS_CFC_DUFT		= 0x0808, /* dev upstream fifo threshold */
+	QS_CFC_DDFT		= 0x080c, /* dev downstream fifo threshold */
+	QS_CCT_CTR0		= 0x0900, /* chan control-0 offset */
+	QS_CCT_CTR1		= 0x0901, /* chan control-1 offset */
+	QS_CCT_CFF		= 0x0a00, /* chan command fifo offset */
+
+	/* channel control bits */
+	QS_CTR0_REG		= (1 << 1),   /* register mode (vs. pkt mode) */
+	QS_CTR0_CLER		= (1 << 2),   /* clear channel errors */
+	QS_CTR1_RDEV		= (1 << 1),   /* sata phy/comms reset */
+	QS_CTR1_RCHN		= (1 << 4),   /* reset channel logic */
+	QS_CCF_RUN_PKT		= 0x107,      /* RUN a new dma PKT */
+
+	/* pkt sub-field headers */
+	QS_HCB_HDR		= 0x01,   /* Host Control Block header */
+	QS_DCB_HDR		= 0x02,   /* Device Control Block header */
+
+	/* pkt HCB flag bits */
+	QS_HF_DIRO		= (1 << 0),   /* data DIRection Out */
+	QS_HF_DAT		= (1 << 3),   /* DATa pkt */
+	QS_HF_IEN		= (1 << 4),   /* Interrupt ENable */
+	QS_HF_VLD		= (1 << 5),   /* VaLiD pkt */
+
+	/* pkt DCB flag bits */
+	QS_DF_PORD		= (1 << 2),   /* Pio OR Dma */
+	QS_DF_ELBA		= (1 << 3),   /* Extended LBA (lba48) */
+
+	/* PCI device IDs */
+	board_2068_idx		= 0,	/* QStor 4-port SATA/RAID */
+};
+
+typedef enum { qs_state_idle, qs_state_pkt, qs_state_mmio } qs_state_t;
+
+struct qs_port_priv {
+	u8			*pkt;
+	dma_addr_t		pkt_dma;
+	qs_state_t		state;
+};
+
+static u32 qs_scr_read (struct ata_port *ap, unsigned int sc_reg);
+static void qs_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
+static int qs_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
+static irqreturn_t qs_intr (int irq, void *dev_instance, struct pt_regs *regs);
+static int qs_port_start(struct ata_port *ap);
+static void qs_host_stop(struct ata_host_set *host_set);
+static void qs_port_stop(struct ata_port *ap);
+static void qs_phy_reset(struct ata_port *ap);
+static void qs_qc_prep(struct ata_queued_cmd *qc);
+static int qs_qc_issue(struct ata_queued_cmd *qc);
+static int qs_check_atapi_dma(struct ata_queued_cmd *qc);
+static void qs_bmdma_stop(struct ata_port *ap);
+static u8 qs_bmdma_status(struct ata_port *ap);
+static void qs_irq_clear(struct ata_port *ap);
+
+static Scsi_Host_Template qs_ata_sht = {
+	.module			= THIS_MODULE,
+	.name			= DRV_NAME,
+	.ioctl			= ata_scsi_ioctl,
+	.queuecommand		= ata_scsi_queuecmd,
+	.eh_strategy_handler	= ata_scsi_error,
+	.can_queue		= ATA_DEF_QUEUE,
+	.this_id		= ATA_SHT_THIS_ID,
+	.sg_tablesize		= QS_MAX_PRD,
+	.max_sectors		= ATA_MAX_SECTORS,
+	.cmd_per_lun		= ATA_SHT_CMD_PER_LUN,
+	.emulated		= ATA_SHT_EMULATED,
+	//FIXME .use_clustering		= ATA_SHT_USE_CLUSTERING,
+	.use_clustering		= ENABLE_CLUSTERING,
+	.proc_name		= DRV_NAME,
+	.dma_boundary		= QS_DMA_BOUNDARY,
+	.slave_configure	= ata_scsi_slave_config,
+	.bios_param		= ata_std_bios_param,
+};
+
+static struct ata_port_operations qs_ata_ops = {
+	.port_disable		= ata_port_disable,
+	.tf_load		= ata_tf_load,
+	.tf_read		= ata_tf_read,
+	.check_status		= ata_check_status,
+	.check_atapi_dma	= qs_check_atapi_dma,
+	.exec_command		= ata_exec_command,
+	.dev_select		= ata_std_dev_select,
+	.phy_reset		= qs_phy_reset,
+	.qc_prep		= qs_qc_prep,
+	.qc_issue		= qs_qc_issue,
+	.eng_timeout		= ata_eng_timeout,
+	.irq_handler		= qs_intr,
+	.irq_clear		= qs_irq_clear,
+	.scr_read		= qs_scr_read,
+	.scr_write		= qs_scr_write,
+	.port_start		= qs_port_start,
+	.port_stop		= qs_port_stop,
+	.host_stop		= qs_host_stop,
+	.bmdma_stop		= qs_bmdma_stop,
+	.bmdma_status		= qs_bmdma_status,
+};
+
+static struct ata_port_info qs_port_info[] = {
+	/* board_2068_idx */
+	{
+		.sht		= &qs_ata_sht,
+		.host_flags	= ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+				  ATA_FLAG_SATA_RESET |
+				  //FIXME ATA_FLAG_SRST |
+				  ATA_FLAG_MMIO,
+		.pio_mask	= 0x10, /* pio4 */
+		.udma_mask	= 0x7f, /* udma0-6 */
+		.port_ops	= &qs_ata_ops,
+	},
+};
+
+static struct pci_device_id qs_ata_pci_tbl[] = {
+	{ PCI_VENDOR_ID_PDC, 0x2068, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+	  board_2068_idx },
+
+	{ }	/* terminate list */
+};
+
+static struct pci_driver qs_ata_pci_driver = {
+	.name			= DRV_NAME,
+	.id_table		= qs_ata_pci_tbl,
+	.probe			= qs_ata_init_one,
+	.remove			= ata_pci_remove_one,
+};
+
+static int qs_check_atapi_dma(struct ata_queued_cmd *qc)
+{
+	return 1;	/* ATAPI DMA not supported */
+}
+
+static void qs_bmdma_stop(struct ata_port *ap)
+{
+	/* nothing */
+}
+
+static u8 qs_bmdma_status(struct ata_port *ap)
+{
+	return 0;
+}
+
+static void qs_irq_clear(struct ata_port *ap)
+{
+	/* nothing */
+}
+
+static void qs_enter_reg_mode(struct ata_port *ap)
+{
+	u8 __iomem *chan = ap->host_set->mmio_base + (ap->port_no * 0x4000);
+
+	writeb(QS_CTR0_REG, chan + QS_CCT_CTR0);
+	readb(chan + QS_CCT_CTR0);        /* flush */
+}
+
+static void qs_phy_reset(struct ata_port *ap)
+{
+	u8 __iomem *chan = ap->host_set->mmio_base + (ap->port_no * 0x4000);
+	struct qs_port_priv *pp = ap->private_data;
+
+	pp->state = qs_state_idle;
+	writeb(QS_CTR1_RCHN, chan + QS_CCT_CTR1);
+	qs_enter_reg_mode(ap);
+	sata_phy_reset(ap);
+}
+
+static u32 qs_scr_read (struct ata_port *ap, unsigned int sc_reg)
+{
+	if (sc_reg > SCR_CONTROL)
+		return ~0U;
+	return readl((void __iomem *)(ap->ioaddr.scr_addr + (sc_reg * 8)));
+}
+
+static void qs_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
+{
+	if (sc_reg > SCR_CONTROL)
+		return;
+	writel(val, (void __iomem *)(ap->ioaddr.scr_addr + (sc_reg * 8)));
+}
+
+static void qs_fill_sg(struct ata_queued_cmd *qc)
+{
+	struct scatterlist *sg = qc->sg;
+	struct ata_port *ap = qc->ap;
+	struct qs_port_priv *pp = ap->private_data;
+	unsigned int nelem;
+	u8 *prd = pp->pkt + QS_CPB_BYTES;
+
+	assert(sg != NULL);
+	assert(qc->n_elem > 0);
+
+	for (nelem = 0; nelem < qc->n_elem; nelem++,sg++) {
+		u64 addr;
+		u32 len;
+
+		addr = sg_dma_address(sg);
+		*(u64 *)prd = cpu_to_le64(addr);
+		prd += sizeof(u64);
+
+		len = sg_dma_len(sg);
+		*(u32 *)prd = cpu_to_le32(len);
+		prd += sizeof(u64);
+
+		VPRINTK("PRD[%u] = (0x%llX, 0x%X)\n", nelem,
+					(unsigned long long)addr, len);
+	}
+}
+
+static void qs_qc_prep(struct ata_queued_cmd *qc)
+{
+	struct qs_port_priv *pp = qc->ap->private_data;
+	u8 dflags = QS_DF_PORD, *buf = pp->pkt;
+	u8 hflags = QS_HF_DAT | QS_HF_IEN | QS_HF_VLD;
+	u64 addr;
+
+	VPRINTK("ENTER\n");
+
+	qs_enter_reg_mode(qc->ap);
+	if (qc->tf.protocol != ATA_PROT_DMA) {
+		ata_qc_prep(qc);
+		return;
+	}
+
+	qs_fill_sg(qc);
+
+	if ((qc->tf.flags & ATA_TFLAG_WRITE))
+		hflags |= QS_HF_DIRO;
+	if ((qc->tf.flags & ATA_TFLAG_LBA48))
+		dflags |= QS_DF_ELBA;
+
+	/* host control block (HCB) */
+	buf[ 0] = QS_HCB_HDR;
+	buf[ 1] = hflags;
+	*(u32 *)(&buf[ 4]) = cpu_to_le32(qc->nsect * ATA_SECT_SIZE);
+	*(u32 *)(&buf[ 8]) = cpu_to_le32(qc->n_elem);
+	addr = ((u64)pp->pkt_dma) + QS_CPB_BYTES;
+	*(u64 *)(&buf[16]) = cpu_to_le64(addr);
+
+	/* device control block (DCB) */
+	buf[24] = QS_DCB_HDR;
+	buf[28] = dflags;
+
+	/* frame information structure (FIS) */
+	ata_tf_to_fis(&qc->tf, &buf[32], 0);
+}
+
+static inline void qs_packet_start(struct ata_queued_cmd *qc)
+{
+	struct ata_port *ap = qc->ap;
+	u8 __iomem *chan = ap->host_set->mmio_base + (ap->port_no * 0x4000);
+
+	VPRINTK("ENTER, ap %p\n", ap);
+
+	writeb(QS_CTR0_CLER, chan + QS_CCT_CTR0);
+	wmb();                             /* flush PRDs and pkt to memory */
+	writel(QS_CCF_RUN_PKT, chan + QS_CCT_CFF);
+	readl(chan + QS_CCT_CFF);          /* flush */
+}
+
+static int qs_qc_issue(struct ata_queued_cmd *qc)
+{
+	struct qs_port_priv *pp = qc->ap->private_data;
+
+	switch (qc->tf.protocol) {
+	case ATA_PROT_DMA:
+
+		pp->state = qs_state_pkt;
+		qs_packet_start(qc);
+		return 0;
+
+	case ATA_PROT_ATAPI_DMA:
+		BUG();
+		break;
+
+	default:
+		break;
+	}
+
+	pp->state = qs_state_mmio;
+	return ata_qc_issue_prot(qc);
+}
+
+static inline unsigned int qs_intr_pkt(struct ata_host_set *host_set)
+{
+	unsigned int handled = 0;
+	u8 sFFE;
+	u8 __iomem *mmio_base = host_set->mmio_base;
+
+	do {
+		u32 sff0 = readl(mmio_base + QS_HST_SFF);
+		u32 sff1 = readl(mmio_base + QS_HST_SFF + 4);
+		u8 sEVLD = (sff1 >> 30) & 0x01;	/* valid flag */
+		sFFE  = sff1 >> 31;		/* empty flag */
+
+		if (sEVLD) {
+			u8 sDST = sff0 >> 16;	/* dev status */
+			u8 sHST = sff1 & 0x3f;	/* host status */
+			unsigned int port_no = (sff1 >> 8) & 0x03;
+			struct ata_port *ap = host_set->ports[port_no];
+
+			DPRINTK("SFF=%08x%08x: sCHAN=%u sHST=%d sDST=%02x\n",
+					sff1, sff0, port_no, sHST, sDST);
+			handled = 1;
+			if (ap && (!(ap->flags & ATA_FLAG_PORT_DISABLED))) {
+				struct ata_queued_cmd *qc;
+				struct qs_port_priv *pp = ap->private_data;
+				if (!pp || pp->state != qs_state_pkt)
+					continue;
+				qc = ata_qc_from_tag(ap, ap->active_tag);
+				if (qc && (!(qc->tf.ctl & ATA_NIEN))) {
+					switch (sHST) {
+					case 0: /* sucessful CPB */
+					case 3: /* device error */
+						pp->state = qs_state_idle;
+						qs_enter_reg_mode(qc->ap);
+						ata_qc_complete(qc, sDST);
+						break;
+					default:
+						break;
+					}
+				}
+			}
+		}
+	} while (!sFFE);
+	return handled;
+}
+
+static inline unsigned int qs_intr_mmio(struct ata_host_set *host_set)
+{
+	unsigned int handled = 0, port_no;
+
+	for (port_no = 0; port_no < host_set->n_ports; ++port_no) {
+		struct ata_port *ap;
+		ap = host_set->ports[port_no];
+		if (ap && (!(ap->flags & ATA_FLAG_PORT_DISABLED))) {
+			struct ata_queued_cmd *qc;
+			struct qs_port_priv *pp = ap->private_data;
+			if (!pp || pp->state != qs_state_mmio)
+				continue;
+			qc = ata_qc_from_tag(ap, ap->active_tag);
+			if (qc && (!(qc->tf.ctl & ATA_NIEN))) {
+
+				/* check main status, clearing INTRQ */
+				u8 status = ata_chk_status(ap);
+				if ((status & ATA_BUSY))
+					continue;
+				DPRINTK("ata%u: protocol %d (dev_stat 0x%X)\n",
+					ap->id, qc->tf.protocol, status);
+		
+				/* complete taskfile transaction */
+				pp->state = qs_state_idle;
+				ata_qc_complete(qc, status);
+				handled = 1;
+			}
+		}
+	}
+	return handled;
+}
+
+static irqreturn_t qs_intr(int irq, void *dev_instance, struct pt_regs *regs)
+{
+	struct ata_host_set *host_set = dev_instance;
+	unsigned int handled = 0;
+
+	VPRINTK("ENTER\n");
+
+	spin_lock(&host_set->lock);
+	handled  = qs_intr_pkt(host_set) | qs_intr_mmio(host_set);
+	spin_unlock(&host_set->lock);
+
+	VPRINTK("EXIT\n");
+
+	return IRQ_RETVAL(handled);
+}
+
+static void qs_ata_setup_port(struct ata_ioports *port, unsigned long base)
+{
+	port->cmd_addr		=
+	port->data_addr		= base + 0x400;
+	port->error_addr	=
+	port->feature_addr	= base + 0x408; /* hob_feature = 0x409 */
+	port->nsect_addr	= base + 0x410; /* hob_nsect   = 0x411 */
+	port->lbal_addr		= base + 0x418; /* hob_lbal    = 0x419 */
+	port->lbam_addr		= base + 0x420; /* hob_lbam    = 0x421 */
+	port->lbah_addr		= base + 0x428; /* hob_lbah    = 0x429 */
+	port->device_addr	= base + 0x430;
+	port->status_addr	=
+	port->command_addr	= base + 0x438;
+	port->altstatus_addr	=
+	port->ctl_addr		= base + 0x440;
+	port->scr_addr		= base + 0xc00;
+}
+
+static int qs_port_start(struct ata_port *ap)
+{
+	struct device *dev = ap->host_set->dev;
+	struct qs_port_priv *pp;
+	void __iomem *mmio_base = ap->host_set->mmio_base;
+	void __iomem *chan = mmio_base + (ap->port_no * 0x4000);
+	u64 addr;
+	int rc;
+
+	rc = ata_port_start(ap);
+	if (rc)
+		return rc;
+	qs_enter_reg_mode(ap);
+	pp = kcalloc(1, sizeof(*pp), GFP_KERNEL);
+	if (!pp) {
+		rc = -ENOMEM;
+		goto err_out;
+	}
+	pp->pkt = dma_alloc_coherent(dev, QS_PKT_BYTES, &pp->pkt_dma,
+								GFP_KERNEL);
+	if (!pp->pkt) {
+		rc = -ENOMEM;
+		goto err_out_kfree;
+	}
+	memset(pp->pkt, 0, QS_PKT_BYTES);
+	ap->private_data = pp;
+
+	addr = (u64)pp->pkt_dma;
+	writel((u32) addr,        chan + QS_CCF_CPBA);
+	writel((u32)(addr >> 32), chan + QS_CCF_CPBA + 4);
+	return 0;
+
+err_out_kfree:
+	kfree(pp);
+err_out:
+	ata_port_stop(ap);
+	return rc;
+}
+
+static void qs_port_stop(struct ata_port *ap)
+{
+	struct device *dev = ap->host_set->dev;
+	struct qs_port_priv *pp = ap->private_data;
+
+	if (pp != NULL) {
+		ap->private_data = NULL;
+		if (pp->pkt != NULL)
+			dma_free_coherent(dev, QS_PKT_BYTES, pp->pkt,
+								pp->pkt_dma);
+		kfree(pp);
+	}
+	ata_port_stop(ap);
+}
+
+static void qs_host_stop(struct ata_host_set *host_set)
+{
+	void __iomem *mmio_base = host_set->mmio_base;
+
+	writeb(0, mmio_base + QS_HCT_CTRL); /* disable host interrupts */
+	writeb(QS_CNFG3_GSRST, mmio_base + QS_HCF_CNFG3); /* global reset */
+}
+
+static void qs_host_init(unsigned int chip_id, struct ata_probe_ent *pe)
+{
+	void __iomem *mmio_base = pe->mmio_base;
+	unsigned int port_no;
+
+	writeb(0, mmio_base + QS_HCT_CTRL); /* disable host interrupts */
+	writeb(QS_CNFG3_GSRST, mmio_base + QS_HCF_CNFG3); /* global reset */
+
+	/* reset each channel in turn */
+	for (port_no = 0; port_no < pe->n_ports; ++port_no) {
+		u8 __iomem *chan = mmio_base + (port_no * 0x4000);
+		writeb(QS_CTR1_RDEV|QS_CTR1_RCHN, chan + QS_CCT_CTR1);
+		writeb(QS_CTR0_REG, chan + QS_CCT_CTR0);
+		readb(chan + QS_CCT_CTR0);        /* flush */
+	}
+	writeb(QS_SERD3_PHY_ENA, mmio_base + QS_HVS_SERD3); /* enable phy */
+
+	for (port_no = 0; port_no < pe->n_ports; ++port_no) {
+		u8 __iomem *chan = mmio_base + (port_no * 0x4000);
+		/* set FIFO depths to same settings as Windows driver */
+		writew(32, chan + QS_CFC_HUFT);
+		writew(32, chan + QS_CFC_HDFT);
+		writew(10, chan + QS_CFC_DUFT);
+		writew( 8, chan + QS_CFC_DDFT);
+		/* set CPB size in bytes, as a power of two */
+		writeb(QS_CPB_ORDER,    chan + QS_CCF_CSEP);
+	}
+	writeb(1, mmio_base + QS_HCT_CTRL); /* enable host interrupts */
+}
+
+/*
+ * The QStor understands 64-bit buses, and uses 64-bit fields
+ * for DMA pointers regardless of bus width.  We just have to
+ * make sure our DMA masks are set appropriately for whatever
+ * bridge lies between us and the QStor, and then the DMA mapping
+ * code will ensure we only ever "see" appropriate buffer addresses.
+ * If we're 32-bit limited somewhere, then our 64-bit fields will
+ * just end up with zeros in the upper 32-bits, without any special
+ * logic required outside of this routine (below).
+ */
+static int qs_set_dma_masks(struct pci_dev *pdev, void __iomem *mmio_base)
+{
+	u32 bus_info = readl(mmio_base + QS_HID_HPHY);
+	int rc, have_64bit_bus = (bus_info & QS_HPHY_64BIT);
+
+	if (have_64bit_bus &&
+	    !pci_set_dma_mask(pdev, 0xffffffffffffffffULL)) {
+		rc = pci_set_consistent_dma_mask(pdev, 0xffffffffffffffffULL);
+		if (rc) {
+			rc = pci_set_consistent_dma_mask(pdev, 0xffffffffULL);
+			if (rc) {
+				printk(KERN_ERR DRV_NAME
+					"(%s): 64-bit DMA enable failed\n",
+					pci_name(pdev));
+				return rc;
+			}
+		}
+	} else {
+		rc = pci_set_dma_mask(pdev, 0xffffffffULL);
+		if (rc) {
+			printk(KERN_ERR DRV_NAME
+				"(%s): 32-bit DMA enable failed\n",
+				pci_name(pdev));
+			return rc;
+		}
+		rc = pci_set_consistent_dma_mask(pdev, 0xffffffffULL);
+		if (rc) {
+			printk(KERN_ERR DRV_NAME
+				"(%s): 32-bit consistent DMA enable failed\n",
+				pci_name(pdev));
+			return rc;
+		}
+	}
+	return 0;
+}
+
+static int qs_ata_init_one(struct pci_dev *pdev,
+				const struct pci_device_id *ent)
+{
+	static int printed_version;
+	struct ata_probe_ent *probe_ent = NULL;
+	void __iomem *mmio_base;
+	unsigned int board_idx = (unsigned int) ent->driver_data;
+	int rc, port_no;
+
+	if (!printed_version++)
+		printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
+
+	rc = pci_enable_device(pdev);
+	if (rc)
+		return rc;
+
+	rc = pci_request_regions(pdev, DRV_NAME);
+	if (rc)
+		goto err_out;
+
+	if ((pci_resource_flags(pdev, 4) & IORESOURCE_MEM) == 0) {
+		rc = -ENODEV;
+		goto err_out_regions;
+	}
+
+	mmio_base = ioremap(pci_resource_start(pdev, 4),
+		            pci_resource_len(pdev, 4));
+	if (mmio_base == NULL) {
+		rc = -ENOMEM;
+		goto err_out_regions;
+	}
+
+	rc = qs_set_dma_masks(pdev, mmio_base);
+	if (rc)
+		goto err_out_iounmap;
+
+	probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL);
+	if (probe_ent == NULL) {
+		rc = -ENOMEM;
+		goto err_out_iounmap;
+	}
+
+	memset(probe_ent, 0, sizeof(*probe_ent));
+	probe_ent->dev = pci_dev_to_dev(pdev);
+	INIT_LIST_HEAD(&probe_ent->node);
+
+	probe_ent->sht		= qs_port_info[board_idx].sht;
+	probe_ent->host_flags	= qs_port_info[board_idx].host_flags;
+	probe_ent->pio_mask	= qs_port_info[board_idx].pio_mask;
+	probe_ent->mwdma_mask	= qs_port_info[board_idx].mwdma_mask;
+	probe_ent->udma_mask	= qs_port_info[board_idx].udma_mask;
+	probe_ent->port_ops	= qs_port_info[board_idx].port_ops;
+
+	probe_ent->irq		= pdev->irq;
+	probe_ent->irq_flags	= SA_SHIRQ;
+	probe_ent->mmio_base	= mmio_base;
+	probe_ent->n_ports	= QS_PORTS;
+
+	for (port_no = 0; port_no < probe_ent->n_ports; ++port_no) {
+		unsigned long chan = (unsigned long)mmio_base +
+							(port_no * 0x4000);
+		qs_ata_setup_port(&probe_ent->port[port_no], chan);
+	}
+
+	pci_set_master(pdev);
+
+	/* initialize adapter */
+	qs_host_init(board_idx, probe_ent);
+
+	rc = ata_device_add(probe_ent);
+	kfree(probe_ent);
+	if (rc != QS_PORTS)
+		goto err_out_iounmap;
+	return 0;
+
+err_out_iounmap:
+	iounmap(mmio_base);
+err_out_regions:
+	pci_release_regions(pdev);
+err_out:
+	pci_disable_device(pdev);
+	return rc;
+}
+
+static int __init qs_ata_init(void)
+{
+	return pci_module_init(&qs_ata_pci_driver);
+}
+
+static void __exit qs_ata_exit(void)
+{
+	pci_unregister_driver(&qs_ata_pci_driver);
+}
+
+MODULE_AUTHOR("Mark Lord");
+MODULE_DESCRIPTION("Pacific Digital Corporation QStor SATA low-level driver");
+MODULE_LICENSE("GPL");
+MODULE_DEVICE_TABLE(pci, qs_ata_pci_tbl);
+MODULE_VERSION(DRV_VERSION);
+
+module_init(qs_ata_init);
+module_exit(qs_ata_exit);
diff -Nru a/drivers/scsi/sata_sil.c b/drivers/scsi/sata_sil.c
--- a/drivers/scsi/sata_sil.c	2005-03-01 23:38:44 -08:00
+++ b/drivers/scsi/sata_sil.c	2005-03-01 23:38:44 -08:00
@@ -71,6 +71,8 @@
 	{ 0x1095, 0x0240, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 },
 	{ 0x1095, 0x3512, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 },
 	{ 0x1095, 0x3114, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3114 },
+	{ 0x1002, 0x436e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 },
+	{ 0x1002, 0x4379, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 },
 	{ }	/* terminate list */
 };
 
@@ -84,10 +86,12 @@
 	{ "ST330013AS",		SIL_QUIRK_MOD15WRITE },
 	{ "ST340017AS",		SIL_QUIRK_MOD15WRITE },
 	{ "ST360015AS",		SIL_QUIRK_MOD15WRITE },
+	{ "ST380013AS",		SIL_QUIRK_MOD15WRITE },
 	{ "ST380023AS",		SIL_QUIRK_MOD15WRITE },
 	{ "ST3120023AS",	SIL_QUIRK_MOD15WRITE },
 	{ "ST3160023AS",	SIL_QUIRK_MOD15WRITE },
 	{ "ST3120026AS",	SIL_QUIRK_MOD15WRITE },
+	{ "ST3200822AS",	SIL_QUIRK_MOD15WRITE },
 	{ "ST340014ASL",	SIL_QUIRK_MOD15WRITE },
 	{ "ST360014ASL",	SIL_QUIRK_MOD15WRITE },
 	{ "ST380011ASL",	SIL_QUIRK_MOD15WRITE },
@@ -135,6 +139,8 @@
 	.post_set_mode		= sil_post_set_mode,
 	.bmdma_setup            = ata_bmdma_setup,
 	.bmdma_start            = ata_bmdma_start,
+	.bmdma_stop		= ata_bmdma_stop,
+	.bmdma_status		= ata_bmdma_status,
 	.qc_prep		= ata_qc_prep,
 	.qc_issue		= ata_qc_issue_prot,
 	.eng_timeout		= ata_eng_timeout,
@@ -332,6 +338,7 @@
 	void *mmio_base;
 	int rc;
 	unsigned int i;
+	int pci_dev_busy = 0;
 	u32 tmp, irq_mask;
 
 	if (!printed_version++)
@@ -346,8 +353,10 @@
 		return rc;
 
 	rc = pci_request_regions(pdev, DRV_NAME);
-	if (rc)
+	if (rc) {
+		pci_dev_busy = 1;
 		goto err_out;
+	}
 
 	rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
 	if (rc)
@@ -434,7 +443,8 @@
 err_out_regions:
 	pci_release_regions(pdev);
 err_out:
-	pci_disable_device(pdev);
+	if (!pci_dev_busy)
+		pci_disable_device(pdev);
 	return rc;
 }
 
diff -Nru a/drivers/scsi/sata_sis.c b/drivers/scsi/sata_sis.c
--- a/drivers/scsi/sata_sis.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/scsi/sata_sis.c	2005-03-01 23:38:57 -08:00
@@ -102,6 +102,8 @@
 	.phy_reset		= sata_phy_reset,
 	.bmdma_setup            = ata_bmdma_setup,
 	.bmdma_start            = ata_bmdma_start,
+	.bmdma_stop		= ata_bmdma_stop,
+	.bmdma_status		= ata_bmdma_status,
 	.qc_prep		= ata_qc_prep,
 	.qc_issue		= ata_qc_issue_prot,
 	.eng_timeout		= ata_eng_timeout,
@@ -200,14 +202,17 @@
 	int rc;
 	u32 genctl;
 	struct ata_port_info *ppi;
+	int pci_dev_busy = 0;
 
 	rc = pci_enable_device(pdev);
 	if (rc)
 		return rc;
 
 	rc = pci_request_regions(pdev, DRV_NAME);
-	if (rc)
+	if (rc) {
+		pci_dev_busy = 1;
 		goto err_out;
+	}
 
 	rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
 	if (rc)
@@ -259,7 +264,8 @@
 	pci_release_regions(pdev);
 
 err_out:
-	pci_disable_device(pdev);
+	if (!pci_dev_busy)
+		pci_disable_device(pdev);
 	return rc;
 
 }
diff -Nru a/drivers/scsi/sata_svw.c b/drivers/scsi/sata_svw.c
--- a/drivers/scsi/sata_svw.c	2005-03-01 23:38:59 -08:00
+++ b/drivers/scsi/sata_svw.c	2005-03-01 23:38:59 -08:00
@@ -301,6 +301,8 @@
 	.phy_reset		= sata_phy_reset,
 	.bmdma_setup		= k2_bmdma_setup_mmio,
 	.bmdma_start		= k2_bmdma_start_mmio,
+	.bmdma_stop		= ata_bmdma_stop,
+	.bmdma_status		= ata_bmdma_status,
 	.qc_prep		= ata_qc_prep,
 	.qc_issue		= ata_qc_issue_prot,
 	.eng_timeout		= ata_eng_timeout,
@@ -338,6 +340,7 @@
 	struct ata_probe_ent *probe_ent = NULL;
 	unsigned long base;
 	void *mmio_base;
+	int pci_dev_busy = 0;
 	int rc;
 
 	if (!printed_version++)
@@ -359,8 +362,10 @@
 
 	/* Request PCI regions */
 	rc = pci_request_regions(pdev, DRV_NAME);
-	if (rc)
+	if (rc) {
+		pci_dev_busy = 1;
 		goto err_out;
+	}
 
 	rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
 	if (rc)
@@ -433,7 +438,8 @@
 err_out_regions:
 	pci_release_regions(pdev);
 err_out:
-	pci_disable_device(pdev);
+	if (!pci_dev_busy)
+		pci_disable_device(pdev);
 	return rc;
 }
 
diff -Nru a/drivers/scsi/sata_sx4.c b/drivers/scsi/sata_sx4.c
--- a/drivers/scsi/sata_sx4.c	2005-03-01 23:38:44 -08:00
+++ b/drivers/scsi/sata_sx4.c	2005-03-01 23:38:44 -08:00
@@ -1366,6 +1366,7 @@
 	void *mmio_base, *dimm_mmio = NULL;
 	struct pdc_host_priv *hpriv = NULL;
 	unsigned int board_idx = (unsigned int) ent->driver_data;
+	int pci_dev_busy = 0;
 	int rc;
 
 	if (!printed_version++)
@@ -1380,8 +1381,10 @@
 		return rc;
 
 	rc = pci_request_regions(pdev, DRV_NAME);
-	if (rc)
+	if (rc) {
+		pci_dev_busy = 1;
 		goto err_out;
+	}
 
 	rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
 	if (rc)
@@ -1471,7 +1474,8 @@
 err_out_regions:
 	pci_release_regions(pdev);
 err_out:
-	pci_disable_device(pdev);
+	if (!pci_dev_busy)
+		pci_disable_device(pdev);
 	return rc;
 }
 
diff -Nru a/drivers/scsi/sata_uli.c b/drivers/scsi/sata_uli.c
--- a/drivers/scsi/sata_uli.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/scsi/sata_uli.c	2005-03-01 23:39:09 -08:00
@@ -32,16 +32,18 @@
 #include <linux/libata.h>
 
 #define DRV_NAME	"sata_uli"
-#define DRV_VERSION	"0.2"
+#define DRV_VERSION	"0.5"
 
 enum {
 	uli_5289		= 0,
 	uli_5287		= 1,
+	uli_5281		= 2,
 
 	/* PCI configuration registers */
-	ULI_SCR_BASE		= 0x90, /* sata0 phy SCR registers */
-	ULI_SATA1_OFS		= 0x10, /* offset from sata0->sata1 phy regs */
-
+	ULI5287_BASE		= 0x90, /* sata0 phy SCR registers */
+	ULI5287_OFFS		= 0x10, /* offset from sata0->sata1 phy regs */
+	ULI5281_BASE		= 0x60, /* sata0 phy SCR  registers */
+	ULI5281_OFFS		= 0x60, /* offset from sata0->sata1 phy regs */
 };
 
 static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
@@ -51,6 +53,7 @@
 static struct pci_device_id uli_pci_tbl[] = {
 	{ PCI_VENDOR_ID_AL, 0x5289, PCI_ANY_ID, PCI_ANY_ID, 0, 0, uli_5289 },
 	{ PCI_VENDOR_ID_AL, 0x5287, PCI_ANY_ID, PCI_ANY_ID, 0, 0, uli_5287 },
+	{ PCI_VENDOR_ID_AL, 0x5281, PCI_ANY_ID, PCI_ANY_ID, 0, 0, uli_5281 },
 	{ }	/* terminate list */
 };
 
@@ -94,6 +97,8 @@
 
 	.bmdma_setup            = ata_bmdma_setup,
 	.bmdma_start            = ata_bmdma_start,
+	.bmdma_stop		= ata_bmdma_stop,
+	.bmdma_status		= ata_bmdma_status,
 	.qc_prep		= ata_qc_prep,
 	.qc_issue		= ata_qc_issue_prot,
 
@@ -125,33 +130,15 @@
 MODULE_DEVICE_TABLE(pci, uli_pci_tbl);
 MODULE_VERSION(DRV_VERSION);
 
-static unsigned int get_scr_cfg_addr(unsigned int port_no, unsigned int sc_reg)
+static unsigned int get_scr_cfg_addr(struct ata_port *ap, unsigned int sc_reg)
 {
-	unsigned int addr = ULI_SCR_BASE + (4 * sc_reg);
-
-	switch (port_no) {
-	case 0:
-		break;
-	case 1:
-		addr += ULI_SATA1_OFS;
-		break;
-	case 2:
-		addr += ULI_SATA1_OFS*4;
-		break;
-	case 3:
-		addr += ULI_SATA1_OFS*5;
-		break;
-	default:
-		BUG();
-		break;
-	}
-	return addr;
+	return ap->ioaddr.scr_addr + (4 * sc_reg);
 }
 
 static u32 uli_scr_cfg_read (struct ata_port *ap, unsigned int sc_reg)
 {
 	struct pci_dev *pdev = to_pci_dev(ap->host_set->dev);
-	unsigned int cfg_addr = get_scr_cfg_addr(ap->port_no, sc_reg);
+	unsigned int cfg_addr = get_scr_cfg_addr(ap, sc_reg);
 	u32 val;
 
 	pci_read_config_dword(pdev, cfg_addr, &val);
@@ -161,7 +148,7 @@
 static void uli_scr_cfg_write (struct ata_port *ap, unsigned int scr, u32 val)
 {
 	struct pci_dev *pdev = to_pci_dev(ap->host_set->dev);
-	unsigned int cfg_addr = get_scr_cfg_addr(ap->port_no, scr);
+	unsigned int cfg_addr = get_scr_cfg_addr(ap, scr);
 
 	pci_write_config_dword(pdev, cfg_addr, val);
 }
@@ -200,14 +187,17 @@
 	struct ata_port_info *ppi;
 	int rc;
 	unsigned int board_idx = (unsigned int) ent->driver_data;
+	int pci_dev_busy = 0;
 
 	rc = pci_enable_device(pdev);
 	if (rc)
 		return rc;
 
 	rc = pci_request_regions(pdev, DRV_NAME);
-	if (rc)
+	if (rc) {
+		pci_dev_busy = 1;
 		goto err_out;
+	}
 
 	rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
 	if (rc)
@@ -222,9 +212,11 @@
 		rc = -ENOMEM;
 		goto err_out_regions;
 	}
-
+	
 	switch (board_idx) {
 	case uli_5287:
+		probe_ent->port[0].scr_addr = ULI5287_BASE;
+		probe_ent->port[1].scr_addr = ULI5287_BASE + ULI5287_OFFS;
        		probe_ent->n_ports = 4;
 
        		probe_ent->port[2].cmd_addr = pci_resource_start(pdev, 0) + 8;
@@ -232,19 +224,27 @@
 		probe_ent->port[2].ctl_addr =
 			(pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS) + 4;
 		probe_ent->port[2].bmdma_addr = pci_resource_start(pdev, 4) + 16;
+		probe_ent->port[2].scr_addr = ULI5287_BASE + ULI5287_OFFS*4;
 
 		probe_ent->port[3].cmd_addr = pci_resource_start(pdev, 2) + 8;
 		probe_ent->port[3].altstatus_addr =
 		probe_ent->port[3].ctl_addr =
 			(pci_resource_start(pdev, 3) | ATA_PCI_CTL_OFS) + 4;
 		probe_ent->port[3].bmdma_addr = pci_resource_start(pdev, 4) + 24;
+		probe_ent->port[3].scr_addr = ULI5287_BASE + ULI5287_OFFS*5;
 
 		ata_std_ports(&probe_ent->port[2]);
 		ata_std_ports(&probe_ent->port[3]);
 		break;
 
 	case uli_5289:
-		/* do nothing; ata_pci_init_native_mode did it all */
+		probe_ent->port[0].scr_addr = ULI5287_BASE;
+		probe_ent->port[1].scr_addr = ULI5287_BASE + ULI5287_OFFS;
+		break;
+
+	case uli_5281:
+		probe_ent->port[0].scr_addr = ULI5281_BASE;
+		probe_ent->port[1].scr_addr = ULI5281_BASE + ULI5281_OFFS;
 		break;
 
 	default:
@@ -265,7 +265,8 @@
 	pci_release_regions(pdev);
 
 err_out:
-	pci_disable_device(pdev);
+	if (!pci_dev_busy)
+		pci_disable_device(pdev);
 	return rc;
 
 }
diff -Nru a/drivers/scsi/sata_via.c b/drivers/scsi/sata_via.c
--- a/drivers/scsi/sata_via.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/scsi/sata_via.c	2005-03-01 23:38:53 -08:00
@@ -24,6 +24,11 @@
    If you do not delete the provisions above, a recipient may use your
    version of this file under either the OSL or the GPL.
 
+   ----------------------------------------------------------------------
+
+   To-do list:
+   * VT6421 PATA support
+
  */
 
 #include <linux/kernel.h>
@@ -38,11 +43,14 @@
 #include <asm/io.h>
 
 #define DRV_NAME	"sata_via"
-#define DRV_VERSION	"1.0"
+#define DRV_VERSION	"1.1"
 
-enum {
-	via_sata		= 0,
+enum board_ids_enum {
+	vt6420,
+	vt6421,
+};
 
+enum {
 	SATA_CHAN_ENAB		= 0x40, /* SATA channel enable */
 	SATA_INT_GATE		= 0x41, /* SATA interrupt gating */
 	SATA_NATIVE_MODE	= 0x42, /* Native mode enable */
@@ -50,10 +58,8 @@
 
 	PORT0			= (1 << 1),
 	PORT1			= (1 << 0),
-
-	ENAB_ALL		= PORT0 | PORT1,
-
-	INT_GATE_ALL		= PORT0 | PORT1,
+	ALL_PORTS		= PORT0 | PORT1,
+	N_PORTS			= 2,
 
 	NATIVE_MODE_ALL		= (1 << 7) | (1 << 6) | (1 << 5) | (1 << 4),
 
@@ -66,7 +72,8 @@
 static void svia_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
 
 static struct pci_device_id svia_pci_tbl[] = {
-	{ 0x1106, 0x3149, PCI_ANY_ID, PCI_ANY_ID, 0, 0, via_sata },
+	{ 0x1106, 0x3149, PCI_ANY_ID, PCI_ANY_ID, 0, 0, vt6420 },
+	{ 0x1106, 0x3249, PCI_ANY_ID, PCI_ANY_ID, 0, 0, vt6421 },
 
 	{ }	/* terminate list */
 };
@@ -110,6 +117,9 @@
 
 	.bmdma_setup            = ata_bmdma_setup,
 	.bmdma_start            = ata_bmdma_start,
+	.bmdma_stop		= ata_bmdma_stop,
+	.bmdma_status		= ata_bmdma_status,
+
 	.qc_prep		= ata_qc_prep,
 	.qc_issue		= ata_qc_issue_prot,
 
@@ -158,18 +168,132 @@
 	8, 4, 8, 4, 16, 256
 };
 
+static const unsigned int vt6421_bar_sizes[] = {
+	16, 16, 16, 16, 32, 128
+};
+
 static unsigned long svia_scr_addr(unsigned long addr, unsigned int port)
 {
 	return addr + (port * 128);
 }
 
+static unsigned long vt6421_scr_addr(unsigned long addr, unsigned int port)
+{
+	return addr + (port * 64);
+}
+
+static void vt6421_init_addrs(struct ata_probe_ent *probe_ent,
+			      struct pci_dev *pdev,
+			      unsigned int port)
+{
+	unsigned long reg_addr = pci_resource_start(pdev, port);
+	unsigned long bmdma_addr = pci_resource_start(pdev, 4) + (port * 8);
+	unsigned long scr_addr;
+
+	probe_ent->port[port].cmd_addr = reg_addr;
+	probe_ent->port[port].altstatus_addr =
+	probe_ent->port[port].ctl_addr = (reg_addr + 8) | ATA_PCI_CTL_OFS;
+	probe_ent->port[port].bmdma_addr = bmdma_addr;
+
+	scr_addr = vt6421_scr_addr(pci_resource_start(pdev, 5), port);
+	probe_ent->port[port].scr_addr = scr_addr;
+
+	ata_std_ports(&probe_ent->port[port]);
+}
+
+static struct ata_probe_ent *vt6420_init_probe_ent(struct pci_dev *pdev)
+{
+	struct ata_probe_ent *probe_ent;
+	struct ata_port_info *ppi = &svia_port_info;
+
+	probe_ent = ata_pci_init_native_mode(pdev, &ppi);
+	if (!probe_ent)
+		return NULL;
+
+	probe_ent->port[0].scr_addr =
+		svia_scr_addr(pci_resource_start(pdev, 5), 0);
+	probe_ent->port[1].scr_addr =
+		svia_scr_addr(pci_resource_start(pdev, 5), 1);
+
+	return probe_ent;
+}
+
+static struct ata_probe_ent *vt6421_init_probe_ent(struct pci_dev *pdev)
+{
+	struct ata_probe_ent *probe_ent;
+	unsigned int i;
+
+	probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL);
+	if (!probe_ent)
+		return NULL;
+
+	memset(probe_ent, 0, sizeof(*probe_ent));
+	probe_ent->dev = pci_dev_to_dev(pdev);
+	INIT_LIST_HEAD(&probe_ent->node);
+
+	probe_ent->sht		= &svia_sht;
+	probe_ent->host_flags	= ATA_FLAG_SATA | ATA_FLAG_SATA_RESET |
+				  ATA_FLAG_NO_LEGACY;
+	probe_ent->port_ops	= &svia_sata_ops;
+	probe_ent->n_ports	= N_PORTS;
+	probe_ent->irq		= pdev->irq;
+	probe_ent->irq_flags	= SA_SHIRQ;
+	probe_ent->pio_mask	= 0x1f;
+	probe_ent->mwdma_mask	= 0x07;
+	probe_ent->udma_mask	= 0x7f;
+
+	for (i = 0; i < N_PORTS; i++)
+		vt6421_init_addrs(probe_ent, pdev, i);
+
+	return probe_ent;
+}
+
+static void svia_configure(struct pci_dev *pdev)
+{
+	u8 tmp8;
+
+	pci_read_config_byte(pdev, PCI_INTERRUPT_LINE, &tmp8);
+	printk(KERN_INFO DRV_NAME "(%s): routed to hard irq line %d\n",
+	       pci_name(pdev),
+	       (int) (tmp8 & 0xf0) == 0xf0 ? 0 : tmp8 & 0x0f);
+
+	/* make sure SATA channels are enabled */
+	pci_read_config_byte(pdev, SATA_CHAN_ENAB, &tmp8);
+	if ((tmp8 & ALL_PORTS) != ALL_PORTS) {
+		printk(KERN_DEBUG DRV_NAME "(%s): enabling SATA channels (0x%x)\n",
+		       pci_name(pdev), (int) tmp8);
+		tmp8 |= ALL_PORTS;
+		pci_write_config_byte(pdev, SATA_CHAN_ENAB, tmp8);
+	}
+
+	/* make sure interrupts for each channel sent to us */
+	pci_read_config_byte(pdev, SATA_INT_GATE, &tmp8);
+	if ((tmp8 & ALL_PORTS) != ALL_PORTS) {
+		printk(KERN_DEBUG DRV_NAME "(%s): enabling SATA channel interrupts (0x%x)\n",
+		       pci_name(pdev), (int) tmp8);
+		tmp8 |= ALL_PORTS;
+		pci_write_config_byte(pdev, SATA_INT_GATE, tmp8);
+	}
+
+	/* make sure native mode is enabled */
+	pci_read_config_byte(pdev, SATA_NATIVE_MODE, &tmp8);
+	if ((tmp8 & NATIVE_MODE_ALL) != NATIVE_MODE_ALL) {
+		printk(KERN_DEBUG DRV_NAME "(%s): enabling SATA channel native mode (0x%x)\n",
+		       pci_name(pdev), (int) tmp8);
+		tmp8 |= NATIVE_MODE_ALL;
+		pci_write_config_byte(pdev, SATA_NATIVE_MODE, tmp8);
+	}
+}
+
 static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
 {
 	static int printed_version;
 	unsigned int i;
 	int rc;
-	struct ata_port_info *ppi;
 	struct ata_probe_ent *probe_ent;
+	int board_id = (int) ent->driver_data;
+	const int *bar_sizes;
+	int pci_dev_busy = 0;
 	u8 tmp8;
 
 	if (!printed_version++)
@@ -180,20 +304,28 @@
 		return rc;
 
 	rc = pci_request_regions(pdev, DRV_NAME);
-	if (rc)
+	if (rc) {
+		pci_dev_busy = 1;
 		goto err_out;
+	}
 
-	pci_read_config_byte(pdev, SATA_PATA_SHARING, &tmp8);
-	if (tmp8 & SATA_2DEV) {
-		printk(KERN_ERR DRV_NAME "(%s): SATA master/slave not supported (0x%x)\n",
-		       pci_name(pdev), (int) tmp8);
-		rc = -EIO;
-		goto err_out_regions;
+	if (board_id == vt6420) {
+		pci_read_config_byte(pdev, SATA_PATA_SHARING, &tmp8);
+		if (tmp8 & SATA_2DEV) {
+			printk(KERN_ERR DRV_NAME "(%s): SATA master/slave not supported (0x%x)\n",
+		       	pci_name(pdev), (int) tmp8);
+			rc = -EIO;
+			goto err_out_regions;
+		}
+
+		bar_sizes = &svia_bar_sizes[0];
+	} else {
+		bar_sizes = &vt6421_bar_sizes[0];
 	}
 
 	for (i = 0; i < ARRAY_SIZE(svia_bar_sizes); i++)
 		if ((pci_resource_start(pdev, i) == 0) ||
-		    (pci_resource_len(pdev, i) < svia_bar_sizes[i])) {
+		    (pci_resource_len(pdev, i) < bar_sizes[i])) {
 			printk(KERN_ERR DRV_NAME "(%s): invalid PCI BAR %u (sz 0x%lx, val 0x%lx)\n",
 			       pci_name(pdev), i,
 			       pci_resource_start(pdev, i),
@@ -209,8 +341,11 @@
 	if (rc)
 		goto err_out_regions;
 
-	ppi = &svia_port_info;
-	probe_ent = ata_pci_init_native_mode(pdev, &ppi);
+	if (board_id == vt6420)
+		probe_ent = vt6420_init_probe_ent(pdev);
+	else
+		probe_ent = vt6421_init_probe_ent(pdev);
+	
 	if (!probe_ent) {
 		printk(KERN_ERR DRV_NAME "(%s): out of memory\n",
 		       pci_name(pdev));
@@ -218,42 +353,7 @@
 		goto err_out_regions;
 	}
 
-	probe_ent->port[0].scr_addr =
-		svia_scr_addr(pci_resource_start(pdev, 5), 0);
-	probe_ent->port[1].scr_addr =
-		svia_scr_addr(pci_resource_start(pdev, 5), 1);
-
-	pci_read_config_byte(pdev, PCI_INTERRUPT_LINE, &tmp8);
-	printk(KERN_INFO DRV_NAME "(%s): routed to hard irq line %d\n",
-	       pci_name(pdev),
-	       (int) (tmp8 & 0xf0) == 0xf0 ? 0 : tmp8 & 0x0f);
-
-	/* make sure SATA channels are enabled */
-	pci_read_config_byte(pdev, SATA_CHAN_ENAB, &tmp8);
-	if ((tmp8 & ENAB_ALL) != ENAB_ALL) {
-		printk(KERN_DEBUG DRV_NAME "(%s): enabling SATA channels (0x%x)\n",
-		       pci_name(pdev), (int) tmp8);
-		tmp8 |= ENAB_ALL;
-		pci_write_config_byte(pdev, SATA_CHAN_ENAB, tmp8);
-	}
-
-	/* make sure interrupts for each channel sent to us */
-	pci_read_config_byte(pdev, SATA_INT_GATE, &tmp8);
-	if ((tmp8 & INT_GATE_ALL) != INT_GATE_ALL) {
-		printk(KERN_DEBUG DRV_NAME "(%s): enabling SATA channel interrupts (0x%x)\n",
-		       pci_name(pdev), (int) tmp8);
-		tmp8 |= INT_GATE_ALL;
-		pci_write_config_byte(pdev, SATA_INT_GATE, tmp8);
-	}
-
-	/* make sure native mode is enabled */
-	pci_read_config_byte(pdev, SATA_NATIVE_MODE, &tmp8);
-	if ((tmp8 & NATIVE_MODE_ALL) != NATIVE_MODE_ALL) {
-		printk(KERN_DEBUG DRV_NAME "(%s): enabling SATA channel native mode (0x%x)\n",
-		       pci_name(pdev), (int) tmp8);
-		tmp8 |= NATIVE_MODE_ALL;
-		pci_write_config_byte(pdev, SATA_NATIVE_MODE, tmp8);
-	}
+	svia_configure(pdev);
 
 	pci_set_master(pdev);
 
@@ -266,7 +366,8 @@
 err_out_regions:
 	pci_release_regions(pdev);
 err_out:
-	pci_disable_device(pdev);
+	if (!pci_dev_busy)
+		pci_disable_device(pdev);
 	return rc;
 }
 
diff -Nru a/drivers/scsi/sata_vsc.c b/drivers/scsi/sata_vsc.c
--- a/drivers/scsi/sata_vsc.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/scsi/sata_vsc.c	2005-03-01 23:38:58 -08:00
@@ -217,6 +217,8 @@
 	.phy_reset		= sata_phy_reset,
 	.bmdma_setup            = ata_bmdma_setup,
 	.bmdma_start            = ata_bmdma_start,
+	.bmdma_stop		= ata_bmdma_stop,
+	.bmdma_status		= ata_bmdma_status,
 	.qc_prep		= ata_qc_prep,
 	.qc_issue		= ata_qc_issue_prot,
 	.eng_timeout		= ata_eng_timeout,
@@ -255,6 +257,7 @@
 	static int printed_version;
 	struct ata_probe_ent *probe_ent = NULL;
 	unsigned long base;
+	int pci_dev_busy = 0;
 	void *mmio_base;
 	int rc;
 
@@ -274,8 +277,10 @@
 	}
 
 	rc = pci_request_regions(pdev, DRV_NAME);
-	if (rc)
+	if (rc) {
+		pci_dev_busy = 1;
 		goto err_out;
+	}
 
 	/*
 	 * Use 32 bit DMA mask, because 64 bit address support is poor.
@@ -352,7 +357,8 @@
 err_out_regions:
 	pci_release_regions(pdev);
 err_out:
-	pci_disable_device(pdev);
+	if (!pci_dev_busy)
+		pci_disable_device(pdev);
 	return rc;
 }
 
diff -Nru a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
--- a/drivers/scsi/scsi.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/scsi/scsi.c	2005-03-01 23:38:57 -08:00
@@ -98,6 +98,9 @@
  * After the system is up, you may enable logging via the /proc interface.
  */
 unsigned int scsi_logging_level;
+#if defined(CONFIG_SCSI_LOGGING)
+EXPORT_SYMBOL(scsi_logging_level);
+#endif
 
 const char *const scsi_device_types[MAX_SCSI_DEVICE_CODE] = {
 	"Direct-Access    ",
@@ -115,6 +118,7 @@
 	"RAID             ",
 	"Enclosure        ",
 };
+EXPORT_SYMBOL(scsi_device_types);
 
 /*
  * Function:    scsi_allocate_request
@@ -147,6 +151,7 @@
 
 	return sreq;
 }
+EXPORT_SYMBOL(scsi_allocate_request);
 
 void __scsi_release_request(struct scsi_request *sreq)
 {
@@ -187,6 +192,7 @@
 	__scsi_release_request(sreq);
 	kfree(sreq);
 }
+EXPORT_SYMBOL(scsi_release_request);
 
 struct scsi_host_cmd_pool {
 	kmem_cache_t	*slab;
@@ -269,6 +275,7 @@
 
 	return cmd;
 }				
+EXPORT_SYMBOL(scsi_get_command);
 
 /*
  * Function:	scsi_put_command()
@@ -305,6 +312,7 @@
 
 	put_device(&sdev->sdev_gendev);
 }
+EXPORT_SYMBOL(scsi_put_command);
 
 /*
  * Function:	scsi_setup_command_freelist()
@@ -606,9 +614,7 @@
 				printk("queuecommand : command too long.\n"));
 		cmd->result = (DID_ABORT << 16);
 
-		spin_lock_irqsave(host->host_lock, flags);
 		scsi_done(cmd);
-		spin_unlock_irqrestore(host->host_lock, flags);
 		goto out;
 	}
 
@@ -919,7 +925,7 @@
  */
 void scsi_adjust_queue_depth(struct scsi_device *sdev, int tagged, int tags)
 {
-	static spinlock_t device_request_lock = SPIN_LOCK_UNLOCKED;
+	static DEFINE_SPINLOCK(device_request_lock);
 	unsigned long flags;
 
 	/*
@@ -961,6 +967,7 @@
 	spin_unlock(sdev->request_queue->queue_lock);
 	spin_unlock_irqrestore(&device_request_lock, flags);
 }
+EXPORT_SYMBOL(scsi_adjust_queue_depth);
 
 /*
  * Function:	scsi_track_queue_full()
@@ -1011,6 +1018,7 @@
 		scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG, depth);
 	return depth;
 }
+EXPORT_SYMBOL(scsi_track_queue_full);
 
 /**
  * scsi_device_get  -  get an addition reference to a scsi_device
@@ -1075,6 +1083,28 @@
 EXPORT_SYMBOL(__scsi_iterate_devices);
 
 /**
+ * starget_for_each_device  -  helper to walk all devices of a target
+ * @starget:	target whose devices we want to iterate over.
+ *
+ * This traverses over each devices of @shost.  The devices have
+ * a reference that must be released by scsi_host_put when breaking
+ * out of the loop.
+ */
+void starget_for_each_device(struct scsi_target *starget, void * data,
+		     void (*fn)(struct scsi_device *, void *))
+{
+	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+	struct scsi_device *sdev;
+
+	shost_for_each_device(sdev, shost) {
+		if ((sdev->channel == starget->channel) &&
+		    (sdev->id == starget->id))
+			fn(sdev, data);
+	}
+}
+EXPORT_SYMBOL(starget_for_each_device);
+
+/**
  * scsi_device_lookup - find a device given the host (UNLOCKED)
  * @shost:	SCSI host pointer
  * @channel:	SCSI channel (zero if only one channel)
@@ -1177,6 +1207,7 @@
 
 	return 0;
 }
+EXPORT_SYMBOL(scsi_device_cancel);
 
 #ifdef CONFIG_HOTPLUG_CPU
 static int scsi_cpu_notify(struct notifier_block *self,
diff -Nru a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
--- a/drivers/scsi/scsi_debug.c	2005-03-01 23:39:06 -08:00
+++ b/drivers/scsi/scsi_debug.c	2005-03-01 23:39:06 -08:00
@@ -11,7 +11,7 @@
  *  (or disk like devices) sharing a common amount of RAM
  *
  *
- *  For documentation see http://www.torque.net/sg/sdebug25.html
+ *  For documentation see http://www.torque.net/sg/sdebug26.html
  *
  *   D. Gilbert (dpg) work for Magneto-Optical device test [20010421]
  *   dpg: work for devfs large number of disks [20010809]
@@ -55,8 +55,8 @@
 #include "scsi_logging.h"
 #include "scsi_debug.h"
 
-#define SCSI_DEBUG_VERSION "1.74"
-static const char * scsi_debug_version_date = "20040829";
+#define SCSI_DEBUG_VERSION "1.75"
+static const char * scsi_debug_version_date = "20050113";
 
 /* Additional Sense Code (ASC) used */
 #define NO_ADDED_SENSE 0x0
@@ -82,7 +82,7 @@
 #define DEF_EVERY_NTH   0
 #define DEF_NUM_PARTS   0
 #define DEF_OPTS   0
-#define DEF_SCSI_LEVEL   4    /* SPC-2 */
+#define DEF_SCSI_LEVEL   5    /* INQUIRY, byte2 [5->SPC-3] */
 #define DEF_PTYPE   0
 #define DEF_D_SENSE   0
 
@@ -95,6 +95,13 @@
  *   - a no response is simulated if SCSI_DEBUG_OPT_TIMEOUT is set
  *   - a RECOVERED_ERROR is simulated on successful read and write
  *     commands if SCSI_DEBUG_OPT_RECOVERED_ERR is set.
+ *
+ * When "every_nth" < 0 then after "- every_nth" commands:
+ *   - a no response is simulated if SCSI_DEBUG_OPT_TIMEOUT is set
+ *   - a RECOVERED_ERROR is simulated on successful read and write
+ *     commands if SCSI_DEBUG_OPT_RECOVERED_ERR is set.
+ * This will continue until some other action occurs (e.g. the user
+ * writing a new value (other than -1 or 1) to every_nth via sysfs).
  */
 
 /* when 1==SCSI_DEBUG_OPT_MEDIUM_ERR, a medium error is simulated at this
@@ -162,7 +169,7 @@
 	container_of(d, struct sdebug_host_info, dev)
 
 static LIST_HEAD(sdebug_host_list);
-static spinlock_t sdebug_host_list_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(sdebug_host_list_lock);
 
 typedef void (* done_funct_t) (struct scsi_cmnd *);
 
@@ -195,21 +202,19 @@
 	.cmd_per_lun =		3,
 	.max_sectors =		4096,
 	.unchecked_isa_dma = 	0,
-	.use_clustering = 	ENABLE_CLUSTERING,
+	.use_clustering = 	DISABLE_CLUSTERING,
 	.module =		THIS_MODULE,
 };
 
 static unsigned char * fake_storep;	/* ramdisk storage */
 
-static unsigned char spare_buff[SDEBUG_SENSE_LEN];
-
 static int num_aborts = 0;
 static int num_dev_resets = 0;
 static int num_bus_resets = 0;
 static int num_host_resets = 0;
 
-static spinlock_t queued_arr_lock = SPIN_LOCK_UNLOCKED;
-static rwlock_t atomic_rw = RW_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(queued_arr_lock);
+static DEFINE_RWLOCK(atomic_rw);
 
 static char sdebug_proc_name[] = "scsi_debug";
 
@@ -228,21 +233,28 @@
 		(DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;
 
 /* function declarations */
-static int resp_inquiry(unsigned char * cmd, int target, unsigned char * buff,
-			int bufflen, struct sdebug_dev_info * devip);
-static int resp_mode_sense(unsigned char * cmd, int target,
-			   unsigned char * buff, int bufflen,
+static int resp_inquiry(struct scsi_cmnd * SCpnt, int target,
+			struct sdebug_dev_info * devip);
+static int resp_requests(struct scsi_cmnd * SCpnt,
+			 struct sdebug_dev_info * devip);
+static int resp_readcap(struct scsi_cmnd * SCpnt,
+			struct sdebug_dev_info * devip);
+static int resp_mode_sense(struct scsi_cmnd * SCpnt, int target,
 			   struct sdebug_dev_info * devip);
 static int resp_read(struct scsi_cmnd * SCpnt, int upper_blk, int block,
 		     int num, struct sdebug_dev_info * devip);
 static int resp_write(struct scsi_cmnd * SCpnt, int upper_blk, int block,
 		      int num, struct sdebug_dev_info * devip);
-static int resp_report_luns(unsigned char * cmd, unsigned char * buff,
-			    int bufflen, struct sdebug_dev_info * devip);
+static int resp_report_luns(struct scsi_cmnd * SCpnt,
+			    struct sdebug_dev_info * devip);
+static int fill_from_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
+                                int arr_len);
+static int fetch_to_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
+                               int max_arr_len);
 static void timer_intr_handler(unsigned long);
 static struct sdebug_dev_info * devInfoReg(struct scsi_device * sdev);
 static void mk_sense_buffer(struct sdebug_dev_info * devip, int key,
-			    int asc, int asq, int inbandLen);
+			    int asc, int asq);
 static int check_reset(struct scsi_cmnd * SCpnt,
 		       struct sdebug_dev_info * devip);
 static int schedule_resp(struct scsi_cmnd * cmnd,
@@ -264,49 +276,20 @@
 static struct device pseudo_primary;
 static struct bus_type pseudo_lld_bus;
 
-static unsigned char * scatg2virt(const struct scatterlist * sclp)
-{
-	if (NULL == sclp)
-		return NULL;
-	else if (sclp->page)
-		return (unsigned char *)page_address(sclp->page) +
-		       sclp->offset;
-	else
-		return NULL;
-}
 
 static
 int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done)
 {
 	unsigned char *cmd = (unsigned char *) SCpnt->cmnd;
 	int block, upper_blk, num, k;
-	unsigned char *buff;
 	int errsts = 0;
 	int target = SCpnt->device->id;
-	int bufflen = SCpnt->request_bufflen;
-	unsigned long capac;
 	struct sdebug_dev_info * devip = NULL;
-	unsigned char * sbuff;
 	int inj_recovered = 0;
 
 	if (done == NULL)
 		return 0;	/* assume mid level reprocessing command */
 
-	if (SCpnt->use_sg) { /* just use first element */
-		struct scatterlist *sgpnt = (struct scatterlist *)
-						SCpnt->request_buffer;
-
-		buff = scatg2virt(&sgpnt[0]);
-		bufflen = sgpnt[0].length;
-		/* READ and WRITE process scatterlist themselves */
-	}
-	else
-		buff = (unsigned char *) SCpnt->request_buffer;
-	if (NULL == buff) {
-		buff = spare_buff;	/* assume cmd moves no data */
-		bufflen = SDEBUG_SENSE_LEN;
-	}
-
 	if ((SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) && cmd) {
 		printk(KERN_INFO "scsi_debug: cmd ");
 		for (k = 0, num = SCpnt->cmd_len; k < num; ++k)
@@ -328,9 +311,11 @@
 		return schedule_resp(SCpnt, NULL, done,
 				     DID_NO_CONNECT << 16, 0);
 
-        if ((scsi_debug_every_nth > 0) &&
-            (++scsi_debug_cmnd_count >= scsi_debug_every_nth)) {
-                scsi_debug_cmnd_count =0;
+        if ((scsi_debug_every_nth != 0) &&
+            (++scsi_debug_cmnd_count >= abs(scsi_debug_every_nth))) {
+                scsi_debug_cmnd_count = 0;
+		if (scsi_debug_every_nth < -1)
+			scsi_debug_every_nth = -1;
 		if (SCSI_DEBUG_OPT_TIMEOUT & scsi_debug_opts)
 			return 0; /* ignore command causing timeout */
 		else if (SCSI_DEBUG_OPT_RECOVERED_ERR & scsi_debug_opts)
@@ -339,23 +324,14 @@
 
 	switch (*cmd) {
 	case INQUIRY:     /* mandatory, ignore unit attention */
-		errsts = resp_inquiry(cmd, target, buff, bufflen, devip);
+		errsts = resp_inquiry(SCpnt, target, devip);
 		break;
 	case REQUEST_SENSE:	/* mandatory, ignore unit attention */
-		if (devip) {
-			sbuff = devip->sense_buff;
-			memcpy(buff, sbuff, (bufflen < SDEBUG_SENSE_LEN) ?
-					     bufflen : SDEBUG_SENSE_LEN);
-			mk_sense_buffer(devip, 0, NO_ADDED_SENSE, 0, 7);
-		} else {
-			memset(buff, 0, bufflen);
-			buff[0] = 0x70;
-		}
+		errsts = resp_requests(SCpnt, devip);
 		break;
 	case REZERO_UNIT:	/* actually this is REWIND for SSC */
 	case START_STOP:
 		errsts = check_reset(SCpnt, devip);
-		memset(buff, 0, bufflen);
 		break;
 	case ALLOW_MEDIUM_REMOVAL:
 		if ((errsts = check_reset(SCpnt, devip)))
@@ -366,40 +342,24 @@
 		break;
 	case SEND_DIAGNOSTIC:     /* mandatory */
 		errsts = check_reset(SCpnt, devip);
-		memset(buff, 0, bufflen);
 		break;
 	case TEST_UNIT_READY:     /* mandatory */
 		errsts = check_reset(SCpnt, devip);
-		memset(buff, 0, bufflen);
 		break;
         case RESERVE:
 		errsts = check_reset(SCpnt, devip);
-		memset(buff, 0, bufflen);
                 break;
         case RESERVE_10:
 		errsts = check_reset(SCpnt, devip);
-		memset(buff, 0, bufflen);
                 break;
         case RELEASE:
 		errsts = check_reset(SCpnt, devip);
-		memset(buff, 0, bufflen);
                 break;
         case RELEASE_10:
 		errsts = check_reset(SCpnt, devip);
-		memset(buff, 0, bufflen);
                 break;
 	case READ_CAPACITY:
-		errsts = check_reset(SCpnt, devip);
-		memset(buff, 0, bufflen);
-		if (bufflen > 7) {
-			capac = (unsigned long)sdebug_capacity - 1;
-			buff[0] = (capac >> 24);
-			buff[1] = (capac >> 16) & 0xff;
-			buff[2] = (capac >> 8) & 0xff;
-			buff[3] = capac & 0xff;
-			buff[6] = (SECT_SIZE_PER(target) >> 8) & 0xff;
-			buff[7] = SECT_SIZE_PER(target) & 0xff;
-		}
+		errsts = resp_readcap(SCpnt, devip);
 		break;
 	case READ_16:
 	case READ_12:
@@ -432,12 +392,15 @@
 		errsts = resp_read(SCpnt, upper_blk, block, num, devip);
 		if (inj_recovered && (0 == errsts)) {
 			mk_sense_buffer(devip, RECOVERED_ERROR,
-					THRESHHOLD_EXCEEDED, 0, 18);
+					THRESHHOLD_EXCEEDED, 0);
 			errsts = check_condition_result;
 		}
 		break;
 	case REPORT_LUNS:	/* mandatory, ignore unit attention */
-		errsts = resp_report_luns(cmd, buff, bufflen, devip);
+		errsts = resp_report_luns(SCpnt, devip);
+		break;
+	case VERIFY:		/* 10 byte SBC-2 command */
+		errsts = check_reset(SCpnt, devip);
 		break;
 	case WRITE_16:
 	case WRITE_12:
@@ -470,19 +433,16 @@
 		errsts = resp_write(SCpnt, upper_blk, block, num, devip);
 		if (inj_recovered && (0 == errsts)) {
 			mk_sense_buffer(devip, RECOVERED_ERROR,
-					THRESHHOLD_EXCEEDED, 0, 18);
+					THRESHHOLD_EXCEEDED, 0);
 			errsts = check_condition_result;
 		}
 		break;
 	case MODE_SENSE:
 	case MODE_SENSE_10:
-		if ((errsts = check_reset(SCpnt, devip)))
-			break;
-		errsts = resp_mode_sense(cmd, target, buff, bufflen, devip);
+		errsts = resp_mode_sense(SCpnt, target, devip);
 		break;
 	case SYNCHRONIZE_CACHE:
 		errsts = check_reset(SCpnt, devip);
-		memset(buff, 0, bufflen);
 		break;
 	default:
 		if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
@@ -490,7 +450,7 @@
 			       "supported\n", *cmd);
 		if ((errsts = check_reset(SCpnt, devip)))
 			break;	/* Unit attention takes precedence */
-		mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_OPCODE, 0, 18);
+		mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_OPCODE, 0);
 		errsts = check_condition_result;
 		break;
 	}
@@ -513,18 +473,105 @@
 			printk(KERN_INFO "scsi_debug: Reporting Unit "
 			       "attention: power on reset\n");
 		devip->reset = 0;
-		mk_sense_buffer(devip, UNIT_ATTENTION, POWERON_RESET, 0, 18);
+		mk_sense_buffer(devip, UNIT_ATTENTION, POWERON_RESET, 0);
 		return check_condition_result;
 	}
 	return 0;
 }
 
-#define SDEBUG_LONG_INQ_SZ 96
-#define SDEBUG_MAX_INQ_ARR_SZ 128
+/* Returns 0 if ok else (DID_ERROR << 16). Sets scp->resid . */
+static int fill_from_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
+				int arr_len)
+{
+	int k, req_len, act_len, len, active;
+	void * kaddr;
+	void * kaddr_off;
+	struct scatterlist * sgpnt;
+
+	if (0 == scp->request_bufflen)
+		return 0;
+	if (NULL == scp->request_buffer)
+		return (DID_ERROR << 16);
+	if (! ((scp->sc_data_direction == DMA_BIDIRECTIONAL) ||
+	      (scp->sc_data_direction == DMA_FROM_DEVICE)))
+		return (DID_ERROR << 16);
+	if (0 == scp->use_sg) {
+		req_len = scp->request_bufflen;
+		act_len = (req_len < arr_len) ? req_len : arr_len;
+		memcpy(scp->request_buffer, arr, act_len);
+		scp->resid = req_len - act_len;
+		return 0;
+	}
+	sgpnt = (struct scatterlist *)scp->request_buffer;
+	active = 1;
+	for (k = 0, req_len = 0, act_len = 0; k < scp->use_sg; ++k, ++sgpnt) {
+		if (active) {
+			kaddr = (unsigned char *)
+				kmap_atomic(sgpnt->page, KM_USER0);
+			if (NULL == kaddr)
+				return (DID_ERROR << 16);
+			kaddr_off = (unsigned char *)kaddr + sgpnt->offset;
+			len = sgpnt->length;
+			if ((req_len + len) > arr_len) {
+				active = 0;
+				len = arr_len - req_len;
+			}
+			memcpy(kaddr_off, arr + req_len, len);
+			kunmap_atomic(kaddr, KM_USER0);
+			act_len += len;
+		}
+		req_len += sgpnt->length;
+	}
+	scp->resid = req_len - act_len;
+	return 0;
+}
 
-static const char * vendor_id = "Linux   ";
-static const char * product_id = "scsi_debug      ";
-static const char * product_rev = "0004";
+/* Returns number of bytes fetched into 'arr' or -1 if error. */
+static int fetch_to_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
+			       int max_arr_len)
+{
+	int k, req_len, len, fin;
+	void * kaddr;
+	void * kaddr_off;
+	struct scatterlist * sgpnt;
+
+	if (0 == scp->request_bufflen)
+		return 0;
+	if (NULL == scp->request_buffer)
+		return -1;
+	if (! ((scp->sc_data_direction == DMA_BIDIRECTIONAL) ||
+	      (scp->sc_data_direction == DMA_TO_DEVICE)))
+		return -1;
+	if (0 == scp->use_sg) {
+		req_len = scp->request_bufflen;
+		len = (req_len < max_arr_len) ? req_len : max_arr_len;
+		memcpy(arr, scp->request_buffer, len);
+		return len;
+	}
+	sgpnt = (struct scatterlist *)scp->request_buffer;
+	for (k = 0, req_len = 0, fin = 0; k < scp->use_sg; ++k, ++sgpnt) {
+		kaddr = (unsigned char *)kmap_atomic(sgpnt->page, KM_USER0);
+		if (NULL == kaddr)
+			return -1;
+		kaddr_off = (unsigned char *)kaddr + sgpnt->offset;
+		len = sgpnt->length;
+		if ((req_len + len) > max_arr_len) {
+			len = max_arr_len - req_len;
+			fin = 1;
+		}
+		memcpy(arr + req_len, kaddr_off, len);
+		kunmap_atomic(kaddr, KM_USER0);
+		if (fin)
+			return req_len + len;
+		req_len += sgpnt->length;
+	}
+	return req_len;
+}
+
+
+static const char * inq_vendor_id = "Linux   ";
+static const char * inq_product_id = "scsi_debug      ";
+static const char * inq_product_rev = "0004";
 
 static int inquiry_evpd_83(unsigned char * arr, int dev_id_num,
 			   const char * dev_id_str, int dev_id_str_len)
@@ -536,8 +583,8 @@
 	arr[0] = 0x2;	/* ASCII */
 	arr[1] = 0x1;
 	arr[2] = 0x0;
-	memcpy(&arr[4], vendor_id, 8);
-	memcpy(&arr[12], product_id, 16);
+	memcpy(&arr[4], inq_vendor_id, 8);
+	memcpy(&arr[12], inq_product_id, 16);
 	memcpy(&arr[28], dev_id_str, dev_id_str_len);
 	num = 8 + 16 + dev_id_str_len;
 	arr[3] = num;
@@ -558,24 +605,25 @@
 	return num + 12;
 }
 
-static int resp_inquiry(unsigned char * cmd, int target, unsigned char * buff,
-			int bufflen, struct sdebug_dev_info * devip)
+
+#define SDEBUG_LONG_INQ_SZ 96
+#define SDEBUG_MAX_INQ_ARR_SZ 128
+
+static int resp_inquiry(struct scsi_cmnd * scp, int target,
+			struct sdebug_dev_info * devip)
 {
 	unsigned char pq_pdt;
 	unsigned char arr[SDEBUG_MAX_INQ_ARR_SZ];
-	int min_len = bufflen > SDEBUG_MAX_INQ_ARR_SZ ?
-			SDEBUG_MAX_INQ_ARR_SZ : bufflen;
+	unsigned char *cmd = (unsigned char *)scp->cmnd;
+	int alloc_len;
 
-	if (bufflen < cmd[4])
-		printk(KERN_INFO "scsi_debug: inquiry: bufflen=%d "
-		       "< alloc_length=%d\n", bufflen, (int)cmd[4]);
-	memset(buff, 0, bufflen);
+	alloc_len = (cmd[3] << 8) + cmd[4];
 	memset(arr, 0, SDEBUG_MAX_INQ_ARR_SZ);
 	pq_pdt = (scsi_debug_ptype & 0x1f);
 	arr[0] = pq_pdt;
 	if (0x2 & cmd[1]) {  /* CMDDT bit set */
 		mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB,
-			       	0, 18);
+			       	0);
 		return check_condition_result;
 	} else if (0x1 & cmd[1]) {  /* EVPD bit set */
 		int dev_id_num, len;
@@ -600,11 +648,11 @@
 		} else {
 			/* Illegal request, invalid field in cdb */
 			mk_sense_buffer(devip, ILLEGAL_REQUEST,
-					INVALID_FIELD_IN_CDB, 0, 18);
+					INVALID_FIELD_IN_CDB, 0);
 			return check_condition_result;
 		}
-		memcpy(buff, arr, min_len);
-		return 0;
+		return fill_from_dev_buffer(scp, arr,
+			    min(alloc_len, SDEBUG_MAX_INQ_ARR_SZ));
 	}
 	/* drops through here for a standard inquiry */
 	arr[1] = DEV_REMOVEABLE(target) ? 0x80 : 0;	/* Removable disk */
@@ -612,20 +660,67 @@
 	arr[3] = 2;    /* response_data_format==2 */
 	arr[4] = SDEBUG_LONG_INQ_SZ - 5;
 	arr[6] = 0x1; /* claim: ADDR16 */
+	/* arr[6] |= 0x40; ... claim: EncServ (enclosure services) */
 	arr[7] = 0x3a; /* claim: WBUS16, SYNC, LINKED + CMDQUE */
-	memcpy(&arr[8], vendor_id, 8);
-	memcpy(&arr[16], product_id, 16);
-	memcpy(&arr[32], product_rev, 4);
+	memcpy(&arr[8], inq_vendor_id, 8);
+	memcpy(&arr[16], inq_product_id, 16);
+	memcpy(&arr[32], inq_product_rev, 4);
 	/* version descriptors (2 bytes each) follow */
 	arr[58] = 0x0; arr[59] = 0x40; /* SAM-2 */
-	arr[60] = 0x2; arr[61] = 0x60; /* SPC-2 */
+	arr[60] = 0x3; arr[61] = 0x0;  /* SPC-3 */
 	if (scsi_debug_ptype == 0) {
-	    arr[62] = 0x1; arr[63] = 0x80; /* SBC */
+		arr[62] = 0x1; arr[63] = 0x80; /* SBC */
 	} else if (scsi_debug_ptype == 1) {
-	    arr[62] = 0x2; arr[63] = 0x00; /* SSC */
+		arr[62] = 0x2; arr[63] = 0x00; /* SSC */
 	}
-	memcpy(buff, arr, min_len);
-	return 0;
+	return fill_from_dev_buffer(scp, arr,
+			    min(alloc_len, SDEBUG_LONG_INQ_SZ));
+}
+
+static int resp_requests(struct scsi_cmnd * scp,
+			 struct sdebug_dev_info * devip)
+{
+	unsigned char * sbuff;
+	unsigned char *cmd = (unsigned char *)scp->cmnd;
+	unsigned char arr[SDEBUG_SENSE_LEN];
+	int len = 18;
+
+	memset(arr, 0, SDEBUG_SENSE_LEN);
+	if (devip->reset == 1)
+		mk_sense_buffer(devip, 0, NO_ADDED_SENSE, 0);
+	sbuff = devip->sense_buff;
+	if ((cmd[1] & 1) && (! scsi_debug_dsense)) {
+		/* DESC bit set and sense_buff in fixed format */
+		arr[0] = 0x72;
+		arr[1] = sbuff[2];     /* sense key */
+		arr[2] = sbuff[12];    /* asc */
+		arr[3] = sbuff[13];    /* ascq */
+		len = 8;
+	} else
+		memcpy(arr, sbuff, SDEBUG_SENSE_LEN);
+	mk_sense_buffer(devip, 0, NO_ADDED_SENSE, 0);
+	return fill_from_dev_buffer(scp, arr, len);
+}
+
+#define SDEBUG_READCAP_ARR_SZ 8
+static int resp_readcap(struct scsi_cmnd * scp,
+			struct sdebug_dev_info * devip)
+{
+	unsigned char arr[SDEBUG_READCAP_ARR_SZ];
+	unsigned long capac;
+	int errsts;
+
+	if ((errsts = check_reset(scp, devip)))
+		return errsts;
+	memset(arr, 0, SDEBUG_READCAP_ARR_SZ);
+	capac = (unsigned long)sdebug_capacity - 1;
+	arr[0] = (capac >> 24);
+	arr[1] = (capac >> 16) & 0xff;
+	arr[2] = (capac >> 8) & 0xff;
+	arr[3] = capac & 0xff;
+	arr[6] = (SECT_SIZE_PER(target) >> 8) & 0xff;
+	arr[7] = SECT_SIZE_PER(target) & 0xff;
+	return fill_from_dev_buffer(scp, arr, SDEBUG_READCAP_ARR_SZ);
 }
 
 /* <<Following mode page info copied from ST318451LW>> */
@@ -706,34 +801,29 @@
 
 #define SDEBUG_MAX_MSENSE_SZ 256
 
-static int resp_mode_sense(unsigned char * cmd, int target,
-			   unsigned char * buff, int bufflen,
+static int resp_mode_sense(struct scsi_cmnd * scp, int target,
 			   struct sdebug_dev_info * devip)
 {
 	unsigned char dbd;
 	int pcontrol, pcode, subpcode;
 	unsigned char dev_spec;
-	int alloc_len, msense_6, offset, len;
+	int alloc_len, msense_6, offset, len, errsts;
 	unsigned char * ap;
 	unsigned char arr[SDEBUG_MAX_MSENSE_SZ];
-	int min_len = bufflen > SDEBUG_MAX_MSENSE_SZ ?
-			SDEBUG_MAX_MSENSE_SZ : bufflen;
+	unsigned char *cmd = (unsigned char *)scp->cmnd;
 
-	SCSI_LOG_LLQUEUE(3, printk("Mode sense ...(%p %d)\n", buff, bufflen));
+	if ((errsts = check_reset(scp, devip)))
+		return errsts;
 	dbd = cmd[1] & 0x8;
 	pcontrol = (cmd[2] & 0xc0) >> 6;
 	pcode = cmd[2] & 0x3f;
 	subpcode = cmd[3];
 	msense_6 = (MODE_SENSE == cmd[0]);
 	alloc_len = msense_6 ? cmd[4] : ((cmd[7] << 8) | cmd[8]);
-	if (bufflen < alloc_len)
-		printk(KERN_INFO "scsi_debug: mode_sense: bufflen=%d "
-		       "< alloc_length=%d\n", bufflen, alloc_len);
-	memset(buff, 0, bufflen);
 	memset(arr, 0, SDEBUG_MAX_MSENSE_SZ);
 	if (0x3 == pcontrol) {  /* Saving values not supported */
 		mk_sense_buffer(devip, ILLEGAL_REQUEST, SAVING_PARAMS_UNSUP,
-			       	0, 18);
+			       	0);
 		return check_condition_result;
 	}
 	dev_spec = DEV_READONLY(target) ? 0x80 : 0x0;
@@ -748,7 +838,7 @@
 
 	if (0 != subpcode) { /* TODO: Control Extension page */
 		mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB,
-			       	0, 18);
+			       	0);
 		return check_condition_result;
 	}
 	switch (pcode) {
@@ -787,146 +877,104 @@
 		break;
 	default:
 		mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB,
-			       	0, 18);
+			       	0);
 		return check_condition_result;
 	}
 	if (msense_6)
 		arr[0] = offset - 1;
 	else {
-		offset -= 2;
-		arr[0] = (offset >> 8) & 0xff;
-		arr[1] = offset & 0xff;
+		arr[0] = ((offset - 2) >> 8) & 0xff;
+		arr[1] = (offset - 2) & 0xff;
 	}
-	memcpy(buff, arr, min_len);
-	return 0;
+	return fill_from_dev_buffer(scp, arr, min(alloc_len, offset));
 }
 
 static int resp_read(struct scsi_cmnd * SCpnt, int upper_blk, int block,
 		     int num, struct sdebug_dev_info * devip)
 {
-        unsigned char *buff = (unsigned char *) SCpnt->request_buffer;
-        int nbytes, sgcount;
-        struct scatterlist *sgpnt = NULL;
-        int bufflen = SCpnt->request_bufflen;
 	unsigned long iflags;
+	int ret;
 
 	if (upper_blk || (block + num > sdebug_capacity)) {
 		mk_sense_buffer(devip, ILLEGAL_REQUEST, ADDR_OUT_OF_RANGE,
-				0, 18);
+				0);
 		return check_condition_result;
 	}
 	if ((SCSI_DEBUG_OPT_MEDIUM_ERR & scsi_debug_opts) &&
 	    (block <= OPT_MEDIUM_ERR_ADDR) &&
 	    ((block + num) > OPT_MEDIUM_ERR_ADDR)) {
 		mk_sense_buffer(devip, MEDIUM_ERROR, UNRECOVERED_READ_ERR,
-				0, 18);
+				0);
 		/* claim unrecoverable read error */
 		return check_condition_result;
 	}
 	read_lock_irqsave(&atomic_rw, iflags);
-        sgcount = 0;
-	nbytes = bufflen;
-	/* printk(KERN_INFO "scsi_debug_read: block=%d, tot_bufflen=%d\n",
-	       block, bufflen); */
-	if (SCpnt->use_sg) {
-		sgcount = 0;
-		sgpnt = (struct scatterlist *) buff;
-		buff = scatg2virt(&sgpnt[sgcount]);
-		bufflen = sgpnt[sgcount].length;
-	}
-	do {
-		memcpy(buff, fake_storep + (block * SECT_SIZE), bufflen);
-		nbytes -= bufflen;
-		if (SCpnt->use_sg) {
-			block += bufflen >> POW2_SECT_SIZE;
-			sgcount++;
-			if (nbytes) {
-				buff = scatg2virt(&sgpnt[sgcount]);
-				bufflen = sgpnt[sgcount].length;
-			}
-		} else if (nbytes > 0)
-			printk(KERN_WARNING "scsi_debug:resp_read: unexpected "
-			       "nbytes=%d\n", nbytes);
-	} while (nbytes);
+	ret = fill_from_dev_buffer(SCpnt, fake_storep + (block * SECT_SIZE),
+			   	   num * SECT_SIZE);
 	read_unlock_irqrestore(&atomic_rw, iflags);
-	return 0;
+	return ret;
 }
 
 static int resp_write(struct scsi_cmnd * SCpnt, int upper_blk, int block,
 		      int num, struct sdebug_dev_info * devip)
 {
-        unsigned char *buff = (unsigned char *) SCpnt->request_buffer;
-        int nbytes, sgcount;
-        struct scatterlist *sgpnt = NULL;
-        int bufflen = SCpnt->request_bufflen;
 	unsigned long iflags;
+	int res;
 
 	if (upper_blk || (block + num > sdebug_capacity)) {
 		mk_sense_buffer(devip, ILLEGAL_REQUEST, ADDR_OUT_OF_RANGE,
-			       	0, 18);
+			       	0);
 		return check_condition_result;
 	}
 
 	write_lock_irqsave(&atomic_rw, iflags);
-        sgcount = 0;
-	nbytes = bufflen;
-	if (SCpnt->use_sg) {
-		sgcount = 0;
-		sgpnt = (struct scatterlist *) buff;
-		buff = scatg2virt(&sgpnt[sgcount]);
-		bufflen = sgpnt[sgcount].length;
-	}
-	do {
-		memcpy(fake_storep + (block * SECT_SIZE), buff, bufflen);
-
-		nbytes -= bufflen;
-		if (SCpnt->use_sg) {
-			block += bufflen >> POW2_SECT_SIZE;
-			sgcount++;
-			if (nbytes) {
-				buff = scatg2virt(&sgpnt[sgcount]);
-				bufflen = sgpnt[sgcount].length;
-			}
-		} else if (nbytes > 0)
-			printk(KERN_WARNING "scsi_debug:resp_write: "
-			       "unexpected nbytes=%d\n", nbytes);
-	} while (nbytes);
+	res = fetch_to_dev_buffer(SCpnt, fake_storep + (block * SECT_SIZE),
+			   	  num * SECT_SIZE);
 	write_unlock_irqrestore(&atomic_rw, iflags);
+	if (-1 == res)
+		return (DID_ERROR << 16);
+	else if ((res < (num * SECT_SIZE)) &&
+		 (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts))
+		printk(KERN_INFO "scsi_debug: write: cdb indicated=%d, "
+		       " IO sent=%d bytes\n", num * SECT_SIZE, res);
 	return 0;
 }
 
-static int resp_report_luns(unsigned char * cmd, unsigned char * buff,
-			    int bufflen, struct sdebug_dev_info * devip)
+#define SDEBUG_RLUN_ARR_SZ 128
+
+static int resp_report_luns(struct scsi_cmnd * scp,
+			    struct sdebug_dev_info * devip)
 {
 	unsigned int alloc_len;
 	int lun_cnt, i, upper;
+	unsigned char *cmd = (unsigned char *)scp->cmnd;
 	int select_report = (int)cmd[2];
 	struct scsi_lun *one_lun;
+	unsigned char arr[SDEBUG_RLUN_ARR_SZ];
 
 	alloc_len = cmd[9] + (cmd[8] << 8) + (cmd[7] << 16) + (cmd[6] << 24);
 	if ((alloc_len < 16) || (select_report > 2)) {
 		mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB,
-			       	0, 18);
+			       	0);
 		return check_condition_result;
 	}
-	if (bufflen > 8) { /* can produce response with up to 16k luns
-			      (lun 0 to lun 16383) */
-		memset(buff, 0, bufflen);
-		lun_cnt = scsi_debug_max_luns;
-		buff[2] = ((sizeof(struct scsi_lun) * lun_cnt) >> 8) & 0xff;
-		buff[3] = (sizeof(struct scsi_lun) * lun_cnt) & 0xff;
-		lun_cnt = min((int)((bufflen - 8) / sizeof(struct scsi_lun)),
-			      lun_cnt);
-		one_lun = (struct scsi_lun *) &buff[8];
-		for (i = 0; i < lun_cnt; i++) {
-			upper = (i >> 8) & 0x3f;
-			if (upper)
-				one_lun[i].scsi_lun[0] =
-				    (upper | (SAM2_LUN_ADDRESS_METHOD << 6));
-			one_lun[i].scsi_lun[1] = i & 0xff;
-		}
+	/* can produce response with up to 16k luns (lun 0 to lun 16383) */
+	memset(arr, 0, SDEBUG_RLUN_ARR_SZ);
+	lun_cnt = scsi_debug_max_luns;
+	arr[2] = ((sizeof(struct scsi_lun) * lun_cnt) >> 8) & 0xff;
+	arr[3] = (sizeof(struct scsi_lun) * lun_cnt) & 0xff;
+	lun_cnt = min((int)((SDEBUG_RLUN_ARR_SZ - 8) /
+			    sizeof(struct scsi_lun)), lun_cnt);
+	one_lun = (struct scsi_lun *) &arr[8];
+	for (i = 0; i < lun_cnt; i++) {
+		upper = (i >> 8) & 0x3f;
+		if (upper)
+			one_lun[i].scsi_lun[0] =
+			    (upper | (SAM2_LUN_ADDRESS_METHOD << 6));
+		one_lun[i].scsi_lun[1] = i & 0xff;
 	}
-	return 0;
+	return fill_from_dev_buffer(scp, arr,
+				    min((int)alloc_len, SDEBUG_RLUN_ARR_SZ));
 }
 
 /* When timer goes off this function is called. */
@@ -1041,14 +1089,19 @@
 		open_devip->reset = 1;
 		open_devip->used = 1;
 		memset(open_devip->sense_buff, 0, SDEBUG_SENSE_LEN);
-		open_devip->sense_buff[0] = 0x70;
+		if (scsi_debug_dsense)
+			open_devip->sense_buff[0] = 0x72;
+		else {
+			open_devip->sense_buff[0] = 0x70;
+			open_devip->sense_buff[7] = 0xa;
+		}
 		return open_devip;
         }
         return NULL;
 }
 
 static void mk_sense_buffer(struct sdebug_dev_info * devip, int key,
-			    int asc, int asq, int inbandLen)
+			    int asc, int asq)
 {
 	unsigned char * sbuff;
 
@@ -1060,11 +1113,9 @@
 		sbuff[2] = asc;
 		sbuff[3] = asq;
 	} else {
-		if (inbandLen > SDEBUG_SENSE_LEN)
-			inbandLen = SDEBUG_SENSE_LEN;
 		sbuff[0] = 0x70;  /* fixed, current */
 		sbuff[2] = key;
-		sbuff[7] = (inbandLen > 7) ? (inbandLen - 8) : 0;
+		sbuff[7] = 0xa;	  /* implies 18 byte sense buffer */
 		sbuff[12] = asc;
 		sbuff[13] = asq;
 	}
@@ -1355,7 +1406,7 @@
 MODULE_PARM_DESC(num_tgts, "number of SCSI targets per host to simulate");
 MODULE_PARM_DESC(opts, "1->noise, 2->medium_error, 4->...");
 MODULE_PARM_DESC(ptype, "SCSI peripheral type(def=0[disk])");
-MODULE_PARM_DESC(scsi_level, "SCSI level to simulate(def=4[SPC-2])");
+MODULE_PARM_DESC(scsi_level, "SCSI level to simulate(def=5[SPC-3])");
 
 
 static char sdebug_info[256];
@@ -1391,7 +1442,7 @@
 		if (1 != sscanf(arr, "%d", &pos))
 			return -EINVAL;
 		scsi_debug_opts = pos;
-		if (scsi_debug_every_nth > 0)
+		if (scsi_debug_every_nth != 0)
                         scsi_debug_cmnd_count = 0;
 		return length;
 	}
@@ -1547,7 +1598,7 @@
 {
         int nth;
 
-	if ((count > 0) && (1 == sscanf(buf, "%d", &nth)) && (nth >= 0)) {
+	if ((count > 0) && (1 == sscanf(buf, "%d", &nth))) {
 		scsi_debug_every_nth = nth;
 		scsi_debug_cmnd_count = 0;
 		return count;
@@ -1624,6 +1675,7 @@
 	driver_create_file(&sdebug_driverfs_driver, &driver_attr_add_host);
 	driver_create_file(&sdebug_driverfs_driver, &driver_attr_delay);
 	driver_create_file(&sdebug_driverfs_driver, &driver_attr_dev_size_mb);
+	driver_create_file(&sdebug_driverfs_driver, &driver_attr_dsense);
 	driver_create_file(&sdebug_driverfs_driver, &driver_attr_every_nth);
 	driver_create_file(&sdebug_driverfs_driver, &driver_attr_max_luns);
 	driver_create_file(&sdebug_driverfs_driver, &driver_attr_num_tgts);
@@ -1642,6 +1694,7 @@
 	driver_remove_file(&sdebug_driverfs_driver, &driver_attr_num_tgts);
 	driver_remove_file(&sdebug_driverfs_driver, &driver_attr_max_luns);
 	driver_remove_file(&sdebug_driverfs_driver, &driver_attr_every_nth);
+	driver_remove_file(&sdebug_driverfs_driver, &driver_attr_dsense);
 	driver_remove_file(&sdebug_driverfs_driver, &driver_attr_dev_size_mb);
 	driver_remove_file(&sdebug_driverfs_driver, &driver_attr_delay);
 	driver_remove_file(&sdebug_driverfs_driver, &driver_attr_add_host);
diff -Nru a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c
--- a/drivers/scsi/scsi_devinfo.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/scsi/scsi_devinfo.c	2005-03-01 23:38:55 -08:00
@@ -28,7 +28,7 @@
 static const char spaces[] = "                "; /* 16 of them */
 static unsigned scsi_default_dev_flags;
 static LIST_HEAD(scsi_dev_info_list);
-static __initdata char scsi_dev_flags[256];
+static char scsi_dev_flags[256];
 
 /*
  * scsi_static_device_list: deprecated list of devices that require
diff -Nru a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
--- a/drivers/scsi/scsi_error.c	2005-03-01 23:38:44 -08:00
+++ b/drivers/scsi/scsi_error.c	2005-03-01 23:38:44 -08:00
@@ -125,6 +125,7 @@
 
 	add_timer(&scmd->eh_timeout);
 }
+EXPORT_SYMBOL(scsi_add_timer);
 
 /**
  * scsi_delete_timer - Delete/cancel timer for a given function.
@@ -152,6 +153,7 @@
 
 	return rtn;
 }
+EXPORT_SYMBOL(scsi_delete_timer);
 
 /**
  * scsi_times_out - Timeout function for normal scsi commands.
@@ -214,6 +216,7 @@
 
 	return online;
 }
+EXPORT_SYMBOL(scsi_block_when_processing_errors);
 
 #ifdef CONFIG_SCSI_LOGGING
 /**
@@ -268,16 +271,42 @@
  *
  * Return value:
  * 	SUCCESS or FAILED or NEEDS_RETRY
+ *
+ * Notes:
+ *	When a deferred error is detected the current command has
+ *	not been executed and needs retrying.
  **/
 static int scsi_check_sense(struct scsi_cmnd *scmd)
 {
-	if (!SCSI_SENSE_VALID(scmd))
-		return FAILED;
+	struct scsi_sense_hdr sshdr;
 
-	if (scmd->sense_buffer[2] & 0xe0)
-		return SUCCESS;
+	if (! scsi_command_normalize_sense(scmd, &sshdr))
+		return FAILED;	/* no valid sense data */
+
+	if (scsi_sense_is_deferred(&sshdr))
+		return NEEDS_RETRY;
+
+	/*
+	 * Previous logic looked for FILEMARK, EOM or ILI which are
+	 * mainly associated with tapes and returned SUCCESS.
+	 */
+	if (sshdr.response_code == 0x70) {
+		/* fixed format */
+		if (scmd->sense_buffer[2] & 0xe0)
+			return SUCCESS;
+	} else {
+		/*
+		 * descriptor format: look for "stream commands sense data
+		 * descriptor" (see SSC-3). Assume single sense data
+		 * descriptor. Ignore ILI from SBC-2 READ LONG and WRITE LONG.
+		 */
+		if ((sshdr.additional_length > 3) &&
+		    (scmd->sense_buffer[8] == 0x4) &&
+		    (scmd->sense_buffer[11] & 0xe0))
+			return SUCCESS;
+	}
 
-	switch (scmd->sense_buffer[2] & 0xf) {
+	switch (sshdr.sense_key) {
 	case NO_SENSE:
 		return SUCCESS;
 	case RECOVERED_ERROR:
@@ -301,19 +330,15 @@
 		 * if the device is in the process of becoming ready, we 
 		 * should retry.
 		 */
-		if ((scmd->sense_buffer[12] == 0x04) &&
-			(scmd->sense_buffer[13] == 0x01)) {
+		if ((sshdr.asc == 0x04) && (sshdr.ascq == 0x01))
 			return NEEDS_RETRY;
-		}
 		/*
 		 * if the device is not started, we need to wake
 		 * the error handler to start the motor
 		 */
 		if (scmd->device->allow_restart &&
-		    (scmd->sense_buffer[12] == 0x04) &&
-		    (scmd->sense_buffer[13] == 0x02)) {
+		    (sshdr.asc == 0x04) && (sshdr.ascq == 0x02))
 			return FAILED;
-		}
 		return SUCCESS;
 
 		/* these three are not supported */
@@ -1358,7 +1383,8 @@
 		return SUCCESS;
 
 	case RESERVATION_CONFLICT:
-		printk("scsi%d (%d,%d,%d) : reservation conflict\n",
+		printk(KERN_INFO "scsi: reservation conflict: host"
+                                " %d channel %d id %d lun %d\n",
 		       scmd->device->host->host_no, scmd->device->channel,
 		       scmd->device->id, scmd->device->lun);
 		return SUCCESS; /* causes immediate i/o error */
@@ -1729,6 +1755,7 @@
 		}
 	}
 }
+EXPORT_SYMBOL(scsi_report_bus_reset);
 
 /*
  * Function:    scsi_report_device_reset()
@@ -1764,6 +1791,7 @@
 		}
 	}
 }
+EXPORT_SYMBOL(scsi_report_device_reset);
 
 static void
 scsi_reset_provider_done_command(struct scsi_cmnd *scmd)
@@ -1843,6 +1871,7 @@
 	scsi_next_command(scmd);
 	return rtn;
 }
+EXPORT_SYMBOL(scsi_reset_provider);
 
 /**
  * scsi_normalize_sense - normalize main elements from either fixed or
@@ -1919,3 +1948,96 @@
 			sizeof(cmd->sense_buffer), sshdr);
 }
 EXPORT_SYMBOL(scsi_command_normalize_sense);
+
+/**
+ * scsi_sense_desc_find - search for a given descriptor type in
+ *			descriptor sense data format.
+ *
+ * @sense_buffer:	byte array of descriptor format sense data
+ * @sb_len:		number of valid bytes in sense_buffer
+ * @desc_type:		value of descriptor type to find
+ *			(e.g. 0 -> information)
+ *
+ * Notes:
+ *	only valid when sense data is in descriptor format
+ *
+ * Return value:
+ *	pointer to start of (first) descriptor if found else NULL
+ **/
+const u8 * scsi_sense_desc_find(const u8 * sense_buffer, int sb_len,
+				int desc_type)
+{
+	int add_sen_len, add_len, desc_len, k;
+	const u8 * descp;
+
+	if ((sb_len < 8) || (0 == (add_sen_len = sense_buffer[7])))
+		return NULL;
+	if ((sense_buffer[0] < 0x72) || (sense_buffer[0] > 0x73))
+		return NULL;
+	add_sen_len = (add_sen_len < (sb_len - 8)) ?
+			add_sen_len : (sb_len - 8);
+	descp = &sense_buffer[8];
+	for (desc_len = 0, k = 0; k < add_sen_len; k += desc_len) {
+		descp += desc_len;
+		add_len = (k < (add_sen_len - 1)) ? descp[1]: -1;
+		desc_len = add_len + 2;
+		if (descp[0] == desc_type)
+			return descp;
+		if (add_len < 0) // short descriptor ??
+			break;
+	}
+	return NULL;
+}
+EXPORT_SYMBOL(scsi_sense_desc_find);
+
+/**
+ * scsi_get_sense_info_fld - attempts to get information field from
+ *			sense data (either fixed or descriptor format)
+ *
+ * @sense_buffer:	byte array of sense data
+ * @sb_len:		number of valid bytes in sense_buffer
+ * @info_out:		pointer to 64 integer where 8 or 4 byte information
+ *			field will be placed if found.
+ *
+ * Return value:
+ *	1 if information field found, 0 if not found.
+ **/
+int scsi_get_sense_info_fld(const u8 * sense_buffer, int sb_len,
+			    u64 * info_out)
+{
+	int j;
+	const u8 * ucp;
+	u64 ull;
+
+	if (sb_len < 7)
+		return 0;
+	switch (sense_buffer[0] & 0x7f) {
+	case 0x70:
+	case 0x71:
+		if (sense_buffer[0] & 0x80) {
+			*info_out = (sense_buffer[3] << 24) +
+				    (sense_buffer[4] << 16) +
+				    (sense_buffer[5] << 8) + sense_buffer[6];
+			return 1;
+		} else
+			return 0;
+	case 0x72:
+	case 0x73:
+		ucp = scsi_sense_desc_find(sense_buffer, sb_len,
+					   0 /* info desc */);
+		if (ucp && (0xa == ucp[1])) {
+			ull = 0;
+			for (j = 0; j < 8; ++j) {
+				if (j > 0)
+					ull <<= 8;
+				ull |= ucp[4 + j];
+			}
+			*info_out = ull;
+			return 1;
+		} else
+			return 0;
+	default:
+		return 0;
+	}
+}
+EXPORT_SYMBOL(scsi_get_sense_info_fld);
diff -Nru a/drivers/scsi/scsi_ioctl.c b/drivers/scsi/scsi_ioctl.c
--- a/drivers/scsi/scsi_ioctl.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/scsi/scsi_ioctl.c	2005-03-01 23:39:17 -08:00
@@ -21,6 +21,7 @@
 #include <scsi/scsi_ioctl.h>
 #include <scsi/scsi_request.h>
 #include <scsi/sg.h>
+#include <scsi/scsi_dbg.h>
 
 #include "scsi_logging.h"
 
@@ -94,12 +95,13 @@
 {
 	struct scsi_request *sreq;
 	int result;
+	struct scsi_sense_hdr sshdr;
 
 	SCSI_LOG_IOCTL(1, printk("Trying ioctl with scsi command %d\n", *cmd));
 
 	sreq = scsi_allocate_request(sdev, GFP_KERNEL);
 	if (!sreq) {
-		printk("SCSI internal ioctl failed, no memory\n");
+		printk(KERN_WARNING "SCSI internal ioctl failed, no memory\n");
 		return -ENOMEM;
 	}
 
@@ -108,17 +110,21 @@
 
 	SCSI_LOG_IOCTL(2, printk("Ioctl returned  0x%x\n", sreq->sr_result));
 
-	if (driver_byte(sreq->sr_result)) {
-		switch (sreq->sr_sense_buffer[2] & 0xf) {
+	if ((driver_byte(sreq->sr_result) & DRIVER_SENSE) &&
+	    (scsi_request_normalize_sense(sreq, &sshdr))) {
+		switch (sshdr.sense_key) {
 		case ILLEGAL_REQUEST:
 			if (cmd[0] == ALLOW_MEDIUM_REMOVAL)
 				sdev->lockable = 0;
 			else
-				printk("SCSI device (ioctl) reports ILLEGAL REQUEST.\n");
+				printk(KERN_INFO "ioctl_internal_command: "
+				       "ILLEGAL REQUEST asc=0x%x ascq=0x%x\n",
+				       sshdr.asc, sshdr.ascq);
 			break;
 		case NOT_READY:	/* This happens if there is no disc in drive */
 			if (sdev->removable && (cmd[0] != TEST_UNIT_READY)) {
-				printk(KERN_INFO "Device not ready.  Make sure there is a disc in the drive.\n");
+				printk(KERN_INFO "Device not ready. Make sure"
+				       " there is a disc in the drive.\n");
 				break;
 			}
 		case UNIT_ATTENTION:
@@ -128,16 +134,15 @@
 				break;
 			}
 		default:	/* Fall through for non-removable media */
-			printk("SCSI error: host %d id %d lun %d return code = %x\n",
+			printk(KERN_INFO "ioctl_internal_command: <%d %d %d "
+			       "%d> return code = %x\n",
 			       sdev->host->host_no,
+			       sdev->channel,
 			       sdev->id,
 			       sdev->lun,
 			       sreq->sr_result);
-			printk("\tSense class %x, sense error %x, extended sense %x\n",
-			       sense_class(sreq->sr_sense_buffer[0]),
-			       sense_error(sreq->sr_sense_buffer[0]),
-			       sreq->sr_sense_buffer[2] & 0xf);
-
+			scsi_print_req_sense("   ", sreq);
+			break;
 		}
 	}
 
@@ -168,6 +173,7 @@
 		sdev->locked = (state == SCSI_REMOVAL_PREVENT);
 	return ret;
 }
+EXPORT_SYMBOL(scsi_set_medium_removal);
 
 /*
  * This interface is deprecated - users should use the scsi generic (sg)
@@ -349,6 +355,7 @@
 	kfree(buf);
 	return result;
 }
+EXPORT_SYMBOL(scsi_ioctl_send_command);
 
 /*
  * The scsi_ioctl_get_pci() function places into arg the value
@@ -401,7 +408,8 @@
 	case SCSI_IOCTL_SYNC:
 	case SCSI_IOCTL_START_UNIT:
 	case SCSI_IOCTL_STOP_UNIT:
-		printk(KERN_WARNING "program %s is using a deprecated SCSI ioctl, please convert it to SG_IO\n", current->comm);
+		printk(KERN_WARNING "program %s is using a deprecated SCSI "
+		       "ioctl, please convert it to SG_IO\n", current->comm);
 		break;
 	default:
 		break;
@@ -457,6 +465,7 @@
 	}
 	return -EINVAL;
 }
+EXPORT_SYMBOL(scsi_ioctl);
 
 /*
  * the scsi_nonblock_ioctl() function is designed for ioctls which may
diff -Nru a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
--- a/drivers/scsi/scsi_lib.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/scsi/scsi_lib.c	2005-03-01 23:38:57 -08:00
@@ -233,7 +233,8 @@
 	 */
 	scsi_insert_special_req(sreq, 1);
 }
- 
+EXPORT_SYMBOL(scsi_do_req);
+
 static void scsi_wait_done(struct scsi_cmnd *cmd)
 {
 	struct request *req = cmd->request;
@@ -267,6 +268,7 @@
 
 	__scsi_release_request(sreq);
 }
+EXPORT_SYMBOL(scsi_wait_req);
 
 /*
  * Function:    scsi_init_cmd_errh()
@@ -496,19 +498,17 @@
 /*
  * Function:    scsi_end_request()
  *
- * Purpose:     Post-processing of completed commands called from interrupt
- *              handler or a bottom-half handler.
+ * Purpose:     Post-processing of completed commands (usually invoked at end
+ *		of upper level post-processing and scsi_io_completion).
  *
  * Arguments:   cmd	 - command that is complete.
- *              uptodate - 1 if I/O indicates success, 0 for I/O error.
- *              sectors  - number of sectors we want to mark.
+ *              uptodate - 1 if I/O indicates success, <= 0 for I/O error.
+ *              bytes    - number of bytes of completed I/O
  *		requeue  - indicates whether we should requeue leftovers.
- *		frequeue - indicates that if we release the command block
- *			   that the queue request function should be called.
  *
  * Lock status: Assumed that lock is not held upon entry.
  *
- * Returns:     Nothing
+ * Returns:     cmd if requeue done or required, NULL otherwise
  *
  * Notes:       This is called for block device requests in order to
  *              mark some number of sectors as complete.
@@ -694,6 +694,8 @@
 	struct request *req = cmd->request;
 	int clear_errors = 1;
 	struct scsi_sense_hdr sshdr;
+	int sense_valid = 0;
+	int sense_deferred = 0;
 
 	/*
 	 * Free up any indirection buffers we allocated for DMA purposes. 
@@ -712,13 +714,18 @@
 		kfree(cmd->buffer);
 	}
 
+	if (result) {
+		sense_valid = scsi_command_normalize_sense(cmd, &sshdr);
+		if (sense_valid)
+			sense_deferred = scsi_sense_is_deferred(&sshdr);
+	}
 	if (blk_pc_request(req)) { /* SG_IO ioctl from block level */
 		req->errors = result;
 		if (result) {
 			clear_errors = 0;
-			if (scsi_command_normalize_sense(cmd, &sshdr)) {
+			if (sense_valid) {
 				/*
-				 * SG_IO wants to know about deferred errors
+				 * SG_IO wants current and deferred errors
 				 */
 				int len = 8 + cmd->sense_buffer[7];
 
@@ -777,52 +784,37 @@
 	 * sense buffer.  We can extract information from this, so we
 	 * can choose a block to remap, etc.
 	 */
-	if (driver_byte(result) != 0) {
-		if (scsi_command_normalize_sense(cmd, &sshdr) &&
-				!scsi_sense_is_deferred(&sshdr)) {
-			/*
-			 * If the device is in the process of becoming ready,
-			 * retry.
-			 */
-			if (sshdr.asc == 0x04 && sshdr.ascq == 0x01) {
+	if (sense_valid && !sense_deferred) {
+		switch (sshdr.sense_key) {
+		case UNIT_ATTENTION:
+			if (cmd->device->removable) {
+				/* detected disc change.  set a bit 
+				 * and quietly refuse further access.
+				 */
+				cmd->device->changed = 1;
+				cmd = scsi_end_request(cmd, 0,
+						this_count, 1);
+				return;
+			} else {
+				/*
+				* Must have been a power glitch, or a
+				* bus reset.  Could not have been a
+				* media change, so we just retry the
+				* request and see what happens.  
+				*/
 				scsi_requeue_command(q, cmd);
 				return;
 			}
-			if (sshdr.sense_key == UNIT_ATTENTION) {
-				if (cmd->device->removable) {
-					/* detected disc change.  set a bit 
-					 * and quietly refuse further access.
-		 			 */
-					cmd->device->changed = 1;
-					cmd = scsi_end_request(cmd, 0,
-							this_count, 1);
-					return;
-				} else {
-					/*
-				 	* Must have been a power glitch, or a
-				 	* bus reset.  Could not have been a
-				 	* media change, so we just retry the
-				 	* request and see what happens.  
-				 	*/
-					scsi_requeue_command(q, cmd);
-					return;
-				}
-			}
-		}
-		/*
-		 * If we had an ILLEGAL REQUEST returned, then we may have
-		 * performed an unsupported command.  The only thing this
-		 * should be would be a ten byte read where only a six byte
-		 * read was supported.  Also, on a system where READ CAPACITY
-		 * failed, we may have read past the end of the disk.
-		 */
-
-		/*
-		 * XXX: Following is probably broken since deferred errors
-		 *	fall through [dpg 20040827]
-		 */
-		switch (sshdr.sense_key) {
+			break;
 		case ILLEGAL_REQUEST:
+			/*
+		 	* If we had an ILLEGAL REQUEST returned, then we may
+		 	* have performed an unsupported command.  The only
+		 	* thing this should be would be a ten byte read where
+			* only a six byte read was supported.  Also, on a
+			* system where READ CAPACITY failed, we may have read
+			* past the end of the disk.
+		 	*/
 			if (cmd->device->use_10_for_rw &&
 			    (cmd->cmnd[0] == READ_10 ||
 			     cmd->cmnd[0] == WRITE_10)) {
@@ -839,14 +831,23 @@
 			}
 			break;
 		case NOT_READY:
+			/*
+			 * If the device is in the process of becoming ready,
+			 * retry.
+			 */
+			if (sshdr.asc == 0x04 && sshdr.ascq == 0x01) {
+				scsi_requeue_command(q, cmd);
+				return;
+			}
 			printk(KERN_INFO "Device %s not ready.\n",
 			       req->rq_disk ? req->rq_disk->disk_name : "");
 			cmd = scsi_end_request(cmd, 0, this_count, 1);
 			return;
 		case VOLUME_OVERFLOW:
-			printk("scsi%d: ERROR on channel %d, id %d, lun %d, CDB: ",
-			       cmd->device->host->host_no, (int) cmd->device->channel,
-			       (int) cmd->device->id, (int) cmd->device->lun);
+			printk(KERN_INFO "Volume overflow <%d %d %d %d> CDB: ",
+			       cmd->device->host->host_no,
+			       (int)cmd->device->channel,
+			       (int)cmd->device->id, (int)cmd->device->lun);
 			__scsi_print_command(cmd->data_cmnd);
 			scsi_print_sense("", cmd);
 			cmd = scsi_end_request(cmd, 0, block_bytes, 1);
@@ -865,8 +866,8 @@
 		return;
 	}
 	if (result) {
-		printk("SCSI error : <%d %d %d %d> return code = 0x%x\n",
-		       cmd->device->host->host_no,
+		printk(KERN_INFO "SCSI error : <%d %d %d %d> return code "
+		       "= 0x%x\n", cmd->device->host->host_no,
 		       cmd->device->channel,
 		       cmd->device->id,
 		       cmd->device->lun, result);
@@ -884,6 +885,7 @@
 		cmd = scsi_end_request(cmd, 0, block_bytes, 1);
 	}
 }
+EXPORT_SYMBOL(scsi_io_completion);
 
 /*
  * Function:    scsi_init_io()
@@ -1344,6 +1346,7 @@
 
 	return bounce_limit;
 }
+EXPORT_SYMBOL(scsi_calculate_bounce_limit);
 
 struct request_queue *scsi_alloc_queue(struct scsi_device *sdev)
 {
@@ -1393,6 +1396,7 @@
 {
 	shost->host_self_blocked = 1;
 }
+EXPORT_SYMBOL(scsi_block_requests);
 
 /*
  * Function:    scsi_unblock_requests()
@@ -1419,6 +1423,7 @@
 	shost->host_self_blocked = 0;
 	scsi_run_host_queues(shost);
 }
+EXPORT_SYMBOL(scsi_unblock_requests);
 
 int __init scsi_init_queue(void)
 {
@@ -1553,6 +1558,7 @@
 
 	return sreq->sr_result;
 }
+EXPORT_SYMBOL(__scsi_mode_sense);
 
 /**
  *	scsi_mode_sense - issue a mode sense, falling back from 10 to 
@@ -1587,6 +1593,7 @@
 
 	return ret;
 }
+EXPORT_SYMBOL(scsi_mode_sense);
 
 int
 scsi_test_unit_ready(struct scsi_device *sdev, int timeout, int retries)
@@ -1604,12 +1611,15 @@
 	sreq->sr_data_direction = DMA_NONE;
 	scsi_wait_req(sreq, cmd, NULL, 0, timeout, retries);
 
-	if ((driver_byte(sreq->sr_result) & DRIVER_SENSE) &&
-	    ((sreq->sr_sense_buffer[2] & 0x0f) == UNIT_ATTENTION ||
-	     (sreq->sr_sense_buffer[2] & 0x0f) == NOT_READY) &&
-	    sdev->removable) {
-		sdev->changed = 1;
-		sreq->sr_result = 0;
+	if ((driver_byte(sreq->sr_result) & DRIVER_SENSE) && sdev->removable) {
+		struct scsi_sense_hdr sshdr;
+
+		if ((scsi_request_normalize_sense(sreq, &sshdr)) &&
+		    ((sshdr.sense_key == UNIT_ATTENTION) ||
+		     (sshdr.sense_key == NOT_READY))) {
+			sdev->changed = 1;
+			sreq->sr_result = 0;
+		}
 	}
 	result = sreq->sr_result;
 	scsi_release_request(sreq);
@@ -1668,6 +1678,7 @@
 		case SDEV_CREATED:
 		case SDEV_RUNNING:
 		case SDEV_QUIESCE:
+		case SDEV_BLOCK:
 			break;
 		default:
 			goto illegal;
@@ -1710,11 +1721,12 @@
 	return 0;
 
  illegal:
-	dev_printk(KERN_ERR, &sdev->sdev_gendev,
-		   "Illegal state transition %s->%s\n",
-		   scsi_device_state_name(oldstate),
-		   scsi_device_state_name(state));
-	WARN_ON(1);
+	SCSI_LOG_ERROR_RECOVERY(1, 
+				dev_printk(KERN_ERR, &sdev->sdev_gendev,
+					   "Illegal state transition %s->%s\n",
+					   scsi_device_state_name(oldstate),
+					   scsi_device_state_name(state))
+				);
 	return -EINVAL;
 }
 EXPORT_SYMBOL(scsi_device_set_state);
@@ -1768,31 +1780,29 @@
 }
 EXPORT_SYMBOL(scsi_device_resume);
 
-static int
-device_quiesce_fn(struct device *dev, void *data)
+static void
+device_quiesce_fn(struct scsi_device *sdev, void *data)
 {
-	scsi_device_quiesce(to_scsi_device(dev));
-	return 0;
+	scsi_device_quiesce(sdev);
 }
 
 void
 scsi_target_quiesce(struct scsi_target *starget)
 {
-	device_for_each_child(&starget->dev, NULL, device_quiesce_fn);
+	starget_for_each_device(starget, NULL, device_quiesce_fn);
 }
 EXPORT_SYMBOL(scsi_target_quiesce);
 
-static int
-device_resume_fn(struct device *dev, void *data)
+static void
+device_resume_fn(struct scsi_device *sdev, void *data)
 {
-	scsi_device_resume(to_scsi_device(dev));
-	return 0;
+	scsi_device_resume(sdev);
 }
 
 void
 scsi_target_resume(struct scsi_target *starget)
 {
-	device_for_each_child(&starget->dev, NULL, device_resume_fn);
+	starget_for_each_device(starget, NULL, device_resume_fn);
 }
 EXPORT_SYMBOL(scsi_target_resume);
 
diff -Nru a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h
--- a/drivers/scsi/scsi_priv.h	2005-03-01 23:39:07 -08:00
+++ b/drivers/scsi/scsi_priv.h	2005-03-01 23:39:07 -08:00
@@ -146,7 +146,7 @@
 extern int scsi_sysfs_add_host(struct Scsi_Host *);
 extern int scsi_sysfs_register(void);
 extern void scsi_sysfs_unregister(void);
-extern int scsi_sysfs_device_initialize(struct scsi_device *);
+extern void scsi_sysfs_device_initialize(struct scsi_device *);
 extern int scsi_sysfs_target_initialize(struct scsi_device *);
 extern struct scsi_transport_template blank_transport_template;
 
diff -Nru a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
--- a/drivers/scsi/scsi_scan.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/scsi/scsi_scan.c	2005-03-01 23:39:09 -08:00
@@ -39,6 +39,7 @@
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_request.h>
 #include <scsi/scsi_transport.h>
+#include <scsi/scsi_eh.h>
 
 #include "scsi_priv.h"
 #include "scsi_logging.h"
@@ -253,6 +254,8 @@
 	sdev->request_queue->queuedata = sdev;
 	scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
 
+	scsi_sysfs_device_initialize(sdev);
+
 	if (shost->hostt->slave_alloc) {
 		ret = shost->hostt->slave_alloc(sdev);
 		if (ret) {
@@ -262,19 +265,10 @@
 			 */
 			if (ret == -ENXIO)
 				display_failure_msg = 0;
-			goto out_free_queue;
+			goto out_device_destroy;
 		}
 	}
 
-	if (shost->transportt->device_setup) {
-		if (shost->transportt->device_setup(sdev))
-			goto out_cleanup_slave;
-	}
-
-	if (scsi_sysfs_device_initialize(sdev) != 0)
-		goto out_cleanup_slave;
-
-
 	/* NOTE: this target initialisation code depends critically on
 	 * lun scanning being sequential. */
 	if (scsi_sysfs_target_initialize(sdev))
@@ -287,10 +281,11 @@
 	list_del(&sdev->siblings);
 	list_del(&sdev->same_target_siblings);
 	spin_unlock_irqrestore(shost->host_lock, flags);
-out_cleanup_slave:
+
 	if (shost->hostt->slave_destroy)
 		shost->hostt->slave_destroy(sdev);
-out_free_queue:
+out_device_destroy:
+	transport_destroy_device(&sdev->sdev_gendev);
 	scsi_free_queue(sdev->request_queue);
 out_free_dev:
 	kfree(sdev);
@@ -322,6 +317,7 @@
 	int first_inquiry_len, try_inquiry_len, next_inquiry_len;
 	int response_len = 0;
 	int pass, count;
+	struct scsi_sense_hdr sshdr;
 
 	*bflags = 0;
 
@@ -357,17 +353,20 @@
 				sreq->sr_result));
 
 		if (sreq->sr_result) {
-
-			/* not-ready to ready transition or power-on - good */
-			/* dpg: bogus? INQUIRY never returns UNIT_ATTENTION */
-			/* Supposedly, but many buggy devices do so anyway. */
+			/*
+			 * not-ready to ready transition [asc/ascq=0x28/0x0]
+			 * or power-on, reset [asc/ascq=0x29/0x0], continue.
+			 * INQUIRY should not yield UNIT_ATTENTION
+			 * but many buggy devices do so anyway. 
+			 */
 			if ((driver_byte(sreq->sr_result) & DRIVER_SENSE) &&
-					(sreq->sr_sense_buffer[2] & 0xf) ==
-						UNIT_ATTENTION &&
-					(sreq->sr_sense_buffer[12] == 0x28 ||
-					 sreq->sr_sense_buffer[12] == 0x29) &&
-					sreq->sr_sense_buffer[13] == 0)
-				continue;
+			    scsi_request_normalize_sense(sreq, &sshdr)) {
+				if ((sshdr.sense_key == UNIT_ATTENTION) &&
+				    ((sshdr.asc == 0x28) ||
+				     (sshdr.asc == 0x29)) &&
+				    (sshdr.ascq == 0))
+					continue;
+			}
 		}
 		break;
 	}
@@ -621,8 +620,7 @@
 	if (*bflags & BLIST_NOT_LOCKABLE)
 		sdev->lockable = 0;
 
-	if (sdev->host->transportt->device_configure)
-		sdev->host->transportt->device_configure(sdev);
+	transport_configure_device(&sdev->sdev_gendev);
 
 	if (sdev->host->hostt->slave_configure)
 		sdev->host->hostt->slave_configure(sdev);
@@ -741,6 +739,7 @@
 	} else {
 		if (sdev->host->hostt->slave_destroy)
 			sdev->host->hostt->slave_destroy(sdev);
+		transport_destroy_device(&sdev->sdev_gendev);
 		put_device(&sdev->sdev_gendev);
 	}
  out:
@@ -893,6 +892,7 @@
 	struct scsi_lun *lunp, *lun_data;
 	struct scsi_request *sreq;
 	u8 *data;
+	struct scsi_sense_hdr sshdr;
 
 	/*
 	 * Only support SCSI-3 and up devices if BLIST_NOREPORTLUN is not set.
@@ -970,9 +970,12 @@
 				" %s (try %d) result 0x%x\n", sreq->sr_result
 				?  "failed" : "successful", retries,
 				sreq->sr_result));
-		if (sreq->sr_result == 0 ||
-		    sreq->sr_sense_buffer[2] != UNIT_ATTENTION)
+		if (sreq->sr_result == 0)
 			break;
+		else if (scsi_request_normalize_sense(sreq, &sshdr)) {
+			if (sshdr.sense_key != UNIT_ATTENTION)
+				break;
+		}
 	}
 
 	if (sreq->sr_result) {
@@ -1082,6 +1085,7 @@
 
 	return sdev;
 }
+EXPORT_SYMBOL(__scsi_add_device);
 
 void scsi_rescan_device(struct device *dev)
 {
@@ -1097,6 +1101,7 @@
 		module_put(drv->owner);
 	}
 }
+EXPORT_SYMBOL(scsi_rescan_device);
 
 /**
  * scsi_scan_target - scan a target id, possibly including all LUNs on the
@@ -1225,6 +1230,20 @@
 	scsi_scan_host_selected(shost, SCAN_WILD_CARD, SCAN_WILD_CARD,
 				SCAN_WILD_CARD, 0);
 }
+EXPORT_SYMBOL(scsi_scan_host);
+
+/**
+ * scsi_scan_single_target - scan the given SCSI target
+ * @shost:         adapter to scan
+ * @chan:          channel to scan
+ * @id:            target id to scan
+ **/
+void scsi_scan_single_target(struct Scsi_Host *shost, 
+	unsigned int chan, unsigned int id)
+{
+	scsi_scan_host_selected(shost, chan, id, SCAN_WILD_CARD, 1);
+}
+EXPORT_SYMBOL(scsi_scan_single_target);
 
 void scsi_forget_host(struct Scsi_Host *shost)
 {
@@ -1279,6 +1298,7 @@
 	}
 	return sdev;
 }
+EXPORT_SYMBOL(scsi_get_host_dev);
 
 /*
  * Function:    scsi_free_host_dev()
@@ -1299,5 +1319,8 @@
 
 	if (sdev->host->hostt->slave_destroy)
 		sdev->host->hostt->slave_destroy(sdev);
+	transport_destroy_device(&sdev->sdev_gendev);
 	put_device(&sdev->sdev_gendev);
 }
+EXPORT_SYMBOL(scsi_free_host_dev);
+
diff -Nru a/drivers/scsi/scsi_syms.c b/drivers/scsi/scsi_syms.c
--- a/drivers/scsi/scsi_syms.c	2005-03-01 23:38:57 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,97 +0,0 @@
-/*
- * We should not even be trying to compile this if we are not doing
- * a module.
- */
-#include <linux/config.h>
-#include <linux/module.h>
-
-#include <scsi/scsi.h>
-#include <scsi/scsi_dbg.h>
-#include <scsi/scsi_device.h>
-#include <scsi/scsi_driver.h>
-#include <scsi/scsi_eh.h>
-#include <scsi/scsi_host.h>
-#include <scsi/scsi_ioctl.h>
-#include <scsi/scsi_request.h>
-#include <scsi/scsicam.h>
-
-#include "scsi_logging.h"
-
-
-/*
- * This source file contains the symbol table used by scsi loadable
- * modules.
- */
-EXPORT_SYMBOL(scsi_register_driver);
-EXPORT_SYMBOL(scsi_register_interface);
-EXPORT_SYMBOL(scsi_host_alloc);
-EXPORT_SYMBOL(scsi_add_host);
-EXPORT_SYMBOL(scsi_scan_host);
-EXPORT_SYMBOL(scsi_remove_host);
-EXPORT_SYMBOL(scsi_host_get);
-EXPORT_SYMBOL(scsi_host_put);
-EXPORT_SYMBOL(scsi_host_lookup);
-EXPORT_SYMBOL(scsi_register);
-EXPORT_SYMBOL(scsi_unregister);
-EXPORT_SYMBOL(scsicam_bios_param);
-EXPORT_SYMBOL(scsi_partsize);
-EXPORT_SYMBOL(scsi_bios_ptable);
-EXPORT_SYMBOL(scsi_ioctl);
-EXPORT_SYMBOL(scsi_print_command);
-EXPORT_SYMBOL(__scsi_print_command);
-EXPORT_SYMBOL(scsi_print_sense);
-EXPORT_SYMBOL(scsi_print_req_sense);
-EXPORT_SYMBOL(scsi_print_msg);
-EXPORT_SYMBOL(scsi_print_status);
-EXPORT_SYMBOL(scsi_sense_key_string);
-EXPORT_SYMBOL(scsi_extd_sense_format);
-EXPORT_SYMBOL(scsi_block_when_processing_errors);
-EXPORT_SYMBOL(scsi_ioctl_send_command);
-EXPORT_SYMBOL(scsi_set_medium_removal);
-#if defined(CONFIG_SCSI_LOGGING)	/* { */
-EXPORT_SYMBOL(scsi_logging_level);
-#endif
-
-EXPORT_SYMBOL(scsi_allocate_request);
-EXPORT_SYMBOL(scsi_release_request);
-EXPORT_SYMBOL(scsi_wait_req);
-EXPORT_SYMBOL(scsi_do_req);
-EXPORT_SYMBOL(scsi_get_command);
-EXPORT_SYMBOL(scsi_put_command);
-
-EXPORT_SYMBOL(scsi_report_bus_reset);
-EXPORT_SYMBOL(scsi_report_device_reset);
-EXPORT_SYMBOL(scsi_block_requests);
-EXPORT_SYMBOL(scsi_unblock_requests);
-EXPORT_SYMBOL(scsi_adjust_queue_depth);
-EXPORT_SYMBOL(scsi_track_queue_full);
-
-EXPORT_SYMBOL(scsi_get_host_dev);
-EXPORT_SYMBOL(scsi_free_host_dev);
-
-EXPORT_SYMBOL(scsi_io_completion);
-
-EXPORT_SYMBOL(__scsi_add_device);
-EXPORT_SYMBOL(scsi_remove_device);
-EXPORT_SYMBOL(scsi_device_cancel);
-
-EXPORT_SYMBOL(__scsi_mode_sense);
-EXPORT_SYMBOL(scsi_mode_sense);
-
-/*
- * This symbol is for the highlevel drivers (e.g. sg) only.
- */
-EXPORT_SYMBOL(scsi_reset_provider);
-
-EXPORT_SYMBOL(scsi_device_types);
-
-/*
- * This is for st to find the bounce limit
- */
-EXPORT_SYMBOL(scsi_calculate_bounce_limit);
-
-/*
- * Externalize timers so that HBAs can safely start/restart commands.
- */
-EXPORT_SYMBOL(scsi_add_timer);
-EXPORT_SYMBOL(scsi_delete_timer);
diff -Nru a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
--- a/drivers/scsi/scsi_sysfs.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/scsi/scsi_sysfs.c	2005-03-01 23:38:53 -08:00
@@ -15,6 +15,7 @@
 #include <scsi/scsi.h>
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_host.h>
+#include <scsi/scsi_tcq.h>
 #include <scsi/scsi_transport.h>
 
 #include "scsi_priv.h"
@@ -170,10 +171,11 @@
 	if (delete) {
 		struct scsi_target *starget = to_scsi_target(parent);
 		if (!starget->create) {
+			transport_remove_device(&starget->dev);
 			device_del(parent);
-			if (starget->transport_classdev.class)
-				class_device_unregister(&starget->transport_classdev);
 		}
+		transport_destroy_device(&starget->dev);
+
 		put_device(parent);
 	}
 	if (sdev->request_queue)
@@ -388,13 +390,30 @@
 	return snprintf(buf, 20, "%s\n", name);
 }
 
-DEVICE_ATTR(state, S_IRUGO | S_IWUSR, show_state_field, store_state_field);
+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)
+{
+	struct scsi_device *sdev = to_scsi_device(dev);
+	const char *name = "none";
+
+	if (sdev->ordered_tags)
+		name = "ordered";
+	else if (sdev->simple_tags)
+		name = "simple";
+
+	return snprintf(buf, 20, "%s\n", name);
+}
+
+static DEVICE_ATTR(queue_type, S_IRUGO, show_queue_type_field, NULL);
 
 
 /* Default template for device attributes.  May NOT be modified */
 static struct device_attribute *scsi_sysfs_sdev_attrs[] = {
 	&dev_attr_device_blocked,
 	&dev_attr_queue_depth,
+	&dev_attr_queue_type,
 	&dev_attr_type,
 	&dev_attr_scsi_level,
 	&dev_attr_vendor,
@@ -407,6 +426,77 @@
 	NULL
 };
 
+static ssize_t sdev_store_queue_depth_rw(struct device *dev, const char *buf,
+					 size_t count)
+{
+	int depth, retval;
+	struct scsi_device *sdev = to_scsi_device(dev);
+	struct scsi_host_template *sht = sdev->host->hostt;
+
+	if (!sht->change_queue_depth)
+		return -EINVAL;
+
+	depth = simple_strtoul(buf, NULL, 0);
+
+	if (depth < 1)
+		return -EINVAL;
+
+	retval = sht->change_queue_depth(sdev, depth);
+	if (retval < 0)
+		return retval;
+
+	return count;
+}
+
+static struct device_attribute sdev_attr_queue_depth_rw =
+	__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,
+					size_t count)
+{
+	struct scsi_device *sdev = to_scsi_device(dev);
+	struct scsi_host_template *sht = sdev->host->hostt;
+	int tag_type = 0, retval;
+	int prev_tag_type = scsi_get_tag_type(sdev);
+
+	if (!sdev->tagged_supported || !sht->change_queue_type)
+		return -EINVAL;
+
+	if (strncmp(buf, "ordered", 7) == 0)
+		tag_type = MSG_ORDERED_TAG;
+	else if (strncmp(buf, "simple", 6) == 0)
+		tag_type = MSG_SIMPLE_TAG;
+	else if (strncmp(buf, "none", 4) != 0)
+		return -EINVAL;
+
+	if (tag_type == prev_tag_type)
+		return count;
+
+	retval = sht->change_queue_type(sdev, tag_type);
+	if (retval < 0)
+		return retval;
+
+	return count;
+}
+
+static struct device_attribute sdev_attr_queue_type_rw =
+	__ATTR(queue_type, S_IRUGO | S_IWUSR, show_queue_type_field,
+	       sdev_store_queue_type_rw);
+
+static struct device_attribute *attr_changed_internally(
+		struct Scsi_Host *shost,
+		struct device_attribute * attr)
+{
+	if (!strcmp("queue_depth", attr->attr.name)
+	    && shost->hostt->change_queue_depth)
+		return &sdev_attr_queue_depth_rw;
+	else if (!strcmp("queue_type", attr->attr.name)
+	    && shost->hostt->change_queue_type)
+		return &sdev_attr_queue_type_rw;
+	return attr;
+}
+
 
 static struct device_attribute *attr_overridden(
 		struct device_attribute **attrs,
@@ -461,7 +551,6 @@
  **/
 int scsi_sysfs_add_sdev(struct scsi_device *sdev)
 {
-	struct class_device_attribute **attrs;
 	struct scsi_target *starget = sdev->sdev_target;
 	struct Scsi_Host *shost = sdev->host;
 	int error, i, create;
@@ -478,31 +567,7 @@
 			printk(KERN_ERR "Target device_add failed\n");
 			return error;
 		}
-		if (starget->transport_classdev.class) {
-			int i;
-			struct class_device_attribute **attrs =
-				sdev->host->transportt->target_attrs;
-
-			error = class_device_add(&starget->transport_classdev);
-			if (error) {
-				dev_printk(KERN_ERR, &starget->dev,
-					   "Target transport add failed\n");
-				return error;
-			}
-
-			/* take a reference for the transport_classdev; this
-			 * is released by the transport_class .release */
-			get_device(&starget->dev);
-			for (i = 0; attrs[i]; i++) {
-				error = class_device_create_file(&starget->transport_classdev,
-								 attrs[i]);
-				if (error) {
-					dev_printk(KERN_ERR, &starget->dev,
-						   "Target transport attr add failed\n");
-					return error;
-				}
-			}
-		}
+		transport_add_device(&starget->dev);
 	}
 
 	if ((error = scsi_device_set_state(sdev, SDEV_RUNNING)) != 0)
@@ -514,25 +579,15 @@
 		printk(KERN_INFO "error 1\n");
 		return error;
 	}
-
 	error = class_device_add(&sdev->sdev_classdev);
 	if (error) {
 		printk(KERN_INFO "error 2\n");
 		goto clean_device;
 	}
+
 	/* take a reference for the sdev_classdev; this is
 	 * released by the sdev_class .release */
 	get_device(&sdev->sdev_gendev);
-	if (sdev->transport_classdev.class) {
-		error = class_device_add(&sdev->transport_classdev);
-		if (error)
-			goto clean_device2;
-		/* take a reference for the transport_classdev; this
-		 * is released by the transport_class .release */
-		get_device(&sdev->sdev_gendev);
-		
-	}
-
 	if (sdev->host->hostt->sdev_attrs) {
 		for (i = 0; sdev->host->hostt->sdev_attrs[i]; i++) {
 			error = attr_add(&sdev->sdev_gendev,
@@ -547,8 +602,10 @@
 	for (i = 0; scsi_sysfs_sdev_attrs[i]; i++) {
 		if (!attr_overridden(sdev->host->hostt->sdev_attrs,
 					scsi_sysfs_sdev_attrs[i])) {
-			error = device_create_file(&sdev->sdev_gendev,
-					scsi_sysfs_sdev_attrs[i]);
+			struct device_attribute * attr = 
+				attr_changed_internally(sdev->host, 
+							scsi_sysfs_sdev_attrs[i]);
+			error = device_create_file(&sdev->sdev_gendev, attr);
 			if (error) {
 				scsi_remove_device(sdev);
 				goto out;
@@ -556,27 +613,16 @@
 		}
 	}
 
- 	if (sdev->transport_classdev.class) {
- 		attrs = sdev->host->transportt->device_attrs;
- 		for (i = 0; attrs[i]; i++) {
- 			error = class_device_create_file(&sdev->transport_classdev,
- 							 attrs[i]);
- 			if (error) {
- 				scsi_remove_device(sdev);
-				goto out;
-			}
- 		}
- 	}
-
+	transport_add_device(&sdev->sdev_gendev);
  out:
 	return error;
 
- clean_device2:
 	class_device_del(&sdev->sdev_classdev);
  clean_device:
 	scsi_device_set_state(sdev, SDEV_CANCEL);
 
 	device_del(&sdev->sdev_gendev);
+	transport_destroy_device(&sdev->sdev_gendev);
 	put_device(&sdev->sdev_gendev);
 
 	return error;
@@ -595,17 +641,17 @@
 		goto out;
 
 	class_device_unregister(&sdev->sdev_classdev);
-	if (sdev->transport_classdev.class)
-		class_device_unregister(&sdev->transport_classdev);
 	device_del(&sdev->sdev_gendev);
 	scsi_device_set_state(sdev, SDEV_DEL);
 	if (sdev->host->hostt->slave_destroy)
 		sdev->host->hostt->slave_destroy(sdev);
+	transport_unregister_device(&sdev->sdev_gendev);
 	put_device(&sdev->sdev_gendev);
 
 out:
 	up(&shost->scan_mutex);
 }
+EXPORT_SYMBOL(scsi_remove_device);
 
 int scsi_register_driver(struct device_driver *drv)
 {
@@ -613,6 +659,7 @@
 
 	return driver_register(drv);
 }
+EXPORT_SYMBOL(scsi_register_driver);
 
 int scsi_register_interface(struct class_interface *intf)
 {
@@ -620,6 +667,7 @@
 
 	return class_interface_register(intf);
 }
+EXPORT_SYMBOL(scsi_register_interface);
 
 
 static struct class_device_attribute *class_attr_overridden(
@@ -687,33 +735,11 @@
 		}
 	}
 
-	class_device_initialize(&shost->transport_classdev);
-	shost->transport_classdev.class = shost->transportt->host_class;
-	shost->transport_classdev.dev = &shost->shost_gendev;
-	snprintf(shost->transport_classdev.class_id, BUS_ID_SIZE,
-		 "host%d", shost->host_no);
-
-	if (shost->transport_classdev.class) {
-		struct class_device_attribute **attrs =
-			shost->transportt->host_attrs;
-		error = class_device_add(&shost->transport_classdev);
-		if (error)
-			return error;
-		/* take a reference for the transport_classdev; this
-		 * is released by the transport_class .release */
-		get_device(&shost->shost_gendev);
-		for (i = 0; attrs[i]; i++) {
- 			error = class_device_create_file(&shost->transport_classdev,
- 							 attrs[i]);
- 			if (error)
-				return error;
- 		}
- 	}
-
+	transport_register_device(&shost->shost_gendev);
 	return 0;
 }
 
-int scsi_sysfs_device_initialize(struct scsi_device *sdev)
+void scsi_sysfs_device_initialize(struct scsi_device *sdev)
 {
 	device_initialize(&sdev->sdev_gendev);
 	sdev->sdev_gendev.bus = &scsi_bus_type;
@@ -729,14 +755,14 @@
 		 "%d:%d:%d:%d", sdev->host->host_no,
 		 sdev->channel, sdev->id, sdev->lun);
 
-	class_device_initialize(&sdev->transport_classdev);
-	sdev->transport_classdev.dev = &sdev->sdev_gendev;
-	sdev->transport_classdev.class = sdev->host->transportt->device_class;
-	snprintf(sdev->transport_classdev.class_id, BUS_ID_SIZE,
-		 "%d:%d:%d:%d", sdev->host->host_no,
-		 sdev->channel, sdev->id, sdev->lun);
-	return 0;
+	transport_setup_device(&sdev->sdev_gendev);
+}
+
+int scsi_is_sdev_device(const struct device *dev)
+{
+	return dev->release == scsi_device_dev_release;
 }
+EXPORT_SYMBOL(scsi_is_sdev_device);
 
 int scsi_sysfs_target_initialize(struct scsi_device *sdev)
 {
@@ -779,12 +805,6 @@
 		dev->release = scsi_target_dev_release;
 		sprintf(dev->bus_id, "target%d:%d:%d",
 			shost->host_no, sdev->channel, sdev->id);
-		class_device_initialize(&starget->transport_classdev);
-		starget->transport_classdev.dev = &starget->dev;
-		starget->transport_classdev.class = shost->transportt->target_class;
-		snprintf(starget->transport_classdev.class_id, BUS_ID_SIZE,
-			 "target%d:%d:%d",
-			 shost->host_no, sdev->channel, sdev->id);
 		starget->id = sdev->id;
 		starget->channel = sdev->channel;
 		create = starget->create = 1;
@@ -800,10 +820,16 @@
 	sdev->sdev_target = starget;
 	list_add_tail(&sdev->siblings, &shost->__devices);
 	spin_unlock_irqrestore(shost->host_lock, flags);
-	if (create && shost->transportt->target_setup)
-		shost->transportt->target_setup(starget);
+	if (create)
+		transport_setup_device(&starget->dev);
 	return 0;
 }
+
+int scsi_is_target_device(const struct device *dev)
+{
+	return dev->release == scsi_target_dev_release;
+}
+EXPORT_SYMBOL(scsi_is_target_device);
 
 /* A blank transport template that is used in drivers that don't
  * yet implement Transport Attributes */
diff -Nru a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
--- a/drivers/scsi/scsi_transport_fc.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/scsi/scsi_transport_fc.c	2005-03-01 23:38:52 -08:00
@@ -27,13 +27,166 @@
 
 #define FC_PRINTK(x, l, f, a...)	printk(l "scsi(%d:%d:%d:%d): " f, (x)->host->host_no, (x)->channel, (x)->id, (x)->lun , ##a)
 
-static void transport_class_release(struct class_device *class_dev);
-static void host_class_release(struct class_device *class_dev);
+/*
+ * Redefine so that we can have same named attributes in the
+ * sdev/starget/host objects.
+ */
+#define FC_CLASS_DEVICE_ATTR(_prefix,_name,_mode,_show,_store)		\
+struct class_device_attribute class_device_attr_##_prefix##_##_name = 	\
+	__ATTR(_name,_mode,_show,_store)
+
+#define fc_enum_name_search(title, table_type, table)			\
+static const char *get_fc_##title##_name(enum table_type table_key)	\
+{									\
+	int i;								\
+	char *name = NULL;						\
+									\
+	for (i = 0; i < sizeof(table)/sizeof(table[0]); i++) {		\
+		if (table[i].value == table_key) {			\
+			name = table[i].name;				\
+			break;						\
+		}							\
+	}								\
+	return name;							\
+}
+
+#define fc_enum_name_match(title, table_type, table)			\
+static int get_fc_##title##_match(const char *table_key,		\
+		enum table_type *value)					\
+{									\
+	int i;								\
+									\
+	for (i = 0; i < sizeof(table)/sizeof(table[0]); i++) {		\
+		if (strncmp(table_key, table[i].name,			\
+				table[i].matchlen) == 0) {		\
+			*value = table[i].value;			\
+			return 0; /* success */				\
+		}							\
+	}								\
+	return 1; /* failure */						\
+}
+
+
+/* Convert fc_port_type values to ascii string name */
+static struct {
+	enum fc_port_type	value;
+	char			*name;
+} fc_port_type_names[] = {
+	{ FC_PORTTYPE_UNKNOWN,		"Unknown" },
+	{ FC_PORTTYPE_OTHER,		"Other" },
+	{ FC_PORTTYPE_NOTPRESENT,	"Not Present" },
+	{ FC_PORTTYPE_NPORT,	"NPort (fabric via point-to-point)" },
+	{ FC_PORTTYPE_NLPORT,	"NLPort (fabric via loop)" },
+	{ FC_PORTTYPE_LPORT,	"LPort (private loop)" },
+	{ FC_PORTTYPE_PTP,	"Point-To-Point (direct nport connection" },
+};
+fc_enum_name_search(port_type, fc_port_type, fc_port_type_names)
+#define FC_PORTTYPE_MAX_NAMELEN		50
+
+
+/* Convert fc_port_state values to ascii string name */
+static struct {
+	enum fc_port_state	value;
+	char			*name;
+} fc_port_state_names[] = {
+	{ FC_PORTSTATE_UNKNOWN,		"Unknown" },
+	{ FC_PORTSTATE_ONLINE,		"Online" },
+	{ FC_PORTSTATE_OFFLINE,		"Offline" },
+	{ FC_PORTSTATE_BYPASSED,	"Bypassed" },
+	{ FC_PORTSTATE_DIAGNOSTICS,	"Diagnostics" },
+	{ FC_PORTSTATE_LINKDOWN,	"Linkdown" },
+	{ FC_PORTSTATE_ERROR,		"Error" },
+	{ FC_PORTSTATE_LOOPBACK,	"Loopback" },
+};
+fc_enum_name_search(port_state, fc_port_state, fc_port_state_names)
+#define FC_PORTSTATE_MAX_NAMELEN	20
+
+
+/* Convert fc_tgtid_binding_type values to ascii string name */
+static struct {
+	enum fc_tgtid_binding_type	value;
+	char				*name;
+	int				matchlen;
+} fc_tgtid_binding_type_names[] = {
+	{ FC_TGTID_BIND_BY_WWPN, "wwpn (World Wide Port Name)", 4 },
+	{ FC_TGTID_BIND_BY_WWNN, "wwnn (World Wide Node Name)", 4 },
+	{ FC_TGTID_BIND_BY_ID, "fcportid (FC Address)", 8 },
+};
+fc_enum_name_search(tgtid_bind_type, fc_tgtid_binding_type,
+		fc_tgtid_binding_type_names)
+fc_enum_name_match(tgtid_bind_type, fc_tgtid_binding_type,
+		fc_tgtid_binding_type_names)
+#define FC_BINDTYPE_MAX_NAMELEN	30
+
+
+#define fc_bitfield_name_search(title, table)			\
+static ssize_t							\
+get_fc_##title##_names(u32 table_key, char *buf)		\
+{								\
+	char *prefix = "";					\
+	ssize_t len = 0;					\
+	int i;							\
+								\
+	for (i = 0; i < sizeof(table)/sizeof(table[0]); i++) {	\
+		if (table[i].value & table_key) {		\
+			len += sprintf(buf + len, "%s%s",	\
+				prefix, table[i].name);		\
+			prefix = ", ";				\
+		}						\
+	}							\
+	len += sprintf(buf + len, "\n");			\
+	return len;						\
+}
+
+
+/* Convert fc_cos bit values to ascii string name */
+static struct {
+	u32 			value;
+	char			*name;
+} fc_cos_names[] = {
+	{ FC_COS_CLASS1,	"Class 1" },
+	{ FC_COS_CLASS2,	"Class 2" },
+	{ FC_COS_CLASS3,	"Class 3" },
+	{ FC_COS_CLASS4,	"Class 4" },
+	{ FC_COS_CLASS6,	"Class 6" },
+};
+fc_bitfield_name_search(cos, fc_cos_names)
+
+
+/* Convert fc_port_speed bit values to ascii string name */
+static struct {
+	u32 			value;
+	char			*name;
+} fc_port_speed_names[] = {
+	{ FC_PORTSPEED_1GBIT,		"1 Gbit" },
+	{ FC_PORTSPEED_2GBIT,		"2 Gbit" },
+	{ FC_PORTSPEED_4GBIT,		"4 Gbit" },
+	{ FC_PORTSPEED_10GBIT,		"10 Gbit" },
+	{ FC_PORTSPEED_NOT_NEGOTIATED,	"Not Negotiated" },
+};
+fc_bitfield_name_search(port_speed, fc_port_speed_names)
+
+
+static int
+show_fc_fc4s (char *buf, u8 *fc4_list)
+{
+	int i, len=0;
+
+	for (i = 0; i < FC_FC4_LIST_SIZE; i++, fc4_list++)
+		len += sprintf(buf + len , "0x%02x ", *fc4_list);
+	len += sprintf(buf + len, "\n");
+	return len;
+}
+
+
+
+static void fc_timeout_blocked_host(void *data);
+static void fc_timeout_blocked_tgt(void *data);
 
 #define FC_STARGET_NUM_ATTRS 	4	/* increase this if you add attributes */
 #define FC_STARGET_OTHER_ATTRS 	0	/* increase this if you add "always on"
 					 * attributes */
-#define FC_HOST_NUM_ATTRS	1
+#define FC_HOST_NUM_ATTRS	15
 
 struct fc_internal {
 	struct scsi_transport_template t;
@@ -52,32 +205,9 @@
 
 #define to_fc_internal(tmpl)	container_of(tmpl, struct fc_internal, t)
 
-struct class fc_transport_class = {
-	.name = "fc_transport",
-	.release = transport_class_release,
-};
-
-struct class fc_host_class = {
-	.name = "fc_host",
-	.release = host_class_release,
-};
-
-static __init int fc_transport_init(void)
-{
-	int error = class_register(&fc_host_class);
-	if (error)
-		return error;
-	return class_register(&fc_transport_class);
-}
-
-static void __exit fc_transport_exit(void)
-{
-	class_unregister(&fc_transport_class);
-	class_unregister(&fc_host_class);
-}
-
-static int fc_setup_starget_transport_attrs(struct scsi_target *starget)
+static int fc_add_target(struct device *dev)
 {
+	struct scsi_target *starget = to_scsi_target(dev);
 	/* 
 	 * Set default values easily detected by the midlayer as
 	 * failure cases.  The scsi lldd is responsible for initializing
@@ -87,37 +217,101 @@
 	fc_starget_port_name(starget) = -1;
 	fc_starget_port_id(starget) = -1;
 	fc_starget_dev_loss_tmo(starget) = -1;
-	init_timer(&fc_starget_dev_loss_timer(starget));
+	INIT_WORK(&fc_starget_dev_loss_work(starget),
+		  fc_timeout_blocked_tgt, starget);
 	return 0;
 }
 
-static int fc_setup_host_transport_attrs(struct Scsi_Host *shost)
+static int fc_remove_target(struct device *dev)
+{
+	struct scsi_target *starget = to_scsi_target(dev);
+	/* Stop the target timer */
+	if (cancel_delayed_work(&fc_starget_dev_loss_work(starget)))
+		flush_scheduled_work();
+	return 0;
+}
+
+static DECLARE_TRANSPORT_CLASS(fc_transport_class,
+			       "fc_transport",
+			       fc_add_target,
+			       fc_remove_target,
+			       NULL);
+
+static int fc_add_host(struct device *dev)
 {
+	struct Scsi_Host *shost = dev_to_shost(dev);
 	/* 
 	 * Set default values easily detected by the midlayer as
 	 * failure cases.  The scsi lldd is responsible for initializing
 	 * all transport attributes to valid values per host.
 	 */
-	fc_host_link_down_tmo(shost) = -1;
-	init_timer(&fc_host_link_down_timer(shost));
+	fc_host_node_name(shost) = -1;
+	fc_host_port_name(shost) = -1;
+	fc_host_supported_classes(shost) = FC_COS_UNSPECIFIED;
+	memset(fc_host_supported_fc4s(shost), 0,
+		sizeof(fc_host_supported_fc4s(shost)));
+	memset(fc_host_symbolic_name(shost), 0,
+		sizeof(fc_host_symbolic_name(shost)));
+	fc_host_supported_speeds(shost) = FC_PORTSPEED_UNKNOWN;
+	fc_host_maxframe_size(shost) = -1;
+	memset(fc_host_hardware_version(shost), 0,
+		sizeof(fc_host_hardware_version(shost)));
+	memset(fc_host_firmware_version(shost), 0,
+		sizeof(fc_host_firmware_version(shost)));
+	memset(fc_host_serial_number(shost), 0,
+		sizeof(fc_host_serial_number(shost)));
+	memset(fc_host_opt_rom_version(shost), 0,
+		sizeof(fc_host_opt_rom_version(shost)));
+	memset(fc_host_driver_version(shost), 0,
+		sizeof(fc_host_driver_version(shost)));
+
+	fc_host_port_id(shost) = -1;
+	fc_host_port_type(shost) = FC_PORTTYPE_UNKNOWN;
+	fc_host_port_state(shost) = FC_PORTSTATE_UNKNOWN;
+	memset(fc_host_active_fc4s(shost), 0,
+		sizeof(fc_host_active_fc4s(shost)));
+	fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;
+	fc_host_fabric_name(shost) = -1;
+ 	fc_host_link_down_tmo(shost) = -1;
+
+	fc_host_tgtid_bind_type(shost) = FC_TGTID_BIND_BY_WWPN;
+
+	INIT_WORK(&fc_host_link_down_work(shost),
+		  fc_timeout_blocked_host, shost);
 	return 0;
 }
 
-static void transport_class_release(struct class_device *class_dev)
+static int fc_remove_host(struct device *dev)
 {
-	struct scsi_target *starget = transport_class_to_starget(class_dev);
-	put_device(&starget->dev);
+	struct Scsi_Host *shost = dev_to_shost(dev);
+	/* Stop the host timer */
+	if (cancel_delayed_work(&fc_host_link_down_work(shost)))
+		flush_scheduled_work();
+	return 0;
 }
 
-static void host_class_release(struct class_device *class_dev)
+static DECLARE_TRANSPORT_CLASS(fc_host_class,
+			       "fc_host",
+			       fc_add_host,
+			       fc_remove_host,
+			       NULL);
+
+static __init int fc_transport_init(void)
 {
-	struct Scsi_Host *shost = transport_class_to_shost(class_dev);
-	put_device(&shost->shost_gendev);
+	int error = transport_class_register(&fc_host_class);
+	if (error)
+		return error;
+	return transport_class_register(&fc_transport_class);
 }
 
+static void __exit fc_transport_exit(void)
+{
+	transport_class_unregister(&fc_transport_class);
+	transport_class_unregister(&fc_host_class);
+}
 
 /*
- * Remote Port Attribute Management
+ * Remote Port (Target) Attribute Management
  */
 
 #define fc_starget_show_function(field, format_string, cast)		\
@@ -126,12 +320,11 @@
 {									\
 	struct scsi_target *starget = transport_class_to_starget(cdev);	\
 	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);	\
-	struct fc_starget_attrs *tp;					\
 	struct fc_internal *i = to_fc_internal(shost->transportt);	\
-	tp = (struct fc_starget_attrs *)&starget->starget_data;		\
 	if (i->f->get_starget_##field)					\
 		i->f->get_starget_##field(starget);			\
-	return snprintf(buf, 20, format_string, cast tp->field);	\
+	return snprintf(buf, 20, format_string, 			\
+		cast fc_starget_##field(starget)); 			\
 }
 
 #define fc_starget_store_function(field, format_string)			\
@@ -151,23 +344,23 @@
 
 #define fc_starget_rd_attr(field, format_string)			\
 	fc_starget_show_function(field, format_string, )		\
-static CLASS_DEVICE_ATTR(field, S_IRUGO,				\
+static FC_CLASS_DEVICE_ATTR(starget, field, S_IRUGO,			\
 			 show_fc_starget_##field, NULL)
 
 #define fc_starget_rd_attr_cast(field, format_string, cast)		\
 	fc_starget_show_function(field, format_string, (cast))		\
-static CLASS_DEVICE_ATTR(field, S_IRUGO,				\
+static FC_CLASS_DEVICE_ATTR(starget, field, S_IRUGO,			\
 			  show_fc_starget_##field, NULL)
 
 #define fc_starget_rw_attr(field, format_string)			\
 	fc_starget_show_function(field, format_string, )		\
 	fc_starget_store_function(field, format_string)			\
-static CLASS_DEVICE_ATTR(field, S_IRUGO | S_IWUSR,			\
+static FC_CLASS_DEVICE_ATTR(starget, field, S_IRUGO | S_IWUSR,		\
 			show_fc_starget_##field,			\
 			store_fc_starget_##field)
 
 #define SETUP_STARGET_ATTRIBUTE_RD(field)				\
-	i->private_starget_attrs[count] = class_device_attr_##field;	\
+	i->private_starget_attrs[count] = class_device_attr_starget_##field; \
 	i->private_starget_attrs[count].attr.mode = S_IRUGO;		\
 	i->private_starget_attrs[count].store = NULL;			\
 	i->starget_attrs[count] = &i->private_starget_attrs[count];	\
@@ -175,7 +368,7 @@
 		count++
 
 #define SETUP_STARGET_ATTRIBUTE_RW(field)				\
-	i->private_starget_attrs[count] = class_device_attr_##field;	\
+	i->private_starget_attrs[count] = class_device_attr_starget_##field; \
 	if (!i->f->set_starget_##field) {				\
 		i->private_starget_attrs[count].attr.mode = S_IRUGO;	\
 		i->private_starget_attrs[count].store = NULL;		\
@@ -191,21 +384,20 @@
 fc_starget_rw_attr(dev_loss_tmo, "%d\n");
 
 
+
 /*
  * Host Attribute Management
  */
 
-#define fc_host_show_function(field, format_string, cast)		\
+#define fc_host_show_function(field, format_string, sz, cast)		\
 static ssize_t								\
 show_fc_host_##field (struct class_device *cdev, char *buf)		\
 {									\
 	struct Scsi_Host *shost = transport_class_to_shost(cdev);	\
-	struct fc_host_attrs *tp;					\
 	struct fc_internal *i = to_fc_internal(shost->transportt);	\
-	tp = (struct fc_host_attrs *)shost->shost_data;		\
 	if (i->f->get_host_##field)					\
 		i->f->get_host_##field(shost);				\
-	return snprintf(buf, 20, format_string, cast tp->field);	\
+	return snprintf(buf, sz, format_string, cast fc_host_##field(shost)); \
 }
 
 #define fc_host_store_function(field, format_string)			\
@@ -222,23 +414,39 @@
 	return count;							\
 }
 
-#define fc_host_rd_attr(field, format_string)				\
-	fc_host_show_function(field, format_string, )			\
-static CLASS_DEVICE_ATTR(host_##field, S_IRUGO,				\
+#define fc_host_rd_attr(field, format_string, sz)			\
+	fc_host_show_function(field, format_string, sz, )		\
+static FC_CLASS_DEVICE_ATTR(host, field, S_IRUGO,			\
 			 show_fc_host_##field, NULL)
 
-#define fc_host_rd_attr_cast(field, format_string, cast)		\
-	fc_host_show_function(field, format_string, (cast))		\
-static CLASS_DEVICE_ATTR(host_##field, S_IRUGO,				\
+#define fc_host_rd_attr_cast(field, format_string, sz, cast)		\
+	fc_host_show_function(field, format_string, sz, (cast))		\
+static FC_CLASS_DEVICE_ATTR(host, field, S_IRUGO,			\
 			  show_fc_host_##field, NULL)
 
-#define fc_host_rw_attr(field, format_string)				\
-	fc_host_show_function(field, format_string, )			\
+#define fc_host_rw_attr(field, format_string, sz)			\
+	fc_host_show_function(field, format_string, sz, )		\
 	fc_host_store_function(field, format_string)			\
-static CLASS_DEVICE_ATTR(host_##field, S_IRUGO | S_IWUSR,		\
+static FC_CLASS_DEVICE_ATTR(host, field, S_IRUGO | S_IWUSR,		\
 			show_fc_host_##field,				\
 			store_fc_host_##field)
 
+#define fc_host_rd_enum_attr(title, maxlen)				\
+static ssize_t								\
+show_fc_host_##title (struct class_device *cdev, char *buf)		\
+{									\
+	struct Scsi_Host *shost = transport_class_to_shost(cdev);	\
+	struct fc_internal *i = to_fc_internal(shost->transportt);	\
+	const char *name;						\
+	if (i->f->get_host_##title)					\
+		i->f->get_host_##title(shost);				\
+	name = get_fc_##title##_name(fc_host_##title(shost));		\
+	if (!name)							\
+		return -EINVAL;						\
+	return snprintf(buf, maxlen, "%s\n", name);			\
+}									\
+static FC_CLASS_DEVICE_ATTR(host, title, S_IRUGO, show_fc_host_##title, NULL)
+
 #define SETUP_HOST_ATTRIBUTE_RD(field)					\
 	i->private_host_attrs[count] = class_device_attr_host_##field;	\
 	i->private_host_attrs[count].attr.mode = S_IRUGO;		\
@@ -257,9 +465,302 @@
 	if (i->f->show_host_##field)					\
 		count++
 
-/* The FC Tranport Host Attributes: */
-fc_host_rw_attr(link_down_tmo, "%d\n");
 
+#define fc_private_host_show_function(field, format_string, sz, cast)	\
+static ssize_t								\
+show_fc_host_##field (struct class_device *cdev, char *buf)		\
+{									\
+	struct Scsi_Host *shost = transport_class_to_shost(cdev);	\
+	return snprintf(buf, sz, format_string, cast fc_host_##field(shost)); \
+}
+
+#define fc_private_host_rd_attr(field, format_string, sz)		\
+	fc_private_host_show_function(field, format_string, sz, )	\
+static FC_CLASS_DEVICE_ATTR(host, field, S_IRUGO,			\
+			 show_fc_host_##field, NULL)
+
+#define fc_private_host_rd_attr_cast(field, format_string, sz, cast)	\
+	fc_private_host_show_function(field, format_string, sz, (cast)) \
+static FC_CLASS_DEVICE_ATTR(host, field, S_IRUGO,			\
+			  show_fc_host_##field, NULL)
+
+#define SETUP_PRIVATE_HOST_ATTRIBUTE_RD(field)			\
+	i->private_host_attrs[count] = class_device_attr_host_##field;	\
+	i->private_host_attrs[count].attr.mode = S_IRUGO;		\
+	i->private_host_attrs[count].store = NULL;			\
+	i->host_attrs[count] = &i->private_host_attrs[count];		\
+	count++
+
+#define SETUP_PRIVATE_HOST_ATTRIBUTE_RW(field)			\
+	i->private_host_attrs[count] = class_device_attr_host_##field;	\
+	i->host_attrs[count] = &i->private_host_attrs[count];		\
+	count++
+
+
+/* Fixed Host Attributes */
+
+static ssize_t
+show_fc_host_supported_classes (struct class_device *cdev, char *buf)
+{
+	struct Scsi_Host *shost = transport_class_to_shost(cdev);
+
+	if (fc_host_supported_classes(shost) == FC_COS_UNSPECIFIED)
+		return snprintf(buf, 20, "unspecified\n");
+
+	return get_fc_cos_names(fc_host_supported_classes(shost), buf);
+}
+static FC_CLASS_DEVICE_ATTR(host, supported_classes, S_IRUGO,
+		show_fc_host_supported_classes, NULL);
+
+static ssize_t
+show_fc_host_supported_fc4s (struct class_device *cdev, char *buf)
+{
+	struct Scsi_Host *shost = transport_class_to_shost(cdev);
+	return (ssize_t)show_fc_fc4s(buf, fc_host_supported_fc4s(shost));
+}
+static FC_CLASS_DEVICE_ATTR(host, supported_fc4s, S_IRUGO,
+		show_fc_host_supported_fc4s, NULL);
+
+static ssize_t
+show_fc_host_supported_speeds (struct class_device *cdev, char *buf)
+{
+	struct Scsi_Host *shost = transport_class_to_shost(cdev);
+
+	if (fc_host_supported_speeds(shost) == FC_PORTSPEED_UNKNOWN)
+		return snprintf(buf, 20, "unknown\n");
+
+	return get_fc_port_speed_names(fc_host_supported_speeds(shost), buf);
+}
+static FC_CLASS_DEVICE_ATTR(host, supported_speeds, S_IRUGO,
+		show_fc_host_supported_speeds, NULL);
+
+
+fc_private_host_rd_attr_cast(node_name, "0x%llx\n", 20, unsigned long long);
+fc_private_host_rd_attr_cast(port_name, "0x%llx\n", 20, unsigned long long);
+fc_private_host_rd_attr(symbolic_name, "%s\n", (FC_SYMBOLIC_NAME_SIZE +1));
+fc_private_host_rd_attr(maxframe_size, "%u bytes\n", 20);
+fc_private_host_rd_attr(hardware_version, "%s\n", (FC_VERSION_STRING_SIZE +1));
+fc_private_host_rd_attr(firmware_version, "%s\n", (FC_VERSION_STRING_SIZE +1));
+fc_private_host_rd_attr(serial_number, "%s\n", (FC_SERIAL_NUMBER_SIZE +1));
+fc_private_host_rd_attr(opt_rom_version, "%s\n", (FC_VERSION_STRING_SIZE +1));
+fc_private_host_rd_attr(driver_version, "%s\n", (FC_VERSION_STRING_SIZE +1));
+
+
+/* Dynamic Host Attributes */
+
+static ssize_t
+show_fc_host_active_fc4s (struct class_device *cdev, char *buf)
+{
+	struct Scsi_Host *shost = transport_class_to_shost(cdev);
+	struct fc_internal *i = to_fc_internal(shost->transportt);
+
+	if (i->f->get_host_active_fc4s)
+		i->f->get_host_active_fc4s(shost);
+
+	return (ssize_t)show_fc_fc4s(buf, fc_host_active_fc4s(shost));
+}
+static FC_CLASS_DEVICE_ATTR(host, active_fc4s, S_IRUGO,
+		show_fc_host_active_fc4s, NULL);
+
+static ssize_t
+show_fc_host_speed (struct class_device *cdev, char *buf)
+{
+	struct Scsi_Host *shost = transport_class_to_shost(cdev);
+	struct fc_internal *i = to_fc_internal(shost->transportt);
+
+	if (i->f->get_host_speed)
+		i->f->get_host_speed(shost);
+
+	if (fc_host_speed(shost) == FC_PORTSPEED_UNKNOWN)
+		return snprintf(buf, 20, "unknown\n");
+
+	return get_fc_port_speed_names(fc_host_speed(shost), buf);
+}
+static FC_CLASS_DEVICE_ATTR(host, speed, S_IRUGO,
+		show_fc_host_speed, NULL);
+
+
+fc_host_rd_attr(port_id, "0x%06x\n", 20);
+fc_host_rd_enum_attr(port_type, FC_PORTTYPE_MAX_NAMELEN);
+fc_host_rd_enum_attr(port_state, FC_PORTSTATE_MAX_NAMELEN);
+fc_host_rd_attr_cast(fabric_name, "0x%llx\n", 20, unsigned long long);
+fc_host_rw_attr(link_down_tmo, "%d\n", 20);
+
+
+/* Private Host Attributes */
+
+static ssize_t
+show_fc_private_host_tgtid_bind_type(struct class_device *cdev, char *buf)
+{
+	struct Scsi_Host *shost = transport_class_to_shost(cdev);
+	const char *name;
+
+	name = get_fc_tgtid_bind_type_name(fc_host_tgtid_bind_type(shost));
+	if (!name)
+		return -EINVAL;
+	return snprintf(buf, FC_BINDTYPE_MAX_NAMELEN, "%s\n", name);
+}
+
+static ssize_t
+store_fc_private_host_tgtid_bind_type(struct class_device *cdev,
+	const char *buf, size_t count)
+{
+	struct Scsi_Host *shost = transport_class_to_shost(cdev);
+	enum fc_tgtid_binding_type val;
+
+	if (get_fc_tgtid_bind_type_match(buf, &val))
+		return -EINVAL;
+	fc_host_tgtid_bind_type(shost) = val;
+	return count;
+}
+
+static FC_CLASS_DEVICE_ATTR(host, tgtid_bind_type, S_IRUGO | S_IWUSR,
+			show_fc_private_host_tgtid_bind_type,
+			store_fc_private_host_tgtid_bind_type);
+
+/*
+ * Host Statistics Management
+ */
+
+/* Show a given an attribute in the statistics group */
+static ssize_t
+fc_stat_show(const struct class_device *cdev, char *buf, unsigned long offset)
+{
+	struct Scsi_Host *shost = transport_class_to_shost(cdev);
+	struct fc_internal *i = to_fc_internal(shost->transportt);
+	struct fc_host_statistics *stats;
+	ssize_t ret = -ENOENT;
+
+	if (offset > sizeof(struct fc_host_statistics) ||
+	    offset % sizeof(u64) != 0)
+		WARN_ON(1);
+
+	if (i->f->get_fc_host_stats) {
+		stats = (i->f->get_fc_host_stats)(shost);
+		if (stats)
+			ret = snprintf(buf, 20, "0x%llx\n",
+			      (unsigned long long)*(u64 *)(((u8 *) stats) + offset));
+	}
+	return ret;
+}
+
+
+/* generate a read-only statistics attribute */
+#define fc_host_statistic(name)						\
+static ssize_t show_fcstat_##name(struct class_device *cd, char *buf) 	\
+{									\
+	return fc_stat_show(cd, buf, 					\
+			    offsetof(struct fc_host_statistics, name));	\
+}									\
+static FC_CLASS_DEVICE_ATTR(host, name, S_IRUGO, show_fcstat_##name, NULL)
+
+fc_host_statistic(seconds_since_last_reset);
+fc_host_statistic(tx_frames);
+fc_host_statistic(tx_words);
+fc_host_statistic(rx_frames);
+fc_host_statistic(rx_words);
+fc_host_statistic(lip_count);
+fc_host_statistic(nos_count);
+fc_host_statistic(error_frames);
+fc_host_statistic(dumped_frames);
+fc_host_statistic(link_failure_count);
+fc_host_statistic(loss_of_sync_count);
+fc_host_statistic(loss_of_signal_count);
+fc_host_statistic(prim_seq_protocol_err_count);
+fc_host_statistic(invalid_tx_word_count);
+fc_host_statistic(invalid_crc_count);
+fc_host_statistic(fcp_input_requests);
+fc_host_statistic(fcp_output_requests);
+fc_host_statistic(fcp_control_requests);
+fc_host_statistic(fcp_input_megabytes);
+fc_host_statistic(fcp_output_megabytes);
+
+static ssize_t
+fc_reset_statistics(struct class_device *cdev, const char *buf,
+			   size_t count)
+{
+	struct Scsi_Host *shost = transport_class_to_shost(cdev);
+	struct fc_internal *i = to_fc_internal(shost->transportt);
+
+	/* ignore any data value written to the attribute */
+	if (i->f->reset_fc_host_stats) {
+		i->f->reset_fc_host_stats(shost);
+		return count;
+	}
+
+	return -ENOENT;
+}
+static FC_CLASS_DEVICE_ATTR(host, reset_statistics, S_IWUSR, NULL,
+				fc_reset_statistics);
+
+
+static struct attribute *fc_statistics_attrs[] = {
+	&class_device_attr_host_seconds_since_last_reset.attr,
+	&class_device_attr_host_tx_frames.attr,
+	&class_device_attr_host_tx_words.attr,
+	&class_device_attr_host_rx_frames.attr,
+	&class_device_attr_host_rx_words.attr,
+	&class_device_attr_host_lip_count.attr,
+	&class_device_attr_host_nos_count.attr,
+	&class_device_attr_host_error_frames.attr,
+	&class_device_attr_host_dumped_frames.attr,
+	&class_device_attr_host_link_failure_count.attr,
+	&class_device_attr_host_loss_of_sync_count.attr,
+	&class_device_attr_host_loss_of_signal_count.attr,
+	&class_device_attr_host_prim_seq_protocol_err_count.attr,
+	&class_device_attr_host_invalid_tx_word_count.attr,
+	&class_device_attr_host_invalid_crc_count.attr,
+	&class_device_attr_host_fcp_input_requests.attr,
+	&class_device_attr_host_fcp_output_requests.attr,
+	&class_device_attr_host_fcp_control_requests.attr,
+	&class_device_attr_host_fcp_input_megabytes.attr,
+	&class_device_attr_host_fcp_output_megabytes.attr,
+	&class_device_attr_host_reset_statistics.attr,
+	NULL
+};
+
+static struct attribute_group fc_statistics_group = {
+	.name = "statistics",
+	.attrs = fc_statistics_attrs,
+};
+
+static int fc_host_match(struct attribute_container *cont,
+			  struct device *dev)
+{
+	struct Scsi_Host *shost;
+	struct fc_internal *i;
+
+	if (!scsi_is_host_device(dev))
+		return 0;
+
+	shost = dev_to_shost(dev);
+	if (!shost->transportt  || shost->transportt->host_attrs.class
+	    != &fc_host_class.class)
+		return 0;
+
+	i = to_fc_internal(shost->transportt);
+	
+	return &i->t.host_attrs == cont;
+}
+
+static int fc_target_match(struct attribute_container *cont,
+			    struct device *dev)
+{
+	struct Scsi_Host *shost;
+	struct fc_internal *i;
+
+	if (!scsi_is_target_device(dev))
+		return 0;
+
+	shost = dev_to_shost(dev->parent);
+	if (!shost->transportt  || shost->transportt->host_attrs.class
+	    != &fc_host_class.class)
+		return 0;
+
+	i = to_fc_internal(shost->transportt);
+	
+	return &i->t.target_attrs == cont;
+}
 
 
 struct scsi_transport_template *
@@ -274,15 +775,21 @@
 
 	memset(i, 0, sizeof(struct fc_internal));
 
-	i->t.target_attrs = &i->starget_attrs[0];
-	i->t.target_class = &fc_transport_class;
-	i->t.target_setup = &fc_setup_starget_transport_attrs;
+	i->t.target_attrs.attrs = &i->starget_attrs[0];
+	i->t.target_attrs.class = &fc_transport_class.class;
+	i->t.target_attrs.match = fc_target_match;
+	attribute_container_register(&i->t.target_attrs);
 	i->t.target_size = sizeof(struct fc_starget_attrs);
 
-	i->t.host_attrs = &i->host_attrs[0];
-	i->t.host_class = &fc_host_class;
-	i->t.host_setup = &fc_setup_host_transport_attrs;
+	i->t.host_attrs.attrs = &i->host_attrs[0];
+	i->t.host_attrs.class = &fc_host_class.class;
+	i->t.host_attrs.match = fc_host_match;
+	attribute_container_register(&i->t.host_attrs);
 	i->t.host_size = sizeof(struct fc_host_attrs);
+
+	if (ft->get_fc_host_stats)
+		i->t.host_statistics = &fc_statistics_group;
+
 	i->f = ft;
 
 	
@@ -303,11 +810,31 @@
 
 	/* setup host attributes */
 	count=0;
+	SETUP_HOST_ATTRIBUTE_RD(node_name);
+	SETUP_HOST_ATTRIBUTE_RD(port_name);
+	SETUP_HOST_ATTRIBUTE_RD(supported_classes);
+	SETUP_HOST_ATTRIBUTE_RD(supported_fc4s);
+	SETUP_HOST_ATTRIBUTE_RD(symbolic_name);
+	SETUP_HOST_ATTRIBUTE_RD(supported_speeds);
+	SETUP_HOST_ATTRIBUTE_RD(maxframe_size);
+	SETUP_HOST_ATTRIBUTE_RD(hardware_version);
+	SETUP_HOST_ATTRIBUTE_RD(firmware_version);
+	SETUP_HOST_ATTRIBUTE_RD(serial_number);
+	SETUP_HOST_ATTRIBUTE_RD(opt_rom_version);
+	SETUP_HOST_ATTRIBUTE_RD(driver_version);
+
+	SETUP_HOST_ATTRIBUTE_RD(port_id);
+	SETUP_HOST_ATTRIBUTE_RD(port_type);
+	SETUP_HOST_ATTRIBUTE_RD(port_state);
+	SETUP_HOST_ATTRIBUTE_RD(active_fc4s);
+	SETUP_HOST_ATTRIBUTE_RD(speed);
+	SETUP_HOST_ATTRIBUTE_RD(fabric_name);
 	SETUP_HOST_ATTRIBUTE_RW(link_down_tmo);
 
-	BUG_ON(count > FC_HOST_NUM_ATTRS);
+	/* Transport-managed attributes */
+	SETUP_PRIVATE_HOST_ATTRIBUTE_RW(tgtid_bind_type);
 
-	/* Setup the always-on attributes here */
+	BUG_ON(count > FC_HOST_NUM_ATTRS);
 
 	i->host_attrs[count] = NULL;
 
@@ -320,6 +847,9 @@
 {
 	struct fc_internal *i = to_fc_internal(t);
 
+	attribute_container_unregister(&i->t.target_attrs);
+	attribute_container_unregister(&i->t.host_attrs);
+
 	kfree(i);
 }
 EXPORT_SYMBOL(fc_release_transport);
@@ -331,10 +861,9 @@
  * @dev:	scsi device
  * @data:	unused
  **/
-static int fc_device_block(struct device *dev, void *data)
+static void fc_device_block(struct scsi_device *sdev, void *data)
 {
-	scsi_internal_device_block(to_scsi_device(dev));
-	return 0;
+	scsi_internal_device_block(sdev);
 }
 
 /**
@@ -342,10 +871,9 @@
  * @dev:	scsi device
  * @data:	unused
  **/
-static int fc_device_unblock(struct device *dev, void *data)
+static void fc_device_unblock(struct scsi_device *sdev, void *data)
 {
-	scsi_internal_device_unblock(to_scsi_device(dev));
-	return 0;
+	scsi_internal_device_unblock(sdev);
 }
 
 /**
@@ -353,7 +881,7 @@
  *			 that fail to recover in the alloted time.
  * @data:	scsi target that failed to reappear in the alloted time.
  **/
-static void fc_timeout_blocked_tgt(unsigned long data)
+static void fc_timeout_blocked_tgt(void  *data)
 {
 	struct scsi_target *starget = (struct scsi_target *)data;
 
@@ -365,7 +893,7 @@
 	 * unblock this device, then IO errors will probably
 	 * result if the host still isn't ready.
 	 */
-	device_for_each_child(&starget->dev, NULL, fc_device_unblock);
+	starget_for_each_device(starget, NULL, fc_device_unblock);
 }
 
 /**
@@ -388,18 +916,15 @@
 fc_target_block(struct scsi_target *starget)
 {
 	int timeout = fc_starget_dev_loss_tmo(starget);
-	struct timer_list *timer = &fc_starget_dev_loss_timer(starget);
+	struct work_struct *work = &fc_starget_dev_loss_work(starget);
 
 	if (timeout < 0 || timeout > SCSI_DEVICE_BLOCK_MAX_TIMEOUT)
 		return -EINVAL;
 
-	device_for_each_child(&starget->dev, NULL, fc_device_block);
+	starget_for_each_device(starget, NULL, fc_device_block);
 
 	/* The scsi lld blocks this target for the timeout period only. */
-	timer->data = (unsigned long)starget;
-	timer->expires = jiffies + timeout * HZ;
-	timer->function = fc_timeout_blocked_tgt;
-	add_timer(timer);
+	schedule_delayed_work(work, timeout * HZ);
 
 	return 0;
 }
@@ -424,9 +949,10 @@
 	 * failure as the state machine state change will validate the
 	 * transaction. 
 	 */
-	del_timer_sync(&fc_starget_dev_loss_timer(starget));
+	if (cancel_delayed_work(&fc_starget_dev_loss_work(starget)))
+		flush_scheduled_work();
 
-	device_for_each_child(&starget->dev, NULL, fc_device_unblock);
+	starget_for_each_device(starget, NULL, fc_device_unblock);
 }
 EXPORT_SYMBOL(fc_target_unblock);
 
@@ -436,7 +962,7 @@
  * @data:	scsi host that failed to recover its devices in the alloted
  *		time.
  **/
-static void fc_timeout_blocked_host(unsigned long data)
+static void fc_timeout_blocked_host(void  *data)
 {
 	struct Scsi_Host *shost = (struct Scsi_Host *)data;
 	struct scsi_device *sdev;
@@ -475,7 +1001,7 @@
 {
 	struct scsi_device *sdev;
 	int timeout = fc_host_link_down_tmo(shost);
-	struct timer_list *timer = &fc_host_link_down_timer(shost);
+	struct work_struct *work = &fc_host_link_down_work(shost);
 
 	if (timeout < 0 || timeout > SCSI_DEVICE_BLOCK_MAX_TIMEOUT)
 		return -EINVAL;
@@ -484,11 +1010,7 @@
 		scsi_internal_device_block(sdev);
 	}
 
-	/* The scsi lld blocks this host for the timeout period only. */
-	timer->data = (unsigned long)shost;
-	timer->expires = jiffies + timeout * HZ;
-	timer->function = fc_timeout_blocked_host;
-	add_timer(timer);
+	schedule_delayed_work(work, timeout * HZ);
 
 	return 0;
 }
@@ -516,7 +1038,9 @@
 	 * failure as the state machine state change will validate the
 	 * transaction.
 	 */
-	del_timer_sync(&fc_host_link_down_timer(shost));
+	if (cancel_delayed_work(&fc_host_link_down_work(shost)))
+		flush_scheduled_work();
+
 	shost_for_each_device(sdev, shost) {
 		scsi_internal_device_unblock(sdev);
 	}
diff -Nru a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/scsi/scsi_transport_iscsi.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,388 @@
+/* 
+ * iSCSI transport class definitions
+ *
+ * Copyright (C) IBM Corporation, 2004
+ * Copyright (C) Mike Christie, 2004
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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 <scsi/scsi.h>
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_transport.h>
+#include <scsi/scsi_transport_iscsi.h>
+
+#define ISCSI_SESSION_ATTRS 20
+#define ISCSI_HOST_ATTRS 2
+
+struct iscsi_internal {
+	struct scsi_transport_template t;
+	struct iscsi_function_template *fnt;
+	/*
+	 * We do not have any private or other attrs.
+	 */
+	struct class_device_attribute *session_attrs[ISCSI_SESSION_ATTRS + 1];
+	struct class_device_attribute *host_attrs[ISCSI_HOST_ATTRS + 1];
+};
+
+#define to_iscsi_internal(tmpl) container_of(tmpl, struct iscsi_internal, t)
+
+static DECLARE_TRANSPORT_CLASS(iscsi_transport_class,
+			       "iscsi_transport",
+			       NULL,
+			       NULL,
+			       NULL);
+
+static DECLARE_TRANSPORT_CLASS(iscsi_host_class,
+			       "iscsi_host",
+			       NULL,
+			       NULL,
+			       NULL);
+/*
+ * iSCSI target and session attrs
+ */
+#define iscsi_session_show_fn(field, format)				\
+									\
+static ssize_t								\
+show_session_##field(struct class_device *cdev, char *buf)		\
+{									\
+	struct scsi_target *starget = transport_class_to_starget(cdev);	\
+	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);	\
+	struct iscsi_internal *i = to_iscsi_internal(shost->transportt); \
+									\
+	if (i->fnt->get_##field)					\
+		i->fnt->get_##field(starget);				\
+	return snprintf(buf, 20, format"\n", iscsi_##field(starget));	\
+}
+
+#define iscsi_session_rd_attr(field, format)				\
+	iscsi_session_show_fn(field, format)				\
+static CLASS_DEVICE_ATTR(field, S_IRUGO, show_session_##field, NULL);
+
+iscsi_session_rd_attr(tpgt, "%hu");
+iscsi_session_rd_attr(tsih, "%2x");
+iscsi_session_rd_attr(max_recv_data_segment_len, "%u");
+iscsi_session_rd_attr(max_burst_len, "%u");
+iscsi_session_rd_attr(first_burst_len, "%u");
+iscsi_session_rd_attr(def_time2wait, "%hu");
+iscsi_session_rd_attr(def_time2retain, "%hu");
+iscsi_session_rd_attr(max_outstanding_r2t, "%hu");
+iscsi_session_rd_attr(erl, "%d");
+
+
+#define iscsi_session_show_bool_fn(field)				\
+									\
+static ssize_t								\
+show_session_bool_##field(struct class_device *cdev, char *buf)		\
+{									\
+	struct scsi_target *starget = transport_class_to_starget(cdev);	\
+	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);	\
+	struct iscsi_internal *i = to_iscsi_internal(shost->transportt); \
+									\
+	if (i->fnt->get_##field)					\
+		i->fnt->get_##field(starget);				\
+									\
+	if (iscsi_##field(starget))					\
+		return sprintf(buf, "Yes\n");				\
+	return sprintf(buf, "No\n");					\
+}
+
+#define iscsi_session_rd_bool_attr(field)				\
+	iscsi_session_show_bool_fn(field)				\
+static CLASS_DEVICE_ATTR(field, S_IRUGO, show_session_bool_##field, NULL);
+
+iscsi_session_rd_bool_attr(initial_r2t);
+iscsi_session_rd_bool_attr(immediate_data);
+iscsi_session_rd_bool_attr(data_pdu_in_order);
+iscsi_session_rd_bool_attr(data_sequence_in_order);
+
+#define iscsi_session_show_digest_fn(field)				\
+									\
+static ssize_t								\
+show_##field(struct class_device *cdev, char *buf)			\
+{									\
+	struct scsi_target *starget = transport_class_to_starget(cdev);	\
+	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);	\
+	struct iscsi_internal *i = to_iscsi_internal(shost->transportt); \
+									\
+	if (i->fnt->get_##field)					\
+		i->fnt->get_##field(starget);				\
+									\
+	if (iscsi_##field(starget))					\
+		return sprintf(buf, "CRC32C\n");			\
+	return sprintf(buf, "None\n");					\
+}
+
+#define iscsi_session_rd_digest_attr(field)				\
+	iscsi_session_show_digest_fn(field)				\
+static CLASS_DEVICE_ATTR(field, S_IRUGO, show_##field, NULL);
+
+iscsi_session_rd_digest_attr(header_digest);
+iscsi_session_rd_digest_attr(data_digest);
+
+static ssize_t
+show_port(struct class_device *cdev, char *buf)
+{
+	struct scsi_target *starget = transport_class_to_starget(cdev);
+	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+	struct iscsi_internal *i = to_iscsi_internal(shost->transportt);
+
+	if (i->fnt->get_port)
+		i->fnt->get_port(starget);
+
+	return snprintf(buf, 20, "%hu\n", ntohs(iscsi_port(starget)));
+}
+static CLASS_DEVICE_ATTR(port, S_IRUGO, show_port, NULL);
+
+static ssize_t
+show_ip_address(struct class_device *cdev, char *buf)
+{
+	struct scsi_target *starget = transport_class_to_starget(cdev);
+	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+	struct iscsi_internal *i = to_iscsi_internal(shost->transportt);
+
+	if (i->fnt->get_ip_address)
+		i->fnt->get_ip_address(starget);
+
+	if (iscsi_addr_type(starget) == AF_INET)
+		return sprintf(buf, "%u.%u.%u.%u\n",
+			       NIPQUAD(iscsi_sin_addr(starget)));
+	else if(iscsi_addr_type(starget) == AF_INET6)
+		return sprintf(buf, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
+			       NIP6(iscsi_sin6_addr(starget)));
+	return -EINVAL;
+}
+static CLASS_DEVICE_ATTR(ip_address, S_IRUGO, show_ip_address, NULL);
+
+static ssize_t
+show_isid(struct class_device *cdev, char *buf)
+{
+	struct scsi_target *starget = transport_class_to_starget(cdev);
+	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+	struct iscsi_internal *i = to_iscsi_internal(shost->transportt);
+
+	if (i->fnt->get_isid)
+		i->fnt->get_isid(starget);
+
+	return sprintf(buf, "%02x%02x%02x%02x%02x%02x\n",
+		       iscsi_isid(starget)[0], iscsi_isid(starget)[1],
+		       iscsi_isid(starget)[2], iscsi_isid(starget)[3],
+		       iscsi_isid(starget)[4], iscsi_isid(starget)[5]);
+}
+static CLASS_DEVICE_ATTR(isid, S_IRUGO, show_isid, NULL);
+
+/*
+ * This is used for iSCSI names. Normally, we follow
+ * the transport class convention of having the lld
+ * set the field, but in these cases the value is
+ * too large.
+ */
+#define iscsi_session_show_str_fn(field)				\
+									\
+static ssize_t								\
+show_session_str_##field(struct class_device *cdev, char *buf)		\
+{									\
+	ssize_t ret = 0;						\
+	struct scsi_target *starget = transport_class_to_starget(cdev);	\
+	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);	\
+	struct iscsi_internal *i = to_iscsi_internal(shost->transportt); \
+									\
+	if (i->fnt->get_##field)					\
+		ret = i->fnt->get_##field(starget, buf, PAGE_SIZE);	\
+	return ret;							\
+}
+
+#define iscsi_session_rd_str_attr(field)				\
+	iscsi_session_show_str_fn(field)				\
+static CLASS_DEVICE_ATTR(field, S_IRUGO, show_session_str_##field, NULL);
+
+iscsi_session_rd_str_attr(target_name);
+iscsi_session_rd_str_attr(target_alias);
+
+/*
+ * iSCSI host attrs
+ */
+
+/*
+ * Again, this is used for iSCSI names. Normally, we follow
+ * the transport class convention of having the lld set
+ * the field, but in these cases the value is too large.
+ */
+#define iscsi_host_show_str_fn(field)					\
+									\
+static ssize_t								\
+show_host_str_##field(struct class_device *cdev, char *buf)		\
+{									\
+	int ret = 0;							\
+	struct Scsi_Host *shost = transport_class_to_shost(cdev);	\
+	struct iscsi_internal *i = to_iscsi_internal(shost->transportt); \
+									\
+	if (i->fnt->get_##field)					\
+		ret = i->fnt->get_##field(shost, buf, PAGE_SIZE);	\
+	return ret;							\
+}
+
+#define iscsi_host_rd_str_attr(field)					\
+	iscsi_host_show_str_fn(field)					\
+static CLASS_DEVICE_ATTR(field, S_IRUGO, show_host_str_##field, NULL);
+
+iscsi_host_rd_str_attr(initiator_name);
+iscsi_host_rd_str_attr(initiator_alias);
+
+#define SETUP_SESSION_RD_ATTR(field)					\
+	if (i->fnt->show_##field) {					\
+		i->session_attrs[count] = &class_device_attr_##field;	\
+		count++;						\
+	}
+
+#define SETUP_HOST_RD_ATTR(field)					\
+	if (i->fnt->show_##field) {					\
+		i->host_attrs[count] = &class_device_attr_##field;	\
+		count++;						\
+	}
+
+static int iscsi_host_match(struct attribute_container *cont,
+			  struct device *dev)
+{
+	struct Scsi_Host *shost;
+	struct iscsi_internal *i;
+
+	if (!scsi_is_host_device(dev))
+		return 0;
+
+	shost = dev_to_shost(dev);
+	if (!shost->transportt  || shost->transportt->host_attrs.class
+	    != &iscsi_host_class.class)
+		return 0;
+
+	i = to_iscsi_internal(shost->transportt);
+	
+	return &i->t.host_attrs == cont;
+}
+
+static int iscsi_target_match(struct attribute_container *cont,
+			    struct device *dev)
+{
+	struct Scsi_Host *shost;
+	struct iscsi_internal *i;
+
+	if (!scsi_is_target_device(dev))
+		return 0;
+
+	shost = dev_to_shost(dev->parent);
+	if (!shost->transportt  || shost->transportt->host_attrs.class
+	    != &iscsi_host_class.class)
+		return 0;
+
+	i = to_iscsi_internal(shost->transportt);
+	
+	return &i->t.target_attrs == cont;
+}
+
+struct scsi_transport_template *
+iscsi_attach_transport(struct iscsi_function_template *fnt)
+{
+	struct iscsi_internal *i = kmalloc(sizeof(struct iscsi_internal),
+					   GFP_KERNEL);
+	int count = 0;
+
+	if (unlikely(!i))
+		return NULL;
+
+	memset(i, 0, sizeof(struct iscsi_internal));
+	i->fnt = fnt;
+
+	i->t.target_attrs.attrs = &i->session_attrs[0];
+	i->t.target_attrs.class = &iscsi_transport_class.class;
+	i->t.target_attrs.match = iscsi_target_match;
+	attribute_container_register(&i->t.target_attrs);
+	i->t.target_size = sizeof(struct iscsi_class_session);
+
+	SETUP_SESSION_RD_ATTR(tsih);
+	SETUP_SESSION_RD_ATTR(isid);
+	SETUP_SESSION_RD_ATTR(header_digest);
+	SETUP_SESSION_RD_ATTR(data_digest);
+	SETUP_SESSION_RD_ATTR(target_name);
+	SETUP_SESSION_RD_ATTR(target_alias);
+	SETUP_SESSION_RD_ATTR(port);
+	SETUP_SESSION_RD_ATTR(tpgt);
+	SETUP_SESSION_RD_ATTR(ip_address);
+	SETUP_SESSION_RD_ATTR(initial_r2t);
+	SETUP_SESSION_RD_ATTR(immediate_data);
+	SETUP_SESSION_RD_ATTR(max_recv_data_segment_len);
+	SETUP_SESSION_RD_ATTR(max_burst_len);
+	SETUP_SESSION_RD_ATTR(first_burst_len);
+	SETUP_SESSION_RD_ATTR(def_time2wait);
+	SETUP_SESSION_RD_ATTR(def_time2retain);
+	SETUP_SESSION_RD_ATTR(max_outstanding_r2t);
+	SETUP_SESSION_RD_ATTR(data_pdu_in_order);
+	SETUP_SESSION_RD_ATTR(data_sequence_in_order);
+	SETUP_SESSION_RD_ATTR(erl);
+
+	BUG_ON(count > ISCSI_SESSION_ATTRS);
+	i->session_attrs[count] = NULL;
+
+	i->t.host_attrs.attrs = &i->host_attrs[0];
+	i->t.host_attrs.class = &iscsi_host_class.class;
+	i->t.host_attrs.match = iscsi_host_match;
+	attribute_container_register(&i->t.host_attrs);
+	i->t.host_size = 0;
+
+	count = 0;
+	SETUP_HOST_RD_ATTR(initiator_name);
+	SETUP_HOST_RD_ATTR(initiator_alias);
+
+	BUG_ON(count > ISCSI_HOST_ATTRS);
+	i->host_attrs[count] = NULL;
+
+	return &i->t;
+}
+
+EXPORT_SYMBOL(iscsi_attach_transport);
+
+void iscsi_release_transport(struct scsi_transport_template *t)
+{
+	struct iscsi_internal *i = to_iscsi_internal(t);
+
+	attribute_container_unregister(&i->t.target_attrs);
+	attribute_container_unregister(&i->t.host_attrs);
+
+	kfree(i);
+}
+
+EXPORT_SYMBOL(iscsi_release_transport);
+
+static __init int iscsi_transport_init(void)
+{
+	int err = transport_class_register(&iscsi_transport_class);
+
+	if (err)
+		return err;
+	return transport_class_register(&iscsi_host_class);
+}
+
+static void __exit iscsi_transport_exit(void)
+{
+	transport_class_unregister(&iscsi_host_class);
+	transport_class_unregister(&iscsi_transport_class);
+}
+
+module_init(iscsi_transport_init);
+module_exit(iscsi_transport_exit);
+
+MODULE_AUTHOR("Mike Christie");
+MODULE_DESCRIPTION("iSCSI Transport Attributes");
+MODULE_LICENSE("GPL");
diff -Nru a/drivers/scsi/scsi_transport_spi.c b/drivers/scsi/scsi_transport_spi.c
--- a/drivers/scsi/scsi_transport_spi.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/scsi/scsi_transport_spi.c	2005-03-01 23:38:57 -08:00
@@ -2,6 +2,7 @@
  *  Parallel SCSI (SPI) transport specific attributes exported to sysfs.
  *
  *  Copyright (c) 2003 Silicon Graphics, Inc.  All rights reserved.
+ *  Copyright (c) 2004, 2005 James Bottomley <James.Bottomley@SteelEye.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
@@ -31,14 +32,12 @@
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_request.h>
+#include <scsi/scsi_eh.h>
 #include <scsi/scsi_transport.h>
 #include <scsi/scsi_transport_spi.h>
 
 #define SPI_PRINTK(x, l, f, a...)	dev_printk(l, &(x)->dev, f , ##a)
 
-static void transport_class_release(struct class_device *class_dev);
-static void host_class_release(struct class_device *class_dev);
-
 #define SPI_NUM_ATTRS 10	/* increase this if you add attributes */
 #define SPI_OTHER_ATTRS 1	/* Increase this if you add "always
 				 * on" attributes */
@@ -118,40 +117,43 @@
 	return SPI_SIGNAL_UNKNOWN;
 }
 
+static int spi_host_setup(struct device *dev)
+{
+	struct Scsi_Host *shost = dev_to_shost(dev);
 
-struct class spi_transport_class = {
-	.name = "spi_transport",
-	.release = transport_class_release,
-};
-
-struct class spi_host_class = {
-	.name = "spi_host",
-	.release = host_class_release,
-};
+	spi_signalling(shost) = SPI_SIGNAL_UNKNOWN;
 
-static __init int spi_transport_init(void)
-{
-	int error = class_register(&spi_host_class);
-	if (error)
-		return error;
-	return class_register(&spi_transport_class);
+	return 0;
 }
 
-static void __exit spi_transport_exit(void)
-{
-	class_unregister(&spi_transport_class);
-	class_unregister(&spi_host_class);
-}
+static DECLARE_TRANSPORT_CLASS(spi_host_class,
+			       "spi_host",
+			       spi_host_setup,
+			       NULL,
+			       NULL);
 
-static int spi_setup_host_attrs(struct Scsi_Host *shost)
+static int spi_host_match(struct attribute_container *cont,
+			  struct device *dev)
 {
-	spi_signalling(shost) = SPI_SIGNAL_UNKNOWN;
+	struct Scsi_Host *shost;
+	struct spi_internal *i;
 
-	return 0;
+	if (!scsi_is_host_device(dev))
+		return 0;
+
+	shost = dev_to_shost(dev);
+	if (!shost->transportt  || shost->transportt->host_attrs.class
+	    != &spi_host_class.class)
+		return 0;
+
+	i = to_spi_internal(shost->transportt);
+	
+	return &i->t.host_attrs == cont;
 }
 
-static int spi_configure_device(struct scsi_device *sdev)
+static int spi_device_configure(struct device *dev)
 {
+	struct scsi_device *sdev = to_scsi_device(dev);
 	struct scsi_target *starget = sdev->sdev_target;
 
 	/* Populate the target capability fields with the values
@@ -167,8 +169,10 @@
 	return 0;
 }
 
-static int spi_setup_transport_attrs(struct scsi_target *starget)
+static int spi_setup_transport_attrs(struct device *dev)
 {
+	struct scsi_target *starget = to_scsi_target(dev);
+
 	spi_period(starget) = -1;	/* illegal value */
 	spi_offset(starget) = 0;	/* async */
 	spi_width(starget) = 0;	/* narrow */
@@ -186,18 +190,6 @@
 	return 0;
 }
 
-static void transport_class_release(struct class_device *class_dev)
-{
-	struct scsi_target *starget = transport_class_to_starget(class_dev);
-	put_device(&starget->dev);
-}
-
-static void host_class_release(struct class_device *class_dev)
-{
-	struct Scsi_Host *shost = transport_class_to_shost(class_dev);
-	put_device(&shost->shost_gendev);
-}
-
 #define spi_transport_show_function(field, format_string)		\
 									\
 static ssize_t								\
@@ -378,10 +370,16 @@
 #define DV_RETRIES	3	/* should only need at most 
 				 * two cc/ua clears */
 
+enum spi_compare_returns {
+	SPI_COMPARE_SUCCESS,
+	SPI_COMPARE_FAILURE,
+	SPI_COMPARE_SKIP_TEST,
+};
+
 
 /* This is for read/write Domain Validation:  If the device supports
  * an echo buffer, we do read/write tests to it */
-static int
+static enum spi_compare_returns
 spi_dv_device_echo_buffer(struct scsi_request *sreq, u8 *buffer,
 			  u8 *ptr, const int retries)
 {
@@ -438,9 +436,23 @@
 		scsi_wait_req(sreq, spi_write_buffer, buffer, len,
 			      DV_TIMEOUT, DV_RETRIES);
 		if(sreq->sr_result || !scsi_device_online(sdev)) {
+			struct scsi_sense_hdr sshdr;
+
 			scsi_device_set_state(sdev, SDEV_QUIESCE);
+			if (scsi_request_normalize_sense(sreq, &sshdr)
+			    && sshdr.sense_key == ILLEGAL_REQUEST
+			    /* INVALID FIELD IN CDB */
+			    && sshdr.asc == 0x24 && sshdr.ascq == 0x00)
+				/* This would mean that the drive lied
+				 * to us about supporting an echo
+				 * buffer (unfortunately some Western
+				 * Digital drives do precisely this)
+				 */
+				return SPI_COMPARE_SKIP_TEST;
+
+
 			SPI_PRINTK(sdev->sdev_target, KERN_ERR, "Write Buffer failure %x\n", sreq->sr_result);
-			return 0;
+			return SPI_COMPARE_FAILURE;
 		}
 
 		memset(ptr, 0, len);
@@ -451,14 +463,14 @@
 		scsi_device_set_state(sdev, SDEV_QUIESCE);
 
 		if (memcmp(buffer, ptr, len) != 0)
-			return 0;
+			return SPI_COMPARE_FAILURE;
 	}
-	return 1;
+	return SPI_COMPARE_SUCCESS;
 }
 
 /* This is for the simplest form of Domain Validation: a read test
  * on the inquiry data from the device */
-static int
+static enum spi_compare_returns
 spi_dv_device_compare_inquiry(struct scsi_request *sreq, u8 *buffer,
 			      u8 *ptr, const int retries)
 {
@@ -480,7 +492,7 @@
 		
 		if(sreq->sr_result || !scsi_device_online(sdev)) {
 			scsi_device_set_state(sdev, SDEV_QUIESCE);
-			return 0;
+			return SPI_COMPARE_FAILURE;
 		}
 
 		/* If we don't have the inquiry data already, the
@@ -493,24 +505,28 @@
 
 		if (memcmp(buffer, ptr, len) != 0)
 			/* failure */
-			return 0;
+			return SPI_COMPARE_FAILURE;
 	}
-	return 1;
+	return SPI_COMPARE_SUCCESS;
 }
 
-static int
+static enum spi_compare_returns
 spi_dv_retrain(struct scsi_request *sreq, u8 *buffer, u8 *ptr,
-	       int (*compare_fn)(struct scsi_request *, u8 *, u8 *, int))
+	       enum spi_compare_returns 
+	       (*compare_fn)(struct scsi_request *, u8 *, u8 *, int))
 {
 	struct spi_internal *i = to_spi_internal(sreq->sr_host->transportt);
 	struct scsi_device *sdev = sreq->sr_device;
 	int period = 0, prevperiod = 0; 
+	enum spi_compare_returns retval;
 
 
 	for (;;) {
 		int newperiod;
-		if (compare_fn(sreq, buffer, ptr, DV_LOOPS))
-			/* Successful DV */
+		retval = compare_fn(sreq, buffer, ptr, DV_LOOPS);
+
+		if (retval == SPI_COMPARE_SUCCESS
+		    || retval == SPI_COMPARE_SKIP_TEST)
 			break;
 
 		/* OK, retrain, fallback */
@@ -527,13 +543,13 @@
 			/* 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 0;
+			return SPI_COMPARE_FAILURE;
 		}
 		SPI_PRINTK(sdev->sdev_target, KERN_ERR, "Domain Validation detected failure, dropping back\n");
 		DV_SET(period, period);
 		prevperiod = period;
 	}
-	return 1;
+	return retval;
 }
 
 static int
@@ -599,7 +615,8 @@
 	DV_SET(offset, 0);
 	DV_SET(width, 0);
 	
-	if (!spi_dv_device_compare_inquiry(sreq, buffer, buffer, DV_LOOPS)) {
+	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");
 		/* FIXME: should probably offline the device here? */
 		return;
@@ -609,9 +626,10 @@
 	if (i->f->set_width && sdev->wdtr) {
 		i->f->set_width(sdev->sdev_target, 1);
 
-		if (!spi_dv_device_compare_inquiry(sreq, buffer,
+		if (spi_dv_device_compare_inquiry(sreq, buffer,
 						   buffer + len,
-						   DV_LOOPS)) {
+						   DV_LOOPS)
+		    != SPI_COMPARE_SUCCESS) {
 			SPI_PRINTK(sdev->sdev_target, KERN_ERR, "Wide Transfers Fail\n");
 			i->f->set_width(sdev->sdev_target, 0);
 		}
@@ -624,31 +642,39 @@
 	if(!sdev->ppr && !sdev->sdtr)
 		return;
 
-	/* now set up to the maximum */
-	DV_SET(offset, 255);
-	DV_SET(period, 1);
-	if (!spi_dv_retrain(sreq, buffer, buffer + len,
-			    spi_dv_device_compare_inquiry))
-		return;
-
-	/* OK, now we have our initial speed set by the read only inquiry
-	 * test, now try an echo buffer test (if the device allows it) */
+	/* see if the device has an echo buffer.  If it does we can
+	 * do the SPI pattern write tests */
 
 	len = 0;
 	if (sdev->ppr)
 		len = spi_dv_device_get_echo_buffer(sreq, buffer);
 
+ retry:
+
+	/* now set up to the maximum */
+	DV_SET(offset, 255);
+	DV_SET(period, 1);
+
 	if (len == 0) {
 		SPI_PRINTK(sdev->sdev_target, 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);
 		len = SPI_MAX_ECHO_BUFFER_SIZE;
 	}
 
-	spi_dv_retrain(sreq, buffer, buffer + len,
-		       spi_dv_device_echo_buffer);
+	if (spi_dv_retrain(sreq, buffer, buffer + len,
+			   spi_dv_device_echo_buffer)
+	    == SPI_COMPARE_SKIP_TEST) {
+		/* OK, the stupid drive can't do a write echo buffer
+		 * test after all, fall back to the read tests */
+		len = 0;
+		goto retry;
+	}
 }
 
 
@@ -788,6 +814,55 @@
 	i->host_attrs[count] = &i->private_host_attrs[count];		\
 	count++
 
+static int spi_device_match(struct attribute_container *cont,
+			    struct device *dev)
+{
+	struct scsi_device *sdev;
+	struct Scsi_Host *shost;
+
+	if (!scsi_is_sdev_device(dev))
+		return 0;
+
+	sdev = to_scsi_device(dev);
+	shost = sdev->host;
+	if (!shost->transportt  || shost->transportt->host_attrs.class
+	    != &spi_host_class.class)
+		return 0;
+	/* Note: this class has no device attributes, so it has
+	 * no per-HBA allocation and thus we don't need to distinguish
+	 * the attribute containers for the device */
+	return 1;
+}
+
+static int spi_target_match(struct attribute_container *cont,
+			    struct device *dev)
+{
+	struct Scsi_Host *shost;
+	struct spi_internal *i;
+
+	if (!scsi_is_target_device(dev))
+		return 0;
+
+	shost = dev_to_shost(dev->parent);
+	if (!shost->transportt  || shost->transportt->host_attrs.class
+	    != &spi_host_class.class)
+		return 0;
+
+	i = to_spi_internal(shost->transportt);
+	
+	return &i->t.target_attrs == cont;
+}
+
+static DECLARE_TRANSPORT_CLASS(spi_transport_class,
+			       "spi_transport",
+			       spi_setup_transport_attrs,
+			       NULL,
+			       NULL);
+
+static DECLARE_ANON_TRANSPORT_CLASS(spi_device_class,
+				    spi_device_match,
+				    spi_device_configure);
+
 struct scsi_transport_template *
 spi_attach_transport(struct spi_function_template *ft)
 {
@@ -800,14 +875,15 @@
 	memset(i, 0, sizeof(struct spi_internal));
 
 
-	i->t.target_attrs = &i->attrs[0];
-	i->t.target_class = &spi_transport_class;
-	i->t.target_setup = &spi_setup_transport_attrs;
-	i->t.device_configure = &spi_configure_device;
+	i->t.target_attrs.class = &spi_transport_class.class;
+	i->t.target_attrs.attrs = &i->attrs[0];
+	i->t.target_attrs.match = spi_target_match;
+	attribute_container_register(&i->t.target_attrs);
 	i->t.target_size = sizeof(struct spi_transport_attrs);
-	i->t.host_attrs = &i->host_attrs[0];
-	i->t.host_class = &spi_host_class;
-	i->t.host_setup = &spi_setup_host_attrs;
+	i->t.host_attrs.class = &spi_host_class.class;
+	i->t.host_attrs.attrs = &i->host_attrs[0];
+	i->t.host_attrs.match = spi_host_match;
+	attribute_container_register(&i->t.host_attrs);
 	i->t.host_size = sizeof(struct spi_host_attrs);
 	i->f = ft;
 
@@ -845,10 +921,28 @@
 {
 	struct spi_internal *i = to_spi_internal(t);
 
+	attribute_container_unregister(&i->t.target_attrs);
+	attribute_container_unregister(&i->t.host_attrs);
+
 	kfree(i);
 }
 EXPORT_SYMBOL(spi_release_transport);
 
+static __init int spi_transport_init(void)
+{
+	int error = transport_class_register(&spi_transport_class);
+	if (error)
+		return error;
+	error = anon_transport_class_register(&spi_device_class);
+	return transport_class_register(&spi_host_class);
+}
+
+static void __exit spi_transport_exit(void)
+{
+	transport_class_unregister(&spi_transport_class);
+	anon_transport_class_unregister(&spi_device_class);
+	transport_class_unregister(&spi_host_class);
+}
 
 MODULE_AUTHOR("Martin Hicks");
 MODULE_DESCRIPTION("SPI Transport Attributes");
diff -Nru a/drivers/scsi/scsicam.c b/drivers/scsi/scsicam.c
--- a/drivers/scsi/scsicam.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/scsi/scsicam.c	2005-03-01 23:39:18 -08:00
@@ -41,6 +41,7 @@
 	}
 	return res;
 }
+EXPORT_SYMBOL(scsi_bios_ptable);
 
 /*
  * Function : int scsicam_bios_param (struct block_device *bdev, ector_t capacity, int *ip)
@@ -94,6 +95,7 @@
 
 	return 0;
 }
+EXPORT_SYMBOL(scsicam_bios_param);
 
 /*
  * Function : static int scsi_partsize(unsigned char *buf, unsigned long 
@@ -175,6 +177,7 @@
 	}
 	return -1;
 }
+EXPORT_SYMBOL(scsi_partsize);
 
 /*
  * Function : static int setsize(unsigned long capacity,unsigned int *cyls,
diff -Nru a/drivers/scsi/sd.c b/drivers/scsi/sd.c
--- a/drivers/scsi/sd.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/scsi/sd.c	2005-03-01 23:39:08 -08:00
@@ -87,6 +87,7 @@
  * Number of allowed retries
  */
 #define SD_MAX_RETRIES		5
+#define SD_PASSTHROUGH_RETRIES	1
 
 static void scsi_disk_release(struct kref *kref);
 
@@ -105,7 +106,7 @@
 };
 
 static DEFINE_IDR(sd_index_idr);
-static spinlock_t sd_index_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(sd_index_lock);
 
 /* This semaphore is used to mediate the 0->1 reference get in the
  * face of object destruction (i.e. we can't allow a get on an
@@ -197,9 +198,11 @@
 
 static void scsi_disk_put(struct scsi_disk *sdkp)
 {
+	struct scsi_device *sdev = sdkp->device;
+
 	down(&sd_ref_sem);
 	kref_put(&sdkp->kref, scsi_disk_release);
-	scsi_device_put(sdkp->device);
+	scsi_device_put(sdev);
 	up(&sd_ref_sem);
 }
 
@@ -217,15 +220,14 @@
 	struct gendisk *disk;
 	sector_t block;
 	struct scsi_device *sdp = SCpnt->device;
+	struct request *rq = SCpnt->request;
 
 	timeout = sdp->timeout;
 
 	/*
-	 * these are already setup, just copy cdb basically
+	 * SG_IO from block layer already setup, just copy cdb basically
 	 */
-	if (SCpnt->request->flags & REQ_BLOCK_PC) {
-		struct request *rq = SCpnt->request;
-
+	if (blk_pc_request(rq)) {
 		if (sizeof(rq->cmd) > sizeof(SCpnt->cmnd))
 			return 0;
 
@@ -242,26 +244,28 @@
 			timeout = rq->timeout;
 
 		SCpnt->transfersize = rq->data_len;
+		SCpnt->allowed = SD_PASSTHROUGH_RETRIES;
 		goto queue;
 	}
 
 	/*
 	 * we only do REQ_CMD and REQ_BLOCK_PC
 	 */
-	if (!(SCpnt->request->flags & REQ_CMD))
+	if (!blk_fs_request(rq))
 		return 0;
 
-	disk = SCpnt->request->rq_disk;
-	block = SCpnt->request->sector;
+	disk = rq->rq_disk;
+	block = rq->sector;
 	this_count = SCpnt->request_bufflen >> 9;
 
 	SCSI_LOG_HLQUEUE(1, printk("sd_init_command: disk=%s, block=%llu, "
-			    "count=%d\n", disk->disk_name, (unsigned long long)block, this_count));
+			    "count=%d\n", disk->disk_name,
+			 (unsigned long long)block, this_count));
 
 	if (!sdp || !scsi_device_online(sdp) ||
- 	    block + SCpnt->request->nr_sectors > get_capacity(disk)) {
+ 	    block + rq->nr_sectors > get_capacity(disk)) {
 		SCSI_LOG_HLQUEUE(2, printk("Finishing %ld sectors\n", 
-				 SCpnt->request->nr_sectors));
+				 rq->nr_sectors));
 		SCSI_LOG_HLQUEUE(2, printk("Retry with 0x%p\n", SCpnt));
 		return 0;
 	}
@@ -289,7 +293,7 @@
 	 * for this.
 	 */
 	if (sdp->sector_size == 1024) {
-		if ((block & 1) || (SCpnt->request->nr_sectors & 1)) {
+		if ((block & 1) || (rq->nr_sectors & 1)) {
 			printk(KERN_ERR "sd: Bad block number requested");
 			return 0;
 		} else {
@@ -298,7 +302,7 @@
 		}
 	}
 	if (sdp->sector_size == 2048) {
-		if ((block & 3) || (SCpnt->request->nr_sectors & 3)) {
+		if ((block & 3) || (rq->nr_sectors & 3)) {
 			printk(KERN_ERR "sd: Bad block number requested");
 			return 0;
 		} else {
@@ -307,7 +311,7 @@
 		}
 	}
 	if (sdp->sector_size == 4096) {
-		if ((block & 7) || (SCpnt->request->nr_sectors & 7)) {
+		if ((block & 7) || (rq->nr_sectors & 7)) {
 			printk(KERN_ERR "sd: Bad block number requested");
 			return 0;
 		} else {
@@ -315,25 +319,24 @@
 			this_count = this_count >> 3;
 		}
 	}
-	if (rq_data_dir(SCpnt->request) == WRITE) {
+	if (rq_data_dir(rq) == WRITE) {
 		if (!sdp->writeable) {
 			return 0;
 		}
 		SCpnt->cmnd[0] = WRITE_6;
 		SCpnt->sc_data_direction = DMA_TO_DEVICE;
-	} else if (rq_data_dir(SCpnt->request) == READ) {
+	} else if (rq_data_dir(rq) == READ) {
 		SCpnt->cmnd[0] = READ_6;
 		SCpnt->sc_data_direction = DMA_FROM_DEVICE;
 	} else {
-		printk(KERN_ERR "sd: Unknown command %lx\n", 
-		       SCpnt->request->flags);
-/* overkill 	panic("Unknown sd command %lx\n", SCpnt->request->flags); */
+		printk(KERN_ERR "sd: Unknown command %lx\n", rq->flags);
+/* overkill 	panic("Unknown sd command %lx\n", rq->flags); */
 		return 0;
 	}
 
 	SCSI_LOG_HLQUEUE(2, printk("%s : %s %d/%ld 512 byte blocks.\n", 
-		disk->disk_name, (rq_data_dir(SCpnt->request) == WRITE) ? 
-		"writing" : "reading", this_count, SCpnt->request->nr_sectors));
+		disk->disk_name, (rq_data_dir(rq) == WRITE) ? 
+		"writing" : "reading", this_count, rq->nr_sectors));
 
 	SCpnt->cmnd[1] = 0;
 	
@@ -385,9 +388,9 @@
 	 */
 	SCpnt->transfersize = sdp->sector_size;
 	SCpnt->underflow = this_count << 9;
+	SCpnt->allowed = SD_MAX_RETRIES;
 
 queue:
-	SCpnt->allowed = SD_MAX_RETRIES;
 	SCpnt->timeout_per_command = timeout;
 
 	/*
@@ -760,15 +763,26 @@
 	int this_count = SCpnt->bufflen;
 	int good_bytes = (result == 0 ? this_count : 0);
 	sector_t block_sectors = 1;
+	u64 first_err_block;
 	sector_t error_sector;
+	struct scsi_sense_hdr sshdr;
+	int sense_valid = 0;
+	int sense_deferred = 0;
+	int info_valid;
+
+	if (result) {
+		sense_valid = scsi_command_normalize_sense(SCpnt, &sshdr);
+		if (sense_valid)
+			sense_deferred = scsi_sense_is_deferred(&sshdr);
+	}
+
 #ifdef CONFIG_SCSI_LOGGING
 	SCSI_LOG_HLCOMPLETE(1, printk("sd_rw_intr: %s: res=0x%x\n", 
 				SCpnt->request->rq_disk->disk_name, result));
-	if (0 != result) {
-		SCSI_LOG_HLCOMPLETE(1, printk("sd_rw_intr: sb[0,2,asc,ascq]"
-				"=%x,%x,%x,%x\n", SCpnt->sense_buffer[0],
-			SCpnt->sense_buffer[2], SCpnt->sense_buffer[12],
-			SCpnt->sense_buffer[13]));
+	if (sense_valid) {
+		SCSI_LOG_HLCOMPLETE(1, printk("sd_rw_intr: sb[respc,sk,asc,"
+				"ascq]=%x,%x,%x,%x\n", sshdr.response_code,
+				sshdr.sense_key, sshdr.asc, sshdr.ascq));
 	}
 #endif
 	/*
@@ -777,19 +791,27 @@
 	   unnecessary additional work such as memcpy's that could be avoided.
 	 */
 
-	/* An error occurred */
-	if (driver_byte(result) != 0 && 	/* An error occurred */
-	    (SCpnt->sense_buffer[0] & 0x7f) == 0x70) { /* Sense current */
-		switch (SCpnt->sense_buffer[2]) {
+	/* 
+	 * If SG_IO from block layer then set good_bytes to stop retries;
+	 * else if errors, check them, and if necessary prepare for
+	 * (partial) retries.
+	 */
+	if (blk_pc_request(SCpnt->request))
+		good_bytes = this_count;
+	else if (driver_byte(result) != 0 &&
+		 sense_valid && !sense_deferred) {
+		switch (sshdr.sense_key) {
 		case MEDIUM_ERROR:
-			if (!(SCpnt->sense_buffer[0] & 0x80))
-				break;
 			if (!blk_fs_request(SCpnt->request))
 				break;
-			error_sector = (SCpnt->sense_buffer[3] << 24) |
-			(SCpnt->sense_buffer[4] << 16) |
-			(SCpnt->sense_buffer[5] << 8) |
-			SCpnt->sense_buffer[6];
+			info_valid = scsi_get_sense_info_fld(
+				SCpnt->sense_buffer, SCSI_SENSE_BUFFERSIZE,
+				&first_err_block);
+			/*
+			 * May want to warn and skip if following cast results
+			 * in actual truncation (if sector_t < 64 bits)
+			 */
+			error_sector = (sector_t)first_err_block;
 			if (SCpnt->request->bio != NULL)
 				block_sectors = bio_sectors(SCpnt->request->bio);
 			switch (SCpnt->device->sector_size) {
@@ -829,7 +851,7 @@
 			 */
 			scsi_print_sense("sd", SCpnt);
 			SCpnt->result = 0;
-			SCpnt->sense_buffer[0] = 0x0;
+			memset(SCpnt->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
 			good_bytes = this_count;
 			break;
 
@@ -858,16 +880,20 @@
 
 static int media_not_present(struct scsi_disk *sdkp, struct scsi_request *srp)
 {
+	struct scsi_sense_hdr sshdr;
+
 	if (!srp->sr_result)
 		return 0;
 	if (!(driver_byte(srp->sr_result) & DRIVER_SENSE))
 		return 0;
-	if (srp->sr_sense_buffer[2] != NOT_READY &&
-	    srp->sr_sense_buffer[2] != UNIT_ATTENTION)
-	    	return 0;
-	if (srp->sr_sense_buffer[12] != 0x3A) /* medium not present */
-		return 0;
-
+	/* not invoked for commands that could return deferred errors */
+	if (scsi_request_normalize_sense(srp, &sshdr)) {
+		if (sshdr.sense_key != NOT_READY &&
+		    sshdr.sense_key != UNIT_ATTENTION)
+			return 0;
+		if (sshdr.asc != 0x3A) /* medium not present */
+			return 0;
+	}
 	set_media_not_present(sdkp);
 	return 1;
 }
@@ -882,6 +908,8 @@
 	unsigned long spintime_value = 0;
 	int retries, spintime;
 	unsigned int the_result;
+	struct scsi_sense_hdr sshdr;
+	int sense_valid = 0;
 
 	spintime = 0;
 
@@ -895,19 +923,22 @@
 			memset((void *) &cmd[1], 0, 9);
 
 			SRpnt->sr_cmd_len = 0;
-			SRpnt->sr_sense_buffer[0] = 0;
-			SRpnt->sr_sense_buffer[2] = 0;
+			memset(SRpnt->sr_sense_buffer, 0,
+			       SCSI_SENSE_BUFFERSIZE);
 			SRpnt->sr_data_direction = DMA_NONE;
 
 			scsi_wait_req (SRpnt, (void *) cmd, (void *) buffer,
 				       0/*512*/, SD_TIMEOUT, SD_MAX_RETRIES);
 
 			the_result = SRpnt->sr_result;
+			if (the_result)
+				sense_valid = scsi_request_normalize_sense(
+							SRpnt, &sshdr);
 			retries++;
 		} while (retries < 3 && 
 			 (!scsi_status_is_good(the_result) ||
 			  ((driver_byte(the_result) & DRIVER_SENSE) &&
-			   SRpnt->sr_sense_buffer[2] == UNIT_ATTENTION)));
+			  sense_valid && sshdr.sense_key == UNIT_ATTENTION)));
 
 		/*
 		 * If the drive has indicated to us that it doesn't have
@@ -921,7 +952,8 @@
 			/* no sense, TUR either succeeded or failed
 			 * with a status error */
 			if(!spintime && !scsi_status_is_good(the_result))
-				printk(KERN_NOTICE "%s: Unit Not Ready, error = 0x%x\n", diskname, the_result);
+				printk(KERN_NOTICE "%s: Unit Not Ready, "
+				       "error = 0x%x\n", diskname, the_result);
 			break;
 		}
 					
@@ -936,15 +968,15 @@
 		 * If manual intervention is required, or this is an
 		 * absent USB storage device, a spinup is meaningless.
 		 */
-		if (SRpnt->sr_sense_buffer[2] == NOT_READY &&
-		    SRpnt->sr_sense_buffer[12] == 4 /* not ready */ &&
-		    SRpnt->sr_sense_buffer[13] == 3) {
+		if (sense_valid &&
+		    sshdr.sense_key == NOT_READY &&
+		    sshdr.asc == 4 && sshdr.ascq == 3) {
 			break;		/* manual intervention required */
 
 		/*
 		 * Issue command to spin up drive when not ready
 		 */
-		} else if (SRpnt->sr_sense_buffer[2] == NOT_READY) {
+		} else if (sense_valid && sshdr.sense_key == NOT_READY) {
 			if (!spintime) {
 				printk(KERN_NOTICE "%s: Spinning up disk...",
 				       diskname);
@@ -953,8 +985,8 @@
 				memset((void *) &cmd[2], 0, 8);
 				cmd[4] = 1;	/* Start spin cycle */
 				SRpnt->sr_cmd_len = 0;
-				SRpnt->sr_sense_buffer[0] = 0;
-				SRpnt->sr_sense_buffer[2] = 0;
+				memset(SRpnt->sr_sense_buffer, 0,
+					SCSI_SENSE_BUFFERSIZE);
 
 				SRpnt->sr_data_direction = DMA_NONE;
 				scsi_wait_req(SRpnt, (void *)cmd, 
@@ -970,7 +1002,8 @@
 			/* we don't understand the sense code, so it's
 			 * probably pointless to loop */
 			if(!spintime) {
-				printk(KERN_NOTICE "%s: Unit Not Ready, sense:\n", diskname);
+				printk(KERN_NOTICE "%s: Unit Not Ready, "
+					"sense:\n", diskname);
 				scsi_print_req_sense("", SRpnt);
 			}
 			break;
@@ -998,6 +1031,8 @@
 	int the_result, retries;
 	int sector_size = 0;
 	int longrc = 0;
+	struct scsi_sense_hdr sshdr;
+	int sense_valid = 0;
 
 repeat:
 	retries = 3;
@@ -1015,8 +1050,7 @@
 		}
 		
 		SRpnt->sr_cmd_len = 0;
-		SRpnt->sr_sense_buffer[0] = 0;
-		SRpnt->sr_sense_buffer[2] = 0;
+		memset(SRpnt->sr_sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
 		SRpnt->sr_data_direction = DMA_FROM_DEVICE;
 
 		scsi_wait_req(SRpnt, (void *) cmd, (void *) buffer,
@@ -1026,6 +1060,9 @@
 			return;
 
 		the_result = SRpnt->sr_result;
+		if (the_result)
+			sense_valid = scsi_request_normalize_sense(SRpnt,
+								   &sshdr);
 		retries--;
 
 	} while (the_result && retries);
@@ -1047,7 +1084,7 @@
 		/* Set dirty bit for removable devices if not ready -
 		 * sometimes drives will not report this properly. */
 		if (sdp->removable &&
-		    SRpnt->sr_sense_buffer[2] == NOT_READY)
+		    sense_valid && sshdr.sense_key == NOT_READY)
 			sdp->changed = 1;
 
 		/* Either no media are present but the drive didn't tell us,
@@ -1082,9 +1119,12 @@
 				       " READ CAPACITY(16).\n", diskname);
 				longrc = 1;
 				goto repeat;
-			} else {
-				printk(KERN_ERR "%s: too big for kernel.  Assuming maximum 2Tb\n", diskname);
 			}
+			printk(KERN_ERR "%s: too big for this kernel.  Use a "
+			       "kernel compiled with support for large block "
+			       "devices.\n", diskname);
+			sdkp->capacity = 0;
+			goto got_data;
 		}
 		sdkp->capacity = 1 + (((sector_t)buffer[0] << 24) |
 			(buffer[1] << 16) |
@@ -1252,6 +1292,7 @@
 	const int dbd = 0;	   /* DBD */
 	const int modepage = 0x08; /* current values, cache page */
 	struct scsi_mode_data data;
+	struct scsi_sense_hdr sshdr;
 
 	if (sdkp->device->skip_ms_page_8)
 		goto defaults;
@@ -1301,17 +1342,14 @@
 	}
 
 bad_sense:
-	if ((SRpnt->sr_sense_buffer[0] & 0x70) == 0x70
-	     && (SRpnt->sr_sense_buffer[2] & 0x0f) == ILLEGAL_REQUEST
-	     /* ASC 0x24 ASCQ 0x00: Invalid field in CDB */
-	     && SRpnt->sr_sense_buffer[12] == 0x24
-	     && SRpnt->sr_sense_buffer[13] == 0x00) {
+	if (scsi_request_normalize_sense(SRpnt, &sshdr) &&
+	    sshdr.sense_key == ILLEGAL_REQUEST &&
+	    sshdr.asc == 0x24 && sshdr.ascq == 0x0)
 		printk(KERN_NOTICE "%s: cache data unavailable\n",
-		       diskname);
-	} else {
+		       diskname);	/* Invalid field in CDB */
+	else
 		printk(KERN_ERR "%s: asking for cache data failed\n",
 		       diskname);
-	}
 
 defaults:
 	printk(KERN_ERR "%s: assuming drive cache: write through\n",
diff -Nru a/drivers/scsi/sg.c b/drivers/scsi/sg.c
--- a/drivers/scsi/sg.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/scsi/sg.c	2005-03-01 23:38:56 -08:00
@@ -7,7 +7,7 @@
  * Original driver (sg.c):
  *        Copyright (C) 1992 Lawrence Foard
  * Version 2 and 3 extensions to driver:
- *        Copyright (C) 1998 - 2004 Douglas Gilbert
+ *        Copyright (C) 1998 - 2005 Douglas Gilbert
  *
  *  Modified  19-JAN-1998  Richard Gooch <rgooch@atnf.csiro.au>  Devfs support
  *
@@ -18,8 +18,8 @@
  *
  */
 
-static int sg_version_num = 30531;	/* 2 digits for each component */
-#define SG_VERSION_STR "3.5.31"
+static int sg_version_num = 30532;	/* 2 digits for each component */
+#define SG_VERSION_STR "3.5.32"
 
 /*
  *  D. P. Gilbert (dgilbert@interlog.com, dougg@triode.net.au), notes:
@@ -60,7 +60,7 @@
 
 #ifdef CONFIG_SCSI_PROC_FS
 #include <linux/proc_fs.h>
-static char *sg_version_date = "20040516";
+static char *sg_version_date = "20050117";
 
 static int sg_proc_init(void);
 static void sg_proc_cleanup(void);
@@ -108,7 +108,7 @@
 
 static Scsi_Request *dummy_cmdp;	/* only used for sizeof */
 
-static rwlock_t sg_dev_arr_lock = RW_LOCK_UNLOCKED;	/* Also used to lock
+static DEFINE_RWLOCK(sg_dev_arr_lock);	/* Also used to lock
 							   file descriptor list for device */
 
 static struct class_interface sg_interface = {
@@ -1282,6 +1282,8 @@
 	srp->header.duration =
 	    jiffies_to_msecs(jiffies - srp->header.duration);
 	if (0 != SRpnt->sr_result) {
+		struct scsi_sense_hdr sshdr;
+
 		memcpy(srp->sense_b, SRpnt->sr_sense_buffer,
 		       sizeof (srp->sense_b));
 		srp->header.status = 0xff & SRpnt->sr_result;
@@ -1296,11 +1298,12 @@
 
 		/* Following if statement is a patch supplied by Eric Youngdale */
 		if (driver_byte(SRpnt->sr_result) != 0
-		    && (SRpnt->sr_sense_buffer[0] & 0x7f) == 0x70
-		    && (SRpnt->sr_sense_buffer[2] & 0xf) == UNIT_ATTENTION
+		    && scsi_command_normalize_sense(SCpnt, &sshdr)
+		    && !scsi_sense_is_deferred(&sshdr)
+		    && sshdr.sense_key == UNIT_ATTENTION
 		    && sdp->device->removable) {
-			/* Detected disc change. Set the bit - this may be used if */
-			/* there are filesystems using this device. */
+			/* Detected possible disc change. Set the bit - this */
+			/* may be used if there are filesystems using this device */
 			sdp->device->changed = 1;
 		}
 	}
@@ -1573,8 +1576,8 @@
  * of sysfs parameters (which module_param doesn't yet support).
  * Sysfs parameters defined explicitly below.
  */
-module_param_named(def_reserved_size, def_reserved_size, int, 0);
-module_param_named(allow_dio, sg_allow_dio, int, 0);
+module_param_named(def_reserved_size, def_reserved_size, int, S_IRUGO);
+module_param_named(allow_dio, sg_allow_dio, int, S_IRUGO | S_IWUSR);
 
 MODULE_AUTHOR("Douglas Gilbert");
 MODULE_DESCRIPTION("SCSI generic (sg) driver");
@@ -2606,9 +2609,14 @@
 	free_pages((unsigned long) buff, order);
 }
 
+#ifndef MAINTENANCE_IN_CMD
+#define MAINTENANCE_IN_CMD 0xa3
+#endif
+
 static unsigned char allow_ops[] = { TEST_UNIT_READY, REQUEST_SENSE,
 	INQUIRY, READ_CAPACITY, READ_BUFFER, READ_6, READ_10, READ_12,
-	MODE_SENSE, MODE_SENSE_10, LOG_SENSE
+	READ_16, MODE_SENSE, MODE_SENSE_10, LOG_SENSE, REPORT_LUNS,
+	SERVICE_ACTION_IN, RECEIVE_DIAGNOSTIC, READ_LONG, MAINTENANCE_IN_CMD
 };
 
 static int
diff -Nru a/drivers/scsi/sim710.c b/drivers/scsi/sim710.c
--- a/drivers/scsi/sim710.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/scsi/sim710.c	2005-03-01 23:39:09 -08:00
@@ -53,7 +53,7 @@
 MODULE_DESCRIPTION("Simple NCR53C710 driver");
 MODULE_LICENSE("GPL");
 
-MODULE_PARM(sim710, "s");
+module_param(sim710, charp, 0);
 
 #ifdef MODULE
 #define ARG_SEP ' '
diff -Nru a/drivers/scsi/sr.c b/drivers/scsi/sr.c
--- a/drivers/scsi/sr.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/scsi/sr.c	2005-03-01 23:39:18 -08:00
@@ -59,9 +59,6 @@
 #include "sr.h"
 
 
-MODULE_PARM(xa_test, "i");	/* see sr_ioctl.c */
-
-
 #define SR_DISKS	256
 
 #define MAX_RETRIES	3
@@ -88,7 +85,7 @@
 };
 
 static unsigned long sr_index_bits[SR_DISKS / BITS_PER_LONG];
-static spinlock_t sr_index_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(sr_index_lock);
 
 /* This semaphore is used to mediate the 0->1 reference get in the
  * face of object destruction (i.e. we can't allow a get on an
@@ -155,9 +152,11 @@
 
 static inline void scsi_cd_put(struct scsi_cd *cd)
 {
+	struct scsi_device *sdev = cd->device;
+
 	down(&sr_ref_sem);
 	kref_put(&cd->kref, sr_kref_release);
-	scsi_device_put(cd->device);
+	scsi_device_put(sdev);
 	up(&sr_ref_sem);
 }
 
@@ -545,7 +544,6 @@
 	return 0;
 
 error_out:
-	scsi_cd_put(cd);
 	return retval;	
 }
 
diff -Nru a/drivers/scsi/sr_ioctl.c b/drivers/scsi/sr_ioctl.c
--- a/drivers/scsi/sr_ioctl.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/scsi/sr_ioctl.c	2005-03-01 23:39:07 -08:00
@@ -29,6 +29,9 @@
  * It is off by default and can be turned on with this module parameter */
 static int xa_test = 0;
 
+module_param(xa_test, int, S_IRUGO | S_IWUSR);
+
+
 #define IOCTL_RETRIES 3
 
 /* ATAPI drives don't have a SCMD_PLAYAUDIO_TI command.  When these drives
diff -Nru a/drivers/scsi/st.c b/drivers/scsi/st.c
--- a/drivers/scsi/st.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/scsi/st.c	2005-03-01 23:39:07 -08:00
@@ -167,7 +167,7 @@
    24 bits) */
 #define SET_DENS_AND_BLK 0x10001
 
-static rwlock_t st_dev_arr_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(st_dev_arr_lock);
 
 static int st_fixed_buffer_size = ST_FIXED_BUFFER_SIZE;
 static int st_max_sg_segs = ST_MAX_SG;
diff -Nru a/drivers/scsi/sym53c416.c b/drivers/scsi/sym53c416.c
--- a/drivers/scsi/sym53c416.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/scsi/sym53c416.c	2005-03-01 23:38:52 -08:00
@@ -239,7 +239,7 @@
 	outb((len & 0xFF0000) >> 16, base + TC_HIGH);
 }
 
-static spinlock_t sym53c416_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(sym53c416_lock);
 
 /* Returns the number of bytes read */
 static __inline__ unsigned int sym53c416_read(int base, unsigned char *buffer, unsigned int len)
diff -Nru a/drivers/scsi/sym53c8xx_2/sym_conf.h b/drivers/scsi/sym53c8xx_2/sym_conf.h
--- a/drivers/scsi/sym53c8xx_2/sym_conf.h	2005-03-01 23:39:09 -08:00
+++ b/drivers/scsi/sym53c8xx_2/sym_conf.h	2005-03-01 23:39:09 -08:00
@@ -79,14 +79,6 @@
 /* #define SYM_CONF_IARB_SUPPORT */
 
 /*
- *  Number of lists for the optimization of the IO timeout handling.
- *  Not used under FreeBSD and Linux.
- */
-#ifndef SYM_CONF_TIMEOUT_ORDER_MAX
-#define SYM_CONF_TIMEOUT_ORDER_MAX	(8)
-#endif
-
-/*
  *  Only relevant if IARB support configured.
  *  - Max number of successive settings of IARB hints.
  *  - Set IARB on arbitration lost.
diff -Nru a/drivers/scsi/sym53c8xx_2/sym_defs.h b/drivers/scsi/sym53c8xx_2/sym_defs.h
--- a/drivers/scsi/sym53c8xx_2/sym_defs.h	2005-03-01 23:38:55 -08:00
+++ b/drivers/scsi/sym53c8xx_2/sym_defs.h	2005-03-01 23:38:55 -08:00
@@ -40,30 +40,10 @@
 #ifndef SYM_DEFS_H
 #define SYM_DEFS_H
 
-#define SYM_VERSION "2.1.18m"
+#define SYM_VERSION "2.1.18n"
 #define SYM_DRIVER_NAME	"sym-" SYM_VERSION
 
 /*
- *  PCI device identifier of SYMBIOS chips.
- */
-#define PCI_ID_SYM53C810	PCI_DEVICE_ID_NCR_53C810
-#define PCI_ID_SYM53C810AP	PCI_DEVICE_ID_LSI_53C810AP
-#define PCI_ID_SYM53C815	PCI_DEVICE_ID_NCR_53C815
-#define PCI_ID_SYM53C820	PCI_DEVICE_ID_NCR_53C820
-#define PCI_ID_SYM53C825	PCI_DEVICE_ID_NCR_53C825
-#define PCI_ID_SYM53C860	PCI_DEVICE_ID_NCR_53C860
-#define PCI_ID_SYM53C875	PCI_DEVICE_ID_NCR_53C875
-#define PCI_ID_SYM53C875_2	PCI_DEVICE_ID_NCR_53C875J
-#define PCI_ID_SYM53C885	PCI_DEVICE_ID_NCR_53C885
-#define PCI_ID_SYM53C895	PCI_DEVICE_ID_NCR_53C895
-#define PCI_ID_SYM53C896	PCI_DEVICE_ID_NCR_53C896
-#define PCI_ID_SYM53C895A	PCI_DEVICE_ID_LSI_53C895A
-#define PCI_ID_SYM53C875A	PCI_DEVICE_ID_LSI_53C875A
-#define PCI_ID_LSI53C1010_33	PCI_DEVICE_ID_LSI_53C1010_33
-#define PCI_ID_LSI53C1010_66	PCI_DEVICE_ID_LSI_53C1010_66
-#define PCI_ID_LSI53C1510D	PCI_DEVICE_ID_LSI_53C1510
-
-/*
  *	SYM53C8XX device features descriptor.
  */
 struct sym_pci_chip {
@@ -764,27 +744,27 @@
 #define	M_RESTORE_DP	RESTORE_POINTERS
 #define	M_DISCONNECT	DISCONNECT
 #define	M_ID_ERROR	INITIATOR_ERROR
-#define	M_ABORT		ABORT
+#define	M_ABORT		ABORT_TASK_SET
 #define	M_REJECT	MESSAGE_REJECT
 #define	M_NOOP		NOP
 #define	M_PARITY	MSG_PARITY_ERROR
 #define	M_LCOMPLETE	LINKED_CMD_COMPLETE
 #define	M_FCOMPLETE	LINKED_FLG_CMD_COMPLETE
-#define	M_RESET		BUS_DEVICE_RESET
-#define	M_ABORT_TAG	(0x0d)
-#define	M_CLEAR_QUEUE	(0x0e)
+#define	M_RESET		TARGET_RESET
+#define	M_ABORT_TAG	ABORT_TASK
+#define	M_CLEAR_QUEUE	CLEAR_TASK_SET
 #define	M_INIT_REC	INITIATE_RECOVERY
 #define	M_REL_REC	RELEASE_RECOVERY
 #define	M_TERMINATE	(0x11)
 #define	M_SIMPLE_TAG	SIMPLE_QUEUE_TAG
 #define	M_HEAD_TAG	HEAD_OF_QUEUE_TAG
 #define	M_ORDERED_TAG	ORDERED_QUEUE_TAG
-#define	M_IGN_RESIDUE	(0x23)
+#define	M_IGN_RESIDUE	IGNORE_WIDE_RESIDUE
 
 #define	M_X_MODIFY_DP	EXTENDED_MODIFY_DATA_POINTER
 #define	M_X_SYNC_REQ	EXTENDED_SDTR
 #define	M_X_WIDE_REQ	EXTENDED_WDTR
-#define	M_X_PPR_REQ	(0x04)
+#define	M_X_PPR_REQ	EXTENDED_PPR
 
 /*
  *	PPR protocol options
diff -Nru a/drivers/scsi/sym53c8xx_2/sym_fw.c b/drivers/scsi/sym53c8xx_2/sym_fw.c
--- a/drivers/scsi/sym53c8xx_2/sym_fw.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/scsi/sym53c8xx_2/sym_fw.c	2005-03-01 23:39:17 -08:00
@@ -223,13 +223,13 @@
 	 *  Remove a couple of work-arounds specific to C1010 if 
 	 *  they are not desirable. See `sym_fw2.h' for more details.
 	 */
-	if (!(np->device_id == PCI_ID_LSI53C1010_66 &&
+	if (!(np->device_id == PCI_DEVICE_ID_LSI_53C1010_66 &&
 	      np->revision_id < 0x1 &&
 	      np->pciclk_khz < 60000)) {
 		scripta0->datao_phase[0] = cpu_to_scr(SCR_NO_OP);
 		scripta0->datao_phase[1] = cpu_to_scr(0);
 	}
-	if (!(np->device_id == PCI_ID_LSI53C1010_33 &&
+	if (!(np->device_id == PCI_DEVICE_ID_LSI_53C1010_33 &&
 	      /* np->revision_id < 0xff */ 1)) {
 		scripta0->sel_done[0] = cpu_to_scr(SCR_NO_OP);
 		scripta0->sel_done[1] = cpu_to_scr(0);
diff -Nru a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c
--- a/drivers/scsi/sym53c8xx_2/sym_glue.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/scsi/sym53c8xx_2/sym_glue.c	2005-03-01 23:39:18 -08:00
@@ -55,6 +55,15 @@
 #define NAME53C		"sym53c"
 #define NAME53C8XX	"sym53c8xx"
 
+/* SPARC just has to be different ... */
+#ifdef __sparc__
+#define IRQ_FMT "%s"
+#define IRQ_PRM(x) __irq_itoa(x)
+#else
+#define IRQ_FMT "%d"
+#define IRQ_PRM(x) (x)
+#endif
+
 struct sym_driver_setup sym_driver_setup = SYM_LINUX_DRIVER_SETUP;
 unsigned int sym_debug_flags = 0;
 
@@ -147,7 +156,7 @@
 }
 
 /* This lock protects only the memory allocation/free.  */
-spinlock_t sym53c8xx_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(sym53c8xx_lock);
 
 static struct scsi_transport_template *sym2_transport_template = NULL;
 
@@ -285,7 +294,7 @@
 	ccb->scsi_done(ccb);
 }
 
-void sym_xpt_done2(struct sym_hcb *np, struct scsi_cmnd *ccb, int cam_status)
+static void sym_xpt_done2(struct sym_hcb *np, struct scsi_cmnd *ccb, int cam_status)
 {
 	sym_set_cam_status(ccb, cam_status);
 	sym_xpt_done(np, ccb);
@@ -379,7 +388,7 @@
 			/*
 			 *  Bounce back the sense data to user.
 			 */
-			bzero(&csio->sense_buffer, sizeof(csio->sense_buffer));
+			memset(&csio->sense_buffer, 0, sizeof(csio->sense_buffer));
 			memcpy(csio->sense_buffer, cp->sns_bbuf,
 			      min(sizeof(csio->sense_buffer),
 				  (size_t)SYM_SNS_BBUF_LEN));
@@ -513,7 +522,7 @@
 	}
 
 	/*
-	 *  Retreive the target descriptor.
+	 *  Retrieve the target descriptor.
 	 */
 	tp = &np->target[ccb->device->id];
 
@@ -1277,7 +1286,7 @@
 	int		arg_len;
 	u_long 		target;
 
-	bzero(uc, sizeof(*uc));
+	memset(uc, 0, sizeof(*uc));
 
 	if (len > 0 && ptr[len-1] == '\n')
 		--len;
@@ -1467,18 +1476,8 @@
 	copy_info(&info, "Chip " NAME53C "%s, device id 0x%x, "
 			 "revision id 0x%x\n",
 			 np->s.chip_name, np->device_id, np->revision_id);
-	copy_info(&info, "At PCI address %s, "
-#ifdef __sparc__
-		"IRQ %s\n",
-#else
-		"IRQ %d\n",
-#endif
-		pci_name(np->s.device),
-#ifdef __sparc__
-		__irq_itoa(np->s.irq));
-#else
-		(int) np->s.irq);
-#endif
+	copy_info(&info, "At PCI address %s, IRQ " IRQ_FMT "\n",
+		pci_name(np->s.device), IRQ_PRM(np->s.irq));
 	copy_info(&info, "Min. period factor %d, %s SCSI BUS%s\n",
 			 (int) (np->minsync_dt ? np->minsync_dt : np->minsync),
 			 np->maxwide ? "Wide" : "Narrow",
@@ -1558,32 +1557,23 @@
  */
 static int sym_setup_bus_dma_mask(struct sym_hcb *np)
 {
-#if   SYM_CONF_DMA_ADDRESSING_MODE == 0
-	if (pci_set_dma_mask(np->s.device, 0xffffffffUL))
-		goto out_err32;
-#else
+#if SYM_CONF_DMA_ADDRESSING_MODE > 0
 #if   SYM_CONF_DMA_ADDRESSING_MODE == 1
-#define	PciDmaMask	0xffffffffffULL
+#define	DMA_DAC_MASK	0x000000ffffffffffULL /* 40-bit */
 #elif SYM_CONF_DMA_ADDRESSING_MODE == 2
-#define	PciDmaMask	0xffffffffffffffffULL
+#define	DMA_DAC_MASK	DMA_64BIT_MASK
 #endif
-	if (np->features & FE_DAC) {
-		if (!pci_set_dma_mask(np->s.device, PciDmaMask)) {
-			np->use_dac = 1;
-			printf_info("%s: using 64 bit DMA addressing\n",
-					sym_name(np));
-		} else {
-			if (pci_set_dma_mask(np->s.device, 0xffffffffUL))
-				goto out_err32;
-		}
+	if ((np->features & FE_DAC) &&
+			!pci_set_dma_mask(np->s.device, DMA_DAC_MASK)) {
+		np->use_dac = 1;
+		return 0;
 	}
-#undef	PciDmaMask
 #endif
-	return 0;
 
-out_err32:
-	printf_warning("%s: 32 BIT DMA ADDRESSING NOT SUPPORTED\n",
-			sym_name(np));
+	if (!pci_set_dma_mask(np->s.device, DMA_32BIT_MASK))
+		return 0;
+
+	printf_warning("%s: No suitable DMA available\n", sym_name(np));
 	return -1;
 }
 
@@ -1606,19 +1596,9 @@
 	struct sym_fw *fw;
 
 	printk(KERN_INFO
-		"sym%d: <%s> rev 0x%x at pci %s "
-#ifdef __sparc__
-		"irq %s\n",
-#else
-		"irq %d\n",
-#endif
+		"sym%d: <%s> rev 0x%x at pci %s irq " IRQ_FMT "\n",
 		unit, dev->chip.name, dev->chip.revision_id,
-		pci_name(dev->pdev),
-#ifdef __sparc__
-		__irq_itoa(dev->s.irq));
-#else
-		dev->s.irq);
-#endif
+		pci_name(dev->pdev), IRQ_PRM(dev->s.irq));
 
 	/*
 	 *  Get the firmware for this chip.
@@ -1672,9 +1652,6 @@
 	strlcpy(np->s.chip_name, dev->chip.name, sizeof(np->s.chip_name));
 	sprintf(np->s.inst_name, "sym%d", np->s.unit);
 
-	/*
-	 *  Ask/tell the system about DMA addressing.
-	 */
 	if (sym_setup_bus_dma_mask(np))
 		goto attach_failed;
 
@@ -2010,7 +1987,7 @@
  * the preset SCSI ID (which may be zero) must be read in from
  * a special configuration space register of the 875.
  */
-void sym_config_pqs(struct pci_dev *pdev, struct sym_device *sym_dev)
+static void sym_config_pqs(struct pci_dev *pdev, struct sym_device *sym_dev)
 {
 	int slot;
 	u8 tmp;
diff -Nru a/drivers/scsi/sym53c8xx_2/sym_glue.h b/drivers/scsi/sym53c8xx_2/sym_glue.h
--- a/drivers/scsi/sym53c8xx_2/sym_glue.h	2005-03-01 23:39:17 -08:00
+++ b/drivers/scsi/sym53c8xx_2/sym_glue.h	2005-03-01 23:39:17 -08:00
@@ -58,13 +58,6 @@
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_host.h>
 
-#ifndef bzero
-#define bzero(d, n)	memset((d), 0, (n))
-#endif
-
-/*
- *  General driver includes.
- */
 #include "sym_conf.h"
 #include "sym_defs.h"
 #include "sym_misc.h"
@@ -123,14 +116,6 @@
 typedef struct sym_tcb *tcb_p;
 typedef struct sym_lcb *lcb_p;
 typedef struct sym_ccb *ccb_p;
-typedef struct sym_hcb *hcb_p;
-
-/*
- *  Define a reference to the O/S dependent IO request.
- */
-typedef struct scsi_cmnd *cam_ccb_p;	/* Generic */
-typedef struct scsi_cmnd *cam_scsiio_p;/* SCSI I/O */
-
 
 /*
  *  IO functions definition for big/little endian CPU support.
@@ -525,7 +510,7 @@
 /*
  *  Async handler for negotiations.
  */
-void sym_xpt_async_nego_wide(hcb_p np, int target);
+void sym_xpt_async_nego_wide(struct sym_hcb *np, int target);
 #define sym_xpt_async_nego_sync(np, target)	\
 	sym_announce_transfer_rate(np, target)
 #define sym_xpt_async_nego_ppr(np, target)	\
@@ -534,14 +519,14 @@
 /*
  *  Build CAM result for a successful IO and for a failed IO.
  */
-static __inline void sym_set_cam_result_ok(hcb_p np, ccb_p cp, int resid)
+static __inline void sym_set_cam_result_ok(struct sym_hcb *np, ccb_p cp, int resid)
 {
 	struct scsi_cmnd *cmd = cp->cam_ccb;
 
 	cmd->resid = resid;
 	cmd->result = (((DID_OK) << 16) + ((cp->ssss_status) & 0x7f));
 }
-void sym_set_cam_result_error(hcb_p np, ccb_p cp, int resid);
+void sym_set_cam_result_error(struct sym_hcb *np, ccb_p cp, int resid);
 
 /*
  *  Other O/S specific methods.
@@ -549,13 +534,12 @@
 #define sym_cam_target_id(ccb)	(ccb)->target
 #define sym_cam_target_lun(ccb)	(ccb)->lun
 #define	sym_freeze_cam_ccb(ccb)	do { ; } while (0)
-void sym_xpt_done(hcb_p np, cam_ccb_p ccb);
-void sym_xpt_done2(hcb_p np, cam_ccb_p ccb, int cam_status);
+void sym_xpt_done(struct sym_hcb *np, struct scsi_cmnd *ccb);
 void sym_print_addr (ccb_p cp);
-void sym_xpt_async_bus_reset(hcb_p np);
-void sym_xpt_async_sent_bdr(hcb_p np, int target);
-int  sym_setup_data_and_start (hcb_p np, cam_scsiio_p csio, ccb_p cp);
-void sym_log_bus_error(hcb_p np);
-void sym_sniff_inquiry(hcb_p np, struct scsi_cmnd *cmd, int resid);
+void sym_xpt_async_bus_reset(struct sym_hcb *np);
+void sym_xpt_async_sent_bdr(struct sym_hcb *np, int target);
+int  sym_setup_data_and_start (struct sym_hcb *np, struct scsi_cmnd *csio, ccb_p cp);
+void sym_log_bus_error(struct sym_hcb *np);
+void sym_sniff_inquiry(struct sym_hcb *np, struct scsi_cmnd *cmd, int resid);
 
 #endif /* SYM_GLUE_H */
diff -Nru a/drivers/scsi/sym53c8xx_2/sym_hipd.c b/drivers/scsi/sym53c8xx_2/sym_hipd.c
--- a/drivers/scsi/sym53c8xx_2/sym_hipd.c	2005-03-01 23:38:44 -08:00
+++ b/drivers/scsi/sym53c8xx_2/sym_hipd.c	2005-03-01 23:38:44 -08:00
@@ -47,14 +47,14 @@
 /*
  *  Needed function prototypes.
  */
-static void sym_int_ma (hcb_p np);
-static void sym_int_sir (hcb_p np);
-static ccb_p sym_alloc_ccb(hcb_p np);
-static ccb_p sym_ccb_from_dsa(hcb_p np, u32 dsa);
-static void sym_alloc_lcb_tags (hcb_p np, u_char tn, u_char ln);
-static void sym_complete_error (hcb_p np, ccb_p cp);
-static void sym_complete_ok (hcb_p np, ccb_p cp);
-static int sym_compute_residual(hcb_p np, ccb_p cp);
+static void sym_int_ma (struct sym_hcb *np);
+static void sym_int_sir (struct sym_hcb *np);
+static ccb_p sym_alloc_ccb(struct sym_hcb *np);
+static ccb_p sym_ccb_from_dsa(struct sym_hcb *np, u32 dsa);
+static void sym_alloc_lcb_tags (struct sym_hcb *np, u_char tn, u_char ln);
+static void sym_complete_error (struct sym_hcb *np, ccb_p cp);
+static void sym_complete_ok (struct sym_hcb *np, ccb_p cp);
+static int sym_compute_residual(struct sym_hcb *np, ccb_p cp);
 
 /*
  *  Returns the name of this driver.
@@ -86,12 +86,12 @@
  *  Print something which allows to retrieve the controler type, 
  *  unit, target, lun concerned by a kernel message.
  */
-static void sym_print_target (hcb_p np, int target)
+static void sym_print_target (struct sym_hcb *np, int target)
 {
 	printf ("%s:%d:", sym_name(np), target);
 }
 
-static void sym_print_lun(hcb_p np, int target, int lun)
+static void sym_print_lun(struct sym_hcb *np, int target, int lun)
 {
 	printf ("%s:%d:%d:", sym_name(np), target, lun);
 }
@@ -126,7 +126,7 @@
 	printf (".\n");
 }
 
-static void sym_print_nego_msg (hcb_p np, int target, char *label, u_char *msg)
+static void sym_print_nego_msg (struct sym_hcb *np, int target, char *label, u_char *msg)
 {
 	PRINT_TARGET(np, target);
 	if (label)
@@ -184,7 +184,7 @@
  *  On the other hand, LVD devices need some delay 
  *  to settle and report actual BUS mode in STEST4.
  */
-static void sym_chip_reset (hcb_p np)
+static void sym_chip_reset (struct sym_hcb *np)
 {
 	OUTB (nc_istat, SRST);
 	UDELAY (10);
@@ -201,7 +201,7 @@
  *  So, we need to abort the current operation prior to 
  *  soft resetting the chip.
  */
-static void sym_soft_reset (hcb_p np)
+static void sym_soft_reset (struct sym_hcb *np)
 {
 	u_char istat = 0;
 	int i;
@@ -234,12 +234,12 @@
  *
  *  The interrupt handler will reinitialize the chip.
  */
-static void sym_start_reset(hcb_p np)
+static void sym_start_reset(struct sym_hcb *np)
 {
 	(void) sym_reset_scsi_bus(np, 1);
 }
  
-int sym_reset_scsi_bus(hcb_p np, int enab_int)
+int sym_reset_scsi_bus(struct sym_hcb *np, int enab_int)
 {
 	u32 term;
 	int retv = 0;
@@ -293,7 +293,7 @@
 /*
  *  Select SCSI clock frequency
  */
-static void sym_selectclock(hcb_p np, u_char scntl3)
+static void sym_selectclock(struct sym_hcb *np, u_char scntl3)
 {
 	/*
 	 *  If multiplier not present or not selected, leave here.
@@ -348,7 +348,7 @@
 /*
  *  calculate SCSI clock frequency (in KHz)
  */
-static unsigned getfreq (hcb_p np, int gen)
+static unsigned getfreq (struct sym_hcb *np, int gen)
 {
 	unsigned int ms = 0;
 	unsigned int f;
@@ -420,7 +420,7 @@
 	return f;
 }
 
-static unsigned sym_getfreq (hcb_p np)
+static unsigned sym_getfreq (struct sym_hcb *np)
 {
 	u_int f1, f2;
 	int gen = 8;
@@ -435,7 +435,7 @@
 /*
  *  Get/probe chip SCSI clock frequency
  */
-static void sym_getclock (hcb_p np, int mult)
+static void sym_getclock (struct sym_hcb *np, int mult)
 {
 	unsigned char scntl3 = np->sv_scntl3;
 	unsigned char stest1 = np->sv_stest1;
@@ -492,7 +492,7 @@
 /*
  *  Get/probe PCI clock frequency
  */
-static int sym_getpciclock (hcb_p np)
+static int sym_getpciclock (struct sym_hcb *np)
 {
 	int f = 0;
 
@@ -528,7 +528,7 @@
  *  synchronous factor period.
  */
 static int 
-sym_getsync(hcb_p np, u_char dt, u_char sfac, u_char *divp, u_char *fakp)
+sym_getsync(struct sym_hcb *np, u_char dt, u_char sfac, u_char *divp, u_char *fakp)
 {
 	u32	clk = np->clock_khz;	/* SCSI clock frequency in kHz	*/
 	int	div = np->clock_divn;	/* Number of divisors supported	*/
@@ -648,7 +648,7 @@
 /*
  *  Set initial io register bits from burst code.
  */
-static __inline void sym_init_burst(hcb_p np, u_char bc)
+static __inline void sym_init_burst(struct sym_hcb *np, u_char bc)
 {
 	np->rv_ctest4	&= ~0x80;
 	np->rv_dmode	&= ~(0x3 << 6);
@@ -668,7 +668,7 @@
 /*
  * Print out the list of targets that have some flag disabled by user.
  */
-static void sym_print_targets_flag(hcb_p np, int mask, char *msg)
+static void sym_print_targets_flag(struct sym_hcb *np, int mask, char *msg)
 {
 	int cnt;
 	int i;
@@ -696,7 +696,7 @@
  *  is not safe on paper, but it seems to work quite 
  *  well. :)
  */
-static void sym_save_initial_setting (hcb_p np)
+static void sym_save_initial_setting (struct sym_hcb *np)
 {
 	np->sv_scntl0	= INB(nc_scntl0) & 0x0a;
 	np->sv_scntl3	= INB(nc_scntl3) & 0x07;
@@ -716,44 +716,11 @@
 		np->sv_ctest5	= INB(nc_ctest5) & 0x24;
 }
 
-#ifdef CONFIG_PARISC
-static u32 parisc_setup_hcb(hcb_p np, u32 period)
-{
-	unsigned long pdc_period;
-	char scsi_mode;
-	struct hardware_path hwpath;
-
-	/* Host firmware (PDC) keeps a table for crippling SCSI capabilities.
-	 * Many newer machines export one channel of 53c896 chip
-	 * as SE, 50-pin HD.  Also used for Multi-initiator SCSI clusters
-	 * to set the SCSI Initiator ID.
-	 */
-	get_pci_node_path(np->s.device, &hwpath);
-	if (!pdc_get_initiator(&hwpath, &np->myaddr, &pdc_period,
-				&np->maxwide, &scsi_mode))
-		return period;
-
-	if (scsi_mode >= 0) {
-		/* C3000 PDC reports period/mode */
-		SYM_SETUP_SCSI_DIFF = 0;
-		switch(scsi_mode) {
-		case 0:	np->scsi_mode = SMODE_SE; break;
-		case 1:	np->scsi_mode = SMODE_HVD; break;
-		case 2:	np->scsi_mode = SMODE_LVD; break;
-		default:	break;
-		}
-	}
-
-	return (u32) pdc_period;
-}
-#else
-static inline int parisc_setup_hcb(hcb_p np, u32 period) { return period; }
-#endif
 /*
  *  Prepare io register values used by sym_start_up() 
  *  according to selected and supported features.
  */
-static int sym_prepare_setting(hcb_p np, struct sym_nvram *nvram)
+static int sym_prepare_setting(struct sym_hcb *np, struct sym_nvram *nvram)
 {
 	u_char	burst_max;
 	u32	period;
@@ -816,8 +783,6 @@
 	 */
 	period = (4 * div_10M[0] + np->clock_khz - 1) / np->clock_khz;
 
-	period = parisc_setup_hcb(np, period);
-
 	if	(period <= 250)		np->minsync = 10;
 	else if	(period <= 303)		np->minsync = 11;
 	else if	(period <= 500)		np->minsync = 12;
@@ -880,7 +845,7 @@
 	 *  In dual channel mode, contention occurs if internal cycles
 	 *  are used. Disable internal cycles.
 	 */
-	if (np->device_id == PCI_ID_LSI53C1010_33 &&
+	if (np->device_id == PCI_DEVICE_ID_LSI_53C1010_33 &&
 	    np->revision_id < 0x1)
 		np->rv_ccntl0	|=  DILS;
 
@@ -904,9 +869,9 @@
 	 *  this driver. The generic ncr driver that does not use 
 	 *  LOAD/STORE instructions does not need this work-around.
 	 */
-	if ((np->device_id == PCI_ID_SYM53C810 &&
+	if ((np->device_id == PCI_DEVICE_ID_NCR_53C810 &&
 	     np->revision_id >= 0x10 && np->revision_id <= 0x11) ||
-	    (np->device_id == PCI_ID_SYM53C860 &&
+	    (np->device_id == PCI_DEVICE_ID_NCR_53C860 &&
 	     np->revision_id <= 0x1))
 		np->features &= ~(FE_WRIE|FE_ERL|FE_ERMP);
 
@@ -1000,7 +965,7 @@
 	if ((SYM_SETUP_SCSI_LED || 
 	     (nvram->type == SYM_SYMBIOS_NVRAM ||
 	      (nvram->type == SYM_TEKRAM_NVRAM &&
-	       np->device_id == PCI_ID_SYM53C895))) &&
+	       np->device_id == PCI_DEVICE_ID_NCR_53C895))) &&
 	    !(np->features & FE_LEDC) && !(np->sv_gpcntl & 0x01))
 		np->features |= FE_LED0;
 
@@ -1091,7 +1056,7 @@
  *  Has to be called with interrupts disabled.
  */
 #ifndef SYM_CONF_IOMAPPED
-static int sym_regtest (hcb_p np)
+static int sym_regtest (struct sym_hcb *np)
 {
 	register volatile u32 data;
 	/*
@@ -1115,7 +1080,7 @@
 }
 #endif
 
-static int sym_snooptest (hcb_p np)
+static int sym_snooptest (struct sym_hcb *np)
 {
 	u32	sym_rd, sym_wr, sym_bk, host_rd, host_wr, pc, dstat;
 	int	i, err=0;
@@ -1241,7 +1206,7 @@
  *  First 24 register of the chip:
  *  	r0..rf
  */
-static void sym_log_hard_error(hcb_p np, u_short sist, u_char dstat)
+static void sym_log_hard_error(struct sym_hcb *np, u_short sist, u_char dstat)
 {
 	u32	dsp;
 	int	script_ofs;
@@ -1299,85 +1264,85 @@
 }
 
 static struct sym_pci_chip sym_pci_dev_table[] = {
- {PCI_ID_SYM53C810, 0x0f, "810", 4, 8, 4, 64,
+ {PCI_DEVICE_ID_NCR_53C810, 0x0f, "810", 4, 8, 4, 64,
  FE_ERL}
  ,
 #ifdef SYM_DEBUG_GENERIC_SUPPORT
- {PCI_ID_SYM53C810, 0xff, "810a", 4,  8, 4, 1,
+ {PCI_DEVICE_ID_NCR_53C810, 0xff, "810a", 4,  8, 4, 1,
  FE_BOF}
  ,
 #else
- {PCI_ID_SYM53C810, 0xff, "810a", 4,  8, 4, 1,
+ {PCI_DEVICE_ID_NCR_53C810, 0xff, "810a", 4,  8, 4, 1,
  FE_CACHE_SET|FE_LDSTR|FE_PFEN|FE_BOF}
  ,
 #endif
- {PCI_ID_SYM53C815, 0xff, "815", 4,  8, 4, 64,
+ {PCI_DEVICE_ID_NCR_53C815, 0xff, "815", 4,  8, 4, 64,
  FE_BOF|FE_ERL}
  ,
- {PCI_ID_SYM53C825, 0x0f, "825", 6,  8, 4, 64,
+ {PCI_DEVICE_ID_NCR_53C825, 0x0f, "825", 6,  8, 4, 64,
  FE_WIDE|FE_BOF|FE_ERL|FE_DIFF}
  ,
- {PCI_ID_SYM53C825, 0xff, "825a", 6,  8, 4, 2,
+ {PCI_DEVICE_ID_NCR_53C825, 0xff, "825a", 6,  8, 4, 2,
  FE_WIDE|FE_CACHE0_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN|FE_RAM|FE_DIFF}
  ,
- {PCI_ID_SYM53C860, 0xff, "860", 4,  8, 5, 1,
+ {PCI_DEVICE_ID_NCR_53C860, 0xff, "860", 4,  8, 5, 1,
  FE_ULTRA|FE_CACHE_SET|FE_BOF|FE_LDSTR|FE_PFEN}
  ,
- {PCI_ID_SYM53C875, 0x01, "875", 6, 16, 5, 2,
+ {PCI_DEVICE_ID_NCR_53C875, 0x01, "875", 6, 16, 5, 2,
  FE_WIDE|FE_ULTRA|FE_CACHE0_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN|
  FE_RAM|FE_DIFF|FE_VARCLK}
  ,
- {PCI_ID_SYM53C875, 0xff, "875", 6, 16, 5, 2,
+ {PCI_DEVICE_ID_NCR_53C875, 0xff, "875", 6, 16, 5, 2,
  FE_WIDE|FE_ULTRA|FE_DBLR|FE_CACHE0_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN|
  FE_RAM|FE_DIFF|FE_VARCLK}
  ,
- {PCI_ID_SYM53C875_2, 0xff, "875", 6, 16, 5, 2,
+ {PCI_DEVICE_ID_NCR_53C875J, 0xff, "875J", 6, 16, 5, 2,
  FE_WIDE|FE_ULTRA|FE_DBLR|FE_CACHE0_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN|
  FE_RAM|FE_DIFF|FE_VARCLK}
  ,
- {PCI_ID_SYM53C885, 0xff, "885", 6, 16, 5, 2,
+ {PCI_DEVICE_ID_NCR_53C885, 0xff, "885", 6, 16, 5, 2,
  FE_WIDE|FE_ULTRA|FE_DBLR|FE_CACHE0_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN|
  FE_RAM|FE_DIFF|FE_VARCLK}
  ,
 #ifdef SYM_DEBUG_GENERIC_SUPPORT
- {PCI_ID_SYM53C895, 0xff, "895", 6, 31, 7, 2,
+ {PCI_DEVICE_ID_NCR_53C895, 0xff, "895", 6, 31, 7, 2,
  FE_WIDE|FE_ULTRA2|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFS|
  FE_RAM|FE_LCKFRQ}
  ,
 #else
- {PCI_ID_SYM53C895, 0xff, "895", 6, 31, 7, 2,
+ {PCI_DEVICE_ID_NCR_53C895, 0xff, "895", 6, 31, 7, 2,
  FE_WIDE|FE_ULTRA2|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN|
  FE_RAM|FE_LCKFRQ}
  ,
 #endif
- {PCI_ID_SYM53C896, 0xff, "896", 6, 31, 7, 4,
+ {PCI_DEVICE_ID_NCR_53C896, 0xff, "896", 6, 31, 7, 4,
  FE_WIDE|FE_ULTRA2|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN|
  FE_RAM|FE_RAM8K|FE_64BIT|FE_DAC|FE_IO256|FE_NOPM|FE_LEDC|FE_LCKFRQ}
  ,
- {PCI_ID_SYM53C895A, 0xff, "895a", 6, 31, 7, 4,
+ {PCI_DEVICE_ID_LSI_53C895A, 0xff, "895a", 6, 31, 7, 4,
  FE_WIDE|FE_ULTRA2|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN|
  FE_RAM|FE_RAM8K|FE_DAC|FE_IO256|FE_NOPM|FE_LEDC|FE_LCKFRQ}
  ,
- {PCI_ID_SYM53C875A, 0xff, "875a", 6, 31, 7, 4,
+ {PCI_DEVICE_ID_LSI_53C875A, 0xff, "875a", 6, 31, 7, 4,
  FE_WIDE|FE_ULTRA|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN|
  FE_RAM|FE_DAC|FE_IO256|FE_NOPM|FE_LEDC|FE_LCKFRQ}
  ,
- {PCI_ID_LSI53C1010_33, 0x00, "1010-33", 6, 31, 7, 8,
+ {PCI_DEVICE_ID_LSI_53C1010_33, 0x00, "1010-33", 6, 31, 7, 8,
  FE_WIDE|FE_ULTRA3|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFBC|FE_LDSTR|FE_PFEN|
  FE_RAM|FE_RAM8K|FE_64BIT|FE_DAC|FE_IO256|FE_NOPM|FE_LEDC|FE_CRC|
  FE_C10}
  ,
- {PCI_ID_LSI53C1010_33, 0xff, "1010-33", 6, 31, 7, 8,
+ {PCI_DEVICE_ID_LSI_53C1010_33, 0xff, "1010-33", 6, 31, 7, 8,
  FE_WIDE|FE_ULTRA3|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFBC|FE_LDSTR|FE_PFEN|
  FE_RAM|FE_RAM8K|FE_64BIT|FE_DAC|FE_IO256|FE_NOPM|FE_LEDC|FE_CRC|
  FE_C10|FE_U3EN}
  ,
- {PCI_ID_LSI53C1010_66, 0xff, "1010-66", 6, 31, 7, 8,
+ {PCI_DEVICE_ID_LSI_53C1010_66, 0xff, "1010-66", 6, 31, 7, 8,
  FE_WIDE|FE_ULTRA3|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFBC|FE_LDSTR|FE_PFEN|
  FE_RAM|FE_RAM8K|FE_64BIT|FE_DAC|FE_IO256|FE_NOPM|FE_LEDC|FE_66MHZ|FE_CRC|
  FE_C10|FE_U3EN}
  ,
- {PCI_ID_LSI53C1510D, 0xff, "1510d", 6, 31, 7, 4,
+ {PCI_DEVICE_ID_LSI_53C1510, 0xff, "1510d", 6, 31, 7, 4,
  FE_WIDE|FE_ULTRA2|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN|
  FE_RAM|FE_IO256|FE_LEDC}
 };
@@ -1415,7 +1380,7 @@
  *  This is only used if the direct mapping 
  *  has been unsuccessful.
  */
-int sym_lookup_dmap(hcb_p np, u32 h, int s)
+int sym_lookup_dmap(struct sym_hcb *np, u32 h, int s)
 {
 	int i;
 
@@ -1448,7 +1413,7 @@
  *  Update IO registers scratch C..R so they will be 
  *  in sync. with queued CCB expectations.
  */
-static void sym_update_dmap_regs(hcb_p np)
+static void sym_update_dmap_regs(struct sym_hcb *np)
 {
 	int o, i;
 
@@ -1463,13 +1428,12 @@
 }
 #endif
 
+/* Enforce all the fiddly SPI rules and the chip limitations */
 static void sym_check_goals(struct scsi_device *sdev)
 {
 	struct sym_hcb *np = ((struct host_data *)sdev->host->hostdata)->ncb;
 	struct sym_trans *st = &np->target[sdev->id].tinfo.goal;
 
-	/* here we enforce all the fiddly SPI rules */
-
 	if (!scsi_device_wide(sdev))
 		st->width = 0;
 
@@ -1479,7 +1443,7 @@
 		st->offset = 0;
 		return;
 	}
-		
+
 	if (scsi_device_dt(sdev)) {
 		if (scsi_device_dt_only(sdev))
 			st->options |= PPR_OPT_DT;
@@ -1490,7 +1454,8 @@
 		st->options &= ~PPR_OPT_DT;
 	}
 
-	if (!(np->features & FE_ULTRA3))
+	/* Some targets fail to properly negotiate DT in SE mode */
+	if ((np->scsi_mode != SMODE_LVD) || !(np->features & FE_U3EN))
 		st->options &= ~PPR_OPT_DT;
 
 	if (st->options & PPR_OPT_DT) {
@@ -1520,38 +1485,31 @@
  *  negotiation and the nego_status field of the CCB.
  *  Returns the size of the message in bytes.
  */
-static int sym_prepare_nego(hcb_p np, ccb_p cp, int nego, u_char *msgptr)
+static int sym_prepare_nego(struct sym_hcb *np, ccb_p cp, u_char *msgptr)
 {
 	tcb_p tp = &np->target[cp->target];
-	int msglen = 0;
 	struct scsi_device *sdev = tp->sdev;
+	struct sym_trans *goal = &tp->tinfo.goal;
+	struct sym_trans *curr = &tp->tinfo.curr;
+	int msglen = 0;
+	int nego;
 
 	if (likely(sdev))
 		sym_check_goals(sdev);
 
 	/*
-	 *  Early C1010 chips need a work-around for DT 
-	 *  data transfer to work.
+	 * Many devices implement PPR in a buggy way, so only use it if we
+	 * really want to.
 	 */
-	if (!(np->features & FE_U3EN))
-		tp->tinfo.goal.options = 0;
-	/*
-	 *  negotiate using PPR ?
-	 */
-	if (scsi_device_dt(sdev)) {
+	if ((goal->options & PPR_OPT_MASK) || (goal->period < 0xa)) {
 		nego = NS_PPR;
+	} else if (curr->width != goal->width) {
+		nego = NS_WIDE;
+	} else if (curr->period != goal->period ||
+		   curr->offset != goal->offset) {
+		nego = NS_SYNC;
 	} else {
-		/*
-		 *  negotiate wide transfers ?
-		 */
-		if (tp->tinfo.curr.width != tp->tinfo.goal.width)
-			nego = NS_WIDE;
-		/*
-		 *  negotiate synchronous transfers?
-		 */
-		else if (tp->tinfo.curr.period != tp->tinfo.goal.period ||
-			 tp->tinfo.curr.offset != tp->tinfo.goal.offset)
-			nego = NS_SYNC;
+		nego = 0;
 	}
 
 	switch (nego) {
@@ -1559,24 +1517,24 @@
 		msgptr[msglen++] = M_EXTENDED;
 		msgptr[msglen++] = 3;
 		msgptr[msglen++] = M_X_SYNC_REQ;
-		msgptr[msglen++] = tp->tinfo.goal.period;
-		msgptr[msglen++] = tp->tinfo.goal.offset;
+		msgptr[msglen++] = goal->period;
+		msgptr[msglen++] = goal->offset;
 		break;
 	case NS_WIDE:
 		msgptr[msglen++] = M_EXTENDED;
 		msgptr[msglen++] = 2;
 		msgptr[msglen++] = M_X_WIDE_REQ;
-		msgptr[msglen++] = tp->tinfo.goal.width;
+		msgptr[msglen++] = goal->width;
 		break;
 	case NS_PPR:
 		msgptr[msglen++] = M_EXTENDED;
 		msgptr[msglen++] = 6;
 		msgptr[msglen++] = M_X_PPR_REQ;
-		msgptr[msglen++] = tp->tinfo.goal.period;
+		msgptr[msglen++] = goal->period;
 		msgptr[msglen++] = 0;
-		msgptr[msglen++] = tp->tinfo.goal.offset;
-		msgptr[msglen++] = tp->tinfo.goal.width;
-		msgptr[msglen++] = tp->tinfo.goal.options & PPR_OPT_MASK;
+		msgptr[msglen++] = goal->offset;
+		msgptr[msglen++] = goal->width;
+		msgptr[msglen++] = goal->options & PPR_OPT_MASK;
 		break;
 	};
 
@@ -1598,7 +1556,7 @@
 /*
  *  Insert a job into the start queue.
  */
-void sym_put_start_queue(hcb_p np, ccb_p cp)
+void sym_put_start_queue(struct sym_hcb *np, ccb_p cp)
 {
 	u_short	qidx;
 
@@ -1630,13 +1588,6 @@
 #endif
 
 	/*
-	 *  Optionnaly, set the IO timeout condition.
-	 */
-#ifdef	SYM_OPT_HANDLE_IO_TIMEOUT
-	sym_timeout_ccb(np, cp, sym_cam_timeout(cp->cam_ccb));
-#endif
-
-	/*
 	 *  Insert first the idle task and then our job.
 	 *  The MBs should ensure proper ordering.
 	 */
@@ -1664,7 +1615,7 @@
 /*
  *  Start next ready-to-start CCBs.
  */
-void sym_start_next_ccbs(hcb_p np, lcb_p lp, int maxn)
+void sym_start_next_ccbs(struct sym_hcb *np, lcb_p lp, int maxn)
 {
 	SYM_QUEHEAD *qp;
 	ccb_p cp;
@@ -1718,7 +1669,7 @@
  *  prevent out of order LOADs by the CPU from having 
  *  prefetched stale data prior to DMA having occurred.
  */
-static int sym_wakeup_done (hcb_p np)
+static int sym_wakeup_done (struct sym_hcb *np)
 {
 	ccb_p cp;
 	int i, n;
@@ -1752,10 +1703,64 @@
 }
 
 /*
+ *  Complete all CCBs queued to the COMP queue.
+ *
+ *  These CCBs are assumed:
+ *  - Not to be referenced either by devices or 
+ *    SCRIPTS-related queues and datas.
+ *  - To have to be completed with an error condition 
+ *    or requeued.
+ *
+ *  The device queue freeze count is incremented 
+ *  for each CCB that does not prevent this.
+ *  This function is called when all CCBs involved 
+ *  in error handling/recovery have been reaped.
+ */
+static void sym_flush_comp_queue(struct sym_hcb *np, int cam_status)
+{
+	SYM_QUEHEAD *qp;
+	ccb_p cp;
+
+	while ((qp = sym_remque_head(&np->comp_ccbq)) != 0) {
+		struct scsi_cmnd *ccb;
+		cp = sym_que_entry(qp, struct sym_ccb, link_ccbq);
+		sym_insque_tail(&cp->link_ccbq, &np->busy_ccbq);
+		/* Leave quiet CCBs waiting for resources */
+		if (cp->host_status == HS_WAIT)
+			continue;
+		ccb = cp->cam_ccb;
+		if (cam_status)
+			sym_set_cam_status(ccb, cam_status);
+#ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
+		if (sym_get_cam_status(ccb) == CAM_REQUEUE_REQ) {
+			tcb_p tp = &np->target[cp->target];
+			lcb_p lp = sym_lp(np, tp, cp->lun);
+			if (lp) {
+				sym_remque(&cp->link2_ccbq);
+				sym_insque_tail(&cp->link2_ccbq,
+				                &lp->waiting_ccbq);
+				if (cp->started) {
+					if (cp->tag != NO_TAG)
+						--lp->started_tags;
+					else
+						--lp->started_no_tag;
+				}
+			}
+			cp->started = 0;
+			continue;
+		}
+#endif
+		sym_free_ccb(np, cp);
+		sym_freeze_cam_ccb(ccb);
+		sym_xpt_done(np, ccb);
+	}
+}
+
+/*
  *  Complete all active CCBs with error.
  *  Used on CHIP/SCSI RESET.
  */
-static void sym_flush_busy_queue (hcb_p np, int cam_status)
+static void sym_flush_busy_queue (struct sym_hcb *np, int cam_status)
 {
 	/*
 	 *  Move all active CCBs to the COMP queue 
@@ -1774,7 +1779,7 @@
  *     1: SCSI BUS RESET delivered or received.
  *     2: SCSI BUS MODE changed.
  */
-void sym_start_up (hcb_p np, int reason)
+void sym_start_up (struct sym_hcb *np, int reason)
 {
  	int	i;
 	u32	phys;
@@ -1865,7 +1870,7 @@
 	/*
 	 *  For now, disable AIP generation on C1010-66.
 	 */
-	if (np->device_id == PCI_ID_LSI53C1010_66)
+	if (np->device_id == PCI_DEVICE_ID_LSI_53C1010_66)
 		OUTB (nc_aipcntl1, DISAIP);
 
 	/*
@@ -1875,7 +1880,7 @@
 	 *  that from SCRIPTS for each selection/reselection, but 
 	 *  I just don't want. :)
 	 */
-	if (np->device_id == PCI_ID_LSI53C1010_33 &&
+	if (np->device_id == PCI_DEVICE_ID_LSI_53C1010_33 &&
 	    np->revision_id < 1)
 		OUTB (nc_stest1, INB(nc_stest1) | 0x30);
 
@@ -1884,9 +1889,9 @@
 	 *  Disable overlapped arbitration for some dual function devices, 
 	 *  regardless revision id (kind of post-chip-design feature. ;-))
 	 */
-	if (np->device_id == PCI_ID_SYM53C875)
+	if (np->device_id == PCI_DEVICE_ID_NCR_53C875)
 		OUTB (nc_ctest0, (1<<5));
-	else if (np->device_id == PCI_ID_SYM53C896)
+	else if (np->device_id == PCI_DEVICE_ID_NCR_53C896)
 		np->rv_ccntl0 |= DPR;
 
 	/*
@@ -2010,7 +2015,7 @@
 /*
  *  Switch trans mode for current job and it's target.
  */
-static void sym_settrans(hcb_p np, int target, u_char opts, u_char ofs,
+static void sym_settrans(struct sym_hcb *np, int target, u_char opts, u_char ofs,
 			 u_char per, u_char wide, u_char div, u_char fak)
 {
 	SYM_QUEHEAD *qp;
@@ -2119,7 +2124,7 @@
  *  We received a WDTR.
  *  Let everything be aware of the changes.
  */
-static void sym_setwide(hcb_p np, int target, u_char wide)
+static void sym_setwide(struct sym_hcb *np, int target, u_char wide)
 {
 	tcb_p tp = &np->target[target];
 
@@ -2138,7 +2143,7 @@
  *  Let everything be aware of the changes.
  */
 static void
-sym_setsync(hcb_p np, int target,
+sym_setsync(struct sym_hcb *np, int target,
             u_char ofs, u_char per, u_char div, u_char fak)
 {
 	tcb_p tp = &np->target[target];
@@ -2164,7 +2169,7 @@
  *  Let everything be aware of the changes.
  */
 static void 
-sym_setpprot(hcb_p np, int target, u_char opts, u_char ofs,
+sym_setpprot(struct sym_hcb *np, int target, u_char opts, u_char ofs,
              u_char per, u_char wide, u_char div, u_char fak)
 {
 	tcb_p tp = &np->target[target];
@@ -2205,7 +2210,7 @@
  *  pushes a DSA into a queue, we can trust it when it 
  *  points to a CCB.
  */
-static void sym_recover_scsi_int (hcb_p np, u_char hsts)
+static void sym_recover_scsi_int (struct sym_hcb *np, u_char hsts)
 {
 	u32	dsp	= INL (nc_dsp);
 	u32	dsa	= INL (nc_dsa);
@@ -2256,7 +2261,7 @@
 /*
  *  chip exception handler for selection timeout
  */
-static void sym_int_sto (hcb_p np)
+static void sym_int_sto (struct sym_hcb *np)
 {
 	u32 dsp	= INL (nc_dsp);
 
@@ -2271,7 +2276,7 @@
 /*
  *  chip exception handler for unexpected disconnect
  */
-static void sym_int_udc (hcb_p np)
+static void sym_int_udc (struct sym_hcb *np)
 {
 	printf ("%s: unexpected disconnect\n", sym_name(np));
 	sym_recover_scsi_int(np, HS_UNEXPECTED);
@@ -2287,7 +2292,7 @@
  *  mode to eight bit asynchronous, etc...
  *  So, just reinitializing all except chip should be enough.
  */
-static void sym_int_sbmc (hcb_p np)
+static void sym_int_sbmc (struct sym_hcb *np)
 {
 	u_char scsi_mode = INB (nc_stest4) & SMODE;
 
@@ -2328,7 +2333,7 @@
  *    The chip will load the DSP with the phase mismatch 
  *    JUMP address and interrupt the host processor.
  */
-static void sym_int_par (hcb_p np, u_short sist)
+static void sym_int_par (struct sym_hcb *np, u_short sist)
 {
 	u_char	hsts	= INB (HS_PRT);
 	u32	dsp	= INL (nc_dsp);
@@ -2416,7 +2421,7 @@
  *  We have to construct a new transfer descriptor,
  *  to transfer the rest of the current block.
  */
-static void sym_int_ma (hcb_p np)
+static void sym_int_ma (struct sym_hcb *np)
 {
 	u32	dbc;
 	u32	rest;
@@ -2826,7 +2831,7 @@
  *  Use at your own decision and risk.
  */
 
-void sym_interrupt (hcb_p np)
+void sym_interrupt (struct sym_hcb *np)
 {
 	u_char	istat, istatc;
 	u_char	dstat;
@@ -2981,7 +2986,7 @@
  *  It is called with SCRIPTS not running.
  */
 static int 
-sym_dequeue_from_squeue(hcb_p np, int i, int target, int lun, int task)
+sym_dequeue_from_squeue(struct sym_hcb *np, int i, int target, int lun, int task)
 {
 	int j;
 	ccb_p cp;
@@ -3025,60 +3030,6 @@
 }
 
 /*
- *  Complete all CCBs queued to the COMP queue.
- *
- *  These CCBs are assumed:
- *  - Not to be referenced either by devices or 
- *    SCRIPTS-related queues and datas.
- *  - To have to be completed with an error condition 
- *    or requeued.
- *
- *  The device queue freeze count is incremented 
- *  for each CCB that does not prevent this.
- *  This function is called when all CCBs involved 
- *  in error handling/recovery have been reaped.
- */
-void sym_flush_comp_queue(hcb_p np, int cam_status)
-{
-	SYM_QUEHEAD *qp;
-	ccb_p cp;
-
-	while ((qp = sym_remque_head(&np->comp_ccbq)) != 0) {
-		cam_ccb_p ccb;
-		cp = sym_que_entry(qp, struct sym_ccb, link_ccbq);
-		sym_insque_tail(&cp->link_ccbq, &np->busy_ccbq);
-		/* Leave quiet CCBs waiting for resources */
-		if (cp->host_status == HS_WAIT)
-			continue;
-		ccb = cp->cam_ccb;
-		if (cam_status)
-			sym_set_cam_status(ccb, cam_status);
-#ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
-		if (sym_get_cam_status(ccb) == CAM_REQUEUE_REQ) {
-			tcb_p tp = &np->target[cp->target];
-			lcb_p lp = sym_lp(np, tp, cp->lun);
-			if (lp) {
-				sym_remque(&cp->link2_ccbq);
-				sym_insque_tail(&cp->link2_ccbq,
-				                &lp->waiting_ccbq);
-				if (cp->started) {
-					if (cp->tag != NO_TAG)
-						--lp->started_tags;
-					else
-						--lp->started_no_tag;
-				}
-			}
-			cp->started = 0;
-			continue;
-		}
-#endif
-		sym_free_ccb(np, cp);
-		sym_freeze_cam_ccb(ccb);
-		sym_xpt_done(np, ccb);
-	}
-}
-
-/*
  *  chip handler for bad SCSI status condition
  *
  *  In case of bad SCSI status, we unqueue all the tasks 
@@ -3096,14 +3047,13 @@
  *  SCRATCHA is assumed to have been loaded with STARTPOS 
  *  before the SCRIPTS called the C code.
  */
-static void sym_sir_bad_scsi_status(hcb_p np, int num, ccb_p cp)
+static void sym_sir_bad_scsi_status(struct sym_hcb *np, int num, ccb_p cp)
 {
 	tcb_p tp	= &np->target[cp->target];
 	u32		startp;
 	u_char		s_status = cp->ssss_status;
 	u_char		h_flags  = cp->host_flags;
 	int		msglen;
-	int		nego;
 	int		i;
 
 	/*
@@ -3178,16 +3128,7 @@
 		 *  cp->nego_status is filled by sym_prepare_nego().
 		 */
 		cp->nego_status = 0;
-		nego = 0;
-		if	(tp->tinfo.curr.options & PPR_OPT_MASK)
-			nego = NS_PPR;
-		else if	(tp->tinfo.curr.width != BUS_8_BIT)
-			nego = NS_WIDE;
-		else if (tp->tinfo.curr.offset != 0)
-			nego = NS_SYNC;
-		if (nego)
-			msglen +=
-			sym_prepare_nego (np,cp, nego, &cp->scsi_smsg2[msglen]);
+		msglen += sym_prepare_nego(np, cp, &cp->scsi_smsg2[msglen]);
 		/*
 		 *  Message table indirect structure.
 		 */
@@ -3213,7 +3154,7 @@
 		/*
 		 *  sense data
 		 */
-		bzero(cp->sns_bbuf, SYM_SNS_BBUF_LEN);
+		memset(cp->sns_bbuf, 0, SYM_SNS_BBUF_LEN);
 		cp->phys.sense.addr	= cpu_to_scr(vtobus(cp->sns_bbuf));
 		cp->phys.sense.size	= cpu_to_scr(SYM_SNS_BBUF_LEN);
 
@@ -3263,7 +3204,7 @@
  *  - lun=-1  means any logical UNIT otherwise a given one.
  *  - task=-1 means any task, otherwise a given one.
  */
-int sym_clear_tasks(hcb_p np, int cam_status, int target, int lun, int task)
+int sym_clear_tasks(struct sym_hcb *np, int cam_status, int target, int lun, int task)
 {
 	SYM_QUEHEAD qtmp, *qp;
 	int i = 0;
@@ -3282,7 +3223,7 @@
 	 *  the BUSY queue.
 	 */
 	while ((qp = sym_remque_head(&qtmp)) != 0) {
-		cam_ccb_p ccb;
+		struct scsi_cmnd *ccb;
 		cp = sym_que_entry(qp, struct sym_ccb, link_ccbq);
 		ccb = cp->cam_ccb;
 		if (cp->host_status != HS_DISCONNECT ||
@@ -3346,7 +3287,7 @@
  *  all the CCBs that should have been aborted by the 
  *  target according to our message.
  */
-static void sym_sir_task_recovery(hcb_p np, int num)
+static void sym_sir_task_recovery(struct sym_hcb *np, int num)
 {
 	SYM_QUEHEAD *qp;
 	ccb_p cp;
@@ -3698,7 +3639,7 @@
  *  the corresponding values of dp_sg and dp_ofs.
  */
 
-static int sym_evaluate_dp(hcb_p np, ccb_p cp, u32 scr, int *ofs)
+static int sym_evaluate_dp(struct sym_hcb *np, ccb_p cp, u32 scr, int *ofs)
 {
 	u32	dp_scr;
 	int	dp_ofs, dp_sg, dp_sgmin;
@@ -3816,7 +3757,7 @@
  *  is equivalent to a MODIFY DATA POINTER (offset=-1).
  */
 
-static void sym_modify_dp(hcb_p np, tcb_p tp, ccb_p cp, int ofs)
+static void sym_modify_dp(struct sym_hcb *np, tcb_p tp, ccb_p cp, int ofs)
 {
 	int dp_ofs	= ofs;
 	u32	dp_scr	= sym_get_script_dp (np, cp);
@@ -3915,7 +3856,7 @@
  *  a relevant information. :)
  */
 
-int sym_compute_residual(hcb_p np, ccb_p cp)
+int sym_compute_residual(struct sym_hcb *np, ccb_p cp)
 {
 	int dp_sg, dp_sgmin, resid = 0;
 	int dp_ofs = 0;
@@ -4015,7 +3956,7 @@
  *  chip handler for SYNCHRONOUS DATA TRANSFER REQUEST (SDTR) message.
  */
 static int  
-sym_sync_nego_check(hcb_p np, int req, int target)
+sym_sync_nego_check(struct sym_hcb *np, int req, int target)
 {
 	u_char	chg, ofs, per, fak, div;
 
@@ -4096,7 +4037,7 @@
 	return -1;
 }
 
-static void sym_sync_nego(hcb_p np, tcb_p tp, ccb_p cp)
+static void sym_sync_nego(struct sym_hcb *np, tcb_p tp, ccb_p cp)
 {
 	int req = 1;
 	int result;
@@ -4133,7 +4074,7 @@
  *  chip handler for PARALLEL PROTOCOL REQUEST (PPR) message.
  */
 static int 
-sym_ppr_nego_check(hcb_p np, int req, int target)
+sym_ppr_nego_check(struct sym_hcb *np, int req, int target)
 {
 	tcb_p tp = &np->target[target];
 	unsigned char fak, div;
@@ -4176,7 +4117,7 @@
 
 	if (ofs) {
 		unsigned char minsync = dt ? np->minsync_dt : np->minsync;
-		if (per < np->minsync_dt) {
+		if (per < minsync) {
 			chg = 1;
 			per = minsync;
 		}
@@ -4242,7 +4183,7 @@
 	return -1;
 }
 
-static void sym_ppr_nego(hcb_p np, tcb_p tp, ccb_p cp)
+static void sym_ppr_nego(struct sym_hcb *np, tcb_p tp, ccb_p cp)
 {
 	int req = 1;
 	int result;
@@ -4279,7 +4220,7 @@
  *  chip handler for WIDE DATA TRANSFER REQUEST (WDTR) message.
  */
 static int  
-sym_wide_nego_check(hcb_p np, int req, int target)
+sym_wide_nego_check(struct sym_hcb *np, int req, int target)
 {
 	u_char	chg, wide;
 
@@ -4344,7 +4285,7 @@
 	return -1;
 }
 
-static void sym_wide_nego(hcb_p np, tcb_p tp, ccb_p cp)
+static void sym_wide_nego(struct sym_hcb *np, tcb_p tp, ccb_p cp)
 {
 	int req = 1;
 	int result;
@@ -4413,7 +4354,7 @@
  *  So, if a PPR makes problems, we may just want to 
  *  try a legacy negotiation later.
  */
-static void sym_nego_default(hcb_p np, tcb_p tp, ccb_p cp)
+static void sym_nego_default(struct sym_hcb *np, tcb_p tp, ccb_p cp)
 {
 	switch (cp->nego_status) {
 	case NS_PPR:
@@ -4443,7 +4384,7 @@
  *  chip handler for MESSAGE REJECT received in response to 
  *  PPR, WIDE or SYNCHRONOUS negotiation.
  */
-static void sym_nego_rejected(hcb_p np, tcb_p tp, ccb_p cp)
+static void sym_nego_rejected(struct sym_hcb *np, tcb_p tp, ccb_p cp)
 {
 	sym_nego_default(np, tp, cp);
 	OUTB (HS_PRT, HS_BUSY);
@@ -4452,7 +4393,7 @@
 /*
  *  chip exception handler for programmed interrupts.
  */
-static void sym_int_sir (hcb_p np)
+static void sym_int_sir (struct sym_hcb *np)
 {
 	u_char	num	= INB (nc_dsps);
 	u32	dsa	= INL (nc_dsa);
@@ -4726,7 +4667,7 @@
 /*
  *  Acquire a control block
  */
-ccb_p sym_get_ccb (hcb_p np, u_char tn, u_char ln, u_char tag_order)
+ccb_p sym_get_ccb (struct sym_hcb *np, u_char tn, u_char ln, u_char tag_order)
 {
 	tcb_p tp = &np->target[tn];
 	lcb_p lp = sym_lp(np, tp, ln);
@@ -4875,7 +4816,7 @@
 /*
  *  Release one control block
  */
-void sym_free_ccb (hcb_p np, ccb_p cp)
+void sym_free_ccb (struct sym_hcb *np, ccb_p cp)
 {
 	tcb_p tp = &np->target[cp->target];
 	lcb_p lp = sym_lp(np, tp, cp->lun);
@@ -4960,13 +4901,6 @@
 	sym_remque(&cp->link_ccbq);
 	sym_insque_head(&cp->link_ccbq, &np->free_ccbq);
 
-#ifdef	SYM_OPT_HANDLE_IO_TIMEOUT
-	/*
-	 *  Cancel any pending timeout condition.
-	 */
-	sym_untimeout_ccb(np, cp);
-#endif
-
 #ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
 	if (lp) {
 		sym_remque(&cp->link2_ccbq);
@@ -4985,7 +4919,7 @@
 /*
  *  Allocate a CCB from memory and initialize its fixed part.
  */
-static ccb_p sym_alloc_ccb(hcb_p np)
+static ccb_p sym_alloc_ccb(struct sym_hcb *np)
 {
 	ccb_p cp = NULL;
 	int hcode;
@@ -5053,9 +4987,6 @@
 	/*
 	 *  Chain into optionnal lists.
 	 */
-#ifdef	SYM_OPT_HANDLE_IO_TIMEOUT
-	sym_insque_head(&cp->tmo_linkq, &np->tmo0_ccbq);
-#endif
 #ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
 	sym_insque_head(&cp->link2_ccbq, &np->dummy_ccbq);
 #endif
@@ -5072,7 +5003,7 @@
 /*
  *  Look up a CCB from a DSA value.
  */
-static ccb_p sym_ccb_from_dsa(hcb_p np, u32 dsa)
+static ccb_p sym_ccb_from_dsa(struct sym_hcb *np, u32 dsa)
 {
 	int hcode;
 	ccb_p cp;
@@ -5092,7 +5023,7 @@
  *  Target control block initialisation.
  *  Nothing important to do at the moment.
  */
-static void sym_init_tcb (hcb_p np, u_char tn)
+static void sym_init_tcb (struct sym_hcb *np, u_char tn)
 {
 #if 0	/*  Hmmm... this checking looks paranoid. */
 	/*
@@ -5108,7 +5039,7 @@
 /*
  *  Lun control block allocation and initialization.
  */
-lcb_p sym_alloc_lcb (hcb_p np, u_char tn, u_char ln)
+lcb_p sym_alloc_lcb (struct sym_hcb *np, u_char tn, u_char ln)
 {
 	tcb_p tp = &np->target[tn];
 	lcb_p lp = sym_lp(np, tp, ln);
@@ -5210,7 +5141,7 @@
 /*
  *  Allocate LCB resources for tagged command queuing.
  */
-static void sym_alloc_lcb_tags (hcb_p np, u_char tn, u_char ln)
+static void sym_alloc_lcb_tags (struct sym_hcb *np, u_char tn, u_char ln)
 {
 	tcb_p tp = &np->target[tn];
 	lcb_p lp = sym_lp(np, tp, ln);
@@ -5262,7 +5193,7 @@
 /*
  *  Queue a SCSI IO to the controller.
  */
-int sym_queue_scsiio(hcb_p np, cam_scsiio_p csio, ccb_p cp)
+int sym_queue_scsiio(struct sym_hcb *np, struct scsi_cmnd *csio, ccb_p cp)
 {
 	tcb_p	tp;
 	lcb_p	lp;
@@ -5273,7 +5204,7 @@
 	/*
 	 *  Keep track of the IO in our CCB.
 	 */
-	cp->cam_ccb = (cam_ccb_p) csio;
+	cp->cam_ccb = csio;
 
 	/*
 	 *  Retrieve the target descriptor.
@@ -5351,7 +5282,7 @@
 	    tp->tinfo.curr.offset  != tp->tinfo.goal.offset ||
 	    tp->tinfo.curr.options != tp->tinfo.goal.options) {
 		if (!tp->nego_cp && lp)
-			msglen += sym_prepare_nego(np, cp, 0, msgptr + msglen);
+			msglen += sym_prepare_nego(np, cp, msgptr + msglen);
 	}
 
 	/*
@@ -5401,7 +5332,7 @@
 /*
  *  Reset a SCSI target (all LUNs of this target).
  */
-int sym_reset_scsi_target(hcb_p np, int target)
+int sym_reset_scsi_target(struct sym_hcb *np, int target)
 {
 	tcb_p tp;
 
@@ -5420,7 +5351,7 @@
 /*
  *  Abort a SCSI IO.
  */
-int sym_abort_ccb(hcb_p np, ccb_p cp, int timed_out)
+int sym_abort_ccb(struct sym_hcb *np, ccb_p cp, int timed_out)
 {
 	/*
 	 *  Check that the IO is active.
@@ -5450,7 +5381,7 @@
 	return 0;
 }
 
-int sym_abort_scsiio(hcb_p np, cam_ccb_p ccb, int timed_out)
+int sym_abort_scsiio(struct sym_hcb *np, struct scsi_cmnd *ccb, int timed_out)
 {
 	ccb_p cp;
 	SYM_QUEHEAD *qp;
@@ -5480,7 +5411,7 @@
  *  SCRATCHA is assumed to have been loaded with STARTPOS 
  *  before the SCRIPTS called the C code.
  */
-void sym_complete_error (hcb_p np, ccb_p cp)
+void sym_complete_error (struct sym_hcb *np, ccb_p cp)
 {
 	tcb_p tp;
 	lcb_p lp;
@@ -5614,11 +5545,11 @@
  *  The SCRIPTS processor is running while we are 
  *  completing successful commands.
  */
-void sym_complete_ok (hcb_p np, ccb_p cp)
+void sym_complete_ok (struct sym_hcb *np, ccb_p cp)
 {
 	tcb_p tp;
 	lcb_p lp;
-	cam_ccb_p ccb;
+	struct scsi_cmnd *ccb;
 	int resid;
 
 	/*
@@ -5724,7 +5655,7 @@
 /*
  *  Soft-attach the controller.
  */
-int sym_hcb_attach(hcb_p np, struct sym_fw *fw, struct sym_nvram *nvram)
+int sym_hcb_attach(struct sym_hcb *np, struct sym_fw *fw, struct sym_nvram *nvram)
 {
 	int i;
 
@@ -5815,17 +5746,9 @@
 	sym_que_init(&np->comp_ccbq);
 
 	/*
-	 *  Initializations for optional handling 
-	 *  of IO timeouts and device queueing.
+	 *  Initialization for optional handling 
+	 *  of device queueing.
 	 */
-#ifdef	SYM_OPT_HANDLE_IO_TIMEOUT
-	sym_que_init(&np->tmo0_ccbq);
-	np->tmo_ccbq =
-		sym_calloc(2*SYM_CONF_TIMEOUT_ORDER_MAX*sizeof(SYM_QUEHEAD),
-			   "TMO_CCBQ");
-	for (i = 0 ; i < 2*SYM_CONF_TIMEOUT_ORDER_MAX ; i++)
-		sym_que_init(&np->tmo_ccbq[i]);
-#endif
 #ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
 	sym_que_init(&np->dummy_ccbq);
 #endif
@@ -5957,7 +5880,7 @@
 /*
  *  Free everything that has been allocated for this device.
  */
-void sym_hcb_free(hcb_p np)
+void sym_hcb_free(struct sym_hcb *np)
 {
 	SYM_QUEHEAD *qp;
 	ccb_p cp;
@@ -5971,12 +5894,6 @@
 		sym_mfree_dma(np->scriptb0, np->scriptb_sz, "SCRIPTB0");
 	if (np->scripta0)
 		sym_mfree_dma(np->scripta0, np->scripta_sz, "SCRIPTA0");
-#ifdef	SYM_OPT_HANDLE_IO_TIMEOUT
-	if (np->tmo_ccbq)
-		sym_mfree(np->tmo_ccbq,
-			  2*SYM_CONF_TIMEOUT_ORDER_MAX*sizeof(SYM_QUEHEAD),
-			  "TMO_CCBQ");
-#endif
 	if (np->squeue)
 		sym_mfree_dma(np->squeue, sizeof(u32)*(MAX_QUEUE*2), "SQUEUE");
 	if (np->dqueue)
diff -Nru a/drivers/scsi/sym53c8xx_2/sym_hipd.h b/drivers/scsi/sym53c8xx_2/sym_hipd.h
--- a/drivers/scsi/sym53c8xx_2/sym_hipd.h	2005-03-01 23:38:55 -08:00
+++ b/drivers/scsi/sym53c8xx_2/sym_hipd.h	2005-03-01 23:38:55 -08:00
@@ -749,7 +749,7 @@
 	/*
 	 *  Pointer to CAM ccb and related stuff.
 	 */
-	cam_ccb_p cam_ccb;	/* CAM scsiio ccb		*/
+	struct scsi_cmnd *cam_ccb;	/* CAM scsiio ccb		*/
 	u8	cdb_buf[16];	/* Copy of CDB			*/
 	u8	*sns_bbuf;	/* Bounce buffer for sense data	*/
 #ifndef	SYM_SNS_BBUF_LEN
@@ -796,10 +796,6 @@
 	/*
 	 *  Other fields.
 	 */
-#ifdef	SYM_OPT_HANDLE_IO_TIMEOUT
-	SYM_QUEHEAD tmo_linkq;	/* Optional timeout handling	*/
-	u_int	tmo_clock;	/* (link and dealine value)	*/
-#endif
 	u32	ccb_ba;		/* BUS address of this CCB	*/
 	u_short	tag;		/* Tag for this transfer	*/
 				/*  NO_TAG means no tag		*/
@@ -946,8 +942,8 @@
 	struct sym_fwa_ba fwa_bas;	/* Useful SCRIPTA bus addresses	*/
 	struct sym_fwb_ba fwb_bas;	/* Useful SCRIPTB bus addresses	*/
 	struct sym_fwz_ba fwz_bas;	/* Useful SCRIPTZ bus addresses	*/
-	void		(*fw_setup)(hcb_p np, struct sym_fw *fw);
-	void		(*fw_patch)(hcb_p np);
+	void		(*fw_setup)(struct sym_hcb *np, struct sym_fw *fw);
+	void		(*fw_patch)(struct sym_hcb *np);
 	char		*fw_name;
 
 	/*
@@ -1025,15 +1021,6 @@
 #ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
 	SYM_QUEHEAD	dummy_ccbq;
 #endif
-	/*
-	 *  Optional handling of IO timeouts.
-	 */
-#ifdef	SYM_OPT_HANDLE_IO_TIMEOUT
-	SYM_QUEHEAD tmo0_ccbq;
-	SYM_QUEHEAD *tmo_ccbq;	/* [2*SYM_TIMEOUT_ORDER_MAX] */
-	u_int	tmo_clock;
-	u_int	tmo_actq;
-#endif
 
 	/*
 	 *  IMMEDIATE ARBITRATION (IARB) control.
@@ -1082,54 +1069,39 @@
  *  FIRMWARES (sym_fw.c)
  */
 struct sym_fw * sym_find_firmware(struct sym_pci_chip *chip);
-void sym_fw_bind_script (hcb_p np, u32 *start, int len);
+void sym_fw_bind_script (struct sym_hcb *np, u32 *start, int len);
 
 /*
  *  Driver methods called from O/S specific code.
  */
 char *sym_driver_name(void);
 void sym_print_xerr(ccb_p cp, int x_status);
-int sym_reset_scsi_bus(hcb_p np, int enab_int);
+int sym_reset_scsi_bus(struct sym_hcb *np, int enab_int);
 struct sym_pci_chip *
 sym_lookup_pci_chip_table (u_short device_id, u_char revision);
-void sym_put_start_queue(hcb_p np, ccb_p cp);
+void sym_put_start_queue(struct sym_hcb *np, ccb_p cp);
 #ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
-void sym_start_next_ccbs(hcb_p np, lcb_p lp, int maxn);
+void sym_start_next_ccbs(struct sym_hcb *np, lcb_p lp, int maxn);
 #endif
-void sym_start_up (hcb_p np, int reason);
-void sym_interrupt (hcb_p np);
-void sym_flush_comp_queue(hcb_p np, int cam_status);
-int sym_clear_tasks(hcb_p np, int cam_status, int target, int lun, int task);
-ccb_p sym_get_ccb (hcb_p np, u_char tn, u_char ln, u_char tag_order);
-void sym_free_ccb (hcb_p np, ccb_p cp);
-lcb_p sym_alloc_lcb (hcb_p np, u_char tn, u_char ln);
-int sym_queue_scsiio(hcb_p np, cam_scsiio_p csio, ccb_p cp);
-int sym_abort_scsiio(hcb_p np, cam_ccb_p ccb, int timed_out);
-int sym_abort_ccb(hcb_p np, ccb_p cp, int timed_out);
-int sym_reset_scsi_target(hcb_p np, int target);
-void sym_hcb_free(hcb_p np);
-int sym_hcb_attach(hcb_p np, struct sym_fw *fw, struct sym_nvram *nvram);
-
-/*
- *  Optionnaly, the driver may handle IO timeouts.
- */
-#ifdef	SYM_OPT_HANDLE_IO_TIMEOUT
-int sym_abort_ccb(hcb_p np, ccb_p cp, int timed_out);
-void sym_timeout_ccb(hcb_p np, ccb_p cp, u_int ticks);
-static void __inline sym_untimeout_ccb(hcb_p np, ccb_p cp)
-{
-	sym_remque(&cp->tmo_linkq);
-	sym_insque_head(&cp->tmo_linkq, &np->tmo0_ccbq);
-}
-void sym_clock(hcb_p np);
-#endif	/* SYM_OPT_HANDLE_IO_TIMEOUT */
+void sym_start_up (struct sym_hcb *np, int reason);
+void sym_interrupt (struct sym_hcb *np);
+int sym_clear_tasks(struct sym_hcb *np, int cam_status, int target, int lun, int task);
+ccb_p sym_get_ccb (struct sym_hcb *np, u_char tn, u_char ln, u_char tag_order);
+void sym_free_ccb (struct sym_hcb *np, ccb_p cp);
+lcb_p sym_alloc_lcb (struct sym_hcb *np, u_char tn, u_char ln);
+int sym_queue_scsiio(struct sym_hcb *np, struct scsi_cmnd *csio, ccb_p cp);
+int sym_abort_scsiio(struct sym_hcb *np, struct scsi_cmnd *ccb, int timed_out);
+int sym_abort_ccb(struct sym_hcb *np, ccb_p cp, int timed_out);
+int sym_reset_scsi_target(struct sym_hcb *np, int target);
+void sym_hcb_free(struct sym_hcb *np);
+int sym_hcb_attach(struct sym_hcb *np, struct sym_fw *fw, struct sym_nvram *nvram);
 
 /*
  *  Optionnaly, the driver may provide a function
  *  to announce transfer rate changes.
  */
 #ifdef	SYM_OPT_ANNOUNCE_TRANSFER_RATE
-void sym_announce_transfer_rate(hcb_p np, int target);
+void sym_announce_transfer_rate(struct sym_hcb *np, int target);
 #endif
 
 /*
@@ -1153,9 +1125,9 @@
 	(data)->size = cpu_to_scr((((badd) >> 8) & 0xff000000) + len);	\
 } while (0)
 #elif SYM_CONF_DMA_ADDRESSING_MODE == 2
-int sym_lookup_dmap(hcb_p np, u32 h, int s);
+int sym_lookup_dmap(struct sym_hcb *np, u32 h, int s);
 static __inline void 
-sym_build_sge(hcb_p np, struct sym_tblmove *data, u64 badd, int len)
+sym_build_sge(struct sym_hcb *np, struct sym_tblmove *data, u64 badd, int len)
 {
 	u32 h = (badd>>32);
 	int s = (h&SYM_DMAP_MASK);
diff -Nru a/drivers/scsi/sym53c8xx_2/sym_malloc.c b/drivers/scsi/sym53c8xx_2/sym_malloc.c
--- a/drivers/scsi/sym53c8xx_2/sym_malloc.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/scsi/sym53c8xx_2/sym_malloc.c	2005-03-01 23:39:09 -08:00
@@ -170,7 +170,7 @@
 	}
 
 	if (p)
-		bzero(p, size);
+		memset(p, 0, size);
 	else if (uflags & SYM_MEM_WARN)
 		printf ("__sym_calloc2: failed to allocate %s[%d]\n", name, size);
 	return p;
diff -Nru a/drivers/scsi/sym53c8xx_2/sym_misc.c b/drivers/scsi/sym53c8xx_2/sym_misc.c
--- a/drivers/scsi/sym53c8xx_2/sym_misc.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/scsi/sym53c8xx_2/sym_misc.c	2005-03-01 23:39:09 -08:00
@@ -37,109 +37,13 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#ifdef __FreeBSD__
-#include <dev/sym/sym_glue.h>
-#else
 #include "sym_glue.h"
-#endif
-
-#ifdef	SYM_OPT_HANDLE_IO_TIMEOUT
-/*
- *  Optional CCB timeout handling.
- *
- *  This code is useful for O/Ses that allow or expect 
- *  SIMs (low-level drivers) to handle SCSI IO timeouts.
- *  It uses a power-of-two based algorithm of my own:) 
- *  that avoids scanning of lists, provided that:
- *
- *  - The IO does complete in less than half the associated
- *    timeout value.
- *  - The greatest delay between the queuing of the IO and 
- *    its completion is less than 
- *          (1<<(SYM_CONF_TIMEOUT_ORDER_MAX-1))/2 ticks.
- *
- *  For example, if tick is 1 second and the max order is 8,
- *  any IO that is completed within less than 64 seconds will 
- *  just be put into some list at queuing and be removed 
- *  at completion without any additionnal overhead.
- */
-
-/*
- *  Set a timeout condition on a CCB.
- */ 
-void sym_timeout_ccb(hcb_p np, ccb_p cp, u_int ticks)
-{
-	sym_remque(&cp->tmo_linkq);
-	cp->tmo_clock = np->tmo_clock + ticks;
-	if (!ticks) {
-		sym_insque_head(&cp->tmo_linkq, &np->tmo0_ccbq);
-	}
-	else {
-		int i = SYM_CONF_TIMEOUT_ORDER_MAX - 1;
-		while (i > 0) {
-			if (ticks >= (1<<(i+1)))
-				break;
-			--i;
-		}
-		if (!(np->tmo_actq & (1<<i)))
-			i += SYM_CONF_TIMEOUT_ORDER_MAX;
-		sym_insque_head(&cp->tmo_linkq, &np->tmo_ccbq[i]);
-	}
-}
-
-/*
- *  Walk a list of CCB and handle timeout conditions.
- *  Should never be called in normal situations.
- */
-static void sym_walk_ccb_tmo_list(hcb_p np, SYM_QUEHEAD *tmoq)
-{
-	SYM_QUEHEAD qtmp, *qp;
-	ccb_p cp;
-
-	sym_que_move(tmoq, &qtmp);
-	while ((qp = sym_remque_head(&qtmp)) != 0) {
-		sym_insque_head(qp, &np->tmo0_ccbq);
-		cp = sym_que_entry(qp, struct sym_ccb, tmo_linkq);
-		if (cp->tmo_clock     != np->tmo_clock &&
-		    cp->tmo_clock + 1 != np->tmo_clock)
-			sym_timeout_ccb(np, cp, cp->tmo_clock - np->tmo_clock);
-		else
-			sym_abort_ccb(np, cp, 1);
-	}
-}
-
-/*
- * Our clock handler called from the O/S specific side.
- */
-void sym_clock(hcb_p np)
-{
-	int i, j;
-	u_int tmp;
-
-	tmp = np->tmo_clock;
-	tmp ^= (++np->tmo_clock);
-
-	for (i = 0; i < SYM_CONF_TIMEOUT_ORDER_MAX; i++, tmp >>= 1) {
-		if (!(tmp & 1))
-			continue;
-		j = i;
-		if (np->tmo_actq & (1<<i))
-			j += SYM_CONF_TIMEOUT_ORDER_MAX;
-
-		if (!sym_que_empty(&np->tmo_ccbq[j])) {
-			sym_walk_ccb_tmo_list(np, &np->tmo_ccbq[j]);
-		}
-		np->tmo_actq ^= (1<<i);
-	}
-}
-#endif	/* SYM_OPT_HANDLE_IO_TIMEOUT */
-
 
 #ifdef	SYM_OPT_ANNOUNCE_TRANSFER_RATE
 /*
  *  Announce transfer rate if anything changed since last announcement.
  */
-void sym_announce_transfer_rate(hcb_p np, int target)
+void sym_announce_transfer_rate(struct sym_hcb *np, int target)
 {
 	tcb_p tp = &np->target[target];
 
diff -Nru a/drivers/scsi/sym53c8xx_2/sym_nvram.c b/drivers/scsi/sym53c8xx_2/sym_nvram.c
--- a/drivers/scsi/sym53c8xx_2/sym_nvram.c	2005-03-01 23:38:59 -08:00
+++ b/drivers/scsi/sym53c8xx_2/sym_nvram.c	2005-03-01 23:38:59 -08:00
@@ -68,6 +68,21 @@
 	case SYM_TEKRAM_NVRAM:
 		np->myaddr = nvram->data.Tekram.host_id & 0x0f;
 		break;
+#ifdef CONFIG_PARISC
+	case SYM_PARISC_PDC:
+		if (nvram->data.parisc.host_id != -1)
+			np->myaddr = nvram->data.parisc.host_id;
+		if (nvram->data.parisc.factor != -1)
+			np->minsync = nvram->data.parisc.factor;
+		if (nvram->data.parisc.width != -1)
+			np->maxwide = nvram->data.parisc.width;
+		switch (nvram->data.parisc.mode) {
+			case 0: np->scsi_mode = SMODE_SE; break;
+			case 1: np->scsi_mode = SMODE_HVD; break;
+			case 2: np->scsi_mode = SMODE_LVD; break;
+			default: break;
+		}
+#endif
 	default:
 		break;
 	}
@@ -702,6 +717,28 @@
 	return 0;
 }
 
+#ifdef CONFIG_PARISC
+/*
+ * Host firmware (PDC) keeps a table for altering SCSI capabilities.
+ * Many newer machines export one channel of 53c896 chip as SE, 50-pin HD.
+ * Also used for Multi-initiator SCSI clusters to set the SCSI Initiator ID.
+ */
+static int sym_read_parisc_pdc(struct sym_device *np, struct pdc_initiator *pdc)
+{
+	struct hardware_path hwpath;
+	get_pci_node_path(np->pdev, &hwpath);
+	if (!pdc_get_initiator(&hwpath, pdc))
+		return 0;
+
+	return SYM_PARISC_PDC;
+}
+#else
+static int sym_read_parisc_pdc(struct sym_device *np, struct pdc_initiator *x)
+{
+	return 0;
+}
+#endif
+
 /*
  *  Try reading Symbios or Tekram NVRAM
  */
@@ -714,7 +751,7 @@
 		nvp->type = SYM_TEKRAM_NVRAM;
 		sym_display_Tekram_nvram(np, &nvp->data.Tekram);
 	} else {
-		nvp->type = 0;
+		nvp->type = sym_read_parisc_pdc(np, &nvp->data.parisc);
 	}
 	return nvp->type;
 }
diff -Nru a/drivers/scsi/sym53c8xx_2/sym_nvram.h b/drivers/scsi/sym53c8xx_2/sym_nvram.h
--- a/drivers/scsi/sym53c8xx_2/sym_nvram.h	2005-03-01 23:39:09 -08:00
+++ b/drivers/scsi/sym53c8xx_2/sym_nvram.h	2005-03-01 23:39:09 -08:00
@@ -171,6 +171,10 @@
 typedef struct Tekram_nvram	Tekram_nvram;
 typedef struct Tekram_target	Tekram_target;
 
+#ifndef CONFIG_PARISC
+struct pdc_initiator { int dummy; };
+#endif
+
 /*
  *  Union of supported NVRAM formats.
  */
@@ -178,10 +182,12 @@
 	int type;
 #define	SYM_SYMBIOS_NVRAM	(1)
 #define	SYM_TEKRAM_NVRAM	(2)
+#define SYM_PARISC_PDC		(3)
 #if SYM_CONF_NVRAM_SUPPORT
 	union {
 		Symbios_nvram Symbios;
 		Tekram_nvram Tekram;
+		struct pdc_initiator parisc;
 	} data;
 #endif
 };
diff -Nru a/drivers/scsi/sym53c8xx_comm.h b/drivers/scsi/sym53c8xx_comm.h
--- a/drivers/scsi/sym53c8xx_comm.h	2005-03-01 23:38:58 -08:00
+++ b/drivers/scsi/sym53c8xx_comm.h	2005-03-01 23:38:58 -08:00
@@ -250,7 +250,7 @@
 	}
 }
 
-static spinlock_t ncr53c8xx_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(ncr53c8xx_lock);
 
 static void *__m_calloc2(m_pool_s *mp, int size, char *name, int uflags)
 {
@@ -505,8 +505,6 @@
 #define unmap_scsi_data(np, cmd)	__unmap_scsi_data(np->dev, cmd)
 #define map_scsi_single_data(np, cmd)	__map_scsi_single_data(np->dev, cmd)
 #define map_scsi_sg_data(np, cmd)	__map_scsi_sg_data(np->dev, cmd)
-#define sync_scsi_data_for_cpu(np, cmd)	__sync_scsi_data_for_cpu(np->dev, cmd)
-#define sync_scsi_data_for_device(np, cmd) __sync_scsi_data_for_device(np->dev, cmd)
 
 /*==========================================================
 **
diff -Nru a/drivers/scsi/u14-34f.c b/drivers/scsi/u14-34f.c
--- a/drivers/scsi/u14-34f.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/scsi/u14-34f.c	2005-03-01 23:38:54 -08:00
@@ -612,7 +612,7 @@
 static struct Scsi_Host *sh[MAX_BOARDS + 1];
 static const char *driver_name = "Ux4F";
 static char sha[MAX_BOARDS];
-static spinlock_t driver_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(driver_lock);
 
 /* Initialize num_boards so that ihdlr can work while detect is in progress */
 static unsigned int num_boards = MAX_BOARDS;
diff -Nru a/drivers/scsi/wd33c93.h b/drivers/scsi/wd33c93.h
--- a/drivers/scsi/wd33c93.h	2005-03-01 23:39:18 -08:00
+++ b/drivers/scsi/wd33c93.h	2005-03-01 23:39:18 -08:00
@@ -22,6 +22,8 @@
 #ifndef WD33C93_H
 #define WD33C93_H
 
+#include <linux/config.h>
+
 #define PROC_INTERFACE     /* add code for /proc/scsi/wd33c93/xxx interface */
 #ifdef  PROC_INTERFACE
 #define PROC_STATISTICS    /* add code for keeping various real time stats */
diff -Nru a/drivers/scsi/zalon.c b/drivers/scsi/zalon.c
--- a/drivers/scsi/zalon.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/scsi/zalon.c	2005-03-01 23:39:07 -08:00
@@ -87,7 +87,7 @@
 {
 	struct gsc_irq gsc_irq;
 	u32 zalon_vers;
-	int irq, error = -ENODEV;
+	int error = -ENODEV;
 	unsigned long zalon = dev->hpa;
 	unsigned long io_port = zalon + GSC_SCSI_ZALON_OFFSET;
 	static int unit = 0;
@@ -107,10 +107,10 @@
 	/* Setup the interrupts first.
 	** Later on request_irq() will register the handler.
 	*/
-	irq = gsc_alloc_irq(&gsc_irq);
+	dev->irq = gsc_alloc_irq(&gsc_irq);
 
 	printk("%s: Zalon vers field is 0x%x, IRQ %d\n", __FUNCTION__,
-		zalon_vers, irq);
+		zalon_vers, dev->irq);
 
 	__raw_writel(gsc_irq.txn_addr | gsc_irq.txn_data, dev->hpa + IO_MODULE_EIM);
 
@@ -130,16 +130,16 @@
 	device.dev		= &dev->dev;
 	device.slot.base	= (u_long)io_port;
 	device.slot.base_c	= (u_long)io_port;
-	device.slot.irq		= irq;
+	device.slot.irq		= dev->irq;
 	device.differential	= 2;
 
 	host = ncr_attach(&zalon7xx_template, unit, &device);
 	if (!host)
 		goto fail;
 
-	if (request_irq(irq, ncr53c8xx_intr, SA_SHIRQ, dev->dev.bus_id, host)) {
+	if (request_irq(dev->irq, ncr53c8xx_intr, SA_SHIRQ, "zalon", host)) {
 		printk(KERN_ERR "%s: irq problem with %d, detaching\n ",
-			dev->dev.bus_id, irq);
+			dev->dev.bus_id, dev->irq);
 		goto fail;
 	}
 
@@ -155,7 +155,7 @@
 	return 0;
 
  fail_free_irq:
-	free_irq(irq, host);
+	free_irq(dev->irq, host);
  fail:
 	ncr53c8xx_release(host);
 	return error;
@@ -171,18 +171,16 @@
 static int __exit zalon_remove(struct parisc_device *dev)
 {
 	struct Scsi_Host *host = dev_get_drvdata(&dev->dev);
-	int irq = host->irq;
 
 	scsi_remove_host(host);
 	ncr53c8xx_release(host);
-	free_irq(irq, host);
+	free_irq(dev->irq, host);
 
 	return 0;
 }
-	
 
 static struct parisc_driver zalon_driver = {
-	.name =		"GSC SCSI (Zalon)",
+	.name =		"zalon",
 	.id_table =	zalon_tbl,
 	.probe =	zalon_probe,
 	.remove =	__devexit_p(zalon_remove),
@@ -201,6 +199,7 @@
 static void __exit zalon7xx_exit(void)
 {
 	unregister_parisc_driver(&zalon_driver);
+	ncr53c8xx_exit();
 }
 
 module_init(zalon7xx_init);
diff -Nru a/drivers/serial/8250.c b/drivers/serial/8250.c
--- a/drivers/serial/8250.c	2005-03-01 23:38:51 -08:00
+++ b/drivers/serial/8250.c	2005-03-01 23:38:51 -08:00
@@ -31,6 +31,7 @@
 #include <linux/init.h>
 #include <linux/console.h>
 #include <linux/sysrq.h>
+#include <linux/mca.h>
 #include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/tty.h>
@@ -449,9 +450,11 @@
  */
 static int size_fifo(struct uart_8250_port *up)
 {
-	unsigned char old_fcr, old_mcr, old_dll, old_dlm;
+	unsigned char old_fcr, old_mcr, old_dll, old_dlm, old_lcr;
 	int count;
 
+	old_lcr = serial_inp(up, UART_LCR);
+	serial_outp(up, UART_LCR, 0);
 	old_fcr = serial_inp(up, UART_FCR);
 	old_mcr = serial_inp(up, UART_MCR);
 	serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO |
@@ -474,11 +477,40 @@
 	serial_outp(up, UART_LCR, UART_LCR_DLAB);
 	serial_outp(up, UART_DLL, old_dll);
 	serial_outp(up, UART_DLM, old_dlm);
+	serial_outp(up, UART_LCR, old_lcr);
 
 	return count;
 }
 
 /*
+ * Read UART ID using the divisor method - set DLL and DLM to zero
+ * and the revision will be in DLL and device type in DLM.  We
+ * preserve the device state across this.
+ */
+static unsigned int autoconfig_read_divisor_id(struct uart_8250_port *p)
+{
+	unsigned char old_dll, old_dlm, old_lcr;
+	unsigned int id;
+
+	old_lcr = serial_inp(p, UART_LCR);
+	serial_outp(p, UART_LCR, UART_LCR_DLAB);
+
+	old_dll = serial_inp(p, UART_DLL);
+	old_dlm = serial_inp(p, UART_DLM);
+
+	serial_outp(p, UART_DLL, 0);
+	serial_outp(p, UART_DLM, 0);
+
+	id = serial_inp(p, UART_DLL) | serial_inp(p, UART_DLM) << 8;
+
+	serial_outp(p, UART_DLL, old_dll);
+	serial_outp(p, UART_DLM, old_dlm);
+	serial_outp(p, UART_LCR, old_lcr);
+
+	return id;
+}
+
+/*
  * This is a helper routine to autodetect StarTech/Exar/Oxsemi UART's.
  * When this function is called we know it is at least a StarTech
  * 16650 V2, but it might be one of several StarTech UARTs, or one of
@@ -490,7 +522,7 @@
  */
 static void autoconfig_has_efr(struct uart_8250_port *up)
 {
-	unsigned char id1, id2, id3, rev, saved_dll, saved_dlm;
+	unsigned int id1, id2, id3, rev;
 
 	/*
 	 * Everything with an EFR has SLEEP
@@ -540,21 +572,13 @@
 	 *  0x12 - XR16C2850.
 	 *  0x14 - XR16C854.
 	 */
-	serial_outp(up, UART_LCR, UART_LCR_DLAB);
-	saved_dll = serial_inp(up, UART_DLL);
-	saved_dlm = serial_inp(up, UART_DLM);
-	serial_outp(up, UART_DLL, 0);
-	serial_outp(up, UART_DLM, 0);
-	id2 = serial_inp(up, UART_DLL);
-	id1 = serial_inp(up, UART_DLM);
-	serial_outp(up, UART_DLL, saved_dll);
-	serial_outp(up, UART_DLM, saved_dlm);
-
-	DEBUG_AUTOCONF("850id=%02x:%02x ", id1, id2);
-
-	if (id1 == 0x10 || id1 == 0x12 || id1 == 0x14) {
-		if (id1 == 0x10)
-			up->rev = id2;
+	id1 = autoconfig_read_divisor_id(up);
+	DEBUG_AUTOCONF("850id=%04x ", id1);
+
+	id2 = id1 >> 8;
+	if (id2 == 0x10 || id2 == 0x12 || id2 == 0x14) {
+		if (id2 == 0x10)
+			up->rev = id1 & 255;
 		up->port.type = PORT_16850;
 		return;
 	}
@@ -596,6 +620,19 @@
 		up->port.type = PORT_16450;
 }
 
+static int broken_efr(struct uart_8250_port *up)
+{
+	/*
+	 * Exar ST16C2550 "A2" devices incorrectly detect as
+	 * having an EFR, and report an ID of 0x0201.  See
+	 * http://www.exar.com/info.php?pdf=dan180_oct2004.pdf
+	 */
+	if (autoconfig_read_divisor_id(up) == 0x0201 && size_fifo(up) == 16)
+		return 1;
+
+	return 0;
+}
+
 /*
  * We know that the chip has FIFOs.  Does it have an EFR?  The
  * EFR is located in the same register position as the IIR and
@@ -632,7 +669,7 @@
 	 * (other ST16C650V2 UARTs, TI16C752A, etc)
 	 */
 	serial_outp(up, UART_LCR, 0xBF);
-	if (serial_in(up, UART_EFR) == 0) {
+	if (serial_in(up, UART_EFR) == 0 && !broken_efr(up)) {
 		DEBUG_AUTOCONF("EFRv2 ");
 		autoconfig_has_efr(up);
 		return;
@@ -986,8 +1023,11 @@
 		/* The following is not allowed by the tty layer and
 		   unsafe. It should be fixed ASAP */
 		if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) {
-			if(tty->low_latency)
+			if (tty->low_latency) {
+				spin_unlock(&up->port.lock);
 				tty_flip_buffer_push(tty);
+				spin_lock(&up->port.lock);
+			}
 			/* If this failed then we will throw away the
 			   bytes but must do so to clear interrupts */
 		}
@@ -1058,7 +1098,9 @@
 	ignore_char:
 		lsr = serial_inp(up, UART_LSR);
 	} while ((lsr & UART_LSR_DR) && (max_count-- > 0));
+	spin_unlock(&up->port.lock);
 	tty_flip_buffer_push(tty);
+	spin_lock(&up->port.lock);
 	*status = lsr;
 }
 
@@ -1861,13 +1903,11 @@
 	int probeflags = PROBE_ANY;
 	int ret;
 
-#ifdef CONFIG_MCA
 	/*
 	 * Don't probe for MCA ports on non-MCA machines.
 	 */
 	if (up->port.flags & UPF_BOOT_ONLYMCA && !MCA_bus)
 		return;
-#endif
 
 	/*
 	 * Find the region that we can probe for.  This in turn
diff -Nru a/drivers/serial/8250_gsc.c b/drivers/serial/8250_gsc.c
--- a/drivers/serial/8250_gsc.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/serial/8250_gsc.c	2005-03-01 23:39:08 -08:00
@@ -40,7 +40,7 @@
 		 * what we have here is a missing parent device, so tell
 		 * the user what they're missing.
 		 */
-		if (dev->parent->id.hw_type != HPHW_IOA) {
+		if (parisc_parent(dev)->id.hw_type != HPHW_IOA) {
 			printk(KERN_INFO "Serial: device 0x%lx not configured.\n"
 				"Enable support for Wax, Lasi, Asp or Dino.\n", dev->hpa);
 		}
@@ -65,7 +65,7 @@
 		printk(KERN_WARNING "serial8250_register_port returned error %d\n", err);
 		return err;
 	}
-
+        
 	return 0;
 }
 
@@ -99,13 +99,13 @@
 MODULE_DEVICE_TABLE(parisc, serial_tbl);
 
 static struct parisc_driver lasi_driver = {
-	.name		= "Lasi RS232",
+	.name		= "serial_1",
 	.id_table	= lasi_tbl,
 	.probe		= serial_init_chip,
 };
 
 static struct parisc_driver serial_driver = {
-	.name		= "Serial RS232",
+	.name		= "serial",
 	.id_table	= serial_tbl,
 	.probe		= serial_init_chip,
 };
diff -Nru a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c
--- a/drivers/serial/8250_pci.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/serial/8250_pci.c	2005-03-01 23:39:08 -08:00
@@ -2212,6 +2212,13 @@
 		0, pbn_exar_XR17C158 },
 
 	/*
+	 * Topic TP560 Data/Fax/Voice 56k modem (reported by Evan Clarke)
+	 */
+	{	PCI_VENDOR_ID_TOPIC, PCI_DEVICE_ID_TOPIC_TP560,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_b0_1_115200 },
+
+	/*
 	 * These entries match devices with class COMMUNICATION_SERIAL,
 	 * COMMUNICATION_MODEM or COMMUNICATION_MULTISERIAL
 	 */
@@ -2241,7 +2248,7 @@
 
 static int __init serial8250_pci_init(void)
 {
-	return pci_module_init(&serial_pci_driver);
+	return pci_register_driver(&serial_pci_driver);
 }
 
 static void __exit serial8250_pci_exit(void)
diff -Nru a/drivers/serial/8250_pnp.c b/drivers/serial/8250_pnp.c
--- a/drivers/serial/8250_pnp.c	2005-03-01 23:38:51 -08:00
+++ b/drivers/serial/8250_pnp.c	2005-03-01 23:38:51 -08:00
@@ -250,6 +250,8 @@
 	/* Kortex International */
 	/* KORTEX 14400 Externe PnP */
 	{	"ROK0100",		0	},
+	/* Rockwell 28.8 */
+	{	"ROK4120",		0	},
 	/* Viking Components, Inc */
 	/* Viking 28.8 INTERNAL Fax+Data+Voice PnP */
 	{	"ROK4920",		0	},
@@ -419,14 +421,14 @@
 	line = serial8250_register_port(&port);
 
 	if (line >= 0)
-		pnp_set_drvdata(dev, (void *)(line + 1));
+		pnp_set_drvdata(dev, (void *)((long)line + 1));
 	return line >= 0 ? 0 : -ENODEV;
 
 }
 
 static void __devexit serial_pnp_remove(struct pnp_dev * dev)
 {
-	int line = (int)pnp_get_drvdata(dev);
+	long line = (long)pnp_get_drvdata(dev);
 	if (line)
 		serial8250_unregister_port(line - 1);
 }
diff -Nru a/drivers/serial/Kconfig b/drivers/serial/Kconfig
--- a/drivers/serial/Kconfig	2005-03-01 23:39:16 -08:00
+++ b/drivers/serial/Kconfig	2005-03-01 23:39:16 -08:00
@@ -321,7 +321,7 @@
 	select SERIAL_CORE
 	help
 	  Say Y here if you want to use the hard logic uart on Excalibur. This
-	  driver also supports soft logic implentations of this uart core.
+	  driver also supports soft logic implementations of this uart core.
 
 config SERIAL_UART00_CONSOLE
 	bool "Support for console on Excalibur serial port"
@@ -338,6 +338,20 @@
 	  your boot loader (lilo or loadlin) about how to pass options to the
 	  kernel at boot time.)
 
+config SERIAL_MPSC
+	bool "Marvell MPSC serial port support"
+	depends on PPC32 && MV64X60
+	select SERIAL_CORE
+	help
+	  Say Y here if you want to use the Marvell MPSC serial controller.
+
+config SERIAL_MPSC_CONSOLE
+	bool "Support for console on Marvell MPSC serial port"
+	depends on SERIAL_MPSC
+	select SERIAL_CORE_CONSOLE
+	help
+	  Say Y here if you want to support a serial console on a Marvell MPSC.
+
 config SERIAL_PXA
 	bool "PXA serial port support"
 	depends on ARM && ARCH_PXA
@@ -515,7 +529,6 @@
 	bool "Console on IP22 Zilog8530 serial port"
 	depends on SERIAL_IP22_ZILOG=y
 	select SERIAL_CORE_CONSOLE
-	help
 
 config V850E_UART
 	bool "NEC V850E on-chip UART support"
@@ -627,7 +640,7 @@
 	  Sharp LH7A40X series CPUs.  Choose Y or M.
 
 config SERIAL_LH7A40X_CONSOLE
-	bool "Support for connsole on Sharp LH7A40X serial port"
+	bool "Support for console on Sharp LH7A40X serial port"
 	depends on SERIAL_LH7A40X=y
 	select SERIAL_CORE_CONSOLE
 	help
@@ -778,5 +791,23 @@
 
 	  If you use an M3T-M32700UT or an OPSPUT platform,
 	  please say Y.
+
+config SERIAL_TXX9
+	bool "TMPTX39XX/49XX SIO support"
+	depends HAS_TXX9_SERIAL
+	select SERIAL_CORE
+	default y
+
+config HAS_TXX9_SERIAL
+	bool
+
+config SERIAL_TXX9_CONSOLE
+	bool "TMPTX39XX/49XX SIO Console support"
+	depends on SERIAL_TXX9=y
+	select SERIAL_CORE_CONSOLE
+
+config SERIAL_TXX9_STDSERIAL
+	bool "TX39XX/49XX SIO act as standard serial"
+	depends on !SERIAL_8250 && SERIAL_TXX9
 
 endmenu
diff -Nru a/drivers/serial/Makefile b/drivers/serial/Makefile
--- a/drivers/serial/Makefile	2005-03-01 23:38:57 -08:00
+++ b/drivers/serial/Makefile	2005-03-01 23:38:57 -08:00
@@ -6,9 +6,9 @@
 
 serial-8250-y :=
 serial-8250-$(CONFIG_SERIAL_8250_ACPI) += 8250_acpi.o
+serial-8250-$(CONFIG_PNP) += 8250_pnp.o
 serial-8250-$(CONFIG_GSC) += 8250_gsc.o
 serial-8250-$(CONFIG_PCI) += 8250_pci.o
-serial-8250-$(CONFIG_PNP) += 8250_pnp.o
 serial-8250-$(CONFIG_HP300) += 8250_hp300.o
 
 obj-$(CONFIG_SERIAL_CORE) += serial_core.o
@@ -46,4 +46,6 @@
 obj-$(CONFIG_SERIAL_MPC52xx) += mpc52xx_uart.o
 obj-$(CONFIG_SERIAL_ICOM) += icom.o
 obj-$(CONFIG_SERIAL_M32R_SIO) += m32r_sio.o
-obj-$(CONFIG_ETRAX_SERIAL) += crisv10.o
\ No newline at end of file
+obj-$(CONFIG_SERIAL_MPSC) += mpsc.o
+obj-$(CONFIG_ETRAX_SERIAL) += crisv10.o
+obj-$(CONFIG_SERIAL_TXX9) += serial_txx9.o
diff -Nru 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	2005-03-01 23:39:10 -08:00
+++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.c	2005-03-01 23:39:10 -08:00
@@ -127,7 +127,7 @@
 	io->iop_pdird |= 0x00000002;	/* Tx */
 
 	/* Wire BRG1 to SCC1 */
-	cpm2_immr->im_cpmux.cmx_scr &= ~0x00ffffff;
+	cpm2_immr->im_cpmux.cmx_scr &= 0x00ffffff;
 	cpm2_immr->im_cpmux.cmx_scr |= 0x00000000;
 	pinfo->brg = 1;
 }
@@ -140,7 +140,7 @@
 	io->iop_psorb |= 0x00880000;
 	io->iop_pdirb &= ~0x00030000;
 	io->iop_psorb &= ~0x00030000;
-	cpm2_immr->im_cpmux.cmx_scr &= ~0xff00ffff;
+	cpm2_immr->im_cpmux.cmx_scr &= 0xff00ffff;
 	cpm2_immr->im_cpmux.cmx_scr |= 0x00090000;
 	pinfo->brg = 2;
 }
@@ -153,7 +153,7 @@
 	io->iop_psorb |= 0x00880000;
 	io->iop_pdirb &= ~0x00030000;
 	io->iop_psorb &= ~0x00030000;
-	cpm2_immr->im_cpmux.cmx_scr &= ~0xffff00ff;
+	cpm2_immr->im_cpmux.cmx_scr &= 0xffff00ff;
 	cpm2_immr->im_cpmux.cmx_scr |= 0x00001200;
 	pinfo->brg = 3;
 }
@@ -167,7 +167,7 @@
 	io->iop_pdird &= ~0x00000200;	/* Rx */
 	io->iop_pdird |= 0x00000400;	/* Tx */
 
-	cpm2_immr->im_cpmux.cmx_scr &= ~0xffffff00;
+	cpm2_immr->im_cpmux.cmx_scr &= 0xffffff00;
 	cpm2_immr->im_cpmux.cmx_scr |= 0x0000001b;
 	pinfo->brg = 4;
 }
diff -Nru a/drivers/serial/icom.c b/drivers/serial/icom.c
--- a/drivers/serial/icom.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/serial/icom.c	2005-03-01 23:38:54 -08:00
@@ -105,25 +105,25 @@
 };
 
 struct lookup_proc_table start_proc[4] = {
-	{0, ICOM_CONTROL_START_A},
-	{0, ICOM_CONTROL_START_B},
-	{0, ICOM_CONTROL_START_C},
-	{0, ICOM_CONTROL_START_D}
+	{NULL, ICOM_CONTROL_START_A},
+	{NULL, ICOM_CONTROL_START_B},
+	{NULL, ICOM_CONTROL_START_C},
+	{NULL, ICOM_CONTROL_START_D}
 };
 
 
 struct lookup_proc_table stop_proc[4] = {
-	{0, ICOM_CONTROL_STOP_A},
-	{0, ICOM_CONTROL_STOP_B},
-	{0, ICOM_CONTROL_STOP_C},
-	{0, ICOM_CONTROL_STOP_D}
+	{NULL, ICOM_CONTROL_STOP_A},
+	{NULL, ICOM_CONTROL_STOP_B},
+	{NULL, ICOM_CONTROL_STOP_C},
+	{NULL, ICOM_CONTROL_STOP_D}
 };
 
 struct lookup_int_table int_mask_tbl[4] = {
-	{0, ICOM_INT_MASK_PRC_A},
-	{0, ICOM_INT_MASK_PRC_B},
-	{0, ICOM_INT_MASK_PRC_C},
-	{0, ICOM_INT_MASK_PRC_D},
+	{NULL, ICOM_INT_MASK_PRC_A},
+	{NULL, ICOM_INT_MASK_PRC_B},
+	{NULL, ICOM_INT_MASK_PRC_C},
+	{NULL, ICOM_INT_MASK_PRC_D},
 };
 
 
@@ -148,23 +148,23 @@
 	if (icom_port->recv_buf) {
 		pci_free_consistent(dev, 4096, icom_port->recv_buf,
 				    icom_port->recv_buf_pci);
-		icom_port->recv_buf = 0;
+		icom_port->recv_buf = NULL;
 	}
 	if (icom_port->xmit_buf) {
 		pci_free_consistent(dev, 4096, icom_port->xmit_buf,
 				    icom_port->xmit_buf_pci);
-		icom_port->xmit_buf = 0;
+		icom_port->xmit_buf = NULL;
 	}
 	if (icom_port->statStg) {
 		pci_free_consistent(dev, 4096, icom_port->statStg,
 				    icom_port->statStg_pci);
-		icom_port->statStg = 0;
+		icom_port->statStg = NULL;
 	}
 
 	if (icom_port->xmitRestart) {
 		pci_free_consistent(dev, 4096, icom_port->xmitRestart,
 				    icom_port->xmitRestart_pci);
-		icom_port->xmitRestart = 0;
+		icom_port->xmitRestart = NULL;
 	}
 }
 
@@ -344,17 +344,17 @@
 static void load_code(struct icom_port *icom_port)
 {
 	const struct firmware *fw;
-	char *iram_ptr;
+	char __iomem *iram_ptr;
 	int index;
 	int status = 0;
-	char *dram_ptr = (char *) icom_port->dram;
+	void __iomem *dram_ptr = icom_port->dram;
 	dma_addr_t temp_pci;
 	unsigned char *new_page = NULL;
 	unsigned char cable_id = NO_CABLE;
 	struct pci_dev *dev = icom_port->adapter->pci_dev;
 
 	/* Clear out any pending interrupts */
-	writew(0x3FFF, (void *) icom_port->int_reg);
+	writew(0x3FFF, icom_port->int_reg);
 
 	trace(icom_port, "CLEAR_INTERRUPTS", 0);
 
@@ -378,7 +378,7 @@
 		goto load_code_exit;
 	}
 
-	iram_ptr = (char *) icom_port->dram + ICOM_IRAM_OFFSET;
+	iram_ptr = (char __iomem *)icom_port->dram + ICOM_IRAM_OFFSET;
 	for (index = 0; index < fw->size; index++)
 		writeb(fw->data[index], &iram_ptr[index]);
 
@@ -398,7 +398,7 @@
 		goto load_code_exit;
 	}
 
-	iram_ptr = (char *) icom_port->dram + ICOM_IRAM_OFFSET;
+	iram_ptr = (char __iomem *) icom_port->dram + ICOM_IRAM_OFFSET;
 	for (index = ICOM_DCE_IRAM_OFFSET; index < fw->size; index++)
 		writeb(fw->data[index], &iram_ptr[index]);
 
@@ -490,7 +490,7 @@
 
 	if (status != 0) {
 		/* Clear out any pending interrupts */
-		writew(0x3FFF, (void *) icom_port->int_reg);
+		writew(0x3FFF, icom_port->int_reg);
 
 		/* Turn off port */
 		writeb(ICOM_DISABLE, &(icom_port->dram->disable));
@@ -514,8 +514,8 @@
 
 	trace(icom_port, "STARTUP", 0);
 
-	if (icom_port->dram == 0x00000000) {
-		/* should NEVER be zero */
+	if (!icom_port->dram) {
+		/* should NEVER be NULL */
 		dev_err(&icom_port->adapter->pci_dev->dev,
 			"Unusable Port, port configuration missing\n");
 		return -ENODEV;
@@ -556,9 +556,9 @@
 		int_mask_tbl[port].global_int_mask = &icom_port->global_reg->int_mask_2;
 
 	if (port == 0 || port == 2)
-		writew(0x00FF,(void *) icom_port->int_reg);
+		writew(0x00FF, icom_port->int_reg);
 	else
-		writew(0x3F00,(void *) icom_port->int_reg);
+		writew(0x3F00, icom_port->int_reg);
 	if (port < 4) {
 		temp = readl(int_mask_tbl[port].global_int_mask);
 		writel(temp & ~int_mask_tbl[port].processor_id, int_mask_tbl[port].global_int_mask);
@@ -859,7 +859,7 @@
 static irqreturn_t icom_interrupt(int irq, void *dev_id,
 				  struct pt_regs *regs)
 {
-	unsigned long int_reg;
+	void __iomem * int_reg;
 	u32 adapter_interrupts;
 	u16 port_int_reg;
 	struct icom_adapter *icom_adapter;
@@ -871,7 +871,7 @@
 	if ((icom_adapter->version | ADAPTER_V2) == ADAPTER_V2) {
 		int_reg = icom_adapter->base_addr + 0x8024;
 
-		adapter_interrupts = readl((void *) int_reg);
+		adapter_interrupts = readl(int_reg);
 
 		if (adapter_interrupts & 0x00003FFF) {
 			/* port 2 interrupt,  NOTE:  for all ADAPTER_V2, port 2 will be active */
@@ -892,14 +892,14 @@
 		}
 
 		/* Clear out any pending interrupts */
-		writel(adapter_interrupts, (void *) int_reg);
+		writel(adapter_interrupts, int_reg);
 
 		int_reg = icom_adapter->base_addr + 0x8004;
 	} else {
 		int_reg = icom_adapter->base_addr + 0x4004;
 	}
 
-	adapter_interrupts = readl((void *) int_reg);
+	adapter_interrupts = readl(int_reg);
 
 	if (adapter_interrupts & 0x00003FFF) {
 		/* port 0 interrupt, NOTE:  for all adapters, port 0 will be active */
@@ -919,10 +919,10 @@
 	}
 
 	/* Clear out any pending interrupts */
-	writel(adapter_interrupts, (void *) int_reg);
+	writel(adapter_interrupts, int_reg);
 
 	/* flush the write */
-	adapter_interrupts = readl((void *) int_reg);
+	adapter_interrupts = readl(int_reg);
 
 	return IRQ_HANDLED;
 }
@@ -1383,18 +1383,16 @@
 static void icom_port_active(struct icom_port *icom_port, struct icom_adapter *icom_adapter, int port_num)
 {
 	if (icom_adapter->version == ADAPTER_V1) {
-		icom_port->global_reg = (struct icom_regs *) ((char *)
-			icom_adapter->base_addr + 0x4000);
-		icom_port->int_reg = (unsigned long) icom_adapter->base_addr +
+		icom_port->global_reg = icom_adapter->base_addr + 0x4000;
+		icom_port->int_reg = icom_adapter->base_addr +
 		    0x4004 + 2 - 2 * port_num;
 	} else {
-		icom_port->global_reg = (struct icom_regs *) ((char *)
-			icom_adapter->base_addr + 0x8000);
+		icom_port->global_reg = icom_adapter->base_addr + 0x8000;
 		if (icom_port->port < 2)
-			icom_port->int_reg = (unsigned long) icom_adapter->base_addr +
+			icom_port->int_reg = icom_adapter->base_addr +
 			    0x8004 + 2 - 2 * icom_port->port;
 		else
-			icom_port->int_reg = (unsigned long) icom_adapter->base_addr +
+			icom_port->int_reg = icom_adapter->base_addr +
 			    0x8024 + 2 - 2 * (icom_port->port - 2);
 	}
 }
@@ -1410,9 +1408,8 @@
 
 		if (icom_port->status == ICOM_PORT_ACTIVE) {
 			icom_port_active(icom_port, icom_adapter, port_num);
-			icom_port->dram = (struct func_dram *) ((char *)
-					icom_adapter->base_addr +
-					0x2000 * icom_port->port);
+			icom_port->dram = icom_adapter->base_addr +
+					0x2000 * icom_port->port;
 
 			icom_port->adapter = icom_adapter;
 
@@ -1495,7 +1492,7 @@
 	}
 
 	free_irq(icom_adapter->irq_number, (void *) icom_adapter);
-	iounmap((void *) icom_adapter->base_addr);
+	iounmap(icom_adapter->base_addr);
 	icom_free_adapter(icom_adapter);
 	pci_release_regions(icom_adapter->pci_dev);
 }
@@ -1572,8 +1569,7 @@
 		goto probe_exit1;
 	}
 
-	 icom_adapter->base_addr =
-	     (unsigned long) ioremap(icom_adapter->base_addr_pci,
+	 icom_adapter->base_addr = ioremap(icom_adapter->base_addr_pci,
 						pci_resource_len(dev, 0));
 
 	if (!icom_adapter->base_addr)
@@ -1614,7 +1610,7 @@
 	return 0;
 
 probe_exit2:
-	iounmap((void *) icom_adapter->base_addr);
+	iounmap(icom_adapter->base_addr);
 probe_exit1:
 	icom_free_adapter(icom_adapter);
 
@@ -1656,7 +1652,6 @@
 	int ret;
 
 	spin_lock_init(&icom_lock);
-	icom_lock = (spinlock_t) SPIN_LOCK_UNLOCKED;
 
 	ret = uart_register_driver(&icom_uart_driver);
 	if (ret)
diff -Nru a/drivers/serial/icom.h b/drivers/serial/icom.h
--- a/drivers/serial/icom.h	2005-03-01 23:38:44 -08:00
+++ b/drivers/serial/icom.h	2005-03-01 23:38:44 -08:00
@@ -234,9 +234,9 @@
 	unsigned char cable_id;
 	unsigned char read_status_mask;
 	unsigned char ignore_status_mask;
-	unsigned long int_reg;
-	struct icom_regs *global_reg;
-	struct func_dram *dram;
+	void __iomem * int_reg;
+	struct icom_regs __iomem *global_reg;
+	struct func_dram __iomem *dram;
 	int port;
 	struct statusArea *statStg;
 	dma_addr_t statStg_pci;
@@ -256,7 +256,7 @@
 };
 
 struct icom_adapter {
-	unsigned long base_addr;
+	void __iomem * base_addr;
 	unsigned long base_addr_pci;
 	unsigned char irq_number;
 	struct pci_dev *pci_dev;
@@ -278,12 +278,12 @@
 extern void iCom_sercons_init(void);
 
 struct lookup_proc_table {
-	u32	*global_control_reg;
+	u32	__iomem *global_control_reg;
 	unsigned long	processor_id;
 };
 
 struct lookup_int_table {
-	u32	*global_int_mask;
+	u32	__iomem *global_int_mask;
 	unsigned long	processor_id;
 };
 
diff -Nru a/drivers/serial/ip22zilog.c b/drivers/serial/ip22zilog.c
--- a/drivers/serial/ip22zilog.c	2005-03-01 23:38:59 -08:00
+++ b/drivers/serial/ip22zilog.c	2005-03-01 23:38:59 -08:00
@@ -47,8 +47,6 @@
 
 #include "ip22zilog.h"
 
-int ip22serial_current_minor = 64;
-
 void ip22_do_break(void);
 
 /*
@@ -59,10 +57,10 @@
 #define ZSDELAY_LONG()		udelay(20)
 #define ZS_WSYNC(channel)	do { } while (0)
 
-#define NUM_IP22ZILOG	1
-#define NUM_CHANNELS	(NUM_IP22ZILOG * 2)
+#define NUM_IP22ZILOG		1
+#define NUM_CHANNELS		(NUM_IP22ZILOG * 2)
 
-#define ZS_CLOCK		4915200 /* Zilog input clock rate. */
+#define ZS_CLOCK		3672000	/* Zilog input clock rate. */
 #define ZS_CLOCK_DIVISOR	16      /* Divisor this driver uses. */
 
 /*
@@ -86,7 +84,7 @@
 #define IP22ZILOG_FLAG_TX_STOPPED	0x00000080
 #define IP22ZILOG_FLAG_TX_ACTIVE	0x00000100
 
-	unsigned int cflag;
+	unsigned int			cflag;
 
 	/* L1-A keyboard break state.  */
 	int				kbd_id;
@@ -642,36 +640,28 @@
 	}
 }
 
-/* The port lock is not held.  */
+/* The port lock is held and interrupts are disabled.  */
 static void ip22zilog_stop_rx(struct uart_port *port)
 {
 	struct uart_ip22zilog_port *up = UART_ZILOG(port);
 	struct zilog_channel *channel;
-	unsigned long flags;
 
 	if (ZS_IS_CONS(up))
 		return;
 
-	spin_lock_irqsave(&port->lock, flags);
-
 	channel = ZILOG_CHANNEL_FROM_PORT(port);
 
 	/* Disable all RX interrupts.  */
 	up->curregs[R1] &= ~RxINT_MASK;
 	ip22zilog_maybe_update_regs(up, channel);
-
-	spin_unlock_irqrestore(&port->lock, flags);
 }
 
-/* The port lock is not held.  */
+/* The port lock is held.  */
 static void ip22zilog_enable_ms(struct uart_port *port)
 {
 	struct uart_ip22zilog_port *up = (struct uart_ip22zilog_port *) port;
 	struct zilog_channel *channel = ZILOG_CHANNEL_FROM_PORT(port);
 	unsigned char new_reg;
-	unsigned long flags;
-
-	spin_lock_irqsave(&port->lock, flags);
 
 	new_reg = up->curregs[R15] | (DCDIE | SYNCIE | CTSIE);
 	if (new_reg != up->curregs[R15]) {
@@ -680,8 +670,6 @@
 		/* NOTE: Not subject to 'transmitter active' rule.  */ 
 		write_zsreg(channel, R15, up->curregs[R15]);
 	}
-
-	spin_unlock_irqrestore(&port->lock, flags);
 }
 
 /* The port lock is not held.  */
@@ -807,7 +795,7 @@
 	up->curregs[R4] |= X16CLK;
 	up->curregs[R12] = brg & 0xff;
 	up->curregs[R13] = (brg >> 8) & 0xff;
-	up->curregs[R14] = BRSRC | BRENAB;
+	up->curregs[R14] = BRENAB;
 
 	/* Character size, stop bits, and parity. */
 	up->curregs[3] &= ~RxN_MASK;
@@ -950,13 +938,6 @@
 static struct uart_ip22zilog_port *ip22zilog_irq_chain;
 static int zilog_irq = -1;
 
-static struct uart_driver ip22zilog_reg = {
-	.owner		=	THIS_MODULE,
-	.driver_name	=	"ttyS",
-	.devfs_name	=	"tty/",
-	.major		=	TTY_MAJOR,
-};
-
 static void * __init alloc_one_table(unsigned long size)
 {
 	void *ret;
@@ -990,7 +971,7 @@
 	}
 
 	/* Not probe-able, hard code it. */
-	base = (unsigned long) &sgioc->serport;
+	base = (unsigned long) &sgioc->uart;
 
 	zilog_irq = SGI_SERIAL_IRQ;
 	request_mem_region(base, 8, "IP22-Zilog");
@@ -1047,9 +1028,6 @@
 	int parity = 'n';
 	int flow = 'n';
 
-	if (!serial_console)
-		return;
-
 	if (options)
 		uart_parse_options(options, &baud, &parity, &bits, &flow);
 
@@ -1077,8 +1055,7 @@
 	unsigned long flags;
 	int baud, brg;
 
-	printk("Console: ttyS%d (IP22-Zilog)\n",
-	       (ip22zilog_reg.minor - 64) + con->index);
+	printk("Console: ttyS%d (IP22-Zilog)\n", con->index);
 
 	/* Get firmware console settings.  */
 	ip22serial_console_termios(con, options);
@@ -1112,6 +1089,8 @@
 	return 0;
 }
 
+static struct uart_driver ip22zilog_reg;
+
 static struct console ip22zilog_console = {
 	.name	=	"ttyS",
 	.write	=	ip22zilog_console_write,
@@ -1121,32 +1100,20 @@
 	.index	=	-1,
 	.data	=	&ip22zilog_reg,
 };
-#define IP22ZILOG_CONSOLE	(&ip22zilog_console)
-
-static int __init ip22zilog_console_init(void)
-{
-	int i;
-
-	if (con_is_present())
-		return 0;
-
-	for (i = 0; i < NUM_CHANNELS; i++) {
-		int this_minor = ip22zilog_reg.minor + i;
+#endif /* CONFIG_SERIAL_IP22_ZILOG_CONSOLE */
 
-		if ((this_minor - 64) == (serial_console - 1))
-			break;
-	}
-	if (i == NUM_CHANNELS)
-		return 0;
-
-	ip22zilog_console.index = i;
-	register_console(&ip22zilog_console);
-	return 0;
-}
-#else /* CONFIG_SERIAL_IP22_ZILOG_CONSOLE */
-#define IP22ZILOG_CONSOLE		(NULL)
-#define ip22zilog_console_init()	do { } while (0)
+static struct uart_driver ip22zilog_reg = {
+	.owner		= THIS_MODULE,
+	.driver_name	= "serial",
+	.devfs_name	= "tts/",
+	.dev_name	= "ttyS",
+	.major		= TTY_MAJOR,
+	.minor		= 64,
+	.nr		= NUM_CHANNELS,
+#ifdef CONFIG_SERIAL_IP22_ZILOG_CONSOLE
+	.cons		= &ip22zilog_console,
 #endif
+};
 
 static void __init ip22zilog_prepare(void)
 {
@@ -1160,17 +1127,24 @@
 	for (channel = 0; channel < NUM_CHANNELS; channel++)
 		spin_lock_init(&ip22zilog_port_table[channel].port.lock);
 
-	ip22zilog_irq_chain = up = &ip22zilog_port_table[0];
-	for (channel = 0; channel < NUM_CHANNELS - 1; channel++)
-		up[channel].next = &up[channel + 1];
+	ip22zilog_irq_chain = &ip22zilog_port_table[NUM_CHANNELS - 1];
+        up = &ip22zilog_port_table[0];
+	for (channel = NUM_CHANNELS - 1 ; channel > 0; channel--)
+		up[channel].next = &up[channel - 1];
 	up[channel].next = NULL;
 
 	for (chip = 0; chip < NUM_IP22ZILOG; chip++) {
 		if (!ip22zilog_chip_regs[chip]) {
 			ip22zilog_chip_regs[chip] = rp = get_zs(chip);
 
-			up[(chip * 2) + 0].port.membase = (char *) &rp->channelA;
-			up[(chip * 2) + 1].port.membase = (char *) &rp->channelB;
+			up[(chip * 2) + 0].port.membase = (char *) &rp->channelB;
+			up[(chip * 2) + 1].port.membase = (char *) &rp->channelA;
+
+			/* In theory mapbase is the physical address ...  */
+			up[(chip * 2) + 0].port.mapbase =
+				(unsigned long) ioremap((unsigned long) &rp->channelB, 8);
+			up[(chip * 2) + 1].port.mapbase =
+				(unsigned long) ioremap((unsigned long) &rp->channelA, 8);
 		}
 
 		/* Channel A */
@@ -1182,7 +1156,7 @@
 		up[(chip * 2) + 0].port.type = PORT_IP22ZILOG;
 		up[(chip * 2) + 0].port.flags = 0;
 		up[(chip * 2) + 0].port.line = (chip * 2) + 0;
-		up[(chip * 2) + 0].flags |= IP22ZILOG_FLAG_IS_CHANNEL_A;
+		up[(chip * 2) + 0].flags = 0;
 
 		/* Channel B */
 		up[(chip * 2) + 1].port.iotype = UPIO_MEM;
@@ -1191,9 +1165,9 @@
 		up[(chip * 2) + 1].port.fifosize = 1;
 		up[(chip * 2) + 1].port.ops = &ip22zilog_pops;
 		up[(chip * 2) + 1].port.type = PORT_IP22ZILOG;
-		up[(chip * 2) + 1].port.flags = 0;
+		up[(chip * 2) + 1].port.flags |= IP22ZILOG_FLAG_IS_CHANNEL_A;
 		up[(chip * 2) + 1].port.line = (chip * 2) + 1;
-		up[(chip * 2) + 1].flags |= 0;
+		up[(chip * 2) + 1].flags = 0;
 	}
 }
 
@@ -1228,8 +1202,10 @@
 		brg = BPS_TO_BRG(baud, ZS_CLOCK / ZS_CLOCK_DIVISOR);
 		up->curregs[R12] = (brg & 0xff);
 		up->curregs[R13] = (brg >> 8) & 0xff;
-		up->curregs[R14] = BRSRC | BRENAB;
+		up->curregs[R14] = BRENAB;
 		__load_zsregs(channel, up->curregs);
+	        /* set master interrupt enable */
+	        write_zsreg(channel, R9, up->curregs[R9]);
 
 		spin_unlock_irqrestore(&up->port.lock, flags);
 	}
@@ -1250,15 +1226,6 @@
 
 	ip22zilog_init_hw();
 
-	/* We can only init this once we have probed the Zilogs
-	 * in the system.
-	 */
-	ip22zilog_reg.nr = NUM_CHANNELS;
-	ip22zilog_reg.cons = IP22ZILOG_CONSOLE;
-
-	ip22zilog_reg.minor = ip22serial_current_minor;
-	ip22serial_current_minor += NUM_CHANNELS;
-
 	ret = uart_register_driver(&ip22zilog_reg);
 	if (ret == 0) {
 		int i;
@@ -1276,11 +1243,8 @@
 static int __init ip22zilog_init(void)
 {
 	/* IP22 Zilog setup is hard coded, no probing to do.  */
-
 	ip22zilog_alloc_tables();
-
 	ip22zilog_ports_init();
-	ip22zilog_console_init();
 
 	return 0;
 }
diff -Nru a/drivers/serial/mcfserial.c b/drivers/serial/mcfserial.c
--- a/drivers/serial/mcfserial.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/serial/mcfserial.c	2005-03-01 23:38:56 -08:00
@@ -58,11 +58,16 @@
  *	keep going.  Perhaps one day the cflag settings for the
  *	console can be used instead.
  */
-#if defined(CONFIG_ARNEWSH) || defined(CONFIG_MOTOROLA) || defined(CONFIG_senTec)
+#if defined(CONFIG_ARNEWSH) || defined(CONFIG_MOTOROLA) || defined(CONFIG_senTec) || defined(CONFIG_SNEHA)
 #define	CONSOLE_BAUD_RATE	19200
 #define	DEFAULT_CBAUD		B19200
 #endif
 
+#if defined(CONFIG_HW_FEITH)
+  #define	CONSOLE_BAUD_RATE	38400
+  #define	DEFAULT_CBAUD		B38400
+#endif
+
 #ifndef CONSOLE_BAUD_RATE
 #define	CONSOLE_BAUD_RATE	9600
 #define	DEFAULT_CBAUD		B9600
@@ -86,8 +91,8 @@
 #undef SERIAL_DEBUG_OPEN
 #undef SERIAL_DEBUG_FLOW
 
-#ifdef CONFIG_M5282
-#define	IRQBASE	77
+#if defined(CONFIG_M527x) || defined(CONFIG_M528x)
+#define	IRQBASE	(MCFINT_VECBASE+MCFINT_UART0)
 #else
 #define	IRQBASE	73
 #endif
@@ -337,20 +342,24 @@
 #endif
 
 		tty->flip.count++;
-		if (status & MCFUART_USR_RXERR)
+		if (status & MCFUART_USR_RXERR) {
 			uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETERR;
-		if (status & MCFUART_USR_RXBREAK) {
-			info->stats.rxbreak++;
-			*tty->flip.flag_buf_ptr++ = TTY_BREAK;
-		} else if (status & MCFUART_USR_RXPARITY) {
-			info->stats.rxparity++;
-			*tty->flip.flag_buf_ptr++ = TTY_PARITY;
-		} else if (status & MCFUART_USR_RXOVERRUN) {
-			info->stats.rxoverrun++;
-			*tty->flip.flag_buf_ptr++ = TTY_OVERRUN;
-		} else if (status & MCFUART_USR_RXFRAMING) {
-			info->stats.rxframing++;
-			*tty->flip.flag_buf_ptr++ = TTY_FRAME;
+			if (status & MCFUART_USR_RXBREAK) {
+				info->stats.rxbreak++;
+				*tty->flip.flag_buf_ptr++ = TTY_BREAK;
+			} else if (status & MCFUART_USR_RXPARITY) {
+				info->stats.rxparity++;
+				*tty->flip.flag_buf_ptr++ = TTY_PARITY;
+			} else if (status & MCFUART_USR_RXOVERRUN) {
+				info->stats.rxoverrun++;
+				*tty->flip.flag_buf_ptr++ = TTY_OVERRUN;
+			} else if (status & MCFUART_USR_RXFRAMING) {
+				info->stats.rxframing++;
+				*tty->flip.flag_buf_ptr++ = TTY_FRAME;
+			} else {
+				/* This should never happen... */
+				*tty->flip.flag_buf_ptr++ = 0;
+			}
 		} else {
 			*tty->flip.flag_buf_ptr++ = 0;
 		}
@@ -724,13 +733,25 @@
 	if (serial_paranoia_check(info, tty->name, "mcfrs_flush_chars"))
 		return;
 
+	uartp = (volatile unsigned char *) info->addr;
+
+	/*
+	 * re-enable receiver interrupt
+	 */
+	local_irq_save(flags);
+	if ((!(info->imr & MCFUART_UIR_RXREADY)) &&
+	    (info->flags & ASYNC_INITIALIZED) ) {
+		info->imr |= MCFUART_UIR_RXREADY;
+		uartp[MCFUART_UIMR] = info->imr;
+	}
+	local_irq_restore(flags);
+
 	if (info->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
 	    !info->xmit_buf)
 		return;
 
 	/* Enable transmitter */
 	local_irq_save(flags);
-	uartp = info->addr;
 	info->imr |= MCFUART_UIR_TXREADY;
 	uartp[MCFUART_UIMR] = info->imr;
 	local_irq_restore(flags);
@@ -984,7 +1005,7 @@
 
 	local_irq_save(flags);
 	uartp[MCFUART_UCR] = MCFUART_UCR_CMDBREAKSTART;
-	schedule_timeout(jiffies + duration);
+	schedule_timeout(duration);
 	uartp[MCFUART_UCR] = MCFUART_UCR_CMDBREAKSTOP;
 	local_irq_restore(flags);
 }
@@ -1506,7 +1527,7 @@
 	*portp = (*portp & ~0x000000ff) | 0x00000055;
 	portp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_PDCNT);
 	*portp = (*portp & ~0x000003fc) | 0x000002a8;
-#elif defined(CONFIG_M5282)
+#elif defined(CONFIG_M527x) || defined(CONFIG_M528x)
 	volatile unsigned char *icrp, *uartp;
 	volatile unsigned long *imrp;
 
@@ -1518,7 +1539,7 @@
 
 	imrp = (volatile unsigned long *) (MCF_MBAR + MCFICM_INTC0 +
 		MCFINTC_IMRL);
-	*imrp &= ~((1 << (info->irq - 64)) | 1);
+	*imrp &= ~((1 << (info->irq - MCFINT_VECBASE)) | 1);
 #else
 	volatile unsigned char	*icrp, *uartp;
 
diff -Nru a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c
--- a/drivers/serial/mpc52xx_uart.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/serial/mpc52xx_uart.c	2005-03-01 23:38:56 -08:00
@@ -640,7 +640,7 @@
 	
 	/* Basic port init. Needed since we use some uart_??? func before
 	 * real init for early access */
-	port->lock	= SPIN_LOCK_UNLOCKED;
+	spin_lock_init(&port->lock);
 	port->uartclk	= __res.bi_ipbfreq / 2; /* Look at CTLR doc */
 	port->ops	= &mpc52xx_uart_ops;
 	port->mapbase	= MPC52xx_PSCx(co->index);
@@ -724,7 +724,7 @@
 	port = &mpc52xx_uart_ports[idx];
 
 	/* Init the port structure */
-	port->lock	= SPIN_LOCK_UNLOCKED;
+	spin_lock_init(&port->lock);
 	port->mapbase	= ocp->def->paddr;
 	port->irq	= ocp->def->irq;
 	port->uartclk	= __res.bi_ipbfreq / 2; /* Look at CTLR doc */
diff -Nru a/drivers/serial/mpsc.c b/drivers/serial/mpsc.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/serial/mpsc.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,1832 @@
+/*
+ * drivers/serial/mpsc.c
+ *
+ * Generic driver for the MPSC (UART mode) on Marvell parts (e.g., GT64240,
+ * GT64260, MV64340, MV64360, GT96100, ... ).
+ *
+ * Author: Mark A. Greer <mgreer@mvista.com>
+ *
+ * Based on an old MPSC driver that was in the linuxppc tree.  It appears to
+ * have been created by Chris Zankel (formerly of MontaVista) but there
+ * is no proper Copyright so I'm not sure.  Apparently, parts were also
+ * taken from PPCBoot (now U-Boot).  Also based on drivers/serial/8250.c
+ * by Russell King.
+ *
+ * 2004 (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.
+ */
+/*
+ * The MPSC interface is much like a typical network controller's interface.
+ * That is, you set up separate rings of descriptors for transmitting and
+ * receiving data.  There is also a pool of buffers with (one buffer per
+ * descriptor) that incoming data are dma'd into or outgoing data are dma'd
+ * out of.
+ *
+ * The MPSC requires two other controllers to be able to work.  The Baud Rate
+ * Generator (BRG) provides a clock at programmable frequencies which determines
+ * the baud rate.  The Serial DMA Controller (SDMA) takes incoming data from the
+ * MPSC and DMA's it into memory or DMA's outgoing data and passes it to the
+ * MPSC.  It is actually the SDMA interrupt that the driver uses to keep the
+ * transmit and receive "engines" going (i.e., indicate data has been
+ * transmitted or received).
+ *
+ * NOTES:
+ *
+ * 1) Some chips have an erratum where several regs cannot be
+ * read.  To work around that, we keep a local copy of those regs in
+ * 'mpsc_port_info'.
+ *
+ * 2) Some chips have an erratum where the ctlr will hang when the SDMA ctlr
+ * accesses system mem with coherency enabled.  For that reason, the driver
+ * assumes that coherency for that ctlr has been disabled.  This means
+ * that when in a cache coherent system, the driver has to manually manage
+ * the data cache on the areas that it touches because the dma_* macro are
+ * basically no-ops.
+ *
+ * 3) There is an erratum (on PPC) where you can't use the instruction to do
+ * a DMA_TO_DEVICE/cache clean so DMA_BIDIRECTIONAL/flushes are used in places
+ * where a DMA_TO_DEVICE/clean would have [otherwise] sufficed.
+ *
+ * 4) AFAICT, hardware flow control isn't supported by the controller --MAG.
+ */
+
+#include "mpsc.h"
+
+/*
+ * Define how this driver is known to the outside (we've been assigned a
+ * range on the "Low-density serial ports" major).
+ */
+#define MPSC_MAJOR		204
+#define MPSC_MINOR_START	44
+#define	MPSC_DRIVER_NAME	"MPSC"
+#define	MPSC_DEVFS_NAME		"ttymm/"
+#define	MPSC_DEV_NAME		"ttyMM"
+#define	MPSC_VERSION		"1.00"
+
+static struct mpsc_port_info mpsc_ports[MPSC_NUM_CTLRS];
+static struct mpsc_shared_regs mpsc_shared_regs;
+
+/*
+ ******************************************************************************
+ *
+ * Baud Rate Generator Routines (BRG)
+ *
+ ******************************************************************************
+ */
+static void
+mpsc_brg_init(struct mpsc_port_info *pi, u32 clk_src)
+{
+	u32	v;
+
+	v = (pi->mirror_regs) ? pi->BRG_BCR_m : readl(pi->brg_base + BRG_BCR);
+	v = (v & ~(0xf << 18)) | ((clk_src & 0xf) << 18);
+
+	if (pi->brg_can_tune)
+		v &= ~(1 << 25);
+
+	if (pi->mirror_regs)
+		pi->BRG_BCR_m = v;
+	writel(v, pi->brg_base + BRG_BCR);
+
+	writel(readl(pi->brg_base + BRG_BTR) & 0xffff0000,
+		pi->brg_base + BRG_BTR);
+	return;
+}
+
+static void
+mpsc_brg_enable(struct mpsc_port_info *pi)
+{
+	u32	v;
+
+	v = (pi->mirror_regs) ? pi->BRG_BCR_m : readl(pi->brg_base + BRG_BCR);
+	v |= (1 << 16);
+
+	if (pi->mirror_regs)
+		pi->BRG_BCR_m = v;
+	writel(v, pi->brg_base + BRG_BCR);
+	return;
+}
+
+static void
+mpsc_brg_disable(struct mpsc_port_info *pi)
+{
+	u32	v;
+
+	v = (pi->mirror_regs) ? pi->BRG_BCR_m : readl(pi->brg_base + BRG_BCR);
+	v &= ~(1 << 16);
+
+	if (pi->mirror_regs)
+		pi->BRG_BCR_m = v;
+	writel(v, pi->brg_base + BRG_BCR);
+	return;
+}
+
+static inline void
+mpsc_set_baudrate(struct mpsc_port_info *pi, u32 baud)
+{
+	/*
+	 * To set the baud, we adjust the CDV field in the BRG_BCR reg.
+	 * From manual: Baud = clk / ((CDV+1)*2) ==> CDV = (clk / (baud*2)) - 1.
+	 * However, the input clock is divided by 16 in the MPSC b/c of how
+	 * 'MPSC_MMCRH' was set up so we have to divide the 'clk' used in our
+	 * calculation by 16 to account for that.  So the real calculation
+	 * that accounts for the way the mpsc is set up is:
+	 * CDV = (clk / (baud*2*16)) - 1 ==> CDV = (clk / (baud << 5)) - 1.
+	 */
+	u32	cdv = (pi->port.uartclk / (baud << 5)) - 1;
+	u32	v;
+
+	mpsc_brg_disable(pi);
+	v = (pi->mirror_regs) ? pi->BRG_BCR_m : readl(pi->brg_base + BRG_BCR);
+	v = (v & 0xffff0000) | (cdv & 0xffff);
+
+	if (pi->mirror_regs)
+		pi->BRG_BCR_m = v;
+	writel(v, pi->brg_base + BRG_BCR);
+	mpsc_brg_enable(pi);
+
+	return;
+}
+
+/*
+ ******************************************************************************
+ *
+ * Serial DMA Routines (SDMA)
+ *
+ ******************************************************************************
+ */
+
+static void
+mpsc_sdma_burstsize(struct mpsc_port_info *pi, u32 burst_size)
+{
+	u32	v;
+
+	pr_debug("mpsc_sdma_burstsize[%d]: burst_size: %d\n",
+	    pi->port.line, burst_size);
+
+	burst_size >>= 3; /* Divide by 8 b/c reg values are 8-byte chunks */
+
+	if (burst_size < 2)
+		v = 0x0;	/* 1 64-bit word */
+	else if (burst_size < 4)
+		v = 0x1;	/* 2 64-bit words */
+	else if (burst_size < 8)
+		v = 0x2;	/* 4 64-bit words */
+	else
+		v = 0x3;	/* 8 64-bit words */
+
+	writel((readl(pi->sdma_base + SDMA_SDC) & (0x3 << 12)) | (v << 12),
+		pi->sdma_base + SDMA_SDC);
+	return;
+}
+
+static void
+mpsc_sdma_init(struct mpsc_port_info *pi, u32 burst_size)
+{
+	pr_debug("mpsc_sdma_init[%d]: burst_size: %d\n", pi->port.line,
+		burst_size);
+
+	writel((readl(pi->sdma_base + SDMA_SDC) & 0x3ff) | 0x03f,
+		pi->sdma_base + SDMA_SDC);
+	mpsc_sdma_burstsize(pi, burst_size);
+	return;
+}
+
+static inline u32
+mpsc_sdma_intr_mask(struct mpsc_port_info *pi, u32 mask)
+{
+	u32	old, v;
+
+	pr_debug("mpsc_sdma_intr_mask[%d]: mask: 0x%x\n", pi->port.line, mask);
+
+	old = v = (pi->mirror_regs) ? pi->shared_regs->SDMA_INTR_MASK_m :
+		readl(pi->shared_regs->sdma_intr_base + SDMA_INTR_MASK);
+
+	mask &= 0xf;
+	if (pi->port.line)
+		mask <<= 8;
+	v &= ~mask;
+
+	if (pi->mirror_regs)
+		pi->shared_regs->SDMA_INTR_MASK_m = v;
+	writel(v, pi->shared_regs->sdma_intr_base + SDMA_INTR_MASK);
+
+	if (pi->port.line)
+		old >>= 8;
+	return old & 0xf;
+}
+
+static inline void
+mpsc_sdma_intr_unmask(struct mpsc_port_info *pi, u32 mask)
+{
+	u32	v;
+
+	pr_debug("mpsc_sdma_intr_unmask[%d]: mask: 0x%x\n", pi->port.line,mask);
+
+	v = (pi->mirror_regs) ? pi->shared_regs->SDMA_INTR_MASK_m :
+		readl(pi->shared_regs->sdma_intr_base + SDMA_INTR_MASK);
+
+	mask &= 0xf;
+	if (pi->port.line)
+		mask <<= 8;
+	v |= mask;
+
+	if (pi->mirror_regs)
+		pi->shared_regs->SDMA_INTR_MASK_m = v;
+	writel(v, pi->shared_regs->sdma_intr_base + SDMA_INTR_MASK);
+	return;
+}
+
+static inline void
+mpsc_sdma_intr_ack(struct mpsc_port_info *pi)
+{
+	pr_debug("mpsc_sdma_intr_ack[%d]: Acknowledging IRQ\n", pi->port.line);
+
+	if (pi->mirror_regs)
+		pi->shared_regs->SDMA_INTR_CAUSE_m = 0;
+	writel(0, pi->shared_regs->sdma_intr_base + SDMA_INTR_CAUSE);
+	return;
+}
+
+static inline void
+mpsc_sdma_set_rx_ring(struct mpsc_port_info *pi, struct mpsc_rx_desc *rxre_p)
+{
+	pr_debug("mpsc_sdma_set_rx_ring[%d]: rxre_p: 0x%x\n",
+		pi->port.line, (u32) rxre_p);
+
+	writel((u32)rxre_p, pi->sdma_base + SDMA_SCRDP);
+	return;
+}
+
+static inline void
+mpsc_sdma_set_tx_ring(struct mpsc_port_info *pi, struct mpsc_tx_desc *txre_p)
+{
+	writel((u32)txre_p, pi->sdma_base + SDMA_SFTDP);
+	writel((u32)txre_p, pi->sdma_base + SDMA_SCTDP);
+	return;
+}
+
+static inline void
+mpsc_sdma_cmd(struct mpsc_port_info *pi, u32 val)
+{
+	u32	v;
+
+	v = readl(pi->sdma_base + SDMA_SDCM);
+	if (val)
+		v |= val;
+	else
+		v = 0;
+	wmb();
+	writel(v, pi->sdma_base + SDMA_SDCM);
+	wmb();
+	return;
+}
+
+static inline uint
+mpsc_sdma_tx_active(struct mpsc_port_info *pi)
+{
+	return readl(pi->sdma_base + SDMA_SDCM) & SDMA_SDCM_TXD;
+}
+
+static inline void
+mpsc_sdma_start_tx(struct mpsc_port_info *pi)
+{
+	struct mpsc_tx_desc *txre, *txre_p;
+
+	/* If tx isn't running & there's a desc ready to go, start it */
+	if (!mpsc_sdma_tx_active(pi)) {
+		txre = (struct mpsc_tx_desc *)(pi->txr +
+			(pi->txr_tail * MPSC_TXRE_SIZE));
+		dma_cache_sync((void *) txre, MPSC_TXRE_SIZE, DMA_FROM_DEVICE);
+#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
+		if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
+			invalidate_dcache_range((ulong)txre,
+				(ulong)txre + MPSC_TXRE_SIZE);
+#endif
+
+		if (be32_to_cpu(txre->cmdstat) & SDMA_DESC_CMDSTAT_O) {
+			txre_p = (struct mpsc_tx_desc *)(pi->txr_p +
+							 (pi->txr_tail *
+							  MPSC_TXRE_SIZE));
+
+			mpsc_sdma_set_tx_ring(pi, txre_p);
+			mpsc_sdma_cmd(pi, SDMA_SDCM_STD | SDMA_SDCM_TXD);
+		}
+	}
+
+	return;
+}
+
+static inline void
+mpsc_sdma_stop(struct mpsc_port_info *pi)
+{
+	pr_debug("mpsc_sdma_stop[%d]: Stopping SDMA\n", pi->port.line);
+
+	/* Abort any SDMA transfers */
+	mpsc_sdma_cmd(pi, 0);
+	mpsc_sdma_cmd(pi, SDMA_SDCM_AR | SDMA_SDCM_AT);
+
+	/* Clear the SDMA current and first TX and RX pointers */
+	mpsc_sdma_set_tx_ring(pi, 0);
+	mpsc_sdma_set_rx_ring(pi, 0);
+
+	/* Disable interrupts */
+	mpsc_sdma_intr_mask(pi, 0xf);
+	mpsc_sdma_intr_ack(pi);
+
+	return;
+}
+
+/*
+ ******************************************************************************
+ *
+ * Multi-Protocol Serial Controller Routines (MPSC)
+ *
+ ******************************************************************************
+ */
+
+static void
+mpsc_hw_init(struct mpsc_port_info *pi)
+{
+	u32	v;
+
+	pr_debug("mpsc_hw_init[%d]: Initializing hardware\n", pi->port.line);
+
+	/* Set up clock routing */
+	if (pi->mirror_regs) {
+		v = pi->shared_regs->MPSC_MRR_m;
+		v &= ~0x1c7;
+		pi->shared_regs->MPSC_MRR_m = v;
+		writel(v, pi->shared_regs->mpsc_routing_base + MPSC_MRR);
+
+		v = pi->shared_regs->MPSC_RCRR_m;
+		v = (v & ~0xf0f) | 0x100;
+		pi->shared_regs->MPSC_RCRR_m = v;
+		writel(v, pi->shared_regs->mpsc_routing_base + MPSC_RCRR);
+
+		v = pi->shared_regs->MPSC_TCRR_m;
+		v = (v & ~0xf0f) | 0x100;
+		pi->shared_regs->MPSC_TCRR_m = v;
+		writel(v, pi->shared_regs->mpsc_routing_base + MPSC_TCRR);
+	}
+	else {
+		v = readl(pi->shared_regs->mpsc_routing_base + MPSC_MRR);
+		v &= ~0x1c7;
+		writel(v, pi->shared_regs->mpsc_routing_base + MPSC_MRR);
+
+		v = readl(pi->shared_regs->mpsc_routing_base + MPSC_RCRR);
+		v = (v & ~0xf0f) | 0x100;
+		writel(v, pi->shared_regs->mpsc_routing_base + MPSC_RCRR);
+
+		v = readl(pi->shared_regs->mpsc_routing_base + MPSC_TCRR);
+		v = (v & ~0xf0f) | 0x100;
+		writel(v, pi->shared_regs->mpsc_routing_base + MPSC_TCRR);
+	}
+
+	/* Put MPSC in UART mode & enabel Tx/Rx egines */
+	writel(0x000004c4, pi->mpsc_base + MPSC_MMCRL);
+
+	/* No preamble, 16x divider, low-latency,  */
+	writel(0x04400400, pi->mpsc_base + MPSC_MMCRH);
+
+	if (pi->mirror_regs) {
+		pi->MPSC_CHR_1_m = 0;
+		pi->MPSC_CHR_2_m = 0;
+	}
+	writel(0, pi->mpsc_base + MPSC_CHR_1);
+	writel(0, pi->mpsc_base + MPSC_CHR_2);
+	writel(pi->mpsc_max_idle, pi->mpsc_base + MPSC_CHR_3);
+	writel(0, pi->mpsc_base + MPSC_CHR_4);
+	writel(0, pi->mpsc_base + MPSC_CHR_5);
+	writel(0, pi->mpsc_base + MPSC_CHR_6);
+	writel(0, pi->mpsc_base + MPSC_CHR_7);
+	writel(0, pi->mpsc_base + MPSC_CHR_8);
+	writel(0, pi->mpsc_base + MPSC_CHR_9);
+	writel(0, pi->mpsc_base + MPSC_CHR_10);
+
+	return;
+}
+
+static inline void
+mpsc_enter_hunt(struct mpsc_port_info *pi)
+{
+	pr_debug("mpsc_enter_hunt[%d]: Hunting...\n", pi->port.line);
+
+	if (pi->mirror_regs) {
+		writel(pi->MPSC_CHR_2_m | MPSC_CHR_2_EH,
+			pi->mpsc_base + MPSC_CHR_2);
+		/* Erratum prevents reading CHR_2 so just delay for a while */
+		udelay(100);
+	}
+	else {
+		writel(readl(pi->mpsc_base + MPSC_CHR_2) | MPSC_CHR_2_EH,
+			pi->mpsc_base + MPSC_CHR_2);
+
+		while (readl(pi->mpsc_base + MPSC_CHR_2) & MPSC_CHR_2_EH)
+			udelay(10);
+	}
+
+	return;
+}
+
+static inline void
+mpsc_freeze(struct mpsc_port_info *pi)
+{
+	u32	v;
+
+	pr_debug("mpsc_freeze[%d]: Freezing\n", pi->port.line);
+
+	v = (pi->mirror_regs) ? pi->MPSC_MPCR_m :
+		readl(pi->mpsc_base + MPSC_MPCR);
+	v |= MPSC_MPCR_FRZ;
+
+	if (pi->mirror_regs)
+		pi->MPSC_MPCR_m = v;
+	writel(v, pi->mpsc_base + MPSC_MPCR);
+	return;
+}
+
+static inline void
+mpsc_unfreeze(struct mpsc_port_info *pi)
+{
+	u32	v;
+
+	v = (pi->mirror_regs) ? pi->MPSC_MPCR_m :
+		readl(pi->mpsc_base + MPSC_MPCR);
+	v &= ~MPSC_MPCR_FRZ;
+
+	if (pi->mirror_regs)
+		pi->MPSC_MPCR_m = v;
+	writel(v, pi->mpsc_base + MPSC_MPCR);
+
+	pr_debug("mpsc_unfreeze[%d]: Unfrozen\n", pi->port.line);
+	return;
+}
+
+static inline void
+mpsc_set_char_length(struct mpsc_port_info *pi, u32 len)
+{
+	u32	v;
+
+	pr_debug("mpsc_set_char_length[%d]: char len: %d\n", pi->port.line,len);
+
+	v = (pi->mirror_regs) ? pi->MPSC_MPCR_m :
+		readl(pi->mpsc_base + MPSC_MPCR);
+	v = (v & ~(0x3 << 12)) | ((len & 0x3) << 12);
+
+	if (pi->mirror_regs)
+		pi->MPSC_MPCR_m = v;
+	writel(v, pi->mpsc_base + MPSC_MPCR);
+	return;
+}
+
+static inline void
+mpsc_set_stop_bit_length(struct mpsc_port_info *pi, u32 len)
+{
+	u32	v;
+
+	pr_debug("mpsc_set_stop_bit_length[%d]: stop bits: %d\n",
+		pi->port.line, len);
+
+	v = (pi->mirror_regs) ? pi->MPSC_MPCR_m :
+		readl(pi->mpsc_base + MPSC_MPCR);
+
+	v = (v & ~(1 << 14)) | ((len & 0x1) << 14);
+
+	if (pi->mirror_regs)
+		pi->MPSC_MPCR_m = v;
+	writel(v, pi->mpsc_base + MPSC_MPCR);
+	return;
+}
+
+static inline void
+mpsc_set_parity(struct mpsc_port_info *pi, u32 p)
+{
+	u32	v;
+
+	pr_debug("mpsc_set_parity[%d]: parity bits: 0x%x\n", pi->port.line, p);
+
+	v = (pi->mirror_regs) ? pi->MPSC_CHR_2_m :
+		readl(pi->mpsc_base + MPSC_CHR_2);
+
+	p &= 0x3;
+	v = (v & ~0xc000c) | (p << 18) | (p << 2);
+
+	if (pi->mirror_regs)
+		pi->MPSC_CHR_2_m = v;
+	writel(v, pi->mpsc_base + MPSC_CHR_2);
+	return;
+}
+
+/*
+ ******************************************************************************
+ *
+ * Driver Init Routines
+ *
+ ******************************************************************************
+ */
+
+static void
+mpsc_init_hw(struct mpsc_port_info *pi)
+{
+	pr_debug("mpsc_init_hw[%d]: Initializing\n", pi->port.line);
+
+	mpsc_brg_init(pi, pi->brg_clk_src);
+	mpsc_brg_enable(pi);
+	mpsc_sdma_init(pi, dma_get_cache_alignment());	/* burst a cacheline */
+	mpsc_sdma_stop(pi);
+	mpsc_hw_init(pi);
+
+	return;
+}
+
+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);
+
+	if (!pi->dma_region) {
+		if (!dma_supported(pi->port.dev, 0xffffffff)) {
+			printk(KERN_ERR "MPSC: Inadequate DMA support\n");
+			rc = -ENXIO;
+		}
+		else if ((pi->dma_region = dma_alloc_noncoherent(pi->port.dev,
+			MPSC_DMA_ALLOC_SIZE, &pi->dma_region_p, GFP_KERNEL))
+			== NULL) {
+
+			printk(KERN_ERR "MPSC: Can't alloc Desc region\n");
+			rc = -ENOMEM;
+		}
+	}
+
+	return rc;
+}
+
+static void
+mpsc_free_ring_mem(struct mpsc_port_info *pi)
+{
+	pr_debug("mpsc_free_ring_mem[%d]: Freeing ring mem\n", pi->port.line);
+
+	if (pi->dma_region) {
+		dma_free_noncoherent(pi->port.dev, MPSC_DMA_ALLOC_SIZE,
+			  pi->dma_region, pi->dma_region_p);
+		pi->dma_region = NULL;
+		pi->dma_region_p = (dma_addr_t) NULL;
+	}
+
+	return;
+}
+
+static void
+mpsc_init_rings(struct mpsc_port_info *pi)
+{
+	struct mpsc_rx_desc *rxre;
+	struct mpsc_tx_desc *txre;
+	dma_addr_t dp, dp_p;
+	u8 *bp, *bp_p;
+	int i;
+
+	pr_debug("mpsc_init_rings[%d]: Initializing rings\n", pi->port.line);
+
+	BUG_ON(pi->dma_region == NULL);
+
+	memset(pi->dma_region, 0, MPSC_DMA_ALLOC_SIZE);
+
+	/*
+	 * Descriptors & buffers are multiples of cacheline size and must be
+	 * cacheline aligned.
+	 */
+	dp = ALIGN((u32) pi->dma_region, dma_get_cache_alignment());
+	dp_p = ALIGN((u32) pi->dma_region_p, dma_get_cache_alignment());
+
+	/*
+	 * Partition dma region into rx ring descriptor, rx buffers,
+	 * tx ring descriptors, and tx buffers.
+	 */
+	pi->rxr = dp;
+	pi->rxr_p = dp_p;
+	dp += MPSC_RXR_SIZE;
+	dp_p += MPSC_RXR_SIZE;
+
+	pi->rxb = (u8 *) dp;
+	pi->rxb_p = (u8 *) dp_p;
+	dp += MPSC_RXB_SIZE;
+	dp_p += MPSC_RXB_SIZE;
+
+	pi->rxr_posn = 0;
+
+	pi->txr = dp;
+	pi->txr_p = dp_p;
+	dp += MPSC_TXR_SIZE;
+	dp_p += MPSC_TXR_SIZE;
+
+	pi->txb = (u8 *) dp;
+	pi->txb_p = (u8 *) dp_p;
+
+	pi->txr_head = 0;
+	pi->txr_tail = 0;
+
+	/* Init rx ring descriptors */
+	dp = pi->rxr;
+	dp_p = pi->rxr_p;
+	bp = pi->rxb;
+	bp_p = pi->rxb_p;
+
+	for (i = 0; i < MPSC_RXR_ENTRIES; i++) {
+		rxre = (struct mpsc_rx_desc *)dp;
+
+		rxre->bufsize = cpu_to_be16(MPSC_RXBE_SIZE);
+		rxre->bytecnt = cpu_to_be16(0);
+		rxre->cmdstat = cpu_to_be32(SDMA_DESC_CMDSTAT_O |
+					    SDMA_DESC_CMDSTAT_EI |
+					    SDMA_DESC_CMDSTAT_F |
+					    SDMA_DESC_CMDSTAT_L);
+		rxre->link = cpu_to_be32(dp_p + MPSC_RXRE_SIZE);
+		rxre->buf_ptr = cpu_to_be32(bp_p);
+
+		dp += MPSC_RXRE_SIZE;
+		dp_p += MPSC_RXRE_SIZE;
+		bp += MPSC_RXBE_SIZE;
+		bp_p += MPSC_RXBE_SIZE;
+	}
+	rxre->link = cpu_to_be32(pi->rxr_p);	/* Wrap last back to first */
+
+	/* Init tx ring descriptors */
+	dp = pi->txr;
+	dp_p = pi->txr_p;
+	bp = pi->txb;
+	bp_p = pi->txb_p;
+
+	for (i = 0; i < MPSC_TXR_ENTRIES; i++) {
+		txre = (struct mpsc_tx_desc *)dp;
+
+		txre->link = cpu_to_be32(dp_p + MPSC_TXRE_SIZE);
+		txre->buf_ptr = cpu_to_be32(bp_p);
+
+		dp += MPSC_TXRE_SIZE;
+		dp_p += MPSC_TXRE_SIZE;
+		bp += MPSC_TXBE_SIZE;
+		bp_p += MPSC_TXBE_SIZE;
+	}
+	txre->link = cpu_to_be32(pi->txr_p);	/* Wrap last back to first */
+
+	dma_cache_sync((void *) pi->dma_region, MPSC_DMA_ALLOC_SIZE,
+		DMA_BIDIRECTIONAL);
+#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
+		if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
+			flush_dcache_range((ulong)pi->dma_region,
+				(ulong)pi->dma_region + MPSC_DMA_ALLOC_SIZE);
+#endif
+
+	return;
+}
+
+static void
+mpsc_uninit_rings(struct mpsc_port_info *pi)
+{
+	pr_debug("mpsc_uninit_rings[%d]: Uninitializing rings\n",pi->port.line);
+
+	BUG_ON(pi->dma_region == NULL);
+
+	pi->rxr = 0;
+	pi->rxr_p = 0;
+	pi->rxb = NULL;
+	pi->rxb_p = NULL;
+	pi->rxr_posn = 0;
+
+	pi->txr = 0;
+	pi->txr_p = 0;
+	pi->txb = NULL;
+	pi->txb_p = NULL;
+	pi->txr_head = 0;
+	pi->txr_tail = 0;
+
+	return;
+}
+
+static int
+mpsc_make_ready(struct mpsc_port_info *pi)
+{
+	int rc;
+
+	pr_debug("mpsc_make_ready[%d]: Making cltr ready\n", pi->port.line);
+
+	if (!pi->ready) {
+		mpsc_init_hw(pi);
+		if ((rc = mpsc_alloc_ring_mem(pi)))
+			return rc;
+		mpsc_init_rings(pi);
+		pi->ready = 1;
+	}
+
+	return 0;
+}
+
+/*
+ ******************************************************************************
+ *
+ * Interrupt Handling Routines
+ *
+ ******************************************************************************
+ */
+
+static inline int
+mpsc_rx_intr(struct mpsc_port_info *pi, struct pt_regs *regs)
+{
+	struct mpsc_rx_desc *rxre;
+	struct tty_struct *tty = pi->port.info->tty;
+	u32	cmdstat, bytes_in, i;
+	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);
+
+	rxre = (struct mpsc_rx_desc *)(pi->rxr + (pi->rxr_posn*MPSC_RXRE_SIZE));
+
+	dma_cache_sync((void *)rxre, MPSC_RXRE_SIZE, DMA_FROM_DEVICE);
+#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
+	if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
+		invalidate_dcache_range((ulong)rxre,
+			(ulong)rxre + MPSC_RXRE_SIZE);
+#endif
+
+	/*
+	 * Loop through Rx descriptors handling ones that have been completed.
+	 */
+	while (!((cmdstat = be32_to_cpu(rxre->cmdstat)) & SDMA_DESC_CMDSTAT_O)){
+		bytes_in = be16_to_cpu(rxre->bytecnt);
+
+		/* Following use of tty struct directly is deprecated */
+		if (unlikely((tty->flip.count + bytes_in) >= TTY_FLIPBUF_SIZE)){
+			if (tty->low_latency)
+				tty_flip_buffer_push(tty);
+			/*
+			 * If this failed then we will throw awa the bytes
+			 * but mst do so to clear interrupts.
+			 */
+		}
+
+		bp = pi->rxb + (pi->rxr_posn * MPSC_RXBE_SIZE);
+		dma_cache_sync((void *) bp, MPSC_RXBE_SIZE, DMA_FROM_DEVICE);
+#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
+		if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
+			invalidate_dcache_range((ulong)bp,
+				(ulong)bp + MPSC_RXBE_SIZE);
+#endif
+
+		/*
+		 * Other than for parity error, the manual provides little
+		 * info on what data will be in a frame flagged by any of
+		 * these errors.  For parity error, it is the last byte in
+		 * the buffer that had the error.  As for the rest, I guess
+		 * we'll assume there is no data in the buffer.
+		 * If there is...it gets lost.
+		 */
+		if (unlikely(cmdstat & (SDMA_DESC_CMDSTAT_BR |
+			SDMA_DESC_CMDSTAT_FR | SDMA_DESC_CMDSTAT_OR))) {
+
+			pi->port.icount.rx++;
+
+			if (cmdstat & SDMA_DESC_CMDSTAT_BR) {	/* Break */
+				pi->port.icount.brk++;
+
+				if (uart_handle_break(&pi->port))
+					goto next_frame;
+			}
+			else if (cmdstat & SDMA_DESC_CMDSTAT_FR)/* Framing */
+				pi->port.icount.frame++;
+			else if (cmdstat & SDMA_DESC_CMDSTAT_OR) /* Overrun */
+				pi->port.icount.overrun++;
+
+			cmdstat &= pi->port.read_status_mask;
+
+			if (cmdstat & SDMA_DESC_CMDSTAT_BR)
+				flag = TTY_BREAK;
+			else if (cmdstat & SDMA_DESC_CMDSTAT_FR)
+				flag = TTY_FRAME;
+			else if (cmdstat & SDMA_DESC_CMDSTAT_OR)
+				flag = TTY_OVERRUN;
+			else if (cmdstat & SDMA_DESC_CMDSTAT_PE)
+				flag = TTY_PARITY;
+		}
+
+		if (uart_handle_sysrq_char(&pi->port, *bp, regs)) {
+			bp++;
+			bytes_in--;
+			goto next_frame;
+		}
+
+		if ((unlikely(cmdstat & (SDMA_DESC_CMDSTAT_BR |
+			SDMA_DESC_CMDSTAT_FR | SDMA_DESC_CMDSTAT_OR))) &&
+			!(cmdstat & pi->port.ignore_status_mask))
+
+			tty_insert_flip_char(tty, *bp, flag);
+		else {
+			for (i=0; i<bytes_in; i++)
+				tty_insert_flip_char(tty, *bp++, TTY_NORMAL);
+
+			pi->port.icount.rx += bytes_in;
+		}
+
+next_frame:
+		rxre->bytecnt = cpu_to_be16(0);
+		wmb();
+		rxre->cmdstat = cpu_to_be32(SDMA_DESC_CMDSTAT_O |
+					    SDMA_DESC_CMDSTAT_EI |
+					    SDMA_DESC_CMDSTAT_F |
+					    SDMA_DESC_CMDSTAT_L);
+		wmb();
+		dma_cache_sync((void *)rxre, MPSC_RXRE_SIZE, DMA_BIDIRECTIONAL);
+#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
+		if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
+			flush_dcache_range((ulong)rxre,
+				(ulong)rxre + MPSC_RXRE_SIZE);
+#endif
+
+		/* Advance to next descriptor */
+		pi->rxr_posn = (pi->rxr_posn + 1) & (MPSC_RXR_ENTRIES - 1);
+		rxre = (struct mpsc_rx_desc *)(pi->rxr +
+			(pi->rxr_posn * MPSC_RXRE_SIZE));
+		dma_cache_sync((void *)rxre, MPSC_RXRE_SIZE, DMA_FROM_DEVICE);
+#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
+		if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
+			invalidate_dcache_range((ulong)rxre,
+				(ulong)rxre + MPSC_RXRE_SIZE);
+#endif
+
+		rc = 1;
+	}
+
+	/* Restart rx engine, if its stopped */
+	if ((readl(pi->sdma_base + SDMA_SDCM) & SDMA_SDCM_ERD) == 0)
+		mpsc_start_rx(pi);
+
+	tty_flip_buffer_push(tty);
+	return rc;
+}
+
+static inline void
+mpsc_setup_tx_desc(struct mpsc_port_info *pi, u32 count, u32 intr)
+{
+	struct mpsc_tx_desc *txre;
+
+	txre = (struct mpsc_tx_desc *)(pi->txr +
+		(pi->txr_head * MPSC_TXRE_SIZE));
+
+	txre->bytecnt = cpu_to_be16(count);
+	txre->shadow = txre->bytecnt;
+	wmb();			/* ensure cmdstat is last field updated */
+	txre->cmdstat = cpu_to_be32(SDMA_DESC_CMDSTAT_O | SDMA_DESC_CMDSTAT_F |
+				    SDMA_DESC_CMDSTAT_L | ((intr) ?
+							   SDMA_DESC_CMDSTAT_EI
+							   : 0));
+	wmb();
+	dma_cache_sync((void *) txre, MPSC_TXRE_SIZE, DMA_BIDIRECTIONAL);
+#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
+	if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
+		flush_dcache_range((ulong)txre,
+			(ulong)txre + MPSC_TXRE_SIZE);
+#endif
+
+	return;
+}
+
+static inline void
+mpsc_copy_tx_data(struct mpsc_port_info *pi)
+{
+	struct circ_buf *xmit = &pi->port.info->xmit;
+	u8 *bp;
+	u32 i;
+
+	/* Make sure the desc ring isn't full */
+	while (CIRC_CNT(pi->txr_head, pi->txr_tail, MPSC_TXR_ENTRIES) <
+	       (MPSC_TXR_ENTRIES - 1)) {
+		if (pi->port.x_char) {
+			/*
+			 * Ideally, we should use the TCS field in
+			 * CHR_1 to put the x_char out immediately but
+			 * errata prevents us from being able to read
+			 * CHR_2 to know that its safe to write to
+			 * CHR_1.  Instead, just put it in-band with
+			 * all the other Tx data.
+			 */
+			bp = pi->txb + (pi->txr_head * MPSC_TXBE_SIZE);
+			*bp = pi->port.x_char;
+			pi->port.x_char = 0;
+			i = 1;
+		}
+		else if (!uart_circ_empty(xmit) && !uart_tx_stopped(&pi->port)){
+			i = min((u32) MPSC_TXBE_SIZE,
+				(u32) uart_circ_chars_pending(xmit));
+			i = min(i, (u32) CIRC_CNT_TO_END(xmit->head, xmit->tail,
+				UART_XMIT_SIZE));
+			bp = pi->txb + (pi->txr_head * MPSC_TXBE_SIZE);
+			memcpy(bp, &xmit->buf[xmit->tail], i);
+			xmit->tail = (xmit->tail + i) & (UART_XMIT_SIZE - 1);
+
+			if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+				uart_write_wakeup(&pi->port);
+		}
+		else /* All tx data copied into ring bufs */
+			return;
+
+		dma_cache_sync((void *) bp, MPSC_TXBE_SIZE, DMA_BIDIRECTIONAL);
+#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
+		if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
+			flush_dcache_range((ulong)bp,
+				(ulong)bp + MPSC_TXBE_SIZE);
+#endif
+		mpsc_setup_tx_desc(pi, i, 1);
+
+		/* Advance to next descriptor */
+		pi->txr_head = (pi->txr_head + 1) & (MPSC_TXR_ENTRIES - 1);
+	}
+
+	return;
+}
+
+static inline int
+mpsc_tx_intr(struct mpsc_port_info *pi)
+{
+	struct mpsc_tx_desc *txre;
+	int rc = 0;
+
+	if (!mpsc_sdma_tx_active(pi)) {
+		txre = (struct mpsc_tx_desc *)(pi->txr +
+			(pi->txr_tail * MPSC_TXRE_SIZE));
+
+		dma_cache_sync((void *) txre, MPSC_TXRE_SIZE, DMA_FROM_DEVICE);
+#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
+		if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
+			invalidate_dcache_range((ulong)txre,
+				(ulong)txre + MPSC_TXRE_SIZE);
+#endif
+
+		while (!(be32_to_cpu(txre->cmdstat) & SDMA_DESC_CMDSTAT_O)) {
+			rc = 1;
+			pi->port.icount.tx += be16_to_cpu(txre->bytecnt);
+			pi->txr_tail = (pi->txr_tail+1) & (MPSC_TXR_ENTRIES-1);
+
+			/* If no more data to tx, fall out of loop */
+			if (pi->txr_head == pi->txr_tail)
+				break;
+
+			txre = (struct mpsc_tx_desc *)(pi->txr +
+				(pi->txr_tail * MPSC_TXRE_SIZE));
+			dma_cache_sync((void *) txre, MPSC_TXRE_SIZE,
+				DMA_FROM_DEVICE);
+#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
+			if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
+				invalidate_dcache_range((ulong)txre,
+					(ulong)txre + MPSC_TXRE_SIZE);
+#endif
+		}
+
+		mpsc_copy_tx_data(pi);
+		mpsc_sdma_start_tx(pi);	/* start next desc if ready */
+	}
+
+	return rc;
+}
+
+/*
+ * This is the driver's interrupt handler.  To avoid a race, we first clear
+ * the interrupt, then handle any completed Rx/Tx descriptors.  When done
+ * handling those descriptors, we restart the Rx/Tx engines if they're stopped.
+ */
+static irqreturn_t
+mpsc_sdma_intr(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct mpsc_port_info *pi = dev_id;
+	ulong iflags;
+	int rc = IRQ_NONE;
+
+	pr_debug("mpsc_sdma_intr[%d]: SDMA Interrupt Received\n",pi->port.line);
+
+	spin_lock_irqsave(&pi->port.lock, iflags);
+	mpsc_sdma_intr_ack(pi);
+	if (mpsc_rx_intr(pi, regs))
+		rc = IRQ_HANDLED;
+	if (mpsc_tx_intr(pi))
+		rc = IRQ_HANDLED;
+	spin_unlock_irqrestore(&pi->port.lock, iflags);
+
+	pr_debug("mpsc_sdma_intr[%d]: SDMA Interrupt Handled\n", pi->port.line);
+	return rc;
+}
+
+/*
+ ******************************************************************************
+ *
+ * serial_core.c Interface routines
+ *
+ ******************************************************************************
+ */
+static uint
+mpsc_tx_empty(struct uart_port *port)
+{
+	struct mpsc_port_info *pi = (struct mpsc_port_info *)port;
+	ulong iflags;
+	uint rc;
+
+	spin_lock_irqsave(&pi->port.lock, iflags);
+	rc = mpsc_sdma_tx_active(pi) ? 0 : TIOCSER_TEMT;
+	spin_unlock_irqrestore(&pi->port.lock, iflags);
+
+	return rc;
+}
+
+static void
+mpsc_set_mctrl(struct uart_port *port, uint mctrl)
+{
+	/* Have no way to set modem control lines AFAICT */
+	return;
+}
+
+static uint
+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)
+		mflags |= TIOCM_CTS;
+	if (status & 0x2)
+		mflags |= TIOCM_CAR;
+
+	return mflags | TIOCM_DSR;	/* No way to tell if DSR asserted */
+}
+
+static void
+mpsc_stop_tx(struct uart_port *port, uint tty_start)
+{
+	struct mpsc_port_info *pi = (struct mpsc_port_info *)port;
+
+	pr_debug("mpsc_stop_tx[%d]: tty_start: %d\n", port->line, tty_start);
+
+	mpsc_freeze(pi);
+	return;
+}
+
+static void
+mpsc_start_tx(struct uart_port *port, uint tty_start)
+{
+	struct mpsc_port_info *pi = (struct mpsc_port_info *)port;
+
+	mpsc_unfreeze(pi);
+	mpsc_copy_tx_data(pi);
+	mpsc_sdma_start_tx(pi);
+
+	pr_debug("mpsc_start_tx[%d]: tty_start: %d\n", port->line, tty_start);
+	return;
+}
+
+static void
+mpsc_start_rx(struct mpsc_port_info *pi)
+{
+	pr_debug("mpsc_start_rx[%d]: Starting...\n", pi->port.line);
+
+	if (pi->rcv_data) {
+		mpsc_enter_hunt(pi);
+		mpsc_sdma_cmd(pi, SDMA_SDCM_ERD);
+	}
+	return;
+}
+
+static void
+mpsc_stop_rx(struct uart_port *port)
+{
+	struct mpsc_port_info *pi = (struct mpsc_port_info *)port;
+
+	pr_debug("mpsc_stop_rx[%d]: Stopping...\n", port->line);
+
+	mpsc_sdma_cmd(pi, SDMA_SDCM_AR);
+	return;
+}
+
+static void
+mpsc_enable_ms(struct uart_port *port)
+{
+	return;			/* Not supported */
+}
+
+static void
+mpsc_break_ctl(struct uart_port *port, int ctl)
+{
+	struct mpsc_port_info *pi = (struct mpsc_port_info *)port;
+	ulong	flags;
+	u32	v;
+
+	v = ctl ? 0x00ff0000 : 0;
+
+	spin_lock_irqsave(&pi->port.lock, flags);
+	if (pi->mirror_regs)
+		pi->MPSC_CHR_1_m = v;
+	writel(v, pi->mpsc_base + MPSC_CHR_1);
+	spin_unlock_irqrestore(&pi->port.lock, flags);
+
+	return;
+}
+
+static int
+mpsc_startup(struct uart_port *port)
+{
+	struct mpsc_port_info *pi = (struct mpsc_port_info *)port;
+	u32 flag = 0;
+	int rc;
+
+	pr_debug("mpsc_startup[%d]: Starting up MPSC, irq: %d\n",
+		port->line, pi->port.irq);
+
+	if ((rc = mpsc_make_ready(pi)) == 0) {
+		/* Setup IRQ handler */
+		mpsc_sdma_intr_ack(pi);
+
+		/* If irq's are shared, need to set flag */
+		if (mpsc_ports[0].port.irq == mpsc_ports[1].port.irq)
+			flag = SA_SHIRQ;
+
+		if (request_irq(pi->port.irq, mpsc_sdma_intr, flag,
+				"mpsc/sdma", pi))
+			printk(KERN_ERR "MPSC: Can't get SDMA IRQ %d\n",
+			       pi->port.irq);
+
+		mpsc_sdma_intr_unmask(pi, 0xf);
+		mpsc_sdma_set_rx_ring(pi, (struct mpsc_rx_desc *)(pi->rxr_p +
+			(pi->rxr_posn * MPSC_RXRE_SIZE)));
+	}
+
+	return rc;
+}
+
+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);
+
+	mpsc_sdma_stop(pi);
+	free_irq(pi->port.irq, pi);
+	return;
+}
+
+static void
+mpsc_set_termios(struct uart_port *port, struct termios *termios,
+		 struct termios *old)
+{
+	struct mpsc_port_info *pi = (struct mpsc_port_info *)port;
+	u32 baud;
+	ulong flags;
+	u32 chr_bits, stop_bits, par;
+
+	pi->c_iflag = termios->c_iflag;
+	pi->c_cflag = termios->c_cflag;
+
+	switch (termios->c_cflag & CSIZE) {
+	case CS5:
+		chr_bits = MPSC_MPCR_CL_5;
+		break;
+	case CS6:
+		chr_bits = MPSC_MPCR_CL_6;
+		break;
+	case CS7:
+		chr_bits = MPSC_MPCR_CL_7;
+		break;
+	case CS8:
+	default:
+		chr_bits = MPSC_MPCR_CL_8;
+		break;
+	}
+
+	if (termios->c_cflag & CSTOPB)
+		stop_bits = MPSC_MPCR_SBL_2;
+	else
+		stop_bits = MPSC_MPCR_SBL_1;
+
+	par = MPSC_CHR_2_PAR_EVEN;
+	if (termios->c_cflag & PARENB)
+		if (termios->c_cflag & PARODD)
+			par = MPSC_CHR_2_PAR_ODD;
+#ifdef	CMSPAR
+		if (termios->c_cflag & CMSPAR) {
+			if (termios->c_cflag & PARODD)
+				par = MPSC_CHR_2_PAR_MARK;
+			else
+				par = MPSC_CHR_2_PAR_SPACE;
+		}
+#endif
+
+	baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk);
+
+	spin_lock_irqsave(&pi->port.lock, flags);
+
+	uart_update_timeout(port, termios->c_cflag, baud);
+
+	mpsc_set_char_length(pi, chr_bits);
+	mpsc_set_stop_bit_length(pi, stop_bits);
+	mpsc_set_parity(pi, par);
+	mpsc_set_baudrate(pi, baud);
+
+	/* Characters/events to read */
+	pi->rcv_data = 1;
+	pi->port.read_status_mask = SDMA_DESC_CMDSTAT_OR;
+
+	if (termios->c_iflag & INPCK)
+		pi->port.read_status_mask |= SDMA_DESC_CMDSTAT_PE |
+		    SDMA_DESC_CMDSTAT_FR;
+
+	if (termios->c_iflag & (BRKINT | PARMRK))
+		pi->port.read_status_mask |= SDMA_DESC_CMDSTAT_BR;
+
+	/* Characters/events to ignore */
+	pi->port.ignore_status_mask = 0;
+
+	if (termios->c_iflag & IGNPAR)
+		pi->port.ignore_status_mask |= SDMA_DESC_CMDSTAT_PE |
+		    SDMA_DESC_CMDSTAT_FR;
+
+	if (termios->c_iflag & IGNBRK) {
+		pi->port.ignore_status_mask |= SDMA_DESC_CMDSTAT_BR;
+
+		if (termios->c_iflag & IGNPAR)
+			pi->port.ignore_status_mask |= SDMA_DESC_CMDSTAT_OR;
+	}
+
+	/* Ignore all chars if CREAD not set */
+	if (!(termios->c_cflag & CREAD))
+		pi->rcv_data = 0;
+	else
+		mpsc_start_rx(pi);
+
+	spin_unlock_irqrestore(&pi->port.lock, flags);
+	return;
+}
+
+static const char *
+mpsc_type(struct uart_port *port)
+{
+	pr_debug("mpsc_type[%d]: port type: %s\n", port->line,MPSC_DRIVER_NAME);
+	return MPSC_DRIVER_NAME;
+}
+
+static int
+mpsc_request_port(struct uart_port *port)
+{
+	/* Should make chip/platform specific call */
+	return 0;
+}
+
+static void
+mpsc_release_port(struct uart_port *port)
+{
+	struct mpsc_port_info *pi = (struct mpsc_port_info *)port;
+
+	if (pi->ready) {
+		mpsc_uninit_rings(pi);
+		mpsc_free_ring_mem(pi);
+		pi->ready = 0;
+	}
+
+	return;
+}
+
+static void
+mpsc_config_port(struct uart_port *port, int flags)
+{
+	return;
+}
+
+static int
+mpsc_verify_port(struct uart_port *port, struct serial_struct *ser)
+{
+	struct mpsc_port_info *pi = (struct mpsc_port_info *)port;
+	int rc = 0;
+
+	pr_debug("mpsc_verify_port[%d]: Verifying port data\n", pi->port.line);
+
+	if (ser->type != PORT_UNKNOWN && ser->type != PORT_MPSC)
+		rc = -EINVAL;
+	else if (pi->port.irq != ser->irq)
+		rc = -EINVAL;
+	else if (ser->io_type != SERIAL_IO_MEM)
+		rc = -EINVAL;
+	else if (pi->port.uartclk / 16 != ser->baud_base) /* Not sure */
+		rc = -EINVAL;
+	else if ((void *)pi->port.mapbase != ser->iomem_base)
+		rc = -EINVAL;
+	else if (pi->port.iobase != ser->port)
+		rc = -EINVAL;
+	else if (ser->hub6 != 0)
+		rc = -EINVAL;
+
+	return rc;
+}
+
+static struct uart_ops mpsc_pops = {
+	.tx_empty     = mpsc_tx_empty,
+	.set_mctrl    = mpsc_set_mctrl,
+	.get_mctrl    = mpsc_get_mctrl,
+	.stop_tx      = mpsc_stop_tx,
+	.start_tx     = mpsc_start_tx,
+	.stop_rx      = mpsc_stop_rx,
+	.enable_ms    = mpsc_enable_ms,
+	.break_ctl    = mpsc_break_ctl,
+	.startup      = mpsc_startup,
+	.shutdown     = mpsc_shutdown,
+	.set_termios  = mpsc_set_termios,
+	.type         = mpsc_type,
+	.release_port = mpsc_release_port,
+	.request_port = mpsc_request_port,
+	.config_port  = mpsc_config_port,
+	.verify_port  = mpsc_verify_port,
+};
+
+/*
+ ******************************************************************************
+ *
+ * Console Interface Routines
+ *
+ ******************************************************************************
+ */
+
+#ifdef CONFIG_SERIAL_MPSC_CONSOLE
+static void
+mpsc_console_write(struct console *co, const char *s, uint count)
+{
+	struct mpsc_port_info *pi = &mpsc_ports[co->index];
+	u8 *bp, *dp, add_cr = 0;
+	int i;
+
+	while (mpsc_sdma_tx_active(pi))
+		udelay(100);
+
+	while (count > 0) {
+		bp = dp = pi->txb + (pi->txr_head * MPSC_TXBE_SIZE);
+
+		for (i = 0; i < MPSC_TXBE_SIZE; i++) {
+			if (count == 0)
+				break;
+
+			if (add_cr) {
+				*(dp++) = '\r';
+				add_cr = 0;
+			}
+			else {
+				*(dp++) = *s;
+
+				if (*(s++) == '\n') { /* add '\r' after '\n' */
+					add_cr = 1;
+					count++;
+				}
+			}
+
+			count--;
+		}
+
+		dma_cache_sync((void *) bp, MPSC_TXBE_SIZE, DMA_BIDIRECTIONAL);
+#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
+		if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
+			flush_dcache_range((ulong)bp,
+				(ulong)bp + MPSC_TXBE_SIZE);
+#endif
+		mpsc_setup_tx_desc(pi, i, 0);
+		pi->txr_head = (pi->txr_head + 1) & (MPSC_TXR_ENTRIES - 1);
+		mpsc_sdma_start_tx(pi);
+
+		while (mpsc_sdma_tx_active(pi))
+			udelay(100);
+
+		pi->txr_tail = (pi->txr_tail + 1) & (MPSC_TXR_ENTRIES - 1);
+	}
+
+	return;
+}
+
+static int __init
+mpsc_console_setup(struct console *co, char *options)
+{
+	struct mpsc_port_info *pi;
+	int baud, bits, parity, flow;
+
+	pr_debug("mpsc_console_setup[%d]: options: %s\n", co->index, options);
+
+	if (co->index >= MPSC_NUM_CTLRS)
+		co->index = 0;
+
+	pi = &mpsc_ports[co->index];
+
+	baud = pi->default_baud;
+	bits = pi->default_bits;
+	parity = pi->default_parity;
+	flow = pi->default_flow;
+
+	if (!pi->port.ops)
+		return -ENODEV;
+
+	spin_lock_init(&pi->port.lock);	/* Temporary fix--copied from 8250.c */
+
+	if (options)
+		uart_parse_options(options, &baud, &parity, &bits, &flow);
+
+	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,
+	.device = uart_console_device,
+	.setup  = mpsc_console_setup,
+	.flags  = CON_PRINTBUFFER,
+	.index  = -1,
+	.data   = &mpsc_reg,
+};
+
+static int __init
+mpsc_late_console_init(void)
+{
+	pr_debug("mpsc_late_console_init: Enter\n");
+
+	if (!(mpsc_console.flags & CON_ENABLED))
+		register_console(&mpsc_console);
+	return 0;
+}
+
+late_initcall(mpsc_late_console_init);
+
+#define MPSC_CONSOLE	&mpsc_console
+#else
+#define MPSC_CONSOLE	NULL
+#endif
+/*
+ ******************************************************************************
+ *
+ * Dummy Platform Driver to extract & map shared register regions
+ *
+ ******************************************************************************
+ */
+static void
+mpsc_resource_err(char *s)
+{
+	printk(KERN_WARNING "MPSC: Platform device resource error in %s\n", s);
+	return;
+}
+
+static int
+mpsc_shared_map_regs(struct platform_device *pd)
+{
+	struct resource	*r;
+
+	if ((r = platform_get_resource(pd, IORESOURCE_MEM,
+		MPSC_ROUTING_BASE_ORDER)) && request_mem_region(r->start,
+		MPSC_ROUTING_REG_BLOCK_SIZE, "mpsc_routing_regs")) {
+
+		mpsc_shared_regs.mpsc_routing_base = ioremap(r->start,
+			MPSC_ROUTING_REG_BLOCK_SIZE);
+		mpsc_shared_regs.mpsc_routing_base_p = r->start;
+	}
+	else {
+		mpsc_resource_err("MPSC routing base");
+		return -ENOMEM;
+	}
+
+	if ((r = platform_get_resource(pd, IORESOURCE_MEM,
+		MPSC_SDMA_INTR_BASE_ORDER)) && request_mem_region(r->start,
+		MPSC_SDMA_INTR_REG_BLOCK_SIZE, "sdma_intr_regs")) {
+
+		mpsc_shared_regs.sdma_intr_base = ioremap(r->start,
+			MPSC_SDMA_INTR_REG_BLOCK_SIZE);
+		mpsc_shared_regs.sdma_intr_base_p = r->start;
+	}
+	else {
+		iounmap(mpsc_shared_regs.mpsc_routing_base);
+		release_mem_region(mpsc_shared_regs.mpsc_routing_base_p,
+			MPSC_ROUTING_REG_BLOCK_SIZE);
+		mpsc_resource_err("SDMA intr base");
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+static void
+mpsc_shared_unmap_regs(void)
+{
+	if (!mpsc_shared_regs.mpsc_routing_base) {
+		iounmap(mpsc_shared_regs.mpsc_routing_base);
+		release_mem_region(mpsc_shared_regs.mpsc_routing_base_p,
+			MPSC_ROUTING_REG_BLOCK_SIZE);
+	}
+	if (!mpsc_shared_regs.sdma_intr_base) {
+		iounmap(mpsc_shared_regs.sdma_intr_base);
+		release_mem_region(mpsc_shared_regs.sdma_intr_base_p,
+			MPSC_SDMA_INTR_REG_BLOCK_SIZE);
+	}
+
+	mpsc_shared_regs.mpsc_routing_base = 0;
+	mpsc_shared_regs.sdma_intr_base = 0;
+
+	mpsc_shared_regs.mpsc_routing_base_p = 0;
+	mpsc_shared_regs.sdma_intr_base_p = 0;
+
+	return;
+}
+
+static int
+mpsc_shared_drv_probe(struct device *dev)
+{
+	struct platform_device		*pd = to_platform_device(dev);
+	struct mpsc_shared_pdata	*pdata;
+	int				 rc = -ENODEV;
+
+	if (pd->id == 0) {
+		if (!(rc = mpsc_shared_map_regs(pd)))  {
+			pdata = (struct mpsc_shared_pdata *)dev->platform_data;
+
+			mpsc_shared_regs.MPSC_MRR_m = pdata->mrr_val;
+			mpsc_shared_regs.MPSC_RCRR_m= pdata->rcrr_val;
+			mpsc_shared_regs.MPSC_TCRR_m= pdata->tcrr_val;
+			mpsc_shared_regs.SDMA_INTR_CAUSE_m =
+				pdata->intr_cause_val;
+			mpsc_shared_regs.SDMA_INTR_MASK_m =
+				pdata->intr_mask_val;
+
+			rc = 0;
+		}
+	}
+
+	return rc;
+}
+
+static int
+mpsc_shared_drv_remove(struct device *dev)
+{
+	struct platform_device	*pd = to_platform_device(dev);
+	int	rc = -ENODEV;
+
+	if (pd->id == 0) {
+		mpsc_shared_unmap_regs();
+		mpsc_shared_regs.MPSC_MRR_m = 0;
+		mpsc_shared_regs.MPSC_RCRR_m = 0;
+		mpsc_shared_regs.MPSC_TCRR_m = 0;
+		mpsc_shared_regs.SDMA_INTR_CAUSE_m = 0;
+		mpsc_shared_regs.SDMA_INTR_MASK_m = 0;
+		rc = 0;
+	}
+
+	return rc;
+}
+
+static struct device_driver mpsc_shared_driver = {
+	.name	= MPSC_SHARED_NAME,
+	.bus	= &platform_bus_type,
+	.probe	= mpsc_shared_drv_probe,
+	.remove	= mpsc_shared_drv_remove,
+};
+
+/*
+ ******************************************************************************
+ *
+ * Driver Interface Routines
+ *
+ ******************************************************************************
+ */
+static struct uart_driver mpsc_reg = {
+	.owner       = THIS_MODULE,
+	.driver_name = MPSC_DRIVER_NAME,
+	.devfs_name  = MPSC_DEVFS_NAME,
+	.dev_name    = MPSC_DEV_NAME,
+	.major       = MPSC_MAJOR,
+	.minor       = MPSC_MINOR_START,
+	.nr          = MPSC_NUM_CTLRS,
+	.cons        = MPSC_CONSOLE,
+};
+
+static int
+mpsc_drv_map_regs(struct mpsc_port_info *pi, struct platform_device *pd)
+{
+	struct resource	*r;
+
+	if ((r = platform_get_resource(pd, IORESOURCE_MEM, MPSC_BASE_ORDER)) &&
+		request_mem_region(r->start, MPSC_REG_BLOCK_SIZE, "mpsc_regs")){
+
+		pi->mpsc_base = ioremap(r->start, MPSC_REG_BLOCK_SIZE);
+		pi->mpsc_base_p = r->start;
+	}
+	else {
+		mpsc_resource_err("MPSC base");
+		return -ENOMEM;
+	}
+
+	if ((r = platform_get_resource(pd, IORESOURCE_MEM,
+		MPSC_SDMA_BASE_ORDER)) && request_mem_region(r->start,
+		MPSC_SDMA_REG_BLOCK_SIZE, "sdma_regs")) {
+
+		pi->sdma_base = ioremap(r->start,MPSC_SDMA_REG_BLOCK_SIZE);
+		pi->sdma_base_p = r->start;
+	}
+	else {
+		mpsc_resource_err("SDMA base");
+		return -ENOMEM;
+	}
+
+	if ((r = platform_get_resource(pd,IORESOURCE_MEM,MPSC_BRG_BASE_ORDER))
+		&& request_mem_region(r->start, MPSC_BRG_REG_BLOCK_SIZE,
+		"brg_regs")) {
+
+		pi->brg_base = ioremap(r->start, MPSC_BRG_REG_BLOCK_SIZE);
+		pi->brg_base_p = r->start;
+	}
+	else {
+		mpsc_resource_err("BRG base");
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+static void
+mpsc_drv_unmap_regs(struct mpsc_port_info *pi)
+{
+	if (!pi->mpsc_base) {
+		iounmap(pi->mpsc_base);
+		release_mem_region(pi->mpsc_base_p, MPSC_REG_BLOCK_SIZE);
+	}
+	if (!pi->sdma_base) {
+		iounmap(pi->sdma_base);
+		release_mem_region(pi->sdma_base_p, MPSC_SDMA_REG_BLOCK_SIZE);
+	}
+	if (!pi->brg_base) {
+		iounmap(pi->brg_base);
+		release_mem_region(pi->brg_base_p, MPSC_BRG_REG_BLOCK_SIZE);
+	}
+
+	pi->mpsc_base = 0;
+	pi->sdma_base = 0;
+	pi->brg_base = 0;
+
+	pi->mpsc_base_p = 0;
+	pi->sdma_base_p = 0;
+	pi->brg_base_p = 0;
+
+	return;
+}
+
+static void
+mpsc_drv_get_platform_data(struct mpsc_port_info *pi,
+	struct platform_device *pd, int num)
+{
+	struct mpsc_pdata	*pdata;
+
+	pdata = (struct mpsc_pdata *)pd->dev.platform_data;
+
+	pi->port.uartclk = pdata->brg_clk_freq;
+	pi->port.iotype = UPIO_MEM;
+	pi->port.line = num;
+	pi->port.type = PORT_MPSC;
+	pi->port.fifosize = MPSC_TXBE_SIZE;
+	pi->port.membase = pi->mpsc_base;
+	pi->port.mapbase = (ulong)pi->mpsc_base;
+	pi->port.ops = &mpsc_pops;
+
+	pi->mirror_regs = pdata->mirror_regs;
+	pi->cache_mgmt = pdata->cache_mgmt;
+	pi->brg_can_tune = pdata->brg_can_tune;
+	pi->brg_clk_src = pdata->brg_clk_src;
+	pi->mpsc_max_idle = pdata->max_idle;
+	pi->default_baud = pdata->default_baud;
+	pi->default_bits = pdata->default_bits;
+	pi->default_parity = pdata->default_parity;
+	pi->default_flow = pdata->default_flow;
+
+	/* Initial values of mirrored regs */
+	pi->MPSC_CHR_1_m = pdata->chr_1_val;
+	pi->MPSC_CHR_2_m = pdata->chr_2_val;
+	pi->MPSC_CHR_10_m = pdata->chr_10_val;
+	pi->MPSC_MPCR_m = pdata->mpcr_val;
+	pi->BRG_BCR_m = pdata->bcr_val;
+
+	pi->shared_regs = &mpsc_shared_regs;
+
+	pi->port.irq = platform_get_irq(pd, 0);
+
+	return;
+}
+
+static int
+mpsc_drv_probe(struct device *dev)
+{
+	struct platform_device	*pd = to_platform_device(dev);
+	struct mpsc_port_info	*pi;
+	int			rc = -ENODEV;
+
+	pr_debug("mpsc_drv_probe: Adding MPSC %d\n", pd->id);
+
+	if (pd->id < MPSC_NUM_CTLRS) {
+		pi = &mpsc_ports[pd->id];
+
+		if (!(rc = mpsc_drv_map_regs(pi, pd))) {
+			mpsc_drv_get_platform_data(pi, pd, pd->id);
+
+			if (!(rc = mpsc_make_ready(pi)))
+				if (!(rc = uart_add_one_port(&mpsc_reg,
+					&pi->port)))
+					rc = 0;
+				else {
+					mpsc_release_port(
+						(struct uart_port *)pi);
+					mpsc_drv_unmap_regs(pi);
+				}
+			else
+				mpsc_drv_unmap_regs(pi);
+		}
+	}
+
+	return rc;
+}
+
+static int
+mpsc_drv_remove(struct device *dev)
+{
+	struct platform_device	*pd = to_platform_device(dev);
+
+	pr_debug("mpsc_drv_exit: Removing MPSC %d\n", pd->id);
+
+	if (pd->id < MPSC_NUM_CTLRS) {
+		uart_remove_one_port(&mpsc_reg, &mpsc_ports[pd->id].port);
+		mpsc_release_port((struct uart_port *)&mpsc_ports[pd->id].port);
+		mpsc_drv_unmap_regs(&mpsc_ports[pd->id]);
+		return 0;
+	}
+	else
+		return -ENODEV;
+}
+
+static struct device_driver mpsc_driver = {
+	.name	= MPSC_CTLR_NAME,
+	.bus	= &platform_bus_type,
+	.probe	= mpsc_drv_probe,
+	.remove	= mpsc_drv_remove,
+};
+
+static int __init
+mpsc_drv_init(void)
+{
+	int	rc;
+
+	printk(KERN_INFO "Serial: MPSC driver $Revision: 1.00 $\n");
+
+	memset(mpsc_ports, 0, sizeof(mpsc_ports));
+	memset(&mpsc_shared_regs, 0, sizeof(mpsc_shared_regs));
+
+	if (!(rc = uart_register_driver(&mpsc_reg))) {
+		if (!(rc = driver_register(&mpsc_shared_driver))) {
+			if ((rc = driver_register(&mpsc_driver))) {
+				driver_unregister(&mpsc_shared_driver);
+				uart_unregister_driver(&mpsc_reg);
+			}
+		}
+		else
+			uart_unregister_driver(&mpsc_reg);
+	}
+
+	return rc;
+
+}
+
+static void __exit
+mpsc_drv_exit(void)
+{
+	driver_unregister(&mpsc_driver);
+	driver_unregister(&mpsc_shared_driver);
+	uart_unregister_driver(&mpsc_reg);
+	memset(mpsc_ports, 0, sizeof(mpsc_ports));
+	memset(&mpsc_shared_regs, 0, sizeof(mpsc_shared_regs));
+	return;
+}
+
+module_init(mpsc_drv_init);
+module_exit(mpsc_drv_exit);
+
+MODULE_AUTHOR("Mark A. Greer <mgreer@mvista.com>");
+MODULE_DESCRIPTION("Generic Marvell MPSC serial/UART driver $Revision: 1.00 $");
+MODULE_VERSION(MPSC_VERSION);
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_CHARDEV_MAJOR(MPSC_MAJOR);
diff -Nru a/drivers/serial/mpsc.h b/drivers/serial/mpsc.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/serial/mpsc.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,289 @@
+/*
+ * drivers/serial/mpsc.h
+ *
+ * Author: Mark A. Greer <mgreer@mvista.com>
+ *
+ * 2004 (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.
+ */
+
+#ifndef	__MPSC_H__
+#define	__MPSC_H__
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/sysrq.h>
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/mv643xx.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#if defined(CONFIG_SERIAL_MPSC_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+#define SUPPORT_SYSRQ
+#endif
+
+#define	MPSC_NUM_CTLRS		2
+
+/*
+ * Descriptors and buffers must be cache line aligned.
+ * Buffers lengths must be multiple of cache line size.
+ * Number of Tx & Rx descriptors must be powers of 2.
+ */
+#define	MPSC_RXR_ENTRIES	32
+#define	MPSC_RXRE_SIZE		dma_get_cache_alignment()
+#define	MPSC_RXR_SIZE		(MPSC_RXR_ENTRIES * MPSC_RXRE_SIZE)
+#define	MPSC_RXBE_SIZE		dma_get_cache_alignment()
+#define	MPSC_RXB_SIZE		(MPSC_RXR_ENTRIES * MPSC_RXBE_SIZE)
+
+#define	MPSC_TXR_ENTRIES	32
+#define	MPSC_TXRE_SIZE		dma_get_cache_alignment()
+#define	MPSC_TXR_SIZE		(MPSC_TXR_ENTRIES * MPSC_TXRE_SIZE)
+#define	MPSC_TXBE_SIZE		dma_get_cache_alignment()
+#define	MPSC_TXB_SIZE		(MPSC_TXR_ENTRIES * MPSC_TXBE_SIZE)
+
+#define	MPSC_DMA_ALLOC_SIZE	(MPSC_RXR_SIZE + MPSC_RXB_SIZE +	\
+				MPSC_TXR_SIZE + MPSC_TXB_SIZE +		\
+				dma_get_cache_alignment() /* for alignment */)
+
+/* Rx and Tx Ring entry descriptors -- assume entry size is <= cacheline size */
+struct mpsc_rx_desc {
+	u16 bufsize;
+	u16 bytecnt;
+	u32 cmdstat;
+	u32 link;
+	u32 buf_ptr;
+} __attribute((packed));
+
+struct mpsc_tx_desc {
+	u16 bytecnt;
+	u16 shadow;
+	u32 cmdstat;
+	u32 link;
+	u32 buf_ptr;
+} __attribute((packed));
+
+/*
+ * Some regs that have the erratum that you can't read them are are shared
+ * between the two MPSC controllers.  This struct contains those shared regs.
+ */
+struct mpsc_shared_regs {
+	phys_addr_t mpsc_routing_base_p;
+	phys_addr_t sdma_intr_base_p;
+
+	void *mpsc_routing_base;
+	void *sdma_intr_base;
+
+	u32 MPSC_MRR_m;
+	u32 MPSC_RCRR_m;
+	u32 MPSC_TCRR_m;
+	u32 SDMA_INTR_CAUSE_m;
+	u32 SDMA_INTR_MASK_m;
+};
+
+/* The main driver data structure */
+struct mpsc_port_info {
+	struct uart_port port;	/* Overlay uart_port structure */
+
+	/* Internal driver state for this ctlr */
+	u8 ready;
+	u8 rcv_data;
+	tcflag_t c_iflag;	/* save termios->c_iflag */
+	tcflag_t c_cflag;	/* save termios->c_cflag */
+
+	/* Info passed in from platform */
+	u8 mirror_regs;		/* Need to mirror regs? */
+	u8 cache_mgmt;		/* Need manual cache mgmt? */
+	u8 brg_can_tune;	/* BRG has baud tuning? */
+	u32 brg_clk_src;
+	u16 mpsc_max_idle;
+	int default_baud;
+	int default_bits;
+	int default_parity;
+	int default_flow;
+
+	/* Physical addresses of various blocks of registers (from platform) */
+	phys_addr_t mpsc_base_p;
+	phys_addr_t sdma_base_p;
+	phys_addr_t brg_base_p;
+
+	/* Virtual addresses of various blocks of registers (from platform) */
+	void *mpsc_base;
+	void *sdma_base;
+	void *brg_base;
+
+	/* Descriptor ring and buffer allocations */
+	void *dma_region;
+	dma_addr_t dma_region_p;
+
+	dma_addr_t rxr;		/* Rx descriptor ring */
+	dma_addr_t rxr_p;	/* Phys addr of rxr */
+	u8 *rxb;		/* Rx Ring I/O buf */
+	u8 *rxb_p;		/* Phys addr of rxb */
+	u32 rxr_posn;		/* First desc w/ Rx data */
+
+	dma_addr_t txr;		/* Tx descriptor ring */
+	dma_addr_t txr_p;	/* Phys addr of txr */
+	u8 *txb;		/* Tx Ring I/O buf */
+	u8 *txb_p;		/* Phys addr of txb */
+	int txr_head;		/* Where new data goes */
+	int txr_tail;		/* Where sent data comes off */
+
+	/* Mirrored values of regs we can't read (if 'mirror_regs' set) */
+	u32 MPSC_MPCR_m;
+	u32 MPSC_CHR_1_m;
+	u32 MPSC_CHR_2_m;
+	u32 MPSC_CHR_10_m;
+	u32 BRG_BCR_m;
+	struct mpsc_shared_regs *shared_regs;
+};
+
+/* Hooks to platform-specific code */
+int mpsc_platform_register_driver(void);
+void mpsc_platform_unregister_driver(void);
+
+/* Hooks back in to mpsc common to be called by platform-specific code */
+struct mpsc_port_info *mpsc_device_probe(int index);
+struct mpsc_port_info *mpsc_device_remove(int index);
+
+/*
+ *****************************************************************************
+ *
+ *	Multi-Protocol Serial Controller Interface Registers
+ *
+ *****************************************************************************
+ */
+
+/* Main Configuratino Register Offsets */
+#define	MPSC_MMCRL			0x0000
+#define	MPSC_MMCRH			0x0004
+#define	MPSC_MPCR			0x0008
+#define	MPSC_CHR_1			0x000c
+#define	MPSC_CHR_2			0x0010
+#define	MPSC_CHR_3			0x0014
+#define	MPSC_CHR_4			0x0018
+#define	MPSC_CHR_5			0x001c
+#define	MPSC_CHR_6			0x0020
+#define	MPSC_CHR_7			0x0024
+#define	MPSC_CHR_8			0x0028
+#define	MPSC_CHR_9			0x002c
+#define	MPSC_CHR_10			0x0030
+#define	MPSC_CHR_11			0x0034
+
+#define	MPSC_MPCR_FRZ			(1 << 9)
+#define	MPSC_MPCR_CL_5			0
+#define	MPSC_MPCR_CL_6			1
+#define	MPSC_MPCR_CL_7			2
+#define	MPSC_MPCR_CL_8			3
+#define	MPSC_MPCR_SBL_1			0
+#define	MPSC_MPCR_SBL_2			1
+
+#define	MPSC_CHR_2_TEV			(1<<1)
+#define	MPSC_CHR_2_TA			(1<<7)
+#define	MPSC_CHR_2_TTCS			(1<<9)
+#define	MPSC_CHR_2_REV			(1<<17)
+#define	MPSC_CHR_2_RA			(1<<23)
+#define	MPSC_CHR_2_CRD			(1<<25)
+#define	MPSC_CHR_2_EH			(1<<31)
+#define	MPSC_CHR_2_PAR_ODD		0
+#define	MPSC_CHR_2_PAR_SPACE		1
+#define	MPSC_CHR_2_PAR_EVEN		2
+#define	MPSC_CHR_2_PAR_MARK		3
+
+/* MPSC Signal Routing */
+#define	MPSC_MRR			0x0000
+#define	MPSC_RCRR			0x0004
+#define	MPSC_TCRR			0x0008
+
+/*
+ *****************************************************************************
+ *
+ *	Serial DMA Controller Interface Registers
+ *
+ *****************************************************************************
+ */
+
+#define	SDMA_SDC			0x0000
+#define	SDMA_SDCM			0x0008
+#define	SDMA_RX_DESC			0x0800
+#define	SDMA_RX_BUF_PTR			0x0808
+#define	SDMA_SCRDP			0x0810
+#define	SDMA_TX_DESC			0x0c00
+#define	SDMA_SCTDP			0x0c10
+#define	SDMA_SFTDP			0x0c14
+
+#define	SDMA_DESC_CMDSTAT_PE		(1<<0)
+#define	SDMA_DESC_CMDSTAT_CDL		(1<<1)
+#define	SDMA_DESC_CMDSTAT_FR		(1<<3)
+#define	SDMA_DESC_CMDSTAT_OR		(1<<6)
+#define	SDMA_DESC_CMDSTAT_BR		(1<<9)
+#define	SDMA_DESC_CMDSTAT_MI		(1<<10)
+#define	SDMA_DESC_CMDSTAT_A		(1<<11)
+#define	SDMA_DESC_CMDSTAT_AM		(1<<12)
+#define	SDMA_DESC_CMDSTAT_CT		(1<<13)
+#define	SDMA_DESC_CMDSTAT_C		(1<<14)
+#define	SDMA_DESC_CMDSTAT_ES		(1<<15)
+#define	SDMA_DESC_CMDSTAT_L		(1<<16)
+#define	SDMA_DESC_CMDSTAT_F		(1<<17)
+#define	SDMA_DESC_CMDSTAT_P		(1<<18)
+#define	SDMA_DESC_CMDSTAT_EI		(1<<23)
+#define	SDMA_DESC_CMDSTAT_O		(1<<31)
+
+#define SDMA_DESC_DFLT			(SDMA_DESC_CMDSTAT_O |	\
+					SDMA_DESC_CMDSTAT_EI)
+
+#define	SDMA_SDC_RFT			(1<<0)
+#define	SDMA_SDC_SFM			(1<<1)
+#define	SDMA_SDC_BLMR			(1<<6)
+#define	SDMA_SDC_BLMT			(1<<7)
+#define	SDMA_SDC_POVR			(1<<8)
+#define	SDMA_SDC_RIFB			(1<<9)
+
+#define	SDMA_SDCM_ERD			(1<<7)
+#define	SDMA_SDCM_AR			(1<<15)
+#define	SDMA_SDCM_STD			(1<<16)
+#define	SDMA_SDCM_TXD			(1<<23)
+#define	SDMA_SDCM_AT			(1<<31)
+
+#define	SDMA_0_CAUSE_RXBUF		(1<<0)
+#define	SDMA_0_CAUSE_RXERR		(1<<1)
+#define	SDMA_0_CAUSE_TXBUF		(1<<2)
+#define	SDMA_0_CAUSE_TXEND		(1<<3)
+#define	SDMA_1_CAUSE_RXBUF		(1<<8)
+#define	SDMA_1_CAUSE_RXERR		(1<<9)
+#define	SDMA_1_CAUSE_TXBUF		(1<<10)
+#define	SDMA_1_CAUSE_TXEND		(1<<11)
+
+#define	SDMA_CAUSE_RX_MASK	(SDMA_0_CAUSE_RXBUF | SDMA_0_CAUSE_RXERR | \
+	SDMA_1_CAUSE_RXBUF | SDMA_1_CAUSE_RXERR)
+#define	SDMA_CAUSE_TX_MASK	(SDMA_0_CAUSE_TXBUF | SDMA_0_CAUSE_TXEND | \
+	SDMA_1_CAUSE_TXBUF | SDMA_1_CAUSE_TXEND)
+
+/* SDMA Interrupt registers */
+#define	SDMA_INTR_CAUSE			0x0000
+#define	SDMA_INTR_MASK			0x0080
+
+/*
+ *****************************************************************************
+ *
+ *	Baud Rate Generator Interface Registers
+ *
+ *****************************************************************************
+ */
+
+#define	BRG_BCR				0x0000
+#define	BRG_BTR				0x0004
+
+#endif				/* __MPSC_H__ */
diff -Nru a/drivers/serial/pmac_zilog.c b/drivers/serial/pmac_zilog.c
--- a/drivers/serial/pmac_zilog.c	2005-03-01 23:38:51 -08:00
+++ b/drivers/serial/pmac_zilog.c	2005-03-01 23:38:51 -08:00
@@ -1946,6 +1946,8 @@
 	unsigned long flags;
 	int i;
 
+	if (ZS_IS_ASLEEP(uap))
+		return;
 	spin_lock_irqsave(&uap->port.lock, flags);
 
 	/* Turn of interrupts and enable the transmitter. */
diff -Nru a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c
--- a/drivers/serial/s3c2410.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/serial/s3c2410.c	2005-03-01 23:38:57 -08:00
@@ -744,11 +744,12 @@
 	unsigned long flags;
 	unsigned int baud, quot;
 	unsigned int ulcon;
+	unsigned int umcon;
 
 	/*
 	 * We don't support modem control lines.
 	 */
-	termios->c_cflag &= ~(HUPCL | CRTSCTS | CMSPAR);
+	termios->c_cflag &= ~(HUPCL | CMSPAR);
 	termios->c_cflag |= CLOCAL;
 
 	/*
@@ -806,8 +807,10 @@
 	if (termios->c_cflag & CSTOPB)
 		ulcon |= S3C2410_LCON_STOPB;
 
+	umcon = (termios->c_cflag & CRTSCTS) ? S3C2410_UMCOM_AFC : 0;
+
 	if (termios->c_cflag & PARENB) {
-		if (!(termios->c_cflag & PARODD))
+		if (termios->c_cflag & PARODD)
 			ulcon |= S3C2410_LCON_PODD;
 		else
 			ulcon |= S3C2410_LCON_PEVEN;
@@ -821,6 +824,7 @@
 
 	wr_regl(port, S3C2410_ULCON, ulcon);
 	wr_regl(port, S3C2410_UBRDIV, quot);
+	wr_regl(port, S3C2410_UMCON, umcon);
 
 	dbg("uart: ulcon = 0x%08x, ucon = 0x%08x, ufcon = 0x%08x\n",
 	    rd_regl(port, S3C2410_ULCON),
diff -Nru a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
--- a/drivers/serial/serial_core.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/serial/serial_core.c	2005-03-01 23:38:53 -08:00
@@ -1877,7 +1877,21 @@
 	 * Re-enable the console device after suspending.
 	 */
 	if (uart_console(port)) {
-		uart_change_speed(state, NULL);
+		struct termios termios;
+
+		/*
+		 * First try to use the console cflag setting.
+		 */
+		memset(&termios, 0, sizeof(struct termios));
+		termios.c_cflag = port->cons->cflag;
+
+		/*
+		 * If that's unset, use the tty termios setting.
+		 */
+		if (state->info && state->info->tty && termios.c_cflag == 0)
+			termios = *state->info->tty->termios;
+
+		port->ops->set_termios(port, &termios, NULL);
 		console_start(port->cons);
 	}
 
diff -Nru a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c
--- a/drivers/serial/serial_cs.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/serial/serial_cs.c	2005-03-01 23:38:57 -08:00
@@ -68,18 +68,11 @@
 
 /* Parameters that can be set with 'insmod' */
 
-/* Bit map of interrupts to choose from */
-static u_int irq_mask = 0xdeb8;
-static int irq_list[4];
-static unsigned int irq_list_count;
-
 /* Enable the speaker? */
 static int do_sound = 1;
 /* Skip strict UART tests? */
 static int buggy_uart;
 
-module_param(irq_mask, uint, 0444);
-module_param_array(irq_list, int, &irq_list_count, 0444);
 module_param(do_sound, int, 0444);
 module_param(buggy_uart, int, 0444);
 
@@ -205,7 +198,7 @@
 	struct serial_info *info;
 	client_reg_t client_reg;
 	dev_link_t *link;
-	int i, ret;
+	int ret;
 
 	DEBUG(0, "serial_attach()\n");
 
@@ -220,12 +213,7 @@
 	link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
 	link->io.NumPorts1 = 8;
 	link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
-	link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
-	if (irq_list_count == 0)
-		link->irq.IRQInfo2 = irq_mask;
-	else
-		for (i = 0; i < irq_list_count; i++)
-			link->irq.IRQInfo2 |= 1 << irq_list[i];
+	link->irq.IRQInfo1 = IRQ_LEVEL_ID;
 	link->conf.Attributes = CONF_ENABLE_IRQ;
 	if (do_sound) {
 		link->conf.Attributes |= CONF_ENABLE_SPKR;
@@ -237,7 +225,6 @@
 	link->next = dev_list;
 	dev_list = link;
 	client_reg.dev_info = &dev_info;
-	client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
 	client_reg.EventMask =
 	    CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
 	    CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
@@ -302,7 +289,7 @@
 
 /*====================================================================*/
 
-static int setup_serial(struct serial_info * info, ioaddr_t iobase, int irq)
+static int setup_serial(struct serial_info * info, kio_addr_t iobase, int irq)
 {
 	struct uart_port port;
 	int line;
@@ -364,7 +351,7 @@
 
 static int simple_config(dev_link_t *link)
 {
-	static ioaddr_t base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
+	static kio_addr_t base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
 	static int size_table[2] = { 8, 16 };
 	client_handle_t handle = link->handle;
 	struct serial_info *info = link->priv;
@@ -379,7 +366,7 @@
 	/* If the card is already configured, look up the port and irq */
 	i = pcmcia_get_configuration_info(handle, &config);
 	if ((i == CS_SUCCESS) && (config.Attributes & CONF_VALID_CLIENT)) {
-		ioaddr_t port = 0;
+		kio_addr_t port = 0;
 		if ((config.BasePort2 != 0) && (config.NumPorts2 == 8)) {
 			port = config.BasePort2;
 			info->slave = 1;
@@ -749,10 +736,7 @@
 static void __exit exit_serial_cs(void)
 {
 	pcmcia_unregister_driver(&serial_cs_driver);
-
-	/* XXX: this really needs to move into generic code.. */
-	while (dev_list != NULL)
-		serial_detach(dev_list);
+	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_serial_cs);
diff -Nru a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/serial/serial_txx9.c	2005-03-01 23:39:26 -08:00
@@ -0,0 +1,1171 @@
+/*
+ *  drivers/serial/serial_txx9.c
+ *
+ * Derived from many drivers using generic_serial interface,
+ * especially serial_tx3912.c by Steven J. Hill and r39xx_serial.c
+ * (was in Linux/VR tree) by Jim Pick.
+ *
+ *  Copyright (C) 1999 Harald Koerfgen
+ *  Copyright (C) 2000 Jim Pick <jim@jimpick.com>
+ *  Copyright (C) 2001 Steven J. Hill (sjhill@realitydiluted.com)
+ *  Copyright (C) 2000-2002 Toshiba 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.
+ *
+ *  Serial driver for TX3927/TX4927/TX4925/TX4938 internal SIO controller
+ *
+ *  Revision History:
+ *	0.30	Initial revision. (Renamed from serial_txx927.c)
+ *	0.31	Use save_flags instead of local_irq_save.
+ *	0.32	Support SCLK.
+ *	0.33	Switch TXX9_TTY_NAME by CONFIG_SERIAL_TXX9_STDSERIAL.
+ *		Support TIOCSERGETLSR.
+ *	0.34	Support slow baudrate.
+ *	0.40	Merge codes from mainstream kernel (2.4.22).
+ *	0.41	Fix console checking in rs_shutdown_port().
+ *		Disable flow-control in serial_console_write().
+ *	0.42	Fix minor compiler warning.
+ *	1.00	Kernel 2.6.  Converted to new serial core (based on 8250.c).
+ *	1.01	Set fifosize to make tx_empry called properly.
+ *		Use standard uart_get_divisor.
+ *	1.02	Cleanup. (import 8250.c changes)
+ */
+#include <linux/config.h>
+
+#if defined(CONFIG_SERIAL_TXX9_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+#define SUPPORT_SYSRQ
+#endif
+
+#include <linux/module.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/sysrq.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/pci.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/serial_core.h>
+#include <linux/serial.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+
+static char *serial_version = "1.02";
+static char *serial_name = "TX39/49 Serial driver";
+
+#define PASS_LIMIT	256
+
+#if !defined(CONFIG_SERIAL_TXX9_STDSERIAL)
+/* "ttyS" is used for standard serial driver */
+#define TXX9_TTY_NAME "ttyTX"
+#define TXX9_TTY_DEVFS_NAME "tttx/"
+#define TXX9_TTY_MINOR_START	(64 + 64)	/* ttyTX0(128), ttyTX1(129) */
+#else
+/* acts like standard serial driver */
+#define TXX9_TTY_NAME "ttyS"
+#define TXX9_TTY_DEVFS_NAME "tts/"
+#define TXX9_TTY_MINOR_START	64
+#endif
+#define TXX9_TTY_MAJOR	TTY_MAJOR
+
+/* flag aliases */
+#define UPF_TXX9_HAVE_CTS_LINE	UPF_BUGGY_UART
+#define UPF_TXX9_USE_SCLK	UPF_MAGIC_MULTIPLIER
+
+#ifdef CONFIG_PCI
+/* support for Toshiba TC86C001 SIO */
+#define ENABLE_SERIAL_TXX9_PCI
+#endif
+
+/*
+ * Number of serial ports
+ */
+#ifdef ENABLE_SERIAL_TXX9_PCI
+#define NR_PCI_BOARDS	4
+#define UART_NR  (2 + NR_PCI_BOARDS)
+#else
+#define UART_NR  2
+#endif
+
+struct uart_txx9_port {
+	struct uart_port	port;
+
+	/*
+	 * We provide a per-port pm hook.
+	 */
+	void			(*pm)(struct uart_port *port,
+				      unsigned int state, unsigned int old);
+};
+
+#define TXX9_REGION_SIZE	0x24
+
+/* TXX9 Serial Registers */
+#define TXX9_SILCR	0x00
+#define TXX9_SIDICR	0x04
+#define TXX9_SIDISR	0x08
+#define TXX9_SICISR	0x0c
+#define TXX9_SIFCR	0x10
+#define TXX9_SIFLCR	0x14
+#define TXX9_SIBGR	0x18
+#define TXX9_SITFIFO	0x1c
+#define TXX9_SIRFIFO	0x20
+
+/* SILCR : Line Control */
+#define TXX9_SILCR_SCS_MASK	0x00000060
+#define TXX9_SILCR_SCS_IMCLK	0x00000000
+#define TXX9_SILCR_SCS_IMCLK_BG	0x00000020
+#define TXX9_SILCR_SCS_SCLK	0x00000040
+#define TXX9_SILCR_SCS_SCLK_BG	0x00000060
+#define TXX9_SILCR_UEPS	0x00000010
+#define TXX9_SILCR_UPEN	0x00000008
+#define TXX9_SILCR_USBL_MASK	0x00000004
+#define TXX9_SILCR_USBL_1BIT	0x00000000
+#define TXX9_SILCR_USBL_2BIT	0x00000004
+#define TXX9_SILCR_UMODE_MASK	0x00000003
+#define TXX9_SILCR_UMODE_8BIT	0x00000000
+#define TXX9_SILCR_UMODE_7BIT	0x00000001
+
+/* SIDICR : DMA/Int. Control */
+#define TXX9_SIDICR_TDE	0x00008000
+#define TXX9_SIDICR_RDE	0x00004000
+#define TXX9_SIDICR_TIE	0x00002000
+#define TXX9_SIDICR_RIE	0x00001000
+#define TXX9_SIDICR_SPIE	0x00000800
+#define TXX9_SIDICR_CTSAC	0x00000600
+#define TXX9_SIDICR_STIE_MASK	0x0000003f
+#define TXX9_SIDICR_STIE_OERS		0x00000020
+#define TXX9_SIDICR_STIE_CTSS		0x00000010
+#define TXX9_SIDICR_STIE_RBRKD	0x00000008
+#define TXX9_SIDICR_STIE_TRDY		0x00000004
+#define TXX9_SIDICR_STIE_TXALS	0x00000002
+#define TXX9_SIDICR_STIE_UBRKD	0x00000001
+
+/* SIDISR : DMA/Int. Status */
+#define TXX9_SIDISR_UBRK	0x00008000
+#define TXX9_SIDISR_UVALID	0x00004000
+#define TXX9_SIDISR_UFER	0x00002000
+#define TXX9_SIDISR_UPER	0x00001000
+#define TXX9_SIDISR_UOER	0x00000800
+#define TXX9_SIDISR_ERI	0x00000400
+#define TXX9_SIDISR_TOUT	0x00000200
+#define TXX9_SIDISR_TDIS	0x00000100
+#define TXX9_SIDISR_RDIS	0x00000080
+#define TXX9_SIDISR_STIS	0x00000040
+#define TXX9_SIDISR_RFDN_MASK	0x0000001f
+
+/* SICISR : Change Int. Status */
+#define TXX9_SICISR_OERS	0x00000020
+#define TXX9_SICISR_CTSS	0x00000010
+#define TXX9_SICISR_RBRKD	0x00000008
+#define TXX9_SICISR_TRDY	0x00000004
+#define TXX9_SICISR_TXALS	0x00000002
+#define TXX9_SICISR_UBRKD	0x00000001
+
+/* SIFCR : FIFO Control */
+#define TXX9_SIFCR_SWRST	0x00008000
+#define TXX9_SIFCR_RDIL_MASK	0x00000180
+#define TXX9_SIFCR_RDIL_1	0x00000000
+#define TXX9_SIFCR_RDIL_4	0x00000080
+#define TXX9_SIFCR_RDIL_8	0x00000100
+#define TXX9_SIFCR_RDIL_12	0x00000180
+#define TXX9_SIFCR_RDIL_MAX	0x00000180
+#define TXX9_SIFCR_TDIL_MASK	0x00000018
+#define TXX9_SIFCR_TDIL_MASK	0x00000018
+#define TXX9_SIFCR_TDIL_1	0x00000000
+#define TXX9_SIFCR_TDIL_4	0x00000001
+#define TXX9_SIFCR_TDIL_8	0x00000010
+#define TXX9_SIFCR_TDIL_MAX	0x00000010
+#define TXX9_SIFCR_TFRST	0x00000004
+#define TXX9_SIFCR_RFRST	0x00000002
+#define TXX9_SIFCR_FRSTE	0x00000001
+#define TXX9_SIO_TX_FIFO	8
+#define TXX9_SIO_RX_FIFO	16
+
+/* SIFLCR : Flow Control */
+#define TXX9_SIFLCR_RCS	0x00001000
+#define TXX9_SIFLCR_TES	0x00000800
+#define TXX9_SIFLCR_RTSSC	0x00000200
+#define TXX9_SIFLCR_RSDE	0x00000100
+#define TXX9_SIFLCR_TSDE	0x00000080
+#define TXX9_SIFLCR_RTSTL_MASK	0x0000001e
+#define TXX9_SIFLCR_RTSTL_MAX	0x0000001e
+#define TXX9_SIFLCR_TBRK	0x00000001
+
+/* SIBGR : Baudrate Control */
+#define TXX9_SIBGR_BCLK_MASK	0x00000300
+#define TXX9_SIBGR_BCLK_T0	0x00000000
+#define TXX9_SIBGR_BCLK_T2	0x00000100
+#define TXX9_SIBGR_BCLK_T4	0x00000200
+#define TXX9_SIBGR_BCLK_T6	0x00000300
+#define TXX9_SIBGR_BRD_MASK	0x000000ff
+
+static inline unsigned int sio_in(struct uart_txx9_port *up, int offset)
+{
+	switch (up->port.iotype) {
+	default:
+		return *(volatile u32 *)(up->port.membase + offset);
+	case UPIO_PORT:
+		return inl(up->port.iobase + offset);
+	}
+}
+
+static inline void
+sio_out(struct uart_txx9_port *up, int offset, int value)
+{
+	switch (up->port.iotype) {
+	default:
+		*(volatile u32 *)(up->port.membase + offset) = value;
+		break;
+	case UPIO_PORT:
+		outl(value, up->port.iobase + offset);
+		break;
+	}
+}
+
+static inline void
+sio_mask(struct uart_txx9_port *up, int offset, unsigned int value)
+{
+	sio_out(up, offset, sio_in(up, offset) & ~value);
+}
+static inline void
+sio_set(struct uart_txx9_port *up, int offset, unsigned int value)
+{
+	sio_out(up, offset, sio_in(up, offset) | value);
+}
+
+static inline void
+sio_quot_set(struct uart_txx9_port *up, int quot)
+{
+	quot >>= 1;
+	if (quot < 256)
+		sio_out(up, TXX9_SIBGR, quot | TXX9_SIBGR_BCLK_T0);
+	else if (quot < (256 << 2))
+		sio_out(up, TXX9_SIBGR, (quot >> 2) | TXX9_SIBGR_BCLK_T2);
+	else if (quot < (256 << 4))
+		sio_out(up, TXX9_SIBGR, (quot >> 4) | TXX9_SIBGR_BCLK_T4);
+	else if (quot < (256 << 6))
+		sio_out(up, TXX9_SIBGR, (quot >> 6) | TXX9_SIBGR_BCLK_T6);
+	else
+		sio_out(up, TXX9_SIBGR, 0xff | TXX9_SIBGR_BCLK_T6);
+}
+
+static void serial_txx9_stop_tx(struct uart_port *port, unsigned int tty_stop)
+{
+	struct uart_txx9_port *up = (struct uart_txx9_port *)port;
+	unsigned long flags;
+
+	spin_lock_irqsave(&up->port.lock, flags);
+	sio_mask(up, TXX9_SIDICR, TXX9_SIDICR_TIE);
+	spin_unlock_irqrestore(&up->port.lock, flags);
+}
+
+static void serial_txx9_start_tx(struct uart_port *port, unsigned int tty_start)
+{
+	struct uart_txx9_port *up = (struct uart_txx9_port *)port;
+	unsigned long flags;
+
+	spin_lock_irqsave(&up->port.lock, flags);
+	sio_set(up, TXX9_SIDICR, TXX9_SIDICR_TIE);
+	spin_unlock_irqrestore(&up->port.lock, flags);
+}
+
+static void serial_txx9_stop_rx(struct uart_port *port)
+{
+	struct uart_txx9_port *up = (struct uart_txx9_port *)port;
+	unsigned long flags;
+
+	spin_lock_irqsave(&up->port.lock, flags);
+	up->port.read_status_mask &= ~TXX9_SIDISR_RDIS;
+#if 0
+	sio_mask(up, TXX9_SIDICR, TXX9_SIDICR_RIE);
+#endif
+	spin_unlock_irqrestore(&up->port.lock, flags);
+}
+
+static void serial_txx9_enable_ms(struct uart_port *port)
+{
+	/* TXX9-SIO can not control DTR... */
+}
+
+static inline void
+receive_chars(struct uart_txx9_port *up, unsigned int *status, struct pt_regs *regs)
+{
+	struct tty_struct *tty = up->port.info->tty;
+	unsigned char ch;
+	unsigned int disr = *status;
+	int max_count = 256;
+	char flag;
+
+	do {
+		/* The following is not allowed by the tty layer and
+		   unsafe. It should be fixed ASAP */
+		if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) {
+			if(tty->low_latency)
+				tty_flip_buffer_push(tty);
+			/* If this failed then we will throw away the
+			   bytes but must do so to clear interrupts */
+		}
+		ch = sio_in(up, TXX9_SIRFIFO);
+		flag = TTY_NORMAL;
+		up->port.icount.rx++;
+
+		if (unlikely(disr & (TXX9_SIDISR_UBRK | TXX9_SIDISR_UPER |
+				     TXX9_SIDISR_UFER | TXX9_SIDISR_UOER))) {
+			/*
+			 * For statistics only
+			 */
+			if (disr & TXX9_SIDISR_UBRK) {
+				disr &= ~(TXX9_SIDISR_UFER | TXX9_SIDISR_UPER);
+				up->port.icount.brk++;
+				/*
+				 * We do the SysRQ and SAK checking
+				 * here because otherwise the break
+				 * may get masked by ignore_status_mask
+				 * or read_status_mask.
+				 */
+				if (uart_handle_break(&up->port))
+					goto ignore_char;
+			} else if (disr & TXX9_SIDISR_UPER)
+				up->port.icount.parity++;
+			else if (disr & TXX9_SIDISR_UFER)
+				up->port.icount.frame++;
+			if (disr & TXX9_SIDISR_UOER)
+				up->port.icount.overrun++;
+
+			/*
+			 * Mask off conditions which should be ingored.
+			 */
+			disr &= up->port.read_status_mask;
+
+			if (disr & TXX9_SIDISR_UBRK) {
+				flag = TTY_BREAK;
+			} else if (disr & TXX9_SIDISR_UPER)
+				flag = TTY_PARITY;
+			else if (disr & TXX9_SIDISR_UFER)
+				flag = TTY_FRAME;
+		}
+		if (uart_handle_sysrq_char(&up->port, ch, regs))
+			goto ignore_char;
+		if ((disr & up->port.ignore_status_mask) == 0) {
+			tty_insert_flip_char(tty, ch, flag);
+		}
+		if ((disr & TXX9_SIDISR_UOER) &&
+		    tty->flip.count < TTY_FLIPBUF_SIZE) {
+			/*
+			 * Overrun is special, since it's reported
+			 * immediately, and doesn't affect the current
+			 * character.
+			 */
+			tty_insert_flip_char(tty, 0, TTY_OVERRUN);
+		}
+	ignore_char:
+		disr = sio_in(up, TXX9_SIDISR);
+	} while (!(disr & TXX9_SIDISR_UVALID) && (max_count-- > 0));
+	tty_flip_buffer_push(tty);
+	*status = disr;
+}
+
+static inline void transmit_chars(struct uart_txx9_port *up)
+{
+	struct circ_buf *xmit = &up->port.info->xmit;
+	int count;
+
+	if (up->port.x_char) {
+		sio_out(up, TXX9_SITFIFO, up->port.x_char);
+		up->port.icount.tx++;
+		up->port.x_char = 0;
+		return;
+	}
+	if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) {
+		serial_txx9_stop_tx(&up->port, 0);
+		return;
+	}
+
+	count = TXX9_SIO_TX_FIFO;
+	do {
+		sio_out(up, TXX9_SITFIFO, xmit->buf[xmit->tail]);
+		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+		up->port.icount.tx++;
+		if (uart_circ_empty(xmit))
+			break;
+	} while (--count > 0);
+
+	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+		uart_write_wakeup(&up->port);
+
+	if (uart_circ_empty(xmit))
+		serial_txx9_stop_tx(&up->port, 0);
+}
+
+static irqreturn_t serial_txx9_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	int pass_counter = 0;
+	struct uart_txx9_port *up = dev_id;
+	unsigned int status;
+
+	while (1) {
+		spin_lock(&up->port.lock);
+		status = sio_in(up, TXX9_SIDISR);
+		if (!(sio_in(up, TXX9_SIDICR) & TXX9_SIDICR_TIE))
+			status &= ~TXX9_SIDISR_TDIS;
+		if (!(status & (TXX9_SIDISR_TDIS | TXX9_SIDISR_RDIS |
+				TXX9_SIDISR_TOUT))) {
+			spin_unlock(&up->port.lock);
+			break;
+		}
+
+		if (status & TXX9_SIDISR_RDIS)
+			receive_chars(up, &status, regs);
+		if (status & TXX9_SIDISR_TDIS)
+			transmit_chars(up);
+		/* Clear TX/RX Int. Status */
+		sio_mask(up, TXX9_SIDISR,
+			 TXX9_SIDISR_TDIS | TXX9_SIDISR_RDIS |
+			 TXX9_SIDISR_TOUT);
+		spin_unlock(&up->port.lock);
+
+		if (pass_counter++ > PASS_LIMIT)
+			break;
+	}
+
+	return pass_counter ? IRQ_HANDLED : IRQ_NONE;
+}
+
+static unsigned int serial_txx9_tx_empty(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_SICISR) & TXX9_SICISR_TXALS) ? TIOCSER_TEMT : 0;
+	spin_unlock_irqrestore(&up->port.lock, flags);
+
+	return ret;
+}
+
+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;
+}
+
+static void serial_txx9_set_mctrl(struct uart_port *port, unsigned int mctrl)
+{
+	struct uart_txx9_port *up = (struct uart_txx9_port *)port;
+	unsigned long flags;
+
+	spin_lock_irqsave(&up->port.lock, flags);
+	if (mctrl & TIOCM_RTS)
+		sio_mask(up, TXX9_SIFLCR, TXX9_SIFLCR_RTSSC);
+	else
+		sio_set(up, TXX9_SIFLCR, TXX9_SIFLCR_RTSSC);
+	spin_unlock_irqrestore(&up->port.lock, flags);
+}
+
+static void serial_txx9_break_ctl(struct uart_port *port, int break_state)
+{
+	struct uart_txx9_port *up = (struct uart_txx9_port *)port;
+	unsigned long flags;
+
+	spin_lock_irqsave(&up->port.lock, flags);
+	if (break_state == -1)
+		sio_set(up, TXX9_SIFLCR, TXX9_SIFLCR_TBRK);
+	else
+		sio_mask(up, TXX9_SIFLCR, TXX9_SIFLCR_TBRK);
+	spin_unlock_irqrestore(&up->port.lock, flags);
+}
+
+static int serial_txx9_startup(struct uart_port *port)
+{
+	struct uart_txx9_port *up = (struct uart_txx9_port *)port;
+	unsigned long flags;
+	int retval;
+
+	/*
+	 * Clear the FIFO buffers and disable them.
+	 * (they will be reeanbled in set_termios())
+	 */
+	sio_set(up, TXX9_SIFCR,
+		TXX9_SIFCR_TFRST | TXX9_SIFCR_RFRST | TXX9_SIFCR_FRSTE);
+	/* clear reset */
+	sio_mask(up, TXX9_SIFCR,
+		 TXX9_SIFCR_TFRST | TXX9_SIFCR_RFRST | TXX9_SIFCR_FRSTE);
+	sio_out(up, TXX9_SIDICR, 0);
+
+	/*
+	 * Clear the interrupt registers.
+	 */
+	sio_out(up, TXX9_SIDISR, 0);
+
+	retval = request_irq(up->port.irq, serial_txx9_interrupt,
+			     SA_SHIRQ, "serial_txx9", up);
+	if (retval)
+		return retval;
+
+	/*
+	 * Now, initialize the UART
+	 */
+	spin_lock_irqsave(&up->port.lock, flags);
+	serial_txx9_set_mctrl(&up->port, up->port.mctrl);
+	spin_unlock_irqrestore(&up->port.lock, flags);
+
+	/* Enable RX/TX */
+	sio_mask(up, TXX9_SIFLCR, TXX9_SIFLCR_RSDE | TXX9_SIFLCR_TSDE);
+
+	/*
+	 * Finally, enable interrupts.
+	 */
+	sio_set(up, TXX9_SIDICR, TXX9_SIDICR_RIE);
+
+	return 0;
+}
+
+static void serial_txx9_shutdown(struct uart_port *port)
+{
+	struct uart_txx9_port *up = (struct uart_txx9_port *)port;
+	unsigned long flags;
+
+	/*
+	 * Disable interrupts from this port
+	 */
+	sio_out(up, TXX9_SIDICR, 0);	/* disable all intrs */
+
+	spin_lock_irqsave(&up->port.lock, flags);
+	serial_txx9_set_mctrl(&up->port, up->port.mctrl);
+	spin_unlock_irqrestore(&up->port.lock, flags);
+
+	/*
+	 * Disable break condition
+	 */
+	sio_mask(up, TXX9_SIFLCR, TXX9_SIFLCR_TBRK);
+
+#ifdef CONFIG_SERIAL_TXX9_CONSOLE
+	if (up->port.cons && up->port.line == up->port.cons->index) {
+		free_irq(up->port.irq, up);
+		return;
+	}
+#endif
+	/* reset FIFOs */
+	sio_set(up, TXX9_SIFCR,
+		TXX9_SIFCR_TFRST | TXX9_SIFCR_RFRST | TXX9_SIFCR_FRSTE);
+	/* clear reset */
+	sio_mask(up, TXX9_SIFCR,
+		 TXX9_SIFCR_TFRST | TXX9_SIFCR_RFRST | TXX9_SIFCR_FRSTE);
+
+	/* Disable RX/TX */
+	sio_set(up, TXX9_SIFLCR, TXX9_SIFLCR_RSDE | TXX9_SIFLCR_TSDE);
+
+	free_irq(up->port.irq, up);
+}
+
+static void
+serial_txx9_set_termios(struct uart_port *port, struct termios *termios,
+		       struct termios *old)
+{
+	struct uart_txx9_port *up = (struct uart_txx9_port *)port;
+	unsigned int cval, fcr = 0;
+	unsigned long flags;
+	unsigned int baud, quot;
+
+	cval = sio_in(up, TXX9_SILCR);
+	/* byte size and parity */
+	cval &= ~TXX9_SILCR_UMODE_MASK;
+	switch (termios->c_cflag & CSIZE) {
+	case CS7:
+		cval |= TXX9_SILCR_UMODE_7BIT;
+		break;
+	default:
+	case CS5:	/* not supported */
+	case CS6:	/* not supported */
+	case CS8:
+		cval |= TXX9_SILCR_UMODE_8BIT;
+		break;
+	}
+
+	cval &= ~TXX9_SILCR_USBL_MASK;
+	if (termios->c_cflag & CSTOPB)
+		cval |= TXX9_SILCR_USBL_2BIT;
+	else
+		cval |= TXX9_SILCR_USBL_1BIT;
+	cval &= ~(TXX9_SILCR_UPEN | TXX9_SILCR_UEPS);
+	if (termios->c_cflag & PARENB)
+		cval |= TXX9_SILCR_UPEN;
+	if (!(termios->c_cflag & PARODD))
+		cval |= TXX9_SILCR_UEPS;
+
+	/*
+	 * Ask the core to calculate the divisor for us.
+	 */
+	baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16/2);
+	quot = uart_get_divisor(port, baud);
+
+	/* Set up FIFOs */
+	/* TX Int by FIFO Empty, RX Int by Receiving 1 char. */
+	fcr = TXX9_SIFCR_TDIL_MAX | TXX9_SIFCR_RDIL_1;
+
+	/*
+	 * Ok, we're now changing the port state.  Do it with
+	 * interrupts disabled.
+	 */
+	spin_lock_irqsave(&up->port.lock, flags);
+
+	/*
+	 * Update the per-port timeout.
+	 */
+	uart_update_timeout(port, termios->c_cflag, baud);
+
+	up->port.read_status_mask = TXX9_SIDISR_UOER |
+		TXX9_SIDISR_TDIS | TXX9_SIDISR_RDIS;
+	if (termios->c_iflag & INPCK)
+		up->port.read_status_mask |= TXX9_SIDISR_UFER | TXX9_SIDISR_UPER;
+	if (termios->c_iflag & (BRKINT | PARMRK))
+		up->port.read_status_mask |= TXX9_SIDISR_UBRK;
+
+	/*
+	 * Characteres to ignore
+	 */
+	up->port.ignore_status_mask = 0;
+	if (termios->c_iflag & IGNPAR)
+		up->port.ignore_status_mask |= TXX9_SIDISR_UPER | TXX9_SIDISR_UFER;
+	if (termios->c_iflag & IGNBRK) {
+		up->port.ignore_status_mask |= TXX9_SIDISR_UBRK;
+		/*
+		 * If we're ignoring parity and break indicators,
+		 * ignore overruns too (for real raw support).
+		 */
+		if (termios->c_iflag & IGNPAR)
+			up->port.ignore_status_mask |= TXX9_SIDISR_UOER;
+	}
+
+	/*
+	 * ignore all characters if CREAD is not set
+	 */
+	if ((termios->c_cflag & CREAD) == 0)
+		up->port.ignore_status_mask |= TXX9_SIDISR_RDIS;
+
+	/* CTS flow control flag */
+	if ((termios->c_cflag & CRTSCTS) &&
+	    (up->port.flags & UPF_TXX9_HAVE_CTS_LINE)) {
+		sio_set(up, TXX9_SIFLCR,
+			TXX9_SIFLCR_RCS | TXX9_SIFLCR_TES);
+	} else {
+		sio_mask(up, TXX9_SIFLCR,
+			 TXX9_SIFLCR_RCS | TXX9_SIFLCR_TES);
+	}
+
+	sio_out(up, TXX9_SILCR, cval);
+	sio_quot_set(up, quot);
+	sio_out(up, TXX9_SIFCR, fcr);
+
+	serial_txx9_set_mctrl(&up->port, up->port.mctrl);
+	spin_unlock_irqrestore(&up->port.lock, flags);
+}
+
+static void
+serial_txx9_pm(struct uart_port *port, unsigned int state,
+	      unsigned int oldstate)
+{
+	struct uart_txx9_port *up = (struct uart_txx9_port *)port;
+	if (state) {
+		/* sleep */
+
+		if (up->pm)
+			up->pm(port, state, oldstate);
+	} else {
+		/* wake */
+
+		if (up->pm)
+			up->pm(port, state, oldstate);
+	}
+}
+
+static int serial_txx9_request_resource(struct uart_txx9_port *up)
+{
+	unsigned int size = TXX9_REGION_SIZE;
+	int ret = 0;
+
+	switch (up->port.iotype) {
+	default:
+		if (!up->port.mapbase)
+			break;
+
+		if (!request_mem_region(up->port.mapbase, size, "serial_txx9")) {
+			ret = -EBUSY;
+			break;
+		}
+
+		if (up->port.flags & UPF_IOREMAP) {
+			up->port.membase = ioremap(up->port.mapbase, size);
+			if (!up->port.membase) {
+				release_mem_region(up->port.mapbase, size);
+				ret = -ENOMEM;
+			}
+		}
+		break;
+
+	case UPIO_PORT:
+		if (!request_region(up->port.iobase, size, "serial_txx9"))
+			ret = -EBUSY;
+		break;
+	}
+	return ret;
+}
+
+static void serial_txx9_release_resource(struct uart_txx9_port *up)
+{
+	unsigned int size = TXX9_REGION_SIZE;
+
+	switch (up->port.iotype) {
+	default:
+		if (!up->port.mapbase)
+			break;
+
+		if (up->port.flags & UPF_IOREMAP) {
+			iounmap(up->port.membase);
+			up->port.membase = NULL;
+		}
+
+		release_mem_region(up->port.mapbase, size);
+		break;
+
+	case UPIO_PORT:
+		release_region(up->port.iobase, size);
+		break;
+	}
+}
+
+static void serial_txx9_release_port(struct uart_port *port)
+{
+	struct uart_txx9_port *up = (struct uart_txx9_port *)port;
+	serial_txx9_release_resource(up);
+}
+
+static int serial_txx9_request_port(struct uart_port *port)
+{
+	struct uart_txx9_port *up = (struct uart_txx9_port *)port;
+	return serial_txx9_request_resource(up);
+}
+
+static void serial_txx9_config_port(struct uart_port *port, int uflags)
+{
+	struct uart_txx9_port *up = (struct uart_txx9_port *)port;
+	unsigned long flags;
+	int ret;
+
+	/*
+	 * Find the region that we can probe for.  This in turn
+	 * tells us whether we can probe for the type of port.
+	 */
+	ret = serial_txx9_request_resource(up);
+	if (ret < 0)
+		return;
+	port->type = PORT_TXX9;
+	up->port.fifosize = TXX9_SIO_TX_FIFO;
+
+#ifdef CONFIG_SERIAL_TXX9_CONSOLE
+	if (up->port.line == up->port.cons->index)
+		return;
+#endif
+	spin_lock_irqsave(&up->port.lock, flags);
+	/*
+	 * Reset the UART.
+	 */
+	sio_out(up, TXX9_SIFCR, TXX9_SIFCR_SWRST);
+#ifdef CONFIG_CPU_TX49XX
+	/* TX4925 BUG WORKAROUND.  Accessing SIOC register
+	 * immediately after soft reset causes bus error. */
+	iob();
+	udelay(1);
+#endif
+	while (sio_in(up, TXX9_SIFCR) & TXX9_SIFCR_SWRST)
+		;
+	/* TX Int by FIFO Empty, RX Int by Receiving 1 char. */
+	sio_set(up, TXX9_SIFCR,
+		TXX9_SIFCR_TDIL_MAX | TXX9_SIFCR_RDIL_1);
+	/* initial settings */
+	sio_out(up, TXX9_SILCR,
+		TXX9_SILCR_UMODE_8BIT | TXX9_SILCR_USBL_1BIT |
+		((up->port.flags & UPF_TXX9_USE_SCLK) ?
+		 TXX9_SILCR_SCS_SCLK_BG : TXX9_SILCR_SCS_IMCLK_BG));
+	sio_quot_set(up, uart_get_divisor(port, 9600));
+	sio_out(up, TXX9_SIFLCR, TXX9_SIFLCR_RTSTL_MAX /* 15 */);
+	spin_unlock_irqrestore(&up->port.lock, flags);
+}
+
+static int
+serial_txx9_verify_port(struct uart_port *port, struct serial_struct *ser)
+{
+	if (ser->irq < 0 ||
+	    ser->baud_base < 9600 || ser->type != PORT_TXX9)
+		return -EINVAL;
+	return 0;
+}
+
+static const char *
+serial_txx9_type(struct uart_port *port)
+{
+	return "txx9";
+}
+
+static struct uart_ops serial_txx9_pops = {
+	.tx_empty	= serial_txx9_tx_empty,
+	.set_mctrl	= serial_txx9_set_mctrl,
+	.get_mctrl	= serial_txx9_get_mctrl,
+	.stop_tx	= serial_txx9_stop_tx,
+	.start_tx	= serial_txx9_start_tx,
+	.stop_rx	= serial_txx9_stop_rx,
+	.enable_ms	= serial_txx9_enable_ms,
+	.break_ctl	= serial_txx9_break_ctl,
+	.startup	= serial_txx9_startup,
+	.shutdown	= serial_txx9_shutdown,
+	.set_termios	= serial_txx9_set_termios,
+	.pm		= serial_txx9_pm,
+	.type		= serial_txx9_type,
+	.release_port	= serial_txx9_release_port,
+	.request_port	= serial_txx9_request_port,
+	.config_port	= serial_txx9_config_port,
+	.verify_port	= serial_txx9_verify_port,
+};
+
+static struct uart_txx9_port serial_txx9_ports[UART_NR];
+
+static void __init serial_txx9_register_ports(struct uart_driver *drv)
+{
+	int i;
+
+	for (i = 0; i < UART_NR; i++) {
+		struct uart_txx9_port *up = &serial_txx9_ports[i];
+
+		up->port.line = i;
+		up->port.ops = &serial_txx9_pops;
+		uart_add_one_port(drv, &up->port);
+	}
+}
+
+#ifdef CONFIG_SERIAL_TXX9_CONSOLE
+
+/*
+ *	Wait for transmitter & holding register to empty
+ */
+static inline void wait_for_xmitr(struct uart_txx9_port *up)
+{
+	unsigned int tmout = 10000;
+
+	/* Wait up to 10ms for the character(s) to be sent. */
+	while (--tmout &&
+	       !(sio_in(up, TXX9_SICISR) & TXX9_SICISR_TXALS))
+		udelay(1);
+
+	/* Wait up to 1s for flow control if necessary */
+	if (up->port.flags & UPF_CONS_FLOW) {
+		tmout = 1000000;
+		while (--tmout &&
+		       (sio_in(up, TXX9_SICISR) & TXX9_SICISR_CTSS))
+			udelay(1);
+	}
+}
+
+/*
+ *	Print a string to the serial port trying not to disturb
+ *	any possible real use of the port...
+ *
+ *	The console_lock must be held when we get here.
+ */
+static void
+serial_txx9_console_write(struct console *co, const char *s, unsigned int count)
+{
+	struct uart_txx9_port *up = &serial_txx9_ports[co->index];
+	unsigned int ier, flcr;
+	int i;
+
+	/*
+	 *	First save the UER then disable the interrupts
+	 */
+	ier = sio_in(up, TXX9_SIDICR);
+	sio_out(up, TXX9_SIDICR, 0);
+	/*
+	 *	Disable flow-control if enabled (and unnecessary)
+	 */
+	flcr = sio_in(up, TXX9_SIFLCR);
+	if (!(up->port.flags & UPF_CONS_FLOW) && (flcr & TXX9_SIFLCR_TES))
+		sio_out(up, TXX9_SIFLCR, flcr & ~TXX9_SIFLCR_TES);
+
+	/*
+	 *	Now, do each character
+	 */
+	for (i = 0; i < count; i++, s++) {
+		wait_for_xmitr(up);
+
+		/*
+		 *	Send the character out.
+		 *	If a LF, also do CR...
+		 */
+		sio_out(up, TXX9_SITFIFO, *s);
+		if (*s == 10) {
+			wait_for_xmitr(up);
+			sio_out(up, TXX9_SITFIFO, 13);
+		}
+	}
+
+	/*
+	 *	Finally, wait for transmitter to become empty
+	 *	and restore the IER
+	 */
+	wait_for_xmitr(up);
+	sio_out(up, TXX9_SIFLCR, flcr);
+	sio_out(up, TXX9_SIDICR, ier);
+}
+
+static int serial_txx9_console_setup(struct console *co, char *options)
+{
+	struct uart_port *port;
+	struct uart_txx9_port *up;
+	int baud = 9600;
+	int bits = 8;
+	int parity = 'n';
+	int flow = 'n';
+
+	/*
+	 * Check whether an invalid uart number has been specified, and
+	 * if so, search for the first available port that does have
+	 * console support.
+	 */
+	if (co->index >= UART_NR)
+		co->index = 0;
+	up = &serial_txx9_ports[co->index];
+	port = &up->port;
+	if (!port->ops)
+		return -ENODEV;
+
+	/*
+	 * Temporary fix.
+	 */
+	spin_lock_init(&port->lock);
+
+	/*
+	 *	Disable UART interrupts, set DTR and RTS high
+	 *	and set speed.
+	 */
+	sio_out(up, TXX9_SIDICR, 0);
+	/* initial settings */
+	sio_out(up, TXX9_SILCR,
+		TXX9_SILCR_UMODE_8BIT | TXX9_SILCR_USBL_1BIT |
+		((port->flags & UPF_TXX9_USE_SCLK) ?
+		 TXX9_SILCR_SCS_SCLK_BG : TXX9_SILCR_SCS_IMCLK_BG));
+	sio_out(up, TXX9_SIFLCR, TXX9_SIFLCR_RTSTL_MAX /* 15 */);
+
+	if (options)
+		uart_parse_options(options, &baud, &parity, &bits, &flow);
+
+	return uart_set_options(port, co, baud, parity, bits, flow);
+}
+
+static struct uart_driver serial_txx9_reg;
+static struct console serial_txx9_console = {
+	.name		= TXX9_TTY_NAME,
+	.write		= serial_txx9_console_write,
+	.device		= uart_console_device,
+	.setup		= serial_txx9_console_setup,
+	.flags		= CON_PRINTBUFFER,
+	.index		= -1,
+	.data		= &serial_txx9_reg,
+};
+
+static int __init serial_txx9_console_init(void)
+{
+	register_console(&serial_txx9_console);
+	return 0;
+}
+console_initcall(serial_txx9_console_init);
+
+static int __init serial_txx9_late_console_init(void)
+{
+	if (!(serial_txx9_console.flags & CON_ENABLED))
+		register_console(&serial_txx9_console);
+	return 0;
+}
+late_initcall(serial_txx9_late_console_init);
+
+#define SERIAL_TXX9_CONSOLE	&serial_txx9_console
+#else
+#define SERIAL_TXX9_CONSOLE	NULL
+#endif
+
+static struct uart_driver serial_txx9_reg = {
+	.owner			= THIS_MODULE,
+	.driver_name		= "serial_txx9",
+	.devfs_name		= TXX9_TTY_DEVFS_NAME,
+	.dev_name		= TXX9_TTY_NAME,
+	.major			= TXX9_TTY_MAJOR,
+	.minor			= TXX9_TTY_MINOR_START,
+	.nr			= UART_NR,
+	.cons			= SERIAL_TXX9_CONSOLE,
+};
+
+int __init early_serial_txx9_setup(struct uart_port *port)
+{
+	if (port->line >= ARRAY_SIZE(serial_txx9_ports))
+		return -ENODEV;
+
+	serial_txx9_ports[port->line].port = *port;
+	serial_txx9_ports[port->line].port.ops = &serial_txx9_pops;
+	serial_txx9_ports[port->line].port.flags |= UPF_BOOT_AUTOCONF;
+	return 0;
+}
+
+#ifdef ENABLE_SERIAL_TXX9_PCI
+/**
+ *	serial_txx9_suspend_port - suspend one serial port
+ *	@line:  serial line number
+ *      @level: the level of port suspension, as per uart_suspend_port
+ *
+ *	Suspend one serial port.
+ */
+static void serial_txx9_suspend_port(int line)
+{
+	uart_suspend_port(&serial_txx9_reg, &serial_txx9_ports[line].port);
+}
+
+/**
+ *	serial_txx9_resume_port - resume one serial port
+ *	@line:  serial line number
+ *      @level: the level of port resumption, as per uart_resume_port
+ *
+ *	Resume one serial port.
+ */
+static void serial_txx9_resume_port(int line)
+{
+	uart_resume_port(&serial_txx9_reg, &serial_txx9_ports[line].port);
+}
+
+/*
+ * Probe one serial board.  Unfortunately, there is no rhyme nor reason
+ * to the arrangement of serial ports on a PCI card.
+ */
+static int __devinit
+pciserial_txx9_init_one(struct pci_dev *dev, const struct pci_device_id *ent)
+{
+	struct uart_port port;
+	int line;
+	int rc;
+
+	rc = pci_enable_device(dev);
+	if (rc)
+		return rc;
+
+	memset(&port, 0, sizeof(port));
+	port.ops = &serial_txx9_pops;
+	port.flags |= UPF_BOOT_AUTOCONF; /* uart_ops.config_port will be called */
+	port.flags |= UPF_TXX9_HAVE_CTS_LINE;
+	port.uartclk = 66670000;
+	port.irq = dev->irq;
+	port.iotype = UPIO_PORT;
+	port.iobase = pci_resource_start(dev, 1);
+	line = uart_register_port(&serial_txx9_reg, &port);
+	if (line < 0) {
+		printk(KERN_WARNING "Couldn't register serial port %s: %d\n", pci_name(dev), line);
+	}
+	pci_set_drvdata(dev, (void *)(long)line);
+
+	return 0;
+}
+
+static void __devexit pciserial_txx9_remove_one(struct pci_dev *dev)
+{
+	int line = (int)(long)pci_get_drvdata(dev);
+
+	pci_set_drvdata(dev, NULL);
+
+	if (line) {
+		uart_unregister_port(&serial_txx9_reg, line);
+		pci_disable_device(dev);
+	}
+}
+
+static int pciserial_txx9_suspend_one(struct pci_dev *dev, u32 state)
+{
+	int line = (int)(long)pci_get_drvdata(dev);
+
+	if (line)
+		serial_txx9_suspend_port(line);
+	return 0;
+}
+
+static int pciserial_txx9_resume_one(struct pci_dev *dev)
+{
+	int line = (int)(long)pci_get_drvdata(dev);
+
+	if (line)
+		serial_txx9_resume_port(line);
+	return 0;
+}
+
+static struct pci_device_id serial_txx9_pci_tbl[] = {
+	{	PCI_VENDOR_ID_TOSHIBA_2, PCI_DEVICE_ID_TOSHIBA_TC86C001_MISC,
+		PCI_ANY_ID, PCI_ANY_ID,
+		0, 0, 0 },
+	{ 0, }
+};
+
+static struct pci_driver serial_txx9_pci_driver = {
+	.name		= "serial_txx9",
+	.probe		= pciserial_txx9_init_one,
+	.remove		= __devexit_p(pciserial_txx9_remove_one),
+	.suspend	= pciserial_txx9_suspend_one,
+	.resume		= pciserial_txx9_resume_one,
+	.id_table	= serial_txx9_pci_tbl,
+};
+
+MODULE_DEVICE_TABLE(pci, serial_txx9_pci_tbl);
+#endif /* ENABLE_SERIAL_TXX9_PCI */
+
+static int __init serial_txx9_init(void)
+{
+	int ret;
+
+ 	printk(KERN_INFO "%s version %s\n", serial_name, serial_version);
+
+	ret = uart_register_driver(&serial_txx9_reg);
+	if (ret >= 0) {
+		serial_txx9_register_ports(&serial_txx9_reg);
+
+#ifdef ENABLE_SERIAL_TXX9_PCI
+		ret = pci_module_init(&serial_txx9_pci_driver);
+#endif
+	}
+	return ret;
+}
+
+static void __exit serial_txx9_exit(void)
+{
+	int i;
+
+#ifdef ENABLE_SERIAL_TXX9_PCI
+	pci_unregister_driver(&serial_txx9_pci_driver);
+#endif
+	for (i = 0; i < UART_NR; i++)
+		uart_remove_one_port(&serial_txx9_reg, &serial_txx9_ports[i].port);
+
+	uart_unregister_driver(&serial_txx9_reg);
+}
+
+module_init(serial_txx9_init);
+module_exit(serial_txx9_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("TX39/49 serial driver");
+
+MODULE_ALIAS_CHARDEV_MAJOR(TXX9_TTY_MAJOR);
diff -Nru a/drivers/serial/sn_console.c b/drivers/serial/sn_console.c
--- a/drivers/serial/sn_console.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/serial/sn_console.c	2005-03-01 23:38:56 -08:00
@@ -853,7 +853,7 @@
 		return -ENODEV;
 	}
 
-	sal_console_port.sc_port.lock = SPIN_LOCK_UNLOCKED;
+	spin_lock_init(&sal_console_port.sc_port.lock);
 
 	/* Setup the port struct with the minimum needed */
 	sal_console_port.sc_port.membase = (char *)1;	/* just needs to be non-zero */
diff -Nru a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c
--- a/drivers/serial/sunsu.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/serial/sunsu.c	2005-03-01 23:38:53 -08:00
@@ -989,7 +989,7 @@
 
 #ifdef CONFIG_SERIO
 
-static spinlock_t sunsu_serio_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(sunsu_serio_lock);
 
 static int sunsu_serio_write(struct serio *serio, unsigned char ch)
 {
@@ -1285,7 +1285,9 @@
 
 static int __init sunsu_kbd_ms_init(struct uart_sunsu_port *up, int channel)
 {
+#ifdef CONFIG_SERIO
 	struct serio *serio;
+#endif
 
 	up->port.line = channel;
 	up->port.type = PORT_UNKNOWN;
diff -Nru a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c
--- a/drivers/serial/sunzilog.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/serial/sunzilog.c	2005-03-01 23:39:17 -08:00
@@ -1293,7 +1293,7 @@
 
 #ifdef CONFIG_SERIO
 
-static spinlock_t sunzilog_serio_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(sunzilog_serio_lock);
 
 static int sunzilog_serio_write(struct serio *serio, unsigned char ch)
 {
diff -Nru a/drivers/tc/lk201.c b/drivers/tc/lk201.c
--- a/drivers/tc/lk201.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/tc/lk201.c	2005-03-01 23:39:17 -08:00
@@ -4,20 +4,44 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
+ * Copyright (C) 1999-2002 Harald Koerfgen <hkoerfg@web.de>
+ * Copyright (C) 2001, 2002, 2003, 2004  Maciej W. Rozycki
  */
+
+#include <linux/config.h>
+
 #include <linux/errno.h>
+#include <linux/sched.h>
 #include <linux/tty.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/kbd_ll.h>
-#include <asm/wbflush.h>
+#include <linux/kbd_kern.h>
+#include <linux/vt_kern.h>
+
+#include <asm/keyboard.h>
 #include <asm/dec/tc.h>
 #include <asm/dec/machtype.h>
+#include <asm/dec/serial.h>
 
-#include "zs.h"
 #include "lk201.h"
 
+/*
+ * Only handle DECstations that have an LK201 interface.
+ * Maxine uses LK501 at the Access.Bus and various DECsystems
+ * have no keyboard interface at all.
+ */
+#define LK_IFACE	(mips_machtype == MACH_DS23100    || \
+			 mips_machtype == MACH_DS5000_200 || \
+			 mips_machtype == MACH_DS5000_1XX || \
+			 mips_machtype == MACH_DS5000_2X0)
+/*
+ * These use the Z8530 SCC.  Others use the DZ11.
+ */
+#define LK_IFACE_ZS	(mips_machtype == MACH_DS5000_1XX || \
+			 mips_machtype == MACH_DS5000_2X0)
+
 /* Simple translation table for the SysRq keys */
 
 #ifdef CONFIG_MAGIC_SYSRQ
@@ -27,25 +51,29 @@
  */
 unsigned char lk201_sysrq_xlate[128];
 unsigned char *kbd_sysrq_xlate = lk201_sysrq_xlate;
+
+unsigned char kbd_sysrq_key = -1;
 #endif
 
 #define KEYB_LINE	3
 
-static int __init lk201_init(struct dec_serial *);
-static void __init lk201_info(struct dec_serial *);
-static void lk201_kbd_rx_char(unsigned char, unsigned char);
-
-struct zs_hook lk201_kbdhook = {
-	.init_channel   = lk201_init,
-	.init_info      = lk201_info,
-	.cflags         = B4800 | CS8 | CSTOPB | CLOCAL
+static int __init lk201_init(void *);
+static void __init lk201_info(void *);
+static void lk201_rx_char(unsigned char, unsigned char);
+
+static struct dec_serial_hook lk201_hook = {
+	.init_channel	= lk201_init,
+	.init_info	= lk201_info,
+	.rx_char	= NULL,
+	.poll_rx_char	= NULL,
+	.poll_tx_char	= NULL,
+	.cflags		= B4800 | CS8 | CSTOPB | CLOCAL,
 };
 
 /*
  * This is used during keyboard initialisation
  */
 static unsigned char lk201_reset_string[] = {
-	LK_CMD_LEDS_ON, LK_PARAM_LED_MASK(0xf),	/* show we are resetting */
 	LK_CMD_SET_DEFAULTS,
 	LK_CMD_MODE(LK_MODE_RPT_DOWN, 1),
 	LK_CMD_MODE(LK_MODE_RPT_DOWN, 2),
@@ -61,28 +89,199 @@
 	LK_CMD_MODE(LK_MODE_RPT_DOWN, 12),
 	LK_CMD_MODE(LK_MODE_DOWN, 13),
 	LK_CMD_MODE(LK_MODE_RPT_DOWN, 14),
-	LK_CMD_ENB_RPT,
 	LK_CMD_DIS_KEYCLK,
-	LK_CMD_RESUME,
 	LK_CMD_ENB_BELL, LK_PARAM_VOLUME(4),
-	LK_CMD_LEDS_OFF, LK_PARAM_LED_MASK(0xf)
 };
 
-static int __init lk201_reset(struct dec_serial *info)
+static void *lk201_handle;
+
+static int lk201_send(unsigned char ch)
+{
+	if (lk201_hook.poll_tx_char(lk201_handle, ch)) {
+		printk(KERN_ERR "lk201: transmit timeout\n");
+		return -EIO;
+	}
+	return 0;
+}
+
+static inline int lk201_get_id(void)
+{
+	return lk201_send(LK_CMD_REQ_ID);
+}
+
+static int lk201_reset(void)
+{
+	int i, r;
+
+	for (i = 0; i < sizeof(lk201_reset_string); i++) {
+		r = lk201_send(lk201_reset_string[i]);
+		if (r < 0)
+			return r;
+	}
+	return 0;
+}
+
+static void lk201_report(unsigned char id[6])
+{
+	char *report = "lk201: keyboard attached, ";
+
+	switch (id[2]) {
+	case LK_STAT_PWRUP_OK:
+		printk(KERN_INFO "%sself-test OK\n", report);
+		break;
+	case LK_STAT_PWRUP_KDOWN:
+		/* The keyboard will resend the power-up ID
+		   after all keys are released, so we don't
+		   bother handling the error specially.  Still
+		   there may be a short-circuit inside.
+		 */
+		printk(KERN_ERR "%skey down (stuck?), code: 0x%02x\n",
+		       report, id[3]);
+		break;
+	case LK_STAT_PWRUP_ERROR:
+		printk(KERN_ERR "%sself-test failure\n", report);
+		break;
+	default:
+		printk(KERN_ERR "%sunknown error: 0x%02x\n",
+		       report, id[2]);
+	}
+}
+
+static void lk201_id(unsigned char id[6])
+{
+	/*
+	 * Report whether there is an LK201 or an LK401
+	 * The LK401 has ALT keys...
+	 */
+	switch (id[4]) {
+	case 1:
+		printk(KERN_INFO "lk201: LK201 detected\n");
+		break;
+	case 2:
+		printk(KERN_INFO "lk201: LK401 detected\n");
+		break;
+	case 3:
+		printk(KERN_INFO "lk201: LK443 detected\n");
+		break;
+	case 4:
+		printk(KERN_INFO "lk201: LK421 detected\n");
+		break;
+	default:
+		printk(KERN_WARNING
+		       "lk201: unknown keyboard detected, ID %d\n", id[4]);
+		printk(KERN_WARNING "lk201: ... please report to "
+		       "<linux-mips@linux-mips.org>\n");
+	}
+}
+
+#define DEFAULT_KEYB_REP_DELAY	(250/5)	/* [5ms] */
+#define DEFAULT_KEYB_REP_RATE	30	/* [cps] */
+
+static struct kbd_repeat kbdrate = {
+	DEFAULT_KEYB_REP_DELAY,
+	DEFAULT_KEYB_REP_RATE
+};
+
+static void parse_kbd_rate(struct kbd_repeat *r)
 {
+	if (r->delay <= 0)
+		r->delay = kbdrate.delay;
+	if (r->rate <= 0)
+		r->rate = kbdrate.rate;
+
+	if (r->delay < 5)
+		r->delay = 5;
+	if (r->delay > 630)
+		r->delay = 630;
+	if (r->rate < 12)
+		r->rate = 12;
+	if (r->rate > 127)
+		r->rate = 127;
+	if (r->rate == 125)
+		r->rate = 124;
+}
+
+static int write_kbd_rate(struct kbd_repeat *rep)
+{
+	int delay, rate;
 	int i;
 
-	for (i = 0; i < sizeof(lk201_reset_string); i++)
-		if (info->hook->poll_tx_char(info, lk201_reset_string[i])) {
-			printk("%s transmit timeout\n", __FUNCTION__);
-			return -EIO;
-		}
+	delay = rep->delay / 5;
+	rate = rep->rate;
+	for (i = 0; i < 4; i++) {
+		if (lk201_hook.poll_tx_char(lk201_handle,
+					    LK_CMD_RPT_RATE(i)))
+			return 1;
+		if (lk201_hook.poll_tx_char(lk201_handle,
+					    LK_PARAM_DELAY(delay)))
+			return 1;
+		if (lk201_hook.poll_tx_char(lk201_handle,
+					    LK_PARAM_RATE(rate)))
+			return 1;
+	}
 	return 0;
 }
 
+static int lk201_kbd_rate(struct kbd_repeat *rep)
+{
+	if (rep == NULL)
+		return -EINVAL;
+
+	parse_kbd_rate(rep);
+
+	if (write_kbd_rate(rep)) {
+		memcpy(rep, &kbdrate, sizeof(struct kbd_repeat));
+		return -EIO;
+	}
+
+	memcpy(&kbdrate, rep, sizeof(struct kbd_repeat));
+
+	return 0;
+}
+
+static void lk201_kd_mksound(unsigned int hz, unsigned int ticks)
+{
+	if (!ticks)
+		return;
+
+	/*
+	 * Can't set frequency and we "approximate"
+	 * duration by volume. ;-)
+	 */
+	ticks /= HZ / 32;
+	if (ticks > 7)
+		ticks = 7;
+	ticks = 7 - ticks;
+
+	if (lk201_hook.poll_tx_char(lk201_handle, LK_CMD_ENB_BELL))
+		return;
+	if (lk201_hook.poll_tx_char(lk201_handle, LK_PARAM_VOLUME(ticks)))
+		return;
+	if (lk201_hook.poll_tx_char(lk201_handle, LK_CMD_BELL))
+		return;
+}
+
 void kbd_leds(unsigned char leds)
 {
-	return;
+	unsigned char l = 0;
+
+	if (!lk201_handle)		/* FIXME */
+		return;
+
+	/* FIXME -- Only Hold and Lock LEDs for now. --macro */
+	if (leds & LED_SCR)
+		l |= LK_LED_HOLD;
+	if (leds & LED_CAP)
+		l |= LK_LED_LOCK;
+
+	if (lk201_hook.poll_tx_char(lk201_handle, LK_CMD_LEDS_ON))
+		return;
+	if (lk201_hook.poll_tx_char(lk201_handle, LK_PARAM_LED_MASK(l)))
+		return;
+	if (lk201_hook.poll_tx_char(lk201_handle, LK_CMD_LEDS_OFF))
+		return;
+	if (lk201_hook.poll_tx_char(lk201_handle, LK_PARAM_LED_MASK(~l)))
+		return;
 }
 
 int kbd_setkeycode(unsigned int scancode, unsigned int keycode)
@@ -107,128 +306,136 @@
 	return 0x80;
 }
 
-static void lk201_kbd_rx_char(unsigned char ch, unsigned char stat)
+static void lk201_rx_char(unsigned char ch, unsigned char fl)
 {
+	static unsigned char id[6];
+	static int id_i;
+
 	static int shift_state = 0;
 	static int prev_scancode;
 	unsigned char c = scancodeRemap[ch];
 
-	if (!stat || stat == 4) {
-		switch (ch) {
-		case LK_KEY_ACK:
-			break;
-		case LK_KEY_LOCK:
-			shift_state ^= LK_LOCK;
-			handle_scancode(c, shift_state && LK_LOCK ? 1 : 0);
-			break;
-		case LK_KEY_SHIFT:
-			shift_state ^= LK_SHIFT;
-			handle_scancode(c, shift_state && LK_SHIFT ? 1 : 0);
-			break;
-		case LK_KEY_CTRL:
-			shift_state ^= LK_CTRL;
-			handle_scancode(c, shift_state && LK_CTRL ? 1 : 0);
-			break;
-		case LK_KEY_COMP:
-			shift_state ^= LK_COMP;
-			handle_scancode(c, shift_state && LK_COMP ? 1 : 0);
-			break;
-		case LK_KEY_RELEASE:
-			if (shift_state & LK_SHIFT)
-				handle_scancode(scancodeRemap[LK_KEY_SHIFT], 0);
-			if (shift_state & LK_CTRL)
-				handle_scancode(scancodeRemap[LK_KEY_CTRL], 0);
-			if (shift_state & LK_COMP)
-				handle_scancode(scancodeRemap[LK_KEY_COMP], 0);
-			if (shift_state & LK_LOCK)
-				handle_scancode(scancodeRemap[LK_KEY_LOCK], 0);
-			shift_state = 0;
-			break;
-		case LK_KEY_REPEAT:
-			handle_scancode(prev_scancode, 1);
-			break;
-		default:
-			prev_scancode = c;
-			handle_scancode(c, 1);
-			break;
+	if (fl != TTY_NORMAL && fl != TTY_OVERRUN) {
+		printk(KERN_ERR "lk201: keyboard receive error: 0x%02x\n", fl);
+		return;
+	}
+
+	/* Assume this is a power-up ID. */
+	if (ch == LK_STAT_PWRUP_ID && !id_i) {
+		id[id_i++] = ch;
+		return;
+	}
+
+	/* Handle the power-up sequence. */
+	if (id_i) {
+		id[id_i++] = ch;
+		if (id_i == 4) {
+			/* OK, the power-up concluded. */
+			lk201_report(id);
+			if (id[2] == LK_STAT_PWRUP_OK)
+				lk201_get_id();
+			else {
+				id_i = 0;
+				printk(KERN_ERR "lk201: keyboard power-up "
+				       "error, skipping initialization\n");
+			}
+		} else if (id_i == 6) {
+			/* We got the ID; report it and start operation. */
+			id_i = 0;
+			lk201_id(id);
+			lk201_reset();
 		}
-	} else
-		printk("Error reading LKx01 keyboard: 0x%02x\n", stat);
+		return;
+	}
+
+	/* Everything else is a scancode/status response. */
+	id_i = 0;
+	switch (ch) {
+	case LK_STAT_RESUME_ERR:
+	case LK_STAT_ERROR:
+	case LK_STAT_INHIBIT_ACK:
+	case LK_STAT_TEST_ACK:
+	case LK_STAT_MODE_KEYDOWN:
+	case LK_STAT_MODE_ACK:
+		break;
+	case LK_KEY_LOCK:
+		shift_state ^= LK_LOCK;
+		handle_scancode(c, (shift_state & LK_LOCK) ? 1 : 0);
+		break;
+	case LK_KEY_SHIFT:
+		shift_state ^= LK_SHIFT;
+		handle_scancode(c, (shift_state & LK_SHIFT) ? 1 : 0);
+		break;
+	case LK_KEY_CTRL:
+		shift_state ^= LK_CTRL;
+		handle_scancode(c, (shift_state & LK_CTRL) ? 1 : 0);
+		break;
+	case LK_KEY_COMP:
+		shift_state ^= LK_COMP;
+		handle_scancode(c, (shift_state & LK_COMP) ? 1 : 0);
+		break;
+	case LK_KEY_RELEASE:
+		if (shift_state & LK_SHIFT)
+			handle_scancode(scancodeRemap[LK_KEY_SHIFT], 0);
+		if (shift_state & LK_CTRL)
+			handle_scancode(scancodeRemap[LK_KEY_CTRL], 0);
+		if (shift_state & LK_COMP)
+			handle_scancode(scancodeRemap[LK_KEY_COMP], 0);
+		if (shift_state & LK_LOCK)
+			handle_scancode(scancodeRemap[LK_KEY_LOCK], 0);
+		shift_state = 0;
+		break;
+	case LK_KEY_REPEAT:
+		handle_scancode(prev_scancode, 1);
+		break;
+	default:
+		prev_scancode = c;
+		handle_scancode(c, 1);
+		break;
+	}
+	tasklet_schedule(&keyboard_tasklet);
 }
 
-static void __init lk201_info(struct dec_serial *info)
+static void __init lk201_info(void *handle)
 {
 }
 
-static int __init lk201_init(struct dec_serial *info)
+static int __init lk201_init(void *handle)
 {
-	unsigned int ch, id = 0;
-	int result;
-
-	printk("DECstation LK keyboard driver v0.04... ");
+	/* First install handlers. */
+	lk201_handle = handle;
+	kbd_rate = lk201_kbd_rate;
+	kd_mksound = lk201_kd_mksound;
 
-	result = lk201_reset(info);
-	if (result)
-		return result;
-	mdelay(10);
-
-	/*
-	 * Detect whether there is an LK201 or an LK401
-	 * The LK401 has ALT keys...
-	 */
-	info->hook->poll_tx_char(info, LK_CMD_REQ_ID);
-	while ((ch = info->hook->poll_rx_char(info)) > 0)
-		id = ch;
-
-	switch (id) {
-	case 1:
-		printk("LK201 detected\n");
-		break;
-	case 2:
-		printk("LK401 detected\n");
-		break;
-	default:
-		printk("unknown keyboard, ID %d,\n", id);
-		printk("... please report to <linux-mips@oss.sgi.com>\n");
-	}
+	lk201_hook.rx_char = lk201_rx_char;
 
-	/*
-	 * now we're ready
-	 */
-	info->hook->rx_char = lk201_kbd_rx_char;
+	/* Then just issue a reset -- the handlers will do the rest. */
+	lk201_send(LK_CMD_POWER_UP);
 
 	return 0;
 }
 
 void __init kbd_init_hw(void)
 {
-	extern int register_zs_hook(unsigned int, struct zs_hook *);
-	extern int unregister_zs_hook(unsigned int);
+	/* Maxine uses LK501 at the Access.Bus. */
+	if (!LK_IFACE)
+		return;
 
-	if (TURBOCHANNEL) {
-		if (mips_machtype != MACH_DS5000_XX) {
-			/*
-			 * This is not a MAXINE, so:
-			 *
-			 * kbd_init_hw() is being called before
-			 * rs_init() so just register the kbd hook
-			 * and let zs_init do the rest :-)
-			 */
-			if (mips_machtype == MACH_DS5000_200)
-				printk("LK201 Support for DS5000/200 not yet ready ...\n");
-			else
-				if(!register_zs_hook(KEYB_LINE, &lk201_kbdhook))
-					unregister_zs_hook(KEYB_LINE);
-		}
+	printk(KERN_INFO "lk201: DECstation LK keyboard driver v0.05.\n");
+
+	if (LK_IFACE_ZS) {
+		/*
+		 * kbd_init_hw() is being called before
+		 * rs_init() so just register the kbd hook
+		 * and let zs_init do the rest :-)
+		 */
+		if (!register_dec_serial_hook(KEYB_LINE, &lk201_hook))
+			unregister_dec_serial_hook(KEYB_LINE);
 	} else {
 		/*
 		 * TODO: modify dz.c to allow similar hooks
 		 * for LK201 handling on DS2100, DS3100, and DS5000/200
 		 */
-		printk("LK201 Support for DS3100 not yet ready ...\n");
+		printk(KERN_ERR "lk201: support for DZ11 not yet ready.\n");
 	}
 }
-
-
-
-
diff -Nru a/drivers/tc/lk201.h b/drivers/tc/lk201.h
--- a/drivers/tc/lk201.h	2005-03-01 23:38:57 -08:00
+++ b/drivers/tc/lk201.h	2005-03-01 23:38:57 -08:00
@@ -2,52 +2,124 @@
  *	Commands to the keyboard processor
  */
 
-#define	LK_PARAM		0x80	/* start/end parameter list */
+#define LK_PARAM		0x80	/* start/end parameter list */
 
-#define	LK_CMD_RESUME		0x8b
-#define	LK_CMD_INHIBIT		0xb9
-#define	LK_CMD_LEDS_ON		0x13	/* 1 param: led bitmask */
-#define	LK_CMD_LEDS_OFF		0x11	/* 1 param: led bitmask */
-#define	LK_CMD_DIS_KEYCLK	0x99
-#define	LK_CMD_ENB_KEYCLK	0x1b	/* 1 param: volume */
-#define	LK_CMD_DIS_CTLCLK	0xb9
-#define	LK_CMD_ENB_CTLCLK	0xbb
-#define	LK_CMD_SOUND_CLK	0x9f
-#define	LK_CMD_DIS_BELL		0xa1
-#define	LK_CMD_ENB_BELL		0x23	/* 1 param: volume */
-#define	LK_CMD_BELL		0xa7
-#define	LK_CMD_TMP_NORPT	0xc1
-#define	LK_CMD_ENB_RPT		0xe3
-#define	LK_CMD_DIS_RPT		0xe1
-#define	LK_CMD_RPT_TO_DOWN	0xd9
-#define	LK_CMD_REQ_ID		0xab
-#define	LK_CMD_POWER_UP		0xfd
-#define	LK_CMD_TEST_MODE	0xcb
-#define	LK_CMD_SET_DEFAULTS	0xd3
+#define LK_CMD_RESUME		0x8b	/* resume transmission to the host */
+#define LK_CMD_INHIBIT		0x89	/* stop transmission to the host */
+#define LK_CMD_LEDS_ON		0x13	/* light LEDs */
+					/* 1st param: led bitmask */
+#define LK_CMD_LEDS_OFF		0x11	/* turn off LEDs */
+					/* 1st param: led bitmask */
+#define LK_CMD_DIS_KEYCLK	0x99	/* disable the keyclick */
+#define LK_CMD_ENB_KEYCLK	0x1b	/* enable the keyclick */
+					/* 1st param: volume */
+#define LK_CMD_DIS_CTLCLK	0xb9	/* disable the Ctrl keyclick */
+#define LK_CMD_ENB_CTLCLK	0xbb	/* enable the Ctrl keyclick */
+#define LK_CMD_SOUND_CLK	0x9f	/* emit a keyclick */
+#define LK_CMD_DIS_BELL		0xa1	/* disable the bell */
+#define LK_CMD_ENB_BELL		0x23	/* enable the bell */
+					/* 1st param: volume */
+#define LK_CMD_BELL		0xa7	/* emit a bell */
+#define LK_CMD_TMP_NORPT	0xd1	/* disable typematic */
+					/* for the currently pressed key */
+#define LK_CMD_ENB_RPT		0xe3	/* enable typematic */
+					/* for RPT_DOWN groups */
+#define LK_CMD_DIS_RPT		0xe1	/* disable typematic */
+					/* for RPT_DOWN groups */
+#define LK_CMD_RPT_TO_DOWN	0xd9	/* set RPT_DOWN groups to DOWN */
+#define LK_CMD_REQ_ID		0xab	/* request the keyboard ID */
+#define LK_CMD_POWER_UP		0xfd	/* init power-up sequence */
+#define LK_CMD_TEST_MODE	0xcb	/* enter the factory test mode */
+#define LK_CMD_TEST_EXIT	0x80	/* exit the factory test mode */
+#define LK_CMD_SET_DEFAULTS	0xd3	/* set power-up defaults */
+
+#define LK_CMD_MODE(m,div)	(LK_PARAM|(((div)&0xf)<<3)|(((m)&0x3)<<1))
+					/* select the repeat mode */
+					/* for the selected key group */
+#define LK_CMD_MODE_AR(m,div)	((((div)&0xf)<<3)|(((m)&0x3)<<1))
+					/* select the repeat mode */
+					/* and the repeat register */
+					/* for the selected key group */
+					/* 1st param: register number */
+#define LK_CMD_RPT_RATE(r)	(0x78|(((r)&0x3)<<1))
+					/* set the delay and repeat rate */
+					/* for the selected repeat register */
+					/* 1st param: initial delay */
+					/* 2nd param: repeat rate */
 
 /* there are 4 leds, represent them in the low 4 bits of a byte */
-#define	LK_PARAM_LED_MASK(ledbmap)	(LK_PARAM|(ledbmap))
+#define LK_PARAM_LED_MASK(ledbmap)	(LK_PARAM|((ledbmap)&0xf))
+#define LK_LED_WAIT		0x1	/* Wait LED */
+#define LK_LED_COMP		0x2	/* Compose LED */
+#define LK_LED_LOCK		0x4	/* Lock LED */
+#define LK_LED_HOLD		0x8	/* Hold Screen LED */
 
 /* max volume is 0, lowest is 0x7 */
-#define	LK_PARAM_VOLUME(v)		(LK_PARAM|((v)&0x7))
+#define LK_PARAM_VOLUME(v)		(LK_PARAM|((v)&0x7))
 
-/* mode set command(s) details */
-#define	LK_MODE_DOWN		0x0
-#define	LK_MODE_RPT_DOWN	0x2
-#define	LK_MODE_DOWN_UP		0x6
-#define	LK_CMD_MODE(m,div)	(LK_PARAM|(div<<3)|m)
+/* mode set command details, div is a key group number */
+#define LK_MODE_DOWN		0x0	/* make only */
+#define LK_MODE_RPT_DOWN	0x1	/* make and typematic */
+#define LK_MODE_DOWN_UP		0x3	/* make and release */
+
+/* there are 4 repeat registers */
+#define LK_PARAM_AR(r)		(LK_PARAM|((v)&0x3))
+
+/*
+ * Mappings between key groups and keycodes are as follows:
+ *
+ *  1: 0xbf - 0xff -- alphanumeric,
+ *  2: 0x91 - 0xa5 -- numeric keypad,
+ *  3: 0xbc        -- Backspace,
+ *  4: 0xbd - 0xbe -- Tab, Return,
+ *  5: 0xb0 - 0xb2 -- Lock, Compose Character,
+ *  6: 0xad - 0xaf -- Ctrl, Shift,
+ *  7: 0xa6 - 0xa8 -- Left Arrow, Right Arrow,
+ *  8: 0xa9 - 0xac -- Up Arrow, Down Arrow, Right Shift,
+ *  9: 0x88 - 0x90 -- editor keypad,
+ * 10: 0x56 - 0x62 -- F1 - F5,
+ * 11: 0x63 - 0x6e -- F6 - F10,
+ * 12: 0x6f - 0x7a -- F11 - F14,
+ * 13: 0x7b - 0x7d -- Help, Do,
+ * 14: 0x7e - 0x87 -- F17 - F20.
+ *
+ * Notes:
+ * 1. Codes in the 0x00 - 0x40 range are reserved.
+ * 2. The assignment of the 0x41 - 0x55 range is undiscovered, probably 10.
+ */
+
+/* delay is 5 - 630 ms; 0x00 and 0x7f are reserved */
+#define LK_PARAM_DELAY(t)	((t)&0x7f)
+
+/* rate is 12 - 127 Hz; 0x00 - 0x0b and 0x7d (power-up!) are reserved */
+#define LK_PARAM_RATE(r)	(LK_PARAM|((r)&0x7f))
 
 #define LK_SHIFT 1<<0
 #define LK_CTRL 1<<1
 #define LK_LOCK 1<<2
 #define LK_COMP 1<<3
 
-#define LK_KEY_SHIFT 174
-#define LK_KEY_CTRL 175
-#define LK_KEY_LOCK 176
-#define LK_KEY_COMP 177
-#define LK_KEY_RELEASE 179
-#define LK_KEY_REPEAT 180
-#define LK_KEY_ACK 186
+#define LK_KEY_SHIFT		0xae
+#define LK_KEY_CTRL		0xaf
+#define LK_KEY_LOCK		0xb0
+#define LK_KEY_COMP		0xb1
+
+#define LK_KEY_RELEASE		0xb3	/* all keys released */
+#define LK_KEY_REPEAT		0xb4	/* repeat the last key */
+
+/* status responses */
+#define LK_STAT_RESUME_ERR	0xb5	/* keystrokes lost while inhibited */
+#define LK_STAT_ERROR		0xb6	/* an invalid command received */
+#define LK_STAT_INHIBIT_ACK	0xb7	/* transmission inhibited */
+#define LK_STAT_TEST_ACK	0xb8	/* the factory test mode entered */
+#define LK_STAT_MODE_KEYDOWN	0xb9	/* a key is down on a change */
+					/* to the DOWN_UP mode; */
+					/* the keycode follows */
+#define LK_STAT_MODE_ACK	0xba	/* the mode command succeeded */
+
+#define LK_STAT_PWRUP_ID	0x01	/* the power-up response start mark */
+#define LK_STAT_PWRUP_OK	0x00	/* the power-up self test OK */
+#define LK_STAT_PWRUP_KDOWN	0x3d	/* a key was down during the test */
+#define LK_STAT_PWRUP_ERROR	0x3e	/* keyboard self test failure */
 
-extern unsigned char scancodeRemap[256];
\ No newline at end of file
+extern unsigned char scancodeRemap[256];
diff -Nru a/drivers/tc/tc.c b/drivers/tc/tc.c
--- a/drivers/tc/tc.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/tc/tc.c	2005-03-01 23:39:16 -08:00
@@ -8,46 +8,46 @@
  * for more details.
  *
  * Copyright (c) Harald Koerfgen, 1998
+ * Copyright (c) 2001, 2003  Maciej W. Rozycki
  */
 #include <linux/string.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+
 #include <asm/addrspace.h>
 #include <asm/errno.h>
 #include <asm/dec/machtype.h>
+#include <asm/dec/prom.h>
 #include <asm/dec/tcinfo.h>
 #include <asm/dec/tcmodule.h>
 #include <asm/dec/interrupts.h>
-
+#include <asm/paccess.h>
 #include <asm/ptrace.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
 
 #define TC_DEBUG
 
 MODULE_LICENSE("GPL");
 slot_info tc_bus[MAX_SLOT];
-static int max_tcslot;
+static int num_tcslots;
 static tcinfo *info;
 
 unsigned long system_base;
 
-extern void (*dbe_board_handler)(struct pt_regs *regs);
-extern unsigned long *(*rex_slot_address)(int);
-extern void *(*rex_gettcinfo)(void);
-
 /*
  * Interface to the world. Read comment in include/asm-mips/tc.h.
  */
 
-int search_tc_card(char *name)
+int search_tc_card(const char *name)
 {
 	int slot;
 	slot_info *sip;
 
-	for (slot = 0; slot <= max_tcslot; slot++) {
+	for (slot = 0; slot < num_tcslots; slot++) {
 		sip = &tc_bus[slot];
-		if ((sip->flags & FREE) && (strncmp(sip->name, name, strlen(name)) == 0)) {
+		if ((sip->flags & FREE) &&
+		    (strncmp(sip->name, name, strlen(name)) == 0)) {
 			return slot;
 		}
 	}
@@ -68,7 +68,8 @@
 void release_tc_card(int slot)
 {
 	if (tc_bus[slot].flags & FREE) {
-		printk("release_tc_card: attempting to release a card already free\n");
+		printk("release_tc_card: "
+		       "attempting to release a card already free\n");
 		return;
 	}
 	tc_bus[slot].flags &= ~IN_USE;
@@ -93,73 +94,84 @@
 /*
  * Probing for TURBOchannel modules
  */
-static void __init my_dbe_handler(struct pt_regs *regs)
+static void __init tc_probe(unsigned long startaddr, unsigned long size,
+			    int slots)
 {
-	regs->cp0_epc += 4;
-}
-
-static void __init tc_probe(unsigned long startaddr, unsigned long size, int max_slot)
-{
-	int i, slot;
+	int i, slot, err;
 	long offset;
+	unsigned char pattern[4];
 	unsigned char *module;
-	void (*old_be_handler)(struct pt_regs *regs);
-
-	/* Install our exception handler temporarily */
 
-	old_be_handler = dbe_board_handler;
-	dbe_board_handler = my_dbe_handler;
-	for (slot = 0; slot <= max_slot; slot++) {
+	for (slot = 0; slot < slots; slot++) {
 		module = (char *)(startaddr + slot * size);
-		offset = -1;
-		if (module[OLDCARD + TC_PATTERN0] == 0x55 && module[OLDCARD + TC_PATTERN1] == 0x00
-		  && module[OLDCARD + TC_PATTERN2] == 0xaa && module[OLDCARD + TC_PATTERN3] == 0xff)
-			offset = OLDCARD;
-		if (module[TC_PATTERN0] == 0x55 && module[TC_PATTERN1] == 0x00
-		  && module[TC_PATTERN2] == 0xaa && module[TC_PATTERN3] == 0xff)
-			offset = 0;
-
-		if (offset != -1) {
-			tc_bus[slot].base_addr = (unsigned long)module;
-			for(i = 0; i < 8; i++) {
-				tc_bus[slot].firmware[i] = module[TC_FIRM_VER + offset + 4 * i];
-				tc_bus[slot].vendor[i] = module[TC_VENDOR + offset + 4 * i];
-				tc_bus[slot].name[i] = module[TC_MODULE + offset + 4 * i];
-			}
-			tc_bus[slot].firmware[8] = 0;
-			tc_bus[slot].vendor[8] = 0;
-			tc_bus[slot].name[8] = 0;
-			/*
-			 * Looks unneccesary, but we may change
-			 * TC? in the future
-			 */
-			switch (slot) {
-			case 0:
-				tc_bus[slot].interrupt = TC0;
-				break;
-			case 1:
-				tc_bus[slot].interrupt = TC1;
-				break;
-			case 2:
-				tc_bus[slot].interrupt = TC2;
-				break;
-			/*
-			 * Yuck! DS5000/200 onboard devices
-			 */
-			case 5:
-				tc_bus[slot].interrupt = SCSI_INT;
-				break;
-			case 6:
-				tc_bus[slot].interrupt = ETHER;
-				break;
-			default:
-				tc_bus[slot].interrupt = -1;
-				break;
-			}	
+
+		offset = OLDCARD;
+
+		err = 0;
+		err |= get_dbe(pattern[0], module + OLDCARD + TC_PATTERN0);
+		err |= get_dbe(pattern[1], module + OLDCARD + TC_PATTERN1);
+		err |= get_dbe(pattern[2], module + OLDCARD + TC_PATTERN2);
+		err |= get_dbe(pattern[3], module + OLDCARD + TC_PATTERN3);
+		if (err)
+			continue;
+
+		if (pattern[0] != 0x55 || pattern[1] != 0x00 ||
+		    pattern[2] != 0xaa || pattern[3] != 0xff) {
+			offset = NEWCARD;
+
+			err = 0;
+			err |= get_dbe(pattern[0], module + TC_PATTERN0);
+			err |= get_dbe(pattern[1], module + TC_PATTERN1);
+			err |= get_dbe(pattern[2], module + TC_PATTERN2);
+			err |= get_dbe(pattern[3], module + TC_PATTERN3);
+			if (err)
+				continue;
 		}
-	}
 
-	dbe_board_handler = old_be_handler;
+		if (pattern[0] != 0x55 || pattern[1] != 0x00 ||
+		    pattern[2] != 0xaa || pattern[3] != 0xff)
+			continue;
+
+		tc_bus[slot].base_addr = (unsigned long)module;
+		for(i = 0; i < 8; i++) {
+			tc_bus[slot].firmware[i] =
+				module[TC_FIRM_VER + offset + 4 * i];
+			tc_bus[slot].vendor[i] =
+				module[TC_VENDOR + offset + 4 * i];
+			tc_bus[slot].name[i] =
+				module[TC_MODULE + offset + 4 * i];
+		}
+		tc_bus[slot].firmware[8] = 0;
+		tc_bus[slot].vendor[8] = 0;
+		tc_bus[slot].name[8] = 0;
+		/*
+		 * Looks unneccesary, but we may change
+		 * TC? in the future
+		 */
+		switch (slot) {
+		case 0:
+			tc_bus[slot].interrupt = dec_interrupt[DEC_IRQ_TC0];
+			break;
+		case 1:
+			tc_bus[slot].interrupt = dec_interrupt[DEC_IRQ_TC1];
+			break;
+		case 2:
+			tc_bus[slot].interrupt = dec_interrupt[DEC_IRQ_TC2];
+			break;
+		/*
+		 * Yuck! DS5000/200 onboard devices
+		 */
+		case 5:
+			tc_bus[slot].interrupt = dec_interrupt[DEC_IRQ_TC5];
+			break;
+		case 6:
+			tc_bus[slot].interrupt = dec_interrupt[DEC_IRQ_TC6];
+			break;
+		default:
+			tc_bus[slot].interrupt = -1;
+			break;
+		}
+	}
 }
 
 /*
@@ -189,15 +201,16 @@
 
 	switch (mips_machtype) {
 	case MACH_DS5000_200:
-		max_tcslot = 6;
+		num_tcslots = 7;
 		break;
 	case MACH_DS5000_1XX:
 	case MACH_DS5000_2X0:
-		max_tcslot = 2;
+	case MACH_DS5900:
+		num_tcslots = 3;
 		break;
 	case MACH_DS5000_XX:
 	default:
-		max_tcslot = 1;
+		num_tcslots = 2;
 		break;
 	}
 
@@ -210,22 +223,22 @@
 
 		slot_size = info->slot_size << 20;
 
-		tc_probe(slot0addr, slot_size, max_tcslot);
+		tc_probe(slot0addr, slot_size, num_tcslots);
 
   		/*
   		 * All TURBOchannel DECstations have the onboard devices
- 		 * where the (max_tcslot + 1 or 2 on DS5k/xx) Option Module
+ 		 * where the (num_tcslots + 0 or 1 on DS5k/xx) Option Module
  		 * would be.
  		 */
  		if(mips_machtype == MACH_DS5000_XX)
- 			i = 2;
-		else
  			i = 1;
- 		
- 	        system_base = slot0addr + slot_size * (max_tcslot + i);
+		else
+ 			i = 0;
+
+ 	        system_base = slot0addr + slot_size * (num_tcslots + i);
 
 #ifdef TC_DEBUG
-		for (i = 0; i <= max_tcslot; i++)
+		for (i = 0; i < num_tcslots; i++)
 			if (tc_bus[i].base_addr) {
 				printk("    slot %d: ", i);
 				printk("%s %s %s\n", tc_bus[i].vendor,
@@ -244,4 +257,4 @@
 EXPORT_SYMBOL(get_tc_base_addr);
 EXPORT_SYMBOL(get_tc_irq_nr);
 EXPORT_SYMBOL(get_tc_speed);
-
+EXPORT_SYMBOL(system_base);
diff -Nru a/drivers/tc/zs.c b/drivers/tc/zs.c
--- a/drivers/tc/zs.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/tc/zs.c	2005-03-01 23:39:09 -08:00
@@ -6,7 +6,7 @@
  *
  * DECstation changes
  * Copyright (C) 1998-2000 Harald Koerfgen
- * Copyright (C) 2000,2001 Maciej W. Rozycki <macro@ds2.pg.gda.pl>
+ * Copyright (C) 2000, 2001, 2002, 2003, 2004  Maciej W. Rozycki
  *
  * For the rest of the code the original Copyright applies:
  * Copyright (C) 1996 Paul Mackerras (Paul.Mackerras@cs.anu.edu.au)
@@ -55,8 +55,7 @@
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
-#include <linux/bitops.h>
-#ifdef CONFIG_SERIAL_CONSOLE
+#ifdef CONFIG_SERIAL_DEC_CONSOLE
 #include <linux/console.h>
 #endif
 
@@ -65,18 +64,15 @@
 #include <asm/irq.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
-#include <asm/wbflush.h>
 #include <asm/bootinfo.h>
+#include <asm/dec/serial.h>
+
 #ifdef CONFIG_MACH_DECSTATION
 #include <asm/dec/interrupts.h>
 #include <asm/dec/machtype.h>
 #include <asm/dec/tc.h>
 #include <asm/dec/ioasic_addrs.h>
 #endif
-#ifdef CONFIG_BAGET_MIPS
-#include <asm/baget/baget.h>
-unsigned long system_base;
-#endif
 #ifdef CONFIG_KGDB
 #include <asm/kgdb.h>
 #endif
@@ -94,7 +90,7 @@
 #define NUM_SERIAL	2		/* Max number of ZS chips supported */
 #define NUM_CHANNELS	(NUM_SERIAL * 2)	/* 2 channels per chip */
 #define CHANNEL_A_NR  (zs_parms->channel_a_offset > zs_parms->channel_b_offset)
-                                        /* Number of channel A in the chip */ 
+                                        /* Number of channel A in the chip */
 #define ZS_CHAN_IO_SIZE 8
 #define ZS_CLOCK        7372800 	/* Z8530 RTxC input clock rate */
 
@@ -105,7 +101,8 @@
 	unsigned long scc1;
 	int channel_a_offset;
 	int channel_b_offset;
-	int irq;
+	int irq0;
+	int irq1;
 	int clock;
 };
 
@@ -113,24 +110,15 @@
 
 #ifdef CONFIG_MACH_DECSTATION
 static struct zs_parms ds_parms = {
-	scc0 : SCC0,
-	scc1 : SCC1,
+	scc0 : IOASIC_SCC0,
+	scc1 : IOASIC_SCC1,
 	channel_a_offset : 1,
 	channel_b_offset : 9,
-	irq : SERIAL,
+	irq0 : -1,
+	irq1 : -1,
 	clock : ZS_CLOCK
 };
 #endif
-#ifdef CONFIG_BAGET_MIPS
-static struct zs_parms baget_parms = {
-	scc0 : UNI_SCC0,
-	scc1 : UNI_SCC1,
-	channel_a_offset : 9,
-	channel_b_offset : 1,
-	irq : BAGET_SCC_IRQ,
-	clock : 14745000
-};
-#endif
 
 #ifdef CONFIG_MACH_DECSTATION
 #define DS_BUS_PRESENT (IOASIC)
@@ -138,13 +126,7 @@
 #define DS_BUS_PRESENT 0
 #endif
 
-#ifdef CONFIG_BAGET_MIPS
-#define BAGET_BUS_PRESENT (mips_machtype == MACH_BAGET202)
-#else
-#define BAGET_BUS_PRESENT 0
-#endif
-
-#define BUS_PRESENT (DS_BUS_PRESENT || BAGET_BUS_PRESENT)
+#define BUS_PRESENT (DS_BUS_PRESENT)
 
 struct dec_zschannel zs_channels[NUM_CHANNELS];
 struct dec_serial zs_soft[NUM_CHANNELS];
@@ -153,28 +135,28 @@
 
 struct tty_struct zs_ttys[NUM_CHANNELS];
 
-#ifdef CONFIG_SERIAL_CONSOLE
+#ifdef CONFIG_SERIAL_DEC_CONSOLE
 static struct console sercons;
 #endif
-#if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) \
-    && !defined(MODULE)
+#if defined(CONFIG_SERIAL_DEC_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) && \
+   !defined(MODULE)
 static unsigned long break_pressed; /* break, really ... */
 #endif
 
 static unsigned char zs_init_regs[16] __initdata = {
-	0,                           /* write 0 */
-	0,			     /* write 1 */
-	0xf0,                        /* write 2 */
-	(Rx8),                       /* write 3 */
-	(X16CLK | SB1),              /* write 4 */
-	(Tx8),                       /* write 5 */
-	0, 0, 0,                     /* write 6, 7, 8 */
-	(VIS),                       /* write 9 */
-	(NRZ),                       /* write 10 */
-	(TCBR | RCBR),               /* write 11 */
-	0, 0,                        /* BRG time constant, write 12 + 13 */
-	(BRSRC | BRENABL),           /* write 14 */
-	0 			     /* write 15 */
+	0,				/* write 0 */
+	0,				/* write 1 */
+	0,				/* write 2 */
+	0,				/* write 3 */
+	(X16CLK),			/* write 4 */
+	0,				/* write 5 */
+	0, 0, 0,			/* write 6, 7, 8 */
+	(MIE | DLC | NV),		/* write 9 */
+	(NRZ),				/* write 10 */
+	(TCBR | RCBR),			/* write 11 */
+	0, 0,				/* BRG time constant, write 12 + 13 */
+	(BRSRC | BRENABL),		/* write 14 */
+	0				/* write 15 */
 };
 
 DECLARE_TASK_QUEUE(tq_zs_serial);
@@ -190,7 +172,6 @@
 /*
  * Debugging.
  */
-#undef SERIAL_DEBUG_INTR
 #undef SERIAL_DEBUG_OPEN
 #undef SERIAL_DEBUG_FLOW
 #undef SERIAL_DEBUG_THROTTLE
@@ -251,7 +232,7 @@
 	0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
 	9600, 19200, 38400, 57600, 115200, 0 };
 
-/* 
+/*
  * Reading and writing Z8530 registers.
  */
 static inline unsigned char read_zsreg(struct dec_zschannel *channel,
@@ -261,7 +242,7 @@
 
 	if (reg != 0) {
 		*channel->control = reg & 0xf;
-		wbflush(); RECOVERY_DELAY;
+		fast_iob(); RECOVERY_DELAY;
 	}
 	retval = *channel->control;
 	RECOVERY_DELAY;
@@ -273,10 +254,10 @@
 {
 	if (reg != 0) {
 		*channel->control = reg & 0xf;
-		wbflush(); RECOVERY_DELAY;
+		fast_iob(); RECOVERY_DELAY;
 	}
 	*channel->control = value;
-	wbflush(); RECOVERY_DELAY;
+	fast_iob(); RECOVERY_DELAY;
 	return;
 }
 
@@ -293,7 +274,7 @@
 				unsigned char value)
 {
 	*channel->data = value;
-	wbflush(); RECOVERY_DELAY;
+	fast_iob(); RECOVERY_DELAY;
 	return;
 }
 
@@ -303,9 +284,9 @@
 /*	ZS_CLEARERR(channel);
 	ZS_CLEARFIFO(channel); */
 	/* Load 'em up */
-	write_zsreg(channel, R4, regs[R4]);
 	write_zsreg(channel, R3, regs[R3] & ~RxENABLE);
 	write_zsreg(channel, R5, regs[R5] & ~TxENAB);
+	write_zsreg(channel, R4, regs[R4]);
 	write_zsreg(channel, R9, regs[R9]);
 	write_zsreg(channel, R1, regs[R1]);
 	write_zsreg(channel, R2, regs[R2]);
@@ -372,8 +353,6 @@
  * -----------------------------------------------------------------------
  */
 
-static int tty_break;	/* Set whenever BREAK condition is detected.  */
-
 /*
  * This routine is used by the interrupt handler to schedule
  * processing in the software interrupt portion of the driver.
@@ -397,23 +376,18 @@
 		stat = read_zsreg(info->zs_channel, R1);
 		ch = read_zsdata(info->zs_channel);
 
-		if (!tty && !info->hook && !info->hook->rx_char)
+		if (!tty && (!info->hook || !info->hook->rx_char))
 			continue;
 
-		if (tty_break) {
-			tty_break = 0;
-#if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) && !defined(MODULE)
-			if (info->line == sercons.index) {
-				if (!break_pressed) {
-					break_pressed = jiffies;
-					goto ignore_char;
-				}
-				break_pressed = 0;
-			}
-#endif
+		flag = TTY_NORMAL;
+		if (info->tty_break) {
+			info->tty_break = 0;
 			flag = TTY_BREAK;
 			if (info->flags & ZILOG_SAK)
 				do_SAK(tty);
+			/* Ignore the null char got when BREAK is removed.  */
+			if (ch == 0)
+				continue;
 		} else {
 			if (stat & Rx_OVR) {
 				flag = TTY_OVERRUN;
@@ -421,20 +395,22 @@
 				flag = TTY_FRAME;
 			} else if (stat & PAR_ERR) {
 				flag = TTY_PARITY;
-			} else
-				flag = 0;
-			if (flag)
+			}
+			if (flag != TTY_NORMAL)
 				/* reset the error indication */
 				write_zsreg(info->zs_channel, R0, ERR_RES);
 		}
 
-#if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) && !defined(MODULE)
+#if defined(CONFIG_SERIAL_DEC_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) && \
+   !defined(MODULE)
 		if (break_pressed && info->line == sercons.index) {
-			if (ch != 0 &&
-			    time_before(jiffies, break_pressed + HZ*5)) {
+			/* Ignore the null char got when BREAK is removed.  */
+			if (ch == 0)
+				continue;
+			if (time_before(jiffies, break_pressed + HZ * 5)) {
 				handle_sysrq(ch, regs, NULL);
 				break_pressed = 0;
-				goto ignore_char;
+				continue;
 			}
 			break_pressed = 0;
 		}
@@ -444,22 +420,8 @@
 			(*info->hook->rx_char)(ch, flag);
 			return;
   		}
-		
-		if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
-			static int flip_buf_ovf;
-			++flip_buf_ovf;
-			continue;
-		}
-		tty->flip.count++;
-		{
-			static int flip_max_cnt;
-			if (flip_max_cnt < tty->flip.count)
-				flip_max_cnt = tty->flip.count;
-		}
 
-		*tty->flip.flag_buf_ptr++ = flag;
-		*tty->flip.char_buf_ptr++ = ch;
-	ignore_char:
+		tty_insert_flip_char(tty, ch, flag);
 	}
 	if (tty)
 		tty_flip_buffer_push(tty);
@@ -501,18 +463,22 @@
 	/* Get status from Read Register 0 */
 	stat = read_zsreg(info->zs_channel, R0);
 
-	if (stat & BRK_ABRT) {
-#ifdef SERIAL_DEBUG_INTR
-		printk("handling break....");
+	if ((stat & BRK_ABRT) && !(info->read_reg_zero & BRK_ABRT)) {
+#if defined(CONFIG_SERIAL_DEC_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) && \
+   !defined(MODULE)
+		if (info->line == sercons.index) {
+			if (!break_pressed)
+				break_pressed = jiffies;
+		} else
 #endif
-		tty_break = 1;
+			info->tty_break = 1;
 	}
 
 	if (info->zs_channel != info->zs_chan_a) {
 
-		/* FIXEM: Check for DCD transitions */
-		if (((stat ^ info->read_reg_zero) & DCD) != 0
-		    && info->tty && !C_CLOCAL(info->tty)) {
+		/* Check for DCD transitions */
+		if (info->tty && !C_CLOCAL(info->tty) &&
+		    ((stat ^ info->read_reg_zero) & DCD) != 0 ) {
 			if (stat & DCD) {
 				wake_up_interruptible(&info->open_wait);
 			} else {
@@ -563,7 +529,7 @@
 		shift = 0;	/* Channel B */
 
 	for (;;) {
-		zs_intreg = read_zsreg(info->zs_chan_a, R3) >> shift; 
+		zs_intreg = read_zsreg(info->zs_chan_a, R3) >> shift;
 		if ((zs_intreg & CHAN_IRQMASK) == 0)
 			break;
 
@@ -577,7 +543,7 @@
 			status_handle(info);
 		}
 	}
-	
+
 	/* Why do we need this ? */
 	write_zsreg(info->zs_channel, 0, RES_H_IUS);
 }
@@ -586,14 +552,14 @@
 void zs_dump (void) {
 	int i, j;
 	for (i = 0; i < zs_channels_found; i++) {
-		struct dec_zschannel *ch = &zs_channels[i]; 
+		struct dec_zschannel *ch = &zs_channels[i];
 		if ((long)ch->control == UNI_IO_BASE+UNI_SCC1A_CTRL) {
 			for (j = 0; j < 15; j++) {
-				printk("W%d = 0x%x\t", 
+				printk("W%d = 0x%x\t",
 				       j, (int)ch->curregs[j]);
 			}
 			for (j = 0; j < 15; j++) {
-				printk("R%d = 0x%x\t", 
+				printk("R%d = 0x%x\t",
 				       j, (int)read_zsreg(ch,j));
 			}
 			printk("\n\n");
@@ -622,7 +588,7 @@
 
 	if (serial_paranoia_check(info, tty->name, "rs_stop"))
 		return;
-	
+
 #if 1
 	save_flags(flags); cli();
 	if (info->zs_channel->curregs[5] & TxENAB) {
@@ -637,10 +603,10 @@
 {
 	struct dec_serial *info = (struct dec_serial *)tty->driver_data;
 	unsigned long flags;
-	
+
 	if (serial_paranoia_check(info, tty->name, "rs_start"))
 		return;
-	
+
 	save_flags(flags); cli();
 #if 1
 	if (info->xmit_cnt && info->xmit_buf && !(info->zs_channel->curregs[5] & TxENAB)) {
@@ -673,7 +639,7 @@
 {
 	struct dec_serial	*info = (struct dec_serial *) private_;
 	struct tty_struct	*tty;
-	
+
 	tty = info->tty;
 	if (!tty)
 		return;
@@ -711,8 +677,13 @@
 	/*
 	 * Clear the interrupt registers.
 	 */
-	write_zsreg(info->zs_channel, 0, ERR_RES);
-	write_zsreg(info->zs_channel, 0, RES_H_IUS);
+	write_zsreg(info->zs_channel, R0, ERR_RES);
+	write_zsreg(info->zs_channel, R0, RES_H_IUS);
+
+	/*
+	 * Set the speed of the serial port
+	 */
+	change_speed(info);
 
 	/*
 	 * Turn on RTS and DTR.
@@ -722,35 +693,30 @@
 	/*
 	 * Finally, enable sequencing and interrupts
 	 */
-	info->zs_channel->curregs[1] = (info->zs_channel->curregs[1] & ~0x18) | (EXT_INT_ENAB | INT_ALL_Rx | TxINT_ENAB);
-	info->zs_channel->curregs[3] |= (RxENABLE | Rx8);
-	info->zs_channel->curregs[5] |= (TxENAB | Tx8);
-	info->zs_channel->curregs[15] |= (DCDIE | CTSIE | TxUIE | BRKIE);
-	info->zs_channel->curregs[9] |= (VIS | MIE);
-	write_zsreg(info->zs_channel, 1, info->zs_channel->curregs[1]);
-	write_zsreg(info->zs_channel, 3, info->zs_channel->curregs[3]);
-	write_zsreg(info->zs_channel, 5, info->zs_channel->curregs[5]);
-	write_zsreg(info->zs_channel, 15, info->zs_channel->curregs[15]);
-	write_zsreg(info->zs_channel, 9, info->zs_channel->curregs[9]);
+	info->zs_channel->curregs[R1] &= ~RxINT_MASK;
+	info->zs_channel->curregs[R1] |= (RxINT_ALL | TxINT_ENAB |
+					  EXT_INT_ENAB);
+	info->zs_channel->curregs[R3] |= RxENABLE;
+	info->zs_channel->curregs[R5] |= TxENAB;
+	info->zs_channel->curregs[R15] |= (DCDIE | CTSIE | TxUIE | BRKIE);
+	write_zsreg(info->zs_channel, R1, info->zs_channel->curregs[R1]);
+	write_zsreg(info->zs_channel, R3, info->zs_channel->curregs[R3]);
+	write_zsreg(info->zs_channel, R5, info->zs_channel->curregs[R5]);
+	write_zsreg(info->zs_channel, R15, info->zs_channel->curregs[R15]);
 
 	/*
 	 * And clear the interrupt registers again for luck.
 	 */
-	write_zsreg(info->zs_channel, 0, ERR_RES);
-	write_zsreg(info->zs_channel, 0, RES_H_IUS);
+	write_zsreg(info->zs_channel, R0, ERR_RES);
+	write_zsreg(info->zs_channel, R0, RES_H_IUS);
+
+	/* Save the current value of RR0 */
+	info->read_reg_zero = read_zsreg(info->zs_channel, R0);
 
 	if (info->tty)
 		clear_bit(TTY_IO_ERROR, &info->tty->flags);
 	info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
 
-	/*
-	 * Set the speed of the serial port
-	 */
-	change_speed(info);
-
-	/* Save the current value of RR0 */
-	info->read_reg_zero = read_zsreg(info->zs_channel, 0);
-
 	info->flags |= ZILOG_INITIALIZED;
 	restore_flags(flags);
 	return 0;
@@ -771,9 +737,9 @@
 	printk("Shutting down serial port %d (irq %d)....", info->line,
 	       info->irq);
 #endif
-	
+
 	save_flags(flags); cli(); /* Disable interrupts */
-	
+
 	if (info->xmit_buf) {
 		free_page((unsigned long) info->xmit_buf);
 		info->xmit_buf = 0;
@@ -833,13 +799,11 @@
 
 	save_flags(flags); cli();
 	info->zs_baud = baud_table[i];
-	info->clk_divisor = 16;
 	if (info->zs_baud) {
-		info->zs_channel->curregs[4] = X16CLK;
 		brg = BPS_TO_BRG(info->zs_baud, zs_parms->clock/info->clk_divisor);
 		info->zs_channel->curregs[12] = (brg & 255);
 		info->zs_channel->curregs[13] = ((brg >> 8) & 255);
-		zs_rtsdtr(info, DTR, 1); 
+		zs_rtsdtr(info, DTR, 1);
 	} else {
 		zs_rtsdtr(info, RTS | DTR, 0);
 		return;
@@ -942,13 +906,21 @@
 
 	save_flags(flags);
 	while (1) {
-		cli();		
-		c = min_t(int, count, min(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
-					  SERIAL_XMIT_SIZE - info->xmit_head));
+		cli();
+		c = min(count, min(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
+				   SERIAL_XMIT_SIZE - info->xmit_head));
 		if (c <= 0)
 			break;
 
-		memcpy(info->xmit_buf + info->xmit_head, buf, c);
+		if (from_user) {
+			down(&tmp_buf_sem);
+			copy_from_user(tmp_buf, buf, c);
+			c = min(c, min(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
+				       SERIAL_XMIT_SIZE - info->xmit_head));
+			memcpy(info->xmit_buf + info->xmit_head, tmp_buf, c);
+			up(&tmp_buf_sem);
+		} else
+			memcpy(info->xmit_buf + info->xmit_head, buf, c);
 		info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
 		info->xmit_cnt += c;
 		restore_flags(flags);
@@ -968,7 +940,7 @@
 {
 	struct dec_serial *info = (struct dec_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;
@@ -980,7 +952,7 @@
 static int rs_chars_in_buffer(struct tty_struct *tty)
 {
 	struct dec_serial *info = (struct dec_serial *)tty->driver_data;
-			
+
 	if (serial_paranoia_check(info, tty->name, "rs_chars_in_buffer"))
 		return 0;
 	return info->xmit_cnt;
@@ -989,7 +961,7 @@
 static void rs_flush_buffer(struct tty_struct *tty)
 {
 	struct dec_serial *info = (struct dec_serial *)tty->driver_data;
-				
+
 	if (serial_paranoia_check(info, tty->name, "rs_flush_buffer"))
 		return;
 	cli();
@@ -1001,7 +973,7 @@
 /*
  * ------------------------------------------------------------
  * rs_throttle()
- * 
+ *
  * This routine is called by the upper-layer tty layer to signal that
  * incoming characters should be throttled.
  * ------------------------------------------------------------
@@ -1013,14 +985,14 @@
 
 #ifdef SERIAL_DEBUG_THROTTLE
 	char	buf[64];
-	
+
 	printk("throttle %s: %d....\n", _tty_name(tty, buf),
 	       tty->ldisc.chars_in_buffer(tty));
 #endif
 
 	if (serial_paranoia_check(info, tty->name, "rs_throttle"))
 		return;
-	
+
 	if (I_IXOFF(tty)) {
 		save_flags(flags); cli();
 		info->x_char = STOP_CHAR(tty);
@@ -1041,14 +1013,14 @@
 
 #ifdef SERIAL_DEBUG_THROTTLE
 	char	buf[64];
-	
+
 	printk("unthrottle %s: %d....\n", _tty_name(tty, buf),
 	       tty->ldisc.chars_in_buffer(tty));
 #endif
 
 	if (serial_paranoia_check(info, tty->name, "rs_unthrottle"))
 		return;
-	
+
 	if (I_IXOFF(tty)) {
 		save_flags(flags); cli();
 		if (info->x_char)
@@ -1145,7 +1117,7 @@
  * 	    release the bus after transmitting. This must be done when
  * 	    the transmit shift register is empty, not be done when the
  * 	    transmit holding register is empty.  This functionality
- * 	    allows an RS485 driver to be written in user space. 
+ * 	    allows an RS485 driver to be written in user space.
  */
 static int get_lsr_info(struct dec_serial * info, unsigned int *value)
 {
@@ -1192,7 +1164,7 @@
 }
 
 static int rs_tiocmset(struct tty_struct *tty, struct file *file,
-		       unsigned int set, unsigned int clear)
+                       unsigned int set, unsigned int clear)
 {
 	struct dec_serial * info = (struct dec_serial *)tty->driver_data;
 	int error;
@@ -1210,6 +1182,7 @@
 	if (info->zs_channel == info->zs_chan_a)
 		return 0;
 
+	get_user(arg, value);
 	cli();
 	if (set & TIOCM_RTS)
 		info->zs_chan_a->curregs[5] |= RTS;
@@ -1264,38 +1237,38 @@
 		if (tty->flags & (1 << TTY_IO_ERROR))
 		    return -EIO;
 	}
-	
+
 	switch (cmd) {
-		case TIOCGSERIAL:
-			error = verify_area(VERIFY_WRITE, (void *) arg,
-						sizeof(struct serial_struct));
-			if (error)
-				return error;
-			return get_serial_info(info,
-					       (struct serial_struct *) arg);
-		case TIOCSSERIAL:
-			return set_serial_info(info,
-					       (struct serial_struct *) arg);
-		case TIOCSERGETLSR: /* Get line status register */
-			error = verify_area(VERIFY_WRITE, (void *) arg,
-				sizeof(unsigned int));
-			if (error)
-				return error;
-			else
-			    return get_lsr_info(info, (unsigned int *) arg);
+	case TIOCGSERIAL:
+		error = verify_area(VERIFY_WRITE, (void *)arg,
+				    sizeof(struct serial_struct));
+		if (error)
+			return error;
+		return get_serial_info(info, (struct serial_struct *)arg);
+
+	case TIOCSSERIAL:
+		return set_serial_info(info, (struct serial_struct *)arg);
+
+	case TIOCSERGETLSR:			/* Get line status register */
+		error = verify_area(VERIFY_WRITE, (void *)arg,
+				    sizeof(unsigned int));
+		if (error)
+			return error;
+		else
+			return get_lsr_info(info, (unsigned int *)arg);
+
+	case TIOCSERGSTRUCT:
+		error = verify_area(VERIFY_WRITE, (void *)arg,
+				    sizeof(struct dec_serial));
+		if (error)
+			return error;
+		copy_from_user((struct dec_serial *)arg, info,
+			       sizeof(struct dec_serial));
+		return 0;
 
-		case TIOCSERGSTRUCT:
-			error = verify_area(VERIFY_WRITE, (void *) arg,
-						sizeof(struct dec_serial));
-			if (error)
-				return error;
-			copy_from_user((struct dec_serial *) arg,
-				       info, sizeof(struct dec_serial));
-			return 0;
-			
-		default:
-			return -ENOIOCTLCMD;
-		}
+	default:
+		return -ENOIOCTLCMD;
+	}
 	return 0;
 }
 
@@ -1317,7 +1290,7 @@
 /*
  * ------------------------------------------------------------
  * rs_close()
- * 
+ *
  * This routine is called when the serial port gets closed.
  * Wait for the last remaining data to be sent.
  * ------------------------------------------------------------
@@ -1329,14 +1302,14 @@
 
 	if (!info || serial_paranoia_check(info, tty->name, "rs_close"))
 		return;
-	
+
 	save_flags(flags); cli();
-	
+
 	if (tty_hung_up_p(filp)) {
 		restore_flags(flags);
 		return;
 	}
-	
+
 #ifdef SERIAL_DEBUG_OPEN
 	printk("rs_close ttyS%d, count = %d\n", info->line, info->count);
 #endif
@@ -1363,7 +1336,7 @@
 	}
 	info->flags |= ZILOG_CLOSING;
 	/*
-	 * Now we wait for the transmit buffer to clear; and we notify 
+	 * Now we wait for the transmit buffer to clear; and we notify
 	 * the line discipline to only process XON/XOFF characters.
 	 */
 	tty->closing = 1;
@@ -1411,7 +1384,8 @@
 static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
 {
 	struct dec_serial *info = (struct dec_serial *) tty->driver_data;
-	unsigned long orig_jiffies, char_time;
+	unsigned long orig_jiffies;
+	int char_time;
 
 	if (serial_paranoia_check(info, tty->name, "rs_wait_until_sent"))
 		return;
@@ -1427,7 +1401,7 @@
 	if (char_time == 0)
 		char_time = 1;
 	if (timeout)
-		char_time = min_t(unsigned long, char_time, timeout);
+		char_time = min(char_time, timeout);
 	while ((read_zsreg(info->zs_channel, 1) & Tx_BUF_EMP) == 0) {
 		current->state = TASK_INTERRUPTIBLE;
 		schedule_timeout(char_time);
@@ -1485,11 +1459,6 @@
 	}
 
 	/*
-	 * If this is a callout device, then just make sure the normal
-	 * device isn't being used.
-	 */
-	
-	/*
 	 * If non-blocking mode is set, or the port is not enabled,
 	 * then make the check up front and then exit.
 	 */
@@ -1516,7 +1485,7 @@
 	       info->line, info->count);
 #endif
 	cli();
-	if (!tty_hung_up_p(filp)) 
+	if (!tty_hung_up_p(filp))
 		info->count--;
 	sti();
 	info->blocked_open++;
@@ -1532,7 +1501,7 @@
 			if (info->flags & ZILOG_HUP_NOTIFY)
 				retval = -EAGAIN;
 			else
-				retval = -ERESTARTSYS;	
+				retval = -ERESTARTSYS;
 #else
 			retval = -EAGAIN;
 #endif
@@ -1564,7 +1533,7 @@
 		return retval;
 	info->flags |= ZILOG_NORMAL_ACTIVE;
 	return 0;
-}	
+}
 
 /*
  * This routine is called whenever a serial port is opened.  It
@@ -1626,7 +1595,7 @@
 		return retval;
 	}
 
-#ifdef CONFIG_SERIAL_CONSOLE
+#ifdef CONFIG_SERIAL_DEC_CONSOLE
 	if (sercons.cflag && sercons.index == line) {
 		tty->termios->c_cflag = sercons.cflag;
 		sercons.cflag = 0;
@@ -1645,7 +1614,7 @@
 
 static void __init show_serial_version(void)
 {
-	printk("DECstation Z8530 serial driver version 0.05\n");
+	printk("DECstation Z8530 serial driver version 0.09\n");
 }
 
 /*  Initialize Z8530s zs_channels
@@ -1655,6 +1624,7 @@
 {
 	struct dec_serial **pp;
 	int i, n, n_chips = 0, n_channels, chip, channel;
+	unsigned long flags;
 
 	/*
 	 * did we get here by accident?
@@ -1663,7 +1633,7 @@
 		printk("Not on JUNKIO machine, skipping probe_sccs\n");
 		return;
 	}
-	
+
 	/*
 	 * When serial console is activated, tc_init has not been called yet
 	 * and system_base is undefined. Unfortunately we have to hardcode
@@ -1672,27 +1642,25 @@
 	switch(mips_machtype) {
 #ifdef CONFIG_MACH_DECSTATION
 	case MACH_DS5000_2X0:
-		system_base = 0xbf800000;
+	case MACH_DS5900:
+		system_base = KSEG1ADDR(0x1f800000);
 		n_chips = 2;
 		zs_parms = &ds_parms;
+		zs_parms->irq0 = dec_interrupt[DEC_IRQ_SCC0];
+		zs_parms->irq1 = dec_interrupt[DEC_IRQ_SCC1];
 		break;
 	case MACH_DS5000_1XX:
-		system_base = 0xbc000000;
+		system_base = KSEG1ADDR(0x1c000000);
 		n_chips = 2;
 		zs_parms = &ds_parms;
+		zs_parms->irq0 = dec_interrupt[DEC_IRQ_SCC0];
+		zs_parms->irq1 = dec_interrupt[DEC_IRQ_SCC1];
 		break;
 	case MACH_DS5000_XX:
-		system_base = 0xbc000000;
+		system_base = KSEG1ADDR(0x1c000000);
 		n_chips = 1;
 		zs_parms = &ds_parms;
-		break;
-#endif
-#ifdef CONFIG_BAGET_MIPS
-	case MACH_BAGET202:
-		system_base = UNI_IO_BASE;
-		n_chips = 2;
-		zs_parms = &baget_parms;
-		zs_init_regs[2] = 0x8;
+		zs_parms->irq0 = dec_interrupt[DEC_IRQ_SCC0];
 		break;
 #endif
 	default:
@@ -1710,15 +1678,15 @@
 			/*
 			 * The sccs reside on the high byte of the 16 bit IOBUS
 			 */
-			zs_channels[n_channels].control = 
-				(volatile unsigned char *)system_base + 
-			  (0 == chip ? zs_parms->scc0 : zs_parms->scc1) + 
-			  (0 == channel ? zs_parms->channel_a_offset : 
+			zs_channels[n_channels].control =
+				(volatile unsigned char *)system_base +
+			  (0 == chip ? zs_parms->scc0 : zs_parms->scc1) +
+			  (0 == channel ? zs_parms->channel_a_offset :
 			                  zs_parms->channel_b_offset);
-			zs_channels[n_channels].data = 
+			zs_channels[n_channels].data =
 				zs_channels[n_channels].control + 4;
 
-#ifndef CONFIG_SERIAL_CONSOLE
+#ifndef CONFIG_SERIAL_DEC_CONSOLE
 			/*
 			 * We're called early and memory managment isn't up, yet.
 			 * Thus check_region would fail.
@@ -1729,20 +1697,24 @@
 				panic("SCC I/O region is not free");
 #endif
 			zs_soft[n_channels].zs_channel = &zs_channels[n_channels];
-			zs_soft[n_channels].irq = zs_parms->irq;
+			/* HACK alert! */
+			if (!(chip & 1))
+				zs_soft[n_channels].irq = zs_parms->irq0;
+			else
+				zs_soft[n_channels].irq = zs_parms->irq1;
 
-			/* 
+			/*
 			 *  Identification of channel A. Location of channel A
                          *  inside chip depends on mapping of internal address
 			 *  the chip decodes channels by.
-			 *  CHANNEL_A_NR returns either 0 (in case of 
+			 *  CHANNEL_A_NR returns either 0 (in case of
 			 *  DECstations) or 1 (in case of Baget).
 			 */
 			if (CHANNEL_A_NR == channel)
-				zs_soft[n_channels].zs_chan_a = 
+				zs_soft[n_channels].zs_chan_a =
 				    &zs_channels[n_channels+1-2*CHANNEL_A_NR];
 			else
-				zs_soft[n_channels].zs_chan_a = 
+				zs_soft[n_channels].zs_chan_a =
 				    &zs_channels[n_channels];
 
 			*pp = &zs_soft[n_channels];
@@ -1760,16 +1732,17 @@
 		}
 	}
 
-/*	save_and_cli(flags);
+	save_and_cli(flags);
 	for (n = 0; n < zs_channels_found; n++) {
-		if (((int)zs_channels[n].control & 0xf) == 1) {
+		if (n % 2 == 0) {
 			write_zsreg(zs_soft[n].zs_chan_a, R9, FHWRES);
-			mdelay(10);
+			udelay(10);
 			write_zsreg(zs_soft[n].zs_chan_a, R9, 0);
 		}
-		load_zsregs(zs_soft[n].zs_channel, zs_soft[n].zs_channel->curregs);
-	} 
-	restore_flags(flags); */
+		load_zsregs(zs_soft[n].zs_channel,
+			    zs_soft[n].zs_channel->curregs);
+	}
+	restore_flags(flags);
 }
 
 static struct tty_operations serial_ops = {
@@ -1797,7 +1770,6 @@
 int __init zs_init(void)
 {
 	int channel, i;
-	unsigned long flags;
 	struct dec_serial *info;
 
 	if(!BUS_PRESENT)
@@ -1809,7 +1781,6 @@
 	/* 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;
@@ -1833,39 +1804,25 @@
 	tty_set_operations(serial_driver, &serial_ops);
 
 	if (tty_register_driver(serial_driver))
-		panic("Couldn't register serial driver\n");
-
-	save_flags(flags); cli();
-
-	for (channel = 0; channel < zs_channels_found; ++channel) {
-		if (zs_soft[channel].hook &&
-		    zs_soft[channel].hook->init_channel)
-			(*zs_soft[channel].hook->init_channel)
-				(&zs_soft[channel]);
+		panic("Couldn't register serial driver");
 
-		zs_soft[channel].clk_divisor = 16;
-		zs_soft[channel].zs_baud = get_zsbaud(&zs_soft[channel]);
+	for (info = zs_chain, i = 0; info; info = info->zs_next, i++) {
 
-		if (request_irq(zs_parms->irq, rs_interrupt, SA_SHIRQ,
-				"SCC", &zs_soft[channel]))
-			printk(KERN_ERR "decserial: can't get irq %d\n",
-			       zs_parms->irq);
-	}
+		/* Needed before interrupts are enabled. */
+		info->tty = 0;
+		info->x_char = 0;
 
-	for (info = zs_chain, i = 0; info; info = info->zs_next, i++)
-	{
 		if (info->hook && info->hook->init_info) {
 			(*info->hook->init_info)(info);
 			continue;
 		}
+
 		info->magic = SERIAL_MAGIC;
 		info->port = (int) info->zs_channel->control;
 		info->line = i;
-		info->tty = 0;
 		info->custom_divisor = 16;
 		info->close_delay = 50;
 		info->closing_wait = 3000;
-		info->x_char = 0;
 		info->event = 0;
 		info->count = 0;
 		info->blocked_open = 0;
@@ -1873,94 +1830,83 @@
 		info->tqueue.data = info;
 		init_waitqueue_head(&info->open_wait);
 		init_waitqueue_head(&info->close_wait);
-		printk("ttyS%d at 0x%08x (irq = %d)", info->line,
-		       info->port, info->irq);
-		printk(" is a Z85C30 SCC\n");
+		printk("ttyS%02d at 0x%08x (irq = %d) is a Z85C30 SCC\n",
+		       info->line, info->port, info->irq);
 		tty_register_device(serial_driver, info->line, NULL);
+
 	}
 
-	restore_flags(flags);
+	for (channel = 0; channel < zs_channels_found; ++channel) {
+		zs_soft[channel].clk_divisor = 16;
+		zs_soft[channel].zs_baud = get_zsbaud(&zs_soft[channel]);
 
-	return 0;
-}
+		if (request_irq(zs_soft[channel].irq, rs_interrupt, SA_SHIRQ,
+				"scc", &zs_soft[channel]))
+			printk(KERN_ERR "decserial: can't get irq %d\n",
+			       zs_soft[channel].irq);
 
-/*
- * 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;
-}
+		if (zs_soft[channel].hook) {
+			zs_startup(&zs_soft[channel]);
+			if (zs_soft[channel].hook->init_channel)
+				(*zs_soft[channel].hook->init_channel)
+					(&zs_soft[channel]);
+		}
+	}
 
-void unregister_serial(int line)
-{
-	return;
+	return 0;
 }
 
 /*
  * polling I/O routines
  */
 static int
-zs_poll_tx_char(struct dec_serial *info, unsigned char ch)
+zs_poll_tx_char(void *handle, unsigned char ch)
 {
+	struct dec_serial *info = handle;
 	struct dec_zschannel *chan = info->zs_channel;
 	int    ret;
 
 	if(chan) {
 		int loops = 10000;
-//		int nine = read_zsreg(chan, R9);
-
-		RECOVERY_DELAY;
-//        	write_zsreg(chan, R9, nine & ~MIE);
-               	wbflush();
-		RECOVERY_DELAY;
-
-        	while (!(*(chan->control) & Tx_BUF_EMP) && --loops)
-	        	RECOVERY_DELAY;
-
-                if (loops) {
-                        ret = 0;
-        	        *(chan->data) = ch;
-                	wbflush();
-			RECOVERY_DELAY;
-                } else
-                        ret = -EAGAIN;
 
-//        	write_zsreg(chan, R9, nine);
-               	wbflush();
-		RECOVERY_DELAY;
+		while (loops && !(read_zsreg(chan, 0) & Tx_BUF_EMP))
+			loops--;
 
-                return ret;
-        }
+		if (loops) {
+			write_zsdata(chan, ch);
+			ret = 0;
+		} else
+			ret = -EAGAIN;
 
-	return -ENODEV;
+		return ret;
+	} else
+		return -ENODEV;
 }
 
 static int
-zs_poll_rx_char(struct dec_serial *info)
+zs_poll_rx_char(void *handle)
 {
+	struct dec_serial *info = handle;
         struct dec_zschannel *chan = info->zs_channel;
         int    ret;
 
 	if(chan) {
                 int loops = 10000;
 
-                while((read_zsreg(chan, 0) & Rx_CH_AV) == 0)
-		        loops--;
+		while (loops && !(read_zsreg(chan, 0) & Rx_CH_AV))
+			loops--;
 
                 if (loops)
                         ret = read_zsdata(chan);
                 else
                         ret = -EAGAIN;
 
-                return ret;
-        } else
-                return -ENODEV;
+		return ret;
+	} else
+		return -ENODEV;
 }
 
-unsigned int register_zs_hook(unsigned int channel, struct zs_hook *hook)
+int register_zs_hook(unsigned int channel, struct dec_serial_hook *hook)
 {
 	struct dec_serial *info = &zs_soft[channel];
 
@@ -1970,22 +1916,15 @@
 
 		return 0;
 	} else {
-		info->hook = hook;
-
-		if (zs_chain == 0)
-			probe_sccs();
-
-		if (!(info->flags & ZILOG_INITIALIZED))
-			zs_startup(info);
-
 		hook->poll_rx_char = zs_poll_rx_char;
 		hook->poll_tx_char = zs_poll_tx_char;
+		info->hook = hook;
 
 		return 1;
 	}
 }
 
-unsigned int unregister_zs_hook(unsigned int channel)
+int unregister_zs_hook(unsigned int channel)
 {
 	struct dec_serial *info = &zs_soft[channel];
 
@@ -2004,7 +1943,7 @@
  * Serial console driver
  * ------------------------------------------------------------
  */
-#ifdef CONFIG_SERIAL_CONSOLE
+#ifdef CONFIG_SERIAL_DEC_CONSOLE
 
 
 /*
@@ -2041,11 +1980,13 @@
 static int __init serial_console_setup(struct console *co, char *options)
 {
 	struct dec_serial *info;
-	int	baud = 9600;
-	int	bits = 8;
-	int	parity = 'n';
-	int	cflag = CREAD | HUPCL | CLOCAL;
-	char	*s;
+	int baud = 9600;
+	int bits = 8;
+	int parity = 'n';
+	int cflag = CREAD | HUPCL | CLOCAL;
+	int clk_divisor = 16;
+	int brg;
+	char *s;
 	unsigned long flags;
 
 	if(!BUS_PRESENT)
@@ -2097,6 +2038,10 @@
 	case 9600:
 	default:
 		cflag |= B9600;
+		/*
+		 * Set this to a sane value to prevent a divide error.
+		 */
+		baud  = 9600;
 		break;
 	}
 	switch(bits) {
@@ -2117,43 +2062,64 @@
 		break;
 	}
 	co->cflag = cflag;
-#if 1 
+
 	save_and_cli(flags);
 
 	/*
+	 * Set up the baud rate generator.
+	 */
+	brg = BPS_TO_BRG(baud, zs_parms->clock / clk_divisor);
+	info->zs_channel->curregs[R12] = (brg & 255);
+	info->zs_channel->curregs[R13] = ((brg >> 8) & 255);
+
+	/*
+	 * Set byte size and parity.
+	 */
+	if (bits == 7) {
+		info->zs_channel->curregs[R3] |= Rx7;
+		info->zs_channel->curregs[R5] |= Tx7;
+	} else {
+		info->zs_channel->curregs[R3] |= Rx8;
+		info->zs_channel->curregs[R5] |= Tx8;
+	}
+	if (cflag & PARENB) {
+		info->zs_channel->curregs[R4] |= PAR_ENA;
+	}
+	if (!(cflag & PARODD)) {
+		info->zs_channel->curregs[R4] |= PAR_EVEN;
+	}
+	info->zs_channel->curregs[R4] |= SB1;
+
+	/*
 	 * Turn on RTS and DTR.
 	 */
 	zs_rtsdtr(info, RTS | DTR, 1);
 
 	/*
-	 * Finally, enable sequencing
+	 * Finally, enable sequencing.
 	 */
-	info->zs_channel->curregs[3] |= (RxENABLE | Rx8);
-	info->zs_channel->curregs[5] |= (TxENAB | Tx8);
-	info->zs_channel->curregs[9] |= (VIS);
-	write_zsreg(info->zs_channel, 3, info->zs_channel->curregs[3]);
-	write_zsreg(info->zs_channel, 5, info->zs_channel->curregs[5]);
-	write_zsreg(info->zs_channel, 9, info->zs_channel->curregs[9]);
+	info->zs_channel->curregs[R3] |= RxENABLE;
+	info->zs_channel->curregs[R5] |= TxENAB;
 
 	/*
 	 * Clear the interrupt registers.
 	 */
-	write_zsreg(info->zs_channel, 0, ERR_RES);
-	write_zsreg(info->zs_channel, 0, RES_H_IUS);
+	write_zsreg(info->zs_channel, R0, ERR_RES);
+	write_zsreg(info->zs_channel, R0, RES_H_IUS);
 
 	/*
-	 * Set the speed of the serial port
+	 * Load up the new values.
 	 */
-	change_speed(info);
+	load_zsregs(info->zs_channel, info->zs_channel->curregs);
 
 	/* Save the current value of RR0 */
-	info->read_reg_zero = read_zsreg(info->zs_channel, 0);
+	info->read_reg_zero = read_zsreg(info->zs_channel, R0);
 
-	zs_soft[co->index].clk_divisor = 16;
+	zs_soft[co->index].clk_divisor = clk_divisor;
 	zs_soft[co->index].zs_baud = get_zsbaud(&zs_soft[co->index]);
 
 	restore_flags(flags);
-#endif
+
 	return 0;
 }
 
@@ -2173,7 +2139,7 @@
 {
 	register_console(&sercons);
 }
-#endif /* ifdef CONFIG_SERIAL_CONSOLE */
+#endif /* ifdef CONFIG_SERIAL_DEC_CONSOLE */
 
 #ifdef CONFIG_KGDB
 struct dec_zschannel *zs_kgdbchan;
@@ -2211,7 +2177,7 @@
 	int one, nine;
 	nine = read_zsreg(chan, 9);
 	if (yes == 1) {
-		one = EXT_INT_ENAB|INT_ALL_Rx;
+		one = EXT_INT_ENAB|RxINT_ALL;
 		nine |= MIE;
 		printk("turning serial ints on\n");
 	} else {
@@ -2223,22 +2189,23 @@
 	write_zsreg(chan, 9, nine);
 }
 
-static int kgdbhook_init_channel(struct dec_serial* info) 
+static int kgdbhook_init_channel(void *handle)
 {
 	return 0;
 }
 
-static void kgdbhook_init_info(struct dec_serial* info)
+static void kgdbhook_init_info(void *handle)
 {
 }
 
-static void kgdbhook_rx_char(struct dec_serial* info, 
-			     unsigned char ch, unsigned char stat)
+static void kgdbhook_rx_char(void *handle, unsigned char ch, unsigned char fl)
 {
+	struct dec_serial *info = handle;
+
+	if (fl != TTY_NORMAL)
+		return;
 	if (ch == 0x03 || ch == '$')
 		breakpoint();
-	if (stat & (Rx_OVR|FRM_ERR|PAR_ERR))
-		write_zsreg(info->zs_channel, 0, ERR_RES);
 }
 
 /* This sets up the serial port we're using, and turns on
@@ -2264,11 +2231,11 @@
  * for /dev/ttyb which is determined in setup_arch() from the
  * boot command line flags.
  */
-struct zs_hook zs_kgdbhook = {
-	init_channel : kgdbhook_init_channel,
-	init_info    : kgdbhook_init_info,
-	cflags       : B38400|CS8|CLOCAL,
-	rx_char      : kgdbhook_rx_char,
+struct dec_serial_hook zs_kgdbhook = {
+	.init_channel	= kgdbhook_init_channel,
+	.init_info	= kgdbhook_init_info,
+	.rx_char	= kgdbhook_rx_char,
+	.cflags		= B38400 | CS8 | CLOCAL,
 }
 
 void __init zs_kgdb_hook(int tty_num)
diff -Nru a/drivers/tc/zs.h b/drivers/tc/zs.h
--- a/drivers/tc/zs.h	2005-03-01 23:38:55 -08:00
+++ b/drivers/tc/zs.h	2005-03-01 23:38:55 -08:00
@@ -1,14 +1,18 @@
 /*
- * macserial.h: Definitions for the Macintosh Z8530 serial driver.
+ * drivers/tc/zs.h: Definitions for the DECstation Z85C30 serial driver.
  *
  * Adapted from drivers/sbus/char/sunserial.h by Paul Mackerras.
+ * Adapted from drivers/macintosh/macserial.h by Harald Koerfgen.
  *
  * Copyright (C) 1996 Paul Mackerras (Paul.Mackerras@cs.anu.edu.au)
  * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 2004  Maciej W. Rozycki
  */
 #ifndef _DECSERIAL_H
 #define _DECSERIAL_H
 
+#include <asm/dec/serial.h>
+
 #define NUM_ZSREGS    16
 
 struct serial_struct {
@@ -89,61 +93,48 @@
 	unsigned char curregs[NUM_ZSREGS];
 };
 
-struct dec_serial;
-
-struct zs_hook {
-	int (*init_channel)(struct dec_serial* info);
-	void (*init_info)(struct dec_serial* info);
-	void (*rx_char)(unsigned char ch, unsigned char stat);
-	int  (*poll_rx_char)(struct dec_serial* info);
-	int  (*poll_tx_char)(struct dec_serial* info,
-			     unsigned char ch);
-	unsigned cflags;
-};
-
 struct dec_serial {
-	struct dec_serial *zs_next;	/* For IRQ servicing chain */
-	struct dec_zschannel *zs_channel; /* Channel registers */
-	struct dec_zschannel *zs_chan_a;	/* A side registers */
-	unsigned char read_reg_zero;
-
-	char soft_carrier;  /* Use soft carrier on this channel */
-	char break_abort;   /* Is serial console in, so process brk/abrt */
-	struct zs_hook *hook;  /* Hook on this channel */
-	char is_cons;       /* Is this our console. */
-	unsigned char tx_active; /* character is being xmitted */
-	unsigned char tx_stopped; /* output is suspended */
-
-	/* We need to know the current clock divisor
-	 * to read the bps rate the chip has currently
-	 * loaded.
+	struct dec_serial	*zs_next;	/* For IRQ servicing chain.  */
+	struct dec_zschannel	*zs_channel;	/* Channel registers.  */
+	struct dec_zschannel	*zs_chan_a;	/* A side registers.  */
+	unsigned char		read_reg_zero;
+
+	struct dec_serial_hook	*hook;		/* Hook on this channel.  */
+	int			tty_break;	/* Set on BREAK condition.  */
+	int			is_cons;	/* Is this our console.  */
+	int			tx_active;	/* Char is being xmitted.  */
+	int			tx_stopped;	/* Output is suspended.  */
+
+	/*
+	 * 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;
+	int			clk_divisor;	/* May be 1, 16, 32, or 64.  */
+	int			zs_baud;
 
-	char change_needed;
+	char			change_needed;
 
 	int			magic;
 	int			baud_base;
 	int			port;
 	int			irq;
-	int			flags; 		/* defined in tty.h */
-	int			type; 		/* UART type */
+	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			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 */
+	int			count;		/* # of fds on device.  */
+	int			blocked_open;	/* # of blocked opens.  */
 	unsigned char 		*xmit_buf;
 	int			xmit_head;
 	int			xmit_tail;
@@ -219,8 +210,9 @@
 
 #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	RxINT_ALL	0x10	/* Int on all Rx Characters or error */
+#define	RxINT_ERR	0x18	/* Int on error only */
+#define	RxINT_MASK	0x18
 
 #define	WT_RDY_RT	0x20	/* Wait/Ready on R/T */
 #define	WT_FN_RDYFN	0x40	/* Wait/FN/Ready FN */
diff -Nru a/drivers/telephony/ixj.c b/drivers/telephony/ixj.c
--- a/drivers/telephony/ixj.c	2005-03-01 23:38:51 -08:00
+++ b/drivers/telephony/ixj.c	2005-03-01 23:38:51 -08:00
@@ -285,7 +285,7 @@
 static int hertz = HZ;
 static int samplerate = 100;
 
-MODULE_PARM(ixjdebug, "i");
+module_param(ixjdebug, int, 0);
 
 /************************************************************************
 *
@@ -406,14 +406,10 @@
 	return 0;
 }
 
-static IXJ_REGFUNC ixj_DownloadG729 = &Stub;
-static IXJ_REGFUNC ixj_DownloadTS85 = &Stub;
 static IXJ_REGFUNC ixj_PreRead = &Stub;
 static IXJ_REGFUNC ixj_PostRead = &Stub;
 static IXJ_REGFUNC ixj_PreWrite = &Stub;
 static IXJ_REGFUNC ixj_PostWrite = &Stub;
-static IXJ_REGFUNC ixj_PreIoctl = &Stub;
-static IXJ_REGFUNC ixj_PostIoctl = &Stub;
 
 static void ixj_read_frame(IXJ *j);
 static void ixj_write_frame(IXJ *j);
@@ -792,97 +788,6 @@
 	return 0;
 }
 
-static int ixj_register(int index, IXJ_REGFUNC regfunc)
-{
-	int cnt;
-	int retval = 0;
-	switch (index) {
-	case G729LOADER:
-		ixj_DownloadG729 = regfunc;
-		for (cnt = 0; cnt < IXJMAX; cnt++) {
-			IXJ *j = get_ixj(cnt);
-			while(test_and_set_bit(cnt, (void *)&j->busyflags) != 0) {
-				set_current_state(TASK_INTERRUPTIBLE);
-				schedule_timeout(1);
-			}
-			ixj_DownloadG729(j, 0L);
-			clear_bit(cnt, &j->busyflags);
-		}
-		break;
-	case TS85LOADER:
-		ixj_DownloadTS85 = regfunc;
-		for (cnt = 0; cnt < IXJMAX; cnt++) {
-			IXJ *j = get_ixj(cnt);
-			while(test_and_set_bit(cnt, (void *)&j->busyflags) != 0) {
-				set_current_state(TASK_INTERRUPTIBLE);
-				schedule_timeout(1);
-			}
-			ixj_DownloadTS85(j, 0L);
-			clear_bit(cnt, &j->busyflags);
-		}
-		break;
-	case PRE_READ:
-		ixj_PreRead = regfunc;
-		break;
-	case POST_READ:
-		ixj_PostRead = regfunc;
-		break;
-	case PRE_WRITE:
-		ixj_PreWrite = regfunc;
-		break;
-	case POST_WRITE:
-		ixj_PostWrite = regfunc;
-		break;
-	case PRE_IOCTL:
-		ixj_PreIoctl = regfunc;
-		break;
-	case POST_IOCTL:
-		ixj_PostIoctl = regfunc;
-		break;
-	default:
-		retval = 1;
-	}
-	return retval;
-}
-
-EXPORT_SYMBOL(ixj_register);
-
-static int ixj_unregister(int index)
-{
-	int retval = 0;
-	switch (index) {
-	case G729LOADER:
-		ixj_DownloadG729 = &Stub;
-		break;
-	case TS85LOADER:
-		ixj_DownloadTS85 = &Stub;
-		break;
-	case PRE_READ:
-		ixj_PreRead = &Stub;
-		break;
-	case POST_READ:
-		ixj_PostRead = &Stub;
-		break;
-	case PRE_WRITE:
-		ixj_PreWrite = &Stub;
-		break;
-	case POST_WRITE:
-		ixj_PostWrite = &Stub;
-		break;
-	case PRE_IOCTL:
-		ixj_PreIoctl = &Stub;
-		break;
-	case POST_IOCTL:
-		ixj_PostIoctl = &Stub;
-		break;
-	default:
-		retval = 1;
-	}
-	return retval;
-}
-
-EXPORT_SYMBOL(ixj_unregister);
-
 static void ixj_init_timer(IXJ *j)
 {
 	init_timer(&j->timer);
@@ -2257,7 +2162,7 @@
 	return 0;
 }
 
-int ixj_release(struct inode *inode, struct file *file_p)
+static int ixj_release(struct inode *inode, struct file *file_p)
 {
 	IXJ_TONE ti;
 	int cnt;
@@ -6785,7 +6690,7 @@
 	return fasync_helper(fd, file_p, mode, &j->async_queue);
 }
 
-struct file_operations ixj_fops =
+static struct file_operations ixj_fops =
 {
         .owner          = THIS_MODULE,
         .read           = ixj_enhanced_read,
@@ -7707,8 +7612,8 @@
 	0,
 };
 
-MODULE_PARM(dspio, "1-" __MODULE_STRING(IXJMAX) "i");
-MODULE_PARM(xio, "1-" __MODULE_STRING(IXJMAX) "i");
+module_param_array(dspio, int, NULL, 0);
+module_param_array(xio, int, NULL, 0);
 MODULE_DESCRIPTION("Quicknet VoIP Telephony card module - www.quicknet.net");
 MODULE_AUTHOR("Ed Okerson <eokerson@quicknet.net>");
 MODULE_LICENSE("GPL");
@@ -7735,7 +7640,7 @@
 	return res;
 }
 
-int __init ixj_probe_isapnp(int *cnt)
+static int __init ixj_probe_isapnp(int *cnt)
 {               
 	int probe = 0;
 	int func = 0x110;
@@ -7815,7 +7720,7 @@
 	return probe;
 }
                         
-int __init ixj_probe_isa(int *cnt)
+static int __init ixj_probe_isa(int *cnt)
 {
 	int i, probe;
 
@@ -7839,7 +7744,7 @@
 	return 0;
 }
 
-int __init ixj_probe_pci(int *cnt)
+static int __init ixj_probe_pci(int *cnt)
 {
 	struct pci_dev *pci = NULL;   
 	int i, probe = 0;
diff -Nru a/drivers/telephony/ixj_pcmcia.c b/drivers/telephony/ixj_pcmcia.c
--- a/drivers/telephony/ixj_pcmcia.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/telephony/ixj_pcmcia.c	2005-03-01 23:39:09 -08:00
@@ -69,7 +69,6 @@
 	link->next = dev_list;
 	dev_list = link;
 	client_reg.dev_info = &dev_info;
-	client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
 	client_reg.EventMask =
 	    CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
 	    CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
@@ -313,10 +312,7 @@
 static void ixj_pcmcia_exit(void)
 {
 	pcmcia_unregister_driver(&ixj_driver);
-
-	/* XXX: this really needs to move into generic code.. */
-	while (dev_list != NULL)
-		ixj_detach(dev_list);
+	BUG_ON(dev_list != NULL);
 }
 
 module_init(ixj_pcmcia_init);
diff -Nru a/drivers/usb/Makefile b/drivers/usb/Makefile
--- a/drivers/usb/Makefile	2005-03-01 23:39:16 -08:00
+++ b/drivers/usb/Makefile	2005-03-01 23:39:16 -08:00
@@ -9,7 +9,7 @@
 obj-$(CONFIG_USB_EHCI_HCD)	+= host/
 obj-$(CONFIG_USB_OHCI_HCD)	+= host/
 obj-$(CONFIG_USB_UHCI_HCD)	+= host/
-obj-$(CONFIG_USB_SL811HS)	+= host/
+obj-$(CONFIG_USB_SL811_HCD)	+= host/
 obj-$(CONFIG_ETRAX_USB_HOST)	+= host/
 
 obj-$(CONFIG_USB_ACM)		+= class/
@@ -49,7 +49,6 @@
 obj-$(CONFIG_USB_RTL8150)	+= net/
 obj-$(CONFIG_USB_USBNET)	+= net/
 
-obj-$(CONFIG_USB_DC2XX)		+= image/
 obj-$(CONFIG_USB_HPUSBSCSI)	+= image/
 obj-$(CONFIG_USB_MDC800)	+= image/
 obj-$(CONFIG_USB_MICROTEK)	+= image/
@@ -60,12 +59,12 @@
 obj-$(CONFIG_USB_CYTHERM)	+= misc/
 obj-$(CONFIG_USB_EMI26)		+= misc/
 obj-$(CONFIG_USB_EMI62)		+= misc/
+obj-$(CONFIG_USB_IDMOUSE)	+= misc/
 obj-$(CONFIG_USB_LCD)		+= misc/
 obj-$(CONFIG_USB_LED)		+= misc/
 obj-$(CONFIG_USB_LEGOTOWER)	+= misc/
 obj-$(CONFIG_USB_RIO500)	+= misc/
 obj-$(CONFIG_USB_TEST)		+= misc/
-obj-$(CONFIG_USB_TIGL)		+= misc/
 obj-$(CONFIG_USB_USS720)	+= misc/
 obj-$(CONFIG_USB_PHIDGETSERVO)	+= misc/
 
diff -Nru a/drivers/usb/README b/drivers/usb/README
--- a/drivers/usb/README	2005-03-01 23:39:16 -08:00
+++ b/drivers/usb/README	2005-03-01 23:39:16 -08:00
@@ -1,14 +1,37 @@
+To understand all the Linux-USB framework, you'll use these resources:
+
+    * This source code.  This is necessarily an evolving work, and
+      includes kerneldoc that should help you get a current overview.
+      ("make pdfdocs", and then look at "usb.pdf" for host side and
+      "gadget.pdf" for peripheral side.)  Also, Documentation/usb has
+      more information.
+
+    * The USB 2.0 specification (from www.usb.org), with supplements
+      such as those for USB OTG and the various device classes.
+      The USB specification has a good overview chapter, and USB
+      peripherals conform to the widely known "Chapter 9".
+
+    * Chip specifications for USB controllers.  Examples include
+      host controllers (on PCs, servers, and more); peripheral
+      controllers (in devices with Linux firmware, like printers or
+      cell phones); and hard-wired peripherals like Ethernet adapters.
+
+    * Specifications for other protocols implemented by USB peripheral
+      functions.  Some are vendor-specific; others are vendor-neutral
+      but just standardized outside of the www.usb.org team.
+
 Here is a list of what each subdirectory here is, and what is contained in
 them.
 
 core/		- This is for the core USB host code, including the
-		  usbfs files.
+		  usbfs files and the hub class driver ("khubd").
 
-host/		- This is for all of the USB host drivers.  This
-		  includes UHCI, OHCI, EHCI, and any others that might
-		  be created in the future.
+host/		- This is for USB host controller drivers.  This
+		  includes UHCI, OHCI, EHCI, and others that might
+		  be used with more specialized "embedded" systems.
 
-gadget/		- This is for all of the USB device controller drivers. 
+gadget/		- This is for USB peripheral controller drivers and
+		  the various gadget drivers which talk to them.
 
 
 Individual USB driver directories.  A new driver should be added to the
diff -Nru a/drivers/usb/atm/speedtch.c b/drivers/usb/atm/speedtch.c
--- a/drivers/usb/atm/speedtch.c	2005-03-01 23:39:19 -08:00
+++ b/drivers/usb/atm/speedtch.c	2005-03-01 23:39:19 -08:00
@@ -44,30 +44,10 @@
 
 #include "usb_atm.h"
 
-/*
-#define DEBUG
-#define VERBOSE_DEBUG
-*/
-
-#if !defined (DEBUG) && defined (CONFIG_USB_DEBUG)
-#	define DEBUG
-#endif
-
-#include <linux/usb.h>
-
 #if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE)
 #	define USE_FW_LOADER
 #endif
 
-#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	"Alcatel SpeedTouch USB driver version " DRIVER_VERSION
@@ -514,7 +494,7 @@
 			dbg("speedtch_upload_firmware: write BLOCK1 to modem failed (%d)!", ret);
 			goto fail_release;
 		}
-		dbg("speedtch_upload_firmware: BLOCK1 uploaded (%d bytes)", fw1->size);
+		dbg("speedtch_upload_firmware: BLOCK1 uploaded (%zu bytes)", fw1->size);
 	}
 
 	/* USB led blinking green, ADSL led off */
@@ -542,7 +522,7 @@
 			goto fail_release;
 		}
 	}
-	dbg("speedtch_upload_firmware: BLOCK3 uploaded (%d bytes)", fw2->size);
+	dbg("speedtch_upload_firmware: BLOCK3 uploaded (%zu bytes)", fw2->size);
 
 	/* USB led static green, ADSL led static red */
 
@@ -594,7 +574,7 @@
 				  const struct firmware **fw_p)
 {
 	char buf[24];
-	const u16 bcdDevice = instance->u.usb_dev->descriptor.bcdDevice;
+	const u16 bcdDevice = le16_to_cpu(instance->u.usb_dev->descriptor.bcdDevice);
 	const u8 major_revision = bcdDevice >> 8;
 	const u8 minor_revision = bcdDevice & 0xff;
 
@@ -737,11 +717,12 @@
 	int ret, i;
 	char buf7[SIZE_7];
 
-	dbg("speedtch_usb_probe: trying device with vendor=0x%x, product=0x%x, ifnum %d", dev->descriptor.idVendor, dev->descriptor.idProduct, ifnum);
+	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);
 
-	if ((dev->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC) ||
-	    (dev->descriptor.idVendor != SPEEDTOUCH_VENDORID) ||
-	    (dev->descriptor.idProduct != SPEEDTOUCH_PRODUCTID) || (ifnum != 1))
+	if ((dev->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC) || 
+	    (ifnum != 1))
 		return -ENODEV;
 
 	dbg("speedtch_usb_probe: device accepted");
diff -Nru a/drivers/usb/atm/usb_atm.c b/drivers/usb/atm/usb_atm.c
--- a/drivers/usb/atm/usb_atm.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/usb/atm/usb_atm.c	2005-03-01 23:39:17 -08:00
@@ -83,23 +83,6 @@
 
 #include "usb_atm.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
-
 #ifdef VERBOSE_DEBUG
 static int udsl_print_packet(const unsigned char *data, int len);
 #define PACKETDEBUG(arg...)	udsl_print_packet (arg)
diff -Nru a/drivers/usb/atm/usb_atm.h b/drivers/usb/atm/usb_atm.h
--- a/drivers/usb/atm/usb_atm.h	2005-03-01 23:39:08 -08:00
+++ b/drivers/usb/atm/usb_atm.h	2005-03-01 23:39:08 -08:00
@@ -21,12 +21,29 @@
  *
  ******************************************************************************/
 
+#include <linux/config.h>
 #include <linux/list.h>
-#include <linux/usb.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
diff -Nru a/drivers/usb/class/audio.c b/drivers/usb/class/audio.c
--- a/drivers/usb/class/audio.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/usb/class/audio.c	2005-03-01 23:39:17 -08:00
@@ -2971,7 +2971,8 @@
 			}
 			format = (fmt[5] == 2) ? (AFMT_U16_LE | AFMT_U8) : (AFMT_S16_LE | AFMT_S8);
 			/* Dallas DS4201 workaround */
-			if (dev->descriptor.idVendor == 0x04fa && dev->descriptor.idProduct == 0x4201)
+			if (le16_to_cpu(dev->descriptor.idVendor) == 0x04fa && 
+			    le16_to_cpu(dev->descriptor.idProduct) == 0x4201)
 				format = (AFMT_S16_LE | AFMT_S8);
 			fmt = find_csinterface_descriptor(buffer, buflen, NULL, FORMAT_TYPE, asifout, i);
 			if (!fmt) {
@@ -3716,7 +3717,7 @@
 		if (alt->desc.bNumEndpoints > 0) {
 			/* Check all endpoints; should they all have a bandwidth of 0 ? */
 			for (k = 0; k < alt->desc.bNumEndpoints; k++) {
-				if (alt->endpoint[k].desc.wMaxPacketSize > 0) {
+				if (le16_to_cpu(alt->endpoint[k].desc.wMaxPacketSize) > 0) {
 					printk(KERN_ERR "usbaudio: device %d audiocontrol interface %u endpoint %d does not have 0 bandwidth at alt[0]\n", dev->devnum, ctrlif, k);
 					break;
 				}
@@ -3800,7 +3801,7 @@
 	 * find which configuration number is active
 	 */
 	buffer = dev->rawdescriptors[dev->actconfig - dev->config];
-	buflen = dev->actconfig->desc.wTotalLength;
+	buflen = le16_to_cpu(dev->actconfig->desc.wTotalLength);
 	s = usb_audio_parsecontrol(dev, buffer, buflen, intf->altsetting->desc.bInterfaceNumber);
 	if (s) {
 		usb_set_intfdata (intf, s);
diff -Nru a/drivers/usb/class/bluetty.c b/drivers/usb/class/bluetty.c
--- a/drivers/usb/class/bluetty.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/usb/class/bluetty.c	2005-03-01 23:39:08 -08:00
@@ -1086,7 +1086,7 @@
 		err("No free urbs available");
 		goto probe_error;
 	}
-	bluetooth->bulk_in_buffer_size = buffer_size = endpoint->wMaxPacketSize;
+	bluetooth->bulk_in_buffer_size = buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
 	bluetooth->bulk_in_endpointAddress = endpoint->bEndpointAddress;
 	bluetooth->bulk_in_buffer = kmalloc (buffer_size, GFP_KERNEL);
 	if (!bluetooth->bulk_in_buffer) {
@@ -1098,7 +1098,7 @@
 
 	endpoint = bulk_out_endpoint[0];
 	bluetooth->bulk_out_endpointAddress = endpoint->bEndpointAddress;
-	bluetooth->bulk_out_buffer_size = endpoint->wMaxPacketSize * 2;
+	bluetooth->bulk_out_buffer_size = le16_to_cpu(endpoint->wMaxPacketSize) * 2;
 
 	endpoint = interrupt_in_endpoint[0];
 	bluetooth->interrupt_in_urb = usb_alloc_urb(0, GFP_KERNEL);
@@ -1106,7 +1106,7 @@
 		err("No free urbs available");
 		goto probe_error;
 	}
-	bluetooth->interrupt_in_buffer_size = buffer_size = endpoint->wMaxPacketSize;
+	bluetooth->interrupt_in_buffer_size = buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
 	bluetooth->interrupt_in_endpointAddress = endpoint->bEndpointAddress;
 	bluetooth->interrupt_in_interval = endpoint->bInterval;
 	bluetooth->interrupt_in_buffer = kmalloc (buffer_size, GFP_KERNEL);
diff -Nru a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
--- a/drivers/usb/class/cdc-acm.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/usb/class/cdc-acm.c	2005-03-01 23:39:07 -08:00
@@ -261,18 +261,24 @@
 
 static int acm_tty_open(struct tty_struct *tty, struct file *filp)
 {
-	struct acm *acm = acm_table[tty->index];
+	struct acm *acm;
+	int rv = -EINVAL;
 	dbg("Entering acm_tty_open.\n");
+	
+	down(&open_sem);
 
+	acm = acm_table[tty->index];
 	if (!acm || !acm->dev)
-		return -EINVAL;
+		goto err_out;
+	else
+		rv = 0;
 
 	tty->driver_data = acm;
 	acm->tty = tty;
 
-        down(&open_sem);
 
-	if (acm->used) {
+
+	if (acm->used++) {
 		goto done;
         }
 
@@ -296,15 +302,16 @@
 	tty->low_latency = 1;
 
 done:
-	acm->used++;
+err_out:
 	up(&open_sem);
-	return 0;
+	return rv;
 
 full_bailout:
 	usb_kill_urb(acm->readurb);
 bail_out_and_unlink:
 	usb_kill_urb(acm->ctrlurb);
 bail_out:
+	acm->used--;
 	up(&open_sem);
 	return -EIO;
 }
@@ -532,26 +539,36 @@
 	u8 call_management_function = 0;
 	int call_interface_num = -1;
 	int data_interface_num;
+	unsigned long quirks;
 
+	/* handle quirks deadly to normal probing*/
+	quirks = (unsigned long)id->driver_info;
+	if (quirks == NO_UNION_NORMAL) {
+		data_interface = usb_ifnum_to_if(usb_dev, 1);
+		control_interface = usb_ifnum_to_if(usb_dev, 0);
+		goto skip_normal_probe;
+	}
+	
+	/* normal probing*/
 	if (!buffer) {
-		err("Wierd descriptor references");
+		err("Wierd descriptor references\n");
 		return -EINVAL;
 	}
 
 	if (!buflen) {
 		if (intf->cur_altsetting->endpoint->extralen && intf->cur_altsetting->endpoint->extra) {
-			dev_dbg(&intf->dev,"Seeking extra descriptors on endpoint");
+			dev_dbg(&intf->dev,"Seeking extra descriptors on endpoint\n");
 			buflen = intf->cur_altsetting->endpoint->extralen;
 			buffer = intf->cur_altsetting->endpoint->extra;
 		} else {
-			err("Zero length descriptor references");
+			err("Zero length descriptor references\n");
 			return -EINVAL;
 		}
 	}
 
 	while (buflen > 0) {
 		if (buffer [1] != USB_DT_CS_INTERFACE) {
-			err("skipping garbage");
+			err("skipping garbage\n");
 			goto next_desc;
 		}
 
@@ -604,13 +621,10 @@
 		}
 	}
 	
-		if (data_interface_num != call_interface_num)
-			dev_dbg(&intf->dev,"Seperate call control interface. That is not fully supported.");
+	if (data_interface_num != call_interface_num)
+		dev_dbg(&intf->dev,"Seperate call control interface. That is not fully supported.\n");
 
-	if (usb_interface_claimed(data_interface)) { /* valid in this context */
-		dev_dbg(&intf->dev,"The data interface isn't available\n");
-		return -EBUSY;
-	}
+skip_normal_probe:
 
 	/*workaround for switched interfaces */
 	if (data_interface->cur_altsetting->desc.bInterfaceClass != CDC_DATA_INTERFACE_TYPE) {
@@ -625,6 +639,13 @@
 			return -EINVAL;
 		}
 	}
+	
+	if (usb_interface_claimed(data_interface)) { /* valid in this context */
+		dev_dbg(&intf->dev,"The data interface isn't available\n");
+		return -EBUSY;
+	}
+
+
 	if (data_interface->cur_altsetting->desc.bNumEndpoints < 2)
 		return -EINVAL;
 
@@ -657,9 +678,9 @@
 	}
 	memset(acm, 0, sizeof(struct acm));
 
-	ctrlsize = epctrl->wMaxPacketSize;
-	readsize = epread->wMaxPacketSize;
-	acm->writesize = epwrite->wMaxPacketSize;
+	ctrlsize = le16_to_cpu(epctrl->wMaxPacketSize);
+	readsize = le16_to_cpu(epread->wMaxPacketSize);
+	acm->writesize = le16_to_cpu(epwrite->wMaxPacketSize);
 	acm->control = control_interface;
 	acm->data = data_interface;
 	acm->minor = minor;
@@ -805,6 +826,10 @@
  */
 
 static struct usb_device_id acm_ids[] = {
+	/* quirky and broken devices */
+	{ USB_DEVICE(0x0870, 0x0001), /* Metricom GS Modem */
+	.driver_info = NO_UNION_NORMAL, /* has no union descriptor */
+	},
 	/* control interfaces with various AT-command sets */
 	{ USB_INTERFACE_INFO(USB_CLASS_COMM, 2, 1) },
 	{ USB_INTERFACE_INFO(USB_CLASS_COMM, 2, 2) },
diff -Nru a/drivers/usb/class/cdc-acm.h b/drivers/usb/class/cdc-acm.h
--- a/drivers/usb/class/cdc-acm.h	2005-03-01 23:39:17 -08:00
+++ b/drivers/usb/class/cdc-acm.h	2005-03-01 23:39:17 -08:00
@@ -125,4 +125,5 @@
 
 #define CDC_DATA_INTERFACE_TYPE	0x0a
 
-
+/* constants describing various quirks and errors */
+#define NO_UNION_NORMAL			1
diff -Nru a/drivers/usb/class/usb-midi.c b/drivers/usb/class/usb-midi.c
--- a/drivers/usb/class/usb-midi.c	2005-03-01 23:38:51 -08:00
+++ b/drivers/usb/class/usb-midi.c	2005-03-01 23:38:51 -08:00
@@ -1306,8 +1306,8 @@
 		return NULL;
 	}
 	u->deviceName = NULL;
-	u->idVendor = d->descriptor.idVendor;
-	u->idProduct = d->descriptor.idProduct;
+	u->idVendor = le16_to_cpu(d->descriptor.idVendor);
+	u->idProduct = le16_to_cpu(d->descriptor.idProduct);
 	u->interface = ifnum;
 	u->altSetting = altSetting;
 	u->in[0].endpoint = -1;
@@ -1661,11 +1661,11 @@
 		} 
 		/* Failsafe */
 		if ( !u->deviceName[0] ) {
-			if ( d->descriptor.idVendor == USB_VENDOR_ID_ROLAND ) {
+			if (le16_to_cpu(d->descriptor.idVendor) == USB_VENDOR_ID_ROLAND ) {
 				strcpy(u->deviceName, "Unknown Roland");
-			} else if ( d->descriptor.idVendor == USB_VENDOR_ID_STEINBERG  ) {
+			} else if (le16_to_cpu(d->descriptor.idVendor) == USB_VENDOR_ID_STEINBERG  ) {
 				strcpy(u->deviceName, "Unknown Steinberg");
-			} else if ( d->descriptor.idVendor == USB_VENDOR_ID_YAMAHA ) {
+			} else if (le16_to_cpu(d->descriptor.idVendor) == USB_VENDOR_ID_YAMAHA ) {
 				strcpy(u->deviceName, "Unknown Yamaha");
 			} else {
 				strcpy(u->deviceName, "Unknown");
@@ -1782,7 +1782,7 @@
 	int alts=-1;
 	int ret;
 
-	if (d->descriptor.idVendor != USB_VENDOR_ID_YAMAHA) {
+	if (le16_to_cpu(d->descriptor.idVendor) != USB_VENDOR_ID_YAMAHA) {
 		return -EINVAL;
 	}
 
@@ -1799,11 +1799,12 @@
 	}
 
 	printk(KERN_INFO "usb-midi: Found YAMAHA USB-MIDI device on dev %04x:%04x, iface %d\n",
-	       d->descriptor.idVendor, d->descriptor.idProduct, ifnum);
+	       le16_to_cpu(d->descriptor.idVendor),
+	       le16_to_cpu(d->descriptor.idProduct), ifnum);
 
 	i = d->actconfig - d->config;
 	buffer = d->rawdescriptors[i];
-	bufSize = d->actconfig->desc.wTotalLength;
+	bufSize = le16_to_cpu(d->actconfig->desc.wTotalLength);
 
 	u = parse_descriptor( d, buffer, bufSize, ifnum, alts, 1);
 	if ( u == NULL ) {
@@ -1833,8 +1834,8 @@
 	for ( i=0; i<VENDOR_SPECIFIC_USB_MIDI_DEVICES ; i++ ) {
 		u=&(usb_midi_devices[i]);
     
-		if ( d->descriptor.idVendor != u->idVendor ||
-		     d->descriptor.idProduct != u->idProduct ||
+		if ( le16_to_cpu(d->descriptor.idVendor) != u->idVendor ||
+		     le16_to_cpu(d->descriptor.idProduct) != u->idProduct ||
 		     ifnum != u->interface )
 			continue;
 
@@ -1875,7 +1876,8 @@
 	}
 
 	printk(KERN_INFO "usb-midi: Found MIDISTREAMING on dev %04x:%04x, iface %d\n",
-	       d->descriptor.idVendor, d->descriptor.idProduct, ifnum);
+	       le16_to_cpu(d->descriptor.idVendor), 
+	       le16_to_cpu(d->descriptor.idProduct), ifnum);
 
 
 	/* From USB Spec v2.0, Section 9.5.
@@ -1890,7 +1892,7 @@
 
 	i = d->actconfig - d->config;
 	buffer = d->rawdescriptors[i];
-	bufSize = d->actconfig->desc.wTotalLength;
+	bufSize = le16_to_cpu(d->actconfig->desc.wTotalLength);
 
 	u = parse_descriptor( d, buffer, bufSize, ifnum, alts, 0);
 	if ( u == NULL ) {
@@ -1915,8 +1917,8 @@
 {
 	struct usb_midi_device u;
 
-	if ( d->descriptor.idVendor != uvendor ||
-	     d->descriptor.idProduct != uproduct ||
+	if ( le16_to_cpu(d->descriptor.idVendor) != uvendor ||
+	     le16_to_cpu(d->descriptor.idProduct) != uproduct ||
 	     ifnum != uinterface ) {
 		return -EINVAL;
 	}
diff -Nru a/drivers/usb/class/usb-midi.h b/drivers/usb/class/usb-midi.h
--- a/drivers/usb/class/usb-midi.h	2005-03-01 23:38:59 -08:00
+++ b/drivers/usb/class/usb-midi.h	2005-03-01 23:38:59 -08:00
@@ -63,8 +63,8 @@
 struct usb_midi_device {
 	char  *deviceName;
 
-	int    idVendor;
-	int    idProduct;
+	u16    idVendor;
+	u16    idProduct;
 	int    interface;
 	int    altSetting; /* -1: auto detect */
 
diff -Nru a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
--- a/drivers/usb/class/usblp.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/usb/class/usblp.c	2005-03-01 23:38:53 -08:00
@@ -527,7 +527,7 @@
 
 			case IOCNR_HP_SET_CHANNEL:
 				if (_IOC_DIR(cmd) != _IOC_WRITE ||
-				    usblp->dev->descriptor.idVendor != 0x03F0 ||
+				    le16_to_cpu(usblp->dev->descriptor.idVendor) != 0x03F0 ||
 				    usblp->quirks & USBLP_QUIRK_BIDIR) {
 					retval = -EINVAL;
 					goto done;
@@ -574,8 +574,8 @@
 					goto done;
 				}
 
-				twoints[0] = usblp->dev->descriptor.idVendor;
-				twoints[1] = usblp->dev->descriptor.idProduct;
+				twoints[0] = le16_to_cpu(usblp->dev->descriptor.idVendor);
+				twoints[1] = le16_to_cpu(usblp->dev->descriptor.idProduct);
 				if (copy_to_user((void __user *)arg,
 						(unsigned char *)twoints,
 						sizeof(twoints))) {
@@ -910,15 +910,15 @@
 
 	/* Lookup quirks for this printer. */
 	usblp->quirks = usblp_quirks(
-		dev->descriptor.idVendor,
-		dev->descriptor.idProduct);
+		le16_to_cpu(dev->descriptor.idVendor),
+		le16_to_cpu(dev->descriptor.idProduct));
 
 	/* Analyze and pick initial alternate settings and endpoints. */
 	protocol = usblp_select_alts(usblp);
 	if (protocol < 0) {
 		dbg("incompatible printer-class device 0x%4.4X/0x%4.4X",
-			dev->descriptor.idVendor,
-			dev->descriptor.idProduct);
+			le16_to_cpu(dev->descriptor.idVendor),
+			le16_to_cpu(dev->descriptor.idProduct));
 		goto abort;
 	}
 
@@ -938,8 +938,9 @@
 		usblp->minor, usblp->bidir ? "Bi" : "Uni", dev->devnum,
 		usblp->ifnum,
 		usblp->protocol[usblp->current_protocol].alt_setting,
-		usblp->current_protocol, usblp->dev->descriptor.idVendor,
-		usblp->dev->descriptor.idProduct);
+		usblp->current_protocol,
+		le16_to_cpu(usblp->dev->descriptor.idVendor),
+		le16_to_cpu(usblp->dev->descriptor.idProduct));
 
 	usb_set_intfdata (intf, usblp);
 
@@ -1095,7 +1096,7 @@
 		usblp->writebuf, 0,
 		usblp_bulk_write, usblp);
 
-	usblp->bidir = (usblp->protocol[protocol].epread != 0);
+	usblp->bidir = (usblp->protocol[protocol].epread != NULL);
 	if (usblp->bidir)
 		usb_fill_bulk_urb(usblp->readurb, usblp->dev,
 			usb_rcvbulkpipe(usblp->dev,
diff -Nru a/drivers/usb/core/config.c b/drivers/usb/core/config.c
--- a/drivers/usb/core/config.c	2005-03-01 23:38:51 -08:00
+++ b/drivers/usb/core/config.c	2005-03-01 23:38:51 -08:00
@@ -87,7 +87,7 @@
 	++ifp->desc.bNumEndpoints;
 
 	memcpy(&endpoint->desc, d, n);
-	le16_to_cpus(&endpoint->desc.wMaxPacketSize);
+	INIT_LIST_HEAD(&endpoint->urb_list);
 
 	/* Skip over any Class Specific or Vendor Specific descriptors;
 	 * find the next endpoint or interface descriptor */
@@ -319,7 +319,7 @@
 
 	}	/* for ((buffer2 = buffer, size2 = size); ...) */
 	size = buffer2 - buffer;
-	config->desc.wTotalLength = buffer2 - buffer0;
+	config->desc.wTotalLength = cpu_to_le16(buffer2 - buffer0);
 
 	if (n != nintf)
 		dev_warn(ddev, "config %d has %d interface%s, different from "
diff -Nru a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c
--- a/drivers/usb/core/devices.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/usb/core/devices.c	2005-03-01 23:39:17 -08:00
@@ -180,7 +180,7 @@
 	in = (desc->bEndpointAddress & USB_DIR_IN);
 	dir = in ? 'I' : 'O';
 	if (speed == USB_SPEED_HIGH) {
-		switch (desc->wMaxPacketSize & (0x03 << 11)) {
+		switch (le16_to_cpu(desc->wMaxPacketSize) & (0x03 << 11)) {
 		case 1 << 11:	bandwidth = 2; break;
 		case 2 << 11:	bandwidth = 3; break;
 		}
@@ -227,7 +227,7 @@
 
 	start += sprintf(start, format_endpt, desc->bEndpointAddress, dir,
 			 desc->bmAttributes, type,
-			 (desc->wMaxPacketSize & 0x07ff) * bandwidth,
+			 (le16_to_cpu(desc->wMaxPacketSize) & 0x07ff) * bandwidth,
 			 interval, unit);
 	return start;
 }
@@ -335,10 +335,13 @@
  */
 static char *usb_dump_device_descriptor(char *start, char *end, const struct usb_device_descriptor *desc)
 {
+	u16 bcdUSB = le16_to_cpu(desc->bcdUSB);
+	u16 bcdDevice = le16_to_cpu(desc->bcdDevice);
+
 	if (start > end)
 		return start;
 	start += sprintf (start, format_device1,
-			  desc->bcdUSB >> 8, desc->bcdUSB & 0xff,
+			  bcdUSB >> 8, bcdUSB & 0xff,
 			  desc->bDeviceClass,
 			  class_decode (desc->bDeviceClass),
 			  desc->bDeviceSubClass,
@@ -348,8 +351,9 @@
 	if (start > end)
 		return start;
 	start += sprintf(start, format_device2,
-			 desc->idVendor, desc->idProduct,
-			 desc->bcdDevice >> 8, desc->bcdDevice & 0xff);
+			 le16_to_cpu(desc->idVendor),
+			 le16_to_cpu(desc->idProduct),
+			 bcdDevice >> 8, bcdDevice & 0xff);
 	return start;
 }
 
diff -Nru a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
--- a/drivers/usb/core/devio.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/usb/core/devio.c	2005-03-01 23:38:57 -08:00
@@ -123,13 +123,26 @@
 	}
 
 	if (pos < sizeof(struct usb_device_descriptor)) {
+		struct usb_device_descriptor *desc = kmalloc(sizeof(*desc), GFP_KERNEL);
+		if (!desc) {
+			ret = -ENOMEM;
+			goto err;
+		}
+		memcpy(desc, &dev->descriptor, sizeof(dev->descriptor));
+		le16_to_cpus(&desc->bcdUSB);
+		le16_to_cpus(&desc->idVendor);
+		le16_to_cpus(&desc->idProduct);
+		le16_to_cpus(&desc->bcdDevice);
+
 		len = sizeof(struct usb_device_descriptor) - pos;
 		if (len > nbytes)
 			len = nbytes;
-		if (copy_to_user(buf, ((char *)&dev->descriptor) + pos, len)) {
+		if (copy_to_user(buf, ((char *)desc) + pos, len)) {
+			kfree(desc);
 			ret = -EFAULT;
 			goto err;
 		}
+		kfree(desc);
 
 		*ppos += len;
 		buf += len;
@@ -148,7 +161,7 @@
 			/* The descriptor may claim to be longer than it
 			 * really is.  Here is the actual allocated length. */
 			unsigned alloclen =
-				dev->config[i].desc.wTotalLength;
+				le16_to_cpu(dev->config[i].desc.wTotalLength);
 
 			len = length - (*ppos - pos);
 			if (len > nbytes)
@@ -807,7 +820,7 @@
 {
 	struct usbdevfs_urb uurb;
 	struct usbdevfs_iso_packet_desc *isopkt = NULL;
-	struct usb_endpoint_descriptor *ep_desc;
+	struct usb_host_endpoint *ep;
 	struct async *as;
 	struct usb_ctrlrequest *dr = NULL;
 	unsigned int u, totlen, isofrmlen;
@@ -828,14 +841,17 @@
 		if ((ret = checkintf(ps, ifnum)))
 			return ret;
 	}
+	if ((uurb.endpoint & USB_ENDPOINT_DIR_MASK) != 0)
+		ep = ps->dev->ep_in [uurb.endpoint & USB_ENDPOINT_NUMBER_MASK];
+	else
+		ep = ps->dev->ep_out [uurb.endpoint & USB_ENDPOINT_NUMBER_MASK];
+	if (!ep)
+		return -ENOENT;
 	switch(uurb.type) {
 	case USBDEVFS_URB_TYPE_CONTROL:
-		if ((uurb.endpoint & ~USB_ENDPOINT_DIR_MASK) != 0) {
-			if (!(ep_desc = usb_epnum_to_ep_desc(ps->dev, uurb.endpoint)))
-				return -ENOENT;
-			if ((ep_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_CONTROL)
-				return -EINVAL;
-		}
+		if ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
+				!= USB_ENDPOINT_XFER_CONTROL)
+			return -EINVAL;
 		/* min 8 byte setup packet, max arbitrary */
 		if (uurb.buffer_length < 8 || uurb.buffer_length > PAGE_SIZE)
 			return -EINVAL;
@@ -864,6 +880,12 @@
 		break;
 
 	case USBDEVFS_URB_TYPE_BULK:
+		switch (ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
+		case USB_ENDPOINT_XFER_CONTROL:
+		case USB_ENDPOINT_XFER_ISOC:
+			return -EINVAL;
+		/* allow single-shot interrupt transfers, at bogus rates */
+		}
 		uurb.number_of_packets = 0;
 		if (uurb.buffer_length > MAX_USBFS_BUFFER_SIZE)
 			return -EINVAL;
@@ -875,9 +897,10 @@
 		/* arbitrary limit */
 		if (uurb.number_of_packets < 1 || uurb.number_of_packets > 128)
 			return -EINVAL;
-		if (!(ep_desc = usb_epnum_to_ep_desc(ps->dev, uurb.endpoint)))
-			return -ENOENT;
-		interval = 1 << min (15, ep_desc->bInterval - 1);
+		if ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
+				!= USB_ENDPOINT_XFER_ISOC)
+			return -EINVAL;
+		interval = 1 << min (15, ep->desc.bInterval - 1);
 		isofrmlen = sizeof(struct usbdevfs_iso_packet_desc) * uurb.number_of_packets;
 		if (!(isopkt = kmalloc(isofrmlen, GFP_KERNEL)))
 			return -ENOMEM;
@@ -901,12 +924,13 @@
 
 	case USBDEVFS_URB_TYPE_INTERRUPT:
 		uurb.number_of_packets = 0;
-		if (!(ep_desc = usb_epnum_to_ep_desc(ps->dev, uurb.endpoint)))
-			return -ENOENT;
+		if ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
+				!= USB_ENDPOINT_XFER_INT)
+			return -EINVAL;
 		if (ps->dev->speed == USB_SPEED_HIGH)
-			interval = 1 << min (15, ep_desc->bInterval - 1);
+			interval = 1 << min (15, ep->desc.bInterval - 1);
 		else
-			interval = ep_desc->bInterval;
+			interval = ep->desc.bInterval;
 		if (uurb.buffer_length > MAX_USBFS_BUFFER_SIZE)
 			return -EINVAL;
 		if (!access_ok((uurb.endpoint & USB_DIR_IN) ? VERIFY_WRITE : VERIFY_READ, uurb.buffer, uurb.buffer_length))
@@ -1110,12 +1134,13 @@
 	int			retval = 0;
 	struct usb_interface    *intf = NULL;
 	struct usb_driver       *driver = NULL;
+	int			i;
 
 	/* get input parameters and alloc buffer */
 	if (copy_from_user(&ctrl, arg, sizeof (ctrl)))
 		return -EFAULT;
 	if ((size = _IOC_SIZE (ctrl.ioctl_code)) > 0) {
-		if ((buf = kmalloc (size, GFP_KERNEL)) == 0)
+		if ((buf = kmalloc (size, GFP_KERNEL)) == NULL)
 			return -ENOMEM;
 		if ((_IOC_DIR(ctrl.ioctl_code) & _IOC_WRITE)) {
 			if (copy_from_user (buf, ctrl.data, size)) {
@@ -1141,6 +1166,16 @@
 
 	/* disconnect kernel driver from interface */
 	case USBDEVFS_DISCONNECT:
+
+		/* don't allow the user to unbind the hub driver from
+		 * a hub with children to manage */
+		for (i = 0; i < ps->dev->maxchild; ++i) {
+			if (ps->dev->children[i])
+				retval = -EBUSY;
+		}
+		if (retval)
+			break;
+
 		down_write(&usb_bus_type.subsys.rwsem);
 		if (intf->dev.driver) {
 			driver = to_usb_driver(intf->dev.driver);
@@ -1165,7 +1200,7 @@
 		down_read(&usb_bus_type.subsys.rwsem);
 		if (intf->dev.driver)
 			driver = to_usb_driver(intf->dev.driver);
-		if (driver == 0 || driver->ioctl == 0) {
+		if (driver == NULL || driver->ioctl == NULL) {
 			retval = -ENOTTY;
 		} else {
 			retval = driver->ioctl (intf, ctrl.ioctl_code, buf);
@@ -1181,7 +1216,7 @@
 			&& size > 0
 			&& copy_to_user (ctrl.data, buf, size) != 0)
 		retval = -EFAULT;
-	if (buf != 0)
+	if (buf != NULL)
 		kfree (buf);
 	return retval;
 }
diff -Nru a/drivers/usb/core/file.c b/drivers/usb/core/file.c
--- a/drivers/usb/core/file.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/usb/core/file.c	2005-03-01 23:39:17 -08:00
@@ -30,7 +30,7 @@
 
 #define MAX_USB_MINORS	256
 static struct file_operations *usb_minors[MAX_USB_MINORS];
-static spinlock_t minor_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(minor_lock);
 
 static int usb_open(struct inode * inode, struct file * file)
 {
diff -Nru a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c
--- a/drivers/usb/core/hcd-pci.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/usb/core/hcd-pci.c	2005-03-01 23:38:57 -08:00
@@ -124,7 +124,7 @@
 	// driver->reset(), later on, will transfer device from
 	// control by SMM/BIOS to control by Linux (if needed)
 
-	hcd = driver->hcd_alloc ();
+	hcd = usb_create_hcd (driver);
 	if (hcd == NULL){
 		dev_dbg (&dev->dev, "hcd alloc fail\n");
 		retval = -ENOMEM;
@@ -144,20 +144,16 @@
 	hcd->region = region;
 
 	pci_set_drvdata (dev, hcd);
-	hcd->driver = driver;
-	hcd->description = driver->description;
 	hcd->self.bus_name = pci_name(dev);
 #ifdef CONFIG_PCI_NAMES
 	hcd->product_desc = dev->pretty_name;
-#else
-	if (hcd->product_desc == NULL)
-		hcd->product_desc = "USB Host Controller";
 #endif
 	hcd->self.controller = &dev->dev;
 
 	if ((retval = hcd_buffer_create (hcd)) != 0) {
 clean_3:
-		kfree (hcd);
+		pci_set_drvdata (dev, NULL);
+		usb_put_hcd (hcd);
 		goto clean_2;
 	}
 
@@ -168,7 +164,6 @@
 		dev_err (hcd->self.controller, "can't reset\n");
 		goto clean_3;
 	}
-	hcd->state = USB_STATE_HALT;
 
 	pci_set_master (dev);
 #ifndef __sparc__
@@ -177,7 +172,7 @@
 	bufp = __irq_itoa(dev->irq);
 #endif
 	retval = request_irq (dev->irq, usb_hcd_irq, SA_SHIRQ,
-				hcd->description, hcd);
+				hcd->driver->description, hcd);
 	if (retval != 0) {
 		dev_err (hcd->self.controller,
 				"request interrupt %s failed\n", bufp);
@@ -189,14 +184,6 @@
 		(driver->flags & HCD_MEMORY) ? "pci mem" : "io base",
 		resource);
 
-	usb_bus_init (&hcd->self);
-	hcd->self.op = &usb_hcd_operations;
-	hcd->self.release = &usb_hcd_release;
-	hcd->self.hcpriv = (void *) hcd;
-	init_timer (&hcd->rh_timer);
-
-	INIT_LIST_HEAD (&hcd->dev_list);
-
 	usb_register_bus (&hcd->self);
 
 	if ((retval = driver->start (hcd)) < 0) {
@@ -411,7 +398,7 @@
 		pci_set_power_state (dev, 0);
 	dev->dev.power.power_state = 0;
 	retval = request_irq (dev->irq, usb_hcd_irq, SA_SHIRQ,
-				hcd->description, hcd);
+				hcd->driver->description, hcd);
 	if (retval < 0) {
 		dev_err (hcd->self.controller,
 			"can't restore IRQ after resume!\n");
diff -Nru a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
--- a/drivers/usb/core/hcd.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/usb/core/hcd.c	2005-03-01 23:38:58 -08:00
@@ -33,12 +33,13 @@
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/completion.h>
-#include <linux/uts.h>			/* for UTS_SYSNAME */
+#include <linux/utsname.h>
 #include <linux/mm.h>
 #include <asm/io.h>
 #include <asm/scatterlist.h>
 #include <linux/device.h>
 #include <linux/dma-mapping.h>
+#include <asm/irq.h>
 #include <asm/byteorder.h>
 
 #include <linux/usb.h>
@@ -86,7 +87,6 @@
 
 /* host controllers we manage */
 LIST_HEAD (usb_bus_list);
-EXPORT_SYMBOL_GPL (usb_bus_list);
 
 /* used when allocating bus numbers */
 #define USB_MAXBUS		64
@@ -97,10 +97,9 @@
 
 /* used when updating list of hcds */
 DECLARE_MUTEX (usb_bus_list_lock);	/* exported only for usbfs */
-EXPORT_SYMBOL_GPL (usb_bus_list_lock);
 
 /* used when updating hcd data */
-static spinlock_t hcd_data_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(hcd_data_lock);
 
 /* wait queue for synchronous unlinks */
 DECLARE_WAIT_QUEUE_HEAD(usb_kill_urb_queue);
@@ -120,16 +119,16 @@
 static const u8 usb2_rh_dev_descriptor [18] = {
 	0x12,       /*  __u8  bLength; */
 	0x01,       /*  __u8  bDescriptorType; Device */
-	0x00, 0x02, /*  __u16 bcdUSB; v2.0 */
+	0x00, 0x02, /*  __le16 bcdUSB; v2.0 */
 
 	0x09,	    /*  __u8  bDeviceClass; HUB_CLASSCODE */
 	0x00,	    /*  __u8  bDeviceSubClass; */
 	0x01,       /*  __u8  bDeviceProtocol; [ usb 2.0 single TT ]*/
 	0x08,       /*  __u8  bMaxPacketSize0; 8 Bytes */
 
-	0x00, 0x00, /*  __u16 idVendor; */
- 	0x00, 0x00, /*  __u16 idProduct; */
-	KERNEL_VER, KERNEL_REL, /*  __u16 bcdDevice */
+	0x00, 0x00, /*  __le16 idVendor; */
+ 	0x00, 0x00, /*  __le16 idProduct; */
+	KERNEL_VER, KERNEL_REL, /*  __le16 bcdDevice */
 
 	0x03,       /*  __u8  iManufacturer; */
 	0x02,       /*  __u8  iProduct; */
@@ -143,16 +142,16 @@
 static const u8 usb11_rh_dev_descriptor [18] = {
 	0x12,       /*  __u8  bLength; */
 	0x01,       /*  __u8  bDescriptorType; Device */
-	0x10, 0x01, /*  __u16 bcdUSB; v1.1 */
+	0x10, 0x01, /*  __le16 bcdUSB; v1.1 */
 
 	0x09,	    /*  __u8  bDeviceClass; HUB_CLASSCODE */
 	0x00,	    /*  __u8  bDeviceSubClass; */
 	0x00,       /*  __u8  bDeviceProtocol; [ low/full speeds only ] */
 	0x08,       /*  __u8  bMaxPacketSize0; 8 Bytes */
 
-	0x00, 0x00, /*  __u16 idVendor; */
- 	0x00, 0x00, /*  __u16 idProduct; */
-	KERNEL_VER, KERNEL_REL, /*  __u16 bcdDevice */
+	0x00, 0x00, /*  __le16 idVendor; */
+ 	0x00, 0x00, /*  __le16 idProduct; */
+	KERNEL_VER, KERNEL_REL, /*  __le16 bcdDevice */
 
 	0x03,       /*  __u8  iManufacturer; */
 	0x02,       /*  __u8  iProduct; */
@@ -170,7 +169,7 @@
 	/* one configuration */
 	0x09,       /*  __u8  bLength; */
 	0x02,       /*  __u8  bDescriptorType; Configuration */
-	0x19, 0x00, /*  __u16 wTotalLength; */
+	0x19, 0x00, /*  __le16 wTotalLength; */
 	0x01,       /*  __u8  bNumInterfaces; (1) */
 	0x01,       /*  __u8  bConfigurationValue; */
 	0x00,       /*  __u8  iConfiguration; */
@@ -208,7 +207,7 @@
 	0x05,       /*  __u8  ep_bDescriptorType; Endpoint */
 	0x81,       /*  __u8  ep_bEndpointAddress; IN Endpoint 1 */
  	0x03,       /*  __u8  ep_bmAttributes; Interrupt */
- 	0x02, 0x00, /*  __u16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8) */
+ 	0x02, 0x00, /*  __le16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8) */
 	0xff        /*  __u8  ep_bInterval; (255ms -- usb 2.0 spec) */
 };
 
@@ -217,7 +216,7 @@
 	/* one configuration */
 	0x09,       /*  __u8  bLength; */
 	0x02,       /*  __u8  bDescriptorType; Configuration */
-	0x19, 0x00, /*  __u16 wTotalLength; */
+	0x19, 0x00, /*  __le16 wTotalLength; */
 	0x01,       /*  __u8  bNumInterfaces; (1) */
 	0x01,       /*  __u8  bConfigurationValue; */
 	0x00,       /*  __u8  iConfiguration; */
@@ -255,7 +254,7 @@
 	0x05,       /*  __u8  ep_bDescriptorType; Endpoint */
 	0x81,       /*  __u8  ep_bEndpointAddress; IN Endpoint 1 */
  	0x03,       /*  __u8  ep_bmAttributes; Interrupt */
- 	0x02, 0x00, /*  __u16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8) */
+ 	0x02, 0x00, /*  __le16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8) */
 	0x0c        /*  __u8  ep_bInterval; (256ms -- usb 2.0 spec) */
 };
 
@@ -311,8 +310,8 @@
 
  	// id 3 == vendor description
 	} else if (id == 3) {
-                sprintf (buf, "%s %s %s", UTS_SYSNAME, UTS_RELEASE,
-			hcd->description);
+                sprintf (buf, "%s %s %s",  system_utsname.sysname,
+			system_utsname.release, hcd->driver->description);
 
 	// unsupported IDs --> "protocol stall"
 	} else
@@ -526,7 +525,7 @@
 	/* do nothing if the urb's been unlinked */
 	if (!urb->dev
 			|| urb->status != -EINPROGRESS
-			|| (hcd = urb->dev->bus->hcpriv) == 0) {
+			|| (hcd = urb->dev->bus->hcpriv) == NULL) {
 		spin_unlock (&urb->lock);
 		local_irq_restore (flags);
 		return;
@@ -676,6 +675,9 @@
 	bus->bandwidth_isoc_reqs = 0;
 
 	INIT_LIST_HEAD (&bus->bus_list);
+
+	class_device_initialize(&bus->class_dev);
+	bus->class_dev.class = &usb_host_class;
 }
 EXPORT_SYMBOL (usb_bus_init);
 
@@ -732,9 +734,8 @@
 	}
 
 	snprintf(bus->class_dev.class_id, BUS_ID_SIZE, "usb%d", busnum);
-	bus->class_dev.class = &usb_host_class;
 	bus->class_dev.dev = bus->controller;
-	retval = class_device_register(&bus->class_dev);
+	retval = class_device_add(&bus->class_dev);
 	if (retval) {
 		clear_bit(busnum, busmap.busmap);
 		up(&usb_bus_list_lock);
@@ -807,7 +808,7 @@
 	down (&usb_bus_list_lock);
 	usb_dev->bus->root_hub = usb_dev;
 
-	usb_dev->epmaxpacketin[0] = usb_dev->epmaxpacketout[0] = 64;
+	usb_dev->ep0.desc.wMaxPacketSize = __constant_cpu_to_le16(64);
 	retval = usb_get_device_descriptor(usb_dev, USB_DT_DEVICE_SIZE);
 	if (retval != sizeof usb_dev->descriptor) {
 		usb_dev->bus->root_hub = NULL;
@@ -1018,40 +1019,6 @@
 
 /*-------------------------------------------------------------------------*/
 
-/* called from khubd, or root hub init threads for hcd-private init */
-static int hcd_alloc_dev (struct usb_device *udev)
-{
-	struct hcd_dev		*dev;
-	struct usb_hcd		*hcd;
-	unsigned long		flags;
-
-	if (!udev || udev->hcpriv)
-		return -EINVAL;
-	if (!udev->bus || !udev->bus->hcpriv)
-		return -ENODEV;
-	hcd = udev->bus->hcpriv;
-	if (hcd->state == USB_STATE_QUIESCING)
-		return -ENOLINK;
-
-	dev = (struct hcd_dev *) kmalloc (sizeof *dev, GFP_KERNEL);
-	if (dev == NULL)
-		return -ENOMEM;
-	memset (dev, 0, sizeof *dev);
-
-	INIT_LIST_HEAD (&dev->dev_list);
-	INIT_LIST_HEAD (&dev->urb_list);
-
-	spin_lock_irqsave (&hcd_data_lock, flags);
-	list_add (&dev->dev_list, &hcd->dev_list);
-	// refcount is implicit
-	udev->hcpriv = dev;
-	spin_unlock_irqrestore (&hcd_data_lock, flags);
-
-	return 0;
-}
-
-/*-------------------------------------------------------------------------*/
-
 static void urb_unlink (struct urb *urb)
 {
 	unsigned long		flags;
@@ -1079,10 +1046,12 @@
 {
 	int			status;
 	struct usb_hcd		*hcd = urb->dev->bus->hcpriv;
-	struct hcd_dev		*dev = urb->dev->hcpriv;
+	struct usb_host_endpoint *ep;
 	unsigned long		flags;
 
-	if (!hcd || !dev)
+	ep = (usb_pipein(urb->pipe) ? urb->dev->ep_in : urb->dev->ep_out)
+			[usb_pipeendpoint(urb->pipe)];
+	if (!hcd || !ep)
 		return -ENODEV;
 
 	/*
@@ -1109,7 +1078,7 @@
 	case USB_STATE_RUNNING:
 	case USB_STATE_RESUMING:
 		usb_get_dev (urb->dev);
-		list_add_tail (&urb->urb_list, &dev->urb_list);
+		list_add_tail (&urb->urb_list, &ep->urb_list);
 		status = 0;
 		break;
 	default:
@@ -1163,7 +1132,7 @@
 					    : DMA_TO_DEVICE);
 	}
 
-	status = hcd->driver->urb_enqueue (hcd, urb, mem_flags);
+	status = hcd->driver->urb_enqueue (hcd, ep, urb, mem_flags);
 done:
 	if (unlikely (status)) {
 		urb_unlink (urb);
@@ -1222,7 +1191,7 @@
  */
 static int hcd_unlink_urb (struct urb *urb, int status)
 {
-	struct hcd_dev			*dev;
+	struct usb_host_endpoint	*ep;
 	struct usb_hcd			*hcd = NULL;
 	struct device			*sys = NULL;
 	unsigned long			flags;
@@ -1231,6 +1200,12 @@
 
 	if (!urb)
 		return -EINVAL;
+	if (!urb->dev || !urb->dev->bus)
+		return -ENODEV;
+	ep = (usb_pipein(urb->pipe) ? urb->dev->ep_in : urb->dev->ep_out)
+			[usb_pipeendpoint(urb->pipe)];
+	if (!ep)
+		return -ENODEV;
 
 	/*
 	 * we contend for urb->status with the hcd core,
@@ -1246,15 +1221,9 @@
 	spin_lock_irqsave (&urb->lock, flags);
 	spin_lock (&hcd_data_lock);
 
-	if (!urb->dev || !urb->dev->bus) {
-		retval = -ENODEV;
-		goto done;
-	}
-
-	dev = urb->dev->hcpriv;
 	sys = &urb->dev->dev;
 	hcd = urb->dev->bus->hcpriv;
-	if (!dev || !hcd) {
+	if (hcd == NULL) {
 		retval = -ENODEV;
 		goto done;
 	}
@@ -1266,7 +1235,7 @@
 	WARN_ON (!HCD_IS_RUNNING (hcd->state) && hcd->state != USB_STATE_HALT);
 
 	/* insist the urb is still queued */
-	list_for_each(tmp, &dev->urb_list) {
+	list_for_each(tmp, &ep->urb_list) {
 		if (tmp == &urb->urb_list)
 			break;
 	}
@@ -1283,13 +1252,14 @@
 		goto done;
 	}
 
-	/* PCI IRQ setup can easily be broken so that USB controllers
+	/* IRQ setup can easily be broken so that USB controllers
 	 * never get completion IRQs ... maybe even the ones we need to
-	 * finish unlinking the initial failed usb_set_address().
+	 * finish unlinking the initial failed usb_set_address()
+	 * or device descriptor fetch.
 	 */
 	if (!hcd->saw_irq && hcd->self.root_hub != urb->dev) {
 		dev_warn (hcd->self.controller, "Unlink after no-IRQ?  "
-			"Different ACPI or APIC settings may help."
+			"Controller is probably using the wrong IRQ."
 			"\n");
 		hcd->saw_irq = 1;
 	}
@@ -1318,46 +1288,36 @@
  * the hcd to make sure all endpoint state is gone from hardware. use for
  * set_configuration, set_interface, driver removal, physical disconnect.
  *
- * example:  a qh stored in hcd_dev.ep[], holding state related to endpoint
+ * example:  a qh stored in ep->hcpriv, holding state related to endpoint
  * type, maxpacket size, toggle, halt status, and scheduling.
  */
-static void hcd_endpoint_disable (struct usb_device *udev, int endpoint)
+static void
+hcd_endpoint_disable (struct usb_device *udev, struct usb_host_endpoint *ep)
 {
-	struct hcd_dev	*dev;
-	struct usb_hcd	*hcd;
-	struct urb	*urb;
-	unsigned	epnum = endpoint & USB_ENDPOINT_NUMBER_MASK;
+	struct usb_hcd		*hcd;
+	struct urb		*urb;
 
-	dev = udev->hcpriv;
 	hcd = udev->bus->hcpriv;
 
 	WARN_ON (!HCD_IS_RUNNING (hcd->state) && hcd->state != USB_STATE_HALT);
 
 	local_irq_disable ();
 
-rescan:
-	/* (re)block new requests, as best we can */
-	if (endpoint & USB_DIR_IN)
-		udev->epmaxpacketin [epnum] = 0;
-	else
-		udev->epmaxpacketout [epnum] = 0;
+	/* FIXME move most of this into message.c as part of its
+	 * endpoint disable logic
+	 */
 
-	/* then kill any current requests */
+	/* ep is already gone from udev->ep_{in,out}[]; no more submits */
+rescan:
 	spin_lock (&hcd_data_lock);
-	list_for_each_entry (urb, &dev->urb_list, urb_list) {
-		int	tmp = urb->pipe;
-
-		/* ignore urbs for other endpoints */
-		if (usb_pipeendpoint (tmp) != epnum)
-			continue;
-		/* NOTE assumption that only ep0 is a control endpoint */
-		if (epnum != 0 && ((tmp ^ endpoint) & USB_DIR_IN))
-			continue;
+	list_for_each_entry (urb, &ep->urb_list, urb_list) {
+		int	tmp;
 
 		/* another cpu may be in hcd, spinning on hcd_data_lock
 		 * to giveback() this urb.  the races here should be
 		 * small, but a full fix needs a new "can't submit"
 		 * urb state.
+		 * FIXME urb->reject should allow that...
 		 */
 		if (urb->status != -EINPROGRESS)
 			continue;
@@ -1399,7 +1359,7 @@
 	 */
 	might_sleep ();
 	if (hcd->driver->endpoint_disable)
-		hcd->driver->endpoint_disable (hcd, dev, endpoint);
+		hcd->driver->endpoint_disable (hcd, ep);
 }
 
 /*-------------------------------------------------------------------------*/
@@ -1469,57 +1429,13 @@
 
 /*-------------------------------------------------------------------------*/
 
-/* called by khubd, rmmod, apmd, or other thread for hcd-private cleanup.
- * we're guaranteed that the device is fully quiesced.  also, that each
- * endpoint has been hcd_endpoint_disabled.
- */
-
-static int hcd_free_dev (struct usb_device *udev)
-{
-	struct hcd_dev		*dev;
-	struct usb_hcd		*hcd;
-	unsigned long		flags;
-
-	if (!udev || !udev->hcpriv)
-		return -EINVAL;
-
-	if (!udev->bus || !udev->bus->hcpriv)
-		return -ENODEV;
-
-	// should udev->devnum == -1 ??
-
-	dev = udev->hcpriv;
-	hcd = udev->bus->hcpriv;
-
-	/* device driver problem with refcounts? */
-	if (!list_empty (&dev->urb_list)) {
-		dev_dbg (hcd->self.controller, "free busy dev, %s devnum %d (bug!)\n",
-			hcd->self.bus_name, udev->devnum);
-		return -EINVAL;
-	}
-
-	spin_lock_irqsave (&hcd_data_lock, flags);
-	list_del (&dev->dev_list);
-	udev->hcpriv = NULL;
-	spin_unlock_irqrestore (&hcd_data_lock, flags);
-
-	kfree (dev);
-	return 0;
-}
-
 /*
  * usb_hcd_operations - adapts usb_bus framework to HCD framework (bus glue)
- *
- * When registering a USB bus through the HCD framework code, use this
- * usb_operations vector.  The PCI glue layer does so automatically; only
- * bus glue for non-PCI system busses will need to use this.
  */
-struct usb_operations usb_hcd_operations = {
-	.allocate =		hcd_alloc_dev,
+static struct usb_operations usb_hcd_operations = {
 	.get_frame_number =	hcd_get_frame_number,
 	.submit_urb =		hcd_submit_urb,
 	.unlink_urb =		hcd_unlink_urb,
-	.deallocate =		hcd_free_dev,
 	.buffer_alloc =		hcd_buffer_alloc,
 	.buffer_free =		hcd_buffer_free,
 	.disable =		hcd_endpoint_disable,
@@ -1528,7 +1444,6 @@
 	.hub_resume =		hcd_hub_resume,
 #endif
 };
-EXPORT_SYMBOL (usb_hcd_operations);
 
 /*-------------------------------------------------------------------------*/
 
@@ -1626,15 +1541,54 @@
 	usb_set_device_state(hcd->self.root_hub, USB_STATE_NOTATTACHED);
 	mod_timer(&hcd->rh_timer, jiffies);
 }
-EXPORT_SYMBOL (usb_hc_died);
 
 /*-------------------------------------------------------------------------*/
 
-void usb_hcd_release(struct usb_bus *bus)
+static void hcd_release (struct usb_bus *bus)
 {
 	struct usb_hcd *hcd;
 
-	hcd = container_of (bus, struct usb_hcd, self);
+	hcd = container_of(bus, struct usb_hcd, self);
 	kfree(hcd);
 }
-EXPORT_SYMBOL (usb_hcd_release);
+
+/**
+ * usb_create_hcd - create and initialize an HCD structure
+ * @driver: HC driver that will use this hcd
+ * Context: !in_interrupt()
+ *
+ * Allocate a struct usb_hcd, with extra space at the end for the
+ * HC driver's private data.  Initialize the generic members of the
+ * hcd structure.
+ *
+ * If memory is unavailable, returns NULL.
+ */
+struct usb_hcd *usb_create_hcd (const struct hc_driver *driver)
+{
+	struct usb_hcd *hcd;
+
+	hcd = kcalloc(1, sizeof(*hcd) + driver->hcd_priv_size, GFP_KERNEL);
+	if (!hcd)
+		return NULL;
+
+	usb_bus_init(&hcd->self);
+	hcd->self.op = &usb_hcd_operations;
+	hcd->self.hcpriv = hcd;
+	hcd->self.release = &hcd_release;
+
+	init_timer(&hcd->rh_timer);
+
+	hcd->driver = driver;
+	hcd->product_desc = (driver->product_desc) ? driver->product_desc :
+			"USB Host Controller";
+	hcd->state = USB_STATE_HALT;
+
+	return hcd;
+}
+EXPORT_SYMBOL (usb_create_hcd);
+
+void usb_put_hcd (struct usb_hcd *hcd)
+{
+	usb_bus_put(&hcd->self);
+}
+EXPORT_SYMBOL (usb_put_hcd);
diff -Nru a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h
--- a/drivers/usb/core/hcd.h	2005-03-01 23:38:55 -08:00
+++ b/drivers/usb/core/hcd.h	2005-03-01 23:38:55 -08:00
@@ -63,15 +63,13 @@
 	struct usb_bus		self;		/* hcd is-a bus */
 
 	const char		*product_desc;	/* product/vendor string */
-	const char		*description;	/* "ehci-hcd" etc */
 
 	struct timer_list	rh_timer;	/* drives root hub */
-	struct list_head	dev_list;	/* devices on this bus */
 
 	/*
 	 * hardware info/state
 	 */
-	struct hc_driver	*driver;	/* hw-specific hooks */
+	const struct hc_driver	*driver;	/* hw-specific hooks */
 	unsigned		saw_irq : 1;
 	unsigned		can_wakeup:1;	/* hw supports wakeup? */
 	unsigned		remote_wakeup:1;/* sw should use wakeup? */
@@ -104,6 +102,12 @@
 	 * input size of periodic table to an interrupt scheduler. 
 	 * (ohci 32, uhci 1024, ehci 256/512/1024).
 	 */
+
+	/* The HC driver's private data is stored at the end of
+	 * this structure.
+	 */
+	unsigned long hcd_priv[0]
+			__attribute__ ((aligned (sizeof(unsigned long))));
 };
 
 /* 2.4 does this a bit differently ... */
@@ -113,14 +117,6 @@
 }
 
 
-struct hcd_dev {	/* usb_device.hcpriv points to this */
-	struct list_head	dev_list;	/* on this hcd */
-	struct list_head	urb_list;	/* pending on this dev */
-
-	/* per-configuration HC/HCD state, such as QH or ED */
-	void			*ep[32];
-};
-
 // urb.hcpriv is really hardware-specific
 
 struct hcd_timeout {	/* timeouts we allocate */
@@ -136,8 +132,6 @@
  */
 
 struct usb_operations {
-	int (*allocate)(struct usb_device *);
-	int (*deallocate)(struct usb_device *);
 	int (*get_frame_number) (struct usb_device *usb_dev);
 	int (*submit_urb) (struct urb *urb, int mem_flags);
 	int (*unlink_urb) (struct urb *urb, int status);
@@ -149,7 +143,8 @@
 	void (*buffer_free)(struct usb_bus *bus, size_t size,
 			void *addr, dma_addr_t dma);
 
-	void (*disable)(struct usb_device *udev, int bEndpointAddress);
+	void (*disable)(struct usb_device *udev,
+			struct usb_host_endpoint *ep);
 
 	/* global suspend/resume of bus */
 	int (*hub_suspend)(struct usb_bus *);
@@ -162,6 +157,8 @@
 
 struct hc_driver {
 	const char	*description;	/* "ehci-hcd" etc */
+	const char	*product_desc;	/* product/vendor string */
+	size_t		hcd_priv_size;	/* size of private data */
 
 	/* irq handler */
 	irqreturn_t	(*irq) (struct usb_hcd *hcd, struct pt_regs *regs);
@@ -190,23 +187,16 @@
 	/* return current frame number */
 	int	(*get_frame_number) (struct usb_hcd *hcd);
 
-	/* memory lifecycle */
-	/* Note: The absence of hcd_free reflects a temporary situation;
-	 * in the near future hcd_alloc will disappear as well and all
-	 * allocations/deallocations will be handled by usbcore.  For the
-	 * moment, drivers are required to return a pointer that the core
-	 * can pass to kfree, i.e., the struct usb_hcd must be the _first_
-	 * member of a larger driver-specific structure. */
-	struct usb_hcd	*(*hcd_alloc) (void);
-
 	/* manage i/o requests, device state */
-	int	(*urb_enqueue) (struct usb_hcd *hcd, struct urb *urb,
+	int	(*urb_enqueue) (struct usb_hcd *hcd,
+					struct usb_host_endpoint *ep,
+					struct urb *urb,
 					int mem_flags);
 	int	(*urb_dequeue) (struct usb_hcd *hcd, struct urb *urb);
 
 	/* hw synch, freeing endpoint resources that urb_dequeue can't */
 	void 	(*endpoint_disable)(struct usb_hcd *hcd,
-			struct hcd_dev *dev, int bEndpointAddress);
+			struct usb_host_endpoint *ep);
 
 	/* root hub support */
 	int		(*hub_status_data) (struct usb_hcd *hcd, char *buf);
@@ -221,6 +211,10 @@
 extern void usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb, struct pt_regs *regs);
 extern void usb_bus_init (struct usb_bus *bus);
 
+extern struct usb_hcd *usb_create_hcd (const struct hc_driver *driver);
+extern void usb_put_hcd (struct usb_hcd *hcd);
+
+
 #ifdef CONFIG_PCI
 struct pci_dev;
 struct pci_device_id;
@@ -245,7 +239,6 @@
 	void *addr, dma_addr_t dma);
 
 /* generic bus glue, needed for host controllers that don't use PCI */
-extern struct usb_operations usb_hcd_operations;
 extern irqreturn_t usb_hcd_irq (int irq, void *__hcd, struct pt_regs *r);
 extern void usb_hc_died (struct usb_hcd *hcd);
 
@@ -364,8 +357,6 @@
 
 	return usb_register_root_hub (usb_dev, hcd->self.controller);
 }
-
-extern void usb_hcd_release (struct usb_bus *);
 
 extern void usb_set_device_state(struct usb_device *udev,
 		enum usb_device_state new_state);
diff -Nru a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
--- a/drivers/usb/core/hub.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/usb/core/hub.c	2005-03-01 23:38:57 -08:00
@@ -26,7 +26,6 @@
 #include <linux/ioctl.h>
 #include <linux/usb.h>
 #include <linux/usbdevice_fs.h>
-#include <linux/suspend.h>
 
 #include <asm/semaphore.h>
 #include <asm/uaccess.h>
@@ -39,10 +38,10 @@
 /* Protect struct usb_device->state and ->children members
  * Note: Both are also protected by ->serialize, except that ->state can
  * change to USB_STATE_NOTATTACHED even when the semaphore isn't held. */
-static spinlock_t device_state_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(device_state_lock);
 
 /* khubd's worklist and its lock */
-static spinlock_t hub_event_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(hub_event_lock);
 static LIST_HEAD(hub_event_list);	/* List of hubs needing servicing */
 
 /* Wakes up khubd */
@@ -94,10 +93,10 @@
 }
 #endif
 
-/* for dev_info, dev_dbg, etc */
-static inline struct device *hubdev (struct usb_device *hdev)
+/* Note that hdev or one of its children must be locked! */
+static inline struct usb_hub *hdev_to_hub(struct usb_device *hdev)
 {
-	return &hdev->actconfig->interface[0]->dev;
+	return usb_get_intfdata(hdev->actconfig->interface[0]);
 }
 
 /* USB 2.0 spec Section 11.24.4.5 */
@@ -128,19 +127,21 @@
 /*
  * USB 2.0 spec Section 11.24.2.2
  */
-static int clear_port_feature(struct usb_device *hdev, int port, int feature)
+static int clear_port_feature(struct usb_device *hdev, int port1, int feature)
 {
 	return usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0),
-		USB_REQ_CLEAR_FEATURE, USB_RT_PORT, feature, port, NULL, 0, HZ);
+		USB_REQ_CLEAR_FEATURE, USB_RT_PORT, feature, port1,
+		NULL, 0, HZ);
 }
 
 /*
  * USB 2.0 spec Section 11.24.2.13
  */
-static int set_port_feature(struct usb_device *hdev, int port, int feature)
+static int set_port_feature(struct usb_device *hdev, int port1, int feature)
 {
 	return usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0),
-		USB_REQ_SET_FEATURE, USB_RT_PORT, feature, port, NULL, 0, HZ);
+		USB_REQ_SET_FEATURE, USB_RT_PORT, feature, port1,
+		NULL, 0, HZ);
 }
 
 /*
@@ -148,17 +149,17 @@
  * for info about using port indicators
  */
 static void set_port_led(
-	struct usb_device *hdev,
-	int port,
+	struct usb_hub *hub,
+	int port1,
 	int selector
 )
 {
-	int status = set_port_feature(hdev, (selector << 8) | port,
+	int status = set_port_feature(hub->hdev, (selector << 8) | port1,
 			USB_PORT_FEAT_INDICATOR);
 	if (status < 0)
-		dev_dbg (hubdev (hdev),
+		dev_dbg (hub->intfdev,
 			"port %d indicator %s status %d\n",
-			port,
+			port1,
 			({ char *s; switch (selector) {
 			case HUB_LED_AMBER: s = "amber"; break;
 			case HUB_LED_GREEN: s = "green"; break;
@@ -226,13 +227,13 @@
 		}
 		if (selector != HUB_LED_AUTO)
 			changed = 1;
-		set_port_led(hdev, i + 1, selector);
+		set_port_led(hub, i + 1, selector);
 		hub->indicator[i] = mode;
 	}
 	if (!changed && blinkenlights) {
 		cursor++;
 		cursor %= hub->descriptor->bNbrPorts;
-		set_port_led(hdev, cursor + 1, HUB_LED_GREEN);
+		set_port_led(hub, cursor + 1, HUB_LED_GREEN);
 		hub->indicator[cursor] = INDICATOR_CYCLE;
 		changed++;
 	}
@@ -240,26 +241,40 @@
 		schedule_delayed_work(&hub->leds, LED_CYCLE_PERIOD);
 }
 
+/* use a short timeout for hub/port status fetches */
+#define	USB_STS_TIMEOUT		1
+#define	USB_STS_RETRIES		5
+
 /*
  * USB 2.0 spec Section 11.24.2.6
  */
 static int get_hub_status(struct usb_device *hdev,
 		struct usb_hub_status *data)
 {
-	return usb_control_msg(hdev, usb_rcvctrlpipe(hdev, 0),
-		USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_HUB, 0, 0,
-		data, sizeof(*data), HZ * USB_CTRL_GET_TIMEOUT);
+	int i, status = -ETIMEDOUT;
+
+	for (i = 0; i < USB_STS_RETRIES && status == -ETIMEDOUT; i++) {
+		status = usb_control_msg(hdev, usb_rcvctrlpipe(hdev, 0),
+			USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_HUB, 0, 0,
+			data, sizeof(*data), HZ * USB_STS_TIMEOUT);
+	}
+	return status;
 }
 
 /*
  * USB 2.0 spec Section 11.24.2.7
  */
-static int get_port_status(struct usb_device *hdev, int port,
+static int get_port_status(struct usb_device *hdev, int port1,
 		struct usb_port_status *data)
 {
-	return usb_control_msg(hdev, usb_rcvctrlpipe(hdev, 0),
-		USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_PORT, 0, port,
-		data, sizeof(*data), HZ * USB_CTRL_GET_TIMEOUT);
+	int i, status = -ETIMEDOUT;
+
+	for (i = 0; i < USB_STS_RETRIES && status == -ETIMEDOUT; i++) {
+		status = usb_control_msg(hdev, usb_rcvctrlpipe(hdev, 0),
+			USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_PORT, 0, port1,
+			data, sizeof(*data), HZ * USB_STS_TIMEOUT);
+	}
+	return status;
 }
 
 static void kick_khubd(struct usb_hub *hub)
@@ -291,7 +306,7 @@
 
 	default:		/* presumably an error */
 		/* Cause a hub reset after 10 consecutive errors */
-		dev_dbg (&hub->intf->dev, "transfer --> %d\n", urb->status);
+		dev_dbg (hub->intfdev, "transfer --> %d\n", urb->status);
 		if ((++hub->nerrors < 10) || hub->error)
 			goto resubmit;
 		hub->error = urb->status;
@@ -318,7 +333,7 @@
 
 	if ((status = usb_submit_urb (hub->urb, GFP_ATOMIC)) != 0
 			&& status != -ENODEV && status != -EPERM)
-		dev_err (&hub->intf->dev, "resubmit --> %d\n", status);
+		dev_err (hub->intfdev, "resubmit --> %d\n", status);
 }
 
 /* USB 2.0 spec Section 11.24.2.3 */
@@ -389,7 +404,7 @@
 	 * since each TT has "at least two" buffers that can need it (and
 	 * there can be many TTs per hub).  even if they're uncommon.
 	 */
-	if ((clear = kmalloc (sizeof *clear, SLAB_ATOMIC)) == 0) {
+	if ((clear = kmalloc (sizeof *clear, SLAB_ATOMIC)) == NULL) {
 		dev_err (&udev->dev, "can't save CLEAR_TT_BUFFER state\n");
 		/* FIXME recover somehow ... RESET_TT? */
 		return;
@@ -414,13 +429,13 @@
 
 static void hub_power_on(struct usb_hub *hub)
 {
-	int i;
+	int port1;
 
 	/* if hub supports power switching, enable power on each port */
 	if ((hub->descriptor->wHubCharacteristics & HUB_CHAR_LPSM) < 2) {
-		dev_dbg(&hub->intf->dev, "enabling power on all ports\n");
-		for (i = 0; i < hub->descriptor->bNbrPorts; i++)
-			set_port_feature(hub->hdev, i + 1,
+		dev_dbg(hub->intfdev, "enabling power on all ports\n");
+		for (port1 = 1; port1 <= hub->descriptor->bNbrPorts; port1++)
+			set_port_feature(hub->hdev, port1,
 					USB_PORT_FEAT_POWER);
 	}
 
@@ -446,12 +461,12 @@
 	hub->quiescing = 0;
 	status = usb_submit_urb(hub->urb, GFP_NOIO);
 	if (status < 0)
-		dev_err(&hub->intf->dev, "activate --> %d\n", status);
+		dev_err(hub->intfdev, "activate --> %d\n", status);
 	if (hub->has_indicators && blinkenlights)
 		schedule_delayed_work(&hub->leds, LED_CYCLE_PERIOD);
 
 	/* scan all ports ASAP */
-	hub->event_bits[0] = ~0;
+	hub->event_bits[0] = (1UL << (hub->descriptor->bNbrPorts + 1)) - 1;
 	kick_khubd(hub);
 }
 
@@ -462,7 +477,7 @@
 
 	ret = get_hub_status(hub->hdev, &hub->status->hub);
 	if (ret < 0)
-		dev_err (&hub->intf->dev,
+		dev_err (hub->intfdev,
 			"%s failed (err = %d)\n", __FUNCTION__, ret);
 	else {
 		*status = le16_to_cpu(hub->status->hub.wHubStatus);
@@ -476,7 +491,7 @@
 	struct usb_endpoint_descriptor *endpoint)
 {
 	struct usb_device *hdev = hub->hdev;
-	struct device *hub_dev = &hub->intf->dev;
+	struct device *hub_dev = hub->intfdev;
 	u16 hubstatus, hubchange;
 	unsigned int pipe;
 	int maxp, ret;
@@ -674,7 +689,7 @@
 		hub->indicator [0] = INDICATOR_CYCLE;
 
 	hub_power_on(hub);
-	hub->change_bits[0] = ~0;
+	hub->change_bits[0] = (1UL << (hub->descriptor->bNbrPorts + 1)) - 2;
 	hub_activate(hub);
 	return 0;
 
@@ -735,18 +750,16 @@
 	struct usb_endpoint_descriptor *endpoint;
 	struct usb_device *hdev;
 	struct usb_hub *hub;
-	struct device *hub_dev;
 
 	desc = intf->cur_altsetting;
 	hdev = interface_to_usbdev(intf);
-	hub_dev = &intf->dev;
 
 	/* Some hubs have a subclass of 1, which AFAICT according to the */
 	/*  specs is not defined, but it works */
 	if ((desc->desc.bInterfaceSubClass != 0) &&
 	    (desc->desc.bInterfaceSubClass != 1)) {
 descriptor_error:
-		dev_err (hub_dev, "bad descriptor, ignoring hub\n");
+		dev_err (&intf->dev, "bad descriptor, ignoring hub\n");
 		return -EIO;
 	}
 
@@ -766,18 +779,18 @@
 		goto descriptor_error;
 
 	/* We found a hub */
-	dev_info (hub_dev, "USB hub found\n");
+	dev_info (&intf->dev, "USB hub found\n");
 
 	hub = kmalloc(sizeof(*hub), GFP_KERNEL);
 	if (!hub) {
-		dev_dbg (hub_dev, "couldn't kmalloc hub struct\n");
+		dev_dbg (&intf->dev, "couldn't kmalloc hub struct\n");
 		return -ENOMEM;
 	}
 
 	memset(hub, 0, sizeof(*hub));
 
 	INIT_LIST_HEAD(&hub->event_list);
-	hub->intf = intf;
+	hub->intfdev = &intf->dev;
 	hub->hdev = hdev;
 	INIT_WORK(&hub->leds, led_work, hub);
 
@@ -802,10 +815,9 @@
 	switch (code) {
 	case USBDEVFS_HUB_PORTINFO: {
 		struct usbdevfs_hub_portinfo *info = user_data;
-		unsigned long flags;
 		int i;
 
-		spin_lock_irqsave(&hub_event_lock, flags);
+		spin_lock_irq(&device_state_lock);
 		if (hdev->devnum <= 0)
 			info->nports = 0;
 		else {
@@ -818,7 +830,7 @@
 						hdev->children[i]->devnum;
 			}
 		}
-		spin_unlock_irqrestore(&hub_event_lock, flags);
+		spin_unlock_irq(&device_state_lock);
 
 		return info->nports + 1;
 		}
@@ -829,9 +841,9 @@
 }
 
 /* caller has locked the hub device */
-static void hub_pre_reset(struct usb_device *hdev)
+static void hub_pre_reset(struct usb_hub *hub)
 {
-	struct usb_hub *hub = usb_get_intfdata(hdev->actconfig->interface[0]);
+	struct usb_device *hdev = hub->hdev;
 	int i;
 
 	for (i = 0; i < hdev->maxchild; ++i) {
@@ -842,10 +854,8 @@
 }
 
 /* caller has locked the hub device */
-static void hub_post_reset(struct usb_device *hdev)
+static void hub_post_reset(struct usb_hub *hub)
 {
-	struct usb_hub *hub = usb_get_intfdata(hdev->actconfig->interface[0]);
-
 	hub_activate(hub);
 	hub_power_on(hub);
 }
@@ -890,7 +900,7 @@
 			 */
 			down(&udev->serialize);
 			up(&hdev->serialize);
-			return t;
+			return t + 1;
 		}
 	}
 	usb_unlock_device(hdev);
@@ -1178,25 +1188,25 @@
 
 		/* descriptor may appear anywhere in config */
 		if (__usb_get_extra_descriptor (udev->rawdescriptors[0],
-					udev->config[0].desc.wTotalLength,
+					le16_to_cpu(udev->config[0].desc.wTotalLength),
 					USB_DT_OTG, (void **) &desc) == 0) {
 			if (desc->bmAttributes & USB_OTG_HNP) {
-				unsigned		port;
+				unsigned		port1;
 				struct usb_device	*root = udev->parent;
 				
-				for (port = 0; port < root->maxchild; port++) {
-					if (root->children[port] == udev)
+				for (port1 = 1; port1 <= root->maxchild;
+						port1++) {
+					if (root->children[port1-1] == udev)
 						break;
 				}
-				port++;
 
 				dev_info(&udev->dev,
 					"Dual-Role OTG device on %sHNP port\n",
-					(port == bus->otg_port)
+					(port1 == bus->otg_port)
 						? "" : "non-");
 
 				/* enable HNP before suspend, it's simpler */
-				if (port == bus->otg_port)
+				if (port1 == bus->otg_port)
 					bus->b_hnp_enable = 1;
 				err = usb_control_msg(udev,
 					usb_sndctrlpipe(udev, 0),
@@ -1225,9 +1235,9 @@
 		 */
 		if (udev->bus->b_hnp_enable || udev->bus->is_b_host) {
 			static int __usb_suspend_device (struct usb_device *,
-						int port, u32 state);
+						int port1, u32 state);
 			err = __usb_suspend_device(udev,
-					udev->bus->otg_port - 1,
+					udev->bus->otg_port,
 					PM_SUSPEND_MEM);
 			if (err < 0)
 				dev_dbg(&udev->dev, "HNP fail, %d\n", err);
@@ -1275,18 +1285,14 @@
 }
 
 
-static int hub_port_status(struct usb_device *hdev, int port,
+static int hub_port_status(struct usb_hub *hub, int port1,
 			       u16 *status, u16 *change)
 {
-	struct usb_hub *hub = usb_get_intfdata(hdev->actconfig->interface[0]);
 	int ret;
 
-	if (!hub)
-		return -ENODEV;
-
-	ret = get_port_status(hdev, port + 1, &hub->status->port);
+	ret = get_port_status(hub->hdev, port1, &hub->status->port);
 	if (ret < 0)
-		dev_err (&hub->intf->dev,
+		dev_err (hub->intfdev,
 			"%s failed (err = %d)\n", __FUNCTION__, ret);
 	else {
 		*status = le16_to_cpu(hub->status->port.wPortStatus);
@@ -1307,7 +1313,7 @@
 #define HUB_LONG_RESET_TIME	200
 #define HUB_RESET_TIMEOUT	500
 
-static int hub_port_wait_reset(struct usb_device *hdev, int port,
+static int hub_port_wait_reset(struct usb_hub *hub, int port1,
 				struct usb_device *udev, unsigned int delay)
 {
 	int delay_time, ret;
@@ -1321,7 +1327,7 @@
 		msleep(delay);
 
 		/* read and decode port status */
-		ret = hub_port_status(hdev, port, &portstatus, &portchange);
+		ret = hub_port_status(hub, port1, &portstatus, &portchange);
 		if (ret < 0)
 			return ret;
 
@@ -1349,36 +1355,40 @@
 		if (delay_time >= 2 * HUB_SHORT_RESET_TIME)
 			delay = HUB_LONG_RESET_TIME;
 
-		dev_dbg (hubdev (hdev),
+		dev_dbg (hub->intfdev,
 			"port %d not reset yet, waiting %dms\n",
-			port + 1, delay);
+			port1, delay);
 	}
 
 	return -EBUSY;
 }
 
-static int hub_port_reset(struct usb_device *hdev, int port,
+static int hub_port_reset(struct usb_hub *hub, int port1,
 				struct usb_device *udev, unsigned int delay)
 {
 	int i, status;
-	struct device *hub_dev = hubdev (hdev);
 
 	/* Reset the port */
 	for (i = 0; i < PORT_RESET_TRIES; i++) {
-		status = set_port_feature(hdev, port + 1, USB_PORT_FEAT_RESET);
+		status = set_port_feature(hub->hdev,
+				port1, USB_PORT_FEAT_RESET);
 		if (status)
-			dev_err(hub_dev, "cannot reset port %d (err = %d)\n",
-					port + 1, status);
+			dev_err(hub->intfdev,
+					"cannot reset port %d (err = %d)\n",
+					port1, status);
 		else
-			status = hub_port_wait_reset(hdev, port, udev, delay);
+			status = hub_port_wait_reset(hub, port1, udev, delay);
 
 		/* return on disconnect or reset */
 		switch (status) {
 		case 0:
+			/* TRSTRCY = 10 ms */
+			msleep(10);
+			/* FALL THROUGH */
 		case -ENOTCONN:
 		case -ENODEV:
-			clear_port_feature(hdev,
-				port + 1, USB_PORT_FEAT_C_RESET);
+			clear_port_feature(hub->hdev,
+				port1, USB_PORT_FEAT_C_RESET);
 			/* FIXME need disconnect() for NOTATTACHED device */
 			usb_set_device_state(udev, status
 					? USB_STATE_NOTATTACHED
@@ -1386,31 +1396,32 @@
 			return status;
 		}
 
-		dev_dbg (hub_dev,
+		dev_dbg (hub->intfdev,
 			"port %d not enabled, trying reset again...\n",
-			port + 1);
+			port1);
 		delay = HUB_LONG_RESET_TIME;
 	}
 
-	dev_err (hub_dev,
+	dev_err (hub->intfdev,
 		"Cannot enable port %i.  Maybe the USB cable is bad?\n",
-		port + 1);
+		port1);
 
 	return status;
 }
 
-static int hub_port_disable(struct usb_device *hdev, int port)
+static int hub_port_disable(struct usb_hub *hub, int port1, int set_state)
 {
+	struct usb_device *hdev = hub->hdev;
 	int ret;
 
-	if (hdev->children[port]) {
-		usb_set_device_state(hdev->children[port],
+	if (hdev->children[port1-1] && set_state) {
+		usb_set_device_state(hdev->children[port1-1],
 				USB_STATE_NOTATTACHED);
 	}
-	ret = clear_port_feature(hdev, port + 1, USB_PORT_FEAT_ENABLE);
+	ret = clear_port_feature(hdev, port1, USB_PORT_FEAT_ENABLE);
 	if (ret)
-		dev_err(hubdev(hdev), "cannot disable port %d (err = %d)\n",
-			port + 1, ret);
+		dev_err(hub->intfdev, "cannot disable port %d (err = %d)\n",
+			port1, ret);
 
 	return ret;
 }
@@ -1420,12 +1431,10 @@
  * time later khubd will disconnect() any existing usb_device on the port
  * and will re-enumerate if there actually is a device attached.
  */
-static void hub_port_logical_disconnect(struct usb_device *hdev, int port)
+static void hub_port_logical_disconnect(struct usb_hub *hub, int port1)
 {
-	struct usb_hub *hub;
-
-	dev_dbg(hubdev(hdev), "logical disconnect on port %d\n", port + 1);
-	hub_port_disable(hdev, port);
+	dev_dbg(hub->intfdev, "logical disconnect on port %d\n", port1);
+	hub_port_disable(hub, port1, 1);
 
 	/* FIXME let caller ask to power down the port:
 	 *  - some devices won't enumerate without a VBUS power cycle
@@ -1436,8 +1445,7 @@
 	 * Powerdown must be optional, because of reset/DFU.
 	 */
 
-	hub = usb_get_intfdata(hdev->actconfig->interface[0]);
-	set_bit(port, hub->change_bits);
+	set_bit(port1, hub->change_bits);
  	kick_khubd(hub);
 }
 
@@ -1454,13 +1462,12 @@
  * tree above them to deliver data, such as a keypress or packet.  In
  * some cases, this wakes the USB host.
  */
-static int hub_port_suspend(struct usb_device *hdev, int port)
+static int hub_port_suspend(struct usb_hub *hub, int port1,
+		struct usb_device *udev)
 {
-	int			status;
-	struct usb_device	*udev;
+	int	status;
 
-	udev = hdev->children[port];
-	// dev_dbg(hubdev(hdev), "suspend port %d\n", port + 1);
+	// dev_dbg(hub->intfdev, "suspend port %d\n", port1);
 
 	/* enable remote wakeup when appropriate; this lets the device
 	 * wake up the upstream hub (including maybe the root hub).
@@ -1485,11 +1492,11 @@
 	}
 
 	/* see 7.1.7.6 */
-	status = set_port_feature(hdev, port + 1, USB_PORT_FEAT_SUSPEND);
+	status = set_port_feature(hub->hdev, port1, USB_PORT_FEAT_SUSPEND);
 	if (status) {
-		dev_dbg(hubdev(hdev),
+		dev_dbg(hub->intfdev,
 			"can't suspend port %d, status %d\n",
-			port + 1, status);
+			port1, status);
 		/* paranoia:  "should not happen" */
 		(void) usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
 				USB_REQ_CLEAR_FEATURE, USB_RECIP_DEVICE,
@@ -1499,7 +1506,7 @@
 	} else {
 		/* device has up to 10 msec to fully suspend */
 		dev_dbg(&udev->dev, "usb suspend\n");
-		udev->state = USB_STATE_SUSPENDED;
+		usb_set_device_state(udev, USB_STATE_SUSPENDED);
 		msleep(10);
 	}
 	return status;
@@ -1519,13 +1526,13 @@
  * Linux (2.6) currently has NO mechanisms to initiate that:  no khubd
  * timer, no SRP, no requests through sysfs.
  */
-int __usb_suspend_device (struct usb_device *udev, int port, u32 state)
+int __usb_suspend_device (struct usb_device *udev, int port1, u32 state)
 {
 	int	status;
 
 	/* caller owns the udev device lock */
-	if (port < 0)
-		return port;
+	if (port1 < 0)
+		return port1;
 
 	if (udev->state == USB_STATE_SUSPENDED
 			|| udev->state == USB_STATE_NOTATTACHED) {
@@ -1606,11 +1613,13 @@
 		} else
 			status = -EOPNOTSUPP;
 	} else
-		status = hub_port_suspend(udev->parent, port);
+		status = hub_port_suspend(hdev_to_hub(udev->parent), port1,
+				udev);
 
+	if (status == 0)
+		udev->dev.power.power_state = state;
 	return status;
 }
-EXPORT_SYMBOL(__usb_suspend_device);
 
 /**
  * usb_suspend_device - suspend a usb device
@@ -1632,13 +1641,13 @@
  */
 int usb_suspend_device(struct usb_device *udev, u32 state)
 {
-	int	port, status;
+	int	port1, status;
 
-	port = locktree(udev);
-	if (port < 0)
-		return port;
+	port1 = locktree(udev);
+	if (port1 < 0)
+		return port1;
 
-	status = __usb_suspend_device(udev, port, state);
+	status = __usb_suspend_device(udev, port1, state);
 	usb_unlock_device(udev);
 	return status;
 }
@@ -1661,9 +1670,10 @@
 	 * first two on the host side; they'd be inside hub_port_init()
 	 * during many timeouts, but khubd can't suspend until later.
 	 */
-	udev->state = udev->actconfig
-		? USB_STATE_CONFIGURED
-		: USB_STATE_ADDRESS;
+	usb_set_device_state(udev, udev->actconfig
+			? USB_STATE_CONFIGURED
+			: USB_STATE_ADDRESS);
+	udev->dev.power.power_state = PM_SUSPEND_ON;
 
  	/* 10.5.4.5 says be sure devices in the tree are still there.
  	 * For now let's assume the device didn't go crazy on resume,
@@ -1731,26 +1741,26 @@
 }
 
 static int
-hub_port_resume(struct usb_device *hdev, int port)
+hub_port_resume(struct usb_hub *hub, int port1, struct usb_device *udev)
 {
-	int			status;
-	struct usb_device	*udev;
+	int	status;
 
-	udev = hdev->children[port];
-	// dev_dbg(hubdev(hdev), "resume port %d\n", port + 1);
+	// dev_dbg(hub->intfdev, "resume port %d\n", port1);
 
 	/* see 7.1.7.7; affects power usage, but not budgeting */
-	status = clear_port_feature(hdev, port + 1, USB_PORT_FEAT_SUSPEND);
+	status = clear_port_feature(hub->hdev,
+			port1, USB_PORT_FEAT_SUSPEND);
 	if (status) {
-		dev_dbg(&hdev->actconfig->interface[0]->dev,
+		dev_dbg(hub->intfdev,
 			"can't resume port %d, status %d\n",
-			port + 1, status);
+			port1, status);
 	} else {
 		u16		devstatus;
 		u16		portchange;
 
 		/* drive resume for at least 20 msec */
-		dev_dbg(&udev->dev, "RESUME\n");
+		if (udev)
+			dev_dbg(&udev->dev, "RESUME\n");
 		msleep(25);
 
 #define LIVE_FLAGS	( USB_PORT_STAT_POWER \
@@ -1762,23 +1772,24 @@
 		 * sequence.
 		 */
 		devstatus = portchange = 0;
-		status = hub_port_status(hdev, port,
+		status = hub_port_status(hub, port1,
 				&devstatus, &portchange);
 		if (status < 0
 				|| (devstatus & LIVE_FLAGS) != LIVE_FLAGS
 				|| (devstatus & USB_PORT_STAT_SUSPEND) != 0
 				) {
-			dev_dbg(&hdev->actconfig->interface[0]->dev,
+			dev_dbg(hub->intfdev,
 				"port %d status %04x.%04x after resume, %d\n",
-				port + 1, portchange, devstatus, status);
+				port1, portchange, devstatus, status);
 		} else {
 			/* TRSMRCY = 10 msec */
 			msleep(10);
-			status = finish_port_resume(udev);
+			if (udev)
+				status = finish_port_resume(udev);
 		}
 	}
 	if (status < 0)
-		hub_port_logical_disconnect(hdev, port);
+		hub_port_logical_disconnect(hub, port1);
 
 	return status;
 }
@@ -1800,11 +1811,11 @@
  */
 int usb_resume_device(struct usb_device *udev)
 {
-	int			port, status;
+	int	port1, status;
 
-	port = locktree(udev);
-	if (port < 0)
-		return port;
+	port1 = locktree(udev);
+	if (port1 < 0)
+		return port1;
 
 	/* "global resume" of the HC-to-USB interface (root hub), or
 	 * selective resume of one hub-to-device port
@@ -1824,7 +1835,8 @@
 		}
 	} else if (udev->state == USB_STATE_SUSPENDED) {
 		// NOTE this fails if parent is also suspended...
-		status = hub_port_resume(udev->parent, port);
+		status = hub_port_resume(hdev_to_hub(udev->parent),
+				port1, udev);
 	} else {
 		status = 0;
 	}
@@ -1866,25 +1878,25 @@
 {
 	struct usb_hub		*hub = usb_get_intfdata (intf);
 	struct usb_device	*hdev = hub->hdev;
-	unsigned		port;
+	unsigned		port1;
 	int			status;
 
 	/* stop khubd and related activity */
 	hub_quiesce(hub);
 
 	/* then suspend every port */
-	for (port = 0; port < hdev->maxchild; port++) {
+	for (port1 = 1; port1 <= hdev->maxchild; port1++) {
 		struct usb_device	*udev;
 
-		udev = hdev->children [port];
+		udev = hdev->children [port1-1];
 		if (!udev)
 			continue;
 		down(&udev->serialize);
-		status = __usb_suspend_device(udev, port, state);
+		status = __usb_suspend_device(udev, port1, state);
 		up(&udev->serialize);
 		if (status < 0)
 			dev_dbg(&intf->dev, "suspend port %d --> %d\n",
-				port, status);
+				port1, status);
 	}
 
 	intf->dev.power.power_state = state;
@@ -1895,21 +1907,21 @@
 {
 	struct usb_device	*hdev = interface_to_usbdev(intf);
 	struct usb_hub		*hub = usb_get_intfdata (intf);
-	unsigned		port;
+	unsigned		port1;
 	int			status;
 
 	if (intf->dev.power.power_state == PM_SUSPEND_ON)
 		return 0;
 
-	for (port = 0; port < hdev->maxchild; port++) {
+	for (port1 = 1; port1 <= hdev->maxchild; port1++) {
 		struct usb_device	*udev;
 		u16			portstat, portchange;
 
-		udev = hdev->children [port];
-		status = hub_port_status(hdev, port, &portstat, &portchange);
+		udev = hdev->children [port1-1];
+		status = hub_port_status(hub, port1, &portstat, &portchange);
 		if (status == 0) {
 			if (portchange & USB_PORT_STAT_C_SUSPEND) {
-				clear_port_feature(hdev, port + 1,
+				clear_port_feature(hdev, port1,
 					USB_PORT_FEAT_C_SUSPEND);
 				portchange &= ~USB_PORT_STAT_C_SUSPEND;
 			}
@@ -1923,13 +1935,13 @@
 			continue;
 		down (&udev->serialize);
 		if (portstat & USB_PORT_STAT_SUSPEND)
-			status = hub_port_resume(hdev, port);
+			status = hub_port_resume(hub, port1, udev);
 		else {
 			status = finish_port_resume(udev);
 			if (status < 0) {
 				dev_dbg(&intf->dev, "resume port %d --> %d\n",
-					port + 1, status);
-				hub_port_logical_disconnect(hdev, port);
+					port1, status);
+				hub_port_logical_disconnect(hub, port1);
 			}
 		}
 		up(&udev->serialize);
@@ -1983,7 +1995,7 @@
 #define HUB_DEBOUNCE_STEP	  25
 #define HUB_DEBOUNCE_STABLE	 100
 
-static int hub_port_debounce(struct usb_device *hdev, int port)
+static int hub_port_debounce(struct usb_hub *hub, int port1)
 {
 	int ret;
 	int total_time, stable_time = 0;
@@ -1991,7 +2003,7 @@
 	unsigned connection = 0xffff;
 
 	for (total_time = 0; ; total_time += HUB_DEBOUNCE_STEP) {
-		ret = hub_port_status(hdev, port, &portstatus, &portchange);
+		ret = hub_port_status(hub, port1, &portstatus, &portchange);
 		if (ret < 0)
 			return ret;
 
@@ -2006,7 +2018,7 @@
 		}
 
 		if (portchange & USB_PORT_STAT_C_CONNECTION) {
-			clear_port_feature(hdev, port+1,
+			clear_port_feature(hub->hdev, port1,
 					USB_PORT_FEAT_C_CONNECTION);
 		}
 
@@ -2015,15 +2027,22 @@
 		msleep(HUB_DEBOUNCE_STEP);
 	}
 
-	dev_dbg (hubdev (hdev),
+	dev_dbg (hub->intfdev,
 		"debounce: port %d: total %dms stable %dms status 0x%x\n",
-		port + 1, total_time, stable_time, portstatus);
+		port1, total_time, stable_time, portstatus);
 
 	if (stable_time < HUB_DEBOUNCE_STABLE)
 		return -ETIMEDOUT;
 	return portstatus;
 }
 
+static void ep0_reinit(struct usb_device *udev)
+{
+	usb_disable_endpoint(udev, 0 + USB_DIR_IN);
+	usb_disable_endpoint(udev, 0 + USB_DIR_OUT);
+	udev->ep_in[0] = udev->ep_out[0] = &udev->ep0;
+}
+
 #define usb_sndaddr0pipe()	(PIPE_CONTROL << 30)
 #define usb_rcvaddr0pipe()	((PIPE_CONTROL << 30) | USB_DIR_IN)
 
@@ -2041,12 +2060,8 @@
 		USB_REQ_SET_ADDRESS, 0, udev->devnum, 0,
 		NULL, 0, HZ * USB_CTRL_SET_TIMEOUT);
 	if (retval == 0) {
-		int m = udev->epmaxpacketin[0];
-
 		usb_set_device_state(udev, USB_STATE_ADDRESS);
-		usb_disable_endpoint(udev, 0 + USB_DIR_IN);
-		usb_disable_endpoint(udev, 0 + USB_DIR_OUT);
-		udev->epmaxpacketin[0] = udev->epmaxpacketout[0] = m;
+		ep0_reinit(udev);
 	}
 	return retval;
 }
@@ -2061,11 +2076,12 @@
  * pointers, it's not necessary to lock the device.
  */
 static int
-hub_port_init (struct usb_device *hdev, struct usb_device *udev, int port,
+hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
 		int retry_counter)
 {
 	static DECLARE_MUTEX(usb_address0_sem);
 
+	struct usb_device	*hdev = hub->hdev;
 	int			i, j, retval;
 	unsigned		delay = HUB_SHORT_RESET_TIME;
 	enum usb_device_speed	oldspeed = udev->speed;
@@ -2075,7 +2091,7 @@
 	 */
 	if (!hdev->parent) {
 		delay = HUB_ROOT_RESET_TIME;
-		if (port + 1 == hdev->bus->otg_port)
+		if (port1 == hdev->bus->otg_port)
 			hdev->bus->b_hnp_enable = 0;
 	}
 
@@ -2087,7 +2103,7 @@
 	down(&usb_address0_sem);
 
 	/* Reset the device; full speed may morph to high speed */
-	retval = hub_port_reset(hdev, port, udev, delay);
+	retval = hub_port_reset(hub, port1, udev, delay);
 	if (retval < 0)		/* error or disconnect */
 		goto fail;
 				/* success, speed is known */
@@ -2104,22 +2120,21 @@
 	 */
 	switch (udev->speed) {
 	case USB_SPEED_HIGH:		/* fixed at 64 */
-		i = 64;
+		udev->ep0.desc.wMaxPacketSize = __constant_cpu_to_le16(64);
 		break;
 	case USB_SPEED_FULL:		/* 8, 16, 32, or 64 */
 		/* to determine the ep0 maxpacket size, try to read
 		 * the device descriptor to get bMaxPacketSize0 and
 		 * then correct our initial guess.
 		 */
-		i = 64;
+		udev->ep0.desc.wMaxPacketSize = __constant_cpu_to_le16(64);
 		break;
 	case USB_SPEED_LOW:		/* fixed at 8 */
-		i = 8;
+		udev->ep0.desc.wMaxPacketSize = __constant_cpu_to_le16(8);
 		break;
 	default:
 		goto fail;
 	}
-	udev->epmaxpacketin[0] = udev->epmaxpacketout[0] = i;
  
 	dev_info (&udev->dev,
 			"%s %s speed USB device using %s and address %d\n",
@@ -2139,11 +2154,8 @@
 		udev->ttport = hdev->ttport;
 	} else if (udev->speed != USB_SPEED_HIGH
 			&& hdev->speed == USB_SPEED_HIGH) {
-		struct usb_hub *hub;
-
-		hub = usb_get_intfdata(hdev->actconfig->interface[0]);
 		udev->tt = &hub->tt;
-		udev->ttport = port + 1;
+		udev->ttport = port1;
 	}
  
 	/* Why interleave GET_DESCRIPTOR and SET_ADDRESS this way?
@@ -2161,6 +2173,7 @@
 	for (i = 0; i < GET_DESCRIPTOR_TRIES; (++i, msleep(100))) {
 		if (USE_NEW_SCHEME(retry_counter)) {
 			struct usb_device_descriptor *buf;
+			int r = 0;
 
 #define GET_DESCRIPTOR_BUFSIZE	64
 			buf = kmalloc(GET_DESCRIPTOR_BUFSIZE, GFP_NOIO);
@@ -2174,18 +2187,25 @@
 			 * so that recalcitrant full-speed devices with
 			 * 8- or 16-byte ep0-maxpackets won't slow things
 			 * down tremendously by NAKing the unexpectedly
-			 * early status stage.
+			 * early status stage.  Also, retry on length 0
+			 * or stall; some devices are flakey.
 			 */
-			j = usb_control_msg(udev, usb_rcvaddr0pipe(),
+			for (j = 0; j < 3; ++j) {
+				r = usb_control_msg(udev, usb_rcvaddr0pipe(),
 					USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
 					USB_DT_DEVICE << 8, 0,
 					buf, GET_DESCRIPTOR_BUFSIZE,
 					(i ? HZ * USB_CTRL_GET_TIMEOUT : HZ));
+				if (r == 0 || r == -EPIPE)
+					continue;
+				if (r < 0)
+					break;
+			}
 			udev->descriptor.bMaxPacketSize0 =
 					buf->bMaxPacketSize0;
 			kfree(buf);
 
-			retval = hub_port_reset(hdev, port, udev, delay);
+			retval = hub_port_reset(hub, port1, udev, delay);
 			if (retval < 0)		/* error or disconnect */
 				goto fail;
 			if (oldspeed != udev->speed) {
@@ -2194,10 +2214,13 @@
 				retval = -ENODEV;
 				goto fail;
 			}
-			if (udev->descriptor.bMaxPacketSize0 == 0) {
+			switch (udev->descriptor.bMaxPacketSize0) {
+			case 64: case 32: case 16: case 8:
+				break;
+			default:
 				dev_err(&udev->dev, "device descriptor "
 						"read/%s, error %d\n",
-						"64", j);
+						"64", r);
 				retval = -EMSGSIZE;
 				continue;
 			}
@@ -2240,13 +2263,17 @@
 	if (retval)
 		goto fail;
 
-	/* Should we verify that the value is valid? */
 	i = udev->descriptor.bMaxPacketSize0;
-	if (udev->epmaxpacketin[0] != i) {
+	if (le16_to_cpu(udev->ep0.desc.wMaxPacketSize) != i) {
+		if (udev->speed != USB_SPEED_FULL ||
+				!(i == 8 || i == 16 || i == 32 || i == 64)) {
+			dev_err(&udev->dev, "ep0 maxpacket = %d\n", i);
+			retval = -EMSGSIZE;
+			goto fail;
+		}
 		dev_dbg(&udev->dev, "ep0 maxpacket = %d\n", i);
-		usb_disable_endpoint(udev, 0 + USB_DIR_IN);
-		usb_disable_endpoint(udev, 0 + USB_DIR_OUT);
-		udev->epmaxpacketin[0] = udev->epmaxpacketout[0] = i;
+		udev->ep0.desc.wMaxPacketSize = cpu_to_le16(i);
+		ep0_reinit(udev);
 	}
   
 	retval = usb_get_device_descriptor(udev, USB_DT_DEVICE_SIZE);
@@ -2261,18 +2288,20 @@
 	retval = 0;
 
 fail:
+	if (retval)
+		hub_port_disable(hub, port1, 0);
 	up(&usb_address0_sem);
 	return retval;
 }
 
 static void
-check_highspeed (struct usb_hub *hub, struct usb_device *udev, int port)
+check_highspeed (struct usb_hub *hub, struct usb_device *udev, int port1)
 {
 	struct usb_qualifier_descriptor	*qual;
 	int				status;
 
 	qual = kmalloc (sizeof *qual, SLAB_KERNEL);
-	if (qual == 0)
+	if (qual == NULL)
 		return;
 
 	status = usb_get_descriptor (udev, USB_DT_DEVICE_QUALIFIER, 0,
@@ -2282,7 +2311,7 @@
 			"connect to a high speed hub\n");
 		/* hub LEDs are probably harder to miss than syslog */
 		if (hub->has_indicators) {
-			hub->indicator[port] = INDICATOR_GREEN_BLINK;
+			hub->indicator[port1-1] = INDICATOR_GREEN_BLINK;
 			schedule_work (&hub->leds);
 		}
 	}
@@ -2324,7 +2353,7 @@
 		remaining -= delta;
 	}
 	if (remaining < 0) {
-		dev_warn(&hub->intf->dev,
+		dev_warn(hub->intfdev,
 			"%dmA over power budget!\n",
 			-2 * remaining);
 		remaining = 0;
@@ -2340,26 +2369,26 @@
  *		a firmware download)
  * caller already locked the hub
  */
-static void hub_port_connect_change(struct usb_hub *hub, int port,
+static void hub_port_connect_change(struct usb_hub *hub, int port1,
 					u16 portstatus, u16 portchange)
 {
 	struct usb_device *hdev = hub->hdev;
-	struct device *hub_dev = &hub->intf->dev;
+	struct device *hub_dev = hub->intfdev;
 	int status, i;
  
 	dev_dbg (hub_dev,
 		"port %d, status %04x, change %04x, %s\n",
-		port + 1, portstatus, portchange, portspeed (portstatus));
+		port1, portstatus, portchange, portspeed (portstatus));
 
 	if (hub->has_indicators) {
-		set_port_led(hdev, port + 1, HUB_LED_AUTO);
-		hub->indicator[port] = INDICATOR_AUTO;
+		set_port_led(hub, port1, HUB_LED_AUTO);
+		hub->indicator[port1-1] = INDICATOR_AUTO;
 	}
  
 	/* Disconnect any existing devices under this port */
-	if (hdev->children[port])
-		usb_disconnect(&hdev->children[port]);
-	clear_bit(port, hub->change_bits);
+	if (hdev->children[port1-1])
+		usb_disconnect(&hdev->children[port1-1]);
+	clear_bit(port1, hub->change_bits);
 
 #ifdef	CONFIG_USB_OTG
 	/* during HNP, don't repeat the debounce */
@@ -2368,11 +2397,11 @@
 #endif
 
 	if (portchange & USB_PORT_STAT_C_CONNECTION) {
-		status = hub_port_debounce(hdev, port);
+		status = hub_port_debounce(hub, port1);
 		if (status < 0) {
 			dev_err (hub_dev,
 				"connect-debounce failed, port %d disabled\n",
-				port+1);
+				port1);
 			goto done;
 		}
 		portstatus = status;
@@ -2385,7 +2414,7 @@
 		if ((hub->descriptor->wHubCharacteristics
 					& HUB_CHAR_LPSM) < 2
 				&& !(portstatus & (1 << USB_PORT_FEAT_POWER)))
-			set_port_feature(hdev, port + 1, USB_PORT_FEAT_POWER);
+			set_port_feature(hdev, port1, USB_PORT_FEAT_POWER);
  
 		if (portstatus & USB_PORT_STAT_ENABLE)
   			goto done;
@@ -2393,11 +2422,15 @@
 	}
 
 #ifdef  CONFIG_USB_SUSPEND
-	/* If something is connected, but the port is suspended, wake it up.. */
+	/* If something is connected, but the port is suspended, wake it up. */
 	if (portstatus & USB_PORT_STAT_SUSPEND) {
-		status = hub_port_resume(hdev, port);
-		if (status < 0)
-			dev_dbg(hub_dev, "can't clear suspend on port %d; %d\n", port+1, status);
+		status = hub_port_resume(hub, port1, NULL);
+		if (status < 0) {
+			dev_dbg(hub_dev,
+				"can't clear suspend on port %d; %d\n",
+				port1, status);
+			goto done;
+		}
 	}
 #endif
 
@@ -2407,10 +2440,11 @@
 		/* reallocate for each attempt, since references
 		 * to the previous one can escape in various ways
 		 */
-		udev = usb_alloc_dev(hdev, hdev->bus, port);
+		udev = usb_alloc_dev(hdev, hdev->bus, port1);
 		if (!udev) {
 			dev_err (hub_dev,
-				"couldn't allocate port %d usb_device\n", port+1);
+				"couldn't allocate port %d usb_device\n",
+				port1);
 			goto done;
 		}
 
@@ -2425,7 +2459,7 @@
 		}
 
 		/* reset and get descriptor */
-		status = hub_port_init(hdev, udev, port, i);
+		status = hub_port_init(hub, udev, port1, i);
 		if (status < 0)
 			goto loop;
 
@@ -2443,7 +2477,7 @@
 					&devstat);
 			if (status < 0) {
 				dev_dbg(&udev->dev, "get status %d ?\n", status);
-				goto loop;
+				goto loop_disable;
 			}
 			cpu_to_le16s(&devstat);
 			if ((devstat & (1 << USB_DEVICE_SELF_POWERED)) == 0) {
@@ -2451,20 +2485,20 @@
 					"can't connect bus-powered hub "
 					"to this port\n");
 				if (hub->has_indicators) {
-					hub->indicator[port] =
+					hub->indicator[port1-1] =
 						INDICATOR_AMBER_BLINK;
 					schedule_work (&hub->leds);
 				}
 				status = -ENOTCONN;	/* Don't retry */
-				goto loop;
+				goto loop_disable;
 			}
 		}
  
 		/* check for devices running slower than they could */
-		if (udev->descriptor.bcdUSB >= 0x0200
+		if (le16_to_cpu(udev->descriptor.bcdUSB) >= 0x0200
 				&& udev->speed == USB_SPEED_FULL
 				&& highspeed_hubs != 0)
-			check_highspeed (hub, udev, port);
+			check_highspeed (hub, udev, port1);
 
 		/* Store the parent's children[] pointer.  At this point
 		 * udev becomes globally accessible, although presumably
@@ -2481,7 +2515,7 @@
 		if (hdev->state == USB_STATE_NOTATTACHED)
 			status = -ENOTCONN;
 		else
-			hdev->children[port] = udev;
+			hdev->children[port1-1] = udev;
 		spin_unlock_irq(&device_state_lock);
 
 		/* Run it through the hoops (find a driver, etc) */
@@ -2489,14 +2523,14 @@
 			status = usb_new_device(udev);
 			if (status) {
 				spin_lock_irq(&device_state_lock);
-				hdev->children[port] = NULL;
+				hdev->children[port1-1] = NULL;
 				spin_unlock_irq(&device_state_lock);
 			}
 		}
 
 		up (&udev->serialize);
 		if (status)
-			goto loop;
+			goto loop_disable;
 
 		status = hub_power_remaining(hub);
 		if (status)
@@ -2506,10 +2540,10 @@
 
 		return;
 
+loop_disable:
+		hub_port_disable(hub, port1, 1);
 loop:
-		hub_port_disable(hdev, port);
-		usb_disable_endpoint(udev, 0 + USB_DIR_IN);
-		usb_disable_endpoint(udev, 0 + USB_DIR_OUT);
+		ep0_reinit(udev);
 		release_address(udev);
 		usb_put_dev(udev);
 		if (status == -ENOTCONN)
@@ -2517,13 +2551,14 @@
 	}
  
 done:
-	hub_port_disable(hdev, port);
+	hub_port_disable(hub, port1, 1);
 }
 
 static void hub_events(void)
 {
 	struct list_head *tmp;
 	struct usb_device *hdev;
+	struct usb_interface *intf;
 	struct usb_hub *hub;
 	struct device *hub_dev;
 	u16 hubstatus;
@@ -2553,10 +2588,8 @@
 
 		hub = list_entry(tmp, struct usb_hub, event_list);
 		hdev = hub->hdev;
-		hub_dev = &hub->intf->dev;
-
-		usb_get_dev(hdev);
-		spin_unlock_irq(&hub_event_lock);
+		intf = to_usb_interface(hub->intfdev);
+		hub_dev = &intf->dev;
 
 		dev_dbg(hub_dev, "state %d ports %d chg %04x evt %04x\n",
 				hdev->state, hub->descriptor
@@ -2566,14 +2599,16 @@
 				(u16) hub->change_bits[0],
 				(u16) hub->event_bits[0]);
 
+		usb_get_intf(intf);
+		spin_unlock_irq(&hub_event_lock);
+
 		/* Lock the device, then check to see if we were
 		 * disconnected while waiting for the lock to succeed. */
-		if (locktree(hdev) < 0)
-			break;
-		if (hdev->state != USB_STATE_CONFIGURED ||
-				!hdev->actconfig ||
-				hub != usb_get_intfdata(
-					hdev->actconfig->interface[0]))
+		if (locktree(hdev) < 0) {
+			usb_put_intf(intf);
+			continue;
+		}
+		if (hub != usb_get_intfdata(intf) || hub->quiescing)
 			goto loop;
 
 		if (hub->error) {
@@ -2592,20 +2627,20 @@
 		}
 
 		/* deal with port status changes */
-		for (i = 0; i < hub->descriptor->bNbrPorts; i++) {
+		for (i = 1; i <= hub->descriptor->bNbrPorts; i++) {
 			connect_change = test_bit(i, hub->change_bits);
-			if (!test_and_clear_bit(i+1, hub->event_bits) &&
+			if (!test_and_clear_bit(i, hub->event_bits) &&
 					!connect_change)
 				continue;
 
-			ret = hub_port_status(hdev, i,
+			ret = hub_port_status(hub, i,
 					&portstatus, &portchange);
 			if (ret < 0)
 				continue;
 
 			if (portchange & USB_PORT_STAT_C_CONNECTION) {
-				clear_port_feature(hdev,
-					i + 1, USB_PORT_FEAT_C_CONNECTION);
+				clear_port_feature(hdev, i,
+					USB_PORT_FEAT_C_CONNECTION);
 				connect_change = 1;
 			}
 
@@ -2614,9 +2649,9 @@
 					dev_dbg (hub_dev,
 						"port %d enable change, "
 						"status %08x\n",
-						i + 1, portstatus);
-				clear_port_feature(hdev,
-					i + 1, USB_PORT_FEAT_C_ENABLE);
+						i, portstatus);
+				clear_port_feature(hdev, i,
+					USB_PORT_FEAT_C_ENABLE);
 
 				/*
 				 * EM interference sometimes causes badly
@@ -2626,47 +2661,48 @@
 				 */
 				if (!(portstatus & USB_PORT_STAT_ENABLE)
 				    && !connect_change
-				    && hdev->children[i]) {
+				    && hdev->children[i-1]) {
 					dev_err (hub_dev,
 					    "port %i "
 					    "disabled by hub (EMI?), "
 					    "re-enabling...\n",
-						i + 1);
+						i);
 					connect_change = 1;
 				}
 			}
 
 			if (portchange & USB_PORT_STAT_C_SUSPEND) {
-				clear_port_feature(hdev, i + 1,
+				clear_port_feature(hdev, i,
 					USB_PORT_FEAT_C_SUSPEND);
-				if (hdev->children[i]) {
-					ret = remote_wakeup(hdev->children[i]);
+				if (hdev->children[i-1]) {
+					ret = remote_wakeup(hdev->
+							children[i-1]);
 					if (ret < 0)
 						connect_change = 1;
 				} else {
 					ret = -ENODEV;
-					hub_port_disable(hdev, i);
+					hub_port_disable(hub, i, 1);
 				}
 				dev_dbg (hub_dev,
 					"resume on port %d, status %d\n",
-					i + 1, ret);
+					i, ret);
 			}
 			
 			if (portchange & USB_PORT_STAT_C_OVERCURRENT) {
 				dev_err (hub_dev,
 					"over-current change on port %d\n",
-					i + 1);
-				clear_port_feature(hdev,
-					i + 1, USB_PORT_FEAT_C_OVER_CURRENT);
+					i);
+				clear_port_feature(hdev, i,
+					USB_PORT_FEAT_C_OVER_CURRENT);
 				hub_power_on(hub);
 			}
 
 			if (portchange & USB_PORT_STAT_C_RESET) {
 				dev_dbg (hub_dev,
 					"reset change on port %d\n",
-					i + 1);
-				clear_port_feature(hdev,
-					i + 1, USB_PORT_FEAT_C_RESET);
+					i);
+				clear_port_feature(hdev, i,
+					USB_PORT_FEAT_C_RESET);
 			}
 
 			if (connect_change)
@@ -2694,7 +2730,7 @@
 
 loop:
 		usb_unlock_device(hdev);
-		usb_put_dev(hdev);
+		usb_put_intf(intf);
 
         } /* end while (1) */
 }
@@ -2713,8 +2749,7 @@
 	do {
 		hub_events();
 		wait_event_interruptible(khubd_wait, !list_empty(&hub_event_list)); 
-		if (current->flags & PF_FREEZE)
-			refrigerator(PF_FREEZE);
+		try_to_freeze(PF_FREEZE);
 	} while (!signal_pending(current));
 
 	pr_debug ("%s: khubd exiting\n", usbcore_name);
@@ -2793,18 +2828,18 @@
 	struct usb_config_descriptor	*buf;
 
 	for (index = 0; index < udev->descriptor.bNumConfigurations; index++) {
-		if (len < udev->config[index].desc.wTotalLength)
-			len = udev->config[index].desc.wTotalLength;
+		if (len < le16_to_cpu(udev->config[index].desc.wTotalLength))
+			len = le16_to_cpu(udev->config[index].desc.wTotalLength);
 	}
 	buf = kmalloc (len, SLAB_KERNEL);
-	if (buf == 0) {
+	if (buf == NULL) {
 		dev_err(&udev->dev, "no mem to re-read configs after reset\n");
 		/* assume the worst */
 		return 1;
 	}
 	for (index = 0; index < udev->descriptor.bNumConfigurations; index++) {
 		int length;
-		int old_length = udev->config[index].desc.wTotalLength;
+		int old_length = le16_to_cpu(udev->config[index].desc.wTotalLength);
 
 		length = usb_get_descriptor(udev, USB_DT_CONFIG, index, buf,
 				old_length);
@@ -2851,10 +2886,11 @@
  */
 int usb_reset_device(struct usb_device *udev)
 {
-	struct usb_device *parent = udev->parent;
-	struct usb_device_descriptor descriptor = udev->descriptor;
-	int i, ret = 0, port = -1;
-	int udev_is_a_hub = 0;
+	struct usb_device		*parent_hdev = udev->parent;
+	struct usb_hub			*parent_hub;
+	struct usb_device_descriptor	descriptor = udev->descriptor;
+	struct usb_hub			*hub = NULL;
+	int 				i, ret = 0, port1 = -1;
 
 	if (udev->state == USB_STATE_NOTATTACHED ||
 			udev->state == USB_STATE_SUSPENDED) {
@@ -2863,39 +2899,39 @@
 		return -EINVAL;
 	}
 
-	if (!parent) {
+	if (!parent_hdev) {
 		/* this requires hcd-specific logic; see OHCI hc_restart() */
 		dev_dbg(&udev->dev, "%s for root hub!\n", __FUNCTION__);
 		return -EISDIR;
 	}
 
-	for (i = 0; i < parent->maxchild; i++)
-		if (parent->children[i] == udev) {
-			port = i;
+	for (i = 0; i < parent_hdev->maxchild; i++)
+		if (parent_hdev->children[i] == udev) {
+			port1 = i + 1;
 			break;
 		}
 
-	if (port < 0) {
+	if (port1 < 0) {
 		/* If this ever happens, it's very bad */
 		dev_err(&udev->dev, "Can't locate device's port!\n");
 		return -ENOENT;
 	}
+	parent_hub = hdev_to_hub(parent_hdev);
 
 	/* If we're resetting an active hub, take some special actions */
 	if (udev->actconfig &&
 			udev->actconfig->interface[0]->dev.driver ==
-			&hub_driver.driver) {
-		udev_is_a_hub = 1;
-		hub_pre_reset(udev);
+				&hub_driver.driver &&
+			(hub = hdev_to_hub(udev)) != NULL) {
+		hub_pre_reset(hub);
 	}
 
 	for (i = 0; i < SET_CONFIG_TRIES; ++i) {
 
 		/* ep0 maxpacket size may change; let the HCD know about it.
 		 * Other endpoints will be handled by re-enumeration. */
-		usb_disable_endpoint(udev, 0 + USB_DIR_IN);
-		usb_disable_endpoint(udev, 0 + USB_DIR_OUT);
-		ret = hub_port_init(parent, udev, port, i);
+		ep0_reinit(udev);
+		ret = hub_port_init(parent_hub, udev, port1, i);
 		if (ret >= 0)
 			break;
 	}
@@ -2946,11 +2982,11 @@
 	}
 
 done:
-	if (udev_is_a_hub)
-		hub_post_reset(udev);
+	if (hub)
+		hub_post_reset(hub);
 	return 0;
  
 re_enumerate:
-	hub_port_logical_disconnect(parent, port);
+	hub_port_logical_disconnect(parent_hub, port1);
 	return -ENODEV;
 }
diff -Nru a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h
--- a/drivers/usb/core/hub.h	2005-03-01 23:38:52 -08:00
+++ b/drivers/usb/core/hub.h	2005-03-01 23:38:52 -08:00
@@ -186,7 +186,7 @@
 extern void usb_hub_tt_clear_buffer (struct usb_device *dev, int pipe);
 
 struct usb_hub {
-	struct usb_interface	*intf;		/* the "real" device */
+	struct device		*intfdev;	/* the "interface" device */
 	struct usb_device	*hdev;
 	struct urb		*urb;		/* for interrupt polling pipe */
 
diff -Nru a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c
--- a/drivers/usb/core/inode.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/usb/core/inode.c	2005-03-01 23:38:52 -08:00
@@ -434,6 +434,7 @@
 	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
 	sb->s_magic = USBDEVICE_SUPER_MAGIC;
 	sb->s_op = &usbfs_ops;
+	sb->s_time_gran = 1;
 	inode = usbfs_get_inode(sb, S_IFDIR | 0755, 0);
 
 	if (!inode) {
@@ -695,7 +696,7 @@
 	for (i = 0; i < dev->descriptor.bNumConfigurations; ++i) {
 		struct usb_config_descriptor *config =
 			(struct usb_config_descriptor *)dev->rawdescriptors[i];
-		i_size += le16_to_cpu ((__force __le16)config->wTotalLength);
+		i_size += le16_to_cpu(config->wTotalLength);
 	}
 	if (dev->usbfs_dentry->d_inode)
 		dev->usbfs_dentry->d_inode->i_size = i_size;
diff -Nru a/drivers/usb/core/message.c b/drivers/usb/core/message.c
--- a/drivers/usb/core/message.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/usb/core/message.c	2005-03-01 23:38:54 -08:00
@@ -209,7 +209,7 @@
 		kfree (io->urbs);
 		io->urbs = NULL;
 	}
-	if (io->dev->dev.dma_mask != 0)
+	if (io->dev->dev.dma_mask != NULL)
 		usb_buffer_unmap_sg (io->dev, io->pipe, io->sg, io->nents);
 	io->dev = NULL;
 }
@@ -334,7 +334,7 @@
 	/* not all host controllers use DMA (like the mainstream pci ones);
 	 * they can use PIO (sl811) or be software over another transport.
 	 */
-	dma = (dev->dev.dma_mask != 0);
+	dma = (dev->dev.dma_mask != NULL);
 	if (dma)
 		io->entries = usb_buffer_map_sg (dev, pipe, sg, nents);
 	else
@@ -796,13 +796,8 @@
 		return -ENOMEM;
 
 	ret = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc, size);
-	if (ret >= 0) {
-		le16_to_cpus(&desc->bcdUSB);
-		le16_to_cpus(&desc->idVendor);
-		le16_to_cpus(&desc->idProduct);
-		le16_to_cpus(&desc->bcdDevice);
+	if (ret >= 0) 
 		memcpy(&dev->descriptor, desc, size);
-	}
 	kfree(desc);
 	return ret;
 }
@@ -918,16 +913,21 @@
  */
 void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr)
 {
-	if (dev && dev->bus && dev->bus->op && dev->bus->op->disable)
-		dev->bus->op->disable(dev, epaddr);
-	else {
-		unsigned int epnum = epaddr & USB_ENDPOINT_NUMBER_MASK;
+	unsigned int epnum = epaddr & USB_ENDPOINT_NUMBER_MASK;
+	struct usb_host_endpoint *ep;
 
-		if (usb_endpoint_out(epaddr))
-			dev->epmaxpacketout[epnum] = 0;
-		else
-			dev->epmaxpacketin[epnum] = 0;
+	if (!dev)
+		return;
+
+	if (usb_endpoint_out(epaddr)) {
+		ep = dev->ep_out[epnum];
+		dev->ep_out[epnum] = NULL;
+	} else {
+		ep = dev->ep_in[epnum];
+		dev->ep_in[epnum] = NULL;
 	}
+	if (ep && dev->bus && dev->bus->op && dev->bus->op->disable)
+		dev->bus->op->disable(dev, ep);
 }
 
 /**
@@ -1002,27 +1002,27 @@
 /*
  * usb_enable_endpoint - Enable an endpoint for USB communications
  * @dev: the device whose interface is being enabled
- * @epd: pointer to the endpoint descriptor
+ * @ep: the endpoint
  *
- * Resets the endpoint toggle and stores its maxpacket value.
+ * Resets the endpoint toggle, and sets dev->ep_{in,out} pointers.
  * For control endpoints, both the input and output sides are handled.
  */
-void usb_enable_endpoint(struct usb_device *dev,
-		struct usb_endpoint_descriptor *epd)
+static void
+usb_enable_endpoint(struct usb_device *dev, struct usb_host_endpoint *ep)
 {
-	int maxsize = epd->wMaxPacketSize;
-	unsigned int epaddr = epd->bEndpointAddress;
+	unsigned int epaddr = ep->desc.bEndpointAddress;
 	unsigned int epnum = epaddr & USB_ENDPOINT_NUMBER_MASK;
-	int is_control = ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
-				USB_ENDPOINT_XFER_CONTROL);
+	int is_control;
 
+	is_control = ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
+			== USB_ENDPOINT_XFER_CONTROL);
 	if (usb_endpoint_out(epaddr) || is_control) {
 		usb_settoggle(dev, epnum, 1, 0);
-		dev->epmaxpacketout[epnum] = maxsize;
+		dev->ep_out[epnum] = ep;
 	}
 	if (!usb_endpoint_out(epaddr) || is_control) {
 		usb_settoggle(dev, epnum, 0, 0);
-		dev->epmaxpacketin[epnum] = maxsize;
+		dev->ep_in[epnum] = ep;
 	}
 }
 
@@ -1040,7 +1040,7 @@
 	int i;
 
 	for (i = 0; i < alt->desc.bNumEndpoints; ++i)
-		usb_enable_endpoint(dev, &alt->endpoint[i].desc);
+		usb_enable_endpoint(dev, &alt->endpoint[i]);
 }
 
 /**
diff -Nru a/drivers/usb/core/otg_whitelist.h b/drivers/usb/core/otg_whitelist.h
--- a/drivers/usb/core/otg_whitelist.h	2005-03-01 23:39:18 -08:00
+++ b/drivers/usb/core/otg_whitelist.h	2005-03-01 23:39:18 -08:00
@@ -55,8 +55,8 @@
 		return 1;
 
 	/* HNP test device is _never_ targeted (see OTG spec 6.6.6) */
-	if (dev->descriptor.idVendor == 0x1a0a
-			&& dev->descriptor.idProduct == 0xbadd)
+	if ((le16_to_cpu(dev->descriptor.idVendor) == 0x1a0a && 
+	     le16_to_cpu(dev->descriptor.idProduct) == 0xbadd))
 		return 0;
 
 	/* NOTE: can't use usb_match_id() since interface caches
@@ -64,21 +64,21 @@
 	 */
 	for (id = whitelist_table; id->match_flags; id++) {
 		if ((id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) &&
-		    id->idVendor != dev->descriptor.idVendor)
+		    id->idVendor != le16_to_cpu(dev->descriptor.idVendor))
 			continue;
 
 		if ((id->match_flags & USB_DEVICE_ID_MATCH_PRODUCT) &&
-		    id->idProduct != dev->descriptor.idProduct)
+		    id->idProduct != le16_to_cpu(dev->descriptor.idProduct))
 			continue;
 
 		/* No need to test id->bcdDevice_lo != 0, since 0 is never
 		   greater than any unsigned number. */
 		if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_LO) &&
-		    (id->bcdDevice_lo > dev->descriptor.bcdDevice))
+		    (id->bcdDevice_lo > le16_to_cpu(dev->descriptor.bcdDevice)))
 			continue;
 
 		if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_HI) &&
-		    (id->bcdDevice_hi < dev->descriptor.bcdDevice))
+		    (id->bcdDevice_hi < le16_to_cpu(dev->descriptor.bcdDevice)))
 			continue;
 
 		if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_CLASS) &&
@@ -101,8 +101,8 @@
 
 	/* OTG MESSAGE: report errors here, customize to match your product */
 	dev_err(&dev->dev, "device v%04x p%04x is not supported\n",
-			dev->descriptor.idVendor,
-			dev->descriptor.idProduct);
+		le16_to_cpu(dev->descriptor.idVendor),
+		le16_to_cpu(dev->descriptor.idProduct));
 #ifdef	CONFIG_USB_OTG_WHITELIST
 	return 0;
 #else
diff -Nru a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c
--- a/drivers/usb/core/sysfs.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/usb/core/sysfs.c	2005-03-01 23:38:54 -08:00
@@ -149,10 +149,11 @@
 show_version (struct device *dev, char *buf)
 {
 	struct usb_device *udev;
+	u16 bcdUSB;
 
-	udev = to_usb_device (dev);
-	return sprintf (buf, "%2x.%02x\n", udev->descriptor.bcdUSB >> 8, 
-			udev->descriptor.bcdUSB & 0xff);
+	udev = to_usb_device(dev);
+	bcdUSB = le16_to_cpu(udev->descriptor.bcdUSB);
+	return sprintf(buf, "%2x.%02x\n", bcdUSB >> 8, bcdUSB & 0xff);
 }
 static DEVICE_ATTR(version, S_IRUGO, show_version, NULL);
 
@@ -167,6 +168,22 @@
 static DEVICE_ATTR(maxchild, S_IRUGO, show_maxchild, NULL);
 
 /* Descriptor fields */
+#define usb_descriptor_attr_le16(field, format_string)			\
+static ssize_t								\
+show_##field (struct device *dev, char *buf)				\
+{									\
+	struct usb_device *udev;					\
+									\
+	udev = to_usb_device (dev);					\
+	return sprintf (buf, format_string, 				\
+			le16_to_cpu(udev->descriptor.field));		\
+}									\
+static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL);
+
+usb_descriptor_attr_le16(idVendor, "%04x\n")
+usb_descriptor_attr_le16(idProduct, "%04x\n")
+usb_descriptor_attr_le16(bcdDevice, "%04x\n")
+
 #define usb_descriptor_attr(field, format_string)			\
 static ssize_t								\
 show_##field (struct device *dev, char *buf)				\
@@ -178,9 +195,6 @@
 }									\
 static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL);
 
-usb_descriptor_attr (idVendor, "%04x\n")
-usb_descriptor_attr (idProduct, "%04x\n")
-usb_descriptor_attr (bcdDevice, "%04x\n")
 usb_descriptor_attr (bDeviceClass, "%02x\n")
 usb_descriptor_attr (bDeviceSubClass, "%02x\n")
 usb_descriptor_attr (bDeviceProtocol, "%02x\n")
diff -Nru a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c
--- a/drivers/usb/core/urb.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/usb/core/urb.c	2005-03-01 23:38:58 -08:00
@@ -265,7 +265,7 @@
 	max = usb_maxpacket (dev, pipe, is_out);
 	if (max <= 0) {
 		dev_dbg(&dev->dev,
-			"bogus endpoint ep%d%s in %s (bad maxpacket %d)",
+			"bogus endpoint ep%d%s in %s (bad maxpacket %d)\n",
 			usb_pipeendpoint (pipe), is_out ? "out" : "in",
 			__FUNCTION__, max);
 		return -EMSGSIZE;
diff -Nru a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
--- a/drivers/usb/core/usb.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/usb/core/usb.c	2005-03-01 23:38:57 -08:00
@@ -63,8 +63,7 @@
 int nousb;		/* Disable USB when built into kernel image */
 			/* Not honored on modular build */
 
-DECLARE_RWSEM(usb_all_devices_rwsem);
-EXPORT_SYMBOL(usb_all_devices_rwsem);
+static DECLARE_RWSEM(usb_all_devices_rwsem);
 
 
 static int generic_probe (struct device *dev)
@@ -267,44 +266,6 @@
 }
 
 /**
- * usb_epnum_to_ep_desc - get the endpoint object with a given endpoint number
- * @dev: the device whose current configuration+altsettings is considered
- * @epnum: the desired endpoint, masked with USB_DIR_IN as appropriate.
- *
- * This walks the device descriptor for the currently active configuration,
- * and returns a pointer to the endpoint with that particular endpoint
- * number, or null.
- *
- * Note that interface descriptors are not required to list endpoint
- * numbers in any standardized order, so that it would be wrong to
- * assume that ep2in precedes either ep5in, ep2out, or even ep1out.
- * This routine helps device drivers avoid such mistakes.
- */
-struct usb_endpoint_descriptor *
-usb_epnum_to_ep_desc(struct usb_device *dev, unsigned epnum)
-{
-	struct usb_host_config *config = dev->actconfig;
-	int i, k;
-
-	if (!config)
-		return NULL;
-	for (i = 0; i < config->desc.bNumInterfaces; i++) {
-		struct usb_interface		*intf;
-		struct usb_host_interface	*alt;
-
-		/* only endpoints in current altsetting are active */
-		intf = config->interface[i];
-		alt = intf->cur_altsetting;
-
-		for (k = 0; k < alt->desc.bNumEndpoints; k++)
-			if (epnum == alt->endpoint[k].desc.bEndpointAddress)
-				return &alt->endpoint[k].desc;
-	}
-
-	return NULL;
-}
-
-/**
  * usb_driver_claim_interface - bind a driver to an interface
  * @driver: the driver to be bound
  * @iface: the interface to which it will be bound; must be in the
@@ -461,21 +422,21 @@
 	       id->driver_info; id++) {
 
 		if ((id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) &&
-		    id->idVendor != dev->descriptor.idVendor)
+		    id->idVendor != le16_to_cpu(dev->descriptor.idVendor))
 			continue;
 
 		if ((id->match_flags & USB_DEVICE_ID_MATCH_PRODUCT) &&
-		    id->idProduct != dev->descriptor.idProduct)
+		    id->idProduct != le16_to_cpu(dev->descriptor.idProduct))
 			continue;
 
 		/* No need to test id->bcdDevice_lo != 0, since 0 is never
 		   greater than any unsigned number. */
 		if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_LO) &&
-		    (id->bcdDevice_lo > dev->descriptor.bcdDevice))
+		    (id->bcdDevice_lo > le16_to_cpu(dev->descriptor.bcdDevice)))
 			continue;
 
 		if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_HI) &&
-		    (id->bcdDevice_hi < dev->descriptor.bcdDevice))
+		    (id->bcdDevice_hi < le16_to_cpu(dev->descriptor.bcdDevice)))
 			continue;
 
 		if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_CLASS) &&
@@ -626,9 +587,9 @@
 	if (add_hotplug_env_var(envp, num_envp, &i,
 				buffer, buffer_size, &length,
 				"PRODUCT=%x/%x/%x",
-				usb_dev->descriptor.idVendor,
-				usb_dev->descriptor.idProduct,
-				usb_dev->descriptor.bcdDevice))
+				le16_to_cpu(usb_dev->descriptor.idVendor),
+				le16_to_cpu(usb_dev->descriptor.idProduct),
+				le16_to_cpu(usb_dev->descriptor.bcdDevice)))
 		return -ENOMEM;
 
 	/* class-based driver binding models */
@@ -684,8 +645,6 @@
 
 	udev = to_usb_device(dev);
 
-	if (udev->bus && udev->bus->op && udev->bus->op->deallocate)
-		udev->bus->op->deallocate(udev);
 	usb_destroy_configuration(udev);
 	usb_bus_put(udev->bus);
 	kfree (udev);
@@ -695,7 +654,7 @@
  * usb_alloc_dev - usb device constructor (usbcore-internal)
  * @parent: hub to which device is connected; null to allocate a root hub
  * @bus: bus used to access the device
- * @port: zero based index of port; ignored for root hubs
+ * @port1: one-based index of port; ignored for root hubs
  * Context: !in_interrupt ()
  *
  * Only hub drivers (including virtual root hub drivers for host
@@ -704,7 +663,7 @@
  * This call may not be used in a non-sleeping context.
  */
 struct usb_device *
-usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus, unsigned port)
+usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus, unsigned port1)
 {
 	struct usb_device *dev;
 
@@ -728,6 +687,12 @@
 	dev->dev.release = usb_release_dev;
 	dev->state = USB_STATE_ATTACHED;
 
+	INIT_LIST_HEAD(&dev->ep0.urb_list);
+	dev->ep0.desc.bLength = USB_DT_ENDPOINT_SIZE;
+	dev->ep0.desc.bDescriptorType = USB_DT_ENDPOINT;
+	/* ep0 maxpacket comes later, from device descriptor */
+	dev->ep_in[0] = dev->ep_out[0] = &dev->ep0;
+
 	/* Save readable and stable topology id, distinguishing devices
 	 * by location for diagnostics, tools, driver model, etc.  The
 	 * string is a path along hub ports, from the root.  Each device's
@@ -745,10 +710,10 @@
 		/* match any labeling on the hubs; it's one-based */
 		if (parent->devpath [0] == '0')
 			snprintf (dev->devpath, sizeof dev->devpath,
-				"%d", port + 1);
+				"%d", port1);
 		else
 			snprintf (dev->devpath, sizeof dev->devpath,
-				"%s.%d", parent->devpath, port + 1);
+				"%s.%d", parent->devpath, port1);
 
 		dev->dev.parent = &parent->dev;
 		sprintf (&dev->dev.bus_id[0], "%d-%s",
@@ -763,13 +728,6 @@
 
 	init_MUTEX(&dev->serialize);
 
-	if (dev->bus->op->allocate)
-		if (dev->bus->op->allocate(dev)) {
-			usb_bus_put(bus);
-			kfree(dev);
-			return NULL;
-		}
-
 	return dev;
 }
 
@@ -1000,12 +958,12 @@
 	int child;
 
 	dev_dbg(&dev->dev, "check for vendor %04x, product %04x ...\n",
-	    dev->descriptor.idVendor,
-	    dev->descriptor.idProduct);
+	    le16_to_cpu(dev->descriptor.idVendor),
+	    le16_to_cpu(dev->descriptor.idProduct));
 
 	/* see if this device matches */
-	if ((dev->descriptor.idVendor == vendor_id) &&
-	    (dev->descriptor.idProduct == product_id)) {
+	if ((vendor_id == le16_to_cpu(dev->descriptor.idVendor)) &&
+	    (product_id == le16_to_cpu(dev->descriptor.idProduct))) {
 		dev_dbg (&dev->dev, "matched this device!\n");
 		ret_dev = usb_get_dev(dev);
 		goto exit;
@@ -1533,7 +1491,6 @@
  * These symbols are exported for device (or host controller)
  * driver modules to use.
  */
-EXPORT_SYMBOL(usb_epnum_to_ep_desc);
 
 EXPORT_SYMBOL(usb_register);
 EXPORT_SYMBOL(usb_deregister);
diff -Nru a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h
--- a/drivers/usb/core/usb.h	2005-03-01 23:38:53 -08:00
+++ b/drivers/usb/core/usb.h	2005-03-01 23:38:53 -08:00
@@ -13,8 +13,6 @@
 extern void usb_release_interface_cache(struct kref *ref);
 extern void usb_disable_device (struct usb_device *dev, int skip_ep0);
 
-extern void usb_enable_endpoint (struct usb_device *dev,
-		struct usb_endpoint_descriptor *epd);
 extern void usb_enable_interface (struct usb_device *dev,
 		struct usb_interface *intf);
 
diff -Nru a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
--- a/drivers/usb/gadget/Kconfig	2005-03-01 23:38:54 -08:00
+++ b/drivers/usb/gadget/Kconfig	2005-03-01 23:38:54 -08:00
@@ -39,6 +39,9 @@
 	   If in doubt, say "N" and don't enable these drivers; most people
 	   don't have this kind of hardware (except maybe inside Linux PDAs).
 
+	   For more information, see <http://www.linux-usb.org/gadget> and
+	   the kernel DocBook documentation for this API.
+
 config USB_GADGET_DEBUG_FILES
 	boolean "Debugging information files"
 	depends on USB_GADGET && PROC_FS
@@ -59,6 +62,8 @@
 	help
 	   A USB device uses a controller to talk to its host.
 	   Systems should have only one such upstream link.
+	   Many controller drivers are platform-specific; these
+	   often need board-specific hooks.
 
 config USB_GADGET_NET2280
 	boolean "NetChip 2280"
@@ -234,6 +239,21 @@
 	tristate "USB Gadget Drivers"
 	depends on USB_GADGET
 	default USB_ETH
+	help
+	  A Linux "Gadget Driver" talks to the USB Peripheral Controller
+	  driver through the abstract "gadget" API.  Some other operating
+	  systems call these "client" drivers, of which "class drivers"
+	  are a subset (implementing a USB device class specification).
+	  A gadget driver implements one or more USB functions using
+	  the peripheral hardware.
+
+	  Gadget drivers are hardware-neutral, or "platform independent",
+	  except that they sometimes must understand quirks or limitations
+	  of the particular controllers they work with.  For example, when
+	  a controller doesn't support alternate configurations or provide
+	  enough of the right types of endpoints, the gadget driver might
+	  not be able work with that controller, or might need to implement
+	  a less common variant of a device class protocol.
 
 # this first set of drivers all depend on bulk-capable hardware.
 
@@ -273,7 +293,7 @@
 	  one serve as the USB host instead (in the "B-Host" role).
 
 config USB_ETH
-	tristate "Ethernet Gadget"
+	tristate "Ethernet Gadget (with CDC Ethernet support)"
 	depends on NET
 	help
 	  This driver implements Ethernet style communication, in either
@@ -314,6 +334,11 @@
 	   If you say "y" here, the Ethernet gadget driver will try to provide
 	   a second device configuration, supporting RNDIS to talk to such
 	   Microsoft USB hosts.
+	   
+	   To make MS-Windows work with this, use Documentation/usb/linux.inf
+	   as the "driver info file".  For versions of MS-Windows older than
+	   XP, you'll need to download drivers from Microsoft's website; a URL
+	   is given in comments found in that info file.
 
 config USB_GADGETFS
 	tristate "Gadget Filesystem (EXPERIMENTAL)"
@@ -352,13 +377,19 @@
 	  normal operation.
 
 config USB_G_SERIAL
-	tristate "Serial Gadget"
+	tristate "Serial Gadget (with CDC ACM support)"
 	help
 	  The Serial Gadget talks to the Linux-USB generic serial driver.
+	  This driver supports a CDC-ACM module option, which can be used
+	  to interoperate with MS-Windows hosts or with the Linux-USB
+	  "cdc-acm" driver.
 
 	  Say "y" to link the driver statically, or "m" to build a
 	  dynamically linked module called "g_serial".
 
+	  For more information, see Documentation/usb/gadget_serial.txt
+	  which includes instructions and a "driver info file" needed to
+	  make MS-Windows work with this driver.
 
 
 # put drivers that need isochronous transfer support (for audio
diff -Nru a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c
--- a/drivers/usb/gadget/dummy_hcd.c	2005-03-01 23:38:51 -08:00
+++ b/drivers/usb/gadget/dummy_hcd.c	2005-03-01 23:38:51 -08:00
@@ -65,7 +65,7 @@
 
 
 #define DRIVER_DESC	"USB Host+Gadget Emulator"
-#define DRIVER_VERSION	"29 Oct 2004"
+#define DRIVER_VERSION	"17 Dec 2004"
 
 static const char	driver_name [] = "dummy_hcd";
 static const char	driver_desc [] = "USB Host+Gadget Emulator";
@@ -143,8 +143,12 @@
 
 #define FIFO_SIZE		64
 
+struct urbp {
+	struct urb		*urb;
+	struct list_head	urbp_list;
+};
+
 struct dummy {
-	struct usb_hcd			hcd;		/* must come first! */
 	spinlock_t			lock;
 
 	/*
@@ -168,16 +172,22 @@
 	unsigned long			re_timeout;
 
 	struct usb_device		*udev;
+	struct list_head		urbp_list;
 };
 
 static inline struct dummy *hcd_to_dummy (struct usb_hcd *hcd)
 {
-	return container_of(hcd, struct dummy, hcd);
+	return (struct dummy *) (hcd->hcd_priv);
+}
+
+static inline struct usb_hcd *dummy_to_hcd (struct dummy *dum)
+{
+	return container_of((void *) dum, struct usb_hcd, hcd_priv);
 }
 
 static inline struct device *dummy_dev (struct dummy *dum)
 {
-	return dum->hcd.self.controller;
+	return dummy_to_hcd(dum)->self.controller;
 }
 
 static inline struct dummy *ep_to_dummy (struct dummy_ep *ep)
@@ -237,7 +247,7 @@
 	dum = ep_to_dummy (ep);
 	if (!dum->driver || !is_enabled (dum))
 		return -ESHUTDOWN;
-	max = desc->wMaxPacketSize & 0x3ff;
+	max = le16_to_cpu(desc->wMaxPacketSize) & 0x3ff;
 
 	/* drivers must not request bad settings, since lower levels
 	 * (hardware or its drivers) may not check.  some endpoints
@@ -365,7 +375,7 @@
 	dum = ep_to_dummy (ep);
 
 	spin_lock_irqsave (&dum->lock, flags);
-	ep->desc = 0;
+	ep->desc = NULL;
 	retval = 0;
 	nuke (dum, ep);
 	spin_unlock_irqrestore (&dum->lock, flags);
@@ -381,12 +391,12 @@
 	struct dummy_request	*req;
 
 	if (!_ep)
-		return 0;
+		return NULL;
 	ep = usb_ep_to_dummy_ep (_ep);
 
 	req = kmalloc (sizeof *req, mem_flags);
 	if (!req)
-		return 0;
+		return NULL;
 	memset (req, 0, sizeof *req);
 	INIT_LIST_HEAD (&req->queue);
 	return &req->req;
@@ -422,7 +432,7 @@
 	dum = ep_to_dummy (ep);
 
 	if (!dum->driver)
-		return 0;
+		return NULL;
 	retval = kmalloc (bytes, mem_flags);
 	*dma = (dma_addr_t) retval;
 	return retval;
@@ -506,7 +516,7 @@
 	struct dummy		*dum;
 	int			retval = -EINVAL;
 	unsigned long		flags;
-	struct dummy_request	*req = 0;
+	struct dummy_request	*req = NULL;
 
 	if (!_ep || !_req)
 		return retval;
@@ -720,7 +730,7 @@
 		ep->ep.maxpacket = ~0;
 		ep->last_io = jiffies;
 		ep->gadget = &dum->gadget;
-		ep->desc = 0;
+		ep->desc = NULL;
 		INIT_LIST_HEAD (&ep->queue);
 	}
 
@@ -734,8 +744,8 @@
 	dev_dbg (dummy_dev(dum), "binding gadget driver '%s'\n",
 			driver->driver.name);
 	if ((retval = driver->bind (&dum->gadget)) != 0) {
-		dum->driver = 0;
-		dum->gadget.dev.driver = 0;
+		dum->driver = NULL;
+		dum->gadget.dev.driver = NULL;
 		return retval;
 	}
 
@@ -797,7 +807,7 @@
 	spin_unlock_irqrestore (&dum->lock, flags);
 
 	driver->unbind (&dum->gadget);
-	dum->driver = 0;
+	dum->driver = NULL;
 
 	device_release_driver (&dum->gadget.dev);
 
@@ -830,16 +840,23 @@
  */
 
 static int dummy_urb_enqueue (
-	struct usb_hcd	*hcd,
-	struct urb	*urb,
-	int		mem_flags
+	struct usb_hcd			*hcd,
+	struct usb_host_endpoint	*ep,
+	struct urb			*urb,
+	int				mem_flags
 ) {
 	struct dummy	*dum;
+	struct urbp	*urbp;
 	unsigned long	flags;
 
 	if (!urb->transfer_buffer && urb->transfer_buffer_length)
 		return -EINVAL;
 
+	urbp = kmalloc (sizeof *urbp, mem_flags);
+	if (!urbp)
+		return -ENOMEM;
+	urbp->urb = urb;
+
 	dum = hcd_to_dummy (hcd);
 	spin_lock_irqsave (&dum->lock, flags);
 
@@ -849,7 +866,8 @@
 	} else if (unlikely (dum->udev != urb->dev))
 		dev_err (dummy_dev(dum), "usb_device address has changed!\n");
 
-	urb->hcpriv = dum;
+	list_add_tail (&urbp->urbp_list, &dum->urbp_list);
+	urb->hcpriv = urbp;
 	if (usb_pipetype (urb->pipe) == PIPE_CONTROL)
 		urb->error_count = 1;		/* mark as a new urb */
 
@@ -1007,7 +1025,7 @@
 		int	tmp;
 
 		/* high bandwidth mode */
-		tmp = ep->desc->wMaxPacketSize;
+		tmp = le16_to_cpu(ep->desc->wMaxPacketSize);
 		tmp = le16_to_cpu (tmp);
 		tmp = (tmp >> 11) & 0x03;
 		tmp *= 8 /* applies to entire frame */;
@@ -1055,8 +1073,7 @@
 static void dummy_timer (unsigned long _dum)
 {
 	struct dummy		*dum = (struct dummy *) _dum;
-	struct hcd_dev		*hdev;
-	struct list_head	*entry, *tmp;
+	struct urbp		*urbp, *tmp;
 	unsigned long		flags;
 	int			limit, total;
 	int			i;
@@ -1088,7 +1105,6 @@
 		spin_unlock_irqrestore (&dum->lock, flags);
 		return;
 	}
-	hdev = dum->udev->hcpriv;
 
 	for (i = 0; i < DUMMY_ENDPOINTS; i++) {
 		if (!ep_name [i])
@@ -1097,14 +1113,14 @@
 	}
 
 restart:
-	list_for_each_safe (entry, tmp, &hdev->urb_list) {
+	list_for_each_entry_safe (urbp, tmp, &dum->urbp_list, urbp_list) {
 		struct urb		*urb;
 		struct dummy_request	*req;
 		u8			address;
-		struct dummy_ep		*ep = 0;
+		struct dummy_ep		*ep = NULL;
 		int			type;
 
-		urb = list_entry (entry, struct urb, urb_list);
+		urb = urbp->urb;
 		if (urb->status != -EINPROGRESS) {
 			/* likely it was just unlinked */
 			goto return_urb;
@@ -1349,19 +1365,21 @@
 			continue;
 
 return_urb:
-		urb->hcpriv = 0;
+		urb->hcpriv = NULL;
+		list_del (&urbp->urbp_list);
+		kfree (urbp);
 		if (ep)
 			ep->already_seen = ep->setup_stage = 0;
 
 		spin_unlock (&dum->lock);
-		usb_hcd_giveback_urb (&dum->hcd, urb, 0);
+		usb_hcd_giveback_urb (dummy_to_hcd(dum), urb, NULL);
 		spin_lock (&dum->lock);
 
 		goto restart;
 	}
 
 	/* want a 1 msec delay here */
-	if (!list_empty (&hdev->urb_list))
+	if (!list_empty (&dum->urbp_list))
 		mod_timer (&dum->timer, jiffies + msecs_to_jiffies(1));
 	else {
 		usb_put_dev (dum->udev);
@@ -1556,20 +1574,6 @@
 
 /*-------------------------------------------------------------------------*/
 
-static struct usb_hcd *dummy_alloc (void)
-{
-	struct dummy		*dum;
-
-	dum = kmalloc (sizeof *dum, SLAB_KERNEL);
-	if (dum == NULL)
-		return NULL;
-	the_controller = dum;
-	memset (dum, 0, sizeof *dum);
-	return &dum->hcd;
-}
-
-/*-------------------------------------------------------------------------*/
-
 static inline ssize_t
 show_urb (char *buf, size_t size, struct urb *urb)
 {
@@ -1601,21 +1605,17 @@
 {
 	struct usb_hcd		*hcd = dev_get_drvdata (dev);
 	struct dummy		*dum = hcd_to_dummy (hcd);
-	struct urb		*urb;
+	struct urbp		*urbp;
 	size_t			size = 0;
 	unsigned long		flags;
-	struct hcd_dev		*hdev;
 
 	spin_lock_irqsave (&dum->lock, flags);
-	if (dum->udev) {
-		hdev = dum->udev->hcpriv;
-		list_for_each_entry (urb, &hdev->urb_list, urb_list) {
-			size_t		temp;
-
-			temp = show_urb (buf, PAGE_SIZE - size, urb);
-			buf += temp;
-			size += temp;
-		}
+	list_for_each_entry (urbp, &dum->urbp_list, urbp_list) {
+		size_t		temp;
+
+		temp = show_urb (buf, PAGE_SIZE - size, urbp->urb);
+		buf += temp;
+		size += temp;
 	}
 	spin_unlock_irqrestore (&dum->lock, flags);
 
@@ -1642,7 +1642,9 @@
 	dum->timer.function = dummy_timer;
 	dum->timer.data = (unsigned long) dum;
 
-	root = usb_alloc_dev (0, &hcd->self, 0);
+	INIT_LIST_HEAD (&dum->urbp_list);
+
+	root = usb_alloc_dev (NULL, &hcd->self, 0);
 	if (!root)
 		return -ENOMEM;
 
@@ -1694,18 +1696,19 @@
 
 static int dummy_h_get_frame (struct usb_hcd *hcd)
 {
-	return dummy_g_get_frame (0);
+	return dummy_g_get_frame (NULL);
 }
 
 static const struct hc_driver dummy_hcd = {
 	.description =		(char *) driver_name,
+	.product_desc =		"Dummy host controller",
+	.hcd_priv_size =	sizeof(struct dummy),
+
 	.flags =		HCD_USB2,
 
 	.start =		dummy_start,
 	.stop =			dummy_stop,
 
-	.hcd_alloc = 		dummy_alloc,
-
 	.urb_enqueue = 		dummy_urb_enqueue,
 	.urb_dequeue = 		dummy_urb_dequeue,
 
@@ -1725,7 +1728,7 @@
 
 	dev_info (dev, "%s, driver " DRIVER_VERSION "\n", driver_desc);
 
-	hcd = dummy_alloc ();
+	hcd = usb_create_hcd (&dummy_hcd);
 	if (hcd == NULL) {
 		dev_dbg (dev, "hcd_alloc failed\n");
 		return -ENOMEM;
@@ -1733,9 +1736,8 @@
 
 	dev_set_drvdata (dev, hcd);
 	dum = hcd_to_dummy (hcd);
+	the_controller = dum;
 
-	hcd->driver = (struct hc_driver *) &dummy_hcd;
-	hcd->description = dummy_hcd.description;
 	hcd->self.controller = dev;
 
 	/* FIXME don't require the pci-based buffer/alloc impls;
@@ -1748,15 +1750,7 @@
 		goto err1;
 	}
 
-	usb_bus_init (&hcd->self);
-	hcd->self.op = &usb_hcd_operations;
-	hcd->self.release = &usb_hcd_release;
-	hcd->self.hcpriv = hcd;
 	hcd->self.bus_name = dev->bus_id;
-	hcd->product_desc = "Dummy host controller";
-
-	INIT_LIST_HEAD (&hcd->dev_list);
-
 	usb_register_bus (&hcd->self);
 
 	if ((retval = dummy_start (hcd)) < 0) 
@@ -1764,7 +1758,7 @@
 	return retval;
 
 err1:
-	kfree (hcd);
+	usb_put_hcd (hcd);
 	dev_set_drvdata (dev, NULL);
 	return retval;
 }
diff -Nru a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c
--- a/drivers/usb/gadget/epautoconf.c	2005-03-01 23:39:19 -08:00
+++ b/drivers/usb/gadget/epautoconf.c	2005-03-01 23:39:19 -08:00
@@ -55,6 +55,9 @@
  *
  * Type suffixes are "-bulk", "-iso", or "-int".  Numbers are decimal.
  * Less common restrictions are implied by gadget_is_*().
+ *
+ * NOTE:  each endpoint is unidirectional, as specified by its USB
+ * descriptor; and isn't specific to a configuration or altsetting.
  */
 static int __init
 ep_matches (
diff -Nru a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
--- a/drivers/usb/gadget/ether.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/usb/gadget/ether.c	2005-03-01 23:39:17 -08:00
@@ -36,8 +36,7 @@
 #include <linux/timer.h>
 #include <linux/list.h>
 #include <linux/interrupt.h>
-#include <linux/uts.h>
-#include <linux/version.h>
+#include <linux/utsname.h>
 #include <linux/device.h>
 #include <linux/moduleparam.h>
 #include <linux/ctype.h>
@@ -2337,8 +2336,8 @@
 			gadget->name);
 		return -ENODEV;
 	}
-	snprintf (manufacturer, sizeof manufacturer,
-		UTS_SYSNAME " " UTS_RELEASE "/%s",
+	snprintf (manufacturer, sizeof manufacturer, "%s %s/%s",
+		system_utsname.sysname, system_utsname.release,
 		gadget->name);
 
 	/* If there's an RNDIS configuration, that's what Windows wants to
diff -Nru a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
--- a/drivers/usb/gadget/file_storage.c	2005-03-01 23:39:19 -08:00
+++ b/drivers/usb/gadget/file_storage.c	2005-03-01 23:39:19 -08:00
@@ -236,8 +236,7 @@
 #include <linux/spinlock.h>
 #include <linux/string.h>
 #include <linux/suspend.h>
-#include <linux/uts.h>
-#include <linux/version.h>
+#include <linux/utsname.h>
 #include <linux/wait.h>
 
 #include <linux/usb_ch9.h>
@@ -3132,7 +3131,7 @@
 	if ((rc = enable_endpoint(fsg, fsg->bulk_out, d)) != 0)
 		goto reset;
 	fsg->bulk_out_enabled = 1;
-	fsg->bulk_out_maxpacket = d->wMaxPacketSize;
+	fsg->bulk_out_maxpacket = le16_to_cpu(d->wMaxPacketSize);
 
 	if (transport_is_cbi()) {
 		d = ep_desc(fsg->gadget, &fs_intr_in_desc, &hs_intr_in_desc);
@@ -3954,8 +3953,8 @@
 	/* This should reflect the actual gadget power source */
 	usb_gadget_set_selfpowered(gadget);
 
-	snprintf(manufacturer, sizeof manufacturer,
-			UTS_SYSNAME " " UTS_RELEASE " with %s",
+	snprintf(manufacturer, sizeof manufacturer, "%s %s with %s",
+			system_utsname.sysname, system_utsname.release,
 			gadget->name);
 
 	/* On a real device, serial[] would be loaded from permanent
diff -Nru a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c
--- a/drivers/usb/gadget/inode.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/usb/gadget/inode.c	2005-03-01 23:39:08 -08:00
@@ -2022,6 +2022,7 @@
 	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
 	sb->s_magic = GADGETFS_MAGIC;
 	sb->s_op = &gadget_fs_operations;
+	sb->s_time_gran = 1;
 
 	/* root inode */
 	inode = gadgetfs_make_inode (sb,
diff -Nru a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c
--- a/drivers/usb/gadget/omap_udc.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/usb/gadget/omap_udc.c	2005-03-01 23:38:54 -08:00
@@ -1,5 +1,5 @@
 /*
- * omap_udc.c -- for OMAP 1610 udc, with OTG support
+ * omap_udc.c -- for OMAP full speed udc; most chips support OTG.
  *
  * Copyright (C) 2004 Texas Instruments, Inc.
  * Copyright (C) 2004 David Brownell
diff -Nru a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c
--- a/drivers/usb/gadget/serial.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/usb/gadget/serial.c	2005-03-01 23:39:09 -08:00
@@ -30,8 +30,7 @@
 #include <linux/timer.h>
 #include <linux/list.h>
 #include <linux/interrupt.h>
-#include <linux/uts.h>
-#include <linux/version.h>
+#include <linux/utsname.h>
 #include <linux/wait.h>
 #include <linux/proc_fs.h>
 #include <linux/device.h>
@@ -1596,8 +1595,9 @@
 	if (dev == NULL)
 		return -ENOMEM;
 
-	snprintf(manufacturer, sizeof(manufacturer),
-		UTS_SYSNAME " " UTS_RELEASE " with %s", gadget->name);
+	snprintf(manufacturer, sizeof(manufacturer), "%s %s with %s",
+		system_utsname.sysname, system_utsname.release,
+		gadget->name);
 
 	memset(dev, 0, sizeof(struct gs_dev));
 	dev->dev_gadget = gadget;
@@ -2322,11 +2322,11 @@
 					wake_up_interruptible(&port->port_tty->read_wait);
 					wake_up_interruptible(&port->port_tty->write_wait);
 				}
+				spin_unlock_irqrestore(&port->port_lock, flags);
 			} else {
 				kfree(port);
 			}
 
-			spin_unlock_irqrestore(&port->port_lock, flags);
 		}
 	}
 }
diff -Nru a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c
--- a/drivers/usb/gadget/zero.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/usb/gadget/zero.c	2005-03-01 23:38:56 -08:00
@@ -75,8 +75,7 @@
 #include <linux/timer.h>
 #include <linux/list.h>
 #include <linux/interrupt.h>
-#include <linux/uts.h>
-#include <linux/version.h>
+#include <linux/utsname.h>
 #include <linux/device.h>
 #include <linux/moduleparam.h>
 
@@ -1265,8 +1264,8 @@
 	INFO (dev, "using %s, OUT %s IN %s\n", gadget->name,
 		EP_OUT_NAME, EP_IN_NAME);
 
-	snprintf (manufacturer, sizeof manufacturer,
-		UTS_SYSNAME " " UTS_RELEASE " with %s",
+	snprintf (manufacturer, sizeof manufacturer, "%s %s with %s",
+		system_utsname.sysname, system_utsname.release,
 		gadget->name);
 
 	return 0;
diff -Nru a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c
--- a/drivers/usb/host/ehci-dbg.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/usb/host/ehci-dbg.c	2005-03-01 23:39:09 -08:00
@@ -19,13 +19,13 @@
 /* this file is part of ehci-hcd.c */
 
 #define ehci_dbg(ehci, fmt, args...) \
-	dev_dbg ((ehci)->hcd.self.controller , fmt , ## args )
+	dev_dbg (ehci_to_hcd(ehci)->self.controller , fmt , ## args )
 #define ehci_err(ehci, fmt, args...) \
-	dev_err ((ehci)->hcd.self.controller , fmt , ## args )
+	dev_err (ehci_to_hcd(ehci)->self.controller , fmt , ## args )
 #define ehci_info(ehci, fmt, args...) \
-	dev_info ((ehci)->hcd.self.controller , fmt , ## args )
+	dev_info (ehci_to_hcd(ehci)->self.controller , fmt , ## args )
 #define ehci_warn(ehci, fmt, args...) \
-	dev_warn ((ehci)->hcd.self.controller , fmt , ## args )
+	dev_warn (ehci_to_hcd(ehci)->self.controller , fmt , ## args )
 
 #ifdef EHCI_VERBOSE_DEBUG
 #	define vdbg dbg
@@ -657,7 +657,7 @@
 		"EHCI %x.%02x, hcd state %d\n",
 		hcd->self.controller->bus->name,
 		hcd->self.controller->bus_id,
-		i >> 8, i & 0x0ff, ehci->hcd.state);
+		i >> 8, i & 0x0ff, hcd->state);
 	size -= temp;
 	next += temp;
 
@@ -733,18 +733,22 @@
 }
 static CLASS_DEVICE_ATTR (registers, S_IRUGO, show_registers, NULL);
 
-static inline void create_debug_files (struct ehci_hcd *bus)
+static inline void create_debug_files (struct ehci_hcd *ehci)
 {
-	class_device_create_file(&bus->hcd.self.class_dev, &class_device_attr_async);
-	class_device_create_file(&bus->hcd.self.class_dev, &class_device_attr_periodic);
-	class_device_create_file(&bus->hcd.self.class_dev, &class_device_attr_registers);
+	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);
+	class_device_create_file(cldev, &class_device_attr_registers);
 }
 
-static inline void remove_debug_files (struct ehci_hcd *bus)
+static inline void remove_debug_files (struct ehci_hcd *ehci)
 {
-	class_device_remove_file(&bus->hcd.self.class_dev, &class_device_attr_async);
-	class_device_remove_file(&bus->hcd.self.class_dev, &class_device_attr_periodic);
-	class_device_remove_file(&bus->hcd.self.class_dev, &class_device_attr_registers);
+	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);
+	class_device_remove_file(cldev, &class_device_attr_registers);
 }
 
 #endif /* STUB_DEBUG_FILES */
diff -Nru a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
--- a/drivers/usb/host/ehci-hcd.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/usb/host/ehci-hcd.c	2005-03-01 23:39:07 -08:00
@@ -97,7 +97,7 @@
  * 2001-June	Works with usb-storage and NEC EHCI on 2.4
  */
 
-#define DRIVER_VERSION "26 Oct 2004"
+#define DRIVER_VERSION "10 Dec 2004"
 #define DRIVER_AUTHOR "David Brownell"
 #define DRIVER_DESC "USB 2.0 'Enhanced' Host Controller (EHCI) Driver"
 
@@ -124,11 +124,16 @@
 #define EHCI_ASYNC_JIFFIES	(HZ/20)		/* async idle timeout */
 #define EHCI_SHRINK_JIFFIES	(HZ/200)	/* async qh unlink delay */
 
-/* Initial IRQ latency:  lower than default */
+/* Initial IRQ latency:  faster than hw default */
 static int log2_irq_thresh = 0;		// 0 to 6
 module_param (log2_irq_thresh, int, S_IRUGO);
 MODULE_PARM_DESC (log2_irq_thresh, "log2 IRQ latency, 1-64 microframes");
 
+/* initial park setting:  slower than hw default */
+static unsigned park = 0;
+module_param (park, uint, S_IRUGO);
+MODULE_PARM_DESC (park, "park setting; 1-3 back-to-back async packets");
+
 #define	INTR_MASK (STS_IAA | STS_FATAL | STS_PCD | STS_ERR | STS_INT)
 
 /*-------------------------------------------------------------------------*/
@@ -194,7 +199,7 @@
 	command |= CMD_RESET;
 	dbg_cmd (ehci, "reset", command);
 	writel (command, &ehci->regs->command);
-	ehci->hcd.state = USB_STATE_HALT;
+	ehci_to_hcd(ehci)->state = USB_STATE_HALT;
 	ehci->next_statechange = jiffies;
 	return handshake (&ehci->regs->command, CMD_RESET, 0, 250 * 1000);
 }
@@ -205,7 +210,7 @@
 	u32	temp;
 
 #ifdef DEBUG
-	if (!HCD_IS_RUNNING (ehci->hcd.state))
+	if (!HCD_IS_RUNNING (ehci_to_hcd(ehci)->state))
 		BUG ();
 #endif
 
@@ -214,7 +219,7 @@
 	temp &= STS_ASS | STS_PSS;
 	if (handshake (&ehci->regs->status, STS_ASS | STS_PSS,
 				temp, 16 * 125) != 0) {
-		ehci->hcd.state = USB_STATE_HALT;
+		ehci_to_hcd(ehci)->state = USB_STATE_HALT;
 		return;
 	}
 
@@ -226,7 +231,7 @@
 	/* hardware can take 16 microframes to turn off ... */
 	if (handshake (&ehci->regs->status, STS_ASS | STS_PSS,
 				0, 16 * 125) != 0) {
-		ehci->hcd.state = USB_STATE_HALT;
+		ehci_to_hcd(ehci)->state = USB_STATE_HALT;
 		return;
 	}
 }
@@ -280,7 +285,8 @@
 {
 	if (cap & (1 << 16)) {
 		int msec = 5000;
-		struct pci_dev *pdev = to_pci_dev(ehci->hcd.self.controller);
+		struct pci_dev *pdev =
+				to_pci_dev(ehci_to_hcd(ehci)->self.controller);
 
 		/* request handoff to OS */
 		cap |= 1 << 24;
@@ -338,7 +344,7 @@
 #ifdef	CONFIG_PCI
 	/* EHCI 0.96 and later may have "extended capabilities" */
 	if (hcd->self.controller->bus == &pci_bus_type) {
-		struct pci_dev	*pdev = to_pci_dev(ehci->hcd.self.controller);
+		struct pci_dev	*pdev = to_pci_dev(hcd->self.controller);
 
 		/* AMD8111 EHCI doesn't work, according to AMD errata */
 		if ((pdev->vendor == PCI_VENDOR_ID_AMD)
@@ -353,7 +359,7 @@
 	while (temp && count--) {
 		u32		cap;
 
-		pci_read_config_dword (to_pci_dev(ehci->hcd.self.controller),
+		pci_read_config_dword (to_pci_dev(hcd->self.controller),
 				temp, &cap);
 		ehci_dbg (ehci, "capability %04x at %02x\n", cap, temp);
 		switch (cap & 0xff) {
@@ -383,8 +389,29 @@
 	temp = HCS_N_CC(ehci->hcs_params) * HCS_N_PCC(ehci->hcs_params);
 	temp &= 0x0f;
 	if (temp && HCS_N_PORTS(ehci->hcs_params) > temp) {
-		temp |= (ehci->hcs_params & ~0xf);
-		ehci->hcs_params = temp;
+		ehci_dbg (ehci, "bogus port configuration: "
+			"cc=%d x pcc=%d < ports=%d\n",
+			HCS_N_CC(ehci->hcs_params),
+			HCS_N_PCC(ehci->hcs_params),
+			HCS_N_PORTS(ehci->hcs_params));
+
+#ifdef	CONFIG_PCI
+		if (hcd->self.controller->bus == &pci_bus_type) {
+			struct pci_dev	*pdev;
+
+			pdev = to_pci_dev(hcd->self.controller);
+			switch (pdev->vendor) {
+			case 0x17a0:		/* GENESYS */
+				/* GL880S: should be PORTS=2 */
+				temp |= (ehci->hcs_params & ~0xf);
+				ehci->hcs_params = temp;
+				break;
+			case PCI_VENDOR_ID_NVIDIA:
+				/* NF4: should be PCC=10 */
+				break;
+			}
+		}
+#endif
 	}
 
 	/* force HC to halt state */
@@ -500,17 +527,30 @@
 		writel (0, &ehci->regs->segment);
 #if 0
 // this is deeply broken on almost all architectures
-		if (!pci_set_dma_mask (to_pci_dev(ehci->hcd.self.controller), 0xffffffffffffffffULL))
+		if (!pci_set_dma_mask (to_pci_dev(hcd->self.controller), 0xffffffffffffffffULL))
 			ehci_info (ehci, "enabled 64bit PCI DMA\n");
 #endif
 	}
 
 	/* clear interrupt enables, set irq latency */
-	temp = readl (&ehci->regs->command) & 0x0fff;
 	if (log2_irq_thresh < 0 || log2_irq_thresh > 6)
 		log2_irq_thresh = 0;
-	temp |= 1 << (16 + log2_irq_thresh);
-	// if hc can park (ehci >= 0.96), default is 3 packets per async QH 
+	temp = 1 << (16 + log2_irq_thresh);
+	if (HCC_CANPARK(hcc_params)) {
+		/* HW default park == 3, on hardware that supports it (like
+		 * NVidia and ALI silicon), maximizes throughput on the async
+		 * schedule by avoiding QH fetches between transfers.
+		 *
+		 * With fast usb storage devices and NForce2, "park" seems to
+		 * make problems:  throughput reduction (!), data errors...
+		 */
+		if (park) {
+			park = min (park, (unsigned) 3);
+			temp |= CMD_PARK;
+			temp |= park << 8;
+		}
+		ehci_info (ehci, "park %d\n", park);
+	}
 	if (HCC_PGM_FRAMELISTLEN (hcc_params)) {
 		/* periodic schedule size can be smaller than default */
 		temp &= ~(3 << 2);
@@ -522,7 +562,6 @@
 		default:	BUG ();
 		}
 	}
-	temp &= ~(CMD_IAAD | CMD_ASE | CMD_PSE),
 	// Philips, Intel, and maybe others need CMD_RUN before the
 	// root hub will detect new devices (why?); NEC doesn't
 	temp |= CMD_RUN;
@@ -553,7 +592,7 @@
 		register_reboot_notifier (&ehci->reboot_notifier);
 	}
 
-	ehci->hcd.state = USB_STATE_RUNNING;
+	hcd->state = USB_STATE_RUNNING;
 	writel (FLAG_CF, &ehci->regs->configured_flag);
 	readl (&ehci->regs->command);	/* unblock posted write */
 
@@ -610,7 +649,7 @@
 	del_timer_sync (&ehci->watchdog);
 
 	spin_lock_irq(&ehci->lock);
-	if (HCD_IS_RUNNING (ehci->hcd.state))
+	if (HCD_IS_RUNNING (hcd->state))
 		ehci_quiesce (ehci);
 
 	ehci_reset (ehci);
@@ -777,8 +816,9 @@
 	 * misplace IRQs, and should let us run completely without IRQs.
 	 * such lossage has been observed on both VT6202 and VT8235. 
 	 */
-	if (HCD_IS_RUNNING (ehci->hcd.state) && (ehci->async->qh_next.ptr != 0
-			|| ehci->periodic_sched != 0))
+	if (HCD_IS_RUNNING (ehci_to_hcd(ehci)->state) &&
+			(ehci->async->qh_next.ptr != NULL ||
+			 ehci->periodic_sched != 0))
 		timer_action (ehci, TIMER_IO_WATCHDOG);
 }
 
@@ -835,7 +875,7 @@
 	}
 
 	/* remote wakeup [4.3.1] */
-	if ((status & STS_PCD) && ehci->hcd.remote_wakeup) {
+	if ((status & STS_PCD) && hcd->remote_wakeup) {
 		unsigned	i = HCS_N_PORTS (ehci->hcs_params);
 
 		/* resume root hub? */
@@ -856,7 +896,7 @@
 			 * stop that signaling.
 			 */
 			ehci->reset_done [i] = jiffies + msecs_to_jiffies (20);
-			mod_timer (&ehci->hcd.rh_timer,
+			mod_timer (&hcd->rh_timer,
 					ehci->reset_done [i] + 1);
 			ehci_dbg (ehci, "port %d remote wakeup\n", i + 1);
 		}
@@ -864,13 +904,20 @@
 
 	/* PCI errors [4.15.2.4] */
 	if (unlikely ((status & STS_FATAL) != 0)) {
-		ehci_err (ehci, "fatal error\n");
+		/* bogus "fatal" IRQs appear on some chips... why?  */
+		status = readl (&ehci->regs->status);
+		dbg_cmd (ehci, "fatal", readl (&ehci->regs->command));
+		dbg_status (ehci, "fatal", status);
+		if (status & STS_HALT) {
+			ehci_err (ehci, "fatal error\n");
 dead:
-		ehci_reset (ehci);
-		/* generic layer kills/unlinks all urbs, then
-		 * uses ehci_stop to clean up the rest
-		 */
-		bh = 1;
+			ehci_reset (ehci);
+			writel (0, &ehci->regs->configured_flag);
+			/* generic layer kills/unlinks all urbs, then
+			 * uses ehci_stop to clean up the rest
+			 */
+			bh = 1;
+		}
 	}
 
 	if (bh)
@@ -895,6 +942,7 @@
  */
 static int ehci_urb_enqueue (
 	struct usb_hcd	*hcd,
+	struct usb_host_endpoint *ep,
 	struct urb	*urb,
 	int		mem_flags
 ) {
@@ -909,12 +957,12 @@
 	default:
 		if (!qh_urb_transaction (ehci, urb, &qtd_list, mem_flags))
 			return -ENOMEM;
-		return submit_async (ehci, urb, &qtd_list, mem_flags);
+		return submit_async (ehci, ep, urb, &qtd_list, mem_flags);
 
 	case PIPE_INTERRUPT:
 		if (!qh_urb_transaction (ehci, urb, &qtd_list, mem_flags))
 			return -ENOMEM;
-		return intr_submit (ehci, urb, &qtd_list, mem_flags);
+		return intr_submit (ehci, ep, urb, &qtd_list, mem_flags);
 
 	case PIPE_ISOCHRONOUS:
 		if (urb->dev->speed == USB_SPEED_HIGH)
@@ -929,7 +977,7 @@
 	/* if we need to use IAA and it's busy, defer */
 	if (qh->qh_state == QH_STATE_LINKED
 			&& ehci->reclaim
-			&& HCD_IS_RUNNING (ehci->hcd.state)) {
+			&& HCD_IS_RUNNING (ehci_to_hcd(ehci)->state)) {
 		struct ehci_qh		*last;
 
 		for (last = ehci->reclaim;
@@ -940,7 +988,7 @@
 		last->reclaim = qh;
 
 	/* bypass IAA if the hc can't care */
-	} else if (!HCD_IS_RUNNING (ehci->hcd.state) && ehci->reclaim)
+	} else if (!HCD_IS_RUNNING (ehci_to_hcd(ehci)->state) && ehci->reclaim)
 		end_unlink_async (ehci, NULL);
 
 	/* something else might have unlinked the qh by now */
@@ -973,16 +1021,22 @@
 		qh = (struct ehci_qh *) urb->hcpriv;
 		if (!qh)
 			break;
-		if (qh->qh_state == QH_STATE_LINKED) {
-			/* messy, can spin or block a microframe ... */
-			intr_deschedule (ehci, qh, 1);
-			/* qh_state == IDLE */
+		switch (qh->qh_state) {
+		case QH_STATE_LINKED:
+			intr_deschedule (ehci, qh);
+			/* FALL THROUGH */
+		case QH_STATE_IDLE:
+			qh_completions (ehci, qh, NULL);
+			break;
+		default:
+			ehci_dbg (ehci, "bogus qh %p state %d\n",
+					qh, qh->qh_state);
+			goto done;
 		}
-		qh_completions (ehci, qh, NULL);
 
 		/* reschedule QH iff another request is queued */
 		if (!list_empty (&qh->qtd_list)
-				&& HCD_IS_RUNNING (ehci->hcd.state)) {
+				&& HCD_IS_RUNNING (hcd->state)) {
 			int status;
 
 			status = qh_schedule (ehci, qh);
@@ -1005,6 +1059,7 @@
 		// completion irqs can wait up to 1024 msec,
 		break;
 	}
+done:
 	spin_unlock_irqrestore (&ehci->lock, flags);
 	return 0;
 }
@@ -1014,23 +1069,18 @@
 // bulk qh holds the data toggle
 
 static void
-ehci_endpoint_disable (struct usb_hcd *hcd, struct hcd_dev *dev, int ep)
+ehci_endpoint_disable (struct usb_hcd *hcd, struct usb_host_endpoint *ep)
 {
 	struct ehci_hcd		*ehci = hcd_to_ehci (hcd);
-	int			epnum;
 	unsigned long		flags;
 	struct ehci_qh		*qh, *tmp;
 
 	/* ASSERT:  any requests/urbs are being unlinked */
 	/* ASSERT:  nobody can be submitting urbs for this any more */
 
-	epnum = ep & USB_ENDPOINT_NUMBER_MASK;
-	if (epnum != 0 && (ep & USB_DIR_IN))
-		epnum |= 0x10;
-
 rescan:
 	spin_lock_irqsave (&ehci->lock, flags);
-	qh = (struct ehci_qh *) dev->ep [epnum];
+	qh = ep->hcpriv;
 	if (!qh)
 		goto done;
 
@@ -1042,7 +1092,7 @@
 		goto idle_timeout;
 	}
 
-	if (!HCD_IS_RUNNING (ehci->hcd.state))
+	if (!HCD_IS_RUNNING (hcd->state))
 		qh->qh_state = QH_STATE_IDLE;
 	switch (qh->qh_state) {
 	case QH_STATE_LINKED:
@@ -1072,12 +1122,12 @@
 		/* caller was supposed to have unlinked any requests;
 		 * that's not our job.  just leak this memory.
 		 */
-		ehci_err (ehci, "qh %p (#%d) state %d%s\n",
-			qh, epnum, qh->qh_state,
+		ehci_err (ehci, "qh %p (#%02x) state %d%s\n",
+			qh, ep->desc.bEndpointAddress, qh->qh_state,
 			list_empty (&qh->qtd_list) ? "" : "(has tds)");
 		break;
 	}
-	dev->ep[epnum] = NULL;
+	ep->hcpriv = NULL;
 done:
 	spin_unlock_irqrestore (&ehci->lock, flags);
 	return;
@@ -1087,6 +1137,8 @@
 
 static const struct hc_driver ehci_driver = {
 	.description =		hcd_name,
+	.product_desc =		"EHCI Host Controller",
+	.hcd_priv_size =	sizeof(struct ehci_hcd),
 
 	/*
 	 * generic hardware linkage
@@ -1104,11 +1156,6 @@
 	.resume =		ehci_resume,
 #endif
 	.stop =			ehci_stop,
-
-	/*
-	 * memory lifecycle (except per-request)
-	 */
-	.hcd_alloc =		ehci_hcd_alloc,
 
 	/*
 	 * managing i/o requests and associated device resources
diff -Nru a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
--- a/drivers/usb/host/ehci-hub.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/usb/host/ehci-hub.c	2005-03-01 23:39:17 -08:00
@@ -44,7 +44,7 @@
 	/* stop schedules, clean any completed work */
 	if (HCD_IS_RUNNING(hcd->state)) {
 		ehci_quiesce (ehci);
-		ehci->hcd.state = USB_STATE_QUIESCING;
+		hcd->state = USB_STATE_QUIESCING;
 	}
 	ehci->command = readl (&ehci->regs->command);
 	if (ehci->reclaim)
@@ -59,7 +59,7 @@
 
 		if ((t1 & PORT_PE) && !(t1 & PORT_OWNER))
 			t2 |= PORT_SUSPEND;
-		if (ehci->hcd.remote_wakeup)
+		if (hcd->remote_wakeup)
 			t2 |= PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E;
 		else
 			t2 &= ~(PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E);
@@ -73,7 +73,7 @@
 
 	/* turn off now-idle HC */
 	ehci_halt (ehci);
-	ehci->hcd.state = HCD_STATE_SUSPENDED;
+	hcd->state = HCD_STATE_SUSPENDED;
 
 	ehci->next_statechange = jiffies + msecs_to_jiffies(10);
 	spin_unlock_irq (&ehci->lock);
@@ -145,7 +145,7 @@
 	}
 
 	ehci->next_statechange = jiffies + msecs_to_jiffies(5);
-	ehci->hcd.state = USB_STATE_RUNNING;
+	hcd->state = USB_STATE_RUNNING;
 
 	/* Now we can safely re-enable irqs */
 	if (intr_enable)
@@ -212,7 +212,7 @@
 	unsigned long	flags;
 
 	/* if !USB_SUSPEND, root hub timers won't get shut down ... */
-	if (!HCD_IS_RUNNING(ehci->hcd.state))
+	if (!HCD_IS_RUNNING(hcd->state))
 		return 0;
 
 	/* init status to no-changes */
@@ -499,7 +499,7 @@
 			if ((temp & PORT_PE) == 0
 					|| (temp & PORT_RESET) != 0)
 				goto error;
-			if (ehci->hcd.remote_wakeup)
+			if (hcd->remote_wakeup)
 				temp |= PORT_WAKE_BITS;
 			writel (temp | PORT_SUSPEND,
 				&ehci->regs->port_status [wIndex]);
diff -Nru a/drivers/usb/host/ehci-mem.c b/drivers/usb/host/ehci-mem.c
--- a/drivers/usb/host/ehci-mem.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/usb/host/ehci-mem.c	2005-03-01 23:39:16 -08:00
@@ -32,25 +32,6 @@
  */
 
 /*-------------------------------------------------------------------------*/
-/* 
- * Allocator / cleanup for the per device structure
- * Called by hcd init / removal code
- */
-static struct usb_hcd *ehci_hcd_alloc (void)
-{
-	struct ehci_hcd *ehci;
-
-	ehci = (struct ehci_hcd *)
-		kmalloc (sizeof (struct ehci_hcd), GFP_KERNEL);
-	if (ehci != 0) {
-		memset (ehci, 0, sizeof (struct ehci_hcd));
-		ehci->hcd.product_desc = "EHCI Host Controller";
-		return &ehci->hcd;
-	}
-	return NULL;
-}
-
-/*-------------------------------------------------------------------------*/
 
 /* Allocate the key transfer structures from the previously allocated pool */
 
@@ -70,7 +51,7 @@
 	dma_addr_t		dma;
 
 	qtd = dma_pool_alloc (ehci->qtd_pool, flags, &dma);
-	if (qtd != 0) {
+	if (qtd != NULL) {
 		ehci_qtd_init (qtd, dma);
 	}
 	return qtd;
@@ -117,7 +98,7 @@
 
 	/* dummy td enables safe urb queuing */
 	qh->dummy = ehci_qtd_alloc (ehci, flags);
-	if (qh->dummy == 0) {
+	if (qh->dummy == NULL) {
 		ehci_dbg (ehci, "no dummy td\n");
 		dma_pool_free (ehci->qh_pool, qh, qh->qh_dma);
 		qh = NULL;
@@ -169,7 +150,7 @@
 	ehci->sitd_pool = NULL;
 
 	if (ehci->periodic)
-		dma_free_coherent (ehci->hcd.self.controller,
+		dma_free_coherent (ehci_to_hcd(ehci)->self.controller,
 			ehci->periodic_size * sizeof (u32),
 			ehci->periodic, ehci->periodic_dma);
 	ehci->periodic = NULL;
@@ -187,7 +168,7 @@
 
 	/* QTDs for control/bulk/intr transfers */
 	ehci->qtd_pool = dma_pool_create ("ehci_qtd", 
-			ehci->hcd.self.controller,
+			ehci_to_hcd(ehci)->self.controller,
 			sizeof (struct ehci_qtd),
 			32 /* byte alignment (for hw parts) */,
 			4096 /* can't cross 4K */);
@@ -197,7 +178,7 @@
 
 	/* QHs for control/bulk/intr transfers */
 	ehci->qh_pool = dma_pool_create ("ehci_qh", 
-			ehci->hcd.self.controller,
+			ehci_to_hcd(ehci)->self.controller,
 			sizeof (struct ehci_qh),
 			32 /* byte alignment (for hw parts) */,
 			4096 /* can't cross 4K */);
@@ -211,7 +192,7 @@
 
 	/* ITD for high speed ISO transfers */
 	ehci->itd_pool = dma_pool_create ("ehci_itd", 
-			ehci->hcd.self.controller,
+			ehci_to_hcd(ehci)->self.controller,
 			sizeof (struct ehci_itd),
 			32 /* byte alignment (for hw parts) */,
 			4096 /* can't cross 4K */);
@@ -221,7 +202,7 @@
 
 	/* SITD for full/low speed split ISO transfers */
 	ehci->sitd_pool = dma_pool_create ("ehci_sitd", 
-			ehci->hcd.self.controller,
+			ehci_to_hcd(ehci)->self.controller,
 			sizeof (struct ehci_sitd),
 			32 /* byte alignment (for hw parts) */,
 			4096 /* can't cross 4K */);
@@ -231,10 +212,10 @@
 
 	/* Hardware periodic table */
 	ehci->periodic = (__le32 *)
-		dma_alloc_coherent (ehci->hcd.self.controller,
+		dma_alloc_coherent (ehci_to_hcd(ehci)->self.controller,
 			ehci->periodic_size * sizeof(__le32),
 			&ehci->periodic_dma, 0);
-	if (ehci->periodic == 0) {
+	if (ehci->periodic == NULL) {
 		goto fail;
 	}
 	for (i = 0; i < ehci->periodic_size; i++)
@@ -242,7 +223,7 @@
 
 	/* software shadow of hardware table */
 	ehci->pshadow = kmalloc (ehci->periodic_size * sizeof (void *), flags);
-	if (ehci->pshadow == 0) {
+	if (ehci->pshadow == NULL) {
 		goto fail;
 	}
 	memset (ehci->pshadow, 0, ehci->periodic_size * sizeof (void *));
diff -Nru a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
--- a/drivers/usb/host/ehci-q.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/usb/host/ehci-q.c	2005-03-01 23:39:09 -08:00
@@ -200,7 +200,7 @@
 					|| QTD_CERR(token) == 0)
 				&& (!ehci_is_ARC(ehci)
                 	                || urb->dev->tt->hub !=
-						ehci->hcd.self.root_hub)) {
+					   ehci_to_hcd(ehci)->self.root_hub)) {
 #ifdef DEBUG
 			struct usb_device *tt = urb->dev->tt->hub;
 			dev_dbg (&tt->dev,
@@ -218,14 +218,14 @@
 __releases(ehci->lock)
 __acquires(ehci->lock)
 {
-	if (likely (urb->hcpriv != 0)) {
+	if (likely (urb->hcpriv != NULL)) {
 		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) {
 
 			/* ... update hc-wide periodic stats (for usbfs) */
-			hcd_to_bus (&ehci->hcd)->bandwidth_int_reqs--;
+			ehci_to_hcd(ehci)->self.bandwidth_int_reqs--;
 		}
 		qh_put (qh);
 	}
@@ -262,14 +262,14 @@
 
 	/* complete() can reenter this HCD */
 	spin_unlock (&ehci->lock);
-	usb_hcd_giveback_urb (&ehci->hcd, urb, regs);
+	usb_hcd_giveback_urb (ehci_to_hcd(ehci), urb, regs);
 	spin_lock (&ehci->lock);
 }
 
 static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh);
+static void unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh);
 
-static void intr_deschedule (struct ehci_hcd *ehci,
-				struct ehci_qh *qh, int wait);
+static void intr_deschedule (struct ehci_hcd *ehci, struct ehci_qh *qh);
 static int qh_schedule (struct ehci_hcd *ehci, struct ehci_qh *qh);
 
 /*
@@ -348,13 +348,13 @@
 
 		/* stop scanning when we reach qtds the hc is using */
 		} else if (likely (!stopped
-				&& HCD_IS_RUNNING (ehci->hcd.state))) {
+				&& HCD_IS_RUNNING (ehci_to_hcd(ehci)->state))) {
 			break;
 
 		} else {
 			stopped = 1;
 
-			if (unlikely (!HCD_IS_RUNNING (ehci->hcd.state)))
+			if (unlikely (!HCD_IS_RUNNING (ehci_to_hcd(ehci)->state)))
 				urb->status = -ESHUTDOWN;
 
 			/* ignore active urbs unless some previous qtd
@@ -405,7 +405,7 @@
 	}
 
 	/* last urb's completion might still need calling */
-	if (likely (last != 0)) {
+	if (likely (last != NULL)) {
 		ehci_urb_done (ehci, last->urb, regs);
 		count++;
 		ehci_qtd_free (ehci, last);
@@ -428,10 +428,10 @@
 			 * except maybe high bandwidth ...
 			 */
 			if (qh->period) {
-				intr_deschedule (ehci, qh, 1);
+				intr_deschedule (ehci, qh);
 				(void) qh_schedule (ehci, qh);
 			} else
-				start_unlink_async (ehci, qh);
+				unlink_async (ehci, qh);
 			break;
 		/* otherwise, unlink already started */
 		}
@@ -664,9 +664,12 @@
 			qh->c_usecs = 0;
 			qh->gap_uf = 0;
 
-			/* FIXME handle HS periods of less than 1 frame. */
 			qh->period = urb->interval >> 3;
-			if (qh->period < 1) {
+			if (qh->period == 0 && urb->interval != 1) {
+				/* NOTE interval 2 or 4 uframes could work.
+				 * But interval 1 scheduling is simpler, and
+				 * includes high bandwidth.
+				 */
 				dbg ("intr period %d uframes, NYET!",
 						urb->interval);
 				goto done;
@@ -715,7 +718,8 @@
 		 * root hub tt, leave it zeroed.
 		 */
 		if (!ehci_is_ARC(ehci)
-				|| urb->dev->tt->hub != ehci->hcd.self.root_hub)
+				|| urb->dev->tt->hub !=
+					ehci_to_hcd(ehci)->self.root_hub)
 			info2 |= urb->dev->tt->hub->devnum << 16;
 
 		/* NOTE:  if (PIPE_INTERRUPT) { scheduler sets c-mask } */
@@ -776,7 +780,7 @@
 			(void) handshake (&ehci->regs->status, STS_ASS, 0, 150);
 			cmd |= CMD_ASE | CMD_RUN;
 			writel (cmd, &ehci->regs->command);
-			ehci->hcd.state = USB_STATE_RUNNING;
+			ehci_to_hcd(ehci)->state = USB_STATE_RUNNING;
 			/* posted write need not be known to HC yet ... */
 		}
 	}
@@ -832,26 +836,8 @@
 			qtd = list_entry (qtd_list->next, struct ehci_qtd,
 					qtd_list);
 
-		/* control qh may need patching after enumeration */
+		/* control qh may need patching ... */
 		if (unlikely (epnum == 0)) {
-			/* set_address changes the address */
-			if ((qh->hw_info1 & QH_ADDR_MASK) == 0)
-				qh->hw_info1 |= cpu_to_le32 (
-						usb_pipedevice (urb->pipe));
-
-			/* for full speed, ep0 maxpacket can grow */
-			else if (!(qh->hw_info1
-					& __constant_cpu_to_le32 (0x3 << 12))) {
-				u32	info, max;
-
-				info = le32_to_cpu (qh->hw_info1);
-				max = urb->dev->descriptor.bMaxPacketSize0;
-				if (max > (0x07ff & (info >> 16))) {
-					info &= ~(0x07ff << 16);
-					info |= max << 16;
-					qh->hw_info1 = cpu_to_le32 (info);
-				}
-			}
 
                         /* usb_reset_device() briefly reverts to address 0 */
                         if (usb_pipedevice (urb->pipe) == 0)
@@ -861,7 +847,7 @@
 		/* just one way to queue requests: swap with the dummy qtd.
 		 * only hc or qh_refresh() ever modify the overlay.
 		 */
-		if (likely (qtd != 0)) {
+		if (likely (qtd != NULL)) {
 			struct ehci_qtd		*dummy;
 			dma_addr_t		dma;
 			__le32			token;
@@ -908,43 +894,40 @@
 static int
 submit_async (
 	struct ehci_hcd		*ehci,
+	struct usb_host_endpoint *ep,
 	struct urb		*urb,
 	struct list_head	*qtd_list,
 	int			mem_flags
 ) {
 	struct ehci_qtd		*qtd;
-	struct hcd_dev		*dev;
 	int			epnum;
 	unsigned long		flags;
 	struct ehci_qh		*qh = NULL;
 
 	qtd = list_entry (qtd_list->next, struct ehci_qtd, qtd_list);
-	dev = (struct hcd_dev *)urb->dev->hcpriv;
-	epnum = usb_pipeendpoint (urb->pipe);
-	if (usb_pipein (urb->pipe) && !usb_pipecontrol (urb->pipe))
-		epnum |= 0x10;
+	epnum = ep->desc.bEndpointAddress;
 
 #ifdef EHCI_URB_TRACE
 	ehci_dbg (ehci,
 		"%s %s urb %p ep%d%s len %d, qtd %p [qh %p]\n",
 		__FUNCTION__, urb->dev->devpath, urb,
-		epnum & 0x0f, usb_pipein (urb->pipe) ? "in" : "out",
+		epnum & 0x0f, (epnum & USB_DIR_IN) ? "in" : "out",
 		urb->transfer_buffer_length,
-		qtd, dev ? dev->ep [epnum] : (void *)~0);
+		qtd, ep->hcpriv);
 #endif
 
 	spin_lock_irqsave (&ehci->lock, flags);
-	qh = qh_append_tds (ehci, urb, qtd_list, epnum, &dev->ep [epnum]);
+	qh = qh_append_tds (ehci, urb, qtd_list, epnum, &ep->hcpriv);
 
 	/* Control/bulk operations through TTs don't need scheduling,
 	 * the HC and TT handle it when the TT has a buffer ready.
 	 */
-	if (likely (qh != 0)) {
+	if (likely (qh != NULL)) {
 		if (likely (qh->qh_state == QH_STATE_IDLE))
 			qh_link_async (ehci, qh_get (qh));
 	}
 	spin_unlock_irqrestore (&ehci->lock, flags);
-	if (unlikely (qh == 0)) {
+	if (unlikely (qh == NULL)) {
 		qtd_list_free (ehci, urb, qtd_list);
 		return -ENOMEM;
 	}
@@ -976,7 +959,7 @@
 	qh_completions (ehci, qh, regs);
 
 	if (!list_empty (&qh->qtd_list)
-			&& HCD_IS_RUNNING (ehci->hcd.state))
+			&& HCD_IS_RUNNING (ehci_to_hcd(ehci)->state))
 		qh_link_async (ehci, qh);
 	else {
 		qh_put (qh);		// refcount from async list
@@ -984,8 +967,8 @@
 		/* it's not free to turn the async schedule on/off; leave it
 		 * active but idle for a while once it empties.
 		 */
-		if (HCD_IS_RUNNING (ehci->hcd.state)
-				&& ehci->async->qh_next.qh == 0)
+		if (HCD_IS_RUNNING (ehci_to_hcd(ehci)->state)
+				&& ehci->async->qh_next.qh == NULL)
 			timer_action (ehci, TIMER_ASYNC_OFF);
 	}
 
@@ -1004,13 +987,10 @@
 	struct ehci_qh	*prev;
 
 #ifdef DEBUG
+	assert_spin_locked(&ehci->lock);
 	if (ehci->reclaim
 			|| (qh->qh_state != QH_STATE_LINKED
 				&& qh->qh_state != QH_STATE_UNLINK_WAIT)
-#ifdef CONFIG_SMP
-// this macro lies except on SMP compiles
-			|| !spin_is_locked (&ehci->lock)
-#endif
 			)
 		BUG ();
 #endif
@@ -1018,7 +998,7 @@
 	/* stop async schedule right now? */
 	if (unlikely (qh == ehci->async)) {
 		/* can't get here without STS_ASS set */
-		if (ehci->hcd.state != USB_STATE_HALT) {
+		if (ehci_to_hcd(ehci)->state != USB_STATE_HALT) {
 			writel (cmd & ~CMD_ASE, &ehci->regs->command);
 			wmb ();
 			// handshake later, if we need to
@@ -1038,7 +1018,7 @@
 	prev->qh_next = qh->qh_next;
 	wmb ();
 
-	if (unlikely (ehci->hcd.state == USB_STATE_HALT)) {
+	if (unlikely (ehci_to_hcd(ehci)->state == USB_STATE_HALT)) {
 		/* if (unlikely (qh->reclaim != 0))
 		 * 	this will recurse, probably not much
 		 */
@@ -1066,7 +1046,7 @@
 	timer_action_done (ehci, TIMER_ASYNC_SHRINK);
 rescan:
 	qh = ehci->async->qh_next.qh;
-	if (likely (qh != 0)) {
+	if (likely (qh != NULL)) {
 		do {
 			/* clean any finished work for this qh */
 			if (!list_empty (&qh->qtd_list)
diff -Nru a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
--- a/drivers/usb/host/ehci-sched.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/usb/host/ehci-sched.c	2005-03-01 23:38:54 -08:00
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001-2003 by David Brownell
+ * Copyright (c) 2001-2004 by David Brownell
  * Copyright (c) 2003 Michal Sojka, for high-speed iso transfers
  * 
  * This program is free software; you can redistribute it and/or modify it
@@ -59,39 +59,28 @@
 	}
 }
 
-/* returns true after successful unlink */
 /* caller must hold ehci->lock */
-static int periodic_unlink (struct ehci_hcd *ehci, unsigned frame, void *ptr)
+static void periodic_unlink (struct ehci_hcd *ehci, unsigned frame, void *ptr)
 {
 	union ehci_shadow	*prev_p = &ehci->pshadow [frame];
 	__le32			*hw_p = &ehci->periodic [frame];
 	union ehci_shadow	here = *prev_p;
-	union ehci_shadow	*next_p;
 
 	/* find predecessor of "ptr"; hw and shadow lists are in sync */
 	while (here.ptr && here.ptr != ptr) {
 		prev_p = periodic_next_shadow (prev_p, Q_NEXT_TYPE (*hw_p));
-		hw_p = &here.qh->hw_next;
+		hw_p = here.hw_next;
 		here = *prev_p;
 	}
 	/* an interrupt entry (at list end) could have been shared */
-	if (!here.ptr) {
-		dbg ("entry %p no longer on frame [%d]", ptr, frame);
-		return 0;
-	}
-	// vdbg ("periodic unlink %p from frame %d", ptr, frame);
+	if (!here.ptr)
+		return;
 
-	/* update hardware list ... HC may still know the old structure, so
-	 * don't change hw_next until it'll have purged its cache
+	/* update shadow and hardware lists ... the old "next" pointers
+	 * from ptr may still be in use, the caller updates them.
 	 */
-	next_p = periodic_next_shadow (&here, Q_NEXT_TYPE (*hw_p));
-	*hw_p = here.qh->hw_next;
-
-	/* unlink from shadow list; HCD won't see old structure again */
-	*prev_p = *next_p;
-	next_p->ptr = NULL;
-
-	return 1;
+	*prev_p = *periodic_next_shadow (&here, Q_NEXT_TYPE (*hw_p));
+	*hw_p = *here.hw_next;
 }
 
 /* how many of the uframe's 125 usecs are allocated? */
@@ -114,7 +103,8 @@
 			hw_p = &q->qh->hw_next;
 			q = &q->qh->qh_next;
 			break;
-		case Q_TYPE_FSTN:
+		// case Q_TYPE_FSTN:
+		default:
 			/* for "save place" FSTNs, count the relevant INTR
 			 * bandwidth from the previous frame
 			 */
@@ -149,13 +139,11 @@
 			hw_p = &q->sitd->hw_next;
 			q = &q->sitd->sitd_next;
 			break;
-		default:
-			BUG ();
 		}
 	}
 #ifdef	DEBUG
 	if (usecs > 100)
-		err ("overallocated uframe %d, periodic is %d usecs",
+		ehci_err (ehci, "uframe %d sched overrun: %d usecs\n",
 			frame * 8 + uframe, usecs);
 #endif
 	return usecs;
@@ -261,14 +249,14 @@
 	 */
 	status = handshake (&ehci->regs->status, STS_PSS, 0, 9 * 125);
 	if (status != 0) {
-		ehci->hcd.state = USB_STATE_HALT;
+		ehci_to_hcd(ehci)->state = USB_STATE_HALT;
 		return status;
 	}
 
 	cmd = readl (&ehci->regs->command) | CMD_PSE;
 	writel (cmd, &ehci->regs->command);
 	/* posted write ... PSS happens later */
-	ehci->hcd.state = USB_STATE_RUNNING;
+	ehci_to_hcd(ehci)->state = USB_STATE_RUNNING;
 
 	/* make sure ehci_work scans these */
 	ehci->next_uframe = readl (&ehci->regs->frame_index)
@@ -286,7 +274,7 @@
 	 */
 	status = handshake (&ehci->regs->status, STS_PSS, STS_PSS, 9 * 125);
 	if (status != 0) {
-		ehci->hcd.state = USB_STATE_HALT;
+		ehci_to_hcd(ehci)->state = USB_STATE_HALT;
 		return status;
 	}
 
@@ -300,64 +288,143 @@
 
 /*-------------------------------------------------------------------------*/
 
-// FIXME microframe periods not yet handled
+/* periodic schedule slots have iso tds (normal or split) first, then a
+ * sparse tree for active interrupt transfers.
+ *
+ * this just links in a qh; caller guarantees uframe masks are set right.
+ * no FSTN support (yet; ehci 0.96+)
+ */
+static int qh_link_periodic (struct ehci_hcd *ehci, struct ehci_qh *qh)
+{
+	unsigned	i;
+	unsigned	period = qh->period;
 
-static void intr_deschedule (
-	struct ehci_hcd	*ehci,
-	struct ehci_qh	*qh,
-	int		wait
-) {
-	int		status;
-	unsigned	frame = qh->start;
+	dev_dbg (&qh->dev->dev,
+		"link qh%d-%04x/%p start %d [%d/%d us]\n",
+		period, le32_to_cpup (&qh->hw_info2) & 0xffff,
+		qh, qh->start, qh->usecs, qh->c_usecs);
+
+	/* high bandwidth, or otherwise every microframe */
+	if (period == 0)
+		period = 1;
+
+	for (i = qh->start; i < ehci->periodic_size; i += period) {
+		union ehci_shadow	*prev = &ehci->pshadow [i];
+		u32			*hw_p = &ehci->periodic [i];
+		union ehci_shadow	here = *prev;
+		u32			type = 0;
 
-	do {
-		periodic_unlink (ehci, frame, qh);
-		qh_put (qh);
-		frame += qh->period;
-	} while (frame < ehci->periodic_size);
+		/* skip the iso nodes at list head */
+		while (here.ptr) {
+			type = Q_NEXT_TYPE (*hw_p);
+			if (type == Q_TYPE_QH)
+				break;
+			prev = periodic_next_shadow (prev, type);
+			hw_p = &here.qh->hw_next;
+			here = *prev;
+		}
+
+		/* sorting each branch by period (slow-->fast)
+		 * enables sharing interior tree nodes
+		 */
+		while (here.ptr && qh != here.qh) {
+			if (qh->period > here.qh->period)
+				break;
+			prev = &here.qh->qh_next;
+			hw_p = &here.qh->hw_next;
+			here = *prev;
+		}
+		/* link in this qh, unless some earlier pass did that */
+		if (qh != here.qh) {
+			qh->qh_next = here;
+			if (here.qh)
+				qh->hw_next = *hw_p;
+			wmb ();
+			prev->qh = qh;
+			*hw_p = QH_NEXT (qh->qh_dma);
+		}
+	}
+	qh->qh_state = QH_STATE_LINKED;
+	qh_get (qh);
+
+	/* update per-qh bandwidth for usbfs */
+	ehci_to_hcd(ehci)->self.bandwidth_allocated += qh->period
+		? ((qh->usecs + qh->c_usecs) / qh->period)
+		: (qh->usecs * 8);
 
+	/* maybe enable periodic schedule processing */
+	if (!ehci->periodic_sched++)
+		return enable_periodic (ehci);
+
+	return 0;
+}
+
+static void qh_unlink_periodic (struct ehci_hcd *ehci, struct ehci_qh *qh)
+{
+	unsigned	i;
+	unsigned	period;
+
+	// FIXME:
+	// IF this isn't high speed
+	//   and this qh is active in the current uframe
+	//   (and overlay token SplitXstate is false?)
+	// THEN
+	//   qh->hw_info1 |= __constant_cpu_to_le32 (1 << 7 /* "ignore" */);
+
+	/* high bandwidth, or otherwise part of every microframe */
+	if ((period = qh->period) == 0)
+		period = 1;
+
+	for (i = qh->start; i < ehci->periodic_size; i += period)
+		periodic_unlink (ehci, i, qh);
+
+	/* update per-qh bandwidth for usbfs */
+	ehci_to_hcd(ehci)->self.bandwidth_allocated -= qh->period
+		? ((qh->usecs + qh->c_usecs) / qh->period)
+		: (qh->usecs * 8);
+
+	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, qh->start, qh->usecs, qh->c_usecs);
+
+	/* qh->qh_next still "live" to HC */
 	qh->qh_state = QH_STATE_UNLINK;
 	qh->qh_next.ptr = NULL;
-	ehci->periodic_sched--;
+	qh_put (qh);
 
 	/* maybe turn off periodic schedule */
+	ehci->periodic_sched--;
 	if (!ehci->periodic_sched)
-		status = disable_periodic (ehci);
-	else {
-		status = 0;
-		ehci_vdbg (ehci, "periodic schedule still enabled\n");
-	}
+		(void) disable_periodic (ehci);
+}
 
-	/*
-	 * If the hc may be looking at this qh, then delay a uframe
-	 * (yeech!) to be sure it's done.
-	 * No other threads may be mucking with this qh.
+static void intr_deschedule (struct ehci_hcd *ehci, struct ehci_qh *qh)
+{
+	unsigned	wait;
+
+	qh_unlink_periodic (ehci, qh);
+
+	/* simple/paranoid:  always delay, expecting the HC needs to read
+	 * qh->hw_next or finish a writeback after SPLIT/CSPLIT ... and
+	 * expect khubd to clean up after any CSPLITs we won't issue.
+	 * active high speed queues may need bigger delays...
 	 */
-	if (((ehci_get_frame (&ehci->hcd) - frame) % qh->period) == 0) {
-		if (wait) {
-			udelay (125);
-			qh->hw_next = EHCI_LIST_END;
-		} else {
-			/* we may not be IDLE yet, but if the qh is empty
-			 * the race is very short.  then if qh also isn't
-			 * rescheduled soon, it won't matter.  otherwise...
-			 */
-			ehci_vdbg (ehci, "intr_deschedule...\n");
-		}
-	} else
-		qh->hw_next = EHCI_LIST_END;
+	if (list_empty (&qh->qtd_list)
+			|| (__constant_cpu_to_le32 (0x0ff << 8)
+					& qh->hw_info2) != 0)
+		wait = 2;
+	else
+		wait = 55;	/* worst case: 3 * 1024 */
 
+	udelay (wait);
 	qh->qh_state = QH_STATE_IDLE;
-
-	/* update per-qh bandwidth utilization (for usbfs) */
-	hcd_to_bus (&ehci->hcd)->bandwidth_allocated -= 
-		(qh->usecs + qh->c_usecs) / qh->period;
-
-	ehci_dbg (ehci, "descheduled qh%d/%p frame=%d count=%d, urbs=%d\n",
-		qh->period, qh, frame,
-		atomic_read (&qh->kref.refcount), ehci->periodic_sched);
+	qh->hw_next = EHCI_LIST_END;
+	wmb ();
 }
 
+/*-------------------------------------------------------------------------*/
+
 static int check_period (
 	struct ehci_hcd *ehci, 
 	unsigned	frame,
@@ -365,6 +432,8 @@
 	unsigned	period,
 	unsigned	usecs
 ) {
+	int		claimed;
+
 	/* complete split running into next frame?
 	 * given FSTN support, we could sometimes check...
 	 */
@@ -377,22 +446,26 @@
 	 */
 	usecs = 100 - usecs;
 
-	do {
-		int	claimed;
-
-// FIXME delete when intr_submit handles non-empty queues
-// this gives us a one intr/frame limit (vs N/uframe)
-// ... and also lets us avoid tracking split transactions
-// that might collide at a given TT/hub.
-		if (ehci->pshadow [frame].ptr)
-			return 0;
-
-		claimed = periodic_usecs (ehci, frame, uframe);
-		if (claimed > usecs)
-			return 0;
+	/* we "know" 2 and 4 uframe intervals were rejected; so
+	 * for period 0, check _every_ microframe in the schedule.
+	 */
+	if (unlikely (period == 0)) {
+		do {
+			for (uframe = 0; uframe < 7; uframe++) {
+				claimed = periodic_usecs (ehci, frame, uframe);
+				if (claimed > usecs)
+					return 0;
+			}
+		} while ((frame += 1) < ehci->periodic_size);
 
-// FIXME update to handle sub-frame periods
-	} while ((frame += period) < ehci->periodic_size);
+	/* just check the specified uframe, at that period */
+	} else {
+		do {
+			claimed = periodic_usecs (ehci, frame, uframe);
+			if (claimed > usecs)
+				return 0;
+		} while ((frame += period) < ehci->periodic_size);
+	}
 
 	// success!
 	return 1;
@@ -407,6 +480,10 @@
 )
 {
     	int		retval = -ENOSPC;
+	u8		mask;
+
+	if (qh->c_usecs && uframe >= 6)		/* FSTN territory? */
+		goto done;
 
 	if (!check_period (ehci, frame, uframe, qh->period, qh->usecs))
 		goto done;
@@ -416,33 +493,33 @@
 		goto done;
 	}
 
-	/* This is a split transaction; check the bandwidth available for
-	 * the completion too.  Check both worst and best case gaps: worst
-	 * case is SPLIT near uframe end, and CSPLIT near start ... best is
-	 * vice versa.  Difference can be almost two uframe times, but we
-	 * reserve unnecessary bandwidth (waste it) this way.  (Actually
-	 * even better cases exist, like immediate device NAK.)
-	 *
-	 * FIXME don't even bother unless we know this TT is idle in that
-	 * range of uframes ... for now, check_period() allows only one
-	 * interrupt transfer per frame, so needn't check "TT busy" status
-	 * when scheduling a split (QH, SITD, or FSTN).
-	 *
-	 * FIXME ehci 0.96 and above can use FSTNs
+	/* Make sure this tt's buffer is also available for CSPLITs.
+	 * We pessimize a bit; probably the typical full speed case
+	 * doesn't need the second CSPLIT.
+	 * 
+	 * NOTE:  both SPLIT and CSPLIT could be checked in just
+	 * one smart pass...
 	 */
-	if (!check_period (ehci, frame, uframe + qh->gap_uf + 1,
-				qh->period, qh->c_usecs))
-		goto done;
-	if (!check_period (ehci, frame, uframe + qh->gap_uf,
-				qh->period, qh->c_usecs))
-		goto done;
+	mask = 0x03 << (uframe + qh->gap_uf);
+	*c_maskp = cpu_to_le32 (mask << 8);
 
-	*c_maskp = cpu_to_le32 (0x03 << (8 + uframe + qh->gap_uf));
-	retval = 0;
+	mask |= 1 << uframe;
+	if (tt_no_collision (ehci, qh->period, qh->dev, frame, mask)) {
+		if (!check_period (ehci, frame, uframe + qh->gap_uf + 1,
+					qh->period, qh->c_usecs))
+			goto done;
+		if (!check_period (ehci, frame, uframe + qh->gap_uf,
+					qh->period, qh->c_usecs))
+			goto done;
+		retval = 0;
+	}
 done:
 	return retval;
 }
 
+/* "first fit" scheduling policy used the first time through,
+ * or when the previous schedule slot can't be re-used.
+ */
 static int qh_schedule (struct ehci_hcd *ehci, struct ehci_qh *qh)
 {
 	int 		status;
@@ -469,62 +546,46 @@
 	 * uframes have enough periodic bandwidth available.
 	 */
 	if (status) {
-		frame = qh->period - 1;
-		do {
-			for (uframe = 0; uframe < 8; uframe++) {
-				status = check_intr_schedule (ehci,
-						frame, uframe, qh,
-						&c_mask);
-				if (status == 0)
-					break;
-			}
-		} while (status && frame--);
+		/* "normal" case, uframing flexible except with splits */
+		if (qh->period) {
+			frame = qh->period - 1;
+			do {
+				for (uframe = 0; uframe < 8; uframe++) {
+					status = check_intr_schedule (ehci,
+							frame, uframe, qh,
+							&c_mask);
+					if (status == 0)
+						break;
+				}
+			} while (status && frame--);
+
+		/* qh->period == 0 means every uframe */
+		} else {
+			frame = 0;
+			status = check_intr_schedule (ehci, 0, 0, qh, &c_mask);
+		}
 		if (status)
 			goto done;
 		qh->start = frame;
 
 		/* reset S-frame and (maybe) C-frame masks */
-		qh->hw_info2 &= ~__constant_cpu_to_le32(0xffff);
-		qh->hw_info2 |= cpu_to_le32 (1 << uframe) | c_mask;
+		qh->hw_info2 &= __constant_cpu_to_le32 (~0xffff);
+		qh->hw_info2 |= qh->period
+			? cpu_to_le32 (1 << uframe)
+			: __constant_cpu_to_le32 (0xff);
+		qh->hw_info2 |= c_mask;
 	} else
 		ehci_dbg (ehci, "reused qh %p schedule\n", qh);
 
 	/* stuff into the periodic schedule */
-	qh->qh_state = QH_STATE_LINKED;
-	ehci_dbg(ehci,
-		"scheduled qh%d/%p usecs %d/%d starting %d.%d (gap %d)\n",
-		qh->period, qh, qh->usecs, qh->c_usecs,
-		frame, uframe, qh->gap_uf);
-	do {
-		if (unlikely (ehci->pshadow [frame].ptr != 0)) {
-
-// FIXME -- just link toward the end, before any qh with a shorter period,
-// AND accommodate it already having been linked here (after some other qh)
-// AS WELL AS updating the schedule checking logic
-
-			BUG ();
-		} else {
-			ehci->pshadow [frame].qh = qh_get (qh);
-			ehci->periodic [frame] =
-				QH_NEXT (qh->qh_dma);
-		}
-		wmb ();
-		frame += qh->period;
-	} while (frame < ehci->periodic_size);
-
-	/* update per-qh bandwidth for usbfs */
-	hcd_to_bus (&ehci->hcd)->bandwidth_allocated += 
-		(qh->usecs + qh->c_usecs) / qh->period;
-
-	/* maybe enable periodic schedule processing */
-	if (!ehci->periodic_sched++)
-		status = enable_periodic (ehci);
+ 	status = qh_link_periodic (ehci, qh);
 done:
 	return status;
 }
 
 static int intr_submit (
 	struct ehci_hcd		*ehci,
+	struct usb_host_endpoint *ep,
 	struct urb		*urb,
 	struct list_head	*qtd_list,
 	int			mem_flags
@@ -532,24 +593,18 @@
 	unsigned		epnum;
 	unsigned long		flags;
 	struct ehci_qh		*qh;
-	struct hcd_dev		*dev;
-	int			is_input;
 	int			status = 0;
 	struct list_head	empty;
 
 	/* get endpoint and transfer/schedule data */
-	epnum = usb_pipeendpoint (urb->pipe);
-	is_input = usb_pipein (urb->pipe);
-	if (is_input)
-		epnum |= 0x10;
+	epnum = ep->desc.bEndpointAddress;
 
 	spin_lock_irqsave (&ehci->lock, flags);
-	dev = (struct hcd_dev *)urb->dev->hcpriv;
 
 	/* get qh and force any scheduling errors */
 	INIT_LIST_HEAD (&empty);
-	qh = qh_append_tds (ehci, urb, &empty, epnum, &dev->ep [epnum]);
-	if (qh == 0) {
+	qh = qh_append_tds (ehci, urb, &empty, epnum, &ep->hcpriv);
+	if (qh == NULL) {
 		status = -ENOMEM;
 		goto done;
 	}
@@ -559,11 +614,11 @@
 	}
 
 	/* then queue the urb's tds to the qh */
-	qh = qh_append_tds (ehci, urb, qtd_list, epnum, &dev->ep [epnum]);
-	BUG_ON (qh == 0);
+	qh = qh_append_tds (ehci, urb, qtd_list, epnum, &ep->hcpriv);
+	BUG_ON (qh == NULL);
 
 	/* ... update usbfs periodic stats */
-	hcd_to_bus (&ehci->hcd)->bandwidth_int_reqs++;
+	ehci_to_hcd(ehci)->self.bandwidth_int_reqs++;
 
 done:
 	spin_unlock_irqrestore (&ehci->lock, flags);
@@ -583,7 +638,7 @@
 	struct ehci_iso_stream *stream;
 
 	stream = kmalloc(sizeof *stream, mem_flags);
-	if (likely (stream != 0)) {
+	if (likely (stream != NULL)) {
 		memset (stream, 0, sizeof(*stream));
 		INIT_LIST_HEAD(&stream->td_list);
 		INIT_LIST_HEAD(&stream->free_list);
@@ -614,11 +669,10 @@
 	 */
 	epnum = usb_pipeendpoint (pipe);
 	is_input = usb_pipein (pipe) ? USB_DIR_IN : 0;
+	maxp = usb_maxpacket(dev, pipe, !is_input);
 	if (is_input) {
-		maxp = dev->epmaxpacketin [epnum];
 		buf1 = (1 << 11);
 	} else {
-		maxp = dev->epmaxpacketout [epnum];
 		buf1 = 0;
 	}
 
@@ -690,7 +744,6 @@
 	 */
 	if (stream->refcount == 1) {
 		int		is_in;
-		struct hcd_dev	*dev = stream->udev->hcpriv;
 
 		// BUG_ON (!list_empty(&stream->td_list));
 
@@ -720,7 +773,7 @@
 
 		is_in = (stream->bEndpointAddress & USB_DIR_IN) ? 0x10 : 0;
 		stream->bEndpointAddress &= 0x0f;
-		dev->ep[is_in + stream->bEndpointAddress] = NULL;
+		stream->ep->hcpriv = NULL;
 
 		if (stream->rescheduled) {
 			ehci_info (ehci, "ep%d%s-iso rescheduled "
@@ -738,7 +791,7 @@
 static inline struct ehci_iso_stream *
 iso_stream_get (struct ehci_iso_stream *stream)
 {
-	if (likely (stream != 0))
+	if (likely (stream != NULL))
 		stream->refcount++;
 	return stream;
 }
@@ -747,24 +800,25 @@
 iso_stream_find (struct ehci_hcd *ehci, struct urb *urb)
 {
 	unsigned		epnum;
-	struct hcd_dev		*dev;
 	struct ehci_iso_stream	*stream;
+	struct usb_host_endpoint *ep;
 	unsigned long		flags;
 
 	epnum = usb_pipeendpoint (urb->pipe);
 	if (usb_pipein(urb->pipe))
-		epnum += 0x10;
+		ep = urb->dev->ep_in[epnum];
+	else
+		ep = urb->dev->ep_out[epnum];
 
 	spin_lock_irqsave (&ehci->lock, flags);
+	stream = ep->hcpriv;
 
-	dev = (struct hcd_dev *)urb->dev->hcpriv;
-	stream = dev->ep [epnum];
-
-	if (unlikely (stream == 0)) {
+	if (unlikely (stream == NULL)) {
 		stream = iso_stream_alloc(GFP_ATOMIC);
-		if (likely (stream != 0)) {
+		if (likely (stream != NULL)) {
 			/* dev->ep owns the initial refcount */
-			dev->ep[epnum] = stream;
+			ep->hcpriv = stream;
+			stream->ep = ep;
 			iso_stream_init(stream, urb->dev, urb->pipe,
 					urb->interval);
 		}
@@ -772,8 +826,8 @@
 	/* if dev->ep [epnum] is a QH, info1.maxpacket is nonzero */
 	} else if (unlikely (stream->hw_info1 != 0)) {
 		ehci_dbg (ehci, "dev %s ep%d%s, not iso??\n",
-			urb->dev->devpath, epnum & 0x0f,
-			(epnum & 0x10) ? "in" : "out");
+			urb->dev->devpath, epnum,
+			usb_pipein(urb->pipe) ? "in" : "out");
 		stream = NULL;
 	}
 
@@ -786,7 +840,7 @@
 
 /*-------------------------------------------------------------------------*/
 
-/* ehci_iso_sched ops can be shared, ITD-only, or SITD-only */
+/* ehci_iso_sched ops can be ITD-only or SITD-only */
 
 static struct ehci_iso_sched *
 iso_sched_alloc (unsigned packets, int mem_flags)
@@ -796,7 +850,7 @@
 
 	size += packets * sizeof (struct ehci_iso_packet);
 	iso_sched = kmalloc (size, mem_flags);
-	if (likely (iso_sched != 0)) {
+	if (likely (iso_sched != NULL)) {
 		memset(iso_sched, 0, size);
 		INIT_LIST_HEAD (&iso_sched->td_list);
 	}
@@ -873,7 +927,7 @@
 	unsigned long		flags;
 
 	sched = iso_sched_alloc (urb->number_of_packets, mem_flags);
-	if (unlikely (sched == 0))
+	if (unlikely (sched == NULL))
 		return -ENOMEM;
 
 	itd_sched_init (sched, stream, urb);
@@ -907,7 +961,7 @@
 			spin_lock_irqsave (&ehci->lock, flags);
 		}
 
-		if (unlikely (0 == itd)) {
+		if (unlikely (NULL == itd)) {
 			iso_sched_free (stream, sched);
 			spin_unlock_irqrestore (&ehci->lock, flags);
 			return -ENOMEM;
@@ -1204,7 +1258,7 @@
 	next_uframe = stream->next_uframe % mod;
 
 	if (unlikely (list_empty(&stream->td_list))) {
-		hcd_to_bus (&ehci->hcd)->bandwidth_allocated
+		ehci_to_hcd(ehci)->self.bandwidth_allocated
 				+= stream->bandwidth;
 		ehci_vdbg (ehci,
 			"schedule devp %s ep%d%s-iso period %d start %d.%d\n",
@@ -1214,7 +1268,7 @@
 			next_uframe >> 3, next_uframe & 0x7);
 		stream->start = jiffies;
 	}
-	hcd_to_bus (&ehci->hcd)->bandwidth_isoc_reqs++;
+	ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs++;
 
 	/* fill iTDs uframe by uframe */
 	for (packet = 0, itd = NULL; packet < urb->number_of_packets; ) {
@@ -1336,10 +1390,10 @@
 	ehci->periodic_sched--;
 	if (unlikely (!ehci->periodic_sched))
 		(void) disable_periodic (ehci);
-	hcd_to_bus (&ehci->hcd)->bandwidth_isoc_reqs--;
+	ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--;
 
 	if (unlikely (list_empty (&stream->td_list))) {
-		hcd_to_bus (&ehci->hcd)->bandwidth_allocated
+		ehci_to_hcd(ehci)->self.bandwidth_allocated
 				-= stream->bandwidth;
 		ehci_vdbg (ehci,
 			"deschedule devp %s ep%d%s-iso\n",
@@ -1362,7 +1416,7 @@
 
 	/* Get iso_stream head */
 	stream = iso_stream_find (ehci, urb);
-	if (unlikely (stream == 0)) {
+	if (unlikely (stream == NULL)) {
 		ehci_dbg (ehci, "can't get iso stream\n");
 		return -ENOMEM;
 	}
@@ -1476,7 +1530,7 @@
 	unsigned long		flags;
 
 	iso_sched = iso_sched_alloc (urb->number_of_packets, mem_flags);
-	if (iso_sched == 0)
+	if (iso_sched == NULL)
 		return -ENOMEM;
 
 	sitd_sched_init (iso_sched, stream, urb);
@@ -1589,7 +1643,7 @@
 
 	if (list_empty(&stream->td_list)) {
 		/* usbfs ignores TT bandwidth */
-		hcd_to_bus (&ehci->hcd)->bandwidth_allocated
+		ehci_to_hcd(ehci)->self.bandwidth_allocated
 				+= stream->bandwidth;
 		ehci_vdbg (ehci,
 			"sched dev%s ep%d%s-iso [%d] %dms/%04x\n",
@@ -1599,7 +1653,7 @@
 			stream->interval, le32_to_cpu (stream->splits));
 		stream->start = jiffies;
 	}
-	hcd_to_bus (&ehci->hcd)->bandwidth_isoc_reqs++;
+	ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs++;
 
 	/* fill sITDs frame by frame */
 	for (packet = 0, sitd = NULL;
@@ -1699,10 +1753,10 @@
 	ehci->periodic_sched--;
 	if (!ehci->periodic_sched)
 		(void) disable_periodic (ehci);
-	hcd_to_bus (&ehci->hcd)->bandwidth_isoc_reqs--;
+	ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--;
 
 	if (list_empty (&stream->td_list)) {
-		hcd_to_bus (&ehci->hcd)->bandwidth_allocated
+		ehci_to_hcd(ehci)->self.bandwidth_allocated
 				-= stream->bandwidth;
 		ehci_vdbg (ehci,
 			"deschedule devp %s ep%d%s-iso\n",
@@ -1730,7 +1784,7 @@
 
 	/* Get iso_stream head */
 	stream = iso_stream_find (ehci, urb);
-	if (stream == 0) {
+	if (stream == NULL) {
 		ehci_dbg (ehci, "can't get iso stream\n");
 		return -ENOMEM;
 	}
@@ -1806,7 +1860,7 @@
 	 * Touches as few pages as possible:  cache-friendly.
 	 */
 	now_uframe = ehci->next_uframe;
-	if (HCD_IS_RUNNING (ehci->hcd.state))
+	if (HCD_IS_RUNNING (ehci_to_hcd(ehci)->state))
 		clock = readl (&ehci->regs->frame_index);
 	else
 		clock = now_uframe + mod - 1;
@@ -1835,12 +1889,12 @@
 		type = Q_NEXT_TYPE (*hw_p);
 		modified = 0;
 
-		while (q.ptr != 0) {
+		while (q.ptr != NULL) {
 			unsigned		uf;
 			union ehci_shadow	temp;
 			int			live;
 
-			live = HCD_IS_RUNNING (ehci->hcd.state);
+			live = HCD_IS_RUNNING (ehci_to_hcd(ehci)->state);
 			switch (type) {
 			case Q_TYPE_QH:
 				/* handle any completions */
@@ -1849,7 +1903,7 @@
 				q = q.qh->qh_next;
 				modified = qh_completions (ehci, temp.qh, regs);
 				if (unlikely (list_empty (&temp.qh->qtd_list)))
-					intr_deschedule (ehci, temp.qh, 0);
+					intr_deschedule (ehci, temp.qh);
 				qh_put (temp.qh);
 				break;
 			case Q_TYPE_FSTN:
@@ -1929,7 +1983,7 @@
 		if (now_uframe == clock) {
 			unsigned	now;
 
-			if (!HCD_IS_RUNNING (ehci->hcd.state))
+			if (!HCD_IS_RUNNING (ehci_to_hcd(ehci)->state))
 				break;
 			ehci->next_uframe = now_uframe;
 			now = readl (&ehci->regs->frame_index) % mod;
diff -Nru a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
--- a/drivers/usb/host/ehci.h	2005-03-01 23:39:09 -08:00
+++ b/drivers/usb/host/ehci.h	2005-03-01 23:39:09 -08:00
@@ -36,7 +36,7 @@
 
 /* ehci_hcd->lock guards shared data against other CPUs:
  *   ehci_hcd:	async, reclaim, periodic (and shadow), ...
- *   hcd_dev:	ep[]
+ *   usb_host_endpoint: hcpriv
  *   ehci_qh:	qh_next, qtd_list
  *   ehci_qtd:	qtd_list
  *
@@ -47,13 +47,6 @@
 #define	EHCI_MAX_ROOT_PORTS	15		/* see HCS_N_PORTS */
 
 struct ehci_hcd {			/* one per controller */
-
-	/* glue to PCI and HCD framework */
-	struct usb_hcd		hcd;		/* must come first! */
-	struct ehci_caps __iomem *caps;
-	struct ehci_regs __iomem *regs;
-	__u32			hcs_params;	/* cached register copy */
-
 	spinlock_t		lock;
 
 	/* async schedule support */
@@ -91,6 +84,11 @@
 
 	unsigned		is_arc_rh_tt:1;	/* ARC roothub with TT */
 
+	/* glue to PCI and HCD framework */
+	struct ehci_caps __iomem *caps;
+	struct ehci_regs __iomem *regs;
+	__u32			hcs_params;	/* cached register copy */
+
 	/* irq statistics */
 #ifdef EHCI_STATS
 	struct ehci_stats	stats;
@@ -100,8 +98,15 @@
 #endif
 };
 
-/* unwrap an HCD pointer to get an EHCI_HCD pointer */ 
-#define hcd_to_ehci(hcd_ptr) container_of(hcd_ptr, struct ehci_hcd, hcd)
+/* convert between an HCD pointer and the corresponding EHCI_HCD */ 
+static inline struct ehci_hcd *hcd_to_ehci (struct usb_hcd *hcd)
+{
+	return (struct ehci_hcd *) (hcd->hcd_priv);
+}
+static inline struct usb_hcd *ehci_to_hcd (struct ehci_hcd *ehci)
+{
+	return container_of ((void *) ehci, struct usb_hcd, hcd_priv);
+}
 
 
 enum ehci_timer_action {
@@ -259,6 +264,30 @@
 #define PORT_CONNECT	(1<<0)		/* device connected */
 } __attribute__ ((packed));
 
+/* Appendix C, Debug port ... intended for use with special "debug devices"
+ * that can help if there's no serial console.  (nonstandard enumeration.)
+ */
+struct ehci_dbg_port {
+	u32	control;
+#define DBGP_OWNER	(1<<30)
+#define DBGP_ENABLED	(1<<28)
+#define DBGP_DONE	(1<<16)
+#define DBGP_INUSE	(1<<10)
+#define DBGP_ERRCODE(x)	(((x)>>7)&0x0f)
+#	define DBGP_ERR_BAD	1
+#	define DBGP_ERR_SIGNAL	2
+#define DBGP_ERROR	(1<<6)
+#define DBGP_GO		(1<<5)
+#define DBGP_OUT	(1<<4)
+#define DBGP_LEN(x)	(((x)>>0)&0x0f)
+	u32	pids;
+#define DBGP_PID_GET(x)		(((x)>>16)&0xff)
+#define DBGP_PID_SET(data,tok)	(((data)<<8)|(tok));
+	u32	data03;
+	u32	data47;
+	u32	address;
+#define DBGP_EPADDR(dev,ep)	(((dev)<<8)|(ep));
+} __attribute__ ((packed));
 
 /*-------------------------------------------------------------------------*/
 
@@ -430,6 +459,7 @@
 	struct list_head	td_list;	/* queued itds/sitds */
 	struct list_head	free_list;	/* list of unused itds/sitds */
 	struct usb_device	*udev;
+ 	struct usb_host_endpoint *ep;
 
 	/* output of (re)scheduling */
 	unsigned long		start;		/* jiffies */
diff -Nru a/drivers/usb/host/hc_crisv10.c b/drivers/usb/host/hc_crisv10.c
--- a/drivers/usb/host/hc_crisv10.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/usb/host/hc_crisv10.c	2005-03-01 23:39:09 -08:00
@@ -113,17 +113,17 @@
 {
 	0x12,  /*  __u8  bLength; */
 	0x01,  /*  __u8  bDescriptorType; Device */
-	0x00,  /*  __u16 bcdUSB; v1.0 */
+	0x00,  /*  __le16 bcdUSB; v1.0 */
 	0x01,
 	0x09,  /*  __u8  bDeviceClass; HUB_CLASSCODE */
 	0x00,  /*  __u8  bDeviceSubClass; */
 	0x00,  /*  __u8  bDeviceProtocol; */
 	0x08,  /*  __u8  bMaxPacketSize0; 8 Bytes */
-	0x00,  /*  __u16 idVendor; */
+	0x00,  /*  __le16 idVendor; */
 	0x00,
-	0x00,  /*  __u16 idProduct; */
+	0x00,  /*  __le16 idProduct; */
 	0x00,
-	0x00,  /*  __u16 bcdDevice; */
+	0x00,  /*  __le16 bcdDevice; */
 	0x00,
 	0x00,  /*  __u8  iManufacturer; */
 	0x02,  /*  __u8  iProduct; */
@@ -136,7 +136,7 @@
 {
 	0x09,  /*  __u8  bLength; */
 	0x02,  /*  __u8  bDescriptorType; Configuration */
-	0x19,  /*  __u16 wTotalLength; */
+	0x19,  /*  __le16 wTotalLength; */
 	0x00,
 	0x01,  /*  __u8  bNumInterfaces; */
 	0x01,  /*  __u8  bConfigurationValue; */
@@ -160,7 +160,7 @@
 	0x05,  /*  __u8  ep_bDescriptorType; Endpoint */
 	0x81,  /*  __u8  ep_bEndpointAddress; IN Endpoint 1 */
 	0x03,  /*  __u8  ep_bmAttributes; Interrupt */
-	0x08,  /*  __u16 ep_wMaxPacketSize; 8 Bytes */
+	0x08,  /*  __le16 ep_wMaxPacketSize; 8 Bytes */
 	0x00,
 	0xff   /*  __u8  ep_bInterval; 255 ms */
 };
@@ -479,8 +479,6 @@
 static int etrax_usb_submit_urb(struct urb *urb, int 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);
-static int etrax_usb_allocate_dev(struct usb_device *usb_dev);
-static int etrax_usb_deallocate_dev(struct usb_device *usb_dev);
 
 static irqreturn_t etrax_usb_tx_interrupt(int irq, void *vhc, struct pt_regs *regs);
 static irqreturn_t etrax_usb_rx_interrupt(int irq, void *vhc, struct pt_regs *regs);
@@ -512,8 +510,6 @@
 
 static struct usb_operations etrax_usb_device_operations =
 {
-	.allocate = etrax_usb_allocate_dev,
-	.deallocate = etrax_usb_deallocate_dev,
 	.get_frame_number = etrax_usb_get_frame_number,
 	.submit_urb = etrax_usb_submit_urb,
 	.unlink_urb = etrax_usb_unlink_urb,
@@ -1579,20 +1575,6 @@
 	return (*R_USB_FM_NUMBER & 0x7ff);
 }
 
-static int etrax_usb_allocate_dev(struct usb_device *usb_dev)
-{
-	DBFENTER;
-	DBFEXIT;
-	return 0;
-}
-
-static int etrax_usb_deallocate_dev(struct usb_device *usb_dev)
-{
-	DBFENTER;
-	DBFEXIT;
-	return 0;
-}
-
 static irqreturn_t etrax_usb_tx_interrupt(int irq, void *vhc, struct pt_regs *regs)
 {
 	DBFENTER;
@@ -4546,7 +4528,7 @@
         usb_rh->speed = USB_SPEED_FULL;
         usb_rh->devnum = 1;
         hc->bus->devnum_next = 2;
-        usb_rh->epmaxpacketin[0] = usb_rh->epmaxpacketout[0] = 64;
+        usb_rh->ep0.desc.wMaxPacketSize = __const_cpu_to_le16(64);
         usb_get_device_descriptor(usb_rh, USB_DT_DEVICE_SIZE);
 	usb_new_device(usb_rh);
 
diff -Nru a/drivers/usb/host/ohci-au1xxx.c b/drivers/usb/host/ohci-au1xxx.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/usb/host/ohci-au1xxx.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,362 @@
+/*
+ * 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
+ *
+ * Bus Glue for AMD Alchemy Au1xxx
+ *
+ * Written by Christopher Hoover <ch@hpl.hp.com>
+ * Based on fragments of previous driver by Rusell King et al.
+ *
+ * Modified for LH7A404 from ohci-sa1111.c
+ *  by Durgesh Pattamatta <pattamattad@sharpsec.com>
+ * Modified for AMD Alchemy Au1xxx
+ *  by Matt Porter <mporter@kernel.crashing.org>
+ *
+ * This file is licenced under the GPL.
+ */
+
+#include <asm/mach-au1x00/au1000.h>
+
+#define USBH_ENABLE_BE (1<<0)
+#define USBH_ENABLE_C  (1<<1)
+#define USBH_ENABLE_E  (1<<2)
+#define USBH_ENABLE_CE (1<<3)
+#define USBH_ENABLE_RD (1<<4)
+
+#ifdef __LITTLE_ENDIAN
+#define USBH_ENABLE_INIT (USBH_ENABLE_CE | USBH_ENABLE_E | USBH_ENABLE_C)
+#elif __BIG_ENDIAN
+#define USBH_ENABLE_INIT (USBH_ENABLE_CE | USBH_ENABLE_E | USBH_ENABLE_C | USBH_ENABLE_BE)
+#else
+#error not byte order defined
+#endif
+
+extern int usb_disabled(void);
+
+/*-------------------------------------------------------------------------*/
+
+static void au1xxx_start_hc(struct platform_device *dev)
+{
+	printk(KERN_DEBUG __FILE__
+		": starting Au1xxx OHCI USB Controller\n");
+
+	/* enable host controller */
+	au_writel(USBH_ENABLE_CE, USB_HOST_CONFIG);
+	udelay(1000);
+	au_writel(USBH_ENABLE_INIT, USB_HOST_CONFIG);
+	udelay(1000);
+
+	/* wait for reset complete (read register twice; see au1500 errata) */
+	while (au_readl(USB_HOST_CONFIG),
+		!(au_readl(USB_HOST_CONFIG) & USBH_ENABLE_RD))
+		udelay(1000);
+
+	printk(KERN_DEBUG __FILE__
+	": Clock to USB host has been enabled \n");
+}
+
+static void au1xxx_stop_hc(struct platform_device *dev)
+{
+	printk(KERN_DEBUG __FILE__
+	       ": stopping Au1xxx OHCI USB Controller\n");
+
+	/* Disable clock */
+	au_writel(readl((void *)USB_HOST_CONFIG) & ~USBH_ENABLE_CE, USB_HOST_CONFIG);
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+
+static irqreturn_t usb_hcd_au1xxx_hcim_irq (int irq, void *__hcd,
+					     struct pt_regs * r)
+{
+	struct usb_hcd *hcd = __hcd;
+
+	return usb_hcd_irq(irq, hcd, r);
+}
+
+/*-------------------------------------------------------------------------*/
+
+void usb_hcd_au1xxx_remove (struct usb_hcd *, struct platform_device *);
+
+/* configure so an HC device and id are always provided */
+/* always called with process context; sleeping is OK */
+
+
+/**
+ * usb_hcd_au1xxx_probe - initialize Au1xxx-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_au1xxx_probe (const struct hc_driver *driver,
+			  struct usb_hcd **hcd_out,
+			  struct platform_device *dev)
+{
+	int retval;
+	struct usb_hcd *hcd = 0;
+
+	unsigned int *addr = NULL;
+
+	if (!request_mem_region(dev->resource[0].start,
+				dev->resource[0].end
+				- dev->resource[0].start + 1, hcd_name)) {
+		pr_debug("request_mem_region failed");
+		return -EBUSY;
+	}
+
+	au1xxx_start_hc(dev);
+
+	addr = ioremap(dev->resource[0].start,
+		       dev->resource[0].end
+		       - dev->resource[0].start + 1);
+	if (!addr) {
+		pr_debug("ioremap failed");
+		retval = -ENOMEM;
+		goto err1;
+	}
+
+	if(dev->resource[1].flags != IORESOURCE_IRQ) {
+		pr_debug ("resource[1] is not IORESOURCE_IRQ");
+		retval = -ENOMEM;
+		goto err1;
+	}
+
+	hcd = usb_create_hcd(driver);
+	if (hcd == NULL) {
+		pr_debug ("usb_create_hcd failed");
+		retval = -ENOMEM;
+		goto err1;
+	}
+	ohci_hcd_init(hcd_to_ohci(hcd));
+
+	hcd->irq = dev->resource[1].start;
+	hcd->regs = addr;
+	hcd->self.controller = &dev->dev;
+
+	retval = hcd_buffer_create (hcd);
+	if (retval != 0) {
+		pr_debug ("pool alloc fail");
+		goto err2;
+	}
+
+	retval = request_irq (hcd->irq, usb_hcd_au1xxx_hcim_irq, SA_INTERRUPT,
+			      hcd->driver->description, hcd);
+	if (retval != 0) {
+		pr_debug("request_irq failed");
+		retval = -EBUSY;
+		goto err3;
+	}
+
+	pr_debug ("%s (Au1xxx) at 0x%p, irq %d",
+	     hcd->driver->description, hcd->regs, hcd->irq);
+
+	hcd->self.bus_name = "au1xxx";
+
+	usb_register_bus (&hcd->self);
+
+	if ((retval = driver->start (hcd)) < 0)
+	{
+		usb_hcd_au1xxx_remove(hcd, dev);
+		printk("bad driver->start\n");
+		return retval;
+	}
+
+	*hcd_out = hcd;
+	return 0;
+
+ err3:
+	hcd_buffer_destroy (hcd);
+ err2:
+	usb_put_hcd(hcd);
+ err1:
+	au1xxx_stop_hc(dev);
+	release_mem_region(dev->resource[0].start,
+				dev->resource[0].end
+			   - dev->resource[0].start + 1);
+	return retval;
+}
+
+
+/* may be called without controller electrically present */
+/* may be called with controller, bus, and devices active */
+
+/**
+ * usb_hcd_au1xxx_remove - shutdown processing for Au1xxx-based HCDs
+ * @dev: USB Host Controller being removed
+ * Context: !in_interrupt()
+ *
+ * Reverses the effect of usb_hcd_au1xxx_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_au1xxx_remove (struct usb_hcd *hcd, struct platform_device *dev)
+{
+	pr_debug ("remove: %s, state %x", hcd->self.bus_name, hcd->state);
+
+	if (in_interrupt ())
+		BUG ();
+
+	hcd->state = USB_STATE_QUIESCING;
+
+	pr_debug ("%s: roothub graceful disconnect", hcd->self.bus_name);
+	usb_disconnect (&hcd->self.root_hub);
+
+	hcd->driver->stop (hcd);
+	hcd->state = USB_STATE_HALT;
+
+	free_irq (hcd->irq, hcd);
+	hcd_buffer_destroy (hcd);
+
+	usb_deregister_bus (&hcd->self);
+
+	au1xxx_stop_hc(dev);
+	release_mem_region(dev->resource[0].start,
+			   dev->resource[0].end
+			   - dev->resource[0].start + 1);
+}
+
+/*-------------------------------------------------------------------------*/
+
+static int __devinit
+ohci_au1xxx_start (struct usb_hcd *hcd)
+{
+	struct ohci_hcd	*ohci = hcd_to_ohci (hcd);
+	int		ret;
+
+	ohci_dbg (ohci, "ohci_au1xxx_start, ohci:%p", ohci);
+
+	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_au1xxx_hc_driver = {
+	.description =		hcd_name,
+	.product_desc =		"Au1xxx OHCI",
+	.hcd_priv_size =	sizeof(struct ohci_hcd),
+
+	/*
+	 * generic hardware linkage
+	 */
+	.irq =			ohci_irq,
+	.flags =		HCD_USB11,
+
+	/*
+	 * basic lifecycle operations
+	 */
+	.start =		ohci_au1xxx_start,
+#ifdef	CONFIG_PM
+	/* suspend:		ohci_au1xxx_suspend,  -- tbd */
+	/* resume:		ohci_au1xxx_resume,   -- tbd */
+#endif /*CONFIG_PM*/
+	.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_hub_status_data,
+	.hub_control =		ohci_hub_control,
+};
+
+/*-------------------------------------------------------------------------*/
+
+static int ohci_hcd_au1xxx_drv_probe(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct usb_hcd *hcd = NULL;
+	int ret;
+
+	pr_debug ("In ohci_hcd_au1xxx_drv_probe");
+
+	if (usb_disabled())
+		return -ENODEV;
+
+	ret = usb_hcd_au1xxx_probe(&ohci_au1xxx_hc_driver, &hcd, pdev);
+
+	if (ret == 0)
+		dev_set_drvdata(dev, hcd);
+
+	return ret;
+}
+
+static int ohci_hcd_au1xxx_drv_remove(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct usb_hcd *hcd = dev_get_drvdata(dev);
+
+	usb_hcd_au1xxx_remove(hcd, pdev);
+	dev_set_drvdata(dev, NULL);
+	return 0;
+}
+	/*TBD*/
+/*static int ohci_hcd_au1xxx_drv_suspend(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct usb_hcd *hcd = dev_get_drvdata(dev);
+
+	return 0;
+}
+static int ohci_hcd_au1xxx_drv_resume(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct usb_hcd *hcd = dev_get_drvdata(dev);
+
+	return 0;
+}
+*/
+
+static struct device_driver ohci_hcd_au1xxx_driver = {
+	.name		= "au1xxx-ohci",
+	.bus		= &platform_bus_type,
+	.probe		= ohci_hcd_au1xxx_drv_probe,
+	.remove		= ohci_hcd_au1xxx_drv_remove,
+	/*.suspend	= ohci_hcd_au1xxx_drv_suspend, */
+	/*.resume	= ohci_hcd_au1xxx_drv_resume, */
+};
+
+static int __init ohci_hcd_au1xxx_init (void)
+{
+	pr_debug (DRIVER_INFO " (Au1xxx)");
+	pr_debug ("block sizes: ed %d td %d\n",
+		sizeof (struct ed), sizeof (struct td));
+
+	return driver_register(&ohci_hcd_au1xxx_driver);
+}
+
+static void __exit ohci_hcd_au1xxx_cleanup (void)
+{
+	driver_unregister(&ohci_hcd_au1xxx_driver);
+}
+
+module_init (ohci_hcd_au1xxx_init);
+module_exit (ohci_hcd_au1xxx_cleanup);
diff -Nru a/drivers/usb/host/ohci-dbg.c b/drivers/usb/host/ohci-dbg.c
--- a/drivers/usb/host/ohci-dbg.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/usb/host/ohci-dbg.c	2005-03-01 23:39:09 -08:00
@@ -676,19 +676,23 @@
 static CLASS_DEVICE_ATTR (registers, S_IRUGO, show_registers, NULL);
 
 
-static inline void create_debug_files (struct ohci_hcd *bus)
+static inline void create_debug_files (struct ohci_hcd *ohci)
 {
-	class_device_create_file(&bus->hcd.self.class_dev, &class_device_attr_async);
-	class_device_create_file(&bus->hcd.self.class_dev, &class_device_attr_periodic);
-	class_device_create_file(&bus->hcd.self.class_dev, &class_device_attr_registers);
-	ohci_dbg (bus, "created debug files\n");
+	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);
+	class_device_create_file(cldev, &class_device_attr_registers);
+	ohci_dbg (ohci, "created debug files\n");
 }
 
-static inline void remove_debug_files (struct ohci_hcd *bus)
+static inline void remove_debug_files (struct ohci_hcd *ohci)
 {
-	class_device_remove_file(&bus->hcd.self.class_dev, &class_device_attr_async);
-	class_device_remove_file(&bus->hcd.self.class_dev, &class_device_attr_periodic);
-	class_device_remove_file(&bus->hcd.self.class_dev, &class_device_attr_registers);
+	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);
+	class_device_remove_file(cldev, &class_device_attr_registers);
 }
 
 #endif
diff -Nru a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
--- a/drivers/usb/host/ohci-hcd.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/usb/host/ohci-hcd.c	2005-03-01 23:38:52 -08:00
@@ -165,6 +165,7 @@
  */
 static int ohci_urb_enqueue (
 	struct usb_hcd	*hcd,
+	struct usb_host_endpoint *ep,
 	struct urb	*urb,
 	int		mem_flags
 ) {
@@ -181,7 +182,7 @@
 #endif
 	
 	/* every endpoint has a ed, locate and maybe (re)initialize it */
-	if (! (ed = ed_get (ohci, urb->dev, pipe, urb->interval)))
+	if (! (ed = ed_get (ohci, ep, urb->dev, pipe, urb->interval)))
 		return -ENOMEM;
 
 	/* for the private part of the URB we need the number of TDs (size) */
@@ -239,7 +240,7 @@
 	spin_lock_irqsave (&ohci->lock, flags);
 
 	/* don't submit to a dead HC */
-	if (!HCD_IS_RUNNING(ohci->hcd.state)) {
+	if (!HCD_IS_RUNNING(hcd->state)) {
 		retval = -ENODEV;
 		goto fail;
 	}
@@ -307,7 +308,7 @@
 #endif		  
 
 	spin_lock_irqsave (&ohci->lock, flags);
- 	if (HCD_IS_RUNNING(ohci->hcd.state)) {
+ 	if (HCD_IS_RUNNING(hcd->state)) {
 		urb_priv_t  *urb_priv;
 
 		/* Unless an IRQ completed the unlink while it was being
@@ -338,28 +339,23 @@
  */
 
 static void
-ohci_endpoint_disable (struct usb_hcd *hcd, struct hcd_dev *dev, int ep)
+ohci_endpoint_disable (struct usb_hcd *hcd, struct usb_host_endpoint *ep)
 {
 	struct ohci_hcd		*ohci = hcd_to_ohci (hcd);
-	int			epnum = ep & USB_ENDPOINT_NUMBER_MASK;
 	unsigned long		flags;
-	struct ed		*ed;
+	struct ed		*ed = ep->hcpriv;
 	unsigned		limit = 1000;
 
 	/* ASSERT:  any requests/urbs are being unlinked */
 	/* ASSERT:  nobody can be submitting urbs for this any more */
 
-	epnum <<= 1;
-	if (epnum != 0 && !(ep & USB_DIR_IN))
-		epnum |= 1;
+	if (!ed)
+		return;
 
 rescan:
 	spin_lock_irqsave (&ohci->lock, flags);
-	ed = dev->ep [epnum];
-	if (!ed)
-		goto done;
 
-	if (!HCD_IS_RUNNING (ohci->hcd.state)) {
+	if (!HCD_IS_RUNNING (hcd->state)) {
 sanitize:
 		ed->state = ED_IDLE;
 		finish_unlinks (ohci, 0, NULL);
@@ -387,14 +383,13 @@
 		/* caller was supposed to have unlinked any requests;
 		 * that's not our job.  can't recover; must leak ed.
 		 */
-		ohci_err (ohci, "leak ed %p (#%d) state %d%s\n",
-			ed, epnum, ed->state,
+		ohci_err (ohci, "leak ed %p (#%02x) state %d%s\n",
+			ed, ep->desc.bEndpointAddress, ed->state,
 			list_empty (&ed->td_list) ? "" : " (has tds)");
 		td_free (ohci, ed->dummy);
 		break;
 	}
-	dev->ep [epnum] = NULL;
-done:
+	ep->hcpriv = NULL;
 	spin_unlock_irqrestore (&ohci->lock, flags);
 	return;
 }
@@ -421,17 +416,18 @@
 
 static int ohci_init (struct ohci_hcd *ohci)
 {
-	u32 temp;
 	int ret;
 
 	disable (ohci);
-	ohci->regs = ohci->hcd.regs;
+	ohci->regs = ohci_to_hcd(ohci)->regs;
 	ohci->next_statechange = jiffies;
 
 #ifndef IR_DISABLE
 	/* SMM owns the HC?  not for long! */
 	if (!no_handshake && ohci_readl (ohci,
 					&ohci->regs->control) & OHCI_CTRL_IR) {
+		u32 temp;
+
 		ohci_dbg (ohci, "USB HC TakeOver from BIOS/SMM\n");
 
 		/* this timeout is arbitrary.  we make it long, so systems
@@ -445,7 +441,8 @@
 		while (ohci_readl (ohci, &ohci->regs->control) & OHCI_CTRL_IR) {
 			msleep (10);
 			if (--temp == 0) {
-				ohci_err (ohci, "USB HC TakeOver failed!\n");
+				ohci_err (ohci, "USB HC takeover failed!"
+					"  (BIOS/SMM bug)\n");
 				return -EBUSY;
 			}
 		}
@@ -461,13 +458,13 @@
 	if (ohci->hcca)
 		return 0;
 
-	ohci->hcca = dma_alloc_coherent (ohci->hcd.self.controller,
+	ohci->hcca = dma_alloc_coherent (ohci_to_hcd(ohci)->self.controller,
 			sizeof *ohci->hcca, &ohci->hcca_dma, 0);
 	if (!ohci->hcca)
 		return -ENOMEM;
 
 	if ((ret = ohci_mem_init (ohci)) < 0)
-		ohci_stop (&ohci->hcd);
+		ohci_stop (ohci_to_hcd(ohci));
 
 	return ret;
 
@@ -512,7 +509,7 @@
 
 	if (ohci->hc_control & OHCI_CTRL_RWC
 			&& !(ohci->flags & OHCI_QUIRK_AMD756))
-		ohci->hcd.can_wakeup = 1;
+		ohci_to_hcd(ohci)->can_wakeup = 1;
 
 	switch (ohci->hc_control & OHCI_CTRL_HCFS) {
 	case OHCI_USB_OPER:
@@ -610,7 +607,7 @@
 	ohci->hc_control &= OHCI_CTRL_RWC;
  	ohci->hc_control |= OHCI_CONTROL_INIT | OHCI_USB_OPER;
  	ohci_writel (ohci, ohci->hc_control, &ohci->regs->control);
-	ohci->hcd.state = USB_STATE_RUNNING;
+	ohci_to_hcd(ohci)->state = USB_STATE_RUNNING;
 
 	/* wake on ConnectStatusChange, matching external hubs */
 	ohci_writel (ohci, RH_HS_DRWE, &ohci->regs->roothub.status);
@@ -650,12 +647,12 @@
 
 	// POTPGT delay is bits 24-31, in 2 ms units.
 	mdelay ((roothub_a (ohci) >> 23) & 0x1fe);
-	bus = hcd_to_bus (&ohci->hcd);
-	ohci->hcd.state = USB_STATE_RUNNING;
+	bus = &ohci_to_hcd(ohci)->self;
+	ohci_to_hcd(ohci)->state = USB_STATE_RUNNING;
 
 	ohci_dump (ohci, 1);
 
-	udev = hcd_to_bus (&ohci->hcd)->root_hub;
+	udev = bus->root_hub;
 	if (udev) {
 		return 0;
 	}
@@ -670,7 +667,7 @@
 	}
 
 	udev->speed = USB_SPEED_FULL;
-	if (hcd_register_root (udev, &ohci->hcd) != 0) {
+	if (hcd_register_root (udev, ohci_to_hcd(ohci)) != 0) {
 		usb_put_dev (udev);
 		disable (ohci);
 		ohci->hc_control &= ~OHCI_CTRL_HCFS;
@@ -745,11 +742,11 @@
 	if (ohci->ed_rm_list)
 		finish_unlinks (ohci, ohci_frame_no(ohci), ptregs);
 	if ((ints & OHCI_INTR_SF) != 0 && !ohci->ed_rm_list
-			&& HCD_IS_RUNNING(ohci->hcd.state))
+			&& HCD_IS_RUNNING(hcd->state))
 		ohci_writel (ohci, OHCI_INTR_SF, &regs->intrdisable);	
 	spin_unlock (&ohci->lock);
 
-	if (HCD_IS_RUNNING(ohci->hcd.state)) {
+	if (HCD_IS_RUNNING(hcd->state)) {
 		ohci_writel (ohci, ints, &regs->intrstatus);
 		ohci_writel (ohci, OHCI_INTR_MIE, &regs->intrenable);	
 		// flush those writes
@@ -767,7 +764,7 @@
 
 	ohci_dbg (ohci, "stop %s controller (state 0x%02x)\n",
 		hcfs2string (ohci->hc_control & OHCI_CTRL_HCFS),
-		ohci->hcd.state);
+		hcd->state);
 	ohci_dump (ohci, 1);
 
 	flush_scheduled_work();
@@ -778,7 +775,7 @@
 	remove_debug_files (ohci);
 	ohci_mem_cleanup (ohci);
 	if (ohci->hcca) {
-		dma_free_coherent (ohci->hcd.self.controller, 
+		dma_free_coherent (hcd->self.controller, 
 				sizeof *ohci->hcca, 
 				ohci->hcca, ohci->hcca_dma);
 		ohci->hcca = NULL;
@@ -797,7 +794,7 @@
 	int temp;
 	int i;
 	struct urb_priv *priv;
-	struct usb_device *root = ohci->hcd.self.root_hub;
+	struct usb_device *root = ohci_to_hcd(ohci)->self.root_hub;
 
 	/* mark any devices gone, so they do nothing till khubd disconnects.
 	 * recycle any "live" eds/tds (and urbs) right away.
@@ -900,21 +897,16 @@
 #include "ohci-pxa27x.c"
 #endif
 
+#ifdef CONFIG_SOC_AU1X00
+#include "ohci-au1xxx.c"
+#endif
+
 #if !(defined(CONFIG_PCI) \
       || defined(CONFIG_SA1111) \
       || defined(CONFIG_ARCH_OMAP) \
       || defined (CONFIG_ARCH_LH7A404) \
       || defined (CONFIG_PXA27x) \
+      || defined (CONFIG_SOC_AU1X00) \
 	)
 #error "missing bus glue for ohci-hcd"
-#endif
-
-#if	!defined(HAVE_HNP) && defined(CONFIG_USB_OTG)
-
-#warning non-OTG configuration, too many HCDs
-
-static void start_hnp(struct ohci_hcd *ohci)
-{
-	/* "can't happen" */
-}
 #endif
diff -Nru a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c
--- a/drivers/usb/host/ohci-hub.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/usb/host/ohci-hub.c	2005-03-01 23:38:52 -08:00
@@ -73,7 +73,7 @@
 	ohci_dbg (ohci, "suspend root hub\n");
 
 	/* First stop any processing */
-	ohci->hcd.state = USB_STATE_QUIESCING;
+	hcd->state = USB_STATE_QUIESCING;
 	if (ohci->hc_control & OHCI_SCHED_ENABLES) {
 		int		limit;
 
@@ -103,7 +103,7 @@
 			&ohci->regs->intrstatus);
 
 	/* maybe resume can wake root hub */
-	if (ohci->hcd.remote_wakeup)
+	if (hcd->remote_wakeup)
 		ohci->hc_control |= OHCI_CTRL_RWE;
 	else
 		ohci->hc_control &= ~OHCI_CTRL_RWE;
@@ -119,7 +119,7 @@
 
 done:
 	if (status == 0)
-		ohci->hcd.state = HCD_STATE_SUSPENDED;
+		hcd->state = HCD_STATE_SUSPENDED;
 	spin_unlock_irqrestore (&ohci->lock, flags);
 	return status;
 }
@@ -198,7 +198,7 @@
 	}
 
 	/* Some controllers (lucent) need extra-long delays */
-	ohci->hcd.state = USB_STATE_RESUMING;
+	hcd->state = USB_STATE_RESUMING;
 	mdelay (20 /* usb 11.5.1.10 */ + 15);
 
 	temp = ohci_readl (ohci, &ohci->regs->control);
@@ -231,7 +231,7 @@
 	msleep (3);
 
 	temp = OHCI_CONTROL_INIT | OHCI_USB_OPER;
-	if (ohci->hcd.can_wakeup)
+	if (hcd->can_wakeup)
 		temp |= OHCI_CTRL_RWC;
 	ohci->hc_control = temp;
 	ohci_writel (ohci, temp, &ohci->regs->control);
@@ -261,8 +261,7 @@
 			temp |= OHCI_BLF;
 		}
 	}
-	if (hcd_to_bus (&ohci->hcd)->bandwidth_isoc_reqs
-			|| hcd_to_bus (&ohci->hcd)->bandwidth_int_reqs)
+	if (hcd->self.bandwidth_isoc_reqs || hcd->self.bandwidth_int_reqs)
 		enables |= OHCI_CTRL_PLE|OHCI_CTRL_IE;
 	if (enables) {
 		ohci_dbg (ohci, "restarting schedules ... %08x\n", enables);
@@ -273,7 +272,7 @@
 		(void) ohci_readl (ohci, &ohci->regs->control);
 	}
 
-	ohci->hcd.state = USB_STATE_RUNNING;
+	hcd->state = USB_STATE_RUNNING;
 	return 0;
 }
 
@@ -314,7 +313,7 @@
 	 * letting khubd or root hub timer see state changes.
 	 */
 	if ((ohci->hc_control & OHCI_CTRL_HCFS) != OHCI_USB_OPER
-			|| !HCD_IS_RUNNING(ohci->hcd.state)) {
+			|| !HCD_IS_RUNNING(hcd->state)) {
 		can_suspend = 0;
 		goto done;
 	}
@@ -356,7 +355,7 @@
 		 */
 		if (!(status & RH_PS_CCS))
 			continue;
-		if ((status & RH_PS_PSS) && ohci->hcd.remote_wakeup)
+		if ((status & RH_PS_PSS) && hcd->remote_wakeup)
 			continue;
 		can_suspend = 0;
 	}
@@ -378,8 +377,8 @@
 			&& usb_trylock_device (hcd->self.root_hub)
 			) {
 		ohci_vdbg (ohci, "autosuspend\n");
-		(void) ohci_hub_suspend (&ohci->hcd);
-		ohci->hcd.state = USB_STATE_RUNNING;
+		(void) ohci_hub_suspend (hcd);
+		hcd->state = USB_STATE_RUNNING;
 		usb_unlock_device (hcd->self.root_hub);
 	}
 #endif
@@ -613,8 +612,8 @@
 		switch (wValue) {
 		case USB_PORT_FEAT_SUSPEND:
 #ifdef	CONFIG_USB_OTG
-			if (ohci->hcd.self.otg_port == (wIndex + 1)
-					&& ohci->hcd.self.b_hnp_enable)
+			if (hcd->self.otg_port == (wIndex + 1)
+					&& hcd->self.b_hnp_enable)
 				start_hnp(ohci);
 			else
 #endif
diff -Nru a/drivers/usb/host/ohci-lh7a404.c b/drivers/usb/host/ohci-lh7a404.c
--- a/drivers/usb/host/ohci-lh7a404.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/usb/host/ohci-lh7a404.c	2005-03-01 23:39:16 -08:00
@@ -106,23 +106,22 @@
 		retval = -ENOMEM;
 		goto err1;
 	}
-	
 
-	hcd = driver->hcd_alloc ();
-	if (hcd == NULL){
-		pr_debug ("hcd_alloc failed");
+	if(dev->resource[1].flags != IORESOURCE_IRQ){
+		pr_debug ("resource[1] is not IORESOURCE_IRQ");
 		retval = -ENOMEM;
 		goto err1;
 	}
+	
 
-	if(dev->resource[1].flags != IORESOURCE_IRQ){
-		pr_debug ("resource[1] is not IORESOURCE_IRQ");
+	hcd = usb_create_hcd (driver);
+	if (hcd == NULL){
+		pr_debug ("hcd_alloc failed");
 		retval = -ENOMEM;
 		goto err1;
 	}
+	ohci_hcd_init(hcd_to_ohci(hcd));
 
-	hcd->driver = (struct hc_driver *) driver;
-	hcd->description = driver->description;
 	hcd->irq = dev->resource[1].start;
 	hcd->regs = addr;
 	hcd->self.controller = &dev->dev;
@@ -130,29 +129,21 @@
 	retval = hcd_buffer_create (hcd);
 	if (retval != 0) {
 		pr_debug ("pool alloc fail");
-		goto err1;
+		goto err2;
 	}
 
 	retval = request_irq (hcd->irq, usb_hcd_lh7a404_hcim_irq, SA_INTERRUPT,
-			      hcd->description, hcd);
+			      hcd->driver->description, hcd);
 	if (retval != 0) {
 		pr_debug("request_irq failed");
 		retval = -EBUSY;
-		goto err2;
+		goto err3;
 	}
 
 	pr_debug ("%s (LH7A404) at 0x%p, irq %d",
-	     hcd->description, hcd->regs, hcd->irq);
+		hcd->driver->description, hcd->regs, hcd->irq);
 
-	usb_bus_init (&hcd->self);
-	hcd->self.op = &usb_hcd_operations;
-	hcd->self.release = &usb_hcd_release;
-	hcd->self.hcpriv = (void *) hcd;
 	hcd->self.bus_name = "lh7a404";
-	hcd->product_desc = "LH7A404 OHCI";
-
-	INIT_LIST_HEAD (&hcd->dev_list);
-
 	usb_register_bus (&hcd->self);
 
 	if ((retval = driver->start (hcd)) < 0)
@@ -164,10 +155,11 @@
 	*hcd_out = hcd;
 	return 0;
 
- err2:
+ err3:
 	hcd_buffer_destroy (hcd);
+ err2:
+	usb_put_hcd(hcd);
  err1:
-	kfree(hcd);
 	lh7a404_stop_hc(dev);
 	release_mem_region(dev->resource[0].start,
 				dev->resource[0].end
@@ -228,7 +220,7 @@
 		return ret;
 
 	if ((ret = ohci_run (ohci)) < 0) {
-		err ("can't start %s", ohci->hcd.self.bus_name);
+		err ("can't start %s", hcd->self.bus_name);
 		ohci_stop (hcd);
 		return ret;
 	}
@@ -239,6 +231,8 @@
 
 static const struct hc_driver ohci_lh7a404_hc_driver = {
 	.description =		hcd_name,
+	.product_desc =		"LH7A404 OHCI",
+	.hcd_priv_size =	sizeof(struct ohci_hcd),
 
 	/*
 	 * generic hardware linkage
@@ -255,11 +249,6 @@
 	/* resume:		ohci_lh7a404_resume,   -- tbd */
 #endif /*CONFIG_PM*/
 	.stop =			ohci_stop,
-
-	/*
-	 * memory lifecycle (except per-request)
-	 */
-	.hcd_alloc =		ohci_hcd_alloc,
 
 	/*
 	 * managing i/o requests and associated device resources
diff -Nru a/drivers/usb/host/ohci-mem.c b/drivers/usb/host/ohci-mem.c
--- a/drivers/usb/host/ohci-mem.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/usb/host/ohci-mem.c	2005-03-01 23:39:07 -08:00
@@ -23,34 +23,27 @@
 
 /*-------------------------------------------------------------------------*/
 
-static struct usb_hcd *ohci_hcd_alloc (void)
+static void ohci_hcd_init (struct ohci_hcd *ohci)
 {
-	struct ohci_hcd *ohci;
-
-	ohci = (struct ohci_hcd *) kmalloc (sizeof *ohci, GFP_KERNEL);
-	if (ohci != 0) {
-		memset (ohci, 0, sizeof (struct ohci_hcd));
-		ohci->hcd.product_desc = "OHCI Host Controller";
-		ohci->next_statechange = jiffies;
-		spin_lock_init (&ohci->lock);
-		INIT_LIST_HEAD (&ohci->pending);
-		INIT_WORK (&ohci->rh_resume, ohci_rh_resume, &ohci->hcd);
-		return &ohci->hcd;
-	}
-	return NULL;
+	ohci->next_statechange = jiffies;
+	spin_lock_init (&ohci->lock);
+	INIT_LIST_HEAD (&ohci->pending);
+	INIT_WORK (&ohci->rh_resume, ohci_rh_resume, ohci_to_hcd(ohci));
 }
 
 /*-------------------------------------------------------------------------*/
 
 static int ohci_mem_init (struct ohci_hcd *ohci)
 {
-	ohci->td_cache = dma_pool_create ("ohci_td", ohci->hcd.self.controller,
+	ohci->td_cache = dma_pool_create ("ohci_td",
+		ohci_to_hcd(ohci)->self.controller,
 		sizeof (struct td),
 		32 /* byte alignment */,
 		0 /* no page-crossing issues */);
 	if (!ohci->td_cache)
 		return -ENOMEM;
-	ohci->ed_cache = dma_pool_create ("ohci_ed", ohci->hcd.self.controller,
+	ohci->ed_cache = dma_pool_create ("ohci_ed",
+		ohci_to_hcd(ohci)->self.controller,
 		sizeof (struct ed),
 		16 /* byte alignment */,
 		0 /* no page-crossing issues */);
diff -Nru a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c
--- a/drivers/usb/host/ohci-omap.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/usb/host/ohci-omap.c	2005-03-01 23:39:07 -08:00
@@ -157,7 +157,7 @@
 
 static void start_hnp(struct ohci_hcd *ohci)
 {
-	const unsigned	port = ohci->hcd.self.otg_port - 1;
+	const unsigned	port = ohci_to_hcd(ohci)->self.otg_port - 1;
 	unsigned long	flags;
 
 	otg_start_hnp(ohci->transceiver);
@@ -181,7 +181,7 @@
 	dev_dbg(&pdev->dev, "starting USB Controller\n");
 
 	if (config->otg) {
-		ohci->hcd.self.otg_port = config->otg;
+		ohci_to_hcd(ohci)->self.otg_port = config->otg;
 		/* default/minimum OTG power budget:  8 mA */
 		ohci->power_budget = 8;
 	}
@@ -198,7 +198,7 @@
 		ohci->transceiver = otg_get_transceiver();
 		if (ohci->transceiver) {
 			int	status = otg_set_host(ohci->transceiver,
-						&ohci->hcd.self);
+						&ohci_to_hcd(ohci)->self);
 			dev_dbg(&pdev->dev, "init %s transceiver, status %d\n",
 					ohci->transceiver->label, status);
 			if (status) {
@@ -293,7 +293,7 @@
 		return -EBUSY;
 	}
 
-	hcd = driver->hcd_alloc ();
+	hcd = usb_create_hcd (driver);
 	if (hcd == NULL){
 		dev_dbg(&pdev->dev, "hcd_alloc failed\n");
 		retval = -ENOMEM;
@@ -301,41 +301,33 @@
 	}
 	dev_set_drvdata(&pdev->dev, hcd);
 	ohci = hcd_to_ohci(hcd);
+	ohci_hcd_init(ohci);
 
-	hcd->driver = (struct hc_driver *) driver;
-	hcd->description = driver->description;
 	hcd->irq = pdev->resource[1].start;
 	hcd->regs = (void *)pdev->resource[0].start;
 	hcd->self.controller = &pdev->dev;
 
 	retval = omap_start_hc(ohci, pdev);
 	if (retval < 0)
-		goto err1;
+		goto err2;
 
 	retval = hcd_buffer_create (hcd);
 	if (retval != 0) {
 		dev_dbg(&pdev->dev, "pool alloc fail\n");
-		goto err1;
+		goto err2;
 	}
 
 	retval = request_irq (hcd->irq, usb_hcd_irq, 
-			      SA_INTERRUPT, hcd->description, hcd);
+			      SA_INTERRUPT, hcd->driver->description, hcd);
 	if (retval != 0) {
 		dev_dbg(&pdev->dev, "request_irq failed\n");
 		retval = -EBUSY;
-		goto err2;
+		goto err3;
 	}
 
 	dev_info(&pdev->dev, "at 0x%p, irq %d\n", hcd->regs, hcd->irq);
 
-	usb_bus_init (&hcd->self);
-	hcd->self.op = &usb_hcd_operations;
-	hcd->self.release = &usb_hcd_release;
-	hcd->self.hcpriv = (void *) hcd;
 	hcd->self.bus_name = pdev->dev.bus_id;
-	hcd->product_desc = "OMAP OHCI";
-
-	INIT_LIST_HEAD (&hcd->dev_list);
 	usb_register_bus (&hcd->self);
 
 	if ((retval = driver->start (hcd)) < 0) 
@@ -346,16 +338,17 @@
 
 	return 0;
 
- err2:
+ err3:
 	hcd_buffer_destroy (hcd);
+ err2:
+	dev_set_drvdata(&pdev->dev, NULL);
+	usb_put_hcd(hcd);
  err1:
-	kfree(hcd);
 	omap_stop_hc(pdev);
 
 	release_mem_region(pdev->resource[0].start, 
 			   pdev->resource[0].end - pdev->resource[0].start + 1);
 
-	dev_set_drvdata(&pdev->dev, 0);
 	return retval;
 }
 
@@ -419,7 +412,7 @@
 		writel(OHCI_CTRL_RWC, &ohci->regs->control);
 
 	if ((ret = ohci_run (ohci)) < 0) {
-		err ("can't start %s", ohci->hcd.self.bus_name);
+		err ("can't start %s", hcd->self.bus_name);
 		ohci_stop (hcd);
 		return ret;
 	}
@@ -430,6 +423,8 @@
 
 static const struct hc_driver ohci_omap_hc_driver = {
 	.description =		hcd_name,
+	.product_desc =		"OMAP OHCI",
+	.hcd_priv_size =	sizeof(struct ohci_hcd),
 
 	/*
 	 * generic hardware linkage
@@ -444,11 +439,6 @@
 	.stop =			ohci_stop,
 
 	/*
-	 * memory lifecycle (except per-request)
-	 */
-	.hcd_alloc =		ohci_hcd_alloc,
-
-	/*
 	 * managing i/o requests and associated device resources
 	 */
 	.urb_enqueue =		ohci_urb_enqueue,
@@ -513,19 +503,20 @@
 		return 0;
 
 	dev_dbg(dev, "suspend to %d\n", state);
-	down(&ohci->hcd.self.root_hub->serialize);
-	status = ohci_hub_suspend(&ohci->hcd);
+	down(&ohci_to_hcd(ohci)->self.root_hub->serialize);
+	status = ohci_hub_suspend(ohci_to_hcd(ohci));
 	if (status == 0) {
 		if (state >= 4) {
 			/* power off + reset */
 			OTG_SYSCON_2_REG &= ~UHOST_EN;
-			ohci->hcd.self.root_hub->state = USB_STATE_SUSPENDED;
+			ohci_to_hcd(ohci)->self.root_hub->state =
+					USB_STATE_SUSPENDED;
 			state = 4;
 		}
-		ohci->hcd.state = HCD_STATE_SUSPENDED;
+		ohci_to_hcd(ohci)->state = HCD_STATE_SUSPENDED;
 		dev->power.power_state = state;
 	}
-	up(&ohci->hcd.self.root_hub->serialize);
+	up(&ohci_to_hcd(ohci)->self.root_hub->serialize);
 	return status;
 }
 
@@ -547,11 +538,11 @@
 		dev_dbg(dev, "resume from %d\n", dev->power.power_state);
 #ifdef	CONFIG_USB_SUSPEND
 		/* get extra cleanup even if remote wakeup isn't in use */
-		status = usb_resume_device(ohci->hcd.self.root_hub);
+		status = usb_resume_device(ohci_to_hcd(ohci)->self.root_hub);
 #else
-		down(&ohci->hcd.self.root_hub->serialize);
-		status = ohci_hub_resume(&ohci->hcd);
-		up(&ohci->hcd.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;
diff -Nru a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c
--- a/drivers/usb/host/ohci-pci.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/usb/host/ohci-pci.c	2005-03-01 23:39:08 -08:00
@@ -35,6 +35,7 @@
 {
 	struct ohci_hcd	*ohci = hcd_to_ohci (hcd);
 
+	ohci_hcd_init (ohci);
 	return ohci_init (ohci);
 }
 
@@ -172,6 +173,8 @@
 
 static const struct hc_driver ohci_pci_hc_driver = {
 	.description =		hcd_name,
+	.product_desc =		"OHCI Host Controller",
+	.hcd_priv_size =	sizeof(struct ohci_hcd),
 
 	/*
 	 * generic hardware linkage
@@ -189,11 +192,6 @@
 	.resume =		ohci_pci_resume,
 #endif
 	.stop =			ohci_stop,
-
-	/*
-	 * memory lifecycle (except per-request)
-	 */
-	.hcd_alloc =		ohci_hcd_alloc,
 
 	/*
 	 * managing i/o requests and associated device resources
diff -Nru a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c
--- a/drivers/usb/host/ohci-pxa27x.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/usb/host/ohci-pxa27x.c	2005-03-01 23:38:57 -08:00
@@ -206,21 +206,20 @@
 		goto err1;
 	}
 
-	hcd = driver->hcd_alloc ();
-	if (hcd == NULL){
-		pr_debug ("hcd_alloc failed");
+	if(dev->resource[1].flags != IORESOURCE_IRQ){
+		pr_debug ("resource[1] is not IORESOURCE_IRQ");
 		retval = -ENOMEM;
 		goto err1;
 	}
 
-	if(dev->resource[1].flags != IORESOURCE_IRQ){
-		pr_debug ("resource[1] is not IORESOURCE_IRQ");
+	hcd = usb_create_hcd (driver);
+	if (hcd == NULL){
+		pr_debug ("hcd_alloc failed");
 		retval = -ENOMEM;
 		goto err1;
 	}
+	ohci_hcd_init(hcd_to_ohci(hcd));
 
-	hcd->driver = (struct hc_driver *) driver;
-	hcd->description = driver->description;
 	hcd->irq = dev->resource[1].start;
 	hcd->regs = addr;
 	hcd->self.controller = &dev->dev;
@@ -228,29 +227,21 @@
 	retval = hcd_buffer_create (hcd);
 	if (retval != 0) {
 		pr_debug ("pool alloc fail");
-		goto err1;
+		goto err2;
 	}
 
 	retval = request_irq (hcd->irq, usb_hcd_irq, SA_INTERRUPT,
-			      hcd->description, hcd);
+			      hcd->driver->description, hcd);
 	if (retval != 0) {
 		pr_debug("request_irq(%d) failed with retval %d\n",hcd->irq,retval);
 		retval = -EBUSY;
-		goto err2;
+		goto err3;
 	}
 
 	pr_debug ("%s (pxa27x) at 0x%p, irq %d",
-	     hcd->description, hcd->regs, hcd->irq);
+		hcd->driver->description, hcd->regs, hcd->irq);
 
-	usb_bus_init (&hcd->self);
-	hcd->self.op = &usb_hcd_operations;
-	hcd->self.release = &usb_hcd_release;
-	hcd->self.hcpriv = (void *) hcd;
 	hcd->self.bus_name = "pxa27x";
-	hcd->product_desc = "PXA27x OHCI";
-
-	INIT_LIST_HEAD (&hcd->dev_list);
-
 	usb_register_bus (&hcd->self);
 
 	if ((retval = driver->start (hcd)) < 0) {
@@ -261,10 +252,11 @@
 	*hcd_out = hcd;
 	return 0;
 
- err2:
+ err3:
 	hcd_buffer_destroy (hcd);
+ err2:
+	usb_put_hcd(hcd);
  err1:
-	kfree(hcd);
 	pxa27x_stop_hc(dev);
 	release_mem_region(dev->resource[0].start,
 				dev->resource[0].end
@@ -325,7 +317,7 @@
 		return ret;
 
 	if ((ret = ohci_run (ohci)) < 0) {
-		err ("can't start %s", ohci->hcd.self.bus_name);
+		err ("can't start %s", hcd->self.bus_name);
 		ohci_stop (hcd);
 		return ret;
 	}
@@ -337,6 +329,8 @@
 
 static const struct hc_driver ohci_pxa27x_hc_driver = {
 	.description =		hcd_name,
+	.product_desc =		"PXA27x OHCI",
+	.hcd_priv_size =	sizeof(struct ohci_hcd),
 
 	/*
 	 * generic hardware linkage
@@ -349,11 +343,6 @@
 	 */
 	.start =		ohci_pxa27x_start,
 	.stop =			ohci_stop,
-
-	/*
-	 * memory lifecycle (except per-request)
-	 */
-	.hcd_alloc =		ohci_hcd_alloc,
 
 	/*
 	 * managing i/o requests and associated device resources
diff -Nru a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c
--- a/drivers/usb/host/ohci-q.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/usb/host/ohci-q.c	2005-03-01 23:39:16 -08:00
@@ -60,10 +60,10 @@
 
 	switch (usb_pipetype (urb->pipe)) {
 	case PIPE_ISOCHRONOUS:
-		hcd_to_bus (&ohci->hcd)->bandwidth_isoc_reqs--;
+		ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs--;
 		break;
 	case PIPE_INTERRUPT:
-		hcd_to_bus (&ohci->hcd)->bandwidth_int_reqs--;
+		ohci_to_hcd(ohci)->self.bandwidth_int_reqs--;
 		break;
 	}
 
@@ -73,12 +73,12 @@
 
 	/* urb->complete() can reenter this HCD */
 	spin_unlock (&ohci->lock);
-	usb_hcd_giveback_urb (&ohci->hcd, urb, regs);
+	usb_hcd_giveback_urb (ohci_to_hcd(ohci), urb, regs);
 	spin_lock (&ohci->lock);
 
 	/* stop periodic dma if it's not needed */
-	if (hcd_to_bus (&ohci->hcd)->bandwidth_isoc_reqs == 0
-			&& hcd_to_bus (&ohci->hcd)->bandwidth_int_reqs == 0) {
+	if (ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs == 0
+			&& ohci_to_hcd(ohci)->self.bandwidth_int_reqs == 0) {
 		ohci->hc_control &= ~(OHCI_CTRL_PLE|OHCI_CTRL_IE);
 		ohci_writel (ohci, ohci->hc_control, &ohci->regs->control);
 	}
@@ -163,7 +163,7 @@
 		}
 		ohci->load [i] += ed->load;
 	}
-	hcd_to_bus (&ohci->hcd)->bandwidth_allocated += ed->load / ed->interval;
+	ohci_to_hcd(ohci)->self.bandwidth_allocated += ed->load / ed->interval;
 }
 
 /* link an ed into one of the HC chains */
@@ -172,7 +172,7 @@
 {	 
 	int	branch;
 
-	if (ohci->hcd.state == USB_STATE_QUIESCING)
+	if (ohci_to_hcd(ohci)->state == USB_STATE_QUIESCING)
 		return -EAGAIN;
 
 	ed->state = ED_OPER;
@@ -276,7 +276,7 @@
 		}
 		ohci->load [i] -= ed->load;
 	}	
-	hcd_to_bus (&ohci->hcd)->bandwidth_allocated -= ed->load / ed->interval;
+	ohci_to_hcd(ohci)->self.bandwidth_allocated -= ed->load / ed->interval;
 
 	ohci_vdbg (ohci, "unlink %sed %p branch %d [%dus.], interval %d\n",
 		(ed->hwINFO & cpu_to_hc32 (ohci, ED_ISO)) ? "iso " : "",
@@ -386,37 +386,30 @@
 /*-------------------------------------------------------------------------*/
 
 /* get and maybe (re)init an endpoint. init _should_ be done only as part
- * of usb_set_configuration() or usb_set_interface() ... but the USB stack
- * isn't very stateful, so we re-init whenever the HC isn't looking.
+ * of enumeration, usb_set_configuration() or usb_set_interface().
  */
 static struct ed *ed_get (
 	struct ohci_hcd		*ohci,
+	struct usb_host_endpoint *ep,
 	struct usb_device	*udev,
 	unsigned int		pipe,
 	int			interval
 ) {
-	int			is_out = !usb_pipein (pipe);
-	int			type = usb_pipetype (pipe);
-	struct hcd_dev		*dev = (struct hcd_dev *) udev->hcpriv;
 	struct ed		*ed; 
-	unsigned		ep;
 	unsigned long		flags;
 
-	ep = usb_pipeendpoint (pipe) << 1;
-	if (type != PIPE_CONTROL && is_out)
-		ep |= 1;
-
 	spin_lock_irqsave (&ohci->lock, flags);
 
-	if (!(ed = dev->ep [ep])) {
+	if (!(ed = ep->hcpriv)) {
 		struct td	*td;
+		int		is_out;
+		u32		info;
 
 		ed = ed_alloc (ohci, GFP_ATOMIC);
 		if (!ed) {
 			/* out of memory */
 			goto done;
 		}
-		dev->ep [ep] = ed;
 
   		/* dummy td; end of td list for ed */
 		td = td_alloc (ohci, GFP_ATOMIC);
@@ -430,38 +423,39 @@
 		ed->hwTailP = cpu_to_hc32 (ohci, td->td_dma);
 		ed->hwHeadP = ed->hwTailP;	/* ED_C, ED_H zeroed */
 		ed->state = ED_IDLE;
-		ed->type = type;
-	}
 
-	/* NOTE: only ep0 currently needs this "re"init logic, during
-	 * enumeration (after set_address).
-	 */
-  	if (ed->state == ED_IDLE) {
-		u32	info;
+		is_out = !(ep->desc.bEndpointAddress & USB_DIR_IN);
 
+		/* FIXME usbcore changes dev->devnum before SET_ADDRESS
+		 * suceeds ... otherwise we wouldn't need "pipe".
+		 */
 		info = usb_pipedevice (pipe);
-		info |= (ep >> 1) << 7;
-		info |= usb_maxpacket (udev, pipe, is_out) << 16;
+		ed->type = usb_pipetype(pipe);
+
+		info |= (ep->desc.bEndpointAddress & ~USB_DIR_IN) << 7;
+		info |= le16_to_cpu(ep->desc.wMaxPacketSize) << 16;
 		if (udev->speed == USB_SPEED_LOW)
 			info |= ED_LOWSPEED;
 		/* only control transfers store pids in tds */
-		if (type != PIPE_CONTROL) {
+		if (ed->type != PIPE_CONTROL) {
 			info |= is_out ? ED_OUT : ED_IN;
-			if (type != PIPE_BULK) {
+			if (ed->type != PIPE_BULK) {
 				/* periodic transfers... */
-				if (type == PIPE_ISOCHRONOUS)
+				if (ed->type == PIPE_ISOCHRONOUS)
 					info |= ED_ISO;
 				else if (interval > 32)	/* iso can be bigger */
 					interval = 32;
 				ed->interval = interval;
 				ed->load = usb_calc_bus_time (
 					udev->speed, !is_out,
-					type == PIPE_ISOCHRONOUS,
-					usb_maxpacket (udev, pipe, is_out))
+					ed->type == PIPE_ISOCHRONOUS,
+					le16_to_cpu(ep->desc.wMaxPacketSize))
 						/ 1000;
 			}
 		}
 		ed->hwINFO = cpu_to_hc32(ohci, info);
+
+		ep->hcpriv = ed;
 	}
 
 done:
@@ -625,8 +619,8 @@
 	 */
 	case PIPE_INTERRUPT:
 		/* ... and periodic urbs have extra accounting */
-		periodic = hcd_to_bus (&ohci->hcd)->bandwidth_int_reqs++ == 0
-			&& hcd_to_bus (&ohci->hcd)->bandwidth_isoc_reqs == 0;
+		periodic = ohci_to_hcd(ohci)->self.bandwidth_int_reqs++ == 0
+			&& ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs == 0;
 		/* FALLTHROUGH */
 	case PIPE_BULK:
 		info = is_out
@@ -694,8 +688,8 @@
 				data + urb->iso_frame_desc [cnt].offset,
 				urb->iso_frame_desc [cnt].length, urb, cnt);
 		}
-		periodic = hcd_to_bus (&ohci->hcd)->bandwidth_isoc_reqs++ == 0
-			&& hcd_to_bus (&ohci->hcd)->bandwidth_int_reqs == 0;
+		periodic = ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs++ == 0
+			&& ohci_to_hcd(ohci)->self.bandwidth_int_reqs == 0;
 		break;
 	}
 
@@ -926,7 +920,7 @@
 		/* only take off EDs that the HC isn't using, accounting for
 		 * frame counter wraps and EDs with partially retired TDs
 		 */
-		if (likely (regs && HCD_IS_RUNNING(ohci->hcd.state))) {
+		if (likely (regs && HCD_IS_RUNNING(ohci_to_hcd(ohci)->state))) {
 			if (tick_before (tick, ed->tick)) {
 skip_ed:
 				last = &ed->ed_next;
@@ -1008,7 +1002,7 @@
 
 		/* but if there's work queued, reschedule */
 		if (!list_empty (&ed->td_list)) {
-			if (HCD_IS_RUNNING(ohci->hcd.state))
+			if (HCD_IS_RUNNING(ohci_to_hcd(ohci)->state))
 				ed_schedule (ohci, ed);
 		}
 
@@ -1017,8 +1011,8 @@
    	}
 
 	/* maybe reenable control and bulk lists */ 
-	if (HCD_IS_RUNNING(ohci->hcd.state)
-			&& ohci->hcd.state != USB_STATE_QUIESCING
+	if (HCD_IS_RUNNING(ohci_to_hcd(ohci)->state)
+			&& ohci_to_hcd(ohci)->state != USB_STATE_QUIESCING
 			&& !ohci->ed_rm_list) {
 		u32	command = 0, control = 0;
 
diff -Nru a/drivers/usb/host/ohci-sa1111.c b/drivers/usb/host/ohci-sa1111.c
--- a/drivers/usb/host/ohci-sa1111.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/usb/host/ohci-sa1111.c	2005-03-01 23:38:57 -08:00
@@ -162,15 +162,14 @@
 
 	sa1111_start_hc(dev);
 
-	hcd = driver->hcd_alloc ();
+	hcd = usb_create_hcd (driver);
 	if (hcd == NULL){
 		dbg ("hcd_alloc failed");
 		retval = -ENOMEM;
 		goto err1;
 	}
+	ohci_hcd_init(hcd_to_ohci(hcd));
 
-	hcd->driver = (struct hc_driver *) driver;
-	hcd->description = driver->description;
 	hcd->irq = dev->irq[1];
 	hcd->regs = dev->mapbase;
 	hcd->self.controller = &dev->dev;
@@ -178,29 +177,21 @@
 	retval = hcd_buffer_create (hcd);
 	if (retval != 0) {
 		dbg ("pool alloc fail");
-		goto err1;
+		goto err2;
 	}
 
 	retval = request_irq (hcd->irq, usb_hcd_sa1111_hcim_irq, SA_INTERRUPT,
-			      hcd->description, hcd);
+			      hcd->driver->description, hcd);
 	if (retval != 0) {
 		dbg("request_irq failed");
 		retval = -EBUSY;
-		goto err2;
+		goto err3;
 	}
 
 	info ("%s (SA-1111) at 0x%p, irq %d\n",
-	      hcd->description, hcd->regs, hcd->irq);
+		hcd->driver->description, hcd->regs, hcd->irq);
 
-	usb_bus_init (&hcd->self);
-	hcd->self.op = &usb_hcd_operations;
-	hcd->self.release = &usb_hcd_release;
-	hcd->self.hcpriv = (void *) hcd;
 	hcd->self.bus_name = "sa1111";
-	hcd->product_desc = "SA-1111 OHCI";
-
-	INIT_LIST_HEAD (&hcd->dev_list);
-
 	usb_register_bus (&hcd->self);
 
 	if ((retval = driver->start (hcd)) < 0) 
@@ -212,10 +203,11 @@
 	*hcd_out = hcd;
 	return 0;
 
- err2:
+ err3:
 	hcd_buffer_destroy (hcd);
+ err2:
+	usb_put_hcd(hcd);
  err1:
-	kfree(hcd);
 	sa1111_stop_hc(dev);
 	release_mem_region(dev->res.start, dev->res.end - dev->res.start + 1);
 	return retval;
@@ -271,7 +263,7 @@
 		return ret;
 
 	if ((ret = ohci_run (ohci)) < 0) {
-		err ("can't start %s", ohci->hcd.self.bus_name);
+		err ("can't start %s", hcd->self.bus_name);
 		ohci_stop (hcd);
 		return ret;
 	}
@@ -282,6 +274,8 @@
 
 static const struct hc_driver ohci_sa1111_hc_driver = {
 	.description =		hcd_name,
+	.product_desc =		"SA-1111 OHCI",
+	.hcd_priv_size =	sizeof(struct ohci_hcd),
 
 	/*
 	 * generic hardware linkage
diff -Nru a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h
--- a/drivers/usb/host/ohci.h	2005-03-01 23:39:17 -08:00
+++ b/drivers/usb/host/ohci.h	2005-03-01 23:39:17 -08:00
@@ -345,11 +345,6 @@
  */
 
 struct ohci_hcd {
-	/*
-	 * framework state
-	 */
-	struct usb_hcd		hcd;		/* must come first! */
-
 	spinlock_t		lock;
 
 	/*
@@ -405,7 +400,15 @@
 
 };
 
-#define hcd_to_ohci(hcd_ptr) container_of(hcd_ptr, struct ohci_hcd, hcd)
+/* convert between an hcd pointer and the corresponding ohci_hcd */
+static inline struct ohci_hcd *hcd_to_ohci (struct usb_hcd *hcd)
+{
+	return (struct ohci_hcd *) (hcd->hcd_priv);
+}
+static inline struct usb_hcd *ohci_to_hcd (const struct ohci_hcd *ohci)
+{
+	return container_of ((void *) ohci, struct usb_hcd, hcd_priv);
+}
 
 /*-------------------------------------------------------------------------*/
 
@@ -414,13 +417,13 @@
 #endif	/* DEBUG */
 
 #define ohci_dbg(ohci, fmt, args...) \
-	dev_dbg ((ohci)->hcd.self.controller , fmt , ## args )
+	dev_dbg (ohci_to_hcd(ohci)->self.controller , fmt , ## args )
 #define ohci_err(ohci, fmt, args...) \
-	dev_err ((ohci)->hcd.self.controller , fmt , ## args )
+	dev_err (ohci_to_hcd(ohci)->self.controller , fmt , ## args )
 #define ohci_info(ohci, fmt, args...) \
-	dev_info ((ohci)->hcd.self.controller , fmt , ## args )
+	dev_info (ohci_to_hcd(ohci)->self.controller , fmt , ## args )
 #define ohci_warn(ohci, fmt, args...) \
-	dev_warn ((ohci)->hcd.self.controller , fmt , ## args )
+	dev_warn (ohci_to_hcd(ohci)->self.controller , fmt , ## args )
 
 #ifdef OHCI_VERBOSE_DEBUG
 #	define ohci_vdbg ohci_dbg
@@ -553,7 +556,7 @@
 
 static inline void disable (struct ohci_hcd *ohci)
 {
-	ohci->hcd.state = USB_STATE_HALT;
+	ohci_to_hcd(ohci)->state = USB_STATE_HALT;
 }
 
 #define	FI			0x2edf		/* 12000 bits per frame (-1) */
diff -Nru a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c
--- a/drivers/usb/host/sl811-hcd.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/usb/host/sl811-hcd.c	2005-03-01 23:38:55 -08:00
@@ -67,7 +67,7 @@
 MODULE_DESCRIPTION("SL811HS USB Host Controller Driver");
 MODULE_LICENSE("GPL");
 
-#define DRIVER_VERSION	"06 Dec 2004"
+#define DRIVER_VERSION	"15 Dec 2004"
 
 
 #ifndef DEBUG
@@ -90,10 +90,12 @@
 
 /*-------------------------------------------------------------------------*/
 
-static irqreturn_t sl811h_irq(int irq, void *_sl811, struct pt_regs *regs);
+static irqreturn_t sl811h_irq(int irq, void *_hcd, struct pt_regs *regs);
 
 static void port_power(struct sl811 *sl811, int is_on)
 {
+	struct usb_hcd	*hcd = sl811_to_hcd(sl811);
+
 	/* hub is inactive unless the port is powered */
 	if (is_on) {
 		if (sl811->port1 & (1 << USB_PORT_FEAT_POWER))
@@ -101,12 +103,12 @@
 
 		sl811->port1 = (1 << USB_PORT_FEAT_POWER);
 		sl811->irq_enable = SL11H_INTMASK_INSRMV;
-		sl811->hcd.self.controller->power.power_state = PM_SUSPEND_ON;
+		hcd->self.controller->power.power_state = PM_SUSPEND_ON;
 	} else {
 		sl811->port1 = 0;
 		sl811->irq_enable = 0;
-		sl811->hcd.state = USB_STATE_HALT;
-		sl811->hcd.self.controller->power.power_state = PM_SUSPEND_DISK;
+		hcd->state = USB_STATE_HALT;
+		hcd->self.controller->power.power_state = PM_SUSPEND_DISK;
 	}
 	sl811->ctrl1 = 0;
 	sl811_write(sl811, SL11H_IRQ_ENABLE, 0);
@@ -115,12 +117,12 @@
 	if (sl811->board && sl811->board->port_power) {
 		/* switch VBUS, at 500mA unless hub power budget gets set */
 		DBG("power %s\n", is_on ? "on" : "off");
-		sl811->board->port_power(sl811->hcd.self.controller, is_on);
+		sl811->board->port_power(hcd->self.controller, is_on);
 	}
 
 	/* reset as thoroughly as we can */
 	if (sl811->board && sl811->board->reset)
-		sl811->board->reset(sl811->hcd.self.controller);
+		sl811->board->reset(hcd->self.controller);
 
 	sl811_write(sl811, SL11H_IRQ_ENABLE, 0);
 	sl811_write(sl811, SL11H_CTLREG1, sl811->ctrl1);
@@ -314,7 +316,6 @@
 static struct sl811h_ep	*start(struct sl811 *sl811, u8 bank)
 {
 	struct sl811h_ep	*ep;
-	struct sl811h_req	*req;
 	struct urb		*urb;
 	int			fclock;
 	u8			control;
@@ -348,13 +349,12 @@
 					struct sl811h_ep, schedule);
 	}
 
-	if (unlikely(list_empty(&ep->queue))) {
+	if (unlikely(list_empty(&ep->hep->urb_list))) {
 		DBG("empty %p queue?\n", ep);
 		return NULL;
 	}
 
-	req = container_of(ep->queue.next, struct sl811h_req, queue);
-	urb = req->urb;
+	urb = container_of(ep->hep->urb_list.next, struct urb, urb_list);
 	control = ep->defctrl;
 
 	/* if this frame doesn't have enough time left to transfer this
@@ -432,17 +432,12 @@
 static void finish_request(
 	struct sl811		*sl811,
 	struct sl811h_ep	*ep,
-	struct sl811h_req	*req,
+	struct urb		*urb,
 	struct pt_regs		*regs,
 	int			status
 ) __releases(sl811->lock) __acquires(sl811->lock)
 {
 	unsigned		i;
-	struct urb		*urb = req->urb;
-
-	list_del(&req->queue);
-	kfree(req);
-	urb->hcpriv = NULL;
 
 	if (usb_pipecontrol(urb->pipe))
 		ep->nextpid = USB_PID_SETUP;
@@ -453,11 +448,11 @@
 	spin_unlock(&urb->lock);
 
 	spin_unlock(&sl811->lock);
-	usb_hcd_giveback_urb(&sl811->hcd, urb, regs);
+	usb_hcd_giveback_urb(sl811_to_hcd(sl811), urb, regs);
 	spin_lock(&sl811->lock);
 
 	/* leave active endpoints in the schedule */
-	if (!list_empty(&ep->queue))
+	if (!list_empty(&ep->hep->urb_list))
 		return;
 
 	/* async deschedule? */
@@ -482,7 +477,7 @@
 	}	
 	ep->branch = PERIODIC_SIZE;
 	sl811->periodic_count--;
-	hcd_to_bus(&sl811->hcd)->bandwidth_allocated
+	sl811_to_hcd(sl811)->self.bandwidth_allocated
 		-= ep->load / ep->period;
 	if (ep == sl811->next_periodic)
 		sl811->next_periodic = ep->next;
@@ -496,7 +491,6 @@
 done(struct sl811 *sl811, struct sl811h_ep *ep, u8 bank, struct pt_regs *regs)
 {
 	u8			status;
-	struct sl811h_req	*req;
 	struct urb		*urb;
 	int			urbstat = -EINPROGRESS;
 
@@ -505,8 +499,7 @@
 
 	status = sl811_read(sl811, bank + SL11H_PKTSTATREG);
 
-	req = container_of(ep->queue.next, struct sl811h_req, queue);
-	urb = req->urb;
+	urb = container_of(ep->hep->urb_list.next, struct urb, urb_list);
 
 	/* we can safely ignore NAKs */
 	if (status & SL11H_STATMASK_NAK) {
@@ -577,7 +570,7 @@
 					urb->status = urbstat;
 				spin_unlock(&urb->lock);
 
-				req = NULL;
+				urb = NULL;
 				ep->nextpid = USB_PID_ACK;
 			}
 			break;
@@ -618,9 +611,8 @@
 				bank, status, ep, urbstat);
 	}
 
-	if ((urbstat != -EINPROGRESS || urb->status != -EINPROGRESS)
-			&& req)
-		finish_request(sl811, ep, req, regs, urbstat);
+	if (urb && (urbstat != -EINPROGRESS || urb->status != -EINPROGRESS))
+		finish_request(sl811, ep, urb, regs, urbstat);
 }
 
 static inline u8 checkdone(struct sl811 *sl811)
@@ -643,7 +635,7 @@
 		ctl = sl811_read(sl811, SL811_EP_B(SL11H_HOSTCTLREG));
 		if (ctl & SL11H_HCTLMASK_ARM)
 			sl811_write(sl811, SL811_EP_B(SL11H_HOSTCTLREG), 0);
-		DBG("%s DONE_B: ctrl %02x sts %02x\n", ctl,
+		DBG("%s DONE_B: ctrl %02x sts %02x\n",
 			(ctl & SL11H_HCTLMASK_ARM) ? "timeout" : "lost",
 			ctl,
 			sl811_read(sl811, SL811_EP_B(SL11H_PKTSTATREG)));
@@ -653,9 +645,10 @@
 	return irqstat;
 }
 
-static irqreturn_t sl811h_irq(int irq, void *_sl811, struct pt_regs *regs)
+static irqreturn_t sl811h_irq(int irq, void *_hcd, struct pt_regs *regs)
 {
-	struct sl811	*sl811 = _sl811;
+	struct usb_hcd	*hcd = _hcd;
+	struct sl811	*sl811 = hcd_to_sl811(hcd);
 	u8		irqstat;
 	irqreturn_t	ret = IRQ_NONE;
 	unsigned	retries = 5;
@@ -732,8 +725,8 @@
 		if (sl811->active_a) {
 			sl811_write(sl811, SL811_EP_A(SL11H_HOSTCTLREG), 0);
 			finish_request(sl811, sl811->active_a,
-				container_of(sl811->active_a->queue.next,
-					struct sl811h_req, queue),
+				container_of(sl811->active_a->hep->urb_list.next,
+					struct urb, urb_list),
 				NULL, -ESHUTDOWN);
 			sl811->active_a = NULL;
 		}
@@ -741,8 +734,8 @@
 		if (sl811->active_b) {
 			sl811_write(sl811, SL811_EP_B(SL11H_HOSTCTLREG), 0);
 			finish_request(sl811, sl811->active_b,
-				container_of(sl811->active_b->queue.next,
-					struct sl811h_req, queue),
+				container_of(sl811->active_b->hep->urb_list.next,
+					struct urb, urb_list),
 				NULL, -ESHUTDOWN);
 			sl811->active_b = NULL;
 		}
@@ -767,7 +760,7 @@
 		if (sl811->port1 & (1 << USB_PORT_FEAT_ENABLE))
 			start_transfer(sl811);
 		ret = IRQ_HANDLED;
-		sl811->hcd.saw_irq = 1;
+		hcd->saw_irq = 1;
 		if (retries--)
 			goto retry;
 	}
@@ -816,19 +809,18 @@
 /*-------------------------------------------------------------------------*/
 
 static int sl811h_urb_enqueue(
-	struct usb_hcd	*hcd,
-	struct urb	*urb,
-	int		mem_flags
+	struct usb_hcd		*hcd,
+	struct usb_host_endpoint *hep,
+	struct urb		*urb,
+	int			mem_flags
 ) {
 	struct sl811		*sl811 = hcd_to_sl811(hcd);
 	struct usb_device	*udev = urb->dev;
-	struct hcd_dev		*hdev = (struct hcd_dev *) udev->hcpriv;
 	unsigned int		pipe = urb->pipe;
 	int			is_out = !usb_pipein(pipe);
 	int			type = usb_pipetype(pipe);
 	int			epnum = usb_pipeendpoint(pipe);
 	struct sl811h_ep	*ep = NULL;
-	struct sl811h_req	*req;
 	unsigned long		flags;
 	int			i;
 	int			retval = 0;
@@ -838,36 +830,27 @@
 		return -ENOSPC;
 #endif
 
-	/* avoid all allocations within spinlocks: request or endpoint */
-	urb->hcpriv = req = kmalloc(sizeof *req, mem_flags);
-	if (!req)
-		return -ENOMEM;
-	req->urb = urb;
-
-	i = epnum << 1;
-	if (i && is_out)
-		i |= 1;
-	if (!hdev->ep[i])
+	/* avoid all allocations within spinlocks */
+	if (!hep->hcpriv)
 		ep = kcalloc(1, sizeof *ep, mem_flags);
 
 	spin_lock_irqsave(&sl811->lock, flags);
 
 	/* don't submit to a dead or disabled port */
 	if (!(sl811->port1 & (1 << USB_PORT_FEAT_ENABLE))
-			|| !HCD_IS_RUNNING(sl811->hcd.state)) {
+			|| !HCD_IS_RUNNING(hcd->state)) {
 		retval = -ENODEV;
 		goto fail;
 	}
 
-	if (hdev->ep[i]) {
+	if (hep->hcpriv) {
 		kfree(ep);
-		ep = hdev->ep[i];
+		ep = hep->hcpriv;
 	} else if (!ep) {
 		retval = -ENOMEM;
 		goto fail;
 
 	} else {
-		INIT_LIST_HEAD(&ep->queue);
 		INIT_LIST_HEAD(&ep->schedule);
 		ep->udev = usb_get_dev(udev);
 		ep->epnum = epnum;
@@ -911,7 +894,7 @@
 			break;
 		}
 
-		hdev->ep[i] = ep;
+		hep->hcpriv = ep;
 	}
 
 	/* maybe put endpoint into schedule */
@@ -957,8 +940,7 @@
 			sl811->load[i] += ep->load;
 		}
 		sl811->periodic_count++;
-		hcd_to_bus(&sl811->hcd)->bandwidth_allocated
-				+= ep->load / ep->period;
+		hcd->self.bandwidth_allocated += ep->load / ep->period;
 		sofirq_on(sl811);
 	}
 
@@ -966,47 +948,38 @@
 	spin_lock(&urb->lock);
 	if (urb->status != -EINPROGRESS) {
 		spin_unlock(&urb->lock);
-		finish_request(sl811, ep, req, NULL, 0);
-		req = NULL;
+		finish_request(sl811, ep, urb, NULL, 0);
 		retval = 0;
 		goto fail;
 	}
-	list_add_tail(&req->queue, &ep->queue);
+	urb->hcpriv = hep;
 	spin_unlock(&urb->lock);
 
 	start_transfer(sl811);
 	sl811_write(sl811, SL11H_IRQ_ENABLE, sl811->irq_enable);
 fail:
 	spin_unlock_irqrestore(&sl811->lock, flags);
-	if (retval)
-		kfree(req);
 	return retval;
 }
 
 static int sl811h_urb_dequeue(struct usb_hcd *hcd, struct urb *urb)
 {
 	struct sl811		*sl811 = hcd_to_sl811(hcd);
-	struct usb_device	*udev = urb->dev;
-	struct hcd_dev		*hdev = (struct hcd_dev *) udev->hcpriv;
-	unsigned int		pipe = urb->pipe;
-	int			is_out = !usb_pipein(pipe);
+	struct usb_host_endpoint *hep = urb->hcpriv;
 	unsigned long		flags;
-	unsigned		i;
 	struct sl811h_ep	*ep;
-	struct sl811h_req	*req = urb->hcpriv;
 	int			retval = 0;
 
-	i = usb_pipeendpoint(pipe) << 1;
-	if (i && is_out)
-		i |= 1;
+	if (!hep)
+		return -EINVAL;
 
 	spin_lock_irqsave(&sl811->lock, flags);
-	ep = hdev->ep[i];
+	ep = hep->hcpriv;
 	if (ep) {
 		/* finish right away if this urb can't be active ...
 		 * note that some drivers wrongly expect delays
 		 */
-		if (ep->queue.next != &req->queue) {
+		if (ep->hep->urb_list.next != &urb->urb_list) {
 			/* not front of queue?  never active */
 
 		/* for active transfers, we expect an IRQ */
@@ -1022,7 +995,7 @@
 						0);
 				sl811->active_a = NULL;
 			} else
-				req = NULL;
+				urb = NULL;
 #ifdef	USE_B
 		} else if (sl811->active_b == ep) {
 			if (time_before_eq(sl811->jiffies_a, jiffies)) {
@@ -1036,14 +1009,14 @@
 						0);
 				sl811->active_b = NULL;
 			} else
-				req = NULL;
+				urb = NULL;
 #endif
 		} else {
 			/* front of queue for inactive endpoint */
 		}
 
-		if (req)
-			finish_request(sl811, ep, req, NULL, 0);
+		if (urb)
+			finish_request(sl811, ep, urb, NULL, 0);
 		else
 			VDBG("dequeue, urb %p active %s; wait4irq\n", urb,
 				(sl811->active_a == ep) ? "A" : "B");
@@ -1054,33 +1027,22 @@
 }
 
 static void
-sl811h_endpoint_disable(struct usb_hcd *hcd, struct hcd_dev *hdev, int epnum)
+sl811h_endpoint_disable(struct usb_hcd *hcd, struct usb_host_endpoint *hep)
 {
-	struct sl811		*sl811 = hcd_to_sl811(hcd);
-	struct sl811h_ep	*ep;
-	unsigned long		flags;
-	int			i;
-
-	i = (epnum & 0xf) << 1;
-	if (epnum && !(epnum & USB_DIR_IN))
-		i |= 1;
-
-	spin_lock_irqsave(&sl811->lock, flags);
-	ep = hdev->ep[i];
-	hdev->ep[i] = NULL;
-	spin_unlock_irqrestore(&sl811->lock, flags);
+	struct sl811h_ep	*ep = hep->hcpriv;
 
-	if (ep) {
-		/* assume we'd just wait for the irq */
-		if (!list_empty(&ep->queue))
-			msleep(3);
-		if (!list_empty(&ep->queue))
-			WARN("ep %p not empty?\n", ep);
+	if (!ep)
+		return;
 
-		usb_put_dev(ep->udev);
-		kfree(ep);
-	}
-	return;
+	/* assume we'd just wait for the irq */
+	if (!list_empty(&hep->urb_list))
+		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
@@ -1436,7 +1398,7 @@
 	unsigned		i;
 
 	seq_printf(s, "%s\n%s version %s\nportstatus[1] = %08x\n",
-		sl811->hcd.product_desc,
+		sl811_to_hcd(sl811)->product_desc,
 		hcd_name, DRIVER_VERSION,
 		sl811->port1);
 
@@ -1481,7 +1443,7 @@
 		sl811_read(sl811, SL811_EP_B(SL11H_PKTSTATREG)));
 	seq_printf(s, "\n");
 	list_for_each_entry (ep, &sl811->async, schedule) {
-		struct sl811h_req	*req;
+		struct urb		*urb;
 
 		seq_printf(s, "%s%sqh%p, ep%d%s, maxpacket %d"
 					" nak %d err %d\n",
@@ -1497,10 +1459,10 @@
 			}; s;}),
 			ep->maxpacket,
 			ep->nak_count, ep->error_count);
-		list_for_each_entry (req, &ep->queue, queue) {
-			seq_printf(s, "  urb%p, %d/%d\n", req->urb,
-				req->urb->actual_length,
-				req->urb->transfer_buffer_length);
+		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(&sl811->async))
@@ -1584,7 +1546,7 @@
 	struct sl811	*sl811 = hcd_to_sl811(hcd);
 	unsigned long	flags;
 
-	del_timer_sync(&sl811->hcd.rh_timer);
+	del_timer_sync(&hcd->rh_timer);
 
 	spin_lock_irqsave(&sl811->lock, flags);
 	port_power(sl811, 0);
@@ -1599,7 +1561,7 @@
 
 	/* chip has been reset, VBUS power is off */
 
-	udev = usb_alloc_dev(NULL, &sl811->hcd.self, 0);
+	udev = usb_alloc_dev(NULL, &hcd->self, 0);
 	if (!udev)
 		return -ENOMEM;
 
@@ -1607,9 +1569,9 @@
 	hcd->state = USB_STATE_RUNNING;
 
 	if (sl811->board)
-		sl811->hcd.can_wakeup = sl811->board->can_wakeup;
+		hcd->can_wakeup = sl811->board->can_wakeup;
 
-	if (hcd_register_root(udev, &sl811->hcd) != 0) {
+	if (hcd_register_root(udev, hcd) != 0) {
 		usb_put_dev(udev);
 		sl811h_stop(hcd);
 		return -ENODEV;
@@ -1625,6 +1587,7 @@
 
 static struct hc_driver sl811h_hc_driver = {
 	.description =		hcd_name,
+	.hcd_priv_size =	sizeof(struct sl811),
 
 	/*
 	 * generic hardware linkage
@@ -1658,35 +1621,32 @@
 sl811h_remove(struct device *dev)
 {
 	struct sl811		*sl811 = dev_get_drvdata(dev);
+	struct usb_hcd		*hcd = sl811_to_hcd(sl811);
 	struct platform_device	*pdev;
 	struct resource		*res;
 
 	pdev = container_of(dev, struct platform_device, dev);
 
-	if (HCD_IS_RUNNING(sl811->hcd.state))
-		sl811->hcd.state = USB_STATE_QUIESCING;
+	if (HCD_IS_RUNNING(hcd->state))
+		hcd->state = USB_STATE_QUIESCING;
 
-	usb_disconnect(&sl811->hcd.self.root_hub);
+	usb_disconnect(&hcd->self.root_hub);
 	remove_debug_file(sl811);
-	sl811h_stop(&sl811->hcd);
+	sl811h_stop(hcd);
 
-	if (!list_empty(&sl811->hcd.self.bus_list))
-		usb_deregister_bus(&sl811->hcd.self);
+	usb_deregister_bus(&hcd->self);
 
-	if (sl811->hcd.irq >= 0)
-		free_irq(sl811->hcd.irq, sl811);
+	free_irq(hcd->irq, hcd);
 
-	if (sl811->data_reg)
-		iounmap(sl811->data_reg);
+	iounmap(sl811->data_reg);
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
 	release_mem_region(res->start, 1);
 
-	if (sl811->addr_reg) 
-		iounmap(sl811->addr_reg);
+	iounmap(sl811->addr_reg);
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	release_mem_region(res->start, 1);
 
-	kfree(sl811);
+	usb_put_hcd(hcd);
 	return 0;
 }
 
@@ -1695,13 +1655,15 @@
 static int __init
 sl811h_probe(struct device *dev)
 {
+	struct usb_hcd		*hcd;
 	struct sl811		*sl811;
 	struct platform_device	*pdev;
 	struct resource		*addr, *data;
 	int			irq;
-	int			status;
+	void __iomem		*addr_reg;
+	void __iomem		*data_reg;
+	int			retval;
 	u8			tmp;
-	unsigned long		flags;
 
 	/* basic sanity checks first.  board-specific init logic should
 	 * have initialized these three resources and probably board
@@ -1724,37 +1686,39 @@
 		return -EINVAL;
 	}
 
-	if (!request_mem_region(addr->start, 1, hcd_name))
-		return -EBUSY;
+	if (!request_mem_region(addr->start, 1, hcd_name)) {
+		retval = -EBUSY;
+		goto err1;
+	}
+	addr_reg = ioremap(addr->start, resource_len(addr));
+	if (addr_reg == NULL) {
+		retval = -ENOMEM;
+		goto err2;
+	}
+
 	if (!request_mem_region(data->start, 1, hcd_name)) {
-		release_mem_region(addr->start, 1);
-		return -EBUSY;
+		retval = -EBUSY;
+		goto err3;
+	}
+	data_reg = ioremap(data->start, resource_len(addr));
+	if (data_reg == NULL) {
+		retval = -ENOMEM;
+		goto err4;
 	}
 
 	/* allocate and initialize hcd */
-	sl811 = kcalloc(1, sizeof *sl811, GFP_KERNEL);
-	if (!sl811)
-		return 0;
+	hcd = usb_create_hcd(&sl811h_hc_driver);
+	if (!hcd) {
+		retval = 0;
+		goto err5;
+	}
+	sl811 = hcd_to_sl811(hcd);
 	dev_set_drvdata(dev, sl811);
 
-	usb_bus_init(&sl811->hcd.self);
-	sl811->hcd.self.controller = dev;
-	sl811->hcd.self.bus_name = dev->bus_id;
-	sl811->hcd.self.op = &usb_hcd_operations;
-	sl811->hcd.self.hcpriv = sl811;
-
-	// NOTE: 2.6.11 starts to change the hcd glue layer some more,
-	// eventually letting us eliminate struct sl811h_req and a
-	// lot of the boilerplate code here 
-
-	INIT_LIST_HEAD(&sl811->hcd.dev_list);
-	sl811->hcd.self.release = &usb_hcd_release;
-
-	sl811->hcd.description = sl811h_hc_driver.description;
-	init_timer(&sl811->hcd.rh_timer);
-	sl811->hcd.driver = &sl811h_hc_driver;
-	sl811->hcd.irq = -1;
-	sl811->hcd.state = USB_STATE_HALT;
+	hcd->self.controller = dev;
+	hcd->self.bus_name = dev->bus_id;
+	hcd->irq = irq;
+	hcd->regs = addr_reg;
 
 	spin_lock_init(&sl811->lock);
 	INIT_LIST_HEAD(&sl811->async);
@@ -1762,36 +1726,27 @@
 	init_timer(&sl811->timer);
 	sl811->timer.function = sl811h_timer;
 	sl811->timer.data = (unsigned long) sl811;
+	sl811->addr_reg = addr_reg;
+	sl811->data_reg = data_reg;
 
-	sl811->addr_reg = ioremap(addr->start, resource_len(addr));
-	if (sl811->addr_reg == NULL) {
-		status = -ENOMEM;
-		goto fail;
-	}
-	sl811->data_reg = ioremap(data->start, resource_len(addr));
-	if (sl811->data_reg == NULL) {
-		status = -ENOMEM;
-		goto fail;
-	}
-
-	spin_lock_irqsave(&sl811->lock, flags);
+	spin_lock_irq(&sl811->lock);
 	port_power(sl811, 0);
-	spin_unlock_irqrestore(&sl811->lock, flags);
+	spin_unlock_irq(&sl811->lock);
 	msleep(200);
 
 	tmp = sl811_read(sl811, SL11H_HWREVREG);
 	switch (tmp >> 4) {
 	case 1:
-		sl811->hcd.product_desc = "SL811HS v1.2";
+		hcd->product_desc = "SL811HS v1.2";
 		break;
 	case 2:
-		sl811->hcd.product_desc = "SL811HS v1.5";
+		hcd->product_desc = "SL811HS v1.5";
 		break;
 	default:
 		/* reject case 0, SL11S is less functional */
 		DBG("chiprev %02x\n", tmp);
-		status = -ENXIO;
-		goto fail;
+		retval = -ENXIO;
+		goto err6;
 	}
 
 	/* sl811s would need a different handler for this irq */
@@ -1799,25 +1754,41 @@
 	/* Cypress docs say the IRQ is IRQT_HIGH ... */
 	set_irq_type(irq, IRQT_RISING);
 #endif
-	status = request_irq(irq, sl811h_irq, SA_INTERRUPT, hcd_name, sl811);
-	if (status < 0)
-		goto fail;
-	sl811->hcd.irq = irq;
+	retval = request_irq(irq, sl811h_irq, SA_INTERRUPT,
+			hcd->driver->description, hcd);
+	if (retval != 0)
+		goto err6;
+
+	INFO("%s, irq %d\n", hcd->product_desc, irq);
+
+	retval = usb_register_bus(&hcd->self);
+	if (retval < 0)
+		goto err7;
+
+	retval = sl811h_start(hcd);
+	if (retval < 0)
+		goto err8;
 
-	INFO("%s, irq %d\n", sl811->hcd.product_desc, irq);
+	create_debug_file(sl811);
+	return 0;
 
-	status = usb_register_bus(&sl811->hcd.self);
-	if (status < 0)
-		goto fail;
-	status = sl811h_start(&sl811->hcd);
-	if (status == 0) {
-		create_debug_file(sl811);
-		return 0;
-	}
-fail:
-	sl811h_remove(dev);
-	DBG("init error, %d\n", status);
-	return status;
+ err8:
+	usb_deregister_bus(&hcd->self);
+ err7:
+	free_irq(hcd->irq, hcd);
+ err6:
+	usb_put_hcd(hcd);
+ err5:
+	iounmap(data_reg);
+ err4:
+	release_mem_region(data->start, 1);
+ err3:
+	iounmap(addr_reg);
+ err2:
+	release_mem_region(addr->start, 1);
+ err1:
+	DBG("init error, %d\n", retval);
+	return retval;
 }
 
 #ifdef	CONFIG_PM
@@ -1837,7 +1808,7 @@
 		return retval;
 
 	if (state <= PM_SUSPEND_MEM)
-		retval = sl811h_hub_suspend(&sl811->hcd);
+		retval = sl811h_hub_suspend(sl811_to_hcd(sl811));
 	else
 		port_power(sl811, 0);
 	if (retval == 0)
@@ -1857,14 +1828,14 @@
 	 * let's assume it'd only be powered to enable remote wakeup.
 	 */
 	if (dev->power.power_state > PM_SUSPEND_MEM
-			|| !sl811->hcd.can_wakeup) {
+			|| !sl811_to_hcd(sl811)->can_wakeup) {
 		sl811->port1 = 0;
 		port_power(sl811, 1);
 		return 0;
 	}
 
 	dev->power.power_state = PM_SUSPEND_ON;
-	return sl811h_hub_resume(&sl811->hcd);
+	return sl811h_hub_resume(sl811_to_hcd(sl811));
 }
 
 #else
diff -Nru a/drivers/usb/host/sl811.h b/drivers/usb/host/sl811.h
--- a/drivers/usb/host/sl811.h	2005-03-01 23:38:57 -08:00
+++ b/drivers/usb/host/sl811.h	2005-03-01 23:38:57 -08:00
@@ -118,7 +118,6 @@
 #define	PERIODIC_SIZE		(1 << LOG2_PERIODIC_SIZE)
 
 struct sl811 {
-	struct usb_hcd		hcd;
 	spinlock_t		lock;
 	void __iomem		*addr_reg;
 	void __iomem		*data_reg;
@@ -158,11 +157,16 @@
 
 static inline struct sl811 *hcd_to_sl811(struct usb_hcd *hcd)
 {
-	return container_of(hcd, struct sl811, hcd);
+	return (struct sl811 *) (hcd->hcd_priv);
+}
+
+static inline struct usb_hcd *sl811_to_hcd(struct sl811 *sl811)
+{
+	return container_of((void *) sl811, struct usb_hcd, hcd_priv);
 }
 
 struct sl811h_ep {
-	struct list_head	queue;
+	struct usb_host_endpoint *hep;
 	struct usb_device	*udev;
 
 	u8			defctrl;
@@ -182,14 +186,6 @@
 
 	/* async schedule */
 	struct list_head	schedule;
-};
-
-struct sl811h_req {
-	/* FIXME usbcore should maintain endpoints' urb queues
-	 * directly in 'struct usb_host_endpoint'
-	 */
-	struct urb		*urb;
-	struct list_head	queue;
 };
 
 /*-------------------------------------------------------------------------*/
diff -Nru a/drivers/usb/host/uhci-debug.c b/drivers/usb/host/uhci-debug.c
--- a/drivers/usb/host/uhci-debug.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/usb/host/uhci-debug.c	2005-03-01 23:38:53 -08:00
@@ -11,7 +11,7 @@
 
 #include <linux/config.h>
 #include <linux/kernel.h>
-#include <linux/proc_fs.h>
+#include <linux/debugfs.h>
 #include <linux/smp_lock.h>
 #include <asm/io.h>
 
@@ -95,24 +95,25 @@
 	struct list_head *head, *tmp;
 	struct uhci_td *td;
 	int i = 0, checked = 0, prevactive = 0;
+	__le32 element = qh_element(qh);
 
 	/* Try to make sure there's enough memory */
 	if (len < 80 * 6)
 		return 0;
 
 	out += sprintf(out, "%*s[%p] link (%08x) element (%08x)\n", space, "",
-			qh, le32_to_cpu(qh->link), le32_to_cpu(qh->element));
+			qh, le32_to_cpu(qh->link), le32_to_cpu(element));
 
-	if (qh->element & UHCI_PTR_QH)
+	if (element & UHCI_PTR_QH)
 		out += sprintf(out, "%*s  Element points to QH (bug?)\n", space, "");
 
-	if (qh->element & UHCI_PTR_DEPTH)
+	if (element & UHCI_PTR_DEPTH)
 		out += sprintf(out, "%*s  Depth traverse\n", space, "");
 
-	if (qh->element & cpu_to_le32(8))
+	if (element & cpu_to_le32(8))
 		out += sprintf(out, "%*s  Bit 3 set (bug?)\n", space, "");
 
-	if (!(qh->element & ~(UHCI_PTR_QH | UHCI_PTR_DEPTH)))
+	if (!(element & ~(UHCI_PTR_QH | UHCI_PTR_DEPTH)))
 		out += sprintf(out, "%*s  Element is NULL (bug?)\n", space, "");
 
 	if (!qh->urbp) {
@@ -127,7 +128,7 @@
 
 	td = list_entry(tmp, struct uhci_td, list);
 
-	if (cpu_to_le32(td->dma_handle) != (qh->element & ~UHCI_PTR_BITS))
+	if (cpu_to_le32(td->dma_handle) != (element & ~UHCI_PTR_BITS))
 		out += sprintf(out, "%*s Element != First TD\n", space, "");
 
 	while (tmp != head) {
@@ -447,7 +448,7 @@
 			if (qh->link != UHCI_PTR_TERM)
 				out += sprintf(out, "    bandwidth reclamation on!\n");
 
-			if (qh->element != cpu_to_le32(uhci->term_td->dma_handle))
+			if (qh_element(qh) != cpu_to_le32(uhci->term_td->dma_handle))
 				out += sprintf(out, "    skel_term_qh element is not set to term_td!\n");
 
 			continue;
@@ -496,19 +497,18 @@
 
 #define MAX_OUTPUT	(64 * 1024)
 
-static struct proc_dir_entry *uhci_proc_root = NULL;
+static struct dentry *uhci_debugfs_root = NULL;
 
-struct uhci_proc {
+struct uhci_debug {
 	int size;
 	char *data;
 	struct uhci_hcd *uhci;
 };
 
-static int uhci_proc_open(struct inode *inode, struct file *file)
+static int uhci_debug_open(struct inode *inode, struct file *file)
 {
-	const struct proc_dir_entry *dp = PDE(inode);
-	struct uhci_hcd *uhci = dp->data;
-	struct uhci_proc *up;
+	struct uhci_hcd *uhci = inode->u.generic_ip;
+	struct uhci_debug *up;
 	int ret = -ENOMEM;
 
 	lock_kernel();
@@ -532,9 +532,9 @@
 	return ret;
 }
 
-static loff_t uhci_proc_lseek(struct file *file, loff_t off, int whence)
+static loff_t uhci_debug_lseek(struct file *file, loff_t off, int whence)
 {
-	struct uhci_proc *up;
+	struct uhci_debug *up;
 	loff_t new = -1;
 
 	lock_kernel();
@@ -556,16 +556,16 @@
 	return (file->f_pos = new);
 }
 
-static ssize_t uhci_proc_read(struct file *file, char __user *buf,
+static ssize_t uhci_debug_read(struct file *file, char __user *buf,
 				size_t nbytes, loff_t *ppos)
 {
-	struct uhci_proc *up = file->private_data;
+	struct uhci_debug *up = file->private_data;
 	return simple_read_from_buffer(buf, nbytes, ppos, up->data, up->size);
 }
 
-static int uhci_proc_release(struct inode *inode, struct file *file)
+static int uhci_debug_release(struct inode *inode, struct file *file)
 {
-	struct uhci_proc *up = file->private_data;
+	struct uhci_debug *up = file->private_data;
 
 	kfree(up->data);
 	kfree(up);
@@ -573,11 +573,10 @@
 	return 0;
 }
 
-static struct file_operations uhci_proc_operations = {
-	.open =		uhci_proc_open,
-	.llseek =	uhci_proc_lseek,
-	.read =		uhci_proc_read,
-//	write:		uhci_proc_write,
-	.release =	uhci_proc_release,
+static struct file_operations uhci_debug_operations = {
+	.open =		uhci_debug_open,
+	.llseek =	uhci_debug_lseek,
+	.read =		uhci_debug_read,
+	.release =	uhci_debug_release,
 };
 #endif
diff -Nru a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
--- a/drivers/usb/host/uhci-hcd.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/usb/host/uhci-hcd.c	2005-03-01 23:39:10 -08:00
@@ -46,7 +46,7 @@
 #include <linux/unistd.h>
 #include <linux/interrupt.h>
 #include <linux/spinlock.h>
-#include <linux/proc_fs.h>
+#include <linux/debugfs.h>
 #include <linux/pm.h>
 #include <linux/dmapool.h>
 #include <linux/dma-mapping.h>
@@ -74,7 +74,7 @@
  * debug = 0, no debugging messages
  * debug = 1, dump failed URB's except for stalls
  * debug = 2, dump all failed URB's (including stalls)
- *            show all queues in /proc/driver/uhci/[pci_addr]
+ *            show all queues in /debug/uhci/[pci_addr]
  * debug = 3, show all TD's in URB's when dumping
  */
 #ifdef DEBUG
@@ -236,7 +236,7 @@
 {
 	struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv;
 	struct uhci_td *td;
-	u32 *plink;
+	__le32 *plink;
 
 	/* Ordering isn't important here yet since the QH hasn't been */
 	/* inserted into the schedule yet */
@@ -637,8 +637,9 @@
 /*
  * Map status to standard result codes
  *
- * <status> is (td->status & 0xF60000) [a.k.a. uhci_status_bits(td->status)]
- * Note: status does not include the TD_CTRL_NAK bit.
+ * <status> is (td_status(td) & 0xF60000), a.k.a.
+ * uhci_status_bits(td_status(td)).
+ * Note: <status> does not include the TD_CTRL_NAK bit.
  * <dir_out> is True for output TDs and False for input TDs.
  */
 static int uhci_map_status(int status, int dir_out)
@@ -843,21 +844,24 @@
 	/* The rest of the TD's (but the last) are data */
 	tmp = tmp->next;
 	while (tmp != head && tmp->next != head) {
-		td = list_entry(tmp, struct uhci_td, list);
+		unsigned int ctrlstat;
 
+		td = list_entry(tmp, struct uhci_td, list);
 		tmp = tmp->next;
 
-		status = uhci_status_bits(td_status(td));
+		ctrlstat = td_status(td);
+		status = uhci_status_bits(ctrlstat);
 		if (status & TD_CTRL_ACTIVE)
 			return -EINPROGRESS;
 
-		urb->actual_length += uhci_actual_length(td_status(td));
+		urb->actual_length += uhci_actual_length(ctrlstat);
 
 		if (status)
 			goto td_error;
 
 		/* Check to see if we received a short packet */
-		if (uhci_actual_length(td_status(td)) < uhci_expected_length(td_token(td))) {
+		if (uhci_actual_length(ctrlstat) <
+				uhci_expected_length(td_token(td))) {
 			if (urb->transfer_flags & URB_SHORT_NOT_OK) {
 				ret = -EREMOTEIO;
 				goto err;
@@ -1031,16 +1035,19 @@
 	urb->actual_length = 0;
 
 	list_for_each_entry(td, &urbp->td_list, list) {
-		status = uhci_status_bits(td_status(td));
+		unsigned int ctrlstat = td_status(td);
+
+		status = uhci_status_bits(ctrlstat);
 		if (status & TD_CTRL_ACTIVE)
 			return -EINPROGRESS;
 
-		urb->actual_length += uhci_actual_length(td_status(td));
+		urb->actual_length += uhci_actual_length(ctrlstat);
 
 		if (status)
 			goto td_error;
 
-		if (uhci_actual_length(td_status(td)) < uhci_expected_length(td_token(td))) {
+		if (uhci_actual_length(ctrlstat) <
+				uhci_expected_length(td_token(td))) {
 			if (urb->transfer_flags & URB_SHORT_NOT_OK) {
 				ret = -EREMOTEIO;
 				goto err;
@@ -1209,15 +1216,16 @@
 	i = 0;
 	list_for_each_entry(td, &urbp->td_list, list) {
 		int actlength;
+		unsigned int ctrlstat = td_status(td);
 
-		if (td_status(td) & TD_CTRL_ACTIVE)
+		if (ctrlstat & TD_CTRL_ACTIVE)
 			return -EINPROGRESS;
 
-		actlength = uhci_actual_length(td_status(td));
+		actlength = uhci_actual_length(ctrlstat);
 		urb->iso_frame_desc[i].actual_length = actlength;
 		urb->actual_length += actlength;
 
-		status = uhci_map_status(uhci_status_bits(td_status(td)),
+		status = uhci_map_status(uhci_status_bits(ctrlstat),
 				usb_pipeout(urb->pipe));
 		urb->iso_frame_desc[i].status = status;
 		if (status) {
@@ -1255,7 +1263,9 @@
 	return NULL;
 }
 
-static int uhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, int mem_flags)
+static int uhci_urb_enqueue(struct usb_hcd *hcd,
+		struct usb_host_endpoint *ep,
+		struct urb *urb, int mem_flags)
 {
 	int ret;
 	struct uhci_hcd *uhci = hcd_to_uhci(hcd);
@@ -1421,19 +1431,21 @@
 	 */
 	head = &urbp->td_list;
 	list_for_each_entry(td, head, list) {
-		if (!(td_status(td) & TD_CTRL_ACTIVE) &&
-				(uhci_actual_length(td_status(td)) <
+		unsigned int ctrlstat = td_status(td);
+
+		if (!(ctrlstat & TD_CTRL_ACTIVE) &&
+				(uhci_actual_length(ctrlstat) <
 				 uhci_expected_length(td_token(td)) ||
 				td->list.next == head))
 			usb_settoggle(urb->dev, uhci_endpoint(td_token(td)),
 				uhci_packetout(td_token(td)),
 				uhci_toggle(td_token(td)) ^ 1);
-		else if ((td_status(td) & TD_CTRL_ACTIVE) && !prevactive)
+		else if ((ctrlstat & TD_CTRL_ACTIVE) && !prevactive)
 			usb_settoggle(urb->dev, uhci_endpoint(td_token(td)),
 				uhci_packetout(td_token(td)),
 				uhci_toggle(td_token(td)));
 
-		prevactive = td_status(td) & TD_CTRL_ACTIVE;
+		prevactive = ctrlstat & TD_CTRL_ACTIVE;
 	}
 
 	uhci_delete_queued_urb(uhci, urb);
@@ -1889,7 +1901,7 @@
 	uhci->state_end = jiffies + HZ;
 	outw(USBCMD_RS | USBCMD_CF | USBCMD_MAXP, io_addr + USBCMD);
 
-        uhci->hcd.state = USB_STATE_RUNNING;
+        uhci_to_hcd(uhci)->state = USB_STATE_RUNNING;
 	return 0;
 }
 
@@ -1927,12 +1939,10 @@
 		uhci->fl = NULL;
 	}
 
-#ifdef CONFIG_PROC_FS
-	if (uhci->proc_entry) {
-		remove_proc_entry(uhci->hcd.self.bus_name, uhci_proc_root);
-		uhci->proc_entry = NULL;
+	if (uhci->dentry) {
+		debugfs_remove(uhci->dentry);
+		uhci->dentry = NULL;
 	}
-#endif
 }
 
 static int uhci_reset(struct usb_hcd *hcd)
@@ -1972,25 +1982,17 @@
 	unsigned io_size;
 	dma_addr_t dma_handle;
 	struct usb_device *udev;
-#ifdef CONFIG_PROC_FS
-	struct proc_dir_entry *ent;
-#endif
+	struct dentry *dentry;
 
 	io_size = pci_resource_len(to_pci_dev(uhci_dev(uhci)), hcd->region);
 
-#ifdef CONFIG_PROC_FS
-	ent = create_proc_entry(hcd->self.bus_name, S_IFREG|S_IRUGO|S_IWUSR, uhci_proc_root);
-	if (!ent) {
-		dev_err(uhci_dev(uhci), "couldn't create uhci proc entry\n");
+	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");
 		retval = -ENOMEM;
-		goto err_create_proc_entry;
+		goto err_create_debug_entry;
 	}
-
-	ent->data = uhci;
-	ent->proc_fops = &uhci_proc_operations;
-	ent->size = 0;
-	uhci->proc_entry = ent;
-#endif
+	uhci->dentry = dentry;
 
 	uhci->fsbr = 0;
 	uhci->fsbrtimeout = 0;
@@ -2149,7 +2151,7 @@
 
 	udev->speed = USB_SPEED_FULL;
 
-	if (hcd_register_root(udev, &uhci->hcd) != 0) {
+	if (hcd_register_root(udev, hcd) != 0) {
 		dev_err(uhci_dev(uhci), "unable to start root hub\n");
 		retval = -ENOMEM;
 		goto err_start_root_hub;
@@ -2192,13 +2194,10 @@
 	uhci->fl = NULL;
 
 err_alloc_fl:
-#ifdef CONFIG_PROC_FS
-	remove_proc_entry(hcd->self.bus_name, uhci_proc_root);
-	uhci->proc_entry = NULL;
-
-err_create_proc_entry:
-#endif
+	debugfs_remove(uhci->dentry);
+	uhci->dentry = NULL;
 
+err_create_debug_entry:
 	return retval;
 }
 
@@ -2275,62 +2274,18 @@
 		if ((rc = start_hc(uhci)) != 0)
 			return rc;
 	}
-	uhci->hcd.state = USB_STATE_RUNNING;
+	hcd->state = USB_STATE_RUNNING;
 	return 0;
 }
 #endif
 
-static struct usb_hcd *uhci_hcd_alloc(void)
-{
-	struct uhci_hcd *uhci;
-
-	uhci = (struct uhci_hcd *)kmalloc(sizeof(*uhci), GFP_KERNEL);
-	if (!uhci)
-		return NULL;
-
-	memset(uhci, 0, sizeof(*uhci));
-	uhci->hcd.product_desc = "UHCI Host Controller";
-	return &uhci->hcd;
-}
-
-/* Are there any URBs for a particular device/endpoint on a given list? */
-static int urbs_for_ep_list(struct list_head *head,
-		struct hcd_dev *hdev, int ep)
-{
-	struct urb_priv *urbp;
-
-	list_for_each_entry(urbp, head, urb_list) {
-		struct urb *urb = urbp->urb;
-
-		if (hdev == urb->dev->hcpriv && ep ==
-				(usb_pipeendpoint(urb->pipe) |
-				 usb_pipein(urb->pipe)))
-			return 1;
-	}
-	return 0;
-}
-
-/* Are there any URBs for a particular device/endpoint? */
-static int urbs_for_ep(struct uhci_hcd *uhci, struct hcd_dev *hdev, int ep)
-{
-	int rc;
-
-	spin_lock_irq(&uhci->schedule_lock);
-	rc = (urbs_for_ep_list(&uhci->urb_list, hdev, ep) ||
-			urbs_for_ep_list(&uhci->complete_list, hdev, ep) ||
-			urbs_for_ep_list(&uhci->urb_remove_list, hdev, ep));
-	spin_unlock_irq(&uhci->schedule_lock);
-	return rc;
-}
-
 /* Wait until all the URBs for a particular device/endpoint are gone */
 static void uhci_hcd_endpoint_disable(struct usb_hcd *hcd,
-		struct hcd_dev *hdev, int endpoint)
+		struct usb_host_endpoint *ep)
 {
 	struct uhci_hcd *uhci = hcd_to_uhci(hcd);
 
-	wait_event_interruptible(uhci->waitqh,
-			!urbs_for_ep(uhci, hdev, endpoint));
+	wait_event_interruptible(uhci->waitqh, list_empty(&ep->urb_list));
 }
 
 static int uhci_hcd_get_frame_number(struct usb_hcd *hcd)
@@ -2342,6 +2297,8 @@
 
 static const struct hc_driver uhci_driver = {
 	.description =		hcd_name,
+	.product_desc =		"UHCI Host Controller",
+	.hcd_priv_size =	sizeof(struct uhci_hcd),
 
 	/* Generic hardware linkage */
 	.irq =			uhci_irq,
@@ -2356,8 +2313,6 @@
 #endif
 	.stop =			uhci_stop,
 
-	.hcd_alloc =		uhci_hcd_alloc,
-
 	.urb_enqueue =		uhci_urb_enqueue,
 	.urb_dequeue =		uhci_urb_dequeue,
 
@@ -2405,11 +2360,9 @@
 			goto errbuf_failed;
 	}
 
-#ifdef CONFIG_PROC_FS
-	uhci_proc_root = create_proc_entry("driver/uhci", S_IFDIR, NULL);
-	if (!uhci_proc_root)
-		goto proc_failed;
-#endif
+	uhci_debugfs_root = debugfs_create_dir("uhci", NULL);
+	if (!uhci_debugfs_root)
+		goto debug_failed;
 
 	uhci_up_cachep = kmem_cache_create("uhci_urb_priv",
 		sizeof(struct urb_priv), 0, 0, NULL, NULL);
@@ -2427,12 +2380,9 @@
 		warn("not all urb_priv's were freed!");
 
 up_failed:
+	debugfs_remove(uhci_debugfs_root);
 
-#ifdef CONFIG_PROC_FS
-	remove_proc_entry("driver/uhci", NULL);
-
-proc_failed:
-#endif
+debug_failed:
 	if (errbuf)
 		kfree(errbuf);
 
@@ -2448,9 +2398,7 @@
 	if (kmem_cache_destroy(uhci_up_cachep))
 		warn("not all urb_priv's were freed!");
 
-#ifdef CONFIG_PROC_FS
-	remove_proc_entry("driver/uhci", NULL);
-#endif
+	debugfs_remove(uhci_debugfs_root);
 
 	if (errbuf)
 		kfree(errbuf);
diff -Nru a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h
--- a/drivers/usb/host/uhci-hcd.h	2005-03-01 23:39:08 -08:00
+++ b/drivers/usb/host/uhci-hcd.h	2005-03-01 23:39:08 -08:00
@@ -119,9 +119,19 @@
 } __attribute__((aligned(16)));
 
 /*
+ * We need a special accessor for the element pointer because it is
+ * subject to asynchronous updates by the controller
+ */
+static __le32 inline qh_element(struct uhci_qh *qh) {
+	__le32 element = qh->element;
+
+	barrier();
+	return element;
+}
+
+/*
  * for TD <status>:
  */
-#define td_status(td)		le32_to_cpu((td)->status)
 #define TD_CTRL_SPD		(1 << 29)	/* Short Packet Detect */
 #define TD_CTRL_C_ERR_MASK	(3 << 27)	/* Error Counter bits */
 #define TD_CTRL_C_ERR_SHIFT	27
@@ -204,6 +214,18 @@
 } __attribute__((aligned(16)));
 
 /*
+ * We need a special accessor for the control/status word because it is
+ * subject to asynchronous updates by the controller
+ */
+static u32 inline td_status(struct uhci_td *td) {
+	__le32 status = td->status;
+
+	barrier();
+	return le32_to_cpu(status);
+}
+
+
+/*
  * The UHCI driver places Interrupt, Control and Bulk into QH's both
  * to group together TD's for one transfer, and also to faciliate queuing
  * of URB's. To make it easy to insert entries into the schedule, we have
@@ -314,9 +336,6 @@
 	UHCI_RESUMING_2
 };
 
-#define hcd_to_uhci(hcd_ptr) container_of(hcd_ptr, struct uhci_hcd, hcd)
-#define uhci_dev(u)	((u)->hcd.self.controller)
-
 /*
  * This describes the full uhci information.
  *
@@ -324,12 +343,9 @@
  * a subset of what the full implementation needs.
  */
 struct uhci_hcd {
-	struct usb_hcd hcd;		/* must come first! */
 
-#ifdef CONFIG_PROC_FS
-	/* procfs */
-	struct proc_dir_entry *proc_entry;
-#endif
+	/* debugfs */
+	struct dentry *dentry;
 
 	/* Grabbed from PCI */
 	unsigned long io_addr;
@@ -382,6 +398,18 @@
 
 	wait_queue_head_t waitqh;		/* endpoint_disable waiters */
 };
+
+/* Convert between a usb_hcd pointer and the corresponding uhci_hcd */
+static inline struct uhci_hcd *hcd_to_uhci(struct usb_hcd *hcd)
+{
+	return (struct uhci_hcd *) (hcd->hcd_priv);
+}
+static inline struct usb_hcd *uhci_to_hcd(struct uhci_hcd *uhci)
+{
+	return container_of((void *) uhci, struct usb_hcd, hcd_priv);
+}
+
+#define uhci_dev(u)	(uhci_to_hcd(u)->self.controller)
 
 struct urb_priv {
 	struct list_head urb_list;
diff -Nru a/drivers/usb/image/Kconfig b/drivers/usb/image/Kconfig
--- a/drivers/usb/image/Kconfig	2005-03-01 23:38:52 -08:00
+++ b/drivers/usb/image/Kconfig	2005-03-01 23:38:52 -08:00
@@ -31,7 +31,7 @@
 
 config USB_HPUSBSCSI
 	tristate "HP53xx USB scanner support"
-	depends on USB && SCSI
+	depends on USB && SCSI && BROKEN
 	help
 	  Say Y here if you want support for the HP 53xx series of scanners
 	  and the Minolta Scan Dual.
diff -Nru a/drivers/usb/image/mdc800.c b/drivers/usb/image/mdc800.c
--- a/drivers/usb/image/mdc800.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/usb/image/mdc800.c	2005-03-01 23:38:58 -08:00
@@ -182,13 +182,48 @@
 /* Specification of the Endpoints */
 static struct usb_endpoint_descriptor mdc800_ed [4] =
 {
-	{ 0,0, 0x01, 0x02,  8, 0,0,0 },
-	{ 0,0, 0x82, 0x03,  8, 0,0,0 },
-	{ 0,0, 0x03, 0x02, 64, 0,0,0 },
-	{ 0,0, 0x84, 0x02, 64, 0,0,0 }
+	{ 
+		.bLength = 		0,
+		.bDescriptorType =	0,
+		.bEndpointAddress =	0x01,
+		.bmAttributes = 	0x02,
+		.wMaxPacketSize =	__constant_cpu_to_le16(8),
+		.bInterval = 		0,
+		.bRefresh = 		0,
+		.bSynchAddress = 	0,
+	},
+	{
+		.bLength = 		0,
+		.bDescriptorType = 	0,
+		.bEndpointAddress = 	0x82,
+		.bmAttributes = 	0x03,
+		.wMaxPacketSize = 	__constant_cpu_to_le16(8),
+		.bInterval = 		0,
+		.bRefresh = 		0,
+		.bSynchAddress = 	0,
+	},
+	{
+		.bLength = 		0,
+		.bDescriptorType = 	0,
+		.bEndpointAddress = 	0x03,
+		.bmAttributes = 	0x02,
+		.wMaxPacketSize = 	__constant_cpu_to_le16(64),
+		.bInterval = 		0,
+		.bRefresh = 		0,
+		.bSynchAddress = 	0,
+	},
+	{
+		.bLength = 		0,
+		.bDescriptorType = 	0,
+		.bEndpointAddress = 	0x84,
+		.bmAttributes = 	0x02,
+		.wMaxPacketSize = 	__constant_cpu_to_le16(64),
+		.bInterval = 		0,
+		.bRefresh = 		0,
+		.bSynchAddress = 	0,
+	},
 };
 
-
 /* The Variable used by the driver */
 static struct mdc800_data* mdc800;
 
@@ -421,7 +456,7 @@
 	dbg ("(mdc800_usb_probe) called.");
 
 
-	if (mdc800->dev != 0)
+	if (mdc800->dev != NULL)
 	{
 		warn ("only one Mustek MDC800 is supported.");
 		return -ENODEV;
@@ -1010,7 +1045,7 @@
 
 cleanup_on_fail:
 
-	if (mdc800 != 0)
+	if (mdc800 != NULL)
 	{
 		err ("can't alloc memory!");
 
diff -Nru a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c
--- a/drivers/usb/image/microtek.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/usb/image/microtek.c	2005-03-01 23:39:18 -08:00
@@ -715,8 +715,8 @@
 	MTS_DEBUG( "usb-device descriptor at %x\n", (int)dev );
 
 	MTS_DEBUG( "product id = 0x%x, vendor id = 0x%x\n",
-		   (int)dev->descriptor.idProduct,
-		   (int)dev->descriptor.idVendor );
+		   le16_to_cpu(dev->descriptor.idProduct),
+		   le16_to_cpu(dev->descriptor.idVendor) );
 
 	MTS_DEBUG_GOT_HERE();
 
diff -Nru a/drivers/usb/input/Kconfig b/drivers/usb/input/Kconfig
--- a/drivers/usb/input/Kconfig	2005-03-01 23:39:08 -08:00
+++ b/drivers/usb/input/Kconfig	2005-03-01 23:39:08 -08:00
@@ -200,7 +200,7 @@
 	  The driver has been tested on a Xenarc 700TSV monitor
 	  with eGalax touchscreen.
 
-	  Have a look at http://linux.chapter7.ch/touchkit/ for
+	  Have a look at <http://linux.chapter7.ch/touchkit/> for
 	  a usage description and the required user-space stuff.
 
 	  To compile this driver as a module, choose M here: the
@@ -228,7 +228,7 @@
 	  These are RF remotes with USB receivers. 
 	  The ATI remote comes with many of ATI's All-In-Wonder video cards.
 	  The X10 "Lola" remote is available at:
-	     http://www.x10.com/products/lola_sg1.htm
+	     <http://www.x10.com/products/lola_sg1.htm>
 	  This driver provides mouse pointer, left and right mouse buttons, 
 	  and maps all the other remote buttons to keypress events.
 	  
diff -Nru a/drivers/usb/input/aiptek.c b/drivers/usb/input/aiptek.c
--- a/drivers/usb/input/aiptek.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/usb/input/aiptek.c	2005-03-01 23:39:08 -08:00
@@ -2137,9 +2137,9 @@
 	aiptek->inputdev.name = "Aiptek";
 	aiptek->inputdev.phys = aiptek->features.usbPath;
 	aiptek->inputdev.id.bustype = BUS_USB;
-	aiptek->inputdev.id.vendor = usbdev->descriptor.idVendor;
-	aiptek->inputdev.id.product = usbdev->descriptor.idProduct;
-	aiptek->inputdev.id.version = usbdev->descriptor.bcdDevice;
+	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);
 
 	aiptek->usbdev = usbdev;
 	aiptek->ifnum = intf->altsetting[0].desc.bInterfaceNumber;
diff -Nru a/drivers/usb/input/ati_remote.c b/drivers/usb/input/ati_remote.c
--- a/drivers/usb/input/ati_remote.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/usb/input/ati_remote.c	2005-03-01 23:39:08 -08:00
@@ -672,9 +672,9 @@
 	idev->phys = ati_remote->phys;
 	
 	idev->id.bustype = BUS_USB;		
-	idev->id.vendor = ati_remote->udev->descriptor.idVendor;
-	idev->id.product = ati_remote->udev->descriptor.idProduct;
-	idev->id.version = ati_remote->udev->descriptor.bcdDevice;
+	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);
 }
 
 static int ati_remote_initialize(struct ati_remote *ati_remote)
@@ -729,13 +729,6 @@
 	char path[64];
 	char *buf = NULL;
 
-	/* See if the offered device matches what we can accept */
-	if ((udev->descriptor.idVendor != ATI_REMOTE_VENDOR_ID) ||
-		( (udev->descriptor.idProduct != ATI_REMOTE_PRODUCT_ID) &&
-		  (udev->descriptor.idProduct != LOLA_REMOTE_PRODUCT_ID) &&
-		  (udev->descriptor.idProduct != MEDION_REMOTE_PRODUCT_ID) ))
-		return -ENODEV;
-
 	/* Allocate and clear an ati_remote struct */
 	if (!(ati_remote = kmalloc(sizeof (struct ati_remote), GFP_KERNEL)))
 		return -ENOMEM;
@@ -763,7 +756,7 @@
 		retval = -ENODEV;
 		goto error;
 	}
-	if (ati_remote->endpoint_in->wMaxPacketSize == 0) {
+	if (le16_to_cpu(ati_remote->endpoint_in->wMaxPacketSize) == 0) {
 		err("%s: endpoint_in message size==0? \n", __FUNCTION__);
 		retval = -ENODEV;
 		goto error;
@@ -803,8 +796,8 @@
 
 	if (!strlen(ati_remote->name))
 		sprintf(ati_remote->name, DRIVER_DESC "(%04x,%04x)",
-			ati_remote->udev->descriptor.idVendor, 
-			ati_remote->udev->descriptor.idProduct);
+			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. */
 	retval = ati_remote_initialize(ati_remote);
diff -Nru a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
--- a/drivers/usb/input/hid-core.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/usb/input/hid-core.c	2005-03-01 23:38:58 -08:00
@@ -676,7 +676,7 @@
 	parser->device = device;
 
 	end = start + size;
-	while ((start = fetch_item(start, end, &item)) != 0) {
+	while ((start = fetch_item(start, end, &item)) != NULL) {
 
 		if (item.format != HID_ITEM_FORMAT_SHORT) {
 			dbg("unexpected long global item");
@@ -925,8 +925,9 @@
 			break;
 		case -ECONNRESET:	/* unlink */
 		case -ENOENT:
-		case -ESHUTDOWN:
 		case -EPERM:
+		case -ESHUTDOWN:	/* unplug */
+		case -EILSEQ:		/* unplug timeout on uhci */
 			return;
 		case -ETIMEDOUT:	/* NAK */
 			break;
@@ -1136,12 +1137,15 @@
 {
 	struct hid_device *hid = urb->context;
 	unsigned long flags;
+	int unplug = 0;
 
 	switch (urb->status) {
 		case 0:			/* success */
+		case -ESHUTDOWN:	/* unplug */
+		case -EILSEQ:		/* unplug timeout on uhci */
+			unplug = 1;
 		case -ECONNRESET:	/* unlink */
 		case -ENOENT:
-		case -ESHUTDOWN:
 			break;
 		default:		/* error */
 			warn("output irq status %d received", urb->status);
@@ -1149,7 +1153,10 @@
 
 	spin_lock_irqsave(&hid->outlock, flags);
 
-	hid->outtail = (hid->outtail + 1) & (HID_OUTPUT_FIFO_SIZE - 1);
+	if (unplug)
+		hid->outtail = hid->outhead;
+	else
+		hid->outtail = (hid->outtail + 1) & (HID_OUTPUT_FIFO_SIZE - 1);
 
 	if (hid->outhead != hid->outtail) {
 		if (hid_submit_out(hid)) {
@@ -1173,6 +1180,7 @@
 {
 	struct hid_device *hid = urb->context;
 	unsigned long flags;
+	int unplug = 0;
 
 	spin_lock_irqsave(&hid->ctrllock, flags);
 
@@ -1180,16 +1188,21 @@
 		case 0:			/* success */
 			if (hid->ctrl[hid->ctrltail].dir == USB_DIR_IN) 
 				hid_input_report(hid->ctrl[hid->ctrltail].report->type, urb, regs);
+		case -ESHUTDOWN:	/* unplug */
+		case -EILSEQ:		/* unplug timectrl on uhci */
+			unplug = 1;
 		case -ECONNRESET:	/* unlink */
 		case -ENOENT:
-		case -ESHUTDOWN:
 		case -EPIPE:		/* report not available */
 			break;
 		default:		/* error */
 			warn("ctrl urb status %d received", urb->status);
 	}
 
-	hid->ctrltail = (hid->ctrltail + 1) & (HID_CONTROL_FIFO_SIZE - 1);
+	if (unplug)
+		hid->ctrltail = hid->ctrlhead;
+	else
+		hid->ctrltail = (hid->ctrltail + 1) & (HID_CONTROL_FIFO_SIZE - 1);
 
 	if (hid->ctrlhead != hid->ctrltail) {
 		if (hid_submit_ctrl(hid)) {
@@ -1281,9 +1294,17 @@
 static int hid_get_class_descriptor(struct usb_device *dev, int ifnum,
 		unsigned char type, void *buf, int size)
 {
-	return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
-		USB_REQ_GET_DESCRIPTOR, USB_RECIP_INTERFACE | USB_DIR_IN,
-		(type << 8), ifnum, buf, size, HZ * USB_CTRL_GET_TIMEOUT);
+	int result, retries = 4;
+
+	memset(buf,0,size);	// Make sure we parse really received data
+
+	do {
+		result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+				USB_REQ_GET_DESCRIPTOR, USB_RECIP_INTERFACE | USB_DIR_IN,
+				(type << 8), ifnum, buf, size, HZ * USB_CTRL_GET_TIMEOUT);
+		retries--;
+	} while (result < size && retries);
+	return result;
 }
 
 int hid_open(struct hid_device *hid)
@@ -1314,7 +1335,7 @@
 	struct hid_report_enum *report_enum;
 	struct hid_report *report;
 	struct list_head *list;
-	int err, ret;
+	int err, ret, size;
 
 	/*
 	 * The Set_Idle request is supposed to affect only the
@@ -1337,6 +1358,10 @@
 	list = report_enum->report_list.next;
 	while (list != &report_enum->report_list) {
 		report = (struct hid_report *) list;
+		size = ((report->size - 1) >> 3) + 1 + report_enum->numbered;
+		if (size > HID_BUFFER_SIZE) size = HID_BUFFER_SIZE;
+		if (size > hid->urbin->transfer_buffer_length)
+			hid->urbin->transfer_buffer_length = size;
 		hid_submit_report(hid, report, USB_DIR_IN);
 		list = list->next;
 	}
@@ -1460,11 +1485,11 @@
 #define USB_DEVICE_ID_1_PHIDGETSERVO_20	0x8101
 #define USB_DEVICE_ID_4_PHIDGETSERVO_20	0x8104
 
-#define USB_VENDOR_ID_CODEMERCS        0x07c0
-#define USB_DEVICE_ID_CODEMERCS_IOW40  0x1500
-#define USB_DEVICE_ID_CODEMERCS_IOW24  0x1501
-#define USB_DEVICE_ID_CODEMERCS_IOW48  0x1502
-#define USB_DEVICE_ID_CODEMERCS_IOW28  0x1503
+#define USB_VENDOR_ID_CODEMERCS		0x07c0
+#define USB_DEVICE_ID_CODEMERCS_IOW40	0x1500
+#define USB_DEVICE_ID_CODEMERCS_IOW24	0x1501
+#define USB_DEVICE_ID_CODEMERCS_IOW48	0x1502
+#define USB_DEVICE_ID_CODEMERCS_IOW28	0x1503
 
 #define USB_VENDOR_ID_DELORME		0x1163
 #define USB_DEVICE_ID_DELORME_EARTHMATE 0x0100
@@ -1485,8 +1510,16 @@
 	{ USB_VENDOR_ID_BERKSHIRE, USB_DEVICE_ID_BERKSHIRE_PCWD, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW40, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW24, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW48, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW28, HID_QUIRK_IGNORE },
+	
 	{ USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_GLAB, USB_DEVICE_ID_4_PHIDGETSERVO_30, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_GLAB, USB_DEVICE_ID_1_PHIDGETSERVO_30, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_GLAB, USB_DEVICE_ID_8_8_8_IF_KIT, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_0_4_IF_KIT, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_8_8_IF_KIT, HID_QUIRK_IGNORE },
 	{ 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_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_IGNORE },
@@ -1522,15 +1555,9 @@
 	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 7, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_VOLITO, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PTU, HID_QUIRK_IGNORE },
-
-	{ USB_VENDOR_ID_GLAB, USB_DEVICE_ID_4_PHIDGETSERVO_30, HID_QUIRK_IGNORE },
-	{ USB_VENDOR_ID_GLAB, USB_DEVICE_ID_1_PHIDGETSERVO_30, HID_QUIRK_IGNORE },
-	{ USB_VENDOR_ID_GLAB, USB_DEVICE_ID_8_8_8_IF_KIT, HID_QUIRK_IGNORE },
-	{ USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_0_4_IF_KIT, HID_QUIRK_IGNORE },
-	{ USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_8_8_IF_KIT, HID_QUIRK_IGNORE },
-
 	{ 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_ATEN, USB_DEVICE_ID_ATEN_UC100KM, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS124U, HID_QUIRK_NOGET },
@@ -1539,8 +1566,8 @@
 	{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_TANGTOP, USB_DEVICE_ID_TANGTOP_USBPS2, HID_QUIRK_NOGET },
 
-	{ USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU, HID_QUIRK_2WHEEL_MOUSE_HACK_BACK },
-	{ USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE, HID_QUIRK_2WHEEL_MOUSE_HACK_EXTRA },
+	{ 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_CYPRESS, USB_DEVICE_ID_CYPRESS_HIDCOM, HID_QUIRK_IGNORE },
 
 	{ USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD, HID_QUIRK_BADPAD },
@@ -1599,8 +1626,8 @@
 	int n;
 
 	for (n = 0; hid_blacklist[n].idVendor; n++)
-		if ((hid_blacklist[n].idVendor == dev->descriptor.idVendor) &&
-			(hid_blacklist[n].idProduct == dev->descriptor.idProduct))
+		if ((hid_blacklist[n].idVendor == le16_to_cpu(dev->descriptor.idVendor)) &&
+			(hid_blacklist[n].idProduct == le16_to_cpu(dev->descriptor.idProduct)))
 				quirks = hid_blacklist[n].quirks;
 
 	if (quirks & HID_QUIRK_IGNORE)
@@ -1639,7 +1666,7 @@
 	printk("\n");
 #endif
 
-	if (!(hid = hid_parse_report(rdesc, rsize))) {
+	if (!(hid = hid_parse_report(rdesc, n))) {
 		dbg("parsing report descriptor failed");
 		kfree(rdesc);
 		return NULL;
@@ -1669,17 +1696,12 @@
 			interval = 1 << (interval - 1);
 
 		if (endpoint->bEndpointAddress & USB_DIR_IN) {
-			int len;
-
 			if (hid->urbin)
 				continue;
 			if (!(hid->urbin = usb_alloc_urb(0, GFP_KERNEL)))
 				goto fail;
 			pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
-			len = usb_maxpacket(dev, pipe, 0);
-			if (len > HID_BUFFER_SIZE)
-				len = HID_BUFFER_SIZE;
-			usb_fill_int_urb(hid->urbin, dev, pipe, hid->inbuf, len,
+			usb_fill_int_urb(hid->urbin, dev, pipe, hid->inbuf, 0,
 					 hid_irq_in, hid, interval);
 			hid->urbin->transfer_dma = hid->inbuf_dma;
 			hid->urbin->transfer_flags |=(URB_NO_TRANSFER_DMA_MAP | URB_ASYNC_UNLINK);
@@ -1721,10 +1743,12 @@
 		strcat(hid->name, buf);
 		if (usb_string(dev, dev->descriptor.iProduct, buf, 64) > 0)
 			snprintf(hid->name, 64, "%s %s", hid->name, buf);
-	} else if (usb_string(dev, dev->descriptor.iProduct, buf, 128) > 0) {
+	} else if (usb_string(dev, dev->descriptor.iProduct, buf, 64) > 0) {
 			snprintf(hid->name, 128, "%s", buf);
 	} else
-		snprintf(hid->name, 128, "%04x:%04x", dev->descriptor.idVendor, dev->descriptor.idProduct);
+		snprintf(hid->name, 128, "%04x:%04x", 
+			 le16_to_cpu(dev->descriptor.idVendor),
+			 le16_to_cpu(dev->descriptor.idProduct));
 
 	usb_make_path(dev, buf, 64);
 	snprintf(hid->phys, 64, "%s/input%d", buf,
diff -Nru a/drivers/usb/input/hid-debug.h b/drivers/usb/input/hid-debug.h
--- a/drivers/usb/input/hid-debug.h	2005-03-01 23:38:58 -08:00
+++ b/drivers/usb/input/hid-debug.h	2005-03-01 23:38:58 -08:00
@@ -27,6 +27,8 @@
  * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
  */
 
+#include <linux/input.h>
+
 struct hid_usage_entry {
 	unsigned  page;
 	unsigned  usage;
@@ -79,15 +81,21 @@
       {0, 0x8b, "SystemMenuLeft"},
       {0, 0x8c, "SystemMenuUp"},
       {0, 0x8d, "SystemMenuDown"},
-    {0, 0x90, "D-padUp"},
-    {0, 0x91, "D-padDown"},
-    {0, 0x92, "D-padRight"},
-    {0, 0x93, "D-padLeft"},
+      {0, 0x90, "D-PadUp"},
+      {0, 0x91, "D-PadDown"},
+      {0, 0x92, "D-PadRight"},
+      {0, 0x93, "D-PadLeft"},
   {  7, 0, "Keyboard" },
   {  8, 0, "LED" },
+      {0, 0x01, "NumLock"},
+      {0, 0x02, "CapsLock"},
+      {0, 0x03, "ScrollLock"},
+      {0, 0x04, "Compose"},
+      {0, 0x05, "Kana"},
   {  9, 0, "Button" },
   { 10, 0, "Ordinal" },
-  { 12, 0, "Hotkey" },
+  { 12, 0, "Consumer" },
+      {0, 0x238, "HorizontalWheel"},
   { 13, 0, "Digitizers" },
     {0, 0x01, "Digitizer"},
     {0, 0x02, "Pen"},
@@ -323,7 +331,7 @@
 	printk(".");
 	for (p = hid_usage_table; p->description; p++)
 		if (p->page == (usage >> 16)) {
-			for(++p; p->description && p->page != 0; p++)
+			for(++p; p->description && p->usage != 0; p++)
 				if (p->usage == (usage & 0xffff)) {
 					printk("%s", p->description);
 					return;
@@ -461,4 +469,262 @@
 	printk("hid-debug: input ");
 	resolv_usage(usage->hid);
 	printk(" = %d\n", value);
+}
+
+
+static char *events[EV_MAX + 1] = {
+	[0 ... EV_MAX] = NULL,
+	[EV_SYN] = "Sync",			[EV_KEY] = "Key",
+	[EV_REL] = "Relative",			[EV_ABS] = "Absolute",
+	[EV_MSC] = "Misc",			[EV_LED] = "LED",
+	[EV_SND] = "Sound",			[EV_REP] = "Repeat",
+	[EV_FF] = "ForceFeedback",		[EV_PWR] = "Power",
+	[EV_FF_STATUS] = "ForceFeedbackStatus",
+};
+
+static char *syncs[2] = {
+	[0 ... 1] = NULL,
+	[SYN_REPORT] = "Report",		[SYN_CONFIG] = "Config",
+};
+static char *keys[KEY_MAX + 1] = {
+	[0 ... KEY_MAX] = NULL,
+	[KEY_RESERVED] = "Reserved",		[KEY_ESC] = "Esc",
+	[KEY_1] = "1",				[KEY_2] = "2",
+	[KEY_3] = "3",				[KEY_4] = "4",
+	[KEY_5] = "5",				[KEY_6] = "6",
+	[KEY_7] = "7",				[KEY_8] = "8",
+	[KEY_9] = "9",				[KEY_0] = "0",
+	[KEY_MINUS] = "Minus",			[KEY_EQUAL] = "Equal",
+	[KEY_BACKSPACE] = "Backspace",		[KEY_TAB] = "Tab",
+	[KEY_Q] = "Q",				[KEY_W] = "W",
+	[KEY_E] = "E",				[KEY_R] = "R",
+	[KEY_T] = "T",				[KEY_Y] = "Y",
+	[KEY_U] = "U",				[KEY_I] = "I",
+	[KEY_O] = "O",				[KEY_P] = "P",
+	[KEY_LEFTBRACE] = "LeftBrace",		[KEY_RIGHTBRACE] = "RightBrace",
+	[KEY_ENTER] = "Enter",			[KEY_LEFTCTRL] = "LeftControl",
+	[KEY_A] = "A",				[KEY_S] = "S",
+	[KEY_D] = "D",				[KEY_F] = "F",
+	[KEY_G] = "G",				[KEY_H] = "H",
+	[KEY_J] = "J",				[KEY_K] = "K",
+	[KEY_L] = "L",				[KEY_SEMICOLON] = "Semicolon",
+	[KEY_APOSTROPHE] = "Apostrophe",	[KEY_GRAVE] = "Grave",
+	[KEY_LEFTSHIFT] = "LeftShift",		[KEY_BACKSLASH] = "BackSlash",
+	[KEY_Z] = "Z",				[KEY_X] = "X",
+	[KEY_C] = "C",				[KEY_V] = "V",
+	[KEY_B] = "B",				[KEY_N] = "N",
+	[KEY_M] = "M",				[KEY_COMMA] = "Comma",
+	[KEY_DOT] = "Dot",			[KEY_SLASH] = "Slash",
+	[KEY_RIGHTSHIFT] = "RightShift",	[KEY_KPASTERISK] = "KPAsterisk",
+	[KEY_LEFTALT] = "LeftAlt",		[KEY_SPACE] = "Space",
+	[KEY_CAPSLOCK] = "CapsLock",		[KEY_F1] = "F1",
+	[KEY_F2] = "F2",			[KEY_F3] = "F3",
+	[KEY_F4] = "F4",			[KEY_F5] = "F5",
+	[KEY_F6] = "F6",			[KEY_F7] = "F7",
+	[KEY_F8] = "F8",			[KEY_F9] = "F9",
+	[KEY_F10] = "F10",			[KEY_NUMLOCK] = "NumLock",
+	[KEY_SCROLLLOCK] = "ScrollLock",	[KEY_KP7] = "KP7",
+	[KEY_KP8] = "KP8",			[KEY_KP9] = "KP9",
+	[KEY_KPMINUS] = "KPMinus",		[KEY_KP4] = "KP4",
+	[KEY_KP5] = "KP5",			[KEY_KP6] = "KP6",
+	[KEY_KPPLUS] = "KPPlus",		[KEY_KP1] = "KP1",
+	[KEY_KP2] = "KP2",			[KEY_KP3] = "KP3",
+	[KEY_KP0] = "KP0",			[KEY_KPDOT] = "KPDot",
+	[KEY_ZENKAKUHANKAKU] = "Zenkaku/Hankaku", [KEY_102ND] = "102nd",
+	[KEY_F11] = "F11",			[KEY_F12] = "F12",
+	[KEY_RO] = "RO",			[KEY_KATAKANA] = "Katakana",
+	[KEY_HIRAGANA] = "HIRAGANA",		[KEY_HENKAN] = "Henkan",
+	[KEY_KATAKANAHIRAGANA] = "Katakana/Hiragana", [KEY_MUHENKAN] = "Muhenkan",
+	[KEY_KPJPCOMMA] = "KPJpComma",		[KEY_KPENTER] = "KPEnter",
+	[KEY_RIGHTCTRL] = "RightCtrl",		[KEY_KPSLASH] = "KPSlash",
+	[KEY_SYSRQ] = "SysRq",			[KEY_RIGHTALT] = "RightAlt",
+	[KEY_LINEFEED] = "LineFeed",		[KEY_HOME] = "Home",
+	[KEY_UP] = "Up",			[KEY_PAGEUP] = "PageUp",
+	[KEY_LEFT] = "Left",			[KEY_RIGHT] = "Right",
+	[KEY_END] = "End",			[KEY_DOWN] = "Down",
+	[KEY_PAGEDOWN] = "PageDown",		[KEY_INSERT] = "Insert",
+	[KEY_DELETE] = "Delete",		[KEY_MACRO] = "Macro",
+	[KEY_MUTE] = "Mute",			[KEY_VOLUMEDOWN] = "VolumeDown",
+	[KEY_VOLUMEUP] = "VolumeUp",		[KEY_POWER] = "Power",
+	[KEY_KPEQUAL] = "KPEqual",		[KEY_KPPLUSMINUS] = "KPPlusMinus",
+	[KEY_PAUSE] = "Pause",			[KEY_KPCOMMA] = "KPComma",
+	[KEY_HANGUEL] = "Hanguel",		[KEY_HANJA] = "Hanja",
+	[KEY_YEN] = "Yen",			[KEY_LEFTMETA] = "LeftMeta",
+	[KEY_RIGHTMETA] = "RightMeta",		[KEY_COMPOSE] = "Compose",
+	[KEY_STOP] = "Stop",			[KEY_AGAIN] = "Again",
+	[KEY_PROPS] = "Props",			[KEY_UNDO] = "Undo",
+	[KEY_FRONT] = "Front",			[KEY_COPY] = "Copy",
+	[KEY_OPEN] = "Open",			[KEY_PASTE] = "Paste",
+	[KEY_FIND] = "Find",			[KEY_CUT] = "Cut",
+	[KEY_HELP] = "Help",			[KEY_MENU] = "Menu",
+	[KEY_CALC] = "Calc",			[KEY_SETUP] = "Setup",
+	[KEY_SLEEP] = "Sleep",			[KEY_WAKEUP] = "WakeUp",
+	[KEY_FILE] = "File",			[KEY_SENDFILE] = "SendFile",
+	[KEY_DELETEFILE] = "DeleteFile",	[KEY_XFER] = "X-fer",
+	[KEY_PROG1] = "Prog1",			[KEY_PROG2] = "Prog2",
+	[KEY_WWW] = "WWW",			[KEY_MSDOS] = "MSDOS",
+	[KEY_COFFEE] = "Coffee",		[KEY_DIRECTION] = "Direction",
+	[KEY_CYCLEWINDOWS] = "CycleWindows",	[KEY_MAIL] = "Mail",
+	[KEY_BOOKMARKS] = "Bookmarks",		[KEY_COMPUTER] = "Computer",
+	[KEY_BACK] = "Back",			[KEY_FORWARD] = "Forward",
+	[KEY_CLOSECD] = "CloseCD",		[KEY_EJECTCD] = "EjectCD",
+	[KEY_EJECTCLOSECD] = "EjectCloseCD",	[KEY_NEXTSONG] = "NextSong",
+	[KEY_PLAYPAUSE] = "PlayPause",		[KEY_PREVIOUSSONG] = "PreviousSong",
+	[KEY_STOPCD] = "StopCD",		[KEY_RECORD] = "Record",
+	[KEY_REWIND] = "Rewind",		[KEY_PHONE] = "Phone",
+	[KEY_ISO] = "ISOKey",			[KEY_CONFIG] = "Config",
+	[KEY_HOMEPAGE] = "HomePage",		[KEY_REFRESH] = "Refresh",
+	[KEY_EXIT] = "Exit",			[KEY_MOVE] = "Move",
+	[KEY_EDIT] = "Edit",			[KEY_SCROLLUP] = "ScrollUp",
+	[KEY_SCROLLDOWN] = "ScrollDown",	[KEY_KPLEFTPAREN] = "KPLeftParenthesis",
+	[KEY_KPRIGHTPAREN] = "KPRightParenthesis", [KEY_F13] = "F13",
+	[KEY_F14] = "F14",			[KEY_F15] = "F15",
+	[KEY_F16] = "F16",			[KEY_F17] = "F17",
+	[KEY_F18] = "F18",			[KEY_F19] = "F19",
+	[KEY_F20] = "F20",			[KEY_F21] = "F21",
+	[KEY_F22] = "F22",			[KEY_F23] = "F23",
+	[KEY_F24] = "F24",			[KEY_PLAYCD] = "PlayCD",
+	[KEY_PAUSECD] = "PauseCD",		[KEY_PROG3] = "Prog3",
+	[KEY_PROG4] = "Prog4",			[KEY_SUSPEND] = "Suspend",
+	[KEY_CLOSE] = "Close",			[KEY_PLAY] = "Play",
+	[KEY_FASTFORWARD] = "Fast Forward",	[KEY_BASSBOOST] = "Bass Boost",
+	[KEY_PRINT] = "Print",			[KEY_HP] = "HP",
+	[KEY_CAMERA] = "Camera",		[KEY_SOUND] = "Sound",
+	[KEY_QUESTION] = "Question",		[KEY_EMAIL] = "Email",
+	[KEY_CHAT] = "Chat",			[KEY_SEARCH] = "Search",
+	[KEY_CONNECT] = "Connect",		[KEY_FINANCE] = "Finance",
+	[KEY_SPORT] = "Sport",			[KEY_SHOP] = "Shop",
+	[KEY_ALTERASE] = "Alternate Erase",	[KEY_CANCEL] = "Cancel",
+	[KEY_BRIGHTNESSDOWN] = "Brightness down", [KEY_BRIGHTNESSUP] = "Brightness up",
+	[KEY_MEDIA] = "Media",			[KEY_UNKNOWN] = "Unknown",
+	[BTN_0] = "Btn0",			[BTN_1] = "Btn1",
+	[BTN_2] = "Btn2",			[BTN_3] = "Btn3",
+	[BTN_4] = "Btn4",			[BTN_5] = "Btn5",
+	[BTN_6] = "Btn6",			[BTN_7] = "Btn7",
+	[BTN_8] = "Btn8",			[BTN_9] = "Btn9",
+	[BTN_LEFT] = "LeftBtn",			[BTN_RIGHT] = "RightBtn",
+	[BTN_MIDDLE] = "MiddleBtn",		[BTN_SIDE] = "SideBtn",
+	[BTN_EXTRA] = "ExtraBtn",		[BTN_FORWARD] = "ForwardBtn",
+	[BTN_BACK] = "BackBtn",			[BTN_TASK] = "TaskBtn",
+	[BTN_TRIGGER] = "Trigger",		[BTN_THUMB] = "ThumbBtn",
+	[BTN_THUMB2] = "ThumbBtn2",		[BTN_TOP] = "TopBtn",
+	[BTN_TOP2] = "TopBtn2",			[BTN_PINKIE] = "PinkieBtn",
+	[BTN_BASE] = "BaseBtn",			[BTN_BASE2] = "BaseBtn2",
+	[BTN_BASE3] = "BaseBtn3",		[BTN_BASE4] = "BaseBtn4",
+	[BTN_BASE5] = "BaseBtn5",		[BTN_BASE6] = "BaseBtn6",
+	[BTN_DEAD] = "BtnDead",			[BTN_A] = "BtnA",
+	[BTN_B] = "BtnB",			[BTN_C] = "BtnC",
+	[BTN_X] = "BtnX",			[BTN_Y] = "BtnY",
+	[BTN_Z] = "BtnZ",			[BTN_TL] = "BtnTL",
+	[BTN_TR] = "BtnTR",			[BTN_TL2] = "BtnTL2",
+	[BTN_TR2] = "BtnTR2",			[BTN_SELECT] = "BtnSelect",
+	[BTN_START] = "BtnStart",		[BTN_MODE] = "BtnMode",
+	[BTN_THUMBL] = "BtnThumbL",		[BTN_THUMBR] = "BtnThumbR",
+	[BTN_TOOL_PEN] = "ToolPen",		[BTN_TOOL_RUBBER] = "ToolRubber",
+	[BTN_TOOL_BRUSH] = "ToolBrush",		[BTN_TOOL_PENCIL] = "ToolPencil",
+	[BTN_TOOL_AIRBRUSH] = "ToolAirbrush",	[BTN_TOOL_FINGER] = "ToolFinger",
+	[BTN_TOOL_MOUSE] = "ToolMouse",		[BTN_TOOL_LENS] = "ToolLens",
+	[BTN_TOUCH] = "Touch",			[BTN_STYLUS] = "Stylus",
+	[BTN_STYLUS2] = "Stylus2",		[BTN_TOOL_DOUBLETAP] = "Tool Doubletap",
+	[BTN_TOOL_TRIPLETAP] = "Tool Tripletap", [BTN_GEAR_DOWN] = "WheelBtn",
+	[BTN_GEAR_UP] = "Gear up",		[KEY_OK] = "Ok",
+	[KEY_SELECT] = "Select",		[KEY_GOTO] = "Goto",
+	[KEY_CLEAR] = "Clear",			[KEY_POWER2] = "Power2",
+	[KEY_OPTION] = "Option",		[KEY_INFO] = "Info",
+	[KEY_TIME] = "Time",			[KEY_VENDOR] = "Vendor",
+	[KEY_ARCHIVE] = "Archive",		[KEY_PROGRAM] = "Program",
+	[KEY_CHANNEL] = "Channel",		[KEY_FAVORITES] = "Favorites",
+	[KEY_EPG] = "EPG",			[KEY_PVR] = "PVR",
+	[KEY_MHP] = "MHP",			[KEY_LANGUAGE] = "Language",
+	[KEY_TITLE] = "Title",			[KEY_SUBTITLE] = "Subtitle",
+	[KEY_ANGLE] = "Angle",			[KEY_ZOOM] = "Zoom",
+	[KEY_MODE] = "Mode",			[KEY_KEYBOARD] = "Keyboard",
+	[KEY_SCREEN] = "Screen",		[KEY_PC] = "PC",
+	[KEY_TV] = "TV",			[KEY_TV2] = "TV2",
+	[KEY_VCR] = "VCR",			[KEY_VCR2] = "VCR2",
+	[KEY_SAT] = "Sat",			[KEY_SAT2] = "Sat2",
+	[KEY_CD] = "CD",			[KEY_TAPE] = "Tape",
+	[KEY_RADIO] = "Radio",			[KEY_TUNER] = "Tuner",
+	[KEY_PLAYER] = "Player",		[KEY_TEXT] = "Text",
+	[KEY_DVD] = "DVD",			[KEY_AUX] = "Aux",
+	[KEY_MP3] = "MP3",			[KEY_AUDIO] = "Audio",
+	[KEY_VIDEO] = "Video",			[KEY_DIRECTORY] = "Directory",
+	[KEY_LIST] = "List",			[KEY_MEMO] = "Memo",
+	[KEY_CALENDAR] = "Calendar",		[KEY_RED] = "Red",
+	[KEY_GREEN] = "Green",			[KEY_YELLOW] = "Yellow",
+	[KEY_BLUE] = "Blue",			[KEY_CHANNELUP] = "ChannelUp",
+	[KEY_CHANNELDOWN] = "ChannelDown",	[KEY_FIRST] = "First",
+	[KEY_LAST] = "Last",			[KEY_AB] = "AB",
+	[KEY_NEXT] = "Next",			[KEY_RESTART] = "Restart",
+	[KEY_SLOW] = "Slow",			[KEY_SHUFFLE] = "Shuffle",
+	[KEY_BREAK] = "Break",			[KEY_PREVIOUS] = "Previous",
+	[KEY_DIGITS] = "Digits",		[KEY_TEEN] = "TEEN",
+	[KEY_TWEN] = "TWEN",			[KEY_DEL_EOL] = "DeleteEOL",
+	[KEY_DEL_EOS] = "DeleteEOS",		[KEY_INS_LINE] = "InsertLine",
+	[KEY_DEL_LINE] = "DeleteLine",
+};
+
+static char *relatives[REL_MAX + 1] = {
+	[0 ... REL_MAX] = NULL,
+	[REL_X] = "X",			[REL_Y] = "Y",
+	[REL_Z] = "Z",			[REL_HWHEEL] = "HWheel",
+	[REL_DIAL] = "Dial",		[REL_WHEEL] = "Wheel", 
+	[REL_MISC] = "Misc",	
+};
+
+static char *absolutes[ABS_MAX + 1] = {
+	[0 ... ABS_MAX] = NULL,
+	[ABS_X] = "X",			[ABS_Y] = "Y",
+	[ABS_Z] = "Z",			[ABS_RX] = "Rx",
+	[ABS_RY] = "Ry",		[ABS_RZ] = "Rz",
+	[ABS_THROTTLE] = "Throttle",	[ABS_RUDDER] = "Rudder",
+	[ABS_WHEEL] = "Wheel",		[ABS_GAS] = "Gas",
+	[ABS_BRAKE] = "Brake",		[ABS_HAT0X] = "Hat0X",
+	[ABS_HAT0Y] = "Hat0Y",		[ABS_HAT1X] = "Hat1X",
+	[ABS_HAT1Y] = "Hat1Y",		[ABS_HAT2X] = "Hat2X",
+	[ABS_HAT2Y] = "Hat2Y",		[ABS_HAT3X] = "Hat3X",
+	[ABS_HAT3Y] = "Hat 3Y",		[ABS_PRESSURE] = "Pressure",
+	[ABS_DISTANCE] = "Distance",	[ABS_TILT_X] = "XTilt",
+	[ABS_TILT_Y] = "YTilt",		[ABS_TOOL_WIDTH] = "Tool Width",
+	[ABS_VOLUME] = "Volume",	[ABS_MISC] = "Misc",
+};
+
+static char *misc[MSC_MAX + 1] = {
+	[ 0 ... MSC_MAX] = NULL,
+	[MSC_SERIAL] = "Serial",	[MSC_PULSELED] = "Pulseled",
+	[MSC_GESTURE] = "Gesture",	[MSC_RAW] = "RawData"
+};
+
+static char *leds[LED_MAX + 1] = {
+	[0 ... LED_MAX] = NULL,
+	[LED_NUML] = "NumLock",		[LED_CAPSL] = "CapsLock", 
+	[LED_SCROLLL] = "ScrollLock",	[LED_COMPOSE] = "Compose",
+	[LED_KANA] = "Kana",		[LED_SLEEP] = "Sleep", 
+	[LED_SUSPEND] = "Suspend",	[LED_MUTE] = "Mute",
+	[LED_MISC] = "Misc",
+};
+
+static char *repeats[REP_MAX + 1] = {
+	[0 ... REP_MAX] = NULL,
+	[REP_DELAY] = "Delay",		[REP_PERIOD] = "Period"
+};
+
+static char *sounds[SND_MAX + 1] = {
+	[0 ... SND_MAX] = NULL,
+	[SND_CLICK] = "Click",		[SND_BELL] = "Bell",
+	[SND_TONE] = "Tone"
+};
+
+static char **names[EV_MAX + 1] = {
+	[0 ... EV_MAX] = NULL,
+	[EV_SYN] = syncs,			[EV_KEY] = keys,
+	[EV_REL] = relatives,			[EV_ABS] = absolutes,
+	[EV_MSC] = misc,			[EV_LED] = leds,
+	[EV_SND] = sounds,			[EV_REP] = repeats,
+};
+
+static void resolv_event(__u8 type, __u16 code) {
+
+	printk("%s.%s", events[type] ? events[type] : "?",
+		names[type] ? (names[type][code] ? names[type][code] : "?") : "?");
 }
diff -Nru a/drivers/usb/input/hid-ff.c b/drivers/usb/input/hid-ff.c
--- a/drivers/usb/input/hid-ff.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/usb/input/hid-ff.c	2005-03-01 23:38:57 -08:00
@@ -82,8 +82,8 @@
 {
 	struct hid_ff_initializer *init;
 
-	init = hid_get_ff_init(hid->dev->descriptor.idVendor,
-			       hid->dev->descriptor.idProduct);
+	init = hid_get_ff_init(le16_to_cpu(hid->dev->descriptor.idVendor),
+			       le16_to_cpu(hid->dev->descriptor.idProduct));
 
 	if (!init) {
 		dbg("hid_ff_init could not find initializer");
diff -Nru a/drivers/usb/input/hid-input.c b/drivers/usb/input/hid-input.c
--- a/drivers/usb/input/hid-input.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/usb/input/hid-input.c	2005-03-01 23:38:56 -08:00
@@ -32,6 +32,8 @@
 #include <linux/input.h>
 #include <linux/usb.h>
 
+#undef DEBUG
+
 #include "hid.h"
 
 #define unk	KEY_UNKNOWN
@@ -60,114 +62,132 @@
 	__s32 y;
 }  hid_hat_to_axis[] = {{ 0, 0}, { 0,-1}, { 1,-1}, { 1, 0}, { 1, 1}, { 0, 1}, {-1, 1}, {-1, 0}, {-1,-1}};
 
-static struct input_dev *find_input(struct hid_device *hid, struct hid_field *field)
-{
-	struct list_head *lh;
-	struct hid_input *hidinput;
-
-	list_for_each (lh, &hid->inputs) {
-		int i;
-
-		hidinput = list_entry(lh, struct hid_input, list);
-
-		if (! hidinput->report)
-			continue;
-
-		for (i = 0; i < hidinput->report->maxfield; i++)
-			if (hidinput->report->field[i] == field)
-				return &hidinput->input;
-	}
-
-	/* Assume we only have one input and use it */
-	if (!list_empty(&hid->inputs)) {
-		hidinput = list_entry(hid->inputs.next, struct hid_input, list);
-		return &hidinput->input;
-	}
-
-	/* This is really a bug */
-	return NULL;
-}
+#define map_abs(c)	do { usage->code = c; usage->type = EV_ABS; bit = input->absbit; max = ABS_MAX; } while (0)
+#define map_rel(c)	do { usage->code = c; usage->type = EV_REL; bit = input->relbit; max = REL_MAX; } while (0)
+#define map_key(c)	do { usage->code = c; usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX; } while (0)
+#define map_led(c)	do { usage->code = c; usage->type = EV_LED; bit = input->ledbit; max = LED_MAX; } while (0)
+#define map_ff(c)	do { usage->code = c; usage->type = EV_FF;  bit = input->ffbit;  max =  FF_MAX; } while (0)
+
+#define map_abs_clear(c)	do { map_abs(c); clear_bit(c, bit); } while (0)
+#define map_key_clear(c)	do { map_key(c); clear_bit(c, bit); } while (0)
+#define map_ff_effect(c)	do { set_bit(c, input->ffbit); } while (0)
 
 static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_field *field,
 				     struct hid_usage *usage)
 {
 	struct input_dev *input = &hidinput->input;
 	struct hid_device *device = hidinput->input.private;
-	int max;
-	int is_abs = 0;
+	int max, code;
 	unsigned long *bit;
 
+	field->hidinput = hidinput;
+
+#ifdef DEBUG
+	printk(KERN_DEBUG "Mapping: ");
+	resolv_usage(usage->hid);
+	printk(" ---> ");
+#endif
+
+	if (field->flags & HID_MAIN_ITEM_CONSTANT)
+		goto ignore;
+
 	switch (usage->hid & HID_USAGE_PAGE) {
 
+		case HID_UP_UNDEFINED:
+			goto ignore;
+
 		case HID_UP_KEYBOARD:
 
 			set_bit(EV_REP, input->evbit);
-			usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX;
 
 			if ((usage->hid & HID_USAGE) < 256) {
-				if (!(usage->code = hid_keyboard[usage->hid & HID_USAGE]))
-					return;
-				clear_bit(usage->code, bit);
+				if (!hid_keyboard[usage->hid & HID_USAGE]) goto ignore;
+				map_key_clear(hid_keyboard[usage->hid & HID_USAGE]);
 			} else
-				usage->code = KEY_UNKNOWN;
+				map_key(KEY_UNKNOWN);
 
 			break;
 
 		case HID_UP_BUTTON:
 
-			usage->code = ((usage->hid - 1) & 0xf) + 0x100;
-			usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX;
+			code = ((usage->hid - 1) & 0xf);
 
 			switch (field->application) {
-				case HID_GD_GAMEPAD:  usage->code += 0x10;
-				case HID_GD_JOYSTICK: usage->code += 0x10;
-				case HID_GD_MOUSE:    usage->code += 0x10; break;
+				case HID_GD_MOUSE:
+				case HID_GD_POINTER:  code += 0x110; break;
+				case HID_GD_JOYSTICK: code += 0x120; break;
+				case HID_GD_GAMEPAD:  code += 0x130; break;
 				default:
-					if (field->physical == HID_GD_POINTER)
-						usage->code += 0x10;
-					break;
+					switch (field->physical) {
+						case HID_GD_MOUSE:
+						case HID_GD_POINTER:  code += 0x110; break;
+						case HID_GD_JOYSTICK: code += 0x120; break;
+						case HID_GD_GAMEPAD:  code += 0x130; break;
+						default:              code += 0x100;
+					}
 			}
+
+			map_key(code);
 			break;
 
 		case HID_UP_GENDESK:
 
 			if ((usage->hid & 0xf0) == 0x80) {	/* SystemControl */
 				switch (usage->hid & 0xf) {
-					case 0x1: usage->code = KEY_POWER;  break;
-					case 0x2: usage->code = KEY_SLEEP;  break;
-					case 0x3: usage->code = KEY_WAKEUP; break;
-					default: usage->code = KEY_UNKNOWN; break;
+					case 0x1: map_key_clear(KEY_POWER);  break;
+					case 0x2: map_key_clear(KEY_SLEEP);  break;
+					case 0x3: map_key_clear(KEY_WAKEUP); break;
+					default: goto unknown;
 				}
-				usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX;
 				break;
 			}
 
-			usage->code = usage->hid & 0xf;
-
-			if (field->report_size == 1) {
-				usage->code = BTN_MISC;
-				usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX;
+			if ((usage->hid & 0xf0) == 0x90) {	/* D-pad */
+				switch (usage->hid) {
+					case HID_GD_UP:	   usage->hat_dir = 1; break;
+					case HID_GD_DOWN:  usage->hat_dir = 5; break;
+					case HID_GD_RIGHT: usage->hat_dir = 3; break;
+					case HID_GD_LEFT:  usage->hat_dir = 7; break;
+					default: goto unknown;
+				}
+				if (field->dpad) {
+					map_abs(field->dpad);
+					goto ignore;
+				}
+				map_abs(ABS_HAT0X);
 				break;
 			}
 
-			if (field->flags & HID_MAIN_ITEM_RELATIVE) {
-				usage->type = EV_REL; bit = input->relbit; max = REL_MAX;
-				break;
-			}
+			switch (usage->hid) {
 
-			usage->type = EV_ABS; bit = input->absbit; max = ABS_MAX;
+				/* These usage IDs map directly to the usage codes. */
+				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) 
+						map_rel(usage->hid & 0xf);
+					else
+						map_abs(usage->hid & 0xf);
+					break;
+
+				case HID_GD_HATSWITCH:
+					usage->hat_min = field->logical_minimum;
+					usage->hat_max = field->logical_maximum;
+					map_abs(ABS_HAT0X);
+					break;
 
-			if (usage->hid == HID_GD_HATSWITCH) {
-				usage->code = ABS_HAT0X;
-				usage->hat_min = field->logical_minimum;
-				usage->hat_max = field->logical_maximum;
+				case HID_GD_START:	map_key_clear(BTN_START);	break;
+				case HID_GD_SELECT:	map_key_clear(BTN_SELECT);	break;
+
+				default: goto unknown;
 			}
+
 			break;
 
 		case HID_UP_LED:
-
-			usage->code = (usage->hid - 1) & 0xf;
-			usage->type = EV_LED; bit = input->ledbit; max = LED_MAX;
+			if (((usage->hid - 1) & 0xffff) >= LED_MAX)
+				goto ignore;
+			map_led((usage->hid - 1) & 0xffff);
 			break;
 
 		case HID_UP_DIGITIZER:
@@ -175,49 +195,36 @@
 			switch (usage->hid & 0xff) {
 
 				case 0x30: /* TipPressure */
-
 					if (!test_bit(BTN_TOUCH, input->keybit)) {
 						device->quirks |= HID_QUIRK_NOTOUCH;
 						set_bit(EV_KEY, input->evbit);
 						set_bit(BTN_TOUCH, input->keybit);
 					}
-					usage->type = EV_ABS; bit = input->absbit; max = ABS_MAX;
-					usage->code = ABS_PRESSURE;
-					clear_bit(usage->code, bit);
+
+					map_abs_clear(ABS_PRESSURE);
 					break;
 
 				case 0x32: /* InRange */
-
-					usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX;
 					switch (field->physical & 0xff) {
-						case 0x21: usage->code = BTN_TOOL_MOUSE; break;
-						case 0x22: usage->code = BTN_TOOL_FINGER; break;
-						default: usage->code = BTN_TOOL_PEN; break;
+						case 0x21: map_key(BTN_TOOL_MOUSE); break;
+						case 0x22: map_key(BTN_TOOL_FINGER); break;
+						default: map_key(BTN_TOOL_PEN); break;
 					}
 					break;
 
 				case 0x3c: /* Invert */
-
-					usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX;
-					usage->code = BTN_TOOL_RUBBER;
-					clear_bit(usage->code, bit);
+					map_key_clear(BTN_TOOL_RUBBER);
 					break;
 
 				case 0x33: /* Touch */
 				case 0x42: /* TipSwitch */
 				case 0x43: /* TipSwitch2 */
-
 					device->quirks &= ~HID_QUIRK_NOTOUCH;
-					usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX;
-					usage->code = BTN_TOUCH;
-					clear_bit(usage->code, bit);
+					map_key_clear(BTN_TOUCH);
 					break;
 
 				case 0x44: /* BarrelSwitch */
-
-					usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX;
-					usage->code = BTN_STYLUS;
-					clear_bit(usage->code, bit);
+					map_key_clear(BTN_STYLUS);
 					break;
 
 				default:  goto unknown;
@@ -226,56 +233,44 @@
 
 		case HID_UP_CONSUMER:	/* USB HUT v1.1, pages 56-62 */
 
-			set_bit(EV_REP, input->evbit);
 			switch (usage->hid & HID_USAGE) {
-				case 0x000: usage->code = 0; break;
-				case 0x034: usage->code = KEY_SLEEP;		break;
-				case 0x036: usage->code = BTN_MISC;		break;
-				case 0x08a: usage->code = KEY_WWW;		break;
-				case 0x095: usage->code = KEY_HELP;		break;
-
-				case 0x0b0: usage->code = KEY_PLAY;		break;
-				case 0x0b1: usage->code = KEY_PAUSE;		break;
-				case 0x0b2: usage->code = KEY_RECORD;		break;
-				case 0x0b3: usage->code = KEY_FASTFORWARD;	break;
-				case 0x0b4: usage->code = KEY_REWIND;		break;
-				case 0x0b5: usage->code = KEY_NEXTSONG;		break;
-				case 0x0b6: usage->code = KEY_PREVIOUSSONG;	break;
-				case 0x0b7: usage->code = KEY_STOPCD;		break;
-				case 0x0b8: usage->code = KEY_EJECTCD;		break;
-				case 0x0cd: usage->code = KEY_PLAYPAUSE;	break;
-			        case 0x0e0: is_abs = 1;
-					    usage->code = ABS_VOLUME;
-					    break;
-				case 0x0e2: usage->code = KEY_MUTE;		break;
-				case 0x0e5: usage->code = KEY_BASSBOOST;	break;
-				case 0x0e9: usage->code = KEY_VOLUMEUP;		break;
-				case 0x0ea: usage->code = KEY_VOLUMEDOWN;	break;
-
-				case 0x183: usage->code = KEY_CONFIG;		break;
-				case 0x18a: usage->code = KEY_MAIL;		break;
-				case 0x192: usage->code = KEY_CALC;		break;
-				case 0x194: usage->code = KEY_FILE;		break;
-				case 0x21a: usage->code = KEY_UNDO;		break;
-				case 0x21b: usage->code = KEY_COPY;		break;
-				case 0x21c: usage->code = KEY_CUT;		break;
-				case 0x21d: usage->code = KEY_PASTE;		break;
-
-				case 0x221: usage->code = KEY_FIND;		break;
-				case 0x223: usage->code = KEY_HOMEPAGE;		break;
-				case 0x224: usage->code = KEY_BACK;		break;
-				case 0x225: usage->code = KEY_FORWARD;		break;
-				case 0x226: usage->code = KEY_STOP;		break;
-				case 0x227: usage->code = KEY_REFRESH;		break;
-				case 0x22a: usage->code = KEY_BOOKMARKS;	break;
-
-				default:    usage->code = KEY_UNKNOWN;		break;
-			}
-
-			if (is_abs) {
-			        usage->type = EV_ABS; bit = input->absbit; max = ABS_MAX;
-			} else  {
-				usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX;
+				case 0x000: goto ignore;
+				case 0x034: map_key_clear(KEY_SLEEP);		break;
+				case 0x036: map_key_clear(BTN_MISC);		break;
+				case 0x08a: map_key_clear(KEY_WWW);		break;
+				case 0x095: map_key_clear(KEY_HELP);		break;
+				case 0x0b0: map_key_clear(KEY_PLAY);		break;
+				case 0x0b1: map_key_clear(KEY_PAUSE);		break;
+				case 0x0b2: map_key_clear(KEY_RECORD);		break;
+				case 0x0b3: map_key_clear(KEY_FASTFORWARD);	break;
+				case 0x0b4: map_key_clear(KEY_REWIND);		break;
+				case 0x0b5: map_key_clear(KEY_NEXTSONG);	break;
+				case 0x0b6: map_key_clear(KEY_PREVIOUSSONG);	break;
+				case 0x0b7: map_key_clear(KEY_STOPCD);		break;
+				case 0x0b8: map_key_clear(KEY_EJECTCD);		break;
+				case 0x0cd: map_key_clear(KEY_PLAYPAUSE);	break;
+			        case 0x0e0: map_abs_clear(ABS_VOLUME);		break;
+				case 0x0e2: map_key_clear(KEY_MUTE);		break;
+				case 0x0e5: map_key_clear(KEY_BASSBOOST);	break;
+				case 0x0e9: map_key_clear(KEY_VOLUMEUP);	break;
+				case 0x0ea: map_key_clear(KEY_VOLUMEDOWN);	break;
+				case 0x183: map_key_clear(KEY_CONFIG);		break;
+				case 0x18a: map_key_clear(KEY_MAIL);		break;
+				case 0x192: map_key_clear(KEY_CALC);		break;
+				case 0x194: map_key_clear(KEY_FILE);		break;
+				case 0x21a: map_key_clear(KEY_UNDO);		break;
+				case 0x21b: map_key_clear(KEY_COPY);		break;
+				case 0x21c: map_key_clear(KEY_CUT);		break;
+				case 0x21d: map_key_clear(KEY_PASTE);		break;
+				case 0x221: map_key_clear(KEY_FIND);		break;
+				case 0x223: map_key_clear(KEY_HOMEPAGE);	break;
+				case 0x224: map_key_clear(KEY_BACK);		break;
+				case 0x225: map_key_clear(KEY_FORWARD);		break;
+				case 0x226: map_key_clear(KEY_STOP);		break;
+				case 0x227: map_key_clear(KEY_REFRESH);		break;
+				case 0x22a: map_key_clear(KEY_BOOKMARKS);	break;
+				case 0x238: map_rel(REL_HWHEEL);		break;
+				default:    goto unknown;
 			}
 			break;
 
@@ -283,114 +278,86 @@
 
 			set_bit(EV_REP, input->evbit);
 			switch (usage->hid & HID_USAGE) {
-			        case 0x021: usage->code = KEY_PRINT;            break;
-				case 0x070: usage->code = KEY_HP;		break;
-				case 0x071: usage->code = KEY_CAMERA;		break;
-				case 0x072: usage->code = KEY_SOUND;		break;
-				case 0x073: usage->code = KEY_QUESTION;		break;
-
-				case 0x080: usage->code = KEY_EMAIL;		break;
-				case 0x081: usage->code = KEY_CHAT;		break;
-				case 0x082: usage->code = KEY_SEARCH;		break;
-				case 0x083: usage->code = KEY_CONNECT;	        break;
-				case 0x084: usage->code = KEY_FINANCE;		break;
-				case 0x085: usage->code = KEY_SPORT;		break;
-				case 0x086: usage->code = KEY_SHOP;	        break;
-
-				default:    usage->code = KEY_UNKNOWN;		break;
-
+			        case 0x021: map_key_clear(KEY_PRINT);           break;
+				case 0x070: map_key_clear(KEY_HP);		break;
+				case 0x071: map_key_clear(KEY_CAMERA);		break;
+				case 0x072: map_key_clear(KEY_SOUND);		break;
+				case 0x073: map_key_clear(KEY_QUESTION);	break;
+				case 0x080: map_key_clear(KEY_EMAIL);		break;
+				case 0x081: map_key_clear(KEY_CHAT);		break;
+				case 0x082: map_key_clear(KEY_SEARCH);		break;
+				case 0x083: map_key_clear(KEY_CONNECT);	        break;
+				case 0x084: map_key_clear(KEY_FINANCE);		break;
+				case 0x085: map_key_clear(KEY_SPORT);		break;
+				case 0x086: map_key_clear(KEY_SHOP);	        break;
+				default:    goto ignore;
 			}
-
-			usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX;
 			break;
+
+		case HID_UP_MSVENDOR:
+
+			goto ignore;
 			
 		case HID_UP_PID:
 
-			usage->type = EV_FF; bit = input->ffbit; max = FF_MAX;
-			
+			set_bit(EV_FF, input->evbit);
 			switch(usage->hid & HID_USAGE) {
-				case 0x26: set_bit(FF_CONSTANT, input->ffbit); break;
-				case 0x27: set_bit(FF_RAMP,     input->ffbit); break;
-				case 0x28: set_bit(FF_CUSTOM,   input->ffbit); break;
-				case 0x30: set_bit(FF_SQUARE,   input->ffbit);
-				           set_bit(FF_PERIODIC, input->ffbit); break;
-				case 0x31: set_bit(FF_SINE,     input->ffbit);
-				           set_bit(FF_PERIODIC, input->ffbit); break;
-				case 0x32: set_bit(FF_TRIANGLE, input->ffbit);
-				           set_bit(FF_PERIODIC, input->ffbit); break;
-				case 0x33: set_bit(FF_SAW_UP,   input->ffbit);
-				           set_bit(FF_PERIODIC, input->ffbit); break;
-				case 0x34: set_bit(FF_SAW_DOWN, input->ffbit);
-				           set_bit(FF_PERIODIC, input->ffbit); break;
-				case 0x40: set_bit(FF_SPRING,   input->ffbit); break;
-				case 0x41: set_bit(FF_DAMPER,   input->ffbit); break;
-				case 0x42: set_bit(FF_INERTIA , input->ffbit); break;
-				case 0x43: set_bit(FF_FRICTION, input->ffbit); break;
-				case 0x7e: usage->code = FF_GAIN;       break;
-				case 0x83:  /* Simultaneous Effects Max */
-					input->ff_effects_max = (field->value[0]);
-					dbg("Maximum Effects - %d",input->ff_effects_max);
-					break;
-				case 0x98:  /* Device Control */
-					usage->code = FF_AUTOCENTER;    break;
-				case 0xa4:  /* Safety Switch */
-					usage->code = BTN_DEAD;
-					bit = input->keybit;
-					usage->type = EV_KEY;
-					max = KEY_MAX;
-					dbg("Safety Switch Report\n");
-					break;
-				case 0x9f: /* Device Paused */
-				case 0xa0: /* Actuators Enabled */
-					dbg("Not telling the input API about ");
-					resolv_usage(usage->hid);
-					return;
+				case 0x26: map_ff_effect(FF_CONSTANT);	goto ignore;
+				case 0x27: map_ff_effect(FF_RAMP);	goto ignore;
+				case 0x28: map_ff_effect(FF_CUSTOM);	goto ignore;
+				case 0x30: map_ff_effect(FF_SQUARE);	map_ff_effect(FF_PERIODIC); goto ignore;
+				case 0x31: map_ff_effect(FF_SINE);	map_ff_effect(FF_PERIODIC); goto ignore;
+				case 0x32: map_ff_effect(FF_TRIANGLE);	map_ff_effect(FF_PERIODIC); goto ignore;
+				case 0x33: map_ff_effect(FF_SAW_UP);	map_ff_effect(FF_PERIODIC); goto ignore;
+				case 0x34: map_ff_effect(FF_SAW_DOWN);	map_ff_effect(FF_PERIODIC); goto ignore;
+				case 0x40: map_ff_effect(FF_SPRING);	goto ignore;
+				case 0x41: map_ff_effect(FF_DAMPER);	goto ignore;
+				case 0x42: map_ff_effect(FF_INERTIA);	goto ignore;
+				case 0x43: map_ff_effect(FF_FRICTION);	goto ignore;
+				case 0x7e: map_ff(FF_GAIN);		break;
+				case 0x83: input->ff_effects_max = field->value[0]; goto ignore;
+				case 0x98: map_ff(FF_AUTOCENTER);	break;
+				case 0xa4: map_key_clear(BTN_DEAD);	break;
+				default: goto ignore;
 			}
 			break;
+
 		default:
 		unknown:
-			resolv_usage(usage->hid);
-
 			if (field->report_size == 1) {
-
 				if (field->report->type == HID_OUTPUT_REPORT) {
-					usage->code = LED_MISC;
-					usage->type = EV_LED; bit = input->ledbit; max = LED_MAX;
+					map_led(LED_MISC);
 					break;
 				}
-
-				usage->code = BTN_MISC;
-				usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX;
+				map_key(BTN_MISC);
 				break;
 			}
-
 			if (field->flags & HID_MAIN_ITEM_RELATIVE) {
-				usage->code = REL_MISC;
-				usage->type = EV_REL; bit = input->relbit; max = REL_MAX;
+				map_rel(REL_MISC);
 				break;
 			}
-
-			usage->code = ABS_MISC;
-			usage->type = EV_ABS; bit = input->absbit; max = ABS_MAX;
+			map_abs(ABS_MISC);
 			break;
 	}
 
 	set_bit(usage->type, input->evbit);
-	if ((usage->type == EV_REL)
-			&& (device->quirks & (HID_QUIRK_2WHEEL_MOUSE_HACK_BACK
-				| HID_QUIRK_2WHEEL_MOUSE_HACK_EXTRA))
-			&& (usage->code == REL_WHEEL)) {
-		set_bit(REL_HWHEEL, bit);
-	}
 
-	while (usage->code <= max && test_and_set_bit(usage->code, bit)) {
+	while (usage->code <= max && test_and_set_bit(usage->code, bit))
 		usage->code = find_next_zero_bit(bit, max + 1, usage->code);
-	}
 
 	if (usage->code > max)
-		return;
+		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)) 
+			set_bit(REL_HWHEEL, bit);
+
+	if (((device->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_5) && (usage->hid == 0x00090005))
+		|| ((device->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_7) && (usage->hid == 0x00090007)))
+		goto ignore;
 
 	if (usage->type == EV_ABS) {
+
 		int a = field->logical_minimum;
 		int b = field->logical_maximum;
 
@@ -399,62 +366,71 @@
 			b = field->logical_maximum = 255;
 		}
 		
-		input->absmin[usage->code] = a;
-		input->absmax[usage->code] = b;
-		input->absfuzz[usage->code] = 0;
-		input->absflat[usage->code] = 0;
-
-		if (field->application == HID_GD_GAMEPAD || field->application == HID_GD_JOYSTICK) {
-			input->absfuzz[usage->code] = (b - a) >> 8;
-			input->absflat[usage->code] = (b - a) >> 4;
-		}
+		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) {
+	if (usage->hat_min < usage->hat_max || usage->hat_dir) {
 		int i;
 		for (i = usage->code; i < usage->code + 2 && i <= max; i++) {
-			input->absmax[i] = 1;
-			input->absmin[i] = -1;
-			input->absfuzz[i] = 0;
-			input->absflat[i] = 0;
+			input_set_abs_params(input, i, -1, 1, 0, 0);
+			set_bit(i, input->absbit);
 		}
-		set_bit(usage->code + 1, input->absbit);
+		if (usage->hat_dir && !field->dpad)
+			field->dpad = usage->code;
 	}
+
+#ifdef DEBUG
+	resolv_event(usage->type, usage->code);
+	printk("\n");
+#endif
+	return;
+
+ignore:
+#ifdef DEBUG
+	printk("IGNORED\n");
+#endif
+	return;
 }
 
 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 = find_input(hid, field);
+	struct input_dev *input = &field->hidinput->input;
 	int *quirks = &hid->quirks;
 
 	if (!input)
 		return;
 
 	input_regs(input, regs);
+	input_event(input, EV_MSC, MSC_SCAN, usage->hid);
 
-	if (((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_EXTRA) && (usage->code == BTN_EXTRA))
-		|| ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_BACK) && (usage->code == BTN_BACK))) {
-		if (value)
-			hid->quirks |= HID_QUIRK_2WHEEL_MOUSE_HACK_ON;
-		else
-			hid->quirks &= ~HID_QUIRK_2WHEEL_MOUSE_HACK_ON;
+	if (!usage->type)
 		return;
-	}
 
-	if ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_ON)
-			&& (usage->code == REL_WHEEL)) {
-		input_event(input, usage->type, REL_HWHEEL, value);
+	if (((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_5) && (usage->hid == 0x00090005))
+		|| ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_7) && (usage->hid == 0x00090007))) {
+		if (value) hid->quirks |=  HID_QUIRK_2WHEEL_MOUSE_HACK_ON;
+		else       hid->quirks &= ~HID_QUIRK_2WHEEL_MOUSE_HACK_ON;
 		return;
 	}
 
-	if (usage->hat_min != usage->hat_max ) { /* FIXME: hat_max can be 0 and hat_min 1 */
-		value = (value - usage->hat_min) * 8 / (usage->hat_max - usage->hat_min + 1) + 1;
-		if (value < 0 || value > 8) value = 0;
-		input_event(input, usage->type, usage->code    , hid_hat_to_axis[value].x);
-		input_event(input, usage->type, usage->code + 1, hid_hat_to_axis[value].y);
+	if ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_ON) && (usage->code == REL_WHEEL)) {
+		input_event(input, usage->type, REL_HWHEEL, value);
 		return;
 	}
 
+	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;
+		if (hat_dir < 0 || hat_dir > 8) hat_dir = 0;
+		input_event(input, usage->type, usage->code    , hid_hat_to_axis[hat_dir].x);
+                input_event(input, usage->type, usage->code + 1, hid_hat_to_axis[hat_dir].y);
+                return;
+        }
+
 	if (usage->hid == (HID_UP_DIGITIZER | 0x003c)) { /* Invert */
 		*quirks = value ? (*quirks | HID_QUIRK_INVERT) : (*quirks & ~HID_QUIRK_INVERT);
 		return;
@@ -481,6 +457,7 @@
 		dbg("Maximum Effects - %d",input->ff_effects_max);
 		return;
 	}
+
 	if (usage->hid == (HID_UP_PID | 0x7fUL)) {
 		dbg("PID Pool Report\n");
 		return;
@@ -515,6 +492,9 @@
 	if (type == EV_FF)
 		return hid_ff_event(hid, dev, type, code, value);
 
+	if (type != EV_LED)
+		return -1;
+
 	if ((offset = hid_find_field(hid, type, code, &field)) == -1) {
 		warn("event field not found");
 		return -1;
@@ -556,9 +536,10 @@
 	INIT_LIST_HEAD(&hid->inputs);
 
 	for (i = 0; i < hid->maxcollection; i++)
-		if (hid->collection[i].type == HID_COLLECTION_APPLICATION &&
-		    IS_INPUT_APPLICATION(hid->collection[i].usage))
-			break;
+		if (hid->collection[i].type == HID_COLLECTION_APPLICATION ||
+		    hid->collection[i].type == HID_COLLECTION_PHYSICAL)
+		    	if (IS_INPUT_APPLICATION(hid->collection[i].usage))
+				break;
 
 	if (i == hid->maxcollection)
 		return -1;
@@ -593,17 +574,20 @@
 				hidinput->input.phys = hid->phys;
 				hidinput->input.uniq = hid->uniq;
 				hidinput->input.id.bustype = BUS_USB;
-				hidinput->input.id.vendor = dev->descriptor.idVendor;
-				hidinput->input.id.product = dev->descriptor.idProduct;
-				hidinput->input.id.version = dev->descriptor.bcdDevice;
+				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);
 				hidinput->input.dev = &hid->intf->dev;
+
+				set_bit(EV_MSC, hidinput->input.evbit);
+				set_bit(MSC_SCAN, hidinput->input.mscbit);
 			}
 
 			for (i = 0; i < report->maxfield; i++)
 				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 -Nru a/drivers/usb/input/hid-lgff.c b/drivers/usb/input/hid-lgff.c
--- a/drivers/usb/input/hid-lgff.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/usb/input/hid-lgff.c	2005-03-01 23:39:08 -08:00
@@ -251,8 +251,8 @@
 {
 	struct device_type* dev = devices;
 	signed short* ff;
-	u16 idVendor = hid->dev->descriptor.idVendor;
-	u16 idProduct = hid->dev->descriptor.idProduct;
+	u16 idVendor = le16_to_cpu(hid->dev->descriptor.idVendor);
+	u16 idProduct = le16_to_cpu(hid->dev->descriptor.idProduct);
 	struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
 
 	while (dev->idVendor && (idVendor != dev->idVendor || idProduct != dev->idProduct))
diff -Nru a/drivers/usb/input/hid.h b/drivers/usb/input/hid.h
--- a/drivers/usb/input/hid.h	2005-03-01 23:38:44 -08:00
+++ b/drivers/usb/input/hid.h	2005-03-01 23:38:44 -08:00
@@ -171,6 +171,7 @@
 
 #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
@@ -180,6 +181,7 @@
 #define HID_UP_DIGITIZER 	0x000d0000
 #define HID_UP_PID 		0x000f0000
 #define HID_UP_HPVENDOR         0xff7f0000
+#define HID_UP_MSVENDOR		0xff000000
 
 #define HID_USAGE		0x0000ffff
 
@@ -187,7 +189,36 @@
 #define HID_GD_MOUSE		0x00010002
 #define HID_GD_JOYSTICK		0x00010004
 #define HID_GD_GAMEPAD		0x00010005
+#define HID_GD_KEYBOARD		0x00010006
+#define HID_GD_KEYPAD		0x00010007
+#define HID_GD_MULTIAXIS	0x00010008
+#define HID_GD_X		0x00010030
+#define HID_GD_Y		0x00010031
+#define HID_GD_Z		0x00010032
+#define HID_GD_RX		0x00010033
+#define HID_GD_RY		0x00010034
+#define HID_GD_RZ		0x00010035
+#define HID_GD_SLIDER		0x00010036
+#define HID_GD_DIAL		0x00010037
+#define HID_GD_WHEEL		0x00010038
 #define HID_GD_HATSWITCH	0x00010039
+#define HID_GD_BUFFER		0x0001003a
+#define HID_GD_BYTECOUNT	0x0001003b
+#define HID_GD_MOTION		0x0001003c
+#define HID_GD_START		0x0001003d
+#define HID_GD_SELECT		0x0001003e
+#define HID_GD_VX		0x00010040
+#define HID_GD_VY		0x00010041
+#define HID_GD_VZ		0x00010042
+#define HID_GD_VBRX		0x00010043
+#define HID_GD_VBRY		0x00010044
+#define HID_GD_VBRZ		0x00010045
+#define HID_GD_VNO		0x00010046
+#define HID_GD_FEATURE		0x00010047
+#define HID_GD_UP		0x00010090
+#define HID_GD_DOWN		0x00010091
+#define HID_GD_RIGHT		0x00010092
+#define HID_GD_LEFT		0x00010093
 
 /*
  * HID report types --- Ouch! HID spec says 1 2 3!
@@ -208,8 +239,8 @@
 #define HID_QUIRK_HIDDEV			0x010
 #define HID_QUIRK_BADPAD			0x020
 #define HID_QUIRK_MULTI_INPUT			0x040
-#define HID_QUIRK_2WHEEL_MOUSE_HACK_BACK	0x080
-#define HID_QUIRK_2WHEEL_MOUSE_HACK_EXTRA	0x100
+#define HID_QUIRK_2WHEEL_MOUSE_HACK_7		0x080
+#define HID_QUIRK_2WHEEL_MOUSE_HACK_5		0x100
 #define HID_QUIRK_2WHEEL_MOUSE_HACK_ON		0x200
 
 /*
@@ -262,12 +293,16 @@
 struct hid_usage {
 	unsigned  hid;			/* hid usage code */
 	unsigned  collection_index;	/* index into collection array */
+	/* hidinput data */
 	__u16     code;			/* input driver code */
 	__u8      type;			/* input driver type */
 	__s8	  hat_min;		/* hat switch fun */
 	__s8	  hat_max;		/* ditto */
+	__s8	  hat_dir;		/* ditto */
 };
 
+struct hid_input;
+
 struct hid_field {
 	unsigned  physical;		/* physical usage for this field */
 	unsigned  logical;		/* logical usage for this field */
@@ -288,6 +323,9 @@
 	unsigned  unit;
 	struct hid_report *report;	/* associated report */
 	unsigned index;			/* index into report->field[] */
+	/* hidinput data */
+	struct hid_input *hidinput;	/* associated input structure */
+	__u16 dpad;			/* dpad input code */
 };
 
 #define HID_MAX_FIELDS 64
@@ -423,6 +461,7 @@
 #define hid_dump_device(c)	do { } while (0)
 #define hid_dump_field(a,b)	do { } while (0)
 #define resolv_usage(a)		do { } while (0)
+#define resolv_event(a,b)	do { } while (0)
 #endif
 
 #endif
@@ -430,7 +469,7 @@
 #ifdef CONFIG_USB_HIDINPUT
 /* Applications from HID Usage Tables 4/8/99 Version 1.1 */
 /* We ignore a few input applications that are not widely used */
-#define IS_INPUT_APPLICATION(a) (((a >= 0x00010000) && (a <= 0x00010008)) || ( a == 0x00010080) || ( a == 0x000c0001))
+#define IS_INPUT_APPLICATION(a) (((a >= 0x00010000) && (a <= 0x00010008)) || (a == 0x00010080) || (a == 0x000c0001))
 extern void hidinput_hid_event(struct hid_device *, struct hid_field *, struct hid_usage *, __s32, struct pt_regs *regs);
 extern void hidinput_report_event(struct hid_device *hid, struct hid_report *report);
 extern int hidinput_connect(struct hid_device *);
diff -Nru a/drivers/usb/input/hiddev.c b/drivers/usb/input/hiddev.c
--- a/drivers/usb/input/hiddev.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/usb/input/hiddev.c	2005-03-01 23:38:56 -08:00
@@ -423,9 +423,9 @@
 		dinfo.busnum = dev->bus->busnum;
 		dinfo.devnum = dev->devnum;
 		dinfo.ifnum = hid->ifnum;
-		dinfo.vendor = dev->descriptor.idVendor;
-		dinfo.product = dev->descriptor.idProduct;
-		dinfo.version = dev->descriptor.bcdDevice;
+		dinfo.vendor = le16_to_cpu(dev->descriptor.idVendor);
+		dinfo.product = le16_to_cpu(dev->descriptor.idProduct);
+		dinfo.version = le16_to_cpu(dev->descriptor.bcdDevice);
 		dinfo.num_applications = hid->maxapplication;
 		if (copy_to_user(user_arg, &dinfo, sizeof(dinfo)))
 			return -EFAULT;
diff -Nru a/drivers/usb/input/kbtab.c b/drivers/usb/input/kbtab.c
--- a/drivers/usb/input/kbtab.c	2005-03-01 23:38:44 -08:00
+++ b/drivers/usb/input/kbtab.c	2005-03-01 23:38:44 -08:00
@@ -175,9 +175,9 @@
 	kbtab->dev.name = "KB Gear Tablet";
 	kbtab->dev.phys = kbtab->phys;
 	kbtab->dev.id.bustype = BUS_USB;
-	kbtab->dev.id.vendor = dev->descriptor.idVendor;
-	kbtab->dev.id.product = dev->descriptor.idProduct;
-	kbtab->dev.id.version = dev->descriptor.bcdDevice;
+	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);
 	kbtab->dev.dev = &intf->dev;
 	kbtab->usbdev = dev;
 
diff -Nru a/drivers/usb/input/mtouchusb.c b/drivers/usb/input/mtouchusb.c
--- a/drivers/usb/input/mtouchusb.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/usb/input/mtouchusb.c	2005-03-01 23:38:58 -08:00
@@ -223,9 +223,9 @@
         mtouch->input.name = mtouch->name;
         mtouch->input.phys = mtouch->phys;
         mtouch->input.id.bustype = BUS_USB;
-        mtouch->input.id.vendor = udev->descriptor.idVendor;
-        mtouch->input.id.product = udev->descriptor.idProduct;
-        mtouch->input.id.version = udev->descriptor.bcdDevice;
+        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);
diff -Nru a/drivers/usb/input/powermate.c b/drivers/usb/input/powermate.c
--- a/drivers/usb/input/powermate.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/usb/input/powermate.c	2005-03-01 23:38:58 -08:00
@@ -375,12 +375,13 @@
 		return -EIO; /* failure */
 	}
 
-	switch (udev->descriptor.idProduct) {
+	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: 
-	  pm->input.name = pm_name_soundknob;
-	  printk(KERN_WARNING "powermate: unknown product id %04x\n", udev->descriptor.idProduct);
+		pm->input.name = pm_name_soundknob;
+		printk(KERN_WARNING "powermate: unknown product id %04x\n",
+		       le16_to_cpu(udev->descriptor.idProduct));
 	}
 
 	pm->input.private = pm;
@@ -389,9 +390,9 @@
 	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 = udev->descriptor.idVendor;
-	pm->input.id.product = udev->descriptor.idProduct;
-	pm->input.id.version = udev->descriptor.bcdDevice;
+	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);
 	pm->input.event = powermate_input_event;
 	pm->input.dev = &intf->dev;
 
diff -Nru a/drivers/usb/input/touchkitusb.c b/drivers/usb/input/touchkitusb.c
--- a/drivers/usb/input/touchkitusb.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/usb/input/touchkitusb.c	2005-03-01 23:38:53 -08:00
@@ -211,9 +211,9 @@
 	touchkit->input.name = touchkit->name;
 	touchkit->input.phys = touchkit->phys;
 	touchkit->input.id.bustype = BUS_USB;
-	touchkit->input.id.vendor = udev->descriptor.idVendor;
-	touchkit->input.id.product = udev->descriptor.idProduct;
-	touchkit->input.id.version = udev->descriptor.bcdDevice;
+	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);
 	touchkit->input.dev = &intf->dev;
 
 	touchkit->input.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
diff -Nru a/drivers/usb/input/usbkbd.c b/drivers/usb/input/usbkbd.c
--- a/drivers/usb/input/usbkbd.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/usb/input/usbkbd.c	2005-03-01 23:39:16 -08:00
@@ -296,9 +296,9 @@
 	kbd->dev.name = kbd->name;
 	kbd->dev.phys = kbd->phys;	
 	kbd->dev.id.bustype = BUS_USB;
-	kbd->dev.id.vendor = dev->descriptor.idVendor;
-	kbd->dev.id.product = dev->descriptor.idProduct;
-	kbd->dev.id.version = dev->descriptor.bcdDevice;
+	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.dev = &iface->dev;
 
 	if (!(buf = kmalloc(63, GFP_KERNEL))) {
diff -Nru a/drivers/usb/input/usbmouse.c b/drivers/usb/input/usbmouse.c
--- a/drivers/usb/input/usbmouse.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/usb/input/usbmouse.c	2005-03-01 23:39:16 -08:00
@@ -180,9 +180,9 @@
 	mouse->dev.name = mouse->name;
 	mouse->dev.phys = mouse->phys;
 	mouse->dev.id.bustype = BUS_USB;
-	mouse->dev.id.vendor = dev->descriptor.idVendor;
-	mouse->dev.id.product = dev->descriptor.idProduct;
-	mouse->dev.id.version = dev->descriptor.bcdDevice;
+	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);
 	mouse->dev.dev = &intf->dev;
 
 	if (!(buf = kmalloc(63, GFP_KERNEL))) {
diff -Nru a/drivers/usb/input/wacom.c b/drivers/usb/input/wacom.c
--- a/drivers/usb/input/wacom.c	2005-03-01 23:38:51 -08:00
+++ b/drivers/usb/input/wacom.c	2005-03-01 23:38:51 -08:00
@@ -692,9 +692,9 @@
 	wacom->dev.name = wacom->features->name;
 	wacom->dev.phys = wacom->phys;
 	wacom->dev.id.bustype = BUS_USB;
-	wacom->dev.id.vendor = dev->descriptor.idVendor;
-	wacom->dev.id.product = dev->descriptor.idProduct;
-	wacom->dev.id.version = dev->descriptor.bcdDevice;
+	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);
 	wacom->dev.dev = &intf->dev;
 	wacom->usbdev = dev;
 
diff -Nru a/drivers/usb/input/xpad.c b/drivers/usb/input/xpad.c
--- a/drivers/usb/input/xpad.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/usb/input/xpad.c	2005-03-01 23:38:57 -08:00
@@ -226,8 +226,8 @@
 	int i;
 	
 	for (i = 0; xpad_device[i].idVendor; i++) {
-		if ((udev->descriptor.idVendor == xpad_device[i].idVendor) &&
-		    (udev->descriptor.idProduct == xpad_device[i].idProduct))
+		if ((le16_to_cpu(udev->descriptor.idVendor) == xpad_device[i].idVendor) &&
+		    (le16_to_cpu(udev->descriptor.idProduct) == xpad_device[i].idProduct))
 			break;
 	}
 	
@@ -264,9 +264,9 @@
 	xpad->udev = udev;
 	
 	xpad->dev.id.bustype = BUS_USB;
-	xpad->dev.id.vendor = udev->descriptor.idVendor;
-	xpad->dev.id.product = udev->descriptor.idProduct;
-	xpad->dev.id.version = udev->descriptor.bcdDevice;
+	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);
 	xpad->dev.dev = &intf->dev;
 	xpad->dev.private = xpad;
 	xpad->dev.name = xpad_device[i].name;
diff -Nru a/drivers/usb/media/Makefile b/drivers/usb/media/Makefile
--- a/drivers/usb/media/Makefile	2005-03-01 23:38:44 -08:00
+++ b/drivers/usb/media/Makefile	2005-03-01 23:38:44 -08:00
@@ -2,7 +2,7 @@
 # Makefile for USB Media drivers
 #
 
-sn9c102-objs	:= sn9c102_core.o sn9c102_pas106b.o sn9c102_tas5110c1b.o sn9c102_tas5130d1b.o sn9c102_pas202bcb.o
+sn9c102-objs	:= sn9c102_core.o sn9c102_hv7131d.o sn9c102_mi0343.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 -Nru a/drivers/usb/media/dabusb.c b/drivers/usb/media/dabusb.c
--- a/drivers/usb/media/dabusb.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/usb/media/dabusb.c	2005-03-01 23:38:58 -08:00
@@ -724,13 +724,16 @@
 	pdabusb_t s;
 
 	dbg("dabusb: probe: vendor id 0x%x, device id 0x%x ifnum:%d",
-	  usbdev->descriptor.idVendor, usbdev->descriptor.idProduct, intf->altsetting->desc.bInterfaceNumber);
+	    le16_to_cpu(usbdev->descriptor.idVendor),
+	    le16_to_cpu(usbdev->descriptor.idProduct),
+	    intf->altsetting->desc.bInterfaceNumber);
 
 	/* We don't handle multiple configurations */
 	if (usbdev->descriptor.bNumConfigurations != 1)
 		return -ENODEV;
 
-	if (intf->altsetting->desc.bInterfaceNumber != _DABUSB_IF && usbdev->descriptor.idProduct == 0x9999)
+	if (intf->altsetting->desc.bInterfaceNumber != _DABUSB_IF &&
+	    le16_to_cpu(usbdev->descriptor.idProduct) == 0x9999)
 		return -ENODEV;
 
 
@@ -746,7 +749,7 @@
 		err("reset_configuration failed");
 		goto reject;
 	}
-	if (usbdev->descriptor.idProduct == 0x2131) {
+	if (le16_to_cpu(usbdev->descriptor.idProduct) == 0x2131) {
 		dabusb_loadmem (s, NULL);
 		goto reject;
 	}
diff -Nru a/drivers/usb/media/ibmcam.c b/drivers/usb/media/ibmcam.c
--- a/drivers/usb/media/ibmcam.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/usb/media/ibmcam.c	2005-03-01 23:38:54 -08:00
@@ -3659,17 +3659,8 @@
 	if (dev->descriptor.bNumConfigurations != 1)
 		return -ENODEV;
 
-	/* Is it an IBM camera? */
-	if (dev->descriptor.idVendor != IBMCAM_VENDOR_ID)
-		return -ENODEV;
-	if ((dev->descriptor.idProduct != IBMCAM_PRODUCT_ID) &&
-	    (dev->descriptor.idProduct != VEO_800C_PRODUCT_ID) &&
-	    (dev->descriptor.idProduct != VEO_800D_PRODUCT_ID) &&
-	    (dev->descriptor.idProduct != NETCAM_PRODUCT_ID))
-		return -ENODEV;
-
 	/* Check the version/revision */
-	switch (dev->descriptor.bcdDevice) {
+	switch (le16_to_cpu(dev->descriptor.bcdDevice)) {
 	case 0x0002:
 		if (ifnum != 2)
 			return -ENODEV;
@@ -3678,8 +3669,8 @@
 	case 0x030A:
 		if (ifnum != 0)
 			return -ENODEV;
-		if ((dev->descriptor.idProduct == NETCAM_PRODUCT_ID) ||
-		    (dev->descriptor.idProduct == VEO_800D_PRODUCT_ID))
+		if ((le16_to_cpu(dev->descriptor.idProduct) == NETCAM_PRODUCT_ID) ||
+		    (le16_to_cpu(dev->descriptor.idProduct) == VEO_800D_PRODUCT_ID))
 			model = IBMCAM_MODEL_4;
 		else
 			model = IBMCAM_MODEL_2;
@@ -3691,14 +3682,14 @@
 		break;
 	default:
 		err("IBM camera with revision 0x%04x is not supported.",
-			dev->descriptor.bcdDevice);
+			le16_to_cpu(dev->descriptor.bcdDevice));
 		return -ENODEV;
 	}
 
 	/* Print detailed info on what we found so far */
 	do {
 		char *brand = NULL;
-		switch (dev->descriptor.idProduct) {
+		switch (le16_to_cpu(dev->descriptor.idProduct)) {
 		case NETCAM_PRODUCT_ID:
 			brand = "IBM NetCamera";
 			break;
@@ -3714,7 +3705,7 @@
 			break;
 		}
 		info("%s USB camera found (model %d, rev. 0x%04x)",
-		     brand, model, dev->descriptor.bcdDevice);
+		     brand, model, le16_to_cpu(dev->descriptor.bcdDevice));
 	} while (0);
 
 	/* Validate found interface: must have one ISO endpoint */
@@ -3752,7 +3743,7 @@
 			err("Interface %d. has ISO OUT endpoint!", ifnum);
 			return -ENODEV;
 		}
-		if (endpoint->wMaxPacketSize == 0) {
+		if (le16_to_cpu(endpoint->wMaxPacketSize) == 0) {
 			if (inactInterface < 0)
 				inactInterface = i;
 			else {
@@ -3762,7 +3753,7 @@
 		} else {
 			if (actInterface < 0) {
 				actInterface = i;
-				maxPS = endpoint->wMaxPacketSize;
+				maxPS = le16_to_cpu(endpoint->wMaxPacketSize);
 				if (debug > 0)
 					info("Active setting=%d. maxPS=%d.", i, maxPS);
 			} else
diff -Nru a/drivers/usb/media/konicawc.c b/drivers/usb/media/konicawc.c
--- a/drivers/usb/media/konicawc.c	2005-03-01 23:38:44 -08:00
+++ b/drivers/usb/media/konicawc.c	2005-03-01 23:38:44 -08:00
@@ -390,7 +390,7 @@
 				spd_to_iface[cam->speed]);
 	if (!interface)
 		return -ENXIO;
-	pktsz = interface->endpoint[1].desc.wMaxPacketSize;
+	pktsz = le16_to_cpu(interface->endpoint[1].desc.wMaxPacketSize);
 	DEBUG(1, "pktsz = %d", pktsz);
 	if (!CAMERA_IS_OPERATIONAL(uvd)) {
 		err("Camera is not operational");
@@ -732,7 +732,7 @@
 	if (dev->descriptor.bNumConfigurations != 1)
 		return -ENODEV;
 
-	info("Konica Webcam (rev. 0x%04x)", dev->descriptor.bcdDevice);
+	info("Konica Webcam (rev. 0x%04x)", le16_to_cpu(dev->descriptor.bcdDevice));
 	RESTRICT_TO_RANGE(speed, 0, MAX_SPEED);
 
 	/* Validate found interface: must have one ISO endpoint */
@@ -756,7 +756,7 @@
 		}
 		endpoint = &interface->endpoint[1].desc;
 		DEBUG(1, "found endpoint: addr: 0x%2.2x maxps = 0x%4.4x",
-		    endpoint->bEndpointAddress, endpoint->wMaxPacketSize);
+		    endpoint->bEndpointAddress, le16_to_cpu(endpoint->wMaxPacketSize));
 		if (video_ep == 0)
 			video_ep = endpoint->bEndpointAddress;
 		else if (video_ep != endpoint->bEndpointAddress) {
@@ -773,7 +773,7 @@
 			    interface->desc.bInterfaceNumber);
 			return -ENODEV;
 		}
-		if (endpoint->wMaxPacketSize == 0) {
+		if (le16_to_cpu(endpoint->wMaxPacketSize) == 0) {
 			if (inactInterface < 0)
 				inactInterface = i;
 			else {
@@ -786,8 +786,8 @@
 				actInterface = i;
 			}
 		}
-		if(endpoint->wMaxPacketSize > maxPS)
-			maxPS = endpoint->wMaxPacketSize;
+		if (le16_to_cpu(endpoint->wMaxPacketSize) > maxPS)
+			maxPS = le16_to_cpu(endpoint->wMaxPacketSize);
 	}
 	if(actInterface == -1) {
 		err("Cant find required endpoint");
@@ -846,9 +846,9 @@
 		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 = dev->descriptor.idVendor;
-		cam->input.id.product = dev->descriptor.idProduct;
-		cam->input.id.version = dev->descriptor.bcdDevice;
+		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);
 		input_register_device(&cam->input);
 		
 		usb_make_path(dev, cam->input_physname, 56);
diff -Nru a/drivers/usb/media/ov511.c b/drivers/usb/media/ov511.c
--- a/drivers/usb/media/ov511.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/usb/media/ov511.c	2005-03-01 23:38:54 -08:00
@@ -3908,15 +3908,11 @@
 		ov->fbuf = NULL;
 	}
 
-	if (ov->rawfbuf) {
-		vfree(ov->rawfbuf);
-		ov->rawfbuf = NULL;
-	}
+	vfree(ov->rawfbuf);
+	ov->rawfbuf = NULL;
 
-	if (ov->tempfbuf) {
-		vfree(ov->tempfbuf);
-		ov->tempfbuf = NULL;
-	}
+	vfree(ov->tempfbuf);
+	ov->tempfbuf = NULL;
 
 	for (i = 0; i < OV511_NUMSBUF; i++) {
 		if (ov->sbuf[i].data) {
@@ -5596,7 +5592,7 @@
 		if (ifp) {
 			alt = usb_altnum_to_altsetting(ifp, 7);
 			if (alt)
-				mxps = alt->endpoint[0].desc.wMaxPacketSize;
+				mxps = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
 		}
 
 		/* Some OV518s have packet numbering by default, some don't */
@@ -5825,7 +5821,7 @@
 	ov->auto_gain = autogain;
 	ov->auto_exp = autoexp;
 
-	switch (dev->descriptor.idProduct) {
+	switch (le16_to_cpu(dev->descriptor.idProduct)) {
 	case PROD_OV511:
 		ov->bridge = BRG_OV511;
 		ov->bclass = BCL_OV511;
@@ -5843,13 +5839,13 @@
 		ov->bclass = BCL_OV518;
 		break;
 	case PROD_ME2CAM:
-		if (dev->descriptor.idVendor != VEND_MATTEL)
+		if (le16_to_cpu(dev->descriptor.idVendor) != VEND_MATTEL)
 			goto error;
 		ov->bridge = BRG_OV511PLUS;
 		ov->bclass = BCL_OV511;
 		break;
 	default:
-		err("Unknown product ID 0x%04x", dev->descriptor.idProduct);
+		err("Unknown product ID 0x%04x", le16_to_cpu(dev->descriptor.idProduct));
 		goto error;
 	}
 
diff -Nru a/drivers/usb/media/se401.c b/drivers/usb/media/se401.c
--- a/drivers/usb/media/se401.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/usb/media/se401.c	2005-03-01 23:38:54 -08:00
@@ -1315,20 +1315,20 @@
         interface = &intf->cur_altsetting->desc;
 
         /* Is it an se401? */
-        if (dev->descriptor.idVendor == 0x03e8 &&
-            dev->descriptor.idProduct == 0x0004) {
+        if (le16_to_cpu(dev->descriptor.idVendor) == 0x03e8 &&
+            le16_to_cpu(dev->descriptor.idProduct) == 0x0004) {
                 camera_name="Endpoints/Aox SE401";
-        } else if (dev->descriptor.idVendor == 0x0471 &&
-            dev->descriptor.idProduct == 0x030b) {
+        } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x0471 &&
+            le16_to_cpu(dev->descriptor.idProduct) == 0x030b) {
                 camera_name="Philips PCVC665K";
-        } else if (dev->descriptor.idVendor == 0x047d &&
-	    dev->descriptor.idProduct == 0x5001) {
+        } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x047d &&
+	    le16_to_cpu(dev->descriptor.idProduct) == 0x5001) {
 		camera_name="Kensington VideoCAM 67014";
-        } else if (dev->descriptor.idVendor == 0x047d &&
-	    dev->descriptor.idProduct == 0x5002) {
+        } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x047d &&
+	    le16_to_cpu(dev->descriptor.idProduct) == 0x5002) {
 		camera_name="Kensington VideoCAM 6701(5/7)";
-        } else if (dev->descriptor.idVendor == 0x047d &&
-	    dev->descriptor.idProduct == 0x5003) {
+        } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x047d &&
+	    le16_to_cpu(dev->descriptor.idProduct) == 0x5003) {
 		camera_name="Kensington VideoCAM 67016";
 		button=0;
 	} else
@@ -1354,7 +1354,7 @@
         se401->iface = interface->bInterfaceNumber;
         se401->camera_name = camera_name;
 
-	info("firmware version: %02x", dev->descriptor.bcdDevice & 255);
+	info("firmware version: %02x", le16_to_cpu(dev->descriptor.bcdDevice) & 255);
 
         if (se401_init(se401, button)) {
 		kfree(se401);
diff -Nru a/drivers/usb/media/sn9c102.h b/drivers/usb/media/sn9c102.h
--- a/drivers/usb/media/sn9c102.h	2005-03-01 23:38:57 -08:00
+++ b/drivers/usb/media/sn9c102.h	2005-03-01 23:38:57 -08:00
@@ -1,7 +1,7 @@
 /***************************************************************************
  * V4L2 driver for SN9C10x PC Camera Controllers                           *
  *                                                                         *
- * Copyright (C) 2004 by Luca Risolia <luca.risolia@studio.unibo.it>       *
+ * Copyright (C) 2004-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    *
@@ -42,12 +42,13 @@
 #define SN9C102_DEBUG_LEVEL       2
 #define SN9C102_MAX_DEVICES       64
 #define SN9C102_PRESERVE_IMGSCALE 0
+#define SN9C102_FORCE_MUNMAP      0
 #define SN9C102_MAX_FRAMES        32
 #define SN9C102_URBS              2
 #define SN9C102_ISO_PACKETS       7
 #define SN9C102_ALTERNATE_SETTING 8
-#define SN9C102_URB_TIMEOUT       msecs_to_jiffies(3)
-#define SN9C102_CTRL_TIMEOUT      msecs_to_jiffies(100)
+#define SN9C102_URB_TIMEOUT       msecs_to_jiffies(2 * SN9C102_ISO_PACKETS)
+#define SN9C102_CTRL_TIMEOUT      msecs_to_jiffies(300)
 
 /*****************************************************************************/
 
@@ -55,8 +56,8 @@
 #define SN9C102_MODULE_AUTHOR   "(C) 2004 Luca Risolia"
 #define SN9C102_AUTHOR_EMAIL    "<luca.risolia@studio.unibo.it>"
 #define SN9C102_MODULE_LICENSE  "GPL"
-#define SN9C102_MODULE_VERSION  "1:1.19"
-#define SN9C102_MODULE_VERSION_CODE  KERNEL_VERSION(1, 0, 19)
+#define SN9C102_MODULE_VERSION  "1:1.22"
+#define SN9C102_MODULE_VERSION_CODE  KERNEL_VERSION(1, 0, 22)
 
 enum sn9c102_bridge {
 	BRIDGE_SN9C101 = 0x01,
@@ -101,8 +102,16 @@
 	STREAM_ON,
 };
 
+typedef char sn9c102_sof_header_t[12];
+typedef char sn9c102_eof_header_t[4];
+
 struct sn9c102_sysfs_attr {
 	u8 reg, i2c_reg;
+	sn9c102_sof_header_t frame_header;
+};
+
+struct sn9c102_module_param {
+	u8 force_munmap;
 };
 
 static DECLARE_MUTEX(sn9c102_sysfs_lock);
@@ -131,7 +140,10 @@
 	struct v4l2_jpegcompression compression;
 
 	struct sn9c102_sysfs_attr sysfs;
+	sn9c102_sof_header_t sof_header;
 	u16 reg[32];
+
+	struct sn9c102_module_param module_param;
 
 	enum sn9c102_dev_state state;
 	u8 users;
diff -Nru a/drivers/usb/media/sn9c102_core.c b/drivers/usb/media/sn9c102_core.c
--- a/drivers/usb/media/sn9c102_core.c	2005-03-01 23:38:51 -08:00
+++ b/drivers/usb/media/sn9c102_core.c	2005-03-01 23:38:51 -08:00
@@ -1,7 +1,7 @@
 /***************************************************************************
  * V4L2 driver for SN9C10x PC Camera Controllers                           *
  *                                                                         *
- * Copyright (C) 2004 by Luca Risolia <luca.risolia@studio.unibo.it>       *
+ * Copyright (C) 2004-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    *
@@ -37,6 +37,7 @@
 #include <linux/mm.h>
 #include <linux/vmalloc.h>
 #include <linux/page-flags.h>
+#include <linux/byteorder/generic.h>
 #include <asm/page.h>
 #include <asm/uaccess.h>
 
@@ -65,6 +66,20 @@
                  "\none and for every other camera."
                  "\n");
 
+static short force_munmap[] = {[0 ... SN9C102_MAX_DEVICES-1] = 
+                               SN9C102_FORCE_MUNMAP};
+module_param_array(force_munmap, bool, NULL, 0444);
+MODULE_PARM_DESC(force_munmap,
+                 "\n<0|1[,...]> Force the application to unmap previously "
+                 "\nmapped buffer memory before calling any VIDIOC_S_CROP or "
+                 "\nVIDIOC_S_FMT ioctl's. Not all the applications support "
+                 "\nthis feature. This parameter is specific for each "
+                 "\ndetected camera."
+                 "\n 0 = do not force memory unmapping"
+                 "\n 1 = force memory unmapping (save memory)"
+                 "\nDefault value is "__MODULE_STRING(SN9C102_FORCE_MUNMAP)"."
+                 "\n");
+
 #ifdef SN9C102_DEBUG
 static unsigned short debug = SN9C102_DEBUG_LEVEL;
 module_param(debug, ushort, 0644);
@@ -82,9 +97,6 @@
 
 /*****************************************************************************/
 
-typedef char sn9c102_sof_header_t[12];
-typedef char sn9c102_eof_header_t[4];
-
 static sn9c102_sof_header_t sn9c102_sof_header[] = {
 	{0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96, 0x00},
 	{0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96, 0x01},
@@ -144,10 +156,16 @@
 }
 
 
-static u32 sn9c102_request_buffers(struct sn9c102_device* cam, u32 count)
+static u32 
+sn9c102_request_buffers(struct sn9c102_device* cam, u32 count, 
+                        enum sn9c102_io_method io)
 {
 	struct v4l2_pix_format* p = &(cam->sensor->pix_format);
-	const size_t imagesize = (p->width * p->height * p->priv)/8;
+	struct v4l2_rect* r = &(cam->sensor->cropcap.bounds);
+	const size_t imagesize = cam->module_param.force_munmap ||
+	                         io == IO_READ ?
+	                         (p->width * p->height * p->priv)/8 :
+	                         (r->width * r->height * p->priv)/8;
 	void* buff = NULL;
 	u32 i;
 
@@ -277,9 +295,9 @@
 		if (r & 0x04)
 			return 0;
 		if (sensor->frequency & SN9C102_I2C_400KHZ)
-			udelay(5*8);
+			udelay(5*16);
 		else
-			udelay(16*8);
+			udelay(16*16);
 	}
 	return -EBUSY;
 }
@@ -306,18 +324,19 @@
 
 
 int 
-sn9c102_i2c_try_read(struct sn9c102_device* cam,
-                     struct sn9c102_sensor* sensor, u8 address)
+sn9c102_i2c_try_raw_read(struct sn9c102_device* cam,
+                         struct sn9c102_sensor* sensor, u8 data0, u8 data1,
+                         u8 n, u8 buffer[])
 {
 	struct usb_device* udev = cam->usbdev;
 	u8* data = cam->control_buffer;
 	int err = 0, res;
 
-	/* Write cycle - address */
+	/* Write cycle */
 	data[0] = ((sensor->interface == SN9C102_I2C_2WIRES) ? 0x80 : 0) |
 	          ((sensor->frequency & SN9C102_I2C_400KHZ) ? 0x01 : 0) | 0x10;
-	data[1] = sensor->slave_write_id;
-	data[2] = address;
+	data[1] = data0; /* I2C slave id */
+	data[2] = data1; /* address */
 	data[7] = 0x10;
 	res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x08, 0x41,
 	                      0x08, 0, data, 8, SN9C102_CTRL_TIMEOUT);
@@ -326,11 +345,11 @@
 
 	err += sn9c102_i2c_wait(cam, sensor);
 
-	/* Read cycle - 1 byte */
+	/* Read cycle - n bytes */
 	data[0] = ((sensor->interface == SN9C102_I2C_2WIRES) ? 0x80 : 0) |
 	          ((sensor->frequency & SN9C102_I2C_400KHZ) ? 0x01 : 0) |
-	          0x10 | 0x02;
-	data[1] = sensor->slave_read_id;
+	          (n << 4) | 0x02;
+	data[1] = data0;
 	data[7] = 0x10;
 	res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x08, 0x41,
 	                      0x08, 0, data, 8, SN9C102_CTRL_TIMEOUT);
@@ -339,7 +358,7 @@
 
 	err += sn9c102_i2c_wait(cam, sensor);
 
-	/* The read byte will be placed in data[4] */
+	/* The first read byte will be placed in data[4] */
 	res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x00, 0xc1,
 	                      0x0a, 0, data, 5, SN9C102_CTRL_TIMEOUT);
 	if (res < 0)
@@ -347,12 +366,18 @@
 
 	err += sn9c102_i2c_detect_read_error(cam, sensor);
 
-	if (err)
+	PDBGG("I2C read: address 0x%02X, first read byte: 0x%02X", data1,
+	      data[4])
+
+	if (err) {
 		DBG(3, "I2C read failed for %s image sensor", sensor->name)
+		return -1;
+	}
 
-	PDBGG("I2C read: address 0x%02X, value: 0x%02X", address, data[4])
+	if (buffer)
+		memcpy(buffer, data, sizeof(buffer));
 
-	return err ? -1 : (int)data[4];
+	return (int)data[4];
 }
 
 
@@ -395,12 +420,21 @@
 }
 
 
+int
+sn9c102_i2c_try_read(struct sn9c102_device* cam,
+                     struct sn9c102_sensor* sensor, u8 address)
+{
+	return sn9c102_i2c_try_raw_read(cam, sensor, sensor->i2c_slave_id,
+	                                address, 1, NULL);
+}
+
+
 int 
 sn9c102_i2c_try_write(struct sn9c102_device* cam,
                       struct sn9c102_sensor* sensor, u8 address, u8 value)
 {
 	return sn9c102_i2c_try_raw_write(cam, sensor, 3, 
-	                                 sensor->slave_write_id, address,
+	                                 sensor->i2c_slave_id, address,
 	                                 value, 0, 0, 0);
 }
 
@@ -433,9 +467,11 @@
 	for (i = 0; (len >= soflen) && (i <= len - soflen); i++)
 		for (j = 0; j < n; j++)
 			/* It's enough to compare 7 bytes */
-			if (!memcmp(mem + i, sn9c102_sof_header[j], 7))
-				/* Skips the header */
+			if (!memcmp(mem + i, sn9c102_sof_header[j], 7)) {
+				memcpy(cam->sof_header, mem + i, soflen);
+				/* Skip the header */
 				return mem + i + soflen;
+			}
 
 	return NULL;
 }
@@ -563,6 +599,9 @@
 						(*f) = NULL;
 					spin_unlock_irqrestore(&cam->queue_lock
 					                       , lock_flags);
+					memcpy(cam->sysfs.frame_header,
+					       cam->sof_header,
+					       sizeof(sn9c102_sof_header_t));
 					DBG(3, "Video frame captured: "
 					       "%lu bytes", (unsigned long)(b))
 
@@ -746,15 +785,14 @@
 	                         (cam->stream == STREAM_OFF) ||
 	                         (cam->state & DEV_DISCONNECTED),
 	                         SN9C102_URB_TIMEOUT);
-	if (err) {
+	if (cam->state & DEV_DISCONNECTED)
+		return -ENODEV;
+	else if (err) {
 		cam->state |= DEV_MISCONFIGURED;
-		DBG(1, "The camera is misconfigured. To use "
-		       "it, close and open /dev/video%d "
-		       "again.", cam->v4ldev->minor)
+		DBG(1, "The camera is misconfigured. To use it, close and "
+		       "open /dev/video%d again.", cam->v4ldev->minor)
 		return err;
 	}
-	if (cam->state & DEV_DISCONNECTED)
-		return -ENODEV;
 
 	return 0;
 }
@@ -937,7 +975,7 @@
 	up(&sn9c102_sysfs_lock);
 
 	return count;
-} 
+}
 
 
 static ssize_t 
@@ -988,7 +1026,7 @@
 		return -ENODEV;
 	}
 
-	if (cam->sensor->slave_read_id == SN9C102_I2C_SLAVEID_UNAVAILABLE) {
+	if (!(cam->sensor->sysfs_ops & SN9C102_I2C_READ)) {
 		up(&sn9c102_sysfs_lock);
 		return -ENOSYS;
 	}
@@ -1025,6 +1063,11 @@
 		return -ENODEV;
 	}
 
+	if (!(cam->sensor->sysfs_ops & SN9C102_I2C_WRITE)) {
+		up(&sn9c102_sysfs_lock);
+		return -ENOSYS;
+	}
+
 	value = sn9c102_strtou8(buf, len, &count);
 	if (!count) {
 		up(&sn9c102_sysfs_lock);
@@ -1129,6 +1172,24 @@
 }
 
 
+static ssize_t sn9c102_show_frame_header(struct class_device* cd, char* buf)
+{
+	struct sn9c102_device* cam;
+	ssize_t count;
+
+	cam = video_get_drvdata(to_video_device(cd));
+	if (!cam)
+		return -ENODEV;
+
+	count = sizeof(cam->sysfs.frame_header);
+	memcpy(buf, cam->sysfs.frame_header, count);
+
+	DBG(3, "Frame header, read bytes: %zd", count)
+
+	return count;
+} 
+
+
 static CLASS_DEVICE_ATTR(reg, S_IRUGO | S_IWUSR,
                          sn9c102_show_reg, sn9c102_store_reg);
 static CLASS_DEVICE_ATTR(val, S_IRUGO | S_IWUSR,
@@ -1140,6 +1201,8 @@
 static CLASS_DEVICE_ATTR(green, S_IWUGO, NULL, sn9c102_store_green);
 static CLASS_DEVICE_ATTR(blue, S_IWUGO, NULL, sn9c102_store_blue);
 static CLASS_DEVICE_ATTR(red, S_IWUGO, NULL, sn9c102_store_red);
+static CLASS_DEVICE_ATTR(frame_header, S_IRUGO,
+                         sn9c102_show_frame_header, NULL);
 
 
 static void sn9c102_create_sysfs(struct sn9c102_device* cam)
@@ -1148,14 +1211,14 @@
 
 	video_device_create_file(v4ldev, &class_device_attr_reg);
 	video_device_create_file(v4ldev, &class_device_attr_val);
+	video_device_create_file(v4ldev, &class_device_attr_frame_header);
 	if (cam->bridge == BRIDGE_SN9C101 || cam->bridge == BRIDGE_SN9C102)
 		video_device_create_file(v4ldev, &class_device_attr_green);
 	else if (cam->bridge == BRIDGE_SN9C103) {
 		video_device_create_file(v4ldev, &class_device_attr_blue);
 		video_device_create_file(v4ldev, &class_device_attr_red);
 	}
-	if (cam->sensor->slave_write_id != SN9C102_I2C_SLAVEID_UNAVAILABLE ||
-	    cam->sensor->slave_read_id != SN9C102_I2C_SLAVEID_UNAVAILABLE) {
+	if (cam->sensor->sysfs_ops) {
 		video_device_create_file(v4ldev, &class_device_attr_i2c_reg);
 		video_device_create_file(v4ldev, &class_device_attr_i2c_val);
 	}
@@ -1164,11 +1227,11 @@
 /*****************************************************************************/
 
 static int
-sn9c102_set_format(struct sn9c102_device* cam, struct v4l2_pix_format* fmt)
+sn9c102_set_pix_format(struct sn9c102_device* cam, struct v4l2_pix_format* pix)
 {
 	int err = 0;
 
-	if (fmt->pixelformat == V4L2_PIX_FMT_SN9C10X)
+	if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X)
 		err += sn9c102_write_reg(cam, cam->reg[0x18] | 0x80, 0x18);
 	else
 		err += sn9c102_write_reg(cam, cam->reg[0x18] & 0x7f, 0x18);
@@ -1273,7 +1336,9 @@
 		cam->compression.quality =  cam->reg[0x17] & 0x01 ? 0 : 1;
 	else
 		err += sn9c102_set_compression(cam, &cam->compression);
-	err += sn9c102_set_format(cam, &s->pix_format);
+	err += sn9c102_set_pix_format(cam, &s->pix_format);
+	if (s->set_pix_format)
+		err += s->set_pix_format(cam, &s->pix_format);
 	if (err)
 		return err;
 
@@ -1470,7 +1535,7 @@
 	}
 
 	if (cam->io == IO_NONE) {
-		if (!sn9c102_request_buffers(cam, cam->nreadbuffers)) {
+		if (!sn9c102_request_buffers(cam,cam->nreadbuffers, IO_READ)) {
 			DBG(1, "read() failed, not enough memory")
 			up(&cam->fileop_sem);
 			return -ENOMEM;
@@ -1550,7 +1615,7 @@
 	}
 
 	if (cam->io == IO_NONE) {
-		if (!sn9c102_request_buffers(cam, 2)) {
+		if (!sn9c102_request_buffers(cam, 2, IO_READ)) {
 			DBG(1, "poll() failed, not enough memory")
 			goto error;
 		}
@@ -1767,6 +1832,7 @@
 		return err;
 	}
 
+	case VIDIOC_S_CTRL_OLD:
 	case VIDIOC_S_CTRL:
 	{
 		struct sn9c102_sensor* s = cam->sensor;
@@ -1851,12 +1917,13 @@
 		if (crop.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 			return -EINVAL;
 
-		for (i = 0; i < cam->nbuffers; i++)
-			if (cam->frame[i].vma_use_count) {
-				DBG(3, "VIDIOC_S_CROP failed. "
-				       "Unmap the buffers first.")
-				return -EINVAL;
-			}
+		if (cam->module_param.force_munmap)
+			for (i = 0; i < cam->nbuffers; i++)
+				if (cam->frame[i].vma_use_count) {
+					DBG(3, "VIDIOC_S_CROP failed. "
+					       "Unmap the buffers first.")
+					return -EINVAL;
+				}
 
 		/* Preserve R,G or B origin */
 		rect->left = (s->_rect.left & 1L) ?
@@ -1903,7 +1970,8 @@
 			return -EFAULT;
 		}
 
-		sn9c102_release_buffers(cam);
+		if (cam->module_param.force_munmap)
+			sn9c102_release_buffers(cam);
 
 		err = sn9c102_set_crop(cam, rect);
 		if (s->set_crop)
@@ -1922,7 +1990,9 @@
 		s->pix_format.height = rect->height/scale;
 		memcpy(&(s->_rect), rect, sizeof(*rect));
 
-		if (nbuffers != sn9c102_request_buffers(cam, nbuffers)) {
+		if (cam->module_param.force_munmap &&
+		    nbuffers != sn9c102_request_buffers(cam, nbuffers,
+		                                        cam->io)) {
 			cam->state |= DEV_MISCONFIGURED;
 			DBG(1, "VIDIOC_S_CROP failed because of not enough "
 			       "memory. To use the camera, close and open "
@@ -2059,12 +2129,13 @@
 			return 0;
 		}
 
-		for (i = 0; i < cam->nbuffers; i++)
-			if (cam->frame[i].vma_use_count) {
-				DBG(3, "VIDIOC_S_FMT failed. "
-				       "Unmap the buffers first.")
-				return -EINVAL;
-			}
+		if (cam->module_param.force_munmap)
+			for (i = 0; i < cam->nbuffers; i++)
+				if (cam->frame[i].vma_use_count) {
+					DBG(3, "VIDIOC_S_FMT failed. "
+					       "Unmap the buffers first.")
+					return -EINVAL;
+				}
 
 		if (cam->stream == STREAM_ON)
 			if ((err = sn9c102_stream_interrupt(cam)))
@@ -2075,10 +2146,13 @@
 			return -EFAULT;
 		}
 
-		sn9c102_release_buffers(cam);
+		if (cam->module_param.force_munmap)
+			sn9c102_release_buffers(cam);
 
-		err += sn9c102_set_format(cam, pix);
+		err += sn9c102_set_pix_format(cam, pix);
 		err += sn9c102_set_crop(cam, &rect);
+		if (s->set_pix_format)
+			err += s->set_pix_format(cam, pix);
 		if (s->set_crop)
 			err += s->set_crop(cam, &rect);
 		err += sn9c102_set_scale(cam, scale);
@@ -2094,7 +2168,9 @@
 		memcpy(pfmt, pix, sizeof(*pix));
 		memcpy(&(s->_rect), &rect, sizeof(rect));
 
-		if (nbuffers != sn9c102_request_buffers(cam, nbuffers)) {
+		if (cam->module_param.force_munmap &&
+		    nbuffers != sn9c102_request_buffers(cam, nbuffers,
+		                                        cam->io)) {
 			cam->state |= DEV_MISCONFIGURED;
 			DBG(1, "VIDIOC_S_FMT failed because of not enough "
 			       "memory. To use the camera, close and open "
@@ -2182,7 +2258,8 @@
 
 		sn9c102_release_buffers(cam);
 		if (rb.count)
-			rb.count = sn9c102_request_buffers(cam, rb.count);
+			rb.count = sn9c102_request_buffers(cam, rb.count,
+			                                   IO_MMAP);
 
 		if (copy_to_user(arg, &rb, sizeof(rb))) {
 			sn9c102_release_buffers(cam);
@@ -2356,6 +2433,7 @@
 		return 0;
 	}
 
+	case VIDIOC_S_PARM_OLD:
 	case VIDIOC_S_PARM:
 	{
 		struct v4l2_streamparm sp;
@@ -2450,8 +2528,10 @@
 
 	n = sizeof(sn9c102_id_table)/sizeof(sn9c102_id_table[0]);
 	for (i = 0; i < n-1; i++)
-		if (udev->descriptor.idVendor==sn9c102_id_table[i].idVendor &&
-		    udev->descriptor.idProduct==sn9c102_id_table[i].idProduct)
+		if (le16_to_cpu(udev->descriptor.idVendor) == 
+		    sn9c102_id_table[i].idVendor &&
+		    le16_to_cpu(udev->descriptor.idProduct) ==
+		    sn9c102_id_table[i].idProduct)
 			break;
 	if (i == n-1)
 		return -ENODEV;
@@ -2550,7 +2630,12 @@
 
 	DBG(2, "V4L2 device registered as /dev/video%d", cam->v4ldev->minor)
 
+	cam->module_param.force_munmap = force_munmap[dev_nr];
+
+	dev_nr = (dev_nr < SN9C102_MAX_DEVICES-1) ? dev_nr+1 : 0;
+
 	sn9c102_create_sysfs(cam);
+	DBG(2, "Optional device control through 'sysfs' interface ready")
 
 	usb_set_intfdata(intf, cam);
 
diff -Nru a/drivers/usb/media/sn9c102_hv7131d.c b/drivers/usb/media/sn9c102_hv7131d.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/usb/media/sn9c102_hv7131d.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,271 @@
+/***************************************************************************
+ * Plug-in for HV7131D image sensor connected to the SN9C10x PC Camera     *
+ * Controllers                                                             *
+ *                                                                         *
+ * Copyright (C) 2004-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 hv7131d;
+
+
+static int hv7131d_init(struct sn9c102_device* cam)
+{
+	int err = 0;
+
+	err += sn9c102_write_reg(cam, 0x00, 0x10);
+	err += sn9c102_write_reg(cam, 0x00, 0x11);
+	err += sn9c102_write_reg(cam, 0x00, 0x14);
+	err += sn9c102_write_reg(cam, 0x60, 0x17);
+	err += sn9c102_write_reg(cam, 0x0e, 0x18);
+	err += sn9c102_write_reg(cam, 0xf2, 0x19);
+
+	err += sn9c102_i2c_write(cam, 0x01, 0x04);
+	err += sn9c102_i2c_write(cam, 0x02, 0x00);
+	err += sn9c102_i2c_write(cam, 0x28, 0x00);
+
+	return err;
+}
+
+
+static int hv7131d_get_ctrl(struct sn9c102_device* cam, 
+                            struct v4l2_control* ctrl)
+{
+	switch (ctrl->id) {
+	case V4L2_CID_EXPOSURE:
+		{
+			int r1 = sn9c102_i2c_read(cam, 0x26),
+			    r2 = sn9c102_i2c_read(cam, 0x27);
+			if (r1 < 0 || r2 < 0)
+				return -EIO;
+			ctrl->value = (r1 << 8) | (r2 & 0xff);
+		}
+		return 0;
+	case V4L2_CID_RED_BALANCE:
+		if ((ctrl->value = sn9c102_i2c_read(cam, 0x31)) < 0)
+			return -EIO;
+		ctrl->value = 0x3f - (ctrl->value & 0x3f);
+		return 0;
+	case V4L2_CID_BLUE_BALANCE:
+		if ((ctrl->value = sn9c102_i2c_read(cam, 0x33)) < 0)
+			return -EIO;
+		ctrl->value = 0x3f - (ctrl->value & 0x3f);
+		return 0;
+	case SN9C102_V4L2_CID_GREEN_BALANCE:
+		if ((ctrl->value = sn9c102_i2c_read(cam, 0x32)) < 0)
+			return -EIO;
+		ctrl->value = 0x3f - (ctrl->value & 0x3f);
+		return 0;
+	case SN9C102_V4L2_CID_RESET_LEVEL:
+		if ((ctrl->value = sn9c102_i2c_read(cam, 0x30)) < 0)
+			return -EIO;
+		ctrl->value &= 0x3f;
+		return 0;
+	case SN9C102_V4L2_CID_PIXEL_BIAS_VOLTAGE:
+		if ((ctrl->value = sn9c102_i2c_read(cam, 0x34)) < 0)
+			return -EIO;
+		ctrl->value &= 0x07;
+		return 0;
+	default:
+		return -EINVAL;
+	}
+}
+
+
+static int hv7131d_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, 0x26, ctrl->value >> 8);
+		err += sn9c102_i2c_write(cam, 0x27, ctrl->value & 0xff);
+		break;
+	case V4L2_CID_RED_BALANCE:
+		err += sn9c102_i2c_write(cam, 0x31, 0x3f - ctrl->value);
+		break;
+	case V4L2_CID_BLUE_BALANCE:
+		err += sn9c102_i2c_write(cam, 0x33, 0x3f - ctrl->value);
+		break;
+	case SN9C102_V4L2_CID_GREEN_BALANCE:
+		err += sn9c102_i2c_write(cam, 0x32, 0x3f - ctrl->value);
+		break;
+	case SN9C102_V4L2_CID_RESET_LEVEL:
+		err += sn9c102_i2c_write(cam, 0x30, ctrl->value);
+		break;
+	case SN9C102_V4L2_CID_PIXEL_BIAS_VOLTAGE:
+		err += sn9c102_i2c_write(cam, 0x34, ctrl->value);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return err ? -EIO : 0;
+}
+
+
+static int hv7131d_set_crop(struct sn9c102_device* cam, 
+                            const struct v4l2_rect* rect)
+{
+	struct sn9c102_sensor* s = &hv7131d;
+	int err = 0;
+	u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 2,
+	   v_start = (u8)(rect->top - s->cropcap.bounds.top) + 2;
+
+	err += sn9c102_write_reg(cam, h_start, 0x12);
+	err += sn9c102_write_reg(cam, v_start, 0x13);
+
+	return err;
+}
+
+
+static int hv7131d_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, 0x42, 0x19);
+	else
+		err += sn9c102_write_reg(cam, 0xf2, 0x19);
+
+	return err;
+}
+
+
+static struct sn9c102_sensor hv7131d = {
+	.name = "HV7131D",
+	.maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
+	.sysfs_ops = SN9C102_I2C_READ | SN9C102_I2C_WRITE,
+	.frequency = SN9C102_I2C_100KHZ,
+	.interface = SN9C102_I2C_2WIRES,
+	.i2c_slave_id = 0x11,
+	.init = &hv7131d_init,
+	.qctrl = {
+		{
+			.id = V4L2_CID_EXPOSURE,
+			.type = V4L2_CTRL_TYPE_INTEGER,
+			.name = "exposure",
+			.minimum = 0x0250,
+			.maximum = 0xffff,
+			.step = 0x0001,
+			.default_value = 0x0250,
+			.flags = 0,
+		},
+		{
+			.id = V4L2_CID_RED_BALANCE,
+			.type = V4L2_CTRL_TYPE_INTEGER,
+			.name = "red balance",
+			.minimum = 0x00,
+			.maximum = 0x3f,
+			.step = 0x01,
+			.default_value = 0x00,
+			.flags = 0,
+		},
+		{
+			.id = V4L2_CID_BLUE_BALANCE,
+			.type = V4L2_CTRL_TYPE_INTEGER,
+			.name = "blue balance",
+			.minimum = 0x00,
+			.maximum = 0x3f,
+			.step = 0x01,
+			.default_value = 0x20,
+			.flags = 0,
+		},
+		{
+			.id = SN9C102_V4L2_CID_GREEN_BALANCE,
+			.type = V4L2_CTRL_TYPE_INTEGER,
+			.name = "green balance",
+			.minimum = 0x00,
+			.maximum = 0x3f,
+			.step = 0x01,
+			.default_value = 0x1e,
+			.flags = 0,
+		},
+		{
+			.id = SN9C102_V4L2_CID_RESET_LEVEL,
+			.type = V4L2_CTRL_TYPE_INTEGER,
+			.name = "reset level",
+			.minimum = 0x19,
+			.maximum = 0x3f,
+			.step = 0x01,
+			.default_value = 0x30,
+			.flags = 0,
+		},
+		{
+			.id = SN9C102_V4L2_CID_PIXEL_BIAS_VOLTAGE,
+			.type = V4L2_CTRL_TYPE_INTEGER,
+			.name = "pixel bias voltage",
+			.minimum = 0x00,
+			.maximum = 0x07,
+			.step = 0x01,
+			.default_value = 0x02,
+			.flags = 0,
+		},
+	},
+	.get_ctrl = &hv7131d_get_ctrl,
+	.set_ctrl = &hv7131d_set_ctrl,
+	.cropcap = {
+		.bounds = {
+			.left = 0,
+			.top = 0,
+			.width = 640,
+			.height = 480,
+		},
+		.defrect = {
+			.left = 0,
+			.top = 0,
+			.width = 640,
+			.height = 480,
+		},
+	},
+	.set_crop = &hv7131d_set_crop,
+	.pix_format = {
+		.width = 640,
+		.height = 480,
+		.pixelformat = V4L2_PIX_FMT_SBGGR8,
+		.priv = 8,
+	},
+	.set_pix_format = &hv7131d_set_pix_format
+};
+
+
+int sn9c102_probe_hv7131d(struct sn9c102_device* cam)
+{
+	int r0 = 0, r1 = 0, err = 0;
+
+	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;
+
+	r0 = sn9c102_i2c_try_read(cam, &hv7131d, 0x00);
+	r1 = sn9c102_i2c_try_read(cam, &hv7131d, 0x01);
+	if (r0 < 0 || r1 < 0)
+		return -EIO;
+
+	if (r0 != 0x00 && r1 != 0x04)
+		return -ENODEV;
+
+	sn9c102_attach_sensor(cam, &hv7131d);
+
+	return 0;
+}
diff -Nru a/drivers/usb/media/sn9c102_mi0343.c b/drivers/usb/media/sn9c102_mi0343.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/usb/media/sn9c102_mi0343.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,363 @@
+/***************************************************************************
+ * Plug-in for MI-0343 image sensor connected to the SN9C10x PC Camera     *
+ * Controllers                                                             *
+ *                                                                         *
+ * Copyright (C) 2004-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 mi0343;
+static u8 mi0343_i2c_data[5+1];
+
+
+static int mi0343_init(struct sn9c102_device* cam)
+{
+	int err = 0;
+
+	err += sn9c102_write_reg(cam, 0x00, 0x10);
+	err += sn9c102_write_reg(cam, 0x00, 0x11);
+	err += sn9c102_write_reg(cam, 0x0a, 0x14);
+	err += sn9c102_write_reg(cam, 0x40, 0x01);
+	err += sn9c102_write_reg(cam, 0x20, 0x17);
+	err += sn9c102_write_reg(cam, 0x07, 0x18);
+	err += sn9c102_write_reg(cam, 0xa0, 0x19);
+
+	err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id,
+	                                 0x0d, 0x00, 0x01, 0, 0);
+	err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id,
+	                                 0x0d, 0x00, 0x00, 0, 0);
+	err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id,
+	                                 0x03, 0x01, 0xe1, 0, 0);
+	err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id,
+	                                 0x04, 0x02, 0x81, 0, 0);
+	err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id,
+	                                 0x05, 0x00, 0x17, 0, 0);
+	err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id,
+	                                 0x06, 0x00, 0x11, 0, 0);
+	err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id,
+	                                 0x62, 0x04, 0x9a, 0, 0);
+
+	return err;
+}
+
+
+static int mi0343_get_ctrl(struct sn9c102_device* cam, 
+                           struct v4l2_control* ctrl)
+{
+	switch (ctrl->id) {
+	case V4L2_CID_EXPOSURE:
+		if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id,
+		                             0x09, 2+1, mi0343_i2c_data) < 0)
+			return -EIO;
+		ctrl->value = mi0343_i2c_data[2];
+		return 0;
+	case V4L2_CID_GAIN:
+		if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id,
+		                             0x35, 2+1, mi0343_i2c_data) < 0)
+			return -EIO;
+		break;
+	case V4L2_CID_HFLIP:
+		if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id,
+		                             0x20, 2+1, mi0343_i2c_data) < 0)
+			return -EIO;
+		ctrl->value = mi0343_i2c_data[3] & 0x20 ? 1 : 0;
+		return 0;
+	case V4L2_CID_VFLIP:
+		if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id,
+		                             0x20, 2+1, mi0343_i2c_data) < 0)
+			return -EIO;
+		ctrl->value = mi0343_i2c_data[3] & 0x80 ? 1 : 0;
+		return 0;
+	case V4L2_CID_RED_BALANCE:
+		if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id,
+		                             0x2d, 2+1, mi0343_i2c_data) < 0)
+			return -EIO;
+		break;
+	case V4L2_CID_BLUE_BALANCE:
+		if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id,
+		                             0x2c, 2+1, mi0343_i2c_data) < 0)
+			return -EIO;
+		break;
+	case SN9C102_V4L2_CID_GREEN_BALANCE:
+		if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id,
+		                             0x2e, 2+1, mi0343_i2c_data) < 0)
+			return -EIO;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	switch (ctrl->id) {
+	case V4L2_CID_GAIN:
+	case V4L2_CID_RED_BALANCE:
+	case V4L2_CID_BLUE_BALANCE:
+	case SN9C102_V4L2_CID_GREEN_BALANCE:
+		ctrl->value = mi0343_i2c_data[3] | (mi0343_i2c_data[2] << 8);
+		if (ctrl->value >= 0x10 && ctrl->value <= 0x3f)
+			ctrl->value -= 0x10;
+		else if (ctrl->value >= 0x60 && ctrl->value <= 0x7f)
+			ctrl->value -= 0x60;
+		else if (ctrl->value >= 0xe0 && ctrl->value <= 0xff)
+			ctrl->value -= 0xe0;
+	}
+
+	return 0;
+}
+
+
+static int mi0343_set_ctrl(struct sn9c102_device* cam, 
+                           const struct v4l2_control* ctrl)
+{
+	u16 reg = 0;
+	int err = 0;
+
+	switch (ctrl->id) {
+	case V4L2_CID_GAIN:
+	case V4L2_CID_RED_BALANCE:
+	case V4L2_CID_BLUE_BALANCE:
+	case SN9C102_V4L2_CID_GREEN_BALANCE:
+		if (ctrl->value <= (0x3f-0x10))
+			reg = 0x10 + ctrl->value;
+		else if (ctrl->value <= ((0x3f-0x10) + (0x7f-0x60)))
+			reg = 0x60 + (ctrl->value - (0x3f-0x10));
+		else
+			reg = 0xe0 + (ctrl->value - (0x3f-0x10) - (0x7f-0x60));
+		break;
+	}
+
+	switch (ctrl->id) {
+	case V4L2_CID_EXPOSURE:
+		err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4,
+		                                 mi0343.i2c_slave_id,
+		                                 0x09, ctrl->value, 0x00,
+		                                 0, 0);
+		break;
+	case V4L2_CID_GAIN:
+		err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4,
+		                                 mi0343.i2c_slave_id,
+		                                 0x35, reg >> 8, reg & 0xff,
+		                                 0, 0);
+		break;
+	case V4L2_CID_HFLIP:
+		err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4,
+		                                 mi0343.i2c_slave_id,
+		                                 0x20, ctrl->value ? 0x40:0x00,
+		                                 ctrl->value ? 0x20:0x00,
+		                                 0, 0);
+		break;
+	case V4L2_CID_VFLIP:
+		err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4,
+		                                 mi0343.i2c_slave_id,
+		                                 0x20, ctrl->value ? 0x80:0x00,
+		                                 ctrl->value ? 0x80:0x00,
+		                                 0, 0);
+		break;
+	case V4L2_CID_RED_BALANCE:
+		err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4,
+		                                 mi0343.i2c_slave_id,
+		                                 0x2d, reg >> 8, reg & 0xff,
+		                                 0, 0);
+		break;
+	case V4L2_CID_BLUE_BALANCE:
+		err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4,
+		                                 mi0343.i2c_slave_id,
+		                                 0x2c, reg >> 8, reg & 0xff,
+		                                 0, 0);
+		break;
+	case SN9C102_V4L2_CID_GREEN_BALANCE:
+		err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4,
+		                                 mi0343.i2c_slave_id,
+		                                 0x2b, reg >> 8, reg & 0xff,
+		                                 0, 0);
+		err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4,
+		                                 mi0343.i2c_slave_id,
+		                                 0x2e, reg >> 8, reg & 0xff,
+		                                 0, 0);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return err ? -EIO : 0;
+}
+
+
+static int mi0343_set_crop(struct sn9c102_device* cam, 
+                            const struct v4l2_rect* rect)
+{
+	struct sn9c102_sensor* s = &mi0343;
+	int err = 0;
+	u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 0,
+	   v_start = (u8)(rect->top - s->cropcap.bounds.top) + 2;
+
+	err += sn9c102_write_reg(cam, h_start, 0x12);
+	err += sn9c102_write_reg(cam, v_start, 0x13);
+
+	return err;
+}
+
+
+static int mi0343_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_i2c_try_raw_write(cam, &mi0343, 4,
+		                                 mi0343.i2c_slave_id,
+		                                 0x0a, 0x00, 0x03, 0, 0);
+		err += sn9c102_write_reg(cam, 0x20, 0x19);
+	} else {
+		err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4,
+		                                 mi0343.i2c_slave_id,
+		                                 0x0a, 0x00, 0x05, 0, 0);
+		err += sn9c102_write_reg(cam, 0xa0, 0x19);
+	}
+
+	return err;
+}
+
+
+static struct sn9c102_sensor mi0343 = {
+	.name = "MI-0343",
+	.maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
+	.frequency = SN9C102_I2C_100KHZ,
+	.interface = SN9C102_I2C_2WIRES,
+	.i2c_slave_id = 0x5d,
+	.init = &mi0343_init,
+	.qctrl = {
+		{
+			.id = V4L2_CID_EXPOSURE,
+			.type = V4L2_CTRL_TYPE_INTEGER,
+			.name = "exposure",
+			.minimum = 0x00,
+			.maximum = 0x0f,
+			.step = 0x01,
+			.default_value = 0x06,
+			.flags = 0,
+		},
+		{
+			.id = V4L2_CID_GAIN,
+			.type = V4L2_CTRL_TYPE_INTEGER,
+			.name = "global gain",
+			.minimum = 0x00,
+			.maximum = (0x3f-0x10)+(0x7f-0x60)+(0xff-0xe0),/*0x6d*/
+			.step = 0x01,
+			.default_value = 0x00,
+			.flags = 0,
+		},
+		{
+			.id = V4L2_CID_HFLIP,
+			.type = V4L2_CTRL_TYPE_BOOLEAN,
+			.name = "horizontal mirror",
+			.minimum = 0,
+			.maximum = 1,
+			.step = 1,
+			.default_value = 0,
+			.flags = 0,
+		},
+		{
+			.id = V4L2_CID_VFLIP,
+			.type = V4L2_CTRL_TYPE_BOOLEAN,
+			.name = "vertical mirror",
+			.minimum = 0,
+			.maximum = 1,
+			.step = 1,
+			.default_value = 0,
+			.flags = 0,
+		},
+		{
+			.id = V4L2_CID_RED_BALANCE,
+			.type = V4L2_CTRL_TYPE_INTEGER,
+			.name = "red balance",
+			.minimum = 0x00,
+			.maximum = (0x3f-0x10)+(0x7f-0x60)+(0xff-0xe0),
+			.step = 0x01,
+			.default_value = 0x00,
+			.flags = 0,
+		},
+		{
+			.id = V4L2_CID_BLUE_BALANCE,
+			.type = V4L2_CTRL_TYPE_INTEGER,
+			.name = "blue balance",
+			.minimum = 0x00,
+			.maximum = (0x3f-0x10)+(0x7f-0x60)+(0xff-0xe0),
+			.step = 0x01,
+			.default_value = 0x00,
+			.flags = 0,
+		},
+		{
+			.id = SN9C102_V4L2_CID_GREEN_BALANCE,
+			.type = V4L2_CTRL_TYPE_INTEGER,
+			.name = "green balance",
+			.minimum = 0x00,
+			.maximum = ((0x3f-0x10)+(0x7f-0x60)+(0xff-0xe0)),
+			.step = 0x01,
+			.default_value = 0x00,
+			.flags = 0,
+		},
+	},
+	.get_ctrl = &mi0343_get_ctrl,
+	.set_ctrl = &mi0343_set_ctrl,
+	.cropcap = {
+		.bounds = {
+			.left = 0,
+			.top = 0,
+			.width = 640,
+			.height = 480,
+		},
+		.defrect = {
+			.left = 0,
+			.top = 0,
+			.width = 640,
+			.height = 480,
+		},
+	},
+	.set_crop = &mi0343_set_crop,
+	.pix_format = {
+		.width = 640,
+		.height = 480,
+		.pixelformat = V4L2_PIX_FMT_SBGGR8,
+		.priv = 8,
+	},
+	.set_pix_format = &mi0343_set_pix_format
+};
+
+
+int sn9c102_probe_mi0343(struct sn9c102_device* cam)
+{
+	int err = 0;
+
+	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;
+
+	if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id, 0x00,
+	                             2, mi0343_i2c_data) < 0)
+		return -EIO;
+
+	if (mi0343_i2c_data[4] != 0x32 && mi0343_i2c_data[3] != 0xe3)
+		return -ENODEV;
+
+	sn9c102_attach_sensor(cam, &mi0343);
+
+	return 0;
+}
diff -Nru a/drivers/usb/media/sn9c102_pas106b.c b/drivers/usb/media/sn9c102_pas106b.c
--- a/drivers/usb/media/sn9c102_pas106b.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/usb/media/sn9c102_pas106b.c	2005-03-01 23:38:52 -08:00
@@ -2,7 +2,7 @@
  * Plug-in for PAS106B image sensor connected to the SN9C10x PC Camera     *
  * Controllers                                                             *
  *                                                                         *
- * Copyright (C) 2004 by Luca Risolia <luca.risolia@studio.unibo.it>       *
+ * Copyright (C) 2004-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    *
@@ -96,11 +96,6 @@
 			return -EIO;
 		ctrl->value &= 0xf8;
 		return 0;
-	case SN9C102_V4L2_CID_DAC_SIGN:
-		if ((ctrl->value = sn9c102_i2c_read(cam, 0x07)) < 0)
-			return -EIO;
-		ctrl->value &= 0x01;
-		return 0;
 	default:
 		return -EINVAL;
 	}
@@ -136,13 +131,6 @@
 	case SN9C102_V4L2_CID_DAC_MAGNITUDE:
 		err += sn9c102_i2c_write(cam, 0x08, ctrl->value << 3);
 		break;
-	case SN9C102_V4L2_CID_DAC_SIGN:
-		{
-			int r;
-			err += (r = sn9c102_i2c_read(cam, 0x07)) < 0 ? r : 0;
-			err += sn9c102_i2c_write(cam, 0x07, r | ctrl->value);
-		}
-		break;
 	default:
 		return -EINVAL;
 	}
@@ -167,13 +155,27 @@
 }
 
 
+static int pas106b_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, 0x2c, 0x17);
+	else
+		err += sn9c102_write_reg(cam, 0x20, 0x17);
+
+	return err;
+}
+
+
 static struct sn9c102_sensor pas106b = {
 	.name = "PAS106B",
 	.maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
+	.sysfs_ops = SN9C102_I2C_READ | SN9C102_I2C_WRITE,
 	.frequency = SN9C102_I2C_400KHZ | SN9C102_I2C_100KHZ,
 	.interface = SN9C102_I2C_2WIRES,
-	.slave_read_id = 0x40,
-	.slave_write_id = 0x40,
+	.i2c_slave_id = 0x40,
 	.init = &pas106b_init,
 	.qctrl = {
 		{
@@ -182,7 +184,7 @@
 			.name = "exposure",
 			.minimum = 0x125,
 			.maximum = 0xfff,
-			.step = 0x01,
+			.step = 0x001,
 			.default_value = 0x140,
 			.flags = 0,
 		},
@@ -246,16 +248,6 @@
 			.default_value = 0x01,
 			.flags = 0,
 		},
-		{
-			.id = SN9C102_V4L2_CID_DAC_SIGN,
-			.type = V4L2_CTRL_TYPE_BOOLEAN,
-			.name = "DAC sign",
-			.minimum = 0x00,
-			.maximum = 0x01,
-			.step = 0x01,
-			.default_value = 0x00,
-			.flags = 0,
-		},
 	},
 	.get_ctrl = &pas106b_get_ctrl,
 	.set_ctrl = &pas106b_set_ctrl,
@@ -279,7 +271,8 @@
 		.height = 288,
 		.pixelformat = V4L2_PIX_FMT_SBGGR8,
 		.priv = 8, /* we use this field as 'bits per pixel' */
-	}
+	},
+	.set_pix_format = &pas106b_set_pix_format
 };
 
 
diff -Nru a/drivers/usb/media/sn9c102_pas202bcb.c b/drivers/usb/media/sn9c102_pas202bcb.c
--- a/drivers/usb/media/sn9c102_pas202bcb.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/usb/media/sn9c102_pas202bcb.c	2005-03-01 23:39:09 -08:00
@@ -6,7 +6,7 @@
  *                       <medaglia@undl.org.br>                            *
  *                       http://cadu.homelinux.com:8080/                   *
  *                                                                         *
- * DAC Magnitude, DAC sign, exposure and green gain controls added by      *
+ * DAC Magnitude, exposure and green gain controls added by                *
  * Luca Risolia <luca.risolia@studio.unibo.it>                             *
  *                                                                         *
  * This program is free software; you can redistribute it and/or modify    *
@@ -95,17 +95,26 @@
 		if ((ctrl->value = sn9c102_i2c_read(cam, 0x0c)) < 0)
 			return -EIO;
 		return 0;
-	case SN9C102_V4L2_CID_DAC_SIGN:
-		if ((ctrl->value = sn9c102_i2c_read(cam, 0x0b)) < 0)
-			return -EIO;
-		ctrl->value &= 0x01;
-		return 0;
 	default:
 		return -EINVAL;
 	}
 }
 
 
+static int pas202bcb_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, 0x24, 0x17);
+	else
+		err += sn9c102_write_reg(cam, 0x20, 0x17);
+
+	return err;
+}
+
+
 static int pas202bcb_set_ctrl(struct sn9c102_device* cam, 
                               const struct v4l2_control* ctrl)
 {
@@ -131,13 +140,6 @@
 	case SN9C102_V4L2_CID_DAC_MAGNITUDE:
 		err += sn9c102_i2c_write(cam, 0x0c, ctrl->value);
 		break;
-	case SN9C102_V4L2_CID_DAC_SIGN:
-		{
-			int r;
-			err += (r = sn9c102_i2c_read(cam, 0x0b)) < 0 ? r : 0;
-			err += sn9c102_i2c_write(cam, 0x0b, r | ctrl->value);
-		}
-		break;
 	default:
 		return -EINVAL;
 	}
@@ -166,10 +168,10 @@
 	.name = "PAS202BCB",
 	.maintainer = "Carlos Eduardo Medaglia Dyonisio "
 	              "<medaglia@undl.org.br>",
+	.sysfs_ops = SN9C102_I2C_READ | SN9C102_I2C_WRITE,
 	.frequency = SN9C102_I2C_400KHZ | SN9C102_I2C_100KHZ,
 	.interface = SN9C102_I2C_2WIRES,
-	.slave_read_id = 0x40,
-	.slave_write_id = 0x40,
+	.i2c_slave_id = 0x40,
 	.init = &pas202bcb_init,
 	.qctrl = {
 		{
@@ -178,7 +180,7 @@
 			.name = "exposure",
 			.minimum = 0x01e5,
 			.maximum = 0x3fff,
-			.step = 0x01,
+			.step = 0x0001,
 			.default_value = 0x01e5,
 			.flags = 0,
 		},
@@ -232,16 +234,6 @@
 			.default_value = 0x04,
 			.flags = 0,
 		},
-		{
-			.id = SN9C102_V4L2_CID_DAC_SIGN,
-			.type = V4L2_CTRL_TYPE_BOOLEAN,
-			.name = "DAC sign",
-			.minimum = 0x00,
-			.maximum = 0x01,
-			.step = 0x01,
-			.default_value = 0x01,
-			.flags = 0,
-		},
 	},
 	.get_ctrl = &pas202bcb_get_ctrl,
 	.set_ctrl = &pas202bcb_set_ctrl,
@@ -265,7 +257,8 @@
 		.height = 480,
 		.pixelformat = V4L2_PIX_FMT_SBGGR8,
 		.priv = 8,
-	}
+	},
+	.set_pix_format = &pas202bcb_set_pix_format
 };
 
 
@@ -286,7 +279,7 @@
 
 	r0 = sn9c102_i2c_try_read(cam, &pas202bcb, 0x00);
 	r1 = sn9c102_i2c_try_read(cam, &pas202bcb, 0x01);
-	
+
 	if (r0 < 0 || r1 < 0)
 		return -EIO;
 
diff -Nru a/drivers/usb/media/sn9c102_sensor.h b/drivers/usb/media/sn9c102_sensor.h
--- a/drivers/usb/media/sn9c102_sensor.h	2005-03-01 23:38:54 -08:00
+++ b/drivers/usb/media/sn9c102_sensor.h	2005-03-01 23:38:54 -08:00
@@ -1,7 +1,7 @@
 /***************************************************************************
  * API for image sensors connected to the SN9C10x PC Camera Controllers    *
  *                                                                         *
- * Copyright (C) 2004 by Luca Risolia <luca.risolia@studio.unibo.it>       *
+ * Copyright (C) 2004-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    *
@@ -62,6 +62,8 @@
    ahead.
    Functions must return 0 on success, the appropriate error otherwise.
 */
+extern int sn9c102_probe_hv7131d(struct sn9c102_device* cam);
+extern int sn9c102_probe_mi0343(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);
@@ -74,8 +76,10 @@
 */
 #define SN9C102_SENSOR_TABLE                                                  \
 static int (*sn9c102_sensor_table[])(struct sn9c102_device*) = {              \
+	&sn9c102_probe_mi0343, /* strong detection based on SENSOR ids */     \
 	&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_tas5110c1b, /* detection based on USB pid/vid */       \
 	&sn9c102_probe_tas5130d1b, /* detection based on USB pid/vid */       \
 	NULL,                                                                 \
@@ -97,7 +101,7 @@
 	{ USB_DEVICE(0x0c45, 0x6025), }, /* TAS5130D1B and TAS5110C1B */      \
 	{ USB_DEVICE(0x0c45, 0x6028), }, /* PAS202BCB */                      \
 	{ USB_DEVICE(0x0c45, 0x6029), }, /* PAS106B */                        \
-	{ USB_DEVICE(0x0c45, 0x602a), }, /* HV7131[D|E1] */                   \
+	{ USB_DEVICE(0x0c45, 0x602a), }, /* HV7131D */                        \
 	{ USB_DEVICE(0x0c45, 0x602b), }, /* MI-0343 */                        \
 	{ USB_DEVICE(0x0c45, 0x602c), }, /* OV7620 */                         \
 	{ USB_DEVICE(0x0c45, 0x6030), }, /* MI03x */                          \
@@ -147,15 +151,23 @@
                                 u8 address);
 
 /*
-   This must be used if and only if the sensor doesn't implement the standard
-   I2C protocol. There a number of good reasons why you must use the 
-   single-byte versions of this function: do not abuse. It writes n bytes, 
-   from data0 to datan, (registers 0x09 - 0x09+n of SN9C10X chip).
+   These must be used if and only if the sensor doesn't implement the standard
+   I2C protocol. There are a number of good reasons why you must use the 
+   single-byte versions of these functions: do not abuse. The first function
+   writes n bytes, from data0 to datan, to registers 0x09 - 0x09+n of SN9C10X
+   chip. The second one programs the registers 0x09 and 0x10 with data0 and
+   data1, and places the n bytes read from the sensor register table in the
+   buffer pointed by 'buffer'. Both the functions return -1 on error; the write
+   version returns 0 on success, while the read version returns the first read
+   byte.
 */
 extern int sn9c102_i2c_try_raw_write(struct sn9c102_device* cam,
                                      struct sn9c102_sensor* sensor, u8 n, 
                                      u8 data0, u8 data1, u8 data2, u8 data3,
                                      u8 data4, u8 data5);
+extern int sn9c102_i2c_try_raw_read(struct sn9c102_device* cam,
+                                    struct sn9c102_sensor* sensor, u8 data0,
+                                    u8 data1, u8 n, u8 buffer[]);
 
 /* To be used after the sensor struct has been attached to the camera struct */
 extern int sn9c102_i2c_write(struct sn9c102_device*, u8 address, u8 value);
@@ -166,16 +178,21 @@
 extern int sn9c102_pread_reg(struct sn9c102_device*, u16 index);
 
 /*
-   NOTE: there are no debugging functions here. To uniform the output you must
-   use the dev_info()/dev_warn()/dev_err() macros defined in device.h, already
-   included here, the argument being the struct device 'dev' of the sensor
-   structure. Do NOT use these macros before the sensor is attached or the
-   kernel will crash! However you should not need to notify the user about
+   NOTE: there are no exported debugging functions. To uniform the output you
+   must use the dev_info()/dev_warn()/dev_err() macros defined in device.h,
+   already included here, the argument being the struct device 'dev' of the
+   sensor structure. Do NOT use these macros before the sensor is attached or
+   the kernel will crash! However, you should not need to notify the user about
    common errors or other messages, since this is done by the master module.
 */
 
 /*****************************************************************************/
 
+enum sn9c102_i2c_sysfs_ops {
+	SN9C102_I2C_READ = 0x01,
+	SN9C102_I2C_WRITE = 0x02,
+};
+
 enum sn9c102_i2c_frequency { /* sensors may support both the frequencies */
 	SN9C102_I2C_100KHZ = 0x01,
 	SN9C102_I2C_400KHZ = 0x02,
@@ -186,13 +203,13 @@
 	SN9C102_I2C_3WIRES,
 };
 
-#define SN9C102_I2C_SLAVEID_FICTITIOUS 0xff
-#define SN9C102_I2C_SLAVEID_UNAVAILABLE 0x00
-
 struct sn9c102_sensor {
 	char name[32], /* sensor name */
 	     maintainer[64]; /* name of the mantainer <email> */
 
+	/* Supported operations through the 'sysfs' interface */
+	enum sn9c102_i2c_sysfs_ops sysfs_ops;
+
 	/*
 	   These sensor capabilities must be provided if the SN9C10X controller
 	   needs to communicate through the sensor serial interface by using
@@ -202,10 +219,10 @@
 	enum sn9c102_i2c_interface interface;
 
 	/*
-	   These identifiers must be provided if the image sensor implements
+	   This identifier must be provided if the image sensor implements
 	   the standard I2C protocol.
 	*/
-	u8 slave_read_id, slave_write_id; /* reg. 0x09 */
+	u8 i2c_slave_id; /* reg. 0x09 */
 
 	/*
 	   NOTE: Where not noted,most of the functions below are not mandatory.
@@ -215,7 +232,7 @@
 
 	int (*init)(struct sn9c102_device* cam);
 	/*
-	   This function is called after the sensor has been attached. 
+	   This function will be called after the sensor has been attached. 
 	   It should be used to initialize the sensor only, but may also
 	   configure part of the SN9C10X chip if necessary. You don't need to
 	   setup picture settings like brightness, contrast, etc.. here, if
@@ -315,6 +332,14 @@
 	           matches the RGB bayer sequence (i.e. BGBGBG...GRGRGR).
 	*/
 
+	int (*set_pix_format)(struct sn9c102_device* cam,
+	                      const struct v4l2_pix_format* pix);
+	/*
+	   To be called on VIDIOC_S_FMT, when switching from the SBGGR8 to
+	   SN9C10X pixel format or viceversa. On error return the corresponding
+	   error code without rolling back.
+	*/
+
 	const struct device* dev;
 	/*
 	   This is the argument for dev_err(), dev_info() and dev_warn(). It
@@ -341,7 +366,8 @@
 
 /* Private ioctl's for control settings supported by some image sensors */
 #define SN9C102_V4L2_CID_DAC_MAGNITUDE V4L2_CID_PRIVATE_BASE
-#define SN9C102_V4L2_CID_DAC_SIGN V4L2_CID_PRIVATE_BASE + 1
-#define SN9C102_V4L2_CID_GREEN_BALANCE V4L2_CID_PRIVATE_BASE + 2
+#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
 
 #endif /* _SN9C102_SENSOR_H_ */
diff -Nru a/drivers/usb/media/sn9c102_tas5110c1b.c b/drivers/usb/media/sn9c102_tas5110c1b.c
--- a/drivers/usb/media/sn9c102_tas5110c1b.c	2005-03-01 23:38:43 -08:00
+++ b/drivers/usb/media/sn9c102_tas5110c1b.c	2005-03-01 23:38:43 -08:00
@@ -2,7 +2,7 @@
  * Plug-in for TAS5110C1B image sensor connected to the SN9C10x PC Camera  *
  * Controllers                                                             *
  *                                                                         *
- * Copyright (C) 2004 by Luca Risolia <luca.risolia@studio.unibo.it>       *
+ * Copyright (C) 2004-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    *
@@ -93,7 +93,21 @@
 	/* Don't change ! */
 	err += sn9c102_write_reg(cam, 0x14, 0x1a);
 	err += sn9c102_write_reg(cam, 0x0a, 0x1b);
-	err += sn9c102_write_reg(cam, 0xfb, 0x19);
+	err += sn9c102_write_reg(cam, sn9c102_pread_reg(cam, 0x19), 0x19);
+
+	return err;
+}
+
+
+static int tas5110c1b_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, 0x2b, 0x19);
+	else
+		err += sn9c102_write_reg(cam, 0xfb, 0x19);
 
 	return err;
 }
@@ -102,10 +116,9 @@
 static struct sn9c102_sensor tas5110c1b = {
 	.name = "TAS5110C1B",
 	.maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
+	.sysfs_ops = SN9C102_I2C_WRITE,
 	.frequency = SN9C102_I2C_100KHZ,
 	.interface = SN9C102_I2C_3WIRES,
-	.slave_read_id = SN9C102_I2C_SLAVEID_UNAVAILABLE,
-	.slave_write_id = SN9C102_I2C_SLAVEID_FICTITIOUS,
 	.init = &tas5110c1b_init,
 	.qctrl = {
 		{
@@ -141,7 +154,8 @@
 		.height = 288,
 		.pixelformat = V4L2_PIX_FMT_SBGGR8,
 		.priv = 8,
-	}
+	},
+	.set_pix_format = &tas5110c1b_set_pix_format
 };
 
 
@@ -151,9 +165,9 @@
 	sn9c102_attach_sensor(cam, &tas5110c1b);
 
 	/* Sensor detection is based on USB pid/vid */
-	if (tas5110c1b.usbdev->descriptor.idProduct != 0x6001 &&
-	    tas5110c1b.usbdev->descriptor.idProduct != 0x6005 &&
-	    tas5110c1b.usbdev->descriptor.idProduct != 0x60ab)
+	if (le16_to_cpu(tas5110c1b.usbdev->descriptor.idProduct) != 0x6001 &&
+	    le16_to_cpu(tas5110c1b.usbdev->descriptor.idProduct) != 0x6005 &&
+	    le16_to_cpu(tas5110c1b.usbdev->descriptor.idProduct) != 0x60ab)
 		return -ENODEV;
 
 	return 0;
diff -Nru a/drivers/usb/media/sn9c102_tas5130d1b.c b/drivers/usb/media/sn9c102_tas5130d1b.c
--- a/drivers/usb/media/sn9c102_tas5130d1b.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/usb/media/sn9c102_tas5130d1b.c	2005-03-01 23:38:58 -08:00
@@ -2,7 +2,7 @@
  * Plug-in for TAS5130D1B image sensor connected to the SN9C10x PC Camera  *
  * Controllers                                                             *
  *                                                                         *
- * Copyright (C) 2004 by Luca Risolia <luca.risolia@studio.unibo.it>       *
+ * Copyright (C) 2004-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    *
@@ -98,7 +98,21 @@
 	/* Do NOT change! */
 	err += sn9c102_write_reg(cam, 0x1f, 0x1a);
 	err += sn9c102_write_reg(cam, 0x1a, 0x1b);
-	err += sn9c102_write_reg(cam, 0xf3, 0x19);
+	err += sn9c102_write_reg(cam, sn9c102_pread_reg(cam, 0x19), 0x19);
+
+	return err;
+}
+
+
+static int tas5130d1b_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, 0x63, 0x19);
+	else
+		err += sn9c102_write_reg(cam, 0xf3, 0x19);
 
 	return err;
 }
@@ -107,10 +121,9 @@
 static struct sn9c102_sensor tas5130d1b = {
 	.name = "TAS5130D1B",
 	.maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
+	.sysfs_ops = SN9C102_I2C_WRITE,
 	.frequency = SN9C102_I2C_100KHZ,
 	.interface = SN9C102_I2C_3WIRES,
-	.slave_read_id = SN9C102_I2C_SLAVEID_UNAVAILABLE,
-	.slave_write_id = SN9C102_I2C_SLAVEID_FICTITIOUS,
 	.init = &tas5130d1b_init,
 	.qctrl = {
 		{
@@ -156,7 +169,8 @@
 		.height = 480,
 		.pixelformat = V4L2_PIX_FMT_SBGGR8,
 		.priv = 8,
-	}
+	},
+	.set_pix_format = &tas5130d1b_set_pix_format
 };
 
 
@@ -166,8 +180,8 @@
 	sn9c102_attach_sensor(cam, &tas5130d1b);
 
 	/* Sensor detection is based on USB pid/vid */
-	if (tas5130d1b.usbdev->descriptor.idProduct != 0x6025 &&
-	    tas5130d1b.usbdev->descriptor.idProduct != 0x60aa)
+	if (le16_to_cpu(tas5130d1b.usbdev->descriptor.idProduct) != 0x6025 &&
+	    le16_to_cpu(tas5130d1b.usbdev->descriptor.idProduct) != 0x60aa)
 		return -ENODEV;
 
 	return 0;
diff -Nru a/drivers/usb/media/stv680.c b/drivers/usb/media/stv680.c
--- a/drivers/usb/media/stv680.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/usb/media/stv680.c	2005-03-01 23:39:07 -08:00
@@ -1371,7 +1371,8 @@
 
 	interface = &intf->altsetting[0];
 	/* Is it a STV680? */
-	if ((dev->descriptor.idVendor == USB_PENCAM_VENDOR_ID) && (dev->descriptor.idProduct == USB_PENCAM_PRODUCT_ID)) {
+	if ((le16_to_cpu(dev->descriptor.idVendor) == USB_PENCAM_VENDOR_ID) &&
+	    (le16_to_cpu(dev->descriptor.idProduct) == USB_PENCAM_PRODUCT_ID)) {
 		camera_name = "STV0680";
 		PDEBUG (0, "STV(i): STV0680 camera found.");
 	} else {
diff -Nru a/drivers/usb/media/ultracam.c b/drivers/usb/media/ultracam.c
--- a/drivers/usb/media/ultracam.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/usb/media/ultracam.c	2005-03-01 23:38:53 -08:00
@@ -524,12 +524,8 @@
 	if (dev->descriptor.bNumConfigurations != 1)
 		return -ENODEV;
 
-	/* Is it an IBM camera? */
-	if ((dev->descriptor.idVendor != ULTRACAM_VENDOR_ID) ||
-	    (dev->descriptor.idProduct != ULTRACAM_PRODUCT_ID))
-		return -ENODEV;
-
-	info("IBM Ultra camera found (rev. 0x%04x)", dev->descriptor.bcdDevice);
+	info("IBM Ultra camera found (rev. 0x%04x)",
+		le16_to_cpu(dev->descriptor.bcdDevice));
 
 	/* Validate found interface: must have one ISO endpoint */
 	nas = intf->num_altsetting;
@@ -569,7 +565,7 @@
 			    interface->desc.bInterfaceNumber);
 			return -ENODEV;
 		}
-		if (endpoint->wMaxPacketSize == 0) {
+		if (le16_to_cpu(endpoint->wMaxPacketSize) == 0) {
 			if (inactInterface < 0)
 				inactInterface = i;
 			else {
@@ -579,15 +575,15 @@
 		} else {
 			if (actInterface < 0) {
 				actInterface = i;
-				maxPS = endpoint->wMaxPacketSize;
+				maxPS = le16_to_cpu(endpoint->wMaxPacketSize);
 				if (debug > 0)
 					info("Active setting=%d. maxPS=%d.", i, maxPS);
 			} else {
 				/* Got another active alt. setting */
-				if (maxPS < endpoint->wMaxPacketSize) {
+				if (maxPS < le16_to_cpu(endpoint->wMaxPacketSize)) {
 					/* This one is better! */
 					actInterface = i;
-					maxPS = endpoint->wMaxPacketSize;
+					maxPS = le16_to_cpu(endpoint->wMaxPacketSize);
 					if (debug > 0) {
 						info("Even better ctive setting=%d. maxPS=%d.",
 						     i, maxPS);
diff -Nru a/drivers/usb/media/vicam.c b/drivers/usb/media/vicam.c
--- a/drivers/usb/media/vicam.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/usb/media/vicam.c	2005-03-01 23:38:55 -08:00
@@ -1281,12 +1281,6 @@
 	const struct usb_endpoint_descriptor *endpoint;
 	struct vicam_camera *cam;
 	
-	/* See if the device offered us matches what we can accept */
-	if ((dev->descriptor.idVendor != USB_VICAM_VENDOR_ID) ||
-	    (dev->descriptor.idProduct != USB_VICAM_PRODUCT_ID)) {
-		return -ENODEV;
-	}
-
 	printk(KERN_INFO "ViCam based webcam connected\n");
 
 	interface = intf->cur_altsetting;
diff -Nru a/drivers/usb/media/w9968cf.c b/drivers/usb/media/w9968cf.c
--- a/drivers/usb/media/w9968cf.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/usb/media/w9968cf.c	2005-03-01 23:39:08 -08:00
@@ -3516,11 +3516,11 @@
 	u8 sc = 0; /* number of simultaneous cameras */
 	static unsigned short dev_nr = 0; /* we are handling device number n */
 
-	if (udev->descriptor.idVendor  == winbond_id_table[0].idVendor &&
-	    udev->descriptor.idProduct == winbond_id_table[0].idProduct)
+	if (le16_to_cpu(udev->descriptor.idVendor)  == winbond_id_table[0].idVendor &&
+	    le16_to_cpu(udev->descriptor.idProduct) == winbond_id_table[0].idProduct)
 		mod_id = W9968CF_MOD_CLVBWGP; /* see camlist[] table */
-	else if (udev->descriptor.idVendor  == winbond_id_table[1].idVendor &&
-	         udev->descriptor.idProduct == winbond_id_table[1].idProduct)
+	else if (le16_to_cpu(udev->descriptor.idVendor)  == winbond_id_table[1].idVendor &&
+	         le16_to_cpu(udev->descriptor.idProduct) == winbond_id_table[1].idProduct)
 		mod_id = W9968CF_MOD_GENERIC; /* see camlist[] table */
 	else
 		return -ENODEV;
diff -Nru a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig
--- a/drivers/usb/misc/Kconfig	2005-03-01 23:39:16 -08:00
+++ b/drivers/usb/misc/Kconfig	2005-03-01 23:39:16 -08:00
@@ -32,26 +32,6 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called emi26.
 
-config USB_TIGL
-	tristate "Texas Instruments Graph Link USB (aka SilverLink) cable support"
-	depends on USB
-	---help---
-	  If you own a Texas Instruments graphing calculator and use a 
-	  TI-GRAPH LINK USB cable (aka SilverLink), then you might be 
-	  interested in this driver.
-
-	  If you enable this driver, you will be able to communicate with
-	  your calculator through a set of device nodes under /dev.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called tiglusb.
-
-	  If you don't know what the SilverLink cable is or what a Texas
-	  Instruments graphing calculator is, then you probably don't need this
-	  driver.
-
-	  If unsure, say N.
-
 config USB_AUERSWALD
 	tristate "USB Auerswald ISDN support (EXPERIMENTAL)"
 	depends on USB && EXPERIMENTAL
@@ -143,11 +123,24 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called phidgetservo.
 
+config USB_IDMOUSE
+	tristate "Siemens ID USB Mouse Fingerprint sensor support"
+	depends on USB
+	help
+	  Say Y here if you want to use the fingerprint sensor on
+	  the Siemens ID Mouse. There is also a Siemens ID Mouse
+	  _Professional_, which has not been tested with this driver,
+	  but uses the same sensor and may therefore work.
+
+	  This driver creates an entry "/dev/idmouseX" or "/dev/usb/idmouseX",
+	  which can be used by, e.g.,"cat /dev/idmouse0 > fingerprint.pnm".
+
+	  See also <http://www.fs.tum.de/~echtler/idmouse/>.
+
 config USB_TEST
 	tristate "USB testing driver (DEVELOPMENT)"
 	depends on USB && USB_DEVICEFS && EXPERIMENTAL
 	help
-
 	  This driver is for testing host controller software.  It is used
 	  with specialized device firmware for regression and stress testing,
 	  to help prevent problems from cropping up with "real" drivers.
diff -Nru a/drivers/usb/misc/Makefile b/drivers/usb/misc/Makefile
--- a/drivers/usb/misc/Makefile	2005-03-01 23:38:58 -08:00
+++ b/drivers/usb/misc/Makefile	2005-03-01 23:38:58 -08:00
@@ -7,6 +7,7 @@
 obj-$(CONFIG_USB_CYTHERM)	+= cytherm.o
 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_LED)		+= usbled.o
 obj-$(CONFIG_USB_LEGOTOWER)	+= legousbtower.o
@@ -14,5 +15,4 @@
 obj-$(CONFIG_USB_PHIDGETSERVO)	+= phidgetservo.o
 obj-$(CONFIG_USB_RIO500)	+= rio500.o
 obj-$(CONFIG_USB_TEST)		+= usbtest.o
-obj-$(CONFIG_USB_TIGL)		+= tiglusb.o
 obj-$(CONFIG_USB_USS720)	+= uss720.o
diff -Nru a/drivers/usb/misc/auerswald.c b/drivers/usb/misc/auerswald.c
--- a/drivers/usb/misc/auerswald.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/usb/misc/auerswald.c	2005-03-01 23:38:56 -08:00
@@ -1123,16 +1123,16 @@
 static int auerswald_int_open (pauerswald_t cp)
 {
         int ret;
-	struct usb_endpoint_descriptor *ep;
+	struct usb_host_endpoint *ep;
 	int irqsize;
 	dbg ("auerswald_int_open");
 
-	ep = usb_epnum_to_ep_desc (cp->usbdev, USB_DIR_IN | AU_IRQENDP);
+	ep = cp->usbdev->ep_in[AU_IRQENDP];
 	if (!ep) {
 		ret = -EFAULT;
   		goto intoend;
     	}
-	irqsize = ep->wMaxPacketSize;
+	irqsize = le16_to_cpu(ep->desc.wMaxPacketSize);
 	cp->irqsize = irqsize;
 
 	/* allocate the urb and data buffer */
@@ -1151,7 +1151,9 @@
                 }
         }
         /* setup urb */
-        usb_fill_int_urb (cp->inturbp, cp->usbdev, usb_rcvintpipe (cp->usbdev,AU_IRQENDP), cp->intbufp, irqsize, auerswald_int_complete, cp, ep->bInterval);
+        usb_fill_int_urb (cp->inturbp, cp->usbdev,
+			usb_rcvintpipe (cp->usbdev,AU_IRQENDP), cp->intbufp,
+			irqsize, auerswald_int_complete, cp, ep->desc.bInterval);
         /* start the urb */
 	cp->inturbp->status = 0;	/* needed! */
 	ret = usb_submit_urb (cp->inturbp, GFP_KERNEL);
@@ -1929,11 +1931,8 @@
 	int ret;
 
 	dbg ("probe: vendor id 0x%x, device id 0x%x",
-	     usbdev->descriptor.idVendor, usbdev->descriptor.idProduct);
-
-	/* See if the device offered us matches that we can accept */
-	if (usbdev->descriptor.idVendor != ID_AUERSWALD)
-		return -ENODEV;
+	     le16_to_cpu(usbdev->descriptor.idVendor),
+	     le16_to_cpu(usbdev->descriptor.idProduct));
 
         /* we use only the first -and only- interface */
         if (intf->altsetting->desc.bInterfaceNumber != 0)
@@ -1967,7 +1966,7 @@
 	cp->dtindex = intf->minor;
 
 	/* Get the usb version of the device */
-	cp->version = cp->usbdev->descriptor.bcdDevice;
+	cp->version = le16_to_cpu(cp->usbdev->descriptor.bcdDevice);
 	dbg ("Version is %X", cp->version);
 
 	/* allow some time to settle the device */
diff -Nru a/drivers/usb/misc/emi26.c b/drivers/usb/misc/emi26.c
--- a/drivers/usb/misc/emi26.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/usb/misc/emi26.c	2005-03-01 23:38:54 -08:00
@@ -213,11 +213,9 @@
 	struct usb_device *dev = interface_to_usbdev(intf);
 
 	info("%s start", __FUNCTION__); 
-	
-	if((dev->descriptor.idVendor == EMI26_VENDOR_ID) && (dev->descriptor.idProduct == EMI26_PRODUCT_ID)) {
-		emi26_load_firmware(dev);
-	}
-	
+
+	emi26_load_firmware(dev);
+
 	/* do not return the driver context, let real audio driver do that */
 	return -EIO;
 }
diff -Nru a/drivers/usb/misc/emi62.c b/drivers/usb/misc/emi62.c
--- a/drivers/usb/misc/emi62.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/usb/misc/emi62.c	2005-03-01 23:39:09 -08:00
@@ -255,10 +255,8 @@
 
 	info("%s start", __FUNCTION__); 
 
-	if((dev->descriptor.idVendor == EMI62_VENDOR_ID) && (dev->descriptor.idProduct == EMI62_PRODUCT_ID)) {
-		emi62_load_firmware(dev);
-	}
-	
+	emi62_load_firmware(dev);
+
 	/* do not return the driver context, let real audio driver do that */
 	return -EIO;
 }
diff -Nru a/drivers/usb/misc/idmouse.c b/drivers/usb/misc/idmouse.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/usb/misc/idmouse.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,443 @@
+/* Siemens ID Mouse driver v0.5
+
+  This program is free software; you can redistribute it and/or
+  modify it under the terms of the 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) 2004-5 by Florian 'Floe' Echtler  <echtler@fs.tum.de>
+                      and Andreas  'ad'  Deresch <aderesch@fs.tum.de>
+
+  Derived from the USB Skeleton driver 1.1,
+  Copyright (C) 2003 Greg Kroah-Hartman (greg@kroah.com)
+
+*/
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/smp_lock.h>
+#include <linux/completion.h>
+#include <asm/uaccess.h>
+#include <linux/usb.h>
+
+#define WIDTH 225
+#define HEIGHT 288
+#define HEADER "P5 225 288 255 "
+#define IMGSIZE ((WIDTH * HEIGHT) + sizeof(HEADER)-1)
+
+/* Version Information */
+#define DRIVER_VERSION "0.5"
+#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 */
+#define USB_IDMOUSE_MINOR_BASE 132
+
+static struct usb_device_id idmouse_table[] = {
+	{USB_DEVICE(USB_IDMOUSE_VENDOR_ID, USB_IDMOUSE_PRODUCT_ID)},
+	{} /* null entry at the end */
+};
+
+MODULE_DEVICE_TABLE(usb, idmouse_table);
+
+/* structure to hold all of our device specific stuff */
+struct usb_idmouse {
+
+	struct usb_device *udev; /* save off the usb device pointer */
+	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 */
+	__u8 bulk_in_endpointAddr; /* the address of the bulk in endpoint */
+
+	int open; /* if the port is open or not */
+	int present; /* if the device is not disconnected */
+	struct semaphore sem; /* locks this structure */
+
+};
+
+/* local function prototypes */
+static ssize_t idmouse_read(struct file *file, char __user *buffer,
+				size_t count, loff_t * ppos);
+
+static int idmouse_open(struct inode *inode, struct file *file);
+static int idmouse_release(struct inode *inode, struct file *file);
+
+static int idmouse_probe(struct usb_interface *interface,
+				const struct usb_device_id *id);
+
+static void idmouse_disconnect(struct usb_interface *interface);
+
+/* file operation pointers */
+static struct file_operations idmouse_fops = {
+	.owner = THIS_MODULE,
+	.read = idmouse_read,
+	.open = idmouse_open,
+	.release = idmouse_release,
+};
+
+/* class driver information for devfs */
+static struct usb_class_driver idmouse_class = {
+	.name = "usb/idmouse%d",
+	.fops = &idmouse_fops,
+	.mode = S_IFCHR | S_IRUSR | S_IRGRP | S_IROTH, /* filemode (char, 444) */
+	.minor_base = USB_IDMOUSE_MINOR_BASE,
+};
+
+/* usb specific object needed to register this driver with the usb subsystem */
+static struct usb_driver idmouse_driver = {
+	.owner = THIS_MODULE,
+	.name = DRIVER_SHORT,
+	.probe = idmouse_probe,
+	.disconnect = idmouse_disconnect,
+	.id_table = idmouse_table,
+};
+
+// prevent races between open() and disconnect()
+static DECLARE_MUTEX(disconnect_sem);
+
+static int idmouse_create_image(struct usb_idmouse *dev)
+{
+	int bytes_read = 0;
+	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);
+	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, HZ);
+	if (result < 0)
+		return result;
+	result = usb_control_msg (dev->udev, usb_sndctrlpipe (dev->udev, 0),
+				0x20, 0x42, 0x0001, 0x0002, NULL, 0, HZ);
+	if (result < 0)
+		return result;
+	result = usb_control_msg (dev->udev, usb_sndctrlpipe (dev->udev, 0),
+				0x22, 0x42, 0x0000, 0x0002, NULL, 0, HZ);
+	if (result < 0)
+		return result;
+
+	result = usb_control_msg (dev->udev, usb_sndctrlpipe (dev->udev, 0),
+				0x21, 0x42, 0x0001, 0x0002, NULL, 0, HZ);
+	if (result < 0)
+		return result;
+	result = usb_control_msg (dev->udev, usb_sndctrlpipe (dev->udev, 0),
+				0x20, 0x42, 0x0001, 0x0002, NULL, 0, HZ);
+	if (result < 0)
+		return result;
+	result = usb_control_msg (dev->udev, usb_sndctrlpipe (dev->udev, 0),
+				0x20, 0x42, 0x0000, 0x0002, NULL, 0, HZ);
+	if (result < 0)
+		return result;
+
+	/* loop over a blocking bulk read to get data from the device */
+	while (bytes_read < IMGSIZE) {
+		result = usb_bulk_msg (dev->udev,
+				usb_rcvbulkpipe (dev->udev, dev->bulk_in_endpointAddr),
+				dev->bulk_in_buffer + bytes_read,
+				dev->bulk_in_size, &bulk_read, HZ * 5);
+		if (result < 0)
+			return result;
+		if (signal_pending(current))
+			return -EINTR;
+		bytes_read += bulk_read;
+	}
+
+	/* reset the device */
+	result = usb_control_msg (dev->udev, usb_sndctrlpipe (dev->udev, 0),
+				0x22, 0x42, 0x0000, 0x0002, NULL, 0, HZ);
+	if (result < 0)
+		return result;
+
+	/* should be IMGSIZE == 64815 */
+	dbg("read %d bytes fingerprint data", bytes_read);
+	return 0;
+}
+
+static inline void idmouse_delete(struct usb_idmouse *dev)
+{
+	kfree(dev->bulk_in_buffer);
+	kfree(dev);
+}
+
+static int idmouse_open(struct inode *inode, struct file *file)
+{
+	struct usb_idmouse *dev = NULL;
+	struct usb_interface *interface;
+	int result = 0;
+
+	/* prevent disconnects */
+	down(&disconnect_sem);
+
+	/* get the interface from minor number and driver information */
+	interface = usb_find_interface (&idmouse_driver, iminor (inode));
+	if (!interface) {
+		up(&disconnect_sem);
+		return -ENODEV;
+	}
+	/* get the device information block from the interface */
+	dev = usb_get_intfdata(interface);
+	if (!dev) {
+		up(&disconnect_sem);
+		return -ENODEV;
+	}
+
+	/* lock this device */
+	down(&dev->sem);
+
+	/* check if already open */
+	if (dev->open) {
+
+		/* already open, so fail */
+		result = -EBUSY;
+
+	} else {
+
+		/* create a new image and check for success */
+		result = idmouse_create_image (dev);
+		if (result)
+			goto error;
+
+		/* increment our usage count for the driver */
+		++dev->open;
+
+		/* save our object in the file's private structure */
+		file->private_data = dev;
+
+	} 
+
+error:
+
+	/* unlock this device */
+	up(&dev->sem);
+
+	/* unlock the disconnect semaphore */
+	up(&disconnect_sem);
+	return result;
+}
+
+static int idmouse_release(struct inode *inode, struct file *file)
+{
+	struct usb_idmouse *dev;
+
+	/* prevent a race condition with open() */
+	down(&disconnect_sem);
+
+	dev = (struct usb_idmouse *) file->private_data;
+
+	if (dev == NULL) {
+		up(&disconnect_sem);
+		return -ENODEV;
+	}
+
+	/* lock our device */
+	down(&dev->sem);
+
+	/* are we really open? */
+	if (dev->open <= 0) {
+		up(&dev->sem);
+		up(&disconnect_sem);
+		return -ENODEV;
+	}
+
+	--dev->open;
+
+	if (!dev->present) {
+		/* the device was unplugged before the file was released */
+		up(&dev->sem);
+		idmouse_delete(dev);
+		up(&disconnect_sem);
+		return 0;
+	}
+
+	up(&dev->sem);
+	up(&disconnect_sem);
+	return 0;
+}
+
+static ssize_t idmouse_read(struct file *file, char __user *buffer, size_t count,
+				loff_t * ppos)
+{
+	struct usb_idmouse *dev;
+	int result = 0;
+
+	dev = (struct usb_idmouse *) file->private_data;
+
+	// lock this object
+	down (&dev->sem);
+
+	// verify that the device wasn't unplugged
+	if (!dev->present) {
+		up (&dev->sem);
+		return -ENODEV;
+	}
+
+	if (*ppos >= IMGSIZE) {
+		up (&dev->sem);
+		return 0;
+	}
+
+	if (count > IMGSIZE - *ppos)
+		count = IMGSIZE - *ppos;
+
+	if (copy_to_user (buffer, dev->bulk_in_buffer + *ppos, count)) {
+		result = -EFAULT;
+	} else {
+		result = count;
+		*ppos += count;
+	}
+
+	// unlock the device 
+	up(&dev->sem);
+	return result;
+}
+
+static int idmouse_probe(struct usb_interface *interface,
+				const struct usb_device_id *id)
+{
+	struct usb_device *udev = interface_to_usbdev(interface);
+	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 */
+	iface_desc = &interface->altsetting[0];
+	if (iface_desc->desc.bInterfaceClass != 0x0A)
+		return -ENODEV;
+
+	/* allocate memory for our device state and initialize it */
+	dev = kmalloc(sizeof(*dev), GFP_KERNEL);
+	if (dev == NULL)
+		return -ENOMEM;
+	memset(dev, 0x00, sizeof(*dev));
+
+	init_MUTEX(&dev->sem);
+	dev->udev = udev;
+	dev->interface = interface;
+
+	/* set up the endpoint information - use only the first bulk-in endpoint */
+	endpoint = &iface_desc->endpoint[0].desc;
+	if (!dev->bulk_in_endpointAddr
+		&& (endpoint->bEndpointAddress & USB_DIR_IN)
+		&& ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
+		USB_ENDPOINT_XFER_BULK)) {
+
+		/* we found a bulk in endpoint */
+		buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
+		dev->bulk_in_size = buffer_size;
+		dev->bulk_in_endpointAddr = endpoint->bEndpointAddress;
+		dev->bulk_in_buffer =
+			kmalloc(IMGSIZE + buffer_size, GFP_KERNEL);
+
+		if (!dev->bulk_in_buffer) {
+			err("Unable to allocate input buffer.");
+			idmouse_delete(dev);
+			return -ENOMEM;
+		}
+	}
+
+	if (!(dev->bulk_in_endpointAddr)) {
+		err("Unable to find bulk-in endpoint.");
+		idmouse_delete(dev);
+		return -ENODEV;
+	}
+	/* allow device read, write and ioctl */
+	dev->present = 1;
+
+	/* we can register the device now, as it is ready */
+	usb_set_intfdata(interface, dev);
+	result = usb_register_dev(interface, &idmouse_class);
+	if (result) {
+		/* something prevented us from registering this device */
+		err("Unble to allocate minor number.");
+		usb_set_intfdata(interface, NULL);
+		idmouse_delete(dev);
+		return result;
+	}
+
+	/* be noisy */
+	dev_info(&interface->dev,"%s now attached\n",DRIVER_DESC);
+
+	return 0;
+}
+
+static void idmouse_disconnect(struct usb_interface *interface)
+{
+	struct usb_idmouse *dev;
+
+	/* prevent races with open() */
+	down(&disconnect_sem);
+
+	/* get device structure */
+	dev = usb_get_intfdata(interface);
+	usb_set_intfdata(interface, NULL);
+
+	/* lock it */
+	down(&dev->sem);
+
+	/* give back our minor */
+	usb_deregister_dev(interface, &idmouse_class);
+
+	/* prevent device read, write and ioctl */
+	dev->present = 0;
+
+	/* unlock */
+	up(&dev->sem);
+
+	/* if the device is opened, idmouse_release will clean this up */
+	if (!dev->open)
+		idmouse_delete(dev);
+
+	up(&disconnect_sem);
+
+	info("%s disconnected", DRIVER_DESC);
+}
+
+static int __init usb_idmouse_init(void)
+{
+	int result;
+
+	info(DRIVER_DESC " " DRIVER_VERSION);
+
+	/* register this driver with the USB subsystem */
+	result = usb_register(&idmouse_driver);
+	if (result)
+		err("Unable to register device (error %d).", result);
+
+	return result;
+}
+
+static void __exit usb_idmouse_exit(void)
+{
+	/* deregister this driver with the USB subsystem */
+	usb_deregister(&idmouse_driver);
+}
+
+module_init(usb_idmouse_init);
+module_exit(usb_idmouse_exit);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+
diff -Nru a/drivers/usb/misc/legousbtower.c b/drivers/usb/misc/legousbtower.c
--- a/drivers/usb/misc/legousbtower.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/usb/misc/legousbtower.c	2005-03-01 23:38:56 -08:00
@@ -405,7 +405,7 @@
 			  dev->udev,
 			  usb_rcvintpipe(dev->udev, dev->interrupt_in_endpoint->bEndpointAddress),
 			  dev->interrupt_in_buffer,
-			  dev->interrupt_in_endpoint->wMaxPacketSize,
+			  le16_to_cpu(dev->interrupt_in_endpoint->wMaxPacketSize),
 			  tower_interrupt_in_callback,
 			  dev,
 			  dev->interrupt_in_interval);
@@ -859,13 +859,6 @@
 		info ("udev is NULL.");
 	}
 
-	/* See if the device offered us matches what we can accept */
-	if ((udev->descriptor.idVendor != LEGO_USB_TOWER_VENDOR_ID) ||
-	    (udev->descriptor.idProduct != LEGO_USB_TOWER_PRODUCT_ID)) {
-		return -ENODEV;
-	}
-
-
 	/* allocate memory for our device state and intialize it */
 
 	dev = kmalloc (sizeof(struct lego_usb_tower), GFP_KERNEL);
@@ -931,7 +924,7 @@
 		err("Couldn't allocate read_buffer");
 		goto error;
 	}
-	dev->interrupt_in_buffer = kmalloc (dev->interrupt_in_endpoint->wMaxPacketSize, GFP_KERNEL);
+	dev->interrupt_in_buffer = kmalloc (le16_to_cpu(dev->interrupt_in_endpoint->wMaxPacketSize), GFP_KERNEL);
 	if (!dev->interrupt_in_buffer) {
 		err("Couldn't allocate interrupt_in_buffer");
 		goto error;
diff -Nru a/drivers/usb/misc/tiglusb.c b/drivers/usb/misc/tiglusb.c
--- a/drivers/usb/misc/tiglusb.c	2005-03-01 23:38:44 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,592 +0,0 @@
-/* Hey EMACS -*- linux-c -*-
- *
- * tiglusb -- Texas Instruments' USB GraphLink (aka SilverLink) driver.
- * Target: Texas Instruments graphing calculators (http://lpg.ticalc.org).
- *
- * Copyright (C) 2001-2004:
- *   Romain Lievin <roms@tilp.info>
- *   Julien BLACHE <jb@technologeek.org>
- * under the terms of the GNU General Public License.
- *
- * Based on dabusb.c, printer.c & scanner.c
- *
- * Please see the file: Documentation/usb/silverlink.txt
- * and the website at:  http://lpg.ticalc.org/prj_usb/
- * for more info.
- *
- * History:
- *   1.0x, Romain & Julien: initial submit.
- *   1.03, Greg Kroah: modifications.
- *   1.04, Julien: clean-up & fixes; Romain: 2.4 backport.
- *   1.05, Randy Dunlap: bug fix with the timeout parameter (divide-by-zero).
- *   1.06, Romain: synched with 2.5, version/firmware changed (confusing).
- *   1.07, Romain: fixed bad use of usb_clear_halt (invalid argument);
- *          timeout argument checked in ioctl + clean-up.
- *   1.08, Romain: added support of USB port embedded on some TI's handhelds.
- */
-
-#include <linux/module.h>
-#include <linux/socket.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <asm/uaccess.h>
-#include <linux/delay.h>
-#include <linux/usb.h>
-#include <linux/smp_lock.h>
-#include <linux/devfs_fs_kernel.h>
-#include <linux/device.h>
-
-#include <linux/ticable.h>
-#include "tiglusb.h"
-
-/*
- * Version Information
- */
-#define DRIVER_VERSION "1.08"
-#define DRIVER_AUTHOR  "Romain Lievin <roms@tilp.info> & Julien Blache <jb@jblache.org>"
-#define DRIVER_DESC    "TI-GRAPH LINK USB (aka SilverLink) driver"
-#define DRIVER_LICENSE "GPL"
-
-/* ----- global variables --------------------------------------------- */
-
-static tiglusb_t tiglusb[MAXTIGL];
-static int timeout = TIMAXTIME;	/* timeout in tenth of seconds     */
-static struct class_simple *tiglusb_class;
-
-/*---------- misc functions ------------------------------------------- */
-
-/*
- * Re-initialize device
- */
-static inline int
-clear_device (struct usb_device *dev)
-{
-	if (usb_reset_configuration (dev) < 0) {
-		err ("clear_device failed");
-		return -1;
-	}
-
-	return 0;
-}
-
-/* 
- * Clear input & output pipes (endpoints)
- */
-static inline int
-clear_pipes (struct usb_device *dev)
-{
-	unsigned int pipe;
-
-	pipe = usb_sndbulkpipe (dev, 2);
-	if (usb_clear_halt (dev, pipe)) {
-		err ("clear_pipe (w), request failed");
-		return -1;
-	}
-
-	pipe = usb_rcvbulkpipe (dev, 1);
-	if (usb_clear_halt (dev, pipe)) {
-		err ("clear_pipe (r), request failed");
-		return -1;
-	}
-
-	return 0;
-}
-
-/* ----- file operations functions--------------------------------------- */
-
-static int
-tiglusb_open (struct inode *inode, struct file *filp)
-{
-	int devnum = iminor(inode);
-	ptiglusb_t s;
-
-	if (devnum < TIUSB_MINOR || devnum >= (TIUSB_MINOR + MAXTIGL))
-		return -EIO;
-
-	s = &tiglusb[devnum - TIUSB_MINOR];
-
-	if (down_interruptible (&s->mutex)) {
-		return -ERESTARTSYS;
-	}
-
-	while (!s->dev || s->opened) {
-		up (&s->mutex);
-
-		if (filp->f_flags & O_NONBLOCK) {
-			return -EBUSY;
-		}
-
-		msleep_interruptible(500);
-
-		if (signal_pending (current)) {
-			return -EAGAIN;
-		}
-
-		if (down_interruptible (&s->mutex)) {
-			return -ERESTARTSYS;
-		}
-	}
-
-	s->opened = 1;
-	up (&s->mutex);
-
-	filp->f_pos = 0;
-	filp->private_data = s;
-
-	return nonseekable_open(inode, filp);
-}
-
-static int
-tiglusb_release (struct inode *inode, struct file *filp)
-{
-	ptiglusb_t s = (ptiglusb_t) filp->private_data;
-
-	if (down_interruptible (&s->mutex)) {
-		return -ERESTARTSYS;
-	}
-
-	s->state = _stopped;
-	up (&s->mutex);
-
-	if (!s->remove_pending)
-		clear_device (s->dev);
-	else
-		wake_up (&s->remove_ok);
-
-	s->opened = 0;
-
-	return 0;
-}
-
-static ssize_t
-tiglusb_read (struct file *filp, char __user *buf, size_t count, loff_t * f_pos)
-{
-	ptiglusb_t s = (ptiglusb_t) filp->private_data;
-	ssize_t ret = 0;
-	int bytes_to_read = 0;
-	int bytes_read = 0;
-	int result = 0;
-	char *buffer;
-	unsigned int pipe;
-
-	if (*f_pos)
-		return -ESPIPE;
-
-	if (s->remove_pending)
-		return -EIO;
-
-	if (!s->dev)
-		return -EIO;
-
-	buffer = kmalloc (s->max_ps, GFP_KERNEL);
-	if (!buffer)
-		return -ENOMEM;
-
-	bytes_to_read = (count >= s->max_ps) ? s->max_ps : count;
-
-	pipe = usb_rcvbulkpipe (s->dev, 1);
-	result = usb_bulk_msg (s->dev, pipe, buffer, bytes_to_read,
-			       &bytes_read, (HZ * timeout) / 10);
-	if (result == -ETIMEDOUT) {	/* NAK */
-		if (!bytes_read)
-			dbg ("quirk !");
-		warn ("tiglusb_read, NAK received.");
-		ret = result;
-		goto out;
-	} else if (result == -EPIPE) {	/* STALL -- shouldn't happen */
-		warn ("clear_halt request to remove STALL condition.");
-		if (usb_clear_halt (s->dev, pipe))
-			err ("clear_halt, request failed");
-		clear_device (s->dev);
-		ret = result;
-		goto out;
-	} else if (result < 0) {	/* We should not get any I/O errors */
-		err ("funky result: %d. Please notify maintainer.", result);
-		ret = -EIO;
-		goto out;
-	}
-
-	if (copy_to_user (buf, buffer, bytes_read)) {
-		ret = -EFAULT;
-	}
-
-      out:
-	kfree(buffer);
-	return ret ? ret : bytes_read;
-}
-
-static ssize_t
-tiglusb_write (struct file *filp, const char __user *buf, size_t count, loff_t * f_pos)
-{
-	ptiglusb_t s = (ptiglusb_t) filp->private_data;
-	ssize_t ret = 0;
-	int bytes_to_write = 0;
-	int bytes_written = 0;
-	int result = 0;
-	char *buffer;
-	unsigned int pipe;
-
-	if (*f_pos)
-		return -ESPIPE;
-
-	if (s->remove_pending)
-		return -EIO;
-
-	if (!s->dev)
-		return -EIO;
-
-	buffer = kmalloc (s->max_ps, GFP_KERNEL);
-	if (!buffer)
-		return -ENOMEM;
-
-	bytes_to_write = (count >= s->max_ps) ? s->max_ps : count;
-	if (copy_from_user (buffer, buf, bytes_to_write)) {
-		ret = -EFAULT;
-		goto out;
-	}
-
-	pipe = usb_sndbulkpipe (s->dev, 2);
-	result = usb_bulk_msg (s->dev, pipe, buffer, bytes_to_write,
-			       &bytes_written, (HZ * timeout) / 10);
-
-	if (result == -ETIMEDOUT) {	/* NAK */
-		warn ("tiglusb_write, NAK received.");
-		ret = result;
-		goto out;
-	} else if (result == -EPIPE) {	/* STALL -- shouldn't happen */
-		warn ("clear_halt request to remove STALL condition.");
-		if (usb_clear_halt (s->dev, pipe))
-			err ("clear_halt, request failed");
-		clear_device (s->dev);
-		ret = result;
-		goto out;
-	} else if (result < 0) {	/* We should not get any I/O errors */
-		warn ("funky result: %d. Please notify maintainer.", result);
-		ret = -EIO;
-		goto out;
-	}
-
-	if (bytes_written != bytes_to_write) {
-		ret = -EIO;
-	}
-
-      out:
-	kfree(buffer);
-	return ret ? ret : bytes_written;
-}
-
-static int
-tiglusb_ioctl (struct inode *inode, struct file *filp,
-	       unsigned int cmd, unsigned long arg)
-{
-	ptiglusb_t s = (ptiglusb_t) filp->private_data;
-	int ret = 0;
-
-	if (s->remove_pending)
-		return -EIO;
-
-	if (down_interruptible (&s->mutex)) {
-		return -ERESTARTSYS;
-	}
-
-	if (!s->dev) {
-		up (&s->mutex);
-		return -EIO;
-	}
-
-	switch (cmd) {
-	case IOCTL_TIUSB_TIMEOUT:
-		if (arg > 0)
-			timeout = arg;
-		else
-			ret = -EINVAL;
-		break;
-	case IOCTL_TIUSB_RESET_DEVICE:
-		if (clear_device (s->dev))
-			ret = -EIO;
-		break;
-	case IOCTL_TIUSB_RESET_PIPES:
-		if (clear_pipes (s->dev))
-			ret = -EIO;
-		break;
-	case IOCTL_TIUSB_GET_MAXPS:
-                if (copy_to_user((int __user *) arg, &s->max_ps, sizeof(int)))
-                        return -EFAULT;
-                break;
-        case IOCTL_TIUSB_GET_DEVID:
-                if (copy_to_user((int __user *) arg, &s->dev->descriptor.idProduct,
-                                 sizeof(int)))
-                        return -EFAULT;
-                break;
-	default:
-		ret = -ENOTTY;
-		break;
-	}
-
-	up (&s->mutex);
-
-	return ret;
-}
-
-/* ----- kernel module registering ------------------------------------ */
-
-static struct file_operations tiglusb_fops = {
-	.owner =	THIS_MODULE,
-	.llseek =	no_llseek,
-	.read =		tiglusb_read,
-	.write =	tiglusb_write,
-	.ioctl =	tiglusb_ioctl,
-	.open =		tiglusb_open,
-	.release =	tiglusb_release,
-};
-
-/* --- initialisation code ------------------------------------- */
-
-static int
-tiglusb_probe (struct usb_interface *intf,
-	       const struct usb_device_id *id)
-{
-	struct usb_device *dev = interface_to_usbdev(intf);
-	int minor = -1;
-	int i, err = 0;
-	ptiglusb_t s;
-	struct usb_host_config *conf;
-        struct usb_host_interface *ifdata = NULL;
-        int max_ps;
-
-	dbg ("probing vendor id 0x%x, device id 0x%x",
-	     dev->descriptor.idVendor, dev->descriptor.idProduct);
-
-	/*
-	 * We don't handle multiple configurations. As of version 0x0103 of
-	 * the TIGL hardware, there's only 1 configuration.
-	 */
-
-	if (dev->descriptor.bNumConfigurations != 1) {
-		err = -ENODEV;
-		goto out;
-	}
-
-	if (dev->descriptor.idVendor != 0x451) {
-		err = -ENODEV;
-		goto out;
-	}
-
-	if ((dev->descriptor.idProduct != 0xe001) &&
-            (dev->descriptor.idProduct != 0xe004) &&
-            (dev->descriptor.idProduct != 0xe008)) {
-                err = -ENODEV;
-                goto out;
-        }
-
-	/*
-         * TI introduced some new handhelds with embedded USB port.
-         * Port advertises same config as SilverLink cable but with a 
-	 * different maximum packet size (64 rather than 32).
-         */
-
-        conf = dev->actconfig;
-        ifdata = conf->interface[0]->cur_altsetting;
-        max_ps = ifdata->endpoint[0].desc.wMaxPacketSize;
-
-        info("max packet size of %d/%d bytes\n",
-             ifdata->endpoint[0].desc.wMaxPacketSize,
-             ifdata->endpoint[1].desc.wMaxPacketSize);
-
-	/*
-	 * Find a tiglusb struct
-	 */
-	for (i = 0; i < MAXTIGL; i++) {
-		ptiglusb_t s = &tiglusb[i];
-		if (!s->dev) {
-			minor = i;
-			break;
-		}
-	}
-
-	if (minor == -1) {
-		err = -ENODEV;
-		goto out;
-	}
-
-	s = &tiglusb[minor];
-
-	down (&s->mutex);
-	s->remove_pending = 0;
-	s->dev = dev;
-	s->max_ps = max_ps;
-	up (&s->mutex);
-	dbg ("bound to interface");
-
-	class_simple_device_add(tiglusb_class, MKDEV(TIUSB_MAJOR, TIUSB_MINOR + s->minor),
-			NULL, "usb%d", s->minor);
-	err = devfs_mk_cdev(MKDEV(TIUSB_MAJOR, TIUSB_MINOR) + s->minor,
-			S_IFCHR | S_IRUGO | S_IWUGO,
-			"ticables/usb/%d", s->minor);
-
-	if (err)
-		goto out_class;
-
-	/* Display firmware version */
-	info ("firmware revision %i.%02x",
-		dev->descriptor.bcdDevice >> 8,
-		dev->descriptor.bcdDevice & 0xff);
-
-	usb_set_intfdata (intf, s);
-	err = 0;
-	goto out;
-
-out_class:
-	class_simple_device_remove(MKDEV(TIUSB_MAJOR, TIUSB_MINOR + s->minor));
-out:
-	return err;
-}
-
-static void
-tiglusb_disconnect (struct usb_interface *intf)
-{
-	wait_queue_t __wait;
-	ptiglusb_t s = usb_get_intfdata (intf);
-	
-	init_waitqueue_entry(&__wait, current);
-	
-
-	usb_set_intfdata (intf, NULL);
-	if (!s || !s->dev) {
-		info ("bogus disconnect");
-		return;
-	}
-
-	s->remove_pending = 1;
-	wake_up (&s->wait);
-	add_wait_queue(&s->wait, &__wait);
-	set_current_state(TASK_UNINTERRUPTIBLE);
-	if (s->state == _started)
-		schedule();
-	current->state = TASK_RUNNING;
-	remove_wait_queue(&s->wait, &__wait);
-	down (&s->mutex);
-	s->dev = NULL;
-	s->opened = 0;
-
-	class_simple_device_remove(MKDEV(TIUSB_MAJOR, TIUSB_MINOR + s->minor));
-	devfs_remove("ticables/usb/%d", s->minor);
-
-	info ("device %d removed", s->minor);
-
-	up (&s->mutex);
-}
-
-static struct usb_device_id tiglusb_ids[] = {
-	{USB_DEVICE (0x0451, 0xe001)},
-	{}
-};
-
-MODULE_DEVICE_TABLE (usb, tiglusb_ids);
-
-static struct usb_driver tiglusb_driver = {
-	.owner =	THIS_MODULE,
-	.name =		"tiglusb",
-	.probe =	tiglusb_probe,
-	.disconnect =	tiglusb_disconnect,
-	.id_table =	tiglusb_ids,
-};
-
-/* --- initialisation code ------------------------------------- */
-
-#ifndef MODULE
-/*
- * You can use 'tiusb=timeout' to set timeout.
- */
-static int __init
-tiglusb_setup (char *str)
-{
-	int ints[2];
-
-	str = get_options (str, ARRAY_SIZE (ints), ints);
-
-	if (ints[0] > 0) {
-		if (ints[1] > 0)
-			timeout = ints[1];
-		else
-			info ("tiglusb: wrong timeout value (0), using default value.");
-	}
-
-	return 1;
-}
-#endif
-
-static int __init
-tiglusb_init (void)
-{
-	unsigned u;
-	int result, err = 0;
-
-	/* initialize struct */
-	for (u = 0; u < MAXTIGL; u++) {
-		ptiglusb_t s = &tiglusb[u];
-		memset (s, 0, sizeof (tiglusb_t));
-		init_MUTEX (&s->mutex);
-		s->dev = NULL;
-		s->minor = u;
-		s->opened = 0;
-		init_waitqueue_head (&s->wait);
-		init_waitqueue_head (&s->remove_ok);
-	}
-
-	/* register device */
-	if (register_chrdev (TIUSB_MAJOR, "tiglusb", &tiglusb_fops)) {
-		err ("unable to get major %d", TIUSB_MAJOR);
-		err = -EIO;
-		goto out;
-	}
-
-	/* Use devfs, tree: /dev/ticables/usb/[0..3] */
-	devfs_mk_dir ("ticables/usb");
-
-	tiglusb_class = class_simple_create(THIS_MODULE, "tiglusb");
-	if (IS_ERR(tiglusb_class)) {
-		err = PTR_ERR(tiglusb_class);
-		goto out_chrdev;
-	}
-	/* register USB module */
-	result = usb_register (&tiglusb_driver);
-	if (result < 0) {
-		err = -1;
-		goto out_chrdev;
-	}
-
-	info (DRIVER_DESC ", version " DRIVER_VERSION);
-
-	err = 0;
-	goto out;
-
-out_chrdev:
-	unregister_chrdev (TIUSB_MAJOR, "tiglusb");
-out:
-	return err;
-}
-
-static void __exit
-tiglusb_cleanup (void)
-{
-	usb_deregister (&tiglusb_driver);
-	class_simple_destroy(tiglusb_class);
-	devfs_remove("ticables/usb");
-	unregister_chrdev (TIUSB_MAJOR, "tiglusb");
-}
-
-/* --------------------------------------------------------------------- */
-
-__setup ("tiusb=", tiglusb_setup);
-module_init (tiglusb_init);
-module_exit (tiglusb_cleanup);
-
-MODULE_AUTHOR (DRIVER_AUTHOR);
-MODULE_DESCRIPTION (DRIVER_DESC);
-MODULE_LICENSE (DRIVER_LICENSE);
-
-module_param(timeout, int, 0);
-MODULE_PARM_DESC (timeout, "Timeout in tenths of seconds (default=1.5 seconds)");
-
-/* --------------------------------------------------------------------- */
diff -Nru a/drivers/usb/misc/tiglusb.h b/drivers/usb/misc/tiglusb.h
--- a/drivers/usb/misc/tiglusb.h	2005-03-01 23:39:17 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,43 +0,0 @@
-/* Hey EMACS -*- linux-c -*-
- *
- * tiglusb - low level driver for SilverLink cable
- *
- * Copyright (C) 2000-2002, Romain Lievin <roms@lpg.ticalc.org>
- * under the terms of the GNU General Public License.
- *
- * Redistribution of this file is permitted under the terms of the GNU
- * Public License (GPL)
- */
-
-#ifndef _TIGLUSB_H
-#define _TIGLUSB_H
-
-/*
- * Max. number of devices supported
- */
-#define MAXTIGL		16
-
-/*
- * The driver context...
- */
-
-typedef enum { _stopped=0, _started } driver_state_t;
-
-typedef struct
-{
-	struct usb_device	*dev;		/* USB device handle */
-	struct semaphore	mutex;		/* locks this struct */
-
-	wait_queue_head_t	wait;		/* for timed waits */
-	wait_queue_head_t	remove_ok;
-
-	int		minor;			/* which minor dev #? */
-
-	driver_state_t	state;			/* started/stopped */
-	int		opened;			/* tru if open */
-	int	remove_pending;
-
-	int             max_ps;                 /* max packet size */
-} tiglusb_t, *ptiglusb_t;
-
-#endif
diff -Nru a/drivers/usb/misc/usblcd.c b/drivers/usb/misc/usblcd.c
--- a/drivers/usb/misc/usblcd.c	2005-03-01 23:38:44 -08:00
+++ b/drivers/usb/misc/usblcd.c	2005-03-01 23:38:44 -08:00
@@ -74,7 +74,7 @@
 	  unsigned long arg)
 {
 	struct lcd_usb_data *lcd = &lcd_instance;
-	int i;
+	u16 bcdDevice;
 	char buf[30];
 
 	/* Sanity check to make sure lcd is connected, powered, etc */
@@ -85,9 +85,12 @@
 
 	switch (cmd) {
 	case IOCTL_GET_HARD_VERSION:
-		i = (lcd->lcd_dev)->descriptor.bcdDevice;
-		sprintf(buf,"%1d%1d.%1d%1d",(i & 0xF000)>>12,(i & 0xF00)>>8,
-			(i & 0xF0)>>4,(i & 0xF));
+		bcdDevice = le16_to_cpu((lcd->lcd_dev)->descriptor.bcdDevice);
+		sprintf(buf,"%1d%1d.%1d%1d",
+			(bcdDevice & 0xF000)>>12,
+			(bcdDevice & 0xF00)>>8,
+			(bcdDevice & 0xF0)>>4,
+			(bcdDevice & 0xF));
 		if (copy_to_user((void __user *)arg,buf,strlen(buf))!=0)
 			return -EFAULT;
 		break;
@@ -258,7 +261,7 @@
 	int i;
 	int retval;
 
-	if (dev->descriptor.idProduct != 0x0001  ) {
+	if (le16_to_cpu(dev->descriptor.idProduct) != 0x0001) {
 		warn(KERN_INFO "USBLCD model not supported.");
 		return -ENODEV;
 	}
@@ -268,7 +271,7 @@
 		return -ENODEV;
 	}
 
-	i = dev->descriptor.bcdDevice;
+	i = le16_to_cpu(dev->descriptor.bcdDevice);
 
 	info("USBLCD Version %1d%1d.%1d%1d found at address %d",
 		(i & 0xF000)>>12,(i & 0xF00)>>8,(i & 0xF0)>>4,(i & 0xF),
diff -Nru a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
--- a/drivers/usb/misc/usbtest.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/usb/misc/usbtest.c	2005-03-01 23:39:16 -08:00
@@ -527,10 +527,9 @@
 		return 0;
 	}
 
-	le16_to_cpus (&config->wTotalLength);
-	if (config->wTotalLength == len)		/* read it all */
+	if (le16_to_cpu(config->wTotalLength) == len)		/* read it all */
 		return 1;
-	if (config->wTotalLength >= TBUF_SIZE)		/* max partial read */
+	if (le16_to_cpu(config->wTotalLength) >= TBUF_SIZE)		/* max partial read */
 		return 1;
 	dbg ("bogus config descriptor read size");
 	return 0;
@@ -636,7 +635,7 @@
 	}
 
 	/* and sometimes [9.2.6.6] speed dependent descriptors */
-	if (udev->descriptor.bcdUSB == 0x0200) {	/* pre-swapped */
+	if (le16_to_cpu(udev->descriptor.bcdUSB) == 0x0200) {
 		struct usb_qualifier_descriptor		*d = NULL;
 
 		/* device qualifier [9.6.2] */
@@ -954,13 +953,13 @@
 		case 13:	// short read, resembling case 10
 			req.wValue = cpu_to_le16 ((USB_DT_CONFIG << 8) | 0);
 			// last data packet "should" be DATA1, not DATA0
-			len = 1024 - udev->epmaxpacketin [0];
+			len = 1024 - udev->descriptor.bMaxPacketSize0;
 			expected = -EREMOTEIO;
 			break;
 		case 14:	// short read; try to fill the last packet
 			req.wValue = cpu_to_le16 ((USB_DT_DEVICE << 8) | 0);
 			// device descriptor size == 18 bytes 
-			len = udev->epmaxpacketin [0];
+			len = udev->descriptor.bMaxPacketSize0;
 			switch (len) {
 			case 8:		len = 24; break;
 			case 16:	len = 32; break;
@@ -1205,7 +1204,7 @@
 	struct urb	*urb;
 
 	urb = simple_alloc_urb (testdev_to_usbdev (dev), 0, 512);
-	if (urb == 0)
+	if (urb == NULL)
 		return -ENOMEM;
 
 	if (dev->in_pipe) {
@@ -1372,8 +1371,8 @@
 
 	if (bytes < 0 || !desc)
 		return NULL;
-	maxp = 0x7ff & desc->wMaxPacketSize;
-	maxp *= 1 + (0x3 & (desc->wMaxPacketSize >> 11));
+	maxp = 0x7ff & le16_to_cpu(desc->wMaxPacketSize);
+	maxp *= 1 + (0x3 & (le16_to_cpu(desc->wMaxPacketSize) >> 11));
 	packets = (bytes + maxp - 1) / maxp;
 
 	urb = usb_alloc_urb (packets, SLAB_KERNEL);
@@ -1433,7 +1432,7 @@
 		"... iso period %d %sframes, wMaxPacket %04x\n",
 		1 << (desc->bInterval - 1),
 		(udev->speed == USB_SPEED_HIGH) ? "micro" : "",
-		desc->wMaxPacketSize);
+		le16_to_cpu(desc->wMaxPacketSize));
 
 	for (i = 0; i < param->sglen; i++) {
 		urbs [i] = iso_alloc_urb (udev, pipe, desc,
@@ -1842,13 +1841,13 @@
 	/* specify devices by module parameters? */
 	if (id->match_flags == 0) {
 		/* vendor match required, product match optional */
-		if (!vendor || udev->descriptor.idVendor != (u16)vendor)
+		if (!vendor || le16_to_cpu(udev->descriptor.idVendor) != (u16)vendor)
 			return -ENODEV;
-		if (product && udev->descriptor.idProduct != (u16)product)
+		if (product && le16_to_cpu(udev->descriptor.idProduct) != (u16)product)
 			return -ENODEV;
 		dbg ("matched module params, vend=0x%04x prod=0x%04x",
-				udev->descriptor.idVendor,
-				udev->descriptor.idProduct);
+				le16_to_cpu(udev->descriptor.idVendor),
+				le16_to_cpu(udev->descriptor.idProduct));
 	}
 #endif
 
@@ -1863,7 +1862,7 @@
 	dev->intf = intf;
 
 	/* cacheline-aligned scratch for i/o */
-	if ((dev->buf = kmalloc (TBUF_SIZE, SLAB_KERNEL)) == 0) {
+	if ((dev->buf = kmalloc (TBUF_SIZE, SLAB_KERNEL)) == NULL) {
 		kfree (dev);
 		return -ENOMEM;
 	}
diff -Nru a/drivers/usb/misc/uss720.c b/drivers/usb/misc/uss720.c
--- a/drivers/usb/misc/uss720.c	2005-03-01 23:38:44 -08:00
+++ b/drivers/usb/misc/uss720.c	2005-03-01 23:38:44 -08:00
@@ -544,7 +544,8 @@
 	int i;
 
 	printk(KERN_DEBUG "uss720: probe: vendor id 0x%x, device id 0x%x\n",
-	       usbdev->descriptor.idVendor, usbdev->descriptor.idProduct);
+	       le16_to_cpu(usbdev->descriptor.idVendor),
+	       le16_to_cpu(usbdev->descriptor.idProduct));
 
 	/* our known interfaces have 3 alternate settings */
 	if (intf->num_altsetting != 3)
diff -Nru a/drivers/usb/net/catc.c b/drivers/usb/net/catc.c
--- a/drivers/usb/net/catc.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/usb/net/catc.c	2005-03-01 23:38:57 -08:00
@@ -800,8 +800,9 @@
 	}
 
 	/* The F5U011 has the same vendor/product as the netmate but a device version of 0x130 */
-	if (usbdev->descriptor.idVendor == 0x0423 && usbdev->descriptor.idProduct == 0xa &&
-	   catc->usbdev->descriptor.bcdDevice == 0x0130	) {
+	if (le16_to_cpu(usbdev->descriptor.idVendor) == 0x0423 && 
+	    le16_to_cpu(usbdev->descriptor.idProduct) == 0xa &&
+	    le16_to_cpu(catc->usbdev->descriptor.bcdDevice) == 0x0130) {
 		dbg("Testing for f5u011");
 		catc->is_f5u011 = 1;		
 		atomic_set(&catc->recq_sz, 0);
diff -Nru a/drivers/usb/net/kaweth.c b/drivers/usb/net/kaweth.c
--- a/drivers/usb/net/kaweth.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/usb/net/kaweth.c	2005-03-01 23:39:08 -08:00
@@ -160,6 +160,7 @@
 	{ USB_DEVICE(0x1342, 0x0204) }, /* Mobility USB-Ethernet Adapter */
 	{ USB_DEVICE(0x13d2, 0x0400) }, /* Shark Pocket Adapter */
 	{ USB_DEVICE(0x1485, 0x0001) },	/* Silicom U2E */
+	{ USB_DEVICE(0x1485, 0x0002) }, /* Psion Dacom Gold Port Ethernet */
 	{ USB_DEVICE(0x1645, 0x0005) }, /* Entrega E45 */
 	{ USB_DEVICE(0x1645, 0x0008) }, /* Entrega USB Ethernet Adapter */
 	{ USB_DEVICE(0x1645, 0x8005) }, /* PortGear Ethernet Adapter */
@@ -903,9 +904,9 @@
 
 	kaweth_dbg("Kawasaki Device Probe (Device number:%d): 0x%4.4x:0x%4.4x:0x%4.4x",
 		 dev->devnum,
-		 (int)dev->descriptor.idVendor,
-		 (int)dev->descriptor.idProduct,
-		 (int)dev->descriptor.bcdDevice);
+		 le16_to_cpu(dev->descriptor.idVendor),
+		 le16_to_cpu(dev->descriptor.idProduct),
+		 le16_to_cpu(dev->descriptor.bcdDevice));
 
 	kaweth_dbg("Device at %p", dev);
 
@@ -933,7 +934,7 @@
 	 * downloaded. Don't try to do it again, or we'll hang the device.
 	 */
 
-	if (dev->descriptor.bcdDevice >> 8) {
+	if (le16_to_cpu(dev->descriptor.bcdDevice) >> 8) {
 		kaweth_info("Firmware present in device.");
 	} else {
 		/* Download the firmware */
diff -Nru a/drivers/usb/net/pegasus.c b/drivers/usb/net/pegasus.c
--- a/drivers/usb/net/pegasus.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/usb/net/pegasus.c	2005-03-01 23:39:17 -08:00
@@ -28,6 +28,8 @@
  * 			is out of the interrupt routine.
  */
 
+#undef	DEBUG
+
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/init.h>
@@ -45,7 +47,7 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v0.5.12 (2003/06/06)"
+#define DRIVER_VERSION "v0.5.12 (2005/01/13)"
 #define DRIVER_AUTHOR "Petko Manolov <petkan@users.sourceforge.net>"
 #define DRIVER_DESC "Pegasus/Pegasus II USB Ethernet driver"
 
@@ -712,11 +714,11 @@
 {
 	pegasus_t *pegasus = urb->context;
 	struct net_device *net;
-	__u8 *d;
 	int status;
 
 	if (!pegasus)
 		return;
+	net = pegasus->net;
 
 	switch (urb->status) {
 	case 0:
@@ -726,36 +728,50 @@
 	case -ESHUTDOWN:
 		return;
 	default:
-		info("intr status %d", urb->status);
+		/* some Pegasus-I products report LOTS of data
+		 * toggle errors... avoid log spamming
+		 */
+		pr_debug("%s: intr status %d\n", net->name, urb->status);
 	}
 
-	d = urb->transfer_buffer;
-	net = pegasus->net;
-	if (d[0] & 0xfc) {
-		pegasus->stats.tx_errors++;
-		if (d[0] & TX_UNDERRUN)
-			pegasus->stats.tx_fifo_errors++;
-		if (d[0] & (EXCESSIVE_COL | JABBER_TIMEOUT))
-			pegasus->stats.tx_aborted_errors++;
-		if (d[0] & LATE_COL)
-			pegasus->stats.tx_window_errors++;
-		if (d[5] & LINK_STATUS) {
-			netif_carrier_on(net);
-		} else {
-			pegasus->stats.tx_carrier_errors++;
-			netif_carrier_off(net);	
+	if (urb->actual_length >= 6) {
+		u8	* d = urb->transfer_buffer;
+
+		/* byte 0 == tx_status1, reg 2B */
+		if (d[0] & (TX_UNDERRUN|EXCESSIVE_COL
+					|LATE_COL|JABBER_TIMEOUT)) {
+			pegasus->stats.tx_errors++;
+			if (d[0] & TX_UNDERRUN)
+				pegasus->stats.tx_fifo_errors++;
+			if (d[0] & (EXCESSIVE_COL | JABBER_TIMEOUT))
+				pegasus->stats.tx_aborted_errors++;
+			if (d[0] & LATE_COL)
+				pegasus->stats.tx_window_errors++;
 		}
+
+		/* d[5].LINK_STATUS lies on some adapters.
+		 * d[0].NO_CARRIER kicks in only with failed TX.
+		 * ... so monitoring with MII may be safest.
+		 */
+		if (d[0] & NO_CARRIER)
+			netif_carrier_off(net);	
+		else
+			netif_carrier_on(net);
+
+		/* bytes 3-4 == rx_lostpkt, reg 2E/2F */
+		pegasus->stats.rx_missed_errors += ((d[3] & 0x7f) << 8) | d[4];
 	}
 
 	status = usb_submit_urb(urb, SLAB_ATOMIC);
 	if (status)
-		err("%s: can't resubmit interrupt urb, %d", net->name, status);
+		printk(KERN_ERR "%s: can't resubmit interrupt urb, %d\n",
+				net->name, status);
 }
 
 static void pegasus_tx_timeout(struct net_device *net)
 {
 	pegasus_t *pegasus = netdev_priv(net);
-	warn("%s: Tx timed out.", net->name);
+	printk(KERN_WARNING "%s: tx timeout\n", net->name);
 	pegasus->tx_urb->transfer_flags |= URB_ASYNC_UNLINK;
 	usb_unlink_urb(pegasus->tx_urb);
 	pegasus->stats.tx_errors++;
@@ -948,14 +964,57 @@
 	usb_make_path(pegasus->usb, info->bus_info, sizeof (info->bus_info));
 }
 
-#ifdef	CONFIG_MII
-static int pegasus_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
+/* also handles three patterns of some kind in hardware */
+#define	WOL_SUPPORTED	(WAKE_MAGIC|WAKE_PHY)
+
+static void
+pegasus_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+	pegasus_t	*pegasus = netdev_priv(dev);
+
+	wol->supported = WAKE_MAGIC | WAKE_PHY;
+	wol->wolopts = pegasus->wolopts;
+}
+
+static int
+pegasus_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+	pegasus_t	*pegasus = netdev_priv(dev);
+	u8		reg78 = 0x04;
+	
+	if (wol->wolopts & ~WOL_SUPPORTED)
+		return -EINVAL;
+
+	if (wol->wolopts & WAKE_MAGIC)
+		reg78 |= 0x80;
+	if (wol->wolopts & WAKE_PHY)
+		reg78 |= 0x40;
+	if (wol->wolopts)
+		pegasus->eth_regs[0] |= 0x10;
+	else
+		pegasus->eth_regs[0] &= ~0x10;
+	pegasus->wolopts = wol->wolopts;
+	return set_register(pegasus, WakeupControl, reg78);
+}
+
+static inline void
+pegasus_reset_wol(struct net_device *dev)
+{
+	struct ethtool_wolinfo wol;
+	
+	memset(&wol, 0, sizeof wol);
+	(void) pegasus_set_wol(dev, &wol);
+}
+
+static int
+pegasus_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 {
 	pegasus_t *pegasus = netdev_priv(dev);
 	mii_ethtool_gset(&pegasus->mii, ecmd);
 	return 0;
 }
-static int pegasus_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
+static int
+pegasus_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 {
 	pegasus_t *pegasus = netdev_priv(dev);
 	return mii_ethtool_sset(&pegasus->mii, ecmd);
@@ -975,19 +1034,14 @@
 
 static u32 pegasus_get_msglevel(struct net_device *dev)
 {
-	/*
-	 * pegasus_t *pegasus = netdev_priv(dev);
-	 * return pegasus->msg_enable; FIXME
-	 */
-	return 0;
+	pegasus_t *pegasus = netdev_priv(dev);
+	return pegasus->msg_level;
 }
 
 static void pegasus_set_msglevel(struct net_device *dev, u32 v)
 {
-	/*
-	 * pegasus_t *pegasus = netdev_priv(dev);
-	 * pegasus->msg_enable = edata.data; FIXME
-	 */
+	pegasus_t *pegasus = netdev_priv(dev);
+	pegasus->msg_level = v;
 }
 
 static struct ethtool_ops ops = {
@@ -998,58 +1052,10 @@
 	.get_link = pegasus_get_link,
 	.get_msglevel = pegasus_get_msglevel,
 	.set_msglevel = pegasus_set_msglevel,
+	.get_wol = pegasus_get_wol,
+	.set_wol = pegasus_set_wol,
 };
 
-#else
-
-static int pegasus_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
-{
-	pegasus_t *pegasus = netdev_priv(dev);
-	short lpa, bmcr;
-	u8 port;
-
-	ecmd->supported = (SUPPORTED_10baseT_Half |
-			  SUPPORTED_10baseT_Full |
-			  SUPPORTED_100baseT_Half |
-			  SUPPORTED_100baseT_Full |
-			  SUPPORTED_Autoneg |
-			  SUPPORTED_TP | SUPPORTED_MII);
-	get_registers(pegasus, Reg7b, 1, &port);
-	if (port == 0)
-		ecmd->port = PORT_MII;
-	else
-		ecmd->port = PORT_TP;
-	ecmd->transceiver = XCVR_INTERNAL;
-	ecmd->phy_address = pegasus->phy;
-	read_mii_word(pegasus, pegasus->phy, MII_BMCR, &bmcr);
-	read_mii_word(pegasus, pegasus->phy, MII_LPA, &lpa);
-	if (bmcr & BMCR_ANENABLE) {
-		ecmd->autoneg = AUTONEG_ENABLE;
-		ecmd->speed = lpa & (LPA_100HALF | LPA_100FULL) ?
-		    SPEED_100 : SPEED_10;
-		if (ecmd->speed == SPEED_100)
-			ecmd->duplex = lpa & LPA_100FULL ?
-			    DUPLEX_FULL : DUPLEX_HALF;
-		else
-			ecmd->duplex = lpa & LPA_10FULL ?
-			    DUPLEX_FULL : DUPLEX_HALF;
-	} else {
-		ecmd->autoneg = AUTONEG_DISABLE;
-		ecmd->speed = bmcr & BMCR_SPEED100 ?
-		    SPEED_100 : SPEED_10;
-		ecmd->duplex = bmcr & BMCR_FULLDPLX ?
-		    DUPLEX_FULL : DUPLEX_HALF;
-	}
-	return 0;
-}
-
-static struct ethtool_ops ops = {
-	.get_drvinfo = pegasus_get_drvinfo,
-	.get_settings = pegasus_get_settings,
-	.get_link = ethtool_op_get_link,
-};
-#endif
-
 static int pegasus_ioctl(struct net_device *net, struct ifreq *rq, int cmd)
 {
 	__u16 *data = (__u16 *) & rq->ifr_ifru;
@@ -1081,12 +1087,12 @@
 
 	if (net->flags & IFF_PROMISC) {
 		pegasus->eth_regs[EthCtrl2] |= RX_PROMISCUOUS;
-		info("%s: Promiscuous mode enabled", net->name);
+		pr_info("%s: Promiscuous mode enabled.\n", net->name);
 	} else if ((net->mc_count > multicast_filter_limit) ||
 		   (net->flags & IFF_ALLMULTI)) {
 		pegasus->eth_regs[EthCtrl0] |= RX_MULTICAST;
 		pegasus->eth_regs[EthCtrl2] &= ~RX_PROMISCUOUS;
-		info("%s set allmulti", net->name);
+		pr_info("%s: set allmulti\n", net->name);
 	} else {
 		pegasus->eth_regs[EthCtrl0] &= ~RX_MULTICAST;
 		pegasus->eth_regs[EthCtrl2] &= ~RX_PROMISCUOUS;
@@ -1180,7 +1186,6 @@
 	net->hard_start_xmit = pegasus_start_xmit;
 	net->set_multicast_list = pegasus_set_multicast;
 	net->get_stats = pegasus_netdev_stats;
-	net->mtu = PEGASUS_MTU;
 	SET_ETHTOOL_OPS(net, &ops);
 	pegasus->mii.dev = net;
 	pegasus->mii.mdio_read = mdio_read;
@@ -1192,27 +1197,28 @@
 	pegasus->features = usb_dev_id[dev_index].private;
 	get_interrupt_interval(pegasus);
 	if (reset_mac(pegasus)) {
-		err("can't reset MAC");
+		dev_err(&intf->dev, "can't reset MAC\n");
 		res = -EIO;
 		goto out2;
 	}
 	set_ethernet_addr(pegasus);
 	fill_skb_pool(pegasus);
 	if (pegasus->features & PEGASUS_II) {
-		info("setup Pegasus II specific registers");
+		dev_info(&intf->dev, "setup Pegasus II specific registers\n");
 		setup_pegasus_II(pegasus);
 	}
 	pegasus->phy = mii_phy_probe(pegasus);
 	if (pegasus->phy == 0xff) {
-		warn("can't locate MII phy, using default");
+		dev_warn(&intf->dev, "can't locate MII phy, using default\n");
 		pegasus->phy = 1;
 	}
 	usb_set_intfdata(intf, pegasus);
 	SET_NETDEV_DEV(net, &intf->dev);
+	pegasus_reset_wol(net);
 	res = register_netdev(net);
 	if (res)
 		goto out3;
-	printk("%s: %s\n", net->name, usb_dev_id[dev_index].name);
+	pr_info("%s: %s\n", net->name, usb_dev_id[dev_index].name);
 	return 0;
 
 out3:
@@ -1247,16 +1253,34 @@
 	free_netdev(pegasus->net);
 }
 
+static int pegasus_suspend (struct usb_interface *intf, u32 state)
+{
+	struct pegasus *pegasus = usb_get_intfdata(intf);
+	
+	netif_device_detach (pegasus->net);
+	return 0;
+}
+
+static int pegasus_resume (struct usb_interface *intf)
+{
+	struct pegasus *pegasus = usb_get_intfdata(intf);
+
+	netif_device_attach (pegasus->net);
+	return 0;
+}
+
 static struct usb_driver pegasus_driver = {
 	.name = driver_name,
 	.probe = pegasus_probe,
 	.disconnect = pegasus_disconnect,
 	.id_table = pegasus_ids,
+	.suspend = pegasus_suspend,
+	.resume = pegasus_resume,
 };
 
 static int __init pegasus_init(void)
 {
-	info(DRIVER_VERSION ":" DRIVER_DESC);
+	pr_info("%s: %s, " DRIVER_DESC "\n", driver_name, DRIVER_VERSION);
 	return usb_register(&pegasus_driver);
 }
 
diff -Nru a/drivers/usb/net/pegasus.h b/drivers/usb/net/pegasus.h
--- a/drivers/usb/net/pegasus.h	2005-03-01 23:39:17 -08:00
+++ b/drivers/usb/net/pegasus.h	2005-03-01 23:39:17 -08:00
@@ -76,6 +76,7 @@
 	EthTxStat0 = 0x2b,
 	EthTxStat1 = 0x2c,
 	EthRxStat = 0x2d,
+	WakeupControl = 0x78,
 	Reg7b = 0x7b,
 	Gpio0 = 0x7e,
 	Gpio1 = 0x7f,
@@ -90,6 +91,8 @@
 	struct mii_if_info	mii;
 	unsigned		flags;
 	unsigned		features;
+	u32			msg_level;
+	u32			wolopts;
 	int			dev_index;
 	int			intr_interval;
 	struct tasklet_struct	rx_tl;
diff -Nru a/drivers/usb/net/usbnet.c b/drivers/usb/net/usbnet.c
--- a/drivers/usb/net/usbnet.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/usb/net/usbnet.c	2005-03-01 23:38:58 -08:00
@@ -745,7 +745,7 @@
 	dev->out = usb_sndbulkpipe(dev->udev, 2);
 
 	// allocate irq urb
-	if ((data->int_urb = usb_alloc_urb (0, GFP_KERNEL)) == 0) {
+	if ((data->int_urb = usb_alloc_urb (0, GFP_KERNEL)) == NULL) {
 		dbg ("%s: cannot allocate interrupt URB",
 			dev->net->name);
 		return -ENOMEM;
@@ -1298,7 +1298,7 @@
 	struct gl_packet	packets;
 };
 
-#ifdef	GENLINK_ACK
+#ifdef	GENELINK_ACK
 
 // FIXME:  this code is incomplete, not debugged; it doesn't
 // handle interrupts correctly.  interrupts should be generic
@@ -2265,14 +2265,34 @@
 	.unbind =	cdc_unbind,
 	.tx_fixup = 	zaurus_tx_fixup,
 };
+#define	ZAURUS_STRONGARM_INFO	((unsigned long)&zaurus_sl5x00_info)
+
 static const struct driver_info	zaurus_pxa_info = {
 	.description =	"Sharp Zaurus, PXA-2xx based",
 	.flags =	FLAG_FRAMING_Z,
 	.check_connect = always_connected,
+	.bind =		generic_cdc_bind,
+	.unbind =	cdc_unbind,
 	.tx_fixup = 	zaurus_tx_fixup,
+};
+#define	ZAURUS_PXA_INFO		((unsigned long)&zaurus_pxa_info)
 
-	.in = 1, .out = 2,
+static const struct driver_info	olympus_mxl_info = {
+	.description =	"Olympus R1000",
+	.flags =	FLAG_FRAMING_Z,
+	.check_connect = always_connected,
+	.bind =		generic_cdc_bind,
+	.unbind =	cdc_unbind,
+	.tx_fixup = 	zaurus_tx_fixup,
 };
+#define	OLYMPUS_MXL_INFO	((unsigned long)&olympus_mxl_info)
+
+#else
+
+/* blacklist all those devices */
+#define	ZAURUS_STRONGARM_INFO	0
+#define	ZAURUS_PXA_INFO		0
+#define	OLYMPUS_MXL_INFO	0
 
 #endif
 
@@ -2384,7 +2404,7 @@
 #endif
 		size = (sizeof (struct ethhdr) + dev->net->mtu);
 
-	if ((skb = alloc_skb (size, flags)) == 0) {
+	if ((skb = alloc_skb (size, flags)) == NULL) {
 		devdbg (dev, "no rx skb");
 		defer_kevent (dev, EVENT_RX_MEMORY);
 		usb_free_urb (urb);
@@ -2741,7 +2761,7 @@
 	if (test_bit (EVENT_TX_HALT, &dev->flags)) {
 		unlink_urbs (dev, &dev->txq);
 		status = usb_clear_halt (dev->udev, dev->out);
-		if (status < 0)
+		if (status < 0 && status != -EPIPE)
 			deverr (dev, "can't clear tx halt, status %d",
 				status);
 		else {
@@ -2752,7 +2772,7 @@
 	if (test_bit (EVENT_RX_HALT, &dev->flags)) {
 		unlink_urbs (dev, &dev->rxq);
 		status = usb_clear_halt (dev->udev, dev->in);
-		if (status < 0)
+		if (status < 0 && status != -EPIPE)
 			deverr (dev, "can't clear rx halt, status %d",
 				status);
 		else {
@@ -2769,7 +2789,7 @@
 			urb = usb_alloc_urb (0, GFP_KERNEL);
 		else
 			clear_bit (EVENT_RX_MEMORY, &dev->flags);
-		if (urb != 0) {
+		if (urb != NULL) {
 			clear_bit (EVENT_RX_MEMORY, &dev->flags);
 			rx_submit (dev, urb, GFP_KERNEL);
 			tasklet_schedule (&dev->bh);
@@ -2996,7 +3016,8 @@
 
 			// don't refill the queue all at once
 			for (i = 0; i < 10 && dev->rxq.qlen < qlen; i++) {
-				if ((urb = usb_alloc_urb (0, GFP_ATOMIC)) != 0)
+				urb = usb_alloc_urb (0, GFP_ATOMIC);
+				if (urb != NULL)
 					rx_submit (dev, urb, GFP_ATOMIC);
 			}
 			if (temp != dev->rxq.qlen)
@@ -3265,6 +3286,10 @@
 	// Surecom EP-1427X-2
 	USB_DEVICE (0x1189, 0x0893),
 	.driver_info = (unsigned long) &ax8817x_info,
+}, {
+	// goodway corp usb gwusb2e
+	USB_DEVICE (0x1631, 0x6200),
+	.driver_info = (unsigned long) &ax8817x_info,
 },
 #endif
 
@@ -3354,12 +3379,15 @@
 }, 
 #endif
 
-#ifdef	CONFIG_USB_ZAURUS
+#if	defined(CONFIG_USB_ZAURUS) || defined(CONFIG_USB_CDCETHER)
 /*
  * SA-1100 based Sharp Zaurus ("collie"), or compatible.
  * Same idea as above, but different framing.
  *
  * PXA-2xx based models are also lying-about-cdc.
+ *
+ * NOTE:  These entries do double-duty, serving as blacklist entries
+ * whenever Zaurus support isn't enabled, but CDC Ethernet is.
  */
 {
 	.match_flags	=   USB_DEVICE_ID_MATCH_INT_INFO
@@ -3370,82 +3398,79 @@
 	.bInterfaceClass	= USB_CLASS_COMM,
 	.bInterfaceSubClass	= 6 /* Ethernet model */,
 	.bInterfaceProtocol	= 0,
-	.driver_info =  (unsigned long) &zaurus_sl5x00_info,
+	.driver_info = ZAURUS_STRONGARM_INFO,
 }, {
 	.match_flags	=   USB_DEVICE_ID_MATCH_INT_INFO
 			  | USB_DEVICE_ID_MATCH_DEVICE, 
 	.idVendor		= 0x04DD,
 	.idProduct		= 0x8005,	/* A-300 */
-	.bInterfaceClass	= 0x02,
-	.bInterfaceSubClass	= 0x0a,
+	.bInterfaceClass	= USB_CLASS_COMM,
+	.bInterfaceSubClass	= 6 /* Ethernet model */,
 	.bInterfaceProtocol	= 0x00,
-	.driver_info =  (unsigned long) &zaurus_pxa_info,
+	.driver_info = ZAURUS_PXA_INFO,
 }, {
 	.match_flags	=   USB_DEVICE_ID_MATCH_INT_INFO
 			  | USB_DEVICE_ID_MATCH_DEVICE, 
 	.idVendor		= 0x04DD,
 	.idProduct		= 0x8006,	/* B-500/SL-5600 */
-	.bInterfaceClass	= 0x02,
-	.bInterfaceSubClass	= 0x0a,
+	.bInterfaceClass	= USB_CLASS_COMM,
+	.bInterfaceSubClass	= 6 /* Ethernet model */,
 	.bInterfaceProtocol	= 0x00,
-	.driver_info =  (unsigned long) &zaurus_pxa_info,
+	.driver_info = ZAURUS_PXA_INFO,
 }, {
 	.match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
 	          | USB_DEVICE_ID_MATCH_DEVICE,
 	.idVendor		= 0x04DD,
 	.idProduct		= 0x8007,	/* C-700 */
-	.bInterfaceClass    = 0x02,
-	.bInterfaceSubClass = 0x0a,
+	.bInterfaceClass	= USB_CLASS_COMM,
+	.bInterfaceSubClass	= 6 /* Ethernet model */,
 	.bInterfaceProtocol = 0x00,
-	.driver_info =  (unsigned long) &zaurus_pxa_info,
+	.driver_info = ZAURUS_PXA_INFO,
 }, {
 	.match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
 		 | USB_DEVICE_ID_MATCH_DEVICE,
 	.idVendor               = 0x04DD,
 	.idProduct              = 0x9031,	/* C-750 C-760 */
-	.bInterfaceClass        = 0x02,
-	.bInterfaceSubClass     = 0x0a,
+	.bInterfaceClass	= USB_CLASS_COMM,
+	.bInterfaceSubClass	= 6 /* Ethernet model */,
 	.bInterfaceProtocol     = 0x00,
-	.driver_info =  (unsigned long) &zaurus_pxa_info,
+	.driver_info = ZAURUS_PXA_INFO,
 }, {
 	.match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
 		 | USB_DEVICE_ID_MATCH_DEVICE,
 	.idVendor               = 0x04DD,
 	.idProduct              = 0x9032,	/* SL-6000 */
-	.bInterfaceClass        = 0x02,
-	.bInterfaceSubClass     = 0x0a,
+	.bInterfaceClass	= USB_CLASS_COMM,
+	.bInterfaceSubClass	= 6 /* Ethernet model */,
 	.bInterfaceProtocol     = 0x00,
-	.driver_info =  (unsigned long) &zaurus_pxa_info,
+	.driver_info = ZAURUS_PXA_INFO,
 }, {
 	.match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
 		 | USB_DEVICE_ID_MATCH_DEVICE,
 	.idVendor               = 0x04DD,
 	.idProduct              = 0x9050,	/* C-860 */
-	.bInterfaceClass        = 0x02,
-	.bInterfaceSubClass     = 0x0a,
+	.bInterfaceClass	= USB_CLASS_COMM,
+	.bInterfaceSubClass	= 6 /* Ethernet model */,
 	.bInterfaceProtocol     = 0x00,
-	.driver_info =  (unsigned long) &zaurus_pxa_info,
+	.driver_info = ZAURUS_PXA_INFO,
 },
-#endif
 
-#ifdef	CONFIG_USB_CDCETHER
-
-#ifndef	CONFIG_USB_ZAURUS
-	/* if we couldn't whitelist Zaurus, we must blacklist it */
+/* Olympus has some models with a Zaurus-compatible option.
+ * R-1000 uses a FreeScale i.MXL cpu (ARMv4T)
+ */
 {
-	.match_flags	=   USB_DEVICE_ID_MATCH_INT_INFO
-			  | USB_DEVICE_ID_MATCH_DEVICE, 
-	.idVendor		= 0x04DD,
-	.idProduct		= 0x8004,
-	/* match the master interface */
+	.match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
+		 | USB_DEVICE_ID_MATCH_DEVICE,
+	.idVendor               = 0x07B4,
+	.idProduct              = 0x0F02,	/* R-1000 */
 	.bInterfaceClass	= USB_CLASS_COMM,
 	.bInterfaceSubClass	= 6 /* Ethernet model */,
-	.bInterfaceProtocol	= 0,
-	.driver_info 		= 0, /* BLACKLIST */
+	.bInterfaceProtocol     = 0x00,
+	.driver_info = OLYMPUS_MXL_INFO,
 },
-	// FIXME blacklist the other Zaurus models too, sigh
 #endif
 
+#ifdef	CONFIG_USB_CDCETHER
 {
 	/* CDC Ether uses two interfaces, not necessarily consecutive.
 	 * We match the main interface, ignoring the optional device
diff -Nru a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig
--- a/drivers/usb/serial/Kconfig	2005-03-01 23:39:08 -08:00
+++ b/drivers/usb/serial/Kconfig	2005-03-01 23:39:08 -08:00
@@ -202,6 +202,19 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called io_ti.
 
+config USB_SERIAL_GARMIN
+       tristate "USB Garmin GPS driver"
+       depends on USB_SERIAL
+       help
+         Say Y here if you want to connect to your Garmin GPS.
+         Should work with most Garmin GPS devices which have a native USB port.
+
+         See <http://sourceforge.net/projects/garmin-gps> for the latest
+         version of the driver.
+
+         To compile this driver as a module, choose M here: the
+         module will be called garmin_gps.
+
 config USB_SERIAL_IPW
         tristate "USB IPWireless (3G UMTS TDD) Driver (EXPERIMENTAL)"
 	depends on USB_SERIAL && EXPERIMENTAL
@@ -379,6 +392,16 @@
 config USB_SERIAL_SAFE_PADDED
 	bool "USB Secure Encapsulated Driver - Padded"
 	depends on USB_SERIAL_SAFE
+
+config USB_SERIAL_TI
+	tristate "USB TI 3410/5052 Serial Driver"
+	depends on USB_SERIAL
+	help
+	  Say Y here if you want to use the TI USB 3410 or 5052
+	  serial devices.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called ti_usb_3410_5052.
 
 config USB_SERIAL_CYBERJACK
 	tristate "USB REINER SCT cyberJack pinpad/e-com chipcard reader (EXPERIMENTAL)"
diff -Nru a/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile
--- a/drivers/usb/serial/Makefile	2005-03-01 23:38:53 -08:00
+++ b/drivers/usb/serial/Makefile	2005-03-01 23:38:53 -08:00
@@ -19,6 +19,7 @@
 obj-$(CONFIG_USB_SERIAL_EDGEPORT_TI)		+= io_ti.o
 obj-$(CONFIG_USB_SERIAL_EMPEG)			+= empeg.o
 obj-$(CONFIG_USB_SERIAL_FTDI_SIO)		+= ftdi_sio.o
+obj-$(CONFIG_USB_SERIAL_GARMIN)			+= garmin_gps.o
 obj-$(CONFIG_USB_SERIAL_IPAQ)			+= ipaq.o
 obj-$(CONFIG_USB_SERIAL_IPW)			+= ipw.o
 obj-$(CONFIG_USB_SERIAL_IR)			+= ir-usb.o
@@ -30,6 +31,7 @@
 obj-$(CONFIG_USB_SERIAL_OMNINET)		+= omninet.o
 obj-$(CONFIG_USB_SERIAL_PL2303)			+= pl2303.o
 obj-$(CONFIG_USB_SERIAL_SAFE)			+= safe_serial.o
+obj-$(CONFIG_USB_SERIAL_TI)			+= ti_usb_3410_5052.o
 obj-$(CONFIG_USB_SERIAL_VISOR)			+= visor.o
 obj-$(CONFIG_USB_SERIAL_WHITEHEAT)		+= whiteheat.o
 obj-$(CONFIG_USB_SERIAL_XIRCOM)			+= keyspan_pda.o
diff -Nru a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c
--- a/drivers/usb/serial/belkin_sa.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/usb/serial/belkin_sa.c	2005-03-01 23:38:58 -08:00
@@ -181,8 +181,8 @@
 	priv->last_lsr = 0;
 	priv->last_msr = 0;
 	/* see comments at top of file */
-	priv->bad_flow_control = (dev->descriptor.bcdDevice <= 0x0206) ? 1 : 0;
-	info("bcdDevice: %04x, bfc: %d", dev->descriptor.bcdDevice, priv->bad_flow_control);
+	priv->bad_flow_control = (le16_to_cpu(dev->descriptor.bcdDevice) <= 0x0206) ? 1 : 0;
+	info("bcdDevice: %04x, bfc: %d", le16_to_cpu(dev->descriptor.bcdDevice), priv->bad_flow_control);
 
 	init_waitqueue_head(&serial->port[0]->write_wait);
 	usb_set_serial_port_data(serial->port[0], priv);
diff -Nru a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c
--- a/drivers/usb/serial/cypress_m8.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/usb/serial/cypress_m8.c	2005-03-01 23:38:52 -08:00
@@ -18,6 +18,12 @@
  *
  *
  *  Lonnie Mendez <dignome@gmail.com>
+ *  12-15-2004
+ *	Incorporated write buffering from pl2303 driver.  Fixed bug with line
+ *	handling so both lines are raised in cypress_open. (was dropping rts)
+ *      Various code cleanups made as well along with other misc bug fixes.
+ *
+ *  Lonnie Mendez <dignome@gmail.com>
  *  04-10-2004
  *	Driver modified to support dynamic line settings.  Various improvments
  *      and features.
@@ -30,9 +36,11 @@
  * Long Term TODO:
  *	Improve transfer speeds - both read/write are somewhat slow
  *   at this point.
+ *      Improve debugging.  Show modem line status with debug output and
+ *   implement filtering for certain data as a module parameter.
  */
 
-/* Neil Whelchel wrote the cypress m8 implementation */
+/* Thanks to Neil Whelchel for writing the first cypress m8 implementation for linux. */
 /* Thanks to cypress for providing references for the hid reports. */
 /* Thanks to Jiang Zhang for providing links and for general help. */
 /* Code originates and was built up from ftdi_sio, belkin, pl2303 and others. */
@@ -53,24 +61,28 @@
 #include <linux/usb.h>
 #include <linux/serial.h>
 
+#include "usb-serial.h"
+#include "cypress_m8.h"
+
+
 #ifdef CONFIG_USB_SERIAL_DEBUG
 	static int debug = 1;
 #else
 	static int debug;
 #endif
-
 static int stats;
 
-#include "usb-serial.h"
-#include "cypress_m8.h"
-
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v1.06"
+#define DRIVER_VERSION "v1.08"
 #define DRIVER_AUTHOR "Lonnie Mendez <dignome@gmail.com>, Neil Whelchel <koyama@firstlight.net>"
 #define DRIVER_DESC "Cypress USB to Serial Driver"
 
+/* write buffer size defines */
+#define CYPRESS_BUF_SIZE	1024
+#define CYPRESS_CLOSING_WAIT	(30*HZ)
+
 static struct usb_device_id id_table_earthmate [] = {
 	{ USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB) },
 	{ }						/* Terminating entry */
@@ -103,6 +115,8 @@
 	int bytes_out;			   /* used for statistics */
 	int cmd_count;			   /* used for statistics */
 	int cmd_ctrl;			   /* always set this to 1 before issuing a command */
+	struct cypress_buf *buf;	   /* write buffer */
+	int write_urb_in_use;		   /* write urb in use indicator */
 	int termios_initialized;
 	__u8 line_control;	   	   /* holds dtr / rts value */
 	__u8 current_status;	   	   /* received from last read - info on dsr,cts,cd,ri,etc */
@@ -115,8 +129,15 @@
 	char prev_status, diff_status;	   /* used for TIOCMIWAIT */
 	/* we pass a pointer to this as the arguement sent to cypress_set_termios old_termios */
 	struct termios tmp_termios; 	   /* stores the old termios settings */
-	int write_interval;		   /* interrupt out write interval, as obtained from interrupt_out_urb */
-	int writepipe;			   /* used for clear halt, if necessary */
+	char calledfromopen;		   /* used when issuing lines on open - fixes rts drop bug */
+};
+
+/* write buffer structure */
+struct cypress_buf {
+	unsigned int	buf_size;
+	char		*buf_buf;
+	char		*buf_get;
+	char		*buf_put;
 };
 
 /* function prototypes for the Cypress USB to serial device */
@@ -126,6 +147,7 @@
 static int  cypress_open		(struct usb_serial_port *port, struct file *filp);
 static void cypress_close		(struct usb_serial_port *port, struct file *filp);
 static int  cypress_write		(struct usb_serial_port *port, const unsigned char *buf, int count);
+static void cypress_send		(struct usb_serial_port *port);
 static int  cypress_write_room		(struct usb_serial_port *port);
 static int  cypress_ioctl		(struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg);
 static void cypress_set_termios		(struct usb_serial_port *port, struct termios * old);
@@ -136,8 +158,20 @@
 static void cypress_unthrottle		(struct usb_serial_port *port);
 static void cypress_read_int_callback	(struct urb *urb, struct pt_regs *regs);
 static void cypress_write_int_callback	(struct urb *urb, struct pt_regs *regs);
-static int  mask_to_rate		(unsigned mask);
-static unsigned rate_to_mask		(int rate);
+/* baud helper functions */
+static int	 mask_to_rate		(unsigned mask);
+static unsigned  rate_to_mask		(int rate);
+/* write buffer functions */
+static struct cypress_buf *cypress_buf_alloc(unsigned int size);
+static void 		  cypress_buf_free(struct cypress_buf *cb);
+static void		  cypress_buf_clear(struct cypress_buf *cb);
+static unsigned int	  cypress_buf_data_avail(struct cypress_buf *cb);
+static unsigned int	  cypress_buf_space_avail(struct cypress_buf *cb);
+static unsigned int	  cypress_buf_put(struct cypress_buf *cb, const char *buf,
+					  unsigned int count);
+static unsigned int	  cypress_buf_get(struct cypress_buf *cb, char *buf,
+					  unsigned int count);
+
 
 static struct usb_serial_device_type cypress_earthmate_device = {
 	.owner =			THIS_MODULE,
@@ -394,25 +428,19 @@
 
 	memset(priv, 0x00, sizeof (struct cypress_private));
 	spin_lock_init(&priv->lock);
+	priv->buf = cypress_buf_alloc(CYPRESS_BUF_SIZE);
+	if (priv->buf == NULL) {
+		kfree(priv);
+		return -ENOMEM;
+	}
 	init_waitqueue_head(&priv->delta_msr_wait);
-	priv->writepipe = serial->port[0]->interrupt_out_urb->pipe;
 	
-	/* free up interrupt_out buffer / urb allocated by usbserial
- 	 * for this port as we use our own urbs for writing */
-	if (serial->port[0]->interrupt_out_buffer) {
-		kfree(serial->port[0]->interrupt_out_buffer);
-		serial->port[0]->interrupt_out_buffer = NULL;
-	}
-	if (serial->port[0]->interrupt_out_urb) {
-		priv->write_interval = serial->port[0]->interrupt_out_urb->interval;
-		usb_free_urb(serial->port[0]->interrupt_out_urb);
-		serial->port[0]->interrupt_out_urb = NULL;
-	} else /* still need a write interval */
-		priv->write_interval = 10;
-
+	usb_reset_configuration (serial->dev);
+	
 	priv->cmd_ctrl = 0;
 	priv->line_control = 0;
 	priv->termios_initialized = 0;
+	priv->calledfromopen = 0;
 	priv->rx_flags = 0;
 	usb_set_serial_port_data(serial->port[0], priv);
 	
@@ -467,6 +495,7 @@
 	priv = usb_get_serial_port_data(serial->port[0]);
 
 	if (priv) {
+		cypress_buf_free(priv->buf);
 		kfree(priv);
 		usb_set_serial_port_data(serial->port[0], NULL);
 	}
@@ -482,37 +511,39 @@
 
 	dbg("%s - port %d", __FUNCTION__, port->number);
 
+	/* clear halts before open */
+	usb_clear_halt(serial->dev, 0x00);
+	usb_clear_halt(serial->dev, 0x81);
+	usb_clear_halt(serial->dev, 0x02);
+
 	spin_lock_irqsave(&priv->lock, flags);
 	/* reset read/write statistics */
 	priv->bytes_in = 0;
 	priv->bytes_out = 0;
 	priv->cmd_count = 0;
-
-	/* turn on dtr / rts since we are not flow controlling by default */
-	priv->line_control = CONTROL_DTR | CONTROL_RTS; /* sent in status byte */
+	priv->rx_flags = 0;
 	spin_unlock_irqrestore(&priv->lock, flags);
-	priv->cmd_ctrl = 1;
-	result = cypress_write(port, NULL, 0);
-	
+
+	/* setting to zero could cause data loss */
 	port->tty->low_latency = 1;
 
-	/* termios defaults are set by usb_serial_init */
-	
-	cypress_set_termios(port, &priv->tmp_termios);
+	/* raise both lines and set termios */
+	spin_lock_irqsave(&priv->lock, flags);
+	priv->line_control = CONTROL_DTR | CONTROL_RTS;
+	priv->calledfromopen = 1;
+	priv->cmd_ctrl = 1;
+	spin_unlock_irqrestore(&priv->lock, flags);
+	result = cypress_write(port, NULL, 0);
 
 	if (result) {
 		dev_err(&port->dev, "%s - failed setting the control lines - error %d\n", __FUNCTION__, result);
 		return result;
 	} else
-		dbg("%s - success setting the control lines", __FUNCTION__);
+		dbg("%s - success setting the control lines", __FUNCTION__);	
 
-	/* throttling off */
-	spin_lock_irqsave(&priv->lock, flags);
-	priv->rx_flags = 0;
-	spin_unlock_irqrestore(&priv->lock, flags);
+	cypress_set_termios(port, &priv->tmp_termios);
 
-	/* setup the port and
-	 * start reading from the device */
+	/* setup the port and start reading from the device */
 	if(!port->interrupt_in_urb){
 		err("%s - interrupt_in_urb is empty!", __FUNCTION__);
 		return(-1);
@@ -537,9 +568,46 @@
 	struct cypress_private *priv = usb_get_serial_port_data(port);
 	unsigned int c_cflag;
 	unsigned long flags;
+	int bps;
+	long timeout;
+	wait_queue_t wait;
 
 	dbg("%s - port %d", __FUNCTION__, port->number);
 
+	/* wait for data to drain from buffer */
+	spin_lock_irqsave(&priv->lock, flags);
+	timeout = CYPRESS_CLOSING_WAIT;
+	init_waitqueue_entry(&wait, current);
+	add_wait_queue(&port->tty->write_wait, &wait);
+	for (;;) {
+		set_current_state(TASK_INTERRUPTIBLE);
+		if (cypress_buf_data_avail(priv->buf) == 0
+		|| timeout == 0 || signal_pending(current)
+		|| !usb_get_intfdata(port->serial->interface))
+			break;
+		spin_unlock_irqrestore(&priv->lock, flags);
+		timeout = schedule_timeout(timeout);
+		spin_lock_irqsave(&priv->lock, flags);
+	}
+	set_current_state(TASK_RUNNING);
+	remove_wait_queue(&port->tty->write_wait, &wait);
+	/* clear out any remaining data in the buffer */
+	cypress_buf_clear(priv->buf);
+	spin_unlock_irqrestore(&priv->lock, flags);
+	
+	/* wait for characters to drain from device */
+	bps = tty_get_baud_rate(port->tty);
+	if (bps > 1200)
+		timeout = max((HZ*2560)/bps,HZ/10);
+	else
+		timeout = 2*HZ;
+	set_current_state(TASK_INTERRUPTIBLE);
+	schedule_timeout(timeout);
+
+	dbg("%s - stopping urbs", __FUNCTION__);
+	usb_kill_urb (port->interrupt_in_urb);
+	usb_kill_urb (port->interrupt_out_urb);
+
 	if (port->tty) {
 		c_cflag = port->tty->termios->c_cflag;
 		if (c_cflag & HUPCL) {
@@ -553,11 +621,6 @@
 		}
 	}
 
-	if (port->interrupt_in_urb) {
-		dbg("%s - stopping read urb", __FUNCTION__);
-		usb_kill_urb (port->interrupt_in_urb);
-	}
-
 	if (stats)
 		dev_info (&port->dev, "Statistics: %d Bytes In | %d Bytes Out | %d Commands Issued\n",
 		          priv->bytes_in, priv->bytes_out, priv->cmd_count);
@@ -568,116 +631,145 @@
 {
 	struct cypress_private *priv = usb_get_serial_port_data(port);
 	unsigned long flags;
-	struct urb *urb;
-	int status, s_pos = 0;
-	__u8 transfer_size = 0;
-	__u8 *buffer;
-
-	dbg("%s - port %d", __FUNCTION__, port->number);
+	
+	dbg("%s - port %d, %d bytes", __FUNCTION__, port->number, count);
 
-	spin_lock_irqsave(&priv->lock, flags);
-	if (count == 0 && !priv->cmd_ctrl) {
-		spin_unlock_irqrestore(&priv->lock, flags);
-		dbg("%s - write request of 0 bytes", __FUNCTION__);
-		return 0;
+	/* line control commands, which need to be executed immediately,
+	   are not put into the buffer for obvious reasons.
+	 */
+	if (priv->cmd_ctrl) {
+		count = 0;
+		goto finish;
 	}
-
-	if (priv->cmd_ctrl)
-		++priv->cmd_count;
-	priv->cmd_ctrl = 0;
+	
+	if (!count)
+		return count;
+	
+	spin_lock_irqsave(&priv->lock, flags);
+	count = cypress_buf_put(priv->buf, buf, count);
 	spin_unlock_irqrestore(&priv->lock, flags);
 
-	dbg("%s - interrupt out size is %d", __FUNCTION__, port->interrupt_out_size);
-	dbg("%s - count is %d", __FUNCTION__, count);
+finish:
+	cypress_send(port);
 
-	/* Allocate buffer and urb */
-	buffer = kmalloc (port->interrupt_out_size, GFP_ATOMIC);
-	if (!buffer) {
-		dev_err(&port->dev, "ran out of memory for buffer\n");
-		return -ENOMEM;
-	}
+	return count;
+} /* cypress_write */
 
-	urb = usb_alloc_urb (0, GFP_ATOMIC);
-	if (!urb) {
-		dev_err(&port->dev, "failed allocating write urb\n");
-		kfree (buffer);
-		return -ENOMEM;
+
+static void cypress_send(struct usb_serial_port *port)
+{
+	int count = 0, result, offset, actual_size;
+	struct cypress_private *priv = usb_get_serial_port_data(port);
+	unsigned long flags;
+	
+	dbg("%s - port %d", __FUNCTION__, port->number);
+	dbg("%s - interrupt out size is %d", __FUNCTION__, port->interrupt_out_size);
+	
+	spin_lock_irqsave(&priv->lock, flags);
+	if (priv->write_urb_in_use) {
+		dbg("%s - can't write, urb in use", __FUNCTION__);
+		spin_unlock_irqrestore(&priv->lock, flags);
+		return;
 	}
+	spin_unlock_irqrestore(&priv->lock, flags);
 
-	memset(buffer, 0, port->interrupt_out_size); // test if this is needed... probably not since loop removed
+	/* clear buffer */
+	memset(port->interrupt_out_urb->transfer_buffer, 0, port->interrupt_out_size);
 
 	spin_lock_irqsave(&priv->lock, flags);
 	switch (port->interrupt_out_size) {
 		case 32:
 			// this is for the CY7C64013...
-			transfer_size = min (count, 30);
-			buffer[0] = priv->line_control;
-			buffer[1] = transfer_size;
-			s_pos = 2;
+			offset = 2;
+			port->interrupt_out_buffer[0] = priv->line_control;
 			break;
 		case 8:
 			// this is for the CY7C63743...
-			transfer_size = min (count, 7);
-			buffer[0] = priv->line_control | transfer_size;
-			s_pos = 1;
+			offset = 1;
+			port->interrupt_out_buffer[0] = priv->line_control;
 			break;
 		default:
 			dbg("%s - wrong packet size", __FUNCTION__);
 			spin_unlock_irqrestore(&priv->lock, flags);
-			kfree (buffer);
-			usb_free_urb (urb);
-			return -1;
+			return;
 	}
 
 	if (priv->line_control & CONTROL_RESET)
 		priv->line_control &= ~CONTROL_RESET;
-	spin_unlock_irqrestore(&priv->lock, flags);
-
-	/* copy data to offset position in urb transfer buffer */
-	memcpy (&buffer[s_pos], buf, transfer_size);
 
-	usb_serial_debug_data (debug, &port->dev, __FUNCTION__, port->interrupt_out_size, buffer);
+	if (priv->cmd_ctrl) {
+		priv->cmd_count++;
+		dbg("%s - line control command being issued", __FUNCTION__);
+		spin_unlock_irqrestore(&priv->lock, flags);
+		goto send;
+	} else
+		spin_unlock_irqrestore(&priv->lock, flags);
 
-	/* build up the urb */
-	usb_fill_int_urb (urb, port->serial->dev,
-			  usb_sndintpipe(port->serial->dev, port->interrupt_out_endpointAddress),
-			  buffer, port->interrupt_out_size,
-			  cypress_write_int_callback, port, priv->write_interval);
+	count = cypress_buf_get(priv->buf, &port->interrupt_out_buffer[offset],
+				port->interrupt_out_size-offset);
 
-	status = usb_submit_urb(urb, GFP_ATOMIC);
+	if (count == 0) {
+		return;
+	}
 
-	if (status) {
-		dev_err(&port->dev, "%s - usb_submit_urb (write interrupt) failed with status %d\n",
-			__FUNCTION__, status);
-		transfer_size = status;
-		kfree (buffer);
-		goto exit;
+	switch (port->interrupt_out_size) {
+		case 32:
+			port->interrupt_out_buffer[1] = count;
+			break;
+		case 8:
+			port->interrupt_out_buffer[0] |= count;
 	}
 
+	dbg("%s - count is %d", __FUNCTION__, count);
+
+send:
 	spin_lock_irqsave(&priv->lock, flags);
-	priv->bytes_out += transfer_size;
+	priv->write_urb_in_use = 1;
 	spin_unlock_irqrestore(&priv->lock, flags);
 
-exit:
-	/* buffer free'd in callback */
-	usb_free_urb (urb);
+	if (priv->cmd_ctrl)
+		actual_size = 1;
+	else
+		actual_size = count + (port->interrupt_out_size == 32 ? 2 : 1);
+	
+	usb_serial_debug_data(debug, &port->dev, __FUNCTION__, port->interrupt_out_size,
+			      port->interrupt_out_urb->transfer_buffer);
 
-	return transfer_size;
+	port->interrupt_out_urb->transfer_buffer_length = actual_size;
+	port->interrupt_out_urb->dev = port->serial->dev;
+	result = usb_submit_urb (port->interrupt_out_urb, GFP_ATOMIC);
+	if (result) {
+		dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __FUNCTION__,
+			result);
+		priv->write_urb_in_use = 0;
+	}
 
-} /* cypress_write */
+	spin_lock_irqsave(&priv->lock, flags);
+	if (priv->cmd_ctrl) {
+		priv->cmd_ctrl = 0;
+	}
+	priv->bytes_out += count; /* do not count the line control and size bytes */
+	spin_unlock_irqrestore(&priv->lock, flags);
 
+	schedule_work(&port->work);
+} /* cypress_send */
 
+
+/* returns how much space is available in the soft buffer */
 static int cypress_write_room(struct usb_serial_port *port)
 {
+	struct cypress_private *priv = usb_get_serial_port_data(port);
+	int room = 0;
+	unsigned long flags;
+
 	dbg("%s - port %d", __FUNCTION__, port->number);
 
-	/*
-	 * We really can take anything the user throw at us
-	 * but let's pick a nice big number to tell the tty
-	 * layer that we have lots of free space
-	 */	
+	spin_lock_irqsave(&priv->lock, flags);
+	room = cypress_buf_space_avail(priv->buf);
+	spin_unlock_irqrestore(&priv->lock, flags);
 
-	return 2048;
+	dbg("%s - returns %d", __FUNCTION__, room);
+	return room;
 }
 
 
@@ -816,6 +908,8 @@
 	int data_bits, stop_bits, parity_type, parity_enable;
 	unsigned cflag, iflag, baud_mask;
 	unsigned long flags;
+	__u8 oldlines;
+	int linechange;
 	
 	dbg("%s - port %d", __FUNCTION__, port->number);
 
@@ -880,6 +974,7 @@
 		data_bits = 3;
 
 	spin_lock_irqsave(&priv->lock, flags);
+	oldlines = priv->line_control;
 	if ((cflag & CBAUD) == B0) {
 		/* drop dtr and rts */
 		dbg("%s - dropping the lines, baud rate 0bps", __FUNCTION__);
@@ -902,11 +997,13 @@
 		}
 		priv->line_control |= CONTROL_DTR;
 		
-		/* this is probably not what I think it is... check into it */
-		if (cflag & CRTSCTS)
-			priv->line_control |= CONTROL_RTS;
-		else
-			priv->line_control &= ~CONTROL_RTS;
+		/* toggle CRTSCTS? - don't do this if being called from cypress_open */
+		if (!priv->calledfromopen) {
+			if (cflag & CRTSCTS)
+				priv->line_control |= CONTROL_RTS;
+			else
+				priv->line_control &= ~CONTROL_RTS;
+		}
 	}
 	spin_unlock_irqrestore(&priv->lock, flags);
 	
@@ -925,7 +1022,7 @@
 
 	/* Here we can define custom tty settings for devices
          *
-         * the main tty base comes from empeg.c
+         * the main tty termios flag base comes from empeg.c
          */
 
 	spin_lock_irqsave(&priv->lock, flags);	
@@ -959,33 +1056,37 @@
 
 		// Software app handling it for device...	
 
-	} else {
-		
-		/* do something here */
-
 	}
+	linechange = (priv->line_control != oldlines);
 	spin_unlock_irqrestore(&priv->lock, flags);
 
-	/* set lines */
-	priv->cmd_ctrl = 1;
-	cypress_write(port, NULL, 0);
+	/* if necessary, set lines */
+	if (!priv->calledfromopen && linechange) {
+		priv->cmd_ctrl = 1;
+		cypress_write(port, NULL, 0);
+	}
+
+	if (priv->calledfromopen)
+		priv->calledfromopen = 0;
 	
-	return;
 } /* cypress_set_termios */
 
-
+ 
+/* returns amount of data still left in soft buffer */
 static int cypress_chars_in_buffer(struct usb_serial_port *port)
 {
-	dbg("%s - port %d", __FUNCTION__, port->number);
+	struct cypress_private *priv = usb_get_serial_port_data(port);
+	int chars = 0;
+	unsigned long flags;
 
-	/*
-	 * We can't really account for how much data we
-	 * have sent out, but hasn't made it through to the
-	 * device, so just tell the tty layer that everything
-	 * is flushed.
-	 */
+	dbg("%s - port %d", __FUNCTION__, port->number);
+	
+	spin_lock_irqsave(&priv->lock, flags);
+	chars = cypress_buf_data_avail(priv->buf);
+	spin_unlock_irqrestore(&priv->lock, flags);
 
-	return 0;
+	dbg("%s - returns %d", __FUNCTION__, chars);
+	return chars;
 }
 
 
@@ -1032,10 +1133,11 @@
 	struct tty_struct *tty;
 	unsigned char *data = urb->transfer_buffer;
 	unsigned long flags;
-	char tty_flag = TTY_NORMAL;
-	int bytes=0;
+	char tty_flag = TTY_NORMAL;	
+	int havedata = 0;
+	int bytes = 0;
 	int result;
-	int i=0;
+	int i = 0;
 
 	dbg("%s - port %d", __FUNCTION__, port->number);
 
@@ -1046,6 +1148,7 @@
 
 	spin_lock_irqsave(&priv->lock, flags);
 	if (priv->rx_flags & THROTTLED) {
+		dbg("%s - now throttling", __FUNCTION__);
 		priv->rx_flags |= ACTUALLY_THROTTLED;
 		spin_unlock_irqrestore(&priv->lock, flags);
 		return;
@@ -1058,8 +1161,6 @@
 		return;
 	}
 
-	usb_serial_debug_data (debug, &port->dev, __FUNCTION__, urb->actual_length, data);
-	
 	spin_lock_irqsave(&priv->lock, flags);
 	switch(urb->actual_length) {
 		case 32:
@@ -1067,12 +1168,16 @@
 			priv->current_status = data[0] & 0xF8;
 			bytes = data[1]+2;
 			i=2;
+			if (bytes > 2)
+				havedata = 1;
 			break;
 		case 8:
 			// This is for the CY7C63743...
 			priv->current_status = data[0] & 0xF8;
 			bytes = (data[0] & 0x07)+1;
 			i=1;
+			if (bytes > 1)
+				havedata = 1;
 			break;
 		default:
 			dbg("%s - wrong packet size - received %d bytes", __FUNCTION__, urb->actual_length);
@@ -1081,6 +1186,8 @@
 	}
 	spin_unlock_irqrestore(&priv->lock, flags);
 
+	usb_serial_debug_data (debug, &port->dev, __FUNCTION__, urb->actual_length, data);
+
 	spin_lock_irqsave(&priv->lock, flags);
 	/* check to see if status has changed */
 	if (priv != NULL) {
@@ -1115,7 +1222,7 @@
 	/* process read if there is data other than line status */
 	if (tty && (bytes > i)) {
 		for (; i < bytes ; ++i) {
-			dbg("pushing byte number %d - %d",i,data[i]);
+			dbg("pushing byte number %d - %d - %c",i,data[i],data[i]);
 			if(tty->flip.count >= TTY_FLIPBUF_SIZE) {
 				tty_flip_buffer_push(tty);
 			}
@@ -1151,21 +1258,229 @@
 static void cypress_write_int_callback(struct urb *urb, struct pt_regs *regs)
 {
 	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
-
-	/* free up the transfer buffer, as usb_free_urb() does not do this */
-	kfree (urb->transfer_buffer);
+	struct cypress_private *priv = usb_get_serial_port_data(port);
+	int result;
 
 	dbg("%s - port %d", __FUNCTION__, port->number);
 	
-	if (urb->status) {
-		dbg("%s - nonzero write status received: %d", __FUNCTION__, urb->status);
-		return;
+	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);
+			priv->write_urb_in_use = 0;
+			return;
+		default:
+			/* error in the urb, so we have to resubmit it */
+			dbg("%s - Overflow in write", __FUNCTION__);
+			dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status);
+			port->interrupt_out_urb->transfer_buffer_length = 1;
+			port->interrupt_out_urb->dev = port->serial->dev;
+			result = usb_submit_urb(port->interrupt_out_urb, GFP_ATOMIC);
+			if (result)
+				dev_err(&urb->dev->dev, "%s - failed resubmitting write urb, error %d\n",
+					__FUNCTION__, result);
+			else
+				return;
 	}
+	
+	priv->write_urb_in_use = 0;
+	
+	/* send any buffered data */
+	cypress_send(port);
+}
+
+
+/*****************************************************************************
+ * Write buffer functions - buffering code from pl2303 used
+ *****************************************************************************/
+
+/*
+ * cypress_buf_alloc
+ *
+ * Allocate a circular buffer and all associated memory.
+ */
+
+static struct cypress_buf *cypress_buf_alloc(unsigned int size)
+{
+
+	struct cypress_buf *cb;
+
+
+	if (size == 0)
+		return NULL;
+
+	cb = (struct cypress_buf *)kmalloc(sizeof(struct cypress_buf), GFP_KERNEL);
+	if (cb == NULL)
+		return NULL;
+
+	cb->buf_buf = kmalloc(size, GFP_KERNEL);
+	if (cb->buf_buf == NULL) {
+		kfree(cb);
+		return NULL;
+	}
+
+	cb->buf_size = size;
+	cb->buf_get = cb->buf_put = cb->buf_buf;
+
+	return cb;
 
-	schedule_work(&port->work);
 }
 
 
+/*
+ * cypress_buf_free
+ *
+ * Free the buffer and all associated memory.
+ */
+
+static void cypress_buf_free(struct cypress_buf *cb)
+{
+	if (cb != NULL) {
+		if (cb->buf_buf != NULL)
+			kfree(cb->buf_buf);
+		kfree(cb);
+	}
+}
+
+
+/*
+ * cypress_buf_clear
+ *
+ * Clear out all data in the circular buffer.
+ */
+
+static void cypress_buf_clear(struct cypress_buf *cb)
+{
+	if (cb != NULL)
+		cb->buf_get = cb->buf_put;
+		/* equivalent to a get of all data available */
+}
+
+
+/*
+ * cypress_buf_data_avail
+ *
+ * Return the number of bytes of data available in the circular
+ * buffer.
+ */
+
+static unsigned int cypress_buf_data_avail(struct cypress_buf *cb)
+{
+	if (cb != NULL)
+		return ((cb->buf_size + cb->buf_put - cb->buf_get) % cb->buf_size);
+	else
+		return 0;
+}
+
+
+/*
+ * cypress_buf_space_avail
+ *
+ * Return the number of bytes of space available in the circular
+ * buffer.
+ */
+
+static unsigned int cypress_buf_space_avail(struct cypress_buf *cb)
+{
+	if (cb != NULL)
+		return ((cb->buf_size + cb->buf_get - cb->buf_put - 1) % cb->buf_size);
+	else
+		return 0;
+}
+
+
+/*
+ * cypress_buf_put
+ *
+ * Copy data data from a user buffer and put it into the circular buffer.
+ * Restrict to the amount of space available.
+ *
+ * Return the number of bytes copied.
+ */
+
+static unsigned int cypress_buf_put(struct cypress_buf *cb, const char *buf,
+	unsigned int count)
+{
+
+	unsigned int len;
+
+
+	if (cb == NULL)
+		return 0;
+
+	len  = cypress_buf_space_avail(cb);
+	if (count > len)
+		count = len;
+
+	if (count == 0)
+		return 0;
+
+	len = cb->buf_buf + cb->buf_size - cb->buf_put;
+	if (count > len) {
+		memcpy(cb->buf_put, buf, len);
+		memcpy(cb->buf_buf, buf+len, count - len);
+		cb->buf_put = cb->buf_buf + count - len;
+	} else {
+		memcpy(cb->buf_put, buf, count);
+		if (count < len)
+			cb->buf_put += count;
+		else /* count == len */
+			cb->buf_put = cb->buf_buf;
+	}
+
+	return count;
+
+}
+
+
+/*
+ * cypress_buf_get
+ *
+ * Get data from the circular buffer and copy to the given buffer.
+ * Restrict to the amount of data available.
+ *
+ * Return the number of bytes copied.
+ */
+
+static unsigned int cypress_buf_get(struct cypress_buf *cb, char *buf,
+	unsigned int count)
+{
+
+	unsigned int len;
+
+
+	if (cb == NULL)
+		return 0;
+
+	len = cypress_buf_data_avail(cb);
+	if (count > len)
+		count = len;
+
+	if (count == 0)
+		return 0;
+
+	len = cb->buf_buf + cb->buf_size - cb->buf_get;
+	if (count > len) {
+		memcpy(buf, cb->buf_get, len);
+		memcpy(buf+len, cb->buf_buf, count - len);
+		cb->buf_get = cb->buf_buf + count - len;
+	} else {
+		memcpy(buf, cb->buf_get, count);
+		if (count < len)
+			cb->buf_get += count;
+		else /* count == len */
+			cb->buf_get = cb->buf_buf;
+	}
+
+	return count;
+
+}
+
 /*****************************************************************************
  * Module functions
  *****************************************************************************/
@@ -1214,6 +1529,7 @@
 
 MODULE_AUTHOR( DRIVER_AUTHOR );
 MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_VERSION( DRIVER_VERSION );
 MODULE_LICENSE("GPL");
 
 module_param(debug, bool, S_IRUGO | S_IWUSR);
diff -Nru a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
--- a/drivers/usb/serial/ftdi_sio.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/usb/serial/ftdi_sio.c	2005-03-01 23:39:09 -08:00
@@ -372,6 +372,7 @@
 	{ 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) },
 	{ }						/* Terminating entry */
 };
 
@@ -486,6 +487,7 @@
 	{ 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) },
 	{ }						/* Terminating entry */
 };
 
@@ -608,6 +610,7 @@
 	{ USB_DEVICE(BANDB_VID, BANDB_USOTL4_PID) },
 	{ USB_DEVICE(BANDB_VID, BANDB_USTL4_PID) },
 	{ USB_DEVICE(BANDB_VID, BANDB_USO9ML2_PID) },
+	{ USB_DEVICE(FTDI_VID, EVER_ECO_PRO_CDS) },
 	{ }						/* Terminating entry */
 };
 
@@ -1137,7 +1140,7 @@
 		goto check_and_exit;
 	}
 
-	if ((new_serial.baud_base != priv->baud_base) ||
+	if ((new_serial.baud_base != priv->baud_base) &&
 	    (new_serial.baud_base < 9600))
 		return -EINVAL;
 
@@ -1174,6 +1177,135 @@
 
 } /* set_serial_info */
 
+
+/*
+ * ***************************************************************************
+ * Sysfs Attribute
+ * ***************************************************************************
+ */
+
+ssize_t show_latency_timer(struct device *dev, char *buf)
+{
+	struct usb_serial_port *port = to_usb_serial_port(dev);
+	struct ftdi_private *priv = usb_get_serial_port_data(port);
+	struct usb_device *udev;
+	unsigned short latency = 0;
+	int rv = 0;
+	
+	udev = to_usb_device(dev);
+	
+	dbg("%s",__FUNCTION__);
+	
+	rv = usb_control_msg(udev,
+			     usb_rcvctrlpipe(udev, 0),
+			     FTDI_SIO_GET_LATENCY_TIMER_REQUEST,
+			     FTDI_SIO_GET_LATENCY_TIMER_REQUEST_TYPE,
+			     0, priv->interface, 
+			     (char*) &latency, 1, WDR_TIMEOUT);
+	
+	if (rv < 0) {
+		dev_err(dev, "Unable to read latency timer: %i", rv);
+		return -EIO;
+	}
+	return sprintf(buf, "%i\n", latency);
+}
+
+/* Write a new value of the latency timer, in units of milliseconds. */
+ssize_t store_latency_timer(struct device *dev, const char *valbuf, size_t count)
+{
+	struct usb_serial_port *port = to_usb_serial_port(dev);
+	struct ftdi_private *priv = usb_get_serial_port_data(port);
+	struct usb_device *udev;
+	char buf[1];
+	int v = simple_strtoul(valbuf, NULL, 10);
+	int rv = 0;
+	
+	udev = to_usb_device(dev);
+	
+	dbg("%s: setting latency timer = %i", __FUNCTION__, v);
+	
+	rv = usb_control_msg(udev,
+			     usb_sndctrlpipe(udev, 0),
+			     FTDI_SIO_SET_LATENCY_TIMER_REQUEST,
+			     FTDI_SIO_SET_LATENCY_TIMER_REQUEST_TYPE,
+			     v, priv->interface, 
+			     buf, 0, WDR_TIMEOUT);
+	
+	if (rv < 0) {
+		dev_err(dev, "Unable to write latency timer: %i", rv);
+		return -EIO;
+	}
+	
+	return count;
+}
+
+/* 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. */
+ssize_t store_event_char(struct device *dev, const char *valbuf, size_t count)
+{
+	struct usb_serial_port *port = to_usb_serial_port(dev);
+	struct ftdi_private *priv = usb_get_serial_port_data(port);
+	struct usb_device *udev;
+	char buf[1];
+	int v = simple_strtoul(valbuf, NULL, 10);
+	int rv = 0;
+	
+	udev = to_usb_device(dev);
+	
+	dbg("%s: setting event char = %i", __FUNCTION__, v);
+	
+	rv = usb_control_msg(udev,
+			     usb_sndctrlpipe(udev, 0),
+			     FTDI_SIO_SET_EVENT_CHAR_REQUEST,
+			     FTDI_SIO_SET_EVENT_CHAR_REQUEST_TYPE,
+			     v, priv->interface, 
+			     buf, 0, WDR_TIMEOUT);
+	
+	if (rv < 0) {
+		dbg("Unable to write event character: %i", rv);
+		return -EIO;
+	}
+	
+	return count;
+}
+
+static DEVICE_ATTR(latency_timer, S_IWUGO | S_IRUGO, show_latency_timer, store_latency_timer);
+static DEVICE_ATTR(event_char, S_IWUGO, NULL, store_event_char);
+
+void create_sysfs_attrs(struct usb_serial *serial)
+{	
+	struct ftdi_private *priv;
+	struct usb_device *udev;
+
+	dbg("%s",__FUNCTION__);
+	
+	priv = usb_get_serial_port_data(serial->port[0]);
+	udev = serial->dev;
+	
+	if (priv->chip_type == FT232BM) {
+		dbg("sysfs attributes for FT232BM");
+		device_create_file(&udev->dev, &dev_attr_event_char);
+		device_create_file(&udev->dev, &dev_attr_latency_timer);
+	}
+}
+
+void remove_sysfs_attrs(struct usb_serial *serial)
+{
+	struct ftdi_private *priv;
+	struct usb_device *udev;
+
+	dbg("%s",__FUNCTION__);	
+
+	priv = usb_get_serial_port_data(serial->port[0]);
+	udev = serial->dev;
+	
+	if (priv->chip_type == FT232BM) {
+		device_remove_file(&udev->dev, &dev_attr_event_char);
+		device_remove_file(&udev->dev, &dev_attr_latency_timer);
+	}
+	
+}
+
 /*
  * ***************************************************************************
  * FTDI driver specific functions
@@ -1291,6 +1423,8 @@
 	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 */
 
@@ -1384,6 +1518,8 @@
 
 	dbg("%s", __FUNCTION__);
 
+	remove_sysfs_attrs(serial);
+	
 	/* all open ports are closed at this point 
          *    (by usbserial.c:__serial_close, which calls ftdi_close)  
 	 */
@@ -1518,7 +1654,7 @@
 	dbg("%s port %d, %d bytes", __FUNCTION__, port->number, count);
 
 	if (count == 0) {
-		err("write request of 0 bytes");
+		dbg("write request of 0 bytes");
 		return 0;
 	}
 	
diff -Nru a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h
--- a/drivers/usb/serial/ftdi_sio.h	2005-03-01 23:39:09 -08:00
+++ b/drivers/usb/serial/ftdi_sio.h	2005-03-01 23:39:09 -08:00
@@ -240,6 +240,12 @@
 #define FTDI_RM_VID		0x0403	/* Vendor  Id */
 #define FTDI_RMCANVIEW_PID	0xfd60	/* Product Id */
 
+/*
+ * EVER Eco Pro UPS (http://www.ever.com.pl/)
+ */
+
+#define	EVER_ECO_PRO_CDS	0xe520	/* RS-232 converter */
+
 /* Commands */
 #define FTDI_SIO_RESET 		0 /* Reset the port */
 #define FTDI_SIO_MODEM_CTRL 	1 /* Set the modem control register */
@@ -249,6 +255,8 @@
 #define FTDI_SIO_GET_MODEM_STATUS	5 /* Retrieve current value of modern status register */
 #define FTDI_SIO_SET_EVENT_CHAR	6 /* Set the event character */
 #define FTDI_SIO_SET_ERROR_CHAR	7 /* Set the error character */
+#define FTDI_SIO_SET_LATENCY_TIMER	9 /* Set the latency timer */
+#define FTDI_SIO_GET_LATENCY_TIMER	10 /* Get the latency timer */
 
 /* Port interface code for FT2232C */
 #define INTERFACE_A		1
@@ -502,6 +510,55 @@
  * and the lValue field contains the XON character.
  */  
  
+/*
+ * FTDI_SIO_GET_LATENCY_TIMER
+ *
+ * Set the timeout interval. The FTDI collects data from the slave
+ * device, transmitting it to the host when either A) 62 bytes are
+ * received, or B) the timeout interval has elapsed and the buffer
+ * contains at least 1 byte.  Setting this value to a small number
+ * can dramatically improve performance for applications which send
+ * small packets, since the default value is 16ms.
+ */
+#define  FTDI_SIO_GET_LATENCY_TIMER_REQUEST FTDI_SIO_GET_LATENCY_TIMER
+#define  FTDI_SIO_GET_LATENCY_TIMER_REQUEST_TYPE 0xC0
+
+/* 
+ *  BmRequestType:   1100 0000b
+ *  bRequest:        FTDI_SIO_GET_LATENCY_TIMER
+ *  wValue:          0
+ *  wIndex:          Port
+ *  wLength:         0
+ *  Data:            latency (on return)
+ */
+
+/* 
+ * FTDI_SIO_SET_LATENCY_TIMER
+ *
+ * Set the timeout interval. The FTDI collects data from the slave
+ * device, transmitting it to the host when either A) 62 bytes are
+ * received, or B) the timeout interval has elapsed and the buffer
+ * contains at least 1 byte.  Setting this value to a small number
+ * can dramatically improve performance for applications which send
+ * small packets, since the default value is 16ms.
+ */
+#define  FTDI_SIO_SET_LATENCY_TIMER_REQUEST FTDI_SIO_SET_LATENCY_TIMER
+#define  FTDI_SIO_SET_LATENCY_TIMER_REQUEST_TYPE 0x40
+
+/* 
+ *  BmRequestType:   0100 0000b
+ *  bRequest:        FTDI_SIO_SET_LATENCY_TIMER
+ *  wValue:          Latency (milliseconds)
+ *  wIndex:          Port
+ *  wLength:         0
+ *  Data:            None
+ *
+ * wValue:
+ *   B0..7   Latency timer
+ *   B8..15  0
+ *
+ */
+
 /*
  * FTDI_SIO_SET_EVENT_CHAR 
  *
diff -Nru a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/usb/serial/garmin_gps.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,1541 @@
+/*
+ * Garmin GPS driver
+ *
+ * Copyright (C) 2004 Hermann Kneissel herkne@users.sourceforge.net
+ *
+ * The latest version of the driver can be found at
+ * http://sourceforge.net/projects/garmin-gps/
+ *
+ * This driver has been derived from v2.1 of the visor 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., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/timer.h>
+#include <linux/tty.h>
+#include <linux/tty_driver.h>
+#include <linux/tty_flip.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <asm/uaccess.h>
+#include <linux/usb.h>
+
+/* the mode to be set when the port ist opened */
+static int initial_mode = 1;
+
+/* debug flag */
+static int debug = 0;
+
+#include "usb-serial.h"
+
+#define GARMIN_VENDOR_ID             0x091E
+
+/*
+ * Version Information
+ */
+
+#define VERSION_MAJOR	0
+#define VERSION_MINOR	23
+
+#define _STR(s) #s
+#define _DRIVER_VERSION(a,b) "v" _STR(a) "." _STR(b)
+#define DRIVER_VERSION _DRIVER_VERSION(VERSION_MAJOR, VERSION_MINOR)
+#define DRIVER_AUTHOR "hermann kneissel"
+#define DRIVER_DESC "garmin gps driver"
+
+/* error codes returned by the driver */
+#define EINVPKT	1000	/* invalid packet structure */
+
+
+// size of the header of a packet using the usb protocol
+#define GARMIN_PKTHDR_LENGTH	12
+
+// max. possible size of a packet using the serial protocol 
+#define MAX_SERIAL_PKT_SIZ (3+255+3)
+
+// max. possible size of a packet with worst case stuffing
+#define MAX_SERIAL_PKT_SIZ_STUFFED MAX_SERIAL_PKT_SIZ+256
+
+// size of a buffer able to hold a complete (no stuffing) packet
+// (the document protocol does not contain packets with a larger
+//  size, but in theory a packet may be 64k+12 bytes - if in
+//  later protocol versions larger packet sizes occur, this value
+//  should be increased accordingly, so the input buffer is always 
+//  large enough the store a complete packet inclusive header)
+#define GPS_IN_BUFSIZ  (GARMIN_PKTHDR_LENGTH+MAX_SERIAL_PKT_SIZ) 
+
+// size of a buffer able to hold a complete (incl. stuffing) packet
+#define GPS_OUT_BUFSIZ (GARMIN_PKTHDR_LENGTH+MAX_SERIAL_PKT_SIZ_STUFFED) 
+
+// where to place the packet id of a serial packet, so we can
+// prepend the usb-packet header without the need to move the
+// packets data
+#define GSP_INITIAL_OFFSET (GARMIN_PKTHDR_LENGTH-2)
+
+// max. size of incoming private packets (header+1 param)
+#define PRIVPKTSIZ (GARMIN_PKTHDR_LENGTH+4)
+
+#define GARMIN_LAYERID_TRANSPORT  0
+#define GARMIN_LAYERID_APPL      20
+// our own layer-id to use for some control mechanisms
+#define GARMIN_LAYERID_PRIVATE	0x01106E4B
+
+#define GARMIN_PKTID_PVT_DATA	51
+#define GARMIN_PKTID_L001_COMMAND_DATA 10
+
+#define CMND_ABORT_TRANSFER 0
+
+// packet ids used in private layer
+#define PRIV_PKTID_SET_DEBUG	1
+#define PRIV_PKTID_SET_MODE	2
+#define PRIV_PKTID_INFO_REQ	3
+#define PRIV_PKTID_INFO_RESP	4
+#define PRIV_PKTID_RESET_REQ	5
+#define PRIV_PKTID_SET_DEF_MODE	6
+
+
+#define ETX	0x03
+#define DLE	0x10
+#define ACK	0x06
+#define NAK	0x15
+
+/* structure used to queue incoming packets */
+struct garmin_packet {
+	struct list_head  list;
+	int               seq;
+	int               size; // the real size of the data array, always > 0
+	__u8              data[1];
+};
+
+/* structure used to keep the current state of the driver */
+struct garmin_data {
+	__u8   state;
+	__u16  flags;
+	__u8   mode;
+	__u8   ignorePkts;
+	__u8   count;
+	__u8   pkt_id;
+	__u32  serial_num;
+	struct timer_list timer;
+	struct usb_serial_port *port;
+	int    seq_counter;
+	int    insize;
+	int    outsize;
+	__u8   inbuffer [GPS_IN_BUFSIZ];  /* tty -> usb */
+	__u8   outbuffer[GPS_OUT_BUFSIZ]; /* usb -> tty */
+	__u8   privpkt[4*6];
+	spinlock_t lock;
+	struct list_head pktlist;
+};
+
+
+#define STATE_NEW            0
+#define STATE_INITIAL_DELAY  1
+#define STATE_TIMEOUT        2
+#define STATE_SESSION_REQ1   3
+#define STATE_SESSION_REQ2   4
+#define STATE_ACTIVE         5
+
+#define STATE_RESET	     8
+#define STATE_DISCONNECTED   9
+#define STATE_WAIT_TTY_ACK  10
+#define STATE_GSP_WAIT_DATA 11
+
+#define MODE_NATIVE          0
+#define MODE_GARMIN_SERIAL   1
+
+// Flags used in garmin_data.flags:
+#define FLAGS_SESSION_REPLY_MASK  0x00C0
+#define FLAGS_SESSION_REPLY1_SEEN 0x0080
+#define FLAGS_SESSION_REPLY2_SEEN 0x0040
+#define FLAGS_BULK_IN_ACTIVE      0x0020
+#define FLAGS_THROTTLED           0x0010
+#define CLEAR_HALT_REQUIRED       0x0001
+
+#define FLAGS_QUEUING             0x0100
+#define FLAGS_APP_RESP_SEEN       0x0200
+#define FLAGS_APP_REQ_SEEN        0x0400
+#define FLAGS_DROP_DATA           0x0800
+
+#define FLAGS_GSP_SKIP            0x1000
+#define FLAGS_GSP_DLESEEN         0x2000
+
+
+
+
+
+
+/* function prototypes */
+static void gsp_next_packet(struct garmin_data * garmin_data_p);
+static int  garmin_write_bulk(struct usb_serial_port *port,
+			     const unsigned char *buf, int count);
+
+/* some special packets to be send or received */
+static unsigned char const GARMIN_START_SESSION_REQ[]
+	= { 0, 0, 0, 0,  5, 0, 0, 0, 0, 0, 0, 0 };
+static unsigned char const GARMIN_START_SESSION_REQ2[]
+	= { 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0 };
+static unsigned char const GARMIN_START_SESSION_REPLY[]
+	= { 0, 0, 0, 0,  6, 0, 0, 0, 4, 0, 0, 0 };
+static unsigned char const GARMIN_SESSION_ACTIVE_REPLY[]
+	= { 0, 0, 0, 0, 17, 0, 0, 0, 4, 0, 0, 0, 0, 16, 0, 0 };
+static unsigned char const GARMIN_BULK_IN_AVAIL_REPLY[]
+	= { 0, 0, 0, 0,  2, 0, 0, 0, 0, 0, 0, 0 };
+static unsigned char const GARMIN_APP_LAYER_REPLY[]
+	= { 0x14, 0, 0, 0 };
+static unsigned char const GARMIN_START_PVT_REQ[]
+	= { 20, 0, 0, 0,  10, 0, 0, 0, 2, 0, 0, 0, 49, 0 };
+static unsigned char const GARMIN_STOP_PVT_REQ[]
+	= { 20, 0, 0, 0,  10, 0, 0, 0, 2, 0, 0, 0, 50, 0 };
+static unsigned char const GARMIN_STOP_TRANSFER_REQ[]
+	= { 20, 0, 0, 0,  10, 0, 0, 0, 2, 0, 0, 0, 0, 0 };
+static unsigned char const GARMIN_STOP_TRANSFER_REQ_V2[]
+	= { 20, 0, 0, 0,  10, 0, 0, 0, 1, 0, 0, 0, 0 };
+static unsigned char const PRIVATE_REQ[]
+	=    { 0x4B, 0x6E, 0x10, 0x01,  0xFF, 0, 0, 0, 0xFF, 0, 0, 0 };
+
+
+
+static struct usb_device_id id_table [] = {
+	/* the same device id seems to be used by all usb enabled gps devices */
+	{ USB_DEVICE(GARMIN_VENDOR_ID, 3 ) },
+	{ }					/* Terminating entry */
+};
+
+MODULE_DEVICE_TABLE (usb, id_table);
+
+static struct usb_driver garmin_driver = {
+	.owner =	THIS_MODULE,
+	.name =		"garmin_gps",
+	.probe =	usb_serial_probe,
+	.disconnect =	usb_serial_disconnect,
+	.id_table =	id_table,
+};
+
+
+static inline int noResponseFromAppLayer(struct garmin_data * garmin_data_p)
+{
+	return ((garmin_data_p->flags
+				& (FLAGS_APP_REQ_SEEN|FLAGS_APP_RESP_SEEN))
+	        == FLAGS_APP_REQ_SEEN);
+}
+
+
+static inline int getLayerId(const __u8 *usbPacket)
+{
+	return __le32_to_cpup((__le32 *)(usbPacket));
+}
+
+static inline int getPacketId(const __u8 *usbPacket)
+{
+	return __le32_to_cpup((__le32 *)(usbPacket+4));
+}
+
+static inline int getDataLength(const __u8 *usbPacket)
+{
+	return __le32_to_cpup((__le32 *)(usbPacket+8));
+}
+
+
+/*
+ * check if the usb-packet in buf contains an abort-transfer command.
+ * (if yes, all queued data will be dropped)
+ */
+static inline int isAbortTrfCmnd(const unsigned char *buf)
+{
+	if (0 == memcmp(buf, GARMIN_STOP_TRANSFER_REQ, 
+	                sizeof(GARMIN_STOP_TRANSFER_REQ)) ||
+	    0 == memcmp(buf, GARMIN_STOP_TRANSFER_REQ_V2, 
+	                sizeof(GARMIN_STOP_TRANSFER_REQ_V2)))
+		return 1;
+	else
+		return 0;
+}
+
+
+
+static void send_to_tty(struct usb_serial_port *port,
+                        char *data, unsigned int actual_length)
+{
+	struct tty_struct *tty = port->tty;
+	int i;
+
+	if (tty && actual_length) {
+
+		usb_serial_debug_data(debug, &port->dev, 
+					__FUNCTION__, actual_length, data);
+
+		for (i = 0; i < actual_length ; ++i) {
+			/* if we insert more than TTY_FLIPBUF_SIZE characters,
+			   we drop them. */
+			if(tty->flip.count >= TTY_FLIPBUF_SIZE) {
+				tty_flip_buffer_push(tty);
+			}
+			/* this doesn't actually push the data through unless
+			   tty->low_latency is set */
+			tty_insert_flip_char(tty, data[i], 0);
+		}
+		tty_flip_buffer_push(tty);
+	}
+}
+
+
+/******************************************************************************
+ * packet queue handling
+ ******************************************************************************/
+
+/*
+ * queue a received (usb-)packet for later processing
+ */
+static int pkt_add(struct garmin_data * garmin_data_p,
+                   unsigned char *data, unsigned int data_length)
+{
+	int result = 0;
+	unsigned long flags;
+	struct garmin_packet *pkt;
+
+	/* process only packets containg data ... */
+	if (data_length) {
+		garmin_data_p->flags |= FLAGS_QUEUING;
+		pkt = kmalloc(sizeof(struct garmin_packet)+data_length,
+		              GFP_ATOMIC);
+		if (pkt == NULL) {
+			dev_err(&garmin_data_p->port->dev, "out of memory\n");
+			return 0;
+		}
+		pkt->size = data_length;
+		memcpy(pkt->data, data, data_length);
+
+		spin_lock_irqsave(&garmin_data_p->lock, flags);
+		result = list_empty(&garmin_data_p->pktlist);
+		pkt->seq = garmin_data_p->seq_counter++;
+		list_add_tail(&pkt->list, &garmin_data_p->pktlist);
+		spin_unlock_irqrestore(&garmin_data_p->lock, flags);
+
+		/* in serial mode, if someone is waiting for data from
+		   the device, iconvert and send the next packet to tty. */
+		if (result && (garmin_data_p->state == STATE_GSP_WAIT_DATA)) {
+			gsp_next_packet(garmin_data_p);
+		}
+	}
+	return result;
+}
+
+
+/* get the next pending packet */
+static struct garmin_packet *pkt_pop(struct garmin_data * garmin_data_p)
+{
+	unsigned long flags;
+	struct garmin_packet *result = NULL;
+
+	spin_lock_irqsave(&garmin_data_p->lock, flags);
+	if (!list_empty(&garmin_data_p->pktlist)) {
+		result = (struct garmin_packet *)garmin_data_p->pktlist.next;
+		list_del(&result->list);
+	}
+	spin_unlock_irqrestore(&garmin_data_p->lock, flags);
+	return result;
+}
+
+
+/* free up all queued data */
+static void pkt_clear(struct garmin_data * garmin_data_p)
+{
+	unsigned long flags;
+	struct garmin_packet *result = NULL;
+
+	dbg("%s", __FUNCTION__);
+
+	spin_lock_irqsave(&garmin_data_p->lock, flags);
+	while (!list_empty(&garmin_data_p->pktlist)) {
+		result = (struct garmin_packet *)garmin_data_p->pktlist.next;
+		list_del(&result->list);
+		kfree(result);
+	}
+	spin_unlock_irqrestore(&garmin_data_p->lock, flags);
+}
+
+
+/******************************************************************************
+ * garmin serial protocol handling handling
+ ******************************************************************************/
+
+/* send an ack packet back to the tty */
+static int gsp_send_ack(struct garmin_data * garmin_data_p, __u8 pkt_id)
+{
+	__u8 pkt[10];
+        __u8 cksum = 0;
+        __u8 *ptr = pkt;
+        unsigned  l = 0;
+
+	dbg("%s - pkt-id: 0x%X.", __FUNCTION__, 0xFF & pkt_id);
+
+	*ptr++ = DLE;
+	*ptr++ = ACK;
+	cksum += ACK;
+
+	*ptr++ = 2;
+	cksum += 2;
+
+	*ptr++ = pkt_id;
+	cksum += pkt_id;
+
+	if (pkt_id == DLE) {
+		*ptr++ = DLE;
+	}
+
+	*ptr++ = 0;
+	*ptr++ = 0xFF & (-cksum);
+	*ptr++ = DLE;
+	*ptr++ = ETX;
+
+	l = ptr-pkt;
+
+	send_to_tty(garmin_data_p->port, pkt, l);
+	return 0;
+}
+
+
+
+/*
+ * called for a complete packet received from tty layer
+ *
+ * the complete packet (pkzid ... cksum) is in garmin_data_p->inbuf starting
+ * at GSP_INITIAL_OFFSET.
+ *
+ * count - number of bytes in the input buffer including space reserved for
+ *         the usb header: GSP_INITIAL_OFFSET + number of bytes in packet 
+ *         (including pkt-id, data-length a. cksum)
+ */
+static int gsp_rec_packet(struct garmin_data * garmin_data_p, int count)
+{
+	const __u8* recpkt = garmin_data_p->inbuffer+GSP_INITIAL_OFFSET;
+        __le32 *usbdata = (__le32 *) garmin_data_p->inbuffer;
+
+	int cksum = 0;
+	int n = 0;
+	int pktid = recpkt[0];
+	int size = recpkt[1];
+
+	usb_serial_debug_data(debug, &garmin_data_p->port->dev,
+			       __FUNCTION__, count-GSP_INITIAL_OFFSET, recpkt);
+
+	if (size != (count-GSP_INITIAL_OFFSET-3)) {
+		dbg("%s - invalid size, expected %d bytes, got %d",
+			__FUNCTION__, size, (count-GSP_INITIAL_OFFSET-3));
+		return -EINVPKT;
+	}
+
+	cksum += *recpkt++;
+	cksum += *recpkt++;
+
+	// sanity check, remove after test ...
+	if ((__u8*)&(usbdata[3]) != recpkt) {
+		dbg("%s - ptr mismatch %p - %p",
+			__FUNCTION__, &(usbdata[4]), recpkt);
+		return -EINVPKT;
+	}
+
+	while (n < size) {
+		cksum += *recpkt++;
+		n++;
+	}
+
+       if ((0xff & (cksum + *recpkt)) != 0) {
+                dbg("%s - invalid checksum, expected %02x, got %02x",
+                        __FUNCTION__, 0xff & -cksum, 0xff & *recpkt);
+                return -EINVPKT;
+        }
+
+	usbdata[0] = __cpu_to_le32(GARMIN_LAYERID_APPL);
+	usbdata[1] = __cpu_to_le32(pktid);
+	usbdata[2] = __cpu_to_le32(size);
+
+	garmin_write_bulk (garmin_data_p->port, garmin_data_p->inbuffer,
+			   GARMIN_PKTHDR_LENGTH+size);
+
+	/* if this was an abort-transfer command, flush all
+	   queued data. */
+	if (isAbortTrfCmnd(garmin_data_p->inbuffer)) {
+		garmin_data_p->flags |= FLAGS_DROP_DATA;
+		pkt_clear(garmin_data_p);
+	}
+
+	return count;
+}
+
+
+
+/*
+ * Called for data received from tty
+ *
+ * buf contains the data read, it may span more than one packet or even
+ * incomplete packets
+ *
+ * input record should be a serial-record, but it may not be complete.
+ * Copy it into our local buffer, until an etx is seen (or an error
+ * occurs).
+ * Once the record is complete, convert into a usb packet and send it
+ * to the bulk pipe, send an ack back to the tty.
+ *
+ * If the input is an ack, just send the last queued packet to the
+ * tty layer.
+ *
+ * if the input is an abort command, drop all queued data.
+ */
+
+static int gsp_receive(struct garmin_data * garmin_data_p,
+                       const unsigned char *buf, int count)
+{
+	int offs = 0;
+	int ack_or_nak_seen = 0;
+	int i = 0;
+	__u8 *dest = garmin_data_p->inbuffer;
+	int size = garmin_data_p->insize;
+	// dleSeen: set if last byte read was a DLE
+	int dleSeen = garmin_data_p->flags & FLAGS_GSP_DLESEEN;
+	// skip: if set, skip incoming data until possible start of
+	//       new packet
+	int skip = garmin_data_p->flags & FLAGS_GSP_SKIP;
+	__u8 data;
+
+	dbg("%s - dle=%d skip=%d size=%d count=%d",
+		__FUNCTION__, dleSeen, skip, size, count);
+
+	if (size == 0) {
+		size = GSP_INITIAL_OFFSET;
+	}
+
+	while (offs < count) {
+
+		data = *(buf+offs);
+		offs ++;
+
+		if (data == DLE) {
+			if (skip) { /* start of a new pkt */
+				skip = 0;
+				size = GSP_INITIAL_OFFSET;
+				dleSeen = 1;
+			} else if (dleSeen) {
+				dest[size++] = data;
+				dleSeen = 0;
+			} else {
+				dleSeen = 1;
+			}
+		} else if (data == ETX) {
+			if (dleSeen) {
+				/* packet complete */
+
+				data = dest[GSP_INITIAL_OFFSET];
+
+				if (data == ACK) {
+					ack_or_nak_seen = ACK;
+					dbg("ACK packet complete.");
+				} else if (data == NAK) {
+					ack_or_nak_seen = NAK;
+					dbg("NAK packet complete.");
+				} else {
+					dbg("packet complete "
+						        "- id=0x%X.",
+						        0xFF & data);
+					gsp_rec_packet(garmin_data_p, size);
+				}
+
+				skip = 1;
+				size = GSP_INITIAL_OFFSET;
+				dleSeen = 0;
+			} else {
+				dest[size++] = data;
+			}
+		} else if (!skip) {
+
+			if (dleSeen) {
+				dbg("non-masked DLE at %d - restarting", i);
+				size = GSP_INITIAL_OFFSET;
+				dleSeen = 0;
+			}
+
+			dest[size++] = data;
+		}
+
+		if (size >= GPS_IN_BUFSIZ) {
+			dbg("%s - packet too large.", __FUNCTION__);
+			skip = 1;
+			size = GSP_INITIAL_OFFSET;
+			dleSeen = 0;
+		}
+	}
+
+	garmin_data_p->insize = size;
+
+	// copy flags back to structure
+	if (skip)
+		garmin_data_p->flags |= FLAGS_GSP_SKIP;
+	else
+		garmin_data_p->flags &= ~FLAGS_GSP_SKIP;
+
+	if (dleSeen)
+		garmin_data_p->flags |= FLAGS_GSP_DLESEEN;
+	else
+		garmin_data_p->flags &= ~FLAGS_GSP_DLESEEN;
+
+	if (ack_or_nak_seen) {
+		garmin_data_p->state = STATE_GSP_WAIT_DATA;
+		gsp_next_packet(garmin_data_p);
+	}
+
+	return count;
+}
+
+
+
+
+/*
+ * Sends a usb packet to the tty
+ *
+ * Assumes, that all packages and at an usb-packet boundary.
+ *
+ * return <0 on error, 0 if packet is incomplete or > 0 if packet was sent
+ */
+int gsp_send(struct garmin_data * garmin_data_p, const unsigned char *buf,
+              int count)
+{
+	const unsigned char *src;
+	unsigned char *dst;
+	int pktid = 0;
+	int datalen = 0;
+	int cksum = 0;
+	int i=0;
+	int k;
+
+	dbg("%s - state %d - %d bytes.", __FUNCTION__,
+	         garmin_data_p->state, count);
+
+	k = garmin_data_p->outsize;
+	if ((k+count) > GPS_OUT_BUFSIZ) {
+		dbg("packet too large");
+		garmin_data_p->outsize = 0;
+		return -4;
+	}
+
+	memcpy(garmin_data_p->outbuffer+k, buf, count);
+	k += count;
+	garmin_data_p->outsize = k;
+
+	if (k >= GARMIN_PKTHDR_LENGTH) {
+		pktid  = getPacketId(garmin_data_p->outbuffer);
+		datalen= getDataLength(garmin_data_p->outbuffer);
+		i = GARMIN_PKTHDR_LENGTH + datalen;
+		if (k < i)
+			return 0;
+	} else {
+		return 0;
+	}
+
+	dbg("%s - %d bytes in buffer, %d bytes in pkt.", __FUNCTION__,
+	         k, i);
+
+	/* garmin_data_p->outbuffer now contains a complete packet */
+
+	usb_serial_debug_data(debug, &garmin_data_p->port->dev,
+		                   __FUNCTION__, k, garmin_data_p->outbuffer);
+
+	garmin_data_p->outsize = 0;
+
+	if (GARMIN_LAYERID_APPL != getLayerId(garmin_data_p->outbuffer)) {
+		dbg("not an application packet (%d)", 
+		        getLayerId(garmin_data_p->outbuffer));
+		return -1;
+	}
+
+	if (pktid > 255) {
+		dbg("packet-id %d too large", pktid);
+		return -2;
+	}
+
+	if (datalen > 255) {
+		dbg("packet-size %d too large", datalen);
+		return -3;
+	}
+
+	/* the serial protocol should be able to handle this packet */
+
+	k = 0;
+	src = garmin_data_p->outbuffer+GARMIN_PKTHDR_LENGTH;
+	for (i=0; i<datalen; i++) {
+		if (*src++ == DLE)
+			k++;
+	}
+
+	src = garmin_data_p->outbuffer+GARMIN_PKTHDR_LENGTH;
+	if (k > (GARMIN_PKTHDR_LENGTH-2)) {
+		/* can't add stuffing DLEs in place, move data to end 
+                   of buffer ... */
+		dst = garmin_data_p->outbuffer+GPS_OUT_BUFSIZ-datalen;
+		memcpy(dst, src, datalen);
+		src = dst;
+	}
+
+	dst = garmin_data_p->outbuffer;
+
+	*dst++ = DLE;
+	*dst++ = pktid;
+	cksum += pktid;
+	*dst++ = datalen;
+	cksum += datalen;
+	if (datalen == DLE)
+		*dst++ = DLE;
+
+	for (i=0; i<datalen; i++) {
+		__u8 c = *src++;
+		*dst++ = c;
+		cksum += c;
+		if (c == DLE)
+			*dst++ = DLE;
+	}
+		
+	cksum = 0xFF & -cksum;
+	*dst++ = cksum;
+	if (cksum == DLE)
+		*dst++ = DLE;
+	*dst++ = DLE;
+	*dst++ = ETX;
+
+	i = dst-garmin_data_p->outbuffer;
+
+	send_to_tty(garmin_data_p->port, garmin_data_p->outbuffer, i);
+
+	garmin_data_p->pkt_id = pktid;
+	garmin_data_p->state  = STATE_WAIT_TTY_ACK;
+
+	return i;
+}
+
+
+
+
+
+/*
+ * Process the next pending data packet - if there is one
+ */
+static void gsp_next_packet(struct garmin_data * garmin_data_p)
+{
+	struct garmin_packet *pkt = NULL;
+
+	while ((pkt = pkt_pop(garmin_data_p)) != NULL) {
+		dbg("%s - next pkt: %d", __FUNCTION__, pkt->seq);
+		if (gsp_send(garmin_data_p, pkt->data, pkt->size) > 0) {
+			kfree(pkt);
+			return;
+		}
+		kfree(pkt);
+	}
+}
+
+
+
+
+/******************************************************************************
+ * garmin native mode
+ ******************************************************************************/
+
+
+/*
+ * Called for data received from tty
+ *
+ * The input data is expected to be in garmin usb-packet format.
+ *
+ * buf contains the data read, it may span more than one packet
+ * or even incomplete packets
+ */
+static int nat_receive(struct garmin_data * garmin_data_p,
+                       const unsigned char *buf, int count)
+{
+	__u8 * dest;
+	int offs = 0;
+	int result = count;
+	int len;
+
+	while (offs < count) {
+		// if buffer contains header, copy rest of data
+		if (garmin_data_p->insize >= GARMIN_PKTHDR_LENGTH)
+			len = GARMIN_PKTHDR_LENGTH
+			      +getDataLength(garmin_data_p->inbuffer);
+		else
+			len = GARMIN_PKTHDR_LENGTH;
+
+		if (len >= GPS_IN_BUFSIZ) {
+			/* seem to be an invalid packet, ignore rest of input */
+			dbg("%s - packet size too large: %d",
+			        __FUNCTION__, len);
+			garmin_data_p->insize = 0;
+			count = 0;
+			result = -EINVPKT;
+		} else {
+			len -= garmin_data_p->insize;
+			if (len > (count-offs))
+				len = (count-offs);
+			if (len > 0) {
+				dest = garmin_data_p->inbuffer
+				       	+garmin_data_p->insize;
+				memcpy(dest, buf+offs, len);
+				garmin_data_p->insize += len;
+				offs += len;
+			}
+		}
+
+		/* do we have a complete packet ? */
+		if (garmin_data_p->insize >= GARMIN_PKTHDR_LENGTH) {
+			len = GARMIN_PKTHDR_LENGTH+
+			   getDataLength(garmin_data_p->inbuffer);
+			if (garmin_data_p->insize >= len) {
+				garmin_write_bulk (garmin_data_p->port,
+				                   garmin_data_p->inbuffer,
+				                   len);
+				garmin_data_p->insize = 0;
+
+				/* if this was an abort-transfer command,
+				   flush all queued data. */
+				if (isAbortTrfCmnd(garmin_data_p->inbuffer)) {
+					garmin_data_p->flags |= FLAGS_DROP_DATA;
+					pkt_clear(garmin_data_p);
+				}
+			}
+		}
+	}
+	return result;
+}
+
+
+/******************************************************************************
+ * private packets
+ ******************************************************************************/
+
+static void priv_status_resp(struct usb_serial_port *port)
+{
+	struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
+	__le32 *pkt = (__le32 *)garmin_data_p->privpkt;
+
+	pkt[0] = __cpu_to_le32(GARMIN_LAYERID_PRIVATE);
+	pkt[1] = __cpu_to_le32(PRIV_PKTID_INFO_RESP);
+	pkt[2] = __cpu_to_le32(12);
+	pkt[3] = __cpu_to_le32(VERSION_MAJOR << 16 | VERSION_MINOR);
+	pkt[4] = __cpu_to_le32(garmin_data_p->mode);
+	pkt[5] = __cpu_to_le32(garmin_data_p->serial_num);
+
+	send_to_tty(port, (__u8*)pkt, 6*4);
+}
+
+
+/******************************************************************************
+ * Garmin specific driver functions
+ ******************************************************************************/
+
+static int process_resetdev_request(struct usb_serial_port *port)
+{
+	int status;
+	struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
+
+	garmin_data_p->flags &= ~(CLEAR_HALT_REQUIRED);
+	garmin_data_p->state = STATE_RESET;
+	garmin_data_p->serial_num = 0;
+
+	usb_kill_urb (port->interrupt_in_urb);
+	dbg("%s - usb_reset_device", __FUNCTION__ );
+	status = usb_reset_device(port->serial->dev);
+	if (status)
+		dbg("%s - usb_reset_device failed: %d",
+			__FUNCTION__, status);
+	return status;
+}
+
+
+
+/*
+ * clear all cached data
+ */
+static int garmin_clear(struct garmin_data * garmin_data_p)
+{
+	int status = 0;
+
+	struct usb_serial_port *port = garmin_data_p->port;
+
+	if (port != NULL && garmin_data_p->flags & FLAGS_APP_RESP_SEEN) {
+		/* send a terminate command */
+		status = garmin_write_bulk(port, GARMIN_STOP_TRANSFER_REQ,
+		                           sizeof(GARMIN_STOP_TRANSFER_REQ));
+	}
+
+	/* flush all queued data */
+	pkt_clear(garmin_data_p);
+
+	garmin_data_p->insize = 0;
+	garmin_data_p->outsize = 0;
+
+	return status;
+}
+
+
+
+
+
+
+static int garmin_init_session(struct usb_serial_port *port)
+{
+	struct usb_serial *serial = port->serial;
+	struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
+	int status = 0;
+
+	if (status == 0) {
+		usb_kill_urb (port->interrupt_in_urb);
+
+		dbg("%s - adding interrupt input", __FUNCTION__);
+		port->interrupt_in_urb->dev = serial->dev;
+		status = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
+		if (status)
+			dev_err(&serial->dev->dev,
+			        "%s - failed submitting interrupt urb,"
+				" error %d\n",
+			        __FUNCTION__, status);
+	}
+
+	if (status == 0) {
+		dbg("%s - starting session ...", __FUNCTION__);
+		garmin_data_p->state = STATE_ACTIVE;
+		status = garmin_write_bulk(port, GARMIN_START_SESSION_REQ,
+		                           sizeof(GARMIN_START_SESSION_REQ));
+
+		if (status >= 0) {
+
+			garmin_data_p->ignorePkts++;
+
+			/* not needed, but the win32 driver does it too ... */
+			status = garmin_write_bulk(port,
+						   GARMIN_START_SESSION_REQ2,
+			                           sizeof(GARMIN_START_SESSION_REQ2));
+			if (status >= 0) {
+				status = 0;
+				garmin_data_p->ignorePkts++;
+			}
+		}
+	}
+
+	return status;
+}
+
+
+
+
+
+static int garmin_open (struct usb_serial_port *port, struct file *filp)
+{
+	int status = 0;
+	struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
+
+	dbg("%s - port %d", __FUNCTION__, port->number);
+
+	/*
+	 * Force low_latency on so that our tty_push actually forces the data
+	 * through, otherwise it is scheduled, and with high data rates (like
+	 * with OHCI) data can get lost.
+	 */
+	if (port->tty)
+		port->tty->low_latency = 1;
+
+	garmin_data_p->mode  = initial_mode;
+	garmin_data_p->count = 0;
+	garmin_data_p->flags = 0;
+
+	/* shutdown any bulk reads that might be going on */
+	usb_kill_urb (port->write_urb);
+	usb_kill_urb (port->read_urb);
+
+	if (garmin_data_p->state == STATE_RESET) {
+		status = garmin_init_session(port);
+	}
+
+	garmin_data_p->state = STATE_ACTIVE;
+
+	return status;
+}
+
+
+static void garmin_close (struct usb_serial_port *port, struct file * filp)
+{
+	struct usb_serial *serial = port->serial;
+	struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
+
+	dbg("%s - port %d - mode=%d state=%d flags=0x%X", __FUNCTION__,
+		port->number, garmin_data_p->mode,
+		garmin_data_p->state, garmin_data_p->flags);
+
+	if (!serial)
+		return;
+
+	garmin_clear(garmin_data_p);
+
+	/* shutdown our urbs */
+	usb_kill_urb (port->read_urb);
+	usb_kill_urb (port->write_urb);
+
+	if (noResponseFromAppLayer(garmin_data_p) ||
+	    ((garmin_data_p->flags & CLEAR_HALT_REQUIRED) != 0)) {
+		process_resetdev_request(port);
+		garmin_data_p->state = STATE_RESET;
+	} else {
+		garmin_data_p->state = STATE_DISCONNECTED;
+	}
+}
+
+
+static void garmin_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
+{
+	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
+	struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
+
+	/* free up the transfer buffer, as usb_free_urb() does not do this */
+	kfree (urb->transfer_buffer);
+
+	dbg("%s - port %d", __FUNCTION__, port->number);
+
+	if (urb->status) {
+		dbg("%s - nonzero write bulk status received: %d",
+			__FUNCTION__, urb->status);
+		garmin_data_p->flags |= CLEAR_HALT_REQUIRED;
+	}
+
+	schedule_work(&port->work);
+}
+
+
+static int garmin_write_bulk (struct usb_serial_port *port,
+                              const unsigned char *buf, int count)
+{
+	struct usb_serial *serial = port->serial;
+	struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
+	struct urb *urb;
+	unsigned char *buffer;
+	int status;
+
+	dbg("%s - port %d, state %d", __FUNCTION__, port->number,
+		garmin_data_p->state);
+
+	garmin_data_p->flags &= ~FLAGS_DROP_DATA;
+
+	buffer = kmalloc (count, GFP_ATOMIC);
+	if (!buffer) {
+		dev_err(&port->dev, "out of memory\n");
+		return -ENOMEM;
+	}
+
+	urb = usb_alloc_urb(0, GFP_ATOMIC);
+	if (!urb) {
+		dev_err(&port->dev, "no more free urbs\n");
+		kfree (buffer);
+		return -ENOMEM;
+	}
+
+	memcpy (buffer, buf, count);
+
+	usb_serial_debug_data(debug, &port->dev, __FUNCTION__, count, buffer);
+
+	usb_fill_bulk_urb (urb, serial->dev,
+			 	usb_sndbulkpipe (serial->dev,
+				port->bulk_out_endpointAddress),
+				buffer, count,
+				garmin_write_bulk_callback, port);
+	urb->transfer_flags |= URB_ZERO_PACKET;
+
+	if (GARMIN_LAYERID_APPL == getLayerId(buffer)) {
+		garmin_data_p->flags |= FLAGS_APP_REQ_SEEN;
+		if (garmin_data_p->mode == MODE_GARMIN_SERIAL)  {
+			pkt_clear(garmin_data_p);
+			garmin_data_p->state = STATE_GSP_WAIT_DATA;
+		}
+	}
+
+	/* send it down the pipe */
+	status = usb_submit_urb(urb, GFP_ATOMIC);
+	if (status) {
+		dev_err(&port->dev,
+		        "%s - usb_submit_urb(write bulk) "
+		        "failed with status = %d\n",
+				__FUNCTION__, status);
+		count = status;
+	} else {
+
+		if (GARMIN_LAYERID_APPL == getLayerId(buffer)
+		    && (garmin_data_p->mode == MODE_GARMIN_SERIAL))  {
+
+			gsp_send_ack(garmin_data_p, buffer[4]);
+		}
+	}
+
+	/* we are done with this urb, so let the host driver
+	 * really free it when it is finished with it */
+	usb_free_urb (urb);
+
+	return count;
+}
+
+
+
+static int garmin_write (struct usb_serial_port *port,
+                         const unsigned char *buf, int count)
+{
+	int pktid, pktsiz, len;
+	struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
+	__le32 *privpkt = (__le32 *)garmin_data_p->privpkt;
+
+	usb_serial_debug_data(debug, &port->dev, __FUNCTION__, count, buf);
+
+	/* check for our private packets */
+	if (count >= GARMIN_PKTHDR_LENGTH) {
+
+		len = PRIVPKTSIZ;
+		if (count < len)
+			len = count;
+
+		memcpy(garmin_data_p->privpkt, buf, len);
+
+		pktsiz = getDataLength(garmin_data_p->privpkt);
+		pktid  = getPacketId(garmin_data_p->privpkt);
+
+		if (count == (GARMIN_PKTHDR_LENGTH+pktsiz)
+		    && GARMIN_LAYERID_PRIVATE == getLayerId(garmin_data_p->privpkt)) {
+
+			dbg("%s - processing private request %d",
+				__FUNCTION__, pktid);
+
+			// drop all unfinished transfers
+			garmin_clear(garmin_data_p);
+
+			switch(pktid) {
+
+			case PRIV_PKTID_SET_DEBUG:
+				if (pktsiz != 4)
+					return -EINVPKT;
+				debug = __le32_to_cpu(privpkt[3]);
+				dbg("%s - debug level set to 0x%X",
+					__FUNCTION__, debug);
+				break;
+
+			case PRIV_PKTID_SET_MODE:
+				if (pktsiz != 4)
+					return -EINVPKT;
+				garmin_data_p->mode = __le32_to_cpu(privpkt[3]);
+				dbg("%s - mode set to %d",
+					__FUNCTION__, garmin_data_p->mode);
+				break;
+
+			case PRIV_PKTID_INFO_REQ:
+				priv_status_resp(port);
+				break;
+
+			case PRIV_PKTID_RESET_REQ:
+				garmin_data_p->flags |= FLAGS_APP_REQ_SEEN;
+				break;
+
+			case PRIV_PKTID_SET_DEF_MODE:
+				if (pktsiz != 4)
+					return -EINVPKT;
+				initial_mode = __le32_to_cpu(privpkt[3]);
+				dbg("%s - initial_mode set to %d",
+					__FUNCTION__,
+					garmin_data_p->mode);
+				break;
+			}
+			return count;
+		}
+	}
+
+	if (garmin_data_p->mode == MODE_GARMIN_SERIAL) {
+		return gsp_receive(garmin_data_p, buf, count);
+	} else {	/* MODE_NATIVE */
+		return nat_receive(garmin_data_p, buf, count);
+	}
+}
+
+
+static int garmin_write_room (struct usb_serial_port *port)
+{
+	/*
+	 * Report back the bytes currently available in the output buffer.
+	 */
+	struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
+	return GPS_OUT_BUFSIZ-garmin_data_p->outsize;
+}
+
+
+static int garmin_chars_in_buffer (struct usb_serial_port *port)
+{
+	/*
+	 * Report back the number of bytes currently in our input buffer.
+         * Will this lock up the driver - the buffer contains an incomplete
+         * package which will not be written to the device until it
+         * has been completed ?
+         */
+	//struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
+	//return garmin_data_p->insize;
+	return 0;
+}
+
+
+static void garmin_read_process(struct garmin_data * garmin_data_p,
+				 unsigned char *data, unsigned data_length)
+{
+	if (garmin_data_p->flags & FLAGS_DROP_DATA) {
+		/* abort-transfer cmd is actice */
+		dbg("%s - pkt dropped", __FUNCTION__);
+	} else if (garmin_data_p->state != STATE_DISCONNECTED &&
+	           garmin_data_p->state != STATE_RESET ) {
+
+		/* remember any appl.layer packets, so we know
+		   if a reset is required or not when closing
+		   the device */
+		if (0 == memcmp(data, GARMIN_APP_LAYER_REPLY,
+		                sizeof(GARMIN_APP_LAYER_REPLY)))
+			garmin_data_p->flags |= FLAGS_APP_RESP_SEEN;
+
+		/* if throttling is active or postprecessing is required
+		   put the received data in th input queue, otherwise
+		   send it directly to the tty port */
+		if (garmin_data_p->flags & FLAGS_QUEUING) {
+			pkt_add(garmin_data_p, data, data_length);
+		} else if (garmin_data_p->mode == MODE_GARMIN_SERIAL) {
+			if (getLayerId(data) == GARMIN_LAYERID_APPL) {
+				pkt_add(garmin_data_p, data, data_length);
+			}
+		} else {
+			send_to_tty(garmin_data_p->port, data, data_length);
+		}
+	}
+}
+
+
+static void garmin_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
+{
+	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
+	struct usb_serial *serial =  port->serial;
+	struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
+	unsigned char *data = urb->transfer_buffer;
+	int status;
+
+	dbg("%s - port %d", __FUNCTION__, port->number);
+
+	if (!serial) {
+		dbg("%s - bad serial pointer, exiting", __FUNCTION__);
+		return;
+	}
+
+	if (urb->status) {
+		dbg("%s - nonzero read bulk status received: %d",
+			__FUNCTION__, urb->status);
+		return;
+	}
+
+	usb_serial_debug_data(debug, &port->dev, 
+				__FUNCTION__, urb->actual_length, data);
+
+	garmin_read_process(garmin_data_p, data, urb->actual_length);
+
+	/* Continue trying to read until nothing more is received  */
+	if (urb->actual_length > 0) {
+		usb_fill_bulk_urb (port->read_urb, serial->dev,
+			   usb_rcvbulkpipe (serial->dev,
+					    port->bulk_in_endpointAddress),
+			   port->read_urb->transfer_buffer,
+			   port->read_urb->transfer_buffer_length,
+			   garmin_read_bulk_callback, port);
+		status = usb_submit_urb(port->read_urb, GFP_ATOMIC);
+		if (status)
+			dev_err(&port->dev,
+				"%s - failed resubmitting read urb, error %d\n",
+			        __FUNCTION__, status);
+	}
+	return;
+}
+
+
+static void garmin_read_int_callback (struct urb *urb, struct pt_regs *regs)
+{
+	int status;
+	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
+	struct usb_serial *serial = port->serial;
+	struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
+	unsigned char *data = urb->transfer_buffer;
+
+	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);
+		return;
+	}
+
+	usb_serial_debug_data(debug, &port->dev, __FUNCTION__, 
+				urb->actual_length, urb->transfer_buffer);
+
+	if (urb->actual_length == sizeof(GARMIN_BULK_IN_AVAIL_REPLY) &&
+	    0 == memcmp(data, GARMIN_BULK_IN_AVAIL_REPLY,
+		        sizeof(GARMIN_BULK_IN_AVAIL_REPLY))) {
+
+		dbg("%s - bulk data available.", __FUNCTION__);
+
+		/* bulk data available */
+		usb_fill_bulk_urb (port->read_urb, serial->dev,
+				usb_rcvbulkpipe (serial->dev,
+				port->bulk_in_endpointAddress),
+				port->read_urb->transfer_buffer,
+				port->read_urb->transfer_buffer_length,
+				garmin_read_bulk_callback, port);
+		status = usb_submit_urb(port->read_urb, GFP_KERNEL);
+		if (status) {
+			dev_err(&port->dev,
+				"%s - failed submitting read urb, error %d\n",
+			__FUNCTION__, status);
+		}
+
+	} else if (urb->actual_length == (4+sizeof(GARMIN_START_SESSION_REPLY))
+			 && 0 == memcmp(data, GARMIN_START_SESSION_REPLY,
+			                sizeof(GARMIN_START_SESSION_REPLY))) {
+
+		garmin_data_p->flags |= FLAGS_SESSION_REPLY1_SEEN;
+
+		/* save the serial number */
+		garmin_data_p->serial_num 
+			= __le32_to_cpup((__le32*)(data+GARMIN_PKTHDR_LENGTH));
+
+		dbg("%s - start-of-session reply seen - serial %u.",
+			__FUNCTION__, garmin_data_p->serial_num);
+	}
+
+	if (garmin_data_p->ignorePkts) {
+		/* this reply belongs to a request generated by the driver,
+		   ignore it. */
+		dbg("%s - pkt ignored (%d)",
+			__FUNCTION__, garmin_data_p->ignorePkts);
+		garmin_data_p->ignorePkts--;
+	} else {
+		garmin_read_process(garmin_data_p, data, urb->actual_length);
+	}
+
+	port->interrupt_in_urb->dev = port->serial->dev;
+	status = usb_submit_urb (urb, GFP_ATOMIC);
+	if (status)
+		dev_err(&urb->dev->dev,
+			"%s - Error %d submitting interrupt urb\n",
+			__FUNCTION__, status);
+}
+
+
+/*
+ * Sends the next queued packt to the tty port (garmin native mode only)
+ * and then sets a timer to call itself again until all queued data
+ * is sent.
+ */
+static int garmin_flush_queue(struct garmin_data * garmin_data_p)
+{
+	struct garmin_packet *pkt;
+
+	if ((garmin_data_p->flags & FLAGS_THROTTLED) == 0) {
+		pkt = pkt_pop(garmin_data_p);
+		if (pkt != NULL) {
+
+			send_to_tty(garmin_data_p->port, pkt->data, pkt->size);
+			kfree(pkt);
+			mod_timer(&garmin_data_p->timer, (1)+jiffies);
+
+		} else {
+			garmin_data_p->flags &= ~FLAGS_QUEUING;
+		}
+	}
+	return 0;
+}
+
+
+static void garmin_throttle (struct usb_serial_port *port)
+{
+	struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
+
+	dbg("%s - port %d", __FUNCTION__, port->number);
+	/* set flag, data received will be put into a queue
+	   for later processing */
+	garmin_data_p->flags |= FLAGS_QUEUING|FLAGS_THROTTLED;
+}
+
+
+static void garmin_unthrottle (struct usb_serial_port *port)
+{
+	struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
+
+	dbg("%s - port %d", __FUNCTION__, port->number);
+	garmin_data_p->flags &= ~FLAGS_THROTTLED;
+
+	/* in native mode send queued data to tty, in
+	   serial mode nothing needs to be done here */
+	if (garmin_data_p->mode == MODE_NATIVE)
+		garmin_flush_queue(garmin_data_p);
+}
+
+
+
+/*
+ * The timer is currently only used to send queued packets to
+ * the tty in cases where the protocol provides no own handshaking
+ * to initiate the transfer.
+ */
+static void timeout_handler(unsigned long data)
+{
+	struct garmin_data *garmin_data_p = (struct garmin_data *) data;
+
+	/* send the next queued packet to the tty port */
+	if (garmin_data_p->mode == MODE_NATIVE)
+		if (garmin_data_p->flags & FLAGS_QUEUING)
+			garmin_flush_queue(garmin_data_p);
+}
+
+
+
+static int garmin_attach (struct usb_serial *serial)
+{
+	int status = 0;
+	struct usb_serial_port *port = serial->port[0];
+	struct garmin_data * garmin_data_p = NULL;
+
+	dbg("%s", __FUNCTION__);
+
+	garmin_data_p = kmalloc (sizeof(struct garmin_data), GFP_KERNEL);
+	if (garmin_data_p == NULL) {
+		dev_err(&port->dev, "%s - Out of memory\n", __FUNCTION__);
+		return -ENOMEM;
+	}
+	memset (garmin_data_p, 0, sizeof(struct garmin_data));
+	init_timer(&garmin_data_p->timer);
+	spin_lock_init(&garmin_data_p->lock);
+	INIT_LIST_HEAD(&garmin_data_p->pktlist);
+	//garmin_data_p->timer.expires = jiffies + session_timeout;
+	garmin_data_p->timer.data = (unsigned long)garmin_data_p;
+	garmin_data_p->timer.function = timeout_handler;
+	garmin_data_p->port = port;
+	garmin_data_p->state = 0;
+	garmin_data_p->count = 0;
+	usb_set_serial_port_data(port, garmin_data_p);
+
+	status = garmin_init_session(port);
+
+	return status;
+}
+
+
+static void garmin_shutdown (struct usb_serial *serial)
+{
+	struct usb_serial_port *port = serial->port[0];
+	struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
+
+	dbg("%s", __FUNCTION__);
+
+	usb_kill_urb (port->interrupt_in_urb);
+	del_timer_sync(&garmin_data_p->timer);
+	kfree (garmin_data_p);
+	usb_set_serial_port_data(port, NULL);
+}
+
+
+
+
+
+
+
+/* All of the device info needed */
+static struct usb_serial_device_type garmin_device = {
+	.owner               = THIS_MODULE,
+	.name                = "Garmin GPS usb/tty",
+	.short_name          = "garmin_gps",
+	.id_table            = id_table,
+	.num_interrupt_in    = 1,
+	.num_bulk_in         = 1,
+	.num_bulk_out        = 1,
+	.num_ports           = 1,
+	.open                = garmin_open,
+	.close               = garmin_close,
+	.throttle            = garmin_throttle,
+	.unthrottle          = garmin_unthrottle,
+	.attach              = garmin_attach,
+	.shutdown            = garmin_shutdown,
+	.write               = garmin_write,
+	.write_room          = garmin_write_room,
+	.chars_in_buffer     = garmin_chars_in_buffer,
+	.write_bulk_callback = garmin_write_bulk_callback,
+	.read_bulk_callback  = garmin_read_bulk_callback,
+	.read_int_callback   = garmin_read_int_callback,
+};
+
+
+static int __init garmin_init (void)
+{
+	int retval;
+
+	retval = usb_serial_register(&garmin_device);
+	if (retval)
+		goto failed_garmin_register;
+	retval = usb_register(&garmin_driver);
+	if (retval)
+		goto failed_usb_register;
+	info(DRIVER_DESC " " DRIVER_VERSION);
+
+	return 0;
+failed_usb_register:
+	usb_serial_deregister(&garmin_device);
+failed_garmin_register:
+	return retval;
+}
+
+
+static void __exit garmin_exit (void)
+{
+	usb_deregister (&garmin_driver);
+	usb_serial_deregister (&garmin_device);
+}
+
+
+
+
+module_init(garmin_init);
+module_exit(garmin_exit);
+
+MODULE_AUTHOR( DRIVER_AUTHOR );
+MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_LICENSE("GPL");
+
+module_param(debug, bool, S_IWUSR | S_IRUGO);
+MODULE_PARM_DESC(debug, "Debug enabled or not");
+module_param(initial_mode, int, S_IRUGO);
+MODULE_PARM_DESC(initial_mode, "Initial mode");
+
diff -Nru a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c
--- a/drivers/usb/serial/io_edgeport.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/usb/serial/io_edgeport.c	2005-03-01 23:38:52 -08:00
@@ -659,7 +659,7 @@
 
 	memset (product_info, 0, sizeof(struct edgeport_product_info));
 
-	product_info->ProductId		= (__u16)(edge_serial->serial->dev->descriptor.idProduct & ~ION_DEVICE_ID_80251_NETCHIP);
+	product_info->ProductId		= (__u16)(le16_to_cpu(edge_serial->serial->dev->descriptor.idProduct) & ~ION_DEVICE_ID_80251_NETCHIP);
 	product_info->NumPorts		= edge_serial->manuf_descriptor.NumPorts;
 	product_info->ProdInfoVer	= 0;
 
@@ -675,7 +675,7 @@
 	memcpy(product_info->ManufactureDescDate, edge_serial->manuf_descriptor.DescDate, sizeof(edge_serial->manuf_descriptor.DescDate));
 
 	// check if this is 2nd generation hardware
-	if (edge_serial->serial->dev->descriptor.idProduct & ION_DEVICE_ID_80251_NETCHIP) {
+	if (le16_to_cpu(edge_serial->serial->dev->descriptor.idProduct) & ION_DEVICE_ID_80251_NETCHIP) {
 		product_info->FirmwareMajorVersion	= OperationalCodeImageVersion_GEN2.MajorVersion;
 		product_info->FirmwareMinorVersion	= OperationalCodeImageVersion_GEN2.MinorVersion;
 		product_info->FirmwareBuildNumber	= cpu_to_le16(OperationalCodeImageVersion_GEN2.BuildNumber);
diff -Nru a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c
--- a/drivers/usb/serial/io_ti.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/usb/serial/io_ti.c	2005-03-01 23:39:17 -08:00
@@ -1342,9 +1342,9 @@
 	if (status)
 		return status;
 
-	if (serial->serial->dev->descriptor.idVendor != USB_VENDOR_ID_ION) {
+	if (le16_to_cpu(serial->serial->dev->descriptor.idVendor) != USB_VENDOR_ID_ION) {
 		dbg ("%s - VID = 0x%x", __FUNCTION__,
-		     serial->serial->dev->descriptor.idVendor);
+		     le16_to_cpu(serial->serial->dev->descriptor.idVendor));
 		serial->TI_I2C_Type = DTK_ADDR_SPACE_I2C_TYPE_II;
 		goto StayInBootMode;
 	}
diff -Nru a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c
--- a/drivers/usb/serial/keyspan.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/usb/serial/keyspan.c	2005-03-01 23:38:52 -08:00
@@ -374,7 +374,7 @@
 		flip = p_priv->out_flip;
 	
 		/* Check we have a valid urb/endpoint before we use it... */
-		if ((this_urb = p_priv->out_urbs[flip]) == 0) {
+		if ((this_urb = p_priv->out_urbs[flip]) == NULL) {
 			/* no bulk out, so return 0 bytes written */
 			dbg("%s - no output urb :(", __FUNCTION__);
 			return count;
@@ -1020,11 +1020,11 @@
 	flip = p_priv->out_flip;
 
 	/* Check both endpoints to see if any are available. */
-	if ((this_urb = p_priv->out_urbs[flip]) != 0) {
+	if ((this_urb = p_priv->out_urbs[flip]) != NULL) {
 		if (this_urb->status != -EINPROGRESS)
 			return (data_len);
 		flip = (flip + 1) & d_details->outdat_endp_flip;        
-		if ((this_urb = p_priv->out_urbs[flip]) != 0) 
+		if ((this_urb = p_priv->out_urbs[flip]) != NULL) 
 			if (this_urb->status != -EINPROGRESS)
 				return (data_len);
 	}
@@ -1174,16 +1174,16 @@
 	char				*fw_name;
 
 	dbg("Keyspan startup version %04x product %04x",
-	    serial->dev->descriptor.bcdDevice,
-	    serial->dev->descriptor.idProduct); 
+	    le16_to_cpu(serial->dev->descriptor.bcdDevice),
+	    le16_to_cpu(serial->dev->descriptor.idProduct));
 	
-	if ((serial->dev->descriptor.bcdDevice & 0x8000) != 0x8000) {
+	if ((le16_to_cpu(serial->dev->descriptor.bcdDevice) & 0x8000) != 0x8000) {
 		dbg("Firmware already loaded.  Quitting.");
 		return(1);
 	}
 
 		/* Select firmware image on the basis of idProduct */
-	switch (serial->dev->descriptor.idProduct) {
+	switch (le16_to_cpu(serial->dev->descriptor.idProduct)) {
 	case keyspan_usa28_pre_product_id:
 		record = &keyspan_usa28_firmware[0];
 		fw_name = "USA28";
@@ -2248,10 +2248,10 @@
 	dbg("%s", __FUNCTION__);
 
 	for (i = 0; (d_details = keyspan_devices[i]) != NULL; ++i)
-		if (d_details->product_id == serial->dev->descriptor.idProduct)
+		if (d_details->product_id == le16_to_cpu(serial->dev->descriptor.idProduct))
 			break;
 	if (d_details == NULL) {
-		dev_err(&serial->dev->dev, "%s - unknown product id %x\n", __FUNCTION__, serial->dev->descriptor.idProduct);
+		dev_err(&serial->dev->dev, "%s - unknown product id %x\n", __FUNCTION__, le16_to_cpu(serial->dev->descriptor.idProduct));
 		return 1;
 	}
 
diff -Nru a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c
--- a/drivers/usb/serial/keyspan_pda.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/usb/serial/keyspan_pda.c	2005-03-01 23:39:07 -08:00
@@ -713,12 +713,12 @@
 	response = ezusb_set_reset(serial, 1);
 
 #ifdef KEYSPAN
-	if (serial->dev->descriptor.idVendor == KEYSPAN_VENDOR_ID)
+	if (le16_to_cpu(serial->dev->descriptor.idVendor) == KEYSPAN_VENDOR_ID)
 		record = &keyspan_pda_firmware[0];
 #endif
 #ifdef XIRCOM
-	if ((serial->dev->descriptor.idVendor == XIRCOM_VENDOR_ID) ||
-	    (serial->dev->descriptor.idVendor == ENTREGRA_VENDOR_ID))
+	if ((le16_to_cpu(serial->dev->descriptor.idVendor) == XIRCOM_VENDOR_ID) ||
+	    (le16_to_cpu(serial->dev->descriptor.idVendor) == ENTREGRA_VENDOR_ID))
 		record = &xircom_pgs_firmware[0];
 #endif
 	if (record == NULL) {
diff -Nru a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c
--- a/drivers/usb/serial/kobil_sct.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/usb/serial/kobil_sct.c	2005-03-01 23:39:09 -08:00
@@ -155,7 +155,7 @@
 
 	priv->filled = 0;
 	priv->cur_pos = 0;
-	priv->device_type = serial->product;
+	priv->device_type = le16_to_cpu(serial->dev->descriptor.idProduct);
 	priv->line_state = 0;
 
 	switch (priv->device_type){
diff -Nru a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c
--- a/drivers/usb/serial/mct_u232.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/usb/serial/mct_u232.c	2005-03-01 23:39:07 -08:00
@@ -82,21 +82,10 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v1.2"
+#define DRIVER_VERSION "z2.0"		/* Linux in-kernel version */
 #define DRIVER_AUTHOR "Wolfgang Grandegger <wolfgang@ces.ch>"
 #define DRIVER_DESC "Magic Control Technology USB-RS232 converter driver"
 
-/*
- * Some not properly written applications do not handle the return code of
- * write() correctly. This can result in character losses. A work-a-round
- * can be compiled in with the following definition. This work-a-round
- * should _NOT_ be part of an 'official' kernel release, of course!
- */
-#undef FIX_WRITE_RETURN_CODE_PROBLEM
-#ifdef FIX_WRITE_RETURN_CODE_PROBLEM
-static int write_blocking; /* disabled by default */
-#endif
-
 static int debug;
 
 /*
@@ -108,12 +97,6 @@
 					  struct file *filp);
 static void mct_u232_close	         (struct usb_serial_port *port,
 					  struct file *filp);
-#ifdef FIX_WRITE_RETURN_CODE_PROBLEM
-static int  mct_u232_write	         (struct usb_serial_port *port,
-					  const unsigned char *buf,
-					  int count);
-static void mct_u232_write_bulk_callback (struct urb *urb, struct pt_regs *regs);
-#endif
 static void mct_u232_read_int_callback   (struct urb *urb, struct pt_regs *regs);
 static void mct_u232_set_termios         (struct usb_serial_port *port,
 					  struct termios * old);
@@ -151,7 +134,7 @@
 
 static struct usb_serial_device_type mct_u232_device = {
 	.owner =	     THIS_MODULE,
-	.name =		     "Magic Control Technology USB-RS232",
+	.name =		     "MCT U232",
 	.short_name =	     "mct_u232",
 	.id_table =	     id_table_combined,
 	.num_interrupt_in =  2,
@@ -160,10 +143,6 @@
 	.num_ports =	     1,
 	.open =		     mct_u232_open,
 	.close =	     mct_u232_close,
-#ifdef FIX_WRITE_RETURN_CODE_PROBLEM
-	.write =	     mct_u232_write,
-	.write_bulk_callback = mct_u232_write_bulk_callback,
-#endif
 	.read_int_callback = mct_u232_read_int_callback,
 	.ioctl =	     mct_u232_ioctl,
 	.set_termios =	     mct_u232_set_termios,
@@ -194,9 +173,10 @@
  * we do not know how to support. We ignore them for the moment.
  * XXX Rate-limit the error message, it's user triggerable.
  */
-static int mct_u232_calculate_baud_rate(struct usb_serial *serial, int value) {
-	if (serial->dev->descriptor.idProduct == MCT_U232_SITECOM_PID
-	  || serial->dev->descriptor.idProduct == MCT_U232_BELKIN_F5U109_PID) {
+static int mct_u232_calculate_baud_rate(struct usb_serial *serial, int value)
+{
+	if (le16_to_cpu(serial->dev->descriptor.idProduct) == MCT_U232_SITECOM_PID
+	  || le16_to_cpu(serial->dev->descriptor.idProduct) == MCT_U232_BELKIN_F5U109_PID) {
 		switch (value) {
 		case    B300: return 0x01;
 		case    B600: return 0x02; /* this one not tested */
@@ -366,15 +346,11 @@
 	struct mct_u232_private *priv;
 	struct usb_serial_port *port, *rport;
 
-	/* allocate the private data structure */
 	priv = kmalloc(sizeof(struct mct_u232_private), GFP_KERNEL);
 	if (!priv)
 		return -ENOMEM;
-	/* set initial values for control structures */
+	memset(priv, 0, sizeof(struct mct_u232_private));
 	spin_lock_init(&priv->lock);
-	priv->control_state = 0;
-	priv->last_lsr = 0;
-	priv->last_msr = 0;
 	usb_set_serial_port_data(serial->port[0], priv);
 
 	init_waitqueue_head(&serial->port[0]->write_wait);
@@ -404,8 +380,10 @@
 	for (i=0; i < serial->num_ports; ++i) {
 		/* My special items, the standard routines free my urbs */
 		priv = usb_get_serial_port_data(serial->port[i]);
-		if (priv)
+		if (priv) {
+			usb_set_serial_port_data(serial->port[i], NULL);
 			kfree(priv);
+		}
 	}
 } /* mct_u232_shutdown */
 
@@ -426,7 +404,7 @@
 	 * it seems to be able to accept only 16 bytes (and that's what
 	 * SniffUSB says too...)
 	 */
-	if (serial->dev->descriptor.idProduct == MCT_U232_SITECOM_PID)
+	if (le16_to_cpu(serial->dev->descriptor.idProduct) == MCT_U232_SITECOM_PID)
 		port->bulk_out_size = 16;
 
 	/* Do a defined restart: the normal serial device seems to 
@@ -459,14 +437,16 @@
 	port->read_urb->dev = port->serial->dev;
 	retval = usb_submit_urb(port->read_urb, GFP_KERNEL);
 	if (retval) {
-		err("usb_submit_urb(read bulk) failed");
+		err("usb_submit_urb(read bulk) failed pipe 0x%x err %d",
+		    port->read_urb->pipe, retval);
 		goto exit;
 	}
 
 	port->interrupt_in_urb->dev = port->serial->dev;
 	retval = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
 	if (retval)
-		err(" usb_submit_urb(read int) failed");
+		err(" usb_submit_urb(read int) failed pipe 0x%x err %d",
+		    port->interrupt_in_urb->pipe, retval);
 
 exit:
 	return 0;
@@ -486,101 +466,6 @@
 } /* mct_u232_close */
 
 
-#ifdef FIX_WRITE_RETURN_CODE_PROBLEM
-/* The generic routines work fine otherwise */
-
-static int mct_u232_write (struct usb_serial_port *port,
-			   const unsigned char *buf, int count)
-{
-	struct usb_serial *serial = port->serial;
-	int result, bytes_sent, size;
-
-	dbg("%s - port %d", __FUNCTION__, port->number);
-
-	if (count == 0) {
-		dbg("%s - write request of 0 bytes", __FUNCTION__);
-		return (0);
-	}
-
-	/* only do something if we have a bulk out endpoint */
-	if (!serial->num_bulk_out)
-		return(0);
-	
-	/* another write is still pending? */
-	if (port->write_urb->status == -EINPROGRESS) {
-		dbg("%s - already writing", __FUNCTION__);
-		return (0);
-	}
-		
-	bytes_sent = 0;
-	while (count > 0) {
-		size = (count > port->bulk_out_size) ? port->bulk_out_size : count;
-		
-		usb_serial_debug_data(debug, &port->dev, __FUNCTION__, size, buf);
-		
-		memcpy (port->write_urb->transfer_buffer, buf, size);
-		
-		/* set up our urb */
-		usb_fill_bulk_urb(port->write_urb, serial->dev,
-			      usb_sndbulkpipe(serial->dev,
-					      port->bulk_out_endpointAddress),
-			      port->write_urb->transfer_buffer, size,
-			      ((serial->type->write_bulk_callback) ?
-			       serial->type->write_bulk_callback :
-			       mct_u232_write_bulk_callback),
-			      port);
-		
-		/* send the data out the bulk port */
-		result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
-		if (result) {
-			err("%s - failed submitting write urb, error %d", __FUNCTION__, result);
-			return result;
-		}
-
-		bytes_sent += size;
-		if (write_blocking)
-			interruptible_sleep_on(&port->write_wait);
-		else
-			break;
-
-		buf += size;
-		count -= size;
-	}
-	
-	return bytes_sent;
-} /* mct_u232_write */
-
-static void mct_u232_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
-{
-	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
-	struct usb_serial *serial = port->serial;
-       	struct tty_struct *tty = port->tty;
-
-	dbg("%s - port %d", __FUNCTION__, port->number);
-	
-	if (!serial) {
-		dbg("%s - bad serial pointer, exiting", __FUNCTION__);
-		return;
-	}
-
-	if (urb->status) {
-		dbg("%s - nonzero write bulk status received: %d", __FUNCTION__,
-		    urb->status);
-		return;
-	}
-
-	if (write_blocking) {
-		wake_up_interruptible(&port->write_wait);
-		tty_wakeup(tty);
-	} else {
-		/* from generic_write_bulk_callback */
-		schedule_work(&port->work);
-	}
-
-	return;
-} /* mct_u232_write_bulk_callback */
-#endif
-
 static void mct_u232_read_int_callback (struct urb *urb, struct pt_regs *regs)
 {
 	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
@@ -591,8 +476,6 @@
 	int status;
 	unsigned long flags;
 
-        dbg("%s - port %d", __FUNCTION__, port->number);
-
 	switch (urb->status) {
 	case 0:
 		/* success */
@@ -612,7 +495,8 @@
 		dbg("%s - bad serial pointer, exiting", __FUNCTION__);
 		return;
 	}
-	
+
+        dbg("%s - port %d", __FUNCTION__, port->number);
 	usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data);
 
 	/*
@@ -893,12 +777,5 @@
 MODULE_DESCRIPTION( DRIVER_DESC );
 MODULE_LICENSE("GPL");
 
-#ifdef FIX_WRITE_RETURN_CODE_PROBLEM
-module_param(write_blocking, int, 0);
-MODULE_PARM_DESC(write_blocking, 
-		 "The write function will block to write out all data");
-#endif
-
 module_param(debug, bool, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(debug, "Debug enabled or not");
-
diff -Nru a/drivers/usb/serial/ti_fw_3410.h b/drivers/usb/serial/ti_fw_3410.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/usb/serial/ti_fw_3410.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,885 @@
+/* vi: ts=8 sw=8
+ *
+ * TI 3410 USB Serial Driver Firmware Header
+ *
+ * Copyright (C) 2004 Texas Instruments
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the 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 _TI_FW_3410_H_
+#define _TI_FW_3410_H_
+
+/* firmware 9/10/04 FW3410_Special_StartWdogOnStartPort */
+
+static unsigned char ti_fw_3410[] = {
+0xC2, 0x35,	/* firmware image length excluding header, little endian */
+0x00, 		/* placeholder for checksum */
+
+0x02,0x00,0x1e,0x02,0x1a,0xdb,0xff,0xff,0xff,0xff,0xff,0x02,0x32,0xcb,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x02,0x33,0x76,0x75,0x81,
+0xce,0x90,0xfd,0xe8,0x85,0x83,0xa0,0x12,0x34,0xea,0xec,0x4d,0x60,0x6a,0x78,0xab,
+0x80,0x03,0x76,0x00,0x18,0xb8,0x9c,0xfa,0x78,0x7f,0x80,0x03,0x76,0x00,0x18,0xb8,
+0x65,0xfa,0x78,0x20,0x80,0x03,0x76,0x00,0x18,0xb8,0x20,0xfa,0x90,0xfd,0xdd,0xae,
+0x83,0xaf,0x82,0x90,0xfb,0xf8,0x12,0x00,0xa1,0x60,0x05,0xe4,0xf0,0xa3,0x80,0xf6,
+0x90,0xfd,0xe8,0xa8,0x82,0x90,0xfd,0xe8,0xa9,0x82,0xe8,0xc3,0x99,0x50,0x05,0x76,
+0x00,0x08,0x80,0xf6,0x90,0x00,0xff,0x12,0x00,0xaa,0x90,0x01,0x03,0x12,0x00,0xaa,
+0x90,0x01,0x07,0x12,0x00,0xaa,0x90,0x01,0x0b,0x12,0x00,0xc8,0x90,0x01,0x11,0x12,
+0x00,0xc8,0x90,0x01,0x17,0x12,0x00,0xc8,0x75,0xd0,0x00,0x12,0x33,0xc8,0x02,0x01,
+0x1d,0xef,0x65,0x82,0x70,0x03,0xee,0x65,0x83,0x22,0xe4,0x93,0xf8,0x74,0x01,0x93,
+0xf9,0x74,0x02,0x93,0xfe,0x74,0x03,0x93,0xf5,0x82,0x8e,0x83,0xe8,0x69,0x70,0x01,
+0x22,0xe4,0x93,0xf6,0xa3,0x08,0x80,0xf4,0xe4,0x93,0xfc,0x74,0x01,0x93,0xfd,0x74,
+0x02,0x93,0xfe,0x74,0x03,0x93,0xff,0x74,0x04,0x93,0xf8,0x74,0x05,0x93,0xf5,0x82,
+0x88,0x83,0x12,0x00,0xa1,0x70,0x01,0x22,0xe4,0x93,0xa3,0xa8,0x83,0xa9,0x82,0x8c,
+0x83,0x8d,0x82,0xf0,0xa3,0xac,0x83,0xad,0x82,0x88,0x83,0x89,0x82,0x80,0xe3,0x21,
+0x21,0x04,0x92,0x80,0x80,0x04,0x92,0xac,0xae,0x04,0x92,0xfd,0xe8,0x04,0x94,0x04,
+0x94,0xfb,0xf3,0x04,0x99,0x04,0x94,0xfb,0xf3,0x04,0xf9,0x04,0xf9,0x80,0xfe,0xd0,
+0xf0,0x30,0xf0,0x09,0x20,0xf3,0x03,0xf6,0x80,0x10,0xf7,0x80,0x0d,0x30,0xf1,0x09,
+0x20,0xf3,0x03,0xf2,0x80,0x04,0xf3,0x80,0x01,0xf0,0x20,0xf4,0x04,0xfc,0xd0,0xe0,
+0xcc,0x22,0xcc,0xc0,0xe0,0x12,0x01,0x5a,0x02,0x01,0x4b,0xbc,0x00,0x05,0xd0,0xf0,
+0xac,0xf0,0x22,0xc3,0x13,0xdc,0xfc,0x02,0x01,0x21,0xbf,0x00,0x09,0xed,0x25,0x82,
+0x75,0xf0,0x01,0xf8,0xe6,0x22,0xbf,0x01,0x0f,0xed,0x25,0x82,0xf5,0x82,0xee,0x35,
+0x83,0xf5,0x83,0x75,0xf0,0x04,0xe0,0x22,0xed,0x25,0x82,0x75,0xf0,0x02,0xf8,0xe2,
+0x22,0xd0,0x83,0xd0,0x82,0xf5,0xf0,0xc3,0xe4,0x93,0xa3,0xc5,0xf0,0x95,0xf0,0xc0,
+0xe0,0xc3,0xd0,0xf0,0xe4,0x93,0xa3,0x95,0xf0,0x40,0x12,0xa3,0xa3,0xc3,0xe5,0xf0,
+0x33,0x50,0x02,0x05,0x83,0x25,0x82,0xf5,0x82,0x50,0x02,0x05,0x83,0x74,0x01,0x93,
+0xc0,0xe0,0xe4,0x93,0xc0,0xe0,0x22,0xd0,0x83,0xd0,0x82,0xf5,0xf0,0xe4,0x93,0x70,
+0x09,0x74,0x01,0x93,0x70,0x04,0xa3,0xa3,0x80,0x0c,0x74,0x02,0x93,0x65,0xf0,0x60,
+0x05,0xa3,0xa3,0xa3,0x80,0xe7,0x74,0x01,0x93,0xc0,0xe0,0xe4,0x93,0xc0,0xe0,0x22,
+0x12,0x02,0x5b,0x02,0x01,0xf2,0x12,0x02,0xaf,0x02,0x01,0xf2,0x12,0x02,0xd3,0x02,
+0x01,0xf2,0x30,0xe0,0x07,0x20,0xe3,0x02,0xe6,0x22,0xe7,0x22,0x30,0xe1,0x07,0x20,
+0xe3,0x02,0xe2,0x22,0xe3,0x22,0x30,0xe2,0x02,0xe0,0x22,0xe4,0x93,0x22,0x12,0x02,
+0xd3,0x02,0x02,0x1a,0x12,0x02,0xaf,0x02,0x02,0x1a,0xab,0xf0,0x12,0x02,0x24,0xcb,
+0xc5,0xf0,0xcb,0x22,0x30,0xe0,0x10,0x20,0xe3,0x06,0xe6,0xf5,0xf0,0x08,0xe6,0x22,
+0xe7,0xf5,0xf0,0x09,0xe7,0x19,0x22,0x30,0xe1,0x10,0x20,0xe3,0x06,0xe2,0xf5,0xf0,
+0x08,0xe2,0x22,0xe3,0xf5,0xf0,0x09,0xe3,0x19,0x22,0x30,0xe2,0x06,0xe0,0xf5,0xf0,
+0xa3,0xe0,0x22,0xe4,0x93,0xf5,0xf0,0x74,0x01,0x93,0x22,0xbb,0x00,0x03,0x74,0x09,
+0x22,0xbb,0x01,0x07,0x89,0x82,0x8a,0x83,0x74,0x04,0x22,0xbb,0x02,0x07,0x89,0x82,
+0x8a,0x83,0x74,0x10,0x22,0x74,0x0a,0x22,0x02,0x02,0x7b,0xbb,0x00,0x07,0xe9,0x25,
+0x82,0xf8,0x74,0x01,0x22,0xbb,0x01,0x0d,0xe9,0x25,0x82,0xf5,0x82,0xea,0x35,0x83,
+0xf5,0x83,0x74,0x04,0x22,0xbb,0x02,0x0d,0xe9,0x25,0x82,0xf5,0x82,0xea,0x35,0x83,
+0xf5,0x83,0x74,0x10,0x22,0xe9,0x25,0x82,0xf8,0x74,0x02,0x22,0x02,0x02,0xaf,0xbf,
+0x00,0x05,0xed,0xf8,0x74,0x01,0x22,0xbf,0x01,0x07,0x8d,0x82,0x8e,0x83,0x74,0x04,
+0x22,0xbf,0x02,0x07,0x8d,0x82,0x8e,0x83,0x74,0x10,0x22,0xed,0xf8,0x74,0x02,0x22,
+0x02,0x02,0xd3,0xbf,0x00,0x07,0xed,0x25,0x82,0xf8,0x74,0x01,0x22,0xbf,0x01,0x0d,
+0xed,0x25,0x82,0xf5,0x82,0xee,0x35,0x83,0xf5,0x83,0x74,0x04,0x22,0xbf,0x02,0x0d,
+0xed,0x25,0x82,0xf5,0x82,0xee,0x35,0x83,0xf5,0x83,0x74,0x10,0x22,0xed,0x25,0x82,
+0xf8,0x74,0x02,0x22,0x02,0x03,0x07,0xc0,0xe0,0x12,0x02,0x5b,0x02,0x03,0x1f,0xc0,
+0xe0,0x12,0x02,0xaf,0x02,0x03,0x1f,0xc0,0xe0,0x12,0x02,0xd3,0x02,0x03,0x1f,0x30,
+0xe0,0x0b,0x20,0xe3,0x04,0xd0,0xe0,0xf6,0x22,0xd0,0xe0,0xf7,0x22,0x30,0xe1,0x0b,
+0x20,0xe3,0x04,0xd0,0xe0,0xf2,0x22,0xd0,0xe0,0xf3,0x22,0xd0,0xe0,0xf0,0x22,0xc9,
+0xcd,0xc9,0xca,0xce,0xca,0xcb,0xcf,0xcb,0x12,0x03,0x52,0xed,0xf9,0xee,0xfa,0xef,
+0xfb,0x22,0xbb,0x00,0x2f,0xbf,0x00,0x0a,0xfa,0xed,0xf8,0xe7,0xf6,0x08,0x09,0xda,
+0xfa,0x22,0xbf,0x01,0x12,0x8d,0x82,0x8e,0x83,0xf8,0x02,0x03,0x6f,0x09,0xa3,0xe7,
+0xf0,0xd8,0xfa,0x22,0x02,0x03,0x7a,0xfa,0xed,0xf8,0xe7,0xf2,0x08,0x09,0xda,0xfa,
+0x22,0x02,0x03,0x84,0xbb,0x01,0x4d,0xbf,0x00,0x14,0x89,0x82,0x8a,0x83,0xf9,0xed,
+0xf8,0x02,0x03,0x96,0x08,0xa3,0xe0,0xf6,0xd9,0xfa,0x22,0x02,0x03,0xa7,0xbf,0x01,
+0x22,0x8d,0x82,0x8e,0x83,0xfb,0x08,0xc9,0xc5,0x82,0xc9,0xca,0xc5,0x83,0xca,0xe0,
+0xa3,0xc9,0xc5,0x82,0xc9,0xca,0xc5,0x83,0xca,0xf0,0xa3,0xdb,0xea,0xd8,0xe8,0x22,
+0x02,0x03,0xca,0x8d,0x82,0x8e,0x83,0xf9,0xed,0xf8,0xe0,0xf2,0x08,0xa3,0xd9,0xfa,
+0x22,0x02,0x03,0xd4,0xbb,0x02,0x4d,0xbf,0x00,0x12,0x89,0x82,0x8a,0x83,0xf9,0xed,
+0xf8,0x02,0x03,0xe6,0x08,0xa3,0xe4,0x93,0xf6,0xd9,0xf9,0x22,0xbf,0x01,0x23,0x8d,
+0x82,0x8e,0x83,0xfb,0x08,0xc9,0xc5,0x82,0xc9,0xca,0xc5,0x83,0xca,0xe4,0x93,0xa3,
+0xc9,0xc5,0x82,0xc9,0xca,0xc5,0x83,0xca,0xf0,0xa3,0xdb,0xe9,0xd8,0xe7,0x22,0x02,
+0x04,0x19,0x89,0x82,0x8a,0x83,0xf9,0xed,0xf8,0xe4,0x93,0xf2,0x08,0xa3,0xd9,0xf9,
+0x22,0x02,0x04,0x2a,0xbf,0x00,0x0d,0xfa,0xed,0xf8,0xe3,0xf6,0x08,0x09,0xda,0xfa,
+0x22,0x02,0x04,0x34,0xbf,0x01,0x12,0x8d,0x82,0x8e,0x83,0xf8,0x02,0x04,0x41,0x09,
+0xa3,0xe3,0xf0,0xd8,0xfa,0x22,0x02,0x04,0x4c,0xfa,0xed,0xf8,0xe3,0xf2,0x08,0x09,
+0xda,0xfa,0x22,0x02,0x04,0x56,0xe6,0xfb,0x08,0xe6,0xfa,0x08,0xe6,0xf9,0x04,0xf6,
+0x18,0x70,0x01,0x06,0x22,0xe6,0xff,0x08,0xe6,0xfe,0x08,0xe6,0xfd,0x22,0xef,0xf0,
+0xa3,0xee,0xf0,0xa3,0xed,0xf0,0x22,0xeb,0xf0,0xa3,0xea,0xf0,0xa3,0xe9,0xf0,0x22,
+0xe0,0xff,0xa3,0xe0,0xfe,0xa3,0xe0,0xfd,0x22,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,
+0xf9,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0xf9,0x00,0x61,0x05,0x68,0x00,
+0x26,0x05,0x8f,0x00,0x33,0x0a,0x00,0x00,0x61,0x0a,0x6c,0x00,0x66,0x15,0x1d,0x00,
+0x61,0x0c,0xf0,0x00,0x61,0x09,0xa0,0x00,0x61,0x09,0xd7,0x00,0x61,0x0d,0xb7,0x00,
+0x61,0x0b,0xe8,0x00,0x61,0x0a,0x13,0x00,0x61,0x0a,0x48,0x00,0x61,0x17,0x15,0x00,
+0x33,0x17,0x28,0x00,0x34,0x1d,0xf6,0x00,0x43,0x1e,0xa1,0x00,0x44,0x20,0x0e,0x00,
+0x44,0x1f,0xfc,0x00,0x47,0x1e,0xc8,0x00,0x47,0x1f,0x6d,0x00,0x4d,0x1f,0xbe,0x00,
+0x4f,0x1e,0xea,0x00,0x58,0x32,0x56,0x00,0x61,0x7c,0xcc,0x7d,0xff,0x12,0x1c,0xa7,
+0x22,0x90,0xff,0xfc,0xe0,0x20,0xe7,0x2d,0xc2,0xaf,0xae,0x59,0xaf,0x58,0x75,0x5a,
+0x20,0xe5,0x5a,0x14,0xc5,0x5a,0x60,0x19,0xe4,0xfe,0x7f,0x05,0xee,0x4f,0xce,0x24,
+0xff,0xce,0xcf,0x34,0xff,0xcf,0x60,0x07,0xe4,0x90,0xff,0x92,0xf0,0x80,0xed,0x80,
+0xe0,0x8e,0x59,0x8f,0x58,0x22,0x12,0x05,0x01,0x7d,0x07,0x7c,0xb7,0x12,0x32,0x72,
+0x7d,0x0f,0x7c,0x6e,0x12,0x32,0x8c,0x78,0x9d,0x7a,0x06,0xe4,0xf6,0x08,0xda,0xfc,
+0x7a,0x06,0x12,0x05,0xc4,0x7c,0x03,0x12,0x0e,0x4c,0x12,0x21,0x4a,0xe4,0xfe,0xff,
+0x7c,0x0f,0x12,0x31,0xfb,0xd2,0xa8,0x22,0x12,0x30,0xe6,0xe4,0x90,0xfc,0x38,0xf0,
+0x90,0xff,0xf0,0xe0,0x30,0xe4,0x08,0x74,0x01,0x90,0xfc,0x39,0xf0,0x80,0x05,0xe4,
+0x90,0xfc,0x39,0xf0,0x7d,0x0a,0x7c,0x00,0x12,0x25,0x26,0x12,0x31,0x69,0x22,0x12,
+0x30,0xe6,0x90,0xfc,0x39,0xe0,0x14,0x70,0x0e,0x90,0xff,0xf0,0xe0,0x44,0x10,0xf0,
+0x7c,0x00,0x12,0x25,0xbf,0x80,0x19,0x90,0xfc,0x39,0xe0,0x70,0x0e,0x90,0xff,0xf0,
+0xe0,0x54,0xef,0xf0,0x7c,0x00,0x12,0x25,0xbf,0x80,0x05,0x7c,0x17,0x12,0x25,0xbf,
+0x12,0x31,0x69,0x22,0x90,0xff,0xf0,0xe0,0x54,0xab,0xf0,0x90,0xff,0xf0,0xe0,0x44,
+0x20,0xf0,0x22,0x8c,0x37,0x8d,0x36,0x78,0x82,0xed,0xf6,0x08,0xec,0xf6,0xed,0xfe,
+0xec,0xfd,0x7f,0x01,0x90,0x00,0x05,0x12,0x01,0xec,0x78,0x80,0xf6,0x78,0x82,0xe6,
+0xfd,0x08,0xe6,0xfc,0xed,0xfe,0xec,0xfd,0x7f,0x01,0x90,0x00,0x04,0x12,0x01,0xec,
+0x54,0x0f,0xfc,0x7d,0x80,0x12,0x17,0x46,0x78,0x80,0xe6,0x70,0x0d,0xad,0x3a,0xae,
+0x39,0xaf,0x38,0xe4,0x12,0x03,0x0f,0x7c,0x08,0x22,0x90,0xff,0xf0,0xe0,0x54,0xfe,
+0xf0,0x90,0xff,0xf0,0xe0,0x54,0xfd,0xf0,0x80,0x1e,0x78,0x82,0xe6,0xfd,0x08,0xe6,
+0xfc,0xed,0xfe,0xec,0xfd,0x7f,0x01,0x90,0x00,0x08,0x12,0x02,0x0e,0x25,0xe0,0x44,
+0x01,0x90,0xff,0xf3,0xf0,0x02,0x06,0xd0,0x78,0x82,0xe6,0xfd,0x08,0xe6,0xfc,0xed,
+0xfe,0xec,0xfd,0x7f,0x01,0x90,0x00,0x06,0x12,0x02,0x0e,0x54,0xfe,0x90,0xff,0xf3,
+0xf0,0x80,0x2b,0x78,0x82,0xe6,0xfd,0x08,0xe6,0xfc,0xed,0xfe,0xec,0xfd,0x7f,0x01,
+0x90,0x00,0x08,0x12,0x02,0x0e,0xfa,0xeb,0x90,0xff,0xf1,0xf0,0x12,0x08,0xbf,0x40,
+0x0d,0xad,0x3a,0xae,0x39,0xaf,0x38,0xe4,0x12,0x03,0x0f,0x7c,0x18,0x22,0x78,0x82,
+0xe6,0xfd,0x08,0xe6,0xfc,0xed,0xfe,0xec,0xfd,0x7f,0x01,0x90,0x00,0x08,0x12,0x02,
+0x0e,0x90,0xff,0xf1,0xf0,0x12,0x08,0xbf,0x40,0x0d,0xad,0x3a,0xae,0x39,0xaf,0x38,
+0xe4,0x12,0x03,0x0f,0x7c,0x18,0x22,0x78,0x82,0xe6,0xfd,0x08,0xe6,0xfc,0xed,0xfe,
+0xec,0xfd,0x7f,0x01,0x90,0x00,0x06,0x12,0x02,0x0e,0x44,0x01,0x90,0xff,0xf3,0xf0,
+0x78,0x83,0xe6,0x24,0x03,0xf6,0x18,0xe6,0x34,0x00,0xf6,0x78,0x80,0xe6,0x24,0xfe,
+0x50,0x09,0x90,0xff,0xf0,0xe0,0x54,0xfd,0xf0,0x80,0x07,0x90,0xff,0xf0,0xe0,0x44,
+0x02,0xf0,0xe4,0x90,0xff,0xf1,0xf0,0x78,0x81,0x76,0x00,0x78,0x80,0xe6,0x24,0xff,
+0xfc,0xe4,0x34,0xff,0xfd,0x78,0x81,0xe6,0x7f,0x00,0xfe,0xec,0xd3,0x9e,0xef,0x64,
+0x80,0xcd,0x64,0x80,0x9d,0x40,0x2f,0x12,0x08,0xa4,0x40,0x0f,0x78,0x81,0xe6,0xad,
+0x3a,0xae,0x39,0xaf,0x38,0x12,0x03,0x0f,0x7c,0x18,0x22,0x90,0xff,0xf2,0xe0,0xfc,
+0x78,0x82,0x86,0x83,0x08,0x86,0x82,0xec,0xf0,0x78,0x81,0x06,0xa3,0x78,0x82,0xa6,
+0x83,0x08,0xa6,0x82,0x80,0xb5,0x12,0x08,0xa4,0x40,0x0f,0x78,0x81,0xe6,0xad,0x3a,
+0xae,0x39,0xaf,0x38,0x12,0x03,0x0f,0x7c,0x18,0x22,0x90,0xff,0xf2,0xe0,0xfc,0x78,
+0x82,0x86,0x83,0x08,0x86,0x82,0xec,0xf0,0x78,0x80,0xe6,0xad,0x3a,0xae,0x39,0xaf,
+0x38,0x12,0x03,0x0f,0x7c,0x00,0x22,0x8c,0x37,0x8d,0x36,0x78,0x82,0xed,0xf6,0x08,
+0xec,0xf6,0xed,0xfe,0xec,0xfd,0x7f,0x01,0x90,0x00,0x05,0x12,0x01,0xec,0x78,0x81,
+0xf6,0x78,0x82,0xe6,0xfd,0x08,0xe6,0xfc,0xed,0xfe,0xec,0xfd,0x7f,0x01,0x90,0x00,
+0x04,0x12,0x01,0xec,0x54,0x0f,0xfc,0x7d,0x81,0x12,0x17,0x46,0x78,0x81,0xe6,0x70,
+0x03,0x7c,0x08,0x22,0x90,0xff,0xf0,0xe0,0x54,0xfe,0xf0,0x90,0xff,0xf0,0xe0,0x54,
+0xfd,0xf0,0x80,0x1b,0x78,0x82,0xe6,0xfd,0x08,0xe6,0xfc,0xed,0xfe,0xec,0xfd,0x7f,
+0x01,0x90,0x00,0x08,0x12,0x02,0x0e,0x25,0xe0,0x90,0xff,0xf3,0xf0,0x80,0x5b,0x78,
+0x82,0xe6,0xfd,0x08,0xe6,0xfc,0xed,0xfe,0xec,0xfd,0x7f,0x01,0x90,0x00,0x06,0x12,
+0x02,0x0e,0x54,0xfe,0x90,0xff,0xf3,0xf0,0x80,0x21,0x78,0x82,0xe6,0xfd,0x08,0xe6,
+0xfc,0xed,0xfe,0xec,0xfd,0x7f,0x01,0x90,0x00,0x08,0x12,0x02,0x0e,0xfa,0xeb,0x90,
+0xff,0xf1,0xf0,0x12,0x08,0xbf,0x40,0x03,0x7c,0x18,0x22,0x78,0x82,0xe6,0xfd,0x08,
+0xe6,0xfc,0xed,0xfe,0xec,0xfd,0x7f,0x01,0x90,0x00,0x08,0x12,0x02,0x0e,0x90,0xff,
+0xf1,0xf0,0x12,0x08,0xbf,0x40,0x03,0x7c,0x18,0x22,0x78,0x83,0xe6,0x24,0x0a,0xf6,
+0x18,0xe6,0x34,0x00,0xf6,0x78,0x80,0x76,0x00,0x78,0x81,0xe6,0x24,0xff,0xfc,0xe4,
+0x34,0xff,0xfd,0x78,0x80,0xe6,0x7f,0x00,0xfe,0xec,0xd3,0x9e,0xef,0x64,0x80,0xcd,
+0x64,0x80,0x9d,0x40,0x21,0x78,0x82,0x86,0x83,0x08,0x86,0x82,0xe0,0x90,0xff,0xf1,
+0xf0,0x12,0x08,0xbf,0x40,0x03,0x7c,0x18,0x22,0x78,0x80,0x06,0x78,0x83,0x06,0xe6,
+0x18,0x70,0x01,0x06,0x80,0xc3,0x90,0xff,0xf0,0xe0,0x44,0x01,0xf0,0x78,0x82,0x86,
+0x83,0x08,0x86,0x82,0xe0,0x90,0xff,0xf1,0xf0,0x12,0x08,0xbf,0x40,0x03,0x7c,0x18,
+0x22,0x7c,0x00,0x22,0x90,0xff,0xf0,0xe0,0x20,0xe7,0x12,0x90,0xff,0xf0,0xe0,0x30,
+0xe5,0x09,0x90,0xff,0xf0,0xe0,0x44,0x20,0xf0,0xc3,0x22,0x80,0xe7,0xd3,0x22,0x90,
+0xff,0xf0,0xe0,0x20,0xe3,0x12,0x90,0xff,0xf0,0xe0,0x30,0xe5,0x09,0x90,0xff,0xf0,
+0xe0,0x44,0x20,0xf0,0xc3,0x22,0x80,0xe7,0xd3,0x22,0x8c,0x42,0x8d,0x41,0x7c,0x00,
+0xed,0x54,0xf0,0xfd,0xec,0x70,0x03,0xed,0x64,0x30,0x70,0x05,0x75,0x3e,0x03,0x80,
+0x03,0x75,0x3e,0x04,0xac,0x3e,0x12,0x0f,0x69,0x75,0x83,0x00,0x85,0x83,0x40,0xe5,
+0x41,0x54,0x0f,0xf5,0x3f,0xe5,0x40,0x70,0x04,0xe5,0x3f,0x64,0x03,0x70,0x35,0xe5,
+0x3e,0x24,0xfd,0x75,0xf0,0x0a,0xa4,0x24,0x02,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,
+0xe0,0x30,0xe6,0x05,0x12,0x10,0x4b,0x80,0x19,0xe5,0x3e,0x24,0x9d,0xf8,0xc6,0x54,
+0xfb,0xf6,0x78,0xa9,0xe6,0x24,0x05,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0x74,
+0x0f,0xf0,0x80,0x59,0xe5,0x40,0x70,0x04,0xe5,0x3f,0x64,0x04,0x70,0x48,0xe5,0x3e,
+0x24,0xfd,0x75,0xf0,0x0a,0xa4,0x24,0x02,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0,
+0x30,0xe5,0x07,0xac,0x42,0xad,0x41,0x12,0x1c,0x3c,0xe5,0x42,0x30,0xe2,0x15,0x78,
+0xad,0xe6,0x30,0xe0,0x0f,0x78,0xad,0xe6,0x30,0xe1,0x09,0xe4,0xff,0x04,0xfe,0x7c,
+0x04,0x12,0x31,0xfb,0x78,0xa9,0xe6,0x24,0x06,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,
+0x83,0x74,0x0f,0xf0,0x80,0x07,0xe4,0xfc,0x7d,0xee,0x12,0x1c,0x3c,0xc2,0x03,0x22,
+0x12,0x30,0xe6,0x12,0x0f,0x69,0x78,0xa9,0xe6,0x24,0x06,0xf5,0x82,0x18,0xe6,0x34,
+0x00,0xf5,0x83,0xe0,0x90,0xfc,0x38,0xf0,0x78,0xa9,0xe6,0x24,0x05,0xf5,0x82,0x18,
+0xe6,0x34,0x00,0xf5,0x83,0xe0,0x90,0xfc,0x39,0xf0,0xc2,0x03,0x7d,0x02,0x7c,0x00,
+0x12,0x25,0x26,0x12,0x31,0x69,0x22,0x12,0x30,0xe6,0x78,0x95,0xec,0xf6,0xec,0x24,
+0x9d,0xf8,0xe6,0x30,0xe1,0x07,0x7c,0x13,0x12,0x25,0xbf,0x80,0x0f,0x90,0xfc,0x39,
+0xe0,0xfd,0x78,0x95,0xe6,0xfc,0x12,0x13,0xc8,0x12,0x25,0xbf,0x12,0x31,0x69,0x22,
+0x12,0x30,0xe6,0x78,0x95,0xec,0xf6,0x7d,0x00,0x12,0x0f,0x09,0x12,0x25,0xbf,0x12,
+0x31,0x69,0x22,0x12,0x30,0xe6,0x78,0x95,0xec,0xf6,0xec,0x24,0x9d,0xf8,0xe6,0x30,
+0xe2,0x07,0x7c,0x13,0x12,0x25,0xbf,0x80,0x1b,0x78,0x95,0xe6,0x24,0x9d,0xf8,0xe6,
+0x20,0xe1,0x07,0x7c,0x12,0x12,0x25,0xbf,0x80,0x0a,0x78,0x95,0xe6,0xfc,0x12,0x13,
+0xec,0x12,0x25,0xbf,0x12,0x31,0x69,0x22,0x12,0x30,0xe6,0x78,0x95,0xec,0xf6,0xec,
+0x24,0x9d,0xf8,0xe6,0x20,0xe2,0x07,0x7c,0x11,0x12,0x25,0xbf,0x80,0x0a,0x78,0x95,
+0xe6,0xfc,0x12,0x14,0xed,0x12,0x25,0xbf,0x12,0x31,0x69,0x22,0x12,0x30,0xe6,0x78,
+0x95,0xec,0xf6,0x12,0x0f,0x69,0x78,0xa9,0xe6,0x24,0x09,0xf5,0x82,0x18,0xe6,0x34,
+0x00,0xf5,0x83,0xe0,0x90,0xfc,0x3f,0xf0,0x78,0xa9,0xe6,0x24,0x0a,0xf5,0x82,0x18,
+0xe6,0x34,0x00,0xf5,0x83,0xe0,0x90,0xfc,0x40,0xf0,0x78,0xa9,0xe6,0x24,0x03,0xf5,
+0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0xfc,0x78,0xa9,0xe6,0x24,0x04,0xf5,0x82,
+0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0xf5,0x62,0x78,0xa9,0xe6,0x24,0x02,0xf5,0x82,
+0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0xf5,0x63,0x8c,0x61,0xe4,0xec,0x33,0x33,0x54,
+0x01,0x78,0x95,0xf6,0x60,0x08,0xe5,0x62,0x30,0xe1,0x03,0x78,0x95,0x06,0x78,0x95,
+0xe6,0x90,0xfc,0x41,0xf0,0x78,0xa7,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,
+0xf5,0x83,0xe0,0xfd,0xa3,0xe0,0x54,0x0c,0xfc,0xed,0x54,0xe6,0x8c,0x65,0xf5,0x64,
+0xe5,0x61,0x30,0xe5,0x03,0x43,0x65,0x01,0xe5,0x62,0x20,0xe5,0x0e,0xe5,0x61,0x54,
+0x7f,0x70,0x08,0xe5,0x61,0x20,0xe7,0x03,0x43,0x65,0x02,0xe5,0x61,0x30,0xe3,0x03,
+0x43,0x65,0x10,0xe5,0x61,0x30,0xe2,0x03,0x43,0x65,0x20,0xe5,0x61,0x54,0x03,0x60,
+0x03,0x43,0x65,0x40,0xe5,0x61,0x30,0xe1,0x03,0x43,0x65,0x80,0xe5,0x61,0x30,0xe4,
+0x03,0x43,0x64,0x01,0xe5,0x61,0x30,0xe6,0x03,0x43,0x64,0x08,0xe5,0x62,0x20,0xe4,
+0x0e,0xe5,0x61,0x54,0x7f,0x70,0x08,0xe5,0x61,0x20,0xe7,0x03,0x43,0x64,0x10,0x53,
+0x65,0xfb,0x53,0x64,0x79,0xad,0x64,0xe5,0x65,0x90,0xfc,0x3a,0xcd,0xf0,0xa3,0xcd,
+0xf0,0xe5,0x63,0x30,0xe3,0x0d,0xe5,0x63,0x54,0x30,0xc4,0x54,0x0f,0x90,0xfc,0x3d,
+0xf0,0x80,0x05,0xe4,0x90,0xfc,0x3d,0xf0,0xe5,0x63,0x54,0x03,0x90,0xfc,0x3c,0xf0,
+0xe5,0x63,0x54,0x04,0xc3,0x13,0x90,0xfc,0x3e,0xf0,0x90,0xfc,0x3c,0xe0,0x70,0x0e,
+0x7d,0x35,0x7e,0xfc,0x7f,0x01,0x74,0x01,0x90,0x00,0x09,0x12,0x01,0x42,0x78,0xa9,
+0xe6,0x24,0x08,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x7c,0x00,0xfd,0x78,
+0xa9,0xe6,0x24,0x07,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x7f,0x00,0x4c,
+0xfe,0xef,0x4d,0x90,0xfc,0x38,0xf0,0xa3,0xce,0xf0,0xce,0xc2,0x03,0x7d,0x0a,0x7c,
+0x00,0x12,0x25,0x26,0x12,0x31,0x69,0x22,0x12,0x30,0xe6,0x78,0x95,0xec,0xf6,0x78,
+0x9a,0x76,0x01,0x08,0x76,0xfc,0x08,0x76,0x38,0x78,0x97,0x76,0x0c,0x78,0x9a,0x12,
+0x04,0x65,0x12,0x02,0x14,0x78,0x98,0xcb,0xf6,0xcb,0x08,0xf6,0x7f,0x00,0xef,0x24,
+0xea,0x40,0x1f,0xe4,0xef,0x25,0xe0,0x90,0x35,0x2c,0xfd,0x93,0xcd,0x04,0x93,0x78,
+0x99,0x66,0x70,0x03,0xed,0x18,0x66,0x70,0x06,0x78,0x97,0x76,0x00,0x80,0x03,0x0f,
+0x80,0xdc,0x78,0x96,0xef,0xf6,0x78,0x9a,0x12,0x04,0x65,0x90,0x00,0x02,0x12,0x02,
+0x0e,0x78,0x98,0xcb,0xf6,0xcb,0x08,0xf6,0x54,0x04,0xcb,0x54,0x86,0x4b,0x60,0x04,
+0x78,0x97,0x76,0x0b,0x78,0x99,0xe6,0x30,0xe3,0x13,0x78,0x9a,0x12,0x04,0x65,0x90,
+0x00,0x05,0x12,0x01,0xec,0x24,0xfb,0x50,0x04,0x78,0x97,0x76,0x0d,0x78,0x99,0xe6,
+0x54,0xc0,0x7d,0x00,0x64,0xc0,0x4d,0x70,0x04,0x78,0x97,0x76,0x0b,0x78,0x9a,0x12,
+0x04,0x65,0x90,0x00,0x04,0x12,0x01,0xec,0x24,0xfc,0x50,0x04,0x78,0x97,0x76,0x0f,
+0x78,0x9a,0x12,0x04,0x65,0x90,0x00,0x06,0x12,0x01,0xec,0x24,0xfd,0x50,0x04,0x78,
+0x97,0x76,0x0e,0x78,0x9a,0x12,0x04,0x65,0x90,0x00,0x09,0x12,0x01,0xec,0x24,0xfd,
+0x50,0x04,0x78,0x97,0x76,0x0a,0x78,0x97,0xe6,0x70,0x2a,0x78,0x95,0xe6,0xfc,0x12,
+0x0f,0x69,0x78,0x9a,0x12,0x04,0x65,0x78,0xa7,0xe6,0xf9,0x78,0xa6,0xe6,0xfa,0x7b,
+0x01,0x74,0x0a,0x78,0x00,0x12,0x03,0x3f,0xc2,0x03,0x78,0x95,0xe6,0xfc,0x12,0x11,
+0x07,0x78,0x97,0xec,0xf6,0x78,0x97,0xe6,0xfc,0x12,0x25,0xbf,0x12,0x31,0x69,0x22,
+0x12,0x30,0xe6,0x78,0x95,0xec,0xf6,0x12,0x0f,0x69,0x78,0x95,0xe6,0x24,0xfd,0x75,
+0xf0,0x0a,0xa4,0x24,0x14,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xac,0x82,0xad,0x83,
+0x78,0xa6,0x86,0x83,0x08,0x86,0x82,0xec,0xf9,0xed,0xfa,0x7b,0x0a,0x78,0x01,0x12,
+0x03,0xa7,0xc2,0x03,0x78,0x95,0xe6,0xfc,0x12,0x11,0x07,0x12,0x31,0x69,0x22,0x8d,
+0x2b,0x8c,0x2a,0xed,0x60,0x40,0x75,0x27,0x01,0x75,0x29,0x48,0x75,0x28,0xff,0xe5,
+0x2a,0x24,0xfd,0xfc,0xe4,0x34,0xff,0xfd,0xec,0x7c,0x03,0x25,0xe0,0xcd,0x33,0xcd,
+0xdc,0xf9,0xfc,0xe5,0x29,0x2c,0xf5,0x29,0xe5,0x28,0x3d,0xf5,0x28,0xad,0x29,0xae,
+0x28,0xaf,0x27,0x74,0x80,0x90,0x00,0x06,0x12,0x03,0x17,0x74,0x80,0x90,0x00,0x02,
+0x12,0x03,0x17,0x12,0x0f,0xb7,0xe5,0x2b,0x14,0x60,0x3b,0x75,0x27,0x01,0x75,0x29,
+0x08,0x75,0x28,0xff,0xe5,0x2a,0x24,0xfd,0xfc,0xe4,0x34,0xff,0xfd,0xec,0x7c,0x03,
+0x25,0xe0,0xcd,0x33,0xcd,0xdc,0xf9,0xfc,0xe5,0x29,0x2c,0xf5,0x29,0xe5,0x28,0x3d,
+0xf5,0x28,0xad,0x29,0xae,0x28,0xaf,0x27,0xe4,0x90,0x00,0x06,0x12,0x03,0x17,0xe4,
+0x90,0x00,0x02,0x12,0x03,0x17,0x22,0x12,0x30,0xe6,0x78,0x95,0xec,0xf6,0xec,0x24,
+0x9d,0xf8,0xe6,0x30,0xe2,0x09,0x78,0x95,0xe6,0xfc,0x12,0x14,0xed,0xd2,0x00,0x78,
+0x95,0xe6,0xfc,0x12,0x0f,0x69,0x78,0x96,0x76,0x00,0x90,0xfc,0x39,0xe0,0x30,0xe7,
+0x04,0x78,0x96,0x76,0x01,0x78,0x96,0xe6,0xfd,0x78,0x95,0xe6,0xfc,0x12,0x0d,0x2f,
+0xc2,0x03,0x30,0x00,0x07,0x78,0x95,0xe6,0xfc,0x12,0x13,0xec,0x7c,0x00,0x12,0x25,
+0xbf,0x12,0x31,0x69,0x22,0x78,0xa9,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,
+0xf5,0x83,0xe0,0x44,0x01,0xf0,0x78,0xa9,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,
+0x00,0xf5,0x83,0xe0,0x30,0xe0,0x02,0x80,0xed,0x78,0xa9,0xe6,0x24,0x0b,0xf5,0x82,
+0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x54,0xf8,0xf0,0x78,0xa9,0xe6,0x24,0x02,0xf5,
+0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x44,0x80,0xf0,0x22,0xc2,0x03,0x8c,0x58,
+0x12,0x0f,0x69,0x78,0xa6,0x86,0x83,0x08,0x86,0x82,0x79,0x5d,0x7a,0x35,0x7b,0x0a,
+0x78,0x01,0x12,0x03,0xf5,0x12,0x0e,0x05,0xac,0x58,0x7d,0x02,0x12,0x0d,0x2f,0xc2,
+0x03,0xac,0x58,0x12,0x11,0x07,0x22,0x8d,0x53,0x8e,0x52,0x8f,0x51,0x8c,0x50,0x12,
+0x0f,0x69,0x75,0x4f,0x00,0x78,0xa9,0xe6,0x24,0x05,0xf5,0x82,0x18,0xe6,0x34,0x00,
+0xf5,0x83,0xe0,0x20,0xe4,0x1f,0xe5,0x4f,0x24,0xf6,0x40,0x19,0x05,0x4f,0xc2,0x03,
+0x7c,0x18,0x12,0x32,0xa9,0x90,0xff,0x93,0xe0,0x44,0x01,0xf0,0xb2,0xb3,0xac,0x50,
+0x12,0x0f,0x69,0x80,0xd0,0x78,0xa9,0xe6,0x24,0x05,0xf5,0x82,0x18,0xe6,0x34,0x00,
+0xf5,0x83,0xe0,0x20,0xe4,0x05,0xc2,0x03,0x7c,0x02,0x22,0x78,0xa9,0xe6,0x24,0x05,
+0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x54,0x0f,0x60,0x16,0x78,0xa9,0xe6,
+0x24,0x05,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x54,0x0f,0xf0,0xc2,0x03,
+0x7c,0x01,0x22,0x78,0xa8,0x86,0x83,0x08,0x86,0x82,0xe0,0xad,0x53,0xae,0x52,0xaf,
+0x51,0x12,0x03,0x0f,0xc2,0x03,0x7c,0x00,0x22,0x8d,0x31,0x8c,0x30,0x12,0x14,0xed,
+0xe5,0x31,0x60,0x0f,0xe5,0x30,0xb4,0x03,0x0a,0x7c,0x01,0x12,0x24,0xee,0x7c,0x81,
+0x12,0x24,0xee,0xac,0x30,0x12,0x0f,0x69,0xe5,0x31,0x60,0x1a,0x78,0xaa,0x86,0x83,
+0x08,0x86,0x82,0xe0,0x54,0xe7,0xf0,0xa3,0xa3,0xa3,0xa3,0xe0,0x54,0xe7,0xf0,0xac,
+0x30,0x7d,0x02,0x12,0x0d,0x2f,0x78,0xa6,0x86,0x83,0x08,0x86,0x82,0x79,0x67,0x7a,
+0x35,0x7b,0x0a,0x78,0x01,0x12,0x03,0xf5,0xc2,0x03,0xe5,0x30,0x24,0x9d,0xf8,0xc6,
+0x54,0xfd,0xf6,0xac,0x30,0x12,0x11,0x07,0x22,0x8c,0x26,0x30,0x03,0x05,0x12,0x32,
+0x48,0x80,0xf8,0x7c,0x0a,0x12,0x31,0x5b,0xd2,0x03,0xe5,0x26,0x24,0xfd,0x78,0xa3,
+0xf6,0x70,0x07,0x78,0xaa,0x76,0xff,0x08,0x76,0xe0,0x78,0xa3,0xe6,0x75,0xf0,0x10,
+0xa4,0xad,0xf0,0xfc,0x24,0xa0,0x78,0xa9,0xf6,0xed,0x34,0xff,0x18,0xf6,0x78,0xa3,
+0xe6,0x75,0xf0,0x0a,0xa4,0x24,0x00,0xfc,0xe4,0x34,0xfc,0xfd,0x78,0xa6,0xed,0xf6,
+0x08,0xec,0xf6,0x12,0x31,0xf4,0x22,0x78,0xa9,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,
+0x34,0x00,0xf5,0x83,0xe0,0x30,0xe7,0x22,0x78,0xa9,0xe6,0x24,0x02,0xf5,0x82,0x18,
+0xe6,0x34,0x00,0xf5,0x83,0xe0,0x54,0x7f,0xf0,0x78,0xa9,0xe6,0x24,0x02,0xf5,0x82,
+0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x44,0x80,0xf0,0x22,0x78,0xaa,0x86,0x83,0x08,
+0x86,0x82,0xe0,0x54,0x7f,0xf0,0xad,0x83,0xe5,0x82,0x24,0x04,0xfc,0xe4,0x3d,0x8c,
+0x82,0xf5,0x83,0xe0,0x54,0x7f,0xf0,0x78,0xa9,0xe6,0x24,0x0b,0xf5,0x82,0x18,0xe6,
+0x34,0x00,0xf5,0x83,0xe0,0x54,0xf8,0xf0,0x78,0xab,0xe6,0x24,0x01,0xf5,0x82,0x18,
+0xe6,0x34,0x00,0xf5,0x83,0xe0,0x44,0x03,0xf0,0x78,0xab,0xe6,0x24,0x05,0xf5,0x82,
+0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x44,0x03,0xf0,0x78,0xa9,0xe6,0x24,0x05,0xf5,
+0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0x74,0x0f,0xf0,0x22,0x78,0xaa,0x86,0x83,0x08,
+0x86,0x82,0xe0,0x54,0x3f,0xf0,0xad,0x83,0xe5,0x82,0x24,0x04,0xfc,0xe4,0x3d,0x8c,
+0x82,0xf5,0x83,0xe0,0x54,0x3f,0xf0,0x78,0xa3,0xe6,0x24,0xa4,0xf8,0xe6,0xfc,0x78,
+0xab,0xe6,0x24,0x01,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xec,0xf0,0x78,0xa3,
+0xe6,0x24,0xa4,0xf8,0xe6,0xfc,0x78,0xab,0xe6,0x24,0x05,0xf5,0x82,0x18,0xe6,0x34,
+0x00,0xf5,0x83,0xec,0xf0,0x78,0xa9,0xe6,0x24,0x0b,0xf5,0x82,0x18,0xe6,0x34,0x00,
+0xf5,0x83,0xe0,0x54,0xfb,0x44,0x02,0xf5,0x26,0x78,0xa7,0xe6,0x24,0x02,0xf5,0x82,
+0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x30,0xe5,0x03,0x43,0x26,0x01,0x78,0xa9,0xe6,
+0x24,0x05,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x30,0xe0,0x03,0x12,0x0f,
+0xb7,0xe5,0x26,0xfc,0x78,0xa9,0xe6,0x24,0x0b,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,
+0x83,0xec,0xf0,0x78,0xa9,0xe6,0x24,0x05,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,
+0x74,0x0f,0xf0,0x78,0xaa,0x86,0x83,0x08,0x86,0x82,0xe0,0x44,0x80,0xf0,0xa3,0xa3,
+0xa3,0xa3,0xe0,0x44,0x80,0xf0,0x22,0x8c,0x2a,0x12,0x0f,0x69,0x78,0xa7,0xe6,0x24,
+0x08,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0xfc,0x78,0xa9,0xe6,0x24,0x0a,
+0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xec,0xf0,0x78,0xa7,0xe6,0x24,0x07,0xf5,
+0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0xfc,0x78,0xa9,0xe6,0x24,0x09,0xf5,0x82,
+0x18,0xe6,0x34,0x00,0xf5,0x83,0xec,0xf0,0x78,0xa6,0x86,0x83,0x08,0x86,0x82,0xe0,
+0xfd,0xa3,0xe0,0xfc,0xed,0xfe,0x78,0xa9,0xe6,0x24,0x08,0xf5,0x82,0x18,0xe6,0x34,
+0x00,0xf5,0x83,0xee,0xf0,0xec,0xfe,0x78,0xa9,0xe6,0x24,0x07,0xf5,0x82,0x18,0xe6,
+0x34,0x00,0xf5,0x83,0xee,0xf0,0x8c,0x29,0x8d,0x28,0xc3,0xec,0x94,0x05,0xed,0x94,
+0x0c,0x40,0x05,0x75,0x27,0x7c,0x80,0x33,0xd3,0xe5,0x29,0x94,0x01,0xe5,0x28,0x94,
+0x03,0x40,0x05,0x75,0x27,0x3c,0x80,0x23,0xd3,0xe5,0x29,0x94,0x81,0xe5,0x28,0x94,
+0x01,0x40,0x05,0x75,0x27,0x18,0x80,0x13,0xd3,0xe5,0x29,0x94,0x60,0xe5,0x28,0x94,
+0x00,0x40,0x05,0x75,0x27,0x0c,0x80,0x03,0x75,0x27,0x08,0xaf,0x27,0xe4,0xef,0x54,
+0x7c,0x44,0x83,0xff,0x8f,0x27,0xe5,0x27,0xfc,0x78,0xab,0xe6,0x24,0x01,0xf5,0x82,
+0x18,0xe6,0x34,0x00,0xf5,0x83,0xec,0xf0,0xe5,0x27,0xfc,0x78,0xab,0xe6,0x24,0x05,
+0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xec,0xf0,0xe5,0x27,0xfc,0x78,0xa3,0xe6,
+0x24,0xa4,0xf8,0xec,0xf6,0x78,0xa9,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,
+0xf5,0x83,0xe0,0xf5,0x27,0x78,0xa7,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,
+0xf5,0x83,0xa3,0xe0,0x30,0xe3,0x17,0x53,0x27,0xc7,0x78,0xa7,0xe6,0x24,0x05,0xf5,
+0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x90,0x35,0x58,0x93,0x42,0x27,0x53,0x27,
+0xfb,0x78,0xa7,0xe6,0x24,0x06,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x60,
+0x03,0x43,0x27,0x04,0x53,0x27,0xfc,0x78,0xa7,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,
+0x34,0x00,0xf5,0x83,0xe0,0x42,0x27,0x43,0x27,0x80,0xe5,0x27,0xfc,0x78,0xa9,0xe6,
+0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xec,0xf0,0x78,0xa9,0xe6,0x24,
+0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0xf5,0x27,0x78,0xa7,0xe6,0x24,
+0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xa3,0xe0,0x30,0xe1,0x05,0x53,0x27,
+0xdf,0x80,0x03,0x43,0x27,0x20,0x78,0xa7,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,
+0x00,0xf5,0x83,0xe0,0x30,0xe4,0x05,0x53,0x27,0xef,0x80,0x03,0x43,0x27,0x10,0x78,
+0xa7,0xe6,0x24,0x09,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0xb4,0x02,0x03,
+0x43,0x27,0x02,0xe5,0x27,0xfc,0x78,0xa9,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,
+0x00,0xf5,0x83,0xec,0xf0,0x78,0xa9,0xe6,0x24,0x03,0xf5,0x82,0x18,0xe6,0x34,0x00,
+0xf5,0x83,0xe0,0xf5,0x27,0x78,0xa7,0xe6,0x24,0x09,0xf5,0x82,0x18,0xe6,0x34,0x00,
+0xf5,0x83,0xe0,0x70,0x05,0x53,0x27,0x7f,0x80,0x03,0x43,0x27,0x80,0x78,0xa7,0xe6,
+0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xa3,0xe0,0x30,0xe0,0x05,0x43,
+0x27,0x20,0x80,0x03,0x53,0x27,0xdf,0x78,0xa7,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,
+0x34,0x00,0xf5,0x83,0xe0,0x30,0xe3,0x05,0x43,0x27,0x40,0x80,0x03,0x53,0x27,0xbf,
+0x78,0xa7,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x30,0xe0,
+0x05,0x43,0x27,0x10,0x80,0x03,0x53,0x27,0xef,0x78,0xa7,0xe6,0x24,0x02,0xf5,0x82,
+0x18,0xe6,0x34,0x00,0xf5,0x83,0xa3,0xe0,0x30,0xe4,0x05,0x43,0x27,0x08,0x80,0x03,
+0x53,0x27,0xf7,0x78,0xa7,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,
+0xa3,0xe0,0x30,0xe5,0x05,0x43,0x27,0x04,0x80,0x03,0x53,0x27,0xfb,0x78,0xa7,0xe6,
+0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xa3,0xe0,0x30,0xe6,0x05,0x43,
+0x27,0x01,0x80,0x03,0x53,0x27,0xfe,0x78,0xa7,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,
+0x34,0x00,0xf5,0x83,0xa3,0xe0,0x30,0xe7,0x05,0x43,0x27,0x02,0x80,0x03,0x53,0x27,
+0xfd,0xe5,0x27,0xfc,0x78,0xa9,0xe6,0x24,0x03,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,
+0x83,0xec,0xf0,0xc2,0x03,0x7c,0x00,0x22,0x8d,0x27,0x8c,0x26,0xed,0x54,0x03,0x14,
+0x60,0x03,0x7c,0x10,0x22,0xe5,0x27,0x54,0x7c,0x24,0xfc,0x40,0x03,0x7c,0x0b,0x22,
+0xe5,0x26,0x24,0x9d,0xf8,0xc6,0x44,0x02,0xf6,0x7c,0x00,0x22,0x8c,0x30,0x12,0x0f,
+0x69,0xe5,0x30,0x24,0x9d,0xf8,0xe6,0x20,0xe2,0x4f,0xac,0x30,0x7d,0x02,0x12,0x0d,
+0x2f,0xe5,0x30,0x24,0xfe,0x44,0x28,0xfc,0x78,0xaa,0x86,0x83,0x08,0x86,0x82,0xec,
+0xf0,0xaf,0x83,0xe5,0x82,0x24,0x04,0xfe,0xe4,0x3f,0xff,0xec,0x8e,0x82,0x8f,0x83,
+0xf0,0x7c,0x03,0x8c,0x2c,0xe5,0x2c,0xfc,0x78,0xab,0xe6,0x24,0x01,0xf5,0x82,0x18,
+0xe6,0x34,0x00,0xf5,0x83,0xec,0xf0,0xe5,0x2c,0xfc,0x78,0xab,0xe6,0x24,0x05,0xf5,
+0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xec,0xf0,0x75,0x2d,0x01,0x75,0x2f,0x48,0x75,
+0x2e,0xff,0xe5,0x30,0x24,0xfd,0xfc,0xe4,0x34,0xff,0xfd,0xec,0x7c,0x03,0x25,0xe0,
+0xcd,0x33,0xcd,0xdc,0xf9,0xfc,0xe5,0x2f,0x2c,0xf5,0x2f,0xe5,0x2e,0x3d,0xf5,0x2e,
+0x78,0xab,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x54,0xe7,
+0xf5,0x2c,0xad,0x2f,0xae,0x2e,0xaf,0x2d,0xe4,0x90,0x00,0x02,0x12,0x03,0x17,0xe4,
+0x90,0x00,0x06,0x12,0x03,0x17,0x12,0x01,0xe6,0x30,0xe5,0x03,0x43,0x2c,0x10,0xe5,
+0x2c,0xfc,0x78,0xab,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xec,
+0xf0,0x12,0x10,0x4b,0x78,0xa9,0xe6,0x24,0x06,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,
+0x83,0xe0,0xc2,0x03,0xfc,0xe5,0x30,0x24,0x9d,0xf8,0xc6,0x44,0x04,0xf6,0x8c,0x2c,
+0xe5,0x30,0x54,0x0f,0xc4,0x54,0xf0,0x7e,0x00,0xff,0xee,0xef,0x44,0x04,0x7d,0x00,
+0xff,0xec,0x4e,0xfc,0xed,0x4f,0xfd,0x12,0x1c,0xa7,0x7c,0x00,0x22,0x8c,0x2f,0x12,
+0x0f,0x69,0x12,0x0f,0xeb,0x78,0xaa,0x86,0x83,0x08,0x86,0x82,0xe0,0x54,0x08,0xf0,
+0xa3,0xa3,0xa3,0xa3,0xe0,0x54,0x08,0xf0,0xac,0x2f,0x7d,0x02,0x12,0x0d,0x2f,0xc2,
+0x03,0xe5,0x2f,0x24,0x9d,0xf8,0xc6,0x54,0xfb,0xf6,0x7c,0x00,0x22,0x12,0x30,0xe6,
+0x78,0x96,0xec,0xf6,0xec,0x24,0x9d,0xf8,0xe6,0x30,0xe1,0x0a,0x7d,0x00,0x7c,0x13,
+0x12,0x25,0x26,0x12,0x31,0x69,0x78,0x96,0xe6,0x24,0x9d,0xf8,0xc6,0x44,0x01,0xf6,
+0x78,0x96,0xe6,0xfc,0x12,0x0f,0x69,0x78,0x96,0xe6,0x24,0xfd,0x75,0xf0,0x0a,0xa4,
+0x24,0x14,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0x78,0xa6,0xe6,0xfa,0x08,0xe6,0xf9,
+0x7b,0x0a,0x78,0x01,0x12,0x03,0xa7,0x78,0xa6,0x86,0x83,0x08,0x86,0x82,0x79,0x67,
+0x7a,0x35,0x7b,0x0a,0x78,0x01,0x12,0x03,0xf5,0x12,0x0f,0xb7,0xc2,0x03,0x78,0x96,
+0xe6,0xfc,0x12,0x11,0x07,0x78,0x95,0xec,0xf6,0xec,0x60,0x0a,0x7d,0x00,0x7c,0x08,
+0x12,0x25,0x26,0x12,0x31,0x69,0x78,0x96,0xe6,0xfc,0x12,0x0f,0x69,0x78,0xa9,0xe6,
+0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x44,0x10,0x54,0xdf,0xfc,
+0x78,0xa9,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xec,0xf0,0x78,
+0x95,0xec,0xf6,0xc2,0x03,0x7c,0xc8,0x12,0x32,0xa9,0x78,0x96,0xe6,0xfc,0x12,0x0f,
+0x69,0x78,0xa9,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x54,
+0xef,0xf0,0xc2,0x03,0x7c,0xc8,0x12,0x32,0xa9,0x78,0x96,0xe6,0xfc,0x12,0x0f,0x69,
+0x78,0xa9,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x44,0x10,
+0xf0,0xc2,0x03,0x7c,0xc8,0x12,0x32,0xa9,0x78,0x96,0xe6,0xfc,0x12,0x0f,0x69,0x78,
+0xa9,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x44,0x20,0xf0,
+0xc2,0x03,0x7c,0xf0,0x12,0x32,0xa9,0x78,0x96,0xe6,0xfc,0x12,0x0f,0x69,0x78,0xa9,
+0xe6,0x24,0x05,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x30,0xe4,0x15,0xc2,
+0x03,0x78,0x96,0xe6,0x44,0x10,0x7f,0x00,0xfe,0x7c,0x07,0x12,0x31,0xfb,0x12,0x31,
+0x69,0x02,0x17,0x14,0x78,0xa9,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,
+0x83,0xe0,0x54,0xcf,0xf0,0xc2,0x03,0x7c,0xc8,0x12,0x32,0xa9,0x78,0x96,0xe6,0xfc,
+0x12,0x0f,0x69,0x78,0xa9,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,
+0xe0,0x44,0x30,0xf0,0xc2,0x03,0x7c,0xf0,0x12,0x32,0xa9,0x78,0x96,0xe6,0xfc,0x12,
+0x0f,0x69,0x78,0xa9,0xe6,0x24,0x05,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,
+0x30,0xe4,0x14,0xc2,0x03,0x78,0x96,0xe6,0x44,0x10,0x7f,0x00,0xfe,0x7c,0x07,0x12,
+0x31,0xfb,0x12,0x31,0x69,0x80,0x5d,0x78,0xa9,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,
+0x34,0x00,0xf5,0x83,0xe0,0x54,0xef,0xf0,0x78,0xa9,0xe6,0x24,0x04,0xf5,0x82,0x18,
+0xe6,0x34,0x00,0xf5,0x83,0xe0,0x54,0xdf,0xf0,0x78,0x96,0xe6,0x24,0xfd,0x75,0xf0,
+0x0a,0xa4,0x24,0x14,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xac,0x82,0xad,0x83,0x78,
+0xa6,0x86,0x83,0x08,0x86,0x82,0xec,0xf9,0xed,0xfa,0x7b,0x0a,0x78,0x01,0x12,0x03,
+0xa7,0xc2,0x03,0x78,0x96,0xe6,0xfc,0x12,0x11,0x07,0x7d,0x00,0x7c,0x0b,0x12,0x25,
+0x26,0x12,0x31,0x69,0x22,0x12,0x30,0xe6,0xe4,0x90,0xfc,0x39,0xf0,0x7d,0x02,0x7c,
+0x00,0x12,0x25,0x26,0x12,0x31,0x69,0x22,0x12,0x30,0xe6,0x7c,0x00,0x12,0x25,0xbf,
+0x12,0x31,0x69,0x22,0x74,0x3c,0x90,0xfb,0xe0,0xf0,0x74,0x3e,0x90,0xfb,0xe0,0xf0,
+0xe4,0x90,0xfc,0x28,0xf0,0x22,0x8d,0x35,0x8c,0x34,0xec,0xb4,0x01,0x02,0x80,0x03,
+0xd3,0x40,0x02,0x80,0x28,0xb4,0x02,0x02,0x80,0x03,0xd3,0x40,0x08,0xa8,0x35,0xc6,
+0x25,0xe0,0xf6,0x80,0x18,0xb4,0x04,0x02,0x80,0x03,0xd3,0x40,0x0a,0xa8,0x35,0xc6,
+0x25,0xe0,0x25,0xe0,0xf6,0x80,0x06,0xa8,0x35,0x76,0x00,0x80,0x00,0x22,0x8c,0x3c,
+0x8d,0x3b,0xed,0xfe,0xec,0xfd,0x7f,0x01,0x75,0x66,0x06,0x75,0x67,0x00,0x90,0xfc,
+0x29,0x12,0x04,0x6e,0x12,0x01,0xe6,0xb4,0x80,0x02,0x80,0x06,0xd3,0x50,0x03,0x02,
+0x18,0x47,0x90,0xfc,0x29,0x12,0x04,0x80,0x90,0x00,0x03,0x12,0x01,0xec,0x54,0xf0,
+0xb4,0x30,0x02,0x80,0x03,0xd3,0x40,0x5f,0x90,0xfc,0x29,0x12,0x04,0x80,0x90,0x00,
+0x08,0x12,0x02,0x0e,0xfa,0xfd,0xeb,0xfe,0x7f,0x01,0x90,0xfc,0x2c,0x12,0x04,0x6e,
+0xee,0xcd,0x90,0x35,0x71,0xfc,0xe4,0x93,0xff,0x74,0x01,0x93,0xfe,0xf9,0xef,0xfa,
+0x7b,0x01,0xea,0xff,0xe9,0xfe,0xec,0xc3,0x9e,0xed,0x9f,0x40,0x25,0x90,0x35,0x73,
+0xe4,0x93,0xfd,0x74,0x01,0x93,0xfc,0xed,0xfe,0xec,0xfd,0x7f,0x01,0xee,0xcd,0xfc,
+0x90,0xfc,0x2e,0xe0,0xd3,0x9c,0x90,0xfc,0x2d,0xe0,0x9d,0x50,0x05,0x75,0x66,0x80,
+0x80,0x33,0x12,0x19,0x65,0x80,0x2e,0xb4,0x60,0x02,0x80,0x03,0xd3,0x40,0x0b,0xac,
+0x3c,0xad,0x3b,0x12,0x07,0x77,0x8c,0x66,0x80,0x1b,0xb4,0x10,0x03,0xb3,0x40,0x10,
+0xc3,0xb4,0x20,0x03,0xb3,0x40,0x09,0xc3,0xb4,0x40,0x02,0x80,0x03,0xd3,0x40,0x00,
+0x75,0x66,0x81,0x80,0x00,0x80,0x75,0xb4,0x81,0x02,0x80,0x03,0xd3,0x40,0x6b,0x90,
+0xfc,0x29,0x12,0x04,0x80,0x90,0x00,0x03,0x12,0x01,0xec,0x54,0xf0,0xb4,0x30,0x02,
+0x80,0x03,0xd3,0x40,0x1d,0x90,0xfc,0x29,0x12,0x04,0x80,0x90,0x00,0x08,0x12,0x02,
+0x0e,0xfa,0xfd,0xeb,0xfe,0x7f,0x01,0x90,0xfc,0x2f,0x12,0x04,0x6e,0x12,0x18,0xcf,
+0x80,0x36,0xb4,0x60,0x02,0x80,0x03,0xd3,0x40,0x13,0x75,0x3a,0x67,0xe4,0xf5,0x39,
+0xf5,0x38,0xac,0x3c,0xad,0x3b,0x12,0x05,0xd3,0x8c,0x66,0x80,0x1b,0xb4,0x10,0x03,
+0xb3,0x40,0x10,0xc3,0xb4,0x20,0x03,0xb3,0x40,0x09,0xc3,0xb4,0x40,0x02,0x80,0x03,
+0xd3,0x40,0x00,0x75,0x66,0x81,0x80,0x00,0x80,0x02,0x80,0x00,0xe5,0x66,0xfc,0x90,
+0xfc,0x29,0x12,0x04,0x80,0xec,0x90,0x00,0x02,0x12,0x03,0x17,0xac,0x67,0x22,0x90,
+0xfc,0x29,0x12,0x04,0x80,0x90,0x00,0x04,0x12,0x01,0xec,0x60,0x04,0x74,0x01,0x80,
+0x01,0xe4,0xa2,0xe0,0x92,0x01,0x90,0xfc,0x29,0x12,0x04,0x80,0xed,0x24,0x03,0xfd,
+0x50,0x01,0x0e,0x90,0xfc,0x2c,0x12,0x04,0x6e,0x90,0xfc,0x29,0x12,0x04,0x80,0x90,
+0x00,0x05,0x12,0x01,0xec,0xf5,0x67,0x90,0x00,0x04,0x12,0x01,0xec,0x54,0x0f,0xfc,
+0x7d,0x67,0x12,0x17,0x46,0xe5,0x67,0x70,0x04,0x75,0x66,0x08,0x22,0x75,0x66,0x00,
+0x78,0x84,0x76,0x00,0x78,0x84,0xe6,0xc3,0x95,0x67,0x50,0x38,0x90,0xfc,0x2f,0x12,
+0x04,0x80,0x12,0x01,0xe6,0xfc,0x90,0xfc,0x2c,0x12,0x04,0x80,0xec,0x12,0x03,0x0f,
+0x30,0x01,0x0e,0x90,0xfc,0x31,0xe0,0x04,0xf0,0x90,0xfc,0x30,0x70,0x03,0xe0,0x04,
+0xf0,0x78,0x84,0x06,0x90,0xfc,0x2e,0xe0,0x04,0xf0,0x90,0xfc,0x2d,0x70,0x03,0xe0,
+0x04,0xf0,0x80,0xc0,0x22,0x90,0xfc,0x2a,0xe0,0xfd,0xa3,0xe0,0xfc,0xed,0xfe,0xec,
+0xfd,0x7f,0x01,0xed,0x24,0x0a,0xfd,0x50,0x01,0x0e,0x90,0xfc,0x32,0x12,0x04,0x6e,
+0x90,0xfc,0x29,0x12,0x04,0x80,0x90,0x00,0x04,0x12,0x01,0xec,0x54,0x0f,0xb4,0x01,
+0x02,0x80,0x03,0xd3,0x40,0x17,0x90,0xfc,0x32,0x12,0x04,0x80,0x0d,0xed,0x70,0x01,
+0x0e,0x90,0xfc,0x2f,0x12,0x04,0x6e,0x78,0x88,0x76,0x01,0x80,0x4e,0xb4,0x02,0x02,
+0x80,0x03,0xd3,0x40,0x19,0x90,0xfc,0x32,0x12,0x04,0x80,0xed,0x24,0x02,0xfd,0x50,
+0x01,0x0e,0x90,0xfc,0x2f,0x12,0x04,0x6e,0x78,0x88,0x76,0x02,0x80,0x2d,0xb4,0x04,
+0x02,0x80,0x03,0xd3,0x40,0x19,0x90,0xfc,0x32,0x12,0x04,0x80,0xed,0x24,0x04,0xfd,
+0x50,0x01,0x0e,0x90,0xfc,0x2f,0x12,0x04,0x6e,0x78,0x88,0x76,0x04,0x80,0x0c,0xb4,
+0x00,0x02,0x80,0x03,0xd3,0x40,0x00,0x75,0x66,0x08,0x22,0x90,0xfc,0x29,0x12,0x04,
+0x80,0x90,0x00,0x05,0x12,0x01,0xec,0xf5,0x67,0x78,0x85,0x76,0x00,0x78,0x85,0xe6,
+0xc3,0x95,0x67,0x40,0x03,0x02,0x1a,0xcd,0x78,0x86,0x76,0x00,0x78,0x86,0xe6,0xc3,
+0x78,0x88,0x96,0x50,0x76,0x90,0xfc,0x2c,0x12,0x04,0x80,0x12,0x01,0xe6,0xfc,0x90,
+0xfc,0x32,0x12,0x04,0x89,0x12,0x01,0xe0,0xf4,0x5c,0xfc,0x12,0x01,0xe0,0xf8,0x90,
+0xfc,0x2f,0x12,0x04,0x80,0xe8,0xc0,0xe0,0x12,0x01,0xe6,0xc8,0xd0,0xe0,0xc8,0x58,
+0x4c,0xfc,0x90,0xfc,0x2c,0x12,0x04,0x80,0xec,0x12,0x03,0x0f,0x78,0x87,0xec,0xf6,
+0x90,0xfc,0x31,0xe0,0x04,0xf0,0x90,0xfc,0x30,0x70,0x03,0xe0,0x04,0xf0,0x09,0xe9,
+0x70,0x01,0x0a,0x90,0xfc,0x32,0x12,0x04,0x77,0x90,0xfc,0x29,0x12,0x04,0x80,0x90,
+0x00,0x04,0x12,0x01,0xec,0x30,0xe4,0x0e,0x90,0xfc,0x2e,0xe0,0x04,0xf0,0x90,0xfc,
+0x2d,0x70,0x03,0xe0,0x04,0xf0,0x78,0x86,0x06,0x80,0x81,0x78,0x88,0xe6,0xfd,0xe4,
+0xfe,0xff,0xee,0xcd,0xfc,0x90,0xfc,0x31,0xe0,0x2c,0xf0,0x90,0xfc,0x30,0xe0,0x3d,
+0xf0,0x78,0x88,0xe6,0xfd,0xe4,0xfe,0xff,0xee,0xcd,0xfc,0x90,0xfc,0x34,0xe0,0x2c,
+0xf0,0x90,0xfc,0x33,0xe0,0x3d,0xf0,0x78,0x85,0x06,0x02,0x1a,0x0d,0x75,0x66,0x00,
+0x22,0xe5,0x3d,0x05,0x3d,0x04,0x70,0x02,0xb2,0xb0,0x22,0xc0,0xe0,0xc0,0xf0,0xc0,
+0x82,0xc0,0x83,0xc0,0xd0,0xe8,0xc0,0xe0,0xe9,0xc0,0xe0,0xea,0xc0,0xe0,0xeb,0xc0,
+0xe0,0xec,0xc0,0xe0,0xed,0xc0,0xe0,0xee,0xc0,0xe0,0xef,0xc0,0xe0,0x90,0xff,0x92,
+0xe0,0x12,0x01,0xb7,0x1b,0x29,0x30,0x1b,0x29,0x32,0x1b,0x38,0x38,0x1b,0x4a,0x3a,
+0x1b,0x5c,0x3e,0x1b,0x74,0x44,0x1b,0x68,0x46,0x1b,0x80,0x50,0x1b,0xc2,0x52,0x1b,
+0xa1,0x54,0x1b,0xe3,0x56,0x00,0x00,0x1c,0x04,0x90,0xff,0x92,0xe0,0x7f,0x00,0xfe,
+0x7c,0x01,0x12,0x31,0xfb,0x02,0x1c,0x14,0xe4,0xff,0x04,0xfe,0x7c,0x03,0x12,0x31,
+0xfb,0x74,0x20,0x90,0xff,0xfe,0xf0,0x02,0x1c,0x14,0xe4,0xff,0x04,0xfe,0x7c,0x02,
+0x12,0x31,0xfb,0x74,0x40,0x90,0xff,0xfe,0xf0,0x02,0x1c,0x14,0xe4,0xff,0x04,0xfe,
+0x7c,0x04,0x12,0x31,0xfb,0x02,0x1c,0x14,0xe4,0xff,0x04,0xfe,0x7c,0x05,0x12,0x31,
+0xfb,0x02,0x1c,0x14,0xe4,0xff,0x04,0xfe,0x7c,0x06,0x12,0x31,0xfb,0x02,0x1c,0x14,
+0x90,0xff,0xa5,0xe0,0x7d,0x00,0x90,0xfb,0xf8,0xcd,0xf0,0xa3,0xcd,0xf0,0x90,0xfb,
+0xf9,0xe0,0xfc,0xf5,0x83,0x90,0xfb,0xf8,0xe0,0x44,0x33,0xfd,0x12,0x1c,0xa7,0x80,
+0x73,0x90,0xff,0xb5,0xe0,0x7d,0x00,0x90,0xfb,0xfa,0xcd,0xf0,0xa3,0xcd,0xf0,0x90,
+0xfb,0xfb,0xe0,0xfc,0xf5,0x83,0x90,0xfb,0xfa,0xe0,0x44,0x43,0xfd,0x12,0x1c,0xa7,
+0x80,0x52,0x90,0xff,0xa6,0xe0,0x7d,0x00,0x90,0xfb,0xfc,0xcd,0xf0,0xa3,0xcd,0xf0,
+0x90,0xfb,0xfd,0xe0,0xfc,0xf5,0x83,0x90,0xfb,0xfc,0xe0,0x44,0x34,0xfd,0x12,0x1c,
+0xa7,0x80,0x31,0x90,0xff,0xb6,0xe0,0x7d,0x00,0x90,0xfb,0xfe,0xcd,0xf0,0xa3,0xcd,
+0xf0,0x90,0xfb,0xff,0xe0,0xfc,0xf5,0x83,0x90,0xfb,0xfe,0xe0,0x44,0x44,0xfd,0x12,
+0x1c,0xa7,0x80,0x10,0x90,0xff,0x92,0xe0,0x7d,0x00,0xfc,0xed,0x44,0xaa,0xfd,0x12,
+0x1c,0xa7,0x80,0x00,0xe4,0x90,0xff,0x92,0xf0,0xd0,0xe0,0xff,0xd0,0xe0,0xfe,0xd0,
+0xe0,0xfd,0xd0,0xe0,0xfc,0xd0,0xe0,0xfb,0xd0,0xe0,0xfa,0xd0,0xe0,0xf9,0xd0,0xe0,
+0xf8,0xd0,0xd0,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32,0x05,0x81,0x05,0x81,
+0x05,0x81,0x05,0x81,0xa8,0x81,0x18,0x18,0x18,0xed,0xf6,0x08,0xec,0xf6,0x90,0xff,
+0x5a,0xe0,0x20,0xe7,0x02,0x80,0xf7,0x90,0xff,0x59,0xe0,0x7d,0x00,0xa8,0x81,0x18,
+0xcd,0xf6,0xcd,0x08,0xf6,0x7d,0x03,0xa8,0x81,0xe6,0x18,0xfc,0xe6,0xcc,0x25,0xe0,
+0xcc,0x33,0xcc,0xdd,0xf9,0xcc,0xf6,0xcc,0x08,0xf6,0xa8,0x81,0x18,0xe6,0x44,0xf8,
+0xf6,0xa8,0x81,0x18,0x18,0x18,0xe6,0xfd,0x08,0xe6,0xfc,0xa8,0x81,0x18,0x86,0x83,
+0x08,0x86,0x82,0xed,0xf0,0xa3,0xec,0xf0,0x74,0x02,0x90,0xff,0x5a,0xf0,0x15,0x81,
+0x15,0x81,0x15,0x81,0x15,0x81,0x22,0xe5,0x81,0x24,0x05,0xf5,0x81,0xe4,0xa8,0x81,
+0x18,0xf6,0xa8,0x81,0x18,0x18,0x18,0x18,0xed,0xf6,0x08,0xec,0xf6,0x90,0xfb,0xf5,
+0xe0,0x24,0xf8,0x50,0x03,0x02,0x1d,0xc8,0xe4,0xa8,0x81,0x18,0x18,0xf6,0xa8,0x81,
+0x18,0xe6,0xfe,0xa8,0x81,0x18,0x18,0x18,0x18,0xe6,0xfd,0x08,0xe6,0xfc,0x7f,0x00,
+0xef,0x24,0xf8,0x40,0x4d,0xe4,0xef,0x25,0xe0,0x24,0x7d,0xf5,0x82,0xe4,0x34,0xfc,
+0xf5,0x83,0xe0,0xfb,0xa3,0xe0,0x6c,0x70,0x03,0xfa,0xeb,0x6d,0x70,0x09,0x74,0x01,
+0xa8,0x81,0x18,0x18,0xf6,0x80,0x2b,0xe4,0xef,0x25,0xe0,0x24,0x7d,0xf5,0x82,0xe4,
+0x34,0xfc,0xf5,0x83,0x7a,0x00,0xe0,0x54,0xf0,0xcc,0xf8,0xcc,0xcd,0xf9,0xcd,0xfb,
+0x78,0x00,0xe9,0x54,0xf0,0xf9,0xea,0x68,0x70,0x02,0xeb,0x69,0x70,0x01,0x0e,0x0f,
+0x80,0xae,0xa8,0x81,0x18,0xee,0xf6,0xa8,0x81,0x18,0x18,0x18,0x18,0xed,0xf6,0x08,
+0xec,0xf6,0xa8,0x81,0xef,0xf6,0xa8,0x81,0x18,0x18,0xe6,0x70,0x79,0xa8,0x81,0x18,
+0xe6,0x24,0xf7,0x40,0x71,0xa8,0x81,0x18,0x18,0x18,0x18,0xe6,0x54,0x0f,0xa8,0x81,
+0xf6,0x64,0x04,0x60,0x17,0xa8,0x81,0xe6,0x64,0x03,0x60,0x10,0xa8,0x81,0x18,0x18,
+0x18,0x18,0xe6,0xfd,0x08,0xe6,0xfc,0x12,0x1c,0x3c,0x80,0x4a,0x7c,0x0a,0x12,0x31,
+0x5b,0xa8,0x81,0x18,0x18,0x18,0x18,0xe6,0xfd,0x08,0xe6,0xfc,0x90,0xfb,0xf4,0xe0,
+0x25,0xe0,0x24,0x7d,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xed,0xf0,0xa3,0xec,0xf0,
+0x90,0xfb,0xf4,0xe0,0xff,0xe4,0xef,0x04,0x54,0x07,0xff,0x90,0xfb,0xf4,0xf0,0x90,
+0xfb,0xf5,0xe0,0x04,0xf0,0x12,0x31,0xf4,0x90,0xfb,0xf6,0xe0,0x70,0x08,0xe4,0xfe,
+0xff,0x7c,0x0f,0x12,0x31,0xfb,0x80,0x27,0x90,0xfb,0xf7,0xe0,0x04,0xf0,0x54,0x3f,
+0x70,0x1d,0x90,0xfb,0xf7,0xe0,0x44,0xfe,0x7d,0x00,0xfc,0x90,0xfb,0xf4,0xe0,0x25,
+0xe0,0x24,0x7d,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xed,0xf0,0xa3,0xec,0xf0,0xe5,
+0x81,0x24,0xfb,0xf5,0x81,0x22,0x78,0x8b,0x76,0x00,0x78,0x8c,0x76,0x00,0x74,0x01,
+0x90,0xfb,0xf6,0xf0,0x12,0x30,0xe6,0x90,0xfb,0xf5,0xe0,0x60,0x57,0x7c,0x0a,0x12,
+0x31,0x5b,0x90,0xfb,0xf3,0xe0,0x25,0xe0,0x24,0x7d,0xf5,0x82,0xe4,0x34,0xfc,0xf5,
+0x83,0xe0,0xfd,0xa3,0xe0,0xfc,0x90,0xfb,0xf3,0xe0,0x25,0xe0,0x24,0x7d,0xf5,0x82,
+0xe4,0x34,0xfc,0xf5,0x83,0xe4,0xf0,0xa3,0xf0,0x90,0xfb,0xf3,0xe0,0xff,0xe4,0xef,
+0x04,0x54,0x07,0xff,0x90,0xfb,0xf3,0xf0,0x90,0xfb,0xf5,0xe0,0x14,0xf0,0x78,0x89,
+0xed,0xf6,0x08,0xec,0xf6,0x12,0x31,0xf4,0x78,0x89,0xe6,0xfd,0x08,0xe6,0xfc,0x12,
+0x08,0xda,0x80,0xa3,0x12,0x32,0x48,0x90,0xff,0x93,0xe0,0x44,0x01,0xf0,0xb2,0xb3,
+0x78,0x8b,0x06,0xb6,0x00,0x11,0x78,0x8b,0x76,0x00,0x78,0x8c,0xe6,0xf4,0x04,0x04,
+0xa2,0xe0,0x92,0xb4,0x78,0x8c,0xf6,0x02,0x1e,0x07,0xe4,0x90,0xfb,0xf6,0xf0,0x90,
+0xfb,0xf5,0xe0,0x7d,0x00,0xfc,0xed,0x44,0xcf,0xfd,0x12,0x1c,0x3c,0x12,0x31,0x69,
+0x22,0x12,0x30,0xe6,0xe5,0x70,0x64,0x49,0x45,0x6f,0x60,0x15,0x90,0xff,0x83,0xe0,
+0x54,0x0f,0x7d,0x00,0xd3,0x95,0x70,0xed,0x95,0x6f,0x50,0x05,0x12,0x2f,0x2f,0x80,
+0x03,0x12,0x2f,0xff,0x12,0x31,0x69,0x22,0x12,0x30,0xe6,0xe5,0x70,0x64,0x49,0x45,
+0x6f,0x60,0x05,0x12,0x30,0x39,0x80,0x0e,0x90,0xff,0x80,0xe0,0x44,0x08,0xf0,0x90,
+0xff,0x83,0xe0,0x54,0x7f,0xf0,0x12,0x31,0x69,0x22,0x12,0x30,0xe6,0x8c,0x54,0xec,
+0x54,0xf0,0xb4,0x10,0x15,0x75,0x6a,0x35,0x75,0x69,0xfc,0x75,0x68,0x01,0xe5,0x6a,
+0x24,0x03,0xf5,0x6a,0xe5,0x69,0x34,0x00,0xf5,0x69,0xe4,0xf5,0x57,0xf5,0x56,0xe5,
+0x56,0xc3,0x94,0x01,0x50,0x27,0xe5,0x54,0x54,0x0f,0xfc,0xad,0x6a,0xae,0x69,0xaf,
+0x68,0x12,0x0e,0x77,0x8c,0x55,0xec,0x60,0x02,0x80,0x12,0x05,0x6a,0xe5,0x6a,0x70,
+0x02,0x05,0x69,0x05,0x57,0xe5,0x57,0x70,0x02,0x05,0x56,0x80,0xd2,0xe5,0x54,0x54,
+0x0f,0x24,0x9d,0xf8,0xc6,0x54,0xfe,0xf6,0xe5,0x54,0x54,0x0f,0x7f,0x00,0xfe,0x7c,
+0x12,0x12,0x31,0xfb,0xe5,0x55,0x14,0x70,0x09,0x7d,0x00,0x7c,0x09,0x12,0x25,0x26,
+0x80,0x07,0xad,0x57,0x7c,0x00,0x12,0x25,0x26,0x12,0x31,0x69,0x22,0x12,0x30,0xe6,
+0x90,0xff,0xfc,0xe0,0x44,0x02,0xf0,0x90,0xff,0x00,0xe0,0x30,0xe7,0x13,0x90,0xff,
+0x83,0xe0,0x44,0x80,0xf0,0x43,0x6d,0x80,0x90,0xff,0xfc,0xe0,0x44,0x01,0xf0,0x80,
+0x11,0x90,0xff,0x82,0xe0,0x44,0x08,0xf0,0x53,0x6d,0x7f,0x90,0xff,0xfc,0xe0,0x54,
+0xfe,0xf0,0x90,0xff,0x81,0xe0,0x44,0x80,0xf0,0x12,0x25,0xd9,0x90,0xff,0xfe,0xe0,
+0x44,0x05,0xf0,0x90,0xff,0xfc,0xe0,0x54,0xfd,0xf0,0x12,0x31,0x69,0x22,0x12,0x30,
+0xe6,0x7c,0x01,0x12,0x32,0xa9,0x78,0xad,0xe6,0x44,0x02,0xf6,0x74,0xfe,0xfc,0x04,
+0xfd,0x12,0x1c,0xa7,0x90,0xff,0x5a,0xe0,0x30,0xe7,0x02,0x80,0xf7,0xe4,0xf5,0x4e,
+0x75,0x4d,0x10,0xac,0x4e,0xad,0x4d,0xe5,0x4e,0x15,0x4e,0x70,0x02,0x15,0x4d,0xec,
+0x4d,0x60,0x02,0x80,0xee,0x43,0x87,0x01,0x12,0x31,0x69,0x22,0x12,0x30,0xe6,0x7c,
+0x02,0x12,0x31,0x75,0x78,0xad,0xe6,0x54,0xfd,0xf6,0x12,0x31,0x69,0x22,0x12,0x30,
+0xe6,0x78,0xad,0xe6,0x30,0xe0,0x2c,0x78,0xad,0xe6,0x30,0xe1,0x26,0x78,0xad,0xe6,
+0xfc,0xf5,0x83,0x18,0xe6,0x44,0xf0,0xfd,0x12,0x1c,0x3c,0x90,0xff,0xfc,0xe0,0x44,
+0x20,0xf0,0x7c,0x02,0x12,0x32,0xa9,0x78,0xad,0xe6,0x54,0xfd,0xf6,0x74,0x1a,0x90,
+0xff,0xfe,0xf0,0x78,0xad,0xe6,0xfc,0xf5,0x83,0x18,0xe6,0x44,0xf1,0xfd,0x12,0x1c,
+0x3c,0x12,0x31,0x69,0x22,0x75,0x6d,0x00,0x90,0xff,0xff,0xe0,0x60,0x03,0x43,0x6d,
+0x01,0x75,0x6e,0x00,0xe4,0xf5,0x6c,0xf5,0x6b,0xe4,0xf5,0x6f,0x75,0x70,0x49,0x74,
+0x84,0x90,0xff,0x82,0xf0,0x74,0x84,0x90,0xff,0x80,0xf0,0x74,0x80,0x90,0xff,0x58,
+0xf0,0x74,0x80,0x90,0xff,0x5a,0xf0,0xad,0x46,0xaf,0x45,0x7e,0x00,0xee,0x24,0xfe,
+0x50,0x03,0x02,0x21,0x24,0xe4,0xee,0x75,0xf0,0x07,0xa4,0x24,0x7f,0xf5,0x82,0xe4,
+0x34,0xf8,0xf5,0x83,0xe0,0xff,0xe4,0xef,0x54,0x80,0xfd,0xe4,0xef,0x54,0x0f,0x14,
+0xff,0xed,0x60,0x38,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x48,0xf5,0x82,0xe4,0x34,
+0xff,0xf5,0x83,0x74,0x90,0xf0,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x4a,0xf5,0x82,
+0xe4,0x34,0xff,0xf5,0x83,0x74,0x80,0xf0,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x4e,
+0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0x74,0x80,0xf0,0x80,0x34,0xe4,0xef,0x75,0xf0,
+0x08,0xa4,0x24,0x08,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0x74,0x90,0xf0,0xe4,0xef,
+0x75,0xf0,0x08,0xa4,0x24,0x0a,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xe4,0xf0,0xe4,
+0xef,0x75,0xf0,0x08,0xa4,0x24,0x0e,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xe4,0xf0,
+0x0e,0x02,0x20,0x8d,0x8d,0x46,0x8e,0x44,0x8f,0x45,0x74,0x7f,0x90,0xff,0xfd,0xf0,
+0x74,0x90,0x90,0xff,0xfc,0xf0,0x22,0x8c,0x58,0xec,0x24,0xf6,0x50,0x06,0xe5,0x58,
+0x24,0x37,0xfc,0x22,0xe5,0x58,0x24,0x30,0xfc,0x22,0x12,0x25,0x23,0xec,0x70,0x03,
+0x02,0x22,0x5e,0x75,0x5c,0x03,0xae,0x5b,0x7f,0x00,0xe5,0x5c,0x15,0x5c,0x64,0x80,
+0x24,0x7f,0x50,0x35,0xef,0x24,0x00,0xf5,0x82,0xe4,0x34,0xfb,0xf5,0x83,0xe0,0xfe,
+0x24,0xfe,0x50,0x1e,0xef,0x7d,0x00,0xfc,0xe4,0xfb,0x74,0x74,0xc3,0x9c,0xfa,0xeb,
+0x9d,0xfb,0xee,0x7d,0x00,0xfc,0xea,0xc3,0x9c,0xed,0x64,0x80,0xcb,0x64,0x80,0x9b,
+0x50,0x02,0x80,0x05,0xef,0x2e,0xff,0x80,0xc1,0x8e,0x5b,0x8f,0x5a,0xe5,0x5c,0x64,
+0x80,0x24,0x7f,0x50,0x03,0x02,0x22,0x5e,0xe5,0x5a,0x24,0x8e,0x50,0x03,0x02,0x22,
+0x5e,0x85,0x5a,0x5d,0x75,0x5b,0x00,0xae,0x5a,0xaf,0x5b,0x90,0x35,0x9c,0xe4,0x93,
+0xf5,0x5c,0xe5,0x5c,0x15,0x5c,0x64,0x80,0x24,0x7f,0x50,0x18,0xee,0x24,0x00,0xf5,
+0x82,0xe4,0x34,0xfb,0xf5,0x83,0xe0,0xfc,0xef,0x90,0x35,0x9c,0x93,0x6c,0x70,0x04,
+0x0e,0x0f,0x80,0xde,0x8e,0x5a,0x8f,0x5b,0xe5,0x5c,0x64,0x80,0x24,0x7f,0x40,0x6e,
+0x75,0x5e,0x01,0x75,0x60,0xe8,0x75,0x5f,0xff,0xe5,0x5d,0x24,0x02,0xf5,0x5a,0x75,
+0x5c,0x07,0xe5,0x5c,0x33,0x40,0x57,0xad,0x60,0xae,0x5f,0xaf,0x5e,0xe5,0x5c,0xf5,
+0x82,0x33,0x95,0xe0,0xf5,0x83,0x12,0x01,0xec,0xc4,0x54,0x0f,0xfc,0x12,0x21,0x37,
+0xe5,0x5a,0x24,0x00,0xf5,0x82,0xe4,0x34,0xfb,0xf5,0x83,0xec,0xf0,0x05,0x5a,0x05,
+0x5a,0xad,0x60,0xae,0x5f,0xaf,0x5e,0xe5,0x5c,0xf5,0x82,0x33,0x95,0xe0,0xf5,0x83,
+0x12,0x01,0xec,0x54,0x0f,0xfc,0x12,0x21,0x37,0xe5,0x5a,0x24,0x00,0xf5,0x82,0xe4,
+0x34,0xfb,0xf5,0x83,0xec,0xf0,0x05,0x5a,0x05,0x5a,0x15,0x5c,0x80,0xa4,0x74,0x02,
+0x90,0xf8,0x51,0xf0,0x90,0xf8,0x6b,0x79,0x75,0x7a,0x35,0x7b,0x27,0x78,0x01,0x12,
+0x03,0xf5,0x75,0x6a,0x35,0x75,0x69,0xfc,0x75,0x68,0x01,0xe4,0x90,0xff,0x83,0xf0,
+0x74,0x80,0x90,0xff,0x81,0xf0,0x75,0x59,0x02,0xe5,0x59,0x75,0xf0,0x07,0xa4,0x24,
+0x7f,0xf5,0x82,0xe4,0x34,0xf8,0xf5,0x83,0xe0,0x78,0x8f,0xf6,0xfc,0x54,0x0f,0x14,
+0xfc,0x78,0x8f,0xec,0xf6,0xe5,0x59,0x75,0xf0,0x07,0xa4,0x24,0x81,0xf5,0x82,0xe4,
+0x34,0xf8,0xf5,0x83,0xe0,0x78,0x92,0x76,0xfd,0x08,0x76,0xe8,0xfc,0x78,0x8f,0xe6,
+0x75,0xf0,0x08,0xa4,0x24,0x48,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xe4,0xf0,0x78,
+0x8f,0xe6,0x75,0xf0,0x08,0xa4,0x24,0x4f,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xec,
+0xf0,0x78,0x92,0xe6,0xff,0x08,0xe6,0x7e,0x03,0xcf,0xc3,0x13,0xcf,0x13,0xde,0xf9,
+0xfe,0x78,0x8f,0xe6,0x75,0xf0,0x08,0xa4,0x24,0x49,0xf5,0x82,0xe4,0x34,0xff,0xf5,
+0x83,0xee,0xf0,0x78,0x8f,0xe6,0x75,0xf0,0x08,0xa4,0x24,0x4a,0xf5,0x82,0xe4,0x34,
+0xff,0xf5,0x83,0x74,0x80,0xf0,0x78,0x90,0xec,0xf6,0x7d,0x00,0x78,0x93,0xe6,0x2c,
+0xf6,0x18,0xe6,0x3d,0xf6,0x78,0x92,0xe6,0xfd,0x08,0xe6,0x7c,0x03,0xcd,0xc3,0x13,
+0xcd,0x13,0xdc,0xf9,0xfc,0x78,0x8f,0xe6,0x75,0xf0,0x08,0xa4,0x24,0x4d,0xf5,0x82,
+0xe4,0x34,0xff,0xf5,0x83,0xec,0xf0,0x78,0x8f,0xe6,0x75,0xf0,0x08,0xa4,0x24,0x4e,
+0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xe4,0xf0,0x78,0x92,0xe6,0xfd,0x08,0xe6,0xfc,
+0x78,0x8f,0xe6,0xff,0x7e,0x00,0xee,0x24,0xfe,0x50,0x03,0x02,0x24,0xdd,0xe4,0xee,
+0x75,0xf0,0x07,0xa4,0x24,0x7f,0xf5,0x82,0xe4,0x34,0xf8,0xf5,0x83,0xe0,0xff,0xe4,
+0xef,0x54,0x80,0xfa,0xe4,0xef,0x54,0x0f,0x14,0xff,0xe4,0xee,0x75,0xf0,0x07,0xa4,
+0x24,0x81,0xf5,0x82,0xe4,0x34,0xf8,0xf5,0x83,0xe0,0x78,0x90,0xf6,0xe4,0xee,0x13,
+0x13,0x54,0x80,0x24,0xf0,0xf8,0xe4,0x34,0xfd,0xf9,0xe8,0xfc,0xe9,0xfd,0x8a,0x5a,
+0xea,0x70,0x03,0x02,0x24,0x4a,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x48,0xf5,0x82,
+0xe4,0x34,0xff,0xf5,0x83,0xe4,0xf0,0x78,0x90,0xe6,0xfa,0xe4,0xef,0x75,0xf0,0x08,
+0xa4,0x24,0x4f,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xea,0xf0,0xed,0xfb,0xec,0x7a,
+0x03,0xcb,0xc3,0x13,0xcb,0x13,0xda,0xf9,0xfa,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,
+0x49,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xea,0xf0,0x78,0x90,0xe6,0x7b,0x00,0xfa,
+0xec,0x2a,0xfc,0xed,0x3b,0xfd,0xfb,0xec,0x7a,0x03,0xcb,0xc3,0x13,0xcb,0x13,0xda,
+0xf9,0xfa,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x4d,0xf5,0x82,0xe4,0x34,0xff,0xf5,
+0x83,0xea,0xf0,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x4a,0xf5,0x82,0xe4,0x34,0xff,
+0xf5,0x83,0x74,0x80,0xf0,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x4e,0xf5,0x82,0xe4,
+0x34,0xff,0xf5,0x83,0x74,0x80,0xf0,0x02,0x24,0xd9,0xe4,0xef,0x75,0xf0,0x08,0xa4,
+0x24,0x08,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xe4,0xf0,0x78,0x90,0xe6,0xfa,0xe4,
+0xef,0x75,0xf0,0x08,0xa4,0x24,0x0f,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xea,0xf0,
+0xed,0xfb,0xec,0x7a,0x03,0xcb,0xc3,0x13,0xcb,0x13,0xda,0xf9,0xfa,0xe4,0xef,0x75,
+0xf0,0x08,0xa4,0x24,0x09,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xea,0xf0,0x78,0x90,
+0xe6,0x7b,0x00,0xfa,0xec,0x2a,0xfc,0xed,0x3b,0xfd,0xfb,0xec,0x7a,0x03,0xcb,0xc3,
+0x13,0xcb,0x13,0xda,0xf9,0xfa,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x0d,0xf5,0x82,
+0xe4,0x34,0xff,0xf5,0x83,0xea,0xf0,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x0a,0xf5,
+0x82,0xe4,0x34,0xff,0xf5,0x83,0xe4,0xf0,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x0e,
+0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xe4,0xf0,0x0e,0x02,0x23,0x66,0x8e,0x59,0x78,
+0x92,0xed,0xf6,0x08,0xec,0xf6,0x78,0x8f,0xef,0xf6,0x12,0x20,0x55,0x22,0x8c,0x26,
+0xec,0x30,0xe7,0x18,0xe5,0x26,0x54,0x0f,0x14,0x75,0xf0,0x08,0xa4,0x24,0x48,0xf5,
+0x82,0xe4,0x34,0xff,0xf5,0x83,0xe0,0x54,0xdf,0xf0,0x80,0x16,0xe5,0x26,0x54,0x0f,
+0x14,0x75,0xf0,0x08,0xa4,0x24,0x08,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xe0,0x54,
+0xdf,0xf0,0x22,0x7c,0x00,0x22,0xec,0x90,0xfc,0x37,0xf0,0x8c,0x24,0xed,0x24,0x03,
+0xf5,0x25,0x7d,0x00,0xd3,0x95,0x72,0xed,0x95,0x71,0x40,0x03,0x85,0x72,0x25,0xe5,
+0x25,0x24,0xb7,0x50,0x09,0x75,0x25,0x03,0x74,0x02,0x90,0xfc,0x37,0xf0,0xac,0x25,
+0x12,0x30,0x24,0x22,0xe4,0xf5,0x6c,0xf5,0x6b,0x12,0x25,0x5d,0x22,0x90,0xfc,0x35,
+0xe0,0x65,0x73,0x60,0x0e,0x74,0x04,0x90,0xfc,0x37,0xf0,0xe4,0xf5,0x6b,0x75,0x6c,
+0x03,0x80,0x46,0x7d,0x73,0xe4,0xfe,0xff,0x79,0x35,0x7a,0xfc,0x7b,0x01,0x74,0x05,
+0x78,0x00,0x12,0x03,0x3f,0xe5,0x6c,0x24,0x03,0xf5,0x6c,0xe5,0x6b,0x34,0x00,0xf5,
+0x6b,0xe5,0x6c,0xd3,0x95,0x72,0xe5,0x6b,0x95,0x71,0x40,0x06,0x85,0x72,0x6c,0x85,
+0x71,0x6b,0xd3,0xe5,0x6c,0x94,0x48,0xe5,0x6b,0x94,0x00,0x40,0x0c,0x74,0x02,0x90,
+0xfc,0x37,0xf0,0xe4,0xf5,0x6b,0x75,0x6c,0x03,0xac,0x6c,0x12,0x30,0x24,0x22,0xec,
+0x90,0xfc,0x37,0xf0,0xe4,0xf5,0x6c,0xf5,0x6b,0x8c,0x32,0xec,0x60,0x05,0x12,0x30,
+0x15,0x80,0x05,0x7c,0x00,0x12,0x30,0x24,0x22,0x90,0xff,0x93,0xe0,0x44,0x01,0xf0,
+0xb2,0xb3,0x90,0xff,0x04,0xe0,0xf5,0x4a,0x90,0xff,0x06,0xe0,0xfd,0xa3,0xe0,0xed,
+0x7d,0x00,0xfc,0x7d,0x00,0xfc,0x90,0xff,0x06,0xe0,0xff,0xa3,0xe0,0x7e,0x00,0xff,
+0xe4,0xfe,0xec,0x4e,0xfc,0xed,0x4f,0xfd,0xc3,0xec,0x94,0x48,0xed,0x94,0x00,0x50,
+0x22,0x90,0xff,0x06,0xe0,0xfd,0xa3,0xe0,0xed,0x7d,0x00,0xfc,0x7d,0x00,0xfc,0x90,
+0xff,0x06,0xe0,0xff,0xa3,0xe0,0x7e,0x00,0xff,0xe4,0xfe,0xec,0x4e,0xfc,0xed,0x4f,
+0xfd,0x80,0x04,0xe4,0xfd,0x7c,0x48,0x8c,0x72,0x8d,0x71,0x90,0xff,0x02,0xe0,0xfd,
+0xa3,0xe0,0xed,0x7d,0x00,0xfc,0x7d,0x00,0xfc,0x90,0xff,0x02,0xe0,0xff,0xa3,0xe0,
+0x7e,0x00,0xff,0xe4,0xfe,0xec,0x4e,0xf5,0x4c,0xed,0x4f,0xf5,0x4b,0x75,0x6a,0x35,
+0x75,0x69,0xfc,0x75,0x68,0x01,0x7d,0x35,0x7e,0xfc,0x7f,0x01,0x79,0x73,0xe4,0xfa,
+0xfb,0x74,0x05,0x78,0x00,0x12,0x03,0x3f,0x75,0x49,0x00,0xe5,0x49,0x24,0xfe,0x40,
+0x19,0xad,0x6a,0xae,0x69,0xaf,0x68,0xe4,0x12,0x03,0x0f,0x05,0x49,0x0d,0xed,0x70,
+0x01,0x0e,0x8d,0x6a,0x8e,0x69,0x8f,0x68,0x80,0xe1,0x75,0x6a,0x35,0x75,0x69,0xfc,
+0x75,0x68,0x01,0x90,0xff,0x00,0xe0,0x54,0x60,0xb4,0x00,0x02,0x80,0x06,0xd3,0x50,
+0x03,0x02,0x2c,0x6d,0xe5,0x4a,0x54,0x0f,0xf5,0x49,0xe5,0x4a,0x54,0x80,0xa2,0xe0,
+0x92,0x02,0x90,0xff,0x01,0xe0,0x12,0x01,0x81,0x00,0x0b,0x2c,0x68,0x26,0xe5,0x28,
+0x03,0x2c,0x68,0x29,0x0f,0x2c,0x68,0x29,0xf2,0x2a,0x26,0x2b,0x8d,0x2b,0x90,0x2b,
+0xd0,0x2c,0x11,0x2c,0x3f,0xe5,0x6d,0x30,0xe7,0x0e,0xe5,0x4c,0x45,0x4b,0x70,0x08,
+0xe5,0x72,0x64,0x02,0x45,0x71,0x60,0x03,0x02,0x2c,0x6a,0x90,0xff,0x00,0xe0,0x54,
+0x1f,0xb4,0x00,0x02,0x80,0x03,0xd3,0x40,0x29,0xe5,0x4a,0x60,0x03,0x02,0x28,0x00,
+0xad,0x6a,0xae,0x69,0xaf,0x68,0x74,0x01,0x12,0x03,0x0f,0x78,0xad,0xe6,0x30,0xe0,
+0x0b,0xad,0x6a,0xae,0x69,0xaf,0x68,0x74,0x02,0x12,0x03,0x0f,0x7c,0x02,0x12,0x30,
+0x24,0x22,0xb4,0x01,0x02,0x80,0x03,0xd3,0x40,0x1b,0xe5,0x6d,0x20,0xe1,0x07,0xe5,
+0x4a,0x60,0x03,0x02,0x28,0x00,0xe5,0x4a,0x24,0xfe,0x50,0x03,0x02,0x28,0x00,0x7c,
+0x02,0x12,0x30,0x24,0x22,0xb4,0x02,0x02,0x80,0x06,0xd3,0x50,0x03,0x02,0x27,0xfe,
+0xe5,0x6d,0x20,0xe1,0x0d,0xe5,0x4a,0x60,0x09,0xe5,0x4a,0x64,0x80,0x60,0x03,0x02,
+0x28,0x00,0xac,0x4a,0x12,0x30,0xab,0x40,0x03,0x02,0x28,0x00,0xe5,0x49,0x70,0x25,
+0x30,0x02,0x11,0x90,0xff,0x80,0xe0,0x54,0x08,0xad,0x6a,0xae,0x69,0xaf,0x68,0x12,
+0x03,0x0f,0x80,0x0f,0x90,0xff,0x82,0xe0,0x54,0x08,0xad,0x6a,0xae,0x69,0xaf,0x68,
+0x12,0x03,0x0f,0x80,0x3d,0x15,0x49,0x30,0x02,0x1d,0xe5,0x49,0x75,0xf0,0x08,0xa4,
+0x24,0x48,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xe0,0x54,0x08,0xad,0x6a,0xae,0x69,
+0xaf,0x68,0x12,0x03,0x0f,0x80,0x1b,0xe5,0x49,0x75,0xf0,0x08,0xa4,0x24,0x08,0xf5,
+0x82,0xe4,0x34,0xff,0xf5,0x83,0xe0,0x54,0x08,0xad,0x6a,0xae,0x69,0xaf,0x68,0x12,
+0x03,0x0f,0xad,0x6a,0xae,0x69,0xaf,0x68,0x12,0x01,0xe6,0x60,0x0b,0xad,0x6a,0xae,
+0x69,0xaf,0x68,0x74,0x01,0x12,0x03,0x0f,0x7c,0x02,0x12,0x30,0x24,0x22,0x80,0x00,
+0x02,0x2c,0x6a,0xe5,0x6d,0x20,0xe7,0x06,0xe5,0x72,0x45,0x71,0x60,0x03,0x02,0x2c,
+0x6a,0x90,0xff,0x00,0xe0,0x54,0x1f,0xb4,0x00,0x02,0x80,0x03,0xd3,0x40,0x1a,0xe5,
+0x4c,0x14,0x45,0x4b,0x70,0x04,0xe5,0x4a,0x60,0x03,0x02,0x29,0x0c,0x78,0xad,0xe6,
+0x54,0xfe,0xf6,0x7c,0x00,0x12,0x30,0x24,0x22,0xb4,0x01,0x02,0x80,0x03,0xd3,0x40,
+0x2a,0xe5,0x6d,0x20,0xe1,0x08,0xe5,0x6d,0x20,0xe0,0x03,0x02,0x29,0x0c,0xe5,0x6d,
+0x30,0xe0,0x04,0xe5,0x4a,0x70,0x0b,0xe5,0x6d,0x30,0xe1,0x09,0xe5,0x4a,0x24,0xfe,
+0x50,0x03,0x02,0x29,0x0c,0x7c,0x00,0x12,0x30,0x24,0x22,0xb4,0x02,0x02,0x80,0x06,
+0xd3,0x50,0x03,0x02,0x29,0x0a,0xe5,0x4c,0x45,0x4b,0x60,0x03,0x02,0x29,0x0c,0xac,
+0x4a,0x12,0x30,0xab,0x40,0x03,0x02,0x29,0x0c,0xe5,0x6d,0x20,0xe1,0x07,0xe5,0x6d,
+0x20,0xe0,0x02,0x80,0x77,0xe5,0x6d,0x30,0xe0,0x06,0xe5,0x49,0x60,0x02,0x80,0x6c,
+0xe5,0x49,0x70,0x0f,0x90,0xff,0x82,0xe0,0x54,0xf7,0xf0,0x90,0xff,0x80,0xe0,0x54,
+0xf7,0xf0,0x22,0xe5,0x49,0xb4,0x01,0x02,0x80,0x03,0xd3,0x40,0x09,0x7d,0x01,0x7c,
+0x03,0x12,0x0f,0x09,0x80,0x11,0xb4,0x02,0x02,0x80,0x03,0xd3,0x40,0x09,0x7d,0x01,
+0x7c,0x04,0x12,0x0f,0x09,0x80,0x00,0x15,0x49,0x30,0x02,0x15,0xe5,0x49,0x75,0xf0,
+0x08,0xa4,0x24,0x48,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xe0,0x54,0xf7,0xf0,0x80,
+0x13,0xe5,0x49,0x75,0xf0,0x08,0xa4,0x24,0x08,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,
+0xe0,0x54,0xf7,0xf0,0x7c,0x00,0x12,0x30,0x24,0x22,0x80,0x00,0x02,0x2c,0x6a,0xe5,
+0x6d,0x20,0xe7,0x06,0xe5,0x72,0x45,0x71,0x60,0x03,0x02,0x2c,0x6a,0x90,0xff,0x00,
+0xe0,0x54,0x1f,0xb4,0x00,0x02,0x80,0x03,0xd3,0x40,0x1a,0xe5,0x4c,0x14,0x45,0x4b,
+0x70,0x04,0xe5,0x4a,0x60,0x03,0x02,0x29,0xef,0x78,0xad,0xe6,0x44,0x01,0xf6,0x7c,
+0x00,0x12,0x30,0x24,0x22,0xb4,0x01,0x02,0x80,0x03,0xd3,0x40,0x29,0xe5,0x6d,0x20,
+0xe1,0x08,0xe5,0x6d,0x20,0xe0,0x03,0x02,0x29,0xef,0xe5,0x6d,0x30,0xe0,0x04,0xe5,
+0x49,0x70,0x0b,0xe5,0x6d,0x30,0xe1,0x08,0xe5,0x49,0x24,0xfe,0x50,0x02,0x80,0x7f,
+0x7c,0x00,0x12,0x30,0x24,0x22,0xb4,0x02,0x02,0x80,0x03,0xd3,0x40,0x6f,0xe5,0x4c,
+0x45,0x4b,0x60,0x02,0x80,0x69,0xac,0x4a,0x12,0x30,0xab,0x40,0x02,0x80,0x60,0xe5,
+0x6d,0x20,0xe1,0x07,0xe5,0x6d,0x20,0xe0,0x02,0x80,0x54,0xe5,0x49,0x70,0x14,0x30,
+0x02,0x09,0x90,0xff,0x80,0xe0,0x44,0x08,0xf0,0x80,0x07,0x90,0xff,0x82,0xe0,0x44,
+0x08,0xf0,0x22,0xe5,0x6d,0x30,0xe1,0x33,0x15,0x49,0x30,0x02,0x15,0xe5,0x49,0x75,
+0xf0,0x08,0xa4,0x24,0x48,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xe0,0x44,0x08,0xf0,
+0x80,0x13,0xe5,0x49,0x75,0xf0,0x08,0xa4,0x24,0x08,0xf5,0x82,0xe4,0x34,0xff,0xf5,
+0x83,0xe0,0x44,0x08,0xf0,0x7c,0x00,0x12,0x30,0x24,0x22,0x80,0x02,0x80,0x00,0x02,
+0x2c,0x6a,0xe5,0x6d,0x20,0xe7,0x12,0xe5,0x72,0x45,0x71,0x70,0x0c,0xe5,0x4a,0x70,
+0x08,0x90,0xff,0x00,0xe0,0x54,0x1f,0x60,0x03,0x02,0x2c,0x6a,0xe5,0x4c,0x90,0xff,
+0xff,0xf0,0x90,0xff,0xff,0xe0,0x60,0x05,0x43,0x6d,0x01,0x80,0x03,0x53,0x6d,0xfe,
+0x7c,0x00,0x12,0x30,0x24,0x22,0xe5,0x6d,0x30,0xe7,0x0e,0xe5,0x72,0x45,0x71,0x60,
+0x08,0x90,0xff,0x00,0xe0,0x54,0x1f,0x60,0x03,0x02,0x2c,0x6a,0xad,0x4b,0xe5,0x4c,
+0xed,0x7d,0x00,0xfc,0x7d,0x00,0xfc,0xbd,0x00,0x02,0x80,0x03,0x02,0x2b,0x88,0xb4,
+0x01,0x02,0x80,0x03,0xd3,0x40,0x32,0xe5,0x4a,0x70,0x05,0xe5,0x4c,0xfc,0x60,0x03,
+0x02,0x2b,0x8a,0x75,0x6a,0x40,0x75,0x69,0xf8,0x75,0x68,0x01,0xd3,0xe5,0x72,0x94,
+0x12,0xe5,0x71,0x94,0x00,0x40,0x06,0xe4,0xfd,0x7c,0x12,0x80,0x04,0xac,0x72,0xad,
+0x71,0x8c,0x70,0x8d,0x6f,0x12,0x30,0x39,0x22,0xb4,0x02,0x02,0x80,0x03,0xd3,0x40,
+0x59,0xe5,0x4a,0x60,0x03,0x02,0x2b,0x8a,0xe5,0x4c,0xfc,0x70,0x27,0x75,0x6a,0x52,
+0x75,0x69,0xf8,0x75,0x68,0x01,0xd3,0xe5,0x72,0x94,0x19,0xe5,0x71,0x94,0x00,0x40,
+0x06,0xe4,0xfd,0x7c,0x19,0x80,0x04,0xac,0x72,0xad,0x71,0x8c,0x70,0x8d,0x6f,0x12,
+0x30,0x39,0x80,0x25,0x75,0x6a,0x6b,0x75,0x69,0xf8,0x75,0x68,0x01,0xd3,0xe5,0x72,
+0x94,0x27,0xe5,0x71,0x94,0x00,0x40,0x06,0xe4,0xfd,0x7c,0x27,0x80,0x04,0xac,0x72,
+0xad,0x71,0x8c,0x70,0x8d,0x6f,0x12,0x30,0x39,0x22,0xb4,0x03,0x02,0x80,0x06,0xd3,
+0x50,0x03,0x02,0x2b,0x88,0xe5,0x4c,0xf5,0x49,0x70,0x0f,0x90,0xff,0x04,0xe0,0xfd,
+0xa3,0xe0,0x4d,0x60,0x03,0x02,0x2b,0x8a,0x80,0x18,0x90,0xfb,0x02,0xe0,0xfd,0xa3,
+0xe0,0xfc,0x90,0xff,0x05,0xe0,0x6c,0x70,0x07,0x90,0xff,0x04,0xe0,0x6d,0x60,0x02,
+0x80,0x68,0xe4,0xf5,0x70,0xf5,0x6f,0x7f,0x00,0xe5,0x49,0x14,0xc5,0x49,0x60,0x0f,
+0xef,0x24,0x00,0xf5,0x82,0xe4,0x34,0xfb,0xf5,0x83,0xe0,0x2f,0xff,0x80,0xea,0x8f,
+0x4a,0xe5,0x4a,0x24,0x00,0xf5,0x82,0xe4,0x34,0xfb,0xf5,0x83,0xe0,0x7d,0x00,0xd3,
+0x95,0x72,0xed,0x95,0x71,0x40,0x06,0xac,0x72,0xad,0x71,0x80,0x0f,0xe5,0x4a,0x24,
+0x00,0xf5,0x82,0xe4,0x34,0xfb,0xf5,0x83,0xe0,0x7d,0x00,0xfc,0x8c,0x70,0x8d,0x6f,
+0xe5,0x4a,0x24,0x00,0xfc,0xe4,0x34,0xfb,0xfd,0xfe,0xec,0xfd,0x7f,0x01,0x8d,0x6a,
+0x8e,0x69,0x8f,0x68,0x12,0x30,0x39,0x22,0x80,0x00,0x02,0x2c,0x6a,0x02,0x2c,0x6a,
+0xe5,0x6d,0x30,0xe7,0x19,0xe5,0x72,0x14,0x45,0x71,0x70,0x12,0xe5,0x4a,0x70,0x0e,
+0xe5,0x4c,0x45,0x4b,0x70,0x08,0x90,0xff,0x00,0xe0,0x54,0x1f,0x60,0x03,0x02,0x2c,
+0x6a,0xe5,0x6d,0x20,0xe0,0x08,0xe5,0x6d,0x20,0xe1,0x03,0x02,0x2c,0x6a,0x75,0x6a,
+0x6e,0xe4,0xf5,0x69,0xf5,0x68,0xe4,0xf5,0x6f,0x04,0xf5,0x70,0x12,0x30,0x39,0x22,
+0xe5,0x6d,0x20,0xe7,0x12,0xe5,0x72,0x45,0x71,0x70,0x0c,0xe5,0x4a,0x70,0x08,0x90,
+0xff,0x00,0xe0,0x54,0x1f,0x60,0x03,0x02,0x2c,0x6a,0xe5,0x6d,0x20,0xe0,0x07,0xe5,
+0x6d,0x20,0xe1,0x02,0x80,0x74,0x85,0x4c,0x6e,0xe5,0x6e,0x70,0x08,0x43,0x6d,0x01,
+0x53,0x6d,0xfd,0x80,0x06,0x53,0x6d,0xfe,0x43,0x6d,0x02,0x7c,0x00,0x12,0x30,0x24,
+0x22,0xe5,0x6d,0x30,0xe7,0x1a,0xe5,0x72,0x14,0x45,0x71,0x70,0x13,0xe5,0x4a,0x70,
+0x0f,0xe5,0x4c,0x45,0x4b,0x70,0x09,0x90,0xff,0x00,0xe0,0x54,0x1f,0x14,0x60,0x02,
+0x80,0x38,0xe5,0x6d,0x20,0xe1,0x02,0x80,0x31,0x7c,0x01,0x12,0x30,0x24,0x22,0xe5,
+0x6d,0x20,0xe7,0x15,0xe5,0x72,0x45,0x71,0x70,0x0f,0xe5,0x4c,0x45,0x4b,0x70,0x09,
+0x90,0xff,0x00,0xe0,0x54,0x1f,0x14,0x60,0x02,0x80,0x0f,0xe5,0x6d,0x20,0xe1,0x02,
+0x80,0x08,0x7c,0x00,0x12,0x30,0x24,0x22,0x80,0x00,0x02,0x2f,0x2b,0xb4,0x40,0x02,
+0x80,0x06,0xd3,0x50,0x03,0x02,0x2f,0x21,0x90,0xff,0x01,0xe0,0x90,0xfc,0x35,0xf0,
+0xe5,0x4a,0x90,0xfc,0x36,0xf0,0xe4,0x90,0xfc,0x37,0xf0,0xe5,0x6a,0x24,0x03,0xf5,
+0x6a,0xe5,0x69,0x34,0x00,0xf5,0x69,0xad,0x4b,0xe5,0x4c,0x85,0x6a,0x82,0x85,0x69,
+0x83,0xcd,0xf0,0xa3,0xcd,0xf0,0x90,0xff,0x01,0xe0,0x12,0x01,0xb7,0x2c,0xd8,0x01,
+0x2c,0xfe,0x02,0x2d,0x28,0x03,0x2d,0x52,0x04,0x2d,0xa0,0x05,0x2d,0xdd,0x06,0x2e,
+0x03,0x07,0x2e,0x29,0x08,0x2e,0x55,0x09,0x2e,0x7b,0x0b,0x2e,0xa1,0x0c,0x2e,0xb0,
+0x80,0x2e,0xb0,0x81,0x00,0x00,0x2f,0x0e,0xe5,0x6d,0x20,0xe7,0x06,0x7c,0x05,0x12,
+0x25,0xbf,0x22,0x7d,0x24,0x7e,0x35,0x7f,0x02,0x79,0x38,0x7a,0xfc,0x7b,0x01,0x74,
+0x08,0x78,0x00,0x12,0x03,0x3f,0x7d,0x08,0x7c,0x00,0x12,0x25,0x26,0x22,0xe5,0x6d,
+0x20,0xe7,0x06,0x7c,0x05,0x12,0x25,0xbf,0x22,0xe5,0x4a,0xb4,0x03,0x00,0x40,0x10,
+0xb4,0x05,0x00,0x50,0x0b,0xe5,0x4a,0x7f,0x00,0xfe,0x7c,0x10,0x12,0x31,0xfb,0x22,
+0x7d,0x00,0x7c,0x07,0x12,0x25,0x26,0x22,0xe5,0x6d,0x20,0xe7,0x06,0x7c,0x05,0x12,
+0x25,0xbf,0x22,0xe5,0x4a,0xb4,0x03,0x00,0x40,0x10,0xb4,0x05,0x00,0x50,0x0b,0xe5,
+0x4a,0x7f,0x00,0xfe,0x7c,0x11,0x12,0x31,0xfb,0x22,0x7d,0x00,0x7c,0x07,0x12,0x25,
+0x26,0x22,0xe5,0x6d,0x20,0xe7,0x06,0x7c,0x05,0x12,0x25,0xbf,0x22,0xe5,0x4a,0xb4,
+0x05,0x02,0x80,0x03,0xd3,0x40,0x0a,0xe4,0xff,0x04,0xfe,0x7c,0x0a,0x12,0x31,0xfb,
+0x22,0xb4,0x01,0x02,0x80,0x03,0xd3,0x40,0x0a,0xe4,0xff,0x04,0xfe,0x7c,0x08,0x12,
+0x31,0xfb,0x22,0xb4,0x03,0x00,0x40,0x10,0xb4,0x05,0x00,0x50,0x0b,0xe5,0x4a,0x7f,
+0x00,0xfe,0x7c,0x13,0x12,0x31,0xfb,0x22,0x7d,0x00,0x7c,0x07,0x12,0x25,0x26,0x22,
+0xe5,0x6d,0x20,0xe7,0x34,0xd3,0xe5,0x72,0x94,0x48,0xe5,0x71,0x94,0x00,0x50,0x06,
+0xe5,0x72,0x45,0x71,0x70,0x06,0x7c,0x02,0x12,0x25,0xbf,0x22,0xe5,0x4a,0xb4,0x01,
+0x03,0xb3,0x40,0x0b,0xc3,0xb4,0x03,0x00,0x40,0x09,0xb4,0x06,0x00,0x50,0x04,0x12,
+0x30,0xd1,0x22,0x7c,0x07,0x12,0x25,0xbf,0x22,0x12,0x25,0x5d,0x22,0xe5,0x6d,0x20,
+0xe7,0x1d,0xe5,0x4a,0xb4,0x03,0x00,0x40,0x10,0xb4,0x05,0x00,0x50,0x0b,0xe5,0x4a,
+0x7f,0x00,0xfe,0x7c,0x16,0x12,0x31,0xfb,0x22,0x7c,0x07,0x12,0x25,0xbf,0x22,0x12,
+0x25,0x5d,0x22,0xe5,0x6d,0x20,0xe7,0x1d,0xe5,0x4a,0xb4,0x03,0x00,0x40,0x10,0xb4,
+0x05,0x00,0x50,0x0b,0xe5,0x4a,0x7f,0x00,0xfe,0x7c,0x19,0x12,0x31,0xfb,0x22,0x7c,
+0x07,0x12,0x25,0xbf,0x22,0x12,0x25,0x5d,0x22,0xe5,0x6d,0x20,0xe7,0x23,0x74,0x81,
+0x90,0xff,0x93,0xf0,0xe5,0x4a,0xb4,0x03,0x00,0x40,0x10,0xb4,0x05,0x00,0x50,0x0b,
+0xe5,0x4a,0x7f,0x00,0xfe,0x7c,0x17,0x12,0x31,0xfb,0x22,0x7c,0x07,0x12,0x25,0xbf,
+0x22,0x12,0x25,0x5d,0x22,0xe5,0x6d,0x20,0xe7,0x1d,0xe5,0x4a,0xb4,0x03,0x00,0x40,
+0x10,0xb4,0x05,0x00,0x50,0x0b,0xe5,0x4a,0x7f,0x00,0xfe,0x7c,0x18,0x12,0x31,0xfb,
+0x22,0x7c,0x07,0x12,0x25,0xbf,0x22,0x12,0x25,0x5d,0x22,0xe5,0x6d,0x20,0xe7,0x1d,
+0xe5,0x4a,0xb4,0x03,0x00,0x40,0x10,0xb4,0x05,0x00,0x50,0x0b,0xe5,0x4a,0x7f,0x00,
+0xfe,0x7c,0x15,0x12,0x31,0xfb,0x22,0x7c,0x07,0x12,0x25,0xbf,0x22,0x12,0x25,0x5d,
+0x22,0xe5,0x6d,0x20,0xe7,0x06,0x7c,0x07,0x12,0x25,0xbf,0x22,0x12,0x25,0x5d,0x22,
+0xe5,0x6d,0x30,0xe7,0x20,0x90,0xff,0x00,0xe0,0x54,0x1f,0x70,0x10,0x90,0xff,0x01,
+0xe0,0xb4,0x80,0x05,0x12,0x25,0x54,0x80,0x03,0x12,0x25,0x5d,0x22,0x7d,0x00,0x7c,
+0x05,0x12,0x25,0x26,0x22,0x90,0xff,0x00,0xe0,0x54,0x1f,0x60,0x06,0x7c,0x05,0x12,
+0x25,0xbf,0x22,0xd3,0xe5,0x72,0x94,0x48,0xe5,0x71,0x94,0x00,0x50,0x0b,0xc3,0xe5,
+0x72,0x94,0x07,0xe5,0x71,0x94,0x00,0x50,0x06,0x7c,0x03,0x12,0x25,0xbf,0x22,0xe5,
+0x4a,0xb4,0x05,0x04,0x12,0x30,0xd1,0x22,0x7c,0x07,0x12,0x25,0xbf,0x22,0xe5,0x6d,
+0x30,0xe7,0x08,0x7d,0x00,0x7c,0x05,0x12,0x25,0x26,0x22,0x7c,0x05,0x12,0x25,0xbf,
+0x22,0xb4,0x20,0x02,0x80,0x03,0xd3,0x40,0x00,0x80,0x00,0x12,0x2f,0xff,0x22,0x75,
+0x43,0x00,0x90,0xff,0x83,0xe0,0x54,0x0f,0xd3,0x95,0x43,0x40,0x24,0xe5,0x43,0x24,
+0xf0,0xf5,0x82,0xe4,0x34,0xfe,0xf5,0x83,0xe0,0xad,0x6a,0xae,0x69,0xaf,0x68,0x12,
+0x03,0x0f,0x05,0x43,0x0d,0xed,0x70,0x01,0x0e,0x8d,0x6a,0x8e,0x69,0x8f,0x68,0x80,
+0xd1,0xe5,0x43,0x7d,0x00,0xfc,0xc3,0xe5,0x70,0x9c,0xf5,0x70,0xe5,0x6f,0x9d,0xf5,
+0x6f,0xe5,0x70,0x45,0x6f,0x60,0x06,0xe4,0x90,0xff,0x83,0xf0,0x22,0x90,0xff,0x82,
+0xe0,0x44,0x08,0xf0,0xe4,0xf5,0x6f,0x75,0x70,0x49,0x90,0xfc,0x35,0xe0,0xb4,0x05,
+0x02,0x80,0x03,0xd3,0x40,0x40,0x90,0xfc,0x36,0xe0,0xf5,0x43,0xb4,0x05,0x02,0x80,
+0x03,0xd3,0x40,0x0a,0xe4,0xff,0x04,0xfe,0x7c,0x0b,0x12,0x31,0xfb,0x22,0xb4,0x01,
+0x02,0x80,0x03,0xd3,0x40,0x0a,0xe4,0xff,0x04,0xfe,0x7c,0x09,0x12,0x31,0xfb,0x22,
+0xb4,0x03,0x00,0x40,0x10,0xb4,0x05,0x00,0x50,0x0b,0xe5,0x43,0x7f,0x00,0xfe,0x7c,
+0x14,0x12,0x31,0xfb,0x22,0x22,0xb4,0x80,0x00,0x40,0x23,0xb4,0x82,0x00,0x50,0x1e,
+0x7c,0x35,0x7d,0xfc,0x12,0x17,0x7e,0x7d,0x00,0x8c,0x6c,0x8d,0x6b,0x90,0xfc,0x37,
+0xe0,0x60,0x05,0x12,0x2f,0xff,0x80,0x05,0x7c,0x00,0x12,0x30,0x24,0x22,0x22,0x90,
+0xff,0x83,0xe0,0x54,0x7f,0xf0,0x90,0xff,0x82,0xe0,0x44,0x08,0xf0,0x90,0xff,0x80,
+0xe0,0x44,0x08,0xf0,0x22,0x90,0xff,0x82,0xe0,0x44,0x08,0xf0,0x90,0xff,0x80,0xe0,
+0x44,0x08,0xf0,0x22,0x8c,0x23,0x7d,0x00,0x8c,0x70,0x8d,0x6f,0x75,0x6a,0x35,0x75,
+0x69,0xfc,0x75,0x68,0x01,0x12,0x30,0x39,0x22,0x90,0xff,0x83,0xe0,0x54,0x7f,0xf0,
+0xe5,0x70,0x64,0x49,0x45,0x6f,0x70,0x01,0x22,0xc3,0xe5,0x70,0x94,0x08,0xe5,0x6f,
+0x94,0x00,0x40,0x15,0x75,0x21,0x08,0xe5,0x21,0x7d,0x00,0xfc,0xc3,0xe5,0x70,0x9c,
+0xf5,0x70,0xe5,0x6f,0x9d,0xf5,0x6f,0x80,0x09,0x85,0x70,0x21,0xe4,0xf5,0x6f,0x75,
+0x70,0x49,0x75,0x22,0x00,0xe5,0x22,0xc3,0x95,0x21,0x50,0x26,0xad,0x6a,0xae,0x69,
+0xaf,0x68,0x12,0x01,0xe6,0xfc,0xe5,0x22,0x24,0xf8,0xf5,0x82,0xe4,0x34,0xfe,0xf5,
+0x83,0xec,0xf0,0x05,0x22,0x0d,0xed,0x70,0x01,0x0e,0x8d,0x6a,0x8e,0x69,0x8f,0x68,
+0x80,0xd3,0xe5,0x21,0x54,0x7f,0x90,0xff,0x81,0xf0,0x22,0x8c,0x48,0x7f,0x00,0xef,
+0x24,0xfd,0x40,0x19,0xe4,0xef,0x75,0xf0,0x07,0xa4,0x24,0x7f,0xf5,0x82,0xe4,0x34,
+0xf8,0xf5,0x83,0xe0,0x65,0x48,0x70,0x02,0xd3,0x22,0x0f,0x80,0xe2,0x8f,0x47,0xc3,
+0x22,0x85,0x72,0x70,0x85,0x71,0x6f,0x90,0xff,0x82,0xe0,0x54,0xf7,0xf0,0x90,0xff,
+0x83,0xe0,0x54,0x7f,0xf0,0x22,0xc0,0x00,0xc0,0x01,0xc0,0x02,0xc0,0x06,0xc0,0x07,
+0xe5,0x78,0x24,0x08,0xf8,0x86,0x06,0x53,0x06,0x7f,0x7c,0xff,0x12,0x31,0x5b,0x7c,
+0x00,0x7d,0x00,0xe5,0x7b,0x60,0x46,0xff,0x90,0xfd,0x95,0xe0,0x54,0x7f,0x6e,0x70,
+0x0f,0xc0,0x83,0xc0,0x82,0xa3,0xe0,0xfd,0xa3,0xe0,0xfc,0xa3,0x15,0x7b,0x80,0x07,
+0xa3,0xa3,0xa3,0xdf,0xe6,0x80,0x26,0xdf,0x06,0xd0,0x82,0xd0,0x83,0x80,0x1e,0xe0,
+0xf8,0xa3,0xe0,0xf9,0xa3,0xe0,0xfa,0xd0,0x82,0xd0,0x83,0xe8,0xf0,0xa3,0xe9,0xf0,
+0xa3,0xea,0xf0,0xa3,0xc0,0x83,0xc0,0x82,0xa3,0xa3,0xa3,0x80,0xda,0x12,0x31,0xf4,
+0xd0,0x07,0xd0,0x06,0xd0,0x02,0xd0,0x01,0xd0,0x00,0x22,0x85,0xa8,0x7a,0x75,0xa8,
+0x88,0xec,0x70,0x02,0x7c,0x3f,0x8c,0x79,0x22,0xe5,0x78,0x24,0x08,0xf8,0x76,0x00,
+0x12,0x32,0x48,0x80,0xfb,0xc0,0x00,0xc0,0x01,0xc0,0x02,0xc0,0x06,0xc0,0x07,0xae,
+0x04,0x7c,0xff,0x12,0x31,0x5b,0xe5,0x7b,0x60,0x42,0xff,0x90,0xfd,0x95,0xe0,0x54,
+0x7f,0x6e,0x70,0x0b,0xc0,0x83,0xc0,0x82,0xa3,0xa3,0xa3,0x15,0x7b,0x80,0x07,0xa3,
+0xa3,0xa3,0xdf,0xea,0x80,0x26,0xdf,0x06,0xd0,0x82,0xd0,0x83,0x80,0xd8,0xe0,0xf8,
+0xa3,0xe0,0xf9,0xa3,0xe0,0xfa,0xd0,0x82,0xd0,0x83,0xe8,0xf0,0xa3,0xe9,0xf0,0xa3,
+0xea,0xf0,0xa3,0xc0,0x83,0xc0,0x82,0xa3,0xa3,0xa3,0x80,0xda,0x78,0x08,0x08,0x79,
+0x18,0x09,0x7c,0x01,0xe6,0x54,0x7f,0x6e,0x70,0x06,0x76,0x00,0x77,0x00,0x80,0x06,
+0x08,0x09,0x0c,0xbc,0x08,0xee,0x12,0x31,0xf4,0xd0,0x07,0xd0,0x06,0xd0,0x02,0xd0,
+0x01,0xd0,0x00,0x22,0x75,0x79,0x00,0x85,0x7a,0xa8,0x22,0xc0,0xf0,0xc0,0x82,0xc0,
+0x83,0xc3,0xe5,0x7b,0x24,0xe8,0x50,0x05,0x12,0x32,0x48,0x80,0xf4,0xec,0x60,0x31,
+0x90,0x35,0x23,0xe4,0x93,0xc3,0x9c,0x40,0x28,0xc0,0x04,0x7c,0xff,0x12,0x31,0x5b,
+0xd0,0x04,0x43,0x04,0x80,0xe5,0x7b,0x75,0xf0,0x03,0xa4,0x24,0x95,0xf5,0x82,0xe4,
+0x34,0xfd,0xf5,0x83,0xec,0xf0,0xef,0xa3,0xf0,0xee,0xa3,0xf0,0x05,0x7b,0x12,0x31,
+0xf4,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0x22,0xc0,0x04,0x7c,0x20,0xd2,0x8c,0xd2,0x8d,
+0xd5,0x04,0xfd,0xd0,0x04,0x22,0x75,0xa8,0x00,0x75,0x88,0x00,0x75,0xb8,0x00,0x75,
+0xf0,0x00,0x75,0xd0,0x00,0xe4,0xf8,0x90,0x00,0x00,0xf6,0x08,0xb8,0x00,0xfb,0x02,
+0x00,0x00,0xc3,0xed,0x94,0x02,0x50,0x04,0x7d,0x03,0x7c,0xe8,0xec,0xf4,0xfc,0xed,
+0xf4,0xfd,0x0c,0xbc,0x00,0x01,0x0d,0x8c,0x7f,0x8d,0x7e,0x22,0xc3,0xec,0x94,0xbc,
+0xed,0x94,0x02,0x50,0x04,0x7d,0x07,0x7c,0xd0,0xec,0xf4,0xfc,0xed,0xf4,0xfd,0x0c,
+0xbc,0x00,0x01,0x0d,0x8c,0x7d,0x8d,0x7c,0x22,0xec,0x70,0x01,0x22,0xc0,0x00,0xe5,
+0x78,0x24,0x18,0xf8,0xa6,0x04,0xe5,0x78,0x24,0x08,0xf8,0xc6,0x54,0x7f,0xf6,0xe6,
+0x30,0xe7,0x03,0xd0,0x00,0x22,0x12,0x32,0x48,0x80,0xf4,0xc2,0x8c,0x85,0x7c,0x8c,
+0x85,0x7d,0x8a,0xd2,0x8c,0xc0,0xe0,0xc0,0xd0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,
+0x00,0xc0,0x01,0xc0,0x02,0xc0,0x03,0xc0,0x04,0xc0,0x05,0xc0,0x06,0xc0,0x07,0x12,
+0x1a,0xd1,0xe5,0x78,0x24,0x08,0xf8,0xe6,0x60,0x24,0xe5,0x78,0x24,0x10,0xf8,0xa6,
+0x81,0xe5,0x78,0x75,0xf0,0x21,0xa4,0x24,0x8d,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,
+0x78,0xae,0xe5,0x81,0x04,0xc3,0x98,0xf9,0xe6,0xf0,0x08,0xa3,0xd9,0xfa,0x74,0x08,
+0x25,0x78,0xf8,0x05,0x78,0x08,0xe6,0x54,0x80,0x70,0x0c,0xe5,0x78,0xb4,0x07,0xf3,
+0x78,0x08,0x75,0x78,0x00,0x80,0xef,0xe5,0x78,0x24,0x10,0xf8,0x86,0x81,0xe5,0x78,
+0x75,0xf0,0x21,0xa4,0x24,0x8d,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0x78,0xae,0xe5,
+0x81,0x04,0xc3,0x98,0xf9,0xe0,0xf6,0x08,0xa3,0xd9,0xfa,0xd0,0x07,0xd0,0x06,0xd0,
+0x05,0xd0,0x04,0xd0,0x03,0xd0,0x02,0xd0,0x01,0xd0,0x00,0xd0,0x83,0xd0,0x82,0xd0,
+0xf0,0xd0,0xd0,0xd0,0xe0,0x32,0xc0,0xe0,0xc0,0xd0,0xc0,0x00,0xc0,0x01,0xc0,0x02,
+0xc2,0x8e,0x85,0x7e,0x8d,0x85,0x7f,0x8b,0xd2,0x8e,0x78,0x19,0x79,0x09,0x7a,0x07,
+0xe7,0x70,0x04,0xa6,0x00,0x80,0x0b,0xe6,0x60,0x08,0x16,0xe6,0x70,0x04,0xe7,0x44,
+0x80,0xf7,0x08,0x09,0xda,0xea,0xe5,0x79,0x60,0x13,0x14,0xf5,0x79,0x70,0x0e,0xe5,
+0x78,0x24,0x08,0xf8,0x76,0x00,0x12,0x31,0xf4,0xd2,0x8c,0xd2,0x8d,0xd0,0x02,0xd0,
+0x01,0xd0,0x00,0xd0,0xd0,0xd0,0xe0,0x32,0x75,0x81,0xad,0x74,0x2a,0x90,0xff,0x93,
+0xf0,0x75,0x7f,0x30,0x75,0x7e,0xf8,0x75,0x7d,0x60,0x75,0x7c,0xf0,0x12,0x05,0x36,
+0x12,0x34,0x7c,0x12,0x17,0x34,0x90,0xff,0x93,0xe0,0x44,0x01,0xf0,0xb2,0xb3,0x12,
+0x34,0xa6,0x12,0x32,0x56,0x80,0xda,0x22,0xc0,0x00,0x7c,0x01,0xec,0x24,0x08,0xf8,
+0xe6,0x60,0x09,0x0c,0xbc,0x08,0xf5,0x12,0x32,0x48,0x80,0xee,0xd0,0x00,0x22,0xc0,
+0xf0,0xc0,0x82,0xc0,0x83,0xc0,0x00,0xc0,0x06,0xc0,0x07,0xed,0x24,0x10,0xf8,0x76,
+0xbc,0xed,0x75,0xf0,0x21,0xa4,0x24,0x8d,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xc0,
+0x82,0xc0,0x83,0xa3,0xa3,0xe4,0x78,0x0d,0xf0,0xa3,0xd8,0xfc,0xec,0x54,0x7f,0x75,
+0xf0,0x02,0xa4,0x24,0xef,0xf5,0x82,0xe5,0xf0,0x34,0x34,0xf5,0x83,0xe4,0x93,0xfe,
+0x74,0x01,0x93,0xf5,0x82,0x8e,0x83,0xe4,0x93,0xfe,0x74,0x01,0x93,0xff,0xd0,0x83,
+0xd0,0x82,0xef,0xf0,0xa3,0xee,0xf0,0xed,0x24,0x08,0xf8,0xec,0x44,0x80,0xf6,0xd0,
+0x07,0xd0,0x06,0xd0,0x00,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0x22,0x75,0x78,0x00,0x75,
+0x7b,0x00,0x7a,0x08,0x79,0x18,0x78,0x08,0x76,0x00,0x77,0x00,0x08,0x09,0xda,0xf8,
+0xe4,0x78,0x08,0x74,0x80,0x44,0x7f,0xf6,0x74,0x01,0x44,0x10,0xf5,0x89,0x75,0xb8,
+0x08,0xd2,0xab,0xd2,0xa9,0x22,0x75,0x81,0xad,0xd2,0x8e,0xd2,0x8c,0xd2,0xaf,0xe5,
+0x7b,0x60,0x32,0xff,0x90,0xfd,0x95,0xe0,0x54,0x80,0x60,0x24,0x78,0x08,0x79,0x08,
+0xe0,0x54,0x7f,0xfa,0x7b,0x00,0xe6,0x54,0x7f,0xb5,0x02,0x02,0x7b,0xff,0x08,0xd9,
+0xf5,0xeb,0x70,0x0c,0xea,0xf0,0x12,0x33,0xf8,0xad,0x04,0xac,0x02,0x12,0x34,0x0f,
+0xa3,0xa3,0xa3,0xdf,0xd2,0x12,0x32,0x48,0x80,0xc5,0x7c,0x01,0x7d,0x00,0x22,0x04,
+0xf5,0x04,0xe9,0x04,0xed,0x04,0xe1,0x04,0xdd,0x04,0xd9,0x04,0xe5,0x04,0xf1,0x04,
+0x9d,0x04,0xa1,0x04,0xcd,0x04,0xd1,0x04,0x99,0x04,0x99,0x04,0x99,0x04,0xd5,0x04,
+0xb5,0x04,0xad,0x04,0xb1,0x04,0xa9,0x04,0xc1,0x04,0xbd,0x04,0xb9,0x04,0xc5,0x04,
+0xc9,0x04,0xa5,0x19,0x01,0x03,0x00,0x22,0x00,0x48,0x02,0x00,0x48,0x0e,0x30,0x14,
+0x20,0xc8,0x1a,0xd0,0x18,0x0a,0x0c,0x05,0x06,0x02,0x03,0x01,0x02,0x00,0x01,0xce,
+0x01,0x81,0x01,0x00,0x00,0xc0,0x00,0x80,0x00,0x60,0x00,0x30,0x00,0x18,0x00,0x10,
+0x00,0x08,0x00,0x04,0x00,0x02,0x00,0x01,0x00,0x08,0x18,0x38,0x28,0x0c,0x05,0x10,
+0x0a,0x02,0x00,0x00,0x00,0x00,0x00,0x03,0x01,0x10,0x0a,0x02,0x00,0x00,0x00,0x00,
+0x00,0xfb,0xe0,0xfb,0xf2,0x09,0x02,0x27,0x00,0x01,0x02,0x00,0xa0,0x32,0x09,0x04,
+0x00,0x00,0x03,0xff,0x00,0x00,0x00,0x07,0x05,0x81,0x02,0x40,0x00,0x00,0x07,0x05,
+0x01,0x02,0x40,0x00,0x00,0x07,0x05,0x83,0x03,0x02,0x00,0x01,0x22,0x03,0x54,0x00,
+0x55,0x00,0x53,0x00,0x42,0x00,0x33,0x00,0x34,0x00,0x31,0x00,0x30,0x00,0x20,0x00,
+0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x00,0x00,
+0x00,0x00,
+};
+
+#endif /* ifndef _TI_FW_3410_H_ */
diff -Nru a/drivers/usb/serial/ti_fw_5052.h b/drivers/usb/serial/ti_fw_5052.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/usb/serial/ti_fw_5052.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,885 @@
+/* vi: ts=8 sw=8
+ *
+ * TI 5052 USB Serial Driver Firmware Header
+ *
+ * Copyright (C) 2004 Texas Instruments
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the 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 _TI_FW_5052_H_
+#define _TI_FW_5052_H_
+
+/* firmware 9/18/04 */
+
+static unsigned char ti_fw_5052[] = {
+0xC1, 0x35,	/* firmware image length excluding header, little endian */
+0x00, 		/* placeholder for checksum */
+
+0x02,0x00,0x1e,0x02,0x1b,0x32,0xff,0xff,0xff,0xff,0xff,0x02,0x32,0x6a,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x02,0x33,0x15,0x75,0x81,
+0xc8,0x90,0xfe,0xf0,0x85,0x83,0xa0,0x12,0x34,0x7d,0xec,0x4d,0x60,0x6a,0x78,0xa5,
+0x80,0x03,0x76,0x00,0x18,0xb8,0x96,0xfa,0x78,0x79,0x80,0x03,0x76,0x00,0x18,0xb8,
+0x5f,0xfa,0x78,0x20,0x80,0x03,0x76,0x00,0x18,0xb8,0x20,0xfa,0x90,0xfe,0xe5,0xae,
+0x83,0xaf,0x82,0x90,0xfd,0x00,0x12,0x00,0xa1,0x60,0x05,0xe4,0xf0,0xa3,0x80,0xf6,
+0x90,0xfe,0xf0,0xa8,0x82,0x90,0xfe,0xf0,0xa9,0x82,0xe8,0xc3,0x99,0x50,0x05,0x76,
+0x00,0x08,0x80,0xf6,0x90,0x00,0xff,0x12,0x00,0xaa,0x90,0x01,0x03,0x12,0x00,0xaa,
+0x90,0x01,0x07,0x12,0x00,0xaa,0x90,0x01,0x0b,0x12,0x00,0xc8,0x90,0x01,0x11,0x12,
+0x00,0xc8,0x90,0x01,0x17,0x12,0x00,0xc8,0x75,0xd0,0x00,0x12,0x33,0x67,0x02,0x01,
+0x1d,0xef,0x65,0x82,0x70,0x03,0xee,0x65,0x83,0x22,0xe4,0x93,0xf8,0x74,0x01,0x93,
+0xf9,0x74,0x02,0x93,0xfe,0x74,0x03,0x93,0xf5,0x82,0x8e,0x83,0xe8,0x69,0x70,0x01,
+0x22,0xe4,0x93,0xf6,0xa3,0x08,0x80,0xf4,0xe4,0x93,0xfc,0x74,0x01,0x93,0xfd,0x74,
+0x02,0x93,0xfe,0x74,0x03,0x93,0xff,0x74,0x04,0x93,0xf8,0x74,0x05,0x93,0xf5,0x82,
+0x88,0x83,0x12,0x00,0xa1,0x70,0x01,0x22,0xe4,0x93,0xa3,0xa8,0x83,0xa9,0x82,0x8c,
+0x83,0x8d,0x82,0xf0,0xa3,0xac,0x83,0xad,0x82,0x88,0x83,0x89,0x82,0x80,0xe3,0x21,
+0x21,0x04,0x92,0x7a,0x7a,0x04,0x92,0xa6,0xa8,0x04,0x92,0xfe,0xf0,0x04,0x94,0x04,
+0x94,0xfb,0xfb,0x04,0x99,0x04,0x94,0xfb,0xfb,0x04,0xf9,0x04,0xf9,0x80,0xfe,0xd0,
+0xf0,0x30,0xf0,0x09,0x20,0xf3,0x03,0xf6,0x80,0x10,0xf7,0x80,0x0d,0x30,0xf1,0x09,
+0x20,0xf3,0x03,0xf2,0x80,0x04,0xf3,0x80,0x01,0xf0,0x20,0xf4,0x04,0xfc,0xd0,0xe0,
+0xcc,0x22,0xcc,0xc0,0xe0,0x12,0x01,0x5a,0x02,0x01,0x4b,0xbc,0x00,0x05,0xd0,0xf0,
+0xac,0xf0,0x22,0xc3,0x13,0xdc,0xfc,0x02,0x01,0x21,0xbf,0x00,0x09,0xed,0x25,0x82,
+0x75,0xf0,0x01,0xf8,0xe6,0x22,0xbf,0x01,0x0f,0xed,0x25,0x82,0xf5,0x82,0xee,0x35,
+0x83,0xf5,0x83,0x75,0xf0,0x04,0xe0,0x22,0xed,0x25,0x82,0x75,0xf0,0x02,0xf8,0xe2,
+0x22,0xd0,0x83,0xd0,0x82,0xf5,0xf0,0xc3,0xe4,0x93,0xa3,0xc5,0xf0,0x95,0xf0,0xc0,
+0xe0,0xc3,0xd0,0xf0,0xe4,0x93,0xa3,0x95,0xf0,0x40,0x12,0xa3,0xa3,0xc3,0xe5,0xf0,
+0x33,0x50,0x02,0x05,0x83,0x25,0x82,0xf5,0x82,0x50,0x02,0x05,0x83,0x74,0x01,0x93,
+0xc0,0xe0,0xe4,0x93,0xc0,0xe0,0x22,0xd0,0x83,0xd0,0x82,0xf5,0xf0,0xe4,0x93,0x70,
+0x09,0x74,0x01,0x93,0x70,0x04,0xa3,0xa3,0x80,0x0c,0x74,0x02,0x93,0x65,0xf0,0x60,
+0x05,0xa3,0xa3,0xa3,0x80,0xe7,0x74,0x01,0x93,0xc0,0xe0,0xe4,0x93,0xc0,0xe0,0x22,
+0x12,0x02,0x5b,0x02,0x01,0xf2,0x12,0x02,0xaf,0x02,0x01,0xf2,0x12,0x02,0xd3,0x02,
+0x01,0xf2,0x30,0xe0,0x07,0x20,0xe3,0x02,0xe6,0x22,0xe7,0x22,0x30,0xe1,0x07,0x20,
+0xe3,0x02,0xe2,0x22,0xe3,0x22,0x30,0xe2,0x02,0xe0,0x22,0xe4,0x93,0x22,0x12,0x02,
+0xd3,0x02,0x02,0x1a,0x12,0x02,0xaf,0x02,0x02,0x1a,0xab,0xf0,0x12,0x02,0x24,0xcb,
+0xc5,0xf0,0xcb,0x22,0x30,0xe0,0x10,0x20,0xe3,0x06,0xe6,0xf5,0xf0,0x08,0xe6,0x22,
+0xe7,0xf5,0xf0,0x09,0xe7,0x19,0x22,0x30,0xe1,0x10,0x20,0xe3,0x06,0xe2,0xf5,0xf0,
+0x08,0xe2,0x22,0xe3,0xf5,0xf0,0x09,0xe3,0x19,0x22,0x30,0xe2,0x06,0xe0,0xf5,0xf0,
+0xa3,0xe0,0x22,0xe4,0x93,0xf5,0xf0,0x74,0x01,0x93,0x22,0xbb,0x00,0x03,0x74,0x09,
+0x22,0xbb,0x01,0x07,0x89,0x82,0x8a,0x83,0x74,0x04,0x22,0xbb,0x02,0x07,0x89,0x82,
+0x8a,0x83,0x74,0x10,0x22,0x74,0x0a,0x22,0x02,0x02,0x7b,0xbb,0x00,0x07,0xe9,0x25,
+0x82,0xf8,0x74,0x01,0x22,0xbb,0x01,0x0d,0xe9,0x25,0x82,0xf5,0x82,0xea,0x35,0x83,
+0xf5,0x83,0x74,0x04,0x22,0xbb,0x02,0x0d,0xe9,0x25,0x82,0xf5,0x82,0xea,0x35,0x83,
+0xf5,0x83,0x74,0x10,0x22,0xe9,0x25,0x82,0xf8,0x74,0x02,0x22,0x02,0x02,0xaf,0xbf,
+0x00,0x05,0xed,0xf8,0x74,0x01,0x22,0xbf,0x01,0x07,0x8d,0x82,0x8e,0x83,0x74,0x04,
+0x22,0xbf,0x02,0x07,0x8d,0x82,0x8e,0x83,0x74,0x10,0x22,0xed,0xf8,0x74,0x02,0x22,
+0x02,0x02,0xd3,0xbf,0x00,0x07,0xed,0x25,0x82,0xf8,0x74,0x01,0x22,0xbf,0x01,0x0d,
+0xed,0x25,0x82,0xf5,0x82,0xee,0x35,0x83,0xf5,0x83,0x74,0x04,0x22,0xbf,0x02,0x0d,
+0xed,0x25,0x82,0xf5,0x82,0xee,0x35,0x83,0xf5,0x83,0x74,0x10,0x22,0xed,0x25,0x82,
+0xf8,0x74,0x02,0x22,0x02,0x03,0x07,0xc0,0xe0,0x12,0x02,0x5b,0x02,0x03,0x1f,0xc0,
+0xe0,0x12,0x02,0xaf,0x02,0x03,0x1f,0xc0,0xe0,0x12,0x02,0xd3,0x02,0x03,0x1f,0x30,
+0xe0,0x0b,0x20,0xe3,0x04,0xd0,0xe0,0xf6,0x22,0xd0,0xe0,0xf7,0x22,0x30,0xe1,0x0b,
+0x20,0xe3,0x04,0xd0,0xe0,0xf2,0x22,0xd0,0xe0,0xf3,0x22,0xd0,0xe0,0xf0,0x22,0xc9,
+0xcd,0xc9,0xca,0xce,0xca,0xcb,0xcf,0xcb,0x12,0x03,0x52,0xed,0xf9,0xee,0xfa,0xef,
+0xfb,0x22,0xbb,0x00,0x2f,0xbf,0x00,0x0a,0xfa,0xed,0xf8,0xe7,0xf6,0x08,0x09,0xda,
+0xfa,0x22,0xbf,0x01,0x12,0x8d,0x82,0x8e,0x83,0xf8,0x02,0x03,0x6f,0x09,0xa3,0xe7,
+0xf0,0xd8,0xfa,0x22,0x02,0x03,0x7a,0xfa,0xed,0xf8,0xe7,0xf2,0x08,0x09,0xda,0xfa,
+0x22,0x02,0x03,0x84,0xbb,0x01,0x4d,0xbf,0x00,0x14,0x89,0x82,0x8a,0x83,0xf9,0xed,
+0xf8,0x02,0x03,0x96,0x08,0xa3,0xe0,0xf6,0xd9,0xfa,0x22,0x02,0x03,0xa7,0xbf,0x01,
+0x22,0x8d,0x82,0x8e,0x83,0xfb,0x08,0xc9,0xc5,0x82,0xc9,0xca,0xc5,0x83,0xca,0xe0,
+0xa3,0xc9,0xc5,0x82,0xc9,0xca,0xc5,0x83,0xca,0xf0,0xa3,0xdb,0xea,0xd8,0xe8,0x22,
+0x02,0x03,0xca,0x8d,0x82,0x8e,0x83,0xf9,0xed,0xf8,0xe0,0xf2,0x08,0xa3,0xd9,0xfa,
+0x22,0x02,0x03,0xd4,0xbb,0x02,0x4d,0xbf,0x00,0x12,0x89,0x82,0x8a,0x83,0xf9,0xed,
+0xf8,0x02,0x03,0xe6,0x08,0xa3,0xe4,0x93,0xf6,0xd9,0xf9,0x22,0xbf,0x01,0x23,0x8d,
+0x82,0x8e,0x83,0xfb,0x08,0xc9,0xc5,0x82,0xc9,0xca,0xc5,0x83,0xca,0xe4,0x93,0xa3,
+0xc9,0xc5,0x82,0xc9,0xca,0xc5,0x83,0xca,0xf0,0xa3,0xdb,0xe9,0xd8,0xe7,0x22,0x02,
+0x04,0x19,0x89,0x82,0x8a,0x83,0xf9,0xed,0xf8,0xe4,0x93,0xf2,0x08,0xa3,0xd9,0xf9,
+0x22,0x02,0x04,0x2a,0xbf,0x00,0x0d,0xfa,0xed,0xf8,0xe3,0xf6,0x08,0x09,0xda,0xfa,
+0x22,0x02,0x04,0x34,0xbf,0x01,0x12,0x8d,0x82,0x8e,0x83,0xf8,0x02,0x04,0x41,0x09,
+0xa3,0xe3,0xf0,0xd8,0xfa,0x22,0x02,0x04,0x4c,0xfa,0xed,0xf8,0xe3,0xf2,0x08,0x09,
+0xda,0xfa,0x22,0x02,0x04,0x56,0xe6,0xfb,0x08,0xe6,0xfa,0x08,0xe6,0xf9,0x04,0xf6,
+0x18,0x70,0x01,0x06,0x22,0xe6,0xff,0x08,0xe6,0xfe,0x08,0xe6,0xfd,0x22,0xef,0xf0,
+0xa3,0xee,0xf0,0xa3,0xed,0xf0,0x22,0xeb,0xf0,0xa3,0xea,0xf0,0xa3,0xe9,0xf0,0x22,
+0xe0,0xff,0xa3,0xe0,0xfe,0xa3,0xe0,0xfd,0x22,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,
+0xf9,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0xf9,0x00,0x5b,0x05,0x73,0x00,
+0x26,0x05,0x9a,0x00,0x33,0x0a,0x0b,0x00,0x5b,0x0a,0x77,0x00,0x60,0x15,0x52,0x00,
+0x5b,0x0c,0xfb,0x00,0x5b,0x09,0xab,0x00,0x5b,0x09,0xe2,0x00,0x5b,0x0d,0xc2,0x00,
+0x5b,0x0b,0xf3,0x00,0x5b,0x0a,0x1e,0x00,0x5b,0x0a,0x53,0x00,0x5b,0x17,0x4a,0x00,
+0x33,0x17,0x60,0x00,0x34,0x1e,0x4d,0x00,0x43,0x1e,0xf0,0x00,0x44,0x20,0x5d,0x00,
+0x44,0x20,0x4b,0x00,0x47,0x1f,0x17,0x00,0x47,0x1f,0xbc,0x00,0x4d,0x20,0x0d,0x00,
+0x4f,0x1f,0x39,0x00,0x58,0x31,0xf5,0x00,0x5b,0x7c,0xcc,0x7d,0xff,0x12,0x1c,0xfe,
+0x22,0x74,0x90,0x90,0xff,0x91,0xf0,0x90,0xff,0xfc,0xe0,0x20,0xe7,0x2d,0xc2,0xaf,
+0xae,0x59,0xaf,0x58,0x75,0x5a,0x20,0xe5,0x5a,0x14,0xc5,0x5a,0x60,0x19,0xe4,0xfe,
+0x7f,0x05,0xee,0x4f,0xce,0x24,0xff,0xce,0xcf,0x34,0xff,0xcf,0x60,0x07,0xe4,0x90,
+0xff,0x92,0xf0,0x80,0xed,0x80,0xe0,0x8e,0x59,0x8f,0x58,0x22,0x12,0x05,0x01,0x7d,
+0x07,0x7c,0xb7,0x12,0x32,0x11,0x7d,0x0f,0x7c,0x6e,0x12,0x32,0x2b,0x78,0x97,0x7a,
+0x06,0xe4,0xf6,0x08,0xda,0xfc,0x7a,0x06,0x12,0x05,0xcf,0x7c,0x03,0x12,0x0e,0x57,
+0x7c,0x04,0x12,0x0e,0x57,0x12,0x21,0x8b,0xe4,0xfe,0xff,0x7c,0x0f,0x12,0x31,0x9a,
+0xd2,0xa8,0x22,0x12,0x30,0x85,0xe4,0x90,0xfd,0x40,0xf0,0x90,0xff,0xf0,0xe0,0x30,
+0xe4,0x08,0x74,0x01,0x90,0xfd,0x41,0xf0,0x80,0x05,0xe4,0x90,0xfd,0x41,0xf0,0x7d,
+0x0a,0x7c,0x00,0x12,0x24,0xb1,0x12,0x31,0x08,0x22,0x12,0x30,0x85,0x90,0xfd,0x41,
+0xe0,0x14,0x70,0x0e,0x90,0xff,0xf0,0xe0,0x44,0x10,0xf0,0x7c,0x00,0x12,0x25,0x4a,
+0x80,0x19,0x90,0xfd,0x41,0xe0,0x70,0x0e,0x90,0xff,0xf0,0xe0,0x54,0xef,0xf0,0x7c,
+0x00,0x12,0x25,0x4a,0x80,0x05,0x7c,0x17,0x12,0x25,0x4a,0x12,0x31,0x08,0x22,0x90,
+0xff,0xf0,0xe0,0x54,0xab,0xf0,0x90,0xff,0xf0,0xe0,0x44,0x20,0xf0,0x22,0x8c,0x37,
+0x8d,0x36,0x78,0x7c,0xed,0xf6,0x08,0xec,0xf6,0xed,0xfe,0xec,0xfd,0x7f,0x01,0x90,
+0x00,0x05,0x12,0x01,0xec,0x78,0x7a,0xf6,0x78,0x7c,0xe6,0xfd,0x08,0xe6,0xfc,0xed,
+0xfe,0xec,0xfd,0x7f,0x01,0x90,0x00,0x04,0x12,0x01,0xec,0x54,0x0f,0xfc,0x7d,0x7a,
+0x12,0x17,0x9d,0x78,0x7a,0xe6,0x70,0x0d,0xad,0x3a,0xae,0x39,0xaf,0x38,0xe4,0x12,
+0x03,0x0f,0x7c,0x08,0x22,0x90,0xff,0xf0,0xe0,0x54,0xfe,0xf0,0x90,0xff,0xf0,0xe0,
+0x54,0xfd,0xf0,0x80,0x1e,0x78,0x7c,0xe6,0xfd,0x08,0xe6,0xfc,0xed,0xfe,0xec,0xfd,
+0x7f,0x01,0x90,0x00,0x08,0x12,0x02,0x0e,0x25,0xe0,0x44,0x01,0x90,0xff,0xf3,0xf0,
+0x02,0x06,0xdb,0x78,0x7c,0xe6,0xfd,0x08,0xe6,0xfc,0xed,0xfe,0xec,0xfd,0x7f,0x01,
+0x90,0x00,0x06,0x12,0x02,0x0e,0x54,0xfe,0x90,0xff,0xf3,0xf0,0x80,0x2b,0x78,0x7c,
+0xe6,0xfd,0x08,0xe6,0xfc,0xed,0xfe,0xec,0xfd,0x7f,0x01,0x90,0x00,0x08,0x12,0x02,
+0x0e,0xfa,0xeb,0x90,0xff,0xf1,0xf0,0x12,0x08,0xca,0x40,0x0d,0xad,0x3a,0xae,0x39,
+0xaf,0x38,0xe4,0x12,0x03,0x0f,0x7c,0x18,0x22,0x78,0x7c,0xe6,0xfd,0x08,0xe6,0xfc,
+0xed,0xfe,0xec,0xfd,0x7f,0x01,0x90,0x00,0x08,0x12,0x02,0x0e,0x90,0xff,0xf1,0xf0,
+0x12,0x08,0xca,0x40,0x0d,0xad,0x3a,0xae,0x39,0xaf,0x38,0xe4,0x12,0x03,0x0f,0x7c,
+0x18,0x22,0x78,0x7c,0xe6,0xfd,0x08,0xe6,0xfc,0xed,0xfe,0xec,0xfd,0x7f,0x01,0x90,
+0x00,0x06,0x12,0x02,0x0e,0x44,0x01,0x90,0xff,0xf3,0xf0,0x78,0x7d,0xe6,0x24,0x03,
+0xf6,0x18,0xe6,0x34,0x00,0xf6,0x78,0x7a,0xe6,0x24,0xfe,0x50,0x09,0x90,0xff,0xf0,
+0xe0,0x54,0xfd,0xf0,0x80,0x07,0x90,0xff,0xf0,0xe0,0x44,0x02,0xf0,0xe4,0x90,0xff,
+0xf1,0xf0,0x78,0x7b,0x76,0x00,0x78,0x7a,0xe6,0x24,0xff,0xfc,0xe4,0x34,0xff,0xfd,
+0x78,0x7b,0xe6,0x7f,0x00,0xfe,0xec,0xd3,0x9e,0xef,0x64,0x80,0xcd,0x64,0x80,0x9d,
+0x40,0x2f,0x12,0x08,0xaf,0x40,0x0f,0x78,0x7b,0xe6,0xad,0x3a,0xae,0x39,0xaf,0x38,
+0x12,0x03,0x0f,0x7c,0x18,0x22,0x90,0xff,0xf2,0xe0,0xfc,0x78,0x7c,0x86,0x83,0x08,
+0x86,0x82,0xec,0xf0,0x78,0x7b,0x06,0xa3,0x78,0x7c,0xa6,0x83,0x08,0xa6,0x82,0x80,
+0xb5,0x12,0x08,0xaf,0x40,0x0f,0x78,0x7b,0xe6,0xad,0x3a,0xae,0x39,0xaf,0x38,0x12,
+0x03,0x0f,0x7c,0x18,0x22,0x90,0xff,0xf2,0xe0,0xfc,0x78,0x7c,0x86,0x83,0x08,0x86,
+0x82,0xec,0xf0,0x78,0x7a,0xe6,0xad,0x3a,0xae,0x39,0xaf,0x38,0x12,0x03,0x0f,0x7c,
+0x00,0x22,0x8c,0x37,0x8d,0x36,0x78,0x7c,0xed,0xf6,0x08,0xec,0xf6,0xed,0xfe,0xec,
+0xfd,0x7f,0x01,0x90,0x00,0x05,0x12,0x01,0xec,0x78,0x7b,0xf6,0x78,0x7c,0xe6,0xfd,
+0x08,0xe6,0xfc,0xed,0xfe,0xec,0xfd,0x7f,0x01,0x90,0x00,0x04,0x12,0x01,0xec,0x54,
+0x0f,0xfc,0x7d,0x7b,0x12,0x17,0x9d,0x78,0x7b,0xe6,0x70,0x03,0x7c,0x08,0x22,0x90,
+0xff,0xf0,0xe0,0x54,0xfe,0xf0,0x90,0xff,0xf0,0xe0,0x54,0xfd,0xf0,0x80,0x1b,0x78,
+0x7c,0xe6,0xfd,0x08,0xe6,0xfc,0xed,0xfe,0xec,0xfd,0x7f,0x01,0x90,0x00,0x08,0x12,
+0x02,0x0e,0x25,0xe0,0x90,0xff,0xf3,0xf0,0x80,0x5b,0x78,0x7c,0xe6,0xfd,0x08,0xe6,
+0xfc,0xed,0xfe,0xec,0xfd,0x7f,0x01,0x90,0x00,0x06,0x12,0x02,0x0e,0x54,0xfe,0x90,
+0xff,0xf3,0xf0,0x80,0x21,0x78,0x7c,0xe6,0xfd,0x08,0xe6,0xfc,0xed,0xfe,0xec,0xfd,
+0x7f,0x01,0x90,0x00,0x08,0x12,0x02,0x0e,0xfa,0xeb,0x90,0xff,0xf1,0xf0,0x12,0x08,
+0xca,0x40,0x03,0x7c,0x18,0x22,0x78,0x7c,0xe6,0xfd,0x08,0xe6,0xfc,0xed,0xfe,0xec,
+0xfd,0x7f,0x01,0x90,0x00,0x08,0x12,0x02,0x0e,0x90,0xff,0xf1,0xf0,0x12,0x08,0xca,
+0x40,0x03,0x7c,0x18,0x22,0x78,0x7d,0xe6,0x24,0x0a,0xf6,0x18,0xe6,0x34,0x00,0xf6,
+0x78,0x7a,0x76,0x00,0x78,0x7b,0xe6,0x24,0xff,0xfc,0xe4,0x34,0xff,0xfd,0x78,0x7a,
+0xe6,0x7f,0x00,0xfe,0xec,0xd3,0x9e,0xef,0x64,0x80,0xcd,0x64,0x80,0x9d,0x40,0x21,
+0x78,0x7c,0x86,0x83,0x08,0x86,0x82,0xe0,0x90,0xff,0xf1,0xf0,0x12,0x08,0xca,0x40,
+0x03,0x7c,0x18,0x22,0x78,0x7a,0x06,0x78,0x7d,0x06,0xe6,0x18,0x70,0x01,0x06,0x80,
+0xc3,0x90,0xff,0xf0,0xe0,0x44,0x01,0xf0,0x78,0x7c,0x86,0x83,0x08,0x86,0x82,0xe0,
+0x90,0xff,0xf1,0xf0,0x12,0x08,0xca,0x40,0x03,0x7c,0x18,0x22,0x7c,0x00,0x22,0x90,
+0xff,0xf0,0xe0,0x20,0xe7,0x12,0x90,0xff,0xf0,0xe0,0x30,0xe5,0x09,0x90,0xff,0xf0,
+0xe0,0x44,0x20,0xf0,0xc3,0x22,0x80,0xe7,0xd3,0x22,0x90,0xff,0xf0,0xe0,0x20,0xe3,
+0x12,0x90,0xff,0xf0,0xe0,0x30,0xe5,0x09,0x90,0xff,0xf0,0xe0,0x44,0x20,0xf0,0xc3,
+0x22,0x80,0xe7,0xd3,0x22,0x8c,0x42,0x8d,0x41,0x7c,0x00,0xed,0x54,0xf0,0xfd,0xec,
+0x70,0x03,0xed,0x64,0x30,0x70,0x05,0x75,0x3e,0x03,0x80,0x03,0x75,0x3e,0x04,0xac,
+0x3e,0x12,0x0f,0x7c,0x75,0x83,0x00,0x85,0x83,0x40,0xe5,0x41,0x54,0x0f,0xf5,0x3f,
+0xe5,0x40,0x70,0x04,0xe5,0x3f,0x64,0x03,0x70,0x35,0xe5,0x3e,0x24,0xfd,0x75,0xf0,
+0x0a,0xa4,0x24,0x0a,0xf5,0x82,0xe4,0x34,0xfd,0xf5,0x83,0xe0,0x30,0xe6,0x05,0x12,
+0x10,0x67,0x80,0x19,0xe5,0x3e,0x24,0x97,0xf8,0xc6,0x54,0xfb,0xf6,0x78,0xa3,0xe6,
+0x24,0x05,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0x74,0x0f,0xf0,0x80,0x59,0xe5,
+0x40,0x70,0x04,0xe5,0x3f,0x64,0x04,0x70,0x48,0xe5,0x3e,0x24,0xfd,0x75,0xf0,0x0a,
+0xa4,0x24,0x0a,0xf5,0x82,0xe4,0x34,0xfd,0xf5,0x83,0xe0,0x30,0xe5,0x07,0xac,0x42,
+0xad,0x41,0x12,0x1c,0x93,0xe5,0x42,0x30,0xe2,0x15,0x78,0xa7,0xe6,0x30,0xe0,0x0f,
+0x78,0xa7,0xe6,0x30,0xe1,0x09,0xe4,0xff,0x04,0xfe,0x7c,0x04,0x12,0x31,0x9a,0x78,
+0xa3,0xe6,0x24,0x06,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0x74,0x0f,0xf0,0x80,
+0x07,0xe4,0xfc,0x7d,0xee,0x12,0x1c,0x93,0xc2,0x03,0x22,0x12,0x30,0x85,0x12,0x0f,
+0x7c,0x78,0xa3,0xe6,0x24,0x06,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x90,
+0xfd,0x40,0xf0,0x78,0xa3,0xe6,0x24,0x05,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,
+0xe0,0x90,0xfd,0x41,0xf0,0xc2,0x03,0x7d,0x02,0x7c,0x00,0x12,0x24,0xb1,0x12,0x31,
+0x08,0x22,0x12,0x30,0x85,0x78,0x8f,0xec,0xf6,0xec,0x24,0x97,0xf8,0xe6,0x30,0xe1,
+0x07,0x7c,0x13,0x12,0x25,0x4a,0x80,0x0f,0x90,0xfd,0x41,0xe0,0xfd,0x78,0x8f,0xe6,
+0xfc,0x12,0x13,0xfd,0x12,0x25,0x4a,0x12,0x31,0x08,0x22,0x12,0x30,0x85,0x78,0x8f,
+0xec,0xf6,0x7d,0x00,0x12,0x0f,0x0b,0x12,0x25,0x4a,0x12,0x31,0x08,0x22,0x12,0x30,
+0x85,0x78,0x8f,0xec,0xf6,0xec,0x24,0x97,0xf8,0xe6,0x30,0xe2,0x07,0x7c,0x13,0x12,
+0x25,0x4a,0x80,0x1b,0x78,0x8f,0xe6,0x24,0x97,0xf8,0xe6,0x20,0xe1,0x07,0x7c,0x12,
+0x12,0x25,0x4a,0x80,0x0a,0x78,0x8f,0xe6,0xfc,0x12,0x14,0x21,0x12,0x25,0x4a,0x12,
+0x31,0x08,0x22,0x12,0x30,0x85,0x78,0x8f,0xec,0xf6,0xec,0x24,0x97,0xf8,0xe6,0x20,
+0xe2,0x07,0x7c,0x11,0x12,0x25,0x4a,0x80,0x0a,0x78,0x8f,0xe6,0xfc,0x12,0x15,0x22,
+0x12,0x25,0x4a,0x12,0x31,0x08,0x22,0x12,0x30,0x85,0x78,0x8f,0xec,0xf6,0x12,0x0f,
+0x7c,0x78,0xa3,0xe6,0x24,0x09,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x90,
+0xfd,0x47,0xf0,0x78,0xa3,0xe6,0x24,0x0a,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,
+0xe0,0x90,0xfd,0x48,0xf0,0x78,0xa3,0xe6,0x24,0x03,0xf5,0x82,0x18,0xe6,0x34,0x00,
+0xf5,0x83,0xe0,0xfc,0x78,0xa3,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,
+0x83,0xe0,0xf5,0x5c,0x78,0xa3,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,
+0x83,0xe0,0xf5,0x5d,0x8c,0x5b,0xe4,0xec,0x33,0x33,0x54,0x01,0x78,0x8f,0xf6,0x60,
+0x08,0xe5,0x5c,0x30,0xe1,0x03,0x78,0x8f,0x06,0x78,0x8f,0xe6,0x90,0xfd,0x49,0xf0,
+0x78,0xa1,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0xfd,0xa3,
+0xe0,0x54,0x0c,0xfc,0xed,0x54,0xe6,0x8c,0x5f,0xf5,0x5e,0xe5,0x5b,0x30,0xe5,0x03,
+0x43,0x5f,0x01,0xe5,0x5c,0x20,0xe5,0x0e,0xe5,0x5b,0x54,0x7f,0x70,0x08,0xe5,0x5b,
+0x20,0xe7,0x03,0x43,0x5f,0x02,0xe5,0x5b,0x30,0xe3,0x03,0x43,0x5f,0x10,0xe5,0x5b,
+0x30,0xe2,0x03,0x43,0x5f,0x20,0xe5,0x5b,0x54,0x03,0x60,0x03,0x43,0x5f,0x40,0xe5,
+0x5b,0x30,0xe1,0x03,0x43,0x5f,0x80,0xe5,0x5b,0x30,0xe4,0x03,0x43,0x5e,0x01,0xe5,
+0x5b,0x30,0xe6,0x03,0x43,0x5e,0x08,0xe5,0x5c,0x20,0xe4,0x0e,0xe5,0x5b,0x54,0x7f,
+0x70,0x08,0xe5,0x5b,0x20,0xe7,0x03,0x43,0x5e,0x10,0x53,0x5f,0xfb,0x53,0x5e,0xf9,
+0xad,0x5e,0xe5,0x5f,0x90,0xfd,0x42,0xcd,0xf0,0xa3,0xcd,0xf0,0xe5,0x5d,0x30,0xe3,
+0x0d,0xe5,0x5d,0x54,0x30,0xc4,0x54,0x0f,0x90,0xfd,0x45,0xf0,0x80,0x05,0xe4,0x90,
+0xfd,0x45,0xf0,0xe5,0x5d,0x54,0x03,0x90,0xfd,0x44,0xf0,0xe5,0x5d,0x54,0x04,0xc3,
+0x13,0x90,0xfd,0x46,0xf0,0x90,0xfd,0x44,0xe0,0x70,0x0e,0x7d,0x3d,0x7e,0xfd,0x7f,
+0x01,0x74,0x01,0x90,0x00,0x09,0x12,0x01,0x42,0x78,0xa3,0xe6,0x24,0x08,0xf5,0x82,
+0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x7c,0x00,0xfd,0x78,0xa3,0xe6,0x24,0x07,0xf5,
+0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x7f,0x00,0x4c,0xfe,0xef,0x4d,0x90,0xfd,
+0x40,0xf0,0xa3,0xce,0xf0,0xce,0xc2,0x03,0x7d,0x0a,0x7c,0x00,0x12,0x24,0xb1,0x12,
+0x31,0x08,0x22,0x12,0x30,0x85,0x78,0x8f,0xec,0xf6,0x78,0x94,0x76,0x01,0x08,0x76,
+0xfd,0x08,0x76,0x40,0x78,0x91,0x76,0x0c,0x78,0x94,0x12,0x04,0x65,0x12,0x02,0x14,
+0x78,0x92,0xcb,0xf6,0xcb,0x08,0xf6,0x7f,0x00,0xef,0x24,0xeb,0x40,0x1f,0xe4,0xef,
+0x25,0xe0,0x90,0x34,0xbf,0xfd,0x93,0xcd,0x04,0x93,0x78,0x93,0x66,0x70,0x03,0xed,
+0x18,0x66,0x70,0x06,0x78,0x91,0x76,0x00,0x80,0x03,0x0f,0x80,0xdc,0x78,0x90,0xef,
+0xf6,0x78,0x94,0x12,0x04,0x65,0x90,0x00,0x02,0x12,0x02,0x0e,0x78,0x92,0xcb,0xf6,
+0xcb,0x08,0xf6,0x54,0x04,0xcb,0x54,0x06,0x4b,0x60,0x04,0x78,0x91,0x76,0x0b,0x78,
+0x93,0xe6,0x30,0xe3,0x13,0x78,0x94,0x12,0x04,0x65,0x90,0x00,0x05,0x12,0x01,0xec,
+0x24,0xfb,0x50,0x04,0x78,0x91,0x76,0x0d,0x78,0x93,0xe6,0x54,0xc0,0x7d,0x00,0x64,
+0xc0,0x4d,0x70,0x04,0x78,0x91,0x76,0x0b,0x78,0x94,0x12,0x04,0x65,0x90,0x00,0x04,
+0x12,0x01,0xec,0x24,0xfc,0x50,0x04,0x78,0x91,0x76,0x0f,0x78,0x94,0x12,0x04,0x65,
+0x90,0x00,0x06,0x12,0x01,0xec,0x24,0xfd,0x50,0x04,0x78,0x91,0x76,0x0e,0x78,0x94,
+0x12,0x04,0x65,0x90,0x00,0x09,0x12,0x01,0xec,0x24,0xfd,0x50,0x04,0x78,0x91,0x76,
+0x0a,0x78,0x91,0xe6,0x70,0x2a,0x78,0x8f,0xe6,0xfc,0x12,0x0f,0x7c,0x78,0x94,0x12,
+0x04,0x65,0x78,0xa1,0xe6,0xf9,0x78,0xa0,0xe6,0xfa,0x7b,0x01,0x74,0x0a,0x78,0x00,
+0x12,0x03,0x3f,0xc2,0x03,0x78,0x8f,0xe6,0xfc,0x12,0x11,0x23,0x78,0x91,0xec,0xf6,
+0x78,0x91,0xe6,0xfc,0x12,0x25,0x4a,0x12,0x31,0x08,0x22,0x12,0x30,0x85,0x78,0x8f,
+0xec,0xf6,0x12,0x0f,0x7c,0x78,0x8f,0xe6,0x24,0xfd,0x75,0xf0,0x0a,0xa4,0x24,0x1c,
+0xf5,0x82,0xe4,0x34,0xfd,0xf5,0x83,0xac,0x82,0xad,0x83,0x78,0xa0,0x86,0x83,0x08,
+0x86,0x82,0xec,0xf9,0xed,0xfa,0x7b,0x0a,0x78,0x01,0x12,0x03,0xa7,0xc2,0x03,0x78,
+0x8f,0xe6,0xfc,0x12,0x11,0x23,0x12,0x31,0x08,0x22,0x8d,0x2b,0x8c,0x2a,0xed,0x60,
+0x40,0x75,0x27,0x01,0x75,0x29,0x48,0x75,0x28,0xff,0xe5,0x2a,0x24,0xfd,0xfc,0xe4,
+0x34,0xff,0xfd,0xec,0x7c,0x03,0x25,0xe0,0xcd,0x33,0xcd,0xdc,0xf9,0xfc,0xe5,0x29,
+0x2c,0xf5,0x29,0xe5,0x28,0x3d,0xf5,0x28,0xad,0x29,0xae,0x28,0xaf,0x27,0x74,0x80,
+0x90,0x00,0x06,0x12,0x03,0x17,0x74,0x80,0x90,0x00,0x02,0x12,0x03,0x17,0x12,0x0f,
+0xd3,0xe5,0x2b,0x14,0x60,0x3b,0x75,0x27,0x01,0x75,0x29,0x08,0x75,0x28,0xff,0xe5,
+0x2a,0x24,0xfd,0xfc,0xe4,0x34,0xff,0xfd,0xec,0x7c,0x03,0x25,0xe0,0xcd,0x33,0xcd,
+0xdc,0xf9,0xfc,0xe5,0x29,0x2c,0xf5,0x29,0xe5,0x28,0x3d,0xf5,0x28,0xad,0x29,0xae,
+0x28,0xaf,0x27,0xe4,0x90,0x00,0x06,0x12,0x03,0x17,0xe4,0x90,0x00,0x02,0x12,0x03,
+0x17,0x22,0x12,0x30,0x85,0x78,0x8f,0xec,0xf6,0xec,0x24,0x97,0xf8,0xe6,0x30,0xe2,
+0x09,0x78,0x8f,0xe6,0xfc,0x12,0x15,0x22,0xd2,0x00,0x78,0x8f,0xe6,0xfc,0x12,0x0f,
+0x7c,0x78,0x90,0x76,0x00,0x90,0xfd,0x41,0xe0,0x30,0xe7,0x04,0x78,0x90,0x76,0x01,
+0x78,0x90,0xe6,0xfd,0x78,0x8f,0xe6,0xfc,0x12,0x0d,0x3a,0xc2,0x03,0x30,0x00,0x07,
+0x78,0x8f,0xe6,0xfc,0x12,0x14,0x21,0x7c,0x00,0x12,0x25,0x4a,0x12,0x31,0x08,0x22,
+0x78,0xa3,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x44,0x01,
+0xf0,0x78,0xa3,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x30,
+0xe0,0x02,0x80,0xed,0x78,0xa3,0xe6,0x24,0x0b,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,
+0x83,0xe0,0x54,0xf8,0xf0,0x78,0xa3,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,
+0xf5,0x83,0xe0,0x44,0x80,0xf0,0x22,0xc2,0x03,0x8c,0x58,0x12,0x0f,0x7c,0x78,0xa0,
+0x86,0x83,0x08,0x86,0x82,0x79,0xee,0x7a,0x34,0x7b,0x0a,0x78,0x01,0x12,0x03,0xf5,
+0x12,0x0e,0x10,0xac,0x58,0x7d,0x02,0x12,0x0d,0x3a,0xc2,0x03,0xac,0x58,0x12,0x11,
+0x23,0x22,0x8d,0x53,0x8e,0x52,0x8f,0x51,0x8c,0x50,0x12,0x0f,0x7c,0x75,0x4f,0x00,
+0x78,0xa3,0xe6,0x24,0x05,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x20,0xe4,
+0x16,0xe5,0x4f,0x24,0xf6,0x40,0x10,0x05,0x4f,0xc2,0x03,0x7c,0x18,0x12,0x32,0x48,
+0xac,0x50,0x12,0x0f,0x7c,0x80,0xd9,0x78,0xa3,0xe6,0x24,0x05,0xf5,0x82,0x18,0xe6,
+0x34,0x00,0xf5,0x83,0xe0,0x20,0xe4,0x05,0xc2,0x03,0x7c,0x02,0x22,0x78,0xa3,0xe6,
+0x24,0x05,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x54,0x0f,0x60,0x16,0x78,
+0xa3,0xe6,0x24,0x05,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x54,0x0f,0xf0,
+0xc2,0x03,0x7c,0x01,0x22,0x78,0xa2,0x86,0x83,0x08,0x86,0x82,0xe0,0xad,0x53,0xae,
+0x52,0xaf,0x51,0x12,0x03,0x0f,0xc2,0x03,0x7c,0x00,0x22,0x8d,0x31,0x8c,0x30,0x12,
+0x15,0x22,0xe5,0x31,0x60,0x20,0xe5,0x30,0xb4,0x03,0x0c,0x7c,0x01,0x12,0x24,0x7c,
+0x7c,0x81,0x12,0x24,0x7c,0x80,0x0f,0xe5,0x30,0xb4,0x04,0x0a,0x7c,0x02,0x12,0x24,
+0x7c,0x7c,0x82,0x12,0x24,0x7c,0xac,0x30,0x12,0x0f,0x7c,0xe5,0x31,0x60,0x1a,0x78,
+0xa4,0x86,0x83,0x08,0x86,0x82,0xe0,0x54,0xe7,0xf0,0xa3,0xa3,0xa3,0xa3,0xe0,0x54,
+0xe7,0xf0,0xac,0x30,0x7d,0x02,0x12,0x0d,0x3a,0x78,0xa0,0x86,0x83,0x08,0x86,0x82,
+0x79,0xf8,0x7a,0x34,0x7b,0x0a,0x78,0x01,0x12,0x03,0xf5,0xc2,0x03,0xe5,0x30,0x24,
+0x97,0xf8,0xc6,0x54,0xfd,0xf6,0xac,0x30,0x12,0x11,0x23,0x22,0x8c,0x26,0x30,0x03,
+0x05,0x12,0x31,0xe7,0x80,0xf8,0x7c,0x0a,0x12,0x30,0xfa,0xd2,0x03,0xe5,0x26,0x24,
+0xfd,0x78,0x9d,0xf6,0x70,0x09,0x78,0xa4,0x76,0xff,0x08,0x76,0xe0,0x80,0x07,0x78,
+0xa4,0x76,0xff,0x08,0x76,0xe2,0x78,0x9d,0xe6,0x75,0xf0,0x10,0xa4,0xad,0xf0,0xfc,
+0x24,0xa0,0x78,0xa3,0xf6,0xed,0x34,0xff,0x18,0xf6,0x78,0x9d,0xe6,0x75,0xf0,0x0a,
+0xa4,0x24,0x08,0xfc,0xe4,0x34,0xfd,0xfd,0x78,0xa0,0xed,0xf6,0x08,0xec,0xf6,0x12,
+0x31,0x93,0x22,0x78,0xa3,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,
+0xe0,0x30,0xe7,0x22,0x78,0xa3,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,
+0x83,0xe0,0x54,0x7f,0xf0,0x78,0xa3,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,
+0xf5,0x83,0xe0,0x44,0x80,0xf0,0x22,0x78,0xa4,0x86,0x83,0x08,0x86,0x82,0xe0,0x54,
+0x7f,0xf0,0xad,0x83,0xe5,0x82,0x24,0x04,0xfc,0xe4,0x3d,0x8c,0x82,0xf5,0x83,0xe0,
+0x54,0x7f,0xf0,0x78,0xa3,0xe6,0x24,0x0b,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,
+0xe0,0x54,0xf8,0xf0,0x78,0xa5,0xe6,0x24,0x01,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,
+0x83,0xe0,0x44,0x03,0xf0,0x78,0xa5,0xe6,0x24,0x05,0xf5,0x82,0x18,0xe6,0x34,0x00,
+0xf5,0x83,0xe0,0x44,0x03,0xf0,0x78,0xa3,0xe6,0x24,0x05,0xf5,0x82,0x18,0xe6,0x34,
+0x00,0xf5,0x83,0x74,0x0f,0xf0,0x22,0x78,0xa4,0x86,0x83,0x08,0x86,0x82,0xe0,0x54,
+0x3f,0xf0,0xad,0x83,0xe5,0x82,0x24,0x04,0xfc,0xe4,0x3d,0x8c,0x82,0xf5,0x83,0xe0,
+0x54,0x3f,0xf0,0x78,0x9d,0xe6,0x24,0x9e,0xf8,0xe6,0xfc,0x78,0xa5,0xe6,0x24,0x01,
+0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xec,0xf0,0x78,0x9d,0xe6,0x24,0x9e,0xf8,
+0xe6,0xfc,0x78,0xa5,0xe6,0x24,0x05,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xec,
+0xf0,0x78,0xa3,0xe6,0x24,0x0b,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x54,
+0xfb,0x44,0x02,0xf5,0x26,0x78,0xa1,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,
+0xf5,0x83,0xe0,0x30,0xe5,0x03,0x43,0x26,0x01,0x78,0xa3,0xe6,0x24,0x05,0xf5,0x82,
+0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x30,0xe0,0x03,0x12,0x0f,0xd3,0xe5,0x26,0xfc,
+0x78,0xa3,0xe6,0x24,0x0b,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xec,0xf0,0x78,
+0xa3,0xe6,0x24,0x05,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0x74,0x0f,0xf0,0x78,
+0xa4,0x86,0x83,0x08,0x86,0x82,0xe0,0x44,0x80,0xf0,0xa3,0xa3,0xa3,0xa3,0xe0,0x44,
+0x80,0xf0,0x22,0x8c,0x2a,0x12,0x0f,0x7c,0x78,0xa1,0xe6,0x24,0x08,0xf5,0x82,0x18,
+0xe6,0x34,0x00,0xf5,0x83,0xe0,0xfc,0x78,0xa3,0xe6,0x24,0x0a,0xf5,0x82,0x18,0xe6,
+0x34,0x00,0xf5,0x83,0xec,0xf0,0x78,0xa1,0xe6,0x24,0x07,0xf5,0x82,0x18,0xe6,0x34,
+0x00,0xf5,0x83,0xe0,0xfc,0x78,0xa3,0xe6,0x24,0x09,0xf5,0x82,0x18,0xe6,0x34,0x00,
+0xf5,0x83,0xec,0xf0,0x78,0xa0,0x86,0x83,0x08,0x86,0x82,0xe0,0xfd,0xa3,0xe0,0xfc,
+0xed,0xfe,0x78,0xa3,0xe6,0x24,0x08,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xee,
+0xf0,0xec,0xfe,0x78,0xa3,0xe6,0x24,0x07,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,
+0xee,0xf0,0x8c,0x29,0x8d,0x28,0xc3,0xec,0x94,0x02,0xed,0x94,0x06,0x40,0x05,0x75,
+0x27,0x7c,0x80,0x33,0xd3,0xe5,0x29,0x94,0x81,0xe5,0x28,0x94,0x01,0x40,0x05,0x75,
+0x27,0x3c,0x80,0x23,0xd3,0xe5,0x29,0x94,0xc0,0xe5,0x28,0x94,0x00,0x40,0x05,0x75,
+0x27,0x18,0x80,0x13,0xd3,0xe5,0x29,0x94,0x30,0xe5,0x28,0x94,0x00,0x40,0x05,0x75,
+0x27,0x0c,0x80,0x03,0x75,0x27,0x08,0xaf,0x27,0xe4,0xef,0x54,0x7c,0x44,0x83,0xff,
+0x8f,0x27,0xe5,0x27,0xfc,0x78,0xa5,0xe6,0x24,0x01,0xf5,0x82,0x18,0xe6,0x34,0x00,
+0xf5,0x83,0xec,0xf0,0xe5,0x27,0xfc,0x78,0xa5,0xe6,0x24,0x05,0xf5,0x82,0x18,0xe6,
+0x34,0x00,0xf5,0x83,0xec,0xf0,0xe5,0x27,0xfc,0x78,0x9d,0xe6,0x24,0x9e,0xf8,0xec,
+0xf6,0x78,0xa3,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0xf5,
+0x27,0x78,0xa1,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xa3,0xe0,
+0x30,0xe3,0x17,0x53,0x27,0xc7,0x78,0xa1,0xe6,0x24,0x05,0xf5,0x82,0x18,0xe6,0x34,
+0x00,0xf5,0x83,0xe0,0x90,0x34,0xe9,0x93,0x42,0x27,0x78,0xa1,0xe6,0x24,0x02,0xf5,
+0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x30,0xe7,0x05,0x43,0x27,0x40,0x80,0x03,
+0x53,0x27,0xbf,0x53,0x27,0xfb,0x78,0xa1,0xe6,0x24,0x06,0xf5,0x82,0x18,0xe6,0x34,
+0x00,0xf5,0x83,0xe0,0x60,0x03,0x43,0x27,0x04,0x53,0x27,0xfc,0x78,0xa1,0xe6,0x24,
+0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x42,0x27,0x43,0x27,0x80,0xe5,
+0x27,0xfc,0x78,0xa3,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xec,
+0xf0,0x78,0xa3,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0xf5,
+0x27,0x78,0xa1,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xa3,0xe0,
+0x30,0xe1,0x05,0x53,0x27,0xdf,0x80,0x03,0x43,0x27,0x20,0x78,0xa1,0xe6,0x24,0x02,
+0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x30,0xe4,0x05,0x53,0x27,0xef,0x80,
+0x03,0x43,0x27,0x10,0x78,0xa1,0xe6,0x24,0x09,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,
+0x83,0xe0,0xb4,0x02,0x03,0x43,0x27,0x02,0xe5,0x27,0xfc,0x78,0xa3,0xe6,0x24,0x04,
+0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xec,0xf0,0x78,0xa3,0xe6,0x24,0x03,0xf5,
+0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0xf5,0x27,0x78,0xa1,0xe6,0x24,0x09,0xf5,
+0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x70,0x05,0x53,0x27,0x7f,0x80,0x03,0x43,
+0x27,0x80,0x78,0xa1,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xa3,
+0xe0,0x30,0xe0,0x05,0x43,0x27,0x20,0x80,0x03,0x53,0x27,0xdf,0x78,0xa1,0xe6,0x24,
+0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x30,0xe3,0x05,0x43,0x27,0x40,
+0x80,0x03,0x53,0x27,0xbf,0x78,0xa1,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,
+0xf5,0x83,0xe0,0x30,0xe0,0x05,0x43,0x27,0x10,0x80,0x03,0x53,0x27,0xef,0x78,0xa1,
+0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xa3,0xe0,0x30,0xe4,0x05,
+0x43,0x27,0x08,0x80,0x03,0x53,0x27,0xf7,0x78,0xa1,0xe6,0x24,0x02,0xf5,0x82,0x18,
+0xe6,0x34,0x00,0xf5,0x83,0xa3,0xe0,0x30,0xe5,0x05,0x43,0x27,0x04,0x80,0x03,0x53,
+0x27,0xfb,0x78,0xa1,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xa3,
+0xe0,0x30,0xe6,0x05,0x43,0x27,0x01,0x80,0x03,0x53,0x27,0xfe,0x78,0xa1,0xe6,0x24,
+0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xa3,0xe0,0x30,0xe7,0x05,0x43,0x27,
+0x02,0x80,0x03,0x53,0x27,0xfd,0xe5,0x27,0xfc,0x78,0xa3,0xe6,0x24,0x03,0xf5,0x82,
+0x18,0xe6,0x34,0x00,0xf5,0x83,0xec,0xf0,0xc2,0x03,0x7c,0x00,0x22,0x8d,0x27,0x8c,
+0x26,0xed,0x54,0x03,0x14,0x60,0x03,0x7c,0x10,0x22,0xe5,0x27,0x54,0x7c,0x24,0xfc,
+0x40,0x03,0x7c,0x0b,0x22,0xe5,0x26,0x24,0x97,0xf8,0xc6,0x44,0x02,0xf6,0x7c,0x00,
+0x22,0x8c,0x30,0x12,0x0f,0x7c,0xe5,0x30,0x24,0x97,0xf8,0xe6,0x20,0xe2,0x4f,0xac,
+0x30,0x7d,0x02,0x12,0x0d,0x3a,0xe5,0x30,0x24,0xfe,0x44,0x28,0xfc,0x78,0xa4,0x86,
+0x83,0x08,0x86,0x82,0xec,0xf0,0xaf,0x83,0xe5,0x82,0x24,0x04,0xfe,0xe4,0x3f,0xff,
+0xec,0x8e,0x82,0x8f,0x83,0xf0,0x7c,0x03,0x8c,0x2c,0xe5,0x2c,0xfc,0x78,0xa5,0xe6,
+0x24,0x01,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xec,0xf0,0xe5,0x2c,0xfc,0x78,
+0xa5,0xe6,0x24,0x05,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xec,0xf0,0x75,0x2d,
+0x01,0x75,0x2f,0x48,0x75,0x2e,0xff,0xe5,0x30,0x24,0xfd,0xfc,0xe4,0x34,0xff,0xfd,
+0xec,0x7c,0x03,0x25,0xe0,0xcd,0x33,0xcd,0xdc,0xf9,0xfc,0xe5,0x2f,0x2c,0xf5,0x2f,
+0xe5,0x2e,0x3d,0xf5,0x2e,0x78,0xa5,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,
+0xf5,0x83,0xe0,0x54,0xe7,0xf5,0x2c,0xad,0x2f,0xae,0x2e,0xaf,0x2d,0xe4,0x90,0x00,
+0x02,0x12,0x03,0x17,0xe4,0x90,0x00,0x06,0x12,0x03,0x17,0x12,0x01,0xe6,0x30,0xe5,
+0x03,0x43,0x2c,0x10,0xe5,0x2c,0xfc,0x78,0xa5,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,
+0x34,0x00,0xf5,0x83,0xec,0xf0,0x12,0x10,0x67,0x78,0xa3,0xe6,0x24,0x06,0xf5,0x82,
+0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0xc2,0x03,0xfc,0xe5,0x30,0x24,0x97,0xf8,0xc6,
+0x44,0x04,0xf6,0x8c,0x2c,0xe5,0x30,0x54,0x0f,0xc4,0x54,0xf0,0x7e,0x00,0xff,0xee,
+0xef,0x44,0x04,0x7d,0x00,0xff,0xec,0x4e,0xfc,0xed,0x4f,0xfd,0x12,0x1c,0xfe,0x7c,
+0x00,0x22,0x8c,0x2f,0x12,0x0f,0x7c,0x12,0x10,0x07,0x78,0xa4,0x86,0x83,0x08,0x86,
+0x82,0xe0,0x54,0x08,0xf0,0xa3,0xa3,0xa3,0xa3,0xe0,0x54,0x08,0xf0,0xac,0x2f,0x7d,
+0x02,0x12,0x0d,0x3a,0xc2,0x03,0xe5,0x2f,0x24,0x97,0xf8,0xc6,0x54,0xfb,0xf6,0x7c,
+0x00,0x22,0x12,0x30,0x85,0x78,0x90,0xec,0xf6,0xec,0x24,0x97,0xf8,0xe6,0x30,0xe1,
+0x0a,0x7d,0x00,0x7c,0x13,0x12,0x24,0xb1,0x12,0x31,0x08,0x78,0x90,0xe6,0x24,0x97,
+0xf8,0xc6,0x44,0x01,0xf6,0x78,0x90,0xe6,0xfc,0x12,0x0f,0x7c,0x78,0x90,0xe6,0x24,
+0xfd,0x75,0xf0,0x0a,0xa4,0x24,0x1c,0xf5,0x82,0xe4,0x34,0xfd,0xf5,0x83,0x78,0xa0,
+0xe6,0xfa,0x08,0xe6,0xf9,0x7b,0x0a,0x78,0x01,0x12,0x03,0xa7,0x78,0xa0,0x86,0x83,
+0x08,0x86,0x82,0x79,0xf8,0x7a,0x34,0x7b,0x0a,0x78,0x01,0x12,0x03,0xf5,0x12,0x0f,
+0xd3,0xc2,0x03,0x78,0x90,0xe6,0xfc,0x12,0x11,0x23,0x78,0x8f,0xec,0xf6,0xec,0x60,
+0x0a,0x7d,0x00,0x7c,0x08,0x12,0x24,0xb1,0x12,0x31,0x08,0x78,0x90,0xe6,0xfc,0x12,
+0x0f,0x7c,0x78,0xa3,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,
+0x44,0x10,0x54,0xdf,0xfc,0x78,0xa3,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,
+0xf5,0x83,0xec,0xf0,0x78,0x8f,0xec,0xf6,0xc2,0x03,0x7c,0xc8,0x12,0x32,0x48,0x78,
+0x90,0xe6,0xfc,0x12,0x0f,0x7c,0x78,0xa3,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,
+0x00,0xf5,0x83,0xe0,0x54,0xef,0xf0,0xc2,0x03,0x7c,0xc8,0x12,0x32,0x48,0x78,0x90,
+0xe6,0xfc,0x12,0x0f,0x7c,0x78,0xa3,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,
+0xf5,0x83,0xe0,0x44,0x10,0xf0,0xc2,0x03,0x7c,0xc8,0x12,0x32,0x48,0x78,0x90,0xe6,
+0xfc,0x12,0x0f,0x7c,0x78,0xa3,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,
+0x83,0xe0,0x44,0x20,0xf0,0xc2,0x03,0x7c,0xf0,0x12,0x32,0x48,0x78,0x90,0xe6,0xfc,
+0x12,0x0f,0x7c,0x78,0xa3,0xe6,0x24,0x05,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,
+0xe0,0x30,0xe4,0x15,0xc2,0x03,0x78,0x90,0xe6,0x44,0x10,0x7f,0x00,0xfe,0x7c,0x07,
+0x12,0x31,0x9a,0x12,0x31,0x08,0x02,0x17,0x49,0x78,0xa3,0xe6,0x24,0x04,0xf5,0x82,
+0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x54,0xcf,0xf0,0xc2,0x03,0x7c,0xc8,0x12,0x32,
+0x48,0x78,0x90,0xe6,0xfc,0x12,0x0f,0x7c,0x78,0xa3,0xe6,0x24,0x04,0xf5,0x82,0x18,
+0xe6,0x34,0x00,0xf5,0x83,0xe0,0x44,0x30,0xf0,0xc2,0x03,0x7c,0xf0,0x12,0x32,0x48,
+0x78,0x90,0xe6,0xfc,0x12,0x0f,0x7c,0x78,0xa3,0xe6,0x24,0x05,0xf5,0x82,0x18,0xe6,
+0x34,0x00,0xf5,0x83,0xe0,0x30,0xe4,0x14,0xc2,0x03,0x78,0x90,0xe6,0x44,0x10,0x7f,
+0x00,0xfe,0x7c,0x07,0x12,0x31,0x9a,0x12,0x31,0x08,0x80,0x5d,0x78,0xa3,0xe6,0x24,
+0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x54,0xef,0xf0,0x78,0xa3,0xe6,
+0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x54,0xdf,0xf0,0x78,0x90,
+0xe6,0x24,0xfd,0x75,0xf0,0x0a,0xa4,0x24,0x1c,0xf5,0x82,0xe4,0x34,0xfd,0xf5,0x83,
+0xac,0x82,0xad,0x83,0x78,0xa0,0x86,0x83,0x08,0x86,0x82,0xec,0xf9,0xed,0xfa,0x7b,
+0x0a,0x78,0x01,0x12,0x03,0xa7,0xc2,0x03,0x78,0x90,0xe6,0xfc,0x12,0x11,0x23,0x7d,
+0x00,0x7c,0x0b,0x12,0x24,0xb1,0x12,0x31,0x08,0x22,0x12,0x30,0x85,0x90,0xff,0x91,
+0xe0,0x90,0xfd,0x41,0xf0,0x7d,0x02,0x7c,0x00,0x12,0x24,0xb1,0x12,0x31,0x08,0x22,
+0x12,0x30,0x85,0x90,0xfd,0x40,0xe0,0xf4,0xfc,0x90,0xff,0x91,0xe0,0x5c,0xf5,0x33,
+0x90,0xfd,0x41,0xe0,0xfc,0x90,0xfd,0x40,0xe0,0x5c,0x42,0x33,0xe5,0x33,0x90,0xff,
+0x91,0xf0,0x7c,0x00,0x12,0x25,0x4a,0x12,0x31,0x08,0x22,0x74,0x3c,0x90,0xfb,0xe8,
+0xf0,0x74,0x3e,0x90,0xfb,0xe8,0xf0,0xe4,0x90,0xfd,0x30,0xf0,0x22,0x8d,0x35,0x8c,
+0x34,0xec,0xb4,0x01,0x02,0x80,0x03,0xd3,0x40,0x02,0x80,0x28,0xb4,0x02,0x02,0x80,
+0x03,0xd3,0x40,0x08,0xa8,0x35,0xc6,0x25,0xe0,0xf6,0x80,0x18,0xb4,0x04,0x02,0x80,
+0x03,0xd3,0x40,0x0a,0xa8,0x35,0xc6,0x25,0xe0,0x25,0xe0,0xf6,0x80,0x06,0xa8,0x35,
+0x76,0x00,0x80,0x00,0x22,0x8c,0x3c,0x8d,0x3b,0xed,0xfe,0xec,0xfd,0x7f,0x01,0x75,
+0x60,0x06,0x75,0x61,0x00,0x90,0xfd,0x31,0x12,0x04,0x6e,0x12,0x01,0xe6,0xb4,0x80,
+0x02,0x80,0x06,0xd3,0x50,0x03,0x02,0x18,0x9e,0x90,0xfd,0x31,0x12,0x04,0x80,0x90,
+0x00,0x03,0x12,0x01,0xec,0x54,0xf0,0xb4,0x30,0x02,0x80,0x03,0xd3,0x40,0x5f,0x90,
+0xfd,0x31,0x12,0x04,0x80,0x90,0x00,0x08,0x12,0x02,0x0e,0xfa,0xfd,0xeb,0xfe,0x7f,
+0x01,0x90,0xfd,0x34,0x12,0x04,0x6e,0xee,0xcd,0x90,0x35,0x02,0xfc,0xe4,0x93,0xff,
+0x74,0x01,0x93,0xfe,0xf9,0xef,0xfa,0x7b,0x01,0xea,0xff,0xe9,0xfe,0xec,0xc3,0x9e,
+0xed,0x9f,0x40,0x25,0x90,0x35,0x04,0xe4,0x93,0xfd,0x74,0x01,0x93,0xfc,0xed,0xfe,
+0xec,0xfd,0x7f,0x01,0xee,0xcd,0xfc,0x90,0xfd,0x36,0xe0,0xd3,0x9c,0x90,0xfd,0x35,
+0xe0,0x9d,0x50,0x05,0x75,0x60,0x80,0x80,0x33,0x12,0x19,0xbc,0x80,0x2e,0xb4,0x60,
+0x02,0x80,0x03,0xd3,0x40,0x0b,0xac,0x3c,0xad,0x3b,0x12,0x07,0x82,0x8c,0x60,0x80,
+0x1b,0xb4,0x10,0x03,0xb3,0x40,0x10,0xc3,0xb4,0x20,0x03,0xb3,0x40,0x09,0xc3,0xb4,
+0x40,0x02,0x80,0x03,0xd3,0x40,0x00,0x75,0x60,0x81,0x80,0x00,0x80,0x75,0xb4,0x81,
+0x02,0x80,0x03,0xd3,0x40,0x6b,0x90,0xfd,0x31,0x12,0x04,0x80,0x90,0x00,0x03,0x12,
+0x01,0xec,0x54,0xf0,0xb4,0x30,0x02,0x80,0x03,0xd3,0x40,0x1d,0x90,0xfd,0x31,0x12,
+0x04,0x80,0x90,0x00,0x08,0x12,0x02,0x0e,0xfa,0xfd,0xeb,0xfe,0x7f,0x01,0x90,0xfd,
+0x37,0x12,0x04,0x6e,0x12,0x19,0x26,0x80,0x36,0xb4,0x60,0x02,0x80,0x03,0xd3,0x40,
+0x13,0x75,0x3a,0x61,0xe4,0xf5,0x39,0xf5,0x38,0xac,0x3c,0xad,0x3b,0x12,0x05,0xde,
+0x8c,0x60,0x80,0x1b,0xb4,0x10,0x03,0xb3,0x40,0x10,0xc3,0xb4,0x20,0x03,0xb3,0x40,
+0x09,0xc3,0xb4,0x40,0x02,0x80,0x03,0xd3,0x40,0x00,0x75,0x60,0x81,0x80,0x00,0x80,
+0x02,0x80,0x00,0xe5,0x60,0xfc,0x90,0xfd,0x31,0x12,0x04,0x80,0xec,0x90,0x00,0x02,
+0x12,0x03,0x17,0xac,0x61,0x22,0x90,0xfd,0x31,0x12,0x04,0x80,0x90,0x00,0x04,0x12,
+0x01,0xec,0x60,0x04,0x74,0x01,0x80,0x01,0xe4,0xa2,0xe0,0x92,0x01,0x90,0xfd,0x31,
+0x12,0x04,0x80,0xed,0x24,0x03,0xfd,0x50,0x01,0x0e,0x90,0xfd,0x34,0x12,0x04,0x6e,
+0x90,0xfd,0x31,0x12,0x04,0x80,0x90,0x00,0x05,0x12,0x01,0xec,0xf5,0x61,0x90,0x00,
+0x04,0x12,0x01,0xec,0x54,0x0f,0xfc,0x7d,0x61,0x12,0x17,0x9d,0xe5,0x61,0x70,0x04,
+0x75,0x60,0x08,0x22,0x75,0x60,0x00,0x78,0x7e,0x76,0x00,0x78,0x7e,0xe6,0xc3,0x95,
+0x61,0x50,0x38,0x90,0xfd,0x37,0x12,0x04,0x80,0x12,0x01,0xe6,0xfc,0x90,0xfd,0x34,
+0x12,0x04,0x80,0xec,0x12,0x03,0x0f,0x30,0x01,0x0e,0x90,0xfd,0x39,0xe0,0x04,0xf0,
+0x90,0xfd,0x38,0x70,0x03,0xe0,0x04,0xf0,0x78,0x7e,0x06,0x90,0xfd,0x36,0xe0,0x04,
+0xf0,0x90,0xfd,0x35,0x70,0x03,0xe0,0x04,0xf0,0x80,0xc0,0x22,0x90,0xfd,0x32,0xe0,
+0xfd,0xa3,0xe0,0xfc,0xed,0xfe,0xec,0xfd,0x7f,0x01,0xed,0x24,0x0a,0xfd,0x50,0x01,
+0x0e,0x90,0xfd,0x3a,0x12,0x04,0x6e,0x90,0xfd,0x31,0x12,0x04,0x80,0x90,0x00,0x04,
+0x12,0x01,0xec,0x54,0x0f,0xb4,0x01,0x02,0x80,0x03,0xd3,0x40,0x17,0x90,0xfd,0x3a,
+0x12,0x04,0x80,0x0d,0xed,0x70,0x01,0x0e,0x90,0xfd,0x37,0x12,0x04,0x6e,0x78,0x82,
+0x76,0x01,0x80,0x4e,0xb4,0x02,0x02,0x80,0x03,0xd3,0x40,0x19,0x90,0xfd,0x3a,0x12,
+0x04,0x80,0xed,0x24,0x02,0xfd,0x50,0x01,0x0e,0x90,0xfd,0x37,0x12,0x04,0x6e,0x78,
+0x82,0x76,0x02,0x80,0x2d,0xb4,0x04,0x02,0x80,0x03,0xd3,0x40,0x19,0x90,0xfd,0x3a,
+0x12,0x04,0x80,0xed,0x24,0x04,0xfd,0x50,0x01,0x0e,0x90,0xfd,0x37,0x12,0x04,0x6e,
+0x78,0x82,0x76,0x04,0x80,0x0c,0xb4,0x00,0x02,0x80,0x03,0xd3,0x40,0x00,0x75,0x60,
+0x08,0x22,0x90,0xfd,0x31,0x12,0x04,0x80,0x90,0x00,0x05,0x12,0x01,0xec,0xf5,0x61,
+0x78,0x7f,0x76,0x00,0x78,0x7f,0xe6,0xc3,0x95,0x61,0x40,0x03,0x02,0x1b,0x24,0x78,
+0x80,0x76,0x00,0x78,0x80,0xe6,0xc3,0x78,0x82,0x96,0x50,0x76,0x90,0xfd,0x34,0x12,
+0x04,0x80,0x12,0x01,0xe6,0xfc,0x90,0xfd,0x3a,0x12,0x04,0x89,0x12,0x01,0xe0,0xf4,
+0x5c,0xfc,0x12,0x01,0xe0,0xf8,0x90,0xfd,0x37,0x12,0x04,0x80,0xe8,0xc0,0xe0,0x12,
+0x01,0xe6,0xc8,0xd0,0xe0,0xc8,0x58,0x4c,0xfc,0x90,0xfd,0x34,0x12,0x04,0x80,0xec,
+0x12,0x03,0x0f,0x78,0x81,0xec,0xf6,0x90,0xfd,0x39,0xe0,0x04,0xf0,0x90,0xfd,0x38,
+0x70,0x03,0xe0,0x04,0xf0,0x09,0xe9,0x70,0x01,0x0a,0x90,0xfd,0x3a,0x12,0x04,0x77,
+0x90,0xfd,0x31,0x12,0x04,0x80,0x90,0x00,0x04,0x12,0x01,0xec,0x30,0xe4,0x0e,0x90,
+0xfd,0x36,0xe0,0x04,0xf0,0x90,0xfd,0x35,0x70,0x03,0xe0,0x04,0xf0,0x78,0x80,0x06,
+0x80,0x81,0x78,0x82,0xe6,0xfd,0xe4,0xfe,0xff,0xee,0xcd,0xfc,0x90,0xfd,0x39,0xe0,
+0x2c,0xf0,0x90,0xfd,0x38,0xe0,0x3d,0xf0,0x78,0x82,0xe6,0xfd,0xe4,0xfe,0xff,0xee,
+0xcd,0xfc,0x90,0xfd,0x3c,0xe0,0x2c,0xf0,0x90,0xfd,0x3b,0xe0,0x3d,0xf0,0x78,0x7f,
+0x06,0x02,0x1a,0x64,0x75,0x60,0x00,0x22,0xe5,0x3d,0x05,0x3d,0x04,0x70,0x02,0xb2,
+0xb0,0x22,0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0xd0,0xe8,0xc0,0xe0,0xe9,
+0xc0,0xe0,0xea,0xc0,0xe0,0xeb,0xc0,0xe0,0xec,0xc0,0xe0,0xed,0xc0,0xe0,0xee,0xc0,
+0xe0,0xef,0xc0,0xe0,0x90,0xff,0x92,0xe0,0x12,0x01,0xb7,0x1b,0x80,0x30,0x1b,0x80,
+0x32,0x1b,0x8f,0x38,0x1b,0xa1,0x3a,0x1b,0xb3,0x3e,0x1b,0xcb,0x44,0x1b,0xbf,0x46,
+0x1b,0xd7,0x50,0x1c,0x19,0x52,0x1b,0xf8,0x54,0x1c,0x3a,0x56,0x00,0x00,0x1c,0x5b,
+0x90,0xff,0x92,0xe0,0x7f,0x00,0xfe,0x7c,0x01,0x12,0x31,0x9a,0x02,0x1c,0x6b,0xe4,
+0xff,0x04,0xfe,0x7c,0x03,0x12,0x31,0x9a,0x74,0x20,0x90,0xff,0xfe,0xf0,0x02,0x1c,
+0x6b,0xe4,0xff,0x04,0xfe,0x7c,0x02,0x12,0x31,0x9a,0x74,0x40,0x90,0xff,0xfe,0xf0,
+0x02,0x1c,0x6b,0xe4,0xff,0x04,0xfe,0x7c,0x04,0x12,0x31,0x9a,0x02,0x1c,0x6b,0xe4,
+0xff,0x04,0xfe,0x7c,0x05,0x12,0x31,0x9a,0x02,0x1c,0x6b,0xe4,0xff,0x04,0xfe,0x7c,
+0x06,0x12,0x31,0x9a,0x02,0x1c,0x6b,0x90,0xff,0xa5,0xe0,0x7d,0x00,0x90,0xfd,0x00,
+0xcd,0xf0,0xa3,0xcd,0xf0,0x90,0xfd,0x01,0xe0,0xfc,0xf5,0x83,0x90,0xfd,0x00,0xe0,
+0x44,0x33,0xfd,0x12,0x1c,0xfe,0x80,0x73,0x90,0xff,0xb5,0xe0,0x7d,0x00,0x90,0xfd,
+0x02,0xcd,0xf0,0xa3,0xcd,0xf0,0x90,0xfd,0x03,0xe0,0xfc,0xf5,0x83,0x90,0xfd,0x02,
+0xe0,0x44,0x43,0xfd,0x12,0x1c,0xfe,0x80,0x52,0x90,0xff,0xa6,0xe0,0x7d,0x00,0x90,
+0xfd,0x04,0xcd,0xf0,0xa3,0xcd,0xf0,0x90,0xfd,0x05,0xe0,0xfc,0xf5,0x83,0x90,0xfd,
+0x04,0xe0,0x44,0x34,0xfd,0x12,0x1c,0xfe,0x80,0x31,0x90,0xff,0xb6,0xe0,0x7d,0x00,
+0x90,0xfd,0x06,0xcd,0xf0,0xa3,0xcd,0xf0,0x90,0xfd,0x07,0xe0,0xfc,0xf5,0x83,0x90,
+0xfd,0x06,0xe0,0x44,0x44,0xfd,0x12,0x1c,0xfe,0x80,0x10,0x90,0xff,0x92,0xe0,0x7d,
+0x00,0xfc,0xed,0x44,0xaa,0xfd,0x12,0x1c,0xfe,0x80,0x00,0xe4,0x90,0xff,0x92,0xf0,
+0xd0,0xe0,0xff,0xd0,0xe0,0xfe,0xd0,0xe0,0xfd,0xd0,0xe0,0xfc,0xd0,0xe0,0xfb,0xd0,
+0xe0,0xfa,0xd0,0xe0,0xf9,0xd0,0xe0,0xf8,0xd0,0xd0,0xd0,0x83,0xd0,0x82,0xd0,0xf0,
+0xd0,0xe0,0x32,0x05,0x81,0x05,0x81,0x05,0x81,0x05,0x81,0xa8,0x81,0x18,0x18,0x18,
+0xed,0xf6,0x08,0xec,0xf6,0x90,0xff,0x6a,0xe0,0x20,0xe7,0x02,0x80,0xf7,0x90,0xff,
+0x69,0xe0,0x7d,0x00,0xa8,0x81,0x18,0xcd,0xf6,0xcd,0x08,0xf6,0x7d,0x03,0xa8,0x81,
+0xe6,0x18,0xfc,0xe6,0xcc,0x25,0xe0,0xcc,0x33,0xcc,0xdd,0xf9,0xcc,0xf6,0xcc,0x08,
+0xf6,0xa8,0x81,0x18,0xe6,0x44,0xf8,0xf6,0xa8,0x81,0x18,0x18,0x18,0xe6,0xfd,0x08,
+0xe6,0xfc,0xa8,0x81,0x18,0x86,0x83,0x08,0x86,0x82,0xed,0xf0,0xa3,0xec,0xf0,0x74,
+0x02,0x90,0xff,0x6a,0xf0,0x15,0x81,0x15,0x81,0x15,0x81,0x15,0x81,0x22,0xe5,0x81,
+0x24,0x05,0xf5,0x81,0xe4,0xa8,0x81,0x18,0xf6,0xa8,0x81,0x18,0x18,0x18,0x18,0xed,
+0xf6,0x08,0xec,0xf6,0x90,0xfb,0xfd,0xe0,0x24,0xf8,0x50,0x03,0x02,0x1e,0x1f,0xe4,
+0xa8,0x81,0x18,0x18,0xf6,0xa8,0x81,0x18,0xe6,0xfe,0xa8,0x81,0x18,0x18,0x18,0x18,
+0xe6,0xfd,0x08,0xe6,0xfc,0x7f,0x00,0xef,0x24,0xf8,0x40,0x4d,0xe4,0xef,0x25,0xe0,
+0x24,0x85,0xf5,0x82,0xe4,0x34,0xfd,0xf5,0x83,0xe0,0xfb,0xa3,0xe0,0x6c,0x70,0x03,
+0xfa,0xeb,0x6d,0x70,0x09,0x74,0x01,0xa8,0x81,0x18,0x18,0xf6,0x80,0x2b,0xe4,0xef,
+0x25,0xe0,0x24,0x85,0xf5,0x82,0xe4,0x34,0xfd,0xf5,0x83,0x7a,0x00,0xe0,0x54,0xf0,
+0xcc,0xf8,0xcc,0xcd,0xf9,0xcd,0xfb,0x78,0x00,0xe9,0x54,0xf0,0xf9,0xea,0x68,0x70,
+0x02,0xeb,0x69,0x70,0x01,0x0e,0x0f,0x80,0xae,0xa8,0x81,0x18,0xee,0xf6,0xa8,0x81,
+0x18,0x18,0x18,0x18,0xed,0xf6,0x08,0xec,0xf6,0xa8,0x81,0xef,0xf6,0xa8,0x81,0x18,
+0x18,0xe6,0x70,0x79,0xa8,0x81,0x18,0xe6,0x24,0xf7,0x40,0x71,0xa8,0x81,0x18,0x18,
+0x18,0x18,0xe6,0x54,0x0f,0xa8,0x81,0xf6,0x64,0x04,0x60,0x17,0xa8,0x81,0xe6,0x64,
+0x03,0x60,0x10,0xa8,0x81,0x18,0x18,0x18,0x18,0xe6,0xfd,0x08,0xe6,0xfc,0x12,0x1c,
+0x93,0x80,0x4a,0x7c,0x0a,0x12,0x30,0xfa,0xa8,0x81,0x18,0x18,0x18,0x18,0xe6,0xfd,
+0x08,0xe6,0xfc,0x90,0xfb,0xfc,0xe0,0x25,0xe0,0x24,0x85,0xf5,0x82,0xe4,0x34,0xfd,
+0xf5,0x83,0xed,0xf0,0xa3,0xec,0xf0,0x90,0xfb,0xfc,0xe0,0xff,0xe4,0xef,0x04,0x54,
+0x07,0xff,0x90,0xfb,0xfc,0xf0,0x90,0xfb,0xfd,0xe0,0x04,0xf0,0x12,0x31,0x93,0x90,
+0xfb,0xfe,0xe0,0x70,0x08,0xe4,0xfe,0xff,0x7c,0x0f,0x12,0x31,0x9a,0x80,0x27,0x90,
+0xfb,0xff,0xe0,0x04,0xf0,0x54,0x3f,0x70,0x1d,0x90,0xfb,0xff,0xe0,0x44,0xfe,0x7d,
+0x00,0xfc,0x90,0xfb,0xfc,0xe0,0x25,0xe0,0x24,0x85,0xf5,0x82,0xe4,0x34,0xfd,0xf5,
+0x83,0xed,0xf0,0xa3,0xec,0xf0,0xe5,0x81,0x24,0xfb,0xf5,0x81,0x22,0x78,0x85,0x76,
+0x00,0x78,0x86,0x76,0x00,0x74,0x01,0x90,0xfb,0xfe,0xf0,0x12,0x30,0x85,0x90,0xfb,
+0xfd,0xe0,0x60,0x59,0x7c,0x0a,0x12,0x30,0xfa,0x90,0xfb,0xfb,0xe0,0x25,0xe0,0x24,
+0x85,0xf5,0x82,0xe4,0x34,0xfd,0xf5,0x83,0xe0,0xfd,0xa3,0xe0,0xfc,0x90,0xfb,0xfb,
+0xe0,0x25,0xe0,0x24,0x85,0xf5,0x82,0xe4,0x34,0xfd,0xf5,0x83,0xe4,0xf0,0xa3,0xf0,
+0x90,0xfb,0xfb,0xe0,0xff,0xe4,0xef,0x04,0x54,0x07,0xff,0x90,0xfb,0xfb,0xf0,0x90,
+0xfb,0xfd,0xe0,0x14,0xf0,0x78,0x83,0xed,0xf6,0x08,0xec,0xf6,0x12,0x31,0x93,0xb2,
+0xb3,0x78,0x83,0xe6,0xfd,0x08,0xe6,0xfc,0x12,0x08,0xe5,0x80,0xa1,0x12,0x31,0xe7,
+0x78,0x85,0x06,0xb6,0x00,0x11,0x78,0x85,0x76,0x00,0x78,0x86,0xe6,0xf4,0x04,0x04,
+0xa2,0xe0,0x92,0xb4,0x78,0x86,0xf6,0x80,0x85,0xe4,0x90,0xfb,0xfe,0xf0,0x90,0xfb,
+0xfd,0xe0,0x7d,0x00,0xfc,0xed,0x44,0xcf,0xfd,0x12,0x1c,0x93,0x12,0x31,0x08,0x22,
+0x12,0x30,0x85,0xe5,0x6a,0x64,0x49,0x45,0x69,0x60,0x15,0x90,0xff,0x83,0xe0,0x54,
+0x0f,0x7d,0x00,0xd3,0x95,0x6a,0xed,0x95,0x69,0x50,0x05,0x12,0x2e,0xce,0x80,0x03,
+0x12,0x2f,0x9e,0x12,0x31,0x08,0x22,0x12,0x30,0x85,0xe5,0x6a,0x64,0x49,0x45,0x69,
+0x60,0x05,0x12,0x2f,0xd8,0x80,0x0e,0x90,0xff,0x80,0xe0,0x44,0x08,0xf0,0x90,0xff,
+0x83,0xe0,0x54,0x7f,0xf0,0x12,0x31,0x08,0x22,0x12,0x30,0x85,0x8c,0x54,0xec,0x54,
+0xf0,0xb4,0x10,0x15,0x75,0x64,0x3d,0x75,0x63,0xfd,0x75,0x62,0x01,0xe5,0x64,0x24,
+0x03,0xf5,0x64,0xe5,0x63,0x34,0x00,0xf5,0x63,0xe4,0xf5,0x57,0xf5,0x56,0xe5,0x56,
+0xc3,0x94,0x01,0x50,0x27,0xe5,0x54,0x54,0x0f,0xfc,0xad,0x64,0xae,0x63,0xaf,0x62,
+0x12,0x0e,0x82,0x8c,0x55,0xec,0x60,0x02,0x80,0x12,0x05,0x64,0xe5,0x64,0x70,0x02,
+0x05,0x63,0x05,0x57,0xe5,0x57,0x70,0x02,0x05,0x56,0x80,0xd2,0xe5,0x54,0x54,0x0f,
+0x24,0x97,0xf8,0xc6,0x54,0xfe,0xf6,0xe5,0x54,0x54,0x0f,0x7f,0x00,0xfe,0x7c,0x12,
+0x12,0x31,0x9a,0xe5,0x55,0x14,0x70,0x09,0x7d,0x00,0x7c,0x09,0x12,0x24,0xb1,0x80,
+0x07,0xad,0x57,0x7c,0x00,0x12,0x24,0xb1,0x12,0x31,0x08,0x22,0x12,0x30,0x85,0x90,
+0xff,0xfc,0xe0,0x44,0x02,0xf0,0x90,0xff,0x00,0xe0,0x30,0xe7,0x13,0x90,0xff,0x83,
+0xe0,0x44,0x80,0xf0,0x43,0x67,0x80,0x90,0xff,0xfc,0xe0,0x44,0x01,0xf0,0x80,0x11,
+0x90,0xff,0x82,0xe0,0x44,0x08,0xf0,0x53,0x67,0x7f,0x90,0xff,0xfc,0xe0,0x54,0xfe,
+0xf0,0x90,0xff,0x81,0xe0,0x44,0x80,0xf0,0x12,0x25,0x64,0x90,0xff,0xfe,0xe0,0x44,
+0x05,0xf0,0x90,0xff,0xfc,0xe0,0x54,0xfd,0xf0,0x12,0x31,0x08,0x22,0x12,0x30,0x85,
+0x7c,0x01,0x12,0x32,0x48,0x78,0xa7,0xe6,0x44,0x02,0xf6,0x74,0xfe,0xfc,0x04,0xfd,
+0x12,0x1c,0xfe,0x90,0xff,0x6a,0xe0,0x30,0xe7,0x02,0x80,0xf7,0xe4,0xf5,0x4e,0x75,
+0x4d,0x10,0xac,0x4e,0xad,0x4d,0xe5,0x4e,0x15,0x4e,0x70,0x02,0x15,0x4d,0xec,0x4d,
+0x60,0x02,0x80,0xee,0x43,0x87,0x01,0x12,0x31,0x08,0x22,0x12,0x30,0x85,0x7c,0x02,
+0x12,0x31,0x14,0x78,0xa7,0xe6,0x54,0xfd,0xf6,0x12,0x31,0x08,0x22,0x12,0x30,0x85,
+0x78,0xa7,0xe6,0x30,0xe0,0x2c,0x78,0xa7,0xe6,0x30,0xe1,0x26,0x78,0xa7,0xe6,0xfc,
+0xf5,0x83,0x18,0xe6,0x44,0xf0,0xfd,0x12,0x1c,0x93,0x90,0xff,0xfc,0xe0,0x44,0x20,
+0xf0,0x7c,0x02,0x12,0x32,0x48,0x78,0xa7,0xe6,0x54,0xfd,0xf6,0x74,0x1a,0x90,0xff,
+0xfe,0xf0,0x78,0xa7,0xe6,0xfc,0xf5,0x83,0x18,0xe6,0x44,0xf1,0xfd,0x12,0x1c,0x93,
+0x12,0x31,0x08,0x22,0x75,0x67,0x00,0x75,0x68,0x00,0xe4,0xf5,0x66,0xf5,0x65,0xe4,
+0xf5,0x69,0x75,0x6a,0x49,0x74,0x84,0x90,0xff,0x82,0xf0,0x74,0x84,0x90,0xff,0x80,
+0xf0,0x74,0x80,0x90,0xff,0x68,0xf0,0x74,0x80,0x90,0xff,0x6a,0xf0,0xad,0x46,0xaf,
+0x45,0x7e,0x00,0xee,0x24,0xfc,0x50,0x03,0x02,0x21,0x6a,0xe4,0xee,0x75,0xf0,0x07,
+0xa4,0x24,0x3f,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0,0xff,0xe4,0xef,0x54,0x80,
+0xfd,0xe4,0xef,0x54,0x0f,0x14,0xff,0xed,0x60,0x38,0xe4,0xef,0x75,0xf0,0x08,0xa4,
+0x24,0x48,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0x74,0x90,0xf0,0xe4,0xef,0x75,0xf0,
+0x08,0xa4,0x24,0x4a,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0x74,0x80,0xf0,0xe4,0xef,
+0x75,0xf0,0x08,0xa4,0x24,0x4e,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0x74,0x80,0xf0,
+0x80,0x34,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x08,0xf5,0x82,0xe4,0x34,0xff,0xf5,
+0x83,0x74,0x90,0xf0,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x0a,0xf5,0x82,0xe4,0x34,
+0xff,0xf5,0x83,0xe4,0xf0,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x0e,0xf5,0x82,0xe4,
+0x34,0xff,0xf5,0x83,0xe4,0xf0,0x0e,0x02,0x20,0xd3,0x8d,0x46,0x8e,0x44,0x8f,0x45,
+0x74,0x7f,0x90,0xff,0xfd,0xf0,0x74,0x90,0x90,0xff,0xfc,0xf0,0x90,0xfc,0x19,0xe0,
+0x30,0xe6,0x07,0x90,0xff,0xfc,0xe0,0x44,0x04,0xf0,0x22,0x90,0xfc,0x0d,0xe0,0x14,
+0x70,0x04,0x90,0xfc,0x0c,0xe0,0x70,0x39,0x90,0xfc,0x00,0x79,0x06,0x7a,0x35,0x7b,
+0x12,0x78,0x01,0x12,0x03,0xf5,0x7f,0x00,0xef,0x33,0x40,0x15,0xef,0x90,0x35,0x4d,
+0x93,0xfc,0xef,0x24,0x80,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xec,0xf0,0x0f,0x80,
+0xe7,0x8f,0x59,0x90,0xfc,0x2b,0x79,0x18,0x7a,0x35,0x7b,0x35,0x78,0x01,0x12,0x03,
+0xf5,0xe4,0x90,0xff,0xff,0xf0,0x74,0x51,0x90,0xff,0xfa,0xf0,0x74,0x04,0x90,0xff,
+0xfb,0xf0,0x74,0x53,0x90,0xff,0xf8,0xf0,0x74,0x51,0x90,0xff,0xf9,0xf0,0x74,0x55,
+0x90,0xff,0xf7,0xf0,0x74,0x93,0x90,0xff,0xf6,0xf0,0x74,0x32,0x90,0xff,0xf5,0xf0,
+0x75,0x64,0x3d,0x75,0x63,0xfd,0x75,0x62,0x01,0xe4,0x90,0xff,0x83,0xf0,0x74,0x80,
+0x90,0xff,0x81,0xf0,0x75,0x58,0x04,0xe5,0x58,0x75,0xf0,0x07,0xa4,0x24,0x3f,0xf5,
+0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0,0x78,0x89,0xf6,0xfc,0x54,0x0f,0x14,0xfc,0x78,
+0x89,0xec,0xf6,0xe5,0x58,0x75,0xf0,0x07,0xa4,0x24,0x41,0xf5,0x82,0xe4,0x34,0xfc,
+0xf5,0x83,0xe0,0x78,0x8c,0x76,0xf8,0x08,0x76,0x00,0xfc,0x78,0x89,0xe6,0x75,0xf0,
+0x08,0xa4,0x24,0x48,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xe4,0xf0,0x78,0x89,0xe6,
+0x75,0xf0,0x08,0xa4,0x24,0x4f,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xec,0xf0,0x78,
+0x8c,0xe6,0xff,0x08,0xe6,0x7e,0x03,0xcf,0xc3,0x13,0xcf,0x13,0xde,0xf9,0xfe,0x78,
+0x89,0xe6,0x75,0xf0,0x08,0xa4,0x24,0x49,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xee,
+0xf0,0x78,0x89,0xe6,0x75,0xf0,0x08,0xa4,0x24,0x4a,0xf5,0x82,0xe4,0x34,0xff,0xf5,
+0x83,0x74,0x80,0xf0,0x78,0x8a,0xec,0xf6,0x7d,0x00,0x78,0x8d,0xe6,0x2c,0xf6,0x18,
+0xe6,0x3d,0xf6,0x78,0x8c,0xe6,0xfd,0x08,0xe6,0x7c,0x03,0xcd,0xc3,0x13,0xcd,0x13,
+0xdc,0xf9,0xfc,0x78,0x89,0xe6,0x75,0xf0,0x08,0xa4,0x24,0x4d,0xf5,0x82,0xe4,0x34,
+0xff,0xf5,0x83,0xec,0xf0,0x78,0x89,0xe6,0x75,0xf0,0x08,0xa4,0x24,0x4e,0xf5,0x82,
+0xe4,0x34,0xff,0xf5,0x83,0xe4,0xf0,0x78,0x8c,0xe6,0xfd,0x08,0xe6,0xfc,0x78,0x89,
+0xe6,0xff,0x7e,0x00,0xee,0x24,0xfc,0x50,0x03,0x02,0x24,0x6b,0xe4,0xee,0x75,0xf0,
+0x07,0xa4,0x24,0x3f,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0,0xff,0xe4,0xef,0x54,
+0x80,0xfa,0xe4,0xef,0x54,0x0f,0x14,0xff,0xe4,0xee,0x75,0xf0,0x07,0xa4,0x24,0x41,
+0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0,0x78,0x8a,0xf6,0xee,0x75,0xf0,0x80,0xa4,
+0x24,0x08,0xf8,0xe5,0xf0,0x34,0xf8,0xf9,0xe8,0xfc,0xe9,0xfd,0x8a,0x59,0xea,0x70,
+0x03,0x02,0x23,0xd8,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x48,0xf5,0x82,0xe4,0x34,
+0xff,0xf5,0x83,0xe4,0xf0,0x78,0x8a,0xe6,0xfa,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,
+0x4f,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xea,0xf0,0xed,0xfb,0xec,0x7a,0x03,0xcb,
+0xc3,0x13,0xcb,0x13,0xda,0xf9,0xfa,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x49,0xf5,
+0x82,0xe4,0x34,0xff,0xf5,0x83,0xea,0xf0,0x78,0x8a,0xe6,0x7b,0x00,0xfa,0xec,0x2a,
+0xfc,0xed,0x3b,0xfd,0xfb,0xec,0x7a,0x03,0xcb,0xc3,0x13,0xcb,0x13,0xda,0xf9,0xfa,
+0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x4d,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xea,
+0xf0,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x4a,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,
+0x74,0x80,0xf0,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x4e,0xf5,0x82,0xe4,0x34,0xff,
+0xf5,0x83,0x74,0x80,0xf0,0x02,0x24,0x67,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x08,
+0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xe4,0xf0,0x78,0x8a,0xe6,0xfa,0xe4,0xef,0x75,
+0xf0,0x08,0xa4,0x24,0x0f,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xea,0xf0,0xed,0xfb,
+0xec,0x7a,0x03,0xcb,0xc3,0x13,0xcb,0x13,0xda,0xf9,0xfa,0xe4,0xef,0x75,0xf0,0x08,
+0xa4,0x24,0x09,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xea,0xf0,0x78,0x8a,0xe6,0x7b,
+0x00,0xfa,0xec,0x2a,0xfc,0xed,0x3b,0xfd,0xfb,0xec,0x7a,0x03,0xcb,0xc3,0x13,0xcb,
+0x13,0xda,0xf9,0xfa,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x0d,0xf5,0x82,0xe4,0x34,
+0xff,0xf5,0x83,0xea,0xf0,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x0a,0xf5,0x82,0xe4,
+0x34,0xff,0xf5,0x83,0xe4,0xf0,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x0e,0xf5,0x82,
+0xe4,0x34,0xff,0xf5,0x83,0xe4,0xf0,0x0e,0x02,0x22,0xf4,0x8e,0x58,0x78,0x8c,0xed,
+0xf6,0x08,0xec,0xf6,0x78,0x89,0xef,0xf6,0x12,0x20,0xa4,0x22,0x8c,0x26,0xec,0x30,
+0xe7,0x18,0xe5,0x26,0x54,0x0f,0x14,0x75,0xf0,0x08,0xa4,0x24,0x48,0xf5,0x82,0xe4,
+0x34,0xff,0xf5,0x83,0xe0,0x54,0xdf,0xf0,0x80,0x16,0xe5,0x26,0x54,0x0f,0x14,0x75,
+0xf0,0x08,0xa4,0x24,0x08,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xe0,0x54,0xdf,0xf0,
+0x22,0xec,0x90,0xfd,0x3f,0xf0,0x8c,0x24,0xed,0x24,0x03,0xf5,0x25,0x7d,0x00,0xd3,
+0x95,0x6c,0xed,0x95,0x6b,0x40,0x03,0x85,0x6c,0x25,0xe5,0x25,0x24,0xb7,0x50,0x09,
+0x75,0x25,0x03,0x74,0x02,0x90,0xfd,0x3f,0xf0,0xac,0x25,0x12,0x2f,0xc3,0x22,0xe4,
+0xf5,0x66,0xf5,0x65,0x12,0x24,0xe8,0x22,0x90,0xfd,0x3d,0xe0,0x65,0x6d,0x60,0x0e,
+0x74,0x04,0x90,0xfd,0x3f,0xf0,0xe4,0xf5,0x65,0x75,0x66,0x03,0x80,0x46,0x7d,0x6d,
+0xe4,0xfe,0xff,0x79,0x3d,0x7a,0xfd,0x7b,0x01,0x74,0x05,0x78,0x00,0x12,0x03,0x3f,
+0xe5,0x66,0x24,0x03,0xf5,0x66,0xe5,0x65,0x34,0x00,0xf5,0x65,0xe5,0x66,0xd3,0x95,
+0x6c,0xe5,0x65,0x95,0x6b,0x40,0x06,0x85,0x6c,0x66,0x85,0x6b,0x65,0xd3,0xe5,0x66,
+0x94,0x48,0xe5,0x65,0x94,0x00,0x40,0x0c,0x74,0x02,0x90,0xfd,0x3f,0xf0,0xe4,0xf5,
+0x65,0x75,0x66,0x03,0xac,0x66,0x12,0x2f,0xc3,0x22,0xec,0x90,0xfd,0x3f,0xf0,0xe4,
+0xf5,0x66,0xf5,0x65,0x8c,0x32,0xec,0x60,0x05,0x12,0x2f,0xb4,0x80,0x05,0x7c,0x00,
+0x12,0x2f,0xc3,0x22,0x90,0xff,0x04,0xe0,0xf5,0x4a,0x90,0xff,0x06,0xe0,0xfd,0xa3,
+0xe0,0xed,0x7d,0x00,0xfc,0x7d,0x00,0xfc,0x90,0xff,0x06,0xe0,0xff,0xa3,0xe0,0x7e,
+0x00,0xff,0xe4,0xfe,0xec,0x4e,0xfc,0xed,0x4f,0xfd,0xc3,0xec,0x94,0x48,0xed,0x94,
+0x00,0x50,0x22,0x90,0xff,0x06,0xe0,0xfd,0xa3,0xe0,0xed,0x7d,0x00,0xfc,0x7d,0x00,
+0xfc,0x90,0xff,0x06,0xe0,0xff,0xa3,0xe0,0x7e,0x00,0xff,0xe4,0xfe,0xec,0x4e,0xfc,
+0xed,0x4f,0xfd,0x80,0x04,0xe4,0xfd,0x7c,0x48,0x8c,0x6c,0x8d,0x6b,0x90,0xff,0x02,
+0xe0,0xfd,0xa3,0xe0,0xed,0x7d,0x00,0xfc,0x7d,0x00,0xfc,0x90,0xff,0x02,0xe0,0xff,
+0xa3,0xe0,0x7e,0x00,0xff,0xe4,0xfe,0xec,0x4e,0xf5,0x4c,0xed,0x4f,0xf5,0x4b,0x75,
+0x64,0x3d,0x75,0x63,0xfd,0x75,0x62,0x01,0x7d,0x3d,0x7e,0xfd,0x7f,0x01,0x79,0x6d,
+0xe4,0xfa,0xfb,0x74,0x05,0x78,0x00,0x12,0x03,0x3f,0x75,0x49,0x00,0xe5,0x49,0x24,
+0xfe,0x40,0x19,0xad,0x64,0xae,0x63,0xaf,0x62,0xe4,0x12,0x03,0x0f,0x05,0x49,0x0d,
+0xed,0x70,0x01,0x0e,0x8d,0x64,0x8e,0x63,0x8f,0x62,0x80,0xe1,0x75,0x64,0x3d,0x75,
+0x63,0xfd,0x75,0x62,0x01,0x90,0xff,0x00,0xe0,0x54,0x60,0xb4,0x00,0x02,0x80,0x06,
+0xd3,0x50,0x03,0x02,0x2c,0x12,0xe5,0x4a,0x54,0x0f,0xf5,0x49,0xe5,0x4a,0x54,0x80,
+0xa2,0xe0,0x92,0x02,0x90,0xff,0x01,0xe0,0x12,0x01,0x81,0x00,0x0b,0x2c,0x0d,0x26,
+0x67,0x27,0x85,0x2c,0x0d,0x28,0x91,0x2c,0x0d,0x29,0x74,0x29,0xa8,0x2b,0x0f,0x2b,
+0x12,0x2b,0x52,0x2b,0xb6,0x2b,0xe4,0xe5,0x67,0x30,0xe7,0x0e,0xe5,0x4c,0x45,0x4b,
+0x70,0x08,0xe5,0x6c,0x64,0x02,0x45,0x6b,0x60,0x03,0x02,0x2c,0x0f,0x90,0xff,0x00,
+0xe0,0x54,0x1f,0xb4,0x00,0x02,0x80,0x03,0xd3,0x40,0x29,0xe5,0x4a,0x60,0x03,0x02,
+0x27,0x82,0xad,0x64,0xae,0x63,0xaf,0x62,0x74,0x01,0x12,0x03,0x0f,0x78,0xa7,0xe6,
+0x30,0xe0,0x0b,0xad,0x64,0xae,0x63,0xaf,0x62,0x74,0x02,0x12,0x03,0x0f,0x7c,0x02,
+0x12,0x2f,0xc3,0x22,0xb4,0x01,0x02,0x80,0x03,0xd3,0x40,0x1b,0xe5,0x67,0x20,0xe1,
+0x07,0xe5,0x4a,0x60,0x03,0x02,0x27,0x82,0xe5,0x4a,0x24,0xfe,0x50,0x03,0x02,0x27,
+0x82,0x7c,0x02,0x12,0x2f,0xc3,0x22,0xb4,0x02,0x02,0x80,0x06,0xd3,0x50,0x03,0x02,
+0x27,0x80,0xe5,0x67,0x20,0xe1,0x0d,0xe5,0x4a,0x60,0x09,0xe5,0x4a,0x64,0x80,0x60,
+0x03,0x02,0x27,0x82,0xac,0x4a,0x12,0x30,0x4a,0x40,0x03,0x02,0x27,0x82,0xe5,0x49,
+0x70,0x25,0x30,0x02,0x11,0x90,0xff,0x80,0xe0,0x54,0x08,0xad,0x64,0xae,0x63,0xaf,
+0x62,0x12,0x03,0x0f,0x80,0x0f,0x90,0xff,0x82,0xe0,0x54,0x08,0xad,0x64,0xae,0x63,
+0xaf,0x62,0x12,0x03,0x0f,0x80,0x3d,0x15,0x49,0x30,0x02,0x1d,0xe5,0x49,0x75,0xf0,
+0x08,0xa4,0x24,0x48,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xe0,0x54,0x08,0xad,0x64,
+0xae,0x63,0xaf,0x62,0x12,0x03,0x0f,0x80,0x1b,0xe5,0x49,0x75,0xf0,0x08,0xa4,0x24,
+0x08,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xe0,0x54,0x08,0xad,0x64,0xae,0x63,0xaf,
+0x62,0x12,0x03,0x0f,0xad,0x64,0xae,0x63,0xaf,0x62,0x12,0x01,0xe6,0x60,0x0b,0xad,
+0x64,0xae,0x63,0xaf,0x62,0x74,0x01,0x12,0x03,0x0f,0x7c,0x02,0x12,0x2f,0xc3,0x22,
+0x80,0x00,0x02,0x2c,0x0f,0xe5,0x67,0x20,0xe7,0x06,0xe5,0x6c,0x45,0x6b,0x60,0x03,
+0x02,0x2c,0x0f,0x90,0xff,0x00,0xe0,0x54,0x1f,0xb4,0x00,0x02,0x80,0x03,0xd3,0x40,
+0x1a,0xe5,0x4c,0x14,0x45,0x4b,0x70,0x04,0xe5,0x4a,0x60,0x03,0x02,0x28,0x8e,0x78,
+0xa7,0xe6,0x54,0xfe,0xf6,0x7c,0x00,0x12,0x2f,0xc3,0x22,0xb4,0x01,0x02,0x80,0x03,
+0xd3,0x40,0x2a,0xe5,0x67,0x20,0xe1,0x08,0xe5,0x67,0x20,0xe0,0x03,0x02,0x28,0x8e,
+0xe5,0x67,0x30,0xe0,0x04,0xe5,0x4a,0x70,0x0b,0xe5,0x67,0x30,0xe1,0x09,0xe5,0x4a,
+0x24,0xfe,0x50,0x03,0x02,0x28,0x8e,0x7c,0x00,0x12,0x2f,0xc3,0x22,0xb4,0x02,0x02,
+0x80,0x06,0xd3,0x50,0x03,0x02,0x28,0x8c,0xe5,0x4c,0x45,0x4b,0x60,0x03,0x02,0x28,
+0x8e,0xac,0x4a,0x12,0x30,0x4a,0x40,0x03,0x02,0x28,0x8e,0xe5,0x67,0x20,0xe1,0x07,
+0xe5,0x67,0x20,0xe0,0x02,0x80,0x77,0xe5,0x67,0x30,0xe0,0x06,0xe5,0x49,0x60,0x02,
+0x80,0x6c,0xe5,0x49,0x70,0x0f,0x90,0xff,0x82,0xe0,0x54,0xf7,0xf0,0x90,0xff,0x80,
+0xe0,0x54,0xf7,0xf0,0x22,0xe5,0x49,0xb4,0x01,0x02,0x80,0x03,0xd3,0x40,0x09,0x7d,
+0x01,0x7c,0x03,0x12,0x0f,0x0b,0x80,0x11,0xb4,0x02,0x02,0x80,0x03,0xd3,0x40,0x09,
+0x7d,0x01,0x7c,0x04,0x12,0x0f,0x0b,0x80,0x00,0x15,0x49,0x30,0x02,0x15,0xe5,0x49,
+0x75,0xf0,0x08,0xa4,0x24,0x48,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xe0,0x54,0xf7,
+0xf0,0x80,0x13,0xe5,0x49,0x75,0xf0,0x08,0xa4,0x24,0x08,0xf5,0x82,0xe4,0x34,0xff,
+0xf5,0x83,0xe0,0x54,0xf7,0xf0,0x7c,0x00,0x12,0x2f,0xc3,0x22,0x80,0x00,0x02,0x2c,
+0x0f,0xe5,0x67,0x20,0xe7,0x06,0xe5,0x6c,0x45,0x6b,0x60,0x03,0x02,0x2c,0x0f,0x90,
+0xff,0x00,0xe0,0x54,0x1f,0xb4,0x00,0x02,0x80,0x03,0xd3,0x40,0x1a,0xe5,0x4c,0x14,
+0x45,0x4b,0x70,0x04,0xe5,0x4a,0x60,0x03,0x02,0x29,0x71,0x78,0xa7,0xe6,0x44,0x01,
+0xf6,0x7c,0x00,0x12,0x2f,0xc3,0x22,0xb4,0x01,0x02,0x80,0x03,0xd3,0x40,0x29,0xe5,
+0x67,0x20,0xe1,0x08,0xe5,0x67,0x20,0xe0,0x03,0x02,0x29,0x71,0xe5,0x67,0x30,0xe0,
+0x04,0xe5,0x49,0x70,0x0b,0xe5,0x67,0x30,0xe1,0x08,0xe5,0x49,0x24,0xfe,0x50,0x02,
+0x80,0x7f,0x7c,0x00,0x12,0x2f,0xc3,0x22,0xb4,0x02,0x02,0x80,0x03,0xd3,0x40,0x6f,
+0xe5,0x4c,0x45,0x4b,0x60,0x02,0x80,0x69,0xac,0x4a,0x12,0x30,0x4a,0x40,0x02,0x80,
+0x60,0xe5,0x67,0x20,0xe1,0x07,0xe5,0x67,0x20,0xe0,0x02,0x80,0x54,0xe5,0x49,0x70,
+0x14,0x30,0x02,0x09,0x90,0xff,0x80,0xe0,0x44,0x08,0xf0,0x80,0x07,0x90,0xff,0x82,
+0xe0,0x44,0x08,0xf0,0x22,0xe5,0x67,0x30,0xe1,0x33,0x15,0x49,0x30,0x02,0x15,0xe5,
+0x49,0x75,0xf0,0x08,0xa4,0x24,0x48,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xe0,0x44,
+0x08,0xf0,0x80,0x13,0xe5,0x49,0x75,0xf0,0x08,0xa4,0x24,0x08,0xf5,0x82,0xe4,0x34,
+0xff,0xf5,0x83,0xe0,0x44,0x08,0xf0,0x7c,0x00,0x12,0x2f,0xc3,0x22,0x80,0x02,0x80,
+0x00,0x02,0x2c,0x0f,0xe5,0x67,0x20,0xe7,0x12,0xe5,0x6c,0x45,0x6b,0x70,0x0c,0xe5,
+0x4a,0x70,0x08,0x90,0xff,0x00,0xe0,0x54,0x1f,0x60,0x03,0x02,0x2c,0x0f,0xe5,0x4c,
+0x90,0xff,0xff,0xf0,0x90,0xff,0xff,0xe0,0x60,0x05,0x43,0x67,0x01,0x80,0x03,0x53,
+0x67,0xfe,0x7c,0x00,0x12,0x2f,0xc3,0x22,0xe5,0x67,0x30,0xe7,0x0e,0xe5,0x6c,0x45,
+0x6b,0x60,0x08,0x90,0xff,0x00,0xe0,0x54,0x1f,0x60,0x03,0x02,0x2c,0x0f,0xad,0x4b,
+0xe5,0x4c,0xed,0x7d,0x00,0xfc,0x7d,0x00,0xfc,0xbd,0x00,0x02,0x80,0x03,0x02,0x2b,
+0x0a,0xb4,0x01,0x02,0x80,0x03,0xd3,0x40,0x32,0xe5,0x4a,0x70,0x05,0xe5,0x4c,0xfc,
+0x60,0x03,0x02,0x2b,0x0c,0x75,0x64,0x00,0x75,0x63,0xfc,0x75,0x62,0x01,0xd3,0xe5,
+0x6c,0x94,0x12,0xe5,0x6b,0x94,0x00,0x40,0x06,0xe4,0xfd,0x7c,0x12,0x80,0x04,0xac,
+0x6c,0xad,0x6b,0x8c,0x6a,0x8d,0x69,0x12,0x2f,0xd8,0x22,0xb4,0x02,0x02,0x80,0x03,
+0xd3,0x40,0x59,0xe5,0x4a,0x60,0x03,0x02,0x2b,0x0c,0xe5,0x4c,0xfc,0x70,0x27,0x75,
+0x64,0x12,0x75,0x63,0xfc,0x75,0x62,0x01,0xd3,0xe5,0x6c,0x94,0x19,0xe5,0x6b,0x94,
+0x00,0x40,0x06,0xe4,0xfd,0x7c,0x19,0x80,0x04,0xac,0x6c,0xad,0x6b,0x8c,0x6a,0x8d,
+0x69,0x12,0x2f,0xd8,0x80,0x25,0x75,0x64,0x2b,0x75,0x63,0xfc,0x75,0x62,0x01,0xd3,
+0xe5,0x6c,0x94,0x35,0xe5,0x6b,0x94,0x00,0x40,0x06,0xe4,0xfd,0x7c,0x35,0x80,0x04,
+0xac,0x6c,0xad,0x6b,0x8c,0x6a,0x8d,0x69,0x12,0x2f,0xd8,0x22,0xb4,0x03,0x02,0x80,
+0x06,0xd3,0x50,0x03,0x02,0x2b,0x0a,0xe5,0x4c,0xf5,0x49,0x70,0x0f,0x90,0xff,0x04,
+0xe0,0xfd,0xa3,0xe0,0x4d,0x60,0x03,0x02,0x2b,0x0c,0x80,0x18,0x90,0xfc,0x82,0xe0,
+0xfd,0xa3,0xe0,0xfc,0x90,0xff,0x05,0xe0,0x6c,0x70,0x07,0x90,0xff,0x04,0xe0,0x6d,
+0x60,0x02,0x80,0x68,0xe4,0xf5,0x6a,0xf5,0x69,0x7f,0x00,0xe5,0x49,0x14,0xc5,0x49,
+0x60,0x0f,0xef,0x24,0x80,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0,0x2f,0xff,0x80,
+0xea,0x8f,0x4a,0xe5,0x4a,0x24,0x80,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0,0x7d,
+0x00,0xd3,0x95,0x6c,0xed,0x95,0x6b,0x40,0x06,0xac,0x6c,0xad,0x6b,0x80,0x0f,0xe5,
+0x4a,0x24,0x80,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0,0x7d,0x00,0xfc,0x8c,0x6a,
+0x8d,0x69,0xe5,0x4a,0x24,0x80,0xfc,0xe4,0x34,0xfc,0xfd,0xfe,0xec,0xfd,0x7f,0x01,
+0x8d,0x64,0x8e,0x63,0x8f,0x62,0x12,0x2f,0xd8,0x22,0x80,0x00,0x02,0x2c,0x0f,0x02,
+0x2c,0x0f,0xe5,0x67,0x30,0xe7,0x19,0xe5,0x6c,0x14,0x45,0x6b,0x70,0x12,0xe5,0x4a,
+0x70,0x0e,0xe5,0x4c,0x45,0x4b,0x70,0x08,0x90,0xff,0x00,0xe0,0x54,0x1f,0x60,0x03,
+0x02,0x2c,0x0f,0xe5,0x67,0x20,0xe0,0x08,0xe5,0x67,0x20,0xe1,0x03,0x02,0x2c,0x0f,
+0x75,0x64,0x68,0xe4,0xf5,0x63,0xf5,0x62,0xe4,0xf5,0x69,0x04,0xf5,0x6a,0x12,0x2f,
+0xd8,0x22,0xe5,0x67,0x20,0xe7,0x27,0xe5,0x6c,0x45,0x6b,0x70,0x21,0xe5,0x4a,0x70,
+0x1d,0xe5,0x4c,0x64,0x02,0x45,0x4b,0x60,0x0d,0xe5,0x4c,0x14,0x45,0x4b,0x60,0x06,
+0xe5,0x4c,0x45,0x4b,0x70,0x08,0x90,0xff,0x00,0xe0,0x54,0x1f,0x60,0x03,0x02,0x2c,
+0x0f,0xe5,0x67,0x20,0xe0,0x08,0xe5,0x67,0x20,0xe1,0x03,0x02,0x2c,0x0f,0x85,0x4c,
+0x68,0xe5,0x68,0x70,0x08,0x43,0x67,0x01,0x53,0x67,0xfd,0x80,0x13,0xe5,0x68,0x64,
+0x02,0x60,0x07,0xe5,0x68,0x14,0x60,0x02,0x80,0x65,0x53,0x67,0xfe,0x43,0x67,0x02,
+0x7c,0x00,0x12,0x2f,0xc3,0x22,0xe5,0x67,0x30,0xe7,0x1a,0xe5,0x6c,0x14,0x45,0x6b,
+0x70,0x13,0xe5,0x4a,0x70,0x0f,0xe5,0x4c,0x45,0x4b,0x70,0x09,0x90,0xff,0x00,0xe0,
+0x54,0x1f,0x14,0x60,0x02,0x80,0x38,0xe5,0x67,0x20,0xe1,0x02,0x80,0x31,0x7c,0x01,
+0x12,0x2f,0xc3,0x22,0xe5,0x67,0x20,0xe7,0x15,0xe5,0x6c,0x45,0x6b,0x70,0x0f,0xe5,
+0x4c,0x45,0x4b,0x70,0x09,0x90,0xff,0x00,0xe0,0x54,0x1f,0x14,0x60,0x02,0x80,0x0f,
+0xe5,0x67,0x20,0xe1,0x02,0x80,0x08,0x7c,0x00,0x12,0x2f,0xc3,0x22,0x80,0x00,0x02,
+0x2e,0xca,0xb4,0x40,0x02,0x80,0x06,0xd3,0x50,0x03,0x02,0x2e,0xc0,0x90,0xff,0x01,
+0xe0,0x90,0xfd,0x3d,0xf0,0xe5,0x4a,0x90,0xfd,0x3e,0xf0,0xe4,0x90,0xfd,0x3f,0xf0,
+0xe5,0x64,0x24,0x03,0xf5,0x64,0xe5,0x63,0x34,0x00,0xf5,0x63,0xad,0x4b,0xe5,0x4c,
+0x85,0x64,0x82,0x85,0x63,0x83,0xcd,0xf0,0xa3,0xcd,0xf0,0x90,0xff,0x01,0xe0,0x12,
+0x01,0xb7,0x2c,0x7d,0x01,0x2c,0xa3,0x02,0x2c,0xcd,0x03,0x2c,0xf7,0x04,0x2d,0x45,
+0x05,0x2d,0x82,0x06,0x2d,0xa8,0x07,0x2d,0xce,0x08,0x2d,0xf4,0x09,0x2e,0x1a,0x0b,
+0x2e,0x40,0x0c,0x2e,0x4f,0x80,0x2e,0x4f,0x81,0x00,0x00,0x2e,0xad,0xe5,0x67,0x20,
+0xe7,0x06,0x7c,0x05,0x12,0x25,0x4a,0x22,0x7d,0xb7,0x7e,0x34,0x7f,0x02,0x79,0x40,
+0x7a,0xfd,0x7b,0x01,0x74,0x08,0x78,0x00,0x12,0x03,0x3f,0x7d,0x08,0x7c,0x00,0x12,
+0x24,0xb1,0x22,0xe5,0x67,0x20,0xe7,0x06,0x7c,0x05,0x12,0x25,0x4a,0x22,0xe5,0x4a,
+0xb4,0x03,0x00,0x40,0x10,0xb4,0x05,0x00,0x50,0x0b,0xe5,0x4a,0x7f,0x00,0xfe,0x7c,
+0x10,0x12,0x31,0x9a,0x22,0x7d,0x00,0x7c,0x07,0x12,0x24,0xb1,0x22,0xe5,0x67,0x20,
+0xe7,0x06,0x7c,0x05,0x12,0x25,0x4a,0x22,0xe5,0x4a,0xb4,0x03,0x00,0x40,0x10,0xb4,
+0x05,0x00,0x50,0x0b,0xe5,0x4a,0x7f,0x00,0xfe,0x7c,0x11,0x12,0x31,0x9a,0x22,0x7d,
+0x00,0x7c,0x07,0x12,0x24,0xb1,0x22,0xe5,0x67,0x20,0xe7,0x06,0x7c,0x05,0x12,0x25,
+0x4a,0x22,0xe5,0x4a,0xb4,0x05,0x02,0x80,0x03,0xd3,0x40,0x0a,0xe4,0xff,0x04,0xfe,
+0x7c,0x0a,0x12,0x31,0x9a,0x22,0xb4,0x01,0x02,0x80,0x03,0xd3,0x40,0x0a,0xe4,0xff,
+0x04,0xfe,0x7c,0x08,0x12,0x31,0x9a,0x22,0xb4,0x03,0x00,0x40,0x10,0xb4,0x05,0x00,
+0x50,0x0b,0xe5,0x4a,0x7f,0x00,0xfe,0x7c,0x13,0x12,0x31,0x9a,0x22,0x7d,0x00,0x7c,
+0x07,0x12,0x24,0xb1,0x22,0xe5,0x67,0x20,0xe7,0x34,0xd3,0xe5,0x6c,0x94,0x48,0xe5,
+0x6b,0x94,0x00,0x50,0x06,0xe5,0x6c,0x45,0x6b,0x70,0x06,0x7c,0x02,0x12,0x25,0x4a,
+0x22,0xe5,0x4a,0xb4,0x01,0x03,0xb3,0x40,0x0b,0xc3,0xb4,0x03,0x00,0x40,0x09,0xb4,
+0x06,0x00,0x50,0x04,0x12,0x30,0x70,0x22,0x7c,0x07,0x12,0x25,0x4a,0x22,0x12,0x24,
+0xe8,0x22,0xe5,0x67,0x20,0xe7,0x1d,0xe5,0x4a,0xb4,0x03,0x00,0x40,0x10,0xb4,0x05,
+0x00,0x50,0x0b,0xe5,0x4a,0x7f,0x00,0xfe,0x7c,0x16,0x12,0x31,0x9a,0x22,0x7c,0x07,
+0x12,0x25,0x4a,0x22,0x12,0x24,0xe8,0x22,0xe5,0x67,0x20,0xe7,0x1d,0xe5,0x4a,0xb4,
+0x03,0x00,0x40,0x10,0xb4,0x05,0x00,0x50,0x0b,0xe5,0x4a,0x7f,0x00,0xfe,0x7c,0x19,
+0x12,0x31,0x9a,0x22,0x7c,0x07,0x12,0x25,0x4a,0x22,0x12,0x24,0xe8,0x22,0xe5,0x67,
+0x20,0xe7,0x1d,0xe5,0x4a,0xb4,0x03,0x00,0x40,0x10,0xb4,0x05,0x00,0x50,0x0b,0xe5,
+0x4a,0x7f,0x00,0xfe,0x7c,0x17,0x12,0x31,0x9a,0x22,0x7c,0x07,0x12,0x25,0x4a,0x22,
+0x12,0x24,0xe8,0x22,0xe5,0x67,0x20,0xe7,0x1d,0xe5,0x4a,0xb4,0x03,0x00,0x40,0x10,
+0xb4,0x05,0x00,0x50,0x0b,0xe5,0x4a,0x7f,0x00,0xfe,0x7c,0x18,0x12,0x31,0x9a,0x22,
+0x7c,0x07,0x12,0x25,0x4a,0x22,0x12,0x24,0xe8,0x22,0xe5,0x67,0x20,0xe7,0x1d,0xe5,
+0x4a,0xb4,0x03,0x00,0x40,0x10,0xb4,0x05,0x00,0x50,0x0b,0xe5,0x4a,0x7f,0x00,0xfe,
+0x7c,0x15,0x12,0x31,0x9a,0x22,0x7c,0x07,0x12,0x25,0x4a,0x22,0x12,0x24,0xe8,0x22,
+0xe5,0x67,0x20,0xe7,0x06,0x7c,0x07,0x12,0x25,0x4a,0x22,0x12,0x24,0xe8,0x22,0xe5,
+0x67,0x30,0xe7,0x20,0x90,0xff,0x00,0xe0,0x54,0x1f,0x70,0x10,0x90,0xff,0x01,0xe0,
+0xb4,0x80,0x05,0x12,0x24,0xdf,0x80,0x03,0x12,0x24,0xe8,0x22,0x7d,0x00,0x7c,0x05,
+0x12,0x24,0xb1,0x22,0x90,0xff,0x00,0xe0,0x54,0x1f,0x60,0x06,0x7c,0x05,0x12,0x25,
+0x4a,0x22,0xd3,0xe5,0x6c,0x94,0x48,0xe5,0x6b,0x94,0x00,0x50,0x0b,0xc3,0xe5,0x6c,
+0x94,0x07,0xe5,0x6b,0x94,0x00,0x50,0x06,0x7c,0x03,0x12,0x25,0x4a,0x22,0xe5,0x4a,
+0xb4,0x05,0x04,0x12,0x30,0x70,0x22,0x7c,0x07,0x12,0x25,0x4a,0x22,0xe5,0x67,0x30,
+0xe7,0x08,0x7d,0x00,0x7c,0x05,0x12,0x24,0xb1,0x22,0x7c,0x05,0x12,0x25,0x4a,0x22,
+0xb4,0x20,0x02,0x80,0x03,0xd3,0x40,0x00,0x80,0x00,0x12,0x2f,0x9e,0x22,0x75,0x43,
+0x00,0x90,0xff,0x83,0xe0,0x54,0x0f,0xd3,0x95,0x43,0x40,0x24,0xe5,0x43,0x24,0xf0,
+0xf5,0x82,0xe4,0x34,0xfe,0xf5,0x83,0xe0,0xad,0x64,0xae,0x63,0xaf,0x62,0x12,0x03,
+0x0f,0x05,0x43,0x0d,0xed,0x70,0x01,0x0e,0x8d,0x64,0x8e,0x63,0x8f,0x62,0x80,0xd1,
+0xe5,0x43,0x7d,0x00,0xfc,0xc3,0xe5,0x6a,0x9c,0xf5,0x6a,0xe5,0x69,0x9d,0xf5,0x69,
+0xe5,0x6a,0x45,0x69,0x60,0x06,0xe4,0x90,0xff,0x83,0xf0,0x22,0x90,0xff,0x82,0xe0,
+0x44,0x08,0xf0,0xe4,0xf5,0x69,0x75,0x6a,0x49,0x90,0xfd,0x3d,0xe0,0xb4,0x05,0x02,
+0x80,0x03,0xd3,0x40,0x40,0x90,0xfd,0x3e,0xe0,0xf5,0x43,0xb4,0x05,0x02,0x80,0x03,
+0xd3,0x40,0x0a,0xe4,0xff,0x04,0xfe,0x7c,0x0b,0x12,0x31,0x9a,0x22,0xb4,0x01,0x02,
+0x80,0x03,0xd3,0x40,0x0a,0xe4,0xff,0x04,0xfe,0x7c,0x09,0x12,0x31,0x9a,0x22,0xb4,
+0x03,0x00,0x40,0x10,0xb4,0x05,0x00,0x50,0x0b,0xe5,0x43,0x7f,0x00,0xfe,0x7c,0x14,
+0x12,0x31,0x9a,0x22,0x22,0xb4,0x80,0x00,0x40,0x23,0xb4,0x82,0x00,0x50,0x1e,0x7c,
+0x3d,0x7d,0xfd,0x12,0x17,0xd5,0x7d,0x00,0x8c,0x66,0x8d,0x65,0x90,0xfd,0x3f,0xe0,
+0x60,0x05,0x12,0x2f,0x9e,0x80,0x05,0x7c,0x00,0x12,0x2f,0xc3,0x22,0x22,0x90,0xff,
+0x83,0xe0,0x54,0x7f,0xf0,0x90,0xff,0x82,0xe0,0x44,0x08,0xf0,0x90,0xff,0x80,0xe0,
+0x44,0x08,0xf0,0x22,0x90,0xff,0x82,0xe0,0x44,0x08,0xf0,0x90,0xff,0x80,0xe0,0x44,
+0x08,0xf0,0x22,0x8c,0x23,0x7d,0x00,0x8c,0x6a,0x8d,0x69,0x75,0x64,0x3d,0x75,0x63,
+0xfd,0x75,0x62,0x01,0x12,0x2f,0xd8,0x22,0x90,0xff,0x83,0xe0,0x54,0x7f,0xf0,0xe5,
+0x6a,0x64,0x49,0x45,0x69,0x70,0x01,0x22,0xc3,0xe5,0x6a,0x94,0x08,0xe5,0x69,0x94,
+0x00,0x40,0x15,0x75,0x21,0x08,0xe5,0x21,0x7d,0x00,0xfc,0xc3,0xe5,0x6a,0x9c,0xf5,
+0x6a,0xe5,0x69,0x9d,0xf5,0x69,0x80,0x09,0x85,0x6a,0x21,0xe4,0xf5,0x69,0x75,0x6a,
+0x49,0x75,0x22,0x00,0xe5,0x22,0xc3,0x95,0x21,0x50,0x26,0xad,0x64,0xae,0x63,0xaf,
+0x62,0x12,0x01,0xe6,0xfc,0xe5,0x22,0x24,0xf8,0xf5,0x82,0xe4,0x34,0xfe,0xf5,0x83,
+0xec,0xf0,0x05,0x22,0x0d,0xed,0x70,0x01,0x0e,0x8d,0x64,0x8e,0x63,0x8f,0x62,0x80,
+0xd3,0xe5,0x21,0x54,0x7f,0x90,0xff,0x81,0xf0,0x22,0x8c,0x48,0x7f,0x00,0xef,0x24,
+0xfb,0x40,0x19,0xe4,0xef,0x75,0xf0,0x07,0xa4,0x24,0x3f,0xf5,0x82,0xe4,0x34,0xfc,
+0xf5,0x83,0xe0,0x65,0x48,0x70,0x02,0xd3,0x22,0x0f,0x80,0xe2,0x8f,0x47,0xc3,0x22,
+0x85,0x6c,0x6a,0x85,0x6b,0x69,0x90,0xff,0x82,0xe0,0x54,0xf7,0xf0,0x90,0xff,0x83,
+0xe0,0x54,0x7f,0xf0,0x22,0xc0,0x00,0xc0,0x01,0xc0,0x02,0xc0,0x06,0xc0,0x07,0xe5,
+0x72,0x24,0x08,0xf8,0x86,0x06,0x53,0x06,0x7f,0x7c,0xff,0x12,0x30,0xfa,0x7c,0x00,
+0x7d,0x00,0xe5,0x75,0x60,0x46,0xff,0x90,0xfe,0x9d,0xe0,0x54,0x7f,0x6e,0x70,0x0f,
+0xc0,0x83,0xc0,0x82,0xa3,0xe0,0xfd,0xa3,0xe0,0xfc,0xa3,0x15,0x75,0x80,0x07,0xa3,
+0xa3,0xa3,0xdf,0xe6,0x80,0x26,0xdf,0x06,0xd0,0x82,0xd0,0x83,0x80,0x1e,0xe0,0xf8,
+0xa3,0xe0,0xf9,0xa3,0xe0,0xfa,0xd0,0x82,0xd0,0x83,0xe8,0xf0,0xa3,0xe9,0xf0,0xa3,
+0xea,0xf0,0xa3,0xc0,0x83,0xc0,0x82,0xa3,0xa3,0xa3,0x80,0xda,0x12,0x31,0x93,0xd0,
+0x07,0xd0,0x06,0xd0,0x02,0xd0,0x01,0xd0,0x00,0x22,0x85,0xa8,0x74,0x75,0xa8,0x88,
+0xec,0x70,0x02,0x7c,0x3f,0x8c,0x73,0x22,0xe5,0x72,0x24,0x08,0xf8,0x76,0x00,0x12,
+0x31,0xe7,0x80,0xfb,0xc0,0x00,0xc0,0x01,0xc0,0x02,0xc0,0x06,0xc0,0x07,0xae,0x04,
+0x7c,0xff,0x12,0x30,0xfa,0xe5,0x75,0x60,0x42,0xff,0x90,0xfe,0x9d,0xe0,0x54,0x7f,
+0x6e,0x70,0x0b,0xc0,0x83,0xc0,0x82,0xa3,0xa3,0xa3,0x15,0x75,0x80,0x07,0xa3,0xa3,
+0xa3,0xdf,0xea,0x80,0x26,0xdf,0x06,0xd0,0x82,0xd0,0x83,0x80,0xd8,0xe0,0xf8,0xa3,
+0xe0,0xf9,0xa3,0xe0,0xfa,0xd0,0x82,0xd0,0x83,0xe8,0xf0,0xa3,0xe9,0xf0,0xa3,0xea,
+0xf0,0xa3,0xc0,0x83,0xc0,0x82,0xa3,0xa3,0xa3,0x80,0xda,0x78,0x08,0x08,0x79,0x18,
+0x09,0x7c,0x01,0xe6,0x54,0x7f,0x6e,0x70,0x06,0x76,0x00,0x77,0x00,0x80,0x06,0x08,
+0x09,0x0c,0xbc,0x08,0xee,0x12,0x31,0x93,0xd0,0x07,0xd0,0x06,0xd0,0x02,0xd0,0x01,
+0xd0,0x00,0x22,0x75,0x73,0x00,0x85,0x74,0xa8,0x22,0xc0,0xf0,0xc0,0x82,0xc0,0x83,
+0xc3,0xe5,0x75,0x24,0xe8,0x50,0x05,0x12,0x31,0xe7,0x80,0xf4,0xec,0x60,0x31,0x90,
+0x34,0xb6,0xe4,0x93,0xc3,0x9c,0x40,0x28,0xc0,0x04,0x7c,0xff,0x12,0x30,0xfa,0xd0,
+0x04,0x43,0x04,0x80,0xe5,0x75,0x75,0xf0,0x03,0xa4,0x24,0x9d,0xf5,0x82,0xe4,0x34,
+0xfe,0xf5,0x83,0xec,0xf0,0xef,0xa3,0xf0,0xee,0xa3,0xf0,0x05,0x75,0x12,0x31,0x93,
+0xd0,0x83,0xd0,0x82,0xd0,0xf0,0x22,0xc0,0x04,0x7c,0x20,0xd2,0x8c,0xd2,0x8d,0xd5,
+0x04,0xfd,0xd0,0x04,0x22,0x75,0xa8,0x00,0x75,0x88,0x00,0x75,0xb8,0x00,0x75,0xf0,
+0x00,0x75,0xd0,0x00,0xe4,0xf8,0x90,0x00,0x00,0xf6,0x08,0xb8,0x00,0xfb,0x02,0x00,
+0x00,0xc3,0xed,0x94,0x02,0x50,0x04,0x7d,0x03,0x7c,0xe8,0xec,0xf4,0xfc,0xed,0xf4,
+0xfd,0x0c,0xbc,0x00,0x01,0x0d,0x8c,0x79,0x8d,0x78,0x22,0xc3,0xec,0x94,0xbc,0xed,
+0x94,0x02,0x50,0x04,0x7d,0x07,0x7c,0xd0,0xec,0xf4,0xfc,0xed,0xf4,0xfd,0x0c,0xbc,
+0x00,0x01,0x0d,0x8c,0x77,0x8d,0x76,0x22,0xec,0x70,0x01,0x22,0xc0,0x00,0xe5,0x72,
+0x24,0x18,0xf8,0xa6,0x04,0xe5,0x72,0x24,0x08,0xf8,0xc6,0x54,0x7f,0xf6,0xe6,0x30,
+0xe7,0x03,0xd0,0x00,0x22,0x12,0x31,0xe7,0x80,0xf4,0xc2,0x8c,0x85,0x76,0x8c,0x85,
+0x77,0x8a,0xd2,0x8c,0xc0,0xe0,0xc0,0xd0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0x00,
+0xc0,0x01,0xc0,0x02,0xc0,0x03,0xc0,0x04,0xc0,0x05,0xc0,0x06,0xc0,0x07,0x12,0x1b,
+0x28,0xe5,0x72,0x24,0x08,0xf8,0xe6,0x60,0x24,0xe5,0x72,0x24,0x10,0xf8,0xa6,0x81,
+0xe5,0x72,0x75,0xf0,0x21,0xa4,0x24,0x95,0xf5,0x82,0xe4,0x34,0xfd,0xf5,0x83,0x78,
+0xa8,0xe5,0x81,0x04,0xc3,0x98,0xf9,0xe6,0xf0,0x08,0xa3,0xd9,0xfa,0x74,0x08,0x25,
+0x72,0xf8,0x05,0x72,0x08,0xe6,0x54,0x80,0x70,0x0c,0xe5,0x72,0xb4,0x07,0xf3,0x78,
+0x08,0x75,0x72,0x00,0x80,0xef,0xe5,0x72,0x24,0x10,0xf8,0x86,0x81,0xe5,0x72,0x75,
+0xf0,0x21,0xa4,0x24,0x95,0xf5,0x82,0xe4,0x34,0xfd,0xf5,0x83,0x78,0xa8,0xe5,0x81,
+0x04,0xc3,0x98,0xf9,0xe0,0xf6,0x08,0xa3,0xd9,0xfa,0xd0,0x07,0xd0,0x06,0xd0,0x05,
+0xd0,0x04,0xd0,0x03,0xd0,0x02,0xd0,0x01,0xd0,0x00,0xd0,0x83,0xd0,0x82,0xd0,0xf0,
+0xd0,0xd0,0xd0,0xe0,0x32,0xc0,0xe0,0xc0,0xd0,0xc0,0x00,0xc0,0x01,0xc0,0x02,0xc2,
+0x8e,0x85,0x78,0x8d,0x85,0x79,0x8b,0xd2,0x8e,0x78,0x19,0x79,0x09,0x7a,0x07,0xe7,
+0x70,0x04,0xa6,0x00,0x80,0x0b,0xe6,0x60,0x08,0x16,0xe6,0x70,0x04,0xe7,0x44,0x80,
+0xf7,0x08,0x09,0xda,0xea,0xe5,0x73,0x60,0x13,0x14,0xf5,0x73,0x70,0x0e,0xe5,0x72,
+0x24,0x08,0xf8,0x76,0x00,0x12,0x31,0x93,0xd2,0x8c,0xd2,0x8d,0xd0,0x02,0xd0,0x01,
+0xd0,0x00,0xd0,0xd0,0xd0,0xe0,0x32,0x75,0x81,0xa7,0x75,0x90,0x00,0x75,0x79,0x30,
+0x75,0x78,0xf8,0x75,0x77,0x60,0x75,0x76,0xf0,0x12,0x05,0x3c,0x12,0x34,0x0f,0x12,
+0x17,0x8b,0x12,0x34,0x39,0x12,0x31,0xf5,0x80,0xe3,0x22,0xc0,0x00,0x7c,0x01,0xec,
+0x24,0x08,0xf8,0xe6,0x60,0x09,0x0c,0xbc,0x08,0xf5,0x12,0x31,0xe7,0x80,0xee,0xd0,
+0x00,0x22,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0x00,0xc0,0x06,0xc0,0x07,0xed,0x24,
+0x10,0xf8,0x76,0xb6,0xed,0x75,0xf0,0x21,0xa4,0x24,0x95,0xf5,0x82,0xe4,0x34,0xfd,
+0xf5,0x83,0xc0,0x82,0xc0,0x83,0xa3,0xa3,0xe4,0x78,0x0d,0xf0,0xa3,0xd8,0xfc,0xec,
+0x54,0x7f,0x75,0xf0,0x02,0xa4,0x24,0x82,0xf5,0x82,0xe5,0xf0,0x34,0x34,0xf5,0x83,
+0xe4,0x93,0xfe,0x74,0x01,0x93,0xf5,0x82,0x8e,0x83,0xe4,0x93,0xfe,0x74,0x01,0x93,
+0xff,0xd0,0x83,0xd0,0x82,0xef,0xf0,0xa3,0xee,0xf0,0xed,0x24,0x08,0xf8,0xec,0x44,
+0x80,0xf6,0xd0,0x07,0xd0,0x06,0xd0,0x00,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0x22,0x75,
+0x72,0x00,0x75,0x75,0x00,0x7a,0x08,0x79,0x18,0x78,0x08,0x76,0x00,0x77,0x00,0x08,
+0x09,0xda,0xf8,0xe4,0x78,0x08,0x74,0x80,0x44,0x7f,0xf6,0x74,0x01,0x44,0x10,0xf5,
+0x89,0x75,0xb8,0x08,0xd2,0xab,0xd2,0xa9,0x22,0x75,0x81,0xa7,0xd2,0x8e,0xd2,0x8c,
+0xd2,0xaf,0xe5,0x75,0x60,0x32,0xff,0x90,0xfe,0x9d,0xe0,0x54,0x80,0x60,0x24,0x78,
+0x08,0x79,0x08,0xe0,0x54,0x7f,0xfa,0x7b,0x00,0xe6,0x54,0x7f,0xb5,0x02,0x02,0x7b,
+0xff,0x08,0xd9,0xf5,0xeb,0x70,0x0c,0xea,0xf0,0x12,0x33,0x8b,0xad,0x04,0xac,0x02,
+0x12,0x33,0xa2,0xa3,0xa3,0xa3,0xdf,0xd2,0x12,0x31,0xe7,0x80,0xc5,0x7c,0x01,0x7d,
+0x00,0x22,0x04,0xf5,0x04,0xe9,0x04,0xed,0x04,0xe1,0x04,0xdd,0x04,0xd9,0x04,0xe5,
+0x04,0xf1,0x04,0x9d,0x04,0xa1,0x04,0xcd,0x04,0xd1,0x04,0x99,0x04,0x99,0x04,0x99,
+0x04,0xd5,0x04,0xb5,0x04,0xad,0x04,0xb1,0x04,0xa9,0x04,0xc1,0x04,0xbd,0x04,0xb9,
+0x04,0xc5,0x04,0xc9,0x04,0xa5,0x19,0x01,0x03,0x00,0x22,0x00,0x48,0x02,0x00,0x24,
+0x0f,0x18,0x0a,0x10,0x64,0x0d,0x68,0x0c,0x05,0x06,0x02,0x03,0x01,0x01,0x81,0x01,
+0x00,0x00,0xe7,0x00,0xc0,0x00,0x80,0x00,0x60,0x00,0x40,0x00,0x30,0x00,0x18,0x00,
+0x0c,0x00,0x08,0x00,0x04,0x00,0x02,0x00,0x01,0x00,0x08,0x18,0x38,0x28,0x06,0x02,
+0x10,0x0a,0x02,0x00,0x00,0x00,0x00,0x00,0x01,0x81,0x10,0x0a,0x02,0x00,0x00,0x00,
+0x00,0x00,0xfb,0xe8,0xfb,0xfa,0x12,0x01,0x10,0x01,0xff,0x00,0x00,0x08,0x51,0x04,
+0x5f,0x50,0x16,0x01,0x01,0x02,0x00,0x02,0x09,0x02,0x35,0x00,0x01,0x02,0x00,0xe0,
+0x00,0x09,0x04,0x00,0x00,0x05,0xff,0x00,0x00,0x00,0x07,0x05,0x81,0x02,0x40,0x00,
+0x00,0x07,0x05,0x01,0x02,0x40,0x00,0x00,0x07,0x05,0x82,0x02,0x40,0x00,0x00,0x07,
+0x05,0x02,0x02,0x40,0x00,0x00,0x07,0x05,0x85,0x03,0x02,0x00,0x01,0x04,0x03,0x09,
+0x04,0x24,0x03,0x54,0x00,0x65,0x00,0x78,0x00,0x61,0x00,0x73,0x00,0x20,0x00,0x49,
+0x00,0x6e,0x00,0x73,0x00,0x74,0x00,0x72,0x00,0x75,0x00,0x6d,0x00,0x65,0x00,0x6e,
+0x00,0x74,0x00,0x73,0x00,0x2a,0x03,0x54,0x00,0x55,0x00,0x53,0x00,0x42,0x00,0x35,
+0x00,0x30,0x00,0x35,0x00,0x32,0x00,0x20,0x00,0x53,0x00,0x65,0x00,0x72,0x00,0x69,
+0x00,0x61,0x00,0x6c,0x00,0x20,0x00,0x50,0x00,0x6f,0x00,0x72,0x00,0x74,0x00,0x22,
+0x03,0x54,0x00,0x55,0x00,0x53,0x00,0x42,0x00,0x35,0x00,0x30,0x00,0x35,0x00,0x32,
+0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,
+0x00,
+};
+
+#endif /* ifndef _TI_FW_5052_H_ */
diff -Nru a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/usb/serial/ti_usb_3410_5052.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,1842 @@
+/* vi: ts=8 sw=8
+ *
+ * TI 3410/5052 USB Serial Driver
+ *
+ * Copyright (C) 2004 Texas Instruments
+ *
+ * This driver is based on the Linux io_ti driver, which is
+ *   Copyright (C) 2000-2002 Inside Out Networks
+ *   Copyright (C) 2001-2002 Greg Kroah-Hartman
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * For questions or problems with this driver, contact Texas Instruments
+ * technical support, or Al Borchers <alborchers@steinerpoint.com>, or
+ * Peter Berger <pberger@brimson.com>.
+ * 
+ * This driver needs this hotplug script in /etc/hotplug/usb/ti_usb_3410_5052
+ * or in /etc/hotplug.d/usb/ti_usb_3410_5052.hotplug to set the device
+ * configuration.
+ *
+ * #!/bin/bash
+ *
+ * BOOT_CONFIG=1
+ * ACTIVE_CONFIG=2
+ *
+ * if [[ "$ACTION" != "add" ]]
+ * then
+ * 	exit
+ * fi
+ *
+ * CONFIG_PATH=/sys${DEVPATH%/?*}/bConfigurationValue
+ *
+ * if [[ 0`cat $CONFIG_PATH` -ne $BOOT_CONFIG ]]
+ * then
+ * 	exit
+ * fi
+ *
+ * PRODUCT=${PRODUCT%/?*}		# delete version
+ * VENDOR_ID=`printf "%d" 0x${PRODUCT%/?*}`
+ * PRODUCT_ID=`printf "%d" 0x${PRODUCT#*?/}`
+ *
+ * PARAM_PATH=/sys/module/ti_usb_3410_5052/parameters
+ *
+ * function scan() {
+ * 	s=$1
+ * 	shift
+ * 	for i
+ * 	do
+ * 		if [[ $s -eq $i ]]
+ * 		then
+ * 			return 0
+ * 		fi
+ * 	done
+ * 	return 1
+ * }
+ *
+ * IFS=$IFS,
+ *
+ * if (scan $VENDOR_ID 1105 `cat $PARAM_PATH/vendor_3410` &&
+ * scan $PRODUCT_ID 13328 `cat $PARAM_PATH/product_3410`) ||
+ * (scan $VENDOR_ID 1105 `cat $PARAM_PATH/vendor_5052` &&
+ * scan $PRODUCT_ID 20562 20818 20570 20575 `cat $PARAM_PATH/product_5052`)
+ * then
+ * 	echo $ACTIVE_CONFIG > $CONFIG_PATH
+ * fi
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/tty.h>
+#include <linux/tty_driver.h>
+#include <linux/tty_flip.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/ioctl.h>
+#include <linux/serial.h>
+#include <linux/circ_buf.h>
+#include <asm/uaccess.h>
+#include <asm/semaphore.h>
+#include <linux/usb.h>
+
+#include "usb-serial.h"
+#include "ti_usb_3410_5052.h"
+#include "ti_fw_3410.h"		/* firmware image for 3410 */
+#include "ti_fw_5052.h"		/* firmware image for 5052 */
+
+
+/* Defines */
+
+#define TI_DRIVER_VERSION	"v0.9"
+#define TI_DRIVER_AUTHOR	"Al Borchers <alborchers@steinerpoint.com>"
+#define TI_DRIVER_DESC		"TI USB 3410/5052 Serial Driver"
+
+#define TI_FIRMWARE_BUF_SIZE	16284
+
+#define TI_WRITE_BUF_SIZE	1024
+
+#define TI_TRANSFER_TIMEOUT	2
+
+#define TI_DEFAULT_LOW_LATENCY	0
+#define TI_DEFAULT_CLOSING_WAIT	4000		/* in .01 secs */
+
+/* supported setserial flags */
+#define TI_SET_SERIAL_FLAGS	(ASYNC_LOW_LATENCY)
+
+/* read urb states */
+#define TI_READ_URB_RUNNING	0
+#define TI_READ_URB_STOPPING	1
+#define TI_READ_URB_STOPPED	2
+
+#define TI_EXTRA_VID_PID_COUNT	5
+
+
+/* Structures */
+
+struct ti_port {
+	int			tp_is_open;
+	__u8			tp_msr;
+	__u8			tp_lsr;
+	__u8			tp_shadow_mcr;
+	__u8			tp_uart_mode;	/* 232 or 485 modes */
+	unsigned int		tp_uart_base_addr;
+	int			tp_flags;
+	int			tp_closing_wait;/* in .01 secs */
+	struct async_icount	tp_icount;
+	wait_queue_head_t	tp_msr_wait;	/* wait for msr change */
+	wait_queue_head_t	tp_write_wait;
+	struct ti_device	*tp_tdev;
+	struct usb_serial_port	*tp_port;
+	spinlock_t		tp_lock;
+	int			tp_read_urb_state;
+	int			tp_write_urb_in_use;
+	struct circ_buf		*tp_write_buf;
+};
+
+struct ti_device {
+	struct semaphore	td_open_close_sem;
+	int			td_open_port_count;
+	struct usb_serial	*td_serial;
+	int			td_is_3410;
+	int			td_urb_error;
+};
+
+
+/* Function Declarations */
+
+static int ti_startup(struct usb_serial *serial);
+static void ti_shutdown(struct usb_serial *serial);
+static int ti_open(struct usb_serial_port *port, struct file *file);
+static void ti_close(struct usb_serial_port *port, struct file *file);
+static int ti_write(struct usb_serial_port *port, const unsigned char *data,
+	int count);
+static int ti_write_room(struct usb_serial_port *port);
+static int ti_chars_in_buffer(struct usb_serial_port *port);
+static void ti_throttle(struct usb_serial_port *port);
+static void ti_unthrottle(struct usb_serial_port *port);
+static int ti_ioctl(struct usb_serial_port *port, struct file *file, unsigned int cmd, unsigned long arg);
+static void ti_set_termios(struct usb_serial_port *port,
+	struct termios *old_termios);
+static int ti_tiocmget(struct usb_serial_port *port, struct file *file);
+static int ti_tiocmset(struct usb_serial_port *port, struct file *file,
+	unsigned int set, unsigned int clear);
+static void ti_break(struct usb_serial_port *port, int break_state);
+static void ti_interrupt_callback(struct urb *urb, struct pt_regs *regs);
+static void ti_bulk_in_callback(struct urb *urb, struct pt_regs *regs);
+static void ti_bulk_out_callback(struct urb *urb, struct pt_regs *regs);
+
+static void ti_recv(struct device *dev, struct tty_struct *tty,
+	unsigned char *data, int length);
+static void ti_send(struct ti_port *tport);
+static int ti_set_mcr(struct ti_port *tport, unsigned int mcr);
+static int ti_get_lsr(struct ti_port *tport);
+static int ti_get_serial_info(struct ti_port *tport,
+	struct serial_struct __user *ret_arg);
+static int ti_set_serial_info(struct ti_port *tport,
+	struct serial_struct __user *new_arg);
+static void ti_handle_new_msr(struct ti_port *tport, __u8 msr);
+
+static void ti_drain(struct ti_port *tport, unsigned long timeout, int flush);
+
+static void ti_stop_read(struct ti_port *tport, struct tty_struct *tty);
+static int ti_restart_read(struct ti_port *tport, struct tty_struct *tty);
+
+static int ti_command_out_sync(struct ti_device *tdev, __u8 command,
+	__u16 moduleid, __u16 value, __u8 *data, int size);
+static int ti_command_in_sync(struct ti_device *tdev, __u8 command,
+	__u16 moduleid, __u16 value, __u8 *data, int size);
+
+static int ti_write_byte(struct ti_device *tdev, unsigned long addr,
+	__u8 mask, __u8 byte);
+
+static int ti_download_firmware(struct ti_device *tdev,
+	unsigned char *firmware, unsigned int firmware_size);
+
+/* circular buffer */
+static struct circ_buf *ti_buf_alloc(void);
+static void ti_buf_free(struct circ_buf *cb);
+static void ti_buf_clear(struct circ_buf *cb);
+static int ti_buf_data_avail(struct circ_buf *cb);
+static int ti_buf_space_avail(struct circ_buf *cb);
+static int ti_buf_put(struct circ_buf *cb, const char *buf, int count);
+static int ti_buf_get(struct circ_buf *cb, char *buf, int count);
+
+
+/* Data */
+
+/* module parameters */
+static int debug;
+static int low_latency = TI_DEFAULT_LOW_LATENCY;
+static int closing_wait = TI_DEFAULT_CLOSING_WAIT;
+static ushort vendor_3410[TI_EXTRA_VID_PID_COUNT];
+static int vendor_3410_count;
+static ushort product_3410[TI_EXTRA_VID_PID_COUNT];
+static int product_3410_count;
+static ushort vendor_5052[TI_EXTRA_VID_PID_COUNT];
+static int vendor_5052_count;
+static ushort product_5052[TI_EXTRA_VID_PID_COUNT];
+static int product_5052_count;
+
+/* supported devices */
+/* the array dimension is the number of default entries plus */
+/* TI_EXTRA_VID_PID_COUNT user defined entries plus 1 terminating */
+/* null entry */
+static struct usb_device_id ti_id_table_3410[1+TI_EXTRA_VID_PID_COUNT+1] = {
+	{ USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) },
+};
+
+static struct usb_device_id ti_id_table_5052[4+TI_EXTRA_VID_PID_COUNT+1] = {
+	{ USB_DEVICE(TI_VENDOR_ID, TI_5052_BOOT_PRODUCT_ID) },
+	{ USB_DEVICE(TI_VENDOR_ID, TI_5152_BOOT_PRODUCT_ID) },
+	{ USB_DEVICE(TI_VENDOR_ID, TI_5052_EEPROM_PRODUCT_ID) },
+	{ USB_DEVICE(TI_VENDOR_ID, TI_5052_FIRMWARE_PRODUCT_ID) },
+};
+
+static struct usb_device_id ti_id_table_combined[] = {
+	{ USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) },
+	{ USB_DEVICE(TI_VENDOR_ID, TI_5052_BOOT_PRODUCT_ID) },
+	{ USB_DEVICE(TI_VENDOR_ID, TI_5152_BOOT_PRODUCT_ID) },
+	{ USB_DEVICE(TI_VENDOR_ID, TI_5052_EEPROM_PRODUCT_ID) },
+	{ USB_DEVICE(TI_VENDOR_ID, TI_5052_FIRMWARE_PRODUCT_ID) },
+	{ }
+};
+
+static struct usb_driver ti_usb_driver = {
+	.owner			= THIS_MODULE,
+	.name			= "ti_usb_3410_5052",
+	.probe			= usb_serial_probe,
+	.disconnect		= usb_serial_disconnect,
+	.id_table		= ti_id_table_combined,
+};
+
+static struct usb_serial_device_type ti_1port_device = {
+	.owner			= THIS_MODULE,
+	.name			= "TI USB 3410 1 port adapter",
+	.id_table		= ti_id_table_3410,
+	.num_interrupt_in	= 1,
+	.num_bulk_in		= 1,
+	.num_bulk_out		= 1,
+	.num_ports		= 1,
+	.attach			= ti_startup,
+	.shutdown		= ti_shutdown,
+	.open			= ti_open,
+	.close			= ti_close,
+	.write			= ti_write,
+	.write_room		= ti_write_room,
+	.chars_in_buffer	= ti_chars_in_buffer,
+	.throttle		= ti_throttle,
+	.unthrottle		= ti_unthrottle,
+	.ioctl			= ti_ioctl,
+	.set_termios		= ti_set_termios,
+	.tiocmget		= ti_tiocmget,
+	.tiocmset		= ti_tiocmset,
+	.break_ctl		= ti_break,
+	.read_int_callback	= ti_interrupt_callback,
+	.read_bulk_callback	= ti_bulk_in_callback,
+	.write_bulk_callback	= ti_bulk_out_callback,
+};
+
+static struct usb_serial_device_type ti_2port_device = {
+	.owner			= THIS_MODULE,
+	.name			= "TI USB 5052 2 port adapter",
+	.id_table		= ti_id_table_5052,
+	.num_interrupt_in	= 1,
+	.num_bulk_in		= 2,
+	.num_bulk_out		= 2,
+	.num_ports		= 2,
+	.attach			= ti_startup,
+	.shutdown		= ti_shutdown,
+	.open			= ti_open,
+	.close			= ti_close,
+	.write			= ti_write,
+	.write_room		= ti_write_room,
+	.chars_in_buffer	= ti_chars_in_buffer,
+	.throttle		= ti_throttle,
+	.unthrottle		= ti_unthrottle,
+	.ioctl			= ti_ioctl,
+	.set_termios		= ti_set_termios,
+	.tiocmget		= ti_tiocmget,
+	.tiocmset		= ti_tiocmset,
+	.break_ctl		= ti_break,
+	.read_int_callback	= ti_interrupt_callback,
+	.read_bulk_callback	= ti_bulk_in_callback,
+	.write_bulk_callback	= ti_bulk_out_callback,
+};
+
+
+/* Module */
+
+MODULE_AUTHOR(TI_DRIVER_AUTHOR);
+MODULE_DESCRIPTION(TI_DRIVER_DESC);
+MODULE_VERSION(TI_DRIVER_VERSION);
+MODULE_LICENSE("GPL");
+
+module_param(debug, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(debug, "Enable debugging, 0=no, 1=yes");
+
+module_param(low_latency, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(low_latency, "TTY low_latency flag, 0=off, 1=on, default is off");
+
+module_param(closing_wait, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(closing_wait, "Maximum wait for data to drain in close, in .01 secs, default is 4000");
+
+module_param_array(vendor_3410, ushort, &vendor_3410_count, S_IRUGO);
+MODULE_PARM_DESC(vendor_3410, "Vendor ids for 3410 based devices, 1-5 short integers");
+module_param_array(product_3410, ushort, &product_3410_count, S_IRUGO);
+MODULE_PARM_DESC(product_3410, "Product ids for 3410 based devices, 1-5 short integers");
+module_param_array(vendor_5052, ushort, &vendor_5052_count, S_IRUGO);
+MODULE_PARM_DESC(vendor_5052, "Vendor ids for 5052 based devices, 1-5 short integers");
+module_param_array(product_5052, ushort, &product_5052_count, S_IRUGO);
+MODULE_PARM_DESC(product_5052, "Product ids for 5052 based devices, 1-5 short integers");
+
+MODULE_DEVICE_TABLE(usb, ti_id_table_combined);
+
+
+/* Functions */
+
+static int __init ti_init(void)
+{
+	int i,j;
+	int ret;
+
+
+	/* insert extra vendor and product ids */
+	j = sizeof(ti_id_table_3410)/sizeof(struct usb_device_id)
+		- TI_EXTRA_VID_PID_COUNT - 1;
+	for (i=0; i<min(vendor_3410_count,product_3410_count); i++,j++) {
+		ti_id_table_3410[j].idVendor = vendor_3410[i];
+		ti_id_table_3410[j].idProduct = product_3410[i];
+		ti_id_table_3410[j].match_flags = USB_DEVICE_ID_MATCH_DEVICE;
+	}
+	j = sizeof(ti_id_table_5052)/sizeof(struct usb_device_id)
+		- TI_EXTRA_VID_PID_COUNT - 1;
+	for (i=0; i<min(vendor_5052_count,product_5052_count); i++,j++) {
+		ti_id_table_5052[j].idVendor = vendor_5052[i];
+		ti_id_table_5052[j].idProduct = product_5052[i];
+		ti_id_table_5052[j].match_flags = USB_DEVICE_ID_MATCH_DEVICE;
+	}
+
+	ret = usb_serial_register(&ti_1port_device);
+	if (ret)
+		goto failed_1port;
+	ret = usb_serial_register(&ti_2port_device);
+	if (ret)
+		goto failed_2port;
+
+	ret = usb_register(&ti_usb_driver);
+	if (ret)
+		goto failed_usb;
+
+	info(TI_DRIVER_DESC " " TI_DRIVER_VERSION);
+
+	return 0;
+
+failed_usb:
+	usb_serial_deregister(&ti_2port_device);
+failed_2port:
+	usb_serial_deregister(&ti_1port_device);
+failed_1port:
+	return ret;
+}
+
+
+static void __exit ti_exit(void)
+{
+	usb_serial_deregister(&ti_1port_device);
+	usb_serial_deregister(&ti_2port_device);
+	usb_deregister(&ti_usb_driver);
+}
+
+
+module_init(ti_init);
+module_exit(ti_exit);
+
+
+static int ti_startup(struct usb_serial *serial)
+{
+	struct ti_device *tdev;
+	struct ti_port *tport;
+	struct usb_device *dev = serial->dev;
+	int status;
+	int i;
+
+
+	dbg("%s - product 0x%4X, num configurations %d, configuration value %d",
+	    __FUNCTION__, le16_to_cpu(dev->descriptor.idProduct),
+	    dev->descriptor.bNumConfigurations,
+	    dev->actconfig->desc.bConfigurationValue);
+
+	/* create device structure */
+	tdev = kmalloc(sizeof(struct ti_device), GFP_KERNEL);
+	if (tdev == NULL) {
+		dev_err(&dev->dev, "%s - out of memory\n", __FUNCTION__);
+		return -ENOMEM;
+	}
+	memset(tdev, 0, sizeof(struct ti_device));
+	sema_init(&tdev->td_open_close_sem, 1);
+	tdev->td_serial = serial;
+	usb_set_serial_data(serial, tdev);
+
+	/* determine device type */
+	if (usb_match_id(serial->interface, ti_id_table_3410))
+		tdev->td_is_3410 = 1;
+	dbg("%s - device type is %s", __FUNCTION__, tdev->td_is_3410 ? "3410" : "5052");
+
+	/* if we have only 1 configuration, download firmware */
+	if (dev->descriptor.bNumConfigurations == 1) {
+
+		if (tdev->td_is_3410)
+			status = ti_download_firmware(tdev, ti_fw_3410,
+				sizeof(ti_fw_3410));
+		else
+			status = ti_download_firmware(tdev, ti_fw_5052,
+				sizeof(ti_fw_5052));
+		if (status)
+			goto free_tdev;
+
+		/* 3410 must be reset, 5052 resets itself */
+		if (tdev->td_is_3410) {
+			msleep_interruptible(100);
+			usb_reset_device(dev);
+		}
+
+		status = -ENODEV;
+		goto free_tdev;
+	} 
+
+	/* the second configuration must be set (in sysfs by hotplug script) */
+	if (dev->actconfig->desc.bConfigurationValue == TI_BOOT_CONFIG) {
+		status = -ENODEV;
+		goto free_tdev;
+	}
+
+	/* set up port structures */
+	for (i = 0; i < serial->num_ports; ++i) {
+		tport = kmalloc(sizeof(struct ti_port), GFP_KERNEL);
+		if (tport == NULL) {
+			dev_err(&dev->dev, "%s - out of memory\n", __FUNCTION__);
+			status = -ENOMEM;
+			goto free_tports;
+		}
+		memset(tport, 0, sizeof(struct ti_port));
+		spin_lock_init(&tport->tp_lock);
+		tport->tp_uart_base_addr = (i == 0 ? TI_UART1_BASE_ADDR : TI_UART2_BASE_ADDR);
+		tport->tp_flags = low_latency ? ASYNC_LOW_LATENCY : 0;
+		tport->tp_closing_wait = closing_wait;
+		init_waitqueue_head(&tport->tp_msr_wait);
+		init_waitqueue_head(&tport->tp_write_wait);
+		tport->tp_write_buf = ti_buf_alloc();
+		if (tport->tp_write_buf == NULL) {
+			dev_err(&dev->dev, "%s - out of memory\n", __FUNCTION__);
+			kfree(tport);
+			status = -ENOMEM;
+			goto free_tports;
+		}
+		tport->tp_port = serial->port[i];
+		tport->tp_tdev = tdev;
+		usb_set_serial_port_data(serial->port[i], tport);
+		tport->tp_uart_mode = 0;	/* default is RS232 */
+	}
+	
+	return 0;
+
+free_tports:
+	for (--i; i>=0; --i) {
+		tport = usb_get_serial_port_data(serial->port[i]);
+		ti_buf_free(tport->tp_write_buf);
+		kfree(tport);
+		usb_set_serial_port_data(serial->port[i], NULL);
+	}
+free_tdev:
+	kfree(tdev);
+	usb_set_serial_data(serial, NULL);
+	return status;
+}
+
+
+static void ti_shutdown(struct usb_serial *serial)
+{
+	int i;
+	struct ti_device *tdev = usb_get_serial_data(serial);
+	struct ti_port *tport;
+
+	dbg("%s", __FUNCTION__);
+
+	for (i=0; i < serial->num_ports; ++i) {
+		tport = usb_get_serial_port_data(serial->port[i]);
+		if (tport) {
+			ti_buf_free(tport->tp_write_buf);
+			kfree(tport);
+			usb_set_serial_port_data(serial->port[i], NULL);
+		}
+	}
+
+	if (tdev)
+		kfree(tdev);
+	usb_set_serial_data(serial, NULL);
+}
+
+
+static int ti_open(struct usb_serial_port *port, struct file *file)
+{
+	struct ti_port *tport = usb_get_serial_port_data(port);
+	struct ti_device *tdev;
+	struct usb_device *dev;
+	struct urb *urb;
+	int port_number;
+	int status;
+	__u16 open_settings = (__u8)(TI_PIPE_MODE_CONTINOUS | 
+			     TI_PIPE_TIMEOUT_ENABLE | 
+			     (TI_TRANSFER_TIMEOUT << 2));
+
+	dbg("%s - port %d", __FUNCTION__, port->number);
+
+	if (tport == NULL)
+		return -ENODEV;
+
+	dev = port->serial->dev;
+	tdev = tport->tp_tdev;
+
+	/* only one open on any port on a device at a time */
+	if (down_interruptible(&tdev->td_open_close_sem))
+		return -ERESTARTSYS;
+
+	if (port->tty)
+		port->tty->low_latency = 
+			(tport->tp_flags & ASYNC_LOW_LATENCY) ? 1 : 0;
+
+	port_number = port->number - port->serial->minor;
+
+	memset(&(tport->tp_icount), 0x00, sizeof(tport->tp_icount));
+
+	tport->tp_msr = 0;
+	tport->tp_shadow_mcr |= (TI_MCR_RTS | TI_MCR_DTR);
+
+	/* start interrupt urb the first time a port is opened on this device */
+	if (tdev->td_open_port_count == 0) {
+		dbg("%s - start interrupt in urb", __FUNCTION__);
+		urb = tdev->td_serial->port[0]->interrupt_in_urb;
+		if (!urb) {
+			dev_err(&port->dev, "%s - no interrupt urb\n", __FUNCTION__);
+			status = -EINVAL;
+			goto up_sem;
+		}
+		urb->complete = ti_interrupt_callback;
+		urb->context = tdev;
+		urb->dev = dev;
+		status = usb_submit_urb(urb, GFP_KERNEL);
+		if (status) {
+			dev_err(&port->dev, "%s - submit interrupt urb failed, %d\n", __FUNCTION__, status);
+			goto up_sem;
+		}
+	}
+
+	ti_set_termios(port, NULL);
+
+	dbg("%s - sending TI_OPEN_PORT", __FUNCTION__);
+	status = ti_command_out_sync(tdev, TI_OPEN_PORT,
+		(__u8)(TI_UART1_PORT + port_number), open_settings, NULL, 0);
+	if (status) {
+		dev_err(&port->dev, "%s - cannot send open command, %d\n", __FUNCTION__, status);
+		goto unlink_int_urb;
+	}
+
+	dbg("%s - sending TI_START_PORT", __FUNCTION__);
+	status = ti_command_out_sync(tdev, TI_START_PORT,
+		(__u8)(TI_UART1_PORT + port_number), 0, NULL, 0);
+	if (status) {
+		dev_err(&port->dev, "%s - cannot send start command, %d\n", __FUNCTION__, status);
+		goto unlink_int_urb;
+	}
+
+	dbg("%s - sending TI_PURGE_PORT", __FUNCTION__);
+	status = ti_command_out_sync(tdev, TI_PURGE_PORT,
+		(__u8)(TI_UART1_PORT + port_number), TI_PURGE_INPUT, NULL, 0);
+	if (status) {
+		dev_err(&port->dev, "%s - cannot clear input buffers, %d\n", __FUNCTION__, status);
+		goto unlink_int_urb;
+	}
+	status = ti_command_out_sync(tdev, TI_PURGE_PORT,
+		(__u8)(TI_UART1_PORT + port_number), TI_PURGE_OUTPUT, NULL, 0);
+	if (status) {
+		dev_err(&port->dev, "%s - cannot clear output buffers, %d\n", __FUNCTION__, status);
+		goto unlink_int_urb;
+	}
+
+	/* reset the data toggle on the bulk endpoints to work around bug in
+	 * host controllers where things get out of sync some times */
+	usb_clear_halt(dev, port->write_urb->pipe);
+	usb_clear_halt(dev, port->read_urb->pipe);
+
+	ti_set_termios(port, NULL);
+
+	dbg("%s - sending TI_OPEN_PORT (2)", __FUNCTION__);
+	status = ti_command_out_sync(tdev, TI_OPEN_PORT,
+		(__u8)(TI_UART1_PORT + port_number), open_settings, NULL, 0);
+	if (status) {
+		dev_err(&port->dev, "%s - cannot send open command (2), %d\n", __FUNCTION__, status);
+		goto unlink_int_urb;
+	}
+
+	dbg("%s - sending TI_START_PORT (2)", __FUNCTION__);
+	status = ti_command_out_sync(tdev, TI_START_PORT,
+		(__u8)(TI_UART1_PORT + port_number), 0, NULL, 0);
+	if (status) {
+		dev_err(&port->dev, "%s - cannot send start command (2), %d\n", __FUNCTION__, status);
+		goto unlink_int_urb;
+	}
+
+	/* start read urb */
+	dbg("%s - start read urb", __FUNCTION__);
+	urb = port->read_urb;
+	if (!urb) {
+		dev_err(&port->dev, "%s - no read urb\n", __FUNCTION__);
+		status = -EINVAL;
+		goto unlink_int_urb;
+	}
+	tport->tp_read_urb_state = TI_READ_URB_RUNNING;
+	urb->complete = ti_bulk_in_callback;
+	urb->context = tport;
+	urb->dev = dev;
+	status = usb_submit_urb(urb, GFP_KERNEL);
+	if (status) {
+		dev_err(&port->dev, "%s - submit read urb failed, %d\n", __FUNCTION__, status);
+		goto unlink_int_urb;
+	}
+
+	tport->tp_is_open = 1;
+	++tdev->td_open_port_count;
+
+	goto up_sem;
+
+unlink_int_urb:
+	if (tdev->td_open_port_count == 0)
+		usb_kill_urb(port->serial->port[0]->interrupt_in_urb);
+up_sem:
+	up(&tdev->td_open_close_sem);
+	dbg("%s - exit %d", __FUNCTION__, status);
+	return status;
+}
+
+
+static void ti_close(struct usb_serial_port *port, struct file *file)
+{
+	struct ti_device *tdev;
+	struct ti_port *tport;
+	int port_number;
+	int status;
+	int do_up;
+
+	dbg("%s - port %d", __FUNCTION__, port->number);
+			 
+	tdev = usb_get_serial_data(port->serial);
+	tport = usb_get_serial_port_data(port);
+	if (tdev == NULL || tport == NULL)
+		return;
+
+	tport->tp_is_open = 0;
+
+	ti_drain(tport, (tport->tp_closing_wait*HZ)/100, 1);
+
+	usb_kill_urb(port->read_urb);
+	usb_kill_urb(port->write_urb);
+	tport->tp_write_urb_in_use = 0;
+
+	port_number = port->number - port->serial->minor;
+
+	dbg("%s - sending TI_CLOSE_PORT", __FUNCTION__);
+	status = ti_command_out_sync(tdev, TI_CLOSE_PORT,
+		     (__u8)(TI_UART1_PORT + port_number), 0, NULL, 0);
+	if (status)
+		dev_err(&port->dev, "%s - cannot send close port command, %d\n" , __FUNCTION__, status);
+
+	/* if down is interrupted, continue anyway */
+	do_up = !down_interruptible(&tdev->td_open_close_sem);
+	--tport->tp_tdev->td_open_port_count;
+	if (tport->tp_tdev->td_open_port_count <= 0) {
+		/* last port is closed, shut down interrupt urb */
+		usb_kill_urb(port->serial->port[0]->interrupt_in_urb);
+		tport->tp_tdev->td_open_port_count = 0;
+	}
+	if (do_up)
+		up(&tdev->td_open_close_sem);
+
+	dbg("%s - exit", __FUNCTION__);
+}
+
+
+static int ti_write(struct usb_serial_port *port, const unsigned char *data,
+	int count)
+{
+	struct ti_port *tport = usb_get_serial_port_data(port);
+	unsigned long flags;
+
+	dbg("%s - port %d", __FUNCTION__, port->number);
+
+	if (count == 0) {
+		dbg("%s - write request of 0 bytes", __FUNCTION__);
+		return 0;
+	}
+
+	if (tport == NULL || !tport->tp_is_open)
+		return -ENODEV;
+
+	spin_lock_irqsave(&tport->tp_lock, flags);
+	count = ti_buf_put(tport->tp_write_buf, data, count);
+	spin_unlock_irqrestore(&tport->tp_lock, flags);
+
+	ti_send(tport);
+
+	return count;
+}
+
+
+static int ti_write_room(struct usb_serial_port *port)
+{
+	struct ti_port *tport = usb_get_serial_port_data(port);
+	int room = 0;
+	unsigned long flags;
+
+	dbg("%s - port %d", __FUNCTION__, port->number);
+
+	if (tport == NULL)
+		return -ENODEV;
+	
+	spin_lock_irqsave(&tport->tp_lock, flags);
+	room = ti_buf_space_avail(tport->tp_write_buf);
+	spin_unlock_irqrestore(&tport->tp_lock, flags);
+
+	dbg("%s - returns %d", __FUNCTION__, room);
+	return room;
+}
+
+
+static int ti_chars_in_buffer(struct usb_serial_port *port)
+{
+	struct ti_port *tport = usb_get_serial_port_data(port);
+	int chars = 0;
+	unsigned long flags;
+
+	dbg("%s - port %d", __FUNCTION__, port->number);
+
+	if (tport == NULL)
+		return -ENODEV;
+
+	spin_lock_irqsave(&tport->tp_lock, flags);
+	chars = ti_buf_data_avail(tport->tp_write_buf);
+	spin_unlock_irqrestore(&tport->tp_lock, flags);
+
+	dbg("%s - returns %d", __FUNCTION__, chars);
+	return chars;
+}
+
+
+static void ti_throttle(struct usb_serial_port *port)
+{
+	struct ti_port *tport = usb_get_serial_port_data(port);
+	struct tty_struct *tty;
+
+	dbg("%s - port %d", __FUNCTION__, port->number);
+
+	if (tport == NULL)
+		return;
+
+	tty = port->tty;
+	if (!tty) {
+		dbg("%s - no tty", __FUNCTION__);
+		return;
+	}
+
+	if (I_IXOFF(tty) || C_CRTSCTS(tty))
+		ti_stop_read(tport, tty);
+
+}
+
+
+static void ti_unthrottle(struct usb_serial_port *port)
+{
+	struct ti_port *tport = usb_get_serial_port_data(port);
+	struct tty_struct *tty;
+	int status;
+
+	dbg("%s - port %d", __FUNCTION__, port->number);
+
+	if (tport == NULL)
+		return;
+
+	tty = port->tty;
+	if (!tty) {
+		dbg("%s - no tty", __FUNCTION__);
+		return;
+	}
+
+	if (I_IXOFF(tty) || C_CRTSCTS(tty)) {
+		status = ti_restart_read(tport, tty);
+		if (status)
+			dev_err(&port->dev, "%s - cannot restart read, %d\n", __FUNCTION__, status);
+	}
+}
+
+
+static int ti_ioctl(struct usb_serial_port *port, struct file *file,
+	unsigned int cmd, unsigned long arg)
+{
+	struct ti_port *tport = usb_get_serial_port_data(port);
+	struct async_icount cnow;
+	struct async_icount cprev;
+
+	dbg("%s - port %d, cmd = 0x%04X", __FUNCTION__, port->number, cmd);
+
+	if (tport == NULL)
+		return -ENODEV;
+
+	switch (cmd) {
+		case TIOCGSERIAL:
+			dbg("%s - (%d) TIOCGSERIAL", __FUNCTION__, port->number);
+			return ti_get_serial_info(tport, (struct serial_struct __user *)arg);
+			break;
+
+		case TIOCSSERIAL:
+			dbg("%s - (%d) TIOCSSERIAL", __FUNCTION__, port->number);
+			return ti_set_serial_info(tport, (struct serial_struct __user *)arg);
+			break;
+
+		case TIOCMIWAIT:
+			dbg("%s - (%d) TIOCMIWAIT", __FUNCTION__, port->number);
+			cprev = tport->tp_icount;
+			while (1) {
+				interruptible_sleep_on(&tport->tp_msr_wait);
+				if (signal_pending(current))
+					return -ERESTARTSYS;
+				cnow = tport->tp_icount;
+				if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
+				    cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
+					return -EIO; /* no change => error */
+				if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
+				    ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
+				    ((arg & TIOCM_CD)  && (cnow.dcd != cprev.dcd)) ||
+				    ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)) ) {
+					return 0;
+				}
+				cprev = cnow;
+			}
+			break;
+
+		case TIOCGICOUNT:
+			dbg("%s - (%d) TIOCGICOUNT RX=%d, TX=%d", __FUNCTION__, port->number, tport->tp_icount.rx, tport->tp_icount.tx);
+			if (copy_to_user((void __user *)arg, &tport->tp_icount, sizeof(tport->tp_icount)))
+				return -EFAULT;
+			return 0;
+	}
+
+	return -ENOIOCTLCMD;
+}
+
+
+static void ti_set_termios(struct usb_serial_port *port,
+	struct termios *old_termios)
+{
+	struct ti_port *tport = usb_get_serial_port_data(port);
+	struct tty_struct *tty = port->tty;
+	struct ti_uart_config *config;
+	tcflag_t cflag,iflag;
+	int baud;
+	int status;
+	int port_number = port->number - port->serial->minor;
+	unsigned int mcr;
+
+	dbg("%s - port %d", __FUNCTION__, port->number);
+
+	if (!tty || !tty->termios) {
+		dbg("%s - no tty or termios", __FUNCTION__);
+		return;
+	}
+
+	cflag = tty->termios->c_cflag;
+	iflag = tty->termios->c_iflag;
+
+	if (old_termios && cflag == old_termios->c_cflag
+	&& iflag == old_termios->c_iflag) {
+		dbg("%s - nothing to change", __FUNCTION__);
+		return;
+	}
+
+	dbg("%s - clfag %08x, iflag %08x", __FUNCTION__, cflag, iflag);
+
+	if (old_termios)
+		dbg("%s - old clfag %08x, old iflag %08x", __FUNCTION__, old_termios->c_cflag, old_termios->c_iflag);
+
+	if (tport == NULL)
+		return;
+
+	config = kmalloc(sizeof(*config), GFP_KERNEL);
+	if (!config) {
+		dev_err(&port->dev, "%s - out of memory\n", __FUNCTION__);
+		return;
+	}
+
+	config->wFlags = 0;
+
+	/* these flags must be set */
+	config->wFlags |= TI_UART_ENABLE_MS_INTS;
+	config->wFlags |= TI_UART_ENABLE_AUTO_START_DMA;
+	config->bUartMode = (__u8)(tport->tp_uart_mode);
+
+	switch (cflag & CSIZE) {
+		case CS5:
+			    config->bDataBits = TI_UART_5_DATA_BITS;
+			    break;
+		case CS6:
+			    config->bDataBits = TI_UART_6_DATA_BITS;
+			    break;
+		case CS7:
+			    config->bDataBits = TI_UART_7_DATA_BITS;
+			    break;
+		default:
+		case CS8:
+			    config->bDataBits = TI_UART_8_DATA_BITS;
+			    break;
+	}
+
+	if (cflag & PARENB) {
+		if (cflag & PARODD) {
+			config->wFlags |= TI_UART_ENABLE_PARITY_CHECKING;
+			config->bParity = TI_UART_ODD_PARITY;
+		} else {
+			config->wFlags |= TI_UART_ENABLE_PARITY_CHECKING;
+			config->bParity = TI_UART_EVEN_PARITY;
+		}
+	} else {
+		config->wFlags &= ~TI_UART_ENABLE_PARITY_CHECKING;
+		config->bParity = TI_UART_NO_PARITY; 	
+	}
+
+	if (cflag & CSTOPB)
+		config->bStopBits = TI_UART_2_STOP_BITS;
+	else
+		config->bStopBits = TI_UART_1_STOP_BITS;
+
+	if (cflag & CRTSCTS) {
+		/* RTS flow control must be off to drop RTS for baud rate B0 */
+		if ((cflag & CBAUD) != B0)
+			config->wFlags |= TI_UART_ENABLE_RTS_IN;
+		config->wFlags |= TI_UART_ENABLE_CTS_OUT;
+	} else {
+		tty->hw_stopped = 0;
+		ti_restart_read(tport, tty);
+	}
+
+	if (I_IXOFF(tty) || I_IXON(tty)) {
+		config->cXon  = START_CHAR(tty);
+		config->cXoff = STOP_CHAR(tty);
+
+		if (I_IXOFF(tty))
+			config->wFlags |= TI_UART_ENABLE_X_IN;
+		else
+			ti_restart_read(tport, tty);
+
+		if (I_IXON(tty))
+			config->wFlags |= TI_UART_ENABLE_X_OUT;
+	}
+
+	baud = tty_get_baud_rate(tty);
+	if (!baud) baud = 9600;
+	if (tport->tp_tdev->td_is_3410)
+		config->wBaudRate = (__u16)((923077 + baud/2) / baud);
+	else
+		config->wBaudRate = (__u16)((461538 + baud/2) / baud);
+
+	dbg("%s - BaudRate=%d, wBaudRate=%d, wFlags=0x%04X, bDataBits=%d, bParity=%d, bStopBits=%d, cXon=%d, cXoff=%d, bUartMode=%d",
+	__FUNCTION__, baud, config->wBaudRate, config->wFlags, config->bDataBits, config->bParity, config->bStopBits, config->cXon, config->cXoff, config->bUartMode);
+
+	cpu_to_be16s(&config->wBaudRate);
+	cpu_to_be16s(&config->wFlags);
+
+	status = ti_command_out_sync(tport->tp_tdev, TI_SET_CONFIG,
+		(__u8)(TI_UART1_PORT + port_number), 0, (__u8 *)config,
+		sizeof(*config));
+	if (status)
+		dev_err(&port->dev, "%s - cannot set config on port %d, %d\n", __FUNCTION__, port_number, status);
+
+	/* SET_CONFIG asserts RTS and DTR, reset them correctly */
+	mcr = tport->tp_shadow_mcr;
+	/* if baud rate is B0, clear RTS and DTR */
+	if ((cflag & CBAUD) == B0)
+		mcr &= ~(TI_MCR_DTR | TI_MCR_RTS);
+	status = ti_set_mcr(tport, mcr);
+	if (status)
+		dev_err(&port->dev, "%s - cannot set modem control on port %d, %d\n", __FUNCTION__, port_number, status);
+
+	kfree(config);
+}
+
+
+static int ti_tiocmget(struct usb_serial_port *port, struct file *file)
+{
+	struct ti_port *tport = usb_get_serial_port_data(port);
+	unsigned int result;
+	unsigned int msr;
+	unsigned int mcr;
+
+	dbg("%s - port %d", __FUNCTION__, port->number);
+
+	if (tport == NULL)
+		return -ENODEV;
+
+	msr = tport->tp_msr;
+	mcr = tport->tp_shadow_mcr;
+
+	result = ((mcr & TI_MCR_DTR) ? TIOCM_DTR : 0)
+		| ((mcr & TI_MCR_RTS) ? TIOCM_RTS : 0)
+		| ((mcr & TI_MCR_LOOP) ? TIOCM_LOOP : 0)
+		| ((msr & TI_MSR_CTS) ? TIOCM_CTS : 0)
+		| ((msr & TI_MSR_CD) ? TIOCM_CAR : 0)
+		| ((msr & TI_MSR_RI) ? TIOCM_RI : 0)
+		| ((msr & TI_MSR_DSR) ? TIOCM_DSR : 0);
+
+	dbg("%s - 0x%04X", __FUNCTION__, result);
+
+	return result;
+}
+
+
+static int ti_tiocmset(struct usb_serial_port *port, struct file *file,
+	unsigned int set, unsigned int clear)
+{
+	struct ti_port *tport = usb_get_serial_port_data(port);
+	unsigned int mcr;
+
+	dbg("%s - port %d", __FUNCTION__, port->number);
+
+	if (tport == NULL)
+		return -ENODEV;
+
+	mcr = tport->tp_shadow_mcr;
+
+	if (set & TIOCM_RTS)
+		mcr |= TI_MCR_RTS;
+	if (set & TIOCM_DTR)
+		mcr |= TI_MCR_DTR;
+	if (set & TIOCM_LOOP)
+		mcr |= TI_MCR_LOOP;
+
+	if (clear & TIOCM_RTS)
+		mcr &= ~TI_MCR_RTS;
+	if (clear & TIOCM_DTR)
+		mcr &= ~TI_MCR_DTR;
+	if (clear & TIOCM_LOOP)
+		mcr &= ~TI_MCR_LOOP;
+
+	return ti_set_mcr(tport, mcr);
+}
+
+
+static void ti_break(struct usb_serial_port *port, int break_state)
+{
+	struct ti_port *tport = usb_get_serial_port_data(port);
+	int status;
+
+	dbg("%s - state = %d", __FUNCTION__, break_state);
+
+	if (tport == NULL)
+		return;
+
+	ti_drain(tport, (tport->tp_closing_wait*HZ)/100, 0);
+
+	status = ti_write_byte(tport->tp_tdev,
+		tport->tp_uart_base_addr + TI_UART_OFFSET_LCR,
+		TI_LCR_BREAK, break_state == -1 ? TI_LCR_BREAK : 0);
+
+	if (status)
+		dbg("%s - error setting break, %d", __FUNCTION__, status);
+}
+
+
+static void ti_interrupt_callback(struct urb *urb, struct pt_regs *regs)
+{
+	struct ti_device *tdev = (struct ti_device *)urb->context;
+	struct usb_serial_port *port;
+	struct usb_serial *serial = tdev->td_serial;
+	struct ti_port *tport;
+	struct device *dev = &urb->dev->dev;
+	unsigned char *data = urb->transfer_buffer;
+	int length = urb->actual_length;
+	int port_number;
+	int function;
+	int status;
+	__u8 msr;
+
+	dbg("%s", __FUNCTION__);
+
+	switch (urb->status) {
+	case 0:
+		break;
+	case -ECONNRESET:
+	case -ENOENT:
+	case -ESHUTDOWN:
+		dbg("%s - urb shutting down, %d", __FUNCTION__, urb->status);
+		tdev->td_urb_error = 1;
+		return;
+	default:
+		dev_err(dev, "%s - nonzero urb status, %d\n", __FUNCTION__, urb->status);
+		tdev->td_urb_error = 1;
+		goto exit;
+	}
+
+	if (length != 2) {
+		dbg("%s - bad packet size, %d", __FUNCTION__, length);
+		goto exit;
+	}
+
+	if (data[0] == TI_CODE_HARDWARE_ERROR) {
+		dev_err(dev, "%s - hardware error, %d\n", __FUNCTION__, data[1]);
+		goto exit;
+	}
+
+	port_number = TI_GET_PORT_FROM_CODE(data[0]);
+	function = TI_GET_FUNC_FROM_CODE(data[0]);
+
+	dbg("%s - port_number %d, function %d, data 0x%02X", __FUNCTION__, port_number, function, data[1]);
+
+	if (port_number >= serial->num_ports) {
+		dev_err(dev, "%s - bad port number, %d\n", __FUNCTION__, port_number);
+		goto exit;
+	}
+
+	port = serial->port[port_number];
+
+	tport = usb_get_serial_port_data(port);
+	if (!tport)
+		goto exit;
+
+	switch (function) {
+	case TI_CODE_DATA_ERROR:
+		dev_err(dev, "%s - DATA ERROR, port %d, data 0x%02X\n", __FUNCTION__, port_number, data[1]);
+		break;
+
+	case TI_CODE_MODEM_STATUS:
+		msr = data[1];
+		dbg("%s - port %d, msr 0x%02X", __FUNCTION__, port_number, msr);
+		ti_handle_new_msr(tport, msr);
+		break;
+
+	default:
+		dev_err(dev, "%s - unknown interrupt code, 0x%02X\n", __FUNCTION__, data[1]);
+		break;
+	}
+
+exit:
+	status = usb_submit_urb(urb, GFP_ATOMIC);
+	if (status)
+		dev_err(dev, "%s - resubmit interrupt urb failed, %d\n", __FUNCTION__, status);
+}
+
+
+static void ti_bulk_in_callback(struct urb *urb, struct pt_regs *regs)
+{
+	struct ti_port *tport = (struct ti_port *)urb->context;
+	struct usb_serial_port *port = tport->tp_port;
+	struct device *dev = &urb->dev->dev;
+	int status = 0;
+
+	dbg("%s", __FUNCTION__);
+
+	switch (urb->status) {
+	case 0:
+		break;
+	case -ECONNRESET:
+	case -ENOENT:
+	case -ESHUTDOWN:
+		dbg("%s - urb shutting down, %d", __FUNCTION__, urb->status);
+		tport->tp_tdev->td_urb_error = 1;
+		wake_up_interruptible(&tport->tp_write_wait);
+		return;
+	default:
+		dev_err(dev, "%s - nonzero urb status, %d\n", __FUNCTION__, urb->status );
+		tport->tp_tdev->td_urb_error = 1;
+		wake_up_interruptible(&tport->tp_write_wait);
+	}
+
+	if (urb->status == -EPIPE)
+		goto exit;
+
+	if (urb->status) {
+		dev_err(dev, "%s - stopping read!\n", __FUNCTION__);
+		return;
+	}
+
+	if (port->tty && urb->actual_length) {
+		usb_serial_debug_data(debug, dev, __FUNCTION__,
+			urb->actual_length, urb->transfer_buffer);
+
+		if (!tport->tp_is_open)
+			dbg("%s - port closed, dropping data", __FUNCTION__);
+		else
+			ti_recv(&urb->dev->dev, port->tty, urb->transfer_buffer,
+				urb->actual_length);
+
+		spin_lock(&tport->tp_lock);
+		tport->tp_icount.rx += urb->actual_length;
+		spin_unlock(&tport->tp_lock);
+	}
+
+exit:
+	/* continue to read unless stopping */
+	spin_lock(&tport->tp_lock);
+	if (tport->tp_read_urb_state == TI_READ_URB_RUNNING) {
+		urb->dev = port->serial->dev;
+		status = usb_submit_urb(urb, GFP_ATOMIC);
+	} else if (tport->tp_read_urb_state == TI_READ_URB_STOPPING) {
+		tport->tp_read_urb_state = TI_READ_URB_STOPPED;
+	}
+	spin_unlock(&tport->tp_lock);
+	if (status)
+		dev_err(dev, "%s - resubmit read urb failed, %d\n", __FUNCTION__, status);
+}
+
+
+static void ti_bulk_out_callback(struct urb *urb, struct pt_regs *regs)
+{
+	struct ti_port *tport = (struct ti_port *)urb->context;
+	struct usb_serial_port *port = tport->tp_port;
+	struct device *dev = &urb->dev->dev;
+
+	dbg("%s - port %d", __FUNCTION__, port->number);
+
+	tport->tp_write_urb_in_use = 0;
+
+	switch (urb->status) {
+	case 0:
+		break;
+	case -ECONNRESET:
+	case -ENOENT:
+	case -ESHUTDOWN:
+		dbg("%s - urb shutting down, %d", __FUNCTION__, urb->status);
+		tport->tp_tdev->td_urb_error = 1;
+		wake_up_interruptible(&tport->tp_write_wait);
+		return;
+	default:
+		dev_err(dev, "%s - nonzero urb status, %d\n", __FUNCTION__, urb->status);
+		tport->tp_tdev->td_urb_error = 1;
+		wake_up_interruptible(&tport->tp_write_wait);
+	}
+
+	/* send any buffered data */
+	ti_send(tport);
+}
+
+
+static void ti_recv(struct device *dev, struct tty_struct *tty,
+	unsigned char *data, int length)
+{
+	int cnt;
+
+	do {
+		if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
+			tty_flip_buffer_push(tty);
+			if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
+				dev_err(dev, "%s - dropping data, %d bytes lost\n", __FUNCTION__, length);
+				return;
+			}
+		}
+		cnt = min(length, TTY_FLIPBUF_SIZE - tty->flip.count);
+		memcpy(tty->flip.char_buf_ptr, data, cnt);
+		memset(tty->flip.flag_buf_ptr, 0, cnt);
+		tty->flip.char_buf_ptr += cnt;
+		tty->flip.flag_buf_ptr += cnt;
+		tty->flip.count += cnt;
+		data += cnt;
+		length -= cnt;
+	} while (length > 0);
+
+	tty_flip_buffer_push(tty);
+}
+
+
+static void ti_send(struct ti_port *tport)
+{
+	int count, result;
+	struct usb_serial_port *port = tport->tp_port;
+	struct tty_struct *tty = port->tty;
+	unsigned long flags;
+
+
+	dbg("%s - port %d", __FUNCTION__, port->number);
+
+	spin_lock_irqsave(&tport->tp_lock, flags);
+
+	if (tport->tp_write_urb_in_use) {
+		spin_unlock_irqrestore(&tport->tp_lock, flags);
+		return;
+	}
+
+	count = ti_buf_get(tport->tp_write_buf,
+				port->write_urb->transfer_buffer,
+				port->bulk_out_size);
+
+	if (count == 0) {
+		spin_unlock_irqrestore(&tport->tp_lock, flags);
+		return;
+	}
+
+	tport->tp_write_urb_in_use = 1;
+
+	spin_unlock_irqrestore(&tport->tp_lock, flags);
+
+	usb_serial_debug_data(debug, &port->dev, __FUNCTION__, count, port->write_urb->transfer_buffer);
+
+	usb_fill_bulk_urb(port->write_urb, port->serial->dev,
+			   usb_sndbulkpipe(port->serial->dev,
+					    port->bulk_out_endpointAddress),
+			   port->write_urb->transfer_buffer, count,
+			   ti_bulk_out_callback, tport);
+
+	result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
+	if (result) {
+		dev_err(&port->dev, "%s - submit write urb failed, %d\n", __FUNCTION__, result);
+		tport->tp_write_urb_in_use = 0; 
+		/* TODO: reschedule ti_send */
+	} else {
+		spin_lock_irqsave(&tport->tp_lock, flags);
+		tport->tp_icount.tx += count;
+		spin_unlock_irqrestore(&tport->tp_lock, flags);
+	}
+
+	/* more room in the buffer for new writes, wakeup */
+	if (tty)
+		tty_wakeup(tty);
+	wake_up_interruptible(&tport->tp_write_wait);
+}
+
+
+static int ti_set_mcr(struct ti_port *tport, unsigned int mcr)
+{
+	int status;
+
+	status = ti_write_byte(tport->tp_tdev,
+		tport->tp_uart_base_addr + TI_UART_OFFSET_MCR,
+		TI_MCR_RTS | TI_MCR_DTR | TI_MCR_LOOP, mcr);
+
+	if (!status)
+		tport->tp_shadow_mcr = mcr;
+
+	return status;
+}
+
+
+static int ti_get_lsr(struct ti_port *tport)
+{
+	int size,status;
+	struct ti_device *tdev = tport->tp_tdev;
+	struct usb_serial_port *port = tport->tp_port;
+	int port_number = port->number - port->serial->minor;
+	struct ti_port_status *data;
+
+	dbg("%s - port %d", __FUNCTION__, port->number);
+
+	size = sizeof(struct ti_port_status);
+	data = kmalloc(size, GFP_KERNEL);
+	if (!data) {
+		dev_err(&port->dev, "%s - out of memory\n", __FUNCTION__);
+		return -ENOMEM;
+	}
+
+	status = ti_command_in_sync(tdev, TI_GET_PORT_STATUS,
+		(__u8)(TI_UART1_PORT+port_number), 0, (__u8 *)data, size);
+	if (status) {
+		dev_err(&port->dev, "%s - get port status command failed, %d\n", __FUNCTION__, status);
+		goto free_data;
+	}
+
+	dbg("%s - lsr 0x%02X", __FUNCTION__, data->bLSR);
+
+	tport->tp_lsr = data->bLSR;
+
+free_data:
+	kfree(data);
+	return status;
+}
+
+
+static int ti_get_serial_info(struct ti_port *tport,
+	struct serial_struct __user *ret_arg)
+{
+	struct usb_serial_port *port = tport->tp_port;
+	struct serial_struct ret_serial;
+
+	if (!ret_arg)
+		return -EFAULT;
+
+	memset(&ret_serial, 0, sizeof(ret_serial));
+
+	ret_serial.type = PORT_16550A;
+	ret_serial.line = port->serial->minor;
+	ret_serial.port = port->number - port->serial->minor;
+	ret_serial.flags = tport->tp_flags;
+	ret_serial.xmit_fifo_size = TI_WRITE_BUF_SIZE;
+	ret_serial.baud_base = tport->tp_tdev->td_is_3410 ? 921600 : 460800;
+	ret_serial.closing_wait = tport->tp_closing_wait;
+
+	if (copy_to_user(ret_arg, &ret_serial, sizeof(*ret_arg)))
+		return -EFAULT;
+
+	return 0;
+}
+
+
+static int ti_set_serial_info(struct ti_port *tport,
+	struct serial_struct __user *new_arg)
+{
+	struct usb_serial_port *port = tport->tp_port;
+	struct serial_struct new_serial;
+
+	if (copy_from_user(&new_serial, new_arg, sizeof(new_serial)))
+		return -EFAULT;
+
+	tport->tp_flags = new_serial.flags & TI_SET_SERIAL_FLAGS;
+	if (port->tty)
+		port->tty->low_latency =
+			(tport->tp_flags & ASYNC_LOW_LATENCY) ? 1 : 0;
+	tport->tp_closing_wait = new_serial.closing_wait;
+
+	return 0;
+}
+
+
+static void ti_handle_new_msr(struct ti_port *tport, __u8 msr)
+{
+	struct async_icount *icount;
+	struct tty_struct *tty;
+	unsigned long flags;
+
+	dbg("%s - msr 0x%02X", __FUNCTION__, msr);
+
+	if (msr & TI_MSR_DELTA_MASK) {
+		spin_lock_irqsave(&tport->tp_lock, flags);
+		icount = &tport->tp_icount;
+		if (msr & TI_MSR_DELTA_CTS)
+			icount->cts++;
+		if (msr & TI_MSR_DELTA_DSR)
+			icount->dsr++;
+		if (msr & TI_MSR_DELTA_CD)
+			icount->dcd++;
+		if (msr & TI_MSR_DELTA_RI)
+			icount->rng++;
+		wake_up_interruptible(&tport->tp_msr_wait);
+		spin_unlock_irqrestore(&tport->tp_lock, flags);
+	}
+
+	tport->tp_msr = msr & TI_MSR_MASK;
+
+	/* handle CTS flow control */
+	tty = tport->tp_port->tty;
+	if (tty && C_CRTSCTS(tty)) {
+		if (msr & TI_MSR_CTS) {
+			tty->hw_stopped = 0;
+			tty_wakeup(tty);
+		} else {
+			tty->hw_stopped = 1;
+		}
+	}
+}
+
+
+static void ti_drain(struct ti_port *tport, unsigned long timeout, int flush)
+{
+	struct ti_device *tdev = tport->tp_tdev;
+	struct usb_serial_port *port = tport->tp_port;
+	wait_queue_t wait;
+	unsigned long flags;
+
+	dbg("%s - port %d", __FUNCTION__, port->number);
+
+	spin_lock_irqsave(&tport->tp_lock, flags);
+
+	/* wait for data to drain from the buffer */
+	tdev->td_urb_error = 0;
+	init_waitqueue_entry(&wait, current);
+	add_wait_queue(&tport->tp_write_wait, &wait);
+	for (;;) {
+		set_current_state(TASK_INTERRUPTIBLE);
+		if (ti_buf_data_avail(tport->tp_write_buf) == 0
+		|| timeout == 0 || signal_pending(current)
+		|| tdev->td_urb_error
+		|| !usb_get_intfdata(port->serial->interface))  /* disconnect */
+			break;
+		spin_unlock_irqrestore(&tport->tp_lock, flags);
+		timeout = schedule_timeout(timeout);
+		spin_lock_irqsave(&tport->tp_lock, flags);
+	}
+	set_current_state(TASK_RUNNING);
+	remove_wait_queue(&tport->tp_write_wait, &wait);
+
+	/* flush any remaining data in the buffer */
+	if (flush)
+		ti_buf_clear(tport->tp_write_buf);
+
+	spin_unlock_irqrestore(&tport->tp_lock, flags);
+
+	/* wait for data to drain from the device */
+	/* wait for empty tx register, plus 20 ms */
+	timeout += jiffies;
+	tport->tp_lsr &= ~TI_LSR_TX_EMPTY;
+	while ((long)(jiffies - timeout) < 0 && !signal_pending(current)
+	&& !(tport->tp_lsr&TI_LSR_TX_EMPTY) && !tdev->td_urb_error
+	&& usb_get_intfdata(port->serial->interface)) {  /* not disconnected */
+		if (ti_get_lsr(tport))
+			break;
+		msleep_interruptible(20);
+	}
+}
+
+
+static void ti_stop_read(struct ti_port *tport, struct tty_struct *tty)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&tport->tp_lock, flags);
+
+	if (tport->tp_read_urb_state == TI_READ_URB_RUNNING)
+		tport->tp_read_urb_state = TI_READ_URB_STOPPING;
+
+	spin_unlock_irqrestore(&tport->tp_lock, flags);
+}
+
+
+static int ti_restart_read(struct ti_port *tport, struct tty_struct *tty)
+{
+	struct urb *urb;
+	int status = 0;
+	unsigned long flags;
+
+	spin_lock_irqsave(&tport->tp_lock, flags);
+
+	if (tport->tp_read_urb_state == TI_READ_URB_STOPPED) {
+		urb = tport->tp_port->read_urb;
+		urb->complete = ti_bulk_in_callback;
+		urb->context = tport;
+		urb->dev = tport->tp_port->serial->dev;
+		status = usb_submit_urb(urb, GFP_KERNEL);
+	}
+	tport->tp_read_urb_state = TI_READ_URB_RUNNING;
+
+	spin_unlock_irqrestore(&tport->tp_lock, flags);
+
+	return status;
+}
+
+
+static int ti_command_out_sync(struct ti_device *tdev, __u8 command,
+	__u16 moduleid, __u16 value, __u8 *data, int size)
+{
+	int status;
+
+	status = usb_control_msg(tdev->td_serial->dev,
+		usb_sndctrlpipe(tdev->td_serial->dev, 0), command,
+		(USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT),
+		value, moduleid, data, size, HZ);
+
+	if (status == size)
+		status = 0;
+
+	if (status > 0)
+		status = -ECOMM;
+
+	return status;
+}
+
+
+static int ti_command_in_sync(struct ti_device *tdev, __u8 command,
+	__u16 moduleid, __u16 value, __u8 *data, int size)
+{
+	int status;
+
+	status = usb_control_msg(tdev->td_serial->dev,
+		usb_rcvctrlpipe(tdev->td_serial->dev, 0), command,
+		(USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN),
+		value, moduleid, data, size, HZ);
+
+	if (status == size)
+		status = 0;
+
+	if (status > 0)
+		status = -ECOMM;
+
+	return status;
+}
+
+
+static int ti_write_byte(struct ti_device *tdev, unsigned long addr,
+	__u8 mask, __u8 byte)
+{
+	int status;
+	unsigned int size;
+	struct ti_write_data_bytes *data;
+	struct device *dev = &tdev->td_serial->dev->dev;
+
+	dbg("%s - addr 0x%08lX, mask 0x%02X, byte 0x%02X", __FUNCTION__, addr, mask, byte);
+
+	size = sizeof(struct ti_write_data_bytes) + 2;
+	data = kmalloc(size, GFP_KERNEL);
+	if (!data) {
+		dev_err(dev, "%s - out of memory\n", __FUNCTION__);
+		return -ENOMEM;
+	}
+
+	data->bAddrType = TI_RW_DATA_ADDR_XDATA;
+	data->bDataType = TI_RW_DATA_BYTE;
+	data->bDataCounter = 1;
+	data->wBaseAddrHi = cpu_to_be16(addr>>16);
+	data->wBaseAddrLo = cpu_to_be16(addr);
+	data->bData[0] = mask;
+	data->bData[1] = byte;
+
+	status = ti_command_out_sync(tdev, TI_WRITE_DATA, TI_RAM_PORT, 0,
+		(__u8 *)data, size);
+
+	if (status < 0)
+		dev_err(dev, "%s - failed, %d\n", __FUNCTION__, status);
+
+	kfree(data);
+
+	return status;
+}
+
+
+static int ti_download_firmware(struct ti_device *tdev,
+	unsigned char *firmware, unsigned int firmware_size)
+{
+	int status = 0;
+	int buffer_size;
+	int pos;
+	int len;
+	int done;
+	__u8 cs = 0;
+	__u8 *buffer;
+	struct usb_device *dev = tdev->td_serial->dev;
+	struct ti_firmware_header *header;
+	unsigned int pipe = usb_sndbulkpipe(dev,
+		tdev->td_serial->port[0]->bulk_out_endpointAddress);
+
+
+	buffer_size = TI_FIRMWARE_BUF_SIZE + sizeof(struct ti_firmware_header);
+	buffer = kmalloc(buffer_size, GFP_KERNEL);
+	if (!buffer) {
+		dev_err(&dev->dev, "%s - out of memory\n", __FUNCTION__);
+		return -ENOMEM;
+	}
+
+	memcpy(buffer, firmware, firmware_size);
+	memset(buffer+firmware_size, 0xff, buffer_size-firmware_size);
+
+	for(pos = sizeof(struct ti_firmware_header); pos < buffer_size; pos++)
+		cs = (__u8)(cs + buffer[pos]);
+
+	header = (struct ti_firmware_header *)buffer;
+	header->wLength = cpu_to_le16((__u16)(buffer_size - sizeof(struct ti_firmware_header)));
+	header->bCheckSum = cs;
+
+	dbg("%s - downloading firmware", __FUNCTION__);
+	for (pos = 0; pos < buffer_size; pos += done) {
+		len = min(buffer_size - pos, TI_DOWNLOAD_MAX_PACKET_SIZE);
+		status = usb_bulk_msg(dev, pipe, buffer+pos, len, &done, HZ);
+		if (status)
+			break;
+	}
+
+	kfree(buffer);
+
+	if (status) {
+		dev_err(&dev->dev, "%s - error downloading firmware, %d\n", __FUNCTION__, status);
+		return status;
+	}
+
+	dbg("%s - download successful", __FUNCTION__);
+
+	return 0;
+}
+
+
+/* Circular Buffer Functions */
+
+/*
+ * ti_buf_alloc
+ *
+ * Allocate a circular buffer and all associated memory.
+ */
+
+static struct circ_buf *ti_buf_alloc(void)
+{
+	struct circ_buf *cb;
+
+	cb = (struct circ_buf *)kmalloc(sizeof(struct circ_buf), GFP_KERNEL);
+	if (cb == NULL)
+		return NULL;
+
+	cb->buf = kmalloc(TI_WRITE_BUF_SIZE, GFP_KERNEL);
+	if (cb->buf == NULL) {
+		kfree(cb);
+		return NULL;
+	}
+
+	ti_buf_clear(cb);
+
+	return cb;
+}
+
+
+/*
+ * ti_buf_free
+ *
+ * Free the buffer and all associated memory.
+ */
+
+static void ti_buf_free(struct circ_buf *cb)
+{
+	kfree(cb->buf);
+	kfree(cb);
+}
+
+
+/*
+ * ti_buf_clear
+ *
+ * Clear out all data in the circular buffer.
+ */
+
+static void ti_buf_clear(struct circ_buf *cb)
+{
+	cb->head = cb->tail = 0;
+}
+
+
+/*
+ * ti_buf_data_avail
+ *
+ * Return the number of bytes of data available in the circular
+ * buffer.
+ */
+
+static int ti_buf_data_avail(struct circ_buf *cb)
+{
+	return CIRC_CNT(cb->head,cb->tail,TI_WRITE_BUF_SIZE);
+}
+
+
+/*
+ * ti_buf_space_avail
+ *
+ * Return the number of bytes of space available in the circular
+ * buffer.
+ */
+
+static int ti_buf_space_avail(struct circ_buf *cb)
+{
+	return CIRC_SPACE(cb->head,cb->tail,TI_WRITE_BUF_SIZE);
+}
+
+
+/*
+ * ti_buf_put
+ *
+ * Copy data data from a user buffer and put it into the circular buffer.
+ * Restrict to the amount of space available.
+ *
+ * Return the number of bytes copied.
+ */
+
+static int ti_buf_put(struct circ_buf *cb, const char *buf, int count)
+{
+	int c, ret = 0;
+
+	while (1) {
+		c = CIRC_SPACE_TO_END(cb->head, cb->tail, TI_WRITE_BUF_SIZE);
+		if (count < c)
+			c = count;
+		if (c <= 0)
+			break;
+		memcpy(cb->buf + cb->head, buf, c);
+		cb->head = (cb->head + c) & (TI_WRITE_BUF_SIZE-1);
+		buf += c;
+		count -= c;
+		ret += c;
+	}
+
+	return ret;
+}
+
+
+/*
+ * ti_buf_get
+ *
+ * Get data from the circular buffer and copy to the given buffer.
+ * Restrict to the amount of data available.
+ *
+ * Return the number of bytes copied.
+ */
+
+static int ti_buf_get(struct circ_buf *cb, char *buf, int count)
+{
+	int c, ret = 0;
+
+	while (1) {
+		c = CIRC_CNT_TO_END(cb->head, cb->tail, TI_WRITE_BUF_SIZE);
+		if (count < c)
+			c = count;
+		if (c <= 0)
+			break;
+		memcpy(buf, cb->buf + cb->tail, c);
+		cb->tail = (cb->tail + c) & (TI_WRITE_BUF_SIZE-1);
+		buf += c;
+		count -= c;
+		ret += c;
+	}
+
+	return ret;
+}
diff -Nru a/drivers/usb/serial/ti_usb_3410_5052.h b/drivers/usb/serial/ti_usb_3410_5052.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/usb/serial/ti_usb_3410_5052.h	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,224 @@
+/* vi: ts=8 sw=8
+ *
+ * TI 3410/5052 USB Serial Driver Header
+ *
+ * Copyright (C) 2004 Texas Instruments
+ *
+ * This driver is based on the Linux io_ti driver, which is
+ *   Copyright (C) 2000-2002 Inside Out Networks
+ *   Copyright (C) 2001-2002 Greg Kroah-Hartman
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * For questions or problems with this driver, contact Texas Instruments
+ * technical support, or Al Borchers <alborchers@steinerpoint.com>, or
+ * Peter Berger <pberger@brimson.com>.
+ */
+
+#ifndef _TI_3410_5052_H_
+#define _TI_3410_5052_H_
+
+/* Configuration ids */
+#define TI_BOOT_CONFIG			1
+#define TI_ACTIVE_CONFIG		2
+
+/* Vendor and product ids */
+#define TI_VENDOR_ID			0x0451
+#define TI_3410_PRODUCT_ID		0x3410
+#define TI_5052_BOOT_PRODUCT_ID		0x5052	/* no EEPROM, no firmware */
+#define TI_5152_BOOT_PRODUCT_ID		0x5152	/* no EEPROM, no firmware */
+#define TI_5052_EEPROM_PRODUCT_ID	0x505A	/* EEPROM, no firmware */
+#define TI_5052_FIRMWARE_PRODUCT_ID	0x505F	/* firmware is running */
+
+/* Commands */
+#define TI_GET_VERSION			0x01
+#define TI_GET_PORT_STATUS		0x02
+#define TI_GET_PORT_DEV_INFO		0x03
+#define TI_GET_CONFIG			0x04
+#define TI_SET_CONFIG			0x05
+#define TI_OPEN_PORT			0x06
+#define TI_CLOSE_PORT			0x07
+#define TI_START_PORT			0x08
+#define TI_STOP_PORT			0x09
+#define TI_TEST_PORT			0x0A
+#define TI_PURGE_PORT			0x0B
+#define TI_RESET_EXT_DEVICE		0x0C
+#define TI_WRITE_DATA			0x80
+#define TI_READ_DATA			0x81
+#define TI_REQ_TYPE_CLASS		0x82
+
+/* Module identifiers */
+#define TI_I2C_PORT			0x01
+#define TI_IEEE1284_PORT		0x02
+#define TI_UART1_PORT			0x03
+#define TI_UART2_PORT			0x04
+#define TI_RAM_PORT			0x05
+
+/* Modem status */
+#define TI_MSR_DELTA_CTS		0x01
+#define TI_MSR_DELTA_DSR		0x02
+#define TI_MSR_DELTA_RI			0x04
+#define TI_MSR_DELTA_CD			0x08
+#define TI_MSR_CTS			0x10
+#define TI_MSR_DSR			0x20
+#define TI_MSR_RI			0x40
+#define TI_MSR_CD			0x80
+#define TI_MSR_DELTA_MASK		0x0F
+#define TI_MSR_MASK			0xF0
+
+/* Line status */
+#define TI_LSR_OVERRUN_ERROR		0x01
+#define TI_LSR_PARITY_ERROR		0x02
+#define TI_LSR_FRAMING_ERROR		0x04
+#define TI_LSR_BREAK			0x08
+#define TI_LSR_ERROR			0x0F
+#define TI_LSR_RX_FULL			0x10
+#define TI_LSR_TX_EMPTY			0x20
+
+/* Line control */
+#define TI_LCR_BREAK			0x40
+
+/* Modem control */
+#define TI_MCR_LOOP			0x04
+#define TI_MCR_DTR			0x10
+#define TI_MCR_RTS			0x20
+
+/* Mask settings */
+#define TI_UART_ENABLE_RTS_IN		0x0001
+#define TI_UART_DISABLE_RTS		0x0002
+#define TI_UART_ENABLE_PARITY_CHECKING	0x0008
+#define TI_UART_ENABLE_DSR_OUT		0x0010
+#define TI_UART_ENABLE_CTS_OUT		0x0020
+#define TI_UART_ENABLE_X_OUT		0x0040
+#define TI_UART_ENABLE_XA_OUT		0x0080
+#define TI_UART_ENABLE_X_IN		0x0100
+#define TI_UART_ENABLE_DTR_IN		0x0800
+#define TI_UART_DISABLE_DTR		0x1000
+#define TI_UART_ENABLE_MS_INTS		0x2000
+#define TI_UART_ENABLE_AUTO_START_DMA	0x4000
+
+/* Parity */
+#define TI_UART_NO_PARITY		0x00
+#define TI_UART_ODD_PARITY		0x01
+#define TI_UART_EVEN_PARITY		0x02
+#define TI_UART_MARK_PARITY		0x03
+#define TI_UART_SPACE_PARITY		0x04
+
+/* Stop bits */
+#define TI_UART_1_STOP_BITS		0x00
+#define TI_UART_1_5_STOP_BITS		0x01
+#define TI_UART_2_STOP_BITS		0x02
+
+/* Bits per character */
+#define TI_UART_5_DATA_BITS		0x00
+#define TI_UART_6_DATA_BITS		0x01
+#define TI_UART_7_DATA_BITS		0x02
+#define TI_UART_8_DATA_BITS		0x03
+
+/* 232/485 modes */
+#define TI_UART_232			0x00
+#define TI_UART_485_RECEIVER_DISABLED	0x01
+#define TI_UART_485_RECEIVER_ENABLED	0x02
+
+/* Pipe transfer mode and timeout */
+#define TI_PIPE_MODE_CONTINOUS		0x01
+#define TI_PIPE_MODE_MASK		0x03
+#define TI_PIPE_TIMEOUT_MASK		0x7C
+#define TI_PIPE_TIMEOUT_ENABLE		0x80
+
+/* Config struct */
+struct ti_uart_config {
+	__u16	wBaudRate;
+	__u16	wFlags;
+	__u8	bDataBits;
+	__u8	bParity;
+	__u8	bStopBits;
+	char	cXon;
+	char	cXoff;
+	__u8	bUartMode;
+} __attribute__((packed));
+
+/* Get port status */
+struct ti_port_status {
+	__u8	bCmdCode;
+	__u8	bModuleId;
+	__u8	bErrorCode;
+	__u8	bMSR;
+	__u8	bLSR;
+} __attribute__((packed));
+
+/* Purge modes */
+#define TI_PURGE_OUTPUT			0x00
+#define TI_PURGE_INPUT			0x80
+
+/* Read/Write data */
+#define TI_RW_DATA_ADDR_SFR		0x10
+#define TI_RW_DATA_ADDR_IDATA		0x20
+#define TI_RW_DATA_ADDR_XDATA		0x30
+#define TI_RW_DATA_ADDR_CODE		0x40
+#define TI_RW_DATA_ADDR_GPIO		0x50
+#define TI_RW_DATA_ADDR_I2C		0x60
+#define TI_RW_DATA_ADDR_FLASH		0x70
+#define TI_RW_DATA_ADDR_DSP		0x80
+
+#define TI_RW_DATA_UNSPECIFIED		0x00
+#define TI_RW_DATA_BYTE			0x01
+#define TI_RW_DATA_WORD			0x02
+#define TI_RW_DATA_DOUBLE_WORD		0x04
+
+struct ti_write_data_bytes {
+	__u8	bAddrType;
+	__u8	bDataType;
+	__u8	bDataCounter;
+	__be16	wBaseAddrHi;
+	__be16	wBaseAddrLo;
+	__u8	bData[0];
+} __attribute__((packed));
+
+struct ti_read_data_request {
+	__u8	bAddrType;
+	__u8	bDataType;
+	__u8	bDataCounter;
+	__be16	wBaseAddrHi;
+	__be16	wBaseAddrLo;
+} __attribute__((packed));
+
+struct ti_read_data_bytes {
+	__u8	bCmdCode;
+	__u8	bModuleId;
+	__u8	bErrorCode;
+	__u8	bData[0];
+} __attribute__((packed));
+
+/* Interrupt struct */
+struct ti_interrupt {
+	__u8	bICode;
+	__u8	bIInfo;
+} __attribute__((packed));
+
+/* Interrupt codes */
+#define TI_GET_PORT_FROM_CODE(c)	(((c) >> 4) - 3)
+#define TI_GET_FUNC_FROM_CODE(c)	((c) & 0x0f)
+#define TI_CODE_HARDWARE_ERROR		0xFF
+#define TI_CODE_DATA_ERROR		0x03
+#define TI_CODE_MODEM_STATUS		0x04
+
+/* Download firmware max packet size */
+#define TI_DOWNLOAD_MAX_PACKET_SIZE	64
+
+/* Firmware image header */
+struct ti_firmware_header {
+	__le16	wLength;
+	__u8	bCheckSum;
+} __attribute__((packed));
+
+/* UART addresses */
+#define TI_UART1_BASE_ADDR		0xFFA0	/* UART 1 base address */
+#define TI_UART2_BASE_ADDR		0xFFB0	/* UART 2 base address */
+#define TI_UART_OFFSET_LCR		0x0002	/* UART MCR register offset */
+#define TI_UART_OFFSET_MCR		0x0004	/* UART MCR register offset */
+
+#endif /* _TI_3410_5052_H_ */
diff -Nru a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
--- a/drivers/usb/serial/usb-serial.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/usb/serial/usb-serial.c	2005-03-01 23:39:18 -08:00
@@ -721,7 +721,9 @@
 		if (serial->type->owner)
 			length += sprintf (page+length, " module:%s", module_name(serial->type->owner));
 		length += sprintf (page+length, " name:\"%s\"", serial->type->name);
-		length += sprintf (page+length, " vendor:%04x product:%04x", serial->vendor, serial->product);
+		length += sprintf (page+length, " vendor:%04x product:%04x", 
+				   le16_to_cpu(serial->dev->descriptor.idVendor), 
+				   le16_to_cpu(serial->dev->descriptor.idProduct));
 		length += sprintf (page+length, " num_ports:%d", serial->num_ports);
 		length += sprintf (page+length, " port:%d", i - serial->minor + 1);
 
@@ -834,8 +836,6 @@
 	serial->dev = usb_get_dev(dev);
 	serial->type = type;
 	serial->interface = interface;
-	serial->vendor = dev->descriptor.idVendor;
-	serial->product = dev->descriptor.idProduct;
 	kref_init(&serial->kref);
 
 	return serial;
@@ -959,10 +959,10 @@
 #if defined(CONFIG_USB_SERIAL_PL2303) || defined(CONFIG_USB_SERIAL_PL2303_MODULE)
 	/* BEGIN HORRIBLE HACK FOR PL2303 */ 
 	/* this is needed due to the looney way its endpoints are set up */
-	if (((dev->descriptor.idVendor == PL2303_VENDOR_ID) &&
-	     (dev->descriptor.idProduct == PL2303_PRODUCT_ID)) ||
-	    ((dev->descriptor.idVendor == ATEN_VENDOR_ID) &&
-	     (dev->descriptor.idProduct == ATEN_PRODUCT_ID))) {
+	if (((le16_to_cpu(dev->descriptor.idVendor) == PL2303_VENDOR_ID) &&
+	     (le16_to_cpu(dev->descriptor.idProduct) == PL2303_PRODUCT_ID)) ||
+	    ((le16_to_cpu(dev->descriptor.idVendor) == ATEN_VENDOR_ID) &&
+	     (le16_to_cpu(dev->descriptor.idProduct) == ATEN_PRODUCT_ID))) {
 		if (interface != dev->actconfig->interface[0]) {
 			/* check out the endpoints of the other interface*/
 			iface_desc = dev->actconfig->interface[0]->cur_altsetting;
@@ -1060,7 +1060,7 @@
 			dev_err(&interface->dev, "No free urbs available\n");
 			goto probe_error;
 		}
-		buffer_size = endpoint->wMaxPacketSize;
+		buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
 		port->bulk_in_size = buffer_size;
 		port->bulk_in_endpointAddress = endpoint->bEndpointAddress;
 		port->bulk_in_buffer = kmalloc (buffer_size, GFP_KERNEL);
@@ -1084,7 +1084,7 @@
 			dev_err(&interface->dev, "No free urbs available\n");
 			goto probe_error;
 		}
-		buffer_size = endpoint->wMaxPacketSize;
+		buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
 		port->bulk_out_size = buffer_size;
 		port->bulk_out_endpointAddress = endpoint->bEndpointAddress;
 		port->bulk_out_buffer = kmalloc (buffer_size, GFP_KERNEL);
@@ -1109,7 +1109,7 @@
 				dev_err(&interface->dev, "No free urbs available\n");
 				goto probe_error;
 			}
-			buffer_size = endpoint->wMaxPacketSize;
+			buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
 			port->interrupt_in_endpointAddress = endpoint->bEndpointAddress;
 			port->interrupt_in_buffer = kmalloc (buffer_size, GFP_KERNEL);
 			if (!port->interrupt_in_buffer) {
@@ -1136,7 +1136,7 @@
 				dev_err(&interface->dev, "No free urbs available\n");
 				goto probe_error;
 			}
-			buffer_size = endpoint->wMaxPacketSize;
+			buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
 			port->interrupt_out_size = buffer_size;
 			port->interrupt_out_endpointAddress = endpoint->bEndpointAddress;
 			port->interrupt_out_buffer = kmalloc (buffer_size, GFP_KERNEL);
@@ -1238,13 +1238,20 @@
 
 void usb_serial_disconnect(struct usb_interface *interface)
 {
+	int i;
 	struct usb_serial *serial = usb_get_intfdata (interface);
 	struct device *dev = &interface->dev;
+	struct usb_serial_port *port;
 
 	dbg ("%s", __FUNCTION__);
 
 	usb_set_intfdata (interface, NULL);
 	if (serial) {
+		for (i = 0; i < serial->num_ports; ++i) {
+			port = serial->port[i];
+			if (port && port->tty)
+				tty_hangup(port->tty);
+		}
 		/* let the last holder of this object 
 		 * cause it to be cleaned up */
 		kref_put(&serial->kref, destroy_serial);
diff -Nru a/drivers/usb/serial/usb-serial.h b/drivers/usb/serial/usb-serial.h
--- a/drivers/usb/serial/usb-serial.h	2005-03-01 23:39:18 -08:00
+++ b/drivers/usb/serial/usb-serial.h	2005-03-01 23:39:18 -08:00
@@ -148,8 +148,6 @@
  * @num_interrupt_out: number of interrupt out endpoints we have
  * @num_bulk_in: number of bulk in endpoints we have
  * @num_bulk_out: number of bulk out endpoints we have
- * @vendor: vendor id of this device
- * @product: product id of this device
  * @port: array of struct usb_serial_port structures for the different ports.
  * @private: place to put any driver specific information that is needed.  The
  *	usb-serial driver is required to manage this data, the usb-serial core
@@ -167,8 +165,6 @@
 	char				num_interrupt_out;
 	char				num_bulk_in;
 	char				num_bulk_out;
-	__u16				vendor;
-	__u16				product;
 	struct usb_serial_port *	port[MAX_NUM_PORTS];
 	struct kref			kref;
 	void *				private;
diff -Nru a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c
--- a/drivers/usb/serial/visor.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/usb/serial/visor.c	2005-03-01 23:38:54 -08:00
@@ -734,9 +734,7 @@
 	if (retval == sizeof(*connection_info)) {
 	        connection_info = (struct visor_connection_info *)transfer_buffer;
 
-		le16_to_cpus(&connection_info->num_ports);
-		num_ports = connection_info->num_ports;
-
+		num_ports = le16_to_cpu(connection_info->num_ports);
 		for (i = 0; i < num_ports; ++i) {
 			switch (connection_info->connections[i].port_function_id) {
 				case VISOR_FUNCTION_GENERIC:
@@ -926,8 +924,8 @@
 
 	/* Only do this endpoint hack for the Handspring devices with
 	 * interrupt in endpoints, which for now are the Treo devices. */
-	if (!((serial->dev->descriptor.idVendor == HANDSPRING_VENDOR_ID) ||
-	      (serial->dev->descriptor.idVendor == KYOCERA_VENDOR_ID)) ||
+	if (!((le16_to_cpu(serial->dev->descriptor.idVendor) == HANDSPRING_VENDOR_ID) ||
+	      (le16_to_cpu(serial->dev->descriptor.idVendor) == KYOCERA_VENDOR_ID)) ||
 	    (serial->num_interrupt_in == 0))
 		goto generic_startup;
 
diff -Nru a/drivers/usb/serial/visor.h b/drivers/usb/serial/visor.h
--- a/drivers/usb/serial/visor.h	2005-03-01 23:39:09 -08:00
+++ b/drivers/usb/serial/visor.h	2005-03-01 23:39:09 -08:00
@@ -89,7 +89,7 @@
  * VISOR_GET_CONNECTION_INFORMATION returns data in the following format
  ****************************************************************************/
 struct visor_connection_info {
-	__u16	num_ports;
+	__le16	num_ports;
 	struct {
 		__u8	port_function_id;
 		__u8	port;
@@ -135,12 +135,12 @@
 struct palm_ext_connection_info {
 	__u8 num_ports;		
 	__u8 endpoint_numbers_different;
-	__u16 reserved1;
+	__le16 reserved1;
 	struct {
 		__u32 port_function_id;
 		__u8 port;
 		__u8 end_point_info;
-		__u16 reserved;
+		__le16 reserved;
 	} connections[2];
 };
 
diff -Nru a/drivers/usb/storage/Kconfig b/drivers/usb/storage/Kconfig
--- a/drivers/usb/storage/Kconfig	2005-03-01 23:39:16 -08:00
+++ b/drivers/usb/storage/Kconfig	2005-03-01 23:39:16 -08:00
@@ -47,7 +47,7 @@
 
 	  Saying Y here allows these commands to be sent to a USB device.
 	  If you find a device this doesn't work for, switch to N and let
-	  us know at usb-storage@lists.one-eyed-alien.net
+	  us know at <usb-storage@lists.one-eyed-alien.net>
 
 	  If you say N here, the kernel will assume that all disk-like USB
 	  devices are write-enabled.
diff -Nru a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c
--- a/drivers/usb/storage/scsiglue.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/usb/storage/scsiglue.c	2005-03-01 23:38:57 -08:00
@@ -118,7 +118,7 @@
 	 * works okay and that's what Windows does.  But we'll be
 	 * conservative; people can always use the sysfs interface to
 	 * increase max_sectors. */
-	if (us->pusb_dev->descriptor.idVendor == USB_VENDOR_ID_GENESYS &&
+	if (le16_to_cpu(us->pusb_dev->descriptor.idVendor) == USB_VENDOR_ID_GENESYS &&
 			sdev->request_queue->max_sectors > 64)
 		blk_queue_max_sectors(sdev->request_queue, 64);
 
diff -Nru a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
--- a/drivers/usb/storage/transport.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/usb/storage/transport.c	2005-03-01 23:38:55 -08:00
@@ -954,6 +954,13 @@
 	int result;
 	int fake_sense = 0;
 	unsigned int cswlen;
+	unsigned int cbwlen = US_BULK_CB_WRAP_LEN;
+
+	/* Take care of BULK32 devices; set extra byte to 0 */
+	if ( unlikely(us->flags & US_FL_BULK32)) {
+		cbwlen = 32;
+		us->iobuf[31] = 0;
+	}
 
 	/* set up the command wrapper */
 	bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
@@ -976,7 +983,7 @@
 			(bcb->Lun >> 4), (bcb->Lun & 0x0F), 
 			bcb->Length);
 	result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe,
-				bcb, US_BULK_CB_WRAP_LEN, NULL);
+				bcb, cbwlen, NULL);
 	US_DEBUGP("Bulk command transfer result=%d\n", result);
 	if (result != USB_STOR_XFER_GOOD)
 		return USB_STOR_TRANSPORT_ERROR;
@@ -985,9 +992,10 @@
 	/* send/receive data payload, if there is any */
 
 	/* Genesys Logic interface chips need a 100us delay between the
-	 * command phase and the data phase */
-	if (us->pusb_dev->descriptor.idVendor == USB_VENDOR_ID_GENESYS)
-		udelay(100);
+	 * command phase and the data phase.  Some devices need a little
+	 * more than that, probably because of clock rate inaccuracies. */
+	if (le16_to_cpu(us->pusb_dev->descriptor.idVendor) == USB_VENDOR_ID_GENESYS)
+		udelay(110);
 
 	if (transfer_length) {
 		unsigned int pipe = srb->sc_data_direction == DMA_FROM_DEVICE ? 
diff -Nru a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
--- a/drivers/usb/storage/unusual_devs.h	2005-03-01 23:39:08 -08:00
+++ b/drivers/usb/storage/unusual_devs.h	2005-03-01 23:39:08 -08:00
@@ -210,7 +210,15 @@
 		0), 
 #endif
 
-UNUSUAL_DEV(  0x04e6, 0x0006, 0x0100, 0x0205, 
+/* Reported by Markus Demleitner <msdemlei@cl.uni-heidelberg.de> */
+UNUSUAL_DEV(  0x04e6, 0x0006, 0x0100, 0x0100, 
+		"SCM Microsystems Inc.",
+		"eUSB MMC Adapter",
+		US_SC_SCSI, US_PR_CB, NULL, 
+		US_FL_SINGLE_LUN), 
+
+/* Reported by Daniel Nouri <dpunktnpunkt@web.de> */
+UNUSUAL_DEV(  0x04e6, 0x0006, 0x0205, 0x0205, 
 		"Shuttle",
 		"eUSB MMC Adapter",
 		US_SC_SCSI, US_PR_DEVICE, NULL, 
@@ -249,6 +257,17 @@
 		"CD-RW Device",
 		US_SC_8020, US_PR_CB, NULL, 0),
 
+/* Entry and supporting patch by Theodore Kilgore <kilgota@auburn.edu>.
+ * Device uses standards-violating 32-byte Bulk Command Block Wrappers and
+ * reports itself as "Proprietary SCSI Bulk." Cf. device entry 0x084d:0x0011.
+ */
+
+UNUSUAL_DEV(  0x04fc, 0x80c2, 0x0100, 0x0100,
+		"Kobian Mercury",
+		"Binocam DCB-132",
+		US_SC_DEVICE, US_PR_DEVICE, NULL,
+		US_FL_BULK32),
+
 /* Reported by Bob Sass <rls@vectordb.com> -- only rev 1.33 tested */
 UNUSUAL_DEV(  0x050d, 0x0115, 0x0133, 0x0133,
 		"Belkin",
@@ -310,14 +329,14 @@
 		"Sony",
 		"DSC-S30/S70/S75/505V/F505/F707/F717/P8", 
 		US_SC_SCSI, US_PR_DEVICE, NULL,
-		US_FL_SINGLE_LUN | US_FL_MODE_XLATE ),
+		US_FL_SINGLE_LUN ),
 
 /* This entry is needed because the device reports Sub=ff */
 UNUSUAL_DEV(  0x054c, 0x0010, 0x0500, 0x0500, 
                "Sony",
                "DSC-T1", 
                US_SC_8070, US_PR_DEVICE, NULL,
-               US_FL_SINGLE_LUN | US_FL_MODE_XLATE ),
+               US_FL_SINGLE_LUN ),
 
 
 /* Reported by wim@geeks.nl */
@@ -346,14 +365,14 @@
 		"Sony",
 		"Handycam",
 		US_SC_SCSI, US_PR_DEVICE, NULL,
-		US_FL_SINGLE_LUN | US_FL_MODE_XLATE),
+		US_FL_SINGLE_LUN ),
 
 /* Submitted by Rajesh Kumble Nayak <nayak@obs-nice.fr> */
 UNUSUAL_DEV(  0x054c, 0x002e, 0x0500, 0x0500, 
 		"Sony",
 		"Handycam HC-85",
 		US_SC_UFI, US_PR_DEVICE, NULL,
-		US_FL_SINGLE_LUN | US_FL_MODE_XLATE),
+		US_FL_SINGLE_LUN ),
 
 UNUSUAL_DEV(  0x054c, 0x0032, 0x0000, 0x9999,
 		"Sony",
@@ -483,7 +502,7 @@
 		"Lexar",
 		"Jumpshot USB CF Reader",
 		US_SC_SCSI, US_PR_JUMPSHOT, NULL,
-		US_FL_NEED_OVERRIDE | US_FL_MODE_XLATE ),
+		US_FL_NEED_OVERRIDE ),
 #endif
 
 /* Reported by Blake Matheny <bmatheny@purdue.edu> */
@@ -499,7 +518,7 @@
 		"Vivitar",
 		"Vivicam 35Xx",
 		US_SC_SCSI, US_PR_BULK, NULL,
-		US_FL_FIX_INQUIRY | US_FL_MODE_XLATE),
+		US_FL_FIX_INQUIRY ),
 
 UNUSUAL_DEV(  0x0644, 0x0000, 0x0100, 0x0100, 
 		"TEAC",
@@ -521,6 +540,20 @@
 		US_SC_DEVICE, US_PR_DEVICE, NULL,
 		US_FL_FIX_CAPACITY ),
 
+/* Reported by Alex Butcher <alex.butcher@assursys.co.uk> */
+UNUSUAL_DEV( 0x067b, 0x3507, 0x0001, 0x0001,
+		"Prolific Technology Inc.",
+		"ATAPI-6 Bridge Controller",
+		US_SC_DEVICE, US_PR_DEVICE, NULL,
+		US_FL_FIX_CAPACITY ),
+
+/* Reported by Alex Butcher <alex.butcher@assursys.co.uk> */
+UNUSUAL_DEV( 0x067b, 0x3507, 0x0001, 0x0001,
+		"Prolific Technology Inc.",
+		"ATAPI-6 Bridge Controller",
+		US_SC_DEVICE, US_PR_DEVICE, NULL,
+		US_FL_FIX_CAPACITY ),
+
 /* Submitted by Benny Sjostrand <benny@hostmobility.com> */
 UNUSUAL_DEV( 0x0686, 0x4011, 0x0001, 0x0001,
 		"Minolta",
@@ -609,48 +642,48 @@
 		"Datafab",
 		"MDCFE-B USB CF Reader",
 		US_SC_SCSI, US_PR_DATAFAB, NULL,
-		US_FL_MODE_XLATE ),
+		0 ),
 
-	/*
-	 * The following Datafab-based devices may or may not work
-	 * using the current driver...the 0xffff is arbitrary since I
-	 * don't know what device versions exist for these guys.
-	 *
-	 * The 0xa003 and 0xa004 devices in particular I'm curious about.
-	 * I'm told they exist but so far nobody has come forward to say that
-	 * they work with this driver.  Given the success we've had getting
-	 * other Datafab-based cards operational with this driver, I've decided
-	 * to leave these two devices in the list.
-	 */
+/*
+ * The following Datafab-based devices may or may not work
+ * using the current driver...the 0xffff is arbitrary since I
+ * don't know what device versions exist for these guys.
+ *
+ * The 0xa003 and 0xa004 devices in particular I'm curious about.
+ * I'm told they exist but so far nobody has come forward to say that
+ * they work with this driver.  Given the success we've had getting
+ * other Datafab-based cards operational with this driver, I've decided
+ * to leave these two devices in the list.
+ */
 UNUSUAL_DEV( 0x07c4, 0xa001, 0x0000, 0xffff,
 		"SIIG/Datafab",
 		"SIIG/Datafab Memory Stick+CF Reader/Writer",
 		US_SC_SCSI, US_PR_DATAFAB, NULL,
-		US_FL_MODE_XLATE ),
+		0 ),
 
 UNUSUAL_DEV( 0x07c4, 0xa003, 0x0000, 0xffff,
 		"Datafab/Unknown",
 		"Datafab-based Reader",
 		US_SC_SCSI, US_PR_DATAFAB, NULL,
-		US_FL_MODE_XLATE ),
+		0 ),
 
 UNUSUAL_DEV( 0x07c4, 0xa004, 0x0000, 0xffff,
 		"Datafab/Unknown",
 		"Datafab-based Reader",
 		US_SC_SCSI, US_PR_DATAFAB, NULL,
-		US_FL_MODE_XLATE ),
+		0 ),
 
 UNUSUAL_DEV( 0x07c4, 0xa005, 0x0000, 0xffff,
 		"PNY/Datafab",
 		"PNY/Datafab CF+SM Reader",
 		US_SC_SCSI, US_PR_DATAFAB, NULL,
-		US_FL_MODE_XLATE ),
+		0 ),
 
 UNUSUAL_DEV( 0x07c4, 0xa006, 0x0000, 0xffff,
 		"Simple Tech/Datafab",
 		"Simple Tech/Datafab CF+SM Reader",
 		US_SC_SCSI, US_PR_DATAFAB, NULL,
-		US_FL_MODE_XLATE ),
+		0 ),
 #endif
 		
 #ifdef CONFIG_USB_STORAGE_SDDR55
@@ -668,7 +701,7 @@
 		"Datafab Systems, Inc.",
 		"USB to CF + SM Combo (LC1)",
 		US_SC_SCSI, US_PR_DATAFAB, NULL,
-		US_FL_MODE_XLATE ),
+		0 ),
 #endif
 #ifdef CONFIG_USB_STORAGE_SDDR55
 /* SM part - aeb <Andries.Brouwer@cwi.nl> */
@@ -715,14 +748,18 @@
 		US_SC_DEVICE, US_PR_DEVICE, NULL,
 		US_FL_FIX_INQUIRY),
 
-/* Aiptek PocketCAM 3Mega
- * Nicolas DUPEUX <nicolas@dupeux.net> 
+/* Entry and supporting patch by Theodore Kilgore <kilgota@auburn.edu>.
+ * Flag will support Bulk devices which use a standards-violating 32-byte
+ * Command Block Wrapper. Here, the "DC2MEGA" cameras (several brands) with
+ * Grandtech GT892x chip, which request "Proprietary SCSI Bulk" support.
  */
-UNUSUAL_DEV(  0x08ca, 0x2011, 0x0000, 0x9999,
-		"AIPTEK",
-		"PocketCAM 3Mega",
+
+UNUSUAL_DEV(  0x084d, 0x0011, 0x0110, 0x0110,
+		"Grandtech",
+		"DC2MEGA",
 		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_MODE_XLATE ),
+		US_FL_BULK32),
+
 
 /* Entry needed for flags. Moreover, all devices with this ID use
  * bulk-only transport, but _some_ falsely report Control/Bulk instead.
@@ -733,14 +770,14 @@
 		"Trumpion",
 		"t33520 USB Flash Card Controller",
 		US_SC_DEVICE, US_PR_BULK, NULL,
-		US_FL_NEED_OVERRIDE | US_FL_MODE_XLATE),
+		US_FL_NEED_OVERRIDE ),
 
 /* Trumpion Microelectronics MP3 player (felipe_alfaro@linuxmail.org) */
 UNUSUAL_DEV( 0x090a, 0x1200, 0x0000, 0x9999,
 		"Trumpion",
 		"MP3 player",
 		US_SC_RBC, US_PR_BULK, NULL,
-		US_FL_MODE_XLATE),
+		0 ),
 
 /* aeb */
 UNUSUAL_DEV( 0x090c, 0x1132, 0x0000, 0xffff,
@@ -749,12 +786,6 @@
 		US_SC_DEVICE, US_PR_DEVICE, NULL,
 		US_FL_FIX_CAPACITY ),
 
-UNUSUAL_DEV(  0x097a, 0x0001, 0x0000, 0x0001,
-		"Minds@Work",
-		"Digital Wallet",
- 		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_MODE_XLATE ),
-
 /* This Pentax still camera is not conformant
  * to the USB storage specification: -
  * - It does not like the INQUIRY command. So we must handle this command
@@ -842,6 +873,14 @@
 		US_SC_DEVICE, US_PR_DEVICE, NULL,
 		US_FL_FIX_INQUIRY ),
 
+/* Submitted by Daniel Drake <dsd@gentoo.org>
+ * Reported by dayul on the Gentoo Forums */
+UNUSUAL_DEV(  0x0ea0, 0x2168, 0x0110, 0x0110,
+		"Ours Technology",
+		"Flash Disk",
+		US_SC_DEVICE, US_PR_DEVICE, NULL,
+		US_FL_IGNORE_RESIDUE ),
+
 /* Reported by Rastislav Stanik <rs_kernel@yahoo.com> */
 UNUSUAL_DEV(  0x0ea0, 0x6828, 0x0110, 0x0110,
 		"USB",
@@ -858,17 +897,6 @@
 		"UCR-61S2B",
 		US_SC_DEVICE, US_PR_DEVICE, usb_stor_ucr61s2b_init,
 		0 ),
-
-/* Reported by Dan Pilone <pilone@slac.com>
- * The device needs the flags only.
- * Also reported by Brian Hall <brihall@pcisys.net>, again for flags.
- * I also suspect this device may have a broken serial number.
- */
-UNUSUAL_DEV(  0x1065, 0x2136, 0x0000, 0x9999,
-		"CCYU TECHNOLOGY",
-		"EasyDisk Portable Device",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_MODE_XLATE ),
 
 /* Reported by Kotrla Vitezslav <kotrla@ceb.cz> */
 UNUSUAL_DEV(  0x1370, 0x6828, 0x0110, 0x0110,
diff -Nru a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
--- a/drivers/usb/storage/usb.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/usb/storage/usb.c	2005-03-01 23:38:54 -08:00
@@ -263,16 +263,17 @@
 			      available from the device."). */
 		memset(data+8,0,28);
 	} else {
+		u16 bcdDevice = le16_to_cpu(us->pusb_dev->descriptor.bcdDevice);
 		memcpy(data+8, us->unusual_dev->vendorName, 
 			strlen(us->unusual_dev->vendorName) > 8 ? 8 :
 			strlen(us->unusual_dev->vendorName));
 		memcpy(data+16, us->unusual_dev->productName, 
 			strlen(us->unusual_dev->productName) > 16 ? 16 :
 			strlen(us->unusual_dev->productName));
-		data[32] = 0x30 + ((us->pusb_dev->descriptor.bcdDevice>>12) & 0x0F);
-		data[33] = 0x30 + ((us->pusb_dev->descriptor.bcdDevice>>8) & 0x0F);
-		data[34] = 0x30 + ((us->pusb_dev->descriptor.bcdDevice>>4) & 0x0F);
-		data[35] = 0x30 + ((us->pusb_dev->descriptor.bcdDevice) & 0x0F);
+		data[32] = 0x30 + ((bcdDevice>>12) & 0x0F);
+		data[33] = 0x30 + ((bcdDevice>>8) & 0x0F);
+		data[34] = 0x30 + ((bcdDevice>>4) & 0x0F);
+		data[35] = 0x30 + ((bcdDevice) & 0x0F);
 	}
 
 	usb_stor_set_xfer_buf(data, data_len, us->srb);
@@ -436,9 +437,9 @@
 	us->pusb_intf = intf;
 	us->ifnum = intf->cur_altsetting->desc.bInterfaceNumber;
 	US_DEBUGP("Vendor: 0x%04x, Product: 0x%04x, Revision: 0x%04x\n",
-			us->pusb_dev->descriptor.idVendor,
-			us->pusb_dev->descriptor.idProduct,
-			us->pusb_dev->descriptor.bcdDevice);
+			le16_to_cpu(us->pusb_dev->descriptor.idVendor),
+			le16_to_cpu(us->pusb_dev->descriptor.idProduct),
+			le16_to_cpu(us->pusb_dev->descriptor.bcdDevice));
 	US_DEBUGP("Interface Subclass: 0x%02x, Protocol: 0x%02x\n",
 			intf->cur_altsetting->desc.bInterfaceSubClass,
 			intf->cur_altsetting->desc.bInterfaceProtocol);
@@ -507,8 +508,9 @@
 				" has %s in unusual_devs.h\n"
 				"   Please send a copy of this message to "
 				"<linux-usb-devel@lists.sourceforge.net>\n",
-				ddesc->idVendor, ddesc->idProduct,
-				ddesc->bcdDevice,
+				le16_to_cpu(ddesc->idVendor),
+				le16_to_cpu(ddesc->idProduct),
+				le16_to_cpu(ddesc->bcdDevice),
 				idesc->bInterfaceSubClass,
 				idesc->bInterfaceProtocol,
 				msgs[msg]);
diff -Nru a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h
--- a/drivers/usb/storage/usb.h	2005-03-01 23:39:07 -08:00
+++ b/drivers/usb/storage/usb.h	2005-03-01 23:39:07 -08:00
@@ -74,6 +74,7 @@
 #define US_FL_FIX_INQUIRY     0x00000040 /* INQUIRY response needs faking   */
 #define US_FL_FIX_CAPACITY    0x00000080 /* READ CAPACITY response too big  */
 #define US_FL_IGNORE_RESIDUE  0x00000100 /* reported residue is wrong	    */
+#define US_FL_BULK32          0x00000200 /* Uses 32-byte CBW length         */
 
 /* Dynamic flag definitions: used in set_bit() etc. */
 #define US_FLIDX_URB_ACTIVE	18  /* 0x00040000  current_urb is in use  */
diff -Nru a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c
--- a/drivers/usb/usb-skeleton.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/usb/usb-skeleton.c	2005-03-01 23:38:57 -08:00
@@ -260,7 +260,7 @@
 		    ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
 					== USB_ENDPOINT_XFER_BULK)) {
 			/* we found a bulk in endpoint */
-			buffer_size = endpoint->wMaxPacketSize;
+			buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
 			dev->bulk_in_size = buffer_size;
 			dev->bulk_in_endpointAddr = endpoint->bEndpointAddress;
 			dev->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL);
diff -Nru a/drivers/video/Kconfig b/drivers/video/Kconfig
--- a/drivers/video/Kconfig	2005-03-01 23:38:51 -08:00
+++ b/drivers/video/Kconfig	2005-03-01 23:38:51 -08:00
@@ -574,7 +574,7 @@
 	  packed pixel and 32 bpp packed pixel. You can also use font widths
 	  different from 8.
 
-config FB_MATROX_G450
+config FB_MATROX_G
 	bool "G100/G200/G400/G450/G550 support"
 	depends on FB_MATROX
 	---help---
@@ -585,10 +585,10 @@
 	  different from 8.
 
 	  If you need support for G400 secondary head, you must first say Y to
-	  "I2C support" and "I2C bit-banging support" in the character devices
-	  section, and then to "Matrox I2C support" and "G400 second head
-	  support" here in the framebuffer section. G450/G550 secondary head
-	  and digital output are supported without additional modules.
+	  "I2C support" in the character devices section, and then to
+	  "Matrox I2C support" and "G400 second head support" here in the
+	  framebuffer section. G450/G550 secondary head and digital output
+	  are supported without additional modules.
 
 	  The driver starts in monitor mode. You must use the matroxset tool 
 	  (available at <ftp://platan.vc.cvut.cz/pub/linux/matrox-latest/>) to 
@@ -605,26 +605,6 @@
 	  G450/G550 hardware can display TV picture only from secondary CRTC,
 	  and it performs no scaling, so picture must have 525 or 625 lines.
 
-config FB_MATROX_G100A
-	bool "G100/G200/G400 support"
-	depends on FB_MATROX && !FB_MATROX_G450
-	---help---
-	  Say Y here if you have a Matrox G100, G200 or G400 based
-	  video card. If you select "Advanced lowlevel driver options", you
-	  should check 8 bpp packed pixel, 16 bpp packed pixel, 24 bpp packed
-	  pixel and 32 bpp packed pixel. You can also use font widths
-	  different from 8.
-
-	  If you need support for G400 secondary head, you must first say Y to
-	  "I2C support" and "I2C bit-banging support" in the character devices
-	  section, and then to "Matrox I2C support" and "G400 second head
-	  support" here in the framebuffer section.
-
-config FB_MATROX_G100
-	bool
-	depends on FB_MATROX && (FB_MATROX_G450 || FB_MATROX_G100A)
-	default y
-
 config FB_MATROX_I2C
 	tristate "Matrox I2C support"
 	depends on FB_MATROX && I2C
@@ -644,7 +624,7 @@
 
 config FB_MATROX_MAVEN
 	tristate "G400 second head support"
-	depends on FB_MATROX_G100 && FB_MATROX_I2C
+	depends on FB_MATROX_G && FB_MATROX_I2C
 	---help---
 	  WARNING !!! This support does not work with G450 !!!
 
@@ -836,7 +816,7 @@
 	depends on FB && PCI
 	help
 	  This is the frame buffer device driver for the SiS 300, 315 and
-	  330 series VGA chipsets. Specs available at http://www.sis.com
+	  330 series VGA chipsets. Specs available at <http://www.sis.com>
 
 	  To compile this driver as a module, choose M here; the module
 	  will be called sisfb.
@@ -905,7 +885,7 @@
 
 	  WARNING: Do not use any application that uses the 3D engine
 	  (namely glide) while using this driver.
-	  Please read the file Documentation/fb/README-sstfb.txt for supported
+	  Please read the <file:Documentation/fb/README-sstfb.txt> for supported
 	  options and other important info  support.
 
 config FB_TRIDENT
@@ -939,6 +919,42 @@
 	  similar boards, 3DLabs Permedia3 Create!, Appian Jeronimo 2000
 	  and maybe other boards.
 
+config FB_E1356
+	tristate "Epson SED1356 framebuffer support"
+	depends on FB && EXPERIMENTAL && PCI && MIPS
+
+config PB1000_CRT
+	bool "Use CRT on Pb1000 (J65)"
+	depends on MIPS_PB1000=y && FB_E1356
+
+config PB1000_NTSC
+	bool "Use Compsite NTSC on Pb1000 (J63)"
+	depends on MIPS_PB1000=y && FB_E1356
+
+config PB1000_TFT
+	bool "Use TFT Panel on Pb1000 (J64)"
+	depends on MIPS_PB1000=y && FB_E1356
+
+config PB1500_CRT
+	bool "Use CRT on Pb1500 " if MIPS_PB1500=y
+	depends on FB_E1356
+
+config PB1500_CRT
+	prompt "Use CRT on Pb1100 "
+	depends on FB_E1356 && MIPS_PB1100=y
+
+config PB1500_TFT
+	bool "Use TFT Panel on Pb1500 " if MIPS_PB1500=y
+	depends on FB_E1356
+
+config PB1500_TFT
+	prompt "Use TFT Panel on Pb1100 "
+	depends on FB_E1356 && MIPS_PB1100=y
+
+config FB_AU1100
+	bool "Au1100 LCD Driver"
+	depends on FB && EXPERIMENTAL && PCI && MIPS && MIPS_PB1100=y
+
 config FB_SBUS
 	bool "SBUS and UPA framebuffers"
 	depends on FB && (SPARC32 || SPARC64)
@@ -998,29 +1014,35 @@
 	  This is the frame buffer device driver for the Hitachi HD64461 LCD
 	  frame buffer card.
 
+config FB_PMAG_AA
+	bool "PMAG-AA TURBOchannel framebuffer support"
+	depends on FB && MACH_DECSTATION && TC
+	help
+	  Support for the PMAG-AA TURBOchannel framebuffer card (1280x1024x1)
+	  used mainly in the MIPS-based DECstation series.
+
 config FB_PMAG_BA
 	bool "PMAG-BA TURBOchannel framebuffer support"
-	depends on FB && DECSTATION && TC
+	depends on FB && MACH_DECSTATION && TC
 	help
-	  Say Y here to directly support the on-board PMAG-BA framebuffer in
-	  the 5000/1xx versions of the DECstation.  There is a page dedicated
-	  to Linux on DECstations at <http://decstation.unix-ag.org/>.
+	  Support for the PMAG-BA TURBOchannel framebuffer card (1024x864x8)
+	  used mainly in the MIPS-based DECstation series.
 
 config FB_PMAGB_B
-	bool "PMAGB-B TURBOchannel framebuffer spport"
-	depends on FB && DECSTATION && TC
+	bool "PMAGB-B TURBOchannel framebuffer support"
+	depends on FB && MACH_DECSTATION && TC
 	help
-	  Say Y here to directly support the on-board PMAGB-B framebuffer in
-	  the 5000/1xx versions of the DECstation.  There is a page dedicated
-	  to Linux on DECstations at <http://decstation.unix-ag.org/>.
+	  Support for the PMAGB-B TURBOchannel framebuffer card used mainly
+	  in the MIPS-based DECstation series. The card is currently only
+	  supported in 1280x1024x8 mode.
 
 config FB_MAXINE
-	bool "Maxine (Personal DECstation) onboard framebuffer spport"
-	depends on FB && DECSTATION && TC
+	bool "Maxine (Personal DECstation) onboard framebuffer support"
+	depends on FB && MACH_DECSTATION && TC
 	help
-	  Say Y here to directly support the on-board framebuffer in the
-	  Maxine (5000/20, /25, /33) version of the DECstation.  There is a
-	  page dedicated to Linux on DECstations at <http://decstation.unix-ag.org/>.
+	  Support for the onboard framebuffer (1024x768x8) in the Personal
+	  DECstation series (Personal DECstation 5000/20, /25, /33, /50,
+	  Codename "Maxine").
 
 config FB_TX3912
 	bool "TMPTX3912/PR31700 frame buffer support"
@@ -1031,6 +1053,13 @@
 
 	  Say Y here to enable kernel support for the on-board framebuffer.
 
+config FB_G364
+	bool
+	depends on MIPS_MAGNUM_4000 || OLIVETTI_M700
+	help
+	  The G364 driver is the framebuffer used in MIPS Magnum 4000 and
+	  Olivetti M700-10 systems.
+
 config FB_68328
 	bool "Motorola 68328 native frame buffer support"
 	depends on (M68328 || M68EZ328 || M68VZ328)
@@ -1052,6 +1081,19 @@
 
 	  If unsure, say N.
 
+config FB_W100
+	tristate "W100 frame buffer support"
+	depends on FB && PXA_SHARPSL
+	---help---
+	  Frame buffer driver for the w100 as found on the Sharp SL-Cxx series.
+
+	  This driver is also available as a module ( = code which can be
+	  inserted and removed from the running kernel whenever you want). The
+	  module will be called vfb. If you want to compile it as a module,
+	  say M here and read <file:Documentation/modules.txt>.
+
+	  If unsure, say N.
+
 config FB_PXA_PARAMETERS
 	bool "PXA LCD command line parameters"
 	default n
@@ -1067,7 +1109,7 @@
 	  single model of flatpanel then you can safely leave this
 	  option disabled.
 
-	  Documentation/fb/pxafb.txt describes the available parameters.
+	  <file:Documentation/fb/pxafb.txt> describes the available parameters.
 
 config FB_VIRTUAL
 	tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)"
@@ -1092,6 +1134,10 @@
 
 if FB || SGI_NEWPORT_CONSOLE
 	source "drivers/video/logo/Kconfig"
+endif
+
+if FB && SYSFS
+	source "drivers/video/backlight/Kconfig"
 endif
 
 endmenu
diff -Nru a/drivers/video/Makefile b/drivers/video/Makefile
--- a/drivers/video/Makefile	2005-03-01 23:38:52 -08:00
+++ b/drivers/video/Makefile	2005-03-01 23:38:52 -08:00
@@ -6,6 +6,7 @@
 
 obj-$(CONFIG_VT)		  += console/
 obj-$(CONFIG_LOGO)		  += logo/
+obj-$(CONFIG_SYSFS)		  += backlight/
 
 obj-$(CONFIG_FB)                  += fbmem.o fbmon.o fbcmap.o fbsysfs.o modedb.o softcursor.o
 # Only include macmodes.o if we have FB support and are PPC
@@ -81,12 +82,8 @@
 obj-$(CONFIG_FB_SA1100)           += sa1100fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
 obj-$(CONFIG_FB_SUN3)             += sun3fb.o
 obj-$(CONFIG_FB_HIT)              += hitfb.o cfbfillrect.o cfbimgblt.o
-obj-$(CONFIG_FB_TX3912)           += tx3912fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
 obj-$(CONFIG_FB_EPSON1355)	  += epson1355fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
 obj-$(CONFIG_FB_PVR2)             += pvr2fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
-obj-$(CONFIG_FB_PMAG_BA)          += pmag-ba-fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
-obj-$(CONFIG_FB_PMAGB_B)          += pmagb-b-fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
-obj-$(CONFIG_FB_MAXINE)           += maxinefb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
 obj-$(CONFIG_FB_VOODOO1)          += sstfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
 obj-$(CONFIG_FB_ARMCLCD)	  += amba-clcd.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
 obj-$(CONFIG_FB_68328)            += 68328fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
@@ -94,6 +91,13 @@
 obj-$(CONFIG_FB_CIRRUS)		  += cirrusfb.o cfbfillrect.o cfbimgblt.o cfbcopyarea.o
 obj-$(CONFIG_FB_ASILIANT)	  += asiliantfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
 obj-$(CONFIG_FB_PXA)		  += pxafb.o cfbimgblt.o cfbcopyarea.o cfbfillrect.o
+obj-$(CONFIG_FB_W100)		   += w100fb.o cfbimgblt.o cfbcopyarea.o cfbfillrect.o
+obj-$(CONFIG_FB_AU1100)		  += au1100fb.o fbgen.o
+obj-$(CONFIG_FB_PMAG_AA)	  += pmag-aa-fb.o  cfbfillrect.o cfbcopyarea.o cfbimgblt.o
+obj-$(CONFIG_FB_PMAG_BA)	  += pmag-ba-fb.o  cfbfillrect.o cfbcopyarea.o cfbimgblt.o
+obj-$(CONFIG_FB_PMAGB_B)	  += pmagb-b-fb.o  cfbfillrect.o cfbcopyarea.o cfbimgblt.o
+obj-$(CONFIG_FB_MAXINE)		  += maxinefb.o  cfbfillrect.o cfbcopyarea.o cfbimgblt.o
+obj-$(CONFIG_FB_TX3912)		  += tx3912fb.o  cfbfillrect.o cfbcopyarea.o cfbimgblt.o
 
 # Platform or fallback drivers go here
 obj-$(CONFIG_FB_VESA)             += vesafb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
diff -Nru a/drivers/video/amba-clcd.c b/drivers/video/amba-clcd.c
--- a/drivers/video/amba-clcd.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/video/amba-clcd.c	2005-03-01 23:39:18 -08:00
@@ -16,6 +16,7 @@
 #include <linux/string.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
+#include <linux/mm.h>
 #include <linux/fb.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
@@ -300,6 +301,22 @@
 	return 0;
 }
 
+static int clcdfb_mmap(struct fb_info *info, struct file *file,
+		       struct vm_area_struct *vma)
+{
+	struct clcd_fb *fb = to_clcd(info);
+	unsigned long len, off = vma->vm_pgoff << PAGE_SHIFT;
+	int ret = -EINVAL;
+
+	len = info->fix.smem_len;
+
+	if (off <= len && vma->vm_end - vma->vm_start <= len - off &&
+	    fb->board->mmap)
+		ret = fb->board->mmap(fb, vma);
+
+	return ret;
+}
+
 static struct fb_ops clcdfb_ops = {
 	.owner		= THIS_MODULE,
 	.fb_check_var	= clcdfb_check_var,
@@ -310,6 +327,7 @@
 	.fb_copyarea	= cfb_copyarea,
 	.fb_imageblit	= cfb_imageblit,
 	.fb_cursor	= soft_cursor,
+	.fb_mmap	= clcdfb_mmap,
 };
 
 static int clcdfb_register(struct clcd_fb *fb)
diff -Nru a/drivers/video/aty/Makefile b/drivers/video/aty/Makefile
--- a/drivers/video/aty/Makefile	2005-03-01 23:38:54 -08:00
+++ b/drivers/video/aty/Makefile	2005-03-01 23:38:54 -08:00
@@ -5,6 +5,8 @@
 atyfb-y				:= atyfb_base.o mach64_accel.o mach64_cursor.o
 atyfb-$(CONFIG_FB_ATY_GX)	+= mach64_gx.o
 atyfb-$(CONFIG_FB_ATY_CT)	+= mach64_ct.o
+atyfb-$(CONFIG_FB_ATY_XL_INIT)  += xlinit.o
+
 atyfb-objs			:= $(atyfb-y)
 
 radeonfb-y			:= radeon_base.o radeon_pm.o radeon_monitor.o radeon_accel.o
diff -Nru a/drivers/video/aty/ati_ids.h b/drivers/video/aty/ati_ids.h
--- a/drivers/video/aty/ati_ids.h	2005-03-01 23:38:55 -08:00
+++ b/drivers/video/aty/ati_ids.h	2005-03-01 23:38:55 -08:00
@@ -4,6 +4,18 @@
  * radeonfb
  */
 
+#define PCI_CHIP_RV380_3150             0x3150
+#define PCI_CHIP_RV380_3151             0x3151
+#define PCI_CHIP_RV380_3152             0x3152
+#define PCI_CHIP_RV380_3153             0x3153
+#define PCI_CHIP_RV380_3154             0x3154
+#define PCI_CHIP_RV380_3156             0x3156
+#define PCI_CHIP_RV380_3E50             0x3E50
+#define PCI_CHIP_RV380_3E51             0x3E51
+#define PCI_CHIP_RV380_3E52             0x3E52
+#define PCI_CHIP_RV380_3E53             0x3E53
+#define PCI_CHIP_RV380_3E54             0x3E54
+#define PCI_CHIP_RV380_3E56             0x3E56
 #define PCI_CHIP_RS100_4136		0x4136
 #define PCI_CHIP_RS200_4137		0x4137
 #define PCI_CHIP_R300_AD		0x4144
@@ -52,6 +64,14 @@
 #define PCI_CHIP_RV250_Ie		0x4965
 #define PCI_CHIP_RV250_If		0x4966
 #define PCI_CHIP_RV250_Ig		0x4967
+#define PCI_CHIP_R420_JH                0x4A48
+#define PCI_CHIP_R420_JI                0x4A49
+#define PCI_CHIP_R420_JJ                0x4A4A
+#define PCI_CHIP_R420_JK                0x4A4B
+#define PCI_CHIP_R420_JL                0x4A4C
+#define PCI_CHIP_R420_JM                0x4A4D
+#define PCI_CHIP_R420_JN                0x4A4E
+#define PCI_CHIP_R420_JP                0x4A50
 #define PCI_CHIP_MACH64LB		0x4C42
 #define PCI_CHIP_MACH64LD		0x4C44
 #define PCI_CHIP_RAGE128LE		0x4C45
@@ -73,6 +93,7 @@
 #define PCI_CHIP_RV250_Le		0x4C65
 #define PCI_CHIP_RV250_Lf		0x4C66
 #define PCI_CHIP_RV250_Lg		0x4C67
+#define PCI_CHIP_RV250_Ln		0x4C6E
 #define PCI_CHIP_RAGE128MF		0x4D46
 #define PCI_CHIP_RAGE128ML		0x4D4C
 #define PCI_CHIP_R300_ND		0x4E44
@@ -148,6 +169,21 @@
 #define PCI_CHIP_RAGE128TS		0x5453
 #define PCI_CHIP_RAGE128TT		0x5454
 #define PCI_CHIP_RAGE128TU		0x5455
+#define PCI_CHIP_RV370_5460             0x5460
+#define PCI_CHIP_RV370_5461             0x5461
+#define PCI_CHIP_RV370_5462             0x5462
+#define PCI_CHIP_RV370_5463             0x5463
+#define PCI_CHIP_RV370_5464             0x5464
+#define PCI_CHIP_RV370_5465             0x5465
+#define PCI_CHIP_RV370_5466             0x5466
+#define PCI_CHIP_RV370_5467             0x5467
+#define PCI_CHIP_R423_UH                0x5548
+#define PCI_CHIP_R423_UI                0x5549
+#define PCI_CHIP_R423_UJ                0x554A
+#define PCI_CHIP_R423_UK                0x554B
+#define PCI_CHIP_R423_UQ                0x5551
+#define PCI_CHIP_R423_UR                0x5552
+#define PCI_CHIP_R423_UT                0x5554
 #define PCI_CHIP_MACH64VT		0x5654
 #define PCI_CHIP_MACH64VU		0x5655
 #define PCI_CHIP_MACH64VV		0x5656
@@ -155,14 +191,21 @@
 #define PCI_CHIP_RS300_5835		0x5835
 #define PCI_CHIP_RS300_5836		0x5836
 #define PCI_CHIP_RS300_5837		0x5837
+#define PCI_CHIP_RV370_5B60             0x5B60
+#define PCI_CHIP_RV370_5B61             0x5B61
+#define PCI_CHIP_RV370_5B62             0x5B62
+#define PCI_CHIP_RV370_5B63             0x5B63
+#define PCI_CHIP_RV370_5B64             0x5B64
+#define PCI_CHIP_RV370_5B65             0x5B65
+#define PCI_CHIP_RV370_5B66             0x5B66
+#define PCI_CHIP_RV370_5B67             0x5B67
 #define PCI_CHIP_RV280_5960		0x5960
 #define PCI_CHIP_RV280_5961		0x5961
 #define PCI_CHIP_RV280_5962		0x5962
-#define PCI_CHIP_RV280_5963		0x5963
 #define PCI_CHIP_RV280_5964		0x5964
-#define PCI_CHIP_RV280_5968		0x5968
-#define PCI_CHIP_RV280_5969		0x5969
-#define PCI_CHIP_RV280_596A		0x596A
-#define PCI_CHIP_RV280_596B		0x596B
 #define PCI_CHIP_RV280_5C61		0x5C61
 #define PCI_CHIP_RV280_5C63		0x5C63
+#define PCI_CHIP_R423_5D57              0x5D57
+#define PCI_CHIP_RS350_7834             0x7834
+#define PCI_CHIP_RS350_7835             0x7835
+
diff -Nru a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c
--- a/drivers/video/aty/aty128fb.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/video/aty/aty128fb.c	2005-03-01 23:38:57 -08:00
@@ -67,6 +67,7 @@
 #include <asm/io.h>
 
 #ifdef CONFIG_PPC_PMAC
+#include <asm/pmac_feature.h>
 #include <asm/prom.h>
 #include <asm/pci-bridge.h>
 #include "../macmodes.h"
@@ -167,6 +168,7 @@
 static void aty128_remove(struct pci_dev *pdev);
 static int aty128_pci_suspend(struct pci_dev *pdev, u32 state);
 static int aty128_pci_resume(struct pci_dev *pdev);
+static int aty128_do_resume(struct pci_dev *pdev);
 
 /* supported Rage128 chipsets */
 static struct pci_device_id aty128_pci_tbl[] = {
@@ -452,7 +454,6 @@
 static void __init aty128_get_pllinfo(struct aty128fb_par *par,
 				      void __iomem *bios);
 static void __init __iomem *aty128_map_ROM(struct pci_dev *pdev, const struct aty128fb_par *par);
-static void __init aty128_unmap_ROM(struct pci_dev *dev, void __iomem * rom);
 #endif
 static void aty128_timings(struct aty128fb_par *par);
 static void aty128_init_engine(struct aty128fb_par *par);
@@ -788,30 +789,12 @@
 
 
 #ifndef __sparc__
-static void __init aty128_unmap_ROM(struct pci_dev *dev, void __iomem * rom)
-{
-	struct resource *r = &dev->resource[PCI_ROM_RESOURCE];
-	
-	iounmap(rom);
-	
-	/* Release the ROM resource if we used it in the first place */
-	if (r->parent && r->flags & PCI_ROM_ADDRESS_ENABLE) {
-		release_resource(r);
-		r->flags &= ~PCI_ROM_ADDRESS_ENABLE;
-		r->end -= r->start;
-		r->start = 0;
-	}
-	/* This will disable and set address to unassigned */
-	pci_write_config_dword(dev, dev->rom_base_reg, 0);
-}
-
-
 static void __iomem * __init aty128_map_ROM(const struct aty128fb_par *par, struct pci_dev *dev)
 {
-	struct resource *r;
 	u16 dptr;
 	u8 rom_type;
 	void __iomem *bios;
+	size_t rom_size;
 
     	/* Fix from ATI for problem with Rage128 hardware not leaving ROM enabled */
     	unsigned int temp;
@@ -821,26 +804,13 @@
 	aty_st_le32(RAGE128_MPP_TB_CONFIG, temp);
 	temp = aty_ld_le32(RAGE128_MPP_TB_CONFIG);
 
-	/* no need to search for the ROM, just ask the card where it is. */
-	r = &dev->resource[PCI_ROM_RESOURCE];
+	bios = pci_map_rom(dev, &rom_size);
 
-	/* assign the ROM an address if it doesn't have one */
-	if (r->parent == NULL)
-		pci_assign_resource(dev, PCI_ROM_RESOURCE);
-	
-	/* enable if needed */
-	if (!(r->flags & PCI_ROM_ADDRESS_ENABLE)) {
-		pci_write_config_dword(dev, dev->rom_base_reg,
-				       r->start | PCI_ROM_ADDRESS_ENABLE);
-		r->flags |= PCI_ROM_ADDRESS_ENABLE;
-	}
-	
-	bios = ioremap(r->start, r->end - r->start + 1);
 	if (!bios) {
 		printk(KERN_ERR "aty128fb: ROM failed to map\n");
 		return NULL;
 	}
-	
+
 	/* Very simple test to make sure it appeared */
 	if (BIOS_IN16(0) != 0xaa55) {
 		printk(KERN_ERR "aty128fb: Invalid ROM signature %x should be 0xaa55\n",
@@ -899,7 +869,7 @@
 	return bios;
 
  failed:
-	aty128_unmap_ROM(dev, bios);
+	pci_unmap_rom(dev, bios);
 	return NULL;
 }
 
@@ -1737,6 +1707,18 @@
  *  Initialisation
  */
 
+#ifdef CONFIG_PPC_PMAC
+static void aty128_early_resume(void *data)
+{
+        struct aty128fb_par *par = data;
+
+	if (try_acquire_console_sem())
+		return;
+	aty128_do_resume(par->pdev);
+	release_console_sem();
+}
+#endif /* CONFIG_PPC_PMAC */
+
 static int __init aty128_init(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
 	struct fb_info *info = pci_get_drvdata(pdev);
@@ -1781,6 +1763,13 @@
 	var = default_var;
 #ifdef CONFIG_PPC_PMAC
 	if (_machine == _MACH_Pmac) {
+		/* Indicate sleep capability */
+		if (par->chip_gen == rage_M3) {
+			pmac_call_feature(PMAC_FTR_DEVICE_CAN_WAKE, NULL, 0, 1);
+			pmac_set_early_video_resume(aty128_early_resume, par);
+		}
+
+		/* Find default mode */
 		if (mode_option) {
 			if (!mac_find_mode(&var, info, mode_option, 8))
 				var = default_var;
@@ -1959,7 +1948,7 @@
 	else {
 		printk(KERN_INFO "aty128fb: Rage128 BIOS located\n");
 		aty128_get_pllinfo(par, bios);
-		aty128_unmap_ROM(pdev, bios);
+		pci_unmap_rom(pdev, bios);
 	}
 #endif /* __sparc__ */
 
@@ -2397,7 +2386,7 @@
 	return 0;
 }
 
-static int aty128_pci_resume(struct pci_dev *pdev)
+static int aty128_do_resume(struct pci_dev *pdev)
 {
 	struct fb_info *info = pci_get_drvdata(pdev);
 	struct aty128fb_par *par = info->par;
@@ -2405,8 +2394,6 @@
 	if (pdev->dev.power.power_state == 0)
 		return 0;
 
-	acquire_console_sem();
-
 	/* Wakeup chip */
 	if (pdev->dev.power.power_state == 2)
 		aty128_set_suspend(par, 0);
@@ -2426,8 +2413,6 @@
 	par->lock_blank = 0;
 	aty128fb_blank(0, info);
 
-	release_console_sem();
-
 	pdev->dev.power.power_state = 0;
 
 	printk(KERN_DEBUG "aty128fb: resumed !\n");
@@ -2435,6 +2420,18 @@
 	return 0;
 }
 
+static int aty128_pci_resume(struct pci_dev *pdev)
+{
+	int rc;
+
+	acquire_console_sem();
+	rc = aty128_do_resume(pdev);
+	release_console_sem();
+
+	return rc;
+}
+
+
 int __init aty128fb_init(void)
 {
 #ifndef MODULE
@@ -2462,10 +2459,10 @@
 MODULE_DESCRIPTION("FBDev driver for ATI Rage128 / Pro cards");
 MODULE_LICENSE("GPL");
 module_param(mode_option, charp, 0);
-MODULE_PARM_DESC(mode, "Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\" ");
+MODULE_PARM_DESC(mode_option, "Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\" ");
 #ifdef CONFIG_MTRR
 module_param_named(nomtrr, mtrr, invbool, 0);
-MODULE_PARM_DESC(mtrr, "bool: Disable MTRR support (0 or 1=disabled) (default=0)");
+MODULE_PARM_DESC(nomtrr, "bool: Disable MTRR support (0 or 1=disabled) (default=0)");
 #endif
 #endif
 
diff -Nru a/drivers/video/aty/atyfb.h b/drivers/video/aty/atyfb.h
--- a/drivers/video/aty/atyfb.h	2005-03-01 23:39:07 -08:00
+++ b/drivers/video/aty/atyfb.h	2005-03-01 23:39:07 -08:00
@@ -83,13 +83,13 @@
 	u8 pll_gen_cntl;
 	u8 mclk_fb_div;
 	u8 mclk_fb_mult; /* 2 ro 4 */
-/*	u8 sclk_fb_div;*/
+	u8 sclk_fb_div;
 	u8 pll_vclk_cntl;
 	u8 vclk_post_div;
 	u8 vclk_fb_div;
 	u8 pll_ext_cntl;
-/*	u8 ext_vpll_cntl;
-	u8 spll_cntl2;*/
+	u8 ext_vpll_cntl;
+	u8 spll_cntl2;
 	u32 dsp_config; /* Mach64 GTB DSP */
 	u32 dsp_on_off; /* Mach64 GTB DSP */
 	u32 dsp_loop_latency;
@@ -215,7 +215,6 @@
 #define M64F_XL_DLL		0x00080000
 #define M64F_MFB_FORCE_4	0x00100000
 #define M64F_HW_TRIPLE		0x00200000
-
     /*
      *  Register access
      */
@@ -246,6 +245,19 @@
 #endif
 }
 
+static inline void aty_st_le16(int regindex, u16 val,
+			       const struct atyfb_par *par)
+{
+	/* Hack for bloc 1, should be cleanly optimized by compiler */
+	if (regindex >= 0x400)
+		regindex -= 0x800;
+#ifdef CONFIG_ATARI
+	out_le16((volatile u16 *)(par->ati_regbase + regindex), val);
+#else
+	writel(val, par->ati_regbase + regindex);
+#endif
+}
+
 static inline u8 aty_ld_8(int regindex, const struct atyfb_par *par)
 {
 	/* Hack for bloc 1, should be cleanly optimized by compiler */
@@ -343,4 +355,6 @@
 
 extern void aty_reset_engine(const struct atyfb_par *par);
 extern void aty_init_engine(struct atyfb_par *par, struct fb_info *info);
-
+extern int  atyfb_xl_init(struct fb_info *info);
+extern void aty_st_pll_ct(int offset, u8 val, const struct atyfb_par *par);
+extern u8   aty_ld_pll_ct(int offset, const struct atyfb_par *par);
diff -Nru a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
--- a/drivers/video/aty/atyfb_base.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/video/aty/atyfb_base.c	2005-03-01 23:39:08 -08:00
@@ -2279,9 +2279,12 @@
 		par->dac_ops = &aty_dac_ct;
 		par->pll_ops = &aty_pll_ct;
 		par->bus_type = PCI;
+#ifdef CONFIG_FB_ATY_XL_INIT
+		if (IS_XL(par->pci_id))
+			atyfb_xl_init(info);
+#endif
 		par->ram_type = (aty_ld_le32(CONFIG_STAT0, par) & 0x07);
 		ramname = aty_ct_ram[par->ram_type];
-
 		/* for many chips, the mclk is 67 MHz for SDRAM, 63 MHz otherwise */
 		if (par->pll_limits.mclk == 67 && par->ram_type < SDRAM)
 			par->pll_limits.mclk = 63;
@@ -2508,7 +2511,15 @@
 		}
 	} else
 #endif /* !CONFIG_PPC */
-	if (!fb_find_mode(&var, info, mode, NULL, 0, &defmode, 8))
+	if (
+#if defined(CONFIG_SPARC32) || defined(CONFIG_SPARC64)
+	   /* On Sparc, unless the user gave a specific mode
+	    * specification, use the PROM probed values in
+	    * default_var.
+	    */
+	    !mode ||
+#endif
+	    !fb_find_mode(&var, info, mode, NULL, 0, &defmode, 8))
 		var = default_var;
 
 	if (noaccel)
diff -Nru a/drivers/video/aty/radeon_accel.c b/drivers/video/aty/radeon_accel.c
--- a/drivers/video/aty/radeon_accel.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/video/aty/radeon_accel.c	2005-03-01 23:39:07 -08:00
@@ -4,6 +4,41 @@
  * "ACCEL_MMIO" ifdef branches in XFree86
  * --dte
  */
+
+static void radeon_fixup_offset(struct radeonfb_info *rinfo)
+{
+	u32 local_base;
+
+	/* *** Ugly workaround *** */
+	/*
+	 * On some platforms, the video memory is mapped at 0 in radeon chip space
+	 * (like PPCs) by the firmware. X will always move it up so that it's seen
+	 * by the chip to be at the same address as the PCI BAR.
+	 * That means that when switching back from X, there is a mismatch between
+	 * the offsets programmed into the engine. This means that potentially,
+	 * accel operations done before radeonfb has a chance to re-init the engine
+	 * will have incorrect offsets, and potentially trash system memory !
+	 *
+	 * The correct fix is for fbcon to never call any accel op before the engine
+	 * has properly been re-initialized (by a call to set_var), but this is a
+	 * complex fix. This workaround in the meantime, called before every accel
+	 * operation, makes sure the offsets are in sync.
+	 */
+
+	radeon_fifo_wait (1);
+	local_base = INREG(MC_FB_LOCATION) << 16;
+	if (local_base == rinfo->fb_local_base)
+		return;
+
+	rinfo->fb_local_base = local_base;
+
+	radeon_fifo_wait (3);
+	OUTREG(DEFAULT_PITCH_OFFSET, (rinfo->pitch << 0x16) |
+				     (rinfo->fb_local_base >> 10));
+	OUTREG(DST_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10));
+	OUTREG(SRC_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10));
+}
+
 static void radeonfb_prim_fillrect(struct radeonfb_info *rinfo, 
 				   const struct fb_fillrect *region)
 {
@@ -38,6 +73,8 @@
 		return;
 	}
 
+	radeon_fixup_offset(rinfo);
+
 	vxres = info->var.xres_virtual;
 	vyres = info->var.yres_virtual;
 
@@ -104,6 +141,8 @@
 		cfb_copyarea(info, area);
 		return;
 	}
+
+	radeon_fixup_offset(rinfo);
 
 	vxres = info->var.xres_virtual;
 	vyres = info->var.yres_virtual;
diff -Nru a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c
--- a/drivers/video/aty/radeon_base.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/video/aty/radeon_base.c	2005-03-01 23:38:55 -08:00
@@ -1,5 +1,7 @@
+
 /*
- *	drivers/video/radeonfb.c
+ *	drivers/video/aty/radeon_base.c
+ *
  *	framebuffer driver for ATI Radeon chipset video boards
  *
  *	Copyright 2003	Ben. Herrenschmidt <benh@kernel.crashing.org>
@@ -75,7 +77,6 @@
 
 #ifdef CONFIG_PPC_OF
 
-#include <asm/prom.h>
 #include <asm/pci-bridge.h>
 #include "../macmodes.h"
 
@@ -150,8 +151,10 @@
 	CHIP_DEF(PCI_CHIP_RV250_Ig,	RV250,	CHIP_HAS_CRTC2),
 	/* Mobility 9100 IGP (U3) */
 	CHIP_DEF(PCI_CHIP_RS300_5835,	RS300,	CHIP_HAS_CRTC2 | CHIP_IS_IGP | CHIP_IS_MOBILITY),
+	CHIP_DEF(PCI_CHIP_RS350_7835,	RS300,	CHIP_HAS_CRTC2 | CHIP_IS_IGP | CHIP_IS_MOBILITY),
 	/* 9100 IGP (A5) */
 	CHIP_DEF(PCI_CHIP_RS300_5834,	RS300,	CHIP_HAS_CRTC2 | CHIP_IS_IGP),
+	CHIP_DEF(PCI_CHIP_RS350_7834,	RS300,	CHIP_HAS_CRTC2 | CHIP_IS_IGP),
 	/* Mobility 9200 (M9+) */
 	CHIP_DEF(PCI_CHIP_RV280_5C61,	RV280,	CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY),
 	CHIP_DEF(PCI_CHIP_RV280_5C63,	RV280,	CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY),
@@ -194,6 +197,33 @@
 	CHIP_DEF(PCI_CHIP_R350_NI,	R350,	CHIP_HAS_CRTC2),
 	CHIP_DEF(PCI_CHIP_R360_NJ,	R350,	CHIP_HAS_CRTC2),
 	CHIP_DEF(PCI_CHIP_R350_NK,	R350,	CHIP_HAS_CRTC2),
+	/* Newer stuff */
+	CHIP_DEF(PCI_CHIP_RV380_3E50,	RV380,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_RV380_3E54,	RV380,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_RV380_3150,	RV380,	CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY),
+	CHIP_DEF(PCI_CHIP_RV380_3154,	RV380,	CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY),
+	CHIP_DEF(PCI_CHIP_RV370_5B60,	RV380,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_RV370_5B62,	RV380,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_RV370_5B64,	RV380,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_RV370_5B65,	RV380,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_RV370_5460,	RV380,	CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY),
+	CHIP_DEF(PCI_CHIP_RV370_5464,	RV380,	CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY),
+	CHIP_DEF(PCI_CHIP_R420_JH,	R420,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_R420_JI,	R420,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_R420_JJ,	R420,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_R420_JK,	R420,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_R420_JL,	R420,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_R420_JM,	R420,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_R420_JN,	R420,	CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY),
+	CHIP_DEF(PCI_CHIP_R420_JP,	R420,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_R423_UH,	R420,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_R423_UI,	R420,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_R423_UJ,	R420,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_R423_UK,	R420,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_R423_UQ,	R420,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_R423_UR,	R420,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_R423_UT,	R420,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_R423_5D57,	R420,	CHIP_HAS_CRTC2),
 	/* Original Radeon/7200 */
 	CHIP_DEF(PCI_CHIP_RADEON_QD,	RADEON,	0),
 	CHIP_DEF(PCI_CHIP_RADEON_QE,	RADEON,	0),
@@ -233,6 +263,7 @@
 static char *mode_option;
 static char *monitor_layout;
 static int noaccel = 0;
+static int default_dynclk = -2;
 static int nomodeset = 0;
 static int ignore_edid = 0;
 static int mirror = 0;
@@ -261,32 +292,19 @@
 
 #endif /* CONFIG_PPC_OF */
 
-static void __devexit radeon_unmap_ROM(struct radeonfb_info *rinfo, struct pci_dev *dev)
+static void radeon_unmap_ROM(struct radeonfb_info *rinfo, struct pci_dev *dev)
 {
-	// leave it disabled and unassigned
-	struct resource *r = &dev->resource[PCI_ROM_RESOURCE];
-	
 	if (!rinfo->bios_seg)
 		return;
-	iounmap(rinfo->bios_seg);
-	
-	/* Release the ROM resource if we used it in the first place */
-	if (r->parent && r->flags & PCI_ROM_ADDRESS_ENABLE) {
-		release_resource(r);
-		r->flags &= ~PCI_ROM_ADDRESS_ENABLE;
-		r->end -= r->start;
-		r->start = 0;
-	}
-	/* This will disable and set address to unassigned */
-	pci_write_config_dword(dev, dev->rom_base_reg, 0);
+	pci_unmap_rom(dev, rinfo->bios_seg);
 }
 
 static int __devinit radeon_map_ROM(struct radeonfb_info *rinfo, struct pci_dev *dev)
 {
 	void __iomem *rom;
-	struct resource *r;
 	u16 dptr;
 	u8 rom_type;
+	size_t rom_size;
 
 	/* If this is a primary card, there is a shadow copy of the
 	 * ROM somewhere in the first meg. We will just ignore the copy
@@ -301,23 +319,10 @@
 	OUTREG(MPP_TB_CONFIG, temp);
 	temp = INREG(MPP_TB_CONFIG);
                                                                                                           
-	/* no need to search for the ROM, just ask the card where it is. */
-	r = &dev->resource[PCI_ROM_RESOURCE];
-	
-	/* assign the ROM an address if it doesn't have one */
-	if (r->parent == NULL)
-		pci_assign_resource(dev, PCI_ROM_RESOURCE);
-	
-	/* enable if needed */
-	if (!(r->flags & PCI_ROM_ADDRESS_ENABLE)) {
-		pci_write_config_dword(dev, dev->rom_base_reg,
-				       r->start | PCI_ROM_ADDRESS_ENABLE);
-		r->flags |= PCI_ROM_ADDRESS_ENABLE;
-	}
-	
-	rom = ioremap(r->start, r->end - r->start + 1);
+	rom = pci_map_rom(dev, &rom_size);
 	if (!rom) {
-		printk(KERN_ERR "radeonfb: ROM failed to map\n");
+		printk(KERN_ERR "radeonfb (%s): ROM failed to map\n",
+		       pci_name(rinfo->pdev));
 		return -ENOMEM;
 	}
 	
@@ -325,8 +330,8 @@
 
 	/* Very simple test to make sure it appeared */
 	if (BIOS_IN16(0) != 0xaa55) {
-		printk(KERN_ERR "radeonfb: Invalid ROM signature %x should be 0xaa55\n",
-		       BIOS_IN16(0));
+		printk(KERN_ERR "radeonfb (%s): Invalid ROM signature %x should be"
+		       "0xaa55\n", pci_name(rinfo->pdev), BIOS_IN16(0));
 		goto failed;
 	}
 	/* Look for the PCI data to check the ROM type */
@@ -357,8 +362,8 @@
 	 * } pci_data_t;
 	 */
 	if (BIOS_IN32(dptr) !=  (('R' << 24) | ('I' << 16) | ('C' << 8) | 'P')) {
-		printk(KERN_WARNING "radeonfb: PCI DATA signature in ROM incorrect: %08x\n",
-		       BIOS_IN32(dptr));
+		printk(KERN_WARNING "radeonfb (%s): PCI DATA signature in ROM"
+		       "incorrect: %08x\n", pci_name(rinfo->pdev), BIOS_IN32(dptr));
 		goto anyway;
 	}
 	rom_type = BIOS_IN8(dptr + 0x14);
@@ -425,14 +430,11 @@
  */
 static int __devinit radeon_read_xtal_OF (struct radeonfb_info *rinfo)
 {
-	struct device_node *dp;
+	struct device_node *dp = rinfo->of_node;
 	u32 *val;
 
-	dp = pci_device_to_OF_node(rinfo->pdev);
-	if (dp == NULL) {
-		printk(KERN_WARNING "radeonfb: Cannot match card to OF node !\n");
+	if (dp == NULL)
 		return -ENODEV;
-	}
 	val = (u32 *) get_property(dp, "ATY,RefCLK", NULL);
 	if (!val || !*val) {
 		printk(KERN_WARNING "radeonfb: No ATY,RefCLK property !\n");
@@ -515,20 +517,20 @@
 		denom = 1;
 		break;
 	case 1:
-		n = ((INPLL(X_MPLL_REF_FB_DIV) >> 16) & 0xff);
-		m = (INPLL(X_MPLL_REF_FB_DIV) & 0xff);
+		n = ((INPLL(M_SPLL_REF_FB_DIV) >> 16) & 0xff);
+		m = (INPLL(M_SPLL_REF_FB_DIV) & 0xff);
 		num = 2*n;
 		denom = 2*m;
 		break;
 	case 2:
-		n = ((INPLL(X_MPLL_REF_FB_DIV) >> 8) & 0xff);
-		m = (INPLL(X_MPLL_REF_FB_DIV) & 0xff);
+		n = ((INPLL(M_SPLL_REF_FB_DIV) >> 8) & 0xff);
+		m = (INPLL(M_SPLL_REF_FB_DIV) & 0xff);
 		num = 2*n;
 		denom = 2*m;
         break;
 	}
 
-	ppll_div_sel = INREG(CLOCK_CNTL_INDEX + 1) & 0x3;
+	ppll_div_sel = INREG8(CLOCK_CNTL_INDEX + 1) & 0x3;
 
 	n = (INPLL(PPLL_DIV_0 + ppll_div_sel) & 0x7ff);
 	m = (INPLL(PPLL_REF_DIV) & 0x3ff);
@@ -572,7 +574,7 @@
 		return -1;
 	}
 
-	tmp = INPLL(X_MPLL_REF_FB_DIV);
+	tmp = INPLL(M_SPLL_REF_FB_DIV);
 	ref_div = INPLL(PPLL_REF_DIV) & 0x3ff;
 
 	Ns = (tmp & 0xff0000) >> 16;
@@ -652,7 +654,7 @@
 		rinfo->pll.ref_clk = 2700;
 		break;
 	}
-	rinfo->pll.ref_div = INPLL(PPLL_REF_DIV) & 0x3ff;
+	rinfo->pll.ref_div = INPLL(PPLL_REF_DIV) & PPLL_REF_DIV_MASK;
 
 
 #ifdef CONFIG_PPC_OF
@@ -933,10 +935,11 @@
 }
 
 
-static int radeon_screen_blank (struct radeonfb_info *rinfo, int blank, int mode_switch)
+int radeon_screen_blank(struct radeonfb_info *rinfo, int blank, int mode_switch)
 {
         u32 val;
 	u32 tmp_pix_clks;
+	int unblank = 0;
 
 	if (rinfo->lock_blank)
 		return 0;
@@ -947,9 +950,6 @@
         val &= ~(CRTC_DISPLAY_DIS | CRTC_HSYNC_DIS |
                  CRTC_VSYNC_DIS);
         switch (blank) {
-	case FB_BLANK_UNBLANK:
-	case FB_BLANK_NORMAL:
-		break;
 	case FB_BLANK_VSYNC_SUSPEND:
 		val |= (CRTC_DISPLAY_DIS | CRTC_VSYNC_DIS);
 		break;
@@ -960,42 +960,51 @@
 		val |= (CRTC_DISPLAY_DIS | CRTC_VSYNC_DIS |
 			CRTC_HSYNC_DIS);
 		break;
+	case FB_BLANK_NORMAL:
+		val |= CRTC_DISPLAY_DIS;
+		break;
+	case FB_BLANK_UNBLANK:
+	default:
+		unblank = 1;
         }
 	OUTREG(CRTC_EXT_CNTL, val);
 
 
 	switch (rinfo->mon1_type) {
 	case MT_DFP:
-		if (mode_switch)
-			break;
-		if (blank == FB_BLANK_UNBLANK ||
-		    blank == FB_BLANK_NORMAL)
+		if (unblank)
 			OUTREGP(FP_GEN_CNTL, (FP_FPON | FP_TMDS_EN),
 				~(FP_FPON | FP_TMDS_EN));
-		else
+		else {
+			if (mode_switch || blank == FB_BLANK_NORMAL)
+				break;
 			OUTREGP(FP_GEN_CNTL, 0, ~(FP_FPON | FP_TMDS_EN));
+		}
 		break;
 	case MT_LCD:
+		del_timer_sync(&rinfo->lvds_timer);
 		val = INREG(LVDS_GEN_CNTL);
-		if (blank == FB_BLANK_UNBLANK ||
-		    blank == FB_BLANK_NORMAL) {
+		if (unblank) {
 			u32 target_val = (val & ~LVDS_DISPLAY_DIS) | LVDS_BLON | LVDS_ON
-				| LVDS_ON | (rinfo->init_state.lvds_gen_cntl & LVDS_DIGON);
+				| LVDS_EN | (rinfo->init_state.lvds_gen_cntl
+					     & (LVDS_DIGON | LVDS_BL_MOD_EN));
 			if ((val ^ target_val) == LVDS_DISPLAY_DIS)
 				OUTREG(LVDS_GEN_CNTL, target_val);
 			else if ((val ^ target_val) != 0) {
-				del_timer_sync(&rinfo->lvds_timer);
-				OUTREG(LVDS_GEN_CNTL, target_val & ~LVDS_ON);
+				OUTREG(LVDS_GEN_CNTL, target_val
+				       & ~(LVDS_ON | LVDS_BL_MOD_EN));
 				rinfo->init_state.lvds_gen_cntl &= ~LVDS_STATE_MASK;
-				rinfo->init_state.lvds_gen_cntl |= target_val & LVDS_STATE_MASK;
+				rinfo->init_state.lvds_gen_cntl |=
+					target_val & LVDS_STATE_MASK;
 				if (mode_switch) {
-					msleep(rinfo->panel_info.pwr_delay);
+					radeon_msleep(rinfo->panel_info.pwr_delay);
 					OUTREG(LVDS_GEN_CNTL, target_val);
 				}
 				else {
 					rinfo->pending_lvds_gen_cntl = target_val;
 					mod_timer(&rinfo->lvds_timer,
-						jiffies + msecs_to_jiffies(rinfo->panel_info.pwr_delay));
+					   jiffies +
+					   msecs_to_jiffies(rinfo->panel_info.pwr_delay));
 				}
 			}
 		} else {
@@ -1003,7 +1012,7 @@
 			OUTREG(LVDS_GEN_CNTL, val);
 
 			/* We don't do a full switch-off on a simple mode switch */
-			if (mode_switch)
+			if (mode_switch || blank == FB_BLANK_NORMAL)
 				break;
 
 			/* Asic bug, when turning off LVDS_ON, we have to make sure
@@ -1012,8 +1021,16 @@
 			tmp_pix_clks = INPLL(PIXCLKS_CNTL);
 			if (rinfo->is_mobility || rinfo->is_IGP)
 				OUTPLLP(PIXCLKS_CNTL, 0, ~PIXCLK_LVDS_ALWAYS_ONb);
-			val &= ~(LVDS_BLON | LVDS_ON);
+			val &= ~(LVDS_BL_MOD_EN);
+			OUTREG(LVDS_GEN_CNTL, val);
+			udelay(100);
+			val &= ~(LVDS_ON | LVDS_EN);
 			OUTREG(LVDS_GEN_CNTL, val);
+			val &= ~LVDS_DIGON;
+			rinfo->pending_lvds_gen_cntl = val;
+			mod_timer(&rinfo->lvds_timer,
+				  jiffies +
+				  msecs_to_jiffies(rinfo->panel_info.pwr_delay));
 			rinfo->init_state.lvds_gen_cntl &= ~LVDS_STATE_MASK;
 			rinfo->init_state.lvds_gen_cntl |= val & LVDS_STATE_MASK;
 			if (rinfo->is_mobility || rinfo->is_IGP)
@@ -1030,16 +1047,14 @@
 	return (blank == FB_BLANK_NORMAL) ? -EINVAL : 0;
 }
 
-int radeonfb_blank (int blank, struct fb_info *info)
+static int radeonfb_blank (int blank, struct fb_info *info)
 {
         struct radeonfb_info *rinfo = info->par;
 
 	if (rinfo->asleep)
 		return 0;
 		
-	radeon_screen_blank(rinfo, blank, 0);
-
-	return 0;
+	return radeon_screen_blank(rinfo, blank, 0);
 }
 
 static int radeonfb_setcolreg (unsigned regno, unsigned red, unsigned green,
@@ -1124,7 +1139,7 @@
 }
 
 
-static void radeon_save_state (struct radeonfb_info *rinfo, struct radeon_regs *save)
+void radeon_save_state (struct radeonfb_info *rinfo, struct radeon_regs *save)
 {
 	/* CRTC regs */
 	save->crtc_gen_cntl = INREG(CRTC_GEN_CNTL);
@@ -1148,8 +1163,14 @@
 	save->fp_vert_stretch = INREG(FP_VERT_STRETCH);
 	save->lvds_gen_cntl = INREG(LVDS_GEN_CNTL);
 	save->lvds_pll_cntl = INREG(LVDS_PLL_CNTL);
-	save->tmds_crc = INREG(TMDS_CRC);	save->tmds_transmitter_cntl = INREG(TMDS_TRANSMITTER_CNTL);
+	save->tmds_crc = INREG(TMDS_CRC);
+	save->tmds_transmitter_cntl = INREG(TMDS_TRANSMITTER_CNTL);
 	save->vclk_ecp_cntl = INPLL(VCLK_ECP_CNTL);
+
+	/* PLL regs */
+	save->clk_cntl_index = INREG(CLOCK_CNTL_INDEX) & ~0x3f;
+	save->ppll_div_3 = INPLL(PPLL_DIV_3);
+	save->ppll_ref_div = INPLL(PPLL_REF_DIV);
 }
 
 
@@ -1161,19 +1182,22 @@
 
 	/* Workaround from XFree */
 	if (rinfo->is_mobility) {
-	        /* A temporal workaround for the occational blanking on certain laptop panels. 
-	           This appears to related to the PLL divider registers (fail to lock?).  
-		   It occurs even when all dividers are the same with their old settings.  
-	           In this case we really don't need to fiddle with PLL registers. 
-	           By doing this we can avoid the blanking problem with some panels.
-	        */
+	        /* A temporal workaround for the occational blanking on certain laptop
+		 * panels. This appears to related to the PLL divider registers
+		 * (fail to lock?). It occurs even when all dividers are the same
+		 * with their old settings. In this case we really don't need to
+		 * fiddle with PLL registers. By doing this we can avoid the blanking
+		 * problem with some panels.
+	         */
 		if ((mode->ppll_ref_div == (INPLL(PPLL_REF_DIV) & PPLL_REF_DIV_MASK)) &&
 		    (mode->ppll_div_3 == (INPLL(PPLL_DIV_3) &
 					  (PPLL_POST3_DIV_MASK | PPLL_FB3_DIV_MASK)))) {
-			/* We still have to force a switch to PPLL div 3 thanks to
+			/* We still have to force a switch to selected PPLL div thanks to
 			 * an XFree86 driver bug which will switch it away in some cases
 			 * even when using UseFDev */
-			OUTREGP(CLOCK_CNTL_INDEX, PPLL_DIV_SEL_MASK, ~PPLL_DIV_SEL_MASK);
+			OUTREGP(CLOCK_CNTL_INDEX,
+				mode->clk_cntl_index & PPLL_DIV_SEL_MASK,
+				~PPLL_DIV_SEL_MASK);
             		return;
 		}
 	}
@@ -1186,8 +1210,10 @@
 		PPLL_RESET | PPLL_ATOMIC_UPDATE_EN | PPLL_VGA_ATOMIC_UPDATE_EN,
 		~(PPLL_RESET | PPLL_ATOMIC_UPDATE_EN | PPLL_VGA_ATOMIC_UPDATE_EN));
 
-	/* Switch to PPLL div 3 */
-	OUTREGP(CLOCK_CNTL_INDEX, PPLL_DIV_SEL_MASK, ~PPLL_DIV_SEL_MASK);
+	/* Switch to selected PPLL divider */
+	OUTREGP(CLOCK_CNTL_INDEX,
+		mode->clk_cntl_index & PPLL_DIV_SEL_MASK,
+		~PPLL_DIV_SEL_MASK);
 
 	/* Set PPLL ref. div */
 	if (rinfo->family == CHIP_FAMILY_R300 ||
@@ -1232,7 +1258,7 @@
 		~(PPLL_RESET | PPLL_SLEEP | PPLL_ATOMIC_UPDATE_EN | PPLL_VGA_ATOMIC_UPDATE_EN));
 
 	/* We may want some locking ... oh well */
-       	msleep(5);
+       	radeon_msleep(5);
 
 	/* Switch back VCLK source to PPLL */
 	OUTPLLP(VCLK_ECP_CNTL, VCLK_SRC_SEL_PPLLCLK, ~VCLK_SRC_SEL_MASK);
@@ -1245,21 +1271,17 @@
 {
 	struct radeonfb_info *rinfo = (struct radeonfb_info *)data;
 
-	radeon_fifo_wait(3);
+	radeon_engine_idle();
 
 	OUTREG(LVDS_GEN_CNTL, rinfo->pending_lvds_gen_cntl);
-	if (rinfo->pending_pixclks_cntl) {
-		OUTPLL(PIXCLKS_CNTL, rinfo->pending_pixclks_cntl);
-		rinfo->pending_pixclks_cntl = 0;
-	}
 }
 
 /*
  * Apply a video mode. This will apply the whole register set, including
  * the PLL registers, to the card
  */
-static void radeon_write_mode (struct radeonfb_info *rinfo,
-                               struct radeon_regs *mode)
+void radeon_write_mode (struct radeonfb_info *rinfo, struct radeon_regs *mode,
+			int regs_only)
 {
 	int i;
 	int primary_mon = PRIMARY_MONITOR(rinfo);
@@ -1267,10 +1289,8 @@
 	if (nomodeset)
 		return;
 
-	del_timer_sync(&rinfo->lvds_timer);
-
-	radeon_screen_blank(rinfo, FB_BLANK_POWERDOWN, 1);
-	msleep(100);
+	if (!regs_only)
+		radeon_screen_blank(rinfo, FB_BLANK_NORMAL, 0);
 
 	radeon_fifo_wait(31);
 	for (i=0; i<10; i++)
@@ -1312,7 +1332,8 @@
 		OUTREG(TMDS_TRANSMITTER_CNTL, mode->tmds_transmitter_cntl);
 	}
 
-	radeon_screen_blank(rinfo, FB_BLANK_UNBLANK, 1);
+	if (!regs_only)
+		radeon_screen_blank(rinfo, FB_BLANK_UNBLANK, 0);
 
 	radeon_fifo_wait(2);
 	OUTPLL(VCLK_ECP_CNTL, mode->vclk_ecp_cntl);
@@ -1423,6 +1444,16 @@
 	       rinfo->pll.ref_div, rinfo->pll.ref_clk,
 	       pll_output_freq);
 
+	/* If we fall through the bottom, try the "default value"
+	   given by the terminal post_div->bitvalue */
+	if ( !post_div->divider ) {
+		post_div = &post_divs[post_div->bitvalue];
+		pll_output_freq = post_div->divider * freq;
+	}
+	RTRACE("ref_div = %d, ref_clk = %d, output_freq = %d\n",
+	       rinfo->pll.ref_div, rinfo->pll.ref_clk,
+	       pll_output_freq);
+
 	fb_div = round_div(rinfo->pll.ref_div*pll_output_freq,
 				  rinfo->pll.ref_clk);
 	regs->ppll_ref_div = rinfo->pll.ref_div;
@@ -1433,22 +1464,27 @@
 	RTRACE("ppll_div_3 = 0x%x\n", regs->ppll_div_3);
 }
 
-int radeonfb_set_par(struct fb_info *info)
+static int radeonfb_set_par(struct fb_info *info)
 {
 	struct radeonfb_info *rinfo = info->par;
 	struct fb_var_screeninfo *mode = &info->var;
-	struct radeon_regs newmode;
+	struct radeon_regs *newmode;
 	int hTotal, vTotal, hSyncStart, hSyncEnd,
 	    hSyncPol, vSyncStart, vSyncEnd, vSyncPol, cSync;
 	u8 hsync_adj_tab[] = {0, 0x12, 9, 9, 6, 5};
 	u8 hsync_fudge_fp[] = {2, 2, 0, 0, 5, 5};
 	u32 sync, h_sync_pol, v_sync_pol, dotClock, pixClock;
 	int i, freq;
-        int format = 0;
+	int format = 0;
 	int nopllcalc = 0;
 	int hsync_start, hsync_fudge, bytpp, hsync_wid, vsync_wid;
 	int primary_mon = PRIMARY_MONITOR(rinfo);
 	int depth = var_to_depth(mode);
+	int use_rmx = 0;
+
+	newmode = kmalloc(sizeof(struct radeon_regs), GFP_KERNEL);
+	if (!newmode)
+		return -ENOMEM;
 
 	/* We always want engine to be idle on a mode switch, even
 	 * if we won't actually change the mode
@@ -1489,9 +1525,9 @@
 
 		if (rinfo->panel_info.use_bios_dividers) {
 			nopllcalc = 1;
-			newmode.ppll_div_3 = rinfo->panel_info.fbk_divider |
+			newmode->ppll_div_3 = rinfo->panel_info.fbk_divider |
 				(rinfo->panel_info.post_divider << 16);
-			newmode.ppll_ref_div = rinfo->panel_info.ref_divider;
+			newmode->ppll_ref_div = rinfo->panel_info.ref_divider;
 		}
 	}
 	dotClock = 1000000000 / pixClock;
@@ -1529,38 +1565,38 @@
 
 	hsync_start = hSyncStart - 8 + hsync_fudge;
 
-	newmode.crtc_gen_cntl = CRTC_EXT_DISP_EN | CRTC_EN |
+	newmode->crtc_gen_cntl = CRTC_EXT_DISP_EN | CRTC_EN |
 				(format << 8);
 
 	/* Clear auto-center etc... */
-	newmode.crtc_more_cntl = rinfo->init_state.crtc_more_cntl;
-	newmode.crtc_more_cntl &= 0xfffffff0;
+	newmode->crtc_more_cntl = rinfo->init_state.crtc_more_cntl;
+	newmode->crtc_more_cntl &= 0xfffffff0;
 	
 	if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) {
-		newmode.crtc_ext_cntl = VGA_ATI_LINEAR | XCRT_CNT_EN;
+		newmode->crtc_ext_cntl = VGA_ATI_LINEAR | XCRT_CNT_EN;
 		if (mirror)
-			newmode.crtc_ext_cntl |= CRTC_CRT_ON;
+			newmode->crtc_ext_cntl |= CRTC_CRT_ON;
 
-		newmode.crtc_gen_cntl &= ~(CRTC_DBL_SCAN_EN |
+		newmode->crtc_gen_cntl &= ~(CRTC_DBL_SCAN_EN |
 					   CRTC_INTERLACE_EN);
 	} else {
-		newmode.crtc_ext_cntl = VGA_ATI_LINEAR | XCRT_CNT_EN |
+		newmode->crtc_ext_cntl = VGA_ATI_LINEAR | XCRT_CNT_EN |
 					CRTC_CRT_ON;
 	}
 
-	newmode.dac_cntl = /* INREG(DAC_CNTL) | */ DAC_MASK_ALL | DAC_VGA_ADR_EN |
+	newmode->dac_cntl = /* INREG(DAC_CNTL) | */ DAC_MASK_ALL | DAC_VGA_ADR_EN |
 			   DAC_8BIT_EN;
 
-	newmode.crtc_h_total_disp = ((((hTotal / 8) - 1) & 0x3ff) |
+	newmode->crtc_h_total_disp = ((((hTotal / 8) - 1) & 0x3ff) |
 				     (((mode->xres / 8) - 1) << 16));
 
-	newmode.crtc_h_sync_strt_wid = ((hsync_start & 0x1fff) |
+	newmode->crtc_h_sync_strt_wid = ((hsync_start & 0x1fff) |
 					(hsync_wid << 16) | (h_sync_pol << 23));
 
-	newmode.crtc_v_total_disp = ((vTotal - 1) & 0xffff) |
+	newmode->crtc_v_total_disp = ((vTotal - 1) & 0xffff) |
 				    ((mode->yres - 1) << 16);
 
-	newmode.crtc_v_sync_strt_wid = (((vSyncStart - 1) & 0xfff) |
+	newmode->crtc_v_sync_strt_wid = (((vSyncStart - 1) & 0xfff) |
 					 (vsync_wid << 16) | (v_sync_pol  << 23));
 
 	if (!(info->flags & FBINFO_HWACCEL_DISABLED)) {
@@ -1569,18 +1605,18 @@
  				& ~(0x3f)) >> 6;
 
 		/* Then, re-multiply it to get the CRTC pitch */
-		newmode.crtc_pitch = (rinfo->pitch << 3) / ((mode->bits_per_pixel + 1) / 8);
+		newmode->crtc_pitch = (rinfo->pitch << 3) / ((mode->bits_per_pixel + 1) / 8);
 	} else
-		newmode.crtc_pitch = (mode->xres_virtual >> 3);
+		newmode->crtc_pitch = (mode->xres_virtual >> 3);
 
-	newmode.crtc_pitch |= (newmode.crtc_pitch << 16);
+	newmode->crtc_pitch |= (newmode->crtc_pitch << 16);
 
 	/*
 	 * It looks like recent chips have a problem with SURFACE_CNTL,
 	 * setting SURF_TRANSLATION_DIS completely disables the
 	 * swapper as well, so we leave it unset now.
 	 */
-	newmode.surface_cntl = 0;
+	newmode->surface_cntl = 0;
 
 #if defined(__BIG_ENDIAN)
 
@@ -1590,28 +1626,28 @@
 	 */
 	switch (mode->bits_per_pixel) {
 		case 16:
-			newmode.surface_cntl |= NONSURF_AP0_SWP_16BPP;
-			newmode.surface_cntl |= NONSURF_AP1_SWP_16BPP;
+			newmode->surface_cntl |= NONSURF_AP0_SWP_16BPP;
+			newmode->surface_cntl |= NONSURF_AP1_SWP_16BPP;
 			break;
 		case 24:	
 		case 32:
-			newmode.surface_cntl |= NONSURF_AP0_SWP_32BPP;
-			newmode.surface_cntl |= NONSURF_AP1_SWP_32BPP;
+			newmode->surface_cntl |= NONSURF_AP0_SWP_32BPP;
+			newmode->surface_cntl |= NONSURF_AP1_SWP_32BPP;
 			break;
 	}
 #endif
 
 	/* Clear surface registers */
 	for (i=0; i<8; i++) {
-		newmode.surf_lower_bound[i] = 0;
-		newmode.surf_upper_bound[i] = 0x1f;
-		newmode.surf_info[i] = 0;
+		newmode->surf_lower_bound[i] = 0;
+		newmode->surf_upper_bound[i] = 0x1f;
+		newmode->surf_info[i] = 0;
 	}
 
 	RTRACE("h_total_disp = 0x%x\t   hsync_strt_wid = 0x%x\n",
-		newmode.crtc_h_total_disp, newmode.crtc_h_sync_strt_wid);
+		newmode->crtc_h_total_disp, newmode->crtc_h_sync_strt_wid);
 	RTRACE("v_total_disp = 0x%x\t   vsync_strt_wid = 0x%x\n",
-		newmode.crtc_v_total_disp, newmode.crtc_v_sync_strt_wid);
+		newmode->crtc_v_total_disp, newmode->crtc_v_sync_strt_wid);
 
 	rinfo->bpp = mode->bits_per_pixel;
 	rinfo->depth = depth;
@@ -1619,10 +1655,14 @@
 	RTRACE("pixclock = %lu\n", (unsigned long)pixClock);
 	RTRACE("freq = %lu\n", (unsigned long)freq);
 
+	/* We use PPLL_DIV_3 */
+	newmode->clk_cntl_index = 0x300;
+
+	/* Calculate PPLL value if necessary */
 	if (!nopllcalc)
-		radeon_calc_pll_regs(rinfo, &newmode, freq);
+		radeon_calc_pll_regs(rinfo, newmode, freq);
 
-	newmode.vclk_ecp_cntl = rinfo->init_state.vclk_ecp_cntl;
+	newmode->vclk_ecp_cntl = rinfo->init_state.vclk_ecp_cntl;
 
 	if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) {
 		unsigned int hRatio, vRatio;
@@ -1632,35 +1672,37 @@
 		if (mode->yres > rinfo->panel_info.yres)
 			mode->yres = rinfo->panel_info.yres;
 
-		newmode.fp_horz_stretch = (((rinfo->panel_info.xres / 8) - 1)
+		newmode->fp_horz_stretch = (((rinfo->panel_info.xres / 8) - 1)
 					   << HORZ_PANEL_SHIFT);
-		newmode.fp_vert_stretch = ((rinfo->panel_info.yres - 1)
+		newmode->fp_vert_stretch = ((rinfo->panel_info.yres - 1)
 					   << VERT_PANEL_SHIFT);
 
 		if (mode->xres != rinfo->panel_info.xres) {
 			hRatio = round_div(mode->xres * HORZ_STRETCH_RATIO_MAX,
 					   rinfo->panel_info.xres);
-			newmode.fp_horz_stretch = (((((unsigned long)hRatio) & HORZ_STRETCH_RATIO_MASK)) |
-						   (newmode.fp_horz_stretch &
+			newmode->fp_horz_stretch = (((((unsigned long)hRatio) & HORZ_STRETCH_RATIO_MASK)) |
+						   (newmode->fp_horz_stretch &
 						    (HORZ_PANEL_SIZE | HORZ_FP_LOOP_STRETCH |
 						     HORZ_AUTO_RATIO_INC)));
-			newmode.fp_horz_stretch |= (HORZ_STRETCH_BLEND |
+			newmode->fp_horz_stretch |= (HORZ_STRETCH_BLEND |
 						    HORZ_STRETCH_ENABLE);
+			use_rmx = 1;
 		}
-		newmode.fp_horz_stretch &= ~HORZ_AUTO_RATIO;
+		newmode->fp_horz_stretch &= ~HORZ_AUTO_RATIO;
 
 		if (mode->yres != rinfo->panel_info.yres) {
 			vRatio = round_div(mode->yres * VERT_STRETCH_RATIO_MAX,
 					   rinfo->panel_info.yres);
-			newmode.fp_vert_stretch = (((((unsigned long)vRatio) & VERT_STRETCH_RATIO_MASK)) |
-						   (newmode.fp_vert_stretch &
+			newmode->fp_vert_stretch = (((((unsigned long)vRatio) & VERT_STRETCH_RATIO_MASK)) |
+						   (newmode->fp_vert_stretch &
 						   (VERT_PANEL_SIZE | VERT_STRETCH_RESERVED)));
-			newmode.fp_vert_stretch |= (VERT_STRETCH_BLEND |
+			newmode->fp_vert_stretch |= (VERT_STRETCH_BLEND |
 						    VERT_STRETCH_ENABLE);
+			use_rmx = 1;
 		}
-		newmode.fp_vert_stretch &= ~VERT_AUTO_RATIO_EN;
+		newmode->fp_vert_stretch &= ~VERT_AUTO_RATIO_EN;
 
-		newmode.fp_gen_cntl = (rinfo->init_state.fp_gen_cntl & (u32)
+		newmode->fp_gen_cntl = (rinfo->init_state.fp_gen_cntl & (u32)
 				       ~(FP_SEL_CRTC2 |
 					 FP_RMX_HVSYNC_CONTROL_EN |
 					 FP_DFP_SYNC_SEL |
@@ -1670,46 +1712,56 @@
 					 FP_CRTC_USE_SHADOW_VEND |
 					 FP_CRT_SYNC_ALT));
 
-		newmode.fp_gen_cntl |= (FP_CRTC_DONT_SHADOW_VPAR |
-					FP_CRTC_DONT_SHADOW_HEND);
+		newmode->fp_gen_cntl |= (FP_CRTC_DONT_SHADOW_VPAR |
+					FP_CRTC_DONT_SHADOW_HEND |
+					FP_PANEL_FORMAT);
+
+		if (IS_R300_VARIANT(rinfo) ||
+		    (rinfo->family == CHIP_FAMILY_R200)) {
+			newmode->fp_gen_cntl &= ~R200_FP_SOURCE_SEL_MASK;
+			if (use_rmx)
+				newmode->fp_gen_cntl |= R200_FP_SOURCE_SEL_RMX;
+			else
+				newmode->fp_gen_cntl |= R200_FP_SOURCE_SEL_CRTC1;
+		} else
+			newmode->fp_gen_cntl |= FP_SEL_CRTC1;
 
-		newmode.lvds_gen_cntl = rinfo->init_state.lvds_gen_cntl;
-		newmode.lvds_pll_cntl = rinfo->init_state.lvds_pll_cntl;
-		newmode.tmds_crc = rinfo->init_state.tmds_crc;
-		newmode.tmds_transmitter_cntl = rinfo->init_state.tmds_transmitter_cntl;
+		newmode->lvds_gen_cntl = rinfo->init_state.lvds_gen_cntl;
+		newmode->lvds_pll_cntl = rinfo->init_state.lvds_pll_cntl;
+		newmode->tmds_crc = rinfo->init_state.tmds_crc;
+		newmode->tmds_transmitter_cntl = rinfo->init_state.tmds_transmitter_cntl;
 
 		if (primary_mon == MT_LCD) {
-			newmode.lvds_gen_cntl |= (LVDS_ON | LVDS_BLON);
-			newmode.fp_gen_cntl &= ~(FP_FPON | FP_TMDS_EN);
+			newmode->lvds_gen_cntl |= (LVDS_ON | LVDS_BLON);
+			newmode->fp_gen_cntl &= ~(FP_FPON | FP_TMDS_EN);
 		} else {
 			/* DFP */
-			newmode.fp_gen_cntl |= (FP_FPON | FP_TMDS_EN);
-			newmode.tmds_transmitter_cntl = (TMDS_RAN_PAT_RST | TMDS_ICHCSEL) &
+			newmode->fp_gen_cntl |= (FP_FPON | FP_TMDS_EN);
+			newmode->tmds_transmitter_cntl = (TMDS_RAN_PAT_RST | TMDS_ICHCSEL) &
 							 ~(TMDS_PLLRST);
 			/* TMDS_PLL_EN bit is reversed on RV (and mobility) chips */
-			if ((rinfo->family == CHIP_FAMILY_R300) ||
-			    (rinfo->family == CHIP_FAMILY_R350) ||
-			    (rinfo->family == CHIP_FAMILY_RV350) ||
+			if (IS_R300_VARIANT(rinfo) ||
 			    (rinfo->family == CHIP_FAMILY_R200) || !rinfo->has_CRTC2)
-				newmode.tmds_transmitter_cntl &= ~TMDS_PLL_EN;
+				newmode->tmds_transmitter_cntl &= ~TMDS_PLL_EN;
 			else
-				newmode.tmds_transmitter_cntl |= TMDS_PLL_EN;
-			newmode.crtc_ext_cntl &= ~CRTC_CRT_ON;
+				newmode->tmds_transmitter_cntl |= TMDS_PLL_EN;
+			newmode->crtc_ext_cntl &= ~CRTC_CRT_ON;
 		}
 
-		newmode.fp_crtc_h_total_disp = (((rinfo->panel_info.hblank / 8) & 0x3ff) |
+		newmode->fp_crtc_h_total_disp = (((rinfo->panel_info.hblank / 8) & 0x3ff) |
 				(((mode->xres / 8) - 1) << 16));
-		newmode.fp_crtc_v_total_disp = (rinfo->panel_info.vblank & 0xffff) |
+		newmode->fp_crtc_v_total_disp = (rinfo->panel_info.vblank & 0xffff) |
 				((mode->yres - 1) << 16);
-		newmode.fp_h_sync_strt_wid = ((rinfo->panel_info.hOver_plus & 0x1fff) |
+		newmode->fp_h_sync_strt_wid = ((rinfo->panel_info.hOver_plus & 0x1fff) |
 				(hsync_wid << 16) | (h_sync_pol << 23));
-		newmode.fp_v_sync_strt_wid = ((rinfo->panel_info.vOver_plus & 0xfff) |
+		newmode->fp_v_sync_strt_wid = ((rinfo->panel_info.vOver_plus & 0xfff) |
 				(vsync_wid << 16) | (v_sync_pol  << 23));
 	}
 
 	/* do it! */
 	if (!rinfo->asleep) {
-		radeon_write_mode (rinfo, &newmode);
+		memcpy(&rinfo->state, newmode, sizeof(*newmode));
+		radeon_write_mode (rinfo, newmode, 0);
 		/* (re)initialize the engine */
 		if (!(info->flags & FBINFO_HWACCEL_DISABLED))
 			radeonfb_engine_init (rinfo);
@@ -1729,6 +1781,7 @@
 			     rinfo->depth, info->fix.line_length);
 #endif
 
+	kfree(newmode);
 	return 0;
 }
 
@@ -1775,6 +1828,7 @@
         info->fix.type_aux = 0;
         info->fix.mmio_start = rinfo->mmio_base_phys;
         info->fix.mmio_len = RADEON_REGSIZE;
+	info->fix.accel = FB_ACCEL_ATI_RADEON;
 
 	fb_alloc_cmap(&info->cmap, 256, 0);
 
@@ -1838,12 +1892,14 @@
 	if (on && (level > BACKLIGHT_OFF)) {
 		lvds_gen_cntl &= ~LVDS_DISPLAY_DIS;
 		if (!(lvds_gen_cntl & LVDS_BLON) || !(lvds_gen_cntl & LVDS_ON)) {
-			lvds_gen_cntl |= LVDS_BLON /* | LVDS_EN | LVDS_DIGON */;
+			lvds_gen_cntl |= (rinfo->init_state.lvds_gen_cntl & LVDS_DIGON);
+			lvds_gen_cntl |= LVDS_BLON | LVDS_EN;
 			OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);
 			lvds_gen_cntl &= ~LVDS_BL_MOD_LEVEL_MASK;
 			lvds_gen_cntl |= (conv_table[level] <<
 					  LVDS_BL_MOD_LEVEL_SHIFT);
 			lvds_gen_cntl |= LVDS_ON;
+			lvds_gen_cntl |= (rinfo->init_state.lvds_gen_cntl & LVDS_BL_MOD_EN);
 			rinfo->pending_lvds_gen_cntl = lvds_gen_cntl;
 			mod_timer(&rinfo->lvds_timer,
 				  jiffies + msecs_to_jiffies(rinfo->panel_info.pwr_delay));
@@ -1863,13 +1919,18 @@
 		tmpPixclksCntl = INPLL(PIXCLKS_CNTL);
 		if (rinfo->is_mobility || rinfo->is_IGP)
 			OUTPLLP(PIXCLKS_CNTL, 0, ~PIXCLK_LVDS_ALWAYS_ONb);
-		lvds_gen_cntl &= ~LVDS_BL_MOD_LEVEL_MASK;
+		lvds_gen_cntl &= ~(LVDS_BL_MOD_LEVEL_MASK | LVDS_BL_MOD_EN);
 		lvds_gen_cntl |= (conv_table[0] <<
 				  LVDS_BL_MOD_LEVEL_SHIFT);
 		lvds_gen_cntl |= LVDS_DISPLAY_DIS;
 		OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);
-		lvds_gen_cntl &= ~(LVDS_ON | LVDS_BLON /* | LVDS_EN | LVDS_DIGON */);
+		udelay(100);
+		lvds_gen_cntl &= ~(LVDS_ON | LVDS_EN);
 		OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);
+		lvds_gen_cntl &= ~(LVDS_DIGON);
+		rinfo->pending_lvds_gen_cntl = lvds_gen_cntl;
+		mod_timer(&rinfo->lvds_timer,
+			  jiffies + msecs_to_jiffies(rinfo->panel_info.pwr_delay));
 		if (rinfo->is_mobility || rinfo->is_IGP)
 			OUTPLL(PIXCLKS_CNTL, tmpPixclksCntl);
 	}
@@ -1952,10 +2013,12 @@
 	OUTREG(DISPLAY_BASE_ADDR, aper_base);
 	if (rinfo->has_CRTC2)
 		OUTREG(CRTC2_DISPLAY_BASE_ADDR, aper_base);
+	OUTREG(OV0_BASE_ADDR, aper_base);
 #else
 	OUTREG(DISPLAY_BASE_ADDR, 0);
 	if (rinfo->has_CRTC2)
 		OUTREG(CRTC2_DISPLAY_BASE_ADDR, 0);
+	OUTREG(OV0_BASE_ADDR, 0);
 #endif
 	mdelay(100);
 
@@ -1973,6 +2036,100 @@
 #endif /* CONFIG_PPC_OF */
 
 
+static void radeon_identify_vram(struct radeonfb_info *rinfo)
+{
+	u32 tmp;
+
+	/* framebuffer size */
+        if ((rinfo->family == CHIP_FAMILY_RS100) ||
+            (rinfo->family == CHIP_FAMILY_RS200) ||
+            (rinfo->family == CHIP_FAMILY_RS300)) {
+          u32 tom = INREG(NB_TOM);
+          tmp = ((((tom >> 16) - (tom & 0xffff) + 1) << 6) * 1024);
+
+ 		radeon_fifo_wait(6);
+          OUTREG(MC_FB_LOCATION, tom);
+          OUTREG(DISPLAY_BASE_ADDR, (tom & 0xffff) << 16);
+          OUTREG(CRTC2_DISPLAY_BASE_ADDR, (tom & 0xffff) << 16);
+          OUTREG(OV0_BASE_ADDR, (tom & 0xffff) << 16);
+
+          /* This is supposed to fix the crtc2 noise problem. */
+          OUTREG(GRPH2_BUFFER_CNTL, INREG(GRPH2_BUFFER_CNTL) & ~0x7f0000);
+
+          if ((rinfo->family == CHIP_FAMILY_RS100) ||
+              (rinfo->family == CHIP_FAMILY_RS200)) {
+             /* This is to workaround the asic bug for RMX, some versions
+                of BIOS dosen't have this register initialized correctly.
+             */
+             OUTREGP(CRTC_MORE_CNTL, CRTC_H_CUTOFF_ACTIVE_EN,
+                     ~CRTC_H_CUTOFF_ACTIVE_EN);
+          }
+        } else {
+          tmp = INREG(CONFIG_MEMSIZE);
+        }
+
+	/* mem size is bits [28:0], mask off the rest */
+	rinfo->video_ram = tmp & CONFIG_MEMSIZE_MASK;
+
+	/*
+	 * Hack to get around some busted production M6's
+	 * reporting no ram
+	 */
+	if (rinfo->video_ram == 0) {
+		switch (rinfo->pdev->device) {
+	       	case PCI_CHIP_RADEON_LY:
+		case PCI_CHIP_RADEON_LZ:
+	       		rinfo->video_ram = 8192 * 1024;
+	       		break;
+	       	default:
+	       		break;
+		}
+	}
+
+
+	/*
+	 * Now try to identify VRAM type
+	 */
+	if (rinfo->is_IGP || (rinfo->family >= CHIP_FAMILY_R300) ||
+	    (INREG(MEM_SDRAM_MODE_REG) & (1<<30)))
+		rinfo->vram_ddr = 1;
+	else
+		rinfo->vram_ddr = 0;
+
+	tmp = INREG(MEM_CNTL);
+	if (IS_R300_VARIANT(rinfo)) {
+		tmp &=  R300_MEM_NUM_CHANNELS_MASK;
+		switch (tmp) {
+		case 0:  rinfo->vram_width = 64; break;
+		case 1:  rinfo->vram_width = 128; break;
+		case 2:  rinfo->vram_width = 256; break;
+		default: rinfo->vram_width = 128; break;
+		}
+	} else if ((rinfo->family == CHIP_FAMILY_RV100) ||
+		   (rinfo->family == CHIP_FAMILY_RS100) ||
+		   (rinfo->family == CHIP_FAMILY_RS200)){
+		if (tmp & RV100_MEM_HALF_MODE)
+			rinfo->vram_width = 32;
+		else
+			rinfo->vram_width = 64;
+	} else {
+		if (tmp & MEM_NUM_CHANNELS_MASK)
+			rinfo->vram_width = 128;
+		else
+			rinfo->vram_width = 64;
+	}
+
+	/* This may not be correct, as some cards can have half of channel disabled
+	 * ToDo: identify these cases
+	 */
+
+	RTRACE("radeonfb (%s): Found %ldk of %s %d bits wide videoram\n",
+	       pci_name(rinfo->pdev),
+	       rinfo->video_ram / 1024,
+	       rinfo->vram_ddr ? "DDR" : "SDRAM",
+	       rinfo->vram_width);
+}
+
 /*
  * Sysfs
  */
@@ -2038,7 +2195,6 @@
 {
 	struct fb_info *info;
 	struct radeonfb_info *rinfo;
-	u32 tmp;
 	int ret;
 
 	RTRACE("radeonfb_pci_register BEGIN\n");
@@ -2046,13 +2202,15 @@
 	/* Enable device in PCI config */
 	ret = pci_enable_device(pdev);
 	if (ret < 0) {
-		printk(KERN_ERR "radeonfb: Cannot enable PCI device\n");
+		printk(KERN_ERR "radeonfb (%s): Cannot enable PCI device\n",
+		       pci_name(pdev));
 		goto err_out;
 	}
 
 	info = framebuffer_alloc(sizeof(struct radeonfb_info), &pdev->dev);
 	if (!info) {
-		printk (KERN_ERR "radeonfb: could not allocate memory\n");
+		printk (KERN_ERR "radeonfb (%s): could not allocate memory\n",
+			pci_name(pdev));
 		ret = -ENOMEM;
 		goto err_disable;
 	}
@@ -2081,121 +2239,39 @@
 	/* request the mem regions */
 	ret = pci_request_regions(pdev, "radeonfb");
 	if (ret < 0) {
-		printk( KERN_ERR "radeonfb: cannot reserve PCI regions."
-			"  Someone already got them?\n");
+		printk( KERN_ERR "radeonfb (%s): cannot reserve PCI regions."
+			"  Someone already got them?\n", pci_name(rinfo->pdev));
 		goto err_release_fb;
 	}
 
 	/* map the regions */
 	rinfo->mmio_base = ioremap(rinfo->mmio_base_phys, RADEON_REGSIZE);
 	if (!rinfo->mmio_base) {
-		printk(KERN_ERR "radeonfb: cannot map MMIO\n");
+		printk(KERN_ERR "radeonfb (%s): cannot map MMIO\n", pci_name(rinfo->pdev));
 		ret = -EIO;
 		goto err_release_pci;
 	}
 
+	rinfo->fb_local_base = INREG(MC_FB_LOCATION) << 16;
+
+#ifdef CONFIG_PPC_OF
+	/* On PPC, we obtain the OF device-node pointer to the firmware
+	 * data for this chip
+	 */
+	rinfo->of_node = pci_device_to_OF_node(pdev);
+	if (rinfo->of_node == NULL)
+		printk(KERN_WARNING "radeonfb (%s): Cannot match card to OF node !\n",
+		       pci_name(rinfo->pdev));
+
 	/* On PPC, the firmware sets up a memory mapping that tends
 	 * to cause lockups when enabling the engine. We reconfigure
 	 * the card internal memory mappings properly
 	 */
-#ifdef CONFIG_PPC_OF
 	fixup_memory_mappings(rinfo);
-#else	
-	rinfo->fb_local_base = INREG(MC_FB_LOCATION) << 16;
 #endif /* CONFIG_PPC_OF */
 
-	/* framebuffer size */
-        if ((rinfo->family == CHIP_FAMILY_RS100) ||
-            (rinfo->family == CHIP_FAMILY_RS200) ||
-            (rinfo->family == CHIP_FAMILY_RS300)) {
-          u32 tom = INREG(NB_TOM);
-          tmp = ((((tom >> 16) - (tom & 0xffff) + 1) << 6) * 1024);
- 
- 		radeon_fifo_wait(6);
-          OUTREG(MC_FB_LOCATION, tom);
-          OUTREG(DISPLAY_BASE_ADDR, (tom & 0xffff) << 16);
-          OUTREG(CRTC2_DISPLAY_BASE_ADDR, (tom & 0xffff) << 16);
-          OUTREG(OV0_BASE_ADDR, (tom & 0xffff) << 16);
- 
-          /* This is supposed to fix the crtc2 noise problem. */
-          OUTREG(GRPH2_BUFFER_CNTL, INREG(GRPH2_BUFFER_CNTL) & ~0x7f0000);
- 
-          if ((rinfo->family == CHIP_FAMILY_RS100) ||
-              (rinfo->family == CHIP_FAMILY_RS200)) {
-             /* This is to workaround the asic bug for RMX, some versions
-                of BIOS dosen't have this register initialized correctly.
-             */
-             OUTREGP(CRTC_MORE_CNTL, CRTC_H_CUTOFF_ACTIVE_EN,
-                     ~CRTC_H_CUTOFF_ACTIVE_EN);
-          }
-        } else {
-          tmp = INREG(CONFIG_MEMSIZE);
-        }
-
-	/* mem size is bits [28:0], mask off the rest */
-	rinfo->video_ram = tmp & CONFIG_MEMSIZE_MASK;
-
-	/* ram type */
-	tmp = INREG(MEM_SDRAM_MODE_REG);
-	switch ((MEM_CFG_TYPE & tmp) >> 30) {
-       	case 0:
-       		/* SDR SGRAM (2:1) */
-       		strcpy(rinfo->ram_type, "SDR SGRAM");
-       		rinfo->ram.ml = 4;
-       		rinfo->ram.mb = 4;
-       		rinfo->ram.trcd = 1;
-       		rinfo->ram.trp = 2;
-       		rinfo->ram.twr = 1;
-       		rinfo->ram.cl = 2;
-       		rinfo->ram.loop_latency = 16;
-       		rinfo->ram.rloop = 16;
-       		break;
-       	case 1:
-       		/* DDR SGRAM */
-       		strcpy(rinfo->ram_type, "DDR SGRAM");
-       		rinfo->ram.ml = 4;
-       		rinfo->ram.mb = 4;
-       		rinfo->ram.trcd = 3;
-       		rinfo->ram.trp = 3;
-       		rinfo->ram.twr = 2;
-       		rinfo->ram.cl = 3;
-       		rinfo->ram.tr2w = 1;
-       		rinfo->ram.loop_latency = 16;
-       		rinfo->ram.rloop = 16;
-		break;
-       	default:
-       		/* 64-bit SDR SGRAM */
-       		strcpy(rinfo->ram_type, "SDR SGRAM 64");
-       		rinfo->ram.ml = 4;
-       		rinfo->ram.mb = 8;
-       		rinfo->ram.trcd = 3;
-       		rinfo->ram.trp = 3;
-       		rinfo->ram.twr = 1;
-       		rinfo->ram.cl = 3;
-       		rinfo->ram.tr2w = 1;
-       		rinfo->ram.loop_latency = 17;
-       		rinfo->ram.rloop = 17;
-		break;
-	}
-
-	/*
-	 * Hack to get around some busted production M6's
-	 * reporting no ram
-	 */
-	if (rinfo->video_ram == 0) {
-		switch (pdev->device) {
-	       	case PCI_CHIP_RADEON_LY:
-		case PCI_CHIP_RADEON_LZ:
-	       		rinfo->video_ram = 8192 * 1024;
-	       		break;
-	       	default:
-			printk (KERN_ERR "radeonfb: no video RAM reported\n");
-			ret = -ENXIO;
-			goto err_unmap_rom;
-		}
-	}
-
-	RTRACE("radeonfb: probed %s %ldk videoram\n", (rinfo->ram_type), (rinfo->video_ram/1024));
+	/* Get VRAM size and type */
+	radeon_identify_vram(rinfo);
 
 	rinfo->mapped_vram = min_t(unsigned long, MAX_MAPPED_VRAM, rinfo->video_ram);
 
@@ -2208,12 +2284,13 @@
 	if (rinfo->fb_base)
 		memset_io(rinfo->fb_base, 0, rinfo->mapped_vram);
 	else {
-		printk (KERN_ERR "radeonfb: cannot map FB\n");
+		printk (KERN_ERR "radeonfb (%s): cannot map FB\n", pci_name(rinfo->pdev));
 		ret = -EIO;
 		goto err_unmap_rom;
 	}
 
-	RTRACE("radeonfb: mapped %ldk videoram\n", rinfo->mapped_vram/1024);
+	RTRACE("radeonfb (%s): mapped %ldk videoram\n", pci_name(rinfo->pdev),
+	       rinfo->mapped_vram/1024);
 
 	/*
 	 * Check for required workaround for PLL accesses
@@ -2280,24 +2357,25 @@
 	 * so we can restore this upon __exit
 	 */
 	radeon_save_state (rinfo, &rinfo->init_state);
+	memcpy(&rinfo->state, &rinfo->init_state, sizeof(struct radeon_regs));
 
 	pci_set_drvdata(pdev, info);
 
-	/* Enable PM on mobility chips */
-	if (rinfo->is_mobility) {
-		/* Find PM registers in config space */
-		rinfo->pm_reg = pci_find_capability(pdev, PCI_CAP_ID_PM);
-		/* Enable dynamic PM of chip clocks */
-		radeon_pm_enable_dynamic_mode(rinfo);
-		printk("radeonfb: Power Management enabled for Mobility chipsets\n");
-	}
-
+	/* Register with fbdev layer */
 	ret = register_framebuffer(info);
 	if (ret < 0) {
-		printk (KERN_ERR "radeonfb: could not register framebuffer\n");
+		printk (KERN_ERR "radeonfb (%s): could not register framebuffer\n",
+			pci_name(rinfo->pdev));
 		goto err_unmap_fb;
 	}
 
+	/* Setup Power Management capabilities */
+	if (default_dynclk < -1) {
+		/* -2 is special: means  ON on mobility chips and do not change on others */
+		radeonfb_pm_init(rinfo, rinfo->is_mobility ? 1 : -1);
+	} else
+		radeonfb_pm_init(rinfo, default_dynclk);
+
 #ifdef CONFIG_MTRR
 	rinfo->mtrr_hdl = nomtrr ? -1 : mtrr_add(rinfo->fb_base_phys,
 						 rinfo->video_ram,
@@ -2313,8 +2391,7 @@
 	}
 #endif
 
-	printk ("radeonfb: %s %s %ld MB\n", rinfo->name, rinfo->ram_type,
-		(rinfo->video_ram/(1024*1024)));
+	printk ("radeonfb (%s): %s\n", pci_name(rinfo->pdev), rinfo->name);
 
 	if (rinfo->bios_seg)
 		radeon_unmap_ROM(rinfo, pdev);
@@ -2357,13 +2434,18 @@
         if (!rinfo)
                 return;
  
+	radeonfb_pm_exit(rinfo);
+
+#if 0
 	/* restore original state
 	 * 
-	 * Doesn't quite work yet, possibly because of the PPC hacking
-	 * I do on startup, disable for now. --BenH
+	 * Doesn't quite work yet, I suspect if we come from a legacy
+	 * VGA mode (or worse, text mode), we need to do some VGA black
+	 * magic here that I know nothing about. --BenH
 	 */
-        radeon_write_mode (rinfo, &rinfo->init_state);
- 
+        radeon_write_mode (rinfo, &rinfo->init_state, 1);
+ #endif
+
 	del_timer_sync(&rinfo->lvds_timer);
 
 #ifdef CONFIG_MTRR
@@ -2469,6 +2551,8 @@
 MODULE_DESCRIPTION("framebuffer driver for ATI Radeon chipset");
 MODULE_LICENSE("GPL");
 module_param(noaccel, bool, 0);
+module_param(default_dynclk, int, 0);
+MODULE_PARM_DESC(default_dynclk, "int: -2=enable on mobility only,-1=do not change,0=off,1=on");
 MODULE_PARM_DESC(noaccel, "bool: disable acceleration");
 module_param(nomodeset, bool, 0);
 MODULE_PARM_DESC(nomodeset, "bool: disable actual setting of video mode");
diff -Nru a/drivers/video/aty/radeon_monitor.c b/drivers/video/aty/radeon_monitor.c
--- a/drivers/video/aty/radeon_monitor.c	2005-03-01 23:38:43 -08:00
+++ b/drivers/video/aty/radeon_monitor.c	2005-03-01 23:38:43 -08:00
@@ -1,11 +1,6 @@
 #include "radeonfb.h"
 #include "../edid.h"
 
-#ifdef CONFIG_PPC_OF
-#include <asm/prom.h>
-#include <asm/pci-bridge.h>
-#endif /* CONFIG_PPC_OF */
-
 static struct fb_var_screeninfo radeonfb_default_var = {
 	.xres		= 640,
 	.yres		= 480,
@@ -64,9 +59,11 @@
  * models with broken OF probing by hard-coding known EDIDs for some Mac
  * laptops internal LVDS panel. (XXX: not done yet)
  */
-static int __devinit radeon_parse_montype_prop(struct device_node *dp, u8 **out_EDID, int hdno)
+static int __devinit radeon_parse_montype_prop(struct device_node *dp, u8 **out_EDID,
+					       int hdno)
 {
-        static char *propnames[] = { "DFP,EDID", "LCD,EDID", "EDID", "EDID1", "EDID2",  NULL };
+        static char *propnames[] = { "DFP,EDID", "LCD,EDID", "EDID",
+				     "EDID1", "EDID2",  NULL };
 	u8 *pedid = NULL;
 	u8 *pmt = NULL;
 	u8 *tmp;
@@ -122,7 +119,7 @@
 
 	RTRACE("radeon_probe_OF_head\n");
 
-        dp = pci_device_to_OF_node(rinfo->pdev);
+        dp = rinfo->of_node;
         while (dp == NULL)
 		return MT_NONE;
 
@@ -502,8 +499,9 @@
 #endif /* CONFIG_PPC_OF */
 #ifdef CONFIG_FB_RADEON_I2C
 			if (rinfo->mon1_type == MT_NONE)
-				rinfo->mon1_type = radeon_probe_i2c_connector(rinfo, ddc_dvi,
-								      &rinfo->mon1_EDID);
+				rinfo->mon1_type =
+					radeon_probe_i2c_connector(rinfo, ddc_dvi,
+								   &rinfo->mon1_EDID);
 			if (rinfo->mon1_type == MT_NONE)
 				rinfo->mon1_type =
 					radeon_probe_i2c_connector(rinfo, ddc_vga,
@@ -545,7 +543,8 @@
 		 */
 #ifdef CONFIG_PPC_OF
 		if (rinfo->mon1_type == MT_NONE)
-			rinfo->mon1_type = radeon_probe_OF_head(rinfo, 0, &rinfo->mon1_EDID);
+			rinfo->mon1_type = radeon_probe_OF_head(rinfo, 0,
+								&rinfo->mon1_EDID);
 #endif /* CONFIG_PPC_OF */
 #ifdef CONFIG_FB_RADEON_I2C
 		if (rinfo->mon1_type == MT_NONE)
@@ -572,7 +571,8 @@
 		 */
 #ifdef CONFIG_PPC_OF
 		if (rinfo->mon2_type == MT_NONE)
-			rinfo->mon2_type = radeon_probe_OF_head(rinfo, 1, &rinfo->mon2_EDID);
+			rinfo->mon2_type = radeon_probe_OF_head(rinfo, 1,
+								&rinfo->mon2_EDID);
 #endif /* CONFIG_PPC_OF */
 #ifdef CONFIG_FB_RADEON_I2C
 		if (rinfo->mon2_type == MT_NONE)
@@ -648,10 +648,10 @@
  */
 static void radeon_fixup_panel_info(struct radeonfb_info *rinfo)
 {
- #ifdef CONFIG_PPC_OF
+#ifdef CONFIG_PPC_OF
 	/*
 	 * LCD Flat panels should use fixed dividers, we enfore that on
-	 * PowerMac only for now...
+	 * PPC only for now...
 	 */
 	if (!rinfo->panel_info.use_bios_dividers && rinfo->mon1_type == MT_LCD
 	    && rinfo->is_mobility) {
@@ -702,40 +702,24 @@
 	rinfo->panel_info.pwr_delay = 200;
 }
 
-static void radeon_var_to_videomode(struct fb_videomode *mode,
-				    const struct fb_var_screeninfo *var)
-{
-    mode->xres = var->xres;
-    mode->yres = var->yres;
-    mode->pixclock = var->pixclock;
-    mode->left_margin = var->left_margin;
-    mode->right_margin = var->right_margin;
-    mode->upper_margin = var->upper_margin;
-    mode->lower_margin = var->lower_margin;
-    mode->hsync_len = var->hsync_len;
-    mode->vsync_len = var->vsync_len;
-    mode->sync = var->sync;
-    mode->vmode = var->vmode;
-}
-
 static void radeon_videomode_to_var(struct fb_var_screeninfo *var,
 				    const struct fb_videomode *mode)
 {
-    var->xres = mode->xres;
-    var->yres = mode->yres;
-    var->xres_virtual = mode->xres;
-    var->yres_virtual = mode->yres;
-    var->xoffset = 0;
-    var->yoffset = 0;
-    var->pixclock = mode->pixclock;
-    var->left_margin = mode->left_margin;
-    var->right_margin = mode->right_margin;
-    var->upper_margin = mode->upper_margin;
-    var->lower_margin = mode->lower_margin;
-    var->hsync_len = mode->hsync_len;
-    var->vsync_len = mode->vsync_len;
-    var->sync = mode->sync;
-    var->vmode = mode->vmode;
+	var->xres = mode->xres;
+	var->yres = mode->yres;
+	var->xres_virtual = mode->xres;
+	var->yres_virtual = mode->yres;
+	var->xoffset = 0;
+	var->yoffset = 0;
+	var->pixclock = mode->pixclock;
+	var->left_margin = mode->left_margin;
+	var->right_margin = mode->right_margin;
+	var->upper_margin = mode->upper_margin;
+	var->lower_margin = mode->lower_margin;
+	var->hsync_len = mode->hsync_len;
+	var->vsync_len = mode->vsync_len;
+	var->sync = mode->sync;
+	var->vmode = mode->vmode;
 }
 
 /*
@@ -744,12 +728,14 @@
  */
 void __devinit radeon_check_modes(struct radeonfb_info *rinfo, const char *mode_option)
 {
+	struct fb_info * info = rinfo->info;
 	int has_default_mode = 0;
 
 	/*
 	 * Fill default var first
 	 */
-	rinfo->info->var = radeonfb_default_var;
+	info->var = radeonfb_default_var;
+	INIT_LIST_HEAD(&info->modelist);
 
 	/*
 	 * First check out what BIOS has to say
@@ -783,7 +769,7 @@
 	 * those
 	 */
 	if (rinfo->mon1_type != MT_CRT && rinfo->panel_info.valid) {
-		struct fb_var_screeninfo *var = &rinfo->info->var;
+		struct fb_var_screeninfo *var = &info->var;
 
 		RTRACE("Setting up default mode based on panel info\n");
 		var->xres = rinfo->panel_info.xres;
@@ -814,9 +800,12 @@
 	 * Now build modedb from EDID
 	 */
 	if (rinfo->mon1_EDID) {
-		rinfo->mon1_modedb = fb_create_modedb(rinfo->mon1_EDID,
-						      &rinfo->mon1_dbsize);
-		fb_get_monitor_limits(rinfo->mon1_EDID, &rinfo->info->monspecs);
+		fb_edid_to_monspecs(rinfo->mon1_EDID, &info->monspecs);
+		fb_videomode_to_modelist(info->monspecs.modedb,
+					 info->monspecs.modedb_len,
+					 &info->modelist);
+		rinfo->mon1_modedb = info->monspecs.modedb;
+		rinfo->mon1_dbsize = info->monspecs.modedb_len;
 	}
 
 	
@@ -847,31 +836,62 @@
 		modedb = rinfo->mon1_modedb;
 		dbsize = rinfo->mon1_dbsize;
 		snprintf(modename, 31, "%dx%d", rinfo->panel_info.xres, rinfo->panel_info.yres);
-		if (fb_find_mode(&rinfo->info->var, rinfo->info, modename,
+		if (fb_find_mode(&info->var, info, modename,
 				 modedb, dbsize, NULL, 8) == 0) {
 			printk(KERN_WARNING "radeonfb: Can't find mode for panel size, going back to CRT\n");
 			rinfo->mon1_type = MT_CRT;
 			goto pickup_default;
 		}
 		has_default_mode = 1;
-		radeon_var_to_panel_info(rinfo, &rinfo->info->var);
+		radeon_var_to_panel_info(rinfo, &info->var);
 	}
 
  pickup_default:
 	/*
-	 * Pick up a random default mode
+	 * Apply passed-in mode option if any
 	 */
-	if (!has_default_mode || mode_option) {
-		struct fb_videomode default_mode;
-		if (has_default_mode)
-			radeon_var_to_videomode(&default_mode, &rinfo->info->var);
-		else
-			radeon_var_to_videomode(&default_mode, &radeonfb_default_var);
-		if (fb_find_mode(&rinfo->info->var, rinfo->info, mode_option,
-				 rinfo->mon1_modedb, rinfo->mon1_dbsize, &default_mode, 8) == 0)
-			rinfo->info->var = radeonfb_default_var;
-	}
+	if (mode_option) {
+		if (fb_find_mode(&info->var, info, mode_option,
+				 info->monspecs.modedb,
+				 info->monspecs.modedb_len, NULL, 8) != 0)
+			has_default_mode = 1;
+ 	}
 
+	/*
+	 * Still no mode, let's pick up a default from the db
+	 */
+	if (!has_default_mode && info->monspecs.modedb != NULL) {
+		struct fb_monspecs *specs = &info->monspecs;
+		struct fb_videomode *modedb = NULL;
+
+		/* get preferred timing */
+		if (specs->misc & FB_MISC_1ST_DETAIL) {
+			int i;
+
+			for (i = 0; i < specs->modedb_len; i++) {
+				if (specs->modedb[i].flag & FB_MODE_IS_FIRST) {
+					modedb = &specs->modedb[i];
+					break;
+				}
+			}
+		} else {
+			/* otherwise, get first mode in database */
+			modedb = &specs->modedb[0];
+		}
+		if (modedb != NULL) {
+			info->var.bits_per_pixel = 8;
+			radeon_videomode_to_var(&info->var, modedb);
+			has_default_mode = 1;
+		}
+	}
+	if (1) {
+		struct fb_videomode mode;
+		/* Make sure that whatever mode got selected is actually in the
+		 * modelist or the kernel may die
+		 */
+		fb_var_to_videomode(&mode, &info->var);
+		fb_add_videomode(&mode, &info->modelist);
+	}
 }
 
 /*
diff -Nru a/drivers/video/aty/radeon_pm.c b/drivers/video/aty/radeon_pm.c
--- a/drivers/video/aty/radeon_pm.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/video/aty/radeon_pm.c	2005-03-01 23:39:07 -08:00
@@ -1,207 +1,449 @@
+/*
+ *	drivers/video/aty/radeon_pm.c
+ *
+ *	Copyright 2003,2004 Ben. Herrenschmidt <benh@kernel.crashing.org>
+ *	Copyright 2004 Paul Mackerras <paulus@samba.org>
+ *
+ *	This is the power management code for ATI radeon chipsets. It contains
+ *	some dynamic clock PM enable/disable code similar to what X.org does,
+ *	some D2-state (APM-style) sleep/wakeup code for use on some PowerMacs,
+ *	and the necessary bits to re-initialize from scratch a few chips found
+ *	on PowerMacs as well. The later could be extended to more platforms
+ *	provided the memory controller configuration code be made more generic,
+ *	and you can get the proper mode register commands for your RAMs.
+ *	Those things may be found in the BIOS image...
+ */
+
 #include "radeonfb.h"
 
 #include <linux/console.h>
 #include <linux/agp_backend.h>
 
-/*
- * Currently, only PowerMac do D2 state
- */
-#define CONFIG_RADEON_HAS_D2	CONFIG_PPC_PMAC
-
-#ifdef CONFIG_RADEON_HAS_D2
-/*
- * On PowerMac, we assume any mobility chip based machine does D2
- */
 #ifdef CONFIG_PPC_PMAC
-static inline int radeon_suspend_to_d2(struct radeonfb_info *rinfo, u32 state)
-{
-	return rinfo->is_mobility;
-}
-#else
-static inline int radeon_suspend_to_d2(struct radeonfb_info *rinfo, u32 state)
-{
-	return 0;
-}
+#include <asm/processor.h>
+#include <asm/prom.h>
+#include <asm/pmac_feature.h>
 #endif
 
-#endif /* CONFIG_RADEON_HAS_D2 */
-
-/*
- * Radeon M6, M7 and M9 Power Management code. This code currently
- * only supports the mobile chips in D2 mode, that is typically what
- * is used on Apple laptops, it's based from some informations provided
- * by ATI along with hours of tracing of MacOS drivers.
- * 
- * New version of this code almost totally rewritten by ATI, many thanks
- * for their support.
- */
+#include "ati_ids.h"
 
 void radeon_pm_disable_dynamic_mode(struct radeonfb_info *rinfo)
 {
+	u32 tmp;
 
-	u32 sclk_cntl;
-	u32 mclk_cntl;
-	u32 sclk_more_cntl;
-	
-	u32 vclk_ecp_cntl;
-	u32 pixclks_cntl;
-
-	/* Mobility chips only, untested on M9+/M10/11 */
-	if (!rinfo->is_mobility)
+	/* RV100 */
+	if ((rinfo->family == CHIP_FAMILY_RV100) && (!rinfo->is_mobility)) {
+		if (rinfo->has_CRTC2) {
+			tmp = INPLL(pllSCLK_CNTL);
+			tmp &= ~SCLK_CNTL__DYN_STOP_LAT_MASK;
+			tmp |= SCLK_CNTL__CP_MAX_DYN_STOP_LAT | SCLK_CNTL__FORCEON_MASK;
+			OUTPLL(pllSCLK_CNTL, tmp);
+		}
+		tmp = INPLL(pllMCLK_CNTL);
+		tmp |= (MCLK_CNTL__FORCE_MCLKA |
+		        MCLK_CNTL__FORCE_MCLKB |
+		        MCLK_CNTL__FORCE_YCLKA |
+		        MCLK_CNTL__FORCE_YCLKB |
+			MCLK_CNTL__FORCE_AIC |
+			MCLK_CNTL__FORCE_MC);
+                OUTPLL(pllMCLK_CNTL, tmp);
+		return;
+	}
+	/* R100 */
+	if (!rinfo->has_CRTC2) {
+                tmp = INPLL(pllSCLK_CNTL);
+                tmp |= (SCLK_CNTL__FORCE_CP	| SCLK_CNTL__FORCE_HDP	|
+			SCLK_CNTL__FORCE_DISP1	| SCLK_CNTL__FORCE_TOP	|
+                        SCLK_CNTL__FORCE_E2	| SCLK_CNTL__FORCE_SE 	|
+			SCLK_CNTL__FORCE_IDCT	| SCLK_CNTL__FORCE_VIP	|
+			SCLK_CNTL__FORCE_RE	| SCLK_CNTL__FORCE_PB 	|
+			SCLK_CNTL__FORCE_TAM	| SCLK_CNTL__FORCE_TDM	|
+                        SCLK_CNTL__FORCE_RB);
+                OUTPLL(pllSCLK_CNTL, tmp);
 		return;
-	if (rinfo->family > CHIP_FAMILY_RV250)
+	}
+	/* RV350 (M10) */
+	if (rinfo->family == CHIP_FAMILY_RV350) {
+                /* for RV350/M10, no delays are required. */
+                tmp = INPLL(pllSCLK_CNTL2);
+                tmp |= (SCLK_CNTL2__R300_FORCE_TCL |
+                        SCLK_CNTL2__R300_FORCE_GA  |
+			SCLK_CNTL2__R300_FORCE_CBA);
+                OUTPLL(pllSCLK_CNTL2, tmp);
+
+                tmp = INPLL(pllSCLK_CNTL);
+                tmp |= (SCLK_CNTL__FORCE_DISP2		| SCLK_CNTL__FORCE_CP		|
+                        SCLK_CNTL__FORCE_HDP		| SCLK_CNTL__FORCE_DISP1	|
+                        SCLK_CNTL__FORCE_TOP		| SCLK_CNTL__FORCE_E2		|
+                        SCLK_CNTL__R300_FORCE_VAP	| SCLK_CNTL__FORCE_IDCT    	|
+			SCLK_CNTL__FORCE_VIP		| SCLK_CNTL__R300_FORCE_SR	|
+			SCLK_CNTL__R300_FORCE_PX	| SCLK_CNTL__R300_FORCE_TX	|
+			SCLK_CNTL__R300_FORCE_US	| SCLK_CNTL__FORCE_TV_SCLK	|
+                        SCLK_CNTL__R300_FORCE_SU	| SCLK_CNTL__FORCE_OV0);
+                OUTPLL(pllSCLK_CNTL, tmp);
+
+                tmp = INPLL(pllSCLK_MORE_CNTL);
+		tmp |= (SCLK_MORE_CNTL__FORCE_DISPREGS	| SCLK_MORE_CNTL__FORCE_MC_GUI	|
+			SCLK_MORE_CNTL__FORCE_MC_HOST);
+                OUTPLL(pllSCLK_MORE_CNTL, tmp);
+
+		tmp = INPLL(pllMCLK_CNTL);
+		tmp |= (MCLK_CNTL__FORCE_MCLKA |
+		        MCLK_CNTL__FORCE_MCLKB |
+		        MCLK_CNTL__FORCE_YCLKA |
+		        MCLK_CNTL__FORCE_YCLKB |
+			MCLK_CNTL__FORCE_MC);
+                OUTPLL(pllMCLK_CNTL, tmp);
+
+                tmp = INPLL(pllVCLK_ECP_CNTL);
+                tmp &= ~(VCLK_ECP_CNTL__PIXCLK_ALWAYS_ONb  |
+                         VCLK_ECP_CNTL__PIXCLK_DAC_ALWAYS_ONb |
+			 VCLK_ECP_CNTL__R300_DISP_DAC_PIXCLK_DAC_BLANK_OFF);
+                OUTPLL(pllVCLK_ECP_CNTL, tmp);
+
+                tmp = INPLL(pllPIXCLKS_CNTL);
+                tmp &= ~(PIXCLKS_CNTL__PIX2CLK_ALWAYS_ONb		|
+			 PIXCLKS_CNTL__PIX2CLK_DAC_ALWAYS_ONb		|
+			 PIXCLKS_CNTL__DISP_TVOUT_PIXCLK_TV_ALWAYS_ONb	|
+			 PIXCLKS_CNTL__R300_DVOCLK_ALWAYS_ONb		|
+			 PIXCLKS_CNTL__PIXCLK_BLEND_ALWAYS_ONb		|
+			 PIXCLKS_CNTL__PIXCLK_GV_ALWAYS_ONb		|
+			 PIXCLKS_CNTL__R300_PIXCLK_DVO_ALWAYS_ONb	|
+			 PIXCLKS_CNTL__PIXCLK_LVDS_ALWAYS_ONb		|
+			 PIXCLKS_CNTL__PIXCLK_TMDS_ALWAYS_ONb		|
+			 PIXCLKS_CNTL__R300_PIXCLK_TRANS_ALWAYS_ONb	|
+			 PIXCLKS_CNTL__R300_PIXCLK_TVO_ALWAYS_ONb	|
+			 PIXCLKS_CNTL__R300_P2G2CLK_ALWAYS_ONb		|
+			 PIXCLKS_CNTL__R300_P2G2CLK_ALWAYS_ONb		|
+			 PIXCLKS_CNTL__R300_DISP_DAC_PIXCLK_DAC2_BLANK_OFF);
+                OUTPLL(pllPIXCLKS_CNTL, tmp);
+
 		return;
+	}
 	
+	/* Default */
+
 	/* Force Core Clocks */
-	sclk_cntl = INPLL( pllSCLK_CNTL_M6);
-	sclk_cntl |= 	SCLK_CNTL_M6__FORCE_CP|
-			SCLK_CNTL_M6__FORCE_HDP|
-			SCLK_CNTL_M6__FORCE_DISP1|
-			SCLK_CNTL_M6__FORCE_DISP2|
-			SCLK_CNTL_M6__FORCE_TOP|
-			SCLK_CNTL_M6__FORCE_E2|
-			SCLK_CNTL_M6__FORCE_SE|
-			SCLK_CNTL_M6__FORCE_IDCT|
-			SCLK_CNTL_M6__FORCE_VIP|
-			SCLK_CNTL_M6__FORCE_RE|
-			SCLK_CNTL_M6__FORCE_PB|
-			SCLK_CNTL_M6__FORCE_TAM|
-			SCLK_CNTL_M6__FORCE_TDM|
-			SCLK_CNTL_M6__FORCE_RB|
-			SCLK_CNTL_M6__FORCE_TV_SCLK|
-			SCLK_CNTL_M6__FORCE_SUBPIC|
-			SCLK_CNTL_M6__FORCE_OV0;
-    	OUTPLL( pllSCLK_CNTL_M6, sclk_cntl);
-	
-	
-	
-	sclk_more_cntl = INPLL(pllSCLK_MORE_CNTL);
-	sclk_more_cntl |= 	SCLK_MORE_CNTL__FORCE_DISPREGS|
-				SCLK_MORE_CNTL__FORCE_MC_GUI|
-				SCLK_MORE_CNTL__FORCE_MC_HOST;	
-	OUTPLL(pllSCLK_MORE_CNTL, sclk_more_cntl);
-	
-	/* Force Display clocks	*/
-	vclk_ecp_cntl = INPLL( pllVCLK_ECP_CNTL);
-	vclk_ecp_cntl &= ~(	VCLK_ECP_CNTL__PIXCLK_ALWAYS_ONb |
-			 	VCLK_ECP_CNTL__PIXCLK_DAC_ALWAYS_ONb);
+	tmp = INPLL(pllSCLK_CNTL);
+	tmp |= (SCLK_CNTL__FORCE_CP | SCLK_CNTL__FORCE_E2);
 
-	OUTPLL( pllVCLK_ECP_CNTL, vclk_ecp_cntl);
-	
-	pixclks_cntl = INPLL( pllPIXCLKS_CNTL);
-	pixclks_cntl &= ~(	PIXCLKS_CNTL__PIXCLK_GV_ALWAYS_ONb |
-			 	PIXCLKS_CNTL__PIXCLK_BLEND_ALWAYS_ONb|
-				PIXCLKS_CNTL__PIXCLK_DIG_TMDS_ALWAYS_ONb |
-				PIXCLKS_CNTL__PIXCLK_LVDS_ALWAYS_ONb|
-				PIXCLKS_CNTL__PIXCLK_TMDS_ALWAYS_ONb|
-				PIXCLKS_CNTL__PIX2CLK_ALWAYS_ONb|
-				PIXCLKS_CNTL__PIX2CLK_DAC_ALWAYS_ONb);
-						
- 	OUTPLL( pllPIXCLKS_CNTL, pixclks_cntl);
+	/* XFree doesn't do that case, but we had this code from Apple and it
+	 * seem necessary for proper suspend/resume operations
+	 */
+	if (rinfo->is_mobility) {
+		tmp |= 	SCLK_CNTL__FORCE_HDP|
+			SCLK_CNTL__FORCE_DISP1|
+			SCLK_CNTL__FORCE_DISP2|
+			SCLK_CNTL__FORCE_TOP|
+			SCLK_CNTL__FORCE_SE|
+			SCLK_CNTL__FORCE_IDCT|
+			SCLK_CNTL__FORCE_VIP|
+			SCLK_CNTL__FORCE_PB|
+			SCLK_CNTL__FORCE_RE|
+			SCLK_CNTL__FORCE_TAM|
+			SCLK_CNTL__FORCE_TDM|
+			SCLK_CNTL__FORCE_RB|
+			SCLK_CNTL__FORCE_TV_SCLK|
+			SCLK_CNTL__FORCE_SUBPIC|
+			SCLK_CNTL__FORCE_OV0;
+	}
+	else if (rinfo->family == CHIP_FAMILY_R300 ||
+		   rinfo->family == CHIP_FAMILY_R350) {
+		tmp |=  SCLK_CNTL__FORCE_HDP   |
+			SCLK_CNTL__FORCE_DISP1 |
+			SCLK_CNTL__FORCE_DISP2 |
+			SCLK_CNTL__FORCE_TOP   |
+			SCLK_CNTL__FORCE_IDCT  |
+			SCLK_CNTL__FORCE_VIP;
+	}
+    	OUTPLL(pllSCLK_CNTL, tmp);
+	radeon_msleep(16);
+
+	if (rinfo->family == CHIP_FAMILY_R300 || rinfo->family == CHIP_FAMILY_R350) {
+		tmp = INPLL(pllSCLK_CNTL2);
+		tmp |=  SCLK_CNTL2__R300_FORCE_TCL |
+			SCLK_CNTL2__R300_FORCE_GA  |
+			SCLK_CNTL2__R300_FORCE_CBA;
+		OUTPLL(pllSCLK_CNTL2, tmp);
+		radeon_msleep(16);
+	}
+
+	tmp = INPLL(pllCLK_PIN_CNTL);
+	tmp &= ~CLK_PIN_CNTL__SCLK_DYN_START_CNTL;
+	OUTPLL(pllCLK_PIN_CNTL, tmp);
+	radeon_msleep(15);
+
+	if (rinfo->is_IGP) {
+		/* Weird  ... X is _un_ forcing clocks here, I think it's
+		 * doing backward. Imitate it for now...
+		 */
+		tmp = INPLL(pllMCLK_CNTL);
+		tmp &= ~(MCLK_CNTL__FORCE_MCLKA |
+			 MCLK_CNTL__FORCE_YCLKA);
+		OUTPLL(pllMCLK_CNTL, tmp);
+		radeon_msleep(16);
+	}
+	/* Hrm... same shit, X doesn't do that but I have to */
+	else if (rinfo->is_mobility) {
+		tmp = INPLL(pllMCLK_CNTL);
+		tmp |= (MCLK_CNTL__FORCE_MCLKA |
+			MCLK_CNTL__FORCE_MCLKB |
+			MCLK_CNTL__FORCE_YCLKA |
+			MCLK_CNTL__FORCE_YCLKB);
+		OUTPLL(pllMCLK_CNTL, tmp);
+		radeon_msleep(16);
+
+		tmp = INPLL(pllMCLK_MISC);
+		tmp &= 	~(MCLK_MISC__MC_MCLK_MAX_DYN_STOP_LAT|
+			  MCLK_MISC__IO_MCLK_MAX_DYN_STOP_LAT|
+			  MCLK_MISC__MC_MCLK_DYN_ENABLE|
+			  MCLK_MISC__IO_MCLK_DYN_ENABLE);
+		OUTPLL(pllMCLK_MISC, tmp);
+		radeon_msleep(15);
+	}
+
+	if (rinfo->is_mobility) {
+		tmp = INPLL(pllSCLK_MORE_CNTL);
+		tmp |= 	SCLK_MORE_CNTL__FORCE_DISPREGS|
+			SCLK_MORE_CNTL__FORCE_MC_GUI|
+			SCLK_MORE_CNTL__FORCE_MC_HOST;
+		OUTPLL(pllSCLK_MORE_CNTL, tmp);
+		radeon_msleep(16);
+	}
 
-	/* Force Memory Clocks */
-	mclk_cntl = INPLL( pllMCLK_CNTL_M6);
-	mclk_cntl &= ~(	MCLK_CNTL_M6__FORCE_MCLKA |  
-			MCLK_CNTL_M6__FORCE_MCLKB |
-			MCLK_CNTL_M6__FORCE_YCLKA |
-			MCLK_CNTL_M6__FORCE_YCLKB );
-    	OUTPLL( pllMCLK_CNTL_M6, mclk_cntl);
+	tmp = INPLL(pllPIXCLKS_CNTL);
+	tmp &= ~(PIXCLKS_CNTL__PIXCLK_GV_ALWAYS_ONb |
+		 PIXCLKS_CNTL__PIXCLK_BLEND_ALWAYS_ONb|
+		 PIXCLKS_CNTL__PIXCLK_DIG_TMDS_ALWAYS_ONb |
+		 PIXCLKS_CNTL__PIXCLK_LVDS_ALWAYS_ONb|
+		 PIXCLKS_CNTL__PIXCLK_TMDS_ALWAYS_ONb|
+		 PIXCLKS_CNTL__PIX2CLK_ALWAYS_ONb|
+		 PIXCLKS_CNTL__PIX2CLK_DAC_ALWAYS_ONb);
+ 	OUTPLL(pllPIXCLKS_CNTL, tmp);
+	radeon_msleep(16);
+
+	tmp = INPLL( pllVCLK_ECP_CNTL);
+	tmp &= ~(VCLK_ECP_CNTL__PIXCLK_ALWAYS_ONb |
+		 VCLK_ECP_CNTL__PIXCLK_DAC_ALWAYS_ONb);
+	OUTPLL( pllVCLK_ECP_CNTL, tmp);
+	radeon_msleep(16);
 }
 
 void radeon_pm_enable_dynamic_mode(struct radeonfb_info *rinfo)
 {
-	u32 clk_pwrmgt_cntl;
-	u32 sclk_cntl;
-	u32 sclk_more_cntl;
-	u32 clk_pin_cntl;
-	u32 pixclks_cntl;
-	u32 vclk_ecp_cntl;
-	u32 mclk_cntl;
-	u32 mclk_misc;
+	u32 tmp;
 
-	/* Mobility chips only, untested on M9+/M10/11 */
-	if (!rinfo->is_mobility)
-		return;
-	if (rinfo->family > CHIP_FAMILY_RV250)
+	/* R100 */
+	if (!rinfo->has_CRTC2) {
+                tmp = INPLL(pllSCLK_CNTL);
+
+		if ((INREG(CONFIG_CNTL) & CFG_ATI_REV_ID_MASK) > CFG_ATI_REV_A13)
+                    tmp &= ~(SCLK_CNTL__FORCE_CP	| SCLK_CNTL__FORCE_RB);
+                tmp &= ~(SCLK_CNTL__FORCE_HDP		| SCLK_CNTL__FORCE_DISP1 |
+			 SCLK_CNTL__FORCE_TOP		| SCLK_CNTL__FORCE_SE   |
+			 SCLK_CNTL__FORCE_IDCT		| SCLK_CNTL__FORCE_RE   |
+			 SCLK_CNTL__FORCE_PB		| SCLK_CNTL__FORCE_TAM  |
+			 SCLK_CNTL__FORCE_TDM);
+                OUTPLL(pllSCLK_CNTL, tmp);
 		return;
-	
-	/* Set Latencies */
-	clk_pwrmgt_cntl = INPLL( pllCLK_PWRMGT_CNTL_M6);
-	
-	clk_pwrmgt_cntl &= ~(	 CLK_PWRMGT_CNTL_M6__ENGINE_DYNCLK_MODE_MASK|
-				 CLK_PWRMGT_CNTL_M6__ACTIVE_HILO_LAT_MASK|
-				 CLK_PWRMGT_CNTL_M6__DISP_DYN_STOP_LAT_MASK|
-				 CLK_PWRMGT_CNTL_M6__DYN_STOP_MODE_MASK);
-	/* Mode 1 */
-	clk_pwrmgt_cntl = 	CLK_PWRMGT_CNTL_M6__MC_CH_MODE|
-				CLK_PWRMGT_CNTL_M6__ENGINE_DYNCLK_MODE | 
-				(1<<CLK_PWRMGT_CNTL_M6__ACTIVE_HILO_LAT__SHIFT) |
-				(0<<CLK_PWRMGT_CNTL_M6__DISP_DYN_STOP_LAT__SHIFT)|
-				(0<<CLK_PWRMGT_CNTL_M6__DYN_STOP_MODE__SHIFT);
+	}
 
-	OUTPLL( pllCLK_PWRMGT_CNTL_M6, clk_pwrmgt_cntl);
-						
+	/* M10 */
+	if (rinfo->family == CHIP_FAMILY_RV350) {
+		tmp = INPLL(pllSCLK_CNTL2);
+		tmp &= ~(SCLK_CNTL2__R300_FORCE_TCL |
+			 SCLK_CNTL2__R300_FORCE_GA  |
+			 SCLK_CNTL2__R300_FORCE_CBA);
+		tmp |=  (SCLK_CNTL2__R300_TCL_MAX_DYN_STOP_LAT |
+			 SCLK_CNTL2__R300_GA_MAX_DYN_STOP_LAT  |
+			 SCLK_CNTL2__R300_CBA_MAX_DYN_STOP_LAT);
+		OUTPLL(pllSCLK_CNTL2, tmp);
+
+		tmp = INPLL(pllSCLK_CNTL);
+		tmp &= ~(SCLK_CNTL__FORCE_DISP2 | SCLK_CNTL__FORCE_CP      |
+			 SCLK_CNTL__FORCE_HDP   | SCLK_CNTL__FORCE_DISP1   |
+			 SCLK_CNTL__FORCE_TOP   | SCLK_CNTL__FORCE_E2      |
+			 SCLK_CNTL__R300_FORCE_VAP | SCLK_CNTL__FORCE_IDCT |
+			 SCLK_CNTL__FORCE_VIP   | SCLK_CNTL__R300_FORCE_SR |
+			 SCLK_CNTL__R300_FORCE_PX | SCLK_CNTL__R300_FORCE_TX |
+			 SCLK_CNTL__R300_FORCE_US | SCLK_CNTL__FORCE_TV_SCLK |
+			 SCLK_CNTL__R300_FORCE_SU | SCLK_CNTL__FORCE_OV0);
+		tmp |= SCLK_CNTL__DYN_STOP_LAT_MASK;
+		OUTPLL(pllSCLK_CNTL, tmp);
+
+		tmp = INPLL(pllSCLK_MORE_CNTL);
+		tmp &= ~SCLK_MORE_CNTL__FORCEON;
+		tmp |=  SCLK_MORE_CNTL__DISPREGS_MAX_DYN_STOP_LAT |
+			SCLK_MORE_CNTL__MC_GUI_MAX_DYN_STOP_LAT |
+			SCLK_MORE_CNTL__MC_HOST_MAX_DYN_STOP_LAT;
+		OUTPLL(pllSCLK_MORE_CNTL, tmp);
+
+		tmp = INPLL(pllVCLK_ECP_CNTL);
+		tmp |= (VCLK_ECP_CNTL__PIXCLK_ALWAYS_ONb |
+			VCLK_ECP_CNTL__PIXCLK_DAC_ALWAYS_ONb);
+		OUTPLL(pllVCLK_ECP_CNTL, tmp);
+
+		tmp = INPLL(pllPIXCLKS_CNTL);
+		tmp |= (PIXCLKS_CNTL__PIX2CLK_ALWAYS_ONb         |
+			PIXCLKS_CNTL__PIX2CLK_DAC_ALWAYS_ONb     |
+			PIXCLKS_CNTL__DISP_TVOUT_PIXCLK_TV_ALWAYS_ONb |
+			PIXCLKS_CNTL__R300_DVOCLK_ALWAYS_ONb            |
+			PIXCLKS_CNTL__PIXCLK_BLEND_ALWAYS_ONb    |
+			PIXCLKS_CNTL__PIXCLK_GV_ALWAYS_ONb       |
+			PIXCLKS_CNTL__R300_PIXCLK_DVO_ALWAYS_ONb        |
+			PIXCLKS_CNTL__PIXCLK_LVDS_ALWAYS_ONb     |
+			PIXCLKS_CNTL__PIXCLK_TMDS_ALWAYS_ONb     |
+			PIXCLKS_CNTL__R300_PIXCLK_TRANS_ALWAYS_ONb      |
+			PIXCLKS_CNTL__R300_PIXCLK_TVO_ALWAYS_ONb        |
+			PIXCLKS_CNTL__R300_P2G2CLK_ALWAYS_ONb           |
+			PIXCLKS_CNTL__R300_P2G2CLK_ALWAYS_ONb);
+		OUTPLL(pllPIXCLKS_CNTL, tmp);
+
+		tmp = INPLL(pllMCLK_MISC);
+		tmp |= (MCLK_MISC__MC_MCLK_DYN_ENABLE |
+			MCLK_MISC__IO_MCLK_DYN_ENABLE);
+		OUTPLL(pllMCLK_MISC, tmp);
+
+		tmp = INPLL(pllMCLK_CNTL);
+		tmp |= (MCLK_CNTL__FORCE_MCLKA | MCLK_CNTL__FORCE_MCLKB);
+		tmp &= ~(MCLK_CNTL__FORCE_YCLKA  |
+			 MCLK_CNTL__FORCE_YCLKB  |
+			 MCLK_CNTL__FORCE_MC);
+
+		/* Some releases of vbios have set DISABLE_MC_MCLKA
+		 * and DISABLE_MC_MCLKB bits in the vbios table.  Setting these
+		 * bits will cause H/W hang when reading video memory with dynamic
+		 * clocking enabled.
+		 */
+		if ((tmp & MCLK_CNTL__R300_DISABLE_MC_MCLKA) &&
+		    (tmp & MCLK_CNTL__R300_DISABLE_MC_MCLKB)) {
+			/* If both bits are set, then check the active channels */
+			tmp = INPLL(pllMCLK_CNTL);
+			if (rinfo->vram_width == 64) {
+			    if (INREG(MEM_CNTL) & R300_MEM_USE_CD_CH_ONLY)
+				tmp &= ~MCLK_CNTL__R300_DISABLE_MC_MCLKB;
+			    else
+				tmp &= ~MCLK_CNTL__R300_DISABLE_MC_MCLKA;
+			} else {
+			    tmp &= ~(MCLK_CNTL__R300_DISABLE_MC_MCLKA |
+				     MCLK_CNTL__R300_DISABLE_MC_MCLKB);
+			}
+		}
+		OUTPLL(pllMCLK_CNTL, tmp);
+		return;
+	}
 
-	clk_pin_cntl = INPLL( pllCLK_PIN_CNTL);
-	clk_pin_cntl |= CLK_PIN_CNTL__SCLK_DYN_START_CNTL;
-	 
-	OUTPLL( pllCLK_PIN_CNTL, clk_pin_cntl);
+	/* R300 */
+	if (rinfo->family == CHIP_FAMILY_R300 || rinfo->family == CHIP_FAMILY_R350) {
+		tmp = INPLL(pllSCLK_CNTL);
+		tmp &= ~(SCLK_CNTL__R300_FORCE_VAP);
+		tmp |= SCLK_CNTL__FORCE_CP;
+		OUTPLL(pllSCLK_CNTL, tmp);
+		radeon_msleep(15);
+
+		tmp = INPLL(pllSCLK_CNTL2);
+		tmp &= ~(SCLK_CNTL2__R300_FORCE_TCL |
+			 SCLK_CNTL2__R300_FORCE_GA  |
+			 SCLK_CNTL2__R300_FORCE_CBA);
+		OUTPLL(pllSCLK_CNTL2, tmp);
+	}
 
-	/* Enable Dyanmic mode for SCLK */
+	/* Others */
 
-	sclk_cntl = INPLL( pllSCLK_CNTL_M6);	
-	sclk_cntl &= SCLK_CNTL_M6__SCLK_SRC_SEL_MASK;
-	sclk_cntl |= SCLK_CNTL_M6__FORCE_VIP;		
+	tmp = INPLL( pllCLK_PWRMGT_CNTL);
+	tmp &= ~(CLK_PWRMGT_CNTL__ACTIVE_HILO_LAT_MASK|
+		 CLK_PWRMGT_CNTL__DISP_DYN_STOP_LAT_MASK|
+		 CLK_PWRMGT_CNTL__DYN_STOP_MODE_MASK);
+	tmp |= CLK_PWRMGT_CNTL__ENGINE_DYNCLK_MODE_MASK |
+	       (0x01 << CLK_PWRMGT_CNTL__ACTIVE_HILO_LAT__SHIFT);
+	OUTPLL( pllCLK_PWRMGT_CNTL, tmp);
+	radeon_msleep(15);
+
+	tmp = INPLL(pllCLK_PIN_CNTL);
+	tmp |= CLK_PIN_CNTL__SCLK_DYN_START_CNTL;
+	OUTPLL(pllCLK_PIN_CNTL, tmp);
+	radeon_msleep(15);
 
-	OUTPLL( pllSCLK_CNTL_M6, sclk_cntl);
+	/* When DRI is enabled, setting DYN_STOP_LAT to zero can cause some R200
+	 * to lockup randomly, leave them as set by BIOS.
+	 */
+	tmp = INPLL(pllSCLK_CNTL);
+	tmp &= ~SCLK_CNTL__FORCEON_MASK;
 
+	/*RAGE_6::A11 A12 A12N1 A13, RV250::A11 A12, R300*/
+	if ((rinfo->family == CHIP_FAMILY_RV250 &&
+	     ((INREG(CONFIG_CNTL) & CFG_ATI_REV_ID_MASK) < CFG_ATI_REV_A13)) ||
+	    ((rinfo->family == CHIP_FAMILY_RV100) &&
+	     ((INREG(CONFIG_CNTL) & CFG_ATI_REV_ID_MASK) <= CFG_ATI_REV_A13))) {
+		tmp |= SCLK_CNTL__FORCE_CP;
+		tmp |= SCLK_CNTL__FORCE_VIP;
+	}
+	OUTPLL(pllSCLK_CNTL, tmp);
+	radeon_msleep(15);
 
-	sclk_more_cntl = INPLL(pllSCLK_MORE_CNTL);
-	sclk_more_cntl &= ~(SCLK_MORE_CNTL__FORCE_DISPREGS);
-				                    
-	OUTPLL(pllSCLK_MORE_CNTL, sclk_more_cntl);
+	if ((rinfo->family == CHIP_FAMILY_RV200) ||
+	    (rinfo->family == CHIP_FAMILY_RV250) ||
+	    (rinfo->family == CHIP_FAMILY_RV280)) {
+		tmp = INPLL(pllSCLK_MORE_CNTL);
+		tmp &= ~SCLK_MORE_CNTL__FORCEON;
+
+		/* RV200::A11 A12 RV250::A11 A12 */
+		if (((rinfo->family == CHIP_FAMILY_RV200) ||
+		     (rinfo->family == CHIP_FAMILY_RV250)) &&
+		    ((INREG(CONFIG_CNTL) & CFG_ATI_REV_ID_MASK) < CFG_ATI_REV_A13))
+			tmp |= SCLK_MORE_CNTL__FORCEON;
 
+		OUTPLL(pllSCLK_MORE_CNTL, tmp);
+		radeon_msleep(15);
+	}
 	
-	/* Enable Dynamic mode for PIXCLK & PIX2CLK */
 
-	pixclks_cntl = INPLL( pllPIXCLKS_CNTL);
-	
-	pixclks_cntl|=  PIXCLKS_CNTL__PIX2CLK_ALWAYS_ONb | 
-			PIXCLKS_CNTL__PIX2CLK_DAC_ALWAYS_ONb|
-			PIXCLKS_CNTL__PIXCLK_BLEND_ALWAYS_ONb|
-			PIXCLKS_CNTL__PIXCLK_GV_ALWAYS_ONb|
-			PIXCLKS_CNTL__PIXCLK_DIG_TMDS_ALWAYS_ONb|
-			PIXCLKS_CNTL__PIXCLK_LVDS_ALWAYS_ONb|
-			PIXCLKS_CNTL__PIXCLK_TMDS_ALWAYS_ONb;
+	/* RV200::A11 A12, RV250::A11 A12 */
+	if (((rinfo->family == CHIP_FAMILY_RV200) ||
+	     (rinfo->family == CHIP_FAMILY_RV250)) &&
+	    ((INREG(CONFIG_CNTL) & CFG_ATI_REV_ID_MASK) < CFG_ATI_REV_A13)) {
+		tmp = INPLL(pllPLL_PWRMGT_CNTL);
+		tmp |= PLL_PWRMGT_CNTL__TCL_BYPASS_DISABLE;
+		OUTPLL(pllPLL_PWRMGT_CNTL, tmp);
+		radeon_msleep(15);
+	}
 
-	OUTPLL( pllPIXCLKS_CNTL, pixclks_cntl);
+	tmp = INPLL(pllPIXCLKS_CNTL);
+	tmp |=  PIXCLKS_CNTL__PIX2CLK_ALWAYS_ONb |
+		PIXCLKS_CNTL__PIX2CLK_DAC_ALWAYS_ONb|
+		PIXCLKS_CNTL__PIXCLK_BLEND_ALWAYS_ONb|
+		PIXCLKS_CNTL__PIXCLK_GV_ALWAYS_ONb|
+		PIXCLKS_CNTL__PIXCLK_DIG_TMDS_ALWAYS_ONb|
+		PIXCLKS_CNTL__PIXCLK_LVDS_ALWAYS_ONb|
+		PIXCLKS_CNTL__PIXCLK_TMDS_ALWAYS_ONb;
+	OUTPLL(pllPIXCLKS_CNTL, tmp);
+	radeon_msleep(15);
 		
-		
-	vclk_ecp_cntl = INPLL( pllVCLK_ECP_CNTL);
-	
-	vclk_ecp_cntl|=  VCLK_ECP_CNTL__PIXCLK_ALWAYS_ONb | 
-			 VCLK_ECP_CNTL__PIXCLK_DAC_ALWAYS_ONb;
-
-	OUTPLL( pllVCLK_ECP_CNTL, vclk_ecp_cntl);
+	tmp = INPLL(pllVCLK_ECP_CNTL);
+	tmp |=  VCLK_ECP_CNTL__PIXCLK_ALWAYS_ONb |
+		VCLK_ECP_CNTL__PIXCLK_DAC_ALWAYS_ONb;
+	OUTPLL(pllVCLK_ECP_CNTL, tmp);
+
+	/* X doesn't do that ... hrm, we do on mobility && Macs */
+#ifdef CONFIG_PPC_OF
+	if (rinfo->is_mobility) {
+		tmp  = INPLL(pllMCLK_CNTL);
+		tmp &= ~(MCLK_CNTL__FORCE_MCLKA |
+			 MCLK_CNTL__FORCE_MCLKB |
+			 MCLK_CNTL__FORCE_YCLKA |
+			 MCLK_CNTL__FORCE_YCLKB);
+		OUTPLL(pllMCLK_CNTL, tmp);
+		radeon_msleep(15);
 
-
-	/* Enable Dynamic mode for MCLK	*/
-
-	mclk_cntl  = INPLL( pllMCLK_CNTL_M6);
-	mclk_cntl |= 	MCLK_CNTL_M6__FORCE_MCLKA|  
-			MCLK_CNTL_M6__FORCE_MCLKB|	
-			MCLK_CNTL_M6__FORCE_YCLKA|
-			MCLK_CNTL_M6__FORCE_YCLKB;
-			
-    	OUTPLL( pllMCLK_CNTL_M6, mclk_cntl);
-
-	mclk_misc = INPLL(pllMCLK_MISC);
-	mclk_misc |= 	MCLK_MISC__MC_MCLK_MAX_DYN_STOP_LAT|
+		tmp = INPLL(pllMCLK_MISC);
+		tmp |= 	MCLK_MISC__MC_MCLK_MAX_DYN_STOP_LAT|
 			MCLK_MISC__IO_MCLK_MAX_DYN_STOP_LAT|
 			MCLK_MISC__MC_MCLK_DYN_ENABLE|
-			MCLK_MISC__IO_MCLK_DYN_ENABLE;	
-	
-	OUTPLL(pllMCLK_MISC, mclk_misc);
+			MCLK_MISC__IO_MCLK_DYN_ENABLE;
+		OUTPLL(pllMCLK_MISC, tmp);
+		radeon_msleep(15);
+	}
+#endif /* CONFIG_PPC_OF */
 }
 
 #ifdef CONFIG_PM
@@ -218,7 +460,7 @@
 	return INREG( MC_IND_DATA);
 }
 
-static void radeon_pm_save_regs(struct radeonfb_info *rinfo)
+static void radeon_pm_save_regs(struct radeonfb_info *rinfo, int saving_for_d3)
 {
 	rinfo->save_regs[0] = INPLL(PLL_PWRMGT_CNTL);
 	rinfo->save_regs[1] = INPLL(CLK_PWRMGT_CNTL);
@@ -233,7 +475,6 @@
 	rinfo->save_regs[9] = INREG(DISP_MISC_CNTL);
 	rinfo->save_regs[10] = INREG(DISP_PWR_MAN);
 	rinfo->save_regs[11] = INREG(LVDS_GEN_CNTL);
-	rinfo->save_regs[12] = INREG(LVDS_PLL_CNTL);
 	rinfo->save_regs[13] = INREG(TV_DAC_CNTL);
 	rinfo->save_regs[14] = INREG(BUS_CNTL1);
 	rinfo->save_regs[15] = INREG(CRTC_OFFSET_CNTL);
@@ -256,6 +497,93 @@
 	rinfo->save_regs[31] = INREG(DISPLAY_BASE_ADDR);
 	rinfo->save_regs[32] = INREG(MC_AGP_LOCATION);
 	rinfo->save_regs[33] = INREG(CRTC2_DISPLAY_BASE_ADDR);
+
+	rinfo->save_regs[34] = INPLL(SCLK_MORE_CNTL);
+	rinfo->save_regs[35] = INREG(MEM_SDRAM_MODE_REG);
+	rinfo->save_regs[36] = INREG(BUS_CNTL);
+	rinfo->save_regs[39] = INREG(RBBM_CNTL);
+	rinfo->save_regs[40] = INREG(DAC_CNTL);
+	rinfo->save_regs[41] = INREG(HOST_PATH_CNTL);
+	rinfo->save_regs[37] = INREG(MPP_TB_CONFIG);
+	rinfo->save_regs[38] = INREG(FCP_CNTL);
+
+	if (rinfo->is_mobility) {
+		rinfo->save_regs[12] = INREG(LVDS_PLL_CNTL);
+		rinfo->save_regs[43] = INPLL(pllSSPLL_CNTL);
+		rinfo->save_regs[44] = INPLL(pllSSPLL_REF_DIV);
+		rinfo->save_regs[45] = INPLL(pllSSPLL_DIV_0);
+		rinfo->save_regs[90] = INPLL(pllSS_INT_CNTL);
+		rinfo->save_regs[91] = INPLL(pllSS_TST_CNTL);
+		rinfo->save_regs[81] = INREG(LVDS_GEN_CNTL);
+	}
+
+	if (rinfo->family >= CHIP_FAMILY_RV200) {
+		rinfo->save_regs[42] = INREG(MEM_REFRESH_CNTL);
+		rinfo->save_regs[46] = INREG(MC_CNTL);
+		rinfo->save_regs[47] = INREG(MC_INIT_GFX_LAT_TIMER);
+		rinfo->save_regs[48] = INREG(MC_INIT_MISC_LAT_TIMER);
+		rinfo->save_regs[49] = INREG(MC_TIMING_CNTL);
+		rinfo->save_regs[50] = INREG(MC_READ_CNTL_AB);
+		rinfo->save_regs[51] = INREG(MC_IOPAD_CNTL);
+		rinfo->save_regs[52] = INREG(MC_CHIP_IO_OE_CNTL_AB);
+		rinfo->save_regs[53] = INREG(MC_DEBUG);
+	}
+	rinfo->save_regs[54] = INREG(PAMAC0_DLY_CNTL);
+	rinfo->save_regs[55] = INREG(PAMAC1_DLY_CNTL);
+	rinfo->save_regs[56] = INREG(PAD_CTLR_MISC);
+	rinfo->save_regs[57] = INREG(FW_CNTL);
+
+	if (rinfo->family >= CHIP_FAMILY_R300) {
+		rinfo->save_regs[58] = INMC(rinfo, ixR300_MC_MC_INIT_WR_LAT_TIMER);
+		rinfo->save_regs[59] = INMC(rinfo, ixR300_MC_IMP_CNTL);
+		rinfo->save_regs[60] = INMC(rinfo, ixR300_MC_CHP_IO_CNTL_C0);
+		rinfo->save_regs[61] = INMC(rinfo, ixR300_MC_CHP_IO_CNTL_C1);
+		rinfo->save_regs[62] = INMC(rinfo, ixR300_MC_CHP_IO_CNTL_D0);
+		rinfo->save_regs[63] = INMC(rinfo, ixR300_MC_CHP_IO_CNTL_D1);
+		rinfo->save_regs[64] = INMC(rinfo, ixR300_MC_BIST_CNTL_3);
+		rinfo->save_regs[65] = INMC(rinfo, ixR300_MC_CHP_IO_CNTL_A0);
+		rinfo->save_regs[66] = INMC(rinfo, ixR300_MC_CHP_IO_CNTL_A1);
+		rinfo->save_regs[67] = INMC(rinfo, ixR300_MC_CHP_IO_CNTL_B0);
+		rinfo->save_regs[68] = INMC(rinfo, ixR300_MC_CHP_IO_CNTL_B1);
+		rinfo->save_regs[69] = INMC(rinfo, ixR300_MC_DEBUG_CNTL);
+		rinfo->save_regs[70] = INMC(rinfo, ixR300_MC_DLL_CNTL);
+		rinfo->save_regs[71] = INMC(rinfo, ixR300_MC_IMP_CNTL_0);
+		rinfo->save_regs[72] = INMC(rinfo, ixR300_MC_ELPIDA_CNTL);
+		rinfo->save_regs[96] = INMC(rinfo, ixR300_MC_READ_CNTL_CD);
+	} else {
+		rinfo->save_regs[59] = INMC(rinfo, ixMC_IMP_CNTL);
+		rinfo->save_regs[65] = INMC(rinfo, ixMC_CHP_IO_CNTL_A0);
+		rinfo->save_regs[66] = INMC(rinfo, ixMC_CHP_IO_CNTL_A1);
+		rinfo->save_regs[67] = INMC(rinfo, ixMC_CHP_IO_CNTL_B0);
+		rinfo->save_regs[68] = INMC(rinfo, ixMC_CHP_IO_CNTL_B1);
+		rinfo->save_regs[71] = INMC(rinfo, ixMC_IMP_CNTL_0);
+	}
+
+	rinfo->save_regs[73] = INPLL(pllMPLL_CNTL);
+	rinfo->save_regs[74] = INPLL(pllSPLL_CNTL);
+	rinfo->save_regs[75] = INPLL(pllMPLL_AUX_CNTL);
+	rinfo->save_regs[76] = INPLL(pllSPLL_AUX_CNTL);
+	rinfo->save_regs[77] = INPLL(pllM_SPLL_REF_FB_DIV);
+	rinfo->save_regs[78] = INPLL(pllAGP_PLL_CNTL);
+	rinfo->save_regs[79] = INREG(PAMAC2_DLY_CNTL);
+
+	rinfo->save_regs[80] = INREG(OV0_BASE_ADDR);
+	rinfo->save_regs[82] = INREG(FP_GEN_CNTL);
+	rinfo->save_regs[83] = INREG(FP2_GEN_CNTL);
+	rinfo->save_regs[84] = INREG(TMDS_CNTL);
+	rinfo->save_regs[85] = INREG(TMDS_TRANSMITTER_CNTL);
+	rinfo->save_regs[86] = INREG(DISP_OUTPUT_CNTL);
+	rinfo->save_regs[87] = INREG(DISP_HW_DEBUG);
+	rinfo->save_regs[88] = INREG(TV_MASTER_CNTL);
+	rinfo->save_regs[89] = INPLL(pllP2PLL_REF_DIV);
+	rinfo->save_regs[92] = INPLL(pllPPLL_DIV_0);
+	rinfo->save_regs[93] = INPLL(pllPPLL_CNTL);
+	rinfo->save_regs[94] = INREG(GRPH_BUFFER_CNTL);
+	rinfo->save_regs[95] = INREG(GRPH2_BUFFER_CNTL);
+	rinfo->save_regs[96] = INREG(HDP_DEBUG);
+	rinfo->save_regs[97] = INPLL(pllMDLL_CKO);
+	rinfo->save_regs[98] = INPLL(pllMDLL_RDCKA);
+	rinfo->save_regs[99] = INPLL(pllMDLL_RDCKB);
 }
 
 static void radeon_pm_restore_regs(struct radeonfb_info *rinfo)
@@ -270,12 +598,15 @@
 	OUTPLL(VCLK_ECP_CNTL, rinfo->save_regs[5]);
 	OUTPLL(PIXCLKS_CNTL, rinfo->save_regs[6]);
 	OUTPLL(MCLK_MISC, rinfo->save_regs[7]);
-	
+	if (rinfo->family == CHIP_FAMILY_RV350)
+		OUTPLL(SCLK_MORE_CNTL, rinfo->save_regs[34]);
+
 	OUTREG(SURFACE_CNTL, rinfo->save_regs[29]);
 	OUTREG(MC_FB_LOCATION, rinfo->save_regs[30]);
 	OUTREG(DISPLAY_BASE_ADDR, rinfo->save_regs[31]);
 	OUTREG(MC_AGP_LOCATION, rinfo->save_regs[32]);
 	OUTREG(CRTC2_DISPLAY_BASE_ADDR, rinfo->save_regs[33]);
+	OUTREG(CONFIG_MEMSIZE, rinfo->video_ram);
 
 	OUTREG(DISP_MISC_CNTL, rinfo->save_regs[9]);
 	OUTREG(DISP_PWR_MAN, rinfo->save_regs[10]);
@@ -287,10 +618,8 @@
 	OUTREG(AGP_CNTL, rinfo->save_regs[16]);
 	OUTREG(CRTC_GEN_CNTL, rinfo->save_regs[17]);
 	OUTREG(CRTC2_GEN_CNTL, rinfo->save_regs[18]);
-
-	// wait VBL before that one  ?
 	OUTPLL(P2PLL_CNTL, rinfo->save_regs[8]);
-	
+
 	OUTREG(GPIOPAD_A, rinfo->save_regs[19]);
 	OUTREG(GPIOPAD_EN, rinfo->save_regs[20]);
 	OUTREG(GPIOPAD_MASK, rinfo->save_regs[21]);
@@ -319,30 +648,32 @@
 
 static void radeon_pm_program_v2clk(struct radeonfb_info *rinfo)
 {
-	/* we use __INPLL and _OUTPLL and do the locking ourselves... */
-	unsigned long flags;
-	spin_lock_irqsave(&rinfo->reg_lock, flags);
 	/* Set v2clk to 65MHz */
-  	__OUTPLL(pllPIXCLKS_CNTL,
-  		__INPLL(rinfo, pllPIXCLKS_CNTL) & ~PIXCLKS_CNTL__PIX2CLK_SRC_SEL_MASK);
+	if (rinfo->family <= CHIP_FAMILY_RV280) {
+		OUTPLL(pllPIXCLKS_CNTL,
+			 __INPLL(rinfo, pllPIXCLKS_CNTL)
+			 & ~PIXCLKS_CNTL__PIX2CLK_SRC_SEL_MASK);
 	 
-  	__OUTPLL(pllP2PLL_REF_DIV, 0x0000000c);
-	__OUTPLL(pllP2PLL_CNTL, 0x0000bf00);
-	__OUTPLL(pllP2PLL_DIV_0, 0x00020074 | P2PLL_DIV_0__P2PLL_ATOMIC_UPDATE_W);
+		OUTPLL(pllP2PLL_REF_DIV, 0x0000000c);
+		OUTPLL(pllP2PLL_CNTL, 0x0000bf00);
+	} else {
+		OUTPLL(pllP2PLL_REF_DIV, 0x0000000c);
+		INPLL(pllP2PLL_REF_DIV);
+		OUTPLL(pllP2PLL_CNTL, 0x0000a700);
+	}
+
+	OUTPLL(pllP2PLL_DIV_0, 0x00020074 | P2PLL_DIV_0__P2PLL_ATOMIC_UPDATE_W);
 	
-	__OUTPLL(pllP2PLL_CNTL,
-		__INPLL(rinfo, pllP2PLL_CNTL) & ~P2PLL_CNTL__P2PLL_SLEEP);
+	OUTPLL(pllP2PLL_CNTL, INPLL(pllP2PLL_CNTL) & ~P2PLL_CNTL__P2PLL_SLEEP);
 	mdelay(1);
 
-	__OUTPLL(pllP2PLL_CNTL,
-		__INPLL(rinfo, pllP2PLL_CNTL) & ~P2PLL_CNTL__P2PLL_RESET);
+	OUTPLL(pllP2PLL_CNTL, INPLL(pllP2PLL_CNTL) & ~P2PLL_CNTL__P2PLL_RESET);
 	mdelay( 1);
 
-  	__OUTPLL(pllPIXCLKS_CNTL,
-  		(__INPLL(rinfo, pllPIXCLKS_CNTL) & ~PIXCLKS_CNTL__PIX2CLK_SRC_SEL_MASK)
+  	OUTPLL(pllPIXCLKS_CNTL,
+  		(INPLL(pllPIXCLKS_CNTL) & ~PIXCLKS_CNTL__PIX2CLK_SRC_SEL_MASK)
   		| (0x03 << PIXCLKS_CNTL__PIX2CLK_SRC_SEL__SHIFT));
 	mdelay( 1);	
-	spin_unlock_irqrestore(&rinfo->reg_lock, flags);
 }
 
 static void radeon_pm_low_current(struct radeonfb_info *rinfo)
@@ -350,8 +681,12 @@
 	u32 reg;
 
 	reg  = INREG(BUS_CNTL1);
-	reg &= ~BUS_CNTL1_MOBILE_PLATFORM_SEL_MASK;
-	reg |= BUS_CNTL1_AGPCLK_VALID | (1<<BUS_CNTL1_MOBILE_PLATFORM_SEL_SHIFT);
+	if (rinfo->family <= CHIP_FAMILY_RV280) {
+		reg &= ~BUS_CNTL1_MOBILE_PLATFORM_SEL_MASK;
+		reg |= BUS_CNTL1_AGPCLK_VALID | (1<<BUS_CNTL1_MOBILE_PLATFORM_SEL_SHIFT);
+	} else {
+		reg |= 0x4080;
+	}
 	OUTREG(BUS_CNTL1, reg);
 	
 	reg  = INPLL(PLL_PWRMGT_CNTL);
@@ -400,35 +735,42 @@
 	u32 tmp;
 	
 	/* Force Core Clocks */
-	sclk_cntl = INPLL( pllSCLK_CNTL_M6);
-	sclk_cntl |= 	SCLK_CNTL_M6__IDCT_MAX_DYN_STOP_LAT|
-			SCLK_CNTL_M6__VIP_MAX_DYN_STOP_LAT|
-			SCLK_CNTL_M6__RE_MAX_DYN_STOP_LAT|
-			SCLK_CNTL_M6__PB_MAX_DYN_STOP_LAT|
-			SCLK_CNTL_M6__TAM_MAX_DYN_STOP_LAT|
-			SCLK_CNTL_M6__TDM_MAX_DYN_STOP_LAT|
-			SCLK_CNTL_M6__RB_MAX_DYN_STOP_LAT|
+	sclk_cntl = INPLL( pllSCLK_CNTL);
+	sclk_cntl |= 	SCLK_CNTL__IDCT_MAX_DYN_STOP_LAT|
+			SCLK_CNTL__VIP_MAX_DYN_STOP_LAT|
+			SCLK_CNTL__RE_MAX_DYN_STOP_LAT|
+			SCLK_CNTL__PB_MAX_DYN_STOP_LAT|
+			SCLK_CNTL__TAM_MAX_DYN_STOP_LAT|
+			SCLK_CNTL__TDM_MAX_DYN_STOP_LAT|
+			SCLK_CNTL__RB_MAX_DYN_STOP_LAT|
 			
-			SCLK_CNTL_M6__FORCE_DISP2|
-			SCLK_CNTL_M6__FORCE_CP|
-			SCLK_CNTL_M6__FORCE_HDP|
-			SCLK_CNTL_M6__FORCE_DISP1|
-			SCLK_CNTL_M6__FORCE_TOP|
-			SCLK_CNTL_M6__FORCE_E2|
-			SCLK_CNTL_M6__FORCE_SE|
-			SCLK_CNTL_M6__FORCE_IDCT|
-			SCLK_CNTL_M6__FORCE_VIP|
+			SCLK_CNTL__FORCE_DISP2|
+			SCLK_CNTL__FORCE_CP|
+			SCLK_CNTL__FORCE_HDP|
+			SCLK_CNTL__FORCE_DISP1|
+			SCLK_CNTL__FORCE_TOP|
+			SCLK_CNTL__FORCE_E2|
+			SCLK_CNTL__FORCE_SE|
+			SCLK_CNTL__FORCE_IDCT|
+			SCLK_CNTL__FORCE_VIP|
 			
-			SCLK_CNTL_M6__FORCE_RE|
-			SCLK_CNTL_M6__FORCE_PB|
-			SCLK_CNTL_M6__FORCE_TAM|
-			SCLK_CNTL_M6__FORCE_TDM|
-			SCLK_CNTL_M6__FORCE_RB|
-			SCLK_CNTL_M6__FORCE_TV_SCLK|
-			SCLK_CNTL_M6__FORCE_SUBPIC|
-			SCLK_CNTL_M6__FORCE_OV0;
+			SCLK_CNTL__FORCE_PB|
+			SCLK_CNTL__FORCE_TAM|
+			SCLK_CNTL__FORCE_TDM|
+			SCLK_CNTL__FORCE_RB|
+			SCLK_CNTL__FORCE_TV_SCLK|
+			SCLK_CNTL__FORCE_SUBPIC|
+			SCLK_CNTL__FORCE_OV0;
+	if (rinfo->family <= CHIP_FAMILY_RV280)
+		sclk_cntl |= SCLK_CNTL__FORCE_RE;
+	else
+		sclk_cntl |= SCLK_CNTL__SE_MAX_DYN_STOP_LAT |
+			SCLK_CNTL__E2_MAX_DYN_STOP_LAT |
+			SCLK_CNTL__TV_MAX_DYN_STOP_LAT |
+			SCLK_CNTL__HDP_MAX_DYN_STOP_LAT |
+			SCLK_CNTL__CP_MAX_DYN_STOP_LAT;
 
-	OUTPLL( pllSCLK_CNTL_M6, sclk_cntl);
+	OUTPLL( pllSCLK_CNTL, sclk_cntl);
 
 	sclk_more_cntl = INPLL(pllSCLK_MORE_CNTL);
 	sclk_more_cntl |= 	SCLK_MORE_CNTL__FORCE_DISPREGS |
@@ -438,18 +780,19 @@
 	OUTPLL(pllSCLK_MORE_CNTL, sclk_more_cntl);		
 
 	
-	mclk_cntl = INPLL( pllMCLK_CNTL_M6);
-	mclk_cntl &= ~(	MCLK_CNTL_M6__FORCE_MCLKA |  
-			MCLK_CNTL_M6__FORCE_MCLKB |
-			MCLK_CNTL_M6__FORCE_YCLKA | 
-			MCLK_CNTL_M6__FORCE_YCLKB | 
-			MCLK_CNTL_M6__FORCE_MC
+	mclk_cntl = INPLL( pllMCLK_CNTL);
+	mclk_cntl &= ~(	MCLK_CNTL__FORCE_MCLKA |
+			MCLK_CNTL__FORCE_MCLKB |
+			MCLK_CNTL__FORCE_YCLKA |
+			MCLK_CNTL__FORCE_YCLKB |
+			MCLK_CNTL__FORCE_MC
 		      );	
-    	OUTPLL( pllMCLK_CNTL_M6, mclk_cntl);
+    	OUTPLL( pllMCLK_CNTL, mclk_cntl);
 	
 	/* Force Display clocks	*/
 	vclk_ecp_cntl = INPLL( pllVCLK_ECP_CNTL);
-	vclk_ecp_cntl &= ~(VCLK_ECP_CNTL__PIXCLK_ALWAYS_ONb |VCLK_ECP_CNTL__PIXCLK_DAC_ALWAYS_ONb);
+	vclk_ecp_cntl &= ~(VCLK_ECP_CNTL__PIXCLK_ALWAYS_ONb
+			   | VCLK_ECP_CNTL__PIXCLK_DAC_ALWAYS_ONb);
 	vclk_ecp_cntl |= VCLK_ECP_CNTL__ECP_FORCE_ON;
 	OUTPLL( pllVCLK_ECP_CNTL, vclk_ecp_cntl);
 	
@@ -480,26 +823,27 @@
 						
 	OUTPLL( pllPLL_PWRMGT_CNTL, pll_pwrmgt_cntl);
 	
-	clk_pwrmgt_cntl	 = INPLL( pllCLK_PWRMGT_CNTL_M6);
+	clk_pwrmgt_cntl	 = INPLL( pllCLK_PWRMGT_CNTL);
 	
-	clk_pwrmgt_cntl &= ~(	CLK_PWRMGT_CNTL_M6__MPLL_PWRMGT_OFF|
-				CLK_PWRMGT_CNTL_M6__SPLL_PWRMGT_OFF|
-				CLK_PWRMGT_CNTL_M6__PPLL_PWRMGT_OFF|
-				CLK_PWRMGT_CNTL_M6__P2PLL_PWRMGT_OFF|
-				CLK_PWRMGT_CNTL_M6__MCLK_TURNOFF|
-				CLK_PWRMGT_CNTL_M6__SCLK_TURNOFF|
-				CLK_PWRMGT_CNTL_M6__PCLK_TURNOFF|
-				CLK_PWRMGT_CNTL_M6__P2CLK_TURNOFF|
-				CLK_PWRMGT_CNTL_M6__TVPLL_PWRMGT_OFF|
-				CLK_PWRMGT_CNTL_M6__GLOBAL_PMAN_EN|
-				CLK_PWRMGT_CNTL_M6__ENGINE_DYNCLK_MODE|
-				CLK_PWRMGT_CNTL_M6__ACTIVE_HILO_LAT_MASK|
-				CLK_PWRMGT_CNTL_M6__CG_NO1_DEBUG_MASK			
+	clk_pwrmgt_cntl &= ~(	CLK_PWRMGT_CNTL__MPLL_PWRMGT_OFF|
+				CLK_PWRMGT_CNTL__SPLL_PWRMGT_OFF|
+				CLK_PWRMGT_CNTL__PPLL_PWRMGT_OFF|
+				CLK_PWRMGT_CNTL__P2PLL_PWRMGT_OFF|
+				CLK_PWRMGT_CNTL__MCLK_TURNOFF|
+				CLK_PWRMGT_CNTL__SCLK_TURNOFF|
+				CLK_PWRMGT_CNTL__PCLK_TURNOFF|
+				CLK_PWRMGT_CNTL__P2CLK_TURNOFF|
+				CLK_PWRMGT_CNTL__TVPLL_PWRMGT_OFF|
+				CLK_PWRMGT_CNTL__GLOBAL_PMAN_EN|
+				CLK_PWRMGT_CNTL__ENGINE_DYNCLK_MODE|
+				CLK_PWRMGT_CNTL__ACTIVE_HILO_LAT_MASK|
+				CLK_PWRMGT_CNTL__CG_NO1_DEBUG_MASK
 			);
 						
-	clk_pwrmgt_cntl |= CLK_PWRMGT_CNTL_M6__GLOBAL_PMAN_EN | CLK_PWRMGT_CNTL_M6__DISP_PM;
+	clk_pwrmgt_cntl |= CLK_PWRMGT_CNTL__GLOBAL_PMAN_EN
+		| CLK_PWRMGT_CNTL__DISP_PM;
 	
-	OUTPLL( pllCLK_PWRMGT_CNTL_M6, clk_pwrmgt_cntl);	
+	OUTPLL( pllCLK_PWRMGT_CNTL, clk_pwrmgt_cntl);
 	
 	clk_pin_cntl = INPLL( pllCLK_PIN_CNTL);
 	
@@ -510,12 +854,19 @@
 	OUTPLL( pllMCLK_MISC, tmp);
 	
 	/* AGP PLL control */
-	OUTREG(BUS_CNTL1, INREG(BUS_CNTL1) |  BUS_CNTL1__AGPCLK_VALID);
+	if (rinfo->family <= CHIP_FAMILY_RV280) {
+		OUTREG(BUS_CNTL1, INREG(BUS_CNTL1) |  BUS_CNTL1__AGPCLK_VALID);
 
-	OUTREG(BUS_CNTL1,
-		(INREG(BUS_CNTL1) & ~BUS_CNTL1__MOBILE_PLATFORM_SEL_MASK)
-		| (2<<BUS_CNTL1__MOBILE_PLATFORM_SEL__SHIFT));	// 440BX
-	OUTREG(CRTC_OFFSET_CNTL, (INREG(CRTC_OFFSET_CNTL) & ~CRTC_OFFSET_CNTL__CRTC_STEREO_SYNC_OUT_EN));
+		OUTREG(BUS_CNTL1,
+		       (INREG(BUS_CNTL1) & ~BUS_CNTL1__MOBILE_PLATFORM_SEL_MASK)
+		       | (2<<BUS_CNTL1__MOBILE_PLATFORM_SEL__SHIFT));	// 440BX
+	} else {
+		OUTREG(BUS_CNTL1, INREG(BUS_CNTL1));
+		OUTREG(BUS_CNTL1, (INREG(BUS_CNTL1) & ~0x4000) | 0x8000);
+	}
+
+	OUTREG(CRTC_OFFSET_CNTL, (INREG(CRTC_OFFSET_CNTL)
+				  & ~CRTC_OFFSET_CNTL__CRTC_STEREO_SYNC_OUT_EN));
 	
 	clk_pin_cntl &= ~CLK_PIN_CNTL__CG_CLK_TO_OUTPIN;
 	clk_pin_cntl |= CLK_PIN_CNTL__XTALIN_ALWAYS_ONb;	
@@ -547,16 +898,16 @@
 				DISP_MISC_CNTL__SOFT_RESET_DIG_TMDS|
 				DISP_MISC_CNTL__SOFT_RESET_TV);
 	
-	OUTREG(DISP_MISC_CNTL, disp_mis_cntl);					
+	OUTREG(DISP_MISC_CNTL, disp_mis_cntl);
 						
 	disp_pwr_man = INREG(DISP_PWR_MAN);
 	
 	disp_pwr_man &= ~(	DISP_PWR_MAN__DISP_PWR_MAN_D3_CRTC_EN	| 
-						DISP_PWR_MAN__DISP2_PWR_MAN_D3_CRTC2_EN |
-						DISP_PWR_MAN__DISP_PWR_MAN_DPMS_MASK|		
-						DISP_PWR_MAN__DISP_D3_RST|
-						DISP_PWR_MAN__DISP_D3_REG_RST
-					);
+				DISP_PWR_MAN__DISP2_PWR_MAN_D3_CRTC2_EN |
+				DISP_PWR_MAN__DISP_PWR_MAN_DPMS_MASK|
+				DISP_PWR_MAN__DISP_D3_RST|
+				DISP_PWR_MAN__DISP_D3_REG_RST
+				);
 	
 	disp_pwr_man |= DISP_PWR_MAN__DISP_D3_GRPH_RST|
 					DISP_PWR_MAN__DISP_D3_SUBPIC_RST|
@@ -571,27 +922,29 @@
 	
 	OUTREG(DISP_PWR_MAN, disp_pwr_man);					
 							
-	clk_pwrmgt_cntl = INPLL( pllCLK_PWRMGT_CNTL_M6);
+	clk_pwrmgt_cntl = INPLL( pllCLK_PWRMGT_CNTL);
 	pll_pwrmgt_cntl = INPLL( pllPLL_PWRMGT_CNTL) ;
 	clk_pin_cntl 	= INPLL( pllCLK_PIN_CNTL);
 	disp_pwr_man	= INREG(DISP_PWR_MAN);
 		
 	
 	/* D2 */
-	clk_pwrmgt_cntl |= CLK_PWRMGT_CNTL_M6__DISP_PM;
+	clk_pwrmgt_cntl |= CLK_PWRMGT_CNTL__DISP_PM;
 	pll_pwrmgt_cntl |= PLL_PWRMGT_CNTL__MOBILE_SU | PLL_PWRMGT_CNTL__SU_SCLK_USE_BCLK;
 	clk_pin_cntl	|= CLK_PIN_CNTL__XTALIN_ALWAYS_ONb;
-	disp_pwr_man 	&= ~(DISP_PWR_MAN__DISP_PWR_MAN_D3_CRTC_EN_MASK | DISP_PWR_MAN__DISP2_PWR_MAN_D3_CRTC2_EN_MASK);							
-						
+	disp_pwr_man 	&= ~(DISP_PWR_MAN__DISP_PWR_MAN_D3_CRTC_EN_MASK
+			     | DISP_PWR_MAN__DISP2_PWR_MAN_D3_CRTC2_EN_MASK);
 
-	OUTPLL( pllCLK_PWRMGT_CNTL_M6, clk_pwrmgt_cntl);
+	OUTPLL( pllCLK_PWRMGT_CNTL, clk_pwrmgt_cntl);
 	OUTPLL( pllPLL_PWRMGT_CNTL, pll_pwrmgt_cntl);
 	OUTPLL( pllCLK_PIN_CNTL, clk_pin_cntl);
 	OUTREG(DISP_PWR_MAN, disp_pwr_man);
 
 	/* disable display request & disable display */
-	OUTREG( CRTC_GEN_CNTL, (INREG( CRTC_GEN_CNTL) & ~CRTC_GEN_CNTL__CRTC_EN) | CRTC_GEN_CNTL__CRTC_DISP_REQ_EN_B);
-	OUTREG( CRTC2_GEN_CNTL, (INREG( CRTC2_GEN_CNTL) & ~CRTC2_GEN_CNTL__CRTC2_EN) | CRTC2_GEN_CNTL__CRTC2_DISP_REQ_EN_B);
+	OUTREG( CRTC_GEN_CNTL, (INREG( CRTC_GEN_CNTL) & ~CRTC_GEN_CNTL__CRTC_EN)
+		| CRTC_GEN_CNTL__CRTC_DISP_REQ_EN_B);
+	OUTREG( CRTC2_GEN_CNTL, (INREG( CRTC2_GEN_CNTL) & ~CRTC2_GEN_CNTL__CRTC2_EN)
+		| CRTC2_GEN_CNTL__CRTC2_DISP_REQ_EN_B);
 
 	mdelay(17);				   
 
@@ -601,17 +954,15 @@
 {
 	u32 mc_chp_io_cntl_a1, mc_chp_io_cntl_b1;
 
-	mc_chp_io_cntl_a1 = INMC( rinfo, ixMC_CHP_IO_CNTL_A1) & ~MC_CHP_IO_CNTL_A1__MEM_SYNC_ENA_MASK;
-	mc_chp_io_cntl_b1 = INMC( rinfo, ixMC_CHP_IO_CNTL_B1) & ~MC_CHP_IO_CNTL_B1__MEM_SYNC_ENB_MASK;
-
-	OUTMC( rinfo, ixMC_CHP_IO_CNTL_A1, mc_chp_io_cntl_a1 | (1<<MC_CHP_IO_CNTL_A1__MEM_SYNC_ENA__SHIFT));
-	OUTMC( rinfo, ixMC_CHP_IO_CNTL_B1, mc_chp_io_cntl_b1 | (1<<MC_CHP_IO_CNTL_B1__MEM_SYNC_ENB__SHIFT));
-
-	/* Wassup ? This doesn't seem to be defined, let's hope we are ok this way --BenH */
-#ifdef MCLK_YCLK_SYNC_ENABLE
-	mc_chp_io_cntl_a1 |= (2<<MC_CHP_IO_CNTL_A1__MEM_SYNC_ENA__SHIFT);
-	mc_chp_io_cntl_b1 |= (2<<MC_CHP_IO_CNTL_B1__MEM_SYNC_ENB__SHIFT);
-#endif
+	mc_chp_io_cntl_a1 = INMC( rinfo, ixMC_CHP_IO_CNTL_A1)
+		& ~MC_CHP_IO_CNTL_A1__MEM_SYNC_ENA_MASK;
+	mc_chp_io_cntl_b1 = INMC( rinfo, ixMC_CHP_IO_CNTL_B1)
+		& ~MC_CHP_IO_CNTL_B1__MEM_SYNC_ENB_MASK;
+
+	OUTMC( rinfo, ixMC_CHP_IO_CNTL_A1, mc_chp_io_cntl_a1
+	       | (1<<MC_CHP_IO_CNTL_A1__MEM_SYNC_ENA__SHIFT));
+	OUTMC( rinfo, ixMC_CHP_IO_CNTL_B1, mc_chp_io_cntl_b1
+	       | (1<<MC_CHP_IO_CNTL_B1__MEM_SYNC_ENB__SHIFT));
 
 	OUTMC( rinfo, ixMC_CHP_IO_CNTL_A1, mc_chp_io_cntl_a1);
 	OUTMC( rinfo, ixMC_CHP_IO_CNTL_B1, mc_chp_io_cntl_b1);
@@ -619,25 +970,70 @@
 	mdelay( 1);
 }
 
-static void radeon_pm_program_mode_reg(struct radeonfb_info *rinfo, u16 value, u8 delay_required)
+static void radeon_pm_yclk_mclk_sync_m10(struct radeonfb_info *rinfo)
+{
+	u32 mc_chp_io_cntl_a1, mc_chp_io_cntl_b1;
+
+	mc_chp_io_cntl_a1 = INMC(rinfo, ixR300_MC_CHP_IO_CNTL_A1)
+		& ~MC_CHP_IO_CNTL_A1__MEM_SYNC_ENA_MASK;
+	mc_chp_io_cntl_b1 = INMC(rinfo, ixR300_MC_CHP_IO_CNTL_B1)
+		& ~MC_CHP_IO_CNTL_B1__MEM_SYNC_ENB_MASK;
+
+	OUTMC( rinfo, ixR300_MC_CHP_IO_CNTL_A1,
+	       mc_chp_io_cntl_a1 | (1<<MC_CHP_IO_CNTL_A1__MEM_SYNC_ENA__SHIFT));
+	OUTMC( rinfo, ixR300_MC_CHP_IO_CNTL_B1,
+	       mc_chp_io_cntl_b1 | (1<<MC_CHP_IO_CNTL_B1__MEM_SYNC_ENB__SHIFT));
+
+	OUTMC( rinfo, ixR300_MC_CHP_IO_CNTL_A1, mc_chp_io_cntl_a1);
+	OUTMC( rinfo, ixR300_MC_CHP_IO_CNTL_B1, mc_chp_io_cntl_b1);
+
+	mdelay( 1);
+}
+
+static void radeon_pm_program_mode_reg(struct radeonfb_info *rinfo, u16 value,
+				       u8 delay_required)
 {  
 	u32 mem_sdram_mode;
 
 	mem_sdram_mode  = INREG( MEM_SDRAM_MODE_REG);
 
 	mem_sdram_mode &= ~MEM_SDRAM_MODE_REG__MEM_MODE_REG_MASK;
-	mem_sdram_mode |= (value<<MEM_SDRAM_MODE_REG__MEM_MODE_REG__SHIFT) | MEM_SDRAM_MODE_REG__MEM_CFG_TYPE;
+	mem_sdram_mode |= (value<<MEM_SDRAM_MODE_REG__MEM_MODE_REG__SHIFT)
+		| MEM_SDRAM_MODE_REG__MEM_CFG_TYPE;
 	OUTREG( MEM_SDRAM_MODE_REG, mem_sdram_mode);
+	if (delay_required >= 2)
+		mdelay(1);
 
 	mem_sdram_mode |=  MEM_SDRAM_MODE_REG__MEM_SDRAM_RESET;
 	OUTREG( MEM_SDRAM_MODE_REG, mem_sdram_mode);
+	if (delay_required >= 2)
+		mdelay(1);
 
 	mem_sdram_mode &= ~MEM_SDRAM_MODE_REG__MEM_SDRAM_RESET;
 	OUTREG( MEM_SDRAM_MODE_REG, mem_sdram_mode);
+	if (delay_required >= 2)
+		mdelay(1);
 
-	if (delay_required == 1)
-		while( (INREG( MC_STATUS) & (MC_STATUS__MEM_PWRUP_COMPL_A | MC_STATUS__MEM_PWRUP_COMPL_B) ) == 0 )
-			{ }; 	
+	if (delay_required) {
+		do {
+			if (delay_required >= 2)
+				mdelay(1);
+		} while ((INREG(MC_STATUS)
+			  & (MC_STATUS__MEM_PWRUP_COMPL_A |
+			     MC_STATUS__MEM_PWRUP_COMPL_B)) == 0);
+	}
+}
+
+static void radeon_pm_m10_program_mode_wait(struct radeonfb_info *rinfo)
+{
+	int cnt;
+
+	for (cnt = 0; cnt < 100; ++cnt) {
+		mdelay(1);
+		if (INREG(MC_STATUS) & (MC_STATUS__MEM_PWRUP_COMPL_A
+					| MC_STATUS__MEM_PWRUP_COMPL_B))
+			break;
+	}
 }
 
 
@@ -646,126 +1042,274 @@
 #define DLL_RESET_DELAY 	5
 #define DLL_SLEEP_DELAY		1
 
-	u32 DLL_CKO_Value = INPLL(pllMDLL_CKO)   | MDLL_CKO__MCKOA_SLEEP |  MDLL_CKO__MCKOA_RESET;
-	u32 DLL_CKA_Value = INPLL(pllMDLL_RDCKA) | MDLL_RDCKA__MRDCKA0_SLEEP | MDLL_RDCKA__MRDCKA1_SLEEP | MDLL_RDCKA__MRDCKA0_RESET | MDLL_RDCKA__MRDCKA1_RESET;
-	u32 DLL_CKB_Value = INPLL(pllMDLL_RDCKB) | MDLL_RDCKB__MRDCKB0_SLEEP | MDLL_RDCKB__MRDCKB1_SLEEP | MDLL_RDCKB__MRDCKB0_RESET | MDLL_RDCKB__MRDCKB1_RESET;
+	u32 cko = INPLL(pllMDLL_CKO)   | MDLL_CKO__MCKOA_SLEEP
+		| MDLL_CKO__MCKOA_RESET;
+	u32 cka = INPLL(pllMDLL_RDCKA) | MDLL_RDCKA__MRDCKA0_SLEEP
+		| MDLL_RDCKA__MRDCKA1_SLEEP | MDLL_RDCKA__MRDCKA0_RESET
+		| MDLL_RDCKA__MRDCKA1_RESET;
+	u32 ckb = INPLL(pllMDLL_RDCKB) | MDLL_RDCKB__MRDCKB0_SLEEP
+		| MDLL_RDCKB__MRDCKB1_SLEEP | MDLL_RDCKB__MRDCKB0_RESET
+		| MDLL_RDCKB__MRDCKB1_RESET;
 
 	/* Setting up the DLL range for write */
-	OUTPLL(pllMDLL_CKO,   	DLL_CKO_Value);
-	OUTPLL(pllMDLL_RDCKA,  	DLL_CKA_Value);
-	OUTPLL(pllMDLL_RDCKB,	DLL_CKB_Value);
+	OUTPLL(pllMDLL_CKO,   	cko);
+	OUTPLL(pllMDLL_RDCKA,  	cka);
+	OUTPLL(pllMDLL_RDCKB,	ckb);
+
+	mdelay(DLL_RESET_DELAY*2);
+
+	cko &= ~(MDLL_CKO__MCKOA_SLEEP | MDLL_CKO__MCKOB_SLEEP);
+	OUTPLL(pllMDLL_CKO, cko);
+	mdelay(DLL_SLEEP_DELAY);
+	cko &= ~(MDLL_CKO__MCKOA_RESET | MDLL_CKO__MCKOB_RESET);
+	OUTPLL(pllMDLL_CKO, cko);
+	mdelay(DLL_RESET_DELAY);
+
+	cka &= ~(MDLL_RDCKA__MRDCKA0_SLEEP | MDLL_RDCKA__MRDCKA1_SLEEP);
+	OUTPLL(pllMDLL_RDCKA, cka);
+	mdelay(DLL_SLEEP_DELAY);
+	cka &= ~(MDLL_RDCKA__MRDCKA0_RESET | MDLL_RDCKA__MRDCKA1_RESET);
+	OUTPLL(pllMDLL_RDCKA, cka);
+	mdelay(DLL_RESET_DELAY);
+
+	ckb &= ~(MDLL_RDCKB__MRDCKB0_SLEEP | MDLL_RDCKB__MRDCKB1_SLEEP);
+	OUTPLL(pllMDLL_RDCKB, ckb);
+	mdelay(DLL_SLEEP_DELAY);
+	ckb &= ~(MDLL_RDCKB__MRDCKB0_RESET | MDLL_RDCKB__MRDCKB1_RESET);
+	OUTPLL(pllMDLL_RDCKB, ckb);
+	mdelay(DLL_RESET_DELAY);
 
-	mdelay( DLL_RESET_DELAY);
-
-	/* Channel A */
-
-	/* Power Up */
-	DLL_CKO_Value &= ~(MDLL_CKO__MCKOA_SLEEP );
-	OUTPLL(pllMDLL_CKO,   	DLL_CKO_Value);
-	mdelay( DLL_SLEEP_DELAY);  		
-   
-	DLL_CKO_Value &= ~(MDLL_CKO__MCKOA_RESET );
-	OUTPLL(pllMDLL_CKO,	DLL_CKO_Value);
-	mdelay( DLL_RESET_DELAY);  		
-
-	/* Power Up */
-	DLL_CKA_Value &= ~(MDLL_RDCKA__MRDCKA0_SLEEP );
-	OUTPLL(pllMDLL_RDCKA,  	DLL_CKA_Value);
-	mdelay( DLL_SLEEP_DELAY);  		
-
-	DLL_CKA_Value &= ~(MDLL_RDCKA__MRDCKA0_RESET );
-	OUTPLL(pllMDLL_RDCKA,	DLL_CKA_Value);
-	mdelay( DLL_RESET_DELAY);  		
-
-	/* Power Up */
-	DLL_CKA_Value &= ~(MDLL_RDCKA__MRDCKA1_SLEEP);
-	OUTPLL(pllMDLL_RDCKA,	DLL_CKA_Value);
-	mdelay( DLL_SLEEP_DELAY);  		
-
-	DLL_CKA_Value &= ~(MDLL_RDCKA__MRDCKA1_RESET);
-	OUTPLL(pllMDLL_RDCKA,	DLL_CKA_Value);
-	mdelay( DLL_RESET_DELAY);  		
 
+#undef DLL_RESET_DELAY
+#undef DLL_SLEEP_DELAY
+}
 
-	/* Channel B */
+static void radeon_pm_enable_dll_m10(struct radeonfb_info *rinfo)
+{
+	u32 dll_value;
+	u32 dll_sleep_mask = 0;
+	u32 dll_reset_mask = 0;
+	u32 mc;
 
-	/* Power Up */
-	DLL_CKO_Value &= ~(MDLL_CKO__MCKOB_SLEEP );
-	OUTPLL(pllMDLL_CKO,   	DLL_CKO_Value);
-	mdelay( DLL_SLEEP_DELAY);  		
-   
-	DLL_CKO_Value &= ~(MDLL_CKO__MCKOB_RESET );
-	OUTPLL(pllMDLL_CKO,   	DLL_CKO_Value);
-	mdelay( DLL_RESET_DELAY);  		
+#define DLL_RESET_DELAY 	5
+#define DLL_SLEEP_DELAY		1
 
-	/* Power Up */
-	DLL_CKB_Value &= ~(MDLL_RDCKB__MRDCKB0_SLEEP);
-	OUTPLL(pllMDLL_RDCKB,   DLL_CKB_Value);
-	mdelay( DLL_SLEEP_DELAY);  		
+	OUTMC(rinfo, ixR300_MC_DLL_CNTL, rinfo->save_regs[70]);
+	mc = INREG(MC_CNTL);
+	/* Check which channels are enabled */
+	switch (mc & 0x3) {
+	case 1:
+		if (mc & 0x4)
+			break;
+	case 2:
+		dll_sleep_mask |= MDLL_R300_RDCK__MRDCKB_SLEEP;
+		dll_reset_mask |= MDLL_R300_RDCK__MRDCKB_RESET;
+	case 0:
+		dll_sleep_mask |= MDLL_R300_RDCK__MRDCKA_SLEEP;
+		dll_reset_mask |= MDLL_R300_RDCK__MRDCKA_RESET;
+	}
+	switch (mc & 0x3) {
+	case 1:
+		if (!(mc & 0x4))
+			break;
+	case 2:
+		dll_sleep_mask |= MDLL_R300_RDCK__MRDCKD_SLEEP;
+		dll_reset_mask |= MDLL_R300_RDCK__MRDCKD_RESET;
+		dll_sleep_mask |= MDLL_R300_RDCK__MRDCKC_SLEEP;
+		dll_reset_mask |= MDLL_R300_RDCK__MRDCKC_RESET;
+	}
 
-	DLL_CKB_Value &= ~(MDLL_RDCKB__MRDCKB0_RESET);
-	OUTPLL(pllMDLL_RDCKB,   DLL_CKB_Value);
-	mdelay( DLL_RESET_DELAY);  		
+	dll_value = INPLL(pllMDLL_RDCKA);
 
 	/* Power Up */
-	DLL_CKB_Value &= ~(MDLL_RDCKB__MRDCKB1_SLEEP);
-	OUTPLL(pllMDLL_RDCKB,   DLL_CKB_Value);
+	dll_value &= ~(dll_sleep_mask);
+	OUTPLL(pllMDLL_RDCKA, dll_value);
 	mdelay( DLL_SLEEP_DELAY);  		
 
-	DLL_CKB_Value &= ~(MDLL_RDCKB__MRDCKB1_RESET);
-	OUTPLL(pllMDLL_RDCKB,   DLL_CKB_Value);
+	dll_value &= ~(dll_reset_mask);
+	OUTPLL(pllMDLL_RDCKA, dll_value);
 	mdelay( DLL_RESET_DELAY);  		
 
 #undef DLL_RESET_DELAY 
 #undef DLL_SLEEP_DELAY
 }
 
+
 static void radeon_pm_full_reset_sdram(struct radeonfb_info *rinfo)
 {
-	u32 crtcGenCntl, crtcGenCntl2, memRefreshCntl, crtc_more_cntl, fp_gen_cntl, fp2_gen_cntl;
+	u32 crtcGenCntl, crtcGenCntl2, memRefreshCntl, crtc_more_cntl,
+		fp_gen_cntl, fp2_gen_cntl;
  
 	crtcGenCntl  = INREG( CRTC_GEN_CNTL);
 	crtcGenCntl2 = INREG( CRTC2_GEN_CNTL);
 
-	memRefreshCntl 	= INREG( MEM_REFRESH_CNTL);
 	crtc_more_cntl 	= INREG( CRTC_MORE_CNTL);
 	fp_gen_cntl 	= INREG( FP_GEN_CNTL);
 	fp2_gen_cntl 	= INREG( FP2_GEN_CNTL);
  
 
-	OUTREG( CRTC_MORE_CNTL, 	0);
-	OUTREG( FP_GEN_CNTL, 	0);
-	OUTREG( FP2_GEN_CNTL, 	0);
+	OUTREG( CRTC_MORE_CNTL, 0);
+	OUTREG( FP_GEN_CNTL, 0);
+	OUTREG( FP2_GEN_CNTL,0);
  
 	OUTREG( CRTC_GEN_CNTL,  (crtcGenCntl | CRTC_GEN_CNTL__CRTC_DISP_REQ_EN_B) );
 	OUTREG( CRTC2_GEN_CNTL, (crtcGenCntl2 | CRTC2_GEN_CNTL__CRTC2_DISP_REQ_EN_B) );
   
-	/* Disable refresh */
-	OUTREG( MEM_REFRESH_CNTL, memRefreshCntl | MEM_REFRESH_CNTL__MEM_REFRESH_DIS);
+	/* This is the code for the Aluminium PowerBooks M10 */
+	if (rinfo->family == CHIP_FAMILY_RV350) {
+		u32 sdram_mode_reg = rinfo->save_regs[35];
+		static u32 default_mrtable[] =
+			{ 0x21320032,
+			  0x21321000, 0xa1321000, 0x21321000, 0xffffffff,
+			  0x21320032, 0xa1320032, 0x21320032, 0xffffffff,
+			  0x21321002, 0xa1321002, 0x21321002, 0xffffffff,
+			  0x21320132, 0xa1320132, 0x21320132, 0xffffffff,
+			  0x21320032, 0xa1320032, 0x21320032, 0xffffffff,
+			  0x31320032 };
+
+		u32 *mrtable = default_mrtable;
+		int i, mrtable_size = ARRAY_SIZE(default_mrtable);
+
+		mdelay(30);
+
+		/* Disable refresh */
+		memRefreshCntl 	= INREG( MEM_REFRESH_CNTL)
+			& ~MEM_REFRESH_CNTL__MEM_REFRESH_DIS;
+		OUTREG( MEM_REFRESH_CNTL, memRefreshCntl
+			| MEM_REFRESH_CNTL__MEM_REFRESH_DIS);
+
+		/* Configure and enable M & SPLLs */
+       		radeon_pm_enable_dll_m10(rinfo);
+		radeon_pm_yclk_mclk_sync_m10(rinfo);
+
+#ifdef CONFIG_PPC_OF
+		if (rinfo->of_node != NULL) {
+			int size;
+
+			mrtable = (u32 *)get_property(rinfo->of_node, "ATY,MRT", &size);
+			if (mrtable)
+				mrtable_size = size >> 2;
+			else
+				mrtable = default_mrtable;
+		}
+#endif /* CONFIG_PPC_OF */
+
+		/* Program the SDRAM */
+		sdram_mode_reg = mrtable[0];
+		OUTREG(MEM_SDRAM_MODE_REG, sdram_mode_reg);
+		for (i = 0; i < mrtable_size; i++) {
+			if (mrtable[i] == 0xffffffffu)
+				radeon_pm_m10_program_mode_wait(rinfo);
+			else {
+				sdram_mode_reg &= ~(MEM_SDRAM_MODE_REG__MEM_MODE_REG_MASK
+						    | MEM_SDRAM_MODE_REG__MC_INIT_COMPLETE
+						    | MEM_SDRAM_MODE_REG__MEM_SDRAM_RESET);
+				sdram_mode_reg |= mrtable[i];
+
+				OUTREG(MEM_SDRAM_MODE_REG, sdram_mode_reg);
+				mdelay(1);
+			}
+		}
+
+		/* Restore memory refresh */
+		OUTREG(MEM_REFRESH_CNTL, memRefreshCntl);
+		mdelay(30);
+
+	}
+	/* Here come the desktop RV200 "QW" card */
+	else if (!rinfo->is_mobility && rinfo->family == CHIP_FAMILY_RV200) {
+		/* Disable refresh */
+		memRefreshCntl 	= INREG( MEM_REFRESH_CNTL)
+			& ~MEM_REFRESH_CNTL__MEM_REFRESH_DIS;
+		OUTREG(MEM_REFRESH_CNTL, memRefreshCntl
+		       | MEM_REFRESH_CNTL__MEM_REFRESH_DIS);
+		mdelay(30);
+
+		/* Reset memory */
+		OUTREG(MEM_SDRAM_MODE_REG,
+		       INREG( MEM_SDRAM_MODE_REG) & ~MEM_SDRAM_MODE_REG__MC_INIT_COMPLETE);
+
+		radeon_pm_program_mode_reg(rinfo, 0x2002, 2);
+		radeon_pm_program_mode_reg(rinfo, 0x0132, 2);
+		radeon_pm_program_mode_reg(rinfo, 0x0032, 2);
+
+		OUTREG(MEM_SDRAM_MODE_REG,
+		       INREG(MEM_SDRAM_MODE_REG) | MEM_SDRAM_MODE_REG__MC_INIT_COMPLETE);
+
+		OUTREG( MEM_REFRESH_CNTL, 	memRefreshCntl);
+
+	}
+	/* The M6 */
+	else if (rinfo->is_mobility && rinfo->family == CHIP_FAMILY_RV100) {
+		/* Disable refresh */
+		memRefreshCntl = INREG(EXT_MEM_CNTL) & ~(1 << 20);
+		OUTREG( EXT_MEM_CNTL, memRefreshCntl | (1 << 20));
  
-	/* Reset memory */
-	OUTREG( MEM_SDRAM_MODE_REG,
-		INREG( MEM_SDRAM_MODE_REG) & ~MEM_SDRAM_MODE_REG__MC_INIT_COMPLETE); // Init  Not Complete
+		/* Reset memory */
+		OUTREG( MEM_SDRAM_MODE_REG,
+			INREG( MEM_SDRAM_MODE_REG)
+			& ~MEM_SDRAM_MODE_REG__MC_INIT_COMPLETE);
 
-	/* DLL */
-	radeon_pm_enable_dll(rinfo);
+		/* DLL */
+		radeon_pm_enable_dll(rinfo);
 
-	// MLCK /YCLK sync 
-	radeon_pm_yclk_mclk_sync(rinfo);
+		/* MLCK / YCLK sync */
+		radeon_pm_yclk_mclk_sync(rinfo);
 
-       	/* M6, M7 and M9 so far ... */
-	if (rinfo->is_mobility && rinfo->family <= CHIP_FAMILY_RV250) {
+		/* Program Mode Register */
 		radeon_pm_program_mode_reg(rinfo, 0x2000, 1);   
 		radeon_pm_program_mode_reg(rinfo, 0x2001, 1);   
 		radeon_pm_program_mode_reg(rinfo, 0x2002, 1);   
 		radeon_pm_program_mode_reg(rinfo, 0x0132, 1);   
 		radeon_pm_program_mode_reg(rinfo, 0x0032, 1); 
-	}	
 
-	OUTREG( MEM_SDRAM_MODE_REG,
-		INREG( MEM_SDRAM_MODE_REG) |  MEM_SDRAM_MODE_REG__MC_INIT_COMPLETE); // Init Complete
+		/* Complete & re-enable refresh */
+		OUTREG( MEM_SDRAM_MODE_REG,
+			INREG( MEM_SDRAM_MODE_REG) | MEM_SDRAM_MODE_REG__MC_INIT_COMPLETE);
 
-	OUTREG( MEM_REFRESH_CNTL, 	memRefreshCntl);
+		OUTREG(EXT_MEM_CNTL, memRefreshCntl);
+	}
+	/* And finally, the M7..M9 models, including M9+ (RV280) */
+	else if (rinfo->is_mobility) {
+
+		/* Disable refresh */
+		memRefreshCntl 	= INREG( MEM_REFRESH_CNTL)
+			& ~MEM_REFRESH_CNTL__MEM_REFRESH_DIS;
+		OUTREG( MEM_REFRESH_CNTL, memRefreshCntl
+			| MEM_REFRESH_CNTL__MEM_REFRESH_DIS);
+
+		/* Reset memory */
+		OUTREG( MEM_SDRAM_MODE_REG,
+			INREG( MEM_SDRAM_MODE_REG)
+			& ~MEM_SDRAM_MODE_REG__MC_INIT_COMPLETE);
+
+		/* DLL */
+		radeon_pm_enable_dll(rinfo);
+
+		/* MLCK / YCLK sync */
+		radeon_pm_yclk_mclk_sync(rinfo);
+
+		/* M6, M7 and M9 so far ... */
+		if (rinfo->family <= CHIP_FAMILY_RV250) {
+			radeon_pm_program_mode_reg(rinfo, 0x2000, 1);
+			radeon_pm_program_mode_reg(rinfo, 0x2001, 1);
+			radeon_pm_program_mode_reg(rinfo, 0x2002, 1);
+			radeon_pm_program_mode_reg(rinfo, 0x0132, 1);
+			radeon_pm_program_mode_reg(rinfo, 0x0032, 1);
+		}
+		/* M9+ (iBook G4) */
+		else if (rinfo->family == CHIP_FAMILY_RV280) {
+			radeon_pm_program_mode_reg(rinfo, 0x2000, 1);
+			radeon_pm_program_mode_reg(rinfo, 0x0132, 1);
+			radeon_pm_program_mode_reg(rinfo, 0x0032, 1);
+		}
+
+		/* Complete & re-enable refresh */
+		OUTREG( MEM_SDRAM_MODE_REG,
+			INREG( MEM_SDRAM_MODE_REG) | MEM_SDRAM_MODE_REG__MC_INIT_COMPLETE);
+
+		OUTREG( MEM_REFRESH_CNTL, 	memRefreshCntl);
+	}
 
 	OUTREG( CRTC_GEN_CNTL, 		crtcGenCntl);
 	OUTREG( CRTC2_GEN_CNTL, 	crtcGenCntl2);
@@ -777,10 +1321,1076 @@
 	mdelay( 15);
 }
 
+#ifdef CONFIG_PPC_OF
+
+static void radeon_pm_reset_pad_ctlr_strength(struct radeonfb_info *rinfo)
+{
+	u32 tmp, tmp2;
+	int i,j;
+
+	/* Reset the PAD_CTLR_STRENGTH & wait for it to be stable */
+	INREG(PAD_CTLR_STRENGTH);
+	OUTREG(PAD_CTLR_STRENGTH, INREG(PAD_CTLR_STRENGTH) & ~PAD_MANUAL_OVERRIDE);
+	tmp = INREG(PAD_CTLR_STRENGTH);
+	for (i = j = 0; i < 65; ++i) {
+		mdelay(1);
+		tmp2 = INREG(PAD_CTLR_STRENGTH);
+		if (tmp != tmp2) {
+			tmp = tmp2;
+			i = 0;
+			j++;
+			if (j > 10) {
+				printk(KERN_WARNING "radeon: PAD_CTLR_STRENGTH doesn't "
+				       "stabilize !\n");
+				break;
+			}
+		}
+	}
+}
+
+static void radeon_pm_all_ppls_off(struct radeonfb_info *rinfo)
+{
+	u32 tmp;
+
+	tmp = INPLL(pllPPLL_CNTL);
+	OUTPLL(pllPPLL_CNTL, tmp | 0x3);
+	tmp = INPLL(pllP2PLL_CNTL);
+	OUTPLL(pllP2PLL_CNTL, tmp | 0x3);
+	tmp = INPLL(pllSPLL_CNTL);
+	OUTPLL(pllSPLL_CNTL, tmp | 0x3);
+	tmp = INPLL(pllMPLL_CNTL);
+	OUTPLL(pllMPLL_CNTL, tmp | 0x3);
+}
+
+static void radeon_pm_start_mclk_sclk(struct radeonfb_info *rinfo)
+{
+	u32 tmp;
+
+	/* Switch SPLL to PCI source */
+	tmp = INPLL(pllSCLK_CNTL);
+	OUTPLL(pllSCLK_CNTL, tmp & ~SCLK_CNTL__SCLK_SRC_SEL_MASK);
+
+	/* Reconfigure SPLL charge pump, VCO gain, duty cycle */
+	tmp = INPLL(pllSPLL_CNTL);
+	OUTREG8(CLOCK_CNTL_INDEX, pllSPLL_CNTL + PLL_WR_EN);
+	OUTREG8(CLOCK_CNTL_DATA + 1, (tmp >> 8) & 0xff);
+
+	/* Set SPLL feedback divider */
+	tmp = INPLL(pllM_SPLL_REF_FB_DIV);
+	tmp = (tmp & 0xff00fffful) | (rinfo->save_regs[77] & 0x00ff0000ul);
+	OUTPLL(pllM_SPLL_REF_FB_DIV, tmp);
+
+	/* Power up SPLL */
+	tmp = INPLL(pllSPLL_CNTL);
+	OUTPLL(pllSPLL_CNTL, tmp & ~1);
+	(void)INPLL(pllSPLL_CNTL);
+
+	mdelay(10);
+
+	/* Release SPLL reset */
+	tmp = INPLL(pllSPLL_CNTL);
+	OUTPLL(pllSPLL_CNTL, tmp & ~0x2);
+	(void)INPLL(pllSPLL_CNTL);
+
+	mdelay(10);
+
+	/* Select SCLK source  */
+	tmp = INPLL(pllSCLK_CNTL);
+	tmp &= ~SCLK_CNTL__SCLK_SRC_SEL_MASK;
+	tmp |= rinfo->save_regs[3] & SCLK_CNTL__SCLK_SRC_SEL_MASK;
+	OUTPLL(pllSCLK_CNTL, tmp);
+	(void)INPLL(pllSCLK_CNTL);
+
+	mdelay(10);
+
+	/* Reconfigure MPLL charge pump, VCO gain, duty cycle */
+	tmp = INPLL(pllMPLL_CNTL);
+	OUTREG8(CLOCK_CNTL_INDEX, pllMPLL_CNTL + PLL_WR_EN);
+	OUTREG8(CLOCK_CNTL_DATA + 1, (tmp >> 8) & 0xff);
+
+	/* Set MPLL feedback divider */
+	tmp = INPLL(pllM_SPLL_REF_FB_DIV);
+	tmp = (tmp & 0xffff00fful) | (rinfo->save_regs[77] & 0x0000ff00ul);
+
+	OUTPLL(pllM_SPLL_REF_FB_DIV, tmp);
+	/* Power up MPLL */
+	tmp = INPLL(pllMPLL_CNTL);
+	OUTPLL(pllMPLL_CNTL, tmp & ~0x2);
+	(void)INPLL(pllMPLL_CNTL);
+
+	mdelay(10);
+
+	/* Un-reset MPLL */
+	tmp = INPLL(pllMPLL_CNTL);
+	OUTPLL(pllMPLL_CNTL, tmp & ~0x1);
+	(void)INPLL(pllMPLL_CNTL);
+
+	mdelay(10);
+
+	/* Select source for MCLK */
+	tmp = INPLL(pllMCLK_CNTL);
+	tmp |= rinfo->save_regs[2] & 0xffff;
+	OUTPLL(pllMCLK_CNTL, tmp);
+	(void)INPLL(pllMCLK_CNTL);
+
+	mdelay(10);
+}
+
+static void radeon_pm_m10_disable_spread_spectrum(struct radeonfb_info *rinfo)
+{
+	u32 r2ec;
+
+	/* GACK ! I though we didn't have a DDA on Radeon's anymore
+	 * here we rewrite with the same value, ... I suppose we clear
+	 * some bits that are already clear ? Or maybe this 0x2ec
+	 * register is something new ?
+	 */
+	mdelay(20);
+	r2ec = INREG(VGA_DDA_ON_OFF);
+	OUTREG(VGA_DDA_ON_OFF, r2ec);
+	mdelay(1);
+
+	/* Spread spectrum PLLL off */
+	OUTPLL(pllSSPLL_CNTL, 0xbf03);
+
+	/* Spread spectrum disabled */
+	OUTPLL(pllSS_INT_CNTL, rinfo->save_regs[90] & ~3);
+
+	/* The trace shows read & rewrite of LVDS_PLL_CNTL here with same
+	 * value, not sure what for...
+	 */
+
+	r2ec |= 0x3f0;
+	OUTREG(VGA_DDA_ON_OFF, r2ec);
+	mdelay(1);
+}
+
+static void radeon_pm_m10_enable_lvds_spread_spectrum(struct radeonfb_info *rinfo)
+{
+	u32 r2ec, tmp;
+
+	/* GACK (bis) ! I though we didn't have a DDA on Radeon's anymore
+	 * here we rewrite with the same value, ... I suppose we clear/set
+	 * some bits that are already clear/set ?
+	 */
+	r2ec = INREG(VGA_DDA_ON_OFF);
+	OUTREG(VGA_DDA_ON_OFF, r2ec);
+	mdelay(1);
+
+	/* Enable spread spectrum */
+	OUTPLL(pllSSPLL_CNTL, rinfo->save_regs[43] | 3);
+	mdelay(3);
+
+	OUTPLL(pllSSPLL_REF_DIV, rinfo->save_regs[44]);
+	OUTPLL(pllSSPLL_DIV_0, rinfo->save_regs[45]);
+	tmp = INPLL(pllSSPLL_CNTL);
+	OUTPLL(pllSSPLL_CNTL, tmp & ~0x2);
+	mdelay(6);
+	tmp = INPLL(pllSSPLL_CNTL);
+	OUTPLL(pllSSPLL_CNTL, tmp & ~0x1);
+	mdelay(5);
+
+       	OUTPLL(pllSS_INT_CNTL, rinfo->save_regs[90]);
+
+	r2ec |= 8;
+	OUTREG(VGA_DDA_ON_OFF, r2ec);
+	mdelay(20);
+
+	/* Enable LVDS interface */
+	tmp = INREG(LVDS_GEN_CNTL);
+	OUTREG(LVDS_GEN_CNTL, tmp | LVDS_EN);
+
+	/* Enable LVDS_PLL */
+	tmp = INREG(LVDS_PLL_CNTL);
+	tmp &= ~0x30000;
+	tmp |= 0x10000;
+	OUTREG(LVDS_PLL_CNTL, tmp);
+
+	OUTPLL(pllSCLK_MORE_CNTL, rinfo->save_regs[34]);
+	OUTPLL(pllSS_TST_CNTL, rinfo->save_regs[91]);
+
+	/* The trace reads that one here, waiting for something to settle down ? */
+	INREG(RBBM_STATUS);
+
+	/* Ugh ? SS_TST_DEC is supposed to be a read register in the
+	 * R300 register spec at least...
+	 */
+	tmp = INPLL(pllSS_TST_CNTL);
+	tmp |= 0x00400000;
+	OUTPLL(pllSS_TST_CNTL, tmp);
+}
+
+static void radeon_pm_restore_pixel_pll(struct radeonfb_info *rinfo)
+{
+	u32 tmp;
+
+	OUTREG8(CLOCK_CNTL_INDEX, pllHTOTAL_CNTL + PLL_WR_EN);
+	OUTREG8(CLOCK_CNTL_DATA, 0);
+
+	tmp = INPLL(pllVCLK_ECP_CNTL);
+	OUTPLL(pllVCLK_ECP_CNTL, tmp | 0x80);
+	mdelay(5);
+
+	tmp = INPLL(pllPPLL_REF_DIV);
+	tmp = (tmp & ~PPLL_REF_DIV_MASK) | rinfo->pll.ref_div;
+	OUTPLL(pllPPLL_REF_DIV, tmp);
+	INPLL(pllPPLL_REF_DIV);
+
+	/* Reconfigure SPLL charge pump, VCO gain, duty cycle,
+	 * probably useless since we already did it ...
+	 */
+	tmp = INPLL(pllPPLL_CNTL);
+	OUTREG8(CLOCK_CNTL_INDEX, pllSPLL_CNTL + PLL_WR_EN);
+	OUTREG8(CLOCK_CNTL_DATA + 1, (tmp >> 8) & 0xff);
+
+	/* Not sure what was intended here ... */
+	tmp = INREG(CLOCK_CNTL_INDEX);
+	OUTREG(CLOCK_CNTL_INDEX, tmp);
+
+	/* Restore our "reference" PPLL divider set by firmware
+	 * according to proper spread spectrum calculations
+	 */
+	OUTPLL(pllPPLL_DIV_0, rinfo->save_regs[92]);
+
+	tmp = INPLL(pllPPLL_CNTL);
+	OUTPLL(pllPPLL_CNTL, tmp & ~0x2);
+	mdelay(5);
+
+	tmp = INPLL(pllPPLL_CNTL);
+	OUTPLL(pllPPLL_CNTL, tmp & ~0x1);
+	mdelay(5);
+
+	tmp = INPLL(pllVCLK_ECP_CNTL);
+	OUTPLL(pllVCLK_ECP_CNTL, tmp | 3);
+	mdelay(5);
+
+	tmp = INPLL(pllVCLK_ECP_CNTL);
+	OUTPLL(pllVCLK_ECP_CNTL, tmp | 3);
+	mdelay(5);
+
+	/* Switch pixel clock to firmware default div 0 */
+	OUTREG8(CLOCK_CNTL_INDEX+1, 0);
+}
+
+static void radeon_pm_m10_reconfigure_mc(struct radeonfb_info *rinfo)
+{
+	OUTREG(MC_CNTL, rinfo->save_regs[46]);
+	OUTREG(MC_INIT_GFX_LAT_TIMER, rinfo->save_regs[47]);
+	OUTREG(MC_INIT_MISC_LAT_TIMER, rinfo->save_regs[48]);
+	OUTREG(MEM_SDRAM_MODE_REG,
+	       rinfo->save_regs[35] & ~MEM_SDRAM_MODE_REG__MC_INIT_COMPLETE);
+	OUTREG(MC_TIMING_CNTL, rinfo->save_regs[49]);
+	OUTREG(MEM_REFRESH_CNTL, rinfo->save_regs[42]);
+	OUTREG(MC_READ_CNTL_AB, rinfo->save_regs[50]);
+	OUTREG(MC_CHIP_IO_OE_CNTL_AB, rinfo->save_regs[52]);
+	OUTREG(MC_IOPAD_CNTL, rinfo->save_regs[51]);
+	OUTREG(MC_DEBUG, rinfo->save_regs[53]);
+
+	OUTMC(rinfo, ixR300_MC_MC_INIT_WR_LAT_TIMER, rinfo->save_regs[58]);
+	OUTMC(rinfo, ixR300_MC_IMP_CNTL, rinfo->save_regs[59]);
+	OUTMC(rinfo, ixR300_MC_CHP_IO_CNTL_C0, rinfo->save_regs[60]);
+	OUTMC(rinfo, ixR300_MC_CHP_IO_CNTL_C1, rinfo->save_regs[61]);
+	OUTMC(rinfo, ixR300_MC_CHP_IO_CNTL_D0, rinfo->save_regs[62]);
+	OUTMC(rinfo, ixR300_MC_CHP_IO_CNTL_D1, rinfo->save_regs[63]);
+	OUTMC(rinfo, ixR300_MC_BIST_CNTL_3, rinfo->save_regs[64]);
+	OUTMC(rinfo, ixR300_MC_CHP_IO_CNTL_A0, rinfo->save_regs[65]);
+	OUTMC(rinfo, ixR300_MC_CHP_IO_CNTL_A1, rinfo->save_regs[66]);
+	OUTMC(rinfo, ixR300_MC_CHP_IO_CNTL_B0, rinfo->save_regs[67]);
+	OUTMC(rinfo, ixR300_MC_CHP_IO_CNTL_B1, rinfo->save_regs[68]);
+	OUTMC(rinfo, ixR300_MC_DEBUG_CNTL, rinfo->save_regs[69]);
+	OUTMC(rinfo, ixR300_MC_DLL_CNTL, rinfo->save_regs[70]);
+	OUTMC(rinfo, ixR300_MC_IMP_CNTL_0, rinfo->save_regs[71]);
+	OUTMC(rinfo, ixR300_MC_ELPIDA_CNTL, rinfo->save_regs[72]);
+	OUTMC(rinfo, ixR300_MC_READ_CNTL_CD, rinfo->save_regs[96]);
+	OUTREG(MC_IND_INDEX, 0);
+}
+
+static void radeon_reinitialize_M10(struct radeonfb_info *rinfo)
+{
+	u32 tmp, i;
+
+	/* Restore a bunch of registers first */
+	OUTREG(MC_AGP_LOCATION, rinfo->save_regs[32]);
+	OUTREG(DISPLAY_BASE_ADDR, rinfo->save_regs[31]);
+	OUTREG(CRTC2_DISPLAY_BASE_ADDR, rinfo->save_regs[33]);
+	OUTREG(MC_FB_LOCATION, rinfo->save_regs[30]);
+	OUTREG(OV0_BASE_ADDR, rinfo->save_regs[80]);
+	OUTREG(CONFIG_MEMSIZE, rinfo->video_ram);
+	OUTREG(BUS_CNTL, rinfo->save_regs[36]);
+	OUTREG(BUS_CNTL1, rinfo->save_regs[14]);
+	OUTREG(MPP_TB_CONFIG, rinfo->save_regs[37]);
+	OUTREG(FCP_CNTL, rinfo->save_regs[38]);
+	OUTREG(RBBM_CNTL, rinfo->save_regs[39]);
+	OUTREG(DAC_CNTL, rinfo->save_regs[40]);
+	OUTREG(DAC_MACRO_CNTL, (INREG(DAC_MACRO_CNTL) & ~0x6) | 8);
+	OUTREG(DAC_MACRO_CNTL, (INREG(DAC_MACRO_CNTL) & ~0x6) | 8);
+
+	/* Hrm... */
+	OUTREG(DAC_CNTL2, INREG(DAC_CNTL2) | DAC2_EXPAND_MODE);
+
+	/* Reset the PAD CTLR */
+	radeon_pm_reset_pad_ctlr_strength(rinfo);
+
+	/* Some PLLs are Read & written identically in the trace here...
+	 * I suppose it's actually to switch them all off & reset,
+	 * let's assume off is what we want. I'm just doing that for all major PLLs now.
+	 */
+	radeon_pm_all_ppls_off(rinfo);
+
+	/* Clear tiling, reset swappers */
+	INREG(SURFACE_CNTL);
+	OUTREG(SURFACE_CNTL, 0);
+
+	/* Some black magic with TV_DAC_CNTL, we should restore those from backups
+	 * rather than hard coding...
+	 */
+	tmp = INREG(TV_DAC_CNTL) & ~TV_DAC_CNTL_BGADJ_MASK;
+	tmp |= 8 << TV_DAC_CNTL_BGADJ__SHIFT;
+	OUTREG(TV_DAC_CNTL, tmp);
+
+	tmp = INREG(TV_DAC_CNTL) & ~TV_DAC_CNTL_DACADJ_MASK;
+	tmp |= 7 << TV_DAC_CNTL_DACADJ__SHIFT;
+	OUTREG(TV_DAC_CNTL, tmp);
+
+	/* More registers restored */
+	OUTREG(AGP_CNTL, rinfo->save_regs[16]);
+	OUTREG(HOST_PATH_CNTL, rinfo->save_regs[41]);
+	OUTREG(DISP_MISC_CNTL, rinfo->save_regs[9]);
+
+	/* Hrmmm ... What is that ? */
+	tmp = rinfo->save_regs[1]
+		& ~(CLK_PWRMGT_CNTL__ACTIVE_HILO_LAT_MASK |
+		    CLK_PWRMGT_CNTL__MC_BUSY);
+	OUTPLL(pllCLK_PWRMGT_CNTL, tmp);
+
+	OUTREG(PAD_CTLR_MISC, rinfo->save_regs[56]);
+	OUTREG(FW_CNTL, rinfo->save_regs[57]);
+	OUTREG(HDP_DEBUG, rinfo->save_regs[96]);
+	OUTREG(PAMAC0_DLY_CNTL, rinfo->save_regs[54]);
+	OUTREG(PAMAC1_DLY_CNTL, rinfo->save_regs[55]);
+	OUTREG(PAMAC2_DLY_CNTL, rinfo->save_regs[79]);
+
+	/* Restore Memory Controller configuration */
+	radeon_pm_m10_reconfigure_mc(rinfo);
+
+	/* Make sure CRTC's dont touch memory */
+	OUTREG(CRTC_GEN_CNTL, INREG(CRTC_GEN_CNTL)
+	       | CRTC_GEN_CNTL__CRTC_DISP_REQ_EN_B);
+	OUTREG(CRTC2_GEN_CNTL, INREG(CRTC2_GEN_CNTL)
+	       | CRTC2_GEN_CNTL__CRTC2_DISP_REQ_EN_B);
+	mdelay(30);
+
+	/* Disable SDRAM refresh */
+	OUTREG(MEM_REFRESH_CNTL, INREG(MEM_REFRESH_CNTL)
+	       | MEM_REFRESH_CNTL__MEM_REFRESH_DIS);
+
+	/* Restore XTALIN routing (CLK_PIN_CNTL) */
+	OUTPLL(pllCLK_PIN_CNTL, rinfo->save_regs[4]);
+
+	/* Switch MCLK, YCLK and SCLK PLLs to PCI source & force them ON */
+	tmp = rinfo->save_regs[2] & 0xff000000;
+	tmp |=	MCLK_CNTL__FORCE_MCLKA |
+		MCLK_CNTL__FORCE_MCLKB |
+		MCLK_CNTL__FORCE_YCLKA |
+		MCLK_CNTL__FORCE_YCLKB |
+		MCLK_CNTL__FORCE_MC;
+	OUTPLL(pllMCLK_CNTL, tmp);
+
+	/* Force all clocks on in SCLK */
+	tmp = INPLL(pllSCLK_CNTL);
+	tmp |=	SCLK_CNTL__FORCE_DISP2|
+		SCLK_CNTL__FORCE_CP|
+		SCLK_CNTL__FORCE_HDP|
+		SCLK_CNTL__FORCE_DISP1|
+		SCLK_CNTL__FORCE_TOP|
+		SCLK_CNTL__FORCE_E2|
+		SCLK_CNTL__FORCE_SE|
+		SCLK_CNTL__FORCE_IDCT|
+		SCLK_CNTL__FORCE_VIP|
+		SCLK_CNTL__FORCE_PB|
+		SCLK_CNTL__FORCE_TAM|
+		SCLK_CNTL__FORCE_TDM|
+		SCLK_CNTL__FORCE_RB|
+		SCLK_CNTL__FORCE_TV_SCLK|
+		SCLK_CNTL__FORCE_SUBPIC|
+		SCLK_CNTL__FORCE_OV0;
+	tmp |=	SCLK_CNTL__CP_MAX_DYN_STOP_LAT  |
+		SCLK_CNTL__HDP_MAX_DYN_STOP_LAT |
+		SCLK_CNTL__TV_MAX_DYN_STOP_LAT  |
+		SCLK_CNTL__E2_MAX_DYN_STOP_LAT  |
+		SCLK_CNTL__SE_MAX_DYN_STOP_LAT  |
+		SCLK_CNTL__IDCT_MAX_DYN_STOP_LAT|
+		SCLK_CNTL__VIP_MAX_DYN_STOP_LAT |
+		SCLK_CNTL__RE_MAX_DYN_STOP_LAT  |
+		SCLK_CNTL__PB_MAX_DYN_STOP_LAT  |
+		SCLK_CNTL__TAM_MAX_DYN_STOP_LAT |
+		SCLK_CNTL__TDM_MAX_DYN_STOP_LAT |
+		SCLK_CNTL__RB_MAX_DYN_STOP_LAT;
+	OUTPLL(pllSCLK_CNTL, tmp);
+
+	OUTPLL(pllVCLK_ECP_CNTL, 0);
+	OUTPLL(pllPIXCLKS_CNTL, 0);
+	OUTPLL(pllMCLK_MISC,
+	       MCLK_MISC__MC_MCLK_MAX_DYN_STOP_LAT |
+	       MCLK_MISC__IO_MCLK_MAX_DYN_STOP_LAT);
+
+	mdelay(5);
+
+	/* Restore the M_SPLL_REF_FB_DIV, MPLL_AUX_CNTL and SPLL_AUX_CNTL values */
+	OUTPLL(pllM_SPLL_REF_FB_DIV, rinfo->save_regs[77]);
+	OUTPLL(pllMPLL_AUX_CNTL, rinfo->save_regs[75]);
+	OUTPLL(pllSPLL_AUX_CNTL, rinfo->save_regs[76]);
+
+	/* Now restore the major PLLs settings, keeping them off & reset though */
+	OUTPLL(pllPPLL_CNTL, rinfo->save_regs[93] | 0x3);
+	OUTPLL(pllP2PLL_CNTL, rinfo->save_regs[8] | 0x3);
+	OUTPLL(pllMPLL_CNTL, rinfo->save_regs[73] | 0x03);
+	OUTPLL(pllSPLL_CNTL, rinfo->save_regs[74] | 0x03);
+
+	/* Restore MC DLL state and switch it off/reset too  */
+	OUTMC(rinfo, ixR300_MC_DLL_CNTL, rinfo->save_regs[70]);
+
+	/* Switch MDLL off & reset */
+	OUTPLL(pllMDLL_RDCKA, rinfo->save_regs[98] | 0xff);
+	mdelay(5);
+
+	/* Setup some black magic bits in PLL_PWRMGT_CNTL. Hrm... we saved
+	 * 0xa1100007... and MacOS writes 0xa1000007 ..
+	 */
+	OUTPLL(pllPLL_PWRMGT_CNTL, rinfo->save_regs[0]);
+
+	/* Restore more stuffs */
+	OUTPLL(pllHTOTAL_CNTL, 0);
+	OUTPLL(pllHTOTAL2_CNTL, 0);
+
+	/* More PLL initial configuration */
+	tmp = INPLL(pllSCLK_CNTL2); /* What for ? */
+	OUTPLL(pllSCLK_CNTL2, tmp);
+
+	tmp = INPLL(pllSCLK_MORE_CNTL);
+	tmp |= 	SCLK_MORE_CNTL__FORCE_DISPREGS |	/* a guess */
+		SCLK_MORE_CNTL__FORCE_MC_GUI |
+		SCLK_MORE_CNTL__FORCE_MC_HOST;
+	OUTPLL(pllSCLK_MORE_CNTL, tmp);
+
+	/* Now we actually start MCLK and SCLK */
+	radeon_pm_start_mclk_sclk(rinfo);
+
+	/* Full reset sdrams, this also re-inits the MDLL */
+	radeon_pm_full_reset_sdram(rinfo);
+
+	/* Fill palettes */
+	OUTREG(DAC_CNTL2, INREG(DAC_CNTL2) | 0x20);
+	for (i=0; i<256; i++)
+		OUTREG(PALETTE_30_DATA, 0x15555555);
+	OUTREG(DAC_CNTL2, INREG(DAC_CNTL2) & ~20);
+	udelay(20);
+	for (i=0; i<256; i++)
+		OUTREG(PALETTE_30_DATA, 0x15555555);
+
+	OUTREG(DAC_CNTL2, INREG(DAC_CNTL2) & ~0x20);
+	mdelay(3);
+
+	/* Restore TMDS */
+	OUTREG(FP_GEN_CNTL, rinfo->save_regs[82]);
+	OUTREG(FP2_GEN_CNTL, rinfo->save_regs[83]);
+
+	/* Set LVDS registers but keep interface & pll down */
+	OUTREG(LVDS_GEN_CNTL, rinfo->save_regs[11] &
+	       ~(LVDS_EN | LVDS_ON | LVDS_DIGON | LVDS_BLON | LVDS_BL_MOD_EN));
+	OUTREG(LVDS_PLL_CNTL, (rinfo->save_regs[12] & ~0xf0000) | 0x20000);
+
+	OUTREG(DISP_OUTPUT_CNTL, rinfo->save_regs[86]);
+
+	/* Restore GPIOPAD state */
+	OUTREG(GPIOPAD_A, rinfo->save_regs[19]);
+	OUTREG(GPIOPAD_EN, rinfo->save_regs[20]);
+	OUTREG(GPIOPAD_MASK, rinfo->save_regs[21]);
+
+	/* write some stuff to the framebuffer... */
+	for (i = 0; i < 0x8000; ++i)
+		writeb(0, rinfo->fb_base + i);
+
+	mdelay(40);
+	OUTREG(LVDS_GEN_CNTL, INREG(LVDS_GEN_CNTL) | LVDS_DIGON | LVDS_ON);
+	mdelay(40);
+
+	/* Restore a few more things */
+	OUTREG(GRPH_BUFFER_CNTL, rinfo->save_regs[94]);
+	OUTREG(GRPH2_BUFFER_CNTL, rinfo->save_regs[95]);
+
+	/* Take care of spread spectrum & PPLLs now */
+	radeon_pm_m10_disable_spread_spectrum(rinfo);
+	radeon_pm_restore_pixel_pll(rinfo);
+
+	/* GRRRR... I can't figure out the proper LVDS power sequence, and the
+	 * code I have for blank/unblank doesn't quite work on some laptop models
+	 * it seems ... Hrm. What I have here works most of the time ...
+	 */
+	radeon_pm_m10_enable_lvds_spread_spectrum(rinfo);
+}
+
+static void radeon_pm_m9p_reconfigure_mc(struct radeonfb_info *rinfo)
+{
+	OUTREG(MC_CNTL, rinfo->save_regs[46]);
+	OUTREG(MC_INIT_GFX_LAT_TIMER, rinfo->save_regs[47]);
+	OUTREG(MC_INIT_MISC_LAT_TIMER, rinfo->save_regs[48]);
+	OUTREG(MEM_SDRAM_MODE_REG,
+	       rinfo->save_regs[35] & ~MEM_SDRAM_MODE_REG__MC_INIT_COMPLETE);
+	OUTREG(MC_TIMING_CNTL, rinfo->save_regs[49]);
+	OUTREG(MC_READ_CNTL_AB, rinfo->save_regs[50]);
+	OUTREG(MEM_REFRESH_CNTL, rinfo->save_regs[42]);
+	OUTREG(MC_IOPAD_CNTL, rinfo->save_regs[51]);
+	OUTREG(MC_DEBUG, rinfo->save_regs[53]);
+	OUTREG(MC_CHIP_IO_OE_CNTL_AB, rinfo->save_regs[52]);
+
+	OUTMC(rinfo, ixMC_IMP_CNTL, rinfo->save_regs[59] /*0x00f460d6*/);
+	OUTMC(rinfo, ixMC_CHP_IO_CNTL_A0, rinfo->save_regs[65] /*0xfecfa666*/);
+	OUTMC(rinfo, ixMC_CHP_IO_CNTL_A1, rinfo->save_regs[66] /*0x141555ff*/);
+	OUTMC(rinfo, ixMC_CHP_IO_CNTL_B0, rinfo->save_regs[67] /*0xfecfa666*/);
+	OUTMC(rinfo, ixMC_CHP_IO_CNTL_B1, rinfo->save_regs[68] /*0x141555ff*/);
+	OUTMC(rinfo, ixMC_IMP_CNTL_0, rinfo->save_regs[71] /*0x00009249*/);
+	OUTREG(MC_IND_INDEX, 0);
+	OUTREG(CONFIG_MEMSIZE, rinfo->video_ram);
+
+	mdelay(20);
+}
+
+static void radeon_reinitialize_M9P(struct radeonfb_info *rinfo)
+{
+	u32 tmp, i;
+
+	/* Restore a bunch of registers first */
+	OUTREG(SURFACE_CNTL, rinfo->save_regs[29]);
+	OUTREG(MC_AGP_LOCATION, rinfo->save_regs[32]);
+	OUTREG(DISPLAY_BASE_ADDR, rinfo->save_regs[31]);
+	OUTREG(CRTC2_DISPLAY_BASE_ADDR, rinfo->save_regs[33]);
+	OUTREG(MC_FB_LOCATION, rinfo->save_regs[30]);
+	OUTREG(OV0_BASE_ADDR, rinfo->save_regs[80]);
+	OUTREG(BUS_CNTL, rinfo->save_regs[36]);
+	OUTREG(BUS_CNTL1, rinfo->save_regs[14]);
+	OUTREG(MPP_TB_CONFIG, rinfo->save_regs[37]);
+	OUTREG(FCP_CNTL, rinfo->save_regs[38]);
+	OUTREG(RBBM_CNTL, rinfo->save_regs[39]);
+
+	OUTREG(DAC_CNTL, rinfo->save_regs[40]);
+	OUTREG(DAC_CNTL2, INREG(DAC_CNTL2) | DAC2_EXPAND_MODE);
+
+	/* Reset the PAD CTLR */
+	radeon_pm_reset_pad_ctlr_strength(rinfo);
+
+	/* Some PLLs are Read & written identically in the trace here...
+	 * I suppose it's actually to switch them all off & reset,
+	 * let's assume off is what we want. I'm just doing that for all major PLLs now.
+	 */
+	radeon_pm_all_ppls_off(rinfo);
+
+	/* Clear tiling, reset swappers */
+	INREG(SURFACE_CNTL);
+	OUTREG(SURFACE_CNTL, 0);
+
+	/* Some black magic with TV_DAC_CNTL, we should restore those from backups
+	 * rather than hard coding...
+	 */
+	tmp = INREG(TV_DAC_CNTL) & ~TV_DAC_CNTL_BGADJ_MASK;
+	tmp |= 6 << TV_DAC_CNTL_BGADJ__SHIFT;
+	OUTREG(TV_DAC_CNTL, tmp);
+
+	tmp = INREG(TV_DAC_CNTL) & ~TV_DAC_CNTL_DACADJ_MASK;
+	tmp |= 6 << TV_DAC_CNTL_DACADJ__SHIFT;
+	OUTREG(TV_DAC_CNTL, tmp);
+
+	OUTPLL(pllAGP_PLL_CNTL, rinfo->save_regs[78]);
+
+	OUTREG(PAMAC0_DLY_CNTL, rinfo->save_regs[54]);
+	OUTREG(PAMAC1_DLY_CNTL, rinfo->save_regs[55]);
+	OUTREG(PAMAC2_DLY_CNTL, rinfo->save_regs[79]);
+
+	OUTREG(AGP_CNTL, rinfo->save_regs[16]);
+	OUTREG(HOST_PATH_CNTL, rinfo->save_regs[41]); /* MacOS sets that to 0 !!! */
+	OUTREG(DISP_MISC_CNTL, rinfo->save_regs[9]);
+
+	tmp  = rinfo->save_regs[1]
+		& ~(CLK_PWRMGT_CNTL__ACTIVE_HILO_LAT_MASK |
+		    CLK_PWRMGT_CNTL__MC_BUSY);
+	OUTPLL(pllCLK_PWRMGT_CNTL, tmp);
+
+	OUTREG(FW_CNTL, rinfo->save_regs[57]);
+
+	/* Disable SDRAM refresh */
+	OUTREG(MEM_REFRESH_CNTL, INREG(MEM_REFRESH_CNTL)
+	       | MEM_REFRESH_CNTL__MEM_REFRESH_DIS);
+
+	/* Restore XTALIN routing (CLK_PIN_CNTL) */
+       	OUTPLL(pllCLK_PIN_CNTL, rinfo->save_regs[4]);
+
+	/* Force MCLK to be PCI sourced and forced ON */
+	tmp = rinfo->save_regs[2] & 0xff000000;
+	tmp |=	MCLK_CNTL__FORCE_MCLKA |
+		MCLK_CNTL__FORCE_MCLKB |
+		MCLK_CNTL__FORCE_YCLKA |
+		MCLK_CNTL__FORCE_YCLKB |
+		MCLK_CNTL__FORCE_MC    |
+		MCLK_CNTL__FORCE_AIC;
+	OUTPLL(pllMCLK_CNTL, tmp);
+
+	/* Force SCLK to be PCI sourced with a bunch forced */
+	tmp =	0 |
+		SCLK_CNTL__FORCE_DISP2|
+		SCLK_CNTL__FORCE_CP|
+		SCLK_CNTL__FORCE_HDP|
+		SCLK_CNTL__FORCE_DISP1|
+		SCLK_CNTL__FORCE_TOP|
+		SCLK_CNTL__FORCE_E2|
+		SCLK_CNTL__FORCE_SE|
+		SCLK_CNTL__FORCE_IDCT|
+		SCLK_CNTL__FORCE_VIP|
+		SCLK_CNTL__FORCE_RE|
+		SCLK_CNTL__FORCE_PB|
+		SCLK_CNTL__FORCE_TAM|
+		SCLK_CNTL__FORCE_TDM|
+		SCLK_CNTL__FORCE_RB;
+	OUTPLL(pllSCLK_CNTL, tmp);
+
+	/* Clear VCLK_ECP_CNTL & PIXCLKS_CNTL  */
+	OUTPLL(pllVCLK_ECP_CNTL, 0);
+	OUTPLL(pllPIXCLKS_CNTL, 0);
+
+	/* Setup MCLK_MISC, non dynamic mode */
+	OUTPLL(pllMCLK_MISC,
+	       MCLK_MISC__MC_MCLK_MAX_DYN_STOP_LAT |
+	       MCLK_MISC__IO_MCLK_MAX_DYN_STOP_LAT);
+
+	mdelay(5);
+
+	/* Set back the default clock dividers */
+	OUTPLL(pllM_SPLL_REF_FB_DIV, rinfo->save_regs[77]);
+	OUTPLL(pllMPLL_AUX_CNTL, rinfo->save_regs[75]);
+	OUTPLL(pllSPLL_AUX_CNTL, rinfo->save_regs[76]);
+
+	/* PPLL and P2PLL default values & off */
+	OUTPLL(pllPPLL_CNTL, rinfo->save_regs[93] | 0x3);
+	OUTPLL(pllP2PLL_CNTL, rinfo->save_regs[8] | 0x3);
+
+	/* S and M PLLs are reset & off, configure them */
+	OUTPLL(pllMPLL_CNTL, rinfo->save_regs[73] | 0x03);
+	OUTPLL(pllSPLL_CNTL, rinfo->save_regs[74] | 0x03);
+
+	/* Default values for MDLL ... fixme */
+	OUTPLL(pllMDLL_CKO, 0x9c009c);
+	OUTPLL(pllMDLL_RDCKA, 0x08830883);
+	OUTPLL(pllMDLL_RDCKB, 0x08830883);
+	mdelay(5);
+
+	/* Restore PLL_PWRMGT_CNTL */ // XXXX
+	tmp = rinfo->save_regs[0];
+	tmp &= ~PLL_PWRMGT_CNTL_SU_SCLK_USE_BCLK;
+	tmp |= PLL_PWRMGT_CNTL_SU_MCLK_USE_BCLK;
+	OUTPLL(PLL_PWRMGT_CNTL,  tmp);
+
+	/* Clear HTOTAL_CNTL & HTOTAL2_CNTL */
+	OUTPLL(pllHTOTAL_CNTL, 0);
+	OUTPLL(pllHTOTAL2_CNTL, 0);
+
+	/* All outputs off */
+	OUTREG(CRTC_GEN_CNTL, 0x04000000);
+	OUTREG(CRTC2_GEN_CNTL, 0x04000000);
+	OUTREG(FP_GEN_CNTL, 0x00004008);
+	OUTREG(FP2_GEN_CNTL, 0x00000008);
+	OUTREG(LVDS_GEN_CNTL, 0x08000008);
+
+	/* Restore Memory Controller configuration */
+	radeon_pm_m9p_reconfigure_mc(rinfo);
+
+	/* Now we actually start MCLK and SCLK */
+	radeon_pm_start_mclk_sclk(rinfo);
+
+	/* Full reset sdrams, this also re-inits the MDLL */
+	radeon_pm_full_reset_sdram(rinfo);
+
+	/* Fill palettes */
+	OUTREG(DAC_CNTL2, INREG(DAC_CNTL2) | 0x20);
+	for (i=0; i<256; i++)
+		OUTREG(PALETTE_30_DATA, 0x15555555);
+	OUTREG(DAC_CNTL2, INREG(DAC_CNTL2) & ~20);
+	udelay(20);
+	for (i=0; i<256; i++)
+		OUTREG(PALETTE_30_DATA, 0x15555555);
+
+	OUTREG(DAC_CNTL2, INREG(DAC_CNTL2) & ~0x20);
+	mdelay(3);
+
+	/* Restore TV stuff, make sure TV DAC is down */
+	OUTREG(TV_MASTER_CNTL, rinfo->save_regs[88]);
+	OUTREG(TV_DAC_CNTL, rinfo->save_regs[13] | 0x07000000);
+
+	/* Restore GPIOS. MacOS does some magic here with one of the GPIO bits,
+	 * possibly related to the weird PLL related workarounds and to the
+	 * fact that CLK_PIN_CNTL is tweaked in ways I don't fully understand,
+	 * but we keep things the simple way here
+	 */
+	OUTREG(GPIOPAD_A, rinfo->save_regs[19]);
+	OUTREG(GPIOPAD_EN, rinfo->save_regs[20]);
+	OUTREG(GPIOPAD_MASK, rinfo->save_regs[21]);
+
+	/* Now do things with SCLK_MORE_CNTL. Force bits are already set, copy
+	 * high bits from backup
+	 */
+	tmp = INPLL(pllSCLK_MORE_CNTL) & 0x0000ffff;
+	tmp |= rinfo->save_regs[34] & 0xffff0000;
+	tmp |= SCLK_MORE_CNTL__FORCE_DISPREGS;
+	OUTPLL(pllSCLK_MORE_CNTL, tmp);
+
+	tmp = INPLL(pllSCLK_MORE_CNTL) & 0x0000ffff;
+	tmp |= rinfo->save_regs[34] & 0xffff0000;
+	tmp |= SCLK_MORE_CNTL__FORCE_DISPREGS;
+	OUTPLL(pllSCLK_MORE_CNTL, tmp);
+
+	OUTREG(LVDS_GEN_CNTL, rinfo->save_regs[11] &
+	       ~(LVDS_EN | LVDS_ON | LVDS_DIGON | LVDS_BLON | LVDS_BL_MOD_EN));
+	OUTREG(LVDS_GEN_CNTL, INREG(LVDS_GEN_CNTL) | LVDS_BLON);
+	OUTREG(LVDS_PLL_CNTL, (rinfo->save_regs[12] & ~0xf0000) | 0x20000);
+	mdelay(20);
+
+	/* write some stuff to the framebuffer... */
+	for (i = 0; i < 0x8000; ++i)
+		writeb(0, rinfo->fb_base + i);
+
+	OUTREG(0x2ec, 0x6332a020);
+	OUTPLL(pllSSPLL_REF_DIV, rinfo->save_regs[44] /*0x3f */);
+	OUTPLL(pllSSPLL_DIV_0, rinfo->save_regs[45] /*0x000081bb */);
+	tmp = INPLL(pllSSPLL_CNTL);
+	tmp &= ~2;
+	OUTPLL(pllSSPLL_CNTL, tmp);
+	mdelay(6);
+	tmp &= ~1;
+	OUTPLL(pllSSPLL_CNTL, tmp);
+	mdelay(5);
+	tmp |= 3;
+	OUTPLL(pllSSPLL_CNTL, tmp);
+	mdelay(5);
+
+	OUTPLL(pllSS_INT_CNTL, rinfo->save_regs[90] & ~3);/*0x0020300c*/
+	OUTREG(0x2ec, 0x6332a3f0);
+	mdelay(17);
+
+	OUTPLL(pllPPLL_REF_DIV, rinfo->pll.ref_div);;
+	OUTPLL(pllPPLL_DIV_0, rinfo->save_regs[92]);
+
+	mdelay(40);
+	OUTREG(LVDS_GEN_CNTL, INREG(LVDS_GEN_CNTL) | LVDS_DIGON | LVDS_ON);
+	mdelay(40);
+
+	/* Restore a few more things */
+	OUTREG(GRPH_BUFFER_CNTL, rinfo->save_regs[94]);
+	OUTREG(GRPH2_BUFFER_CNTL, rinfo->save_regs[95]);
+
+	/* Restore PPLL, spread spectrum & LVDS */
+	radeon_pm_m10_disable_spread_spectrum(rinfo);
+	radeon_pm_restore_pixel_pll(rinfo);
+	radeon_pm_m10_enable_lvds_spread_spectrum(rinfo);
+}
+
+#if 0 /* Not ready yet */
+static void radeon_reinitialize_QW(struct radeonfb_info *rinfo)
+{
+	int i;
+	u32 tmp, tmp2;
+	u32 cko, cka, ckb;
+	u32 cgc, cec, c2gc;
+
+	OUTREG(MC_AGP_LOCATION, rinfo->save_regs[32]);
+	OUTREG(DISPLAY_BASE_ADDR, rinfo->save_regs[31]);
+	OUTREG(CRTC2_DISPLAY_BASE_ADDR, rinfo->save_regs[33]);
+	OUTREG(MC_FB_LOCATION, rinfo->save_regs[30]);
+	OUTREG(BUS_CNTL, rinfo->save_regs[36]);
+	OUTREG(RBBM_CNTL, rinfo->save_regs[39]);
+
+	INREG(PAD_CTLR_STRENGTH);
+	OUTREG(PAD_CTLR_STRENGTH, INREG(PAD_CTLR_STRENGTH) & ~0x10000);
+	for (i = 0; i < 65; ++i) {
+		mdelay(1);
+		INREG(PAD_CTLR_STRENGTH);
+	}
+
+	OUTREG(DISP_TEST_DEBUG_CNTL, INREG(DISP_TEST_DEBUG_CNTL) | 0x10000000);
+	OUTREG(OV0_FLAG_CNTRL, INREG(OV0_FLAG_CNTRL) | 0x100);
+	OUTREG(CRTC_GEN_CNTL, INREG(CRTC_GEN_CNTL));
+	OUTREG(DAC_CNTL, 0xff00410a);
+	OUTREG(CRTC2_GEN_CNTL, INREG(CRTC2_GEN_CNTL));
+	OUTREG(DAC_CNTL2, INREG(DAC_CNTL2) | 0x4000);
+
+	OUTREG(SURFACE_CNTL, rinfo->save_regs[29]);
+	OUTREG(AGP_CNTL, rinfo->save_regs[16]);
+	OUTREG(HOST_PATH_CNTL, rinfo->save_regs[41]);
+	OUTREG(DISP_MISC_CNTL, rinfo->save_regs[9]);
+
+	OUTMC(rinfo, ixMC_CHP_IO_CNTL_A0, 0xf7bb4433);
+	OUTREG(MC_IND_INDEX, 0);
+	OUTMC(rinfo, ixMC_CHP_IO_CNTL_B0, 0xf7bb4433);
+	OUTREG(MC_IND_INDEX, 0);
+
+	OUTREG(CRTC_MORE_CNTL, INREG(CRTC_MORE_CNTL));
+
+	tmp = INPLL(pllVCLK_ECP_CNTL);
+	OUTPLL(pllVCLK_ECP_CNTL, tmp);
+	tmp = INPLL(pllPIXCLKS_CNTL);
+	OUTPLL(pllPIXCLKS_CNTL, tmp);
+
+	OUTPLL(MCLK_CNTL, 0xaa3f0000);
+	OUTPLL(SCLK_CNTL, 0xffff0000);
+	OUTPLL(pllMPLL_AUX_CNTL, 6);
+	OUTPLL(pllSPLL_AUX_CNTL, 1);
+	OUTPLL(MDLL_CKO, 0x9f009f);
+	OUTPLL(MDLL_RDCKA, 0x830083);
+	OUTPLL(pllMDLL_RDCKB, 0x830083);
+	OUTPLL(PPLL_CNTL, 0xa433);
+	OUTPLL(P2PLL_CNTL, 0xa433);
+	OUTPLL(MPLL_CNTL, 0x0400a403);
+	OUTPLL(SPLL_CNTL, 0x0400a433);
+
+	tmp = INPLL(M_SPLL_REF_FB_DIV);
+	OUTPLL(M_SPLL_REF_FB_DIV, tmp);
+	tmp = INPLL(M_SPLL_REF_FB_DIV);
+	OUTPLL(M_SPLL_REF_FB_DIV, tmp | 0xc);
+	INPLL(M_SPLL_REF_FB_DIV);
+
+	tmp = INPLL(MPLL_CNTL);
+	OUTREG8(CLOCK_CNTL_INDEX, MPLL_CNTL + PLL_WR_EN);
+	OUTREG8(CLOCK_CNTL_DATA + 1, (tmp >> 8) & 0xff);
+
+	tmp = INPLL(M_SPLL_REF_FB_DIV);
+	OUTPLL(M_SPLL_REF_FB_DIV, tmp | 0x5900);
+
+	tmp = INPLL(MPLL_CNTL);
+	OUTPLL(MPLL_CNTL, tmp & ~0x2);
+	mdelay(1);
+	tmp = INPLL(MPLL_CNTL);
+	OUTPLL(MPLL_CNTL, tmp & ~0x1);
+	mdelay(10);
+
+	OUTPLL(MCLK_CNTL, 0xaa3f1212);
+	mdelay(1);
+
+	INPLL(M_SPLL_REF_FB_DIV);
+	INPLL(MCLK_CNTL);
+	INPLL(M_SPLL_REF_FB_DIV);
+
+	tmp = INPLL(SPLL_CNTL);
+	OUTREG8(CLOCK_CNTL_INDEX, SPLL_CNTL + PLL_WR_EN);
+	OUTREG8(CLOCK_CNTL_DATA + 1, (tmp >> 8) & 0xff);
+
+	tmp = INPLL(M_SPLL_REF_FB_DIV);
+	OUTPLL(M_SPLL_REF_FB_DIV, tmp | 0x780000);
+
+	tmp = INPLL(SPLL_CNTL);
+	OUTPLL(SPLL_CNTL, tmp & ~0x1);
+	mdelay(1);
+	tmp = INPLL(SPLL_CNTL);
+	OUTPLL(SPLL_CNTL, tmp & ~0x2);
+	mdelay(10);
+
+	tmp = INPLL(SCLK_CNTL);
+	OUTPLL(SCLK_CNTL, tmp | 2);
+	mdelay(1);
+
+	cko = INPLL(pllMDLL_CKO);
+	cka = INPLL(pllMDLL_RDCKA);
+	ckb = INPLL(pllMDLL_RDCKB);
+
+	cko &= ~(MDLL_CKO__MCKOA_SLEEP | MDLL_CKO__MCKOB_SLEEP);
+	OUTPLL(pllMDLL_CKO, cko);
+	mdelay(1);
+	cko &= ~(MDLL_CKO__MCKOA_RESET | MDLL_CKO__MCKOB_RESET);
+	OUTPLL(pllMDLL_CKO, cko);
+	mdelay(5);
+
+	cka &= ~(MDLL_RDCKA__MRDCKA0_SLEEP | MDLL_RDCKA__MRDCKA1_SLEEP);
+	OUTPLL(pllMDLL_RDCKA, cka);
+	mdelay(1);
+	cka &= ~(MDLL_RDCKA__MRDCKA0_RESET | MDLL_RDCKA__MRDCKA1_RESET);
+	OUTPLL(pllMDLL_RDCKA, cka);
+	mdelay(5);
+
+	ckb &= ~(MDLL_RDCKB__MRDCKB0_SLEEP | MDLL_RDCKB__MRDCKB1_SLEEP);
+	OUTPLL(pllMDLL_RDCKB, ckb);
+	mdelay(1);
+	ckb &= ~(MDLL_RDCKB__MRDCKB0_RESET | MDLL_RDCKB__MRDCKB1_RESET);
+	OUTPLL(pllMDLL_RDCKB, ckb);
+	mdelay(5);
+
+	OUTMC(rinfo, ixMC_CHP_IO_CNTL_A1, 0x151550ff);
+	OUTREG(MC_IND_INDEX, 0);
+	OUTMC(rinfo, ixMC_CHP_IO_CNTL_B1, 0x151550ff);
+	OUTREG(MC_IND_INDEX, 0);
+	mdelay(1);
+	OUTMC(rinfo, ixMC_CHP_IO_CNTL_A1, 0x141550ff);
+	OUTREG(MC_IND_INDEX, 0);
+	OUTMC(rinfo, ixMC_CHP_IO_CNTL_B1, 0x141550ff);
+	OUTREG(MC_IND_INDEX, 0);
+	mdelay(1);
+
+	OUTPLL(pllHTOTAL_CNTL, 0);
+	OUTPLL(pllHTOTAL2_CNTL, 0);
+
+	OUTREG(MEM_CNTL, 0x29002901);
+	OUTREG(MEM_SDRAM_MODE_REG, 0x45320032);	/* XXX use save_regs[35]? */
+	OUTREG(EXT_MEM_CNTL, 0x1a394333);
+	OUTREG(MEM_IO_CNTL_A1, 0x0aac0aac);
+	OUTREG(MEM_INIT_LATENCY_TIMER, 0x34444444);
+	OUTREG(MEM_REFRESH_CNTL, 0x1f1f7218);	/* XXX or save_regs[42]? */
+	OUTREG(MC_DEBUG, 0);
+	OUTREG(MEM_IO_OE_CNTL, 0x04300430);
+
+	OUTMC(rinfo, ixMC_IMP_CNTL, 0x00f460d6);
+	OUTREG(MC_IND_INDEX, 0);
+	OUTMC(rinfo, ixMC_IMP_CNTL_0, 0x00009249);
+	OUTREG(MC_IND_INDEX, 0);
+
+	OUTREG(CONFIG_MEMSIZE, rinfo->video_ram);
+
+	radeon_pm_full_reset_sdram(rinfo);
+
+	INREG(FP_GEN_CNTL);
+	OUTREG(TMDS_CNTL, 0x01000000);	/* XXX ? */
+	tmp = INREG(FP_GEN_CNTL);
+	tmp |= FP_CRTC_DONT_SHADOW_HEND | FP_CRTC_DONT_SHADOW_VPAR | 0x200;
+	OUTREG(FP_GEN_CNTL, tmp);
+
+	tmp = INREG(DISP_OUTPUT_CNTL);
+	tmp &= ~0x400;
+	OUTREG(DISP_OUTPUT_CNTL, tmp);
+
+	OUTPLL(CLK_PIN_CNTL, rinfo->save_regs[4]);
+	OUTPLL(CLK_PWRMGT_CNTL, rinfo->save_regs[1]);
+	OUTPLL(PLL_PWRMGT_CNTL, rinfo->save_regs[0]);
+
+	tmp = INPLL(MCLK_MISC);
+	tmp |= MCLK_MISC__MC_MCLK_DYN_ENABLE | MCLK_MISC__IO_MCLK_DYN_ENABLE;
+	OUTPLL(MCLK_MISC, tmp);
+
+	tmp = INPLL(SCLK_CNTL);
+	OUTPLL(SCLK_CNTL, tmp);
+
+	OUTREG(CRTC_MORE_CNTL, 0);
+	OUTREG8(CRTC_GEN_CNTL+1, 6);
+	OUTREG8(CRTC_GEN_CNTL+3, 1);
+	OUTREG(CRTC_PITCH, 32);
+
+	tmp = INPLL(VCLK_ECP_CNTL);
+	OUTPLL(VCLK_ECP_CNTL, tmp);
+
+	tmp = INPLL(PPLL_CNTL);
+	OUTPLL(PPLL_CNTL, tmp);
+
+	/* palette stuff and BIOS_1_SCRATCH... */
+
+	tmp = INREG(FP_GEN_CNTL);
+	tmp2 = INREG(TMDS_TRANSMITTER_CNTL);
+	tmp |= 2;
+	OUTREG(FP_GEN_CNTL, tmp);
+	mdelay(5);
+	OUTREG(FP_GEN_CNTL, tmp);
+	mdelay(5);
+	OUTREG(TMDS_TRANSMITTER_CNTL, tmp2);
+	OUTREG(CRTC_MORE_CNTL, 0);
+	mdelay(20);
+
+	tmp = INREG(CRTC_MORE_CNTL);
+	OUTREG(CRTC_MORE_CNTL, tmp);
+
+	cgc = INREG(CRTC_GEN_CNTL);
+	cec = INREG(CRTC_EXT_CNTL);
+	c2gc = INREG(CRTC2_GEN_CNTL);
+
+	OUTREG(CRTC_H_SYNC_STRT_WID, 0x008e0580);
+	OUTREG(CRTC_H_TOTAL_DISP, 0x009f00d2);
+	OUTREG8(CLOCK_CNTL_INDEX, HTOTAL_CNTL + PLL_WR_EN);
+	OUTREG8(CLOCK_CNTL_DATA, 0);
+	OUTREG(CRTC_V_SYNC_STRT_WID, 0x00830403);
+	OUTREG(CRTC_V_TOTAL_DISP, 0x03ff0429);
+	OUTREG(FP_CRTC_H_TOTAL_DISP, 0x009f0033);
+	OUTREG(FP_H_SYNC_STRT_WID, 0x008e0080);
+	OUTREG(CRT_CRTC_H_SYNC_STRT_WID, 0x008e0080);
+	OUTREG(FP_CRTC_V_TOTAL_DISP, 0x03ff002a);
+	OUTREG(FP_V_SYNC_STRT_WID, 0x00830004);
+	OUTREG(CRT_CRTC_V_SYNC_STRT_WID, 0x00830004);
+	OUTREG(FP_HORZ_VERT_ACTIVE, 0x009f03ff);
+	OUTREG(FP_HORZ_STRETCH, 0);
+	OUTREG(FP_VERT_STRETCH, 0);
+	OUTREG(OVR_CLR, 0);
+	OUTREG(OVR_WID_LEFT_RIGHT, 0);
+	OUTREG(OVR_WID_TOP_BOTTOM, 0);
+
+	tmp = INPLL(PPLL_REF_DIV);
+	tmp = (tmp & ~PPLL_REF_DIV_MASK) | rinfo->pll.ref_div;
+	OUTPLL(PPLL_REF_DIV, tmp);
+	INPLL(PPLL_REF_DIV);
+
+	OUTREG8(CLOCK_CNTL_INDEX, PPLL_CNTL + PLL_WR_EN);
+	OUTREG8(CLOCK_CNTL_DATA + 1, 0xbc);
+
+	tmp = INREG(CLOCK_CNTL_INDEX);
+	OUTREG(CLOCK_CNTL_INDEX, tmp & 0xff);
+
+	OUTPLL(PPLL_DIV_0, 0x48090);
+
+	tmp = INPLL(PPLL_CNTL);
+	OUTPLL(PPLL_CNTL, tmp & ~0x2);
+	mdelay(1);
+	tmp = INPLL(PPLL_CNTL);
+	OUTPLL(PPLL_CNTL, tmp & ~0x1);
+	mdelay(10);
+
+	tmp = INPLL(VCLK_ECP_CNTL);
+	OUTPLL(VCLK_ECP_CNTL, tmp | 3);
+	mdelay(1);
+
+	tmp = INPLL(VCLK_ECP_CNTL);
+	OUTPLL(VCLK_ECP_CNTL, tmp);
+
+	c2gc |= CRTC2_DISP_REQ_EN_B;
+	OUTREG(CRTC2_GEN_CNTL, c2gc);
+	cgc |= CRTC_EN;
+	OUTREG(CRTC_GEN_CNTL, cgc);
+	OUTREG(CRTC_EXT_CNTL, cec);
+	OUTREG(CRTC_PITCH, 0xa0);
+	OUTREG(CRTC_OFFSET, 0);
+	OUTREG(CRTC_OFFSET_CNTL, 0);
+
+	OUTREG(GRPH_BUFFER_CNTL, 0x20117c7c);
+	OUTREG(GRPH2_BUFFER_CNTL, 0x00205c5c);
+
+	tmp2 = INREG(FP_GEN_CNTL);
+	tmp = INREG(TMDS_TRANSMITTER_CNTL);
+	OUTREG(0x2a8, 0x0000061b);
+	tmp |= TMDS_PLL_EN;
+	OUTREG(TMDS_TRANSMITTER_CNTL, tmp);
+	mdelay(1);
+	tmp &= ~TMDS_PLLRST;
+	OUTREG(TMDS_TRANSMITTER_CNTL, tmp);
+	tmp2 &= ~2;
+	tmp2 |= FP_TMDS_EN;
+	OUTREG(FP_GEN_CNTL, tmp2);
+	mdelay(5);
+	tmp2 |= FP_FPON;
+	OUTREG(FP_GEN_CNTL, tmp2);
+
+	OUTREG(CUR_HORZ_VERT_OFF, CUR_LOCK | 1);
+	cgc = INREG(CRTC_GEN_CNTL);
+	OUTREG(CUR_HORZ_VERT_POSN, 0xbfff0fff);
+	cgc |= 0x10000;
+	OUTREG(CUR_OFFSET, 0);
+}
+#endif /* 0 */
+
+#endif /* CONFIG_PPC_OF */
+
 static void radeon_set_suspend(struct radeonfb_info *rinfo, int suspend)
 {
 	u16 pwr_cmd;
 	u32 tmp;
+	int i;
 
 	if (!rinfo->pm_reg)
 		return;
@@ -796,13 +2406,13 @@
 		 * duration of the suspend/resume process
 		 */
 		radeon_pm_disable_dynamic_mode(rinfo);
+
 		/* Save some registers */
-		radeon_pm_save_regs(rinfo);
+		radeon_pm_save_regs(rinfo, 0);
 
-		/* Prepare mobility chips for suspend. Only do that on <= RV250 chips that
-		 * have been tested
+		/* Prepare mobility chips for suspend.
 		 */
-		if (rinfo->is_mobility && rinfo->family <= CHIP_FAMILY_RV250) {
+		if (rinfo->is_mobility) {
 			/* Program V2CLK */
 			radeon_pm_program_v2clk(rinfo);
 		
@@ -815,13 +2425,22 @@
 			/* Prepare chip for power management */
 			radeon_pm_setup_for_suspend(rinfo);
 
-			/* Reset the MDLL */
-			/* because both INPLL and OUTPLL take the same lock, that's why. */
-			tmp = INPLL( pllMDLL_CKO) | MDLL_CKO__MCKOA_RESET | MDLL_CKO__MCKOB_RESET;
-			OUTPLL( pllMDLL_CKO, tmp );
+			if (rinfo->family <= CHIP_FAMILY_RV280) {
+				/* Reset the MDLL */
+				/* because both INPLL and OUTPLL take the same
+				 * lock, that's why. */
+				tmp = INPLL( pllMDLL_CKO) | MDLL_CKO__MCKOA_RESET
+					| MDLL_CKO__MCKOB_RESET;
+				OUTPLL( pllMDLL_CKO, tmp );
+			}
 		}
 
+		for (i = 0; i < 64; ++i)
+			pci_read_config_dword(rinfo->pdev, i * 4,
+					      &rinfo->cfg_save[i]);
+
 		/* Switch PCI power managment to D2. */
+		pci_disable_device(rinfo->pdev);
 		for (;;) {
 			pci_read_config_word(
 				rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL,
@@ -841,37 +2460,74 @@
 		pci_write_config_word(rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL, 0);
 		mdelay(500);
 
-		/* Reset the SDRAM controller  */
-       		radeon_pm_full_reset_sdram(rinfo);
-		
-		/* Restore some registers */
-		radeon_pm_restore_regs(rinfo);
-		radeon_pm_enable_dynamic_mode(rinfo);
+		if (rinfo->family <= CHIP_FAMILY_RV250) {
+			/* Reset the SDRAM controller  */
+			radeon_pm_full_reset_sdram(rinfo);
+
+			/* Restore some registers */
+			radeon_pm_restore_regs(rinfo);
+		} else {
+			/* Restore registers first */
+			radeon_pm_restore_regs(rinfo);
+			/* init sdram controller */
+			radeon_pm_full_reset_sdram(rinfo);
+		}
 	}
 }
 
+static int radeon_restore_pci_cfg(struct radeonfb_info *rinfo)
+{
+	int i;
+	static u32 radeon_cfg_after_resume[64];
+
+	for (i = 0; i < 64; ++i)
+		pci_read_config_dword(rinfo->pdev, i * 4,
+				      &radeon_cfg_after_resume[i]);
+
+	if (radeon_cfg_after_resume[PCI_BASE_ADDRESS_0/4]
+	    == rinfo->cfg_save[PCI_BASE_ADDRESS_0/4])
+		return 0;	/* assume everything is ok */
+
+	for (i = PCI_BASE_ADDRESS_0/4; i < 64; ++i) {
+		if (radeon_cfg_after_resume[i] != rinfo->cfg_save[i])
+			pci_write_config_dword(rinfo->pdev, i * 4,
+					       rinfo->cfg_save[i]);
+	}
+	pci_write_config_word(rinfo->pdev, PCI_CACHE_LINE_SIZE,
+			      rinfo->cfg_save[PCI_CACHE_LINE_SIZE/4]);
+	pci_write_config_word(rinfo->pdev, PCI_COMMAND,
+			      rinfo->cfg_save[PCI_COMMAND/4]);
+	return 1;
+}
+
+
+static/*extern*/ int susdisking = 0;
+
 int radeonfb_pci_suspend(struct pci_dev *pdev, u32 state)
 {
         struct fb_info *info = pci_get_drvdata(pdev);
         struct radeonfb_info *rinfo = info->par;
+	int i;
 
-	/* We don't do anything but D2, for now we return 0, but
-	 * we may want to change that. How do we know if the BIOS
-	 * can properly take care of D3 ? Also, with swsusp, we
-	 * know we'll be rebooted, ...
-	 */
+	if (state == pdev->dev.power.power_state)
+		return 0;
 
-	printk(KERN_DEBUG "radeonfb: suspending to state: %d...\n", state);
-	
-	acquire_console_sem();
+	printk(KERN_DEBUG "radeonfb (%s): suspending to state: %d...\n",
+	       pci_name(pdev), state);
 
-	/* Userland should do this but doesn't... bridge gets suspended
-	 * too late. Unfortunately, that works only when AGP is built-in,
-	 * not for a module.
+	/* For suspend-to-disk, we cheat here. We don't suspend anything and
+	 * let fbcon continue drawing until we are all set. That shouldn't
+	 * really cause any problem at this point, provided that the wakeup
+	 * code knows that any state in memory may not match the HW
 	 */
-#ifdef CONFIG_AGP
-	agp_enable(0);
-#endif
+	if (state != PM_SUSPEND_MEM)
+		goto done;
+	if (susdisking) {
+		printk("suspending to disk but state = %d\n", state);
+		goto done;
+	}
+
+	acquire_console_sem();
 
 	fb_set_suspend(info, 1);
 
@@ -883,21 +2539,52 @@
 	}
 
 	/* Blank display and LCD */
-	radeonfb_blank(VESA_POWERDOWN, info);
+	radeon_screen_blank(rinfo, FB_BLANK_POWERDOWN, 1);
 
 	/* Sleep */
 	rinfo->asleep = 1;
 	rinfo->lock_blank = 1;
+	del_timer_sync(&rinfo->lvds_timer);
 
-	/* Suspend the chip to D2 state when supported
+	/* If we support wakeup from poweroff, we save all regs we can including cfg
+	 * space
+	 */
+	if (rinfo->pm_mode & radeon_pm_off) {
+		/* Always disable dynamic clocks or weird things are happening when
+		 * the chip goes off (basically the panel doesn't shut down properly
+		 * and we crash on wakeup),
+		 * also, we want the saved regs context to have no dynamic clocks in
+		 * it, we'll restore the dynamic clocks state on wakeup
+		 */
+		radeon_pm_disable_dynamic_mode(rinfo);
+		mdelay(50);
+		radeon_pm_save_regs(rinfo, 1);
+
+		if (rinfo->is_mobility && !(rinfo->pm_mode & radeon_pm_d2)) {
+			/* Switch off LVDS interface */
+			mdelay(1);
+			OUTREG(LVDS_GEN_CNTL, INREG(LVDS_GEN_CNTL) & ~(LVDS_BL_MOD_EN));
+			mdelay(1);
+			OUTREG(LVDS_GEN_CNTL, INREG(LVDS_GEN_CNTL) & ~(LVDS_EN | LVDS_ON));
+			OUTREG(LVDS_PLL_CNTL, (INREG(LVDS_PLL_CNTL) & ~30000) | 0x20000);
+			mdelay(20);
+			OUTREG(LVDS_GEN_CNTL, INREG(LVDS_GEN_CNTL) & ~(LVDS_DIGON));
+
+			// FIXME: Use PCI layer
+			for (i = 0; i < 64; ++i)
+				pci_read_config_dword(rinfo->pdev, i * 4,
+						      &rinfo->cfg_save[i]);
+		}
+	}
+	/* If we support D2, we go to it (should be fixed later with a flag forcing
+	 * D3 only for some laptops)
 	 */
-#ifdef CONFIG_RADEON_HAS_D2
-	if (radeon_suspend_to_d2(rinfo, state))
+	if (rinfo->pm_mode & radeon_pm_d2)
 		radeon_set_suspend(rinfo, 1);
-#endif /* CONFIG_RADEON_HAS_D2 */
 
 	release_console_sem();
 
+ done:
 	pdev->dev.power.power_state = state;
 
 	return 0;
@@ -907,22 +2594,59 @@
 {
         struct fb_info *info = pci_get_drvdata(pdev);
         struct radeonfb_info *rinfo = info->par;
+	int rc = 0;
 
 	if (pdev->dev.power.power_state == 0)
 		return 0;
 
-	acquire_console_sem();
+	if (rinfo->no_schedule) {
+		if (try_acquire_console_sem())
+			return 0;
+	} else
+		acquire_console_sem();
+
+	printk(KERN_DEBUG "radeonfb (%s): resuming from state: %d...\n",
+	       pci_name(pdev), pdev->dev.power.power_state);
+
+
+	if (pci_enable_device(pdev)) {
+		rc = -ENODEV;
+		printk(KERN_ERR "radeonfb (%s): can't enable PCI device !\n",
+		       pci_name(pdev));
+		goto bail;
+	}
+	pci_set_master(pdev);
 
-	/* Wakeup chip */
-#ifdef CONFIG_RADEON_HAS_D2
-	if (radeon_suspend_to_d2(rinfo, 0))
-		radeon_set_suspend(rinfo, 0);
-#endif /* CONFIG_RADEON_HAS_D2 */
+	if (pdev->dev.power.power_state == PM_SUSPEND_MEM) {
+		/* Wakeup chip. Check from config space if we were powered off
+		 * (todo: additionally, check CLK_PIN_CNTL too)
+		 */
+		if ((rinfo->pm_mode & radeon_pm_off) && radeon_restore_pci_cfg(rinfo)) {
+			if (rinfo->reinit_func != NULL)
+				rinfo->reinit_func(rinfo);
+			else {
+				printk(KERN_ERR "radeonfb (%s): can't resume radeon from"
+				       " D3 cold, need softboot !", pci_name(pdev));
+				rc = -EIO;
+				goto bail;
+			}
+		}
+		/* If we support D2, try to resume... we should check what was our
+		 * state though... (were we really in D2 state ?). Right now, this code
+		 * is only enable on Macs so it's fine.
+		 */
+		else if (rinfo->pm_mode & radeon_pm_d2)
+			radeon_set_suspend(rinfo, 0);
 
-	rinfo->asleep = 0;
+		rinfo->asleep = 0;
+	} else
+		radeon_engine_idle();
 
 	/* Restore display & engine */
-	radeonfb_set_par(info);
+	radeon_write_mode (rinfo, &rinfo->state, 1);
+	if (!(info->flags & FBINFO_HWACCEL_DISABLED))
+		radeonfb_engine_init (rinfo);
+
 	fb_pan_display(info, &info->var);
 	fb_set_cmap(&info->cmap, info);
 
@@ -931,15 +2655,107 @@
 
 	/* Unblank */
 	rinfo->lock_blank = 0;
-	radeonfb_blank(0, info);
+	radeon_screen_blank(rinfo, FB_BLANK_UNBLANK, 1);
 
-	release_console_sem();
+	/* Check status of dynclk */
+	if (rinfo->dynclk == 1)
+		radeon_pm_enable_dynamic_mode(rinfo);
+	else if (rinfo->dynclk == 0)
+		radeon_pm_disable_dynamic_mode(rinfo);
 
 	pdev->dev.power.power_state = 0;
 
-	printk(KERN_DEBUG "radeonfb: resumed !\n");
+ bail:
+	release_console_sem();
 
-	return 0;
+	return rc;
+}
+
+#ifdef CONFIG_PPC_OF
+static void radeonfb_early_resume(void *data)
+{
+        struct radeonfb_info *rinfo = data;
+
+	rinfo->no_schedule = 1;
+	radeonfb_pci_resume(rinfo->pdev);
+	rinfo->no_schedule = 0;
 }
+#endif /* CONFIG_PPC_OF */
 
 #endif /* CONFIG_PM */
+
+void radeonfb_pm_init(struct radeonfb_info *rinfo, int dynclk)
+{
+	/* Find PM registers in config space if any*/
+	rinfo->pm_reg = pci_find_capability(rinfo->pdev, PCI_CAP_ID_PM);
+
+	/* Enable/Disable dynamic clocks: TODO add sysfs access */
+	rinfo->dynclk = dynclk;
+	if (dynclk == 1) {
+		radeon_pm_enable_dynamic_mode(rinfo);
+		printk("radeonfb: Dynamic Clock Power Management enabled\n");
+	} else if (dynclk == 0) {
+		radeon_pm_disable_dynamic_mode(rinfo);
+		printk("radeonfb: Dynamic Clock Power Management disabled\n");
+	}
+
+	/* Check if we can power manage on suspend/resume. We can do
+	 * D2 on M6, M7 and M9, and we can resume from D3 cold a few other
+	 * "Mac" cards, but that's all. We need more infos about what the
+	 * BIOS does tho. Right now, all this PM stuff is pmac-only for that
+	 * reason. --BenH
+	 */
+#if defined(CONFIG_PM) && defined(CONFIG_PPC_OF)
+	if (_machine == _MACH_Pmac && rinfo->of_node) {
+		if (rinfo->is_mobility && rinfo->pm_reg &&
+		    rinfo->family <= CHIP_FAMILY_RV250)
+			rinfo->pm_mode |= radeon_pm_d2;
+
+		/* We can restart Jasper (M10 chip in albooks), BlueStone (7500 chip
+		 * in some desktop G4s), and Via (M9+ chip on iBook G4)
+		 */
+		if (!strcmp(rinfo->of_node->name, "ATY,JasperParent")) {
+			rinfo->reinit_func = radeon_reinitialize_M10;
+			rinfo->pm_mode |= radeon_pm_off;
+		}
+#if 0 /* Not ready yet */
+		if (!strcmp(rinfo->of_node->name, "ATY,BlueStoneParent")) {
+			rinfo->reinit_func = radeon_reinitialize_QW;
+			rinfo->pm_mode |= radeon_pm_off;
+		}
+#endif
+		if (!strcmp(rinfo->of_node->name, "ATY,ViaParent")) {
+			rinfo->reinit_func = radeon_reinitialize_M9P;
+			rinfo->pm_mode |= radeon_pm_off;
+			/* Workaround not used for now */
+			rinfo->m9p_workaround = 1;
+		}
+
+		/* If any of the above is set, we assume the machine can sleep/resume.
+		 * It's a bit of a "shortcut" but will work fine. Ideally, we need infos
+		 * from the platform about what happens to the chip...
+		 * Now we tell the platform about our capability
+		 */
+		if (rinfo->pm_mode != radeon_pm_none) {
+			pmac_call_feature(PMAC_FTR_DEVICE_CAN_WAKE, rinfo->of_node, 0, 1);
+			pmac_set_early_video_resume(radeonfb_early_resume, rinfo);
+		}
+
+#if 0
+		/* Power down TV DAC, taht saves a significant amount of power,
+		 * we'll have something better once we actually have some TVOut
+		 * support
+		 */
+		OUTREG(TV_DAC_CNTL, INREG(TV_DAC_CNTL) | 0x07000000);
+#endif
+	}
+#endif /* defined(CONFIG_PM) && defined(CONFIG_PPC_OF) */
+}
+
+void radeonfb_pm_exit(struct radeonfb_info *rinfo)
+{
+#if defined(CONFIG_PM) && defined(CONFIG_PPC_OF)
+	if (rinfo->pm_mode != radeon_pm_none)
+		pmac_set_early_video_resume(NULL, NULL);
+#endif
+}
diff -Nru a/drivers/video/aty/radeonfb.h b/drivers/video/aty/radeonfb.h
--- a/drivers/video/aty/radeonfb.h	2005-03-01 23:39:18 -08:00
+++ b/drivers/video/aty/radeonfb.h	2005-03-01 23:39:18 -08:00
@@ -16,8 +16,17 @@
 
 #include <asm/io.h>
 
+#ifdef CONFIG_PPC_OF
+#include <asm/prom.h>
+#endif
+
 #include <video/radeon.h>
 
+/* Some weird black magic use by Apple driver that we don't use for
+ * now --BenH
+ */
+#undef HAS_PLL_M9_GPIO_MAGIC
+
 /***************************************************************
  * Most of the definitions here are adapted right from XFree86 *
  ***************************************************************/
@@ -33,7 +42,8 @@
 	CHIP_FAMILY_RV100,
 	CHIP_FAMILY_RS100,    /* U1 (IGP320M) or A3 (IGP320)*/
 	CHIP_FAMILY_RV200,
-	CHIP_FAMILY_RS200,    /* U2 (IGP330M/340M/350M) or A4 (IGP330/340/345/350), RS250 (IGP 7000) */
+	CHIP_FAMILY_RS200,    /* U2 (IGP330M/340M/350M) or A4 (IGP330/340/345/350),
+				 RS250 (IGP 7000) */
 	CHIP_FAMILY_R200,
 	CHIP_FAMILY_RV250,
 	CHIP_FAMILY_RS300,    /* Radeon 9000 IGP */
@@ -41,9 +51,26 @@
 	CHIP_FAMILY_R300,
 	CHIP_FAMILY_R350,
 	CHIP_FAMILY_RV350,
+	CHIP_FAMILY_RV380,    /* RV370/RV380/M22/M24 */
+	CHIP_FAMILY_R420,     /* R420/R423/M18 */
 	CHIP_FAMILY_LAST,
 };
 
+#define IS_RV100_VARIANT(rinfo) (((rinfo)->family == CHIP_FAMILY_RV100)  || \
+				 ((rinfo)->family == CHIP_FAMILY_RV200)  || \
+				 ((rinfo)->family == CHIP_FAMILY_RS100)  || \
+				 ((rinfo)->family == CHIP_FAMILY_RS200)  || \
+				 ((rinfo)->family == CHIP_FAMILY_RV250)  || \
+				 ((rinfo)->family == CHIP_FAMILY_RV280)  || \
+				 ((rinfo)->family == CHIP_FAMILY_RS300))
+
+
+#define IS_R300_VARIANT(rinfo) (((rinfo)->family == CHIP_FAMILY_R300)  || \
+				((rinfo)->family == CHIP_FAMILY_RV350) || \
+				((rinfo)->family == CHIP_FAMILY_R350)  || \
+				((rinfo)->family == CHIP_FAMILY_RV380) || \
+				((rinfo)->family == CHIP_FAMILY_R420))
+
 /*
  * Chip flags
  */
@@ -102,21 +129,6 @@
 	int ref_clk;
 };
 
-/*
- * VRAM infos
- */
-struct ram_info {
-	int ml;
-	int mb;
-	int trcd;
-	int trp;
-	int twr;
-	int cl;
-	int tr2w;
-	int loop_latency;
-	int rloop;
-};
-
 
 /*
  * This structure contains the various registers manipulated by this
@@ -210,6 +222,7 @@
 	u32		ppll_div_3;
 	u32		ppll_ref_div;
 	u32		vclk_ecp_cntl;
+	u32		clk_cntl_index;
 
 	/* Computed values for PLL2 */
 	u32		dot_clock_freq_2;
@@ -250,6 +263,12 @@
 };
 #endif
 
+enum radeon_pm_mode {
+	radeon_pm_none	= 0,		/* Nothing supported */
+	radeon_pm_d2	= 0x00000001,	/* Can do D2 state */
+	radeon_pm_off	= 0x00000002,	/* Can resume from D3 cold */
+};
+
 struct radeonfb_info {
 	struct fb_info		*info;
 
@@ -257,7 +276,6 @@
 	struct radeon_regs	init_state;
 
 	char			name[DEVICE_NAME_SIZE];
-	char			ram_type[12];
 
 	unsigned long		mmio_base_phys;
 	unsigned long		fb_base_phys;
@@ -268,6 +286,9 @@
 	unsigned long		fb_local_base;
 
 	struct pci_dev		*pdev;
+#ifdef CONFIG_PPC_OF
+	struct device_node	*of_node;
+#endif
 
 	void __iomem		*bios_seg;
 	int			fp_bios_start;
@@ -281,6 +302,8 @@
 	u8			rev;
 	unsigned long		video_ram;
 	unsigned long		mapped_vram;
+	int			vram_width;
+	int			vram_ddr;
 
 	int			pitch, bpp, depth;
 
@@ -288,6 +311,7 @@
 	int			is_mobility;
 	int			is_IGP;
 	int			R300_cg_workaround;
+	int			m9p_workaround;
 	int			reversed_DAC;
 	int			reversed_TMDS;
 	struct panel_info	panel_info;
@@ -302,14 +326,16 @@
 
 	struct pll_info		pll;
 
-	struct ram_info		ram;
-
 	int			mtrr_hdl;
 
 	int			pm_reg;
-	u32			save_regs[64];
+	u32			save_regs[100];
 	int			asleep;
 	int			lock_blank;
+	int			dynclk;
+	int			no_schedule;
+	enum radeon_pm_mode	pm_mode;
+	void			(*reinit_func)(struct radeonfb_info *rinfo);
 
 	/* Lock on register access */
 	spinlock_t		reg_lock;
@@ -317,11 +343,12 @@
 	/* Timer used for delayed LVDS operations */
 	struct timer_list	lvds_timer;
 	u32			pending_lvds_gen_cntl;
-	u32			pending_pixclks_cntl;
 
 #ifdef CONFIG_FB_RADEON_I2C
 	struct radeon_i2c_chan 	i2c[4];
 #endif
+
+	u32			cfg_save[64];
 };
 
 
@@ -353,6 +380,22 @@
 #define INREG(addr)		readl((rinfo->mmio_base)+addr)
 #define OUTREG(addr,val)	writel(val, (rinfo->mmio_base)+addr)
 
+static inline void _OUTREGP(struct radeonfb_info *rinfo, u32 addr,
+		       u32 val, u32 mask)
+{
+	unsigned long flags;
+	unsigned int tmp;
+
+	spin_lock_irqsave(&rinfo->reg_lock, flags);
+	tmp = INREG(addr);
+	tmp &= (mask);
+	tmp |= (val);
+	OUTREG(addr, tmp);
+	spin_unlock_irqrestore(&rinfo->reg_lock, flags);
+}
+
+#define OUTREGP(addr,val,mask)	_OUTREGP(rinfo, addr, val,mask)
+
 static inline void R300_cg_workardound(struct radeonfb_info *rinfo)
 {
 	u32 save, tmp;
@@ -363,18 +406,35 @@
 	OUTREG(CLOCK_CNTL_INDEX, save);
 }
 
-#define __OUTPLL(addr,val)	\
-	do {	\
-		OUTREG8(CLOCK_CNTL_INDEX, (addr & 0x0000003f) | 0x00000080); \
-		OUTREG(CLOCK_CNTL_DATA, val); \
-} while(0)
-
 
 static inline u32 __INPLL(struct radeonfb_info *rinfo, u32 addr)
 {
 	u32 data;
+#ifdef HAS_PLL_M9_GPIO_MAGIC
+	u32 sv[3];
+
+	if (rinfo->m9p_workaround) {
+		sv[0] = INREG(0x19c);
+		sv[1] = INREG(0x1a0);
+		sv[2] = INREG(0x198);
+		OUTREG(0x198, 0);
+		OUTREG(0x1a0, 0);
+		OUTREG(0x19c, 0);
+	}
+#endif /* HAS_PLL_M9_GPIO_MAGIC */
+
 	OUTREG8(CLOCK_CNTL_INDEX, addr & 0x0000003f);
 	data = (INREG(CLOCK_CNTL_DATA));
+
+#ifdef HAS_PLL_M9_GPIO_MAGIC
+	if (rinfo->m9p_workaround) {
+		(void)INREG(CRTC_GEN_CNTL);
+		data = INREG(CLOCK_CNTL_DATA);
+		OUTREG(0x19c, sv[0]);
+		OUTREG(0x1a0, sv[1]);
+		OUTREG(0x198, sv[2]);
+	}
+#endif /* HAS_PLL_M9_GPIO_MAGIC */
 	if (rinfo->R300_cg_workaround)
 		R300_cg_workardound(rinfo);
 	return data;
@@ -393,37 +453,61 @@
 
 #define INPLL(addr)		_INPLL(rinfo, addr)
 
-#define OUTPLL(addr,val)	\
-	do {	\
-		unsigned long flags;\
-		spin_lock_irqsave(&rinfo->reg_lock, flags); \
-		__OUTPLL(addr, val); \
-		spin_unlock_irqrestore(&rinfo->reg_lock, flags); \
-	} while(0)
-
-#define OUTPLLP(addr,val,mask)  					\
-	do {								\
-		unsigned long flags;                                    \
-		unsigned int _tmp;					\
-		spin_lock_irqsave(&rinfo->reg_lock, flags); 		\
-		_tmp  = __INPLL(rinfo,addr);				\
-		_tmp &= (mask);						\
-		_tmp |= (val);						\
-		__OUTPLL(addr, _tmp);					\
-		spin_unlock_irqrestore(&rinfo->reg_lock, flags); 	\
-	} while (0)
-
-#define OUTREGP(addr,val,mask)  					\
-	do {								\
-		unsigned long flags;                                    \
-		unsigned int _tmp;					\
-		spin_lock_irqsave(&rinfo->reg_lock, flags); 		\
-		_tmp = INREG(addr);				       	\
-		_tmp &= (mask);						\
-		_tmp |= (val);						\
-		OUTREG(addr, _tmp);					\
-		spin_unlock_irqrestore(&rinfo->reg_lock, flags); 	\
-	} while (0)
+
+static inline void __OUTPLL(struct radeonfb_info *rinfo, unsigned int index, u32 val)
+{
+#ifdef HAS_PLL_M9_GPIO_MAGIC
+	u32 sv[3];
+
+	if (rinfo->m9p_workaround) {
+		sv[0] = INREG(0x19c);
+		sv[1] = INREG(0x1a0);
+		sv[2] = INREG(0x198);
+		OUTREG(0x198, 0);
+		OUTREG(0x1a0, 0);
+		OUTREG(0x19c, 0);
+		mdelay(1);
+	}
+#endif /* HAS_PLL_M9_GPIO_MAGIC */
+
+	OUTREG8(CLOCK_CNTL_INDEX, (index & 0x0000003f) | 0x00000080);
+	OUTREG(CLOCK_CNTL_DATA, val);
+
+#ifdef HAS_PLL_M9_GPIO_MAGIC
+	if (rinfo->m9p_workaround) {
+		OUTREG(0x19c, sv[0]);
+		OUTREG(0x1a0, sv[1]);
+		OUTREG(0x198, sv[2]);
+	}
+#endif /* HAS_PLL_M9_GPIO_MAGIC */
+}
+
+static inline void _OUTPLL(struct radeonfb_info *rinfo, unsigned int index, u32 val)
+{
+       	unsigned long flags;
+	spin_lock_irqsave(&rinfo->reg_lock, flags);
+	__OUTPLL(rinfo, index, val);
+	spin_unlock_irqrestore(&rinfo->reg_lock, flags);
+}
+
+static inline void _OUTPLLP(struct radeonfb_info *rinfo, unsigned int index,
+			    u32 val, u32 mask)
+{
+	unsigned long flags;
+	unsigned int tmp;
+
+	spin_lock_irqsave(&rinfo->reg_lock, flags);
+	tmp  = __INPLL(rinfo, index);
+	tmp &= (mask);
+	tmp |= (val);
+	__OUTPLL(rinfo, index, tmp);
+	spin_unlock_irqrestore(&rinfo->reg_lock, flags);
+}
+
+
+#define OUTPLL(index, val)		_OUTPLL(rinfo, index, val)
+#define OUTPLLP(index, val, mask)	_OUTPLLP(rinfo, index, val, mask)
+
 
 #define BIOS_IN8(v)  	(readb(rinfo->bios_seg + (v)))
 #define BIOS_IN16(v) 	(readb(rinfo->bios_seg + (v)) | \
@@ -484,7 +568,7 @@
 }
 
 
-static inline void _radeon_fifo_wait (struct radeonfb_info *rinfo, int entries)
+static inline void _radeon_fifo_wait(struct radeonfb_info *rinfo, int entries)
 {
 	int i;
 
@@ -497,7 +581,7 @@
 }
 
 
-static inline void _radeon_engine_idle (struct radeonfb_info *rinfo)
+static inline void _radeon_engine_idle(struct radeonfb_info *rinfo)
 {
 	int i;
 
@@ -514,8 +598,24 @@
 	printk(KERN_ERR "radeonfb: Idle Timeout !\n");
 }
 
+/* Note about this function: we have some rare cases where we must not schedule,
+ * this typically happen with our special "wake up early" hook which allows us to
+ * wake up the graphic chip (and thus get the console back) before everything else
+ * on some machines that support that mecanism. At this point, interrupts are off
+ * and scheduling is not permitted
+ */
+static inline void _radeon_msleep(struct radeonfb_info *rinfo, unsigned long ms)
+{
+	if (rinfo->no_schedule)
+		mdelay(ms);
+	else
+		msleep(ms);
+}
+
+
 #define radeon_engine_idle()		_radeon_engine_idle(rinfo)
 #define radeon_fifo_wait(entries)	_radeon_fifo_wait(rinfo,entries)
+#define radeon_msleep(ms)		_radeon_msleep(rinfo,ms)
 
 
 /* I2C Functions */
@@ -524,10 +624,10 @@
 extern int radeon_probe_i2c_connector(struct radeonfb_info *rinfo, int conn, u8 **out_edid);
 
 /* PM Functions */
-extern void radeon_pm_disable_dynamic_mode(struct radeonfb_info *rinfo);
-extern void radeon_pm_enable_dynamic_mode(struct radeonfb_info *rinfo);
 extern int radeonfb_pci_suspend(struct pci_dev *pdev, u32 state);
 extern int radeonfb_pci_resume(struct pci_dev *pdev);
+extern void radeonfb_pm_init(struct radeonfb_info *rinfo, int dynclk);
+extern void radeonfb_pm_exit(struct radeonfb_info *rinfo);
 
 /* Monitor probe functions */
 extern void radeon_probe_screens(struct radeonfb_info *rinfo,
@@ -546,7 +646,9 @@
 extern void radeonfb_engine_reset(struct radeonfb_info *rinfo);
 
 /* Other functions */
-extern int radeonfb_blank(int blank, struct fb_info *info);
-extern int radeonfb_set_par(struct fb_info *info);
+extern int radeon_screen_blank(struct radeonfb_info *rinfo, int blank, int mode_switch);
+extern void radeon_save_state (struct radeonfb_info *rinfo, struct radeon_regs *save);
+extern void radeon_write_mode (struct radeonfb_info *rinfo, struct radeon_regs *mode,
+			       int reg_only);
 
 #endif /* __RADEONFB_H__ */
diff -Nru a/drivers/video/aty/xlinit.c b/drivers/video/aty/xlinit.c
--- a/drivers/video/aty/xlinit.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/video/aty/xlinit.c	2005-03-01 23:38:57 -08:00
@@ -105,19 +105,6 @@
 	{ 0x37,	0x00000000 }
 };
 
-static inline u32 aty_ld_lcd(u8 lcd_reg, struct atyfb_par *par)
-{
-	aty_st_8(LCD_INDEX, lcd_reg, par);
-	return aty_ld_le32(LCD_DATA, par);
-}
-
-static inline void aty_st_lcd(u8 lcd_reg, u32 val,
-			      struct atyfb_par *par)
-{
-	aty_st_8(LCD_INDEX, lcd_reg, par);
-	aty_st_le32(LCD_DATA, val, par);
-}
-
 static void reset_gui(struct atyfb_par *par)
 {
 	aty_st_8(GEN_TEST_CNTL+1, 0x01, par);
@@ -205,7 +192,7 @@
 		// the MCLK, XCLK are 120MHz on victoria card
 		par->mclk_per = 1000000/120;
 		par->xclk_per = 1000000/120;
-		par->features &= ~M64F_MFB_TIMES_4;
+		par->features &= ~M64F_MFB_FORCE_4;
 	}
 	
 	/*
diff -Nru a/drivers/video/au1100fb.c b/drivers/video/au1100fb.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/video/au1100fb.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,676 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ *	Au1100 LCD Driver.
+ *
+ * Copyright 2002 MontaVista Software
+ * Author: MontaVista Software, Inc.
+ *		ppopov@mvista.com or source@mvista.com
+ *
+ * Copyright 2002 Alchemy Semiconductor
+ * Author: Alchemy Semiconductor
+ *
+ * Based on:
+ * linux/drivers/video/skeletonfb.c -- Skeleton for a frame buffer device
+ *  Created 28 Dec 1997 by Geert Uytterhoeven
+ *
+ *  This program is free software; you can redistribute	 it and/or modify it
+ *  under  the terms of	 the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the	License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED	  ``AS	IS'' AND   ANY	EXPRESS OR IMPLIED
+ *  WARRANTIES,	  INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO	EVENT  SHALL   THE AUTHOR  BE	 LIABLE FOR ANY	  DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED	  TO, PROCUREMENT OF  SUBSTITUTE GOODS	OR SERVICES; LOSS OF
+ *  USE, DATA,	OR PROFITS; OR	BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN	 CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+
+#include <asm/au1000.h>
+#include <asm/pb1100.h>
+#include "au1100fb.h"
+
+#include <video/fbcon.h>
+#include <video/fbcon-mfb.h>
+#include <video/fbcon-cfb2.h>
+#include <video/fbcon-cfb4.h>
+#include <video/fbcon-cfb8.h>
+#include <video/fbcon-cfb16.h>
+
+/*
+ * Sanity check. If this is a new Au1100 based board, search for
+ * the PB1100 ifdefs to make sure you modify the code accordingly.
+ */
+#if defined(CONFIG_MIPS_PB1100) || defined(CONFIG_MIPS_DB1100) || defined(CONFIG_MIPS_HYDROGEN3)
+#else
+error Unknown Au1100 board
+#endif
+
+#define CMAPSIZE 16
+
+static int my_lcd_index; /* default is zero */
+struct known_lcd_panels *p_lcd;
+AU1100_LCD *p_lcd_reg = (AU1100_LCD *)AU1100_LCD_ADDR;
+
+struct au1100fb_info {
+	struct fb_info_gen gen;
+	unsigned long fb_virt_start;
+	unsigned long fb_size;
+	unsigned long fb_phys;
+	int mmaped;
+	int nohwcursor;
+
+	struct { unsigned red, green, blue, pad; } palette[256];
+
+#if defined(FBCON_HAS_CFB16)
+	u16 fbcon_cmap16[16];
+#endif
+};
+
+
+struct au1100fb_par {
+        struct fb_var_screeninfo var;
+
+	int line_length;  // in bytes
+	int cmap_len;     // color-map length
+};
+
+
+static struct au1100fb_info fb_info;
+static struct au1100fb_par current_par;
+static struct display disp;
+
+int au1100fb_init(void);
+void au1100fb_setup(char *options, int *ints);
+static int au1100fb_mmap(struct fb_info *fb, struct file *file,
+		struct vm_area_struct *vma);
+static int au1100_blank(int blank_mode, struct fb_info_gen *info);
+static int au1100fb_ioctl(struct inode *inode, struct file *file, u_int cmd,
+			  u_long arg, int con, struct fb_info *info);
+
+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,
+};
+
+static void au1100_detect(void)
+{
+	/*
+	 *  This function should detect the current video mode settings
+	 *  and store it as the default video mode
+	 */
+
+	/*
+	 * Yeh, well, we're not going to change any settings so we're
+	 * always stuck with the default ...
+	 */
+
+}
+
+static int au1100_encode_fix(struct fb_fix_screeninfo *fix,
+		const void *_par, struct fb_info_gen *_info)
+{
+        struct au1100fb_info *info = (struct au1100fb_info *) _info;
+        struct au1100fb_par *par = (struct au1100fb_par *) _par;
+	struct fb_var_screeninfo *var = &par->var;
+
+	memset(fix, 0, sizeof(struct fb_fix_screeninfo));
+
+	fix->smem_start = info->fb_phys;
+	fix->smem_len = info->fb_size;
+	fix->type = FB_TYPE_PACKED_PIXELS;
+	fix->type_aux = 0;
+        fix->visual = (var->bits_per_pixel == 8) ?
+	       	FB_VISUAL_PSEUDOCOLOR	: FB_VISUAL_TRUECOLOR;
+	fix->ywrapstep = 0;
+	fix->xpanstep = 1;
+	fix->ypanstep = 1;
+	fix->line_length = current_par.line_length;
+	return 0;
+}
+
+static void set_color_bitfields(struct fb_var_screeninfo *var)
+{
+	switch (var->bits_per_pixel) {
+	case 8:
+		var->red.offset = 0;
+		var->red.length = 8;
+		var->green.offset = 0;
+		var->green.length = 8;
+		var->blue.offset = 0;
+		var->blue.length = 8;
+		var->transp.offset = 0;
+		var->transp.length = 0;
+		break;
+	case 16:	/* RGB 565 */
+		var->red.offset = 11;
+		var->red.length = 5;
+		var->green.offset = 5;
+		var->green.length = 6;
+		var->blue.offset = 0;
+		var->blue.length = 5;
+		var->transp.offset = 0;
+		var->transp.length = 0;
+		break;
+	}
+
+	var->red.msb_right = 0;
+	var->green.msb_right = 0;
+	var->blue.msb_right = 0;
+	var->transp.msb_right = 0;
+}
+
+static int au1100_decode_var(const struct fb_var_screeninfo *var,
+		void *_par, struct fb_info_gen *_info)
+{
+
+	struct au1100fb_par *par = (struct au1100fb_par *)_par;
+
+	/*
+	 * Don't allow setting any of these yet: xres and yres don't
+	 * make sense for LCD panels.
+	 */
+	if (var->xres != p_lcd->xres ||
+	    var->yres != p_lcd->yres ||
+	    var->xres != p_lcd->xres ||
+	    var->yres != p_lcd->yres) {
+		return -EINVAL;
+	}
+	if(var->bits_per_pixel != p_lcd->bpp) {
+		return -EINVAL;
+	}
+
+	memset(par, 0, sizeof(struct au1100fb_par));
+	par->var = *var;
+
+	/* FIXME */
+	switch (var->bits_per_pixel) {
+		case 8:
+			par->var.bits_per_pixel = 8;
+			break;
+		case 16:
+			par->var.bits_per_pixel = 16;
+			break;
+		default:
+			printk("color depth %d bpp not supported\n",
+					var->bits_per_pixel);
+			return -EINVAL;
+
+	}
+	set_color_bitfields(&par->var);
+	par->cmap_len = (par->var.bits_per_pixel == 8) ? 256 : 16;
+	return 0;
+}
+
+static int au1100_encode_var(struct fb_var_screeninfo *var,
+		const void *par, struct fb_info_gen *_info)
+{
+
+	*var = ((struct au1100fb_par *)par)->var;
+	return 0;
+}
+
+static void
+au1100_get_par(void *_par, struct fb_info_gen *_info)
+{
+	*(struct au1100fb_par *)_par = current_par;
+}
+
+static void au1100_set_par(const void *par, struct fb_info_gen *info)
+{
+	/* nothing to do: we don't change any settings */
+}
+
+static int au1100_getcolreg(unsigned regno, unsigned *red, unsigned *green,
+			 unsigned *blue, unsigned *transp,
+			 struct fb_info *info)
+{
+
+	struct au1100fb_info* i = (struct au1100fb_info*)info;
+
+	if (regno > 255)
+		return 1;
+
+	*red    = i->palette[regno].red;
+	*green  = i->palette[regno].green;
+	*blue   = i->palette[regno].blue;
+	*transp = 0;
+
+	return 0;
+}
+
+static int au1100_setcolreg(unsigned regno, unsigned red, unsigned green,
+			 unsigned blue, unsigned transp,
+			 struct fb_info *info)
+{
+	struct au1100fb_info* i = (struct au1100fb_info *)info;
+	u32 rgbcol;
+
+	if (regno > 255)
+		return 1;
+
+	i->palette[regno].red    = red;
+	i->palette[regno].green  = green;
+	i->palette[regno].blue   = blue;
+
+	switch(p_lcd->bpp) {
+#ifdef FBCON_HAS_CFB8
+	case 8:
+		red >>= 10;
+		green >>= 10;
+		blue >>= 10;
+		p_lcd_reg->lcd_pallettebase[regno] = (blue&0x1f) |
+			((green&0x3f)<<5) | ((red&0x1f)<<11);
+		break;
+#endif
+#ifdef FBCON_HAS_CFB16
+	case 16:
+		i->fbcon_cmap16[regno] =
+			((red & 0xf800) >> 0) |
+			((green & 0xfc00) >> 5) |
+			((blue & 0xf800) >> 11);
+		break;
+#endif
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+
+static int  au1100_blank(int blank_mode, struct fb_info_gen *_info)
+{
+
+	switch (blank_mode) {
+	case VESA_NO_BLANKING:
+		/* turn on panel */
+		//printk("turn on panel\n");
+#ifdef CONFIG_MIPS_PB1100
+		p_lcd_reg->lcd_control |= LCD_CONTROL_GO;
+		au_writew(au_readw(PB1100_G_CONTROL) | p_lcd->mode_backlight,
+			PB1100_G_CONTROL);
+#endif
+#ifdef CONFIG_MIPS_HYDROGEN3
+		/*  Turn controller & power supply on,  GPIO213 */
+		au_writel(0x20002000, 0xB1700008);
+		au_writel(0x00040000, 0xB1900108);
+		au_writel(0x01000100, 0xB1700008);
+#endif
+		au_sync();
+		break;
+
+	case VESA_VSYNC_SUSPEND:
+	case VESA_HSYNC_SUSPEND:
+	case VESA_POWERDOWN:
+		/* turn off panel */
+		//printk("turn off panel\n");
+#ifdef CONFIG_MIPS_PB1100
+		au_writew(au_readw(PB1100_G_CONTROL) & ~p_lcd->mode_backlight,
+			PB1100_G_CONTROL);
+		p_lcd_reg->lcd_control &= ~LCD_CONTROL_GO;
+#endif
+		au_sync();
+		break;
+	default:
+		break;
+
+	}
+	return 0;
+}
+
+static void au1100_set_disp(const void *unused, struct display *disp,
+			 struct fb_info_gen *info)
+{
+	disp->screen_base = (char *)fb_info.fb_virt_start;
+
+	switch (disp->var.bits_per_pixel) {
+#ifdef FBCON_HAS_CFB8
+	case 8:
+		disp->dispsw = &fbcon_cfb8;
+		if (fb_info.nohwcursor)
+			fbcon_cfb8.cursor = au1100_nocursor;
+		break;
+#endif
+#ifdef FBCON_HAS_CFB16
+	case 16:
+		disp->dispsw = &fbcon_cfb16;
+		disp->dispsw_data = fb_info.fbcon_cmap16;
+		if (fb_info.nohwcursor)
+			fbcon_cfb16.cursor = au1100_nocursor;
+		break;
+#endif
+	default:
+		disp->dispsw = &fbcon_dummy;
+		disp->dispsw_data = NULL;
+		break;
+	}
+}
+
+static int
+au1100fb_mmap(struct fb_info *_fb,
+	     struct file *file,
+	     struct vm_area_struct *vma)
+{
+	unsigned int len;
+	unsigned long start=0, off;
+	struct au1100fb_info *fb = (struct au1100fb_info *)_fb;
+
+	if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) {
+		return -EINVAL;
+	}
+
+	start = fb_info.fb_phys & PAGE_MASK;
+	len = PAGE_ALIGN((start & ~PAGE_MASK) + fb_info.fb_size);
+
+	off = vma->vm_pgoff << PAGE_SHIFT;
+
+	if ((vma->vm_end - vma->vm_start + off) > len) {
+		return -EINVAL;
+	}
+
+	off += start;
+	vma->vm_pgoff = off >> PAGE_SHIFT;
+
+	pgprot_val(vma->vm_page_prot) &= ~_CACHE_MASK;
+	//pgprot_val(vma->vm_page_prot) |= _CACHE_CACHABLE_NONCOHERENT;
+	pgprot_val(vma->vm_page_prot) |= (6 << 9); //CCA=6
+
+	/* This is an IO map - tell maydump to skip this VMA */
+	vma->vm_flags |= VM_IO;
+
+	if (io_remap_page_range(vma, vma->vm_start, off,
+				vma->vm_end - vma->vm_start,
+				vma->vm_page_prot)) {
+		return -EAGAIN;
+	}
+
+	fb->mmaped = 1;
+	return 0;
+}
+
+int au1100_pan_display(const struct fb_var_screeninfo *var,
+		       struct fb_info_gen *info)
+{
+	return 0;
+}
+
+static int au1100fb_ioctl(struct inode *inode, struct file *file, u_int cmd,
+			  u_long arg, int con, struct fb_info *info)
+{
+	/* nothing to do yet */
+	return -EINVAL;
+}
+
+static struct fbgen_hwswitch au1100_switch = {
+	au1100_detect,
+	au1100_encode_fix,
+	au1100_decode_var,
+	au1100_encode_var,
+	au1100_get_par,
+	au1100_set_par,
+	au1100_getcolreg,
+	au1100_setcolreg,
+	au1100_pan_display,
+	au1100_blank,
+	au1100_set_disp
+};
+
+
+int au1100_setmode(void)
+{
+	int words;
+
+	/* FIXME Need to accomodate for swivel mode and 12bpp, <8bpp*/
+	switch (p_lcd->mode_control & LCD_CONTROL_SM)
+	{
+		case LCD_CONTROL_SM_0:
+		case LCD_CONTROL_SM_180:
+		words = (p_lcd->xres * p_lcd->yres * p_lcd->bpp) / 32;
+			break;
+		case LCD_CONTROL_SM_90:
+		case LCD_CONTROL_SM_270:
+			/* is this correct? */
+		words = (p_lcd->xres * p_lcd->bpp) / 8;
+			break;
+		default:
+			printk("mode_control reg not initialized\n");
+			return -EINVAL;
+	}
+
+	/*
+	 * Setup LCD controller
+	 */
+
+	p_lcd_reg->lcd_control = p_lcd->mode_control;
+	p_lcd_reg->lcd_intstatus = 0;
+	p_lcd_reg->lcd_intenable = 0;
+	p_lcd_reg->lcd_horztiming = p_lcd->mode_horztiming;
+	p_lcd_reg->lcd_verttiming = p_lcd->mode_verttiming;
+	p_lcd_reg->lcd_clkcontrol = p_lcd->mode_clkcontrol;
+	p_lcd_reg->lcd_words = words - 1;
+	p_lcd_reg->lcd_dmaaddr0 = fb_info.fb_phys;
+
+	/* turn on panel */
+#ifdef CONFIG_MIPS_PB1100
+	au_writew(au_readw(PB1100_G_CONTROL) | p_lcd->mode_backlight,
+			PB1100_G_CONTROL);
+#endif
+#ifdef CONFIG_MIPS_HYDROGEN3
+	/*  Turn controller & power supply on,  GPIO213 */
+	au_writel(0x20002000, 0xB1700008);
+	au_writel(0x00040000, 0xB1900108);
+	au_writel(0x01000100, 0xB1700008);
+#endif
+
+	p_lcd_reg->lcd_control |= LCD_CONTROL_GO;
+
+	return 0;
+}
+
+
+int __init au1100fb_init(void)
+{
+	uint32 sys_clksrc;
+	unsigned long page;
+
+	/*
+	* Get the panel information/display mode and update the registry
+	*/
+	p_lcd = &panels[my_lcd_index];
+
+	switch (p_lcd->mode_control & LCD_CONTROL_SM)
+	{
+		case LCD_CONTROL_SM_0:
+		case LCD_CONTROL_SM_180:
+		p_lcd->xres =
+			(p_lcd->mode_horztiming & LCD_HORZTIMING_PPL) + 1;
+		p_lcd->yres =
+			(p_lcd->mode_verttiming & LCD_VERTTIMING_LPP) + 1;
+			break;
+		case LCD_CONTROL_SM_90:
+		case LCD_CONTROL_SM_270:
+		p_lcd->yres =
+			(p_lcd->mode_horztiming & LCD_HORZTIMING_PPL) + 1;
+		p_lcd->xres =
+			(p_lcd->mode_verttiming & LCD_VERTTIMING_LPP) + 1;
+			break;
+	}
+
+	/*
+	 * Panel dimensions x bpp must be divisible by 32
+	 */
+	if (((p_lcd->yres * p_lcd->bpp) % 32) != 0)
+		printk("VERT %% 32\n");
+	if (((p_lcd->xres * p_lcd->bpp) % 32) != 0)
+		printk("HORZ %% 32\n");
+
+	/*
+	 * Allocate LCD framebuffer from system memory
+	 */
+	fb_info.fb_size = (p_lcd->xres * p_lcd->yres * p_lcd->bpp) / 8;
+
+	current_par.var.xres = p_lcd->xres;
+	current_par.var.xres_virtual = p_lcd->xres;
+	current_par.var.yres = p_lcd->yres;
+	current_par.var.yres_virtual = p_lcd->yres;
+	current_par.var.bits_per_pixel = p_lcd->bpp;
+
+	/* FIX!!! only works for 8/16 bpp */
+	current_par.line_length = p_lcd->xres * p_lcd->bpp / 8; /* in bytes */
+	fb_info.fb_virt_start = (unsigned long )
+		__get_free_pages(GFP_ATOMIC | GFP_DMA,
+				get_order(fb_info.fb_size + 0x1000));
+	if (!fb_info.fb_virt_start) {
+		printk("Unable to allocate fb memory\n");
+		return -ENOMEM;
+	}
+	fb_info.fb_phys = virt_to_bus((void *)fb_info.fb_virt_start);
+
+	/*
+	 * Set page reserved so that mmap will work. This is necessary
+	 * since we'll be remapping normal memory.
+	 */
+	for (page = fb_info.fb_virt_start;
+	     page < PAGE_ALIGN(fb_info.fb_virt_start + fb_info.fb_size);
+	     page += PAGE_SIZE) {
+		SetPageReserved(virt_to_page(page));
+	}
+
+	memset((void *)fb_info.fb_virt_start, 0, fb_info.fb_size);
+
+	/* set freqctrl now to allow more time to stabilize */
+	/* zero-out out LCD bits */
+	sys_clksrc = au_readl(SYS_CLKSRC) & ~0x000003e0;
+	sys_clksrc |= p_lcd->mode_toyclksrc;
+	au_writel(sys_clksrc, SYS_CLKSRC);
+
+	/* FIXME add check to make sure auxpll is what is expected! */
+	au1100_setmode();
+
+	fb_info.gen.parsize = sizeof(struct au1100fb_par);
+	fb_info.gen.fbhw = &au1100_switch;
+
+	strcpy(fb_info.gen.info.modename, "Au1100 LCD");
+	fb_info.gen.info.changevar = NULL;
+	fb_info.gen.info.node = -1;
+
+	fb_info.gen.info.fbops = &au1100fb_ops;
+	fb_info.gen.info.disp = &disp;
+	fb_info.gen.info.switch_con = &fbgen_switch;
+	fb_info.gen.info.updatevar = &fbgen_update_var;
+	fb_info.gen.info.blank = &fbgen_blank;
+	fb_info.gen.info.flags = FBINFO_FLAG_DEFAULT;
+
+	/* This should give a reasonable default video mode */
+	fbgen_get_var(&disp.var, -1, &fb_info.gen.info);
+	fbgen_do_set_var(&disp.var, 1, &fb_info.gen);
+	fbgen_set_disp(-1, &fb_info.gen);
+	fbgen_install_cmap(0, &fb_info.gen);
+	if (register_framebuffer(&fb_info.gen.info) < 0)
+		return -EINVAL;
+	printk(KERN_INFO "fb%d: %s frame buffer device\n",
+			GET_FB_IDX(fb_info.gen.info.node),
+			fb_info.gen.info.modename);
+
+	return 0;
+}
+
+
+void au1100fb_cleanup(struct fb_info *info)
+{
+	unregister_framebuffer(info);
+}
+
+
+void au1100fb_setup(char *options, int *ints)
+{
+	char* this_opt;
+	int i;
+	int num_panels = sizeof(panels)/sizeof(struct known_lcd_panels);
+
+
+	if (!options || !*options)
+		return;
+
+	for(this_opt=strtok(options, ","); this_opt;
+	    this_opt=strtok(NULL, ",")) {
+		if (!strncmp(this_opt, "panel:", 6)) {
+#if defined(CONFIG_MIPS_PB1100) || defined(CONFIG_MIPS_DB1100)
+			/* Read Pb1100 Switch S10 ? */
+			if (!strncmp(this_opt+6, "s10", 3))
+			{
+				int panel;
+				panel = *(volatile int *)0xAE000008; /* BCSR SWITCHES */
+				panel >>= 8;
+				panel &= 0x0F;
+				if (panel >= num_panels) panel = 0;
+				my_lcd_index = panel;
+			}
+			else
+#endif
+			/* Get the panel name, everything else if fixed */
+			for (i=0; i<num_panels; i++) {
+				if (!strncmp(this_opt+6, panels[i].panel_name,
+							strlen(this_opt))) {
+					my_lcd_index = i;
+					break;
+				}
+			}
+		}
+		else if (!strncmp(this_opt, "nohwcursor", 10)) {
+			printk("nohwcursor\n");
+			fb_info.nohwcursor = 1;
+		}
+	}
+
+	printk("au1100fb: Panel %d %s\n", my_lcd_index,
+		panels[my_lcd_index].panel_name);
+}
+
+
+
+#ifdef MODULE
+MODULE_LICENSE("GPL");
+int init_module(void)
+{
+	return au1100fb_init();
+}
+
+void cleanup_module(void)
+{
+	au1100fb_cleanup(void);
+}
+
+MODULE_AUTHOR("Pete Popov <ppopov@mvista.com>");
+MODULE_DESCRIPTION("Au1100 LCD framebuffer device driver");
+#endif /* MODULE */
diff -Nru a/drivers/video/au1100fb.h b/drivers/video/au1100fb.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/video/au1100fb.h	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,381 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ *	Hardware definitions for the Au1100 LCD controller
+ *
+ * Copyright 2002 MontaVista Software
+ * Copyright 2002 Alchemy Semiconductor
+ * Author:	Alchemy Semiconductor, MontaVista Software
+ *
+ *  This program is free software; you can redistribute	 it and/or modify it
+ *  under  the terms of	 the GNU 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 _AU1100LCD_H
+#define _AU1100LCD_H
+
+/********************************************************************/
+#define uint32 unsigned long
+typedef volatile struct
+{
+	uint32	lcd_control;
+	uint32	lcd_intstatus;
+	uint32	lcd_intenable;
+	uint32	lcd_horztiming;
+	uint32	lcd_verttiming;
+	uint32	lcd_clkcontrol;
+	uint32	lcd_dmaaddr0;
+	uint32	lcd_dmaaddr1;
+	uint32	lcd_words;
+	uint32	lcd_pwmdiv;
+	uint32	lcd_pwmhi;
+	uint32	reserved[(0x0400-0x002C)/4];
+	uint32	lcd_pallettebase[256];
+
+} AU1100_LCD;
+
+/********************************************************************/
+
+#define AU1100_LCD_ADDR		0xB5000000
+
+/*
+ * Register bit definitions
+ */
+
+/* lcd_control */
+#define LCD_CONTROL_SBPPF		(7<<18)
+#define LCD_CONTROL_SBPPF_655	(0<<18)
+#define LCD_CONTROL_SBPPF_565	(1<<18)
+#define LCD_CONTROL_SBPPF_556	(2<<18)
+#define LCD_CONTROL_SBPPF_1555	(3<<18)
+#define LCD_CONTROL_SBPPF_5551	(4<<18)
+#define LCD_CONTROL_WP			(1<<17)
+#define LCD_CONTROL_WD			(1<<16)
+#define LCD_CONTROL_C			(1<<15)
+#define LCD_CONTROL_SM			(3<<13)
+#define LCD_CONTROL_SM_0		(0<<13)
+#define LCD_CONTROL_SM_90		(1<<13)
+#define LCD_CONTROL_SM_180		(2<<13)
+#define LCD_CONTROL_SM_270		(3<<13)
+#define LCD_CONTROL_DB			(1<<12)
+#define LCD_CONTROL_CCO			(1<<11)
+#define LCD_CONTROL_DP			(1<<10)
+#define LCD_CONTROL_PO			(3<<8)
+#define LCD_CONTROL_PO_00		(0<<8)
+#define LCD_CONTROL_PO_01		(1<<8)
+#define LCD_CONTROL_PO_10		(2<<8)
+#define LCD_CONTROL_PO_11		(3<<8)
+#define LCD_CONTROL_MPI			(1<<7)
+#define LCD_CONTROL_PT			(1<<6)
+#define LCD_CONTROL_PC			(1<<5)
+#define LCD_CONTROL_BPP			(7<<1)
+#define LCD_CONTROL_BPP_1		(0<<1)
+#define LCD_CONTROL_BPP_2		(1<<1)
+#define LCD_CONTROL_BPP_4		(2<<1)
+#define LCD_CONTROL_BPP_8		(3<<1)
+#define LCD_CONTROL_BPP_12		(4<<1)
+#define LCD_CONTROL_BPP_16		(5<<1)
+#define LCD_CONTROL_GO			(1<<0)
+
+/* lcd_intstatus, lcd_intenable */
+#define LCD_INT_SD				(1<<7)
+#define LCD_INT_OF				(1<<6)
+#define LCD_INT_UF				(1<<5)
+#define LCD_INT_SA				(1<<3)
+#define LCD_INT_SS				(1<<2)
+#define LCD_INT_S1				(1<<1)
+#define LCD_INT_S0				(1<<0)
+
+/* lcd_horztiming */
+#define LCD_HORZTIMING_HN2		(255<<24)
+#define LCD_HORZTIMING_HN2_N(N)	(((N)-1)<<24)
+#define LCD_HORZTIMING_HN1		(255<<16)
+#define LCD_HORZTIMING_HN1_N(N)	(((N)-1)<<16)
+#define LCD_HORZTIMING_HPW		(63<<10)
+#define LCD_HORZTIMING_HPW_N(N)	(((N)-1)<<10)
+#define LCD_HORZTIMING_PPL		(1023<<0)
+#define LCD_HORZTIMING_PPL_N(N)	(((N)-1)<<0)
+
+/* lcd_verttiming */
+#define LCD_VERTTIMING_VN2		(255<<24)
+#define LCD_VERTTIMING_VN2_N(N)	(((N)-1)<<24)
+#define LCD_VERTTIMING_VN1		(255<<16)
+#define LCD_VERTTIMING_VN1_N(N)	(((N)-1)<<16)
+#define LCD_VERTTIMING_VPW		(63<<10)
+#define LCD_VERTTIMING_VPW_N(N)	(((N)-1)<<10)
+#define LCD_VERTTIMING_LPP		(1023<<0)
+#define LCD_VERTTIMING_LPP_N(N)	(((N)-1)<<0)
+
+/* lcd_clkcontrol */
+#define LCD_CLKCONTROL_IB		(1<<18)
+#define LCD_CLKCONTROL_IC		(1<<17)
+#define LCD_CLKCONTROL_IH		(1<<16)
+#define LCD_CLKCONTROL_IV		(1<<15)
+#define LCD_CLKCONTROL_BF		(31<<10)
+#define LCD_CLKCONTROL_BF_N(N)	(((N)-1)<<10)
+#define LCD_CLKCONTROL_PCD		(1023<<0)
+#define LCD_CLKCONTROL_PCD_N(N)	((N)<<0)
+
+/* lcd_pwmdiv */
+#define LCD_PWMDIV_EN			(1<<12)
+#define LCD_PWMDIV_PWMDIV		(2047<<0)
+#define LCD_PWMDIV_PWMDIV_N(N)	(((N)-1)<<0)
+
+/* lcd_pwmhi */
+#define LCD_PWMHI_PWMHI1		(2047<<12)
+#define LCD_PWMHI_PWMHI1_N(N)	((N)<<12)
+#define LCD_PWMHI_PWMHI0		(2047<<0)
+#define LCD_PWMHI_PWMHI0_N(N)	((N)<<0)
+
+/* lcd_pallettebase - MONOCHROME */
+#define LCD_PALLETTE_MONO_MI		(15<<0)
+#define LCD_PALLETTE_MONO_MI_N(N)	((N)<<0)
+
+/* lcd_pallettebase - COLOR */
+#define LCD_PALLETTE_COLOR_BI		(15<<8)
+#define LCD_PALLETTE_COLOR_BI_N(N)	((N)<<8)
+#define LCD_PALLETTE_COLOR_GI		(15<<4)
+#define LCD_PALLETTE_COLOR_GI_N(N)	((N)<<4)
+#define LCD_PALLETTE_COLOR_RI		(15<<0)
+#define LCD_PALLETTE_COLOR_RI_N(N)	((N)<<0)
+
+/* lcd_palletebase - COLOR TFT PALLETIZED */
+#define LCD_PALLETTE_TFT_DC			(65535<<0)
+#define LCD_PALLETTE_TFT_DC_N(N)	((N)<<0)
+
+/********************************************************************/
+
+struct known_lcd_panels
+{
+	uint32 xres;
+	uint32 yres;
+	uint32 bpp;
+	unsigned char  panel_name[256];
+	uint32 mode_control;
+	uint32 mode_horztiming;
+	uint32 mode_verttiming;
+	uint32 mode_clkcontrol;
+	uint32 mode_pwmdiv;
+	uint32 mode_pwmhi;
+	uint32 mode_toyclksrc;
+	uint32 mode_backlight;
+
+};
+
+#if defined(__BIG_ENDIAN)
+#define LCD_DEFAULT_PIX_FORMAT LCD_CONTROL_PO_11
+#else
+#define LCD_DEFAULT_PIX_FORMAT LCD_CONTROL_PO_00
+#endif
+
+/*
+ * The fb driver assumes that AUX PLL is at 48MHz.  That can
+ * cover up to 800x600 resolution; if you need higher resolution,
+ * you should modify the driver as needed, not just this structure.
+ */
+struct known_lcd_panels panels[] =
+{
+	{ /* 0: Pb1100 LCDA: Sharp 320x240 TFT panel */
+		320, /* xres */
+		240, /* yres */
+		16,  /* bpp  */
+
+		"Sharp_320x240_16",
+		/* mode_control */
+		( LCD_CONTROL_SBPPF_565
+		/*LCD_CONTROL_WP*/
+		/*LCD_CONTROL_WD*/
+		| LCD_CONTROL_C
+		| LCD_CONTROL_SM_0
+		/*LCD_CONTROL_DB*/
+		/*LCD_CONTROL_CCO*/
+		/*LCD_CONTROL_DP*/
+		| LCD_DEFAULT_PIX_FORMAT
+		/*LCD_CONTROL_MPI*/
+		| LCD_CONTROL_PT
+		| LCD_CONTROL_PC
+		| LCD_CONTROL_BPP_16 ),
+
+		/* mode_horztiming */
+		( LCD_HORZTIMING_HN2_N(8)
+		| LCD_HORZTIMING_HN1_N(60)
+		| LCD_HORZTIMING_HPW_N(12)
+		| LCD_HORZTIMING_PPL_N(320) ),
+
+		/* mode_verttiming */
+		( LCD_VERTTIMING_VN2_N(5)
+		| LCD_VERTTIMING_VN1_N(17)
+		| LCD_VERTTIMING_VPW_N(1)
+		| LCD_VERTTIMING_LPP_N(240) ),
+
+		/* mode_clkcontrol */
+		( 0
+		/*LCD_CLKCONTROL_IB*/
+		/*LCD_CLKCONTROL_IC*/
+		/*LCD_CLKCONTROL_IH*/
+		/*LCD_CLKCONTROL_IV*/
+		| LCD_CLKCONTROL_PCD_N(1) ),
+
+		/* mode_pwmdiv */
+		0,
+
+		/* mode_pwmhi */
+		0,
+
+		/* mode_toyclksrc */
+		((1<<7) | (1<<6) | (1<<5)),
+
+		/* mode_backlight */
+		6
+	},
+
+	{ /* 1: Pb1100 LCDC 640x480 TFT panel */
+		640, /* xres */
+		480, /* yres */
+		16,  /* bpp  */
+
+		"Generic_640x480_16",
+
+		/* mode_control */
+		0x004806a | LCD_DEFAULT_PIX_FORMAT,
+
+		/* mode_horztiming */
+		0x3434d67f,
+
+		/* mode_verttiming */
+		0x0e0e39df,
+
+		/* mode_clkcontrol */
+		( 0
+		/*LCD_CLKCONTROL_IB*/
+		/*LCD_CLKCONTROL_IC*/
+		/*LCD_CLKCONTROL_IH*/
+		/*LCD_CLKCONTROL_IV*/
+		| LCD_CLKCONTROL_PCD_N(1) ),
+
+		/* mode_pwmdiv */
+		0,
+
+		/* mode_pwmhi */
+		0,
+
+		/* mode_toyclksrc */
+		((1<<7) | (1<<6) | (0<<5)),
+
+		/* mode_backlight */
+		7
+	},
+
+	{ /* 2: Pb1100 LCDB 640x480 PrimeView TFT panel */
+		640, /* xres */
+		480, /* yres */
+		16,  /* bpp  */
+
+		"PrimeView_640x480_16",
+
+		/* mode_control */
+		0x0004886a | LCD_DEFAULT_PIX_FORMAT,
+
+		/* mode_horztiming */
+		0x0e4bfe7f,
+
+		/* mode_verttiming */
+		0x210805df,
+
+		/* mode_clkcontrol */
+		0x00038001,
+
+		/* mode_pwmdiv */
+		0,
+
+		/* mode_pwmhi */
+		0,
+
+		/* mode_toyclksrc */
+		((1<<7) | (1<<6) | (0<<5)),
+
+		/* mode_backlight */
+		7
+	},
+
+	{ /* 3: Pb1100 800x600x16bpp NEON CRT */
+		800, /* xres */
+		600, /* yres */
+		16,  /* bpp */
+
+		"NEON_800x600_16",
+
+		/* mode_control */
+		0x0004886A | LCD_DEFAULT_PIX_FORMAT,
+
+		/* mode_horztiming */
+		0x005AFF1F,
+
+		/* mode_verttiming */
+		0x16000E57,
+
+		/* mode_clkcontrol */
+		0x00020000,
+
+		/* mode_pwmdiv */
+		0,
+
+		/* mode_pwmhi */
+		0,
+
+		/* mode_toyclksrc */
+		((1<<7) | (1<<6) | (0<<5)),
+
+		/* mode_backlight */
+		7
+	},
+
+	{ /* 4: Pb1100 640x480x16bpp NEON CRT */
+		640, /* xres */
+		480, /* yres */
+		16,  /* bpp */
+
+		"NEON_640x480_16",
+
+		/* mode_control */
+		0x0004886A | LCD_DEFAULT_PIX_FORMAT,
+
+		/* mode_horztiming */
+		0x0052E27F,
+
+		/* mode_verttiming */
+		0x18000DDF,
+
+		/* mode_clkcontrol */
+		0x00020000,
+
+		/* mode_pwmdiv */
+		0,
+
+		/* mode_pwmhi */
+		0,
+
+		/* mode_toyclksrc */
+		((1<<7) | (1<<6) | (0<<5)),
+
+		/* mode_backlight */
+		7
+	},
+};
+#endif /* _AU1100LCD_H */
diff -Nru a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/video/backlight/Kconfig	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,52 @@
+#
+# Backlight & LCD drivers configuration
+#
+
+menuconfig BACKLIGHT_LCD_SUPPORT
+	bool "Backlight & LCD device support"
+	help
+	  Enable this to be able to choose the drivers for controlling the
+	  backlight and the LCD panel on some platforms, for example on PDAs.
+
+config BACKLIGHT_CLASS_DEVICE
+        tristate "Lowlevel Backlight controls"
+	depends on BACKLIGHT_LCD_SUPPORT
+	default m
+	help
+	  This framework adds support for low-level control of the LCD
+          backlight. This includes support for brightness and power.
+
+	  To have support for your specific LCD panel you will have to
+	  select the proper drivers which depend on this option.
+
+config BACKLIGHT_DEVICE
+	bool
+	depends on BACKLIGHT_CLASS_DEVICE
+	default y
+
+config LCD_CLASS_DEVICE
+        tristate "Lowlevel LCD controls"
+	depends on BACKLIGHT_LCD_SUPPORT
+	default m
+	help
+	  This framework adds support for low-level control of LCD.
+	  Some framebuffer devices connect to platform-specific LCD modules
+	  in order to have a platform-specific way to control the flat panel
+	  (contrast and applying power to the LCD (not to the backlight!)).
+
+	  To have support for your specific LCD panel you will have to
+	  select the proper drivers which depend on this option.
+
+config LCD_DEVICE
+	bool
+	depends on LCD_CLASS_DEVICE
+	default y
+
+config BACKLIGHT_CORGI
+	tristate "Sharp Corgi Backlight Driver (SL-C7xx Series)"
+	depends on BACKLIGHT_DEVICE && PXA_SHARPSL
+	default y
+	help
+	  If you have a Sharp Zaurus SL-C7xx, say y to enable the
+	  backlight driver.
+
diff -Nru a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/video/backlight/Makefile	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,5 @@
+# Backlight & LCD drivers
+
+obj-$(CONFIG_LCD_CLASS_DEVICE)     += lcd.o
+obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o
+obj-$(CONFIG_BACKLIGHT_CORGI)	+= corgi_bl.o
diff -Nru a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/video/backlight/backlight.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,264 @@
+/*
+ * Backlight Lowlevel Control Abstraction
+ *
+ * Copyright (C) 2003,2004 Hewlett-Packard Company
+ *
+ */
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/backlight.h>
+#include <linux/notifier.h>
+#include <linux/ctype.h>
+#include <linux/err.h>
+#include <linux/fb.h>
+#include <asm/bug.h>
+
+static ssize_t backlight_show_power(struct class_device *cdev, char *buf)
+{
+	int rc;
+	struct backlight_device *bd = to_backlight_device(cdev);
+
+	down(&bd->sem);
+	if (likely(bd->props && bd->props->get_power))
+		rc = sprintf(buf, "%d\n", bd->props->get_power(bd));
+	else
+		rc = -ENXIO;
+	up(&bd->sem);
+
+	return rc;
+}
+
+static ssize_t backlight_store_power(struct class_device *cdev, const char *buf, size_t count)
+{
+	int rc, power;
+	char *endp;
+	struct backlight_device *bd = to_backlight_device(cdev);
+
+	power = simple_strtoul(buf, &endp, 0);
+	if (*endp && !isspace(*endp))
+		return -EINVAL;
+
+	down(&bd->sem);
+	if (likely(bd->props && bd->props->set_power)) {
+		pr_debug("backlight: set power to %d\n", power);
+		bd->props->set_power(bd, power);
+		rc = count;
+	} else
+		rc = -ENXIO;
+	up(&bd->sem);
+
+	return rc;
+}
+
+static ssize_t backlight_show_brightness(struct class_device *cdev, char *buf)
+{
+	int rc;
+	struct backlight_device *bd = to_backlight_device(cdev);
+
+	down(&bd->sem);
+	if (likely(bd->props && bd->props->get_brightness))
+		rc = sprintf(buf, "%d\n", bd->props->get_brightness(bd));
+	else
+		rc = -ENXIO;
+	up(&bd->sem);
+
+	return rc;
+}
+
+static ssize_t backlight_store_brightness(struct class_device *cdev, const char *buf, size_t count)
+{
+	int rc, brightness;
+	char *endp;
+	struct backlight_device *bd = to_backlight_device(cdev);
+
+	brightness = simple_strtoul(buf, &endp, 0);
+	if (*endp && !isspace(*endp))
+		return -EINVAL;
+
+	down(&bd->sem);
+	if (likely(bd->props && bd->props->set_brightness)) {
+		pr_debug("backlight: set brightness to %d\n", brightness);
+		bd->props->set_brightness(bd, brightness);
+		rc = count;
+	} else
+		rc = -ENXIO;
+	up(&bd->sem);
+
+	return rc;
+}
+
+static ssize_t backlight_show_max_brightness(struct class_device *cdev, char *buf)
+{
+	int rc;
+	struct backlight_device *bd = to_backlight_device(cdev);
+
+	down(&bd->sem);
+	if (likely(bd->props))
+		rc = sprintf(buf, "%d\n", bd->props->max_brightness);
+	else
+		rc = -ENXIO;
+	up(&bd->sem);
+
+	return rc;
+}
+
+static void backlight_class_release(struct class_device *dev)
+{
+	struct backlight_device *bd = to_backlight_device(dev);
+	kfree(bd);
+}
+
+struct class backlight_class = {
+	.name = "backlight",
+	.release = backlight_class_release,
+};
+
+#define DECLARE_ATTR(_name,_mode,_show,_store)			\
+{							 	\
+	.attr	= { .name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE },	\
+	.show	= _show,					\
+	.store	= _store,					\
+}
+
+static struct class_device_attribute bl_class_device_attributes[] = {
+	DECLARE_ATTR(power, 0644, backlight_show_power, backlight_store_power),
+	DECLARE_ATTR(brightness, 0644, backlight_show_brightness, backlight_store_brightness),
+	DECLARE_ATTR(max_brightness, 0444, backlight_show_max_brightness, NULL),
+};
+
+/* This callback gets called when something important happens inside a
+ * framebuffer driver. We're looking if that important event is blanking,
+ * and if it is, we're switching backlight power as well ...
+ */
+static int fb_notifier_callback(struct notifier_block *self,
+				unsigned long event, void *data)
+{
+	struct backlight_device *bd;
+	struct fb_event *evdata =(struct fb_event *)data;
+
+	/* If we aren't interested in this event, skip it immediately ... */
+	if (event != FB_EVENT_BLANK)
+		return 0;
+
+	bd = container_of(self, struct backlight_device, fb_notif);
+	down(&bd->sem);
+	if (bd->props)
+		if (!bd->props->check_fb || bd->props->check_fb(evdata->info))
+			bd->props->set_power(bd, *(int *)evdata->data);
+	up(&bd->sem);
+	return 0;
+}
+
+/**
+ * backlight_device_register - create and register a new object of
+ *   backlight_device class.
+ * @name: the name of the new object(must be the same as the name of the
+ *   respective framebuffer device).
+ * @devdata: an optional pointer to be stored in the class_device. The
+ *   methods may retrieve it by using class_get_devdata(&bd->class_dev).
+ * @bp: the backlight properties structure.
+ *
+ * Creates and registers new backlight class_device. Returns either an
+ * ERR_PTR() or a pointer to the newly allocated device.
+ */
+struct backlight_device *backlight_device_register(const char *name, void *devdata,
+						   struct backlight_properties *bp)
+{
+	int i, rc;
+	struct backlight_device *new_bd;
+
+	pr_debug("backlight_device_alloc: name=%s\n", name);
+
+	new_bd = kmalloc(sizeof(struct backlight_device), GFP_KERNEL);
+	if (unlikely(!new_bd))
+		return ERR_PTR(ENOMEM);
+
+	init_MUTEX(&new_bd->sem);
+	new_bd->props = bp;
+	memset(&new_bd->class_dev, 0, sizeof(new_bd->class_dev));
+	new_bd->class_dev.class = &backlight_class;
+	strlcpy(new_bd->class_dev.class_id, name, KOBJ_NAME_LEN);
+	class_set_devdata(&new_bd->class_dev, devdata);
+
+	rc = class_device_register(&new_bd->class_dev);
+	if (unlikely(rc)) {
+error:		kfree(new_bd);
+		return ERR_PTR(rc);
+	}
+
+	memset(&new_bd->fb_notif, 0, sizeof(new_bd->fb_notif));
+	new_bd->fb_notif.notifier_call = fb_notifier_callback;
+
+	rc = fb_register_client(&new_bd->fb_notif);
+	if (unlikely(rc))
+		goto error;
+
+	for (i = 0; i < ARRAY_SIZE(bl_class_device_attributes); i++) {
+		rc = class_device_create_file(&new_bd->class_dev,
+					      &bl_class_device_attributes[i]);
+		if (unlikely(rc)) {
+			while (--i >= 0)
+				class_device_remove_file(&new_bd->class_dev,
+							 &bl_class_device_attributes[i]);
+			class_device_unregister(&new_bd->class_dev);
+			/* No need to kfree(new_bd) since release() method was called */
+			return ERR_PTR(rc);
+		}
+	}
+
+	return new_bd;
+}
+EXPORT_SYMBOL(backlight_device_register);
+
+/**
+ * backlight_device_unregister - unregisters a backlight device object.
+ * @bd: the backlight device object to be unregistered and freed.
+ *
+ * Unregisters a previously registered via backlight_device_register object.
+ */
+void backlight_device_unregister(struct backlight_device *bd)
+{
+	int i;
+
+	if (!bd)
+		return;
+
+	pr_debug("backlight_device_unregister: name=%s\n", bd->class_dev.class_id);
+
+	for (i = 0; i < ARRAY_SIZE(bl_class_device_attributes); i++)
+		class_device_remove_file(&bd->class_dev,
+					 &bl_class_device_attributes[i]);
+
+	down(&bd->sem);
+	bd->props = NULL;
+	up(&bd->sem);
+
+	fb_unregister_client(&bd->fb_notif);
+
+	class_device_unregister(&bd->class_dev);
+}
+EXPORT_SYMBOL(backlight_device_unregister);
+
+static void __exit backlight_class_exit(void)
+{
+	class_unregister(&backlight_class);
+}
+
+static int __init backlight_class_init(void)
+{
+	return class_register(&backlight_class);
+}
+
+/*
+ * if this is compiled into the kernel, we need to ensure that the
+ * class is registered before users of the class try to register lcd's
+ */
+postcore_initcall(backlight_class_init);
+module_exit(backlight_class_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Jamey Hicks <jamey.hicks@hp.com>, Andrew Zabolotny <zap@homelink.ru>");
+MODULE_DESCRIPTION("Backlight Lowlevel Control Abstraction");
diff -Nru a/drivers/video/backlight/corgi_bl.c b/drivers/video/backlight/corgi_bl.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/video/backlight/corgi_bl.c	2005-03-01 23:39:26 -08:00
@@ -0,0 +1,198 @@
+/*
+ *  Backlight Driver for Sharp Corgi
+ *
+ *  Copyright (c) 2004-2005 Richard Purdie
+ *
+ *  Based on Sharp's 2.4 Backlight Driver
+ *
+ *  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/spinlock.h>
+#include <linux/fb.h>
+#include <linux/backlight.h>
+
+#include <asm/arch-pxa/corgi.h>
+#include <asm/hardware/scoop.h>
+
+#define CORGI_MAX_INTENSITY 		0x3e
+#define CORGI_DEFAULT_INTENSITY		0x1f
+#define CORGI_LIMIT_MASK			0x0b
+
+static int corgibl_powermode = FB_BLANK_UNBLANK;
+static int current_intensity = 0;
+static int corgibl_limit = 0;
+static spinlock_t bl_lock = SPIN_LOCK_UNLOCKED;
+
+static void corgibl_send_intensity(int intensity)
+{
+	unsigned long flags;
+	void (*corgi_kick_batt)(void);
+
+	if (corgibl_powermode != FB_BLANK_UNBLANK) {
+		intensity = 0;
+	} else {
+		if (corgibl_limit)
+			intensity &= CORGI_LIMIT_MASK;
+	}
+
+	/* Skip 0x20 as it will blank the display */
+	if (intensity >= 0x20)
+		intensity++;
+
+	spin_lock_irqsave(&bl_lock, flags);
+	/* Bits 0-4 are accessed via the SSP interface */
+	corgi_ssp_blduty_set(intensity & 0x1f);
+	/* Bit 5 is via SCOOP */
+	if (intensity & 0x0020)
+		set_scoop_gpio(CORGI_SCP_BACKLIGHT_CONT);
+	else
+		reset_scoop_gpio(CORGI_SCP_BACKLIGHT_CONT);
+	spin_unlock_irqrestore(&bl_lock, flags);
+}
+
+static void corgibl_blank(int blank)
+{
+	switch(blank) {
+
+	case FB_BLANK_NORMAL:
+	case FB_BLANK_VSYNC_SUSPEND:
+	case FB_BLANK_HSYNC_SUSPEND:
+	case FB_BLANK_POWERDOWN:
+		if (corgibl_powermode == FB_BLANK_UNBLANK) {
+			corgibl_send_intensity(0);
+			corgibl_powermode = blank;
+		}
+		break;
+	case FB_BLANK_UNBLANK:
+		if (corgibl_powermode != FB_BLANK_UNBLANK) {
+			corgibl_powermode = blank;
+			corgibl_send_intensity(current_intensity);
+		}
+		break;
+	}
+}
+
+#ifdef CONFIG_PM
+static int corgibl_suspend(struct device *dev, u32 state, u32 level)
+{
+	if (level == SUSPEND_POWER_DOWN)
+		corgibl_blank(FB_BLANK_POWERDOWN);
+	return 0;
+}
+
+static int corgibl_resume(struct device *dev, u32 level)
+{
+	if (level == RESUME_POWER_ON)
+		corgibl_blank(FB_BLANK_UNBLANK);
+	return 0;
+}
+#else
+#define corgibl_suspend	NULL
+#define corgibl_resume	NULL
+#endif
+
+
+static int corgibl_set_power(struct backlight_device *bd, int state)
+{
+	corgibl_blank(state);
+	return 0;
+}
+
+static int corgibl_get_power(struct backlight_device *bd)
+{
+	return corgibl_powermode;
+}
+
+static int corgibl_set_intensity(struct backlight_device *bd, int intensity)
+{
+	if (intensity > CORGI_MAX_INTENSITY)
+		intensity = CORGI_MAX_INTENSITY;
+	corgibl_send_intensity(intensity);
+	current_intensity=intensity;
+	return 0;
+}
+
+static int corgibl_get_intensity(struct backlight_device *bd)
+{
+	return current_intensity;
+}
+
+/*
+ * Called when the battery is low to limit the backlight intensity.
+ * If limit==0 clear any limit, otherwise limit the intensity
+ */
+void corgibl_limit_intensity(int limit)
+{
+	corgibl_limit = (limit ? 1 : 0);
+	corgibl_send_intensity(current_intensity);
+}
+EXPORT_SYMBOL(corgibl_limit_intensity);
+
+
+static struct backlight_properties corgibl_data = {
+	.owner		= THIS_MODULE,
+	.get_power      = corgibl_get_power,
+	.set_power      = corgibl_set_power,
+	.max_brightness = CORGI_MAX_INTENSITY,
+	.get_brightness = corgibl_get_intensity,
+	.set_brightness = corgibl_set_intensity,
+};
+
+static struct backlight_device *corgi_backlight_device;
+
+static int __init corgibl_probe(struct device *dev)
+{
+	corgi_backlight_device = backlight_device_register ("corgi-bl",
+		NULL, &corgibl_data);
+	if (IS_ERR (corgi_backlight_device))
+		return PTR_ERR (corgi_backlight_device);
+
+	corgibl_set_intensity(NULL, CORGI_DEFAULT_INTENSITY);
+
+	printk("Corgi Backlight Driver Initialized.\n");
+	return 0;
+}
+
+static int corgibl_remove(struct device *dev)
+{
+	backlight_device_unregister(corgi_backlight_device);
+
+	corgibl_set_intensity(NULL, 0);
+
+	printk("Corgi Backlight Driver Unloaded\n");
+	return 0;
+}
+
+static struct device_driver corgibl_driver = {
+	.name		= "corgi-bl",
+	.bus		= &platform_bus_type,
+	.probe		= corgibl_probe,
+	.remove		= corgibl_remove,
+	.suspend	= corgibl_suspend,
+	.resume		= corgibl_resume,
+};
+
+static int __init corgibl_init(void)
+{
+	return driver_register(&corgibl_driver);
+}
+
+static void __exit corgibl_exit(void)
+{
+ 	driver_unregister(&corgibl_driver);
+}
+
+module_init(corgibl_init);
+module_exit(corgibl_exit);
+
+MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>");
+MODULE_DESCRIPTION("Corgi Backlight Driver");
+MODULE_LICENSE("GPLv2");
diff -Nru a/drivers/video/backlight/lcd.c b/drivers/video/backlight/lcd.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/video/backlight/lcd.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,263 @@
+/*
+ * LCD Lowlevel Control Abstraction
+ *
+ * Copyright (C) 2003,2004 Hewlett-Packard Company
+ *
+ */
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/lcd.h>
+#include <linux/notifier.h>
+#include <linux/ctype.h>
+#include <linux/err.h>
+#include <linux/fb.h>
+#include <asm/bug.h>
+
+static ssize_t lcd_show_power(struct class_device *cdev, char *buf)
+{
+	int rc;
+	struct lcd_device *ld = to_lcd_device(cdev);
+
+	down(&ld->sem);
+	if (likely(ld->props && ld->props->get_power))
+		rc = sprintf(buf, "%d\n", ld->props->get_power(ld));
+	else
+		rc = -ENXIO;
+	up(&ld->sem);
+
+	return rc;
+}
+
+static ssize_t lcd_store_power(struct class_device *cdev, const char *buf, size_t count)
+{
+	int rc, power;
+	char *endp;
+	struct lcd_device *ld = to_lcd_device(cdev);
+
+	power = simple_strtoul(buf, &endp, 0);
+	if (*endp && !isspace(*endp))
+		return -EINVAL;
+
+	down(&ld->sem);
+	if (likely(ld->props && ld->props->set_power)) {
+		pr_debug("lcd: set power to %d\n", power);
+		ld->props->set_power(ld, power);
+		rc = count;
+	} else
+		rc = -ENXIO;
+	up(&ld->sem);
+
+	return rc;
+}
+
+static ssize_t lcd_show_contrast(struct class_device *cdev, char *buf)
+{
+	int rc;
+	struct lcd_device *ld = to_lcd_device(cdev);
+
+	down(&ld->sem);
+	if (likely(ld->props && ld->props->get_contrast))
+		rc = sprintf(buf, "%d\n", ld->props->get_contrast(ld));
+	else
+		rc = -ENXIO;
+	up(&ld->sem);
+
+	return rc;
+}
+
+static ssize_t lcd_store_contrast(struct class_device *cdev, const char *buf, size_t count)
+{
+	int rc, contrast;
+	char *endp;
+	struct lcd_device *ld = to_lcd_device(cdev);
+
+	contrast = simple_strtoul(buf, &endp, 0);
+	if (*endp && !isspace(*endp))
+		return -EINVAL;
+
+	down(&ld->sem);
+	if (likely(ld->props && ld->props->set_contrast)) {
+		pr_debug("lcd: set contrast to %d\n", contrast);
+		ld->props->set_contrast(ld, contrast);
+		rc = count;
+	} else
+		rc = -ENXIO;
+	up(&ld->sem);
+
+	return rc;
+}
+
+static ssize_t lcd_show_max_contrast(struct class_device *cdev, char *buf)
+{
+	int rc;
+	struct lcd_device *ld = to_lcd_device(cdev);
+
+	down(&ld->sem);
+	if (likely(ld->props))
+		rc = sprintf(buf, "%d\n", ld->props->max_contrast);
+	else
+		rc = -ENXIO;
+	up(&ld->sem);
+
+	return rc;
+}
+
+static void lcd_class_release(struct class_device *dev)
+{
+	struct lcd_device *ld = to_lcd_device(dev);
+	kfree(ld);
+}
+
+struct class lcd_class = {
+	.name = "lcd",
+	.release = lcd_class_release,
+};
+
+#define DECLARE_ATTR(_name,_mode,_show,_store)			\
+{							 	\
+	.attr	= { .name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE },	\
+	.show	= _show,					\
+	.store	= _store,					\
+}
+
+static struct class_device_attribute lcd_class_device_attributes[] = {
+	DECLARE_ATTR(power, 0644, lcd_show_power, lcd_store_power),
+	DECLARE_ATTR(contrast, 0644, lcd_show_contrast, lcd_store_contrast),
+	DECLARE_ATTR(max_contrast, 0444, lcd_show_max_contrast, NULL),
+};
+
+/* This callback gets called when something important happens inside a
+ * framebuffer driver. We're looking if that important event is blanking,
+ * and if it is, we're switching lcd power as well ...
+ */
+static int fb_notifier_callback(struct notifier_block *self,
+				 unsigned long event, void *data)
+{
+	struct lcd_device *ld;
+	struct fb_event *evdata =(struct fb_event *)data;
+
+	/* If we aren't interested in this event, skip it immediately ... */
+	if (event != FB_EVENT_BLANK)
+		return 0;
+
+	ld = container_of(self, struct lcd_device, fb_notif);
+	down(&ld->sem);
+	if (ld->props)
+		if (!ld->props->check_fb || ld->props->check_fb(evdata->info))
+			ld->props->set_power(ld, *(int *)evdata->data);
+	up(&ld->sem);
+	return 0;
+}
+
+/**
+ * lcd_device_register - register a new object of lcd_device class.
+ * @name: the name of the new object(must be the same as the name of the
+ *   respective framebuffer device).
+ * @devdata: an optional pointer to be stored in the class_device. The
+ *   methods may retrieve it by using class_get_devdata(ld->class_dev).
+ * @lp: the lcd properties structure.
+ *
+ * Creates and registers a new lcd class_device. Returns either an ERR_PTR()
+ * or a pointer to the newly allocated device.
+ */
+struct lcd_device *lcd_device_register(const char *name, void *devdata,
+				       struct lcd_properties *lp)
+{
+	int i, rc;
+	struct lcd_device *new_ld;
+
+	pr_debug("lcd_device_register: name=%s\n", name);
+
+	new_ld = kmalloc(sizeof(struct lcd_device), GFP_KERNEL);
+	if (unlikely(!new_ld))
+		return ERR_PTR(ENOMEM);
+
+	init_MUTEX(&new_ld->sem);
+	new_ld->props = lp;
+	memset(&new_ld->class_dev, 0, sizeof(new_ld->class_dev));
+	new_ld->class_dev.class = &lcd_class;
+	strlcpy(new_ld->class_dev.class_id, name, KOBJ_NAME_LEN);
+	class_set_devdata(&new_ld->class_dev, devdata);
+
+	rc = class_device_register(&new_ld->class_dev);
+	if (unlikely(rc)) {
+error:		kfree(new_ld);
+		return ERR_PTR(rc);
+	}
+
+	memset(&new_ld->fb_notif, 0, sizeof(new_ld->fb_notif));
+	new_ld->fb_notif.notifier_call = fb_notifier_callback;
+
+	rc = fb_register_client(&new_ld->fb_notif);
+	if (unlikely(rc))
+		goto error;
+
+	for (i = 0; i < ARRAY_SIZE(lcd_class_device_attributes); i++) {
+		rc = class_device_create_file(&new_ld->class_dev,
+					      &lcd_class_device_attributes[i]);
+		if (unlikely(rc)) {
+			while (--i >= 0)
+				class_device_remove_file(&new_ld->class_dev,
+							 &lcd_class_device_attributes[i]);
+			class_device_unregister(&new_ld->class_dev);
+			/* No need to kfree(new_ld) since release() method was called */
+			return ERR_PTR(rc);
+		}
+	}
+
+	return new_ld;
+}
+EXPORT_SYMBOL(lcd_device_register);
+
+/**
+ * lcd_device_unregister - unregisters a object of lcd_device class.
+ * @ld: the lcd device object to be unregistered and freed.
+ *
+ * Unregisters a previously registered via lcd_device_register object.
+ */
+void lcd_device_unregister(struct lcd_device *ld)
+{
+	int i;
+
+	if (!ld)
+		return;
+
+	pr_debug("lcd_device_unregister: name=%s\n", ld->class_dev.class_id);
+
+	for (i = 0; i < ARRAY_SIZE(lcd_class_device_attributes); i++)
+		class_device_remove_file(&ld->class_dev,
+					 &lcd_class_device_attributes[i]);
+
+	down(&ld->sem);
+	ld->props = NULL;
+	up(&ld->sem);
+
+	fb_unregister_client(&ld->fb_notif);
+
+	class_device_unregister(&ld->class_dev);
+}
+EXPORT_SYMBOL(lcd_device_unregister);
+
+static void __exit lcd_class_exit(void)
+{
+	class_unregister(&lcd_class);
+}
+
+static int __init lcd_class_init(void)
+{
+	return class_register(&lcd_class);
+}
+
+/*
+ * if this is compiled into the kernel, we need to ensure that the
+ * class is registered before users of the class try to register lcd's
+ */
+postcore_initcall(lcd_class_init);
+module_exit(lcd_class_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Jamey Hicks <jamey.hicks@hp.com>, Andrew Zabolotny <zap@homelink.ru>");
+MODULE_DESCRIPTION("LCD Lowlevel Control Abstraction");
diff -Nru a/drivers/video/bt431.h b/drivers/video/bt431.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/video/bt431.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,236 @@
+/*
+ *	linux/drivers/video/bt431.h
+ *
+ *	Copyright 2003  Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+ *
+ *	This file 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/types.h>
+#include <asm/system.h>
+
+/*
+ * Bt431 cursor generator registers, 32-bit aligned.
+ * Two twin Bt431 are used on the DECstation's PMAG-AA.
+ */
+struct bt431_regs {
+	volatile u16 addr_lo;
+	u16 pad0;
+	volatile u16 addr_hi;
+	u16 pad1;
+	volatile u16 addr_cmap;
+	u16 pad2;
+	volatile u16 addr_reg;
+	u16 pad3;
+};
+
+static inline u16 bt431_set_value(u8 val)
+{
+	return ((val << 8) | (val & 0xff)) & 0xffff;
+}
+
+static inline u8 bt431_get_value(u16 val)
+{
+	return val & 0xff;
+}
+
+/*
+ * Additional registers addressed indirectly.
+ */
+#define BT431_REG_CMD		0x0000
+#define BT431_REG_CXLO		0x0001
+#define BT431_REG_CXHI		0x0002
+#define BT431_REG_CYLO		0x0003
+#define BT431_REG_CYHI		0x0004
+#define BT431_REG_WXLO		0x0005
+#define BT431_REG_WXHI		0x0006
+#define BT431_REG_WYLO		0x0007
+#define BT431_REG_WYHI		0x0008
+#define BT431_REG_WWLO		0x0009
+#define BT431_REG_WWHI		0x000a
+#define BT431_REG_WHLO		0x000b
+#define BT431_REG_WHHI		0x000c
+
+#define BT431_REG_CRAM_BASE	0x0000
+#define BT431_REG_CRAM_END	0x01ff
+
+/*
+ * Command register.
+ */
+#define BT431_CMD_CURS_ENABLE	0x40
+#define BT431_CMD_XHAIR_ENABLE	0x20
+#define BT431_CMD_OR_CURSORS	0x10
+#define BT431_CMD_AND_CURSORS	0x00
+#define BT431_CMD_1_1_MUX	0x00
+#define BT431_CMD_4_1_MUX	0x04
+#define BT431_CMD_5_1_MUX	0x08
+#define BT431_CMD_xxx_MUX	0x0c
+#define BT431_CMD_THICK_1	0x00
+#define BT431_CMD_THICK_3	0x01
+#define BT431_CMD_THICK_5	0x02
+#define BT431_CMD_THICK_7	0x03
+
+static inline void bt431_select_reg(struct bt431_regs *regs, int ir)
+{
+	/*
+	 * The compiler splits the write in two bytes without these
+	 * helper variables.
+	 */
+	volatile u16 *lo = &(regs->addr_lo);
+	volatile u16 *hi = &(regs->addr_hi);
+
+	mb();
+	*lo = bt431_set_value(ir & 0xff);
+	wmb();
+	*hi = bt431_set_value((ir >> 8) & 0xff);
+}
+
+/* Autoincrement read/write. */
+static inline u8 bt431_read_reg_inc(struct bt431_regs *regs)
+{
+	/*
+	 * The compiler splits the write in two bytes without the
+	 * helper variable.
+	 */
+	volatile u16 *r = &(regs->addr_reg);
+
+	mb();
+	return bt431_get_value(*r);
+}
+
+static inline void bt431_write_reg_inc(struct bt431_regs *regs, u8 value)
+{
+	/*
+	 * The compiler splits the write in two bytes without the
+	 * helper variable.
+	 */
+	volatile u16 *r = &(regs->addr_reg);
+
+	mb();
+	*r = bt431_set_value(value);
+}
+
+static inline u8 bt431_read_reg(struct bt431_regs *regs, int ir)
+{
+	bt431_select_reg(regs, ir);
+	return bt431_read_reg_inc(regs);
+}
+
+static inline void bt431_write_reg(struct bt431_regs *regs, int ir, u8 value)
+{
+	bt431_select_reg(regs, ir);
+	bt431_write_reg_inc(regs, value);
+}
+
+/* Autoincremented read/write for the cursor map. */
+static inline u16 bt431_read_cmap_inc(struct bt431_regs *regs)
+{
+	/*
+	 * The compiler splits the write in two bytes without the
+	 * helper variable.
+	 */
+	volatile u16 *r = &(regs->addr_cmap);
+
+	mb();
+	return *r;
+}
+
+static inline void bt431_write_cmap_inc(struct bt431_regs *regs, u16 value)
+{
+	/*
+	 * The compiler splits the write in two bytes without the
+	 * helper variable.
+	 */
+	volatile u16 *r = &(regs->addr_cmap);
+
+	mb();
+	*r = value;
+}
+
+static inline u16 bt431_read_cmap(struct bt431_regs *regs, int cr)
+{
+	bt431_select_reg(regs, cr);
+	return bt431_read_cmap_inc(regs);
+}
+
+static inline void bt431_write_cmap(struct bt431_regs *regs, int cr, u16 value)
+{
+	bt431_select_reg(regs, cr);
+	bt431_write_cmap_inc(regs, value);
+}
+
+static inline void bt431_enable_cursor(struct bt431_regs *regs)
+{
+	bt431_write_reg(regs, BT431_REG_CMD,
+			BT431_CMD_CURS_ENABLE | BT431_CMD_OR_CURSORS
+			| BT431_CMD_4_1_MUX | BT431_CMD_THICK_1);
+}
+
+static inline void bt431_erase_cursor(struct bt431_regs *regs)
+{
+	bt431_write_reg(regs, BT431_REG_CMD, BT431_CMD_4_1_MUX);
+}
+
+static inline void bt431_position_cursor(struct bt431_regs *regs, u16 x, u16 y)
+{
+	/*
+	 * Magic from the MACH sources.
+	 *
+	 * Cx = x + D + H - P
+	 *  P = 37 if 1:1, 52 if 4:1, 57 if 5:1
+	 *  D = pixel skew between outdata and external data
+	 *  H = pixels between HSYNCH falling and active video
+	 *
+	 * Cy = y + V - 32
+	 *  V = scanlines between HSYNCH falling, two or more
+	 *      clocks after VSYNCH falling, and active video
+	 */
+	x += 412 - 52;
+	y += 68 - 32;
+
+	/* Use autoincrement. */
+	bt431_select_reg(regs, BT431_REG_CXLO);
+	bt431_write_reg_inc(regs, x & 0xff); /* BT431_REG_CXLO */
+	bt431_write_reg_inc(regs, (x >> 8) & 0x0f); /* BT431_REG_CXHI */
+	bt431_write_reg_inc(regs, y & 0xff); /* BT431_REG_CYLO */
+	bt431_write_reg_inc(regs, (y >> 8) & 0x0f); /* BT431_REG_CYHI */
+}
+
+static inline void bt431_set_font(struct bt431_regs *regs, u8 fgc,
+				  u16 width, u16 height)
+{
+	int i;
+	u16 fgp = fgc ? 0xffff : 0x0000;
+	u16 bgp = fgc ? 0x0000 : 0xffff;
+
+	bt431_select_reg(regs, BT431_REG_CRAM_BASE);
+	for (i = BT431_REG_CRAM_BASE; i <= BT431_REG_CRAM_END; i++) {
+		u16 value;
+
+		if (height << 6 <= i << 3)
+			value = bgp;
+		else if (width <= i % 8 << 3)
+			value = bgp;
+		else if (((width >> 3) & 0xffff) > i % 8)
+			value = fgp;
+		else
+			value = fgp & ~(bgp << (width % 8 << 1));
+
+		bt431_write_cmap_inc(regs, value);
+	}
+}
+
+static inline void bt431_init_cursor(struct bt431_regs *regs)
+{
+	/* no crosshair window */
+	bt431_select_reg(regs, BT431_REG_WXLO);
+	bt431_write_reg_inc(regs, 0x00); /* BT431_REG_WXLO */
+	bt431_write_reg_inc(regs, 0x00); /* BT431_REG_WXHI */
+	bt431_write_reg_inc(regs, 0x00); /* BT431_REG_WYLO */
+	bt431_write_reg_inc(regs, 0x00); /* BT431_REG_WYHI */
+	bt431_write_reg_inc(regs, 0x00); /* BT431_REG_WWLO */
+	bt431_write_reg_inc(regs, 0x00); /* BT431_REG_WWHI */
+	bt431_write_reg_inc(regs, 0x00); /* BT431_REG_WHLO */
+	bt431_write_reg_inc(regs, 0x00); /* BT431_REG_WHHI */
+}
diff -Nru a/drivers/video/bt455.h b/drivers/video/bt455.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/video/bt455.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,95 @@
+/*
+ *	linux/drivers/video/bt455.h
+ *
+ *	Copyright 2003  Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+ *
+ *	This file 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/types.h>
+#include <asm/system.h>
+
+/*
+ * Bt455 byte-wide registers, 32-bit aligned.
+ */
+struct bt455_regs {
+	volatile u8 addr_cmap;
+	u8 pad0[3];
+	volatile u8 addr_cmap_data;
+	u8 pad1[3];
+	volatile u8 addr_clr;
+	u8 pad2[3];
+	volatile u8 addr_ovly;
+	u8 pad3[3];
+};
+
+static inline void bt455_select_reg(struct bt455_regs *regs, int ir)
+{
+	mb();
+	regs->addr_cmap = ir & 0x0f;
+}
+
+/*
+ * Read/write to a Bt455 color map register.
+ */
+static inline void bt455_read_cmap_entry(struct bt455_regs *regs, int cr,
+					 u8* red, u8* green, u8* blue)
+{
+	bt455_select_reg(regs, cr);
+	mb();
+	*red = regs->addr_cmap_data & 0x0f;
+	rmb();
+	*green = regs->addr_cmap_data & 0x0f;
+	rmb();
+	*blue = regs->addr_cmap_data & 0x0f;
+}
+
+static inline void bt455_write_cmap_entry(struct bt455_regs *regs, int cr,
+					  u8 red, u8 green, u8 blue)
+{
+	bt455_select_reg(regs, cr);
+	wmb();
+	regs->addr_cmap_data = red & 0x0f;
+	wmb();
+	regs->addr_cmap_data = green & 0x0f;
+	wmb();
+	regs->addr_cmap_data = blue & 0x0f;
+}
+
+static inline void bt455_write_ovly_entry(struct bt455_regs *regs, int cr,
+					  u8 red, u8 green, u8 blue)
+{
+	bt455_select_reg(regs, cr);
+	wmb();
+	regs->addr_ovly = red & 0x0f;
+	wmb();
+	regs->addr_ovly = green & 0x0f;
+	wmb();
+	regs->addr_ovly = blue & 0x0f;
+}
+
+static inline void bt455_set_cursor(struct bt455_regs *regs)
+{
+	mb();
+	regs->addr_ovly = 0x0f;
+	wmb();
+	regs->addr_ovly = 0x0f;
+	wmb();
+	regs->addr_ovly = 0x0f;
+}
+
+static inline void bt455_erase_cursor(struct bt455_regs *regs)
+{
+	/* bt455_write_cmap_entry(regs, 8, 0x00, 0x00, 0x00); */
+	/* bt455_write_cmap_entry(regs, 9, 0x00, 0x00, 0x00); */
+	bt455_write_ovly_entry(regs, 8, 0x03, 0x03, 0x03);
+	bt455_write_ovly_entry(regs, 9, 0x07, 0x07, 0x07);
+
+	wmb();
+	regs->addr_ovly = 0x09;
+	wmb();
+	regs->addr_ovly = 0x09;
+	wmb();
+	regs->addr_ovly = 0x09;
+}
diff -Nru a/drivers/video/cg14.c b/drivers/video/cg14.c
--- a/drivers/video/cg14.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/video/cg14.c	2005-03-01 23:39:16 -08:00
@@ -469,9 +469,9 @@
 	int is_8mb, linebytes, i;
 
 	if (!sdev) {
-		prom_getproperty(node, "address",
-				 (char *) &bases[0], sizeof(bases));
-		if (!bases[0]) {
+		if (prom_getproperty(node, "address",
+				     (char *) &bases[0], sizeof(bases)) <= 0
+		    || !bases[0]) {
 			printk(KERN_ERR "cg14: Device is not mapped.\n");
 			return;
 		}
diff -Nru a/drivers/video/cg3.c b/drivers/video/cg3.c
--- a/drivers/video/cg3.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/video/cg3.c	2005-03-01 23:39:07 -08:00
@@ -209,7 +209,7 @@
 	case FB_BLANK_HSYNC_SUSPEND: /* VESA blank (hsync off) */
 	case FB_BLANK_POWERDOWN: /* Poweroff */
 		val = sbus_readb(&regs->control);
-		val |= CG3_CR_ENABLE_VIDEO;
+		val &= ~CG3_CR_ENABLE_VIDEO;
 		sbus_writeb(val, &regs->control);
 		par->flags |= CG3_FLAG_BLANKED;
 		break;
@@ -222,8 +222,8 @@
 
 static struct sbus_mmap_map cg3_mmap_map[] = {
 	{
-		.poff	= CG3_MMAP_OFFSET,
-		.voff	= CG3_RAM_OFFSET,
+		.voff	= CG3_MMAP_OFFSET,
+		.poff	= CG3_RAM_OFFSET,
 		.size	= SBUS_MMAP_FBSIZE(1)
 	},
 	{ .size = 0 }
@@ -385,6 +385,9 @@
 	all->par.physbase = sdev->reg_addrs[0].phys_addr;
 
 	sbusfb_fill_var(&all->info.var, sdev->prom_node, 8);
+	all->info.var.red.length = 8;
+	all->info.var.green.length = 8;
+	all->info.var.blue.length = 8;
 	if (!strcmp(sdev->prom_name, "cgRDI"))
 		all->par.flags |= CG3_FLAG_RDI;
 	if (all->par.flags & CG3_FLAG_RDI)
@@ -419,6 +422,7 @@
 		kfree(all);
 		return;
 	}
+	fb_set_cmap(&all->info.cmap, &all->info);
 
 	cg3_init_fix(&all->info, linebytes);
 
diff -Nru a/drivers/video/cg6.c b/drivers/video/cg6.c
--- a/drivers/video/cg6.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/video/cg6.c	2005-03-01 23:38:54 -08:00
@@ -689,6 +689,9 @@
 	all->par.physbase = sdev->reg_addrs[0].phys_addr;
 
 	sbusfb_fill_var(&all->info.var, sdev->prom_node, 8);
+	all->info.var.red.length = 8;
+	all->info.var.green.length = 8;
+	all->info.var.blue.length = 8;
 
 	linebytes = prom_getintdefault(sdev->prom_node, "linebytes",
 				       all->info.var.xres);
@@ -732,6 +735,7 @@
 		return;
 	}
 
+	fb_set_cmap(&all->info.cmap, &all->info);
 	cg6_init_fix(&all->info, linebytes);
 
 	if (register_framebuffer(&all->info) < 0) {
diff -Nru a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
--- a/drivers/video/console/fbcon.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/video/console/fbcon.c	2005-03-01 23:39:07 -08:00
@@ -2000,37 +2000,14 @@
 				int blank)
 {
 	if (blank) {
-		if (info->fix.visual == FB_VISUAL_DIRECTCOLOR ||
-		    info->fix.visual == FB_VISUAL_PSEUDOCOLOR) {
-			struct fb_cmap cmap;
-			u16 *black;
-
-			black = kmalloc(sizeof(u16) * info->cmap.len,
-					GFP_KERNEL);
-			if (black) {
-				memset(black, 0, info->cmap.len * sizeof(u16));
-				cmap.red = cmap.green = cmap.blue = black;
-				cmap.transp = info->cmap.transp ? black : NULL;
-				cmap.start = info->cmap.start;
-				cmap.len = info->cmap.len;
-				fb_set_cmap(&cmap, info);
-			}
-
-			kfree(black);
-		} else {
-			unsigned short charmask = vc->vc_hi_font_mask ?
-				0x1ff : 0xff;
-			unsigned short oldc;
-
-			oldc = vc->vc_video_erase_char;
-			vc->vc_video_erase_char &= charmask;
-			fbcon_clear(vc, 0, 0, vc->vc_rows, vc->vc_cols);
-			vc->vc_video_erase_char = oldc;
-		}
-	} else {
-		if (info->fix.visual == FB_VISUAL_DIRECTCOLOR ||
-		    info->fix.visual == FB_VISUAL_PSEUDOCOLOR)
-			fb_set_cmap(&info->cmap, info);
+		unsigned short charmask = vc->vc_hi_font_mask ?
+			0x1ff : 0xff;
+		unsigned short oldc;
+
+		oldc = vc->vc_video_erase_char;
+		vc->vc_video_erase_char &= charmask;
+		fbcon_clear(vc, 0, 0, vc->vc_rows, vc->vc_cols);
+		vc->vc_video_erase_char = oldc;
 	}
 }
 
@@ -2061,19 +2038,17 @@
 	}
 
  	if (active) {
- 		int ret = -1;
-
- 		fbcon_cursor(vc, blank ? CM_ERASE : CM_DRAW);
- 		ops->cursor_flash = (!blank);
+		if (ops->blank_state != blank) {
+			ops->blank_state = blank;
+			fbcon_cursor(vc, blank ? CM_ERASE : CM_DRAW);
+			ops->cursor_flash = (!blank);
 
- 		if (info->fbops->fb_blank)
- 			ret = info->fbops->fb_blank(blank, info);
-
- 		if (ret)
- 			fbcon_generic_blank(vc, info, blank);
+			if (fb_blank(info, blank))
+				fbcon_generic_blank(vc, info, blank);
+		}
 
  		if (!blank)
-  			update_screen(vc->vc_num);
+ 			update_screen(vc->vc_num);
  	}
 
  	return 0;
@@ -2580,14 +2555,12 @@
 	struct display *p;
 	int rows, cols;
 
-	if (!ops)
+	if (!ops || ops->currcon < 0 || vt_cons[ops->currcon]->vc_mode !=
+	    KD_TEXT || registered_fb[con2fb_map[ops->currcon]] != info)
 		return;
 
 	vc = vc_cons[ops->currcon].d;
 
-	if (ops->currcon < 0 || vt_cons[ops->currcon]->vc_mode !=
-	    KD_TEXT)
-		return;
 	p = &fb_display[vc->vc_num];
 
 	info->var.xoffset = info->var.yoffset = p->yscroll = 0;
@@ -2665,6 +2638,31 @@
 	return ret;
 }
 
+static void fbcon_fb_blanked(struct fb_info *info, int blank)
+{
+	struct fbcon_ops *ops = info->fbcon_par;
+	int valid = 1;
+
+	if (!ops || ops->currcon < 0 ||
+	    vt_cons[ops->currcon]->vc_mode != KD_TEXT ||
+	    registered_fb[con2fb_map[ops->currcon]] != info)
+		valid = 0;
+
+	if (valid) {
+		struct vc_data *vc;
+
+		vc = vc_cons[ops->currcon].d;
+
+		if (CON_IS_VISIBLE(vc)) {
+			if (blank)
+				do_blank_screen(0);
+			else
+				do_unblank_screen(0);
+		}
+		ops->blank_state = blank;
+	}
+}
+
 static int fbcon_event_notify(struct notifier_block *self, 
 			      unsigned long action, void *data)
 {
@@ -2699,6 +2697,9 @@
 	case FB_EVENT_GET_CONSOLE_MAP:
 		con2fb = event->data;
 		con2fb->framebuffer = con2fb_map[con2fb->console - 1];
+		break;
+	case FB_EVENT_BLANK:
+		fbcon_fb_blanked(info, *(int *)event->data);
 		break;
 	}
 
diff -Nru a/drivers/video/console/fbcon.h b/drivers/video/console/fbcon.h
--- a/drivers/video/console/fbcon.h	2005-03-01 23:39:08 -08:00
+++ b/drivers/video/console/fbcon.h	2005-03-01 23:39:08 -08:00
@@ -66,6 +66,7 @@
         int    currcon;	                /* Current VC. */
 	int    cursor_flash;
 	int    cursor_reset;
+	int    blank_state;
 	char  *cursor_data;
 };
     /*
@@ -161,4 +162,7 @@
 			      struct display *p, struct fbcon_ops *ops);
 #endif
 extern void fbcon_set_bitops(struct fbcon_ops *ops);
+
+extern const struct consw fb_con;
+
 #endif /* _VIDEO_FBCON_H */
diff -Nru a/drivers/video/console/mdacon.c b/drivers/video/console/mdacon.c
--- a/drivers/video/console/mdacon.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/video/console/mdacon.c	2005-03-01 23:38:58 -08:00
@@ -47,7 +47,7 @@
 #include <asm/io.h>
 #include <asm/vga.h>
 
-static spinlock_t mda_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(mda_lock);
 
 /* description of the hardware layout */
 
@@ -64,7 +64,6 @@
 
 /* current hardware state */
 
-static int	mda_origin_loc=-1;
 static int	mda_cursor_loc=-1;
 static int	mda_cursor_size_from=-1;
 static int	mda_cursor_size_to=-1;
@@ -79,8 +78,8 @@
 
 static struct vc_data	*mda_display_fg = NULL;
 
-MODULE_PARM(mda_first_vc, "1-255i");
-MODULE_PARM(mda_last_vc,  "1-255i");
+module_param(mda_first_vc, int, 0);
+module_param(mda_last_vc, int, 0);
 
 /* MDA register values
  */
@@ -147,16 +146,6 @@
 	return val;
 }
 #endif
-
-static inline void mda_set_origin(unsigned int location)
-{
-	if (mda_origin_loc == location)
-		return;
-
-	write_mda_w(location >> 1, 0x0c);
-
-	mda_origin_loc = location;
-}
 
 static inline void mda_set_cursor(unsigned int location) 
 {
diff -Nru a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c
--- a/drivers/video/console/newport_con.c	2005-03-01 23:39:19 -08:00
+++ b/drivers/video/console/newport_con.c	2005-03-01 23:39:19 -08:00
@@ -21,6 +21,7 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 
+#include <asm/io.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
 #include <asm/page.h>
@@ -73,7 +74,7 @@
 static inline void newport_render_background(int xstart, int ystart,
 					     int xend, int yend, int ci)
 {
-	newport_wait();
+	newport_wait(npregs);
 	npregs->set.wrmask = 0xffffffff;
 	npregs->set.drawmode0 = (NPORT_DMODE0_DRAW | NPORT_DMODE0_BLOCK |
 				 NPORT_DMODE0_DOSETUP | NPORT_DMODE0_STOPX
@@ -90,7 +91,7 @@
 	unsigned short i;
 
 	for (i = 0; i < 16; i++) {
-		newport_bfwait();
+		newport_bfwait(npregs);
 		newport_cmap_setaddr(npregs, color_table[i]);
 		newport_cmap_setrgb(npregs,
 				    default_red[i],
@@ -107,19 +108,19 @@
 	unsigned long i;
 
 	for (i = 0; i < logo->clutsize; i++) {
-		newport_bfwait();
+		newport_bfwait(npregs);
 		newport_cmap_setaddr(npregs, i + 0x20);
 		newport_cmap_setrgb(npregs, clut[0], clut[1], clut[2]);
 		clut += 3;
 	}
 
-	newport_wait();
+	newport_wait(npregs);
 	npregs->set.drawmode0 = (NPORT_DMODE0_DRAW | NPORT_DMODE0_BLOCK |
 				 NPORT_DMODE0_CHOST);
 
 	npregs->set.xystarti = ((newport_xsize - logo->width) << 16) | (0);
 	npregs->set.xyendi = ((newport_xsize - 1) << 16);
-	newport_wait();
+	newport_wait(npregs);
 
 	for (i = 0; i < logo->width*logo->height; i++)
 		npregs->go.hostrw0 = *data++ << 24;
@@ -132,7 +133,7 @@
 	if (logo_active)
 		return;
 
-	newport_wait();
+	newport_wait(npregs);
 	npregs->set.wrmask = 0xffffffff;
 	npregs->set.drawmode0 = (NPORT_DMODE0_DRAW | NPORT_DMODE0_BLOCK |
 				 NPORT_DMODE0_DOSETUP | NPORT_DMODE0_STOPX
@@ -154,7 +155,7 @@
 	unsigned short treg;
 	int i;
 
-	newport_wait();
+	newport_wait(npregs);
 	treg = newport_vc2_get(npregs, VC2_IREG_CONTROL);
 	newport_vc2_set(npregs, VC2_IREG_CONTROL,
 			(treg | VC2_CTRL_EVIDEO));
@@ -164,7 +165,7 @@
 	npregs->set.dcbmode = (NPORT_DMODE_AVC2 | VC2_REGADDR_RAM |
 			       NPORT_DMODE_W2 | VC2_PROTOCOL);
 	for (i = 0; i < 128; i++) {
-		newport_bfwait();
+		newport_bfwait(npregs);
 		if (i == 92 || i == 94)
 			npregs->set.dcbdata0.byshort.s1 = 0xff00;
 		else
@@ -204,7 +205,7 @@
 	npregs->set.dcbmode = (NPORT_DMODE_AVC2 | VC2_REGADDR_RAM |
 			       NPORT_DMODE_W2 | VC2_PROTOCOL);
 	for (i = 0; i < 128; i++) {
-		newport_bfwait();
+		newport_bfwait(npregs);
 		linetable[i] = npregs->set.dcbdata0.byshort.s1;
 	}
 
@@ -215,12 +216,12 @@
 		npregs->set.dcbmode = (NPORT_DMODE_AVC2 | VC2_REGADDR_RAM |
 				       NPORT_DMODE_W2 | VC2_PROTOCOL);
 		do {
-			newport_bfwait();
+			newport_bfwait(npregs);
 			treg = npregs->set.dcbdata0.byshort.s1;
 			if ((treg & 1) == 0)
 				cols += (treg >> 7) & 0xfe;
 			if ((treg & 0x80) == 0) {
-				newport_bfwait();
+				newport_bfwait(npregs);
 				treg = npregs->set.dcbdata0.byshort.s1;
 			}
 		} while ((treg & 0x8000) == 0);
@@ -290,16 +291,16 @@
 
 	if (!sgi_gfxaddr)
 		return NULL;
-	npregs = (struct newport_regs *) (KSEG1 + sgi_gfxaddr);
+	npregs = (struct newport_regs *)	/* ioremap cannot fail */
+		 ioremap(sgi_gfxaddr, sizeof(struct newport_regs));
 	npregs->cset.config = NPORT_CFG_GD0;
 
-	if (newport_wait()) {
-		return NULL;
-	}
+	if (newport_wait(npregs))
+		goto out_unmap;
 
 	npregs->set.xstarti = TESTVAL;
 	if (npregs->set._xstart.word != XSTI_TO_FXSTART(TESTVAL))
-		return NULL;
+		goto out_unmap;
 
 	for (i = 0; i < MAX_NR_CONSOLES; i++)
 		font_data[i] = FONT_DATA;
@@ -309,6 +310,10 @@
 	newport_get_screensize();
 
 	return "SGI Newport";
+
+out_unmap:
+	iounmap((void *)npregs);
+	return NULL;
 }
 
 static void newport_init(struct vc_data *vc, int init)
@@ -362,7 +367,7 @@
 				  (charattr & 0xf0) >> 4);
 
 	/* Set the color and drawing mode. */
-	newport_wait();
+	newport_wait(npregs);
 	npregs->set.colori = charattr & 0xf;
 	npregs->set.drawmode0 = (NPORT_DMODE0_DRAW | NPORT_DMODE0_BLOCK |
 				 NPORT_DMODE0_STOPX | NPORT_DMODE0_ZPENAB |
@@ -371,7 +376,7 @@
 	/* Set coordinates for bitmap operation. */
 	npregs->set.xystarti = (xpos << 16) | ((ypos + topscan) & 0x3ff);
 	npregs->set.xyendi = ((xpos + 7) << 16);
-	newport_wait();
+	newport_wait(npregs);
 
 	/* Go, baby, go... */
 	RENDER(npregs, p);
@@ -395,7 +400,7 @@
 					  xpos + ((count - 1) << 3), ypos,
 					  (charattr & 0xf0) >> 4);
 
-	newport_wait();
+	newport_wait(npregs);
 
 	/* Set the color and drawing mode. */
 	npregs->set.colori = charattr & 0xf;
@@ -406,7 +411,7 @@
 	for (i = 0; i < count; i++, xpos += 8) {
 		p = &font_data[vc->vc_num][(scr_readw(s++) & 0xff) << 4];
 
-		newport_wait();
+		newport_wait(npregs);
 
 		/* Set coordinates for bitmap operation. */
 		npregs->set.xystarti =
@@ -459,7 +464,7 @@
 	return 1;
 }
 
-static int newport_blank(struct vc_data *c, int blank)
+static int newport_blank(struct vc_data *c, int blank, int mode_switch)
 {
 	unsigned short treg;
 
@@ -684,7 +689,7 @@
 		xe = xs;
 		xs = tmp;
 	}
-	newport_wait();
+	newport_wait(npregs);
 	npregs->set.drawmode0 = (NPORT_DMODE0_S2S | NPORT_DMODE0_BLOCK |
 				 NPORT_DMODE0_DOSETUP | NPORT_DMODE0_STOPX
 				 | NPORT_DMODE0_STOPY);
@@ -701,24 +706,24 @@
 #define DUMMY (void *) newport_dummy
 
 const struct consw newport_con = {
-    .owner =		THIS_MODULE,
-    .con_startup =	newport_startup,
-    .con_init =		newport_init,
-    .con_deinit =	newport_deinit,
-    .con_clear =	newport_clear,
-    .con_putc =		newport_putc,
-    .con_putcs =	newport_putcs,
-    .con_cursor =	newport_cursor,
-    .con_scroll =	newport_scroll,
-    .con_bmove =	newport_bmove,
-    .con_switch =	newport_switch,
-    .con_blank =	newport_blank,
-    .con_font_set =	newport_font_set,
-    .con_font_default =	newport_font_default,
-    .con_set_palette =	newport_set_palette,
-    .con_scrolldelta =	newport_scrolldelta,
-    .con_set_origin =	DUMMY,
-    .con_save_screen =	DUMMY
+	.owner		  = THIS_MODULE,
+	.con_startup	  = newport_startup,
+	.con_init	  = newport_init,
+	.con_deinit	  = newport_deinit,
+	.con_clear	  = newport_clear,
+	.con_putc	  = newport_putc,
+	.con_putcs	  = newport_putcs,
+	.con_cursor	  = newport_cursor,
+	.con_scroll	  = newport_scroll,
+	.con_bmove 	  = newport_bmove,
+	.con_switch	  = newport_switch,
+	.con_blank	  = newport_blank,
+	.con_font_set	  = newport_font_set,
+	.con_font_default = newport_font_default,
+	.con_set_palette  = newport_set_palette,
+	.con_scrolldelta  = newport_scrolldelta,
+	.con_set_origin	  = DUMMY,
+	.con_save_screen  = DUMMY
 };
 
 #ifdef MODULE
@@ -730,6 +735,7 @@
 static void __exit newport_console_exit(void)
 {
 	give_up_console(&newport_con);
+	iounmap((void *)npregs);
 }
 
 module_init(newport_console_init);
diff -Nru a/drivers/video/console/sticore.c b/drivers/video/console/sticore.c
--- a/drivers/video/console/sticore.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/video/console/sticore.c	2005-03-01 23:38:54 -08:00
@@ -817,7 +817,7 @@
 	}
 		    
 	memset(sti, 0, sizeof(*sti));
-	sti->lock = SPIN_LOCK_UNLOCKED;
+	spin_lock_init(&sti->lock);
 
 test_rom:
 	/* if we can't read the ROM, bail out early.  Not being able
diff -Nru a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
--- a/drivers/video/console/vgacon.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/video/console/vgacon.c	2005-03-01 23:38:56 -08:00
@@ -49,10 +49,13 @@
 #include <linux/spinlock.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
+#include <linux/smp_lock.h>
 #include <video/vga.h>
 #include <asm/io.h>
 
-static spinlock_t vga_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(vga_lock);
+static int cursor_size_lastfrom;
+static int cursor_size_lastto;
 static struct vgastate state;
 
 #define BLANK 0x0020
@@ -408,17 +411,16 @@
 {
 	unsigned long flags;
 	int curs, cure;
-	static int lastfrom, lastto;
 
 #ifdef TRIDENT_GLITCH
 	if (xpos < 16)
 		from--, to--;
 #endif
 
-	if ((from == lastfrom) && (to == lastto))
+	if ((from == cursor_size_lastfrom) && (to == cursor_size_lastto))
 		return;
-	lastfrom = from;
-	lastto = to;
+	cursor_size_lastfrom = from;
+	cursor_size_lastto = to;
 
 	spin_lock_irqsave(&vga_lock, flags);
 	outb_p(0x0a, vga_video_port_reg);	/* Cursor start */
@@ -763,6 +765,7 @@
 		charmap += 4 * cmapsz;
 #endif
 
+	unlock_kernel();
 	spin_lock_irq(&vga_lock);
 	/* First, the Sequencer */
 	vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x1);
@@ -848,6 +851,7 @@
 		vga_wattr(state->vgabase, VGA_AR_ENABLE_DISPLAY, 0);	
 	}
 	spin_unlock_irq(&vga_lock);
+	lock_kernel();
 	return 0;
 }
 
@@ -859,11 +863,6 @@
 	unsigned char ovr, vde, fsr;
 	int rows, maxscan, i;
 
-	if (fontheight == vc->vc_font.height)
-		return 0;
-
-	vc->vc_font.height = fontheight;
-
 	rows = vc->vc_scan_lines / fontheight;	/* Number of video rows we end up with */
 	maxscan = rows * fontheight - 1;	/* Scan lines to actually display-1 */
 
@@ -902,6 +901,12 @@
 		struct vc_data *c = vc_cons[i].d;
 
 		if (c && c->vc_sw == &vga_con) {
+			if (CON_IS_VISIBLE(c)) {
+			        /* void size to cause regs to be rewritten */
+				cursor_size_lastfrom = 0;
+				cursor_size_lastto = 0;
+				c->vc_sw->con_cursor(c, CM_DRAW);
+			}
 			c->vc_font.height = fontheight;
 			vc_resize(c->vc_num, 0, rows);	/* Adjust console size */
 		}
diff -Nru a/drivers/video/cyber2000fb.c b/drivers/video/cyber2000fb.c
--- a/drivers/video/cyber2000fb.c	2005-03-01 23:38:53 -08:00
+++ b/drivers/video/cyber2000fb.c	2005-03-01 23:38:53 -08:00
@@ -94,7 +94,7 @@
 
 static char default_font_storage[40];
 static char *default_font = "Acorn8x8";
-MODULE_PARM(default_font, "s");
+module_param(default_font, charp, 0);
 MODULE_PARM_DESC(default_font, "Default font name");
 
 /*
diff -Nru a/drivers/video/fbmem.c b/drivers/video/fbmem.c
--- a/drivers/video/fbmem.c	2005-03-01 23:38:43 -08:00
+++ b/drivers/video/fbmem.c	2005-03-01 23:38:43 -08:00
@@ -35,6 +35,7 @@
 #include <linux/err.h>
 #include <linux/kernel.h>
 #include <linux/device.h>
+#include <linux/efi.h>
 
 #if defined(__mc68000__) || defined(CONFIG_APUS)
 #include <asm/setup.h>
@@ -715,8 +716,9 @@
 
 		if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
 			struct fb_videomode mode;
-			info->var = *var;
+			int err = 0;
 
+			info->var = *var;
 			if (info->fbops->fb_set_par)
 				info->fbops->fb_set_par(info);
 
@@ -728,15 +730,16 @@
 
 			if (info->modelist.prev && info->modelist.next &&
 			    !list_empty(&info->modelist))
-				fb_add_videomode(&mode, &info->modelist);
+				err = fb_add_videomode(&mode, &info->modelist);
 
-			if (info->flags & FBINFO_MISC_MODECHANGEUSER) {
+			if (!err && info->flags & FBINFO_MISC_USEREVENT) {
 				struct fb_event event;
 
-				info->flags &= ~FBINFO_MISC_MODECHANGEUSER;
+				info->flags &= ~FBINFO_MISC_USEREVENT;
 				event.info = info;
 				notifier_call_chain(&fb_notifier_list,
-						    FB_EVENT_MODE_CHANGE, &event);
+						    FB_EVENT_MODE_CHANGE,
+						    &event);
 			}
 		}
 	}
@@ -746,15 +749,23 @@
 int
 fb_blank(struct fb_info *info, int blank)
 {	
-	int err = -EINVAL;
-	
+ 	int ret = -EINVAL;
+
  	if (blank > FB_BLANK_POWERDOWN)
  		blank = FB_BLANK_POWERDOWN;
 
 	if (info->fbops->fb_blank)
- 		err = info->fbops->fb_blank(blank, info);
+ 		ret = info->fbops->fb_blank(blank, info);
+
+ 	if (!ret) {
+		struct fb_event event;
+
+		event.info = info;
+		event.data = &blank;
+		notifier_call_chain(&fb_notifier_list, FB_EVENT_BLANK, &event);
+	}
 
-	return err;
+ 	return ret;
 }
 
 static int 
@@ -782,9 +793,9 @@
 		if (copy_from_user(&var, argp, sizeof(var)))
 			return -EFAULT;
 		acquire_console_sem();
-		info->flags |= FBINFO_MISC_MODECHANGEUSER;
+		info->flags |= FBINFO_MISC_USEREVENT;
 		i = fb_set_var(info, &var);
-		info->flags &= ~FBINFO_MISC_MODECHANGEUSER;
+		info->flags &= ~FBINFO_MISC_USEREVENT;
 		release_console_sem();
 		if (i) return i;
 		if (copy_to_user(argp, &var, sizeof(var)))
@@ -846,7 +857,9 @@
 					   &event);
 	case FBIOBLANK:
 		acquire_console_sem();
+		info->flags |= FBINFO_MISC_USEREVENT;
 		i = fb_blank(info, arg);
+		info->flags &= ~FBINFO_MISC_USEREVENT;
 		release_console_sem();
 		return i;
 	default:
@@ -856,6 +869,23 @@
 	}
 }
 
+#ifdef CONFIG_COMPAT
+static long
+fb_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	int fbidx = iminor(file->f_dentry->d_inode);
+	struct fb_info *info = registered_fb[fbidx];
+	struct fb_ops *fb = info->fbops;
+	int ret;
+	if (fb->fb_compat_ioctl == NULL)
+		return -ENOIOCTLCMD;
+	lock_kernel();
+	ret = fb->fb_compat_ioctl(file, cmd, arg, info);
+	unlock_kernel();
+	return ret;
+}
+#endif
+
 static int 
 fb_mmap(struct file *file, struct vm_area_struct * vma)
 {
@@ -938,8 +968,13 @@
 	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
 #elif defined(__hppa__)
 	pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE;
-#elif defined(__ia64__) || defined(__arm__) || defined(__sh__)
+#elif defined(__arm__) || defined(__sh__) || defined(__m32r__)
 	vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
+#elif defined(__ia64__)
+	if (efi_range_is_wc(vma->vm_start, vma->vm_end - vma->vm_start))
+		vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
+	else
+		vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
 #else
 #warning What do we have to do here??
 #endif
@@ -996,6 +1031,9 @@
 	.read =		fb_read,
 	.write =	fb_write,
 	.ioctl =	fb_ioctl,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl = fb_compat_ioctl,
+#endif
 	.mmap =		fb_mmap,
 	.open =		fb_open,
 	.release =	fb_release,
@@ -1166,7 +1204,7 @@
 	}
 	return 0;
 }
-module_init(fbmem_init);
+subsys_initcall(fbmem_init);
 
 static char *video_options[FB_MAX];
 static int ofonly;
@@ -1224,19 +1262,32 @@
  *
  */
 
+extern const char *global_mode_option;
+
 int __init video_setup(char *options)
 {
-	int i;
+	int i, global = 0;
 
 	if (!options || !*options)
-		return 0;
+ 		global = 1;
+
+ 	if (!global && !strncmp(options, "ofonly", 6)) {
+ 		ofonly = 1;
+ 		global = 1;
+ 	}
+
+ 	if (!global && !strstr(options, "fb:")) {
+ 		global_mode_option = options;
+ 		global = 1;
+ 	}
+
+ 	if (!global) {
+ 		for (i = 0; i < FB_MAX; i++) {
+ 			if (video_options[i] == NULL) {
+ 				video_options[i] = options;
+ 				break;
+ 			}
 
-	for (i = 0; i < FB_MAX; i++) {
-		if (!strncmp(options, "ofonly", 6))
-			ofonly = 1;
-		if (video_options[i] == NULL) {
-			video_options[i] = options;
-			break;
 		}
 	}
 
diff -Nru a/drivers/video/fbmon.c b/drivers/video/fbmon.c
--- a/drivers/video/fbmon.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/video/fbmon.c	2005-03-01 23:39:09 -08:00
@@ -50,6 +50,7 @@
 #endif
 
 #define FBMON_FIX_HEADER 1
+#define FBMON_FIX_INPUT  2
 
 #ifdef CONFIG_FB_MODE_HELPERS
 struct broken_edid {
@@ -60,9 +61,16 @@
 
 static struct broken_edid brokendb[] = {
 	/* DEC FR-PCXAV-YZ */
-	{ .manufacturer = "DEC",
-	  .model        = 0x073a,
-	  .fix          = FBMON_FIX_HEADER,
+	{
+		.manufacturer = "DEC",
+		.model        = 0x073a,
+		.fix          = FBMON_FIX_HEADER,
+	},
+	/* ViewSonic PF775a */
+	{
+		.manufacturer = "VSC",
+		.model        = 0x5a44,
+		.fix          = FBMON_FIX_INPUT,
 	},
 };
 
@@ -81,10 +89,12 @@
   while (i-- && (*--s == 0x20)) *s = 0;
 }
 
-static void fix_broken_edid(unsigned char *edid)
+static int check_edid(unsigned char *edid)
 {
 	unsigned char *block = edid + ID_MANUFACTURER_NAME, manufacturer[4];
-	u32 model, i;
+	unsigned char *b;
+	u32 model;
+	int i, fix = 0, ret = 0;
 
 	manufacturer[0] = ((block[0] & 0x7c) >> 2) + '@';
 	manufacturer[1] = ((block[0] & 0x03) << 3) +
@@ -96,23 +106,57 @@
 	for (i = 0; i < ARRAY_SIZE(brokendb); i++) {
 		if (!strncmp(manufacturer, brokendb[i].manufacturer, 4) &&
 			brokendb[i].model == model) {
-			switch (brokendb[i].fix) {
-			case FBMON_FIX_HEADER:
-				printk("fbmon: The EDID header of "
-				       "Manufacturer: %s Model: 0x%x is "
-				       "known to be broken,\n"
-				       "fbmon: trying a header "
-				       "reconstruct\n", manufacturer, model);
-				memcpy(edid, edid_v1_header, 8);
-				break;
-			}
+			printk("fbmon: The EDID Block of "
+			       "Manufacturer: %s Model: 0x%x is known to "
+			       "be broken,\n",  manufacturer, model);
+ 			fix = brokendb[i].fix;
+ 			break;
+		}
+	}
+
+	switch (fix) {
+	case FBMON_FIX_HEADER:
+		for (i = 0; i < 8; i++) {
+			if (edid[i] != edid_v1_header[i])
+				ret = fix;
 		}
+		break;
+	case FBMON_FIX_INPUT:
+		b = edid + EDID_STRUCT_DISPLAY;
+		/* Only if display is GTF capable will
+		   the input type be reset to analog */
+		if (b[4] & 0x01 && b[0] & 0x80)
+			ret = fix;
+		break;
+	}
+
+	return ret;
+}
+
+static void fix_edid(unsigned char *edid, int fix)
+{
+	unsigned char *b;
+
+	switch (fix) {
+	case FBMON_FIX_HEADER:
+		printk("fbmon: trying a header reconstruct\n");
+		memcpy(edid, edid_v1_header, 8);
+		break;
+	case FBMON_FIX_INPUT:
+		printk("fbmon: trying to fix input type\n");
+		b = edid + EDID_STRUCT_DISPLAY;
+		b[0] &= ~0x80;
+		edid[127] += 0x80;
 	}
 }
 
 static int edid_checksum(unsigned char *edid)
 {
 	unsigned char i, csum = 0, all_null = 0;
+	int err = 0, fix = check_edid(edid);
+
+	if (fix)
+		fix_edid(edid, fix);
 
 	for (i = 0; i < EDID_LENGTH; i++) {
 		csum += edid[i];
@@ -121,39 +165,25 @@
 
 	if (csum == 0x00 && all_null) {
 		/* checksum passed, everything's good */
-		return 1;
+		err = 1;
 	}
 
-	fix_broken_edid(edid);
-	csum = all_null = 0;
-	for (i = 0; i < EDID_LENGTH; i++) {
-		csum += edid[i];
-		all_null |= edid[i];
-	}
-	if (csum != 0x00 || !all_null) {
-		printk("EDID checksum failed, aborting\n");
-		return 0;
-	}
-	return 1;
+	return err;
 }
 
 static int edid_check_header(unsigned char *edid)
 {
-	int i, fix = 0;
+	int i, err = 1, fix = check_edid(edid);
 
-	for (i = 0; i < 8; i++) {
-		if (edid[i] != edid_v1_header[i])
-			fix = 1;
-	}
-	if (!fix)
-		return 1;
+	if (fix)
+		fix_edid(edid, fix);
 
-	fix_broken_edid(edid);
 	for (i = 0; i < 8; i++) {
 		if (edid[i] != edid_v1_header[i])
-			return 0;
+			err = 0;
 	}
-	return 1;
+
+	return err;
 }
 
 static void parse_vendor_block(unsigned char *block, struct fb_monspecs *specs)
@@ -632,7 +662,7 @@
 
 	fb_get_monitor_limits(edid, specs);
 
-	c = (block[0] & 0x80) >> 7;
+	c = block[0] & 0x80;
 	specs->input = 0;
 	if (c) {
 		specs->input |= FB_DISP_DDI;
@@ -656,13 +686,10 @@
 			DPRINTK("0.700V/0.000V");
 			specs->input |= FB_DISP_ANA_700_000;
 			break;
-		default:
-			DPRINTK("unknown");
-			specs->input |= FB_DISP_UNKNOWN;
 		}
 	}
 	DPRINTK("\n      Sync: ");
-	c = (block[0] & 0x10) >> 4;
+	c = block[0] & 0x10;
 	if (c)
 		DPRINTK("      Configurable signal level\n");
 	c = block[0] & 0x0f;
diff -Nru a/drivers/video/g364fb.c b/drivers/video/g364fb.c
--- a/drivers/video/g364fb.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/video/g364fb.c	2005-03-01 23:38:52 -08:00
@@ -15,6 +15,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/console.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
diff -Nru a/drivers/video/gbefb.c b/drivers/video/gbefb.c
--- a/drivers/video/gbefb.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/video/gbefb.c	2005-03-01 23:38:55 -08:00
@@ -85,7 +85,6 @@
 
 static int gbe_revision;
 
-static struct fb_info fb_info;
 static int ypan, ywrap;
 
 static uint32_t pseudo_palette[256];
@@ -190,8 +189,6 @@
 
 static int flat_panel_enabled = 0;
 
-static struct gbefb_par par_current;
-
 static void gbe_reset(void)
 {
 	/* Turn on dotclock PLL */
@@ -1045,6 +1042,36 @@
 };
 
 /*
+ * sysfs
+ */
+
+static ssize_t gbefb_show_memsize(struct device *dev, 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)
+{
+	return snprintf(buf, PAGE_SIZE, "%d\n", gbe_revision);
+}
+
+static DEVICE_ATTR(revision, S_IRUGO, gbefb_show_rev, NULL);
+
+static void __devexit gbefb_remove_sysfs(struct device *dev)
+{
+	device_remove_file(dev, &dev_attr_size);
+	device_remove_file(dev, &dev_attr_revision);
+}
+
+static void gbefb_create_sysfs(struct device *dev)
+{
+	device_create_file(dev, &dev_attr_size);
+	device_create_file(dev, &dev_attr_revision);
+}
+
+/*
  * Initialization
  */
 
@@ -1079,13 +1106,21 @@
 	return 0;
 }
 
-int __init gbefb_init(void)
+static int __init gbefb_probe(struct device *dev)
 {
 	int i, ret = 0;
-
+	struct fb_info *info;
+	struct gbefb_par *par;
+	struct platform_device *p_dev = to_platform_device(dev);
 #ifndef MODULE
 	char *options = NULL;
+#endif
 
+	info = framebuffer_alloc(sizeof(struct gbefb_par), &p_dev->dev);
+	if (!info)
+		return -ENOMEM;
+
+#ifndef MODULE
 	if (fb_get_options("gbefb", &options))
 		return -ENODEV;
 	gbefb_setup(options);
@@ -1093,7 +1128,8 @@
 
 	if (!request_mem_region(GBE_BASE, sizeof(struct sgi_gbe), "GBE")) {
 		printk(KERN_ERR "gbefb: couldn't reserve mmio region\n");
-		return -EBUSY;
+		ret = -EBUSY;
+		goto out_release_framebuffer;
 	}
 
 	gbe = (struct sgi_gbe *) ioremap(GBE_BASE, sizeof(struct sgi_gbe));
@@ -1113,7 +1149,6 @@
 		goto out_unmap;
 	}
 
-
 	if (gbe_mem_phys) {
 		/* memory was allocated at boot time */
 		gbe_mem = ioremap_nocache(gbe_mem_phys, gbe_mem_size);
@@ -1140,32 +1175,35 @@
 	for (i = 0; i < (gbe_mem_size >> TILE_SHIFT); i++)
 		gbe_tiles.cpu[i] = (gbe_mem_phys >> TILE_SHIFT) + i;
 
-	fb_info.fbops = &gbefb_ops;
-	fb_info.pseudo_palette = pseudo_palette;
-	fb_info.flags = FBINFO_DEFAULT;
-	fb_info.screen_base = gbe_mem;
-	fb_alloc_cmap(&fb_info.cmap, 256, 0);
+	info->fbops = &gbefb_ops;
+	info->pseudo_palette = pseudo_palette;
+	info->flags = FBINFO_DEFAULT;
+	info->screen_base = gbe_mem;
+	fb_alloc_cmap(&info->cmap, 256, 0);
 
 	/* reset GBE */
 	gbe_reset();
 
+	par = info->par;
 	/* turn on default video mode */
-	if (fb_find_mode(&par_current.var, &fb_info, mode_option, NULL, 0,
+	if (fb_find_mode(&par->var, info, mode_option, NULL, 0,
 			 default_mode, 8) == 0)
-		par_current.var = *default_var;
-	fb_info.var = par_current.var;
-	gbefb_check_var(&par_current.var, &fb_info);
-	gbefb_encode_fix(&fb_info.fix, &fb_info.var);
-	fb_info.par = &par_current;
+		par->var = *default_var;
+	info->var = par->var;
+	gbefb_check_var(&par->var, info);
+	gbefb_encode_fix(&info->fix, &info->var);
 
-	if (register_framebuffer(&fb_info) < 0) {
-		ret = -ENXIO;
+	if (register_framebuffer(info) < 0) {
 		printk(KERN_ERR "gbefb: couldn't register framebuffer\n");
+		ret = -ENXIO;
 		goto out_gbe_unmap;
 	}
 
+	dev_set_drvdata(&p_dev->dev, info);
+	gbefb_create_sysfs(dev);
+
 	printk(KERN_INFO "fb%d: %s rev %d @ 0x%08x using %dkB memory\n",
-	       fb_info.node, fb_info.fix.id, gbe_revision, (unsigned) GBE_BASE,
+	       info->node, info->fix.id, gbe_revision, (unsigned) GBE_BASE,
 	       gbe_mem_size >> 10);
 
 	return 0;
@@ -1182,12 +1220,18 @@
 	iounmap(gbe);
 out_release_mem_region:
 	release_mem_region(GBE_BASE, sizeof(struct sgi_gbe));
+out_release_framebuffer:
+	framebuffer_release(info);
+
 	return ret;
 }
 
-void __exit gbefb_exit(void)
+static int __devexit gbefb_remove(struct device* dev)
 {
-	unregister_framebuffer(&fb_info);
+	struct platform_device *p_dev = to_platform_device(dev);
+	struct fb_info *info = dev_get_drvdata(&p_dev->dev);
+
+	unregister_framebuffer(info);
 	gbe_turn_off();
 	if (gbe_dma_addr)
 		dma_free_coherent(NULL, gbe_mem_size, gbe_mem, gbe_mem_phys);
@@ -1197,12 +1241,40 @@
 			  (void *)gbe_tiles.cpu, gbe_tiles.dma);
 	release_mem_region(GBE_BASE, sizeof(struct sgi_gbe));
 	iounmap(gbe);
+	gbefb_remove_sysfs(dev);
+	framebuffer_release(info);
+
+	return 0;
 }
 
-module_init(gbefb_init);
+static struct device_driver gbefb_driver = {
+	.name = "gbefb",
+	.bus = &platform_bus_type,
+	.probe = gbefb_probe,
+	.remove = __devexit_p(gbefb_remove),
+};
+
+static struct platform_device gbefb_device = {
+	.name = "gbefb",
+};
 
-#ifdef MODULE
+int __init gbefb_init(void)
+{
+	int ret = driver_register(&gbefb_driver);
+	if (!ret) {
+		ret = platform_device_register(&gbefb_device);
+		if (ret)
+			driver_unregister(&gbefb_driver);
+	}
+	return ret;
+}
+
+void __exit gbefb_exit(void)
+{
+	 driver_unregister(&gbefb_driver);
+}
+
+module_init(gbefb_init);
 module_exit(gbefb_exit);
-#endif
 
 MODULE_LICENSE("GPL");
diff -Nru a/drivers/video/hgafb.c b/drivers/video/hgafb.c
--- a/drivers/video/hgafb.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/video/hgafb.c	2005-03-01 23:39:09 -08:00
@@ -103,7 +103,7 @@
 
 /* Global locks */
 
-static spinlock_t hga_reg_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(hga_reg_lock);
 
 /* Framebuffer driver structures */
 
@@ -618,7 +618,7 @@
 MODULE_DESCRIPTION("FBDev driver for Hercules Graphics Adaptor");
 MODULE_LICENSE("GPL");
 
-MODULE_PARM(nologo, "i");
+module_param(nologo, bool, 0);
 MODULE_PARM_DESC(nologo, "Disables startup logo if != 0 (default=0)");
 module_init(hgafb_init);
 
diff -Nru a/drivers/video/i810/i810_accel.c b/drivers/video/i810/i810_accel.c
--- a/drivers/video/i810/i810_accel.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/video/i810/i810_accel.c	2005-03-01 23:38:52 -08:00
@@ -252,49 +252,6 @@
 	end_iring(par);
 }
 
-/**
- * mono_src_copy_blit - color expand from video memory to framebuffer
- * @dwidth: width of destination
- * @dheight: height of destination
- * @dpitch: pixels per line of the buffer
- * @qsize: size of bitmap in quad words
- * @dest: address of first byte of pixel;
- * @rop: raster operation
- * @blit_bpp: pixelformat to use which can be different from the 
- *            framebuffer's pixelformat
- * @src: address of image data
- * @bg: backgound color
- * @fg: forground color
- * @par: pointer to i810fb_par structure
- *
- * DESCRIPTION:
- * A color expand operation where the  source data is in video memory. 
- * Useful for drawing text. 
- *
- * REQUIREMENT:
- * The end of a scanline must be padded to the next word.
- */
-static inline void mono_src_copy_blit(int dwidth, int dheight, int dpitch, 
-				      int qsize, int blit_bpp, int rop, 
-				      int dest, int src, int bg,
-				      int fg, struct fb_info *info)
-{
-	struct i810fb_par *par = (struct i810fb_par *) info->par;
-
-	if (begin_iring(info, 32 + IRING_PAD)) return;
-
-	PUT_RING(BLIT | MONO_SOURCE_COPY_BLIT | 6);
-	PUT_RING(DYN_COLOR_EN | blit_bpp | rop << 16 | dpitch | 1 << 27);
-	PUT_RING(dheight << 16 | dwidth);
-	PUT_RING(dest);
-	PUT_RING(qsize - 1);
-	PUT_RING(src);
-	PUT_RING(bg);
-	PUT_RING(fg);
-
-	end_iring(par);
-}
-
 static inline void load_front(int offset, struct fb_info *info)
 {
 	struct i810fb_par *par = (struct i810fb_par *) info->par;
diff -Nru a/drivers/video/i810/i810_main.c b/drivers/video/i810/i810_main.c
--- a/drivers/video/i810/i810_main.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/video/i810/i810_main.c	2005-03-01 23:38:55 -08:00
@@ -2002,20 +2002,20 @@
 	return pci_register_driver(&i810fb_driver);
 }
 
-module_param(vram, int, 4);
+module_param(vram, int, 0);
 MODULE_PARM_DESC(vram, "System RAM to allocate to framebuffer in MiB" 
 		 " (default=4)");
 module_param(voffset, int, 0);
 MODULE_PARM_DESC(voffset, "at what offset to place start of framebuffer "
                  "memory (0 to maximum aperture size), in MiB (default = 48)");
-module_param(bpp, int, 8);
+module_param(bpp, int, 0);
 MODULE_PARM_DESC(bpp, "Color depth for display in bits per pixel"
 		 " (default = 8)");
-module_param(xres, int, 640);
+module_param(xres, int, 0);
 MODULE_PARM_DESC(xres, "Horizontal resolution in pixels (default = 640)");
-module_param(yres, int, 480);
+module_param(yres, int, 0);
 MODULE_PARM_DESC(yres, "Vertical resolution in scanlines (default = 480)");
-module_param(vyres,int, 480);
+module_param(vyres,int, 0);
 MODULE_PARM_DESC(vyres, "Virtual vertical resolution in scanlines"
 		 " (default = 480)");
 module_param(hsync1, int, 0);
diff -Nru a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c
--- a/drivers/video/intelfb/intelfbdrv.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/video/intelfb/intelfbdrv.c	2005-03-01 23:39:08 -08:00
@@ -1234,8 +1234,7 @@
 static int
 intelfb_set_par(struct fb_info *info)
 {
-	struct intelfb_hwstate hw;
-
+ 	struct intelfb_hwstate *hw;
         struct intelfb_info *dinfo = GET_DINFO(info);
 
 	if (FIXED_MODE(dinfo)) {
@@ -1243,6 +1242,10 @@
 		return -EINVAL;
 	}
 
+ 	hw = kmalloc(sizeof(*hw), GFP_ATOMIC);
+ 	if (!hw)
+ 		return -ENOMEM;
+
 	DBG_MSG("intelfb_set_par (%dx%d-%d)\n", info->var.xres,
 		info->var.yres, info->var.bits_per_pixel);
 
@@ -1251,15 +1254,15 @@
 	if (dinfo->accel)
 		intelfbhw_2d_stop(dinfo);
 
-	hw = dinfo->save_state;
-	if (intelfbhw_mode_to_hw(dinfo, &hw, &info->var))
-		return -EINVAL;
-	if (intelfbhw_program_mode(dinfo, &hw, 0))
-		return -EINVAL;
+ 	memcpy(hw, &dinfo->save_state, sizeof(*hw));
+ 	if (intelfbhw_mode_to_hw(dinfo, hw, &info->var))
+ 		goto invalid_mode;
+ 	if (intelfbhw_program_mode(dinfo, hw, 0))
+ 		goto invalid_mode;
 
 #if REGDUMP > 0
-	intelfbhw_read_hw_state(dinfo, &hw, 0);
-	intelfbhw_print_hw_state(dinfo, &hw);
+ 	intelfbhw_read_hw_state(dinfo, hw, 0);
+ 	intelfbhw_print_hw_state(dinfo, hw);
 #endif
 
 	update_dinfo(dinfo, &info->var);
@@ -1278,7 +1281,11 @@
 	} else {
 		info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
 	}
+	kfree(hw);
 	return 0;
+invalid_mode:
+	kfree(hw);
+	return -EINVAL;
 }
 
 static int
diff -Nru a/drivers/video/intelfb/intelfbhw.c b/drivers/video/intelfb/intelfbhw.c
--- a/drivers/video/intelfb/intelfbhw.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/video/intelfb/intelfbhw.c	2005-03-01 23:38:52 -08:00
@@ -1207,6 +1207,22 @@
 	OUTREG(ADPA, tmp);
 
 	/* setup display plane */
+	if (dinfo->pdev->device == PCI_DEVICE_ID_INTEL_830M) {
+		/*
+		 *      i830M errata: the display plane must be enabled
+		 *      to allow writes to the other bits in the plane
+		 *      control register.
+		 */
+		tmp = INREG(DSPACNTR);
+		if ((tmp & DISPPLANE_PLANE_ENABLE) != DISPPLANE_PLANE_ENABLE) {
+			tmp |= DISPPLANE_PLANE_ENABLE;
+			OUTREG(DSPACNTR, tmp);
+			OUTREG(DSPACNTR,
+			       hw->disp_a_ctrl|DISPPLANE_PLANE_ENABLE);
+			mdelay(1);
+              }
+	}
+
 	OUTREG(DSPACNTR, hw->disp_a_ctrl & ~DISPPLANE_PLANE_ENABLE);
 	OUTREG(DSPASTRIDE, hw->disp_a_stride);
 	OUTREG(DSPABASE, hw->disp_a_base);
diff -Nru a/drivers/video/logo/Kconfig b/drivers/video/logo/Kconfig
--- a/drivers/video/logo/Kconfig	2005-03-01 23:38:56 -08:00
+++ b/drivers/video/logo/Kconfig	2005-03-01 23:38:56 -08:00
@@ -25,7 +25,7 @@
 
 config LOGO_DEC_CLUT224
 	bool "224-color Digital Equipment Corporation Linux logo"
-	depends on LOGO && DECSTATION
+	depends on LOGO && MACH_DECSTATION
 	default y
 
 config LOGO_MAC_CLUT224
diff -Nru a/drivers/video/matrox/Makefile b/drivers/video/matrox/Makefile
--- a/drivers/video/matrox/Makefile	2005-03-01 23:38:54 -08:00
+++ b/drivers/video/matrox/Makefile	2005-03-01 23:38:54 -08:00
@@ -4,8 +4,7 @@
 
 # Each configuration option enables a list of files.
 
-my-obj-$(CONFIG_FB_MATROX_G100)	  += g450_pll.o
-my-obj-$(CONFIG_FB_MATROX_G450)   += matroxfb_g450.o matroxfb_crtc2.o
+my-obj-$(CONFIG_FB_MATROX_G)      += g450_pll.o matroxfb_g450.o matroxfb_crtc2.o
 
 obj-$(CONFIG_FB_MATROX)           += matroxfb_base.o matroxfb_accel.o matroxfb_DAC1064.o matroxfb_Ti3026.o matroxfb_misc.o $(my-obj-y)
 obj-$(CONFIG_FB_MATROX_I2C)       += i2c-matroxfb.o
diff -Nru a/drivers/video/matrox/matroxfb_DAC1064.c b/drivers/video/matrox/matroxfb_DAC1064.c
--- a/drivers/video/matrox/matroxfb_DAC1064.c	2005-03-01 23:38:56 -08:00
+++ b/drivers/video/matrox/matroxfb_DAC1064.c	2005-03-01 23:38:56 -08:00
@@ -155,7 +155,7 @@
 	hw->MXoptionReg = mx;
 }
 
-#ifdef CONFIG_FB_MATROX_G450
+#ifdef CONFIG_FB_MATROX_G
 static void g450_set_plls(WPMINFO2) {
 	u_int32_t c2_ctl;
 	unsigned int pxc;
@@ -253,7 +253,7 @@
 	hw->DACreg[POS1064_XMISCCTRL] &= M1064_XMISCCTRL_DAC_WIDTHMASK;
 	hw->DACreg[POS1064_XMISCCTRL] |= M1064_XMISCCTRL_LUT_EN;
 	hw->DACreg[POS1064_XPIXCLKCTRL] = M1064_XPIXCLKCTRL_PLL_UP | M1064_XPIXCLKCTRL_EN | M1064_XPIXCLKCTRL_SRC_PLL;
-#ifdef CONFIG_FB_MATROX_G450
+#ifdef CONFIG_FB_MATROX_G
 	if (ACCESS_FBINFO(devflags.g450dac)) {
 		hw->DACreg[POS1064_XPWRCTRL] = 0x1F;	/* powerup everything */
 		hw->DACreg[POS1064_XOUTPUTCONN] = 0x00;	/* disable outputs */
@@ -498,7 +498,7 @@
 	.compute = m1064_compute,
 };
 
-#ifdef CONFIG_FB_MATROX_G450
+#ifdef CONFIG_FB_MATROX_G
 static int g450_compute(void* out, struct my_timming* m) {
 #define minfo ((struct matrox_fb_info*)out)
 	if (m->mnp < 0) {
@@ -541,7 +541,7 @@
 }
 #endif
 
-#ifdef CONFIG_FB_MATROX_G100
+#ifdef CONFIG_FB_MATROX_G
 static int MGAG100_init(WPMINFO struct my_timming* m) {
 	struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
 
@@ -562,7 +562,7 @@
 	if (DAC1064_init_2(PMINFO m)) return 1;
 	return 0;
 }
-#endif	/* G100 */
+#endif	/* G */
 
 #ifdef CONFIG_FB_MATROX_MYSTIQUE
 static void MGA1064_ramdac_init(WPMINFO2) {
@@ -583,7 +583,7 @@
 }
 #endif
 
-#ifdef CONFIG_FB_MATROX_G100
+#ifdef CONFIG_FB_MATROX_G
 /* BIOS environ */
 static int x7AF4 = 0x10;	/* flags, maybe 0x10 = SDRAM, 0x00 = SGRAM??? */
 				/* G100 wants 0x10, G200 SGRAM does not care... */
@@ -692,8 +692,7 @@
 }
 #endif
 
-#ifdef CONFIG_FB_MATROX_G100
-#ifdef CONFIG_FB_MATROX_G450
+#ifdef CONFIG_FB_MATROX_G
 static void g450_mclk_init(WPMINFO2) {
 	/* switch all clocks to PCI source */
 	pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg | 4);
@@ -811,10 +810,6 @@
 	
 	return;
 }
-#else
-static inline void g450_preinit(WPMINFO2) {
-}
-#endif
 
 static int MGAG100_preinit(WPMINFO2) {
 	static const int vxres_g100[] = {  512,        640, 768,  800,  832,  960,
@@ -851,7 +846,7 @@
 	ACCESS_FBINFO(capable.plnwt) = ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG100
 			? ACCESS_FBINFO(devflags.sgram) : 1;
 
-#ifdef CONFIG_FB_MATROX_G450
+#ifdef CONFIG_FB_MATROX_G
 	if (ACCESS_FBINFO(devflags.g450dac)) {
 		ACCESS_FBINFO(outputs[0]).output = &g450out;
 	} else
@@ -1043,7 +1038,7 @@
 }
 #endif
 
-#ifdef CONFIG_FB_MATROX_G100
+#ifdef CONFIG_FB_MATROX_G
 static void MGAG100_restore(WPMINFO2) {
 	int i;
 	struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
@@ -1077,7 +1072,7 @@
 EXPORT_SYMBOL(matrox_mystique);
 #endif
 
-#ifdef CONFIG_FB_MATROX_G100
+#ifdef CONFIG_FB_MATROX_G
 struct matrox_switch matrox_G100 = {
 	MGAG100_preinit, MGAG100_reset, MGAG100_init, MGAG100_restore,
 };
diff -Nru a/drivers/video/matrox/matroxfb_DAC1064.h b/drivers/video/matrox/matroxfb_DAC1064.h
--- a/drivers/video/matrox/matroxfb_DAC1064.h	2005-03-01 23:39:17 -08:00
+++ b/drivers/video/matrox/matroxfb_DAC1064.h	2005-03-01 23:39:17 -08:00
@@ -9,7 +9,7 @@
 #ifdef CONFIG_FB_MATROX_MYSTIQUE
 extern struct matrox_switch matrox_mystique;
 #endif
-#ifdef CONFIG_FB_MATROX_G100
+#ifdef CONFIG_FB_MATROX_G
 extern struct matrox_switch matrox_G100;
 #endif
 #ifdef NEED_DAC1064
diff -Nru a/drivers/video/matrox/matroxfb_base.c b/drivers/video/matrox/matroxfb_base.c
--- a/drivers/video/matrox/matroxfb_base.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/video/matrox/matroxfb_base.c	2005-03-01 23:39:07 -08:00
@@ -1346,7 +1346,7 @@
 #ifdef CONFIG_FB_MATROX_MYSTIQUE
 static struct video_board vbMystique		= {0x0800000, 0x0800000, FB_ACCEL_MATROX_MGA1064SG,	&matrox_mystique};
 #endif	/* CONFIG_FB_MATROX_MYSTIQUE */
-#ifdef CONFIG_FB_MATROX_G100
+#ifdef CONFIG_FB_MATROX_G
 static struct video_board vbG100		= {0x0800000, 0x0800000, FB_ACCEL_MATROX_MGAG100,	&matrox_G100};
 static struct video_board vbG200		= {0x1000000, 0x1000000, FB_ACCEL_MATROX_MGAG200,	&matrox_G100};
 #ifdef CONFIG_FB_MATROX_32MB
@@ -1430,7 +1430,7 @@
 		&vbMystique,
 		"Mystique 220 (PCI)"},
 #endif
-#ifdef CONFIG_FB_MATROX_G100
+#ifdef CONFIG_FB_MATROX_G
 	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_G100_MM,	0xFF,
 		0,			0,
 		DEVF_G100,
@@ -2105,7 +2105,7 @@
 	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_MYS,
 		PCI_ANY_ID,	PCI_ANY_ID,	0, 0, 0},
 #endif
-#ifdef CONFIG_FB_MATROX_G100
+#ifdef CONFIG_FB_MATROX_G
 	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_G100_MM,
 		PCI_ANY_ID,	PCI_ANY_ID,	0, 0, 0},
 	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_G100_AGP,
@@ -2459,84 +2459,86 @@
 MODULE_DESCRIPTION("Accelerated FBDev driver for Matrox Millennium/Mystique/G100/G200/G400/G450/G550");
 MODULE_LICENSE("GPL");
 
-MODULE_PARM(mem, "i");
+module_param(mem, int, 0);
 MODULE_PARM_DESC(mem, "Size of available memory in MB, KB or B (2,4,8,12,16MB, default=autodetect)");
-MODULE_PARM(disabled, "i");
+module_param(disabled, int, 0);
 MODULE_PARM_DESC(disabled, "Disabled (0 or 1=disabled) (default=0)");
-MODULE_PARM(noaccel, "i");
+module_param(noaccel, int, 0);
 MODULE_PARM_DESC(noaccel, "Do not use accelerating engine (0 or 1=disabled) (default=0)");
-MODULE_PARM(nopan, "i");
+module_param(nopan, int, 0);
 MODULE_PARM_DESC(nopan, "Disable pan on startup (0 or 1=disabled) (default=0)");
-MODULE_PARM(no_pci_retry, "i");
+module_param(no_pci_retry, int, 0);
 MODULE_PARM_DESC(no_pci_retry, "PCI retries enabled (0 or 1=disabled) (default=0)");
-MODULE_PARM(novga, "i");
+module_param(novga, int, 0);
 MODULE_PARM_DESC(novga, "VGA I/O (0x3C0-0x3DF) disabled (0 or 1=disabled) (default=0)");
-MODULE_PARM(nobios, "i");
+module_param(nobios, int, 0);
 MODULE_PARM_DESC(nobios, "Disables ROM BIOS (0 or 1=disabled) (default=do not change BIOS state)");
-MODULE_PARM(noinit, "i");
+module_param(noinit, int, 0);
 MODULE_PARM_DESC(noinit, "Disables W/SG/SD-RAM and bus interface initialization (0 or 1=do not initialize) (default=0)");
-MODULE_PARM(memtype, "i");
+module_param(memtype, int, 0);
 MODULE_PARM_DESC(memtype, "Memory type for G200/G400 (see Documentation/fb/matroxfb.txt for explanation) (default=3 for G200, 0 for G400)");
-MODULE_PARM(mtrr, "i");
+#ifdef CONFIG_MTRR
+module_param(mtrr, int, 0);
 MODULE_PARM_DESC(mtrr, "This speeds up video memory accesses (0=disabled or 1) (default=1)");
-MODULE_PARM(sgram, "i");
+#endif
+module_param(sgram, int, 0);
 MODULE_PARM_DESC(sgram, "Indicates that G100/G200/G400 has SGRAM memory (0=SDRAM, 1=SGRAM) (default=0)");
-MODULE_PARM(inv24, "i");
+module_param(inv24, int, 0);
 MODULE_PARM_DESC(inv24, "Inverts clock polarity for 24bpp and loop frequency > 100MHz (default=do not invert polarity)");
-MODULE_PARM(inverse, "i");
+module_param(inverse, int, 0);
 MODULE_PARM_DESC(inverse, "Inverse (0 or 1) (default=0)");
 #ifdef CONFIG_FB_MATROX_MULTIHEAD
-MODULE_PARM(dev, "i");
+module_param(dev, int, 0);
 MODULE_PARM_DESC(dev, "Multihead support, attach to device ID (0..N) (default=all working)");
 #else
-MODULE_PARM(dev, "i");
+module_param(dev, int, 0);
 MODULE_PARM_DESC(dev, "Multihead support, attach to device ID (0..N) (default=first working)");
 #endif
-MODULE_PARM(vesa, "i");
+module_param(vesa, int, 0);
 MODULE_PARM_DESC(vesa, "Startup videomode (0x000-0x1FF) (default=0x101)");
-MODULE_PARM(xres, "i");
+module_param(xres, int, 0);
 MODULE_PARM_DESC(xres, "Horizontal resolution (px), overrides xres from vesa (default=vesa)");
-MODULE_PARM(yres, "i");
+module_param(yres, int, 0);
 MODULE_PARM_DESC(yres, "Vertical resolution (scans), overrides yres from vesa (default=vesa)");
-MODULE_PARM(upper, "i");
+module_param(upper, int, 0);
 MODULE_PARM_DESC(upper, "Upper blank space (scans), overrides upper from vesa (default=vesa)");
-MODULE_PARM(lower, "i");
+module_param(lower, int, 0);
 MODULE_PARM_DESC(lower, "Lower blank space (scans), overrides lower from vesa (default=vesa)");
-MODULE_PARM(vslen, "i");
+module_param(vslen, int, 0);
 MODULE_PARM_DESC(vslen, "Vertical sync length (scans), overrides lower from vesa (default=vesa)");
-MODULE_PARM(left, "i");
+module_param(left, int, 0);
 MODULE_PARM_DESC(left, "Left blank space (px), overrides left from vesa (default=vesa)");
-MODULE_PARM(right, "i");
+module_param(right, int, 0);
 MODULE_PARM_DESC(right, "Right blank space (px), overrides right from vesa (default=vesa)");
-MODULE_PARM(hslen, "i");
+module_param(hslen, int, 0);
 MODULE_PARM_DESC(hslen, "Horizontal sync length (px), overrides hslen from vesa (default=vesa)");
-MODULE_PARM(pixclock, "i");
+module_param(pixclock, int, 0);
 MODULE_PARM_DESC(pixclock, "Pixelclock (ns), overrides pixclock from vesa (default=vesa)");
-MODULE_PARM(sync, "i");
+module_param(sync, int, 0);
 MODULE_PARM_DESC(sync, "Sync polarity, overrides sync from vesa (default=vesa)");
-MODULE_PARM(depth, "i");
+module_param(depth, int, 0);
 MODULE_PARM_DESC(depth, "Color depth (0=text,8,15,16,24,32) (default=vesa)");
-MODULE_PARM(maxclk, "i");
+module_param(maxclk, int, 0);
 MODULE_PARM_DESC(maxclk, "Startup maximal clock, 0-999MHz, 1000-999999kHz, 1000000-INF Hz");
-MODULE_PARM(fh, "i");
+module_param(fh, int, 0);
 MODULE_PARM_DESC(fh, "Startup horizontal frequency, 0-999kHz, 1000-INF Hz");
-MODULE_PARM(fv, "i");
+module_param(fv, int, 0);
 MODULE_PARM_DESC(fv, "Startup vertical frequency, 0-INF Hz\n"
 "You should specify \"fv:max_monitor_vsync,fh:max_monitor_hsync,maxclk:max_monitor_dotclock\"\n");
-MODULE_PARM(grayscale, "i");
+module_param(grayscale, int, 0);
 MODULE_PARM_DESC(grayscale, "Sets display into grayscale. Works perfectly with paletized videomode (4, 8bpp), some limitations apply to 16, 24 and 32bpp videomodes (default=nograyscale)");
-MODULE_PARM(cross4MB, "i");
+module_param(cross4MB, int, 0);
 MODULE_PARM_DESC(cross4MB, "Specifies that 4MB boundary can be in middle of line. (default=autodetected)");
-MODULE_PARM(dfp, "i");
+module_param(dfp, int, 0);
 MODULE_PARM_DESC(dfp, "Specifies whether to use digital flat panel interface of G200/G400 (0 or 1) (default=0)");
-MODULE_PARM(dfp_type, "i");
+module_param(dfp_type, int, 0);
 MODULE_PARM_DESC(dfp_type, "Specifies DFP interface type (0 to 255) (default=read from hardware)");
-MODULE_PARM(outputs, "c8");
+module_param_string(outputs, outputs, sizeof(outputs), 0);
 MODULE_PARM_DESC(outputs, "Specifies which CRTC is mapped to which output (string of up to three letters, consisting of 0 (disabled), 1 (CRTC1), 2 (CRTC2)) (default=111 for Gx50, 101 for G200/G400 with DFP, and 100 for all other devices)");
 #ifdef CONFIG_PPC_PMAC
-MODULE_PARM(vmode, "i");
+module_param_named(vmode, default_vmode, int, 0);
 MODULE_PARM_DESC(vmode, "Specify the vmode mode number that should be used (640x480 default)");
-MODULE_PARM(cmode, "i");
+module_param_named(cmode, default_cmode, int, 0);
 MODULE_PARM_DESC(cmode, "Specify the video depth that should be used (8bit default)");
 #endif
 
diff -Nru a/drivers/video/matrox/matroxfb_base.h b/drivers/video/matrox/matroxfb_base.h
--- a/drivers/video/matrox/matroxfb_base.h	2005-03-01 23:38:57 -08:00
+++ b/drivers/video/matrox/matroxfb_base.h	2005-03-01 23:38:57 -08:00
@@ -127,7 +127,7 @@
 
 /* G-series and Mystique have (almost) same DAC */
 #undef NEED_DAC1064
-#if defined(CONFIG_FB_MATROX_MYSTIQUE) || defined(CONFIG_FB_MATROX_G100)
+#if defined(CONFIG_FB_MATROX_MYSTIQUE) || defined(CONFIG_FB_MATROX_G)
 #define NEED_DAC1064 1
 #endif
 
diff -Nru a/drivers/video/matrox/matroxfb_crtc2.c b/drivers/video/matrox/matroxfb_crtc2.c
--- a/drivers/video/matrox/matroxfb_crtc2.c	2005-03-01 23:39:09 -08:00
+++ b/drivers/video/matrox/matroxfb_crtc2.c	2005-03-01 23:39:09 -08:00
@@ -21,7 +21,7 @@
 
 static int mem = 8192;
 
-MODULE_PARM(mem, "i");
+module_param(mem, int, 0);
 MODULE_PARM_DESC(mem, "Memory size reserved for dualhead (default=8MB)");
 
 /* **************************************************** */
diff -Nru a/drivers/video/matrox/matroxfb_g450.h b/drivers/video/matrox/matroxfb_g450.h
--- a/drivers/video/matrox/matroxfb_g450.h	2005-03-01 23:39:17 -08:00
+++ b/drivers/video/matrox/matroxfb_g450.h	2005-03-01 23:39:17 -08:00
@@ -3,7 +3,7 @@
 
 #include "matroxfb_base.h"
 
-#ifdef CONFIG_FB_MATROX_G450
+#ifdef CONFIG_FB_MATROX_G
 void matroxfb_g450_connect(WPMINFO2);
 void matroxfb_g450_shutdown(WPMINFO2);
 #else
diff -Nru a/drivers/video/maxinefb.c b/drivers/video/maxinefb.c
--- a/drivers/video/maxinefb.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/video/maxinefb.c	2005-03-01 23:38:54 -08:00
@@ -43,31 +43,25 @@
 static struct fb_info fb_info;
 
 static struct fb_var_screeninfo maxinefb_defined = {
-	.xres 		= 1024,
-	.yres 		= 768,
-	.xres_virtual 	= 1024,
-	.yres_virtual 	= 768,
-	.bits_per_pixel = 8,
-	.red.length	= 8,
-	.green.length	= 8,
-	.blue.length	= 8,
-	.activate 	= FB_ACTIVATE_NOW,
-	.height 	= -1,
-	.width 		= -1,
-	.vmode 		= FB_VMODE_NONINTERLACED,
+	.xres =		1024,
+	.yres =		768,
+	.xres_virtual =	1024,
+	.yres_virtual =	768,
+	.bits_per_pixel =8,
+	.activate =	FB_ACTIVATE_NOW,
+	.height =	-1,
+	.width =	-1,
+	.vmode =	FB_VMODE_NONINTERLACED,
 };
 
 static struct fb_fix_screeninfo maxinefb_fix = {
-	.id 		= "Maxine onboard graphics 1024x768x8",
-	.smem_len 	= (1024*768),
-	.type 		= FB_TYPE_PACKED_PIXELS,
-	.visual 	= FB_VISUAL_PSEUDOCOLOR,
-	.line_length 	= 1024,
+	.id =		"Maxine onboard graphics 1024x768x8",
+	.smem_len =	(1024*768),
+	.type =		FB_TYPE_PACKED_PIXELS,
+	.visual =	FB_VISUAL_PSEUDOCOLOR,
+	.line_length =	1024,
 };
 
-/* Reference to machine type set in arch/mips/dec/prom/identify.c, KM */
-extern unsigned long mips_machtype;
-
 /* Handle the funny Inmos RamDAC/video controller ... */
 
 void maxinefb_ims332_write_register(int regno, register unsigned int val)
@@ -100,12 +94,12 @@
 	/* value to be written into the palette reg. */
 	unsigned long hw_colorvalue = 0;
 
-	red   >>= 8;	/* The cmap fields are 16 bits    */
-	green >>= 8;	/* wide, but the harware colormap */
-	blue  >>= 8;	/* registers are only 8 bits wide */
+	red   >>= 8;    /* The cmap fields are 16 bits    */
+	green >>= 8;    /* wide, but the harware colormap */
+	blue  >>= 8;    /* registers are only 8 bits wide */
 
 	hw_colorvalue = (blue << 16) + (green << 8) + (red);
-	
+
 	maxinefb_ims332_write_register(IMS332_REG_COLOR_PALETTE + regno,
 				       hw_colorvalue);
 	return 0;
@@ -113,16 +107,18 @@
 
 static struct fb_ops maxinefb_ops = {
 	.owner		= THIS_MODULE,
-	.fb_setcolreg	= maxinefb_setcolreg,	
+	.fb_get_fix	= gen_get_fix,
+	.fb_get_var	= gen_get_var,
+	.fb_setcolreg	= maxinefb_setcolreg,
 	.fb_fillrect	= cfb_fillrect,
 	.fb_copyarea	= cfb_copyarea,
-	.fb_imageblit	= cfb_imageblit,		
+	.fb_imageblit	= cfb_imageblit,
 	.fb_cursor	= soft_cursor,
 };
 
 int __init maxinefb_init(void)
 {
-	volatile unsigned char *fboff;
+	unsigned long fboff;
 	unsigned long fb_start;
 	int i;
 
@@ -142,7 +138,7 @@
 
 	/* Clear screen */
 	for (fboff = fb_start; fboff < fb_start + 0x1ffff; fboff++)
-		*fboff = 0x0;
+		*(volatile unsigned char *)fboff = 0x0;
 
 	maxinefb_fix.smem_start = fb_start;
 	
@@ -159,7 +155,7 @@
 	}
 
 	fb_info.fbops = &maxinefb_ops;
-	fb_info.screen_base = (char *) maxinefb_fix.smem_start;
+	fb_info.screen_base = (char *)maxinefb_fix.smem_start;
 	fb_info.var = maxinefb_defined;
 	fb_info.fix = maxinefb_fix;
 	fb_info.flags = FBINFO_DEFAULT;
diff -Nru a/drivers/video/modedb.c b/drivers/video/modedb.c
--- a/drivers/video/modedb.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/video/modedb.c	2005-03-01 23:38:57 -08:00
@@ -29,9 +29,7 @@
 #define DPRINTK(fmt, args...)
 #endif
 
-
-const char *global_mode_option = NULL;
-
+const char *global_mode_option;
 
     /*
      *  Standard video mode definitions (taken from XFree86)
@@ -39,7 +37,7 @@
 
 #define DEFAULT_MODEDB_INDEX	0
 
-static const __init struct fb_videomode modedb[] = {
+static const struct fb_videomode modedb[] = {
     {
 	/* 640x400 @ 70 Hz, 31.5 kHz hsync */
 	NULL, 70, 640, 400, 39721, 40, 24, 39, 9, 96, 2,
diff -Nru a/drivers/video/neofb.c b/drivers/video/neofb.c
--- a/drivers/video/neofb.c	2005-03-01 23:39:06 -08:00
+++ b/drivers/video/neofb.c	2005-03-01 23:39:06 -08:00
@@ -152,11 +152,6 @@
 };
 #endif
 
-static inline u32 read_le32(int regindex, const struct neofb_par *par)
-{
-	return readl(par->neo2200 + par->cursorOff + regindex);
-}
-
 static inline void write_le32(int regindex, u32 val, const struct neofb_par *par)
 {
 	writel(val, par->neo2200 + par->cursorOff + regindex);
diff -Nru a/drivers/video/pm2fb.c b/drivers/video/pm2fb.c
--- a/drivers/video/pm2fb.c	2005-03-01 23:39:18 -08:00
+++ b/drivers/video/pm2fb.c	2005-03-01 23:39:18 -08:00
@@ -11,11 +11,11 @@
  * and additional input from James Simmon's port of Hannu Mallat's tdfx
  * driver.
  *
- * $Id$
- *
- * I have a Creative Graphics Blaster Exxtreme card - pm2fb on x86.
- * I have no access to other pm2fb implementations, and cannot test
- * on them. Therefore for now I am omitting Sparc and CVision code.
+ * I have a Creative Graphics Blaster Exxtreme card - pm2fb on x86.  I
+ * have no access to other pm2fb implementations. Sparc (and thus
+ * hopefully other big-endian) devices now work, thanks to a lot of
+ * testing work by Ron Murray. I have no access to CVision hardware,
+ * and therefore for now I am omitting the CVision code.
  *
  * Multiple boards support has been on the TODO list for ages.
  * Don't expect this to change.
@@ -29,6 +29,7 @@
 
 #include <linux/config.h>
 #include <linux/module.h>
+#include <linux/moduleparam.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/string.h>
@@ -47,10 +48,6 @@
 #error	"The endianness of the target host has not been defined."
 #endif
 
-#if defined(__BIG_ENDIAN) && !defined(__sparc__)
-#define PM2FB_BE_APERTURE
-#endif
-
 #if !defined(CONFIG_PCI)
 #error "Only generic PCI cards supported."
 #endif
@@ -63,16 +60,6 @@
 #endif
 
 /*
- * The 2.4 driver calls reset_card() at init time, where it also sets the
- * initial mode. I don't think the driver should touch the chip until
- * the console sets a video mode. So I was calling this at the start
- * of setting a mode. However, certainly on 1280x1024 depth 16 on my
- * PCI Graphics Blaster Exxtreme this causes the display to smear
- * slightly.  I don't know why. Guesses to jim.hague@acm.org.
- */
-#undef RESET_CARD_ON_MODE_SET
-
-/*
  * Driver data 
  */
 static char *mode __initdata = NULL;
@@ -101,6 +88,9 @@
 	unsigned char	__iomem *v_regs;/* virtual address of p_regs */
 	u32 	   	memclock;	/* memclock */
 	u32		video;		/* video flags before blanking */
+	u32		mem_config;	/* MemConfig reg at probe */
+	u32		mem_control;	/* MemControl reg at probe */
+	u32		boot_address;	/* BootAddress reg at probe */
 };
 
 /*
@@ -118,8 +108,7 @@
 };
 
 /*
- * Default video mode. In case the modedb doesn't work, or we're
- * a module (in which case modedb doesn't really work).
+ * Default video mode. In case the modedb doesn't work.
  */
 static struct fb_var_screeninfo pm2fb_var __initdata = {
 	/* "640x480, 8 bpp @ 60 Hz */
@@ -201,13 +190,6 @@
 	pm2_WR(p, index, v);
 }
 
-inline static u32 pm2v_RDAC_RD(struct pm2fb_par* p, s32 idx)
-{
-	pm2_WR(p, PM2VR_RD_INDEX_LOW, idx & 0xff);
-	mb();
-	return pm2_RD(p, PM2VR_RD_INDEXED_DATA);
-}
-
 inline static void pm2v_RDAC_WR(struct pm2fb_par* p, s32 idx, u32 v)
 {
 	pm2_WR(p, PM2VR_RD_INDEX_LOW, idx & 0xff);
@@ -350,7 +332,6 @@
 	}
 }
 
-#ifdef RESET_CARD_ON_MODE_SET
 static void reset_card(struct pm2fb_par* p)
 {
 	if (p->type == PM2_TYPE_PERMEDIA2V)
@@ -365,8 +346,14 @@
 	pm2_WR(p, PM2R_FIFO_DISCON, 1);
 	mb();
 #endif
+
+	/* Restore stashed memory config information from probe */
+	WAIT_FIFO(p, 3);
+	pm2_WR(p, PM2R_MEM_CONTROL, p->mem_control);
+	pm2_WR(p, PM2R_BOOT_ADDRESS, p->boot_address);
+	wmb();
+	pm2_WR(p, PM2R_MEM_CONFIG, p->mem_config);
 }
-#endif
 
 static void reset_config(struct pm2fb_par* p)
 {
@@ -426,27 +413,36 @@
 
 static void set_aperture(struct pm2fb_par* p, u32 depth)
 {
+	/*
+	 * The hardware is little-endian. When used in big-endian
+	 * hosts, the on-chip aperture settings are used where
+	 * possible to translate from host to card byte order.
+	 */
 	WAIT_FIFO(p, 4);
 #ifdef __LITTLE_ENDIAN
-	pm2_WR(p, PM2R_APERTURE_ONE, 0);
-	pm2_WR(p, PM2R_APERTURE_TWO, 0);
+	pm2_WR(p, PM2R_APERTURE_ONE, PM2F_APERTURE_STANDARD);
 #else
 	switch (depth) {
-	case 8:
-	case 24:
-		pm2_WR(p, PM2R_APERTURE_ONE, 0);
-		pm2_WR(p, PM2R_APERTURE_TWO, 1);
+	case 24:	/* RGB->BGR */
+		/*
+		 * We can't use the aperture to translate host to
+		 * card byte order here, so we switch to BGR mode
+		 * in pm2fb_set_par().
+		 */
+	case 8:		/* B->B */
+		pm2_WR(p, PM2R_APERTURE_ONE, PM2F_APERTURE_STANDARD);
 		break;
-	case 16:
-		pm2_WR(p, PM2R_APERTURE_ONE, 2);
-		pm2_WR(p, PM2R_APERTURE_TWO, 1);
+	case 16:	/* HL->LH */
+		pm2_WR(p, PM2R_APERTURE_ONE, PM2F_APERTURE_HALFWORDSWAP);
 		break;
-	case 32:
-		pm2_WR(p, PM2R_APERTURE_ONE, 1);
-		pm2_WR(p, PM2R_APERTURE_TWO, 1);
+	case 32:	/* RGBA->ABGR */
+		pm2_WR(p, PM2R_APERTURE_ONE, PM2F_APERTURE_BYTESWAP);
 		break;
 	}
 #endif
+
+	// We don't use aperture two, so this may be superflous
+	pm2_WR(p, PM2R_APERTURE_TWO, PM2F_APERTURE_STANDARD);
 }
 
 static void set_color(struct pm2fb_par* p, unsigned char regno,
@@ -462,6 +458,28 @@
 	pm2_WR(p, PM2R_RD_PALETTE_DATA, b);
 }
 
+static void set_memclock(struct pm2fb_par* par, u32 clk)
+{
+	int i;
+	unsigned char m, n, p;
+
+	pm2_mnp(clk, &m, &n, &p);
+	WAIT_FIFO(par, 10);
+	pm2_RDAC_WR(par, PM2I_RD_MEMORY_CLOCK_3, 6);
+	wmb();
+	pm2_RDAC_WR(par, PM2I_RD_MEMORY_CLOCK_1, m);
+	pm2_RDAC_WR(par, PM2I_RD_MEMORY_CLOCK_2, n);
+	wmb();
+	pm2_RDAC_WR(par, PM2I_RD_MEMORY_CLOCK_3, 8|p);
+	wmb();
+	pm2_RDAC_RD(par, PM2I_RD_MEMORY_CLOCK_STATUS);
+	rmb();
+	for (i = 256;
+	     i && !(pm2_RD(par, PM2R_RD_INDEXED_DATA) & PM2F_PLL_LOCKED);
+	     i--)
+		;
+}
+
 static void set_pixclock(struct pm2fb_par* par, u32 clk)
 {
 	int i;
@@ -618,15 +636,23 @@
 		var->blue.offset  = 0;
 		var->blue.length  = 5;
 		break;
-	case 24:
+	case 32:
+		var->transp.offset = 24;
+		var->transp.length = 8;
 		var->red.offset	  = 16;
 		var->green.offset = 8;
 		var->blue.offset  = 0;
 		var->red.length = var->green.length = var->blue.length = 8;
-	case 32:
+		break;
+	case 24:
+#ifdef __BIG_ENDIAN
+		var->red.offset   = 0;
+		var->blue.offset  = 16;
+#else
 		var->red.offset   = 16;
-		var->green.offset = 8;
 		var->blue.offset  = 0;
+#endif
+		var->green.offset = 8;
 		var->red.length = var->green.length = var->blue.length = 8;
 		break;
 	}
@@ -656,18 +682,18 @@
 	u32 stride;
 	u32 base;
 	u32 video = 0;
-	u32 clrmode = PM2F_RD_COLOR_MODE_RGB;
+	u32 clrmode = PM2F_RD_COLOR_MODE_RGB | PM2F_RD_GUI_ACTIVE;
 	u32 txtmap = 0;
 	u32 pixsize = 0;
 	u32 clrformat = 0;
 	u32 xres;
 	int data64;
 
-#ifdef RESET_CARD_ON_MODE_SET
 	reset_card(par);
-#endif
 	reset_config(par);
 	clear_palette(par);
+	if ( par->memclock )
+		set_memclock(par, par->memclock);
     
 	width = (info->var.xres_virtual + 7) & ~7;
 	height = info->var.yres_virtual;
@@ -751,24 +777,21 @@
 		break;
 	case 16:
 		pm2_WR(par, PM2R_FB_READ_PIXEL, 1);
-		clrmode |= PM2F_RD_TRUECOLOR | 0x06;
+		clrmode |= PM2F_RD_TRUECOLOR | PM2F_RD_PIXELFORMAT_RGB565;
 		txtmap = PM2F_TEXTEL_SIZE_16;
 		pixsize = 1;
 		clrformat = 0x70;
 		break;
 	case 32:
 		pm2_WR(par, PM2R_FB_READ_PIXEL, 2);
-		clrmode |= PM2F_RD_TRUECOLOR | 0x08;
+		clrmode |= PM2F_RD_TRUECOLOR | PM2F_RD_PIXELFORMAT_RGBA8888;
 		txtmap = PM2F_TEXTEL_SIZE_32;
 		pixsize = 2;
 		clrformat = 0x20;
 		break;
 	case 24:
 		pm2_WR(par, PM2R_FB_READ_PIXEL, 4);
-		clrmode |= PM2F_RD_TRUECOLOR | 0x09;
-#ifndef PM2FB_BE_APERTURE
-		clrmode &= ~PM2F_RD_COLOR_MODE_RGB;
-#endif
+		clrmode |= PM2F_RD_TRUECOLOR | PM2F_RD_PIXELFORMAT_RGB888;
 		txtmap = PM2F_TEXTEL_SIZE_24;
 		pixsize = 4;
 		clrformat = 0x20;
@@ -799,8 +822,7 @@
 	WAIT_FIFO(par, 4);
 	switch (par->type) {
 	case PM2_TYPE_PERMEDIA2:
-		pm2_RDAC_WR(par, PM2I_RD_COLOR_MODE,
-			    PM2F_RD_COLOR_MODE_RGB | PM2F_RD_GUI_ACTIVE | clrmode);
+		pm2_RDAC_WR(par, PM2I_RD_COLOR_MODE, clrmode);
 		break;
 	case PM2_TYPE_PERMEDIA2V:
 		pm2v_RDAC_WR(par, PM2VI_RD_PIXEL_SIZE, pixsize);
@@ -1034,7 +1056,6 @@
 	struct pm2fb_par *default_par;
 	struct fb_info *info;
 	int size, err;
-	u32 pci_mem_config;
 	int err_retval = -ENXIO;
 
 	err = pci_enable_device(pdev);
@@ -1067,9 +1088,15 @@
 	pm2fb_fix.mmio_start = pci_resource_start(pdev, 0);
 	pm2fb_fix.mmio_len = PM2_REGS_SIZE;
 
-#ifdef PM2FB_BE_APERTURE
+#if defined(__BIG_ENDIAN)
+	/*
+	 * PM2 has a 64k register file, mapped twice in 128k. Lower
+	 * map is little-endian, upper map is big-endian.
+	 */
 	pm2fb_fix.mmio_start += PM2_REGS_SIZE;
+	DPRINTK("Adjusting register base for big-endian.\n");
 #endif
+	DPRINTK("Register base at 0x%lx\n", pm2fb_fix.mmio_start);
     
 	/* Registers - request region and map it. */
 	if ( !request_mem_region(pm2fb_fix.mmio_start, pm2fb_fix.mmio_len,
@@ -1086,9 +1113,16 @@
 		goto err_exit_neither;
 	}
 
+	/* Stash away memory register info for use when we reset the board */
+	default_par->mem_control = pm2_RD(default_par, PM2R_MEM_CONTROL);
+	default_par->boot_address = pm2_RD(default_par, PM2R_BOOT_ADDRESS);
+	default_par->mem_config = pm2_RD(default_par, PM2R_MEM_CONFIG);
+	DPRINTK("MemControl 0x%x BootAddress 0x%x MemConfig 0x%x\n",
+		default_par->mem_control, default_par->boot_address,
+		default_par->mem_config);
+
 	/* Now work out how big lfb is going to be. */
-	pci_mem_config = RD32(default_par->v_regs, PM2R_MEM_CONFIG);
-	switch(pci_mem_config & PM2F_MEM_CONFIG_RAM_MASK) {
+	switch(default_par->mem_config & PM2F_MEM_CONFIG_RAM_MASK) {
 	case PM2F_MEM_BANKS_1:
 		default_par->fb_size=0x200000;
 		break;
@@ -1126,13 +1160,11 @@
 	info->flags		= FBINFO_DEFAULT |
                                   FBINFO_HWACCEL_YPAN;
 
-#ifndef MODULE
 	if (!mode)
 		mode = "640x480@60";
 	 
 	err = fb_find_mode(&info->var, info, mode, NULL, 0, NULL, 8); 
 	if (!err || err == 4)
-#endif
 		info->var = pm2fb_var;
 
 	if (fb_alloc_cmap(&info->cmap, 256, 0) < 0)
@@ -1230,6 +1262,7 @@
 	return pci_module_init(&pm2fb_driver);
 }
 
+#ifdef MODULE
 /*
  *  Cleanup
  */
@@ -1238,11 +1271,13 @@
 {
 	pci_unregister_driver(&pm2fb_driver);
 }
+#endif
 
 /*
  *  Setup
  */
 
+#ifndef MODULE
 /**
  * Parse user speficied options.
  *
@@ -1268,6 +1303,7 @@
 	}
 	return 0;
 }
+#endif
 
 
 /* ------------------------------------------------------------------------- */
@@ -1277,12 +1313,18 @@
 
 
 module_init(pm2fb_init);
+
+#ifdef MODULE
 module_exit(pm2fb_exit);
 
-MODULE_PARM(mode,"s");
-MODULE_PARM(lowhsync,"i");
-MODULE_PARM(lowvsync,"i");
+module_param(mode, charp, 0);
+MODULE_PARM_DESC(mode, "Preferred video mode e.g. '648x480-8@60'");
+module_param(lowhsync, bool, 0);
+MODULE_PARM_DESC(lowhsync, "Force horizontal sync low regardless of mode");
+module_param(lowvsync, bool, 0);
+MODULE_PARM_DESC(lowvsync, "Force vertical sync low regardless of mode");
 
 MODULE_AUTHOR("Jim Hague <jim.hague@acm.org>");
 MODULE_DESCRIPTION("Permedia2 framebuffer device driver");
 MODULE_LICENSE("GPL");
+#endif
diff -Nru a/drivers/video/pmag-aa-fb.c b/drivers/video/pmag-aa-fb.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/video/pmag-aa-fb.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,514 @@
+/*
+ *	linux/drivers/video/pmag-aa-fb.c
+ *	Copyright 2002 Karsten Merker <merker@debian.org>
+ *
+ *	PMAG-AA TurboChannel framebuffer card support ... derived from
+ *	pmag-ba-fb.c, which is Copyright (C) 1999, 2000, 2001 by
+ *	Michael Engel <engel@unix-ag.org>, Karsten Merker <merker@debian.org>
+ *	and Harald Koerfgen <hkoerfg@web.de>, which itself is derived from
+ *	"HP300 Topcat framebuffer support (derived from macfb of all things)
+ *	Phil Blundell <philb@gnu.org> 1998"
+ *
+ *	This file 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.
+ *
+ *	2002-09-28  Karsten Merker <merker@linuxtag.org>
+ *		Version 0.01: First try to get a PMAG-AA running.
+ *
+ *	2003-02-24  Thiemo Seufer  <seufer@csv.ica.uni-stuttgart.de>
+ *		Version 0.02: Major code cleanup.
+ *
+ *	2003-09-21  Thiemo Seufer  <seufer@csv.ica.uni-stuttgart.de>
+ *		Hardware cursor support.
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/fb.h>
+#include <linux/console.h>
+
+#include <asm/bootinfo.h>
+#include <asm/dec/machtype.h>
+#include <asm/dec/tc.h>
+
+#include <video/fbcon.h>
+#include <video/fbcon-cfb8.h>
+
+#include "bt455.h"
+#include "bt431.h"
+
+/* Version information */
+#define DRIVER_VERSION "0.02"
+#define DRIVER_AUTHOR "Karsten Merker <merker@linuxtag.org>"
+#define DRIVER_DESCRIPTION "PMAG-AA Framebuffer Driver"
+
+/* Prototypes */
+static int aafb_set_var(struct fb_var_screeninfo *var, int con,
+			struct fb_info *info);
+
+/*
+ * Bt455 RAM DAC register base offset (rel. to TC slot base address).
+ */
+#define PMAG_AA_BT455_OFFSET		0x100000
+
+/*
+ * Bt431 cursor generator offset (rel. to TC slot base address).
+ */
+#define PMAG_AA_BT431_OFFSET		0x180000
+
+/*
+ * Begin of PMAG-AA framebuffer memory relative to TC slot address,
+ * resolution is 1280x1024x1 (8 bits deep, but only LSB is used).
+ */
+#define PMAG_AA_ONBOARD_FBMEM_OFFSET	0x200000
+
+struct aafb_cursor {
+	struct timer_list timer;
+	int enable;
+	int on;
+	int vbl_cnt;
+	int blink_rate;
+	u16 x, y, width, height;
+};
+
+#define CURSOR_TIMER_FREQ	(HZ / 50)
+#define CURSOR_BLINK_RATE	(20)
+#define CURSOR_DRAW_DELAY	(2)
+
+struct aafb_info {
+	struct fb_info info;
+	struct display disp;
+	struct aafb_cursor cursor;
+	struct bt455_regs *bt455;
+	struct bt431_regs *bt431;
+	unsigned long fb_start;
+	unsigned long fb_size;
+	unsigned long fb_line_length;
+};
+
+/*
+ * Max 3 TURBOchannel slots -> max 3 PMAG-AA.
+ */
+static struct aafb_info my_fb_info[3];
+
+static struct aafb_par {
+} current_par;
+
+static int currcon = -1;
+
+static void aafb_set_cursor(struct aafb_info *info, int on)
+{
+	struct aafb_cursor *c = &info->cursor;
+
+	if (on) {
+		bt431_position_cursor(info->bt431, c->x, c->y);
+		bt431_enable_cursor(info->bt431);
+	} else
+		bt431_erase_cursor(info->bt431);
+}
+
+static void aafbcon_cursor(struct display *disp, int mode, int x, int y)
+{
+	struct aafb_info *info = (struct aafb_info *)disp->fb_info;
+	struct aafb_cursor *c = &info->cursor;
+
+	x *= fontwidth(disp);
+	y *= fontheight(disp);
+
+	if (c->x == x && c->y == y && (mode == CM_ERASE) == !c->enable)
+		return;
+
+	c->enable = 0;
+	if (c->on)
+		aafb_set_cursor(info, 0);
+	c->x = x - disp->var.xoffset;
+	c->y = y - disp->var.yoffset;
+
+	switch (mode) {
+		case CM_ERASE:
+			c->on = 0;
+			break;
+		case CM_DRAW:
+		case CM_MOVE:
+			if (c->on)
+				aafb_set_cursor(info, c->on);
+			else
+				c->vbl_cnt = CURSOR_DRAW_DELAY;
+			c->enable = 1;
+			break;
+	}
+}
+
+static int aafbcon_set_font(struct display *disp, int width, int height)
+{
+	struct aafb_info *info = (struct aafb_info *)disp->fb_info;
+	struct aafb_cursor *c = &info->cursor;
+	u8 fgc = ~attr_bgcol_ec(disp, disp->conp);
+
+	if (width > 64 || height > 64 || width < 0 || height < 0)
+		return -EINVAL;
+
+	c->height = height;
+	c->width = width;
+
+	bt431_set_font(info->bt431, fgc, width, height);
+
+	return 1;
+}
+
+static void aafb_cursor_timer_handler(unsigned long data)
+{
+	struct aafb_info *info = (struct aafb_info *)data;
+	struct aafb_cursor *c = &info->cursor;
+
+	if (!c->enable)
+		goto out;
+
+	if (c->vbl_cnt && --c->vbl_cnt == 0) {
+		c->on ^= 1;
+		aafb_set_cursor(info, c->on);
+		c->vbl_cnt = c->blink_rate;
+	}
+
+out:
+	c->timer.expires = jiffies + CURSOR_TIMER_FREQ;
+	add_timer(&c->timer);
+}
+
+static void __init aafb_cursor_init(struct aafb_info *info)
+{
+	struct aafb_cursor *c = &info->cursor;
+
+	c->enable = 1;
+	c->on = 1;
+	c->x = c->y = 0;
+	c->width = c->height = 0;
+	c->vbl_cnt = CURSOR_DRAW_DELAY;
+	c->blink_rate = CURSOR_BLINK_RATE;
+
+	init_timer(&c->timer);
+	c->timer.data = (unsigned long)info;
+	c->timer.function = aafb_cursor_timer_handler;
+	mod_timer(&c->timer, jiffies + CURSOR_TIMER_FREQ);
+}
+
+static void __exit aafb_cursor_exit(struct aafb_info *info)
+{
+	struct aafb_cursor *c = &info->cursor;
+
+	del_timer_sync(&c->timer);
+}
+
+static struct display_switch aafb_switch8 = {
+	.setup = fbcon_cfb8_setup,
+	.bmove = fbcon_cfb8_bmove,
+	.clear = fbcon_cfb8_clear,
+	.putc = fbcon_cfb8_putc,
+	.putcs = fbcon_cfb8_putcs,
+	.revc = fbcon_cfb8_revc,
+	.cursor = aafbcon_cursor,
+	.set_font = aafbcon_set_font,
+	.clear_margins = fbcon_cfb8_clear_margins,
+	.fontwidthmask = FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
+};
+
+static void aafb_get_par(struct aafb_par *par)
+{
+	*par = current_par;
+}
+
+static int aafb_get_fix(struct fb_fix_screeninfo *fix, int con,
+			struct fb_info *info)
+{
+	struct aafb_info *ip = (struct aafb_info *)info;
+
+	memset(fix, 0, sizeof(struct fb_fix_screeninfo));
+	strcpy(fix->id, "PMAG-AA");
+	fix->smem_start = ip->fb_start;
+	fix->smem_len = ip->fb_size;
+	fix->type = FB_TYPE_PACKED_PIXELS;
+	fix->ypanstep = 1;
+	fix->ywrapstep = 1;
+	fix->visual = FB_VISUAL_MONO10;
+	fix->line_length = 1280;
+	fix->accel = FB_ACCEL_NONE;
+
+	return 0;
+}
+
+static void aafb_set_disp(struct display *disp, int con,
+			  struct aafb_info *info)
+{
+	struct fb_fix_screeninfo fix;
+
+	disp->fb_info = &info->info;
+	aafb_set_var(&disp->var, con, &info->info);
+	if (disp->conp && disp->conp->vc_sw && disp->conp->vc_sw->con_cursor)
+		disp->conp->vc_sw->con_cursor(disp->conp, CM_ERASE);
+	disp->dispsw = &aafb_switch8;
+	disp->dispsw_data = 0;
+
+	aafb_get_fix(&fix, con, &info->info);
+	disp->screen_base = (u8 *) fix.smem_start;
+	disp->visual = fix.visual;
+	disp->type = fix.type;
+	disp->type_aux = fix.type_aux;
+	disp->ypanstep = fix.ypanstep;
+	disp->ywrapstep = fix.ywrapstep;
+	disp->line_length = fix.line_length;
+	disp->next_line = 2048;
+	disp->can_soft_blank = 1;
+	disp->inverse = 0;
+	disp->scrollmode = SCROLL_YREDRAW;
+
+	aafbcon_set_font(disp, fontwidth(disp), fontheight(disp));
+}
+
+static int aafb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+			 struct fb_info *info)
+{
+	static u16 color[2] = {0x0000, 0x000f};
+	static struct fb_cmap aafb_cmap = {0, 2, color, color, color, NULL};
+
+	fb_copy_cmap(&aafb_cmap, cmap, kspc ? 0 : 2);
+	return 0;
+}
+
+static int aafb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+			 struct fb_info *info)
+{
+	u16 color[2] = {0x0000, 0x000f};
+
+	if (cmap->start == 0
+	    && cmap->len == 2
+	    && memcmp(cmap->red, color, sizeof(color)) == 0
+	    && memcmp(cmap->green, color, sizeof(color)) == 0
+	    && memcmp(cmap->blue, color, sizeof(color)) == 0
+	    && cmap->transp == NULL)
+		return 0;
+	else
+		return -EINVAL;
+}
+
+static int aafb_ioctl(struct inode *inode, struct file *file, u32 cmd,
+		      unsigned long arg, int con, struct fb_info *info)
+{
+	/* TODO: Not yet implemented */
+	return -ENOIOCTLCMD;
+}
+
+static int aafb_switch(int con, struct fb_info *info)
+{
+	struct aafb_info *ip = (struct aafb_info *)info;
+	struct display *old = (currcon < 0) ? &ip->disp : (fb_display + currcon);
+	struct display *new = (con < 0) ? &ip->disp : (fb_display + con);
+
+	if (old->conp && old->conp->vc_sw && old->conp->vc_sw->con_cursor)
+		old->conp->vc_sw->con_cursor(old->conp, CM_ERASE);
+
+	/* Set the current console. */
+	currcon = con;
+	aafb_set_disp(new, con, ip);
+
+	return 0;
+}
+
+static void aafb_encode_var(struct fb_var_screeninfo *var,
+			    struct aafb_par *par)
+{
+	var->xres = 1280;
+	var->yres = 1024;
+	var->xres_virtual = 2048;
+	var->yres_virtual = 1024;
+	var->xoffset = 0;
+	var->yoffset = 0;
+	var->bits_per_pixel = 8;
+	var->grayscale = 1;
+	var->red.offset = 0;
+	var->red.length = 0;
+	var->red.msb_right = 0;
+	var->green.offset = 0;
+	var->green.length = 1;
+	var->green.msb_right = 0;
+	var->blue.offset = 0;
+	var->blue.length = 0;
+	var->blue.msb_right = 0;
+	var->transp.offset = 0;
+	var->transp.length = 0;
+	var->transp.msb_right = 0;
+	var->nonstd = 0;
+	var->activate &= ~FB_ACTIVATE_MASK & FB_ACTIVATE_NOW;
+	var->accel_flags = 0;
+	var->sync = FB_SYNC_ON_GREEN;
+	var->vmode &= ~FB_VMODE_MASK & FB_VMODE_NONINTERLACED;
+}
+
+static int aafb_get_var(struct fb_var_screeninfo *var, int con,
+			struct fb_info *info)
+{
+	if (con < 0) {
+		struct aafb_par par;
+
+		memset(var, 0, sizeof(struct fb_var_screeninfo));
+		aafb_get_par(&par);
+		aafb_encode_var(var, &par);
+	} else
+		*var = info->var;
+
+	return 0;
+}
+
+static int aafb_set_var(struct fb_var_screeninfo *var, int con,
+			struct fb_info *info)
+{
+	struct aafb_par par;
+
+	aafb_get_par(&par);
+	aafb_encode_var(var, &par);
+	info->var = *var;
+
+	return 0;
+}
+
+static int aafb_update_var(int con, struct fb_info *info)
+{
+	struct aafb_info *ip = (struct aafb_info *)info;
+	struct display *disp = (con < 0) ? &ip->disp : (fb_display + con);
+
+	if (con == currcon)
+		aafbcon_cursor(disp, CM_ERASE, ip->cursor.x, ip->cursor.y);
+
+	return 0;
+}
+
+/* 0 unblanks, any other blanks. */
+
+static void aafb_blank(int blank, struct fb_info *info)
+{
+	struct aafb_info *ip = (struct aafb_info *)info;
+	u8 val = blank ? 0x00 : 0x0f;
+
+	bt455_write_cmap_entry(ip->bt455, 1, val, val, val);
+	aafbcon_cursor(&ip->disp, CM_ERASE, ip->cursor.x, ip->cursor.y);
+}
+
+static struct fb_ops aafb_ops = {
+	.owner = THIS_MODULE,
+	.fb_get_fix = aafb_get_fix,
+	.fb_get_var = aafb_get_var,
+	.fb_set_var = aafb_set_var,
+	.fb_get_cmap = aafb_get_cmap,
+	.fb_set_cmap = aafb_set_cmap,
+	.fb_ioctl = aafb_ioctl
+};
+
+static int __init init_one(int slot)
+{
+	unsigned long base_addr = get_tc_base_addr(slot);
+	struct aafb_info *ip = &my_fb_info[slot];
+
+	memset(ip, 0, sizeof(struct aafb_info));
+
+	/*
+	 * Framebuffer display memory base address and friends.
+	 */
+	ip->bt455 = (struct bt455_regs *) (base_addr + PMAG_AA_BT455_OFFSET);
+	ip->bt431 = (struct bt431_regs *) (base_addr + PMAG_AA_BT431_OFFSET);
+	ip->fb_start = base_addr + PMAG_AA_ONBOARD_FBMEM_OFFSET;
+	ip->fb_size = 2048 * 1024; /* fb_fix_screeninfo.smem_length
+				      seems to be physical */
+	ip->fb_line_length = 2048;
+
+	/*
+	 * Let there be consoles..
+	 */
+	strcpy(ip->info.modename, "PMAG-AA");
+	ip->info.node = -1;
+	ip->info.flags = FBINFO_FLAG_DEFAULT;
+	ip->info.fbops = &aafb_ops;
+	ip->info.disp = &ip->disp;
+	ip->info.changevar = NULL;
+	ip->info.switch_con = &aafb_switch;
+	ip->info.updatevar = &aafb_update_var;
+	ip->info.blank = &aafb_blank;
+
+	aafb_set_disp(&ip->disp, currcon, ip);
+
+	/*
+	 * Configure the RAM DACs.
+	 */
+	bt455_erase_cursor(ip->bt455);
+
+	/* Init colormap. */
+	bt455_write_cmap_entry(ip->bt455, 0, 0x00, 0x00, 0x00);
+	bt455_write_cmap_entry(ip->bt455, 1, 0x0f, 0x0f, 0x0f);
+
+	/* Init hardware cursor. */
+	bt431_init_cursor(ip->bt431);
+	aafb_cursor_init(ip);
+
+	/* Clear the screen. */
+	memset ((void *)ip->fb_start, 0, ip->fb_size);
+
+	if (register_framebuffer(&ip->info) < 0)
+		return -EINVAL;
+
+	printk(KERN_INFO "fb%d: %s frame buffer in TC slot %d\n",
+	       GET_FB_IDX(ip->info.node), ip->info.modename, slot);
+
+	return 0;
+}
+
+static int __exit exit_one(int slot)
+{
+	struct aafb_info *ip = &my_fb_info[slot];
+
+	if (unregister_framebuffer(&ip->info) < 0)
+		return -EINVAL;
+
+	return 0;
+}
+
+/*
+ * Initialise the framebuffer.
+ */
+int __init pmagaafb_init(void)
+{
+	int sid;
+	int found = 0;
+
+	while ((sid = search_tc_card("PMAG-AA")) >= 0) {
+		found = 1;
+		claim_tc_card(sid);
+		init_one(sid);
+	}
+
+	return found ? 0 : -ENXIO;
+}
+
+static void __exit pmagaafb_exit(void)
+{
+	int sid;
+
+	while ((sid = search_tc_card("PMAG-AA")) >= 0) {
+		exit_one(sid);
+		release_tc_card(sid);
+	}
+}
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESCRIPTION);
+MODULE_LICENSE("GPL");
+#ifdef MODULE
+module_init(pmagaafb_init);
+module_exit(pmagaafb_exit);
+#endif
diff -Nru a/drivers/video/pmag-ba-fb.c b/drivers/video/pmag-ba-fb.c
--- a/drivers/video/pmag-ba-fb.c	2005-03-01 23:39:16 -08:00
+++ b/drivers/video/pmag-ba-fb.c	2005-03-01 23:39:16 -08:00
@@ -52,27 +52,27 @@
 static struct fb_info pmagba_fb_info[3];
 
 static struct fb_var_screeninfo pmagbafb_defined = {
-	.xres 		= 1024,
+	.xres		= 1024,
 	.yres		= 864,
-	.xres_virtual 	= 1024,
-	.yres_virtual 	= 864,
-	.bits_per_pixel = 8,
+	.xres_virtual	= 1024,
+	.yres_virtual	= 864,
+	.bits_per_pixel	= 8,
 	.red.length	= 8,
 	.green.length	= 8,
 	.blue.length	= 8,
-	.activate 	= FB_ACTIVATE_NOW, 
-	.height 	= 274,	
-	.width 		= 195,
-	.accel 		= FB_ACCEL_NONE,
-	.vmode 		= FB_VMODE_NONINTERLACED,
+	.activate	= FB_ACTIVATE_NOW,
+	.height		= 274,
+	.width		= 195,
+	.accel		= FB_ACCEL_NONE,
+	.vmode		= FB_VMODE_NONINTERLACED,
 };
 
 static struct fb_fix_screeninfo pmagbafb_fix = {
-	.id 		= "PMAG-BA",
-	.smem_len 	= (1024 * 864),
-	.type 		= FB_TYPE_PACKED_PIXELS,
-	.visual 	= FB_VISUAL_PSEUDOCOLOR,
-	.line_length 	= 1024,
+	.id		= "PMAG-BA",
+	.smem_len	= (1024 * 864),
+	.type		= FB_TYPE_PACKED_PIXELS,
+	.visual		= FB_VISUAL_PSEUDOCOLOR,
+	.line_length	= 1024,
 };
 
 /*
@@ -89,10 +89,10 @@
  * Set the palette. 
  */
 static int pmagbafb_setcolreg(unsigned regno, unsigned red, unsigned green,
-                              unsigned blue, unsigned transp,
-                              struct fb_info *info)
+			      unsigned blue, unsigned transp,
+			      struct fb_info *info)
 {
-	struct pmag_ba_ramdac_regs *bt459_regs = (struct pmag_ba_ramdac_regs *) info->par; 
+	struct pmag_ba_ramdac_regs *bt459_regs = (struct pmag_ba_ramdac_regs *) info->par;
 
 	if (regno >= info->cmap.len)
 		return 1;
@@ -111,6 +111,8 @@
 
 static struct fb_ops pmagbafb_ops = {
 	.owner		= THIS_MODULE,
+	.fb_get_fix	= gen_get_fix,
+	.fb_get_var	= gen_get_var,
 	.fb_setcolreg	= pmagbafb_setcolreg,
 	.fb_fillrect	= cfb_fillrect,
 	.fb_copyarea	= cfb_copyarea,
@@ -122,6 +124,7 @@
 {
 	unsigned long base_addr = get_tc_base_addr(slot);
 	struct fb_info *info = &pmagba_fb_info[slot]; 
+	struct display *disp = &pmagba_disp[slot];
 
 	printk("PMAG-BA framebuffer in slot %d\n", slot);
 	/*
@@ -145,7 +148,7 @@
 	info->flags = FBINFO_DEFAULT;
 
 	fb_alloc_cmap(&fb_info.cmap, 256, 0);
-	
+
 	if (register_framebuffer(info) < 0)
 		return 1;
 	return 0;
diff -Nru a/drivers/video/pmagb-b-fb.c b/drivers/video/pmagb-b-fb.c
--- a/drivers/video/pmagb-b-fb.c	2005-03-01 23:38:58 -08:00
+++ b/drivers/video/pmagb-b-fb.c	2005-03-01 23:38:58 -08:00
@@ -55,27 +55,27 @@
 static struct fb_info pmagbb_fb_info[3];
 
 static struct fb_var_screeninfo pmagbbfb_defined = {
-	.xres 		= 1280,
-	.yres 		= 1024,
-	.xres_virtual 	= 1280,
-	.yres_virtual 	= 1024,
-	.bits_per_pixel = 8,
+	.xres		= 1280,
+	.yres		= 1024,
+	.xres_virtual	= 1280,
+	.yres_virtual	= 1024,
+	.bits_per_pixel	= 8,
 	.red.length	= 8,
 	.green.length	= 8,
 	.blue.length	= 8,
-	.activate 	= FB_ACTIVATE_NOW,
-	.height 	= 274,
-	.width 		= 195,
-	.accel_flags 	= FB_ACCEL_NONE,
-	.vmode 		= FB_VMODE_NONINTERLACED,
+	.activate	= FB_ACTIVATE_NOW,
+	.height		= 274,
+	.width		= 195,
+	.accel_flags	= FB_ACCEL_NONE,
+	.vmode		= FB_VMODE_NONINTERLACED,
 };
 
 static struct fb_fix_screeninfo pmagbafb_fix = {
-	.id 		= "PMAGB-BA",
-	.smem_len 	= (1280 * 1024),
-	.type 		= FB_TYPE_PACKED_PIXELS,
-	.visual 	= FB_VISUAL_PSEUDOCOLOR,
-	.line_length 	= 1280,
+	.id		= "PMAGB-BA",
+	.smem_len	= (1280 * 1024),
+	.type		= FB_TYPE_PACKED_PIXELS,
+	.visual		= FB_VISUAL_PSEUDOCOLOR,
+	.line_length	= 1280,
 }
 
 /*
diff -Nru a/drivers/video/pxafb.c b/drivers/video/pxafb.c
--- a/drivers/video/pxafb.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/video/pxafb.c	2005-03-01 23:38:55 -08:00
@@ -394,6 +394,20 @@
 	return 0;
 }
 
+static int pxafb_mmap(struct fb_info *info, struct file *file,
+		      struct vm_area_struct *vma)
+{
+	struct pxafb_info *fbi = (struct pxafb_info *)info;
+	unsigned long off = vma->vm_pgoff << PAGE_SHIFT;
+
+	if (off < info->fix.smem_len) {
+		vma->vm_pgoff += 1;
+		return dma_mmap_writecombine(fbi->dev, vma, fbi->map_cpu,
+					     fbi->map_dma, fbi->map_size);
+	}
+	return -EINVAL;
+}
+
 static struct fb_ops pxafb_ops = {
 	.owner		= THIS_MODULE,
 	.fb_check_var	= pxafb_check_var,
@@ -404,6 +418,7 @@
 	.fb_imageblit	= cfb_imageblit,
 	.fb_blank	= pxafb_blank,
 	.fb_cursor	= soft_cursor,
+	.fb_mmap	= pxafb_mmap,
 };
 
 /*
@@ -725,8 +740,8 @@
 
 	DPRINTK("Disabling LCD controller\n");
 
-	add_wait_queue(&fbi->ctrlr_wait, &wait);
 	set_current_state(TASK_UNINTERRUPTIBLE);
+	add_wait_queue(&fbi->ctrlr_wait, &wait);
 
 	LCSR = 0xffffffff;	/* Clear LCD Status Register */
 	LCCR0 &= ~LCCR0_LDM;	/* Enable LCD Disable Done Interrupt */
diff -Nru a/drivers/video/radeonfb.c b/drivers/video/radeonfb.c
--- a/drivers/video/radeonfb.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/video/radeonfb.c	2005-03-01 23:39:17 -08:00
@@ -621,30 +621,6 @@
 #define radeon_engine_reset()		_radeon_engine_reset(rinfo)
 
 
-static __inline__ u8 radeon_get_post_div_bitval(int post_div)
-{
-        switch (post_div) {
-                case 1:
-                        return 0x00;
-                case 2: 
-                        return 0x01;
-                case 3: 
-                        return 0x04;
-                case 4:
-                        return 0x02;
-                case 6:
-                        return 0x06;
-                case 8:
-                        return 0x03;
-                case 12:
-                        return 0x07;
-                default:
-                        return 0x02;
-        }
-}
-
-
-
 static __inline__ int round_div(int num, int den)
 {
         return (num + (den / 2)) / den;
@@ -838,7 +814,7 @@
 		if (radeon_read_OF(rinfo)) {
 			unsigned int tmp, Nx, M, ref_div, xclk;
 
-			tmp = INPLL(X_MPLL_REF_FB_DIV);
+			tmp = INPLL(M_SPLL_REF_FB_DIV);
 			ref_div = INPLL(PPLL_REF_DIV) & 0x3ff;
 
 			Nx = (tmp & 0xff00) >> 8;
diff -Nru a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c
--- a/drivers/video/riva/fbdev.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/video/riva/fbdev.c	2005-03-01 23:39:08 -08:00
@@ -152,6 +152,9 @@
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
 	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_440,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+	// NF2/IGP version, GeForce 4 MX, NV18
+	{ PCI_VENDOR_ID_NVIDIA, 0x01f0,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
 	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_420,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
 	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_440_GO,
@@ -1769,17 +1772,19 @@
 static int __devinit riva_get_EDID_i2c(struct fb_info *info)
 {
 	struct riva_par *par = (struct riva_par *) info->par;
+	struct fb_var_screeninfo var;
 	int i;
 
 	NVTRACE_ENTER();
 	riva_create_i2c_busses(par);
-	for (i = par->bus; i >= 1; i--) {
-		riva_probe_i2c_connector(par, i, &par->EDID);
-		if (par->EDID) {
+	for (i = 0; i < par->bus; i++) {
+		riva_probe_i2c_connector(par, i+1, &par->EDID);
+		if (par->EDID && !fb_parse_edid(par->EDID, &var)) {
 			printk(PFX "Found EDID Block from BUS %i\n", i);
 			break;
 		}
 	}
+
 	NVTRACE_LEAVE();
 	return (par->EDID) ? 1 : 0;
 }
diff -Nru a/drivers/video/riva/rivafb-i2c.c b/drivers/video/riva/rivafb-i2c.c
--- a/drivers/video/riva/rivafb-i2c.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/video/riva/rivafb-i2c.c	2005-03-01 23:38:57 -08:00
@@ -19,6 +19,7 @@
 #include <linux/delay.h>
 #include <linux/pci.h>
 #include <linux/fb.h>
+#include <linux/jiffies.h>
 
 #include <asm/io.h>
 
@@ -106,8 +107,7 @@
 	chan->algo.getsda		= riva_gpio_getsda;
 	chan->algo.getscl		= riva_gpio_getscl;
 	chan->algo.udelay		= 40;
-	chan->algo.mdelay               = 5;
-	chan->algo.timeout		= 20;
+	chan->algo.timeout		= msecs_to_jiffies(2);
 	chan->algo.data 		= chan;
 
 	i2c_set_adapdata(&chan->adapter, chan);
@@ -127,39 +127,18 @@
 
 void riva_create_i2c_busses(struct riva_par *par)
 {
+	par->bus = 3;
+
 	par->chan[0].par	= par;
 	par->chan[1].par	= par;
 	par->chan[2].par        = par;
 
-	par->bus = 0;
-
-	switch ((par->pdev->device >> 4) & 0xff) {
-	case 0x17:
-	case 0x18:
-	case 0x25:
-	case 0x28:
-	case 0x30:
-	case 0x31:
-	case 0x32:
-	case 0x33:
-	case 0x34:
-		par->chan[2].ddc_base   = 0x50;
-		par->bus++;
-		riva_setup_i2c_bus(&par->chan[2], "BUS3");
-	case 0x04:
-	case 0x05:
-	case 0x10:
-	case 0x11:
-	case 0x15:
-	case 0x20:
-		par->chan[1].ddc_base	= 0x36;
-		par->bus++;
-		riva_setup_i2c_bus(&par->chan[1], "BUS2");
-	case 0x03:
-		par->chan[0].ddc_base	= 0x3e;
-		par->bus++;
-		riva_setup_i2c_bus(&par->chan[0], "BUS1");
-	}
+	par->chan[0].ddc_base = 0x3e;
+	par->chan[1].ddc_base = 0x36;
+	par->chan[2].ddc_base = 0x50;
+	riva_setup_i2c_bus(&par->chan[0], "BUS1");
+	riva_setup_i2c_bus(&par->chan[1], "BUS2");
+	riva_setup_i2c_bus(&par->chan[2], "BUS3");
 }
 
 void riva_delete_i2c_busses(struct riva_par *par)
@@ -172,6 +151,9 @@
 		i2c_bit_del_bus(&par->chan[1].adapter);
 	par->chan[1].par = NULL;
 
+	if (par->chan[2].par)
+		i2c_bit_del_bus(&par->chan[2].adapter);
+	par->chan[2].par = NULL;
 }
 
 static u8 *riva_do_probe_i2c_edid(struct riva_i2c_chan *chan)
diff -Nru a/drivers/video/sa1100fb.c b/drivers/video/sa1100fb.c
--- a/drivers/video/sa1100fb.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/video/sa1100fb.c	2005-03-01 23:38:54 -08:00
@@ -393,7 +393,7 @@
 	.left_margin	= 2,		.upper_margin	= 0,
 	.right_margin	= 1,		.lower_margin	= 0,
 
-	.sync		= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 
+	.sync		= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
 
 	.lccr0		= LCCR0_Color | LCCR0_Dual | LCCR0_Pas,
 	.lccr3		= LCCR3_ACBsDiv(512),
@@ -814,6 +814,33 @@
 	return 0;
 }
 
+static int sa1100fb_mmap(struct fb_info *info, struct file *file,
+			 struct vm_area_struct *vma)
+{
+	struct sa1100fb_info *fbi = (struct sa1100fb_info *)info;
+	unsigned long start, len, off = vma->vm_pgoff << PAGE_SHIFT;
+
+	if (off < info->fix.smem_len) {
+		vma->vm_pgoff += 1; /* skip over the palette */
+		return dma_mmap_writecombine(fbi->dev, vma, fbi->map_cpu,
+					     fbi->map_dma, fbi->map_size);
+	}
+
+	start = info->fix.mmio_start;
+	len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.mmio_len);
+
+	if ((vma->vm_end - vma->vm_start + off) > len)
+		return -EINVAL;
+
+	off += start & PAGE_MASK;
+	vma->vm_pgoff = off >> PAGE_SHIFT;
+	vma->vm_flags |= VM_IO;
+	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+	return io_remap_page_range(vma, vma->vm_start, off,
+				   vma->vm_end - vma->vm_start,
+				   vma->vm_page_prot);
+}
+
 static struct fb_ops sa1100fb_ops = {
 	.owner		= THIS_MODULE,
 	.fb_check_var	= sa1100fb_check_var,
@@ -825,6 +852,7 @@
 	.fb_imageblit	= cfb_imageblit,
 	.fb_blank	= sa1100fb_blank,
 	.fb_cursor	= soft_cursor,
+	.fb_mmap	= sa1100fb_mmap,
 };
 
 /*
@@ -1024,7 +1052,7 @@
 	if (machine_is_shannon()) {
 		GPDR |= SHANNON_GPIO_DISP_EN;
 		GPSR |= SHANNON_GPIO_DISP_EN;
-	}	
+	}
 
 	DPRINTK("DBAR1 = 0x%08x\n", DBAR1);
 	DPRINTK("DBAR2 = 0x%08x\n", DBAR2);
@@ -1044,8 +1072,8 @@
 		GPCR |= SHANNON_GPIO_DISP_EN;
 	}	
 
-	add_wait_queue(&fbi->ctrlr_wait, &wait);
 	set_current_state(TASK_UNINTERRUPTIBLE);
+	add_wait_queue(&fbi->ctrlr_wait, &wait);
 
 	LCSR = 0xffffffff;	/* Clear LCD Status Register */
 	LCCR0 &= ~LCCR0_LDM;	/* Enable LCD Disable Done Interrupt */
diff -Nru a/drivers/video/savage/savagefb-i2c.c b/drivers/video/savage/savagefb-i2c.c
--- a/drivers/video/savage/savagefb-i2c.c	2005-03-01 23:39:08 -08:00
+++ b/drivers/video/savage/savagefb-i2c.c	2005-03-01 23:39:08 -08:00
@@ -163,12 +163,15 @@
 		udelay(20);
 
 		rc = add_bus(&chan->adapter);
+
 		if (rc == 0)
 			dev_dbg(&chan->par->pcidev->dev,
 				"I2C bus %s registered.\n", name);
 		else
 			dev_warn(&chan->par->pcidev->dev,
 				 "Failed to register I2C bus %s.\n", name);
+
+		symbol_put(i2c_bit_add_bus);
 	} else
 		chan->par = NULL;
 
@@ -212,8 +215,10 @@
 	int (*del_bus)(struct i2c_adapter *) =
 		symbol_get(i2c_bit_del_bus);
 
-	if (del_bus && par->chan.par)
+	if (del_bus && par->chan.par) {
 		del_bus(&par->chan.adapter);
+		symbol_put(i2c_bit_del_bus);
+	}
 
 	par->chan.par = NULL;
 }
@@ -239,6 +244,7 @@
 
 	if (transfer && chan->par) {
 		buf = kmalloc(EDID_LENGTH, GFP_KERNEL);
+
 		if (buf) {
 			msgs[1].buf = buf;
 
@@ -249,6 +255,8 @@
 				buf = NULL;
 			}
 		}
+
+		symbol_put(i2c_transfer);
 	}
 
 	return buf;
diff -Nru a/drivers/video/sbuslib.c b/drivers/video/sbuslib.c
--- a/drivers/video/sbuslib.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/video/sbuslib.c	2005-03-01 23:38:54 -08:00
@@ -108,6 +108,7 @@
 		struct fbcmap __user *c = (struct fbcmap __user *) arg;
 		struct fb_cmap cmap;
 		u16 red, green, blue;
+		u8 red8, green8, blue8;
 		unsigned char __user *ured;
 		unsigned char __user *ugreen;
 		unsigned char __user *ublue;
@@ -128,11 +129,15 @@
 		for (i = 0; i < count; i++) {
 			int err;
 
-			if (get_user(red, &ured[i]) ||
-			    get_user(green, &ugreen[i]) ||
-			    get_user(blue, &ublue[i]))
+			if (get_user(red8, &ured[i]) ||
+			    get_user(green8, &ugreen[i]) ||
+			    get_user(blue8, &ublue[i]))
 				return -EFAULT;
 
+			red = red8 << 8;
+			green = green8 << 8;
+			blue = blue8 << 8;
+
 			cmap.start = index + i;
 			err = fb_set_cmap(&cmap, info);
 			if (err)
@@ -147,6 +152,7 @@
 		unsigned char __user *ublue;
 		struct fb_cmap *cmap = &info->cmap;
 		int index, count, i;
+		u8 red, green, blue;
 
 		if (get_user(index, &c->index) ||
 		    __get_user(count, &c->count) ||
@@ -159,9 +165,12 @@
 			return -EINVAL;
 
 		for (i = 0; i < count; i++) {
-			if (put_user(cmap->red[index + i], &ured[i]) ||
-			    put_user(cmap->green[index + i], &ugreen[i]) ||
-			    put_user(cmap->blue[index + i], &ublue[i]))
+			red = cmap->red[index + i] >> 8;
+			green = cmap->green[index + i] >> 8;
+			blue = cmap->blue[index + i] >> 8;
+			if (put_user(red, &ured[i]) ||
+			    put_user(green, &ugreen[i]) ||
+			    put_user(blue, &ublue[i]))
 				return -EFAULT;
 		}
 		return 0;
diff -Nru a/drivers/video/sis/300vtbl.h b/drivers/video/sis/300vtbl.h
--- a/drivers/video/sis/300vtbl.h	2005-03-01 23:38:53 -08:00
+++ b/drivers/video/sis/300vtbl.h	2005-03-01 23:38:53 -08:00
@@ -35,7 +35,7 @@
  * * 3) The name of the author may not be used to endorse or promote products
  * *    derived from this software without specific prior written permission.
  * *
- * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR
+ * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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,
@@ -80,12 +80,12 @@
 	{0x2e,0x0a1b,0x0101,SIS_RI_640x480,  0x00,0x00,0x00,0x00,0x08,-1},
 	{0x2f,0x021b,0x0100,SIS_RI_640x400,  0x00,0x00,0x00,0x00,0x10,-1},  /* 640x400x8 */
 	{0x30,0x2a1b,0x0103,SIS_RI_800x600,  0x00,0x00,0x00,0x00,0x00,-1},
-	{0x31,0x0a1b,0x0000,SIS_RI_720x480,  0x00,0x00,0x00,0x00,0x11,-1},  /* 720x480x8 */
-	{0x32,0x2a1b,0x0000,SIS_RI_720x576,  0x00,0x00,0x00,0x00,0x12,-1},  /* 720x576x8 */
-	{0x33,0x0a1d,0x0000,SIS_RI_720x480,  0x00,0x00,0x00,0x00,0x11,-1},  /* 720x480x16 */
-	{0x34,0x2a1d,0x0000,SIS_RI_720x576,  0x00,0x00,0x00,0x00,0x12,-1},  /* 720x576x16 */
-	{0x35,0x0a1f,0x0000,SIS_RI_720x480,  0x00,0x00,0x00,0x00,0x11,-1},  /* 720x480x32 */
-	{0x36,0x2a1f,0x0000,SIS_RI_720x576,  0x00,0x00,0x00,0x00,0x12,-1},  /* 720x576x32 */
+	{0x31,0x4a1b,0x0000,SIS_RI_720x480,  0x00,0x00,0x00,0x00,0x11,-1},  /* 720x480x8 */
+	{0x32,0x6a1b,0x0000,SIS_RI_720x576,  0x00,0x00,0x00,0x00,0x12,-1},  /* 720x576x8 */
+	{0x33,0x4a1d,0x0000,SIS_RI_720x480,  0x00,0x00,0x00,0x00,0x11,-1},  /* 720x480x16 */
+	{0x34,0x6a1d,0x0000,SIS_RI_720x576,  0x00,0x00,0x00,0x00,0x12,-1},  /* 720x576x16 */
+	{0x35,0x4a1f,0x0000,SIS_RI_720x480,  0x00,0x00,0x00,0x00,0x11,-1},  /* 720x480x32 */
+	{0x36,0x6a1f,0x0000,SIS_RI_720x576,  0x00,0x00,0x00,0x00,0x12,-1},  /* 720x576x32 */
 	{0x37,0x0212,0x0104,SIS_RI_1024x768, 0x00,0x00,0x00,0x00,0x13,-1},  /* 1024x768x? */
 	{0x38,0x0a1b,0x0105,SIS_RI_1024x768, 0x00,0x00,0x00,0x00,0x13,-1},  /* 1024x768x8 */
 	{0x3a,0x0e3b,0x0107,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x1a,-1},  /* 1280x1024x8 */
@@ -121,48 +121,48 @@
 	{0x6b,0x07ff,0x0000,SIS_RI_1920x1440,0x00,0x00,0x00,0x00,0x27,-1},
 	{0x6c,0x067b,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x00,0x28,-1},  /* 2048x1536x8 - not in BIOS! */
 	{0x6d,0x06fd,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x00,0x28,-1},  /* 2048x1536x16 - not in BIOS! */
-	{0x70,0x2a1b,0x0000,SIS_RI_800x480,  0x00,0x00,0x07,0x00,0x2d,-1},  /* 800x480x8 */
-	{0x71,0x0a1b,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x30,-1},  /* 1024x576x8 */
-	{0x74,0x0a1d,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x30,-1},  /* 1024x576x16 */
+	{0x70,0x6a1b,0x0000,SIS_RI_800x480,  0x00,0x00,0x07,0x00,0x2d,-1},  /* 800x480x8 */
+	{0x71,0x4a1b,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x30,-1},  /* 1024x576x8 */
+	{0x74,0x4a1d,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x30,-1},  /* 1024x576x16 */
 	{0x75,0x0e3d,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x00,0x33,-1},  /* 1280x720x16 */
-	{0x76,0x2a1f,0x0000,SIS_RI_800x480,  0x00,0x00,0x07,0x00,0x2d,-1},  /* 800x480x32 */
-	{0x77,0x0a3f,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x30,-1},  /* 1024x576x32 */
+	{0x76,0x6a1f,0x0000,SIS_RI_800x480,  0x00,0x00,0x07,0x00,0x2d,-1},  /* 800x480x32 */
+	{0x77,0x4a3f,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x30,-1},  /* 1024x576x32 */
 	{0x78,0x0eff,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x00,0x33,-1},  /* 1280x720x32 */
 	{0x79,0x0e3b,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x00,0x33,-1},  /* 1280x720x8 */
-	{0x7a,0x2a1d,0x0000,SIS_RI_800x480,  0x00,0x00,0x07,0x00,0x2d,-1},  /* 800x480x16 */
+	{0x7a,0x6a1d,0x0000,SIS_RI_800x480,  0x00,0x00,0x07,0x00,0x2d,-1},  /* 800x480x16 */
 	{0x7c,0x0a3b,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x00,0x29,-1},  /* 1280x960x8 */
 	{0x7d,0x0a7d,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x00,0x29,-1},  /* 1280x960x16 */
 	{0x7e,0x0aff,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x00,0x29,-1},  /* 1280x960x32 */
-	{0x20,0x0a1b,0x0000,SIS_RI_1024x600, 0x00,0x00,0x00,0x00,0x2b,-1},  /* 1024x600 */
-	{0x21,0x0a3d,0x0000,SIS_RI_1024x600, 0x00,0x00,0x00,0x00,0x2b,-1},
-	{0x22,0x0a7f,0x0000,SIS_RI_1024x600, 0x00,0x00,0x00,0x00,0x2b,-1},
-	{0x23,0x0a1b,0x0000,SIS_RI_1152x768, 0x00,0x00,0x00,0x00,0x2c,-1},  /* 1152x768 */
-	{0x24,0x0a3d,0x0000,SIS_RI_1152x768, 0x00,0x00,0x00,0x00,0x2c,-1},
-	{0x25,0x0a7f,0x0000,SIS_RI_1152x768, 0x00,0x00,0x00,0x00,0x2c,-1},
-	{0x29,0x0e1b,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x36,-1},  /* 1152x864 */
-	{0x2a,0x0e3d,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x36,-1},
-	{0x2b,0x0e7f,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x36,-1},
-	{0x39,0x2a1b,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x00,0x38,-1},  /* 848x480 */
-	{0x3b,0x2a3d,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x00,0x38,-1},
-	{0x3e,0x2a7f,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x00,0x38,-1},
-	{0x3f,0x2a1b,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x00,0x3a,-1},  /* 856x480 */
-	{0x42,0x2a3d,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x00,0x3a,-1},
-	{0x45,0x2a7f,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x00,0x3a,-1},
-	{0x48,0x223b,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x3c,-1},  /* 1360x768 */
-	{0x4b,0x227d,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x3c,-1},
-	{0x4e,0x22ff,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x3c,-1},
+	{0x20,0x4a1b,0x0000,SIS_RI_1024x600, 0x00,0x00,0x00,0x00,0x2b,-1},  /* 1024x600 */
+	{0x21,0x4a3d,0x0000,SIS_RI_1024x600, 0x00,0x00,0x00,0x00,0x2b,-1},
+	{0x22,0x4a7f,0x0000,SIS_RI_1024x600, 0x00,0x00,0x00,0x00,0x2b,-1},
+	{0x23,0x4a1b,0x0000,SIS_RI_1152x768, 0x00,0x00,0x00,0x00,0x2c,-1},  /* 1152x768 */
+	{0x24,0x4a3d,0x0000,SIS_RI_1152x768, 0x00,0x00,0x00,0x00,0x2c,-1},
+	{0x25,0x4a7f,0x0000,SIS_RI_1152x768, 0x00,0x00,0x00,0x00,0x2c,-1},
+	{0x29,0x4e1b,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x36,-1},  /* 1152x864 */
+	{0x2a,0x4e3d,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x36,-1},
+	{0x2b,0x4e7f,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x36,-1},
+	{0x39,0x6a1b,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x00,0x39,-1},  /* 848x480 */
+	{0x3b,0x6a3d,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x00,0x39,-1},
+	{0x3e,0x6a7f,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x00,0x39,-1},
+	{0x3f,0x6a1b,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x00,0x3b,-1},  /* 856x480 */
+	{0x42,0x6a3d,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x00,0x3b,-1},
+	{0x45,0x6a7f,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x00,0x3b,-1},
+	{0x48,0x6a3b,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x3d,-1},  /* 1360x768 */
+	{0x4b,0x6a7d,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x3d,-1},
+	{0x4e,0x6aff,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x3d,-1},
 	{0x4f,0x921f,0x0000,SIS_RI_320x200,  0x00,0x00,0x00,0x00,0x23,-1},  /* 320x200x32 */
 	{0x53,0x921f,0x0000,SIS_RI_320x240,  0x00,0x00,0x00,0x00,0x24,-1},  /* 320x240x32 */
 	{0x54,0xb21f,0x0000,SIS_RI_400x300,  0x00,0x00,0x00,0x00,0x25,-1},  /* 400x300x32 */
-	{0x55,0x2e3b,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x3d,-1},  /* 1280x768   */
-	{0x5a,0x2e7d,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x3d,-1},
-	{0x5b,0x2eff,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x3d,-1},
-	{0x5f,0x2a1b,0x0000,SIS_RI_768x576,  0x00,0x00,0x00,0x00,0x3e,-1},  /* 768x576x8 */
-	{0x60,0x2a1d,0x0000,SIS_RI_768x576,  0x00,0x00,0x00,0x00,0x3e,-1},  /* 768x576x16 */
-	{0x61,0x2a1f,0x0000,SIS_RI_768x576,  0x00,0x00,0x00,0x00,0x3e,-1},  /* 768x576x32 */
-	{0x67,0x2e3b,0x0000,SIS_RI_1360x1024,0x00,0x00,0x00,0x00,0x3f,-1},  /* 1360x1024x8 (BARCO) */
-	{0x6f,0x2e7d,0x0000,SIS_RI_1360x1024,0x00,0x00,0x00,0x00,0x3f,-1},  /* 1360x1024x16 (BARCO) */
-	{0x72,0x2eff,0x0000,SIS_RI_1360x1024,0x00,0x00,0x00,0x00,0x3f,-1},  /* 1360x1024x32 (BARCO) */
+	{0x55,0x2e3b,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x3e,-1},  /* 1280x768   */
+	{0x5a,0x2e7d,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x3e,-1},
+	{0x5b,0x2eff,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x3e,-1},
+	{0x5f,0x6a1b,0x0000,SIS_RI_768x576,  0x00,0x00,0x00,0x00,0x3f,-1},  /* 768x576x8 */
+	{0x60,0x6a1d,0x0000,SIS_RI_768x576,  0x00,0x00,0x00,0x00,0x3f,-1},  /* 768x576x16 */
+	{0x61,0x6a1f,0x0000,SIS_RI_768x576,  0x00,0x00,0x00,0x00,0x3f,-1},  /* 768x576x32 */
+	{0x67,0x6e3b,0x0000,SIS_RI_1360x1024,0x00,0x00,0x00,0x00,0x40,-1},  /* 1360x1024x8 (BARCO) */
+	{0x6f,0x6e7d,0x0000,SIS_RI_1360x1024,0x00,0x00,0x00,0x00,0x40,-1},  /* 1360x1024x16 (BARCO) */
+	{0x72,0x6eff,0x0000,SIS_RI_1360x1024,0x00,0x00,0x00,0x00,0x40,-1},  /* 1360x1024x32 (BARCO) */
 	{0xff,0x0000,0xffff,0,               0x00,0x00,0x00,0x00,0x00}
 };
 
@@ -170,34 +170,34 @@
 {
 	{0x085f,0x0d,0x03,0x05,0x05,0x6a, 800, 600, 0}, /* 00 */
 	{0x0467,0x0e,0x44,0x05,0x05,0x6a, 800, 600, 0}, /* 01 */
-	{0x0067,0x0f,0x07,0x48,0x00,0x6a, 800, 600, 0}, /* 02 - CRT1CRTC was 0x4f */
-	{0x0067,0x10,0x06,0x8b,0x00,0x6a, 800, 600, 0}, /* 03 */
-	{0x0147,0x11,0x08,0x00,0x00,0x6a, 800, 600, 0}, /* 04 */
-	{0x0147,0x12,0x0c,0x00,0x00,0x6a, 800, 600, 0}, /* 05 */
-	{0x0047,0x11,0x4e,0x00,0x00,0x6a, 800, 600, 0}, /* 06 - CRT1CRTC was 0x51 */
-	{0x0047,0x11,0x13,0x00,0x00,0x6a, 800, 600, 0}, /* 07 */
+	{0x0067,0x0f,0x07,0x48,0x05,0x6a, 800, 600, 0}, /* 02 - CRT1CRTC was 0x4f */
+	{0x0067,0x10,0x06,0x8b,0x05,0x6a, 800, 600, 0}, /* 03 */
+	{0x0147,0x11,0x08,0x00,0x05,0x6a, 800, 600, 0}, /* 04 */
+	{0x0147,0x12,0x0c,0x00,0x05,0x6a, 800, 600, 0}, /* 05 */
+	{0x0047,0x11,0x4e,0x00,0x05,0x6a, 800, 600, 0}, /* 06 - CRT1CRTC was 0x51 */
+	{0x0047,0x11,0x13,0x00,0x05,0x6a, 800, 600, 0}, /* 07 */
 	{0xc85f,0x05,0x00,0x04,0x04,0x2e, 640, 480, 0}, /* 08 */
 	{0xc067,0x06,0x02,0x04,0x04,0x2e, 640, 480, 0}, /* 09 */
 	{0xc067,0x07,0x02,0x47,0x04,0x2e, 640, 480, 0}, /* 0a */
 	{0xc067,0x08,0x03,0x8a,0x04,0x2e, 640, 480, 0}, /* 0b */
-	{0xc047,0x09,0x05,0x00,0x00,0x2e, 640, 480, 0}, /* 0c */
-	{0xc047,0x0a,0x08,0x00,0x00,0x2e, 640, 480, 0}, /* 0d */
-	{0xc047,0x0b,0x0a,0x00,0x00,0x2e, 640, 480, 0}, /* 0e */
-	{0xc047,0x0c,0x10,0x00,0x00,0x2e, 640, 480, 0}, /* 0f */
+	{0xc047,0x09,0x05,0x00,0x04,0x2e, 640, 480, 0}, /* 0c */
+	{0xc047,0x0a,0x08,0x00,0x04,0x2e, 640, 480, 0}, /* 0d */
+	{0xc047,0x0b,0x0a,0x00,0x04,0x2e, 640, 480, 0}, /* 0e */
+	{0xc047,0x0c,0x10,0x00,0x04,0x2e, 640, 480, 0}, /* 0f */
 	{0x487f,0x04,0x00,0x00,0x00,0x2f, 640, 400, 0}, /* 10 */
-	{0xc04f,0x31,0x01,0x06,0x00,0x31, 720, 480, 0}, /* 11 */
-	{0x004f,0x32,0x03,0x06,0x00,0x32, 720, 576, 0}, /* 12 */
-	{0x0187,0x15,0x05,0x00,0x00,0x37,1024, 768, 0}, /* 13 */
+	{0xc06f,0x31,0x01,0x06,0x13,0x31, 720, 480, 0}, /* 11 */
+	{0x006f,0x32,0x03,0x06,0x14,0x32, 720, 576, 0}, /* 12 */
+	{0x0187,0x15,0x05,0x00,0x06,0x37,1024, 768, 0}, /* 13 */
         {0xc877,0x16,0x09,0x06,0x06,0x37,1024, 768, 0}, /* 14 */
 	{0xc067,0x17,0x0b,0x49,0x06,0x37,1024, 768, 0}, /* 15 - CRT1CRTC was 0x97 */
 	{0x0267,0x18,0x0d,0x00,0x06,0x37,1024, 768, 0}, /* 16 */
-	{0x0047,0x19,0x11,0x8c,0x00,0x37,1024, 768, 0}, /* 17 - CRT1CRTC was 0x59 */
-	{0x0047,0x1a,0x52,0x00,0x00,0x37,1024, 768, 0}, /* 18 */
-	{0x0007,0x1b,0x16,0x00,0x00,0x37,1024, 768, 0}, /* 19 - CRT1CRTC was 0x5b */
-	{0x0387,0x1c,0x4d,0x00,0x00,0x3a,1280,1024, 0}, /* 1a - CRT1CRTC was 0x5c */
-	{0x0077,0x1d,0x14,0x07,0x00,0x3a,1280,1024, 0}, /* 1b */
-	{0x0047,0x1e,0x17,0x00,0x00,0x3a,1280,1024, 0}, /* 1c */
-	{0x0007,0x1f,0x98,0x00,0x00,0x3a,1280,1024, 0}, /* 1d */
+	{0x0047,0x19,0x11,0x8c,0x06,0x37,1024, 768, 0}, /* 17 - CRT1CRTC was 0x59 */
+	{0x0047,0x1a,0x52,0x00,0x06,0x37,1024, 768, 0}, /* 18 */
+	{0x0007,0x1b,0x16,0x00,0x06,0x37,1024, 768, 0}, /* 19 - CRT1CRTC was 0x5b */
+	{0x0387,0x1c,0x4d,0x00,0x07,0x3a,1280,1024, 0}, /* 1a - CRT1CRTC was 0x5c */
+	{0x0077,0x1d,0x14,0x07,0x07,0x3a,1280,1024, 0}, /* 1b */
+	{0x0047,0x1e,0x17,0x00,0x07,0x3a,1280,1024, 0}, /* 1c */
+	{0x0007,0x1f,0x98,0x00,0x07,0x3a,1280,1024, 0}, /* 1d */
 	{0x0007,0x20,0x59,0x00,0x00,0x3c,1600,1200, 0}, /* 1e - CRT1CRTC was 0x60 */
 	{0x0007,0x21,0x5a,0x00,0x00,0x3c,1600,1200, 0}, /* 1f */
 	{0x0007,0x22,0x1b,0x00,0x00,0x3c,1600,1200, 0}, /* 20 */
@@ -213,25 +213,26 @@
 	{0x0027,0x45,0x3c,0x08,0x0a,0x6e,1280, 960, 0}, /* 2a - 1280x960-85 */
 	{0xc077,0x33,0x09,0x06,0x00,0x20,1024, 600, 0}, /* 2b */
 	{0xc077,0x34,0x0b,0x06,0x00,0x23,1152, 768, 0}, /* 2c */	/* VCLK 0x09 */
-	{0x0057,0x35,0x27,0x08,0x00,0x70, 800, 480, 0}, /* 2d */
-	{0x0047,0x36,0x37,0x08,0x00,0x70, 800, 480, 0}, /* 2e */
-	{0x0047,0x37,0x08,0x08,0x00,0x70, 800, 480, 0}, /* 2f */
-	{0x0057,0x38,0x09,0x09,0x00,0x71,1024, 576, 0}, /* 30 */
-	{0x0047,0x39,0x38,0x09,0x00,0x71,1024, 576, 0}, /* 31 */
-	{0x0047,0x3a,0x11,0x09,0x00,0x71,1024, 576, 0}, /* 32 */
-	{0x0057,0x3b,0x39,0x0a,0x00,0x75,1280, 720, 0}, /* 33 */
-	{0x0047,0x3c,0x3a,0x0a,0x00,0x75,1280, 720, 0}, /* 34 */
-	{0x0007,0x3d,0x3b,0x0a,0x00,0x75,1280, 720, 0}, /* 35 */
-	{0x0047,0x3e,0x34,0x06,0x00,0x29,1152, 864, 0}, /* 36 1152x864-75Hz */
-	{0x0047,0x44,0x3a,0x06,0x00,0x29,1152, 864, 0}, /* 37 1152x864-85Hz */
-	{0x00c7,0x3f,0x28,0x00,0x00,0x39, 848, 480, 0}, /* 38 848x480-38Hzi */
-	{0xc067,0x40,0x3d,0x0b,0x0b,0x39, 848, 480, 0}, /* 39 848x480-60Hz  */
-	{0x00c7,0x41,0x28,0x00,0x00,0x3f, 856, 480, 0}, /* 3a 856x480-38Hzi */
-	{0xc047,0x42,0x28,0x00,0x00,0x3f, 856, 480, 0}, /* 3b 856x480-60Hz  */
-	{0x0067,0x43,0x3e,0x0c,0x0b,0x48,1360, 768, 0}, /* 3c 1360x768-60Hz */
-	{0x0077,0x46,0x3f,0x08,0x00,0x55,1280, 768, 0}, /* 3d 1280x768-60Hz */
-	{0x004f,0x47,0x03,0x06,0x00,0x5f, 768, 576, 0}, /* 3e 768x576 */
-	{0x0027,0x48,0x13,0x08,0x08,0x67,1360,1024, 0}, /* 3f 1360x1024-59Hz (BARCO1366 only) */
+	{0x0077,0x35,0x27,0x08,0x18,0x70, 800, 480, 0}, /* 2d */
+	{0x0047,0x36,0x37,0x08,0x18,0x70, 800, 480, 0}, /* 2e */
+	{0x0047,0x37,0x08,0x08,0x18,0x70, 800, 480, 0}, /* 2f */
+	{0x0077,0x38,0x09,0x09,0x19,0x71,1024, 576, 0}, /* 30 */
+	{0x0047,0x39,0x38,0x09,0x19,0x71,1024, 576, 0}, /* 31 */
+	{0x0047,0x3a,0x11,0x09,0x19,0x71,1024, 576, 0}, /* 32 */
+	{0x0077,0x3b,0x39,0x0a,0x0c,0x75,1280, 720, 0}, /* 33 */
+	{0x0047,0x3c,0x3a,0x0a,0x0c,0x75,1280, 720, 0}, /* 34 */
+	{0x0007,0x3d,0x3b,0x0a,0x0c,0x75,1280, 720, 0}, /* 35 */
+	{0x0067,0x49,0x35,0x06,0x1a,0x29,1152, 864, 0}, /* 36 1152x864-60Hz  */
+	{0x0067,0x3e,0x34,0x06,0x1a,0x29,1152, 864, 0}, /* 37 1152x864-75Hz */
+	{0x0047,0x44,0x3a,0x06,0x1a,0x29,1152, 864, 0}, /* 38 1152x864-85Hz */
+	{0x00c7,0x3f,0x28,0x00,0x16,0x39, 848, 480, 0}, /* 39 848x480-38Hzi */
+	{0xc067,0x40,0x3d,0x0b,0x16,0x39, 848, 480, 0}, /* 3a 848x480-60Hz  */
+	{0x00c7,0x41,0x28,0x00,0x17,0x3f, 856, 480, 0}, /* 3b 856x480-38Hzi */
+	{0xc047,0x42,0x28,0x00,0x17,0x3f, 856, 480, 0}, /* 3c 856x480-60Hz  */
+	{0x0067,0x43,0x3e,0x0c,0x1b,0x48,1360, 768, 0}, /* 3d 1360x768-60Hz */
+	{0x0077,0x46,0x3f,0x08,0x08,0x55,1280, 768, 0}, /* 3e 1280x768-60Hz */
+	{0x006f,0x47,0x03,0x06,0x15,0x5f, 768, 576, 0}, /* 3f 768x576 */
+	{0x0027,0x48,0x13,0x08,0x00,0x67,1360,1024, 0}, /* 40 1360x1024-59Hz (BARCO1366 only) */
 	{0xffff,   0,   0,   0,   0,   0,   0,   0, 0}
 };
 
@@ -378,7 +379,7 @@
   0xe0,0x83,0xdf,0xdf,0xfc,0x10,0x00,0x01,
   0x00}},
  {{0x65,0x4f,0x4f,0x89,0x57,0x9f,0xfb,0x1f,
-  0xe6,0x8a,0xdf,0xdf,0xfc,0x10,0x00,0x01,    /* TW: Corrected VDE, VBE */
+  0xe6,0x8a,0xdf,0xdf,0xfc,0x10,0x00,0x01,    /* Corrected VDE, VBE */
   0x00}},
  {{0x7b,0x63,0x63,0x9f,0x6a,0x93,0x6f,0xf0,
   0x58,0x8a,0x57,0x57,0x70,0x20,0x00,0x05,
@@ -558,13 +559,16 @@
    0x01}}, /* 0x45 */
  {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x20,0xf5,  /* 1280x768-60 */
    0x03,0x88,0xff,0xff,0x21,0x10,0x00,0x07,
-   0x01}},  /* 0x46 */
+   0x01}}, /* 0x46 */
  {{0x7b,0x5f,0x63,0x9f,0x6a,0x93,0x6f,0xf0,  /* 768x576 */
    0x58,0x8a,0x3f,0x57,0x70,0x20,0x00,0x05,
-   0x01}},  /* 0x47 */
+   0x01}}, /* 0x47 */
  {{0xce,0xa9,0xa9,0x92,0xb1,0x07,0x28,0x52,  /* 1360x1024 (Barco iQ Pro R300) */
    0x02,0x8e,0xff,0x00,0x29,0x0d,0x00,0x03,
-   0x00}}   /* 0x48 */
+   0x00}}, /* 0x48 */
+ {{0xcd,0x8f,0x8f,0x91,0x9b,0x1b,0x7a,0xff,  /* 1152x864-60 */
+   0x64,0x8c,0x5f,0x62,0x7b,0x10,0x00,0x07,
+   0x41}}  /* 0x49 */
 };
 
 static const SiS_MCLKDataStruct  SiS300_MCLKData_630[] =
@@ -646,7 +650,7 @@
 	{ 0x52,0x4a, 36}, /* 0x32 */  /* CH/PAL 800x600 5/6 */
 	{ 0x34,0x61, 95}, /* 0x33 */
 	{ 0x78,0x27,108}, /* 0x34 */  /* Replacement for index 0x14 for 630 (?) */
-	{ 0xce,0x25,189}, /* 0x35 */  /* Replacement for index 0x1b for 730 (and 540?) */
+	{ 0x70,0x28, 90}, /* 0x35 */  /* 1152x864@60 */
 	{ 0x45,0x6b, 21}, /* 0x36 */  /* Chrontel SuperOverscan */
 	{ 0x52,0xe2, 49}, /* 0x37 */  /* 16:9 modes  */
 	{ 0x2b,0x61, 78}, /* 0x38 */  /* 16:9 modes  */
@@ -656,20 +660,19 @@
 	{ 0x52,0x07,149}, /* 0x3c */  /* 1280x960-85 */
 	{ 0x62,0xc6, 34}, /* 0x3d */  /* 848x480-60  */
 	{ 0x30,0x23, 88}, /* 0x3e */  /* 1360x768-60 */
-#if 0
-	{ 0x3f,0x64, 46}, /* 0x3f */  /* 640x480-100 */
-#endif
         { 0x70,0x29, 81}, /* 0x3f */  /* 1280x768-60 */
-	{ 0x72,0x2a, 76}, /* 0x40 */  /* test for SiS730 */
+	{ 0x72,0x2a, 76}, /* 0x40 */  /* test for SiS730 --- LIMIT for table (&0x3f) */
 	{ 0x15,0x21, 79}, /* 0x41 */  /* test for SiS730 */
 	{ 0xa1,0x42,108}, /* 0x42 */  /* 1280x960 LCD */
 	{ 0x37,0x61,100}, /* 0x43 */  /* 1280x960 LCD */
 	{ 0xe3,0x9a,106}, /* 0x44 */  /* 1360x1024 - special for Barco iQ R300 */
 	{ 0xe2,0x46,135}, /* 0x45 */  /* 1280x1024-75, better clock for VGA2 */
-	{    0,   0,  0}  /* 0x46 custom (will be filled out) */
+	{ 0x70,0x29, 81}, /* 0x46 */  /* unused */
+	{    0,   0,  0}, /* 0x47 custom (will be filled out) */
+	{ 0xce,0x25,189}  /* 0x48 */  /* Replacement for index 0x1b for 730 (and 540?) */
 };
 
-#ifndef LINUX_XF86
+#ifdef LINUX_KERNEL
 static UCHAR SiS300_SR07 = 0x10;
 #endif
 
@@ -685,7 +688,7 @@
 	{0x00,0x00,0x00,0x00}
 };
 
-#ifndef LINUX_XF86
+#ifdef LINUX_KERNEL
 static UCHAR SiS300_SR1F = 0x00;
 static UCHAR SiS300_SR21 = 0x16;
 static UCHAR SiS300_SR22 = 0xb2;
diff -Nru a/drivers/video/sis/310vtbl.h b/drivers/video/sis/310vtbl.h
--- a/drivers/video/sis/310vtbl.h	2005-03-01 23:38:59 -08:00
+++ b/drivers/video/sis/310vtbl.h	2005-03-01 23:38:59 -08:00
@@ -35,7 +35,7 @@
  * * 3) The name of the author may not be used to endorse or promote products
  * *    derived from this software without specific prior written permission.
  * *
- * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR
+ * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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,
@@ -145,33 +145,36 @@
 	{0x29,0x4e1b,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x43,-1}, /* 1152x864 */
 	{0x2a,0x4e3d,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x43,-1},
 	{0x2b,0x4e7f,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x43,-1},
-	{0x39,0x6a1b,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x00,0x45,-1}, /* 848x480 */
-	{0x3b,0x6a3d,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x00,0x45,-1},
-	{0x3e,0x6a7f,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x00,0x45,-1},
-	{0x3f,0x6a1b,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x00,0x47,-1}, /* 856x480 */
-	{0x42,0x6a3d,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x00,0x47,-1},
-	{0x45,0x6a7f,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x00,0x47,-1},
-	{0x48,0x6a3b,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x49,-1}, /* 1360x768 */
-	{0x4b,0x6a7d,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x49,-1},
-	{0x4e,0x6aff,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x49,-1},
+	{0x39,0x6a1b,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x00,0x46,-1}, /* 848x480 */
+	{0x3b,0x6a3d,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x00,0x46,-1},
+	{0x3e,0x6a7f,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x00,0x46,-1},
+	{0x3f,0x6a1b,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x00,0x48,-1}, /* 856x480 */
+	{0x42,0x6a3d,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x00,0x48,-1},
+	{0x45,0x6a7f,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x00,0x48,-1},
+	{0x48,0x6a3b,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x4a,-1}, /* 1360x768 */
+	{0x4b,0x6a7d,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x4a,-1},
+	{0x4e,0x6aff,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x4a,-1},
 	{0x4f,0x9a1f,0x0000,SIS_RI_320x200,  0x00,0x00,0x04,0x04,0x25, 0}, /* 320x200x32 */
 	{0x53,0x9a1f,0x0000,SIS_RI_320x240,  0x00,0x00,0x04,0x04,0x26, 2}, /* 320x240x32 */
 	{0x54,0xba1f,0x0000,SIS_RI_400x300,  0x00,0x00,0x07,0x07,0x27, 3}, /* 400x300x32 */
-	{0x5f,0x6a1b,0x0000,SIS_RI_768x576,  0x00,0x00,0x06,0x06,0x4a,-1}, /* 768x576 */
-	{0x60,0x6a1d,0x0000,SIS_RI_768x576,  0x00,0x00,0x06,0x06,0x4a,-1},
-	{0x61,0x6a3f,0x0000,SIS_RI_768x576,  0x00,0x00,0x06,0x06,0x4a,-1},
-	{0x14,0x0e3b,0x0000,SIS_RI_1280x800, 0x00,0x00,0x00,0x00,0x4b, 7}, /* 1280x800 */
-	{0x15,0x0e7d,0x0000,SIS_RI_1280x800, 0x00,0x00,0x00,0x00,0x4b, 7},
-	{0x16,0x0eff,0x0000,SIS_RI_1280x800, 0x00,0x00,0x00,0x00,0x4b, 7},
-	{0x17,0x0e3b,0x0000,SIS_RI_1680x1050,0x00,0x00,0x00,0x00,0x4c, 9}, /* 1680x1050 */
-	{0x18,0x0e7d,0x0000,SIS_RI_1680x1050,0x00,0x00,0x00,0x00,0x4c, 9},
-	{0x19,0x0eff,0x0000,SIS_RI_1680x1050,0x00,0x00,0x00,0x00,0x4c, 9},
-	{0x2c,0x267b,0x0000,SIS_RI_1920x1080,0x00,0x00,0x00,0x00,0x4d,-1}, /* 1920x1080(i) */
-	{0x2d,0x26fd,0x0000,SIS_RI_1920x1080,0x00,0x00,0x00,0x00,0x4d,-1},
-	{0x73,0x27ff,0x0000,SIS_RI_1920x1080,0x00,0x00,0x00,0x00,0x4d,-1},
-	{0x1d,0x6a1b,0x0000,SIS_RI_960x540,  0x00,0x00,0x00,0x00,0x4e,-1}, /* 960x540 */
-	{0x1e,0x6a3d,0x0000,SIS_RI_960x540,  0x00,0x00,0x00,0x00,0x4e,-1},
-	{0x1f,0x6a7f,0x0000,SIS_RI_960x540,  0x00,0x00,0x00,0x00,0x4e,-1},
+	{0x5f,0x6a1b,0x0000,SIS_RI_768x576,  0x00,0x00,0x06,0x06,0x4b,-1}, /* 768x576 */
+	{0x60,0x6a1d,0x0000,SIS_RI_768x576,  0x00,0x00,0x06,0x06,0x4b,-1},
+	{0x61,0x6a3f,0x0000,SIS_RI_768x576,  0x00,0x00,0x06,0x06,0x4b,-1},
+	{0x14,0x0e3b,0x0000,SIS_RI_1280x800, 0x00,0x00,0x00,0x00,0x4c, 7}, /* 1280x800 */
+	{0x15,0x0e7d,0x0000,SIS_RI_1280x800, 0x00,0x00,0x00,0x00,0x4c, 7},
+	{0x16,0x0eff,0x0000,SIS_RI_1280x800, 0x00,0x00,0x00,0x00,0x4c, 7},
+	{0x17,0x0e3b,0x0000,SIS_RI_1680x1050,0x00,0x00,0x00,0x00,0x4d, 9}, /* 1680x1050 */
+	{0x18,0x0e7d,0x0000,SIS_RI_1680x1050,0x00,0x00,0x00,0x00,0x4d, 9},
+	{0x19,0x0eff,0x0000,SIS_RI_1680x1050,0x00,0x00,0x00,0x00,0x4d, 9},
+	{0x2c,0x267b,0x0000,SIS_RI_1920x1080,0x00,0x00,0x00,0x00,0x4e,-1}, /* 1920x1080(i) */
+	{0x2d,0x26fd,0x0000,SIS_RI_1920x1080,0x00,0x00,0x00,0x00,0x4e,-1},
+	{0x73,0x27ff,0x0000,SIS_RI_1920x1080,0x00,0x00,0x00,0x00,0x4e,-1},
+	{0x1d,0x6a1b,0x0000,SIS_RI_960x540,  0x00,0x00,0x00,0x00,0x4f,-1}, /* 960x540 */
+	{0x1e,0x6a3d,0x0000,SIS_RI_960x540,  0x00,0x00,0x00,0x00,0x4f,-1},
+	{0x1f,0x6a7f,0x0000,SIS_RI_960x540,  0x00,0x00,0x00,0x00,0x4f,-1},
+	{0x20,0x6a1b,0x0000,SIS_RI_960x600,  0x00,0x00,0x00,0x00,0x50,-1}, /* 960x600 */
+	{0x21,0x6a3d,0x0000,SIS_RI_960x600,  0x00,0x00,0x00,0x00,0x50,-1},
+	{0x22,0x6a7f,0x0000,SIS_RI_960x600,  0x00,0x00,0x00,0x00,0x50,-1},
 	{0xff,0x0000,0x0000,0,               0x00,0x00,0x00,0x00,0x00,-1}
 };
 
@@ -244,21 +247,89 @@
         {0x0077,0x42,0x5b,0x08,0x11,0x23,1280, 768, 0x30}, /* 0x40 */    /* 0x5b was 0x12 */
 	{0x0127,0x43,0x4d,0x08,0x0b,0x26,1400,1050, 0x30}, /* 0x41 */
 	{0x0207,0x4b,0x5a,0x08,0x0b,0x26,1400,1050, 0x30}, /* 0x42 1400x1050-75Hz */
-	{0x0127,0x44,0x19,0x00,0x1a,0x29,1152, 864, 0x30}, /* 0x43 1152x864-75Hz  */
-	{0x0127,0x4a,0x1e,0x00,0x1a,0x29,1152, 864, 0x30}, /* 0x44 1152x864-85Hz  */
-	{0x0087,0x45,0x57,0x00,0x16,0x39, 848, 480, 0x30}, /* 0x45 848x480-38Hzi  */
-	{0xc067,0x46,0x55,0x0b,0x16,0x39, 848, 480, 0x30}, /* 0x46 848x480-60Hz   */
-	{0x0087,0x47,0x57,0x00,0x17,0x3f, 856, 480, 0x30}, /* 0x47 856x480-38Hzi  */
-	{0xc067,0x48,0x57,0x00,0x17,0x3f, 856, 480, 0x30}, /* 0x48 856x480-60Hz   */
-	{0x0067,0x49,0x58,0x0c,0x1b,0x48,1360, 768, 0x30}, /* 0x49 1360x768-60Hz  */
-	{0x006f,0x4d,0x03,0x06,0x15,0x5f, 768, 576, 0x30}, /* 0x4a 768x576-56Hz   */
-	{0x0067,0x4f,0x5c,0x08,0x0d,0x14,1280, 800, 0x30}, /* 0x4b 1280x800-60Hz  */
-	{0x0067,0x50,0x5d,0x0c,0x0e,0x17,1680,1050, 0x30}, /* 0x4c 1680x1050-60Hz */
-	{0x0087,0x51,0x69,0x00,0x00,0x2c,1920,1080, 0x30}, /* 0x4d 1920x1080 60Hzi */
-	{0x0067,0x52,0x6a,0x00,0x1c,0x1d, 960, 540, 0x30}, /* 0x4e 960x540 60Hz */
+	{0x0127,0x54,0x6d,0x00,0x1a,0x29,1152, 864, 0x30}, /* 0x43 1152x864-60Hz  */
+	{0x0127,0x44,0x19,0x00,0x1a,0x29,1152, 864, 0x30}, /* 0x44 1152x864-75Hz  */
+	{0x0127,0x4a,0x1e,0x00,0x1a,0x29,1152, 864, 0x30}, /* 0x45 1152x864-85Hz  */
+	{0x0087,0x45,0x57,0x00,0x16,0x39, 848, 480, 0x30}, /* 0x46 848x480-38Hzi  */
+	{0xc067,0x46,0x55,0x0b,0x16,0x39, 848, 480, 0x30}, /* 0x47 848x480-60Hz   */
+	{0x0087,0x47,0x57,0x00,0x17,0x3f, 856, 480, 0x30}, /* 0x48 856x480-38Hzi  */
+	{0xc067,0x48,0x57,0x00,0x17,0x3f, 856, 480, 0x30}, /* 0x49 856x480-60Hz   */
+	{0x0067,0x49,0x58,0x0c,0x1b,0x48,1360, 768, 0x30}, /* 0x4a 1360x768-60Hz  */
+	{0x006f,0x4d,0x03,0x06,0x15,0x5f, 768, 576, 0x30}, /* 0x4b 768x576-56Hz   */
+	{0x0067,0x4f,0x5c,0x08,0x0d,0x14,1280, 800, 0x30}, /* 0x4c 1280x800-60Hz  */
+	{0x0067,0x50,0x5d,0x0c,0x0e,0x17,1680,1050, 0x30}, /* 0x4d 1680x1050-60Hz */
+	{0x0087,0x51,0x69,0x00,0x00,0x2c,1920,1080, 0x30}, /* 0x4e 1920x1080 60Hzi */
+	{0x0067,0x52,0x6a,0x00,0x1c,0x1d, 960, 540, 0x30}, /* 0x4f 960x540 60Hz */
+	{0x0077,0x53,0x6b,0x0b,0x1d,0x20, 960, 600, 0x30}, /* 0x50 960x600 60Hz */
 	{0xffff,0x00,0x00,0x00,0x00,0x00,   0,   0,    0}
 };
 
+#ifdef LINUX_XF86
+static const struct {
+	UCHAR  Ext_ModeID;     /* ModeID in new ROM */
+	UCHAR  Ext_MyModeID;   /* corresponding ModeID in my tables (0 = identical) */
+	USHORT Ext_VESAID;     /* corresponding VESA ID in new ROM */
+} SiS_EModeIDTable661[] = {
+        { 0x6a, 0x00, 0x0102 },
+	{ 0x1d, 0x20, 0x0000 },
+	{ 0x1e, 0x21, 0x0000 },
+	{ 0x1f, 0x22, 0x0000 },
+	{ 0x20, 0x29, 0x0000 },
+	{ 0x21, 0x2a, 0x0000 },
+	{ 0x22, 0x2b, 0x0000 },
+	{ 0x23, 0x00, 0x011c },
+	{ 0x24, 0x00, 0x011d },
+	{ 0x25, 0x00, 0x011e },
+	{ 0x26, 0x00, 0x011f },
+	{ 0x27, 0x00, 0x0120 },
+	{ 0x28, 0x00, 0x0121 },
+	{ 0x2a, 0x14, 0x013d },
+	{ 0x2b, 0x15, 0x013e },
+	{ 0x2c, 0x16, 0x013f },
+	{ 0x2e, 0x00, 0x0101 },
+	{ 0x2f, 0x00, 0x0100 },
+	{ 0x30, 0x00, 0x0103 },
+	{ 0x37, 0x00, 0x0104 },
+	{ 0x38, 0x00, 0x0105 },
+	{ 0x3a, 0x00, 0x0107 },
+	{ 0x3c, 0x00, 0x0125 },
+	{ 0x3d, 0x00, 0x0126 },
+	{ 0x40, 0x00, 0x010d },
+	{ 0x41, 0x00, 0x010e },
+	{ 0x43, 0x00, 0x0110 },
+	{ 0x44, 0x00, 0x0111 },
+	{ 0x46, 0x00, 0x0113 },
+	{ 0x47, 0x00, 0x0114 },
+	{ 0x49, 0x00, 0x0116 },
+	{ 0x4a, 0x00, 0x0117 },
+	{ 0x4c, 0x00, 0x0119 },
+	{ 0x4d, 0x00, 0x011a },
+	{ 0x50, 0x00, 0x0127 },
+	{ 0x51, 0x00, 0x0128 },
+	{ 0x52, 0x00, 0x0129 },
+	{ 0x56, 0x00, 0x012a },
+	{ 0x57, 0x00, 0x012b },
+	{ 0x58, 0x00, 0x012c },
+	{ 0x59, 0x00, 0x012d },
+	{ 0x5a, 0x17, 0x012e },
+	{ 0x5b, 0x18, 0x012f },
+	{ 0x5c, 0x19, 0x0130 },
+	{ 0x5d, 0x00, 0x0131 },
+	{ 0x62, 0x00, 0x0112 },
+	{ 0x63, 0x00, 0x0115 },
+	{ 0x64, 0x00, 0x0118 },
+	{ 0x65, 0x00, 0x011b },
+	{ 0x66, 0x00, 0x0132 },
+	{ 0x75, 0x00, 0x013a },
+	{ 0x78, 0x00, 0x013b },
+	{ 0x79, 0x00, 0x013c },
+	{ 0x7b, 0x7c, 0x0136 },
+	{ 0x7c, 0x7d, 0x0137 },
+	{ 0x7d, 0x7e, 0x0138 },
+	{ 0xff, 0xff, 0xffff }
+};
+#endif
+
 static const SiS_CRT1TableStruct SiS310_CRT1Table[]=
 {
  {{0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,
@@ -524,7 +595,13 @@
    0x61}},  /* 0x51 */
  {{0x85,0x77,0x77,0x89,0x7d,0x01,0x31,0xf0, /* 960x540-60 */
    0x1e,0x84,0x1b,0x1c,0x32,0x00,0x00,0x02,
-   0x41}}   /* 0x52 */
+   0x41}},  /* 0x52 */
+ {{0x87,0x77,0x77,0x8b,0x81,0x0b,0x68,0xf0, /* 960x600-60 */
+   0x5a,0x80,0x57,0x57,0x69,0x00,0x00,0x02,
+   0x01}},  /* 0x53 */
+ {{0xcd,0x8f,0x8f,0x91,0x9b,0x1b,0x7a,0xff, /* 1152x864-60 */
+   0x64,0x8c,0x5f,0x62,0x7b,0x10,0x00,0x07,
+   0x41}}   /* 0x54 */
 };
 
 static const SiS_MCLKDataStruct SiS310_MCLKData_0_315[] =
@@ -587,6 +664,30 @@
 	{ 0x37,0x21,0x82,200}
 };
 
+static const SiS_MCLKDataStruct SiS310_MCLKData_0_761[] =
+{
+	{ 0x37,0x22,0x82,133},  /* Preliminary */
+	{ 0x5c,0x23,0x82,166},
+	{ 0x65,0x23,0x82,183},
+	{ 0x7c,0x08,0x82,200},
+	{ 0x29,0x21,0x82,150},
+	{ 0x5c,0x23,0x82,166},
+	{ 0x65,0x23,0x82,183},
+	{ 0x37,0x21,0x82,200}
+};
+
+static const SiS_MCLKDataStruct SiS310_MCLKData_0_340[] =
+{
+	{ 0x79,0x06,0x01,250},
+	{ 0x7c,0x08,0x01,200},
+	{ 0x7c,0x08,0x80,200},
+	{ 0x79,0x06,0x80,250},
+	{ 0x29,0x01,0x81,300},
+	{ 0x29,0x01,0x81,300},
+	{ 0x29,0x01,0x81,300},
+	{ 0x29,0x01,0x81,300}
+};
+
 static const SiS_MCLKDataStruct SiS310_MCLKData_1[] = /* ECLK */
 {
         { 0x29,0x21,0x82,150},
@@ -599,6 +700,18 @@
 	{ 0x37,0x22,0x82,133}
 };
 
+static const SiS_MCLKDataStruct SiS310_MCLKData_1_340[] =
+{
+	{ 0x7c,0x08,0x01,200},
+	{ 0x7c,0x08,0x01,200},
+	{ 0x7c,0x08,0x80,200},
+	{ 0x79,0x06,0x80,250},
+	{ 0x29,0x01,0x81,300},
+	{ 0x29,0x01,0x81,300},
+	{ 0x29,0x01,0x81,300},
+	{ 0x29,0x01,0x81,300}
+};
+
 static SiS_VCLKDataStruct SiS310_VCLKData[]=
 {
 	{ 0x1b,0xe1, 25}, /* 0x00 */
@@ -707,7 +820,10 @@
 	{ 0x76,0xe7, 27}, /* 0x67 720x480@60 */
 	{ 0x5f,0xc6, 33}, /* 0x68 720/768x576@60 */
 	{ 0x52,0x27, 75}, /* 0x69 1920x1080i 60Hz interlaced */
-	{ 0x7c,0x6b, 38}  /* 0x6a 960x540@60 */
+	{ 0x7c,0x6b, 38}, /* 0x6a 960x540@60 */
+	{ 0xe3,0x56, 41}, /* 0x6b 960x600@60 */
+	{ 0x45,0x25, 83}, /* 0x6c 1280x800 */
+	{ 0x70,0x28, 90}  /* 0x6d 1152x864@60 */
 };
 
 static SiS_VBVCLKDataStruct SiS310_VBVCLKData[]=
@@ -809,22 +925,25 @@
 	{ 0x30,0x23, 88}, /* 0x58 1360x768-62 (is 60Hz!) TEMP, UNUSED */
 	{ 0x52,0x07,149}, /* 0x59 1280x960-85  */
 	{ 0x56,0x07,156}, /* 0x5a 1400x1050-75 */
-   	{ 0x70,0x29, 81}, /* 0x5b 1280x768 LCD */
-	{ 0x45,0x25, 83}, /* 0x5c 1280x800 LCD - (was 0x9c,0x62, 69 - wrong?) */
+   	{ 0x70,0x29, 81}, /* 0x5b 1280x768 LCD (TMDS) */
+	{ 0xce,0x1e, 73}, /* 0x5c 1280x800_2 LCD (SiS LVDS) - (CRT1: 45 25 83) */
 	{ 0xbe,0x44,121}, /* 0x5d 1680x1050 LCD */
 	{ 0x70,0x24,162}, /* 0x5e 1600x1200 LCD */
-	{ 0x52,0x27, 75}, /* 0x5f 1280x720 LCD TMDS + HDTV (correct) */
-	{ 0x63,0x46, 68}, /* 0x60 1280x768_2 */
-	{ 0x31,0x42, 79}, /* 0x61 1280x768_3 - temp */
+	{ 0x52,0x27, 75}, /* 0x5f 1280x720 (TMDS + HDTV) (correct) */
+	{ 0xc8,0x48, 77}, /* 0x60 1280x768_2 (SiS LVDS) */
+	{ 0x31,0x42, 79}, /* 0x61 1280x768_3 (SiS LVDS) - temp */
 	{    0,   0,  0}, /* 0x62 - custom (will be filled out at run-time) */
-	{ 0x5a,0x64, 65}, /* 0x63 1280x720 (LCD LVDS) */
+	{ 0x9c,0x62, 69}, /* 0x63 1280x720 (SiS LVDS) */
 	{ 0x70,0x28, 90}, /* 0x64 1152x864@60 */
 	{ 0x41,0xc4, 32}, /* 0x65 848x480@60 */
 	{ 0x5c,0xc6, 32}, /* 0x66 856x480@60 */
 	{ 0x76,0xe7, 27}, /* 0x67 720x480@60 */
 	{ 0x5f,0xc6, 33}, /* 0x68 720/768x576@60 */
 	{ 0x52,0x27, 75}, /* 0x69 1920x1080i 60Hz interlaced (UNUSED) */
-	{ 0x7c,0x6b, 38}  /* 0x6a 960x540@60 */
+	{ 0x7c,0x6b, 38}, /* 0x6a 960x540@60 */
+	{ 0xe3,0x56, 41}, /* 0x6b 960x600@60 */
+	{ 0x9c,0x62, 69}, /* 0x6c 1280x800 (SiS TMDS) (special) */
+	{ 0x70,0x28, 90}  /* 0x6d 1152x864@60 */
 };
 
 static const DRAM4Type SiS310_SR15[8] = {
@@ -838,7 +957,7 @@
 	{0x00,0xa5,0xfb,0xf6}
 };
 
-#ifndef LINUX_XF86
+#ifdef LINUX_KERNEL
 
 static UCHAR SiS310_SR07 = 0x18;
 
diff -Nru a/drivers/video/sis/init.c b/drivers/video/sis/init.c
--- a/drivers/video/sis/init.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/video/sis/init.c	2005-03-01 23:38:54 -08:00
@@ -38,7 +38,7 @@
  * * 3) The name of the author may not be used to endorse or promote products
  * *    derived from this software without specific prior written permission.
  * *
- * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR
+ * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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,
@@ -135,8 +135,8 @@
    SiS_Pr->SiS_LCD1280x720Data      = SiS_LCD1280x720Data;
    SiS_Pr->SiS_StLCD1280x768_2Data  = SiS_StLCD1280x768_2Data;
    SiS_Pr->SiS_ExtLCD1280x768_2Data = SiS_ExtLCD1280x768_2Data;
-   SiS_Pr->SiS_LCD1280x768_3Data    = SiS_LCD1280x768_3Data;
    SiS_Pr->SiS_LCD1280x800Data      = SiS_LCD1280x800Data;
+   SiS_Pr->SiS_LCD1280x800_2Data    = SiS_LCD1280x800_2Data;
    SiS_Pr->SiS_LCD1280x960Data      = SiS_LCD1280x960Data;
    SiS_Pr->SiS_StLCD1400x1050Data   = SiS_StLCD1400x1050Data;
    SiS_Pr->SiS_ExtLCD1400x1050Data  = SiS_ExtLCD1400x1050Data;
@@ -217,34 +217,6 @@
 {
    InitCommonPointer(SiS_Pr, HwInfo);
 
-   SiS_StandTable[0x04].CRTC[4] = 0x2b;
-   SiS_StandTable[0x05].CRTC[4] = 0x2b;
-   SiS_StandTable[0x06].CRTC[4] = 0x54;
-   SiS_StandTable[0x06].CRTC[5] = 0x80;
-   SiS_StandTable[0x0d].CRTC[4] = 0x2b;
-   SiS_StandTable[0x0e].CRTC[4] = 0x54;
-   SiS_StandTable[0x0e].CRTC[5] = 0x80;
-   SiS_StandTable[0x11].CRTC[4] = 0x54;
-   SiS_StandTable[0x11].CRTC[5] = 0x80;
-   SiS_StandTable[0x11].CRTC[16] = 0x83;
-   SiS_StandTable[0x11].CRTC[17] = 0x85;
-   SiS_StandTable[0x12].CRTC[4] = 0x54;
-   SiS_StandTable[0x12].CRTC[5] = 0x80;
-   SiS_StandTable[0x12].CRTC[16] = 0x83;
-   SiS_StandTable[0x12].CRTC[17] = 0x85;
-   SiS_StandTable[0x13].CRTC[5] = 0xa0;
-   SiS_StandTable[0x17].CRTC[5] = 0xa0;
-   SiS_StandTable[0x1a].CRTC[4] = 0x54;
-   SiS_StandTable[0x1a].CRTC[5] = 0x80;
-   SiS_StandTable[0x1a].CRTC[16] = 0xea;
-   SiS_StandTable[0x1a].CRTC[17] = 0x8c;
-   SiS_StandTable[0x1b].CRTC[4] = 0x54;
-   SiS_StandTable[0x1b].CRTC[5] = 0x80;
-   SiS_StandTable[0x1b].CRTC[16] = 0xea;
-   SiS_StandTable[0x1b].CRTC[17] = 0x8c;
-   SiS_StandTable[0x1c].CRTC[4] = 0x54;
-   SiS_StandTable[0x1c].CRTC[5] = 0x80;
-
    SiS_Pr->SiS_SModeIDTable  = SiS300_SModeIDTable;
    SiS_Pr->SiS_VBModeIDTable = SiS300_VBModeIDTable;
    SiS_Pr->SiS_EModeIDTable  = SiS300_EModeIDTable;
@@ -260,7 +232,7 @@
 
    SiS_Pr->SiS_SR15  = SiS300_SR15;
 
-#ifndef LINUX_XF86
+#ifdef LINUX_KERNEL
    SiS_Pr->pSiS_SR07 = &SiS300_SR07;
    SiS_Pr->SiS_CR40  = SiS300_CR40;
    SiS_Pr->SiS_CR49  = SiS300_CR49;
@@ -399,39 +371,15 @@
 {
    InitCommonPointer(SiS_Pr, HwInfo);
 
-   SiS_StandTable[0x04].CRTC[4] = 0x2c;
-   SiS_StandTable[0x05].CRTC[4] = 0x2c;
-   SiS_StandTable[0x06].CRTC[4] = 0x55;
-   SiS_StandTable[0x06].CRTC[5] = 0x81;
-   SiS_StandTable[0x0d].CRTC[4] = 0x2c;
-   SiS_StandTable[0x0e].CRTC[4] = 0x55;
-   SiS_StandTable[0x0e].CRTC[5] = 0x81;
-   SiS_StandTable[0x11].CRTC[4] = 0x55;
-   SiS_StandTable[0x11].CRTC[5] = 0x81;
-   SiS_StandTable[0x11].CRTC[16] = 0x82;
-   SiS_StandTable[0x11].CRTC[17] = 0x84;
-   SiS_StandTable[0x12].CRTC[4] = 0x55;
-   SiS_StandTable[0x12].CRTC[5] = 0x81;
-   SiS_StandTable[0x12].CRTC[16] = 0x82;
-   SiS_StandTable[0x12].CRTC[17] = 0x84;
-   SiS_StandTable[0x13].CRTC[5] = 0xb1;
-   SiS_StandTable[0x17].CRTC[5] = 0xb1;
-   SiS_StandTable[0x1a].CRTC[4] = 0x55;
-   SiS_StandTable[0x1a].CRTC[5] = 0x81;
-   SiS_StandTable[0x1a].CRTC[16] = 0xe9;
-   SiS_StandTable[0x1a].CRTC[17] = 0x8b;
-   SiS_StandTable[0x1b].CRTC[4] = 0x55;
-   SiS_StandTable[0x1b].CRTC[5] = 0x81;
-   SiS_StandTable[0x1b].CRTC[16] = 0xe9;
-   SiS_StandTable[0x1b].CRTC[17] = 0x8b;
-   SiS_StandTable[0x1c].CRTC[4] = 0x55;
-   SiS_StandTable[0x1c].CRTC[5] = 0x81;
-
    SiS_Pr->SiS_SModeIDTable  = SiS310_SModeIDTable;
    SiS_Pr->SiS_EModeIDTable  = SiS310_EModeIDTable;
    SiS_Pr->SiS_RefIndex      = (SiS_Ext2Struct *)SiS310_RefIndex;
    SiS_Pr->SiS_CRT1Table     = SiS310_CRT1Table;
-   if(HwInfo->jChipType >= SIS_760) {
+   if(HwInfo->jChipType >= SIS_340) {
+      SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_340;  /* 340 */
+   } else if(HwInfo->jChipType >= SIS_761) {
+      SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_761;  /* 761 - preliminary */
+   } else if(HwInfo->jChipType >= SIS_760) {
       SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_760;  /* 760 */
    } else if(HwInfo->jChipType >= SIS_661) {
       SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_660;  /* 661/741 */
@@ -442,13 +390,17 @@
    } else {
       SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_315;  /* 315 */
    }
-   SiS_Pr->SiS_MCLKData_1    = SiS310_MCLKData_1;
+   if(HwInfo->jChipType >= SIS_340) {
+      SiS_Pr->SiS_MCLKData_1    = SiS310_MCLKData_1_340;
+   } else {
+      SiS_Pr->SiS_MCLKData_1    = SiS310_MCLKData_1;
+   }
    SiS_Pr->SiS_VCLKData      = SiS310_VCLKData;
    SiS_Pr->SiS_VBVCLKData    = SiS310_VBVCLKData;
 
    SiS_Pr->SiS_SR15  = SiS310_SR15;
 
-#ifndef LINUX_XF86
+#ifdef LINUX_KERNEL
    SiS_Pr->pSiS_SR07 = &SiS310_SR07;
    SiS_Pr->SiS_CR40  = SiS310_CR40;
    SiS_Pr->SiS_CR49  = SiS310_CR49;
@@ -592,6 +544,8 @@
    case SIS_741:
    case SIS_660:
    case SIS_760:
+   case SIS_761:
+   case SIS_340:
       InitTo310Pointer(SiS_Pr, HwInfo);
       break;
 #endif
@@ -612,6 +566,7 @@
 /*            HELPER: Get ModeID             */
 /*********************************************/
 
+#ifdef LINUX_XF86
 USHORT
 SiS_GetModeID(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay,
               int Depth, BOOLEAN FSTN, int LCDwidth, int LCDheight)
@@ -628,10 +583,14 @@
           }
           break;
      case 400:
-          if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
+          if((!(VBFlags & CRT1_LCDA)) || ((LCDwidth >= 800) && (LCDwidth >= 600))) {
+             if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
+	  }
           break;
      case 512:
-          if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
+          if((!(VBFlags & CRT1_LCDA)) || ((LCDwidth >= 1024) && (LCDwidth >= 768))) {
+             if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
+	  }
           break;
      case 640:
           if(VDisplay == 480)      ModeIndex = ModeIndex_640x480[Depth];
@@ -656,67 +615,58 @@
 	  break;
      case 960:
 	  if(VGAEngine == SIS_315_VGA) {
-	     if(VDisplay == 540) ModeIndex = ModeIndex_960x540[Depth];
+	     if(VDisplay == 540)      ModeIndex = ModeIndex_960x540[Depth];
+	     else if(VDisplay == 600) ModeIndex = ModeIndex_960x600[Depth];
 	  }
 	  break;
      case 1024:
-          if(VDisplay == 768)      ModeIndex = ModeIndex_1024x768[Depth];
-	  else if(VDisplay == 576) ModeIndex = ModeIndex_1024x576[Depth];
-	  else if((!(VBFlags & CRT1_LCDA)) && (VGAEngine == SIS_300_VGA)) {
-	     if(VDisplay == 600) ModeIndex = ModeIndex_1024x600[Depth];
+          if(VDisplay == 576)      ModeIndex = ModeIndex_1024x576[Depth];
+          else if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth];
+	  else if(VGAEngine == SIS_300_VGA) {
+	     if(VDisplay == 600)   ModeIndex = ModeIndex_1024x600[Depth];
 	  }
           break;
      case 1152:
           if(VDisplay == 864) ModeIndex = ModeIndex_1152x864[Depth];
-          if((!(VBFlags & CRT1_LCDA)) && (VGAEngine == SIS_300_VGA)) {
+          if(VGAEngine == SIS_300_VGA) {
 	     if(VDisplay == 768) ModeIndex = ModeIndex_1152x768[Depth];
 	  }
 	  break;
      case 1280:
-          if(VDisplay == 1024) ModeIndex = ModeIndex_1280x1024[Depth];
-	  else if(VDisplay == 800) {
-	     if(VGAEngine == SIS_315_VGA) {
-	        if((VBFlags & CRT1_LCDA) && (LCDwidth == 1280) && (LCDheight == 800)) {
-	           ModeIndex = ModeIndex_1280x800[Depth];
-	        } else if(!(VBFlags & CRT1_LCDA)) {
-	           ModeIndex = ModeIndex_1280x800[Depth];
-	        }
-	     }
-	  } else if(VDisplay == 720) {
-	     if((VBFlags & CRT1_LCDA) && (LCDwidth == 1280) && (LCDheight == 720)) {
-	        ModeIndex = ModeIndex_1280x720[Depth];
-	     } else if(!(VBFlags & CRT1_LCDA)) {
-	        ModeIndex = ModeIndex_1280x720[Depth];
+          switch(VDisplay) {
+	  case 720:
+	     ModeIndex = ModeIndex_1280x720[Depth];
+	     break;
+	  case 768:
+	     if(VGAEngine == SIS_300_VGA) {
+	        ModeIndex = ModeIndex_300_1280x768[Depth];
+	     } else {
+	        ModeIndex = ModeIndex_310_1280x768[Depth];
 	     }
-	  } else if(!(VBFlags & CRT1_LCDA)) {
-             if(VDisplay == 960) ModeIndex = ModeIndex_1280x960[Depth];
-	     else if(VDisplay == 768) {
-	        if(VGAEngine == SIS_300_VGA) {
-	           ModeIndex = ModeIndex_300_1280x768[Depth];
-	        } else {
-	           ModeIndex = ModeIndex_310_1280x768[Depth];
-	        }
+	     break;
+	  case 800:
+	     if(VGAEngine == SIS_315_VGA) {
+	        ModeIndex = ModeIndex_1280x800[Depth];
 	     }
+	     break;
+	  case 960:
+	     ModeIndex = ModeIndex_1280x960[Depth];
+	     break;
+	  case 1024:
+	     ModeIndex = ModeIndex_1280x1024[Depth];
+	     break;
 	  }
           break;
      case 1360:
           if(VDisplay == 768) ModeIndex = ModeIndex_1360x768[Depth];
-          if(!(VBFlags & CRT1_LCDA)) {
-	     if(VGAEngine == SIS_300_VGA) {
-	        if(VDisplay == 1024) ModeIndex = ModeIndex_300_1360x1024[Depth];
-             }
-	  }
+	  if(VGAEngine == SIS_300_VGA) {
+	     if(VDisplay == 1024) ModeIndex = ModeIndex_300_1360x1024[Depth];
+          }
           break;
      case 1400:
           if(VGAEngine == SIS_315_VGA) {
 	     if(VDisplay == 1050) {
-	        if((VBFlags & CRT1_LCDA) &&
-	           (((LCDwidth == 1400) && (LCDheight == 1050)) ||
-		    ((LCDwidth == 1600) && (LCDheight == 1200)))) {
-	           ModeIndex = ModeIndex_1400x1050[Depth];
-	        } else if(!(VBFlags & CRT1_LCDA)) {
-	           ModeIndex = ModeIndex_1400x1050[Depth];
-	        }
+	        ModeIndex = ModeIndex_1400x1050[Depth];
 	     }
 	  }
           break;
@@ -729,28 +679,25 @@
 	  }
           break;
      case 1920:
-          if(!(VBFlags & CRT1_LCDA)) {
-	     if(VGAEngine == SIS_315_VGA) {
-	        if(VDisplay == 1080) ModeIndex = ModeIndex_1920x1080[Depth];
-	     }
-             if(VDisplay == 1440) ModeIndex = ModeIndex_1920x1440[Depth];
+          if(VDisplay == 1440)    ModeIndex = ModeIndex_1920x1440[Depth];
+	  else if(VGAEngine == SIS_315_VGA) {
+	     if(VDisplay == 1080) ModeIndex = ModeIndex_1920x1080[Depth];
 	  }
           break;
      case 2048:
-          if(!(VBFlags & CRT1_LCDA)) {
-             if(VDisplay == 1536) {
-                if(VGAEngine == SIS_300_VGA) {
-	            ModeIndex = ModeIndex_300_2048x1536[Depth];
-  	        } else {
-	            ModeIndex = ModeIndex_310_2048x1536[Depth];
-                }
-	     }
+          if(VDisplay == 1536) {
+             if(VGAEngine == SIS_300_VGA) {
+	         ModeIndex = ModeIndex_300_2048x1536[Depth];
+  	     } else {
+	         ModeIndex = ModeIndex_310_2048x1536[Depth];
+             }
 	  }
           break;
    }
 
    return(ModeIndex);
 }
+#endif
 
 USHORT
 SiS_GetModeID_LCD(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay,
@@ -783,7 +730,7 @@
 	case 512:
 	     if(CustomT != CUT_PANEL848) {
 	        if(!((VGAEngine == SIS_300_VGA) && (VBFlags & VB_TRUMPION))) {
-		   if(LCDwidth != 1024 || LCDheight != 600) {
+		   if(LCDwidth >= 1024 && LCDwidth != 1152 && LCDheight >= 768) {
 		      if(VDisplay == 384) {
 		         ModeIndex = ModeIndex_512x384[Depth];
 		      }
@@ -826,9 +773,6 @@
 	        if((VDisplay == 768) && (LCDheight == 768)) {
 		   ModeIndex = ModeIndex_310_1280x768[Depth];
 		}
-		if((VDisplay == 800) && (LCDheight == 800)) {
-		   ModeIndex = ModeIndex_310_1280x768[Depth];
-		}
 	     }
 	     break;
 	case 1360:
@@ -862,10 +806,14 @@
 	     else if(VDisplay == 240) ModeIndex = ModeIndex_320x240[Depth];
              break;
      	case 400:
-             if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
+	     if(LCDwidth >= 800 && LCDheight >= 600) {
+                if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
+	     }
              break;
 	case 512:
-	     if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
+	     if(LCDwidth >= 1024 && LCDheight >= 768 && LCDwidth != 1152) {
+	        if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
+	     }
 	     break;
 	case 640:
 	     if(VDisplay == 480)      ModeIndex = ModeIndex_640x480[Depth];
@@ -900,7 +848,8 @@
 	     break;
 	case 960:
 	     if(VGAEngine == SIS_315_VGA) {
-	        if(VDisplay == 540) ModeIndex = ModeIndex_960x540[Depth];
+	        if(VDisplay == 540)      ModeIndex = ModeIndex_960x540[Depth];
+		else if(VDisplay == 600) ModeIndex = ModeIndex_960x600[Depth];
 	     }
 	     break;
 	case 1024:
@@ -915,32 +864,27 @@
 	     }
 	     break;
 	case 1280:
-	     if(VDisplay == 1024) ModeIndex = ModeIndex_1280x1024[Depth];
-	     else if(VDisplay == 768) {
-		if((LCDheight == 768) ||  (LCDwidth == 1680) ||
-		   (VBFlags & VB_SISTMDS)) {
-		   if(VGAEngine == SIS_300_VGA) {
-		      ModeIndex = ModeIndex_300_1280x768[Depth];
-		   } else {
-		      ModeIndex = ModeIndex_310_1280x768[Depth];
-		   }
-		}
-	     } else if(VDisplay == 960) {
-	        if((LCDheight == 960) || (VBFlags & VB_SISTMDS)) {
-		   ModeIndex = ModeIndex_1280x960[Depth];
+	     switch(VDisplay) {
+	     case 720:
+	        ModeIndex = ModeIndex_1280x720[Depth];
+	     case 768:
+	        if(VGAEngine == SIS_300_VGA) {
+		   ModeIndex = ModeIndex_300_1280x768[Depth];
+		} else {
+		   ModeIndex = ModeIndex_310_1280x768[Depth];
 		}
-	     } else if(VGAEngine == SIS_315_VGA) {
-	        if(VDisplay == 800) {
-		   if((LCDheight == 800) || (LCDwidth == 1680) ||
-		      (VBFlags & VB_SISTMDS)) {
-		      ModeIndex = ModeIndex_1280x800[Depth];
-		   }
-		} else if(VDisplay == 720) {
-		   if((LCDheight == 720) || (LCDwidth == 1680) || (LCDwidth == 1400) ||
-		      (VBFlags & VB_SISTMDS)) {
-		      ModeIndex = ModeIndex_1280x720[Depth];
-		   }
+		break;
+	     case 800:
+	        if(VGAEngine == SIS_315_VGA) {
+		   ModeIndex = ModeIndex_1280x800[Depth];
 		}
+		break;
+	     case 960:
+	        ModeIndex = ModeIndex_1280x960[Depth];
+		break;
+	     case 1024:
+	        ModeIndex = ModeIndex_1280x1024[Depth];
+		break;
 	     }
 	     break;
 	case 1360:
@@ -950,27 +894,27 @@
 	     break;
 	case 1400:
 	     if(VGAEngine == SIS_315_VGA) {
-	        if(VBFlags & (VB_301B | VB_301C | VB_302B | VB_302LV | VB_302ELV)) {
-		   if((LCDwidth == 1400) || (LCDwidth == 1600) || (LCDwidth == 1680)) {
-		      ModeIndex = ModeIndex_1400x1050[Depth];
-		   }
+	        if(VBFlags & (VB_301C | VB_302LV | VB_302ELV)) {
+		   if(VDisplay == 1050) ModeIndex = ModeIndex_1400x1050[Depth];
 		}
 	     }
 	     break;
 	case 1600:
 	     if(VGAEngine == SIS_315_VGA) {
-	        if(VBFlags & (VB_301C | VB_302B | VB_302LV | VB_302ELV)) {
+	        if(VBFlags & (VB_301C | VB_302LV | VB_302ELV)) {
 	           if(VDisplay == 1200) ModeIndex = ModeIndex_1600x1200[Depth];
 		}
 	     }
 	     break;
+#ifndef VB_FORBID_CRT2LCD_OVER_1600
 	case 1680:
 	     if(VGAEngine == SIS_315_VGA) {
-	        if(VBFlags & (VB_301C | VB_302B | VB_302LV | VB_302ELV)) {
+	        if(VBFlags & (VB_301C | VB_302LV | VB_302ELV)) {
 	           if(VDisplay == 1050) ModeIndex = ModeIndex_1680x1050[Depth];
 		}
 	     }
 	     break;
+#endif
       }
    }
 
@@ -1030,8 +974,7 @@
 	case 720:
 	     if((!(VBFlags & TV_HIVISION)) && (!((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I)))) {
                 if(VDisplay == 480) {
-		   /* if((VBFlags & TV_YPBPR) || (VBFlags & (TV_NTSC | TV_PALM))) */
-                      ModeIndex = ModeIndex_720x480[Depth];
+                   ModeIndex = ModeIndex_720x480[Depth];
                 } else if(VDisplay == 576) {
 		   if( ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR750P)) ||
 		       ((!(VBFlags & (TV_YPBPR | TV_PALM))) && (VBFlags & TV_PAL)) )
@@ -1055,6 +998,15 @@
 		}
 	     }
 	     break;
+	case 960:
+	     if(VGAEngine == SIS_315_VGA) {
+	        if(VDisplay == 600) {
+		   if((VBFlags & TV_HIVISION) || ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I))) {
+		      ModeIndex = ModeIndex_960x600[Depth];
+		   }
+		}
+	     }
+	     break;
 	case 1024:
 	     if(VDisplay == 768) {
 		if(VBFlags & (VB_301B|VB_301C|VB_302B|VB_301LV|VB_302LV|VB_302ELV)) {
@@ -1126,7 +1078,8 @@
 		break;
 	case 960:
 		if(VGAEngine == SIS_315_VGA) {
-		   if(VDisplay == 540) ModeIndex = ModeIndex_960x540[Depth];
+		   if(VDisplay == 540)      ModeIndex = ModeIndex_960x540[Depth];
+		   else if(VDisplay == 600) ModeIndex = ModeIndex_960x600[Depth];
 		}
 		break;
 	case 1024:
@@ -1407,6 +1360,8 @@
    case SIS_741:
    case SIS_660:
    case SIS_760:
+   case SIS_761:
+   case SIS_340:
       SiS_SetReg(SiS_Pr->SiS_P3c4,0x20,0xa1);
       /*  - Enable 2D (0x40)
        *  - Enable 3D (0x02)
@@ -1477,6 +1432,8 @@
    case SIS_741:
    case SIS_660:
    case SIS_760:
+   case SIS_761:
+   case SIS_340:
         temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
       	temp = (temp & 0xe0) >> 5;
       	if((temp >= 2) && (temp <= 3)) 	SiS_Pr->SiS_IF_DEF_LVDS = 1;
@@ -1515,7 +1472,10 @@
    UCHAR  *ROMAddr  = HwInfo->pjVirtualRomBase;
    USHORT romversoffs, romvmaj = 1, romvmin = 0;
 
-   if(HwInfo->jChipType >= SIS_661) {
+   if(HwInfo->jChipType >= SIS_761) {
+      /* I very much assume 761 and 340 will use new layout */
+      return TRUE;
+   } else if(HwInfo->jChipType >= SIS_661) {
       if((ROMAddr[0x1a] == 'N') &&
          (ROMAddr[0x1b] == 'e') &&
          (ROMAddr[0x1c] == 'w') &&
@@ -1569,14 +1529,21 @@
          /* 315/330 series stick to the standard(s) */
 	 SiS_Pr->SiS_UseROM = TRUE;
 	 if((SiS_Pr->SiS_ROMNew = SiSDetermineROMLayout661(SiS_Pr, HwInfo))) {
+	    SiS_Pr->SiS_EMIOffset = 14;
+	    SiS_Pr->SiS661LCD2TableSize = 36;
 	    /* Find out about LCD data table entry size */
 	    if((romptr = SISGETROMW(0x0102))) {
 	       if(ROMAddr[romptr + (32 * 16)] == 0xff)
 	          SiS_Pr->SiS661LCD2TableSize = 32;
 	       else if(ROMAddr[romptr + (34 * 16)] == 0xff)
 	          SiS_Pr->SiS661LCD2TableSize = 34;
-	       else if(ROMAddr[romptr + (36 * 16)] == 0xff)
-	          SiS_Pr->SiS661LCD2TableSize = 36;  /* 0.94 final */
+	       else if(ROMAddr[romptr + (36 * 16)] == 0xff)	   /* 0.94 */
+	          SiS_Pr->SiS661LCD2TableSize = 36;
+	       else if( (ROMAddr[romptr + (38 * 16)] == 0xff) ||   /* 2.00.00 - 2.02.00 */
+	       	 	(ROMAddr[0x6F] & 0x01) ) {		   /* 2.03.00+ */
+		  SiS_Pr->SiS661LCD2TableSize = 38;
+		  SiS_Pr->SiS_EMIOffset = 16;
+	       }
 	    }
 	 }
       }
@@ -1661,7 +1628,7 @@
 void
 SiS_GetVBType(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
-  USHORT flag=0, rev=0, nolcd=0;
+  USHORT flag=0, rev=0, nolcd=0, p4_0f, p4_25, p4_27;
 
   SiS_Pr->SiS_VBType = 0;
 
@@ -1697,13 +1664,27 @@
 	SiS_Pr->SiS_VBType = VB_SIS301LV;
      }
   }
+  if(SiS_Pr->SiS_VBType & (VB_301C | VB_301LV | VB_302LV | VB_302ELV)) {
+     p4_0f = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x0f);
+     p4_25 = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x25);
+     p4_27 = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x27);
+     SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x0f,0x7f);
+     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x25,0x08);
+     SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x27,0xfd);
+     if(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x08) {
+        SiS_Pr->SiS_VBType |= VB_UMC;
+     }
+     SiS_SetReg(SiS_Pr->SiS_Part4Port,0x27,p4_27);
+     SiS_SetReg(SiS_Pr->SiS_Part4Port,0x25,p4_25);
+     SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0f,p4_0f);
+  }
 }
 
 /*********************************************/
 /*           HELPER: Check RAM size          */
 /*********************************************/
 
-#ifndef LINUX_XF86
+#ifdef LINUX_KERNEL
 static BOOLEAN
 SiS_CheckMemorySize(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
                     USHORT ModeNo, USHORT ModeIdIndex)
@@ -1743,7 +1724,10 @@
    if((*SiS_Pr->pSiS_SoftSetting) & SoftDRAMType) {
      data = (*SiS_Pr->pSiS_SoftSetting) & 0x03;
    } else {
-     if(HwInfo->jChipType >= SIS_661) {
+     if(HwInfo->jChipType >= SIS_340) {
+        /* TODO */
+	data = 0;
+     } if(HwInfo->jChipType >= SIS_661) {
         data = SiS_GetReg(SiS_Pr->SiS_P3d4,0x78) & 0x07;
 	if(SiS_Pr->SiS_ROMNew) {
 	   data = ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x78) & 0xc0) >> 6);
@@ -1771,10 +1755,10 @@
    return data;
 }
 
-USHORT
+static USHORT
 SiS_GetMCLK(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
-  UCHAR  *ROMAddr  = HwInfo->pjVirtualRomBase;
+  UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
   USHORT index;
 
   index = SiS_Get310DRAMType(SiS_Pr, HwInfo);
@@ -1796,26 +1780,26 @@
 /*           HELPER: ClearBuffer             */
 /*********************************************/
 
-#ifndef LINUX_XF86
+#ifdef LINUX_KERNEL
 static void
 SiS_ClearBuffer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
 {
-  UCHAR   *VideoMemoryAddress = HwInfo->pjVideoMemoryAddress;
-  ULONG   AdapterMemorySize  = (ULONG)HwInfo->ulVideoMemorySize;
-  USHORT  *pBuffer;
+  UCHAR SISIOMEMTYPE *VideoMemoryAddress = HwInfo->pjVideoMemoryAddress;
+  ULONG  AdapterMemorySize = HwInfo->ulVideoMemorySize;
+  USHORT SISIOMEMTYPE *pBuffer;
   int i;
 
   if(SiS_Pr->SiS_ModeType >= ModeEGA) {
      if(ModeNo > 0x13) {
         SiS_SetMemory(VideoMemoryAddress, AdapterMemorySize, 0);
      } else {
-        pBuffer = (USHORT *)VideoMemoryAddress;
-        for(i=0; i<0x4000; i++) pBuffer[i] = 0x0000;
+        pBuffer = (USHORT SISIOMEMTYPE *)VideoMemoryAddress;
+        for(i=0; i<0x4000; i++) writew(0x0000, &pBuffer[i]);
      }
   } else {
      if(SiS_Pr->SiS_ModeType < ModeCGA) {
-        pBuffer = (USHORT *)VideoMemoryAddress;
-        for(i=0; i<0x4000; i++) pBuffer[i] = 0x0720;
+        pBuffer = (USHORT SISIOMEMTYPE *)VideoMemoryAddress;
+        for(i=0; i<0x4000; i++) writew(0x0720, &pBuffer[i]);
      } else {
         SiS_SetMemory(VideoMemoryAddress, 0x8000, 0);
      }
@@ -1927,25 +1911,26 @@
 static void
 SiS_SetupCR5x(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
-   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-      if(IS_SIS650) {
-	 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f);
-	 if(IS_SIS651) SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x51,0x20);
-	 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7);
-      } else if(IS_SIS661741660760) {
-         SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x61,0xf7);
-	 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f);
-	 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7);
-	 if(!SiS_Pr->SiS_ROMNew) {
-	    SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x3a,0xef);
-	 }
-      }
-   }
+    if(IS_SIS650) {
+       if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+	  SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f);
+	  if(IS_SIS651) SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x51,0x20);
+	  SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7);
+       }
+    } else if(IS_SIS661741660760) {
+       SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x61,0xf7);
+       SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f);
+       SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7);
+       if(!SiS_Pr->SiS_ROMNew) {
+	  SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x3a,0xef);
+       }
+    }
 }
 
 static void
 SiS_HandleCRT1(SiS_Private *SiS_Pr)
 {
+  /* Enable CRT1 gating */
   SiS_SetRegAND(SiS_Pr->SiS_P3d4,SiS_Pr->SiS_MyCR63,0xbf);
 #if 0
   if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x15) & 0x01)) {
@@ -1978,7 +1963,7 @@
     	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
   }
 
-  index = (modeflag & ModeInfoFlag) - ModeEGA;
+  index = (modeflag & ModeTypeMask) - ModeEGA;
   if(index < 0) index = 0;
   return(ColorDepth[index]);
 }
@@ -2736,7 +2721,7 @@
      data2 = (data2 & 0xC0) >> 5;
      data2 <<= 8;
 
-#ifndef LINUX_XF86
+#ifdef LINUX_KERNEL
      SiS_SetRegLong(0xcf8,0x80000050);
      eax = SiS_GetRegLong(0xcfc);
      eax &= 0xfffff9ff;
@@ -2758,7 +2743,7 @@
      data2 = (data2 & 0x0f00) | ((data2 & 0x3000) >> 8);
      data2 <<= 20;
 
-#ifndef LINUX_XF86
+#ifdef LINUX_KERNEL
      SiS_SetRegLong(0xcf8,0x800000A0);
      eax = SiS_GetRegLong(0xcfc);
      eax &= 0x00ffffff;
@@ -2777,7 +2762,7 @@
      data2 = (data2 & 0xf0) >> 4;
      data2 <<= 24;
 
-#ifndef LINUX_XF86
+#ifdef LINUX_KERNEL
      SiS_SetRegLong(0xcf8,0x80000050);
      eax = SiS_GetRegLong(0xcfc);
      eax &= 0xf0ffffff;
@@ -2795,7 +2780,7 @@
      data2 &= 0x0f;
      data2 <<= 24;
 
-#ifndef LINUX_XF86
+#ifdef LINUX_KERNEL
      SiS_SetRegLong(0xcf8,0x800000A0);
      eax = SiS_GetRegLong(0xcfc);
      eax &= 0xf0ffffff;
@@ -3079,6 +3064,8 @@
 	}
      }
      SiS_SetReg(SiS_Pr->SiS_P3c4,0x17,data);
+  } else if(HwInfo->jChipType == SIS_340) {
+     /* TODO */
   }
 #endif
 
@@ -3327,7 +3314,7 @@
 
   SiS_LoadDAC(SiS_Pr, HwInfo, ModeNo, ModeIdIndex);
 
-#ifndef LINUX_XF86
+#ifdef LINUX_KERNEL
   if(SiS_Pr->SiS_flag_clearbuffer) {
      SiS_ClearBuffer(SiS_Pr,HwInfo,ModeNo);
   }
@@ -3340,7 +3327,7 @@
 }
 
 /*********************************************/
-/*         HELPER: RESET VIDEO BRIDGE        */
+/*       HELPER: VIDEO BRIDGE PROG CLK       */
 /*********************************************/
 
 static void
@@ -3349,17 +3336,16 @@
    UCHAR  *ROMAddr  = HwInfo->pjVirtualRomBase;
    USHORT temp;
 
+   /* VB programming clock */
    if(SiS_Pr->SiS_UseROM) {
       if(HwInfo->jChipType < SIS_330) {
          temp = ROMAddr[VB310Data_1_2_Offset] | 0x40;
 	 if(SiS_Pr->SiS_ROMNew) temp = ROMAddr[0x80] | 0x40;
-         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,temp);
+	 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,temp);
       } else if(HwInfo->jChipType >= SIS_661) {
-         temp = ROMAddr[0x7e];
-         if(SiS_Pr->SiS_ROMNew) temp = ROMAddr[0x80];
-         if(HwInfo->jChipType >= SIS_660)                  temp |= 0x40;
-         else if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x7b) >= 100) temp |= 0x40;
-         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,temp);
+         temp = ROMAddr[0x7e] | 0x40;
+         if(SiS_Pr->SiS_ROMNew) temp = ROMAddr[0x80] | 0x40;
+	 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,temp);
       }
    }
 }
@@ -3453,7 +3439,7 @@
    USHORT  ModeIdIndex;
    SISIOADDRESS BaseAddr = HwInfo->ulIOAddress;
    unsigned char backupreg=0;
-#ifndef LINUX_XF86
+#ifdef LINUX_KERNEL
    USHORT  KeepLockReg;
    ULONG   temp;
 
@@ -3482,13 +3468,13 @@
    SiS_Pr->SiS_flag_clearbuffer = 0;
 
    if(!SiS_Pr->UseCustomMode) {
-#ifndef LINUX_XF86
+#ifdef LINUX_KERNEL
       if(!(ModeNo & 0x80)) SiS_Pr->SiS_flag_clearbuffer = 1;
 #endif
       ModeNo &= 0x7f;
    }
 
-#ifndef LINUX_XF86
+#ifdef LINUX_KERNEL
    KeepLockReg = SiS_GetReg(SiS_Pr->SiS_P3c4,0x05);
 #endif
    SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x86);
@@ -3523,7 +3509,7 @@
    SiS_GetLCDResInfo(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
    SiS_SetLowModeTest(SiS_Pr, ModeNo, HwInfo);
 
-#ifndef LINUX_XF86
+#ifdef LINUX_KERNEL
    /* 3. Check memory size (Kernel framebuffer driver only) */
    temp = SiS_CheckMemorySize(SiS_Pr, HwInfo, ModeNo, ModeIdIndex);
    if(!temp) return(0);
@@ -3612,7 +3598,7 @@
    }
 #endif
 
-#ifndef LINUX_XF86  /* We never lock registers in XF86 */
+#ifdef LINUX_KERNEL  /* We never lock registers in XF86 */
    if(KeepLockReg == 0xA1) SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x86);
    else SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x00);
 #endif
@@ -3630,27 +3616,28 @@
 SiSBIOSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
                DisplayModePtr mode, BOOLEAN IsCustom)
 {
-   SISPtr  pSiS = SISPTR(pScrn);
-   UShort  ModeNo=0;
+   SISPtr pSiS = SISPTR(pScrn);
+   UShort ModeNo = 0;
 
    SiS_Pr->UseCustomMode = FALSE;
 
    if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) {
 
-         xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting custom mode %dx%d\n",
+      xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting custom mode %dx%d\n",
 	 	SiS_Pr->CHDisplay,
 		(mode->Flags & V_INTERLACE ? SiS_Pr->CVDisplay * 2 :
 		   (mode->Flags & V_DBLSCAN ? SiS_Pr->CVDisplay / 2 :
 		      SiS_Pr->CVDisplay)));
 
-	 return(SiSSetMode(SiS_Pr, HwInfo, pScrn, ModeNo, TRUE));
+   } else {
 
-   }
+      /* Don't need vbflags here; checks done earlier */
+      ModeNo = SiS_GetModeNumber(pScrn, mode, 0);
+      if(!ModeNo) return FALSE;
 
-   ModeNo = SiS_CalcModeIndex(pScrn, mode, pSiS->VBFlags, pSiS->HaveCustomModes);
-   if(!ModeNo) return FALSE;
+      xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting standard mode 0x%x\n", ModeNo);
 
-   xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting standard mode 0x%x\n", ModeNo);
+   }
 
    return(SiSSetMode(SiS_Pr, HwInfo, pScrn, ModeNo, TRUE));
 }
@@ -3675,9 +3662,8 @@
    SiS_Pr->UseCustomMode = FALSE;
 
    /* Remember: Custom modes for CRT2 are ONLY supported
-    * 		-) on 315/330 series,
-    *           -) on the 30x/B/C, and
-    *           -) if CRT2 is LCD or VGA
+    *     -) on the 30x/B/C, and
+    *     -) if CRT2 is LCD or VGA, or CRT1 is LCDA
     */
 
    if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) {
@@ -3686,13 +3672,7 @@
 
    } else {
 
-         BOOLEAN havecustommodes = pSiS->HaveCustomModes;
-
-#ifdef SISMERGED
-	 if(pSiS->MergedFB) havecustommodes = pSiS->HaveCustomModes2;
-#endif
-
-         ModeNo = SiS_CalcModeIndex(pScrn, mode, pSiS->VBFlags, havecustommodes);
+         ModeNo = SiS_GetModeNumber(pScrn, mode, 0);
          if(!ModeNo) return FALSE;
 
    }
@@ -3731,7 +3711,7 @@
    }
 #endif
 
-   /* We don't clear the buffer under X */
+   /* We don't clear the buffer in X */
    SiS_Pr->SiS_flag_clearbuffer=0;
 
    if(SiS_Pr->UseCustomMode) {
@@ -3870,7 +3850,7 @@
 
    } else {
 
-         ModeNo = SiS_CalcModeIndex(pScrn, mode, pSiS->VBFlags, pSiS->HaveCustomModes);
+         ModeNo = SiS_GetModeNumber(pScrn, mode, 0);
          if(!ModeNo) return FALSE;
 
          xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
@@ -3889,7 +3869,7 @@
    SiSSetLVDSetc(SiS_Pr, HwInfo);
    SiSDetermineROMUsage(SiS_Pr, HwInfo);
 
-   /* We don't clear the buffer under X */
+   /* We don't clear the buffer in X */
    SiS_Pr->SiS_flag_clearbuffer = 0;
 
    SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x86);
@@ -4267,18 +4247,12 @@
 #endif
 }
 
-/* ================ XFREE86 ================= */
-
-/* Helper functions */
-
 #ifdef LINUX_XF86
 
-USHORT
-SiS_CheckBuildCustomMode(ScrnInfoPtr pScrn, DisplayModePtr mode, int VBFlags)
+void
+SiS_MakeClockRegs(ScrnInfoPtr pScrn, int clock, UCHAR *p2b, UCHAR *p2c)
 {
-   SISPtr pSiS = SISPTR(pScrn);
-   int    out_n, out_dn, out_div, out_sbit, out_scale;
-   int    depth = pSiS->CurrentLayout.bitsPerPixel;
+   int          out_n, out_dn, out_div, out_sbit, out_scale;
    unsigned int vclk[5];
 
 #define Midx         0
@@ -4287,6 +4261,50 @@
 #define Pidx         3
 #define PSNidx       4
 
+   if(SiS_compute_vclk(clock, &out_n, &out_dn, &out_div, &out_sbit, &out_scale)) {
+      (*p2b) = (out_div == 2) ? 0x80 : 0x00;
+      (*p2b) |= ((out_n - 1) & 0x7f);
+      (*p2c) = (out_dn - 1) & 0x1f;
+      (*p2c) |= (((out_scale - 1) & 3) << 5);
+      (*p2c) |= ((out_sbit & 0x01) << 7);
+#ifdef TWDEBUG
+      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Clock %d: n %d dn %d div %d sb %d sc %d\n",
+        	 clock, out_n, out_dn, out_div, out_sbit, out_scale);
+#endif
+   } else {
+      SiSCalcClock(pScrn, clock, 2, vclk);
+      (*p2b) = (vclk[VLDidx] == 2) ? 0x80 : 0x00;
+      (*p2b) |= (vclk[Midx] - 1) & 0x7f;
+      (*p2c) = (vclk[Nidx] - 1) & 0x1f;
+      if(vclk[Pidx] <= 4) {
+         /* postscale 1,2,3,4 */
+         (*p2c) |= ((vclk[Pidx] - 1) & 3) << 5;
+      } else {
+         /* postscale 6,8 */
+         (*p2c) |= (((vclk[Pidx] / 2) - 1) & 3) << 5;
+	 (*p2c) |= 0x80;
+      }
+#ifdef TWDEBUG
+      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Clock %d: n %d dn %d div %d sc %d\n",
+        	 clock, vclk[Midx], vclk[Nidx], vclk[VLDidx], vclk[Pidx]);
+#endif
+   }
+}
+
+#endif
+
+/* ================ XFREE86/X.ORG ================= */
+
+/* Helper functions */
+
+#ifdef LINUX_XF86
+
+USHORT
+SiS_CheckBuildCustomMode(ScrnInfoPtr pScrn, DisplayModePtr mode, int VBFlags)
+{
+   SISPtr pSiS = SISPTR(pScrn);
+   int    depth = pSiS->CurrentLayout.bitsPerPixel;
+
    pSiS->SiS_Pr->CModeFlag = 0;
    
    pSiS->SiS_Pr->CDClock = mode->Clock;
@@ -4322,34 +4340,7 @@
    pSiS->SiS_Pr->CVBlankStart = pSiS->SiS_Pr->CVSyncStart - 1;
    pSiS->SiS_Pr->CVBlankEnd = pSiS->SiS_Pr->CVTotal;
 
-   if(SiS_compute_vclk(pSiS->SiS_Pr->CDClock, &out_n, &out_dn, &out_div, &out_sbit, &out_scale)) {
-      pSiS->SiS_Pr->CSR2B = (out_div == 2) ? 0x80 : 0x00;
-      pSiS->SiS_Pr->CSR2B |= ((out_n - 1) & 0x7f);
-      pSiS->SiS_Pr->CSR2C = (out_dn - 1) & 0x1f;
-      pSiS->SiS_Pr->CSR2C |= (((out_scale - 1) & 3) << 5);
-      pSiS->SiS_Pr->CSR2C |= ((out_sbit & 0x01) << 7);
-#ifdef TWDEBUG
-      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Clock %d: n %d dn %d div %d sb %d sc %d\n",
-        	pSiS->SiS_Pr->CDClock, out_n, out_dn, out_div, out_sbit, out_scale);
-#endif
-   } else {
-      SiSCalcClock(pScrn, pSiS->SiS_Pr->CDClock, 2, vclk);
-      pSiS->SiS_Pr->CSR2B = (vclk[VLDidx] == 2) ? 0x80 : 0x00;
-      pSiS->SiS_Pr->CSR2B |= (vclk[Midx] - 1) & 0x7f;
-      pSiS->SiS_Pr->CSR2C = (vclk[Nidx] - 1) & 0x1f;
-      if(vclk[Pidx] <= 4) {
-         /* postscale 1,2,3,4 */
-         pSiS->SiS_Pr->CSR2C |= ((vclk[Pidx] - 1) & 3) << 5;
-      } else {
-         /* postscale 6,8 */
-         pSiS->SiS_Pr->CSR2C |= (((vclk[Pidx] / 2) - 1) & 3) << 5;
-	 pSiS->SiS_Pr->CSR2C |= 0x80;
-      }
-#ifdef TWDEBUG
-      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Clock %d: n %d dn %d div %d sc %d\n",
-        	pSiS->SiS_Pr->CDClock, vclk[Midx], vclk[Nidx], vclk[VLDidx], vclk[Pidx]);
-#endif
-   }
+   SiS_MakeClockRegs(pScrn, pSiS->SiS_Pr->CDClock, &pSiS->SiS_Pr->CSR2B, &pSiS->SiS_Pr->CSR2C);
 
    pSiS->SiS_Pr->CSRClock = (pSiS->SiS_Pr->CDClock / 1000) + 1;
 
@@ -4407,7 +4398,41 @@
    return 1;
 }
 
-/* Build a list of supported modes */
+int
+SiS_FindPanelFromDB(SISPtr pSiS, USHORT panelvendor, USHORT panelproduct, int *maxx, int *maxy, int *prefx, int *prefy)
+{
+   int i, j;
+   BOOLEAN done = FALSE;
+
+   i = 0;
+   while((!done) && (SiS_PlasmaTable[i].vendor) && panelvendor) {
+      if(SiS_PlasmaTable[i].vendor == panelvendor) {
+         for(j=0; j<SiS_PlasmaTable[i].productnum; j++) {
+	    if(SiS_PlasmaTable[i].product[j] == panelproduct) {
+	       if(SiS_PlasmaTable[i].maxx && SiS_PlasmaTable[i].maxy) {
+	          (*maxx) = (int)SiS_PlasmaTable[i].maxx;
+		  (*maxy) = (int)SiS_PlasmaTable[i].maxy;
+		  (*prefx) = (int)SiS_PlasmaTable[i].prefx;
+		  (*prefy) = (int)SiS_PlasmaTable[i].prefy;
+		  done = TRUE;
+		  xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
+	       	        "Identified %s, correcting max X res %d, max Y res %d\n",
+			 SiS_PlasmaTable[i].plasmaname,
+		         SiS_PlasmaTable[i].maxx, SiS_PlasmaTable[i].maxy);
+	          break;
+	       }
+ 	    }
+	 }
+      }
+      i++;
+   }
+   return (done) ? 1 : 0;
+}
+
+/* Build a list of supported modes:
+ * Built-in modes for which we have all data are M_T_DEFAULT,
+ * modes derived from DDC or database data are M_T_BUILTIN
+ */
 DisplayModePtr
 SiSBuildBuiltInModeList(ScrnInfoPtr pScrn, BOOLEAN includelcdmodes, BOOLEAN isfordvi)
 {
@@ -4717,27 +4742,6 @@
 	 current->VTotal >>= 1;
       }
 
-#if 0
-      if((backup = xalloc(sizeof(DisplayModeRec)))) {
-         if(!pSiS->backupmodelist) pSiS->backupmodelist = backup;
-	 else {
-	    pSiS->backupmodelist->next = backup;
-	    backup->prev = pSiS->backupmodelist;
-	 }
-	 backup->next = NULL;
-	 backup->HDisplay = current->HDisplay;
-         backup->HSyncStart = current->HSyncStart;
-         backup->HSyncEnd = current->HSyncEnd;
-         backup->HTotal = current->HTotal;
-         backup->VDisplay = current->VDisplay;
-         backup->VSyncStart = current->VSyncStart;
-         backup->VSyncEnd = current->VSyncEnd;
-         backup->VTotal = current->VTotal;
-	 backup->Flags = current->Flags;
-	 backup->Clock = current->Clock;
-      }
-#endif
-
 #ifdef TWDEBUG
       xf86DrvMsg(pScrn->scrnIndex, X_INFO,
       	"Built-in: %s %.2f %d %d %d %d %d %d %d %d\n",
@@ -4781,10 +4785,18 @@
 		     if(!(SiS_PlasmaTable[i].plasmamodes[k] & 0x40)) continue;
 		  }
 
+		  l = SiS_PlasmaTable[i].plasmamodes[k] & 0x3f;
+
+		  if(pSiS->VBFlags & (VB_301|VB_301B|VB_302B|VB_301LV)) {
+		     if(isfordvi) {
+		        if(SiS_PlasmaMode[l].VDisplay > 1024) continue;
+		     }
+		  }
+
 	          if(!(new = xalloc(sizeof(DisplayModeRec)))) return first;
 
                   memset(new, 0, sizeof(DisplayModeRec));
-                  if(!(new->name = xalloc(10))) {
+                  if(!(new->name = xalloc(12))) {
       		     xfree(new);
 		     return first;
                   }
@@ -4798,10 +4810,9 @@
 
 		  pSiS->AddedPlasmaModes = TRUE;
 
-		  l = SiS_PlasmaTable[i].plasmamodes[k] & 0x3f;
-
-	          sprintf(current->name, "%dx%d", SiS_PlasmaMode[l].HDisplay,
-                                                  SiS_PlasmaMode[l].VDisplay);
+		  strcpy(current->name, SiS_PlasmaMode[l].name);
+	          /* sprintf(current->name, "%dx%d", SiS_PlasmaMode[l].HDisplay,
+                                                  SiS_PlasmaMode[l].VDisplay); */
 
                   current->status = MODE_OK;
 
@@ -4849,6 +4860,9 @@
 	          if(current->VDisplay > pSiS->LCDheight)
 		     pSiS->LCDheight = pSiS->SiS_Pr->CP_MaxY = current->VDisplay;
 
+		  xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+		  	"\tAdding \"%s\" to list of built-in modes\n", current->name);
+
                }
 	       done = TRUE;
 	       break;
@@ -4938,12 +4952,12 @@
 
 }
 
-/* Build a list of supported modes */
+/* Translate a mode number into the VESA pendant */
 int
 SiSTranslateToVESA(ScrnInfoPtr pScrn, int modenumber)
 {
-   SISPtr         pSiS = SISPTR(pScrn);
-   int i;
+   SISPtr pSiS = SISPTR(pScrn);
+   int    i = 0;
 
    /* Initialize our pointers */
    if(pSiS->VGAEngine == SIS_300_VGA) {
@@ -4962,15 +4976,48 @@
 
    if(modenumber <= 0x13) return modenumber;
 
-   i = 0;
-   while(pSiS->SiS_Pr->SiS_EModeIDTable[i].Ext_ModeID != 0xff) {
-      if(pSiS->SiS_Pr->SiS_EModeIDTable[i].Ext_ModeID == modenumber) {
-         return (int)pSiS->SiS_Pr->SiS_EModeIDTable[i].Ext_VESAID;
+#ifdef SIS315H
+   if(pSiS->ROM661New) {
+      while(SiS_EModeIDTable661[i].Ext_ModeID != 0xff) {
+         if(SiS_EModeIDTable661[i].Ext_ModeID == modenumber) {
+            return (int)SiS_EModeIDTable661[i].Ext_VESAID;
+         }
+         i++;
       }
-      i++;
+   } else {
+#endif
+      while(pSiS->SiS_Pr->SiS_EModeIDTable[i].Ext_ModeID != 0xff) {
+         if(pSiS->SiS_Pr->SiS_EModeIDTable[i].Ext_ModeID == modenumber) {
+            return (int)pSiS->SiS_Pr->SiS_EModeIDTable[i].Ext_VESAID;
+         }
+         i++;
+      }
+#ifdef SIS315H
    }
+#endif
    return -1;
 }
+
+/* Translate a new BIOS mode number into the driver's pendant */
+int
+SiSTranslateToOldMode(int modenumber)
+{
+#ifdef SIS315H
+   int    i = 0;
+
+   while(SiS_EModeIDTable661[i].Ext_ModeID != 0xff) {
+      if(SiS_EModeIDTable661[i].Ext_ModeID == modenumber) {
+         if(SiS_EModeIDTable661[i].Ext_MyModeID)
+            return (int)SiS_EModeIDTable661[i].Ext_MyModeID;
+	 else
+	    return modenumber;
+      }
+      i++;
+   }
+#endif
+   return modenumber;
+}
+
 #endif  /* Xfree86 */
 
 #ifdef LINUX_KERNEL
diff -Nru a/drivers/video/sis/init.h b/drivers/video/sis/init.h
--- a/drivers/video/sis/init.h	2005-03-01 23:39:09 -08:00
+++ b/drivers/video/sis/init.h	2005-03-01 23:39:09 -08:00
@@ -35,7 +35,7 @@
  * * 3) The name of the author may not be used to endorse or promote products
  * *    derived from this software without specific prior written permission.
  * *
- * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR
+ * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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,
@@ -54,21 +54,16 @@
 #define _INIT_
 
 #include "osdef.h"
-
 #include "initdef.h"
-#include "vgatypes.h"
-#include "vstruct.h"
 
 #ifdef LINUX_XF86
-#include "xf86.h"
-#include "xf86Pci.h"
-#include "xf86PciInfo.h"
-#include "xf86_OSproc.h"
 #include "sis.h"
 #include "sis_regs.h"
 #endif
 
 #ifdef LINUX_KERNEL
+#include "vgatypes.h"
+#include "vstruct.h"
 #ifdef SIS_CP
 #undef SIS_CP
 #endif
@@ -85,43 +80,44 @@
 #endif
 
 /* Mode numbers */
-const USHORT  ModeIndex_320x200[]      = {0x59, 0x41, 0x00, 0x4f};
-const USHORT  ModeIndex_320x240[]      = {0x50, 0x56, 0x00, 0x53};
-const USHORT  ModeIndex_320x240_FSTN[] = {0x5a, 0x5b, 0x00, 0x00};  /* FSTN */
-const USHORT  ModeIndex_400x300[]      = {0x51, 0x57, 0x00, 0x54};
-const USHORT  ModeIndex_512x384[]      = {0x52, 0x58, 0x00, 0x5c};
-const USHORT  ModeIndex_640x400[]      = {0x2f, 0x5d, 0x00, 0x5e};
-const USHORT  ModeIndex_640x480[]      = {0x2e, 0x44, 0x00, 0x62};
-const USHORT  ModeIndex_720x480[]      = {0x31, 0x33, 0x00, 0x35};
-const USHORT  ModeIndex_720x576[]      = {0x32, 0x34, 0x00, 0x36};
-const USHORT  ModeIndex_768x576[]      = {0x5f, 0x60, 0x00, 0x61};
-const USHORT  ModeIndex_800x480[]      = {0x70, 0x7a, 0x00, 0x76};
-const USHORT  ModeIndex_800x600[]      = {0x30, 0x47, 0x00, 0x63};
-const USHORT  ModeIndex_848x480[]      = {0x39, 0x3b, 0x00, 0x3e};
-const USHORT  ModeIndex_856x480[]      = {0x3f, 0x42, 0x00, 0x45};
-const USHORT  ModeIndex_960x540[]      = {0x1d, 0x1e, 0x00, 0x1f};  /* 315 series only */
-const USHORT  ModeIndex_1024x768[]     = {0x38, 0x4a, 0x00, 0x64};
-const USHORT  ModeIndex_1024x576[]     = {0x71, 0x74, 0x00, 0x77};
-const USHORT  ModeIndex_1024x600[]     = {0x20, 0x21, 0x00, 0x22};  /* 300 series only */
-const USHORT  ModeIndex_1280x1024[]    = {0x3a, 0x4d, 0x00, 0x65};
-const USHORT  ModeIndex_1280x960[]     = {0x7c, 0x7d, 0x00, 0x7e};
-const USHORT  ModeIndex_1152x768[]     = {0x23, 0x24, 0x00, 0x25};  /* 300 series only */
-const USHORT  ModeIndex_1152x864[]     = {0x29, 0x2a, 0x00, 0x2b};
-const USHORT  ModeIndex_300_1280x768[] = {0x55, 0x5a, 0x00, 0x5b};
-const USHORT  ModeIndex_310_1280x768[] = {0x23, 0x24, 0x00, 0x25};
-const USHORT  ModeIndex_1280x720[]     = {0x79, 0x75, 0x00, 0x78};
-const USHORT  ModeIndex_1280x800[]     = {0x14, 0x15, 0x00, 0x16};
-const USHORT  ModeIndex_1360x768[]     = {0x48, 0x4b, 0x00, 0x4e};
-const USHORT  ModeIndex_300_1360x1024[]= {0x67, 0x6f, 0x00, 0x72};  /* 300 series, BARCO only */
-const USHORT  ModeIndex_1400x1050[]    = {0x26, 0x27, 0x00, 0x28};  /* 315 series only */
-const USHORT  ModeIndex_1680x1050[]    = {0x17, 0x18, 0x00, 0x19};  /* 315 series only */
-const USHORT  ModeIndex_1600x1200[]    = {0x3c, 0x3d, 0x00, 0x66};
-const USHORT  ModeIndex_1920x1080[]    = {0x2c, 0x2d, 0x00, 0x73};  /* 315 series only */
-const USHORT  ModeIndex_1920x1440[]    = {0x68, 0x69, 0x00, 0x6b};
-const USHORT  ModeIndex_300_2048x1536[]= {0x6c, 0x6d, 0x00, 0x00};
-const USHORT  ModeIndex_310_2048x1536[]= {0x6c, 0x6d, 0x00, 0x6e};
+static const USHORT ModeIndex_320x200[]      = {0x59, 0x41, 0x00, 0x4f};
+static const USHORT ModeIndex_320x240[]      = {0x50, 0x56, 0x00, 0x53};
+static const USHORT ModeIndex_320x240_FSTN[] = {0x5a, 0x5b, 0x00, 0x00};  /* FSTN */
+static const USHORT ModeIndex_400x300[]      = {0x51, 0x57, 0x00, 0x54};
+static const USHORT ModeIndex_512x384[]      = {0x52, 0x58, 0x00, 0x5c};
+static const USHORT ModeIndex_640x400[]      = {0x2f, 0x5d, 0x00, 0x5e};
+static const USHORT ModeIndex_640x480[]      = {0x2e, 0x44, 0x00, 0x62};
+static const USHORT ModeIndex_720x480[]      = {0x31, 0x33, 0x00, 0x35};
+static const USHORT ModeIndex_720x576[]      = {0x32, 0x34, 0x00, 0x36};
+static const USHORT ModeIndex_768x576[]      = {0x5f, 0x60, 0x00, 0x61};
+static const USHORT ModeIndex_800x480[]      = {0x70, 0x7a, 0x00, 0x76};
+static const USHORT ModeIndex_800x600[]      = {0x30, 0x47, 0x00, 0x63};
+static const USHORT ModeIndex_848x480[]      = {0x39, 0x3b, 0x00, 0x3e};
+static const USHORT ModeIndex_856x480[]      = {0x3f, 0x42, 0x00, 0x45};
+static const USHORT ModeIndex_960x540[]      = {0x1d, 0x1e, 0x00, 0x1f};  /* 315 series only */
+static const USHORT ModeIndex_960x600[]      = {0x20, 0x21, 0x00, 0x22};  /* 315 series only */
+static const USHORT ModeIndex_1024x768[]     = {0x38, 0x4a, 0x00, 0x64};
+static const USHORT ModeIndex_1024x576[]     = {0x71, 0x74, 0x00, 0x77};
+static const USHORT ModeIndex_1024x600[]     = {0x20, 0x21, 0x00, 0x22};  /* 300 series only */
+static const USHORT ModeIndex_1280x1024[]    = {0x3a, 0x4d, 0x00, 0x65};
+static const USHORT ModeIndex_1280x960[]     = {0x7c, 0x7d, 0x00, 0x7e};
+static const USHORT ModeIndex_1152x768[]     = {0x23, 0x24, 0x00, 0x25};  /* 300 series only */
+static const USHORT ModeIndex_1152x864[]     = {0x29, 0x2a, 0x00, 0x2b};
+static const USHORT ModeIndex_300_1280x768[] = {0x55, 0x5a, 0x00, 0x5b};
+static const USHORT ModeIndex_310_1280x768[] = {0x23, 0x24, 0x00, 0x25};
+static const USHORT ModeIndex_1280x720[]     = {0x79, 0x75, 0x00, 0x78};
+static const USHORT ModeIndex_1280x800[]     = {0x14, 0x15, 0x00, 0x16};
+static const USHORT ModeIndex_1360x768[]     = {0x48, 0x4b, 0x00, 0x4e};
+static const USHORT ModeIndex_300_1360x1024[]= {0x67, 0x6f, 0x00, 0x72};  /* 300 series, BARCO only */
+static const USHORT ModeIndex_1400x1050[]    = {0x26, 0x27, 0x00, 0x28};  /* 315 series only */
+static const USHORT ModeIndex_1680x1050[]    = {0x17, 0x18, 0x00, 0x19};  /* 315 series only */
+static const USHORT ModeIndex_1600x1200[]    = {0x3c, 0x3d, 0x00, 0x66};
+static const USHORT ModeIndex_1920x1080[]    = {0x2c, 0x2d, 0x00, 0x73};  /* 315 series only */
+static const USHORT ModeIndex_1920x1440[]    = {0x68, 0x69, 0x00, 0x6b};
+static const USHORT ModeIndex_300_2048x1536[]= {0x6c, 0x6d, 0x00, 0x00};
+static const USHORT ModeIndex_310_2048x1536[]= {0x6c, 0x6d, 0x00, 0x6e};
 
-const USHORT SiS_DRAMType[17][5]={
+static const USHORT SiS_DRAMType[17][5]={
 	{0x0C,0x0A,0x02,0x40,0x39},
 	{0x0D,0x0A,0x01,0x40,0x48},
 	{0x0C,0x09,0x02,0x20,0x35},
@@ -141,7 +137,7 @@
 	{0x09,0x08,0x01,0x01,0x00}
 };
 
-const USHORT SiS_SDRDRAM_TYPE[13][5] =
+static const USHORT SiS_SDRDRAM_TYPE[13][5] =
 {
 	{ 2,12, 9,64,0x35},
 	{ 1,13, 9,64,0x44},
@@ -158,7 +154,7 @@
 	{ 1, 9, 8, 2,0x00}
 };
 
-const USHORT SiS_DDRDRAM_TYPE[4][5] =
+static const USHORT SiS_DDRDRAM_TYPE[4][5] =
 {
 	{ 2,12, 9,64,0x35},
 	{ 2,12, 8,32,0x31},
@@ -166,7 +162,7 @@
 	{ 2, 9, 8, 4,0x01}
 };
 
-const USHORT SiS_MDA_DAC[] =
+static const USHORT SiS_MDA_DAC[] =
 {
 	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
         0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
@@ -178,7 +174,7 @@
         0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F
 };
 
-const USHORT SiS_CGA_DAC[] =
+static const USHORT SiS_CGA_DAC[] =
 {
         0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15,
         0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15,
@@ -190,7 +186,7 @@
         0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F
 };
 
-const USHORT SiS_EGA_DAC[] =
+static const USHORT SiS_EGA_DAC[] =
 {
         0x00,0x10,0x04,0x14,0x01,0x11,0x05,0x15,
         0x20,0x30,0x24,0x34,0x21,0x31,0x25,0x35,
@@ -202,7 +198,7 @@
         0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F
 };
 
-const USHORT SiS_VGA_DAC[] =
+static const USHORT SiS_VGA_DAC[] =
 {
 	0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15,
 	0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F,
@@ -259,11 +255,12 @@
 	{ 1680,1050, 8,16},   /* 0x1d */
 	{ 1280, 800, 8,16},   /* 0x1e */
 	{ 1920,1080, 8,16},   /* 0x1f */
-	{  960, 540, 8,16}    /* 0x20 */
+	{  960, 540, 8,16},   /* 0x20 */
+	{  960, 600, 8,16}    /* 0x21 */
 };
 
 #if defined(SIS300) || defined(SIS315H)
-static SiS_StandTableStruct SiS_StandTable[]=
+static const SiS_StandTableStruct SiS_StandTable[]=
 {
 /* 0x00: MD_0_200 */
  {
@@ -907,7 +904,8 @@
  {    5,   4, 0x627,0x464,0x670,0x3c0,0x128,  0, 0, 0x00,0x00,0x00,0x00},  /* 1280x1024 */
  {    4,   1, 0x41a,0x233,0x60c,0x3c0,0x143,128, 0, 0x00,0x00,0x00,0x00},  /* 800x480   */
  {    5,   2, 0x578,0x293,0x670,0x3c0,0x032,  0, 0, 0x00,0x00,0x00,0x00},  /* 1024x576  */
- {    8,   5, 0x6d6,0x323,0x670,0x3c0,0x128,  0, 0, 0x00,0x00,0x00,0x00}   /* 1280x720  */
+ {    8,   5, 0x6d6,0x323,0x670,0x3c0,0x128,  0, 0, 0x00,0x00,0x00,0x00},  /* 1280x720  */
+ {  137,  32, 0x3d4,0x233,0x663,0x3bf,0x143,  0, 0, 0x00,0x00,0x00,0x00}   /* 960x600  */
 };
 
 static const SiS_TVDataStruct  SiS_St525pData[] =
@@ -930,67 +928,41 @@
 
 static const SiS_TVDataStruct  SiS_Ext750pData[] =
 {
-#if 1
  {  143,  65, 0x35a,0x1bb,0x4f6,0x1b8,0x0ab,  0, 0x0ab, 0x00,0x00,0x00,0x00},
  {   88,  35, 0x35a,0x189,0x4f6,0x1b8,0x0ab,  0, 0x0ab, 0x00,0x00,0x00,0x00},
  {   18,   5, 0x339,0x1ae,0x500,0x2d0,0x05c,  0, 0x05c, 0x00,0x00,0x00,0x00},
  {  143,  70, 0x39c,0x189,0x4f6,0x1b8,0x05c,  0, 0x05c, 0x00,0x00,0x00,0x00},
  {   99,  32, 0x320,0x1fe,0x500,0x2d0,   50,  0,     0, 0x00,0x00,0x00,0x00},  /* 640x480  */
  {    5,   4, 0x5d8,0x29e,0x500,0x2a8,   50,  0,     0, 0x00,0x00,0x00,0x00},  /* 800x600  */
-#if 0
- {    2,   1, 0x35a,0x1f7,0x4f6,0x1e0,    0,128,     0, 0x00,0x00,0x00,0x00},  /* 720x480  */
-#endif
  {   99,  32, 0x320,0x1fe,0x500,0x2d0,   50,  0,     0, 0x00,0x00,0x00,0x00},  /* 720x480 test WORKS */
  {   68,  64, 0x55f,0x346,0x500,0x2a8,0x27e,  0,     0, 0x00,0x00,0x00,0x00},  /* 1024x768 */
  {    5,   2, 0x3a7,0x226,0x500,0x2a8,    0,128,     0, 0x00,0x00,0x00,0x00},  /* 720x576  */
  {   25,  24, 0x5d8,0x2f3,0x460,0x2a8,   50,  0,     0, 0x00,0x00,0x00,0x00}   /* 1280x720 WORKS */
-#endif
-#if 0
- {    3,   1, 0x3a7,0x1d6,0x500,0x2a8,   50,  0,     0, 0x00,0x00,0x00,0x00},
- {   24,   7, 0x3a7,0x1a4,0x500,0x2a8,   50,  0,     0, 0x00,0x00,0x00,0x00},
- {    3,   1, 0x3a7,0x1d6,0x500,0x2a8,   50,  0,     0, 0x00,0x00,0x00,0x00},
- {   24,   7, 0x3a7,0x1a4,0x500,0x2a8,   50,  0,     0, 0x00,0x00,0x00,0x00},
- {   99,  32, 0x320,0x1fe,0x500,0x2d0,   50,  0,     0, 0x00,0x00,0x00,0x00},  /* 640x480   */
- {    5,   4, 0x5d8,0x29e,0x500,0x2a8,   50,  0,     0, 0x00,0x00,0x00,0x00},  /* 800x600   */
- {    2,   1, 0x35a,0x1f7,0x4f6,0x1e0,    0,128,     0, 0x00,0x00,0x00,0x00},  /* 720x480   */
- {   68,  64, 0x55f,0x346,0x500,0x2a8,0x27e,  0,     0, 0x00,0x00,0x00,0x00},  /* 1024x768  */
- {   25,  24, 0x5d8,0x2f3,0x460,0x2a8,   50,  0,     0, 0x00,0x00,0x00,0x00}   /* 1280x720  */
-#endif
-#if 0
- {  136,  35, 0x339,0x181,0x460,0x2a8,   50,  0,     0, 0x00,0x00,0x00,0x00},  /* TEST (0.93) BAD */
- {   17,   6, 0x339,0x203,0x460,0x2a8,   50,  0,    50, 0x00,0x00,0x00,0x00},
- {  136,  35, 0x339,0x181,0x460,0x2a8,   50,  0,    50, 0x00,0x00,0x00,0x00},
- {   17,   6, 0x339,0x203,0x460,0x2a8,   50,  0,    50, 0x00,0x00,0x00,0x00},
- {   85,  46, 0x3f4,0x27b,0x460,0x2a8,   50,  0,     0, 0x00,0x00,0x00,0x00},  /* 640x480   */
- {   17,  16, 0x55f,0x323,0x460,0x2a8,0x2b6,  0,     0, 0x00,0x00,0x00,0x00},  /* 800x600   */
- {  136,  35, 0x339,0x181,0x460,0x2a8,   50,  0,     0, 0x00,0x00,0x00,0x00},  /* 720x480   */
- {  187,  74, 0x39d,0x203,0x460,0x2a8,   50,  0,     0, 0x00,0x00,0x00,0x00},  /* 1024x768  */
- {   25,  24, 0x5d8,0x2f3,0x460,0x2a8,   50,  0,    50, 0x00,0x00,0x00,0x00}   /* 1280x720  */
-#endif
 };
 
-static const SiS_LCDDataStruct  SiS_LCD1280x720Data[] =
+static const SiS_LCDDataStruct  SiS_LCD1280x720Data[] =  /* 2.03.00 */
 {
-	{  14,    5,  864,  432, 1344,  806 }, /* 640x400 */
-	{  16,    5,  864,  378, 1344,  806 },
-	{  14,    5,  864,  432, 1344,  806 },
-	{  16,    5,  864,  378, 1344,  806 },
-	{  24,   11,  924,  523, 1344,  806 }, /* 640x480 */
-	{   7,    5, 1152,  664, 1344,  806 }, /* 800x600 */
-	{   0,    0,    0,    0,    0,    0 },
+	{  44,   15,  864,  430, 1408,  806 }, /* 640x400 */
+	{ 128,   35,  792,  385, 1408,  806 },
+	{  44,   15,  864,  430, 1408,  806 },
+	{ 128,   35,  792,  385, 1408,  806 },
+	{  22,    9,  864,  516, 1408,  806 }, /* 640x480 */
+	{   8,    5, 1056,  655, 1408,  806 }, /* 800x600 */
+	{   0,    0,    0,    0,    0,    0 }, /* 1024x768 */
+	{   0,    0,    0,    0,    0,    0 }, /* 1280x1024 */
 	{   0,    0,    0,    0,    0,    0 },
 	{   0,    0,    0,    0,    0,    0 },
-	{   0,    0,    0,    0,    0,    0 },
-	{   1,    1, 1344,  806, 1344,  806 }  /* 1280x720 */
+	{   1,    1, 1408,  806, 1408,  806 }  /* 1280x720 */
 };
 
 /* About 1280x768: For TMDS, Panel_1280x768 will only be set if
  * the panel is a Fujitsu 7911 (VL-17WDX8) (with clock 81, 1688x802)
  * Other TMDS panels of this resolution will be treated as custom.
- * For LVDS, we know two types. Data follows:
+ * For LVDS, we know another type (_2).
+ * (Note: 1280x768_3 is now special for SiS301/NetVista
  */
 
-static const SiS_LCDDataStruct  SiS_StLCD1280x768_2Data[] =
+static const SiS_LCDDataStruct  SiS_StLCD1280x768_2Data[] = /* 2.03.00 */
 {
 	{  64,   21,  858,  434, 1408,  806 }, /* 640x400 */
 	{  32,    9,  858,  372, 1408,  806 },
@@ -1000,22 +972,27 @@
 	{  64,   51, 1364,  663, 1408,  806 }, /* 800x600 */
 	{  88,   81, 1296,  806, 1408,  806 }, /* 1024x768 */
 	{   0,    0,    0,    0,    0,    0 },
-	{   1,    1, 1408,  806, 1408,  806 }  /* 1280x768 */
+	{   1,    1, 1408,  806, 1408,  806 }, /* 1280x768 */
+	{   0,    0,    0,    0,    0,    0 },
+	{  16,   15, 1600,  750, 1600,  806 }  /* 1280x720 - from Ext */
 };
 
-static const SiS_LCDDataStruct  SiS_ExtLCD1280x768_2Data[] =
+static const SiS_LCDDataStruct  SiS_ExtLCD1280x768_2Data[] = /* 2.03.00 */
 {
-	{  64,   25, 1056,  422, 1408,  806 }, /*, 664 */
-	{ 128,   39,  884,  396, 1408,  806 }, /*, 640 */
-	{  64,   25, 1056,  422, 1408,  806 }, /*, 664 */
-	{ 128,   39,  884,  396, 1408,  806 }, /*, 640 */
-	{  32,   15, 1056,  513, 1408,  806 }, /*, 664 */
-	{ 176,  125, 1280,  640, 1408,  806 }, /*, 768 */
-	{  88,   81, 1296,  806, 1408,  806 },
+	{  16,    5,  960,  410, 1600,  806 }, /* 640x400 */
+	{  64,   21, 1152,  364, 1600,  806 },
+	{  16,    5,  960,  410, 1600,  806 },
+	{  64,   21, 1152,  364, 1600,  806 },
+	{  32,   13, 1040,  493, 1600,  806 }, /* 640x480 */
+	{  16,    9, 1152,  618, 1600,  806 }, /* 800x600 */
+	{  25,   21, 1344,  796, 1600,  806 }, /* 1024x768 */
+	{   0,    0,    0,    0,    0,    0 },
+	{   1,    1, 1600,  806, 1600,  806 }, /* 1280x768 */
 	{   0,    0,    0,    0,    0,    0 },
-	{   1,    1, 1408,  806, 1408,  806 }
+	{  16,   15, 1600,  750, 1600,  806 }  /* 1280x720 */
 };
 
+#if 0  /* Not used; _3 now reserved for NetVista (SiS301) */
 static const SiS_LCDDataStruct  SiS_LCD1280x768_3Data[] =
 {
 	{  64,   25, 1056,  422, 1664,  798 },			/* 640x400 */
@@ -1026,20 +1003,40 @@
 	{ 176,  125, 1280,  640, 1408,  806 }, /* ,768 */	/* 800x600 */
 	{  64,   61, 1342,  806, 1408,  806 },			/* 1024x768 */
 	{   0,    0,    0,    0,    0,    0 },
-	{   1,    1, 1408,  806, 1408,  806 }			/* 1280x768 */
+	{   1,    1, 1408,  806, 1408,  806 },			/* 1280x768 */
+	{   0,    0,    0,    0,    0,    0 },
+	{  16,   15, 1600,  750, 1600,  806 }  /* 1280x720  from above */
 };
+#endif
 
-static const SiS_LCDDataStruct  SiS_LCD1280x800Data[] =
+static const SiS_LCDDataStruct  SiS_LCD1280x800Data[] = /* 0.93.12a (TMDS) */
 {
-	{ 128,   51, 1122,  412, 1408,  816 }, /* 640x400 */
+	{ 128,   51, 1122,  412, 1408,  816 },  /* 640x400 */
 	{ 128,   49, 1232,  361, 1408,  816 },
 	{ 128,   51, 1122,  412, 1408,  816 },
 	{ 128,   49, 1232,  361, 1408,  816 },
-	{   8,    3,  880,  491, 1408,  816 }, /* 640x480 */
-	{  11,    6, 1024,  612, 1408,  816 }, /* 800x600 */
-	{  22,   21, 1400,  784, 1408,  816 }, /* 1024x768 */
-	{   0,    0,    0,    0,    0,    0 },
-	{   1,    1, 1408,  816, 1408,  816 }  /* 1280x800 */
+	{   8,    3,  880,  491, 1408,  816 },  /* 640x480 */
+	{  11,    6, 1024,  612, 1408,  816 },  /* 800x600 */
+	{  22,   21, 1400,  784, 1408,  816 },  /* 1024x768 */
+	{   0,    0,    0,    0,    0,    0 },  /* 1280x1024 */
+	{   1,    1, 1408,  816, 1408,  816 },  /* 1280x800 */
+	{   0,    0,    0,    0,    0,    0 },  /* 1280x768 (patch index) */
+	{   0,    0,    0,    0,    0,    0 }   /* 1280x720 */
+};
+
+static const SiS_LCDDataStruct  SiS_LCD1280x800_2Data[] = /* 2.03.00 (LVDS) */
+{
+	{  97,   42, 1344,  409, 1552,  812 }, /* 640x400 */
+	{  97,   35, 1280,  358, 1552,  812 },
+	{  97,   42, 1344,  409, 1552,  812 },
+	{  97,   35, 1280,  358, 1552,  812 },
+	{  97,   39, 1040,  488, 1552,  812 }, /* 640x480 */
+	{ 194,  105, 1120,  608, 1552,  812 }, /* 800x600 */
+	{  97,   84, 1400,  780, 1552,  812 }, /* 1024x768 */
+	{   0,    0,    0,    0,    0,    0 }, /* 1280x1024 */
+	{   1,    1, 1552,  812, 1552,  812 }, /* 1280x800 */
+	{  97,   96, 1600,  780, 1552,  812 }, /* 1280x768 - patch index */
+	{  97,   90, 1600,  730, 1552,  812 }  /* 1280x720 */
 };
 
 static const SiS_LCDDataStruct  SiS_LCD1280x960Data[] =
@@ -1097,9 +1094,9 @@
 	{  95,   64, 1750,  784, 1900, 1066 }, /*  6 1024x768 */
 	{  95,   94, 1900, 1055, 1900, 1066 }, /*  7 1280x1024 */
 	{  41,   31, 1900,  806, 1900, 1066 }, /*  8 1280x768 */
-	{  95,   69, 1800,  817, 1900, 1066 }, /*  9 1280x800 patch */
+	{  95,   69, 1800,  817, 1900, 1066 }, /*  9 1280x800 patch index */
 	{  13,    9, 1900,  739, 1900, 1066 }, /* 10 1280x720 */
-	{  95,   94, 1880, 1066, 1900, 1066 }, /* 11 1400x1050 patch */
+	{  95,   94, 1880, 1066, 1900, 1066 }, /* 11 1400x1050 patch index */
 	{   1,    1, 1900, 1066, 1900, 1066 }  /* 12 1680x1050 */
 };
 
@@ -1148,12 +1145,12 @@
 	{ 1, 1,1800,1000,1800,1000 },  /* 0x0a: 1280x960  */
 	{ 1, 1,1688,1066,1688,1066 },  /* 0x0b: 1400x1050 */
 	{ 1, 1,1650, 750,1650, 750 },  /* 0x0c: 1280x720 (TMDS, projector)  */
-	{ 1, 1,1656, 841,1656, 841 },  /* 0x0d: 1280x800 (was: 1408, 816) */
+	{ 1, 1,1552, 812,1552, 812 },  /* 0x0d: 1280x800_2 (LVDS) (was: 1408,816/ 1656,841) */
 	{ 1, 1,1900,1066,1900,1066 },  /* 0x0e: 1680x1050 (LVDS) */
-	{ 1, 1,1408, 806,1408, 806 },  /* 0x0f: 1280x768_2 */
-	{ 1, 1,1664, 798,1664, 798 },  /* 0x10: 1280x768_3 */
-	{ 1, 1,1688, 802,1688, 802 },  /* 0x11: 1280x768: Std, TMDS only */
-	{ 1, 1,1344, 806,1344, 806 },  /* 0x12: 1280x720 (LVDS)  */
+	{ 1, 1,1660, 806,1660, 806 },  /* 0x0f: 1280x768_2 (LVDS) */
+	{ 1, 1,1664, 798,1664, 798 },  /* 0x10: 1280x768_3 (NetVista SiS 301) - TODO */
+	{ 1, 1,1688, 802,1688, 802 },  /* 0x11: 1280x768   (TMDS Fujitsu) */
+	{ 1, 1,1408, 806,1408, 806 },  /* 0x12: 1280x720 (LVDS) */
 	{ 1, 1, 896, 497, 896, 497 },  /* 0x13: 720x480 */
 	{ 1, 1, 912, 597, 912, 597 },  /* 0x14: 720x576 */
 	{ 1, 1, 912, 597, 912, 597 },  /* 0x15: 768x576 */
@@ -1163,10 +1160,11 @@
 	{ 1, 1,1328, 739,1328, 739 },  /* 0x19: 1024x576 */
 	{ 1, 1,1680, 892,1680, 892 },  /* 0x1a: 1152x864 */
 	{ 1, 1,1808, 808,1808, 808 },  /* 0x1b: 1360x768 */
-	{ 1, 1,1104, 563,1104, 563 }   /* 0x1c: 960x540 */
+	{ 1, 1,1104, 563,1104, 563 },  /* 0x1c: 960x540 */
+	{ 1, 1,1120, 618,1120, 618 },  /* 0x1d: 960x600 */
+	{ 1, 1,1408, 816,1408, 816 }   /* 0x1f: 1280x800 (TMDS special) */
 };
 
-
 /**************************************************************/
 /* LVDS ----------------------------------------------------- */
 /**************************************************************/
@@ -1207,7 +1205,6 @@
 	{ 800, 525, 800, 525}    /* pseudo */
 };
 
-
 static const SiS_LVDSDataStruct  SiS_LVDS800x600Data_1[]=
 {
 	{ 848, 433,1060, 629},
@@ -1221,12 +1218,6 @@
 
 static const SiS_LVDSDataStruct  SiS_LVDS800x600Data_2[]=
 {
-	{1056, 628,1056, 628},
-	{1056, 628,1056, 628},
-	{1056, 628,1056, 628},
-	{1056, 628,1056, 628},
-	{1056, 628,1056, 628},
-	{1056, 628,1056, 628},
 	{1056, 628,1056, 628}
 };
 
@@ -1243,13 +1234,7 @@
 
 static const SiS_LVDSDataStruct  SiS_LVDS1024x768Data_2[]=
 {
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
+	{1344, 806,1344, 806}
 };
 
 static const SiS_LVDSDataStruct  SiS_LVDS1280x1024Data_1[]=
@@ -1266,13 +1251,6 @@
 
 static const SiS_LVDSDataStruct  SiS_LVDS1280x1024Data_2[]=
 {
-	{1688,1066,1688,1066},
-	{1688,1066,1688,1066},
-	{1688,1066,1688,1066},
-	{1688,1066,1688,1066},
-	{1688,1066,1688,1066},
-	{1688,1066,1688,1066},
-	{1688,1066,1688,1066},
 	{1688,1066,1688,1066}
 };
 
@@ -1291,15 +1269,7 @@
 
 static const SiS_LVDSDataStruct  SiS_LVDS1400x1050Data_2[]=
 {
-        {1688,1066, 1688,1066},
-	{1688,1066, 1688,1066},
-	{1688,1066, 1688,1066},
-	{1688,1066, 1688,1066},
-	{1688,1066, 1688,1066},
-	{1688,1066, 1688,1066},
-	{1688,1066, 1688,1066},
-	{1688,1066, 1688,1066},
-	{1688,1066, 1688,1066},
+        {1688,1066, 1688,1066}
 };
 
 static const SiS_LVDSDataStruct  SiS_LVDS1600x1200Data_1[]=
@@ -1314,32 +1284,11 @@
 	{1728,1144, 2048,1320},
 	{1848,1170, 2048,1320},
 	{2048,1320, 2048,1320}
-#if 0
-        {1088, 450, 2048,1250},
-	{1088, 400, 2048,1250},
-	{1088, 450, 2048,1250},
-	{1088, 400, 2048,1250},
-	{1088, 530, 2048,1250},
-	{1248, 650, 2048,1250},
-	{1472, 818, 2048,1250},
-	{1728,1066, 2048,1250},
-	{1848,1066, 2048,1250},
-	{2048,1250, 2048,1250}
-#endif
 };
 
 static const SiS_LVDSDataStruct  SiS_LVDS1600x1200Data_2[]=
 {
-        {2048,1320, 2048,1320},
-	{2048,1320, 2048,1320},
-	{2048,1320, 2048,1320},
-	{2048,1320, 2048,1320},
-	{2048,1320, 2048,1320},
-	{2048,1320, 2048,1320},
-	{2048,1320, 2048,1320},
-	{2048,1320, 2048,1320},
-	{2048,1320, 2048,1320},
-	{2048,1320, 2048,1320}
+        {2048,1320, 2048,1320}
 };
 
 static const SiS_LVDSDataStruct  SiS_LVDS1280x960Data_1[]=
@@ -1357,15 +1306,7 @@
 
 static const SiS_LVDSDataStruct  SiS_LVDS1280x960Data_2[]=
 {
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{ 800, 449,1280, 801},
-	{ 800, 525,1280, 813}
+	{1344, 806,1344, 806}
 };
 
 static const SiS_LVDSDataStruct  SiS_LVDS1280x768Data_1[]=
@@ -1383,14 +1324,6 @@
 
 static const SiS_LVDSDataStruct  SiS_LVDS1280x768Data_2[]=
 {
-	{1408, 806, 1408, 806},
-	{1408, 806, 1408, 806},
-	{1408, 806, 1408, 806},
-	{1408, 806, 1408, 806},
-	{1408, 806, 1408, 806},
-	{1408, 806, 1408, 806},
-	{1408, 806, 1408, 806},
-	{1408, 806, 1408, 806},
 	{1408, 806, 1408, 806}
 };
 
@@ -1407,12 +1340,6 @@
 
 static const SiS_LVDSDataStruct  SiS_LVDS1024x600Data_2[] =
 {
-	{1344, 800,1344, 800},
-	{1344, 800,1344, 800},
-	{1344, 800,1344, 800},
-	{1344, 800,1344, 800},
-	{1344, 800,1344, 800},
-	{1344, 800,1344, 800},
 	{1344, 800,1344, 800}
 };
 
@@ -1429,12 +1356,6 @@
 
 static const SiS_LVDSDataStruct  SiS_LVDS1152x768Data_2[] =
 {
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
 	{1344, 806,1344, 806}
 };
 
@@ -1445,12 +1366,11 @@
 	{ 800, 449,  800, 449},
 	{ 900, 449,  900, 449},
 	{ 900, 449,  900, 449},
-	{ 800, 525,  800, 525},  /*  640x480   */
-	{1056, 628, 1056, 628},  /*  800x600   */
-	{1344, 806, 1344, 806},  /* 1024x768   */
-	{1688,1066, 1688,1066},  /* 1280x1024  */  /* INSERTED ! */
- 	{1688, 806, 1688, 806},  /* 1280x768   */
-	/* No other panels ! */
+	{ 800, 525,  800, 525},  /*  640x480  */
+	{1056, 628, 1056, 628},  /*  800x600  */
+	{1344, 806, 1344, 806},  /* 1024x768  */
+	{1688,1066, 1688,1066},  /* 1280x1024 */  /* INSERTED */
+ 	{1688, 806, 1688, 806},  /* 1280x768  */
 };
 
 /* Custom data for Barco iQ R series */
@@ -1496,13 +1416,7 @@
 /* Custom data for Barco iQ G series */
 static const SiS_LVDSDataStruct  SiS_LVDSBARCO1024Data_2[]=
 {
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
+	{1344, 806,1344, 806}
 };
 
 /* Custom data for 848x480 parallel panel */
@@ -1589,10 +1503,10 @@
 
 static const SiS_LVDSDesStruct  SiS_CHTVUPALDesData[]=
 {
-	{256,   0},
-	{256,   0},
-	{256,   0},
-	{256,   0},
+	{256,  0},
+	{256,  0},
+	{256,  0},
+	{256,  0},
 	{ 0,   0},
 	{ 0,   0},
 	{ 0,   0}
@@ -1600,10 +1514,10 @@
 
 static const SiS_LVDSDesStruct  SiS_CHTVOPALDesData[]=
 {
-	{256,   0},
-	{256,   0},
-	{256,   0},
-	{256,   0},
+	{256,  0},
+	{256,  0},
+	{256,  0},
+	{256,  0},
 	{ 0,   0},
 	{ 0,   0},
 	{ 0,   0}
@@ -2105,6 +2019,8 @@
 /* COMMON --------------------------------------------------- */
 /**************************************************************/
 
+#ifdef LINUX_XF86
+
 #define SIS_PL_HSYNCP 0x01
 #define SIS_PL_HSYNCN 0x02
 #define SIS_PL_VSYNCP 0x04
@@ -2127,6 +2043,8 @@
    USHORT product[5];
    const char *DDCnames[5];
    const char *plasmaname;
+   USHORT maxx,maxy;
+   USHORT prefx, prefy;
    UCHAR  modenum;
    UCHAR  plasmamodes[20];  /* | 0x80 = DVI-capable, | 0x40 = analog */
 } SiS_PlasmaTables;
@@ -2237,14 +2155,51 @@
         848, 1068, 20,  40,	/* differs from DDC data, better centered */
         480,  516,  3,   5,	/* won't work assumingly, because data is % 8 */
       SIS_PL_HSYNCN | SIS_PL_VSYNCN },
+   {  "1280x720",		/* 21: WIDE720(60) (aka "750p") (Panasonic) */
+      74300,
+      1280, 1650,110,  40,
+       720,  750,  5,   5,
+      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
+   {  "1280x768",		/* 22: 1280x768@56.5 (Panasonic) */
+      76200,			/* (According to manual not supported for HDMI; but works) */
+      1280, 1680, 16,  24,
+       768,  802,  2,   5,
+      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
+   {  "1280x720@50",		/* 23: WIDE720(50) (aka "750p") (Panasonic) */
+      74300,			/* Panasonic states 45.0kHz. Not possible. This one works (with some overscan) */
+      1280, 1980,400,  80,
+       720,  750,  1,   2,
+      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
+   {  "720x480",		/* 24: 720x480 (aka "525p" and "480p") (Panasonic) */
+      27000,
+       720,  856, 40,  32,
+       480,  525,  1,   3,
+      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
+   {  "720x576",		/* 25: 720x576 (aka "625p"and "576p") (Panasonic) */
+      27500,
+       720,  864, 16,  64,
+       576,  625,  5,   6,
+      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
+   {  "1280x720@50",		/* 26: WIDE720(50) (aka "750p") (Generic) */
+      74300,
+      1280, 1980,400,  80,
+       720,  750,  5,   5,
+      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
 };
 
+/*
+27.00  720 755 791 858  480 480 484 525
+27.50  720 732 795 864  576 581 587 625
+*/
+
 static const SiS_PlasmaTables SiS_PlasmaTable[] = {
 #if 0  /* Product IDs missing */
    { 0x38a3, 4,
      { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
      { "", "", "", "", "" },
      "NEC PlasmaSync 42VP4/42VP4D/42VP4G/42VP4DG",
+     0, 0,
+     0, 0,
      11,   /* All DVI, except 0, 7, 13 */
      { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 7|0x40, 9|0xc0,10|0xc0,11|0xc0,13|0x40,14|0xc0,
       17|0xc0, 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
@@ -2255,6 +2210,8 @@
      { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
      { "", "", "", "", "" },
      "NEC PlasmaSync 42PD1/50PD1/50PD2",
+     0, 0,
+     0, 0,
      5,   /* DVI entirely unknown */
      { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 9|0xc0, 0     , 0     , 0     , 0     , 0     ,
        0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
@@ -2263,6 +2220,8 @@
      { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
      { "", "", "", "", "" },
      "NEC PlasmaSync 42PD3",
+     0, 0,
+     0, 0,
      10,   /* DVI entirely unknown */
      { 0|0x40, 1|0xc0, 2|0xc0, 3|0xc0, 4|0xc0, 5|0xc0, 6|0xc0, 7|0x40, 8|0xc0, 9|0xc0,
        0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
@@ -2271,6 +2230,8 @@
      { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
      { "", "", "", "", "" },
      "NEC PlasmaSync 42VM3/61XM1",
+     0, 0,
+     0, 0,
      11,  /* DVI entirely unknown */
      { 0|0x40, 1|0xc0, 2|0xc0, 3|0xc0, 4|0xc0, 5|0xc0, 6|0xc0, 8|0xc0, 9|0xc0,11|0xc0,
       17|0xc0, 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
@@ -2279,6 +2240,8 @@
      { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
      { "", "", "", "", "" },
      "NEC PlasmaSync 42MP1/42MP2",
+     0, 0,
+     0, 0,
      6,   /* DVI entirely unknown */
      { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 9|0xc0,11|0xc0, 0     , 0     , 0     , 0     ,
        0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
@@ -2287,6 +2250,8 @@
      { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
      { "", "", "", "", "" },
      "NEC PlasmaSync 50MP1",
+     0, 0,
+     0, 0,
      10,   /* DVI entirely unknown */
      { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 7|0x40, 9|0xc0,10|0xc0,11|0xc0,13|0x40,14|0xc0,
        0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
@@ -2296,6 +2261,8 @@
      { 0xa482, 0xa483, 0x0000, 0x0000, 0x0000 },
      { "PX-42VM", "", "", "", "" },
      "NEC PlasmaSync 42MP3/42MP4/50MP2/61MP1",
+     0, 0,
+     0, 0,
      11,   /* All DVI except 0, 7, 13, 17 */
      { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 7|0x40, 9|0xc0,10|0xc0,11|0xc0,13|0x40,14|0xc0,
       17|0x40, 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
@@ -2305,6 +2272,8 @@
      { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
      { "", "", "", "", "" },
      "NEC PlasmaSync 3300W",
+     0, 0,
+     0, 0,
      3,
      { 0|0x40, 1|0xc0,18|0xc0, 0     , 0     , 0     , 0     , 0     , 0     , 0     ,
        0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
@@ -2321,6 +2290,8 @@
      { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
      { "", "", "", "", "" },
      "NEC PlasmaSync 4210W",
+     0, 0,
+     0, 0,
      6,   /* DVI entirely unknown */
      { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 9|0xc0,11|0xc0, 0     , 0     , 0     , 0     ,
        0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
@@ -2329,6 +2300,8 @@
      { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
      { "", "", "", "", "" },
      "NEC PlasmaSync 5000W",
+     0, 0,
+     0, 0,
      7,   /* DVI entirely unknown */
      { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 7|0x40, 9|0xc0,11|0xc0, 0     , 0     , 0     ,
        0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
@@ -2338,6 +2311,8 @@
      { 0x000c, 0x000b, 0x0000, 0x0000, 0x0000 },
      { "", "", "", "", "" },
      "Pioneer 503CMX/PDA-5002",
+     0, 0,
+     0, 0,
      6,   /* DVI unknown */
      { 1|0xc0, 2|0xc0, 9|0xc0,11|0xc0,12|0xc0,15|0xc0, 0     , 0     , 0     , 0     ,
        0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
@@ -2346,6 +2321,8 @@
      { 0xa00e, 0x0000, 0x0000, 0x0000, 0x0000 },
      { "", "", "", "", "" },
      "Panasonic TH-42",
+     0, 0,
+     0, 0,
      5,   /* No DVI output */
      { 1|0x40, 2|0x40, 4|0x40, 9|0x40,15|0x40, 0     , 0     , 0     , 0     , 0     ,
        0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
@@ -2354,15 +2331,50 @@
      { 0xa005, 0x0000, 0x0000, 0x0000, 0x0000 },
      { "TH-42PW*4", "", "", "", "" },
      "Panasonic TH-42PW5",
+     0, 0,
+     0, 0,
      1,   /* No special modes otherwise; no DVI. */
      {20|0x40,19|0x40, 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     ,
        0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
    },
+   { 0x4c2e, 1,
+     { 0x9b05, 0x0000, 0x0000, 0x0000, 0x0000 },
+     { "PLV-Z2", "", "", "", "" },
+     "Sanyo PLV-Z2 (non HDCP-mode)", 	/* HDCP mode would be id 9b06, but not needed */
+     1280, 768,				/* as it then advertises correct size */
+     1280, 720,
+     1,   /* 1280x720, no special modes otherwise */
+     {21|0xc0, 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     ,
+       0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
+   },
+   { 0x34a9, 1,
+     { 0xd034, 0x0000, 0x0000, 0x0000, 0x0000 },
+     { "AE500U (DVI-D)", "", "", "", "" },
+     "Panasonic AE500U",
+     1280, 768,
+     1280, 720,
+     1,   /* 1280x720, no special modes otherwise */
+     {21|0xc0, 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     ,
+       0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
+   },
+   { 0x34a9, 1,
+     { 0xd043, 0x0000, 0x0000, 0x0000, 0x0000 },
+     { "AE700U (HDMI)", "", "", "", "" },
+     "Panasonic AE700U",
+     1360, 768,
+     1280, 720,
+     6,   /* 1280x720/60, 1280x720/50, 1280x768@56(digital/analog), 720x480, 720x576 */
+     {21|0xc0,23|0xc0,22|0x80,13|0x40,24|0x80,25|0x80, 0     , 0     , 0     , 0     ,
+       0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
+   },
    { 0x0000 }
 };
+#endif
 
+#ifdef LINUX_XF86
 USHORT  SiS_GetModeID(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay,
 			  int Depth, BOOLEAN FSTN, int LCDwith, int LCDheight);
+#endif
 USHORT  SiS_GetModeID_LCD(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int Depth, BOOLEAN FSTN,
                           USHORT CustomT, int LCDwith, int LCDheight);
 USHORT  SiS_GetModeID_TV(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int Depth);
@@ -2376,9 +2388,9 @@
 UCHAR 	SiS_GetRegByte(SISIOADDRESS port);
 USHORT	SiS_GetRegShort(SISIOADDRESS port);
 ULONG	SiS_GetRegLong(SISIOADDRESS port);
-void	SiS_SetRegANDOR(SISIOADDRESS Port,USHORT Index,USHORT DataAND,USHORT DataOR);
-void 	SiS_SetRegAND(SISIOADDRESS Port,USHORT Index,USHORT DataAND);
-void	SiS_SetRegOR(SISIOADDRESS Port,USHORT Index,USHORT DataOR);
+void	SiS_SetRegANDOR(SISIOADDRESS Port, USHORT Index, USHORT DataAND, USHORT DataOR);
+void 	SiS_SetRegAND(SISIOADDRESS Port,USHORT Index, USHORT DataAND);
+void	SiS_SetRegOR(SISIOADDRESS Port,USHORT Index, USHORT DataOR);
 void	SiS_DisplayOn(SiS_Private *SiS_Pr);
 void	SiS_DisplayOff(SiS_Private *SiS_Pr);
 void	SiSRegInit(SiS_Private *SiS_Pr, SISIOADDRESS BaseAddr);
@@ -2387,14 +2399,14 @@
 void	SiS_SetEnableDstn(SiS_Private *SiS_Pr, int enable);
 void	SiS_SetEnableFstn(SiS_Private *SiS_Pr, int enable);
 void	SiS_GetVBType(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
-USHORT	SiS_GetMCLK(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
 BOOLEAN	SiS_SearchModeID(SiS_Private *SiS_Pr, USHORT *ModeNo, USHORT *ModeIdIndex);
 UCHAR	SiS_GetModePtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex);
 USHORT	SiS_GetColorDepth(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex);
-USHORT	SiS_GetOffset(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
-              USHORT RefreshRateTableIndex,PSIS_HW_INFO HwInfo);
+USHORT	SiS_GetOffset(SiS_Private *SiS_Pr,USHORT ModeNo, USHORT ModeIdIndex,
+              USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo);
 void	SiS_LoadDAC(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo, USHORT ModeIdIndex);
-void	SiS_CalcLCDACRT1Timing(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex);
+void	SiS_CalcLCDACRT1Timing(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex);
+
 #ifdef LINUX_XF86
 BOOLEAN	SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,ScrnInfoPtr pScrn,USHORT ModeNo, BOOLEAN dosetpitch);
 BOOLEAN	SiSBIOSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
@@ -2404,51 +2416,56 @@
 BOOLEAN	SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
                DisplayModePtr mode, BOOLEAN IsCustom);
 int	SiSTranslateToVESA(ScrnInfoPtr pScrn, int modenumber);
+int	SiSTranslateToOldMode(int modenumber);
 BOOLEAN	SiS_GetPanelID(SiS_Private *SiS_Pr, PSIS_HW_INFO);
 USHORT 	SiS_CheckBuildCustomMode(ScrnInfoPtr pScrn, DisplayModePtr mode, int VBFlags);
 DisplayModePtr SiSBuildBuiltInModeList(ScrnInfoPtr pScrn, BOOLEAN includelcdmodes, BOOLEAN isfordvi);
+int 	SiS_FindPanelFromDB(SISPtr pSiS, USHORT panelvendor, USHORT panelproduct, int *maxx, int *maxy, int *prefx, int *prefy);
+void    SiS_MakeClockRegs(ScrnInfoPtr pScrn, int clock, UCHAR *p2b, UCHAR *p2c);
 #else
 BOOLEAN	SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,USHORT ModeNo);
 #endif
+
 #ifdef LINUX_KERNEL
-int    sisfb_mode_rate_to_dclock(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
-			      unsigned char modeno, unsigned char rateindex);
-int    sisfb_mode_rate_to_ddata(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
-			 unsigned char modeno, unsigned char rateindex,
-			 struct fb_var_screeninfo *var);
+int    	sisfb_mode_rate_to_dclock(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
+			      UCHAR modeno, UCHAR rateindex);
+int    	sisfb_mode_rate_to_ddata(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
+			UCHAR modeno, UCHAR rateindex,
+			struct fb_var_screeninfo *var);
 BOOLEAN sisfb_gettotalfrommode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
-		       unsigned char modeno, int *htotal, int *vtotal, unsigned char rateindex);
+		       	UCHAR modeno, int *htotal, int *vtotal, UCHAR rateindex);
 #endif
 
-extern void      SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
-			       PSIS_HW_INFO HwInfo, int chkcrt2mode);
-extern void      SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
-			           PSIS_HW_INFO HwInfo);
-extern void      SiS_SetYPbPr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
-extern void 	 SiS_SetTVMode(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, PSIS_HW_INFO HwInfo);
-extern void      SiS_UnLockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
-extern void      SiS_LockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
-extern void      SiS_DisableBridge(SiS_Private *, PSIS_HW_INFO);
-extern BOOLEAN   SiS_SetCRT2Group(SiS_Private *, PSIS_HW_INFO, USHORT);
-extern USHORT    SiS_GetRatePtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
-                                PSIS_HW_INFO HwInfo);
-extern void      SiS_WaitRetrace1(SiS_Private *SiS_Pr);
-extern USHORT    SiS_GetResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex);
-extern USHORT    SiS_GetCH700x(SiS_Private *SiS_Pr, USHORT tempax);
-extern USHORT    SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
-                                 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo);
-extern BOOLEAN   SiS_IsVAMode(SiS_Private *, PSIS_HW_INFO);
-extern BOOLEAN   SiS_IsDualEdge(SiS_Private *, PSIS_HW_INFO);
+/* init301.c: */
+extern void     SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
+			       	PSIS_HW_INFO HwInfo, int chkcrt2mode);
+extern void     SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
+			       	PSIS_HW_INFO HwInfo);
+extern void     SiS_SetYPbPr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
+extern void 	SiS_SetTVMode(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, PSIS_HW_INFO HwInfo);
+extern void     SiS_UnLockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
+extern void     SiS_LockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
+extern void     SiS_DisableBridge(SiS_Private *, PSIS_HW_INFO);
+extern BOOLEAN  SiS_SetCRT2Group(SiS_Private *, PSIS_HW_INFO, USHORT);
+extern USHORT   SiS_GetRatePtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
+                               	PSIS_HW_INFO HwInfo);
+extern void     SiS_WaitRetrace1(SiS_Private *SiS_Pr);
+extern USHORT   SiS_GetResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex);
+extern USHORT   SiS_GetCH700x(SiS_Private *SiS_Pr, USHORT tempax);
+extern USHORT   SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
+                               	USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo);
+extern BOOLEAN  SiS_IsVAMode(SiS_Private *, PSIS_HW_INFO);
+extern BOOLEAN  SiS_IsDualEdge(SiS_Private *, PSIS_HW_INFO);
 
 #ifdef LINUX_XF86
+/* From other sis driver modules: */
 extern int      SiS_compute_vclk(int Clock, int *out_n, int *out_dn, int *out_div,
-	     	 		 int *out_sbit, int *out_scale);
+	     	 	 	int *out_sbit, int *out_scale);
 extern void 	SiSCalcClock(ScrnInfoPtr pScrn, int clock, int max_VLD, unsigned int *vclk);
 
-extern unsigned char SiS_GetSetBIOSScratch(ScrnInfoPtr pScrn, USHORT offset, unsigned char value);
-extern unsigned char SiS_GetSetModeID(ScrnInfoPtr pScrn, unsigned char id);
-extern USHORT 	     SiS_CalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode, unsigned long VBFlags,
-					BOOLEAN hcm);
+extern UCHAR   	SiS_GetSetBIOSScratch(ScrnInfoPtr pScrn, USHORT offset, UCHAR value);
+extern UCHAR   	SiS_GetSetModeID(ScrnInfoPtr pScrn, UCHAR id);
+extern USHORT 	SiS_GetModeNumber(ScrnInfoPtr pScrn, DisplayModePtr mode, ULONG VBFlags);
 #endif
 
 #endif
diff -Nru a/drivers/video/sis/init301.c b/drivers/video/sis/init301.c
--- a/drivers/video/sis/init301.c	2005-03-01 23:38:51 -08:00
+++ b/drivers/video/sis/init301.c	2005-03-01 23:38:51 -08:00
@@ -133,17 +133,29 @@
 {
    UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
    UCHAR  *myptr = NULL;
-   USHORT romindex = 0;
+   USHORT romindex = 0, reg = 0, idx = 0;
 
-   /* Use the BIOS tables only for LVDS panels; DVI is unreliable
+   /* Use the BIOS tables only for LVDS panels; TMDS is unreliable
     * due to the variaty of panels the BIOS doesn't know about.
+    * Exception: If the BIOS has better knowledge (such as in case
+    * of machines with a 301C and a panel that does not support DDC)
+    * use the BIOS data as well.
     */
 
-   if((SiS_Pr->SiS_ROMNew) && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
-      myptr = (UCHAR *)SiS_LCDStruct661;
+   if((SiS_Pr->SiS_ROMNew) &&
+      ((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) || (!SiS_Pr->PanelSelfDetected))) {
+
+      if(HwInfo->jChipType < SIS_661) reg = 0x3c;
+      else                            reg = 0x7d;
+
+      idx = (SiS_GetReg(SiS_Pr->SiS_P3d4,reg) & 0x1f) * 26;
+
+      if(idx < (8*26)) {
+         myptr = (UCHAR *)&SiS_LCDStruct661[idx];
+      }
       romindex = SISGETROMW(0x100);
       if(romindex) {
-         romindex += ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x7d) & 0x1f) * 26);
+         romindex += idx;
          myptr = &ROMAddr[romindex];
       }
    }
@@ -156,11 +168,15 @@
    UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
    USHORT romptr = 0;
 
-   /* Use the BIOS tables only for LVDS panels; DVI is unreliable
+   /* Use the BIOS tables only for LVDS panels; TMDS is unreliable
     * due to the variaty of panels the BIOS doesn't know about.
+    * Exception: If the BIOS has better knowledge (such as in case
+    * of machines with a 301C and a panel that does not support DDC)
+    * use the BIOS data as well.
     */
 
-   if((SiS_Pr->SiS_ROMNew) && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
+   if((SiS_Pr->SiS_ROMNew) &&
+      ((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) || (!SiS_Pr->PanelSelfDetected))) {
       romptr = SISGETROMW(0x102);
       romptr += ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) * SiS_Pr->SiS661LCD2TableSize);
    }
@@ -175,12 +191,11 @@
 
 static BOOLEAN
 SiS_AdjustCRT2Rate(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
-                   USHORT RefreshRateTableIndex, USHORT *i,
-		   PSIS_HW_INFO HwInfo)
+                   USHORT RRTI, USHORT *i, PSIS_HW_INFO HwInfo)
 {
   USHORT checkmask=0,modeid,infoflag;
 
-  modeid = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].ModeID;
+  modeid = SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID;
 
   if(SiS_Pr->SiS_VBType & VB_SISVB) {
 
@@ -241,8 +256,8 @@
   }
 
   /* Look backwards in table for matching CRT2 mode */
-  for(; SiS_Pr->SiS_RefIndex[RefreshRateTableIndex+(*i)].ModeID == modeid; (*i)--) {
-     infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].Ext_InfoFlag;
+  for(; SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID == modeid; (*i)--) {
+     infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;
      if(infoflag & checkmask) return TRUE;
      if((*i) == 0) break;
   }
@@ -251,13 +266,11 @@
    * for a matching CRT2 mode if no mode was found yet.
    */
   for((*i) = 0; ; (*i)++) {
-     if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].ModeID != modeid) {
-     	return FALSE;
-     }
-     infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].Ext_InfoFlag;
+     if(SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID != modeid) break;
+     infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;
      if(infoflag & checkmask) return TRUE;
   }
-  return TRUE;
+  return FALSE;
 }
 
 /*********************************************/
@@ -273,7 +286,7 @@
 			       0x01, 0x01, 0x01, 0x01,
 			       0x01, 0x01, 0x01, 0x01,
 			       0x00, 0x00, 0x00, 0x00 };
-  USHORT RefreshRateTableIndex,i,backup_i;
+  USHORT RRTI,i,backup_i;
   USHORT modeflag,index,temp,backupindex;
 
   /* Do NOT check for UseCustomMode here, will skrew up FIFO */
@@ -318,23 +331,23 @@
      }
   }
 
-  RefreshRateTableIndex = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
-  ModeNo = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].ModeID;
+  RRTI = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
+  ModeNo = SiS_Pr->SiS_RefIndex[RRTI].ModeID;
 
   if(HwInfo->jChipType >= SIS_315H) {
      if(!(SiS_Pr->SiS_VBInfo & DriverMode)) {
         if( (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x105) ||
             (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x107) ) {
-           if(backupindex <= 1) RefreshRateTableIndex++;
+           if(backupindex <= 1) RRTI++;
         }
      }
   }
 
   i = 0;
   do {
-     if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + i].ModeID != ModeNo) break;
-     temp = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + i].Ext_InfoFlag;
-     temp &= ModeInfoFlag;
+     if(SiS_Pr->SiS_RefIndex[RRTI + i].ModeID != ModeNo) break;
+     temp = SiS_Pr->SiS_RefIndex[RRTI + i].Ext_InfoFlag;
+     temp &= ModeTypeMask;
      if(temp < SiS_Pr->SiS_ModeType) break;
      i++;
      index--;
@@ -342,7 +355,7 @@
 
   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
-      	temp = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + i - 1].Ext_InfoFlag;
+      	temp = SiS_Pr->SiS_RefIndex[RRTI + i - 1].Ext_InfoFlag;
       	if(temp & InterlaceMode) i++;
      }
   }
@@ -351,12 +364,12 @@
 
   if((SiS_Pr->SiS_SetFlag & ProgrammingCRT2) && (!(SiS_Pr->SiS_VBInfo & DisableCRT2Display))) {
      backup_i = i;
-     if(!(SiS_AdjustCRT2Rate(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, &i, HwInfo))) {
+     if(!(SiS_AdjustCRT2Rate(SiS_Pr, ModeNo, ModeIdIndex, RRTI, &i, HwInfo))) {
 	i = backup_i;
      }
   }
 
-  return(RefreshRateTableIndex + i);
+  return(RRTI + i);
 }
 
 /*********************************************/
@@ -383,12 +396,12 @@
 static BOOLEAN
 SiS_CR36BIOSWord23b(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
-  UCHAR *ROMAddr = (UCHAR *)HwInfo->pjVirtualRomBase;
+  UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
   USHORT temp,temp1;
 
   if(SiS_Pr->SiS_UseROM) {
      if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
-        temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xff) >> 4);
+        temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);
         temp1 = SISGETROMW(0x23b);
         if(temp1 & temp) return TRUE;
      }
@@ -399,12 +412,12 @@
 static BOOLEAN
 SiS_CR36BIOSWord23d(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
-  UCHAR *ROMAddr = (UCHAR *)HwInfo->pjVirtualRomBase;
+  UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
   USHORT temp,temp1;
 
   if(SiS_Pr->SiS_UseROM) {
      if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
-        temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xff) >> 4);
+        temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);
         temp1 = SISGETROMW(0x23d);
         if(temp1 & temp) return TRUE;
      }
@@ -478,6 +491,7 @@
 
       PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
       if(SiS_Pr->SiS_VBType & VB_SISVB) {
+         if(SiS_Pr->SiS_VBType & VB_SIS301) PanelID &= 0xf7;
          if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x18) & 0x10)) PanelID = 0x12;
       }
       DelayIndex = PanelID >> 4;
@@ -507,7 +521,8 @@
 
       if((HwInfo->jChipType >= SIS_661)    ||
          (HwInfo->jChipType <= SIS_315PRO) ||
-	 (HwInfo->jChipType == SIS_330)) {
+	 (HwInfo->jChipType == SIS_330)    ||
+	 (SiS_Pr->SiS_ROMNew)) {
 
          if(!(DelayTime & 0x01)) {
 	    SiS_DDC2Delay(SiS_Pr, 0x1000);
@@ -920,7 +935,7 @@
 
    if(!(SiS_Pr->SiS_ChSW)) return;
 
-#ifndef LINUX_XF86
+#ifdef LINUX_KERNEL
    SiS_SetRegLong(0xcf8,0x80000874);		       /* get ACPI base */
    acpibase = SiS_GetRegLong(0xcfc);
 #else
@@ -956,7 +971,7 @@
 
   SiS_Pr->SiS_SetFlag = 0;
 
-  SiS_Pr->SiS_ModeType = modeflag & ModeInfoFlag;
+  SiS_Pr->SiS_ModeType = modeflag & ModeTypeMask;
 
   tempbx = 0;
   if(SiS_BridgeIsOn(SiS_Pr)) {
@@ -981,7 +996,7 @@
 
 #ifdef SIS315H
 	if(HwInfo->jChipType >= SIS_315H) {
-    	   if(SiS_Pr->SiS_VBType & (VB_SIS301C|VB_SIS302B|VB_SIS301LV|VB_SIS302LV|VB_SIS302ELV)) {
+    	   if(SiS_Pr->SiS_VBType & VB_SISLCDA) {
 	      if(ModeNo == 0x03) {
 	         /* Mode 0x03 is never in driver mode */
 		 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x31,0xbf);
@@ -1012,13 +1027,13 @@
 	   if(HwInfo->jChipType >= SIS_661) {
 	      tempbx &= ~(SetCRT2ToYPbPr525750 | SetCRT2ToHiVision);
 	      temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
-	      if(SiS_Pr->SiS_VBType & (VB_SIS301C|VB_SIS301LV|VB_SIS302LV|VB_SIS302ELV)) {
+	      if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
 	         if(temp & 0x04) {
 		    temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xe0;
 		    if(temp == 0x60) tempbx |= SetCRT2ToHiVision;
 		    else             tempbx |= SetCRT2ToYPbPr525750;
 		 }
-	      } else if(SiS_Pr->SiS_VBType & (VB_SIS301 | VB_SIS301B | VB_SIS302B)) {
+	      } else if(SiS_Pr->SiS_VBType & VB_SISHIVISION) {
 	         if(temp & 0x04) {
 		    temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xe0;
 		    if(temp == 0x60) tempbx |= SetCRT2ToHiVision;
@@ -1445,7 +1460,7 @@
    USHORT temp = SiS_Pr->SiS_LCDResInfo;
    /* Translate my LCDResInfo to BIOS value */
    if(temp == Panel_1280x768_2)  temp = Panel_1280x768;
-   if(temp == Panel_1280x768_3)  temp = Panel_1280x768;
+   if(temp == Panel_1280x800_2)  temp = Panel_1280x800;
    return temp;
 }
 
@@ -1501,20 +1516,36 @@
 #endif
 }
 
+static void
+SiS_CheckScaling(SiS_Private *SiS_Pr, USHORT resinfo, const UCHAR *nonscalingmodes)
+{
+    int i = 0;
+    while(nonscalingmodes[i] != 0xff) {
+        if(nonscalingmodes[i++] == resinfo) {
+	   if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ||
+	      (SiS_Pr->UsePanelScaler == -1)) {
+	      SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+	   }
+	   break;
+	}
+    }
+}
+
 void
 SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
 		  PSIS_HW_INFO HwInfo)
 {
 #ifdef SIS300
-  UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
+  UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
+  const unsigned char SiS300SeriesLCDRes[] =
+          { 0,  1,  2,  3,  7,  4,  5,  8,
+	    0,  0, 10,  0,  0,  0,  0, 15 };
 #endif
 #ifdef SIS315H
-  UCHAR  *myptr = NULL;
+  UCHAR   *myptr = NULL;
 #endif
-  USHORT temp,modeflag,resinfo=0;
-  const unsigned char SiS300SeriesLCDRes[] =
-         { 0,  1,  2,  3,  7,  4,  5,  8,
-	   0,  0, 10,  0,  0,  0,  0, 15 };
+  USHORT  temp,modeflag,resinfo=0,modexres=0,modeyres=0;
+  BOOLEAN panelcanscale = FALSE;
 
   SiS_Pr->SiS_LCDResInfo  = 0;
   SiS_Pr->SiS_LCDTypeInfo = 0;
@@ -1534,10 +1565,14 @@
   } else {
      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+     modexres = SiS_Pr->SiS_ModeResInfo[resinfo].HTotal;
+     modeyres = SiS_Pr->SiS_ModeResInfo[resinfo].VTotal;
   }
 
   temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
-  if(!temp) return;
+
+  /* For broken BIOSes: Assume 1024x768 */
+  if(temp == 0) temp = 0x02;
 
   if((HwInfo->jChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
      SiS_Pr->SiS_LCDTypeInfo = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x7c) >> 2;
@@ -1547,24 +1582,31 @@
      SiS_Pr->SiS_LCDTypeInfo = (temp & 0x0F) - 1;
   }
   temp &= 0x0f;
+#ifdef SIS300
   if(HwInfo->jChipType < SIS_315H) {
+     /* Very old BIOSes only know 7 sizes (NetVista 2179, 1.01g) */
+     if(SiS_Pr->SiS_VBType & VB_SIS301) {
+        if(temp < 0x0f) temp &= 0x07;
+     }
      /* Translate 300 series LCDRes to 315 series for unified usage */
      temp = SiS300SeriesLCDRes[temp];
   }
+#endif
 
+  /* Translate to our internal types */
   if(HwInfo->jChipType == SIS_550) {
      if(temp == Panel310_640x480_2) temp = Panel_640x480_2;
      if(temp == Panel310_640x480_3) temp = Panel_640x480_3;
   }
 
-  if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {	/* SiS LVDS */
+  if(SiS_Pr->SiS_VBType & VB_SISLVDS) {	/* SiS LVDS */
      if(temp == Panel310_1280x768) {
         temp = Panel_1280x768_2;
-#ifdef SIS315H
-	if((myptr = GetLCDStructPtr661(SiS_Pr, HwInfo))) {
-	   if((myptr[8] | (myptr[9] << 8)) == 798) temp = Panel_1280x768_3;
+     }
+     if(SiS_Pr->SiS_ROMNew) {
+        if(temp == Panel661_1280x800) {
+	   temp = Panel_1280x800_2;
 	}
-#endif
      }
   }
 
@@ -1586,6 +1628,77 @@
 	SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMinLVDS;
   }
 
+  temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
+  SiS_Pr->SiS_LCDInfo = temp & ~0x000e;
+  /* Need temp below! */
+
+  /* These can't scale no matter what */
+  switch(SiS_Pr->SiS_LCDResInfo) {
+  case Panel_1280x960:
+      SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
+  }
+
+  panelcanscale = (SiS_Pr->SiS_LCDInfo & DontExpandLCD) ? TRUE : FALSE;
+
+  if(!SiS_Pr->UsePanelScaler)          SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
+  else if(SiS_Pr->UsePanelScaler == 1) SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+
+  /* Dual link, Pass 1:1 BIOS default, etc. */
+#ifdef SIS315H
+  if(HwInfo->jChipType >= SIS_661) {
+     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+        if(temp & 0x08) SiS_Pr->SiS_LCDInfo |= LCDPass11;
+     }
+     if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
+        if(SiS_Pr->SiS_ROMNew) {
+	   if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
+	} else if((myptr = GetLCDStructPtr661(SiS_Pr, HwInfo))) {
+           if(myptr[2] & 0x01) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
+	}
+     }
+  } else if(HwInfo->jChipType >= SIS_315H) {
+     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+        if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x01) SiS_Pr->SiS_LCDInfo |= LCDPass11;
+     }
+     if((SiS_Pr->SiS_ROMNew) && (!(SiS_Pr->PanelSelfDetected))) {
+        SiS_Pr->SiS_LCDInfo &= ~(LCDRGB18Bit);
+	temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
+        if(temp & 0x01) SiS_Pr->SiS_LCDInfo |= LCDRGB18Bit;
+	if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
+	   if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
+	}
+     } else if(!(SiS_Pr->SiS_ROMNew)) {
+        if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
+           if((SiS_Pr->SiS_CustomT == CUT_CLEVO1024) &&
+	      (SiS_Pr->SiS_LCDResInfo == Panel_1024x768)) {
+	      SiS_Pr->SiS_LCDInfo |= LCDDualLink;
+	   }
+           if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
+	      (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
+              (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
+	      (SiS_Pr->SiS_LCDResInfo == Panel_1680x1050)) {
+	      SiS_Pr->SiS_LCDInfo |= LCDDualLink;
+	   }
+        }
+     }
+  }
+#endif
+
+  /* Pass 1:1 */
+  if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
+     /* Always center screen on LVDS (if scaling is disabled) */
+     SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
+  } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
+     if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
+        /* Always center screen on SiS LVDS (if scaling is disabled) */
+        SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
+     } else {
+        /* By default, pass 1:1 on SiS TMDS (if scaling is supported) */
+        if(panelcanscale)             SiS_Pr->SiS_LCDInfo |= LCDPass11;
+        if(SiS_Pr->CenterScreen == 1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
+     }
+  }
+
   SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
   SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
 
@@ -1654,31 +1767,37 @@
 			    SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
 			    break;
      case Panel_1280x768:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  768;
-     			    SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   =  802;
-			    SiS_Pr->PanelHRS  =   48; SiS_Pr->PanelHRS  =  112;
-			    SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
-			    SiS_Pr->PanelVCLKIdx300 = VCLK81_300;
-			    SiS_Pr->PanelVCLKIdx315 = VCLK81_315;
+     			    if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+			       SiS_Pr->PanelHT   = 1408; SiS_Pr->PanelVT   =  806;
+			       SiS_Pr->PanelVCLKIdx300 = VCLK81_300; /* ? */
+			       SiS_Pr->PanelVCLKIdx315 = VCLK81_315; /* ? */
+			    } else {
+     			       SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   =  802;
+			       SiS_Pr->PanelHRS  =   48; SiS_Pr->PanelHRS  =  112;
+			       SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
+			       SiS_Pr->PanelVCLKIdx300 = VCLK81_300;
+			       SiS_Pr->PanelVCLKIdx315 = VCLK81_315;
+			    }
 			    break;
      case Panel_1280x768_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  768;
-     			    SiS_Pr->PanelHT   = 1408; SiS_Pr->PanelVT   =  806;
-			    SiS_Pr->PanelHRS  =   16; SiS_Pr->PanelHRE  =   64;
+     			    SiS_Pr->PanelHT   = 1660; SiS_Pr->PanelVT   =  806;
+			    SiS_Pr->PanelHRS  =   48; SiS_Pr->PanelHRE  =  112;
 			    SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
 			    SiS_Pr->PanelVCLKIdx315 = VCLK_1280x768_2;
 			    SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
 			    break;
-     case Panel_1280x768_3: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  768;
-     			    SiS_Pr->PanelHT   = 1664; SiS_Pr->PanelVT   =  798;
-			    SiS_Pr->PanelHRS   =  64; SiS_Pr->PanelHRE  =  128;
-			    SiS_Pr->PanelVRS   =   3; SiS_Pr->PanelVRE  =    7;
-			    SiS_Pr->PanelVCLKIdx315 = VCLK_1280x768_3;
+     case Panel_1280x800:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  800;
+     			    SiS_Pr->PanelHT   = 1408; SiS_Pr->PanelVT   =  816;
+			    SiS_Pr->PanelHRS   =  21; SiS_Pr->PanelHRE  =   24;
+			    SiS_Pr->PanelVRS   =   4; SiS_Pr->PanelVRE  =    3;
+			    SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315;
 			    SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
 			    break;
-     case Panel_1280x800:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  800;
-     			    SiS_Pr->PanelHT   = 1656; SiS_Pr->PanelVT   =  841;  /* 1408, 816 */
-			    SiS_Pr->PanelHRS   =  32; SiS_Pr->PanelHRE  =  312;  /*   16,  64 */
-			    SiS_Pr->PanelVRS   =  16; SiS_Pr->PanelVRE  =    8;  /*    4,   3 */
-			    SiS_Pr->PanelVCLKIdx315 = VCLK83_315;
+     case Panel_1280x800_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  800;
+     			    SiS_Pr->PanelHT   = 1552; SiS_Pr->PanelVT   =  812;
+			    SiS_Pr->PanelHRS   =  48; SiS_Pr->PanelHRE  =  112;
+			    SiS_Pr->PanelVRS   =   4; SiS_Pr->PanelVRE  =    3;
+			    SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315_2;
 			    SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
 			    break;
      case Panel_1280x960:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  960;
@@ -1719,6 +1838,12 @@
 			    SiS_Pr->PanelVCLKIdx315 = VCLK121_315;
 			    SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
 			    break;
+     case Panel_Barco1366:  SiS_Pr->PanelXRes = 1360; SiS_Pr->PanelYRes = 1024;
+     			    SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   = 1066;
+     			    break;
+     case Panel_848x480:    SiS_Pr->PanelXRes =  848; SiS_Pr->PanelYRes =  480;
+     			    SiS_Pr->PanelHT   = 1088; SiS_Pr->PanelVT   =  525;
+     			    break;
      case Panel_Custom:     SiS_Pr->PanelXRes = SiS_Pr->CP_MaxX;
     			    SiS_Pr->PanelYRes = SiS_Pr->CP_MaxY;
 			    SiS_Pr->PanelHT   = SiS_Pr->CHTotal;
@@ -1736,63 +1861,185 @@
 			       SiS_Pr->PanelHRE -= SiS_Pr->PanelHRS;
 			       SiS_Pr->PanelVRS -= SiS_Pr->PanelYRes;
 			       SiS_Pr->PanelVRE -= SiS_Pr->PanelVRS;
+			       if(SiS_Pr->CP_PrefClock) {
+			          int idx;
+			          SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
+				  SiS_Pr->PanelVCLKIdx300 = VCLK_CUSTOM_300;
+				  if(HwInfo->jChipType < SIS_315H) idx = VCLK_CUSTOM_300;
+				  else				   idx = VCLK_CUSTOM_315;
+      			          SiS_Pr->SiS_VCLKData[idx].CLOCK =
+	 		             SiS_Pr->SiS_VBVCLKData[idx].CLOCK = SiS_Pr->CP_PrefClock;
+      			          SiS_Pr->SiS_VCLKData[idx].SR2B =
+  	 			     SiS_Pr->SiS_VBVCLKData[idx].Part4_A = SiS_Pr->CP_PrefSR2B;
+      			          SiS_Pr->SiS_VCLKData[idx].SR2C =
+	 			     SiS_Pr->SiS_VBVCLKData[idx].Part4_B = SiS_Pr->CP_PrefSR2C;
+			       }
 			    }
 			    break;
-     case Panel_Barco1366:  SiS_Pr->PanelXRes = 1360; SiS_Pr->PanelYRes = 1024;
-     			    SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   = 1066;
-     			    break;
-     case Panel_848x480:    SiS_Pr->PanelXRes =  848; SiS_Pr->PanelYRes =  480;
-     			    SiS_Pr->PanelHT   = 1088; SiS_Pr->PanelVT   =  525;
-     			    break;
      default:		    SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes =  768;
      			    SiS_Pr->PanelHT   = 1344; SiS_Pr->PanelVT   =  806;
 			    break;
   }
 
-  temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
-  SiS_Pr->SiS_LCDInfo = temp & ~0x000e;
+  /* Special cases */
+  if( (SiS_Pr->SiS_IF_DEF_FSTN)              ||
+      (SiS_Pr->SiS_IF_DEF_DSTN)              ||
+      (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
+      (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
+      (SiS_Pr->SiS_CustomT == CUT_PANEL848) ) {
+     SiS_Pr->PanelHRS = 999;
+     SiS_Pr->PanelHRE = 999;
+  }
 
-  if(!(SiS_Pr->UsePanelScaler))        SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
-  else if(SiS_Pr->UsePanelScaler == 1) SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+  if( (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
+      (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
+      (SiS_Pr->SiS_CustomT == CUT_PANEL848) ) {
+     SiS_Pr->PanelVRS = 999;
+     SiS_Pr->PanelVRE = 999;
+  }
 
-#ifdef SIS315H
-  if(HwInfo->jChipType >= SIS_661) {
-     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
-        if(temp & 0x08) SiS_Pr->SiS_LCDInfo |= LCDPass11;
+  /* DontExpand overrule */
+  if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
+
+     if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (modeflag & NoSupportLCDScale)) {
+	/* No scaling for this mode on any panel (LCD=CRT2)*/
+	SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
      }
-     if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
-        if(SiS_Pr->SiS_ROMNew) {
-	   if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
-	} else if((myptr = GetLCDStructPtr661(SiS_Pr, HwInfo))) {
-           if(myptr[2] & 0x01) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
+
+     switch(SiS_Pr->SiS_LCDResInfo) {
+
+     case Panel_Custom:
+     case Panel_1152x864:
+     case Panel_1280x768:	/* TMDS only */
+        SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+	break;
+
+     case Panel_800x600: {
+        static const UCHAR nonscalingmodes[] = {
+	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, 0xff
+	};
+	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
+	break;
+     }
+     case Panel_1024x768: {
+        static const UCHAR nonscalingmodes[] = {
+	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
+	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
+	   0xff
+	};
+	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
+	break;
+     }
+     case Panel_1280x720: {
+        static const UCHAR nonscalingmodes[] = {
+	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
+	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
+	   0xff
+	};
+	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
+	if(SiS_Pr->PanelHT == 1650) {
+	   SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
 	}
+	break;
      }
-  } else if(HwInfo->jChipType >= SIS_315H) {
-     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
-        if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x01) SiS_Pr->SiS_LCDInfo |= LCDPass11;
+     case Panel_1280x768_2: {  /* LVDS only */
+        static const UCHAR nonscalingmodes[] = {
+	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
+	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
+	   SIS_RI_1152x768,0xff
+	};
+	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
+	switch(resinfo) {
+	case SIS_RI_1280x720:  if(SiS_Pr->UsePanelScaler == -1) {
+	      			  SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+	   		       }
+	   		       break;
+	}
+        break;
      }
-     if((SiS_Pr->SiS_ROMNew) && (!(SiS_Pr->PanelSelfDetected))) {
-        SiS_Pr->SiS_LCDInfo &= ~(LCDRGB18Bit);
-	temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
-        if(temp & 0x01) SiS_Pr->SiS_LCDInfo |= LCDRGB18Bit;
-	if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
-	   if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
+     case Panel_1280x800: {  	/* SiS TMDS special (Averatec 6200 series) */
+        static const UCHAR nonscalingmodes[] = {
+	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
+	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
+	   SIS_RI_1152x768,SIS_RI_1280x720,SIS_RI_1280x768,0xff
+	};
+	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
+        break;
+     }
+     case Panel_1280x800_2:  { 	/* SiS LVDS */
+        static const UCHAR nonscalingmodes[] = {
+	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
+	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
+	   SIS_RI_1152x768,0xff
+	};
+	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
+	switch(resinfo) {
+	case SIS_RI_1280x720:
+	case SIS_RI_1280x768:  if(SiS_Pr->UsePanelScaler == -1) {
+	      			  SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+	   		       }
+	   		       break;
 	}
+        break;
+     }
+     case Panel_1280x960: {
+        static const UCHAR nonscalingmodes[] = {
+	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
+	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
+	   SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
+	   0xff
+	};
+	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
+        break;
+     }
+     case Panel_1280x1024: {
+        static const UCHAR nonscalingmodes[] = {
+	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
+	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
+	   SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
+	   SIS_RI_1280x960,0xff
+	};
+	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
+	break;
+     }
+     case Panel_1400x1050: {
+        static const UCHAR nonscalingmodes[] = {
+	     SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
+	     SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
+	     SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x768,SIS_RI_1280x800,SIS_RI_1280x960,
+	     0xff
+	};
+	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
+        switch(resinfo) {
+	case SIS_RI_1280x720:  if(SiS_Pr->UsePanelScaler == -1) {
+	      			  SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+	   		       }
+	   		       break;
+	case SIS_RI_1280x1024: SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+	      		       break;
+	}
+	break;
+     }
+     case Panel_1600x1200: {
+        static const UCHAR nonscalingmodes[] = {
+	     SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
+	     SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
+	     SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
+	     SIS_RI_1280x960,SIS_RI_1360x768,SIS_RI_1360x1024,0xff
+	};
+	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
+        break;
+     }
+     case Panel_1680x1050: {
+        static const UCHAR nonscalingmodes[] = {
+	     SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
+	     SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
+	     SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x960,SIS_RI_1360x768,SIS_RI_1360x1024,
+	     0xff
+	};
+	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
+	break;
      }
-  }
-#endif
-
-  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-     /* Always center screen on LVDS (if scaling is disabled) */
-     SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
-  } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
-     if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
-        /* Always center screen on SiS LVDS (if scaling is disabled) */
-        SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
-     } else {
-        /* By default, pass 1:1 on SiS TMDS (if scaling is disabled) */
-        SiS_Pr->SiS_LCDInfo |= LCDPass11;
-        if(SiS_Pr->CenterScreen == 1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
      }
   }
 
@@ -1802,78 +2049,6 @@
      }
   }
 
-  if(SiS_Pr->SiS_VBType & VB_SISVB) {
-     if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
-        if(modeflag & NoSupportLCDScale) {
-	   /* No scaling for this mode on any panel */
-	   SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
-	}
-        switch(SiS_Pr->SiS_LCDResInfo) {
-        case Panel_Custom:
-		/* For non-standard LCD resolution, we let the panel scale */
-           	SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
-		break;
-	case Panel_1280x720:
-	      	if(SiS_Pr->PanelHT == 1650) {
-		   SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
-		}
-	case Panel_1280x768:	/* TMDS only */
-		/* No idea about the timing and zoom factors */
-           	SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
-		break;
-	case Panel_1280x960:
-	 	SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
-		break;
-	case Panel_1280x1024:
-	        if(SiS_Pr->SiS_VBType & VB_SISTMDS) {
-		   if(ModeNo == 0x7c || ModeNo == 0x7d || ModeNo == 0x7e ||
-		      ModeNo == 0x79 || ModeNo == 0x75 || ModeNo == 0x78 ||
-		      ModeNo == 0x14 || ModeNo == 0x15 || ModeNo == 0x16) {
-	      	      /* We do not scale to 1280x720/800/960 (B/C bridges only) */
-                      SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
-	           }
-	           if(((HwInfo->jChipType >= SIS_315H) &&
-		       (ModeNo == 0x23 || ModeNo == 0x24 || ModeNo == 0x25)) ||
-	              ((HwInfo->jChipType < SIS_315H)  &&
-		       (ModeNo == 0x55 || ModeNo == 0x5a || ModeNo == 0x5b))) {
-	              /* We do not scale to 1280x768 (B/C bridges only) */
-                      SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
-	           }
-		}
-		break;
-	case Panel_1400x1050:
-	 	if(SiS_Pr->SiS_VBType & VB_SISTMDS) {
-	  	   if(ModeNo == 0x7c || ModeNo == 0x7d || ModeNo == 0x7e ||
-		      ModeNo == 0x79 || ModeNo == 0x75 || ModeNo == 0x78 ||
-		      ModeNo == 0x14 || ModeNo == 0x15 || ModeNo == 0x16 ||
-		      ModeNo == 0x23 || ModeNo == 0x24 || ModeNo == 0x25) {
-	      	      /* Do not scale to 1280x720/768/800/960 (B/C bridges only) */
-                      SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
-	           }
-		}
-		if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
-		   if(ModeNo == 0x79 || ModeNo == 0x75 || ModeNo == 0x78) {
-		      if(SiS_Pr->UsePanelScaler == -1) {
-		         /* Do not scale to 1280x720 by default (LVDS bridges) */
-	      	         SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
-		      }
-		   }
-		}
-		if(ModeNo == 0x3a || ModeNo == 0x4d || ModeNo == 0x65) {
-	      	   /* Do not scale to 1280x1024 (all bridges) */
-	      	   SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
-	   	}
-		break;
-	case Panel_1600x1200:
-		if(SiS_Pr->SiS_VBType & VB_SISTMDS) {
-	      	   /* No idea about the timing and zoom factors (C bridge only) */
-	      	   SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
-	   	}
-		break;
-	}
-     }
-  }
-
 #ifdef SIS300
   if(HwInfo->jChipType < SIS_315H) {
      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
@@ -1893,12 +2068,32 @@
 #endif
 
   /* Special cases */
+
+  if(modexres == SiS_Pr->PanelXRes && modeyres == SiS_Pr->PanelYRes) {
+     SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
+  }
+
   if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
      SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
   }
 
-  if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) {
+  switch(SiS_Pr->SiS_LCDResInfo) {
+  case Panel_640x480:
      SiS_Pr->SiS_LCDInfo |= LCDPass11;
+     break;
+  case Panel_1280x800:
+     /* Don't pass 1:1 by default (TMDS special) */
+     if(SiS_Pr->CenterScreen == -1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
+     break;
+  case Panel_1280x960:
+     SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
+     break;
+  case Panel_Custom:
+     if((!SiS_Pr->CP_PrefClock) ||
+        (modexres > SiS_Pr->PanelXRes) || (modeyres > SiS_Pr->PanelYRes)) {
+        SiS_Pr->SiS_LCDInfo |= LCDPass11;
+     }
+     break;
   }
 
   if(SiS_Pr->UseCustomMode) {
@@ -1910,49 +2105,10 @@
      SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
   }
 
-  /* Special cases */
-  if( (SiS_Pr->SiS_IF_DEF_FSTN)              ||
-      (SiS_Pr->SiS_IF_DEF_DSTN)              ||
-      (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
-      (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
-      (SiS_Pr->SiS_CustomT == CUT_PANEL848) ) {
-     SiS_Pr->PanelHRS = 999;
-     SiS_Pr->PanelHRE = 999;
-  }
-
-  if( (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
-      (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
-      (SiS_Pr->SiS_CustomT == CUT_PANEL848) ) {
-     SiS_Pr->PanelVRS = 999;
-     SiS_Pr->PanelVRE = 999;
-  }
-
-#ifdef SIS315H
-  if((HwInfo->jChipType >= SIS_315H) && (HwInfo->jChipType < SIS_661)) {
-     if(!(SiS_Pr->SiS_ROMNew)) {
-        if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
-	   /* Enable 302LV/302ELV dual link mode.
-	    * For 661, this is done above.
-	    */
-           if((SiS_Pr->SiS_CustomT == CUT_CLEVO1024) &&
-	      (SiS_Pr->SiS_LCDResInfo == Panel_1024x768)) {
-	      /* (Sets this in SenseLCD; new paneltypes) */
-	      SiS_Pr->SiS_LCDInfo |= LCDDualLink;
-	   }
-           if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
-	      (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
-              (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
-	      (SiS_Pr->SiS_LCDResInfo == Panel_1680x1050)) {
-	      SiS_Pr->SiS_LCDInfo |= LCDDualLink;
-	   }
-        }
-     }
-  }
-#endif
-
+  /* LVDS DDA */
   if(!((HwInfo->jChipType < SIS_315H) && (SiS_Pr->SiS_SetFlag & SetDOSMode))) {
 
-     if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+     if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
 	if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
 	   if(ModeNo == 0x12) {
 	      if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
@@ -1988,6 +2144,7 @@
 
   }
 
+  /* VESA timing */
   if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
      if(SiS_Pr->SiS_VBInfo & SetNotSimuMode) {
      	SiS_Pr->SiS_SetFlag |= LCDVESATiming;
@@ -2043,19 +2200,15 @@
 
            if(HwInfo->jChipType < SIS_315H) {
 	      VCLKIndex = SiS_Pr->PanelVCLKIdx300;
+	      if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
+	         VCLKIndex = VCLKIndexGEN;
+	      }
 	   } else {
 	      VCLKIndex = SiS_Pr->PanelVCLKIdx315;
 	      if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
-	         VCLKIndex = VCLKIndexGEN;
 		 switch(resinfo) {
-		 /* Only those whose IndexGEN doesn't match VBVCLK array: */
-		 case SIS_RI_1280x720: VCLKIndex = VCLK_1280x720;
-		 		       if(SiS_Pr->SiS_LCDResInfo == Panel_1280x720) {
-		                          if(SiS_Pr->PanelHT == 1344) {
-					     VCLKIndex = VCLK_1280x720_2;
-					  }
-				       }
-		 		       break;
+		 /* Only those whose IndexGEN doesn't match VBVCLK array */
+		 case SIS_RI_1280x720: VCLKIndex = VCLK_1280x720; break;
 		 case SIS_RI_720x480:  VCLKIndex = VCLK_720x480;  break;
 		 case SIS_RI_720x576:  VCLKIndex = VCLK_720x576;  break;
 		 case SIS_RI_768x576:  VCLKIndex = VCLK_768x576;  break;
@@ -2065,6 +2218,7 @@
 		 case SIS_RI_1024x576: VCLKIndex = VCLK_1024x576; break;
 		 case SIS_RI_1152x864: VCLKIndex = VCLK_1152x864; break;
 		 case SIS_RI_1360x768: VCLKIndex = VCLK_1360x768; break;
+		 default:              VCLKIndex = VCLKIndexGEN;
 		 }
 
 		 if(ModeNo <= 0x13) {
@@ -2121,7 +2275,7 @@
            if(ModeNo > 0x13) {
 	      if( (HwInfo->jChipType != SIS_630) &&
 		  (HwInfo->jChipType != SIS_300) ) {
-		 if(VCLKIndex == 0x1b) VCLKIndex = 0x35;
+		 if(VCLKIndex == 0x1b) VCLKIndex = 0x48;
 	      }
 	   }
         }
@@ -2207,7 +2361,7 @@
            if(ModeNo > 0x13) {
 	      if( (HwInfo->jChipType != SIS_630) &&
 	          (HwInfo->jChipType != SIS_300) ) {
-		 if(VCLKIndex == 0x1b) VCLKIndex = 0x35;
+		 if(VCLKIndex == 0x1b) VCLKIndex = 0x48;
 	      }
 #if 0
 	      if(HwInfo->jChipType == SIS_730) {
@@ -2255,10 +2409,6 @@
      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
   }
 
-  /* BIOS does not do this (neither 301 nor LVDS) */
-  /* (But it's harmless; see SetCRT2Offset) */
-  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,0x00);   /* fix write part1 index 0  BTDRAM bit Bug */
-
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
 
      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xAF,0x40);
@@ -2372,13 +2522,9 @@
       	   tempah |= 0x10;
         }
 
-        if((HwInfo->jChipType < SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS301)) {
-	   if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
-	      (SiS_Pr->SiS_LCDResInfo == Panel_1280x960)) {
-	      tempah |= 0x80;
-	   }
-        } else {
-	   tempah |= 0x80;
+	tempah |= 0x80;
+        if(SiS_Pr->SiS_VBType & VB_SIS301) {
+	   if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah &= ~0x80;
         }
 
         if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
@@ -2391,7 +2537,10 @@
 
         SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0D,0x40,tempah);
 
-        tempah = 0;
+	tempah = 0x80;
+	if(SiS_Pr->SiS_VBType & VB_SIS301) {
+	   if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah = 0;
+	}
 
 	if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempah |= 0x40;
 
@@ -2401,19 +2550,13 @@
        	   }
         }
 
-	if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
-	   (SiS_Pr->SiS_LCDResInfo == Panel_1280x960)  ||
-	   ((SiS_Pr->SiS_LCDResInfo == Panel_Custom) &&
-	    (SiS_Pr->CP_MaxX >= 1280) && (SiS_Pr->CP_MaxY >= 960))) {
-	   tempah |= 0x80;
-        }
-
         SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0C,tempah);
 
      } else {  /* LVDS */
 
         if(HwInfo->jChipType >= SIS_315H) {
 
+#ifdef SIS315H
 	   /* LVDS can only be slave in 8bpp modes */
 	   tempah = 0x80;
 	   if((modeflag & CRT2Mode) && (SiS_Pr->SiS_ModeType > ModeVGA)) {
@@ -2435,9 +2578,11 @@
 	   }
 
     	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2e,0xF0,tempah);
+#endif
 
         } else {
 
+#ifdef SIS300
 	   tempah = 0;
 	   if( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) && (SiS_Pr->SiS_ModeType > ModeVGA) ) {
               tempah |= 0x02;
@@ -2447,6 +2592,7 @@
 	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display)  tempah = 0;
 
 	   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
+#endif
 
         }
 
@@ -2459,7 +2605,6 @@
      if(HwInfo->jChipType >= SIS_315H) {
 
 #ifdef SIS315H
-
         unsigned char bridgerev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01);
 
 	/* The following is nearly unpreditable and varies from machine
@@ -2538,26 +2683,29 @@
            SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,tempbl,tempah);
 	}
 
-#if 0
-	if(SiS_Pr->SiS_VBType & VB_SIS301C) {
-	   SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3a,0xc0);
-	}
-#endif
-
 #endif /* SIS315H */
 
      } else if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
 
+#ifdef SIS300
         SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
 
         if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
-           (   (SiS_Pr->SiS_VBType & VB_NoLCD) &&
-	       (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ) ) {
+           ((SiS_Pr->SiS_VBType & VB_NoLCD) &&
+	    (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD))) {
 	   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x23,0x7F);
 	} else {
 	   SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x23,0x80);
 	}
+#endif
+
+     }
 
+     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+        SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x0D,0x80);
+        if(SiS_Pr->SiS_VBType & VB_SIS301C) {
+	   SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3A,0xC0);
+        }
      }
 
   } else {  /* LVDS */
@@ -2823,19 +2971,18 @@
 	if(SiS_Pr->SiS_LCDResInfo == Panel_1680x1050) {
 	   if     (resinfo == SIS_RI_1280x800)  tempal =  9;
 	   else if(resinfo == SIS_RI_1400x1050) tempal = 11;
+	} else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x800) ||
+	          (SiS_Pr->SiS_LCDResInfo == Panel_1280x800_2)) {
+	   if     (resinfo == SIS_RI_1280x768)  tempal =  9;
 	}
 
-  	if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {  /* Pass 1:1 only (center-screen handled outside) */
+  	if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+	   /* Pass 1:1 only (center-screen handled outside) */
+	   /* This is never called for the panel's native resolution */
+	   /* since Pass1:1 will not be set in this case */
 	   tempbx = 100;
 	   if(ModeNo >= 0x13) {
 	      tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
-	      if((SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes == 1280) &&
-	         (SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].YRes ==  768)) {
-	         /* Special for Fujitsu 7911 (VL-17WDX8), others custom */
-	         if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768)        tempal = 0x08;
-		 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768_2) tempal = 0x0f;
-		 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768_3) tempal = 0x10;
-	      }
 	   }
 	}
 
@@ -2907,6 +3054,7 @@
 
      tempbx = 0;
      if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
+
         tempbx = 10;
 	if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
         if(SiS_Pr->SiS_TVMode & TVSetPAL) {
@@ -2922,10 +3070,12 @@
 	      if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
 	   }
         }
+
      } else {
+
         switch(SiS_Pr->SiS_LCDResInfo) {
 	case Panel_640x480:   tempbx = 6;  break;
-	case Panel_640x480_2: tempbx = 30; break;
+	case Panel_640x480_2:
 	case Panel_640x480_3: tempbx = 30; break;
 	case Panel_800x600:   tempbx = 0;  break;
 	case Panel_1024x600:  tempbx = 15; break;
@@ -2951,19 +3101,20 @@
 
 	if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
 	   tempbx = 82;
-	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx++;
+	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
 	} else if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
 	   tempbx = 84;
-	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx++;
+	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
 	}
 
-     }
+	if((SiS_Pr->SiS_CustomT != CUT_BARCO1366) &&
+           (SiS_Pr->SiS_CustomT != CUT_PANEL848)) {
+           if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) &&
+	      (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
+              tempal = 0;
+	   }
+        }
 
-     if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
-        if(SiS_Pr->SiS_LCDResInfo != Panel_640x480) tempal = 7;
-  	if(HwInfo->jChipType < SIS_315H) {
-	   if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) tempal++;
-	}
      }
 
      (*CRT2Index) = tempbx;
@@ -3062,20 +3213,6 @@
 	          ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
 	       } else {
 	          ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
-		  /* Special for our 3 types, others custom (works with default) */
-		  if((SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes == 1280) &&
-	             (SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].YRes ==  768)) {
-	             if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768)        ResIndex = 0x08;
-		     else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768_2) ResIndex = 0x0f;
-		     else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768_3) ResIndex = 0x10;
-	          }
-		  /* Special for 1280x720 TMDS <> LVDS */
-		  if((SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes == 1280) &&
-	             (SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].YRes ==  720)) {
-		     if(SiS_Pr->SiS_LCDResInfo == Panel_1280x720) {
-		        if(SiS_Pr->PanelHT == 1344) ResIndex = 0x12;
-		     }
-	          }
 	       }
 	       SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAHT;
                SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAVT;
@@ -3348,12 +3485,12 @@
 
      if(SiS_Pr->UseCustomMode) {
 
-        SiS_Pr->SiS_VGAHT     = SiS_Pr->CHTotal;
-        SiS_Pr->SiS_VGAVT     = SiS_Pr->CVTotal;
-        SiS_Pr->SiS_HT        = SiS_Pr->CHTotal;
-        SiS_Pr->SiS_VT        = SiS_Pr->CVTotal;
-	SiS_Pr->SiS_HDE       = SiS_Pr->SiS_VGAHDE;
-        SiS_Pr->SiS_VDE       = SiS_Pr->SiS_VGAVDE;
+        SiS_Pr->SiS_VGAHT = SiS_Pr->CHTotal;
+        SiS_Pr->SiS_VGAVT = SiS_Pr->CVTotal;
+        SiS_Pr->SiS_HT    = SiS_Pr->CHTotal;
+        SiS_Pr->SiS_VT    = SiS_Pr->CVTotal;
+	SiS_Pr->SiS_HDE   = SiS_Pr->SiS_VGAHDE;
+        SiS_Pr->SiS_VDE   = SiS_Pr->SiS_VGAVDE;
 
      } else {
 
@@ -3361,10 +3498,10 @@
 
         if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
 
-           SiS_Pr->SiS_VGAHT     = SiS_Pr->PanelHT;
-           SiS_Pr->SiS_VGAVT     = SiS_Pr->PanelVT;
-           SiS_Pr->SiS_HT        = SiS_Pr->PanelHT;
-           SiS_Pr->SiS_VT        = SiS_Pr->PanelVT;
+           SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT;
+           SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT;
+           SiS_Pr->SiS_HT    = SiS_Pr->PanelHT;
+           SiS_Pr->SiS_VT    = SiS_Pr->PanelVT;
 	   gotit = TRUE;
 
 	} else if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) && (romptr) && (ROMAddr) ) {
@@ -3377,6 +3514,15 @@
            SiS_Pr->SiS_HT        = ROMAddr[romptr+5] | ((ROMAddr[romptr+6] & 0x0f) << 8);
            SiS_Pr->SiS_VT        = ROMAddr[romptr+7] | ((ROMAddr[romptr+6] & 0xf0) << 4);
 	   if(SiS_Pr->SiS_VGAHT) gotit = TRUE;
+	   else {
+	      SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+	      SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
+	      SiS_Pr->SiS_VGAHT   = SiS_Pr->PanelHT;
+              SiS_Pr->SiS_VGAVT   = SiS_Pr->PanelVT;
+              SiS_Pr->SiS_HT      = SiS_Pr->PanelHT;
+              SiS_Pr->SiS_VT      = SiS_Pr->PanelVT;
+	      gotit = TRUE;
+	   }
 #endif
 
 	}
@@ -3393,10 +3539,10 @@
 	      case Panel_1280x720  + 32: LCDPtr = SiS_Pr->SiS_LCD1280x720Data;      break;
 	      case Panel_1280x768_2    : LCDPtr = SiS_Pr->SiS_ExtLCD1280x768_2Data; break;
               case Panel_1280x768_2+ 32: LCDPtr = SiS_Pr->SiS_StLCD1280x768_2Data;  break;
-	      case Panel_1280x768_3    :
-	      case Panel_1280x768_3+ 32: LCDPtr = SiS_Pr->SiS_LCD1280x768_3Data;    break;
 	      case Panel_1280x800      :
 	      case Panel_1280x800  + 32: LCDPtr = SiS_Pr->SiS_LCD1280x800Data;      break;
+	      case Panel_1280x800_2    :
+	      case Panel_1280x800_2+ 32: LCDPtr = SiS_Pr->SiS_LCD1280x800_2Data;    break;
 	      case Panel_1280x960      :
 	      case Panel_1280x960  + 32: LCDPtr = SiS_Pr->SiS_LCD1280x960Data;      break;
               case Panel_1280x1024     : LCDPtr = SiS_Pr->SiS_ExtLCD1280x1024Data;  break;
@@ -3777,9 +3923,11 @@
            }
 
 	   if(!(SiS_IsNotM650orLater(SiS_Pr, HwInfo))) {
-	      tempah = 0xef;
-	      if(SiS_IsVAMode(SiS_Pr,HwInfo)) tempah = 0xf7;
-	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
+	      if(HwInfo->jChipType < SIS_340) {
+	         tempah = 0xef;
+	         if(SiS_IsVAMode(SiS_Pr,HwInfo)) tempah = 0xf7;
+	         SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
+	      }
 	   }
 
 	   if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
@@ -3962,7 +4110,9 @@
 #ifdef SIS315H	/* 315 series */
 
         if(!(SiS_IsNotM650orLater(SiS_Pr,HwInfo))) {
-          SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,~0x18);
+	   if(HwInfo->jChipType < SIS_340) {
+              SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,~0x18);
+	   }
         }
 
 	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
@@ -4185,12 +4335,14 @@
 	 }
 
          if(!(SiS_IsNotM650orLater(SiS_Pr, HwInfo))) {
-	    tempah = 0x10;
-	    if(SiS_LCDAEnabled(SiS_Pr, HwInfo)) {
-	       if(SiS_TVEnabled(SiS_Pr, HwInfo)) tempah = 0x18;
-	       else 			         tempah = 0x08;
+	    if(HwInfo->jChipType < SIS_340) {
+	       tempah = 0x10;
+	       if(SiS_LCDAEnabled(SiS_Pr, HwInfo)) {
+	          if(SiS_TVEnabled(SiS_Pr, HwInfo)) tempah = 0x18;
+	          else 			            tempah = 0x08;
+	       }
+	       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4c,tempah);
 	    }
-	    SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4c,tempah);
 	 }
 
 	 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
@@ -4267,6 +4419,7 @@
 #ifdef SET_EMI
 	       if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
 	          SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
+		  SiS_GenericDelay(SiS_Pr, 0x500);
 	       }
 #endif
 	       SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c);
@@ -4277,13 +4430,13 @@
 
 		  if(SiS_Pr->SiS_ROMNew) {
 		     UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
-		     USHORT romptr   = GetLCDStructPtr661_2(SiS_Pr, HwInfo);
+		     USHORT romptr = GetLCDStructPtr661_2(SiS_Pr, HwInfo);
 		     if(romptr) {
-		        SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20);
+		        SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
 			SiS_Pr->EMI_30 = 0;
-			SiS_Pr->EMI_31 = ROMAddr[romptr + 14];
-			SiS_Pr->EMI_32 = ROMAddr[romptr + 15];
-			SiS_Pr->EMI_33 = ROMAddr[romptr + 16];
+			SiS_Pr->EMI_31 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 0];
+			SiS_Pr->EMI_32 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 1];
+			SiS_Pr->EMI_33 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 2];
 			if(ROMAddr[romptr + 1] & 0x10) SiS_Pr->EMI_30 = 0x40;
 			/* emidelay = SISGETROMW((romptr + 0x22)); */
 			SiS_Pr->HaveEMI = SiS_Pr->HaveEMILCD = SiS_Pr->OverruleEMI = TRUE;
@@ -4382,7 +4535,8 @@
  		  }
 
 		  if(!(SiS_Pr->OverruleEMI && (!r30) && (!r31) && (!r32) && (!r33))) {
-		     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20);
+		     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
+		     SiS_GenericDelay(SiS_Pr, 0x500);
 		  }
 		  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x31,r31);
 		  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x32,r32);
@@ -4404,7 +4558,7 @@
 			if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
 			   SiS_GenericDelay(SiS_Pr, 0x500);
 			}
-	                SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40);
+	                SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40);   /* Enable */
 	             }
 		  }
 #endif
@@ -4537,7 +4691,9 @@
 #ifdef SIS315H    /* 315 series */
 
        if(!(SiS_IsNotM650orLater(SiS_Pr,HwInfo))) {
-          SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,0x18);
+          if(HwInfo->jChipType < SIS_340) {
+             SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,0x18);
+	  }
        }
 
        if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
@@ -4794,9 +4950,11 @@
   	         }
 	      }
 	      if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
-	         if(SiS_Pr->SiS_LCDInfo & LCDSync) {
-	            tempah = SiS_Pr->SiS_LCDInfo;
-		    tempbl = (tempah >> 6) & 0x03;
+	         if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
+	            if(SiS_Pr->SiS_LCDInfo & LCDSync) {
+	               tempah = SiS_Pr->SiS_LCDInfo;
+		       tempbl = (tempah >> 6) & 0x03;
+		    }
 	         }
 	      }
 	   }
@@ -4901,7 +5059,7 @@
 
      CRT1ModeNo = 0xfe;
      VCLK = SiS_Pr->CSRClock_CRT1;					/* Get VCLK */
-     data2 = (SiS_Pr->CModeFlag_CRT1 & ModeInfoFlag) - 2;
+     data2 = (SiS_Pr->CModeFlag_CRT1 & ModeTypeMask) - 2;
      switch(data2) {							/* Get color depth */
         case 0 : colorth = 1; break;
         case 1 : colorth = 1; break;
@@ -4964,7 +5122,7 @@
 
     } else if(HwInfo->jChipType == SIS_730) {
 
-#ifndef LINUX_XF86
+#ifdef LINUX_KERNEL
        SiS_SetRegLong(0xcf8,0x80000050);
        eax = SiS_GetRegLong(0xcfc);
 #else
@@ -4974,7 +5132,7 @@
        tempal &= 0x06;
        tempal <<= 5;
 
-#ifndef LINUX_XF86
+#ifdef LINUX_KERNEL
        SiS_SetRegLong(0xcf8,0x800000A0);
        eax = SiS_GetRegLong(0xcfc);
 #else
@@ -5004,7 +5162,7 @@
        temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
        if(temp & 0x0080) index += 12;
 
-#ifndef LINUX_XF86
+#ifdef LINUX_KERNEL
        SiS_SetRegLong(0xcf8,0x800000A0);
        eax = SiS_GetRegLong(0xcfc);
 #else
@@ -5017,7 +5175,7 @@
        temp = (USHORT)(eax >> 24);
        if(!(temp&0x01)) index += 24;
 
-#ifndef LINUX_XF86
+#ifdef LINUX_KERNEL
        SiS_SetRegLong(0xcf8,0x80000050);
        eax = SiS_GetRegLong(0xcfc);
 #else
@@ -5512,9 +5670,8 @@
 #endif
   }
 
-  /* is lvds if really LVDS, or SiS 301B-DH with external LVDS transmitter */
-  if((SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
-     ((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBType & VB_NoLCD))) {
+  /* is lvds if really LVDS, or 301B-DH with external LVDS transmitter */
+  if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
      islvds = TRUE;
   }
 
@@ -7467,7 +7624,7 @@
    if(!(temp & 0x01)) {
       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3a,0xdf);
       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xfc);
-      if(HwInfo->jChipType < SIS_661) {
+      if((HwInfo->jChipType < SIS_661) && (!(SiS_Pr->SiS_ROMNew))) {
          SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xf8);
       }
       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x0f,0xfb);
@@ -7475,7 +7632,7 @@
       else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) temp = 0x0002;
       else if(SiS_Pr->SiS_TVMode & TVSetHiVision)  temp = 0x0400;
       else					   temp = 0x0402;
-      if(HwInfo->jChipType >= SIS_661) {
+      if((HwInfo->jChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
          temp1 = 0;
 	 if(SiS_Pr->SiS_TVMode & TVAspect43) temp1 = 4;
 	 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0f,0xfb,temp1);
@@ -7488,6 +7645,9 @@
 	 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xf8,(temp & 0xff));
       }
       SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8));
+      if(ModeNo > 0x13) {
+         SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3b,0xfd);
+      }
 
       if(HwInfo->jChipType >= SIS_661) { 		/* ? */
          if(SiS_Pr->SiS_TVMode & TVAspect43) {
@@ -7580,6 +7740,8 @@
         if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
 	   if(SiS_IsDualLink(SiS_Pr, HwInfo)) {
 	      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
+	   } else {
+	      SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x27,~0x20);
 	   }
 
 	   if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
@@ -7705,7 +7867,7 @@
      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1E,temp);
 
      temp = 0x0036; tempbx = 0xD0;
-     if((IS_SIS550650740660) && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
+     if((HwInfo->jChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
 	temp = 0x0026; tempbx = 0xC0; /* See En/DisableBridge() */
      }
      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
@@ -7735,6 +7897,8 @@
 	if(HwInfo->jChipType >= SIS_315H) {
 	   if(SiS_IsDualLink(SiS_Pr, HwInfo)) {
 	      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
+	   } else {
+	      SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x27,~0x20);
 	   }
 	}
 	if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
@@ -8376,7 +8540,7 @@
   SiS_SetCH701x(SiS_Pr,(temp1 << 8) | 0x49);
 }
 
-void
+static void
 SiS_Chrontel701xOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
   USHORT temp;
@@ -8421,7 +8585,7 @@
   }
 }
 
-void
+static void
 SiS_Chrontel701xOff(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
   USHORT temp;
@@ -8494,7 +8658,7 @@
      }
 }
 
-void
+static void
 SiS_ChrontelInitTVVSync(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
      USHORT temp;
@@ -8620,7 +8784,7 @@
     SiS_SetCH701x(SiS_Pr,0x0077);  /* MV? */
 }
 
-void
+static void
 SiS_ChrontelDoSomething1(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
      USHORT temp;
@@ -8823,16 +8987,9 @@
 	       (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
 	       SetOEMLCDData2(SiS_Pr, HwInfo, ModeNo, ModeIdIndex,RefreshRateTableIndex);
 	    }
-            if(HwInfo->jChipType == SIS_730) {
-               SiS_DisplayOn(SiS_Pr);
-	    }
+	    SiS_DisplayOn(SiS_Pr);
          }
       }
-      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-          if(HwInfo->jChipType != SIS_730) {
-             SiS_DisplayOn(SiS_Pr);
-	  }
-      }
    }
 #endif
 
@@ -8841,7 +8998,7 @@
       if(SiS_Pr->SiS_SetFlag & LowModeTests) {
 	 if(HwInfo->jChipType < SIS_661) {
 	    SiS_FinalizeLCD(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
-            SiS_OEM310Setting(SiS_Pr, HwInfo, ModeNo, ModeIdIndex);
+            SiS_OEM310Setting(SiS_Pr, HwInfo, ModeNo, ModeIdIndex, RefreshRateTableIndex);
 	 } else {
 	    SiS_OEM661Setting(SiS_Pr, HwInfo, ModeNo, ModeIdIndex, RefreshRateTableIndex);
 	 }
@@ -9008,9 +9165,10 @@
   return FALSE;
 }
 
+#if 0
 #ifdef SIS300
 /* Write Trumpion register */
-void
+static void
 SiS_SetTrumpReg(SiS_Private *SiS_Pr, USHORT tempbx)
 {
   SiS_Pr->SiS_DDC_DeviceAddr = 0xF0;  		/* DAB (Device Address Byte) */
@@ -9021,6 +9179,7 @@
   SiS_SetChReg(SiS_Pr, tempbx, 0);
 }
 #endif
+#endif
 
 /* Write to Chrontel 700x */
 /* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
@@ -9098,9 +9257,10 @@
   return 0xFFFF;
 }
 
+#if 0
 #ifdef SIS300
 /* Read from Trumpion */
-USHORT
+static USHORT
 SiS_GetTrumpReg(SiS_Private *SiS_Pr, USHORT tempbx)
 {
   SiS_Pr->SiS_DDC_DeviceAddr = 0xF0;	/* DAB */
@@ -9112,6 +9272,7 @@
   return(SiS_GetChReg(SiS_Pr,0));
 }
 #endif
+#endif
 
 /* Read from Chrontel 700x */
 /* Parameter is [Register no (S7-S0)] */
@@ -9172,7 +9333,7 @@
 }
 
 /* Our own DDC functions */
-USHORT
+static USHORT
 SiS_InitDDCRegs(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
                 USHORT adaptnum, USHORT DDCdatatype, BOOLEAN checkcr32)
 {
@@ -9286,7 +9447,7 @@
     return 0;
 }
 
-USHORT
+static USHORT
 SiS_WriteDABDDC(SiS_Private *SiS_Pr)
 {
    if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
@@ -9299,7 +9460,7 @@
    return(0);
 }
 
-USHORT
+static USHORT
 SiS_PrepareReadDDC(SiS_Private *SiS_Pr)
 {
    if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
@@ -9309,7 +9470,7 @@
    return(0);
 }
 
-USHORT
+static USHORT
 SiS_PrepareDDC(SiS_Private *SiS_Pr)
 {
    if(SiS_WriteDABDDC(SiS_Pr)) SiS_WriteDABDDC(SiS_Pr);
@@ -9317,7 +9478,7 @@
    return(0);
 }
 
-void
+static void
 SiS_SendACK(SiS_Private *SiS_Pr, USHORT yesno)
 {
    SiS_SetSCLKLow(SiS_Pr);
@@ -9335,7 +9496,7 @@
    SiS_SetSCLKHigh(SiS_Pr);
 }
 
-USHORT
+static USHORT
 SiS_DoProbeDDC(SiS_Private *SiS_Pr)
 {
     unsigned char mask, value;
@@ -9385,7 +9546,7 @@
     return(ret);
 }
 
-USHORT
+static USHORT
 SiS_ProbeDDC(SiS_Private *SiS_Pr)
 {
    USHORT flag;
@@ -9401,7 +9562,7 @@
    return(flag);
 }
 
-USHORT
+static USHORT
 SiS_ReadDDC(SiS_Private *SiS_Pr, USHORT DDCdatatype, unsigned char *buffer)
 {
    USHORT flag, length, i;
@@ -9444,8 +9605,9 @@
    regards chipset and video bridge type.
 
    Arguments:
-       adaptnum: 0=CRT1, 1=LCD, 2=VGA2
-                 CRT2 DDC is only supported on SiS301, 301B, 302B.
+       adaptnum: 0=CRT1(analog), 1=CRT2/LCD(digital), 2=CRT2/VGA2(analog)
+                 CRT2 DDC is only supported on SiS301, 301B, 301C, 302B.
+		 LCDA is CRT1, but DDC is read from CRT2 port.
        DDCdatatype: 0=Probe, 1=EDID, 2=EDID+VDIF, 3=EDID V2 (P&D), 4=EDID V2 (FPDI-2)
        buffer: ptr to 256 data bytes which will be filled with read data.
 
@@ -9487,6 +9649,19 @@
       result = SiS_ProbeDDC(SiS_Pr);
    } else {
       result = SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer);
+      if((!result) && (DDCdatatype == 1)) {
+         if((buffer[0] == 0x00) && (buffer[1] == 0xff) &&
+	    (buffer[2] == 0xff) && (buffer[3] == 0xff) &&
+	    (buffer[4] == 0xff) && (buffer[5] == 0xff) &&
+	    (buffer[6] == 0xff) && (buffer[7] == 0x00) &&
+	    (buffer[0x12] == 1)) {
+	    if(adaptnum == 1) {
+	       if(!(buffer[0x14] & 0x80)) result = 0xFFFE;
+	    } else {
+	       if(buffer[0x14] & 0x80)    result = 0xFFFE;
+	    }
+	 }
+      }
    }
    SiS_SetReg(SiS_Pr->SiS_P3c4,0x1f,sr1f);
    if(VGAEngine == SIS_300_VGA) {
@@ -9546,9 +9721,12 @@
 SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS)
 {
    USHORT DDCdatatype, paneltype, flag, xres=0, yres=0;
-   USHORT index, myindex, lumsize, numcodes;
+   USHORT index, myindex, lumsize, numcodes, panelvendor, panelproduct;
+   int maxx=0, maxy=0, prefx=0, prefy=0;
    unsigned char cr37=0, seekcode;
    BOOLEAN checkexpand = FALSE;
+   BOOLEAN havesync = FALSE;
+   BOOLEAN indb = FALSE;
    int retry, i;
    unsigned char buffer[256];
 
@@ -9557,6 +9735,8 @@
    SiS_Pr->CP_MaxX = SiS_Pr->CP_MaxY = SiS_Pr->CP_MaxClock = 0;
    SiS_Pr->CP_PreferredX = SiS_Pr->CP_PreferredY = 0;
    SiS_Pr->CP_PreferredIndex = -1;
+   SiS_Pr->CP_PrefClock = 0;
+   SiS_Pr->PanelSelfDetected = FALSE;
 
    if(!(pSiS->VBFlags & (VB_301|VB_301B|VB_301C|VB_302B))) return 0;
    if(pSiS->VBFlags & VB_30xBDH) return 0;
@@ -9612,25 +9792,24 @@
       /* Catch a few clear cases: */
       if(!(checkedid1(buffer))) {
          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
-	 	"CRT2: EDID corrupt\n");
+	 	"LCD sense: EDID corrupt\n");
 	 return 0;
       }
 
       if(!(buffer[0x14] & 0x80)) {
          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
-	        "CRT2: Attached display expects analog input (0x%02x)\n",
+	        "LCD sense: Attached display expects analog input (0x%02x)\n",
 		buffer[0x14]);
       	 return 0;
       }
 
       if((buffer[0x18] & 0x18) != 0x08) {
          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
-	 	"CRT2: Attached display is not of RGB but of %s type (0x%02x)\n",
+	 	"LCD sense: Warning: Attached display is not of RGB but of %s type (0x%02x)\n",
 		((buffer[0x18] & 0x18) == 0x00) ? "monochrome/greyscale" :
 		  ( ((buffer[0x18] & 0x18) == 0x10) ? "non-RGB multicolor" :
 		     "undefined"),
 		buffer[0x18]);
-	 return 0;
       }
 
       /* Now analyze the first Detailed Timing Block and see
@@ -9642,13 +9821,23 @@
       paneltype = Panel_Custom;
       checkexpand = FALSE;
 
+      panelvendor = buffer[9] | (buffer[8] << 8);
+      panelproduct = buffer[10] | (buffer[11] << 8);
+
+      /* Overrule bogus preferred modes from database */
+      if((indb = SiS_FindPanelFromDB(pSiS, panelvendor, panelproduct, &maxx, &maxy, &prefx, &prefy))) {
+         if(prefx) SiS_Pr->CP_PreferredX = xres = prefx;
+	 if(prefy) SiS_Pr->CP_PreferredY = yres = prefy;
+      }
+
       if(buffer[0x18] & 0x02) {
 
-         xres = buffer[0x38] | ((buffer[0x3a] & 0xf0) << 4);
-         yres = buffer[0x3b] | ((buffer[0x3d] & 0xf0) << 4);
+         USHORT pclk = (buffer[0x36] | (buffer[0x37] << 8));
+	 USHORT phb  = (buffer[0x39] | ((buffer[0x3a] & 0x0f) << 8));
+	 USHORT pvb  = (buffer[0x3c] | ((buffer[0x3d] & 0x0f) << 8));
 
-	 SiS_Pr->CP_PreferredX = xres;
-	 SiS_Pr->CP_PreferredY = yres;
+	 if(!xres) SiS_Pr->CP_PreferredX = xres = buffer[0x38] | ((buffer[0x3a] & 0xf0) << 4);
+         if(!yres) SiS_Pr->CP_PreferredY = yres = buffer[0x3b] | ((buffer[0x3d] & 0xf0) << 4);
 
          switch(xres) {
 #if 0	    /* Treat as custom */
@@ -9676,14 +9865,20 @@
 		      paneltype = Panel310_1280x960;
 		   }
 	        } else if(yres == 768) {
-		   if( ((buffer[0x36] | (buffer[0x37] << 8)) == 8100) &&
-		       ((buffer[0x39] | ((buffer[0x3a] & 0x0f) << 8)) == (1688 - 1280)) &&
-		       ((buffer[0x3c] | ((buffer[0x3d] & 0x0f) << 8)) == (802 - 768)) ) {
+		   if( (pclk == 8100) &&
+		       (phb == (1688 - 1280)) &&
+		       (pvb == (802 - 768)) ) {
 	       	      paneltype = Panel_1280x768;
 		      checkexpand = FALSE;
 		      cr37 |= 0x10;
 		   }
-	        }
+	        } else if(yres == 800) {
+		   if( (pclk == 6900) &&
+		       (phb == (1408 - 1280)) &&
+		       (pvb == (816 - 800)) ) {
+	       	      paneltype = Panel_1280x800;
+		   }
+		}
 	        break;
 	    case 1400:
 	        if(pSiS->VGAEngine == SIS_315_VGA) {
@@ -9693,7 +9888,6 @@
 	           }
 	        }
       	        break;
-#if 0	    /* Treat this as custom, as we have no valid timing data yet */
 	    case 1600:
 	        if(pSiS->VGAEngine == SIS_315_VGA) {
 		   if(pSiS->VBFlags & VB_301C) {
@@ -9704,41 +9898,61 @@
 	           }
 	        }
       	        break;
-#endif
          }
 
-	 if(paneltype != Panel_Custom) {
-	    if((buffer[0x47] & 0x18) == 0x18) {
-	       cr37 |= ((((buffer[0x47] & 0x06) ^ 0x06) << 5) | 0x20);
-	    } else {
-	       /* What now? There is no digital separate output timing... */
-	       xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
-	       	   "CRT2: Unable to retrieve Sync polarity information\n");
-	       cr37 |= 0xc0;  /* Default */
-	    }
+	 /* Save sync: This is used if "Pass 1:1" is off; in this case
+	  * we always use the panel's native mode = this "preferred mode"
+	  * we just have been analysing. Hence, we also need its sync.
+	  */
+	 if((buffer[0x47] & 0x18) == 0x18) {
+	    cr37 |= ((((buffer[0x47] & 0x06) ^ 0x06) << 5) | 0x20);
+	    havesync = TRUE;
+	 } else {
+	    /* What now? There is no digital separate output timing... */
+	    xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
+	       	   "LCD sense: Unable to retrieve Sync polarity information\n");
+	    cr37 |= 0xc0;  /* Default */
 	 }
 
       }
 
+      /* Check against our database; eg. Sanyo Z2 projector reports
+       * 1024x768 as preferred mode, although it supports 1280x720
+       * natively in non-HDCP mode. Treat such wrongly reporting
+       * panels as custom and fixup actual maximum resolutions.
+       */
+      if(paneltype != Panel_Custom) {
+         if(indb) {
+	    paneltype = Panel_Custom;
+	    SiS_Pr->CP_MaxX = maxx;
+	    SiS_Pr->CP_MaxY = maxy;
+	    /* Leave preferred unchanged (MUST contain a valid mode!) */
+	 }
+      }
+
       /* If we still don't know what panel this is, we take it
        * as a custom panel and derive the timing data from the
        * detailed timing blocks
        */
       if(paneltype == Panel_Custom) {
 
-         BOOLEAN havesync = FALSE;
 	 int i, temp, base = 0x36;
 	 unsigned long estpack;
-	 unsigned short estx[] = {
+	 const unsigned short estx[] = {
 	 	720, 720, 640, 640, 640, 640, 800, 800,
 		800, 800, 832,1024,1024,1024,1024,1280,
 		1152
 	 };
-	 unsigned short esty[] = {
+	 const unsigned short esty[] = {
 	 	400, 400, 480, 480, 480, 480, 600, 600,
 		600, 600, 624, 768, 768, 768, 768,1024,
 		870
 	 };
+	 const int estclk[] = {
+	            0,     0, 25100,   0, 31500, 31500, 36100, 40000,
+		50100, 49500,     0,   0, 65100, 75200, 78700,135200,
+		0
+	 };
 
 	 paneltype = 0;
 	 SiS_Pr->CP_Supports64048075 = TRUE;
@@ -9751,9 +9965,15 @@
 	     if(estpack & (1 << i)) {
 	        if(estx[16 - i] > SiS_Pr->CP_MaxX) SiS_Pr->CP_MaxX = estx[16 - i];
 		if(esty[16 - i] > SiS_Pr->CP_MaxY) SiS_Pr->CP_MaxY = esty[16 - i];
+		if(estclk[16 - i] > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = estclk[16 - i];
 	     }
 	 }
 
+	 /* By default we drive the LCD at 75Hz in 640x480 mode; if
+  	  * the panel does not provide this mode, use 60hz
+	  */
+	 if(!(buffer[0x23] & 0x04)) SiS_Pr->CP_Supports64048075 = FALSE;
+
 	 /* 2. From Standard Timings */
 	 for(i=0x26; i < 0x36; i+=2) {
 	    if((buffer[i] != 0x01) && (buffer[i+1] != 0x01)) {
@@ -9797,29 +10017,29 @@
 	       SiS_Pr->CP_DataValid[i] = TRUE;
 
 	       /* Sort out invalid timings, interlace and too high clocks */
-	       if((SiS_Pr->CP_HDisplay[i] & 7)						||
-	          (SiS_Pr->CP_HDisplay[i] > SiS_Pr->CP_HSyncStart[i])  			||
-	          (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HSyncEnd[i])   			||
-	          (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HTotal[i])     			||
-	          (SiS_Pr->CP_HSyncStart[i] >= SiS_Pr->CP_HSyncEnd[i]) 			||
-	          (SiS_Pr->CP_HSyncStart[i] > SiS_Pr->CP_HTotal[i])    			||
-	          (SiS_Pr->CP_HSyncEnd[i] > SiS_Pr->CP_HTotal[i])      			||
-	          (SiS_Pr->CP_VDisplay[i] > SiS_Pr->CP_VSyncStart[i])  			||
-	          (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VSyncEnd[i])   			||
-	          (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VTotal[i])     			||
-	          (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VSyncEnd[i])  			||
-	          (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VTotal[i])    			||
-	          (SiS_Pr->CP_VSyncEnd[i] > SiS_Pr->CP_VTotal[i])      			||
+	       if((SiS_Pr->CP_HDisplay[i] & 7)						  ||
+	          (SiS_Pr->CP_HDisplay[i] > SiS_Pr->CP_HSyncStart[i])  			  ||
+	          (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HSyncEnd[i])   			  ||
+	          (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HTotal[i])     			  ||
+	          (SiS_Pr->CP_HSyncStart[i] >= SiS_Pr->CP_HSyncEnd[i]) 			  ||
+	          (SiS_Pr->CP_HSyncStart[i] > SiS_Pr->CP_HTotal[i])    			  ||
+	          (SiS_Pr->CP_HSyncEnd[i] > SiS_Pr->CP_HTotal[i])      			  ||
+	          (SiS_Pr->CP_VDisplay[i] > SiS_Pr->CP_VSyncStart[i])  			  ||
+	          (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VSyncEnd[i])   			  ||
+	          (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VTotal[i])     			  ||
+	          (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VSyncEnd[i])  			  ||
+	          (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VTotal[i])    			  ||
+	          (SiS_Pr->CP_VSyncEnd[i] > SiS_Pr->CP_VTotal[i])      			  ||
 		  (((pSiS->VBFlags & VB_301C) && (SiS_Pr->CP_Clock[i] > 162500)) ||
-	           ((!(pSiS->VBFlags & VB_301C)) && (SiS_Pr->CP_Clock[i] > 108200)))	||
+	           ((!(pSiS->VBFlags & VB_301C)) &&
+		    ((SiS_Pr->CP_Clock[i] > 108200) || (SiS_Pr->CP_VDisplay[i] > 1024) ||
+		     (SiS_Pr->CP_HDisplay[i] > 1600)))) 				  ||
 		  (buffer[base+17] & 0x80)) {
 
 	          SiS_Pr->CP_DataValid[i] = FALSE;
 
 	       } else {
 
-	          paneltype = Panel_Custom;
-
 		  SiS_Pr->CP_HaveCustomData = TRUE;
 
 		  if(xres > SiS_Pr->CP_MaxX) SiS_Pr->CP_MaxX = xres;
@@ -9828,22 +10048,10 @@
 
 		  if((SiS_Pr->CP_PreferredX == xres) && (SiS_Pr->CP_PreferredY == yres)) {
 	             SiS_Pr->CP_PreferredIndex = i;
+		     SiS_MakeClockRegs(pSiS->pScrn, SiS_Pr->CP_Clock[i], &SiS_Pr->CP_PrefSR2B, &SiS_Pr->CP_PrefSR2C);
+		     SiS_Pr->CP_PrefClock = (SiS_Pr->CP_Clock[i] / 1000) + 1;
 	          }
 
-		  SiS_Pr->CP_Vendor = buffer[9] | (buffer[8] << 8);
-		  SiS_Pr->CP_Product = buffer[10] | (buffer[11] << 8);
-
-		  /* By default we drive the LCD at 75Hz in 640x480 mode; if
-		   * the panel does not provide this mode, use 60hz
-		   */
-		  if(!(buffer[0x23] & 0x04)) SiS_Pr->CP_Supports64048075 = FALSE;
-
-	          /* We must assume the panel can scale, since we have
-	           * no scaling data
-		   */
-	          checkexpand = FALSE;
-	          cr37 |= 0x10;
-
 	          /* Extract the sync polarisation information. This only works
 	           * if the Flags indicate a digital separate output.
 	           */
@@ -9851,20 +10059,37 @@
 		     SiS_Pr->CP_HSync_P[i] = (buffer[base+17] & 0x02) ? TRUE : FALSE;
 		     SiS_Pr->CP_VSync_P[i] = (buffer[base+17] & 0x04) ? TRUE : FALSE;
 		     SiS_Pr->CP_SyncValid[i] = TRUE;
-		     if(!havesync) {
+		     if((i == SiS_Pr->CP_PreferredIndex) && (!havesync)) {
 	                cr37 |= ((((buffer[base+17] & 0x06) ^ 0x06) << 5) | 0x20);
 			havesync = TRUE;
 	   	     }
 	          } else {
 		     SiS_Pr->CP_SyncValid[i] = FALSE;
 		  }
+
 	       }
-            }
+
+            } else if((!buffer[base]) && (!buffer[base+1]) && (!buffer[base+2]) && (!buffer[base+4])) {
+
+	       /* Maximum pixclock from Monitor Range Limits */
+	       if((buffer[base+3] == 0xfd) && (buffer[base+9] != 0xff)) {
+	          int maxclk = buffer[base+9] * 10;
+		  /* More than 170 is not supported anyway */
+		  if(maxclk <= 170) SiS_Pr->CP_MaxClock = maxclk * 1000;
+	       }
+
+	    }
+
 	 }
-	 if(!havesync) {
-	    xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
-	       	   "CRT2: Unable to retrieve Sync polarity information\n");
-   	 }
+
+	 if(SiS_Pr->CP_MaxX && SiS_Pr->CP_MaxY) {
+	    paneltype = Panel_Custom;
+	    checkexpand = FALSE;
+	    cr37 |= 0x10;
+	    SiS_Pr->CP_Vendor = panelvendor;
+	    SiS_Pr->CP_Product = panelproduct;
+	 }
+
       }
 
       if(paneltype && checkexpand) {
@@ -9887,28 +10112,32 @@
 
       if(!(checkedid2(buffer))) {
          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
-	 	"CRT2: EDID corrupt\n");
+	 	"LCD sense: EDID corrupt\n");
 	 return 0;
       }
 
       if((buffer[0x41] & 0x0f) == 0x03) {
          index = 0x42 + 3;
          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
-	 	"CRT2: Display supports TMDS input on primary interface\n");
+	 	"LCD sense: Display supports TMDS input on primary interface\n");
       } else if((buffer[0x41] & 0xf0) == 0x30) {
          index = 0x46 + 3;
          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
-	 	"CRT2: Display supports TMDS input on secondary interface\n");
+	 	"LCD sense: Display supports TMDS input on secondary interface\n");
       } else {
          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
-	 	"CRT2: Display does not support TMDS video interface (0x%02x)\n", 
+	 	"LCD sense: Display does not support TMDS video interface (0x%02x)\n",
 		buffer[0x41]);
 	 return 0;
       }
 
+      SiS_Pr->CP_Vendor = panelvendor = buffer[2] | (buffer[1] << 8);
+      SiS_Pr->CP_Product = panelproduct = buffer[3] | (buffer[4] << 8);
+
       paneltype = Panel_Custom;
-      SiS_Pr->CP_MaxX = xres = buffer[0x76] | (buffer[0x77] << 8);
-      SiS_Pr->CP_MaxY = yres = buffer[0x78] | (buffer[0x79] << 8);
+      SiS_Pr->CP_MaxX = SiS_Pr->CP_PreferredX = xres = buffer[0x76] | (buffer[0x77] << 8);
+      SiS_Pr->CP_MaxY = SiS_Pr->CP_PreferredY = yres = buffer[0x78] | (buffer[0x79] << 8);
+
       switch(xres) {
 #if 0
          case 800:
@@ -9945,7 +10174,6 @@
 	        }
 	     }
       	     break;
-#if 0    /* Treat this one as custom since we have no timing data yet */
 	 case 1600:
 	     if(pSiS->VGAEngine == SIS_315_VGA) {
 	        if(pSiS->VBFlags & VB_301C) {
@@ -9956,7 +10184,6 @@
 	        }
 	     }
       	     break;
-#endif
       }
 
       /* Determine if RGB18 or RGB24 */
@@ -9979,7 +10206,25 @@
 	 lumsize++;  /* luminance header byte */
 	 index += lumsize;
       }
+#if 0 /* "pixel rate" = pixel clock? */
+      if(buffer[0x7e] & 0x1c) {
+         for(i=0; i<((buffer[0x7e] & 0x1c) >> 2); i++) {
+	    if(buffer[index + (i*8) + 6] && (buffer[index + (i*8) + 7] & 0x0f)) {
+	       int clk = (buffer[index + (i*8) + 6] | ((buffer[index + (i*8) + 7] & 0x0f) << 4)) * 1000;
+	       if(clk > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = clk;
+	    }
+	 }
+      }
+#endif
       index += (((buffer[0x7e] & 0x1c) >> 2) * 8);   /* skip Frequency Ranges */
+      if(buffer[0x7e] & 0x03) {
+         for(i=0; i<(buffer[0x7e] & 0x03); i++) {
+	    if((buffer[index + (i*27) + 9]) || (buffer[index + (i*27) + 10])) {
+	       int clk = ((buffer[index + (i*27) + 9]) | ((buffer[index + (i*27) + 9]) << 8)) * 10;
+	       if(clk > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = clk;
+	    }
+	 }
+      }
       index += ((buffer[0x7e] & 0x03) * 27);         /* skip Detailed Range Limits */
       numcodes = (buffer[0x7f] & 0xf8) >> 3;
       if(numcodes) {
@@ -9991,13 +10236,29 @@
 	 }
 	 if(buffer[myindex] == seekcode) {
 	    cr37 |= ((((buffer[myindex + 1] & 0x0c) ^ 0x0c) << 4) | 0x20);
+	    havesync = TRUE;
 	 } else {
 	    xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
-	        "CRT2: Unable to retrieve Sync polarity information\n");
+	        "LCD sense: Unable to retrieve Sync polarity information\n");
 	 }
       } else {
          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
-	     "CRT2: Unable to retrieve Sync polarity information\n");
+	     "LCD sense: Unable to retrieve Sync polarity information\n");
+      }
+
+      /* Check against our database; Eg. Sanyo projector reports
+       * 1024x768 in non-HDPC mode, although it supports 1280x720.
+       * Treat such wrongly reporting panels as custom.
+       */
+      if(paneltype != Panel_Custom) {
+         int maxx, maxy, prefx, prefy;
+         if((SiS_FindPanelFromDB(pSiS, panelvendor, panelproduct, &maxx, &maxy, &prefx, &prefy))) {
+	    paneltype = Panel_Custom;
+	    SiS_Pr->CP_MaxX = maxx;
+	    SiS_Pr->CP_MaxY = maxy;
+	    cr37 |= 0x10;
+	    /* Leave preferred unchanged (MUST be a valid mode!) */
+	 }
       }
 
       /* Now seek the detailed timing descriptions for custom panels */
@@ -10043,7 +10304,8 @@
 	       (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VTotal[i])    			||
 	       (SiS_Pr->CP_VSyncEnd[i] > SiS_Pr->CP_VTotal[i])      			||
 	       (((pSiS->VBFlags & VB_301C) && (SiS_Pr->CP_Clock[i] > 162500)) ||
-	        ((!(pSiS->VBFlags & VB_301C)) && (SiS_Pr->CP_Clock[i] > 108200)))	||
+	        ((!(pSiS->VBFlags & VB_301C)) &&
+		 ((SiS_Pr->CP_Clock[i] > 108200) || (SiS_Pr->CP_VDisplay[i] > 1024))))	||
 	       (buffer[index + 17] & 0x80)) {
 
 	       SiS_Pr->CP_DataValid[i] = FALSE;
@@ -10054,25 +10316,25 @@
 
 	       if(SiS_Pr->CP_Clock[i] > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = SiS_Pr->CP_Clock[i];
 
-	       if((SiS_Pr->CP_MaxX == xres) && (SiS_Pr->CP_MaxY == yres)) {
+	       if((SiS_Pr->CP_PreferredX == xres) && (SiS_Pr->CP_PreferredY == yres)) {
 	          SiS_Pr->CP_PreferredIndex = i;
+		  SiS_MakeClockRegs(pSiS->pScrn, SiS_Pr->CP_Clock[i], &SiS_Pr->CP_PrefSR2B, &SiS_Pr->CP_PrefSR2C);
+		  SiS_Pr->CP_PrefClock = (SiS_Pr->CP_Clock[i] / 1000) + 1;
+		  if(!havesync) {
+	             cr37 |= ((((buffer[index + 17] & 0x06) ^ 0x06) << 5) | 0x20);
+		     havesync = TRUE;
+	   	  }
 	       }
 
 	       SiS_Pr->CP_HSync_P[i] = (buffer[index + 17] & 0x02) ? TRUE : FALSE;
 	       SiS_Pr->CP_VSync_P[i] = (buffer[index + 17] & 0x04) ? TRUE : FALSE;
 	       SiS_Pr->CP_SyncValid[i] = TRUE;
 
-	       SiS_Pr->CP_Vendor = buffer[2] | (buffer[1] << 8);
-	       SiS_Pr->CP_Product = buffer[3] | (buffer[4] << 8);
-
-	       /* We must assume the panel can scale, since we have
-	        * no scaling data
-    	        */
-	       cr37 |= 0x10;
-
 	    }
 	 }
 
+	 cr37 |= 0x10;
+
       }
 
       break;
@@ -10091,7 +10353,7 @@
    for(i = 0; i < 7; i++) {
       if(SiS_Pr->CP_DataValid[i]) {
          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
-            "Non-standard LCD timing data no. %d:\n", i);
+            "Non-standard LCD/DVI-D timing data no. %d:\n", i);
          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
 	    "   HDisplay %d HSync %d HSyncEnd %d HTotal %d\n",
 	    SiS_Pr->CP_HDisplay[i], SiS_Pr->CP_HSyncStart[i],
@@ -10119,7 +10381,7 @@
        SiS_Pr->PanelSelfDetected = TRUE;
 #ifdef TWDEBUG
        xf86DrvMsgVerb(pSiS->pScrn->scrnIndex, X_PROBED, 3, 
-       	   "CRT2: [DDC LCD results: 0x%02x, 0x%02x]\n", paneltype, cr37);
+       	   "LCD sense: [DDC LCD results: 0x%02x, 0x%02x]\n", paneltype, cr37);
 #endif	
    } else {
        SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x32,~0x08);
@@ -10155,7 +10417,7 @@
       DDCdatatype = 1;
    } else {
    	xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
-		"Do DDC answer\n");
+		"VGA2 sense: Do DDC answer\n");
    	return 0;				/* no DDC support (or no device attached) */
    }
 
@@ -10164,7 +10426,7 @@
    do {
       if(SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer)) {
          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
-	 	"CRT2: DDC read failed (attempt %d), %s\n",
+	 	"VGA2 sense: DDC read failed (attempt %d), %s\n",
 		(3-retry), (retry == 1) ? "giving up" : "retrying");
 	 retry--;
 	 if(retry == 0) return 0xFFFF;
@@ -10177,13 +10439,13 @@
    switch(DDCdatatype) {
    case 1:
       if(!(checkedid1(buffer))) {
-          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
-	  	"CRT2: EDID corrupt\n");
+          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_ERROR,
+	  	"VGA2 sense: EDID corrupt\n");
       	  return 0;
       }
       if(buffer[0x14] & 0x80) {			/* Display uses digital input */
-          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
-	  	"CRT2: Attached display expects digital input\n");
+          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_ERROR,
+	  	"VGA2 sense: Attached display expects digital input\n");
       	  return 0;
       }
       SiS_Pr->CP_Vendor = buffer[9] | (buffer[8] << 8);
@@ -10193,16 +10455,16 @@
    case 3:
    case 4:
       if(!(checkedid2(buffer))) {
-          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
-	  	"CRT2: EDID corrupt\n");
+          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_ERROR,
+	  	"VGA2 sense: EDID corrupt\n");
       	  return 0;
       }
       if( ((buffer[0x41] & 0x0f) != 0x01) &&  	/* Display does not support analog input */
           ((buffer[0x41] & 0x0f) != 0x02) &&
 	  ((buffer[0x41] & 0xf0) != 0x10) &&
 	  ((buffer[0x41] & 0xf0) != 0x20) ) {
-	  xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
-	     	"CRT2: Attached display does not support analog input (0x%02x)\n",
+	  xf86DrvMsg(pSiS->pScrn->scrnIndex, X_ERROR,
+	     	"VGA2 sense: Attached display does not support analog input (0x%02x)\n",
 		buffer[0x41]);
 	  return 0;
       }
@@ -10232,7 +10494,7 @@
 
 /* Generic I2C functions for Chrontel & DDC --------- */
 
-void
+static void
 SiS_SetSwitchDDC2(SiS_Private *SiS_Pr)
 {
   SiS_SetSCLKHigh(SiS_Pr);
@@ -10251,7 +10513,7 @@
 
 /* Set I2C start condition */
 /* This is done by a SD high-to-low transition while SC is high */
-USHORT
+static USHORT
 SiS_SetStart(SiS_Private *SiS_Pr)
 {
   if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF;			           /* (SC->low)  */
@@ -10270,7 +10532,7 @@
 
 /* Set I2C stop condition */
 /* This is done by a SD low-to-high transition while SC is high */
-USHORT
+static USHORT
 SiS_SetStop(SiS_Private *SiS_Pr)
 {
   if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF;			           /* (SC->low) */
@@ -10288,7 +10550,7 @@
 }
 
 /* Write 8 bits of data */
-USHORT
+static USHORT
 SiS_WriteDDC2Data(SiS_Private *SiS_Pr, USHORT tempax)
 {
   USHORT i,flag,temp;
@@ -10314,7 +10576,7 @@
   return(temp);
 }
 
-USHORT
+static USHORT
 SiS_ReadDDC2Data(SiS_Private *SiS_Pr, USHORT tempax)
 {
   USHORT i,temp,getdata;
@@ -10334,7 +10596,7 @@
   return(getdata);
 }
 
-USHORT
+static USHORT
 SiS_SetSCLKLow(SiS_Private *SiS_Pr)
 {
   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
@@ -10345,7 +10607,7 @@
   return 0;
 }
 
-USHORT
+static USHORT
 SiS_SetSCLKHigh(SiS_Private *SiS_Pr)
 {
   USHORT temp, watchdog=1000;
@@ -10369,7 +10631,7 @@
 
 /* Check I2C acknowledge */
 /* Returns 0 if ack ok, non-0 if ack not ok */
-USHORT
+static USHORT
 SiS_CheckACK(SiS_Private *SiS_Pr)
 {
   USHORT tempah;
@@ -11075,35 +11337,18 @@
   }
 }
 
-void
-SiS_OEM310Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
-                  USHORT ModeNo,USHORT ModeIdIndex)
-{
-   SetDelayComp(SiS_Pr,HwInfo,ModeNo);
-
-   if(SiS_Pr->UseCustomMode) return;
-
-   if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
-      SetAntiFlicker(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
-      SetPhaseIncr(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
-      SetYFilter(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
-      if(SiS_Pr->SiS_VBType & VB_SIS301) {
-         SetEdgeEnhance(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
-      }
-   }
-}
-
 static void
 SetDelayComp661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo,
                 USHORT ModeIdIndex, USHORT RTI)
 {
-   USHORT delay = 0, romptr = 0, index;
+   USHORT delay = 0, romptr = 0, index, lcdpdcindex;
    UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
 
    if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToLCD | SetCRT2ToLCDA | SetCRT2ToRAMDAC)))
       return;
 
    /* 1. New ROM: VGA2 and LCD/LCDA-Pass1:1 */
+   /* (If a custom mode is used, Pass1:1 is always set; hence we do this:) */
 
    if(SiS_Pr->SiS_ROMNew) {
       if((SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) 			||
@@ -11121,7 +11366,7 @@
          if((ROMAddr[0x5b] & 0x80) || (SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD))) {
 	    index++;
 	 }
-	 romptr = SISGETROMW(0x104);  /* 0x4ae */
+	 romptr = SISGETROMW(0x104);
          delay = ROMAddr[romptr + index];
          if(SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD)) {
             SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));
@@ -11147,10 +11392,12 @@
 
       index = GetOEMTVPtr661(SiS_Pr);
       if(SiS_Pr->SiS_ROMNew) {
-         romptr = SISGETROMW(0x106);  /* 0x4ba */
+         romptr = SISGETROMW(0x106);
+	 if(SiS_Pr->SiS_VBType & VB_UMC) romptr += 12;
          delay = ROMAddr[romptr + index];
       } else {
          delay = 0x04;
+	 if(index > 3) delay = 0;
       }
 
    } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
@@ -11160,22 +11407,41 @@
       if( (SiS_Pr->SiS_LCDResInfo != Panel_Custom) &&
           ((romptr = GetLCDStructPtr661_2(SiS_Pr, HwInfo))) ) {
 
-	 /* For LV, the BIOS must know about the correct value */
-	 delay = ROMAddr[romptr + 0x0d];		/* LCD  */
-	 delay |= (ROMAddr[romptr + 0x0c] << 8);	/* LCDA */
+	 lcdpdcindex = (SiS_Pr->SiS_VBType & VB_UMC) ? 14 : 12;
+
+	 /* For LVDS (and sometimes TMDS), the BIOS must know about the correct value */
+	 delay = ROMAddr[romptr + lcdpdcindex + 1];	/* LCD  */
+	 delay |= (ROMAddr[romptr + lcdpdcindex] << 8);	/* LCDA */
 
       } else {
 
-         /* TMDS: Set our own, since BIOS has no idea - TODO: Find out about values */
+         /* TMDS: Set our own, since BIOS has no idea */
+	 /* (This is done on >=661 only, since <661 is calling this only for LVDS) */
          if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
-            if((SiS_Pr->PanelXRes <= 1024) && (SiS_Pr->PanelYRes <= 768)) {
-	       delay = 0x0404;
-            } else if((SiS_Pr->PanelXRes <= 1280) && (SiS_Pr->PanelYRes <= 1024)) {
-	       delay = 0x0404;
-            } else if((SiS_Pr->PanelXRes <= 1400) && (SiS_Pr->PanelYRes <= 1050)) {
-	       delay = 0x1004;
-            } else
-	       delay = 0x0000;
+	    switch(SiS_Pr->SiS_LCDResInfo) {
+	    case Panel_1024x768:  delay = 0x0008; break;
+	    case Panel_1280x720:  delay = 0x0004; break;
+	    case Panel_1280x768:
+	    case Panel_1280x768_2:delay = 0x0004; break;
+	    case Panel_1280x800:
+	    case Panel_1280x800_2:delay = 0x0004; break; /* Verified for 1280x800 */
+	    case Panel_1280x1024: delay = 0x1e04; break;
+	    case Panel_1400x1050: delay = 0x0004; break;
+	    case Panel_1600x1200: delay = 0x0400; break;
+	    case Panel_1680x1050: delay = 0x0e04; break;
+	    default:
+               if((SiS_Pr->PanelXRes <= 1024) && (SiS_Pr->PanelYRes <= 768)) {
+	          delay = 0x0008;
+	       } else if((SiS_Pr->PanelXRes == 1280) && (SiS_Pr->PanelYRes == 1024)) {
+	          delay = 0x1e04;
+               } else if((SiS_Pr->PanelXRes <= 1400) && (SiS_Pr->PanelYRes <= 1050)) {
+	          delay = 0x0004;
+	       } else if((SiS_Pr->PanelXRes <= 1600) && (SiS_Pr->PanelYRes <= 1200)) {
+	          delay = 0x0400;
+               } else
+	          delay = 0x0e04;
+	       break;
+	    }
          }
 
 	 /* Override by detected or user-set values */
@@ -11216,31 +11482,30 @@
       } else {
          infoflag = SiS_Pr->SiS_RefIndex[RTI].Ext_InfoFlag;
       }
-      infoflag &= 0xc0;
 
-      temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
-      if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
-         temp &= 0x3f;
-	 temp |= infoflag;
-      } else {
-         if(temp & 0x20) infoflag = temp;
+      if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
+         infoflag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37); /* No longer check D5 */
       }
-      if(temp & 0x01) infoflag |= 0x01;
+
+      infoflag &= 0xc0;
 
       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-         temp = 0x0c;
-         if(infoflag & 0x01) temp ^= 0x14;  /* BIOS: 18, wrong */
-         temp |= (infoflag >> 6);
+         temp = (infoflag >> 6) | 0x0c;
+         if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
+	    temp ^= 0x04;
+	    if(SiS_Pr->SiS_ModeType >= Mode24Bpp) temp |= 0x10;
+	 }
          SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xe0,temp);
       } else {
-         temp = 0;
-         if(infoflag & 0x01) temp |= 0x80;
-         SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1a,0x7f,temp);
          temp = 0x30;
-         if(infoflag & 0x01) temp = 0x20;
-         infoflag &= 0xc0;
+         if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) temp = 0x20;
          temp |= infoflag;
          SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0f,temp);
+         temp = 0;
+         if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
+	    if(SiS_Pr->SiS_ModeType >= Mode24Bpp) temp |= 0x80;
+	 }
+         SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1a,0x7f,temp);
       }
 
    }
@@ -11279,7 +11544,31 @@
    }
 }
 
-void
+static void
+SiS_OEM310Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
+                  USHORT ModeNo,USHORT ModeIdIndex,USHORT RRTI)
+{
+   if((SiS_Pr->SiS_ROMNew) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
+      SetDelayComp661(SiS_Pr,HwInfo,ModeNo,ModeIdIndex,RRTI);
+      if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+         SetCRT2SyncDither661(SiS_Pr,HwInfo,ModeNo,RRTI);
+         SetPanelParms661(SiS_Pr,HwInfo);
+      }
+   } else {
+      SetDelayComp(SiS_Pr,HwInfo,ModeNo);
+   }
+
+   if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
+      SetAntiFlicker(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
+      SetPhaseIncr(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
+      SetYFilter(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
+      if(SiS_Pr->SiS_VBType & VB_SIS301) {
+         SetEdgeEnhance(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
+      }
+   }
+}
+
+static void
 SiS_OEM661Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
                   USHORT ModeNo,USHORT ModeIdIndex, USHORT RRTI)
 {
@@ -11310,7 +11599,7 @@
  * function looks quite different in every BIOS, so you better
  * pray that we have a backup...
  */
-void
+static void
 SiS_FinalizeLCD(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
                 PSIS_HW_INFO HwInfo)
 {
@@ -11318,6 +11607,7 @@
   USHORT resinfo,modeflag;
 
   if(!(SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) return;
+  if(SiS_Pr->SiS_ROMNew) return;
 
   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
      if(SiS_Pr->LVDSHL != -1) {
@@ -11514,7 +11804,7 @@
 
 #ifdef SIS300
 
-void
+static void
 SetOEMLCDData2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
                USHORT ModeNo,USHORT ModeIdIndex, USHORT RefTabIndex)
 {
@@ -11574,7 +11864,9 @@
 
   if(HwInfo->jChipType == SIS_300) {
 
-    tempbx = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0x0f) - 2;
+    tempbx = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0x0f;
+    if(SiS_Pr->SiS_VBType & VB_SIS301) tempbx &= 0x07;
+    tempbx -= 2;
     if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 4;
     if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
        if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 3;
@@ -11612,7 +11904,9 @@
     tempbx = SiS_Pr->SiS_LCDTypeInfo << 2;
     if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
+
   }
+
   return tempbx;
 }
 
@@ -11914,7 +12208,7 @@
    return ModeIdIndex;
 }
 
-void
+static void
 SiS_OEM300Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
 		  USHORT ModeNo, USHORT ModeIdIndex, USHORT RefTableIndex)
 {
diff -Nru a/drivers/video/sis/init301.h b/drivers/video/sis/init301.h
--- a/drivers/video/sis/init301.h	2005-03-01 23:38:57 -08:00
+++ b/drivers/video/sis/init301.h	2005-03-01 23:38:57 -08:00
@@ -35,7 +35,7 @@
  * * 3) The name of the author may not be used to endorse or promote products
  * *    derived from this software without specific prior written permission.
  * *
- * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR
+ * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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,
@@ -54,20 +54,16 @@
 #define  _INIT301_
 
 #include "osdef.h"
-
 #include "initdef.h"
-#include "vgatypes.h"
-#include "vstruct.h"
 
 #ifdef LINUX_XF86
-#include "xf86.h"
-#include "xf86Pci.h"
-#include "xf86PciInfo.h"
 #include "sis.h"
 #include "sis_regs.h"
 #endif
 
 #ifdef LINUX_KERNEL
+#include "vgatypes.h"
+#include "vstruct.h"
 #ifdef SIS_CP
 #undef SIS_CP
 #endif
@@ -82,7 +78,7 @@
 #endif
 #endif
 
-const UCHAR SiS_YPbPrTable[3][64] = {
+static const UCHAR SiS_YPbPrTable[3][64] = {
   {
     0x17,0x1d,0x03,0x09,0x05,0x06,0x0c,0x0c,
     0x94,0x49,0x01,0x0a,0x06,0x0d,0x04,0x0a,
@@ -127,7 +123,7 @@
   }
 };
 
-const UCHAR SiS_HiTVGroup3_1[] = {
+static const UCHAR SiS_HiTVGroup3_1[] = {
     0x00, 0x14, 0x15, 0x25, 0x55, 0x15, 0x0b, 0x13,
     0xb1, 0x41, 0x62, 0x62, 0xff, 0xf4, 0x45, 0xa6,
     0x25, 0x2f, 0x67, 0xf6, 0xbf, 0xff, 0x8e, 0x20,
@@ -138,7 +134,7 @@
     0x1a, 0x1f, 0x25, 0x2a, 0x4c, 0xaa, 0x01
 };
 
-const UCHAR SiS_HiTVGroup3_2[] = {
+static const UCHAR SiS_HiTVGroup3_2[] = {
     0x00, 0x14, 0x15, 0x25, 0x55, 0x15, 0x0b, 0x7a,
     0x54, 0x41, 0xe7, 0xe7, 0xff, 0xf4, 0x45, 0xa6,
     0x25, 0x2f, 0x67, 0xf6, 0xbf, 0xff, 0x8e, 0x20,
@@ -149,7 +145,7 @@
     0x18, 0x1d, 0x23, 0x28, 0x4c, 0xaa, 0x01
 };
 
-/* 301C / 302ELV extended Part2 TV registers */
+/* 301C / 302ELV extended Part2 TV registers (4 tap scaler) */
 
 static const UCHAR SiS_Part2CLVX_1[] = {
     0x00,0x00,
@@ -224,13 +220,13 @@
 };
 
 #ifdef SIS315H
-/* 661 et al LCD data structure (0.94.0) */
+/* 661 et al LCD data structure (2.03.00) */
 static const UCHAR SiS_LCDStruct661[] = {
     /* 1024x768 */
 /*  type|CR37|   HDE   |   VDE   |    HT   |    VT   |   hss    | hse   */
     0x02,0xC0,0x00,0x04,0x00,0x03,0x40,0x05,0x26,0x03,0x10,0x00,0x88,
     0x00,0x02,0x00,0x06,0x00,0x41,0x5A,0x64,0x00,0x00,0x00,0x00,0x04,
-    /*  | vss      |   vse  |clck|  clock  |CRT2DataP|CRT2DataP|idx     */
+    /*  | vss     |    vse  |clck|  clock  |CRT2DataP|CRT2DataP|idx     */
     /*					      VESA    non-VESA  noscale */
     /* 1280x1024 */
     0x03,0xC0,0x00,0x05,0x00,0x04,0x98,0x06,0x2A,0x04,0x30,0x00,0x70,
@@ -239,23 +235,20 @@
     0x09,0x20,0x78,0x05,0x1A,0x04,0x98,0x06,0x2A,0x04,0x18,0x00,0x38,
     0x00,0x01,0x00,0x03,0x00,0x6C,0xF8,0x2F,0x00,0x00,0x00,0x00,0x09,
     /* 1600x1200 */
-    0x0B,0xC0,0x40,0x06,0xB0,0x04,0x70,0x08,0xE2,0x04,0x40,0x00,0xC0,
-    0x00,0x01,0x00,0x03,0x00,0xA2,0x70,0x24,0x00,0x00,0x00,0x00,0x0B,
-    /* 1280x768 */
-    0x0A,0xC0,0x00,0x05,0x00,0x03,0x80,0x05,0x26,0x03,0x10,0x00,0x40,
-    0x00,0x03,0x00,0x06,0x00,0x44,0x63,0x46,0x00,0x00,0x00,0x00,0x06,
+    0x0B,0xE0,0x40,0x06,0xB0,0x04,0x70,0x08,0xE2,0x04,0x40,0x00,0xC0,
+    0x00,0x01,0x00,0x03,0x00,0xA2,0x70,0x24,0x00,0x00,0x00,0x00,0x0A,
+    /* 1280x768 (_2) */
+    0x0A,0xE0,0x00,0x05,0x00,0x03,0x7C,0x06,0x26,0x03,0x30,0x00,0x70,
+    0x00,0x03,0x00,0x06,0x00,0x4D,0xC8,0x48,0x00,0x00,0x00,0x00,0x06,
     /* 1280x720 */
-    0x0E,0xE0,0x00,0x05,0xD0,0x02,0x80,0x05,0x26,0x03,0x10,0x00,0x02,
+    0x0E,0xE0,0x00,0x05,0xD0,0x02,0x80,0x05,0x26,0x03,0x10,0x00,0x20,
     0x00,0x01,0x00,0x06,0x00,0x45,0x9C,0x62,0x00,0x00,0x00,0x00,0x05,
-    /* 1280x800 */
-    0x0C,0xE0,0x00,0x05,0x20,0x03,0x80,0x05,0x30,0x03,0x10,0x00,0x40,
-    0x00,0x04,0x00,0x03,0x00,0x45,0x9C,0x62,0x00,0x00,0x00,0x00,0x07,
+    /* 1280x800 (_2) */
+    0x0C,0xE0,0x00,0x05,0x20,0x03,0x10,0x06,0x2C,0x03,0x30,0x00,0x70,
+    0x00,0x04,0x00,0x03,0x00,0x49,0xCE,0x1E,0x00,0x00,0x00,0x00,0x09,
     /* 1680x1050 */
     0x0D,0xE0,0x90,0x06,0x1A,0x04,0x6C,0x07,0x2A,0x04,0x1A,0x00,0x4C,
     0x00,0x03,0x00,0x06,0x00,0x79,0xBE,0x44,0x00,0x00,0x00,0x00,0x06,
-    /* 1280x768 (not in 0.93) */
-    0x0A,0xC0,0x00,0x05,0x00,0x03,0x80,0x06,0x1E,0x03,0x40,0x00,0x80,
-    0x00,0x03,0x00,0x07,0x00,0x4F,0x00,0x00,0x00,0x00,0x00,0x00,0x06
 };
 #endif
 
@@ -308,8 +301,8 @@
 BOOLEAN	SiS_IsVAMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
 void	SiS_SetChrontelGPIO(SiS_Private *SiS_Pr, USHORT myvbinfo);
 void	SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT ModeNo,
-              USHORT ModeIdIndex,PSIS_HW_INFO HwInfo,
-	      int checkcrt2mode);
+              	USHORT ModeIdIndex, PSIS_HW_INFO HwInfo,
+	      	int checkcrt2mode);
 void	SiS_SetYPbPr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
 void    SiS_SetTVMode(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, PSIS_HW_INFO HwInfo);
 void	SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, PSIS_HW_INFO HwInfo);
@@ -330,58 +323,61 @@
 USHORT 	SiS_GetCH70xx(SiS_Private *SiS_Pr, USHORT tempax);
 void   	SiS_SetCH70xxANDOR(SiS_Private *SiS_Pr, USHORT tempax,USHORT tempbh);
 #ifdef SIS315H
-void   	SiS_Chrontel701xOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
-void   	SiS_Chrontel701xOff(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
-void   	SiS_ChrontelInitTVVSync(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
-void   	SiS_ChrontelDoSomething1(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
+static void   	SiS_Chrontel701xOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
+static void   	SiS_Chrontel701xOff(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
+static void   	SiS_ChrontelInitTVVSync(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
+static void  	SiS_ChrontelDoSomething1(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
 void   	SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
 void   	SiS_Chrontel701xBLOff(SiS_Private *SiS_Pr);
 #endif /* 315 */
+
 #ifdef SIS300
-void    SiS_SetTrumpReg(SiS_Private *SiS_Pr, USHORT tempbx);
-USHORT  SiS_GetTrumpReg(SiS_Private *SiS_Pr, USHORT tempbx);
-static  BOOLEAN SiS_SetTrumpionBlock(SiS_Private *SiS_Pr, UCHAR *dataptr);
+#if 0
+static  void    SiS_SetTrumpReg(SiS_Private *SiS_Pr, USHORT tempbx);
+static  USHORT  SiS_GetTrumpReg(SiS_Private *SiS_Pr, USHORT tempbx);
+#endif
+static  BOOLEAN	SiS_SetTrumpionBlock(SiS_Private *SiS_Pr, UCHAR *dataptr);
 #endif
 
-USHORT  SiS_ReadDDC1Bit(SiS_Private *SiS_Pr);
-void    SiS_SetSwitchDDC2(SiS_Private *SiS_Pr);
-USHORT  SiS_SetStart(SiS_Private *SiS_Pr);
-USHORT  SiS_SetStop(SiS_Private *SiS_Pr);
 void    SiS_DDC2Delay(SiS_Private *SiS_Pr, USHORT delaytime);
-USHORT  SiS_SetSCLKLow(SiS_Private *SiS_Pr);
-USHORT  SiS_SetSCLKHigh(SiS_Private *SiS_Pr);
-USHORT  SiS_ReadDDC2Data(SiS_Private *SiS_Pr, USHORT tempax);
-USHORT  SiS_WriteDDC2Data(SiS_Private *SiS_Pr, USHORT tempax);
-USHORT  SiS_CheckACK(SiS_Private *SiS_Pr);
-
-USHORT  SiS_InitDDCRegs(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
-                        USHORT adaptnum, USHORT DDCdatatype, BOOLEAN checkcr32);
-USHORT  SiS_WriteDABDDC(SiS_Private *SiS_Pr);
-USHORT  SiS_PrepareReadDDC(SiS_Private *SiS_Pr);
-USHORT  SiS_PrepareDDC(SiS_Private *SiS_Pr);
-void    SiS_SendACK(SiS_Private *SiS_Pr, USHORT yesno);
-USHORT  SiS_DoProbeDDC(SiS_Private *SiS_Pr);
-USHORT  SiS_ProbeDDC(SiS_Private *SiS_Pr);
-USHORT  SiS_ReadDDC(SiS_Private *SiS_Pr, USHORT DDCdatatype, unsigned char *buffer);
-USHORT  SiS_HandleDDC(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
-		      USHORT adaptnum, USHORT DDCdatatype, unsigned char *buffer);
+USHORT  SiS_ReadDDC1Bit(SiS_Private *SiS_Pr);
+USHORT  SiS_HandleDDC(SiS_Private *SiS_Pr, ULONG VBFlags, int VGAEngine,
+		      USHORT adaptnum, USHORT DDCdatatype, UCHAR *buffer);
 #ifdef LINUX_XF86
 USHORT  SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS);
 USHORT  SiS_SenseVGA2DDC(SiS_Private *SiS_Pr, SISPtr pSiS);
 #endif
 
+static void    	SiS_SetSwitchDDC2(SiS_Private *SiS_Pr);
+static USHORT  	SiS_SetStart(SiS_Private *SiS_Pr);
+static USHORT  	SiS_SetStop(SiS_Private *SiS_Pr);
+static USHORT  	SiS_SetSCLKLow(SiS_Private *SiS_Pr);
+static USHORT  	SiS_SetSCLKHigh(SiS_Private *SiS_Pr);
+static USHORT  	SiS_ReadDDC2Data(SiS_Private *SiS_Pr, USHORT tempax);
+static USHORT  	SiS_WriteDDC2Data(SiS_Private *SiS_Pr, USHORT tempax);
+static USHORT  	SiS_CheckACK(SiS_Private *SiS_Pr);
+static USHORT  	SiS_InitDDCRegs(SiS_Private *SiS_Pr, ULONG VBFlags, int VGAEngine,
+                        USHORT adaptnum, USHORT DDCdatatype, BOOLEAN checkcr32);
+static USHORT  	SiS_WriteDABDDC(SiS_Private *SiS_Pr);
+static USHORT  	SiS_PrepareReadDDC(SiS_Private *SiS_Pr);
+static USHORT  	SiS_PrepareDDC(SiS_Private *SiS_Pr);
+static void    	SiS_SendACK(SiS_Private *SiS_Pr, USHORT yesno);
+static USHORT  	SiS_DoProbeDDC(SiS_Private *SiS_Pr);
+static USHORT  	SiS_ProbeDDC(SiS_Private *SiS_Pr);
+static USHORT  	SiS_ReadDDC(SiS_Private *SiS_Pr, USHORT DDCdatatype, UCHAR *buffer);
+
 #ifdef SIS315H
-void    SiS_OEM310Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
-                          USHORT ModeNo,USHORT ModeIdIndex);
-void    SiS_OEM661Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
-                          USHORT ModeNo,USHORT ModeIdIndex, USHORT RRTI);
-void    SiS_FinalizeLCD(SiS_Private *, USHORT, USHORT, PSIS_HW_INFO);
+static void    	SiS_OEM310Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
+                        USHORT ModeNo,USHORT ModeIdIndex, USHORT RRTI);
+static void    	SiS_OEM661Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
+                        USHORT ModeNo,USHORT ModeIdIndex, USHORT RRTI);
+static void    	SiS_FinalizeLCD(SiS_Private *, USHORT, USHORT, PSIS_HW_INFO);
 #endif
 #ifdef SIS300
-void    SiS_OEM300Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
-                          USHORT ModeNo, USHORT ModeIdIndex, USHORT RefTabindex);
-void    SetOEMLCDData2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
-		       USHORT ModeNo, USHORT ModeIdIndex,USHORT RefTableIndex);
+static void    	SiS_OEM300Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
+                        USHORT ModeNo, USHORT ModeIdIndex, USHORT RefTabindex);
+static void    	SetOEMLCDData2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
+		        USHORT ModeNo, USHORT ModeIdIndex,USHORT RefTableIndex);
 #endif
 
 extern void     SiS_SetReg(SISIOADDRESS, USHORT, USHORT);
@@ -392,23 +388,23 @@
 extern UCHAR    SiS_GetRegByte(SISIOADDRESS);
 extern USHORT   SiS_GetRegShort(SISIOADDRESS);
 extern ULONG    SiS_GetRegLong(SISIOADDRESS);
-extern void     SiS_SetRegANDOR(SISIOADDRESS Port,USHORT Index,USHORT DataAND,USHORT DataOR);
-extern void     SiS_SetRegOR(SISIOADDRESS Port,USHORT Index,USHORT DataOR);
-extern void     SiS_SetRegAND(SISIOADDRESS Port,USHORT Index,USHORT DataAND);
-
+extern void     SiS_SetRegANDOR(SISIOADDRESS, USHORT, USHORT, USHORT);
+extern void     SiS_SetRegOR(SISIOADDRESS, USHORT, USHORT);
+extern void     SiS_SetRegAND(SISIOADDRESS, USHORT, USHORT);
 extern void     SiS_DisplayOff(SiS_Private *SiS_Pr);
 extern void     SiS_DisplayOn(SiS_Private *SiS_Pr);
-
 extern BOOLEAN  SiS_SearchModeID(SiS_Private *, USHORT *, USHORT *);
-extern UCHAR    SiS_GetModePtr(SiS_Private *SiS_Pr, USHORT ModeNo,USHORT ModeIdIndex);
-
-extern USHORT   SiS_GetColorDepth(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex);
-extern USHORT   SiS_GetOffset(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
-                              USHORT RefreshRateTableIndex,PSIS_HW_INFO HwInfo);
-
-extern void     SiS_LoadDAC(SiS_Private *SiS_Pr, PSIS_HW_INFO,USHORT ModeNo,
-                            USHORT ModeIdIndex);
-
-extern void	SiS_CalcLCDACRT1Timing(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex);
+extern UCHAR    SiS_GetModePtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex);
+extern USHORT   SiS_GetColorDepth(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex);
+extern USHORT   SiS_GetOffset(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
+                      	USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo);
+extern void     SiS_LoadDAC(SiS_Private *SiS_Pr, PSIS_HW_INFO, USHORT ModeNo,
+                        USHORT ModeIdIndex);
+extern void	SiS_CalcLCDACRT1Timing(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex);
+#ifdef LINUX_XF86
+extern void     SiS_MakeClockRegs(ScrnInfoPtr pScrn, int clock, UCHAR *p2b, UCHAR *p2c);
+extern int 	SiS_FindPanelFromDB(SISPtr pSiS, USHORT panelvendor, USHORT panelproduct,
+			int *maxx, int *maxy, int *prefx, int *prefy);
+#endif
 
 #endif
diff -Nru a/drivers/video/sis/initdef.h b/drivers/video/sis/initdef.h
--- a/drivers/video/sis/initdef.h	2005-03-01 23:39:06 -08:00
+++ b/drivers/video/sis/initdef.h	2005-03-01 23:39:06 -08:00
@@ -35,7 +35,7 @@
  * * 3) The name of the author may not be used to endorse or promote products
  * *    derived from this software without specific prior written permission.
  * *
- * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR
+ * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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,
@@ -80,6 +80,7 @@
 #define VB_SIS302LV     	0x0010
 #define VB_SIS302ELV		0x0020
 #define VB_SIS301C              0x0040
+#define VB_UMC			0x4000
 #define VB_NoLCD        	0x8000
 #define VB_SIS301BLV302BLV      (VB_SIS301B|VB_SIS301C|VB_SIS302B|VB_SIS301LV|VB_SIS302LV|VB_SIS302ELV)
 #define VB_SIS301B302B          (VB_SIS301B|VB_SIS301C|VB_SIS302B)
@@ -87,6 +88,9 @@
 #define VB_SISVB		(VB_SIS301 | VB_SIS301BLV302BLV)
 #define VB_SISTMDS		(VB_SIS301 | VB_SIS301B302B)
 #define VB_SISLVDS		VB_SIS301LV302LV
+#define VB_SISLCDA		(VB_SIS302B|VB_SIS301C|VB_SIS301LV|VB_SIS302LV|VB_SIS302ELV)
+#define VB_SISYPBPR		(VB_SIS301C|VB_SIS301LV|VB_SIS302LV|VB_SIS302ELV)
+#define VB_SISHIVISION		(VB_SIS301|VB_SIS301B|VB_SIS302B)
 
 /* VBInfo */
 #define SetSimuScanMode         0x0001   /* CR 30 */
@@ -126,7 +130,7 @@
 #define Mode24Bpp               0x06
 #define Mode32Bpp               0x07
 
-#define ModeInfoFlag            0x07
+#define ModeTypeMask            0x07
 #define IsTextMode              0x07
 
 #define DACInfoFlag             0x0018
@@ -139,7 +143,7 @@
 #define CRT2Mode                0x0800
 #define HalfDCLK                0x1000
 #define NoSupportSimuTV         0x2000
-#define NoSupportLCDScale	0x4000 /* TMDS: No scaling possible (no matter what panel) */
+#define NoSupportLCDScale	0x4000 /* SiS bridge: No scaling possible (no matter what panel) */
 #define DoubleScanMode          0x8000
 
 /* Infoflag */
@@ -402,17 +406,18 @@
 #define Panel_1400x1050         0x09
 #define Panel_1280x768          0x0a    /* 30xB/C and LVDS only (BIOS: all) */
 #define Panel_1600x1200         0x0b
-#define Panel_1280x800		0x0c    /* 661etc  */
+#define Panel_1280x800		0x0c    /* 661etc (TMDS) */
 #define Panel_1680x1050         0x0d    /* 661etc  */
 #define Panel_1280x720		0x0e    /* 661etc  */
-#define Panel_Custom		0x0f	/* MUST BE 0x0f (for DVI DDC detection */
+#define Panel_Custom		0x0f	/* MUST BE 0x0f (for DVI DDC detection) */
 #define Panel_320x480           0x10    /* SiS 550 fstn - TW: This is fake, can be any */
 #define Panel_Barco1366         0x11
 #define Panel_848x480		0x12
 #define Panel_640x480_2		0x13    /* SiS 550 */
 #define Panel_640x480_3		0x14    /* SiS 550 */
 #define Panel_1280x768_2        0x15	/* 30xLV */
-#define Panel_1280x768_3        0x16    /* 30xLV */
+#define Panel_1280x768_3        0x16    /* (unused) */
+#define Panel_1280x800_2	0x17    /* 30xLV */
 
 /* Index in ModeResInfo table */
 #define SIS_RI_320x200    0
@@ -448,6 +453,7 @@
 #define SIS_RI_1280x800  30
 #define SIS_RI_1920x1080 31
 #define SIS_RI_960x540   32
+#define SIS_RI_960x600   33
 
 /* CR5F */
 #define IsM650                  0x80
@@ -475,7 +481,7 @@
 #define VCLK108_3_300           0x42   /* Index in VCLKData table (300) */
 #define VCLK100_300             0x43   /* Index in VCLKData table (300) */
 #define VCLK34_300              0x3d   /* Index in VCLKData table (300) */
-#define VCLK_CUSTOM_300		0x46
+#define VCLK_CUSTOM_300		0x47
 #define VCLK65_315              0x0b   /* Index in (VB)VCLKData table (315) */
 #define VCLK108_2_315           0x19   /* Index in (VB)VCLKData table (315) */
 #define VCLK81_315		0x5b   /* Index in (VB)VCLKData table (315) */
@@ -484,12 +490,11 @@
 #define VCLK100_315             0x46   /* Index in VBVCLKData table (315) */
 #define VCLK34_315              0x55
 #define VCLK68_315		0x0d
-#define VCLK69_315		0x5c   /* deprecated ! Index in VBVCLKData table (315) */
-#define VCLK83_315		0x5c   /* Index in VBVCLKData table (315) */
+#define VCLK_1280x800_315_2	0x5c   /* Index in VBVCLKData table (315) */
 #define VCLK121_315		0x5d   /* Index in VBVCLKData table (315) */
 #define VCLK_1280x720		0x5f
 #define VCLK_1280x768_2		0x60
-#define VCLK_1280x768_3		0x61
+#define VCLK_1280x768_3		0x61   /* (unused?) */
 #define VCLK_CUSTOM_315		0x62
 #define VCLK_1280x720_2		0x63
 #define VCLK_720x480		0x67
@@ -501,6 +506,7 @@
 #define VCLK_1024x576		0x51
 #define VCLK_1152x864		0x64
 #define VCLK_1360x768		0x58
+#define VCLK_1280x800_315	0x6c
 
 #define TVCLKBASE_300		0x21   /* Indices on TV clocks in VCLKData table (300) */
 #define TVCLKBASE_315	        0x3a   /* Indices on TV clocks in (VB)VCLKData table (315) */
diff -Nru a/drivers/video/sis/oem300.h b/drivers/video/sis/oem300.h
--- a/drivers/video/sis/oem300.h	2005-03-01 23:38:54 -08:00
+++ b/drivers/video/sis/oem300.h	2005-03-01 23:38:54 -08:00
@@ -35,7 +35,7 @@
  * * 3) The name of the author may not be used to endorse or promote products
  * *    derived from this software without specific prior written permission.
  * *
- * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR
+ * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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,
@@ -50,7 +50,7 @@
  *
  */
 
-const UCHAR SiS300_OEMTVDelay301[8][4] =
+static const UCHAR SiS300_OEMTVDelay301[8][4] =
 {
 	{0x08,0x08,0x08,0x08},
 	{0x08,0x08,0x08,0x08},
@@ -62,7 +62,7 @@
 	{0x20,0x20,0x20,0x20}
 };
 
-const UCHAR SiS300_OEMTVDelayLVDS[8][4] =
+static const UCHAR SiS300_OEMTVDelayLVDS[8][4] =
 {
 	{0x20,0x20,0x20,0x20},
 	{0x20,0x20,0x20,0x20},
@@ -74,7 +74,7 @@
 	{0x20,0x20,0x20,0x20}
 };
 
-const UCHAR SiS300_OEMTVFlicker[8][4] =
+static const UCHAR SiS300_OEMTVFlicker[8][4] =
 {
 	{0x00,0x00,0x00,0x00},
 	{0x00,0x00,0x00,0x00},
@@ -87,7 +87,7 @@
 };
 
 #if 0   /* TW: Not used */
-const UCHAR SiS300_OEMLCDDelay1[12][4]={
+static const UCHAR SiS300_OEMLCDDelay1[12][4]={
 	{0x2c,0x2c,0x2c,0x2c},
 	{0x20,0x20,0x20,0x20},
 	{0x20,0x20,0x20,0x20},
@@ -103,8 +103,8 @@
 };
 #endif
 
-/* TW: From 630/301B BIOS */
-const UCHAR SiS300_OEMLCDDelay2[64][4] =		 /* for 301/301b/302b/301LV/302LV */
+/* From 630/301B BIOS */
+static const UCHAR SiS300_OEMLCDDelay2[64][4] =		 /* for 301/301b/302b/301LV/302LV */
 {
 	{0x20,0x20,0x20,0x20},
 	{0x20,0x20,0x20,0x20},
@@ -172,8 +172,8 @@
 	{0x20,0x20,0x20,0x20}
 };
 
-/* TW: From 300/301LV BIOS */
-const UCHAR SiS300_OEMLCDDelay4[12][4] =
+/* From 300/301LV BIOS */
+static const UCHAR SiS300_OEMLCDDelay4[12][4] =
 {
 	{0x2c,0x2c,0x2c,0x2c},
 	{0x20,0x20,0x20,0x20},
@@ -189,8 +189,8 @@
 	{0x24,0x24,0x24,0x24}
 };
 
-/* TW: From 300/301LV BIOS */
-const UCHAR SiS300_OEMLCDDelay5[32][4] =
+/* From 300/301LV BIOS */
+static const UCHAR SiS300_OEMLCDDelay5[32][4] =
 {
 	{0x20,0x20,0x20,0x20},
 	{0x20,0x20,0x20,0x20},
@@ -226,8 +226,8 @@
 	{0x20,0x20,0x20,0x20},
 };
 
-/* TW: Added for LVDS */
-const UCHAR SiS300_OEMLCDDelay3[64][4] = {	/* For LVDS */
+/* Added for LVDS */
+static const UCHAR SiS300_OEMLCDDelay3[64][4] = {	/* For LVDS */
 	{0x20,0x20,0x20,0x20},
 	{0x20,0x20,0x20,0x20},
 	{0x20,0x20,0x20,0x20},
@@ -294,7 +294,7 @@
 	{0x20,0x20,0x20,0x20}
 };
 
-const UCHAR SiS300_Phase1[8][5][4] =
+static const UCHAR SiS300_Phase1[8][5][4] =
 {
     {
 	{0x21,0xed,0x00,0x08},
@@ -355,7 +355,7 @@
 };
 
 
-const UCHAR SiS300_Phase2[8][5][4] =
+static const UCHAR SiS300_Phase2[8][5][4] =
 {
     {
         {0x21,0xed,0x00,0x08},
@@ -415,7 +415,7 @@
     }
 };
 
-const UCHAR SiS300_Filter1[10][16][4] =
+static const UCHAR SiS300_Filter1[10][16][4] =
 {
     {
 	{0x00,0xf4,0x10,0x38},
@@ -599,7 +599,7 @@
     },
 };
 
-const UCHAR SiS300_Filter2[10][9][7] =
+static const UCHAR SiS300_Filter2[10][9][7] =
 {
     {
 	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
@@ -714,7 +714,7 @@
 };
 
 /* Custom data for Barco iQ Pro R300 */
-const UCHAR barco_p1[2][9][7][3] = {
+static const UCHAR barco_p1[2][9][7][3] = {
     {
 	{  { 0x16, 0xcf, 0x00 },
 	   { 0x18, 0x00, 0x00 },
diff -Nru a/drivers/video/sis/oem310.h b/drivers/video/sis/oem310.h
--- a/drivers/video/sis/oem310.h	2005-03-01 23:38:44 -08:00
+++ b/drivers/video/sis/oem310.h	2005-03-01 23:38:44 -08:00
@@ -35,7 +35,7 @@
  * * 3) The name of the author may not be used to endorse or promote products
  * *    derived from this software without specific prior written permission.
  * *
- * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR
+ * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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,
diff -Nru a/drivers/video/sis/osdef.h b/drivers/video/sis/osdef.h
--- a/drivers/video/sis/osdef.h	2005-03-01 23:38:44 -08:00
+++ b/drivers/video/sis/osdef.h	2005-03-01 23:38:44 -08:00
@@ -35,7 +35,7 @@
  * * 3) The name of the author may not be used to endorse or promote products
  * *    derived from this software without specific prior written permission.
  * *
- * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR
+ * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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,
@@ -51,9 +51,12 @@
  *
  */
 
+#ifndef _SIS_OSDEF_H_
+#define _SIS_OSDEF_H_
+
 /* The choices are: */
-#define LINUX_KERNEL	   /* Kernel framebuffer */
-/* #define LINUX_XF86 */   /* XFree86 */
+#define LINUX_KERNEL	   /* Linux kernel framebuffer */
+/* #define LINUX_XF86 */   /* XFree86/X.org */
 
 #ifdef OutPortByte
 #undef OutPortByte
@@ -109,20 +112,20 @@
 #endif
 
 /**********************************************************************/
-/*  XFree86, X.org                                                    */
+/*  XFree86/X.org                                                    */
 /**********************************************************************/
 
 #ifdef LINUX_XF86
 #define SIS300
 #define SIS315H
 
-#define OutPortByte(p,v) outb((IOADDRESS)(p),(CARD8)(v))
-#define OutPortWord(p,v) outw((IOADDRESS)(p),(CARD16)(v))
-#define OutPortLong(p,v) outl((IOADDRESS)(p),(CARD32)(v))
-#define InPortByte(p)    inb((IOADDRESS)(p))
-#define InPortWord(p)    inw((IOADDRESS)(p))
-#define InPortLong(p)    inl((IOADDRESS)(p))
+#define OutPortByte(p,v) outSISREG((IOADDRESS)(p),(CARD8)(v))
+#define OutPortWord(p,v) outSISREGW((IOADDRESS)(p),(CARD16)(v))
+#define OutPortLong(p,v) outSISREGL((IOADDRESS)(p),(CARD32)(v))
+#define InPortByte(p)    inSISREG((IOADDRESS)(p))
+#define InPortWord(p)    inSISREGW((IOADDRESS)(p))
+#define InPortLong(p)    inSISREGL((IOADDRESS)(p))
 #define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize)
 #endif
 
-
+#endif  /* _OSDEF_H_ */
diff -Nru a/drivers/video/sis/sis.h b/drivers/video/sis/sis.h
--- a/drivers/video/sis/sis.h	2005-03-01 23:39:07 -08:00
+++ b/drivers/video/sis/sis.h	2005-03-01 23:39:07 -08:00
@@ -1,5 +1,5 @@
 /*
- * SiS 300/630/730/540/315/550/650/651/M650/661FX/M661FX/740/741/330/760
+ * SiS 300/630/730/540/315/550/[M]650/651/[M]661[FM]X/740/[M]741[GX]/330/[M]760[GX]
  * frame buffer driver for Linux kernels >=2.4.14 and >=2.6.3
  *
  * Copyright (C) 2001-2004 Thomas Winischhofer, Vienna, Austria.
@@ -37,7 +37,7 @@
 
 #define VER_MAJOR                 1
 #define VER_MINOR                 7
-#define VER_LEVEL                 12
+#define VER_LEVEL                 17
 
 #undef SIS_CONFIG_COMPAT
 
@@ -55,6 +55,16 @@
 #endif
 #endif
 
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8)
+#define SIS_IOTYPE1 void __iomem
+#define SIS_IOTYPE2 __iomem
+#define SISINITSTATIC static
+#else
+#define SIS_IOTYPE1 unsigned char
+#define SIS_IOTYPE2
+#define SISINITSTATIC
+#endif
+
 #undef SISFBDEBUG
 
 #ifdef SISFBDEBUG
@@ -180,6 +190,7 @@
 #define SIS_CRT2_WENABLE_315 	  0x2F
 
 #define SIS_PASSWORD              0x86  /* SR05 */
+
 #define SIS_INTERLACED_MODE       0x20  /* SR06 */
 #define SIS_8BPP_COLOR_MODE       0x0
 #define SIS_15BPP_COLOR_MODE      0x1
@@ -238,41 +249,58 @@
 #define HW_DEVICE_EXTENSION	  SIS_HW_INFO
 #define PHW_DEVICE_EXTENSION      PSIS_HW_INFO
 
-/* Useful macros */
+/* I/O port access macros */
 #define inSISREG(base)          inb(base)
+
 #define outSISREG(base,val)     outb(val,base)
-#define orSISREG(base,val)      do { \
-                                  u8 __Temp = inb(base); \
-                                  outSISREG(base, __Temp | (val)); \
-                                } while (0)
-#define andSISREG(base,val)     do { \
-                                  u8 __Temp = inb(base); \
-                                  outSISREG(base, __Temp & (val)); \
-                                } while (0)
-#define inSISIDXREG(base,idx,var)   do { \
-                                      outb(idx,base); var=inb((base)+1); \
-                                    } while (0)
-#define outSISIDXREG(base,idx,val)  do { \
-                                      outb(idx,base); outb((val),(base)+1); \
-                                    } while (0)
-#define orSISIDXREG(base,idx,val)   do { \
-                                      u8 __Temp; \
-                                      outb(idx,base);   \
-                                      __Temp = inb((base)+1)|(val); \
-                                      outSISIDXREG(base,idx,__Temp); \
-                                    } while (0)
-#define andSISIDXREG(base,idx,and)  do { \
-                                      u8 __Temp; \
-                                      outb(idx,base);   \
-                                      __Temp = inb((base)+1)&(and); \
-                                      outSISIDXREG(base,idx,__Temp); \
-                                    } while (0)
-#define setSISIDXREG(base,idx,and,or)   do { \
-                                          u8 __Temp; \
-                                          outb(idx,base);   \
-                                          __Temp = (inb((base)+1)&(and))|(or); \
-                                          outSISIDXREG(base,idx,__Temp); \
-                                        } while (0)
+
+#define orSISREG(base,val)      			\
+		    do { 				\
+                      u8 __Temp = inSISREG(base); 	\
+                      outSISREG(base, __Temp | (val)); 	\
+                    } while (0)
+
+#define andSISREG(base,val)     			\
+		    do { 				\
+                      u8 __Temp = inSISREG(base); 	\
+                      outSISREG(base, __Temp & (val)); 	\
+                    } while (0)
+
+#define inSISIDXREG(base,idx,var)   		\
+		    do { 			\
+                      outSISREG(base, idx); 	\
+		      var = inSISREG((base)+1);	\
+                    } while (0)
+
+#define outSISIDXREG(base,idx,val)  		\
+		    do { 			\
+                      outSISREG(base, idx); 	\
+		      outSISREG((base)+1, val); \
+                    } while (0)
+
+#define orSISIDXREG(base,idx,val)   				\
+		    do { 					\
+                      u8 __Temp; 				\
+                      outSISREG(base, idx);   			\
+                      __Temp = inSISREG((base)+1) | (val); 	\
+		      outSISREG((base)+1, __Temp);		\
+                    } while (0)
+
+#define andSISIDXREG(base,idx,and)  				\
+		    do { 					\
+                      u8 __Temp; 				\
+                      outSISREG(base, idx);   			\
+                      __Temp = inSISREG((base)+1) & (and); 	\
+		      outSISREG((base)+1, __Temp);		\
+                    } while (0)
+
+#define setSISIDXREG(base,idx,and,or)   		   		\
+		    do { 				   		\
+                      u8 __Temp; 		   			\
+                      outSISREG(base, idx);   		   		\
+                      __Temp = (inSISREG((base)+1) & (and)) | (or); 	\
+		      outSISREG((base)+1, __Temp);			\
+                    } while (0)
 
 /* MMIO access macros */
 #define MMIO_IN8(base, offset)  readb((base+offset))
@@ -293,10 +321,52 @@
 #define MMIO_QUEUE_WRITEPORT    Q_WRITE_PTR
 #define MMIO_QUEUE_READPORT     Q_READ_PTR
 
+#ifndef FB_BLANK_UNBLANK
+#define FB_BLANK_UNBLANK 	0
+#endif
+#ifndef FB_BLANK_NORMAL
+#define FB_BLANK_NORMAL  	1
+#endif
+#ifndef FB_BLANK_VSYNC_SUSPEND
+#define FB_BLANK_VSYNC_SUSPEND 	2
+#endif
+#ifndef FB_BLANK_HSYNC_SUSPEND
+#define FB_BLANK_HSYNC_SUSPEND 	3
+#endif
+#ifndef FB_BLANK_POWERDOWN
+#define FB_BLANK_POWERDOWN 	4
+#endif
+
+enum _SIS_LCD_TYPE {
+    LCD_INVALID = 0,
+    LCD_800x600,
+    LCD_1024x768,
+    LCD_1280x1024,
+    LCD_1280x960,
+    LCD_640x480,
+    LCD_1600x1200,
+    LCD_1920x1440,
+    LCD_2048x1536,
+    LCD_320x480,       /* FSTN */
+    LCD_1400x1050,
+    LCD_1152x864,
+    LCD_1152x768,
+    LCD_1280x768,
+    LCD_1024x600,
+    LCD_640x480_2,     /* DSTN */
+    LCD_640x480_3,     /* DSTN */
+    LCD_848x480,
+    LCD_1280x800,
+    LCD_1680x1050,
+    LCD_1280x720,
+    LCD_CUSTOM,
+    LCD_UNKNOWN
+};
+
 enum _SIS_CMDTYPE {
-	MMIO_CMD = 0,
-	AGP_CMD_QUEUE,
-	VM_CMD_QUEUE,
+    MMIO_CMD = 0,
+    AGP_CMD_QUEUE,
+    VM_CMD_QUEUE,
 };
 typedef unsigned int SIS_CMDTYPE;
 
@@ -360,10 +430,10 @@
 	unsigned long 	mmio_base;
 	unsigned long 	vga_base;
 
-	void __iomem *	video_vbase;
-	void __iomem *	mmio_vbase;
-	void __iomem * 	bios_vbase;
-	void *		bios_abase;
+	SIS_IOTYPE1  	*video_vbase;
+	SIS_IOTYPE1 	*mmio_vbase;
+
+	unsigned char   *bios_abase;
 
 	int 		mtrr;
 
@@ -391,9 +461,9 @@
 	int		sisfb_inverse;
 #endif
 
-	u32 		heapstart;        /* offset  */
-	void __iomem * 	sisfb_heap_start; /* address */
-	void __iomem * 	sisfb_heap_end;   /* address */
+	u32 		heapstart;        	/* offset  */
+	SIS_IOTYPE1  	*sisfb_heap_start; 	/* address */
+	SIS_IOTYPE1  	*sisfb_heap_end;   	/* address */
 	u32 	      	sisfb_heap_size;
 	int		havenoheap;
 #if 0
@@ -434,6 +504,7 @@
 
 	int		lcdxres, lcdyres;
 	int		lcddefmodeidx, tvdefmodeidx, defmodeidx;
+	u32  		CRT2LCDType;        	/* defined in "SIS_LCD_TYPE" */
 
 	int    		current_bpp;
 	int    		current_width;
@@ -455,10 +526,7 @@
 
 	int  		newrom;
 	int  		registered;
-#ifdef SIS_CONFIG_COMPAT
-	int		ioctl32registered;
-	int		ioctl32vblankregistered;
-#endif
+	int		warncount;
 
 	int 		sisvga_engine;
 	int 		hwcursor_size;
@@ -469,7 +537,7 @@
 	u8 		detectedpdca;
 	u8 		detectedlcda;
 
-	void __iomem * 	hwcursor_vbase;
+	SIS_IOTYPE1 	*hwcursor_vbase;
 
 	int 		chronteltype;
 	int    		tvxpos, tvypos;
diff -Nru a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c
--- a/drivers/video/sis/sis_main.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/video/sis/sis_main.c	2005-03-01 23:39:07 -08:00
@@ -39,6 +39,7 @@
 #include <linux/moduleparam.h>
 #endif
 #include <linux/kernel.h>
+#include <linux/smp_lock.h>
 #include <linux/spinlock.h>
 #include <linux/errno.h>
 #include <linux/string.h>
@@ -754,8 +755,8 @@
    }
 
    inSISIDXREG(SISPART1, reg, temp);
-   if(temp & 0x02) return FALSE;
-   else 	   return TRUE;
+   if(temp & 0x02) return TRUE;
+   else 	   return FALSE;
 }
 
 static BOOLEAN
@@ -794,9 +795,9 @@
       inSISIDXREG(SISPART1,(idx+1),reg2); /* 31 */
       inSISIDXREG(SISPART1,(idx+2),reg3); /* 32 */
       inSISIDXREG(SISPART1,(idx+3),reg4); /* 33 */
-      if(!(reg1 & 0x01)) ret |= FB_VBLANK_VBLANKING;
-      if(!(reg1 & 0x02)) ret |= FB_VBLANK_VSYNCING;
-      if(!(reg4 & 0x80)) ret |= FB_VBLANK_HBLANKING;
+      if(reg1 & 0x01) ret |= FB_VBLANK_VBLANKING;
+      if(reg1 & 0x02) ret |= FB_VBLANK_VSYNCING;
+      if(reg4 & 0x80) ret |= FB_VBLANK_HBLANKING;
       (*vcount) = reg3 | ((reg4 & 0x70) << 4);
       (*hcount) = reg2 | ((reg4 & 0x0f) << 8);
    } else if(sisfballowretracecrt1(ivideo)) {
@@ -824,7 +825,7 @@
    BOOLEAN backlight = TRUE;
 
    switch(blank) {
-   case 0:	/* on */
+   case FB_BLANK_UNBLANK:	/* on */
       sr01  = 0x00;
       sr11  = 0x00;
       sr1f  = 0x00;
@@ -833,7 +834,7 @@
       p1_13 = 0x00;
       backlight = TRUE;
       break;
-   case 1:	/* blank */
+   case FB_BLANK_NORMAL:	/* blank */
       sr01  = 0x20;
       sr11  = 0x00;
       sr1f  = 0x00;
@@ -842,7 +843,7 @@
       p1_13 = 0x00;
       backlight = TRUE;
       break;
-   case 2:	/* no vsync */
+   case FB_BLANK_VSYNC_SUSPEND:	/* no vsync */
       sr01  = 0x20;
       sr11  = 0x08;
       sr1f  = 0x80;
@@ -851,7 +852,7 @@
       p1_13 = 0x80;
       backlight = FALSE;
       break;
-   case 3:	/* no hsync */
+   case FB_BLANK_HSYNC_SUSPEND:	/* no hsync */
       sr01  = 0x20;
       sr11  = 0x08;
       sr1f  = 0x40;
@@ -860,7 +861,7 @@
       p1_13 = 0x40;
       backlight = FALSE;
       break;
-   case 4:	/* off */
+   case FB_BLANK_POWERDOWN:	/* off */
       sr01  = 0x20;
       sr11  = 0x08;
       sr1f  = 0xc0;
@@ -1566,10 +1567,10 @@
         if(con != ivideo->currcon) return;
 
         if(fb_display[con].cmap.len) {
-		fb_set_cmap(&fb_display[con].cmap, sisfb_setcolreg, info);
+		fb_set_cmap(&fb_display[con].cmap, 1, sisfb_setcolreg, info);
         } else {
 		int size = sisfb_get_cmap_len(&fb_display[con].var);
-		fb_set_cmap(fb_default_cmap(size), sisfb_setcolreg, info);
+		fb_set_cmap(fb_default_cmap(size), 1, sisfb_setcolreg, info);
 	}
 }
 
@@ -1812,11 +1813,10 @@
         if((err = sisfb_do_set_var(&info->var, 1, info))) {
 		return err;
 	}
-
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
 	sisfb_get_fix(&info->fix, info->currcon, info);
 #else
-	sisfb_get_fix(&info->fix, -1, info);
+      	sisfb_get_fix(&info->fix, -1, info);
 #endif
 	return 0;
 }
@@ -2054,24 +2054,26 @@
 #endif
 	    struct fb_info *info)
 {
-	struct sis_video_info 	*ivideo = (struct sis_video_info *)info->par;
+	struct sis_video_info	*ivideo = (struct sis_video_info *)info->par;
 	struct sis_memreq 	sismemreq;
 	struct fb_vblank  	sisvbblank;
 	sisfb_info        	x;
 	u32			gpu32 = 0;
-	static int 		count = 0;
-	u32 __user		*argp = (u32 __user *) arg;
+#ifndef __user
+#define __user
+#endif
+	u32 __user 		*argp = (u32 __user *)arg;
 
 	switch (cmd) {
 	   case FBIO_ALLOC:
 		if(!capable(CAP_SYS_RAWIO)) {
 			return -EPERM;
 		}
-		if(copy_from_user(&sismemreq, argp, sizeof(sismemreq))) {
+		if(copy_from_user(&sismemreq, (void __user *)arg, sizeof(sismemreq))) {
 		   	return -EFAULT;
 		}
-        	sis_malloc(&sismemreq);
-		if(copy_to_user(argp, &sismemreq, sizeof(sismemreq))) {
+		sis_malloc(&sismemreq);
+		if(copy_to_user((void __user *)arg, &sismemreq, sizeof(sismemreq))) {
 			sis_free((u32)sismemreq.offset);
 		    	return -EFAULT;
 		}
@@ -2090,7 +2092,7 @@
 	   case FBIOGET_VBLANK:
 		sisvbblank.count = 0;
 		sisvbblank.flags = sisfb_setupvbblankflags(ivideo, &sisvbblank.vcount, &sisvbblank.hcount);
-		if(copy_to_user(argp, &sisvbblank, sizeof(sisvbblank))) {
+		if(copy_to_user((void __user *)arg, &sisvbblank, sizeof(sisvbblank))) {
 			return -EFAULT;
 		}
 		break;
@@ -2099,7 +2101,7 @@
 	        return put_user(sizeof(sisfb_info), argp);
 
 	   case SISFB_GET_INFO_OLD:
-	        if(++count < 50) {
+	        if(ivideo->warncount++ < 50) {
 	           printk(KERN_INFO "sisfb: Deprecated ioctl call received - update your application!\n");
 		}
 	   case SISFB_GET_INFO:  /* For communication with X driver */
@@ -2136,13 +2138,13 @@
 		x.sisfb_tvxpos = (u16)(ivideo->tvxpos + 32);
 		x.sisfb_tvypos = (u16)(ivideo->tvypos + 32);
 
-		if(copy_to_user(argp, &x, sizeof(x))) {
+		if(copy_to_user((void __user *)arg, &x, sizeof(x))) {
 			return -EFAULT;
 		}
 	        break;
 
 	   case SISFB_GET_VBRSTATUS_OLD:
-	   	if(++count < 50) {
+	   	if(ivideo->warncount++ < 50) {
 	           printk(KERN_INFO "sisfb: Deprecated ioctl call received - update your application!\n");
 		}
 	   case SISFB_GET_VBRSTATUS:
@@ -2153,15 +2155,15 @@
 		}
 
 	   case SISFB_GET_AUTOMAXIMIZE_OLD:
-	   	if(++count < 50) {
+	   	if(ivideo->warncount++ < 50) {
 	           printk(KERN_INFO "sisfb: Deprecated ioctl call received - update your application!\n");
 		}
 	   case SISFB_GET_AUTOMAXIMIZE:
-	        if(ivideo->sisfb_max) return put_user((u32)1, argp);
-		else 	              return put_user((u32)0, argp);
+	        if(ivideo->sisfb_max)	return put_user((u32)1, argp);
+		else			return put_user((u32)0, argp);
 
 	   case SISFB_SET_AUTOMAXIMIZE_OLD:
-	   	if(++count < 50) {
+	   	if(ivideo->warncount++ < 50) {
 		   printk(KERN_INFO "sisfb: Deprecated ioctl call received - update your application!\n");
 		}
 	   case SISFB_SET_AUTOMAXIMIZE:
@@ -2180,7 +2182,8 @@
 		break;
 
 	   case SISFB_GET_TVPOSOFFSET:
-	        return put_user((u32)(((ivideo->tvxpos+32)<<16)|((ivideo->tvypos+32)&0xffff)), argp);
+	        return put_user((u32)(((ivideo->tvxpos+32)<<16)|((ivideo->tvypos+32)&0xffff)),
+				argp);
 
 	   case SISFB_SET_LOCK:
 		if(copy_from_user(&gpu32, argp, sizeof(gpu32))) {
@@ -2190,11 +2193,22 @@
 		break;
 
 	   default:
-		return -EINVAL;
+		return -ENOIOCTLCMD;
 	}
 	return 0;
 }
 
+#ifdef CONFIG_COMPAT
+static long sisfb_compat_ioctl(struct file *f, unsigned cmd, unsigned long arg, struct fb_info *info)
+{
+	int ret;
+	lock_kernel();
+	ret = sisfb_ioctl(NULL, f, cmd, arg, info);
+	unlock_kernel();
+	return ret;
+}
+#endif
+
 static int
 sisfb_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info)
 {
@@ -2256,7 +2270,10 @@
 	.fb_imageblit   = cfb_imageblit,
 	.fb_cursor      = soft_cursor,
 	.fb_sync        = fbcon_sis_sync,
-	.fb_ioctl       = sisfb_ioctl
+	.fb_ioctl       = sisfb_ioctl,
+#ifdef CONFIG_COMPAT
+	.fb_compat_ioctl = sisfb_compat_ioctl,
+#endif
 };
 #endif
 
@@ -2628,29 +2645,29 @@
 static void __devinit sisfb_sense_crt1(struct sis_video_info *ivideo)
 {
     BOOLEAN mustwait = FALSE;
-    u8  SR1F, CR17;
+    u8  sr1F, cr17;
 #ifdef CONFIG_FB_SIS_315
-    u8  CR63=0;
+    u8  cr63=0;
 #endif
     u16 temp = 0xffff;
     int i;
 
-    inSISIDXREG(SISSR,0x1F,SR1F);
+    inSISIDXREG(SISSR,0x1F,sr1F);
     orSISIDXREG(SISSR,0x1F,0x04);
     andSISIDXREG(SISSR,0x1F,0x3F);
-    if(SR1F & 0xc0) mustwait = TRUE;
+    if(sr1F & 0xc0) mustwait = TRUE;
 
 #ifdef CONFIG_FB_SIS_315
     if(ivideo->sisvga_engine == SIS_315_VGA) {
-       inSISIDXREG(SISCR,ivideo->SiS_Pr.SiS_MyCR63,CR63);
-       CR63 &= 0x40;
+       inSISIDXREG(SISCR,ivideo->SiS_Pr.SiS_MyCR63,cr63);
+       cr63 &= 0x40;
        andSISIDXREG(SISCR,ivideo->SiS_Pr.SiS_MyCR63,0xBF);
     }
 #endif
 
-    inSISIDXREG(SISCR,0x17,CR17);
-    CR17 &= 0x80;
-    if(!CR17) {
+    inSISIDXREG(SISCR,0x17,cr17);
+    cr17 &= 0x80;
+    if(!cr17) {
        orSISIDXREG(SISCR,0x17,0x80);
        mustwait = TRUE;
        outSISIDXREG(SISSR, 0x00, 0x01);
@@ -2695,13 +2712,13 @@
 
 #ifdef CONFIG_FB_SIS_315
     if(ivideo->sisvga_engine == SIS_315_VGA) {
-       setSISIDXREG(SISCR,ivideo->SiS_Pr.SiS_MyCR63,0xBF,CR63);
+       setSISIDXREG(SISCR,ivideo->SiS_Pr.SiS_MyCR63,0xBF,cr63);
     }
 #endif
 
-    setSISIDXREG(SISCR,0x17,0x7F,CR17);
+    setSISIDXREG(SISCR,0x17,0x7F,cr17);
 
-    outSISIDXREG(SISSR,0x1F,SR1F);
+    outSISIDXREG(SISSR,0x1F,sr1F);
 }
 
 /* Determine and detect attached devices on SiS30x */
@@ -3840,7 +3857,7 @@
 }
 
 #ifndef MODULE
-int __init sisfb_setup(char *options)
+SISINITSTATIC int __init sisfb_setup(char *options)
 {
 	char *this_opt;
 	
@@ -3955,19 +3972,22 @@
 }
 #endif
 
-static void __iomem * __devinit sis_find_rom(struct pci_dev *pdev)
+static UCHAR * __devinit sis_find_rom(struct pci_dev *pdev)
 {
 	struct sis_video_info *ivideo = pci_get_drvdata(pdev);
+	USHORT pciid;
+	int    romptr;
+	UCHAR  *myrombase;
+	u32    temp;
+	SIS_IOTYPE1 *rom_base, *rom;
+
+	if(!(myrombase = vmalloc(65536))) return NULL;
 
 #if defined(__i386__) || defined(__x86_64__)
-        u32  segstart;
-	void __iomem *rom_base, *rom;
-        int  romptr;
-	unsigned short pciid;
 
-        for(segstart=0x000c0000; segstart<0x000f0000; segstart+=0x00001000) {
+        for(temp = 0x000c0000; temp < 0x000f0000; temp += 0x00001000) {
 
-            rom_base = ioremap(segstart, 0x10000);
+            rom_base = ioremap(temp, 0x10000);
 	    if(!rom_base) continue;
 
 	    if((readb(rom_base) != 0x55) || (readb(rom_base + 1) != 0xaa)) {
@@ -3996,17 +4016,18 @@
 	    }
 
 	    pciid = readb(rom + 6) | (readb(rom + 7) << 8);
-	    if(pciid == ivideo->chip_id) return rom_base;
+	    if(pciid == ivideo->chip_id) {
+	       memcpy_fromio(myrombase, rom_base, 65536);
+	       iounmap(rom_base);
+	       return myrombase;
+	    }
 
 	    iounmap(rom_base);
         }
+
 #else
-	void __iomem *rom_base, *rom, *myrombase = NULL;
-        int  romptr;
-	unsigned short pciid;
-	u32 backup;
 
-	pci_read_config_dword(pdev, PCI_ROM_ADDRESS, &backup);
+	pci_read_config_dword(pdev, PCI_ROM_ADDRESS, &temp);
 	pci_write_config_dword(pdev, PCI_ROM_ADDRESS,
 			(ivideo->video_base & PCI_ROM_ADDRESS_MASK) | PCI_ROM_ADDRESS_ENABLE);
 
@@ -4022,9 +4043,10 @@
 		    if(pciid == 0x1039) {
 		       pciid = readb(rom + 6) | (readb(rom + 7) << 8);
 		       if(pciid == ivideo->chip_id) {
-		          if((myrombase = vmalloc(65536))) {
-			     memcpy_fromio(myrombase, rom_base, 65536);
-			  }
+			  memcpy_fromio(myrombase, rom_base, 65536);
+			  iounmap(rom_base);
+			  pci_write_config_dword(pdev, PCI_ROM_ADDRESS, temp);
+			  return myrombase;
 		       }
 		    }
 		 }
@@ -4032,15 +4054,17 @@
 	   }
 	   iounmap(rom_base);
 	}
-        pci_write_config_dword(pdev, PCI_ROM_ADDRESS, backup);
-	if(myrombase) return myrombase;
+        pci_write_config_dword(pdev, PCI_ROM_ADDRESS, temp);
+
 #endif
+
+       	vfree(myrombase);
         return NULL;
 }
 
 #ifdef CONFIG_FB_SIS_300
 static int __devinit
-sisfb_chkbuswidth300(struct pci_dev *pdev, void __iomem *FBAddress)
+sisfb_chkbuswidth300(struct pci_dev *pdev, SIS_IOTYPE1 *FBAddress)
 {
 	struct sis_video_info *ivideo = pci_get_drvdata(pdev);
 	int i, j;
@@ -4083,8 +4107,9 @@
 sisfb_setramsize300(struct pci_dev *pdev)
 {
 	struct  sis_video_info *ivideo = pci_get_drvdata(pdev);
-	void __iomem *FBAddr = ivideo->sishw_ext.pjVideoMemoryAddress, *Addr;
-	USHORT 	SR13, SR14=0, buswidth, Done, data, TotalCapacity, PhysicalAdrOtherPage=0;
+  	SIS_IOTYPE1 *FBAddr = ivideo->video_vbase;
+	SIS_IOTYPE1 *Addr;
+	USHORT 	sr13, sr14=0, buswidth, Done, data, TotalCapacity, PhysicalAdrOtherPage=0;
 	int     PseudoRankCapacity, PseudoTotalCapacity, PseudoAdrPinCount;
    	int     RankCapacity, AdrPinCount, BankNumHigh, BankNumMid, MB2Bank;
    	int     PageCapacity, PhysicalAdrHigh, PhysicalAdrHalfPage, i, j, k;
@@ -4141,12 +4166,12 @@
                           andSISIDXREG(SISSR,0x15,0xFB); /* Test */
                           orSISIDXREG(SISSR,0x15,0x04);  /* Test */
                           TotalCapacity = SiS_DRAMType[k][3] * buswidth;
-                          SR13 = SiS_DRAMType[k][4];
-                          if(buswidth == 4) SR14 = (TotalCapacity - 1) | 0x80;
-                          if(buswidth == 2) SR14 = (TotalCapacity - 1) | 0x40;
-                          if(buswidth == 1) SR14 = (TotalCapacity - 1) | 0x00;
-                          outSISIDXREG(SISSR,0x13,SR13);
-                          outSISIDXREG(SISSR,0x14,SR14);
+                          sr13 = SiS_DRAMType[k][4];
+                          if(buswidth == 4) sr14 = (TotalCapacity - 1) | 0x80;
+                          if(buswidth == 2) sr14 = (TotalCapacity - 1) | 0x40;
+                          if(buswidth == 1) sr14 = (TotalCapacity - 1) | 0x00;
+                          outSISIDXREG(SISSR,0x13,sr13);
+                          outSISIDXREG(SISSR,0x14,sr14);
                           Addr = FBAddr + BankNumHigh * 64 * 1024 + PhysicalAdrHigh;
                           /* *((USHORT *)(Addr)) = (USHORT)PhysicalAdrHigh; */
 			  writew(((USHORT)PhysicalAdrHigh), Addr);
@@ -4307,10 +4332,10 @@
 	} else {
 #endif
 	   /* Need to map max FB size for finding out about RAM size */
-	   ivideo->sishw_ext.pjVideoMemoryAddress = ioremap(ivideo->video_base, 0x4000000);
-	   if(ivideo->sishw_ext.pjVideoMemoryAddress) {
+	   ivideo->video_vbase = ioremap(ivideo->video_base, 0x4000000);
+	   if(ivideo->video_vbase) {
 	      sisfb_setramsize300(pdev);
-	      iounmap(ivideo->sishw_ext.pjVideoMemoryAddress);
+	      iounmap(ivideo->video_vbase);
 	   } else {
 	      printk(KERN_DEBUG "sisfb: Failed to map memory for size detection, assuming 8MB\n");
 	      outSISIDXREG(SISSR,0x13,0x28);  /* ? */
@@ -4696,8 +4721,8 @@
 	andSIDIDXREG(SISSR,0x13,0x00);
 
 	/* Need to map max FB size for finding out about RAM size */
-	ivideo->sishw_ext.pjVideoMemoryAddress = ioremap(ivideo->video_base, 0x4000000);
-	if(ivideo->sishw_ext.pjVideoMemoryAddress) {
+	ivideo->video_vbase = ioremap(ivideo->video_base, 0x4000000);
+	if(ivideo->video_vbase) {
 	   /* Find out about bus width */
 	   if(memtype <= 1) {
 	      outSISIDXREG(SISSR,0x14,0x02);
@@ -4715,7 +4740,7 @@
 	   /* Find out about size */
 
 
-	   iounmap(ivideo->sishw_ext.pjVideoMemoryAddress);
+	   iounmap(ivideo->video_vbase);
 	} else {
 	   printk(KERN_DEBUG "sisfb: Failed to map memory for size detection, assuming 8MB\n");
 	   outSISIDXREG(SISSR,0x14,0x??);  /* 8MB, 64bit default */
@@ -4765,11 +4790,12 @@
 	} else {
 	   struct sis_video_info *countvideo = card_list;
 	   ivideo->cardnumber = 1;
-	   while ((countvideo = countvideo->next) != NULL) ivideo->cardnumber++;
+	   while((countvideo = countvideo->next) != NULL) ivideo->cardnumber++;
 	}
 
 	strncpy(ivideo->myid, chipinfo->chip_name, 30);
 
+	ivideo->warncount = 0;
 	ivideo->chip_id = pdev->device;
 	pci_read_config_byte(pdev, PCI_REVISION_ID, &ivideo->revision_id);
 	ivideo->sishw_ext.jChipRevision = ivideo->revision_id;
@@ -4780,10 +4806,6 @@
 	ivideo->pcifunc = PCI_FUNC(pdev->devfn);
 	ivideo->subsysvendor = pdev->subsystem_vendor;
 	ivideo->subsysdevice = pdev->subsystem_device;
-#ifdef SIS_CONFIG_COMPAT
-	ivideo->ioctl32registered = 0;
-	ivideo->ioctl32vblankregistered = 0;
-#endif
 
 #ifndef MODULE
 	if(sisfb_mode_idx == -1) {
@@ -4955,18 +4977,16 @@
 	}
 
 	/* Find out about current video mode */
+	ivideo->modeprechange = 0x03;
 	inSISIDXREG(SISCR,0x34,reg);
 	if(reg & 0x7f) {
 		ivideo->modeprechange = reg & 0x7f;
-	} else {
-		ivideo->modeprechange = 0x03;
+	} else if(sisvga_enabled) {
 #if defined(__i386__) || defined(__x86_64__)
-		{
-			unsigned char __iomem *tt = ioremap(0, 0x1000);
-			if(tt) {
-			   	ivideo->modeprechange = tt[0x449];
-			   	iounmap(tt);
-			}
+		unsigned char SIS_IOTYPE2 *tt = ioremap(0, 0x1000);
+		if(tt) {
+		   	ivideo->modeprechange = readb(tt + 0x449);
+		   	iounmap(tt);
 		}
 #endif
 	}
@@ -4997,18 +5017,11 @@
 #endif
 
 	ivideo->bios_abase = NULL;
-	ivideo->bios_vbase = NULL;
 	if(ivideo->sisfb_userom) {
 	    ivideo->sishw_ext.pjVirtualRomBase = sis_find_rom(pdev);
-#if defined(__i386__) || defined(__x86_64__)
-	    ivideo->bios_vbase = ivideo->sishw_ext.pjVirtualRomBase;	/* mapped */
-#else
-	    ivideo->bios_abase = ivideo->sishw_ext.pjVirtualRomBase;	/* allocated */
-#endif
+	    ivideo->bios_abase = ivideo->sishw_ext.pjVirtualRomBase;
 	    if(ivideo->sishw_ext.pjVirtualRomBase) {
-		printk(KERN_INFO "sisfb: Video ROM found and %s to 0x%p\n",
-			ivideo->bios_vbase ? "mapped" : "copied",
-		        ivideo->sishw_ext.pjVirtualRomBase);
+		printk(KERN_INFO "sisfb: Video ROM found and copied\n");
 		ivideo->sishw_ext.UseROM = TRUE;
 	    } else {
 	        ivideo->sishw_ext.UseROM = FALSE;
@@ -5135,7 +5148,6 @@
 		printk(KERN_ERR "sisfb: Fatal error: Unable to reserve frame buffer memory\n");
 		printk(KERN_ERR "sisfb: Is there another framebuffer driver active?\n");
 		if(ivideo->bios_abase) vfree(ivideo->bios_abase);
-		if(ivideo->bios_vbase) iounmap(ivideo->bios_vbase);
 		pci_set_drvdata(pdev, NULL);
 		kfree(sis_fb_info);
 		return -ENODEV;
@@ -5145,7 +5157,6 @@
 		printk(KERN_ERR "sisfb: Fatal error: Unable to reserve MMIO region\n");
 		release_mem_region(ivideo->video_base, ivideo->video_size);
 		if(ivideo->bios_abase) vfree(ivideo->bios_abase);
-		if(ivideo->bios_vbase) iounmap(ivideo->bios_vbase);
 		pci_set_drvdata(pdev, NULL);
 		kfree(sis_fb_info);
 		return -ENODEV;
@@ -5158,7 +5169,6 @@
 	   	release_mem_region(ivideo->video_base, ivideo->video_size);
 	   	release_mem_region(ivideo->mmio_base, ivideo->mmio_size);
 		if(ivideo->bios_abase) vfree(ivideo->bios_abase);
-		if(ivideo->bios_vbase) iounmap(ivideo->bios_vbase);
 		pci_set_drvdata(pdev, NULL);
 	   	kfree(sis_fb_info);
 	   	return -ENODEV;
@@ -5171,17 +5181,16 @@
 	   	release_mem_region(ivideo->video_base, ivideo->video_size);
 	   	release_mem_region(ivideo->mmio_base, ivideo->mmio_size);
 		if(ivideo->bios_abase) vfree(ivideo->bios_abase);
-		if(ivideo->bios_vbase) iounmap(ivideo->bios_vbase);
 		pci_set_drvdata(pdev, NULL);
 	   	kfree(sis_fb_info);
 	   	return -ENODEV;
 	}
 
-	printk(KERN_INFO "sisfb: Framebuffer at 0x%lx, mapped to 0x%p, size %ldk\n",
-	       	ivideo->video_base, ivideo->video_vbase, ivideo->video_size / 1024);
+	printk(KERN_INFO "sisfb: Framebuffer at 0x%lx, mapped to 0x%lx, size %ldk\n",
+	       	ivideo->video_base, (ULONG)ivideo->video_vbase, ivideo->video_size / 1024);
 
-	printk(KERN_INFO "sisfb: MMIO at 0x%lx, mapped to 0x%p, size %ldk\n",
-	       	ivideo->mmio_base, ivideo->mmio_vbase, ivideo->mmio_size / 1024);
+	printk(KERN_INFO "sisfb: MMIO at 0x%lx, mapped to 0x%lx, size %ldk\n",
+	       	ivideo->mmio_base, (ULONG)ivideo->mmio_vbase, ivideo->mmio_size / 1024);
 
 	if((ivideo->havenoheap = sisfb_heap_init(ivideo))) {
 		printk(KERN_WARNING "sisfb: Failed to initialize offscreen memory heap\n");
@@ -5239,24 +5248,27 @@
 		   inSISIDXREG(SISCR, 0x36, reg);
 		   reg &= 0x0f;
 		   if(ivideo->sisvga_engine == SIS_300_VGA) {
-		      ivideo->sishw_ext.ulCRT2LCDType = sis300paneltype[reg];
+		      ivideo->CRT2LCDType = sis300paneltype[reg];
 		   } else if(ivideo->chip >= SIS_661) {
-		      ivideo->sishw_ext.ulCRT2LCDType = sis661paneltype[reg];
+		      ivideo->CRT2LCDType = sis661paneltype[reg];
 		   } else {
-		      ivideo->sishw_ext.ulCRT2LCDType = sis310paneltype[reg];
+		      ivideo->CRT2LCDType = sis310paneltype[reg];
 		      if((ivideo->chip == SIS_550) && (sisfb_fstn)) {
-		         if((ivideo->sishw_ext.ulCRT2LCDType != LCD_640x480_2) &&
-			    (ivideo->sishw_ext.ulCRT2LCDType != LCD_640x480_3)) {
-		      	    ivideo->sishw_ext.ulCRT2LCDType = LCD_320x480;
+		         if((ivideo->CRT2LCDType != LCD_640x480_2) &&
+			    (ivideo->CRT2LCDType != LCD_640x480_3)) {
+		      	    ivideo->CRT2LCDType = LCD_320x480;
 			 }
 		      }
 		   }
-		   if(ivideo->sishw_ext.ulCRT2LCDType == LCD_UNKNOWN) {
-		      ivideo->sishw_ext.ulCRT2LCDType = LCD_1024x768;
-		      printk(KERN_DEBUG "sisfb: Illegal panel ID (%02x), assuming 1024x768\n", reg);
+		   if(ivideo->CRT2LCDType == LCD_UNKNOWN) {
+		      /* For broken BIOSes: Assume 1024x768, RGB18 */
+		      ivideo->CRT2LCDType = LCD_1024x768;
+		      setSISIDXREG(SISCR,0x36,0xf0,0x02);
+		      setSISIDXREG(SISCR,0x37,0xee,0x01);
+		      printk(KERN_DEBUG "sisfb: Invalid panel ID (%02x), assuming 1024x768, RGB18\n", reg);
 		   }
 		   for(i = 0; i < SIS_LCD_NUMBER; i++) {
-		      if(ivideo->sishw_ext.ulCRT2LCDType == sis_lcd_data[i].lcdtype) {
+		      if(ivideo->CRT2LCDType == sis_lcd_data[i].lcdtype) {
 		         ivideo->lcdxres = sis_lcd_data[i].xres;
 			 ivideo->lcdyres = sis_lcd_data[i].yres;
 			 ivideo->lcddefmodeidx = sis_lcd_data[i].default_mode_idx;
@@ -5459,7 +5471,6 @@
 			release_mem_region(ivideo->video_base, ivideo->video_size);
 			release_mem_region(ivideo->mmio_base, ivideo->mmio_size);
 			if(ivideo->bios_abase) vfree(ivideo->bios_abase);
-			if(ivideo->bios_vbase) iounmap(ivideo->bios_vbase);
 			pci_set_drvdata(pdev, NULL);
 			kfree(sis_fb_info);
 			return -EINVAL;
@@ -5583,7 +5594,6 @@
 			release_mem_region(ivideo->video_base, ivideo->video_size);
 			release_mem_region(ivideo->mmio_base, ivideo->mmio_size);
 			if(ivideo->bios_abase) vfree(ivideo->bios_abase);
-			if(ivideo->bios_vbase) iounmap(ivideo->bios_vbase);
 			pci_set_drvdata(pdev, NULL);
 			kfree(sis_fb_info);
 			return -EINVAL;
@@ -5595,30 +5605,6 @@
 		ivideo->next = card_list;
 		card_list = ivideo;
 
-#ifdef SIS_CONFIG_COMPAT
-		{
-		int ret;
-		/* Our ioctls are all "32/64bit compatible" */
-		if(register_ioctl32_conversion(FBIOGET_VBLANK, NULL)) {
-		   printk(KERN_ERR "sisfb: Error registering FBIOGET_VBLANK ioctl32 translation\n");
-		} else {
-		   ivideo->ioctl32vblankregistered = 1;
-		}
-		ret =  register_ioctl32_conversion(FBIO_ALLOC,             NULL);
-		ret |= register_ioctl32_conversion(FBIO_FREE,              NULL);
-		ret |= register_ioctl32_conversion(SISFB_GET_INFO_SIZE,    NULL);
-		ret |= register_ioctl32_conversion(SISFB_GET_INFO,         NULL);
-		ret |= register_ioctl32_conversion(SISFB_GET_TVPOSOFFSET,  NULL);
-		ret |= register_ioctl32_conversion(SISFB_SET_TVPOSOFFSET,  NULL);
-		ret |= register_ioctl32_conversion(SISFB_SET_LOCK,         NULL);
-		ret |= register_ioctl32_conversion(SISFB_GET_VBRSTATUS,    NULL);
-		ret |= register_ioctl32_conversion(SISFB_GET_AUTOMAXIMIZE, NULL);
-		ret |= register_ioctl32_conversion(SISFB_SET_AUTOMAXIMIZE, NULL);
-		if(ret)	printk(KERN_ERR "sisfb: Error registering ioctl32 translations\n");
-		else    ivideo->ioctl32registered = 1;
-		}
-#endif
-
 		printk(KERN_INFO "sisfb: 2D acceleration is %s, y-panning %s\n",
 		     ivideo->sisfb_accel ? "enabled" : "disabled",
 		     ivideo->sisfb_ypan  ?
@@ -5650,33 +5636,10 @@
 	struct fb_info        *sis_fb_info = ivideo->memyselfandi;
 	int                   registered = ivideo->registered;
 
-#ifdef SIS_CONFIG_COMPAT
-	if(ivideo->ioctl32vblankregistered) {
-		if(unregister_ioctl32_conversion(FBIOGET_VBLANK)) {
-			printk(KERN_ERR "sisfb: Error unregistering FBIOGET_VBLANK ioctl32 translation\n");
-		}
-	}
-	if(ivideo->ioctl32registered) {
-		int ret;
-		ret =  unregister_ioctl32_conversion(FBIO_ALLOC);
-		ret |= unregister_ioctl32_conversion(FBIO_FREE);
-		ret |= unregister_ioctl32_conversion(SISFB_GET_INFO_SIZE);
-		ret |= unregister_ioctl32_conversion(SISFB_GET_INFO);
-		ret |= unregister_ioctl32_conversion(SISFB_GET_TVPOSOFFSET);
-		ret |= unregister_ioctl32_conversion(SISFB_SET_TVPOSOFFSET);
-		ret |= unregister_ioctl32_conversion(SISFB_SET_LOCK);
-		ret |= unregister_ioctl32_conversion(SISFB_GET_VBRSTATUS);
-		ret |= unregister_ioctl32_conversion(SISFB_GET_AUTOMAXIMIZE);
-		ret |= unregister_ioctl32_conversion(SISFB_SET_AUTOMAXIMIZE);
-		if(ret)	printk(KERN_ERR "sisfb: Error unregistering ioctl32 translations\n");
-	}
-#endif
-
 	/* Unmap */
 	iounmap(ivideo->video_vbase);
 	iounmap(ivideo->mmio_vbase);
-	if(ivideo->bios_vbase) iounmap(ivideo->bios_vbase);
-	if(ivideo->bios_abase)    vfree(ivideo->bios_abase);
+	if(ivideo->bios_abase) vfree(ivideo->bios_abase);
 
 	/* Release mem regions */
 	release_mem_region(ivideo->video_base, ivideo->video_size);
@@ -5720,15 +5683,15 @@
 	.remove 	= __devexit_p(sisfb_remove)
 };
 
-int __init sisfb_init(void)
+SISINITSTATIC int __init sisfb_init(void)
 {
 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8)
 #ifndef MODULE
-	char *option = NULL;
+	char *options = NULL;
 
-	if (fb_get_options("sisfb", &option))
+	if(fb_get_options("sisfb", &options))
 		return -ENODEV;
-	sisfb_setup(option);
+	sisfb_setup(options);
 #endif
 #endif
 	return(pci_module_init(&sisfb_driver));
diff -Nru a/drivers/video/sis/sis_main.h b/drivers/video/sis/sis_main.h
--- a/drivers/video/sis/sis_main.h	2005-03-01 23:38:54 -08:00
+++ b/drivers/video/sis/sis_main.h	2005-03-01 23:38:54 -08:00
@@ -153,7 +153,7 @@
    now (hoping that nobody is crazy enough to run two
    SiS cards at the same time).
  */
-SIS_HEAP       	sisfb_heap;
+static SIS_HEAP       	sisfb_heap;
 
 #define MD_SIS300 1
 #define MD_SIS315 2
@@ -234,78 +234,82 @@
 	{"960x540x16",   {0x1e,0x1e}, 0x0000, 0x0000,  960,  540, 16, 1, 120, 33,           MD_SIS315},
 	{"960x540x24",   {0x1f,0x1f}, 0x0000, 0x0000,  960,  540, 32, 1, 120, 33,           MD_SIS315},
 	{"960x540x32",   {0x1f,0x1f}, 0x0000, 0x0000,  960,  540, 32, 1, 120, 33,           MD_SIS315},
+	{"960x600x8",    {0x20,0x20}, 0x0000, 0x0000,  960,  600,  8, 1, 120, 37,           MD_SIS315},
+/*60*/	{"960x600x16",   {0x21,0x21}, 0x0000, 0x0000,  960,  600, 16, 1, 120, 37,           MD_SIS315},
+	{"960x600x24",   {0x22,0x22}, 0x0000, 0x0000,  960,  600, 32, 1, 120, 37,           MD_SIS315},
+	{"960x600x32",   {0x22,0x22}, 0x0000, 0x0000,  960,  600, 32, 1, 120, 37,           MD_SIS315},
 	{"1024x576x8",   {0x71,0x71}, 0x0000, 0x0000, 1024,  576,  8, 1, 128, 36, MD_SIS300|MD_SIS315},
-/*60*/	{"1024x576x16",  {0x74,0x74}, 0x0000, 0x0000, 1024,  576, 16, 1, 128, 36, MD_SIS300|MD_SIS315},
+	{"1024x576x16",  {0x74,0x74}, 0x0000, 0x0000, 1024,  576, 16, 1, 128, 36, MD_SIS300|MD_SIS315},
 	{"1024x576x24",  {0x77,0x77}, 0x0000, 0x0000, 1024,  576, 32, 1, 128, 36, MD_SIS300|MD_SIS315},
 	{"1024x576x32",  {0x77,0x77}, 0x0000, 0x0000, 1024,  576, 32, 1, 128, 36, MD_SIS300|MD_SIS315},
 	{"1024x600x8",   {0x20,0x20}, 0x0000, 0x0000, 1024,  600,  8, 1, 128, 37, MD_SIS300          },
 	{"1024x600x16",  {0x21,0x21}, 0x0000, 0x0000, 1024,  600, 16, 1, 128, 37, MD_SIS300          },
 	{"1024x600x24",  {0x22,0x22}, 0x0000, 0x0000, 1024,  600, 32, 1, 128, 37, MD_SIS300          },
-	{"1024x600x32",  {0x22,0x22}, 0x0000, 0x0000, 1024,  600, 32, 1, 128, 37, MD_SIS300          },
+/*70*/	{"1024x600x32",  {0x22,0x22}, 0x0000, 0x0000, 1024,  600, 32, 1, 128, 37, MD_SIS300          },
 	{"1024x768x8",   {0x38,0x38}, 0x0105, 0x0105, 1024,  768,  8, 2, 128, 48, MD_SIS300|MD_SIS315},
 	{"1024x768x16",  {0x4a,0x4a}, 0x0117, 0x0117, 1024,  768, 16, 2, 128, 48, MD_SIS300|MD_SIS315},
 	{"1024x768x24",  {0x64,0x64}, 0x013c, 0x0118, 1024,  768, 32, 2, 128, 48, MD_SIS300|MD_SIS315},
-/*70*/	{"1024x768x32",  {0x64,0x64}, 0x013c, 0x0118, 1024,  768, 32, 2, 128, 48, MD_SIS300|MD_SIS315},
+	{"1024x768x32",  {0x64,0x64}, 0x013c, 0x0118, 1024,  768, 32, 2, 128, 48, MD_SIS300|MD_SIS315},
 	{"1152x768x8",   {0x23,0x23}, 0x0000, 0x0000, 1152,  768,  8, 1, 144, 48, MD_SIS300          },
 	{"1152x768x16",  {0x24,0x24}, 0x0000, 0x0000, 1152,  768, 16, 1, 144, 48, MD_SIS300          },
 	{"1152x768x24",  {0x25,0x25}, 0x0000, 0x0000, 1152,  768, 32, 1, 144, 48, MD_SIS300          },
 	{"1152x768x32",  {0x25,0x25}, 0x0000, 0x0000, 1152,  768, 32, 1, 144, 48, MD_SIS300          },
 	{"1152x864x8",   {0x29,0x29}, 0x0000, 0x0000, 1152,  864,  8, 1, 144, 54, MD_SIS300|MD_SIS315},
-	{"1152x864x16",  {0x2a,0x2a}, 0x0000, 0x0000, 1152,  864, 16, 1, 144, 54, MD_SIS300|MD_SIS315},
+/*80*/	{"1152x864x16",  {0x2a,0x2a}, 0x0000, 0x0000, 1152,  864, 16, 1, 144, 54, MD_SIS300|MD_SIS315},
 	{"1152x864x24",  {0x2b,0x2b}, 0x0000, 0x0000, 1152,  864, 32, 1, 144, 54, MD_SIS300|MD_SIS315},
 	{"1152x864x32",  {0x2b,0x2b}, 0x0000, 0x0000, 1152,  864, 32, 1, 144, 54, MD_SIS300|MD_SIS315},
 	{"1280x720x8",   {0x79,0x79}, 0x0000, 0x0000, 1280,  720,  8, 1, 160, 45, MD_SIS300|MD_SIS315},
-/*80*/	{"1280x720x16",  {0x75,0x75}, 0x0000, 0x0000, 1280,  720, 16, 1, 160, 45, MD_SIS300|MD_SIS315},
+	{"1280x720x16",  {0x75,0x75}, 0x0000, 0x0000, 1280,  720, 16, 1, 160, 45, MD_SIS300|MD_SIS315},
 	{"1280x720x24",  {0x78,0x78}, 0x0000, 0x0000, 1280,  720, 32, 1, 160, 45, MD_SIS300|MD_SIS315},
 	{"1280x720x32",  {0x78,0x78}, 0x0000, 0x0000, 1280,  720, 32, 1, 160, 45, MD_SIS300|MD_SIS315},
 	{"1280x768x8",   {0x55,0x23}, 0x0000, 0x0000, 1280,  768,  8, 1, 160, 48, MD_SIS300|MD_SIS315},
 	{"1280x768x16",  {0x5a,0x24}, 0x0000, 0x0000, 1280,  768, 16, 1, 160, 48, MD_SIS300|MD_SIS315},
 	{"1280x768x24",  {0x5b,0x25}, 0x0000, 0x0000, 1280,  768, 32, 1, 160, 48, MD_SIS300|MD_SIS315},
-	{"1280x768x32",  {0x5b,0x25}, 0x0000, 0x0000, 1280,  768, 32, 1, 160, 48, MD_SIS300|MD_SIS315},
+/*90*/	{"1280x768x32",  {0x5b,0x25}, 0x0000, 0x0000, 1280,  768, 32, 1, 160, 48, MD_SIS300|MD_SIS315},
 	{"1280x800x8",   {0x14,0x14}, 0x0000, 0x0000, 1280,  800,  8, 1, 160, 50,           MD_SIS315},
 	{"1280x800x16",  {0x15,0x15}, 0x0000, 0x0000, 1280,  800, 16, 1, 160, 50,           MD_SIS315},
 	{"1280x800x24",  {0x16,0x16}, 0x0000, 0x0000, 1280,  800, 32, 1, 160, 50,           MD_SIS315},
-/*90*/	{"1280x800x32",  {0x16,0x16}, 0x0000, 0x0000, 1280,  800, 32, 1, 160, 50,           MD_SIS315},
+	{"1280x800x32",  {0x16,0x16}, 0x0000, 0x0000, 1280,  800, 32, 1, 160, 50,           MD_SIS315},
 	{"1280x960x8",   {0x7c,0x7c}, 0x0000, 0x0000, 1280,  960,  8, 1, 160, 60, MD_SIS300|MD_SIS315},
 	{"1280x960x16",  {0x7d,0x7d}, 0x0000, 0x0000, 1280,  960, 16, 1, 160, 60, MD_SIS300|MD_SIS315},
 	{"1280x960x24",  {0x7e,0x7e}, 0x0000, 0x0000, 1280,  960, 32, 1, 160, 60, MD_SIS300|MD_SIS315},
 	{"1280x960x32",  {0x7e,0x7e}, 0x0000, 0x0000, 1280,  960, 32, 1, 160, 60, MD_SIS300|MD_SIS315},
 	{"1280x1024x8",  {0x3a,0x3a}, 0x0107, 0x0107, 1280, 1024,  8, 2, 160, 64, MD_SIS300|MD_SIS315},
-	{"1280x1024x16", {0x4d,0x4d}, 0x011a, 0x011a, 1280, 1024, 16, 2, 160, 64, MD_SIS300|MD_SIS315},
+/*100*/	{"1280x1024x16", {0x4d,0x4d}, 0x011a, 0x011a, 1280, 1024, 16, 2, 160, 64, MD_SIS300|MD_SIS315},
 	{"1280x1024x24", {0x65,0x65}, 0x013d, 0x011b, 1280, 1024, 32, 2, 160, 64, MD_SIS300|MD_SIS315},
 	{"1280x1024x32", {0x65,0x65}, 0x013d, 0x011b, 1280, 1024, 32, 2, 160, 64, MD_SIS300|MD_SIS315},
 	{"1360x768x8",   {0x48,0x48}, 0x0000, 0x0000, 1360,  768,  8, 1, 170, 48, MD_SIS300|MD_SIS315},
-/*100*/	{"1360x768x16",  {0x4b,0x4b}, 0x0000, 0x0000, 1360,  768, 16, 1, 170, 48, MD_SIS300|MD_SIS315},
+	{"1360x768x16",  {0x4b,0x4b}, 0x0000, 0x0000, 1360,  768, 16, 1, 170, 48, MD_SIS300|MD_SIS315},
 	{"1360x768x24",  {0x4e,0x4e}, 0x0000, 0x0000, 1360,  768, 32, 1, 170, 48, MD_SIS300|MD_SIS315},
 	{"1360x768x32",  {0x4e,0x4e}, 0x0000, 0x0000, 1360,  768, 32, 1, 170, 48, MD_SIS300|MD_SIS315},
 	{"1360x1024x8",  {0x67,0x67}, 0x0000, 0x0000, 1360, 1024,  8, 1, 170, 64, MD_SIS300          },
 	{"1360x1024x16", {0x6f,0x6f}, 0x0000, 0x0000, 1360, 1024, 16, 1, 170, 64, MD_SIS300          },
 	{"1360x1024x24", {0x72,0x72}, 0x0000, 0x0000, 1360, 1024, 32, 1, 170, 64, MD_SIS300          },
-	{"1360x1024x32", {0x72,0x72}, 0x0000, 0x0000, 1360, 1024, 32, 1, 170, 64, MD_SIS300          },
+/*110*/	{"1360x1024x32", {0x72,0x72}, 0x0000, 0x0000, 1360, 1024, 32, 1, 170, 64, MD_SIS300          },
 	{"1400x1050x8",  {0x26,0x26}, 0x0000, 0x0000, 1400, 1050,  8, 1, 175, 65,           MD_SIS315},
 	{"1400x1050x16", {0x27,0x27}, 0x0000, 0x0000, 1400, 1050, 16, 1, 175, 65,           MD_SIS315},
 	{"1400x1050x24", {0x28,0x28}, 0x0000, 0x0000, 1400, 1050, 32, 1, 175, 65,           MD_SIS315},
-/*110*/	{"1400x1050x32", {0x28,0x28}, 0x0000, 0x0000, 1400, 1050, 32, 1, 175, 65,           MD_SIS315},
+	{"1400x1050x32", {0x28,0x28}, 0x0000, 0x0000, 1400, 1050, 32, 1, 175, 65,           MD_SIS315},
 	{"1600x1200x8",  {0x3c,0x3c}, 0x0130, 0x011c, 1600, 1200,  8, 1, 200, 75, MD_SIS300|MD_SIS315},
 	{"1600x1200x16", {0x3d,0x3d}, 0x0131, 0x011e, 1600, 1200, 16, 1, 200, 75, MD_SIS300|MD_SIS315},
 	{"1600x1200x24", {0x66,0x66}, 0x013e, 0x011f, 1600, 1200, 32, 1, 200, 75, MD_SIS300|MD_SIS315},
 	{"1600x1200x32", {0x66,0x66}, 0x013e, 0x011f, 1600, 1200, 32, 1, 200, 75, MD_SIS300|MD_SIS315},
 	{"1680x1050x8",  {0x17,0x17}, 0x0000, 0x0000, 1680, 1050,  8, 1, 210, 65,           MD_SIS315},
-	{"1680x1050x16", {0x18,0x18}, 0x0000, 0x0000, 1680, 1050, 16, 1, 210, 65,           MD_SIS315},
+/*120*/	{"1680x1050x16", {0x18,0x18}, 0x0000, 0x0000, 1680, 1050, 16, 1, 210, 65,           MD_SIS315},
 	{"1680x1050x24", {0x19,0x19}, 0x0000, 0x0000, 1680, 1050, 32, 1, 210, 65,           MD_SIS315},
 	{"1680x1050x32", {0x19,0x19}, 0x0000, 0x0000, 1680, 1050, 32, 1, 210, 65,           MD_SIS315},
 	{"1920x1080x8",  {0x2c,0x2c}, 0x0000, 0x0000, 1920, 1080,  8, 1, 240, 67,           MD_SIS315},
-/*120*/	{"1920x1080x16", {0x2d,0x2d}, 0x0000, 0x0000, 1920, 1080, 16, 1, 240, 67,           MD_SIS315},
+	{"1920x1080x16", {0x2d,0x2d}, 0x0000, 0x0000, 1920, 1080, 16, 1, 240, 67,           MD_SIS315},
 	{"1920x1080x24", {0x73,0x73}, 0x0000, 0x0000, 1920, 1080, 32, 1, 240, 67,           MD_SIS315},
 	{"1920x1080x32", {0x73,0x73}, 0x0000, 0x0000, 1920, 1080, 32, 1, 240, 67,           MD_SIS315},
 	{"1920x1440x8",  {0x68,0x68}, 0x013f, 0x0000, 1920, 1440,  8, 1, 240, 75, MD_SIS300|MD_SIS315},
 	{"1920x1440x16", {0x69,0x69}, 0x0140, 0x0000, 1920, 1440, 16, 1, 240, 75, MD_SIS300|MD_SIS315},
 	{"1920x1440x24", {0x6b,0x6b}, 0x0141, 0x0000, 1920, 1440, 32, 1, 240, 75, MD_SIS300|MD_SIS315},
-	{"1920x1440x32", {0x6b,0x6b}, 0x0141, 0x0000, 1920, 1440, 32, 1, 240, 75, MD_SIS300|MD_SIS315},
+/*130*/	{"1920x1440x32", {0x6b,0x6b}, 0x0141, 0x0000, 1920, 1440, 32, 1, 240, 75, MD_SIS300|MD_SIS315},
 	{"2048x1536x8",  {0x6c,0x6c}, 0x0000, 0x0000, 2048, 1536,  8, 1, 256, 96,           MD_SIS315},
 	{"2048x1536x16", {0x6d,0x6d}, 0x0000, 0x0000, 2048, 1536, 16, 1, 256, 96,           MD_SIS315},
 	{"2048x1536x24", {0x6e,0x6e}, 0x0000, 0x0000, 2048, 1536, 32, 1, 256, 96,           MD_SIS315},
-/*130*/	{"2048x1536x32", {0x6e,0x6e}, 0x0000, 0x0000, 2048, 1536, 32, 1, 256, 96,           MD_SIS315},
+	{"2048x1536x32", {0x6e,0x6e}, 0x0000, 0x0000, 2048, 1536, 32, 1, 256, 96,           MD_SIS315},
 	{"\0", {0x00,0x00}, 0, 0, 0, 0, 0, 0, 0}
 };
 
@@ -318,37 +322,37 @@
 } sis_lcd_data[] = {
 	{ LCD_640x480,    640,  480,  23 },
 	{ LCD_800x600,    800,  600,  43 },
-	{ LCD_1024x600,  1024,  600,  63 },
-	{ LCD_1024x768,  1024,  768,  67 },
-	{ LCD_1152x768,  1152,  768,  71 },
-	{ LCD_1152x864,  1152,  864,  75 },
-	{ LCD_1280x720,  1280,  720,  79 },
-	{ LCD_1280x768,  1280,  768,  83 },
-	{ LCD_1280x800,  1280,  800,  87 },
-	{ LCD_1280x960,  1280,  960,  91 },
-	{ LCD_1280x1024, 1280, 1024,  95 },
-	{ LCD_1400x1050, 1400, 1050, 107 },
-	{ LCD_1680x1050, 1680, 1050, 115 },
-	{ LCD_1600x1200, 1600, 1200, 111 },
+	{ LCD_1024x600,  1024,  600,  67 },
+	{ LCD_1024x768,  1024,  768,  71 },
+	{ LCD_1152x768,  1152,  768,  75 },
+	{ LCD_1152x864,  1152,  864,  79 },
+	{ LCD_1280x720,  1280,  720,  83 },
+	{ LCD_1280x768,  1280,  768,  87 },
+	{ LCD_1280x800,  1280,  800,  91 },
+	{ LCD_1280x960,  1280,  960,  95 },
+	{ LCD_1280x1024, 1280, 1024,  99 },
+	{ LCD_1400x1050, 1400, 1050, 111 },
+	{ LCD_1680x1050, 1680, 1050, 119 },
+	{ LCD_1600x1200, 1600, 1200, 115 },
 	{ LCD_640x480_2,  640,  480,  23 },
 	{ LCD_640x480_3,  640,  480,  23 },
 	{ LCD_320x480,    320,  480,   9 },
 };
 
 /* CR36 evaluation */
-const USHORT sis300paneltype[] =
+static const USHORT sis300paneltype[] =
     { LCD_UNKNOWN,   LCD_800x600,   LCD_1024x768,  LCD_1280x1024,
       LCD_1280x960,  LCD_640x480,   LCD_1024x600,  LCD_1152x768,
       LCD_UNKNOWN,   LCD_UNKNOWN,   LCD_UNKNOWN,   LCD_UNKNOWN,
       LCD_UNKNOWN,   LCD_UNKNOWN,   LCD_UNKNOWN,   LCD_UNKNOWN };
 
-const USHORT sis310paneltype[] =
+static const USHORT sis310paneltype[] =
     { LCD_UNKNOWN,   LCD_800x600,   LCD_1024x768,  LCD_1280x1024,
       LCD_640x480,   LCD_1024x600,  LCD_1152x864,  LCD_1280x960,
       LCD_1152x768,  LCD_1400x1050, LCD_1280x768,  LCD_1600x1200,
       LCD_640x480_2, LCD_640x480_3, LCD_UNKNOWN,   LCD_UNKNOWN };
 
-const USHORT sis661paneltype[] =
+static const USHORT sis661paneltype[] =
     { LCD_UNKNOWN,   LCD_800x600,   LCD_1024x768,  LCD_1280x1024,
       LCD_640x480,   LCD_1024x600,  LCD_1152x864,  LCD_1280x960,
       LCD_1152x768,  LCD_1400x1050, LCD_1280x768,  LCD_1600x1200,
@@ -426,13 +430,14 @@
 	{1,  848,  480,  39,  TRUE}, {2,  848,  480,  60,  TRUE},
 	{1,  856,  480,  39,  TRUE}, {2,  856,  480,  60,  TRUE},
 	{1,  960,  540,  60,  TRUE},
+	{1,  960,  600,  60,  TRUE},
 	{1, 1024,  576,  60,  TRUE}, {2, 1024,  576,  75,  TRUE}, {3, 1024,  576,  85,  TRUE},
 	{1, 1024,  600,  60,  TRUE},
 	{1, 1024,  768,  43,  TRUE}, {2, 1024,  768,  60,  TRUE}, {3, 1024,  768,  70, FALSE},
 	{4, 1024,  768,  75, FALSE}, {5, 1024,  768,  85,  TRUE}, {6, 1024,  768, 100,  TRUE},
 	{7, 1024,  768, 120,  TRUE},
 	{1, 1152,  768,  60,  TRUE},
-	{1, 1152,  864,  75,  TRUE}, {2, 1152,  864,  84,  TRUE},
+	{1, 1152,  864,  60,  TRUE}, {1, 1152,  864,  75,  TRUE}, {2, 1152,  864,  84,  TRUE},
 	{1, 1280,  720,  60,  TRUE}, {2, 1280,  720,  75,  TRUE}, {3, 1280,  720,  85,  TRUE},
 	{1, 1280,  768,  60,  TRUE},
 	{1, 1280,  800,  60,  TRUE},
@@ -800,11 +805,11 @@
 
 /* Interface used by the world */
 #ifndef MODULE
-int             sisfb_setup(char *options);
+SISINITSTATIC int sisfb_setup(char *options);
 #endif
 
 /* Interface to the low level console driver */
-int             sisfb_init(void);
+SISINITSTATIC int sisfb_init(void);
 
 
 /* fbdev routines */
@@ -880,7 +885,6 @@
 		      	struct fb_info *info);
 static void     sisfb_pre_setmode(struct sis_video_info *ivideo);
 static void     sisfb_post_setmode(struct sis_video_info *ivideo);
-static void __iomem *sis_find_rom(struct pci_dev *pdev);
 static BOOLEAN  sisfb_CheckVBRetrace(struct sis_video_info *ivideo);
 static BOOLEAN  sisfbcheckvretracecrt2(struct sis_video_info *ivideo);
 static BOOLEAN  sisfbcheckvretracecrt1(struct sis_video_info *ivideo);
@@ -908,7 +912,6 @@
 static void     SiS_SenseCh(struct sis_video_info *ivideo);
 
 /* Routines from init.c/init301.c */
-extern USHORT   SiS_GetModeID(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int Depth, BOOLEAN FSTN);
 extern USHORT   SiS_GetModeID_LCD(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int Depth,
                                   BOOLEAN FSTN, USHORT CustomT, int LCDwith, int LCDheight);
 extern USHORT   SiS_GetModeID_TV(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int Depth);
diff -Nru a/drivers/video/sis/vgatypes.h b/drivers/video/sis/vgatypes.h
--- a/drivers/video/sis/vgatypes.h	2005-03-01 23:38:44 -08:00
+++ b/drivers/video/sis/vgatypes.h	2005-03-01 23:38:44 -08:00
@@ -35,7 +35,7 @@
  * * 3) The name of the author may not be used to endorse or promote products
  * *    derived from this software without specific prior written permission.
  * *
- * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR
+ * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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,
@@ -53,13 +53,9 @@
 #ifndef _VGATYPES_
 #define _VGATYPES_
 
-#ifdef LINUX_XF86
-#include "xf86Version.h"
-#include "xf86Pci.h"
-#endif
-
 #ifdef LINUX_KERNEL  /* We don't want the X driver to depend on kernel source */
 #include <linux/ioctl.h>
+#include <linux/version.h>
 #endif
 
 #ifndef FALSE
@@ -99,15 +95,18 @@
 #endif
 
 #ifndef BOOLEAN
-typedef UCHAR BOOLEAN;
+typedef unsigned char BOOLEAN;
 #endif
 
-#ifndef bool
-typedef UCHAR bool;
-#endif
+#define SISIOMEMTYPE
 
 #ifdef LINUX_KERNEL
 typedef unsigned long SISIOADDRESS;
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8)
+#include <linux/types.h>  /* Need __iomem */
+#undef SISIOMEMTYPE
+#define SISIOMEMTYPE __iomem
+#endif
 #endif
 
 #ifdef LINUX_XF86
@@ -143,55 +142,26 @@
     MAX_SIS_CHIP
 };
 
-#ifdef LINUX_KERNEL
-enum _SIS_LCD_TYPE {
-    LCD_INVALID = 0,
-    LCD_800x600,
-    LCD_1024x768,
-    LCD_1280x1024,
-    LCD_1280x960,
-    LCD_640x480,
-    LCD_1600x1200,
-    LCD_1920x1440,
-    LCD_2048x1536,
-    LCD_320x480,       /* FSTN */
-    LCD_1400x1050,
-    LCD_1152x864,
-    LCD_1152x768,
-    LCD_1280x768,
-    LCD_1024x600,
-    LCD_640x480_2,     /* DSTN */
-    LCD_640x480_3,     /* DSTN */
-    LCD_848x480,
-    LCD_1280x800,
-    LCD_1680x1050,
-    LCD_1280x720,
-    LCD_CUSTOM,
-    LCD_UNKNOWN
-};
-typedef unsigned int SIS_LCD_TYPE;
-#endif
-
 #ifndef SIS_HW_INFO
-
 typedef struct _SIS_HW_INFO  SIS_HW_INFO, *PSIS_HW_INFO;
 
-typedef BOOLEAN (*PSIS_QUERYSPACE)   (PSIS_HW_INFO, ULONG, ULONG, ULONG *);
-
 struct _SIS_HW_INFO
 {
 #ifdef LINUX_XF86
     PCITAG PciTag;		 /* PCI Tag */
 #endif
 
-    UCHAR  *pjVirtualRomBase;    /* ROM image */
+    UCHAR *pjVirtualRomBase;	 /* ROM image */
 
     BOOLEAN UseROM;		 /* Use the ROM image if provided */
 
-    UCHAR  *pjVideoMemoryAddress;/* base virtual memory address */
+#ifdef LINUX_KERNEL
+    UCHAR SISIOMEMTYPE *pjVideoMemoryAddress;
+    				 /* base virtual memory address */
                                  /* of Linear VGA memory */
 
     ULONG  ulVideoMemorySize;    /* size, in bytes, of the memory on the board */
+#endif
 
     SISIOADDRESS ulIOAddress;    /* base I/O address of VGA ports (0x3B0; relocated) */
 
@@ -201,11 +171,6 @@
     UCHAR  jChipRevision;        /* Used to Identify SiS Graphics Chip Revision */
 
     BOOLEAN bIntegratedMMEnabled;/* supporting integration MM enable */
-
-#ifdef LINUX_KERNEL
-    ULONG  ulCRT2LCDType;        /* defined in the data structure type */
-                                 /* "SIS_LCD_TYPE" */
-#endif
 };
 #endif
 
diff -Nru a/drivers/video/sis/vstruct.h b/drivers/video/sis/vstruct.h
--- a/drivers/video/sis/vstruct.h	2005-03-01 23:39:07 -08:00
+++ b/drivers/video/sis/vstruct.h	2005-03-01 23:39:07 -08:00
@@ -35,7 +35,7 @@
  * * 3) The name of the author may not be used to endorse or promote products
  * *    derived from this software without specific prior written permission.
  * *
- * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR
+ * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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,
@@ -50,12 +50,6 @@
  *
  */
 
-#ifdef _INIT_
-#define EXTERN
-#else
-#define EXTERN extern
-#endif /* _INIT_ */
-
 #ifndef _VSTRUCT_
 #define _VSTRUCT_
 
@@ -286,7 +280,7 @@
 	USHORT SiS_IF_DEF_FSTN;
 	USHORT SiS_SysFlags;
 	UCHAR  SiS_VGAINFO;
-#ifndef LINUX_KERNEL
+#ifdef LINUX_XF86
         USHORT SiS_CP1, SiS_CP2, SiS_CP3, SiS_CP4;
 #endif
 	BOOLEAN SiS_UseROM;
@@ -304,6 +298,7 @@
 	BOOLEAN HaveEMILCD;
 	BOOLEAN OverruleEMI;
 	UCHAR  EMI_30,EMI_31,EMI_32,EMI_33;
+	USHORT SiS_EMIOffset;
 	SHORT  PDC, PDCA;
 	UCHAR  SiS_MyCR63;
 	USHORT SiS_CRT1Mode;
@@ -358,7 +353,7 @@
 	USHORT SiS_PanelMin301;
 
 	const SiS_StStruct          *SiS_SModeIDTable;
-	SiS_StandTableStruct        *SiS_StandTable;
+	const SiS_StandTableStruct  *SiS_StandTable;
 	const SiS_ExtStruct         *SiS_EModeIDTable;
 	const SiS_Ext2Struct        *SiS_RefIndex;
 	const SiS_VBModeStruct      *SiS_VBModeIDTable;
@@ -374,7 +369,7 @@
 	const UCHAR                 *pSiS_SoftSetting;
 
 	const DRAM4Type *SiS_SR15; /* pointer : point to array */
-#ifndef LINUX_XF86
+#ifdef LINUX_KERNEL
 	UCHAR *pSiS_SR07;
 	const DRAM4Type *SiS_CR40; /* pointer : point to array */
 	UCHAR *SiS_CR49;
@@ -420,8 +415,8 @@
 	const SiS_LCDDataStruct  *SiS_LCD1280x720Data;
 	const SiS_LCDDataStruct  *SiS_StLCD1280x768_2Data;
 	const SiS_LCDDataStruct  *SiS_ExtLCD1280x768_2Data;
-	const SiS_LCDDataStruct  *SiS_LCD1280x768_3Data;
 	const SiS_LCDDataStruct  *SiS_LCD1280x800Data;
+	const SiS_LCDDataStruct  *SiS_LCD1280x800_2Data;
 	const SiS_LCDDataStruct  *SiS_LCD1280x960Data;
 	const SiS_LCDDataStruct  *SiS_ExtLCD1280x1024Data;
 	const SiS_LCDDataStruct  *SiS_St2LCD1280x1024Data;
@@ -663,6 +658,8 @@
 	BOOLEAN CP_HaveCustomData;
 	int     CP_PreferredX, CP_PreferredY, CP_PreferredIndex;
 	int	CP_MaxX, CP_MaxY, CP_MaxClock;
+	UCHAR   CP_PrefSR2B, CP_PrefSR2C;
+	USHORT  CP_PrefClock;
 	BOOLEAN CP_Supports64048075;
 	int     CP_HDisplay[7], CP_VDisplay[7];	/* For Custom LCD panel dimensions */
     	int     CP_HTotal[7], CP_VTotal[7];
diff -Nru a/drivers/video/sstfb.c b/drivers/video/sstfb.c
--- a/drivers/video/sstfb.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/video/sstfb.c	2005-03-01 23:39:07 -08:00
@@ -1706,14 +1706,14 @@
 MODULE_DESCRIPTION("FBDev driver for 3dfx Voodoo Graphics and Voodoo2 based video boards");
 MODULE_LICENSE("GPL");
 
-MODULE_PARM(mem, "i");
+module_param(mem, int, 0);
 MODULE_PARM_DESC(mem, "Size of frame buffer memory in MB (1, 2, 4 MB, default=autodetect)");
-MODULE_PARM(vgapass, "i");
+module_param(vgapass, bool, 0);
 MODULE_PARM_DESC(vgapass, "Enable VGA PassThrough mode (0 or 1) (default=0)");
-MODULE_PARM(clipping , "i");
+module_param(clipping, bool, 0);
 MODULE_PARM_DESC(clipping, "Enable clipping (slower, safer) (0 or 1) (default=1)");
-MODULE_PARM(gfxclk , "i");
+module_param(gfxclk, int, 0);
 MODULE_PARM_DESC(gfxclk, "Force graphic chip frequency in MHz. DANGEROUS. (default=auto)");
-MODULE_PARM(slowpci, "i");
+module_param(slowpci, bool, 0);
 MODULE_PARM_DESC(slowpci, "Uses slow PCI settings (0 or 1) (default=0)");
 
diff -Nru a/drivers/video/tdfxfb.c b/drivers/video/tdfxfb.c
--- a/drivers/video/tdfxfb.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/video/tdfxfb.c	2005-03-01 23:38:54 -08:00
@@ -210,41 +210,21 @@
 
 #ifdef VGA_REG_IO 
 static inline  u8 vga_inb(struct tdfx_par *par, u32 reg) { return inb(reg); }
-static inline u16 vga_inw(struct tdfx_par *par, u32 reg) { return inw(reg); }
-static inline u16 vga_inl(struct tdfx_par *par, u32 reg) { return inl(reg); }
 
 static inline void vga_outb(struct tdfx_par *par, u32 reg,  u8 val) { outb(val, reg); }
-static inline void vga_outw(struct tdfx_par *par, u32 reg, u16 val) { outw(val, reg); }
-static inline void vga_outl(struct tdfx_par *par, u32 reg, u32 val) { outl(val, reg); }
 #else
 static inline  u8 vga_inb(struct tdfx_par *par, u32 reg) { 
 	return inb(par->iobase + reg - 0x300); 
 }
-static inline u16 vga_inw(struct tdfx_par *par, u32 reg) { 
-	return inw(par->iobase + reg - 0x300); 
-}
-static inline u16 vga_inl(struct tdfx_par *par, u32 reg) { 
-	return inl(par->iobase + reg - 0x300); 
-}
 static inline void vga_outb(struct tdfx_par *par, u32 reg,  u8 val) { 
 	outb(val, par->iobase + reg - 0x300); 
 }
-static inline void vga_outw(struct tdfx_par *par, u32 reg, u16 val) { 
-	outw(val, par->iobase + reg - 0x300); 
-}
-static inline void vga_outl(struct tdfx_par *par, u32 reg, u32 val) { 
-	outl(val, par->iobase + reg - 0x300); 
-}
 #endif
 
 static inline void gra_outb(struct tdfx_par *par, u32 idx, u8 val) {
 	vga_outb(par, GRA_I, idx); vga_outb(par, GRA_D, val);
 }
 
-static inline u8 gra_inb(struct tdfx_par *par, u32 idx) {
-	vga_outb(par, GRA_I, idx); return vga_inb(par, GRA_D);
-}
-
 static inline void seq_outb(struct tdfx_par *par, u32 idx, u8 val) {
 	vga_outb(par, SEQ_I, idx); vga_outb(par, SEQ_D, val);
 }
@@ -270,15 +250,6 @@
 	vga_outb(par, ATT_IW, val);
 }
 
-static inline u8 att_inb(struct tdfx_par *par, u32 idx) 
-{
-	unsigned char tmp;
-
-	tmp = vga_inb(par, IS1_R);
-	vga_outb(par, ATT_IW, idx);
-	return vga_inb(par, ATT_IW);
-}
-
 static inline void vga_disable_video(struct tdfx_par *par)
 {
 	unsigned char s;
@@ -297,12 +268,6 @@
 	seq_outb(par, 0x00, 0x01);
 	seq_outb(par, 0x01, s);
 	seq_outb(par, 0x00, 0x03);
-}
-
-static inline void vga_disable_palette(struct tdfx_par *par)
-{
-	vga_inb(par, IS1_R);
-	vga_outb(par, ATT_IW, 0x00);
 }
 
 static inline void vga_enable_palette(struct tdfx_par *par)
diff -Nru a/drivers/video/tridentfb.c b/drivers/video/tridentfb.c
--- a/drivers/video/tridentfb.c	2005-03-01 23:38:57 -08:00
+++ b/drivers/video/tridentfb.c	2005-03-01 23:38:57 -08:00
@@ -76,16 +76,16 @@
 static int nativex;
 
 
-MODULE_PARM(mode,"s");
-MODULE_PARM(bpp,"i");
-MODULE_PARM(center,"i");
-MODULE_PARM(stretch,"i");
-MODULE_PARM(noaccel,"i");
-MODULE_PARM(memsize,"i");
-MODULE_PARM(memdiff,"i");
-MODULE_PARM(nativex,"i");
-MODULE_PARM(fp,"i");
-MODULE_PARM(crt,"i");
+module_param(mode, charp, 0);
+module_param(bpp, int, 0);
+module_param(center, int, 0);
+module_param(stretch, int, 0);
+module_param(noaccel, int, 0);
+module_param(memsize, int, 0);
+module_param(memdiff, int, 0);
+module_param(nativex, int, 0);
+module_param(fp, int, 0);
+module_param(crt, int, 0);
 
 
 static int chip3D;
@@ -521,13 +521,6 @@
 	readb(((struct tridentfb_par *)fb_info.par)->io_virt + CRT + 0x0A);	//flip-flop to index
 	t_outb(reg, 0x3C0);
 	t_outb(val, 0x3C0);
-}
-
-static inline unsigned char readAttr(int reg)
-{
-	readb(((struct tridentfb_par *)fb_info.par)->io_virt + CRT + 0x0A);	//flip-flop to index
-	t_outb(reg, 0x3C0);
-	return t_inb(0x3C1);
 }
 
 static inline void write3CE(int reg, unsigned char val)
diff -Nru a/drivers/video/tx3912fb.c b/drivers/video/tx3912fb.c
--- a/drivers/video/tx3912fb.c	2005-03-01 23:38:59 -08:00
+++ b/drivers/video/tx3912fb.c	2005-03-01 23:38:59 -08:00
@@ -10,7 +10,6 @@
  *
  *  Framebuffer for LCD controller in TMPR3912/05 and PR31700 processors
  */
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
@@ -35,11 +34,7 @@
 
 static struct fb_fix_screeninfo tx3912fb_fix __initdata = {
 	.id =		"tx3912fb",
-#ifdef CONFIG_NINO_16MB
-	.smem_len =	(240 * 320),
-#else
 	.smem_len =	((240 * 320)/2),
-#endif
 	.type =		FB_TYPE_PACKED_PIXELS,
 	.visual =	FB_VISUAL_TRUECOLOR, 
 	.xpanstep =	1,
@@ -53,17 +48,10 @@
 	.yres =		320,
 	.xres_virtual =	240,
 	.yres_virtual =	320,
-#ifdef CONFIG_NINO_16MB
-	.bits_per_pixel =8,
-	.red =		{ 5, 3, 0 },	/* RGB 332 */
-	.green =	{ 2, 3, 0 },
-	.blue =		{ 0, 2, 0 },
-#else
 	.bits_per_pixel =4,
 	.red =		{ 0, 4, 0 },	/* ??? */
 	.green =	{ 0, 4, 0 },
 	.blue =		{ 0, 4, 0 },
-#endif
 	.activate =	FB_ACTIVATE_NOW,
 	.width =	-1,
 	.height =	-1,
diff -Nru a/drivers/video/vesafb.c b/drivers/video/vesafb.c
--- a/drivers/video/vesafb.c	2005-03-01 23:38:52 -08:00
+++ b/drivers/video/vesafb.c	2005-03-01 23:38:52 -08:00
@@ -229,7 +229,7 @@
 	unsigned int size_total;
 
 	if (screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB)
-		return -ENXIO;
+		return -ENODEV;
 
 	vesafb_fix.smem_start = screen_info.lfb_base;
 	vesafb_defined.bits_per_pixel = screen_info.lfb_depth;
@@ -407,7 +407,7 @@
 		(ypan) ? FBINFO_HWACCEL_YPAN : 0;
 
 	if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {
-		err = -ENXIO;
+		err = -ENOMEM;
 		goto err;
 	}
 	if (register_framebuffer(info)<0) {
diff -Nru a/drivers/video/vfb.c b/drivers/video/vfb.c
--- a/drivers/video/vfb.c	2005-03-01 23:38:43 -08:00
+++ b/drivers/video/vfb.c	2005-03-01 23:38:43 -08:00
@@ -35,7 +35,7 @@
 
 static void *videomemory;
 static u_long videomemorysize = VIDEOMEMSIZE;
-MODULE_PARM(videomemorysize, "l");
+module_param(videomemorysize, ulong, 0);
 
 static struct fb_var_screeninfo vfb_default __initdata = {
 	.xres =		640,
@@ -70,7 +70,7 @@
 };
 
 static int vfb_enable __initdata = 0;	/* disabled by default */
-MODULE_PARM(vfb_enable, "i");
+module_param(vfb_enable, bool, 0);
 
     /*
      *  Interface used by the world
diff -Nru a/drivers/video/vga16fb.c b/drivers/video/vga16fb.c
--- a/drivers/video/vga16fb.c	2005-03-01 23:38:54 -08:00
+++ b/drivers/video/vga16fb.c	2005-03-01 23:38:54 -08:00
@@ -91,8 +91,8 @@
 	.pixclock	= 39721,
 	.left_margin	= 48,
 	.right_margin	= 16,
-	.upper_margin	= 39,
-	.lower_margin	= 8,
+	.upper_margin	= 33,
+	.lower_margin	= 10,
 	.hsync_len 	= 96,
 	.vsync_len	= 2,
 	.vmode		= FB_VMODE_NONINTERLACED,
diff -Nru a/drivers/video/w100fb.c b/drivers/video/w100fb.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/video/w100fb.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,1864 @@
+/*
+ * linux/drivers/video/w100fb.c
+ *
+ * Frame Buffer Device for ATI Imageon w100 (Wallaby)
+ *
+ * Copyright (C) 2002, ATI Corp.
+ * Copyright (C) 2004-2005 Richard Purdie
+ *
+ * Rewritten for 2.6 by Richard Purdie <rpurdie@rpsys.net>
+ *
+ * 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/fb.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/device.h>
+#include <linux/string.h>
+#include <linux/proc_fs.h>
+#include <linux/vmalloc.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <video/w100fb.h>
+#include "w100fb.h"
+
+/*
+ * Prototypes
+ */
+static void w100fb_save_buffer(void);
+static void w100fb_clear_buffer(void);
+static void w100fb_restore_buffer(void);
+static void w100fb_clear_screen(u32 mode, long int offset);
+static void w100_resume(void);
+static void w100_suspend(u32 mode);
+static void w100_init_qvga_rotation(u16 deg);
+static void w100_init_vga_rotation(u16 deg);
+static void w100_vsync(void);
+static void w100_init_sharp_lcd(u32 mode);
+static void w100_pwm_setup(void);
+static void w100_InitExtMem(u32 mode);
+static void w100_hw_init(void);
+static u16 w100_set_fastsysclk(u16 Freq);
+
+static void lcdtg_hw_init(u32 mode);
+static void lcdtg_lcd_change(u32 mode);
+static void lcdtg_resume(void);
+static void lcdtg_suspend(void);
+
+
+/* Register offsets & lengths */
+#define REMAPPED_FB_LEN   0x15ffff
+
+#define BITS_PER_PIXEL    16
+
+/* Pseudo palette size */
+#define MAX_PALETTES      16
+
+/* for resolution change */
+#define LCD_MODE_INIT (-1)
+#define LCD_MODE_480    0
+#define LCD_MODE_320    1
+#define LCD_MODE_240    2
+#define LCD_MODE_640    3
+
+#define LCD_SHARP_QVGA 0
+#define LCD_SHARP_VGA  1
+
+#define LCD_MODE_PORTRAIT	0
+#define LCD_MODE_LANDSCAPE	1
+
+#define W100_SUSPEND_EXTMEM 0
+#define W100_SUSPEND_ALL    1
+
+/* General frame buffer data structures */
+struct w100fb_par {
+	u32 xres;
+	u32 yres;
+	int fastsysclk_mode;
+	int lcdMode;
+	int rotation_flag;
+	int blanking_flag;
+	int comadj;
+	int phadadj;
+};
+
+static struct w100fb_par *current_par;
+
+static u16 *gSaveImagePtr = NULL;
+
+/* Remapped addresses for base cfg, memmapped regs and the frame buffer itself */
+static void *remapped_base;
+static void *remapped_regs;
+static void *remapped_fbuf;
+
+/* External Function */
+static void(*w100fb_ssp_send)(u8 adrs, u8 data);
+
+/*
+ * Sysfs functions
+ */
+
+static ssize_t rotation_show(struct device *dev, char *buf)
+{
+	struct fb_info *info = dev_get_drvdata(dev);
+	struct w100fb_par *par=info->par;
+
+	return sprintf(buf, "%d\n",par->rotation_flag);
+}
+
+static ssize_t rotation_store(struct device *dev, const char *buf, size_t count)
+{
+	unsigned int rotate;
+	struct fb_info *info = dev_get_drvdata(dev);
+	struct w100fb_par *par=info->par;
+
+	rotate = simple_strtoul(buf, NULL, 10);
+
+	if (rotate > 0) par->rotation_flag = 1;
+	else par->rotation_flag = 0;
+
+	if (par->lcdMode == LCD_MODE_320)
+		w100_init_qvga_rotation(par->rotation_flag ? 270 : 90);
+	else if (par->lcdMode == LCD_MODE_240)
+		w100_init_qvga_rotation(par->rotation_flag ? 180 : 0);
+	else if (par->lcdMode == LCD_MODE_640)
+		w100_init_vga_rotation(par->rotation_flag ? 270 : 90);
+	else if (par->lcdMode == LCD_MODE_480)
+		w100_init_vga_rotation(par->rotation_flag ? 180 : 0);
+
+	return count;
+}
+
+static DEVICE_ATTR(rotation, 0644, rotation_show, rotation_store);
+
+static ssize_t w100fb_reg_read(struct device *dev, const char *buf, size_t count)
+{
+	unsigned long param;
+	unsigned long regs;
+	regs = simple_strtoul(buf, NULL, 16);
+	param = readl(remapped_regs + regs);
+	printk("Read Register 0x%08lX: 0x%08lX\n", regs, param);
+	return count;
+}
+
+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)
+{
+	unsigned long regs;
+	unsigned long param;
+	sscanf(buf, "%lx %lx", &regs, &param);
+
+	if (regs <= 0x2000) {
+		printk("Write Register 0x%08lX: 0x%08lX\n", regs, param);
+		writel(param, remapped_regs + regs);
+	}
+
+	return count;
+}
+
+static DEVICE_ATTR(reg_write, 0200, NULL, w100fb_reg_write);
+
+
+static ssize_t fastsysclk_show(struct device *dev, char *buf)
+{
+	struct fb_info *info = dev_get_drvdata(dev);
+	struct w100fb_par *par=info->par;
+
+	return sprintf(buf, "%d\n",par->fastsysclk_mode);
+}
+
+static ssize_t fastsysclk_store(struct device *dev, const char *buf, size_t count)
+{
+	int param;
+	struct fb_info *info = dev_get_drvdata(dev);
+	struct w100fb_par *par=info->par;
+
+	param = simple_strtoul(buf, NULL, 10);
+
+	if (param == 75) {
+		printk("Set fastsysclk %d\n", param);
+		par->fastsysclk_mode = param;
+		w100_set_fastsysclk(par->fastsysclk_mode);
+	} else if (param == 100) {
+		printk("Set fastsysclk %d\n", param);
+		par->fastsysclk_mode = param;
+		w100_set_fastsysclk(par->fastsysclk_mode);
+	}
+	return count;
+}
+
+static DEVICE_ATTR(fastsysclk, 0644, fastsysclk_show, fastsysclk_store);
+
+/*
+ * The touchscreen on this device needs certain information
+ * from the video driver to function correctly. We export it here.
+ */
+int w100fb_get_xres(void) {
+	return current_par->xres;
+}
+
+int w100fb_get_blanking(void) {
+	return current_par->blanking_flag;
+}
+
+int w100fb_get_fastsysclk(void) {
+	return current_par->fastsysclk_mode;
+}
+EXPORT_SYMBOL(w100fb_get_xres);
+EXPORT_SYMBOL(w100fb_get_blanking);
+EXPORT_SYMBOL(w100fb_get_fastsysclk);
+
+
+/*
+ * Set a palette value from rgb components
+ */
+static int w100fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+			     u_int trans, struct fb_info *info)
+{
+	unsigned int val;
+	int ret = 1;
+
+	/*
+	 * If greyscale is true, then we convert the RGB value
+	 * to greyscale no matter what visual we are using.
+	 */
+	if (info->var.grayscale)
+		red = green = blue = (19595 * red + 38470 * green + 7471 * blue) >> 16;
+
+	/*
+	 * 16-bit True Colour.  We encode the RGB value
+	 * according to the RGB bitfield information.
+	 */
+	if (regno < MAX_PALETTES) {
+
+		u32 *pal = info->pseudo_palette;
+
+		val = (red & 0xf800) | ((green & 0xfc00) >> 5) | ((blue & 0xf800) >> 11);
+		pal[regno] = val;
+		ret = 0;
+	}
+	return ret;
+}
+
+
+/*
+ * Blank the display based on value in blank_mode
+ */
+static int w100fb_blank(int blank_mode, struct fb_info *info)
+{
+	struct w100fb_par *par;
+	par=info->par;
+
+	switch(blank_mode) {
+
+ 	case FB_BLANK_NORMAL: /* Normal blanking */
+	case FB_BLANK_VSYNC_SUSPEND: /* VESA blank (vsync off) */
+	case FB_BLANK_HSYNC_SUSPEND: /* VESA blank (hsync off) */
+ 	case FB_BLANK_POWERDOWN: /* Poweroff */
+  		if (par->blanking_flag == 0) {
+			w100fb_save_buffer();
+			lcdtg_suspend();
+			par->blanking_flag = 1;
+  		}
+  		break;
+
+ 	case FB_BLANK_UNBLANK: /* Unblanking */
+  		if (par->blanking_flag != 0) {
+			w100fb_restore_buffer();
+			lcdtg_resume();
+			par->blanking_flag = 0;
+  		}
+  		break;
+ 	}
+	return 0;
+}
+
+/*
+ *  Change the resolution by calling the appropriate hardware functions
+ */
+static void w100fb_changeres(int rotate_mode, u32 mode)
+{
+	u16 rotation=0;
+
+	switch(rotate_mode) {
+	case LCD_MODE_LANDSCAPE:
+		rotation=(current_par->rotation_flag ? 270 : 90);
+		break;
+	case LCD_MODE_PORTRAIT:
+		rotation=(current_par->rotation_flag ? 180 : 0);
+		break;
+	}
+
+	w100_pwm_setup();
+	switch(mode) {
+	case LCD_SHARP_QVGA:
+		w100_vsync();
+		w100_suspend(W100_SUSPEND_EXTMEM);
+		w100_init_sharp_lcd(LCD_SHARP_QVGA);
+		w100_init_qvga_rotation(rotation);
+		w100_InitExtMem(LCD_SHARP_QVGA);
+		w100fb_clear_screen(LCD_SHARP_QVGA, 0);
+		lcdtg_lcd_change(LCD_SHARP_QVGA);
+		break;
+	case LCD_SHARP_VGA:
+		w100fb_clear_screen(LCD_SHARP_QVGA, 0);
+		writel(0xBFFFA000, remapped_regs + mmMC_EXT_MEM_LOCATION);
+		w100_InitExtMem(LCD_SHARP_VGA);
+		w100fb_clear_screen(LCD_SHARP_VGA, 0x200000);
+		w100_vsync();
+		w100_init_sharp_lcd(LCD_SHARP_VGA);
+		if (rotation != 0)
+			w100_init_vga_rotation(rotation);
+		lcdtg_lcd_change(LCD_SHARP_VGA);
+		break;
+	}
+}
+
+/*
+ * Set up the display for the fb subsystem
+ */
+static void w100fb_activate_var(struct fb_info *info)
+{
+	u32 temp32;
+	struct w100fb_par *par=info->par;
+	struct fb_var_screeninfo *var = &info->var;
+
+	/* Set the hardware to 565 */
+	temp32 = readl(remapped_regs + mmDISP_DEBUG2);
+	temp32 &= 0xff7fffff;
+	temp32 |= 0x00800000;
+	writel(temp32, remapped_regs + mmDISP_DEBUG2);
+
+	if (par->lcdMode == LCD_MODE_INIT) {
+		w100_init_sharp_lcd(LCD_SHARP_VGA);
+		w100_init_vga_rotation(par->rotation_flag ? 270 : 90);
+		par->lcdMode = LCD_MODE_640;
+		lcdtg_hw_init(LCD_SHARP_VGA);
+	} else if (var->xres == 320 && var->yres == 240) {
+		if (par->lcdMode != LCD_MODE_320) {
+			w100fb_changeres(LCD_MODE_LANDSCAPE, LCD_SHARP_QVGA);
+			par->lcdMode = LCD_MODE_320;
+		}
+	} else if (var->xres == 240 && var->yres == 320) {
+		if (par->lcdMode != LCD_MODE_240) {
+			w100fb_changeres(LCD_MODE_PORTRAIT, LCD_SHARP_QVGA);
+			par->lcdMode = LCD_MODE_240;
+		}
+	} else if (var->xres == 640 && var->yres == 480) {
+		if (par->lcdMode != LCD_MODE_640) {
+			w100fb_changeres(LCD_MODE_LANDSCAPE, LCD_SHARP_VGA);
+			par->lcdMode = LCD_MODE_640;
+		}
+	} else if (var->xres == 480 && var->yres == 640) {
+		if (par->lcdMode != LCD_MODE_480) {
+			w100fb_changeres(LCD_MODE_PORTRAIT, LCD_SHARP_VGA);
+			par->lcdMode = LCD_MODE_480;
+		}
+	} else printk(KERN_ERR "W100FB: Resolution error!\n");
+}
+
+
+/*
+ *  w100fb_check_var():
+ *  Get the video params out of 'var'. If a value doesn't fit, round it up,
+ *  if it's too big, return -EINVAL.
+ *
+ */
+static int w100fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+	if (var->xres < var->yres) { /* Portrait mode */
+		if ((var->xres > 480) || (var->yres > 640)) {
+			return -EINVAL;
+		} else if ((var->xres > 240) || (var->yres > 320)) {
+			var->xres = 480;
+			var->yres = 640;
+		} else {
+			var->xres = 240;
+			var->yres = 320;
+		}
+	} else { /* Landscape mode */
+		if ((var->xres > 640) || (var->yres > 480)) {
+			return -EINVAL;
+		} else if ((var->xres > 320) || (var->yres > 240)) {
+			var->xres = 640;
+			var->yres = 480;
+		} else {
+			var->xres = 320;
+			var->yres = 240;
+		}
+	}
+
+	var->xres_virtual = max(var->xres_virtual, var->xres);
+	var->yres_virtual = max(var->yres_virtual, var->yres);
+
+	if (var->bits_per_pixel > BITS_PER_PIXEL)
+		return -EINVAL;
+	else
+		var->bits_per_pixel = BITS_PER_PIXEL;
+
+	var->red.offset = 11;
+	var->red.length = 5;
+	var->green.offset = 5;
+	var->green.length = 6;
+	var->blue.offset = 0;
+	var->blue.length = 5;
+	var->transp.offset = var->transp.length = 0;
+
+	var->nonstd = 0;
+
+	var->height = -1;
+	var->width = -1;
+	var->vmode = FB_VMODE_NONINTERLACED;
+
+	var->sync = 0;
+	var->pixclock = 0x04;	/* 171521; */
+
+	return 0;
+}
+
+
+/*
+ * w100fb_set_par():
+ *	Set the user defined part of the display for the specified console
+ *  by looking at the values in info.var
+ */
+static int w100fb_set_par(struct fb_info *info)
+{
+	struct w100fb_par *par=info->par;
+
+	par->xres = info->var.xres;
+	par->yres = info->var.yres;
+
+	info->fix.visual = FB_VISUAL_TRUECOLOR;
+
+	info->fix.ypanstep = 0;
+	info->fix.ywrapstep = 0;
+
+	if (par->blanking_flag)
+		w100fb_clear_buffer();
+
+	w100fb_activate_var(info);
+
+	if (par->lcdMode == LCD_MODE_480) {
+		info->fix.line_length = (480 * BITS_PER_PIXEL) / 8;
+		info->fix.smem_len = 0x200000;
+	} else if (par->lcdMode == LCD_MODE_320) {
+		info->fix.line_length = (320 * BITS_PER_PIXEL) / 8;
+		info->fix.smem_len = 0x60000;
+	} else if (par->lcdMode == LCD_MODE_240) {
+		info->fix.line_length = (240 * BITS_PER_PIXEL) / 8;
+		info->fix.smem_len = 0x60000;
+	} else if (par->lcdMode == LCD_MODE_INIT || par->lcdMode == LCD_MODE_640) {
+		info->fix.line_length = (640 * BITS_PER_PIXEL) / 8;
+		info->fix.smem_len = 0x200000;
+	}
+
+	return 0;
+}
+
+
+/*
+ *      Frame buffer operations
+ */
+static struct fb_ops w100fb_ops = {
+	.owner = THIS_MODULE,
+	.fb_check_var = w100fb_check_var,
+	.fb_set_par = w100fb_set_par,
+	.fb_setcolreg = w100fb_setcolreg,
+	.fb_blank = w100fb_blank,
+	.fb_fillrect = cfb_fillrect,
+	.fb_copyarea = cfb_copyarea,
+	.fb_imageblit = cfb_imageblit,
+	.fb_cursor = soft_cursor,
+};
+
+
+static void w100fb_clear_screen(u32 mode, long int offset)
+{
+	int i, numPix = 0;
+
+	if (mode == LCD_SHARP_VGA)
+		numPix = 640 * 480;
+	else if (mode == LCD_SHARP_QVGA)
+		numPix = 320 * 240;
+
+	for (i = 0; i < numPix; i++)
+		writew(0xffff, remapped_fbuf + offset + (2*i));
+}
+
+
+static void w100fb_save_buffer(void)
+{
+	int i;
+
+	if (gSaveImagePtr != NULL) {
+		vfree(gSaveImagePtr);
+		gSaveImagePtr = NULL;
+	}
+	gSaveImagePtr = vmalloc(current_par->xres * current_par->yres * BITS_PER_PIXEL / 8);
+	if (gSaveImagePtr != NULL) {
+		for (i = 0; i < (current_par->xres * current_par->yres); i++)
+			*(gSaveImagePtr + i) = readw(remapped_fbuf + (2*i));
+	} else {
+		printk(KERN_WARNING "can't alloc pre-off image buffer\n");
+	}
+}
+
+
+static void w100fb_restore_buffer(void)
+{
+	int i;
+
+	if (gSaveImagePtr != NULL) {
+		for (i = 0; i < (current_par->xres * current_par->yres); i++) {
+				writew(*(gSaveImagePtr + i),remapped_fbuf + (2*i));
+			}
+		vfree(gSaveImagePtr);
+		gSaveImagePtr = NULL;
+	}
+}
+
+static void w100fb_clear_buffer(void)
+{
+	if (gSaveImagePtr != NULL) {
+		vfree(gSaveImagePtr);
+		gSaveImagePtr = NULL;
+	}
+}
+
+
+#ifdef CONFIG_PM
+static int w100fb_suspend(struct device *dev, u32 state, u32 level)
+{
+	if (level == SUSPEND_POWER_DOWN) {
+		struct fb_info *info = dev_get_drvdata(dev);
+		struct w100fb_par *par=info->par;
+
+		w100fb_save_buffer();
+		lcdtg_suspend();
+		w100_suspend(W100_SUSPEND_ALL);
+		par->blanking_flag = 1;
+	}
+	return 0;
+}
+
+static int w100fb_resume(struct device *dev, u32 level)
+{
+	if (level == RESUME_POWER_ON) {
+		struct fb_info *info = dev_get_drvdata(dev);
+		struct w100fb_par *par=info->par;
+
+		w100_resume();
+		w100fb_restore_buffer();
+		lcdtg_resume();
+		par->blanking_flag = 0;
+	}
+	return 0;
+}
+#else
+#define w100fb_suspend	NULL
+#define w100fb_resume	NULL
+#endif
+
+
+int __init w100fb_probe(struct device *dev)
+{
+	struct w100fb_mach_info *inf;
+	struct fb_info *info;
+	struct w100fb_par *par;
+	struct platform_device *pdev = to_platform_device(dev);
+	struct resource *mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+	if (!mem)
+		return -EINVAL;
+
+	/* remap the areas we're going to use */
+	remapped_base = ioremap_nocache(mem->start+W100_CFG_BASE, W100_CFG_LEN);
+	if (remapped_base == NULL)
+		return -EIO;
+
+	remapped_regs = ioremap_nocache(mem->start+W100_REG_BASE, W100_REG_LEN);
+	if (remapped_regs == NULL) {
+		iounmap(remapped_base);
+		return -EIO;
+	}
+
+	remapped_fbuf = ioremap_nocache(mem->start+MEM_EXT_BASE_VALUE, REMAPPED_FB_LEN);
+	if (remapped_fbuf == NULL) {
+		iounmap(remapped_base);
+		iounmap(remapped_regs);
+		return -EIO;
+	}
+
+	info=framebuffer_alloc(sizeof(struct w100fb_par), dev);
+	if (!info) {
+		iounmap(remapped_base);
+		iounmap(remapped_regs);
+		iounmap(remapped_fbuf);
+		return -ENOMEM;
+	}
+
+	info->device=dev;
+	par = info->par;
+	current_par=info->par;
+	dev_set_drvdata(dev, info);
+
+	inf = dev->platform_data;
+	par->phadadj = inf->phadadj;
+	par->comadj = inf->comadj;
+	par->fastsysclk_mode = 75;
+	par->lcdMode = LCD_MODE_INIT;
+	par->rotation_flag=0;
+	par->blanking_flag=0;
+	w100fb_ssp_send = inf->w100fb_ssp_send;
+
+	w100_hw_init();
+	w100_pwm_setup();
+
+	info->pseudo_palette = kmalloc(sizeof (u32) * MAX_PALETTES, GFP_KERNEL);
+	if (!info->pseudo_palette) {
+		iounmap(remapped_base);
+		iounmap(remapped_regs);
+		iounmap(remapped_fbuf);
+		return -ENOMEM;
+	}
+
+	info->fbops = &w100fb_ops;
+	info->flags = FBINFO_DEFAULT;
+	info->node = -1;
+	info->screen_base = remapped_fbuf;
+	info->screen_size = REMAPPED_FB_LEN;
+
+	info->var.xres = 640;
+	info->var.xres_virtual = info->var.xres;
+	info->var.yres = 480;
+	info->var.yres_virtual = info->var.yres;
+	info->var.pixclock = 0x04;	/* 171521; */
+	info->var.sync = 0;
+	info->var.grayscale = 0;
+	info->var.xoffset = info->var.yoffset = 0;
+	info->var.accel_flags = 0;
+	info->var.activate = FB_ACTIVATE_NOW;
+
+	strcpy(info->fix.id, "w100fb");
+	info->fix.type = FB_TYPE_PACKED_PIXELS;
+	info->fix.type_aux = 0;
+	info->fix.accel = FB_ACCEL_NONE;
+	info->fix.smem_start = mem->start+MEM_EXT_BASE_VALUE;
+	info->fix.mmio_start = mem->start+W100_REG_BASE;
+	info->fix.mmio_len = W100_REG_LEN;
+
+	w100fb_check_var(&info->var, info);
+	w100fb_set_par(info);
+
+	if (register_framebuffer(info) < 0) {
+		kfree(info->pseudo_palette);
+		iounmap(remapped_base);
+		iounmap(remapped_regs);
+		iounmap(remapped_fbuf);
+		return -EINVAL;
+	}
+
+	device_create_file(dev, &dev_attr_fastsysclk);
+	device_create_file(dev, &dev_attr_reg_read);
+	device_create_file(dev, &dev_attr_reg_write);
+	device_create_file(dev, &dev_attr_rotation);
+
+	printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node, info->fix.id);
+	return 0;
+}
+
+
+static int w100fb_remove(struct device *dev)
+{
+	struct fb_info *info = dev_get_drvdata(dev);
+
+	device_remove_file(dev, &dev_attr_fastsysclk);
+	device_remove_file(dev, &dev_attr_reg_read);
+	device_remove_file(dev, &dev_attr_reg_write);
+	device_remove_file(dev, &dev_attr_rotation);
+
+	unregister_framebuffer(info);
+
+	w100fb_clear_buffer();
+	kfree(info->pseudo_palette);
+
+	iounmap(remapped_base);
+	iounmap(remapped_regs);
+	iounmap(remapped_fbuf);
+
+	framebuffer_release(info);
+
+	return 0;
+}
+
+
+/* ------------------- chipset specific functions -------------------------- */
+
+
+static void w100_soft_reset(void)
+{
+	u16 val = readw((u16 *) remapped_base + cfgSTATUS);
+	writew(val | 0x08, (u16 *) remapped_base + cfgSTATUS);
+	udelay(100);
+	writew(0x00, (u16 *) remapped_base + cfgSTATUS);
+	udelay(100);
+}
+
+/*
+ * Initialization of critical w100 hardware
+ */
+static void w100_hw_init(void)
+{
+	u32 temp32;
+	union cif_cntl_u cif_cntl;
+	union intf_cntl_u intf_cntl;
+	union cfgreg_base_u cfgreg_base;
+	union wrap_top_dir_u wrap_top_dir;
+	union cif_read_dbg_u cif_read_dbg;
+	union cpu_defaults_u cpu_default;
+	union cif_write_dbg_u cif_write_dbg;
+	union wrap_start_dir_u wrap_start_dir;
+	union mc_ext_mem_location_u mc_ext_mem_loc;
+	union cif_io_u cif_io;
+
+	w100_soft_reset();
+
+	/* This is what the fpga_init code does on reset. May be wrong
+	   but there is little info available */
+	writel(0x31, remapped_regs + mmSCRATCH_UMSK);
+	for (temp32 = 0; temp32 < 10000; temp32++)
+		readl(remapped_regs + mmSCRATCH_UMSK);
+	writel(0x30, remapped_regs + mmSCRATCH_UMSK);
+
+	/* Set up CIF */
+	cif_io.val = defCIF_IO;
+	writel((u32)(cif_io.val), remapped_regs + mmCIF_IO);
+
+	cif_write_dbg.val = readl(remapped_regs + mmCIF_WRITE_DBG);
+	cif_write_dbg.f.dis_packer_ful_during_rbbm_timeout = 0;
+	cif_write_dbg.f.en_dword_split_to_rbbm = 1;
+	cif_write_dbg.f.dis_timeout_during_rbbm = 1;
+	writel((u32) (cif_write_dbg.val), remapped_regs + mmCIF_WRITE_DBG);
+
+	cif_read_dbg.val = readl(remapped_regs + mmCIF_READ_DBG);
+	cif_read_dbg.f.dis_rd_same_byte_to_trig_fetch = 1;
+	writel((u32) (cif_read_dbg.val), remapped_regs + mmCIF_READ_DBG);
+
+	cif_cntl.val = readl(remapped_regs + mmCIF_CNTL);
+	cif_cntl.f.dis_system_bits = 1;
+	cif_cntl.f.dis_mr = 1;
+	cif_cntl.f.en_wait_to_compensate_dq_prop_dly = 0;
+	cif_cntl.f.intb_oe = 1;
+	cif_cntl.f.interrupt_active_high = 1;
+	writel((u32) (cif_cntl.val), remapped_regs + mmCIF_CNTL);
+
+	/* Setup cfgINTF_CNTL and cfgCPU defaults */
+	intf_cntl.val = defINTF_CNTL;
+	intf_cntl.f.ad_inc_a = 1;
+	intf_cntl.f.ad_inc_b = 1;
+	intf_cntl.f.rd_data_rdy_a = 0;
+	intf_cntl.f.rd_data_rdy_b = 0;
+	writeb((u8) (intf_cntl.val), remapped_base + cfgINTF_CNTL);
+
+	cpu_default.val = defCPU_DEFAULTS;
+	cpu_default.f.access_ind_addr_a = 1;
+	cpu_default.f.access_ind_addr_b = 1;
+	cpu_default.f.access_scratch_reg = 1;
+	cpu_default.f.transition_size = 0;
+	writeb((u8) (cpu_default.val), remapped_base + cfgCPU_DEFAULTS);
+
+	/* set up the apertures */
+	writeb((u8) (W100_REG_BASE >> 16), remapped_base + cfgREG_BASE);
+
+	cfgreg_base.val = defCFGREG_BASE;
+	cfgreg_base.f.cfgreg_base = W100_CFG_BASE;
+	writel((u32) (cfgreg_base.val), remapped_regs + mmCFGREG_BASE);
+
+	/* This location is relative to internal w100 addresses */
+	writel(0x15FF1000, remapped_regs + mmMC_FB_LOCATION);
+
+	mc_ext_mem_loc.val = defMC_EXT_MEM_LOCATION;
+	mc_ext_mem_loc.f.mc_ext_mem_start = MEM_EXT_BASE_VALUE >> 8;
+	mc_ext_mem_loc.f.mc_ext_mem_top = MEM_EXT_TOP_VALUE >> 8;
+	writel((u32) (mc_ext_mem_loc.val), remapped_regs + mmMC_EXT_MEM_LOCATION);
+
+	if ((current_par->lcdMode == LCD_MODE_240) || (current_par->lcdMode == LCD_MODE_320))
+		w100_InitExtMem(LCD_SHARP_QVGA);
+	else
+		w100_InitExtMem(LCD_SHARP_VGA);
+
+	wrap_start_dir.val = defWRAP_START_DIR;
+	wrap_start_dir.f.start_addr = WRAP_BUF_BASE_VALUE >> 1;
+	writel((u32) (wrap_start_dir.val), remapped_regs + mmWRAP_START_DIR);
+
+	wrap_top_dir.val = defWRAP_TOP_DIR;
+	wrap_top_dir.f.top_addr = WRAP_BUF_TOP_VALUE >> 1;
+	writel((u32) (wrap_top_dir.val), remapped_regs + mmWRAP_TOP_DIR);
+
+	writel((u32) 0x2440, remapped_regs + mmRBBM_CNTL);
+}
+
+
+/*
+ * Types
+ */
+
+struct pll_parm {
+	u16 freq;		/* desired Fout for PLL */
+	u8 M;
+	u8 N_int;
+	u8 N_fac;
+	u8 tfgoal;
+	u8 lock_time;
+};
+
+struct power_state {
+	union clk_pin_cntl_u clk_pin_cntl;
+	union pll_ref_fb_div_u pll_ref_fb_div;
+	union pll_cntl_u pll_cntl;
+	union sclk_cntl_u sclk_cntl;
+	union pclk_cntl_u pclk_cntl;
+	union clk_test_cntl_u clk_test_cntl;
+	union pwrmgt_cntl_u pwrmgt_cntl;
+	u32 freq;		/* Fout for PLL calibration */
+	u8 tf100;		/* for pll calibration */
+	u8 tf80;		/* for pll calibration */
+	u8 tf20;		/* for pll calibration */
+	u8 M;			/* for pll calibration */
+	u8 N_int;		/* for pll calibration */
+	u8 N_fac;		/* for pll calibration */
+	u8 lock_time;	/* for pll calibration */
+	u8 tfgoal;		/* for pll calibration */
+	u8 auto_mode;	/* hardware auto switch? */
+	u8 pwm_mode;		/* 0 fast, 1 normal/slow */
+	u16 fast_sclk;	/* fast clk freq */
+	u16 norm_sclk;	/* slow clk freq */
+};
+
+
+/*
+ * Global state variables
+ */
+
+static struct power_state w100_pwr_state;
+
+/* This table is specific for 12.5MHz ref crystal.  */
+static struct pll_parm gPLLTable[] = {
+    /*freq     M   N_int    N_fac  tfgoal  lock_time */
+    { 50,      0,   1,       0,     0xE0,        56}, /*  50.00 MHz */
+    { 75,      0,   5,       0,     0xDE,	     37}, /*  75.00 MHz */
+    {100,      0,   7,       0,     0xE0,        28}, /* 100.00 MHz */
+    {125,      0,   9,       0,     0xE0,        22}, /* 125.00 MHz */
+    {150,      0,   11,      0,     0xE0,        17}, /* 150.00 MHz */
+    {  0,      0,   0,       0,        0,         0}  /* Terminator */
+};
+
+
+static u8 w100_pll_get_testcount(u8 testclk_sel)
+{
+	udelay(5);
+
+	w100_pwr_state.clk_test_cntl.f.start_check_freq = 0x0;
+	w100_pwr_state.clk_test_cntl.f.testclk_sel = testclk_sel;
+	w100_pwr_state.clk_test_cntl.f.tstcount_rst = 0x1;	/*reset test count */
+	writel((u32) (w100_pwr_state.clk_test_cntl.val), remapped_regs + mmCLK_TEST_CNTL);
+	w100_pwr_state.clk_test_cntl.f.tstcount_rst = 0x0;
+	writel((u32) (w100_pwr_state.clk_test_cntl.val), remapped_regs + mmCLK_TEST_CNTL);
+
+	w100_pwr_state.clk_test_cntl.f.start_check_freq = 0x1;
+	writel((u32) (w100_pwr_state.clk_test_cntl.val), remapped_regs + mmCLK_TEST_CNTL);
+
+	udelay(20);
+
+	w100_pwr_state.clk_test_cntl.val = readl(remapped_regs + mmCLK_TEST_CNTL);
+	w100_pwr_state.clk_test_cntl.f.start_check_freq = 0x0;
+	writel((u32) (w100_pwr_state.clk_test_cntl.val), remapped_regs + mmCLK_TEST_CNTL);
+
+	return w100_pwr_state.clk_test_cntl.f.test_count;
+}
+
+
+static u8 w100_pll_adjust(void)
+{
+	do {
+		/* Wai Ming 80 percent of VDD 1.3V gives 1.04V, minimum operating voltage is 1.08V
+		 * therefore, commented out the following lines
+		 * tf80 meant tf100
+		 * set VCO input = 0.8 * VDD
+		 */
+		w100_pwr_state.pll_cntl.f.pll_dactal = 0xd;
+		writel((u32) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL);
+
+		w100_pwr_state.tf80 = w100_pll_get_testcount(0x1);	/* PLLCLK */
+		if (w100_pwr_state.tf80 >= (w100_pwr_state.tfgoal)) {
+			/* set VCO input = 0.2 * VDD */
+			w100_pwr_state.pll_cntl.f.pll_dactal = 0x7;
+			writel((u32) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL);
+
+			w100_pwr_state.tf20 = w100_pll_get_testcount(0x1);	/* PLLCLK */
+			if (w100_pwr_state.tf20 <= (w100_pwr_state.tfgoal))
+				return 1; // Success
+
+			if ((w100_pwr_state.pll_cntl.f.pll_vcofr == 0x0) &&
+			    ((w100_pwr_state.pll_cntl.f.pll_pvg == 0x7) ||
+			     (w100_pwr_state.pll_cntl.f.pll_ioffset == 0x0))) {
+				/* slow VCO config */
+				w100_pwr_state.pll_cntl.f.pll_vcofr = 0x1;
+				w100_pwr_state.pll_cntl.f.pll_pvg = 0x0;
+				w100_pwr_state.pll_cntl.f.pll_ioffset = 0x0;
+				writel((u32) (w100_pwr_state.pll_cntl.val),
+					remapped_regs + mmPLL_CNTL);
+				continue;
+			}
+		}
+		if ((w100_pwr_state.pll_cntl.f.pll_ioffset) < 0x3) {
+			w100_pwr_state.pll_cntl.f.pll_ioffset += 0x1;
+			writel((u32) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL);
+			continue;
+		}
+		if ((w100_pwr_state.pll_cntl.f.pll_pvg) < 0x7) {
+			w100_pwr_state.pll_cntl.f.pll_ioffset = 0x0;
+			w100_pwr_state.pll_cntl.f.pll_pvg += 0x1;
+			writel((u32) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL);
+			continue;
+		}
+		return 0; // error
+	} while(1);
+}
+
+
+/*
+ * w100_pll_calibration
+ *                freq = target frequency of the PLL
+ *                (note: crystal = 14.3MHz)
+ */
+static u8 w100_pll_calibration(u32 freq)
+{
+	u8 status;
+
+	/* initial setting */
+	w100_pwr_state.pll_cntl.f.pll_pwdn = 0x0;		/* power down */
+	w100_pwr_state.pll_cntl.f.pll_reset = 0x0;		/* not reset */
+	w100_pwr_state.pll_cntl.f.pll_tcpoff = 0x1;	/* Hi-Z */
+	w100_pwr_state.pll_cntl.f.pll_pvg = 0x0;		/* VCO gain = 0 */
+	w100_pwr_state.pll_cntl.f.pll_vcofr = 0x0;		/* VCO frequency range control = off */
+	w100_pwr_state.pll_cntl.f.pll_ioffset = 0x0;	/* current offset inside VCO = 0 */
+	w100_pwr_state.pll_cntl.f.pll_ring_off = 0x0;
+	writel((u32) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL);
+
+	/* check for (tf80 >= tfgoal) && (tf20 =< tfgoal) */
+	if ((w100_pwr_state.tf80 < w100_pwr_state.tfgoal) || (w100_pwr_state.tf20 > w100_pwr_state.tfgoal)) {
+		status=w100_pll_adjust();
+	}
+	/* PLL Reset And Lock */
+
+	/* set VCO input = 0.5 * VDD */
+	w100_pwr_state.pll_cntl.f.pll_dactal = 0xa;
+	writel((u32) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL);
+
+	/* reset time */
+	udelay(1);
+
+	/* enable charge pump */
+	w100_pwr_state.pll_cntl.f.pll_tcpoff = 0x0;	/* normal */
+	writel((u32) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL);
+
+	/* set VCO input = Hi-Z */
+	/* disable DAC */
+	w100_pwr_state.pll_cntl.f.pll_dactal = 0x0;
+	writel((u32) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL);
+
+	/* lock time */
+	udelay(400);	/* delay 400 us */
+
+	/* PLL locked */
+
+	w100_pwr_state.sclk_cntl.f.sclk_src_sel = 0x1;	/* PLL clock */
+	writel((u32) (w100_pwr_state.sclk_cntl.val), remapped_regs + mmSCLK_CNTL);
+
+	w100_pwr_state.tf100 = w100_pll_get_testcount(0x1);	/* PLLCLK */
+
+	return status;
+}
+
+
+static u8 w100_pll_set_clk(void)
+{
+	u8 status;
+
+	if (w100_pwr_state.auto_mode == 1)	/* auto mode */
+	{
+		w100_pwr_state.pwrmgt_cntl.f.pwm_fast_noml_hw_en = 0x0;	/* disable fast to normal */
+		w100_pwr_state.pwrmgt_cntl.f.pwm_noml_fast_hw_en = 0x0;	/* disable normal to fast */
+		writel((u32) (w100_pwr_state.pwrmgt_cntl.val), remapped_regs + mmPWRMGT_CNTL);
+	}
+
+	w100_pwr_state.sclk_cntl.f.sclk_src_sel = 0x0;	/* crystal clock */
+	writel((u32) (w100_pwr_state.sclk_cntl.val), remapped_regs + mmSCLK_CNTL);
+
+	w100_pwr_state.pll_ref_fb_div.f.pll_ref_div = w100_pwr_state.M;
+	w100_pwr_state.pll_ref_fb_div.f.pll_fb_div_int = w100_pwr_state.N_int;
+	w100_pwr_state.pll_ref_fb_div.f.pll_fb_div_frac = w100_pwr_state.N_fac;
+	w100_pwr_state.pll_ref_fb_div.f.pll_lock_time = w100_pwr_state.lock_time;
+	writel((u32) (w100_pwr_state.pll_ref_fb_div.val), remapped_regs + mmPLL_REF_FB_DIV);
+
+	w100_pwr_state.pwrmgt_cntl.f.pwm_mode_req = 0;
+	writel((u32) (w100_pwr_state.pwrmgt_cntl.val), remapped_regs + mmPWRMGT_CNTL);
+
+	status = w100_pll_calibration (w100_pwr_state.freq);
+
+	if (w100_pwr_state.auto_mode == 1)	/* auto mode */
+	{
+		w100_pwr_state.pwrmgt_cntl.f.pwm_fast_noml_hw_en = 0x1;	/* reenable fast to normal */
+		w100_pwr_state.pwrmgt_cntl.f.pwm_noml_fast_hw_en = 0x1;	/* reenable normal to fast  */
+		writel((u32) (w100_pwr_state.pwrmgt_cntl.val), remapped_regs + mmPWRMGT_CNTL);
+	}
+	return status;
+}
+
+
+/* assume reference crystal clk is 12.5MHz,
+ * and that doubling is not enabled.
+ *
+ * Freq = 12 == 12.5MHz.
+ */
+static u16 w100_set_slowsysclk(u16 freq)
+{
+	if (w100_pwr_state.norm_sclk == freq)
+		return freq;
+
+	if (w100_pwr_state.auto_mode == 1)	/* auto mode */
+		return 0;
+
+	if (freq == 12) {
+		w100_pwr_state.norm_sclk = freq;
+		w100_pwr_state.sclk_cntl.f.sclk_post_div_slow = 0x0;	/* Pslow = 1 */
+		w100_pwr_state.sclk_cntl.f.sclk_src_sel = 0x0;	/* crystal src */
+
+		writel((u32) (w100_pwr_state.sclk_cntl.val), remapped_regs + mmSCLK_CNTL);
+
+		w100_pwr_state.clk_pin_cntl.f.xtalin_pm_en = 0x1;
+		writel((u32) (w100_pwr_state.clk_pin_cntl.val), remapped_regs + mmCLK_PIN_CNTL);
+
+		w100_pwr_state.pwrmgt_cntl.f.pwm_enable = 0x1;
+		w100_pwr_state.pwrmgt_cntl.f.pwm_mode_req = 0x1;
+		writel((u32) (w100_pwr_state.pwrmgt_cntl.val), remapped_regs + mmPWRMGT_CNTL);
+		w100_pwr_state.pwm_mode = 1;	/* normal mode */
+		return freq;
+	} else
+		return 0;
+}
+
+
+static u16 w100_set_fastsysclk(u16 freq)
+{
+	u16 pll_freq;
+	int i;
+
+	while(1) {
+		pll_freq = (u16) (freq * (w100_pwr_state.sclk_cntl.f.sclk_post_div_fast + 1));
+		i = 0;
+		do {
+			if (pll_freq == gPLLTable[i].freq) {
+				w100_pwr_state.freq = gPLLTable[i].freq * 1000000;
+				w100_pwr_state.M = gPLLTable[i].M;
+				w100_pwr_state.N_int = gPLLTable[i].N_int;
+				w100_pwr_state.N_fac = gPLLTable[i].N_fac;
+				w100_pwr_state.tfgoal = gPLLTable[i].tfgoal;
+				w100_pwr_state.lock_time = gPLLTable[i].lock_time;
+				w100_pwr_state.tf20 = 0xff;	/* set highest */
+				w100_pwr_state.tf80 = 0x00;	/* set lowest */
+
+				w100_pll_set_clk();
+				w100_pwr_state.pwm_mode = 0;	/* fast mode */
+				w100_pwr_state.fast_sclk = freq;
+				return freq;
+			}
+			i++;
+		} while(gPLLTable[i].freq);
+
+		if (w100_pwr_state.auto_mode == 1)
+			break;
+
+		if (w100_pwr_state.sclk_cntl.f.sclk_post_div_fast == 0)
+			break;
+
+		w100_pwr_state.sclk_cntl.f.sclk_post_div_fast -= 1;
+		writel((u32) (w100_pwr_state.sclk_cntl.val), remapped_regs + mmSCLK_CNTL);
+	}
+	return 0;
+}
+
+
+/* Set up an initial state.  Some values/fields set
+   here will be overwritten. */
+static void w100_pwm_setup(void)
+{
+	w100_pwr_state.clk_pin_cntl.f.osc_en = 0x1;
+	w100_pwr_state.clk_pin_cntl.f.osc_gain = 0x1f;
+	w100_pwr_state.clk_pin_cntl.f.dont_use_xtalin = 0x0;
+	w100_pwr_state.clk_pin_cntl.f.xtalin_pm_en = 0x0;
+	w100_pwr_state.clk_pin_cntl.f.xtalin_dbl_en = 0x0;	/* no freq doubling */
+	w100_pwr_state.clk_pin_cntl.f.cg_debug = 0x0;
+	writel((u32) (w100_pwr_state.clk_pin_cntl.val), remapped_regs + mmCLK_PIN_CNTL);
+
+	w100_pwr_state.sclk_cntl.f.sclk_src_sel = 0x0;	/* Crystal Clk */
+	w100_pwr_state.sclk_cntl.f.sclk_post_div_fast = 0x0;	/* Pfast = 1 */
+	w100_pwr_state.sclk_cntl.f.sclk_clkon_hys = 0x3;
+	w100_pwr_state.sclk_cntl.f.sclk_post_div_slow = 0x0;	/* Pslow = 1 */
+	w100_pwr_state.sclk_cntl.f.disp_cg_ok2switch_en = 0x0;
+	w100_pwr_state.sclk_cntl.f.sclk_force_reg = 0x0;	/* Dynamic */
+	w100_pwr_state.sclk_cntl.f.sclk_force_disp = 0x0;	/* Dynamic */
+	w100_pwr_state.sclk_cntl.f.sclk_force_mc = 0x0;	/* Dynamic */
+	w100_pwr_state.sclk_cntl.f.sclk_force_extmc = 0x0;	/* Dynamic */
+	w100_pwr_state.sclk_cntl.f.sclk_force_cp = 0x0;	/* Dynamic */
+	w100_pwr_state.sclk_cntl.f.sclk_force_e2 = 0x0;	/* Dynamic */
+	w100_pwr_state.sclk_cntl.f.sclk_force_e3 = 0x0;	/* Dynamic */
+	w100_pwr_state.sclk_cntl.f.sclk_force_idct = 0x0;	/* Dynamic */
+	w100_pwr_state.sclk_cntl.f.sclk_force_bist = 0x0;	/* Dynamic */
+	w100_pwr_state.sclk_cntl.f.busy_extend_cp = 0x0;
+	w100_pwr_state.sclk_cntl.f.busy_extend_e2 = 0x0;
+	w100_pwr_state.sclk_cntl.f.busy_extend_e3 = 0x0;
+	w100_pwr_state.sclk_cntl.f.busy_extend_idct = 0x0;
+	writel((u32) (w100_pwr_state.sclk_cntl.val), remapped_regs + mmSCLK_CNTL);
+
+	w100_pwr_state.pclk_cntl.f.pclk_src_sel = 0x0;	/* Crystal Clk */
+	w100_pwr_state.pclk_cntl.f.pclk_post_div = 0x1;	/* P = 2 */
+	w100_pwr_state.pclk_cntl.f.pclk_force_disp = 0x0;	/* Dynamic */
+	writel((u32) (w100_pwr_state.pclk_cntl.val), remapped_regs + mmPCLK_CNTL);
+
+	w100_pwr_state.pll_ref_fb_div.f.pll_ref_div = 0x0;	/* M = 1 */
+	w100_pwr_state.pll_ref_fb_div.f.pll_fb_div_int = 0x0;	/* N = 1.0 */
+	w100_pwr_state.pll_ref_fb_div.f.pll_fb_div_frac = 0x0;
+	w100_pwr_state.pll_ref_fb_div.f.pll_reset_time = 0x5;
+	w100_pwr_state.pll_ref_fb_div.f.pll_lock_time = 0xff;
+	writel((u32) (w100_pwr_state.pll_ref_fb_div.val), remapped_regs + mmPLL_REF_FB_DIV);
+
+	w100_pwr_state.pll_cntl.f.pll_pwdn = 0x1;
+	w100_pwr_state.pll_cntl.f.pll_reset = 0x1;
+	w100_pwr_state.pll_cntl.f.pll_pm_en = 0x0;
+	w100_pwr_state.pll_cntl.f.pll_mode = 0x0;	/* uses VCO clock */
+	w100_pwr_state.pll_cntl.f.pll_refclk_sel = 0x0;
+	w100_pwr_state.pll_cntl.f.pll_fbclk_sel = 0x0;
+	w100_pwr_state.pll_cntl.f.pll_tcpoff = 0x0;
+	w100_pwr_state.pll_cntl.f.pll_pcp = 0x4;
+	w100_pwr_state.pll_cntl.f.pll_pvg = 0x0;
+	w100_pwr_state.pll_cntl.f.pll_vcofr = 0x0;
+	w100_pwr_state.pll_cntl.f.pll_ioffset = 0x0;
+	w100_pwr_state.pll_cntl.f.pll_pecc_mode = 0x0;
+	w100_pwr_state.pll_cntl.f.pll_pecc_scon = 0x0;
+	w100_pwr_state.pll_cntl.f.pll_dactal = 0x0;	/* Hi-Z */
+	w100_pwr_state.pll_cntl.f.pll_cp_clip = 0x3;
+	w100_pwr_state.pll_cntl.f.pll_conf = 0x2;
+	w100_pwr_state.pll_cntl.f.pll_mbctrl = 0x2;
+	w100_pwr_state.pll_cntl.f.pll_ring_off = 0x0;
+	writel((u32) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL);
+
+	w100_pwr_state.clk_test_cntl.f.testclk_sel = 0x1;	/* PLLCLK (for testing) */
+	w100_pwr_state.clk_test_cntl.f.start_check_freq = 0x0;
+	w100_pwr_state.clk_test_cntl.f.tstcount_rst = 0x0;
+	writel((u32) (w100_pwr_state.clk_test_cntl.val), remapped_regs + mmCLK_TEST_CNTL);
+
+	w100_pwr_state.pwrmgt_cntl.f.pwm_enable = 0x0;
+	w100_pwr_state.pwrmgt_cntl.f.pwm_mode_req = 0x1;	/* normal mode (0, 1, 3) */
+	w100_pwr_state.pwrmgt_cntl.f.pwm_wakeup_cond = 0x0;
+	w100_pwr_state.pwrmgt_cntl.f.pwm_fast_noml_hw_en = 0x0;
+	w100_pwr_state.pwrmgt_cntl.f.pwm_noml_fast_hw_en = 0x0;
+	w100_pwr_state.pwrmgt_cntl.f.pwm_fast_noml_cond = 0x1;	/* PM4,ENG */
+	w100_pwr_state.pwrmgt_cntl.f.pwm_noml_fast_cond = 0x1;	/* PM4,ENG */
+	w100_pwr_state.pwrmgt_cntl.f.pwm_idle_timer = 0xFF;
+	w100_pwr_state.pwrmgt_cntl.f.pwm_busy_timer = 0xFF;
+	writel((u32) (w100_pwr_state.pwrmgt_cntl.val), remapped_regs + mmPWRMGT_CNTL);
+
+	w100_pwr_state.auto_mode = 0;	/* manual mode */
+	w100_pwr_state.pwm_mode = 1;	/* normal mode (0, 1, 2) */
+	w100_pwr_state.freq = 50000000;	/* 50 MHz */
+	w100_pwr_state.M = 3;	/* M = 4 */
+	w100_pwr_state.N_int = 6;	/* N = 7.0 */
+	w100_pwr_state.N_fac = 0;
+	w100_pwr_state.tfgoal = 0xE0;
+	w100_pwr_state.lock_time = 56;
+	w100_pwr_state.tf20 = 0xff;	/* set highest */
+	w100_pwr_state.tf80 = 0x00;	/* set lowest */
+	w100_pwr_state.tf100 = 0x00;	/* set lowest */
+	w100_pwr_state.fast_sclk = 50;	/* 50.0 MHz */
+	w100_pwr_state.norm_sclk = 12;	/* 12.5 MHz */
+}
+
+
+static void w100_init_sharp_lcd(u32 mode)
+{
+	u32 temp32;
+	union disp_db_buf_cntl_wr_u disp_db_buf_wr_cntl;
+
+	/* Prevent display updates */
+	disp_db_buf_wr_cntl.f.db_buf_cntl = 0x1e;
+	disp_db_buf_wr_cntl.f.update_db_buf = 0;
+	disp_db_buf_wr_cntl.f.en_db_buf = 0;
+	writel((u32) (disp_db_buf_wr_cntl.val), remapped_regs + mmDISP_DB_BUF_CNTL);
+
+	switch(mode) {
+	case LCD_SHARP_QVGA:
+		w100_set_slowsysclk(12);	/* use crystal -- 12.5MHz */
+		/* not use PLL */
+
+		writel(0x7FFF8000, remapped_regs + mmMC_EXT_MEM_LOCATION);
+		writel(0x85FF8000, remapped_regs + mmMC_FB_LOCATION);
+		writel(0x00000003, remapped_regs + mmLCD_FORMAT);
+		writel(0x00CF1C06, remapped_regs + mmGRAPHIC_CTRL);
+		writel(0x01410145, remapped_regs + mmCRTC_TOTAL);
+		writel(0x01170027, remapped_regs + mmACTIVE_H_DISP);
+		writel(0x01410001, remapped_regs + mmACTIVE_V_DISP);
+		writel(0x01170027, remapped_regs + mmGRAPHIC_H_DISP);
+		writel(0x01410001, remapped_regs + mmGRAPHIC_V_DISP);
+		writel(0x81170027, remapped_regs + mmCRTC_SS);
+		writel(0xA0140000, remapped_regs + mmCRTC_LS);
+		writel(0x00400008, remapped_regs + mmCRTC_REV);
+		writel(0xA0000000, remapped_regs + mmCRTC_DCLK);
+		writel(0xC0140014, remapped_regs + mmCRTC_GS);
+		writel(0x00010141, remapped_regs + mmCRTC_VPOS_GS);
+		writel(0x8015010F, remapped_regs + mmCRTC_GCLK);
+		writel(0x80100110, remapped_regs + mmCRTC_GOE);
+		writel(0x00000000, remapped_regs + mmCRTC_FRAME);
+		writel(0x00000000, remapped_regs + mmCRTC_FRAME_VPOS);
+		writel(0x01CC0000, remapped_regs + mmLCDD_CNTL1);
+		writel(0x0003FFFF, remapped_regs + mmLCDD_CNTL2);
+		writel(0x00FFFF0D, remapped_regs + mmGENLCD_CNTL1);
+		writel(0x003F3003, remapped_regs + mmGENLCD_CNTL2);
+		writel(0x00000000, remapped_regs + mmCRTC_DEFAULT_COUNT);
+		writel(0x0000FF00, remapped_regs + mmLCD_BACKGROUND_COLOR);
+		writel(0x000102aa, remapped_regs + mmGENLCD_CNTL3);
+		writel(0x00800000, remapped_regs + mmGRAPHIC_OFFSET);
+		writel(0x000001e0, remapped_regs + mmGRAPHIC_PITCH);
+		writel(0x000000bf, remapped_regs + mmGPIO_DATA);
+		writel(0x03c0feff, remapped_regs + mmGPIO_CNTL2);
+		writel(0x00000000, remapped_regs + mmGPIO_CNTL1);
+		writel(0x41060010, remapped_regs + mmCRTC_PS1_ACTIVE);
+		break;
+	case LCD_SHARP_VGA:
+		w100_set_slowsysclk(12);	/* use crystal -- 12.5MHz */
+		w100_set_fastsysclk(current_par->fastsysclk_mode);	/* use PLL -- 75.0MHz */
+		w100_pwr_state.pclk_cntl.f.pclk_src_sel = 0x1;
+		w100_pwr_state.pclk_cntl.f.pclk_post_div = 0x2;
+		writel((u32) (w100_pwr_state.pclk_cntl.val), remapped_regs + mmPCLK_CNTL);
+		writel(0x15FF1000, remapped_regs + mmMC_FB_LOCATION);
+		writel(0x9FFF8000, remapped_regs + mmMC_EXT_MEM_LOCATION);
+		writel(0x00000003, remapped_regs + mmLCD_FORMAT);
+		writel(0x00DE1D66, remapped_regs + mmGRAPHIC_CTRL);
+
+		writel(0x0283028B, remapped_regs + mmCRTC_TOTAL);
+		writel(0x02360056, remapped_regs + mmACTIVE_H_DISP);
+		writel(0x02830003, remapped_regs + mmACTIVE_V_DISP);
+		writel(0x02360056, remapped_regs + mmGRAPHIC_H_DISP);
+		writel(0x02830003, remapped_regs + mmGRAPHIC_V_DISP);
+		writel(0x82360056, remapped_regs + mmCRTC_SS);
+		writel(0xA0280000, remapped_regs + mmCRTC_LS);
+		writel(0x00400008, remapped_regs + mmCRTC_REV);
+		writel(0xA0000000, remapped_regs + mmCRTC_DCLK);
+		writel(0x80280028, remapped_regs + mmCRTC_GS);
+		writel(0x02830002, remapped_regs + mmCRTC_VPOS_GS);
+		writel(0x8015010F, remapped_regs + mmCRTC_GCLK);
+		writel(0x80100110, remapped_regs + mmCRTC_GOE);
+		writel(0x00000000, remapped_regs + mmCRTC_FRAME);
+		writel(0x00000000, remapped_regs + mmCRTC_FRAME_VPOS);
+		writel(0x01CC0000, remapped_regs + mmLCDD_CNTL1);
+		writel(0x0003FFFF, remapped_regs + mmLCDD_CNTL2);
+		writel(0x00FFFF0D, remapped_regs + mmGENLCD_CNTL1);
+		writel(0x003F3003, remapped_regs + mmGENLCD_CNTL2);
+		writel(0x00000000, remapped_regs + mmCRTC_DEFAULT_COUNT);
+		writel(0x0000FF00, remapped_regs + mmLCD_BACKGROUND_COLOR);
+		writel(0x000102aa, remapped_regs + mmGENLCD_CNTL3);
+		writel(0x00800000, remapped_regs + mmGRAPHIC_OFFSET);
+		writel(0x000003C0, remapped_regs + mmGRAPHIC_PITCH);
+		writel(0x000000bf, remapped_regs + mmGPIO_DATA);
+		writel(0x03c0feff, remapped_regs + mmGPIO_CNTL2);
+		writel(0x00000000, remapped_regs + mmGPIO_CNTL1);
+		writel(0x41060010, remapped_regs + mmCRTC_PS1_ACTIVE);
+		break;
+	default:
+		break;
+	}
+
+	/* Hack for overlay in ext memory */
+	temp32 = readl(remapped_regs + mmDISP_DEBUG2);
+	temp32 |= 0xc0000000;
+	writel(temp32, remapped_regs + mmDISP_DEBUG2);
+
+	/* Re-enable display updates */
+	disp_db_buf_wr_cntl.f.db_buf_cntl = 0x1e;
+	disp_db_buf_wr_cntl.f.update_db_buf = 1;
+	disp_db_buf_wr_cntl.f.en_db_buf = 1;
+	writel((u32) (disp_db_buf_wr_cntl.val), remapped_regs + mmDISP_DB_BUF_CNTL);
+}
+
+
+static void w100_set_vga_rotation_regs(u16 divider, unsigned long ctrl, unsigned long offset, unsigned long pitch)
+{
+	w100_pwr_state.pclk_cntl.f.pclk_src_sel = 0x1;
+	w100_pwr_state.pclk_cntl.f.pclk_post_div = divider;
+	writel((u32) (w100_pwr_state.pclk_cntl.val), remapped_regs + mmPCLK_CNTL);
+
+	writel(ctrl, remapped_regs + mmGRAPHIC_CTRL);
+	writel(offset, remapped_regs + mmGRAPHIC_OFFSET);
+	writel(pitch, remapped_regs + mmGRAPHIC_PITCH);
+
+	/* Re-enable display updates */
+	writel(0x0000007b, remapped_regs + mmDISP_DB_BUF_CNTL);
+}
+
+
+static void w100_init_vga_rotation(u16 deg)
+{
+	switch(deg) {
+	case 0:
+		w100_set_vga_rotation_regs(0x02, 0x00DE1D66, 0x00800000, 0x000003c0);
+		break;
+	case 90:
+		w100_set_vga_rotation_regs(0x06, 0x00DE1D0e, 0x00895b00, 0x00000500);
+		break;
+	case 180:
+		w100_set_vga_rotation_regs(0x02, 0x00DE1D7e, 0x00895ffc, 0x000003c0);
+		break;
+	case 270:
+		w100_set_vga_rotation_regs(0x06, 0x00DE1D16, 0x008004fc, 0x00000500);
+		break;
+	default:
+		/* not-support */
+		break;
+	}
+}
+
+
+static void w100_set_qvga_rotation_regs(unsigned long ctrl, unsigned long offset, unsigned long pitch)
+{
+	writel(ctrl, remapped_regs + mmGRAPHIC_CTRL);
+	writel(offset, remapped_regs + mmGRAPHIC_OFFSET);
+	writel(pitch, remapped_regs + mmGRAPHIC_PITCH);
+
+	/* Re-enable display updates */
+	writel(0x0000007b, remapped_regs + mmDISP_DB_BUF_CNTL);
+}
+
+
+static void w100_init_qvga_rotation(u16 deg)
+{
+	switch(deg) {
+	case 0:
+		w100_set_qvga_rotation_regs(0x00d41c06, 0x00800000, 0x000001e0);
+		break;
+	case 90:
+		w100_set_qvga_rotation_regs(0x00d41c0E, 0x00825580, 0x00000280);
+		break;
+	case 180:
+		w100_set_qvga_rotation_regs(0x00d41c1e, 0x008257fc, 0x000001e0);
+		break;
+	case 270:
+		w100_set_qvga_rotation_regs(0x00d41c16, 0x0080027c, 0x00000280);
+		break;
+	default:
+		/* not-support */
+		break;
+	}
+}
+
+
+static void w100_suspend(u32 mode)
+{
+	u32 val;
+
+	writel(0x7FFF8000, remapped_regs + mmMC_EXT_MEM_LOCATION);
+	writel(0x00FF0000, remapped_regs + mmMC_PERF_MON_CNTL);
+
+	val = readl(remapped_regs + mmMEM_EXT_TIMING_CNTL);
+	val &= ~(0x00100000);	/* bit20=0 */
+	val |= 0xFF000000;	/* bit31:24=0xff */
+	writel(val, remapped_regs + mmMEM_EXT_TIMING_CNTL);
+
+	val = readl(remapped_regs + mmMEM_EXT_CNTL);
+	val &= ~(0x00040000);	/* bit18=0 */
+	val |= 0x00080000;	/* bit19=1 */
+	writel(val, remapped_regs + mmMEM_EXT_CNTL);
+
+	udelay(1);		/* wait 1us */
+
+	if (mode == W100_SUSPEND_EXTMEM) {
+
+		/* CKE: Tri-State */
+		val = readl(remapped_regs + mmMEM_EXT_CNTL);
+		val |= 0x40000000;	/* bit30=1 */
+		writel(val, remapped_regs + mmMEM_EXT_CNTL);
+
+		/* CLK: Stop */
+		val = readl(remapped_regs + mmMEM_EXT_CNTL);
+		val &= ~(0x00000001);	/* bit0=0 */
+		writel(val, remapped_regs + mmMEM_EXT_CNTL);
+	} else {
+
+		writel(0x00000000, remapped_regs + mmSCLK_CNTL);
+		writel(0x000000BF, remapped_regs + mmCLK_PIN_CNTL);
+		writel(0x00000015, remapped_regs + mmPWRMGT_CNTL);
+
+		udelay(5);
+
+		val = readl(remapped_regs + mmPLL_CNTL);
+		val |= 0x00000004;	/* bit2=1 */
+		writel(val, remapped_regs + mmPLL_CNTL);
+		writel(0x0000001d, remapped_regs + mmPWRMGT_CNTL);
+	}
+}
+
+
+static void w100_resume(void)
+{
+	u32 temp32;
+
+	w100_hw_init();
+	w100_pwm_setup();
+
+	temp32 = readl(remapped_regs + mmDISP_DEBUG2);
+	temp32 &= 0xff7fffff;
+	temp32 |= 0x00800000;
+	writel(temp32, remapped_regs + mmDISP_DEBUG2);
+
+	if (current_par->lcdMode == LCD_MODE_480 || current_par->lcdMode == LCD_MODE_640) {
+		w100_init_sharp_lcd(LCD_SHARP_VGA);
+		if (current_par->lcdMode == LCD_MODE_640) {
+			w100_init_vga_rotation(current_par->rotation_flag ? 270 : 90);
+		}
+	} else {
+		w100_init_sharp_lcd(LCD_SHARP_QVGA);
+		if (current_par->lcdMode == LCD_MODE_320) {
+			w100_init_qvga_rotation(current_par->rotation_flag ? 270 : 90);
+		}
+	}
+}
+
+
+static void w100_vsync(void)
+{
+	u32 tmp;
+	int timeout = 30000; /* VSync timeout = 30[ms] > 16.8[ms] */
+
+	tmp = readl(remapped_regs + mmACTIVE_V_DISP);
+
+	/* set vline pos  */
+	writel((tmp >> 16) & 0x3ff, remapped_regs + mmDISP_INT_CNTL);
+
+	/* disable vline irq */
+	tmp = readl(remapped_regs + mmGEN_INT_CNTL);
+
+	tmp &= ~0x00000002;
+	writel(tmp, remapped_regs + mmGEN_INT_CNTL);
+
+	/* clear vline irq status */
+	writel(0x00000002, remapped_regs + mmGEN_INT_STATUS);
+
+	/* enable vline irq */
+	writel((tmp | 0x00000002), remapped_regs + mmGEN_INT_CNTL);
+
+	/* clear vline irq status */
+	writel(0x00000002, remapped_regs + mmGEN_INT_STATUS);
+
+	while(timeout > 0) {
+		if (readl(remapped_regs + mmGEN_INT_STATUS) & 0x00000002)
+			break;
+		udelay(1);
+		timeout--;
+	}
+
+	/* disable vline irq */
+	writel(tmp, remapped_regs + mmGEN_INT_CNTL);
+
+	/* clear vline irq status */
+	writel(0x00000002, remapped_regs + mmGEN_INT_STATUS);
+}
+
+
+static void w100_InitExtMem(u32 mode)
+{
+	switch(mode) {
+	case LCD_SHARP_QVGA:
+		/* QVGA doesn't use external memory
+		   nothing to do, really. */
+		break;
+	case LCD_SHARP_VGA:
+		writel(0x00007800, remapped_regs + mmMC_BIST_CTRL);
+		writel(0x00040003, remapped_regs + mmMEM_EXT_CNTL);
+		writel(0x00200021, remapped_regs + mmMEM_SDRAM_MODE_REG);
+		udelay(100);
+		writel(0x80200021, remapped_regs + mmMEM_SDRAM_MODE_REG);
+		udelay(100);
+		writel(0x00650021, remapped_regs + mmMEM_SDRAM_MODE_REG);
+		udelay(100);
+		writel(0x10002a4a, remapped_regs + mmMEM_EXT_TIMING_CNTL);
+		writel(0x7ff87012, remapped_regs + mmMEM_IO_CNTL);
+		break;
+	default:
+		break;
+	}
+}
+
+
+#define RESCTL_ADRS     0x00
+#define PHACTRL_ADRS	0x01
+#define DUTYCTRL_ADRS	0x02
+#define POWERREG0_ADRS	0x03
+#define POWERREG1_ADRS	0x04
+#define GPOR3_ADRS		0x05
+#define PICTRL_ADRS     0x06
+#define POLCTRL_ADRS    0x07
+
+#define RESCTL_QVGA     0x01
+#define RESCTL_VGA      0x00
+
+#define POWER1_VW_ON	0x01	/* VW Supply FET ON */
+#define POWER1_GVSS_ON	0x02	/* GVSS(-8V) Power Supply ON */
+#define POWER1_VDD_ON	0x04	/* VDD(8V),SVSS(-4V) Power Supply ON */
+
+#define POWER1_VW_OFF	0x00	/* VW Supply FET OFF */
+#define POWER1_GVSS_OFF	0x00	/* GVSS(-8V) Power Supply OFF */
+#define POWER1_VDD_OFF	0x00	/* VDD(8V),SVSS(-4V) Power Supply OFF */
+
+#define POWER0_COM_DCLK	0x01	/* COM Voltage DC Bias DAC Serial Data Clock */
+#define POWER0_COM_DOUT	0x02	/* COM Voltage DC Bias DAC Serial Data Out */
+#define POWER0_DAC_ON	0x04	/* DAC Power Supply ON */
+#define POWER0_COM_ON	0x08	/* COM Powewr Supply ON */
+#define POWER0_VCC5_ON	0x10	/* VCC5 Power Supply ON */
+
+#define POWER0_DAC_OFF	0x00	/* DAC Power Supply OFF */
+#define POWER0_COM_OFF	0x00	/* COM Powewr Supply OFF */
+#define POWER0_VCC5_OFF	0x00	/* VCC5 Power Supply OFF */
+
+#define PICTRL_INIT_STATE	0x01
+#define PICTRL_INIOFF		0x02
+#define PICTRL_POWER_DOWN	0x04
+#define PICTRL_COM_SIGNAL_OFF	0x08
+#define PICTRL_DAC_SIGNAL_OFF	0x10
+
+#define PICTRL_POWER_ACTIVE	(0)
+
+#define POLCTRL_SYNC_POL_FALL	0x01
+#define POLCTRL_EN_POL_FALL	0x02
+#define POLCTRL_DATA_POL_FALL	0x04
+#define POLCTRL_SYNC_ACT_H	0x08
+#define POLCTRL_EN_ACT_L	0x10
+
+#define POLCTRL_SYNC_POL_RISE	0x00
+#define POLCTRL_EN_POL_RISE	0x00
+#define POLCTRL_DATA_POL_RISE	0x00
+#define POLCTRL_SYNC_ACT_L	0x00
+#define POLCTRL_EN_ACT_H	0x00
+
+#define PHACTRL_PHASE_MANUAL	0x01
+
+#define PHAD_QVGA_DEFAULT_VAL (9)
+#define COMADJ_DEFAULT        (125)
+
+static void lcdtg_ssp_send(u8 adrs, u8 data)
+{
+	w100fb_ssp_send(adrs,data);
+}
+
+/*
+ * This is only a psuedo I2C interface. We can't use the standard kernel
+ * routines as the interface is write only. We just assume the data is acked...
+ */
+static void lcdtg_ssp_i2c_send(u8 data)
+{
+	lcdtg_ssp_send(POWERREG0_ADRS, data);
+	udelay(10);
+}
+
+static void lcdtg_i2c_send_bit(u8 data)
+{
+	lcdtg_ssp_i2c_send(data);
+	lcdtg_ssp_i2c_send(data | POWER0_COM_DCLK);
+	lcdtg_ssp_i2c_send(data);
+}
+
+static void lcdtg_i2c_send_start(u8 base)
+{
+	lcdtg_ssp_i2c_send(base | POWER0_COM_DCLK | POWER0_COM_DOUT);
+	lcdtg_ssp_i2c_send(base | POWER0_COM_DCLK);
+	lcdtg_ssp_i2c_send(base);
+}
+
+static void lcdtg_i2c_send_stop(u8 base)
+{
+	lcdtg_ssp_i2c_send(base);
+	lcdtg_ssp_i2c_send(base | POWER0_COM_DCLK);
+	lcdtg_ssp_i2c_send(base | POWER0_COM_DCLK | POWER0_COM_DOUT);
+}
+
+static void lcdtg_i2c_send_byte(u8 base, u8 data)
+{
+	int i;
+	for (i = 0; i < 8; i++) {
+		if (data & 0x80)
+			lcdtg_i2c_send_bit(base | POWER0_COM_DOUT);
+		else
+			lcdtg_i2c_send_bit(base);
+		data <<= 1;
+	}
+}
+
+static void lcdtg_i2c_wait_ack(u8 base)
+{
+	lcdtg_i2c_send_bit(base);
+}
+
+static void lcdtg_set_common_voltage(u8 base_data, u8 data)
+{
+	/* Set Common Voltage to M62332FP via I2C */
+	lcdtg_i2c_send_start(base_data);
+	lcdtg_i2c_send_byte(base_data, 0x9c);
+	lcdtg_i2c_wait_ack(base_data);
+	lcdtg_i2c_send_byte(base_data, 0x00);
+	lcdtg_i2c_wait_ack(base_data);
+	lcdtg_i2c_send_byte(base_data, data);
+	lcdtg_i2c_wait_ack(base_data);
+	lcdtg_i2c_send_stop(base_data);
+}
+
+static struct lcdtg_register_setting {
+	u8 adrs;
+	u8 data;
+	u32 wait;
+} lcdtg_power_on_table[] = {
+
+    /* Initialize Internal Logic & Port */
+    { PICTRL_ADRS,
+      PICTRL_POWER_DOWN | PICTRL_INIOFF | PICTRL_INIT_STATE |
+      PICTRL_COM_SIGNAL_OFF | PICTRL_DAC_SIGNAL_OFF,
+      0 },
+
+    { POWERREG0_ADRS,
+      POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_OFF | POWER0_COM_OFF |
+      POWER0_VCC5_OFF,
+      0 },
+
+    { POWERREG1_ADRS,
+      POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_OFF,
+      0 },
+
+    /* VDD(+8V),SVSS(-4V) ON */
+    { POWERREG1_ADRS,
+      POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_ON /* VDD ON */,
+      3000 },
+
+    /* DAC ON */
+    { POWERREG0_ADRS,
+      POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_ON /* DAC ON */ |
+      POWER0_COM_OFF | POWER0_VCC5_OFF,
+      0 },
+
+    /* INIB = H, INI = L  */
+    { PICTRL_ADRS,
+      /* PICTL[0] = H , PICTL[1] = PICTL[2] = PICTL[4] = L */
+      PICTRL_INIT_STATE | PICTRL_COM_SIGNAL_OFF,
+      0 },
+
+    /* Set Common Voltage */
+    { 0xfe, 0, 0 },
+
+    /* VCC5 ON */
+    { POWERREG0_ADRS,
+      POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_ON /* DAC ON */ |
+      POWER0_COM_OFF | POWER0_VCC5_ON /* VCC5 ON */,
+      0 },
+
+    /* GVSS(-8V) ON */
+    { POWERREG1_ADRS,
+      POWER1_VW_OFF | POWER1_GVSS_ON /* GVSS ON */ |
+      POWER1_VDD_ON /* VDD ON */,
+      2000 },
+
+    /* COM SIGNAL ON (PICTL[3] = L) */
+    { PICTRL_ADRS,
+      PICTRL_INIT_STATE,
+      0 },
+
+    /* COM ON */
+    { POWERREG0_ADRS,
+      POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_ON /* DAC ON */ |
+      POWER0_COM_ON /* COM ON */ | POWER0_VCC5_ON /* VCC5_ON */,
+      0 },
+
+    /* VW ON */
+    { POWERREG1_ADRS,
+      POWER1_VW_ON /* VW ON */ | POWER1_GVSS_ON /* GVSS ON */ |
+      POWER1_VDD_ON /* VDD ON */,
+      0 /* Wait 100ms */ },
+
+    /* Signals output enable */
+    { PICTRL_ADRS,
+      0 /* Signals output enable */,
+      0 },
+
+    { PHACTRL_ADRS,
+      PHACTRL_PHASE_MANUAL,
+      0 },
+
+    /* Initialize for Input Signals from ATI */
+    { POLCTRL_ADRS,
+      POLCTRL_SYNC_POL_RISE | POLCTRL_EN_POL_RISE | POLCTRL_DATA_POL_RISE |
+      POLCTRL_SYNC_ACT_L | POLCTRL_EN_ACT_H,
+      1000 /*100000*/ /* Wait 100ms */ },
+
+    /* end mark */
+    { 0xff, 0, 0 }
+};
+
+static void lcdtg_resume(void)
+{
+	if (current_par->lcdMode == LCD_MODE_480 || current_par->lcdMode == LCD_MODE_640) {
+		lcdtg_hw_init(LCD_SHARP_VGA);
+	} else {
+		lcdtg_hw_init(LCD_SHARP_QVGA);
+	}
+}
+
+static void lcdtg_suspend(void)
+{
+	int i;
+
+	for (i = 0; i < (current_par->xres * current_par->yres); i++) {
+		writew(0xffff, remapped_fbuf + (2*i));
+	}
+
+	/* 60Hz x 2 frame = 16.7msec x 2 = 33.4 msec */
+	mdelay(34);
+
+	/* (1)VW OFF */
+	lcdtg_ssp_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_ON | POWER1_VDD_ON);
+
+	/* (2)COM OFF */
+	lcdtg_ssp_send(PICTRL_ADRS, PICTRL_COM_SIGNAL_OFF);
+	lcdtg_ssp_send(POWERREG0_ADRS, POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_ON);
+
+	/* (3)Set Common Voltage Bias 0V */
+	lcdtg_set_common_voltage(POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_ON, 0);
+
+	/* (4)GVSS OFF */
+	lcdtg_ssp_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_ON);
+
+	/* (5)VCC5 OFF */
+	lcdtg_ssp_send(POWERREG0_ADRS, POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_OFF);
+
+	/* (6)Set PDWN, INIOFF, DACOFF */
+	lcdtg_ssp_send(PICTRL_ADRS, PICTRL_INIOFF | PICTRL_DAC_SIGNAL_OFF |
+			PICTRL_POWER_DOWN | PICTRL_COM_SIGNAL_OFF);
+
+	/* (7)DAC OFF */
+	lcdtg_ssp_send(POWERREG0_ADRS, POWER0_DAC_OFF | POWER0_COM_OFF | POWER0_VCC5_OFF);
+
+	/* (8)VDD OFF */
+	lcdtg_ssp_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_OFF);
+
+}
+
+static void lcdtg_set_phadadj(u32 mode)
+{
+	int adj;
+
+	if (mode == LCD_SHARP_VGA) {
+		/* Setting for VGA */
+		adj = current_par->phadadj;
+		if (adj < 0) {
+			adj = PHACTRL_PHASE_MANUAL;
+		} else {
+			adj = ((adj & 0x0f) << 1) | PHACTRL_PHASE_MANUAL;
+		}
+	} else {
+		/* Setting for QVGA */
+		adj = (PHAD_QVGA_DEFAULT_VAL << 1) | PHACTRL_PHASE_MANUAL;
+	}
+	lcdtg_ssp_send(PHACTRL_ADRS, adj);
+}
+
+static void lcdtg_hw_init(u32 mode)
+{
+	int i;
+	int comadj;
+
+	i = 0;
+	while(lcdtg_power_on_table[i].adrs != 0xff) {
+		if (lcdtg_power_on_table[i].adrs == 0xfe) {
+			/* Set Common Voltage */
+			comadj = current_par->comadj;
+			if (comadj < 0) {
+				comadj = COMADJ_DEFAULT;
+			}
+			lcdtg_set_common_voltage((POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_OFF), comadj);
+		} else if (lcdtg_power_on_table[i].adrs == PHACTRL_ADRS) {
+			/* Set Phase Adjuct */
+			lcdtg_set_phadadj(mode);
+		} else {
+			/* Other */
+			lcdtg_ssp_send(lcdtg_power_on_table[i].adrs, lcdtg_power_on_table[i].data);
+		}
+		if (lcdtg_power_on_table[i].wait != 0)
+			udelay(lcdtg_power_on_table[i].wait);
+		i++;
+	}
+
+	switch(mode) {
+	case LCD_SHARP_QVGA:
+		/* Set Lcd Resolution (QVGA) */
+		lcdtg_ssp_send(RESCTL_ADRS, RESCTL_QVGA);
+		break;
+	case LCD_SHARP_VGA:
+		/* Set Lcd Resolution (VGA) */
+		lcdtg_ssp_send(RESCTL_ADRS, RESCTL_VGA);
+		break;
+	default:
+		break;
+	}
+}
+
+static void lcdtg_lcd_change(u32 mode)
+{
+	/* Set Phase Adjuct */
+	lcdtg_set_phadadj(mode);
+
+	if (mode == LCD_SHARP_VGA)
+		/* Set Lcd Resolution (VGA) */
+		lcdtg_ssp_send(RESCTL_ADRS, RESCTL_VGA);
+	else if (mode == LCD_SHARP_QVGA)
+		/* Set Lcd Resolution (QVGA) */
+		lcdtg_ssp_send(RESCTL_ADRS, RESCTL_QVGA);
+}
+
+
+static struct device_driver w100fb_driver = {
+	.name		= "w100fb",
+	.bus		= &platform_bus_type,
+	.probe		= w100fb_probe,
+	.remove		= w100fb_remove,
+	.suspend	= w100fb_suspend,
+	.resume		= w100fb_resume,
+};
+
+int __devinit w100fb_init(void)
+{
+	return driver_register(&w100fb_driver);
+}
+
+void __exit w100fb_cleanup(void)
+{
+ 	driver_unregister(&w100fb_driver);
+}
+
+module_init(w100fb_init);
+module_exit(w100fb_cleanup);
+
+MODULE_DESCRIPTION("ATI Imageon w100 framebuffer driver");
+MODULE_LICENSE("GPLv2");
diff -Nru a/drivers/video/w100fb.h b/drivers/video/w100fb.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/video/w100fb.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,615 @@
+/*
+ * linux/drivers/video/w100fb.h
+ *
+ * Frame Buffer Device for ATI w100 (Wallaby)
+ *
+ * Copyright (C) 2002, ATI Corp.
+ * Copyright (C) 2004-2005 Richard Purdie
+ *
+ * Modified to work with 2.6 by Richard Purdie <rpurdie@rpsys.net>
+ *
+ * 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.
+ *
+ */
+
+#if !defined (_W100FB_H)
+#define _W100FB_H
+
+/* Block CIF Start: */
+#define mmCHIP_ID           0x0000
+#define mmREVISION_ID		0x0004
+#define mmWRAP_BUF_A        0x0008
+#define mmWRAP_BUF_B        0x000C
+#define mmWRAP_TOP_DIR      0x0010
+#define mmWRAP_START_DIR    0x0014
+#define mmCIF_CNTL          0x0018
+#define mmCFGREG_BASE       0x001C
+#define mmCIF_IO            0x0020
+#define mmCIF_READ_DBG      0x0024
+#define mmCIF_WRITE_DBG     0x0028
+#define cfgIND_ADDR_A_0     0x0000
+#define cfgIND_ADDR_A_1     0x0001
+#define cfgIND_ADDR_A_2     0x0002
+#define cfgIND_DATA_A       0x0003
+#define cfgREG_BASE         0x0004
+#define cfgINTF_CNTL        0x0005
+#define cfgSTATUS           0x0006
+#define cfgCPU_DEFAULTS     0x0007
+#define cfgIND_ADDR_B_0     0x0008
+#define cfgIND_ADDR_B_1     0x0009
+#define cfgIND_ADDR_B_2     0x000A
+#define cfgIND_DATA_B       0x000B
+#define cfgPM4_RPTR         0x000C
+#define cfgSCRATCH          0x000D
+#define cfgPM4_WRPTR_0      0x000E
+#define cfgPM4_WRPTR_1      0x000F
+/* Block CIF End: */
+
+/* Block CP Start: */
+#define mmSCRATCH_UMSK      0x0280
+#define mmSCRATCH_ADDR      0x0284
+#define mmGEN_INT_CNTL      0x0200
+#define mmGEN_INT_STATUS    0x0204
+/* Block CP End: */
+
+/* Block DISPLAY Start: */
+#define mmLCD_FORMAT        0x0410
+#define mmGRAPHIC_CTRL      0x0414
+#define mmGRAPHIC_OFFSET    0x0418
+#define mmGRAPHIC_PITCH     0x041C
+#define mmCRTC_TOTAL        0x0420
+#define mmACTIVE_H_DISP     0x0424
+#define mmACTIVE_V_DISP     0x0428
+#define mmGRAPHIC_H_DISP    0x042C
+#define mmGRAPHIC_V_DISP    0x0430
+#define mmVIDEO_CTRL        0x0434
+#define mmGRAPHIC_KEY       0x0438
+#define mmBRIGHTNESS_CNTL   0x045C
+#define mmDISP_INT_CNTL     0x0488
+#define mmCRTC_SS           0x048C
+#define mmCRTC_LS           0x0490
+#define mmCRTC_REV          0x0494
+#define mmCRTC_DCLK         0x049C
+#define mmCRTC_GS           0x04A0
+#define mmCRTC_VPOS_GS      0x04A4
+#define mmCRTC_GCLK         0x04A8
+#define mmCRTC_GOE          0x04AC
+#define mmCRTC_FRAME        0x04B0
+#define mmCRTC_FRAME_VPOS   0x04B4
+#define mmGPIO_DATA         0x04B8
+#define mmGPIO_CNTL1        0x04BC
+#define mmGPIO_CNTL2        0x04C0
+#define mmLCDD_CNTL1        0x04C4
+#define mmLCDD_CNTL2        0x04C8
+#define mmGENLCD_CNTL1      0x04CC
+#define mmGENLCD_CNTL2      0x04D0
+#define mmDISP_DEBUG        0x04D4
+#define mmDISP_DB_BUF_CNTL  0x04D8
+#define mmDISP_CRC_SIG      0x04DC
+#define mmCRTC_DEFAULT_COUNT 	0x04E0
+#define mmLCD_BACKGROUND_COLOR  0x04E4
+#define mmCRTC_PS2          0x04E8
+#define mmCRTC_PS2_VPOS     0x04EC
+#define mmCRTC_PS1_ACTIVE   0x04F0
+#define mmCRTC_PS1_NACTIVE  0x04F4
+#define mmCRTC_GCLK_EXT     0x04F8
+#define mmCRTC_ALW          0x04FC
+#define mmCRTC_ALW_VPOS     0x0500
+#define mmCRTC_PSK          0x0504
+#define mmCRTC_PSK_HPOS     0x0508
+#define mmCRTC_CV4_START    0x050C
+#define mmCRTC_CV4_END      0x0510
+#define mmCRTC_CV4_HPOS     0x0514
+#define mmCRTC_ECK          0x051C
+#define mmREFRESH_CNTL      0x0520
+#define mmGENLCD_CNTL3      0x0524
+#define mmGPIO_DATA2        0x0528
+#define mmGPIO_CNTL3        0x052C
+#define mmGPIO_CNTL4        0x0530
+#define mmCHIP_STRAP        0x0534
+#define mmDISP_DEBUG2       0x0538
+#define mmDEBUG_BUS_CNTL    0x053C
+#define mmGAMMA_VALUE1      0x0540
+#define mmGAMMA_VALUE2      0x0544
+#define mmGAMMA_SLOPE       0x0548
+#define mmGEN_STATUS        0x054C
+#define mmHW_INT            0x0550
+/* Block DISPLAY End: */
+
+/* Block GFX Start: */
+#define mmBRUSH_OFFSET      0x108C
+#define mmBRUSH_Y_X         0x1074
+#define mmDEFAULT_PITCH_OFFSET		0x10A0
+#define mmDEFAULT_SC_BOTTOM_RIGHT	0x10A8
+#define mmDEFAULT2_SC_BOTTOM_RIGHT	0x10AC
+#define mmGLOBAL_ALPHA      0x1210
+#define mmFILTER_COEF       0x1214
+#define mmMVC_CNTL_START    0x11E0
+#define mmE2_ARITHMETIC_CNTL	0x1220
+#define mmENG_CNTL          0x13E8
+#define mmENG_PERF_CNT      0x13F0
+/* Block GFX End: */
+
+/* Block IDCT Start: */
+#define mmIDCT_RUNS         0x0C00
+#define mmIDCT_LEVELS       0x0C04
+#define mmIDCT_CONTROL      0x0C3C
+#define mmIDCT_AUTH_CONTROL 0x0C08
+#define mmIDCT_AUTH         0x0C0C
+/* Block IDCT End: */
+
+/* Block MC Start: */
+#define mmMEM_CNTL          0x0180
+#define mmMEM_ARB           0x0184
+#define mmMC_FB_LOCATION    0x0188
+#define mmMEM_EXT_CNTL      0x018C
+#define mmMC_EXT_MEM_LOCATION   0x0190
+#define mmMEM_EXT_TIMING_CNTL   0x0194
+#define mmMEM_SDRAM_MODE_REG	0x0198
+#define mmMEM_IO_CNTL       0x019C
+#define mmMC_DEBUG          0x01A0
+#define mmMC_BIST_CTRL      0x01A4
+#define mmMC_BIST_COLLAR_READ  	0x01A8
+#define mmTC_MISMATCH       0x01AC
+#define mmMC_PERF_MON_CNTL  0x01B0
+#define mmMC_PERF_COUNTERS  0x01B4
+/* Block MC End: */
+
+/* Block RBBM Start: */
+#define mmWAIT_UNTIL        0x1400
+#define mmISYNC_CNTL        0x1404
+#define mmRBBM_CNTL         0x0144
+#define mmNQWAIT_UNTIL      0x0150
+/* Block RBBM End: */
+
+/* Block CG Start: */
+#define mmCLK_PIN_CNTL      0x0080
+#define mmPLL_REF_FB_DIV    0x0084
+#define mmPLL_CNTL          0x0088
+#define mmSCLK_CNTL         0x008C
+#define mmPCLK_CNTL         0x0090
+#define mmCLK_TEST_CNTL     0x0094
+#define mmPWRMGT_CNTL       0x0098
+#define mmPWRMGT_STATUS     0x009C
+/* Block CG End: */
+
+/* default value definitions */
+#define defWRAP_TOP_DIR     0x00000000
+#define defWRAP_START_DIR	0x00000000
+#define defCFGREG_BASE      0x00000000
+#define defCIF_IO           0x000C0902
+#define defINTF_CNTL        0x00000011
+#define defCPU_DEFAULTS     0x00000006
+#define defHW_INT           0x00000000
+#define defMC_EXT_MEM_LOCATION            0x07ff0000
+#define defTC_MISMATCH      0x00000000
+
+#define W100_CFG_BASE          0x0
+#define W100_CFG_LEN           0x10
+#define W100_REG_BASE          0x10000
+#define W100_REG_LEN           0x2000
+#define MEM_INT_BASE_VALUE     0x100000
+#define MEM_INT_TOP_VALUE_W100 0x15ffff
+#define MEM_EXT_BASE_VALUE     0x800000
+#define MEM_EXT_TOP_VALUE      0x9fffff
+#define WRAP_BUF_BASE_VALUE    0x80000
+#define WRAP_BUF_TOP_VALUE     0xbffff
+
+
+/* data structure definitions */
+
+struct wrap_top_dir_t {
+     unsigned long top_addr         : 23;
+     unsigned long    				: 9;
+} __attribute__((packed));
+
+union wrap_top_dir_u {
+     unsigned long val : 32;
+     struct wrap_top_dir_t f;
+} __attribute__((packed));
+
+struct wrap_start_dir_t {
+     unsigned long start_addr       : 23;
+     unsigned long    				: 9;
+} __attribute__((packed));
+
+union wrap_start_dir_u {
+     unsigned long val : 32;
+     struct wrap_start_dir_t f;
+} __attribute__((packed));
+
+struct cif_cntl_t {
+     unsigned long swap_reg         		: 2;
+     unsigned long swap_fbuf_1      		: 2;
+     unsigned long swap_fbuf_2      		: 2;
+     unsigned long swap_fbuf_3      		: 2;
+     unsigned long pmi_int_disable  		: 1;
+     unsigned long pmi_schmen_disable       : 1;
+     unsigned long intb_oe          		: 1;
+     unsigned long en_wait_to_compensate_dq_prop_dly : 1;
+     unsigned long compensate_wait_rd_size  : 2;
+     unsigned long wait_asserted_timeout_val      : 2;
+     unsigned long wait_masked_val  		: 2;
+     unsigned long en_wait_timeout  		: 1;
+     unsigned long en_one_clk_setup_before_wait   : 1;
+     unsigned long interrupt_active_high    : 1;
+     unsigned long en_overwrite_straps      : 1;
+     unsigned long strap_wait_active_hi     : 1;
+     unsigned long lat_busy_count   		: 2;
+     unsigned long lat_rd_pm4_sclk_busy     : 1;
+     unsigned long dis_system_bits  		: 1;
+     unsigned long dis_mr           		: 1;
+     unsigned long cif_spare_1      		: 4;
+} __attribute__((packed));
+
+union cif_cntl_u {
+     unsigned long val : 32;
+     struct cif_cntl_t f;
+} __attribute__((packed));
+
+struct cfgreg_base_t {
+     unsigned long cfgreg_base      : 24;
+     unsigned long    				: 8;
+} __attribute__((packed));
+
+union cfgreg_base_u {
+     unsigned long val : 32;
+     struct cfgreg_base_t f;
+} __attribute__((packed));
+
+struct cif_io_t {
+     unsigned long dq_srp           : 1;
+     unsigned long dq_srn           : 1;
+     unsigned long dq_sp            : 4;
+     unsigned long dq_sn            : 4;
+     unsigned long waitb_srp        : 1;
+     unsigned long waitb_srn        : 1;
+     unsigned long waitb_sp         : 4;
+     unsigned long waitb_sn         : 4;
+     unsigned long intb_srp         : 1;
+     unsigned long intb_srn         : 1;
+     unsigned long intb_sp          : 4;
+     unsigned long intb_sn          : 4;
+     unsigned long    				: 2;
+} __attribute__((packed));
+
+union cif_io_u {
+     unsigned long val : 32;
+     struct cif_io_t f;
+} __attribute__((packed));
+
+struct cif_read_dbg_t {
+     unsigned long unpacker_pre_fetch_trig_gen  : 2;
+     unsigned long dly_second_rd_fetch_trig     : 1;
+     unsigned long rst_rd_burst_id  			: 1;
+     unsigned long dis_rd_burst_id  			: 1;
+     unsigned long en_block_rd_when_packer_is_not_emp : 1;
+     unsigned long dis_pre_fetch_cntl_sm        : 1;
+     unsigned long rbbm_chrncy_dis  			: 1;
+     unsigned long rbbm_rd_after_wr_lat         : 2;
+     unsigned long dis_be_during_rd 			: 1;
+     unsigned long one_clk_invalidate_pulse     : 1;
+     unsigned long dis_chnl_priority			: 1;
+     unsigned long rst_read_path_a_pls          : 1;
+     unsigned long rst_read_path_b_pls          : 1;
+     unsigned long dis_reg_rd_fetch_trig        : 1;
+     unsigned long dis_rd_fetch_trig_from_ind_addr : 1;
+     unsigned long dis_rd_same_byte_to_trig_fetch : 1;
+     unsigned long dis_dir_wrap     			: 1;
+     unsigned long dis_ring_buf_to_force_dec    : 1;
+     unsigned long dis_addr_comp_in_16bit       : 1;
+     unsigned long clr_w            			: 1;
+     unsigned long err_rd_tag_is_3  			: 1;
+     unsigned long err_load_when_ful_a          : 1;
+     unsigned long err_load_when_ful_b          : 1;
+     unsigned long    							: 7;
+} __attribute__((packed));
+
+union cif_read_dbg_u {
+     unsigned long val : 32;
+     struct cif_read_dbg_t f;
+} __attribute__((packed));
+
+struct cif_write_dbg_t {
+     unsigned long packer_timeout_count           : 2;
+     unsigned long en_upper_load_cond             : 1;
+     unsigned long en_chnl_change_cond            : 1;
+     unsigned long dis_addr_comp_cond             : 1;
+     unsigned long dis_load_same_byte_addr_cond   : 1;
+     unsigned long dis_timeout_cond 			  : 1;
+     unsigned long dis_timeout_during_rbbm        : 1;
+     unsigned long dis_packer_ful_during_rbbm_timeout : 1;
+     unsigned long en_dword_split_to_rbbm         : 1;
+     unsigned long en_dummy_val     			  : 1;
+     unsigned long dummy_val_sel    			  : 1;
+     unsigned long mask_pm4_wrptr_dec             : 1;
+     unsigned long dis_mc_clean_cond			  : 1;
+     unsigned long err_two_reqi_during_ful        : 1;
+     unsigned long err_reqi_during_idle_clk       : 1;
+     unsigned long err_global       			  : 1;
+     unsigned long en_wr_buf_dbg_load             : 1;
+     unsigned long en_wr_buf_dbg_path             : 1;
+     unsigned long sel_wr_buf_byte  			  : 3;
+     unsigned long dis_rd_flush_wr  			  : 1;
+     unsigned long dis_packer_ful_cond            : 1;
+     unsigned long dis_invalidate_by_ops_chnl     : 1;
+     unsigned long en_halt_when_reqi_err          : 1;
+     unsigned long cif_spare_2      			  : 5;
+     unsigned long    							  : 1;
+} __attribute__((packed));
+
+union cif_write_dbg_u {
+     unsigned long val : 32;
+     struct cif_write_dbg_t f;
+} __attribute__((packed));
+
+
+struct intf_cntl_t {
+     unsigned char ad_inc_a            : 1;
+     unsigned char ring_buf_a          : 1;
+     unsigned char rd_fetch_trigger_a  : 1;
+     unsigned char rd_data_rdy_a       : 1;
+     unsigned char ad_inc_b            : 1;
+     unsigned char ring_buf_b          : 1;
+     unsigned char rd_fetch_trigger_b  : 1;
+     unsigned char rd_data_rdy_b       : 1;
+} __attribute__((packed));
+
+union intf_cntl_u {
+     unsigned char val : 8;
+     struct intf_cntl_t f;
+} __attribute__((packed));
+
+struct cpu_defaults_t {
+     unsigned char unpack_rd_data   : 1;
+     unsigned char access_ind_addr_a: 1;
+     unsigned char access_ind_addr_b: 1;
+     unsigned char access_scratch_reg             : 1;
+     unsigned char pack_wr_data     : 1;
+     unsigned char transition_size  : 1;
+     unsigned char en_read_buf_mode : 1;
+     unsigned char rd_fetch_scratch : 1;
+} __attribute__((packed));
+
+union cpu_defaults_u {
+     unsigned char val : 8;
+     struct cpu_defaults_t f;
+} __attribute__((packed));
+
+struct video_ctrl_t {
+     unsigned long video_mode       : 1;
+     unsigned long keyer_en         : 1;
+     unsigned long en_video_req     : 1;
+     unsigned long en_graphic_req_video           : 1;
+     unsigned long en_video_crtc    : 1;
+     unsigned long video_hor_exp    : 2;
+     unsigned long video_ver_exp    : 2;
+     unsigned long uv_combine       : 1;
+     unsigned long total_req_video  : 9;
+     unsigned long video_ch_sel     : 1;
+     unsigned long video_portrait   : 2;
+     unsigned long yuv2rgb_en       : 1;
+     unsigned long yuv2rgb_option   : 1;
+     unsigned long video_inv_hor    : 1;
+     unsigned long video_inv_ver    : 1;
+     unsigned long gamma_sel        : 2;
+     unsigned long dis_limit        : 1;
+     unsigned long en_uv_hblend     : 1;
+     unsigned long rgb_gamma_sel    : 2;
+} __attribute__((packed));
+
+union video_ctrl_u {
+     unsigned long val : 32;
+     struct video_ctrl_t f;
+} __attribute__((packed));
+
+struct disp_db_buf_cntl_rd_t {
+     unsigned long en_db_buf        	: 1;
+     unsigned long update_db_buf_done   : 1;
+     unsigned long db_buf_cntl      	: 6;
+     unsigned long    					: 24;
+} __attribute__((packed));
+
+union disp_db_buf_cntl_rd_u {
+     unsigned long val : 32;
+     struct disp_db_buf_cntl_rd_t f;
+} __attribute__((packed));
+
+struct disp_db_buf_cntl_wr_t {
+     unsigned long en_db_buf        : 1;
+     unsigned long update_db_buf    : 1;
+     unsigned long db_buf_cntl      : 6;
+     unsigned long    : 24;
+} __attribute__((packed));
+
+union disp_db_buf_cntl_wr_u {
+     unsigned long val : 32;
+     struct disp_db_buf_cntl_wr_t f;
+} __attribute__((packed));
+
+struct gamma_value1_t {
+     unsigned long gamma1           : 8;
+     unsigned long gamma2           : 8;
+     unsigned long gamma3           : 8;
+     unsigned long gamma4           : 8;
+} __attribute__((packed));
+
+union gamma_value1_u {
+     unsigned long val : 32;
+     struct gamma_value1_t f;
+} __attribute__((packed));
+
+struct gamma_value2_t {
+     unsigned long gamma5           : 8;
+     unsigned long gamma6           : 8;
+     unsigned long gamma7           : 8;
+     unsigned long gamma8           : 8;
+} __attribute__((packed));
+
+union gamma_value2_u {
+     unsigned long val : 32;
+     struct gamma_value2_t f;
+} __attribute__((packed));
+
+struct gamma_slope_t {
+     unsigned long slope1           : 3;
+     unsigned long slope2           : 3;
+     unsigned long slope3           : 3;
+     unsigned long slope4           : 3;
+     unsigned long slope5           : 3;
+     unsigned long slope6           : 3;
+     unsigned long slope7           : 3;
+     unsigned long slope8           : 3;
+     unsigned long    				: 8;
+} __attribute__((packed));
+
+union gamma_slope_u {
+     unsigned long val : 32;
+     struct gamma_slope_t f;
+} __attribute__((packed));
+
+struct mc_ext_mem_location_t {
+     unsigned long mc_ext_mem_start : 16;
+     unsigned long mc_ext_mem_top   : 16;
+} __attribute__((packed));
+
+union mc_ext_mem_location_u {
+     unsigned long val : 32;
+     struct mc_ext_mem_location_t f;
+} __attribute__((packed));
+
+struct clk_pin_cntl_t {
+     unsigned long osc_en           : 1;
+     unsigned long osc_gain         : 5;
+     unsigned long dont_use_xtalin  : 1;
+     unsigned long xtalin_pm_en     : 1;
+     unsigned long xtalin_dbl_en    : 1;
+     unsigned long    				: 7;
+     unsigned long cg_debug         : 16;
+} __attribute__((packed));
+
+union clk_pin_cntl_u {
+     unsigned long val : 32;
+     struct clk_pin_cntl_t f;
+} __attribute__((packed));
+
+struct pll_ref_fb_div_t {
+     unsigned long pll_ref_div      : 4;
+     unsigned long    				: 4;
+     unsigned long pll_fb_div_int   : 6;
+     unsigned long    				: 2;
+     unsigned long pll_fb_div_frac  : 3;
+     unsigned long    				: 1;
+     unsigned long pll_reset_time   : 4;
+     unsigned long pll_lock_time    : 8;
+} __attribute__((packed));
+
+union pll_ref_fb_div_u {
+     unsigned long val : 32;
+     struct pll_ref_fb_div_t f;
+} __attribute__((packed));
+
+struct pll_cntl_t {
+     unsigned long pll_pwdn         : 1;
+     unsigned long pll_reset        : 1;
+     unsigned long pll_pm_en        : 1;
+     unsigned long pll_mode         : 1;
+     unsigned long pll_refclk_sel   : 1;
+     unsigned long pll_fbclk_sel    : 1;
+     unsigned long pll_tcpoff       : 1;
+     unsigned long pll_pcp          : 3;
+     unsigned long pll_pvg          : 3;
+     unsigned long pll_vcofr        : 1;
+     unsigned long pll_ioffset      : 2;
+     unsigned long pll_pecc_mode    : 2;
+     unsigned long pll_pecc_scon    : 2;
+     unsigned long pll_dactal       : 4;
+     unsigned long pll_cp_clip      : 2;
+     unsigned long pll_conf         : 3;
+     unsigned long pll_mbctrl       : 2;
+     unsigned long pll_ring_off     : 1;
+} __attribute__((packed));
+
+union pll_cntl_u {
+     unsigned long val : 32;
+     struct pll_cntl_t f;
+} __attribute__((packed));
+
+struct sclk_cntl_t {
+     unsigned long sclk_src_sel     	: 2;
+     unsigned long    					: 2;
+     unsigned long sclk_post_div_fast   : 4;
+     unsigned long sclk_clkon_hys   	: 3;
+     unsigned long sclk_post_div_slow   : 4;
+     unsigned long disp_cg_ok2switch_en : 1;
+     unsigned long sclk_force_reg   	: 1;
+     unsigned long sclk_force_disp  	: 1;
+     unsigned long sclk_force_mc    	: 1;
+     unsigned long sclk_force_extmc 	: 1;
+     unsigned long sclk_force_cp    	: 1;
+     unsigned long sclk_force_e2    	: 1;
+     unsigned long sclk_force_e3    	: 1;
+     unsigned long sclk_force_idct  	: 1;
+     unsigned long sclk_force_bist  	: 1;
+     unsigned long busy_extend_cp   	: 1;
+     unsigned long busy_extend_e2   	: 1;
+     unsigned long busy_extend_e3   	: 1;
+     unsigned long busy_extend_idct 	: 1;
+     unsigned long    					: 3;
+} __attribute__((packed));
+
+union sclk_cntl_u {
+     unsigned long val : 32;
+     struct sclk_cntl_t f;
+} __attribute__((packed));
+
+struct pclk_cntl_t {
+     unsigned long pclk_src_sel     : 2;
+     unsigned long    				: 2;
+     unsigned long pclk_post_div    : 4;
+     unsigned long    				: 8;
+     unsigned long pclk_force_disp  : 1;
+     unsigned long    				: 15;
+} __attribute__((packed));
+
+union pclk_cntl_u {
+     unsigned long val : 32;
+     struct pclk_cntl_t f;
+} __attribute__((packed));
+
+struct clk_test_cntl_t {
+     unsigned long testclk_sel      : 4;
+     unsigned long    				: 3;
+     unsigned long start_check_freq : 1;
+     unsigned long tstcount_rst     : 1;
+     unsigned long    				: 15;
+     unsigned long test_count       : 8;
+} __attribute__((packed));
+
+union clk_test_cntl_u {
+     unsigned long val : 32;
+     struct clk_test_cntl_t f;
+} __attribute__((packed));
+
+struct pwrmgt_cntl_t {
+     unsigned long pwm_enable       	: 1;
+     unsigned long    					: 1;
+     unsigned long pwm_mode_req         : 2;
+     unsigned long pwm_wakeup_cond      : 2;
+     unsigned long pwm_fast_noml_hw_en  : 1;
+     unsigned long pwm_noml_fast_hw_en  : 1;
+     unsigned long pwm_fast_noml_cond   : 4;
+     unsigned long pwm_noml_fast_cond   : 4;
+     unsigned long pwm_idle_timer   	: 8;
+     unsigned long pwm_busy_timer   	: 8;
+} __attribute__((packed));
+
+union pwrmgt_cntl_u {
+     unsigned long val : 32;
+     struct pwrmgt_cntl_t f;
+} __attribute__((packed));
+
+#endif
+
diff -Nru a/drivers/w1/dscore.c b/drivers/w1/dscore.c
--- a/drivers/w1/dscore.c	2005-03-01 23:39:17 -08:00
+++ b/drivers/w1/dscore.c	2005-03-01 23:39:17 -08:00
@@ -676,7 +676,7 @@
 		ds_dev->ep[i+1] = endpoint->bEndpointAddress;
 		
 		printk("%d: addr=%x, size=%d, dir=%s, type=%x\n",
-			i, endpoint->bEndpointAddress, endpoint->wMaxPacketSize,
+			i, endpoint->bEndpointAddress, le16_to_cpu(endpoint->wMaxPacketSize),
 			(endpoint->bEndpointAddress & USB_DIR_IN)?"IN":"OUT",
 			endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK);
 	}
diff -Nru a/drivers/w1/w1.c b/drivers/w1/w1.c
--- a/drivers/w1/w1.c	2005-03-01 23:38:55 -08:00
+++ b/drivers/w1/w1.c	2005-03-01 23:38:55 -08:00
@@ -32,7 +32,6 @@
 #include <linux/device.h>
 #include <linux/slab.h>
 #include <linux/sched.h>
-#include <linux/suspend.h>
 
 #include "w1.h"
 #include "w1_io.h"
@@ -53,7 +52,7 @@
 module_param_named(max_slave_count, w1_max_slave_count, int, 0);
 module_param_named(slave_ttl, w1_max_slave_ttl, int, 0);
 
-spinlock_t w1_mlock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(w1_mlock);
 LIST_HEAD(w1_masters);
 
 static pid_t control_thread;
@@ -468,17 +467,75 @@
 	w1_netlink_send(sl->master, &msg);
 }
 
-static void w1_search(struct w1_master *dev)
+static struct w1_master *w1_search_master(unsigned long data)
 {
-	u64 last, rn, tmp;
-	int i, count = 0, slave_count;
-	int last_family_desc, last_zero, last_device;
-	int search_bit, id_bit, comp_bit, desc_bit;
-	struct list_head *ent;
+	struct w1_master *dev;
+	int found = 0;
+	
+	spin_lock_irq(&w1_mlock);
+	list_for_each_entry(dev, &w1_masters, w1_master_entry) {
+		if (dev->bus_master->data == data) {
+			found = 1;
+			atomic_inc(&dev->refcnt);
+			break;
+		}
+	}
+	spin_unlock_irq(&w1_mlock);
+
+	return (found)?dev:NULL;
+}
+
+void w1_slave_found(unsigned long data, u64 rn)
+{
+	int slave_count;
 	struct w1_slave *sl;
+	struct list_head *ent;
+	struct w1_reg_num *tmp;
 	int family_found = 0;
+	struct w1_master *dev;
+
+	dev = w1_search_master(data);
+	if (!dev) {
+		printk(KERN_ERR "Failed to find w1 master device for data %08lx, it is impossible.\n",
+				data);
+		return;
+	}
+	
+	tmp = (struct w1_reg_num *) &rn;
+
+	slave_count = 0;
+	list_for_each(ent, &dev->slist) {
+
+		sl = list_entry(ent, struct w1_slave, w1_slave_entry);
+
+		if (sl->reg_num.family == tmp->family &&
+		    sl->reg_num.id == tmp->id &&
+		    sl->reg_num.crc == tmp->crc) {
+			set_bit(W1_SLAVE_ACTIVE, (long *)&sl->flags);
+			break;
+		}
+		else if (sl->reg_num.family == tmp->family) {
+			family_found = 1;
+			break;
+		}
 
-	dev->attempts++;
+		slave_count++;
+	}
+
+	if (slave_count == dev->slave_count &&
+		rn && ((rn >> 56) & 0xff) == w1_calc_crc8((u8 *)&rn, 7)) {
+		w1_attach_slave_device(dev, (struct w1_reg_num *) &rn);
+	}
+			
+	atomic_dec(&dev->refcnt);
+}
+
+void w1_search(struct w1_master *dev)
+{
+	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;
@@ -556,33 +613,8 @@
 			last_device = 1;
 
 		desc_bit = last_zero;
-
-		slave_count = 0;
-		list_for_each(ent, &dev->slist) {
-			struct w1_reg_num *tmp;
-
-			tmp = (struct w1_reg_num *) &rn;
-
-			sl = list_entry(ent, struct w1_slave, w1_slave_entry);
-
-			if (sl->reg_num.family == tmp->family &&
-			    sl->reg_num.id == tmp->id &&
-			    sl->reg_num.crc == tmp->crc) {
-				set_bit(W1_SLAVE_ACTIVE, (long *)&sl->flags);
-				break;
-			}
-			else if (sl->reg_num.family == tmp->family) {
-				family_found = 1;
-				break;
-			}
-
-			slave_count++;
-		}
-
-		if (slave_count == dev->slave_count &&
-			rn && ((rn >> 56) & 0xff) == w1_calc_crc8((u8 *)&rn, 7)) {
-			w1_attach_slave_device(dev, (struct w1_reg_num *) &rn);
-		}
+	
+		w1_slave_found(dev->bus_master->data, rn);
 	}
 }
 
@@ -628,8 +660,7 @@
 		timeout = w1_timeout*HZ;
 		do {
 			timeout = interruptible_sleep_on_timeout(&w1_control_wait, timeout);
-			if (current->flags & PF_FREEZE)
-				refrigerator(PF_FREEZE);
+			try_to_freeze(PF_FREEZE);
 		} while (!signal_pending(current) && (timeout > 0));
 
 		if (signal_pending(current))
@@ -701,8 +732,7 @@
 		timeout = w1_timeout*HZ;
 		do {
 			timeout = interruptible_sleep_on_timeout(&dev->kwait, timeout);
-			if (current->flags & PF_FREEZE)
-				refrigerator(PF_FREEZE);
+			try_to_freeze(PF_FREEZE);
 		} while (!signal_pending(current) && (timeout > 0));
 
 		if (signal_pending(current))
@@ -724,8 +754,8 @@
 				clear_bit(W1_SLAVE_ACTIVE, (long *)&sl->flags);
 		}
 		
-      		w1_search(dev);
-		
+		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);
 
diff -Nru a/drivers/w1/w1.h b/drivers/w1/w1.h
--- a/drivers/w1/w1.h	2005-03-01 23:39:18 -08:00
+++ b/drivers/w1/w1.h	2005-03-01 23:39:18 -08:00
@@ -74,6 +74,8 @@
 	struct device_attribute	attr_name, attr_val;
 };
 
+typedef void (* w1_slave_found_callback)(unsigned long, u64);
+
 struct w1_bus_master
 {
 	unsigned long		data;
@@ -90,6 +92,8 @@
   	u8			(*touch_bit)(unsigned long, u8);
   
   	u8			(*reset_bus)(unsigned long);
+
+	void			(*search)(unsigned long, w1_slave_found_callback);
 };
 
 struct w1_master
@@ -127,6 +131,7 @@
 
 int w1_create_master_attributes(struct w1_master *);
 void w1_destroy_master_attributes(struct w1_master *);
+void w1_search(struct w1_master *dev);
 
 #endif /* __KERNEL__ */
 
diff -Nru a/drivers/w1/w1_family.c b/drivers/w1/w1_family.c
--- a/drivers/w1/w1_family.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/w1/w1_family.c	2005-03-01 23:39:07 -08:00
@@ -25,7 +25,7 @@
 
 #include "w1_family.h"
 
-spinlock_t w1_flock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(w1_flock);
 static LIST_HEAD(w1_families);
 
 static int w1_check_family(struct w1_family *f)
diff -Nru a/drivers/w1/w1_io.c b/drivers/w1/w1_io.c
--- a/drivers/w1/w1_io.c	2005-03-01 23:39:07 -08:00
+++ b/drivers/w1/w1_io.c	2005-03-01 23:39:07 -08:00
@@ -174,6 +174,15 @@
 	return crc;
 }
 
+void w1_search_devices(struct w1_master *dev, w1_slave_found_callback cb)
+{
+	dev->attempts++;
+	if (dev->bus_master->search)
+		dev->bus_master->search(dev->bus_master->data, cb);
+	else
+		w1_search(dev);
+}
+
 EXPORT_SYMBOL(w1_write_bit);
 EXPORT_SYMBOL(w1_write_8);
 EXPORT_SYMBOL(w1_read_bit);
@@ -183,3 +192,4 @@
 EXPORT_SYMBOL(w1_delay);
 EXPORT_SYMBOL(w1_read_block);
 EXPORT_SYMBOL(w1_write_block);
+EXPORT_SYMBOL(w1_search_devices);
diff -Nru a/drivers/w1/w1_io.h b/drivers/w1/w1_io.h
--- a/drivers/w1/w1_io.h	2005-03-01 23:39:10 -08:00
+++ b/drivers/w1/w1_io.h	2005-03-01 23:39:10 -08:00
@@ -34,5 +34,6 @@
 u8 w1_calc_crc8(u8 *, int);
 void w1_write_block(struct w1_master *, u8 *, int);
 u8 w1_read_block(struct w1_master *, u8 *, int);
+void w1_search_devices(struct w1_master *dev, w1_slave_found_callback cb);
 
 #endif /* __W1_IO_H */
diff -Nru a/fs/Kconfig b/fs/Kconfig
--- a/fs/Kconfig	2005-03-01 23:38:58 -08:00
+++ b/fs/Kconfig	2005-03-01 23:38:58 -08:00
@@ -250,7 +250,7 @@
 	select NLS
 	help
 	  This is a port of IBM's Journaled Filesystem .  More information is
-	  available in the file Documentation/filesystems/jfs.txt.
+	  available in the file <file:Documentation/filesystems/jfs.txt>.
 
 	  If you do not intend to use the JFS filesystem, say N.
 
@@ -266,6 +266,18 @@
 
 	  If you don't know what Access Control Lists are, say N
 
+config JFS_SECURITY
+	bool "JFS Security Labels"
+	depends on JFS_FS
+	help
+	  Security labels support alternative access control models
+	  implemented by security modules like SELinux.  This option
+	  enables an extended attribute handler for file security
+	  labels in the jfs filesystem.
+
+	  If you are not using a security module that requires using
+	  extended attributes for file security labels, say N.
+
 config JFS_DEBUG
 	bool "JFS debugging"
 	depends on JFS_FS
@@ -292,82 +304,7 @@
 	depends on EXT2_FS_POSIX_ACL || EXT3_FS_POSIX_ACL || JFS_POSIX_ACL || REISERFS_FS_POSIX_ACL || NFSD_V4
 	default y
 
-config XFS_FS
-	tristate "XFS filesystem support"
-	help
-	  XFS is a high performance journaling filesystem which originated
-	  on the SGI IRIX platform.  It is completely multi-threaded, can
-	  support large files and large filesystems, extended attributes,
-	  variable block sizes, is extent based, and makes extensive use of
-	  Btrees (directories, extents, free space) to aid both performance
-	  and scalability.
-
-	  Refer to the documentation at <http://oss.sgi.com/projects/xfs/>
-	  for complete details.  This implementation is on-disk compatible
-	  with the IRIX version of XFS.
-
-	  To compile this file system support as a module, choose M here: the
-	  module will be called xfs.  Be aware, however, that if the file
-	  system of your root partition is compiled as a module, you'll need
-	  to use an initial ramdisk (initrd) to boot.
-
-config XFS_RT
-	bool "Realtime support (EXPERIMENTAL)"
-	depends on XFS_FS && EXPERIMENTAL
-	help
-	  If you say Y here you will be able to mount and use XFS filesystems
-	  which contain a realtime subvolume. The realtime subvolume is a
-	  separate area of disk space where only file data is stored. The
-	  realtime subvolume is designed to provide very deterministic
-	  data rates suitable for media streaming applications.
-
-	  See the xfs man page in section 5 for a bit more information.
-
-	  This feature is unsupported at this time, is not yet fully
-	  functional, and may cause serious problems.
-
-	  If unsure, say N.
-
-config XFS_QUOTA
-	bool "Quota support"
-	depends on XFS_FS
-	help
-	  If you say Y here, you will be able to set limits for disk usage on
-	  a per user and/or a per group basis under XFS.  XFS considers quota
-	  information as filesystem metadata and uses journaling to provide a
-	  higher level guarantee of consistency.  The on-disk data format for
-	  quota is also compatible with the IRIX version of XFS, allowing a
-	  filesystem to be migrated between Linux and IRIX without any need
-	  for conversion.
-
-	  If unsure, say N.  More comprehensive documentation can be found in
-	  README.quota in the xfsprogs package.  XFS quota can be used either
-	  with or without the generic quota support enabled (CONFIG_QUOTA) -
-	  they are completely independent subsystems.
-
-config XFS_SECURITY
-	bool "Security Label support"
-	depends on XFS_FS
-	help
-	  Security labels support alternative access control models
-	  implemented by security modules like SELinux.  This option
-	  enables an extended attribute namespace for inode security
-	  labels in the XFS filesystem.
-
-	  If you are not using a security module that requires using
-	  extended attributes for inode security labels, say N.
-
-config XFS_POSIX_ACL
-	bool "POSIX ACL support"
-	depends on XFS_FS
-	help
-	  POSIX Access Control Lists (ACLs) support permissions for users and
-	  groups beyond the owner/group/world scheme.
-
-	  To learn more about Access Control Lists, visit the POSIX ACLs for
-	  Linux website <http://acl.bestbits.at/>.
-
-	  If you don't know what Access Control Lists are, say N.
+source "fs/xfs/Kconfig"
 
 config MINIX_FS
 	tristate "Minix fs support"
@@ -566,9 +503,8 @@
 	tristate
 	select NLS
 	help
-	  If you want to use one of the FAT-based file systems (the MS-DOS,
-	  VFAT (Windows 95) and UMSDOS (used to run Linux on top of an
-	  ordinary DOS partition) file systems), then you must say Y or M here
+	  If you want to use one of the FAT-based file systems (the MS-DOS and
+	  VFAT (Windows 95) file systems), then you must say Y or M here
 	  to include FAT support. You will then be able to mount partitions or
 	  diskettes with FAT-based file systems and transparently access the
 	  files on them, i.e. MSDOS files will look and behave just like all
@@ -600,9 +536,6 @@
 	  fat.  Note that if you compile the FAT support as a module, you
 	  cannot compile any of the FAT-based file systems into the kernel
 	  -- they will have to be modules as well.
-	  The file system of your root partition (the one containing the
-	  directory /) cannot be a module, so don't say M here if you intend
-	  to use UMSDOS as your root file system.
 
 config MSDOS_FS
 	tristate "MSDOS fs support"
@@ -619,10 +552,6 @@
 	  transparent, i.e. the MSDOS files look and behave just like all
 	  other Unix files.
 
-	  If you want to use UMSDOS, the Unix-like file system on top of a
-	  DOS file system, which allows you to run Linux from within a DOS
-	  partition without repartitioning, you'll have to say Y or M here.
-
 	  If you have Windows 95 or Windows NT installed on your MSDOS
 	  partitions, you should use the VFAT file system (say Y to "VFAT fs
 	  support" below), or you will not be able to see the long filenames
@@ -642,11 +571,6 @@
 	  used by Windows 95, Windows 98, Windows NT 4.0, and the Unix
 	  programs from the mtools package.
 
-	  You cannot use the VFAT file system for your Linux root partition
-	  (the one containing the directory /); use UMSDOS instead if you
-	  want to run Linux from within a DOS partition (i.e. say Y to
-	  "Unix like fs on top of std MSDOS fs", below).
-
 	  The VFAT support enlarges your kernel by about 10 KB and it only
 	  works if you said Y to the "DOS FAT fs support" above.  Please read
 	  the file <file:Documentation/filesystems/vfat.txt> for details.  If
@@ -677,35 +601,6 @@
 	  If unsure, you shouldn't set "utf8" here.
 	  See <file:Documentation/filesystems/vfat.txt> for more information.
 
-config UMSDOS_FS
-#dep_tristate '    UMSDOS: Unix-like file system on top of standard MSDOS fs' CONFIG_UMSDOS_FS $CONFIG_MSDOS_FS
-# UMSDOS is temprory broken
-	bool
-	help
-	  Say Y here if you want to run Linux from within an existing DOS
-	  partition of your hard drive. The advantage of this is that you can
-	  get away without repartitioning your hard drive (which often implies
-	  backing everything up and restoring afterwards) and hence you're
-	  able to quickly try out Linux or show it to your friends; the
-	  disadvantage is that Linux becomes susceptible to DOS viruses and
-	  that UMSDOS is somewhat slower than ext2fs.  Another use of UMSDOS
-	  is to write files with long unix filenames to MSDOS floppies; it
-	  also allows Unix-style soft-links and owner/permissions of files on
-	  MSDOS floppies.  You will need a program called umssync in order to
-	  make use of UMSDOS; read
-	  <file:Documentation/filesystems/umsdos.txt>.
-
-	  To get utilities for initializing/checking UMSDOS file system, or
-	  latest patches and/or information, visit the UMSDOS home page at
-	  <http://www.voyager.hr/~mnalis/umsdos/>.
-
-	  This option enlarges your kernel by about 28 KB and it only works if
-	  you said Y to both "DOS FAT fs support" and "MSDOS fs support"
-	  above.  To compile this as a module, choose M here: the module will be
-	  called umsdos.  Note that the file system of your root partition
-	  (the one containing the directory /) cannot be a module, so saying M
-	  could be dangerous.  If unsure, say N.
-
 config NTFS_FS
 	tristate "NTFS file system support"
 	select NLS
@@ -1057,10 +952,10 @@
 	help
 	  The BeOS File System (BeFS) is the native file system of Be, Inc's
 	  BeOS. Notable features include support for arbitrary attributes
-	  on files and directories, and database-like indices on selected
+	  on files and directories, and database-like indeces on selected
 	  attributes. (Also note that this driver doesn't make those features
 	  available at this time). It is a 64 bit filesystem, so it supports
-	  extreemly large volumes and files.
+	  extremly large volumes and files.
 
 	  If you use this filesystem, you should also say Y to at least one
 	  of the NLS (native language support) options below.
@@ -1179,6 +1074,15 @@
 
 	  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.
+
 config JFFS2_COMPRESSION_OPTIONS
 	bool "Advanced compression options for JFFS2"
 	depends on JFFS2_FS
@@ -1201,7 +1105,7 @@
         help
           Zlib is designed to be a free, general-purpose, legally unencumbered,
           lossless data-compression library for use on virtually any computer 
-          hardware and operating system. See http://www.gzip.org/zlib/ for
+          hardware and operating system. See <http://www.gzip.org/zlib/> for
           further information.
           
           Say 'Y' if unsure.
@@ -1226,7 +1130,7 @@
         depends on JFFS2_FS
         help
           You can set here the default compression mode of JFFS2 from 
-          the avaiable compression modes. Don't touch if unsure.
+          the available compression modes. Don't touch if unsure.
 
 config JFFS2_CMODE_NONE
         bool "no compression"
@@ -1317,7 +1221,7 @@
 
 config QNX4FS_RW
 	bool "QNX4FS write support (DANGEROUS)"
-	depends on QNX4FS_FS && EXPERIMENTAL
+	depends on QNX4FS_FS && EXPERIMENTAL && BROKEN
 	help
 	  Say Y if you want to test write support for QNX4 file systems.
 
@@ -1497,6 +1401,7 @@
 	depends on INET
 	select LOCKD
 	select SUNRPC
+	select EXPORTFS
 	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
@@ -1570,7 +1475,6 @@
 
 config EXPORTFS
 	tristate
-	default NFSD
 
 config SUNRPC
 	tristate
@@ -1803,7 +1707,7 @@
 	  If you say Y here, you will get an experimental Andrew File System
 	  driver. It currently only supports unsecured read-only AFS access.
 
-	  See Documentation/filesystems/afs.txt for more intormation.
+	  See <file:Documentation/filesystems/afs.txt> for more intormation.
 
 	  If unsure, say N.
 
diff -Nru a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt
--- a/fs/Kconfig.binfmt	2005-03-01 23:39:16 -08:00
+++ b/fs/Kconfig.binfmt	2005-03-01 23:39:16 -08:00
@@ -23,6 +23,19 @@
 	  ld.so (check the file <file:Documentation/Changes> for location and
 	  latest version).
 
+config BINFMT_ELF_FDPIC
+	bool "Kernel support for FDPIC ELF binaries"
+	default y
+	depends on FRV
+	help
+	  ELF FDPIC binaries are based on ELF, but allow the individual load
+	  segments of a binary to be located in memory independently of each
+	  other. This makes this format ideal for use in environments where no
+	  MMU is available as it still permits text segments to be shared,
+	  even if data segments are not.
+
+	  It is also possible to run FDPIC ELF binaries on MMU linux also.
+
 config BINFMT_FLAT
 	tristate "Kernel support for flat binaries"
 	depends on !MMU || SUPERH
diff -Nru a/fs/Makefile b/fs/Makefile
--- a/fs/Makefile	2005-03-01 23:38:58 -08:00
+++ b/fs/Makefile	2005-03-01 23:38:58 -08:00
@@ -25,6 +25,7 @@
 obj-y				+= binfmt_script.o
 
 obj-$(CONFIG_BINFMT_ELF)	+= binfmt_elf.o
+obj-$(CONFIG_BINFMT_ELF_FDPIC)	+= binfmt_elf_fdpic.o
 obj-$(CONFIG_BINFMT_SOM)	+= binfmt_som.o
 obj-$(CONFIG_BINFMT_FLAT)	+= binfmt_flat.o
 
@@ -56,7 +57,6 @@
 obj-$(CONFIG_CODA_FS)		+= coda/
 obj-$(CONFIG_MINIX_FS)		+= minix/
 obj-$(CONFIG_FAT_FS)		+= fat/
-obj-$(CONFIG_UMSDOS_FS)		+= umsdos/
 obj-$(CONFIG_MSDOS_FS)		+= msdos/
 obj-$(CONFIG_VFAT_FS)		+= vfat/
 obj-$(CONFIG_BFS_FS)		+= bfs/
@@ -94,3 +94,4 @@
 obj-$(CONFIG_BEFS_FS)		+= befs/
 obj-$(CONFIG_HOSTFS)		+= hostfs/
 obj-$(CONFIG_HPPFS)		+= hppfs/
+obj-$(CONFIG_DEBUG_FS)		+= debugfs/
diff -Nru a/fs/adfs/dir.c b/fs/adfs/dir.c
--- a/fs/adfs/dir.c	2005-03-01 23:39:07 -08:00
+++ b/fs/adfs/dir.c	2005-03-01 23:39:07 -08:00
@@ -24,7 +24,7 @@
 /*
  * For future.  This should probably be per-directory.
  */
-static rwlock_t adfs_dir_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(adfs_dir_lock);
 
 static int
 adfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
diff -Nru a/fs/adfs/inode.c b/fs/adfs/inode.c
--- a/fs/adfs/inode.c	2005-03-01 23:38:54 -08:00
+++ b/fs/adfs/inode.c	2005-03-01 23:38:54 -08:00
@@ -210,7 +210,7 @@
 	return;
 
  cur_time:
-	*tv = CURRENT_TIME;
+	*tv = CURRENT_TIME_SEC;
 	return;
 
  too_early:
diff -Nru a/fs/adfs/map.c b/fs/adfs/map.c
--- a/fs/adfs/map.c	2005-03-01 23:38:57 -08:00
+++ b/fs/adfs/map.c	2005-03-01 23:38:57 -08:00
@@ -53,7 +53,7 @@
 /*
  * For the future...
  */
-static rwlock_t adfs_map_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(adfs_map_lock);
 
 /*
  * This is fun.  We need to load up to 19 bits from the map at an
diff -Nru a/fs/affs/affs.h b/fs/affs/affs.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/fs/affs/affs.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,304 @@
+#include <linux/types.h>
+#include <linux/fs.h>
+#include <linux/buffer_head.h>
+#include <linux/affs_fs.h>
+#include <linux/amigaffs.h>
+
+/* AmigaOS allows file names with up to 30 characters length.
+ * Names longer than that will be silently truncated. If you
+ * want to disallow this, comment out the following #define.
+ * Creating filesystem objects with longer names will then
+ * result in an error (ENAMETOOLONG).
+ */
+/*#define AFFS_NO_TRUNCATE */
+
+/* Ugly macros make the code more pretty. */
+
+#define GET_END_PTR(st,p,sz)		 ((st *)((char *)(p)+((sz)-sizeof(st))))
+#define AFFS_GET_HASHENTRY(data,hashkey) be32_to_cpu(((struct dir_front *)data)->hashtable[hashkey])
+#define AFFS_BLOCK(sb, bh, blk)		(AFFS_HEAD(bh)->table[AFFS_SB(sb)->s_hashsize-1-(blk)])
+
+#ifdef __LITTLE_ENDIAN
+#define BO_EXBITS	0x18UL
+#elif defined(__BIG_ENDIAN)
+#define BO_EXBITS	0x00UL
+#else
+#error Endianness must be known for affs to work.
+#endif
+
+#define AFFS_HEAD(bh)		((struct affs_head *)(bh)->b_data)
+#define AFFS_TAIL(sb, bh)	((struct affs_tail *)((bh)->b_data+(sb)->s_blocksize-sizeof(struct affs_tail)))
+#define AFFS_ROOT_HEAD(bh)	((struct affs_root_head *)(bh)->b_data)
+#define AFFS_ROOT_TAIL(sb, bh)	((struct affs_root_tail *)((bh)->b_data+(sb)->s_blocksize-sizeof(struct affs_root_tail)))
+#define AFFS_DATA_HEAD(bh)	((struct affs_data_head *)(bh)->b_data)
+#define AFFS_DATA(bh)		(((struct affs_data_head *)(bh)->b_data)->data)
+
+#define AFFS_CACHE_SIZE		PAGE_SIZE
+
+#define AFFS_MAX_PREALLOC	32
+#define AFFS_LC_SIZE		(AFFS_CACHE_SIZE/sizeof(u32)/2)
+#define AFFS_AC_SIZE		(AFFS_CACHE_SIZE/sizeof(struct affs_ext_key)/2)
+#define AFFS_AC_MASK		(AFFS_AC_SIZE-1)
+
+struct affs_ext_key {
+	u32	ext;				/* idx of the extended block */
+	u32	key;				/* block number */
+};
+
+/*
+ * affs fs inode data in memory
+ */
+struct affs_inode_info {
+	u32	 i_opencnt;
+	struct semaphore i_link_lock;		/* Protects internal inode access. */
+	struct semaphore i_ext_lock;		/* Protects internal inode access. */
+#define i_hash_lock i_ext_lock
+	u32	 i_blkcnt;			/* block count */
+	u32	 i_extcnt;			/* extended block count */
+	u32	*i_lc;				/* linear cache of extended blocks */
+	u32	 i_lc_size;
+	u32	 i_lc_shift;
+	u32	 i_lc_mask;
+	struct affs_ext_key *i_ac;		/* associative cache of extended blocks */
+	u32	 i_ext_last;			/* last accessed extended block */
+	struct buffer_head *i_ext_bh;		/* bh of last extended block */
+	loff_t	 mmu_private;
+	u32	 i_protect;			/* unused attribute bits */
+	u32	 i_lastalloc;			/* last allocated block */
+	int	 i_pa_cnt;			/* number of preallocated blocks */
+	struct inode vfs_inode;
+};
+
+/* short cut to get to the affs specific inode data */
+static inline struct affs_inode_info *AFFS_I(struct inode *inode)
+{
+	return list_entry(inode, struct affs_inode_info, vfs_inode);
+}
+
+/*
+ * super-block data in memory
+ *
+ * Block numbers are adjusted for their actual size
+ *
+ */
+
+struct affs_bm_info {
+	u32 bm_key;			/* Disk block number */
+	u32 bm_free;			/* Free blocks in here */
+};
+
+struct affs_sb_info {
+	int s_partition_size;		/* Partition size in blocks. */
+	int s_reserved;			/* Number of reserved blocks. */
+	//u32 s_blksize;			/* Initial device blksize */
+	u32 s_data_blksize;		/* size of the data block w/o header */
+	u32 s_root_block;		/* FFS root block number. */
+	int s_hashsize;			/* Size of hash table. */
+	unsigned long s_flags;		/* See below. */
+	uid_t s_uid;			/* uid to override */
+	gid_t s_gid;			/* gid to override */
+	umode_t s_mode;			/* mode to override */
+	struct buffer_head *s_root_bh;	/* Cached root block. */
+	struct semaphore s_bmlock;	/* Protects bitmap access. */
+	struct affs_bm_info *s_bitmap;	/* Bitmap infos. */
+	u32 s_bmap_count;		/* # of bitmap blocks. */
+	u32 s_bmap_bits;		/* # of bits in one bitmap blocks */
+	u32 s_last_bmap;
+	struct buffer_head *s_bmap_bh;
+	char *s_prefix;			/* Prefix for volumes and assigns. */
+	int s_prefix_len;		/* Length of prefix. */
+	char s_volume[32];		/* Volume prefix for absolute symlinks. */
+};
+
+#define SF_INTL		0x0001		/* International filesystem. */
+#define SF_BM_VALID	0x0002		/* Bitmap is valid. */
+#define SF_IMMUTABLE	0x0004		/* Protection bits cannot be changed */
+#define SF_QUIET	0x0008		/* chmod errors will be not reported */
+#define SF_SETUID	0x0010		/* Ignore Amiga uid */
+#define SF_SETGID	0x0020		/* Ignore Amiga gid */
+#define SF_SETMODE	0x0040		/* Ignore Amiga protection bits */
+#define SF_MUFS		0x0100		/* Use MUFS uid/gid mapping */
+#define SF_OFS		0x0200		/* Old filesystem */
+#define SF_PREFIX	0x0400		/* Buffer for prefix is allocated */
+#define SF_VERBOSE	0x0800		/* Talk about fs when mounting */
+
+/* short cut to get to the affs specific sb data */
+static inline struct affs_sb_info *AFFS_SB(struct super_block *sb)
+{
+	return sb->s_fs_info;
+}
+
+/* amigaffs.c */
+
+extern int	affs_insert_hash(struct inode *inode, struct buffer_head *bh);
+extern int	affs_remove_hash(struct inode *dir, struct buffer_head *rem_bh);
+extern int	affs_remove_header(struct dentry *dentry);
+extern u32	affs_checksum_block(struct super_block *sb, struct buffer_head *bh);
+extern void	affs_fix_checksum(struct super_block *sb, struct buffer_head *bh);
+extern void	secs_to_datestamp(time_t secs, struct affs_date *ds);
+extern mode_t	prot_to_mode(u32 prot);
+extern void	mode_to_prot(struct inode *inode);
+extern void	affs_error(struct super_block *sb, const char *function, const char *fmt, ...);
+extern void	affs_warning(struct super_block *sb, const char *function, const char *fmt, ...);
+extern int	affs_check_name(const unsigned char *name, int len);
+extern int	affs_copy_name(unsigned char *bstr, struct dentry *dentry);
+
+/* bitmap. c */
+
+extern u32	affs_count_free_blocks(struct super_block *s);
+extern void	affs_free_block(struct super_block *sb, u32 block);
+extern u32	affs_alloc_block(struct inode *inode, u32 goal);
+extern int	affs_init_bitmap(struct super_block *sb, int *flags);
+extern void	affs_free_bitmap(struct super_block *sb);
+
+/* namei.c */
+
+extern int	affs_hash_name(struct super_block *sb, const u8 *name, unsigned int len);
+extern struct dentry *affs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *);
+extern int	affs_unlink(struct inode *dir, struct dentry *dentry);
+extern int	affs_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *);
+extern int	affs_mkdir(struct inode *dir, struct dentry *dentry, int mode);
+extern int	affs_rmdir(struct inode *dir, struct dentry *dentry);
+extern int	affs_link(struct dentry *olddentry, struct inode *dir,
+			  struct dentry *dentry);
+extern int	affs_symlink(struct inode *dir, struct dentry *dentry,
+			     const char *symname);
+extern int	affs_rename(struct inode *old_dir, struct dentry *old_dentry,
+			    struct inode *new_dir, struct dentry *new_dentry);
+
+/* inode.c */
+
+extern unsigned long		 affs_parent_ino(struct inode *dir);
+extern struct inode		*affs_new_inode(struct inode *dir);
+extern int			 affs_notify_change(struct dentry *dentry, struct iattr *attr);
+extern void			 affs_put_inode(struct inode *inode);
+extern void			 affs_delete_inode(struct inode *inode);
+extern void			 affs_clear_inode(struct inode *inode);
+extern void			 affs_read_inode(struct inode *inode);
+extern int			 affs_write_inode(struct inode *inode, int);
+extern int			 affs_add_entry(struct inode *dir, struct inode *inode, struct dentry *dentry, s32 type);
+
+/* file.c */
+
+void		affs_free_prealloc(struct inode *inode);
+extern void	affs_truncate(struct inode *);
+
+/* dir.c */
+
+extern void   affs_dir_truncate(struct inode *);
+
+/* jump tables */
+
+extern struct inode_operations	 affs_file_inode_operations;
+extern struct inode_operations	 affs_dir_inode_operations;
+extern struct inode_operations   affs_symlink_inode_operations;
+extern struct file_operations	 affs_file_operations;
+extern struct file_operations	 affs_file_operations_ofs;
+extern struct file_operations	 affs_dir_operations;
+extern struct address_space_operations	 affs_symlink_aops;
+extern struct address_space_operations	 affs_aops;
+extern struct address_space_operations	 affs_aops_ofs;
+
+extern struct dentry_operations	 affs_dentry_operations;
+extern struct dentry_operations	 affs_dentry_operations_intl;
+
+static inline void
+affs_set_blocksize(struct super_block *sb, int size)
+{
+	sb_set_blocksize(sb, size);
+}
+static inline struct buffer_head *
+affs_bread(struct super_block *sb, int block)
+{
+	pr_debug("affs_bread: %d\n", block);
+	if (block >= AFFS_SB(sb)->s_reserved && block < AFFS_SB(sb)->s_partition_size)
+		return sb_bread(sb, block);
+	return NULL;
+}
+static inline struct buffer_head *
+affs_getblk(struct super_block *sb, int block)
+{
+	pr_debug("affs_getblk: %d\n", block);
+	if (block >= AFFS_SB(sb)->s_reserved && block < AFFS_SB(sb)->s_partition_size)
+		return sb_getblk(sb, block);
+	return NULL;
+}
+static inline struct buffer_head *
+affs_getzeroblk(struct super_block *sb, int block)
+{
+	struct buffer_head *bh;
+	pr_debug("affs_getzeroblk: %d\n", block);
+	if (block >= AFFS_SB(sb)->s_reserved && block < AFFS_SB(sb)->s_partition_size) {
+		bh = sb_getblk(sb, block);
+		lock_buffer(bh);
+		memset(bh->b_data, 0 , sb->s_blocksize);
+		set_buffer_uptodate(bh);
+		unlock_buffer(bh);
+		return bh;
+	}
+	return NULL;
+}
+static inline struct buffer_head *
+affs_getemptyblk(struct super_block *sb, int block)
+{
+	struct buffer_head *bh;
+	pr_debug("affs_getemptyblk: %d\n", block);
+	if (block >= AFFS_SB(sb)->s_reserved && block < AFFS_SB(sb)->s_partition_size) {
+		bh = sb_getblk(sb, block);
+		wait_on_buffer(bh);
+		set_buffer_uptodate(bh);
+		return bh;
+	}
+	return NULL;
+}
+static inline void
+affs_brelse(struct buffer_head *bh)
+{
+	if (bh)
+		pr_debug("affs_brelse: %lld\n", (long long) bh->b_blocknr);
+	brelse(bh);
+}
+
+static inline void
+affs_adjust_checksum(struct buffer_head *bh, u32 val)
+{
+	u32 tmp = be32_to_cpu(((__be32 *)bh->b_data)[5]);
+	((__be32 *)bh->b_data)[5] = cpu_to_be32(tmp - val);
+}
+static inline void
+affs_adjust_bitmapchecksum(struct buffer_head *bh, u32 val)
+{
+	u32 tmp = be32_to_cpu(((__be32 *)bh->b_data)[0]);
+	((__be32 *)bh->b_data)[0] = cpu_to_be32(tmp - val);
+}
+
+static inline void
+affs_lock_link(struct inode *inode)
+{
+	down(&AFFS_I(inode)->i_link_lock);
+}
+static inline void
+affs_unlock_link(struct inode *inode)
+{
+	up(&AFFS_I(inode)->i_link_lock);
+}
+static inline void
+affs_lock_dir(struct inode *inode)
+{
+	down(&AFFS_I(inode)->i_hash_lock);
+}
+static inline void
+affs_unlock_dir(struct inode *inode)
+{
+	up(&AFFS_I(inode)->i_hash_lock);
+}
+static inline void
+affs_lock_ext(struct inode *inode)
+{
+	down(&AFFS_I(inode)->i_ext_lock);
+}
+static inline void
+affs_unlock_ext(struct inode *inode)
+{
+	up(&AFFS_I(inode)->i_ext_lock);
+}
diff -Nru a/fs/affs/amigaffs.c b/fs/affs/amigaffs.c
--- a/fs/affs/amigaffs.c	2005-03-01 23:38:54 -08:00
+++ b/fs/affs/amigaffs.c	2005-03-01 23:38:54 -08:00
@@ -8,14 +8,7 @@
  *  Please send bug reports to: hjw@zvw.de
  */
 
-#include <stdarg.h>
-#include <linux/stat.h>
-#include <linux/time.h>
-#include <linux/affs_fs.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/amigaffs.h>
-#include <linux/buffer_head.h>
+#include "affs.h"
 
 extern struct timezone sys_tz;
 
@@ -68,7 +61,7 @@
 	mark_buffer_dirty_inode(dir_bh, dir);
 	affs_brelse(dir_bh);
 
-	dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+	dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
 	dir->i_version++;
 	mark_inode_dirty(dir);
 
@@ -121,7 +114,7 @@
 
 	affs_brelse(bh);
 
-	dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+	dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
 	dir->i_version++;
 	mark_inode_dirty(dir);
 
@@ -319,7 +312,7 @@
 	else
 		inode->i_nlink = 0;
 	affs_unlock_link(inode);
-	inode->i_ctime = CURRENT_TIME;
+	inode->i_ctime = CURRENT_TIME_SEC;
 	mark_inode_dirty(inode);
 
 done:
diff -Nru a/fs/affs/bitmap.c b/fs/affs/bitmap.c
--- a/fs/affs/bitmap.c	2005-03-01 23:39:17 -08:00
+++ b/fs/affs/bitmap.c	2005-03-01 23:39:17 -08:00
@@ -7,15 +7,7 @@
  *  block allocation, deallocation, calculation of free space.
  */
 
-#include <linux/time.h>
-#include <linux/affs_fs.h>
-#include <linux/stat.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/bitops.h>
-#include <linux/amigaffs.h>
-#include <linux/buffer_head.h>
+#include "affs.h"
 
 /* This is, of course, shamelessly stolen from fs/minix */
 
diff -Nru a/fs/affs/dir.c b/fs/affs/dir.c
--- a/fs/affs/dir.c	2005-03-01 23:39:09 -08:00
+++ b/fs/affs/dir.c	2005-03-01 23:39:09 -08:00
@@ -13,17 +13,7 @@
  *
  */
 
-#include <asm/uaccess.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/affs_fs.h>
-#include <linux/stat.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/amigaffs.h>
-#include <linux/smp_lock.h>
-#include <linux/buffer_head.h>
+#include "affs.h"
 
 static int affs_readdir(struct file *, void *, filldir_t);
 
diff -Nru a/fs/affs/file.c b/fs/affs/file.c
--- a/fs/affs/file.c	2005-03-01 23:38:57 -08:00
+++ b/fs/affs/file.c	2005-03-01 23:38:57 -08:00
@@ -12,24 +12,7 @@
  *  affs regular file handling primitives
  */
 
-#include <asm/div64.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <linux/time.h>
-#include <linux/affs_fs.h>
-#include <linux/fcntl.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-#include <linux/stat.h>
-#include <linux/smp_lock.h>
-#include <linux/dirent.h>
-#include <linux/fs.h>
-#include <linux/amigaffs.h>
-#include <linux/mm.h>
-#include <linux/highmem.h>
-#include <linux/pagemap.h>
-#include <linux/buffer_head.h>
+#include "affs.h"
 
 #if PAGE_SIZE < 4096
 #error PAGE_SIZE must be at least 4096
@@ -499,7 +482,7 @@
 	retval = generic_file_write (file, buf, count, ppos);
 	if (retval >0) {
 		struct inode *inode = file->f_dentry->d_inode;
-		inode->i_ctime = inode->i_mtime = CURRENT_TIME;
+		inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC;
 		mark_inode_dirty(inode);
 	}
 	return retval;
diff -Nru a/fs/affs/inode.c b/fs/affs/inode.c
--- a/fs/affs/inode.c	2005-03-01 23:38:56 -08:00
+++ b/fs/affs/inode.c	2005-03-01 23:38:56 -08:00
@@ -10,26 +10,7 @@
  *  (C) 1991  Linus Torvalds - minix filesystem
  */
 
-#include <asm/div64.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/slab.h>
-#include <linux/stat.h>
-#include <linux/time.h>
-#include <linux/affs_fs.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/string.h>
-#include <linux/genhd.h>
-#include <linux/amigaffs.h>
-#include <linux/major.h>
-#include <linux/blkdev.h>
-#include <linux/init.h>
-#include <linux/smp_lock.h>
-#include <linux/buffer_head.h>
-#include <asm/system.h>
-#include <asm/uaccess.h>
-#include <linux/module.h>
+#include "affs.h"
 
 extern struct inode_operations affs_symlink_inode_operations;
 extern struct timezone sys_tz;
@@ -322,7 +303,7 @@
 	inode->i_gid     = current->fsgid;
 	inode->i_ino     = block;
 	inode->i_nlink   = 1;
-	inode->i_mtime   = inode->i_atime = inode->i_ctime = CURRENT_TIME;
+	inode->i_mtime   = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
 	AFFS_I(inode)->i_opencnt = 0;
 	AFFS_I(inode)->i_blkcnt = 0;
 	AFFS_I(inode)->i_lc = NULL;
@@ -428,4 +409,3 @@
 	affs_unlock_link(inode);
 	goto done;
 }
-MODULE_LICENSE("GPL");
diff -Nru a/fs/affs/namei.c b/fs/affs/namei.c
--- a/fs/affs/namei.c	2005-03-01 23:38:54 -08:00
+++ b/fs/affs/namei.c	2005-03-01 23:38:54 -08:00
@@ -8,22 +8,9 @@
  *  (C) 1991  Linus Torvalds - minix filesystem
  */
 
-#include <linux/time.h>
-#include <linux/affs_fs.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/stat.h>
-#include <linux/fcntl.h>
-#include <linux/amigaffs.h>
-#include <linux/smp_lock.h>
-#include <linux/buffer_head.h>
-#include <asm/uaccess.h>
-
-#include <linux/errno.h>
+#include "affs.h"
 
 typedef int (*toupper_t)(int);
-
-extern struct inode_operations affs_symlink_inode_operations;
 
 static int	 affs_toupper(int ch);
 static int	 affs_hash_dentry(struct dentry *, struct qstr *);
diff -Nru a/fs/affs/super.c b/fs/affs/super.c
--- a/fs/affs/super.c	2005-03-01 23:39:07 -08:00
+++ b/fs/affs/super.c	2005-03-01 23:39:07 -08:00
@@ -11,26 +11,10 @@
  */
 
 #include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/slab.h>
-#include <linux/stat.h>
-#include <linux/time.h>
-#include <linux/affs_fs.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/string.h>
-#include <linux/genhd.h>
-#include <linux/amigaffs.h>
-#include <linux/major.h>
-#include <linux/blkdev.h>
 #include <linux/init.h>
-#include <linux/smp_lock.h>
-#include <linux/buffer_head.h>
-#include <linux/vfs.h>
+#include <linux/statfs.h>
 #include <linux/parser.h>
-#include <asm/system.h>
-#include <asm/uaccess.h>
+#include "affs.h"
 
 extern struct timezone sys_tz;
 
diff -Nru a/fs/affs/symlink.c b/fs/affs/symlink.c
--- a/fs/affs/symlink.c	2005-03-01 23:38:53 -08:00
+++ b/fs/affs/symlink.c	2005-03-01 23:38:53 -08:00
@@ -8,14 +8,7 @@
  *  affs symlink handling code
  */
 
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/stat.h>
-#include <linux/affs_fs.h>
-#include <linux/amigaffs.h>
-#include <linux/pagemap.h>
-#include <linux/smp_lock.h>
-#include <linux/buffer_head.h>
+#include "affs.h"
 
 static int affs_symlink_readpage(struct file *file, struct page *page)
 {
diff -Nru a/fs/afs/cell.c b/fs/afs/cell.c
--- a/fs/afs/cell.c	2005-03-01 23:38:51 -08:00
+++ b/fs/afs/cell.c	2005-03-01 23:38:51 -08:00
@@ -27,7 +27,7 @@
 LIST_HEAD(afs_proc_cells);
 
 static struct list_head afs_cells = LIST_HEAD_INIT(afs_cells);
-static rwlock_t afs_cells_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(afs_cells_lock);
 static DECLARE_RWSEM(afs_cells_sem); /* add/remove serialisation */
 static struct afs_cell *afs_cell_root;
 
diff -Nru a/fs/afs/cmservice.c b/fs/afs/cmservice.c
--- a/fs/afs/cmservice.c	2005-03-01 23:38:57 -08:00
+++ b/fs/afs/cmservice.c	2005-03-01 23:38:57 -08:00
@@ -102,8 +102,8 @@
 static DECLARE_WAIT_QUEUE_HEAD(kafscmd_sleepq);
 static LIST_HEAD(kafscmd_attention_list);
 static LIST_HEAD(afscm_calls);
-static spinlock_t afscm_calls_lock = SPIN_LOCK_UNLOCKED;
-static spinlock_t kafscmd_attention_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(afscm_calls_lock);
+static DEFINE_SPINLOCK(kafscmd_attention_lock);
 static int kafscmd_die;
 
 /*****************************************************************************/
diff -Nru a/fs/afs/kafsasyncd.c b/fs/afs/kafsasyncd.c
--- a/fs/afs/kafsasyncd.c	2005-03-01 23:39:16 -08:00
+++ b/fs/afs/kafsasyncd.c	2005-03-01 23:39:16 -08:00
@@ -39,7 +39,7 @@
 
 static LIST_HEAD(kafsasyncd_async_attnq);
 static LIST_HEAD(kafsasyncd_async_busyq);
-static spinlock_t kafsasyncd_async_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(kafsasyncd_async_lock);
 
 static void kafsasyncd_null_call_attn_func(struct rxrpc_call *call)
 {
diff -Nru a/fs/afs/kafstimod.c b/fs/afs/kafstimod.c
--- a/fs/afs/kafstimod.c	2005-03-01 23:39:18 -08:00
+++ b/fs/afs/kafstimod.c	2005-03-01 23:39:18 -08:00
@@ -25,7 +25,7 @@
 static int kafstimod_die;
 
 static LIST_HEAD(kafstimod_list);
-static spinlock_t kafstimod_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(kafstimod_lock);
 
 static int kafstimod(void *arg);
 
diff -Nru a/fs/afs/main.c b/fs/afs/main.c
--- a/fs/afs/main.c	2005-03-01 23:38:54 -08:00
+++ b/fs/afs/main.c	2005-03-01 23:38:54 -08:00
@@ -58,7 +58,7 @@
 };
 
 struct list_head afs_cb_hash_tbl[AFS_CB_HASH_COUNT];
-spinlock_t afs_cb_hash_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(afs_cb_hash_lock);
 
 #ifdef AFS_CACHING_SUPPORT
 static struct cachefs_netfs_operations afs_cache_ops = {
diff -Nru a/fs/afs/server.c b/fs/afs/server.c
--- a/fs/afs/server.c	2005-03-01 23:38:52 -08:00
+++ b/fs/afs/server.c	2005-03-01 23:38:52 -08:00
@@ -21,7 +21,7 @@
 #include "kafstimod.h"
 #include "internal.h"
 
-spinlock_t afs_server_peer_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(afs_server_peer_lock);
 
 #define FS_SERVICE_ID		1	/* AFS Volume Location Service ID */
 #define VL_SERVICE_ID		52	/* AFS Volume Location Service ID */
diff -Nru a/fs/afs/types.h b/fs/afs/types.h
--- a/fs/afs/types.h	2005-03-01 23:38:57 -08:00
+++ b/fs/afs/types.h	2005-03-01 23:38:57 -08:00
@@ -26,8 +26,6 @@
 	AFSVL_BACKVOL,			/* backup volume */
 } __attribute__((packed)) afs_voltype_t;
 
-extern const char *afs_voltypes[];
-
 typedef enum {
 	AFS_FTYPE_INVALID	= 0,
 	AFS_FTYPE_FILE		= 1,
diff -Nru a/fs/afs/vlocation.c b/fs/afs/vlocation.c
--- a/fs/afs/vlocation.c	2005-03-01 23:38:55 -08:00
+++ b/fs/afs/vlocation.c	2005-03-01 23:38:55 -08:00
@@ -57,7 +57,7 @@
 
 static LIST_HEAD(afs_vlocation_update_pendq);	/* queue of VLs awaiting update */
 static struct afs_vlocation *afs_vlocation_update;	/* VL currently being updated */
-static spinlock_t afs_vlocation_update_lock = SPIN_LOCK_UNLOCKED; /* lock guarding update queue */
+static DEFINE_SPINLOCK(afs_vlocation_update_lock); /* lock guarding update queue */
 
 #ifdef AFS_CACHING_SUPPORT
 static cachefs_match_val_t afs_vlocation_cache_match(void *target,
diff -Nru a/fs/afs/volume.c b/fs/afs/volume.c
--- a/fs/afs/volume.c	2005-03-01 23:38:44 -08:00
+++ b/fs/afs/volume.c	2005-03-01 23:38:44 -08:00
@@ -24,7 +24,9 @@
 #include "vlclient.h"
 #include "internal.h"
 
-const char *afs_voltypes[] = { "R/W", "R/O", "BAK" };
+#ifdef __KDEBUG
+static const char *afs_voltypes[] = { "R/W", "R/O", "BAK" };
+#endif
 
 #ifdef AFS_CACHING_SUPPORT
 static cachefs_match_val_t afs_volume_cache_match(void *target,
diff -Nru a/fs/aio.c b/fs/aio.c
--- a/fs/aio.c	2005-03-01 23:38:56 -08:00
+++ b/fs/aio.c	2005-03-01 23:38:56 -08:00
@@ -57,7 +57,7 @@
 static void aio_fput_routine(void *);
 static DECLARE_WORK(fput_work, aio_fput_routine, NULL);
 
-static spinlock_t	fput_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(fput_lock);
 LIST_HEAD(fput_head);
 
 static void aio_kick_handler(void *);
@@ -1285,6 +1285,7 @@
 		if (!ret)
 			return 0;
 
+		get_ioctx(ioctx); /* io_destroy() expects us to hold a ref */
 		io_destroy(ioctx);
 	}
 
diff -Nru a/fs/attr.c b/fs/attr.c
--- a/fs/attr.c	2005-03-01 23:38:52 -08:00
+++ b/fs/attr.c	2005-03-01 23:38:52 -08:00
@@ -14,6 +14,7 @@
 #include <linux/fcntl.h>
 #include <linux/quotaops.h>
 #include <linux/security.h>
+#include <linux/time.h>
 
 /* Taken over from the old code... */
 
@@ -87,11 +88,14 @@
 	if (ia_valid & ATTR_GID)
 		inode->i_gid = attr->ia_gid;
 	if (ia_valid & ATTR_ATIME)
-		inode->i_atime = attr->ia_atime;
+		inode->i_atime = timespec_trunc(attr->ia_atime,
+						inode->i_sb->s_time_gran);
 	if (ia_valid & ATTR_MTIME)
-		inode->i_mtime = attr->ia_mtime;
+		inode->i_mtime = timespec_trunc(attr->ia_mtime,
+						inode->i_sb->s_time_gran);
 	if (ia_valid & ATTR_CTIME)
-		inode->i_ctime = attr->ia_ctime;
+		inode->i_ctime = timespec_trunc(attr->ia_ctime,
+						inode->i_sb->s_time_gran);
 	if (ia_valid & ATTR_MODE) {
 		umode_t mode = attr->ia_mode;
 
@@ -133,7 +137,7 @@
 	struct inode *inode = dentry->d_inode;
 	mode_t mode = inode->i_mode;
 	int error;
-	struct timespec now = CURRENT_TIME;
+	struct timespec now = current_fs_time(inode->i_sb);
 	unsigned int ia_valid = attr->ia_valid;
 
 	if (!inode)
@@ -167,6 +171,9 @@
 	if (!attr->ia_valid)
 		return 0;
 
+	if (ia_valid & ATTR_SIZE)
+		down_write(&dentry->d_inode->i_alloc_sem);
+
 	if (inode->i_op && inode->i_op->setattr) {
 		error = security_inode_setattr(dentry, attr);
 		if (!error)
@@ -183,6 +190,10 @@
 				error = inode_setattr(inode, attr);
 		}
 	}
+
+	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)
diff -Nru a/fs/autofs/inode.c b/fs/autofs/inode.c
--- a/fs/autofs/inode.c	2005-03-01 23:39:08 -08:00
+++ b/fs/autofs/inode.c	2005-03-01 23:39:08 -08:00
@@ -147,6 +147,7 @@
 	s->s_blocksize_bits = 10;
 	s->s_magic = AUTOFS_SUPER_MAGIC;
 	s->s_op = &autofs_sops;
+	s->s_time_gran = 1;
 
 	root_inode = iget(s, AUTOFS_ROOT_INO);
 	root = d_alloc_root(root_inode);
diff -Nru a/fs/autofs4/inode.c b/fs/autofs4/inode.c
--- a/fs/autofs4/inode.c	2005-03-01 23:39:08 -08:00
+++ b/fs/autofs4/inode.c	2005-03-01 23:39:08 -08:00
@@ -211,6 +211,7 @@
 	s->s_blocksize_bits = 10;
 	s->s_magic = AUTOFS_SUPER_MAGIC;
 	s->s_op = &autofs4_sops;
+	s->s_time_gran = 1;
 
 	/*
 	 * Get the root inode and dentry, but defer checking for errors.
diff -Nru a/fs/bad_inode.c b/fs/bad_inode.c
--- a/fs/bad_inode.c	2005-03-01 23:39:18 -08:00
+++ b/fs/bad_inode.c	2005-03-01 23:39:18 -08:00
@@ -105,7 +105,8 @@
 	remove_inode_hash(inode);
 
 	inode->i_mode = S_IFREG;
-	inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+	inode->i_atime = inode->i_mtime = inode->i_ctime =
+		current_fs_time(inode->i_sb);
 	inode->i_op = &bad_inode_ops;	
 	inode->i_fop = &bad_file_ops;	
 }
diff -Nru a/fs/befs/debug.c b/fs/befs/debug.c
--- a/fs/befs/debug.c	2005-03-01 23:39:18 -08:00
+++ b/fs/befs/debug.c	2005-03-01 23:39:18 -08:00
@@ -222,6 +222,7 @@
 #endif				//CONFIG_BEFS_DEBUG
 }
 
+#if 0
 /* unused */
 void
 befs_dump_small_data(const struct super_block *sb, befs_small_data * sd)
@@ -241,6 +242,7 @@
 
 #endif				//CONFIG_BEFS_DEBUG
 }
+#endif  /*  0  */
 
 void
 befs_dump_index_entry(const struct super_block *sb, befs_btree_super * super)
diff -Nru a/fs/bfs/dir.c b/fs/bfs/dir.c
--- a/fs/bfs/dir.c	2005-03-01 23:39:10 -08:00
+++ b/fs/bfs/dir.c	2005-03-01 23:39:10 -08:00
@@ -100,7 +100,7 @@
 	info->si_freei--;
 	inode->i_uid = current->fsuid;
 	inode->i_gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid;
-	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
+	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
 	inode->i_blocks = inode->i_blksize = 0;
 	inode->i_op = &bfs_file_inops;
 	inode->i_fop = &bfs_file_operations;
@@ -164,7 +164,7 @@
 		return err;
 	}
 	inode->i_nlink++;
-	inode->i_ctime = CURRENT_TIME;
+	inode->i_ctime = CURRENT_TIME_SEC;
 	mark_inode_dirty(inode);
 	atomic_inc(&inode->i_count);
 	d_instantiate(new, inode);
@@ -193,7 +193,7 @@
 	}
 	de->ino = 0;
 	mark_buffer_dirty(bh);
-	dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+	dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
 	mark_inode_dirty(dir);
 	inode->i_nlink--;
 	inode->i_ctime = dir->i_ctime;
@@ -245,11 +245,11 @@
 			goto end_rename;
 	}
 	old_de->ino = 0;
-	old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
+	old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME_SEC;
 	mark_inode_dirty(old_dir);
 	if (new_inode) {
 		new_inode->i_nlink--;
-		new_inode->i_ctime = CURRENT_TIME;
+		new_inode->i_ctime = CURRENT_TIME_SEC;
 		mark_inode_dirty(new_inode);
 	}
 	mark_buffer_dirty(old_bh);
@@ -300,9 +300,9 @@
 			if (!de->ino) {
 				if ((block-sblock)*BFS_BSIZE + off >= dir->i_size) {
 					dir->i_size += BFS_DIRENT_SIZE;
-					dir->i_ctime = CURRENT_TIME;
+					dir->i_ctime = CURRENT_TIME_SEC;
 				}
-				dir->i_mtime = CURRENT_TIME;
+				dir->i_mtime = CURRENT_TIME_SEC;
 				mark_inode_dirty(dir);
 				de->ino = ino;
 				for (i=0; i<BFS_NAMELEN; i++)
diff -Nru a/fs/bfs/inode.c b/fs/bfs/inode.c
--- a/fs/bfs/inode.c	2005-03-01 23:38:56 -08:00
+++ b/fs/bfs/inode.c	2005-03-01 23:38:56 -08:00
@@ -149,7 +149,7 @@
 	}
 	
 	inode->i_size = 0;
-	inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+	inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC;
 	lock_kernel();
 	mark_inode_dirty(inode);
 	block = (ino - BFS_ROOT_INO)/BFS_INODES_PER_BLOCK + 1;
diff -Nru a/fs/binfmt_aout.c b/fs/binfmt_aout.c
--- a/fs/binfmt_aout.c	2005-03-01 23:39:18 -08:00
+++ b/fs/binfmt_aout.c	2005-03-01 23:39:18 -08:00
@@ -50,7 +50,10 @@
 	start = PAGE_ALIGN(start);
 	end = PAGE_ALIGN(end);
 	if (end > start) {
-		unsigned long addr = do_brk(start, end - start);
+		unsigned long addr;
+		down_write(&current->mm->mmap_sem);
+		addr = do_brk(start, end - start);
+		up_write(&current->mm->mmap_sem);
 		if (BAD_ADDR(addr))
 			return addr;
 	}
@@ -112,7 +115,7 @@
 	set_fs(KERNEL_DS);
 	has_dumped = 1;
 	current->flags |= PF_DUMPCORE;
-       	strncpy(dump.u_comm, current->comm, sizeof(current->comm));
+       	strncpy(dump.u_comm, current->comm, sizeof(dump.u_comm));
 #ifndef __sparc__
 	dump.u_ar0 = (void *)(((unsigned long)(&dump.regs)) - ((unsigned long)(&dump)));
 #endif
@@ -323,10 +326,14 @@
 		loff_t pos = fd_offset;
 		/* Fuck me plenty... */
 		/* <AOL></AOL> */
+		down_write(&current->mm->mmap_sem);	
 		error = do_brk(N_TXTADDR(ex), ex.a_text);
+		up_write(&current->mm->mmap_sem);
 		bprm->file->f_op->read(bprm->file, (char *) N_TXTADDR(ex),
 			  ex.a_text, &pos);
+		down_write(&current->mm->mmap_sem);
 		error = do_brk(N_DATADDR(ex), ex.a_data);
+		up_write(&current->mm->mmap_sem);
 		bprm->file->f_op->read(bprm->file, (char *) N_DATADDR(ex),
 			  ex.a_data, &pos);
 		goto beyond_if;
@@ -346,8 +353,9 @@
 		pos = 32;
 		map_size = ex.a_text+ex.a_data;
 #endif
-
+		down_write(&current->mm->mmap_sem);
 		error = do_brk(text_addr & PAGE_MASK, map_size);
+		up_write(&current->mm->mmap_sem);
 		if (error != (text_addr & PAGE_MASK)) {
 			send_sig(SIGKILL, current, 0);
 			return error;
@@ -382,7 +390,9 @@
 
 		if (!bprm->file->f_op->mmap||((fd_offset & ~PAGE_MASK) != 0)) {
 			loff_t pos = fd_offset;
+			down_write(&current->mm->mmap_sem);
 			do_brk(N_TXTADDR(ex), ex.a_text+ex.a_data);
+			up_write(&current->mm->mmap_sem);
 			bprm->file->f_op->read(bprm->file,
 					(char __user *)N_TXTADDR(ex),
 					ex.a_text+ex.a_data, &pos);
@@ -424,7 +434,7 @@
 		return retval;
 	}
 
-	retval = setup_arg_pages(bprm, EXSTACK_DEFAULT);
+	retval = setup_arg_pages(bprm, STACK_TOP, EXSTACK_DEFAULT);
 	if (retval < 0) { 
 		/* Someone check-me: is this error path enough? */ 
 		send_sig(SIGKILL, current, 0); 
@@ -487,8 +497,9 @@
 			       file->f_dentry->d_name.name);
 			error_time = jiffies;
 		}
-
+		down_write(&current->mm->mmap_sem);
 		do_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss);
+		up_write(&current->mm->mmap_sem);
 		
 		file->f_op->read(file, (char __user *)start_addr,
 			ex.a_text + ex.a_data, &pos);
@@ -512,7 +523,9 @@
 	len = PAGE_ALIGN(ex.a_text + ex.a_data);
 	bss = ex.a_text + ex.a_data + ex.a_bss;
 	if (bss > len) {
+		down_write(&current->mm->mmap_sem);
 		error = do_brk(start_addr + len, bss - len);
+		up_write(&current->mm->mmap_sem);
 		retval = error;
 		if (error != start_addr + len)
 			goto out;
diff -Nru a/fs/binfmt_elf.c b/fs/binfmt_elf.c
--- a/fs/binfmt_elf.c	2005-03-01 23:38:56 -08:00
+++ b/fs/binfmt_elf.c	2005-03-01 23:38:56 -08:00
@@ -69,6 +69,10 @@
 # define ELF_MIN_ALIGN	PAGE_SIZE
 #endif
 
+#ifndef ELF_CORE_EFLAGS
+#define ELF_CORE_EFLAGS	0
+#endif
+
 #define ELF_PAGESTART(_v) ((_v) & ~(unsigned long)(ELF_MIN_ALIGN-1))
 #define ELF_PAGEOFFSET(_v) ((_v) & (ELF_MIN_ALIGN-1))
 #define ELF_PAGEALIGN(_v) (((_v) + ELF_MIN_ALIGN - 1) & ~(ELF_MIN_ALIGN - 1))
@@ -88,7 +92,10 @@
 	start = ELF_PAGEALIGN(start);
 	end = ELF_PAGEALIGN(end);
 	if (end > start) {
-		unsigned long addr = do_brk(start, end - start);
+		unsigned long addr;
+		down_write(&current->mm->mmap_sem);
+		addr = do_brk(start, end - start);
+		up_write(&current->mm->mmap_sem);
 		if (BAD_ADDR(addr))
 			return addr;
 	}
@@ -103,15 +110,17 @@
    be in memory */
 
 
-static void padzero(unsigned long elf_bss)
+static int padzero(unsigned long elf_bss)
 {
 	unsigned long nbyte;
 
 	nbyte = ELF_PAGEOFFSET(elf_bss);
 	if (nbyte) {
 		nbyte = ELF_MIN_ALIGN - nbyte;
-		clear_user((void __user *) elf_bss, nbyte);
+		if (clear_user((void __user *) elf_bss, nbyte))
+			return -EFAULT;
 	}
+	return 0;
 }
 
 /* Let's use some macros to make this stack manipulation a litle clearer */
@@ -127,7 +136,7 @@
 #define STACK_ALLOC(sp, len) ({ sp -= len ; sp; })
 #endif
 
-static void
+static int
 create_elf_tables(struct linux_binprm *bprm, struct elfhdr * exec,
 		int interp_aout, unsigned long load_addr,
 		unsigned long interp_load_addr)
@@ -172,7 +181,8 @@
 			STACK_ALLOC(p, ((current->pid % 64) << 7));
 #endif
 		u_platform = (elf_addr_t __user *)STACK_ALLOC(p, len);
-		__copy_to_user(u_platform, k_platform, len);
+		if (__copy_to_user(u_platform, k_platform, len))
+			return -EFAULT;
 	}
 
 	/* Create the ELF interpreter info */
@@ -234,7 +244,8 @@
 #endif
 
 	/* Now, let's put argc (and argv, envp if appropriate) on the stack */
-	__put_user(argc, sp++);
+	if (__put_user(argc, sp++))
+		return -EFAULT;
 	if (interp_aout) {
 		argv = sp + 2;
 		envp = argv + argc + 1;
@@ -252,25 +263,29 @@
 		__put_user((elf_addr_t)p, argv++);
 		len = strnlen_user((void __user *)p, PAGE_SIZE*MAX_ARG_PAGES);
 		if (!len || len > PAGE_SIZE*MAX_ARG_PAGES)
-			return;
+			return 0;
 		p += len;
 	}
-	__put_user(0, argv);
+	if (__put_user(0, argv))
+		return -EFAULT;
 	current->mm->arg_end = current->mm->env_start = p;
 	while (envc-- > 0) {
 		size_t len;
 		__put_user((elf_addr_t)p, envp++);
 		len = strnlen_user((void __user *)p, PAGE_SIZE*MAX_ARG_PAGES);
 		if (!len || len > PAGE_SIZE*MAX_ARG_PAGES)
-			return;
+			return 0;
 		p += len;
 	}
-	__put_user(0, envp);
+	if (__put_user(0, envp))
+		return -EFAULT;
 	current->mm->env_end = p;
 
 	/* Put the elf_info on the stack in the right place.  */
 	sp = (elf_addr_t __user *)envp + 1;
-	copy_to_user(sp, elf_info, ei_index * sizeof(elf_addr_t));
+	if (copy_to_user(sp, elf_info, ei_index * sizeof(elf_addr_t)))
+		return -EFAULT;
+	return 0;
 }
 
 #ifndef elf_map
@@ -322,7 +337,8 @@
 	 */
 	if (interp_elf_ex->e_phentsize != sizeof(struct elf_phdr))
 		goto out;
-	if (interp_elf_ex->e_phnum > 65536U / sizeof(struct elf_phdr))
+	if (interp_elf_ex->e_phnum < 1 ||
+		interp_elf_ex->e_phnum > 65536U / sizeof(struct elf_phdr))
 		goto out;
 
 	/* Now read in all of the header information */
@@ -403,12 +419,18 @@
 	 * that there are zero-mapped pages up to and including the 
 	 * last bss page.
 	 */
-	padzero(elf_bss);
+	if (padzero(elf_bss)) {
+		error = -EFAULT;
+		goto out_close;
+	}
+
 	elf_bss = ELF_PAGESTART(elf_bss + ELF_MIN_ALIGN - 1);	/* What we have mapped so far */
 
 	/* Map the last of the bss segment */
 	if (last_bss > elf_bss) {
+		down_write(&current->mm->mmap_sem);
 		error = do_brk(elf_bss, last_bss - elf_bss);
+		up_write(&current->mm->mmap_sem);
 		if (BAD_ADDR(error))
 			goto out_close;
 	}
@@ -448,7 +470,9 @@
 		goto out;
 	}
 
+	down_write(&current->mm->mmap_sem);	
 	do_brk(0, text_data);
+	up_write(&current->mm->mmap_sem);
 	if (!interpreter->f_op || !interpreter->f_op->read)
 		goto out;
 	if (interpreter->f_op->read(interpreter, addr, text_data, &offset) < 0)
@@ -456,8 +480,11 @@
 	flush_icache_range((unsigned long)addr,
 	                   (unsigned long)addr + text_data);
 
+
+	down_write(&current->mm->mmap_sem);	
 	do_brk(ELF_PAGESTART(text_data + ELF_MIN_ALIGN - 1),
 		interp_ex->a_bss);
+	up_write(&current->mm->mmap_sem);
 	elf_entry = interp_ex->a_entry;
 
 out:
@@ -524,12 +551,13 @@
 
 	/* Now read in all of the header information */
 
-	retval = -ENOMEM;
 	if (loc->elf_ex.e_phentsize != sizeof(struct elf_phdr))
 		goto out;
-	if (loc->elf_ex.e_phnum > 65536U / sizeof(struct elf_phdr))
+	if (loc->elf_ex.e_phnum < 1 ||
+	 	loc->elf_ex.e_phnum > 65536U / sizeof(struct elf_phdr))
 		goto out;
 	size = loc->elf_ex.e_phnum * sizeof(struct elf_phdr);
+	retval = -ENOMEM;
 	elf_phdata = (struct elf_phdr *) kmalloc(size, GFP_KERNEL);
 	if (!elf_phdata)
 		goto out;
@@ -575,10 +603,12 @@
 			 * is an a.out format binary
 			 */
 
-			retval = -ENOMEM;
+			retval = -ENOEXEC;
 			if (elf_ppnt->p_filesz > PATH_MAX || 
-			    elf_ppnt->p_filesz == 0)
+			    elf_ppnt->p_filesz < 2)
 				goto out_free_file;
+
+			retval = -ENOMEM;
 			elf_interpreter = (char *) kmalloc(elf_ppnt->p_filesz,
 							   GFP_KERNEL);
 			if (!elf_interpreter)
@@ -593,7 +623,7 @@
 				goto out_free_interp;
 			}
 			/* make sure path is NULL terminated */
-			retval = -EINVAL;
+			retval = -ENOEXEC;
 			if (elf_interpreter[elf_ppnt->p_filesz - 1] != '\0')
 				goto out_free_interp;
 
@@ -727,7 +757,7 @@
 	/* Do this immediately, since STACK_TOP as used in setup_arg_pages
 	   may depend on the personality.  */
 	SET_PERSONALITY(loc->elf_ex, ibcs2_interpreter);
-	if (elf_read_implies_exec(loc->elf_ex, have_pt_gnu_stack))
+	if (elf_read_implies_exec(loc->elf_ex, executable_stack))
 		current->personality |= READ_IMPLIES_EXEC;
 
 	arch_pick_mmap_layout(current->mm);
@@ -736,7 +766,7 @@
 	   change some of these later */
 	current->mm->rss = 0;
 	current->mm->free_area_cache = current->mm->mmap_base;
-	retval = setup_arg_pages(bprm, executable_stack);
+	retval = setup_arg_pages(bprm, STACK_TOP, executable_stack);
 	if (retval < 0) {
 		send_sig(SIGKILL, current, 0);
 		goto out_free_dentry;
@@ -773,7 +803,14 @@
 				nbyte = ELF_MIN_ALIGN - nbyte;
 				if (nbyte > elf_brk - elf_bss)
 					nbyte = elf_brk - elf_bss;
-				clear_user((void __user *) elf_bss + load_bias, nbyte);
+				if (clear_user((void __user *)elf_bss +
+							load_bias, nbyte)) {
+					/*
+					 * This bss-zeroing can fail if the ELF
+					 * file specifies odd protections.  So
+					 * we don't check the return value
+					 */
+				}
 			}
 		}
 
@@ -857,7 +894,11 @@
 		send_sig(SIGKILL, current, 0);
 		goto out_free_dentry;
 	}
-	padzero(elf_bss);
+	if (padzero(elf_bss)) {
+		send_sig(SIGSEGV, current, 0);
+		retval = -EFAULT; /* Nobody gets to see this, but.. */
+		goto out_free_dentry;
+	}
 
 	if (elf_interpreter) {
 		if (interpreter_type == INTERPRETER_AOUT)
@@ -868,8 +909,9 @@
 						    interpreter,
 						    &interp_load_addr);
 		if (BAD_ADDR(elf_entry)) {
-			printk(KERN_ERR "Unable to load interpreter\n");
-			send_sig(SIGSEGV, current, 0);
+			printk(KERN_ERR "Unable to load interpreter %.128s\n",
+				elf_interpreter);
+			force_sig(SIGSEGV, current);
 			retval = -ENOEXEC; /* Nobody gets to see this, but.. */
 			goto out_free_dentry;
 		}
@@ -1020,12 +1062,18 @@
 		goto out_free_ph;
 
 	elf_bss = elf_phdata->p_vaddr + elf_phdata->p_filesz;
-	padzero(elf_bss);
+	if (padzero(elf_bss)) {
+		error = -EFAULT;
+		goto out_free_ph;
+	}
 
 	len = ELF_PAGESTART(elf_phdata->p_filesz + elf_phdata->p_vaddr + ELF_MIN_ALIGN - 1);
 	bss = elf_phdata->p_memsz + elf_phdata->p_vaddr;
-	if (bss > len)
+	if (bss > len) {
+		down_write(&current->mm->mmap_sem);
 		do_brk(len, bss - len);
+		up_write(&current->mm->mmap_sem);
+	}
 	error = 0;
 
 out_free_ph:
@@ -1154,7 +1202,7 @@
 	elf->e_entry = 0;
 	elf->e_phoff = sizeof(struct elfhdr);
 	elf->e_shoff = 0;
-	elf->e_flags = 0;
+	elf->e_flags = ELF_CORE_EFLAGS;
 	elf->e_ehsize = sizeof(struct elfhdr);
 	elf->e_phentsize = sizeof(struct elf_phdr);
 	elf->e_phnum = segs;
@@ -1201,7 +1249,7 @@
 	prstatus->pr_ppid = p->parent->pid;
 	prstatus->pr_pgrp = process_group(p);
 	prstatus->pr_sid = p->signal->session;
-	if (p->pid == p->tgid) {
+	if (thread_group_leader(p)) {
 		/*
 		 * This is the record for the group leader.  Add in the
 		 * cumulative times of previous dead threads.  This total
@@ -1212,20 +1260,20 @@
 		 * this and each other thread to finish dying after the
 		 * core dump synchronization phase.
 		 */
-		jiffies_to_timeval(p->utime + p->signal->utime,
+		cputime_to_timeval(cputime_add(p->utime, p->signal->utime),
 				   &prstatus->pr_utime);
-		jiffies_to_timeval(p->stime + p->signal->stime,
+		cputime_to_timeval(cputime_add(p->stime, p->signal->stime),
 				   &prstatus->pr_stime);
 	} else {
-		jiffies_to_timeval(p->utime, &prstatus->pr_utime);
-		jiffies_to_timeval(p->stime, &prstatus->pr_stime);
+		cputime_to_timeval(p->utime, &prstatus->pr_utime);
+		cputime_to_timeval(p->stime, &prstatus->pr_stime);
 	}
-	jiffies_to_timeval(p->signal->cutime, &prstatus->pr_cutime);
-	jiffies_to_timeval(p->signal->cstime, &prstatus->pr_cstime);
+	cputime_to_timeval(p->signal->cutime, &prstatus->pr_cutime);
+	cputime_to_timeval(p->signal->cstime, &prstatus->pr_cstime);
 }
 
-static void fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p,
-			struct mm_struct *mm)
+static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p,
+		       struct mm_struct *mm)
 {
 	int i, len;
 	
@@ -1235,8 +1283,9 @@
 	len = mm->arg_end - mm->arg_start;
 	if (len >= ELF_PRARGSZ)
 		len = ELF_PRARGSZ-1;
-	copy_from_user(&psinfo->pr_psargs,
-		       (const char __user *)mm->arg_start, len);
+	if (copy_from_user(&psinfo->pr_psargs,
+		           (const char __user *)mm->arg_start, len))
+		return -EFAULT;
 	for(i = 0; i < len; i++)
 		if (psinfo->pr_psargs[i] == 0)
 			psinfo->pr_psargs[i] = ' ';
@@ -1257,7 +1306,7 @@
 	SET_GID(psinfo->pr_gid, p->gid);
 	strncpy(psinfo->pr_fname, p->comm, sizeof(psinfo->pr_fname));
 	
-	return;
+	return 0;
 }
 
 /* Here is the structure in which status of each thread is captured. */
diff -Nru a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/fs/binfmt_elf_fdpic.c	2005-03-01 23:39:26 -08:00
@@ -0,0 +1,1101 @@
+/* binfmt_elf_fdpic.c: FDPIC ELF binary format
+ *
+ * Copyright (C) 2003, 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ * Derived from binfmt_elf.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.
+ */
+
+#include <linux/module.h>
+
+#include <linux/fs.h>
+#include <linux/stat.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/mman.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/binfmts.h>
+#include <linux/string.h>
+#include <linux/file.h>
+#include <linux/fcntl.h>
+#include <linux/slab.h>
+#include <linux/highmem.h>
+#include <linux/personality.h>
+#include <linux/ptrace.h>
+#include <linux/init.h>
+#include <linux/smp_lock.h>
+#include <linux/elf.h>
+#include <linux/elf-fdpic.h>
+#include <linux/elfcore.h>
+
+#include <asm/uaccess.h>
+#include <asm/param.h>
+#include <asm/pgalloc.h>
+
+typedef char *elf_caddr_t;
+#ifndef elf_addr_t
+#define elf_addr_t unsigned long
+#endif
+
+#if 0
+#define kdebug(fmt, ...) printk("FDPIC "fmt"\n" ,##__VA_ARGS__ )
+#else
+#define kdebug(fmt, ...) do {} while(0)
+#endif
+
+MODULE_LICENSE("GPL");
+
+static int load_elf_fdpic_binary(struct linux_binprm *bprm, struct pt_regs *regs);
+//static int load_elf_fdpic_library(struct file *);
+static int elf_fdpic_fetch_phdrs(struct elf_fdpic_params *params, struct file *file);
+static int elf_fdpic_map_file(struct elf_fdpic_params *params,
+			      struct file *file,
+			      struct mm_struct *mm,
+			      const char *what);
+
+static int create_elf_fdpic_tables(struct linux_binprm *bprm,
+				   struct mm_struct *mm,
+				   struct elf_fdpic_params *exec_params,
+				   struct elf_fdpic_params *interp_params);
+
+#ifndef CONFIG_MMU
+static int elf_fdpic_transfer_args_to_stack(struct linux_binprm *bprm, unsigned long *_sp);
+static int elf_fdpic_map_file_constdisp_on_uclinux(struct elf_fdpic_params *params,
+						   struct file *file,
+						   struct mm_struct *mm);
+#endif
+
+static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *params,
+					     struct file *file,
+					     struct mm_struct *mm);
+
+static struct linux_binfmt elf_fdpic_format = {
+	.module		= THIS_MODULE,
+	.load_binary	= load_elf_fdpic_binary,
+//	.load_shlib	= load_elf_fdpic_library,
+//	.core_dump	= elf_fdpic_core_dump,
+	.min_coredump	= ELF_EXEC_PAGESIZE,
+};
+
+static int __init init_elf_fdpic_binfmt(void)  { return register_binfmt(&elf_fdpic_format); }
+static void __exit exit_elf_fdpic_binfmt(void) { unregister_binfmt(&elf_fdpic_format); }
+
+module_init(init_elf_fdpic_binfmt)
+module_exit(exit_elf_fdpic_binfmt)
+
+static int is_elf_fdpic(struct elfhdr *hdr, struct file *file)
+{
+	if (memcmp(hdr->e_ident, ELFMAG, SELFMAG) != 0)
+		return 0;
+	if (hdr->e_type != ET_EXEC && hdr->e_type != ET_DYN)
+		return 0;
+	if (!elf_check_arch(hdr) || !elf_check_fdpic(hdr))
+		return 0;
+	if (!file->f_op || !file->f_op->mmap)
+		return 0;
+	return 1;
+}
+
+/*****************************************************************************/
+/*
+ * read the program headers table into memory
+ */
+static int elf_fdpic_fetch_phdrs(struct elf_fdpic_params *params, struct file *file)
+{
+	struct elf32_phdr *phdr;
+	unsigned long size;
+	int retval, loop;
+
+	if (params->hdr.e_phentsize != sizeof(struct elf_phdr))
+		return -ENOMEM;
+	if (params->hdr.e_phnum > 65536U / sizeof(struct elf_phdr))
+		return -ENOMEM;
+
+	size = params->hdr.e_phnum * sizeof(struct elf_phdr);
+	params->phdrs = kmalloc(size, GFP_KERNEL);
+	if (!params->phdrs)
+		return -ENOMEM;
+
+	retval = kernel_read(file, params->hdr.e_phoff, (char *) params->phdrs, size);
+	if (retval < 0)
+		return retval;
+
+	/* determine stack size for this binary */
+	phdr = params->phdrs;
+	for (loop = 0; loop < params->hdr.e_phnum; loop++, phdr++) {
+		if (phdr->p_type != PT_GNU_STACK)
+			continue;
+
+		if (phdr->p_flags & PF_X)
+			params->flags |= ELF_FDPIC_FLAG_EXEC_STACK;
+		else
+			params->flags |= ELF_FDPIC_FLAG_NOEXEC_STACK;
+
+		params->stack_size = phdr->p_memsz;
+		break;
+	}
+
+	return 0;
+} /* end elf_fdpic_fetch_phdrs() */
+
+/*****************************************************************************/
+/*
+ * load an fdpic binary into various bits of memory
+ */
+static int load_elf_fdpic_binary(struct linux_binprm *bprm, struct pt_regs *regs)
+{
+	struct elf_fdpic_params exec_params, interp_params;
+	struct elf_phdr *phdr;
+	unsigned long stack_size;
+	struct file *interpreter = NULL; /* to shut gcc up */
+	char *interpreter_name = NULL;
+	int executable_stack;
+	int retval, i;
+
+	memset(&exec_params, 0, sizeof(exec_params));
+	memset(&interp_params, 0, sizeof(interp_params));
+
+	exec_params.hdr = *(struct elfhdr *) bprm->buf;
+	exec_params.flags = ELF_FDPIC_FLAG_PRESENT | ELF_FDPIC_FLAG_EXECUTABLE;
+
+	/* check that this is a binary we know how to deal with */
+	retval = -ENOEXEC;
+	if (!is_elf_fdpic(&exec_params.hdr, bprm->file))
+		goto error;
+
+	/* read the program header table */
+	retval = elf_fdpic_fetch_phdrs(&exec_params, bprm->file);
+	if (retval < 0)
+		goto error;
+
+	/* scan for a program header that specifies an interpreter */
+	phdr = exec_params.phdrs;
+
+	for (i = 0; i < exec_params.hdr.e_phnum; i++, phdr++) {
+		switch (phdr->p_type) {
+		case PT_INTERP:
+			retval = -ENOMEM;
+			if (phdr->p_filesz > PATH_MAX)
+				goto error;
+			retval = -ENOENT;
+			if (phdr->p_filesz < 2)
+				goto error;
+
+			/* read the name of the interpreter into memory */
+			interpreter_name = (char *) kmalloc(phdr->p_filesz, GFP_KERNEL);
+			if (!interpreter_name)
+				goto error;
+
+			retval = kernel_read(bprm->file,
+					     phdr->p_offset,
+					     interpreter_name,
+					     phdr->p_filesz);
+			if (retval < 0)
+				goto error;
+
+			retval = -ENOENT;
+			if (interpreter_name[phdr->p_filesz - 1] != '\0')
+				goto error;
+
+			kdebug("Using ELF interpreter %s", interpreter_name);
+
+			/* replace the program with the interpreter */
+			interpreter = open_exec(interpreter_name);
+			retval = PTR_ERR(interpreter);
+			if (IS_ERR(interpreter)) {
+				interpreter = NULL;
+				goto error;
+			}
+
+			retval = kernel_read(interpreter, 0, bprm->buf, BINPRM_BUF_SIZE);
+			if (retval < 0)
+				goto error;
+
+			interp_params.hdr = *((struct elfhdr *) bprm->buf);
+			break;
+
+		case PT_LOAD:
+#ifdef CONFIG_MMU
+			if (exec_params.load_addr == 0)
+				exec_params.load_addr = phdr->p_vaddr;
+#endif
+			break;
+		}
+
+	}
+
+	if (elf_check_const_displacement(&exec_params.hdr))
+		exec_params.flags |= ELF_FDPIC_FLAG_CONSTDISP;
+
+	/* perform insanity checks on the interpreter */
+	if (interpreter_name) {
+		retval = -ELIBBAD;
+		if (!is_elf_fdpic(&interp_params.hdr, interpreter))
+			goto error;
+
+		interp_params.flags = ELF_FDPIC_FLAG_PRESENT;
+
+		/* read the interpreter's program header table */
+		retval = elf_fdpic_fetch_phdrs(&interp_params, interpreter);
+		if (retval < 0)
+			goto error;
+	}
+
+	stack_size = exec_params.stack_size;
+	if (stack_size < interp_params.stack_size)
+		stack_size = interp_params.stack_size;
+
+	if (exec_params.flags & ELF_FDPIC_FLAG_EXEC_STACK)
+		executable_stack = EXSTACK_ENABLE_X;
+	else if (exec_params.flags & ELF_FDPIC_FLAG_NOEXEC_STACK)
+		executable_stack = EXSTACK_DISABLE_X;
+	else if (interp_params.flags & ELF_FDPIC_FLAG_EXEC_STACK)
+		executable_stack = EXSTACK_ENABLE_X;
+	else if (interp_params.flags & ELF_FDPIC_FLAG_NOEXEC_STACK)
+		executable_stack = EXSTACK_DISABLE_X;
+	else
+		executable_stack = EXSTACK_DEFAULT;
+
+	retval = -ENOEXEC;
+	if (stack_size == 0)
+		goto error;
+
+	if (elf_check_const_displacement(&interp_params.hdr))
+		interp_params.flags |= ELF_FDPIC_FLAG_CONSTDISP;
+
+	/* flush all traces of the currently running executable */
+	retval = flush_old_exec(bprm);
+	if (retval)
+		goto error;
+
+	/* there's now no turning back... the old userspace image is dead,
+	 * defunct, deceased, etc. after this point we have to exit via
+	 * error_kill */
+	set_personality(PER_LINUX_FDPIC);
+	set_binfmt(&elf_fdpic_format);
+
+	current->mm->start_code = 0;
+	current->mm->end_code = 0;
+	current->mm->start_stack = 0;
+	current->mm->start_data = 0;
+	current->mm->end_data = 0;
+	current->mm->context.exec_fdpic_loadmap = 0;
+	current->mm->context.interp_fdpic_loadmap = 0;
+
+	current->flags &= ~PF_FORKNOEXEC;
+
+#ifdef CONFIG_MMU
+	elf_fdpic_arch_lay_out_mm(&exec_params,
+				  &interp_params,
+				  &current->mm->start_stack,
+				  &current->mm->start_brk);
+#endif
+
+	/* do this so that we can load the interpreter, if need be
+	 * - we will change some of these later
+	 */
+	current->mm->rss = 0;
+
+#ifdef CONFIG_MMU
+	retval = setup_arg_pages(bprm, current->mm->start_stack, executable_stack);
+	if (retval < 0) {
+		send_sig(SIGKILL, current, 0);
+		goto error_kill;
+	}
+#endif
+
+	/* load the executable and interpreter into memory */
+	retval = elf_fdpic_map_file(&exec_params, bprm->file, current->mm, "executable");
+	if (retval < 0)
+		goto error_kill;
+
+	if (interpreter_name) {
+		retval = elf_fdpic_map_file(&interp_params, interpreter,
+					    current->mm, "interpreter");
+		if (retval < 0) {
+			printk(KERN_ERR "Unable to load interpreter\n");
+			goto error_kill;
+		}
+
+		allow_write_access(interpreter);
+		fput(interpreter);
+		interpreter = NULL;
+	}
+
+#ifdef CONFIG_MMU
+	if (!current->mm->start_brk)
+		current->mm->start_brk = current->mm->end_data;
+
+	current->mm->brk = current->mm->start_brk = PAGE_ALIGN(current->mm->start_brk);
+
+#else
+	/* create a stack and brk area big enough for everyone
+	 * - the brk heap starts at the bottom and works up
+	 * - the stack starts at the top and works down
+	 */
+	stack_size = (stack_size + PAGE_SIZE - 1) & PAGE_MASK;
+	if (stack_size < PAGE_SIZE * 2)
+		stack_size = PAGE_SIZE * 2;
+
+	down_write(&current->mm->mmap_sem);
+	current->mm->start_brk = do_mmap(NULL,
+					 0,
+					 stack_size,
+					 PROT_READ | PROT_WRITE | PROT_EXEC,
+					 MAP_PRIVATE | MAP_ANON | MAP_GROWSDOWN,
+					 0);
+
+	if (IS_ERR((void *) current->mm->start_brk)) {
+		up_write(&current->mm->mmap_sem);
+		retval = current->mm->start_brk;
+		current->mm->start_brk = 0;
+		goto error_kill;
+	}
+
+	if (do_mremap(current->mm->start_brk,
+		      stack_size,
+		      ksize((char *) current->mm->start_brk),
+		      0, 0
+		      ) == current->mm->start_brk
+	    )
+		stack_size = ksize((char *) current->mm->start_brk);
+	up_write(&current->mm->mmap_sem);
+
+	current->mm->brk = current->mm->start_brk;
+	current->mm->context.end_brk = current->mm->start_brk;
+	current->mm->context.end_brk += (stack_size > PAGE_SIZE) ? (stack_size - PAGE_SIZE) : 0;
+	current->mm->start_stack = current->mm->start_brk + stack_size;
+#endif
+
+	compute_creds(bprm);
+	current->flags &= ~PF_FORKNOEXEC;
+	if (create_elf_fdpic_tables(bprm, current->mm, &exec_params, &interp_params) < 0)
+		goto error_kill;
+
+	kdebug("- start_code  %lx",	(long) current->mm->start_code);
+	kdebug("- end_code    %lx",	(long) current->mm->end_code);
+	kdebug("- start_data  %lx",	(long) current->mm->start_data);
+	kdebug("- end_data    %lx",	(long) current->mm->end_data);
+	kdebug("- start_brk   %lx",	(long) current->mm->start_brk);
+	kdebug("- brk         %lx",	(long) current->mm->brk);
+	kdebug("- start_stack %lx",	(long) current->mm->start_stack);
+
+#ifdef ELF_FDPIC_PLAT_INIT
+	/*
+	 * The ABI may specify that certain registers be set up in special
+	 * ways (on i386 %edx is the address of a DT_FINI function, for
+	 * example.  This macro performs whatever initialization to
+	 * the regs structure is required.
+	 */
+	ELF_FDPIC_PLAT_INIT(regs,
+			    exec_params.map_addr,
+			    interp_params.map_addr,
+			    interp_params.dynamic_addr ?: exec_params.dynamic_addr
+			    );
+#endif
+
+	/* everything is now ready... get the userspace context ready to roll */
+	start_thread(regs,
+		     interp_params.entry_addr ?: exec_params.entry_addr,
+		     current->mm->start_stack);
+
+	if (unlikely(current->ptrace & PT_PTRACED)) {
+		if (current->ptrace & PT_TRACE_EXEC)
+			ptrace_notify ((PTRACE_EVENT_EXEC << 8) | SIGTRAP);
+		else
+			send_sig(SIGTRAP, current, 0);
+	}
+
+	retval = 0;
+
+error:
+	if (interpreter) {
+		allow_write_access(interpreter);
+		fput(interpreter);
+	}
+	if (interpreter_name)
+		kfree(interpreter_name);
+	if (exec_params.phdrs)
+		kfree(exec_params.phdrs);
+	if (exec_params.loadmap)
+		kfree(exec_params.loadmap);
+	if (interp_params.phdrs)
+		kfree(interp_params.phdrs);
+	if (interp_params.loadmap)
+		kfree(interp_params.loadmap);
+	return retval;
+
+	/* unrecoverable error - kill the process */
+ error_kill:
+	send_sig(SIGSEGV, current, 0);
+	goto error;
+
+} /* end load_elf_fdpic_binary() */
+
+/*****************************************************************************/
+/*
+ * present useful information to the program
+ */
+static int create_elf_fdpic_tables(struct linux_binprm *bprm,
+				   struct mm_struct *mm,
+				   struct elf_fdpic_params *exec_params,
+				   struct elf_fdpic_params *interp_params)
+{
+	unsigned long sp, csp, nitems;
+	elf_caddr_t *argv, *envp;
+	size_t platform_len = 0, len;
+	char *k_platform, *u_platform, *p;
+	long hwcap;
+	int loop;
+
+	/* we're going to shovel a whole load of stuff onto the stack */
+#ifdef CONFIG_MMU
+	sp = bprm->p;
+#else
+	sp = mm->start_stack;
+
+	/* stack the program arguments and environment */
+	if (elf_fdpic_transfer_args_to_stack(bprm, &sp) < 0)
+		return -EFAULT;
+#endif
+
+	/* get hold of platform and hardware capabilities masks for the machine
+	 * we are running on.  In some cases (Sparc), this info is impossible
+	 * to get, in others (i386) it is merely difficult.
+	 */
+	hwcap = ELF_HWCAP;
+	k_platform = ELF_PLATFORM;
+
+	if (k_platform) {
+		platform_len = strlen(k_platform) + 1;
+		sp -= platform_len;
+		if (__copy_to_user(u_platform, k_platform, platform_len) != 0)
+			return -EFAULT;
+	}
+
+	u_platform = (char *) sp;
+
+#if defined(__i386__) && defined(CONFIG_SMP)
+	/* in some cases (e.g. Hyper-Threading), we want to avoid L1 evictions
+	 * by the processes running on the same package. One thing we can do
+	 * is to shuffle the initial stack for them.
+	 *
+	 * the conditionals here are unneeded, but kept in to make the
+	 * code behaviour the same as pre change unless we have hyperthreaded
+	 * processors. This keeps Mr Marcelo Person happier but should be
+	 * removed for 2.5
+	 */
+	if (smp_num_siblings > 1)
+		sp = sp - ((current->pid % 64) << 7);
+#endif
+
+	sp &= ~7UL;
+
+	/* stack the load map(s) */
+	len = sizeof(struct elf32_fdpic_loadmap);
+	len += sizeof(struct elf32_fdpic_loadseg) * exec_params->loadmap->nsegs;
+	sp = (sp - len) & ~7UL;
+	exec_params->map_addr = sp;
+
+	if (copy_to_user((void *) sp, exec_params->loadmap, len) != 0)
+		return -EFAULT;
+
+	current->mm->context.exec_fdpic_loadmap = (unsigned long) sp;
+
+	if (interp_params->loadmap) {
+		len = sizeof(struct elf32_fdpic_loadmap);
+		len += sizeof(struct elf32_fdpic_loadseg) * interp_params->loadmap->nsegs;
+		sp = (sp - len) & ~7UL;
+		interp_params->map_addr = sp;
+
+		if (copy_to_user((void *) sp, interp_params->loadmap, len) != 0)
+			return -EFAULT;
+
+		current->mm->context.interp_fdpic_loadmap = (unsigned long) sp;
+	}
+
+	/* force 16 byte _final_ alignment here for generality */
+#define DLINFO_ITEMS 13
+
+	nitems = 1 + DLINFO_ITEMS + (k_platform ? 1 : 0);
+#ifdef DLINFO_ARCH_ITEMS
+	nitems += DLINFO_ARCH_ITEMS;
+#endif
+
+	csp = sp;
+	sp -= nitems * 2 * sizeof(unsigned long);
+	sp -= (bprm->envc + 1) * sizeof(char *);	/* envv[] */
+	sp -= (bprm->argc + 1) * sizeof(char *);	/* argv[] */
+	sp -= 1 * sizeof(unsigned long);		/* argc */
+
+	csp -= sp & 15UL;
+	sp -= sp & 15UL;
+
+	/* put the ELF interpreter info on the stack */
+#define NEW_AUX_ENT(nr, id, val)						\
+	do {									\
+		struct { unsigned long _id, _val; } *ent = (void *) csp;	\
+		__put_user((id), &ent[nr]._id);					\
+		__put_user((val), &ent[nr]._val);				\
+	} while (0)
+
+	csp -= 2 * sizeof(unsigned long);
+	NEW_AUX_ENT(0, AT_NULL, 0);
+	if (k_platform) {
+		csp -= 2 * sizeof(unsigned long);
+		NEW_AUX_ENT(0, AT_PLATFORM, (elf_addr_t)(unsigned long) u_platform);
+	}
+
+	csp -= DLINFO_ITEMS * 2 * sizeof(unsigned long);
+	NEW_AUX_ENT( 0, AT_HWCAP,		hwcap);
+	NEW_AUX_ENT( 1, AT_PAGESZ,		PAGE_SIZE);
+	NEW_AUX_ENT( 2, AT_CLKTCK,		CLOCKS_PER_SEC);
+	NEW_AUX_ENT( 3, AT_PHDR,		exec_params->ph_addr);
+	NEW_AUX_ENT( 4, AT_PHENT,		sizeof(struct elf_phdr));
+	NEW_AUX_ENT( 5, AT_PHNUM,		exec_params->hdr.e_phnum);
+	NEW_AUX_ENT( 6,	AT_BASE,		interp_params->elfhdr_addr);
+	NEW_AUX_ENT( 7, AT_FLAGS,		0);
+	NEW_AUX_ENT( 8, AT_ENTRY,		exec_params->entry_addr);
+	NEW_AUX_ENT( 9, AT_UID,			(elf_addr_t) current->uid);
+	NEW_AUX_ENT(10, AT_EUID,		(elf_addr_t) current->euid);
+	NEW_AUX_ENT(11, AT_GID,			(elf_addr_t) current->gid);
+	NEW_AUX_ENT(12, AT_EGID,		(elf_addr_t) current->egid);
+
+#ifdef ARCH_DLINFO
+	/* ARCH_DLINFO must come last so platform specific code can enforce
+	 * special alignment requirements on the AUXV if necessary (eg. PPC).
+	 */
+	ARCH_DLINFO;
+#endif
+#undef NEW_AUX_ENT
+
+	/* allocate room for argv[] and envv[] */
+	csp -= (bprm->envc + 1) * sizeof(elf_caddr_t);
+	envp = (elf_caddr_t *) csp;
+	csp -= (bprm->argc + 1) * sizeof(elf_caddr_t);
+	argv = (elf_caddr_t *) csp;
+
+	/* stack argc */
+	csp -= sizeof(unsigned long);
+	__put_user(bprm->argc, (unsigned long *) csp);
+
+	if (csp != sp)
+		BUG();
+
+	/* fill in the argv[] array */
+#ifdef CONFIG_MMU
+	current->mm->arg_start = bprm->p;
+#else
+	current->mm->arg_start = current->mm->start_stack - (MAX_ARG_PAGES * PAGE_SIZE - bprm->p);
+#endif
+
+	p = (char *) current->mm->arg_start;
+	for (loop = bprm->argc; loop > 0; loop--) {
+		__put_user((elf_caddr_t) p, argv++);
+		len = strnlen_user(p, PAGE_SIZE * MAX_ARG_PAGES);
+		if (!len || len > PAGE_SIZE * MAX_ARG_PAGES)
+			return -EINVAL;
+		p += len;
+	}
+	__put_user(NULL, argv);
+	current->mm->arg_end = (unsigned long) p;
+
+	/* fill in the envv[] array */
+	current->mm->env_start = (unsigned long) p;
+	for (loop = bprm->envc; loop > 0; loop--) {
+		__put_user((elf_caddr_t)(unsigned long) p, envp++);
+		len = strnlen_user(p, PAGE_SIZE * MAX_ARG_PAGES);
+		if (!len || len > PAGE_SIZE * MAX_ARG_PAGES)
+			return -EINVAL;
+		p += len;
+	}
+	__put_user(NULL, envp);
+	current->mm->env_end = (unsigned long) p;
+
+	mm->start_stack = (unsigned long) sp;
+	return 0;
+} /* end create_elf_fdpic_tables() */
+
+/*****************************************************************************/
+/*
+ * transfer the program arguments and environment from the holding pages onto
+ * the stack
+ */
+#ifndef CONFIG_MMU
+static int elf_fdpic_transfer_args_to_stack(struct linux_binprm *bprm, unsigned long *_sp)
+{
+	unsigned long index, stop, sp;
+	char *src;
+	int ret = 0;
+
+	stop = bprm->p >> PAGE_SHIFT;
+	sp = *_sp;
+
+	for (index = MAX_ARG_PAGES - 1; index >= stop; index--) {
+		src = kmap(bprm->page[index]);
+		sp -= PAGE_SIZE;
+		if (copy_to_user((void *) sp, src, PAGE_SIZE) != 0)
+			ret = -EFAULT;
+		kunmap(bprm->page[index]);
+		if (ret < 0)
+			goto out;
+	}
+
+	*_sp = (*_sp - (MAX_ARG_PAGES * PAGE_SIZE - bprm->p)) & ~15;
+
+ out:
+	return ret;
+} /* end elf_fdpic_transfer_args_to_stack() */
+#endif
+
+/*****************************************************************************/
+/*
+ * load the appropriate binary image (executable or interpreter) into memory
+ * - we assume no MMU is available
+ * - if no other PIC bits are set in params->hdr->e_flags
+ *   - we assume that the LOADable segments in the binary are independently relocatable
+ *   - we assume R/O executable segments are shareable
+ * - else
+ *   - we assume the loadable parts of the image to require fixed displacement
+ *   - the image is not shareable
+ */
+static int elf_fdpic_map_file(struct elf_fdpic_params *params,
+			      struct file *file,
+			      struct mm_struct *mm,
+			      const char *what)
+{
+	struct elf32_fdpic_loadmap *loadmap;
+#ifdef CONFIG_MMU
+	struct elf32_fdpic_loadseg *mseg;
+#endif
+	struct elf32_fdpic_loadseg *seg;
+	struct elf32_phdr *phdr;
+	unsigned long load_addr, stop;
+	unsigned nloads, tmp;
+	size_t size;
+	int loop, ret;
+
+	/* allocate a load map table */
+	nloads = 0;
+	for (loop = 0; loop < params->hdr.e_phnum; loop++)
+		if (params->phdrs[loop].p_type == PT_LOAD)
+			nloads++;
+
+	if (nloads == 0)
+		return -ELIBBAD;
+
+	size = sizeof(*loadmap) + nloads * sizeof(*seg);
+	loadmap = kmalloc(size, GFP_KERNEL);
+	if (!loadmap)
+		return -ENOMEM;
+
+	params->loadmap = loadmap;
+	memset(loadmap, 0, size);
+
+	loadmap->version = ELF32_FDPIC_LOADMAP_VERSION;
+	loadmap->nsegs = nloads;
+
+	load_addr = params->load_addr;
+	seg = loadmap->segs;
+
+	/* map the requested LOADs into the memory space */
+	switch (params->flags & ELF_FDPIC_FLAG_ARRANGEMENT) {
+	case ELF_FDPIC_FLAG_CONSTDISP:
+	case ELF_FDPIC_FLAG_CONTIGUOUS:
+#ifndef CONFIG_MMU
+		ret = elf_fdpic_map_file_constdisp_on_uclinux(params, file, mm);
+		if (ret < 0)
+			return ret;
+		break;
+#endif
+	default:
+		ret = elf_fdpic_map_file_by_direct_mmap(params, file, mm);
+		if (ret < 0)
+			return ret;
+		break;
+	}
+
+	/* map the entry point */
+	if (params->hdr.e_entry) {
+		seg = loadmap->segs;
+		for (loop = loadmap->nsegs; loop > 0; loop--, seg++) {
+			if (params->hdr.e_entry >= seg->p_vaddr &&
+			    params->hdr.e_entry < seg->p_vaddr + seg->p_memsz
+			    ) {
+				params->entry_addr =
+					(params->hdr.e_entry - seg->p_vaddr) + seg->addr;
+				break;
+			}
+		}
+	}
+
+	/* determine where the program header table has wound up if mapped */
+	stop = params->hdr.e_phoff + params->hdr.e_phnum * sizeof (struct elf_phdr);
+	phdr = params->phdrs;
+
+	for (loop = 0; loop < params->hdr.e_phnum; loop++, phdr++) {
+		if (phdr->p_type != PT_LOAD)
+			continue;
+
+		if (phdr->p_offset > params->hdr.e_phoff ||
+		    phdr->p_offset + phdr->p_filesz < stop)
+			continue;
+
+		seg = loadmap->segs;
+		for (loop = loadmap->nsegs; loop > 0; loop--, seg++) {
+			if (phdr->p_vaddr >= seg->p_vaddr &&
+			    phdr->p_vaddr + phdr->p_filesz <= seg->p_vaddr + seg->p_memsz
+			    ) {
+				params->ph_addr = (phdr->p_vaddr - seg->p_vaddr) + seg->addr +
+					params->hdr.e_phoff - phdr->p_offset;
+				break;
+			}
+		}
+		break;
+	}
+
+	/* determine where the dynamic section has wound up if there is one */
+	phdr = params->phdrs;
+	for (loop = 0; loop < params->hdr.e_phnum; loop++, phdr++) {
+		if (phdr->p_type != PT_DYNAMIC)
+			continue;
+
+		seg = loadmap->segs;
+		for (loop = loadmap->nsegs; loop > 0; loop--, seg++) {
+			if (phdr->p_vaddr >= seg->p_vaddr &&
+			    phdr->p_vaddr + phdr->p_memsz <= seg->p_vaddr + seg->p_memsz
+			    ) {
+				params->dynamic_addr = (phdr->p_vaddr - seg->p_vaddr) + seg->addr;
+
+				/* check the dynamic section contains at least one item, and that
+				 * the last item is a NULL entry */
+				if (phdr->p_memsz == 0 ||
+				    phdr->p_memsz % sizeof(Elf32_Dyn) != 0)
+					goto dynamic_error;
+
+				tmp = phdr->p_memsz / sizeof(Elf32_Dyn);
+				if (((Elf32_Dyn *) params->dynamic_addr)[tmp - 1].d_tag != 0)
+					goto dynamic_error;
+				break;
+			}
+		}
+		break;
+	}
+
+	/* now elide adjacent segments in the load map on MMU linux
+	 * - on uClinux the holes between may actually be filled with system stuff or stuff from
+	 *   other processes
+	 */
+#ifdef CONFIG_MMU
+	nloads = loadmap->nsegs;
+	mseg = loadmap->segs;
+	seg = mseg + 1;
+	for (loop = 1; loop < nloads; loop++) {
+		/* see if we have a candidate for merging */
+		if (seg->p_vaddr - mseg->p_vaddr == seg->addr - mseg->addr) {
+			load_addr = PAGE_ALIGN(mseg->addr + mseg->p_memsz);
+			if (load_addr == (seg->addr & PAGE_MASK)) {
+				mseg->p_memsz += load_addr - (mseg->addr + mseg->p_memsz);
+				mseg->p_memsz += seg->addr & ~PAGE_MASK;
+				mseg->p_memsz += seg->p_memsz;
+				loadmap->nsegs--;
+				continue;
+			}
+		}
+
+		mseg++;
+		if (mseg != seg)
+			*mseg = *seg;
+	}
+#endif
+
+	kdebug("Mapped Object [%s]:", what);
+	kdebug("- elfhdr   : %lx", params->elfhdr_addr);
+	kdebug("- entry    : %lx", params->entry_addr);
+	kdebug("- PHDR[]   : %lx", params->ph_addr);
+	kdebug("- DYNAMIC[]: %lx", params->dynamic_addr);
+	seg = loadmap->segs;
+	for (loop = 0; loop < loadmap->nsegs; loop++, seg++)
+		kdebug("- LOAD[%d] : %08x-%08x [va=%x ms=%x]",
+		       loop,
+		       seg->addr, seg->addr + seg->p_memsz - 1,
+		       seg->p_vaddr, seg->p_memsz);
+
+	return 0;
+
+ dynamic_error:
+	printk("ELF FDPIC %s with invalid DYNAMIC section (inode=%lu)\n",
+	       what, file->f_dentry->d_inode->i_ino);
+	return -ELIBBAD;
+} /* end elf_fdpic_map_file() */
+
+/*****************************************************************************/
+/*
+ * map a file with constant displacement under uClinux
+ */
+#ifndef CONFIG_MMU
+static int elf_fdpic_map_file_constdisp_on_uclinux(struct elf_fdpic_params *params,
+						   struct file *file,
+						   struct mm_struct *mm)
+{
+	struct elf32_fdpic_loadseg *seg;
+	struct elf32_phdr *phdr;
+	unsigned long load_addr, base = ULONG_MAX, top = 0, maddr = 0, mflags;
+	loff_t fpos;
+	int loop, ret;
+
+	load_addr = params->load_addr;
+	seg = params->loadmap->segs;
+
+	/* determine the bounds of the contiguous overall allocation we must make */
+	phdr = params->phdrs;
+	for (loop = 0; loop < params->hdr.e_phnum; loop++, phdr++) {
+		if (params->phdrs[loop].p_type != PT_LOAD)
+			continue;
+
+		if (base > phdr->p_vaddr)
+			base = phdr->p_vaddr;
+		if (top < phdr->p_vaddr + phdr->p_memsz)
+			top = phdr->p_vaddr + phdr->p_memsz;
+	}
+
+	/* allocate one big anon block for everything */
+	mflags = MAP_PRIVATE;
+	if (params->flags & ELF_FDPIC_FLAG_EXECUTABLE)
+		mflags |= MAP_EXECUTABLE;
+
+	down_write(&mm->mmap_sem);
+	maddr = do_mmap(NULL, load_addr, top - base,
+			PROT_READ | PROT_WRITE | PROT_EXEC, mflags, 0);
+	up_write(&mm->mmap_sem);
+	if (IS_ERR((void *) maddr))
+		return (int) maddr;
+
+	if (load_addr != 0)
+		load_addr += PAGE_ALIGN(top - base);
+
+	/* and then load the file segments into it */
+	phdr = params->phdrs;
+	for (loop = 0; loop < params->hdr.e_phnum; loop++, phdr++) {
+		if (params->phdrs[loop].p_type != PT_LOAD)
+			continue;
+
+		fpos = phdr->p_offset;
+
+		seg->addr = maddr + (phdr->p_vaddr - base);
+		seg->p_vaddr = phdr->p_vaddr;
+		seg->p_memsz = phdr->p_memsz;
+
+		ret = file->f_op->read(file, (void *) seg->addr, phdr->p_filesz, &fpos);
+		if (ret < 0)
+			return ret;
+
+		/* map the ELF header address if in this segment */
+		if (phdr->p_offset == 0)
+			params->elfhdr_addr = seg->addr;
+
+		/* clear any space allocated but not loaded */
+		if (phdr->p_filesz < phdr->p_memsz)
+			clear_user((void *) (seg->addr + phdr->p_filesz),
+				   phdr->p_memsz - phdr->p_filesz);
+
+		if (mm) {
+			if (phdr->p_flags & PF_X) {
+				mm->start_code = seg->addr;
+				mm->end_code = seg->addr + phdr->p_memsz;
+			}
+			else if (!mm->start_data) {
+				mm->start_data = seg->addr;
+#ifndef CONFIG_MMU
+				mm->end_data = seg->addr + phdr->p_memsz;
+#endif
+			}
+
+#ifdef CONFIG_MMU
+			if (seg->addr + phdr->p_memsz > mm->end_data)
+				mm->end_data = seg->addr + phdr->p_memsz;
+#endif
+		}
+
+		seg++;
+	}
+
+	return 0;
+} /* end elf_fdpic_map_file_constdisp_on_uclinux() */
+#endif
+
+/*****************************************************************************/
+/*
+ * map a binary by direct mmap() of the individual PT_LOAD segments
+ */
+static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *params,
+					     struct file *file,
+					     struct mm_struct *mm)
+{
+	struct elf32_fdpic_loadseg *seg;
+	struct elf32_phdr *phdr;
+	unsigned long load_addr, delta_vaddr;
+	int loop, dvset;
+
+	load_addr = params->load_addr;
+	delta_vaddr = 0;
+	dvset = 0;
+
+	seg = params->loadmap->segs;
+
+	/* deal with each load segment separately */
+	phdr = params->phdrs;
+	for (loop = 0; loop < params->hdr.e_phnum; loop++, phdr++) {
+		unsigned long maddr, disp, excess, excess1;
+		int prot = 0, flags;
+
+		if (phdr->p_type != PT_LOAD)
+			continue;
+
+		kdebug("[LOAD] va=%lx of=%lx fs=%lx ms=%lx",
+		       (unsigned long) phdr->p_vaddr,
+		       (unsigned long) phdr->p_offset,
+		       (unsigned long) phdr->p_filesz,
+		       (unsigned long) phdr->p_memsz);
+
+		/* determine the mapping parameters */
+		if (phdr->p_flags & PF_R) prot |= PROT_READ;
+		if (phdr->p_flags & PF_W) prot |= PROT_WRITE;
+		if (phdr->p_flags & PF_X) prot |= PROT_EXEC;
+
+		flags = MAP_PRIVATE | MAP_DENYWRITE;
+		if (params->flags & ELF_FDPIC_FLAG_EXECUTABLE)
+			flags |= MAP_EXECUTABLE;
+
+		maddr = 0;
+
+		switch (params->flags & ELF_FDPIC_FLAG_ARRANGEMENT) {
+		case ELF_FDPIC_FLAG_INDEPENDENT:
+			/* PT_LOADs are independently locatable */
+			break;
+
+		case ELF_FDPIC_FLAG_HONOURVADDR:
+			/* the specified virtual address must be honoured */
+			maddr = phdr->p_vaddr;
+			flags |= MAP_FIXED;
+			break;
+
+		case ELF_FDPIC_FLAG_CONSTDISP:
+			/* constant displacement
+			 * - can be mapped anywhere, but must be mapped as a unit
+			 */
+			if (!dvset) {
+				maddr = load_addr;
+				delta_vaddr = phdr->p_vaddr;
+				dvset = 1;
+			}
+			else {
+				maddr = load_addr + phdr->p_vaddr - delta_vaddr;
+				flags |= MAP_FIXED;
+			}
+			break;
+
+		case ELF_FDPIC_FLAG_CONTIGUOUS:
+			/* contiguity handled later */
+			break;
+
+		default:
+			BUG();
+		}
+
+		maddr &= PAGE_MASK;
+
+		/* create the mapping */
+		disp = phdr->p_vaddr & ~PAGE_MASK;
+		down_write(&mm->mmap_sem);
+		maddr = do_mmap(file, maddr, phdr->p_memsz + disp, prot, flags,
+				phdr->p_offset - disp);
+		up_write(&mm->mmap_sem);
+
+		kdebug("mmap[%d] <file> sz=%lx pr=%x fl=%x of=%lx --> %08lx",
+		       loop, phdr->p_memsz + disp, prot, flags, phdr->p_offset - disp,
+		       maddr);
+
+		if (IS_ERR((void *) maddr))
+			return (int) maddr;
+
+		if ((params->flags & ELF_FDPIC_FLAG_ARRANGEMENT) == ELF_FDPIC_FLAG_CONTIGUOUS)
+			load_addr += PAGE_ALIGN(phdr->p_memsz + disp);
+
+		seg->addr = maddr + disp;
+		seg->p_vaddr = phdr->p_vaddr;
+		seg->p_memsz = phdr->p_memsz;
+
+		/* map the ELF header address if in this segment */
+		if (phdr->p_offset == 0)
+			params->elfhdr_addr = seg->addr;
+
+		/* clear the bit between beginning of mapping and beginning of PT_LOAD */
+		if (prot & PROT_WRITE && disp > 0) {
+			kdebug("clear[%d] ad=%lx sz=%lx", loop, maddr, disp);
+			clear_user((void *) maddr, disp);
+			maddr += disp;
+		}
+
+		/* clear any space allocated but not loaded
+		 * - on uClinux we can just clear the lot
+		 * - on MMU linux we'll get a SIGBUS beyond the last page
+		 *   extant in the file
+		 */
+		excess = phdr->p_memsz - phdr->p_filesz;
+		excess1 = PAGE_SIZE - ((maddr + phdr->p_filesz) & ~PAGE_MASK);
+
+#ifdef CONFIG_MMU
+
+		if (excess > excess1) {
+			unsigned long xaddr = maddr + phdr->p_filesz + excess1;
+			unsigned long xmaddr;
+
+			flags |= MAP_FIXED | MAP_ANONYMOUS;
+			down_write(&mm->mmap_sem);
+			xmaddr = do_mmap(NULL, xaddr, excess - excess1, prot, flags, 0);
+			up_write(&mm->mmap_sem);
+
+			kdebug("mmap[%d] <anon>"
+			       " ad=%lx sz=%lx pr=%x fl=%x of=0 --> %08lx",
+			       loop, xaddr, excess - excess1, prot, flags, xmaddr);
+
+			if (xmaddr != xaddr)
+				return -ENOMEM;
+		}
+
+		if (prot & PROT_WRITE && excess1 > 0) {
+			kdebug("clear[%d] ad=%lx sz=%lx",
+			       loop, maddr + phdr->p_filesz, excess1);
+			clear_user((void *) maddr + phdr->p_filesz, excess1);
+		}
+
+#else
+		if (excess > 0) {
+			kdebug("clear[%d] ad=%lx sz=%lx",
+			       loop, maddr + phdr->p_filesz, excess);
+			clear_user((void *) maddr + phdr->p_filesz, excess);
+		}
+#endif
+
+		if (mm) {
+			if (phdr->p_flags & PF_X) {
+				mm->start_code = maddr;
+				mm->end_code = maddr + phdr->p_memsz;
+			}
+			else if (!mm->start_data) {
+				mm->start_data = maddr;
+				mm->end_data = maddr + phdr->p_memsz;
+			}
+		}
+
+		seg++;
+	}
+
+	return 0;
+} /* end elf_fdpic_map_file_by_direct_mmap() */
diff -Nru a/fs/binfmt_em86.c b/fs/binfmt_em86.c
--- a/fs/binfmt_em86.c	2005-03-01 23:39:07 -08:00
+++ b/fs/binfmt_em86.c	2005-03-01 23:39:07 -08:00
@@ -95,7 +95,7 @@
 	return search_binary_handler(bprm, regs);
 }
 
-struct linux_binfmt em86_format = {
+static struct linux_binfmt em86_format = {
 	.module		= THIS_MODULE,
 	.load_binary	= load_em86,
 };
diff -Nru a/fs/binfmt_misc.c b/fs/binfmt_misc.c
--- a/fs/binfmt_misc.c	2005-03-01 23:38:55 -08:00
+++ b/fs/binfmt_misc.c	2005-03-01 23:38:55 -08:00
@@ -54,7 +54,7 @@
 	struct dentry *dentry;
 } Node;
 
-static rwlock_t entries_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(entries_lock);
 static struct vfsmount *bm_mnt;
 static int entry_count;
 
@@ -509,7 +509,8 @@
 		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_atime = inode->i_mtime = inode->i_ctime =
+			current_fs_time(inode->i_sb);
 	}
 	return inode;
 }
diff -Nru a/fs/binfmt_script.c b/fs/binfmt_script.c
--- a/fs/binfmt_script.c	2005-03-01 23:38:52 -08:00
+++ b/fs/binfmt_script.c	2005-03-01 23:38:52 -08:00
@@ -96,7 +96,7 @@
 	return search_binary_handler(bprm,regs);
 }
 
-struct linux_binfmt script_format = {
+static struct linux_binfmt script_format = {
 	.module		= THIS_MODULE,
 	.load_binary	= load_script,
 };
diff -Nru a/fs/binfmt_som.c b/fs/binfmt_som.c
--- a/fs/binfmt_som.c	2005-03-01 23:38:55 -08:00
+++ b/fs/binfmt_som.c	2005-03-01 23:38:55 -08:00
@@ -254,7 +254,7 @@
 
 	set_binfmt(&som_format);
 	compute_creds(bprm);
-	setup_arg_pages(bprm, EXSTACK_DEFAULT);
+	setup_arg_pages(bprm, STACK_TOP, EXSTACK_DEFAULT);
 
 	create_som_tables(bprm);
 
diff -Nru a/fs/bio.c b/fs/bio.c
--- a/fs/bio.c	2005-03-01 23:38:58 -08:00
+++ b/fs/bio.c	2005-03-01 23:38:58 -08:00
@@ -91,19 +91,14 @@
 /*
  * default destructor for a bio allocated with bio_alloc()
  */
-void bio_destructor(struct bio *bio)
+static void bio_destructor(struct bio *bio)
 {
 	const int pool_idx = BIO_POOL_IDX(bio);
 	struct biovec_pool *bp = bvec_array + pool_idx;
 
 	BIO_BUG_ON(pool_idx >= BIOVEC_NR_POOLS);
 
-	/*
-	 * cloned bio doesn't own the veclist
-	 */
-	if (!bio_flagged(bio, BIO_CLONED))
-		mempool_free(bio->bi_io_vec, bp->pool);
-
+	mempool_free(bio->bi_io_vec, bp->pool);
 	mempool_free(bio, bio_pool);
 }
 
@@ -210,7 +205,9 @@
  */
 inline void __bio_clone(struct bio *bio, struct bio *bio_src)
 {
-	bio->bi_io_vec = bio_src->bi_io_vec;
+	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));
 
 	bio->bi_sector = bio_src->bi_sector;
 	bio->bi_bdev = bio_src->bi_bdev;
@@ -222,21 +219,9 @@
 	 * for the clone
 	 */
 	bio->bi_vcnt = bio_src->bi_vcnt;
-	bio->bi_idx = bio_src->bi_idx;
-	if (bio_flagged(bio, BIO_SEG_VALID)) {
-		bio->bi_phys_segments = bio_src->bi_phys_segments;
-		bio->bi_hw_segments = bio_src->bi_hw_segments;
-		bio->bi_flags |= (1 << BIO_SEG_VALID);
-	}
 	bio->bi_size = bio_src->bi_size;
-
-	/*
-	 * cloned bio does not own the bio_vec, so users cannot fiddle with
-	 * it. clear bi_max_vecs and clear the BIO_POOL_BITS to make this
-	 * apparent
-	 */
-	bio->bi_max_vecs = 0;
-	bio->bi_flags &= (BIO_POOL_MASK - 1);
+	bio_phys_segments(q, bio);
+	bio_hw_segments(q, bio);
 }
 
 /**
@@ -248,7 +233,7 @@
  */
 struct bio *bio_clone(struct bio *bio, int gfp_mask)
 {
-	struct bio *b = bio_alloc(gfp_mask, 0);
+	struct bio *b = bio_alloc(gfp_mask, bio->bi_max_vecs);
 
 	if (b)
 		__bio_clone(b, bio);
@@ -743,7 +728,7 @@
 static void bio_dirty_fn(void *data);
 
 static DECLARE_WORK(bio_dirty_work, bio_dirty_fn, NULL);
-static spinlock_t bio_dirty_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(bio_dirty_lock);
 static struct bio *bio_dirty_list;
 
 /*
diff -Nru a/fs/block_dev.c b/fs/block_dev.c
--- a/fs/block_dev.c	2005-03-01 23:39:18 -08:00
+++ b/fs/block_dev.c	2005-03-01 23:39:18 -08:00
@@ -237,7 +237,7 @@
  * pseudo-fs
  */
 
-static spinlock_t bdev_lock __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
+static  __cacheline_aligned_in_smp DEFINE_SPINLOCK(bdev_lock);
 static kmem_cache_t * bdev_cachep;
 
 static struct inode *bdev_alloc_inode(struct super_block *sb)
@@ -804,6 +804,9 @@
 	.mmap		= generic_file_mmap,
 	.fsync		= block_fsync,
 	.ioctl		= block_ioctl,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl	= compat_blkdev_ioctl,
+#endif
 	.readv		= generic_file_readv,
 	.writev		= generic_file_write_nolock,
 	.sendfile	= generic_file_sendfile,
diff -Nru a/fs/buffer.c b/fs/buffer.c
--- a/fs/buffer.c	2005-03-01 23:38:58 -08:00
+++ b/fs/buffer.c	2005-03-01 23:38:58 -08:00
@@ -311,10 +311,10 @@
 {
 	struct inode * inode = dentry->d_inode;
 	struct super_block * sb;
-	int ret;
+	int ret, err;
 
 	/* sync the inode to buffers */
-	write_inode_now(inode, 0);
+	ret = write_inode_now(inode, 0);
 
 	/* sync the superblock to buffers */
 	sb = inode->i_sb;
@@ -324,7 +324,9 @@
 	unlock_super(sb);
 
 	/* .. finally sync the buffers to disk */
-	ret = sync_blockdev(sb->s_bdev);
+	err = sync_blockdev(sb->s_bdev);
+	if (!ret)
+		ret = err;
 	return ret;
 }
 
@@ -347,18 +349,22 @@
 		goto out_putf;
 	}
 
-	/* We need to protect against concurrent writers.. */
-	down(&mapping->host->i_sem);
 	current->flags |= PF_SYNCWRITE;
 	ret = filemap_fdatawrite(mapping);
+
+	/*
+	 * We need to protect against concurrent writers,
+	 * which could cause livelocks in fsync_buffers_list
+	 */
+	down(&mapping->host->i_sem);
 	err = file->f_op->fsync(file, file->f_dentry, 0);
 	if (!ret)
 		ret = err;
+	up(&mapping->host->i_sem);
 	err = filemap_fdatawait(mapping);
 	if (!ret)
 		ret = err;
 	current->flags &= ~PF_SYNCWRITE;
-	up(&mapping->host->i_sem);
 
 out_putf:
 	fput(file);
@@ -383,17 +389,17 @@
 
 	mapping = file->f_mapping;
 
-	down(&mapping->host->i_sem);
 	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;
-	up(&mapping->host->i_sem);
 
 out_putf:
 	fput(file);
@@ -422,6 +428,7 @@
 	struct buffer_head *bh;
 	struct buffer_head *head;
 	struct page *page;
+	int all_mapped = 1;
 
 	index = block >> (PAGE_CACHE_SHIFT - bd_inode->i_blkbits);
 	page = find_get_page(bd_mapping, index);
@@ -439,14 +446,23 @@
 			get_bh(bh);
 			goto out_unlock;
 		}
+		if (!buffer_mapped(bh))
+			all_mapped = 0;
 		bh = bh->b_this_page;
 	} while (bh != head);
 
-	printk("__find_get_block_slow() failed. "
-		"block=%llu, b_blocknr=%llu\n",
-		(unsigned long long)block, (unsigned long long)bh->b_blocknr);
-	printk("b_state=0x%08lx, b_size=%u\n", bh->b_state, bh->b_size);
-	printk("device blocksize: %d\n", 1 << bd_inode->i_blkbits);
+	/* we might be here because some of the buffers on this page are
+	 * not mapped.  This is due to various races between
+	 * file io on the block device and getblk.  It gets dealt with
+	 * elsewhere, don't buffer_error if we had some unmapped buffers
+	 */
+	if (all_mapped) {
+		printk("__find_get_block_slow() failed. "
+			"block=%llu, b_blocknr=%llu\n",
+			(unsigned long long)block, (unsigned long long)bh->b_blocknr);
+		printk("b_state=0x%08lx, b_size=%u\n", bh->b_state, bh->b_size);
+		printk("device blocksize: %d\n", 1 << bd_inode->i_blkbits);
+	}
 out_unlock:
 	spin_unlock(&bd_mapping->private_lock);
 	page_cache_release(page);
@@ -521,7 +537,7 @@
  */
 static void end_buffer_async_read(struct buffer_head *bh, int uptodate)
 {
-	static spinlock_t page_uptodate_lock = SPIN_LOCK_UNLOCKED;
+	static DEFINE_SPINLOCK(page_uptodate_lock);
 	unsigned long flags;
 	struct buffer_head *tmp;
 	struct page *page;
@@ -534,7 +550,8 @@
 		set_buffer_uptodate(bh);
 	} else {
 		clear_buffer_uptodate(bh);
-		buffer_io_error(bh);
+		if (printk_ratelimit())
+			buffer_io_error(bh);
 		SetPageError(page);
 	}
 
@@ -579,7 +596,7 @@
 void end_buffer_async_write(struct buffer_head *bh, int uptodate)
 {
 	char b[BDEVNAME_SIZE];
-	static spinlock_t page_uptodate_lock = SPIN_LOCK_UNLOCKED;
+	static DEFINE_SPINLOCK(page_uptodate_lock);
 	unsigned long flags;
 	struct buffer_head *tmp;
 	struct page *page;
@@ -1089,18 +1106,16 @@
 {
 	struct buffer_head *head = page_buffers(page);
 	struct buffer_head *bh = head;
-	unsigned int b_state;
-
-	b_state = 1 << BH_Mapped;
-	if (PageUptodate(page))
-		b_state |= 1 << BH_Uptodate;
+	int uptodate = PageUptodate(page);
 
 	do {
-		if (!(bh->b_state & (1 << BH_Mapped))) {
+		if (!buffer_mapped(bh)) {
 			init_buffer(bh, NULL, NULL);
 			bh->b_bdev = bdev;
 			bh->b_blocknr = block;
-			bh->b_state = b_state;
+			if (uptodate)
+				set_buffer_uptodate(bh);
+			set_buffer_mapped(bh);
 		}
 		block++;
 		bh = bh->b_this_page;
@@ -1129,8 +1144,10 @@
 
 	if (page_has_buffers(page)) {
 		bh = page_buffers(page);
-		if (bh->b_size == size)
+		if (bh->b_size == size) {
+			init_page_buffers(page, bdev, block, size);
 			return page;
+		}
 		if (!try_to_free_buffers(page))
 			goto failed;
 	}
diff -Nru a/fs/char_dev.c b/fs/char_dev.c
--- a/fs/char_dev.c	2005-03-01 23:38:55 -08:00
+++ b/fs/char_dev.c	2005-03-01 23:38:55 -08:00
@@ -28,7 +28,7 @@
 
 #define MAX_PROBE_HASH 255	/* random */
 
-static rwlock_t chrdevs_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(chrdevs_lock);
 
 static struct char_device_struct {
 	struct char_device_struct *next;
@@ -248,7 +248,7 @@
 	return 0;
 }
 
-static spinlock_t cdev_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(cdev_lock);
 
 static struct kobject *cdev_get(struct cdev *p)
 {
diff -Nru a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
--- a/fs/cifs/cifsfs.c	2005-03-01 23:38:58 -08:00
+++ b/fs/cifs/cifsfs.c	2005-03-01 23:38:58 -08:00
@@ -853,8 +853,8 @@
 	GlobalCurrentXid = 0;
 	GlobalTotalActiveXid = 0;
 	GlobalMaxActiveXid = 0;
-	GlobalSMBSeslock = RW_LOCK_UNLOCKED;
-	GlobalMid_Lock = SPIN_LOCK_UNLOCKED;
+	rwlock_init(&GlobalSMBSeslock);
+	spin_lock_init(&GlobalMid_Lock);
 
 	if(cifs_max_pending < 2) {
 		cifs_max_pending = 2;
diff -Nru a/fs/cifs/connect.c b/fs/cifs/connect.c
--- a/fs/cifs/connect.c	2005-03-01 23:39:16 -08:00
+++ b/fs/cifs/connect.c	2005-03-01 23:39:16 -08:00
@@ -23,7 +23,6 @@
 #include <linux/string.h>
 #include <linux/list.h>
 #include <linux/wait.h>
-#include <linux/version.h>
 #include <linux/ipv6.h>
 #include <linux/pagemap.h>
 #include <linux/ctype.h>
@@ -1489,6 +1488,8 @@
 			sb->s_maxbytes = (u64) 1 << 31;	/* 2 GB */
 	}
 
+	sb->s_time_gran = 100;
+
 /* on error free sesinfo and tcon struct if needed */
 	if (rc) {
 		/* if session setup failed, use count is zero but
@@ -1645,7 +1646,7 @@
 				  32, nls_codepage);
 		bcc_ptr += 2 * bytes_returned;
 		bytes_returned =
-		    cifs_strtoUCS((wchar_t *) bcc_ptr, UTS_RELEASE, 32,
+		    cifs_strtoUCS((wchar_t *) bcc_ptr, system_utsname.release, 32,
 				  nls_codepage);
 		bcc_ptr += 2 * bytes_returned;
 		bcc_ptr += 2;
@@ -1672,8 +1673,8 @@
 		}
 		strcpy(bcc_ptr, "Linux version ");
 		bcc_ptr += strlen("Linux version ");
-		strcpy(bcc_ptr, UTS_RELEASE);
-		bcc_ptr += strlen(UTS_RELEASE) + 1;
+		strcpy(bcc_ptr, system_utsname.release);
+		bcc_ptr += strlen(system_utsname.release) + 1;
 		strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
 		bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
 	}
@@ -1889,7 +1890,7 @@
 				  32, nls_codepage);
 		bcc_ptr += 2 * bytes_returned;
 		bytes_returned =
-		    cifs_strtoUCS((wchar_t *) bcc_ptr, UTS_RELEASE, 32,
+		    cifs_strtoUCS((wchar_t *) bcc_ptr, system_utsname.release, 32,
 				  nls_codepage);
 		bcc_ptr += 2 * bytes_returned;
 		bcc_ptr += 2;
@@ -1914,8 +1915,8 @@
 		}
 		strcpy(bcc_ptr, "Linux version ");
 		bcc_ptr += strlen("Linux version ");
-		strcpy(bcc_ptr, UTS_RELEASE);
-		bcc_ptr += strlen(UTS_RELEASE) + 1;
+		strcpy(bcc_ptr, system_utsname.release);
+		bcc_ptr += strlen(system_utsname.release) + 1;
 		strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
 		bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
 	}
@@ -2178,7 +2179,7 @@
 				  32, nls_codepage);
 		bcc_ptr += 2 * bytes_returned;
 		bytes_returned =
-		    cifs_strtoUCS((wchar_t *) bcc_ptr, UTS_RELEASE, 32,
+		    cifs_strtoUCS((wchar_t *) bcc_ptr, system_utsname.release, 32,
 				  nls_codepage);
 		bcc_ptr += 2 * bytes_returned;
 		bcc_ptr += 2;	/* null terminate Linux version */
@@ -2195,8 +2196,8 @@
 	} else {		/* ASCII */
 		strcpy(bcc_ptr, "Linux version ");
 		bcc_ptr += strlen("Linux version ");
-		strcpy(bcc_ptr, UTS_RELEASE);
-		bcc_ptr += strlen(UTS_RELEASE) + 1;
+		strcpy(bcc_ptr, system_utsname.release);
+		bcc_ptr += strlen(system_utsname.release) + 1;
 		strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
 		bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
 		bcc_ptr++;	/* empty domain field */
@@ -2563,7 +2564,7 @@
 				  32, nls_codepage);
 		bcc_ptr += 2 * bytes_returned;
 		bytes_returned =
-		    cifs_strtoUCS((wchar_t *) bcc_ptr, UTS_RELEASE, 32,
+		    cifs_strtoUCS((wchar_t *) bcc_ptr, system_utsname.release, 32,
 				  nls_codepage);
 		bcc_ptr += 2 * bytes_returned;
 		bcc_ptr += 2;	/* null term version string */
@@ -2615,8 +2616,8 @@
 
 		strcpy(bcc_ptr, "Linux version ");
 		bcc_ptr += strlen("Linux version ");
-		strcpy(bcc_ptr, UTS_RELEASE);
-		bcc_ptr += strlen(UTS_RELEASE) + 1;
+		strcpy(bcc_ptr, system_utsname.release);
+		bcc_ptr += strlen(system_utsname.release) + 1;
 		strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
 		bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
 		bcc_ptr++;	/* null domain */
diff -Nru a/fs/cifs/file.c b/fs/cifs/file.c
--- a/fs/cifs/file.c	2005-03-01 23:38:44 -08:00
+++ b/fs/cifs/file.c	2005-03-01 23:38:44 -08:00
@@ -709,8 +709,9 @@
 	/* since the write may have blocked check these pointers again */
 	if(file->f_dentry) {
 		if(file->f_dentry->d_inode) {
-			file->f_dentry->d_inode->i_ctime = file->f_dentry->d_inode->i_mtime =
-				CURRENT_TIME;
+			struct inode *inode = file->f_dentry->d_inode;
+			inode->i_ctime = inode->i_mtime =
+				current_fs_time(inode->i_sb);
 			if (total_written > 0) {
 				if (*poffset > file->f_dentry->d_inode->i_size)
 					i_size_write(file->f_dentry->d_inode, *poffset);
@@ -903,7 +904,7 @@
 					to-from, &offset);
 			read_lock(&GlobalSMBSeslock);
 		/* Does mm or vfs already set times? */
-			inode->i_atime = inode->i_mtime = CURRENT_TIME;
+			inode->i_atime = inode->i_mtime = current_fs_time(inode->i_sb);
 			if ((bytes_written > 0) && (offset)) {
 				rc = 0;
 			} else if(bytes_written < 0) {
@@ -1493,7 +1494,8 @@
 		cFYI(1,("Bytes read %d ",rc));
 	}
                                                                                                                            
-	file->f_dentry->d_inode->i_atime = CURRENT_TIME;
+	file->f_dentry->d_inode->i_atime =
+		current_fs_time(file->f_dentry->d_inode->i_sb);
                                                                                                                            
 	if(PAGE_CACHE_SIZE > rc) {
 		memset(read_data+rc, 0, PAGE_CACHE_SIZE - rc);
diff -Nru a/fs/cifs/inode.c b/fs/cifs/inode.c
--- a/fs/cifs/inode.c	2005-03-01 23:38:44 -08:00
+++ b/fs/cifs/inode.c	2005-03-01 23:38:44 -08:00
@@ -451,7 +451,7 @@
 	cifsInode = CIFS_I(direntry->d_inode);
 	cifsInode->time = 0;	/* will force revalidate to get info when needed */
 	direntry->d_inode->i_ctime = inode->i_ctime = inode->i_mtime =
-	    CURRENT_TIME;
+	    current_fs_time(inode->i_sb);
 	cifsInode = CIFS_I(inode);
 	cifsInode->time = 0;	/* force revalidate of dir as well */
 
@@ -564,7 +564,7 @@
 	cifsInode = CIFS_I(direntry->d_inode);
 	cifsInode->time = 0;	/* force revalidate to go get info when needed */
 	direntry->d_inode->i_ctime = inode->i_ctime = inode->i_mtime =
-	    CURRENT_TIME;
+	    current_fs_time(inode->i_sb);
 
 	if (full_path)
 		kfree(full_path);
diff -Nru a/fs/cifs/misc.c b/fs/cifs/misc.c
--- a/fs/cifs/misc.c	2005-03-01 23:39:16 -08:00
+++ b/fs/cifs/misc.c	2005-03-01 23:39:16 -08:00
@@ -125,7 +125,7 @@
 		INIT_LIST_HEAD(&ret_buf->openFileList);
 		init_MUTEX(&ret_buf->tconSem);
 #ifdef CONFIG_CIFS_STATS
-		ret_buf->stat_lock = SPIN_LOCK_UNLOCKED;
+		spin_lock_init(&ret_buf->stat_lock);
 #endif
 		write_unlock(&GlobalSMBSeslock);
 	}
diff -Nru a/fs/coda/cnode.c b/fs/coda/cnode.c
--- a/fs/coda/cnode.c	2005-03-01 23:39:08 -08:00
+++ b/fs/coda/cnode.c	2005-03-01 23:39:08 -08:00
@@ -11,7 +11,7 @@
 #include <linux/coda_fs_i.h>
 #include <linux/coda_psdev.h>
 
-inline int coda_fideq(struct CodaFid *fid1, struct CodaFid *fid2)
+static inline int coda_fideq(struct CodaFid *fid1, struct CodaFid *fid2)
 {
 	return memcmp(fid1, fid2, sizeof(*fid1)) == 0;
 }
diff -Nru a/fs/coda/dir.c b/fs/coda/dir.c
--- a/fs/coda/dir.c	2005-03-01 23:38:52 -08:00
+++ b/fs/coda/dir.c	2005-03-01 23:38:52 -08:00
@@ -29,7 +29,6 @@
 
 /* dir inode-ops */
 static int coda_create(struct inode *dir, struct dentry *new, int mode, struct nameidata *nd);
-static int coda_mknod(struct inode *dir, struct dentry *new, int mode, dev_t rdev);
 static struct dentry *coda_lookup(struct inode *dir, struct dentry *target, struct nameidata *nd);
 static int coda_link(struct dentry *old_dentry, struct inode *dir_inode, 
 		     struct dentry *entry);
@@ -53,9 +52,14 @@
 			      void *dirent, struct dentry *dir);
 int coda_fsync(struct file *, struct dentry *dentry, int datasync);
 
-int coda_hasmknod;
+/* same as fs/bad_inode.c */
+static int coda_return_EIO(void)
+{
+	return -EIO;
+}
+#define CODA_EIO_ERROR ((void *) (coda_return_EIO))
 
-struct dentry_operations coda_dentry_operations =
+static struct dentry_operations coda_dentry_operations =
 {
 	.d_revalidate	= coda_dentry_revalidate,
 	.d_delete	= coda_dentry_delete,
@@ -70,7 +74,7 @@
 	.symlink	= coda_symlink,
 	.mkdir		= coda_mkdir,
 	.rmdir		= coda_rmdir,
-	.mknod		= coda_mknod,
+	.mknod		= CODA_EIO_ERROR,
 	.rename		= coda_rename,
 	.permission	= coda_permission,
 	.getattr	= coda_getattr,
@@ -183,7 +187,7 @@
 	/* optimistically we can also act as if our nose bleeds. The
          * granularity of the mtime is coarse anyways so we might actually be
          * right most of the time. Note: we only do this for directories. */
-	dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+	dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
 #endif
 	if (link)
 		dir->i_nlink += link;
@@ -208,7 +212,7 @@
 	}
 
 	error = venus_create(dir->i_sb, coda_i2f(dir), name, length, 
-				0, mode, 0, &newfid, &attrs);
+				0, mode, &newfid, &attrs);
 
         if ( error ) {
 		unlock_kernel();
@@ -229,52 +233,6 @@
 	d_instantiate(de, inode);
         return 0;
 }
-
-static int coda_mknod(struct inode *dir, struct dentry *de, int mode, dev_t rdev)
-{
-        int error=0;
-	const char *name=de->d_name.name;
-	int length=de->d_name.len;
-	struct inode *inode;
-	struct CodaFid newfid;
-	struct coda_vattr attrs;
-
-	if ( coda_hasmknod == 0 )
-		return -EIO;
-
-	if (!old_valid_dev(rdev))
-		return -EINVAL;
-
-	lock_kernel();
-	coda_vfs_stat.create++;
-
-	if (coda_isroot(dir) && coda_iscontrol(name, length)) {
-		unlock_kernel();
-		return -EPERM;
-	}
-
-	error = venus_create(dir->i_sb, coda_i2f(dir), name, length, 
-				0, mode, rdev, &newfid, &attrs);
-
-        if ( error ) {
-		unlock_kernel();
-		d_drop(de);
-		return error;
-	}
-
-	inode = coda_iget(dir->i_sb, &newfid, &attrs);
-	if ( IS_ERR(inode) ) {
-		unlock_kernel();
-		d_drop(de);
-		return PTR_ERR(inode);
-	}
-
-	/* invalidate the directory cnode's attributes */
-	coda_dir_changed(dir, 0);
-	unlock_kernel();
-	d_instantiate(de, inode);
-        return 0;
-}			     
 
 static int coda_mkdir(struct inode *dir, struct dentry *de, int mode)
 {
diff -Nru a/fs/coda/file.c b/fs/coda/file.c
--- a/fs/coda/file.c	2005-03-01 23:38:56 -08:00
+++ b/fs/coda/file.c	2005-03-01 23:38:56 -08:00
@@ -26,7 +26,7 @@
 
 /* if CODA_STORE fails with EOPNOTSUPP, venus clearly doesn't support
  * CODA_STORE/CODA_RELEASE and we fall back on using the CODA_CLOSE upcall */
-int use_coda_close;
+static int use_coda_close;
 
 static ssize_t
 coda_file_read(struct file *coda_file, char __user *buf, size_t count, loff_t *ppos)
@@ -83,7 +83,7 @@
 
 	coda_inode->i_size = host_inode->i_size;
 	coda_inode->i_blocks = (coda_inode->i_size + 511) >> 9;
-	coda_inode->i_mtime = coda_inode->i_ctime = CURRENT_TIME;
+	coda_inode->i_mtime = coda_inode->i_ctime = CURRENT_TIME_SEC;
 	up(&coda_inode->i_sem);
 
 	return ret;
diff -Nru a/fs/coda/inode.c b/fs/coda/inode.c
--- a/fs/coda/inode.c	2005-03-01 23:38:57 -08:00
+++ b/fs/coda/inode.c	2005-03-01 23:38:57 -08:00
@@ -89,7 +89,7 @@
 }
 
 /* exported operations */
-struct super_operations coda_super_operations =
+static struct super_operations coda_super_operations =
 {
 	.alloc_inode	= coda_alloc_inode,
 	.destroy_inode	= coda_destroy_inode,
@@ -253,7 +253,7 @@
 	
 	memset(&vattr, 0, sizeof(vattr)); 
 
-	inode->i_ctime = CURRENT_TIME;
+	inode->i_ctime = CURRENT_TIME_SEC;
 	coda_iattr_to_vattr(iattr, &vattr);
 	vattr.va_type = C_VNON; /* cannot set type */
 
diff -Nru a/fs/coda/psdev.c b/fs/coda/psdev.c
--- a/fs/coda/psdev.c	2005-03-01 23:39:07 -08:00
+++ b/fs/coda/psdev.c	2005-03-01 23:39:07 -08:00
@@ -22,7 +22,6 @@
 #include <linux/kernel.h>
 #include <linux/major.h>
 #include <linux/time.h>
-#include <linux/lp.h>
 #include <linux/slab.h>
 #include <linux/ioport.h>
 #include <linux/fcntl.h>
@@ -310,8 +309,7 @@
 static int coda_psdev_release(struct inode * inode, struct file * file)
 {
         struct venus_comm *vcp = (struct venus_comm *) file->private_data;
-        struct upc_req *req;
-	struct list_head *lh, *next;
+        struct upc_req *req, *tmp;
 
 	lock_kernel();
 	if ( !vcp->vc_inuse ) {
@@ -326,8 +324,7 @@
 	}
         
         /* Wakeup clients so they can return. */
-	list_for_each_safe(lh, next, &vcp->vc_pending) {
-		req = list_entry(lh, struct upc_req, uc_chain);
+	list_for_each_entry_safe(req, tmp, &vcp->vc_pending, uc_chain) {
 		/* Async requests need to be freed here */
 		if (req->uc_flags & REQ_ASYNC) {
 			CODA_FREE(req->uc_data, sizeof(struct coda_in_hdr));
@@ -361,13 +358,12 @@
 static int init_coda_psdev(void)
 {
 	int i, err = 0;
-	if (register_chrdev(CODA_PSDEV_MAJOR,"coda_psdev",
-				 &coda_psdev_fops)) {
+	if (register_chrdev(CODA_PSDEV_MAJOR, "coda", &coda_psdev_fops)) {
               printk(KERN_ERR "coda_psdev: unable to get major %d\n", 
 		     CODA_PSDEV_MAJOR);
               return -EIO;
 	}
-	coda_psdev_class = class_simple_create(THIS_MODULE, "coda_psdev");
+	coda_psdev_class = class_simple_create(THIS_MODULE, "coda");
 	if (IS_ERR(coda_psdev_class)) {
 		err = PTR_ERR(coda_psdev_class);
 		goto out_chrdev;
@@ -389,7 +385,7 @@
 		class_simple_device_remove(MKDEV(CODA_PSDEV_MAJOR, i));
 	class_simple_destroy(coda_psdev_class);
 out_chrdev:
-	unregister_chrdev(CODA_PSDEV_MAJOR, "coda_psdev");
+	unregister_chrdev(CODA_PSDEV_MAJOR, "coda");
 out:
 	return err;
 }
@@ -434,7 +430,7 @@
 	}
 	class_simple_destroy(coda_psdev_class);
 	devfs_remove("coda");
-	unregister_chrdev(CODA_PSDEV_MAJOR,"coda_psdev");
+	unregister_chrdev(CODA_PSDEV_MAJOR, "coda");
 	coda_sysctl_clean();
 out1:
 	coda_destroy_inodecache();
@@ -456,7 +452,7 @@
 	}
 	class_simple_destroy(coda_psdev_class);
 	devfs_remove("coda");
-	unregister_chrdev(CODA_PSDEV_MAJOR, "coda_psdev");
+	unregister_chrdev(CODA_PSDEV_MAJOR, "coda");
 	coda_sysctl_clean();
 	coda_destroy_inodecache();
 }
diff -Nru a/fs/coda/sysctl.c b/fs/coda/sysctl.c
--- a/fs/coda/sysctl.c	2005-03-01 23:38:55 -08:00
+++ b/fs/coda/sysctl.c	2005-03-01 23:38:55 -08:00
@@ -41,35 +41,22 @@
 #define CODA_CACHE_INV 	 9       /* cache invalidation statistics */
 #define CODA_FAKE_STATFS 10	 /* don't query venus for actual cache usage */
 
-static ctl_table coda_table[] = {
- 	{CODA_TIMEOUT, "timeout", &coda_timeout, sizeof(int), 0644, NULL, &proc_dointvec},
- 	{CODA_HARD, "hard", &coda_hard, sizeof(int), 0644, NULL, &proc_dointvec},
- 	{CODA_VFS, "vfs_stats", NULL, 0, 0644, NULL, &do_reset_coda_vfs_stats},
- 	{CODA_CACHE_INV, "cache_inv_stats", NULL, 0, 0644, NULL, &do_reset_coda_cache_inv_stats},
- 	{CODA_FAKE_STATFS, "fake_statfs", &coda_fake_statfs, sizeof(int), 0600, NULL, &proc_dointvec},
-	{ 0 }
-};
-
-static ctl_table fs_table[] = {
-       {FS_CODA, "coda",    NULL, 0, 0555, coda_table},
-       {0}
-};
-
 struct coda_vfs_stats		coda_vfs_stat;
-struct coda_cache_inv_stats	coda_cache_inv_stat;
+static struct coda_cache_inv_stats	coda_cache_inv_stat;
 
-void reset_coda_vfs_stats( void )
+static void reset_coda_vfs_stats( void )
 {
 	memset( &coda_vfs_stat, 0, sizeof( coda_vfs_stat ) );
 }
 
-void reset_coda_cache_inv_stats( void )
+static void reset_coda_cache_inv_stats( void )
 {
 	memset( &coda_cache_inv_stat, 0, sizeof( coda_cache_inv_stat ) );
 }
 
-int do_reset_coda_vfs_stats( ctl_table * table, int write, struct file * filp,
-			     void __user * buffer, size_t * lenp, loff_t * ppos )
+static int do_reset_coda_vfs_stats( ctl_table * table, int write,
+				    struct file * filp, void __user * buffer,
+				    size_t * lenp, loff_t * ppos )
 {
 	if ( write ) {
 		reset_coda_vfs_stats();
@@ -82,9 +69,10 @@
 	return 0;
 }
 
-int do_reset_coda_cache_inv_stats( ctl_table * table, int write, 
-				   struct file * filp, void __user * buffer, 
-				   size_t * lenp, loff_t * ppos )
+static int do_reset_coda_cache_inv_stats( ctl_table * table, int write,
+					  struct file * filp,
+					  void __user * buffer,
+					  size_t * lenp, loff_t * ppos )
 {
 	if ( write ) {
 		reset_coda_cache_inv_stats();
@@ -97,8 +85,8 @@
 	return 0;
 }
 
-int coda_vfs_stats_get_info( char * buffer, char ** start, off_t offset,
-			     int length)
+static int coda_vfs_stats_get_info( char * buffer, char ** start,
+				    off_t offset, int length)
 {
 	int len=0;
 	off_t begin;
@@ -158,8 +146,8 @@
 	return len;
 }
 
-int coda_cache_inv_stats_get_info( char * buffer, char ** start, off_t offset,
-				   int length)
+static int coda_cache_inv_stats_get_info( char * buffer, char ** start,
+					  off_t offset, int length)
 {
 	int len=0;
 	off_t begin;
@@ -196,6 +184,20 @@
 	return len;
 }
 
+static ctl_table coda_table[] = {
+ 	{CODA_TIMEOUT, "timeout", &coda_timeout, sizeof(int), 0644, NULL, &proc_dointvec},
+ 	{CODA_HARD, "hard", &coda_hard, sizeof(int), 0644, NULL, &proc_dointvec},
+ 	{CODA_VFS, "vfs_stats", NULL, 0, 0644, NULL, &do_reset_coda_vfs_stats},
+ 	{CODA_CACHE_INV, "cache_inv_stats", NULL, 0, 0644, NULL, &do_reset_coda_cache_inv_stats},
+ 	{CODA_FAKE_STATFS, "fake_statfs", &coda_fake_statfs, sizeof(int), 0600, NULL, &proc_dointvec},
+	{ 0 }
+};
+
+static ctl_table fs_table[] = {
+       {FS_CODA, "coda",    NULL, 0, 0555, coda_table},
+       {0}
+};
+
 
 #ifdef CONFIG_PROC_FS
 
@@ -207,7 +209,7 @@
 
 */
 
-struct proc_dir_entry* proc_fs_coda;
+static struct proc_dir_entry* proc_fs_coda;
 
 #endif
 
diff -Nru a/fs/coda/upcall.c b/fs/coda/upcall.c
--- a/fs/coda/upcall.c	2005-03-01 23:39:09 -08:00
+++ b/fs/coda/upcall.c	2005-03-01 23:39:09 -08:00
@@ -331,7 +331,7 @@
 }
 
 int venus_create(struct super_block *sb, struct CodaFid *dirfid, 
-		 const char *name, int length, int excl, int mode, dev_t rdev,
+		 const char *name, int length, int excl, int mode,
 		 struct CodaFid *newfid, struct coda_vattr *attrs) 
 {
         union inputArgs *inp;
@@ -345,7 +345,6 @@
 
         inp->coda_create.VFid = *dirfid;
         inp->coda_create.attr.va_mode = mode;
-        inp->coda_create.attr.va_rdev = huge_encode_dev(rdev);
 	inp->coda_create.excl = excl;
         inp->coda_create.mode = mode;
         inp->coda_create.name = offset;
@@ -555,6 +554,11 @@
 		goto exit;
         }
 
+        if (data->vi.out_size > VC_MAXDATASIZE) {
+		error = -EINVAL;
+		goto exit;
+	}
+
         inp->coda_ioctl.VFid = *fid;
     
         /* the cmd field was mutated by increasing its size field to
@@ -583,18 +587,25 @@
 		       error, coda_f2s(fid));
 		goto exit; 
 	}
+
+	if (outsize < (long)outp->coda_ioctl.data + outp->coda_ioctl.len) {
+		error = -EINVAL;
+		goto exit;
+	}
         
 	/* Copy out the OUT buffer. */
         if (outp->coda_ioctl.len > data->vi.out_size) {
 		error = -EINVAL;
-        } else {
-		if (copy_to_user(data->vi.out, 
-				 (char *)outp + (long)outp->coda_ioctl.data, 
-				 data->vi.out_size)) {
-			error = -EFAULT;
-			goto exit;
-		}
+		goto exit;
         }
+
+	/* Copy out the OUT buffer. */
+	if (copy_to_user(data->vi.out,
+			 (char *)outp + (long)outp->coda_ioctl.data,
+			 outp->coda_ioctl.len)) {
+		error = -EFAULT;
+		goto exit;
+	}
 
  exit:
 	CODA_FREE(inp, insize);
diff -Nru a/fs/compat.c b/fs/compat.c
--- a/fs/compat.c	2005-03-01 23:38:56 -08:00
+++ b/fs/compat.c	2005-03-01 23:38:56 -08:00
@@ -25,6 +25,7 @@
 #include <linux/file.h>
 #include <linux/vfs.h>
 #include <linux/ioctl32.h>
+#include <linux/ioctl.h>
 #include <linux/init.h>
 #include <linux/sockios.h>	/* for SIOCDEVPRIVATE */
 #include <linux/smb.h>
@@ -47,6 +48,7 @@
 
 #include <asm/uaccess.h>
 #include <asm/mmu_context.h>
+#include <asm/ioctls.h>
 
 /*
  * Not all architectures have sys_utime, so implement this in terms
@@ -397,77 +399,121 @@
 }
 EXPORT_SYMBOL(unregister_ioctl32_conversion); 
 
+static void compat_ioctl_error(struct file *filp, unsigned int fd,
+		unsigned int cmd, unsigned long arg)
+{
+	char buf[10];
+	char *fn = "?";
+	char *path;
+
+	/* find the name of the device. */
+	path = (char *)__get_free_page(GFP_KERNEL);
+	if (path) {
+		fn = d_path(filp->f_dentry, filp->f_vfsmnt, path, PAGE_SIZE);
+		if (IS_ERR(fn))
+			fn = "?";
+	}
+
+	sprintf(buf,"'%c'", (cmd>>24) & 0x3f);
+	if (!isprint(buf[1]))
+		sprintf(buf, "%02x", buf[1]);
+	printk("ioctl32(%s:%d): Unknown cmd fd(%d) "
+			"cmd(%08x){%s} arg(%08x) on %s\n",
+			current->comm, current->pid,
+			(int)fd, (unsigned int)cmd, buf,
+			(unsigned int)arg, fn);
+
+	if (path)
+		free_page((unsigned long)path);
+}
+
 asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd,
 				unsigned long arg)
 {
-	struct file * filp;
+	struct file *filp;
 	int error = -EBADF;
 	struct ioctl_trans *t;
+	int fput_needed;
 
-	filp = fget(fd);
-	if(!filp)
-		goto out2;
-
-	if (!filp->f_op || !filp->f_op->ioctl) {
-		error = sys_ioctl (fd, cmd, arg);
+	filp = fget_light(fd, &fput_needed);
+	if (!filp)
 		goto out;
-	}
 
-	down_read(&ioctl32_sem);
+	/* RED-PEN how should LSM module know it's handling 32bit? */
+	error = security_file_ioctl(filp, cmd, arg);
+	if (error)
+		goto out_fput;
 
-	t = ioctl32_hash_table[ioctl32_hash (cmd)];
+	/*
+	 * To allow the compat_ioctl handlers to be self contained
+	 * we need to check the common ioctls here first.
+	 * Just handle them with the standard handlers below.
+	 */
+	switch (cmd) {
+	case FIOCLEX:
+	case FIONCLEX:
+	case FIONBIO:
+	case FIOASYNC:
+	case FIOQSIZE:
+		break;
 
-	while (t && t->cmd != cmd)
-		t = t->next;
-	if (t) {
-		if (t->handler) { 
-			lock_kernel();
-			error = t->handler(fd, cmd, arg, filp);
-			unlock_kernel();
-			up_read(&ioctl32_sem);
-		} else {
-			up_read(&ioctl32_sem);
-			error = sys_ioctl(fd, cmd, arg);
+	case FIBMAP:
+	case FIGETBSZ:
+	case FIONREAD:
+		if (S_ISREG(filp->f_dentry->d_inode->i_mode))
+			break;
+		/*FALL THROUGH*/
+
+	default:
+		if (filp->f_op && filp->f_op->compat_ioctl) {
+			error = filp->f_op->compat_ioctl(filp, cmd, arg);
+			if (error != -ENOIOCTLCMD)
+				goto out_fput;
 		}
+
+		if (!filp->f_op ||
+		    (!filp->f_op->ioctl && !filp->f_op->unlocked_ioctl))
+			goto do_ioctl;
+		break;
+	}
+
+	/* When register_ioctl32_conversion is finally gone remove
+	   this lock! -AK */
+	down_read(&ioctl32_sem);
+	for (t = ioctl32_hash_table[ioctl32_hash(cmd)]; t; t = t->next) {
+		if (t->cmd == cmd)
+			goto found_handler;
+	}
+	up_read(&ioctl32_sem);
+
+	if (S_ISSOCK(filp->f_dentry->d_inode->i_mode) &&
+	    cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) {
+		error = siocdevprivate_ioctl(fd, cmd, arg);
 	} else {
+		static int count;
+
+		if (++count <= 50)
+			compat_ioctl_error(filp, fd, cmd, arg);
+		error = -EINVAL;
+	}
+
+	goto out_fput;
+
+ found_handler:
+	if (t->handler) {
+		lock_kernel();
+		error = t->handler(fd, cmd, arg, filp);
+		unlock_kernel();
 		up_read(&ioctl32_sem);
-		if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) {
-			error = siocdevprivate_ioctl(fd, cmd, arg);
-		} else {
-			static int count;
-			if (++count <= 50) {
-				char buf[10];
-				char *fn = "?";
-				char *path;
-
-				path = (char *)__get_free_page(GFP_KERNEL);
-
-				/* find the name of the device. */
-				if (path) {
-			       		fn = d_path(filp->f_dentry,
-						filp->f_vfsmnt, path,
-						PAGE_SIZE);
-					if (IS_ERR(fn))
-						fn = "?";
-				}
-
-				sprintf(buf,"'%c'", (cmd>>24) & 0x3f);
-				if (!isprint(buf[1]))
-				    sprintf(buf, "%02x", buf[1]);
-				printk("ioctl32(%s:%d): Unknown cmd fd(%d) "
-					"cmd(%08x){%s} arg(%08x) on %s\n",
-					current->comm, current->pid,
-					(int)fd, (unsigned int)cmd, buf,
-					(unsigned int)arg, fn);
-				if (path)
-					free_page((unsigned long)path);
-			}
-			error = -EINVAL;
-		}
+		goto out_fput;
 	}
-out:
-	fput(filp);
-out2:
+
+	up_read(&ioctl32_sem);
+ do_ioctl:
+	error = vfs_ioctl(filp, fd, cmd, arg);
+ out_fput:
+	fput_light(filp, fput_needed);
+ out:
 	return error;
 }
 
@@ -1080,7 +1126,6 @@
 	int seg;
 	io_fn_t fn;
 	iov_fn_t fnv;
-	struct inode *inode;
 
 	/*
 	 * SuS says "The readv() function *may* fail if the iovcnt argument
@@ -1145,11 +1190,7 @@
 		goto out;
 	}
 
-	inode = file->f_dentry->d_inode;
-	/* VERIFY_WRITE actually means a read, as we write to user space */
-	ret = locks_verify_area((type == READ
-				 ? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE),
-				inode, file, *pos, tot_len);
+	ret = rw_verify_area(type, file, pos, tot_len);
 	if (ret)
 		goto out;
 
diff -Nru a/fs/compat_ioctl.c b/fs/compat_ioctl.c
--- a/fs/compat_ioctl.c	2005-03-01 23:39:19 -08:00
+++ b/fs/compat_ioctl.c	2005-03-01 23:39:19 -08:00
@@ -645,8 +645,11 @@
 	/* Don't check these user accesses, just let that get trapped
 	 * in the ioctl handler instead.
 	 */
-	copy_to_user(&u_ifreq64->ifr_ifrn.ifrn_name[0], &tmp_buf[0], IFNAMSIZ);
-	__put_user(data64, &u_ifreq64->ifr_ifru.ifru_data);
+	if (copy_to_user(&u_ifreq64->ifr_ifrn.ifrn_name[0], &tmp_buf[0],
+			 IFNAMSIZ))
+		return -EFAULT;
+	if (__put_user(data64, &u_ifreq64->ifr_ifru.ifru_data))
+		return -EFAULT;
 
 	return sys_ioctl(fd, cmd, (unsigned long) u_ifreq64);
 }
@@ -684,6 +687,11 @@
 	set_fs (old_fs);
 	if (!err) {
 		switch (cmd) {
+		/* TUNSETIFF is defined as _IOW, it should be _IORW
+		 * as the data is copied back to user space, but that
+		 * cannot be fixed without breaking all existing apps.
+		 */
+		case TUNSETIFF:
 		case SIOCGIFFLAGS:
 		case SIOCGIFMETRIC:
 		case SIOCGIFMTU:
@@ -2343,7 +2351,9 @@
         __put_user(d->d_ino, &d32->d_ino);
         __put_user(d->d_off, &d32->d_off);
         __put_user(d->d_reclen, &d32->d_reclen);
-        __copy_to_user(d32->d_name, d->d_name, d->d_reclen);
+        if (__copy_to_user(d32->d_name, d->d_name, d->d_reclen))
+		return -EFAULT;
+
         return ret;
 }
 
@@ -2486,7 +2496,8 @@
         if (cmd == TIOCSSERIAL) {
                 if (verify_area(VERIFY_READ, ss32, sizeof(SS32)))
                         return -EFAULT;
-                __copy_from_user(&ss, ss32, offsetof(SS32, iomem_base));
+                if (__copy_from_user(&ss, ss32, offsetof(SS32, iomem_base)))
+			return -EFAULT;
                 __get_user(udata, &ss32->iomem_base);
                 ss.iomem_base = compat_ptr(udata);
                 __get_user(ss.iomem_reg_shift, &ss32->iomem_reg_shift);
@@ -2499,7 +2510,8 @@
         if (cmd == TIOCGSERIAL && err >= 0) {
                 if (verify_area(VERIFY_WRITE, ss32, sizeof(SS32)))
                         return -EFAULT;
-                __copy_to_user(ss32,&ss,offsetof(SS32,iomem_base));
+                if (__copy_to_user(ss32,&ss,offsetof(SS32,iomem_base)))
+			return -EFAULT;
                 __put_user((unsigned long)ss.iomem_base  >> 32 ?
                             0xffffffff : (unsigned)(unsigned long)ss.iomem_base,
                             &ss32->iomem_base);
@@ -2841,48 +2853,42 @@
 	compat_caddr_t data; /* union i2c_smbus_data *data */
 };
 
+struct i2c_rdwr_aligned {
+	struct i2c_rdwr_ioctl_data cmd;
+	struct i2c_msg msgs[0];
+};
+
 static int do_i2c_rdwr_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
-	struct i2c_rdwr_ioctl_data	__user *tdata;
-	struct i2c_rdwr_ioctl_data32	__user *udata;
+	struct i2c_rdwr_ioctl_data32	__user *udata = compat_ptr(arg);
+	struct i2c_rdwr_aligned		__user *tdata;
 	struct i2c_msg			__user *tmsgs;
 	struct i2c_msg32		__user *umsgs;
 	compat_caddr_t			datap;
 	int				nmsgs, i;
 
-	tdata = compat_alloc_user_space(sizeof(*tdata));
-	if (tdata == NULL)
-		return -ENOMEM;
-	if (verify_area(VERIFY_WRITE, tdata, sizeof(*tdata)))
-		return -EFAULT;
-
-	udata = compat_ptr(arg);
-	if (verify_area(VERIFY_READ, udata, sizeof(*udata)))
-		return -EFAULT;
-	if (__get_user(nmsgs, &udata->nmsgs) || __put_user(nmsgs, &tdata->nmsgs))
+	if (get_user(nmsgs, &udata->nmsgs))
 		return -EFAULT;
 	if (nmsgs > I2C_RDRW_IOCTL_MAX_MSGS)
 		return -EINVAL;
-	if (__get_user(datap, &udata->msgs))
+
+	if (get_user(datap, &udata->msgs))
 		return -EFAULT;
 	umsgs = compat_ptr(datap);
-	if (verify_area(VERIFY_READ, umsgs, sizeof(struct i2c_msg) * nmsgs))
-		return -EFAULT;
 
-	tmsgs = compat_alloc_user_space(sizeof(struct i2c_msg) * nmsgs);
-	if (tmsgs == NULL)
-		return -ENOMEM;
-	if (verify_area(VERIFY_WRITE, tmsgs, sizeof(struct i2c_msg) * nmsgs))
+	tdata = compat_alloc_user_space(sizeof(*tdata) +
+				      nmsgs * sizeof(struct i2c_msg));
+	tmsgs = &tdata->msgs[0];
+
+	if (put_user(nmsgs, &tdata->cmd.nmsgs) ||
+	    put_user(tmsgs, &tdata->cmd.msgs))
 		return -EFAULT;
-	if (__put_user(tmsgs, &tdata->msgs))
-		return -ENOMEM;
+
 	for (i = 0; i < nmsgs; i++) {
-		if (__copy_in_user(&tmsgs[i].addr,
-				   &umsgs[i].addr,
-				   3 * sizeof(u16)))
+		if (copy_in_user(&tmsgs[i].addr, &umsgs[i].addr, 3*sizeof(u16)))
 			return -EFAULT;
-		if (__get_user(datap, &umsgs[i].buf) ||
-		    __put_user(compat_ptr(datap), &tmsgs[i].buf))
+		if (get_user(datap, &umsgs[i].buf) ||
+		    put_user(compat_ptr(datap), &tmsgs[i].buf))
 			return -EFAULT;
 	}
 	return sys_ioctl(fd, cmd, (unsigned long)tdata);
diff -Nru a/fs/dcache.c b/fs/dcache.c
--- a/fs/dcache.c	2005-03-01 23:38:52 -08:00
+++ b/fs/dcache.c	2005-03-01 23:38:52 -08:00
@@ -37,7 +37,7 @@
 
 int sysctl_vfs_cache_pressure = 100;
 
-spinlock_t dcache_lock __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
+ __cacheline_aligned_in_smp DEFINE_SPINLOCK(dcache_lock);
 seqlock_t rename_lock __cacheline_aligned_in_smp = SEQLOCK_UNLOCKED;
 
 EXPORT_SYMBOL(dcache_lock);
@@ -156,7 +156,7 @@
 		spin_unlock(&dcache_lock);
 		return;
 	}
-			
+
 	/*
 	 * AV: ->d_delete() is _NOT_ allowed to block now.
 	 */
@@ -392,6 +392,8 @@
 		struct dentry *dentry;
 		struct list_head *tmp;
 
+		cond_resched_lock(&dcache_lock);
+
 		tmp = dentry_unused.prev;
 		if (tmp == &dentry_unused)
 			break;
@@ -548,6 +550,13 @@
  * list for prune_dcache(). We descend to the next level
  * whenever the d_subdirs list is non-empty and continue
  * searching.
+ *
+ * It returns zero iff there are no unused children,
+ * otherwise  it returns the number of children moved to
+ * the end of the unused list. This may not be the total
+ * number of unused children, because select_parent can
+ * drop the lock and return early due to latency
+ * constraints.
  */
 static int select_parent(struct dentry * parent)
 {
@@ -577,6 +586,15 @@
 			dentry_stat.nr_unused++;
 			found++;
 		}
+
+		/*
+		 * We can return to the caller if we have found some (this
+		 * ensures forward progress). We'll be coming back to find
+		 * the rest.
+		 */
+		if (found && need_resched())
+			goto out;
+
 		/*
 		 * Descend a level if the d_subdirs list is non-empty.
 		 */
@@ -601,6 +619,7 @@
 #endif
 		goto resume;
 	}
+out:
 	spin_unlock(&dcache_lock);
 	return found;
 }
@@ -718,7 +737,7 @@
 
 	atomic_set(&dentry->d_count, 1);
 	dentry->d_flags = DCACHE_UNHASHED;
-	dentry->d_lock = SPIN_LOCK_UNLOCKED;
+	spin_lock_init(&dentry->d_lock);
 	dentry->d_inode = NULL;
 	dentry->d_parent = NULL;
 	dentry->d_sb = NULL;
@@ -784,6 +803,54 @@
 }
 
 /**
+ * d_instantiate_unique - instantiate a non-aliased dentry
+ * @entry: dentry to instantiate
+ * @inode: inode to attach to this dentry
+ *
+ * Fill in inode information in the entry. On success, it returns NULL.
+ * If an unhashed alias of "entry" already exists, then we return the
+ * aliased dentry instead.
+ *
+ * Note that in order to avoid conflicts with rename() etc, the caller
+ * had better be holding the parent directory semaphore.
+ */
+struct dentry *d_instantiate_unique(struct dentry *entry, struct inode *inode)
+{
+	struct dentry *alias;
+	int len = entry->d_name.len;
+	const char *name = entry->d_name.name;
+	unsigned int hash = entry->d_name.hash;
+
+	BUG_ON(!list_empty(&entry->d_alias));
+	spin_lock(&dcache_lock);
+	if (!inode)
+		goto do_negative;
+	list_for_each_entry(alias, &inode->i_dentry, d_alias) {
+		struct qstr *qstr = &alias->d_name;
+
+		if (qstr->hash != hash)
+			continue;
+		if (alias->d_parent != entry->d_parent)
+			continue;
+		if (qstr->len != len)
+			continue;
+		if (memcmp(qstr->name, name, len))
+			continue;
+		dget_locked(alias);
+		spin_unlock(&dcache_lock);
+		BUG_ON(!d_unhashed(alias));
+		return alias;
+	}
+	list_add(&entry->d_alias, &inode->i_dentry);
+do_negative:
+	entry->d_inode = inode;
+	spin_unlock(&dcache_lock);
+	security_d_instantiate(entry, inode);
+	return NULL;
+}
+EXPORT_SYMBOL(d_instantiate_unique);
+
+/**
  * d_alloc_root - allocate root dentry
  * @root_inode: inode to allocate the root for
  *
@@ -1574,14 +1641,21 @@
 {
 	int loop;
 
+	/* If hashes are distributed across NUMA nodes, defer
+	 * hash allocation until vmalloc space is available.
+	 */
+	if (hashdist)
+		return;
+
 	dentry_hashtable =
 		alloc_large_system_hash("Dentry cache",
 					sizeof(struct hlist_head),
 					dhash_entries,
 					13,
-					0,
+					HASH_EARLY,
 					&d_hash_shift,
-					&d_hash_mask);
+					&d_hash_mask,
+					0);
 
 	for (loop = 0; loop < (1 << d_hash_shift); loop++)
 		INIT_HLIST_HEAD(&dentry_hashtable[loop]);
@@ -1589,6 +1663,8 @@
 
 static void __init dcache_init(unsigned long mempages)
 {
+	int loop;
+
 	/* 
 	 * A constructor could be added for stable state like the lists,
 	 * but it is probably not worth it because of the cache nature
@@ -1601,6 +1677,23 @@
 					 NULL, NULL);
 	
 	set_shrinker(DEFAULT_SEEKS, shrink_dcache_memory);
+
+	/* Hash may have been set up in dcache_init_early */
+	if (!hashdist)
+		return;
+
+	dentry_hashtable =
+		alloc_large_system_hash("Dentry cache",
+					sizeof(struct hlist_head),
+					dhash_entries,
+					13,
+					0,
+					&d_hash_shift,
+					&d_hash_mask,
+					0);
+
+	for (loop = 0; loop < (1 << d_hash_shift); loop++)
+		INIT_HLIST_HEAD(&dentry_hashtable[loop]);
 }
 
 /* SLAB cache for __getname() consumers */
diff -Nru a/fs/debugfs/Makefile b/fs/debugfs/Makefile
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/fs/debugfs/Makefile	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,4 @@
+debugfs-objs	:= inode.o file.o
+
+obj-$(CONFIG_DEBUG_FS)	+= debugfs.o
+
diff -Nru a/fs/debugfs/file.c b/fs/debugfs/file.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/fs/debugfs/file.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,262 @@
+/*
+ *  file.c - part of debugfs, a tiny little debug file system
+ *
+ *  Copyright (C) 2004 Greg Kroah-Hartman <greg@kroah.com>
+ *  Copyright (C) 2004 IBM 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.
+ *
+ *  debugfs is for people to use instead of /proc or /sys.
+ *  See Documentation/DocBook/kernel-api for more details.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/pagemap.h>
+#include <linux/debugfs.h>
+
+static ssize_t default_read_file(struct file *file, char __user *buf,
+				 size_t count, loff_t *ppos)
+{
+	return 0;
+}
+
+static ssize_t default_write_file(struct file *file, const char __user *buf,
+				   size_t count, loff_t *ppos)
+{
+	return count;
+}
+
+static int default_open(struct inode *inode, struct file *file)
+{
+	if (inode->u.generic_ip)
+		file->private_data = inode->u.generic_ip;
+
+	return 0;
+}
+
+struct file_operations debugfs_file_operations = {
+	.read =		default_read_file,
+	.write =	default_write_file,
+	.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, *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);
+
+/**
+ * debugfs_create_u8 - create a file in the debugfs filesystem that is used to read and write a unsigned 8 bit value.
+ *
+ * @name: a pointer to a string containing the name of the file to create.
+ * @mode: the permission that the file should have
+ * @parent: a pointer to the parent dentry for this file.  This should be a
+ *          directory dentry if set.  If this paramater is NULL, then the
+ *          file will be created in the root of the debugfs filesystem.
+ * @value: a pointer to the variable that the file should read to and write
+ *         from.
+ *
+ * This function creates a file in debugfs with the given name that
+ * contains the value of the variable @value.  If the @mode variable is so
+ * set, it can be read from, and written to.
+ *
+ * This function will return a pointer to a dentry if it succeeds.  This
+ * pointer must be passed to the debugfs_remove() function when the file is
+ * to be removed (no automatic cleanup happens if your module is unloaded,
+ * you are responsible here.)  If an error occurs, NULL will be returned.
+ *
+ * If debugfs is not enabled in the kernel, the value -ENODEV will be
+ * returned.  It is not wise to check for this value, but rather, check for
+ * NULL or !NULL instead as to eliminate the need for #ifdef in the calling
+ * code.
+ */
+struct dentry *debugfs_create_u8(const char *name, mode_t mode,
+				 struct dentry *parent, u8 *value)
+{
+	return debugfs_create_file(name, mode, parent, value, &fops_u8);
+}
+EXPORT_SYMBOL_GPL(debugfs_create_u8);
+
+/**
+ * debugfs_create_u16 - create a file in the debugfs filesystem that is used to read and write a unsigned 8 bit value.
+ *
+ * @name: a pointer to a string containing the name of the file to create.
+ * @mode: the permission that the file should have
+ * @parent: a pointer to the parent dentry for this file.  This should be a
+ *          directory dentry if set.  If this paramater is NULL, then the
+ *          file will be created in the root of the debugfs filesystem.
+ * @value: a pointer to the variable that the file should read to and write
+ *         from.
+ *
+ * This function creates a file in debugfs with the given name that
+ * contains the value of the variable @value.  If the @mode variable is so
+ * set, it can be read from, and written to.
+ *
+ * This function will return a pointer to a dentry if it succeeds.  This
+ * pointer must be passed to the debugfs_remove() function when the file is
+ * to be removed (no automatic cleanup happens if your module is unloaded,
+ * you are responsible here.)  If an error occurs, NULL will be returned.
+ *
+ * If debugfs is not enabled in the kernel, the value -ENODEV will be
+ * returned.  It is not wise to check for this value, but rather, check for
+ * NULL or !NULL instead as to eliminate the need for #ifdef in the calling
+ * code.
+ */
+struct dentry *debugfs_create_u16(const char *name, mode_t mode,
+				  struct dentry *parent, u16 *value)
+{
+	return debugfs_create_file(name, mode, parent, value, &fops_u16);
+}
+EXPORT_SYMBOL_GPL(debugfs_create_u16);
+
+/**
+ * debugfs_create_u32 - create a file in the debugfs filesystem that is used to read and write a unsigned 8 bit value.
+ *
+ * @name: a pointer to a string containing the name of the file to create.
+ * @mode: the permission that the file should have
+ * @parent: a pointer to the parent dentry for this file.  This should be a
+ *          directory dentry if set.  If this paramater is NULL, then the
+ *          file will be created in the root of the debugfs filesystem.
+ * @value: a pointer to the variable that the file should read to and write
+ *         from.
+ *
+ * This function creates a file in debugfs with the given name that
+ * contains the value of the variable @value.  If the @mode variable is so
+ * set, it can be read from, and written to.
+ *
+ * This function will return a pointer to a dentry if it succeeds.  This
+ * pointer must be passed to the debugfs_remove() function when the file is
+ * to be removed (no automatic cleanup happens if your module is unloaded,
+ * you are responsible here.)  If an error occurs, NULL will be returned.
+ *
+ * If debugfs is not enabled in the kernel, the value -ENODEV will be
+ * returned.  It is not wise to check for this value, but rather, check for
+ * NULL or !NULL instead as to eliminate the need for #ifdef in the calling
+ * code.
+ */
+struct dentry *debugfs_create_u32(const char *name, mode_t mode,
+				 struct dentry *parent, u32 *value)
+{
+	return debugfs_create_file(name, mode, parent, value, &fops_u32);
+}
+EXPORT_SYMBOL_GPL(debugfs_create_u32);
+
+static ssize_t read_file_bool(struct file *file, char __user *user_buf,
+			      size_t count, loff_t *ppos)
+{
+	char buf[3];
+	u32 *val = file->private_data;
+	
+	if (val)
+		buf[0] = 'Y';
+	else
+		buf[0] = 'N';
+	buf[1] = '\n';
+	buf[2] = 0x00;
+	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
+}
+
+static ssize_t write_file_bool(struct file *file, const char __user *user_buf,
+			       size_t count, loff_t *ppos)
+{
+	char buf[32];
+	int buf_size;
+	u32 *val = file->private_data;
+
+	buf_size = min(count, (sizeof(buf)-1));
+	if (copy_from_user(buf, user_buf, buf_size))
+		return -EFAULT;
+
+	switch (buf[0]) {
+	case 'y':
+	case 'Y':
+	case '1':
+		*val = 1;
+		break;
+	case 'n':
+	case 'N':
+	case '0':
+		*val = 0;
+		break;
+	}
+	
+	return count;
+}
+
+static struct file_operations fops_bool = {
+	.read =		read_file_bool,
+	.write =	write_file_bool,
+	.open =		default_open,
+};
+
+/**
+ * debugfs_create_bool - create a file in the debugfs filesystem that is used to read and write a boolean value.
+ *
+ * @name: a pointer to a string containing the name of the file to create.
+ * @mode: the permission that the file should have
+ * @parent: a pointer to the parent dentry for this file.  This should be a
+ *          directory dentry if set.  If this paramater is NULL, then the
+ *          file will be created in the root of the debugfs filesystem.
+ * @value: a pointer to the variable that the file should read to and write
+ *         from.
+ *
+ * This function creates a file in debugfs with the given name that
+ * contains the value of the variable @value.  If the @mode variable is so
+ * set, it can be read from, and written to.
+ *
+ * This function will return a pointer to a dentry if it succeeds.  This
+ * pointer must be passed to the debugfs_remove() function when the file is
+ * to be removed (no automatic cleanup happens if your module is unloaded,
+ * you are responsible here.)  If an error occurs, NULL will be returned.
+ *
+ * If debugfs is not enabled in the kernel, the value -ENODEV will be
+ * returned.  It is not wise to check for this value, but rather, check for
+ * NULL or !NULL instead as to eliminate the need for #ifdef in the calling
+ * code.
+ */
+struct dentry *debugfs_create_bool(const char *name, mode_t mode,
+				   struct dentry *parent, u32 *value)
+{
+	return debugfs_create_file(name, mode, parent, value, &fops_bool);
+}
+EXPORT_SYMBOL_GPL(debugfs_create_bool);
+
diff -Nru a/fs/debugfs/inode.c b/fs/debugfs/inode.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/fs/debugfs/inode.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,328 @@
+/*
+ *  file.c - part of debugfs, a tiny little debug file system
+ *
+ *  Copyright (C) 2004 Greg Kroah-Hartman <greg@kroah.com>
+ *  Copyright (C) 2004 IBM 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.
+ *
+ *  debugfs is for people to use instead of /proc or /sys.
+ *  See Documentation/DocBook/kernel-api for more details.
+ *
+ */
+
+/* uncomment to get debug messages from the debug filesystem, ah the irony. */
+/* #define DEBUG */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/mount.h>
+#include <linux/pagemap.h>
+#include <linux/init.h>
+#include <linux/namei.h>
+#include <linux/debugfs.h>
+
+#define DEBUGFS_MAGIC	0x64626720
+
+/* declared over in file.c */
+extern struct file_operations debugfs_file_operations;
+
+static struct vfsmount *debugfs_mount;
+static int debugfs_mount_count;
+
+static struct inode *debugfs_get_inode(struct super_block *sb, int mode, dev_t dev)
+{
+	struct inode *inode = new_inode(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;
+		switch (mode & S_IFMT) {
+		default:
+			init_special_inode(inode, mode, dev);
+			break;
+		case S_IFREG:
+			inode->i_fop = &debugfs_file_operations;
+			break;
+		case S_IFDIR:
+			inode->i_op = &simple_dir_inode_operations;
+			inode->i_fop = &simple_dir_operations;
+
+			/* directory inodes start off with i_nlink == 2 (for "." entry) */
+			inode->i_nlink++;
+			break;
+		}
+	}
+	return inode; 
+}
+
+/* SMP-safe */
+static int debugfs_mknod(struct inode *dir, struct dentry *dentry,
+			 int mode, dev_t dev)
+{
+	struct inode *inode = debugfs_get_inode(dir->i_sb, mode, dev);
+	int error = -EPERM;
+
+	if (dentry->d_inode)
+		return -EEXIST;
+
+	if (inode) {
+		d_instantiate(dentry, inode);
+		dget(dentry);
+		error = 0;
+	}
+	return error;
+}
+
+static int debugfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
+{
+	int res;
+
+	mode = (mode & (S_IRWXUGO | S_ISVTX)) | S_IFDIR;
+	res = debugfs_mknod(dir, dentry, mode, 0);
+	if (!res)
+		dir->i_nlink++;
+	return res;
+}
+
+static int debugfs_create(struct inode *dir, struct dentry *dentry, int mode)
+{
+	mode = (mode & S_IALLUGO) | S_IFREG;
+	return debugfs_mknod(dir, dentry, mode, 0);
+}
+
+static inline int debugfs_positive(struct dentry *dentry)
+{
+	return dentry->d_inode && !d_unhashed(dentry);
+}
+
+static int debug_fill_super(struct super_block *sb, void *data, int silent)
+{
+	static struct tree_descr debug_files[] = {{""}};
+
+	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)
+{
+	return get_sb_single(fs_type, flags, data, debug_fill_super);
+}
+
+static struct file_system_type debug_fs_type = {
+	.owner =	THIS_MODULE,
+	.name =		"debugfs",
+	.get_sb =	debug_get_sb,
+	.kill_sb =	kill_litter_super,
+};
+
+static int debugfs_create_by_name(const char *name, mode_t mode,
+				  struct dentry *parent,
+				  struct dentry **dentry)
+{
+	int error = 0;
+
+	/* If the parent is not specified, we create it in the root.
+	 * We need the root dentry to do this, which is in the super 
+	 * block. A pointer to that is in the struct vfsmount that we
+	 * have around.
+	 */
+	if (!parent ) {
+		if (debugfs_mount && debugfs_mount->mnt_sb) {
+			parent = debugfs_mount->mnt_sb->s_root;
+		}
+	}
+	if (!parent) {
+		pr_debug("debugfs: Ah! can not find a parent!\n");
+		return -EFAULT;
+	}
+
+	*dentry = NULL;
+	down(&parent->d_inode->i_sem);
+	*dentry = get_dentry (parent, name);
+	if (!IS_ERR(dentry)) {
+		if ((mode & S_IFMT) == S_IFDIR)
+			error = debugfs_mkdir(parent->d_inode, *dentry, mode);
+		else 
+			error = debugfs_create(parent->d_inode, *dentry, mode);
+	} else
+		error = PTR_ERR(dentry);
+	up(&parent->d_inode->i_sem);
+
+	return error;
+}
+
+/**
+ * debugfs_create_file - create a file in the debugfs filesystem
+ *
+ * @name: a pointer to a string containing the name of the file to create.
+ * @mode: the permission that the file should have
+ * @parent: a pointer to the parent dentry for this file.  This should be a
+ *          directory dentry if set.  If this paramater is NULL, then the
+ *          file will be created in the root of the debugfs filesystem.
+ * @data: a pointer to something that the caller will want to get to later
+ *        on.  The inode.u.generic_ip pointer will point to this value on
+ *        the open() call.
+ * @fops: a pointer to a struct file_operations that should be used for
+ *        this file.
+ *
+ * This is the basic "create a file" function for debugfs.  It allows for a
+ * wide range of flexibility in createing a file, or a directory (if you
+ * want to create a directory, the debugfs_create_dir() function is
+ * recommended to be used instead.)
+ *
+ * This function will return a pointer to a dentry if it succeeds.  This
+ * pointer must be passed to the debugfs_remove() function when the file is
+ * to be removed (no automatic cleanup happens if your module is unloaded,
+ * you are responsible here.)  If an error occurs, NULL will be returned.
+ *
+ * If debugfs is not enabled in the kernel, the value -ENODEV will be
+ * returned.  It is not wise to check for this value, but rather, check for
+ * NULL or !NULL instead as to eliminate the need for #ifdef in the calling
+ * code.
+ */
+struct dentry *debugfs_create_file(const char *name, mode_t mode,
+				   struct dentry *parent, void *data,
+				   struct file_operations *fops)
+{
+	struct dentry *dentry = NULL;
+	int error;
+
+	pr_debug("debugfs: creating file '%s'\n",name);
+
+	error = simple_pin_fs("debugfs", &debugfs_mount, &debugfs_mount_count);
+	if (error)
+		goto exit;
+
+	error = debugfs_create_by_name(name, mode, parent, &dentry);
+	if (error) {
+		dentry = NULL;
+		goto exit;
+	}
+
+	if (dentry->d_inode) {
+		if (data)
+			dentry->d_inode->u.generic_ip = data;
+		if (fops)
+			dentry->d_inode->i_fop = fops;
+	}
+exit:
+	return dentry;
+}
+EXPORT_SYMBOL_GPL(debugfs_create_file);
+
+/**
+ * debugfs_create_dir - create a directory in the debugfs filesystem
+ *
+ * @name: a pointer to a string containing the name of the directory to
+ *        create.
+ * @parent: a pointer to the parent dentry for this file.  This should be a
+ *          directory dentry if set.  If this paramater is NULL, then the
+ *          directory will be created in the root of the debugfs filesystem.
+ *
+ * This function creates a directory in debugfs with the given name.
+ *
+ * This function will return a pointer to a dentry if it succeeds.  This
+ * pointer must be passed to the debugfs_remove() function when the file is
+ * to be removed (no automatic cleanup happens if your module is unloaded,
+ * you are responsible here.)  If an error occurs, NULL will be returned.
+ *
+ * If debugfs is not enabled in the kernel, the value -ENODEV will be
+ * returned.  It is not wise to check for this value, but rather, check for
+ * NULL or !NULL instead as to eliminate the need for #ifdef in the calling
+ * code.
+ */
+struct dentry *debugfs_create_dir(const char *name, struct dentry *parent)
+{
+	return debugfs_create_file(name, 
+				   S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO,
+				   parent, NULL, NULL);
+}
+EXPORT_SYMBOL_GPL(debugfs_create_dir);
+
+/**
+ * debugfs_remove - removes a file or directory from the debugfs filesystem
+ *
+ * @dentry: a pointer to a the dentry of the file or directory to be
+ *          removed.
+ *
+ * This function removes a file or directory in debugfs that was previously
+ * created with a call to another debugfs function (like
+ * debufs_create_file() or variants thereof.)
+ *
+ * This function is required to be called in order for the file to be
+ * removed, no automatic cleanup of files will happen when a module is
+ * removed, you are responsible here.
+ */
+void debugfs_remove(struct dentry *dentry)
+{
+	struct dentry *parent;
+	
+	if (!dentry)
+		return;
+
+	parent = dentry->d_parent;
+	if (!parent || !parent->d_inode)
+		return;
+
+	down(&parent->d_inode->i_sem);
+	if (debugfs_positive(dentry)) {
+		if (dentry->d_inode) {
+			if (S_ISDIR(dentry->d_inode->i_mode))
+				simple_rmdir(parent->d_inode, dentry);
+			else
+				simple_unlink(parent->d_inode, dentry);
+		dput(dentry);
+		}
+	}
+	up(&parent->d_inode->i_sem);
+	simple_release_fs(&debugfs_mount, &debugfs_mount_count);
+}
+EXPORT_SYMBOL_GPL(debugfs_remove);
+
+static decl_subsys(debug, NULL, NULL);
+
+static int __init debugfs_init(void)
+{
+	int retval;
+
+	kset_set_kset_s(&debug_subsys, kernel_subsys);
+	retval = subsystem_register(&debug_subsys);
+	if (retval)
+		return retval;
+
+	retval = register_filesystem(&debug_fs_type);
+	if (retval)
+		subsystem_unregister(&debug_subsys);
+	return retval;
+}
+
+static void __exit debugfs_exit(void)
+{
+	simple_release_fs(&debugfs_mount, &debugfs_mount_count);
+	unregister_filesystem(&debug_fs_type);
+	subsystem_unregister(&debug_subsys);
+}
+
+core_initcall(debugfs_init);
+module_exit(debugfs_exit);
+MODULE_LICENSE("GPL");
+
diff -Nru a/fs/devfs/base.c b/fs/devfs/base.c
--- a/fs/devfs/base.c	2005-03-01 23:38:53 -08:00
+++ b/fs/devfs/base.c	2005-03-01 23:38:53 -08:00
@@ -831,7 +831,7 @@
 #ifdef CONFIG_DEVFS_DEBUG
 static unsigned int devfs_debug_init __initdata = DEBUG_NONE;
 static unsigned int devfs_debug = DEBUG_NONE;
-static spinlock_t stat_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(stat_lock);
 static unsigned int stat_num_entries;
 static unsigned int stat_num_bytes;
 #endif
@@ -966,7 +966,7 @@
 {
 	struct devfs_entry *new;
 	static unsigned long inode_counter = FIRST_INODE;
-	static spinlock_t counter_lock = SPIN_LOCK_UNLOCKED;
+	static DEFINE_SPINLOCK(counter_lock);
 
 	if (name && (namelen < 1))
 		namelen = strlen(name);
@@ -1063,7 +1063,7 @@
 static struct devfs_entry *_devfs_get_root_entry(void)
 {
 	struct devfs_entry *new;
-	static spinlock_t root_lock = SPIN_LOCK_UNLOCKED;
+	static DEFINE_SPINLOCK(root_lock);
 
 	if (root_entry)
 		return root_entry;
@@ -2533,6 +2533,7 @@
 	sb->s_blocksize_bits = 10;
 	sb->s_magic = DEVFS_SUPER_MAGIC;
 	sb->s_op = &devfs_sops;
+	sb->s_time_gran = 1;
 	if ((root_inode = _devfs_get_vfs_inode(sb, root_entry, NULL)) == NULL)
 		goto out_no_root;
 	sb->s_root = d_alloc_root(root_inode);
@@ -2682,7 +2683,7 @@
 		   work even if the global kernel lock were to be removed, because it
 		   doesn't matter who gets in first, as long as only one gets it  */
 		if (fs_info->devfsd_task == NULL) {
-			static spinlock_t lock = SPIN_LOCK_UNLOCKED;
+			static DEFINE_SPINLOCK(lock);
 
 			if (!spin_trylock(&lock))
 				return -EBUSY;
diff -Nru a/fs/devpts/inode.c b/fs/devpts/inode.c
--- a/fs/devpts/inode.c	2005-03-01 23:38:53 -08:00
+++ b/fs/devpts/inode.c	2005-03-01 23:38:53 -08:00
@@ -31,7 +31,7 @@
 	NULL
 };
 
-struct inode_operations devpts_file_inode_operations = {
+static struct inode_operations devpts_file_inode_operations = {
 #ifdef CONFIG_DEVPTS_FS_XATTR
 	.setxattr	= generic_setxattr,
 	.getxattr	= generic_getxattr,
@@ -103,6 +103,7 @@
 	s->s_magic = DEVPTS_SUPER_MAGIC;
 	s->s_op = &devpts_sops;
 	s->s_xattr = devpts_xattr_handlers;
+	s->s_time_gran = 1;
 
 	inode = new_inode(s);
 	if (!inode)
diff -Nru a/fs/direct-io.c b/fs/direct-io.c
--- a/fs/direct-io.c	2005-03-01 23:38:58 -08:00
+++ b/fs/direct-io.c	2005-03-01 23:38:58 -08:00
@@ -215,7 +215,7 @@
 {
 	if (dio->end_io && dio->result)
 		dio->end_io(dio->inode, offset, bytes, dio->map_bh.b_private);
-	if (dio->lock_type != DIO_NO_LOCKING)
+	if (dio->lock_type == DIO_LOCKING)
 		up_read(&dio->inode->i_alloc_sem);
 }
 
@@ -1201,8 +1201,8 @@
 	 *	readers need to grab i_sem and i_alloc_sem
 	 *	writers need to grab i_alloc_sem only (i_sem is already held)
 	 * For regular files using DIO_OWN_LOCKING,
-	 *	readers need to grab i_alloc_sem only (i_sem is already held)
-	 *	writers need to grab i_alloc_sem only
+	 *	neither readers nor writers take any locks here
+	 *	(i_sem is already held and release for writers here)
 	 */
 	dio->lock_type = dio_lock_type;
 	if (dio_lock_type != DIO_NO_LOCKING) {
@@ -1219,14 +1219,15 @@
 				kfree(dio);
 				goto out;
 			}
-			down_read(&inode->i_alloc_sem);
+
 			if (dio_lock_type == DIO_OWN_LOCKING) {
 				up(&inode->i_sem);
 				reader_with_isem = 0;
 			}
-		} else {
-			down_read(&inode->i_alloc_sem);
 		}
+
+		if (dio_lock_type == DIO_LOCKING)
+			down_read(&inode->i_alloc_sem);
 	}
 
 	/*
diff -Nru a/fs/dquot.c b/fs/dquot.c
--- a/fs/dquot.c	2005-03-01 23:39:07 -08:00
+++ b/fs/dquot.c	2005-03-01 23:39:07 -08:00
@@ -49,7 +49,7 @@
  *		New SMP locking.
  *		Jan Kara, <jack@suse.cz>, 10/2002
  *
- *		Added journalled quota support
+ *		Added journalled quota support, fix lock inversion problems
  *		Jan Kara, <jack@suse.cz>, 2003,2004
  *
  * (C) Copyright 1994 - 1997 Marco van Wieringen 
@@ -75,7 +75,8 @@
 #include <linux/proc_fs.h>
 #include <linux/security.h>
 #include <linux/kmod.h>
-#include <linux/pagemap.h>
+#include <linux/namei.h>
+#include <linux/buffer_head.h>
 
 #include <asm/uaccess.h>
 
@@ -114,19 +115,22 @@
  * operations on dquots don't hold dq_lock as they copy data under dq_data_lock
  * spinlock to internal buffers before writing.
  *
- * Lock ordering (including related VFS locks) is following:
+ * Lock ordering (including related VFS locks) is the following:
  *   i_sem > dqonoff_sem > iprune_sem > journal_lock > dqptr_sem >
  *   > dquot->dq_lock > dqio_sem
  * i_sem on quota files is special (it's below dqio_sem)
  */
 
-static spinlock_t dq_list_lock = SPIN_LOCK_UNLOCKED;
-spinlock_t dq_data_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(dq_list_lock);
+DEFINE_SPINLOCK(dq_data_lock);
 
 static char *quotatypes[] = INITQFNAMES;
 static struct quota_format_type *quota_formats;	/* List of registered formats */
 static struct quota_module_name module_names[] = INIT_QUOTA_MODULE_NAMES;
 
+/* SLAB cache for dquot structures */
+static kmem_cache_t *dquot_cachep;
+
 int register_quota_format(struct quota_format_type *fmt)
 {
 	spin_lock(&dq_list_lock);
@@ -183,8 +187,7 @@
  * on all three lists, depending on its current state.
  *
  * All dquots are placed to the end of inuse_list when first created, and this
- * list is used for the sync and invalidate operations, which must look
- * at every dquot.
+ * list is used for invalidate operation, which must look at every dquot.
  *
  * Unused dquots (dq_count == 0) are added to the free_dquots list when freed,
  * and this list is searched whenever we need an available dquot.  Dquots are
@@ -199,7 +202,7 @@
 
 static LIST_HEAD(inuse_list);
 static LIST_HEAD(free_dquots);
-unsigned int dq_hash_bits, dq_hash_mask;
+static unsigned int dq_hash_bits, dq_hash_mask;
 static struct hlist_head *dquot_hash;
 
 struct dqstats dqstats;
@@ -774,8 +777,13 @@
 	clear_bit(DQ_BLKS_B, &dquot->dq_flags);
 }
 
+static int flag_print_warnings = 1;
+
 static inline int need_print_warning(struct dquot *dquot)
 {
+	if (!flag_print_warnings)
+		return 0;
+
 	switch (dquot->dq_type) {
 		case USRQUOTA:
 			return current->fsuid == dquot->dq_id;
@@ -803,6 +811,7 @@
 
 	if (!need_print_warning(dquot) || (flag && test_and_set_bit(flag, &dquot->dq_flags)))
 		return;
+
 	tty_write_message(current->signal->tty, dquot->dq_sb->s_id);
 	if (warntype == ISOFTWARN || warntype == BSOFTWARN)
 		tty_write_message(current->signal->tty, ": warning, ");
@@ -1314,10 +1323,14 @@
 {
 	int cnt;
 	struct quota_info *dqopt = sb_dqopt(sb);
+	struct inode *toputinode[MAXQUOTAS];
+	struct vfsmount *toputmnt[MAXQUOTAS];
 
 	/* We need to serialize quota_off() for device */
 	down(&dqopt->dqonoff_sem);
 	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
+		toputinode[cnt] = NULL;
+		toputmnt[cnt] = NULL;
 		if (type != -1 && cnt != type)
 			continue;
 		if (!sb_has_quota_enabled(sb, cnt))
@@ -1337,14 +1350,51 @@
 			dqopt->ops[cnt]->free_file_info(sb, cnt);
 		put_quota_format(dqopt->info[cnt].dqi_format);
 
-		fput(dqopt->files[cnt]);
+		toputinode[cnt] = dqopt->files[cnt];
+		toputmnt[cnt] = dqopt->mnt[cnt];
 		dqopt->files[cnt] = NULL;
+		dqopt->mnt[cnt] = NULL;
 		dqopt->info[cnt].dqi_flags = 0;
 		dqopt->info[cnt].dqi_igrace = 0;
 		dqopt->info[cnt].dqi_bgrace = 0;
 		dqopt->ops[cnt] = NULL;
 	}
 	up(&dqopt->dqonoff_sem);
+	/* Sync the superblock so that buffers with quota data are written to
+	 * disk (and so userspace sees correct data afterwards).
+	 * The reference to vfsmnt we are still holding protects us from
+	 * umount (we don't have it only when quotas are turned on/off for
+	 * journal replay but in that case we are guarded by the fs anyway). */
+	if (sb->s_op->sync_fs)
+		sb->s_op->sync_fs(sb, 1);
+	sync_blockdev(sb->s_bdev);
+	/* Now the quota files are just ordinary files and we can set the
+	 * inode flags back. Moreover we discard the pagecache so that
+	 * userspace sees the writes we did bypassing the pagecache. We
+	 * must also discard the blockdev buffers so that we see the
+	 * changes done by userspace on the next quotaon() */
+	for (cnt = 0; cnt < MAXQUOTAS; cnt++)
+		if (toputinode[cnt]) {
+			down(&dqopt->dqonoff_sem);
+			/* If quota was reenabled in the meantime, we have
+			 * nothing to do */
+			if (!sb_has_quota_enabled(sb, cnt)) {
+				down(&toputinode[cnt]->i_sem);
+				toputinode[cnt]->i_flags &= ~(S_IMMUTABLE |
+				  S_NOATIME | S_NOQUOTA);
+				truncate_inode_pages(&toputinode[cnt]->i_data, 0);
+				up(&toputinode[cnt]->i_sem);
+				mark_inode_dirty(toputinode[cnt]);
+				iput(toputinode[cnt]);
+			}
+			up(&dqopt->dqonoff_sem);
+			/* We don't hold the reference when we turned on quotas
+			 * just for the journal replay... */
+			if (toputmnt[cnt])
+				mntput(toputmnt[cnt]);
+		}
+	if (sb->s_bdev)
+		invalidate_bdev(sb->s_bdev, 0);
 	return 0;
 }
 
@@ -1352,68 +1402,56 @@
  *	Turn quotas on on a device
  */
 
-/* Helper function when we already have file open */
-static int vfs_quota_on_file(struct file *f, int type, int format_id)
+/* Helper function when we already have the inode */
+static int vfs_quota_on_inode(struct inode *inode, int type, int format_id)
 {
 	struct quota_format_type *fmt = find_quota_format(format_id);
-	struct inode *inode;
-	struct super_block *sb = f->f_dentry->d_sb;
+	struct super_block *sb = inode->i_sb;
 	struct quota_info *dqopt = sb_dqopt(sb);
-	struct dquot *to_drop[MAXQUOTAS];
-	int error, cnt;
-	unsigned int oldflags = -1;
+	int error;
+	int oldflags = -1;
 
 	if (!fmt)
 		return -ESRCH;
-	error = -EIO;
-	if (!f->f_op || !f->f_op->read || !f->f_op->write)
+	if (!S_ISREG(inode->i_mode)) {
+		error = -EACCES;
 		goto out_fmt;
-	inode = f->f_dentry->d_inode;
-	error = -EACCES;
-	if (!S_ISREG(inode->i_mode))
+	}
+	if (IS_RDONLY(inode)) {
+		error = -EROFS;
+		goto out_fmt;
+	}
+	if (!sb->s_op->quota_write || !sb->s_op->quota_read) {
+		error = -EINVAL;
 		goto out_fmt;
+	}
 
+	/* As we bypass the pagecache we must now flush the inode so that
+	 * we see all the changes from userspace... */
+	write_inode_now(inode, 1);
+	/* And now flush the block cache so that kernel sees the changes */
+	invalidate_bdev(sb->s_bdev, 0);
 	down(&inode->i_sem);
 	down(&dqopt->dqonoff_sem);
 	if (sb_has_quota_enabled(sb, type)) {
-		up(&inode->i_sem);
 		error = -EBUSY;
 		goto out_lock;
 	}
 	/* We don't want quota and atime on quota files (deadlocks possible)
-	 * We also need to set GFP mask differently because we cannot recurse
-	 * into filesystem when allocating page for quota inode */
+	 * Also nobody should write to the file - we use special IO operations
+	 * which ignore the immutable bit. */
 	down_write(&dqopt->dqptr_sem);
-	oldflags = inode->i_flags & (S_NOATIME | S_NOQUOTA);
-	inode->i_flags |= S_NOQUOTA | S_NOATIME;
+	oldflags = inode->i_flags & (S_NOATIME | S_IMMUTABLE | S_NOQUOTA);
+	inode->i_flags |= S_NOQUOTA | S_NOATIME | S_IMMUTABLE;
 	up_write(&dqopt->dqptr_sem);
-	up(&inode->i_sem);
 
-	dqopt->files[type] = f;
+	error = -EIO;
+	dqopt->files[type] = igrab(inode);
+	if (!dqopt->files[type])
+		goto out_lock;
 	error = -EINVAL;
 	if (!fmt->qf_ops->check_quota_file(sb, type))
 		goto out_file_init;
-	/*
-	 * We write to quota files deep within filesystem code.  We don't want
-	 * the VFS to reenter filesystem code when it tries to allocate a
-	 * pagecache page for the quota file write.  So clear __GFP_FS in
-	 * the quota file's allocation flags.
-	 */
-	mapping_set_gfp_mask(inode->i_mapping,
-		mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS);
-
-	down_write(&dqopt->dqptr_sem);
-	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
-		to_drop[cnt] = inode->i_dquot[cnt];
-		inode->i_dquot[cnt] = NODQUOT;
-	}
-	up_write(&dqopt->dqptr_sem);
-	/* We must put dquots outside of dqptr_sem because we may need to
-	 * start transaction for dquot_release() */
-	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
-		if (to_drop[cnt])
-			dqput(to_drop[cnt]);
-	}
 
 	dqopt->ops[type] = fmt->qf_ops;
 	dqopt->info[type].dqi_format = fmt;
@@ -1424,6 +1462,7 @@
 		goto out_file_init;
 	}
 	up(&dqopt->dqio_sem);
+	up(&inode->i_sem);
 	set_enable_flags(dqopt, type);
 
 	add_dquot_ref(sb, type);
@@ -1433,19 +1472,18 @@
 
 out_file_init:
 	dqopt->files[type] = NULL;
+	iput(inode);
 out_lock:
 	up(&dqopt->dqonoff_sem);
 	if (oldflags != -1) {
-		down(&inode->i_sem);
 		down_write(&dqopt->dqptr_sem);
-		/* Reset the NOATIME flag back. I know it could change in the
-		 * mean time but playing with NOATIME flags on a quota file is
-		 * never a good idea */
-		inode->i_flags &= ~(S_NOATIME | S_NOQUOTA);
+		/* Set the flags back (in the case of accidental quotaon()
+		 * on a wrong file we don't want to mess up the flags) */
+		inode->i_flags &= ~(S_NOATIME | S_NOQUOTA | S_IMMUTABLE);
 		inode->i_flags |= oldflags;
 		up_write(&dqopt->dqptr_sem);
-		up(&inode->i_sem);
 	}
+	up(&inode->i_sem);
 out_fmt:
 	put_quota_format(fmt);
 
@@ -1455,47 +1493,40 @@
 /* Actual function called from quotactl() */
 int vfs_quota_on(struct super_block *sb, int type, int format_id, char *path)
 {
-	struct file *f;
+	struct nameidata nd;
 	int error;
 
-	f = filp_open(path, O_RDWR, 0600);
-	if (IS_ERR(f))
-		return PTR_ERR(f);
-	error = security_quota_on(f);
+	error = path_lookup(path, LOOKUP_FOLLOW, &nd);
+	if (error < 0)
+		return error;
+	error = security_quota_on(nd.dentry);
 	if (error)
-		goto out_f;
-	error = vfs_quota_on_file(f, type, format_id);
-	if (!error)
-		return 0;
-out_f:
-	filp_close(f, NULL);
+		goto out_path;
+	/* Quota file not on the same filesystem? */
+	if (nd.mnt->mnt_sb != sb)
+		error = -EXDEV;
+	else {
+		error = vfs_quota_on_inode(nd.dentry->d_inode, type, format_id);
+		if (!error)
+			sb_dqopt(sb)->mnt[type] = mntget(nd.mnt);
+	}
+out_path:
+	path_release(&nd);
 	return error;
 }
 
 /*
- * Function used by filesystems when filp_open() would fail (filesystem is
- * being mounted now). We will use a private file structure. Caller is
- * responsible that it's IO functions won't need vfsmnt structure or
- * some dentry tricks...
+ * 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)
 {
-	struct file *f;
 	int error;
 
-	dget(dentry);	/* Get a reference for struct file */
-	f = dentry_open(dentry, NULL, O_RDWR);
-	if (IS_ERR(f)) {
-		error = PTR_ERR(f);
-		goto out_dentry;
-	}
-	error = vfs_quota_on_file(f, type, format_id);
-	if (!error)
-		return 0;
-	fput(f);
-out_dentry:
-	dput(dentry);
-	return error;
+	error = security_quota_on(dentry);
+	if (error)
+		return error;
+	return vfs_quota_on_inode(dentry->d_inode, type, format_id);
 }
 
 /* Generic routine for getting common part of quota structure */
@@ -1722,6 +1753,14 @@
 		.mode		= 0444,
 		.proc_handler	= &proc_dointvec,
 	},
+	{
+		.ctl_name	= FS_DQ_WARNINGS,
+		.procname	= "warnings",
+		.data		= &flag_print_warnings,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec,
+	},
 	{ .ctl_name = 0 },
 };
 
@@ -1744,9 +1783,6 @@
 	},
 	{ .ctl_name = 0 },
 };
-
-/* SLAB cache for dquot structures */
-kmem_cache_t *dquot_cachep;
 
 static int __init dquot_init(void)
 {
diff -Nru a/fs/efs/super.c b/fs/efs/super.c
--- a/fs/efs/super.c	2005-03-01 23:39:09 -08:00
+++ b/fs/efs/super.c	2005-03-01 23:39:09 -08:00
@@ -32,6 +32,26 @@
 	.fs_flags	= FS_REQUIRES_DEV,
 };
 
+static struct pt_types sgi_pt_types[] = {
+	{0x00,		"SGI vh"},
+	{0x01,		"SGI trkrepl"},
+	{0x02,		"SGI secrepl"},
+	{0x03,		"SGI raw"},
+	{0x04,		"SGI bsd"},
+	{SGI_SYSV,	"SGI sysv"},
+	{0x06,		"SGI vol"},
+	{SGI_EFS,	"SGI efs"},
+	{0x08,		"SGI lv"},
+	{0x09,		"SGI rlv"},
+	{0x0A,		"SGI xfs"},
+	{0x0B,		"SGI xfslog"},
+	{0x0C,		"SGI xlv"},
+	{0x82,		"Linux swap"},
+	{0x83,		"Linux native"},
+	{0,		NULL}
+};
+
+
 static kmem_cache_t * efs_inode_cachep;
 
 static struct inode *efs_alloc_inode(struct super_block *sb)
diff -Nru a/fs/exec.c b/fs/exec.c
--- a/fs/exec.c	2005-03-01 23:38:55 -08:00
+++ b/fs/exec.c	2005-03-01 23:38:55 -08:00
@@ -47,6 +47,7 @@
 #include <linux/security.h>
 #include <linux/syscalls.h>
 #include <linux/rmap.h>
+#include <linux/acct.h>
 
 #include <asm/uaccess.h>
 #include <asm/mmu_context.h>
@@ -60,7 +61,7 @@
 /* The maximal length of core_pattern is also specified in sysctl.c */
 
 static struct linux_binfmt *formats;
-static rwlock_t binfmt_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(binfmt_lock);
 
 int register_binfmt(struct linux_binfmt * fmt)
 {
@@ -185,6 +186,7 @@
 			argv++;
 			if(++i > max)
 				return -E2BIG;
+			cond_resched();
 		}
 	}
 	return i;
@@ -300,6 +302,7 @@
 {
 	struct mm_struct *mm = vma->vm_mm;
 	pgd_t * pgd;
+	pud_t * pud;
 	pmd_t * pmd;
 	pte_t * pte;
 
@@ -310,7 +313,10 @@
 	pgd = pgd_offset(mm, address);
 
 	spin_lock(&mm->page_table_lock);
-	pmd = pmd_alloc(mm, pgd, address);
+	pud = pud_alloc(mm, pgd, address);
+	if (!pud)
+		goto out;
+	pmd = pmd_alloc(mm, pud, address);
 	if (!pmd)
 		goto out;
 	pte = pte_alloc_map(mm, pmd, address);
@@ -337,7 +343,11 @@
 	force_sig(SIGKILL, current);
 }
 
-int setup_arg_pages(struct linux_binprm *bprm, int executable_stack)
+#define EXTRA_STACK_VM_PAGES	20	/* random */
+
+int setup_arg_pages(struct linux_binprm *bprm,
+		    unsigned long stack_top,
+		    int executable_stack)
 {
 	unsigned long stack_base;
 	struct vm_area_struct *mpnt;
@@ -374,14 +384,14 @@
 	memmove(to, to + offset, PAGE_SIZE - offset);
 	kunmap(bprm->page[j - 1]);
 
-	/* Adjust bprm->p to point to the end of the strings. */
-	bprm->p = PAGE_SIZE * i - offset;
-
 	/* Limit stack size to 1GB */
 	stack_base = current->signal->rlim[RLIMIT_STACK].rlim_max;
 	if (stack_base > (1 << 30))
 		stack_base = 1 << 30;
-	stack_base = PAGE_ALIGN(STACK_TOP - stack_base);
+	stack_base = PAGE_ALIGN(stack_top - stack_base);
+
+	/* Adjust bprm->p to point to the end of the strings. */
+	bprm->p = stack_base + PAGE_SIZE * i - offset;
 
 	mm->arg_start = stack_base;
 	arg_size = i << PAGE_SHIFT;
@@ -390,12 +400,14 @@
 	while (i < MAX_ARG_PAGES)
 		bprm->page[i++] = NULL;
 #else
-	stack_base = STACK_TOP - MAX_ARG_PAGES * PAGE_SIZE;
-	mm->arg_start = bprm->p + stack_base;
-	arg_size = STACK_TOP - (PAGE_MASK & (unsigned long) mm->arg_start);
+	stack_base = stack_top - MAX_ARG_PAGES * PAGE_SIZE;
+	bprm->p += stack_base;
+	mm->arg_start = bprm->p;
+	arg_size = stack_top - (PAGE_MASK & (unsigned long) mm->arg_start);
 #endif
 
-	bprm->p += stack_base;
+	arg_size += EXTRA_STACK_VM_PAGES * PAGE_SIZE;
+
 	if (bprm->loader)
 		bprm->loader += stack_base;
 	bprm->exec += stack_base;
@@ -416,11 +428,10 @@
 		mpnt->vm_mm = mm;
 #ifdef CONFIG_STACK_GROWSUP
 		mpnt->vm_start = stack_base;
-		mpnt->vm_end = PAGE_MASK &
-			(PAGE_SIZE - 1 + (unsigned long) bprm->p);
+		mpnt->vm_end = stack_base + arg_size;
 #else
-		mpnt->vm_start = PAGE_MASK & (unsigned long) bprm->p;
-		mpnt->vm_end = STACK_TOP;
+		mpnt->vm_end = stack_top;
+		mpnt->vm_start = mpnt->vm_end - arg_size;
 #endif
 		/* Adjust stack execute permissions; explicitly enable
 		 * for EXSTACK_ENABLE_X, disable for EXSTACK_DISABLE_X
@@ -539,6 +550,21 @@
 	old_mm = current->mm;
 	mm_release(tsk, old_mm);
 
+	if (old_mm) {
+		/*
+		 * Make sure that if there is a core dump in progress
+		 * for the old mm, we get out and die instead of going
+		 * through with the exec.  We must hold mmap_sem around
+		 * checking core_waiters and changing tsk->mm.  The
+		 * core-inducing thread will increment core_waiters for
+		 * each thread whose ->mm == old_mm.
+		 */
+		down_read(&old_mm->mmap_sem);
+		if (unlikely(old_mm->core_waiters)) {
+			up_read(&old_mm->mmap_sem);
+			return -EINTR;
+		}
+	}
 	task_lock(tsk);
 	active_mm = tsk->active_mm;
 	tsk->mm = mm;
@@ -547,6 +573,7 @@
 	task_unlock(tsk);
 	arch_pick_mmap_layout(mm);
 	if (old_mm) {
+		up_read(&old_mm->mmap_sem);
 		if (active_mm != old_mm) BUG();
 		mmput(old_mm);
 		return 0;
@@ -591,7 +618,7 @@
 	 */
 	read_lock(&tasklist_lock);
 	spin_lock_irq(lock);
-	if (sig->group_exit) {
+	if (sig->flags & SIGNAL_GROUP_EXIT) {
 		/*
 		 * Another group action in progress, just
 		 * return so that the signal is processed.
@@ -601,7 +628,6 @@
 		kmem_cache_free(sighand_cachep, newsighand);
 		return -EAGAIN;
 	}
-	sig->group_exit = 1;
 	zap_other_threads(current);
 	read_unlock(&tasklist_lock);
 
@@ -609,7 +635,7 @@
 	 * Account for the thread group leader hanging around:
 	 */
 	count = 2;
-	if (current->pid == current->tgid)
+	if (thread_group_leader(current))
 		count = 1;
 	while (atomic_read(&sig->count) > count) {
 		sig->group_exit_task = current;
@@ -628,7 +654,7 @@
 	 * do is to wait for the thread group leader to become inactive,
 	 * and to assume its PID:
 	 */
-	if (current->pid != current->tgid) {
+	if (!thread_group_leader(current)) {
 		struct task_struct *leader = current->group_leader, *parent;
 		struct dentry *proc_dentry1, *proc_dentry2;
 		unsigned long exit_state, ptrace;
@@ -659,6 +685,14 @@
 		 */
 		ptrace = leader->ptrace;
 		parent = leader->parent;
+		if (unlikely(ptrace) && unlikely(parent == current)) {
+			/*
+			 * Joker was ptracing his own group leader,
+			 * and now he wants to be his own parent!
+			 * We can't have that.
+			 */
+			ptrace = 0;
+		}
 
 		ptrace_unlink(current);
 		ptrace_unlink(leader);
@@ -699,7 +733,7 @@
 	 * Now there are really no other threads at all,
 	 * so it's safe to stop telling them to kill themselves.
 	 */
-	sig->group_exit = 0;
+	sig->flags = 0;
 
 no_thread_group:
 	BUG_ON(atomic_read(&sig->count) != 1);
@@ -738,7 +772,7 @@
 
 	if (!thread_group_empty(current))
 		BUG();
-	if (current->tgid != current->pid)
+	if (!thread_group_leader(current))
 		BUG();
 	return 0;
 }
@@ -953,6 +987,7 @@
 	unsafe = unsafe_exec(current);
 	security_bprm_apply_creds(bprm, unsafe);
 	task_unlock(current);
+	security_bprm_post_apply_creds(bprm);
 }
 
 EXPORT_SYMBOL(compute_creds);
@@ -1156,6 +1191,8 @@
 
 		/* execve success */
 		security_bprm_free(bprm);
+		acct_update_integrals();
+		update_mem_hiwater();
 		kfree(bprm);
 		return retval;
 	}
@@ -1325,6 +1362,7 @@
 	struct task_struct *g, *p;
 	struct task_struct *tsk = current;
 	struct completion *vfork_done = tsk->vfork_done;
+	int traced = 0;
 
 	/*
 	 * Make sure nobody is waiting for us to release the VM,
@@ -1340,10 +1378,30 @@
 		if (mm == p->mm && p != tsk) {
 			force_sig_specific(SIGKILL, p);
 			mm->core_waiters++;
+			if (unlikely(p->ptrace) &&
+			    unlikely(p->parent->mm == mm))
+				traced = 1;
 		}
 	while_each_thread(g,p);
 
 	read_unlock(&tasklist_lock);
+
+	if (unlikely(traced)) {
+		/*
+		 * We are zapping a thread and the thread it ptraces.
+		 * If the tracee went into a ptrace stop for exit tracing,
+		 * we could deadlock since the tracer is waiting for this
+		 * coredump to finish.  Detach them so they can both die.
+		 */
+		write_lock_irq(&tasklist_lock);
+		do_each_thread(g,p) {
+			if (mm == p->mm && p != tsk &&
+			    p->ptrace && p->parent->mm == mm) {
+				__ptrace_unlink(p);
+			}
+		} while_each_thread(g,p);
+		write_unlock_irq(&tasklist_lock);
+	}
 }
 
 static void coredump_wait(struct mm_struct *mm)
@@ -1384,9 +1442,18 @@
 	}
 	mm->dumpable = 0;
 	init_completion(&mm->core_done);
-	current->signal->group_exit = 1;
+	spin_lock_irq(&current->sighand->siglock);
+	current->signal->flags = SIGNAL_GROUP_EXIT;
 	current->signal->group_exit_code = exit_code;
+	spin_unlock_irq(&current->sighand->siglock);
 	coredump_wait(mm);
+
+	/*
+	 * Clear any false indication of pending signals that might
+	 * be seen by the filesystem code called to write the core file.
+	 */
+	current->signal->group_stop_count = 0;
+	clear_thread_flag(TIF_SIGPENDING);
 
 	if (current->signal->rlim[RLIMIT_CORE].rlim_cur < binfmt->min_coredump)
 		goto fail_unlock;
diff -Nru a/fs/ext2/acl.c b/fs/ext2/acl.c
--- a/fs/ext2/acl.c	2005-03-01 23:39:09 -08:00
+++ b/fs/ext2/acl.c	2005-03-01 23:39:09 -08:00
@@ -255,8 +255,6 @@
 			return -EINVAL;
 	}
  	if (acl) {
-		if (acl->a_count > EXT2_ACL_MAX_ENTRIES)
-			return -EINVAL;
 		value = ext2_acl_to_disk(acl, &size);
 		if (IS_ERR(value))
 			return (int)PTR_ERR(value);
diff -Nru a/fs/ext2/acl.h b/fs/ext2/acl.h
--- a/fs/ext2/acl.h	2005-03-01 23:39:08 -08:00
+++ b/fs/ext2/acl.h	2005-03-01 23:39:08 -08:00
@@ -7,7 +7,6 @@
 #include <linux/xattr_acl.h>
 
 #define EXT2_ACL_VERSION	0x0001
-#define EXT2_ACL_MAX_ENTRIES	32
 
 typedef struct {
 	__le16		e_tag;
@@ -77,7 +76,6 @@
 
 static inline int ext2_init_acl (struct inode *inode, struct inode *dir)
 {
-	inode->i_mode &= ~current->fs->umask;
 	return 0;
 }
 #endif
diff -Nru a/fs/ext2/balloc.c b/fs/ext2/balloc.c
--- a/fs/ext2/balloc.c	2005-03-01 23:38:55 -08:00
+++ b/fs/ext2/balloc.c	2005-03-01 23:38:55 -08:00
@@ -6,7 +6,7 @@
  * Laboratoire MASI - Institut Blaise Pascal
  * Universite Pierre et Marie Curie (Paris VI)
  *
- *  Enhanced block allocation by Stephen Tweedie (sct@dcs.ed.ac.uk), 1993
+ *  Enhanced block allocation by Stephen Tweedie (sct@redhat.com), 1993
  *  Big-endian to little-endian byte-swapping/bitmaps by
  *        David S. Miller (davem@caip.rutgers.edu), 1995
  */
@@ -52,9 +52,9 @@
 
 		return NULL;
 	}
-	
-	group_desc = block_group / EXT2_DESC_PER_BLOCK(sb);
-	offset = block_group % EXT2_DESC_PER_BLOCK(sb);
+
+	group_desc = block_group >> EXT2_DESC_PER_BLOCK_BITS(sb);
+	offset = block_group & (EXT2_DESC_PER_BLOCK(sb) - 1);
 	if (!sbi->s_group_desc[group_desc]) {
 		ext2_error (sb, "ext2_get_group_desc",
 			    "Group descriptor not loaded - "
@@ -62,7 +62,7 @@
 			     block_group, group_desc, offset);
 		return NULL;
 	}
-	
+
 	desc = (struct ext2_group_desc *) sbi->s_group_desc[group_desc]->b_data;
 	if (bh)
 		*bh = sbi->s_group_desc[group_desc];
@@ -236,12 +236,12 @@
 
 	for (i = 0, group_freed = 0; i < count; i++) {
 		if (!ext2_clear_bit_atomic(sb_bgl_lock(sbi, block_group),
-					bit + i, (void *) bitmap_bh->b_data))
-			ext2_error (sb, "ext2_free_blocks",
-				      "bit already cleared for block %lu",
-				      block + i);
-		else
+						bit + i, bitmap_bh->b_data)) {
+			ext2_error(sb, __FUNCTION__,
+				"bit already cleared for block %lu", block + i);
+		} else {
 			group_freed++;
+		}
 	}
 
 	mark_buffer_dirty(bitmap_bh);
@@ -569,25 +569,24 @@
 static inline int
 block_in_use(unsigned long block, struct super_block *sb, unsigned char *map)
 {
-	return ext2_test_bit ((block - le32_to_cpu(EXT2_SB(sb)->s_es->s_first_data_block)) %
+	return ext2_test_bit ((block -
+		le32_to_cpu(EXT2_SB(sb)->s_es->s_first_data_block)) %
 			 EXT2_BLOCKS_PER_GROUP(sb), map);
 }
 
 static inline int test_root(int a, int b)
 {
-	if (a == 0)
-		return 1;
-	while (1) {
-		if (a == 1)
-			return 1;
-		if (a % b)
-			return 0;
-		a = a / b;
-	}
+	int num = b;
+
+	while (a > num)
+		num *= b;
+	return num == a;
 }
 
 static int ext2_group_sparse(int group)
 {
+	if (group <= 1)
+		return 1;
 	return (test_root(group, 3) || test_root(group, 5) ||
 		test_root(group, 7));
 }
diff -Nru a/fs/ext2/dir.c b/fs/ext2/dir.c
--- a/fs/ext2/dir.c	2005-03-01 23:38:58 -08:00
+++ b/fs/ext2/dir.c	2005-03-01 23:38:58 -08:00
@@ -426,7 +426,7 @@
 	ext2_set_de_type (de, inode);
 	err = ext2_commit_chunk(page, from, to);
 	ext2_put_page(page);
-	dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+	dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
 	EXT2_I(dir)->i_flags &= ~EXT2_BTREE_FL;
 	mark_inode_dirty(dir);
 }
@@ -516,7 +516,7 @@
 	de->inode = cpu_to_le32(inode->i_ino);
 	ext2_set_de_type (de, inode);
 	err = ext2_commit_chunk(page, from, to);
-	dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+	dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
 	EXT2_I(dir)->i_flags &= ~EXT2_BTREE_FL;
 	mark_inode_dirty(dir);
 	/* OFFSET_CACHE */
@@ -564,7 +564,7 @@
 		pde->rec_len = cpu_to_le16(to-from);
 	dir->inode = 0;
 	err = ext2_commit_chunk(page, from, to);
-	inode->i_ctime = inode->i_mtime = CURRENT_TIME;
+	inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC;
 	EXT2_I(inode)->i_flags &= ~EXT2_BTREE_FL;
 	mark_inode_dirty(inode);
 out:
diff -Nru a/fs/ext2/ext2.h b/fs/ext2/ext2.h
--- a/fs/ext2/ext2.h	2005-03-01 23:39:17 -08:00
+++ b/fs/ext2/ext2.h	2005-03-01 23:39:17 -08:00
@@ -119,6 +119,7 @@
 extern void ext2_delete_inode (struct inode *);
 extern int ext2_sync_inode (struct inode *);
 extern void ext2_discard_prealloc (struct inode *);
+extern int ext2_get_block(struct inode *, sector_t, struct buffer_head *, int);
 extern void ext2_truncate (struct inode *);
 extern int ext2_setattr (struct dentry *, struct iattr *);
 extern void ext2_set_inode_flags(struct inode *inode);
diff -Nru a/fs/ext2/ialloc.c b/fs/ext2/ialloc.c
--- a/fs/ext2/ialloc.c	2005-03-01 23:38:57 -08:00
+++ b/fs/ext2/ialloc.c	2005-03-01 23:38:57 -08:00
@@ -577,7 +577,7 @@
 	inode->i_ino = ino;
 	inode->i_blksize = PAGE_SIZE;	/* This is the optimal IO size (for stat), not the fs block size */
 	inode->i_blocks = 0;
-	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
+	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
 	memset(ei->i_data, 0, sizeof(ei->i_data));
 	ei->i_flags = EXT2_I(dir)->i_flags & ~EXT2_BTREE_FL;
 	if (S_ISLNK(mode))
diff -Nru a/fs/ext2/inode.c b/fs/ext2/inode.c
--- a/fs/ext2/inode.c	2005-03-01 23:38:52 -08:00
+++ b/fs/ext2/inode.c	2005-03-01 23:38:52 -08:00
@@ -354,7 +354,7 @@
 {
 	struct ext2_inode_info *ei = EXT2_I(inode);
 	write_lock(&ei->i_meta_lock);
-	if (block == ei->i_next_alloc_block + 1) {
+	if ((block == ei->i_next_alloc_block + 1) && ei->i_next_alloc_goal) {
 		ei->i_next_alloc_block++;
 		ei->i_next_alloc_goal++;
 	} 
@@ -493,7 +493,7 @@
 
 	/* We are done with atomic stuff, now do the rest of housekeeping */
 
-	inode->i_ctime = CURRENT_TIME;
+	inode->i_ctime = CURRENT_TIME_SEC;
 
 	/* had we spliced it onto indirect block? */
 	if (where->bh)
@@ -524,7 +524,7 @@
  * reachable from inode.
  */
 
-static int ext2_get_block(struct inode *inode, sector_t iblock, struct buffer_head *bh_result, int create)
+int ext2_get_block(struct inode *inode, sector_t iblock, struct buffer_head *bh_result, int create)
 {
 	int err = -EIO;
 	int offsets[4];
@@ -953,7 +953,7 @@
 		case EXT2_TIND_BLOCK:
 			;
 	}
-	inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+	inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC;
 	if (inode_needs_sync(inode)) {
 		sync_mapping_buffers(inode->i_mapping);
 		ext2_sync_inode (inode);
diff -Nru a/fs/ext2/ioctl.c b/fs/ext2/ioctl.c
--- a/fs/ext2/ioctl.c	2005-03-01 23:39:18 -08:00
+++ b/fs/ext2/ioctl.c	2005-03-01 23:39:18 -08:00
@@ -59,7 +59,7 @@
 		ei->i_flags = flags;
 
 		ext2_set_inode_flags(inode);
-		inode->i_ctime = CURRENT_TIME;
+		inode->i_ctime = CURRENT_TIME_SEC;
 		mark_inode_dirty(inode);
 		return 0;
 	}
@@ -72,7 +72,7 @@
 			return -EROFS;
 		if (get_user(inode->i_generation, (int __user *) arg))
 			return -EFAULT;	
-		inode->i_ctime = CURRENT_TIME;
+		inode->i_ctime = CURRENT_TIME_SEC;
 		mark_inode_dirty(inode);
 		return 0;
 	default:
diff -Nru a/fs/ext2/namei.c b/fs/ext2/namei.c
--- a/fs/ext2/namei.c	2005-03-01 23:39:09 -08:00
+++ b/fs/ext2/namei.c	2005-03-01 23:39:09 -08:00
@@ -211,7 +211,7 @@
 	if (inode->i_nlink >= EXT2_LINK_MAX)
 		return -EMLINK;
 
-	inode->i_ctime = CURRENT_TIME;
+	inode->i_ctime = CURRENT_TIME_SEC;
 	ext2_inc_count(inode);
 	atomic_inc(&inode->i_count);
 
@@ -337,7 +337,7 @@
 			goto out_dir;
 		ext2_inc_count(old_inode);
 		ext2_set_link(new_dir, new_de, new_page, old_inode);
-		new_inode->i_ctime = CURRENT_TIME;
+		new_inode->i_ctime = CURRENT_TIME_SEC;
 		if (dir_de)
 			new_inode->i_nlink--;
 		ext2_dec_count(new_inode);
@@ -362,7 +362,7 @@
  	 * rename.
 	 * ext2_dec_count() will mark the inode dirty.
 	 */
-	old_inode->i_ctime = CURRENT_TIME;
+	old_inode->i_ctime = CURRENT_TIME_SEC;
 
 	ext2_delete_entry (old_de, old_page);
 	ext2_dec_count(old_inode);
diff -Nru a/fs/ext2/super.c b/fs/ext2/super.c
--- a/fs/ext2/super.c	2005-03-01 23:39:07 -08:00
+++ b/fs/ext2/super.c	2005-03-01 23:39:07 -08:00
@@ -203,6 +203,11 @@
 }
 
 
+#ifdef CONFIG_QUOTA
+static ssize_t ext2_quota_read(struct super_block *sb, int type, char *data, size_t len, loff_t off);
+static ssize_t ext2_quota_write(struct super_block *sb, int type, const char *data, size_t len, loff_t off);
+#endif
+
 static struct super_operations ext2_sops = {
 	.alloc_inode	= ext2_alloc_inode,
 	.destroy_inode	= ext2_destroy_inode,
@@ -214,6 +219,10 @@
 	.statfs		= ext2_statfs,
 	.remount_fs	= ext2_remount,
 	.clear_inode	= ext2_clear_inode,
+#ifdef CONFIG_QUOTA
+	.quota_read	= ext2_quota_read,
+	.quota_write	= ext2_quota_write,
+#endif
 };
 
 /* Yes, most of these are left as NULL!!
@@ -595,7 +604,6 @@
 	es = (struct ext2_super_block *) (((char *)bh->b_data) + offset);
 	sbi->s_es = es;
 	sb->s_magic = le16_to_cpu(es->s_magic);
-	sb->s_flags |= MS_ONE_SECOND;
 
 	if (sb->s_magic != EXT2_SUPER_MAGIC)
 		goto cantfind_ext2;
@@ -1003,6 +1011,111 @@
 {
 	return get_sb_bdev(fs_type, flags, dev_name, data, ext2_fill_super);
 }
+
+#ifdef CONFIG_QUOTA
+
+/* Read data from quotafile - avoid pagecache and such because we cannot afford
+ * acquiring the locks... As quota files are never truncated and quota code
+ * itself serializes the operations (and noone else should touch the files)
+ * we don't have to be afraid of races */
+static ssize_t ext2_quota_read(struct super_block *sb, int type, char *data,
+			       size_t len, loff_t off)
+{
+	struct inode *inode = sb_dqopt(sb)->files[type];
+	sector_t blk = off >> EXT2_BLOCK_SIZE_BITS(sb);
+	int err = 0;
+	int offset = off & (sb->s_blocksize - 1);
+	int tocopy;
+	size_t toread;
+	struct buffer_head tmp_bh;
+	struct buffer_head *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;
+		err = ext2_get_block(inode, blk, &tmp_bh, 0);
+		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 */
+static ssize_t ext2_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];
+	sector_t blk = off >> EXT2_BLOCK_SIZE_BITS(sb);
+	int err = 0;
+	int offset = off & (sb->s_blocksize - 1);
+	int tocopy;
+	size_t towrite = len;
+	struct buffer_head tmp_bh;
+	struct buffer_head *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 = ext2_get_block(inode, blk, &tmp_bh, 1);
+		if (err)
+			goto out;
+		if (offset || tocopy != EXT2_BLOCK_SIZE(sb))
+			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);
+		mark_buffer_dirty(bh);
+		unlock_buffer(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 file_system_type ext2_fs_type = {
 	.owner		= THIS_MODULE,
diff -Nru a/fs/ext2/xattr.c b/fs/ext2/xattr.c
--- a/fs/ext2/xattr.c	2005-03-01 23:39:07 -08:00
+++ b/fs/ext2/xattr.c	2005-03-01 23:39:07 -08:00
@@ -24,7 +24,7 @@
  *
  *   +------------------+
  *   | header           |
- *   ¦ entry 1          | |
+ *   | entry 1          | |
  *   | entry 2          | | growing downwards
  *   | entry 3          | v
  *   | four null bytes  |
@@ -95,13 +95,12 @@
 static int ext2_xattr_cache_insert(struct buffer_head *);
 static struct buffer_head *ext2_xattr_cache_find(struct inode *,
 						 struct ext2_xattr_header *);
-static void ext2_xattr_cache_remove(struct buffer_head *);
 static void ext2_xattr_rehash(struct ext2_xattr_header *,
 			      struct ext2_xattr_entry *);
 
 static struct mb_cache *ext2_xattr_cache;
 
-static struct xattr_handler *ext2_xattr_handler_map[EXT2_XATTR_INDEX_MAX] = {
+static struct xattr_handler *ext2_xattr_handler_map[] = {
 	[EXT2_XATTR_INDEX_USER]		     = &ext2_xattr_user_handler,
 #ifdef CONFIG_EXT2_FS_POSIX_ACL
 	[EXT2_XATTR_INDEX_POSIX_ACL_ACCESS]  = &ext2_xattr_acl_access_handler,
@@ -131,23 +130,12 @@
 {
 	struct xattr_handler *handler = NULL;
 
-	if (name_index > 0 && name_index <= EXT2_XATTR_INDEX_MAX)
+	if (name_index > 0 && name_index < ARRAY_SIZE(ext2_xattr_handler_map))
 		handler = ext2_xattr_handler_map[name_index];
 	return handler;
 }
 
 /*
- * Inode operation listxattr()
- *
- * dentry->d_inode->i_sem: don't care
- */
-ssize_t
-ext2_listxattr(struct dentry *dentry, char *buffer, size_t size)
-{
-	return ext2_xattr_list(dentry->d_inode, buffer, size);
-}
-
-/*
  * ext2_xattr_get()
  *
  * Copy an extended attribute into the buffer
@@ -260,7 +248,7 @@
  * Returns a negative error number on failure, or the number of bytes
  * used / required on success.
  */
-int
+static int
 ext2_xattr_list(struct inode *inode, char *buffer, size_t buffer_size)
 {
 	struct buffer_head *bh = NULL;
@@ -335,6 +323,17 @@
 }
 
 /*
+ * Inode operation listxattr()
+ *
+ * dentry->d_inode->i_sem: don't care
+ */
+ssize_t
+ext2_listxattr(struct dentry *dentry, char *buffer, size_t size)
+{
+	return ext2_xattr_list(dentry->d_inode, buffer, size);
+}
+
+/*
  * If the EXT2_FEATURE_COMPAT_EXT_ATTR feature of this file system is
  * not set, set it.
  */
@@ -494,15 +493,22 @@
 	/* Here we know that we can set the new attribute. */
 
 	if (header) {
+		struct mb_cache_entry *ce;
+
 		/* assert(header == HDR(bh)); */
+		ce = mb_cache_entry_get(ext2_xattr_cache, bh->b_bdev,
+					bh->b_blocknr);
 		lock_buffer(bh);
 		if (header->h_refcount == cpu_to_le32(1)) {
 			ea_bdebug(bh, "modifying in-place");
-			ext2_xattr_cache_remove(bh);
+			if (ce)
+				mb_cache_entry_free(ce);
 			/* keep the buffer locked while modifying it. */
 		} else {
 			int offset;
 
+			if (ce)
+				mb_cache_entry_release(ce);
 			unlock_buffer(bh);
 			ea_bdebug(bh, "cloning");
 			header = kmalloc(bh->b_size, GFP_KERNEL);
@@ -697,23 +703,35 @@
 
 	/* Update the inode. */
 	EXT2_I(inode)->i_file_acl = new_bh ? new_bh->b_blocknr : 0;
-	inode->i_ctime = CURRENT_TIME;
+	inode->i_ctime = CURRENT_TIME_SEC;
 	if (IS_SYNC(inode)) {
 		error = ext2_sync_inode (inode);
-		if (error)
+		/* In case sync failed due to ENOSPC the inode was actually
+		 * written (only some dirty data were not) so we just proceed
+		 * as if nothing happened and cleanup the unused block */
+		if (error && error != -ENOSPC) {
+			if (new_bh && new_bh != old_bh)
+				DQUOT_FREE_BLOCK(inode, 1);
 			goto cleanup;
+		}
 	} else
 		mark_inode_dirty(inode);
 
 	error = 0;
 	if (old_bh && old_bh != new_bh) {
+		struct mb_cache_entry *ce;
+
 		/*
 		 * If there was an old block and we are no longer using it,
 		 * release the old block.
 		 */
+		ce = mb_cache_entry_get(ext2_xattr_cache, old_bh->b_bdev,
+					old_bh->b_blocknr);
 		lock_buffer(old_bh);
 		if (HDR(old_bh)->h_refcount == cpu_to_le32(1)) {
 			/* Free the old block. */
+			if (ce)
+				mb_cache_entry_free(ce);
 			ea_bdebug(old_bh, "freeing");
 			ext2_free_blocks(inode, old_bh->b_blocknr, 1);
 			/* We let our caller release old_bh, so we
@@ -724,6 +742,8 @@
 			/* Decrement the refcount only. */
 			HDR(old_bh)->h_refcount = cpu_to_le32(
 				le32_to_cpu(HDR(old_bh)->h_refcount) - 1);
+			if (ce)
+				mb_cache_entry_release(ce);
 			DQUOT_FREE_BLOCK(inode, 1);
 			mark_buffer_dirty(old_bh);
 			ea_bdebug(old_bh, "refcount now=%d",
@@ -748,6 +768,7 @@
 ext2_xattr_delete_inode(struct inode *inode)
 {
 	struct buffer_head *bh = NULL;
+	struct mb_cache_entry *ce;
 
 	down_write(&EXT2_I(inode)->xattr_sem);
 	if (!EXT2_I(inode)->i_file_acl)
@@ -767,15 +788,19 @@
 			EXT2_I(inode)->i_file_acl);
 		goto cleanup;
 	}
+	ce = mb_cache_entry_get(ext2_xattr_cache, bh->b_bdev, bh->b_blocknr);
 	lock_buffer(bh);
 	if (HDR(bh)->h_refcount == cpu_to_le32(1)) {
-		ext2_xattr_cache_remove(bh);
+		if (ce)
+			mb_cache_entry_free(ce);
 		ext2_free_blocks(inode, EXT2_I(inode)->i_file_acl, 1);
 		get_bh(bh);
 		bforget(bh);
 	} else {
 		HDR(bh)->h_refcount = cpu_to_le32(
 			le32_to_cpu(HDR(bh)->h_refcount) - 1);
+		if (ce)
+			mb_cache_entry_release(ce);
 		mark_buffer_dirty(bh);
 		if (IS_SYNC(inode))
 			sync_dirty_buffer(bh);
@@ -856,6 +881,7 @@
 		if (IS_LAST_ENTRY(entry2))
 			return 1;
 		if (entry1->e_hash != entry2->e_hash ||
+		    entry1->e_name_index != entry2->e_name_index ||
 		    entry1->e_name_len != entry2->e_name_len ||
 		    entry1->e_value_size != entry2->e_value_size ||
 		    memcmp(entry1->e_name, entry2->e_name, entry1->e_name_len))
@@ -892,11 +918,19 @@
 	if (!header->h_hash)
 		return NULL;  /* never share */
 	ea_idebug(inode, "looking for cached blocks [%x]", (int)hash);
+again:
 	ce = mb_cache_entry_find_first(ext2_xattr_cache, 0,
 				       inode->i_sb->s_bdev, hash);
 	while (ce) {
-		struct buffer_head *bh = sb_bread(inode->i_sb, ce->e_block);
+		struct buffer_head *bh;
+
+		if (IS_ERR(ce)) {
+			if (PTR_ERR(ce) == -EAGAIN)
+				goto again;
+			break;
+		}
 
+		bh = sb_bread(inode->i_sb, ce->e_block);
 		if (!bh) {
 			ext2_error(inode->i_sb, "ext2_xattr_cache_find",
 				"inode %ld: block %ld read error",
@@ -923,26 +957,6 @@
 	return NULL;
 }
 
-/*
- * ext2_xattr_cache_remove()
- *
- * Remove the cache entry of a block from the cache. Called when a
- * block becomes invalid.
- */
-static void
-ext2_xattr_cache_remove(struct buffer_head *bh)
-{
-	struct mb_cache_entry *ce;
-
-	ce = mb_cache_entry_get(ext2_xattr_cache, bh->b_bdev, bh->b_blocknr);
-	if (ce) {
-		ea_bdebug(bh, "removing (%d cache entries remaining)",
-			  atomic_read(&ext2_xattr_cache->c_entry_count)-1);
-		mb_cache_entry_free(ce);
-	} else 
-		ea_bdebug(bh, "no cache entry");
-}
-
 #define NAME_HASH_SHIFT 5
 #define VALUE_HASH_SHIFT 16
 
@@ -1016,7 +1030,7 @@
 {
 	ext2_xattr_cache = mb_cache_create("ext2_xattr", NULL,
 		sizeof(struct mb_cache_entry) +
-		sizeof(struct mb_cache_entry_index), 1, 6);
+		sizeof(((struct mb_cache_entry *) 0)->e_indexes[0]), 1, 6);
 	if (!ext2_xattr_cache)
 		return -ENOMEM;
 	return 0;
diff -Nru a/fs/ext2/xattr.h b/fs/ext2/xattr.h
--- a/fs/ext2/xattr.h	2005-03-01 23:39:07 -08:00
+++ b/fs/ext2/xattr.h	2005-03-01 23:39:07 -08:00
@@ -17,7 +17,6 @@
 #define EXT2_XATTR_REFCOUNT_MAX		1024
 
 /* Name indexes */
-#define EXT2_XATTR_INDEX_MAX			10
 #define EXT2_XATTR_INDEX_USER			1
 #define EXT2_XATTR_INDEX_POSIX_ACL_ACCESS	2
 #define EXT2_XATTR_INDEX_POSIX_ACL_DEFAULT	3
@@ -66,7 +65,6 @@
 extern ssize_t ext2_listxattr(struct dentry *, char *, size_t);
 
 extern int ext2_xattr_get(struct inode *, int, const char *, void *, size_t);
-extern int ext2_xattr_list(struct inode *, char *, size_t);
 extern int ext2_xattr_set(struct inode *, int, const char *, const void *, size_t, int);
 
 extern void ext2_xattr_delete_inode(struct inode *);
@@ -82,12 +80,6 @@
 static inline int
 ext2_xattr_get(struct inode *inode, int name_index,
 	       const char *name, void *buffer, size_t size)
-{
-	return -EOPNOTSUPP;
-}
-
-static inline int
-ext2_xattr_list(struct inode *inode, char *buffer, size_t size)
 {
 	return -EOPNOTSUPP;
 }
diff -Nru a/fs/ext3/acl.c b/fs/ext3/acl.c
--- a/fs/ext3/acl.c	2005-03-01 23:38:55 -08:00
+++ b/fs/ext3/acl.c	2005-03-01 23:38:55 -08:00
@@ -259,8 +259,6 @@
 			return -EINVAL;
 	}
  	if (acl) {
-		if (acl->a_count > EXT3_ACL_MAX_ENTRIES)
-			return -EINVAL;
 		value = ext3_acl_to_disk(acl, &size);
 		if (IS_ERR(value))
 			return (int)PTR_ERR(value);
diff -Nru a/fs/ext3/acl.h b/fs/ext3/acl.h
--- a/fs/ext3/acl.h	2005-03-01 23:39:16 -08:00
+++ b/fs/ext3/acl.h	2005-03-01 23:39:16 -08:00
@@ -7,7 +7,6 @@
 #include <linux/xattr_acl.h>
 
 #define EXT3_ACL_VERSION	0x0001
-#define EXT3_ACL_MAX_ENTRIES	32
 
 typedef struct {
 	__le16		e_tag;
@@ -79,7 +78,6 @@
 static inline int
 ext3_init_acl(handle_t *handle, struct inode *inode, struct inode *dir)
 {
-	inode->i_mode &= ~current->fs->umask;
 	return 0;
 }
 #endif  /* CONFIG_EXT3_FS_POSIX_ACL */
diff -Nru a/fs/ext3/balloc.c b/fs/ext3/balloc.c
--- a/fs/ext3/balloc.c	2005-03-01 23:38:52 -08:00
+++ b/fs/ext3/balloc.c	2005-03-01 23:38:52 -08:00
@@ -56,8 +56,8 @@
 	}
 	smp_rmb();
 
-	group_desc = block_group / EXT3_DESC_PER_BLOCK(sb);
-	desc = block_group % EXT3_DESC_PER_BLOCK(sb);
+	group_desc = block_group >> EXT3_DESC_PER_BLOCK_BITS(sb);
+	desc = block_group & (EXT3_DESC_PER_BLOCK(sb) - 1);
 	if (!EXT3_SB(sb)->s_group_desc[group_desc]) {
 		ext3_error (sb, "ext3_get_group_desc",
 			    "Group descriptor not loaded - "
@@ -378,6 +378,11 @@
 		}
 		jbd_lock_bh_state(bitmap_bh);
 #endif
+		if (need_resched()) {
+			jbd_unlock_bh_state(bitmap_bh);
+			cond_resched();
+			jbd_lock_bh_state(bitmap_bh);
+		}
 		/* @@@ This prevents newly-allocated data from being
 		 * freed and then reallocated within the same
 		 * transaction. 
@@ -1435,19 +1440,17 @@
 
 static inline int test_root(int a, int b)
 {
-	if (a == 0)
-		return 1;
-	while (1) {
-		if (a == 1)
-			return 1;
-		if (a % b)
-			return 0;
-		a = a / b;
-	}
+	int num = b;
+
+	while (a > num)
+		num *= b;
+	return num == a;
 }
 
-int ext3_group_sparse(int group)
+static int ext3_group_sparse(int group)
 {
+	if (group <= 1)
+		return 1;
 	return (test_root(group, 3) || test_root(group, 5) ||
 		test_root(group, 7));
 }
diff -Nru a/fs/ext3/dir.c b/fs/ext3/dir.c
--- a/fs/ext3/dir.c	2005-03-01 23:38:57 -08:00
+++ b/fs/ext3/dir.c	2005-03-01 23:38:57 -08:00
@@ -306,7 +306,7 @@
 }
 
 
-struct dir_private_info *create_dir_info(loff_t pos)
+static struct dir_private_info *create_dir_info(loff_t pos)
 {
 	struct dir_private_info *p;
 
diff -Nru a/fs/ext3/file.c b/fs/ext3/file.c
--- a/fs/ext3/file.c	2005-03-01 23:39:17 -08:00
+++ b/fs/ext3/file.c	2005-03-01 23:39:17 -08:00
@@ -43,20 +43,6 @@
 	return 0;
 }
 
-/*
- * Called when an inode is about to be opened.
- * We use this to disallow opening RW large files on 32bit systems if
- * the caller didn't specify O_LARGEFILE.  On 64bit systems we force
- * on this flag in sys_open.
- */
-static int ext3_open_file (struct inode *inode, struct file *filp)
-{
-	if (!(filp->f_flags & O_LARGEFILE) &&
-	    inode->i_size > 0x7FFFFFFFLL)
-		return -EFBIG;
-	return 0;
-}
-
 static ssize_t
 ext3_file_write(struct kiocb *iocb, const char __user *buf, size_t count, loff_t pos)
 {
@@ -125,7 +111,7 @@
 	.writev		= generic_file_writev,
 	.ioctl		= ext3_ioctl,
 	.mmap		= generic_file_mmap,
-	.open		= ext3_open_file,
+	.open		= generic_file_open,
 	.release	= ext3_release_file,
 	.fsync		= ext3_sync_file,
 	.sendfile	= generic_file_sendfile,
diff -Nru a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c
--- a/fs/ext3/ialloc.c	2005-03-01 23:38:57 -08:00
+++ b/fs/ext3/ialloc.c	2005-03-01 23:38:57 -08:00
@@ -558,7 +558,7 @@
 	/* This is the optimal IO size (for stat), not the fs block size */
 	inode->i_blksize = PAGE_SIZE;
 	inode->i_blocks = 0;
-	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
+	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
 
 	memset(ei->i_data, 0, sizeof(ei->i_data));
 	ei->i_next_alloc_block = 0;
@@ -596,6 +596,9 @@
 	spin_unlock(&sbi->s_next_gen_lock);
 
 	ei->i_state = EXT3_STATE_NEW;
+	ei->i_extra_isize =
+		(EXT3_INODE_SIZE(inode->i_sb) > EXT3_GOOD_OLD_INODE_SIZE) ?
+		sizeof(struct ext3_inode) - EXT3_GOOD_OLD_INODE_SIZE : 0;
 
 	ret = inode;
 	if(DQUOT_ALLOC_INODE(inode)) {
@@ -732,6 +735,7 @@
 		if (!gdp)
 			continue;
 		desc_count += le16_to_cpu(gdp->bg_free_inodes_count);
+		cond_resched();
 	}
 	return desc_count;
 #endif
diff -Nru a/fs/ext3/inode.c b/fs/ext3/inode.c
--- a/fs/ext3/inode.c	2005-03-01 23:39:07 -08:00
+++ b/fs/ext3/inode.c	2005-03-01 23:39:07 -08:00
@@ -39,6 +39,8 @@
 #include "xattr.h"
 #include "acl.h"
 
+static int ext3_writepage_trans_blocks(struct inode *inode);
+
 /*
  * Test whether an inode is a fast symlink.
  */
@@ -84,7 +86,7 @@
 	    (!is_metadata && !ext3_should_journal_data(inode))) {
 		if (bh) {
 			BUFFER_TRACE(bh, "call journal_forget");
-			ext3_journal_forget(handle, bh);
+			return ext3_journal_forget(handle, bh);
 		}
 		return 0;
 	}
@@ -462,7 +464,7 @@
 {
 	struct ext3_inode_info *ei = EXT3_I(inode);
 	/* Writer: ->i_next_alloc* */
-	if (block == ei->i_next_alloc_block + 1) {
+	if ((block == ei->i_next_alloc_block + 1)&& ei->i_next_alloc_goal) {
 		ei->i_next_alloc_block++;
 		ei->i_next_alloc_goal++;
 	}
@@ -626,7 +628,7 @@
 
 	/* We are done with atomic stuff, now do the rest of housekeeping */
 
-	inode->i_ctime = CURRENT_TIME;
+	inode->i_ctime = CURRENT_TIME_SEC;
 	ext3_mark_inode_dirty(handle, inode);
 
 	/* had we spliced it onto indirect block? */
@@ -1025,7 +1027,7 @@
 	return ret;
 }
 
-static int
+int
 ext3_journal_dirty_data(handle_t *handle, struct buffer_head *bh)
 {
 	int err = journal_dirty_data(handle, bh);
@@ -2199,7 +2201,7 @@
 			;
 	}
 	up(&ei->truncate_sem);
-	inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+	inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC;
 	ext3_mark_inode_dirty(handle, inode);
 
 	/* In a multi-transaction truncate, we only make the final
@@ -2269,13 +2271,13 @@
 	return block;
 }
 
-/* 
+/*
  * ext3_get_inode_loc returns with an extra refcount against the inode's
- * underlying buffer_head on success.  If `in_mem' is false then we're purely
- * trying to determine the inode's location on-disk and no read need be
- * performed.
+ * underlying buffer_head on success. If 'in_mem' is true, we have all
+ * data in memory that is needed to recreate the on-disk version of this
+ * inode.
  */
-static int ext3_get_inode_loc(struct inode *inode,
+static int __ext3_get_inode_loc(struct inode *inode,
 				struct ext3_iloc *iloc, int in_mem)
 {
 	unsigned long block;
@@ -2300,7 +2302,11 @@
 			goto has_buffer;
 		}
 
-		/* we can't skip I/O if inode is on a disk only */
+		/*
+		 * If we have all information of the inode in memory and this
+		 * is the only valid inode in the block, we need not read the
+		 * block.
+		 */
 		if (in_mem) {
 			struct buffer_head *bitmap_bh;
 			struct ext3_group_desc *desc;
@@ -2309,10 +2315,6 @@
 			int block_group;
 			int start;
 
-			/*
-			 * If this is the only valid inode in the block we
-			 * need not read the block.
-			 */
 			block_group = (inode->i_ino - 1) /
 					EXT3_INODES_PER_GROUP(inode->i_sb);
 			inodes_per_buffer = bh->b_size /
@@ -2359,8 +2361,9 @@
 
 make_io:
 		/*
-		 * There are another valid inodes in the buffer so we must
-		 * read the block from disk
+		 * There are other valid inodes in the buffer, this inode
+		 * has in-inode xattrs, or we don't have this inode in memory.
+		 * Read the block from disk.
 		 */
 		get_bh(bh);
 		bh->b_end_io = end_buffer_read_sync;
@@ -2380,6 +2383,13 @@
 	return 0;
 }
 
+int ext3_get_inode_loc(struct inode *inode, struct ext3_iloc *iloc)
+{
+	/* We have all inode data except xattrs in memory here. */
+	return __ext3_get_inode_loc(inode, iloc,
+		!(EXT3_I(inode)->i_state & EXT3_STATE_XATTR));
+}
+
 void ext3_set_inode_flags(struct inode *inode)
 {
 	unsigned int flags = EXT3_I(inode)->i_flags;
@@ -2411,7 +2421,7 @@
 #endif
 	ei->i_rsv_window.rsv_end = EXT3_RESERVE_WINDOW_NOT_ALLOCATED;
 
-	if (ext3_get_inode_loc(inode, &iloc, 0))
+	if (__ext3_get_inode_loc(inode, &iloc, 0))
 		goto bad_inode;
 	bh = iloc.bh;
 	raw_inode = ext3_raw_inode(&iloc);
@@ -2483,6 +2493,31 @@
 		ei->i_data[block] = raw_inode->i_block[block];
 	INIT_LIST_HEAD(&ei->i_orphan);
 
+	if (inode->i_ino >= EXT3_FIRST_INO(inode->i_sb) + 1 &&
+	    EXT3_INODE_SIZE(inode->i_sb) > EXT3_GOOD_OLD_INODE_SIZE) {
+		/*
+		 * When mke2fs creates big inodes it does not zero out
+		 * the unused bytes above EXT3_GOOD_OLD_INODE_SIZE,
+		 * so ignore those first few inodes.
+		 */
+		ei->i_extra_isize = le16_to_cpu(raw_inode->i_extra_isize);
+		if (EXT3_GOOD_OLD_INODE_SIZE + ei->i_extra_isize >
+		    EXT3_INODE_SIZE(inode->i_sb))
+			goto bad_inode;
+		if (ei->i_extra_isize == 0) {
+			/* The extra space is currently unused. Use it. */
+			ei->i_extra_isize = sizeof(struct ext3_inode) -
+					    EXT3_GOOD_OLD_INODE_SIZE;
+		} else {
+			__le32 *magic = (void *)raw_inode +
+					EXT3_GOOD_OLD_INODE_SIZE +
+					ei->i_extra_isize;
+			if (*magic == cpu_to_le32(EXT3_XATTR_MAGIC))
+				 ei->i_state |= EXT3_STATE_XATTR;
+		}
+	} else
+		ei->i_extra_isize = 0;
+
 	if (S_ISREG(inode->i_mode)) {
 		inode->i_op = &ext3_file_inode_operations;
 		inode->i_fop = &ext3_file_operations;
@@ -2618,6 +2653,9 @@
 	} 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)
+		raw_inode->i_extra_isize = cpu_to_le16(ei->i_extra_isize);
+
 	BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata");
 	rc = ext3_journal_dirty_metadata(handle, bh);
 	if (!err)
@@ -2799,7 +2837,7 @@
  * block and work out the exact number of indirects which are touched.  Pah.
  */
 
-int ext3_writepage_trans_blocks(struct inode *inode)
+static int ext3_writepage_trans_blocks(struct inode *inode)
 {
 	int bpp = ext3_journal_blocks_per_page(inode);
 	int indirects = (EXT3_NDIR_BLOCKS % bpp) ? 5 : 3;
@@ -2848,7 +2886,7 @@
 {
 	int err = 0;
 	if (handle) {
-		err = ext3_get_inode_loc(inode, iloc, 1);
+		err = ext3_get_inode_loc(inode, iloc);
 		if (!err) {
 			BUFFER_TRACE(iloc->bh, "get_write_access");
 			err = ext3_journal_get_write_access(handle, iloc->bh);
@@ -2947,7 +2985,7 @@
 
 	int err = 0;
 	if (handle) {
-		err = ext3_get_inode_loc(inode, &iloc, 1);
+		err = ext3_get_inode_loc(inode, &iloc);
 		if (!err) {
 			BUFFER_TRACE(iloc.bh, "get_write_access");
 			err = journal_get_write_access(handle, iloc.bh);
diff -Nru a/fs/ext3/ioctl.c b/fs/ext3/ioctl.c
--- a/fs/ext3/ioctl.c	2005-03-01 23:38:55 -08:00
+++ b/fs/ext3/ioctl.c	2005-03-01 23:38:55 -08:00
@@ -87,7 +87,7 @@
 		ei->i_flags = flags;
 
 		ext3_set_inode_flags(inode);
-		inode->i_ctime = CURRENT_TIME;
+		inode->i_ctime = CURRENT_TIME_SEC;
 
 		err = ext3_mark_iloc_dirty(handle, inode, &iloc);
 flags_err:
@@ -121,7 +121,7 @@
 			return PTR_ERR(handle);
 		err = ext3_reserve_inode_write(handle, inode, &iloc);
 		if (err == 0) {
-			inode->i_ctime = CURRENT_TIME;
+			inode->i_ctime = CURRENT_TIME_SEC;
 			inode->i_generation = generation;
 			err = ext3_mark_iloc_dirty(handle, inode, &iloc);
 		}
diff -Nru a/fs/ext3/namei.c b/fs/ext3/namei.c
--- a/fs/ext3/namei.c	2005-03-01 23:38:58 -08:00
+++ b/fs/ext3/namei.c	2005-03-01 23:38:58 -08:00
@@ -610,10 +610,14 @@
 		de = (struct ext3_dir_entry_2 *) frames[0].bh->b_data;
 		if ((err = ext3_htree_store_dirent(dir_file, 0, 0, de)) != 0)
 			goto errout;
+		count++;
+	}
+	if (start_hash < 2 || (start_hash ==2 && start_minor_hash==0)) {
+		de = (struct ext3_dir_entry_2 *) frames[0].bh->b_data;
 		de = ext3_next_entry(de);
-		if ((err = ext3_htree_store_dirent(dir_file, 0, 0, de)) != 0)
+		if ((err = ext3_htree_store_dirent(dir_file, 2, 0, de)) != 0)
 			goto errout;
-		count += 2;
+		count++;
 	}
 
 	while (1) {
@@ -671,6 +675,7 @@
 			map_tail->hash = h.hash;
 			map_tail->offs = (u32) ((char *) de - base);
 			count++;
+			cond_resched();
 		}
 		/* XXX: do we need to check rec_len == 0 case? -Chris */
 		de = (struct ext3_dir_entry_2 *) ((char *) de + le16_to_cpu(de->rec_len));
@@ -1251,7 +1256,7 @@
 	 * happen is that the times are slightly out of date
 	 * and/or different from the directory change time.
 	 */
-	dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+	dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
 	ext3_update_dx_flag(dir);
 	dir->i_version++;
 	ext3_mark_inode_dirty(handle, dir);
@@ -2029,7 +2034,7 @@
 	 * recovery. */
 	inode->i_size = 0;
 	ext3_orphan_add(handle, inode);
-	inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+	inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
 	ext3_mark_inode_dirty(handle, inode);
 	dir->i_nlink--;
 	ext3_update_dx_flag(dir);
@@ -2079,7 +2084,7 @@
 	retval = ext3_delete_entry(handle, dir, de, bh);
 	if (retval)
 		goto end_unlink;
-	dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+	dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
 	ext3_update_dx_flag(dir);
 	ext3_mark_inode_dirty(handle, dir);
 	inode->i_nlink--;
@@ -2169,7 +2174,7 @@
 	if (IS_DIRSYNC(dir))
 		handle->h_sync = 1;
 
-	inode->i_ctime = CURRENT_TIME;
+	inode->i_ctime = CURRENT_TIME_SEC;
 	ext3_inc_count(handle, inode);
 	atomic_inc(&inode->i_count);
 
@@ -2270,7 +2275,7 @@
 	 * Like most other Unix systems, set the ctime for inodes on a
 	 * rename.
 	 */
-	old_inode->i_ctime = CURRENT_TIME;
+	old_inode->i_ctime = CURRENT_TIME_SEC;
 	ext3_mark_inode_dirty(handle, old_inode);
 
 	/*
@@ -2303,9 +2308,9 @@
 
 	if (new_inode) {
 		new_inode->i_nlink--;
-		new_inode->i_ctime = CURRENT_TIME;
+		new_inode->i_ctime = CURRENT_TIME_SEC;
 	}
-	old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
+	old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME_SEC;
 	ext3_update_dx_flag(old_dir);
 	if (dir_bh) {
 		BUFFER_TRACE(dir_bh, "get_write_access");
diff -Nru a/fs/ext3/resize.c b/fs/ext3/resize.c
--- a/fs/ext3/resize.c	2005-03-01 23:39:18 -08:00
+++ b/fs/ext3/resize.c	2005-03-01 23:39:18 -08:00
@@ -285,8 +285,8 @@
  * sequence of powers of 3, 5, and 7: 1, 3, 5, 7, 9, 25, 27, 49, 81, ...
  * For a non-sparse filesystem it will be every group: 1, 2, 3, 4, ...
  */
-unsigned ext3_list_backups(struct super_block *sb, unsigned *three,
-			   unsigned *five, unsigned *seven)
+static unsigned ext3_list_backups(struct super_block *sb, unsigned *three,
+				  unsigned *five, unsigned *seven)
 {
 	unsigned *min = three;
 	int mult = 3;
diff -Nru a/fs/ext3/super.c b/fs/ext3/super.c
--- a/fs/ext3/super.c	2005-03-01 23:39:10 -08:00
+++ b/fs/ext3/super.c	2005-03-01 23:39:10 -08:00
@@ -50,6 +50,13 @@
 static void ext3_clear_journal_err(struct super_block * sb,
 				   struct ext3_super_block * es);
 static int ext3_sync_fs(struct super_block *sb, int wait);
+static const char *ext3_decode_error(struct super_block * sb, int errno,
+				     char nbuf[16]);
+static int ext3_remount (struct super_block * sb, int * flags, char * data);
+static int ext3_statfs (struct super_block * sb, struct kstatfs * buf);
+static void ext3_unlockfs(struct super_block *sb);
+static void ext3_write_super (struct super_block * sb);
+static void ext3_write_super_lockfs(struct super_block *sb);
 
 /* 
  * Wrappers for journal_start/end.
@@ -108,14 +115,19 @@
 	char nbuf[16];
 	const char *errstr = ext3_decode_error(NULL, err, nbuf);
 
-	printk(KERN_ERR "%s: aborting transaction: %s in %s", 
-	       caller, errstr, err_fn);
-
 	if (bh)
 		BUFFER_TRACE(bh, "abort");
-	journal_abort_handle(handle);
+
 	if (!handle->h_err)
 		handle->h_err = err;
+
+	if (is_handle_aborted(handle))
+		return;
+
+	printk(KERN_ERR "%s: aborting transaction: %s in %s\n",
+	       caller, errstr, err_fn);
+
+	journal_abort_handle(handle);
 }
 
 /* Deal with the reporting of failure conditions on a filesystem such as
@@ -143,9 +155,6 @@
 	if (sb->s_flags & MS_RDONLY)
 		return;
 
-	if (test_opt (sb, ERRORS_PANIC))
-		panic ("EXT3-fs (device %s): panic forced after error\n",
-		       sb->s_id);
 	if (test_opt (sb, ERRORS_RO)) {
 		printk (KERN_CRIT "Remounting filesystem read-only\n");
 		sb->s_flags |= MS_RDONLY;
@@ -156,6 +165,9 @@
 		if (journal)
 			journal_abort(journal, -EIO);
 	}
+	if (test_opt(sb, ERRORS_PANIC))
+		panic("EXT3-fs (device %s): panic forced after error\n",
+			sb->s_id);
 	ext3_commit_super(sb, es, 1);
 }
 
@@ -173,7 +185,8 @@
 	ext3_handle_error(sb);
 }
 
-const char *ext3_decode_error(struct super_block * sb, int errno, char nbuf[16])
+static const char *ext3_decode_error(struct super_block * sb, int errno,
+				     char nbuf[16])
 {
 	char *errstr = NULL;
 
@@ -256,29 +269,6 @@
 	journal_abort(EXT3_SB(sb)->s_journal, -EIO);
 }
 
-/* Deal with the reporting of failure conditions while running, such as
- * inconsistencies in operation or invalid system states.
- *
- * Use ext3_error() for cases of invalid filesystem states, as that will
- * record an error on disk and force a filesystem check on the next boot.
- */
-NORET_TYPE void ext3_panic (struct super_block * sb, const char * function,
-			    const char * fmt, ...)
-{
-	va_list args;
-
-	va_start(args, fmt);
-	printk(KERN_CRIT "EXT3-fs error (device %s): %s: ",sb->s_id, function);
-	vprintk(fmt, args);
-	printk("\n");
-	va_end(args);
-
-	/* this is to prevent panic from syncing this filesystem */
-	/* AKPM: is this sufficient? */
-	sb->s_flags |= MS_RDONLY;
-	panic ("EXT3-fs panic forced\n");
-}
-
 void ext3_warning (struct super_block * sb, const char * function,
 		   const char * fmt, ...)
 {
@@ -381,7 +371,7 @@
 	}
 }
 
-void ext3_put_super (struct super_block * sb)
+static void ext3_put_super (struct super_block * sb)
 {
 	struct ext3_sb_info *sbi = EXT3_SB(sb);
 	struct ext3_super_block *es = sbi->s_es;
@@ -524,7 +514,10 @@
 static int ext3_write_info(struct super_block *sb, int type);
 static int ext3_quota_on(struct super_block *sb, int type, int format_id, char *path);
 static int ext3_quota_on_mount(struct super_block *sb, int type);
-static int ext3_quota_off_mount(struct super_block *sb, int type);
+static ssize_t ext3_quota_read(struct super_block *sb, int type, char *data,
+			       size_t len, loff_t off);
+static ssize_t ext3_quota_write(struct super_block *sb, int type,
+				const char *data, size_t len, loff_t off);
 
 static struct dquot_operations ext3_quota_operations = {
 	.initialize	= ext3_dquot_initialize,
@@ -567,6 +560,10 @@
 	.statfs		= ext3_statfs,
 	.remount_fs	= ext3_remount,
 	.clear_inode	= ext3_clear_inode,
+#ifdef CONFIG_QUOTA
+	.quota_read	= ext3_quota_read,
+	.quota_write	= ext3_quota_write,
+#endif
 };
 
 struct dentry *ext3_get_parent(struct dentry *child);
@@ -666,6 +663,7 @@
 	int option;
 #ifdef CONFIG_QUOTA
 	int qtype;
+	char *qname;
 #endif
 
 	if (!options)
@@ -844,19 +842,22 @@
 					"quota options when quota turned on.\n");
 				return 0;
 			}
-			if (sbi->s_qf_names[qtype]) {
+			qname = match_strdup(&args[0]);
+			if (!qname) {
 				printk(KERN_ERR
-					"EXT3-fs: %s quota file already "
-					"specified.\n", QTYPE2NAME(qtype));
+					"EXT3-fs: not enough memory for "
+					"storing quotafile name.\n");
 				return 0;
 			}
-			sbi->s_qf_names[qtype] = match_strdup(&args[0]);
-			if (!sbi->s_qf_names[qtype]) {
+			if (sbi->s_qf_names[qtype] &&
+			    strcmp(sbi->s_qf_names[qtype], qname)) {
 				printk(KERN_ERR
-					"EXT3-fs: not enough memory for "
-					"storing quotafile name.\n");
+					"EXT3-fs: %s quota file already "
+					"specified.\n", QTYPE2NAME(qtype));
+				kfree(qname);
 				return 0;
 			}
+			sbi->s_qf_names[qtype] = qname;
 			if (strchr(sbi->s_qf_names[qtype], '/')) {
 				printk(KERN_ERR
 					"EXT3-fs: quotafile must be on "
@@ -1176,7 +1177,7 @@
 	/* Turn quotas off */
 	for (i = 0; i < MAXQUOTAS; i++) {
 		if (sb_dqopt(sb)->files[i])
-			ext3_quota_off_mount(sb, i);
+			vfs_quota_off(sb, i);
 	}
 #endif
 	sb->s_flags = s_flags; /* Restore MS_RDONLY status */
@@ -1250,6 +1251,8 @@
 	sbi->s_resuid = EXT3_DEF_RESUID;
 	sbi->s_resgid = EXT3_DEF_RESGID;
 
+	unlock_kernel();
+
 	blocksize = sb_min_blocksize(sb, EXT3_MIN_BLOCK_SIZE);
 	if (!blocksize) {
 		printk(KERN_ERR "EXT3-fs: unable to set blocksize\n");
@@ -1313,7 +1316,6 @@
 	if (!parse_options ((char *) data, sb, &journal_inum, NULL, 0))
 		goto failed_mount;
 
-	sb->s_flags |= MS_ONE_SECOND;
 	sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
 		((sbi->s_mount_opt & EXT3_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0);
 
@@ -1607,6 +1609,7 @@
 	percpu_counter_mod(&sbi->s_dirs_counter,
 		ext3_count_dirs(sb));
 
+	lock_kernel();
 	return 0;
 
 cantfind_ext3:
@@ -1631,6 +1634,7 @@
 out_fail:
 	sb->s_fs_info = NULL;
 	kfree(sbi);
+	lock_kernel();
 	return -EINVAL;
 }
 
@@ -1999,7 +2003,7 @@
  * This implicitly triggers the writebehind on sync().
  */
 
-void ext3_write_super (struct super_block * sb)
+static void ext3_write_super (struct super_block * sb)
 {
 	if (down_trylock(&sb->s_lock) == 0)
 		BUG();
@@ -2022,7 +2026,7 @@
  * LVM calls this function before a (read-only) snapshot is created.  This
  * gives us a chance to flush the journal completely and mark the fs clean.
  */
-void ext3_write_super_lockfs(struct super_block *sb)
+static void ext3_write_super_lockfs(struct super_block *sb)
 {
 	sb->s_dirt = 0;
 
@@ -2043,7 +2047,7 @@
  * Called by LVM after the snapshot is done.  We need to reset the RECOVER
  * flag here, even though the filesystem is not technically dirty yet.
  */
-void ext3_unlockfs(struct super_block *sb)
+static void ext3_unlockfs(struct super_block *sb)
 {
 	if (!(sb->s_flags & MS_RDONLY)) {
 		lock_super(sb);
@@ -2055,7 +2059,7 @@
 	}
 }
 
-int ext3_remount (struct super_block * sb, int * flags, char * data)
+static int ext3_remount (struct super_block * sb, int * flags, char * data)
 {
 	struct ext3_super_block * es;
 	struct ext3_sb_info *sbi = EXT3_SB(sb);
@@ -2127,7 +2131,7 @@
 	return 0;
 }
 
-int ext3_statfs (struct super_block * sb, struct kstatfs * buf)
+static int ext3_statfs (struct super_block * sb, struct kstatfs * buf)
 {
 	struct ext3_super_block *es = EXT3_SB(sb)->s_es;
 	unsigned long overhead;
@@ -2155,9 +2159,11 @@
 		 * block group descriptors.  If the sparse superblocks
 		 * feature is turned on, then not all groups have this.
 		 */
-		for (i = 0; i < ngroups; i++)
+		for (i = 0; i < ngroups; i++) {
 			overhead += ext3_bg_has_super(sb, i) +
 				ext3_bg_num_gdb(sb, i);
+			cond_resched();
+		}
 
 		/*
 		 * Every block group has an inode bitmap, a block
@@ -2193,7 +2199,7 @@
 
 static inline struct inode *dquot_to_inode(struct dquot *dquot)
 {
-	return sb_dqopt(dquot->dq_sb)->files[dquot->dq_type]->f_dentry->d_inode;
+	return sb_dqopt(dquot->dq_sb)->files[dquot->dq_type];
 }
 
 static int ext3_dquot_initialize(struct inode *inode, int type)
@@ -2232,8 +2238,10 @@
 {
 	int ret, err;
 	handle_t *handle;
+	struct inode *inode;
 
-	handle = ext3_journal_start(dquot_to_inode(dquot),
+	inode = dquot_to_inode(dquot);
+	handle = ext3_journal_start(inode,
 					EXT3_QUOTA_TRANS_BLOCKS);
 	if (IS_ERR(handle))
 		return PTR_ERR(handle);
@@ -2320,22 +2328,9 @@
 	if (IS_ERR(dentry))
 		return PTR_ERR(dentry);
 	err = vfs_quota_on_mount(type, EXT3_SB(sb)->s_jquota_fmt, dentry);
-	if (err)
-		dput(dentry);
-	/* We keep the dentry reference if everything went ok - we drop it
-	 * on quota_off time */
-	return err;
-}
-
-/* Turn quotas off during mount time */
-static int ext3_quota_off_mount(struct super_block *sb, int type)
-{
-	int err;
-	struct dentry *dentry;
-
-	dentry = sb_dqopt(sb)->files[type]->f_dentry;
-	err = vfs_quota_off_mount(sb, type);
-	/* We invalidate dentry - it has at least wrong hash... */
+	/* 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;
@@ -2358,18 +2353,119 @@
 	if (err)
 		return err;
 	/* Quotafile not on the same filesystem? */
-	if (nd.mnt->mnt_sb != sb)
+	if (nd.mnt->mnt_sb != sb) {
+		path_release(&nd);
 		return -EXDEV;
+	}
 	/* Quotafile not of fs root? */
 	if (nd.dentry->d_parent->d_inode != sb->s_root->d_inode)
 		printk(KERN_WARNING
 			"EXT3-fs: Quota file not on filesystem root. "
 			"Journalled quota will not work.\n");
-	if (!ext3_should_journal_data(nd.dentry->d_inode))
-		printk(KERN_WARNING "EXT3-fs: Quota file does not have "
-			"data-journalling. Journalled quota will not work.\n");
 	path_release(&nd);
 	return vfs_quota_on(sb, type, format_id, path);
+}
+
+/* Read data from quotafile - avoid pagecache and such because we cannot afford
+ * acquiring the locks... As quota files are never truncated and quota code
+ * itself serializes the operations (and noone else should touch the files)
+ * we don't have to be afraid of races */
+static ssize_t ext3_quota_read(struct super_block *sb, int type, char *data,
+			       size_t len, loff_t off)
+{
+	struct inode *inode = sb_dqopt(sb)->files[type];
+	sector_t blk = off >> EXT3_BLOCK_SIZE_BITS(sb);
+	int err = 0;
+	int offset = off & (sb->s_blocksize - 1);
+	int tocopy;
+	size_t toread;
+	struct buffer_head *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;
+		bh = ext3_bread(NULL, inode, blk, 0, &err);
+		if (err)
+			return err;
+		if (!bh)	/* A hole? */
+			memset(data, 0, tocopy);
+		else
+			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
+ * enough credits) */
+static ssize_t ext3_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];
+	sector_t blk = off >> EXT3_BLOCK_SIZE_BITS(sb);
+	int err = 0;
+	int offset = off & (sb->s_blocksize - 1);
+	int tocopy;
+	int journal_quota = EXT3_SB(sb)->s_qf_names[type] != NULL;
+	size_t towrite = len;
+	struct buffer_head *bh;
+	handle_t *handle = journal_current_handle();
+
+	down(&inode->i_sem);
+	while (towrite > 0) {
+		tocopy = sb->s_blocksize - offset < towrite ?
+				sb->s_blocksize - offset : towrite;
+		bh = ext3_bread(handle, inode, blk, 1, &err);
+		if (!bh)
+			goto out;
+		if (journal_quota) {
+			err = ext3_journal_get_write_access(handle, bh);
+			if (err) {
+				brelse(bh);
+				goto out;
+			}
+		}
+		lock_buffer(bh);
+		memcpy(bh->b_data+offset, data, tocopy);
+		flush_dcache_page(bh->b_page);
+		unlock_buffer(bh);
+		if (journal_quota)
+			err = ext3_journal_dirty_metadata(handle, bh);
+		else {
+			/* Always do at least ordered writes for quotas */
+			err = ext3_journal_dirty_data(handle, bh);
+			mark_buffer_dirty(bh);
+		}
+		brelse(bh);
+		if (err)
+			goto out;
+		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);
+		EXT3_I(inode)->i_disksize = inode->i_size;
+	}
+	inode->i_version++;
+	inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+	ext3_mark_inode_dirty(handle, inode);
+	up(&inode->i_sem);
+	return len - towrite;
 }
 
 #endif
diff -Nru a/fs/ext3/xattr.c b/fs/ext3/xattr.c
--- a/fs/ext3/xattr.c	2005-03-01 23:38:58 -08:00
+++ b/fs/ext3/xattr.c	2005-03-01 23:38:58 -08:00
@@ -9,22 +9,25 @@
  *  suggestion of Luka Renko <luka.renko@hermes.si>.
  * xattr consolidation Copyright (c) 2004 James Morris <jmorris@redhat.com>,
  *  Red Hat Inc.
+ * ea-in-inode support by Alex Tomas <alex@clusterfs.com> aka bzzz
+ *  and Andreas Gruenbacher <agruen@suse.de>.
  */
 
 /*
- * Extended attributes are stored on disk blocks allocated outside of
- * any inode. The i_file_acl field is then made to point to this allocated
- * block. If all extended attributes of an inode are identical, these
- * inodes may share the same extended attribute block. Such situations
- * are automatically detected by keeping a cache of recent attribute block
- * numbers and hashes over the block's contents in memory.
+ * Extended attributes are stored directly in inodes (on file systems with
+ * inodes bigger than 128 bytes) and on additional disk blocks. The i_file_acl
+ * field contains the block number if an inode uses an additional block. All
+ * attributes must fit in the inode and one additional block. Blocks that
+ * contain the identical set of attributes may be shared among several inodes.
+ * Identical blocks are detected by keeping a cache of blocks that have
+ * recently been accessed.
  *
- *
- * Extended attribute block layout:
+ * The attributes in inodes and on blocks have a different header; the entries
+ * are stored in the same format:
  *
  *   +------------------+
  *   | header           |
- *   ¦ entry 1          | |
+ *   | entry 1          | |
  *   | entry 2          | | growing downwards
  *   | entry 3          | v
  *   | four null bytes  |
@@ -34,23 +37,17 @@
  *   | value 2          | |
  *   +------------------+
  *
- * The block header is followed by multiple entry descriptors. These entry
- * descriptors are variable in size, and alligned to EXT3_XATTR_PAD
- * byte boundaries. The entry descriptors are sorted by attribute name,
- * so that two extended attribute blocks can be compared efficiently.
- *
- * Attribute values are aligned to the end of the block, stored in
- * no specific order. They are also padded to EXT3_XATTR_PAD byte
- * boundaries. No additional gaps are left between them.
+ * The header is followed by multiple entry descriptors. In disk blocks, the
+ * entry descriptors are kept sorted. In inodes, they are unsorted. The
+ * attribute values are aligned to the end of the block in no specific order.
  *
  * Locking strategy
  * ----------------
  * EXT3_I(inode)->i_file_acl is protected by EXT3_I(inode)->xattr_sem.
  * EA blocks are only changed if they are exclusive to an inode, so
  * holding xattr_sem also means that nothing but the EA block's reference
- * count will change. Multiple writers to an EA block are synchronized
- * by the bh lock. No more than a single bh lock is held at any time
- * to avoid deadlocks.
+ * count can change. Multiple writers to the same block are synchronized
+ * by the buffer lock.
  */
 
 #include <linux/init.h>
@@ -64,11 +61,18 @@
 #include "xattr.h"
 #include "acl.h"
 
-#define HDR(bh) ((struct ext3_xattr_header *)((bh)->b_data))
+#define BHDR(bh) ((struct ext3_xattr_header *)((bh)->b_data))
 #define ENTRY(ptr) ((struct ext3_xattr_entry *)(ptr))
-#define FIRST_ENTRY(bh) ENTRY(HDR(bh)+1)
+#define BFIRST(bh) ENTRY(BHDR(bh)+1)
 #define IS_LAST_ENTRY(entry) (*(__u32 *)(entry) == 0)
 
+#define IHDR(inode, raw_inode) \
+	((struct ext3_xattr_ibody_header *) \
+		((void *)raw_inode + \
+		 EXT3_GOOD_OLD_INODE_SIZE + \
+		 EXT3_I(inode)->i_extra_isize))
+#define IFIRST(hdr) ((struct ext3_xattr_entry *)((hdr)+1))
+
 #ifdef EXT3_XATTR_DEBUG
 # define ea_idebug(inode, f...) do { \
 		printk(KERN_DEBUG "inode %s:%ld: ", \
@@ -89,21 +93,16 @@
 # define ea_bdebug(f...)
 #endif
 
-static int ext3_xattr_set_handle2(handle_t *, struct inode *,
-				  struct buffer_head *,
-				  struct ext3_xattr_header *);
-
-static int ext3_xattr_cache_insert(struct buffer_head *);
-static struct buffer_head *ext3_xattr_cache_find(handle_t *, struct inode *,
+static void ext3_xattr_cache_insert(struct buffer_head *);
+static struct buffer_head *ext3_xattr_cache_find(struct inode *,
 						 struct ext3_xattr_header *,
-						 int *);
-static void ext3_xattr_cache_remove(struct buffer_head *);
+						 struct mb_cache_entry **);
 static void ext3_xattr_rehash(struct ext3_xattr_header *,
 			      struct ext3_xattr_entry *);
 
 static struct mb_cache *ext3_xattr_cache;
 
-static struct xattr_handler *ext3_xattr_handler_map[EXT3_XATTR_INDEX_MAX] = {
+static struct xattr_handler *ext3_xattr_handler_map[] = {
 	[EXT3_XATTR_INDEX_USER]		     = &ext3_xattr_user_handler,
 #ifdef CONFIG_EXT3_FS_POSIX_ACL
 	[EXT3_XATTR_INDEX_POSIX_ACL_ACCESS]  = &ext3_xattr_acl_access_handler,
@@ -133,7 +132,7 @@
 {
 	struct xattr_handler *handler = NULL;
 
-	if (name_index > 0 && name_index <= EXT3_XATTR_INDEX_MAX)
+	if (name_index > 0 && name_index < ARRAY_SIZE(ext3_xattr_handler_map))
 		handler = ext3_xattr_handler_map[name_index];
 	return handler;
 }
@@ -149,113 +148,165 @@
 	return ext3_xattr_list(dentry->d_inode, buffer, size);
 }
 
-/*
- * ext3_xattr_get()
- *
- * Copy an extended attribute into the buffer
- * provided, or compute the buffer size required.
- * Buffer is NULL to compute the size of the buffer required.
- *
- * Returns a negative error number on failure, or the number of bytes
- * used / required on success.
- */
+static int
+ext3_xattr_check_names(struct ext3_xattr_entry *entry, void *end)
+{
+	while (!IS_LAST_ENTRY(entry)) {
+		struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(entry);
+		if ((void *)next >= end)
+			return -EIO;
+		entry = next;
+	}
+	return 0;
+}
+
+static inline int
+ext3_xattr_check_block(struct buffer_head *bh)
+{
+	int error;
+
+	if (BHDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
+	    BHDR(bh)->h_blocks != cpu_to_le32(1))
+		return -EIO;
+	error = ext3_xattr_check_names(BFIRST(bh), bh->b_data + bh->b_size);
+	return error;
+}
+
+static inline int
+ext3_xattr_check_entry(struct ext3_xattr_entry *entry, size_t size)
+{
+	size_t value_size = le32_to_cpu(entry->e_value_size);
+
+	if (entry->e_value_block != 0 || value_size > size ||
+	    le16_to_cpu(entry->e_value_offs) + value_size > size)
+		return -EIO;
+	return 0;
+}
+
+static int
+ext3_xattr_find_entry(struct ext3_xattr_entry **pentry, int name_index,
+		      const char *name, size_t size, int sorted)
+{
+	struct ext3_xattr_entry *entry;
+	size_t name_len;
+	int cmp = 1;
+
+	if (name == NULL)
+		return -EINVAL;
+	name_len = strlen(name);
+	entry = *pentry;
+	for (; !IS_LAST_ENTRY(entry); entry = EXT3_XATTR_NEXT(entry)) {
+		cmp = name_index - entry->e_name_index;
+		if (!cmp)
+			cmp = name_len - entry->e_name_len;
+		if (!cmp)
+			cmp = memcmp(name, entry->e_name, name_len);
+		if (cmp <= 0 && (sorted || cmp == 0))
+			break;
+	}
+	*pentry = entry;
+	if (!cmp && ext3_xattr_check_entry(entry, size))
+			return -EIO;
+	return cmp ? -ENODATA : 0;
+}
+
 int
-ext3_xattr_get(struct inode *inode, int name_index, const char *name,
-	       void *buffer, size_t buffer_size)
+ext3_xattr_block_get(struct inode *inode, int name_index, const char *name,
+		     void *buffer, size_t buffer_size)
 {
 	struct buffer_head *bh = NULL;
 	struct ext3_xattr_entry *entry;
-	size_t name_len, size;
-	char *end;
+	size_t size;
 	int error;
 
 	ea_idebug(inode, "name=%d.%s, buffer=%p, buffer_size=%ld",
 		  name_index, name, buffer, (long)buffer_size);
 
-	if (name == NULL)
-		return -EINVAL;
-	down_read(&EXT3_I(inode)->xattr_sem);
 	error = -ENODATA;
 	if (!EXT3_I(inode)->i_file_acl)
 		goto cleanup;
 	ea_idebug(inode, "reading block %d", EXT3_I(inode)->i_file_acl);
 	bh = sb_bread(inode->i_sb, EXT3_I(inode)->i_file_acl);
-	error = -EIO;
 	if (!bh)
 		goto cleanup;
 	ea_bdebug(bh, "b_count=%d, refcount=%d",
-		atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount));
-	end = bh->b_data + bh->b_size;
-	if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
-	    HDR(bh)->h_blocks != cpu_to_le32(1)) {
-bad_block:	ext3_error(inode->i_sb, "ext3_xattr_get",
-			"inode %ld: bad block %d", inode->i_ino,
-			EXT3_I(inode)->i_file_acl);
+		atomic_read(&(bh->b_count)), le32_to_cpu(BHDR(bh)->h_refcount));
+	if (ext3_xattr_check_block(bh)) {
+bad_block:	ext3_error(inode->i_sb, __FUNCTION__,
+			   "inode %ld: bad block %d", inode->i_ino,
+			   EXT3_I(inode)->i_file_acl);
 		error = -EIO;
 		goto cleanup;
 	}
-	/* find named attribute */
-	name_len = strlen(name);
-
-	error = -ERANGE;
-	if (name_len > 255)
-		goto cleanup;
-	entry = FIRST_ENTRY(bh);
-	while (!IS_LAST_ENTRY(entry)) {
-		struct ext3_xattr_entry *next =
-			EXT3_XATTR_NEXT(entry);
-		if ((char *)next >= end)
-			goto bad_block;
-		if (name_index == entry->e_name_index &&
-		    name_len == entry->e_name_len &&
-		    memcmp(name, entry->e_name, name_len) == 0)
-			goto found;
-		entry = next;
-	}
-	/* Check the remaining name entries */
-	while (!IS_LAST_ENTRY(entry)) {
-		struct ext3_xattr_entry *next =
-			EXT3_XATTR_NEXT(entry);
-		if ((char *)next >= end)
-			goto bad_block;
-		entry = next;
-	}
-	if (ext3_xattr_cache_insert(bh))
-		ea_idebug(inode, "cache insert failed");
-	error = -ENODATA;
-	goto cleanup;
-found:
-	/* check the buffer size */
-	if (entry->e_value_block != 0)
+	ext3_xattr_cache_insert(bh);
+	entry = BFIRST(bh);
+	error = ext3_xattr_find_entry(&entry, name_index, name, bh->b_size, 1);
+	if (error == -EIO)
 		goto bad_block;
+	if (error)
+		goto cleanup;
 	size = le32_to_cpu(entry->e_value_size);
-	if (size > inode->i_sb->s_blocksize ||
-	    le16_to_cpu(entry->e_value_offs) + size > inode->i_sb->s_blocksize)
-		goto bad_block;
-
-	if (ext3_xattr_cache_insert(bh))
-		ea_idebug(inode, "cache insert failed");
 	if (buffer) {
 		error = -ERANGE;
 		if (size > buffer_size)
 			goto cleanup;
-		/* return value of attribute */
 		memcpy(buffer, bh->b_data + le16_to_cpu(entry->e_value_offs),
-			size);
+		       size);
 	}
 	error = size;
 
 cleanup:
 	brelse(bh);
-	up_read(&EXT3_I(inode)->xattr_sem);
+	return error;
+}
+
+static int
+ext3_xattr_ibody_get(struct inode *inode, int name_index, const char *name,
+		     void *buffer, size_t buffer_size)
+{
+	struct ext3_xattr_ibody_header *header;
+	struct ext3_xattr_entry *entry;
+	struct ext3_inode *raw_inode;
+	struct ext3_iloc iloc;
+	size_t size;
+	void *end;
+	int error;
+
+	if (!(EXT3_I(inode)->i_state & EXT3_STATE_XATTR))
+		return -ENODATA;
+	error = ext3_get_inode_loc(inode, &iloc);
+	if (error)
+		return error;
+	raw_inode = ext3_raw_inode(&iloc);
+	header = IHDR(inode, raw_inode);
+	entry = IFIRST(header);
+	end = (void *)raw_inode + EXT3_SB(inode->i_sb)->s_inode_size;
+	error = ext3_xattr_check_names(entry, end);
+	if (error)
+		goto cleanup;
+	error = ext3_xattr_find_entry(&entry, name_index, name,
+				      end - (void *)entry, 0);
+	if (error)
+		goto cleanup;
+	size = le32_to_cpu(entry->e_value_size);
+	if (buffer) {
+		error = -ERANGE;
+		if (size > buffer_size)
+			goto cleanup;
+		memcpy(buffer, (void *)IFIRST(header) +
+		       le16_to_cpu(entry->e_value_offs), size);
+	}
+	error = size;
 
+cleanup:
+	brelse(iloc.bh);
 	return error;
 }
 
 /*
- * ext3_xattr_list()
+ * ext3_xattr_get()
  *
- * Copy a list of attribute names into the buffer
+ * Copy an extended attribute into the buffer
  * provided, or compute the buffer size required.
  * Buffer is NULL to compute the size of the buffer required.
  *
@@ -263,18 +314,55 @@
  * used / required on success.
  */
 int
-ext3_xattr_list(struct inode *inode, char *buffer, size_t buffer_size)
+ext3_xattr_get(struct inode *inode, int name_index, const char *name,
+	       void *buffer, size_t buffer_size)
+{
+	int error;
+
+	down_read(&EXT3_I(inode)->xattr_sem);
+	error = ext3_xattr_ibody_get(inode, name_index, name, buffer,
+				     buffer_size);
+	if (error == -ENODATA)
+		error = ext3_xattr_block_get(inode, name_index, name, buffer,
+					     buffer_size);
+	up_read(&EXT3_I(inode)->xattr_sem);
+	return error;
+}
+
+static int
+ext3_xattr_list_entries(struct inode *inode, struct ext3_xattr_entry *entry,
+			char *buffer, size_t buffer_size)
 {
-	struct buffer_head *bh = NULL;
-	struct ext3_xattr_entry *entry;
-	char *end;
 	size_t rest = buffer_size;
+
+	for (; !IS_LAST_ENTRY(entry); entry = EXT3_XATTR_NEXT(entry)) {
+		struct xattr_handler *handler =
+			ext3_xattr_handler(entry->e_name_index);
+
+		if (handler) {
+			size_t size = handler->list(inode, buffer, rest,
+						    entry->e_name,
+						    entry->e_name_len);
+			if (buffer) {
+				if (size > rest)
+					return -ERANGE;
+				buffer += size;
+			}
+			rest -= size;
+		}
+	}
+	return buffer_size - rest;
+}
+
+int
+ext3_xattr_block_list(struct inode *inode, char *buffer, size_t buffer_size)
+{
+	struct buffer_head *bh = NULL;
 	int error;
 
 	ea_idebug(inode, "buffer=%p, buffer_size=%ld",
 		  buffer, (long)buffer_size);
 
-	down_read(&EXT3_I(inode)->xattr_sem);
 	error = 0;
 	if (!EXT3_I(inode)->i_file_acl)
 		goto cleanup;
@@ -284,59 +372,84 @@
 	if (!bh)
 		goto cleanup;
 	ea_bdebug(bh, "b_count=%d, refcount=%d",
-		atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount));
-	end = bh->b_data + bh->b_size;
-	if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
-	    HDR(bh)->h_blocks != cpu_to_le32(1)) {
-bad_block:	ext3_error(inode->i_sb, "ext3_xattr_list",
-			"inode %ld: bad block %d", inode->i_ino,
-			EXT3_I(inode)->i_file_acl);
+		atomic_read(&(bh->b_count)), le32_to_cpu(BHDR(bh)->h_refcount));
+	if (ext3_xattr_check_block(bh)) {
+		ext3_error(inode->i_sb, __FUNCTION__,
+			   "inode %ld: bad block %d", inode->i_ino,
+			   EXT3_I(inode)->i_file_acl);
 		error = -EIO;
 		goto cleanup;
 	}
+	ext3_xattr_cache_insert(bh);
+	error = ext3_xattr_list_entries(inode, BFIRST(bh), buffer, buffer_size);
 
-	/* check the on-disk data structure */
-	entry = FIRST_ENTRY(bh);
-	while (!IS_LAST_ENTRY(entry)) {
-		struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(entry);
+cleanup:
+	brelse(bh);
 
-		if ((char *)next >= end)
-			goto bad_block;
-		entry = next;
-	}
-	if (ext3_xattr_cache_insert(bh))
-		ea_idebug(inode, "cache insert failed");
+	return error;
+}
 
-	/* list the attribute names */
-	for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry);
-	     entry = EXT3_XATTR_NEXT(entry)) {
-		struct xattr_handler *handler =
-			ext3_xattr_handler(entry->e_name_index);
+static int
+ext3_xattr_ibody_list(struct inode *inode, char *buffer, size_t buffer_size)
+{
+	struct ext3_xattr_ibody_header *header;
+	struct ext3_inode *raw_inode;
+	struct ext3_iloc iloc;
+	void *end;
+	int error;
 
-		if (handler) {
-			size_t size = handler->list(inode, buffer, rest,
-						    entry->e_name,
-						    entry->e_name_len);
-			if (buffer) {
-				if (size > rest) {
-					error = -ERANGE;
-					goto cleanup;
-				}
-				buffer += size;
-			}
-			rest -= size;
-		}
-	}
-	error = buffer_size - rest;  /* total size */
+	if (!(EXT3_I(inode)->i_state & EXT3_STATE_XATTR))
+		return 0;
+	error = ext3_get_inode_loc(inode, &iloc);
+	if (error)
+		return error;
+	raw_inode = ext3_raw_inode(&iloc);
+	header = IHDR(inode, raw_inode);
+	end = (void *)raw_inode + EXT3_SB(inode->i_sb)->s_inode_size;
+	error = ext3_xattr_check_names(IFIRST(header), end);
+	if (error)
+		goto cleanup;
+	error = ext3_xattr_list_entries(inode, IFIRST(header),
+					buffer, buffer_size);
 
 cleanup:
-	brelse(bh);
-	up_read(&EXT3_I(inode)->xattr_sem);
-
+	brelse(iloc.bh);
 	return error;
 }
 
 /*
+ * ext3_xattr_list()
+ *
+ * Copy a list of attribute names into the buffer
+ * provided, or compute the buffer size required.
+ * Buffer is NULL to compute the size of the buffer required.
+ *
+ * Returns a negative error number on failure, or the number of bytes
+ * used / required on success.
+ */
+int
+ext3_xattr_list(struct inode *inode, char *buffer, size_t buffer_size)
+{
+	int i_error, b_error;
+
+	down_read(&EXT3_I(inode)->xattr_sem);
+	i_error = ext3_xattr_ibody_list(inode, buffer, buffer_size);
+	if (i_error < 0) {
+		b_error = 0;
+	} else {
+		if (buffer) {
+			buffer += i_error;
+			buffer_size -= i_error;
+		}
+		b_error = ext3_xattr_block_list(inode, buffer, buffer_size);
+		if (b_error < 0)
+			i_error = 0;
+	}
+	up_read(&EXT3_I(inode)->xattr_sem);
+	return i_error + b_error;
+}
+
+/*
  * If the EXT3_FEATURE_COMPAT_EXT_ATTR feature of this file system is
  * not set, set it.
  */
@@ -357,329 +470,326 @@
 }
 
 /*
- * ext3_xattr_set_handle()
- *
- * Create, replace or remove an extended attribute for this inode. Buffer
- * is NULL to remove an existing extended attribute, and non-NULL to
- * either replace an existing extended attribute, or create a new extended
- * attribute. The flags XATTR_REPLACE and XATTR_CREATE
- * specify that an extended attribute must exist and must not exist
- * previous to the call, respectively.
- *
- * Returns 0, or a negative error number on failure.
+ * Release the xattr block BH: If the reference count is > 1, decrement
+ * it; otherwise free the block.
  */
-int
-ext3_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index,
-		      const char *name, const void *value, size_t value_len,
-		      int flags)
+static void
+ext3_xattr_release_block(handle_t *handle, struct inode *inode,
+			 struct buffer_head *bh)
 {
-	struct super_block *sb = inode->i_sb;
-	struct buffer_head *bh = NULL;
-	struct ext3_xattr_header *header = NULL;
-	struct ext3_xattr_entry *here, *last;
-	size_t name_len, free, min_offs = sb->s_blocksize;
-	int not_found = 1, error;
-	char *end;
-
-	/*
-	 * header -- Points either into bh, or to a temporarily
-	 *           allocated buffer.
-	 * here -- The named entry found, or the place for inserting, within
-	 *         the block pointed to by header.
-	 * last -- Points right after the last named entry within the block
-	 *         pointed to by header.
-	 * min_offs -- The offset of the first value (values are aligned
-	 *             towards the end of the block).
-	 * end -- Points right after the block pointed to by header.
-	 */
-
-	ea_idebug(inode, "name=%d.%s, value=%p, value_len=%ld",
-		  name_index, name, value, (long)value_len);
-
-	if (IS_RDONLY(inode))
-		return -EROFS;
-	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
-		return -EPERM;
-	if (value == NULL)
-		value_len = 0;
-	if (name == NULL)
-		return -EINVAL;
-	name_len = strlen(name);
-	if (name_len > 255 || value_len > sb->s_blocksize)
-		return -ERANGE;
-	down_write(&EXT3_I(inode)->xattr_sem);
-	if (EXT3_I(inode)->i_file_acl) {
-		/* The inode already has an extended attribute block. */
-		bh = sb_bread(sb, EXT3_I(inode)->i_file_acl);
-		error = -EIO;
-		if (!bh)
-			goto cleanup;
-		ea_bdebug(bh, "b_count=%d, refcount=%d",
-			atomic_read(&(bh->b_count)),
-			le32_to_cpu(HDR(bh)->h_refcount));
-		header = HDR(bh);
-		end = bh->b_data + bh->b_size;
-		if (header->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
-		    header->h_blocks != cpu_to_le32(1)) {
-bad_block:		ext3_error(sb, "ext3_xattr_set",
-				"inode %ld: bad block %d", inode->i_ino,
-				EXT3_I(inode)->i_file_acl);
-			error = -EIO;
-			goto cleanup;
-		}
-		/* Find the named attribute. */
-		here = FIRST_ENTRY(bh);
-		while (!IS_LAST_ENTRY(here)) {
-			struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(here);
-			if ((char *)next >= end)
-				goto bad_block;
-			if (!here->e_value_block && here->e_value_size) {
-				size_t offs = le16_to_cpu(here->e_value_offs);
-				if (offs < min_offs)
-					min_offs = offs;
-			}
-			not_found = name_index - here->e_name_index;
-			if (!not_found)
-				not_found = name_len - here->e_name_len;
-			if (!not_found)
-				not_found = memcmp(name, here->e_name,name_len);
-			if (not_found <= 0)
-				break;
-			here = next;
-		}
-		last = here;
-		/* We still need to compute min_offs and last. */
-		while (!IS_LAST_ENTRY(last)) {
-			struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(last);
-			if ((char *)next >= end)
-				goto bad_block;
-			if (!last->e_value_block && last->e_value_size) {
-				size_t offs = le16_to_cpu(last->e_value_offs);
-				if (offs < min_offs)
-					min_offs = offs;
-			}
-			last = next;
-		}
-
-		/* Check whether we have enough space left. */
-		free = min_offs - ((char*)last - (char*)header) - sizeof(__u32);
-	} else {
-		/* We will use a new extended attribute block. */
-		free = sb->s_blocksize -
-			sizeof(struct ext3_xattr_header) - sizeof(__u32);
-		here = last = NULL;  /* avoid gcc uninitialized warning. */
-	}
+	struct mb_cache_entry *ce = NULL;
 
-	if (not_found) {
-		/* Request to remove a nonexistent attribute? */
-		error = -ENODATA;
-		if (flags & XATTR_REPLACE)
-			goto cleanup;
-		error = 0;
-		if (value == NULL)
-			goto cleanup;
+	ce = mb_cache_entry_get(ext3_xattr_cache, bh->b_bdev, bh->b_blocknr);
+	if (BHDR(bh)->h_refcount == cpu_to_le32(1)) {
+		ea_bdebug(bh, "refcount now=0; freeing");
+		if (ce)
+			mb_cache_entry_free(ce);
+		ext3_free_blocks(handle, inode, bh->b_blocknr, 1);
+		get_bh(bh);
+		ext3_forget(handle, 1, inode, bh, bh->b_blocknr);
 	} else {
-		/* Request to create an existing attribute? */
-		error = -EEXIST;
-		if (flags & XATTR_CREATE)
-			goto cleanup;
-		if (!here->e_value_block && here->e_value_size) {
-			size_t size = le32_to_cpu(here->e_value_size);
-
-			if (le16_to_cpu(here->e_value_offs) + size > 
-			    sb->s_blocksize || size > sb->s_blocksize)
-				goto bad_block;
-			free += EXT3_XATTR_SIZE(size);
+		if (ext3_journal_get_write_access(handle, bh) == 0) {
+			lock_buffer(bh);
+			BHDR(bh)->h_refcount = cpu_to_le32(
+				le32_to_cpu(BHDR(bh)->h_refcount) - 1);
+			ext3_journal_dirty_metadata(handle, bh);
+			if (IS_SYNC(inode))
+				handle->h_sync = 1;
+			DQUOT_FREE_BLOCK(inode, 1);
+			unlock_buffer(bh);
+			ea_bdebug(bh, "refcount now=%d; releasing",
+				  le32_to_cpu(BHDR(bh)->h_refcount));
 		}
-		free += EXT3_XATTR_LEN(name_len);
+		if (ce)
+			mb_cache_entry_release(ce);
 	}
-	error = -ENOSPC;
-	if (free < EXT3_XATTR_LEN(name_len) + EXT3_XATTR_SIZE(value_len))
-		goto cleanup;
+}
 
-	/* Here we know that we can set the new attribute. */
+struct ext3_xattr_info {
+	int name_index;
+	const char *name;
+	const void *value;
+	size_t value_len;
+};
 
-	if (header) {
-		int credits = 0;
+struct ext3_xattr_search {
+	struct ext3_xattr_entry *first;
+	void *base;
+	void *end;
+	struct ext3_xattr_entry *here;
+	int not_found;
+};
 
-		/* assert(header == HDR(bh)); */
-		if (header->h_refcount != cpu_to_le32(1))
-			goto skip_get_write_access;
-		/* ext3_journal_get_write_access() requires an unlocked bh,
-		   which complicates things here. */
-		error = ext3_journal_get_write_access_credits(handle, bh,
-							      &credits);
-		if (error)
-			goto cleanup;
-		lock_buffer(bh);
-		if (header->h_refcount == cpu_to_le32(1)) {
-			ea_bdebug(bh, "modifying in-place");
-			ext3_xattr_cache_remove(bh);
-			/* keep the buffer locked while modifying it. */
-		} else {
-			int offset;
+static int
+ext3_xattr_set_entry(struct ext3_xattr_info *i, struct ext3_xattr_search *s)
+{
+	struct ext3_xattr_entry *last;
+	size_t free, min_offs = s->end - s->base, name_len = strlen(i->name);
 
-			unlock_buffer(bh);
-			journal_release_buffer(handle, bh, credits);
-		skip_get_write_access:
-			ea_bdebug(bh, "cloning");
-			header = kmalloc(bh->b_size, GFP_KERNEL);
-			error = -ENOMEM;
-			if (header == NULL)
-				goto cleanup;
-			memcpy(header, HDR(bh), bh->b_size);
-			header->h_refcount = cpu_to_le32(1);
-			offset = (char *)here - bh->b_data;
-			here = ENTRY((char *)header + offset);
-			offset = (char *)last - bh->b_data;
-			last = ENTRY((char *)header + offset);
+	/* Compute min_offs and last. */
+	last = s->first;
+	for (; !IS_LAST_ENTRY(last); last = EXT3_XATTR_NEXT(last)) {
+		if (!last->e_value_block && last->e_value_size) {
+			size_t offs = le16_to_cpu(last->e_value_offs);
+			if (offs < min_offs)
+				min_offs = offs;
 		}
-	} else {
-		/* Allocate a buffer where we construct the new block. */
-		header = kmalloc(sb->s_blocksize, GFP_KERNEL);
-		error = -ENOMEM;
-		if (header == NULL)
-			goto cleanup;
-		memset(header, 0, sb->s_blocksize);
-		end = (char *)header + sb->s_blocksize;
-		header->h_magic = cpu_to_le32(EXT3_XATTR_MAGIC);
-		header->h_blocks = header->h_refcount = cpu_to_le32(1);
-		last = here = ENTRY(header+1);
+	}
+	free = min_offs - ((void *)last - s->base) - sizeof(__u32);
+	if (!s->not_found) {
+		if (!s->here->e_value_block && s->here->e_value_size) {
+			size_t size = le32_to_cpu(s->here->e_value_size);
+			free += EXT3_XATTR_SIZE(size);
+		}
+		free += EXT3_XATTR_LEN(name_len);
+	}
+	if (i->value) {
+		if (free < EXT3_XATTR_SIZE(i->value_len) ||
+		    free < EXT3_XATTR_LEN(name_len) +
+			   EXT3_XATTR_SIZE(i->value_len))
+			return -ENOSPC;
 	}
 
-	/* Iff we are modifying the block in-place, bh is locked here. */
-
-	if (not_found) {
+	if (i->value && s->not_found) {
 		/* Insert the new name. */
 		size_t size = EXT3_XATTR_LEN(name_len);
-		size_t rest = (char *)last - (char *)here;
-		memmove((char *)here + size, here, rest);
-		memset(here, 0, size);
-		here->e_name_index = name_index;
-		here->e_name_len = name_len;
-		memcpy(here->e_name, name, name_len);
+		size_t rest = (void *)last - (void *)s->here + sizeof(__u32);
+		memmove((void *)s->here + size, s->here, rest);
+		memset(s->here, 0, size);
+		s->here->e_name_index = i->name_index;
+		s->here->e_name_len = name_len;
+		memcpy(s->here->e_name, i->name, name_len);
 	} else {
-		if (!here->e_value_block && here->e_value_size) {
-			char *first_val = (char *)header + min_offs;
-			size_t offs = le16_to_cpu(here->e_value_offs);
-			char *val = (char *)header + offs;
+		if (!s->here->e_value_block && s->here->e_value_size) {
+			void *first_val = s->base + min_offs;
+			size_t offs = le16_to_cpu(s->here->e_value_offs);
+			void *val = s->base + offs;
 			size_t size = EXT3_XATTR_SIZE(
-				le32_to_cpu(here->e_value_size));
+				le32_to_cpu(s->here->e_value_size));
 
-			if (size == EXT3_XATTR_SIZE(value_len)) {
+			if (i->value && size == EXT3_XATTR_SIZE(i->value_len)) {
 				/* The old and the new value have the same
 				   size. Just replace. */
-				here->e_value_size = cpu_to_le32(value_len);
+				s->here->e_value_size =
+					cpu_to_le32(i->value_len);
 				memset(val + size - EXT3_XATTR_PAD, 0,
 				       EXT3_XATTR_PAD); /* Clear pad bytes. */
-				memcpy(val, value, value_len);
-				goto skip_replace;
+				memcpy(val, i->value, i->value_len);
+				return 0;
 			}
 
 			/* Remove the old value. */
 			memmove(first_val + size, first_val, val - first_val);
 			memset(first_val, 0, size);
-			here->e_value_offs = 0;
+			s->here->e_value_size = 0;
+			s->here->e_value_offs = 0;
 			min_offs += size;
 
 			/* Adjust all value offsets. */
-			last = ENTRY(header+1);
+			last = s->first;
 			while (!IS_LAST_ENTRY(last)) {
 				size_t o = le16_to_cpu(last->e_value_offs);
-				if (!last->e_value_block && o < offs)
+				if (!last->e_value_block &&
+				    last->e_value_size && o < offs)
 					last->e_value_offs =
 						cpu_to_le16(o + size);
 				last = EXT3_XATTR_NEXT(last);
 			}
 		}
-		if (value == NULL) {
+		if (!i->value) {
 			/* Remove the old name. */
 			size_t size = EXT3_XATTR_LEN(name_len);
-			last = ENTRY((char *)last - size);
-			memmove(here, (char*)here + size,
-				(char*)last - (char*)here);
+			last = ENTRY((void *)last - size);
+			memmove(s->here, (void *)s->here + size,
+				(void *)last - (void *)s->here + sizeof(__u32));
 			memset(last, 0, size);
 		}
 	}
 
-	if (value != NULL) {
+	if (i->value) {
 		/* Insert the new value. */
-		here->e_value_size = cpu_to_le32(value_len);
-		if (value_len) {
-			size_t size = EXT3_XATTR_SIZE(value_len);
-			char *val = (char *)header + min_offs - size;
-			here->e_value_offs =
-				cpu_to_le16((char *)val - (char *)header);
+		s->here->e_value_size = cpu_to_le32(i->value_len);
+		if (i->value_len) {
+			size_t size = EXT3_XATTR_SIZE(i->value_len);
+			void *val = s->base + min_offs - size;
+			s->here->e_value_offs = cpu_to_le16(min_offs - size);
 			memset(val + size - EXT3_XATTR_PAD, 0,
 			       EXT3_XATTR_PAD); /* Clear the pad bytes. */
-			memcpy(val, value, value_len);
+			memcpy(val, i->value, i->value_len);
 		}
 	}
+	return 0;
+}
 
-skip_replace:
-	if (IS_LAST_ENTRY(ENTRY(header+1))) {
-		/* This block is now empty. */
-		if (bh && header == HDR(bh))
-			unlock_buffer(bh);  /* we were modifying in-place. */
-		error = ext3_xattr_set_handle2(handle, inode, bh, NULL);
-	} else {
-		ext3_xattr_rehash(header, here);
-		if (bh && header == HDR(bh))
-			unlock_buffer(bh);  /* we were modifying in-place. */
-		error = ext3_xattr_set_handle2(handle, inode, bh, header);
+struct ext3_xattr_block_find {
+	struct ext3_xattr_search s;
+	struct buffer_head *bh;
+};
+
+int
+ext3_xattr_block_find(struct inode *inode, struct ext3_xattr_info *i,
+		      struct ext3_xattr_block_find *bs)
+{
+	struct super_block *sb = inode->i_sb;
+	int error;
+
+	ea_idebug(inode, "name=%d.%s, value=%p, value_len=%ld",
+		  i->name_index, i->name, i->value, (long)i->value_len);
+
+	if (EXT3_I(inode)->i_file_acl) {
+		/* The inode already has an extended attribute block. */
+		bs->bh = sb_bread(sb, EXT3_I(inode)->i_file_acl);
+		error = -EIO;
+		if (!bs->bh)
+			goto cleanup;
+		ea_bdebug(bs->bh, "b_count=%d, refcount=%d",
+			atomic_read(&(bs->bh->b_count)),
+			le32_to_cpu(BHDR(bs->bh)->h_refcount));
+		if (ext3_xattr_check_block(bs->bh)) {
+			ext3_error(sb, __FUNCTION__,
+				"inode %ld: bad block %d", inode->i_ino,
+				EXT3_I(inode)->i_file_acl);
+			error = -EIO;
+			goto cleanup;
+		}
+		/* Find the named attribute. */
+		bs->s.base = BHDR(bs->bh);
+		bs->s.first = BFIRST(bs->bh);
+		bs->s.end = bs->bh->b_data + bs->bh->b_size;
+		bs->s.here = bs->s.first;
+		error = ext3_xattr_find_entry(&bs->s.here, i->name_index,
+					      i->name, bs->bh->b_size, 1);
+		if (error && error != -ENODATA)
+			goto cleanup;
+		bs->s.not_found = error;
 	}
+	error = 0;
 
 cleanup:
-	brelse(bh);
-	if (!(bh && header == HDR(bh)))
-		kfree(header);
-	up_write(&EXT3_I(inode)->xattr_sem);
-
 	return error;
 }
 
-/*
- * Second half of ext3_xattr_set_handle(): Update the file system.
- */
 static int
-ext3_xattr_set_handle2(handle_t *handle, struct inode *inode,
-		       struct buffer_head *old_bh,
-		       struct ext3_xattr_header *header)
+ext3_xattr_block_set(handle_t *handle, struct inode *inode,
+		     struct ext3_xattr_info *i,
+		     struct ext3_xattr_block_find *bs)
 {
 	struct super_block *sb = inode->i_sb;
 	struct buffer_head *new_bh = NULL;
-	int credits = 0, error;
+	struct ext3_xattr_search *s = &bs->s;
+	struct mb_cache_entry *ce = NULL;
+	int error;
+
+#define header(x) ((struct ext3_xattr_header *)(x))
+
+	if (i->value && i->value_len > sb->s_blocksize)
+		return -ENOSPC;
+	if (s->base) {
+		ce = mb_cache_entry_get(ext3_xattr_cache, bs->bh->b_bdev,
+					bs->bh->b_blocknr);
+		if (header(s->base)->h_refcount == cpu_to_le32(1)) {
+			if (ce) {
+				mb_cache_entry_free(ce);
+				ce = NULL;
+			}
+			ea_bdebug(bs->bh, "modifying in-place");
+			error = ext3_journal_get_write_access(handle, bs->bh);
+			if (error)
+				goto cleanup;
+			lock_buffer(bs->bh);
+			error = ext3_xattr_set_entry(i, s);
+			if (!error) {
+				if (!IS_LAST_ENTRY(s->first))
+					ext3_xattr_rehash(header(s->base),
+							  s->here);
+				ext3_xattr_cache_insert(bs->bh);
+			}
+			unlock_buffer(bs->bh);
+			if (error == -EIO)
+				goto bad_block;
+			if (!error)
+				error = ext3_journal_dirty_metadata(handle,
+								    bs->bh);
+			if (error)
+				goto cleanup;
+			goto inserted;
+		} else {
+			int offset = (char *)s->here - bs->bh->b_data;
+
+			if (ce) {
+				mb_cache_entry_release(ce);
+				ce = NULL;
+			}
+			ea_bdebug(bs->bh, "cloning");
+			s->base = kmalloc(bs->bh->b_size, GFP_KERNEL);
+			error = -ENOMEM;
+			if (s->base == NULL)
+				goto cleanup;
+			memcpy(s->base, BHDR(bs->bh), bs->bh->b_size);
+			s->first = ENTRY(header(s->base)+1);
+			header(s->base)->h_refcount = cpu_to_le32(1);
+			s->here = ENTRY(s->base + offset);
+			s->end = s->base + bs->bh->b_size;
+		}
+	} else {
+		/* Allocate a buffer where we construct the new block. */
+		s->base = kmalloc(sb->s_blocksize, GFP_KERNEL);
+		/* assert(header == s->base) */
+		error = -ENOMEM;
+		if (s->base == NULL)
+			goto cleanup;
+		memset(s->base, 0, sb->s_blocksize);
+		header(s->base)->h_magic = cpu_to_le32(EXT3_XATTR_MAGIC);
+		header(s->base)->h_blocks = cpu_to_le32(1);
+		header(s->base)->h_refcount = cpu_to_le32(1);
+		s->first = ENTRY(header(s->base)+1);
+		s->here = ENTRY(header(s->base)+1);
+		s->end = s->base + sb->s_blocksize;
+	}
+
+	error = ext3_xattr_set_entry(i, s);
+	if (error == -EIO)
+		goto bad_block;
+	if (error)
+		goto cleanup;
+	if (!IS_LAST_ENTRY(s->first))
+		ext3_xattr_rehash(header(s->base), s->here);
 
-	if (header) {
-		new_bh = ext3_xattr_cache_find(handle, inode, header, &credits);
+inserted:
+	if (!IS_LAST_ENTRY(s->first)) {
+		new_bh = ext3_xattr_cache_find(inode, header(s->base), &ce);
 		if (new_bh) {
 			/* We found an identical block in the cache. */
-			if (new_bh == old_bh)
-				ea_bdebug(new_bh, "keeping this block");
+			if (new_bh == bs->bh)
+				ea_bdebug(new_bh, "keeping");
 			else {
 				/* The old block is released after updating
 				   the inode. */
-				ea_bdebug(new_bh, "reusing block");
-
 				error = -EDQUOT;
-				if (DQUOT_ALLOC_BLOCK(inode, 1)) {
-					unlock_buffer(new_bh);
-					journal_release_buffer(handle, new_bh,
-							       credits);
+				if (DQUOT_ALLOC_BLOCK(inode, 1))
 					goto cleanup;
-				}
-				HDR(new_bh)->h_refcount = cpu_to_le32(1 +
-					le32_to_cpu(HDR(new_bh)->h_refcount));
-				ea_bdebug(new_bh, "refcount now=%d",
-					le32_to_cpu(HDR(new_bh)->h_refcount));
+				error = ext3_journal_get_write_access(handle,
+								      new_bh);
+				if (error)
+					goto cleanup_dquot;
+				lock_buffer(new_bh);
+				BHDR(new_bh)->h_refcount = cpu_to_le32(1 +
+					le32_to_cpu(BHDR(new_bh)->h_refcount));
+				ea_bdebug(new_bh, "reusing; refcount now=%d",
+					le32_to_cpu(BHDR(new_bh)->h_refcount));
+				unlock_buffer(new_bh);
+				error = ext3_journal_dirty_metadata(handle,
+								    new_bh);
+				if (error)
+					goto cleanup_dquot;
 			}
-			unlock_buffer(new_bh);
-		} else if (old_bh && header == HDR(old_bh)) {
-			/* Keep this block. No need to lock the block as we
-			 * don't need to change the reference count. */
-			new_bh = old_bh;
+			mb_cache_entry_release(ce);
+			ce = NULL;
+		} else if (bs->bh && s->base == bs->bh->b_data) {
+			/* We were modifying this block in-place. */
+			ea_bdebug(bs->bh, "keeping this block");
+			new_bh = bs->bh;
 			get_bh(new_bh);
-			ext3_xattr_cache_insert(new_bh);
 		} else {
 			/* We need to allocate a new block */
 			int goal = le32_to_cpu(
@@ -704,60 +814,217 @@
 				unlock_buffer(new_bh);
 				goto getblk_failed;
 			}
-			memcpy(new_bh->b_data, header, new_bh->b_size);
+			memcpy(new_bh->b_data, s->base, new_bh->b_size);
 			set_buffer_uptodate(new_bh);
 			unlock_buffer(new_bh);
 			ext3_xattr_cache_insert(new_bh);
-
-			ext3_xattr_update_super_block(handle, sb);
+			error = ext3_journal_dirty_metadata(handle, new_bh);
+			if (error)
+				goto cleanup;
 		}
-		error = ext3_journal_dirty_metadata(handle, new_bh);
-		if (error)
-			goto cleanup;
 	}
 
 	/* Update the inode. */
 	EXT3_I(inode)->i_file_acl = new_bh ? new_bh->b_blocknr : 0;
-	inode->i_ctime = CURRENT_TIME;
-	ext3_mark_inode_dirty(handle, inode);
-	if (IS_SYNC(inode))
-		handle->h_sync = 1;
 
+	/* Drop the previous xattr block. */
+	if (bs->bh && bs->bh != new_bh)
+		ext3_xattr_release_block(handle, inode, bs->bh);
 	error = 0;
-	if (old_bh && old_bh != new_bh) {
-		/*
-		 * If there was an old block, and we are no longer using it,
-		 * release the old block.
-		*/
-		error = ext3_journal_get_write_access(handle, old_bh);
+
+cleanup:
+	if (ce)
+		mb_cache_entry_release(ce);
+	brelse(new_bh);
+	if (!(bs->bh && s->base == bs->bh->b_data))
+		kfree(s->base);
+
+	return error;
+
+cleanup_dquot:
+	DQUOT_FREE_BLOCK(inode, 1);
+	goto cleanup;
+
+bad_block:
+	ext3_error(inode->i_sb, __FUNCTION__,
+		   "inode %ld: bad block %d", inode->i_ino,
+		   EXT3_I(inode)->i_file_acl);
+	goto cleanup;
+
+#undef header
+}
+
+struct ext3_xattr_ibody_find {
+	struct ext3_xattr_search s;
+	struct ext3_iloc iloc;
+};
+
+int
+ext3_xattr_ibody_find(struct inode *inode, struct ext3_xattr_info *i,
+		      struct ext3_xattr_ibody_find *is)
+{
+	struct ext3_xattr_ibody_header *header;
+	struct ext3_inode *raw_inode;
+	int error;
+
+	if (EXT3_I(inode)->i_extra_isize == 0)
+		return 0;
+	raw_inode = ext3_raw_inode(&is->iloc);
+	header = IHDR(inode, raw_inode);
+	is->s.base = is->s.first = IFIRST(header);
+	is->s.here = is->s.first;
+	is->s.end = (void *)raw_inode + EXT3_SB(inode->i_sb)->s_inode_size;
+	if (EXT3_I(inode)->i_state & EXT3_STATE_XATTR) {
+		error = ext3_xattr_check_names(IFIRST(header), is->s.end);
 		if (error)
+			return error;
+		/* Find the named attribute. */
+		error = ext3_xattr_find_entry(&is->s.here, i->name_index,
+					      i->name, is->s.end -
+					      (void *)is->s.base, 0);
+		if (error && error != -ENODATA)
+			return error;
+		is->s.not_found = error;
+	}
+	return 0;
+}
+
+static int
+ext3_xattr_ibody_set(handle_t *handle, struct inode *inode,
+		     struct ext3_xattr_info *i,
+		     struct ext3_xattr_ibody_find *is)
+{
+	struct ext3_xattr_ibody_header *header;
+	struct ext3_xattr_search *s = &is->s;
+	int error;
+
+	if (EXT3_I(inode)->i_extra_isize == 0)
+		return -ENOSPC;
+	error = ext3_xattr_set_entry(i, s);
+	if (error)
+		return error;
+	header = IHDR(inode, ext3_raw_inode(&is->iloc));
+	if (!IS_LAST_ENTRY(s->first)) {
+		header->h_magic = cpu_to_le32(EXT3_XATTR_MAGIC);
+		EXT3_I(inode)->i_state |= EXT3_STATE_XATTR;
+	} else {
+		header->h_magic = cpu_to_le32(0);
+		EXT3_I(inode)->i_state &= ~EXT3_STATE_XATTR;
+	}
+	return 0;
+}
+
+/*
+ * ext3_xattr_set_handle()
+ *
+ * Create, replace or remove an extended attribute for this inode. Buffer
+ * is NULL to remove an existing extended attribute, and non-NULL to
+ * either replace an existing extended attribute, or create a new extended
+ * attribute. The flags XATTR_REPLACE and XATTR_CREATE
+ * specify that an extended attribute must exist and must not exist
+ * previous to the call, respectively.
+ *
+ * Returns 0, or a negative error number on failure.
+ */
+int
+ext3_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index,
+		      const char *name, const void *value, size_t value_len,
+		      int flags)
+{
+	struct ext3_xattr_info i = {
+		.name_index = name_index,
+		.name = name,
+		.value = value,
+		.value_len = value_len,
+
+	};
+	struct ext3_xattr_ibody_find is = {
+		.s = { .not_found = -ENODATA, },
+	};
+	struct ext3_xattr_block_find bs = {
+		.s = { .not_found = -ENODATA, },
+	};
+	int error;
+
+	if (IS_RDONLY(inode))
+		return -EROFS;
+	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
+		return -EPERM;
+	if (!name)
+		return -EINVAL;
+	if (strlen(name) > 255)
+		return -ERANGE;
+	down_write(&EXT3_I(inode)->xattr_sem);
+	error = ext3_get_inode_loc(inode, &is.iloc);
+	if (error)
+		goto cleanup;
+
+	if (EXT3_I(inode)->i_state & EXT3_STATE_NEW) {
+		struct ext3_inode *raw_inode = ext3_raw_inode(&is.iloc);
+		memset(raw_inode, 0, EXT3_SB(inode->i_sb)->s_inode_size);
+		EXT3_I(inode)->i_state &= ~EXT3_STATE_NEW;
+	}
+
+	error = ext3_xattr_ibody_find(inode, &i, &is);
+	if (error)
+		goto cleanup;
+	if (is.s.not_found)
+		error = ext3_xattr_block_find(inode, &i, &bs);
+	if (error)
+		goto cleanup;
+	if (is.s.not_found && bs.s.not_found) {
+		error = -ENODATA;
+		if (flags & XATTR_REPLACE)
 			goto cleanup;
-		lock_buffer(old_bh);
-		if (HDR(old_bh)->h_refcount == cpu_to_le32(1)) {
-			/* Free the old block. */
-			ea_bdebug(old_bh, "freeing");
-			ext3_free_blocks(handle, inode, old_bh->b_blocknr, 1);
-
-			/* ext3_forget() calls bforget() for us, but we
-			   let our caller release old_bh, so we need to
-			   duplicate the handle before. */
-			get_bh(old_bh);
-			ext3_forget(handle, 1, inode, old_bh,old_bh->b_blocknr);
-		} else {
-			/* Decrement the refcount only. */
-			HDR(old_bh)->h_refcount = cpu_to_le32(
-				le32_to_cpu(HDR(old_bh)->h_refcount) - 1);
-			DQUOT_FREE_BLOCK(inode, 1);
-			ext3_journal_dirty_metadata(handle, old_bh);
-			ea_bdebug(old_bh, "refcount now=%d",
-				le32_to_cpu(HDR(old_bh)->h_refcount));
+		error = 0;
+		if (!value)
+			goto cleanup;
+	} else {
+		error = -EEXIST;
+		if (flags & XATTR_CREATE)
+			goto cleanup;
+	}
+	error = ext3_journal_get_write_access(handle, is.iloc.bh);
+	if (error)
+		goto cleanup;
+	if (!value) {
+		if (!is.s.not_found)
+			error = ext3_xattr_ibody_set(handle, inode, &i, &is);
+		else if (!bs.s.not_found)
+			error = ext3_xattr_block_set(handle, inode, &i, &bs);
+	} else {
+		error = ext3_xattr_ibody_set(handle, inode, &i, &is);
+		if (!error && !bs.s.not_found) {
+			i.value = NULL;
+			error = ext3_xattr_block_set(handle, inode, &i, &bs);
+		} else if (error == -ENOSPC) {
+			error = ext3_xattr_block_set(handle, inode, &i, &bs);
+			if (error)
+				goto cleanup;
+			if (!is.s.not_found) {
+				i.value = NULL;
+				error = ext3_xattr_ibody_set(handle, inode, &i,
+							     &is);
+			}
 		}
-		unlock_buffer(old_bh);
+	}
+	if (!error) {
+		ext3_xattr_update_super_block(handle, inode->i_sb);
+		inode->i_ctime = CURRENT_TIME_SEC;
+		error = ext3_mark_iloc_dirty(handle, inode, &is.iloc);
+		/*
+		 * The bh is consumed by ext3_mark_iloc_dirty, even with
+		 * error != 0.
+		 */
+		is.iloc.bh = NULL;
+		if (IS_SYNC(inode))
+			handle->h_sync = 1;
 	}
 
 cleanup:
-	brelse(new_bh);
-
+	brelse(is.iloc.bh);
+	brelse(bs.bh);
+	up_write(&EXT3_I(inode)->xattr_sem);
 	return error;
 }
 
@@ -800,53 +1067,35 @@
  * ext3_xattr_delete_inode()
  *
  * Free extended attribute resources associated with this inode. This
- * is called immediately before an inode is freed.
+ * is called immediately before an inode is freed. We have exclusive
+ * access to the inode.
  */
 void
 ext3_xattr_delete_inode(handle_t *handle, struct inode *inode)
 {
 	struct buffer_head *bh = NULL;
 
-	down_write(&EXT3_I(inode)->xattr_sem);
 	if (!EXT3_I(inode)->i_file_acl)
 		goto cleanup;
 	bh = sb_bread(inode->i_sb, EXT3_I(inode)->i_file_acl);
 	if (!bh) {
-		ext3_error(inode->i_sb, "ext3_xattr_delete_inode",
+		ext3_error(inode->i_sb, __FUNCTION__,
 			"inode %ld: block %d read error", inode->i_ino,
 			EXT3_I(inode)->i_file_acl);
 		goto cleanup;
 	}
-	if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
-	    HDR(bh)->h_blocks != cpu_to_le32(1)) {
-		ext3_error(inode->i_sb, "ext3_xattr_delete_inode",
+	if (BHDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
+	    BHDR(bh)->h_blocks != cpu_to_le32(1)) {
+		ext3_error(inode->i_sb, __FUNCTION__,
 			"inode %ld: bad block %d", inode->i_ino,
 			EXT3_I(inode)->i_file_acl);
 		goto cleanup;
 	}
-	if (ext3_journal_get_write_access(handle, bh) != 0)
-		goto cleanup;
-	lock_buffer(bh);
-	if (HDR(bh)->h_refcount == cpu_to_le32(1)) {
-		ext3_xattr_cache_remove(bh);
-		ext3_free_blocks(handle, inode, EXT3_I(inode)->i_file_acl, 1);
-		get_bh(bh);
-		ext3_forget(handle, 1, inode, bh, EXT3_I(inode)->i_file_acl);
-	} else {
-		HDR(bh)->h_refcount = cpu_to_le32(
-			le32_to_cpu(HDR(bh)->h_refcount) - 1);
-		ext3_journal_dirty_metadata(handle, bh);
-		if (IS_SYNC(inode))
-			handle->h_sync = 1;
-		DQUOT_FREE_BLOCK(inode, 1);
-	}
-	ea_bdebug(bh, "refcount now=%d", le32_to_cpu(HDR(bh)->h_refcount) - 1);
-	unlock_buffer(bh);
+	ext3_xattr_release_block(handle, inode, bh);
 	EXT3_I(inode)->i_file_acl = 0;
 
 cleanup:
 	brelse(bh);
-	up_write(&EXT3_I(inode)->xattr_sem);
 }
 
 /*
@@ -868,30 +1117,29 @@
  *
  * Returns 0, or a negative error number on failure.
  */
-static int
+static void
 ext3_xattr_cache_insert(struct buffer_head *bh)
 {
-	__u32 hash = le32_to_cpu(HDR(bh)->h_hash);
+	__u32 hash = le32_to_cpu(BHDR(bh)->h_hash);
 	struct mb_cache_entry *ce;
 	int error;
 
 	ce = mb_cache_entry_alloc(ext3_xattr_cache);
-	if (!ce)
-		return -ENOMEM;
+	if (!ce) {
+		ea_bdebug(bh, "out of memory");
+		return;
+	}
 	error = mb_cache_entry_insert(ce, bh->b_bdev, bh->b_blocknr, &hash);
 	if (error) {
 		mb_cache_entry_free(ce);
 		if (error == -EBUSY) {
-			ea_bdebug(bh, "already in cache (%d cache entries)",
-				atomic_read(&ext3_xattr_cache->c_entry_count));
+			ea_bdebug(bh, "already in cache");
 			error = 0;
 		}
 	} else {
-		ea_bdebug(bh, "inserting [%x] (%d cache entries)", (int)hash,
-			  atomic_read(&ext3_xattr_cache->c_entry_count));
+		ea_bdebug(bh, "inserting [%x]", (int)hash);
 		mb_cache_entry_release(ce);
 	}
-	return error;
 }
 
 /*
@@ -914,6 +1162,7 @@
 		if (IS_LAST_ENTRY(entry2))
 			return 1;
 		if (entry1->e_hash != entry2->e_hash ||
+		    entry1->e_name_index != entry2->e_name_index ||
 		    entry1->e_name_len != entry2->e_name_len ||
 		    entry1->e_value_size != entry2->e_value_size ||
 		    memcmp(entry1->e_name, entry2->e_name, entry1->e_name_len))
@@ -942,8 +1191,8 @@
  * not found or an error occurred.
  */
 static struct buffer_head *
-ext3_xattr_cache_find(handle_t *handle, struct inode *inode,
-		      struct ext3_xattr_header *header, int *credits)
+ext3_xattr_cache_find(struct inode *inode, struct ext3_xattr_header *header,
+		      struct mb_cache_entry **pce)
 {
 	__u32 hash = le32_to_cpu(header->h_hash);
 	struct mb_cache_entry *ce;
@@ -951,62 +1200,38 @@
 	if (!header->h_hash)
 		return NULL;  /* never share */
 	ea_idebug(inode, "looking for cached blocks [%x]", (int)hash);
+again:
 	ce = mb_cache_entry_find_first(ext3_xattr_cache, 0,
 				       inode->i_sb->s_bdev, hash);
 	while (ce) {
-		struct buffer_head *bh = sb_bread(inode->i_sb, ce->e_block);
+		struct buffer_head *bh;
 
+		if (IS_ERR(ce)) {
+			if (PTR_ERR(ce) == -EAGAIN)
+				goto again;
+			break;
+		}
+		bh = sb_bread(inode->i_sb, ce->e_block);
 		if (!bh) {
-			ext3_error(inode->i_sb, "ext3_xattr_cache_find",
+			ext3_error(inode->i_sb, __FUNCTION__,
 				"inode %ld: block %ld read error",
 				inode->i_ino, (unsigned long) ce->e_block);
-		} else if (ext3_journal_get_write_access_credits(
-				handle, bh, credits) == 0) {
-			/* ext3_journal_get_write_access() requires an unlocked
-			 * bh, which complicates things here. */
-			lock_buffer(bh);
-			if (le32_to_cpu(HDR(bh)->h_refcount) >
-				   EXT3_XATTR_REFCOUNT_MAX) {
-				ea_idebug(inode, "block %ld refcount %d>%d",
-					  (unsigned long) ce->e_block,
-					  le32_to_cpu(HDR(bh)->h_refcount),
+		} else if (le32_to_cpu(BHDR(bh)->h_refcount) >=
+				EXT3_XATTR_REFCOUNT_MAX) {
+			ea_idebug(inode, "block %ld refcount %d>=%d",
+				  (unsigned long) ce->e_block,
+				  le32_to_cpu(BHDR(bh)->h_refcount),
 					  EXT3_XATTR_REFCOUNT_MAX);
-			} else if (!ext3_xattr_cmp(header, HDR(bh))) {
-				mb_cache_entry_release(ce);
-				/* buffer will be unlocked by caller */
-				return bh;
-			}
-			unlock_buffer(bh);
-			journal_release_buffer(handle, bh, *credits);
-			*credits = 0;
-			brelse(bh);
+		} else if (ext3_xattr_cmp(header, BHDR(bh)) == 0) {
+			*pce = ce;
+			return bh;
 		}
+		brelse(bh);
 		ce = mb_cache_entry_find_next(ce, 0, inode->i_sb->s_bdev, hash);
 	}
 	return NULL;
 }
 
-/*
- * ext3_xattr_cache_remove()
- *
- * Remove the cache entry of a block from the cache. Called when a
- * block becomes invalid.
- */
-static void
-ext3_xattr_cache_remove(struct buffer_head *bh)
-{
-	struct mb_cache_entry *ce;
-
-	ce = mb_cache_entry_get(ext3_xattr_cache, bh->b_bdev,
-				bh->b_blocknr);
-	if (ce) {
-		ea_bdebug(bh, "removing (%d cache entries remaining)",
-			  atomic_read(&ext3_xattr_cache->c_entry_count)-1);
-		mb_cache_entry_free(ce);
-	} else 
-		ea_bdebug(bh, "no cache entry");
-}
-
 #define NAME_HASH_SHIFT 5
 #define VALUE_HASH_SHIFT 16
 
@@ -1080,7 +1305,7 @@
 {
 	ext3_xattr_cache = mb_cache_create("ext3_xattr", NULL,
 		sizeof(struct mb_cache_entry) +
-		sizeof(struct mb_cache_entry_index), 1, 6);
+		sizeof(((struct mb_cache_entry *) 0)->e_indexes[0]), 1, 6);
 	if (!ext3_xattr_cache)
 		return -ENOMEM;
 	return 0;
diff -Nru a/fs/ext3/xattr.h b/fs/ext3/xattr.h
--- a/fs/ext3/xattr.h	2005-03-01 23:39:16 -08:00
+++ b/fs/ext3/xattr.h	2005-03-01 23:39:16 -08:00
@@ -16,7 +16,6 @@
 #define EXT3_XATTR_REFCOUNT_MAX		1024
 
 /* Name indexes */
-#define EXT3_XATTR_INDEX_MAX			10
 #define EXT3_XATTR_INDEX_USER			1
 #define EXT3_XATTR_INDEX_POSIX_ACL_ACCESS	2
 #define EXT3_XATTR_INDEX_POSIX_ACL_DEFAULT	3
@@ -30,6 +29,10 @@
 	__le32	h_blocks;	/* number of disk blocks used */
 	__le32	h_hash;		/* hash value of all attributes */
 	__u32	h_reserved[4];	/* zero right now */
+};
+
+struct ext3_xattr_ibody_header {
+	__le32	h_magic;	/* magic number for identification */
 };
 
 struct ext3_xattr_entry {
diff -Nru a/fs/fat/Makefile b/fs/fat/Makefile
--- a/fs/fat/Makefile	2005-03-01 23:39:18 -08:00
+++ b/fs/fat/Makefile	2005-03-01 23:39:18 -08:00
@@ -4,4 +4,4 @@
 
 obj-$(CONFIG_FAT_FS) += fat.o
 
-fat-objs := cache.o dir.o file.o inode.o misc.o fatfs_syms.o
+fat-objs := cache.o dir.o file.o inode.o misc.o
diff -Nru a/fs/fat/cache.c b/fs/fat/cache.c
--- a/fs/fat/cache.c	2005-03-01 23:39:09 -08:00
+++ b/fs/fat/cache.c	2005-03-01 23:39:09 -08:00
@@ -203,7 +203,7 @@
 	spin_unlock(&MSDOS_I(inode)->cache_lru_lock);
 }
 
-int __fat_access(struct super_block *sb, int nr, int new_value)
+static int __fat_access(struct super_block *sb, int nr, int new_value)
 {
 	struct msdos_sb_info *sbi = MSDOS_SB(sb);
 	struct buffer_head *bh, *bh2, *c_bh, *c_bh2;
@@ -296,7 +296,7 @@
 	return next;
 }
 
-/* 
+/*
  * Returns the this'th FAT entry, -1 if it is an end-of-file entry. If
  * new_value is != -1, that FAT entry is replaced by it.
  */
@@ -305,7 +305,7 @@
 	int next;
 
 	next = -EIO;
-	if (nr < 2 || MSDOS_SB(sb)->clusters + 2 <= nr) {
+	if (nr < FAT_START_ENT || MSDOS_SB(sb)->max_cluster <= nr) {
 		fat_fs_panic(sb, "invalid access to FAT (entry 0x%08x)", nr);
 		goto out;
 	}
@@ -343,7 +343,7 @@
 	int nr;
 
 	BUG_ON(MSDOS_I(inode)->i_start == 0);
-	
+
 	*fclus = 0;
 	*dclus = MSDOS_I(inode)->i_start;
 	if (cluster == 0)
@@ -368,7 +368,7 @@
 
 		nr = fat_access(sb, *dclus, -1);
 		if (nr < 0)
- 			return nr;
+			return nr;
 		else if (nr == FAT_ENT_FREE) {
 			fat_fs_panic(sb, "%s: invalid cluster chain"
 				     " (i_pos %lld)", __FUNCTION__,
@@ -431,71 +431,7 @@
 	cluster = fat_bmap_cluster(inode, cluster);
 	if (cluster < 0)
 		return cluster;
-	else if (cluster) {
-		*phys = ((sector_t)cluster - 2) * sbi->sec_per_clus
-			+ sbi->data_start + offset;
-	}
+	else if (cluster)
+		*phys = fat_clus_to_blknr(sbi, cluster) + offset;
 	return 0;
-}
-
-/* Free all clusters after the skip'th cluster. */
-int fat_free(struct inode *inode, int skip)
-{
-	struct super_block *sb = inode->i_sb;
-	int nr, ret, fclus, dclus;
-
-	if (MSDOS_I(inode)->i_start == 0)
-		return 0;
-
-	if (skip) {
-		ret = fat_get_cluster(inode, skip - 1, &fclus, &dclus);
-		if (ret < 0)
-			return ret;
-		else if (ret == FAT_ENT_EOF)
-			return 0;
-
-		nr = fat_access(sb, dclus, -1);
-		if (nr == FAT_ENT_EOF)
-			return 0;
-		else if (nr > 0) {
-			/*
-			 * write a new EOF, and get the remaining cluster
-			 * chain for freeing.
-			 */
-			nr = fat_access(sb, dclus, FAT_ENT_EOF);
-		}
-		if (nr < 0)
-			return nr;
-
-		fat_cache_inval_inode(inode);
-	} else {
-		fat_cache_inval_inode(inode);
-
-		nr = MSDOS_I(inode)->i_start;
-		MSDOS_I(inode)->i_start = 0;
-		MSDOS_I(inode)->i_logstart = 0;
-		mark_inode_dirty(inode);
-	}
-
-	lock_fat(sb);
-	do {
-		nr = fat_access(sb, nr, FAT_ENT_FREE);
-		if (nr < 0)
-			goto error;
-		else if (nr == FAT_ENT_FREE) {
-			fat_fs_panic(sb, "%s: deleting beyond EOF (i_pos %lld)",
-				     __FUNCTION__, MSDOS_I(inode)->i_pos);
-			nr = -EIO;
-			goto error;
-		}
-		if (MSDOS_SB(sb)->free_clusters != -1)
-			MSDOS_SB(sb)->free_clusters++;
-		inode->i_blocks -= MSDOS_SB(sb)->cluster_size >> 9;
-	} while (nr != FAT_ENT_EOF);
-	fat_clusters_flush(sb);
-	nr = 0;
-error:
-	unlock_fat(sb);
-
-	return nr;
 }
diff -Nru a/fs/fat/dir.c b/fs/fat/dir.c
--- a/fs/fat/dir.c	2005-03-01 23:38:52 -08:00
+++ b/fs/fat/dir.c	2005-03-01 23:38:52 -08:00
@@ -13,26 +13,15 @@
  *  Short name translation 1999, 2001 by Wolfram Pienkoss <wp@bszh.de>
  */
 
+#include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/time.h>
 #include <linux/msdos_fs.h>
 #include <linux/dirent.h>
 #include <linux/smp_lock.h>
 #include <linux/buffer_head.h>
-
 #include <asm/uaccess.h>
 
-static int fat_dir_ioctl(struct inode * inode, struct file * filp,
-		  unsigned int cmd, unsigned long arg);
-static int fat_readdir(struct file *filp, void *dirent, filldir_t filldir);
-
-struct file_operations fat_dir_operations = {
-	.read		= generic_read_dir,
-	.readdir	= fat_readdir,
-	.ioctl		= fat_dir_ioctl,
-	.fsync		= file_fsync,
-};
-
 /*
  * Convert Unicode 16 to UTF8, translated Unicode, or ASCII.
  * If uni_xlate is enabled and we can't get a 1:1 conversion, use a
@@ -43,9 +32,8 @@
  * but ignore that right now.
  * Ahem... Stack smashing in ring 0 isn't fun. Fixed.
  */
-static int
-uni16_to_x8(unsigned char *ascii, wchar_t *uni, int uni_xlate,
-	    struct nls_table *nls)
+static int uni16_to_x8(unsigned char *ascii, wchar_t *uni, int uni_xlate,
+		       struct nls_table *nls)
 {
 	wchar_t *ip, ec;
 	unsigned char *op, nc;
@@ -83,20 +71,6 @@
 	return (op - ascii);
 }
 
-#if 0
-static void dump_de(struct msdos_dir_entry *de)
-{
-	int i;
-	unsigned char *p = (unsigned char *) de;
-	printk("[");
-
-	for (i = 0; i < 32; i++, p++) {
-		printk("%02x ", *p);
-	}
-	printk("]\n");
-}
-#endif
-
 static inline int
 fat_short2uni(struct nls_table *t, unsigned char *c, int clen, wchar_t *uni)
 {
@@ -122,17 +96,17 @@
 		charlen = 1;
 	} else if (charlen <= 1) {
 		unsigned char nc = t->charset2lower[*c];
-		
+
 		if (!nc)
 			nc = *c;
-		
+
 		if ( (charlen = t->char2uni(&nc, 1, uni)) < 0) {
 			*uni = 0x003f;	/* a question mark */
 			charlen = 1;
 		}
 	} else
 		*uni = wc;
-	
+
 	return charlen;
 }
 
@@ -149,7 +123,7 @@
 	else if (opt & VFAT_SFN_DISPLAY_WINNT) {
 		if (lower)
 			len = fat_short2lower_uni(nls, buf, buf_size, uni_buf);
-		else 
+		else
 			len = fat_short2uni(nls, buf, buf_size, uni_buf);
 	} else
 		len = fat_short2uni(nls, buf, buf_size, uni_buf);
@@ -325,6 +299,8 @@
 	return res;
 }
 
+EXPORT_SYMBOL(fat_search_long);
+
 struct fat_ioctl_filldir_callback {
 	struct dirent __user *dirent;
 	int result;
@@ -359,7 +335,7 @@
 	int chi, chl, i, i2, j, last, last_u, dotoffset = 0;
 	loff_t i_pos, cpos;
 	int ret = 0;
-	
+
 	lock_kernel();
 
 	cpos = filp->f_pos;
@@ -382,7 +358,7 @@
 		goto out;
 	}
 
- 	bh = NULL;
+	bh = NULL;
 GetNew:
 	long_slots = 0;
 	if (fat_get_entry(inode,&cpos,&bh,&de,&i_pos) == -1)
@@ -691,6 +667,132 @@
 	return ret;
 }
 
+struct file_operations fat_dir_operations = {
+	.read		= generic_read_dir,
+	.readdir	= fat_readdir,
+	.ioctl		= fat_dir_ioctl,
+	.fsync		= file_fsync,
+};
+
+static int fat_get_short_entry(struct inode *dir, loff_t *pos,
+			       struct buffer_head **bh,
+			       struct msdos_dir_entry **de, loff_t *i_pos)
+{
+	while (fat_get_entry(dir, pos, bh, de, i_pos) >= 0) {
+		/* free entry or long name entry or volume label */
+		if (!IS_FREE((*de)->name) && !((*de)->attr & ATTR_VOLUME))
+			return 0;
+	}
+	return -ENOENT;
+}
+
+/* See if directory is empty */
+int fat_dir_empty(struct inode *dir)
+{
+	struct buffer_head *bh;
+	struct msdos_dir_entry *de;
+	loff_t cpos, i_pos;
+	int result = 0;
+
+	bh = NULL;
+	cpos = 0;
+	while (fat_get_short_entry(dir, &cpos, &bh, &de, &i_pos) >= 0) {
+		if (strncmp(de->name, MSDOS_DOT   , MSDOS_NAME) &&
+		    strncmp(de->name, MSDOS_DOTDOT, MSDOS_NAME)) {
+			result = -ENOTEMPTY;
+			break;
+		}
+	}
+	brelse(bh);
+	return result;
+}
+
+EXPORT_SYMBOL(fat_dir_empty);
+
+/*
+ * fat_subdirs counts the number of sub-directories of dir. It can be run
+ * on directories being created.
+ */
+int fat_subdirs(struct inode *dir)
+{
+	struct buffer_head *bh;
+	struct msdos_dir_entry *de;
+	loff_t cpos, i_pos;
+	int count = 0;
+
+	bh = NULL;
+	cpos = 0;
+	while (fat_get_short_entry(dir, &cpos, &bh, &de, &i_pos) >= 0) {
+		if (de->attr & ATTR_DIR)
+			count++;
+	}
+	brelse(bh);
+	return count;
+}
+
+/*
+ * Scans a directory for a given file (name points to its formatted name).
+ * Returns an error code or zero.
+ */
+int fat_scan(struct inode *dir, const unsigned char *name,
+	     struct buffer_head **bh, struct msdos_dir_entry **de,
+	     loff_t *i_pos)
+{
+	loff_t cpos;
+
+	*bh = NULL;
+	cpos = 0;
+	while (fat_get_short_entry(dir, &cpos, bh, de, i_pos) >= 0) {
+		if (!strncmp((*de)->name, name, MSDOS_NAME))
+			return 0;
+	}
+	return -ENOENT;
+}
+
+EXPORT_SYMBOL(fat_scan);
+
+static struct buffer_head *fat_extend_dir(struct inode *inode)
+{
+	struct super_block *sb = inode->i_sb;
+	struct buffer_head *bh, *res = NULL;
+	int nr, sec_per_clus = MSDOS_SB(sb)->sec_per_clus;
+	sector_t sector, last_sector;
+
+	if (MSDOS_SB(sb)->fat_bits != 32) {
+		if (inode->i_ino == MSDOS_ROOT_INO)
+			return ERR_PTR(-ENOSPC);
+	}
+
+	nr = fat_add_cluster(inode);
+	if (nr < 0)
+		return ERR_PTR(nr);
+
+	sector = fat_clus_to_blknr(MSDOS_SB(sb), nr);
+	last_sector = sector + sec_per_clus;
+	for ( ; sector < last_sector; sector++) {
+		if ((bh = sb_getblk(sb, sector))) {
+			memset(bh->b_data, 0, sb->s_blocksize);
+			set_buffer_uptodate(bh);
+			mark_buffer_dirty(bh);
+			if (!res)
+				res = bh;
+			else
+				brelse(bh);
+		}
+	}
+	if (res == NULL)
+		res = ERR_PTR(-EIO);
+	if (inode->i_size & (sb->s_blocksize - 1)) {
+		fat_fs_panic(sb, "Odd directory size");
+		inode->i_size = (inode->i_size + sb->s_blocksize)
+			& ~((loff_t)sb->s_blocksize - 1);
+	}
+	inode->i_size += MSDOS_SB(sb)->cluster_size;
+	MSDOS_I(inode)->mmu_private += MSDOS_SB(sb)->cluster_size;
+
+	return res;
+}
+
 /* This assumes that size of cluster is above the 32*slots */
 
 int fat_add_entries(struct inode *dir,int slots, struct buffer_head **bh,
@@ -719,7 +821,7 @@
 			offset = curr;
 		}
 	}
-	if ((dir->i_ino == MSDOS_ROOT_INO) && (MSDOS_SB(sb)->fat_bits != 32)) 
+	if ((dir->i_ino == MSDOS_ROOT_INO) && (MSDOS_SB(sb)->fat_bits != 32))
 		return -ENOSPC;
 	new_bh = fat_extend_dir(dir);
 	if (IS_ERR(new_bh))
@@ -732,6 +834,8 @@
 	return offset;
 }
 
+EXPORT_SYMBOL(fat_add_entries);
+
 int fat_new_dir(struct inode *dir, struct inode *parent, int is_vfat)
 {
 	struct buffer_head *bh;
@@ -761,81 +865,10 @@
 	de[1].starthi = cpu_to_le16(MSDOS_I(parent)->i_logstart>>16);
 	mark_buffer_dirty(bh);
 	brelse(bh);
-	dir->i_atime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+	dir->i_atime = dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
 	mark_inode_dirty(dir);
 
 	return 0;
 }
 
-static int fat_get_short_entry(struct inode *dir, loff_t *pos,
-			       struct buffer_head **bh,
-			       struct msdos_dir_entry **de, loff_t *i_pos)
-{
-	while (fat_get_entry(dir, pos, bh, de, i_pos) >= 0) {
-		/* free entry or long name entry or volume label */
-		if (!IS_FREE((*de)->name) && !((*de)->attr & ATTR_VOLUME))
-			return 0;
-	}
-	return -ENOENT;
-}
-
-/* See if directory is empty */
-int fat_dir_empty(struct inode *dir)
-{
-	struct buffer_head *bh;
-	struct msdos_dir_entry *de;
-	loff_t cpos, i_pos;
-	int result = 0;
-
-	bh = NULL;
-	cpos = 0;
-	while (fat_get_short_entry(dir, &cpos, &bh, &de, &i_pos) >= 0) {
-		if (strncmp(de->name, MSDOS_DOT   , MSDOS_NAME) &&
-		    strncmp(de->name, MSDOS_DOTDOT, MSDOS_NAME)) {
-			result = -ENOTEMPTY;
-			break;
-		}
-	}
-	brelse(bh);
-	return result;
-}
-
-/*
- * fat_subdirs counts the number of sub-directories of dir. It can be run
- * on directories being created.
- */
-int fat_subdirs(struct inode *dir)
-{
-	struct buffer_head *bh;
-	struct msdos_dir_entry *de;
-	loff_t cpos, i_pos;
-	int count = 0;
-
-	bh = NULL;
-	cpos = 0;
-	while (fat_get_short_entry(dir, &cpos, &bh, &de, &i_pos) >= 0) {
-		if (de->attr & ATTR_DIR)
-			count++;
-	}
-	brelse(bh);
-	return count;
-}
-
-/*
- * Scans a directory for a given file (name points to its formatted name).
- * Returns an error code or zero.
- */
-int fat_scan(struct inode *dir, const unsigned char *name,
-	     struct buffer_head **bh, struct msdos_dir_entry **de,
-	     loff_t *i_pos)
-{
-	loff_t cpos;
-
-	*bh = NULL;
-	cpos = 0;
-	while (fat_get_short_entry(dir, &cpos, bh, de, i_pos) >= 0) {
-		if (!strncmp((*de)->name, name, MSDOS_NAME))
-			return 0;
-	}
-	return -ENOENT;
-}
+EXPORT_SYMBOL(fat_new_dir);
diff -Nru a/fs/fat/fatfs_syms.c b/fs/fat/fatfs_syms.c
--- a/fs/fat/fatfs_syms.c	2005-03-01 23:38:53 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,48 +0,0 @@
-/*
- * linux/fs/fat/fatfs_syms.c
- *
- * Exported kernel symbols for the low-level FAT-based fs support.
- *
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-
-#include <linux/mm.h>
-#include <linux/msdos_fs.h>
-
-EXPORT_SYMBOL(fat_new_dir);
-EXPORT_SYMBOL(fat_date_unix2dos);
-EXPORT_SYMBOL(fat__get_entry);
-EXPORT_SYMBOL(fat_notify_change);
-EXPORT_SYMBOL(fat_attach);
-EXPORT_SYMBOL(fat_detach);
-EXPORT_SYMBOL(fat_build_inode);
-EXPORT_SYMBOL(fat_fill_super);
-EXPORT_SYMBOL(fat_search_long);
-EXPORT_SYMBOL(fat_scan);
-EXPORT_SYMBOL(fat_add_entries);
-EXPORT_SYMBOL(fat_dir_empty);
-
-int __init fat_cache_init(void);
-void __exit fat_cache_destroy(void);
-int __init fat_init_inodecache(void);
-void __exit fat_destroy_inodecache(void);
-static int __init init_fat_fs(void)
-{
-	int ret;
-
-	ret = fat_cache_init();
-	if (ret < 0)
-		return ret;
-	return fat_init_inodecache();
-}
-
-static void __exit exit_fat_fs(void)
-{
-	fat_cache_destroy();
-	fat_destroy_inodecache();
-}
-
-module_init(init_fat_fs)
-module_exit(exit_fat_fs)
diff -Nru a/fs/fat/file.c b/fs/fat/file.c
--- a/fs/fat/file.c	2005-03-01 23:38:54 -08:00
+++ b/fs/fat/file.c	2005-03-01 23:38:54 -08:00
@@ -6,13 +6,26 @@
  *  regular file handling primitives for fat-based filesystems
  */
 
+#include <linux/module.h>
 #include <linux/time.h>
 #include <linux/msdos_fs.h>
 #include <linux/smp_lock.h>
 #include <linux/buffer_head.h>
 
 static ssize_t fat_file_write(struct file *filp, const char __user *buf,
-			      size_t count, loff_t *ppos);
+			      size_t count, loff_t *ppos)
+{
+	struct inode *inode = filp->f_dentry->d_inode;
+	int retval;
+
+	retval = generic_file_write(filp, buf, count, ppos);
+	if (retval > 0) {
+		inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC;
+		MSDOS_I(inode)->i_attrs |= ATTR_ARCH;
+		mark_inode_dirty(inode);
+	}
+	return retval;
+}
 
 struct file_operations fat_file_operations = {
 	.llseek		= generic_file_llseek,
@@ -25,63 +38,117 @@
 	.sendfile	= generic_file_sendfile,
 };
 
-struct inode_operations fat_file_inode_operations = {
-	.truncate	= fat_truncate,
-	.setattr	= fat_notify_change,
-};
-
-int fat_get_block(struct inode *inode, sector_t iblock,
-		  struct buffer_head *bh_result, int create)
+int fat_notify_change(struct dentry *dentry, struct iattr *attr)
 {
-	struct super_block *sb = inode->i_sb;
-	sector_t phys;
-	int err;
+	struct msdos_sb_info *sbi = MSDOS_SB(dentry->d_sb);
+	struct inode *inode = dentry->d_inode;
+	int mask, error = 0;
 
-	err = fat_bmap(inode, iblock, &phys);
-	if (err)
-		return err;
-	if (phys) {
-		map_bh(bh_result, sb, phys);
-		return 0;
-	}
-	if (!create)
-		return 0;
-	if (iblock != MSDOS_I(inode)->mmu_private >> sb->s_blocksize_bits) {
-		fat_fs_panic(sb, "corrupted file size (i_pos %lld, %lld)",
-			     MSDOS_I(inode)->i_pos, MSDOS_I(inode)->mmu_private);
-		return -EIO;
+	lock_kernel();
+
+	/* FAT cannot truncate to a longer file */
+	if (attr->ia_valid & ATTR_SIZE) {
+		if (attr->ia_size > inode->i_size) {
+			error = -EPERM;
+			goto out;
+		}
 	}
-	if (!((unsigned long)iblock & (MSDOS_SB(sb)->sec_per_clus - 1))) {
-		int error;
 
-		error = fat_add_cluster(inode);
-		if (error < 0)
-			return error;
+	error = inode_change_ok(inode, attr);
+	if (error) {
+		if (sbi->options.quiet)
+			error = 0;
+		goto out;
+	}
+	if (((attr->ia_valid & ATTR_UID) &&
+	     (attr->ia_uid != sbi->options.fs_uid)) ||
+	    ((attr->ia_valid & ATTR_GID) &&
+	     (attr->ia_gid != sbi->options.fs_gid)) ||
+	    ((attr->ia_valid & ATTR_MODE) &&
+	     (attr->ia_mode & ~MSDOS_VALID_MODE)))
+		error = -EPERM;
+
+	if (error) {
+		if (sbi->options.quiet)
+			error = 0;
+		goto out;
 	}
-	MSDOS_I(inode)->mmu_private += sb->s_blocksize;
-	err = fat_bmap(inode, iblock, &phys);
-	if (err)
-		return err;
-	if (!phys)
-		BUG();
-	set_buffer_new(bh_result);
-	map_bh(bh_result, sb, phys);
-	return 0;
+	error = inode_setattr(inode, attr);
+	if (error)
+		goto out;
+
+	if (S_ISDIR(inode->i_mode))
+		mask = sbi->options.fs_dmask;
+	else
+		mask = sbi->options.fs_fmask;
+	inode->i_mode &= S_IFMT | (S_IRWXUGO & ~mask);
+out:
+	unlock_kernel();
+	return error;
 }
 
-static ssize_t fat_file_write(struct file *filp, const char __user *buf,
-			      size_t count, loff_t *ppos)
+EXPORT_SYMBOL(fat_notify_change);
+
+/* Free all clusters after the skip'th cluster. */
+static int fat_free(struct inode *inode, int skip)
 {
-	struct inode *inode = filp->f_dentry->d_inode;
-	int retval;
+	struct super_block *sb = inode->i_sb;
+	int nr, ret, fclus, dclus;
 
-	retval = generic_file_write(filp, buf, count, ppos);
-	if (retval > 0) {
-		inode->i_mtime = inode->i_ctime = CURRENT_TIME;
-		MSDOS_I(inode)->i_attrs |= ATTR_ARCH;
+	if (MSDOS_I(inode)->i_start == 0)
+		return 0;
+
+	if (skip) {
+		ret = fat_get_cluster(inode, skip - 1, &fclus, &dclus);
+		if (ret < 0)
+			return ret;
+		else if (ret == FAT_ENT_EOF)
+			return 0;
+
+		nr = fat_access(sb, dclus, -1);
+		if (nr == FAT_ENT_EOF)
+			return 0;
+		else if (nr > 0) {
+			/*
+			 * write a new EOF, and get the remaining cluster
+			 * chain for freeing.
+			 */
+			nr = fat_access(sb, dclus, FAT_ENT_EOF);
+		}
+		if (nr < 0)
+			return nr;
+
+		fat_cache_inval_inode(inode);
+	} else {
+		fat_cache_inval_inode(inode);
+
+		nr = MSDOS_I(inode)->i_start;
+		MSDOS_I(inode)->i_start = 0;
+		MSDOS_I(inode)->i_logstart = 0;
 		mark_inode_dirty(inode);
 	}
-	return retval;
+
+	lock_fat(sb);
+	do {
+		nr = fat_access(sb, nr, FAT_ENT_FREE);
+		if (nr < 0)
+			goto error;
+		else if (nr == FAT_ENT_FREE) {
+			fat_fs_panic(sb, "%s: deleting beyond EOF (i_pos %lld)",
+				     __FUNCTION__, MSDOS_I(inode)->i_pos);
+			nr = -EIO;
+			goto error;
+		}
+		if (MSDOS_SB(sb)->free_clusters != -1)
+			MSDOS_SB(sb)->free_clusters++;
+		inode->i_blocks -= MSDOS_SB(sb)->cluster_size >> 9;
+	} while (nr != FAT_ENT_EOF);
+	fat_clusters_flush(sb);
+	nr = 0;
+error:
+	unlock_fat(sb);
+
+	return nr;
 }
 
 void fat_truncate(struct inode *inode)
@@ -90,7 +157,7 @@
 	const unsigned int cluster_size = sbi->cluster_size;
 	int nr_clusters;
 
-	/* 
+	/*
 	 * This protects against truncating a file bigger than it was then
 	 * trying to write into the hole.
 	 */
@@ -103,6 +170,11 @@
 	fat_free(inode, nr_clusters);
 	MSDOS_I(inode)->i_attrs |= ATTR_ARCH;
 	unlock_kernel();
-	inode->i_ctime = inode->i_mtime = CURRENT_TIME;
+	inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC;
 	mark_inode_dirty(inode);
 }
+
+struct inode_operations fat_file_inode_operations = {
+	.truncate	= fat_truncate,
+	.setattr	= fat_notify_change,
+};
diff -Nru a/fs/fat/inode.c b/fs/fat/inode.c
--- a/fs/fat/inode.c	2005-03-01 23:38:56 -08:00
+++ b/fs/fat/inode.c	2005-03-01 23:38:56 -08:00
@@ -7,10 +7,11 @@
  *
  *  Fixes:
  *
- *  	Max Cohan: Fixed invalid FSINFO offset when info_sector is 0
+ *	Max Cohan: Fixed invalid FSINFO offset when info_sector is 0
  */
 
 #include <linux/module.h>
+#include <linux/init.h>
 #include <linux/time.h>
 #include <linux/slab.h>
 #include <linux/smp_lock.h>
@@ -31,8 +32,76 @@
 static int fat_default_codepage = CONFIG_FAT_DEFAULT_CODEPAGE;
 static char fat_default_iocharset[] = CONFIG_FAT_DEFAULT_IOCHARSET;
 
-static int fat_statfs(struct super_block *sb, struct kstatfs *buf);
-static int fat_write_inode(struct inode *inode, int wait);
+
+static int fat_get_block(struct inode *inode, sector_t iblock,
+			 struct buffer_head *bh_result, int create)
+{
+	struct super_block *sb = inode->i_sb;
+	sector_t phys;
+	int err;
+
+	err = fat_bmap(inode, iblock, &phys);
+	if (err)
+		return err;
+	if (phys) {
+		map_bh(bh_result, sb, phys);
+		return 0;
+	}
+	if (!create)
+		return 0;
+	if (iblock != MSDOS_I(inode)->mmu_private >> sb->s_blocksize_bits) {
+		fat_fs_panic(sb, "corrupted file size (i_pos %lld, %lld)",
+			     MSDOS_I(inode)->i_pos, MSDOS_I(inode)->mmu_private);
+		return -EIO;
+	}
+	if (!((unsigned long)iblock & (MSDOS_SB(sb)->sec_per_clus - 1))) {
+		int error;
+
+		error = fat_add_cluster(inode);
+		if (error < 0)
+			return error;
+	}
+	MSDOS_I(inode)->mmu_private += sb->s_blocksize;
+	err = fat_bmap(inode, iblock, &phys);
+	if (err)
+		return err;
+	if (!phys)
+		BUG();
+	set_buffer_new(bh_result);
+	map_bh(bh_result, sb, phys);
+	return 0;
+}
+
+static int fat_writepage(struct page *page, struct writeback_control *wbc)
+{
+	return block_write_full_page(page, fat_get_block, wbc);
+}
+
+static int fat_readpage(struct file *file, struct page *page)
+{
+	return block_read_full_page(page, fat_get_block);
+}
+
+static int fat_prepare_write(struct file *file, struct page *page,
+			     unsigned from, unsigned to)
+{
+	return cont_prepare_write(page, from, to, fat_get_block,
+				  &MSDOS_I(page->mapping->host)->mmu_private);
+}
+
+static sector_t _fat_bmap(struct address_space *mapping, sector_t block)
+{
+	return generic_block_bmap(mapping, block, fat_get_block);
+}
+
+static struct address_space_operations fat_aops = {
+	.readpage	= fat_readpage,
+	.writepage	= fat_writepage,
+	.sync_page	= block_sync_page,
+	.prepare_write	= fat_prepare_write,
+	.commit_write	= generic_commit_write,
+	.bmap		= _fat_bmap
+};
 
 /*
  * New FAT inode stuff. We do the following:
@@ -87,6 +156,8 @@
 	spin_unlock(&sbi->inode_hash_lock);
 }
 
+EXPORT_SYMBOL(fat_attach);
+
 void fat_detach(struct inode *inode)
 {
 	struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
@@ -96,6 +167,8 @@
 	spin_unlock(&sbi->inode_hash_lock);
 }
 
+EXPORT_SYMBOL(fat_detach);
+
 struct inode *fat_iget(struct super_block *sb, loff_t i_pos)
 {
 	struct msdos_sb_info *sbi = MSDOS_SB(sb);
@@ -117,7 +190,102 @@
 	return inode;
 }
 
-static int fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de);
+static int is_exec(unsigned char *extension)
+{
+	unsigned char *exe_extensions = "EXECOMBAT", *walk;
+
+	for (walk = exe_extensions; *walk; walk += 3)
+		if (!strncmp(extension, walk, 3))
+			return 1;
+	return 0;
+}
+
+static int fat_calc_dir_size(struct inode *inode)
+{
+	struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
+	int ret, fclus, dclus;
+
+	inode->i_size = 0;
+	if (MSDOS_I(inode)->i_start == 0)
+		return 0;
+
+	ret = fat_get_cluster(inode, FAT_ENT_EOF, &fclus, &dclus);
+	if (ret < 0)
+		return ret;
+	inode->i_size = (fclus + 1) << sbi->cluster_bits;
+
+	return 0;
+}
+
+/* doesn't deal with root inode */
+static int fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de)
+{
+	struct super_block *sb = inode->i_sb;
+	struct msdos_sb_info *sbi = MSDOS_SB(sb);
+	int error;
+
+	MSDOS_I(inode)->i_pos = 0;
+	inode->i_uid = sbi->options.fs_uid;
+	inode->i_gid = sbi->options.fs_gid;
+	inode->i_version++;
+	inode->i_generation = get_seconds();
+
+	if ((de->attr & ATTR_DIR) && !IS_FREE(de->name)) {
+		inode->i_generation &= ~1;
+		inode->i_mode = MSDOS_MKMODE(de->attr,
+			S_IRWXUGO & ~sbi->options.fs_dmask) | S_IFDIR;
+		inode->i_op = sbi->dir_ops;
+		inode->i_fop = &fat_dir_operations;
+
+		MSDOS_I(inode)->i_start = le16_to_cpu(de->start);
+		if (sbi->fat_bits == 32)
+			MSDOS_I(inode)->i_start |= (le16_to_cpu(de->starthi) << 16);
+
+		MSDOS_I(inode)->i_logstart = MSDOS_I(inode)->i_start;
+		error = fat_calc_dir_size(inode);
+		if (error < 0)
+			return error;
+		MSDOS_I(inode)->mmu_private = inode->i_size;
+
+		inode->i_nlink = fat_subdirs(inode);
+	} else { /* not a directory */
+		inode->i_generation |= 1;
+		inode->i_mode = MSDOS_MKMODE(de->attr,
+		    ((sbi->options.showexec &&
+			!is_exec(de->ext))
+			? S_IRUGO|S_IWUGO : S_IRWXUGO)
+		    & ~sbi->options.fs_fmask) | S_IFREG;
+		MSDOS_I(inode)->i_start = le16_to_cpu(de->start);
+		if (sbi->fat_bits == 32)
+			MSDOS_I(inode)->i_start |= (le16_to_cpu(de->starthi) << 16);
+
+		MSDOS_I(inode)->i_logstart = MSDOS_I(inode)->i_start;
+		inode->i_size = le32_to_cpu(de->size);
+		inode->i_op = &fat_file_inode_operations;
+		inode->i_fop = &fat_file_operations;
+		inode->i_mapping->a_ops = &fat_aops;
+		MSDOS_I(inode)->mmu_private = inode->i_size;
+	}
+	if(de->attr & ATTR_SYS)
+		if (sbi->options.sys_immutable)
+			inode->i_flags |= S_IMMUTABLE;
+	MSDOS_I(inode)->i_attrs = de->attr & ATTR_UNUSED;
+	/* this is as close to the truth as we can get ... */
+	inode->i_blksize = sbi->cluster_size;
+	inode->i_blocks = ((inode->i_size + (sbi->cluster_size - 1))
+			   & ~((loff_t)sbi->cluster_size - 1)) >> 9;
+	inode->i_mtime.tv_sec = inode->i_atime.tv_sec =
+		date_dos2unix(le16_to_cpu(de->time), le16_to_cpu(de->date));
+	inode->i_mtime.tv_nsec = inode->i_atime.tv_nsec = 0;
+	inode->i_ctime.tv_sec =
+		MSDOS_SB(sb)->options.isvfat
+		? date_dos2unix(le16_to_cpu(de->ctime), le16_to_cpu(de->cdate))
+		: inode->i_mtime.tv_sec;
+	inode->i_ctime.tv_nsec = de->ctime_ms * 1000000;
+	MSDOS_I(inode)->i_ctime_ms = de->ctime_ms;
+
+	return 0;
+}
 
 struct inode *fat_build_inode(struct super_block *sb,
 			struct msdos_dir_entry *de, loff_t i_pos, int *res)
@@ -145,6 +313,8 @@
 	return inode;
 }
 
+EXPORT_SYMBOL(fat_build_inode);
+
 static void fat_delete_inode(struct inode *inode)
 {
 	if (!is_bad_inode(inode)) {
@@ -193,6 +363,321 @@
 	kfree(sbi);
 }
 
+static kmem_cache_t *fat_inode_cachep;
+
+static struct inode *fat_alloc_inode(struct super_block *sb)
+{
+	struct msdos_inode_info *ei;
+	ei = kmem_cache_alloc(fat_inode_cachep, SLAB_KERNEL);
+	if (!ei)
+		return NULL;
+	return &ei->vfs_inode;
+}
+
+static void fat_destroy_inode(struct inode *inode)
+{
+	kmem_cache_free(fat_inode_cachep, MSDOS_I(inode));
+}
+
+static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags)
+{
+	struct msdos_inode_info *ei = (struct msdos_inode_info *)foo;
+
+	if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
+	    SLAB_CTOR_CONSTRUCTOR) {
+		spin_lock_init(&ei->cache_lru_lock);
+		ei->nr_caches = 0;
+		ei->cache_valid_id = FAT_CACHE_VALID + 1;
+		INIT_LIST_HEAD(&ei->cache_lru);
+		INIT_HLIST_NODE(&ei->i_fat_hash);
+		inode_init_once(&ei->vfs_inode);
+	}
+}
+
+static int __init fat_init_inodecache(void)
+{
+	fat_inode_cachep = kmem_cache_create("fat_inode_cache",
+					     sizeof(struct msdos_inode_info),
+					     0, SLAB_RECLAIM_ACCOUNT,
+					     init_once, NULL);
+	if (fat_inode_cachep == NULL)
+		return -ENOMEM;
+	return 0;
+}
+
+static void __exit fat_destroy_inodecache(void)
+{
+	if (kmem_cache_destroy(fat_inode_cachep))
+		printk(KERN_INFO "fat_inode_cache: not all structures were freed\n");
+}
+
+static int fat_remount(struct super_block *sb, int *flags, char *data)
+{
+	*flags |= MS_NODIRATIME;
+	return 0;
+}
+
+static int fat_statfs(struct super_block *sb, struct kstatfs *buf)
+{
+	struct msdos_sb_info *sbi = MSDOS_SB(sb);
+	int free, nr, ret;
+
+	if (sbi->free_clusters != -1)
+		free = sbi->free_clusters;
+	else {
+		lock_fat(sb);
+		if (sbi->free_clusters != -1)
+			free = sbi->free_clusters;
+		else {
+			free = 0;
+			for (nr = FAT_START_ENT; nr < sbi->max_cluster; nr++) {
+				ret = fat_access(sb, nr, -1);
+				if (ret < 0) {
+					unlock_fat(sb);
+					return ret;
+				} else if (ret == FAT_ENT_FREE)
+					free++;
+			}
+			sbi->free_clusters = free;
+		}
+		unlock_fat(sb);
+	}
+
+	buf->f_type = sb->s_magic;
+	buf->f_bsize = sbi->cluster_size;
+	buf->f_blocks = sbi->max_cluster - FAT_START_ENT;
+	buf->f_bfree = free;
+	buf->f_bavail = free;
+	buf->f_namelen = sbi->options.isvfat ? 260 : 12;
+
+	return 0;
+}
+
+static int fat_write_inode(struct inode *inode, int wait)
+{
+	struct super_block *sb = inode->i_sb;
+	struct msdos_sb_info *sbi = MSDOS_SB(sb);
+	struct buffer_head *bh;
+	struct msdos_dir_entry *raw_entry;
+	loff_t i_pos;
+
+retry:
+	i_pos = MSDOS_I(inode)->i_pos;
+	if (inode->i_ino == MSDOS_ROOT_INO || !i_pos) {
+		return 0;
+	}
+	lock_kernel();
+	if (!(bh = sb_bread(sb, i_pos >> sbi->dir_per_block_bits))) {
+		printk(KERN_ERR "FAT: unable to read inode block "
+		       "for updating (i_pos %lld)\n", i_pos);
+		unlock_kernel();
+		return -EIO;
+	}
+	spin_lock(&sbi->inode_hash_lock);
+	if (i_pos != MSDOS_I(inode)->i_pos) {
+		spin_unlock(&sbi->inode_hash_lock);
+		brelse(bh);
+		unlock_kernel();
+		goto retry;
+	}
+
+	raw_entry = &((struct msdos_dir_entry *) (bh->b_data))
+	    [i_pos & (sbi->dir_per_block - 1)];
+	if (S_ISDIR(inode->i_mode)) {
+		raw_entry->attr = ATTR_DIR;
+		raw_entry->size = 0;
+	}
+	else {
+		raw_entry->attr = ATTR_NONE;
+		raw_entry->size = cpu_to_le32(inode->i_size);
+	}
+	raw_entry->attr |= MSDOS_MKATTR(inode->i_mode) |
+	    MSDOS_I(inode)->i_attrs;
+	raw_entry->start = cpu_to_le16(MSDOS_I(inode)->i_logstart);
+	raw_entry->starthi = cpu_to_le16(MSDOS_I(inode)->i_logstart >> 16);
+	fat_date_unix2dos(inode->i_mtime.tv_sec, &raw_entry->time, &raw_entry->date);
+	if (sbi->options.isvfat) {
+		fat_date_unix2dos(inode->i_ctime.tv_sec,&raw_entry->ctime,&raw_entry->cdate);
+		raw_entry->ctime_ms = MSDOS_I(inode)->i_ctime_ms; /* use i_ctime.tv_nsec? */
+	}
+	spin_unlock(&sbi->inode_hash_lock);
+	mark_buffer_dirty(bh);
+	brelse(bh);
+	unlock_kernel();
+	return 0;
+}
+
+static int fat_show_options(struct seq_file *m, struct vfsmount *mnt);
+static struct super_operations fat_sops = {
+	.alloc_inode	= fat_alloc_inode,
+	.destroy_inode	= fat_destroy_inode,
+	.write_inode	= fat_write_inode,
+	.delete_inode	= fat_delete_inode,
+	.put_super	= fat_put_super,
+	.statfs		= fat_statfs,
+	.clear_inode	= fat_clear_inode,
+	.remount_fs	= fat_remount,
+
+	.read_inode	= make_bad_inode,
+
+	.show_options	= fat_show_options,
+};
+
+/*
+ * a FAT file handle with fhtype 3 is
+ *  0/  i_ino - for fast, reliable lookup if still in the cache
+ *  1/  i_generation - to see if i_ino is still valid
+ *          bit 0 == 0 iff directory
+ *  2/  i_pos(8-39) - if ino has changed, but still in cache
+ *  3/  i_pos(4-7)|i_logstart - to semi-verify inode found at i_pos
+ *  4/  i_pos(0-3)|parent->i_logstart - maybe used to hunt for the file on disc
+ *
+ * Hack for NFSv2: Maximum FAT entry number is 28bits and maximum
+ * i_pos is 40bits (blocknr(32) + dir offset(8)), so two 4bits
+ * of i_logstart is used to store the directory entry offset.
+ */
+
+static struct dentry *
+fat_decode_fh(struct super_block *sb, __u32 *fh, int len, int fhtype,
+	      int (*acceptable)(void *context, struct dentry *de),
+	      void *context)
+{
+	if (fhtype != 3)
+		return ERR_PTR(-ESTALE);
+	if (len < 5)
+		return ERR_PTR(-ESTALE);
+
+	return sb->s_export_op->find_exported_dentry(sb, fh, NULL, acceptable, context);
+}
+
+static struct dentry *fat_get_dentry(struct super_block *sb, void *inump)
+{
+	struct inode *inode = NULL;
+	struct dentry *result;
+	__u32 *fh = inump;
+
+	inode = iget(sb, fh[0]);
+	if (!inode || is_bad_inode(inode) || inode->i_generation != fh[1]) {
+		if (inode)
+			iput(inode);
+		inode = NULL;
+	}
+	if (!inode) {
+		loff_t i_pos;
+		int i_logstart = fh[3] & 0x0fffffff;
+
+		i_pos = (loff_t)fh[2] << 8;
+		i_pos |= ((fh[3] >> 24) & 0xf0) | (fh[4] >> 28);
+
+		/* try 2 - see if i_pos is in F-d-c
+		 * require i_logstart to be the same
+		 * Will fail if you truncate and then re-write
+		 */
+
+		inode = fat_iget(sb, i_pos);
+		if (inode && MSDOS_I(inode)->i_logstart != i_logstart) {
+			iput(inode);
+			inode = NULL;
+		}
+	}
+	if (!inode) {
+		/* For now, do nothing
+		 * What we could do is:
+		 * follow the file starting at fh[4], and record
+		 * the ".." entry, and the name of the fh[2] entry.
+		 * The follow the ".." file finding the next step up.
+		 * This way we build a path to the root of
+		 * the tree. If this works, we lookup the path and so
+		 * get this inode into the cache.
+		 * Finally try the fat_iget lookup again
+		 * If that fails, then weare totally out of luck
+		 * But all that is for another day
+		 */
+	}
+	if (!inode)
+		return ERR_PTR(-ESTALE);
+
+
+	/* now to find a dentry.
+	 * If possible, get a well-connected one
+	 */
+	result = d_alloc_anon(inode);
+	if (result == NULL) {
+		iput(inode);
+		return ERR_PTR(-ENOMEM);
+	}
+	result->d_op = sb->s_root->d_op;
+	return result;
+}
+
+static int
+fat_encode_fh(struct dentry *de, __u32 *fh, int *lenp, int connectable)
+{
+	int len = *lenp;
+	struct inode *inode =  de->d_inode;
+	u32 ipos_h, ipos_m, ipos_l;
+
+	if (len < 5)
+		return 255; /* no room */
+
+	ipos_h = MSDOS_I(inode)->i_pos >> 8;
+	ipos_m = (MSDOS_I(inode)->i_pos & 0xf0) << 24;
+	ipos_l = (MSDOS_I(inode)->i_pos & 0x0f) << 28;
+	*lenp = 5;
+	fh[0] = inode->i_ino;
+	fh[1] = inode->i_generation;
+	fh[2] = ipos_h;
+	fh[3] = ipos_m | MSDOS_I(inode)->i_logstart;
+	spin_lock(&de->d_lock);
+	fh[4] = ipos_l | MSDOS_I(de->d_parent->d_inode)->i_logstart;
+	spin_unlock(&de->d_lock);
+	return 3;
+}
+
+static struct dentry *fat_get_parent(struct dentry *child)
+{
+	struct buffer_head *bh=NULL;
+	struct msdos_dir_entry *de = NULL;
+	struct dentry *parent = NULL;
+	int res;
+	loff_t i_pos = 0;
+	struct inode *inode;
+
+	lock_kernel();
+	res = fat_scan(child->d_inode, MSDOS_DOTDOT, &bh, &de, &i_pos);
+
+	if (res < 0)
+		goto out;
+	inode = fat_build_inode(child->d_sb, de, i_pos, &res);
+	if (res)
+		goto out;
+	if (!inode)
+		res = -EACCES;
+	else {
+		parent = d_alloc_anon(inode);
+		if (!parent) {
+			iput(inode);
+			res = -ENOMEM;
+		}
+	}
+
+ out:
+	if(bh)
+		brelse(bh);
+	unlock_kernel();
+	if (res)
+		return ERR_PTR(res);
+	else
+		return parent;
+}
+
+static struct export_operations fat_export_ops = {
+	.decode_fh	= fat_decode_fh,
+	.encode_fh	= fat_encode_fh,
+	.get_dentry	= fat_get_dentry,
+	.get_parent	= fat_get_parent,
+};
+
 static int fat_show_options(struct seq_file *m, struct vfsmount *mnt)
 {
 	struct msdos_sb_info *sbi = MSDOS_SB(mnt->mnt_sb);
@@ -205,11 +690,10 @@
 		seq_printf(m, ",gid=%u", opts->fs_gid);
 	seq_printf(m, ",fmask=%04o", opts->fs_fmask);
 	seq_printf(m, ",dmask=%04o", opts->fs_dmask);
-	if (sbi->nls_disk && opts->codepage != fat_default_codepage)
+	if (sbi->nls_disk)
 		seq_printf(m, ",codepage=%s", sbi->nls_disk->charset);
 	if (isvfat) {
-		if (sbi->nls_io &&
-		    strcmp(opts->iocharset, fat_default_iocharset))
+		if (sbi->nls_io)
 			seq_printf(m, ",iocharset=%s", sbi->nls_io->charset);
 
 		switch (opts->shortname) {
@@ -509,23 +993,6 @@
 
 	if (opts->unicode_xlate)
 		opts->utf8 = 0;
-	
-	return 0;
-}
-
-static int fat_calc_dir_size(struct inode *inode)
-{
-	struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
-	int ret, fclus, dclus;
-
-	inode->i_size = 0;
-	if (MSDOS_I(inode)->i_start == 0)
-		return 0;
-
-	ret = fat_get_cluster(inode, FAT_ENT_EOF, &fclus, &dclus);
-	if (ret < 0)
-		return ret;
-	inode->i_size = (fclus + 1) << sbi->cluster_bits;
 
 	return 0;
 }
@@ -569,230 +1036,6 @@
 }
 
 /*
- * a FAT file handle with fhtype 3 is
- *  0/  i_ino - for fast, reliable lookup if still in the cache
- *  1/  i_generation - to see if i_ino is still valid
- *          bit 0 == 0 iff directory
- *  2/  i_pos(8-39) - if ino has changed, but still in cache
- *  3/  i_pos(4-7)|i_logstart - to semi-verify inode found at i_pos
- *  4/  i_pos(0-3)|parent->i_logstart - maybe used to hunt for the file on disc
- *
- * Hack for NFSv2: Maximum FAT entry number is 28bits and maximum
- * i_pos is 40bits (blocknr(32) + dir offset(8)), so two 4bits
- * of i_logstart is used to store the directory entry offset.
- */
-
-static struct dentry *
-fat_decode_fh(struct super_block *sb, __u32 *fh, int len, int fhtype, 
-	      int (*acceptable)(void *context, struct dentry *de),
-	      void *context)
-{
-	if (fhtype != 3)
-		return ERR_PTR(-ESTALE);
-	if (len < 5)
-		return ERR_PTR(-ESTALE);
-
-	return sb->s_export_op->find_exported_dentry(sb, fh, NULL, acceptable, context);
-}
-
-static struct dentry *fat_get_dentry(struct super_block *sb, void *inump)
-{
-	struct inode *inode = NULL;
-	struct dentry *result;
-	__u32 *fh = inump;
-
-	inode = iget(sb, fh[0]);
-	if (!inode || is_bad_inode(inode) || inode->i_generation != fh[1]) {
-		if (inode)
-			iput(inode);
-		inode = NULL;
-	}
-	if (!inode) {
-		loff_t i_pos;
-		int i_logstart = fh[3] & 0x0fffffff;
-
-		i_pos = (loff_t)fh[2] << 8;
-		i_pos |= ((fh[3] >> 24) & 0xf0) | (fh[4] >> 28);
-
-		/* try 2 - see if i_pos is in F-d-c
-		 * require i_logstart to be the same
-		 * Will fail if you truncate and then re-write
-		 */
-
-		inode = fat_iget(sb, i_pos);
-		if (inode && MSDOS_I(inode)->i_logstart != i_logstart) {
-			iput(inode);
-			inode = NULL;
-		}
-	}
-	if (!inode) {
-		/* For now, do nothing
-		 * What we could do is:
-		 * follow the file starting at fh[4], and record
-		 * the ".." entry, and the name of the fh[2] entry.
-		 * The follow the ".." file finding the next step up.
-		 * This way we build a path to the root of
-		 * the tree. If this works, we lookup the path and so
-		 * get this inode into the cache.
-		 * Finally try the fat_iget lookup again
-		 * If that fails, then weare totally out of luck
-		 * But all that is for another day
-		 */
-	}
-	if (!inode)
-		return ERR_PTR(-ESTALE);
-
-	
-	/* now to find a dentry.
-	 * If possible, get a well-connected one
-	 */
-	result = d_alloc_anon(inode);
-	if (result == NULL) {
-		iput(inode);
-		return ERR_PTR(-ENOMEM);
-	}
-	result->d_op = sb->s_root->d_op;
-	return result;
-}
-
-static int
-fat_encode_fh(struct dentry *de, __u32 *fh, int *lenp, int connectable)
-{
-	int len = *lenp;
-	struct inode *inode =  de->d_inode;
-	u32 ipos_h, ipos_m, ipos_l;
-	
-	if (len < 5)
-		return 255; /* no room */
-
-	ipos_h = MSDOS_I(inode)->i_pos >> 8;
-	ipos_m = (MSDOS_I(inode)->i_pos & 0xf0) << 24;
-	ipos_l = (MSDOS_I(inode)->i_pos & 0x0f) << 28;
-	*lenp = 5;
-	fh[0] = inode->i_ino;
-	fh[1] = inode->i_generation;
-	fh[2] = ipos_h;
-	fh[3] = ipos_m | MSDOS_I(inode)->i_logstart;
-	spin_lock(&de->d_lock);
-	fh[4] = ipos_l | MSDOS_I(de->d_parent->d_inode)->i_logstart;
-	spin_unlock(&de->d_lock);
-	return 3;
-}
-
-static struct dentry *fat_get_parent(struct dentry *child)
-{
-	struct buffer_head *bh=NULL;
-	struct msdos_dir_entry *de = NULL;
-	struct dentry *parent = NULL;
-	int res;
-	loff_t i_pos = 0;
-	struct inode *inode;
-
-	lock_kernel();
-	res = fat_scan(child->d_inode, MSDOS_DOTDOT, &bh, &de, &i_pos);
-
-	if (res < 0)
-		goto out;
-	inode = fat_build_inode(child->d_sb, de, i_pos, &res);
-	if (res)
-		goto out;
-	if (!inode)
-		res = -EACCES;
-	else {
-		parent = d_alloc_anon(inode);
-		if (!parent) {
-			iput(inode);
-			res = -ENOMEM;
-		}
-	}
-
- out:
-	if(bh)
-		brelse(bh);
-	unlock_kernel();
-	if (res)
-		return ERR_PTR(res);
-	else
-		return parent;
-}
-
-static kmem_cache_t *fat_inode_cachep;
-
-static struct inode *fat_alloc_inode(struct super_block *sb)
-{
-	struct msdos_inode_info *ei;
-	ei = (struct msdos_inode_info *)kmem_cache_alloc(fat_inode_cachep, SLAB_KERNEL);
-	if (!ei)
-		return NULL;
-	return &ei->vfs_inode;
-}
-
-static void fat_destroy_inode(struct inode *inode)
-{
-	kmem_cache_free(fat_inode_cachep, MSDOS_I(inode));
-}
-
-static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags)
-{
-	struct msdos_inode_info *ei = (struct msdos_inode_info *) foo;
-
-	if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
-	    SLAB_CTOR_CONSTRUCTOR) {
-		spin_lock_init(&ei->cache_lru_lock);
-		ei->nr_caches = 0;
-		ei->cache_valid_id = FAT_CACHE_VALID + 1;
-		INIT_LIST_HEAD(&ei->cache_lru);
-		INIT_HLIST_NODE(&ei->i_fat_hash);
-		inode_init_once(&ei->vfs_inode);
-	}
-}
- 
-int __init fat_init_inodecache(void)
-{
-	fat_inode_cachep = kmem_cache_create("fat_inode_cache",
-					     sizeof(struct msdos_inode_info),
-					     0, SLAB_RECLAIM_ACCOUNT,
-					     init_once, NULL);
-	if (fat_inode_cachep == NULL)
-		return -ENOMEM;
-	return 0;
-}
-
-void __exit fat_destroy_inodecache(void)
-{
-	if (kmem_cache_destroy(fat_inode_cachep))
-		printk(KERN_INFO "fat_inode_cache: not all structures were freed\n");
-}
-
-static int fat_remount(struct super_block *sb, int *flags, char *data)
-{
-	*flags |= MS_NODIRATIME;
-	return 0;
-}
-
-static struct super_operations fat_sops = { 
-	.alloc_inode	= fat_alloc_inode,
-	.destroy_inode	= fat_destroy_inode,
-	.write_inode	= fat_write_inode,
-	.delete_inode	= fat_delete_inode,
-	.put_super	= fat_put_super,
-	.statfs		= fat_statfs,
-	.clear_inode	= fat_clear_inode,
-	.remount_fs	= fat_remount,
-
-	.read_inode	= make_bad_inode,
-
-	.show_options	= fat_show_options,
-};
-
-static struct export_operations fat_export_ops = {
-	.decode_fh	= fat_decode_fh,
-	.encode_fh	= fat_encode_fh,
-	.get_dentry	= fat_get_dentry,
-	.get_parent	= fat_get_parent,
-};
-
-/*
  * Read the super block of an MS-DOS FS.
  */
 int fat_fill_super(struct super_block *sb, void *data, int silent,
@@ -930,7 +1173,7 @@
 		sbi->root_cluster = le32_to_cpu(b->root_cluster);
 
 		sb->s_maxbytes = 0xffffffff;
-		
+
 		/* MC - if info_sector is 0, don't multiply by 0 */
 		sbi->fsinfo_sector = le16_to_cpu(b->info_sector);
 		if (sbi->fsinfo_sector == 0)
@@ -989,7 +1232,7 @@
 
 	/* check that FAT table does not overflow */
 	fat_clusters = sbi->fat_length * sb->s_blocksize * 8 / sbi->fat_bits;
-	total_clusters = min(total_clusters, fat_clusters - 2);
+	total_clusters = min(total_clusters, fat_clusters - FAT_START_ENT);
 	if (total_clusters > MAX_FAT(sb)) {
 		if (!silent)
 			printk(KERN_ERR "FAT: count of clusters too big (%u)\n",
@@ -998,9 +1241,9 @@
 		goto out_invalid;
 	}
 
-	sbi->clusters = total_clusters;
+	sbi->max_cluster = total_clusters + FAT_START_ENT;
 	/* check the free_clusters, it's not necessarily correct */
-	if (sbi->free_clusters != -1 && sbi->free_clusters > sbi->clusters)
+	if (sbi->free_clusters != -1 && sbi->free_clusters > total_clusters)
 		sbi->free_clusters = -1;
 
 	brelse(bh);
@@ -1070,262 +1313,28 @@
 	return error;
 }
 
-static int fat_statfs(struct super_block *sb, struct kstatfs *buf)
-{
-	int free, nr, ret;
-       
-	if (MSDOS_SB(sb)->free_clusters != -1)
-		free = MSDOS_SB(sb)->free_clusters;
-	else {
-		lock_fat(sb);
-		if (MSDOS_SB(sb)->free_clusters != -1)
-			free = MSDOS_SB(sb)->free_clusters;
-		else {
-			free = 0;
-			for (nr = 2; nr < MSDOS_SB(sb)->clusters + 2; nr++) {
-				ret = fat_access(sb, nr, -1);
-				if (ret < 0) {
-					unlock_fat(sb);
-					return ret;
-				} else if (ret == FAT_ENT_FREE)
-					free++;
-			}
-			MSDOS_SB(sb)->free_clusters = free;
-		}
-		unlock_fat(sb);
-	}
-
-	buf->f_type = sb->s_magic;
-	buf->f_bsize = MSDOS_SB(sb)->cluster_size;
-	buf->f_blocks = MSDOS_SB(sb)->clusters;
-	buf->f_bfree = free;
-	buf->f_bavail = free;
-	buf->f_namelen = MSDOS_SB(sb)->options.isvfat ? 260 : 12;
-
-	return 0;
-}
-
-static int is_exec(unsigned char *extension)
-{
-	unsigned char *exe_extensions = "EXECOMBAT", *walk;
-
-	for (walk = exe_extensions; *walk; walk += 3)
-		if (!strncmp(extension, walk, 3))
-			return 1;
-	return 0;
-}
-
-static int fat_writepage(struct page *page, struct writeback_control *wbc)
-{
-	return block_write_full_page(page,fat_get_block, wbc);
-}
-static int fat_readpage(struct file *file, struct page *page)
-{
-	return block_read_full_page(page,fat_get_block);
-}
+EXPORT_SYMBOL(fat_fill_super);
 
-static int
-fat_prepare_write(struct file *file, struct page *page,
-			unsigned from, unsigned to)
-{
-	kmap(page);
-	return cont_prepare_write(page,from,to,fat_get_block,
-		&MSDOS_I(page->mapping->host)->mmu_private);
-}
+int __init fat_cache_init(void);
+void __exit fat_cache_destroy(void);
 
-static int
-fat_commit_write(struct file *file, struct page *page,
-			unsigned from, unsigned to)
+static int __init init_fat_fs(void)
 {
-	kunmap(page);
-	return generic_commit_write(file, page, from, to);
-}
+	int ret;
 
-static sector_t _fat_bmap(struct address_space *mapping, sector_t block)
-{
-	return generic_block_bmap(mapping,block,fat_get_block);
-}
-static struct address_space_operations fat_aops = {
-	.readpage = fat_readpage,
-	.writepage = fat_writepage,
-	.sync_page = block_sync_page,
-	.prepare_write = fat_prepare_write,
-	.commit_write = fat_commit_write,
-	.bmap = _fat_bmap
-};
-
-/* doesn't deal with root inode */
-static int fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de)
-{
-	struct super_block *sb = inode->i_sb;
-	struct msdos_sb_info *sbi = MSDOS_SB(sb);
-	int error;
-
-	MSDOS_I(inode)->i_pos = 0;
-	inode->i_uid = sbi->options.fs_uid;
-	inode->i_gid = sbi->options.fs_gid;
-	inode->i_version++;
-	inode->i_generation = get_seconds();
-	
-	if ((de->attr & ATTR_DIR) && !IS_FREE(de->name)) {
-		inode->i_generation &= ~1;
-		inode->i_mode = MSDOS_MKMODE(de->attr,
-			S_IRWXUGO & ~sbi->options.fs_dmask) | S_IFDIR;
-		inode->i_op = sbi->dir_ops;
-		inode->i_fop = &fat_dir_operations;
-
-		MSDOS_I(inode)->i_start = le16_to_cpu(de->start);
-		if (sbi->fat_bits == 32)
-			MSDOS_I(inode)->i_start |= (le16_to_cpu(de->starthi) << 16);
-
-		MSDOS_I(inode)->i_logstart = MSDOS_I(inode)->i_start;
-		error = fat_calc_dir_size(inode);
-		if (error < 0)
-			return error;
-		MSDOS_I(inode)->mmu_private = inode->i_size;
-
-		inode->i_nlink = fat_subdirs(inode);
-	} else { /* not a directory */
-		inode->i_generation |= 1;
-		inode->i_mode = MSDOS_MKMODE(de->attr,
-		    ((sbi->options.showexec &&
-		       !is_exec(de->ext))
-		    	? S_IRUGO|S_IWUGO : S_IRWXUGO)
-		    & ~sbi->options.fs_fmask) | S_IFREG;
-		MSDOS_I(inode)->i_start = le16_to_cpu(de->start);
-		if (sbi->fat_bits == 32)
-			MSDOS_I(inode)->i_start |= (le16_to_cpu(de->starthi) << 16);
-
-		MSDOS_I(inode)->i_logstart = MSDOS_I(inode)->i_start;
-		inode->i_size = le32_to_cpu(de->size);
-	        inode->i_op = &fat_file_inode_operations;
-	        inode->i_fop = &fat_file_operations;
-		inode->i_mapping->a_ops = &fat_aops;
-		MSDOS_I(inode)->mmu_private = inode->i_size;
-	}
-	if(de->attr & ATTR_SYS)
-		if (sbi->options.sys_immutable)
-			inode->i_flags |= S_IMMUTABLE;
-	MSDOS_I(inode)->i_attrs = de->attr & ATTR_UNUSED;
-	/* this is as close to the truth as we can get ... */
-	inode->i_blksize = sbi->cluster_size;
-	inode->i_blocks = ((inode->i_size + (sbi->cluster_size - 1))
-			   & ~((loff_t)sbi->cluster_size - 1)) >> 9;
-	inode->i_mtime.tv_sec = inode->i_atime.tv_sec =
-		date_dos2unix(le16_to_cpu(de->time), le16_to_cpu(de->date));
-	inode->i_mtime.tv_nsec = inode->i_atime.tv_nsec = 0;
-	inode->i_ctime.tv_sec =
-		MSDOS_SB(sb)->options.isvfat
-		? date_dos2unix(le16_to_cpu(de->ctime), le16_to_cpu(de->cdate))
-		: inode->i_mtime.tv_sec;
-	inode->i_ctime.tv_nsec = de->ctime_ms * 1000000;
-	MSDOS_I(inode)->i_ctime_ms = de->ctime_ms;
-
-	return 0;
+	ret = fat_cache_init();
+	if (ret < 0)
+		return ret;
+	return fat_init_inodecache();
 }
 
-static int fat_write_inode(struct inode *inode, int wait)
+static void __exit exit_fat_fs(void)
 {
-	struct super_block *sb = inode->i_sb;
-	struct msdos_sb_info *sbi = MSDOS_SB(sb);
-	struct buffer_head *bh;
-	struct msdos_dir_entry *raw_entry;
-	loff_t i_pos;
-
-retry:
-	i_pos = MSDOS_I(inode)->i_pos;
-	if (inode->i_ino == MSDOS_ROOT_INO || !i_pos) {
-		return 0;
-	}
-	lock_kernel();
-	if (!(bh = sb_bread(sb, i_pos >> sbi->dir_per_block_bits))) {
-		printk(KERN_ERR "FAT: unable to read inode block "
-		       "for updating (i_pos %lld)\n", i_pos);
-		unlock_kernel();
-		return -EIO;
-	}
-	spin_lock(&sbi->inode_hash_lock);
-	if (i_pos != MSDOS_I(inode)->i_pos) {
-		spin_unlock(&sbi->inode_hash_lock);
-		brelse(bh);
-		unlock_kernel();
-		goto retry;
-	}
-
-	raw_entry = &((struct msdos_dir_entry *) (bh->b_data))
-	    [i_pos & (sbi->dir_per_block - 1)];
-	if (S_ISDIR(inode->i_mode)) {
-		raw_entry->attr = ATTR_DIR;
-		raw_entry->size = 0;
-	}
-	else {
-		raw_entry->attr = ATTR_NONE;
-		raw_entry->size = cpu_to_le32(inode->i_size);
-	}
-	raw_entry->attr |= MSDOS_MKATTR(inode->i_mode) |
-	    MSDOS_I(inode)->i_attrs;
-	raw_entry->start = cpu_to_le16(MSDOS_I(inode)->i_logstart);
-	raw_entry->starthi = cpu_to_le16(MSDOS_I(inode)->i_logstart >> 16);
-	fat_date_unix2dos(inode->i_mtime.tv_sec, &raw_entry->time, &raw_entry->date);
-	if (sbi->options.isvfat) {
-		fat_date_unix2dos(inode->i_ctime.tv_sec,&raw_entry->ctime,&raw_entry->cdate);
-		raw_entry->ctime_ms = MSDOS_I(inode)->i_ctime_ms; /* use i_ctime.tv_nsec? */
-	}
-	spin_unlock(&sbi->inode_hash_lock);
-	mark_buffer_dirty(bh);
-	brelse(bh);
-	unlock_kernel();
-	return 0;
+	fat_cache_destroy();
+	fat_destroy_inodecache();
 }
 
+module_init(init_fat_fs)
+module_exit(exit_fat_fs)
 
-int fat_notify_change(struct dentry * dentry, struct iattr * attr)
-{
-	struct msdos_sb_info *sbi = MSDOS_SB(dentry->d_sb);
-	struct inode *inode = dentry->d_inode;
-	int mask, error = 0;
-
-	lock_kernel();
-
-	/* FAT cannot truncate to a longer file */
-	if (attr->ia_valid & ATTR_SIZE) {
-		if (attr->ia_size > inode->i_size) {
-			error = -EPERM;
-			goto out;
-		}
-	}
-
-	error = inode_change_ok(inode, attr);
-	if (error) {
-		if (sbi->options.quiet)
-			error = 0;
- 		goto out;
-	}
-
-	if (((attr->ia_valid & ATTR_UID) && 
-	     (attr->ia_uid != sbi->options.fs_uid)) ||
-	    ((attr->ia_valid & ATTR_GID) && 
-	     (attr->ia_gid != sbi->options.fs_gid)) ||
-	    ((attr->ia_valid & ATTR_MODE) &&
-	     (attr->ia_mode & ~MSDOS_VALID_MODE)))
-		error = -EPERM;
-
-	if (error) {
-		if (sbi->options.quiet)  
-			error = 0;
-		goto out;
-	}
-	error = inode_setattr(inode, attr);
-	if (error)
-		goto out;
-
-	if (S_ISDIR(inode->i_mode))
-		mask = sbi->options.fs_dmask;
-	else
-		mask = sbi->options.fs_fmask;
-	inode->i_mode &= S_IFMT | (S_IRWXUGO & ~mask);
-out:
-	unlock_kernel();
-	return error;
-}
 MODULE_LICENSE("GPL");
diff -Nru a/fs/fat/misc.c b/fs/fat/misc.c
--- a/fs/fat/misc.c	2005-03-01 23:39:09 -08:00
+++ b/fs/fat/misc.c	2005-03-01 23:39:09 -08:00
@@ -6,6 +6,7 @@
  *		 and date_dos2unix for date==0 by Igor Zhbanov(bsg@uniyar.ac.ru)
  */
 
+#include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/msdos_fs.h>
 #include <linux/buffer_head.h>
@@ -14,26 +15,22 @@
  * fat_fs_panic reports a severe file system problem and sets the file system
  * read-only. The file system can be made writable again by remounting it.
  */
-
-static char panic_msg[512];
-
 void fat_fs_panic(struct super_block *s, const char *fmt, ...)
 {
-	int not_ro;
 	va_list args;
 
-	va_start (args, fmt);
-	vsnprintf (panic_msg, sizeof(panic_msg), fmt, args);
-	va_end (args);
+	printk(KERN_ERR "FAT: Filesystem panic (dev %s)\n", s->s_id);
 
-	not_ro = !(s->s_flags & MS_RDONLY);
-	if (not_ro)
-		s->s_flags |= MS_RDONLY;
+	printk(KERN_ERR "    ");
+	va_start(args, fmt);
+	vprintk(fmt, args);
+	va_end(args);
+	printk("\n");
 
-	printk(KERN_ERR "FAT: Filesystem panic (dev %s)\n"
-	       "    %s\n", s->s_id, panic_msg);
-	if (not_ro)
+	if (!(s->s_flags & MS_RDONLY)) {
+		s->s_flags |= MS_RDONLY;
 		printk(KERN_ERR "    File system has been set read-only\n");
+	}
 }
 
 void lock_fat(struct super_block *sb)
@@ -89,10 +86,11 @@
 int fat_add_cluster(struct inode *inode)
 {
 	struct super_block *sb = inode->i_sb;
+	struct msdos_sb_info *sbi = MSDOS_SB(sb);
 	int ret, count, limit, new_dclus, new_fclus, last;
-	int cluster_bits = MSDOS_SB(sb)->cluster_bits;
-	
-	/* 
+	int cluster_bits = sbi->cluster_bits;
+
+	/*
 	 * We must locate the last cluster of the file to add this new
 	 * one (new_dclus) to the end of the link list (the FAT).
 	 *
@@ -112,18 +110,18 @@
 
 	/* find free FAT entry */
 	lock_fat(sb);
-	
-	if (MSDOS_SB(sb)->free_clusters == 0) {
+
+	if (sbi->free_clusters == 0) {
 		unlock_fat(sb);
 		return -ENOSPC;
 	}
 
-	limit = MSDOS_SB(sb)->clusters + 2;
-	new_dclus = MSDOS_SB(sb)->prev_free + 1;
-	for (count = 0; count < MSDOS_SB(sb)->clusters; count++, new_dclus++) {
+	limit = sbi->max_cluster;
+	new_dclus = sbi->prev_free + 1;
+	for (count = FAT_START_ENT; count < limit; count++, new_dclus++) {
 		new_dclus = new_dclus % limit;
-		if (new_dclus < 2)
-			new_dclus = 2;
+		if (new_dclus < FAT_START_ENT)
+			new_dclus = FAT_START_ENT;
 
 		ret = fat_access(sb, new_dclus, -1);
 		if (ret < 0) {
@@ -132,8 +130,8 @@
 		} else if (ret == FAT_ENT_FREE)
 			break;
 	}
-	if (count >= MSDOS_SB(sb)->clusters) {
-		MSDOS_SB(sb)->free_clusters = 0;
+	if (count >= limit) {
+		sbi->free_clusters = 0;
 		unlock_fat(sb);
 		return -ENOSPC;
 	}
@@ -144,11 +142,11 @@
 		return ret;
 	}
 
-	MSDOS_SB(sb)->prev_free = new_dclus;
-	if (MSDOS_SB(sb)->free_clusters != -1)
-		MSDOS_SB(sb)->free_clusters--;
+	sbi->prev_free = new_dclus;
+	if (sbi->free_clusters != -1)
+		sbi->free_clusters--;
 	fat_clusters_flush(sb);
-	
+
 	unlock_fat(sb);
 
 	/* add new one to the last of the cluster chain */
@@ -167,70 +165,28 @@
 			new_fclus, inode->i_blocks >> (cluster_bits - 9));
 		fat_cache_inval_inode(inode);
 	}
-	inode->i_blocks += MSDOS_SB(sb)->cluster_size >> 9;
+	inode->i_blocks += sbi->cluster_size >> 9;
 
 	return new_dclus;
 }
 
-struct buffer_head *fat_extend_dir(struct inode *inode)
-{
-	struct super_block *sb = inode->i_sb;
-	struct buffer_head *bh, *res = NULL;
-	int nr, sec_per_clus = MSDOS_SB(sb)->sec_per_clus;
-	sector_t sector, last_sector;
-
-	if (MSDOS_SB(sb)->fat_bits != 32) {
-		if (inode->i_ino == MSDOS_ROOT_INO)
-			return ERR_PTR(-ENOSPC);
-	}
-
-	nr = fat_add_cluster(inode);
-	if (nr < 0)
-		return ERR_PTR(nr);
-	
-	sector = ((sector_t)nr - 2) * sec_per_clus + MSDOS_SB(sb)->data_start;
-	last_sector = sector + sec_per_clus;
-	for ( ; sector < last_sector; sector++) {
-		if ((bh = sb_getblk(sb, sector))) {
-			memset(bh->b_data, 0, sb->s_blocksize);
-			set_buffer_uptodate(bh);
-			mark_buffer_dirty(bh);
-			if (!res)
-				res = bh;
-			else
-				brelse(bh);
-		}
-	}
-	if (res == NULL)
-		res = ERR_PTR(-EIO);
-	if (inode->i_size & (sb->s_blocksize - 1)) {
-		fat_fs_panic(sb, "Odd directory size");
-		inode->i_size = (inode->i_size + sb->s_blocksize)
-			& ~((loff_t)sb->s_blocksize - 1);
-	}
-	inode->i_size += MSDOS_SB(sb)->cluster_size;
-	MSDOS_I(inode)->mmu_private += MSDOS_SB(sb)->cluster_size;
-
-	return res;
-}
-
-/* Linear day numbers of the respective 1sts in non-leap years. */
-
-static int day_n[] = { 0,31,59,90,120,151,181,212,243,273,304,334,0,0,0,0 };
-		  /* JanFebMarApr May Jun Jul Aug Sep Oct Nov Dec */
-
-
 extern struct timezone sys_tz;
 
+/* Linear day numbers of the respective 1sts in non-leap years. */
+static int day_n[] = {
+   /* Jan  Feb  Mar  Apr   May  Jun  Jul  Aug  Sep  Oct  Nov  Dec */
+	0,  31,  59,  90,  120, 151, 181, 212, 243, 273, 304, 334, 0, 0, 0, 0
+};
 
 /* Convert a MS-DOS time/date pair to a UNIX date (seconds since 1 1 70). */
-
-int date_dos2unix(unsigned short time,unsigned short date)
+int date_dos2unix(unsigned short time, unsigned short date)
 {
-	int month,year,secs;
+	int month, year, secs;
 
-	/* first subtract and mask after that... Otherwise, if
-	   date == 0, bad things happen */
+	/*
+	 * first subtract and mask after that... Otherwise, if
+	 * date == 0, bad things happen
+	 */
 	month = ((date >> 5) - 1) & 15;
 	year = date >> 9;
 	secs = (time & 31)*2+60*((time >> 5) & 63)+(time >> 11)*3600+86400*
@@ -241,12 +197,10 @@
 	return secs;
 }
 
-
 /* Convert linear UNIX date to a MS-DOS time/date pair. */
-
-void fat_date_unix2dos(int unix_date,__le16 *time, __le16 *date)
+void fat_date_unix2dos(int unix_date, __le16 *time, __le16 *date)
 {
-	int day,year,nl_day,month;
+	int day, year, nl_day, month;
 
 	unix_date -= sys_tz.tz_minuteswest*60;
 
@@ -258,20 +212,23 @@
 	    (((unix_date/3600) % 24) << 11));
 	day = unix_date/86400-3652;
 	year = day/365;
-	if ((year+3)/4+365*year > day) year--;
+	if ((year+3)/4+365*year > day)
+		year--;
 	day -= (year+3)/4+365*year;
 	if (day == 59 && !(year & 3)) {
 		nl_day = day;
 		month = 2;
-	}
-	else {
+	} else {
 		nl_day = (year & 3) || day <= 59 ? day : day-1;
-		for (month = 0; month < 12; month++)
-			if (day_n[month] > nl_day) break;
+		for (month = 0; month < 12; month++) {
+			if (day_n[month] > nl_day)
+				break;
+		}
 	}
 	*date = cpu_to_le16(nl_day-day_n[month-1]+1+(month << 5)+(year << 9));
 }
 
+EXPORT_SYMBOL(fat_date_unix2dos);
 
 /* Returns the inode number of the directory entry at offset pos. If bh is
    non-NULL, it is brelse'd before. Pos is incremented. The buffer header is
@@ -281,10 +238,10 @@
    AV. want the next entry (took one explicit de=NULL in vfat/namei.c).
    AV. It's done in fat_get_entry() (inlined), here the slow case lives.
    AV. Additionally, when we return -1 (i.e. reached the end of directory)
-   AV. we make bh NULL. 
+   AV. we make bh NULL.
  */
 
-int fat__get_entry(struct inode *dir, loff_t *pos,struct buffer_head **bh,
+int fat__get_entry(struct inode *dir, loff_t *pos, struct buffer_head **bh,
 		   struct msdos_dir_entry **de, loff_t *i_pos)
 {
 	struct super_block *sb = dir->i_sb;
@@ -320,3 +277,5 @@
 
 	return 0;
 }
+
+EXPORT_SYMBOL(fat__get_entry);
diff -Nru a/fs/fcntl.c b/fs/fcntl.c
--- a/fs/fcntl.c	2005-03-01 23:39:07 -08:00
+++ b/fs/fcntl.c	2005-03-01 23:39:07 -08:00
@@ -41,38 +41,6 @@
 	return res;
 }
 
-
-/* Expand files.  Return <0 on error; 0 nothing done; 1 files expanded,
- * we may have blocked. 
- *
- * Should be called with the files->file_lock spinlock held for write.
- */
-static int expand_files(struct files_struct *files, int nr)
-{
-	int err, expand = 0;
-#ifdef FDSET_DEBUG	
-	printk (KERN_ERR "%s %d: nr = %d\n", __FUNCTION__, current->pid, nr);
-#endif
-	
-	if (nr >= files->max_fdset) {
-		expand = 1;
-		if ((err = expand_fdset(files, nr)))
-			goto out;
-	}
-	if (nr >= files->max_fds) {
-		expand = 1;
-		if ((err = expand_fd_array(files, nr)))
-			goto out;
-	}
-	err = expand;
- out:
-#ifdef FDSET_DEBUG	
-	if (err)
-		printk (KERN_ERR "%s %d: return %d\n", __FUNCTION__, current->pid, err);
-#endif
-	return err;
-}
-
 /*
  * locate_fd finds a free file descriptor in the open_fds fdset,
  * expanding the fd arrays if necessary.  Must be called with the
@@ -539,7 +507,7 @@
 	return ret;
 }
 
-static rwlock_t fasync_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(fasync_lock);
 static kmem_cache_t *fasync_cache;
 
 /*
diff -Nru a/fs/fifo.c b/fs/fifo.c
--- a/fs/fifo.c	2005-03-01 23:38:56 -08:00
+++ b/fs/fifo.c	2005-03-01 23:38:56 -08:00
@@ -135,12 +135,8 @@
 	goto err;
 
 err:
-	if (!PIPE_READERS(*inode) && !PIPE_WRITERS(*inode)) {
-		struct pipe_inode_info *info = inode->i_pipe;
-		inode->i_pipe = NULL;
-		free_page((unsigned long)info->base);
-		kfree(info);
-	}
+	if (!PIPE_READERS(*inode) && !PIPE_WRITERS(*inode))
+		free_pipe_info(inode);
 
 err_nocleanup:
 	up(PIPE_SEM(*inode));
diff -Nru a/fs/file.c b/fs/file.c
--- a/fs/file.c	2005-03-01 23:38:52 -08:00
+++ b/fs/file.c	2005-03-01 23:38:52 -08:00
@@ -53,7 +53,7 @@
  * spinlock held for write.
  */
 
-int expand_fd_array(struct files_struct *files, int nr)
+static int expand_fd_array(struct files_struct *files, int nr)
 	__releases(files->file_lock)
 	__acquires(files->file_lock)
 {
@@ -158,7 +158,7 @@
  * Expand the fdset in the files_struct.  Called with the files spinlock
  * held for write.
  */
-int expand_fdset(struct files_struct *files, int nr)
+static int expand_fdset(struct files_struct *files, int nr)
 	__releases(file->file_lock)
 	__acquires(file->file_lock)
 {
@@ -229,3 +229,26 @@
 	return error;
 }
 
+/*
+ * Expand files.
+ * Return <0 on error; 0 nothing done; 1 files expanded, we may have blocked.
+ * Should be called with the files->file_lock spinlock held for write.
+ */
+int expand_files(struct files_struct *files, int nr)
+{
+	int err, expand = 0;
+
+	if (nr >= files->max_fdset) {
+		expand = 1;
+		if ((err = expand_fdset(files, nr)))
+			goto out;
+	}
+	if (nr >= files->max_fds) {
+		expand = 1;
+		if ((err = expand_fd_array(files, nr)))
+			goto out;
+	}
+	err = expand;
+out:
+	return err;
+}
diff -Nru a/fs/file_table.c b/fs/file_table.c
--- a/fs/file_table.c	2005-03-01 23:38:51 -08:00
+++ b/fs/file_table.c	2005-03-01 23:38:51 -08:00
@@ -25,9 +25,9 @@
 EXPORT_SYMBOL(files_stat); /* Needed by unix.o */
 
 /* public. Not pretty! */
-spinlock_t __cacheline_aligned_in_smp files_lock = SPIN_LOCK_UNLOCKED;
+ __cacheline_aligned_in_smp DEFINE_SPINLOCK(files_lock);
 
-static spinlock_t filp_count_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(filp_count_lock);
 
 /* slab constructors and destructors are called from arbitrary
  * context and must be fully threaded - use a local spinlock
@@ -82,9 +82,10 @@
 			atomic_set(&f->f_count, 1);
 			f->f_uid = current->fsuid;
 			f->f_gid = current->fsgid;
-			f->f_owner.lock = RW_LOCK_UNLOCKED;
+			rwlock_init(&f->f_owner.lock);
 			/* f->f_version: 0 */
 			INIT_LIST_HEAD(&f->f_list);
+			f->f_maxcount = INT_MAX;
 			return f;
 		}
 	}
diff -Nru a/fs/filesystems.c b/fs/filesystems.c
--- a/fs/filesystems.c	2005-03-01 23:39:09 -08:00
+++ b/fs/filesystems.c	2005-03-01 23:39:09 -08:00
@@ -28,7 +28,7 @@
  */
 
 static struct file_system_type *file_systems;
-static rwlock_t file_systems_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(file_systems_lock);
 
 /* WARNING: This can be used only if we _already_ own a reference */
 void get_filesystem(struct file_system_type *fs)
diff -Nru a/fs/fs-writeback.c b/fs/fs-writeback.c
--- a/fs/fs-writeback.c	2005-03-01 23:39:18 -08:00
+++ b/fs/fs-writeback.c	2005-03-01 23:39:18 -08:00
@@ -378,6 +378,7 @@
 			list_move(&inode->i_list, &sb->s_dirty);
 		}
 		spin_unlock(&inode_lock);
+		cond_resched();
 		iput(inode);
 		spin_lock(&inode_lock);
 		if (wbc->nr_to_write <= 0)
@@ -557,22 +558,24 @@
  *	dirty. This is primarily needed by knfsd.
  */
  
-void write_inode_now(struct inode *inode, int sync)
+int write_inode_now(struct inode *inode, int sync)
 {
+	int ret;
 	struct writeback_control wbc = {
 		.nr_to_write = LONG_MAX,
 		.sync_mode = WB_SYNC_ALL,
 	};
 
 	if (inode->i_mapping->backing_dev_info->memory_backed)
-		return;
+		return 0;
 
 	might_sleep();
 	spin_lock(&inode_lock);
-	__writeback_single_inode(inode, &wbc);
+	ret = __writeback_single_inode(inode, &wbc);
 	spin_unlock(&inode_lock);
 	if (sync)
 		wait_on_inode(inode);
+	return ret;
 }
 EXPORT_SYMBOL(write_inode_now);
 
@@ -641,8 +644,11 @@
 		need_write_inode_now = 1;
 	spin_unlock(&inode_lock);
 
-	if (need_write_inode_now)
-		write_inode_now(inode, 1);
+	if (need_write_inode_now) {
+		err2 = write_inode_now(inode, 1);
+		if (!err)
+			err = err2;
+	}
 	else
 		wait_on_inode(inode);
 
diff -Nru a/fs/hfs/catalog.c b/fs/hfs/catalog.c
--- a/fs/hfs/catalog.c	2005-03-01 23:39:08 -08:00
+++ b/fs/hfs/catalog.c	2005-03-01 23:39:08 -08:00
@@ -121,7 +121,7 @@
 		goto err1;
 
 	dir->i_size++;
-	dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+	dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
 	mark_inode_dirty(dir);
 	hfs_find_exit(&fd);
 	return 0;
@@ -248,7 +248,7 @@
 	}
 
 	dir->i_size--;
-	dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+	dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
 	mark_inode_dirty(dir);
 	res = 0;
 out:
@@ -301,7 +301,7 @@
 	if (err)
 		goto out;
 	dst_dir->i_size++;
-	dst_dir->i_mtime = dst_dir->i_ctime = CURRENT_TIME;
+	dst_dir->i_mtime = dst_dir->i_ctime = CURRENT_TIME_SEC;
 	mark_inode_dirty(dst_dir);
 
 	/* finally remove the old entry */
@@ -313,7 +313,7 @@
 	if (err)
 		goto out;
 	src_dir->i_size--;
-	src_dir->i_mtime = src_dir->i_ctime = CURRENT_TIME;
+	src_dir->i_mtime = src_dir->i_ctime = CURRENT_TIME_SEC;
 	mark_inode_dirty(src_dir);
 
 	type = entry.type;
diff -Nru a/fs/hfs/dir.c b/fs/hfs/dir.c
--- a/fs/hfs/dir.c	2005-03-01 23:39:09 -08:00
+++ b/fs/hfs/dir.c	2005-03-01 23:39:09 -08:00
@@ -248,7 +248,7 @@
 
 	inode->i_nlink--;
 	hfs_delete_inode(inode);
-	inode->i_ctime = CURRENT_TIME;
+	inode->i_ctime = CURRENT_TIME_SEC;
 	mark_inode_dirty(inode);
 
 	return res;
@@ -274,7 +274,7 @@
 	if (res)
 		return res;
 	inode->i_nlink = 0;
-	inode->i_ctime = CURRENT_TIME;
+	inode->i_ctime = CURRENT_TIME_SEC;
 	hfs_delete_inode(inode);
 	mark_inode_dirty(inode);
 	return 0;
diff -Nru a/fs/hfs/inode.c b/fs/hfs/inode.c
--- a/fs/hfs/inode.c	2005-03-01 23:39:17 -08:00
+++ b/fs/hfs/inode.c	2005-03-01 23:39:17 -08:00
@@ -169,7 +169,7 @@
 	inode->i_uid = current->fsuid;
 	inode->i_gid = current->fsgid;
 	inode->i_nlink = 1;
-	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
+	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
 	inode->i_blksize = HFS_SB(sb)->alloc_blksz;
 	HFS_I(inode)->flags = 0;
 	HFS_I(inode)->rsrc_inode = NULL;
diff -Nru a/fs/hfsplus/catalog.c b/fs/hfsplus/catalog.c
--- a/fs/hfsplus/catalog.c	2005-03-01 23:38:58 -08:00
+++ b/fs/hfsplus/catalog.c	2005-03-01 23:38:58 -08:00
@@ -187,7 +187,7 @@
 		goto err1;
 
 	dir->i_size++;
-	dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+	dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
 	mark_inode_dirty(dir);
 	hfs_find_exit(&fd);
 	return 0;
@@ -269,7 +269,7 @@
 		goto out;
 
 	dir->i_size--;
-	dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+	dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
 	mark_inode_dirty(dir);
 out:
 	hfs_find_exit(&fd);
@@ -315,7 +315,7 @@
 	if (err)
 		goto out;
 	dst_dir->i_size++;
-	dst_dir->i_mtime = dst_dir->i_ctime = CURRENT_TIME;
+	dst_dir->i_mtime = dst_dir->i_ctime = CURRENT_TIME_SEC;
 	mark_inode_dirty(dst_dir);
 
 	/* finally remove the old entry */
@@ -327,7 +327,7 @@
 	if (err)
 		goto out;
 	src_dir->i_size--;
-	src_dir->i_mtime = src_dir->i_ctime = CURRENT_TIME;
+	src_dir->i_mtime = src_dir->i_ctime = CURRENT_TIME_SEC;
 	mark_inode_dirty(src_dir);
 
 	/* remove old thread entry */
diff -Nru a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c
--- a/fs/hfsplus/dir.c	2005-03-01 23:39:18 -08:00
+++ b/fs/hfsplus/dir.c	2005-03-01 23:39:18 -08:00
@@ -294,7 +294,7 @@
 	inode->i_nlink++;
 	hfsplus_instantiate(dst_dentry, inode, cnid);
 	atomic_inc(&inode->i_count);
-	inode->i_ctime = CURRENT_TIME;
+	inode->i_ctime = CURRENT_TIME_SEC;
 	mark_inode_dirty(inode);
 	HFSPLUS_SB(sb).file_count++;
 	sb->s_dirt = 1;
@@ -340,7 +340,7 @@
 		} else
 			inode->i_flags |= S_DEAD;
 	}
-	inode->i_ctime = CURRENT_TIME;
+	inode->i_ctime = CURRENT_TIME_SEC;
 	mark_inode_dirty(inode);
 
 	return res;
@@ -379,7 +379,7 @@
 	if (res)
 		return res;
 	inode->i_nlink = 0;
-	inode->i_ctime = CURRENT_TIME;
+	inode->i_ctime = CURRENT_TIME_SEC;
 	hfsplus_delete_inode(inode);
 	mark_inode_dirty(inode);
 	return 0;
diff -Nru a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c
--- a/fs/hfsplus/inode.c	2005-03-01 23:38:54 -08:00
+++ b/fs/hfsplus/inode.c	2005-03-01 23:38:54 -08:00
@@ -334,7 +334,7 @@
 	inode->i_uid = current->fsuid;
 	inode->i_gid = current->fsgid;
 	inode->i_nlink = 1;
-	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
+	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
 	inode->i_blksize = HFSPLUS_SB(sb).alloc_blksz;
 	INIT_LIST_HEAD(&HFSPLUS_I(inode).open_dir_list);
 	init_MUTEX(&HFSPLUS_I(inode).extents_lock);
diff -Nru a/fs/hfsplus/ioctl.c b/fs/hfsplus/ioctl.c
--- a/fs/hfsplus/ioctl.c	2005-03-01 23:38:54 -08:00
+++ b/fs/hfsplus/ioctl.c	2005-03-01 23:38:54 -08:00
@@ -73,7 +73,7 @@
 		else
 			HFSPLUS_I(inode).userflags &= ~HFSPLUS_FLG_NODUMP;
 
-		inode->i_ctime = CURRENT_TIME;
+		inode->i_ctime = CURRENT_TIME_SEC;
 		mark_inode_dirty(inode);
 		return 0;
 	}
diff -Nru a/fs/hostfs/hostfs.h b/fs/hostfs/hostfs.h
--- a/fs/hostfs/hostfs.h	2005-03-01 23:39:09 -08:00
+++ b/fs/hostfs/hostfs.h	2005-03-01 23:39:09 -08:00
@@ -16,8 +16,29 @@
 #define HOSTFS_ATTR_CTIME	64
 #define HOSTFS_ATTR_ATIME_SET	128
 #define HOSTFS_ATTR_MTIME_SET	256
+
+/* These two are unused by hostfs. */
 #define HOSTFS_ATTR_FORCE	512	/* Not a change, but a change it */
 #define HOSTFS_ATTR_ATTR_FLAG	1024
+
+/* If you are very careful, you'll notice that these two are missing:
+ *
+ * #define ATTR_KILL_SUID	2048
+ * #define ATTR_KILL_SGID	4096
+ *
+ * and this is because they were added in 2.5 development in this patch:
+ *
+ * http://linux.bkbits.net:8080/linux-2.5/
+ * cset@3caf4a12k4XgDzK7wyK-TGpSZ9u2Ww?nav=index.html
+ * |src/.|src/include|src/include/linux|related/include/linux/fs.h
+ *
+ * Actually, they are not needed by most ->setattr() methods - they are set by
+ * callers of notify_change() to notify that the setuid/setgid bits must be
+ * dropped.
+ * notify_change() will delete those flags, make sure attr->ia_valid & ATTR_MODE
+ * is on, and remove the appropriate bits from attr->ia_mode (attr is a
+ * "struct iattr *"). -BlaisorBlade
+ */
 
 struct hostfs_iattr {
 	unsigned int	ia_valid;
diff -Nru a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c
--- a/fs/hostfs/hostfs_kern.c	2005-03-01 23:38:53 -08:00
+++ b/fs/hostfs/hostfs_kern.c	2005-03-01 23:38:53 -08:00
@@ -15,7 +15,6 @@
 #include <linux/pagemap.h>
 #include <linux/blkdev.h>
 #include <linux/list.h>
-#include <linux/buffer_head.h>
 #include <linux/root_dev.h>
 #include <linux/statfs.h>
 #include <linux/kdev_t.h>
@@ -393,6 +392,11 @@
 static struct file_operations hostfs_file_fops = {
 	.llseek		= generic_file_llseek,
 	.read		= generic_file_read,
+	.sendfile	= generic_file_sendfile,
+	.aio_read	= generic_file_aio_read,
+	.aio_write	= generic_file_aio_write,
+	.readv		= generic_file_readv,
+	.writev		= generic_file_writev,
 	.write		= generic_file_write,
 	.mmap		= generic_file_mmap,
 	.open		= hostfs_file_open,
@@ -401,6 +405,7 @@
 };
 
 static struct file_operations hostfs_dir_fops = {
+	.llseek		= generic_file_llseek,
 	.readdir	= hostfs_readdir,
 	.read		= generic_read_dir,
 };
@@ -817,6 +822,10 @@
 	struct hostfs_iattr attrs;
 	char *name;
 	int err;
+
+	err = inode_change_ok(dentry->d_inode, attr);
+	if (err)
+		return err;
 
 	if(append)
 		attr->ia_valid &= ~ATTR_SIZE;
diff -Nru a/fs/hpfs/file.c b/fs/hpfs/file.c
--- a/fs/hpfs/file.c	2005-03-01 23:39:17 -08:00
+++ b/fs/hpfs/file.c	2005-03-01 23:39:17 -08:00
@@ -116,7 +116,7 @@
 	retval = generic_file_write(file, buf, count, ppos);
 	if (retval > 0) {
 		struct inode *inode = file->f_dentry->d_inode;
-		inode->i_mtime = CURRENT_TIME;
+		inode->i_mtime = CURRENT_TIME_SEC;
 		hpfs_i(inode)->i_dirty = 1;
 	}
 	return retval;
diff -Nru a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
--- a/fs/hugetlbfs/inode.c	2005-03-01 23:39:10 -08:00
+++ b/fs/hugetlbfs/inode.c	2005-03-01 23:39:10 -08:00
@@ -168,7 +168,7 @@
 	return -EINVAL;
 }
 
-void huge_pagevec_release(struct pagevec *pvec)
+static void huge_pagevec_release(struct pagevec *pvec)
 {
 	int i;
 
@@ -178,7 +178,7 @@
 	pagevec_reinit(pvec);
 }
 
-void truncate_huge_page(struct page *page)
+static void truncate_huge_page(struct page *page)
 {
 	clear_page_dirty(page);
 	ClearPageUptodate(page);
@@ -186,7 +186,7 @@
 	put_page(page);
 }
 
-void truncate_hugepages(struct address_space *mapping, loff_t lstart)
+static void truncate_hugepages(struct address_space *mapping, loff_t lstart)
 {
 	const pgoff_t start = lstart >> HPAGE_SHIFT;
 	struct pagevec pvec;
@@ -225,6 +225,7 @@
 
 	hlist_del_init(&inode->i_hash);
 	list_del_init(&inode->i_list);
+	list_del_init(&inode->i_sb_list);
 	inode->i_state |= I_FREEING;
 	inodes_stat.nr_inodes--;
 	spin_unlock(&inode_lock);
@@ -267,6 +268,7 @@
 	hlist_del_init(&inode->i_hash);
 out_truncate:
 	list_del_init(&inode->i_list);
+	list_del_init(&inode->i_sb_list);
 	inode->i_state |= I_FREEING;
 	inodes_stat.nr_inodes--;
 	spin_unlock(&inode_lock);
@@ -493,7 +495,7 @@
 /*
  * For direct-IO reads into hugetlb pages
  */
-int hugetlbfs_set_page_dirty(struct page *page)
+static int hugetlbfs_set_page_dirty(struct page *page)
 {
 	return 0;
 }
@@ -670,6 +672,7 @@
 	sb->s_blocksize_bits = HPAGE_SHIFT;
 	sb->s_magic = HUGETLBFS_MAGIC;
 	sb->s_op = &hugetlbfs_ops;
+	sb->s_time_gran = 1;
 	inode = hugetlbfs_get_inode(sb, config.uid, config.gid,
 					S_IFDIR | config.mode, 0);
 	if (!inode)
@@ -734,7 +737,7 @@
  */
 static unsigned long hugetlbfs_counter(void)
 {
-	static spinlock_t lock = SPIN_LOCK_UNLOCKED;
+	static DEFINE_SPINLOCK(lock);
 	static unsigned long counter;
 	unsigned long ret;
 
diff -Nru a/fs/inode.c b/fs/inode.c
--- a/fs/inode.c	2005-03-01 23:39:17 -08:00
+++ b/fs/inode.c	2005-03-01 23:39:17 -08:00
@@ -80,7 +80,7 @@
  * NOTE! You also have to own the lock if you change
  * the i_state of an inode while it is in use..
  */
-spinlock_t inode_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(inode_lock);
 
 /*
  * iprune_sem provides exclusion between the kswapd or try_to_free_pages
@@ -198,10 +198,9 @@
 	INIT_RADIX_TREE(&inode->i_data.page_tree, GFP_ATOMIC);
 	spin_lock_init(&inode->i_data.tree_lock);
 	spin_lock_init(&inode->i_data.i_mmap_lock);
-	atomic_set(&inode->i_data.truncate_count, 0);
 	INIT_LIST_HEAD(&inode->i_data.private_list);
 	spin_lock_init(&inode->i_data.private_lock);
-	INIT_PRIO_TREE_ROOT(&inode->i_data.i_mmap);
+	INIT_RAW_PRIO_TREE_ROOT(&inode->i_data.i_mmap);
 	INIT_LIST_HEAD(&inode->i_data.i_mmap_nonlinear);
 	spin_lock_init(&inode->i_lock);
 	i_size_ordered_init(inode);
@@ -296,7 +295,7 @@
 /*
  * Invalidate all inodes for a device.
  */
-static int invalidate_list(struct list_head *head, struct super_block * sb, struct list_head * dispose)
+static int invalidate_list(struct list_head *head, struct list_head *dispose)
 {
 	struct list_head *next;
 	int busy = 0, count = 0;
@@ -306,15 +305,22 @@
 		struct list_head * tmp = next;
 		struct inode * inode;
 
+		/*
+		 * We can reschedule here without worrying about the list's
+		 * consistency because the per-sb list of inodes must not
+		 * change during umount anymore, and because iprune_sem keeps
+		 * shrink_icache_memory() away.
+		 */
+		cond_resched_lock(&inode_lock);
+
 		next = next->next;
 		if (tmp == head)
 			break;
-		inode = list_entry(tmp, struct inode, i_list);
-		if (inode->i_sb != sb)
-			continue;
+		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++;
@@ -350,10 +356,7 @@
 
 	down(&iprune_sem);
 	spin_lock(&inode_lock);
-	busy = invalidate_list(&inode_in_use, sb, &throw_away);
-	busy |= invalidate_list(&inode_unused, sb, &throw_away);
-	busy |= invalidate_list(&sb->s_dirty, sb, &throw_away);
-	busy |= invalidate_list(&sb->s_io, sb, &throw_away);
+	busy = invalidate_list(&sb->s_inodes, &throw_away);
 	spin_unlock(&inode_lock);
 
 	dispose_list(&throw_away);
@@ -453,6 +456,7 @@
 				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++;
@@ -564,6 +568,7 @@
 		spin_lock(&inode_lock);
 		inodes_stat.nr_inodes++;
 		list_add(&inode->i_list, &inode_in_use);
+		list_add(&inode->i_sb_list, &sb->s_inodes);
 		inode->i_ino = ++last_ino;
 		inode->i_state = 0;
 		spin_unlock(&inode_lock);
@@ -612,6 +617,7 @@
 
 			inodes_stat.nr_inodes++;
 			list_add(&inode->i_list, &inode_in_use);
+			list_add(&inode->i_sb_list, &sb->s_inodes);
 			hlist_add_head(&inode->i_hash, head);
 			inode->i_state = I_LOCK|I_NEW;
 			spin_unlock(&inode_lock);
@@ -660,6 +666,7 @@
 			inode->i_ino = ino;
 			inodes_stat.nr_inodes++;
 			list_add(&inode->i_list, &inode_in_use);
+			list_add(&inode->i_sb_list, &sb->s_inodes);
 			hlist_add_head(&inode->i_hash, head);
 			inode->i_state = I_LOCK|I_NEW;
 			spin_unlock(&inode_lock);
@@ -996,6 +1003,7 @@
 	struct super_operations *op = inode->i_sb->s_op;
 
 	list_del_init(&inode->i_list);
+	list_del_init(&inode->i_sb_list);
 	inode->i_state|=I_FREEING;
 	inodes_stat.nr_inodes--;
 	spin_unlock(&inode_lock);
@@ -1041,6 +1049,7 @@
 		hlist_del_init(&inode->i_hash);
 	}
 	list_del_init(&inode->i_list);
+	list_del_init(&inode->i_sb_list);
 	inode->i_state|=I_FREEING;
 	inodes_stat.nr_inodes--;
 	spin_unlock(&inode_lock);
@@ -1130,19 +1139,6 @@
 
 EXPORT_SYMBOL(bmap);
 
-/*
- * Return true if the filesystem which backs this inode considers the two
- * passed timespecs to be sufficiently different to warrant flushing the
- * altered time out to disk.
- */
-static int inode_times_differ(struct inode *inode,
-			struct timespec *old, struct timespec *new)
-{
-	if (IS_ONE_SECOND(inode))
-		return old->tv_sec != new->tv_sec;
-	return !timespec_equal(old, new);
-}
-
 /**
  *	update_atime	-	update the access time
  *	@inode: inode accessed
@@ -1162,8 +1158,8 @@
 	if (IS_RDONLY(inode))
 		return;
 
-	now = current_kernel_time();
-	if (inode_times_differ(inode, &inode->i_atime, &now)) {
+	now = current_fs_time(inode->i_sb);
+	if (!timespec_equal(&inode->i_atime, &now)) {
 		inode->i_atime = now;
 		mark_inode_dirty_sync(inode);
 	} else {
@@ -1193,14 +1189,13 @@
 	if (IS_RDONLY(inode))
 		return;
 
-	now = current_kernel_time();
-
-	if (inode_times_differ(inode, &inode->i_mtime, &now))
+	now = current_fs_time(inode->i_sb);
+	if (!timespec_equal(&inode->i_mtime, &now))
 		sync_it = 1;
 	inode->i_mtime = now;
 
 	if (ctime_too) {
-		if (inode_times_differ(inode, &inode->i_ctime, &now))
+		if (!timespec_equal(&inode->i_ctime, &now))
 			sync_it = 1;
 		inode->i_ctime = now;
 	}
@@ -1229,36 +1224,23 @@
 /* Function back in dquot.c */
 int remove_inode_dquot_ref(struct inode *, int, struct list_head *);
 
-void remove_dquot_ref(struct super_block *sb, int type, struct list_head *tofree_head)
+void remove_dquot_ref(struct super_block *sb, int type,
+			struct list_head *tofree_head)
 {
 	struct inode *inode;
-	struct list_head *act_head;
 
 	if (!sb->dq_op)
 		return;	/* nothing to do */
 	spin_lock(&inode_lock);	/* This lock is for inodes code */
 
-	/* We hold dqptr_sem so we are safe against the quota code */
-	list_for_each(act_head, &inode_in_use) {
-		inode = list_entry(act_head, struct inode, i_list);
-		if (inode->i_sb == sb && !IS_NOQUOTA(inode))
-			remove_inode_dquot_ref(inode, type, tofree_head);
-	}
-	list_for_each(act_head, &inode_unused) {
-		inode = list_entry(act_head, struct inode, i_list);
-		if (inode->i_sb == sb && !IS_NOQUOTA(inode))
-			remove_inode_dquot_ref(inode, type, tofree_head);
-	}
-	list_for_each(act_head, &sb->s_dirty) {
-		inode = list_entry(act_head, struct inode, i_list);
-		if (!IS_NOQUOTA(inode))
-			remove_inode_dquot_ref(inode, type, tofree_head);
-	}
-	list_for_each(act_head, &sb->s_io) {
-		inode = list_entry(act_head, struct inode, i_list);
+	/*
+	 * We don't have to lock against quota code - test IS_QUOTAINIT is
+	 * just for speedup...
+	 */
+	list_for_each_entry(inode, &sb->s_inodes, i_sb_list)
 		if (!IS_NOQUOTA(inode))
 			remove_inode_dquot_ref(inode, type, tofree_head);
-	}
+
 	spin_unlock(&inode_lock);
 }
 
@@ -1328,14 +1310,21 @@
 {
 	int loop;
 
+	/* If hashes are distributed across NUMA nodes, defer
+	 * hash allocation until vmalloc space is available.
+	 */
+	if (hashdist)
+		return;
+
 	inode_hashtable =
 		alloc_large_system_hash("Inode-cache",
 					sizeof(struct hlist_head),
 					ihash_entries,
 					14,
-					0,
+					HASH_EARLY,
 					&i_hash_shift,
-					&i_hash_mask);
+					&i_hash_mask,
+					0);
 
 	for (loop = 0; loop < (1 << i_hash_shift); loop++)
 		INIT_HLIST_HEAD(&inode_hashtable[loop]);
@@ -1343,10 +1332,29 @@
 
 void __init inode_init(unsigned long mempages)
 {
+	int loop;
+
 	/* inode slab cache */
 	inode_cachep = kmem_cache_create("inode_cache", sizeof(struct inode),
 				0, SLAB_PANIC, init_once, NULL);
 	set_shrinker(DEFAULT_SEEKS, shrink_icache_memory);
+
+	/* Hash may have been set up in inode_init_early */
+	if (!hashdist)
+		return;
+
+	inode_hashtable =
+		alloc_large_system_hash("Inode-cache",
+					sizeof(struct hlist_head),
+					ihash_entries,
+					14,
+					0,
+					&i_hash_shift,
+					&i_hash_mask,
+					0);
+
+	for (loop = 0; loop < (1 << i_hash_shift); loop++)
+		INIT_HLIST_HEAD(&inode_hashtable[loop]);
 }
 
 void init_special_inode(struct inode *inode, umode_t mode, dev_t rdev)
diff -Nru a/fs/ioctl.c b/fs/ioctl.c
--- a/fs/ioctl.c	2005-03-01 23:38:53 -08:00
+++ b/fs/ioctl.c	2005-03-01 23:38:53 -08:00
@@ -16,7 +16,32 @@
 #include <asm/uaccess.h>
 #include <asm/ioctls.h>
 
-static int file_ioctl(struct file *filp,unsigned int cmd,unsigned long arg)
+static long do_ioctl(struct file *filp, unsigned int cmd,
+		unsigned long arg)
+{
+	int error = -ENOTTY;
+
+	if (!filp->f_op)
+		goto out;
+
+	if (filp->f_op->unlocked_ioctl) {
+		error = filp->f_op->unlocked_ioctl(filp, cmd, arg);
+		if (error == -ENOIOCTLCMD)
+			error = -EINVAL;
+		goto out;
+	} else if (filp->f_op->ioctl) {
+		lock_kernel();
+		error = filp->f_op->ioctl(filp->f_dentry->d_inode,
+					  filp, cmd, arg);
+		unlock_kernel();
+	}
+
+ out:
+	return error;
+}
+
+static int file_ioctl(struct file *filp, unsigned int cmd,
+		unsigned long arg)
 {
 	int error;
 	int block;
@@ -36,7 +61,9 @@
 			if ((error = get_user(block, p)) != 0)
 				return error;
 
+			lock_kernel();
 			res = mapping->a_ops->bmap(mapping, block);
+			unlock_kernel();
 			return put_user(res, p);
 		}
 		case FIGETBSZ:
@@ -46,29 +73,22 @@
 		case FIONREAD:
 			return put_user(i_size_read(inode) - filp->f_pos, p);
 	}
-	if (filp->f_op && filp->f_op->ioctl)
-		return filp->f_op->ioctl(inode, filp, cmd, arg);
-	return -ENOTTY;
-}
 
+	return do_ioctl(filp, cmd, arg);
+}
 
-asmlinkage long sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
-{	
-	struct file * filp;
+/*
+ * When you add any new common ioctls to the switches above and below
+ * please update compat_sys_ioctl() too.
+ *
+ * vfs_ioctl() is not for drivers and not intended to be EXPORT_SYMBOL()'d.
+ * It's just a simple helper for sys_ioctl and compat_sys_ioctl.
+ */
+int vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd, unsigned long arg)
+{
 	unsigned int flag;
-	int on, error = -EBADF;
+	int on, error = 0;
 
-	filp = fget(fd);
-	if (!filp)
-		goto out;
-
-	error = security_file_ioctl(filp, cmd, arg);
-	if (error) {
-                fput(filp);
-                goto out;
-        }
-
-	lock_kernel();
 	switch (cmd) {
 		case FIOCLEX:
 			set_close_on_exec(fd, 1);
@@ -100,8 +120,11 @@
 
 			/* Did FASYNC state change ? */
 			if ((flag ^ filp->f_flags) & FASYNC) {
-				if (filp->f_op && filp->f_op->fasync)
+				if (filp->f_op && filp->f_op->fasync) {
+					lock_kernel();
 					error = filp->f_op->fasync(fd, filp, on);
+					unlock_kernel();
+				}
 				else error = -ENOTTY;
 			}
 			if (error != 0)
@@ -124,16 +147,33 @@
 				error = -ENOTTY;
 			break;
 		default:
-			error = -ENOTTY;
 			if (S_ISREG(filp->f_dentry->d_inode->i_mode))
 				error = file_ioctl(filp, cmd, arg);
-			else if (filp->f_op && filp->f_op->ioctl)
-				error = filp->f_op->ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
+			else
+				error = do_ioctl(filp, cmd, arg);
+			break;
 	}
-	unlock_kernel();
-	fput(filp);
+	return error;
+}
+
+asmlinkage long sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	struct file * filp;
+	int error = -EBADF;
+	int fput_needed;
+
+	filp = fget_light(fd, &fput_needed);
+	if (!filp)
+		goto out;
+
+	error = security_file_ioctl(filp, cmd, arg);
+	if (error)
+		goto out_fput;
 
-out:
+	error = vfs_ioctl(filp, fd, cmd, arg);
+ out_fput:
+	fput_light(filp, fput_needed);
+ out:
 	return error;
 }
 
diff -Nru a/fs/isofs/compress.c b/fs/isofs/compress.c
--- a/fs/isofs/compress.c	2005-03-01 23:38:52 -08:00
+++ b/fs/isofs/compress.c	2005-03-01 23:38:52 -08:00
@@ -28,7 +28,6 @@
 #include <linux/string.h>
 #include <linux/slab.h>
 #include <linux/errno.h>
-#include <linux/cdrom.h>
 #include <linux/init.h>
 #include <linux/nls.h>
 #include <linux/ctype.h>
diff -Nru a/fs/jbd/checkpoint.c b/fs/jbd/checkpoint.c
--- a/fs/jbd/checkpoint.c	2005-03-01 23:39:18 -08:00
+++ b/fs/jbd/checkpoint.c	2005-03-01 23:39:18 -08:00
@@ -333,6 +333,10 @@
 				break;
 			}
 			retry = __flush_buffer(journal, jh, bhs, &batch_count, &drop_count);
+			if (cond_resched_lock(&journal->j_list_lock)) {
+				retry = 1;
+				break;
+			}
 		} while (jh != last_jh && !retry);
 
 		if (batch_count)
@@ -487,6 +491,14 @@
 				/* Use trylock because of the ranknig */
 				if (jbd_trylock_bh_state(jh2bh(jh)))
 					ret += __try_to_free_cp_buf(jh);
+				/*
+				 * This function only frees up some memory
+				 * if possible so we dont have an obligation
+				 * to finish processing. Bail out if preemption
+				 * requested:
+				 */
+				if (need_resched())
+					goto out;
 			} while (jh != last_jh);
 		}
 	} while (transaction != last_transaction);
diff -Nru a/fs/jbd/commit.c b/fs/jbd/commit.c
--- a/fs/jbd/commit.c	2005-03-01 23:39:09 -08:00
+++ b/fs/jbd/commit.c	2005-03-01 23:39:09 -08:00
@@ -262,7 +262,7 @@
 			__journal_file_buffer(jh, commit_transaction,
 						BJ_Locked);
 			jbd_unlock_bh_state(bh);
-			if (need_resched()) {
+			if (lock_need_resched(&journal->j_list_lock)) {
 				spin_unlock(&journal->j_list_lock);
 				goto write_out_data;
 			}
@@ -288,7 +288,7 @@
 				jbd_unlock_bh_state(bh);
 				journal_remove_journal_head(bh);
 				put_bh(bh);
-				if (need_resched()) {
+				if (lock_need_resched(&journal->j_list_lock)) {
 					spin_unlock(&journal->j_list_lock);
 					goto write_out_data;
 				}
@@ -333,14 +333,13 @@
 			jbd_unlock_bh_state(bh);
 		}
 		put_bh(bh);
-		if (need_resched()) {
-			spin_unlock(&journal->j_list_lock);
-			cond_resched();
-			spin_lock(&journal->j_list_lock);
-		}
+		cond_resched_lock(&journal->j_list_lock);
 	}
 	spin_unlock(&journal->j_list_lock);
 
+	if (err)
+		__journal_abort_hard(journal);
+
 	journal_write_revoke_records(journal, commit_transaction);
 
 	jbd_debug(3, "JBD: commit phase 2\n");
@@ -545,6 +544,8 @@
 			wait_on_buffer(bh);
 			goto wait_for_iobuf;
 		}
+		if (cond_resched())
+			goto wait_for_iobuf;
 
 		if (unlikely(!buffer_uptodate(bh)))
 			err = -EIO;
@@ -599,6 +600,8 @@
 			wait_on_buffer(bh);
 			goto wait_for_ctlbuf;
 		}
+		if (cond_resched())
+			goto wait_for_ctlbuf;
 
 		if (unlikely(!buffer_uptodate(bh)))
 			err = -EIO;
@@ -695,6 +698,7 @@
 	J_ASSERT(commit_transaction->t_shadow_list == NULL);
 	J_ASSERT(commit_transaction->t_log_list == NULL);
 
+restart_loop:
 	while (commit_transaction->t_forget) {
 		transaction_t *cp_transaction;
 		struct buffer_head *bh;
@@ -768,6 +772,8 @@
 			release_buffer_page(bh);
 		}
 		spin_unlock(&journal->j_list_lock);
+		if (cond_resched())
+			goto restart_loop;
 	}
 
 	/* Done with this transaction! */
diff -Nru a/fs/jbd/recovery.c b/fs/jbd/recovery.c
--- a/fs/jbd/recovery.c	2005-03-01 23:39:19 -08:00
+++ b/fs/jbd/recovery.c	2005-03-01 23:39:19 -08:00
@@ -354,6 +354,8 @@
 		struct buffer_head *	obh;
 		struct buffer_head *	nbh;
 
+		cond_resched();		/* We're under lock_kernel() */
+
 		/* If we already know where to stop the log traversal,
 		 * check right now that we haven't gone past the end of
 		 * the log. */
diff -Nru a/fs/jbd/revoke.c b/fs/jbd/revoke.c
--- a/fs/jbd/revoke.c	2005-03-01 23:38:52 -08:00
+++ b/fs/jbd/revoke.c	2005-03-01 23:38:52 -08:00
@@ -376,7 +376,12 @@
            first having the revoke cancelled: it's illegal to free a
            block twice without allocating it in between! */
 	if (bh) {
-		J_ASSERT_BH(bh, !buffer_revoked(bh));
+		if (!J_EXPECT_BH(bh, !buffer_revoked(bh),
+				 "inconsistent data on disk")) {
+			if (!bh_in)
+				brelse(bh);
+			return -EIO;
+		}
 		set_buffer_revoked(bh);
 		set_buffer_revokevalid(bh);
 		if (bh_in) {
diff -Nru a/fs/jbd/transaction.c b/fs/jbd/transaction.c
--- a/fs/jbd/transaction.c	2005-03-01 23:38:54 -08:00
+++ b/fs/jbd/transaction.c	2005-03-01 23:38:54 -08:00
@@ -1198,11 +1198,12 @@
  * Allow this call even if the handle has aborted --- it may be part of
  * the caller's cleanup after an abort.
  */
-void journal_forget(handle_t *handle, struct buffer_head *bh)
+int journal_forget (handle_t *handle, struct buffer_head *bh)
 {
 	transaction_t *transaction = handle->h_transaction;
 	journal_t *journal = transaction->t_journal;
 	struct journal_head *jh;
+	int err = 0;
 
 	BUFFER_TRACE(bh, "entry");
 
@@ -1213,6 +1214,14 @@
 		goto not_jbd;
 	jh = bh2jh(bh);
 
+	/* Critical error: attempting to delete a bitmap buffer, maybe?
+	 * Don't do any jbd operations, and return an error. */
+	if (!J_EXPECT_JH(jh, !jh->b_committed_data,
+			 "inconsistent data on disk")) {
+		err = -EIO;
+		goto not_jbd;
+	}
+
 	if (jh->b_transaction == handle->h_transaction) {
 		J_ASSERT_JH(jh, !jh->b_frozen_data);
 
@@ -1223,7 +1232,6 @@
 		clear_buffer_jbddirty(bh);
 
 		JBUFFER_TRACE(jh, "belongs to current transaction: unfile");
-		J_ASSERT_JH(jh, !jh->b_committed_data);
 
 		__journal_unfile_buffer(jh);
 
@@ -1248,7 +1256,7 @@
 				spin_unlock(&journal->j_list_lock);
 				jbd_unlock_bh_state(bh);
 				__bforget(bh);
-				return;
+				return 0;
 			}
 		}
 	} else if (jh->b_transaction) {
@@ -1270,7 +1278,7 @@
 	spin_unlock(&journal->j_list_lock);
 	jbd_unlock_bh_state(bh);
 	__brelse(bh);
-	return;
+	return err;
 }
 
 /**
diff -Nru a/fs/jffs/inode-v23.c b/fs/jffs/inode-v23.c
--- a/fs/jffs/inode-v23.c	2005-03-01 23:38:59 -08:00
+++ b/fs/jffs/inode-v23.c	2005-03-01 23:38:59 -08:00
@@ -298,7 +298,7 @@
 		if (len) {
 			invalidate_inode_pages(inode->i_mapping);
 		}
-		inode->i_ctime = CURRENT_TIME;
+		inode->i_ctime = CURRENT_TIME_SEC;
 		inode->i_mtime = inode->i_ctime;
 	}
 	if (update_all || iattr->ia_valid & ATTR_ATIME) {
@@ -548,7 +548,7 @@
 	/* This is a kind of update of the inode we're about to make
 	   here.  This is what they do in ext2fs.  Kind of.  */
 	if ((inode = iget(new_dir->i_sb, f->ino))) {
-		inode->i_ctime = CURRENT_TIME;
+		inode->i_ctime = CURRENT_TIME_SEC;
 		mark_inode_dirty(inode);
 		iput(inode);
 	}
@@ -1051,7 +1051,7 @@
 	   from the in-memory file system structures.  */
 	jffs_insert_node(c, del_f, &raw_inode, NULL, del_node);
 
-	dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+	dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
 	mark_inode_dirty(dir);
 	inode->i_nlink--;
 	inode->i_ctime = dir->i_ctime;
@@ -1518,7 +1518,7 @@
 		inode->i_size = pos;
 		inode->i_blocks = (inode->i_size + 511) >> 9;
 	}
-	inode->i_ctime = inode->i_mtime = CURRENT_TIME;
+	inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC;
 	mark_inode_dirty(inode);
 	invalidate_inode_pages(inode->i_mapping);
 
diff -Nru a/fs/jffs2/Makefile b/fs/jffs2/Makefile
--- a/fs/jffs2/Makefile	2005-03-01 23:39:18 -08:00
+++ b/fs/jffs2/Makefile	2005-03-01 23:39:18 -08:00
@@ -1,7 +1,7 @@
 #
 # Makefile for the Linux Journalling Flash File System v2 (JFFS2)
 #
-# $Id: Makefile.common,v 1.6 2004/07/16 15:17:57 dwmw2 Exp $
+# $Id: Makefile.common,v 1.7 2004/11/03 12:57:38 jwboyer Exp $
 #
 
 obj-$(CONFIG_JFFS2_FS) += jffs2.o
@@ -12,6 +12,7 @@
 jffs2-y	+= super.o
 
 jffs2-$(CONFIG_JFFS2_FS_NAND)	+= wbuf.o
+jffs2-$(CONFIG_JFFS2_FS_NOR_ECC) += wbuf.o
 jffs2-$(CONFIG_JFFS2_RUBIN)	+= compr_rubin.o
 jffs2-$(CONFIG_JFFS2_RTIME)	+= compr_rtime.o
 jffs2-$(CONFIG_JFFS2_ZLIB)	+= compr_zlib.o
diff -Nru a/fs/jffs2/README.Locking b/fs/jffs2/README.Locking
--- a/fs/jffs2/README.Locking	2005-03-01 23:38:55 -08:00
+++ b/fs/jffs2/README.Locking	2005-03-01 23:38:55 -08:00
@@ -1,4 +1,4 @@
-	$Id: README.Locking,v 1.4 2002/03/08 16:20:06 dwmw2 Exp $
+	$Id: README.Locking,v 1.9 2004/11/20 10:35:40 dwmw2 Exp $
 
 	JFFS2 LOCKING DOCUMENTATION
 	---------------------------
@@ -80,10 +80,10 @@
 (NB) the per-inode list of physical nodes. The latter is a special
 case - see below.
 
-As the MTD API permits erase-completion callback functions to be
-called from bottom-half (timer) context, and these functions access
-the data structures protected by this lock, it must be locked with
-spin_lock_bh().
+As the MTD API no longer permits erase-completion callback functions
+to be called from bottom-half (timer) context (on the basis that nobody
+ever actually implemented such a thing), it's now sufficient to use
+a simple spin_lock() rather than spin_lock_bh().
 
 Note that the per-inode list of physical nodes (f->nodes) is a special
 case. Any changes to _valid_ nodes (i.e. ->flash_offset & 1 == 0) in
@@ -99,8 +99,27 @@
 GC thread locks it, sends the signal, then unlocks it - while the GC
 thread itself locks it, zeroes c->gc_task, then unlocks on the exit path.
 
-	node_free_sem
-	-------------
+
+	inocache_lock spinlock
+	----------------------
+
+This spinlock protects the hashed list (c->inocache_list) of the
+in-core jffs2_inode_cache objects (each inode in JFFS2 has the
+correspondent jffs2_inode_cache object). So, the inocache_lock
+has to be locked while walking the c->inocache_list hash buckets.
+
+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. 
+
+Ordering constraints: 
+
+	If both erase_completion_lock and inocache_lock are needed, the
+	c->erase_completion has to be acquired first.
+
+
+	erase_free_sem
+	--------------
 
 This semaphore is only used by the erase code which frees obsolete
 node references and the jffs2_garbage_collect_deletion_dirent()
@@ -114,3 +133,16 @@
 collection code is looking at them.
 
 Suggestions for alternative solutions to this problem would be welcomed.
+
+
+	wbuf_sem
+	--------
+
+This read/write semaphore protects against concurrent access to the
+write-behind buffer ('wbuf') used for flash chips where we must write
+in blocks. It protects both the contents of the wbuf and the metadata
+which indicates which flash region (if any) is currently covered by 
+the buffer.
+
+Ordering constraints:
+	Lock wbuf_sem last, after the alloc_sem or and f->sem.
diff -Nru a/fs/jffs2/background.c b/fs/jffs2/background.c
--- a/fs/jffs2/background.c	2005-03-01 23:38:44 -08:00
+++ b/fs/jffs2/background.c	2005-03-01 23:38:44 -08:00
@@ -3,11 +3,11 @@
  *
  * Copyright (C) 2001-2003 Red Hat, Inc.
  *
- * Created by David Woodhouse <dwmw2@redhat.com>
+ * Created by David Woodhouse <dwmw2@infradead.org>
  *
  * For licensing information, see the file 'LICENCE' in this directory.
  *
- * $Id: background.c,v 1.49 2004/07/13 08:56:40 dwmw2 Exp $
+ * $Id: background.c,v 1.50 2004/11/16 20:36:10 dwmw2 Exp $
  *
  */
 
@@ -15,7 +15,6 @@
 #include <linux/jffs2.h>
 #include <linux/mtd/mtd.h>
 #include <linux/completion.h>
-#include <linux/suspend.h>
 #include "nodelist.h"
 
 
@@ -93,12 +92,8 @@
 			schedule();
 		}
 
-		if (current->flags & PF_FREEZE) {
-			refrigerator(0);
-			/* refrigerator() should recalc sigpending for us
-			   but doesn't. No matter - allow_signal() will. */
+		if (try_to_freeze(0))
 			continue;
-		}
 
 		cond_resched();
 
diff -Nru a/fs/jffs2/build.c b/fs/jffs2/build.c
--- a/fs/jffs2/build.c	2005-03-01 23:38:57 -08:00
+++ b/fs/jffs2/build.c	2005-03-01 23:38:57 -08:00
@@ -3,17 +3,19 @@
  *
  * Copyright (C) 2001-2003 Red Hat, Inc.
  *
- * Created by David Woodhouse <dwmw2@redhat.com>
+ * Created by David Woodhouse <dwmw2@infradead.org>
  *
  * For licensing information, see the file 'LICENCE' in this directory.
  *
- * $Id: build.c,v 1.55 2003/10/28 17:02:44 dwmw2 Exp $
+ * $Id: build.c,v 1.69 2004/12/16 20:22:18 dmarlin Exp $
  *
  */
 
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/mtd/mtd.h>
 #include "nodelist.h"
 
 static void jffs2_build_remove_unlinked_inode(struct jffs2_sb_info *, struct jffs2_inode_cache *, struct jffs2_full_dirent **);
@@ -62,6 +64,7 @@
 		if (!child_ic) {
 			printk(KERN_NOTICE "Eep. Child \"%s\" (ino #%u) of dir ino #%u doesn't exist!\n",
 				  fd->name, fd->ino, ic->ino);
+			jffs2_mark_node_obsolete(c, fd->raw);
 			continue;
 		}
 
@@ -88,6 +91,7 @@
 	int ret;
 	int i;
 	struct jffs2_inode_cache *ic;
+	struct jffs2_full_dirent *fd;
 	struct jffs2_full_dirent *dead_fds = NULL;
 
 	/* First, scan the medium and build all the inode caches with
@@ -95,13 +99,11 @@
 
 	c->flags |= JFFS2_SB_FLAG_MOUNTING;
 	ret = jffs2_scan_medium(c);
-	c->flags &= ~JFFS2_SB_FLAG_MOUNTING;
-
 	if (ret)
-		return ret;
+		goto exit;
 
 	D1(printk(KERN_DEBUG "Scanned flash completely\n"));
-	D1(jffs2_dump_block_lists(c));
+	D2(jffs2_dump_block_lists(c));
 
 	/* Now scan the directory tree, increasing nlink according to every dirent found. */
 	for_each_inode(i, c, ic) {
@@ -114,6 +116,8 @@
 			cond_resched();
 		}
 	}
+	c->flags &= ~JFFS2_SB_FLAG_MOUNTING;
+
 	D1(printk(KERN_DEBUG "Pass 1 complete\n"));
 
 	/* Next, scan for inodes with nlink == 0 and remove them. If
@@ -135,9 +139,7 @@
 	D1(printk(KERN_DEBUG "Pass 2a starting\n"));
 
 	while (dead_fds) {
-		struct jffs2_inode_cache *ic;
-		struct jffs2_full_dirent *fd = dead_fds;
-
+		fd = dead_fds;
 		dead_fds = fd->next;
 
 		ic = jffs2_get_ino_cache(c, fd->ino);
@@ -152,7 +154,6 @@
 	
 	/* Finally, we can scan again and free the dirent structs */
 	for_each_inode(i, c, ic) {
-		struct jffs2_full_dirent *fd;
 		D1(printk(KERN_DEBUG "Pass 3: ino #%u, ic %p, nodes %p\n", ic->ino, ic, ic->nodes));
 
 		while(ic->scan_dents) {
@@ -164,11 +165,24 @@
 		cond_resched();
 	}
 	D1(printk(KERN_DEBUG "Pass 3 complete\n"));
-	D1(jffs2_dump_block_lists(c));
+	D2(jffs2_dump_block_lists(c));
 
 	/* Rotate the lists by some number to ensure wear levelling */
 	jffs2_rotate_lists(c);
 
+	ret = 0;
+
+exit:
+	if (ret) {
+		for_each_inode(i, c, ic) {
+			while(ic->scan_dents) {
+				fd = ic->scan_dents;
+				ic->scan_dents = fd->next;
+				jffs2_free_full_dirent(fd);
+			}
+		}
+	}
+
 	return ret;
 }
 
@@ -179,9 +193,12 @@
 
 	D1(printk(KERN_DEBUG "JFFS2: Removing ino #%u with nlink == zero.\n", ic->ino));
 	
-	for (raw = ic->nodes; raw != (void *)ic; raw = raw->next_in_ino) {
+	raw = ic->nodes;
+	while (raw != (void *)ic) {
+		struct jffs2_raw_node_ref *next = raw->next_in_ino;
 		D1(printk(KERN_DEBUG "obsoleting node at 0x%08x\n", ref_offset(raw)));
 		jffs2_mark_node_obsolete(c, raw);
+		raw = next;
 	}
 
 	if (ic->scan_dents) {
@@ -297,7 +314,10 @@
 
 	c->free_size = c->flash_size;
 	c->nr_blocks = c->flash_size / c->sector_size;
-	c->blocks = kmalloc(sizeof(struct jffs2_eraseblock) * c->nr_blocks, GFP_KERNEL);
+ 	if (c->mtd->flags & MTD_NO_VIRTBLOCKS)
+		c->blocks = vmalloc(sizeof(struct jffs2_eraseblock) * c->nr_blocks);
+	else
+		c->blocks = kmalloc(sizeof(struct jffs2_eraseblock) * c->nr_blocks, GFP_KERNEL);
 	if (!c->blocks)
 		return -ENOMEM;
 	for (i=0; i<c->nr_blocks; i++) {
@@ -310,6 +330,7 @@
 		c->blocks[i].used_size = 0;
 		c->blocks[i].first_node = NULL;
 		c->blocks[i].last_node = NULL;
+		c->blocks[i].bad_count = 0;
 	}
 
 	init_MUTEX(&c->alloc_sem);
@@ -336,7 +357,11 @@
 		D1(printk(KERN_DEBUG "build_fs failed\n"));
 		jffs2_free_ino_caches(c);
 		jffs2_free_raw_node_refs(c);
-		kfree(c->blocks);
+		if (c->mtd->flags & MTD_NO_VIRTBLOCKS) {
+			vfree(c->blocks);
+		} else {
+			kfree(c->blocks);
+		}
 		return -EIO;
 	}
 
diff -Nru a/fs/jffs2/compr.c b/fs/jffs2/compr.c
--- a/fs/jffs2/compr.c	2005-03-01 23:38:54 -08:00
+++ b/fs/jffs2/compr.c	2005-03-01 23:38:54 -08:00
@@ -15,7 +15,7 @@
 
 #include "compr.h"
 
-static spinlock_t jffs2_compressor_list_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(jffs2_compressor_list_lock);
 
 /* Available compressors are on this list */
 static LIST_HEAD(jffs2_compressor_list);
diff -Nru a/fs/jffs2/compr_zlib.c b/fs/jffs2/compr_zlib.c
--- a/fs/jffs2/compr_zlib.c	2005-03-01 23:39:18 -08:00
+++ b/fs/jffs2/compr_zlib.c	2005-03-01 23:39:18 -08:00
@@ -3,11 +3,11 @@
  *
  * Copyright (C) 2001-2003 Red Hat, Inc.
  *
- * Created by David Woodhouse <dwmw2@redhat.com>
+ * Created by David Woodhouse <dwmw2@infradead.org>
  *
  * For licensing information, see the file 'LICENCE' in this directory.
  *
- * $Id: compr_zlib.c,v 1.28 2004/06/23 16:34:40 havasi Exp $
+ * $Id: compr_zlib.c,v 1.29 2004/11/16 20:36:11 dwmw2 Exp $
  *
  */
 
diff -Nru a/fs/jffs2/dir.c b/fs/jffs2/dir.c
--- a/fs/jffs2/dir.c	2005-03-01 23:39:09 -08:00
+++ b/fs/jffs2/dir.c	2005-03-01 23:39:09 -08:00
@@ -3,11 +3,11 @@
  *
  * Copyright (C) 2001-2003 Red Hat, Inc.
  *
- * Created by David Woodhouse <dwmw2@redhat.com>
+ * Created by David Woodhouse <dwmw2@infradead.org>
  *
  * For licensing information, see the file 'LICENCE' in this directory.
  *
- * $Id: dir.c,v 1.83 2004/10/19 07:48:44 havasi Exp $
+ * $Id: dir.c,v 1.84 2004/11/16 20:36:11 dwmw2 Exp $
  *
  */
 
diff -Nru a/fs/jffs2/erase.c b/fs/jffs2/erase.c
--- a/fs/jffs2/erase.c	2005-03-01 23:38:52 -08:00
+++ b/fs/jffs2/erase.c	2005-03-01 23:38:52 -08:00
@@ -3,11 +3,11 @@
  *
  * Copyright (C) 2001-2003 Red Hat, Inc.
  *
- * Created by David Woodhouse <dwmw2@redhat.com>
+ * Created by David Woodhouse <dwmw2@infradead.org>
  *
  * For licensing information, see the file 'LICENCE' in this directory.
  *
- * $Id: erase.c,v 1.61 2004/10/20 23:59:49 dwmw2 Exp $
+ * $Id: erase.c,v 1.66 2004/11/16 20:36:11 dwmw2 Exp $
  *
  */
 
@@ -43,6 +43,7 @@
                jffs2_erase_succeeded(c, jeb);
                return;
        }
+       bad_offset = jeb->offset;
 #else /* Linux */
 	struct erase_info *instr;
 
@@ -386,6 +387,7 @@
 		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),
 			.nodetype =	cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER),
@@ -394,8 +396,10 @@
 
 		marker.hdr_crc = cpu_to_je32(crc32(0, &marker, sizeof(struct jffs2_unknown_node)-4));
 
-		/* We only write the header; the rest was noise or padding anyway */
-		ret = jffs2_flash_write(c, jeb->offset, sizeof(marker), &retlen, (char *)&marker);
+		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);
diff -Nru a/fs/jffs2/file.c b/fs/jffs2/file.c
--- a/fs/jffs2/file.c	2005-03-01 23:39:17 -08:00
+++ b/fs/jffs2/file.c	2005-03-01 23:39:17 -08:00
@@ -3,11 +3,11 @@
  *
  * Copyright (C) 2001-2003 Red Hat, Inc.
  *
- * Created by David Woodhouse <dwmw2@redhat.com>
+ * Created by David Woodhouse <dwmw2@infradead.org>
  *
  * For licensing information, see the file 'LICENCE' in this directory.
  *
- * $Id: file.c,v 1.98 2004/03/19 16:41:09 dwmw2 Exp $
+ * $Id: file.c,v 1.99 2004/11/16 20:36:11 dwmw2 Exp $
  *
  */
 
diff -Nru a/fs/jffs2/fs.c b/fs/jffs2/fs.c
--- a/fs/jffs2/fs.c	2005-03-01 23:38:56 -08:00
+++ b/fs/jffs2/fs.c	2005-03-01 23:38:56 -08:00
@@ -3,11 +3,11 @@
  *
  * Copyright (C) 2001-2003 Red Hat, Inc.
  *
- * Created by David Woodhouse <dwmw2@redhat.com>
+ * Created by David Woodhouse <dwmw2@infradead.org>
  *
  * For licensing information, see the file 'LICENCE' in this directory.
  *
- * $Id: fs.c,v 1.46 2004/07/13 08:56:54 dwmw2 Exp $
+ * $Id: fs.c,v 1.51 2004/11/28 12:19:37 dedekind Exp $
  *
  */
 
@@ -20,6 +20,7 @@
 #include <linux/mtd/mtd.h>
 #include <linux/pagemap.h>
 #include <linux/slab.h>
+#include <linux/vmalloc.h>
 #include <linux/vfs.h>
 #include <linux/crc32.h>
 #include "nodelist.h"
@@ -202,7 +203,7 @@
 
 	buf->f_bavail = buf->f_bfree = avail >> PAGE_SHIFT;
 
-	D1(jffs2_dump_block_lists(c));
+	D2(jffs2_dump_block_lists(c));
 
 	spin_unlock(&c->erase_completion_lock);
 
@@ -426,7 +427,7 @@
 	inode->i_mode = jemode_to_cpu(ri->mode);
 	inode->i_gid = je16_to_cpu(ri->gid);
 	inode->i_uid = je16_to_cpu(ri->uid);
-	inode->i_atime = inode->i_ctime = inode->i_mtime = CURRENT_TIME;
+	inode->i_atime = inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC;
 	ri->atime = ri->mtime = ri->ctime = cpu_to_je32(I_SEC(inode->i_mtime));
 
 	inode->i_blksize = PAGE_SIZE;
@@ -463,11 +464,13 @@
 	 */
 	c->sector_size = c->mtd->erasesize; 
 	blocks = c->flash_size / c->sector_size;
-	while ((blocks * sizeof (struct jffs2_eraseblock)) > (128 * 1024)) {
-		blocks >>= 1;
-		c->sector_size <<= 1;
-	}	
-	
+	if (!(c->mtd->flags & MTD_NO_VIRTBLOCKS)) {
+		while ((blocks * sizeof (struct jffs2_eraseblock)) > (128 * 1024)) {
+			blocks >>= 1;
+			c->sector_size <<= 1;
+		}	
+	}
+
 	/*
 	 * Size alignment check
 	 */
@@ -533,7 +536,10 @@
  out_nodes:
 	jffs2_free_ino_caches(c);
 	jffs2_free_raw_node_refs(c);
-	kfree(c->blocks);
+	if (c->mtd->flags & MTD_NO_VIRTBLOCKS)
+		vfree(c->blocks);
+	else
+		kfree(c->blocks);
  out_inohash:
 	kfree(c->inocache_list);
  out_wbuf:
@@ -649,6 +655,11 @@
 	}
 
 	/* add setups for other bizarre flashes here... */
+	if (jffs2_nor_ecc(c)) {
+		ret = jffs2_nor_ecc_flash_setup(c);
+		if (ret)
+			return ret;
+	}
 	return ret;
 }
 
@@ -659,4 +670,7 @@
 	}
 
 	/* add cleanups for other bizarre flashes here... */
+	if (jffs2_nor_ecc(c)) {
+		jffs2_nor_ecc_flash_cleanup(c);
+	}
 }
diff -Nru a/fs/jffs2/gc.c b/fs/jffs2/gc.c
--- a/fs/jffs2/gc.c	2005-03-01 23:38:54 -08:00
+++ b/fs/jffs2/gc.c	2005-03-01 23:38:54 -08:00
@@ -3,11 +3,11 @@
  *
  * Copyright (C) 2001-2003 Red Hat, Inc.
  *
- * Created by David Woodhouse <dwmw2@redhat.com>
+ * Created by David Woodhouse <dwmw2@infradead.org>
  *
  * For licensing information, see the file 'LICENCE' in this directory.
  *
- * $Id: gc.c,v 1.140 2004/11/13 10:59:22 dedekind Exp $
+ * $Id: gc.c,v 1.144 2004/12/21 11:18:50 dwmw2 Exp $
  *
  */
 
@@ -103,7 +103,7 @@
 		ret->wasted_size = 0;
 	}
 
-	D1(jffs2_dump_block_lists(c));
+	D2(jffs2_dump_block_lists(c));
 	return ret;
 }
 
@@ -134,7 +134,7 @@
 		if (c->checked_ino > c->highest_ino) {
 			printk(KERN_CRIT "Checked all inodes but still 0x%x bytes of unchecked space?\n",
 			       c->unchecked_size);
-			D1(jffs2_dump_block_lists(c));
+			D2(jffs2_dump_block_lists(c));
 			spin_unlock(&c->erase_completion_lock);
 			BUG();
 		}
@@ -602,7 +602,7 @@
 			printk(KERN_NOTICE "Not marking the space at 0x%08x as dirty because the flash driver returned retlen zero\n", nraw->flash_offset);
                         jffs2_free_raw_node_ref(nraw);
 		}
-		if (!retried && (nraw == jffs2_alloc_raw_node_ref())) {
+		if (!retried && (nraw = jffs2_alloc_raw_node_ref())) {
 			/* Try to reallocate space and retry */
 			uint32_t dummy;
 			struct jffs2_eraseblock *jeb = &c->blocks[phys_ofs / c->sector_size];
diff -Nru a/fs/jffs2/ioctl.c b/fs/jffs2/ioctl.c
--- a/fs/jffs2/ioctl.c	2005-03-01 23:39:08 -08:00
+++ b/fs/jffs2/ioctl.c	2005-03-01 23:39:08 -08:00
@@ -3,11 +3,11 @@
  *
  * Copyright (C) 2001-2003 Red Hat, Inc.
  *
- * Created by David Woodhouse <dwmw2@redhat.com>
+ * Created by David Woodhouse <dwmw2@infradead.org>
  *
  * For licensing information, see the file 'LICENCE' in this directory.
  *
- * $Id: ioctl.c,v 1.8 2003/10/28 16:16:28 dwmw2 Exp $
+ * $Id: ioctl.c,v 1.9 2004/11/16 20:36:11 dwmw2 Exp $
  *
  */
 
diff -Nru a/fs/jffs2/malloc.c b/fs/jffs2/malloc.c
--- a/fs/jffs2/malloc.c	2005-03-01 23:39:18 -08:00
+++ b/fs/jffs2/malloc.c	2005-03-01 23:39:18 -08:00
@@ -3,11 +3,11 @@
  *
  * Copyright (C) 2001-2003 Red Hat, Inc.
  *
- * Created by David Woodhouse <dwmw2@redhat.com>
+ * Created by David Woodhouse <dwmw2@infradead.org>
  *
  * For licensing information, see the file 'LICENCE' in this directory.
  *
- * $Id: malloc.c,v 1.27 2003/10/28 17:14:58 dwmw2 Exp $
+ * $Id: malloc.c,v 1.28 2004/11/16 20:36:11 dwmw2 Exp $
  *
  */
 
diff -Nru a/fs/jffs2/nodelist.c b/fs/jffs2/nodelist.c
--- a/fs/jffs2/nodelist.c	2005-03-01 23:38:58 -08:00
+++ b/fs/jffs2/nodelist.c	2005-03-01 23:38:58 -08:00
@@ -3,11 +3,11 @@
  *
  * Copyright (C) 2001-2003 Red Hat, Inc.
  *
- * Created by David Woodhouse <dwmw2@redhat.com>
+ * Created by David Woodhouse <dwmw2@infradead.org>
  *
  * For licensing information, see the file 'LICENCE' in this directory.
  *
- * $Id: nodelist.c,v 1.87 2004/11/14 17:07:07 dedekind Exp $
+ * $Id: nodelist.c,v 1.90 2004/12/08 17:59:20 dwmw2 Exp $
  *
  */
 
@@ -92,6 +92,17 @@
 	}
 }
 
+/* Returns first valid node after 'ref'. May return 'ref' */
+static struct jffs2_raw_node_ref *jffs2_first_valid_node(struct jffs2_raw_node_ref *ref)
+{
+	while (ref && ref->next_in_ino) {
+		if (!ref_obsolete(ref))
+			return ref;
+		D1(printk(KERN_DEBUG "node at 0x%08x is obsoleted. Ignoring.\n", ref_offset(ref)));
+		ref = ref->next_in_ino;
+	}
+	return NULL;
+}
 
 /* Get tmp_dnode_info and full_dirent for all non-obsolete nodes associated
    with this ino, returning the former in order of version */
@@ -101,7 +112,7 @@
 			  uint32_t *highest_version, uint32_t *latest_mctime,
 			  uint32_t *mctime_ver)
 {
-	struct jffs2_raw_node_ref *ref = f->inocache->nodes;
+	struct jffs2_raw_node_ref *ref, *valid_ref;
 	struct jffs2_tmp_dnode_info *tn, *ret_tn = NULL;
 	struct jffs2_full_dirent *fd, *ret_fd = NULL;
 	union jffs2_node_union node;
@@ -111,22 +122,23 @@
 	*mctime_ver = 0;
 	
 	D1(printk(KERN_DEBUG "jffs2_get_inode_nodes(): ino #%u\n", f->inocache->ino));
-	if (!f->inocache->nodes) {
-		printk(KERN_WARNING "Eep. no nodes for ino #%u\n", f->inocache->ino);
-	}
 
 	spin_lock(&c->erase_completion_lock);
 
-	for (ref = f->inocache->nodes; ref && ref->next_in_ino; ref = ref->next_in_ino) {
-		/* Work out whether it's a data node or a dirent node */
-		if (ref_obsolete(ref)) {
-			/* FIXME: On NAND flash we may need to read these */
-			D1(printk(KERN_DEBUG "node at 0x%08x is obsoleted. Ignoring.\n", ref_offset(ref)));
-			continue;
-		}
+	valid_ref = jffs2_first_valid_node(f->inocache->nodes);
+
+	if (!valid_ref)
+		printk(KERN_WARNING "Eep. No valid nodes for ino #%u\n", f->inocache->ino);
+
+	while (valid_ref) {
 		/* We can hold a pointer to a non-obsolete node without the spinlock,
 		   but _obsolete_ nodes may disappear at any time, if the block
-		   they're in gets erased */
+		   they're in gets erased. So if we mark 'ref' obsolete while we're
+		   not holding the lock, it can go away immediately. For that reason,
+		   we find the next valid node first, before processing 'ref'.
+		*/
+		ref = valid_ref;
+		valid_ref = jffs2_first_valid_node(ref->next_in_ino);
 		spin_unlock(&c->erase_completion_lock);
 
 		cond_resched();
@@ -182,7 +194,6 @@
 				err = -ENOMEM;
 				goto free_out;
 			}
-			memset(fd,0,sizeof(struct jffs2_full_dirent) + node.d.nsize+1);
 			fd->raw = ref;
 			fd->version = je32_to_cpu(node.d.version);
 			fd->ino = je32_to_cpu(node.d.ino);
@@ -220,6 +231,7 @@
 			}
 			fd->nhash = full_name_hash(fd->name, node.d.nsize);
 			fd->next = NULL;
+			fd->name[node.d.nsize] = '\0';
 				/* Wheee. We now have a complete jffs2_full_dirent structure, with
 				   the name in it and everything. Link it into the list 
 				*/
diff -Nru a/fs/jffs2/nodelist.h b/fs/jffs2/nodelist.h
--- a/fs/jffs2/nodelist.h	2005-03-01 23:39:18 -08:00
+++ b/fs/jffs2/nodelist.h	2005-03-01 23:39:18 -08:00
@@ -3,11 +3,11 @@
  *
  * Copyright (C) 2001-2003 Red Hat, Inc.
  *
- * Created by David Woodhouse <dwmw2@redhat.com>
+ * Created by David Woodhouse <dwmw2@infradead.org>
  *
  * For licensing information, see the file 'LICENCE' in this directory.
  *
- * $Id: nodelist.h,v 1.121 2004/11/14 17:07:07 dedekind Exp $
+ * $Id: nodelist.h,v 1.126 2004/11/19 15:06:29 dedekind Exp $
  *
  */
 
@@ -107,16 +107,6 @@
 #define ref_obsolete(ref)	(((ref)->flash_offset & 3) == REF_OBSOLETE)
 #define mark_ref_normal(ref)    do { (ref)->flash_offset = ref_offset(ref) | REF_NORMAL; } while(0)
 
-/* 
-   Used for keeping track of deletion nodes &c, which can only be marked
-   as obsolete when the node which they mark as deleted has actually been 
-   removed from the flash.
-*/
-struct jffs2_raw_node_ref_list {
-	struct jffs2_raw_node_ref *rew;
-	struct jffs2_raw_node_ref_list *next;
-};
-
 /* For each inode in the filesystem, we need to keep a record of
    nlink, because it would be a PITA to scan the whole directory tree
    at read_inode() time to calculate it, and to keep sufficient information
@@ -148,13 +138,6 @@
 
 #define INOCACHE_HASHSIZE 128
 
-struct jffs2_scan_info {
-	struct jffs2_full_dirent *dents;
-	struct jffs2_tmp_dnode_info *tmpnodes;
-	/* Latest i_size info */
-	uint32_t version;
-	uint32_t isize;
-};
 /*
   Larger representation of a raw node, kept in-core only when the 
   struct inode for this particular ino is instantiated.
@@ -163,12 +146,11 @@
 struct jffs2_full_dnode
 {
 	struct jffs2_raw_node_ref *raw;
-	uint32_t ofs; /* Don't really need this, but optimisation */
+	uint32_t ofs; /* The offset to which the data of this node belongs */
 	uint32_t size;
 	uint32_t frags; /* Number of fragments which currently refer
 			to this node. When this reaches zero, 
-			the node is obsolete.
-		     */
+			the node is obsolete.  */
 };
 
 /* 
@@ -193,6 +175,7 @@
 	unsigned char type;
 	unsigned char name[0];
 };
+
 /*
   Fragments - used to build a map of which raw node to obtain 
   data from for each part of the ino
@@ -202,7 +185,7 @@
 	struct rb_node rb;
 	struct jffs2_full_dnode *node; /* NULL for holes */
 	uint32_t size;
-	uint32_t ofs; /* Don't really need this, but optimisation */
+	uint32_t ofs; /* The offset to which this fragment belongs */
 };
 
 struct jffs2_eraseblock
@@ -221,14 +204,6 @@
 	struct jffs2_raw_node_ref *last_node;
 
 	struct jffs2_raw_node_ref *gc_node;	/* Next node to be garbage collected */
-
-	/* For deletia. When a dirent node in this eraseblock is
-	   deleted by a node elsewhere, that other node can only 
-	   be marked as obsolete when this block is actually erased.
-	   So we keep a list of the nodes to mark as obsolete when
-	   the erase is completed.
-	*/
-	// MAYBE	struct jffs2_raw_node_ref_list *deletia;
 };
 
 #define ACCT_SANITY_CHECK(c, jeb) do { \
@@ -396,7 +371,7 @@
 #define frag_erase(frag, list) rb_erase(&frag->rb, list);
 
 /* nodelist.c */
-D1(void jffs2_print_frag_list(struct jffs2_inode_info *f));
+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,
diff -Nru a/fs/jffs2/nodemgmt.c b/fs/jffs2/nodemgmt.c
--- a/fs/jffs2/nodemgmt.c	2005-03-01 23:38:53 -08:00
+++ b/fs/jffs2/nodemgmt.c	2005-03-01 23:38:53 -08:00
@@ -3,11 +3,11 @@
  *
  * Copyright (C) 2001-2003 Red Hat, Inc.
  *
- * Created by David Woodhouse <dwmw2@redhat.com>
+ * Created by David Woodhouse <dwmw2@infradead.org>
  *
  * For licensing information, see the file 'LICENCE' in this directory.
  *
- * $Id: nodemgmt.c,v 1.109 2004/10/07 15:08:47 havasi Exp $
+ * $Id: nodemgmt.c,v 1.115 2004/11/22 11:07:21 dwmw2 Exp $
  *
  */
 
@@ -399,6 +399,17 @@
 	}
 	jeb = &c->blocks[blocknr];
 
+	if (jffs2_can_mark_obsolete(c) && !jffs2_is_readonly(c) &&
+	    !(c->flags & JFFS2_SB_FLAG_MOUNTING)) {
+		/* 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
+		   any jffs2_raw_node_refs. So we don't need to stop erases from
+		   happening, or protect against people holding an obsolete
+		   jffs2_raw_node_ref without the erase_completion_lock. */
+		down(&c->erase_free_sem);
+	}
+
 	spin_lock(&c->erase_completion_lock);
 
 	if (ref_flags(ref) == REF_UNCHECKED) {
@@ -463,6 +474,7 @@
 		   marked obsolete on the flash at the time they _became_
 		   obsolete, there was probably a reason for that. */
 		spin_unlock(&c->erase_completion_lock);
+		/* We didn't lock the erase_free_sem */
 		return;
 	}
 
@@ -515,61 +527,87 @@
 
 	spin_unlock(&c->erase_completion_lock);
 
-	if (!jffs2_can_mark_obsolete(c))
-		return;
-	if (jffs2_is_readonly(c))
+	if (!jffs2_can_mark_obsolete(c) || jffs2_is_readonly(c)) {
+		/* We didn't lock the erase_free_sem */
 		return;
+	}
+
+	/* The erase_free_sem is locked, and has been since before we marked the node obsolete
+	   and potentially put its eraseblock onto the erase_pending_list. Thus, we know that
+	   the block hasn't _already_ been erased, and that 'ref' itself hasn't been freed yet
+	   by jffs2_free_all_node_refs() in erase.c. Which is nice. */
 
 	D1(printk(KERN_DEBUG "obliterating obsoleted node at 0x%08x\n", ref_offset(ref)));
 	ret = jffs2_flash_read(c, ref_offset(ref), sizeof(n), &retlen, (char *)&n);
 	if (ret) {
 		printk(KERN_WARNING "Read error reading from obsoleted node at 0x%08x: %d\n", ref_offset(ref), ret);
-		return;
+		goto out_erase_sem;
 	}
 	if (retlen != sizeof(n)) {
 		printk(KERN_WARNING "Short read from obsoleted node at 0x%08x: %zd\n", ref_offset(ref), retlen);
-		return;
+		goto out_erase_sem;
 	}
 	if (PAD(je32_to_cpu(n.totlen)) != PAD(ref_totlen(c, jeb, ref))) {
 		printk(KERN_WARNING "Node totlen on flash (0x%08x) != totlen from node ref (0x%08x)\n", je32_to_cpu(n.totlen), ref_totlen(c, jeb, ref));
-		return;
+		goto out_erase_sem;
 	}
 	if (!(je16_to_cpu(n.nodetype) & JFFS2_NODE_ACCURATE)) {
 		D1(printk(KERN_DEBUG "Node at 0x%08x was already marked obsolete (nodetype 0x%04x)\n", ref_offset(ref), je16_to_cpu(n.nodetype)));
-		return;
+		goto out_erase_sem;
 	}
 	/* XXX FIXME: This is ugly now */
 	n.nodetype = cpu_to_je16(je16_to_cpu(n.nodetype) & ~JFFS2_NODE_ACCURATE);
 	ret = jffs2_flash_write(c, ref_offset(ref), sizeof(n), &retlen, (char *)&n);
 	if (ret) {
 		printk(KERN_WARNING "Write error in obliterating obsoleted node at 0x%08x: %d\n", ref_offset(ref), ret);
-		return;
+		goto out_erase_sem;
 	}
 	if (retlen != sizeof(n)) {
 		printk(KERN_WARNING "Short write in obliterating obsoleted node at 0x%08x: %zd\n", ref_offset(ref), retlen);
-		return;
+		goto out_erase_sem;
 	}
 
 	/* Nodes which have been marked obsolete no longer need to be
-	   associated with any inode. Remove them from the per-inode list */
+	   associated with any inode. Remove them from the per-inode list.
+	   
+	   Note we can't do this for NAND at the moment because we need 
+	   obsolete dirent nodes to stay on the lists, because of the
+	   horridness in jffs2_garbage_collect_deletion_dirent(). Also
+	   because we delete the inocache, and on NAND we need that to 
+	   stay around until all the nodes are actually erased, in order
+	   to stop us from giving the same inode number to another newly
+	   created inode. */
 	if (ref->next_in_ino) {
 		struct jffs2_inode_cache *ic;
 		struct jffs2_raw_node_ref **p;
 
+		spin_lock(&c->erase_completion_lock);
+
 		ic = jffs2_raw_ref_to_ic(ref);
 		for (p = &ic->nodes; (*p) != ref; p = &((*p)->next_in_ino))
 			;
 
 		*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));
+			jffs2_del_ino_cache(c, ic);
+			jffs2_free_inode_cache(ic);
+		}
+
+		spin_unlock(&c->erase_completion_lock);
 	}
 
 
 	/* Merge with the next node in the physical list, if there is one
-	   and if it's also obsolete. */
-	if (ref->next_phys && ref_obsolete(ref->next_phys) ) {
+	   and if it's also obsolete and if it doesn't belong to any inode */
+	if (ref->next_phys && ref_obsolete(ref->next_phys) &&
+	    !ref->next_phys->next_in_ino) {
 		struct jffs2_raw_node_ref *n = ref->next_phys;
 		
+		spin_lock(&c->erase_completion_lock);
+
 		ref->__totlen += n->__totlen;
 		ref->next_phys = n->next_phys;
                 if (jeb->last_node == n) jeb->last_node = ref;
@@ -577,7 +615,8 @@
 			/* gc will be happy continuing gc on this node */
 			jeb->gc_node=ref;
 		}
-		BUG_ON(n->next_in_ino);
+		spin_unlock(&c->erase_completion_lock);
+
 		jffs2_free_raw_node_ref(n);
 	}
 	
@@ -585,11 +624,13 @@
 	   and that one is obsolete */
 	if (ref != jeb->first_node ) {
 		struct jffs2_raw_node_ref *p = jeb->first_node;
-		
+
+		spin_lock(&c->erase_completion_lock);
+
 		while (p->next_phys != ref)
 			p = p->next_phys;
 		
-		if (ref_obsolete(p) ) {
+		if (ref_obsolete(p) && !ref->next_in_ino) {
 			p->__totlen += ref->__totlen;
 			if (jeb->last_node == ref) {
 				jeb->last_node = p;
@@ -601,10 +642,13 @@
 			p->next_phys = ref->next_phys;
 			jffs2_free_raw_node_ref(ref);
 		}
+		spin_unlock(&c->erase_completion_lock);
 	}
+ out_erase_sem:
+	up(&c->erase_free_sem);
 }
 
-#if CONFIG_JFFS2_FS_DEBUG > 0
+#if CONFIG_JFFS2_FS_DEBUG >= 2
 void jffs2_dump_block_lists(struct jffs2_sb_info *c)
 {
 
diff -Nru a/fs/jffs2/os-linux.h b/fs/jffs2/os-linux.h
--- a/fs/jffs2/os-linux.h	2005-03-01 23:38:52 -08:00
+++ b/fs/jffs2/os-linux.h	2005-03-01 23:38:52 -08:00
@@ -3,11 +3,11 @@
  *
  * Copyright (C) 2002-2003 Red Hat, Inc.
  *
- * Created by David Woodhouse <dwmw2@redhat.com>
+ * Created by David Woodhouse <dwmw2@infradead.org>
  *
  * For licensing information, see the file 'LICENCE' in this directory.
  *
- * $Id: os-linux.h,v 1.47 2004/07/14 13:20:23 dwmw2 Exp $
+ * $Id: os-linux.h,v 1.51 2004/11/16 20:36:11 dwmw2 Exp $
  *
  */
 
@@ -99,7 +99,7 @@
 
 #define jffs2_is_readonly(c) (OFNI_BS_2SFFJ(c)->s_flags & MS_RDONLY)
 
-#ifndef CONFIG_JFFS2_FS_NAND
+#if (!defined CONFIG_JFFS2_FS_NAND && !defined CONFIG_JFFS2_FS_NOR_ECC)
 #define jffs2_can_mark_obsolete(c) (1)
 #define jffs2_cleanmarker_oob(c) (0)
 #define jffs2_write_nand_cleanmarker(c,jeb) (-EIO)
@@ -115,10 +115,13 @@
 #define jffs2_flash_writev(a,b,c,d,e,f) jffs2_flash_direct_writev(a,b,c,d,e)
 #define jffs2_wbuf_timeout NULL
 #define jffs2_wbuf_process NULL
+#define jffs2_nor_ecc(c) (0)
+#define jffs2_nor_ecc_flash_setup(c) (0)
+#define jffs2_nor_ecc_flash_cleanup(c) do {} while (0)
 
-#else /* NAND support present */
+#else /* NAND and/or ECC'd NOR support present */
 
-#define jffs2_can_mark_obsolete(c) (c->mtd->type == MTD_NORFLASH || c->mtd->type == MTD_RAM)
+#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)
 
 #define jffs2_flash_write_oob(c, ofs, len, retlen, buf) ((c)->mtd->write_oob((c)->mtd, ofs, len, retlen, buf))
@@ -135,8 +138,19 @@
 int jffs2_write_nand_badblock(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, uint32_t bad_offset);
 void jffs2_wbuf_timeout(unsigned long data);
 void jffs2_wbuf_process(void *data);
+int jffs2_flush_wbuf_gc(struct jffs2_sb_info *c, uint32_t ino);
+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 */
 
 /* erase.c */
diff -Nru a/fs/jffs2/pushpull.h b/fs/jffs2/pushpull.h
--- a/fs/jffs2/pushpull.h	2005-03-01 23:38:44 -08:00
+++ b/fs/jffs2/pushpull.h	2005-03-01 23:38:44 -08:00
@@ -3,11 +3,11 @@
  *
  * Copyright (C) 2001, 2002 Red Hat, Inc.
  *
- * Created by David Woodhouse <dwmw2@redhat.com>
+ * Created by David Woodhouse <dwmw2@infradead.org>
  *
  * For licensing information, see the file 'LICENCE' in this directory.
  *
- * $Id: pushpull.h,v 1.9 2003/10/04 08:33:06 dwmw2 Exp $
+ * $Id: pushpull.h,v 1.10 2004/11/16 20:36:11 dwmw2 Exp $
  *
  */
 
diff -Nru a/fs/jffs2/read.c b/fs/jffs2/read.c
--- a/fs/jffs2/read.c	2005-03-01 23:38:54 -08:00
+++ b/fs/jffs2/read.c	2005-03-01 23:38:54 -08:00
@@ -3,11 +3,11 @@
  *
  * Copyright (C) 2001-2003 Red Hat, Inc.
  *
- * Created by David Woodhouse <dwmw2@redhat.com>
+ * Created by David Woodhouse <dwmw2@infradead.org>
  *
  * For licensing information, see the file 'LICENCE' in this directory.
  *
- * $Id: read.c,v 1.36 2004/05/25 11:12:32 havasi Exp $
+ * $Id: read.c,v 1.38 2004/11/16 20:36:12 dwmw2 Exp $
  *
  */
 
@@ -174,7 +174,7 @@
 			if (frag) {
 				D1(printk(KERN_NOTICE "Eep. Hole in ino #%u fraglist. frag->ofs = 0x%08x, offset = 0x%08x\n", f->inocache->ino, frag->ofs, offset));
 				holesize = min(holesize, frag->ofs - offset);
-				D1(jffs2_print_frag_list(f));
+				D2(jffs2_print_frag_list(f));
 			}
 			D1(printk(KERN_DEBUG "Filling non-frag hole from %d-%d\n", offset, offset+holesize));
 			memset(buf, 0, holesize);
diff -Nru a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c
--- a/fs/jffs2/readinode.c	2005-03-01 23:38:51 -08:00
+++ b/fs/jffs2/readinode.c	2005-03-01 23:38:51 -08:00
@@ -3,11 +3,11 @@
  *
  * Copyright (C) 2001-2003 Red Hat, Inc.
  *
- * Created by David Woodhouse <dwmw2@redhat.com>
+ * Created by David Woodhouse <dwmw2@infradead.org>
  *
  * For licensing information, see the file 'LICENCE' in this directory.
  *
- * $Id: readinode.c,v 1.114 2004/11/14 17:07:07 dedekind Exp $
+ * $Id: readinode.c,v 1.117 2004/11/20 18:06:54 dwmw2 Exp $
  *
  */
 
@@ -22,7 +22,7 @@
 
 static int jffs2_add_frag_to_fragtree(struct jffs2_sb_info *c, struct rb_root *list, struct jffs2_node_frag *newfrag);
 
-#if CONFIG_JFFS2_FS_DEBUG >= 1
+#if CONFIG_JFFS2_FS_DEBUG >= 2
 static void jffs2_print_fragtree(struct rb_root *list, int permitbug)
 {
 	struct jffs2_node_frag *this = frag_first(list);
@@ -56,7 +56,9 @@
 		printk(KERN_DEBUG "metadata at 0x%08x\n", ref_offset(f->metadata->raw));
 	}
 }
+#endif
 
+#if CONFIG_JFFS2_FS_DEBUG >= 1
 static int jffs2_sanitycheck_fragtree(struct jffs2_inode_info *f)
 {
 	struct jffs2_node_frag *frag;
@@ -225,7 +227,7 @@
 		   If so, both 'this' and the new node get marked REF_NORMAL so
 		   the GC can take a look.
 		*/
-		if ((lastend-1) >> PAGE_CACHE_SHIFT == newfrag->ofs >> PAGE_CACHE_SHIFT) {
+		if (lastend && (lastend-1) >> PAGE_CACHE_SHIFT == newfrag->ofs >> PAGE_CACHE_SHIFT) {
 			if (this->node)
 				mark_ref_normal(this->node->raw);
 			mark_ref_normal(newfrag->node->raw);
diff -Nru a/fs/jffs2/scan.c b/fs/jffs2/scan.c
--- a/fs/jffs2/scan.c	2005-03-01 23:39:16 -08:00
+++ b/fs/jffs2/scan.c	2005-03-01 23:39:16 -08:00
@@ -3,11 +3,11 @@
  *
  * Copyright (C) 2001-2003 Red Hat, Inc.
  *
- * Created by David Woodhouse <dwmw2@redhat.com>
+ * Created by David Woodhouse <dwmw2@infradead.org>
  *
  * For licensing information, see the file 'LICENCE' in this directory.
  *
- * $Id: scan.c,v 1.112 2004/09/12 09:56:13 gleixner Exp $
+ * $Id: scan.c,v 1.115 2004/11/17 12:59:08 dedekind Exp $
  *
  */
 #include <linux/kernel.h>
@@ -68,7 +68,7 @@
 static inline int min_free(struct jffs2_sb_info *c)
 {
 	uint32_t min = 2 * sizeof(struct jffs2_raw_inode);
-#ifdef CONFIG_JFFS2_FS_NAND
+#if defined CONFIG_JFFS2_FS_NAND || defined CONFIG_JFFS2_FS_NOR_ECC
 	if (!jffs2_can_mark_obsolete(c) && min < c->wbuf_pagesize)
 		return c->wbuf_pagesize;
 #endif
@@ -160,11 +160,8 @@
 
 		case BLK_STATE_PARTDIRTY:
                         /* Some data, but not full. Dirty list. */
-                        /* Except that we want to remember the block with most free space,
-                           and stick it in the 'nextblock' position to start writing to it.
-                           Later when we do snapshots, this must be the most recent block,
-                           not the one with most free space.
-                        */
+                        /* We want to remember the block with most free space
+                           and stick it in the 'nextblock' position to start writing to it. */
                         if (jeb->free_size > min_free(c) && 
 			    (!c->nextblock || c->nextblock->free_size < jeb->free_size)) {
                                 /* Better candidate for the next writes to go to */
@@ -223,7 +220,7 @@
 		c->dirty_size -= c->nextblock->dirty_size;
 		c->nextblock->dirty_size = 0;
 	}
-#ifdef CONFIG_JFFS2_FS_NAND
+#if defined CONFIG_JFFS2_FS_NAND || defined CONFIG_JFFS2_FS_NOR_ECC
 	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,
diff -Nru a/fs/jffs2/super.c b/fs/jffs2/super.c
--- a/fs/jffs2/super.c	2005-03-01 23:38:55 -08:00
+++ b/fs/jffs2/super.c	2005-03-01 23:38:55 -08:00
@@ -3,11 +3,11 @@
  *
  * Copyright (C) 2001-2003 Red Hat, Inc.
  *
- * Created by David Woodhouse <dwmw2@redhat.com>
+ * Created by David Woodhouse <dwmw2@infradead.org>
  *
  * For licensing information, see the file 'LICENCE' in this directory.
  *
- * $Id: super.c,v 1.102 2004/11/12 02:42:17 tpoynor Exp $
+ * $Id: super.c,v 1.104 2004/11/23 15:37:31 gleixner Exp $
  *
  */
 
@@ -277,7 +277,10 @@
 	up(&c->alloc_sem);
 	jffs2_free_ino_caches(c);
 	jffs2_free_raw_node_refs(c);
-	kfree(c->blocks);
+	if (c->mtd->flags & MTD_NO_VIRTBLOCKS)
+		vfree(c->blocks);
+	else
+		kfree(c->blocks);
 	jffs2_flash_cleanup(c);
 	kfree(c->inocache_list);
 	if (c->mtd->sync)
diff -Nru a/fs/jffs2/symlink.c b/fs/jffs2/symlink.c
--- a/fs/jffs2/symlink.c	2005-03-01 23:38:44 -08:00
+++ b/fs/jffs2/symlink.c	2005-03-01 23:38:44 -08:00
@@ -3,11 +3,11 @@
  *
  * Copyright (C) 2001, 2002 Red Hat, Inc.
  *
- * Created by David Woodhouse <dwmw2@redhat.com>
+ * Created by David Woodhouse <dwmw2@infradead.org>
  *
  * For licensing information, see the file 'LICENCE' in this directory.
  *
- * $Id: symlink.c,v 1.13 2004/07/13 08:59:04 dwmw2 Exp $
+ * $Id: symlink.c,v 1.14 2004/11/16 20:36:12 dwmw2 Exp $
  *
  */
 
diff -Nru a/fs/jffs2/wbuf.c b/fs/jffs2/wbuf.c
--- a/fs/jffs2/wbuf.c	2005-03-01 23:38:54 -08:00
+++ b/fs/jffs2/wbuf.c	2005-03-01 23:38:54 -08:00
@@ -4,12 +4,12 @@
  * Copyright (C) 2001-2003 Red Hat, Inc.
  * Copyright (C) 2004 Thomas Gleixner <tglx@linutronix.de>
  *
- * Created by David Woodhouse <dwmw2@redhat.com>
+ * Created by David Woodhouse <dwmw2@infradead.org>
  * Modified debugged and enhanced by Thomas Gleixner <tglx@linutronix.de>
  *
  * For licensing information, see the file 'LICENCE' in this directory.
  *
- * $Id: wbuf.c,v 1.72 2004/09/11 19:22:43 gleixner Exp $
+ * $Id: wbuf.c,v 1.82 2004/11/20 22:08:31 dwmw2 Exp $
  *
  */
 
@@ -130,22 +130,8 @@
 	}
 }
 
-/* Recover from failure to write wbuf. Recover the nodes up to the
- * wbuf, not the one which we were starting to try to write. */
-
-static void jffs2_wbuf_recover(struct jffs2_sb_info *c)
+static void jffs2_block_refile(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
 {
-	struct jffs2_eraseblock *jeb, *new_jeb;
-	struct jffs2_raw_node_ref **first_raw, **raw;
-	size_t retlen;
-	int ret;
-	unsigned char *buf;
-	uint32_t start, end, ofs, len;
-
-	spin_lock(&c->erase_completion_lock);
-
-	jeb = &c->blocks[c->wbuf_ofs / c->sector_size];
-
 	D1(printk("About to refile bad block at %08x\n", jeb->offset));
 
 	D2(jffs2_dump_block_lists(c));
@@ -175,6 +161,25 @@
 
 	ACCT_SANITY_CHECK(c,jeb);
 	D1(ACCT_PARANOIA_CHECK(jeb));
+}
+
+/* Recover from failure to write wbuf. Recover the nodes up to the
+ * wbuf, not the one which we were starting to try to write. */
+
+static void jffs2_wbuf_recover(struct jffs2_sb_info *c)
+{
+	struct jffs2_eraseblock *jeb, *new_jeb;
+	struct jffs2_raw_node_ref **first_raw, **raw;
+	size_t retlen;
+	int ret;
+	unsigned char *buf;
+	uint32_t start, end, ofs, len;
+
+	spin_lock(&c->erase_completion_lock);
+
+	jeb = &c->blocks[c->wbuf_ofs / c->sector_size];
+
+	jffs2_block_refile(c, jeb);
 
 	/* Find the first node to be recovered, by skipping over every
 	   node which ends before the wbuf starts, or which is obsolete. */
@@ -224,7 +229,11 @@
 		}
 
 		/* Do the read... */
-		ret = c->mtd->read_ecc(c->mtd, start, c->wbuf_ofs - start, &retlen, buf, NULL, c->oobinfo);
+		if (jffs2_cleanmarker_oob(c))
+			ret = c->mtd->read_ecc(c->mtd, start, c->wbuf_ofs - start, &retlen, buf, NULL, c->oobinfo);
+		else
+			ret = c->mtd->read(c->mtd, start, c->wbuf_ofs - start, &retlen, buf);
+		
 		if (ret == -EBADMSG && retlen == c->wbuf_ofs - start) {
 			/* ECC recovered */
 			ret = 0;
@@ -281,8 +290,11 @@
 			ret = -EIO;
 		} else
 #endif
+		if (jffs2_cleanmarker_oob(c))
 			ret = c->mtd->write_ecc(c->mtd, ofs, towrite, &retlen,
 						buf, NULL, c->oobinfo);
+		else
+			ret = c->mtd->write(c->mtd, ofs, towrite, &retlen, buf);
 
 		if (ret || retlen != towrite) {
 			/* Argh. We tried. Really we did. */
@@ -392,6 +404,10 @@
    1: Pad, do not adjust nextblock free_size
    2: Pad, adjust nextblock free_size
 */
+#define NOPAD		0
+#define PAD_NOACCOUNT	1
+#define PAD_ACCOUNTING	2
+
 static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad)
 {
 	int ret;
@@ -419,6 +435,10 @@
 	*/
 	if (pad) {
 		c->wbuf_len = PAD(c->wbuf_len);
+
+		/* Pad with JFFS2_DIRTY_BITMASK initially.  this helps out ECC'd NOR
+		   with 8 byte page size */
+		memset(c->wbuf + c->wbuf_len, 0, c->wbuf_pagesize - c->wbuf_len);
 		
 		if ( c->wbuf_len + sizeof(struct jffs2_unknown_node) < c->wbuf_pagesize) {
 			struct jffs2_unknown_node *padnode = (void *)(c->wbuf + c->wbuf_len);
@@ -426,9 +446,6 @@
 			padnode->nodetype = cpu_to_je16(JFFS2_NODETYPE_PADDING);
 			padnode->totlen = cpu_to_je32(c->wbuf_pagesize - c->wbuf_len);
 			padnode->hdr_crc = cpu_to_je32(crc32(0, padnode, sizeof(*padnode)-4));
-		} else {
-			/* Pad with JFFS2_DIRTY_BITMASK */
-			memset(c->wbuf + c->wbuf_len, 0, c->wbuf_pagesize - c->wbuf_len);
 		}
 	}
 	/* else jffs2_flash_writev has actually filled in the rest of the
@@ -444,8 +461,11 @@
 		ret = -EIO;
 	} else 
 #endif
-	ret = c->mtd->write_ecc(c->mtd, c->wbuf_ofs, c->wbuf_pagesize, &retlen, c->wbuf, NULL, c->oobinfo);
-
+	
+	if (jffs2_cleanmarker_oob(c))
+		ret = c->mtd->write_ecc(c->mtd, c->wbuf_ofs, c->wbuf_pagesize, &retlen, c->wbuf, NULL, c->oobinfo);
+	else
+		ret = c->mtd->write(c->mtd, c->wbuf_ofs, c->wbuf_pagesize, &retlen, c->wbuf);
 
 	if (ret || retlen != c->wbuf_pagesize) {
 		if (ret)
@@ -458,7 +478,7 @@
 
 		jffs2_wbuf_recover(c);
 
-		return ret; 
+		return ret;
 	}
 
 	spin_lock(&c->erase_completion_lock);
@@ -525,7 +545,9 @@
 	if (c->unchecked_size) {
 		/* GC won't make any progress for a while */
 		D1(printk(KERN_DEBUG "jffs2_flush_wbuf_gc() padding. Not finished checking\n"));
-		ret = __jffs2_flush_wbuf(c, 2);
+		down_write(&c->wbuf_sem);
+		ret = __jffs2_flush_wbuf(c, PAD_ACCOUNTING);
+		up_write(&c->wbuf_sem);
 	} else while (old_wbuf_len &&
 		      old_wbuf_ofs == c->wbuf_ofs) {
 
@@ -537,7 +559,9 @@
 		if (ret) {
 			/* GC failed. Flush it with padding instead */
 			down(&c->alloc_sem);
-			ret = __jffs2_flush_wbuf(c, 2);
+			down_write(&c->wbuf_sem);
+			ret = __jffs2_flush_wbuf(c, PAD_ACCOUNTING);
+			up_write(&c->wbuf_sem);
 			break;
 		}
 		down(&c->alloc_sem);
@@ -552,9 +576,14 @@
 /* Pad write-buffer to end and write it, wasting space. */
 int jffs2_flush_wbuf_pad(struct jffs2_sb_info *c)
 {
-	return __jffs2_flush_wbuf(c, 1);
-}
+	int ret;
 
+	down_write(&c->wbuf_sem);
+	ret = __jffs2_flush_wbuf(c, PAD_NOACCOUNT);
+	up_write(&c->wbuf_sem);
+
+	return ret;
+}
 
 #define PAGE_DIV(x) ( (x) & (~(c->wbuf_pagesize - 1)) )
 #define PAGE_MOD(x) ( (x) & (c->wbuf_pagesize - 1) )
@@ -575,6 +604,8 @@
 	if (!c->wbuf)
 		return jffs2_flash_direct_writev(c, invecs, count, to, retlen);
 	
+	down_write(&c->wbuf_sem);
+
 	/* If wbuf_ofs is not initialized, set it to target address */
 	if (c->wbuf_ofs == 0xFFFFFFFF) {
 		c->wbuf_ofs = PAGE_DIV(to);
@@ -582,6 +613,17 @@
 		memset(c->wbuf,0xff,c->wbuf_pagesize);
 	}
 
+	/* Fixup the wbuf if we are moving to a new eraseblock.  The checks below
+	   fail for ECC'd NOR because cleanmarker == 16, so a block starts at
+	   xxx0010.  */
+	if (jffs2_nor_ecc(c)) {
+		if (((c->wbuf_ofs % c->sector_size) == 0) && !c->wbuf_len) {
+			c->wbuf_ofs = PAGE_DIV(to);
+			c->wbuf_len = PAGE_MOD(to);
+			memset(c->wbuf,0xff,c->wbuf_pagesize);
+		}
+	}
+	
 	/* Sanity checks on target address. 
 	   It's permitted to write at PAD(c->wbuf_len+c->wbuf_ofs), 
 	   and it's permitted to write at the beginning of a new 
@@ -592,12 +634,12 @@
 		/* 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));
-			ret = jffs2_flush_wbuf_pad(c);
+			ret = __jffs2_flush_wbuf(c, PAD_NOACCOUNT);
 			if (ret) {
 				/* the underlying layer has to check wbuf_len to do the cleanup */
 				D1(printk(KERN_WARNING "jffs2_flush_wbuf() called from jffs2_flash_writev() failed %d\n", ret));
 				*retlen = 0;
-				return ret;
+				goto exit;
 			}
 		}
 		/* set pointer to new block */
@@ -623,7 +665,6 @@
 	invec = 0;
 	outvec = 0;
 
-
 	/* Fill writebuffer first, if already in use */	
 	if (c->wbuf_len) {
 		uint32_t invec_ofs = 0;
@@ -658,14 +699,14 @@
 		}			
 		
 		/* write buffer is full, flush buffer */
-		ret = __jffs2_flush_wbuf(c, 0);
+		ret = __jffs2_flush_wbuf(c, NOPAD);
 		if (ret) {
 			/* the underlying layer has to check wbuf_len to do the cleanup */
 			D1(printk(KERN_WARNING "jffs2_flush_wbuf() called from jffs2_flash_writev() failed %d\n", ret));
 			/* Retlen zero to make sure our caller doesn't mark the space dirty.
 			   We've already done everything that's necessary */
 			*retlen = 0;
-			return ret;
+			goto exit;
 		}
 		outvec_to += donelen;
 		c->wbuf_ofs = outvec_to;
@@ -709,19 +750,22 @@
 
 	if (splitvec != -1) {
 		uint32_t remainder;
-		int ret;
 
 		remainder = outvecs[splitvec].iov_len - split_ofs;
 		outvecs[splitvec].iov_len = split_ofs;
 
 		/* We did cross a page boundary, so we write some now */
-		ret = c->mtd->writev_ecc(c->mtd, outvecs, splitvec+1, outvec_to, &wbuf_retlen, NULL, c->oobinfo); 
+		if (jffs2_cleanmarker_oob(c))
+			ret = c->mtd->writev_ecc(c->mtd, outvecs, splitvec+1, outvec_to, &wbuf_retlen, NULL, c->oobinfo); 
+		else
+			ret = jffs2_flash_direct_writev(c, outvecs, splitvec+1, outvec_to, &wbuf_retlen);
+		
 		if (ret < 0 || wbuf_retlen != PAGE_DIV(totlen)) {
 			/* At this point we have no problem,
 			   c->wbuf is empty. 
 			*/
 			*retlen = donelen;
-			return ret;
+			goto exit;
 		}
 		
 		donelen += wbuf_retlen;
@@ -760,7 +804,11 @@
 	if (c->wbuf_len && ino)
 		jffs2_wbuf_dirties_inode(c, ino);
 
-	return 0;
+	ret = 0;
+	
+exit:
+	up_write(&c->wbuf_sem);
+	return ret;
 }
 
 /*
@@ -789,7 +837,12 @@
 
 	/* Read flash */
 	if (!jffs2_can_mark_obsolete(c)) {
-		ret = c->mtd->read_ecc(c->mtd, ofs, len, retlen, buf, NULL, c->oobinfo);
+		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",
@@ -811,23 +864,23 @@
 
 	/* if no writebuffer available or write buffer empty, return */
 	if (!c->wbuf_pagesize || !c->wbuf_len)
-		return ret;
+		goto exit;
 
 	/* if we read in a different block, return */
 	if ( (ofs & ~(c->sector_size-1)) != (c->wbuf_ofs & ~(c->sector_size-1)) ) 
-		return ret;	
+		goto exit;
 
 	if (ofs >= c->wbuf_ofs) {
 		owbf = (ofs - c->wbuf_ofs);	/* offset in write buffer */
 		if (owbf > c->wbuf_len)		/* is read beyond write buffer ? */
-			return ret;
+			goto exit;
 		lwbf = c->wbuf_len - owbf;	/* number of bytes to copy */
 		if (lwbf > len)	
 			lwbf = len;
 	} else {	
 		orbf = (c->wbuf_ofs - ofs);	/* offset in read buffer */
 		if (orbf > len)			/* is write beyond write buffer ? */
-			return ret;
+			goto exit;
 		lwbf = len - orbf; 		/* number of bytes to copy */
 		if (lwbf > c->wbuf_len)	
 			lwbf = c->wbuf_len;
@@ -835,6 +888,8 @@
 	if (lwbf > 0)
 		memcpy(buf+orbf,c->wbuf+owbf,lwbf);
 
+exit:
+	up_read(&c->wbuf_sem);
 	return ret;
 }
 
@@ -1079,9 +1134,9 @@
 	int res;
 
 	/* Initialise write buffer */
+	init_rwsem(&c->wbuf_sem);
 	c->wbuf_pagesize = c->mtd->oobblock;
 	c->wbuf_ofs = 0xFFFFFFFF;
-
 	
 	c->wbuf = kmalloc(c->wbuf_pagesize, GFP_KERNEL);
 	if (!c->wbuf)
@@ -1105,3 +1160,25 @@
 {
 	kfree(c->wbuf);
 }
+
+#ifdef CONFIG_JFFS2_FS_NOR_ECC
+int jffs2_nor_ecc_flash_setup(struct jffs2_sb_info *c) {
+	/* Cleanmarker is actually larger on the flashes */
+	c->cleanmarker_size = 16;
+
+	/* Initialize write buffer */
+	init_rwsem(&c->wbuf_sem);
+	c->wbuf_pagesize = c->mtd->eccsize;
+	c->wbuf_ofs = 0xFFFFFFFF;
+
+	c->wbuf = kmalloc(c->wbuf_pagesize, GFP_KERNEL);
+	if (!c->wbuf)
+		return -ENOMEM;
+
+	return 0;
+}
+
+void jffs2_nor_ecc_flash_cleanup(struct jffs2_sb_info *c) {
+	kfree(c->wbuf);
+}
+#endif
diff -Nru a/fs/jffs2/write.c b/fs/jffs2/write.c
--- a/fs/jffs2/write.c	2005-03-01 23:38:57 -08:00
+++ b/fs/jffs2/write.c	2005-03-01 23:38:57 -08:00
@@ -3,11 +3,11 @@
  *
  * Copyright (C) 2001-2003 Red Hat, Inc.
  *
- * Created by David Woodhouse <dwmw2@redhat.com>
+ * Created by David Woodhouse <dwmw2@infradead.org>
  *
  * For licensing information, see the file 'LICENCE' in this directory.
  *
- * $Id: write.c,v 1.86 2004/11/13 10:44:26 dedekind Exp $
+ * $Id: write.c,v 1.87 2004/11/16 20:36:12 dwmw2 Exp $
  *
  */
 
diff -Nru a/fs/jffs2/writev.c b/fs/jffs2/writev.c
--- a/fs/jffs2/writev.c	2005-03-01 23:38:57 -08:00
+++ b/fs/jffs2/writev.c	2005-03-01 23:38:57 -08:00
@@ -3,11 +3,11 @@
  *
  * Copyright (C) 2001, 2002 Red Hat, Inc.
  *
- * Created by David Woodhouse <dwmw2@redhat.com>
+ * Created by David Woodhouse <dwmw2@infradead.org>
  *
  * For licensing information, see the file 'LICENCE' in this directory.
  *
- * $Id: writev.c,v 1.5 2004/07/13 08:58:25 dwmw2 Exp $
+ * $Id: writev.c,v 1.6 2004/11/16 20:36:12 dwmw2 Exp $
  *
  */
 
diff -Nru a/fs/jfs/inode.c b/fs/jfs/inode.c
--- a/fs/jfs/inode.c	2005-03-01 23:38:44 -08:00
+++ b/fs/jfs/inode.c	2005-03-01 23:38:44 -08:00
@@ -81,8 +81,7 @@
 	 * Don't commit if inode has been committed since last being
 	 * marked dirty, or if it has been deleted.
 	 */
-	if (test_cflag(COMMIT_Nolink, inode) ||
-	    !test_cflag(COMMIT_Dirty, inode))
+	if (inode->i_nlink == 0 || !test_cflag(COMMIT_Dirty, inode))
 		return 0;
 
 	if (isReadOnly(inode)) {
@@ -100,7 +99,13 @@
 
 	tid = txBegin(inode->i_sb, COMMIT_INODE);
 	down(&JFS_IP(inode)->commit_sem);
-	rc = txCommit(tid, 1, &inode, wait ? COMMIT_SYNC : 0);
+
+	/*
+	 * Retest inode state after taking commit_sem
+	 */
+	if (inode->i_nlink && test_cflag(COMMIT_Dirty, inode))
+		rc = txCommit(tid, 1, &inode, wait ? COMMIT_SYNC : 0);
+
 	txEnd(tid);
 	up(&JFS_IP(inode)->commit_sem);
 	return rc;
diff -Nru a/fs/jfs/jfs_defragfs.h b/fs/jfs/jfs_defragfs.h
--- a/fs/jfs/jfs_defragfs.h	2005-03-01 23:39:07 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,51 +0,0 @@
-/*
- *   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
- *   the Free Software Foundation; either version 2 of the License, or 
- *   (at your option) any later version.
- * 
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
- *   the GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program;  if not, write to the Free Software 
- *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#ifndef	_H_JFS_DEFRAGFS
-#define _H_JFS_DEFRAGFS
-
-/*
- *	defragfs parameter list
- */
-struct defragfs {
-	uint flag;		/* 4: */
-	u8 dev;			/* 1: */
-	u8 pad[3];		/* 3: */
-	s32 fileset;		/* 4: */
-	u32 inostamp;		/* 4: */
-	u32 ino;		/* 4: */
-	u32 gen;		/* 4: */
-	s64 xoff;		/* 8: */
-	s64 old_xaddr;		/* 8: */
-	s64 new_xaddr;		/* 8: */
-	s32 xlen;		/* 4: */
-};
-
-/* plist flag */
-#define DEFRAGFS_SYNC		0x80000000
-#define DEFRAGFS_COMMIT		0x40000000
-#define DEFRAGFS_RELOCATE	0x10000000
-
-#define	INODE_TYPE		0x0000F000	/* IFREG or IFDIR */
-
-#define EXTENT_TYPE		0x000000ff
-#define DTPAGE			0x00000001
-#define XTPAGE			0x00000002
-#define DATAEXT			0x00000004
-#define EAEXT			0x00000008
-
-#endif				/* _H_JFS_DEFRAGFS */
diff -Nru a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c
--- a/fs/jfs/jfs_imap.c	2005-03-01 23:38:53 -08:00
+++ b/fs/jfs/jfs_imap.c	2005-03-01 23:38:53 -08:00
@@ -2604,6 +2604,12 @@
 		for (i = 0; i < SMAPSZ; i++)
 			iagp->inosmap[i] = cpu_to_le32(ONES);
 
+		/*
+		 * Invalidate the page after writing and syncing it.
+		 * After it's initialized, we access it in a different
+		 * address space
+		 */
+		set_bit(META_discard, &mp->flag);
 		flush_metapage(mp);
 
 		/*
diff -Nru a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c
--- a/fs/jfs/jfs_logmgr.c	2005-03-01 23:38:57 -08:00
+++ b/fs/jfs/jfs_logmgr.c	2005-03-01 23:38:57 -08:00
@@ -78,7 +78,7 @@
  * lbuf's ready to be redriven.  Protected by log_redrive_lock (jfsIO thread)
  */
 static struct lbuf *log_redrive_list;
-static spinlock_t log_redrive_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(log_redrive_lock);
 DECLARE_WAIT_QUEUE_HEAD(jfs_IO_thread_wait);
 
 
@@ -113,7 +113,7 @@
 /*
  *	log buffer cache synchronization
  */
-static spinlock_t jfsLCacheLock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(jfsLCacheLock);
 
 #define	LCACHE_LOCK(flags)	spin_lock_irqsave(&jfsLCacheLock, flags)
 #define	LCACHE_UNLOCK(flags)	spin_unlock_irqrestore(&jfsLCacheLock, flags)
@@ -980,11 +980,15 @@
 		 * actually make it to disk
 		 */
 		list_for_each_entry(sbi, &log->sb_list, log_list) {
+			if (sbi->flag & JFS_NOINTEGRITY)
+				continue;
 			filemap_fdatawrite(sbi->ipbmap->i_mapping);
 			filemap_fdatawrite(sbi->ipimap->i_mapping);
 			filemap_fdatawrite(sbi->sb->s_bdev->bd_inode->i_mapping);
 		}
 		list_for_each_entry(sbi, &log->sb_list, log_list) {
+			if (sbi->flag & JFS_NOINTEGRITY)
+				continue;
 			filemap_fdatawait(sbi->ipbmap->i_mapping);
 			filemap_fdatawait(sbi->ipimap->i_mapping);
 			filemap_fdatawait(sbi->sb->s_bdev->bd_inode->i_mapping);
diff -Nru a/fs/jfs/jfs_metapage.c b/fs/jfs/jfs_metapage.c
--- a/fs/jfs/jfs_metapage.c	2005-03-01 23:38:54 -08:00
+++ b/fs/jfs/jfs_metapage.c	2005-03-01 23:38:54 -08:00
@@ -28,7 +28,7 @@
 #include "jfs_txnmgr.h"
 #include "jfs_debug.h"
 
-static spinlock_t meta_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(meta_lock);
 
 #ifdef CONFIG_JFS_STATISTICS
 static struct {
@@ -396,14 +396,6 @@
 
 	jfs_info("__write_metapage: mp = 0x%p", mp);
 
-	if (test_bit(META_discard, &mp->flag)) {
-		/*
-		 * This metadata is no longer valid
-		 */
-		clear_bit(META_dirty, &mp->flag);
-		return;
-	}
-
 	page_index = mp->page->index;
 	page_offset =
 	    (mp->index - (page_index << l2BlocksPerPage)) << l2bsize;
@@ -549,6 +541,7 @@
 				goto again;
 			}
 
+			clear_bit(META_dirty, &mp->flag);
 			set_bit(META_discard, &mp->flag);
 			spin_unlock(&meta_lock);
 		} else {
diff -Nru a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c
--- a/fs/jfs/jfs_txnmgr.c	2005-03-01 23:38:58 -08:00
+++ b/fs/jfs/jfs_txnmgr.c	2005-03-01 23:38:58 -08:00
@@ -113,7 +113,7 @@
 /*
  *      transaction management lock
  */
-static spinlock_t jfsTxnLock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(jfsTxnLock);
 
 #define TXN_LOCK()              spin_lock(&jfsTxnLock)
 #define TXN_UNLOCK()            spin_unlock(&jfsTxnLock)
diff -Nru a/fs/jfs/namei.c b/fs/jfs/namei.c
--- a/fs/jfs/namei.c	2005-03-01 23:39:18 -08:00
+++ b/fs/jfs/namei.c	2005-03-01 23:39:18 -08:00
@@ -1233,7 +1233,7 @@
 	old_ip->i_ctime = CURRENT_TIME;
 	mark_inode_dirty(old_ip);
 
-	new_dir->i_ctime = new_dir->i_mtime = CURRENT_TIME;
+	new_dir->i_ctime = new_dir->i_mtime = current_fs_time(new_dir->i_sb);
 	mark_inode_dirty(new_dir);
 
 	/* Build list of inodes modified by this transaction */
diff -Nru a/fs/jfs/super.c b/fs/jfs/super.c
--- a/fs/jfs/super.c	2005-03-01 23:38:56 -08:00
+++ b/fs/jfs/super.c	2005-03-01 23:38:56 -08:00
@@ -464,7 +464,7 @@
 	 */
 	sb->s_maxbytes = min(((u64) PAGE_CACHE_SIZE << 32) - 1, sb->s_maxbytes);
 #endif
-
+	sb->s_time_gran = 1;
 	return 0;
 
 out_no_root:
diff -Nru a/fs/jfs/xattr.c b/fs/jfs/xattr.c
--- a/fs/jfs/xattr.c	2005-03-01 23:39:18 -08:00
+++ b/fs/jfs/xattr.c	2005-03-01 23:39:18 -08:00
@@ -91,6 +91,12 @@
 #define XATTR_OS2_PREFIX "os2."
 #define XATTR_OS2_PREFIX_LEN (sizeof (XATTR_OS2_PREFIX) - 1)
 
+/* XATTR_SECURITY_PREFIX is defined in include/linux/xattr.h */
+#define XATTR_SECURITY_PREFIX_LEN (sizeof (XATTR_SECURITY_PREFIX) - 1)
+
+#define XATTR_TRUSTED_PREFIX "trusted."
+#define XATTR_TRUSTED_PREFIX_LEN (sizeof (XATTR_TRUSTED_PREFIX) - 1)
+
 /*
  * These three routines are used to recognize on-disk extended attributes
  * that are in a recognized namespace.  If the attribute is not recognized,
@@ -111,6 +117,19 @@
 	    !strncmp(ea->name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN))
 		return FALSE;
 	/*
+	 * Check for "security."
+	 */
+	if ((ea->namelen >= XATTR_SECURITY_PREFIX_LEN) &&
+	    !strncmp(ea->name, XATTR_SECURITY_PREFIX,
+		     XATTR_SECURITY_PREFIX_LEN))
+		return FALSE;
+	/*
+	 * Check for "trusted."
+	 */
+	if ((ea->namelen >= XATTR_TRUSTED_PREFIX_LEN) &&
+	    !strncmp(ea->name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN))
+		return FALSE;
+	/*
 	 * Add any other valid namespace prefixes here
 	 */
 
@@ -770,6 +789,15 @@
 		 */
 		return can_set_system_xattr(inode, name, value, value_len);
 
+	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)
+		return 0;	/* Leave it to the security module */
+#endif
+		
 	if((strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN) != 0) &&
 	   (strncmp(name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN) != 0))
 		return -EOPNOTSUPP;
@@ -937,8 +965,17 @@
 
 static int can_get_xattr(struct inode *inode, const char *name)
 {
+#ifdef CONFIG_JFS_SECURITY
+	if(strncmp(name, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN) == 0)
+		return 0;
+#endif
+
+	if(strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) == 0)
+		return (capable(CAP_SYS_ADMIN) ? 0 : -EPERM);
+
 	if(strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN) == 0)
 		return 0;
+
 	return permission(inode, MAY_READ, NULL);
 }
 
@@ -1021,6 +1058,16 @@
 	return err;
 }
 
+/*
+ * No special permissions are needed to list attributes except for trusted.*
+ */
+static inline int can_list(struct jfs_ea *ea)
+{
+	return (strncmp(ea->name, XATTR_TRUSTED_PREFIX,
+			    XATTR_TRUSTED_PREFIX_LEN) ||
+		capable(CAP_SYS_ADMIN));
+}
+
 ssize_t jfs_listxattr(struct dentry * dentry, char *data, size_t buf_size)
 {
 	struct inode *inode = dentry->d_inode;
@@ -1045,8 +1092,10 @@
 	ealist = (struct jfs_ea_list *) ea_buf.xattr;
 
 	/* compute required size of list */
-	for (ea = FIRST_EA(ealist); ea < END_EALIST(ealist); ea = NEXT_EA(ea))
-		size += name_size(ea) + 1;
+	for (ea = FIRST_EA(ealist); ea < END_EALIST(ealist); ea = NEXT_EA(ea)) {
+	    	if (can_list(ea))
+			size += name_size(ea) + 1;
+	}
 
 	if (!data)
 		goto release;
@@ -1059,8 +1108,10 @@
 	/* Copy attribute names to buffer */
 	buffer = data;
 	for (ea = FIRST_EA(ealist); ea < END_EALIST(ealist); ea = NEXT_EA(ea)) {
-		int namelen = copy_name(buffer, ea);
-		buffer += namelen + 1;
+	    	if (can_list(ea)) {
+			int namelen = copy_name(buffer, ea);
+			buffer += namelen + 1;
+		}
 	}
 
       release:
diff -Nru a/fs/libfs.c b/fs/libfs.c
--- a/fs/libfs.c	2005-03-01 23:38:44 -08:00
+++ b/fs/libfs.c	2005-03-01 23:38:44 -08:00
@@ -212,6 +212,7 @@
 	s->s_blocksize_bits = 10;
 	s->s_magic = magic;
 	s->s_op = ops ? ops : &default_ops;
+	s->s_time_gran = 1;
 	root = new_inode(s);
 	if (!root)
 		goto Enomem;
@@ -374,6 +375,7 @@
 	s->s_blocksize_bits = PAGE_CACHE_SHIFT;
 	s->s_magic = magic;
 	s->s_op = &s_ops;
+	s->s_time_gran = 1;
 
 	inode = new_inode(s);
 	if (!inode)
@@ -416,7 +418,7 @@
 	return -ENOMEM;
 }
 
-static spinlock_t pin_fs_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(pin_fs_lock);
 
 int simple_pin_fs(char *name, struct vfsmount **mount, int *count)
 {
@@ -474,7 +476,7 @@
 char *simple_transaction_get(struct file *file, const char __user *buf, size_t size)
 {
 	struct simple_transaction_argresp *ar;
-	static spinlock_t simple_transaction_lock = SPIN_LOCK_UNLOCKED;
+	static DEFINE_SPINLOCK(simple_transaction_lock);
 
 	if (size > SIMPLE_TRANSACTION_LIMIT - 1)
 		return ERR_PTR(-EFBIG);
@@ -522,6 +524,7 @@
 EXPORT_SYMBOL(dcache_dir_open);
 EXPORT_SYMBOL(dcache_readdir);
 EXPORT_SYMBOL(generic_read_dir);
+EXPORT_SYMBOL(get_sb_pseudo);
 EXPORT_SYMBOL(simple_commit_write);
 EXPORT_SYMBOL(simple_dir_inode_operations);
 EXPORT_SYMBOL(simple_dir_operations);
diff -Nru a/fs/lockd/mon.c b/fs/lockd/mon.c
--- a/fs/lockd/mon.c	2005-03-01 23:39:08 -08:00
+++ b/fs/lockd/mon.c	2005-03-01 23:39:08 -08:00
@@ -19,7 +19,7 @@
 
 static struct rpc_clnt *	nsm_create(void);
 
-extern struct rpc_program	nsm_program;
+static struct rpc_program	nsm_program;
 
 /*
  * Local NSM state
@@ -237,7 +237,7 @@
 
 static struct rpc_stat		nsm_stats;
 
-struct rpc_program		nsm_program = {
+static struct rpc_program	nsm_program = {
 		.name		= "statd",
 		.number		= SM_PROGRAM,
 		.nrvers		= sizeof(nsm_version)/sizeof(nsm_version[0]),
diff -Nru a/fs/lockd/svc.c b/fs/lockd/svc.c
--- a/fs/lockd/svc.c	2005-03-01 23:39:07 -08:00
+++ b/fs/lockd/svc.c	2005-03-01 23:39:07 -08:00
@@ -38,7 +38,7 @@
 #define LOCKD_BUFSIZE		(1024 + NLMSVC_XDRSIZE)
 #define ALLOWED_SIGS		(sigmask(SIGKILL))
 
-extern struct svc_program	nlmsvc_program;
+static struct svc_program	nlmsvc_program;
 
 struct nlmsvc_binding *		nlmsvc_ops;
 EXPORT_SYMBOL(nlmsvc_ops);
@@ -476,11 +476,11 @@
 static struct svc_stat		nlmsvc_stats;
 
 #define NLM_NRVERS	(sizeof(nlmsvc_version)/sizeof(nlmsvc_version[0]))
-struct svc_program	nlmsvc_program = {
-	.pg_prog	= NLM_PROGRAM,		/* program number */
-	.pg_nvers	= NLM_NRVERS,		/* number of entries in nlmsvc_version */
-	.pg_vers	= nlmsvc_version,	/* version table */
-	.pg_name	= "lockd",		/* service name */
-	.pg_class	= "nfsd",		/* share authentication with nfsd */
-	.pg_stats	= &nlmsvc_stats,	/* stats table */
+static struct svc_program	nlmsvc_program = {
+	.pg_prog		= NLM_PROGRAM,		/* program number */
+	.pg_nvers		= NLM_NRVERS,		/* number of entries in nlmsvc_version */
+	.pg_vers		= nlmsvc_version,	/* version table */
+	.pg_name		= "lockd",		/* service name */
+	.pg_class		= "nfsd",		/* share authentication with nfsd */
+	.pg_stats		= &nlmsvc_stats,	/* stats table */
 };
diff -Nru a/fs/locks.c b/fs/locks.c
--- a/fs/locks.c	2005-03-01 23:39:16 -08:00
+++ b/fs/locks.c	2005-03-01 23:39:16 -08:00
@@ -1011,7 +1011,7 @@
  * @count:      length of area to check
  *
  * Searches the inode's list of locks to find any POSIX locks which conflict.
- * This function is called from locks_verify_area() and
+ * This function is called from rw_verify_area() and
  * locks_verify_truncate().
  */
 int locks_mandatory_area(int read_write, struct inode *inode,
@@ -1096,15 +1096,13 @@
 */
 void remove_lease(struct file_lock *fl)
 {
-	if (!IS_LEASE(fl))
-		return;
-
 	lock_kernel();
-
+	if (!fl || !IS_LEASE(fl))
+		goto out;
 	fl->fl_type = F_UNLCK | F_INPROGRESS;
 	fl->fl_break_time = jiffies - 10;
 	time_out_leases(fl->fl_file->f_dentry->d_inode);
-
+out:
 	unlock_kernel();
 }
 
@@ -1228,7 +1226,7 @@
 {
 	struct file_lock *flock = inode->i_flock;
 	if (flock && IS_LEASE(flock) && (flock->fl_type & F_WRLCK))
-		*time = CURRENT_TIME;
+		*time = current_fs_time(inode->i_sb);
 	else
 		*time = inode->i_mtime;
 }
@@ -1563,9 +1561,6 @@
 		error = filp->f_op->lock(filp, F_GETLK, &file_lock);
 		if (error < 0)
 			goto out;
-		else if (error == LOCK_USE_CLNT)
-		  /* Bypass for NFS with no locking - 2.0.36 compat */
-		  fl = posix_test_lock(filp, &file_lock);
 		else
 		  fl = (file_lock.fl_type == F_UNLCK ? NULL : &file_lock);
 	} else {
@@ -1708,9 +1703,6 @@
 		error = filp->f_op->lock(filp, F_GETLK, &file_lock);
 		if (error < 0)
 			goto out;
-		else if (error == LOCK_USE_CLNT)
-		  /* Bypass for NFS with no locking - 2.0.36 compat */
-		  fl = posix_test_lock(filp, &file_lock);
 		else
 		  fl = (file_lock.fl_type == F_UNLCK ? NULL : &file_lock);
 	} else {
diff -Nru a/fs/mbcache.c b/fs/mbcache.c
--- a/fs/mbcache.c	2005-03-01 23:39:17 -08:00
+++ b/fs/mbcache.c	2005-03-01 23:39:17 -08:00
@@ -54,6 +54,10 @@
 		printk(KERN_ERR f); \
 		printk("\n"); \
 	} while(0)
+
+#define MB_CACHE_WRITER ((unsigned short)~0U >> 1)
+
+DECLARE_WAIT_QUEUE_HEAD(mb_cache_queue);
 		
 MODULE_AUTHOR("Andreas Gruenbacher <a.gruenbacher@computer.org>");
 MODULE_DESCRIPTION("Meta block cache (for extended attributes)");
@@ -72,6 +76,20 @@
 EXPORT_SYMBOL(mb_cache_entry_find_next);
 #endif
 
+struct mb_cache {
+	struct list_head		c_cache_list;
+	const char			*c_name;
+	struct mb_cache_op		c_op;
+	atomic_t			c_entry_count;
+	int				c_bucket_bits;
+#ifndef MB_CACHE_INDEXES_COUNT
+	int				c_indexes_count;
+#endif
+	kmem_cache_t			*c_entry_cache;
+	struct list_head		*c_block_hash;
+	struct list_head		*c_indexes_hash[0];
+};
+
 
 /*
  * Global data: list of all mbcache's, lru list, and a spinlock for
@@ -81,7 +99,7 @@
 
 static LIST_HEAD(mb_cache_list);
 static LIST_HEAD(mb_cache_lru_list);
-static spinlock_t mb_cache_spinlock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(mb_cache_spinlock);
 static struct shrinker *mb_shrinker;
 
 static inline int
@@ -126,7 +144,7 @@
 {
 	struct mb_cache *cache = ce->e_cache;
 
-	mb_assert(atomic_read(&ce->e_used) == 0);
+	mb_assert(!(ce->e_used || ce->e_queued));
 	if (cache->c_op.free && cache->c_op.free(ce, gfp_mask)) {
 		/* free failed -- put back on the lru list
 		   for freeing later. */
@@ -143,9 +161,16 @@
 static inline void
 __mb_cache_entry_release_unlock(struct mb_cache_entry *ce)
 {
-	if (atomic_dec_and_test(&ce->e_used)) {
+	/* Wake up all processes queuing for this cache entry. */
+	if (ce->e_queued)
+		wake_up_all(&mb_cache_queue);
+	if (ce->e_used >= MB_CACHE_WRITER)
+		ce->e_used -= MB_CACHE_WRITER;
+	ce->e_used--;
+	if (!(ce->e_used || ce->e_queued)) {
 		if (!__mb_cache_entry_is_hashed(ce))
 			goto forget;
+		mb_assert(list_empty(&ce->e_lru_list));
 		list_add_tail(&ce->e_lru_list, &mb_cache_lru_list);
 	}
 	spin_unlock(&mb_cache_spinlock);
@@ -229,7 +254,7 @@
 	struct mb_cache *cache = NULL;
 
 	if(entry_size < sizeof(struct mb_cache_entry) +
-	   indexes_count * sizeof(struct mb_cache_entry_index))
+	   indexes_count * sizeof(((struct mb_cache_entry *) 0)->e_indexes[0]))
 		return NULL;
 
 	cache = kmalloc(sizeof(struct mb_cache) +
@@ -382,7 +407,8 @@
 		INIT_LIST_HEAD(&ce->e_lru_list);
 		INIT_LIST_HEAD(&ce->e_block_list);
 		ce->e_cache = cache;
-		atomic_set(&ce->e_used, 1);
+		ce->e_used = 1 + MB_CACHE_WRITER;
+		ce->e_queued = 0;
 	}
 	return ce;
 }
@@ -474,7 +500,8 @@
  *
  * Get a cache entry  by device / block number. (There can only be one entry
  * in the cache per device and block.) Returns NULL if no such cache entry
- * exists.
+ * exists. The returned cache entry is locked for exclusive access ("single
+ * writer").
  */
 struct mb_cache_entry *
 mb_cache_entry_get(struct mb_cache *cache, struct block_device *bdev,
@@ -490,9 +517,27 @@
 	list_for_each(l, &cache->c_block_hash[bucket]) {
 		ce = list_entry(l, struct mb_cache_entry, e_block_list);
 		if (ce->e_bdev == bdev && ce->e_block == block) {
+			DEFINE_WAIT(wait);
+
 			if (!list_empty(&ce->e_lru_list))
 				list_del_init(&ce->e_lru_list);
-			atomic_inc(&ce->e_used);
+
+			while (ce->e_used > 0) {
+				ce->e_queued++;
+				prepare_to_wait(&mb_cache_queue, &wait,
+						TASK_UNINTERRUPTIBLE);
+				spin_unlock(&mb_cache_spinlock);
+				schedule();
+				spin_lock(&mb_cache_spinlock);
+				ce->e_queued--;
+			}
+			finish_wait(&mb_cache_queue, &wait);
+			ce->e_used += 1 + MB_CACHE_WRITER;
+
+			if (!__mb_cache_entry_is_hashed(ce)) {
+				__mb_cache_entry_release_unlock(ce);
+				return NULL;
+			}
 			goto cleanup;
 		}
 	}
@@ -514,9 +559,30 @@
 			list_entry(l, struct mb_cache_entry,
 			           e_indexes[index].o_list);
 		if (ce->e_bdev == bdev && ce->e_indexes[index].o_key == key) {
+			DEFINE_WAIT(wait);
+
 			if (!list_empty(&ce->e_lru_list))
 				list_del_init(&ce->e_lru_list);
-			atomic_inc(&ce->e_used);
+
+			/* Incrementing before holding the lock gives readers
+			   priority over writers. */
+			ce->e_used++;
+			while (ce->e_used >= MB_CACHE_WRITER) {
+				ce->e_queued++;
+				prepare_to_wait(&mb_cache_queue, &wait,
+						TASK_UNINTERRUPTIBLE);
+				spin_unlock(&mb_cache_spinlock);
+				schedule();
+				spin_lock(&mb_cache_spinlock);
+				ce->e_queued--;
+			}
+			finish_wait(&mb_cache_queue, &wait);
+
+			if (!__mb_cache_entry_is_hashed(ce)) {
+				__mb_cache_entry_release_unlock(ce);
+				spin_lock(&mb_cache_spinlock);
+				return ERR_PTR(-EAGAIN);
+			}
 			return ce;
 		}
 		l = l->next;
@@ -530,7 +596,8 @@
  *
  * Find the first cache entry on a given device with a certain key in
  * an additional index. Additonal matches can be found with
- * mb_cache_entry_find_next(). Returns NULL if no match was found.
+ * mb_cache_entry_find_next(). Returns NULL if no match was found. The
+ * returned cache entry is locked for shared access ("multiple readers").
  *
  * @cache: the cache to search
  * @index: the number of the additonal index to search (0<=index<indexes_count)
diff -Nru a/fs/minix/bitmap.c b/fs/minix/bitmap.c
--- a/fs/minix/bitmap.c	2005-03-01 23:39:08 -08:00
+++ b/fs/minix/bitmap.c	2005-03-01 23:39:08 -08:00
@@ -253,7 +253,7 @@
 	inode->i_uid = current->fsuid;
 	inode->i_gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid;
 	inode->i_ino = j;
-	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
+	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
 	inode->i_blocks = inode->i_blksize = 0;
 	memset(&minix_i(inode)->u, 0, sizeof(minix_i(inode)->u));
 	insert_inode_hash(inode);
diff -Nru a/fs/minix/dir.c b/fs/minix/dir.c
--- a/fs/minix/dir.c	2005-03-01 23:39:08 -08:00
+++ b/fs/minix/dir.c	2005-03-01 23:39:08 -08:00
@@ -246,7 +246,7 @@
 	memset (de->name + namelen, 0, sbi->s_dirsize - namelen - 2);
 	de->inode = inode->i_ino;
 	err = dir_commit_chunk(page, from, to);
-	dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+	dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
 	mark_inode_dirty(dir);
 out_put:
 	dir_put_page(page);
@@ -275,7 +275,7 @@
 		unlock_page(page);
 	}
 	dir_put_page(page);
-	inode->i_ctime = inode->i_mtime = CURRENT_TIME;
+	inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC;
 	mark_inode_dirty(inode);
 	return err;
 }
@@ -378,7 +378,7 @@
 		unlock_page(page);
 	}
 	dir_put_page(page);
-	dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+	dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
 	mark_inode_dirty(dir);
 }
 
diff -Nru a/fs/minix/itree_common.c b/fs/minix/itree_common.c
--- a/fs/minix/itree_common.c	2005-03-01 23:39:07 -08:00
+++ b/fs/minix/itree_common.c	2005-03-01 23:39:07 -08:00
@@ -6,7 +6,7 @@
 	struct buffer_head *bh;
 } Indirect;
 
-static rwlock_t pointers_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(pointers_lock);
 
 static inline void add_chain(Indirect *p, struct buffer_head *bh, block_t *v)
 {
@@ -124,7 +124,7 @@
 
 	/* We are done with atomic stuff, now do the rest of housekeeping */
 
-	inode->i_ctime = CURRENT_TIME;
+	inode->i_ctime = CURRENT_TIME_SEC;
 
 	/* had we spliced it onto indirect block? */
 	if (where->bh)
@@ -342,7 +342,7 @@
 		}
 		first_whole++;
 	}
-	inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+	inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC;
 	mark_inode_dirty(inode);
 }
 
diff -Nru a/fs/minix/namei.c b/fs/minix/namei.c
--- a/fs/minix/namei.c	2005-03-01 23:38:55 -08:00
+++ b/fs/minix/namei.c	2005-03-01 23:38:55 -08:00
@@ -138,7 +138,7 @@
 	if (inode->i_nlink >= minix_sb(inode->i_sb)->s_link_max)
 		return -EMLINK;
 
-	inode->i_ctime = CURRENT_TIME;
+	inode->i_ctime = CURRENT_TIME_SEC;
 	inc_count(inode);
 	atomic_inc(&inode->i_count);
 	return add_nondir(dentry, inode);
@@ -259,7 +259,7 @@
 			goto out_dir;
 		inc_count(old_inode);
 		minix_set_link(new_de, new_page, old_inode);
-		new_inode->i_ctime = CURRENT_TIME;
+		new_inode->i_ctime = CURRENT_TIME_SEC;
 		if (dir_de)
 			new_inode->i_nlink--;
 		dec_count(new_inode);
diff -Nru a/fs/msdos/namei.c b/fs/msdos/namei.c
--- a/fs/msdos/namei.c	2005-03-01 23:39:18 -08:00
+++ b/fs/msdos/namei.c	2005-03-01 23:39:18 -08:00
@@ -12,25 +12,28 @@
 #include <linux/msdos_fs.h>
 #include <linux/smp_lock.h>
 
-
 /* MS-DOS "device special files" */
 static const unsigned char *reserved_names[] = {
-	"CON     ","PRN     ","NUL     ","AUX     ",
-	"LPT1    ","LPT2    ","LPT3    ","LPT4    ",
-	"COM1    ","COM2    ","COM3    ","COM4    ",
+	"CON     ", "PRN     ", "NUL     ", "AUX     ",
+	"LPT1    ", "LPT2    ", "LPT3    ", "LPT4    ",
+	"COM1    ", "COM2    ", "COM3    ", "COM4    ",
 	NULL
 };
 
 /* Characters that are undesirable in an MS-DOS file name */
 static unsigned char bad_chars[] = "*?<>|\"";
 static unsigned char bad_if_strict_pc[] = "+=,; ";
-static unsigned char bad_if_strict_atari[] = " "; /* GEMDOS is less restrictive */
-#define	bad_if_strict(opts) ((opts)->atari ? bad_if_strict_atari : bad_if_strict_pc)
+/* GEMDOS is less restrictive */
+static unsigned char bad_if_strict_atari[] = " ";
+
+#define bad_if_strict(opts) \
+	((opts)->atari ? bad_if_strict_atari : bad_if_strict_pc)
 
 /***** Formats an MS-DOS file name. Rejects invalid names. */
 static int msdos_format_name(const unsigned char *name, int len,
-	unsigned char *res, struct fat_mount_options *opts)
-	/* name is the proposed name, len is its length, res is
+			     unsigned char *res, struct fat_mount_options *opts)
+	/*
+	 * name is the proposed name, len is its length, res is
 	 * the resulting name, opts->name_check is either (r)elaxed,
 	 * (n)ormal or (s)trict, opts->dotsOK allows dots at the
 	 * beginning of name (for hidden files)
@@ -41,52 +44,66 @@
 	unsigned char c;
 	int space;
 
-	if (name[0] == '.') {  /* dotfile because . and .. already done */
+	if (name[0] == '.') {	/* dotfile because . and .. already done */
 		if (opts->dotsOK) {
 			/* Get rid of dot - test for it elsewhere */
-			name++; len--;
-		}
-		else if (!opts->atari) return -EINVAL;
+			name++;
+			len--;
+		} else if (!opts->atari)
+			return -EINVAL;
 	}
-	/* disallow names that _really_ start with a dot for MS-DOS, GEMDOS does
-	 * not care */
+	/*
+	 * disallow names that _really_ start with a dot for MS-DOS,
+	 * GEMDOS does not care
+	 */
 	space = !opts->atari;
 	c = 0;
-	for (walk = res; len && walk-res < 8; walk++) {
-	    	c = *name++;
+	for (walk = res; len && walk - res < 8; walk++) {
+		c = *name++;
 		len--;
-		if (opts->name_check != 'r' && strchr(bad_chars,c))
+		if (opts->name_check != 'r' && strchr(bad_chars, c))
 			return -EINVAL;
-		if (opts->name_check == 's' && strchr(bad_if_strict(opts),c))
+		if (opts->name_check == 's' && strchr(bad_if_strict(opts), c))
 			return -EINVAL;
-  		if (c >= 'A' && c <= 'Z' && opts->name_check == 's')
+		if (c >= 'A' && c <= 'Z' && opts->name_check == 's')
 			return -EINVAL;
-		if (c < ' ' || c == ':' || c == '\\') return -EINVAL;
-/*  0xE5 is legal as a first character, but we must substitute 0x05     */
-/*  because 0xE5 marks deleted files.  Yes, DOS really does this.       */
-/*  It seems that Microsoft hacked DOS to support non-US characters     */
-/*  after the 0xE5 character was already in use to mark deleted files.  */
-		if((res==walk) && (c==0xE5)) c=0x05;
-		if (c == '.') break;
+		if (c < ' ' || c == ':' || c == '\\')
+			return -EINVAL;
+	/*
+	 * 0xE5 is legal as a first character, but we must substitute
+	 * 0x05 because 0xE5 marks deleted files.  Yes, DOS really
+	 * does this.
+	 * It seems that Microsoft hacked DOS to support non-US
+	 * characters after the 0xE5 character was already in use to
+	 * mark deleted files.
+	 */
+		if ((res == walk) && (c == 0xE5))
+			c = 0x05;
+		if (c == '.')
+			break;
 		space = (c == ' ');
-		*walk = (!opts->nocase && c >= 'a' && c <= 'z') ? c-32 : c;
+		*walk = (!opts->nocase && c >= 'a' && c <= 'z') ? c - 32 : c;
 	}
-	if (space) return -EINVAL;
+	if (space)
+		return -EINVAL;
 	if (opts->name_check == 's' && len && c != '.') {
 		c = *name++;
 		len--;
-		if (c != '.') return -EINVAL;
+		if (c != '.')
+			return -EINVAL;
 	}
-	while (c != '.' && len--) c = *name++;
+	while (c != '.' && len--)
+		c = *name++;
 	if (c == '.') {
-		while (walk-res < 8) *walk++ = ' ';
-		while (len > 0 && walk-res < MSDOS_NAME) {
+		while (walk - res < 8)
+			*walk++ = ' ';
+		while (len > 0 && walk - res < MSDOS_NAME) {
 			c = *name++;
 			len--;
-			if (opts->name_check != 'r' && strchr(bad_chars,c))
+			if (opts->name_check != 'r' && strchr(bad_chars, c))
 				return -EINVAL;
 			if (opts->name_check == 's' &&
-			    strchr(bad_if_strict(opts),c))
+			    strchr(bad_if_strict(opts), c))
 				return -EINVAL;
 			if (c < ' ' || c == ':' || c == '\\')
 				return -EINVAL;
@@ -98,16 +115,23 @@
 			if (c >= 'A' && c <= 'Z' && opts->name_check == 's')
 				return -EINVAL;
 			space = c == ' ';
-			*walk++ = (!opts->nocase && c >= 'a' && c <= 'z') ? c-32 : c;
+			if (!opts->nocase && c >= 'a' && c <= 'z')
+				*walk++ = c - 32;
+			else
+				*walk++ = c;
 		}
-		if (space) return -EINVAL;
-		if (opts->name_check == 's' && len) return -EINVAL;
+		if (space)
+			return -EINVAL;
+		if (opts->name_check == 's' && len)
+			return -EINVAL;
 	}
-	while (walk-res < MSDOS_NAME) *walk++ = ' ';
+	while (walk - res < MSDOS_NAME)
+		*walk++ = ' ';
 	if (!opts->atari)
 		/* GEMDOS is less stupid and has no reserved names */
 		for (reserved = reserved_names; *reserved; reserved++)
-			if (!strncmp(res,*reserved,8)) return -EINVAL;
+			if (!strncmp(res, *reserved, 8))
+				return -EINVAL;
 	return 0;
 }
 
@@ -121,12 +145,13 @@
 	int res;
 
 	dotsOK = MSDOS_SB(dir->i_sb)->options.dotsOK;
-	res = msdos_format_name(name,len, msdos_name,&MSDOS_SB(dir->i_sb)->options);
+	res = msdos_format_name(name, len, msdos_name,
+				&MSDOS_SB(dir->i_sb)->options);
 	if (res < 0)
 		return -ENOENT;
 	res = fat_scan(dir, msdos_name, bh, de, i_pos);
 	if (!res && dotsOK) {
-		if (name[0]=='.') {
+		if (name[0] == '.') {
 			if (!((*de)->attr & ATTR_HIDDEN))
 				res = -ENOENT;
 		} else {
@@ -145,10 +170,10 @@
  */
 static int msdos_hash(struct dentry *dentry, struct qstr *qstr)
 {
-	struct fat_mount_options *options = & (MSDOS_SB(dentry->d_sb)->options);
+	struct fat_mount_options *options = &MSDOS_SB(dentry->d_sb)->options;
 	unsigned char msdos_name[MSDOS_NAME];
 	int error;
-	
+
 	error = msdos_format_name(qstr->name, qstr->len, msdos_name, options);
 	if (!error)
 		qstr->hash = full_name_hash(msdos_name, MSDOS_NAME);
@@ -161,7 +186,7 @@
  */
 static int msdos_cmp(struct dentry *dentry, struct qstr *a, struct qstr *b)
 {
-	struct fat_mount_options *options = & (MSDOS_SB(dentry->d_sb)->options);
+	struct fat_mount_options *options = &MSDOS_SB(dentry->d_sb)->options;
 	unsigned char a_msdos_name[MSDOS_NAME], b_msdos_name[MSDOS_NAME];
 	int error;
 
@@ -182,7 +207,6 @@
 	goto out;
 }
 
-
 static struct dentry_operations msdos_dentry_operations = {
 	.d_hash		= msdos_hash,
 	.d_compare	= msdos_cmp,
@@ -194,7 +218,7 @@
 
 /***** Get inode using directory and name */
 static struct dentry *msdos_lookup(struct inode *dir, struct dentry *dentry,
-		struct nameidata *nd)
+				   struct nameidata *nd)
 {
 	struct super_block *sb = dir->i_sb;
 	struct inode *inode = NULL;
@@ -202,7 +226,7 @@
 	struct buffer_head *bh = NULL;
 	loff_t i_pos;
 	int res;
-	
+
 	dentry->d_op = &msdos_dentry_operations;
 
 	lock_kernel();
@@ -243,7 +267,7 @@
 	/*
 	 * XXX all times should be set by caller upon successful completion.
 	 */
-	dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+	dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
 	mark_inode_dirty(dir);
 
 	memcpy((*de)->name, name, MSDOS_NAME);
@@ -260,7 +284,7 @@
 
 /***** Create a file */
 static int msdos_create(struct inode *dir, struct dentry *dentry, int mode,
-		struct nameidata *nd)
+			struct nameidata *nd)
 {
 	struct super_block *sb = dir->i_sb;
 	struct buffer_head *bh;
@@ -271,19 +295,19 @@
 	unsigned char msdos_name[MSDOS_NAME];
 
 	lock_kernel();
-	res = msdos_format_name(dentry->d_name.name,dentry->d_name.len,
+	res = msdos_format_name(dentry->d_name.name, dentry->d_name.len,
 				msdos_name, &MSDOS_SB(sb)->options);
 	if (res < 0) {
 		unlock_kernel();
 		return res;
 	}
-	is_hid = (dentry->d_name.name[0]=='.') && (msdos_name[0]!='.');
+	is_hid = (dentry->d_name.name[0] == '.') && (msdos_name[0] != '.');
 	/* Have to do it due to foo vs. .foo conflicts */
 	if (fat_scan(dir, msdos_name, &bh, &de, &i_pos) >= 0) {
 		brelse(bh);
 		unlock_kernel();
 		return -EINVAL;
- 	}
+	}
 	inode = NULL;
 	res = msdos_add_entry(dir, msdos_name, &bh, &de, &i_pos, 0, is_hid);
 	if (res) {
@@ -296,7 +320,7 @@
 		unlock_kernel();
 		return res;
 	}
-	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
+	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
 	mark_inode_dirty(inode);
 	d_instantiate(dentry, inode);
 	unlock_kernel();
@@ -330,7 +354,7 @@
 	mark_buffer_dirty(bh);
 	fat_detach(inode);
 	inode->i_nlink = 0;
-	inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+	inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
 	dir->i_nlink--;
 	mark_inode_dirty(inode);
 	mark_inode_dirty(dir);
@@ -349,18 +373,18 @@
 	struct buffer_head *bh;
 	struct msdos_dir_entry *de;
 	struct inode *inode;
-	int res,is_hid;
+	int res, is_hid;
 	unsigned char msdos_name[MSDOS_NAME];
 	loff_t i_pos;
 
 	lock_kernel();
-	res = msdos_format_name(dentry->d_name.name,dentry->d_name.len,
+	res = msdos_format_name(dentry->d_name.name, dentry->d_name.len,
 				msdos_name, &MSDOS_SB(sb)->options);
 	if (res < 0) {
 		unlock_kernel();
 		return res;
 	}
-	is_hid = (dentry->d_name.name[0]=='.') && (msdos_name[0]!='.');
+	is_hid = (dentry->d_name.name[0] == '.') && (msdos_name[0] != '.');
 	/* foo vs .foo situation */
 	if (fat_scan(dir, msdos_name, &bh, &de, &i_pos) >= 0)
 		goto out_exist;
@@ -376,7 +400,7 @@
 	res = 0;
 
 	dir->i_nlink++;
-	inode->i_nlink = 2; /* no need to mark them dirty */
+	inode->i_nlink = 2;	/* no need to mark them dirty */
 
 	res = fat_new_dir(inode, dir, 0);
 	if (res)
@@ -392,7 +416,7 @@
 
 mkdir_error:
 	inode->i_nlink = 0;
-	inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+	inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
 	dir->i_nlink--;
 	mark_inode_dirty(inode);
 	mark_inode_dirty(dir);
@@ -430,7 +454,7 @@
 	fat_detach(inode);
 	brelse(bh);
 	inode->i_nlink = 0;
-	inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+	inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
 	mark_inode_dirty(inode);
 	mark_inode_dirty(dir);
 	res = 0;
@@ -440,14 +464,16 @@
 }
 
 static int do_msdos_rename(struct inode *old_dir, unsigned char *old_name,
-    struct dentry *old_dentry,
-    struct inode *new_dir, unsigned char *new_name, struct dentry *new_dentry,
-    struct buffer_head *old_bh,
-    struct msdos_dir_entry *old_de, loff_t old_i_pos, int is_hid)
-{
-	struct buffer_head *new_bh=NULL,*dotdot_bh=NULL;
-	struct msdos_dir_entry *new_de,*dotdot_de;
-	struct inode *old_inode,*new_inode;
+			   struct dentry *old_dentry,
+			   struct inode *new_dir, unsigned char *new_name,
+			   struct dentry *new_dentry,
+			   struct buffer_head *old_bh,
+			   struct msdos_dir_entry *old_de, loff_t old_i_pos,
+			   int is_hid)
+{
+	struct buffer_head *new_bh = NULL, *dotdot_bh = NULL;
+	struct msdos_dir_entry *new_de, *dotdot_de;
+	struct inode *old_inode, *new_inode;
 	loff_t new_i_pos, dotdot_i_pos;
 	int error;
 	int is_dir;
@@ -456,8 +482,8 @@
 	new_inode = new_dentry->d_inode;
 	is_dir = S_ISDIR(old_inode->i_mode);
 
-	if (fat_scan(new_dir, new_name, &new_bh, &new_de, &new_i_pos) >= 0
-	    && !new_inode)
+	if (fat_scan(new_dir, new_name, &new_bh, &new_de, &new_i_pos) >= 0 &&
+	    !new_inode)
 		goto degenerate_case;
 	if (is_dir) {
 		if (new_inode) {
@@ -493,16 +519,17 @@
 		MSDOS_I(old_inode)->i_attrs &= ~ATTR_HIDDEN;
 	mark_inode_dirty(old_inode);
 	old_dir->i_version++;
-	old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
+	old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME_SEC;
 	mark_inode_dirty(old_dir);
 	if (new_inode) {
 		new_inode->i_nlink--;
-		new_inode->i_ctime = CURRENT_TIME;
+		new_inode->i_ctime = CURRENT_TIME_SEC;
 		mark_inode_dirty(new_inode);
 	}
 	if (dotdot_bh) {
 		dotdot_de->start = cpu_to_le16(MSDOS_I(new_dir)->i_logstart);
-		dotdot_de->starthi = cpu_to_le16((MSDOS_I(new_dir)->i_logstart) >> 16);
+		dotdot_de->starthi =
+			cpu_to_le16((MSDOS_I(new_dir)->i_logstart) >> 16);
 		mark_buffer_dirty(dotdot_bh);
 		old_dir->i_nlink--;
 		mark_inode_dirty(old_dir);
@@ -522,7 +549,7 @@
 
 degenerate_case:
 	error = -EINVAL;
-	if (new_de!=old_de)
+	if (new_de != old_de)
 		goto out;
 	if (is_hid)
 		MSDOS_I(old_inode)->i_attrs |= ATTR_HIDDEN;
@@ -530,14 +557,14 @@
 		MSDOS_I(old_inode)->i_attrs &= ~ATTR_HIDDEN;
 	mark_inode_dirty(old_inode);
 	old_dir->i_version++;
-	old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
+	old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME_SEC;
 	mark_inode_dirty(old_dir);
 	return 0;
 }
 
 /***** Rename, a wrapper for rename_same_dir & rename_diff_dir */
 static int msdos_rename(struct inode *old_dir, struct dentry *old_dentry,
-		struct inode *new_dir, struct dentry *new_dentry)
+			struct inode *new_dir, struct dentry *new_dentry)
 {
 	struct buffer_head *old_bh;
 	struct msdos_dir_entry *old_de;
@@ -547,18 +574,21 @@
 
 	lock_kernel();
 	error = msdos_format_name(old_dentry->d_name.name,
-				  old_dentry->d_name.len,old_msdos_name,
+				  old_dentry->d_name.len, old_msdos_name,
 				  &MSDOS_SB(old_dir->i_sb)->options);
 	if (error < 0)
 		goto rename_done;
 	error = msdos_format_name(new_dentry->d_name.name,
-				  new_dentry->d_name.len,new_msdos_name,
+				  new_dentry->d_name.len, new_msdos_name,
 				  &MSDOS_SB(new_dir->i_sb)->options);
 	if (error < 0)
 		goto rename_done;
 
-	is_hid  = (new_dentry->d_name.name[0]=='.') && (new_msdos_name[0]!='.');
-	old_hid = (old_dentry->d_name.name[0]=='.') && (old_msdos_name[0]!='.');
+	is_hid =
+	     (new_dentry->d_name.name[0] == '.') && (new_msdos_name[0] != '.');
+	old_hid =
+	     (old_dentry->d_name.name[0] == '.') && (old_msdos_name[0] != '.');
+
 	error = fat_scan(old_dir, old_msdos_name, &old_bh, &old_de, &old_i_pos);
 	if (error < 0)
 		goto rename_done;
@@ -583,7 +613,7 @@
 	.setattr	= fat_notify_change,
 };
 
-static int msdos_fill_super(struct super_block *sb,void *data, int silent)
+static int msdos_fill_super(struct super_block *sb, void *data, int silent)
 {
 	int res;
 
@@ -596,7 +626,8 @@
 }
 
 static struct super_block *msdos_get_sb(struct file_system_type *fs_type,
-	int flags, const char *dev_name, void *data)
+					int flags, const char *dev_name,
+					void *data)
 {
 	return get_sb_bdev(fs_type, flags, dev_name, data, msdos_fill_super);
 }
diff -Nru a/fs/namei.c b/fs/namei.c
--- a/fs/namei.c	2005-03-01 23:38:55 -08:00
+++ b/fs/namei.c	2005-03-01 23:38:55 -08:00
@@ -116,13 +116,14 @@
 	int retval;
 	unsigned long len = PATH_MAX;
 
-	if ((unsigned long) filename >= TASK_SIZE) {
-		if (!segment_eq(get_fs(), KERNEL_DS))
+	if (!segment_eq(get_fs(), KERNEL_DS)) {
+		if ((unsigned long) filename >= TASK_SIZE)
 			return -EFAULT;
-	} else if (TASK_SIZE - (unsigned long) filename < PATH_MAX)
-		len = TASK_SIZE - (unsigned long) filename;
+		if (TASK_SIZE - (unsigned long) filename < PATH_MAX)
+			len = TASK_SIZE - (unsigned long) filename;
+	}
 
-	retval = strncpy_from_user((char *)page, filename, len);
+	retval = strncpy_from_user(page, filename, len);
 	if (retval > 0) {
 		if (retval < len)
 			return 0;
@@ -168,21 +169,6 @@
 {
 	umode_t			mode = inode->i_mode;
 
-	if (mask & MAY_WRITE) {
-		/*
-		 * Nobody gets write access to a read-only fs.
-		 */
-		if (IS_RDONLY(inode) &&
-		    (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
-			return -EROFS;
-
-		/*
-		 * Nobody gets write access to an immutable file.
-		 */
-		if (IS_IMMUTABLE(inode))
-			return -EACCES;
-	}
-
 	if (current->fsuid == inode->i_uid)
 		mode >>= 6;
 	else {
@@ -224,14 +210,30 @@
 	return -EACCES;
 }
 
-int permission(struct inode * inode,int mask, struct nameidata *nd)
+int permission(struct inode *inode, int mask, struct nameidata *nd)
 {
-	int retval;
-	int submask;
+	int retval, submask;
+
+	if (mask & MAY_WRITE) {
+		umode_t mode = inode->i_mode;
+
+		/*
+		 * Nobody gets write access to a read-only fs.
+		 */
+		if (IS_RDONLY(inode) &&
+		    (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
+			return -EROFS;
+
+		/*
+		 * Nobody gets write access to an immutable file.
+		 */
+		if (IS_IMMUTABLE(inode))
+			return -EACCES;
+	}
+
 
 	/* Ordinary permission routines do not understand MAY_APPEND. */
 	submask = mask & ~MAY_APPEND;
-
 	if (inode->i_op && inode->i_op->permission)
 		retval = inode->i_op->permission(inode, submask, nd);
 	else
@@ -480,6 +482,24 @@
 	return PTR_ERR(link);
 }
 
+static inline int __do_follow_link(struct dentry *dentry, struct nameidata *nd)
+{
+	int error;
+
+	touch_atime(nd->mnt, dentry);
+	nd_set_link(nd, NULL);
+	error = dentry->d_inode->i_op->follow_link(dentry, nd);
+	if (!error) {
+		char *s = nd_get_link(nd);
+		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);
+	}
+
+	return error;
+}
+
 /*
  * This limits recursive symlink follows to 8, while
  * limiting consecutive symlinks to 40.
@@ -502,16 +522,7 @@
 	current->link_count++;
 	current->total_link_count++;
 	nd->depth++;
-	touch_atime(nd->mnt, dentry);
-	nd_set_link(nd, NULL);
-	err = dentry->d_inode->i_op->follow_link(dentry, nd);
-	if (!err) {
-		char *s = nd_get_link(nd);
-		if (s)
-			err = __vfs_follow_link(nd, s);
-		if (dentry->d_inode->i_op->put_link)
-			dentry->d_inode->i_op->put_link(dentry, nd);
-	}
+	err = __do_follow_link(dentry, nd);
 	current->link_count--;
 	nd->depth--;
 	return err;
@@ -1468,16 +1479,7 @@
 	error = security_inode_follow_link(dentry, nd);
 	if (error)
 		goto exit_dput;
-	touch_atime(nd->mnt, dentry);
-	nd_set_link(nd, NULL);
-	error = dentry->d_inode->i_op->follow_link(dentry, nd);
-	if (!error) {
-		char *s = nd_get_link(nd);
-		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);
-	}
+	error = __do_follow_link(dentry, nd);
 	dput(dentry);
 	if (error)
 		return error;
diff -Nru a/fs/namespace.c b/fs/namespace.c
--- a/fs/namespace.c	2005-03-01 23:39:07 -08:00
+++ b/fs/namespace.c	2005-03-01 23:39:07 -08:00
@@ -37,7 +37,7 @@
 #endif
 
 /* spinlock for vfsmount related operations, inplace of dcache_lock */
-spinlock_t vfsmount_lock __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
+ __cacheline_aligned_in_smp DEFINE_SPINLOCK(vfsmount_lock);
 
 static struct list_head *mount_hashtable;
 static int hash_mask, hash_bits;
diff -Nru a/fs/nfs/dir.c b/fs/nfs/dir.c
--- a/fs/nfs/dir.c	2005-03-01 23:38:57 -08:00
+++ b/fs/nfs/dir.c	2005-03-01 23:38:57 -08:00
@@ -40,8 +40,6 @@
 static int nfs_opendir(struct inode *, struct file *);
 static int nfs_readdir(struct file *, void *, filldir_t);
 static struct dentry *nfs_lookup(struct inode *, struct dentry *, struct nameidata *);
-static int nfs_cached_lookup(struct inode *, struct dentry *,
-				struct nfs_fh *, struct nfs_fattr *);
 static int nfs_create(struct inode *, struct dentry *, int, struct nameidata *);
 static int nfs_mkdir(struct inode *, struct dentry *, int);
 static int nfs_rmdir(struct inode *, struct dentry *);
@@ -294,24 +292,13 @@
 	return res;
 }
 
-static unsigned int nfs_type2dtype[] = {
-	DT_UNKNOWN,
-	DT_REG,
-	DT_DIR,
-	DT_BLK,
-	DT_CHR,
-	DT_LNK,
-	DT_SOCK,
-	DT_UNKNOWN,
-	DT_FIFO
-};
-
-static inline
-unsigned int nfs_type_to_d_type(enum nfs_ftype type)
+static inline unsigned int dt_type(struct inode *inode)
 {
-	return nfs_type2dtype[type];
+	return (inode->i_mode >> 12) & 15;
 }
 
+static struct dentry *nfs_readdir_lookup(nfs_readdir_descriptor_t *desc);
+
 /*
  * Once we've found the start of the dirent within a page: fill 'er up...
  */
@@ -321,6 +308,7 @@
 {
 	struct file	*file = desc->file;
 	struct nfs_entry *entry = desc->entry;
+	struct dentry	*dentry = NULL;
 	unsigned long	fileid;
 	int		loop_count = 0,
 			res;
@@ -333,9 +321,16 @@
 		 *	 retrieving the current dirent on the server */
 		fileid = nfs_fileid_to_ino_t(entry->ino);
 
+		/* Get a dentry if we have one */
+		if (dentry != NULL)
+			dput(dentry);
+		dentry = nfs_readdir_lookup(desc);
+
 		/* Use readdirplus info */
-		if (desc->plus && (entry->fattr->valid & NFS_ATTR_FATTR))
-			d_type = nfs_type_to_d_type(entry->fattr->type);
+		if (dentry != NULL && dentry->d_inode != NULL) {
+			d_type = dt_type(dentry->d_inode);
+			fileid = dentry->d_inode->i_ino;
+		}
 
 		res = filldir(dirent, entry->name, entry->len, 
 			      entry->prev_cookie, fileid, d_type);
@@ -352,7 +347,8 @@
 		}
 	}
 	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);
 	return res;
 }
@@ -615,24 +611,10 @@
 		goto out_valid;
 	}
 
-	/*
-	 * Note: we're not holding inode->i_sem and so may be racing with
-	 * operations that change the directory. We therefore save the
-	 * change attribute *before* we do the RPC call.
-	 */
-	verifier = nfs_save_change_attribute(dir);
-	error = nfs_cached_lookup(dir, dentry, &fhandle, &fattr);
-	if (!error) {
-		if (nfs_compare_fh(NFS_FH(inode), &fhandle))
-			goto out_bad;
-		if (nfs_lookup_verify_inode(inode, isopen))
-			goto out_zap_parent;
-		goto out_valid_renew;
-	}
-
 	if (NFS_STALE(inode))
 		goto out_bad;
 
+	verifier = nfs_save_change_attribute(dir);
 	error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, &fhandle, &fattr);
 	if (error)
 		goto out_bad;
@@ -641,7 +623,6 @@
 	if ((error = nfs_refresh_inode(inode, &fattr)) != 0)
 		goto out_bad;
 
- out_valid_renew:
 	nfs_renew_times(dentry);
 	nfs_set_verifier(dentry, verifier);
  out_valid:
@@ -723,6 +704,7 @@
 
 static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd)
 {
+	struct dentry *res;
 	struct inode *inode = NULL;
 	int error;
 	struct nfs_fh fhandle;
@@ -731,11 +713,11 @@
 	dfprintk(VFS, "NFS: lookup(%s/%s)\n",
 		dentry->d_parent->d_name.name, dentry->d_name.name);
 
-	error = -ENAMETOOLONG;
+	res = ERR_PTR(-ENAMETOOLONG);
 	if (dentry->d_name.len > NFS_SERVER(dir)->namelen)
 		goto out;
 
-	error = -ENOMEM;
+	res = ERR_PTR(-ENOMEM);
 	dentry->d_op = NFS_PROTO(dir)->dentry_ops;
 
 	lock_kernel();
@@ -746,29 +728,27 @@
 	if (nfs_is_exclusive_create(dir, nd))
 		goto no_entry;
 
-	error = nfs_cached_lookup(dir, dentry, &fhandle, &fattr);
-	if (error != 0) {
-		error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name,
-				&fhandle, &fattr);
-		if (error == -ENOENT)
-			goto no_entry;
-		if (error != 0)
-			goto out_unlock;
+	error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, &fhandle, &fattr);
+	if (error == -ENOENT)
+		goto no_entry;
+	if (error < 0) {
+		res = ERR_PTR(error);
+		goto out_unlock;
 	}
-	error = -EACCES;
+	res = ERR_PTR(-EACCES);
 	inode = nfs_fhget(dentry->d_sb, &fhandle, &fattr);
 	if (!inode)
 		goto out_unlock;
 no_entry:
-	error = 0;
-	d_add(dentry, inode);
+	res = d_add_unique(dentry, inode);
+	if (res != NULL)
+		dentry = res;
 	nfs_renew_times(dentry);
 	nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
 out_unlock:
 	unlock_kernel();
 out:
-	BUG_ON(error > 0);
-	return ERR_PTR(error);
+	return res;
 }
 
 #ifdef CONFIG_NFS_V4
@@ -798,15 +778,15 @@
 
 static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
 {
+	struct dentry *res = NULL;
 	struct inode *inode = NULL;
-	int error = 0;
 
 	/* Check that we are indeed trying to open this file */
 	if (!is_atomic_open(dir, nd))
 		goto no_open;
 
 	if (dentry->d_name.len > NFS_SERVER(dir)->namelen) {
-		error = -ENAMETOOLONG;
+		res = ERR_PTR(-ENAMETOOLONG);
 		goto out;
 	}
 	dentry->d_op = NFS_PROTO(dir)->dentry_ops;
@@ -828,7 +808,7 @@
 		inode = nfs4_atomic_open(dir, dentry, nd);
 	unlock_kernel();
 	if (IS_ERR(inode)) {
-		error = PTR_ERR(inode);
+		int error = PTR_ERR(inode);
 		switch (error) {
 			/* Make a negative dentry */
 			case -ENOENT:
@@ -841,16 +821,18 @@
 			/* case -EISDIR: */
 			/* case -EINVAL: */
 			default:
+				res = ERR_PTR(error);
 				goto out;
 		}
 	}
 no_entry:
-	d_add(dentry, inode);
+	res = d_add_unique(dentry, inode);
+	if (res != NULL)
+		dentry = res;
 	nfs_renew_times(dentry);
 	nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
 out:
-	BUG_ON(error > 0);
-	return ERR_PTR(error);
+	return res;
 no_open:
 	return nfs_lookup(dir, dentry, nd);
 }
@@ -906,83 +888,51 @@
 }
 #endif /* CONFIG_NFSV4 */
 
-static inline
-int find_dirent_name(nfs_readdir_descriptor_t *desc, struct page *page, struct dentry *dentry)
+static struct dentry *nfs_readdir_lookup(nfs_readdir_descriptor_t *desc)
 {
+	struct dentry *parent = desc->file->f_dentry;
+	struct inode *dir = parent->d_inode;
 	struct nfs_entry *entry = desc->entry;
-	int		 status;
-
-	while((status = dir_decode(desc)) == 0) {
-		if (entry->len != dentry->d_name.len)
-			continue;
-		if (memcmp(entry->name, dentry->d_name.name, entry->len))
-			continue;
-		if (!(entry->fattr->valid & NFS_ATTR_FATTR))
-			continue;
-		break;
-	}
-	return status;
-}
-
-/*
- * Use the cached Readdirplus results in order to avoid a LOOKUP call
- * whenever we believe that the parent directory has not changed.
- *
- * We assume that any file creation/rename changes the directory mtime.
- * As this results in a page cache invalidation whenever it occurs,
- * we don't require any other tests for cache coherency.
- */
-static
-int nfs_cached_lookup(struct inode *dir, struct dentry *dentry,
-			struct nfs_fh *fh, struct nfs_fattr *fattr)
-{
-	nfs_readdir_descriptor_t desc;
-	struct nfs_server *server;
-	struct nfs_entry entry;
-	struct page *page;
-	unsigned long timestamp;
-	int res;
-
-	if (!NFS_USE_READDIRPLUS(dir))
-		return -ENOENT;
-	server = NFS_SERVER(dir);
-	/* Don't use readdirplus unless the cache is stable */
-	if ((server->flags & NFS_MOUNT_NOAC) != 0
-			|| nfs_caches_unstable(dir)
-			|| nfs_attribute_timeout(dir))
-		return -ENOENT;
-	if ((NFS_FLAGS(dir) & (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA)) != 0)
-		return -ENOENT;
-	timestamp = NFS_I(dir)->readdir_timestamp;
-
-	entry.fh = fh;
-	entry.fattr = fattr;
-
-	desc.decode = NFS_PROTO(dir)->decode_dirent;
-	desc.entry = &entry;
-	desc.page_index = 0;
-	desc.plus = 1;
-
-	for(;(page = find_get_page(dir->i_mapping, desc.page_index)); desc.page_index++) {
-
-		res = -EIO;
-		if (PageUptodate(page)) {
-			void * kaddr = kmap_atomic(page, KM_USER0);
-			desc.ptr = kaddr;
-			res = find_dirent_name(&desc, page, dentry);
-			kunmap_atomic(kaddr, KM_USER0);
-		}
-		page_cache_release(page);
+	struct dentry *dentry, *alias;
+	struct qstr name = {
+		.name = entry->name,
+		.len = entry->len,
+	};
+	struct inode *inode;
 
-		if (res == 0)
-			goto out_found;
-		if (res != -EAGAIN)
+	switch (name.len) {
+		case 2:
+			if (name.name[0] == '.' && name.name[1] == '.')
+				return dget_parent(parent);
 			break;
+		case 1:
+			if (name.name[0] == '.')
+				return dget(parent);
+	}
+	name.hash = full_name_hash(name.name, name.len);
+	dentry = d_lookup(parent, &name);
+	if (dentry != NULL)
+		return dentry;
+	if (!desc->plus || !(entry->fattr->valid & NFS_ATTR_FATTR))
+		return NULL;
+	/* Note: caller is already holding the dir->i_sem! */
+	dentry = d_alloc(parent, &name);
+	if (dentry == NULL)
+		return NULL;
+	dentry->d_op = NFS_PROTO(dir)->dentry_ops;
+	inode = nfs_fhget(dentry->d_sb, entry->fh, entry->fattr);
+	if (!inode) {
+		dput(dentry);
+		return NULL;
 	}
-	return -ENOENT;
- out_found:
-	fattr->timestamp = timestamp;
-	return 0;
+	alias = d_add_unique(dentry, inode);
+	if (alias != NULL) {
+		dput(dentry);
+		dentry = alias;
+	}
+	nfs_renew_times(dentry);
+	nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
+	return dentry;
 }
 
 /*
@@ -1045,15 +995,9 @@
 	if (nd && (nd->flags & LOOKUP_CREATE))
 		open_flags = nd->intent.open.flags;
 
-	/*
-	 * The 0 argument passed into the create function should one day
-	 * contain the O_EXCL flag if requested. This allows NFSv3 to
-	 * select the appropriate create strategy. Currently open_namei
-	 * does not pass the create flags.
-	 */
 	lock_kernel();
 	nfs_begin_data_update(dir);
-	inode = NFS_PROTO(dir)->create(dir, &dentry->d_name, &attr, open_flags);
+	inode = NFS_PROTO(dir)->create(dir, dentry, &attr, open_flags);
 	nfs_end_data_update(dir);
 	if (!IS_ERR(inode)) {
 		d_instantiate(dentry, inode);
@@ -1438,7 +1382,7 @@
 		goto go_ahead;
 	if (S_ISDIR(new_inode->i_mode))
 		goto out;
-	else if (atomic_read(&new_dentry->d_count) > 1) {
+	else if (atomic_read(&new_dentry->d_count) > 2) {
 		int err;
 		/* copy the target dentry's name */
 		dentry = d_alloc(new_dentry->d_parent,
@@ -1453,10 +1397,8 @@
 			new_inode = NULL;
 			/* instantiate the replacement target */
 			d_instantiate(new_dentry, NULL);
-		}
-
+		} else if (atomic_read(&new_dentry->d_count) > 1) {
 		/* dentry still busy? */
-		if (atomic_read(&new_dentry->d_count) > 1) {
 #ifdef NFS_PARANOIA
 			printk("nfs_rename: target %s/%s busy, d_count=%d\n",
 			       new_dentry->d_parent->d_name.name,
@@ -1510,7 +1452,7 @@
 
 	if (cache->cred != cred
 			|| time_after(jiffies, cache->jiffies + NFS_ATTRTIMEO(inode))
-			|| (NFS_FLAGS(inode) & NFS_INO_INVALID_ATTR))
+			|| (NFS_FLAGS(inode) & NFS_INO_INVALID_ACCESS))
 		return -ENOENT;
 	memcpy(res, cache, sizeof(*res));
 	return 0;
@@ -1524,6 +1466,7 @@
 		if (cache->cred)
 			put_rpccred(cache->cred);
 		cache->cred = get_rpccred(set->cred);
+		NFS_FLAGS(inode) &= ~NFS_INO_INVALID_ACCESS;
 	}
 	cache->jiffies = set->jiffies;
 	cache->mask = set->mask;
@@ -1555,29 +1498,11 @@
 int nfs_permission(struct inode *inode, int mask, struct nameidata *nd)
 {
 	struct rpc_cred *cred;
-	int mode = inode->i_mode;
 	int res;
 
 	if (mask == 0)
 		return 0;
-	if (mask & MAY_WRITE) {
-		/*
-		 *
-		 * Nobody gets write access to a read-only fs.
-		 *
-		 */
-		if (IS_RDONLY(inode) &&
-		    (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
-			return -EROFS;
 
-		/*
-		 *
-		 * Nobody gets write access to an immutable file.
-		 *
-		 */
-		if (IS_IMMUTABLE(inode))
-			return -EACCES;
-	}
 	/* Are we checking permissions on anything other than lookup/execute? */
 	if ((mask & MAY_EXEC) == 0) {
 		/* We only need to check permissions on file open() and access() */
diff -Nru a/fs/nfs/direct.c b/fs/nfs/direct.c
--- a/fs/nfs/direct.c	2005-03-01 23:39:10 -08:00
+++ b/fs/nfs/direct.c	2005-03-01 23:39:10 -08:00
@@ -33,6 +33,7 @@
  * 08 Jul 2002	Version for 2.4.19, with bug fixes --trondmy
  * 08 Jun 2003	Port to 2.5 APIs  --cel
  * 31 Mar 2004	Handle direct I/O without VFS support  --cel
+ * 15 Sep 2004	Parallel async reads  --cel
  *
  */
 
@@ -43,6 +44,7 @@
 #include <linux/smp_lock.h>
 #include <linux/file.h>
 #include <linux/pagemap.h>
+#include <linux/kref.h>
 
 #include <linux/nfs_fs.h>
 #include <linux/nfs_page.h>
@@ -50,11 +52,27 @@
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
+#include <asm/atomic.h>
 
 #define NFSDBG_FACILITY		NFSDBG_VFS
-#define VERF_SIZE		(2 * sizeof(__u32))
 #define MAX_DIRECTIO_SIZE	(4096UL << PAGE_SHIFT)
 
+static kmem_cache_t *nfs_direct_cachep;
+
+/*
+ * This represents a set of asynchronous requests that we're waiting on
+ */
+struct nfs_direct_req {
+	struct kref		kref;		/* release manager */
+	struct list_head	list;		/* nfs_read_data structs */
+	wait_queue_head_t	wait;		/* wait for i/o completion */
+	struct page **		pages;		/* pages in our buffer */
+	unsigned int		npages;		/* count of pages */
+	atomic_t		complete,	/* i/os we're waiting for */
+				count,		/* bytes actually processed */
+				error;		/* any reported error */
+};
+
 
 /**
  * nfs_get_user_pages - find and set up pages underlying user's buffer
@@ -71,9 +89,12 @@
 	unsigned long page_count;
 	size_t array_size;
 
-	/* set an arbitrary limit to prevent arithmetic overflow */
-	if (size > MAX_DIRECTIO_SIZE)
+	/* set an arbitrary limit to prevent type overflow */
+	/* XXX: this can probably be as large as INT_MAX */
+	if (size > MAX_DIRECTIO_SIZE) {
+		*pages = NULL;
 		return -EFBIG;
+	}
 
 	page_count = (user_addr + size + PAGE_SIZE - 1) >> PAGE_SHIFT;
 	page_count -= user_addr >> PAGE_SHIFT;
@@ -93,6 +114,8 @@
 /**
  * nfs_free_user_pages - tear down page struct array
  * @pages: array of page struct pointers underlying target buffer
+ * @npages: number of pages in the array
+ * @do_dirty: dirty the pages as we release them
  */
 static void
 nfs_free_user_pages(struct page **pages, int npages, int do_dirty)
@@ -107,77 +130,231 @@
 }
 
 /**
- * nfs_direct_read_seg - Read in one iov segment.  Generate separate
- *                        read RPCs for each "rsize" bytes.
+ * nfs_direct_req_release - release  nfs_direct_req structure for direct read
+ * @kref: kref object embedded in an nfs_direct_req structure
+ *
+ */
+static void nfs_direct_req_release(struct kref *kref)
+{
+	struct nfs_direct_req *dreq = container_of(kref, struct nfs_direct_req, kref);
+	kmem_cache_free(nfs_direct_cachep, dreq);
+}
+
+/**
+ * nfs_direct_read_alloc - allocate nfs_read_data structures for direct read
+ * @count: count of bytes for the read request
+ * @rsize: local rsize setting
+ *
+ * Note we also set the number of requests we have in the dreq when we are
+ * done.  This prevents races with I/O completion so we will always wait
+ * until all requests have been dispatched and completed.
+ */
+static struct nfs_direct_req *nfs_direct_read_alloc(size_t nbytes, unsigned int rsize)
+{
+	struct list_head *list;
+	struct nfs_direct_req *dreq;
+	unsigned int reads = 0;
+
+	dreq = kmem_cache_alloc(nfs_direct_cachep, SLAB_KERNEL);
+	if (!dreq)
+		return NULL;
+
+	kref_init(&dreq->kref);
+	init_waitqueue_head(&dreq->wait);
+	INIT_LIST_HEAD(&dreq->list);
+	atomic_set(&dreq->count, 0);
+	atomic_set(&dreq->error, 0);
+
+	list = &dreq->list;
+	for(;;) {
+		struct nfs_read_data *data = nfs_readdata_alloc();
+
+		if (unlikely(!data)) {
+			while (!list_empty(list)) {
+				data = list_entry(list->next,
+						  struct nfs_read_data, pages);
+				list_del(&data->pages);
+				nfs_readdata_free(data);
+			}
+			kref_put(&dreq->kref, nfs_direct_req_release);
+			return NULL;
+		}
+
+		INIT_LIST_HEAD(&data->pages);
+		list_add(&data->pages, list);
+
+		data->req = (struct nfs_page *) dreq;
+		reads++;
+		if (nbytes <= rsize)
+			break;
+		nbytes -= rsize;
+	}
+	kref_get(&dreq->kref);
+	atomic_set(&dreq->complete, reads);
+	return dreq;
+}
+
+/**
+ * nfs_direct_read_result - handle a read reply for a direct read request
+ * @data: address of NFS READ operation control block
+ * @status: status of this NFS READ operation
+ *
+ * We must hold a reference to all the pages in this direct read request
+ * until the RPCs complete.  This could be long *after* we are woken up in
+ * nfs_direct_read_wait (for instance, if someone hits ^C on a slow server).
+ */
+static void nfs_direct_read_result(struct nfs_read_data *data, int status)
+{
+	struct nfs_direct_req *dreq = (struct nfs_direct_req *) data->req;
+
+	if (likely(status >= 0))
+		atomic_add(data->res.count, &dreq->count);
+	else
+		atomic_set(&dreq->error, status);
+
+	if (unlikely(atomic_dec_and_test(&dreq->complete))) {
+		nfs_free_user_pages(dreq->pages, dreq->npages, 1);
+		wake_up(&dreq->wait);
+		kref_put(&dreq->kref, nfs_direct_req_release);
+	}
+}
+
+/**
+ * nfs_direct_read_schedule - dispatch NFS READ operations for a direct read
+ * @dreq: address of nfs_direct_req struct for this request
  * @inode: target inode
  * @ctx: target file open context
- * user_addr: starting address of this segment of user's buffer
- * count: size of this segment
- * file_offset: offset in file to begin the operation
- * @pages: array of addresses of page structs defining user's buffer
- * nr_pages: size of pages array
+ * @user_addr: starting address of this segment of user's buffer
+ * @count: size of this segment
+ * @file_offset: offset in file to begin the operation
+ *
+ * For each nfs_read_data struct that was allocated on the list, dispatch
+ * an NFS READ operation
  */
-static int
-nfs_direct_read_seg(struct inode *inode, struct nfs_open_context *ctx,
-		unsigned long user_addr, size_t count, loff_t file_offset,
-		struct page **pages, int nr_pages)
-{
-	const unsigned int rsize = NFS_SERVER(inode)->rsize;
-	int tot_bytes = 0;
-	int curpage = 0;
-	struct nfs_read_data	rdata = {
-		.inode		= inode,
-		.cred		= ctx->cred,
-		.args		= {
-			.fh		= NFS_FH(inode),
-			.context	= ctx,
-		},
-		.res		= {
-			.fattr		= &rdata.fattr,
-		},
-	};
+static void nfs_direct_read_schedule(struct nfs_direct_req *dreq,
+		struct inode *inode, struct nfs_open_context *ctx,
+		unsigned long user_addr, size_t count, loff_t file_offset)
+{
+	struct list_head *list = &dreq->list;
+	struct page **pages = dreq->pages;
+	unsigned int curpage, pgbase;
+	unsigned int rsize = NFS_SERVER(inode)->rsize;
 
-	rdata.args.pgbase = user_addr & ~PAGE_MASK;
-	rdata.args.offset = file_offset;
-        do {
-		int result;
-
-		rdata.args.count = count;
-                if (rdata.args.count > rsize)
-                        rdata.args.count = rsize;
-		rdata.args.pages = &pages[curpage];
-
-		dprintk("NFS: direct read: c=%u o=%Ld ua=%lu, pb=%u, cp=%u\n",
-			rdata.args.count, (long long) rdata.args.offset,
-			user_addr + tot_bytes, rdata.args.pgbase, curpage);
+	curpage = 0;
+	pgbase = user_addr & ~PAGE_MASK;
+	do {
+		struct nfs_read_data *data;
+		unsigned int bytes;
+
+		bytes = rsize;
+		if (count < rsize)
+			bytes = count;
+
+		data = list_entry(list->next, struct nfs_read_data, pages);
+		list_del_init(&data->pages);
+
+		data->inode = inode;
+		data->cred = ctx->cred;
+		data->args.fh = NFS_FH(inode);
+		data->args.context = ctx;
+		data->args.offset = file_offset;
+		data->args.pgbase = pgbase;
+		data->args.pages = &pages[curpage];
+		data->args.count = bytes;
+		data->res.fattr = &data->fattr;
+		data->res.eof = 0;
+		data->res.count = bytes;
+
+		NFS_PROTO(inode)->read_setup(data);
+
+		data->task.tk_cookie = (unsigned long) inode;
+		data->task.tk_calldata = data;
+		data->task.tk_release = nfs_readdata_release;
+		data->complete = nfs_direct_read_result;
 
 		lock_kernel();
-		result = NFS_PROTO(inode)->read(&rdata);
+		rpc_execute(&data->task);
 		unlock_kernel();
 
-		if (result <= 0) {
-			if (tot_bytes > 0)
-				break;
-			if (result == -EISDIR)
-				result = -EINVAL;
-			return result;
-		}
-
-                tot_bytes += result;
-		if (rdata.res.eof)
-			break;
+		dfprintk(VFS, "NFS: %4d initiated direct read call (req %s/%Ld, %u bytes @ offset %Lu)\n",
+				data->task.tk_pid,
+				inode->i_sb->s_id,
+				(long long)NFS_FILEID(inode),
+				bytes,
+				(unsigned long long)data->args.offset);
+
+		file_offset += bytes;
+		pgbase += bytes;
+		curpage += pgbase >> PAGE_SHIFT;
+		pgbase &= ~PAGE_MASK;
 
-                rdata.args.offset += result;
-		rdata.args.pgbase += result;
-		curpage += rdata.args.pgbase >> PAGE_SHIFT;
-		rdata.args.pgbase &= ~PAGE_MASK;
-		count -= result;
+		count -= bytes;
 	} while (count != 0);
+}
 
-	/* XXX: should we zero the rest of the user's buffer if we
-	 *      hit eof? */
+/**
+ * nfs_direct_read_wait - wait for I/O completion for direct reads
+ * @dreq: request on which we are to wait
+ * @intr: whether or not this wait can be interrupted
+ *
+ * Collects and returns the final error value/byte-count.
+ */
+static ssize_t nfs_direct_read_wait(struct nfs_direct_req *dreq, int intr)
+{
+	int result = 0;
 
-	return tot_bytes;
+	if (intr) {
+		result = wait_event_interruptible(dreq->wait,
+					(atomic_read(&dreq->complete) == 0));
+	} else {
+		wait_event(dreq->wait, (atomic_read(&dreq->complete) == 0));
+	}
+
+	if (!result)
+		result = atomic_read(&dreq->error);
+	if (!result)
+		result = atomic_read(&dreq->count);
+
+	kref_put(&dreq->kref, nfs_direct_req_release);
+	return (ssize_t) result;
+}
+
+/**
+ * nfs_direct_read_seg - Read in one iov segment.  Generate separate
+ *                        read RPCs for each "rsize" bytes.
+ * @inode: target inode
+ * @ctx: target file open context
+ * @user_addr: starting address of this segment of user's buffer
+ * @count: size of this segment
+ * @file_offset: offset in file to begin the operation
+ * @pages: array of addresses of page structs defining user's buffer
+ * @nr_pages: number of pages in the array
+ *
+ */
+static ssize_t nfs_direct_read_seg(struct inode *inode,
+		struct nfs_open_context *ctx, unsigned long user_addr,
+		size_t count, loff_t file_offset, struct page **pages,
+		unsigned int nr_pages)
+{
+	ssize_t result;
+	sigset_t oldset;
+	struct rpc_clnt *clnt = NFS_CLIENT(inode);
+	struct nfs_direct_req *dreq;
+
+	dreq = nfs_direct_read_alloc(count, NFS_SERVER(inode)->rsize);
+	if (!dreq)
+		return -ENOMEM;
+
+	dreq->pages = pages;
+	dreq->npages = nr_pages;
+
+	rpc_clnt_sigmask(clnt, &oldset);
+	nfs_direct_read_schedule(dreq, inode, ctx, user_addr, count,
+				 file_offset);
+	result = nfs_direct_read_wait(dreq, clnt->cl_intr);
+	rpc_clnt_sigunmask(clnt, &oldset);
+
+	return result;
 }
 
 /**
@@ -189,9 +366,8 @@
  * file_offset: offset in file to begin the operation
  * nr_segs: size of iovec array
  *
- * generic_file_direct_IO has already pushed out any non-direct
- * writes so that this read will see them when we read from the
- * server.
+ * We've already pushed out any non-direct writes so that this read
+ * will see them when we read from the server.
  */
 static ssize_t
 nfs_direct_read(struct inode *inode, struct nfs_open_context *ctx,
@@ -220,8 +396,6 @@
 		result = nfs_direct_read_seg(inode, ctx, user_addr, size,
 				file_offset, pages, page_count);
 
-		nfs_free_user_pages(pages, page_count, 1);
-
 		if (result <= 0) {
 			if (tot_bytes > 0)
 				break;
@@ -247,31 +421,31 @@
  * @pages: array of addresses of page structs defining user's buffer
  * nr_pages: size of pages array
  */
-static int
-nfs_direct_write_seg(struct inode *inode, struct nfs_open_context *ctx,
-		unsigned long user_addr, size_t count, loff_t file_offset,
-		struct page **pages, int nr_pages)
+static ssize_t nfs_direct_write_seg(struct inode *inode,
+		struct nfs_open_context *ctx, unsigned long user_addr,
+		size_t count, loff_t file_offset, struct page **pages,
+		int nr_pages)
 {
 	const unsigned int wsize = NFS_SERVER(inode)->wsize;
 	size_t request;
-	int curpage, need_commit, result, tot_bytes;
+	int curpage, need_commit;
+	ssize_t result, tot_bytes;
 	struct nfs_writeverf first_verf;
-	struct nfs_write_data	wdata = {
-		.inode		= inode,
-		.cred		= ctx->cred,
-		.args		= {
-			.fh		= NFS_FH(inode),
-			.context	= ctx,
-		},
-		.res		= {
-			.fattr		= &wdata.fattr,
-			.verf		= &wdata.verf,
-		},
-	};
+	struct nfs_write_data *wdata;
 
-	wdata.args.stable = NFS_UNSTABLE;
+	wdata = nfs_writedata_alloc();
+	if (!wdata)
+		return -ENOMEM;
+
+	wdata->inode = inode;
+	wdata->cred = ctx->cred;
+	wdata->args.fh = NFS_FH(inode);
+	wdata->args.context = ctx;
+	wdata->args.stable = NFS_UNSTABLE;
 	if (IS_SYNC(inode) || NFS_PROTO(inode)->version == 2 || count <= wsize)
-		wdata.args.stable = NFS_FILE_SYNC;
+		wdata->args.stable = NFS_FILE_SYNC;
+	wdata->res.fattr = &wdata->fattr;
+	wdata->res.verf = &wdata->verf;
 
 	nfs_begin_data_update(inode);
 retry:
@@ -279,20 +453,20 @@
 	tot_bytes = 0;
 	curpage = 0;
 	request = count;
-	wdata.args.pgbase = user_addr & ~PAGE_MASK;
-	wdata.args.offset = file_offset;
-        do {
-		wdata.args.count = request;
-                if (wdata.args.count > wsize)
-                        wdata.args.count = wsize;
-		wdata.args.pages = &pages[curpage];
+	wdata->args.pgbase = user_addr & ~PAGE_MASK;
+	wdata->args.offset = file_offset;
+	do {
+		wdata->args.count = request;
+		if (wdata->args.count > wsize)
+			wdata->args.count = wsize;
+		wdata->args.pages = &pages[curpage];
 
 		dprintk("NFS: direct write: c=%u o=%Ld ua=%lu, pb=%u, cp=%u\n",
-			wdata.args.count, (long long) wdata.args.offset,
-			user_addr + tot_bytes, wdata.args.pgbase, curpage);
+			wdata->args.count, (long long) wdata->args.offset,
+			user_addr + tot_bytes, wdata->args.pgbase, curpage);
 
 		lock_kernel();
-		result = NFS_PROTO(inode)->write(&wdata);
+		result = NFS_PROTO(inode)->write(wdata);
 		unlock_kernel();
 
 		if (result <= 0) {
@@ -302,20 +476,25 @@
 		}
 
 		if (tot_bytes == 0)
-			memcpy(&first_verf.verifier, &wdata.verf.verifier,
-								VERF_SIZE);
-		if (wdata.verf.committed != NFS_FILE_SYNC) {
+			memcpy(&first_verf.verifier, &wdata->verf.verifier,
+						sizeof(first_verf.verifier));
+		if (wdata->verf.committed != NFS_FILE_SYNC) {
 			need_commit = 1;
-			if (memcmp(&first_verf.verifier,
-					&wdata.verf.verifier, VERF_SIZE))
+			if (memcmp(&first_verf.verifier, &wdata->verf.verifier,
+					sizeof(first_verf.verifier)));
 				goto sync_retry;
 		}
 
-                tot_bytes += result;
-                wdata.args.offset += result;
-		wdata.args.pgbase += result;
-		curpage += wdata.args.pgbase >> PAGE_SHIFT;
-		wdata.args.pgbase &= ~PAGE_MASK;
+		tot_bytes += result;
+
+		/* in case of a short write: stop now, let the app recover */
+		if (result < wdata->args.count)
+			break;
+
+		wdata->args.offset += result;
+		wdata->args.pgbase += result;
+		curpage += wdata->args.pgbase >> PAGE_SHIFT;
+		wdata->args.pgbase &= ~PAGE_MASK;
 		request -= result;
 	} while (request != 0);
 
@@ -323,27 +502,27 @@
 	 * Commit data written so far, even in the event of an error
 	 */
 	if (need_commit) {
-		wdata.args.count = tot_bytes;
-		wdata.args.offset = file_offset;
+		wdata->args.count = tot_bytes;
+		wdata->args.offset = file_offset;
 
 		lock_kernel();
-		result = NFS_PROTO(inode)->commit(&wdata);
+		result = NFS_PROTO(inode)->commit(wdata);
 		unlock_kernel();
 
 		if (result < 0 || memcmp(&first_verf.verifier,
-						&wdata.verf.verifier,
-						VERF_SIZE) != 0)
+					 &wdata->verf.verifier,
+					 sizeof(first_verf.verifier)) != 0)
 			goto sync_retry;
 	}
 	result = tot_bytes;
 
 out:
 	nfs_end_data_update_defer(inode);
-
+	nfs_writedata_free(wdata);
 	return result;
 
 sync_retry:
-	wdata.args.stable = NFS_FILE_SYNC;
+	wdata->args.stable = NFS_FILE_SYNC;
 	goto retry;
 }
 
@@ -360,9 +539,9 @@
  * that non-direct readers might access, so they will pick up these
  * writes immediately.
  */
-static int nfs_direct_write(struct inode *inode, struct nfs_open_context *ctx,
-		const struct iovec *iov, loff_t file_offset,
-		unsigned long nr_segs)
+static ssize_t nfs_direct_write(struct inode *inode,
+		struct nfs_open_context *ctx, const struct iovec *iov,
+		loff_t file_offset, unsigned long nr_segs)
 {
 	ssize_t tot_bytes = 0;
 	unsigned long seg = 0;
@@ -502,6 +681,8 @@
 	if (mapping->nrpages) {
 		retval = filemap_fdatawrite(mapping);
 		if (retval == 0)
+			retval = nfs_wb_all(inode);
+		if (retval == 0)
 			retval = filemap_fdatawait(mapping);
 		if (retval)
 			goto out;
@@ -591,6 +772,8 @@
 	if (mapping->nrpages) {
 		retval = filemap_fdatawrite(mapping);
 		if (retval == 0)
+			retval = nfs_wb_all(inode);
+		if (retval == 0)
 			retval = filemap_fdatawait(mapping);
 		if (retval)
 			goto out;
@@ -604,4 +787,22 @@
 
 out:
 	return retval;
+}
+
+int nfs_init_directcache(void)
+{
+	nfs_direct_cachep = kmem_cache_create("nfs_direct_cache",
+						sizeof(struct nfs_direct_req),
+						0, SLAB_RECLAIM_ACCOUNT,
+						NULL, NULL);
+	if (nfs_direct_cachep == NULL)
+		return -ENOMEM;
+
+	return 0;
+}
+
+void nfs_destroy_directcache(void)
+{
+	if (kmem_cache_destroy(nfs_direct_cachep))
+		printk(KERN_INFO "nfs_direct_cache: not all structures were freed\n");
 }
diff -Nru a/fs/nfs/file.c b/fs/nfs/file.c
--- a/fs/nfs/file.c	2005-03-01 23:39:07 -08:00
+++ b/fs/nfs/file.c	2005-03-01 23:39:07 -08:00
@@ -295,10 +295,19 @@
 static int do_getlk(struct file *filp, int cmd, struct file_lock *fl)
 {
 	struct inode *inode = filp->f_mapping->host;
-	int status;
+	int status = 0;
 
 	lock_kernel();
-	status = NFS_PROTO(inode)->lock(filp, cmd, fl);
+	/* Use local locking if mounted with "-onolock" */
+	if (!(NFS_SERVER(inode)->flags & NFS_MOUNT_NONLM))
+		status = NFS_PROTO(inode)->lock(filp, cmd, fl);
+	else {
+		struct file_lock *cfl = posix_test_lock(filp, fl);
+
+		fl->fl_type = F_UNLCK;
+		if (cfl != NULL)
+			memcpy(fl, cfl, sizeof(*fl));
+	}
 	unlock_kernel();
 	return status;
 }
@@ -325,7 +334,12 @@
 	 * 	still need to complete the unlock.
 	 */
 	lock_kernel();
-	status = NFS_PROTO(inode)->lock(filp, cmd, fl);
+	/* Use local locking if mounted with "-onolock" */
+	if (!(NFS_SERVER(inode)->flags & NFS_MOUNT_NONLM))
+		status = NFS_PROTO(inode)->lock(filp, cmd, fl);
+	else
+		status = posix_lock_file_wait(filp, fl);
+	unlock_kernel();
 	rpc_clnt_sigunmask(NFS_CLIENT(inode), &oldset);
 	return status;
 }
@@ -333,8 +347,10 @@
 static int do_setlk(struct file *filp, int cmd, struct file_lock *fl)
 {
 	struct inode *inode = filp->f_mapping->host;
+	sigset_t oldset;
 	int status;
 
+	rpc_clnt_sigmask(NFS_CLIENT(inode), &oldset);
 	/*
 	 * Flush all pending writes before doing anything
 	 * with locks..
@@ -348,21 +364,25 @@
 			status = filemap_fdatawait(filp->f_mapping);
 	}
 	if (status < 0)
-		return status;
+		goto out;
 
 	lock_kernel();
-	status = NFS_PROTO(inode)->lock(filp, cmd, fl);
-	/* If we were signalled we still need to ensure that
-	 * we clean up any state on the server. We therefore
-	 * record the lock call as having succeeded in order to
-	 * ensure that locks_remove_posix() cleans it out when
-	 * the process exits.
-	 */
-	if (status == -EINTR || status == -ERESTARTSYS)
-		posix_lock_file(filp, fl);
+	/* Use local locking if mounted with "-onolock" */
+	if (!(NFS_SERVER(inode)->flags & NFS_MOUNT_NONLM)) {
+		status = NFS_PROTO(inode)->lock(filp, cmd, fl);
+		/* If we were signalled we still need to ensure that
+		 * we clean up any state on the server. We therefore
+		 * record the lock call as having succeeded in order to
+		 * ensure that locks_remove_posix() cleans it out when
+		 * the process exits.
+		 */
+		if (status == -EINTR || status == -ERESTARTSYS)
+			posix_lock_file_wait(filp, fl);
+	} else
+		status = posix_lock_file_wait(filp, fl);
 	unlock_kernel();
 	if (status < 0)
-		return status;
+		goto out;
 	/*
 	 * Make sure we clear the cache whenever we try to get the lock.
 	 * This makes locking act as a cache coherency point.
@@ -373,7 +393,9 @@
 	up(&inode->i_sem);
 	filemap_fdatawait(filp->f_mapping);
 	nfs_zap_caches(inode);
-	return 0;
+out:
+	rpc_clnt_sigunmask(NFS_CLIENT(inode), &oldset);
+	return status;
 }
 
 /*
@@ -395,15 +417,6 @@
 	/* No mandatory locks over NFS */
 	if ((inode->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID)
 		return -ENOLCK;
-
-	if (NFS_PROTO(inode)->version != 4) {
-		/* Fake OK code if mounted without NLM support */
-		if (NFS_SERVER(inode)->flags & NFS_MOUNT_NONLM) {
-			if (IS_GETLK(cmd))
-				return LOCK_USE_CLNT;
-			return 0;
-		}
-	}
 
 	/*
 	 * No BSD flocks over NFS allowed.
diff -Nru a/fs/nfs/inode.c b/fs/nfs/inode.c
--- a/fs/nfs/inode.c	2005-03-01 23:39:09 -08:00
+++ b/fs/nfs/inode.c	2005-03-01 23:39:09 -08:00
@@ -457,6 +457,7 @@
 	if (server->flags & NFS_MOUNT_VER3) {
 		if (server->namelen == 0 || server->namelen > NFS3_MAXNAMLEN)
 			server->namelen = NFS3_MAXNAMLEN;
+		sb->s_time_gran = 1;
 	} else {
 		if (server->namelen == 0 || server->namelen > NFS2_MAXNAMLEN)
 			server->namelen = NFS2_MAXNAMLEN;
@@ -486,13 +487,27 @@
 	if (error < 0)
 		goto out_err;
 
-	buf->f_frsize = server->wtmult;
+	/*
+	 * Current versions of glibc do not correctly handle the
+	 * case where f_frsize != f_bsize.  Eventually we want to
+	 * report the value of wtmult in this field.
+	 */
+	buf->f_frsize = sb->s_blocksize;
+
+	/*
+	 * On most *nix systems, f_blocks, f_bfree, and f_bavail
+	 * are reported in units of f_frsize.  Linux hasn't had
+	 * an f_frsize field in its statfs struct until recently,
+	 * thus historically Linux's sys_statfs reports these
+	 * fields in units of f_bsize.
+	 */
 	buf->f_bsize = sb->s_blocksize;
 	blockbits = sb->s_blocksize_bits;
 	blockres = (1 << blockbits) - 1;
 	buf->f_blocks = (res.tbytes + blockres) >> blockbits;
 	buf->f_bfree = (res.fbytes + blockres) >> blockbits;
 	buf->f_bavail = (res.abytes + blockres) >> blockbits;
+
 	buf->f_files = res.tfiles;
 	buf->f_ffree = res.afiles;
 
@@ -565,9 +580,9 @@
 
 	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;
+		nfsi->flags |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS;
 	else
-		nfsi->flags |= NFS_INO_INVALID_ATTR;
+		nfsi->flags |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS;
 }
 
 /*
@@ -605,7 +620,7 @@
 		return 0;
 	if (nfs_compare_fh(NFS_FH(inode), fh))
 		return 0;
-	if (is_bad_inode(inode))
+	if (is_bad_inode(inode) || NFS_STALE(inode))
 		return 0;
 	return 1;
 }
@@ -766,13 +781,8 @@
 			vmtruncate(inode, attr->ia_size);
 		}
 	}
-	if ((attr->ia_valid & (ATTR_MODE|ATTR_UID|ATTR_GID)) != 0) {
-		struct rpc_cred **cred = &NFS_I(inode)->cache_access.cred;
-		if (*cred) {
-			put_rpccred(*cred);
-			*cred = NULL;
-		}
-	}
+	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;
@@ -949,14 +959,14 @@
 	lock_kernel();
 	if (!inode || is_bad_inode(inode))
  		goto out_nowait;
-	if (NFS_STALE(inode) && inode != inode->i_sb->s_root->d_inode)
+	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_SERVER(inode)->flags & NFS_MOUNT_NOAC)
+		if (NFS_ATTRTIMEO(inode) == 0)
 			continue;
 		if (NFS_FLAGS(inode) & (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ATIME))
 			continue;
@@ -968,14 +978,14 @@
 	/* Protect against RPC races by saving the change attribute */
 	verifier = nfs_save_change_attribute(inode);
 	status = NFS_PROTO(inode)->getattr(server, NFS_FH(inode), &fattr);
-	if (status) {
+	if (status != 0) {
 		dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Ld) getattr failed, error=%d\n",
 			 inode->i_sb->s_id,
 			 (long long)NFS_FILEID(inode), status);
 		if (status == -ESTALE) {
-			NFS_FLAGS(inode) |= NFS_INO_STALE;
-			if (inode != inode->i_sb->s_root->d_inode)
-				remove_inode_hash(inode);
+			nfs_zap_caches(inode);
+			if (!S_ISDIR(inode->i_mode))
+				NFS_FLAGS(inode) |= NFS_INO_STALE;
 		}
 		goto out;
 	}
@@ -1014,7 +1024,6 @@
 		inode->i_sb->s_id,
 		(long long)NFS_FILEID(inode));
 
-	NFS_FLAGS(inode) &= ~NFS_INO_STALE;
 out:
 	NFS_FLAGS(inode) &= ~NFS_INO_REVALIDATING;
 	wake_up(&nfsi->nfs_i_wait);
@@ -1161,7 +1170,7 @@
 	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;
+		nfsi->flags |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS;
 
 	/* Has the link count changed? */
 	if (inode->i_nlink != fattr->nlink)
@@ -1270,7 +1279,7 @@
 #endif
 		nfsi->change_attr = fattr->change_attr;
 		if (!data_unstable)
-			invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA;
+			invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS;
 	}
 
 	memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime));
@@ -1278,14 +1287,8 @@
 
 	if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO) ||
 	    inode->i_uid != fattr->uid ||
-	    inode->i_gid != fattr->gid) {
-		struct rpc_cred **cred = &NFS_I(inode)->cache_access.cred;
-		if (*cred) {
-			put_rpccred(*cred);
-			*cred = NULL;
-		}
-		invalid |= NFS_INO_INVALID_ATTR;
-	}
+	    inode->i_gid != fattr->gid)
+		invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS;
 
 	inode->i_mode = fattr->mode;
 	inode->i_nlink = fattr->nlink;
@@ -1335,7 +1338,8 @@
 	 */
 	nfs_invalidate_inode(inode);
  out_err:
-	return -EIO;
+	NFS_FLAGS(inode) |= NFS_INO_STALE;
+	return -ESTALE;
 }
 
 /*
@@ -1449,8 +1453,6 @@
 
 	kill_anon_super(s);
 
-	nfs4_renewd_prepare_shutdown(server);
-
 	if (server->client != NULL && !IS_ERR(server->client))
 		rpc_shutdown_client(server->client);
 	if (server->client_sys != NULL && !IS_ERR(server->client_sys))
@@ -1461,8 +1463,6 @@
 
 	rpciod_down();		/* release rpciod */
 
-	destroy_nfsv4_state(server);
-
 	if (server->hostname != NULL)
 		kfree(server->hostname);
 	kfree(server);
@@ -1543,9 +1543,6 @@
 		server->wsize = nfs_block_size(data->wsize, NULL);
 	server->flags = data->flags & NFS_MOUNT_FLAGMASK;
 
-	/* NFSv4 doesn't use NLM locking */
-	server->flags |= NFS_MOUNT_NONLM;
-
 	server->acregmin = data->acregmin*HZ;
 	server->acregmax = data->acregmax*HZ;
 	server->acdirmin = data->acdirmin*HZ;
@@ -1653,6 +1650,8 @@
 		}
 	}
 
+	sb->s_time_gran = 1;
+
 	sb->s_op = &nfs4_sops;
 	err = nfs_sb_init(sb, authflavour);
 	if (err == 0)
@@ -1790,8 +1789,22 @@
 
 static void nfs4_kill_super(struct super_block *sb)
 {
+	struct nfs_server *server = NFS_SB(sb);
+
 	nfs_return_all_delegations(sb);
-	nfs_kill_super(sb);
+	kill_anon_super(sb);
+
+	nfs4_renewd_prepare_shutdown(server);
+
+	if (server->client != NULL && !IS_ERR(server->client))
+		rpc_shutdown_client(server->client);
+	rpciod_down();		/* release rpciod */
+
+	destroy_nfsv4_state(server);
+
+	if (server->hostname != NULL)
+		kfree(server->hostname);
+	kfree(server);
 }
 
 static struct file_system_type nfs4_fs_type = {
@@ -1821,9 +1834,13 @@
 extern int nfs_init_nfspagecache(void);
 extern void nfs_destroy_nfspagecache(void);
 extern int nfs_init_readpagecache(void);
-extern int nfs_destroy_readpagecache(void);
+extern void nfs_destroy_readpagecache(void);
 extern int nfs_init_writepagecache(void);
-extern int nfs_destroy_writepagecache(void);
+extern void nfs_destroy_writepagecache(void);
+#ifdef CONFIG_NFS_DIRECTIO
+extern int nfs_init_directcache(void);
+extern void nfs_destroy_directcache(void);
+#endif
 
 static kmem_cache_t * nfs_inode_cachep;
 
@@ -1904,6 +1921,12 @@
 	if (err)
 		goto out1;
 
+#ifdef CONFIG_NFS_DIRECTIO
+	err = nfs_init_directcache();
+	if (err)
+		goto out0;
+#endif
+
 #ifdef CONFIG_PROC_FS
 	rpc_proc_register(&nfs_rpcstat);
 #endif
@@ -1914,8 +1937,14 @@
 		goto out;
 	return 0;
 out:
+#ifdef CONFIG_PROC_FS
 	rpc_proc_unregister("nfs");
+#endif
 	nfs_destroy_writepagecache();
+#ifdef CONFIG_NFS_DIRECTIO
+out0:
+	nfs_destroy_directcache();
+#endif
 out1:
 	nfs_destroy_readpagecache();
 out2:
@@ -1928,6 +1957,9 @@
 
 static void __exit exit_nfs_fs(void)
 {
+#ifdef CONFIG_NFS_DIRECTIO
+	nfs_destroy_directcache();
+#endif
 	nfs_destroy_writepagecache();
 	nfs_destroy_readpagecache();
 	nfs_destroy_inodecache();
diff -Nru a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c
--- a/fs/nfs/nfs3proc.c	2005-03-01 23:38:57 -08:00
+++ b/fs/nfs/nfs3proc.c	2005-03-01 23:38:57 -08:00
@@ -80,10 +80,10 @@
 	dprintk("%s: call  fsinfo\n", __FUNCTION__);
 	info->fattr->valid = 0;
 	status = rpc_call(server->client_sys, NFS3PROC_FSINFO, fhandle, info, 0);
-	dprintk("%s: reply fsinfo %d\n", __FUNCTION__, status);
+	dprintk("%s: reply fsinfo: %d\n", __FUNCTION__, status);
 	if (!(info->fattr->valid & NFS_ATTR_FATTR)) {
 		status = rpc_call(server->client_sys, NFS3PROC_GETATTR, fhandle, info->fattr, 0);
-		dprintk("%s: reply getattr %d\n", __FUNCTION__, status);
+		dprintk("%s: reply getattr: %d\n", __FUNCTION__, status);
 	}
 	return status;
 }
@@ -101,7 +101,7 @@
 	fattr->valid = 0;
 	status = rpc_call(server->client, NFS3PROC_GETATTR,
 			  fhandle, fattr, 0);
-	dprintk("NFS reply getattr\n");
+	dprintk("NFS reply getattr: %d\n", status);
 	return status;
 }
 
@@ -119,7 +119,7 @@
 	dprintk("NFS call  setattr\n");
 	fattr->valid = 0;
 	status = rpc_call(NFS_CLIENT(inode), NFS3PROC_SETATTR, &arg, fattr, 0);
-	dprintk("NFS reply setattr\n");
+	dprintk("NFS reply setattr: %d\n", status);
 	return status;
 }
 
@@ -198,7 +198,7 @@
 		if (res.access & (NFS3_ACCESS_LOOKUP|NFS3_ACCESS_EXECUTE))
 			entry->mask |= MAY_EXEC;
 	}
-	dprintk("NFS reply access, status = %d\n", status);
+	dprintk("NFS reply access: %d\n", status);
 	return status;
 }
 
@@ -296,7 +296,7 @@
  * For now, we don't implement O_EXCL.
  */
 static struct inode *
-nfs3_proc_create(struct inode *dir, struct qstr *name, struct iattr *sattr,
+nfs3_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
 		 int flags)
 {
 	struct nfs_fh		fhandle;
@@ -304,8 +304,8 @@
 	struct nfs_fattr	dir_attr;
 	struct nfs3_createargs	arg = {
 		.fh		= NFS_FH(dir),
-		.name		= name->name,
-		.len		= name->len,
+		.name		= dentry->d_name.name,
+		.len		= dentry->d_name.len,
 		.sattr		= sattr,
 	};
 	struct nfs3_diropres	res = {
@@ -315,7 +315,7 @@
 	};
 	int			status;
 
-	dprintk("NFS call  create %s\n", name->name);
+	dprintk("NFS call  create %s\n", dentry->d_name.name);
 	arg.createmode = NFS3_CREATE_UNCHECKED;
 	if (flags & O_EXCL) {
 		arg.createmode  = NFS3_CREATE_EXCLUSIVE;
@@ -353,7 +353,7 @@
 	if (status != 0)
 		goto out;
 	if (fhandle.size == 0 || !(fattr.valid & NFS_ATTR_FATTR)) {
-		status = nfs3_proc_lookup(dir, name, &fhandle, &fattr);
+		status = nfs3_proc_lookup(dir, &dentry->d_name, &fhandle, &fattr);
 		if (status != 0)
 			goto out;
 	}
diff -Nru a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
--- a/fs/nfs/nfs4proc.c	2005-03-01 23:39:08 -08:00
+++ b/fs/nfs/nfs4proc.c	2005-03-01 23:39:08 -08:00
@@ -477,7 +477,7 @@
 /*
  * Returns an nfs4_state + an referenced inode
  */
-static int _nfs4_do_open(struct inode *dir, struct qstr *name, int flags, struct iattr *sattr, struct rpc_cred *cred, struct nfs4_state **res)
+static int _nfs4_do_open(struct inode *dir, struct dentry *dentry, int flags, struct iattr *sattr, struct rpc_cred *cred, struct nfs4_state **res)
 {
 	struct nfs4_state_owner  *sp;
 	struct nfs4_state     *state = NULL;
@@ -491,7 +491,7 @@
 	struct nfs_openargs o_arg = {
 		.fh             = NFS_FH(dir),
 		.open_flags	= flags,
-		.name           = name,
+		.name           = &dentry->d_name,
 		.server         = server,
 		.bitmask = server->attr_bitmask,
 		.claim = NFS4_OPEN_CLAIM_NULL,
@@ -581,14 +581,14 @@
 }
 
 
-struct nfs4_state *nfs4_do_open(struct inode *dir, struct qstr *name, int flags, struct iattr *sattr, struct rpc_cred *cred)
+struct nfs4_state *nfs4_do_open(struct inode *dir, struct dentry *dentry, int flags, struct iattr *sattr, struct rpc_cred *cred)
 {
 	struct nfs4_exception exception = { };
 	struct nfs4_state *res;
 	int status;
 
 	do {
-		status = _nfs4_do_open(dir, name, flags, sattr, cred, &res);
+		status = _nfs4_do_open(dir, dentry, flags, sattr, cred, &res);
 		if (status == 0)
 			break;
 		/* NOTE: BAD_SEQID means the server and client disagree about the
@@ -635,6 +635,8 @@
 
         fattr->valid = 0;
 
+	if (state != NULL)
+		msg.rpc_cred = state->owner->so_cred;
 	if (sattr->ia_valid & ATTR_SIZE)
 		nfs4_copy_stateid(&arg.stateid, state, NULL);
 	else
@@ -658,6 +660,61 @@
 	return err;
 }
 
+struct nfs4_closedata {
+	struct inode *inode;
+	struct nfs4_state *state;
+	struct nfs_closeargs arg;
+	struct nfs_closeres res;
+};
+
+static void nfs4_close_done(struct rpc_task *task)
+{
+	struct nfs4_closedata *calldata = (struct nfs4_closedata *)task->tk_calldata;
+	struct nfs4_state *state = calldata->state;
+	struct nfs4_state_owner *sp = state->owner;
+	struct nfs_server *server = NFS_SERVER(calldata->inode);
+
+        /* hmm. we are done with the inode, and in the process of freeing
+	 * the state_owner. we keep this around to process errors
+	 */
+	nfs4_increment_seqid(task->tk_status, sp);
+	switch (task->tk_status) {
+		case 0:
+			state->state = calldata->arg.open_flags;
+			memcpy(&state->stateid, &calldata->res.stateid,
+					sizeof(state->stateid));
+			break;
+		case -NFS4ERR_STALE_STATEID:
+		case -NFS4ERR_EXPIRED:
+			state->state = calldata->arg.open_flags;
+			nfs4_schedule_state_recovery(server->nfs4_state);
+			break;
+		default:
+			if (nfs4_async_handle_error(task, server) == -EAGAIN) {
+				rpc_restart_call(task);
+				return;
+			}
+	}
+	nfs4_put_open_state(state);
+	up(&sp->so_sema);
+	nfs4_put_state_owner(sp);
+	up_read(&server->nfs4_state->cl_sem);
+	kfree(calldata);
+}
+
+static inline int nfs4_close_call(struct rpc_clnt *clnt, struct nfs4_closedata *calldata)
+{
+	struct rpc_message msg = {
+		.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CLOSE],
+		.rpc_argp = &calldata->arg,
+		.rpc_resp = &calldata->res,
+		.rpc_cred = calldata->state->owner->so_cred,
+	};
+	if (calldata->arg.open_flags != 0)
+		msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_DOWNGRADE];
+	return rpc_call_async(clnt, &msg, 0, nfs4_close_done, calldata);
+}
+
 /* 
  * It is possible for data to be read/written from a mem-mapped file 
  * after the sys_close call (which hits the vfs layer as a flush).
@@ -669,102 +726,34 @@
  *
  * NOTE: Caller must be holding the sp->so_owner semaphore!
  */
-static int _nfs4_do_close(struct inode *inode, struct nfs4_state *state) 
+int nfs4_do_close(struct inode *inode, struct nfs4_state *state, mode_t mode) 
 {
-	struct nfs4_state_owner *sp = state->owner;
-	int status = 0;
-	struct nfs_closeargs arg = {
-		.fh		= NFS_FH(inode),
-	};
-	struct nfs_closeres res;
-	struct rpc_message msg = {
-		.rpc_proc	= &nfs4_procedures[NFSPROC4_CLNT_CLOSE],
-		.rpc_argp	= &arg,
-		.rpc_resp	= &res,
-	};
+	struct nfs4_closedata *calldata;
+	int status;
 
-	if (test_bit(NFS_DELEGATED_STATE, &state->flags))
+	/* Tell caller we're done */
+	if (test_bit(NFS_DELEGATED_STATE, &state->flags)) {
+		state->state = mode;
 		return 0;
-	memcpy(&arg.stateid, &state->stateid, sizeof(arg.stateid));
+	}
+	calldata = (struct nfs4_closedata *)kmalloc(sizeof(*calldata), GFP_KERNEL);
+	if (calldata == NULL)
+		return -ENOMEM;
+	calldata->inode = inode;
+	calldata->state = state;
+	calldata->arg.fh = NFS_FH(inode);
 	/* Serialization for the sequence id */
-	arg.seqid = sp->so_seqid,
-	status = rpc_call_sync(NFS_SERVER(inode)->client, &msg, RPC_TASK_NOINTR);
-
-        /* hmm. we are done with the inode, and in the process of freeing
-	 * the state_owner. we keep this around to process errors
+	calldata->arg.seqid = state->owner->so_seqid;
+	calldata->arg.open_flags = mode;
+	memcpy(&calldata->arg.stateid, &state->stateid,
+			sizeof(calldata->arg.stateid));
+	status = nfs4_close_call(NFS_SERVER(inode)->client, calldata);
+	/*
+	 * Return -EINPROGRESS on success in order to indicate to the
+	 * caller that an asynchronous RPC call has been launched, and
+	 * that it will release the semaphores on completion.
 	 */
-	nfs4_increment_seqid(status, sp);
-	if (!status)
-		memcpy(&state->stateid, &res.stateid, sizeof(state->stateid));
-
-	return status;
-}
-
-int nfs4_do_close(struct inode *inode, struct nfs4_state *state) 
-{
-	struct nfs_server *server = NFS_SERVER(state->inode);
-	struct nfs4_exception exception = { };
-	int err;
-	do {
-		err = _nfs4_do_close(inode, state);
-		switch (err) {
-			case -NFS4ERR_STALE_STATEID:
-			case -NFS4ERR_EXPIRED:
-				nfs4_schedule_state_recovery(server->nfs4_state);
-				err = 0;
-			default:
-				state->state = 0;
-		}
-		err = nfs4_handle_exception(server, err, &exception);
-	} while (exception.retry);
-	return err;
-}
-
-static int _nfs4_do_downgrade(struct inode *inode, struct nfs4_state *state, mode_t mode) 
-{
-	struct nfs4_state_owner *sp = state->owner;
-	int status = 0;
-	struct nfs_closeargs arg = {
-		.fh		= NFS_FH(inode),
-		.seqid		= sp->so_seqid,
-		.open_flags	= mode,
-	};
-	struct nfs_closeres res;
-	struct rpc_message msg = {
-		.rpc_proc	= &nfs4_procedures[NFSPROC4_CLNT_OPEN_DOWNGRADE],
-		.rpc_argp	= &arg,
-		.rpc_resp	= &res,
-	};
-
-	if (test_bit(NFS_DELEGATED_STATE, &state->flags))
-		return 0;
-	memcpy(&arg.stateid, &state->stateid, sizeof(arg.stateid));
-	status = rpc_call_sync(NFS_SERVER(inode)->client, &msg, RPC_TASK_NOINTR);
-	nfs4_increment_seqid(status, sp);
-	if (!status)
-		memcpy(&state->stateid, &res.stateid, sizeof(state->stateid));
-
-	return status;
-}
-
-int nfs4_do_downgrade(struct inode *inode, struct nfs4_state *state, mode_t mode) 
-{
-	struct nfs_server *server = NFS_SERVER(state->inode);
-	struct nfs4_exception exception = { };
-	int err;
-	do {
-		err = _nfs4_do_downgrade(inode, state, mode);
-		switch (err) {
-			case -NFS4ERR_STALE_STATEID:
-			case -NFS4ERR_EXPIRED:
-				nfs4_schedule_state_recovery(server->nfs4_state);
-				err = 0;
-			default:
-				state->state = mode;
-		}
-		err = nfs4_handle_exception(server, err, &exception);
-	} while (exception.retry);
-	return err;
+	return (status == 0) ? -EINPROGRESS : status;
 }
 
 struct inode *
@@ -785,7 +774,7 @@
 	}
 
 	cred = rpcauth_lookupcred(NFS_SERVER(dir)->client->cl_auth, 0);
-	state = nfs4_do_open(dir, &dentry->d_name, nd->intent.open.flags, &attr, cred);
+	state = nfs4_do_open(dir, dentry, nd->intent.open.flags, &attr, cred);
 	put_rpccred(cred);
 	if (IS_ERR(state))
 		return (struct inode *)state;
@@ -802,7 +791,7 @@
 	cred = rpcauth_lookupcred(NFS_SERVER(dir)->client->cl_auth, 0);
 	state = nfs4_open_delegated(dentry->d_inode, openflags, cred);
 	if (IS_ERR(state))
-		state = nfs4_do_open(dir, &dentry->d_name, openflags, NULL, cred);
+		state = nfs4_do_open(dir, dentry, openflags, NULL, cred);
 	put_rpccred(cred);
 	if (state == ERR_PTR(-ENOENT) && dentry->d_inode == 0)
 		return 1;
@@ -1026,7 +1015,7 @@
 					FMODE_WRITE, cred);
 			if (IS_ERR(state))
 				state = nfs4_do_open(dentry->d_parent->d_inode,
-						&dentry->d_name, FMODE_WRITE,
+						dentry, FMODE_WRITE,
 						NULL, cred);
 			need_iput = 1;
 		}
@@ -1327,7 +1316,7 @@
  */
 
 static struct inode *
-nfs4_proc_create(struct inode *dir, struct qstr *name, struct iattr *sattr,
+nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
                  int flags)
 {
 	struct inode *inode;
@@ -1335,7 +1324,7 @@
 	struct rpc_cred *cred;
 
 	cred = rpcauth_lookupcred(NFS_SERVER(dir)->client->cl_auth, 0);
-	state = nfs4_do_open(dir, name, flags, sattr, cred);
+	state = nfs4_do_open(dir, dentry, flags, sattr, cred);
 	put_rpccred(cred);
 	if (!IS_ERR(state)) {
 		inode = state->inode;
diff -Nru a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
--- a/fs/nfs/nfs4state.c	2005-03-01 23:38:44 -08:00
+++ b/fs/nfs/nfs4state.c	2005-03-01 23:38:44 -08:00
@@ -51,7 +51,7 @@
 
 #define OPENOWNER_POOL_SIZE	8
 
-static spinlock_t		state_spinlock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(state_spinlock);
 
 nfs4_stateid zero_stateid;
 
@@ -445,7 +445,7 @@
 		state->owner = owner;
 		atomic_inc(&owner->so_count);
 		list_add(&state->inode_states, &nfsi->open_states);
-		state->inode = inode;
+		state->inode = igrab(inode);
 		spin_unlock(&inode->i_lock);
 	} else {
 		spin_unlock(&inode->i_lock);
@@ -471,6 +471,7 @@
 		list_del(&state->inode_states);
 	spin_unlock(&inode->i_lock);
 	list_del(&state->open_states);
+	iput(inode);
 	BUG_ON (state->state != 0);
 	nfs4_free_open_state(state);
 	nfs4_put_state_owner(owner);
@@ -486,7 +487,6 @@
 	struct nfs4_state_owner *owner = state->owner;
 	struct nfs4_client *clp = owner->so_client;
 	int newstate;
-	int status = 0;
 
 	atomic_inc(&owner->so_count);
 	down_read(&clp->cl_sem);
@@ -508,10 +508,8 @@
 			newstate |= FMODE_WRITE;
 		if (state->state == newstate)
 			goto out;
-		if (newstate != 0)
-			status = nfs4_do_downgrade(inode, state, newstate);
-		else
-			status = nfs4_do_close(inode, state);
+		if (nfs4_do_close(inode, state, newstate) == -EINPROGRESS)
+			return;
 	}
 out:
 	nfs4_put_open_state(state);
diff -Nru a/fs/nfs/proc.c b/fs/nfs/proc.c
--- a/fs/nfs/proc.c	2005-03-01 23:39:16 -08:00
+++ b/fs/nfs/proc.c	2005-03-01 23:39:16 -08:00
@@ -63,12 +63,12 @@
 	dprintk("%s: call getattr\n", __FUNCTION__);
 	fattr->valid = 0;
 	status = rpc_call(server->client_sys, NFSPROC_GETATTR, fhandle, fattr, 0);
-	dprintk("%s: reply getattr %d\n", __FUNCTION__, status);
+	dprintk("%s: reply getattr: %d\n", __FUNCTION__, status);
 	if (status)
 		return status;
 	dprintk("%s: call statfs\n", __FUNCTION__);
 	status = rpc_call(server->client_sys, NFSPROC_STATFS, fhandle, &fsinfo, 0);
-	dprintk("%s: reply statfs %d\n", __FUNCTION__, status);
+	dprintk("%s: reply statfs: %d\n", __FUNCTION__, status);
 	if (status)
 		return status;
 	info->rtmax  = NFS_MAXDATA;
@@ -96,7 +96,7 @@
 	fattr->valid = 0;
 	status = rpc_call(server->client, NFSPROC_GETATTR,
 				fhandle, fattr, 0);
-	dprintk("NFS reply getattr\n");
+	dprintk("NFS reply getattr: %d\n", status);
 	return status;
 }
 
@@ -114,7 +114,7 @@
 	dprintk("NFS call  setattr\n");
 	fattr->valid = 0;
 	status = rpc_call(NFS_CLIENT(inode), NFSPROC_SETATTR, &arg, fattr, 0);
-	dprintk("NFS reply setattr\n");
+	dprintk("NFS reply setattr: %d\n", status);
 	return status;
 }
 
@@ -213,15 +213,15 @@
 }
 
 static struct inode *
-nfs_proc_create(struct inode *dir, struct qstr *name, struct iattr *sattr,
+nfs_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
 		int flags)
 {
 	struct nfs_fh		fhandle;
 	struct nfs_fattr	fattr;
 	struct nfs_createargs	arg = {
 		.fh		= NFS_FH(dir),
-		.name		= name->name,
-		.len		= name->len,
+		.name		= dentry->d_name.name,
+		.len		= dentry->d_name.len,
 		.sattr		= sattr
 	};
 	struct nfs_diropok	res = {
@@ -231,7 +231,7 @@
 	int			status;
 
 	fattr.valid = 0;
-	dprintk("NFS call  create %s\n", name->name);
+	dprintk("NFS call  create %s\n", dentry->d_name.name);
 	status = rpc_call(NFS_CLIENT(dir), NFSPROC_CREATE, &arg, &res, 0);
 	dprintk("NFS reply create: %d\n", status);
 	if (status == 0) {
diff -Nru a/fs/nfs/read.c b/fs/nfs/read.c
--- a/fs/nfs/read.c	2005-03-01 23:38:43 -08:00
+++ b/fs/nfs/read.c	2005-03-01 23:38:43 -08:00
@@ -24,7 +24,6 @@
 #include <linux/mm.h>
 #include <linux/slab.h>
 #include <linux/pagemap.h>
-#include <linux/mempool.h>
 #include <linux/sunrpc/clnt.h>
 #include <linux/nfs_fs.h>
 #include <linux/nfs_page.h>
@@ -39,25 +38,11 @@
 static void nfs_readpage_result_full(struct nfs_read_data *, int);
 
 static kmem_cache_t *nfs_rdata_cachep;
-static mempool_t *nfs_rdata_mempool;
+mempool_t *nfs_rdata_mempool;
 
 #define MIN_POOL_READ	(32)
 
-static struct nfs_read_data *nfs_readdata_alloc(void)
-{
-	struct nfs_read_data   *p;
-	p = (struct nfs_read_data *)mempool_alloc(nfs_rdata_mempool, SLAB_NOFS);
-	if (p)
-		memset(p, 0, sizeof(*p));
-	return p;
-}
-
-static __inline__ void nfs_readdata_free(struct nfs_read_data *p)
-{
-	mempool_free(p, nfs_rdata_mempool);
-}
-
-static void nfs_readdata_release(struct rpc_task *task)
+void nfs_readdata_release(struct rpc_task *task)
 {
         struct nfs_read_data   *data = (struct nfs_read_data *)task->tk_calldata;
         nfs_readdata_free(data);
diff -Nru a/fs/nfs/unlink.c b/fs/nfs/unlink.c
--- a/fs/nfs/unlink.c	2005-03-01 23:39:16 -08:00
+++ b/fs/nfs/unlink.c	2005-03-01 23:39:16 -08:00
@@ -215,7 +215,6 @@
 	spin_lock(&dentry->d_lock);
 	dentry->d_flags &= ~DCACHE_NFSFS_RENAMED;
 	spin_unlock(&dentry->d_lock);
-	if (data->task.tk_rpcwait == &nfs_delete_queue)
-		rpc_wake_up_task(&data->task);
+	rpc_wake_up_task(&data->task);
 	nfs_put_unlinkdata(data);
 }
diff -Nru a/fs/nfs/write.c b/fs/nfs/write.c
--- a/fs/nfs/write.c	2005-03-01 23:39:08 -08:00
+++ b/fs/nfs/write.c	2005-03-01 23:39:08 -08:00
@@ -61,7 +61,6 @@
 #include <linux/nfs_page.h>
 #include <asm/uaccess.h>
 #include <linux/smp_lock.h>
-#include <linux/mempool.h>
 
 #include "delegation.h"
 
@@ -83,49 +82,17 @@
 static int nfs_wait_on_requests(struct inode *, unsigned long, unsigned int);
 
 static kmem_cache_t *nfs_wdata_cachep;
-static mempool_t *nfs_wdata_mempool;
-static mempool_t *nfs_commit_mempool;
+mempool_t *nfs_wdata_mempool;
+mempool_t *nfs_commit_mempool;
 
 static DECLARE_WAIT_QUEUE_HEAD(nfs_write_congestion);
 
-static __inline__ struct nfs_write_data *nfs_writedata_alloc(void)
-{
-	struct nfs_write_data	*p;
-	p = (struct nfs_write_data *)mempool_alloc(nfs_wdata_mempool, SLAB_NOFS);
-	if (p) {
-		memset(p, 0, sizeof(*p));
-		INIT_LIST_HEAD(&p->pages);
-	}
-	return p;
-}
-
-static __inline__ void nfs_writedata_free(struct nfs_write_data *p)
-{
-	mempool_free(p, nfs_wdata_mempool);
-}
-
-static void nfs_writedata_release(struct rpc_task *task)
+void nfs_writedata_release(struct rpc_task *task)
 {
 	struct nfs_write_data	*wdata = (struct nfs_write_data *)task->tk_calldata;
 	nfs_writedata_free(wdata);
 }
 
-static __inline__ struct nfs_write_data *nfs_commit_alloc(void)
-{
-	struct nfs_write_data	*p;
-	p = (struct nfs_write_data *)mempool_alloc(nfs_commit_mempool, SLAB_NOFS);
-	if (p) {
-		memset(p, 0, sizeof(*p));
-		INIT_LIST_HEAD(&p->pages);
-	}
-	return p;
-}
-
-static __inline__ void nfs_commit_free(struct nfs_write_data *p)
-{
-	mempool_free(p, nfs_commit_mempool);
-}
-
 /* Adjust the file length if we're writing beyond the end */
 static void nfs_grow_file(struct page *page, unsigned int offset, unsigned int count)
 {
@@ -184,11 +151,10 @@
 	int		result, written = 0;
 	struct nfs_write_data *wdata;
 
-	wdata = kmalloc(sizeof(*wdata), GFP_NOFS);
+	wdata = nfs_writedata_alloc();
 	if (!wdata)
 		return -ENOMEM;
 
-	memset(wdata, 0, sizeof(*wdata));
 	wdata->flags = how;
 	wdata->cred = ctx->cred;
 	wdata->inode = inode;
@@ -238,8 +204,7 @@
 
 io_error:
 	nfs_end_data_update_defer(inode);
-
-	kfree(wdata);
+	nfs_writedata_free(wdata);
 	return written ? written : result;
 }
 
@@ -1199,7 +1164,8 @@
 		}
 		if (time_before(complain, jiffies)) {
 			printk(KERN_WARNING
-			       "NFS: Server wrote less than requested.\n");
+			       "NFS: Server wrote zero bytes, expected %u.\n",
+					argp->count);
 			complain = jiffies + 300 * HZ;
 		}
 		/* Can't do anything about it except throw an error. */
diff -Nru a/fs/nfsd/Makefile b/fs/nfsd/Makefile
--- a/fs/nfsd/Makefile	2005-03-01 23:39:18 -08:00
+++ b/fs/nfsd/Makefile	2005-03-01 23:39:18 -08:00
@@ -8,5 +8,5 @@
 			   export.o auth.o lockd.o nfscache.o nfsxdr.o stats.o
 nfsd-$(CONFIG_NFSD_V3)	+= nfs3proc.o nfs3xdr.o
 nfsd-$(CONFIG_NFSD_V4)	+= nfs4proc.o nfs4xdr.o nfs4state.o nfs4idmap.o \
-			   nfs4acl.o
+			   nfs4acl.o nfs4callback.o
 nfsd-objs		:= $(nfsd-y)
diff -Nru a/fs/nfsd/export.c b/fs/nfsd/export.c
--- a/fs/nfsd/export.c	2005-03-01 23:38:58 -08:00
+++ b/fs/nfsd/export.c	2005-03-01 23:38:58 -08:00
@@ -305,11 +305,6 @@
 
 static struct svc_export *svc_export_lookup(struct svc_export *, int);
 
-extern struct dentry *
-find_exported_dentry(struct super_block *sb, void *obj, void *parent,
-		     int (*acceptable)(void *context, struct dentry *de),
-		     void *context);
-
 static int check_export(struct inode *inode, int flags)
 {
 
diff -Nru a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
--- a/fs/nfsd/nfs3xdr.c	2005-03-01 23:38:43 -08:00
+++ b/fs/nfsd/nfs3xdr.c	2005-03-01 23:38:43 -08:00
@@ -102,22 +102,6 @@
 }
 
 static inline u32 *
-decode_pathname(u32 *p, char **namp, int *lenp)
-{
-	char		*name;
-	int		i;
-
-	if ((p = xdr_decode_string_inplace(p, namp, lenp, NFS3_MAXPATHLEN)) != NULL) {
-		for (i = 0, name = *namp; i < *lenp; i++, name++) {
-			if (*name == '\0')
-				return NULL;
-		}
-	}
-
-	return p;
-}
-
-static inline u32 *
 decode_sattr3(u32 *p, struct iattr *iap)
 {
 	u32	tmp;
diff -Nru a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/fs/nfsd/nfs4callback.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,583 @@
+/*
+ *  linux/fs/nfsd/nfs4callback.c
+ *
+ *  Copyright (c) 2001 The Regents of the University of Michigan.
+ *  All rights reserved.
+ *
+ *  Kendrick Smith <kmsmith@umich.edu>
+ *  Andy Adamson <andros@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/config.h>
+#include <linux/module.h>
+#include <linux/list.h>
+#include <linux/inet.h>
+#include <linux/errno.h>
+#include <linux/sunrpc/xdr.h>
+#include <linux/sunrpc/svc.h>
+#include <linux/sunrpc/clnt.h>
+#include <linux/nfsd/nfsd.h>
+#include <linux/nfsd/state.h>
+#include <linux/sunrpc/sched.h>
+#include <linux/nfs4.h>
+
+#define NFSDDBG_FACILITY                NFSDDBG_PROC
+
+#define NFSPROC4_CB_NULL 0
+#define NFSPROC4_CB_COMPOUND 1
+
+/* declarations */
+static void nfs4_cb_null(struct rpc_task *task);
+extern spinlock_t recall_lock;
+
+/* Index of predefined Linux callback client operations */
+
+enum {
+        NFSPROC4_CLNT_CB_NULL = 0,
+	NFSPROC4_CLNT_CB_RECALL,
+};
+
+enum nfs_cb_opnum4 {
+	OP_CB_RECALL            = 4,
+};
+
+#define NFS4_MAXTAGLEN		20
+
+#define NFS4_enc_cb_null_sz		0
+#define NFS4_dec_cb_null_sz		0
+#define cb_compound_enc_hdr_sz		4
+#define cb_compound_dec_hdr_sz		(3 + (NFS4_MAXTAGLEN >> 2))
+#define op_enc_sz			1
+#define op_dec_sz			2
+#define enc_nfs4_fh_sz			(1 + (NFS4_FHSIZE >> 2))
+#define enc_stateid_sz			16
+#define NFS4_enc_cb_recall_sz		(cb_compound_enc_hdr_sz +       \
+					1 + enc_stateid_sz +            \
+					enc_nfs4_fh_sz)
+
+#define NFS4_dec_cb_recall_sz		(cb_compound_dec_hdr_sz  +      \
+					op_dec_sz)
+
+/*
+* Generic encode routines from fs/nfs/nfs4xdr.c
+*/
+static inline u32 *
+xdr_writemem(u32 *p, const void *ptr, int nbytes)
+{
+	int tmp = XDR_QUADLEN(nbytes);
+	if (!tmp)
+		return p;
+	p[tmp-1] = 0;
+	memcpy(p, ptr, nbytes);
+	return p + tmp;
+}
+
+#define WRITE32(n)               *p++ = htonl(n)
+#define WRITEMEM(ptr,nbytes)     do {                           \
+	p = xdr_writemem(p, ptr, nbytes);                       \
+} while (0)
+#define RESERVE_SPACE(nbytes)   do {                            \
+	p = xdr_reserve_space(xdr, nbytes);                     \
+	if (!p) dprintk("NFSD: RESERVE_SPACE(%d) failed in function %s\n", (int) (nbytes), __FUNCTION__); \
+	BUG_ON(!p);                                             \
+} while (0)
+
+/*
+ * Generic decode routines from fs/nfs/nfs4xdr.c
+ */
+#define DECODE_TAIL                             \
+	status = 0;                             \
+out:                                            \
+	return status;                          \
+xdr_error:                                      \
+	dprintk("NFSD: xdr error! (%s:%d)\n", __FILE__, __LINE__); \
+	status = -EIO;                          \
+	goto out
+
+#define READ32(x)         (x) = ntohl(*p++)
+#define READ64(x)         do {                  \
+	(x) = (u64)ntohl(*p++) << 32;           \
+	(x) |= ntohl(*p++);                     \
+} while (0)
+#define READTIME(x)       do {                  \
+	p++;                                    \
+	(x.tv_sec) = ntohl(*p++);               \
+	(x.tv_nsec) = ntohl(*p++);              \
+} while (0)
+#define READ_BUF(nbytes)  do { \
+	p = xdr_inline_decode(xdr, nbytes); \
+	if (!p) { \
+		dprintk("NFSD: %s: reply buffer overflowed in line %d.", \
+			__FUNCTION__, __LINE__); \
+		return -EIO; \
+	} \
+} while (0)
+
+struct nfs4_cb_compound_hdr {
+	int		status;
+	u32		ident;
+	u32		nops;
+	u32		taglen;
+	char *		tag;
+};
+
+static struct {
+int stat;
+int errno;
+} nfs_cb_errtbl[] = {
+	{ NFS4_OK,		0               },
+	{ NFS4ERR_PERM,		EPERM           },
+	{ NFS4ERR_NOENT,	ENOENT          },
+	{ NFS4ERR_IO,		EIO             },
+	{ NFS4ERR_NXIO,		ENXIO           },
+	{ NFS4ERR_ACCESS,	EACCES          },
+	{ NFS4ERR_EXIST,	EEXIST          },
+	{ NFS4ERR_XDEV,		EXDEV           },
+	{ NFS4ERR_NOTDIR,	ENOTDIR         },
+	{ NFS4ERR_ISDIR,	EISDIR          },
+	{ NFS4ERR_INVAL,	EINVAL          },
+	{ NFS4ERR_FBIG,		EFBIG           },
+	{ NFS4ERR_NOSPC,	ENOSPC          },
+	{ NFS4ERR_ROFS,		EROFS           },
+	{ NFS4ERR_MLINK,	EMLINK          },
+	{ NFS4ERR_NAMETOOLONG,	ENAMETOOLONG    },
+	{ NFS4ERR_NOTEMPTY,	ENOTEMPTY       },
+	{ NFS4ERR_DQUOT,	EDQUOT          },
+	{ NFS4ERR_STALE,	ESTALE          },
+	{ NFS4ERR_BADHANDLE,	EBADHANDLE      },
+	{ NFS4ERR_BAD_COOKIE,	EBADCOOKIE      },
+	{ NFS4ERR_NOTSUPP,	ENOTSUPP        },
+	{ NFS4ERR_TOOSMALL,	ETOOSMALL       },
+	{ NFS4ERR_SERVERFAULT,	ESERVERFAULT    },
+	{ NFS4ERR_BADTYPE,	EBADTYPE        },
+	{ NFS4ERR_LOCKED,	EAGAIN          },
+	{ NFS4ERR_RESOURCE,	EREMOTEIO       },
+	{ NFS4ERR_SYMLINK,	ELOOP           },
+	{ NFS4ERR_OP_ILLEGAL,	EOPNOTSUPP      },
+	{ NFS4ERR_DEADLOCK,	EDEADLK         },
+	{ -1,                   EIO             }
+};
+
+static int
+nfs_cb_stat_to_errno(int stat)
+{
+	int i;
+	for (i = 0; nfs_cb_errtbl[i].stat != -1; i++) {
+		if (nfs_cb_errtbl[i].stat == stat)
+			return nfs_cb_errtbl[i].errno;
+	}
+	/* If we cannot translate the error, the recovery routines should
+	* handle it.
+	* Note: remaining NFSv4 error codes have values > 10000, so should
+	* not conflict with native Linux error codes.
+	*/
+	return stat;
+}
+
+/*
+ * XDR encode
+ */
+
+static int
+encode_cb_compound_hdr(struct xdr_stream *xdr, struct nfs4_cb_compound_hdr *hdr)
+{
+	u32 * p;
+
+	RESERVE_SPACE(16);
+	WRITE32(0);            /* tag length is always 0 */
+	WRITE32(NFS4_MINOR_VERSION);
+	WRITE32(hdr->ident);
+	WRITE32(hdr->nops);
+	return 0;
+}
+
+static int
+encode_cb_recall(struct xdr_stream *xdr, struct nfs4_cb_recall *cb_rec)
+{
+	u32 *p;
+	int len = cb_rec->cbr_fhlen;
+
+	RESERVE_SPACE(12+sizeof(cb_rec->cbr_stateid) + len);
+	WRITE32(OP_CB_RECALL);
+	WRITEMEM(&cb_rec->cbr_stateid, sizeof(stateid_t));
+	WRITE32(cb_rec->cbr_trunc);
+	WRITE32(len);
+	WRITEMEM(cb_rec->cbr_fhval, len);
+	return 0;
+}
+
+static int
+nfs4_xdr_enc_cb_null(struct rpc_rqst *req, u32 *p)
+{
+	struct xdr_stream xdrs, *xdr = &xdrs;
+
+	xdr_init_encode(&xdrs, &req->rq_snd_buf, p);
+        RESERVE_SPACE(0);
+	return 0;
+}
+
+static int
+nfs4_xdr_enc_cb_recall(struct rpc_rqst *req, u32 *p, struct nfs4_cb_recall *args)
+{
+	struct xdr_stream xdr;
+	struct nfs4_cb_compound_hdr hdr = {
+		.nops   = 1,
+	};
+
+	xdr_init_encode(&xdr, &req->rq_snd_buf, p);
+	encode_cb_compound_hdr(&xdr, &hdr);
+	return (encode_cb_recall(&xdr, args));
+}
+
+
+static int
+decode_cb_compound_hdr(struct xdr_stream *xdr, struct nfs4_cb_compound_hdr *hdr){
+        u32 *p;
+
+        READ_BUF(8);
+        READ32(hdr->status);
+        READ32(hdr->taglen);
+        READ_BUF(hdr->taglen + 4);
+        hdr->tag = (char *)p;
+        p += XDR_QUADLEN(hdr->taglen);
+        READ32(hdr->nops);
+        return 0;
+}
+
+static int
+decode_cb_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected)
+{
+	u32 *p;
+	u32 op;
+	int32_t nfserr;
+
+	READ_BUF(8);
+	READ32(op);
+	if (op != expected) {
+		dprintk("NFSD: decode_cb_op_hdr: Callback server returned "
+		         " operation %d but we issued a request for %d\n",
+		         op, expected);
+		return -EIO;
+	}
+	READ32(nfserr);
+	if (nfserr != NFS_OK)
+		return -nfs_cb_stat_to_errno(nfserr);
+	return 0;
+}
+
+static int
+nfs4_xdr_dec_cb_null(struct rpc_rqst *req, u32 *p)
+{
+	return 0;
+}
+
+static int
+nfs4_xdr_dec_cb_recall(struct rpc_rqst *rqstp, u32 *p)
+{
+	struct xdr_stream xdr;
+	struct nfs4_cb_compound_hdr hdr;
+	int status;
+
+	xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
+	status = decode_cb_compound_hdr(&xdr, &hdr);
+	if (status)
+		goto out;
+	status = decode_cb_op_hdr(&xdr, OP_CB_RECALL);
+out	:
+	return status;
+}
+
+/*
+ * RPC procedure tables
+ */
+#ifndef MAX
+# define MAX(a, b)      (((a) > (b))? (a) : (b))
+#endif
+
+#define PROC(proc, call, argtype, restype)                              \
+[NFSPROC4_CLNT_##proc] = {                                      	\
+        .p_proc   = NFSPROC4_CB_##call,					\
+        .p_encode = (kxdrproc_t) nfs4_xdr_##argtype,                    \
+        .p_decode = (kxdrproc_t) nfs4_xdr_##restype,                    \
+        .p_bufsiz = MAX(NFS4_##argtype##_sz,NFS4_##restype##_sz) << 2,  \
+}
+
+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 = {
+        .number                 = 1,
+        .nrprocs                = sizeof(nfs4_cb_procedures)/sizeof(nfs4_cb_procedures[0]),
+        .procs                  = nfs4_cb_procedures
+};
+
+static struct rpc_version *	nfs_cb_version[] = {
+	NULL,
+	&nfs_cb_version4,
+};
+
+/*
+ * Use the SETCLIENTID credential
+ */
+struct rpc_cred *
+nfsd4_lookupcred(struct nfs4_client *clp, int taskflags)
+{
+        struct auth_cred acred;
+	struct rpc_clnt *clnt = clp->cl_callback.cb_client;
+        struct rpc_cred *ret = NULL;
+
+	if (!clnt)
+		goto out;
+        get_group_info(clp->cl_cred.cr_group_info);
+        acred.uid = clp->cl_cred.cr_uid;
+        acred.gid = clp->cl_cred.cr_gid;
+        acred.group_info = clp->cl_cred.cr_group_info;
+
+        dprintk("NFSD:     looking up %s cred\n",
+                clnt->cl_auth->au_ops->au_name);
+        ret = rpcauth_lookup_credcache(clnt->cl_auth, &acred, taskflags);
+        put_group_info(clp->cl_cred.cr_group_info);
+out:
+        return ret;
+}
+
+/*
+ * Set up the callback client and put a NFSPROC4_CB_NULL on the wire...
+ */
+void
+nfsd4_probe_callback(struct nfs4_client *clp)
+{
+	struct sockaddr_in	addr;
+	struct nfs4_callback    *cb = &clp->cl_callback;
+	struct rpc_timeout	timeparms;
+	struct rpc_xprt *	xprt;
+	struct rpc_program *	program = &cb->cb_program;
+	struct rpc_stat *	stat = &cb->cb_stat;
+	struct rpc_clnt *	clnt;
+	struct rpc_message msg = {
+		.rpc_proc       = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_NULL],
+		.rpc_argp       = clp,
+	};
+	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))
+		return;
+
+	/* Initialize address */
+	memset(&addr, 0, sizeof(addr));
+	addr.sin_family = AF_INET;
+	addr.sin_port = htons(cb->cb_port);
+	addr.sin_addr.s_addr = htonl(cb->cb_addr);
+
+	/* Initialize timeout */
+	timeparms.to_initval = (NFSD_LEASE_TIME/4) * HZ;
+	timeparms.to_retries = 5;
+	timeparms.to_maxval = (NFSD_LEASE_TIME/2) * HZ;
+	timeparms.to_exponential = 1;
+
+	/* Create RPC transport */
+	if (!(xprt = xprt_create_proto(IPPROTO_TCP, &addr, &timeparms))) {
+		dprintk("NFSD: couldn't create callback transport!\n");
+		goto out_err;
+	}
+
+	/* Initialize rpc_program */
+	program->name = "nfs4_cb";
+	program->number = cb->cb_prog;
+	program->nrvers = sizeof(nfs_cb_version)/sizeof(nfs_cb_version[0]);
+	program->version = nfs_cb_version;
+	program->stats = stat;
+
+	/* Initialize rpc_stat */
+	memset(stat, 0, sizeof(struct rpc_stat));
+	stat->program = program;
+
+	/* Create RPC client
+ 	 *
+	 * XXX AUTH_UNIX only - need AUTH_GSS....
+	 */
+	sprintf(hostname, "%u.%u.%u.%u", NIPQUAD(addr.sin_addr.s_addr));
+	if (!(clnt = rpc_create_client(xprt, hostname, program, 1, RPC_AUTH_UNIX))) {
+		dprintk("NFSD: couldn't create callback client\n");
+		goto out_xprt;
+	}
+	clnt->cl_intr = 1;
+	clnt->cl_softrtry = 1;
+	clnt->cl_chatty = 1;
+	cb->cb_client = clnt;
+
+	/* Kick rpciod, put the call on the wire. */
+
+	if (rpciod_up() != 0) {
+		dprintk("nfsd: couldn't start rpciod for callbacks!\n");
+		goto out_clnt;
+	}
+
+	/* the task holds a reference to the nfs4_client struct */
+	atomic_inc(&clp->cl_count);
+
+	msg.rpc_cred = nfsd4_lookupcred(clp,0);
+	status = rpc_call_async(clnt, &msg, RPC_TASK_ASYNC, nfs4_cb_null, NULL);
+
+	if (status != 0) {
+		dprintk("NFSD: asynchronous NFSPROC4_CB_NULL failed!\n");
+		goto out_rpciod;
+	}
+	return;
+
+out_rpciod:
+	rpciod_down();
+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);
+	cb->cb_client = NULL;
+}
+
+static void
+nfs4_cb_null(struct rpc_task *task)
+{
+	struct nfs4_client *clp = (struct nfs4_client *)task->tk_msg.rpc_argp;
+	struct nfs4_callback *cb = &clp->cl_callback;
+	u32 addr = htonl(cb->cb_addr);
+
+	dprintk("NFSD: nfs4_cb_null task->tk_status %d\n", task->tk_status);
+
+	if (task->tk_status < 0) {
+		dprintk("NFSD: callback establishment to client %.*s failed\n",
+			(int)clp->cl_name.len, clp->cl_name.data);
+		goto out;
+	}
+	atomic_set(&cb->cb_set, 1);
+	dprintk("NFSD: callback set to client %u.%u.%u.%u\n", NIPQUAD(addr));
+out:
+	put_nfs4_client(clp);
+}
+
+/*
+ *  Called with dp->dl_count incremented
+ */
+static void
+nfs4_cb_recall_done(struct rpc_task *task)
+{
+	struct nfs4_cb_recall *cbr = (struct nfs4_cb_recall *)task->tk_calldata;
+	struct nfs4_delegation *dp = cbr->cbr_dp;
+	int status;
+
+	/* all is well... */
+	if (task->tk_status == 0)
+		goto out;
+
+	/* network partition, retry nfsd4_cb_recall once.  */
+	if (task->tk_status == -EIO) {
+		if (atomic_read(&dp->dl_recall_cnt) == 0)
+			goto retry;
+		else
+			/* callback channel no longer available */
+			atomic_set(&dp->dl_client->cl_callback.cb_set, 0);
+	}
+
+	/* Race: a recall occurred miliseconds after a delegation was granted.
+	* Client may have received recall prior to delegation. retry recall
+	* once.
+	*/
+	if ((task->tk_status == -EBADHANDLE) || (task->tk_status == -NFS4ERR_BAD_STATEID)){
+		if (atomic_read(&dp->dl_recall_cnt) == 0)
+			goto retry;
+	}
+	atomic_set(&dp->dl_state, NFS4_RECALL_COMPLETE);
+
+out:
+	if (atomic_dec_and_test(&dp->dl_count))
+		atomic_set(&dp->dl_state, NFS4_REAP_DELEG);
+	BUG_ON(atomic_read(&dp->dl_count) < 0);
+	dprintk("NFSD: nfs4_cb_recall_done: dp %p dl_flock %p dl_count %d\n",dp, dp->dl_flock, atomic_read(&dp->dl_count));
+	return;
+
+retry:
+	atomic_inc(&dp->dl_recall_cnt);
+	/* sleep 2 seconds before retrying recall */
+	set_current_state(TASK_UNINTERRUPTIBLE);
+	schedule_timeout(2*HZ);
+	status = nfsd4_cb_recall(dp);
+	dprintk("NFSD: nfs4_cb_recall_done: retry status: %d  dp %p dl_flock %p\n",status,dp, dp->dl_flock);
+}
+
+/*
+ * called with dp->dl_count inc'ed.
+ * nfs4_lock_state() may or may not have been called.
+ */
+int
+nfsd4_cb_recall(struct nfs4_delegation *dp)
+{
+	struct nfs4_client *clp;
+	struct rpc_clnt *clnt;
+	struct rpc_message msg = {
+		.rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_RECALL],
+	};
+	struct nfs4_cb_recall *cbr = &dp->dl_recall;
+	int status;
+
+	dprintk("NFSD: nfsd4_cb_recall NFS4_enc_cb_recall_sz %d NFS4_dec_cb_recall_sz %d \n",NFS4_enc_cb_recall_sz,NFS4_dec_cb_recall_sz);
+
+	clp = dp->dl_client;
+	clnt = clp->cl_callback.cb_client;
+	status = EIO;
+	if ((!atomic_read(&clp->cl_callback.cb_set)) || !clnt)
+		goto out_free;
+
+	msg.rpc_argp = cbr;
+	msg.rpc_resp = cbr;
+	msg.rpc_cred = nfsd4_lookupcred(clp,0);
+
+	cbr->cbr_trunc = 0; /* XXX need to implement truncate optimization */
+	cbr->cbr_dp = dp;
+
+	if ((status = rpc_call_async(clnt, &msg, RPC_TASK_SOFT,
+		nfs4_cb_recall_done, cbr ))) {
+		dprintk("NFSD: recall_delegation: rpc_call_async failed %d\n",
+			status);
+		goto out_fail;
+	}
+out:
+	return status;
+out_fail:
+	status = nfserrno(status);
+	out_free:
+	kfree(cbr);
+	goto out;
+}
diff -Nru a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
--- a/fs/nfsd/nfs4proc.c	2005-03-01 23:39:17 -08:00
+++ b/fs/nfsd/nfs4proc.c	2005-03-01 23:39:17 -08:00
@@ -461,23 +461,8 @@
 }
 
 static inline int
-access_bits_permit_read(unsigned long access_bmap)
-{
-	return test_bit(NFS4_SHARE_ACCESS_READ, &access_bmap) ||
-		test_bit(NFS4_SHARE_ACCESS_BOTH, &access_bmap);
-}
-
-static inline int
-access_bits_permit_write(unsigned long access_bmap)
-{
-	return test_bit(NFS4_SHARE_ACCESS_WRITE, &access_bmap) ||
-		test_bit(NFS4_SHARE_ACCESS_BOTH, &access_bmap);
-}
-
-static inline int
 nfsd4_read(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_read *read)
 {
-	struct nfs4_stateid *stp;
 	int status;
 
 	/* no need to check permission - this will be done in nfsd_read() */
@@ -509,15 +494,10 @@
 	}
 	/* check stateid */
 	if ((status = nfs4_preprocess_stateid_op(current_fh, &read->rd_stateid, 
-					CHECK_FH | RDWR_STATE, &stp))) {
+					CHECK_FH | RD_STATE))) {
 		dprintk("NFSD: nfsd4_read: couldn't process stateid!\n");
 		goto out;
 	}
-	status = nfserr_openmode;
-	if (!access_bits_permit_read(stp->st_access_bmap)) {
-		dprintk("NFSD: nfsd4_read: file not opened for read!\n");
-		goto out;
-	}
 	status = nfs_ok;
 out:
 	nfs4_unlock_state();
@@ -605,7 +585,6 @@
 static inline int
 nfsd4_setattr(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_setattr *setattr)
 {
-	struct nfs4_stateid *stp;
 	int status = nfs_ok;
 
 	if (nfs4_in_grace())
@@ -626,15 +605,10 @@
 		nfs4_lock_state();
 		if ((status = nfs4_preprocess_stateid_op(current_fh, 
 						&setattr->sa_stateid, 
-						CHECK_FH | RDWR_STATE, &stp))) {
+						CHECK_FH | WR_STATE))) {
 			dprintk("NFSD: nfsd4_setattr: couldn't process stateid!\n");
 			goto out_unlock;
 		}
-		status = nfserr_openmode;
-		if (!access_bits_permit_write(stp->st_access_bmap)) {
-			dprintk("NFSD: nfsd4_setattr: not opened for write!\n");
-			goto out_unlock;
-		}
 		nfs4_unlock_state();
 	}
 	status = nfs_ok;
@@ -654,7 +628,6 @@
 static inline int
 nfsd4_write(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_write *write)
 {
-	struct nfs4_stateid *stp;
 	stateid_t *stateid = &write->wr_stateid;
 	u32 *p;
 	int status = nfs_ok;
@@ -677,18 +650,13 @@
 		goto zero_stateid;
 	}
 	if ((status = nfs4_preprocess_stateid_op(current_fh, stateid, 
-					CHECK_FH | RDWR_STATE, &stp))) {
+					CHECK_FH | WR_STATE))) {
 		dprintk("NFSD: nfsd4_write: couldn't process stateid!\n");
 		goto out;
 	}
 
-	status = nfserr_openmode;
-	if (!access_bits_permit_write(stp->st_access_bmap)) {
-		dprintk("NFSD: nfsd4_write: file not open for write!\n");
-		goto out;
-	}
-
 zero_stateid:
+
 	nfs4_unlock_state();
 	write->wr_bytes_written = write->wr_buflen;
 	write->wr_how_written = write->wr_stable_how;
@@ -871,6 +839,9 @@
 			break;
 		case OP_CREATE:
 			op->status = nfsd4_create(rqstp, current_fh, &op->u.create);
+			break;
+		case OP_DELEGRETURN:
+			op->status = nfsd4_delegreturn(rqstp, current_fh, &op->u.delegreturn);
 			break;
 		case OP_GETATTR:
 			op->status = nfsd4_getattr(rqstp, current_fh, &op->u.getattr);
diff -Nru a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
--- a/fs/nfsd/nfs4state.c	2005-03-01 23:39:08 -08:00
+++ b/fs/nfsd/nfs4state.c	2005-03-01 23:39:08 -08:00
@@ -44,6 +44,7 @@
 #include <linux/mount.h>
 #include <linux/workqueue.h>
 #include <linux/smp_lock.h>
+#include <linux/kthread.h>
 #include <linux/nfs4.h>
 #include <linux/nfsd/state.h>
 #include <linux/nfsd/xdr4.h>
@@ -57,8 +58,9 @@
 time_t boot_time;
 static time_t grace_end = 0;
 static u32 current_clientid = 1;
-static u32 current_ownerid;
-static u32 current_fileid;
+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 */
@@ -75,9 +77,14 @@
 u32 vfsopen = 0;
 u32 vfsclose = 0;
 u32 alloc_lsowner= 0;
+u32 alloc_delegation= 0;
+u32 free_delegation= 0;
 
 /* forward declarations */
 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_delegation(struct nfs4_delegation *dp);
+static void release_stateid_lockowner(struct nfs4_stateid *open_stp);
 
 /* Locking:
  *
@@ -117,6 +124,111 @@
 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 struct list_head del_recall_lru;
+
+static struct nfs4_delegation *
+alloc_init_deleg(struct nfs4_client *clp, struct nfs4_file *fp, struct svc_fh *current_fh, u32 type)
+{
+	struct nfs4_delegation *dp;
+
+	dprintk("NFSD alloc_init_deleg\n");
+	if ((dp = kmalloc(sizeof(struct nfs4_delegation),
+		GFP_KERNEL)) == NULL)
+		return dp;
+	INIT_LIST_HEAD(&dp->dl_del_perfile);
+	INIT_LIST_HEAD(&dp->dl_del_perclnt);
+	INIT_LIST_HEAD(&dp->dl_recall_lru);
+	dp->dl_client = clp;
+	dp->dl_file = fp;
+	dp->dl_flock = NULL;
+	dp->dl_stp = NULL;
+	dp->dl_type = type;
+	dp->dl_recall.cbr_dp = NULL;
+	dp->dl_recall.cbr_ident = 0;
+	dp->dl_recall.cbr_trunc = 0;
+	dp->dl_stateid.si_boot = boot_time;
+	dp->dl_stateid.si_stateownerid = current_delegid++;
+	dp->dl_stateid.si_fileid = 0;
+	dp->dl_stateid.si_generation = 0;
+	dp->dl_fhlen = current_fh->fh_handle.fh_size;
+	memcpy(dp->dl_fhval, &current_fh->fh_handle.fh_base,
+		        current_fh->fh_handle.fh_size);
+	dp->dl_time = 0;
+	atomic_set(&dp->dl_state, NFS4_NO_RECALL);
+	atomic_set(&dp->dl_count, 1);
+	atomic_set(&dp->dl_recall_cnt, 0);
+	list_add(&dp->dl_del_perfile, &fp->fi_del_perfile);
+	list_add(&dp->dl_del_perclnt, &clp->cl_del_perclnt);
+	alloc_delegation++;
+	return dp;
+}
+
+/*
+ * Free the delegation structure.
+ * Called with the recall_lock held.
+ */
+static void
+nfs4_free_delegation(struct nfs4_delegation *dp)
+{
+	dprintk("NFSD: nfs4_free_delegation freeing dp %p\n",dp);
+	list_del(&dp->dl_recall_lru);
+	kfree(dp);
+	free_delegation++;
+}
+
+/* release_delegation:
+ *
+ * Remove the associated file_lock first, then remove the delegation.
+ * lease_modify() is called to remove the FS_LEASE file_lock from
+ * the i_flock list, eventually calling nfsd's lock_manager
+ * fl_release_callback.
+ *
+ * call either:
+ *   nfsd_close : if last close, locks_remove_flock calls lease_modify.
+ *                otherwise, recalled state set to NFS4_RECALL_COMPLETE
+ *                so that it will be reaped by the laundromat service.
+ * or
+ *   remove_lease (calls time_out_lease which calls lease_modify).
+ *   and nfs4_free_delegation.
+ *
+ * Called with nfs_lock_state() held.
+ * Called with the recall_lock held.
+ */
+
+static void
+release_delegation(struct nfs4_delegation *dp)
+{
+	/* delayed nfsd_close */
+	if (dp->dl_stp) {
+		struct file *filp = dp->dl_stp->st_vfs_file;
+
+		dprintk("NFSD: release_delegation CLOSE\n");
+		release_stateid_lockowner(dp->dl_stp);
+		kfree(dp->dl_stp);
+		dp->dl_stp = NULL;
+		atomic_set(&dp->dl_state, NFS4_RECALL_COMPLETE);
+		nfsd_close(filp);
+		vfsclose++;
+	} else {
+		dprintk("NFSD: release_delegation remove lease dl_flock %p\n",
+			dp->dl_flock);
+		remove_lease(dp->dl_flock);
+		list_del_init(&dp->dl_del_perfile);
+		list_del_init(&dp->dl_del_perclnt);
+		/* dl_count > 0 => outstanding recall rpc */
+		dprintk("NFSD: release_delegation free deleg dl_count %d\n",
+			           atomic_read(&dp->dl_count));
+		if ((atomic_read(&dp->dl_state) == NFS4_REAP_DELEG)
+		     || atomic_dec_and_test(&dp->dl_count))
+			nfs4_free_delegation(dp);
+	}
+}
 
 /* 
  * SETCLIENTID state 
@@ -213,12 +325,40 @@
 	kfree(clp);
 }
 
+void
+put_nfs4_client(struct nfs4_client *clp)
+{
+	if (atomic_dec_and_test(&clp->cl_count))
+		free_client(clp);
+}
+
 static void
 expire_client(struct nfs4_client *clp)
 {
 	struct nfs4_stateowner *sop;
+	struct nfs4_delegation *dp;
+	struct nfs4_callback *cb = &clp->cl_callback;
+	struct rpc_clnt *clnt = clp->cl_callback.cb_client;
+
+	dprintk("NFSD: expire_client cl_count %d\n",
+	                    atomic_read(&clp->cl_count));
 
-	dprintk("NFSD: expire_client\n");
+	/* shutdown rpc client, ending any outstanding recall rpcs */
+	if (atomic_read(&cb->cb_set) == 1 && clnt) {
+		rpc_shutdown_client(clnt);
+		clnt = clp->cl_callback.cb_client = NULL;
+	}
+	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);
+		dprintk("NFSD: expire client. dp %p, dl_state %d, fp %p\n",
+				dp, atomic_read(&dp->dl_state), dp->dl_flock);
+
+		/* force release of delegation. */
+		atomic_set(&dp->dl_state, NFS4_RECALL_COMPLETE);
+		release_delegation(dp);
+	}
+	spin_unlock(&recall_lock);
 	list_del(&clp->cl_idhash);
 	list_del(&clp->cl_strhash);
 	list_del(&clp->cl_lru);
@@ -226,7 +366,7 @@
 		sop = list_entry(clp->cl_perclient.next, struct nfs4_stateowner, so_perclient);
 		release_stateowner(sop);
 	}
-	free_client(clp);
+	put_nfs4_client(clp);
 }
 
 static struct nfs4_client *
@@ -235,9 +375,13 @@
 
 	if (!(clp = alloc_client(name)))
 		goto out;
+	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_lru);
 out:
 	return clp;
@@ -420,17 +564,24 @@
 {
 	struct nfs4_callback *cb = &clp->cl_callback;
 
+	/* Currently, we only support tcp for the callback channel */
+	if ((se->se_callback_netid_len != 3) || memcmp((char *)se->se_callback_netid_val, "tcp", 3))
+		goto out_err;
+
 	if ( !(parse_ipv4(se->se_callback_addr_len, se->se_callback_addr_val,
-		         &cb->cb_addr, &cb->cb_port))) {
-		printk(KERN_INFO "NFSD: BAD callback address. client will not receive delegations\n");
-		cb->cb_parsed = 0;
-		return;
-	}
-	cb->cb_netid.len = se->se_callback_netid_len;
-	cb->cb_netid.data = se->se_callback_netid_val;
+	                 &cb->cb_addr, &cb->cb_port)))
+		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;
 }
 
 /*
@@ -651,9 +802,8 @@
 	clientid_t * clid = &setclientid_confirm->sc_clientid;
 	int status;
 
-	status = nfserr_stale_clientid;
 	if (STALE_CLIENTID(clid))
-		goto out;
+		return nfserr_stale_clientid;
 	/* 
 	 * XXX The Duplicate Request Cache (DRC) has been checked (??)
 	 * We get here on a DRC miss.
@@ -707,6 +857,7 @@
 			status = nfserr_clid_inuse;
 		else {
 			expire_client(conf);
+			clp = unconf;
 			move_to_confirmed(unconf, idhashval);
 			status = nfs_ok;
 		}
@@ -724,6 +875,7 @@
 		if (!cmp_creds(&conf->cl_cred,&rqstp->rq_cred)) {
 			status = nfserr_clid_inuse;
 		} else {
+			clp = conf;
 			status = nfs_ok;
 		}
 		goto out;
@@ -738,6 +890,7 @@
 			status = nfserr_clid_inuse;
 		} else {
 			status = nfs_ok;
+			clp = unconf;
 			move_to_confirmed(unconf, idhashval);
 		}
 		goto out;
@@ -757,7 +910,8 @@
 	status = nfserr_inval;
 	goto out;
 out:
-	/* XXX if status == nfs_ok, probe callback path */
+	if (!status)
+		nfsd4_probe_callback(clp);
 	nfs4_unlock_state();
 	return status;
 }
@@ -803,6 +957,7 @@
 	if ((fp = kmalloc(sizeof(struct nfs4_file),GFP_KERNEL))) {
 		INIT_LIST_HEAD(&fp->fi_hash);
 		INIT_LIST_HEAD(&fp->fi_perfile);
+		INIT_LIST_HEAD(&fp->fi_del_perfile);
 		list_add(&fp->fi_hash, &file_hashtbl[hashval]);
 		fp->fi_inode = igrab(ino);
 		fp->fi_id = current_fileid++;
@@ -822,7 +977,7 @@
 		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)) {
+			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);
@@ -957,14 +1112,29 @@
 	__set_bit(open->op_share_deny, &stp->st_deny_bmap);
 }
 
+/*
+* Because nfsd_close() can call locks_remove_flock() which removes leases,
+* delay nfsd_close() for delegations from the nfsd_open() clientid
+* until the delegation is reaped.
+*/
 static void
-release_stateid(struct nfs4_stateid *stp, int flags) {
+release_stateid(struct nfs4_stateid *stp, int flags)
+{
+	struct nfs4_delegation *dp;
+	struct nfs4_file *fp = stp->st_file;
 
 	list_del(&stp->st_hash);
 	list_del_perfile++;
 	list_del(&stp->st_perfile);
 	list_del(&stp->st_perfilestate);
 	if ((stp->st_vfs_set) && (flags & OPEN_STATE)) {
+		list_for_each_entry(dp, &fp->fi_del_perfile, dl_del_perfile) {
+			if(cmp_clid(&dp->dl_client->cl_clientid,
+			    &stp->st_stateowner->so_client->cl_clientid)) {
+				dp->dl_stp = stp;
+				return;
+			}
+		}
 		release_stateid_lockowner(stp);
 		nfsd_close(stp->st_vfs_file);
 		vfsclose++;
@@ -1013,7 +1183,7 @@
 	if (sop->so_confirmed && list_empty(&sop->so_perfilestate))
 		move_to_close_lru(sop);
 	/* unused nfs4_file's are releseed. XXX slab cache? */
-	if (list_empty(&fp->fi_perfile)) {
+	if (list_empty(&fp->fi_perfile) && list_empty(&fp->fi_del_perfile)) {
 		release_file(fp);
 	}
 }
@@ -1141,6 +1311,101 @@
 	}
 }
 
+/*
+ * Recall a delegation
+ */
+static int
+do_recall(void *__dp)
+{
+	struct nfs4_delegation *dp = __dp;
+
+	daemonize("nfsv4-recall");
+
+	atomic_inc(&dp->dl_count);
+	nfsd4_cb_recall(dp);
+	return 0;
+}
+
+/*
+ * Spawn a thread to perform a recall on the delegation represented
+ * by the lease (file_lock)
+ *
+ * Called from break_lease() with lock_kernel() held,
+ *
+ */
+static
+void nfsd_break_deleg_cb(struct file_lock *fl)
+{
+	struct nfs4_delegation *dp=  (struct nfs4_delegation *)fl->fl_owner;
+	struct task_struct *t;
+
+	dprintk("NFSD nfsd_break_deleg_cb: dp %p fl %p\n",dp,fl);
+	if (!dp)
+		return;
+
+	/* schedule delegation for recall */
+	spin_lock(&recall_lock);
+	atomic_set(&dp->dl_state, NFS4_RECALL_IN_PROGRESS);
+	list_add_tail(&dp->dl_recall_lru, &del_recall_lru);
+	spin_unlock(&recall_lock);
+
+	/* only place dl_time is set. protected by lock_kernel*/
+	dp->dl_time = get_seconds();
+
+	/* XXX need to merge NFSD_LEASE_TIME with fs/locks.c:lease_break_time */
+	fl->fl_break_time = jiffies + NFSD_LEASE_TIME * HZ;
+
+	t = kthread_run(do_recall, dp, "%s", "nfs4_cb_recall");
+	if (IS_ERR(t)) {
+		struct nfs4_client *clp = dp->dl_client;
+
+		printk(KERN_INFO "NFSD: Callback thread failed for "
+			"for client (clientid %08x/%08x)\n",
+			clp->cl_clientid.cl_boot, clp->cl_clientid.cl_id);
+	}
+}
+
+/*
+ * The file_lock is being reapd.
+ *
+ * Called by locks_free_lock() with lock_kernel() held.
+ */
+static
+void nfsd_release_deleg_cb(struct file_lock *fl)
+{
+	struct nfs4_delegation *dp = (struct nfs4_delegation *)fl->fl_owner;
+
+	dprintk("NFSD nfsd_release_deleg_cb: fl %p dp %p dl_count %d, dl_state %d\n", fl,dp, atomic_read(&dp->dl_count), atomic_read(&dp->dl_state));
+
+	if (!(fl->fl_flags & FL_LEASE) || !dp)
+		return;
+	atomic_set(&dp->dl_state,NFS4_RECALL_COMPLETE);
+	dp->dl_flock = NULL;
+}
+
+/*
+ * Set the delegation file_lock back pointer.
+ *
+ * Called from __setlease() with lock_kernel() held.
+ */
+static
+void nfsd_copy_lock_deleg_cb(struct file_lock *new, struct file_lock *fl)
+{
+	struct nfs4_delegation *dp = (struct nfs4_delegation *)new->fl_owner;
+
+	dprintk("NFSD: nfsd_copy_lock_deleg_cb: new fl %p dp %p\n", new, dp);
+	if (!dp)
+		return;
+	dp->dl_flock = new;
+}
+
+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,
+};
+
+
 
 /*
  * nfsd4_process_open1()
@@ -1238,6 +1503,43 @@
 }
 
 static int
+nfs4_deleg_conflict(u32 share, u32 dtype)
+{
+	return (((share & NFS4_SHARE_ACCESS_WRITE) &&
+		dtype == NFS4_OPEN_DELEGATE_READ) ||
+		((share & NFS4_SHARE_ACCESS_READ) &&
+		dtype == NFS4_OPEN_DELEGATE_WRITE));
+}
+
+#define DONT_DELEGATE  8
+
+/*
+ * nfs4_check_deleg_recall()
+ *
+ * Test any delegation that is currently within an incompleted recalled
+ * state, and return NFSERR_DELAY for conflicting open share.
+ * flag is set to DONT_DELEGATE for shares that match the deleg type.
+ */
+static int
+nfs4_check_deleg_recall(struct nfs4_file *fp, struct nfsd4_open *op, int *flag)
+{
+	struct nfs4_delegation *dp;
+	int status = 0;
+
+	list_for_each_entry(dp, &fp->fi_del_perfile, dl_del_perfile) {
+		dprintk("NFSD: found delegation %p with dl_state %d\n",
+		 	                 dp, atomic_read(&dp->dl_state));
+		if (atomic_read(&dp->dl_state) == NFS4_RECALL_IN_PROGRESS) {
+			if(nfs4_deleg_conflict(op->op_share_access, dp->dl_type))
+				status = nfserr_jukebox;
+			else
+				*flag = DONT_DELEGATE;
+		}
+	}
+	return status;
+}
+
+static int
 nfs4_check_open(struct nfs4_file *fp, struct nfs4_stateowner *sop, struct nfsd4_open *open, struct nfs4_stateid **stpp)
 {
 	struct nfs4_stateid *local;
@@ -1339,6 +1641,65 @@
 }
 
 /*
+ * Attempt to hand out a delegation.
+ */
+static void
+nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_stateid *stp, int *flag)
+{
+	struct nfs4_delegation *dp;
+	struct nfs4_stateowner *sop = stp->st_stateowner;
+	struct nfs4_callback *cb = &sop->so_client->cl_callback;
+	struct file_lock fl, *flp = &fl;
+	int status;
+
+	if (*flag == DONT_DELEGATE) {
+		*flag = NFS4_OPEN_DELEGATE_NONE;
+		return;
+	}
+
+	/* set flag */
+	*flag = NFS4_OPEN_DELEGATE_NONE;
+	if (open->op_claim_type != NFS4_OPEN_CLAIM_NULL
+	     || !atomic_read(&cb->cb_set) || !sop->so_confirmed)
+		return;
+
+	if (!(open->op_share_access & NFS4_SHARE_ACCESS_WRITE))
+		*flag = NFS4_OPEN_DELEGATE_READ;
+
+	else if (!(open->op_share_access & NFS4_SHARE_ACCESS_READ))
+		*flag = NFS4_OPEN_DELEGATE_WRITE;
+
+	if (!(dp = alloc_init_deleg(sop->so_client, stp->st_file, fh, *flag)))
+		return;
+	locks_init_lock(&fl);
+	fl.fl_lmops = &nfsd_lease_mng_ops;
+	fl.fl_flags = FL_LEASE;
+	fl.fl_end = OFFSET_MAX;
+	fl.fl_owner =  (fl_owner_t)dp;
+	fl.fl_file = stp->st_vfs_file;
+	fl.fl_pid = current->tgid;
+
+	if ((status = setlease(stp->st_vfs_file,
+		*flag == NFS4_OPEN_DELEGATE_READ? F_RDLCK: F_WRLCK, &flp))) {
+		dprintk("NFSD: setlease failed [%d], no delegation\n", status);
+		list_del(&dp->dl_del_perfile);
+		list_del(&dp->dl_del_perclnt);
+		kfree(dp);
+		free_delegation++;
+		*flag = NFS4_OPEN_DELEGATE_NONE;
+		return;
+	}
+
+	memcpy(&open->op_delegate_stateid, &dp->dl_stateid, sizeof(dp->dl_stateid));
+
+	dprintk("NFSD: delegation stateid=(%08x/%08x/%08x/%08x)\n\n",
+	             dp->dl_stateid.si_boot,
+	             dp->dl_stateid.si_stateownerid,
+	             dp->dl_stateid.si_fileid,
+	             dp->dl_stateid.si_generation);
+}
+
+/*
  * called with nfs4_lock_state() held.
  */
 int
@@ -1346,28 +1707,24 @@
 {
 	struct nfs4_stateowner *sop = open->op_stateowner;
 	struct nfs4_file *fp = NULL;
-	struct inode *ino;
+	struct inode *ino = current_fh->fh_dentry->d_inode;
 	unsigned int fi_hashval;
 	struct nfs4_stateid *stp = NULL;
-	int status;
-
-	status = nfserr_resource;
-	if (!sop)
-		return status;
-
-	ino = current_fh->fh_dentry->d_inode;
+	int status, delegflag = 0;
 
 	status = nfserr_inval;
 	if (!TEST_ACCESS(open->op_share_access) || !TEST_DENY(open->op_share_deny))
 		goto out;
 	/*
-	 * Lookup file; if found, lookup stateid and check open request;
-	 * not found, create
+	 * Lookup file; if found, lookup stateid and check open request,
+	 * and check for delegations in the process of being recalled.
+	 * If not found, create the nfs4_file struct
 	 */
 	fi_hashval = file_hashval(ino);
 	if (find_file(fi_hashval, ino, &fp)) {
-		status = nfs4_check_open(fp, sop, open, &stp);
-		if (status)
+		if ((status = nfs4_check_open(fp, sop, open, &stp)))
+			goto out;
+		if ((status = nfs4_check_deleg_recall(fp, open, &delegflag)))
 			goto out;
 	} else {
 		status = nfserr_resource;
@@ -1407,14 +1764,20 @@
 			}
 		}
 	}
-	dprintk("nfs4_process_open2: stateid=(%08x/%08x/%08x/%08x)\n",
-	            stp->st_stateid.si_boot, stp->st_stateid.si_stateownerid,
-	            stp->st_stateid.si_fileid, stp->st_stateid.si_generation);
-
 	memcpy(&open->op_stateid, &stp->st_stateid, sizeof(stateid_t));
 
-	open->op_delegate_type = NFS4_OPEN_DELEGATE_NONE;
+	/*
+	* Attempt to hand out a delegation. No error return, because the
+	* OPEN succeeds even if we fail.
+	*/
+	nfs4_open_delegation(current_fh, open, stp, &delegflag);
+	open->op_delegate_type = delegflag;
+
 	status = nfs_ok;
+
+	dprintk("nfs4_process_open2: stateid=(%08x/%08x/%08x/%08x)\n",
+	            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))
@@ -1480,14 +1843,15 @@
 {
 	struct nfs4_client *clp;
 	struct nfs4_stateowner *sop;
+	struct nfs4_delegation *dp;
 	struct list_head *pos, *next;
 	time_t cutoff = get_seconds() - NFSD_LEASE_TIME;
 	time_t t, clientid_val = NFSD_LEASE_TIME;
-	time_t u, close_val = NFSD_LEASE_TIME;
+	time_t u, test_val = NFSD_LEASE_TIME;
 
 	nfs4_lock_state();
 
-	dprintk("NFSD: laundromat service - starting, examining clients\n");
+	dprintk("NFSD: laundromat service - starting\n");
 	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)) {
@@ -1500,12 +1864,30 @@
 			clp->cl_clientid.cl_id);
 		expire_client(clp);
 	}
+	spin_lock(&recall_lock);
+	list_for_each_safe(pos, next, &del_recall_lru) {
+		dp = list_entry (pos, struct nfs4_delegation, dl_recall_lru);
+		if (atomic_read(&dp->dl_state) == NFS4_RECALL_COMPLETE)
+			goto reap;
+		if (time_after((unsigned long)dp->dl_time, (unsigned long)cutoff)) {
+			u = dp->dl_time - cutoff;
+			if (test_val > u)
+				test_val = u;
+			break;
+		}
+reap:
+		dprintk("NFSD: purging unused delegation dp %p, fp %p\n",
+			            dp, dp->dl_flock);
+		release_delegation(dp);
+	}
+	spin_unlock(&recall_lock);
+	test_val = NFSD_LEASE_TIME;
 	list_for_each_safe(pos, next, &close_lru) {
 		sop = list_entry(pos, struct nfs4_stateowner, so_close_lru);
 		if (time_after((unsigned long)sop->so_time, (unsigned long)cutoff)) {
 			u = sop->so_time - cutoff;
-			if (close_val > u)
-				close_val = u;
+			if (test_val > u)
+				test_val = u;
 			break;
 		}
 		dprintk("NFSD: purging unused open stateowner (so_id %d)\n",
@@ -1564,22 +1946,63 @@
 	return 1;
 }
 
+static inline int
+access_permit_read(unsigned long access_bmap)
+{
+	return test_bit(NFS4_SHARE_ACCESS_READ, &access_bmap) ||
+		test_bit(NFS4_SHARE_ACCESS_BOTH, &access_bmap);
+}
+
+static inline int
+access_permit_write(unsigned long access_bmap)
+{
+	return test_bit(NFS4_SHARE_ACCESS_WRITE, &access_bmap) ||
+		test_bit(NFS4_SHARE_ACCESS_BOTH, &access_bmap);
+}
+
+static
+int nfs4_check_openmode(struct nfs4_stateid *stp, int flags)
+{
+        int status = nfserr_openmode;
+
+	if ((flags & WR_STATE) && (!access_permit_write(stp->st_access_bmap)))
+                goto out;
+	if ((flags & RD_STATE) && (!access_permit_read(stp->st_access_bmap)))
+                goto out;
+	status = nfs_ok;
+out:
+	return status;
+}
+
+static int
+nfs4_check_delegmode(struct nfs4_delegation *dp, int flags)
+{
+	int status = nfserr_openmode;
+
+	if ((flags & WR_STATE) & (dp->dl_type == NFS4_OPEN_DELEGATE_READ))
+		goto out;
+	if ((flags & RD_STATE) & (dp->dl_type == NFS4_OPEN_DELEGATE_WRITE))
+		goto out;
+	status = nfs_ok;
+out:
+	return status;
+}
 
 /*
 * Checks for stateid operations
 */
 int
-nfs4_preprocess_stateid_op(struct svc_fh *current_fh, stateid_t *stateid, int flags, struct nfs4_stateid **stpp)
+nfs4_preprocess_stateid_op(struct svc_fh *current_fh, stateid_t *stateid, int flags)
 {
-	struct nfs4_stateid *stp;
+	struct nfs4_stateid *stp = NULL;
+	struct nfs4_delegation *dp = NULL;
+	stateid_t *stidp;
 	int status;
 
 	dprintk("NFSD: preprocess_stateid_op: stateid = (%08x/%08x/%08x/%08x)\n",
 		stateid->si_boot, stateid->si_stateownerid, 
 		stateid->si_fileid, stateid->si_generation); 
 
-	*stpp = NULL;
-
 	/* STALE STATEID */
 	status = nfserr_stale_stateid;
 	if (STALE_STATEID(stateid)) 
@@ -1587,33 +2010,48 @@
 
 	/* BAD STATEID */
 	status = nfserr_bad_stateid;
-	if (!(stp = find_stateid(stateid, flags))) {
-		dprintk("NFSD: preprocess_stateid_op: no open stateid!\n");
-		goto out;
-	}
-	if ((flags & CHECK_FH) && nfs4_check_fh(current_fh, stp)) {
-		dprintk("NFSD: preprocess_stateid_op: fh-stateid mismatch!\n");
-		stp->st_vfs_set = 0;
-		goto out;
-	}
-	if (!stp->st_stateowner->so_confirmed) {
-		dprintk("preprocess_stateid_op: lockowner not confirmed yet!\n");
-		goto out;
+	if (!stateid->si_fileid) { /* delegation stateid */
+		struct inode *ino = current_fh->fh_dentry->d_inode;
+
+		if(!(dp = find_delegation_stateid(ino, stateid))) {
+			dprintk("NFSD: delegation stateid not found\n");
+			goto out;
+		}
+		stidp = &dp->dl_stateid;
+	} else { /* open or lock stateid */
+		if (!(stp = find_stateid(stateid, flags))) {
+			dprintk("NFSD: open or lock stateid not found\n");
+			goto out;
+		}
+		if ((flags & CHECK_FH) && nfs4_check_fh(current_fh, stp))
+			goto out;
+		if (!stp->st_stateowner->so_confirmed)
+			goto out;
+		stidp = &stp->st_stateid;
 	}
-	if (stateid->si_generation > stp->st_stateid.si_generation) {
-		dprintk("preprocess_stateid_op: future stateid?!\n");
+	if (stateid->si_generation > stidp->si_generation)
 		goto out;
-	}
 
 	/* OLD STATEID */
 	status = nfserr_old_stateid;
-	if (stateid->si_generation < stp->st_stateid.si_generation) {
-		dprintk("preprocess_stateid_op: old stateid!\n");
+	if (stateid->si_generation < stidp->si_generation)
 		goto out;
+	if (stp) {
+		if ((status = nfs4_check_openmode(stp,flags)))
+			goto out;
+		renew_client(stp->st_stateowner->so_client);
+	} else if (dp) {
+		if ((status = nfs4_check_delegmode(dp, flags)))
+			goto out;
+		renew_client(dp->dl_client);
+		if (flags & DELEG_RET) {
+			atomic_set(&dp->dl_state,NFS4_RECALL_COMPLETE);
+			spin_lock(&recall_lock);
+			release_delegation(dp);
+			spin_unlock(&recall_lock);
+		}
 	}
-	*stpp = stp;
 	status = nfs_ok;
-	renew_client(stp->st_stateowner->so_client);
 out:
 	return status;
 }
@@ -1912,6 +2350,22 @@
 	return status;
 }
 
+int
+nfsd4_delegreturn(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_delegreturn *dr)
+{
+	int status;
+
+	if ((status = fh_verify(rqstp, current_fh, S_IFREG, 0)))
+		goto out;
+
+	nfs4_lock_state();
+	status = nfs4_preprocess_stateid_op(current_fh, &dr->dr_stateid, DELEG_RET);
+	nfs4_unlock_state();
+out:
+	return status;
+}
+
+
 /* 
  * Lock owner state (byte-range locks)
  */
@@ -1938,7 +2392,7 @@
 	unsigned int hashval;
 
 	dprintk("NFSD: find_stateid flags 0x%x\n",flags);
-	if ((flags & LOCK_STATE) || (flags & RDWR_STATE)) {
+	if ((flags & LOCK_STATE) || (flags & RD_STATE) || (flags & WR_STATE)) {
 		hashval = stateid_hashval(st_id, f_id);
 		list_for_each_entry(local, &lockstateid_hashtbl[hashval], st_hash) {
 			if ((local->st_stateid.si_stateownerid == st_id) &&
@@ -1946,7 +2400,7 @@
 				return local;
 		}
 	} 
-	if ((flags & OPEN_STATE) || (flags & RDWR_STATE)) {
+	if ((flags & OPEN_STATE) || (flags & RD_STATE) || (flags & WR_STATE)) {
 		hashval = stateid_hashval(st_id, f_id);
 		list_for_each_entry(local, &stateid_hashtbl[hashval], st_hash) {
 			if ((local->st_stateid.si_stateownerid == st_id) &&
@@ -1958,6 +2412,32 @@
 	return NULL;
 }
 
+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;
+	unsigned int fi_hashval;
+
+	dprintk("NFSD:find_delegation_stateid stateid=(%08x/%08x/%08x/%08x)\n",
+                    stid->si_boot, stid->si_stateownerid,
+                    stid->si_fileid, stid->si_generation);
+
+	if(!ino || !stid)
+		return NULL;
+	st_id = stid->si_stateownerid;
+	fi_hashval = file_hashval(ino);
+	if (find_file(fi_hashval, ino, &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;
+}
 
 /*
  * TODO: Linux file offsets are _signed_ 64-bit quantities, which means that
@@ -2689,6 +3169,8 @@
 
 	INIT_LIST_HEAD(&close_lru);
 	INIT_LIST_HEAD(&client_lru);
+	INIT_LIST_HEAD(&del_recall_lru);
+	spin_lock_init(&recall_lock);
 	boot_time = get_seconds();
 	grace_time = max(old_lease_time, lease_time);
 	if (reclaim_str_hashtbl_size == 0)
@@ -2725,6 +3207,8 @@
 {
 	int i;
 	struct nfs4_client *clp = NULL;
+	struct nfs4_delegation *dp = NULL;
+	struct list_head *pos, *next;
 
 	for (i = 0; i < CLIENT_HASH_SIZE; i++) {
 		while (!list_empty(&conf_id_hashtbl[i])) {
@@ -2736,6 +3220,14 @@
 			expire_client(clp);
 		}
 	}
+	spin_lock(&recall_lock);
+	list_for_each_safe(pos, next, &del_recall_lru) {
+		dp = list_entry (pos, struct nfs4_delegation, dl_recall_lru);
+		atomic_set(&dp->dl_state, NFS4_RECALL_COMPLETE);
+		release_delegation(dp);
+	}
+	spin_unlock(&recall_lock);
+
 	release_all_files();
 	cancel_delayed_work(&laundromat_work);
 	flush_scheduled_work();
@@ -2750,6 +3242,9 @@
 			alloc_sowner, alloc_lsowner, free_sowner);
 	dprintk("NFSD: vfsopen %d vfsclose %d\n",
 			vfsopen, vfsclose);
+	dprintk("NFSD: alloc_delegation %d free_delegation %d\n",
+			alloc_delegation, free_delegation);
+
 }
 
 void
diff -Nru a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
--- a/fs/nfsd/nfs4xdr.c	2005-03-01 23:39:09 -08:00
+++ b/fs/nfsd/nfs4xdr.c	2005-03-01 23:39:09 -08:00
@@ -615,6 +615,18 @@
 }
 
 static inline int
+nfsd4_decode_delegreturn(struct nfsd4_compoundargs *argp, struct nfsd4_delegreturn *dr)
+{
+	DECODE_HEAD;
+
+	READ_BUF(sizeof(stateid_t));
+	READ32(dr->dr_stateid.si_generation);
+	COPYMEM(&dr->dr_stateid.si_opaque, sizeof(stateid_opaque_t));
+
+	DECODE_TAIL;
+}
+
+static inline int
 nfsd4_decode_getattr(struct nfsd4_compoundargs *argp, struct nfsd4_getattr *getattr)
 {
 	return nfsd4_decode_bitmap(argp, getattr->ga_bmval);
@@ -790,8 +802,8 @@
 		READ32(open->op_delegate_type);
 		break;
 	case NFS4_OPEN_CLAIM_DELEGATE_CUR:
-		READ_BUF(sizeof(delegation_stateid_t) + 4);
-		COPYMEM(&open->op_delegate_stateid, sizeof(delegation_stateid_t));
+		READ_BUF(sizeof(stateid_t) + 4);
+		COPYMEM(&open->op_delegate_stateid, sizeof(stateid_t));
 		READ32(open->op_fname.len);
 		READ_BUF(open->op_fname.len);
 		SAVEMEM(open->op_fname.data, open->op_fname.len);
@@ -825,7 +837,7 @@
 	DECODE_HEAD;
 		    
 	open_down->od_stateowner = NULL;
-	READ_BUF(4 + sizeof(stateid_t));
+	READ_BUF(12 + sizeof(stateid_t));
 	READ32(open_down->od_stateid.si_generation);
 	COPYMEM(&open_down->od_stateid.si_opaque, sizeof(stateid_opaque_t));
 	READ32(open_down->od_seqid);
@@ -1170,6 +1182,9 @@
 		case OP_CREATE:
 			op->status = nfsd4_decode_create(argp, &op->u.create);
 			break;
+		case OP_DELEGRETURN:
+			op->status = nfsd4_decode_delegreturn(argp, &op->u.delegreturn);
+			break;
 		case OP_GETATTR:
 			op->status = nfsd4_decode_getattr(argp, &op->u.getattr);
 			break;
@@ -1425,7 +1440,7 @@
 		if (status)
 			goto out_nfserr;
 	}
-	if ((bmval0 & FATTR4_WORD0_FILEHANDLE) && !fhp) {
+	if ((bmval0 & (FATTR4_WORD0_FILEHANDLE | FATTR4_WORD0_FSID)) && !fhp) {
 		fh_init(&tempfh, NFS4_FHSIZE);
 		status = fh_compose(&tempfh, exp, dentry, NULL);
 		if (status)
@@ -1508,10 +1523,15 @@
 	if (bmval0 & FATTR4_WORD0_FSID) {
 		if ((buflen -= 16) < 0)
 			goto out_resource;
-		WRITE32(0);
-		WRITE32(MAJOR(stat.dev));
-		WRITE32(0);
-		WRITE32(MINOR(stat.dev));
+		if (is_fsid(fhp, rqstp->rq_reffh)) {
+			WRITE64((u64)exp->ex_fsid);
+			WRITE64((u64)0);
+		} else {
+			WRITE32(0);
+			WRITE32(MAJOR(stat.dev));
+			WRITE32(0);
+			WRITE32(MINOR(stat.dev));
+		}
 	}
 	if (bmval0 & FATTR4_WORD0_UNIQUE_HANDLES) {
 		if ((buflen -= 4) < 0)
@@ -1765,17 +1785,65 @@
 }
 
 static int
+nfsd4_encode_dirent_fattr(struct nfsd4_readdir *cd,
+		const char *name, int namlen, u32 *p, int *buflen)
+{
+	struct svc_export *exp = cd->rd_fhp->fh_export;
+	struct dentry *dentry;
+	int nfserr;
+
+	dentry = lookup_one_len(name, cd->rd_fhp->fh_dentry, namlen);
+	if (IS_ERR(dentry))
+		return nfserrno(PTR_ERR(dentry));
+
+	exp_get(exp);
+	if (d_mountpoint(dentry)) {
+		if (nfsd_cross_mnt(cd->rd_rqstp, &dentry, &exp)) {
+		/*
+		 * -EAGAIN is the only error returned from
+		 * nfsd_cross_mnt() and it indicates that an
+		 * up-call has  been initiated to fill in the export
+		 * options on exp.  When the answer comes back,
+		 * this call will be retried.
+		 */
+			nfserr = nfserr_dropit;
+			goto out_put;
+		}
+
+	}
+	nfserr = nfsd4_encode_fattr(NULL, exp, dentry, p, buflen, cd->rd_bmval,
+					cd->rd_rqstp);
+out_put:
+	dput(dentry);
+	exp_put(exp);
+	return nfserr;
+}
+
+static u32 *
+nfsd4_encode_rdattr_error(u32 *p, int buflen, int nfserr)
+{
+	u32 *attrlenp;
+
+	if (buflen < 6)
+		return NULL;
+	*p++ = htonl(2);
+	*p++ = htonl(FATTR4_WORD0_RDATTR_ERROR); /* bmval0 */
+	*p++ = htonl(0);			 /* bmval1 */
+
+	attrlenp = p++;
+	*p++ = nfserr;       /* no htonl */
+	*attrlenp = htonl((char *)p - (char *)attrlenp - 4);
+	return p;
+}
+
+static int
 nfsd4_encode_dirent(struct readdir_cd *ccd, const char *name, int namlen,
 		    loff_t offset, ino_t ino, unsigned int d_type)
 {
 	struct nfsd4_readdir *cd = container_of(ccd, struct nfsd4_readdir, common);
 	int buflen;
 	u32 *p = cd->buffer;
-	u32 *attrlenp;
-	struct dentry *dentry;
-	struct svc_export *exp = cd->rd_fhp->fh_export;
-	u32 bmval0, bmval1;
-	int nfserr = 0;
+	int nfserr = nfserr_toosmall;
 
 	/* In nfsv4, "." and ".." never make it onto the wire.. */
 	if (name && isdotent(name, namlen)) {
@@ -1788,106 +1856,44 @@
 
 	buflen = cd->buflen - 4 - XDR_QUADLEN(namlen);
 	if (buflen < 0)
-		goto nospc;
+		goto fail;
 
 	*p++ = xdr_one;                             /* mark entry present */
 	cd->offset = p;                             /* remember pointer */
 	p = xdr_encode_hyper(p, NFS_OFFSET_MAX);    /* offset of next entry */
 	p = xdr_encode_array(p, name, namlen);      /* name length & name */
 
-	/*
-	 * Now we come to the ugly part: writing the fattr for this entry.
-	 */
-	bmval0 = cd->rd_bmval[0];
-	bmval1 = cd->rd_bmval[1];
-	if ((bmval0 & ~(FATTR4_WORD0_RDATTR_ERROR | FATTR4_WORD0_FILEID)) || bmval1)  {
-		/*
-		 * "Heavyweight" case: we have no choice except to
-		 * call nfsd4_encode_fattr(). 
-		 */
-		dentry = lookup_one_len(name, cd->rd_fhp->fh_dentry, namlen);
-		if (IS_ERR(dentry)) {
-			nfserr = nfserrno(PTR_ERR(dentry));
-			goto error;
-		}
-
-		exp_get(exp);
-		if (d_mountpoint(dentry)) {
-			if ((nfserr = nfsd_cross_mnt(cd->rd_rqstp, &dentry, 
-					 &exp))) {	
-			/* 
-			 * -EAGAIN is the only error returned from 
-			 * nfsd_cross_mnt() and it indicates that an 
-			 * up-call has  been initiated to fill in the export 
-			 * options on exp.  When the answer comes back,
-			 * this call will be retried.
-			 */
-				dput(dentry);
-				exp_put(exp);
-				nfserr = nfserr_dropit;
-				goto error;
-			}
-
-		}
-
-		nfserr = nfsd4_encode_fattr(NULL, exp,
-				dentry, p, &buflen, cd->rd_bmval,
-				cd->rd_rqstp);
-		dput(dentry);
-		exp_put(exp);
-		if (!nfserr) {
-			p += buflen;
-			goto out;
-		}
-		if (nfserr == nfserr_resource)
-			goto nospc;
-
-error:
+	nfserr = nfsd4_encode_dirent_fattr(cd, name, namlen, p, &buflen);
+	switch (nfserr) {
+	case nfs_ok:
+		p += buflen;
+		break;
+	case nfserr_resource:
+		nfserr = nfserr_toosmall;
+		goto fail;
+	case nfserr_dropit:
+		goto fail;
+	default:
 		/*
-		 * If we get here, we experienced a miscellaneous
-		 * failure while writing the attributes.  If the
-		 * client requested the RDATTR_ERROR attribute,
+		 * If the client requested the RDATTR_ERROR attribute,
 		 * we stuff the error code into this attribute
 		 * and continue.  If this attribute was not requested,
 		 * then in accordance with the spec, we fail the
 		 * entire READDIR operation(!)
 		 */
-		if (!(bmval0 & FATTR4_WORD0_RDATTR_ERROR)) {
-			cd->common.err = nfserr;
-			return -EINVAL;
-		}
-
-		bmval0 = FATTR4_WORD0_RDATTR_ERROR;
-		bmval1 = 0;
-		/* falling through here will do the right thing... */
+		if (!(cd->rd_bmval[0] & FATTR4_WORD0_RDATTR_ERROR))
+			goto fail;
+		nfserr = nfserr_toosmall;
+		p = nfsd4_encode_rdattr_error(p, buflen, nfserr);
+		if (p == NULL)
+			goto fail;
 	}
-
-	/*
-	 * In the common "lightweight" case, we avoid
-	 * the overhead of nfsd4_encode_fattr() by assembling
-	 * a small fattr by hand.
-	 */
-	if (buflen < 6)
-		goto nospc;
-	*p++ = htonl(2);
-	*p++ = htonl(bmval0);
-	*p++ = htonl(bmval1);
-
-	attrlenp = p++;
-	if (bmval0 & FATTR4_WORD0_RDATTR_ERROR)
-		*p++ = nfserr;       /* no htonl */
-	if (bmval0 & FATTR4_WORD0_FILEID)
-		p = xdr_encode_hyper(p, (u64)ino);
-	*attrlenp = htonl((char *)p - (char *)attrlenp - 4);
-
-out:
 	cd->buflen -= (p - cd->buffer);
 	cd->buffer = p;
 	cd->common.err = nfs_ok;
 	return 0;
-
-nospc:
-	cd->common.err = nfserr_toosmall;
+fail:
+	cd->common.err = nfserr;
 	return -EINVAL;
 }
 
@@ -2081,8 +2087,8 @@
 	case NFS4_OPEN_DELEGATE_NONE:
 		break;
 	case NFS4_OPEN_DELEGATE_READ:
-		RESERVE_SPACE(20 + sizeof(delegation_stateid_t));
-		WRITEMEM(&open->op_delegate_stateid, sizeof(delegation_stateid_t));
+		RESERVE_SPACE(20 + sizeof(stateid_t));
+		WRITEMEM(&open->op_delegate_stateid, sizeof(stateid_t));
 		WRITE32(0);
 
 		/*
@@ -2095,8 +2101,8 @@
 		ADJUST_ARGS();
 		break;
 	case NFS4_OPEN_DELEGATE_WRITE:
-		RESERVE_SPACE(32 + sizeof(delegation_stateid_t));
-		WRITEMEM(&open->op_delegate_stateid, sizeof(delegation_stateid_t));
+		RESERVE_SPACE(32 + sizeof(stateid_t));
+		WRITEMEM(&open->op_delegate_stateid, sizeof(stateid_t));
 		WRITE32(0);
 
 		/*
@@ -2459,6 +2465,8 @@
 		break;
 	case OP_CREATE:
 		nfsd4_encode_create(resp, op->status, &op->u.create);
+		break;
+	case OP_DELEGRETURN:
 		break;
 	case OP_GETATTR:
 		op->status = nfsd4_encode_getattr(resp, op->status, &op->u.getattr);
diff -Nru a/fs/nfsd/nfscache.c b/fs/nfsd/nfscache.c
--- a/fs/nfsd/nfscache.c	2005-03-01 23:39:17 -08:00
+++ b/fs/nfsd/nfscache.c	2005-03-01 23:39:17 -08:00
@@ -48,7 +48,7 @@
  * A cache entry is "single use" if c_state == RC_INPROG
  * Otherwise, it when accessing _prev or _next, the lock must be held.
  */
-static spinlock_t cache_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(cache_lock);
 
 void
 nfsd_cache_init(void)
diff -Nru a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c
--- a/fs/nfsd/nfsproc.c	2005-03-01 23:38:55 -08:00
+++ b/fs/nfsd/nfsproc.c	2005-03-01 23:38:55 -08:00
@@ -540,7 +540,7 @@
   PROC(symlink,	 symlinkargs,	void,		none,		RC_REPLSTAT, ST),
   PROC(mkdir,	 createargs,	diropres,	fhandle,	RC_REPLBUFF, ST+FH+AT),
   PROC(rmdir,	 diropargs,	void,		none,		RC_REPLSTAT, ST),
-  PROC(readdir,	 readdirargs,	readdirres,	none,		RC_REPLBUFF, 0),
+  PROC(readdir,	 readdirargs,	readdirres,	none,		RC_NOCACHE, 0),
   PROC(statfs,	 fhandle,	statfsres,	none,		RC_NOCACHE, ST+5),
 };
 
@@ -586,7 +586,6 @@
 		{ nfserr_dquot, -EDQUOT },
 #endif
 		{ nfserr_stale, -ESTALE },
-		{ nfserr_jukebox, -EWOULDBLOCK },
 		{ nfserr_jukebox, -ETIMEDOUT },
 		{ nfserr_dropit, -EAGAIN },
 		{ nfserr_dropit, -ENOMEM },
diff -Nru a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
--- a/fs/nfsd/nfssvc.c	2005-03-01 23:38:58 -08:00
+++ b/fs/nfsd/nfssvc.c	2005-03-01 23:38:58 -08:00
@@ -54,7 +54,7 @@
 static struct svc_serv 		*nfsd_serv;
 static atomic_t			nfsd_busy;
 static unsigned long		nfsd_last_call;
-static spinlock_t		nfsd_call_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(nfsd_call_lock);
 
 struct nfsd_list {
 	struct list_head 	list;
diff -Nru a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
--- a/fs/nfsd/vfs.c	2005-03-01 23:38:55 -08:00
+++ b/fs/nfsd/vfs.c	2005-03-01 23:38:55 -08:00
@@ -304,6 +304,8 @@
 		 * we need to break all leases.
 		 */
 		err = break_lease(inode, FMODE_WRITE | O_NONBLOCK);
+		if (err == -EWOULDBLOCK)
+			err = -ETIMEDOUT;
 		if (err) /* ENOMEM or EWOULDBLOCK */
 			goto out_nfserr;
 
@@ -654,12 +656,15 @@
 	dentry = fhp->fh_dentry;
 	inode = dentry->d_inode;
 
-	/* Disallow access to files with the append-only bit set or
-	 * with mandatory locking enabled
+	/* Disallow write access to files with the append-only bit set
+	 * or any access when mandatory locking enabled
 	 */
 	err = nfserr_perm;
-	if (IS_APPEND(inode) || IS_ISMNDLK(inode))
+	if (IS_APPEND(inode) && (access & MAY_WRITE))
 		goto out;
+	if (IS_ISMNDLK(inode))
+		goto out;
+
 	if (!inode->i_fop)
 		goto out;
 
@@ -668,6 +673,8 @@
 	 * This may block while leases are broken.
 	 */
 	err = break_lease(inode, O_NONBLOCK | ((access & MAY_WRITE) ? FMODE_WRITE : 0));
+	if (err == -EWOULDBLOCK)
+		err = -ETIMEDOUT;
 	if (err) /* NOMEM or WOULDBLOCK */
 		goto out_nfserr;
 
@@ -733,7 +740,7 @@
  * Obtain the readahead parameters for the file
  * specified by (dev, ino).
  */
-static spinlock_t ra_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(ra_lock);
 
 static inline struct raparms *
 nfsd_get_raparms(dev_t dev, ino_t ino)
diff -Nru a/fs/nls/nls_ascii.c b/fs/nls/nls_ascii.c
--- a/fs/nls/nls_ascii.c	2005-03-01 23:38:52 -08:00
+++ b/fs/nls/nls_ascii.c	2005-03-01 23:38:52 -08:00
@@ -13,7 +13,7 @@
 #include <linux/nls.h>
 #include <linux/errno.h>
 
-static wchar_t charset2uni[128] = {
+static wchar_t charset2uni[256] = {
 	/* 0x00*/
 	0x0000, 0x0001, 0x0002, 0x0003,
 	0x0004, 0x0005, 0x0006, 0x0007,
@@ -56,7 +56,7 @@
 	0x007c, 0x007d, 0x007e, 0x007f,
 };
 
-static unsigned char page00[128] = {
+static unsigned char page00[256] = {
 	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
 	0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
 	0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -75,11 +75,11 @@
 	0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */
 };
 
-static unsigned char *page_uni2charset[128] = {
-	page00, NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,
+static unsigned char *page_uni2charset[256] = {
+	page00,
 };
 
-static unsigned char charset2lower[128] = {
+static unsigned char charset2lower[256] = {
 	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
 	0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
 	0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -98,7 +98,7 @@
 	0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */
 };
 
-static unsigned char charset2upper[128] = {
+static unsigned char charset2upper[256] = {
 	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
 	0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
 	0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
diff -Nru a/fs/nls/nls_base.c b/fs/nls/nls_base.c
--- a/fs/nls/nls_base.c	2005-03-01 23:39:07 -08:00
+++ b/fs/nls/nls_base.c	2005-03-01 23:39:07 -08:00
@@ -21,7 +21,7 @@
 
 static struct nls_table default_table;
 static struct nls_table *tables = &default_table;
-static spinlock_t nls_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(nls_lock);
 
 /*
  * Sample implementation from Unicode home page.
diff -Nru a/fs/nls/nls_cp932.c b/fs/nls/nls_cp932.c
--- a/fs/nls/nls_cp932.c	2005-03-01 23:38:54 -08:00
+++ b/fs/nls/nls_cp932.c	2005-03-01 23:38:54 -08:00
@@ -30,7 +30,7 @@
 	0x201D,0xFF08,0xFF09,0x3014,0x3015,0xFF3B,0xFF3D,0xFF5B,/* 0x68-0x6F */
 	0xFF5D,0x3008,0x3009,0x300A,0x300B,0x300C,0x300D,0x300E,/* 0x70-0x77 */
 	0x300F,0x3010,0x3011,0xFF0B,0xFF0D,0x00B1,0x00D7,0x0000,/* 0x78-0x7F */
-	
+
 	0x00F7,0xFF1D,0x2260,0xFF1C,0xFF1E,0x2266,0x2267,0x221E,/* 0x80-0x87 */
 	0x2234,0x2642,0x2640,0x00B0,0x2032,0x2033,0x2103,0xFFE5,/* 0x88-0x8F */
 	0xFF04,0xFFE0,0xFFE1,0xFF05,0xFF03,0xFF06,0xFF0A,0xFF20,/* 0x90-0x97 */
@@ -66,7 +66,7 @@
 	0xFF29,0xFF2A,0xFF2B,0xFF2C,0xFF2D,0xFF2E,0xFF2F,0xFF30,/* 0x68-0x6F */
 	0xFF31,0xFF32,0xFF33,0xFF34,0xFF35,0xFF36,0xFF37,0xFF38,/* 0x70-0x77 */
 	0xFF39,0xFF3A,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xFF41,0xFF42,0xFF43,0xFF44,0xFF45,0xFF46,0xFF47,/* 0x80-0x87 */
 	0xFF48,0xFF49,0xFF4A,0xFF4B,0xFF4C,0xFF4D,0xFF4E,0xFF4F,/* 0x88-0x8F */
 	0xFF50,0xFF51,0xFF52,0xFF53,0xFF54,0xFF55,0xFF56,0xFF57,/* 0x90-0x97 */
@@ -101,7 +101,7 @@
 	0x30C9,0x30CA,0x30CB,0x30CC,0x30CD,0x30CE,0x30CF,0x30D0,/* 0x68-0x6F */
 	0x30D1,0x30D2,0x30D3,0x30D4,0x30D5,0x30D6,0x30D7,0x30D8,/* 0x70-0x77 */
 	0x30D9,0x30DA,0x30DB,0x30DC,0x30DD,0x30DE,0x30DF,0x0000,/* 0x78-0x7F */
-	
+
 	0x30E0,0x30E1,0x30E2,0x30E3,0x30E4,0x30E5,0x30E6,0x30E7,/* 0x80-0x87 */
 	0x30E8,0x30E9,0x30EA,0x30EB,0x30EC,0x30ED,0x30EE,0x30EF,/* 0x88-0x8F */
 	0x30F0,0x30F1,0x30F2,0x30F3,0x30F4,0x30F5,0x30F6,0x0000,/* 0x90-0x97 */
@@ -132,7 +132,7 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x68-0x6F */
 	0x0430,0x0431,0x0432,0x0433,0x0434,0x0435,0x0451,0x0436,/* 0x70-0x77 */
 	0x0437,0x0438,0x0439,0x043A,0x043B,0x043C,0x043D,0x0000,/* 0x78-0x7F */
-	
+
 	0x043E,0x043F,0x0440,0x0441,0x0442,0x0443,0x0444,0x0445,/* 0x80-0x87 */
 	0x0446,0x0447,0x0448,0x0449,0x044A,0x044B,0x044C,0x044D,/* 0x88-0x8F */
 	0x044E,0x044F,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -160,7 +160,7 @@
 	0x3357,0x330D,0x3326,0x3323,0x332B,0x334A,0x333B,0x339C,/* 0x68-0x6F */
 	0x339D,0x339E,0x338E,0x338F,0x33C4,0x33A1,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x337B,0x0000,/* 0x78-0x7F */
-	
+
 	0x301D,0x301F,0x2116,0x33CD,0x2121,0x32A4,0x32A5,0x32A6,/* 0x80-0x87 */
 	0x32A7,0x32A8,0x3231,0x3232,0x3239,0x337E,0x337D,0x337C,/* 0x88-0x8F */
 	0x2252,0x2261,0x222B,0x222E,0x2211,0x221A,0x22A5,0x2220,/* 0x90-0x97 */
@@ -184,7 +184,7 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x68-0x6F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -220,7 +220,7 @@
 	0x6804,0x6C38,0x6CF3,0x6D29,0x745B,0x76C8,0x7A4E,0x9834,/* 0x68-0x6F */
 	0x82F1,0x885B,0x8A60,0x92ED,0x6DB2,0x75AB,0x76CA,0x99C5,/* 0x70-0x77 */
 	0x60A6,0x8B01,0x8D8A,0x95B2,0x698E,0x53AD,0x5186,0x0000,/* 0x78-0x7F */
-	
+
 	0x5712,0x5830,0x5944,0x5BB4,0x5EF6,0x6028,0x63A9,0x63F4,/* 0x80-0x87 */
 	0x6CBF,0x6F14,0x708E,0x7114,0x7159,0x71D5,0x733F,0x7E01,/* 0x88-0x8F */
 	0x8276,0x82D1,0x8597,0x9060,0x925B,0x9D1B,0x5869,0x65BC,/* 0x90-0x97 */
@@ -256,7 +256,7 @@
 	0x64B9,0x683C,0x6838,0x6BBB,0x7372,0x78BA,0x7A6B,0x899A,/* 0x68-0x6F */
 	0x89D2,0x8D6B,0x8F03,0x90ED,0x95A3,0x9694,0x9769,0x5B66,/* 0x70-0x77 */
 	0x5CB3,0x697D,0x984D,0x984E,0x639B,0x7B20,0x6A2B,0x0000,/* 0x78-0x7F */
-	
+
 	0x6A7F,0x68B6,0x9C0D,0x6F5F,0x5272,0x559D,0x6070,0x62EC,/* 0x80-0x87 */
 	0x6D3B,0x6E07,0x6ED1,0x845B,0x8910,0x8F44,0x4E14,0x9C39,/* 0x88-0x8F */
 	0x53F6,0x691B,0x6A3A,0x9784,0x682A,0x515C,0x7AC3,0x84B2,/* 0x90-0x97 */
@@ -292,7 +292,7 @@
 	0x5403,0x55AB,0x6854,0x6A58,0x8A70,0x7827,0x6775,0x9ECD,/* 0x68-0x6F */
 	0x5374,0x5BA2,0x811A,0x8650,0x9006,0x4E18,0x4E45,0x4EC7,/* 0x70-0x77 */
 	0x4F11,0x53CA,0x5438,0x5BAE,0x5F13,0x6025,0x6551,0x0000,/* 0x78-0x7F */
-	
+
 	0x673D,0x6C42,0x6C72,0x6CE3,0x7078,0x7403,0x7A76,0x7AAE,/* 0x80-0x87 */
 	0x7B08,0x7D1A,0x7CFE,0x7D66,0x65E7,0x725B,0x53BB,0x5C45,/* 0x88-0x8F */
 	0x5DE8,0x62D2,0x62E0,0x6319,0x6E20,0x865A,0x8A31,0x8DDD,/* 0x90-0x97 */
@@ -328,7 +328,7 @@
 	0x656C,0x666F,0x6842,0x6E13,0x7566,0x7A3D,0x7CFB,0x7D4C,/* 0x68-0x6F */
 	0x7D99,0x7E4B,0x7F6B,0x830E,0x834A,0x86CD,0x8A08,0x8A63,/* 0x70-0x77 */
 	0x8B66,0x8EFD,0x981A,0x9D8F,0x82B8,0x8FCE,0x9BE8,0x0000,/* 0x78-0x7F */
-	
+
 	0x5287,0x621F,0x6483,0x6FC0,0x9699,0x6841,0x5091,0x6B20,/* 0x80-0x87 */
 	0x6C7A,0x6F54,0x7A74,0x7D50,0x8840,0x8A23,0x6708,0x4EF6,/* 0x88-0x8F */
 	0x5039,0x5026,0x5065,0x517C,0x5238,0x5263,0x55A7,0x570F,/* 0x90-0x97 */
@@ -364,7 +364,7 @@
 	0x7D18,0x7D5E,0x7DB1,0x8015,0x8003,0x80AF,0x80B1,0x8154,/* 0x68-0x6F */
 	0x818F,0x822A,0x8352,0x884C,0x8861,0x8B1B,0x8CA2,0x8CFC,/* 0x70-0x77 */
 	0x90CA,0x9175,0x9271,0x783F,0x92FC,0x95A4,0x964D,0x0000,/* 0x78-0x7F */
-	
+
 	0x9805,0x9999,0x9AD8,0x9D3B,0x525B,0x52AB,0x53F7,0x5408,/* 0x80-0x87 */
 	0x58D5,0x62F7,0x6FE0,0x8C6A,0x8F5F,0x9EB9,0x514B,0x523B,/* 0x88-0x8F */
 	0x544A,0x56FD,0x7A40,0x9177,0x9D60,0x9ED2,0x7344,0x6F09,/* 0x90-0x97 */
@@ -400,7 +400,7 @@
 	0x523A,0x53F8,0x53F2,0x55E3,0x56DB,0x58EB,0x59CB,0x59C9,/* 0x68-0x6F */
 	0x59FF,0x5B50,0x5C4D,0x5E02,0x5E2B,0x5FD7,0x601D,0x6307,/* 0x70-0x77 */
 	0x652F,0x5B5C,0x65AF,0x65BD,0x65E8,0x679D,0x6B62,0x0000,/* 0x78-0x7F */
-	
+
 	0x6B7B,0x6C0F,0x7345,0x7949,0x79C1,0x7CF8,0x7D19,0x7D2B,/* 0x80-0x87 */
 	0x80A2,0x8102,0x81F3,0x8996,0x8A5E,0x8A69,0x8A66,0x8A8C,/* 0x88-0x8F */
 	0x8AEE,0x8CC7,0x8CDC,0x96CC,0x98FC,0x6B6F,0x4E8B,0x4F3C,/* 0x90-0x97 */
@@ -436,7 +436,7 @@
 	0x5BBF,0x6DD1,0x795D,0x7E2E,0x7C9B,0x587E,0x719F,0x51FA,/* 0x68-0x6F */
 	0x8853,0x8FF0,0x4FCA,0x5CFB,0x6625,0x77AC,0x7AE3,0x821C,/* 0x70-0x77 */
 	0x99FF,0x51C6,0x5FAA,0x65EC,0x696F,0x6B89,0x6DF3,0x0000,/* 0x78-0x7F */
-	
+
 	0x6E96,0x6F64,0x76FE,0x7D14,0x5DE1,0x9075,0x9187,0x9806,/* 0x80-0x87 */
 	0x51E6,0x521D,0x6240,0x6691,0x66D9,0x6E1A,0x5EB6,0x7DD2,/* 0x88-0x8F */
 	0x7F72,0x66F8,0x85AF,0x85F7,0x8AF8,0x52A9,0x53D9,0x5973,/* 0x90-0x97 */
@@ -472,7 +472,7 @@
 	0x8F9B,0x9032,0x91DD,0x9707,0x4EBA,0x4EC1,0x5203,0x5875,/* 0x68-0x6F */
 	0x58EC,0x5C0B,0x751A,0x5C3D,0x814E,0x8A0A,0x8FC5,0x9663,/* 0x70-0x77 */
 	0x976D,0x7B25,0x8ACF,0x9808,0x9162,0x56F3,0x53A8,0x0000,/* 0x78-0x7F */
-	
+
 	0x9017,0x5439,0x5782,0x5E25,0x63A8,0x6C34,0x708A,0x7761,/* 0x80-0x87 */
 	0x7C8B,0x7FE0,0x8870,0x9042,0x9154,0x9310,0x9318,0x968F,/* 0x88-0x8F */
 	0x745E,0x9AC4,0x5D07,0x5D69,0x6570,0x67A2,0x8DA8,0x96DB,/* 0x90-0x97 */
@@ -508,7 +508,7 @@
 	0x8607,0x8A34,0x963B,0x9061,0x9F20,0x50E7,0x5275,0x53CC,/* 0x68-0x6F */
 	0x53E2,0x5009,0x55AA,0x58EE,0x594F,0x723D,0x5B8B,0x5C64,/* 0x70-0x77 */
 	0x531D,0x60E3,0x60F3,0x635C,0x6383,0x633F,0x63BB,0x0000,/* 0x78-0x7F */
-	
+
 	0x64CD,0x65E9,0x66F9,0x5DE3,0x69CD,0x69FD,0x6F15,0x71E5,/* 0x80-0x87 */
 	0x4E89,0x75E9,0x76F8,0x7A93,0x7CDF,0x7DCF,0x7D9C,0x8061,/* 0x88-0x8F */
 	0x8349,0x8358,0x846C,0x84BC,0x85FB,0x88C5,0x8D70,0x9001,/* 0x90-0x97 */
@@ -544,7 +544,7 @@
 	0x6A80,0x6BB5,0x7537,0x8AC7,0x5024,0x77E5,0x5730,0x5F1B,/* 0x68-0x6F */
 	0x6065,0x667A,0x6C60,0x75F4,0x7A1A,0x7F6E,0x81F4,0x8718,/* 0x70-0x77 */
 	0x9045,0x99B3,0x7BC9,0x755C,0x7AF9,0x7B51,0x84C4,0x0000,/* 0x78-0x7F */
-	
+
 	0x9010,0x79E9,0x7A92,0x8336,0x5AE1,0x7740,0x4E2D,0x4EF2,/* 0x80-0x87 */
 	0x5B99,0x5FE0,0x62BD,0x663C,0x67F1,0x6CE8,0x866B,0x8877,/* 0x88-0x8F */
 	0x8A3B,0x914E,0x92F3,0x99D0,0x6A17,0x7026,0x732A,0x82E7,/* 0x90-0x97 */
@@ -580,7 +580,7 @@
 	0x5857,0x59AC,0x5C60,0x5F92,0x6597,0x675C,0x6E21,0x767B,/* 0x68-0x6F */
 	0x83DF,0x8CED,0x9014,0x90FD,0x934D,0x7825,0x783A,0x52AA,/* 0x70-0x77 */
 	0x5EA6,0x571F,0x5974,0x6012,0x5012,0x515A,0x51AC,0x0000,/* 0x78-0x7F */
-	
+
 	0x51CD,0x5200,0x5510,0x5854,0x5858,0x5957,0x5B95,0x5CF6,/* 0x80-0x87 */
 	0x5D8B,0x60BC,0x6295,0x642D,0x6771,0x6843,0x68BC,0x68DF,/* 0x88-0x8F */
 	0x76D7,0x6DD8,0x6E6F,0x6D9B,0x706F,0x71C8,0x5F53,0x75D8,/* 0x90-0x97 */
@@ -616,7 +616,7 @@
 	0x6D3E,0x7436,0x7834,0x5A46,0x7F75,0x82AD,0x99AC,0x4FF3,/* 0x68-0x6F */
 	0x5EC3,0x62DD,0x6392,0x6557,0x676F,0x76C3,0x724C,0x80CC,/* 0x70-0x77 */
 	0x80BA,0x8F29,0x914D,0x500D,0x57F9,0x5A92,0x6885,0x0000,/* 0x78-0x7F */
-	
+
 	0x6973,0x7164,0x72FD,0x8CB7,0x58F2,0x8CE0,0x966A,0x9019,/* 0x80-0x87 */
 	0x877F,0x79E4,0x77E7,0x8429,0x4F2F,0x5265,0x535A,0x62CD,/* 0x88-0x8F */
 	0x67CF,0x6CCA,0x767D,0x7B94,0x7C95,0x8236,0x8584,0x8FEB,/* 0x90-0x97 */
@@ -652,7 +652,7 @@
 	0x9C2D,0x54C1,0x5F6C,0x658C,0x6D5C,0x7015,0x8CA7,0x8CD3,/* 0x68-0x6F */
 	0x983B,0x654F,0x74F6,0x4E0D,0x4ED8,0x57E0,0x592B,0x5A66,/* 0x70-0x77 */
 	0x5BCC,0x51A8,0x5E03,0x5E9C,0x6016,0x6276,0x6577,0x0000,/* 0x78-0x7F */
-	
+
 	0x65A7,0x666E,0x6D6E,0x7236,0x7B26,0x8150,0x819A,0x8299,/* 0x80-0x87 */
 	0x8B5C,0x8CA0,0x8CE6,0x8D74,0x961C,0x9644,0x4FAE,0x64AB,/* 0x88-0x8F */
 	0x6B66,0x821E,0x8461,0x856A,0x90E8,0x5C01,0x6953,0x98A8,/* 0x90-0x97 */
@@ -688,7 +688,7 @@
 	0x9632,0x5420,0x982C,0x5317,0x50D5,0x535C,0x58A8,0x64B2,/* 0x68-0x6F */
 	0x6734,0x7267,0x7766,0x7A46,0x91E6,0x52C3,0x6CA1,0x6B86,/* 0x70-0x77 */
 	0x5800,0x5E4C,0x5954,0x672C,0x7FFB,0x51E1,0x76C6,0x0000,/* 0x78-0x7F */
-	
+
 	0x6469,0x78E8,0x9B54,0x9EBB,0x57CB,0x59B9,0x6627,0x679A,/* 0x80-0x87 */
 	0x6BCE,0x54E9,0x69D9,0x5E55,0x819C,0x6795,0x9BAA,0x67FE,/* 0x88-0x8F */
 	0x9C52,0x685D,0x4EA6,0x4FE3,0x53C8,0x62B9,0x672B,0x6CAB,/* 0x90-0x97 */
@@ -724,7 +724,7 @@
 	0x63FA,0x64C1,0x66DC,0x694A,0x69D8,0x6D0B,0x6EB6,0x7194,/* 0x68-0x6F */
 	0x7528,0x7AAF,0x7F8A,0x8000,0x8449,0x84C9,0x8981,0x8B21,/* 0x70-0x77 */
 	0x8E0A,0x9065,0x967D,0x990A,0x617E,0x6291,0x6B32,0x0000,/* 0x78-0x7F */
-	
+
 	0x6C83,0x6D74,0x7FCC,0x7FFC,0x6DC0,0x7F85,0x87BA,0x88F8,/* 0x80-0x87 */
 	0x6765,0x83B1,0x983C,0x96F7,0x6D1B,0x7D61,0x843D,0x916A,/* 0x88-0x8F */
 	0x4E71,0x5375,0x5D50,0x6B04,0x6FEB,0x85CD,0x862D,0x89A7,/* 0x90-0x97 */
@@ -760,7 +760,7 @@
 	0x9DF2,0x4E99,0x4E98,0x9C10,0x8A6B,0x85C1,0x8568,0x6900,/* 0x68-0x6F */
 	0x6E7E,0x7897,0x8155,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -796,7 +796,7 @@
 	0x5191,0x5193,0x5195,0x5196,0x51A4,0x51A6,0x51A2,0x51A9,/* 0x68-0x6F */
 	0x51AA,0x51AB,0x51B3,0x51B1,0x51B2,0x51B0,0x51B5,0x51BD,/* 0x70-0x77 */
 	0x51C5,0x51C9,0x51DB,0x51E0,0x8655,0x51E9,0x51ED,0x0000,/* 0x78-0x7F */
-	
+
 	0x51F0,0x51F5,0x51FE,0x5204,0x520B,0x5214,0x520E,0x5227,/* 0x80-0x87 */
 	0x522A,0x522E,0x5233,0x5239,0x524F,0x5244,0x524B,0x524C,/* 0x88-0x8F */
 	0x525E,0x5254,0x526A,0x5274,0x5269,0x5273,0x527F,0x527D,/* 0x90-0x97 */
@@ -832,7 +832,7 @@
 	0x5587,0x55A8,0x55DA,0x55C5,0x55DF,0x55C4,0x55DC,0x55E4,/* 0x68-0x6F */
 	0x55D4,0x5614,0x55F7,0x5616,0x55FE,0x55FD,0x561B,0x55F9,/* 0x70-0x77 */
 	0x564E,0x5650,0x71DF,0x5634,0x5636,0x5632,0x5638,0x0000,/* 0x78-0x7F */
-	
+
 	0x566B,0x5664,0x562F,0x566C,0x566A,0x5686,0x5680,0x568A,/* 0x80-0x87 */
 	0x56A0,0x5694,0x568F,0x56A5,0x56AE,0x56B6,0x56B4,0x56C2,/* 0x88-0x8F */
 	0x56BC,0x56C1,0x56C3,0x56C0,0x56C8,0x56CE,0x56D1,0x56D3,/* 0x90-0x97 */
@@ -868,7 +868,7 @@
 	0x5B0B,0x5B16,0x5B32,0x5AD0,0x5B2A,0x5B36,0x5B3E,0x5B43,/* 0x68-0x6F */
 	0x5B45,0x5B40,0x5B51,0x5B55,0x5B5A,0x5B5B,0x5B65,0x5B69,/* 0x70-0x77 */
 	0x5B70,0x5B73,0x5B75,0x5B78,0x6588,0x5B7A,0x5B80,0x0000,/* 0x78-0x7F */
-	
+
 	0x5B83,0x5BA6,0x5BB8,0x5BC3,0x5BC7,0x5BC9,0x5BD4,0x5BD0,/* 0x80-0x87 */
 	0x5BE4,0x5BE6,0x5BE2,0x5BDE,0x5BE5,0x5BEB,0x5BF0,0x5BF6,/* 0x88-0x8F */
 	0x5BF3,0x5C05,0x5C07,0x5C08,0x5C0D,0x5C13,0x5C20,0x5C22,/* 0x90-0x97 */
@@ -904,7 +904,7 @@
 	0x5F82,0x5F7F,0x5F8A,0x5F88,0x5F91,0x5F87,0x5F9E,0x5F99,/* 0x68-0x6F */
 	0x5F98,0x5FA0,0x5FA8,0x5FAD,0x5FBC,0x5FD6,0x5FFB,0x5FE4,/* 0x70-0x77 */
 	0x5FF8,0x5FF1,0x5FDD,0x60B3,0x5FFF,0x6021,0x6060,0x0000,/* 0x78-0x7F */
-	
+
 	0x6019,0x6010,0x6029,0x600E,0x6031,0x601B,0x6015,0x602B,/* 0x80-0x87 */
 	0x6026,0x600F,0x603A,0x605A,0x6041,0x606A,0x6077,0x605F,/* 0x88-0x8F */
 	0x604A,0x6046,0x604D,0x6063,0x6043,0x6064,0x6042,0x606C,/* 0x90-0x97 */
@@ -940,7 +940,7 @@
 	0x62EE,0x62F1,0x6327,0x6302,0x6308,0x62EF,0x62F5,0x6350,/* 0x68-0x6F */
 	0x633E,0x634D,0x641C,0x634F,0x6396,0x638E,0x6380,0x63AB,/* 0x70-0x77 */
 	0x6376,0x63A3,0x638F,0x6389,0x639F,0x63B5,0x636B,0x0000,/* 0x78-0x7F */
-	
+
 	0x6369,0x63BE,0x63E9,0x63C0,0x63C6,0x63E3,0x63C9,0x63D2,/* 0x80-0x87 */
 	0x63F6,0x63C4,0x6416,0x6434,0x6406,0x6413,0x6426,0x6436,/* 0x88-0x8F */
 	0x651D,0x6417,0x6428,0x640F,0x6467,0x646F,0x6476,0x644E,/* 0x90-0x97 */
@@ -976,7 +976,7 @@
 	0x67EF,0x67B4,0x67EC,0x67B3,0x67E9,0x67B8,0x67E4,0x67DE,/* 0x68-0x6F */
 	0x67DD,0x67E2,0x67EE,0x67B9,0x67CE,0x67C6,0x67E7,0x6A9C,/* 0x70-0x77 */
 	0x681E,0x6846,0x6829,0x6840,0x684D,0x6832,0x684E,0x0000,/* 0x78-0x7F */
-	
+
 	0x68B3,0x682B,0x6859,0x6863,0x6877,0x687F,0x689F,0x688F,/* 0x80-0x87 */
 	0x68AD,0x6894,0x689D,0x689B,0x6883,0x6AAE,0x68B9,0x6874,/* 0x88-0x8F */
 	0x68B5,0x68A0,0x68BA,0x690F,0x688D,0x687E,0x6901,0x68CA,/* 0x90-0x97 */
@@ -1012,7 +1012,7 @@
 	0x6B84,0x6B83,0x6B8D,0x6B98,0x6B95,0x6B9E,0x6BA4,0x6BAA,/* 0x68-0x6F */
 	0x6BAB,0x6BAF,0x6BB2,0x6BB1,0x6BB3,0x6BB7,0x6BBC,0x6BC6,/* 0x70-0x77 */
 	0x6BCB,0x6BD3,0x6BDF,0x6BEC,0x6BEB,0x6BF3,0x6BEF,0x0000,/* 0x78-0x7F */
-	
+
 	0x9EBE,0x6C08,0x6C13,0x6C14,0x6C1B,0x6C24,0x6C23,0x6C5E,/* 0x80-0x87 */
 	0x6C55,0x6C62,0x6C6A,0x6C82,0x6C8D,0x6C9A,0x6C81,0x6C9B,/* 0x88-0x8F */
 	0x6C7E,0x6C68,0x6C73,0x6C92,0x6C90,0x6CC4,0x6CF1,0x6CD3,/* 0x90-0x97 */
@@ -1048,7 +1048,7 @@
 	0x6FFE,0x701B,0x701A,0x6F74,0x701D,0x7018,0x701F,0x7030,/* 0x68-0x6F */
 	0x703E,0x7032,0x7051,0x7063,0x7099,0x7092,0x70AF,0x70F1,/* 0x70-0x77 */
 	0x70AC,0x70B8,0x70B3,0x70AE,0x70DF,0x70CB,0x70DD,0x0000,/* 0x78-0x7F */
-	
+
 	0x70D9,0x7109,0x70FD,0x711C,0x7119,0x7165,0x7155,0x7188,/* 0x80-0x87 */
 	0x7166,0x7162,0x714C,0x7156,0x716C,0x718F,0x71FB,0x7184,/* 0x88-0x8F */
 	0x7195,0x71A8,0x71AC,0x71D7,0x71B9,0x71BE,0x71D2,0x71C9,/* 0x90-0x97 */
@@ -1084,7 +1084,7 @@
 	0x7589,0x7582,0x7594,0x759A,0x759D,0x75A5,0x75A3,0x75C2,/* 0x68-0x6F */
 	0x75B3,0x75C3,0x75B5,0x75BD,0x75B8,0x75BC,0x75B1,0x75CD,/* 0x70-0x77 */
 	0x75CA,0x75D2,0x75D9,0x75E3,0x75DE,0x75FE,0x75FF,0x0000,/* 0x78-0x7F */
-	
+
 	0x75FC,0x7601,0x75F0,0x75FA,0x75F2,0x75F3,0x760B,0x760D,/* 0x80-0x87 */
 	0x7609,0x761F,0x7627,0x7620,0x7621,0x7622,0x7624,0x7634,/* 0x88-0x8F */
 	0x7630,0x763B,0x7647,0x7648,0x7646,0x765C,0x7658,0x7661,/* 0x90-0x97 */
@@ -1120,7 +1120,7 @@
 	0x7980,0x7A31,0x7A3B,0x7A3E,0x7A37,0x7A43,0x7A57,0x7A49,/* 0x68-0x6F */
 	0x7A61,0x7A62,0x7A69,0x9F9D,0x7A70,0x7A79,0x7A7D,0x7A88,/* 0x70-0x77 */
 	0x7A97,0x7A95,0x7A98,0x7A96,0x7AA9,0x7AC8,0x7AB0,0x0000,/* 0x78-0x7F */
-	
+
 	0x7AB6,0x7AC5,0x7AC4,0x7ABF,0x9083,0x7AC7,0x7ACA,0x7ACD,/* 0x80-0x87 */
 	0x7ACF,0x7AD5,0x7AD3,0x7AD9,0x7ADA,0x7ADD,0x7AE1,0x7AE2,/* 0x88-0x8F */
 	0x7AE6,0x7AED,0x7AF0,0x7B02,0x7B0F,0x7B0A,0x7B06,0x7B33,/* 0x90-0x97 */
@@ -1156,7 +1156,7 @@
 	0x7DDD,0x7DE4,0x7DDE,0x7DFB,0x7DF2,0x7DE1,0x7E05,0x7E0A,/* 0x68-0x6F */
 	0x7E23,0x7E21,0x7E12,0x7E31,0x7E1F,0x7E09,0x7E0B,0x7E22,/* 0x70-0x77 */
 	0x7E46,0x7E66,0x7E3B,0x7E35,0x7E39,0x7E43,0x7E37,0x0000,/* 0x78-0x7F */
-	
+
 	0x7E32,0x7E3A,0x7E67,0x7E5D,0x7E56,0x7E5E,0x7E59,0x7E5A,/* 0x80-0x87 */
 	0x7E79,0x7E6A,0x7E69,0x7E7C,0x7E7B,0x7E83,0x7DD5,0x7E7D,/* 0x88-0x8F */
 	0x8FAE,0x7E7F,0x7E88,0x7E89,0x7E8C,0x7E92,0x7E90,0x7E93,/* 0x90-0x97 */
@@ -1192,7 +1192,7 @@
 	0x81E7,0x81FA,0x81FB,0x81FE,0x8201,0x8202,0x8205,0x8207,/* 0x68-0x6F */
 	0x820A,0x820D,0x8210,0x8216,0x8229,0x822B,0x8238,0x8233,/* 0x70-0x77 */
 	0x8240,0x8259,0x8258,0x825D,0x825A,0x825F,0x8264,0x0000,/* 0x78-0x7F */
-	
+
 	0x8262,0x8268,0x826A,0x826B,0x822E,0x8271,0x8277,0x8278,/* 0x80-0x87 */
 	0x827E,0x828D,0x8292,0x82AB,0x829F,0x82BB,0x82AC,0x82E1,/* 0x88-0x8F */
 	0x82E3,0x82DF,0x82D2,0x82F4,0x82F3,0x82FA,0x8393,0x8303,/* 0x90-0x97 */
@@ -1228,7 +1228,7 @@
 	0x4E55,0x8654,0x865F,0x8667,0x8671,0x8693,0x86A3,0x86A9,/* 0x68-0x6F */
 	0x86AA,0x868B,0x868C,0x86B6,0x86AF,0x86C4,0x86C6,0x86B0,/* 0x70-0x77 */
 	0x86C9,0x8823,0x86AB,0x86D4,0x86DE,0x86E9,0x86EC,0x0000,/* 0x78-0x7F */
-	
+
 	0x86DF,0x86DB,0x86EF,0x8712,0x8706,0x8708,0x8700,0x8703,/* 0x80-0x87 */
 	0x86FB,0x8711,0x8709,0x870D,0x86F9,0x870A,0x8734,0x873F,/* 0x88-0x8F */
 	0x8737,0x873B,0x8725,0x8729,0x871A,0x8760,0x875F,0x8778,/* 0x90-0x97 */
@@ -1264,7 +1264,7 @@
 	0x8A46,0x8A48,0x8A7C,0x8A6D,0x8A6C,0x8A62,0x8A85,0x8A82,/* 0x68-0x6F */
 	0x8A84,0x8AA8,0x8AA1,0x8A91,0x8AA5,0x8AA6,0x8A9A,0x8AA3,/* 0x70-0x77 */
 	0x8AC4,0x8ACD,0x8AC2,0x8ADA,0x8AEB,0x8AF3,0x8AE7,0x0000,/* 0x78-0x7F */
-	
+
 	0x8AE4,0x8AF1,0x8B14,0x8AE0,0x8AE2,0x8AF7,0x8ADE,0x8ADB,/* 0x80-0x87 */
 	0x8B0C,0x8B07,0x8B1A,0x8AE1,0x8B16,0x8B10,0x8B17,0x8B20,/* 0x88-0x8F */
 	0x8B33,0x97AB,0x8B26,0x8B2B,0x8B3E,0x8B28,0x8B41,0x8B4C,/* 0x90-0x97 */
@@ -1300,7 +1300,7 @@
 	0x8F0A,0x8F05,0x8F15,0x8F12,0x8F19,0x8F13,0x8F1C,0x8F1F,/* 0x68-0x6F */
 	0x8F1B,0x8F0C,0x8F26,0x8F33,0x8F3B,0x8F39,0x8F45,0x8F42,/* 0x70-0x77 */
 	0x8F3E,0x8F4C,0x8F49,0x8F46,0x8F4E,0x8F57,0x8F5C,0x0000,/* 0x78-0x7F */
-	
+
 	0x8F62,0x8F63,0x8F64,0x8F9C,0x8F9F,0x8FA3,0x8FAD,0x8FAF,/* 0x80-0x87 */
 	0x8FB7,0x8FDA,0x8FE5,0x8FE2,0x8FEA,0x8FEF,0x9087,0x8FF4,/* 0x88-0x8F */
 	0x9005,0x8FF9,0x8FFA,0x9011,0x9015,0x9021,0x900D,0x901E,/* 0x90-0x97 */
@@ -1336,7 +1336,7 @@
 	0x9444,0x945B,0x9460,0x9462,0x945E,0x946A,0x9229,0x9470,/* 0x68-0x6F */
 	0x9475,0x9477,0x947D,0x945A,0x947C,0x947E,0x9481,0x947F,/* 0x70-0x77 */
 	0x9582,0x9587,0x958A,0x9594,0x9596,0x9598,0x9599,0x0000,/* 0x78-0x7F */
-	
+
 	0x95A0,0x95A8,0x95A7,0x95AD,0x95BC,0x95BB,0x95B9,0x95BE,/* 0x80-0x87 */
 	0x95CA,0x6FF6,0x95C3,0x95CD,0x95CC,0x95D5,0x95D4,0x95D6,/* 0x88-0x8F */
 	0x95DC,0x95E1,0x95E5,0x95E2,0x9621,0x9628,0x962E,0x962F,/* 0x90-0x97 */
@@ -1372,7 +1372,7 @@
 	0x99BC,0x99DF,0x99DB,0x99DD,0x99D8,0x99D1,0x99ED,0x99EE,/* 0x68-0x6F */
 	0x99F1,0x99F2,0x99FB,0x99F8,0x9A01,0x9A0F,0x9A05,0x99E2,/* 0x70-0x77 */
 	0x9A19,0x9A2B,0x9A37,0x9A45,0x9A42,0x9A40,0x9A43,0x0000,/* 0x78-0x7F */
-	
+
 	0x9A3E,0x9A55,0x9A4D,0x9A5B,0x9A57,0x9A5F,0x9A62,0x9A65,/* 0x80-0x87 */
 	0x9A64,0x9A69,0x9A6B,0x9A6A,0x9AAD,0x9AB0,0x9ABC,0x9AC0,/* 0x88-0x8F */
 	0x9ACF,0x9AD1,0x9AD3,0x9AD4,0x9ADE,0x9ADF,0x9AE2,0x9AE3,/* 0x90-0x97 */
@@ -1408,23 +1408,12 @@
 	0x9E8C,0x9E92,0x9E95,0x9E91,0x9E9D,0x9EA5,0x9EA9,0x9EB8,/* 0x68-0x6F */
 	0x9EAA,0x9EAD,0x9761,0x9ECC,0x9ECE,0x9ECF,0x9ED0,0x9ED4,/* 0x70-0x77 */
 	0x9EDC,0x9EDE,0x9EDD,0x9EE0,0x9EE5,0x9EE8,0x9EEF,0x0000,/* 0x78-0x7F */
-	
+
 	0x9EF4,0x9EF6,0x9EF7,0x9EF9,0x9EFB,0x9EFC,0x9EFD,0x9F07,/* 0x80-0x87 */
 	0x9F08,0x76B7,0x9F15,0x9F21,0x9F2C,0x9F3E,0x9F4A,0x9F52,/* 0x88-0x8F */
 	0x9F54,0x9F63,0x9F5F,0x9F60,0x9F61,0x9F66,0x9F67,0x9F6C,/* 0x90-0x97 */
 	0x9F6A,0x9F77,0x9F72,0x9F76,0x9F95,0x9F9C,0x9FA0,0x582F,/* 0x98-0x9F */
 	0x69C7,0x9059,0x7464,0x51DC,0x7199,0x0000,0x0000,0x0000,/* 0xA0-0xA7 */
-	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0xA8-0xAF */
-	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0xB0-0xB7 */
-	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0xB8-0xBF */
-	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0xC0-0xC7 */
-	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0xC8-0xCF */
-	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0xD0-0xD7 */
-	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0xD8-0xDF */
-	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0xE0-0xE7 */
-	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0xE8-0xEF */
-	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0xF0-0xF7 */
-	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0xF8-0xFF */
 };
 
 static wchar_t c2u_ED[256] = {
@@ -1444,7 +1433,7 @@
 	0x529C,0x52A6,0x52C0,0x52DB,0x5300,0x5307,0x5324,0x5372,/* 0x68-0x6F */
 	0x5393,0x53B2,0x53DD,0xFA0E,0x549C,0x548A,0x54A9,0x54FF,/* 0x70-0x77 */
 	0x5586,0x5759,0x5765,0x57AC,0x57C8,0x57C7,0xFA0F,0x0000,/* 0x78-0x7F */
-	
+
 	0xFA10,0x589E,0x58B2,0x590B,0x5953,0x595B,0x595D,0x5963,/* 0x80-0x87 */
 	0x59A4,0x59BA,0x5B56,0x5BC0,0x752F,0x5BD8,0x5BEC,0x5C1E,/* 0x88-0x8F */
 	0x5CA6,0x5CBA,0x5CF5,0x5D27,0x5D53,0xFA11,0x5D42,0x5D6D,/* 0x90-0x97 */
@@ -1480,7 +1469,7 @@
 	0x7AE7,0xFA1C,0x7AEB,0x7B9E,0xFA1D,0x7D48,0x7D5C,0x7DB7,/* 0x68-0x6F */
 	0x7DA0,0x7DD6,0x7E52,0x7F47,0x7FA1,0xFA1E,0x8301,0x8362,/* 0x70-0x77 */
 	0x837F,0x83C7,0x83F6,0x8448,0x84B4,0x8553,0x8559,0x0000,/* 0x78-0x7F */
-	
+
 	0x856B,0xFA1F,0x85B0,0xFA20,0xFA21,0x8807,0x88F5,0x8A12,/* 0x80-0x87 */
 	0x8A37,0x8A79,0x8AA7,0x8ABE,0x8ADF,0xFA22,0x8AF6,0x8B53,/* 0x88-0x8F */
 	0x8B7F,0x8CF0,0x8CF4,0x8D12,0x8D76,0xFA23,0x8ECF,0xFA24,/* 0x90-0x97 */
@@ -1510,13 +1499,13 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x38-0x3F */
 	0x2170,0x2171,0x2172,0x2173,0x2174,0x2175,0x2176,0x2177,/* 0x40-0x47 */
 	0x2178,0x2179,0x2160,0x2161,0x2162,0x2163,0x2164,0x2165,/* 0x48-0x4F */
-	0x2166,0x2167,0x2168,0x2169,0x0000,0xFFE4,0xFF07,0xFF02,/* 0x50-0x57 */
+	0x2166,0x2167,0x2168,0x2169,0xFFE2,0xFFE4,0xFF07,0xFF02,/* 0x50-0x57 */
 	0x3231,0x2116,0x2121,0x2235,0x7E8A,0x891C,0x9348,0x9288,/* 0x58-0x5F */
 	0x84DC,0x4FC9,0x70BB,0x6631,0x68C8,0x92F9,0x66FB,0x5F45,/* 0x60-0x67 */
 	0x4E28,0x4EE1,0x4EFC,0x4F00,0x4F03,0x4F39,0x4F56,0x4F92,/* 0x68-0x6F */
 	0x4F8A,0x4F9A,0x4F94,0x4FCD,0x5040,0x5022,0x4FFF,0x501E,/* 0x70-0x77 */
 	0x5046,0x5070,0x5042,0x5094,0x50F4,0x50D8,0x514A,0x0000,/* 0x78-0x7F */
-	
+
 	0x5164,0x519D,0x51BE,0x51EC,0x5215,0x529C,0x52A6,0x52C0,/* 0x80-0x87 */
 	0x52DB,0x5300,0x5307,0x5324,0x5372,0x5393,0x53B2,0x53DD,/* 0x88-0x8F */
 	0xFA0E,0x549C,0x548A,0x54A9,0x54FF,0x5586,0x5759,0x5765,/* 0x90-0x97 */
@@ -1552,7 +1541,7 @@
 	0x742A,0x7429,0x742E,0x7462,0x7489,0x749F,0x7501,0x756F,/* 0x68-0x6F */
 	0x7682,0x769C,0x769E,0x769B,0x76A6,0xFA17,0x7746,0x52AF,/* 0x70-0x77 */
 	0x7821,0x784E,0x7864,0x787A,0x7930,0xFA18,0xFA19,0x0000,/* 0x78-0x7F */
-	
+
 	0xFA1A,0x7994,0xFA1B,0x799B,0x7AD1,0x7AE7,0xFA1C,0x7AEB,/* 0x80-0x87 */
 	0x7B9E,0xFA1D,0x7D48,0x7D5C,0x7DB7,0x7DA0,0x7DD6,0x7E52,/* 0x88-0x8F */
 	0x7F47,0x7FA1,0xFA1E,0x8301,0x8362,0x837F,0x83C7,0x83F6,/* 0x90-0x97 */
diff -Nru a/fs/nls/nls_cp936.c b/fs/nls/nls_cp936.c
--- a/fs/nls/nls_cp936.c	2005-03-01 23:38:55 -08:00
+++ b/fs/nls/nls_cp936.c	2005-03-01 23:38:56 -08:00
@@ -29,8 +29,8 @@
 	0x4E63,0x4E64,0x4E65,0x4E67,0x4E68,0x4E6A,0x4E6B,0x4E6C,/* 0x60-0x67 */
 	0x4E6D,0x4E6E,0x4E6F,0x4E72,0x4E74,0x4E75,0x4E76,0x4E77,/* 0x68-0x6F */
 	0x4E78,0x4E79,0x4E7A,0x4E7B,0x4E7C,0x4E7D,0x4E7F,0x4E80,/* 0x70-0x77 */
-	0x4E81,0xF91B,0x4E83,0x4E84,0x4E85,0x4E87,0x4E8A,0x0000,/* 0x78-0x7F */
-	
+	0x4E81,0x4E82,0x4E83,0x4E84,0x4E85,0x4E87,0x4E8A,0x0000,/* 0x78-0x7F */
+
 	0x4E90,0x4E96,0x4E97,0x4E99,0x4E9C,0x4E9D,0x4E9E,0x4EA3,/* 0x80-0x87 */
 	0x4EAA,0x4EAF,0x4EB0,0x4EB1,0x4EB4,0x4EB6,0x4EB7,0x4EB8,/* 0x88-0x8F */
 	0x4EB9,0x4EBC,0x4EBD,0x4EBE,0x4EC8,0x4ECC,0x4ECF,0x4ED0,/* 0x90-0x97 */
@@ -44,7 +44,7 @@
 	0x4F47,0x4F48,0x4F49,0x4F4A,0x4F4B,0x4F4C,0x4F52,0x4F54,/* 0xD0-0xD7 */
 	0x4F56,0x4F61,0x4F62,0x4F66,0x4F68,0x4F6A,0x4F6B,0x4F6D,/* 0xD8-0xDF */
 	0x4F6E,0x4F71,0x4F72,0x4F75,0x4F77,0x4F78,0x4F79,0x4F7A,/* 0xE0-0xE7 */
-	0x4F7D,0x4F80,0x4F81,0x4F82,0x4F85,0xF92D,0x4F87,0x4F8A,/* 0xE8-0xEF */
+	0x4F7D,0x4F80,0x4F81,0x4F82,0x4F85,0x4F86,0x4F87,0x4F8A,/* 0xE8-0xEF */
 	0x4F8C,0x4F8E,0x4F90,0x4F92,0x4F93,0x4F95,0x4F96,0x4F98,/* 0xF0-0xF7 */
 	0x4F99,0x4F9A,0x4F9C,0x4F9E,0x4F9F,0x4FA1,0x4FA2,0x0000,/* 0xF8-0xFF */
 };
@@ -66,10 +66,10 @@
 	0x4FEC,0x4FF0,0x4FF2,0x4FF4,0x4FF5,0x4FF6,0x4FF7,0x4FF9,/* 0x68-0x6F */
 	0x4FFB,0x4FFC,0x4FFD,0x4FFF,0x5000,0x5001,0x5002,0x5003,/* 0x70-0x77 */
 	0x5004,0x5005,0x5006,0x5007,0x5008,0x5009,0x500A,0x0000,/* 0x78-0x7F */
-	
+
 	0x500B,0x500E,0x5010,0x5011,0x5013,0x5015,0x5016,0x5017,/* 0x80-0x87 */
 	0x501B,0x501D,0x501E,0x5020,0x5022,0x5023,0x5024,0x5027,/* 0x88-0x8F */
-	0xF9D4,0x502F,0x5030,0x5031,0x5032,0x5033,0x5034,0x5035,/* 0x90-0x97 */
+	0x502B,0x502F,0x5030,0x5031,0x5032,0x5033,0x5034,0x5035,/* 0x90-0x97 */
 	0x5036,0x5037,0x5038,0x5039,0x503B,0x503D,0x503F,0x5040,/* 0x98-0x9F */
 	0x5041,0x5042,0x5044,0x5045,0x5046,0x5049,0x504A,0x504B,/* 0xA0-0xA7 */
 	0x504D,0x5050,0x5051,0x5052,0x5053,0x5054,0x5056,0x5057,/* 0xA8-0xAF */
@@ -102,7 +102,7 @@
 	0x50EA,0x50EB,0x50EF,0x50F0,0x50F1,0x50F2,0x50F4,0x50F6,/* 0x68-0x6F */
 	0x50F7,0x50F8,0x50F9,0x50FA,0x50FC,0x50FD,0x50FE,0x50FF,/* 0x70-0x77 */
 	0x5100,0x5101,0x5102,0x5103,0x5104,0x5105,0x5108,0x0000,/* 0x78-0x7F */
-	
+
 	0x5109,0x510A,0x510C,0x510D,0x510E,0x510F,0x5110,0x5111,/* 0x80-0x87 */
 	0x5113,0x5114,0x5115,0x5116,0x5117,0x5118,0x5119,0x511A,/* 0x88-0x8F */
 	0x511B,0x511C,0x511D,0x511E,0x511F,0x5120,0x5122,0x5123,/* 0x90-0x97 */
@@ -112,7 +112,7 @@
 	0x513C,0x513D,0x513E,0x5142,0x5147,0x514A,0x514C,0x514E,/* 0xB0-0xB7 */
 	0x514F,0x5150,0x5152,0x5153,0x5157,0x5158,0x5159,0x515B,/* 0xB8-0xBF */
 	0x515D,0x515E,0x515F,0x5160,0x5161,0x5163,0x5164,0x5166,/* 0xC0-0xC7 */
-	0x5167,0xF978,0x516A,0x516F,0x5172,0x517A,0x517E,0x517F,/* 0xC8-0xCF */
+	0x5167,0x5169,0x516A,0x516F,0x5172,0x517A,0x517E,0x517F,/* 0xC8-0xCF */
 	0x5183,0x5184,0x5186,0x5187,0x518A,0x518B,0x518E,0x518F,/* 0xD0-0xD7 */
 	0x5190,0x5191,0x5193,0x5194,0x5198,0x519A,0x519D,0x519E,/* 0xD8-0xDF */
 	0x519F,0x51A1,0x51A3,0x51A6,0x51A7,0x51A8,0x51A9,0x51AA,/* 0xE0-0xE7 */
@@ -130,7 +130,7 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x28-0x2F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x30-0x37 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x38-0x3F */
-	0x51D8,0x51D9,0x51DA,0xF954,0xFA15,0x51DF,0x51E2,0x51E3,/* 0x40-0x47 */
+	0x51D8,0x51D9,0x51DA,0x51DC,0x51DE,0x51DF,0x51E2,0x51E3,/* 0x40-0x47 */
 	0x51E5,0x51E6,0x51E7,0x51E8,0x51E9,0x51EA,0x51EC,0x51EE,/* 0x48-0x4F */
 	0x51F1,0x51F2,0x51F4,0x51F7,0x51FE,0x5204,0x5205,0x5209,/* 0x50-0x57 */
 	0x520B,0x520C,0x520F,0x5210,0x5213,0x5214,0x5215,0x521C,/* 0x58-0x5F */
@@ -138,21 +138,21 @@
 	0x522A,0x522C,0x522F,0x5231,0x5232,0x5234,0x5235,0x523C,/* 0x68-0x6F */
 	0x523E,0x5244,0x5245,0x5246,0x5247,0x5248,0x5249,0x524B,/* 0x70-0x77 */
 	0x524E,0x524F,0x5252,0x5253,0x5255,0x5257,0x5258,0x0000,/* 0x78-0x7F */
-	
+
 	0x5259,0x525A,0x525B,0x525D,0x525F,0x5260,0x5262,0x5263,/* 0x80-0x87 */
 	0x5264,0x5266,0x5268,0x526B,0x526C,0x526D,0x526E,0x5270,/* 0x88-0x8F */
 	0x5271,0x5273,0x5274,0x5275,0x5276,0x5277,0x5278,0x5279,/* 0x90-0x97 */
 	0x527A,0x527B,0x527C,0x527E,0x5280,0x5283,0x5284,0x5285,/* 0x98-0x9F */
-	0x5286,0x5287,0xF9C7,0x528A,0x528B,0x528C,0x528D,0x528E,/* 0xA0-0xA7 */
+	0x5286,0x5287,0x5289,0x528A,0x528B,0x528C,0x528D,0x528E,/* 0xA0-0xA7 */
 	0x528F,0x5291,0x5292,0x5294,0x5295,0x5296,0x5297,0x5298,/* 0xA8-0xAF */
 	0x5299,0x529A,0x529C,0x52A4,0x52A5,0x52A6,0x52A7,0x52AE,/* 0xB0-0xB7 */
 	0x52AF,0x52B0,0x52B4,0x52B5,0x52B6,0x52B7,0x52B8,0x52B9,/* 0xB8-0xBF */
 	0x52BA,0x52BB,0x52BC,0x52BD,0x52C0,0x52C1,0x52C2,0x52C4,/* 0xC0-0xC7 */
 	0x52C5,0x52C6,0x52C8,0x52CA,0x52CC,0x52CD,0x52CE,0x52CF,/* 0xC8-0xCF */
 	0x52D1,0x52D3,0x52D4,0x52D5,0x52D7,0x52D9,0x52DA,0x52DB,/* 0xD0-0xD7 */
-	0x52DC,0x52DD,0xF92F,0x52E0,0x52E1,0x52E2,0x52E3,0x52E5,/* 0xD8-0xDF */
+	0x52DC,0x52DD,0x52DE,0x52E0,0x52E1,0x52E2,0x52E3,0x52E5,/* 0xD8-0xDF */
 	0x52E6,0x52E7,0x52E8,0x52E9,0x52EA,0x52EB,0x52EC,0x52ED,/* 0xE0-0xE7 */
-	0x52EE,0x52EF,0x52F1,0x52F2,0x52F3,0x52F4,0xF97F,0x52F6,/* 0xE8-0xEF */
+	0x52EE,0x52EF,0x52F1,0x52F2,0x52F3,0x52F4,0x52F5,0x52F6,/* 0xE8-0xEF */
 	0x52F7,0x52F8,0x52FB,0x52FC,0x52FD,0x5301,0x5302,0x5303,/* 0xF0-0xF7 */
 	0x5304,0x5307,0x5309,0x530A,0x530B,0x530C,0x530E,0x0000,/* 0xF8-0xFF */
 };
@@ -174,17 +174,17 @@
 	0x5359,0x535B,0x535D,0x5365,0x5368,0x536A,0x536C,0x536D,/* 0x68-0x6F */
 	0x5372,0x5376,0x5379,0x537B,0x537C,0x537D,0x537E,0x5380,/* 0x70-0x77 */
 	0x5381,0x5383,0x5387,0x5388,0x538A,0x538E,0x538F,0x0000,/* 0x78-0x7F */
-	
+
 	0x5390,0x5391,0x5392,0x5393,0x5394,0x5396,0x5397,0x5399,/* 0x80-0x87 */
 	0x539B,0x539C,0x539E,0x53A0,0x53A1,0x53A4,0x53A7,0x53AA,/* 0x88-0x8F */
 	0x53AB,0x53AC,0x53AD,0x53AF,0x53B0,0x53B1,0x53B2,0x53B3,/* 0x90-0x97 */
 	0x53B4,0x53B5,0x53B7,0x53B8,0x53B9,0x53BA,0x53BC,0x53BD,/* 0x98-0x9F */
-	0x53BE,0x53C0,0xF96B,0x53C4,0x53C5,0x53C6,0x53C7,0x53CE,/* 0xA0-0xA7 */
+	0x53BE,0x53C0,0x53C3,0x53C4,0x53C5,0x53C6,0x53C7,0x53CE,/* 0xA0-0xA7 */
 	0x53CF,0x53D0,0x53D2,0x53D3,0x53D5,0x53DA,0x53DC,0x53DD,/* 0xA8-0xAF */
 	0x53DE,0x53E1,0x53E2,0x53E7,0x53F4,0x53FA,0x53FE,0x53FF,/* 0xB0-0xB7 */
 	0x5400,0x5402,0x5405,0x5407,0x540B,0x5414,0x5418,0x5419,/* 0xB8-0xBF */
 	0x541A,0x541C,0x5422,0x5424,0x5425,0x542A,0x5430,0x5433,/* 0xC0-0xC7 */
-	0x5436,0x5437,0x543A,0x543D,0x543F,0x5441,0xF980,0x5444,/* 0xC8-0xCF */
+	0x5436,0x5437,0x543A,0x543D,0x543F,0x5441,0x5442,0x5444,/* 0xC8-0xCF */
 	0x5445,0x5447,0x5449,0x544C,0x544D,0x544E,0x544F,0x5451,/* 0xD0-0xD7 */
 	0x545A,0x545D,0x545E,0x545F,0x5460,0x5461,0x5463,0x5465,/* 0xD8-0xDF */
 	0x5467,0x5469,0x546A,0x546B,0x546C,0x546D,0x546E,0x546F,/* 0xE0-0xE7 */
@@ -210,7 +210,7 @@
 	0x5504,0x5505,0x5508,0x550A,0x550B,0x550C,0x550D,0x550E,/* 0x68-0x6F */
 	0x5512,0x5513,0x5515,0x5516,0x5517,0x5518,0x5519,0x551A,/* 0x70-0x77 */
 	0x551C,0x551D,0x551E,0x551F,0x5521,0x5525,0x5526,0x0000,/* 0x78-0x7F */
-	
+
 	0x5528,0x5529,0x552B,0x552D,0x5532,0x5534,0x5535,0x5536,/* 0x80-0x87 */
 	0x5538,0x5539,0x553A,0x553B,0x553D,0x5540,0x5542,0x5545,/* 0x88-0x8F */
 	0x5547,0x5548,0x554B,0x554C,0x554D,0x554E,0x554F,0x5551,/* 0x90-0x97 */
@@ -246,7 +246,7 @@
 	0x5643,0x5644,0x5645,0x5646,0x5647,0x5648,0x5649,0x564A,/* 0x68-0x6F */
 	0x564B,0x564F,0x5650,0x5651,0x5652,0x5653,0x5655,0x5656,/* 0x70-0x77 */
 	0x565A,0x565B,0x565D,0x565E,0x565F,0x5660,0x5661,0x0000,/* 0x78-0x7F */
-	
+
 	0x5663,0x5665,0x5666,0x5667,0x566D,0x566E,0x566F,0x5670,/* 0x80-0x87 */
 	0x5672,0x5673,0x5674,0x5675,0x5677,0x5678,0x5679,0x567A,/* 0x88-0x8F */
 	0x567D,0x567E,0x567F,0x5680,0x5681,0x5682,0x5683,0x5684,/* 0x90-0x97 */
@@ -282,7 +282,7 @@
 	0x5754,0x5755,0x5756,0x5758,0x5759,0x5762,0x5763,0x5765,/* 0x68-0x6F */
 	0x5767,0x576C,0x576E,0x5770,0x5771,0x5772,0x5774,0x5775,/* 0x70-0x77 */
 	0x5778,0x5779,0x577A,0x577D,0x577E,0x577F,0x5780,0x0000,/* 0x78-0x7F */
-	
+
 	0x5781,0x5787,0x5788,0x5789,0x578A,0x578D,0x578E,0x578F,/* 0x80-0x87 */
 	0x5790,0x5791,0x5794,0x5795,0x5796,0x5797,0x5798,0x5799,/* 0x88-0x8F */
 	0x579A,0x579C,0x579D,0x579E,0x579F,0x57A5,0x57A8,0x57AA,/* 0x90-0x97 */
@@ -312,13 +312,13 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x38-0x3F */
 	0x583E,0x583F,0x5840,0x5841,0x5842,0x5843,0x5845,0x5846,/* 0x40-0x47 */
 	0x5847,0x5848,0x5849,0x584A,0x584B,0x584E,0x584F,0x5850,/* 0x48-0x4F */
-	0x5852,0x5853,0x5855,0x5856,0x5857,0x5859,0xFA10,0x585B,/* 0x50-0x57 */
+	0x5852,0x5853,0x5855,0x5856,0x5857,0x5859,0x585A,0x585B,/* 0x50-0x57 */
 	0x585C,0x585D,0x585F,0x5860,0x5861,0x5862,0x5863,0x5864,/* 0x58-0x5F */
 	0x5866,0x5867,0x5868,0x5869,0x586A,0x586D,0x586E,0x586F,/* 0x60-0x67 */
 	0x5870,0x5871,0x5872,0x5873,0x5874,0x5875,0x5876,0x5877,/* 0x68-0x6F */
 	0x5878,0x5879,0x587A,0x587B,0x587C,0x587D,0x587F,0x5882,/* 0x70-0x77 */
 	0x5884,0x5886,0x5887,0x5888,0x588A,0x588B,0x588C,0x0000,/* 0x78-0x7F */
-	
+
 	0x588D,0x588E,0x588F,0x5890,0x5891,0x5894,0x5895,0x5896,/* 0x80-0x87 */
 	0x5897,0x5898,0x589B,0x589C,0x589D,0x58A0,0x58A1,0x58A2,/* 0x88-0x8F */
 	0x58A3,0x58A4,0x58A5,0x58A6,0x58A7,0x58AA,0x58AB,0x58AC,/* 0x90-0x97 */
@@ -326,8 +326,8 @@
 	0x58B5,0x58B6,0x58B7,0x58B8,0x58B9,0x58BA,0x58BB,0x58BD,/* 0xA0-0xA7 */
 	0x58BE,0x58BF,0x58C0,0x58C2,0x58C3,0x58C4,0x58C6,0x58C7,/* 0xA8-0xAF */
 	0x58C8,0x58C9,0x58CA,0x58CB,0x58CC,0x58CD,0x58CE,0x58CF,/* 0xB0-0xB7 */
-	0x58D0,0x58D2,0x58D3,0x58D4,0x58D6,0x58D7,0xF94A,0x58D9,/* 0xB8-0xBF */
-	0x58DA,0x58DB,0x58DC,0x58DD,0x58DE,0xF942,0x58E0,0x58E1,/* 0xC0-0xC7 */
+	0x58D0,0x58D2,0x58D3,0x58D4,0x58D6,0x58D7,0x58D8,0x58D9,/* 0xB8-0xBF */
+	0x58DA,0x58DB,0x58DC,0x58DD,0x58DE,0x58DF,0x58E0,0x58E1,/* 0xC0-0xC7 */
 	0x58E2,0x58E3,0x58E5,0x58E6,0x58E7,0x58E8,0x58E9,0x58EA,/* 0xC8-0xCF */
 	0x58ED,0x58EF,0x58F1,0x58F2,0x58F4,0x58F5,0x58F7,0x58F8,/* 0xD0-0xD7 */
 	0x58FA,0x58FB,0x58FC,0x58FD,0x58FE,0x58FF,0x5900,0x5901,/* 0xD8-0xDF */
@@ -354,7 +354,7 @@
 	0x597E,0x597F,0x5980,0x5985,0x5989,0x598B,0x598C,0x598E,/* 0x68-0x6F */
 	0x598F,0x5990,0x5991,0x5994,0x5995,0x5998,0x599A,0x599B,/* 0x70-0x77 */
 	0x599C,0x599D,0x599F,0x59A0,0x59A1,0x59A2,0x59A6,0x0000,/* 0x78-0x7F */
-	
+
 	0x59A7,0x59AC,0x59AD,0x59B0,0x59B1,0x59B3,0x59B4,0x59B5,/* 0x80-0x87 */
 	0x59B6,0x59B7,0x59B8,0x59BA,0x59BC,0x59BD,0x59BF,0x59C0,/* 0x88-0x8F */
 	0x59C1,0x59C2,0x59C3,0x59C4,0x59C5,0x59C7,0x59C8,0x59C9,/* 0x90-0x97 */
@@ -390,7 +390,7 @@
 	0x5A93,0x5A94,0x5A95,0x5A96,0x5A97,0x5A98,0x5A99,0x5A9C,/* 0x68-0x6F */
 	0x5A9D,0x5A9E,0x5A9F,0x5AA0,0x5AA1,0x5AA2,0x5AA3,0x5AA4,/* 0x70-0x77 */
 	0x5AA5,0x5AA6,0x5AA7,0x5AA8,0x5AA9,0x5AAB,0x5AAC,0x0000,/* 0x78-0x7F */
-	
+
 	0x5AAD,0x5AAE,0x5AAF,0x5AB0,0x5AB1,0x5AB4,0x5AB6,0x5AB7,/* 0x80-0x87 */
 	0x5AB9,0x5ABA,0x5ABB,0x5ABC,0x5ABD,0x5ABF,0x5AC0,0x5AC3,/* 0x88-0x8F */
 	0x5AC4,0x5AC5,0x5AC6,0x5AC7,0x5AC8,0x5ACA,0x5ACB,0x5ACD,/* 0x90-0x97 */
@@ -426,9 +426,9 @@
 	0x5BA7,0x5BA8,0x5BA9,0x5BAC,0x5BAD,0x5BAE,0x5BAF,0x5BB1,/* 0x68-0x6F */
 	0x5BB2,0x5BB7,0x5BBA,0x5BBB,0x5BBC,0x5BC0,0x5BC1,0x5BC3,/* 0x70-0x77 */
 	0x5BC8,0x5BC9,0x5BCA,0x5BCB,0x5BCD,0x5BCE,0x5BCF,0x0000,/* 0x78-0x7F */
-	
+
 	0x5BD1,0x5BD4,0x5BD5,0x5BD6,0x5BD7,0x5BD8,0x5BD9,0x5BDA,/* 0x80-0x87 */
-	0x5BDB,0x5BDC,0x5BE0,0x5BE2,0x5BE3,0x5BE6,0xF9AA,0x5BE9,/* 0x88-0x8F */
+	0x5BDB,0x5BDC,0x5BE0,0x5BE2,0x5BE3,0x5BE6,0x5BE7,0x5BE9,/* 0x88-0x8F */
 	0x5BEA,0x5BEB,0x5BEC,0x5BED,0x5BEF,0x5BF1,0x5BF2,0x5BF3,/* 0x90-0x97 */
 	0x5BF4,0x5BF5,0x5BF6,0x5BF7,0x5BFD,0x5BFE,0x5C00,0x5C02,/* 0x98-0x9F */
 	0x5C03,0x5C05,0x5C07,0x5C08,0x5C0B,0x5C0C,0x5C0D,0x5C0E,/* 0xA0-0xA7 */
@@ -437,7 +437,7 @@
 	0x5C2D,0x5C2E,0x5C2F,0x5C30,0x5C32,0x5C33,0x5C35,0x5C36,/* 0xB8-0xBF */
 	0x5C37,0x5C43,0x5C44,0x5C46,0x5C47,0x5C4C,0x5C4D,0x5C52,/* 0xC0-0xC7 */
 	0x5C53,0x5C54,0x5C56,0x5C57,0x5C58,0x5C5A,0x5C5B,0x5C5C,/* 0xC8-0xCF */
-	0x5C5D,0x5C5F,0xF94B,0x5C64,0x5C67,0x5C68,0x5C69,0x5C6A,/* 0xD0-0xD7 */
+	0x5C5D,0x5C5F,0x5C62,0x5C64,0x5C67,0x5C68,0x5C69,0x5C6A,/* 0xD0-0xD7 */
 	0x5C6B,0x5C6C,0x5C6D,0x5C70,0x5C72,0x5C73,0x5C74,0x5C75,/* 0xD8-0xDF */
 	0x5C76,0x5C77,0x5C78,0x5C7B,0x5C7C,0x5C7D,0x5C7E,0x5C80,/* 0xE0-0xE7 */
 	0x5C83,0x5C84,0x5C85,0x5C86,0x5C87,0x5C89,0x5C8A,0x5C8B,/* 0xE8-0xEF */
@@ -462,15 +462,15 @@
 	0x5CE2,0x5CE3,0x5CE7,0x5CE9,0x5CEB,0x5CEC,0x5CEE,0x5CEF,/* 0x68-0x6F */
 	0x5CF1,0x5CF2,0x5CF3,0x5CF4,0x5CF5,0x5CF6,0x5CF7,0x5CF8,/* 0x70-0x77 */
 	0x5CF9,0x5CFA,0x5CFC,0x5CFD,0x5CFE,0x5CFF,0x5D00,0x0000,/* 0x78-0x7F */
-	
+
 	0x5D01,0x5D04,0x5D05,0x5D08,0x5D09,0x5D0A,0x5D0B,0x5D0C,/* 0x80-0x87 */
 	0x5D0D,0x5D0F,0x5D10,0x5D11,0x5D12,0x5D13,0x5D15,0x5D17,/* 0x88-0x8F */
-	0x5D18,0xF9D5,0x5D1A,0x5D1C,0x5D1D,0x5D1F,0x5D20,0x5D21,/* 0x90-0x97 */
+	0x5D18,0x5D19,0x5D1A,0x5D1C,0x5D1D,0x5D1F,0x5D20,0x5D21,/* 0x90-0x97 */
 	0x5D22,0x5D23,0x5D25,0x5D28,0x5D2A,0x5D2B,0x5D2C,0x5D2F,/* 0x98-0x9F */
 	0x5D30,0x5D31,0x5D32,0x5D33,0x5D35,0x5D36,0x5D37,0x5D38,/* 0xA0-0xA7 */
 	0x5D39,0x5D3A,0x5D3B,0x5D3C,0x5D3F,0x5D40,0x5D41,0x5D42,/* 0xA8-0xAF */
 	0x5D43,0x5D44,0x5D45,0x5D46,0x5D48,0x5D49,0x5D4D,0x5D4E,/* 0xB0-0xB7 */
-	0x5D4F,0xF921,0x5D51,0x5D52,0x5D53,0x5D54,0x5D55,0x5D56,/* 0xB8-0xBF */
+	0x5D4F,0x5D50,0x5D51,0x5D52,0x5D53,0x5D54,0x5D55,0x5D56,/* 0xB8-0xBF */
 	0x5D57,0x5D59,0x5D5A,0x5D5C,0x5D5E,0x5D5F,0x5D60,0x5D61,/* 0xC0-0xC7 */
 	0x5D62,0x5D63,0x5D64,0x5D65,0x5D66,0x5D67,0x5D68,0x5D6A,/* 0xC8-0xCF */
 	0x5D6D,0x5D6E,0x5D70,0x5D71,0x5D72,0x5D73,0x5D75,0x5D76,/* 0xD0-0xD7 */
@@ -493,12 +493,12 @@
 	0x5DA1,0x5DA2,0x5DA3,0x5DA4,0x5DA5,0x5DA6,0x5DA7,0x5DA8,/* 0x40-0x47 */
 	0x5DA9,0x5DAA,0x5DAB,0x5DAC,0x5DAD,0x5DAE,0x5DAF,0x5DB0,/* 0x48-0x4F */
 	0x5DB1,0x5DB2,0x5DB3,0x5DB4,0x5DB5,0x5DB6,0x5DB8,0x5DB9,/* 0x50-0x57 */
-	0xF9AB,0x5DBB,0x5DBC,0x5DBD,0x5DBE,0x5DBF,0x5DC0,0x5DC1,/* 0x58-0x5F */
+	0x5DBA,0x5DBB,0x5DBC,0x5DBD,0x5DBE,0x5DBF,0x5DC0,0x5DC1,/* 0x58-0x5F */
 	0x5DC2,0x5DC3,0x5DC4,0x5DC6,0x5DC7,0x5DC8,0x5DC9,0x5DCA,/* 0x60-0x67 */
 	0x5DCB,0x5DCC,0x5DCE,0x5DCF,0x5DD0,0x5DD1,0x5DD2,0x5DD3,/* 0x68-0x6F */
 	0x5DD4,0x5DD5,0x5DD6,0x5DD7,0x5DD8,0x5DD9,0x5DDA,0x5DDC,/* 0x70-0x77 */
 	0x5DDF,0x5DE0,0x5DE3,0x5DE4,0x5DEA,0x5DEC,0x5DED,0x0000,/* 0x78-0x7F */
-	
+
 	0x5DF0,0x5DF5,0x5DF6,0x5DF8,0x5DF9,0x5DFA,0x5DFB,0x5DFC,/* 0x80-0x87 */
 	0x5DFF,0x5E00,0x5E04,0x5E07,0x5E09,0x5E0A,0x5E0B,0x5E0D,/* 0x88-0x8F */
 	0x5E0E,0x5E12,0x5E13,0x5E17,0x5E1E,0x5E1F,0x5E20,0x5E21,/* 0x90-0x97 */
@@ -529,12 +529,12 @@
 	0x5EC6,0x5EC7,0x5EC8,0x5ECB,0x5ECC,0x5ECD,0x5ECE,0x5ECF,/* 0x40-0x47 */
 	0x5ED0,0x5ED4,0x5ED5,0x5ED7,0x5ED8,0x5ED9,0x5EDA,0x5EDC,/* 0x48-0x4F */
 	0x5EDD,0x5EDE,0x5EDF,0x5EE0,0x5EE1,0x5EE2,0x5EE3,0x5EE4,/* 0x50-0x57 */
-	0x5EE5,0x5EE6,0x5EE7,0x5EE9,0x5EEB,0xF982,0x5EED,0x5EEE,/* 0x58-0x5F */
+	0x5EE5,0x5EE6,0x5EE7,0x5EE9,0x5EEB,0x5EEC,0x5EED,0x5EEE,/* 0x58-0x5F */
 	0x5EEF,0x5EF0,0x5EF1,0x5EF2,0x5EF3,0x5EF5,0x5EF8,0x5EF9,/* 0x60-0x67 */
 	0x5EFB,0x5EFC,0x5EFD,0x5F05,0x5F06,0x5F07,0x5F09,0x5F0C,/* 0x68-0x6F */
 	0x5F0D,0x5F0E,0x5F10,0x5F12,0x5F14,0x5F16,0x5F19,0x5F1A,/* 0x70-0x77 */
 	0x5F1C,0x5F1D,0x5F1E,0x5F21,0x5F22,0x5F23,0x5F24,0x0000,/* 0x78-0x7F */
-	
+
 	0x5F28,0x5F2B,0x5F2C,0x5F2E,0x5F30,0x5F32,0x5F33,0x5F34,/* 0x80-0x87 */
 	0x5F35,0x5F36,0x5F37,0x5F38,0x5F3B,0x5F3D,0x5F3E,0x5F3F,/* 0x88-0x8F */
 	0x5F41,0x5F42,0x5F43,0x5F44,0x5F45,0x5F46,0x5F47,0x5F48,/* 0x90-0x97 */
@@ -544,7 +544,7 @@
 	0x5F74,0x5F75,0x5F76,0x5F78,0x5F7A,0x5F7D,0x5F7E,0x5F7F,/* 0xB0-0xB7 */
 	0x5F83,0x5F86,0x5F8D,0x5F8E,0x5F8F,0x5F91,0x5F93,0x5F94,/* 0xB8-0xBF */
 	0x5F96,0x5F9A,0x5F9B,0x5F9D,0x5F9E,0x5F9F,0x5FA0,0x5FA2,/* 0xC0-0xC7 */
-	0x5FA3,0x5FA4,0x5FA5,0x5FA6,0x5FA7,0xF966,0x5FAB,0x5FAC,/* 0xC8-0xCF */
+	0x5FA3,0x5FA4,0x5FA5,0x5FA6,0x5FA7,0x5FA9,0x5FAB,0x5FAC,/* 0xC8-0xCF */
 	0x5FAF,0x5FB0,0x5FB1,0x5FB2,0x5FB3,0x5FB4,0x5FB6,0x5FB8,/* 0xD0-0xD7 */
 	0x5FB9,0x5FBA,0x5FBB,0x5FBE,0x5FBF,0x5FC0,0x5FC1,0x5FC2,/* 0xD8-0xDF */
 	0x5FC7,0x5FC8,0x5FCA,0x5FCB,0x5FCE,0x5FD3,0x5FD4,0x5FD5,/* 0xE0-0xE7 */
@@ -570,7 +570,7 @@
 	0x604F,0x6051,0x6053,0x6054,0x6056,0x6057,0x6058,0x605B,/* 0x68-0x6F */
 	0x605C,0x605E,0x605F,0x6060,0x6061,0x6065,0x6066,0x606E,/* 0x70-0x77 */
 	0x6071,0x6072,0x6074,0x6075,0x6077,0x607E,0x6080,0x0000,/* 0x78-0x7F */
-	
+
 	0x6081,0x6082,0x6085,0x6086,0x6087,0x6088,0x608A,0x608B,/* 0x80-0x87 */
 	0x608E,0x608F,0x6090,0x6091,0x6093,0x6095,0x6097,0x6098,/* 0x88-0x8F */
 	0x6099,0x609C,0x609E,0x60A1,0x60A2,0x60A4,0x60A5,0x60A7,/* 0x90-0x97 */
@@ -578,7 +578,7 @@
 	0x60B9,0x60BA,0x60BD,0x60BE,0x60BF,0x60C0,0x60C1,0x60C2,/* 0xA0-0xA7 */
 	0x60C3,0x60C4,0x60C7,0x60C8,0x60C9,0x60CC,0x60CD,0x60CE,/* 0xA8-0xAF */
 	0x60CF,0x60D0,0x60D2,0x60D3,0x60D4,0x60D6,0x60D7,0x60D9,/* 0xB0-0xB7 */
-	0x60DB,0x60DE,0xF9B9,0x60E2,0x60E3,0x60E4,0x60E5,0x60EA,/* 0xB8-0xBF */
+	0x60DB,0x60DE,0x60E1,0x60E2,0x60E3,0x60E4,0x60E5,0x60EA,/* 0xB8-0xBF */
 	0x60F1,0x60F2,0x60F5,0x60F7,0x60F8,0x60FB,0x60FC,0x60FD,/* 0xC0-0xC7 */
 	0x60FE,0x60FF,0x6102,0x6103,0x6104,0x6105,0x6107,0x610A,/* 0xC8-0xCF */
 	0x610B,0x610C,0x6110,0x6111,0x6112,0x6113,0x6114,0x6116,/* 0xD0-0xD7 */
@@ -586,7 +586,7 @@
 	0x6122,0x6125,0x6128,0x6129,0x612A,0x612C,0x612D,0x612E,/* 0xE0-0xE7 */
 	0x612F,0x6130,0x6131,0x6132,0x6133,0x6134,0x6135,0x6136,/* 0xE8-0xEF */
 	0x6137,0x6138,0x6139,0x613A,0x613B,0x613C,0x613D,0x613E,/* 0xF0-0xF7 */
-	0x6140,0x6141,0x6142,0x6143,0xF9D9,0x6145,0x6146,0x0000,/* 0xF8-0xFF */
+	0x6140,0x6141,0x6142,0x6143,0x6144,0x6145,0x6146,0x0000,/* 0xF8-0xFF */
 };
 
 static wchar_t c2u_91[256] = {
@@ -605,8 +605,8 @@
 	0x6172,0x6173,0x6174,0x6176,0x6178,0x6179,0x617A,0x617B,/* 0x60-0x67 */
 	0x617C,0x617D,0x617E,0x617F,0x6180,0x6181,0x6182,0x6183,/* 0x68-0x6F */
 	0x6184,0x6185,0x6186,0x6187,0x6188,0x6189,0x618A,0x618C,/* 0x70-0x77 */
-	0x618D,0x618F,0xF98F,0x6191,0x6192,0x6193,0x6195,0x0000,/* 0x78-0x7F */
-	
+	0x618D,0x618F,0x6190,0x6191,0x6192,0x6193,0x6195,0x0000,/* 0x78-0x7F */
+
 	0x6196,0x6197,0x6198,0x6199,0x619A,0x619B,0x619C,0x619E,/* 0x80-0x87 */
 	0x619F,0x61A0,0x61A1,0x61A2,0x61A3,0x61A4,0x61A5,0x61A6,/* 0x88-0x8F */
 	0x61AA,0x61AB,0x61AD,0x61AE,0x61AF,0x61B0,0x61B1,0x61B2,/* 0x90-0x97 */
@@ -617,8 +617,8 @@
 	0x61DC,0x61DD,0x61DE,0x61DF,0x61E0,0x61E1,0x61E2,0x61E3,/* 0xB8-0xBF */
 	0x61E4,0x61E5,0x61E7,0x61E8,0x61E9,0x61EA,0x61EB,0x61EC,/* 0xC0-0xC7 */
 	0x61ED,0x61EE,0x61EF,0x61F0,0x61F1,0x61F2,0x61F3,0x61F4,/* 0xC8-0xCF */
-	0xF90D,0x61F7,0x61F8,0x61F9,0x61FA,0x61FB,0x61FC,0x61FD,/* 0xD0-0xD7 */
-	0x61FE,0xF990,0x6201,0x6202,0x6203,0x6204,0x6205,0x6207,/* 0xD8-0xDF */
+	0x61F6,0x61F7,0x61F8,0x61F9,0x61FA,0x61FB,0x61FC,0x61FD,/* 0xD0-0xD7 */
+	0x61FE,0x6200,0x6201,0x6202,0x6203,0x6204,0x6205,0x6207,/* 0xD8-0xDF */
 	0x6209,0x6213,0x6214,0x6219,0x621C,0x621D,0x621E,0x6220,/* 0xE0-0xE7 */
 	0x6223,0x6226,0x6227,0x6228,0x6229,0x622B,0x622D,0x622F,/* 0xE8-0xEF */
 	0x6230,0x6231,0x6232,0x6235,0x6236,0x6238,0x6239,0x623A,/* 0xF0-0xF7 */
@@ -642,8 +642,8 @@
 	0x6299,0x629C,0x629D,0x629E,0x62A3,0x62A6,0x62A7,0x62A9,/* 0x68-0x6F */
 	0x62AA,0x62AD,0x62AE,0x62AF,0x62B0,0x62B2,0x62B3,0x62B4,/* 0x70-0x77 */
 	0x62B6,0x62B7,0x62B8,0x62BA,0x62BE,0x62C0,0x62C1,0x0000,/* 0x78-0x7F */
-	
-	0x62C3,0x62CB,0xF95B,0x62D1,0x62D5,0x62DD,0x62DE,0x62E0,/* 0x80-0x87 */
+
+	0x62C3,0x62CB,0x62CF,0x62D1,0x62D5,0x62DD,0x62DE,0x62E0,/* 0x80-0x87 */
 	0x62E1,0x62E4,0x62EA,0x62EB,0x62F0,0x62F2,0x62F5,0x62F8,/* 0x88-0x8F */
 	0x62F9,0x62FA,0x62FB,0x6300,0x6303,0x6304,0x6305,0x6306,/* 0x90-0x97 */
 	0x630A,0x630B,0x630C,0x630D,0x630F,0x6310,0x6312,0x6313,/* 0x98-0x9F */
@@ -678,7 +678,7 @@
 	0x63FE,0x6403,0x6404,0x6406,0x6407,0x6408,0x6409,0x640A,/* 0x68-0x6F */
 	0x640D,0x640E,0x6411,0x6412,0x6415,0x6416,0x6417,0x6418,/* 0x70-0x77 */
 	0x6419,0x641A,0x641D,0x641F,0x6422,0x6423,0x6424,0x0000,/* 0x78-0x7F */
-	
+
 	0x6425,0x6427,0x6428,0x6429,0x642B,0x642E,0x642F,0x6430,/* 0x80-0x87 */
 	0x6431,0x6432,0x6433,0x6435,0x6436,0x6437,0x6438,0x6439,/* 0x88-0x8F */
 	0x643B,0x643C,0x643E,0x6440,0x6442,0x6443,0x6449,0x644B,/* 0x90-0x97 */
@@ -689,10 +689,10 @@
 	0x6473,0x6474,0x6475,0x6476,0x6477,0x647B,0x647C,0x647D,/* 0xB8-0xBF */
 	0x647E,0x647F,0x6480,0x6481,0x6483,0x6486,0x6488,0x6489,/* 0xC0-0xC7 */
 	0x648A,0x648B,0x648C,0x648D,0x648E,0x648F,0x6490,0x6493,/* 0xC8-0xCF */
-	0x6494,0x6497,0x6498,0xF991,0x649B,0x649C,0x649D,0x649F,/* 0xD0-0xD7 */
+	0x6494,0x6497,0x6498,0x649A,0x649B,0x649C,0x649D,0x649F,/* 0xD0-0xD7 */
 	0x64A0,0x64A1,0x64A2,0x64A3,0x64A5,0x64A6,0x64A7,0x64A8,/* 0xD8-0xDF */
 	0x64AA,0x64AB,0x64AF,0x64B1,0x64B2,0x64B3,0x64B4,0x64B6,/* 0xE0-0xE7 */
-	0x64B9,0x64BB,0x64BD,0x64BE,0x64BF,0x64C1,0x64C3,0xF930,/* 0xE8-0xEF */
+	0x64B9,0x64BB,0x64BD,0x64BE,0x64BF,0x64C1,0x64C3,0x64C4,/* 0xE8-0xEF */
 	0x64C6,0x64C7,0x64C8,0x64C9,0x64CA,0x64CB,0x64CC,0x64CF,/* 0xF0-0xF7 */
 	0x64D1,0x64D3,0x64D4,0x64D5,0x64D6,0x64D9,0x64DA,0x0000,/* 0xF8-0xFF */
 };
@@ -714,14 +714,14 @@
 	0x6508,0x650A,0x650B,0x650C,0x650D,0x650E,0x650F,0x6510,/* 0x68-0x6F */
 	0x6511,0x6513,0x6514,0x6515,0x6516,0x6517,0x6519,0x651A,/* 0x70-0x77 */
 	0x651B,0x651C,0x651D,0x651E,0x651F,0x6520,0x6521,0x0000,/* 0x78-0x7F */
-	
+
 	0x6522,0x6523,0x6524,0x6526,0x6527,0x6528,0x6529,0x652A,/* 0x80-0x87 */
 	0x652C,0x652D,0x6530,0x6531,0x6532,0x6533,0x6537,0x653A,/* 0x88-0x8F */
 	0x653C,0x653D,0x6540,0x6541,0x6542,0x6543,0x6544,0x6546,/* 0x90-0x97 */
 	0x6547,0x654A,0x654B,0x654D,0x654E,0x6550,0x6552,0x6553,/* 0x98-0x9F */
 	0x6554,0x6557,0x6558,0x655A,0x655C,0x655F,0x6560,0x6561,/* 0xA0-0xA7 */
 	0x6564,0x6565,0x6567,0x6568,0x6569,0x656A,0x656D,0x656E,/* 0xA8-0xAF */
-	0x656F,0x6571,0x6573,0x6575,0x6576,0xF969,0x6579,0x657A,/* 0xB0-0xB7 */
+	0x656F,0x6571,0x6573,0x6575,0x6576,0x6578,0x6579,0x657A,/* 0xB0-0xB7 */
 	0x657B,0x657C,0x657D,0x657E,0x657F,0x6580,0x6581,0x6582,/* 0xB8-0xBF */
 	0x6583,0x6584,0x6585,0x6586,0x6588,0x6589,0x658A,0x658D,/* 0xC0-0xC7 */
 	0x658E,0x658F,0x6592,0x6594,0x6595,0x6596,0x6598,0x659A,/* 0xC8-0xCF */
@@ -750,18 +750,18 @@
 	0x6632,0x6633,0x6637,0x6638,0x6639,0x663A,0x663B,0x663D,/* 0x68-0x6F */
 	0x663F,0x6640,0x6642,0x6644,0x6645,0x6646,0x6647,0x6648,/* 0x70-0x77 */
 	0x6649,0x664A,0x664D,0x664E,0x6650,0x6651,0x6658,0x0000,/* 0x78-0x7F */
-	
+
 	0x6659,0x665B,0x665C,0x665D,0x665E,0x6660,0x6662,0x6663,/* 0x80-0x87 */
 	0x6665,0x6667,0x6669,0x666A,0x666B,0x666C,0x666D,0x6671,/* 0x88-0x8F */
 	0x6672,0x6673,0x6675,0x6678,0x6679,0x667B,0x667C,0x667D,/* 0x90-0x97 */
-	0x667F,0x6680,0x6681,0x6683,0x6685,0x6686,0xF9C5,0x6689,/* 0x98-0x9F */
+	0x667F,0x6680,0x6681,0x6683,0x6685,0x6686,0x6688,0x6689,/* 0x98-0x9F */
 	0x668A,0x668B,0x668D,0x668E,0x668F,0x6690,0x6692,0x6693,/* 0xA0-0xA7 */
 	0x6694,0x6695,0x6698,0x6699,0x669A,0x669B,0x669C,0x669E,/* 0xA8-0xAF */
 	0x669F,0x66A0,0x66A1,0x66A2,0x66A3,0x66A4,0x66A5,0x66A6,/* 0xB0-0xB7 */
 	0x66A9,0x66AA,0x66AB,0x66AC,0x66AD,0x66AF,0x66B0,0x66B1,/* 0xB8-0xBF */
 	0x66B2,0x66B3,0x66B5,0x66B6,0x66B7,0x66B8,0x66BA,0x66BB,/* 0xC0-0xC7 */
 	0x66BC,0x66BD,0x66BF,0x66C0,0x66C1,0x66C2,0x66C3,0x66C4,/* 0xC8-0xCF */
-	0x66C5,0xF98B,0x66C7,0x66C8,0x66C9,0x66CA,0x66CB,0x66CC,/* 0xD0-0xD7 */
+	0x66C5,0x66C6,0x66C7,0x66C8,0x66C9,0x66CA,0x66CB,0x66CC,/* 0xD0-0xD7 */
 	0x66CD,0x66CE,0x66CF,0x66D0,0x66D1,0x66D2,0x66D3,0x66D4,/* 0xD8-0xDF */
 	0x66D5,0x66D6,0x66D7,0x66D8,0x66DA,0x66DE,0x66DF,0x66E0,/* 0xE0-0xE7 */
 	0x66E1,0x66E2,0x66E3,0x66E4,0x66E5,0x66E7,0x66E8,0x66EA,/* 0xE8-0xEF */
@@ -786,8 +786,8 @@
 	0x674A,0x674B,0x674D,0x6752,0x6754,0x6755,0x6757,0x6758,/* 0x68-0x6F */
 	0x6759,0x675A,0x675B,0x675D,0x6762,0x6763,0x6764,0x6766,/* 0x70-0x77 */
 	0x6767,0x676B,0x676C,0x676E,0x6771,0x6774,0x6776,0x0000,/* 0x78-0x7F */
-	
-	0x6778,0x6779,0x677A,0xF9C8,0x677D,0x6780,0x6782,0x6783,/* 0x80-0x87 */
+
+	0x6778,0x6779,0x677A,0x677B,0x677D,0x6780,0x6782,0x6783,/* 0x80-0x87 */
 	0x6785,0x6786,0x6788,0x678A,0x678C,0x678D,0x678E,0x678F,/* 0x88-0x8F */
 	0x6791,0x6792,0x6793,0x6794,0x6796,0x6799,0x679B,0x679F,/* 0x90-0x97 */
 	0x67A0,0x67A1,0x67A4,0x67A6,0x67A9,0x67AC,0x67AE,0x67B1,/* 0x98-0x9F */
@@ -822,7 +822,7 @@
 	0x6899,0x689A,0x689B,0x689C,0x689D,0x689E,0x689F,0x68A0,/* 0x68-0x6F */
 	0x68A1,0x68A3,0x68A4,0x68A5,0x68A9,0x68AA,0x68AB,0x68AC,/* 0x70-0x77 */
 	0x68AE,0x68B1,0x68B2,0x68B4,0x68B6,0x68B7,0x68B8,0x0000,/* 0x78-0x7F */
-	
+
 	0x68B9,0x68BA,0x68BB,0x68BC,0x68BD,0x68BE,0x68BF,0x68C1,/* 0x80-0x87 */
 	0x68C3,0x68C4,0x68C5,0x68C6,0x68C7,0x68C8,0x68CA,0x68CC,/* 0x88-0x8F */
 	0x68CE,0x68CF,0x68D0,0x68D1,0x68D3,0x68D4,0x68D6,0x68D7,/* 0x90-0x97 */
@@ -858,16 +858,16 @@
 	0x699F,0x69A0,0x69A1,0x69A2,0x69A3,0x69A4,0x69A5,0x69A6,/* 0x68-0x6F */
 	0x69A9,0x69AA,0x69AC,0x69AE,0x69AF,0x69B0,0x69B2,0x69B3,/* 0x70-0x77 */
 	0x69B5,0x69B6,0x69B8,0x69B9,0x69BA,0x69BC,0x69BD,0x0000,/* 0x78-0x7F */
-	
+
 	0x69BE,0x69BF,0x69C0,0x69C2,0x69C3,0x69C4,0x69C5,0x69C6,/* 0x80-0x87 */
 	0x69C7,0x69C8,0x69C9,0x69CB,0x69CD,0x69CF,0x69D1,0x69D2,/* 0x88-0x8F */
 	0x69D3,0x69D5,0x69D6,0x69D7,0x69D8,0x69D9,0x69DA,0x69DC,/* 0x90-0x97 */
 	0x69DD,0x69DE,0x69E1,0x69E2,0x69E3,0x69E4,0x69E5,0x69E6,/* 0x98-0x9F */
 	0x69E7,0x69E8,0x69E9,0x69EA,0x69EB,0x69EC,0x69EE,0x69EF,/* 0xA0-0xA7 */
 	0x69F0,0x69F1,0x69F3,0x69F4,0x69F5,0x69F6,0x69F7,0x69F8,/* 0xA8-0xAF */
-	0x69F9,0x69FA,0x69FB,0x69FC,0x69FE,0x6A00,0x6A01,0xF9BF,/* 0xB0-0xB7 */
+	0x69F9,0x69FA,0x69FB,0x69FC,0x69FE,0x6A00,0x6A01,0x6A02,/* 0xB0-0xB7 */
 	0x6A03,0x6A04,0x6A05,0x6A06,0x6A07,0x6A08,0x6A09,0x6A0B,/* 0xB8-0xBF */
-	0x6A0C,0x6A0D,0x6A0E,0x6A0F,0x6A10,0x6A11,0x6A12,0xF94C,/* 0xC0-0xC7 */
+	0x6A0C,0x6A0D,0x6A0E,0x6A0F,0x6A10,0x6A11,0x6A12,0x6A13,/* 0xC0-0xC7 */
 	0x6A14,0x6A15,0x6A16,0x6A19,0x6A1A,0x6A1B,0x6A1C,0x6A1D,/* 0xC8-0xCF */
 	0x6A1E,0x6A20,0x6A22,0x6A23,0x6A24,0x6A25,0x6A26,0x6A27,/* 0xD0-0xD7 */
 	0x6A29,0x6A2B,0x6A2C,0x6A2D,0x6A2E,0x6A30,0x6A32,0x6A33,/* 0xD8-0xDF */
@@ -894,19 +894,19 @@
 	0x6A8B,0x6A8C,0x6A8D,0x6A8F,0x6A92,0x6A93,0x6A94,0x6A95,/* 0x68-0x6F */
 	0x6A96,0x6A98,0x6A99,0x6A9A,0x6A9B,0x6A9C,0x6A9D,0x6A9E,/* 0x70-0x77 */
 	0x6A9F,0x6AA1,0x6AA2,0x6AA3,0x6AA4,0x6AA5,0x6AA6,0x0000,/* 0x78-0x7F */
-	
+
 	0x6AA7,0x6AA8,0x6AAA,0x6AAD,0x6AAE,0x6AAF,0x6AB0,0x6AB1,/* 0x80-0x87 */
 	0x6AB2,0x6AB3,0x6AB4,0x6AB5,0x6AB6,0x6AB7,0x6AB8,0x6AB9,/* 0x88-0x8F */
 	0x6ABA,0x6ABB,0x6ABC,0x6ABD,0x6ABE,0x6ABF,0x6AC0,0x6AC1,/* 0x90-0x97 */
 	0x6AC2,0x6AC3,0x6AC4,0x6AC5,0x6AC6,0x6AC7,0x6AC8,0x6AC9,/* 0x98-0x9F */
 	0x6ACA,0x6ACB,0x6ACC,0x6ACD,0x6ACE,0x6ACF,0x6AD0,0x6AD1,/* 0xA0-0xA7 */
-	0x6AD2,0xF931,0x6AD4,0x6AD5,0x6AD6,0x6AD7,0x6AD8,0x6AD9,/* 0xA8-0xAF */
+	0x6AD2,0x6AD3,0x6AD4,0x6AD5,0x6AD6,0x6AD7,0x6AD8,0x6AD9,/* 0xA8-0xAF */
 	0x6ADA,0x6ADB,0x6ADC,0x6ADD,0x6ADE,0x6ADF,0x6AE0,0x6AE1,/* 0xB0-0xB7 */
 	0x6AE2,0x6AE3,0x6AE4,0x6AE5,0x6AE6,0x6AE7,0x6AE8,0x6AE9,/* 0xB8-0xBF */
 	0x6AEA,0x6AEB,0x6AEC,0x6AED,0x6AEE,0x6AEF,0x6AF0,0x6AF1,/* 0xC0-0xC7 */
 	0x6AF2,0x6AF3,0x6AF4,0x6AF5,0x6AF6,0x6AF7,0x6AF8,0x6AF9,/* 0xC8-0xCF */
 	0x6AFA,0x6AFB,0x6AFC,0x6AFD,0x6AFE,0x6AFF,0x6B00,0x6B01,/* 0xD0-0xD7 */
-	0x6B02,0x6B03,0xF91D,0x6B05,0x6B06,0x6B07,0x6B08,0x6B09,/* 0xD8-0xDF */
+	0x6B02,0x6B03,0x6B04,0x6B05,0x6B06,0x6B07,0x6B08,0x6B09,/* 0xD8-0xDF */
 	0x6B0A,0x6B0B,0x6B0C,0x6B0D,0x6B0E,0x6B0F,0x6B10,0x6B11,/* 0xE0-0xE7 */
 	0x6B12,0x6B13,0x6B14,0x6B15,0x6B16,0x6B17,0x6B18,0x6B19,/* 0xE8-0xEF */
 	0x6B1A,0x6B1B,0x6B1C,0x6B1D,0x6B1E,0x6B1F,0x6B25,0x6B26,/* 0xF0-0xF7 */
@@ -928,14 +928,14 @@
 	0x6B51,0x6B52,0x6B53,0x6B54,0x6B55,0x6B56,0x6B57,0x6B58,/* 0x58-0x5F */
 	0x6B5A,0x6B5B,0x6B5C,0x6B5D,0x6B5E,0x6B5F,0x6B60,0x6B61,/* 0x60-0x67 */
 	0x6B68,0x6B69,0x6B6B,0x6B6C,0x6B6D,0x6B6E,0x6B6F,0x6B70,/* 0x68-0x6F */
-	0x6B71,0x6B72,0x6B73,0x6B74,0x6B75,0x6B76,0xF98C,0x6B78,/* 0x70-0x77 */
+	0x6B71,0x6B72,0x6B73,0x6B74,0x6B75,0x6B76,0x6B77,0x6B78,/* 0x70-0x77 */
 	0x6B7A,0x6B7D,0x6B7E,0x6B7F,0x6B80,0x6B85,0x6B88,0x0000,/* 0x78-0x7F */
-	
+
 	0x6B8C,0x6B8E,0x6B8F,0x6B90,0x6B91,0x6B94,0x6B95,0x6B97,/* 0x80-0x87 */
 	0x6B98,0x6B99,0x6B9C,0x6B9D,0x6B9E,0x6B9F,0x6BA0,0x6BA2,/* 0x88-0x8F */
 	0x6BA3,0x6BA4,0x6BA5,0x6BA6,0x6BA7,0x6BA8,0x6BA9,0x6BAB,/* 0x90-0x97 */
-	0x6BAC,0x6BAD,0xF9A5,0x6BAF,0x6BB0,0x6BB1,0x6BB2,0x6BB6,/* 0x98-0x9F */
-	0x6BB8,0x6BB9,0xF970,0x6BBB,0x6BBC,0x6BBD,0x6BBE,0x6BC0,/* 0xA0-0xA7 */
+	0x6BAC,0x6BAD,0x6BAE,0x6BAF,0x6BB0,0x6BB1,0x6BB2,0x6BB6,/* 0x98-0x9F */
+	0x6BB8,0x6BB9,0x6BBA,0x6BBB,0x6BBC,0x6BBD,0x6BBE,0x6BC0,/* 0xA0-0xA7 */
 	0x6BC3,0x6BC4,0x6BC6,0x6BC7,0x6BC8,0x6BC9,0x6BCA,0x6BCC,/* 0xA8-0xAF */
 	0x6BCE,0x6BD0,0x6BD1,0x6BD8,0x6BDA,0x6BDC,0x6BDD,0x6BDE,/* 0xB0-0xB7 */
 	0x6BDF,0x6BE0,0x6BE2,0x6BE3,0x6BE4,0x6BE5,0x6BE6,0x6BE7,/* 0xB8-0xBF */
@@ -966,7 +966,7 @@
 	0x6CA8,0x6CAC,0x6CAF,0x6CB0,0x6CB4,0x6CB5,0x6CB6,0x6CB7,/* 0x68-0x6F */
 	0x6CBA,0x6CC0,0x6CC1,0x6CC2,0x6CC3,0x6CC6,0x6CC7,0x6CC8,/* 0x70-0x77 */
 	0x6CCB,0x6CCD,0x6CCE,0x6CCF,0x6CD1,0x6CD2,0x6CD8,0x0000,/* 0x78-0x7F */
-	
+
 	0x6CD9,0x6CDA,0x6CDC,0x6CDD,0x6CDF,0x6CE4,0x6CE6,0x6CE7,/* 0x80-0x87 */
 	0x6CE9,0x6CEC,0x6CED,0x6CF2,0x6CF4,0x6CF9,0x6CFF,0x6D00,/* 0x88-0x8F */
 	0x6D02,0x6D03,0x6D05,0x6D06,0x6D08,0x6D09,0x6D0A,0x6D0D,/* 0x90-0x97 */
@@ -995,14 +995,14 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x30-0x37 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x38-0x3F */
 	0x6DCD,0x6DCE,0x6DCF,0x6DD0,0x6DD2,0x6DD3,0x6DD4,0x6DD5,/* 0x40-0x47 */
-	0x6DD7,0xF94D,0x6DDB,0x6DDC,0x6DDF,0x6DE2,0x6DE3,0x6DE5,/* 0x48-0x4F */
-	0x6DE7,0x6DE8,0x6DE9,0xF9D6,0x6DED,0x6DEF,0x6DF0,0x6DF2,/* 0x50-0x57 */
+	0x6DD7,0x6DDA,0x6DDB,0x6DDC,0x6DDF,0x6DE2,0x6DE3,0x6DE5,/* 0x48-0x4F */
+	0x6DE7,0x6DE8,0x6DE9,0x6DEA,0x6DED,0x6DEF,0x6DF0,0x6DF2,/* 0x50-0x57 */
 	0x6DF4,0x6DF5,0x6DF6,0x6DF8,0x6DFA,0x6DFD,0x6DFE,0x6DFF,/* 0x58-0x5F */
 	0x6E00,0x6E01,0x6E02,0x6E03,0x6E04,0x6E06,0x6E07,0x6E08,/* 0x60-0x67 */
 	0x6E09,0x6E0B,0x6E0F,0x6E12,0x6E13,0x6E15,0x6E18,0x6E19,/* 0x68-0x6F */
 	0x6E1B,0x6E1C,0x6E1E,0x6E1F,0x6E22,0x6E26,0x6E27,0x6E28,/* 0x70-0x77 */
 	0x6E2A,0x6E2C,0x6E2E,0x6E30,0x6E31,0x6E33,0x6E35,0x0000,/* 0x78-0x7F */
-	
+
 	0x6E36,0x6E37,0x6E39,0x6E3B,0x6E3C,0x6E3D,0x6E3E,0x6E3F,/* 0x80-0x87 */
 	0x6E40,0x6E41,0x6E42,0x6E45,0x6E46,0x6E47,0x6E48,0x6E49,/* 0x88-0x8F */
 	0x6E4A,0x6E4B,0x6E4C,0x6E4F,0x6E50,0x6E51,0x6E52,0x6E55,/* 0x90-0x97 */
@@ -1035,10 +1035,10 @@
 	0x6F03,0x6F04,0x6F05,0x6F07,0x6F08,0x6F0A,0x6F0B,0x6F0C,/* 0x50-0x57 */
 	0x6F0D,0x6F0E,0x6F10,0x6F11,0x6F12,0x6F16,0x6F17,0x6F18,/* 0x58-0x5F */
 	0x6F19,0x6F1A,0x6F1B,0x6F1C,0x6F1D,0x6F1E,0x6F1F,0x6F21,/* 0x60-0x67 */
-	0x6F22,0xF992,0x6F25,0x6F26,0x6F27,0x6F28,0x6F2C,0x6F2E,/* 0x68-0x6F */
+	0x6F22,0x6F23,0x6F25,0x6F26,0x6F27,0x6F28,0x6F2C,0x6F2E,/* 0x68-0x6F */
 	0x6F30,0x6F32,0x6F34,0x6F35,0x6F37,0x6F38,0x6F39,0x6F3A,/* 0x70-0x77 */
 	0x6F3B,0x6F3C,0x6F3D,0x6F3F,0x6F40,0x6F41,0x6F42,0x0000,/* 0x78-0x7F */
-	
+
 	0x6F43,0x6F44,0x6F45,0x6F48,0x6F49,0x6F4A,0x6F4C,0x6F4E,/* 0x80-0x87 */
 	0x6F4F,0x6F50,0x6F51,0x6F52,0x6F53,0x6F54,0x6F55,0x6F56,/* 0x88-0x8F */
 	0x6F57,0x6F59,0x6F5A,0x6F5B,0x6F5D,0x6F5F,0x6F60,0x6F61,/* 0x90-0x97 */
@@ -1066,15 +1066,15 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x28-0x2F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x30-0x37 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x38-0x3F */
-	0x6FE6,0x6FE7,0x6FE8,0x6FE9,0x6FEA,0xF922,0x6FEC,0x6FED,/* 0x40-0x47 */
+	0x6FE6,0x6FE7,0x6FE8,0x6FE9,0x6FEA,0x6FEB,0x6FEC,0x6FED,/* 0x40-0x47 */
 	0x6FF0,0x6FF1,0x6FF2,0x6FF3,0x6FF4,0x6FF5,0x6FF6,0x6FF7,/* 0x48-0x4F */
-	0x6FF8,0x6FF9,0x6FFA,0x6FFB,0x6FFC,0x6FFD,0xF984,0x6FFF,/* 0x50-0x57 */
+	0x6FF8,0x6FF9,0x6FFA,0x6FFB,0x6FFC,0x6FFD,0x6FFE,0x6FFF,/* 0x50-0x57 */
 	0x7000,0x7001,0x7002,0x7003,0x7004,0x7005,0x7006,0x7007,/* 0x58-0x5F */
 	0x7008,0x7009,0x700A,0x700B,0x700C,0x700D,0x700E,0x700F,/* 0x60-0x67 */
 	0x7010,0x7012,0x7013,0x7014,0x7015,0x7016,0x7017,0x7018,/* 0x68-0x6F */
 	0x7019,0x701C,0x701D,0x701E,0x701F,0x7020,0x7021,0x7022,/* 0x70-0x77 */
 	0x7024,0x7025,0x7026,0x7027,0x7028,0x7029,0x702A,0x0000,/* 0x78-0x7F */
-	
+
 	0x702B,0x702C,0x702D,0x702E,0x702F,0x7030,0x7031,0x7032,/* 0x80-0x87 */
 	0x7033,0x7034,0x7036,0x7037,0x7038,0x703A,0x703B,0x703C,/* 0x88-0x8F */
 	0x703D,0x703E,0x703F,0x7040,0x7041,0x7042,0x7043,0x7044,/* 0x90-0x97 */
@@ -1110,10 +1110,10 @@
 	0x7117,0x711B,0x711C,0x711D,0x711E,0x711F,0x7120,0x7121,/* 0x68-0x6F */
 	0x7122,0x7123,0x7124,0x7125,0x7127,0x7128,0x7129,0x712A,/* 0x70-0x77 */
 	0x712B,0x712C,0x712D,0x712E,0x7132,0x7133,0x7134,0x0000,/* 0x78-0x7F */
-	
+
 	0x7135,0x7137,0x7138,0x7139,0x713A,0x713B,0x713C,0x713D,/* 0x80-0x87 */
 	0x713E,0x713F,0x7140,0x7141,0x7142,0x7143,0x7144,0x7146,/* 0x88-0x8F */
-	0x7147,0x7148,0xF993,0x714B,0x714D,0x714F,0x7150,0x7151,/* 0x90-0x97 */
+	0x7147,0x7148,0x7149,0x714B,0x714D,0x714F,0x7150,0x7151,/* 0x90-0x97 */
 	0x7152,0x7153,0x7154,0x7155,0x7156,0x7157,0x7158,0x7159,/* 0x98-0x9F */
 	0x715A,0x715B,0x715D,0x715F,0x7160,0x7161,0x7162,0x7163,/* 0xA0-0xA7 */
 	0x7165,0x7169,0x716A,0x716B,0x716C,0x716D,0x716F,0x7170,/* 0xA8-0xAF */
@@ -1126,7 +1126,7 @@
 	0x71B0,0x71B1,0x71B2,0x71B4,0x71B6,0x71B7,0x71B8,0x71BA,/* 0xE0-0xE7 */
 	0x71BB,0x71BC,0x71BD,0x71BE,0x71BF,0x71C0,0x71C1,0x71C2,/* 0xE8-0xEF */
 	0x71C4,0x71C5,0x71C6,0x71C7,0x71C8,0x71C9,0x71CA,0x71CB,/* 0xF0-0xF7 */
-	0x71CC,0x71CD,0x71CF,0xF9EE,0x71D1,0x71D2,0x71D3,0x0000,/* 0xF8-0xFF */
+	0x71CC,0x71CD,0x71CF,0x71D0,0x71D1,0x71D2,0x71D3,0x0000,/* 0xF8-0xFF */
 };
 
 static wchar_t c2u_A0[256] = {
@@ -1144,10 +1144,10 @@
 	0x71F2,0x71F3,0x71F4,0x71F5,0x71F6,0x71F7,0x71F8,0x71FA,/* 0x58-0x5F */
 	0x71FB,0x71FC,0x71FD,0x71FE,0x71FF,0x7200,0x7201,0x7202,/* 0x60-0x67 */
 	0x7203,0x7204,0x7205,0x7207,0x7208,0x7209,0x720A,0x720B,/* 0x68-0x6F */
-	0x720C,0x720D,0x720E,0x720F,0xF932,0x7211,0x7212,0x7213,/* 0x70-0x77 */
+	0x720C,0x720D,0x720E,0x720F,0x7210,0x7211,0x7212,0x7213,/* 0x70-0x77 */
 	0x7214,0x7215,0x7216,0x7217,0x7218,0x7219,0x721A,0x0000,/* 0x78-0x7F */
-	
-	0xF91E,0x721C,0x721E,0x721F,0x7220,0x7221,0x7222,0x7223,/* 0x80-0x87 */
+
+	0x721B,0x721C,0x721E,0x721F,0x7220,0x7221,0x7222,0x7223,/* 0x80-0x87 */
 	0x7224,0x7225,0x7226,0x7227,0x7229,0x722B,0x722D,0x722E,/* 0x88-0x8F */
 	0x722F,0x7232,0x7233,0x7234,0x723A,0x723C,0x723E,0x7240,/* 0x90-0x97 */
 	0x7241,0x7242,0x7243,0x7244,0x7245,0x7246,0x7249,0x724A,/* 0x98-0x9F */
@@ -1160,7 +1160,7 @@
 	0x7298,0x7299,0x729A,0x729B,0x729C,0x729D,0x729E,0x72A0,/* 0xD0-0xD7 */
 	0x72A1,0x72A2,0x72A3,0x72A4,0x72A5,0x72A6,0x72A7,0x72A8,/* 0xD8-0xDF */
 	0x72A9,0x72AA,0x72AB,0x72AE,0x72B1,0x72B2,0x72B3,0x72B5,/* 0xE0-0xE7 */
-	0x72BA,0x72BB,0x72BC,0x72BD,0x72BE,0x72BF,0xF9FA,0x72C5,/* 0xE8-0xEF */
+	0x72BA,0x72BB,0x72BC,0x72BD,0x72BE,0x72BF,0x72C0,0x72C5,/* 0xE8-0xEF */
 	0x72C6,0x72C7,0x72C9,0x72CA,0x72CB,0x72CC,0x72CF,0x72D1,/* 0xF0-0xF7 */
 	0x72D3,0x72D4,0x72D5,0x72D6,0x72D8,0x72DA,0x72DB,0x0000,/* 0xF8-0xFF */
 };
@@ -1182,7 +1182,7 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x68-0x6F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -1195,7 +1195,7 @@
 	0x222A,0x2229,0x2208,0x2237,0x221A,0x22A5,0x2225,0x2220,/* 0xC8-0xCF */
 	0x2312,0x2299,0x222B,0x222E,0x2261,0x224C,0x2248,0x223D,/* 0xD0-0xD7 */
 	0x221D,0x2260,0x226E,0x226F,0x2264,0x2265,0x221E,0x2235,/* 0xD8-0xDF */
-	0x2234,0x2642,0x2640,0x2218,0x2032,0x2033,0x2103,0xFF04,/* 0xE0-0xE7 */
+	0x2234,0x2642,0x2640,0x00B0,0x2032,0x2033,0x2103,0xFF04,/* 0xE0-0xE7 */
 	0x00A4,0xFFE0,0xFFE1,0x2030,0x00A7,0x2116,0x2606,0x2605,/* 0xE8-0xEF */
 	0x25CB,0x25CF,0x25CE,0x25C7,0x25C6,0x25A1,0x25A0,0x25B3,/* 0xF0-0xF7 */
 	0x25B2,0x203B,0x2192,0x2190,0x2191,0x2193,0x3013,0x0000,/* 0xF8-0xFF */
@@ -1218,7 +1218,7 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x68-0x6F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -1254,7 +1254,7 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x68-0x6F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -1290,7 +1290,7 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x68-0x6F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -1325,7 +1325,7 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x68-0x6F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -1360,7 +1360,7 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x68-0x6F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -1395,7 +1395,7 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x68-0x6F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -1430,7 +1430,7 @@
 	0x2564,0x2565,0x2566,0x2567,0x2568,0x2569,0x256A,0x256B,/* 0x68-0x6F */
 	0x256C,0x256D,0x256E,0x256F,0x2570,0x2571,0x2572,0x2573,/* 0x70-0x77 */
 	0x2581,0x2582,0x2583,0x2584,0x2585,0x2586,0x2587,0x0000,/* 0x78-0x7F */
-	
+
 	0x2588,0x2589,0x258A,0x258B,0x258C,0x258D,0x258E,0x258F,/* 0x80-0x87 */
 	0x2593,0x2594,0x2595,0x25BC,0x25BD,0x25E2,0x25E3,0x25E4,/* 0x88-0x8F */
 	0x25E5,0x2609,0x2295,0x3012,0x301D,0x301E,0x0000,0x0000,/* 0x90-0x97 */
@@ -1464,7 +1464,7 @@
 	0xFE49,0xFE4A,0xFE4B,0xFE4C,0xFE4D,0xFE4E,0xFE4F,0xFE50,/* 0x68-0x6F */
 	0xFE51,0xFE52,0xFE54,0xFE55,0xFE56,0xFE57,0xFE59,0xFE5A,/* 0x70-0x77 */
 	0xFE5B,0xFE5C,0xFE5D,0xFE5E,0xFE5F,0xFE60,0xFE61,0x0000,/* 0x78-0x7F */
-	
+
 	0xFE62,0xFE63,0xFE64,0xFE65,0xFE66,0xFE68,0xFE69,0xFE6A,/* 0x80-0x87 */
 	0xFE6B,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3007,0x0000,/* 0x90-0x97 */
@@ -1498,7 +1498,7 @@
 	0x7326,0x7327,0x7328,0x732D,0x732F,0x7330,0x7332,0x7333,/* 0x68-0x6F */
 	0x7335,0x7336,0x733A,0x733B,0x733C,0x733D,0x7340,0x7341,/* 0x70-0x77 */
 	0x7342,0x7343,0x7344,0x7345,0x7346,0x7347,0x7348,0x0000,/* 0x78-0x7F */
-	
+
 	0x7349,0x734A,0x734B,0x734C,0x734E,0x734F,0x7351,0x7353,/* 0x80-0x87 */
 	0x7354,0x7355,0x7356,0x7358,0x7359,0x735A,0x735B,0x735C,/* 0x88-0x8F */
 	0x735D,0x735E,0x735F,0x7361,0x7362,0x7363,0x7364,0x7365,/* 0x90-0x97 */
@@ -1515,7 +1515,7 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x28-0x2F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x30-0x37 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x38-0x3F */
-	0x7372,0x7373,0x7374,0xF9A7,0x7376,0x7377,0x7378,0x7379,/* 0x40-0x47 */
+	0x7372,0x7373,0x7374,0x7375,0x7376,0x7377,0x7378,0x7379,/* 0x40-0x47 */
 	0x737A,0x737B,0x737C,0x737D,0x737F,0x7380,0x7381,0x7382,/* 0x48-0x4F */
 	0x7383,0x7385,0x7386,0x7388,0x738A,0x738C,0x738D,0x738F,/* 0x50-0x57 */
 	0x7390,0x7392,0x7393,0x7394,0x7395,0x7397,0x7398,0x7399,/* 0x58-0x5F */
@@ -1523,7 +1523,7 @@
 	0x73A5,0x73A6,0x73A7,0x73A8,0x73AA,0x73AC,0x73AD,0x73B1,/* 0x68-0x6F */
 	0x73B4,0x73B5,0x73B6,0x73B8,0x73B9,0x73BC,0x73BD,0x73BE,/* 0x70-0x77 */
 	0x73BF,0x73C1,0x73C3,0x73C4,0x73C5,0x73C6,0x73C7,0x0000,/* 0x78-0x7F */
-	
+
 	0x73CB,0x73CC,0x73CE,0x73D2,0x73D3,0x73D4,0x73D5,0x73D6,/* 0x80-0x87 */
 	0x73D7,0x73D8,0x73DA,0x73DB,0x73DC,0x73DD,0x73DF,0x73E1,/* 0x88-0x8F */
 	0x73E2,0x73E3,0x73E4,0x73E6,0x73E8,0x73EA,0x73EB,0x73EC,/* 0x90-0x97 */
@@ -1548,10 +1548,10 @@
 	0x7431,0x7432,0x7437,0x7438,0x7439,0x743A,0x743B,0x743D,/* 0x68-0x6F */
 	0x743E,0x743F,0x7440,0x7442,0x7443,0x7444,0x7445,0x7446,/* 0x70-0x77 */
 	0x7447,0x7448,0x7449,0x744A,0x744B,0x744C,0x744D,0x0000,/* 0x78-0x7F */
-	
+
 	0x744E,0x744F,0x7450,0x7451,0x7452,0x7453,0x7454,0x7456,/* 0x80-0x87 */
 	0x7458,0x745D,0x7460,0x7461,0x7462,0x7463,0x7464,0x7465,/* 0x88-0x8F */
-	0x7466,0x7467,0x7468,0xF9AE,0x746A,0x746B,0x746C,0x746E,/* 0x90-0x97 */
+	0x7466,0x7467,0x7468,0x7469,0x746A,0x746B,0x746C,0x746E,/* 0x90-0x97 */
 	0x746F,0x7471,0x7472,0x7473,0x7474,0x7475,0x7478,0x7479,/* 0x98-0x9F */
 	0x747A,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0xA0-0xA7 */
 };
@@ -1566,14 +1566,14 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x30-0x37 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x38-0x3F */
 	0x747B,0x747C,0x747D,0x747F,0x7482,0x7484,0x7485,0x7486,/* 0x40-0x47 */
-	0x7488,0xF994,0x748A,0x748C,0x748D,0x748F,0x7491,0x7492,/* 0x48-0x4F */
-	0x7493,0x7494,0x7495,0x7496,0x7497,0xF9EF,0x7499,0x749A,/* 0x50-0x57 */
+	0x7488,0x7489,0x748A,0x748C,0x748D,0x748F,0x7491,0x7492,/* 0x48-0x4F */
+	0x7493,0x7494,0x7495,0x7496,0x7497,0x7498,0x7499,0x749A,/* 0x50-0x57 */
 	0x749B,0x749D,0x749F,0x74A0,0x74A1,0x74A2,0x74A3,0x74A4,/* 0x58-0x5F */
 	0x74A5,0x74A6,0x74AA,0x74AB,0x74AC,0x74AD,0x74AE,0x74AF,/* 0x60-0x67 */
 	0x74B0,0x74B1,0x74B2,0x74B3,0x74B4,0x74B5,0x74B6,0x74B7,/* 0x68-0x6F */
 	0x74B8,0x74B9,0x74BB,0x74BC,0x74BD,0x74BE,0x74BF,0x74C0,/* 0x70-0x77 */
 	0x74C1,0x74C2,0x74C3,0x74C4,0x74C5,0x74C6,0x74C7,0x0000,/* 0x78-0x7F */
-	
+
 	0x74C8,0x74C9,0x74CA,0x74CB,0x74CC,0x74CD,0x74CE,0x74CF,/* 0x80-0x87 */
 	0x74D0,0x74D1,0x74D3,0x74D4,0x74D5,0x74D6,0x74D7,0x74D8,/* 0x88-0x8F */
 	0x74D9,0x74DA,0x74DB,0x74DD,0x74DF,0x74E1,0x74E5,0x74E7,/* 0x90-0x97 */
@@ -1598,10 +1598,10 @@
 	0x7534,0x7536,0x7539,0x753C,0x753D,0x753F,0x7541,0x7542,/* 0x68-0x6F */
 	0x7543,0x7544,0x7546,0x7547,0x7549,0x754A,0x754D,0x7550,/* 0x70-0x77 */
 	0x7551,0x7552,0x7553,0x7555,0x7556,0x7557,0x7558,0x0000,/* 0x78-0x7F */
-	
+
 	0x755D,0x755E,0x755F,0x7560,0x7561,0x7562,0x7563,0x7564,/* 0x80-0x87 */
 	0x7567,0x7568,0x7569,0x756B,0x756C,0x756D,0x756E,0x756F,/* 0x88-0x8F */
-	0xF962,0x7571,0x7573,0x7575,0x7576,0x7577,0x757A,0x757B,/* 0x90-0x97 */
+	0x7570,0x7571,0x7573,0x7575,0x7576,0x7577,0x757A,0x757B,/* 0x90-0x97 */
 	0x757C,0x757D,0x757E,0x7580,0x7581,0x7582,0x7584,0x7585,/* 0x98-0x9F */
 	0x7587,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0xA0-0xA7 */
 };
@@ -1623,11 +1623,11 @@
 	0x75DF,0x75E0,0x75E1,0x75E5,0x75E9,0x75EC,0x75ED,0x75EE,/* 0x68-0x6F */
 	0x75EF,0x75F2,0x75F3,0x75F5,0x75F6,0x75F7,0x75F8,0x75FA,/* 0x70-0x77 */
 	0x75FB,0x75FD,0x75FE,0x7602,0x7604,0x7606,0x7607,0x0000,/* 0x78-0x7F */
-	
+
 	0x7608,0x7609,0x760B,0x760D,0x760E,0x760F,0x7611,0x7612,/* 0x80-0x87 */
 	0x7613,0x7614,0x7616,0x761A,0x761C,0x761D,0x761E,0x7621,/* 0x88-0x8F */
 	0x7623,0x7627,0x7628,0x762C,0x762E,0x762F,0x7631,0x7632,/* 0x90-0x97 */
-	0x7636,0x7637,0x7639,0x763A,0x763B,0x763D,0x7641,0xF9C1,/* 0x98-0x9F */
+	0x7636,0x7637,0x7639,0x763A,0x763B,0x763D,0x7641,0x7642,/* 0x98-0x9F */
 	0x7644,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0xA0-0xA7 */
 };
 
@@ -1643,12 +1643,12 @@
 	0x7645,0x7646,0x7647,0x7648,0x7649,0x764A,0x764B,0x764E,/* 0x40-0x47 */
 	0x764F,0x7650,0x7651,0x7652,0x7653,0x7655,0x7657,0x7658,/* 0x48-0x4F */
 	0x7659,0x765A,0x765B,0x765D,0x765F,0x7660,0x7661,0x7662,/* 0x50-0x57 */
-	0x7664,0x7665,0x7666,0x7667,0x7668,0xF90E,0x766A,0x766C,/* 0x58-0x5F */
+	0x7664,0x7665,0x7666,0x7667,0x7668,0x7669,0x766A,0x766C,/* 0x58-0x5F */
 	0x766D,0x766E,0x7670,0x7671,0x7672,0x7673,0x7674,0x7675,/* 0x60-0x67 */
 	0x7676,0x7677,0x7679,0x767A,0x767C,0x767F,0x7680,0x7681,/* 0x68-0x6F */
 	0x7683,0x7685,0x7689,0x768A,0x768C,0x768D,0x768F,0x7690,/* 0x70-0x77 */
 	0x7692,0x7694,0x7695,0x7697,0x7698,0x769A,0x769B,0x0000,/* 0x78-0x7F */
-	
+
 	0x769C,0x769D,0x769E,0x769F,0x76A0,0x76A1,0x76A2,0x76A3,/* 0x80-0x87 */
 	0x76A5,0x76A6,0x76A7,0x76A8,0x76A9,0x76AA,0x76AB,0x76AC,/* 0x88-0x8F */
 	0x76AD,0x76AF,0x76B0,0x76B3,0x76B5,0x76B6,0x76B7,0x76B8,/* 0x90-0x97 */
@@ -1678,26 +1678,26 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x38-0x3F */
 	0x76C4,0x76C7,0x76C9,0x76CB,0x76CC,0x76D3,0x76D5,0x76D9,/* 0x40-0x47 */
 	0x76DA,0x76DC,0x76DD,0x76DE,0x76E0,0x76E1,0x76E2,0x76E3,/* 0x48-0x4F */
-	0x76E4,0x76E6,0xF933,0x76E8,0x76E9,0x76EA,0x76EB,0x76EC,/* 0x50-0x57 */
+	0x76E4,0x76E6,0x76E7,0x76E8,0x76E9,0x76EA,0x76EB,0x76EC,/* 0x50-0x57 */
 	0x76ED,0x76F0,0x76F3,0x76F5,0x76F6,0x76F7,0x76FA,0x76FB,/* 0x58-0x5F */
 	0x76FD,0x76FF,0x7700,0x7702,0x7703,0x7705,0x7706,0x770A,/* 0x60-0x67 */
 	0x770C,0x770E,0x770F,0x7710,0x7711,0x7712,0x7713,0x7714,/* 0x68-0x6F */
 	0x7715,0x7716,0x7717,0x7718,0x771B,0x771C,0x771D,0x771E,/* 0x70-0x77 */
 	0x7721,0x7723,0x7724,0x7725,0x7727,0x772A,0x772B,0x0000,/* 0x78-0x7F */
-	
+
 	0x772C,0x772E,0x7730,0x7731,0x7732,0x7733,0x7734,0x7739,/* 0x80-0x87 */
 	0x773B,0x773D,0x773E,0x773F,0x7742,0x7744,0x7745,0x7746,/* 0x88-0x8F */
 	0x7748,0x7749,0x774A,0x774B,0x774C,0x774D,0x774E,0x774F,/* 0x90-0x97 */
 	0x7752,0x7753,0x7754,0x7755,0x7756,0x7757,0x7758,0x7759,/* 0x98-0x9F */
 	0x775C,0x8584,0x96F9,0x4FDD,0x5821,0x9971,0x5B9D,0x62B1,/* 0xA0-0xA7 */
-	0x62A5,0xFA06,0x8C79,0x9C8D,0x7206,0x676F,0x7891,0x60B2,/* 0xA8-0xAF */
-	0x5351,0xF963,0x8F88,0x80CC,0x8D1D,0x94A1,0x500D,0x72C8,/* 0xB0-0xB7 */
+	0x62A5,0x66B4,0x8C79,0x9C8D,0x7206,0x676F,0x7891,0x60B2,/* 0xA8-0xAF */
+	0x5351,0x5317,0x8F88,0x80CC,0x8D1D,0x94A1,0x500D,0x72C8,/* 0xB0-0xB7 */
 	0x5907,0x60EB,0x7119,0x88AB,0x5954,0x82EF,0x672C,0x7B28,/* 0xB8-0xBF */
 	0x5D29,0x7EF7,0x752D,0x6CF5,0x8E66,0x8FF8,0x903C,0x9F3B,/* 0xC0-0xC7 */
 	0x6BD4,0x9119,0x7B14,0x5F7C,0x78A7,0x84D6,0x853D,0x6BD5,/* 0xC8-0xCF */
 	0x6BD9,0x6BD6,0x5E01,0x5E87,0x75F9,0x95ED,0x655D,0x5F0A,/* 0xD0-0xD7 */
 	0x5FC5,0x8F9F,0x58C1,0x81C2,0x907F,0x965B,0x97AD,0x8FB9,/* 0xD8-0xDF */
-	0x7F16,0x8D2C,0x6241,0xF965,0x53D8,0x535E,0x8FA8,0x8FA9,/* 0xE0-0xE7 */
+	0x7F16,0x8D2C,0x6241,0x4FBF,0x53D8,0x535E,0x8FA8,0x8FA9,/* 0xE0-0xE7 */
 	0x8FAB,0x904D,0x6807,0x5F6A,0x8198,0x8868,0x9CD6,0x618B,/* 0xE8-0xEF */
 	0x522B,0x762A,0x5F6C,0x658C,0x6FD2,0x6EE8,0x5BBE,0x6448,/* 0xF0-0xF7 */
 	0x5175,0x51B0,0x67C4,0x4E19,0x79C9,0x997C,0x70B3,0x0000,/* 0xF8-0xFF */
@@ -1720,7 +1720,7 @@
 	0x7799,0x779A,0x779B,0x779C,0x779D,0x779E,0x77A1,0x77A3,/* 0x68-0x6F */
 	0x77A4,0x77A6,0x77A8,0x77AB,0x77AD,0x77AE,0x77AF,0x77B1,/* 0x70-0x77 */
 	0x77B2,0x77B4,0x77B6,0x77B7,0x77B8,0x77B9,0x77BA,0x0000,/* 0x78-0x7F */
-	
+
 	0x77BC,0x77BE,0x77C0,0x77C1,0x77C2,0x77C3,0x77C4,0x77C5,/* 0x80-0x87 */
 	0x77C6,0x77C7,0x77C8,0x77C9,0x77CA,0x77CB,0x77CC,0x77CE,/* 0x88-0x8F */
 	0x77CF,0x77D0,0x77D1,0x77D2,0x77D3,0x77D4,0x77D5,0x77D6,/* 0x90-0x97 */
@@ -1728,13 +1728,13 @@
 	0x77E4,0x75C5,0x5E76,0x73BB,0x83E0,0x64AD,0x62E8,0x94B5,/* 0xA0-0xA7 */
 	0x6CE2,0x535A,0x52C3,0x640F,0x94C2,0x7B94,0x4F2F,0x5E1B,/* 0xA8-0xAF */
 	0x8236,0x8116,0x818A,0x6E24,0x6CCA,0x9A73,0x6355,0x535C,/* 0xB0-0xB7 */
-	0x54FA,0x8865,0x57E0,0xF967,0x5E03,0x6B65,0x7C3F,0x90E8,/* 0xB8-0xBF */
+	0x54FA,0x8865,0x57E0,0x4E0D,0x5E03,0x6B65,0x7C3F,0x90E8,/* 0xB8-0xBF */
 	0x6016,0x64E6,0x731C,0x88C1,0x6750,0x624D,0x8D22,0x776C,/* 0xC0-0xC7 */
 	0x8E29,0x91C7,0x5F69,0x83DC,0x8521,0x9910,0x53C2,0x8695,/* 0xC8-0xCF */
 	0x6B8B,0x60ED,0x60E8,0x707F,0x82CD,0x8231,0x4ED3,0x6CA7,/* 0xD0-0xD7 */
 	0x85CF,0x64CD,0x7CD9,0x69FD,0x66F9,0x8349,0x5395,0x7B56,/* 0xD8-0xDF */
 	0x4FA7,0x518C,0x6D4B,0x5C42,0x8E6D,0x63D2,0x53C9,0x832C,/* 0xE0-0xE7 */
-	0xF9FE,0x67E5,0x78B4,0x643D,0x5BDF,0x5C94,0x5DEE,0x8BE7,/* 0xE8-0xEF */
+	0x8336,0x67E5,0x78B4,0x643D,0x5BDF,0x5C94,0x5DEE,0x8BE7,/* 0xE8-0xEF */
 	0x62C6,0x67F4,0x8C7A,0x6400,0x63BA,0x8749,0x998B,0x8C17,/* 0xF0-0xF7 */
 	0x7F20,0x94F2,0x4EA7,0x9610,0x98A4,0x660C,0x7316,0x0000,/* 0xF8-0xFF */
 };
@@ -1756,7 +1756,7 @@
 	0x7832,0x7833,0x7835,0x7836,0x783D,0x783F,0x7841,0x7842,/* 0x68-0x6F */
 	0x7843,0x7844,0x7846,0x7848,0x7849,0x784A,0x784B,0x784D,/* 0x70-0x77 */
 	0x784F,0x7851,0x7853,0x7854,0x7858,0x7859,0x785A,0x0000,/* 0x78-0x7F */
-	
+
 	0x785B,0x785C,0x785E,0x785F,0x7860,0x7861,0x7862,0x7863,/* 0x80-0x87 */
 	0x7864,0x7865,0x7866,0x7867,0x7868,0x7869,0x786F,0x7870,/* 0x88-0x8F */
 	0x7871,0x7872,0x7873,0x7874,0x7875,0x7876,0x7878,0x7879,/* 0x90-0x97 */
@@ -1764,7 +1764,7 @@
 	0x7883,0x573A,0x5C1D,0x5E38,0x957F,0x507F,0x80A0,0x5382,/* 0xA0-0xA7 */
 	0x655E,0x7545,0x5531,0x5021,0x8D85,0x6284,0x949E,0x671D,/* 0xA8-0xAF */
 	0x5632,0x6F6E,0x5DE2,0x5435,0x7092,0x8F66,0x626F,0x64A4,/* 0xB0-0xB7 */
-	0x63A3,0x5F7B,0x6F88,0x90F4,0x81E3,0xF971,0x5C18,0x6668,/* 0xB8-0xBF */
+	0x63A3,0x5F7B,0x6F88,0x90F4,0x81E3,0x8FB0,0x5C18,0x6668,/* 0xB8-0xBF */
 	0x5FF1,0x6C89,0x9648,0x8D81,0x886C,0x6491,0x79F0,0x57CE,/* 0xC0-0xC7 */
 	0x6A59,0x6210,0x5448,0x4E58,0x7A0B,0x60E9,0x6F84,0x8BDA,/* 0xC8-0xCF */
 	0x627F,0x901E,0x9A8B,0x79E4,0x5403,0x75F4,0x6301,0x5319,/* 0xD0-0xD7 */
@@ -1792,17 +1792,17 @@
 	0x78C6,0x78C7,0x78C8,0x78CC,0x78CD,0x78CE,0x78CF,0x78D1,/* 0x68-0x6F */
 	0x78D2,0x78D3,0x78D6,0x78D7,0x78D8,0x78DA,0x78DB,0x78DC,/* 0x70-0x77 */
 	0x78DD,0x78DE,0x78DF,0x78E0,0x78E1,0x78E2,0x78E3,0x0000,/* 0x78-0x7F */
-	
+
 	0x78E4,0x78E5,0x78E6,0x78E7,0x78E9,0x78EA,0x78EB,0x78ED,/* 0x80-0x87 */
 	0x78EE,0x78EF,0x78F0,0x78F1,0x78F3,0x78F5,0x78F6,0x78F8,/* 0x88-0x8F */
-	0x78F9,0xF964,0x78FC,0x78FD,0x78FE,0x78FF,0x7900,0x7902,/* 0x90-0x97 */
+	0x78F9,0x78FB,0x78FC,0x78FD,0x78FE,0x78FF,0x7900,0x7902,/* 0x90-0x97 */
 	0x7903,0x7904,0x7906,0x7907,0x7908,0x7909,0x790A,0x790B,/* 0x98-0x9F */
 	0x790C,0x7840,0x50A8,0x77D7,0x6410,0x89E6,0x5904,0x63E3,/* 0xA0-0xA7 */
-	0x5DDD,0x7A7F,0x693D,0x4F20,0x8239,0x5598,0xF905,0x75AE,/* 0xA8-0xAF */
+	0x5DDD,0x7A7F,0x693D,0x4F20,0x8239,0x5598,0x4E32,0x75AE,/* 0xA8-0xAF */
 	0x7A97,0x5E62,0x5E8A,0x95EF,0x521B,0x5439,0x708A,0x6376,/* 0xB0-0xB7 */
 	0x9524,0x5782,0x6625,0x693F,0x9187,0x5507,0x6DF3,0x7EAF,/* 0xB8-0xBF */
 	0x8822,0x6233,0x7EF0,0x75B5,0x8328,0x78C1,0x96CC,0x8F9E,/* 0xC0-0xC7 */
-	0x6148,0x74F7,0x8BCD,0x6B64,0xF9FF,0x8D50,0x6B21,0x806A,/* 0xC8-0xCF */
+	0x6148,0x74F7,0x8BCD,0x6B64,0x523A,0x8D50,0x6B21,0x806A,/* 0xC8-0xCF */
 	0x8471,0x56F1,0x5306,0x4ECE,0x4E1B,0x51D1,0x7C97,0x918B,/* 0xD0-0xD7 */
 	0x7C07,0x4FC3,0x8E7F,0x7BE1,0x7A9C,0x6467,0x5D14,0x50AC,/* 0xD8-0xDF */
 	0x8106,0x7601,0x7CB9,0x6DEC,0x7FE0,0x6751,0x5B58,0x5BF8,/* 0xE0-0xE7 */
@@ -1823,17 +1823,17 @@
 	0x790D,0x790E,0x790F,0x7910,0x7911,0x7912,0x7914,0x7915,/* 0x40-0x47 */
 	0x7916,0x7917,0x7918,0x7919,0x791A,0x791B,0x791C,0x791D,/* 0x48-0x4F */
 	0x791F,0x7920,0x7921,0x7922,0x7923,0x7925,0x7926,0x7927,/* 0x50-0x57 */
-	0x7928,0x7929,0xF985,0x792B,0x792C,0x792D,0x792E,0x792F,/* 0x58-0x5F */
+	0x7928,0x7929,0x792A,0x792B,0x792C,0x792D,0x792E,0x792F,/* 0x58-0x5F */
 	0x7930,0x7931,0x7932,0x7933,0x7935,0x7936,0x7937,0x7938,/* 0x60-0x67 */
 	0x7939,0x793D,0x793F,0x7942,0x7943,0x7944,0x7945,0x7947,/* 0x68-0x6F */
 	0x794A,0x794B,0x794C,0x794D,0x794E,0x794F,0x7950,0x7951,/* 0x70-0x77 */
 	0x7952,0x7954,0x7955,0x7958,0x7959,0x7961,0x7963,0x0000,/* 0x78-0x7F */
-	
+
 	0x7964,0x7966,0x7969,0x796A,0x796B,0x796C,0x796E,0x7970,/* 0x80-0x87 */
 	0x7971,0x7972,0x7973,0x7974,0x7975,0x7976,0x7979,0x797B,/* 0x88-0x8F */
-	0x797C,0x797D,0x797E,0xF93C,0x7982,0x7983,0x7986,0x7987,/* 0x90-0x97 */
+	0x797C,0x797D,0x797E,0x797F,0x7982,0x7983,0x7986,0x7987,/* 0x90-0x97 */
 	0x7988,0x7989,0x798B,0x798C,0x798D,0x798E,0x7990,0x7991,/* 0x98-0x9F */
-	0x7992,0x6020,0x803D,0x62C5,0xF95E,0x5355,0x90F8,0x63B8,/* 0xA0-0xA7 */
+	0x7992,0x6020,0x803D,0x62C5,0x4E39,0x5355,0x90F8,0x63B8,/* 0xA0-0xA7 */
 	0x80C6,0x65E6,0x6C2E,0x4F46,0x60EE,0x6DE1,0x8BDE,0x5F39,/* 0xA8-0xAF */
 	0x86CB,0x5F53,0x6321,0x515A,0x8361,0x6863,0x5200,0x6363,/* 0xB0-0xB7 */
 	0x8E48,0x5012,0x5C9B,0x7977,0x5BFC,0x5230,0x7A3B,0x60BC,/* 0xB8-0xBF */
@@ -1859,22 +1859,22 @@
 	0x7993,0x7994,0x7995,0x7996,0x7997,0x7998,0x7999,0x799B,/* 0x40-0x47 */
 	0x799C,0x799D,0x799E,0x799F,0x79A0,0x79A1,0x79A2,0x79A3,/* 0x48-0x4F */
 	0x79A4,0x79A5,0x79A6,0x79A8,0x79A9,0x79AA,0x79AB,0x79AC,/* 0x50-0x57 */
-	0x79AD,0xF9B6,0x79AF,0x79B0,0x79B1,0x79B2,0x79B4,0x79B5,/* 0x58-0x5F */
+	0x79AD,0x79AE,0x79AF,0x79B0,0x79B1,0x79B2,0x79B4,0x79B5,/* 0x58-0x5F */
 	0x79B6,0x79B7,0x79B8,0x79BC,0x79BF,0x79C2,0x79C4,0x79C5,/* 0x60-0x67 */
 	0x79C7,0x79C8,0x79CA,0x79CC,0x79CE,0x79CF,0x79D0,0x79D3,/* 0x68-0x6F */
 	0x79D4,0x79D6,0x79D7,0x79D9,0x79DA,0x79DB,0x79DC,0x79DD,/* 0x70-0x77 */
 	0x79DE,0x79E0,0x79E1,0x79E2,0x79E5,0x79E8,0x79EA,0x0000,/* 0x78-0x7F */
-	
+
 	0x79EC,0x79EE,0x79F1,0x79F2,0x79F3,0x79F4,0x79F5,0x79F6,/* 0x80-0x87 */
 	0x79F7,0x79F9,0x79FA,0x79FC,0x79FE,0x79FF,0x7A01,0x7A04,/* 0x88-0x8F */
 	0x7A05,0x7A07,0x7A08,0x7A09,0x7A0A,0x7A0C,0x7A0F,0x7A10,/* 0x90-0x97 */
 	0x7A11,0x7A12,0x7A13,0x7A15,0x7A16,0x7A18,0x7A19,0x7A1B,/* 0x98-0x9F */
-	0xF956,0x4E01,0x76EF,0x53EE,0x9489,0x9876,0x9F0E,0x952D,/* 0xA0-0xA7 */
+	0x7A1C,0x4E01,0x76EF,0x53EE,0x9489,0x9876,0x9F0E,0x952D,/* 0xA0-0xA7 */
 	0x5B9A,0x8BA2,0x4E22,0x4E1C,0x51AC,0x8463,0x61C2,0x52A8,/* 0xA8-0xAF */
-	0x680B,0x4F97,0x606B,0x51BB,0xFA05,0x515C,0x6296,0x6597,/* 0xB0-0xB7 */
-	0x9661,0x8C46,0x9017,0x75D8,0xFA26,0x7763,0x6BD2,0x728A,/* 0xB8-0xBF */
+	0x680B,0x4F97,0x606B,0x51BB,0x6D1E,0x515C,0x6296,0x6597,/* 0xB0-0xB7 */
+	0x9661,0x8C46,0x9017,0x75D8,0x90FD,0x7763,0x6BD2,0x728A,/* 0xB8-0xBF */
 	0x72EC,0x8BFB,0x5835,0x7779,0x8D4C,0x675C,0x9540,0x809A,/* 0xC0-0xC7 */
-	0xFA01,0x6E21,0x5992,0x7AEF,0x77ED,0x953B,0x6BB5,0x65AD,/* 0xC8-0xCF */
+	0x5EA6,0x6E21,0x5992,0x7AEF,0x77ED,0x953B,0x6BB5,0x65AD,/* 0xC8-0xCF */
 	0x7F0E,0x5806,0x5151,0x961F,0x5BF9,0x58A9,0x5428,0x8E72,/* 0xD0-0xD7 */
 	0x6566,0x987F,0x56E4,0x949D,0x76FE,0x9041,0x6387,0x54C6,/* 0xD8-0xDF */
 	0x591A,0x593A,0x579B,0x8EB2,0x6735,0x8DFA,0x8235,0x5241,/* 0xE0-0xE7 */
@@ -1900,7 +1900,7 @@
 	0x7A50,0x7A52,0x7A53,0x7A54,0x7A55,0x7A56,0x7A58,0x7A59,/* 0x68-0x6F */
 	0x7A5A,0x7A5B,0x7A5C,0x7A5D,0x7A5E,0x7A5F,0x7A60,0x7A61,/* 0x70-0x77 */
 	0x7A62,0x7A63,0x7A64,0x7A65,0x7A66,0x7A67,0x7A68,0x0000,/* 0x78-0x7F */
-	
+
 	0x7A69,0x7A6A,0x7A6B,0x7A6C,0x7A6D,0x7A6E,0x7A6F,0x7A71,/* 0x80-0x87 */
 	0x7A72,0x7A73,0x7A75,0x7A7B,0x7A7C,0x7A7D,0x7A7E,0x7A82,/* 0x88-0x8F */
 	0x7A85,0x7A87,0x7A89,0x7A8A,0x7A8B,0x7A8C,0x7A8E,0x7A8F,/* 0x90-0x97 */
@@ -1936,12 +1936,12 @@
 	0x7AD3,0x7AD4,0x7AD5,0x7AD7,0x7AD8,0x7ADA,0x7ADB,0x7ADC,/* 0x68-0x6F */
 	0x7ADD,0x7AE1,0x7AE2,0x7AE4,0x7AE7,0x7AE8,0x7AE9,0x7AEA,/* 0x70-0x77 */
 	0x7AEB,0x7AEC,0x7AEE,0x7AF0,0x7AF1,0x7AF2,0x7AF3,0x0000,/* 0x78-0x7F */
-	
+
 	0x7AF4,0x7AF5,0x7AF6,0x7AF7,0x7AF8,0x7AFB,0x7AFC,0x7AFE,/* 0x80-0x87 */
 	0x7B00,0x7B01,0x7B02,0x7B05,0x7B07,0x7B09,0x7B0C,0x7B0D,/* 0x88-0x8F */
 	0x7B0E,0x7B10,0x7B12,0x7B13,0x7B16,0x7B17,0x7B18,0x7B1A,/* 0x90-0x97 */
 	0x7B1C,0x7B1D,0x7B1F,0x7B21,0x7B22,0x7B23,0x7B27,0x7B29,/* 0x98-0x9F */
-	0x7B2D,0x6D6E,0x6DAA,0xFA1B,0x88B1,0x5F17,0x752B,0x629A,/* 0xA0-0xA7 */
+	0x7B2D,0x6D6E,0x6DAA,0x798F,0x88B1,0x5F17,0x752B,0x629A,/* 0xA0-0xA7 */
 	0x8F85,0x4FEF,0x91DC,0x65A7,0x812F,0x8151,0x5E9C,0x8150,/* 0xA8-0xAF */
 	0x8D74,0x526F,0x8986,0x8D4B,0x590D,0x5085,0x4ED8,0x961C,/* 0xB0-0xB7 */
 	0x7236,0x8179,0x8D1F,0x5BCC,0x8BA3,0x9644,0x5987,0x7F1A,/* 0xB8-0xBF */
@@ -1952,7 +1952,7 @@
 	0x818F,0x7F94,0x7CD5,0x641E,0x9550,0x7A3F,0x544A,0x54E5,/* 0xE0-0xE7 */
 	0x6B4C,0x6401,0x6208,0x9E3D,0x80F3,0x7599,0x5272,0x9769,/* 0xE8-0xEF */
 	0x845B,0x683C,0x86E4,0x9601,0x9694,0x94EC,0x4E2A,0x5404,/* 0xF0-0xF7 */
-	0x7ED9,0x6839,0x8DDF,0x8015,0xF901,0x5E9A,0x7FB9,0x0000,/* 0xF8-0xFF */
+	0x7ED9,0x6839,0x8DDF,0x8015,0x66F4,0x5E9A,0x7FB9,0x0000,/* 0xF8-0xFF */
 };
 
 static wchar_t c2u_B9[256] = {
@@ -1972,7 +1972,7 @@
 	0x7B6F,0x7B70,0x7B73,0x7B74,0x7B76,0x7B78,0x7B7A,0x7B7C,/* 0x68-0x6F */
 	0x7B7D,0x7B7F,0x7B81,0x7B82,0x7B83,0x7B84,0x7B86,0x7B87,/* 0x70-0x77 */
 	0x7B88,0x7B89,0x7B8A,0x7B8B,0x7B8C,0x7B8E,0x7B8F,0x0000,/* 0x78-0x7F */
-	
+
 	0x7B91,0x7B92,0x7B93,0x7B96,0x7B98,0x7B99,0x7B9A,0x7B9B,/* 0x80-0x87 */
 	0x7B9E,0x7B9F,0x7BA0,0x7BA3,0x7BA4,0x7BA5,0x7BAE,0x7BAF,/* 0x88-0x8F */
 	0x7BB0,0x7BB2,0x7BB3,0x7BB5,0x7BB6,0x7BB7,0x7BB9,0x7BBA,/* 0x90-0x97 */
@@ -2008,11 +2008,11 @@
 	0x7BFD,0x7BFF,0x7C00,0x7C01,0x7C02,0x7C03,0x7C04,0x7C05,/* 0x68-0x6F */
 	0x7C06,0x7C08,0x7C09,0x7C0A,0x7C0D,0x7C0E,0x7C10,0x7C11,/* 0x70-0x77 */
 	0x7C12,0x7C13,0x7C14,0x7C15,0x7C17,0x7C18,0x7C19,0x0000,/* 0x78-0x7F */
-	
+
 	0x7C1A,0x7C1B,0x7C1C,0x7C1D,0x7C1E,0x7C20,0x7C21,0x7C22,/* 0x80-0x87 */
 	0x7C23,0x7C24,0x7C25,0x7C28,0x7C29,0x7C2B,0x7C2C,0x7C2D,/* 0x88-0x8F */
 	0x7C2E,0x7C2F,0x7C30,0x7C31,0x7C32,0x7C33,0x7C34,0x7C35,/* 0x90-0x97 */
-	0x7C36,0x7C37,0x7C39,0x7C3A,0x7C3B,0x7C3C,0x7C3D,0xF9A6,/* 0x98-0x9F */
+	0x7C36,0x7C37,0x7C39,0x7C3A,0x7C3B,0x7C3C,0x7C3D,0x7C3E,/* 0x98-0x9F */
 	0x7C42,0x9AB8,0x5B69,0x6D77,0x6C26,0x4EA5,0x5BB3,0x9A87,/* 0xA0-0xA7 */
 	0x9163,0x61A8,0x90AF,0x97E9,0x542B,0x6DB5,0x5BD2,0x51FD,/* 0xA8-0xAF */
 	0x558A,0x7F55,0x7FF0,0x64BC,0x634D,0x65F1,0x61BE,0x608D,/* 0xB0-0xB7 */
@@ -2039,18 +2039,18 @@
 	0x7C43,0x7C44,0x7C45,0x7C46,0x7C47,0x7C48,0x7C49,0x7C4A,/* 0x40-0x47 */
 	0x7C4B,0x7C4C,0x7C4E,0x7C4F,0x7C50,0x7C51,0x7C52,0x7C53,/* 0x48-0x4F */
 	0x7C54,0x7C55,0x7C56,0x7C57,0x7C58,0x7C59,0x7C5A,0x7C5B,/* 0x50-0x57 */
-	0x7C5C,0x7C5D,0x7C5E,0x7C5F,0xF944,0x7C61,0x7C62,0x7C63,/* 0x58-0x5F */
+	0x7C5C,0x7C5D,0x7C5E,0x7C5F,0x7C60,0x7C61,0x7C62,0x7C63,/* 0x58-0x5F */
 	0x7C64,0x7C65,0x7C66,0x7C67,0x7C68,0x7C69,0x7C6A,0x7C6B,/* 0x60-0x67 */
 	0x7C6C,0x7C6D,0x7C6E,0x7C6F,0x7C70,0x7C71,0x7C72,0x7C75,/* 0x68-0x6F */
 	0x7C76,0x7C77,0x7C78,0x7C79,0x7C7A,0x7C7E,0x7C7F,0x7C80,/* 0x70-0x77 */
 	0x7C81,0x7C82,0x7C83,0x7C84,0x7C85,0x7C86,0x7C87,0x0000,/* 0x78-0x7F */
-	
+
 	0x7C88,0x7C8A,0x7C8B,0x7C8C,0x7C8D,0x7C8E,0x7C8F,0x7C90,/* 0x80-0x87 */
 	0x7C93,0x7C94,0x7C96,0x7C99,0x7C9A,0x7C9B,0x7CA0,0x7CA1,/* 0x88-0x8F */
 	0x7CA3,0x7CA6,0x7CA7,0x7CA8,0x7CA9,0x7CAB,0x7CAC,0x7CAD,/* 0x90-0x97 */
 	0x7CAF,0x7CB0,0x7CB4,0x7CB5,0x7CB6,0x7CB7,0x7CB8,0x7CBA,/* 0x98-0x9F */
 	0x7CBB,0x5F27,0x864E,0x552C,0x62A4,0x4E92,0x6CAA,0x6237,/* 0xA0-0xA7 */
-	0x82B1,0x54D7,0x534E,0x733E,0xF904,0x753B,0x5212,0x5316,/* 0xA8-0xAF */
+	0x82B1,0x54D7,0x534E,0x733E,0x6ED1,0x753B,0x5212,0x5316,/* 0xA8-0xAF */
 	0x8BDD,0x69D0,0x5F8A,0x6000,0x6DEE,0x574F,0x6B22,0x73AF,/* 0xB0-0xB7 */
 	0x6853,0x8FD8,0x7F13,0x6362,0x60A3,0x5524,0x75EA,0x8C62,/* 0xB8-0xBF */
 	0x7115,0x6DA3,0x5BA6,0x5E7B,0x8352,0x614C,0x9EC4,0x78FA,/* 0xC0-0xC7 */
@@ -2075,12 +2075,12 @@
 	0x7CBF,0x7CC0,0x7CC2,0x7CC3,0x7CC4,0x7CC6,0x7CC9,0x7CCB,/* 0x40-0x47 */
 	0x7CCE,0x7CCF,0x7CD0,0x7CD1,0x7CD2,0x7CD3,0x7CD4,0x7CD8,/* 0x48-0x4F */
 	0x7CDA,0x7CDB,0x7CDD,0x7CDE,0x7CE1,0x7CE2,0x7CE3,0x7CE4,/* 0x50-0x57 */
-	0x7CE5,0x7CE6,0xF97B,0x7CE9,0x7CEA,0x7CEB,0x7CEC,0x7CED,/* 0x58-0x5F */
+	0x7CE5,0x7CE6,0x7CE7,0x7CE9,0x7CEA,0x7CEB,0x7CEC,0x7CED,/* 0x58-0x5F */
 	0x7CEE,0x7CF0,0x7CF1,0x7CF2,0x7CF3,0x7CF4,0x7CF5,0x7CF6,/* 0x60-0x67 */
 	0x7CF7,0x7CF9,0x7CFA,0x7CFC,0x7CFD,0x7CFE,0x7CFF,0x7D00,/* 0x68-0x6F */
 	0x7D01,0x7D02,0x7D03,0x7D04,0x7D05,0x7D06,0x7D07,0x7D08,/* 0x70-0x77 */
-	0x7D09,0x7D0B,0x7D0C,0x7D0D,0x7D0E,0x7D0F,0xF9CF,0x0000,/* 0x78-0x7F */
-	
+	0x7D09,0x7D0B,0x7D0C,0x7D0D,0x7D0E,0x7D0F,0x7D10,0x0000,/* 0x78-0x7F */
+
 	0x7D11,0x7D12,0x7D13,0x7D14,0x7D15,0x7D16,0x7D17,0x7D18,/* 0x80-0x87 */
 	0x7D19,0x7D1A,0x7D1B,0x7D1C,0x7D1D,0x7D1E,0x7D1F,0x7D21,/* 0x88-0x8F */
 	0x7D23,0x7D24,0x7D25,0x7D26,0x7D28,0x7D29,0x7D2A,0x7D2C,/* 0x90-0x97 */
@@ -2116,14 +2116,14 @@
 	0x7D5F,0x7D60,0x7D61,0x7D62,0x7D63,0x7D64,0x7D65,0x7D66,/* 0x68-0x6F */
 	0x7D67,0x7D68,0x7D69,0x7D6A,0x7D6B,0x7D6C,0x7D6D,0x7D6F,/* 0x70-0x77 */
 	0x7D70,0x7D71,0x7D72,0x7D73,0x7D74,0x7D75,0x7D76,0x0000,/* 0x78-0x7F */
-	
+
 	0x7D78,0x7D79,0x7D7A,0x7D7B,0x7D7C,0x7D7D,0x7D7E,0x7D7F,/* 0x80-0x87 */
 	0x7D80,0x7D81,0x7D82,0x7D83,0x7D84,0x7D85,0x7D86,0x7D87,/* 0x88-0x8F */
 	0x7D88,0x7D89,0x7D8A,0x7D8B,0x7D8C,0x7D8D,0x7D8E,0x7D8F,/* 0x90-0x97 */
 	0x7D90,0x7D91,0x7D92,0x7D93,0x7D94,0x7D95,0x7D96,0x7D97,/* 0x98-0x9F */
 	0x7D98,0x5065,0x8230,0x5251,0x996F,0x6E10,0x6E85,0x6DA7,/* 0xA0-0xA7 */
 	0x5EFA,0x50F5,0x59DC,0x5C06,0x6D46,0x6C5F,0x7586,0x848B,/* 0xA8-0xAF */
-	0x6868,0x5956,0x8BB2,0x5320,0x9171,0xFA09,0x8549,0x6912,/* 0xB0-0xB7 */
+	0x6868,0x5956,0x8BB2,0x5320,0x9171,0x964D,0x8549,0x6912,/* 0xB0-0xB7 */
 	0x7901,0x7126,0x80F6,0x4EA4,0x90CA,0x6D47,0x9A84,0x5A07,/* 0xB8-0xBF */
 	0x56BC,0x6405,0x94F0,0x77EB,0x4FA5,0x811A,0x72E1,0x89D2,/* 0xC0-0xC7 */
 	0x997A,0x7F34,0x7EDE,0x527F,0x6559,0x9175,0x8F7F,0x8F83,/* 0xC8-0xCF */
@@ -2131,7 +2131,7 @@
 	0x622A,0x52AB,0x8282,0x6854,0x6770,0x6377,0x776B,0x7AED,/* 0xD8-0xDF */
 	0x6D01,0x7ED3,0x89E3,0x59D0,0x6212,0x85C9,0x82A5,0x754C,/* 0xE0-0xE7 */
 	0x501F,0x4ECB,0x75A5,0x8BEB,0x5C4A,0x5DFE,0x7B4B,0x65A4,/* 0xE8-0xEF */
-	0xF90A,0x4ECA,0x6D25,0x895F,0x7D27,0x9526,0x4EC5,0x8C28,/* 0xF0-0xF7 */
+	0x91D1,0x4ECA,0x6D25,0x895F,0x7D27,0x9526,0x4EC5,0x8C28,/* 0xF0-0xF7 */
 	0x8FDB,0x9773,0x664B,0x7981,0x8FD1,0x70EC,0x6D78,0x0000,/* 0xF8-0xFF */
 };
 
@@ -2144,28 +2144,28 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x28-0x2F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x30-0x37 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x38-0x3F */
-	0x7D99,0x7D9A,0x7D9B,0x7D9C,0x7D9D,0x7D9E,0x7D9F,0xF93D,/* 0x40-0x47 */
+	0x7D99,0x7D9A,0x7D9B,0x7D9C,0x7D9D,0x7D9E,0x7D9F,0x7DA0,/* 0x40-0x47 */
 	0x7DA1,0x7DA2,0x7DA3,0x7DA4,0x7DA5,0x7DA7,0x7DA8,0x7DA9,/* 0x48-0x4F */
 	0x7DAA,0x7DAB,0x7DAC,0x7DAD,0x7DAF,0x7DB0,0x7DB1,0x7DB2,/* 0x50-0x57 */
 	0x7DB3,0x7DB4,0x7DB5,0x7DB6,0x7DB7,0x7DB8,0x7DB9,0x7DBA,/* 0x58-0x5F */
-	0x7DBB,0x7DBC,0x7DBD,0xF957,0x7DBF,0x7DC0,0x7DC1,0x7DC2,/* 0x60-0x67 */
+	0x7DBB,0x7DBC,0x7DBD,0x7DBE,0x7DBF,0x7DC0,0x7DC1,0x7DC2,/* 0x60-0x67 */
 	0x7DC3,0x7DC4,0x7DC5,0x7DC6,0x7DC7,0x7DC8,0x7DC9,0x7DCA,/* 0x68-0x6F */
 	0x7DCB,0x7DCC,0x7DCD,0x7DCE,0x7DCF,0x7DD0,0x7DD1,0x7DD2,/* 0x70-0x77 */
 	0x7DD3,0x7DD4,0x7DD5,0x7DD6,0x7DD7,0x7DD8,0x7DD9,0x0000,/* 0x78-0x7F */
-	
+
 	0x7DDA,0x7DDB,0x7DDC,0x7DDD,0x7DDE,0x7DDF,0x7DE0,0x7DE1,/* 0x80-0x87 */
 	0x7DE2,0x7DE3,0x7DE4,0x7DE5,0x7DE6,0x7DE7,0x7DE8,0x7DE9,/* 0x88-0x8F */
 	0x7DEA,0x7DEB,0x7DEC,0x7DED,0x7DEE,0x7DEF,0x7DF0,0x7DF1,/* 0x90-0x97 */
-	0x7DF2,0x7DF3,0xF996,0x7DF5,0x7DF6,0x7DF7,0x7DF8,0x7DF9,/* 0x98-0x9F */
+	0x7DF2,0x7DF3,0x7DF4,0x7DF5,0x7DF6,0x7DF7,0x7DF8,0x7DF9,/* 0x98-0x9F */
 	0x7DFA,0x5C3D,0x52B2,0x8346,0x5162,0x830E,0x775B,0x6676,/* 0xA0-0xA7 */
-	0x9CB8,0x4EAC,0x60CA,0xFA1D,0x7CB3,0x7ECF,0x4E95,0x8B66,/* 0xA8-0xAF */
+	0x9CB8,0x4EAC,0x60CA,0x7CBE,0x7CB3,0x7ECF,0x4E95,0x8B66,/* 0xA8-0xAF */
 	0x666F,0x9888,0x9759,0x5883,0x656C,0x955C,0x5F84,0x75C9,/* 0xB0-0xB7 */
-	0xFA1C,0x7ADF,0x7ADE,0x51C0,0x70AF,0x7A98,0x63EA,0x7A76,/* 0xB8-0xBF */
+	0x9756,0x7ADF,0x7ADE,0x51C0,0x70AF,0x7A98,0x63EA,0x7A76,/* 0xB8-0xBF */
 	0x7EA0,0x7396,0x97ED,0x4E45,0x7078,0x4E5D,0x9152,0x53A9,/* 0xC0-0xC7 */
 	0x6551,0x65E7,0x81FC,0x8205,0x548E,0x5C31,0x759A,0x97A0,/* 0xC8-0xCF */
 	0x62D8,0x72D9,0x75BD,0x5C45,0x9A79,0x83CA,0x5C40,0x5480,/* 0xD0-0xD7 */
 	0x77E9,0x4E3E,0x6CAE,0x805A,0x62D2,0x636E,0x5DE8,0x5177,/* 0xD8-0xDF */
-	0x8DDD,0x8E1E,0x952F,0x4FF1,0xF906,0x60E7,0x70AC,0x5267,/* 0xE0-0xE7 */
+	0x8DDD,0x8E1E,0x952F,0x4FF1,0x53E5,0x60E7,0x70AC,0x5267,/* 0xE0-0xE7 */
 	0x6350,0x9E43,0x5A1F,0x5026,0x7737,0x5377,0x7EE2,0x6485,/* 0xE8-0xEF */
 	0x652B,0x6289,0x6398,0x5014,0x7235,0x89C9,0x51B3,0x8BC0,/* 0xF0-0xF7 */
 	0x7EDD,0x5747,0x83CC,0x94A7,0x519B,0x541B,0x5CFB,0x0000,/* 0xF8-0xFF */
@@ -2187,8 +2187,8 @@
 	0x7E1B,0x7E1C,0x7E1D,0x7E1E,0x7E1F,0x7E20,0x7E21,0x7E22,/* 0x60-0x67 */
 	0x7E23,0x7E24,0x7E25,0x7E26,0x7E27,0x7E28,0x7E29,0x7E2A,/* 0x68-0x6F */
 	0x7E2B,0x7E2C,0x7E2D,0x7E2E,0x7E2F,0x7E30,0x7E31,0x7E32,/* 0x70-0x77 */
-	0x7E33,0x7E34,0x7E35,0x7E36,0xF950,0x7E38,0x7E39,0x0000,/* 0x78-0x7F */
-	
+	0x7E33,0x7E34,0x7E35,0x7E36,0x7E37,0x7E38,0x7E39,0x0000,/* 0x78-0x7F */
+
 	0x7E3A,0x7E3C,0x7E3D,0x7E3E,0x7E3F,0x7E40,0x7E42,0x7E43,/* 0x80-0x87 */
 	0x7E44,0x7E45,0x7E46,0x7E48,0x7E49,0x7E4A,0x7E4B,0x7E4C,/* 0x88-0x8F */
 	0x7E4D,0x7E4E,0x7E4F,0x7E50,0x7E51,0x7E52,0x7E53,0x7E54,/* 0x90-0x97 */
@@ -2224,23 +2224,23 @@
 	0x7E87,0x7E88,0x7E89,0x7E8A,0x7E8B,0x7E8C,0x7E8D,0x7E8E,/* 0x68-0x6F */
 	0x7E8F,0x7E90,0x7E91,0x7E92,0x7E93,0x7E94,0x7E95,0x7E96,/* 0x70-0x77 */
 	0x7E97,0x7E98,0x7E99,0x7E9A,0x7E9C,0x7E9D,0x7E9E,0x0000,/* 0x78-0x7F */
-	
+
 	0x7EAE,0x7EB4,0x7EBB,0x7EBC,0x7ED6,0x7EE4,0x7EEC,0x7EF9,/* 0x80-0x87 */
 	0x7F0A,0x7F10,0x7F1E,0x7F37,0x7F39,0x7F3B,0x7F3C,0x7F3D,/* 0x88-0x8F */
 	0x7F3E,0x7F3F,0x7F40,0x7F41,0x7F43,0x7F46,0x7F47,0x7F48,/* 0x90-0x97 */
 	0x7F49,0x7F4A,0x7F4B,0x7F4C,0x7F4D,0x7F4E,0x7F4F,0x7F52,/* 0x98-0x9F */
 	0x7F53,0x9988,0x6127,0x6E83,0x5764,0x6606,0x6346,0x56F0,/* 0xA0-0xA7 */
-	0x62EC,0x6269,0xFA0B,0x9614,0x5783,0xF925,0xF90B,0x8721,/* 0xA8-0xAF */
+	0x62EC,0x6269,0x5ED3,0x9614,0x5783,0x62C9,0x5587,0x8721,/* 0xA8-0xAF */
 	0x814A,0x8FA3,0x5566,0x83B1,0x6765,0x8D56,0x84DD,0x5A6A,/* 0xB0-0xB7 */
 	0x680F,0x62E6,0x7BEE,0x9611,0x5170,0x6F9C,0x8C30,0x63FD,/* 0xB8-0xBF */
-	0x89C8,0x61D2,0x7F06,0x70C2,0x6EE5,0x7405,0x6994,0xF92B,/* 0xC0-0xC7 */
-	0xF928,0x90CE,0xF929,0xF92A,0x635E,0x52B3,0xF946,0xF934,/* 0xC8-0xCF */
-	0x4F6C,0x59E5,0xF919,0xF916,0x6D9D,0xF952,0x4E50,0xF949,/* 0xD0-0xD7 */
-	0x956D,0x857E,0xF947,0xF94F,0x5121,0x5792,0x64C2,0xF953,/* 0xD8-0xDF */
-	0x7C7B,0x6CEA,0x68F1,0x695E,0xF92E,0x5398,0xF9E2,0x7281,/* 0xE0-0xE7 */
-	0xF989,0x7BF1,0x72F8,0x79BB,0x6F13,0xF9E4,0xF9E1,0xF9E9,/* 0xE8-0xEF */
-	0x9CA4,0x793C,0x8389,0x8354,0xF9DE,0xF9DA,0x4E3D,0x5389,/* 0xF0-0xF7 */
-	0x52B1,0x783E,0x5386,0xF9DD,0x5088,0xF9B5,0x4FD0,0x0000,/* 0xF8-0xFF */
+	0x89C8,0x61D2,0x7F06,0x70C2,0x6EE5,0x7405,0x6994,0x72FC,/* 0xC0-0xC7 */
+	0x5ECA,0x90CE,0x6717,0x6D6A,0x635E,0x52B3,0x7262,0x8001,/* 0xC8-0xCF */
+	0x4F6C,0x59E5,0x916A,0x70D9,0x6D9D,0x52D2,0x4E50,0x96F7,/* 0xD0-0xD7 */
+	0x956D,0x857E,0x78CA,0x7D2F,0x5121,0x5792,0x64C2,0x808B,/* 0xD8-0xDF */
+	0x7C7B,0x6CEA,0x68F1,0x695E,0x51B7,0x5398,0x68A8,0x7281,/* 0xE0-0xE7 */
+	0x9ECE,0x7BF1,0x72F8,0x79BB,0x6F13,0x7406,0x674E,0x91CC,/* 0xE8-0xEF */
+	0x9CA4,0x793C,0x8389,0x8354,0x540F,0x6817,0x4E3D,0x5389,/* 0xF0-0xF7 */
+	0x52B1,0x783E,0x5386,0x5229,0x5088,0x4F8B,0x4FD0,0x0000,/* 0xF8-0xFF */
 };
 
 static wchar_t c2u_C1[256] = {
@@ -2255,28 +2255,28 @@
 	0x7F56,0x7F59,0x7F5B,0x7F5C,0x7F5D,0x7F5E,0x7F60,0x7F63,/* 0x40-0x47 */
 	0x7F64,0x7F65,0x7F66,0x7F67,0x7F6B,0x7F6C,0x7F6D,0x7F6F,/* 0x48-0x4F */
 	0x7F70,0x7F73,0x7F75,0x7F76,0x7F77,0x7F78,0x7F7A,0x7F7B,/* 0x50-0x57 */
-	0x7F7C,0x7F7D,0x7F7F,0x7F80,0x7F82,0x7F83,0x7F84,0xF90F,/* 0x58-0x5F */
+	0x7F7C,0x7F7D,0x7F7F,0x7F80,0x7F82,0x7F83,0x7F84,0x7F85,/* 0x58-0x5F */
 	0x7F86,0x7F87,0x7F88,0x7F89,0x7F8B,0x7F8D,0x7F8F,0x7F90,/* 0x60-0x67 */
 	0x7F91,0x7F92,0x7F93,0x7F95,0x7F96,0x7F97,0x7F98,0x7F99,/* 0x68-0x6F */
 	0x7F9B,0x7F9C,0x7FA0,0x7FA2,0x7FA3,0x7FA5,0x7FA6,0x7FA8,/* 0x70-0x77 */
 	0x7FA9,0x7FAA,0x7FAB,0x7FAC,0x7FAD,0x7FAE,0x7FB1,0x0000,/* 0x78-0x7F */
-	
+
 	0x7FB3,0x7FB4,0x7FB5,0x7FB6,0x7FB7,0x7FBA,0x7FBB,0x7FBE,/* 0x80-0x87 */
 	0x7FC0,0x7FC2,0x7FC3,0x7FC4,0x7FC6,0x7FC7,0x7FC8,0x7FC9,/* 0x88-0x8F */
 	0x7FCB,0x7FCD,0x7FCF,0x7FD0,0x7FD1,0x7FD2,0x7FD3,0x7FD6,/* 0x90-0x97 */
 	0x7FD7,0x7FD9,0x7FDA,0x7FDB,0x7FDC,0x7FDD,0x7FDE,0x7FE2,/* 0x98-0x9F */
-	0x7FE3,0xF9E5,0xF9F7,0xF9F9,0x6CA5,0x96B6,0xF98A,0x7483,/* 0xA0-0xA7 */
-	0x54E9,0x4FE9,0x8054,0x83B2,0x8FDE,0x9570,0xF9A2,0xF9AC,/* 0xA8-0xAF */
+	0x7FE3,0x75E2,0x7ACB,0x7C92,0x6CA5,0x96B6,0x529B,0x7483,/* 0xA0-0xA7 */
+	0x54E9,0x4FE9,0x8054,0x83B2,0x8FDE,0x9570,0x5EC9,0x601C,/* 0xA8-0xAF */
 	0x6D9F,0x5E18,0x655B,0x8138,0x94FE,0x604B,0x70BC,0x7EC3,/* 0xB0-0xB7 */
-	0x7CAE,0x51C9,0xF97A,0x7CB1,0xF97C,0x4E24,0x8F86,0xF97E,/* 0xB8-0xBF */
-	0x667E,0xF977,0x8C05,0x64A9,0x804A,0xF9BB,0x7597,0xF9C0,/* 0xC0-0xC7 */
-	0x5BE5,0x8FBD,0x6F66,0xF9BA,0x6482,0x9563,0x5ED6,0xF9BE,/* 0xC8-0xCF */
-	0xF99C,0xF9A0,0xF99F,0xF99D,0x730E,0x7433,0xF9F4,0x78F7,/* 0xD0-0xD7 */
-	0x9716,0x4E34,0x90BB,0x9CDE,0xF9F5,0x51DB,0x8D41,0xF9ED,/* 0xD8-0xDF */
-	0x62CE,0xF9AD,0xF958,0xF9B2,0x9F84,0x94C3,0x4F36,0xF9AF,/* 0xE0-0xE7 */
-	0xF955,0x7075,0xF959,0x5CAD,0x9886,0x53E6,0xF9A8,0xF9CB,/* 0xE8-0xEF */
-	0xF9CC,0x69B4,0xF9CE,0x998F,0xF9CD,0x5218,0x7624,0xF9CA,/* 0xF0-0xF7 */
-	0xF9C9,0xF9D1,0x9F99,0x804B,0x5499,0x7B3C,0x7ABF,0x0000,/* 0xF8-0xFF */
+	0x7CAE,0x51C9,0x6881,0x7CB1,0x826F,0x4E24,0x8F86,0x91CF,/* 0xB8-0xBF */
+	0x667E,0x4EAE,0x8C05,0x64A9,0x804A,0x50DA,0x7597,0x71CE,/* 0xC0-0xC7 */
+	0x5BE5,0x8FBD,0x6F66,0x4E86,0x6482,0x9563,0x5ED6,0x6599,/* 0xC8-0xCF */
+	0x5217,0x88C2,0x70C8,0x52A3,0x730E,0x7433,0x6797,0x78F7,/* 0xD0-0xD7 */
+	0x9716,0x4E34,0x90BB,0x9CDE,0x6DCB,0x51DB,0x8D41,0x541D,/* 0xD8-0xDF */
+	0x62CE,0x73B2,0x83F1,0x96F6,0x9F84,0x94C3,0x4F36,0x7F9A,/* 0xE0-0xE7 */
+	0x51CC,0x7075,0x9675,0x5CAD,0x9886,0x53E6,0x4EE4,0x6E9C,/* 0xE8-0xEF */
+	0x7409,0x69B4,0x786B,0x998F,0x7559,0x5218,0x7624,0x6D41,/* 0xF0-0xF7 */
+	0x67F3,0x516D,0x9F99,0x804B,0x5499,0x7B3C,0x7ABF,0x0000,/* 0xF8-0xFF */
 };
 
 static wchar_t c2u_C2[256] = {
@@ -2296,20 +2296,20 @@
 	0x802F,0x8030,0x8032,0x8034,0x8039,0x803A,0x803C,0x803E,/* 0x68-0x6F */
 	0x8040,0x8041,0x8044,0x8045,0x8047,0x8048,0x8049,0x804E,/* 0x70-0x77 */
 	0x804F,0x8050,0x8051,0x8053,0x8055,0x8056,0x8057,0x0000,/* 0x78-0x7F */
-	
+
 	0x8059,0x805B,0x805C,0x805D,0x805E,0x805F,0x8060,0x8061,/* 0x80-0x87 */
 	0x8062,0x8063,0x8064,0x8065,0x8066,0x8067,0x8068,0x806B,/* 0x88-0x8F */
-	0x806C,0x806D,0x806E,0xF997,0x8070,0x8072,0x8073,0x8074,/* 0x90-0x97 */
+	0x806C,0x806D,0x806E,0x806F,0x8070,0x8072,0x8073,0x8074,/* 0x90-0x97 */
 	0x8075,0x8076,0x8077,0x8078,0x8079,0x807A,0x807B,0x807C,/* 0x98-0x9F */
-	0x807D,0xF9DC,0x5784,0x62E2,0x9647,0x697C,0x5A04,0x6402,/* 0xA0-0xA7 */
-	0x7BD3,0xF94E,0xF951,0x82A6,0x5362,0x9885,0x5E90,0x7089,/* 0xA8-0xAF */
-	0x63B3,0x5364,0x864F,0x9C81,0x9E93,0xF93B,0xF938,0xF937,/* 0xB0-0xB7 */
-	0x8D42,0xF940,0x6F5E,0x7984,0x5F55,0x9646,0xF9D2,0x9A74,/* 0xB8-0xBF */
-	0x5415,0x94DD,0x4FA3,0xF983,0xF9DF,0x5C61,0x7F15,0x8651,/* 0xC0-0xC7 */
-	0x6C2F,0xF9D8,0xF9DB,0x6EE4,0x7EFF,0x5CE6,0x631B,0x5B6A,/* 0xC8-0xCF */
-	0x6EE6,0xF91C,0x4E71,0xF975,0xF976,0x62A1,0x8F6E,0x4F26,/* 0xD0-0xD7 */
-	0x4ED1,0x6CA6,0x7EB6,0x8BBA,0x841D,0xF911,0x7F57,0x903B,/* 0xD8-0xDF */
-	0x9523,0x7BA9,0x9AA1,0xF912,0xF918,0xF915,0x9A86,0x7EDC,/* 0xE0-0xE7 */
+	0x807D,0x9686,0x5784,0x62E2,0x9647,0x697C,0x5A04,0x6402,/* 0xA0-0xA7 */
+	0x7BD3,0x6F0F,0x964B,0x82A6,0x5362,0x9885,0x5E90,0x7089,/* 0xA8-0xAF */
+	0x63B3,0x5364,0x864F,0x9C81,0x9E93,0x788C,0x9732,0x8DEF,/* 0xB0-0xB7 */
+	0x8D42,0x9E7F,0x6F5E,0x7984,0x5F55,0x9646,0x622E,0x9A74,/* 0xB8-0xBF */
+	0x5415,0x94DD,0x4FA3,0x65C5,0x5C65,0x5C61,0x7F15,0x8651,/* 0xC0-0xC7 */
+	0x6C2F,0x5F8B,0x7387,0x6EE4,0x7EFF,0x5CE6,0x631B,0x5B6A,/* 0xC8-0xCF */
+	0x6EE6,0x5375,0x4E71,0x63A0,0x7565,0x62A1,0x8F6E,0x4F26,/* 0xD0-0xD7 */
+	0x4ED1,0x6CA6,0x7EB6,0x8BBA,0x841D,0x87BA,0x7F57,0x903B,/* 0xD8-0xDF */
+	0x9523,0x7BA9,0x9AA1,0x88F8,0x843D,0x6D1B,0x9A86,0x7EDC,/* 0xE0-0xE7 */
 	0x5988,0x9EBB,0x739B,0x7801,0x8682,0x9A6C,0x9A82,0x561B,/* 0xE8-0xEF */
 	0x5417,0x57CB,0x4E70,0x9EA6,0x5356,0x8FC8,0x8109,0x7792,/* 0xF0-0xF7 */
 	0x9992,0x86EE,0x6EE1,0x8513,0x66FC,0x6162,0x6F2B,0x0000,/* 0xF8-0xFF */
@@ -2324,7 +2324,7 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x28-0x2F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x30-0x37 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x38-0x3F */
-	0xF945,0x8081,0x8082,0x8085,0x8088,0x808A,0x808D,0x808E,/* 0x40-0x47 */
+	0x807E,0x8081,0x8082,0x8085,0x8088,0x808A,0x808D,0x808E,/* 0x40-0x47 */
 	0x808F,0x8090,0x8091,0x8092,0x8094,0x8095,0x8097,0x8099,/* 0x48-0x4F */
 	0x809E,0x80A3,0x80A6,0x80A7,0x80A8,0x80AC,0x80B0,0x80B3,/* 0x50-0x57 */
 	0x80B5,0x80B6,0x80B8,0x80B9,0x80BB,0x80C5,0x80C7,0x80C8,/* 0x58-0x5F */
@@ -2332,7 +2332,7 @@
 	0x80D4,0x80D5,0x80D8,0x80DF,0x80E0,0x80E2,0x80E3,0x80E6,/* 0x68-0x6F */
 	0x80EE,0x80F5,0x80F7,0x80F9,0x80FB,0x80FE,0x80FF,0x8100,/* 0x70-0x77 */
 	0x8101,0x8103,0x8104,0x8105,0x8107,0x8108,0x810B,0x0000,/* 0x78-0x7F */
-	
+
 	0x810C,0x8115,0x8117,0x8119,0x811B,0x811C,0x811D,0x811F,/* 0x80-0x87 */
 	0x8120,0x8121,0x8122,0x8123,0x8124,0x8125,0x8126,0x8127,/* 0x88-0x8F */
 	0x8128,0x8129,0x812A,0x812B,0x812D,0x812E,0x8130,0x8133,/* 0x90-0x97 */
@@ -2344,7 +2344,7 @@
 	0x7F8E,0x6627,0x5BD0,0x59B9,0x5A9A,0x95E8,0x95F7,0x4EEC,/* 0xC0-0xC7 */
 	0x840C,0x8499,0x6AAC,0x76DF,0x9530,0x731B,0x68A6,0x5B5F,/* 0xC8-0xCF */
 	0x772F,0x919A,0x9761,0x7CDC,0x8FF7,0x8C1C,0x5F25,0x7C73,/* 0xD0-0xD7 */
-	0x79D8,0x89C5,0xF968,0x871C,0x5BC6,0x5E42,0x68C9,0x7720,/* 0xD8-0xDF */
+	0x79D8,0x89C5,0x6CCC,0x871C,0x5BC6,0x5E42,0x68C9,0x7720,/* 0xD8-0xDF */
 	0x7EF5,0x5195,0x514D,0x52C9,0x5A29,0x7F05,0x9762,0x82D7,/* 0xE0-0xE7 */
 	0x63CF,0x7784,0x85D0,0x79D2,0x6E3A,0x5E99,0x5999,0x8511,/* 0xE8-0xEF */
 	0x706D,0x6C11,0x62BF,0x76BF,0x654F,0x60AF,0x95FD,0x660E,/* 0xF0-0xF7 */
@@ -2368,7 +2368,7 @@
 	0x8186,0x8187,0x8189,0x818B,0x818C,0x818D,0x818E,0x8190,/* 0x68-0x6F */
 	0x8192,0x8193,0x8194,0x8195,0x8196,0x8197,0x8199,0x819A,/* 0x70-0x77 */
 	0x819E,0x819F,0x81A0,0x81A1,0x81A2,0x81A4,0x81A5,0x0000,/* 0x78-0x7F */
-	
+
 	0x81A7,0x81A9,0x81AB,0x81AC,0x81AD,0x81AE,0x81AF,0x81B0,/* 0x80-0x87 */
 	0x81B1,0x81B2,0x81B4,0x81B5,0x81B6,0x81B7,0x81B8,0x81B9,/* 0x88-0x8F */
 	0x81BC,0x81BD,0x81BE,0x81BF,0x81C4,0x81C5,0x81C7,0x81C8,/* 0x90-0x97 */
@@ -2378,12 +2378,12 @@
 	0x964C,0x8C0B,0x725F,0x67D0,0x62C7,0x7261,0x4EA9,0x59C6,/* 0xB0-0xB7 */
 	0x6BCD,0x5893,0x66AE,0x5E55,0x52DF,0x6155,0x6728,0x76EE,/* 0xB8-0xBF */
 	0x7766,0x7267,0x7A46,0x62FF,0x54EA,0x5450,0x94A0,0x90A3,/* 0xC0-0xC7 */
-	0x5A1C,0x7EB3,0x6C16,0x4E43,0x5976,0x8010,0xF90C,0x5357,/* 0xC8-0xCF */
+	0x5A1C,0x7EB3,0x6C16,0x4E43,0x5976,0x8010,0x5948,0x5357,/* 0xC8-0xCF */
 	0x7537,0x96BE,0x56CA,0x6320,0x8111,0x607C,0x95F9,0x6DD6,/* 0xD0-0xD7 */
 	0x5462,0x9981,0x5185,0x5AE9,0x80FD,0x59AE,0x9713,0x502A,/* 0xD8-0xDF */
-	0xF9E3,0x5C3C,0x62DF,0x4F60,0xF9EB,0x817B,0x9006,0xF9EC,/* 0xE0-0xE7 */
-	0x852B,0x62C8,0xF98E,0x78BE,0x64B5,0xF9A4,0xF9A3,0x5A18,/* 0xE8-0xEF */
-	0x917F,0x9E1F,0xF9BD,0x634F,0x8042,0x5B7D,0x556E,0x954A,/* 0xF0-0xF7 */
+	0x6CE5,0x5C3C,0x62DF,0x4F60,0x533F,0x817B,0x9006,0x6EBA,/* 0xE0-0xE7 */
+	0x852B,0x62C8,0x5E74,0x78BE,0x64B5,0x637B,0x5FF5,0x5A18,/* 0xE8-0xEF */
+	0x917F,0x9E1F,0x5C3F,0x634F,0x8042,0x5B7D,0x556E,0x954A,/* 0xF0-0xF7 */
 	0x954D,0x6D85,0x60A8,0x67E0,0x72DE,0x51DD,0x5B81,0x0000,/* 0xF8-0xFF */
 };
 
@@ -2396,21 +2396,21 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x28-0x2F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x30-0x37 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x38-0x3F */
-	0x81D4,0x81D5,0x81D6,0x81D7,0xF926,0x81D9,0x81DA,0x81DB,/* 0x40-0x47 */
+	0x81D4,0x81D5,0x81D6,0x81D7,0x81D8,0x81D9,0x81DA,0x81DB,/* 0x40-0x47 */
 	0x81DC,0x81DD,0x81DE,0x81DF,0x81E0,0x81E1,0x81E2,0x81E4,/* 0x48-0x4F */
-	0x81E5,0x81E6,0xF9F6,0x81E9,0x81EB,0x81EE,0x81EF,0x81F0,/* 0x50-0x57 */
+	0x81E5,0x81E6,0x81E8,0x81E9,0x81EB,0x81EE,0x81EF,0x81F0,/* 0x50-0x57 */
 	0x81F1,0x81F2,0x81F5,0x81F6,0x81F7,0x81F8,0x81F9,0x81FA,/* 0x58-0x5F */
 	0x81FD,0x81FF,0x8203,0x8207,0x8208,0x8209,0x820A,0x820B,/* 0x60-0x67 */
 	0x820E,0x820F,0x8211,0x8213,0x8215,0x8216,0x8217,0x8218,/* 0x68-0x6F */
 	0x8219,0x821A,0x821D,0x8220,0x8224,0x8225,0x8226,0x8227,/* 0x70-0x77 */
 	0x8229,0x822E,0x8232,0x823A,0x823C,0x823D,0x823F,0x0000,/* 0x78-0x7F */
-	
+
 	0x8240,0x8241,0x8242,0x8243,0x8245,0x8246,0x8248,0x824A,/* 0x80-0x87 */
 	0x824C,0x824D,0x824E,0x8250,0x8251,0x8252,0x8253,0x8254,/* 0x88-0x8F */
 	0x8255,0x8256,0x8257,0x8259,0x825B,0x825C,0x825D,0x825E,/* 0x90-0x97 */
 	0x8260,0x8261,0x8262,0x8263,0x8264,0x8265,0x8266,0x8267,/* 0x98-0x9F */
 	0x8269,0x62E7,0x6CDE,0x725B,0x626D,0x94AE,0x7EBD,0x8113,/* 0xA0-0xA7 */
-	0x6D53,0x519C,0xF943,0x5974,0x52AA,0xF960,0xF981,0x6696,/* 0xA8-0xAF */
+	0x6D53,0x519C,0x5F04,0x5974,0x52AA,0x6012,0x5973,0x6696,/* 0xA8-0xAF */
 	0x8650,0x759F,0x632A,0x61E6,0x7CEF,0x8BFA,0x54E6,0x6B27,/* 0xB0-0xB7 */
 	0x9E25,0x6BB4,0x85D5,0x5455,0x5076,0x6CA4,0x556A,0x8DB4,/* 0xB8-0xBF */
 	0x722C,0x5E15,0x6015,0x7436,0x62CD,0x6392,0x724C,0x5F98,/* 0xC0-0xC7 */
@@ -2440,7 +2440,7 @@
 	0x82C3,0x82C5,0x82C6,0x82C9,0x82D0,0x82D6,0x82D9,0x82DA,/* 0x68-0x6F */
 	0x82DD,0x82E2,0x82E7,0x82E8,0x82E9,0x82EA,0x82EC,0x82ED,/* 0x70-0x77 */
 	0x82EE,0x82F0,0x82F2,0x82F3,0x82F5,0x82F6,0x82F8,0x0000,/* 0x78-0x7F */
-	
+
 	0x82FA,0x82FC,0x82FD,0x82FE,0x82FF,0x8300,0x830A,0x830B,/* 0x80-0x87 */
 	0x830D,0x8310,0x8312,0x8313,0x8316,0x8318,0x8319,0x831D,/* 0x88-0x8F */
 	0x831E,0x831F,0x8320,0x8321,0x8322,0x8323,0x8324,0x8325,/* 0x90-0x97 */
@@ -2455,7 +2455,7 @@
 	0x66DD,0x7011,0x671F,0x6B3A,0x6816,0x621A,0x59BB,0x4E03,/* 0xD8-0xDF */
 	0x51C4,0x6F06,0x67D2,0x6C8F,0x5176,0x68CB,0x5947,0x6B67,/* 0xE0-0xE7 */
 	0x7566,0x5D0E,0x8110,0x9F50,0x65D7,0x7948,0x7941,0x9A91,/* 0xE8-0xEF */
-	0x8D77,0x5C82,0x4E5E,0x4F01,0x542F,0xF909,0x780C,0x5668,/* 0xF0-0xF7 */
+	0x8D77,0x5C82,0x4E5E,0x4F01,0x542F,0x5951,0x780C,0x5668,/* 0xF0-0xF7 */
 	0x6C14,0x8FC4,0x5F03,0x6C7D,0x6CE3,0x8BAB,0x6390,0x0000,/* 0xF8-0xFF */
 };
 
@@ -2476,9 +2476,9 @@
 	0x838C,0x838D,0x838F,0x8390,0x8391,0x8394,0x8395,0x8396,/* 0x68-0x6F */
 	0x8397,0x8399,0x839A,0x839D,0x839F,0x83A1,0x83A2,0x83A3,/* 0x70-0x77 */
 	0x83A4,0x83A5,0x83A6,0x83A7,0x83AC,0x83AD,0x83AE,0x0000,/* 0x78-0x7F */
-	
+
 	0x83AF,0x83B5,0x83BB,0x83BE,0x83BF,0x83C2,0x83C3,0x83C4,/* 0x80-0x87 */
-	0x83C6,0x83C8,0xF93E,0x83CB,0x83CD,0x83CE,0x83D0,0x83D1,/* 0x88-0x8F */
+	0x83C6,0x83C8,0x83C9,0x83CB,0x83CD,0x83CE,0x83D0,0x83D1,/* 0x88-0x8F */
 	0x83D2,0x83D3,0x83D5,0x83D7,0x83D9,0x83DA,0x83DB,0x83DE,/* 0x90-0x97 */
 	0x83E2,0x83E3,0x83E4,0x83E6,0x83E7,0x83E8,0x83EB,0x83EC,/* 0x98-0x9F */
 	0x83ED,0x6070,0x6D3D,0x7275,0x6266,0x948E,0x94C5,0x5343,/* 0xA0-0xA7 */
@@ -2487,9 +2487,9 @@
 	0x6B49,0x67AA,0x545B,0x8154,0x7F8C,0x5899,0x8537,0x5F3A,/* 0xB8-0xBF */
 	0x62A2,0x6A47,0x9539,0x6572,0x6084,0x6865,0x77A7,0x4E54,/* 0xC0-0xC7 */
 	0x4FA8,0x5DE7,0x9798,0x64AC,0x7FD8,0x5CED,0x4FCF,0x7A8D,/* 0xC8-0xCF */
-	0xFA00,0x8304,0x4E14,0x602F,0x7A83,0x94A6,0x4FB5,0x4EB2,/* 0xD0-0xD7 */
+	0x5207,0x8304,0x4E14,0x602F,0x7A83,0x94A6,0x4FB5,0x4EB2,/* 0xD0-0xD7 */
 	0x79E6,0x7434,0x52E4,0x82B9,0x64D2,0x79BD,0x5BDD,0x6C81,/* 0xD8-0xDF */
-	0x9752,0x8F7B,0x6C22,0x503E,0x537F,0x6E05,0x64CE,0xFA12,/* 0xE0-0xE7 */
+	0x9752,0x8F7B,0x6C22,0x503E,0x537F,0x6E05,0x64CE,0x6674,/* 0xE0-0xE7 */
 	0x6C30,0x60C5,0x9877,0x8BF7,0x5E86,0x743C,0x7A77,0x79CB,/* 0xE8-0xEF */
 	0x4E18,0x90B1,0x7403,0x6C42,0x56DA,0x914B,0x6CC5,0x8D8B,/* 0xF0-0xF7 */
 	0x533A,0x86C6,0x66F2,0x8EAF,0x5C48,0x9A71,0x6E20,0x0000,/* 0xF8-0xFF */
@@ -2511,8 +2511,8 @@
 	0x8421,0x8422,0x8423,0x8429,0x842A,0x842B,0x842C,0x842D,/* 0x60-0x67 */
 	0x842E,0x842F,0x8430,0x8432,0x8433,0x8434,0x8435,0x8436,/* 0x68-0x6F */
 	0x8437,0x8439,0x843A,0x843B,0x843E,0x843F,0x8440,0x8441,/* 0x70-0x77 */
-	0x8442,0x8443,0x8444,0x8445,0x8447,0x8448,0xF96E,0x0000,/* 0x78-0x7F */
-	
+	0x8442,0x8443,0x8444,0x8445,0x8447,0x8448,0x8449,0x0000,/* 0x78-0x7F */
+
 	0x844A,0x844B,0x844C,0x844D,0x844E,0x844F,0x8450,0x8452,/* 0x80-0x87 */
 	0x8453,0x8454,0x8455,0x8456,0x8458,0x845D,0x845E,0x845F,/* 0x88-0x8F */
 	0x8460,0x8462,0x8464,0x8465,0x8466,0x8467,0x8468,0x846A,/* 0x90-0x97 */
@@ -2526,9 +2526,9 @@
 	0x5203,0x598A,0x7EAB,0x6254,0x4ECD,0x65E5,0x620E,0x8338,/* 0xD0-0xD7 */
 	0x84C9,0x8363,0x878D,0x7194,0x6EB6,0x5BB9,0x7ED2,0x5197,/* 0xD8-0xDF */
 	0x63C9,0x67D4,0x8089,0x8339,0x8815,0x5112,0x5B7A,0x5982,/* 0xE0-0xE7 */
-	0x8FB1,0x4E73,0x6C5D,0x5165,0x8925,0x8F6F,0xF9C6,0x854A,/* 0xE8-0xEF */
-	0x745E,0x9510,0x95F0,0x6DA6,0xF974,0x5F31,0x6492,0x6D12,/* 0xF0-0xF7 */
-	0x8428,0x816E,0x9CC3,0xF96C,0x8D5B,0x4E09,0x53C1,0x0000,/* 0xF8-0xFF */
+	0x8FB1,0x4E73,0x6C5D,0x5165,0x8925,0x8F6F,0x962E,0x854A,/* 0xE8-0xEF */
+	0x745E,0x9510,0x95F0,0x6DA6,0x82E5,0x5F31,0x6492,0x6D12,/* 0xF0-0xF7 */
+	0x8428,0x816E,0x9CC3,0x585E,0x8D5B,0x4E09,0x53C1,0x0000,/* 0xF8-0xFF */
 };
 
 static wchar_t c2u_C9[256] = {
@@ -2548,9 +2548,9 @@
 	0x84B1,0x84B3,0x84B5,0x84B6,0x84B7,0x84BB,0x84BC,0x84BE,/* 0x68-0x6F */
 	0x84C0,0x84C2,0x84C3,0x84C5,0x84C6,0x84C7,0x84C8,0x84CB,/* 0x70-0x77 */
 	0x84CC,0x84CE,0x84CF,0x84D2,0x84D4,0x84D5,0x84D7,0x0000,/* 0x78-0x7F */
-	
+
 	0x84D8,0x84D9,0x84DA,0x84DB,0x84DC,0x84DE,0x84E1,0x84E2,/* 0x80-0x87 */
-	0x84E4,0x84E7,0x84E8,0x84E9,0x84EA,0x84EB,0x84ED,0xF999,/* 0x88-0x8F */
+	0x84E4,0x84E7,0x84E8,0x84E9,0x84EA,0x84EB,0x84ED,0x84EE,/* 0x88-0x8F */
 	0x84EF,0x84F1,0x84F2,0x84F3,0x84F4,0x84F5,0x84F6,0x84F7,/* 0x90-0x97 */
 	0x84F8,0x84F9,0x84FA,0x84FB,0x84FD,0x84FE,0x8500,0x8501,/* 0x98-0x9F */
 	0x8502,0x4F1E,0x6563,0x6851,0x55D3,0x4E27,0x6414,0x9A9A,/* 0xA0-0xA7 */
@@ -2563,7 +2563,7 @@
 	0x97F6,0x5C11,0x54E8,0x90B5,0x7ECD,0x5962,0x8D4A,0x86C7,/* 0xD8-0xDF */
 	0x820C,0x820D,0x8D66,0x6444,0x5C04,0x6151,0x6D89,0x793E,/* 0xE0-0xE7 */
 	0x8BBE,0x7837,0x7533,0x547B,0x4F38,0x8EAB,0x6DF1,0x5A20,/* 0xE8-0xEF */
-	0x7EC5,0xFA19,0xF972,0x5BA1,0x5A76,0x751A,0x80BE,0x614E,/* 0xF0-0xF7 */
+	0x7EC5,0x795E,0x6C88,0x5BA1,0x5A76,0x751A,0x80BE,0x614E,/* 0xF0-0xF7 */
 	0x6E17,0x58F0,0x751F,0x7525,0x7272,0x5347,0x7EF3,0x0000,/* 0xF8-0xFF */
 };
 
@@ -2584,14 +2584,14 @@
 	0x8534,0x8535,0x8536,0x853E,0x853F,0x8540,0x8541,0x8542,/* 0x68-0x6F */
 	0x8544,0x8545,0x8546,0x8547,0x854B,0x854C,0x854D,0x854E,/* 0x70-0x77 */
 	0x854F,0x8550,0x8551,0x8552,0x8553,0x8554,0x8555,0x0000,/* 0x78-0x7F */
-	
+
 	0x8557,0x8558,0x855A,0x855B,0x855C,0x855D,0x855F,0x8560,/* 0x80-0x87 */
 	0x8561,0x8562,0x8563,0x8565,0x8566,0x8567,0x8569,0x856A,/* 0x88-0x8F */
 	0x856B,0x856C,0x856D,0x856E,0x856F,0x8570,0x8571,0x8573,/* 0x90-0x97 */
 	0x8575,0x8576,0x8577,0x8578,0x857C,0x857D,0x857F,0x8580,/* 0x98-0x9F */
-	0x8581,0xF96D,0x76DB,0x5269,0x80DC,0x5723,0x5E08,0x5931,/* 0xA0-0xA7 */
+	0x8581,0x7701,0x76DB,0x5269,0x80DC,0x5723,0x5E08,0x5931,/* 0xA0-0xA7 */
 	0x72EE,0x65BD,0x6E7F,0x8BD7,0x5C38,0x8671,0x5341,0x77F3,/* 0xA8-0xAF */
-	0xF973,0x65F6,0xF9FD,0x98DF,0x8680,0x5B9E,0x8BC6,0x53F2,/* 0xB0-0xB7 */
+	0x62FE,0x65F6,0x4EC0,0x98DF,0x8680,0x5B9E,0x8BC6,0x53F2,/* 0xB0-0xB7 */
 	0x77E2,0x4F7F,0x5C4E,0x9A76,0x59CB,0x5F0F,0x793A,0x58EB,/* 0xB8-0xBF */
 	0x4E16,0x67FF,0x4E8B,0x62ED,0x8A93,0x901D,0x52BF,0x662F,/* 0xC0-0xC7 */
 	0x55DC,0x566C,0x9002,0x4ED5,0x4F8D,0x91CA,0x9970,0x6C0F,/* 0xC8-0xCF */
@@ -2619,8 +2619,8 @@
 	0x85AB,0x85AC,0x85AD,0x85B1,0x85B2,0x85B3,0x85B4,0x85B5,/* 0x60-0x67 */
 	0x85B6,0x85B8,0x85BA,0x85BB,0x85BC,0x85BD,0x85BE,0x85BF,/* 0x68-0x6F */
 	0x85C0,0x85C2,0x85C3,0x85C4,0x85C5,0x85C6,0x85C7,0x85C8,/* 0x70-0x77 */
-	0x85CA,0x85CB,0x85CC,0xF923,0x85CE,0x85D1,0x85D2,0x0000,/* 0x78-0x7F */
-	
+	0x85CA,0x85CB,0x85CC,0x85CD,0x85CE,0x85D1,0x85D2,0x0000,/* 0x78-0x7F */
+
 	0x85D4,0x85D6,0x85D7,0x85D8,0x85D9,0x85DA,0x85DB,0x85DD,/* 0x80-0x87 */
 	0x85DE,0x85DF,0x85E0,0x85E1,0x85E2,0x85E3,0x85E5,0x85E6,/* 0x88-0x8F */
 	0x85E7,0x85E8,0x85EA,0x85EB,0x85EC,0x85ED,0x85EE,0x85EF,/* 0x90-0x97 */
@@ -2635,7 +2635,7 @@
 	0x7D20,0x901F,0x7C9F,0x50F3,0x5851,0x6EAF,0x5BBF,0x8BC9,/* 0xD8-0xDF */
 	0x8083,0x9178,0x849C,0x7B97,0x867D,0x968B,0x968F,0x7EE5,/* 0xE0-0xE7 */
 	0x9AD3,0x788E,0x5C81,0x7A57,0x9042,0x96A7,0x795F,0x5B59,/* 0xE8-0xEF */
-	0x635F,0x7B0B,0x84D1,0x68AD,0x5506,0x7F29,0x7410,0xF96A,/* 0xF0-0xF7 */
+	0x635F,0x7B0B,0x84D1,0x68AD,0x5506,0x7F29,0x7410,0x7D22,/* 0xF0-0xF7 */
 	0x9501,0x6240,0x584C,0x4ED6,0x5B83,0x5979,0x5854,0x0000,/* 0xF8-0xFF */
 };
 
@@ -2648,24 +2648,24 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x28-0x2F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x30-0x37 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x38-0x3F */
-	0x85F9,0xF9F0,0x85FC,0x85FD,0x85FE,0x8600,0x8601,0x8602,/* 0x40-0x47 */
-	0x8603,0x8604,0xF935,0x8607,0x8608,0x8609,0x860A,0x860B,/* 0x48-0x4F */
+	0x85F9,0x85FA,0x85FC,0x85FD,0x85FE,0x8600,0x8601,0x8602,/* 0x40-0x47 */
+	0x8603,0x8604,0x8606,0x8607,0x8608,0x8609,0x860A,0x860B,/* 0x48-0x4F */
 	0x860C,0x860D,0x860E,0x860F,0x8610,0x8612,0x8613,0x8614,/* 0x50-0x57 */
 	0x8615,0x8617,0x8618,0x8619,0x861A,0x861B,0x861C,0x861D,/* 0x58-0x5F */
 	0x861E,0x861F,0x8620,0x8621,0x8622,0x8623,0x8624,0x8625,/* 0x60-0x67 */
-	0x8626,0x8628,0x862A,0x862B,0x862C,0xF91F,0x862E,0x862F,/* 0x68-0x6F */
+	0x8626,0x8628,0x862A,0x862B,0x862C,0x862D,0x862E,0x862F,/* 0x68-0x6F */
 	0x8630,0x8631,0x8632,0x8633,0x8634,0x8635,0x8636,0x8637,/* 0x70-0x77 */
-	0x8639,0x863A,0x863B,0x863D,0x863E,0xF910,0x8640,0x0000,/* 0x78-0x7F */
-	
+	0x8639,0x863A,0x863B,0x863D,0x863E,0x863F,0x8640,0x0000,/* 0x78-0x7F */
+
 	0x8641,0x8642,0x8643,0x8644,0x8645,0x8646,0x8647,0x8648,/* 0x80-0x87 */
 	0x8649,0x864A,0x864B,0x864C,0x8652,0x8653,0x8655,0x8656,/* 0x88-0x8F */
-	0x8657,0x8658,0x8659,0x865B,0xF936,0x865D,0x865F,0x8660,/* 0x90-0x97 */
+	0x8657,0x8658,0x8659,0x865B,0x865C,0x865D,0x865F,0x8660,/* 0x90-0x97 */
 	0x8661,0x8663,0x8664,0x8665,0x8666,0x8667,0x8668,0x8669,/* 0x98-0x9F */
 	0x866A,0x736D,0x631E,0x8E4B,0x8E0F,0x80CE,0x82D4,0x62AC,/* 0xA0-0xA7 */
 	0x53F0,0x6CF0,0x915E,0x592A,0x6001,0x6C70,0x574D,0x644A,/* 0xA8-0xAF */
 	0x8D2A,0x762B,0x6EE9,0x575B,0x6A80,0x75F0,0x6F6D,0x8C2D,/* 0xB0-0xB7 */
 	0x8C08,0x5766,0x6BEF,0x8892,0x78B3,0x63A2,0x53F9,0x70AD,/* 0xB8-0xBF */
-	0x6C64,0x5858,0x642A,0x5802,0x68E0,0x819B,0x5510,0xFA03,/* 0xC0-0xC7 */
+	0x6C64,0x5858,0x642A,0x5802,0x68E0,0x819B,0x5510,0x7CD6,/* 0xC0-0xC7 */
 	0x5018,0x8EBA,0x6DCC,0x8D9F,0x70EB,0x638F,0x6D9B,0x6ED4,/* 0xC8-0xCF */
 	0x7EE6,0x8404,0x6843,0x9003,0x6DD8,0x9676,0x8BA8,0x5957,/* 0xD0-0xD7 */
 	0x7279,0x85E4,0x817E,0x75BC,0x8A8A,0x68AF,0x5254,0x8E22,/* 0xD8-0xDF */
@@ -2692,7 +2692,7 @@
 	0x86B3,0x86B7,0x86B8,0x86B9,0x86BB,0x86BC,0x86BD,0x86BE,/* 0x68-0x6F */
 	0x86BF,0x86C1,0x86C2,0x86C3,0x86C5,0x86C8,0x86CC,0x86CD,/* 0x70-0x77 */
 	0x86D2,0x86D3,0x86D5,0x86D6,0x86D7,0x86DA,0x86DC,0x0000,/* 0x78-0x7F */
-	
+
 	0x86DD,0x86E0,0x86E1,0x86E2,0x86E3,0x86E5,0x86E6,0x86E7,/* 0x80-0x87 */
 	0x86E8,0x86EA,0x86EB,0x86EC,0x86EF,0x86F5,0x86F6,0x86F7,/* 0x88-0x8F */
 	0x86FA,0x86FB,0x86FC,0x86FD,0x86FF,0x8701,0x8704,0x8705,/* 0x90-0x97 */
@@ -2704,7 +2704,7 @@
 	0x5C60,0x571F,0x5410,0x5154,0x6E4D,0x56E2,0x63A8,0x9893,/* 0xC0-0xC7 */
 	0x817F,0x8715,0x892A,0x9000,0x541E,0x5C6F,0x81C0,0x62D6,/* 0xC8-0xCF */
 	0x6258,0x8131,0x9E35,0x9640,0x9A6E,0x9A7C,0x692D,0x59A5,/* 0xD0-0xD7 */
-	0xFA02,0x553E,0x6316,0x54C7,0x86D9,0x6D3C,0x5A03,0x74E6,/* 0xD8-0xDF */
+	0x62D3,0x553E,0x6316,0x54C7,0x86D9,0x6D3C,0x5A03,0x74E6,/* 0xD8-0xDF */
 	0x889C,0x6B6A,0x5916,0x8C4C,0x5F2F,0x6E7E,0x73A9,0x987D,/* 0xE0-0xE7 */
 	0x4E38,0x70F7,0x5B8C,0x7897,0x633D,0x665A,0x7696,0x60CB,/* 0xE8-0xEF */
 	0x5B9B,0x5A49,0x4E07,0x8155,0x6C6A,0x738B,0x4EA1,0x6789,/* 0xF0-0xF7 */
@@ -2728,7 +2728,7 @@
 	0x8756,0x8758,0x875A,0x875B,0x875C,0x875D,0x875E,0x875F,/* 0x68-0x6F */
 	0x8761,0x8762,0x8766,0x8767,0x8768,0x8769,0x876A,0x876B,/* 0x70-0x77 */
 	0x876C,0x876D,0x876F,0x8771,0x8772,0x8773,0x8775,0x0000,/* 0x78-0x7F */
-	
+
 	0x8777,0x8778,0x8779,0x877A,0x877F,0x8780,0x8781,0x8784,/* 0x80-0x87 */
 	0x8786,0x8787,0x8789,0x878A,0x878C,0x878E,0x878F,0x8790,/* 0x88-0x8F */
 	0x8791,0x8792,0x8794,0x8795,0x8796,0x8798,0x8799,0x879A,/* 0x90-0x97 */
@@ -2764,11 +2764,11 @@
 	0x87DE,0x87DF,0x87E1,0x87E2,0x87E3,0x87E4,0x87E6,0x87E7,/* 0x68-0x6F */
 	0x87E8,0x87E9,0x87EB,0x87EC,0x87ED,0x87EF,0x87F0,0x87F1,/* 0x70-0x77 */
 	0x87F2,0x87F3,0x87F4,0x87F5,0x87F6,0x87F7,0x87F8,0x0000,/* 0x78-0x7F */
-	
+
 	0x87FA,0x87FB,0x87FC,0x87FD,0x87FF,0x8800,0x8801,0x8802,/* 0x80-0x87 */
 	0x8804,0x8805,0x8806,0x8807,0x8808,0x8809,0x880B,0x880C,/* 0x88-0x8F */
 	0x880D,0x880E,0x880F,0x8810,0x8811,0x8812,0x8814,0x8817,/* 0x90-0x97 */
-	0x8818,0x8819,0x881A,0x881C,0x881D,0x881E,0xF927,0x8820,/* 0x98-0x9F */
+	0x8818,0x8819,0x881A,0x881C,0x881D,0x881E,0x881F,0x8820,/* 0x98-0x9F */
 	0x8823,0x7A00,0x606F,0x5E0C,0x6089,0x819D,0x5915,0x60DC,/* 0xA0-0xA7 */
 	0x7184,0x70EF,0x6EAA,0x6C50,0x7280,0x6A84,0x88AD,0x5E2D,/* 0xA8-0xAF */
 	0x4E60,0x5AB3,0x559C,0x94E3,0x6D17,0x7CFB,0x9699,0x620F,/* 0xB0-0xB7 */
@@ -2778,7 +2778,7 @@
 	0x95F2,0x6D8E,0x5F26,0x5ACC,0x663E,0x9669,0x73B0,0x732E,/* 0xD0-0xD7 */
 	0x53BF,0x817A,0x9985,0x7FA1,0x5BAA,0x9677,0x9650,0x7EBF,/* 0xD8-0xDF */
 	0x76F8,0x53A2,0x9576,0x9999,0x7BB1,0x8944,0x6E58,0x4E61,/* 0xE0-0xE7 */
-	0x7FD4,0xFA1A,0x8BE6,0x60F3,0x54CD,0x4EAB,0x9879,0x5DF7,/* 0xE8-0xEF */
+	0x7FD4,0x7965,0x8BE6,0x60F3,0x54CD,0x4EAB,0x9879,0x5DF7,/* 0xE8-0xEF */
 	0x6A61,0x50CF,0x5411,0x8C61,0x8427,0x785D,0x9704,0x524A,/* 0xF0-0xF7 */
 	0x54EE,0x56A3,0x9500,0x6D88,0x5BB5,0x6DC6,0x6653,0x0000,/* 0xF8-0xFF */
 };
@@ -2800,7 +2800,7 @@
 	0x8855,0x8856,0x8858,0x885A,0x885B,0x885C,0x885D,0x885E,/* 0x68-0x6F */
 	0x885F,0x8860,0x8866,0x8867,0x886A,0x886D,0x886F,0x8871,/* 0x70-0x77 */
 	0x8873,0x8874,0x8875,0x8876,0x8878,0x8879,0x887A,0x0000,/* 0x78-0x7F */
-	
+
 	0x887B,0x887C,0x8880,0x8883,0x8886,0x8887,0x8889,0x888A,/* 0x80-0x87 */
 	0x888C,0x888E,0x888F,0x8890,0x8891,0x8893,0x8894,0x8895,/* 0x88-0x8F */
 	0x8897,0x8898,0x8899,0x889A,0x889B,0x889D,0x889E,0x889F,/* 0x90-0x97 */
@@ -2811,7 +2811,7 @@
 	0x61C8,0x6CC4,0x6CFB,0x8C22,0x5C51,0x85AA,0x82AF,0x950C,/* 0xB8-0xBF */
 	0x6B23,0x8F9B,0x65B0,0x5FFB,0x5FC3,0x4FE1,0x8845,0x661F,/* 0xC0-0xC7 */
 	0x8165,0x7329,0x60FA,0x5174,0x5211,0x578B,0x5F62,0x90A2,/* 0xC8-0xCF */
-	0xFA08,0x9192,0x5E78,0x674F,0x6027,0x59D3,0x5144,0x51F6,/* 0xD0-0xD7 */
+	0x884C,0x9192,0x5E78,0x674F,0x6027,0x59D3,0x5144,0x51F6,/* 0xD0-0xD7 */
 	0x80F8,0x5308,0x6C79,0x96C4,0x718A,0x4F11,0x4FEE,0x7F9E,/* 0xD8-0xDF */
 	0x673D,0x55C5,0x9508,0x79C0,0x8896,0x7EE3,0x589F,0x620C,/* 0xE0-0xE7 */
 	0x9700,0x865A,0x5618,0x987B,0x5F90,0x8BB8,0x84C4,0x9157,/* 0xE8-0xEF */
@@ -2832,11 +2832,11 @@
 	0x88B6,0x88B8,0x88B9,0x88BA,0x88BB,0x88BD,0x88BE,0x88BF,/* 0x48-0x4F */
 	0x88C0,0x88C3,0x88C4,0x88C7,0x88C8,0x88CA,0x88CB,0x88CC,/* 0x50-0x57 */
 	0x88CD,0x88CF,0x88D0,0x88D1,0x88D3,0x88D6,0x88D7,0x88DA,/* 0x58-0x5F */
-	0x88DB,0x88DC,0x88DD,0x88DE,0x88E0,0xF9E8,0x88E6,0x88E7,/* 0x60-0x67 */
+	0x88DB,0x88DC,0x88DD,0x88DE,0x88E0,0x88E1,0x88E6,0x88E7,/* 0x60-0x67 */
 	0x88E9,0x88EA,0x88EB,0x88EC,0x88ED,0x88EE,0x88EF,0x88F2,/* 0x68-0x6F */
 	0x88F5,0x88F6,0x88F7,0x88FA,0x88FB,0x88FD,0x88FF,0x8900,/* 0x70-0x77 */
 	0x8901,0x8903,0x8904,0x8905,0x8906,0x8907,0x8908,0x0000,/* 0x78-0x7F */
-	
+
 	0x8909,0x890B,0x890C,0x890D,0x890E,0x890F,0x8911,0x8914,/* 0x80-0x87 */
 	0x8915,0x8916,0x8917,0x8918,0x891C,0x891D,0x891E,0x891F,/* 0x88-0x8F */
 	0x8920,0x8922,0x8923,0x8924,0x8926,0x8927,0x8928,0x8929,/* 0x90-0x97 */
@@ -2846,7 +2846,7 @@
 	0x5BFB,0x9A6F,0x5DE1,0x6B89,0x6C5B,0x8BAD,0x8BAF,0x900A,/* 0xB0-0xB7 */
 	0x8FC5,0x538B,0x62BC,0x9E26,0x9E2D,0x5440,0x4E2B,0x82BD,/* 0xB8-0xBF */
 	0x7259,0x869C,0x5D16,0x8859,0x6DAF,0x96C5,0x54D1,0x4E9A,/* 0xC0-0xC7 */
-	0x8BB6,0x7109,0xF99E,0x9609,0x70DF,0x6DF9,0x76D0,0x4E25,/* 0xC8-0xCF */
+	0x8BB6,0x7109,0x54BD,0x9609,0x70DF,0x6DF9,0x76D0,0x4E25,/* 0xC8-0xCF */
 	0x7814,0x8712,0x5CA9,0x5EF6,0x8A00,0x989C,0x960E,0x708E,/* 0xD0-0xD7 */
 	0x6CBF,0x5944,0x63A9,0x773C,0x884D,0x6F14,0x8273,0x5830,/* 0xD8-0xDF */
 	0x71D5,0x538C,0x781A,0x96C1,0x5501,0x5F66,0x7130,0x5BB4,/* 0xE0-0xE7 */
@@ -2869,12 +2869,12 @@
 	0x894A,0x894B,0x894C,0x894D,0x894E,0x894F,0x8950,0x8951,/* 0x50-0x57 */
 	0x8952,0x8953,0x8954,0x8955,0x8956,0x8957,0x8958,0x8959,/* 0x58-0x5F */
 	0x895A,0x895B,0x895C,0x895D,0x8960,0x8961,0x8962,0x8963,/* 0x60-0x67 */
-	0xF924,0x8965,0x8967,0x8968,0x8969,0x896A,0x896B,0x896C,/* 0x68-0x6F */
+	0x8964,0x8965,0x8967,0x8968,0x8969,0x896A,0x896B,0x896C,/* 0x68-0x6F */
 	0x896D,0x896E,0x896F,0x8970,0x8971,0x8972,0x8973,0x8974,/* 0x70-0x77 */
 	0x8975,0x8976,0x8977,0x8978,0x8979,0x897A,0x897C,0x0000,/* 0x78-0x7F */
-	
+
 	0x897D,0x897E,0x8980,0x8982,0x8984,0x8985,0x8987,0x8988,/* 0x80-0x87 */
-	0x8989,0x898A,0xFA0A,0x898C,0x898D,0x898E,0x898F,0x8990,/* 0x88-0x8F */
+	0x8989,0x898A,0x898B,0x898C,0x898D,0x898E,0x898F,0x8990,/* 0x88-0x8F */
 	0x8991,0x8992,0x8993,0x8994,0x8995,0x8996,0x8997,0x8998,/* 0x90-0x97 */
 	0x8999,0x899A,0x899B,0x899C,0x899D,0x899E,0x899F,0x89A0,/* 0x98-0x9F */
 	0x89A1,0x6447,0x5C27,0x9065,0x7A91,0x8C23,0x59DA,0x54AC,/* 0xA0-0xA7 */
@@ -2883,9 +2883,9 @@
 	0x814B,0x591C,0x6DB2,0x4E00,0x58F9,0x533B,0x63D6,0x94F1,/* 0xB8-0xBF */
 	0x4F9D,0x4F0A,0x8863,0x9890,0x5937,0x9057,0x79FB,0x4EEA,/* 0xC0-0xC7 */
 	0x80F0,0x7591,0x6C82,0x5B9C,0x59E8,0x5F5D,0x6905,0x8681,/* 0xC8-0xCF */
-	0x501A,0x5DF2,0x4E59,0x77E3,0x4EE5,0x827A,0x6291,0xF9E0,/* 0xD0-0xD7 */
-	0x9091,0x5C79,0x4EBF,0x5F79,0x81C6,0xFA25,0x8084,0x75AB,/* 0xD8-0xDF */
-	0x4EA6,0x88D4,0x610F,0x6BC5,0x5FC6,0x4E49,0xFA17,0x6EA2,/* 0xE0-0xE7 */
+	0x501A,0x5DF2,0x4E59,0x77E3,0x4EE5,0x827A,0x6291,0x6613,/* 0xD0-0xD7 */
+	0x9091,0x5C79,0x4EBF,0x5F79,0x81C6,0x9038,0x8084,0x75AB,/* 0xD8-0xDF */
+	0x4EA6,0x88D4,0x610F,0x6BC5,0x5FC6,0x4E49,0x76CA,0x6EA2,/* 0xE0-0xE7 */
 	0x8BE3,0x8BAE,0x8C0A,0x8BD1,0x5F02,0x7FFC,0x7FCC,0x7ECE,/* 0xE8-0xEF */
 	0x8335,0x836B,0x56E0,0x6BB7,0x97F3,0x9634,0x59FB,0x541F,/* 0xF0-0xF7 */
 	0x94F6,0x6DEB,0x5BC5,0x996E,0x5C39,0x5F15,0x9690,0x0000,/* 0xF8-0xFF */
@@ -2908,7 +2908,7 @@
 	0x89DD,0x89DF,0x89E0,0x89E1,0x89E2,0x89E4,0x89E7,0x89E8,/* 0x68-0x6F */
 	0x89E9,0x89EA,0x89EC,0x89ED,0x89EE,0x89F0,0x89F1,0x89F2,/* 0x70-0x77 */
 	0x89F4,0x89F5,0x89F6,0x89F7,0x89F8,0x89F9,0x89FA,0x0000,/* 0x78-0x7F */
-	
+
 	0x89FB,0x89FC,0x89FD,0x89FE,0x89FF,0x8A01,0x8A02,0x8A03,/* 0x80-0x87 */
 	0x8A04,0x8A05,0x8A06,0x8A08,0x8A09,0x8A0A,0x8A0B,0x8A0C,/* 0x88-0x8F */
 	0x8A0D,0x8A0E,0x8A0F,0x8A10,0x8A11,0x8A12,0x8A13,0x8A14,/* 0x90-0x97 */
@@ -2923,7 +2923,7 @@
 	0x8FC2,0x6DE4,0x4E8E,0x76C2,0x6986,0x865E,0x611A,0x8206,/* 0xD8-0xDF */
 	0x4F59,0x4FDE,0x903E,0x9C7C,0x6109,0x6E1D,0x6E14,0x9685,/* 0xE0-0xE7 */
 	0x4E88,0x5A31,0x96E8,0x4E0E,0x5C7F,0x79B9,0x5B87,0x8BED,/* 0xE8-0xEF */
-	0xFA1E,0x7389,0x57DF,0x828B,0x90C1,0x5401,0x9047,0x55BB,/* 0xF0-0xF7 */
+	0x7FBD,0x7389,0x57DF,0x828B,0x90C1,0x5401,0x9047,0x55BB,/* 0xF0-0xF7 */
 	0x5CEA,0x5FA1,0x6108,0x6B32,0x72F1,0x80B2,0x8A89,0x0000,/* 0xF8-0xFF */
 };
 
@@ -2944,7 +2944,7 @@
 	0x8A47,0x8A49,0x8A4A,0x8A4B,0x8A4C,0x8A4D,0x8A4E,0x8A4F,/* 0x68-0x6F */
 	0x8A50,0x8A51,0x8A52,0x8A53,0x8A54,0x8A55,0x8A56,0x8A57,/* 0x70-0x77 */
 	0x8A58,0x8A59,0x8A5A,0x8A5B,0x8A5C,0x8A5D,0x8A5E,0x0000,/* 0x78-0x7F */
-	
+
 	0x8A5F,0x8A60,0x8A61,0x8A62,0x8A63,0x8A64,0x8A65,0x8A66,/* 0x80-0x87 */
 	0x8A67,0x8A68,0x8A69,0x8A6A,0x8A6B,0x8A6C,0x8A6D,0x8A6E,/* 0x88-0x8F */
 	0x8A6F,0x8A70,0x8A71,0x8A72,0x8A73,0x8A74,0x8A75,0x8A76,/* 0x90-0x97 */
@@ -2976,17 +2976,17 @@
 	0x8A8B,0x8A8C,0x8A8D,0x8A8E,0x8A8F,0x8A90,0x8A91,0x8A92,/* 0x48-0x4F */
 	0x8A94,0x8A95,0x8A96,0x8A97,0x8A98,0x8A99,0x8A9A,0x8A9B,/* 0x50-0x57 */
 	0x8A9C,0x8A9D,0x8A9E,0x8A9F,0x8AA0,0x8AA1,0x8AA2,0x8AA3,/* 0x58-0x5F */
-	0x8AA4,0x8AA5,0x8AA6,0x8AA7,0x8AA8,0x8AA9,0xF9A1,0x8AAB,/* 0x60-0x67 */
+	0x8AA4,0x8AA5,0x8AA6,0x8AA7,0x8AA8,0x8AA9,0x8AAA,0x8AAB,/* 0x60-0x67 */
 	0x8AAC,0x8AAD,0x8AAE,0x8AAF,0x8AB0,0x8AB1,0x8AB2,0x8AB3,/* 0x68-0x6F */
 	0x8AB4,0x8AB5,0x8AB6,0x8AB7,0x8AB8,0x8AB9,0x8ABA,0x8ABB,/* 0x70-0x77 */
 	0x8ABC,0x8ABD,0x8ABE,0x8ABF,0x8AC0,0x8AC1,0x8AC2,0x0000,/* 0x78-0x7F */
-	
+
 	0x8AC3,0x8AC4,0x8AC5,0x8AC6,0x8AC7,0x8AC8,0x8AC9,0x8ACA,/* 0x80-0x87 */
-	0x8ACB,0x8ACC,0x8ACD,0x8ACE,0x8ACF,0x8AD0,0x8AD1,0xF97D,/* 0x88-0x8F */
-	0x8AD3,0x8AD4,0x8AD5,0xF941,0x8AD7,0x8AD8,0x8AD9,0x8ADA,/* 0x90-0x97 */
+	0x8ACB,0x8ACC,0x8ACD,0x8ACE,0x8ACF,0x8AD0,0x8AD1,0x8AD2,/* 0x88-0x8F */
+	0x8AD3,0x8AD4,0x8AD5,0x8AD6,0x8AD7,0x8AD8,0x8AD9,0x8ADA,/* 0x90-0x97 */
 	0x8ADB,0x8ADC,0x8ADD,0x8ADE,0x8ADF,0x8AE0,0x8AE1,0x8AE2,/* 0x98-0x9F */
 	0x8AE3,0x94E1,0x95F8,0x7728,0x6805,0x69A8,0x548B,0x4E4D,/* 0xA0-0xA7 */
-	0x70B8,0x8BC8,0x6458,0x658B,0xFA04,0x7A84,0x503A,0x5BE8,/* 0xA8-0xAF */
+	0x70B8,0x8BC8,0x6458,0x658B,0x5B85,0x7A84,0x503A,0x5BE8,/* 0xA8-0xAF */
 	0x77BB,0x6BE1,0x8A79,0x7C98,0x6CBE,0x76CF,0x65A9,0x8F97,/* 0xB0-0xB7 */
 	0x5D2D,0x5C55,0x8638,0x6808,0x5360,0x6218,0x7AD9,0x6E5B,/* 0xB8-0xBF */
 	0x7EFD,0x6A1F,0x7AE0,0x5F70,0x6F33,0x5F20,0x638C,0x6DA8,/* 0xC0-0xC7 */
@@ -3010,13 +3010,13 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x38-0x3F */
 	0x8AE4,0x8AE5,0x8AE6,0x8AE7,0x8AE8,0x8AE9,0x8AEA,0x8AEB,/* 0x40-0x47 */
 	0x8AEC,0x8AED,0x8AEE,0x8AEF,0x8AF0,0x8AF1,0x8AF2,0x8AF3,/* 0x48-0x4F */
-	0x8AF4,0x8AF5,0x8AF6,0x8AF7,0xFA22,0x8AF9,0x8AFA,0x8AFB,/* 0x50-0x57 */
-	0x8AFC,0x8AFD,0xF95D,0x8AFF,0x8B00,0x8B01,0x8B02,0x8B03,/* 0x58-0x5F */
+	0x8AF4,0x8AF5,0x8AF6,0x8AF7,0x8AF8,0x8AF9,0x8AFA,0x8AFB,/* 0x50-0x57 */
+	0x8AFC,0x8AFD,0x8AFE,0x8AFF,0x8B00,0x8B01,0x8B02,0x8B03,/* 0x58-0x5F */
 	0x8B04,0x8B05,0x8B06,0x8B08,0x8B09,0x8B0A,0x8B0B,0x8B0C,/* 0x60-0x67 */
 	0x8B0D,0x8B0E,0x8B0F,0x8B10,0x8B11,0x8B12,0x8B13,0x8B14,/* 0x68-0x6F */
 	0x8B15,0x8B16,0x8B17,0x8B18,0x8B19,0x8B1A,0x8B1B,0x8B1C,/* 0x70-0x77 */
 	0x8B1D,0x8B1E,0x8B1F,0x8B20,0x8B21,0x8B22,0x8B23,0x0000,/* 0x78-0x7F */
-	
+
 	0x8B24,0x8B25,0x8B27,0x8B28,0x8B29,0x8B2A,0x8B2B,0x8B2C,/* 0x80-0x87 */
 	0x8B2D,0x8B2E,0x8B2F,0x8B30,0x8B31,0x8B32,0x8B33,0x8B34,/* 0x88-0x8F */
 	0x8B35,0x8B36,0x8B37,0x8B38,0x8B39,0x8B3A,0x8B3B,0x8B3C,/* 0x90-0x97 */
@@ -3026,7 +3026,7 @@
 	0x804C,0x76F4,0x690D,0x6B96,0x6267,0x503C,0x4F84,0x5740,/* 0xB0-0xB7 */
 	0x6307,0x6B62,0x8DBE,0x53EA,0x65E8,0x7EB8,0x5FD7,0x631A,/* 0xB8-0xBF */
 	0x63B7,0x81F3,0x81F4,0x7F6E,0x5E1C,0x5CD9,0x5236,0x667A,/* 0xC0-0xC7 */
-	0x79E9,0x7A1A,0x8D28,0xF9FB,0x75D4,0x6EDE,0x6CBB,0x7A92,/* 0xC8-0xCF */
+	0x79E9,0x7A1A,0x8D28,0x7099,0x75D4,0x6EDE,0x6CBB,0x7A92,/* 0xC8-0xCF */
 	0x4E2D,0x76C5,0x5FE0,0x949F,0x8877,0x7EC8,0x79CD,0x80BF,/* 0xD0-0xD7 */
 	0x91CD,0x4EF2,0x4F17,0x821F,0x5468,0x5DDE,0x6D32,0x8BCC,/* 0xD8-0xDF */
 	0x7CA5,0x8F74,0x8098,0x5E1A,0x5492,0x76B1,0x5B99,0x663C,/* 0xE0-0xE7 */
@@ -3046,13 +3046,13 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x38-0x3F */
 	0x8B46,0x8B47,0x8B48,0x8B49,0x8B4A,0x8B4B,0x8B4C,0x8B4D,/* 0x40-0x47 */
 	0x8B4E,0x8B4F,0x8B50,0x8B51,0x8B52,0x8B53,0x8B54,0x8B55,/* 0x48-0x4F */
-	0x8B56,0x8B57,0xF9FC,0x8B59,0x8B5A,0x8B5B,0x8B5C,0x8B5D,/* 0x50-0x57 */
+	0x8B56,0x8B57,0x8B58,0x8B59,0x8B5A,0x8B5B,0x8B5C,0x8B5D,/* 0x50-0x57 */
 	0x8B5E,0x8B5F,0x8B60,0x8B61,0x8B62,0x8B63,0x8B64,0x8B65,/* 0x58-0x5F */
 	0x8B67,0x8B68,0x8B69,0x8B6A,0x8B6B,0x8B6D,0x8B6E,0x8B6F,/* 0x60-0x67 */
 	0x8B70,0x8B71,0x8B72,0x8B73,0x8B74,0x8B75,0x8B76,0x8B77,/* 0x68-0x6F */
 	0x8B78,0x8B79,0x8B7A,0x8B7B,0x8B7C,0x8B7D,0x8B7E,0x8B7F,/* 0x70-0x77 */
-	0xF95A,0x8B81,0x8B82,0x8B83,0x8B84,0x8B85,0x8B86,0x0000,/* 0x78-0x7F */
-	
+	0x8B80,0x8B81,0x8B82,0x8B83,0x8B84,0x8B85,0x8B86,0x0000,/* 0x78-0x7F */
+
 	0x8B87,0x8B88,0x8B89,0x8B8A,0x8B8B,0x8B8C,0x8B8D,0x8B8E,/* 0x80-0x87 */
 	0x8B8F,0x8B90,0x8B91,0x8B92,0x8B93,0x8B94,0x8B95,0x8B96,/* 0x88-0x8F */
 	0x8B97,0x8B98,0x8B99,0x8B9A,0x8B9B,0x8B9C,0x8B9D,0x8B9E,/* 0x90-0x97 */
@@ -3081,14 +3081,14 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x30-0x37 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x38-0x3F */
 	0x8C38,0x8C39,0x8C3A,0x8C3B,0x8C3C,0x8C3D,0x8C3E,0x8C3F,/* 0x40-0x47 */
-	0x8C40,0x8C42,0x8C43,0x8C44,0x8C45,0xF900,0x8C4A,0x8C4B,/* 0x48-0x4F */
+	0x8C40,0x8C42,0x8C43,0x8C44,0x8C45,0x8C48,0x8C4A,0x8C4B,/* 0x48-0x4F */
 	0x8C4D,0x8C4E,0x8C4F,0x8C50,0x8C51,0x8C52,0x8C53,0x8C54,/* 0x50-0x57 */
 	0x8C56,0x8C57,0x8C58,0x8C59,0x8C5B,0x8C5C,0x8C5D,0x8C5E,/* 0x58-0x5F */
 	0x8C5F,0x8C60,0x8C63,0x8C64,0x8C65,0x8C66,0x8C67,0x8C68,/* 0x60-0x67 */
-	0x8C69,0xFA16,0x8C6D,0x8C6E,0x8C6F,0x8C70,0x8C71,0x8C72,/* 0x68-0x6F */
+	0x8C69,0x8C6C,0x8C6D,0x8C6E,0x8C6F,0x8C70,0x8C71,0x8C72,/* 0x68-0x6F */
 	0x8C74,0x8C75,0x8C76,0x8C77,0x8C7B,0x8C7C,0x8C7D,0x8C7E,/* 0x70-0x77 */
 	0x8C7F,0x8C80,0x8C81,0x8C83,0x8C84,0x8C86,0x8C87,0x0000,/* 0x78-0x7F */
-	
+
 	0x8C88,0x8C8B,0x8C8D,0x8C8E,0x8C8F,0x8C90,0x8C91,0x8C92,/* 0x80-0x87 */
 	0x8C93,0x8C95,0x8C96,0x8C97,0x8C99,0x8C9A,0x8C9B,0x8C9C,/* 0x88-0x8F */
 	0x8C9D,0x8C9E,0x8C9F,0x8CA0,0x8CA1,0x8CA2,0x8CA3,0x8CA4,/* 0x90-0x97 */
@@ -3118,13 +3118,13 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x38-0x3F */
 	0x8CAE,0x8CAF,0x8CB0,0x8CB1,0x8CB2,0x8CB3,0x8CB4,0x8CB5,/* 0x40-0x47 */
 	0x8CB6,0x8CB7,0x8CB8,0x8CB9,0x8CBA,0x8CBB,0x8CBC,0x8CBD,/* 0x48-0x4F */
-	0x8CBE,0x8CBF,0x8CC0,0x8CC1,0xF948,0x8CC3,0x8CC4,0x8CC5,/* 0x50-0x57 */
-	0x8CC6,0x8CC7,0xF903,0x8CC9,0x8CCA,0x8CCB,0x8CCC,0x8CCD,/* 0x58-0x5F */
+	0x8CBE,0x8CBF,0x8CC0,0x8CC1,0x8CC2,0x8CC3,0x8CC4,0x8CC5,/* 0x50-0x57 */
+	0x8CC6,0x8CC7,0x8CC8,0x8CC9,0x8CCA,0x8CCB,0x8CCC,0x8CCD,/* 0x58-0x5F */
 	0x8CCE,0x8CCF,0x8CD0,0x8CD1,0x8CD2,0x8CD3,0x8CD4,0x8CD5,/* 0x60-0x67 */
 	0x8CD6,0x8CD7,0x8CD8,0x8CD9,0x8CDA,0x8CDB,0x8CDC,0x8CDD,/* 0x68-0x6F */
 	0x8CDE,0x8CDF,0x8CE0,0x8CE1,0x8CE2,0x8CE3,0x8CE4,0x8CE5,/* 0x70-0x77 */
 	0x8CE6,0x8CE7,0x8CE8,0x8CE9,0x8CEA,0x8CEB,0x8CEC,0x0000,/* 0x78-0x7F */
-	
+
 	0x8CED,0x8CEE,0x8CEF,0x8CF0,0x8CF1,0x8CF2,0x8CF3,0x8CF4,/* 0x80-0x87 */
 	0x8CF5,0x8CF6,0x8CF7,0x8CF8,0x8CF9,0x8CFA,0x8CFB,0x8CFC,/* 0x88-0x8F */
 	0x8CFD,0x8CFE,0x8CFF,0x8D00,0x8D01,0x8D02,0x8D03,0x8D04,/* 0x90-0x97 */
@@ -3160,7 +3160,7 @@
 	0x8D86,0x8D87,0x8D88,0x8D89,0x8D8C,0x8D8D,0x8D8E,0x8D8F,/* 0x68-0x6F */
 	0x8D90,0x8D92,0x8D93,0x8D95,0x8D96,0x8D97,0x8D98,0x8D99,/* 0x70-0x77 */
 	0x8D9A,0x8D9B,0x8D9C,0x8D9D,0x8D9E,0x8DA0,0x8DA1,0x0000,/* 0x78-0x7F */
-	
+
 	0x8DA2,0x8DA4,0x8DA5,0x8DA6,0x8DA7,0x8DA8,0x8DA9,0x8DAA,/* 0x80-0x87 */
 	0x8DAB,0x8DAC,0x8DAD,0x8DAE,0x8DAF,0x8DB0,0x8DB2,0x8DB6,/* 0x88-0x8F */
 	0x8DB7,0x8DB9,0x8DBB,0x8DBD,0x8DC0,0x8DC1,0x8DC2,0x8DC5,/* 0x90-0x97 */
@@ -3196,7 +3196,7 @@
 	0x8E19,0x8E1A,0x8E1B,0x8E1C,0x8E20,0x8E21,0x8E24,0x8E25,/* 0x68-0x6F */
 	0x8E26,0x8E27,0x8E28,0x8E2B,0x8E2D,0x8E30,0x8E32,0x8E33,/* 0x70-0x77 */
 	0x8E34,0x8E36,0x8E37,0x8E38,0x8E3B,0x8E3C,0x8E3E,0x0000,/* 0x78-0x7F */
-	
+
 	0x8E3F,0x8E43,0x8E45,0x8E46,0x8E4C,0x8E4D,0x8E4E,0x8E4F,/* 0x80-0x87 */
 	0x8E50,0x8E53,0x8E54,0x8E55,0x8E56,0x8E57,0x8E58,0x8E5A,/* 0x88-0x8F */
 	0x8E5B,0x8E5C,0x8E5D,0x8E5E,0x8E5F,0x8E60,0x8E61,0x8E62,/* 0x90-0x97 */
@@ -3232,8 +3232,8 @@
 	0x8EA7,0x8EA8,0x8EA9,0x8EAA,0x8EAD,0x8EAE,0x8EB0,0x8EB1,/* 0x68-0x6F */
 	0x8EB3,0x8EB4,0x8EB5,0x8EB6,0x8EB7,0x8EB8,0x8EB9,0x8EBB,/* 0x70-0x77 */
 	0x8EBC,0x8EBD,0x8EBE,0x8EBF,0x8EC0,0x8EC1,0x8EC2,0x0000,/* 0x78-0x7F */
-	
-	0x8EC3,0x8EC4,0x8EC5,0x8EC6,0x8EC7,0x8EC8,0x8EC9,0xF902,/* 0x80-0x87 */
+
+	0x8EC3,0x8EC4,0x8EC5,0x8EC6,0x8EC7,0x8EC8,0x8EC9,0x8ECA,/* 0x80-0x87 */
 	0x8ECB,0x8ECC,0x8ECD,0x8ECF,0x8ED0,0x8ED1,0x8ED2,0x8ED3,/* 0x88-0x8F */
 	0x8ED4,0x8ED5,0x8ED6,0x8ED7,0x8ED8,0x8ED9,0x8EDA,0x8EDB,/* 0x90-0x97 */
 	0x8EDC,0x8EDD,0x8EDE,0x8EDF,0x8EE0,0x8EE1,0x8EE2,0x8EE3,/* 0x98-0x9F */
@@ -3268,10 +3268,10 @@
 	0x8F0D,0x8F0E,0x8F0F,0x8F10,0x8F11,0x8F12,0x8F13,0x8F14,/* 0x68-0x6F */
 	0x8F15,0x8F16,0x8F17,0x8F18,0x8F19,0x8F1A,0x8F1B,0x8F1C,/* 0x70-0x77 */
 	0x8F1D,0x8F1E,0x8F1F,0x8F20,0x8F21,0x8F22,0x8F23,0x0000,/* 0x78-0x7F */
-	
-	0x8F24,0x8F25,0xF998,0x8F27,0x8F28,0x8F29,0xF9D7,0x8F2B,/* 0x80-0x87 */
+
+	0x8F24,0x8F25,0x8F26,0x8F27,0x8F28,0x8F29,0x8F2A,0x8F2B,/* 0x80-0x87 */
 	0x8F2C,0x8F2D,0x8F2E,0x8F2F,0x8F30,0x8F31,0x8F32,0x8F33,/* 0x88-0x8F */
-	0x8F34,0x8F35,0x8F36,0x8F37,0x8F38,0x8F39,0x8F3A,0xFA07,/* 0x90-0x97 */
+	0x8F34,0x8F35,0x8F36,0x8F37,0x8F38,0x8F39,0x8F3A,0x8F3B,/* 0x90-0x97 */
 	0x8F3C,0x8F3D,0x8F3E,0x8F3F,0x8F40,0x8F41,0x8F42,0x8F43,/* 0x98-0x9F */
 	0x8F44,0x8368,0x831B,0x8369,0x836C,0x836A,0x836D,0x836E,/* 0xA0-0xA7 */
 	0x83B0,0x8378,0x83B3,0x83B4,0x83A0,0x83AA,0x8393,0x839C,/* 0xA8-0xAF */
@@ -3299,17 +3299,17 @@
 	0x8F45,0x8F46,0x8F47,0x8F48,0x8F49,0x8F4A,0x8F4B,0x8F4C,/* 0x40-0x47 */
 	0x8F4D,0x8F4E,0x8F4F,0x8F50,0x8F51,0x8F52,0x8F53,0x8F54,/* 0x48-0x4F */
 	0x8F55,0x8F56,0x8F57,0x8F58,0x8F59,0x8F5A,0x8F5B,0x8F5C,/* 0x50-0x57 */
-	0x8F5D,0x8F5E,0x8F5F,0x8F60,0x8F61,0xF98D,0x8F63,0x8F64,/* 0x58-0x5F */
+	0x8F5D,0x8F5E,0x8F5F,0x8F60,0x8F61,0x8F62,0x8F63,0x8F64,/* 0x58-0x5F */
 	0x8F65,0x8F6A,0x8F80,0x8F8C,0x8F92,0x8F9D,0x8FA0,0x8FA1,/* 0x60-0x67 */
 	0x8FA2,0x8FA4,0x8FA5,0x8FA6,0x8FA7,0x8FAA,0x8FAC,0x8FAD,/* 0x68-0x6F */
 	0x8FAE,0x8FAF,0x8FB2,0x8FB3,0x8FB4,0x8FB5,0x8FB7,0x8FB8,/* 0x70-0x77 */
 	0x8FBA,0x8FBB,0x8FBC,0x8FBF,0x8FC0,0x8FC3,0x8FC6,0x0000,/* 0x78-0x7F */
-	
+
 	0x8FC9,0x8FCA,0x8FCB,0x8FCC,0x8FCD,0x8FCF,0x8FD2,0x8FD6,/* 0x80-0x87 */
 	0x8FD7,0x8FDA,0x8FE0,0x8FE1,0x8FE3,0x8FE7,0x8FEC,0x8FEF,/* 0x88-0x8F */
 	0x8FF1,0x8FF2,0x8FF4,0x8FF5,0x8FF6,0x8FFA,0x8FFB,0x8FFC,/* 0x90-0x97 */
 	0x8FFE,0x8FFF,0x9007,0x9008,0x900C,0x900E,0x9013,0x9015,/* 0x98-0x9F */
-	0x9018,0x8556,0x853B,0x84FF,0xF9C2,0x8559,0x8548,0x8568,/* 0xA0-0xA7 */
+	0x9018,0x8556,0x853B,0x84FF,0x84FC,0x8559,0x8548,0x8568,/* 0xA0-0xA7 */
 	0x8564,0x855E,0x857A,0x77A2,0x8543,0x8572,0x857B,0x85A4,/* 0xA8-0xAF */
 	0x85A8,0x8587,0x858F,0x8579,0x85AE,0x859C,0x8585,0x85B9,/* 0xB0-0xB7 */
 	0x85B7,0x85B0,0x85D3,0x85C1,0x85DC,0x85FF,0x8627,0x8605,/* 0xB8-0xBF */
@@ -3332,17 +3332,17 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x28-0x2F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x30-0x37 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x38-0x3F */
-	0x9019,0x901C,0xF99A,0x9024,0x9025,0x9027,0x9028,0x9029,/* 0x40-0x47 */
+	0x9019,0x901C,0x9023,0x9024,0x9025,0x9027,0x9028,0x9029,/* 0x40-0x47 */
 	0x902A,0x902B,0x902C,0x9030,0x9031,0x9032,0x9033,0x9034,/* 0x48-0x4F */
 	0x9037,0x9039,0x903A,0x903D,0x903F,0x9040,0x9043,0x9045,/* 0x50-0x57 */
 	0x9046,0x9048,0x9049,0x904A,0x904B,0x904C,0x904E,0x9054,/* 0x58-0x5F */
 	0x9055,0x9056,0x9059,0x905A,0x905C,0x905D,0x905E,0x905F,/* 0x60-0x67 */
 	0x9060,0x9061,0x9064,0x9066,0x9067,0x9069,0x906A,0x906B,/* 0x68-0x6F */
 	0x906C,0x906F,0x9070,0x9071,0x9072,0x9073,0x9076,0x9077,/* 0x70-0x77 */
-	0x9078,0x9079,0x907A,0x907B,0xF9C3,0x907E,0x9081,0x0000,/* 0x78-0x7F */
-	
+	0x9078,0x9079,0x907A,0x907B,0x907C,0x907E,0x9081,0x0000,/* 0x78-0x7F */
+
 	0x9084,0x9085,0x9086,0x9087,0x9089,0x908A,0x908C,0x908D,/* 0x80-0x87 */
-	0x908E,0xF913,0x9090,0x9092,0x9094,0x9096,0x9098,0x909A,/* 0x88-0x8F */
+	0x908E,0x908F,0x9090,0x9092,0x9094,0x9096,0x9098,0x909A,/* 0x88-0x8F */
 	0x909C,0x909E,0x909F,0x90A0,0x90A4,0x90A5,0x90A7,0x90A8,/* 0x90-0x97 */
 	0x90A9,0x90AB,0x90AD,0x90B2,0x90B7,0x90BC,0x90BD,0x90BF,/* 0x98-0x9F */
 	0x90C0,0x647A,0x64B7,0x64B8,0x6499,0x64BA,0x64C0,0x64D0,/* 0xA0-0xA7 */
@@ -3376,7 +3376,7 @@
 	0x9105,0x9106,0x9107,0x9108,0x9109,0x910A,0x910B,0x910C,/* 0x68-0x6F */
 	0x910D,0x910E,0x910F,0x9110,0x9111,0x9112,0x9113,0x9114,/* 0x70-0x77 */
 	0x9115,0x9116,0x9117,0x9118,0x911A,0x911B,0x911C,0x0000,/* 0x78-0x7F */
-	
+
 	0x911D,0x911F,0x9120,0x9121,0x9124,0x9125,0x9126,0x9127,/* 0x80-0x87 */
 	0x9128,0x9129,0x912A,0x912B,0x912C,0x912D,0x912E,0x9130,/* 0x88-0x8F */
 	0x9132,0x9133,0x9134,0x9135,0x9136,0x9137,0x9138,0x913A,/* 0x90-0x97 */
@@ -3391,7 +3391,7 @@
 	0x562D,0x5658,0x5639,0x5657,0x562C,0x564D,0x5662,0x5659,/* 0xD8-0xDF */
 	0x565C,0x564C,0x5654,0x5686,0x5664,0x5671,0x566B,0x567B,/* 0xE0-0xE7 */
 	0x567C,0x5685,0x5693,0x56AF,0x56D4,0x56D7,0x56DD,0x56E1,/* 0xE8-0xEF */
-	0x56F5,0x56EB,0xF9A9,0x56FF,0x5704,0x570A,0x5709,0x571C,/* 0xF0-0xF7 */
+	0x56F5,0x56EB,0x56F9,0x56FF,0x5704,0x570A,0x5709,0x571C,/* 0xF0-0xF7 */
 	0x5E0F,0x5E19,0x5E14,0x5E11,0x5E31,0x5E3B,0x5E3C,0x0000,/* 0xF8-0xFF */
 };
 
@@ -3412,7 +3412,7 @@
 	0x919C,0x919D,0x919E,0x919F,0x91A0,0x91A1,0x91A4,0x91A5,/* 0x68-0x6F */
 	0x91A6,0x91A7,0x91A8,0x91A9,0x91AB,0x91AC,0x91B0,0x91B1,/* 0x70-0x77 */
 	0x91B2,0x91B3,0x91B6,0x91B7,0x91B8,0x91B9,0x91BB,0x0000,/* 0x78-0x7F */
-	
+
 	0x91BC,0x91BD,0x91BE,0x91BF,0x91C0,0x91C1,0x91C2,0x91C3,/* 0x80-0x87 */
 	0x91C4,0x91C5,0x91C6,0x91C8,0x91CB,0x91D0,0x91D2,0x91D3,/* 0x88-0x8F */
 	0x91D4,0x91D5,0x91D6,0x91D7,0x91D8,0x91D9,0x91DA,0x91DB,/* 0x90-0x97 */
@@ -3448,9 +3448,9 @@
 	0x920E,0x920F,0x9210,0x9211,0x9212,0x9213,0x9214,0x9215,/* 0x68-0x6F */
 	0x9216,0x9217,0x9218,0x9219,0x921A,0x921B,0x921C,0x921D,/* 0x70-0x77 */
 	0x921E,0x921F,0x9220,0x9221,0x9222,0x9223,0x9224,0x0000,/* 0x78-0x7F */
-	
+
 	0x9225,0x9226,0x9227,0x9228,0x9229,0x922A,0x922B,0x922C,/* 0x80-0x87 */
-	0x922D,0x922E,0x922F,0x9230,0x9231,0x9232,0x9233,0xF9B1,/* 0x88-0x8F */
+	0x922D,0x922E,0x922F,0x9230,0x9231,0x9232,0x9233,0x9234,/* 0x88-0x8F */
 	0x9235,0x9236,0x9237,0x9238,0x9239,0x923A,0x923B,0x923C,/* 0x90-0x97 */
 	0x923D,0x923E,0x923F,0x9240,0x9241,0x9242,0x9243,0x9244,/* 0x98-0x9F */
 	0x9245,0x72FB,0x7317,0x7313,0x7321,0x730A,0x731E,0x731D,/* 0xA0-0xA7 */
@@ -3484,7 +3484,7 @@
 	0x926E,0x926F,0x9270,0x9271,0x9272,0x9273,0x9275,0x9276,/* 0x68-0x6F */
 	0x9277,0x9278,0x9279,0x927A,0x927B,0x927C,0x927D,0x927E,/* 0x70-0x77 */
 	0x927F,0x9280,0x9281,0x9282,0x9283,0x9284,0x9285,0x0000,/* 0x78-0x7F */
-	
+
 	0x9286,0x9287,0x9288,0x9289,0x928A,0x928B,0x928C,0x928D,/* 0x80-0x87 */
 	0x928F,0x9290,0x9291,0x9292,0x9293,0x9294,0x9295,0x9296,/* 0x88-0x8F */
 	0x9297,0x9298,0x9299,0x929A,0x929B,0x929C,0x929D,0x929E,/* 0x90-0x97 */
@@ -3520,11 +3520,11 @@
 	0x92D2,0x92D3,0x92D4,0x92D5,0x92D6,0x92D7,0x92D8,0x92D9,/* 0x68-0x6F */
 	0x92DA,0x92DB,0x92DC,0x92DD,0x92DE,0x92DF,0x92E0,0x92E1,/* 0x70-0x77 */
 	0x92E2,0x92E3,0x92E4,0x92E5,0x92E6,0x92E7,0x92E8,0x0000,/* 0x78-0x7F */
-	
+
 	0x92E9,0x92EA,0x92EB,0x92EC,0x92ED,0x92EE,0x92EF,0x92F0,/* 0x80-0x87 */
 	0x92F1,0x92F2,0x92F3,0x92F4,0x92F5,0x92F6,0x92F7,0x92F8,/* 0x88-0x8F */
 	0x92F9,0x92FA,0x92FB,0x92FC,0x92FD,0x92FE,0x92FF,0x9300,/* 0x90-0x97 */
-	0x9301,0x9302,0x9303,0xF93F,0x9305,0x9306,0x9307,0x9308,/* 0x98-0x9F */
+	0x9301,0x9302,0x9303,0x9304,0x9305,0x9306,0x9307,0x9308,/* 0x98-0x9F */
 	0x9309,0x6D39,0x6D27,0x6D0C,0x6D43,0x6D48,0x6D07,0x6D04,/* 0xA0-0xA7 */
 	0x6D19,0x6D0E,0x6D2B,0x6D4D,0x6D2E,0x6D35,0x6D1A,0x6D4F,/* 0xA8-0xAF */
 	0x6D52,0x6D54,0x6D33,0x6D91,0x6D6F,0x6D9E,0x6DA0,0x6D5E,/* 0xB0-0xB7 */
@@ -3556,15 +3556,15 @@
 	0x9332,0x9333,0x9334,0x9335,0x9336,0x9337,0x9338,0x9339,/* 0x68-0x6F */
 	0x933A,0x933B,0x933C,0x933D,0x933F,0x9340,0x9341,0x9342,/* 0x70-0x77 */
 	0x9343,0x9344,0x9345,0x9346,0x9347,0x9348,0x9349,0x0000,/* 0x78-0x7F */
-	
-	0xF99B,0x934B,0x934C,0x934D,0x934E,0x934F,0x9350,0x9351,/* 0x80-0x87 */
+
+	0x934A,0x934B,0x934C,0x934D,0x934E,0x934F,0x9350,0x9351,/* 0x80-0x87 */
 	0x9352,0x9353,0x9354,0x9355,0x9356,0x9357,0x9358,0x9359,/* 0x88-0x8F */
 	0x935A,0x935B,0x935C,0x935D,0x935E,0x935F,0x9360,0x9361,/* 0x90-0x97 */
 	0x9362,0x9363,0x9364,0x9365,0x9366,0x9367,0x9368,0x9369,/* 0x98-0x9F */
 	0x936B,0x6FC9,0x6FA7,0x6FB9,0x6FB6,0x6FC2,0x6FE1,0x6FEE,/* 0xA0-0xA7 */
 	0x6FDE,0x6FE0,0x6FEF,0x701A,0x7023,0x701B,0x7039,0x7035,/* 0xA8-0xAF */
 	0x704F,0x705E,0x5B80,0x5B84,0x5B95,0x5B93,0x5BA5,0x5BB8,/* 0xB0-0xB7 */
-	0x752F,0x9A9E,0x6434,0x5BE4,0xF9BC,0x8930,0x5BF0,0x8E47,/* 0xB8-0xBF */
+	0x752F,0x9A9E,0x6434,0x5BE4,0x5BEE,0x8930,0x5BF0,0x8E47,/* 0xB8-0xBF */
 	0x8B07,0x8FB6,0x8FD3,0x8FD5,0x8FE5,0x8FEE,0x8FE4,0x8FE9,/* 0xC0-0xC7 */
 	0x8FE6,0x8FF3,0x8FE8,0x9005,0x9004,0x900B,0x9026,0x9011,/* 0xC8-0xCF */
 	0x900D,0x9016,0x9021,0x9035,0x9036,0x902D,0x902F,0x9044,/* 0xD0-0xD7 */
@@ -3592,7 +3592,7 @@
 	0x9395,0x9396,0x9397,0x9398,0x9399,0x939A,0x939B,0x939C,/* 0x68-0x6F */
 	0x939D,0x939E,0x939F,0x93A0,0x93A1,0x93A2,0x93A3,0x93A4,/* 0x70-0x77 */
 	0x93A5,0x93A6,0x93A7,0x93A8,0x93A9,0x93AA,0x93AB,0x0000,/* 0x78-0x7F */
-	
+
 	0x93AC,0x93AD,0x93AE,0x93AF,0x93B0,0x93B1,0x93B2,0x93B3,/* 0x80-0x87 */
 	0x93B4,0x93B5,0x93B6,0x93B7,0x93B8,0x93B9,0x93BA,0x93BB,/* 0x88-0x8F */
 	0x93BC,0x93BD,0x93BE,0x93BF,0x93C0,0x93C1,0x93C2,0x93C3,/* 0x90-0x97 */
@@ -3628,7 +3628,7 @@
 	0x93F7,0x93F8,0x93F9,0x93FA,0x93FB,0x93FC,0x93FD,0x93FE,/* 0x68-0x6F */
 	0x93FF,0x9400,0x9401,0x9402,0x9403,0x9404,0x9405,0x9406,/* 0x70-0x77 */
 	0x9407,0x9408,0x9409,0x940A,0x940B,0x940C,0x940D,0x0000,/* 0x78-0x7F */
-	
+
 	0x940E,0x940F,0x9410,0x9411,0x9412,0x9413,0x9414,0x9415,/* 0x80-0x87 */
 	0x9416,0x9417,0x9418,0x9419,0x941A,0x941B,0x941C,0x941D,/* 0x88-0x8F */
 	0x941E,0x941F,0x9420,0x9421,0x9422,0x9423,0x9424,0x9425,/* 0x90-0x97 */
@@ -3643,7 +3643,7 @@
 	0x7F32,0x7F33,0x7F35,0x5E7A,0x757F,0x5DDB,0x753E,0x9095,/* 0xD8-0xDF */
 	0x738E,0x7391,0x73AE,0x73A2,0x739F,0x73CF,0x73C2,0x73D1,/* 0xE0-0xE7 */
 	0x73B7,0x73B3,0x73C0,0x73C9,0x73C8,0x73E5,0x73D9,0x987C,/* 0xE8-0xEF */
-	0x740A,0x73E9,0x73E7,0xF917,0x73BA,0x73F2,0x740F,0x742A,/* 0xF0-0xF7 */
+	0x740A,0x73E9,0x73E7,0x73DE,0x73BA,0x73F2,0x740F,0x742A,/* 0xF0-0xF7 */
 	0x745B,0x7426,0x7425,0x7428,0x7430,0x742E,0x742C,0x0000,/* 0xF8-0xFF */
 };
 
@@ -3664,7 +3664,7 @@
 	0x9458,0x9459,0x945A,0x945B,0x945C,0x945D,0x945E,0x945F,/* 0x68-0x6F */
 	0x9460,0x9461,0x9462,0x9463,0x9464,0x9465,0x9466,0x9467,/* 0x70-0x77 */
 	0x9468,0x9469,0x946A,0x946C,0x946D,0x946E,0x946F,0x0000,/* 0x78-0x7F */
-	
+
 	0x9470,0x9471,0x9472,0x9473,0x9474,0x9475,0x9476,0x9477,/* 0x80-0x87 */
 	0x9478,0x9479,0x947A,0x947B,0x947C,0x947D,0x947E,0x947F,/* 0x88-0x8F */
 	0x9480,0x9481,0x9482,0x9483,0x9484,0x9491,0x9496,0x9498,/* 0x90-0x97 */
@@ -3700,8 +3700,8 @@
 	0x9594,0x9595,0x9596,0x9597,0x9598,0x9599,0x959A,0x959B,/* 0x68-0x6F */
 	0x959C,0x959D,0x959E,0x959F,0x95A0,0x95A1,0x95A2,0x95A3,/* 0x70-0x77 */
 	0x95A4,0x95A5,0x95A6,0x95A7,0x95A8,0x95A9,0x95AA,0x0000,/* 0x78-0x7F */
-	
-	0x95AB,0x95AC,0xF986,0x95AE,0x95AF,0x95B0,0x95B1,0x95B2,/* 0x80-0x87 */
+
+	0x95AB,0x95AC,0x95AD,0x95AE,0x95AF,0x95B0,0x95B1,0x95B2,/* 0x80-0x87 */
 	0x95B3,0x95B4,0x95B5,0x95B6,0x95B7,0x95B8,0x95B9,0x95BA,/* 0x88-0x8F */
 	0x95BB,0x95BC,0x95BD,0x95BE,0x95BF,0x95C0,0x95C1,0x95C2,/* 0x90-0x97 */
 	0x95C3,0x95C4,0x95C5,0x95C6,0x95C7,0x95C8,0x95C9,0x95CA,/* 0x98-0x9F */
@@ -3736,10 +3736,10 @@
 	0x9627,0x9628,0x9629,0x962B,0x962C,0x962D,0x962F,0x9630,/* 0x68-0x6F */
 	0x9637,0x9638,0x9639,0x963A,0x963E,0x9641,0x9643,0x964A,/* 0x70-0x77 */
 	0x964E,0x964F,0x9651,0x9652,0x9653,0x9656,0x9657,0x0000,/* 0x78-0x7F */
-	
+
 	0x9658,0x9659,0x965A,0x965C,0x965D,0x965E,0x9660,0x9663,/* 0x80-0x87 */
 	0x9665,0x9666,0x966B,0x966D,0x966E,0x966F,0x9670,0x9671,/* 0x88-0x8F */
-	0x9673,0xF9D3,0x9679,0x967A,0x967B,0x967C,0x967D,0x967E,/* 0x90-0x97 */
+	0x9673,0x9678,0x9679,0x967A,0x967B,0x967C,0x967D,0x967E,/* 0x90-0x97 */
 	0x967F,0x9680,0x9681,0x9682,0x9683,0x9684,0x9687,0x9689,/* 0x98-0x9F */
 	0x968A,0x8F8D,0x8F8E,0x8F8F,0x8F98,0x8F9A,0x8ECE,0x620B,/* 0xA0-0xA7 */
 	0x6217,0x621B,0x621F,0x6222,0x6221,0x6225,0x6224,0x622C,/* 0xA8-0xAF */
@@ -3768,11 +3768,11 @@
 	0x969B,0x969D,0x969E,0x969F,0x96A0,0x96A1,0x96A2,0x96A3,/* 0x48-0x4F */
 	0x96A4,0x96A5,0x96A6,0x96A8,0x96A9,0x96AA,0x96AB,0x96AC,/* 0x50-0x57 */
 	0x96AD,0x96AE,0x96AF,0x96B1,0x96B2,0x96B4,0x96B5,0x96B7,/* 0x58-0x5F */
-	0xF9B8,0x96BA,0x96BB,0x96BF,0x96C2,0x96C3,0x96C8,0x96CA,/* 0x60-0x67 */
+	0x96B8,0x96BA,0x96BB,0x96BF,0x96C2,0x96C3,0x96C8,0x96CA,/* 0x60-0x67 */
 	0x96CB,0x96D0,0x96D1,0x96D3,0x96D4,0x96D6,0x96D7,0x96D8,/* 0x68-0x6F */
 	0x96D9,0x96DA,0x96DB,0x96DC,0x96DD,0x96DE,0x96DF,0x96E1,/* 0x70-0x77 */
-	0xF9EA,0x96E3,0x96E4,0x96E5,0x96E6,0x96E7,0x96EB,0x0000,/* 0x78-0x7F */
-	
+	0x96E2,0x96E3,0x96E4,0x96E5,0x96E6,0x96E7,0x96EB,0x0000,/* 0x78-0x7F */
+
 	0x96EC,0x96ED,0x96EE,0x96F0,0x96F1,0x96F2,0x96F4,0x96F5,/* 0x80-0x87 */
 	0x96F8,0x96FA,0x96FB,0x96FC,0x96FD,0x96FF,0x9702,0x9703,/* 0x88-0x8F */
 	0x9705,0x970A,0x970B,0x970C,0x9710,0x9711,0x9712,0x9714,/* 0x90-0x97 */
@@ -3804,11 +3804,11 @@
 	0x9729,0x972B,0x972C,0x972E,0x972F,0x9731,0x9733,0x9734,/* 0x48-0x4F */
 	0x9735,0x9736,0x9737,0x973A,0x973B,0x973C,0x973D,0x973F,/* 0x50-0x57 */
 	0x9740,0x9741,0x9742,0x9743,0x9744,0x9745,0x9746,0x9747,/* 0x58-0x5F */
-	0xF9B3,0x9749,0x974A,0x974B,0x974C,0x974D,0x974E,0x974F,/* 0x60-0x67 */
+	0x9748,0x9749,0x974A,0x974B,0x974C,0x974D,0x974E,0x974F,/* 0x60-0x67 */
 	0x9750,0x9751,0x9754,0x9755,0x9757,0x9758,0x975A,0x975C,/* 0x68-0x6F */
 	0x975D,0x975F,0x9763,0x9764,0x9766,0x9767,0x9768,0x976A,/* 0x70-0x77 */
 	0x976B,0x976C,0x976D,0x976E,0x976F,0x9770,0x9771,0x0000,/* 0x78-0x7F */
-	
+
 	0x9772,0x9775,0x9777,0x9778,0x9779,0x977A,0x977B,0x977D,/* 0x80-0x87 */
 	0x977E,0x977F,0x9780,0x9781,0x9782,0x9783,0x9784,0x9786,/* 0x88-0x8F */
 	0x9787,0x9788,0x9789,0x978A,0x978C,0x978E,0x978F,0x9790,/* 0x90-0x97 */
@@ -3844,7 +3844,7 @@
 	0x97CD,0x97CE,0x97CF,0x97D0,0x97D1,0x97D2,0x97D3,0x97D4,/* 0x68-0x6F */
 	0x97D5,0x97D6,0x97D7,0x97D8,0x97D9,0x97DA,0x97DB,0x97DC,/* 0x70-0x77 */
 	0x97DD,0x97DE,0x97DF,0x97E0,0x97E1,0x97E2,0x97E3,0x0000,/* 0x78-0x7F */
-	
+
 	0x97E4,0x97E5,0x97E8,0x97EE,0x97EF,0x97F0,0x97F1,0x97F2,/* 0x80-0x87 */
 	0x97F4,0x97F7,0x97F8,0x97F9,0x97FA,0x97FB,0x97FC,0x97FD,/* 0x88-0x8F */
 	0x97FE,0x97FF,0x9800,0x9801,0x9802,0x9803,0x9804,0x9805,/* 0x90-0x97 */
@@ -3873,22 +3873,22 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x30-0x37 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x38-0x3F */
 	0x980F,0x9810,0x9811,0x9812,0x9813,0x9814,0x9815,0x9816,/* 0x40-0x47 */
-	0x9817,0xF9B4,0x9819,0x981A,0x981B,0x981C,0x981D,0x981E,/* 0x48-0x4F */
+	0x9817,0x9818,0x9819,0x981A,0x981B,0x981C,0x981D,0x981E,/* 0x48-0x4F */
 	0x981F,0x9820,0x9821,0x9822,0x9823,0x9824,0x9825,0x9826,/* 0x50-0x57 */
 	0x9827,0x9828,0x9829,0x982A,0x982B,0x982C,0x982D,0x982E,/* 0x58-0x5F */
 	0x982F,0x9830,0x9831,0x9832,0x9833,0x9834,0x9835,0x9836,/* 0x60-0x67 */
 	0x9837,0x9838,0x9839,0x983A,0x983B,0x983C,0x983D,0x983E,/* 0x68-0x6F */
 	0x983F,0x9840,0x9841,0x9842,0x9843,0x9844,0x9845,0x9846,/* 0x70-0x77 */
 	0x9847,0x9848,0x9849,0x984A,0x984B,0x984C,0x984D,0x0000,/* 0x78-0x7F */
-	
+
 	0x984E,0x984F,0x9850,0x9851,0x9852,0x9853,0x9854,0x9855,/* 0x80-0x87 */
 	0x9856,0x9857,0x9858,0x9859,0x985A,0x985B,0x985C,0x985D,/* 0x88-0x8F */
-	0xF9D0,0x985F,0x9860,0x9861,0x9862,0x9863,0x9864,0x9865,/* 0x90-0x97 */
+	0x985E,0x985F,0x9860,0x9861,0x9862,0x9863,0x9864,0x9865,/* 0x90-0x97 */
 	0x9866,0x9867,0x9868,0x9869,0x986A,0x986B,0x986C,0x986D,/* 0x98-0x9F */
 	0x986E,0x7762,0x7765,0x777F,0x778D,0x777D,0x7780,0x778C,/* 0xA0-0xA7 */
 	0x7791,0x779F,0x77A0,0x77B0,0x77B5,0x77BD,0x753A,0x7540,/* 0xA8-0xAF */
 	0x754E,0x754B,0x7548,0x755B,0x7572,0x7579,0x7583,0x7F58,/* 0xB0-0xB7 */
-	0x7F61,0x7F5F,0x8A48,0x7F68,0x7F74,0x7F71,0xF9E6,0x7F81,/* 0xB8-0xBF */
+	0x7F61,0x7F5F,0x8A48,0x7F68,0x7F74,0x7F71,0x7F79,0x7F81,/* 0xB8-0xBF */
 	0x7F7E,0x76CD,0x76E5,0x8832,0x9485,0x9486,0x9487,0x948B,/* 0xC0-0xC7 */
 	0x948A,0x948C,0x948D,0x948F,0x9490,0x9494,0x9497,0x9495,/* 0xC8-0xCF */
 	0x949A,0x949B,0x949C,0x94A3,0x94A4,0x94AB,0x94AA,0x94AD,/* 0xD0-0xD7 */
@@ -3916,10 +3916,10 @@
 	0x98C4,0x98C5,0x98C6,0x98C7,0x98C8,0x98C9,0x98CA,0x98CB,/* 0x68-0x6F */
 	0x98CC,0x98CD,0x98CF,0x98D0,0x98D4,0x98D6,0x98D7,0x98DB,/* 0x70-0x77 */
 	0x98DC,0x98DD,0x98E0,0x98E1,0x98E2,0x98E3,0x98E4,0x0000,/* 0x78-0x7F */
-	
+
 	0x98E5,0x98E6,0x98E9,0x98EA,0x98EB,0x98EC,0x98ED,0x98EE,/* 0x80-0x87 */
-	0xFA2A,0x98F0,0x98F1,0x98F2,0x98F3,0x98F4,0x98F5,0x98F6,/* 0x88-0x8F */
-	0x98F7,0x98F8,0x98F9,0x98FA,0x98FB,0xFA2B,0x98FD,0x98FE,/* 0x90-0x97 */
+	0x98EF,0x98F0,0x98F1,0x98F2,0x98F3,0x98F4,0x98F5,0x98F6,/* 0x88-0x8F */
+	0x98F7,0x98F8,0x98F9,0x98FA,0x98FB,0x98FC,0x98FD,0x98FE,/* 0x90-0x97 */
 	0x98FF,0x9900,0x9901,0x9902,0x9903,0x9904,0x9905,0x9906,/* 0x98-0x9F */
 	0x9907,0x94E9,0x94EB,0x94EE,0x94EF,0x94F3,0x94F4,0x94F5,/* 0xA0-0xA7 */
 	0x94F7,0x94F9,0x94FC,0x94FD,0x94FF,0x9503,0x9502,0x9506,/* 0xA8-0xAF */
@@ -3947,12 +3947,12 @@
 	0x9908,0x9909,0x990A,0x990B,0x990C,0x990E,0x990F,0x9911,/* 0x40-0x47 */
 	0x9912,0x9913,0x9914,0x9915,0x9916,0x9917,0x9918,0x9919,/* 0x48-0x4F */
 	0x991A,0x991B,0x991C,0x991D,0x991E,0x991F,0x9920,0x9921,/* 0x50-0x57 */
-	0x9922,0x9923,0x9924,0x9925,0x9926,0x9927,0xFA2C,0x9929,/* 0x58-0x5F */
+	0x9922,0x9923,0x9924,0x9925,0x9926,0x9927,0x9928,0x9929,/* 0x58-0x5F */
 	0x992A,0x992B,0x992C,0x992D,0x992F,0x9930,0x9931,0x9932,/* 0x60-0x67 */
 	0x9933,0x9934,0x9935,0x9936,0x9937,0x9938,0x9939,0x993A,/* 0x68-0x6F */
 	0x993B,0x993C,0x993D,0x993E,0x993F,0x9940,0x9941,0x9942,/* 0x70-0x77 */
 	0x9943,0x9944,0x9945,0x9946,0x9947,0x9948,0x9949,0x0000,/* 0x78-0x7F */
-	
+
 	0x994A,0x994B,0x994C,0x994D,0x994E,0x994F,0x9950,0x9951,/* 0x80-0x87 */
 	0x9952,0x9953,0x9956,0x9957,0x9958,0x9959,0x995A,0x995B,/* 0x88-0x8F */
 	0x995C,0x995D,0x995E,0x995F,0x9960,0x9961,0x9962,0x9964,/* 0x90-0x97 */
@@ -3988,11 +3988,11 @@
 	0x99C2,0x99C3,0x99C4,0x99C5,0x99C6,0x99C7,0x99C8,0x99C9,/* 0x68-0x6F */
 	0x99CA,0x99CB,0x99CC,0x99CD,0x99CE,0x99CF,0x99D0,0x99D1,/* 0x70-0x77 */
 	0x99D2,0x99D3,0x99D4,0x99D5,0x99D6,0x99D7,0x99D8,0x0000,/* 0x78-0x7F */
-	
+
 	0x99D9,0x99DA,0x99DB,0x99DC,0x99DD,0x99DE,0x99DF,0x99E0,/* 0x80-0x87 */
 	0x99E1,0x99E2,0x99E3,0x99E4,0x99E5,0x99E6,0x99E7,0x99E8,/* 0x88-0x8F */
 	0x99E9,0x99EA,0x99EB,0x99EC,0x99ED,0x99EE,0x99EF,0x99F0,/* 0x90-0x97 */
-	0xF91A,0x99F2,0x99F3,0x99F4,0x99F5,0x99F6,0x99F7,0x99F8,/* 0x98-0x9F */
+	0x99F1,0x99F2,0x99F3,0x99F4,0x99F5,0x99F6,0x99F7,0x99F8,/* 0x98-0x9F */
 	0x99F9,0x761B,0x763C,0x7622,0x7620,0x7640,0x762D,0x7630,/* 0xA0-0xA7 */
 	0x763F,0x7635,0x7643,0x763E,0x7633,0x764D,0x765E,0x7654,/* 0xA8-0xAF */
 	0x765C,0x7656,0x766B,0x766F,0x7FCA,0x7AE6,0x7A78,0x7A79,/* 0xB0-0xB7 */
@@ -4003,7 +4003,7 @@
 	0x8919,0x8913,0x891B,0x890A,0x8934,0x892B,0x8936,0x8941,/* 0xD8-0xDF */
 	0x8966,0x897B,0x758B,0x80E5,0x76B2,0x76B4,0x77DC,0x8012,/* 0xE0-0xE7 */
 	0x8014,0x8016,0x801C,0x8020,0x8022,0x8025,0x8026,0x8027,/* 0xE8-0xEF */
-	0x8029,0x8028,0x8031,0x800B,0x8035,0x8043,0xF9B0,0x804D,/* 0xF0-0xF7 */
+	0x8029,0x8028,0x8031,0x800B,0x8035,0x8043,0x8046,0x804D,/* 0xF0-0xF7 */
 	0x8052,0x8069,0x8071,0x8983,0x9878,0x9880,0x9883,0x0000,/* 0xF8-0xFF */
 };
 
@@ -4024,7 +4024,7 @@
 	0x9A22,0x9A23,0x9A24,0x9A25,0x9A26,0x9A27,0x9A28,0x9A29,/* 0x68-0x6F */
 	0x9A2A,0x9A2B,0x9A2C,0x9A2D,0x9A2E,0x9A2F,0x9A30,0x9A31,/* 0x70-0x77 */
 	0x9A32,0x9A33,0x9A34,0x9A35,0x9A36,0x9A37,0x9A38,0x0000,/* 0x78-0x7F */
-	
+
 	0x9A39,0x9A3A,0x9A3B,0x9A3C,0x9A3D,0x9A3E,0x9A3F,0x9A40,/* 0x80-0x87 */
 	0x9A41,0x9A42,0x9A43,0x9A44,0x9A45,0x9A46,0x9A47,0x9A48,/* 0x88-0x8F */
 	0x9A49,0x9A4A,0x9A4B,0x9A4C,0x9A4D,0x9A4E,0x9A4F,0x9A50,/* 0x90-0x97 */
@@ -4054,13 +4054,13 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x38-0x3F */
 	0x9A5A,0x9A5B,0x9A5C,0x9A5D,0x9A5E,0x9A5F,0x9A60,0x9A61,/* 0x40-0x47 */
 	0x9A62,0x9A63,0x9A64,0x9A65,0x9A66,0x9A67,0x9A68,0x9A69,/* 0x48-0x4F */
-	0xF987,0x9A6B,0x9A72,0x9A83,0x9A89,0x9A8D,0x9A8E,0x9A94,/* 0x50-0x57 */
+	0x9A6A,0x9A6B,0x9A72,0x9A83,0x9A89,0x9A8D,0x9A8E,0x9A94,/* 0x50-0x57 */
 	0x9A95,0x9A99,0x9AA6,0x9AA9,0x9AAA,0x9AAB,0x9AAC,0x9AAD,/* 0x58-0x5F */
 	0x9AAE,0x9AAF,0x9AB2,0x9AB3,0x9AB4,0x9AB5,0x9AB9,0x9ABB,/* 0x60-0x67 */
 	0x9ABD,0x9ABE,0x9ABF,0x9AC3,0x9AC4,0x9AC6,0x9AC7,0x9AC8,/* 0x68-0x6F */
 	0x9AC9,0x9ACA,0x9ACD,0x9ACE,0x9ACF,0x9AD0,0x9AD2,0x9AD4,/* 0x70-0x77 */
 	0x9AD5,0x9AD6,0x9AD7,0x9AD9,0x9ADA,0x9ADB,0x9ADC,0x0000,/* 0x78-0x7F */
-	
+
 	0x9ADD,0x9ADE,0x9AE0,0x9AE2,0x9AE3,0x9AE4,0x9AE5,0x9AE7,/* 0x80-0x87 */
 	0x9AE8,0x9AE9,0x9AEA,0x9AEC,0x9AEE,0x9AF0,0x9AF1,0x9AF2,/* 0x88-0x8F */
 	0x9AF3,0x9AF4,0x9AF5,0x9AF6,0x9AF7,0x9AF8,0x9AFA,0x9AFC,/* 0x90-0x97 */
@@ -4071,7 +4071,7 @@
 	0x87FE,0x880A,0x881B,0x8821,0x8839,0x883C,0x7F36,0x7F42,/* 0xB8-0xBF */
 	0x7F44,0x7F45,0x8210,0x7AFA,0x7AFD,0x7B08,0x7B03,0x7B04,/* 0xC0-0xC7 */
 	0x7B15,0x7B0A,0x7B2B,0x7B0F,0x7B47,0x7B38,0x7B2A,0x7B19,/* 0xC8-0xCF */
-	0x7B2E,0x7B31,0xF9F8,0x7B25,0x7B24,0x7B33,0x7B3E,0x7B1E,/* 0xD0-0xD7 */
+	0x7B2E,0x7B31,0x7B20,0x7B25,0x7B24,0x7B33,0x7B3E,0x7B1E,/* 0xD0-0xD7 */
 	0x7B58,0x7B5A,0x7B45,0x7B75,0x7B4C,0x7B5D,0x7B60,0x7B6E,/* 0xD8-0xDF */
 	0x7B7B,0x7B62,0x7B72,0x7B71,0x7B90,0x7BA6,0x7BA7,0x7BB8,/* 0xE0-0xE7 */
 	0x7BAC,0x7B9D,0x7BA8,0x7B85,0x7BAA,0x7B9C,0x7BA2,0x7BAB,/* 0xE8-0xEF */
@@ -4096,10 +4096,10 @@
 	0x9B36,0x9B37,0x9B38,0x9B39,0x9B3A,0x9B3D,0x9B3E,0x9B3F,/* 0x68-0x6F */
 	0x9B40,0x9B46,0x9B4A,0x9B4B,0x9B4C,0x9B4E,0x9B50,0x9B52,/* 0x70-0x77 */
 	0x9B53,0x9B55,0x9B56,0x9B57,0x9B58,0x9B59,0x9B5A,0x0000,/* 0x78-0x7F */
-	
+
 	0x9B5B,0x9B5C,0x9B5D,0x9B5E,0x9B5F,0x9B60,0x9B61,0x9B62,/* 0x80-0x87 */
 	0x9B63,0x9B64,0x9B65,0x9B66,0x9B67,0x9B68,0x9B69,0x9B6A,/* 0x88-0x8F */
-	0x9B6B,0x9B6C,0x9B6D,0x9B6E,0xF939,0x9B70,0x9B71,0x9B72,/* 0x90-0x97 */
+	0x9B6B,0x9B6C,0x9B6D,0x9B6E,0x9B6F,0x9B70,0x9B71,0x9B72,/* 0x90-0x97 */
 	0x9B73,0x9B74,0x9B75,0x9B76,0x9B77,0x9B78,0x9B79,0x9B7A,/* 0x98-0x9F */
 	0x9B7B,0x7C1F,0x7C2A,0x7C26,0x7C38,0x7C41,0x7C40,0x81FE,/* 0xA0-0xA7 */
 	0x8201,0x8202,0x8204,0x81EC,0x8844,0x8221,0x8222,0x8223,/* 0xA8-0xAF */
@@ -4132,14 +4132,14 @@
 	0x9BA4,0x9BA5,0x9BA6,0x9BA7,0x9BA8,0x9BA9,0x9BAA,0x9BAB,/* 0x68-0x6F */
 	0x9BAC,0x9BAD,0x9BAE,0x9BAF,0x9BB0,0x9BB1,0x9BB2,0x9BB3,/* 0x70-0x77 */
 	0x9BB4,0x9BB5,0x9BB6,0x9BB7,0x9BB8,0x9BB9,0x9BBA,0x0000,/* 0x78-0x7F */
-	
+
 	0x9BBB,0x9BBC,0x9BBD,0x9BBE,0x9BBF,0x9BC0,0x9BC1,0x9BC2,/* 0x80-0x87 */
 	0x9BC3,0x9BC4,0x9BC5,0x9BC6,0x9BC7,0x9BC8,0x9BC9,0x9BCA,/* 0x88-0x8F */
 	0x9BCB,0x9BCC,0x9BCD,0x9BCE,0x9BCF,0x9BD0,0x9BD1,0x9BD2,/* 0x90-0x97 */
 	0x9BD3,0x9BD4,0x9BD5,0x9BD6,0x9BD7,0x9BD8,0x9BD9,0x9BDA,/* 0x98-0x9F */
 	0x9BDB,0x9162,0x9161,0x9170,0x9169,0x916F,0x917D,0x917E,/* 0xA0-0xA7 */
 	0x9172,0x9174,0x9179,0x918C,0x9185,0x9190,0x918D,0x9191,/* 0xA8-0xAF */
-	0x91A2,0x91A3,0x91AA,0x91AD,0x91AE,0x91AF,0x91B5,0xF9B7,/* 0xB0-0xB7 */
+	0x91A2,0x91A3,0x91AA,0x91AD,0x91AE,0x91AF,0x91B5,0x91B4,/* 0xB0-0xB7 */
 	0x91BA,0x8C55,0x9E7E,0x8DB8,0x8DEB,0x8E05,0x8E59,0x8E69,/* 0xB8-0xBF */
 	0x8DB5,0x8DBF,0x8DBC,0x8DBA,0x8DC4,0x8DD6,0x8DD7,0x8DDA,/* 0xC0-0xC7 */
 	0x8DDE,0x8DCE,0x8DCF,0x8DDB,0x8DC6,0x8DEC,0x8DF7,0x8DF8,/* 0xC8-0xCF */
@@ -4168,7 +4168,7 @@
 	0x9C04,0x9C05,0x9C06,0x9C07,0x9C08,0x9C09,0x9C0A,0x9C0B,/* 0x68-0x6F */
 	0x9C0C,0x9C0D,0x9C0E,0x9C0F,0x9C10,0x9C11,0x9C12,0x9C13,/* 0x70-0x77 */
 	0x9C14,0x9C15,0x9C16,0x9C17,0x9C18,0x9C19,0x9C1A,0x0000,/* 0x78-0x7F */
-	
+
 	0x9C1B,0x9C1C,0x9C1D,0x9C1E,0x9C1F,0x9C20,0x9C21,0x9C22,/* 0x80-0x87 */
 	0x9C23,0x9C24,0x9C25,0x9C26,0x9C27,0x9C28,0x9C29,0x9C2A,/* 0x88-0x8F */
 	0x9C2B,0x9C2C,0x9C2D,0x9C2E,0x9C2F,0x9C30,0x9C31,0x9C32,/* 0x90-0x97 */
@@ -4199,12 +4199,12 @@
 	0x9C3C,0x9C3D,0x9C3E,0x9C3F,0x9C40,0x9C41,0x9C42,0x9C43,/* 0x40-0x47 */
 	0x9C44,0x9C45,0x9C46,0x9C47,0x9C48,0x9C49,0x9C4A,0x9C4B,/* 0x48-0x4F */
 	0x9C4C,0x9C4D,0x9C4E,0x9C4F,0x9C50,0x9C51,0x9C52,0x9C53,/* 0x50-0x57 */
-	0x9C54,0x9C55,0x9C56,0xF9F2,0x9C58,0x9C59,0x9C5A,0x9C5B,/* 0x58-0x5F */
+	0x9C54,0x9C55,0x9C56,0x9C57,0x9C58,0x9C59,0x9C5A,0x9C5B,/* 0x58-0x5F */
 	0x9C5C,0x9C5D,0x9C5E,0x9C5F,0x9C60,0x9C61,0x9C62,0x9C63,/* 0x60-0x67 */
 	0x9C64,0x9C65,0x9C66,0x9C67,0x9C68,0x9C69,0x9C6A,0x9C6B,/* 0x68-0x6F */
 	0x9C6C,0x9C6D,0x9C6E,0x9C6F,0x9C70,0x9C71,0x9C72,0x9C73,/* 0x70-0x77 */
 	0x9C74,0x9C75,0x9C76,0x9C77,0x9C78,0x9C79,0x9C7A,0x0000,/* 0x78-0x7F */
-	
+
 	0x9C7B,0x9C7D,0x9C7E,0x9C80,0x9C83,0x9C84,0x9C89,0x9C8A,/* 0x80-0x87 */
 	0x9C8C,0x9C8F,0x9C93,0x9C96,0x9C97,0x9C98,0x9C99,0x9C9D,/* 0x88-0x8F */
 	0x9CAA,0x9CAC,0x9CAF,0x9CB9,0x9CBE,0x9CBF,0x9CC0,0x9CC1,/* 0x90-0x97 */
@@ -4218,7 +4218,7 @@
 	0x990D,0x992E,0x9955,0x9954,0x9ADF,0x9AE1,0x9AE6,0x9AEF,/* 0xD0-0xD7 */
 	0x9AEB,0x9AFB,0x9AED,0x9AF9,0x9B08,0x9B0F,0x9B13,0x9B1F,/* 0xD8-0xDF */
 	0x9B23,0x9EBD,0x9EBE,0x7E3B,0x9E82,0x9E87,0x9E88,0x9E8B,/* 0xE0-0xE7 */
-	0x9E92,0x93D6,0x9E9D,0xF9F3,0x9EDB,0x9EDC,0x9EDD,0x9EE0,/* 0xE8-0xEF */
+	0x9E92,0x93D6,0x9E9D,0x9E9F,0x9EDB,0x9EDC,0x9EDD,0x9EE0,/* 0xE8-0xEF */
 	0x9EDF,0x9EE2,0x9EE9,0x9EE7,0x9EE5,0x9EEA,0x9EEF,0x9F22,/* 0xF0-0xF7 */
 	0x9F2C,0x9F2F,0x9F39,0x9F37,0x9F3D,0x9F3E,0x9F44,0x0000,/* 0xF8-0xFF */
 };
@@ -4240,23 +4240,12 @@
 	0x9D0B,0x9D0C,0x9D0D,0x9D0E,0x9D0F,0x9D10,0x9D11,0x9D12,/* 0x68-0x6F */
 	0x9D13,0x9D14,0x9D15,0x9D16,0x9D17,0x9D18,0x9D19,0x9D1A,/* 0x70-0x77 */
 	0x9D1B,0x9D1C,0x9D1D,0x9D1E,0x9D1F,0x9D20,0x9D21,0x0000,/* 0x78-0x7F */
-	
+
 	0x9D22,0x9D23,0x9D24,0x9D25,0x9D26,0x9D27,0x9D28,0x9D29,/* 0x80-0x87 */
 	0x9D2A,0x9D2B,0x9D2C,0x9D2D,0x9D2E,0x9D2F,0x9D30,0x9D31,/* 0x88-0x8F */
 	0x9D32,0x9D33,0x9D34,0x9D35,0x9D36,0x9D37,0x9D38,0x9D39,/* 0x90-0x97 */
 	0x9D3A,0x9D3B,0x9D3C,0x9D3D,0x9D3E,0x9D3F,0x9D40,0x9D41,/* 0x98-0x9F */
 	0x9D42,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0xA0-0xA7 */
-	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0xA8-0xAF */
-	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0xB0-0xB7 */
-	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0xB8-0xBF */
-	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0xC0-0xC7 */
-	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0xC8-0xCF */
-	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0xD0-0xD7 */
-	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0xD8-0xDF */
-	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0xE0-0xE7 */
-	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0xE8-0xEF */
-	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0xF0-0xF7 */
-	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0xF8-0xFF */
 };
 
 static wchar_t c2u_F9[256] = {
@@ -4276,7 +4265,7 @@
 	0x9D6B,0x9D6C,0x9D6D,0x9D6E,0x9D6F,0x9D70,0x9D71,0x9D72,/* 0x68-0x6F */
 	0x9D73,0x9D74,0x9D75,0x9D76,0x9D77,0x9D78,0x9D79,0x9D7A,/* 0x70-0x77 */
 	0x9D7B,0x9D7C,0x9D7D,0x9D7E,0x9D7F,0x9D80,0x9D81,0x0000,/* 0x78-0x7F */
-	
+
 	0x9D82,0x9D83,0x9D84,0x9D85,0x9D86,0x9D87,0x9D88,0x9D89,/* 0x80-0x87 */
 	0x9D8A,0x9D8B,0x9D8C,0x9D8D,0x9D8E,0x9D8F,0x9D90,0x9D91,/* 0x88-0x8F */
 	0x9D92,0x9D93,0x9D94,0x9D95,0x9D96,0x9D97,0x9D98,0x9D99,/* 0x90-0x97 */
@@ -4295,17 +4284,17 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x38-0x3F */
 	0x9DA3,0x9DA4,0x9DA5,0x9DA6,0x9DA7,0x9DA8,0x9DA9,0x9DAA,/* 0x40-0x47 */
 	0x9DAB,0x9DAC,0x9DAD,0x9DAE,0x9DAF,0x9DB0,0x9DB1,0x9DB2,/* 0x48-0x4F */
-	0x9DB3,0xFA2D,0x9DB5,0x9DB6,0x9DB7,0x9DB8,0x9DB9,0x9DBA,/* 0x50-0x57 */
+	0x9DB3,0x9DB4,0x9DB5,0x9DB6,0x9DB7,0x9DB8,0x9DB9,0x9DBA,/* 0x50-0x57 */
 	0x9DBB,0x9DBC,0x9DBD,0x9DBE,0x9DBF,0x9DC0,0x9DC1,0x9DC2,/* 0x58-0x5F */
 	0x9DC3,0x9DC4,0x9DC5,0x9DC6,0x9DC7,0x9DC8,0x9DC9,0x9DCA,/* 0x60-0x67 */
 	0x9DCB,0x9DCC,0x9DCD,0x9DCE,0x9DCF,0x9DD0,0x9DD1,0x9DD2,/* 0x68-0x6F */
 	0x9DD3,0x9DD4,0x9DD5,0x9DD6,0x9DD7,0x9DD8,0x9DD9,0x9DDA,/* 0x70-0x77 */
 	0x9DDB,0x9DDC,0x9DDD,0x9DDE,0x9DDF,0x9DE0,0x9DE1,0x0000,/* 0x78-0x7F */
-	
+
 	0x9DE2,0x9DE3,0x9DE4,0x9DE5,0x9DE6,0x9DE7,0x9DE8,0x9DE9,/* 0x80-0x87 */
 	0x9DEA,0x9DEB,0x9DEC,0x9DED,0x9DEE,0x9DEF,0x9DF0,0x9DF1,/* 0x88-0x8F */
 	0x9DF2,0x9DF3,0x9DF4,0x9DF5,0x9DF6,0x9DF7,0x9DF8,0x9DF9,/* 0x90-0x97 */
-	0xF93A,0x9DFB,0x9DFC,0x9DFD,0x9DFE,0x9DFF,0x9E00,0x9E01,/* 0x98-0x9F */
+	0x9DFA,0x9DFB,0x9DFC,0x9DFD,0x9DFE,0x9DFF,0x9E00,0x9E01,/* 0x98-0x9F */
 	0x9E02,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0xA0-0xA7 */
 };
 
@@ -4321,15 +4310,15 @@
 	0x9E03,0x9E04,0x9E05,0x9E06,0x9E07,0x9E08,0x9E09,0x9E0A,/* 0x40-0x47 */
 	0x9E0B,0x9E0C,0x9E0D,0x9E0E,0x9E0F,0x9E10,0x9E11,0x9E12,/* 0x48-0x4F */
 	0x9E13,0x9E14,0x9E15,0x9E16,0x9E17,0x9E18,0x9E19,0x9E1A,/* 0x50-0x57 */
-	0x9E1B,0x9E1C,0x9E1D,0xF920,0x9E24,0x9E27,0x9E2E,0x9E30,/* 0x58-0x5F */
+	0x9E1B,0x9E1C,0x9E1D,0x9E1E,0x9E24,0x9E27,0x9E2E,0x9E30,/* 0x58-0x5F */
 	0x9E34,0x9E3B,0x9E3C,0x9E40,0x9E4D,0x9E50,0x9E52,0x9E53,/* 0x60-0x67 */
 	0x9E54,0x9E56,0x9E59,0x9E5D,0x9E5F,0x9E60,0x9E61,0x9E62,/* 0x68-0x6F */
 	0x9E65,0x9E6E,0x9E6F,0x9E72,0x9E74,0x9E75,0x9E76,0x9E77,/* 0x70-0x77 */
 	0x9E78,0x9E79,0x9E7A,0x9E7B,0x9E7C,0x9E7D,0x9E80,0x0000,/* 0x78-0x7F */
-	
+
 	0x9E81,0x9E83,0x9E84,0x9E85,0x9E86,0x9E89,0x9E8A,0x9E8C,/* 0x80-0x87 */
 	0x9E8D,0x9E8E,0x9E8F,0x9E90,0x9E91,0x9E94,0x9E95,0x9E96,/* 0x88-0x8F */
-	0xF988,0x9E98,0x9E99,0x9E9A,0x9E9B,0x9E9C,0x9E9E,0x9EA0,/* 0x90-0x97 */
+	0x9E97,0x9E98,0x9E99,0x9E9A,0x9E9B,0x9E9C,0x9E9E,0x9EA0,/* 0x90-0x97 */
 	0x9EA1,0x9EA2,0x9EA3,0x9EA4,0x9EA5,0x9EA7,0x9EA8,0x9EA9,/* 0x98-0x9F */
 	0x9EAA,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0xA0-0xA7 */
 };
@@ -4351,7 +4340,7 @@
 	0x9EE8,0x9EEB,0x9EEC,0x9EED,0x9EEE,0x9EF0,0x9EF1,0x9EF2,/* 0x68-0x6F */
 	0x9EF3,0x9EF4,0x9EF5,0x9EF6,0x9EF7,0x9EF8,0x9EFA,0x9EFD,/* 0x70-0x77 */
 	0x9EFF,0x9F00,0x9F01,0x9F02,0x9F03,0x9F04,0x9F05,0x0000,/* 0x78-0x7F */
-	
+
 	0x9F06,0x9F07,0x9F08,0x9F09,0x9F0A,0x9F0C,0x9F0F,0x9F11,/* 0x80-0x87 */
 	0x9F12,0x9F14,0x9F15,0x9F16,0x9F18,0x9F1A,0x9F1B,0x9F1C,/* 0x88-0x8F */
 	0x9F1D,0x9F1E,0x9F1F,0x9F21,0x9F23,0x9F24,0x9F25,0x9F26,/* 0x90-0x97 */
@@ -4376,10 +4365,10 @@
 	0x9F62,0x9F63,0x9F64,0x9F65,0x9F66,0x9F67,0x9F68,0x9F69,/* 0x68-0x6F */
 	0x9F6A,0x9F6B,0x9F6C,0x9F6D,0x9F6E,0x9F6F,0x9F70,0x9F71,/* 0x70-0x77 */
 	0x9F72,0x9F73,0x9F74,0x9F75,0x9F76,0x9F77,0x9F78,0x0000,/* 0x78-0x7F */
-	
+
 	0x9F79,0x9F7A,0x9F7B,0x9F7C,0x9F7D,0x9F7E,0x9F81,0x9F82,/* 0x80-0x87 */
-	0xF9C4,0x9F8E,0x9F8F,0x9F90,0x9F91,0x9F92,0x9F93,0x9F94,/* 0x88-0x8F */
-	0x9F95,0x9F96,0x9F97,0x9F98,0xF908,0x9F9D,0x9F9E,0x9FA1,/* 0x90-0x97 */
+	0x9F8D,0x9F8E,0x9F8F,0x9F90,0x9F91,0x9F92,0x9F93,0x9F94,/* 0x88-0x8F */
+	0x9F95,0x9F96,0x9F97,0x9F98,0x9F9C,0x9F9D,0x9F9E,0x9FA1,/* 0x90-0x97 */
 	0x9FA2,0x9FA3,0x9FA4,0x9FA5,0xF92C,0xF979,0xF995,0xF9E7,/* 0x98-0x9F */
 	0xF9F1,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0xA0-0xA7 */
 };
diff -Nru a/fs/nls/nls_cp949.c b/fs/nls/nls_cp949.c
--- a/fs/nls/nls_cp949.c	2005-03-01 23:39:17 -08:00
+++ b/fs/nls/nls_cp949.c	2005-03-01 23:39:17 -08:00
@@ -30,7 +30,7 @@
 	0xAC3F,0xAC41,0xAC42,0xAC43,0xAC44,0xAC45,0xAC46,0xAC47,/* 0x68-0x6F */
 	0xAC48,0xAC49,0xAC4A,0xAC4C,0xAC4E,0xAC4F,0xAC50,0xAC51,/* 0x70-0x77 */
 	0xAC52,0xAC53,0xAC55,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xAC56,0xAC57,0xAC59,0xAC5A,0xAC5B,0xAC5D,0xAC5E,/* 0x80-0x87 */
 	0xAC5F,0xAC60,0xAC61,0xAC62,0xAC63,0xAC64,0xAC65,0xAC66,/* 0x88-0x8F */
 	0xAC67,0xAC68,0xAC69,0xAC6A,0xAC6B,0xAC6C,0xAC6D,0xAC6E,/* 0x90-0x97 */
@@ -66,7 +66,7 @@
 	0xAD3F,0xAD40,0xAD41,0xAD42,0xAD43,0xAD46,0xAD48,0xAD4A,/* 0x68-0x6F */
 	0xAD4B,0xAD4C,0xAD4D,0xAD4E,0xAD4F,0xAD51,0xAD52,0xAD53,/* 0x70-0x77 */
 	0xAD55,0xAD56,0xAD57,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xAD59,0xAD5A,0xAD5B,0xAD5C,0xAD5D,0xAD5E,0xAD5F,/* 0x80-0x87 */
 	0xAD60,0xAD62,0xAD64,0xAD65,0xAD66,0xAD67,0xAD68,0xAD69,/* 0x88-0x8F */
 	0xAD6A,0xAD6B,0xAD6E,0xAD6F,0xAD71,0xAD72,0xAD77,0xAD78,/* 0x90-0x97 */
@@ -102,7 +102,7 @@
 	0xAE24,0xAE25,0xAE26,0xAE27,0xAE28,0xAE29,0xAE2A,0xAE2B,/* 0x68-0x6F */
 	0xAE2C,0xAE2D,0xAE2E,0xAE2F,0xAE32,0xAE33,0xAE35,0xAE36,/* 0x70-0x77 */
 	0xAE39,0xAE3B,0xAE3C,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xAE3D,0xAE3E,0xAE3F,0xAE42,0xAE44,0xAE47,0xAE48,/* 0x80-0x87 */
 	0xAE49,0xAE4B,0xAE4F,0xAE51,0xAE52,0xAE53,0xAE55,0xAE57,/* 0x88-0x8F */
 	0xAE58,0xAE59,0xAE5A,0xAE5B,0xAE5E,0xAE62,0xAE63,0xAE64,/* 0x90-0x97 */
@@ -138,7 +138,7 @@
 	0xAF11,0xAF12,0xAF13,0xAF14,0xAF15,0xAF16,0xAF17,0xAF18,/* 0x68-0x6F */
 	0xAF19,0xAF1A,0xAF1B,0xAF1C,0xAF1D,0xAF1E,0xAF1F,0xAF20,/* 0x70-0x77 */
 	0xAF21,0xAF22,0xAF23,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xAF24,0xAF25,0xAF26,0xAF27,0xAF28,0xAF29,0xAF2A,/* 0x80-0x87 */
 	0xAF2B,0xAF2E,0xAF2F,0xAF31,0xAF33,0xAF35,0xAF36,0xAF37,/* 0x88-0x8F */
 	0xAF38,0xAF39,0xAF3A,0xAF3B,0xAF3E,0xAF40,0xAF44,0xAF45,/* 0x90-0x97 */
@@ -174,7 +174,7 @@
 	0xAFEB,0xAFEC,0xAFED,0xAFEE,0xAFEF,0xAFF2,0xAFF3,0xAFF5,/* 0x68-0x6F */
 	0xAFF6,0xAFF7,0xAFF9,0xAFFA,0xAFFB,0xAFFC,0xAFFD,0xAFFE,/* 0x70-0x77 */
 	0xAFFF,0xB002,0xB003,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xB005,0xB006,0xB007,0xB008,0xB009,0xB00A,0xB00B,/* 0x80-0x87 */
 	0xB00D,0xB00E,0xB00F,0xB011,0xB012,0xB013,0xB015,0xB016,/* 0x88-0x8F */
 	0xB017,0xB018,0xB019,0xB01A,0xB01B,0xB01E,0xB01F,0xB020,/* 0x90-0x97 */
@@ -210,7 +210,7 @@
 	0xB0DC,0xB0DD,0xB0DE,0xB0DF,0xB0E1,0xB0E2,0xB0E3,0xB0E4,/* 0x68-0x6F */
 	0xB0E6,0xB0E7,0xB0E8,0xB0E9,0xB0EA,0xB0EB,0xB0EC,0xB0ED,/* 0x70-0x77 */
 	0xB0EE,0xB0EF,0xB0F0,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xB0F1,0xB0F2,0xB0F3,0xB0F4,0xB0F5,0xB0F6,0xB0F7,/* 0x80-0x87 */
 	0xB0F8,0xB0F9,0xB0FA,0xB0FB,0xB0FC,0xB0FD,0xB0FE,0xB0FF,/* 0x88-0x8F */
 	0xB100,0xB101,0xB102,0xB103,0xB104,0xB105,0xB106,0xB107,/* 0x90-0x97 */
@@ -246,7 +246,7 @@
 	0xB1C0,0xB1C1,0xB1C2,0xB1C3,0xB1C4,0xB1C5,0xB1C6,0xB1C7,/* 0x68-0x6F */
 	0xB1C8,0xB1C9,0xB1CA,0xB1CB,0xB1CD,0xB1CE,0xB1CF,0xB1D1,/* 0x70-0x77 */
 	0xB1D2,0xB1D3,0xB1D5,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xB1D6,0xB1D7,0xB1D8,0xB1D9,0xB1DA,0xB1DB,0xB1DE,/* 0x80-0x87 */
 	0xB1E0,0xB1E1,0xB1E2,0xB1E3,0xB1E4,0xB1E5,0xB1E6,0xB1E7,/* 0x88-0x8F */
 	0xB1EA,0xB1EB,0xB1ED,0xB1EE,0xB1EF,0xB1F1,0xB1F2,0xB1F3,/* 0x90-0x97 */
@@ -282,7 +282,7 @@
 	0xB29C,0xB29D,0xB29E,0xB29F,0xB2A2,0xB2A4,0xB2A7,0xB2A8,/* 0x68-0x6F */
 	0xB2A9,0xB2AB,0xB2AD,0xB2AE,0xB2AF,0xB2B1,0xB2B2,0xB2B3,/* 0x70-0x77 */
 	0xB2B5,0xB2B6,0xB2B7,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xB2B8,0xB2B9,0xB2BA,0xB2BB,0xB2BC,0xB2BD,0xB2BE,/* 0x80-0x87 */
 	0xB2BF,0xB2C0,0xB2C1,0xB2C2,0xB2C3,0xB2C4,0xB2C5,0xB2C6,/* 0x88-0x8F */
 	0xB2C7,0xB2CA,0xB2CB,0xB2CD,0xB2CE,0xB2CF,0xB2D1,0xB2D3,/* 0x90-0x97 */
@@ -318,7 +318,7 @@
 	0xB397,0xB398,0xB399,0xB39A,0xB39B,0xB39C,0xB39D,0xB39E,/* 0x68-0x6F */
 	0xB39F,0xB3A2,0xB3A3,0xB3A4,0xB3A5,0xB3A6,0xB3A7,0xB3A9,/* 0x70-0x77 */
 	0xB3AA,0xB3AB,0xB3AD,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xB3AE,0xB3AF,0xB3B0,0xB3B1,0xB3B2,0xB3B3,0xB3B4,/* 0x80-0x87 */
 	0xB3B5,0xB3B6,0xB3B7,0xB3B8,0xB3B9,0xB3BA,0xB3BB,0xB3BC,/* 0x88-0x8F */
 	0xB3BD,0xB3BE,0xB3BF,0xB3C0,0xB3C1,0xB3C2,0xB3C3,0xB3C6,/* 0x90-0x97 */
@@ -354,7 +354,7 @@
 	0xB46F,0xB470,0xB471,0xB472,0xB473,0xB474,0xB475,0xB476,/* 0x68-0x6F */
 	0xB477,0xB478,0xB479,0xB47A,0xB47B,0xB47C,0xB47D,0xB47E,/* 0x70-0x77 */
 	0xB47F,0xB481,0xB482,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xB483,0xB484,0xB485,0xB486,0xB487,0xB489,0xB48A,/* 0x80-0x87 */
 	0xB48B,0xB48C,0xB48D,0xB48E,0xB48F,0xB490,0xB491,0xB492,/* 0x88-0x8F */
 	0xB493,0xB494,0xB495,0xB496,0xB497,0xB498,0xB499,0xB49A,/* 0x90-0x97 */
@@ -390,7 +390,7 @@
 	0xB552,0xB553,0xB555,0xB556,0xB557,0xB558,0xB559,0xB55A,/* 0x68-0x6F */
 	0xB55B,0xB55E,0xB562,0xB563,0xB564,0xB565,0xB566,0xB567,/* 0x70-0x77 */
 	0xB568,0xB569,0xB56A,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xB56B,0xB56C,0xB56D,0xB56E,0xB56F,0xB570,0xB571,/* 0x80-0x87 */
 	0xB572,0xB573,0xB574,0xB575,0xB576,0xB577,0xB578,0xB579,/* 0x88-0x8F */
 	0xB57A,0xB57B,0xB57C,0xB57D,0xB57E,0xB57F,0xB580,0xB581,/* 0x90-0x97 */
@@ -426,7 +426,7 @@
 	0xB626,0xB627,0xB628,0xB629,0xB62A,0xB62B,0xB62D,0xB62E,/* 0x68-0x6F */
 	0xB62F,0xB630,0xB631,0xB632,0xB633,0xB635,0xB636,0xB637,/* 0x70-0x77 */
 	0xB638,0xB639,0xB63A,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xB63B,0xB63C,0xB63D,0xB63E,0xB63F,0xB640,0xB641,/* 0x80-0x87 */
 	0xB642,0xB643,0xB644,0xB645,0xB646,0xB647,0xB649,0xB64A,/* 0x88-0x8F */
 	0xB64B,0xB64C,0xB64D,0xB64E,0xB64F,0xB650,0xB651,0xB652,/* 0x90-0x97 */
@@ -462,7 +462,7 @@
 	0xB6E5,0xB6E6,0xB6E7,0xB6E8,0xB6E9,0xB6EA,0xB6EB,0xB6EC,/* 0x68-0x6F */
 	0xB6ED,0xB6EE,0xB6EF,0xB6F1,0xB6F2,0xB6F3,0xB6F5,0xB6F6,/* 0x70-0x77 */
 	0xB6F7,0xB6F9,0xB6FA,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xB6FB,0xB6FC,0xB6FD,0xB6FE,0xB6FF,0xB702,0xB703,/* 0x80-0x87 */
 	0xB704,0xB706,0xB707,0xB708,0xB709,0xB70A,0xB70B,0xB70C,/* 0x88-0x8F */
 	0xB70D,0xB70E,0xB70F,0xB710,0xB711,0xB712,0xB713,0xB714,/* 0x90-0x97 */
@@ -498,7 +498,7 @@
 	0xB7CB,0xB7CC,0xB7CD,0xB7CE,0xB7CF,0xB7D0,0xB7D1,0xB7D2,/* 0x68-0x6F */
 	0xB7D3,0xB7D4,0xB7D5,0xB7D6,0xB7D7,0xB7D8,0xB7D9,0xB7DA,/* 0x70-0x77 */
 	0xB7DB,0xB7DC,0xB7DD,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xB7DE,0xB7DF,0xB7E0,0xB7E1,0xB7E2,0xB7E3,0xB7E4,/* 0x80-0x87 */
 	0xB7E5,0xB7E6,0xB7E7,0xB7E8,0xB7E9,0xB7EA,0xB7EB,0xB7EE,/* 0x88-0x8F */
 	0xB7EF,0xB7F1,0xB7F2,0xB7F3,0xB7F5,0xB7F6,0xB7F7,0xB7F8,/* 0x90-0x97 */
@@ -534,7 +534,7 @@
 	0xB8A7,0xB8A9,0xB8AA,0xB8AB,0xB8AC,0xB8AD,0xB8AE,0xB8AF,/* 0x68-0x6F */
 	0xB8B1,0xB8B2,0xB8B3,0xB8B5,0xB8B6,0xB8B7,0xB8B9,0xB8BA,/* 0x70-0x77 */
 	0xB8BB,0xB8BC,0xB8BD,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xB8BE,0xB8BF,0xB8C2,0xB8C4,0xB8C6,0xB8C7,0xB8C8,/* 0x80-0x87 */
 	0xB8C9,0xB8CA,0xB8CB,0xB8CD,0xB8CE,0xB8CF,0xB8D1,0xB8D2,/* 0x88-0x8F */
 	0xB8D3,0xB8D5,0xB8D6,0xB8D7,0xB8D8,0xB8D9,0xB8DA,0xB8DB,/* 0x90-0x97 */
@@ -570,7 +570,7 @@
 	0xB988,0xB98B,0xB98C,0xB98F,0xB990,0xB991,0xB992,0xB993,/* 0x68-0x6F */
 	0xB994,0xB995,0xB996,0xB997,0xB998,0xB999,0xB99A,0xB99B,/* 0x70-0x77 */
 	0xB99C,0xB99D,0xB99E,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xB99F,0xB9A0,0xB9A1,0xB9A2,0xB9A3,0xB9A4,0xB9A5,/* 0x80-0x87 */
 	0xB9A6,0xB9A7,0xB9A8,0xB9A9,0xB9AA,0xB9AB,0xB9AE,0xB9AF,/* 0x88-0x8F */
 	0xB9B1,0xB9B2,0xB9B3,0xB9B5,0xB9B6,0xB9B7,0xB9B8,0xB9B9,/* 0x90-0x97 */
@@ -606,7 +606,7 @@
 	0xBA7B,0xBA7C,0xBA7D,0xBA7E,0xBA7F,0xBA80,0xBA81,0xBA82,/* 0x68-0x6F */
 	0xBA86,0xBA88,0xBA89,0xBA8A,0xBA8B,0xBA8D,0xBA8E,0xBA8F,/* 0x70-0x77 */
 	0xBA90,0xBA91,0xBA92,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xBA93,0xBA94,0xBA95,0xBA96,0xBA97,0xBA98,0xBA99,/* 0x80-0x87 */
 	0xBA9A,0xBA9B,0xBA9C,0xBA9D,0xBA9E,0xBA9F,0xBAA0,0xBAA1,/* 0x88-0x8F */
 	0xBAA2,0xBAA3,0xBAA4,0xBAA5,0xBAA6,0xBAA7,0xBAAA,0xBAAD,/* 0x90-0x97 */
@@ -642,7 +642,7 @@
 	0xBB5C,0xBB5D,0xBB5E,0xBB5F,0xBB60,0xBB62,0xBB64,0xBB65,/* 0x68-0x6F */
 	0xBB66,0xBB67,0xBB68,0xBB69,0xBB6A,0xBB6B,0xBB6D,0xBB6E,/* 0x70-0x77 */
 	0xBB6F,0xBB70,0xBB71,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xBB72,0xBB73,0xBB74,0xBB75,0xBB76,0xBB77,0xBB78,/* 0x80-0x87 */
 	0xBB79,0xBB7A,0xBB7B,0xBB7C,0xBB7D,0xBB7E,0xBB7F,0xBB80,/* 0x88-0x8F */
 	0xBB81,0xBB82,0xBB83,0xBB84,0xBB85,0xBB86,0xBB87,0xBB89,/* 0x90-0x97 */
@@ -678,7 +678,7 @@
 	0xBC3E,0xBC3F,0xBC42,0xBC46,0xBC47,0xBC48,0xBC4A,0xBC4B,/* 0x68-0x6F */
 	0xBC4E,0xBC4F,0xBC51,0xBC52,0xBC53,0xBC54,0xBC55,0xBC56,/* 0x70-0x77 */
 	0xBC57,0xBC58,0xBC59,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xBC5A,0xBC5B,0xBC5C,0xBC5E,0xBC5F,0xBC60,0xBC61,/* 0x80-0x87 */
 	0xBC62,0xBC63,0xBC64,0xBC65,0xBC66,0xBC67,0xBC68,0xBC69,/* 0x88-0x8F */
 	0xBC6A,0xBC6B,0xBC6C,0xBC6D,0xBC6E,0xBC6F,0xBC70,0xBC71,/* 0x90-0x97 */
@@ -714,7 +714,7 @@
 	0xBD26,0xBD27,0xBD28,0xBD29,0xBD2A,0xBD2B,0xBD2D,0xBD2E,/* 0x68-0x6F */
 	0xBD2F,0xBD30,0xBD31,0xBD32,0xBD33,0xBD34,0xBD35,0xBD36,/* 0x70-0x77 */
 	0xBD37,0xBD38,0xBD39,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xBD3A,0xBD3B,0xBD3C,0xBD3D,0xBD3E,0xBD3F,0xBD41,/* 0x80-0x87 */
 	0xBD42,0xBD43,0xBD44,0xBD45,0xBD46,0xBD47,0xBD4A,0xBD4B,/* 0x88-0x8F */
 	0xBD4D,0xBD4E,0xBD4F,0xBD51,0xBD52,0xBD53,0xBD54,0xBD55,/* 0x90-0x97 */
@@ -750,7 +750,7 @@
 	0xBDFB,0xBDFC,0xBDFD,0xBDFE,0xBDFF,0xBE01,0xBE02,0xBE04,/* 0x68-0x6F */
 	0xBE06,0xBE07,0xBE08,0xBE09,0xBE0A,0xBE0B,0xBE0E,0xBE0F,/* 0x70-0x77 */
 	0xBE11,0xBE12,0xBE13,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xBE15,0xBE16,0xBE17,0xBE18,0xBE19,0xBE1A,0xBE1B,/* 0x80-0x87 */
 	0xBE1E,0xBE20,0xBE21,0xBE22,0xBE23,0xBE24,0xBE25,0xBE26,/* 0x88-0x8F */
 	0xBE27,0xBE28,0xBE29,0xBE2A,0xBE2B,0xBE2C,0xBE2D,0xBE2E,/* 0x90-0x97 */
@@ -786,7 +786,7 @@
 	0xBEDE,0xBEDF,0xBEE1,0xBEE2,0xBEE6,0xBEE7,0xBEE8,0xBEE9,/* 0x68-0x6F */
 	0xBEEA,0xBEEB,0xBEED,0xBEEE,0xBEEF,0xBEF0,0xBEF1,0xBEF2,/* 0x70-0x77 */
 	0xBEF3,0xBEF4,0xBEF5,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xBEF6,0xBEF7,0xBEF8,0xBEF9,0xBEFA,0xBEFB,0xBEFC,/* 0x80-0x87 */
 	0xBEFD,0xBEFE,0xBEFF,0xBF00,0xBF02,0xBF03,0xBF04,0xBF05,/* 0x88-0x8F */
 	0xBF06,0xBF07,0xBF0A,0xBF0B,0xBF0C,0xBF0D,0xBF0E,0xBF0F,/* 0x90-0x97 */
@@ -822,7 +822,7 @@
 	0xBFA5,0xBFA6,0xBFA7,0xBFA8,0xBFA9,0xBFAA,0xBFAB,0xBFAC,/* 0x68-0x6F */
 	0xBFAD,0xBFAE,0xBFAF,0xBFB1,0xBFB2,0xBFB3,0xBFB4,0xBFB5,/* 0x70-0x77 */
 	0xBFB6,0xBFB7,0xBFB8,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xBFB9,0xBFBA,0xBFBB,0xBFBC,0xBFBD,0xBFBE,0xBFBF,/* 0x80-0x87 */
 	0xBFC0,0xBFC1,0xBFC2,0xBFC3,0xBFC4,0xBFC6,0xBFC7,0xBFC8,/* 0x88-0x8F */
 	0xBFC9,0xBFCA,0xBFCB,0xBFCE,0xBFCF,0xBFD1,0xBFD2,0xBFD3,/* 0x90-0x97 */
@@ -858,7 +858,7 @@
 	0xC065,0xC066,0xC067,0xC06A,0xC06B,0xC06C,0xC06D,0xC06E,/* 0x68-0x6F */
 	0xC06F,0xC070,0xC071,0xC072,0xC073,0xC074,0xC075,0xC076,/* 0x70-0x77 */
 	0xC077,0xC078,0xC079,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xC07A,0xC07B,0xC07C,0xC07D,0xC07E,0xC07F,0xC080,/* 0x80-0x87 */
 	0xC081,0xC082,0xC083,0xC084,0xC085,0xC086,0xC087,0xC088,/* 0x88-0x8F */
 	0xC089,0xC08A,0xC08B,0xC08C,0xC08D,0xC08E,0xC08F,0xC092,/* 0x90-0x97 */
@@ -894,7 +894,7 @@
 	0xC161,0xC162,0xC163,0xC166,0xC16A,0xC16B,0xC16C,0xC16D,/* 0x68-0x6F */
 	0xC16E,0xC16F,0xC171,0xC172,0xC173,0xC175,0xC176,0xC177,/* 0x70-0x77 */
 	0xC179,0xC17A,0xC17B,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xC17C,0xC17D,0xC17E,0xC17F,0xC180,0xC181,0xC182,/* 0x80-0x87 */
 	0xC183,0xC184,0xC186,0xC187,0xC188,0xC189,0xC18A,0xC18B,/* 0x88-0x8F */
 	0xC18F,0xC191,0xC192,0xC193,0xC195,0xC197,0xC198,0xC199,/* 0x90-0x97 */
@@ -930,7 +930,7 @@
 	0xC24E,0xC24F,0xC252,0xC253,0xC255,0xC256,0xC257,0xC259,/* 0x68-0x6F */
 	0xC25A,0xC25B,0xC25C,0xC25D,0xC25E,0xC25F,0xC261,0xC262,/* 0x70-0x77 */
 	0xC263,0xC264,0xC266,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xC267,0xC268,0xC269,0xC26A,0xC26B,0xC26E,0xC26F,/* 0x80-0x87 */
 	0xC271,0xC272,0xC273,0xC275,0xC276,0xC277,0xC278,0xC279,/* 0x88-0x8F */
 	0xC27A,0xC27B,0xC27E,0xC280,0xC282,0xC283,0xC284,0xC285,/* 0x90-0x97 */
@@ -966,7 +966,7 @@
 	0xC33A,0xC33B,0xC33C,0xC33D,0xC33E,0xC33F,0xC340,0xC341,/* 0x68-0x6F */
 	0xC342,0xC343,0xC344,0xC346,0xC347,0xC348,0xC349,0xC34A,/* 0x70-0x77 */
 	0xC34B,0xC34C,0xC34D,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xC34E,0xC34F,0xC350,0xC351,0xC352,0xC353,0xC354,/* 0x80-0x87 */
 	0xC355,0xC356,0xC357,0xC358,0xC359,0xC35A,0xC35B,0xC35C,/* 0x88-0x8F */
 	0xC35D,0xC35E,0xC35F,0xC360,0xC361,0xC362,0xC363,0xC364,/* 0x90-0x97 */
@@ -1002,7 +1002,7 @@
 	0xC406,0xC407,0xC409,0xC40A,0xC40B,0xC40C,0xC40D,0xC40E,/* 0x68-0x6F */
 	0xC40F,0xC411,0xC412,0xC413,0xC414,0xC415,0xC416,0xC417,/* 0x70-0x77 */
 	0xC418,0xC419,0xC41A,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xC41B,0xC41C,0xC41D,0xC41E,0xC41F,0xC420,0xC421,/* 0x80-0x87 */
 	0xC422,0xC423,0xC425,0xC426,0xC427,0xC428,0xC429,0xC42A,/* 0x88-0x8F */
 	0xC42B,0xC42D,0xC42E,0xC42F,0xC431,0xC432,0xC433,0xC435,/* 0x90-0x97 */
@@ -1038,7 +1038,7 @@
 	0xC4CD,0xC4CE,0xC4CF,0xC4D0,0xC4D1,0xC4D2,0xC4D3,0xC4D4,/* 0x68-0x6F */
 	0xC4D5,0xC4D6,0xC4D7,0xC4D8,0xC4D9,0xC4DA,0xC4DB,0xC4DC,/* 0x70-0x77 */
 	0xC4DD,0xC4DE,0xC4DF,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xC4E0,0xC4E1,0xC4E2,0xC4E3,0xC4E4,0xC4E5,0xC4E6,/* 0x80-0x87 */
 	0xC4E7,0xC4E8,0xC4EA,0xC4EB,0xC4EC,0xC4ED,0xC4EE,0xC4EF,/* 0x88-0x8F */
 	0xC4F2,0xC4F3,0xC4F5,0xC4F6,0xC4F7,0xC4F9,0xC4FB,0xC4FC,/* 0x90-0x97 */
@@ -1074,7 +1074,7 @@
 	0xC5CB,0xC5CD,0xC5CF,0xC5D2,0xC5D3,0xC5D5,0xC5D6,0xC5D7,/* 0x68-0x6F */
 	0xC5D9,0xC5DA,0xC5DB,0xC5DC,0xC5DD,0xC5DE,0xC5DF,0xC5E2,/* 0x70-0x77 */
 	0xC5E4,0xC5E6,0xC5E7,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xC5E8,0xC5E9,0xC5EA,0xC5EB,0xC5EF,0xC5F1,0xC5F2,/* 0x80-0x87 */
 	0xC5F3,0xC5F5,0xC5F8,0xC5F9,0xC5FA,0xC5FB,0xC602,0xC603,/* 0x88-0x8F */
 	0xC604,0xC609,0xC60A,0xC60B,0xC60D,0xC60E,0xC60F,0xC611,/* 0x90-0x97 */
@@ -1110,7 +1110,7 @@
 	0xC6D8,0xC6D9,0xC6DA,0xC6DB,0xC6DE,0xC6DF,0xC6E2,0xC6E3,/* 0x68-0x6F */
 	0xC6E4,0xC6E5,0xC6E6,0xC6E7,0xC6EA,0xC6EB,0xC6ED,0xC6EE,/* 0x70-0x77 */
 	0xC6EF,0xC6F1,0xC6F2,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xC6F3,0xC6F4,0xC6F5,0xC6F6,0xC6F7,0xC6FA,0xC6FB,/* 0x80-0x87 */
 	0xC6FC,0xC6FE,0xC6FF,0xC700,0xC701,0xC702,0xC703,0xC706,/* 0x88-0x8F */
 	0xC707,0xC709,0xC70A,0xC70B,0xC70D,0xC70E,0xC70F,0xC710,/* 0x90-0x97 */
@@ -1146,7 +1146,7 @@
 	0xC7E6,0xC7E7,0xC7E9,0xC7EA,0xC7EB,0xC7ED,0xC7EE,0xC7EF,/* 0x68-0x6F */
 	0xC7F0,0xC7F1,0xC7F2,0xC7F3,0xC7F4,0xC7F5,0xC7F6,0xC7F7,/* 0x70-0x77 */
 	0xC7F8,0xC7F9,0xC7FA,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xC7FB,0xC7FC,0xC7FD,0xC7FE,0xC7FF,0xC802,0xC803,/* 0x80-0x87 */
 	0xC805,0xC806,0xC807,0xC809,0xC80B,0xC80C,0xC80D,0xC80E,/* 0x88-0x8F */
 	0xC80F,0xC812,0xC814,0xC817,0xC818,0xC819,0xC81A,0xC81B,/* 0x90-0x97 */
@@ -1182,7 +1182,7 @@
 	0xC8CB,0xC8CD,0xC8CE,0xC8CF,0xC8D0,0xC8D1,0xC8D2,0xC8D3,/* 0x68-0x6F */
 	0xC8D6,0xC8D8,0xC8DA,0xC8DB,0xC8DC,0xC8DD,0xC8DE,0xC8DF,/* 0x70-0x77 */
 	0xC8E2,0xC8E3,0xC8E5,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xC8E6,0xC8E7,0xC8E8,0xC8E9,0xC8EA,0xC8EB,0xC8EC,/* 0x80-0x87 */
 	0xC8ED,0xC8EE,0xC8EF,0xC8F0,0xC8F1,0xC8F2,0xC8F3,0xC8F4,/* 0x88-0x8F */
 	0xC8F6,0xC8F7,0xC8F8,0xC8F9,0xC8FA,0xC8FB,0xC8FE,0xC8FF,/* 0x90-0x97 */
@@ -1218,7 +1218,7 @@
 	0xC935,0xC936,0xC937,0xC938,0xC939,0xC93A,0xC93B,0xC93C,/* 0x68-0x6F */
 	0xC93D,0xC93E,0xC93F,0xC940,0xC941,0xC942,0xC943,0xC944,/* 0x70-0x77 */
 	0xC945,0xC946,0xC947,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xC948,0xC949,0xC94A,0xC94B,0xC94C,0xC94D,0xC94E,/* 0x80-0x87 */
 	0xC94F,0xC952,0xC953,0xC955,0xC956,0xC957,0xC959,0xC95A,/* 0x88-0x8F */
 	0xC95B,0xC95C,0xC95D,0xC95E,0xC95F,0xC962,0xC964,0xC965,/* 0x90-0x97 */
@@ -1231,7 +1231,7 @@
 	0x25A5,0x25A8,0x25A7,0x25A6,0x25A9,0x2668,0x260F,0x260E,/* 0xC8-0xCF */
 	0x261C,0x261E,0x00B6,0x2020,0x2021,0x2195,0x2197,0x2199,/* 0xD0-0xD7 */
 	0x2196,0x2198,0x266D,0x2669,0x266A,0x266C,0x327F,0x321C,/* 0xD8-0xDF */
-	0x2116,0x33C7,0x2122,0x33C2,0x33D8,0x2121,0x0000,0x0000,/* 0xE0-0xE7 */
+	0x2116,0x33C7,0x2122,0x33C2,0x33D8,0x2121,0x20AC,0x00AE,/* 0xE0-0xE7 */
 };
 
 static wchar_t c2u_A3[256] = {
@@ -1251,7 +1251,7 @@
 	0xC99A,0xC99C,0xC99E,0xC99F,0xC9A0,0xC9A1,0xC9A2,0xC9A3,/* 0x68-0x6F */
 	0xC9A4,0xC9A5,0xC9A6,0xC9A7,0xC9A8,0xC9A9,0xC9AA,0xC9AB,/* 0x70-0x77 */
 	0xC9AC,0xC9AD,0xC9AE,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xC9AF,0xC9B0,0xC9B1,0xC9B2,0xC9B3,0xC9B4,0xC9B5,/* 0x80-0x87 */
 	0xC9B6,0xC9B7,0xC9B8,0xC9B9,0xC9BA,0xC9BB,0xC9BC,0xC9BD,/* 0x88-0x8F */
 	0xC9BE,0xC9BF,0xC9C2,0xC9C3,0xC9C5,0xC9C6,0xC9C9,0xC9CB,/* 0x90-0x97 */
@@ -1287,18 +1287,18 @@
 	0xCA11,0xCA12,0xCA13,0xCA15,0xCA16,0xCA17,0xCA19,0xCA1A,/* 0x68-0x6F */
 	0xCA1B,0xCA1C,0xCA1D,0xCA1E,0xCA1F,0xCA20,0xCA21,0xCA22,/* 0x70-0x77 */
 	0xCA23,0xCA24,0xCA25,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xCA26,0xCA27,0xCA28,0xCA2A,0xCA2B,0xCA2C,0xCA2D,/* 0x80-0x87 */
 	0xCA2E,0xCA2F,0xCA30,0xCA31,0xCA32,0xCA33,0xCA34,0xCA35,/* 0x88-0x8F */
 	0xCA36,0xCA37,0xCA38,0xCA39,0xCA3A,0xCA3B,0xCA3C,0xCA3D,/* 0x90-0x97 */
 	0xCA3E,0xCA3F,0xCA40,0xCA41,0xCA42,0xCA43,0xCA44,0xCA45,/* 0x98-0x9F */
-	0xCA46,0xFFA1,0xFFA2,0xFFA3,0xFFA4,0xFFA5,0xFFA6,0xFFA7,/* 0xA0-0xA7 */
-	0xFFA8,0xFFA9,0xFFAA,0xFFAB,0xFFAC,0xFFAD,0xFFAE,0xFFAF,/* 0xA8-0xAF */
-	0xFFB0,0xFFB1,0xFFB2,0xFFB3,0xFFB4,0xFFB5,0xFFB6,0xFFB7,/* 0xB0-0xB7 */
-	0xFFB8,0xFFB9,0xFFBA,0xFFBB,0xFFBC,0xFFBD,0xFFBE,0xFFC2,/* 0xB8-0xBF */
-	0xFFC3,0xFFC4,0xFFC5,0xFFC6,0xFFC7,0xFFCA,0xFFCB,0xFFCC,/* 0xC0-0xC7 */
-	0xFFCD,0xFFCE,0xFFCF,0xFFD2,0xFFD3,0xFFD4,0xFFD5,0xFFD6,/* 0xC8-0xCF */
-	0xFFD7,0xFFDA,0xFFDB,0xFFDC,0xFFA0,0x3165,0x3166,0x3167,/* 0xD0-0xD7 */
+	0xCA46,0x3131,0x3132,0x3133,0x3134,0x3135,0x3136,0x3137,/* 0xA0-0xA7 */
+	0x3138,0x3139,0x313A,0x313B,0x313C,0x313D,0x313E,0x313F,/* 0xA8-0xAF */
+	0x3140,0x3141,0x3142,0x3143,0x3144,0x3145,0x3146,0x3147,/* 0xB0-0xB7 */
+	0x3148,0x3149,0x314A,0x314B,0x314C,0x314D,0x314E,0x314F,/* 0xB8-0xBF */
+	0x3150,0x3151,0x3152,0x3153,0x3154,0x3155,0x3156,0x3157,/* 0xC0-0xC7 */
+	0x3158,0x3159,0x315A,0x315B,0x315C,0x315D,0x315E,0x315F,/* 0xC8-0xCF */
+	0x3160,0x3161,0x3162,0x3163,0x3164,0x3165,0x3166,0x3167,/* 0xD0-0xD7 */
 	0x3168,0x3169,0x316A,0x316B,0x316C,0x316D,0x316E,0x316F,/* 0xD8-0xDF */
 	0x3170,0x3171,0x3172,0x3173,0x3174,0x3175,0x3176,0x3177,/* 0xE0-0xE7 */
 	0x3178,0x3179,0x317A,0x317B,0x317C,0x317D,0x317E,0x317F,/* 0xE8-0xEF */
@@ -1323,7 +1323,7 @@
 	0xCA72,0xCA73,0xCA74,0xCA75,0xCA76,0xCA77,0xCA78,0xCA79,/* 0x68-0x6F */
 	0xCA7A,0xCA7B,0xCA7C,0xCA7E,0xCA7F,0xCA80,0xCA81,0xCA82,/* 0x70-0x77 */
 	0xCA83,0xCA85,0xCA86,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xCA87,0xCA88,0xCA89,0xCA8A,0xCA8B,0xCA8C,0xCA8D,/* 0x80-0x87 */
 	0xCA8E,0xCA8F,0xCA90,0xCA91,0xCA92,0xCA93,0xCA94,0xCA95,/* 0x88-0x8F */
 	0xCA96,0xCA97,0xCA99,0xCA9A,0xCA9B,0xCA9C,0xCA9D,0xCA9E,/* 0x90-0x97 */
@@ -1359,7 +1359,7 @@
 	0xCAD0,0xCAD2,0xCAD4,0xCAD5,0xCAD6,0xCAD7,0xCADA,0xCADB,/* 0x68-0x6F */
 	0xCADC,0xCADD,0xCADE,0xCADF,0xCAE1,0xCAE2,0xCAE3,0xCAE4,/* 0x70-0x77 */
 	0xCAE5,0xCAE6,0xCAE7,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xCAE8,0xCAE9,0xCAEA,0xCAEB,0xCAED,0xCAEE,0xCAEF,/* 0x80-0x87 */
 	0xCAF0,0xCAF1,0xCAF2,0xCAF3,0xCAF5,0xCAF6,0xCAF7,0xCAF8,/* 0x88-0x8F */
 	0xCAF9,0xCAFA,0xCAFB,0xCAFC,0xCAFD,0xCAFE,0xCAFF,0xCB00,/* 0x90-0x97 */
@@ -1392,7 +1392,7 @@
 	0xCB31,0xCB32,0xCB33,0xCB34,0xCB35,0xCB36,0xCB37,0xCB38,/* 0x68-0x6F */
 	0xCB39,0xCB3A,0xCB3B,0xCB3C,0xCB3D,0xCB3E,0xCB3F,0xCB40,/* 0x70-0x77 */
 	0xCB42,0xCB43,0xCB44,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xCB45,0xCB46,0xCB47,0xCB4A,0xCB4B,0xCB4D,0xCB4E,/* 0x80-0x87 */
 	0xCB4F,0xCB51,0xCB52,0xCB53,0xCB54,0xCB55,0xCB56,0xCB57,/* 0x88-0x8F */
 	0xCB5A,0xCB5B,0xCB5C,0xCB5E,0xCB5F,0xCB60,0xCB61,0xCB62,/* 0x90-0x97 */
@@ -1426,7 +1426,7 @@
 	0xCB90,0xCB91,0xCB92,0xCB93,0xCB94,0xCB95,0xCB96,0xCB97,/* 0x68-0x6F */
 	0xCB98,0xCB99,0xCB9A,0xCB9B,0xCB9D,0xCB9E,0xCB9F,0xCBA0,/* 0x70-0x77 */
 	0xCBA1,0xCBA2,0xCBA3,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xCBA4,0xCBA5,0xCBA6,0xCBA7,0xCBA8,0xCBA9,0xCBAA,/* 0x80-0x87 */
 	0xCBAB,0xCBAC,0xCBAD,0xCBAE,0xCBAF,0xCBB0,0xCBB1,0xCBB2,/* 0x88-0x8F */
 	0xCBB3,0xCBB4,0xCBB5,0xCBB6,0xCBB7,0xCBB9,0xCBBA,0xCBBB,/* 0x90-0x97 */
@@ -1462,7 +1462,7 @@
 	0xCBEA,0xCBEB,0xCBEC,0xCBED,0xCBEE,0xCBEF,0xCBF0,0xCBF1,/* 0x68-0x6F */
 	0xCBF2,0xCBF3,0xCBF4,0xCBF5,0xCBF6,0xCBF7,0xCBF8,0xCBF9,/* 0x70-0x77 */
 	0xCBFA,0xCBFB,0xCBFC,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xCBFD,0xCBFE,0xCBFF,0xCC00,0xCC01,0xCC02,0xCC03,/* 0x80-0x87 */
 	0xCC04,0xCC05,0xCC06,0xCC07,0xCC08,0xCC09,0xCC0A,0xCC0B,/* 0x88-0x8F */
 	0xCC0E,0xCC0F,0xCC11,0xCC12,0xCC13,0xCC15,0xCC16,0xCC17,/* 0x90-0x97 */
@@ -1498,7 +1498,7 @@
 	0xCC5B,0xCC5C,0xCC5D,0xCC5E,0xCC5F,0xCC61,0xCC62,0xCC63,/* 0x68-0x6F */
 	0xCC65,0xCC67,0xCC69,0xCC6A,0xCC6B,0xCC6C,0xCC6D,0xCC6E,/* 0x70-0x77 */
 	0xCC6F,0xCC71,0xCC72,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xCC73,0xCC74,0xCC76,0xCC77,0xCC78,0xCC79,0xCC7A,/* 0x80-0x87 */
 	0xCC7B,0xCC7C,0xCC7D,0xCC7E,0xCC7F,0xCC80,0xCC81,0xCC82,/* 0x88-0x8F */
 	0xCC83,0xCC84,0xCC85,0xCC86,0xCC87,0xCC88,0xCC89,0xCC8A,/* 0x90-0x97 */
@@ -1533,7 +1533,7 @@
 	0xCCC2,0xCCC3,0xCCC6,0xCCC8,0xCCCA,0xCCCB,0xCCCC,0xCCCD,/* 0x68-0x6F */
 	0xCCCE,0xCCCF,0xCCD1,0xCCD2,0xCCD3,0xCCD5,0xCCD6,0xCCD7,/* 0x70-0x77 */
 	0xCCD8,0xCCD9,0xCCDA,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xCCDB,0xCCDC,0xCCDD,0xCCDE,0xCCDF,0xCCE0,0xCCE1,/* 0x80-0x87 */
 	0xCCE2,0xCCE3,0xCCE5,0xCCE6,0xCCE7,0xCCE8,0xCCE9,0xCCEA,/* 0x88-0x8F */
 	0xCCEB,0xCCED,0xCCEE,0xCCEF,0xCCF1,0xCCF2,0xCCF3,0xCCF4,/* 0x90-0x97 */
@@ -1568,7 +1568,7 @@
 	0xCD2A,0xCD2B,0xCD2D,0xCD2E,0xCD2F,0xCD30,0xCD31,0xCD32,/* 0x68-0x6F */
 	0xCD33,0xCD34,0xCD35,0xCD36,0xCD37,0xCD38,0xCD3A,0xCD3B,/* 0x70-0x77 */
 	0xCD3C,0xCD3D,0xCD3E,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xCD3F,0xCD40,0xCD41,0xCD42,0xCD43,0xCD44,0xCD45,/* 0x80-0x87 */
 	0xCD46,0xCD47,0xCD48,0xCD49,0xCD4A,0xCD4B,0xCD4C,0xCD4D,/* 0x88-0x8F */
 	0xCD4E,0xCD4F,0xCD50,0xCD51,0xCD52,0xCD53,0xCD54,0xCD55,/* 0x90-0x97 */
@@ -1603,7 +1603,7 @@
 	0xCD89,0xCD8A,0xCD8B,0xCD8C,0xCD8D,0xCD8E,0xCD8F,0xCD90,/* 0x68-0x6F */
 	0xCD91,0xCD92,0xCD93,0xCD96,0xCD97,0xCD99,0xCD9A,0xCD9B,/* 0x70-0x77 */
 	0xCD9D,0xCD9E,0xCD9F,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xCDA0,0xCDA1,0xCDA2,0xCDA3,0xCDA6,0xCDA8,0xCDAA,/* 0x80-0x87 */
 	0xCDAB,0xCDAC,0xCDAD,0xCDAE,0xCDAF,0xCDB1,0xCDB2,0xCDB3,/* 0x88-0x8F */
 	0xCDB4,0xCDB5,0xCDB6,0xCDB7,0xCDB8,0xCDB9,0xCDBA,0xCDBB,/* 0x90-0x97 */
@@ -1628,7 +1628,7 @@
 	0xCDEA,0xCDEB,0xCDED,0xCDEE,0xCDEF,0xCDF1,0xCDF2,0xCDF3,/* 0x68-0x6F */
 	0xCDF4,0xCDF5,0xCDF6,0xCDF7,0xCDFA,0xCDFC,0xCDFE,0xCDFF,/* 0x70-0x77 */
 	0xCE00,0xCE01,0xCE02,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xCE03,0xCE05,0xCE06,0xCE07,0xCE09,0xCE0A,0xCE0B,/* 0x80-0x87 */
 	0xCE0D,0xCE0E,0xCE0F,0xCE10,0xCE11,0xCE12,0xCE13,0xCE15,/* 0x88-0x8F */
 	0xCE16,0xCE17,0xCE18,0xCE1A,0xCE1B,0xCE1C,0xCE1D,0xCE1E,/* 0x90-0x97 */
@@ -1653,7 +1653,7 @@
 	0xCE51,0xCE52,0xCE53,0xCE54,0xCE55,0xCE56,0xCE57,0xCE5A,/* 0x68-0x6F */
 	0xCE5B,0xCE5D,0xCE5E,0xCE62,0xCE63,0xCE64,0xCE65,0xCE66,/* 0x70-0x77 */
 	0xCE67,0xCE6A,0xCE6C,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xCE6E,0xCE6F,0xCE70,0xCE71,0xCE72,0xCE73,0xCE76,/* 0x80-0x87 */
 	0xCE77,0xCE79,0xCE7A,0xCE7B,0xCE7D,0xCE7E,0xCE7F,0xCE80,/* 0x88-0x8F */
 	0xCE81,0xCE82,0xCE83,0xCE86,0xCE88,0xCE8A,0xCE8B,0xCE8C,/* 0x90-0x97 */
@@ -1678,7 +1678,7 @@
 	0xCEC3,0xCEC4,0xCEC5,0xCEC6,0xCEC7,0xCEC8,0xCEC9,0xCECA,/* 0x68-0x6F */
 	0xCECB,0xCECC,0xCECD,0xCECE,0xCECF,0xCED0,0xCED1,0xCED2,/* 0x70-0x77 */
 	0xCED3,0xCED4,0xCED5,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xCED6,0xCED7,0xCED8,0xCED9,0xCEDA,0xCEDB,0xCEDC,/* 0x80-0x87 */
 	0xCEDD,0xCEDE,0xCEDF,0xCEE0,0xCEE1,0xCEE2,0xCEE3,0xCEE6,/* 0x88-0x8F */
 	0xCEE7,0xCEE9,0xCEEA,0xCEED,0xCEEE,0xCEEF,0xCEF0,0xCEF1,/* 0x90-0x97 */
@@ -1714,7 +1714,7 @@
 	0xCF2E,0xCF32,0xCF33,0xCF34,0xCF35,0xCF36,0xCF37,0xCF39,/* 0x68-0x6F */
 	0xCF3A,0xCF3B,0xCF3C,0xCF3D,0xCF3E,0xCF3F,0xCF40,0xCF41,/* 0x70-0x77 */
 	0xCF42,0xCF43,0xCF44,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xCF45,0xCF46,0xCF47,0xCF48,0xCF49,0xCF4A,0xCF4B,/* 0x80-0x87 */
 	0xCF4C,0xCF4D,0xCF4E,0xCF4F,0xCF50,0xCF51,0xCF52,0xCF53,/* 0x88-0x8F */
 	0xCF56,0xCF57,0xCF59,0xCF5A,0xCF5B,0xCF5D,0xCF5E,0xCF5F,/* 0x90-0x97 */
@@ -1750,7 +1750,7 @@
 	0xCF95,0xCF96,0xCF97,0xCF98,0xCF99,0xCF9A,0xCF9B,0xCF9C,/* 0x68-0x6F */
 	0xCF9D,0xCF9E,0xCF9F,0xCFA0,0xCFA2,0xCFA3,0xCFA4,0xCFA5,/* 0x70-0x77 */
 	0xCFA6,0xCFA7,0xCFA9,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xCFAA,0xCFAB,0xCFAC,0xCFAD,0xCFAE,0xCFAF,0xCFB1,/* 0x80-0x87 */
 	0xCFB2,0xCFB3,0xCFB4,0xCFB5,0xCFB6,0xCFB7,0xCFB8,0xCFB9,/* 0x88-0x8F */
 	0xCFBA,0xCFBB,0xCFBC,0xCFBD,0xCFBE,0xCFBF,0xCFC0,0xCFC1,/* 0x90-0x97 */
@@ -1786,7 +1786,7 @@
 	0xCFF4,0xCFF6,0xCFF7,0xCFF8,0xCFF9,0xCFFA,0xCFFB,0xCFFD,/* 0x68-0x6F */
 	0xCFFE,0xCFFF,0xD001,0xD002,0xD003,0xD005,0xD006,0xD007,/* 0x70-0x77 */
 	0xD008,0xD009,0xD00A,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xD00B,0xD00C,0xD00D,0xD00E,0xD00F,0xD010,0xD012,/* 0x80-0x87 */
 	0xD013,0xD014,0xD015,0xD016,0xD017,0xD019,0xD01A,0xD01B,/* 0x88-0x8F */
 	0xD01C,0xD01D,0xD01E,0xD01F,0xD020,0xD021,0xD022,0xD023,/* 0x90-0x97 */
@@ -1822,7 +1822,7 @@
 	0xD05A,0xD05B,0xD05C,0xD05D,0xD05E,0xD05F,0xD061,0xD062,/* 0x68-0x6F */
 	0xD063,0xD064,0xD065,0xD066,0xD067,0xD068,0xD069,0xD06A,/* 0x70-0x77 */
 	0xD06B,0xD06E,0xD06F,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xD071,0xD072,0xD073,0xD075,0xD076,0xD077,0xD078,/* 0x80-0x87 */
 	0xD079,0xD07A,0xD07B,0xD07E,0xD07F,0xD080,0xD082,0xD083,/* 0x88-0x8F */
 	0xD084,0xD085,0xD086,0xD087,0xD088,0xD089,0xD08A,0xD08B,/* 0x90-0x97 */
@@ -1858,7 +1858,7 @@
 	0xD0BE,0xD0BF,0xD0C2,0xD0C3,0xD0C5,0xD0C6,0xD0C7,0xD0CA,/* 0x68-0x6F */
 	0xD0CB,0xD0CC,0xD0CD,0xD0CE,0xD0CF,0xD0D2,0xD0D6,0xD0D7,/* 0x70-0x77 */
 	0xD0D8,0xD0D9,0xD0DA,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xD0DB,0xD0DE,0xD0DF,0xD0E1,0xD0E2,0xD0E3,0xD0E5,/* 0x80-0x87 */
 	0xD0E6,0xD0E7,0xD0E8,0xD0E9,0xD0EA,0xD0EB,0xD0EE,0xD0F2,/* 0x88-0x8F */
 	0xD0F3,0xD0F4,0xD0F5,0xD0F6,0xD0F7,0xD0F9,0xD0FA,0xD0FB,/* 0x90-0x97 */
@@ -1894,7 +1894,7 @@
 	0xD127,0xD128,0xD129,0xD12A,0xD12B,0xD12C,0xD12D,0xD12E,/* 0x68-0x6F */
 	0xD12F,0xD132,0xD133,0xD135,0xD136,0xD137,0xD139,0xD13B,/* 0x70-0x77 */
 	0xD13C,0xD13D,0xD13E,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xD13F,0xD142,0xD146,0xD147,0xD148,0xD149,0xD14A,/* 0x80-0x87 */
 	0xD14B,0xD14E,0xD14F,0xD151,0xD152,0xD153,0xD155,0xD156,/* 0x88-0x8F */
 	0xD157,0xD158,0xD159,0xD15A,0xD15B,0xD15E,0xD160,0xD162,/* 0x90-0x97 */
@@ -1930,7 +1930,7 @@
 	0xD192,0xD193,0xD194,0xD195,0xD196,0xD197,0xD198,0xD199,/* 0x68-0x6F */
 	0xD19A,0xD19B,0xD19C,0xD19D,0xD19E,0xD19F,0xD1A2,0xD1A3,/* 0x70-0x77 */
 	0xD1A5,0xD1A6,0xD1A7,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xD1A9,0xD1AA,0xD1AB,0xD1AC,0xD1AD,0xD1AE,0xD1AF,/* 0x80-0x87 */
 	0xD1B2,0xD1B4,0xD1B6,0xD1B7,0xD1B8,0xD1B9,0xD1BB,0xD1BD,/* 0x88-0x8F */
 	0xD1BE,0xD1BF,0xD1C1,0xD1C2,0xD1C3,0xD1C4,0xD1C5,0xD1C6,/* 0x90-0x97 */
@@ -1966,7 +1966,7 @@
 	0xD1F2,0xD1F3,0xD1F5,0xD1F6,0xD1F7,0xD1F9,0xD1FA,0xD1FB,/* 0x68-0x6F */
 	0xD1FC,0xD1FD,0xD1FE,0xD1FF,0xD200,0xD201,0xD202,0xD203,/* 0x70-0x77 */
 	0xD204,0xD205,0xD206,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xD208,0xD20A,0xD20B,0xD20C,0xD20D,0xD20E,0xD20F,/* 0x80-0x87 */
 	0xD211,0xD212,0xD213,0xD214,0xD215,0xD216,0xD217,0xD218,/* 0x88-0x8F */
 	0xD219,0xD21A,0xD21B,0xD21C,0xD21D,0xD21E,0xD21F,0xD220,/* 0x90-0x97 */
@@ -2002,7 +2002,7 @@
 	0xD254,0xD255,0xD256,0xD257,0xD258,0xD259,0xD25A,0xD25B,/* 0x68-0x6F */
 	0xD25D,0xD25E,0xD25F,0xD260,0xD261,0xD262,0xD263,0xD265,/* 0x70-0x77 */
 	0xD266,0xD267,0xD268,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xD269,0xD26A,0xD26B,0xD26C,0xD26D,0xD26E,0xD26F,/* 0x80-0x87 */
 	0xD270,0xD271,0xD272,0xD273,0xD274,0xD275,0xD276,0xD277,/* 0x88-0x8F */
 	0xD278,0xD279,0xD27A,0xD27B,0xD27C,0xD27D,0xD27E,0xD27F,/* 0x90-0x97 */
@@ -2038,7 +2038,7 @@
 	0xD2B6,0xD2B7,0xD2BA,0xD2BB,0xD2BD,0xD2BE,0xD2C1,0xD2C3,/* 0x68-0x6F */
 	0xD2C4,0xD2C5,0xD2C6,0xD2C7,0xD2CA,0xD2CC,0xD2CD,0xD2CE,/* 0x70-0x77 */
 	0xD2CF,0xD2D0,0xD2D1,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xD2D2,0xD2D3,0xD2D5,0xD2D6,0xD2D7,0xD2D9,0xD2DA,/* 0x80-0x87 */
 	0xD2DB,0xD2DD,0xD2DE,0xD2DF,0xD2E0,0xD2E1,0xD2E2,0xD2E3,/* 0x88-0x8F */
 	0xD2E6,0xD2E7,0xD2E8,0xD2E9,0xD2EA,0xD2EB,0xD2EC,0xD2ED,/* 0x90-0x97 */
@@ -2074,7 +2074,7 @@
 	0xD32F,0xD331,0xD332,0xD333,0xD334,0xD335,0xD336,0xD337,/* 0x68-0x6F */
 	0xD33A,0xD33E,0xD33F,0xD340,0xD341,0xD342,0xD343,0xD346,/* 0x70-0x77 */
 	0xD347,0xD348,0xD349,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xD34A,0xD34B,0xD34C,0xD34D,0xD34E,0xD34F,0xD350,/* 0x80-0x87 */
 	0xD351,0xD352,0xD353,0xD354,0xD355,0xD356,0xD357,0xD358,/* 0x88-0x8F */
 	0xD359,0xD35A,0xD35B,0xD35C,0xD35D,0xD35E,0xD35F,0xD360,/* 0x90-0x97 */
@@ -2110,7 +2110,7 @@
 	0xD394,0xD395,0xD396,0xD397,0xD39A,0xD39B,0xD39D,0xD39E,/* 0x68-0x6F */
 	0xD39F,0xD3A1,0xD3A2,0xD3A3,0xD3A4,0xD3A5,0xD3A6,0xD3A7,/* 0x70-0x77 */
 	0xD3AA,0xD3AC,0xD3AE,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xD3AF,0xD3B0,0xD3B1,0xD3B2,0xD3B3,0xD3B5,0xD3B6,/* 0x80-0x87 */
 	0xD3B7,0xD3B9,0xD3BA,0xD3BB,0xD3BD,0xD3BE,0xD3BF,0xD3C0,/* 0x88-0x8F */
 	0xD3C1,0xD3C2,0xD3C3,0xD3C6,0xD3C7,0xD3CA,0xD3CB,0xD3CC,/* 0x90-0x97 */
@@ -2146,7 +2146,7 @@
 	0xD403,0xD404,0xD405,0xD406,0xD407,0xD409,0xD40A,0xD40B,/* 0x68-0x6F */
 	0xD40C,0xD40D,0xD40E,0xD40F,0xD410,0xD411,0xD412,0xD413,/* 0x70-0x77 */
 	0xD414,0xD415,0xD416,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xD417,0xD418,0xD419,0xD41A,0xD41B,0xD41C,0xD41E,/* 0x80-0x87 */
 	0xD41F,0xD420,0xD421,0xD422,0xD423,0xD424,0xD425,0xD426,/* 0x88-0x8F */
 	0xD427,0xD428,0xD429,0xD42A,0xD42B,0xD42C,0xD42D,0xD42E,/* 0x90-0x97 */
@@ -2182,7 +2182,7 @@
 	0xD45B,0xD45D,0xD45E,0xD45F,0xD461,0xD462,0xD463,0xD465,/* 0x68-0x6F */
 	0xD466,0xD467,0xD468,0xD469,0xD46A,0xD46B,0xD46C,0xD46E,/* 0x70-0x77 */
 	0xD470,0xD471,0xD472,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xD473,0xD474,0xD475,0xD476,0xD477,0xD47A,0xD47B,/* 0x80-0x87 */
 	0xD47D,0xD47E,0xD481,0xD483,0xD484,0xD485,0xD486,0xD487,/* 0x88-0x8F */
 	0xD48A,0xD48C,0xD48E,0xD48F,0xD490,0xD491,0xD492,0xD493,/* 0x90-0x97 */
@@ -2218,7 +2218,7 @@
 	0xD4C0,0xD4C1,0xD4C2,0xD4C3,0xD4C4,0xD4C5,0xD4C6,0xD4C7,/* 0x68-0x6F */
 	0xD4C8,0xD4C9,0xD4CA,0xD4CB,0xD4CD,0xD4CE,0xD4CF,0xD4D1,/* 0x70-0x77 */
 	0xD4D2,0xD4D3,0xD4D5,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xD4D6,0xD4D7,0xD4D8,0xD4D9,0xD4DA,0xD4DB,0xD4DD,/* 0x80-0x87 */
 	0xD4DE,0xD4E0,0xD4E1,0xD4E2,0xD4E3,0xD4E4,0xD4E5,0xD4E6,/* 0x88-0x8F */
 	0xD4E7,0xD4E9,0xD4EA,0xD4EB,0xD4ED,0xD4EE,0xD4EF,0xD4F1,/* 0x90-0x97 */
@@ -2254,7 +2254,7 @@
 	0xD525,0xD526,0xD527,0xD528,0xD529,0xD52A,0xD52B,0xD52C,/* 0x68-0x6F */
 	0xD52D,0xD52E,0xD52F,0xD530,0xD531,0xD532,0xD533,0xD534,/* 0x70-0x77 */
 	0xD535,0xD536,0xD537,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xD538,0xD539,0xD53A,0xD53B,0xD53E,0xD53F,0xD541,/* 0x80-0x87 */
 	0xD542,0xD543,0xD545,0xD546,0xD547,0xD548,0xD549,0xD54A,/* 0x88-0x8F */
 	0xD54B,0xD54E,0xD550,0xD552,0xD553,0xD554,0xD555,0xD556,/* 0x90-0x97 */
@@ -2290,7 +2290,7 @@
 	0xD594,0xD595,0xD596,0xD597,0xD598,0xD599,0xD59A,0xD59B,/* 0x68-0x6F */
 	0xD59C,0xD59D,0xD59E,0xD59F,0xD5A0,0xD5A1,0xD5A2,0xD5A3,/* 0x70-0x77 */
 	0xD5A4,0xD5A6,0xD5A7,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xD5A8,0xD5A9,0xD5AA,0xD5AB,0xD5AC,0xD5AD,0xD5AE,/* 0x80-0x87 */
 	0xD5AF,0xD5B0,0xD5B1,0xD5B2,0xD5B3,0xD5B4,0xD5B5,0xD5B6,/* 0x88-0x8F */
 	0xD5B7,0xD5B8,0xD5B9,0xD5BA,0xD5BB,0xD5BC,0xD5BD,0xD5BE,/* 0x90-0x97 */
@@ -2326,7 +2326,7 @@
 	0xD5FA,0xD5FB,0xD5FC,0xD5FD,0xD5FE,0xD5FF,0xD602,0xD603,/* 0x68-0x6F */
 	0xD605,0xD606,0xD607,0xD609,0xD60A,0xD60B,0xD60C,0xD60D,/* 0x70-0x77 */
 	0xD60E,0xD60F,0xD612,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xD616,0xD617,0xD618,0xD619,0xD61A,0xD61B,0xD61D,/* 0x80-0x87 */
 	0xD61E,0xD61F,0xD621,0xD622,0xD623,0xD625,0xD626,0xD627,/* 0x88-0x8F */
 	0xD628,0xD629,0xD62A,0xD62B,0xD62C,0xD62E,0xD62F,0xD630,/* 0x90-0x97 */
@@ -2362,7 +2362,7 @@
 	0xD66B,0xD66C,0xD66D,0xD66E,0xD66F,0xD672,0xD673,0xD675,/* 0x68-0x6F */
 	0xD676,0xD677,0xD678,0xD679,0xD67A,0xD67B,0xD67C,0xD67D,/* 0x70-0x77 */
 	0xD67E,0xD67F,0xD680,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xD681,0xD682,0xD684,0xD686,0xD687,0xD688,0xD689,/* 0x80-0x87 */
 	0xD68A,0xD68B,0xD68E,0xD68F,0xD691,0xD692,0xD693,0xD695,/* 0x88-0x8F */
 	0xD696,0xD697,0xD698,0xD699,0xD69A,0xD69B,0xD69C,0xD69E,/* 0x90-0x97 */
@@ -2398,7 +2398,7 @@
 	0xD6D6,0xD6D8,0xD6DA,0xD6DB,0xD6DC,0xD6DD,0xD6DE,0xD6DF,/* 0x68-0x6F */
 	0xD6E1,0xD6E2,0xD6E3,0xD6E5,0xD6E6,0xD6E7,0xD6E9,0xD6EA,/* 0x70-0x77 */
 	0xD6EB,0xD6EC,0xD6ED,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xD6EE,0xD6EF,0xD6F1,0xD6F2,0xD6F3,0xD6F4,0xD6F6,/* 0x80-0x87 */
 	0xD6F7,0xD6F8,0xD6F9,0xD6FA,0xD6FB,0xD6FE,0xD6FF,0xD701,/* 0x88-0x8F */
 	0xD702,0xD703,0xD705,0xD706,0xD707,0xD708,0xD709,0xD70A,/* 0x90-0x97 */
@@ -2434,7 +2434,7 @@
 	0xD742,0xD743,0xD745,0xD746,0xD748,0xD74A,0xD74B,0xD74C,/* 0x68-0x6F */
 	0xD74D,0xD74E,0xD74F,0xD752,0xD753,0xD755,0xD75A,0xD75B,/* 0x70-0x77 */
 	0xD75C,0xD75D,0xD75E,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0xD75F,0xD762,0xD764,0xD766,0xD767,0xD768,0xD76A,/* 0x80-0x87 */
 	0xD76B,0xD76D,0xD76E,0xD76F,0xD771,0xD772,0xD773,0xD775,/* 0x88-0x8F */
 	0xD776,0xD777,0xD778,0xD779,0xD77A,0xD77B,0xD77E,0xD77F,/* 0x90-0x97 */
@@ -2470,7 +2470,7 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x68-0x6F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -2506,7 +2506,7 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x68-0x6F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -2542,7 +2542,7 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x68-0x6F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -2578,7 +2578,7 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x68-0x6F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -2614,7 +2614,7 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x68-0x6F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -2650,7 +2650,7 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x68-0x6F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -2686,7 +2686,7 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x68-0x6F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -2722,7 +2722,7 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x68-0x6F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -2730,7 +2730,7 @@
 	0x0000,0x79D1,0x83D3,0x8A87,0x8AB2,0x8DE8,0x904E,0x934B,/* 0xA0-0xA7 */
 	0x9846,0x5ED3,0x69E8,0x85FF,0x90ED,0xF905,0x51A0,0x5B98,/* 0xA8-0xAF */
 	0x5BEC,0x6163,0x68FA,0x6B3E,0x704C,0x742F,0x74D8,0x7BA1,/* 0xB0-0xB7 */
-	0x7F50,0x83C5,0x89C0,0x8CAB,0x95DC,0xFA2C,0x522E,0x605D,/* 0xB8-0xBF */
+	0x7F50,0x83C5,0x89C0,0x8CAB,0x95DC,0x9928,0x522E,0x605D,/* 0xB8-0xBF */
 	0x62EC,0x9002,0x4F8A,0x5149,0x5321,0x58D9,0x5EE3,0x66E0,/* 0xC0-0xC7 */
 	0x6D38,0x709A,0x72C2,0x73D6,0x7B50,0x80F1,0x945B,0x5366,/* 0xC8-0xCF */
 	0x639B,0x7F6B,0x4E56,0x5080,0x584A,0x58DE,0x602A,0x6127,/* 0xD0-0xD7 */
@@ -2758,7 +2758,7 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x68-0x6F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -2794,7 +2794,7 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x68-0x6F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -2830,7 +2830,7 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x68-0x6F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -2866,7 +2866,7 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x68-0x6F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -2902,7 +2902,7 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x68-0x6F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -2938,14 +2938,14 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x68-0x6F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x98-0x9F */
 	0x0000,0x68F9,0x6AC2,0x6DD8,0x6E21,0x6ED4,0x6FE4,0x71FE,/* 0xA0-0xA7 */
 	0x76DC,0x7779,0x79B1,0x7A3B,0x8404,0x89A9,0x8CED,0x8DF3,/* 0xA8-0xAF */
-	0x8E48,0x9003,0x9014,0x9053,0xFA26,0x934D,0x9676,0x97DC,/* 0xB0-0xB7 */
+	0x8E48,0x9003,0x9014,0x9053,0x90FD,0x934D,0x9676,0x97DC,/* 0xB0-0xB7 */
 	0x6BD2,0x7006,0x7258,0x72A2,0x7368,0x7763,0x79BF,0x7BE4,/* 0xB8-0xBF */
 	0x7E9B,0x8B80,0x58A9,0x60C7,0x6566,0x65FD,0x66BE,0x6C8C,/* 0xC0-0xC7 */
 	0x711E,0x71C9,0x8C5A,0x9813,0x4E6D,0x7A81,0x4EDD,0x51AC,/* 0xC8-0xCF */
@@ -2974,7 +2974,7 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x68-0x6F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -3010,7 +3010,7 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x68-0x6F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -3046,7 +3046,7 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x68-0x6F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -3082,7 +3082,7 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x68-0x6F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -3118,7 +3118,7 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x68-0x6F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -3154,7 +3154,7 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x68-0x6F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -3170,7 +3170,7 @@
 	0x99C1,0x4F34,0x534A,0x53CD,0x53DB,0x62CC,0x642C,0x6500,/* 0xE0-0xE7 */
 	0x6591,0x69C3,0x6CEE,0x6F58,0x73ED,0x7554,0x7622,0x76E4,/* 0xE8-0xEF */
 	0x76FC,0x78D0,0x78FB,0x792C,0x7D46,0x822C,0x87E0,0x8FD4,/* 0xF0-0xF7 */
-	0x9812,0xFA2A,0x52C3,0x62D4,0x64A5,0x6E24,0x6F51,0x0000,/* 0xF8-0xFF */
+	0x9812,0x98EF,0x52C3,0x62D4,0x64A5,0x6E24,0x6F51,0x0000,/* 0xF8-0xFF */
 };
 
 static wchar_t c2u_DB[256] = {
@@ -3190,7 +3190,7 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x68-0x6F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -3226,7 +3226,7 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x68-0x6F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -3238,7 +3238,7 @@
 	0x9A08,0x4FDD,0x5821,0x5831,0x5BF6,0x666E,0x6B65,0x6D11,/* 0xC0-0xC7 */
 	0x6E7A,0x6F7D,0x73E4,0x752B,0x83E9,0x88DC,0x8913,0x8B5C,/* 0xC8-0xCF */
 	0x8F14,0x4F0F,0x50D5,0x5310,0x535C,0x5B93,0x5FA9,0x670D,/* 0xD0-0xD7 */
-	0xFA1B,0x8179,0x832F,0x8514,0x8907,0x8986,0x8F39,0x8F3B,/* 0xD8-0xDF */
+	0x798F,0x8179,0x832F,0x8514,0x8907,0x8986,0x8F39,0x8F3B,/* 0xD8-0xDF */
 	0x99A5,0x9C12,0x672C,0x4E76,0x4FF8,0x5949,0x5C01,0x5CEF,/* 0xE0-0xE7 */
 	0x5CF0,0x6367,0x68D2,0x70FD,0x71A2,0x742B,0x7E2B,0x84EC,/* 0xE8-0xEF */
 	0x8702,0x9022,0x92D2,0x9CF3,0x4E0D,0x4ED8,0x4FEF,0x5085,/* 0xF0-0xF7 */
@@ -3262,7 +3262,7 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x68-0x6F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -3298,7 +3298,7 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x68-0x6F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -3314,7 +3314,7 @@
 	0x6E23,0x7009,0x7345,0x7802,0x793E,0x7940,0x7960,0x79C1,/* 0xE0-0xE7 */
 	0x7BE9,0x7D17,0x7D72,0x8086,0x820D,0x838E,0x84D1,0x86C7,/* 0xE8-0xEF */
 	0x88DF,0x8A50,0x8A5E,0x8B1D,0x8CDC,0x8D66,0x8FAD,0x90AA,/* 0xF0-0xF7 */
-	0xFA2B,0x99DF,0x9E9D,0x524A,0xF969,0x6714,0xF96A,0x0000,/* 0xF8-0xFF */
+	0x98FC,0x99DF,0x9E9D,0x524A,0xF969,0x6714,0xF96A,0x0000,/* 0xF8-0xFF */
 };
 
 static wchar_t c2u_DF[256] = {
@@ -3334,7 +3334,7 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x68-0x6F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -3345,7 +3345,7 @@
 	0x8518,0x886B,0x63F7,0x6F81,0x9212,0x98AF,0x4E0A,0x50B7,/* 0xB8-0xBF */
 	0x50CF,0x511F,0x5546,0x55AA,0x5617,0x5B40,0x5C19,0x5CE0,/* 0xC0-0xC7 */
 	0x5E38,0x5E8A,0x5EA0,0x5EC2,0x60F3,0x6851,0x6A61,0x6E58,/* 0xC8-0xCF */
-	0x723D,0x7240,0x72C0,0x76F8,0xFA1A,0x7BB1,0x7FD4,0x88F3,/* 0xD0-0xD7 */
+	0x723D,0x7240,0x72C0,0x76F8,0x7965,0x7BB1,0x7FD4,0x88F3,/* 0xD0-0xD7 */
 	0x89F4,0x8A73,0x8C61,0x8CDE,0x971C,0x585E,0x74BD,0x8CFD,/* 0xD8-0xDF */
 	0x55C7,0xF96C,0x7A61,0x7D22,0x8272,0x7272,0x751F,0x7525,/* 0xE0-0xE7 */
 	0xF96D,0x7B19,0x5885,0x58FB,0x5DBC,0x5E8F,0x5EB6,0x5F90,/* 0xE8-0xEF */
@@ -3370,7 +3370,7 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x68-0x6F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -3406,7 +3406,7 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x68-0x6F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -3442,7 +3442,7 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x68-0x6F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -3478,7 +3478,7 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x68-0x6F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -3492,7 +3492,7 @@
 	0x57F4,0x5BD4,0x5F0F,0x606F,0x62ED,0x690D,0x6B96,0x6E5C,/* 0xD0-0xD7 */
 	0x7184,0x7BD2,0x8755,0x8B58,0x8EFE,0x98DF,0x98FE,0x4F38,/* 0xD8-0xDF */
 	0x4F81,0x4FE1,0x547B,0x5A20,0x5BB8,0x613C,0x65B0,0x6668,/* 0xE0-0xE7 */
-	0x71FC,0x7533,0xFA19,0x7D33,0x814E,0x81E3,0x8398,0x85AA,/* 0xE8-0xEF */
+	0x71FC,0x7533,0x795E,0x7D33,0x814E,0x81E3,0x8398,0x85AA,/* 0xE8-0xEF */
 	0x85CE,0x8703,0x8A0A,0x8EAB,0x8F9B,0xF971,0x8FC5,0x5931,/* 0xF0-0xF7 */
 	0x5BA4,0x5BE6,0x6089,0x5BE9,0x5C0B,0x5FC3,0x6C81,0x0000,/* 0xF8-0xFF */
 };
@@ -3514,7 +3514,7 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x68-0x6F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -3550,7 +3550,7 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x68-0x6F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -3586,7 +3586,7 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x68-0x6F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -3622,7 +3622,7 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x68-0x6F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -3658,14 +3658,14 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x68-0x6F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x98-0x9F */
 	0x0000,0x70CF,0x71AC,0x7352,0x7B7D,0x8708,0x8AA4,0x9C32,/* 0xA0-0xA7 */
 	0x9F07,0x5C4B,0x6C83,0x7344,0x7389,0x923A,0x6EAB,0x7465,/* 0xA8-0xAF */
-	0x761F,0x7A69,0x7E15,0x860A,0xFA0C,0x58C5,0x64C1,0x74EE,/* 0xB0-0xB7 */
+	0x761F,0x7A69,0x7E15,0x860A,0x5140,0x58C5,0x64C1,0x74EE,/* 0xB0-0xB7 */
 	0x7515,0x7670,0x7FC1,0x9095,0x96CD,0x9954,0x6E26,0x74E6,/* 0xB8-0xBF */
 	0x7AA9,0x7AAA,0x81E5,0x86D9,0x8778,0x8A1B,0x5A49,0x5B8C,/* 0xC0-0xC7 */
 	0x5B9B,0x68A1,0x6900,0x6D63,0x73A9,0x7413,0x742C,0x7897,/* 0xC8-0xCF */
@@ -3694,7 +3694,7 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x68-0x6F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -3707,7 +3707,7 @@
 	0x84C9,0x8E0A,0x9394,0x93DE,0xF9C4,0x4E8E,0x4F51,0x5076,/* 0xC8-0xCF */
 	0x512A,0x53C8,0x53CB,0x53F3,0x5B87,0x5BD3,0x5C24,0x611A,/* 0xD0-0xD7 */
 	0x6182,0x65F4,0x725B,0x7397,0x7440,0x76C2,0x7950,0x7991,/* 0xD8-0xDF */
-	0x79B9,0x7D06,0xFA1E,0x828B,0x85D5,0x865E,0x8FC2,0x9047,/* 0xE0-0xE7 */
+	0x79B9,0x7D06,0x7FBD,0x828B,0x85D5,0x865E,0x8FC2,0x9047,/* 0xE0-0xE7 */
 	0x90F5,0x91EA,0x9685,0x96E8,0x96E9,0x52D6,0x5F67,0x65ED,/* 0xE8-0xEF */
 	0x6631,0x682F,0x715C,0x7A36,0x90C1,0x980A,0x4E91,0xF9C5,/* 0xF0-0xF7 */
 	0x6A52,0x6B9E,0x6F90,0x7189,0x8018,0x82B8,0x8553,0x0000,/* 0xF8-0xFF */
@@ -3730,7 +3730,7 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x68-0x6F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -3766,7 +3766,7 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x68-0x6F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -3802,7 +3802,7 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x68-0x6F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -3812,11 +3812,11 @@
 	0xF9E1,0xF9E2,0xF9E3,0x723E,0x73E5,0xF9E4,0x7570,0x75CD,/* 0xB0-0xB7 */
 	0xF9E5,0x79FB,0xF9E6,0x800C,0x8033,0x8084,0x82E1,0x8351,/* 0xB8-0xBF */
 	0xF9E7,0xF9E8,0x8CBD,0x8CB3,0x9087,0xF9E9,0xF9EA,0x98F4,/* 0xC0-0xC7 */
-	0x990C,0xF9EB,0xF9EC,0x7037,0xFA17,0x7FCA,0x7FCC,0x7FFC,/* 0xC8-0xCF */
+	0x990C,0xF9EB,0xF9EC,0x7037,0x76CA,0x7FCA,0x7FCC,0x7FFC,/* 0xC8-0xCF */
 	0x8B1A,0x4EBA,0x4EC1,0x5203,0x5370,0xF9ED,0x54BD,0x56E0,/* 0xD0-0xD7 */
 	0x59FB,0x5BC5,0x5F15,0x5FCD,0x6E6E,0xF9EE,0xF9EF,0x7D6A,/* 0xD8-0xDF */
 	0x8335,0xF9F0,0x8693,0x8A8D,0xF9F1,0x976D,0x9777,0xF9F2,/* 0xE0-0xE7 */
-	0xF9F3,0x4E00,0x4F5A,0x4F7E,0x58F9,0x65E5,0x6EA2,0xFA25,/* 0xE8-0xEF */
+	0xF9F3,0x4E00,0x4F5A,0x4F7E,0x58F9,0x65E5,0x6EA2,0x9038,/* 0xE8-0xEF */
 	0x93B0,0x99B9,0x4EFB,0x58EC,0x598A,0x59D9,0x6041,0xF9F4,/* 0xF0-0xF7 */
 	0xF9F5,0x7A14,0xF9F6,0x834F,0x8CC3,0x5165,0x5344,0x0000,/* 0xF8-0xFF */
 };
@@ -3838,7 +3838,7 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x68-0x6F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -3874,7 +3874,7 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x68-0x6F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -3910,7 +3910,7 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x68-0x6F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -3925,8 +3925,8 @@
 	0x633A,0x653F,0x6574,0x65CC,0x6676,0x6678,0x67FE,0x6968,/* 0xD8-0xDF */
 	0x6A89,0x6B63,0x6C40,0x6DC0,0x6DE8,0x6E1F,0x6E5E,0x701E,/* 0xE0-0xE7 */
 	0x70A1,0x738E,0x73FD,0x753A,0x775B,0x7887,0x798E,0x7A0B,/* 0xE8-0xEF */
-	0x7A7D,0xFA1D,0x7D8E,0x8247,0x8A02,0x8AEA,0x8C9E,0x912D,/* 0xF0-0xF7 */
-	0x914A,0x91D8,0x9266,0x92CC,0x9320,0x9706,0xFA1C,0x0000,/* 0xF8-0xFF */
+	0x7A7D,0x7CBE,0x7D8E,0x8247,0x8A02,0x8AEA,0x8C9E,0x912D,/* 0xF0-0xF7 */
+	0x914A,0x91D8,0x9266,0x92CC,0x9320,0x9706,0x9756,0x0000,/* 0xF8-0xFF */
 };
 
 static wchar_t c2u_F0[256] = {
@@ -3946,14 +3946,14 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x68-0x6F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x98-0x9F */
 	0x0000,0x975C,0x9802,0x9F0E,0x5236,0x5291,0x557C,0x5824,/* 0xA0-0xA7 */
 	0x5E1D,0x5F1F,0x608C,0x63D0,0x68AF,0x6FDF,0x796D,0x7B2C,/* 0xA8-0xAF */
-	0x81CD,0x85BA,0x88FD,0xFA22,0x8E44,0x918D,0x9664,0x969B,/* 0xB0-0xB7 */
+	0x81CD,0x85BA,0x88FD,0x8AF8,0x8E44,0x918D,0x9664,0x969B,/* 0xB0-0xB7 */
 	0x973D,0x984C,0x9F4A,0x4FCE,0x5146,0x51CB,0x52A9,0x5632,/* 0xB8-0xBF */
 	0x5F14,0x5F6B,0x63AA,0x64CD,0x65E9,0x6641,0x66FA,0x66F9,/* 0xC0-0xC7 */
 	0x671D,0x689D,0x68D7,0x69FD,0x6F15,0x6F6E,0x7167,0x71E5,/* 0xC8-0xCF */
@@ -3982,7 +3982,7 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x68-0x6F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -4018,7 +4018,7 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x68-0x6F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -4054,7 +4054,7 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x68-0x6F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -4090,7 +4090,7 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x68-0x6F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -4103,7 +4103,7 @@
 	0x51F8,0x54F2,0x5586,0x5FB9,0x64A4,0x6F88,0x7DB4,0x8F1F,/* 0xC8-0xCF */
 	0x8F4D,0x9435,0x50C9,0x5C16,0x6CBE,0x6DFB,0x751B,0x77BB,/* 0xD0-0xD7 */
 	0x7C3D,0x7C64,0x8A79,0x8AC2,0x581E,0x59BE,0x5E16,0x6377,/* 0xD8-0xDF */
-	0x7252,0x758A,0x776B,0x8ADC,0x8CBC,0x8F12,0x5EF3,0xFA12,/* 0xE0-0xE7 */
+	0x7252,0x758A,0x776B,0x8ADC,0x8CBC,0x8F12,0x5EF3,0x6674,/* 0xE0-0xE7 */
 	0x6DF8,0x807D,0x83C1,0x8ACB,0x9751,0x9BD6,0xFA00,0x5243,/* 0xE8-0xEF */
 	0x66FF,0x6D95,0x6EEF,0x7DE0,0x8AE6,0x902E,0x905E,0x9AD4,/* 0xF0-0xF7 */
 	0x521D,0x527F,0x54E8,0x6194,0x6284,0x62DB,0x68A2,0x0000,/* 0xF8-0xFF */
@@ -4126,7 +4126,7 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x68-0x6F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -4135,7 +4135,7 @@
 	0x790E,0x79D2,0x7A0D,0x8096,0x8278,0x82D5,0x8349,0x8549,/* 0xA8-0xAF */
 	0x8C82,0x8D85,0x9162,0x918B,0x91AE,0x4FC3,0x56D1,0x71ED,/* 0xB0-0xB7 */
 	0x77D7,0x8700,0x89F8,0x5BF8,0x5FD6,0x6751,0x90A8,0x53E2,/* 0xB8-0xBF */
-	0xFA10,0x5BF5,0x60A4,0x6181,0x6460,0x7E3D,0x8070,0x8525,/* 0xC0-0xC7 */
+	0x585A,0x5BF5,0x60A4,0x6181,0x6460,0x7E3D,0x8070,0x8525,/* 0xC0-0xC7 */
 	0x9283,0x64AE,0x50AC,0x5D14,0x6700,0x589C,0x62BD,0x63A8,/* 0xC8-0xCF */
 	0x690E,0x6978,0x6A1E,0x6E6B,0x76BA,0x79CB,0x82BB,0x8429,/* 0xD0-0xD7 */
 	0x8ACF,0x8DA8,0x8FFD,0x9112,0x914B,0x919C,0x9310,0x9318,/* 0xD8-0xDF */
@@ -4162,7 +4162,7 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x68-0x6F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -4198,7 +4198,7 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x68-0x6F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -4234,7 +4234,7 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x68-0x6F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -4270,7 +4270,7 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x68-0x6F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -4280,7 +4280,7 @@
 	0x5F3C,0x5FC5,0x6CCC,0x73CC,0x7562,0x758B,0x7B46,0x82FE,/* 0xB0-0xB7 */
 	0x999D,0x4E4F,0x903C,0x4E0B,0x4F55,0x53A6,0x590F,0x5EC8,/* 0xB8-0xBF */
 	0x6630,0x6CB3,0x7455,0x8377,0x8766,0x8CC0,0x9050,0x971E,/* 0xC0-0xC7 */
-	0x9C15,0x58D1,0x5B78,0x8650,0x8B14,0xFA2D,0x5BD2,0x6068,/* 0xC8-0xCF */
+	0x9C15,0x58D1,0x5B78,0x8650,0x8B14,0x9DB4,0x5BD2,0x6068,/* 0xC8-0xCF */
 	0x608D,0x65F1,0x6C57,0x6F22,0x6FA3,0x701A,0x7F55,0x7FF0,/* 0xD0-0xD7 */
 	0x9591,0x9592,0x9650,0x97D3,0x5272,0x8F44,0x51FD,0x542B,/* 0xD8-0xDF */
 	0x54B8,0x5563,0x558A,0x6ABB,0x6DB5,0x7DD8,0x8266,0x929C,/* 0xE0-0xE7 */
@@ -4306,7 +4306,7 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x68-0x6F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -4342,7 +4342,7 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x68-0x6F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -4378,7 +4378,7 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x68-0x6F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -4414,7 +4414,7 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x68-0x6F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x70-0x77 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -4428,7 +4428,7 @@
 	0x8667,0x6064,0x8B4E,0x9DF8,0x5147,0x51F6,0x5308,0x6D36,/* 0xD0-0xD7 */
 	0x80F8,0x9ED1,0x6615,0x6B23,0x7098,0x75D5,0x5403,0x5C79,/* 0xD8-0xDF */
 	0x7D07,0x8A16,0x6B20,0x6B3D,0x6B46,0x5438,0x6070,0x6D3D,/* 0xE0-0xE7 */
-	0x7FD5,0x8208,0x50D6,0xFA15,0x559C,0x566B,0x56CD,0x59EC,/* 0xE8-0xEF */
+	0x7FD5,0x8208,0x50D6,0x51DE,0x559C,0x566B,0x56CD,0x59EC,/* 0xE8-0xEF */
 	0x5B09,0x5E0C,0x6199,0x6198,0x6231,0x665E,0x66E6,0x7199,/* 0xF0-0xF7 */
 	0x71B9,0x71BA,0x72A7,0x79A7,0x7A00,0x7FB2,0x8A70,0x0000,/* 0xF8-0xFF */
 };
diff -Nru a/fs/nls/nls_cp950.c b/fs/nls/nls_cp950.c
--- a/fs/nls/nls_cp950.c	2005-03-01 23:39:17 -08:00
+++ b/fs/nls/nls_cp950.c	2005-03-01 23:39:17 -08:00
@@ -23,29 +23,29 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x30-0x37 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x38-0x3F */
 	0x3000,0xFF0C,0x3001,0x3002,0xFF0E,0x2027,0xFF1B,0xFF1A,/* 0x40-0x47 */
-	0xFF1F,0xFF01,0xFE30,0x2026,0x2025,0xFE50,0xFF64,0xFE52,/* 0x48-0x4F */
+	0xFF1F,0xFF01,0xFE30,0x2026,0x2025,0xFE50,0xFE51,0xFE52,/* 0x48-0x4F */
 	0x00B7,0xFE54,0xFE55,0xFE56,0xFE57,0xFF5C,0x2013,0xFE31,/* 0x50-0x57 */
 	0x2014,0xFE33,0x2574,0xFE34,0xFE4F,0xFF08,0xFF09,0xFE35,/* 0x58-0x5F */
-	0xFE36,0xFF5B,0xFF5D,0xFE37,0xFE38,0xFF3B,0xFF3D,0xFE39,/* 0x60-0x67 */
+	0xFE36,0xFF5B,0xFF5D,0xFE37,0xFE38,0x3014,0x3015,0xFE39,/* 0x60-0x67 */
 	0xFE3A,0x3010,0x3011,0xFE3B,0xFE3C,0x300A,0x300B,0xFE3D,/* 0x68-0x6F */
-	0xFE3E,0x3008,0x3009,0xFF3E,0xFE40,0x300C,0x300D,0xFE41,/* 0x70-0x77 */
+	0xFE3E,0x3008,0x3009,0xFE3F,0xFE40,0x300C,0x300D,0xFE41,/* 0x70-0x77 */
 	0xFE42,0x300E,0x300F,0xFE43,0xFE44,0xFE59,0xFE5A,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x98-0x9F */
-	0x0000,0xFE5B,0xFE5C,0xFE5D,0xFE5E,0xFF40,0xFF07,0x201C,/* 0xA0-0xA7 */
-	0xFF02,0x301D,0x301E,0x2035,0x2032,0xFF03,0xFF06,0xFF0A,/* 0xA8-0xAF */
+	0x0000,0xFE5B,0xFE5C,0xFE5D,0xFE5E,0x2018,0x2019,0x201C,/* 0xA0-0xA7 */
+	0x201D,0x301D,0x301E,0x2035,0x2032,0xFF03,0xFF06,0xFF0A,/* 0xA8-0xAF */
 	0x203B,0x00A7,0x3003,0x25CB,0x25CF,0x25B3,0x25B2,0x25CE,/* 0xB0-0xB7 */
 	0x2606,0x2605,0x25C7,0x25C6,0x25A1,0x25A0,0x25BD,0x25BC,/* 0xB8-0xBF */
-	0x32A3,0x2105,0x0305,0xFFE3,0xFF3F,0x02CD,0xFE49,0xFE4A,/* 0xC0-0xC7 */
+	0x32A3,0x2105,0x00AF,0xFFE3,0xFF3F,0x02CD,0xFE49,0xFE4A,/* 0xC0-0xC7 */
 	0xFE4D,0xFE4E,0xFE4B,0xFE4C,0xFE5F,0xFE60,0xFE61,0xFF0B,/* 0xC8-0xCF */
 	0xFF0D,0x00D7,0x00F7,0x00B1,0x221A,0xFF1C,0xFF1E,0xFF1D,/* 0xD0-0xD7 */
-	0x2266,0x2267,0x2260,0x221E,0x2252,0x2263,0xFE62,0xFE63,/* 0xD8-0xDF */
+	0x2266,0x2267,0x2260,0x221E,0x2252,0x2261,0xFE62,0xFE63,/* 0xD8-0xDF */
 	0xFE64,0xFE65,0xFE66,0xFF5E,0x2229,0x222A,0x22A5,0x2220,/* 0xE0-0xE7 */
 	0x221F,0x22BF,0x33D2,0x33D1,0x222B,0x222E,0x2235,0x2234,/* 0xE8-0xEF */
-	0x2640,0x2642,0x2641,0x2609,0x2191,0x2193,0x2190,0x2192,/* 0xF0-0xF7 */
+	0x2640,0x2642,0x2295,0x2299,0x2191,0x2193,0x2190,0x2192,/* 0xF0-0xF7 */
 	0x2196,0x2197,0x2199,0x2198,0x2225,0x2223,0xFF0F,0x0000,/* 0xF8-0xFF */
 };
 
@@ -61,22 +61,22 @@
 	0xFF3C,0x2215,0xFE68,0xFF04,0xFFE5,0x3012,0xFFE0,0xFFE1,/* 0x40-0x47 */
 	0xFF05,0xFF20,0x2103,0x2109,0xFE69,0xFE6A,0xFE6B,0x33D5,/* 0x48-0x4F */
 	0x339C,0x339D,0x339E,0x33CE,0x33A1,0x338E,0x338F,0x33C4,/* 0x50-0x57 */
-	0x2218,0x5159,0x515B,0x515E,0x515D,0x5161,0x5163,0x55E7,/* 0x58-0x5F */
+	0x00B0,0x5159,0x515B,0x515E,0x515D,0x5161,0x5163,0x55E7,/* 0x58-0x5F */
 	0x74E9,0x7CCE,0x2581,0x2582,0x2583,0x2584,0x2585,0x2586,/* 0x60-0x67 */
 	0x2587,0x2588,0x258F,0x258E,0x258D,0x258C,0x258B,0x258A,/* 0x68-0x6F */
 	0x2589,0x253C,0x2534,0x252C,0x2524,0x251C,0x2594,0x2500,/* 0x70-0x77 */
 	0x2502,0x2595,0x250C,0x2510,0x2514,0x2518,0x256D,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x98-0x9F */
-	0x0000,0x256E,0x2570,0x256F,0x0000,0x0000,0x0000,0x0000,/* 0xA0-0xA7 */
+	0x0000,0x256E,0x2570,0x256F,0x2550,0x255E,0x256A,0x2561,/* 0xA0-0xA7 */
 	0x25E2,0x25E3,0x25E5,0x25E4,0x2571,0x2572,0x2573,0xFF10,/* 0xA8-0xAF */
 	0xFF11,0xFF12,0xFF13,0xFF14,0xFF15,0xFF16,0xFF17,0xFF18,/* 0xB0-0xB7 */
 	0xFF19,0x2160,0x2161,0x2162,0x2163,0x2164,0x2165,0x2166,/* 0xB8-0xBF */
 	0x2167,0x2168,0x2169,0x3021,0x3022,0x3023,0x3024,0x3025,/* 0xC0-0xC7 */
-	0x3026,0x3027,0x3028,0x3029,0x0000,0x5344,0x0000,0xFF21,/* 0xC8-0xCF */
+	0x3026,0x3027,0x3028,0x3029,0x5341,0x5344,0x5345,0xFF21,/* 0xC8-0xCF */
 	0xFF22,0xFF23,0xFF24,0xFF25,0xFF26,0xFF27,0xFF28,0xFF29,/* 0xD0-0xD7 */
 	0xFF2A,0xFF2B,0xFF2C,0xFF2D,0xFF2E,0xFF2F,0xFF30,0xFF31,/* 0xD8-0xDF */
 	0xFF32,0xFF33,0xFF34,0xFF35,0xFF36,0xFF37,0xFF38,0xFF39,/* 0xE0-0xE7 */
@@ -102,7 +102,7 @@
 	0x03BD,0x03BE,0x03BF,0x03C0,0x03C1,0x03C3,0x03C4,0x03C5,/* 0x68-0x6F */
 	0x03C6,0x03C7,0x03C8,0x03C9,0x3105,0x3106,0x3107,0x3108,/* 0x70-0x77 */
 	0x3109,0x310A,0x310B,0x310C,0x310D,0x310E,0x310F,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -110,15 +110,12 @@
 	0x0000,0x3110,0x3111,0x3112,0x3113,0x3114,0x3115,0x3116,/* 0xA0-0xA7 */
 	0x3117,0x3118,0x3119,0x311A,0x311B,0x311C,0x311D,0x311E,/* 0xA8-0xAF */
 	0x311F,0x3120,0x3121,0x3122,0x3123,0x3124,0x3125,0x3126,/* 0xB0-0xB7 */
-	0x3127,0x3128,0x3129,0x2024,0x02C9,0x02CA,0x02C7,0x02CB,/* 0xB8-0xBF */
+	0x3127,0x3128,0x3129,0x02D9,0x02C9,0x02CA,0x02C7,0x02CB,/* 0xB8-0xBF */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0xC0-0xC7 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0xC8-0xCF */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0xD0-0xD7 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0xD8-0xDF */
-	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0xE0-0xE7 */
-	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0xE8-0xEF */
-	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0xF0-0xF7 */
-	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0xF8-0xFF */
+	0x0000,0x20AC,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0xE0-0xE7 */
 };
 
 static wchar_t c2u_A4[256] = {
@@ -130,24 +127,24 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x28-0x2F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x30-0x37 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x38-0x3F */
-	0x4E00,0x4E59,0x4E01,0x4E03,0x4E43,0x4E5D,0xF9BA,0x4E8C,/* 0x40-0x47 */
-	0x4EBA,0x513F,0x5165,0x516B,0x51E0,0x5200,0x5201,0xF98A,/* 0x48-0x4F */
+	0x4E00,0x4E59,0x4E01,0x4E03,0x4E43,0x4E5D,0x4E86,0x4E8C,/* 0x40-0x47 */
+	0x4EBA,0x513F,0x5165,0x516B,0x51E0,0x5200,0x5201,0x529B,/* 0x48-0x4F */
 	0x5315,0x5341,0x535C,0x53C8,0x4E09,0x4E0B,0x4E08,0x4E0A,/* 0x50-0x57 */
 	0x4E2B,0x4E38,0x51E1,0x4E45,0x4E48,0x4E5F,0x4E5E,0x4E8E,/* 0x58-0x5F */
 	0x4EA1,0x5140,0x5203,0x52FA,0x5343,0x53C9,0x53E3,0x571F,/* 0x60-0x67 */
-	0x58EB,0x5915,0x5927,0xF981,0x5B50,0x5B51,0x5B53,0x5BF8,/* 0x68-0x6F */
+	0x58EB,0x5915,0x5927,0x5973,0x5B50,0x5B51,0x5B53,0x5BF8,/* 0x68-0x6F */
 	0x5C0F,0x5C22,0x5C38,0x5C71,0x5DDD,0x5DE5,0x5DF1,0x5DF2,/* 0x70-0x77 */
 	0x5DF3,0x5DFE,0x5E72,0x5EFE,0x5F0B,0x5F13,0x624D,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x98-0x9F */
-	0x0000,0x4E11,0x4E10,0xF967,0x4E2D,0x4E30,0xF95E,0x4E4B,/* 0xA0-0xA7 */
+	0x0000,0x4E11,0x4E10,0x4E0D,0x4E2D,0x4E30,0x4E39,0x4E4B,/* 0xA0-0xA7 */
 	0x5C39,0x4E88,0x4E91,0x4E95,0x4E92,0x4E94,0x4EA2,0x4EC1,/* 0xA8-0xAF */
-	0xF9FD,0x4EC3,0x4EC6,0x4EC7,0x4ECD,0x4ECA,0x4ECB,0x4EC4,/* 0xB0-0xB7 */
-	0x5143,0x5141,0x5167,0xF9D1,0x516E,0x516C,0x5197,0x51F6,/* 0xB8-0xBF */
-	0x5206,0xFA00,0x5208,0x52FB,0x52FE,0x52FF,0x5316,0x5339,/* 0xC0-0xC7 */
+	0x4EC0,0x4EC3,0x4EC6,0x4EC7,0x4ECD,0x4ECA,0x4ECB,0x4EC4,/* 0xB0-0xB7 */
+	0x5143,0x5141,0x5167,0x516D,0x516E,0x516C,0x5197,0x51F6,/* 0xB8-0xBF */
+	0x5206,0x5207,0x5208,0x52FB,0x52FE,0x52FF,0x5316,0x5339,/* 0xC0-0xC7 */
 	0x5348,0x5347,0x5345,0x535E,0x5384,0x53CB,0x53CA,0x53CD,/* 0xC8-0xCF */
 	0x58EC,0x5929,0x592B,0x592A,0x592D,0x5B54,0x5C11,0x5C24,/* 0xD0-0xD7 */
 	0x5C3A,0x5C6F,0x5DF4,0x5E7B,0x5EFF,0x5F14,0x5F15,0x5FC3,/* 0xD8-0xDF */
@@ -167,14 +164,14 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x30-0x37 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x38-0x3F */
 	0x4E16,0x4E15,0x4E14,0x4E18,0x4E3B,0x4E4D,0x4E4F,0x4E4E,/* 0x40-0x47 */
-	0x4EE5,0x4ED8,0x4ED4,0x4ED5,0x4ED6,0x4ED7,0x4EE3,0xF9A8,/* 0x48-0x4F */
+	0x4EE5,0x4ED8,0x4ED4,0x4ED5,0x4ED6,0x4ED7,0x4EE3,0x4EE4,/* 0x48-0x4F */
 	0x4ED9,0x4EDE,0x5145,0x5144,0x5189,0x518A,0x51AC,0x51F9,/* 0x50-0x57 */
-	0x51FA,0x51F8,0x520A,0x52A0,0x529F,0x5305,0x5306,0xF963,/* 0x58-0x5F */
+	0x51FA,0x51F8,0x520A,0x52A0,0x529F,0x5305,0x5306,0x5317,/* 0x58-0x5F */
 	0x531D,0x4EDF,0x534A,0x5349,0x5361,0x5360,0x536F,0x536E,/* 0x60-0x67 */
 	0x53BB,0x53EF,0x53E4,0x53F3,0x53EC,0x53EE,0x53E9,0x53E8,/* 0x68-0x6F */
 	0x53FC,0x53F8,0x53F5,0x53EB,0x53E6,0x53EA,0x53F2,0x53F1,/* 0x70-0x77 */
-	0x53F0,0xF906,0x53ED,0x53FB,0x56DB,0x56DA,0x5916,0x0000,/* 0x78-0x7F */
-	
+	0x53F0,0x53E5,0x53ED,0x53FB,0x56DB,0x56DA,0x5916,0x0000,/* 0x78-0x7F */
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -186,7 +183,7 @@
 	0x6BCD,0x6C11,0x6C10,0x6C38,0x6C41,0x6C40,0x6C3E,0x72AF,/* 0xC0-0xC7 */
 	0x7384,0x7389,0x74DC,0x74E6,0x7518,0x751F,0x7528,0x7529,/* 0xC8-0xCF */
 	0x7530,0x7531,0x7532,0x7533,0x758B,0x767D,0x76AE,0x76BF,/* 0xD0-0xD7 */
-	0x76EE,0x77DB,0x77E2,0x77F3,0x793A,0x79BE,0x7A74,0xF9F7,/* 0xD8-0xDF */
+	0x76EE,0x77DB,0x77E2,0x77F3,0x793A,0x79BE,0x7A74,0x7ACB,/* 0xD8-0xDF */
 	0x4E1E,0x4E1F,0x4E52,0x4E53,0x4E69,0x4E99,0x4EA4,0x4EA6,/* 0xE0-0xE7 */
 	0x4EA5,0x4EFF,0x4F09,0x4F19,0x4F0A,0x4F15,0x4F0D,0x4F10,/* 0xE8-0xEF */
 	0x4F11,0x4F0F,0x4EF2,0x4EF6,0x4EFB,0x4EF0,0x4EF3,0x4EFD,/* 0xF0-0xF7 */
@@ -202,15 +199,15 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x28-0x2F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x30-0x37 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x38-0x3F */
-	0x5171,0x518D,0x51B0,0xF99C,0x5211,0x5212,0x520E,0x5216,/* 0x40-0x47 */
-	0xF99D,0x5308,0x5321,0x5320,0x5370,0x5371,0x5409,0xF9DE,/* 0x48-0x4F */
+	0x5171,0x518D,0x51B0,0x5217,0x5211,0x5212,0x520E,0x5216,/* 0x40-0x47 */
+	0x52A3,0x5308,0x5321,0x5320,0x5370,0x5371,0x5409,0x540F,/* 0x48-0x4F */
 	0x540C,0x540A,0x5410,0x5401,0x540B,0x5404,0x5411,0x540D,/* 0x50-0x57 */
 	0x5408,0x5403,0x540E,0x5406,0x5412,0x56E0,0x56DE,0x56DD,/* 0x58-0x5F */
 	0x5733,0x5730,0x5728,0x572D,0x572C,0x572F,0x5729,0x5919,/* 0x60-0x67 */
 	0x591A,0x5937,0x5938,0x5984,0x5978,0x5983,0x597D,0x5979,/* 0x68-0x6F */
-	0x5982,0x5981,0x5B57,0x5B58,0x5B87,0x5B88,0xFA04,0x5B89,/* 0x70-0x77 */
-	0x5BFA,0x5C16,0x5C79,0x5DDE,0x5E06,0x5E76,0xF98E,0x0000,/* 0x78-0x7F */
-	
+	0x5982,0x5981,0x5B57,0x5B58,0x5B87,0x5B88,0x5B85,0x5B89,/* 0x70-0x77 */
+	0x5BFA,0x5C16,0x5C79,0x5DDE,0x5E06,0x5E76,0x5E74,0x0000,/* 0x78-0x7F */
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -221,10 +218,10 @@
 	0x6B21,0x6B64,0x6B7B,0x6C16,0x6C5D,0x6C57,0x6C59,0x6C5F,/* 0xB8-0xBF */
 	0x6C60,0x6C50,0x6C55,0x6C61,0x6C5B,0x6C4D,0x6C4E,0x7070,/* 0xC0-0xC7 */
 	0x725F,0x725D,0x767E,0x7AF9,0x7C73,0x7CF8,0x7F36,0x7F8A,/* 0xC8-0xCF */
-	0xFA1E,0xF934,0x8003,0x800C,0x8012,0x8033,0x807F,0x8089,/* 0xD0-0xD7 */
-	0xF953,0x808C,0x81E3,0x81EA,0x81F3,0x81FC,0x820C,0x821B,/* 0xD8-0xDF */
-	0x821F,0x826E,0x8272,0x827E,0x866B,0x8840,0xFA08,0x8863,/* 0xE0-0xE7 */
-	0x897F,0x9621,0xF905,0x4EA8,0x4F4D,0x4F4F,0x4F47,0x4F57,/* 0xE8-0xEF */
+	0x7FBD,0x8001,0x8003,0x800C,0x8012,0x8033,0x807F,0x8089,/* 0xD0-0xD7 */
+	0x808B,0x808C,0x81E3,0x81EA,0x81F3,0x81FC,0x820C,0x821B,/* 0xD8-0xDF */
+	0x821F,0x826E,0x8272,0x827E,0x866B,0x8840,0x884C,0x8863,/* 0xE0-0xE7 */
+	0x897F,0x9621,0x4E32,0x4EA8,0x4F4D,0x4F4F,0x4F47,0x4F57,/* 0xE8-0xEF */
 	0x4F5E,0x4F34,0x4F5B,0x4F55,0x4F30,0x4F50,0x4F51,0x4F3D,/* 0xF0-0xF7 */
 	0x4F3A,0x4F38,0x4F43,0x4F54,0x4F3C,0x4F46,0x4F63,0x0000,/* 0xF8-0xFF */
 };
@@ -239,14 +236,14 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x30-0x37 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x38-0x3F */
 	0x4F5C,0x4F60,0x4F2F,0x4F4E,0x4F36,0x4F59,0x4F5D,0x4F48,/* 0x40-0x47 */
-	0x4F5A,0x514C,0x514B,0x514D,0x5175,0x51B6,0xF92E,0x5225,/* 0x48-0x4F */
-	0x5224,0xF9DD,0x522A,0x5228,0x52AB,0x52A9,0x52AA,0x52AC,/* 0x50-0x57 */
-	0x5323,0x5373,0xF91C,0xF9ED,0x542D,0x541E,0x543E,0x5426,/* 0x58-0x5F */
-	0x544E,0x5427,0x5446,0x5443,0x5433,0x5448,0xF980,0x541B,/* 0x60-0x67 */
+	0x4F5A,0x514C,0x514B,0x514D,0x5175,0x51B6,0x51B7,0x5225,/* 0x48-0x4F */
+	0x5224,0x5229,0x522A,0x5228,0x52AB,0x52A9,0x52AA,0x52AC,/* 0x50-0x57 */
+	0x5323,0x5373,0x5375,0x541D,0x542D,0x541E,0x543E,0x5426,/* 0x58-0x5F */
+	0x544E,0x5427,0x5446,0x5443,0x5433,0x5448,0x5442,0x541B,/* 0x60-0x67 */
 	0x5429,0x544A,0x5439,0x543B,0x5438,0x542E,0x5435,0x5436,/* 0x68-0x6F */
 	0x5420,0x543C,0x5440,0x5431,0x542B,0x541F,0x542C,0x56EA,/* 0x70-0x77 */
 	0x56F0,0x56E4,0x56EB,0x574A,0x5751,0x5740,0x574D,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -254,14 +251,14 @@
 	0x0000,0x5747,0x574E,0x573E,0x5750,0x574F,0x573B,0x58EF,/* 0xA0-0xA7 */
 	0x593E,0x599D,0x5992,0x59A8,0x599E,0x59A3,0x5999,0x5996,/* 0xA8-0xAF */
 	0x598D,0x59A4,0x5993,0x598A,0x59A5,0x5B5D,0x5B5C,0x5B5A,/* 0xB0-0xB7 */
-	0x5B5B,0x5B8C,0x5B8B,0x5B8F,0x5C2C,0x5C40,0x5C41,0xF9BD,/* 0xB8-0xBF */
+	0x5B5B,0x5B8C,0x5B8B,0x5B8F,0x5C2C,0x5C40,0x5C41,0x5C3F,/* 0xB8-0xBF */
 	0x5C3E,0x5C90,0x5C91,0x5C94,0x5C8C,0x5DEB,0x5E0C,0x5E8F,/* 0xC0-0xC7 */
-	0x5E87,0x5E8A,0x5EF7,0xF943,0x5F1F,0x5F64,0x5F62,0x5F77,/* 0xC8-0xCF */
+	0x5E87,0x5E8A,0x5EF7,0x5F04,0x5F1F,0x5F64,0x5F62,0x5F77,/* 0xC8-0xCF */
 	0x5F79,0x5FD8,0x5FCC,0x5FD7,0x5FCD,0x5FF1,0x5FEB,0x5FF8,/* 0xD0-0xD7 */
 	0x5FEA,0x6212,0x6211,0x6284,0x6297,0x6296,0x6280,0x6276,/* 0xD8-0xDF */
 	0x6289,0x626D,0x628A,0x627C,0x627E,0x6279,0x6273,0x6292,/* 0xE0-0xE7 */
 	0x626F,0x6298,0x626E,0x6295,0x6293,0x6291,0x6286,0x6539,/* 0xE8-0xEF */
-	0x653B,0x6538,0x65F1,0xF901,0x675F,0xF9E1,0x674F,0x6750,/* 0xF0-0xF7 */
+	0x653B,0x6538,0x65F1,0x66F4,0x675F,0x674E,0x674F,0x6750,/* 0xF0-0xF7 */
 	0x6751,0x675C,0x6756,0x675E,0x6749,0x6746,0x6760,0x0000,/* 0xF8-0xFF */
 };
 
@@ -275,28 +272,28 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x30-0x37 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x38-0x3F */
 	0x6753,0x6757,0x6B65,0x6BCF,0x6C42,0x6C5E,0x6C99,0x6C81,/* 0x40-0x47 */
-	0xF972,0x6C89,0x6C85,0x6C9B,0x6C6A,0x6C7A,0x6C90,0x6C70,/* 0x48-0x4F */
+	0x6C88,0x6C89,0x6C85,0x6C9B,0x6C6A,0x6C7A,0x6C90,0x6C70,/* 0x48-0x4F */
 	0x6C8C,0x6C68,0x6C96,0x6C92,0x6C7D,0x6C83,0x6C72,0x6C7E,/* 0x50-0x57 */
 	0x6C74,0x6C86,0x6C76,0x6C8D,0x6C94,0x6C98,0x6C82,0x7076,/* 0x58-0x5F */
-	0x707C,0x707D,0x7078,0xF946,0x7261,0x7260,0x72C4,0x72C2,/* 0x60-0x67 */
+	0x707C,0x707D,0x7078,0x7262,0x7261,0x7260,0x72C4,0x72C2,/* 0x60-0x67 */
 	0x7396,0x752C,0x752B,0x7537,0x7538,0x7682,0x76EF,0x77E3,/* 0x68-0x6F */
 	0x79C1,0x79C0,0x79BF,0x7A76,0x7CFB,0x7F55,0x8096,0x8093,/* 0x70-0x77 */
-	0x809D,0x8098,0x809B,0x809A,0x80B2,0xF97C,0x8292,0x0000,/* 0x78-0x7F */
-	
+	0x809D,0x8098,0x809B,0x809A,0x80B2,0x826F,0x8292,0x0000,/* 0x78-0x7F */
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x98-0x9F */
-	0x0000,0x828B,0x828D,0xFA0A,0x89D2,0x8A00,0x8C37,0x8C46,/* 0xA0-0xA7 */
-	0x8C55,0x8C9D,0x8D64,0x8D70,0x8DB3,0x8EAB,0xF902,0x8F9B,/* 0xA8-0xAF */
-	0xF971,0x8FC2,0x8FC6,0x8FC5,0x8FC4,0x5DE1,0x9091,0x90A2,/* 0xB0-0xB7 */
-	0x90AA,0x90A6,0x90A3,0x9149,0x91C6,0xF9E9,0x9632,0xF9C6,/* 0xB8-0xBF */
+	0x0000,0x828B,0x828D,0x898B,0x89D2,0x8A00,0x8C37,0x8C46,/* 0xA0-0xA7 */
+	0x8C55,0x8C9D,0x8D64,0x8D70,0x8DB3,0x8EAB,0x8ECA,0x8F9B,/* 0xA8-0xAF */
+	0x8FB0,0x8FC2,0x8FC6,0x8FC5,0x8FC4,0x5DE1,0x9091,0x90A2,/* 0xB0-0xB7 */
+	0x90AA,0x90A6,0x90A3,0x9149,0x91C6,0x91CC,0x9632,0x962E,/* 0xB8-0xBF */
 	0x9631,0x962A,0x962C,0x4E26,0x4E56,0x4E73,0x4E8B,0x4E9B,/* 0xC0-0xC7 */
 	0x4E9E,0x4EAB,0x4EAC,0x4F6F,0x4F9D,0x4F8D,0x4F73,0x4F7F,/* 0xC8-0xCF */
-	0x4F6C,0x4F9B,0xF9B5,0xF92D,0x4F83,0x4F70,0x4F75,0x4F88,/* 0xD0-0xD7 */
+	0x4F6C,0x4F9B,0x4F8B,0x4F86,0x4F83,0x4F70,0x4F75,0x4F88,/* 0xD0-0xD7 */
 	0x4F69,0x4F7B,0x4F96,0x4F7E,0x4F8F,0x4F91,0x4F7A,0x5154,/* 0xD8-0xDF */
-	0x5152,0x5155,0xF978,0x5177,0x5176,0x5178,0x51BD,0x51FD,/* 0xE0-0xE7 */
-	0x523B,0x5238,0x5237,0xF9FF,0x5230,0x522E,0x5236,0x5241,/* 0xE8-0xEF */
+	0x5152,0x5155,0x5169,0x5177,0x5176,0x5178,0x51BD,0x51FD,/* 0xE0-0xE7 */
+	0x523B,0x5238,0x5237,0x523A,0x5230,0x522E,0x5236,0x5241,/* 0xE8-0xEF */
 	0x52BE,0x52BB,0x5352,0x5354,0x5353,0x5351,0x5366,0x5377,/* 0xF0-0xF7 */
 	0x5378,0x5379,0x53D6,0x53D4,0x53D7,0x5473,0x5475,0x0000,/* 0xF8-0xFF */
 };
@@ -314,11 +311,11 @@
 	0x5486,0x547C,0x5490,0x5471,0x5476,0x548C,0x549A,0x5462,/* 0x48-0x4F */
 	0x5468,0x548B,0x547D,0x548E,0x56FA,0x5783,0x5777,0x576A,/* 0x50-0x57 */
 	0x5769,0x5761,0x5766,0x5764,0x577C,0x591C,0x5949,0x5947,/* 0x58-0x5F */
-	0xF90C,0x5944,0x5954,0x59BE,0x59BB,0x59D4,0x59B9,0x59AE,/* 0x60-0x67 */
+	0x5948,0x5944,0x5954,0x59BE,0x59BB,0x59D4,0x59B9,0x59AE,/* 0x60-0x67 */
 	0x59D1,0x59C6,0x59D0,0x59CD,0x59CB,0x59D3,0x59CA,0x59AF,/* 0x68-0x6F */
 	0x59B3,0x59D2,0x59C5,0x5B5F,0x5B64,0x5B63,0x5B97,0x5B9A,/* 0x70-0x77 */
 	0x5B98,0x5B9C,0x5B99,0x5B9B,0x5C1A,0x5C48,0x5C45,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -327,13 +324,13 @@
 	0x5CB3,0x5E18,0x5E1A,0x5E16,0x5E15,0x5E1B,0x5E11,0x5E78,/* 0xA8-0xAF */
 	0x5E9A,0x5E97,0x5E9C,0x5E95,0x5E96,0x5EF6,0x5F26,0x5F27,/* 0xB0-0xB7 */
 	0x5F29,0x5F80,0x5F81,0x5F7F,0x5F7C,0x5FDD,0x5FE0,0x5FFD,/* 0xB8-0xBF */
-	0xF9A3,0x5FFF,0x600F,0x6014,0x602F,0x6035,0x6016,0x602A,/* 0xC0-0xC7 */
+	0x5FF5,0x5FFF,0x600F,0x6014,0x602F,0x6035,0x6016,0x602A,/* 0xC0-0xC7 */
 	0x6015,0x6021,0x6027,0x6029,0x602B,0x601B,0x6216,0x6215,/* 0xC8-0xCF */
-	0x623F,0x623E,0x6240,0x627F,0xF925,0x62CC,0x62C4,0x62BF,/* 0xD0-0xD7 */
-	0x62C2,0x62B9,0x62D2,0x62DB,0x62AB,0xFA02,0x62D4,0x62CB,/* 0xD8-0xDF */
+	0x623F,0x623E,0x6240,0x627F,0x62C9,0x62CC,0x62C4,0x62BF,/* 0xD0-0xD7 */
+	0x62C2,0x62B9,0x62D2,0x62DB,0x62AB,0x62D3,0x62D4,0x62CB,/* 0xD8-0xDF */
 	0x62C8,0x62A8,0x62BD,0x62BC,0x62D0,0x62D9,0x62C7,0x62CD,/* 0xE0-0xE7 */
 	0x62B5,0x62DA,0x62B1,0x62D8,0x62D6,0x62D7,0x62C6,0x62AC,/* 0xE8-0xEF */
-	0x62CE,0x653E,0x65A7,0x65BC,0x65FA,0x6614,0xF9E0,0x660C,/* 0xF0-0xF7 */
+	0x62CE,0x653E,0x65A7,0x65BC,0x65FA,0x6614,0x6613,0x660C,/* 0xF0-0xF7 */
 	0x6606,0x6602,0x660E,0x6600,0x660F,0x6615,0x660A,0x0000,/* 0xF8-0xFF */
 };
 
@@ -347,20 +344,20 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x30-0x37 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x38-0x3F */
 	0x6607,0x670D,0x670B,0x676D,0x678B,0x6795,0x6771,0x679C,/* 0x40-0x47 */
-	0x6773,0x6777,0x6787,0x679D,0xF9F4,0x676F,0x6770,0x677F,/* 0x48-0x4F */
+	0x6773,0x6777,0x6787,0x679D,0x6797,0x676F,0x6770,0x677F,/* 0x48-0x4F */
 	0x6789,0x677E,0x6790,0x6775,0x679A,0x6793,0x677C,0x676A,/* 0x50-0x57 */
 	0x6772,0x6B23,0x6B66,0x6B67,0x6B7F,0x6C13,0x6C1B,0x6CE3,/* 0x58-0x5F */
-	0x6CE8,0x6CF3,0x6CB1,0xF968,0xF9E3,0x6CB3,0x6CBD,0x6CBE,/* 0x60-0x67 */
+	0x6CE8,0x6CF3,0x6CB1,0x6CCC,0x6CE5,0x6CB3,0x6CBD,0x6CBE,/* 0x60-0x67 */
 	0x6CBC,0x6CE2,0x6CAB,0x6CD5,0x6CD3,0x6CB8,0x6CC4,0x6CB9,/* 0x68-0x6F */
 	0x6CC1,0x6CAE,0x6CD7,0x6CC5,0x6CF1,0x6CBF,0x6CBB,0x6CE1,/* 0x70-0x77 */
 	0x6CDB,0x6CCA,0x6CAC,0x6CEF,0x6CDC,0x6CD6,0x6CE0,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x98-0x9F */
-	0x0000,0x7095,0x708E,0x7092,0x708A,0xF9FB,0x722C,0x722D,/* 0xA0-0xA7 */
-	0x7238,0x7248,0x7267,0x7269,0xF9FA,0x72CE,0x72D9,0x72D7,/* 0xA8-0xAF */
+	0x0000,0x7095,0x708E,0x7092,0x708A,0x7099,0x722C,0x722D,/* 0xA0-0xA7 */
+	0x7238,0x7248,0x7267,0x7269,0x72C0,0x72CE,0x72D9,0x72D7,/* 0xA8-0xAF */
 	0x72D0,0x73A9,0x73A8,0x739F,0x73AB,0x73A5,0x753D,0x759D,/* 0xB0-0xB7 */
 	0x7599,0x759A,0x7684,0x76C2,0x76F2,0x76F4,0x77E5,0x77FD,/* 0xB8-0xBF */
 	0x793E,0x7940,0x7941,0x79C9,0x79C8,0x7A7A,0x7A79,0x7AFA,/* 0xC0-0xC7 */
@@ -369,7 +366,7 @@
 	0x81FE,0x820D,0x82B3,0x829D,0x8299,0x82AD,0x82BD,0x829F,/* 0xD8-0xDF */
 	0x82B9,0x82B1,0x82AC,0x82A5,0x82AF,0x82B8,0x82A3,0x82B0,/* 0xE0-0xE7 */
 	0x82BE,0x82B7,0x864E,0x8671,0x521D,0x8868,0x8ECB,0x8FCE,/* 0xE8-0xEF */
-	0x8FD4,0x8FD1,0x90B5,0x90B8,0x90B1,0x90B6,0x91C7,0xF90A,/* 0xF0-0xF7 */
+	0x8FD4,0x8FD1,0x90B5,0x90B8,0x90B1,0x90B6,0x91C7,0x91D1,/* 0xF0-0xF7 */
 	0x9577,0x9580,0x961C,0x9640,0x963F,0x963B,0x9644,0x0000,/* 0xF8-0xFF */
 };
 
@@ -382,28 +379,28 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x28-0x2F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x30-0x37 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x38-0x3F */
-	0x9642,0x96B9,0x96E8,0x9752,0x975E,0x4E9F,0x4EAD,0xF977,/* 0x40-0x47 */
-	0x4FE1,0x4FB5,0x4FAF,0xF965,0x4FE0,0x4FD1,0x4FCF,0x4FDD,/* 0x48-0x4F */
+	0x9642,0x96B9,0x96E8,0x9752,0x975E,0x4E9F,0x4EAD,0x4EAE,/* 0x40-0x47 */
+	0x4FE1,0x4FB5,0x4FAF,0x4FBF,0x4FE0,0x4FD1,0x4FCF,0x4FDD,/* 0x48-0x4F */
 	0x4FC3,0x4FB6,0x4FD8,0x4FDF,0x4FCA,0x4FD7,0x4FAE,0x4FD0,/* 0x50-0x57 */
 	0x4FC4,0x4FC2,0x4FDA,0x4FCE,0x4FDE,0x4FB7,0x5157,0x5192,/* 0x58-0x5F */
 	0x5191,0x51A0,0x524E,0x5243,0x524A,0x524D,0x524C,0x524B,/* 0x60-0x67 */
 	0x5247,0x52C7,0x52C9,0x52C3,0x52C1,0x530D,0x5357,0x537B,/* 0x68-0x6F */
 	0x539A,0x53DB,0x54AC,0x54C0,0x54A8,0x54CE,0x54C9,0x54B8,/* 0x70-0x77 */
-	0x54A6,0x54B3,0x54C7,0x54C2,0xF99E,0x54AA,0x54C1,0x0000,/* 0x78-0x7F */
-	
+	0x54A6,0x54B3,0x54C7,0x54C2,0x54BD,0x54AA,0x54C1,0x0000,/* 0x78-0x7F */
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x98-0x9F */
 	0x0000,0x54C4,0x54C8,0x54AF,0x54AB,0x54B1,0x54BB,0x54A9,/* 0xA0-0xA7 */
 	0x54A7,0x54BF,0x56FF,0x5782,0x578B,0x57A0,0x57A3,0x57A2,/* 0xA8-0xAF */
-	0x57CE,0x57AE,0x5793,0x5955,0xF909,0x594F,0x594E,0x5950,/* 0xB0-0xB7 */
+	0x57CE,0x57AE,0x5793,0x5955,0x5951,0x594F,0x594E,0x5950,/* 0xB0-0xB7 */
 	0x59DC,0x59D8,0x59FF,0x59E3,0x59E8,0x5A03,0x59E5,0x59EA,/* 0xB8-0xBF */
 	0x59DA,0x59E6,0x5A01,0x59FB,0x5B69,0x5BA3,0x5BA6,0x5BA4,/* 0xC0-0xC7 */
 	0x5BA2,0x5BA5,0x5C01,0x5C4E,0x5C4F,0x5C4D,0x5C4B,0x5CD9,/* 0xC8-0xCF */
-	0x5CD2,0x5DF7,0x5E1D,0x5E25,0x5E1F,0x5E7D,0x5EA0,0xFA01,/* 0xD0-0xD7 */
-	0x5EFA,0x5F08,0x5F2D,0x5F65,0x5F88,0x5F85,0x5F8A,0xF9D8,/* 0xD8-0xDF */
-	0x5F87,0x5F8C,0x5F89,0xF960,0x601D,0x6020,0x6025,0x600E,/* 0xE0-0xE7 */
+	0x5CD2,0x5DF7,0x5E1D,0x5E25,0x5E1F,0x5E7D,0x5EA0,0x5EA6,/* 0xD0-0xD7 */
+	0x5EFA,0x5F08,0x5F2D,0x5F65,0x5F88,0x5F85,0x5F8A,0x5F8B,/* 0xD8-0xDF */
+	0x5F87,0x5F8C,0x5F89,0x6012,0x601D,0x6020,0x6025,0x600E,/* 0xE0-0xE7 */
 	0x6028,0x604D,0x6070,0x6068,0x6062,0x6046,0x6043,0x606C,/* 0xE8-0xEF */
 	0x606B,0x606A,0x6064,0x6241,0x62DC,0x6316,0x6309,0x62FC,/* 0xF0-0xF7 */
 	0x62ED,0x6301,0x62EE,0x62FD,0x6307,0x62F1,0x62F7,0x0000,/* 0xF8-0xFF */
@@ -418,27 +415,27 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x28-0x2F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x30-0x37 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x38-0x3F */
-	0x62EF,0x62EC,0xF973,0x62F4,0x6311,0x6302,0x653F,0x6545,/* 0x40-0x47 */
+	0x62EF,0x62EC,0x62FE,0x62F4,0x6311,0x6302,0x653F,0x6545,/* 0x40-0x47 */
 	0x65AB,0x65BD,0x65E2,0x6625,0x662D,0x6620,0x6627,0x662F,/* 0x48-0x4F */
 	0x661F,0x6628,0x6631,0x6624,0x66F7,0x67FF,0x67D3,0x67F1,/* 0x50-0x57 */
 	0x67D4,0x67D0,0x67EC,0x67B6,0x67AF,0x67F5,0x67E9,0x67EF,/* 0x58-0x5F */
 	0x67C4,0x67D1,0x67B4,0x67DA,0x67E5,0x67B8,0x67CF,0x67DE,/* 0x60-0x67 */
-	0xF9C9,0x67B0,0x67D9,0x67E2,0x67DD,0x67D2,0x6B6A,0x6B83,/* 0x68-0x6F */
+	0x67F3,0x67B0,0x67D9,0x67E2,0x67DD,0x67D2,0x6B6A,0x6B83,/* 0x68-0x6F */
 	0x6B86,0x6BB5,0x6BD2,0x6BD7,0x6C1F,0x6CC9,0x6D0B,0x6D32,/* 0x70-0x77 */
-	0x6D2A,0xF9CA,0x6D25,0x6D0C,0x6D31,0xFA05,0x6D17,0x0000,/* 0x78-0x7F */
-	
+	0x6D2A,0x6D41,0x6D25,0x6D0C,0x6D31,0x6D1E,0x6D17,0x0000,/* 0x78-0x7F */
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x98-0x9F */
-	0x0000,0x6D3B,0x6D3D,0x6D3E,0x6D36,0xF915,0x6CF5,0x6D39,/* 0xA0-0xA7 */
+	0x0000,0x6D3B,0x6D3D,0x6D3E,0x6D36,0x6D1B,0x6CF5,0x6D39,/* 0xA0-0xA7 */
 	0x6D27,0x6D38,0x6D29,0x6D2E,0x6D35,0x6D0E,0x6D2B,0x70AB,/* 0xA8-0xAF */
 	0x70BA,0x70B3,0x70AC,0x70AF,0x70AD,0x70B8,0x70AE,0x70A4,/* 0xB0-0xB7 */
 	0x7230,0x7272,0x726F,0x7274,0x72E9,0x72E0,0x72E1,0x73B7,/* 0xB8-0xBF */
-	0x73CA,0x73BB,0xF9AD,0x73CD,0x73C0,0x73B3,0x751A,0x752D,/* 0xC0-0xC7 */
+	0x73CA,0x73BB,0x73B2,0x73CD,0x73C0,0x73B3,0x751A,0x752D,/* 0xC0-0xC7 */
 	0x754F,0x754C,0x754E,0x754B,0x75AB,0x75A4,0x75A5,0x75A2,/* 0xC8-0xCF */
 	0x75A3,0x7678,0x7686,0x7687,0x7688,0x76C8,0x76C6,0x76C3,/* 0xD0-0xD7 */
-	0x76C5,0xF96D,0x76F9,0x76F8,0x7709,0x770B,0x76FE,0x76FC,/* 0xD8-0xDF */
+	0x76C5,0x7701,0x76F9,0x76F8,0x7709,0x770B,0x76FE,0x76FC,/* 0xD8-0xDF */
 	0x7707,0x77DC,0x7802,0x7814,0x780C,0x780D,0x7946,0x7949,/* 0xE0-0xE7 */
 	0x7948,0x7947,0x79B9,0x79BA,0x79D1,0x79D2,0x79CB,0x7A7F,/* 0xE8-0xEF */
 	0x7A81,0x7AFF,0x7AFD,0x7C7D,0x7D02,0x7D05,0x7D00,0x7D09,/* 0xF0-0xF7 */
@@ -457,25 +454,25 @@
 	0x8010,0x800D,0x8011,0x8036,0x80D6,0x80E5,0x80DA,0x80C3,/* 0x40-0x47 */
 	0x80C4,0x80CC,0x80E1,0x80DB,0x80CE,0x80DE,0x80E4,0x80DD,/* 0x48-0x4F */
 	0x81F4,0x8222,0x82E7,0x8303,0x8305,0x82E3,0x82DB,0x82E6,/* 0x50-0x57 */
-	0x8304,0xF974,0x8302,0x8309,0x82D2,0x82D7,0x82F1,0x8301,/* 0x58-0x5F */
+	0x8304,0x82E5,0x8302,0x8309,0x82D2,0x82D7,0x82F1,0x8301,/* 0x58-0x5F */
 	0x82DC,0x82D4,0x82D1,0x82DE,0x82D3,0x82DF,0x82EF,0x8306,/* 0x60-0x67 */
 	0x8650,0x8679,0x867B,0x867A,0x884D,0x886B,0x8981,0x89D4,/* 0x68-0x6F */
 	0x8A08,0x8A02,0x8A03,0x8C9E,0x8CA0,0x8D74,0x8D73,0x8DB4,/* 0x70-0x77 */
 	0x8ECD,0x8ECC,0x8FF0,0x8FE6,0x8FE2,0x8FEA,0x8FE5,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x98-0x9F */
 	0x0000,0x8FED,0x8FEB,0x8FE4,0x8FE8,0x90CA,0x90CE,0x90C1,/* 0xA0-0xA7 */
-	0x90C3,0x914B,0x914A,0x91CD,0x9582,0x9650,0xF951,0x964C,/* 0xA8-0xAF */
-	0xFA09,0x9762,0x9769,0x97CB,0x97ED,0x97F3,0x9801,0x98A8,/* 0xB0-0xB7 */
+	0x90C3,0x914B,0x914A,0x91CD,0x9582,0x9650,0x964B,0x964C,/* 0xA8-0xAF */
+	0x964D,0x9762,0x9769,0x97CB,0x97ED,0x97F3,0x9801,0x98A8,/* 0xB0-0xB7 */
 	0x98DB,0x98DF,0x9996,0x9999,0x4E58,0x4EB3,0x500C,0x500D,/* 0xB8-0xBF */
 	0x5023,0x4FEF,0x5026,0x5025,0x4FF8,0x5029,0x5016,0x5006,/* 0xC0-0xC7 */
 	0x503C,0x501F,0x501A,0x5012,0x5011,0x4FFA,0x5000,0x5014,/* 0xC8-0xCF */
 	0x5028,0x4FF1,0x5021,0x500B,0x5019,0x5018,0x4FF3,0x4FEE,/* 0xD0-0xD7 */
-	0x502D,0x502A,0x4FFE,0xF9D4,0x5009,0x517C,0x51A4,0x51A5,/* 0xD8-0xDF */
-	0x51A2,0x51CD,0xF955,0x51C6,0x51CB,0x5256,0x525C,0x5254,/* 0xE0-0xE7 */
+	0x502D,0x502A,0x4FFE,0x502B,0x5009,0x517C,0x51A4,0x51A5,/* 0xD8-0xDF */
+	0x51A2,0x51CD,0x51CC,0x51C6,0x51CB,0x5256,0x525C,0x5254,/* 0xE0-0xE7 */
 	0x525B,0x525D,0x532A,0x537F,0x539F,0x539D,0x53DF,0x54E8,/* 0xE8-0xEF */
 	0x5510,0x5501,0x5537,0x54FC,0x54E5,0x54F2,0x5506,0x54FA,/* 0xF0-0xF7 */
 	0x5514,0x54E9,0x54ED,0x54E1,0x5509,0x54EE,0x54EA,0x0000,/* 0xF8-0xFF */
@@ -498,7 +495,7 @@
 	0x5C51,0x5C55,0x5C50,0x5CED,0x5CFD,0x5CFB,0x5CEA,0x5CE8,/* 0x68-0x6F */
 	0x5CF0,0x5CF6,0x5D01,0x5CF4,0x5DEE,0x5E2D,0x5E2B,0x5EAB,/* 0x70-0x77 */
 	0x5EAD,0x5EA7,0x5F31,0x5F92,0x5F91,0x5F90,0x6059,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -507,13 +504,13 @@
 	0x6084,0x609F,0x609A,0x608D,0x6094,0x608C,0x6085,0x6096,/* 0xA8-0xAF */
 	0x6247,0x62F3,0x6308,0x62FF,0x634E,0x633E,0x632F,0x6355,/* 0xB0-0xB7 */
 	0x6342,0x6346,0x634F,0x6349,0x633A,0x6350,0x633D,0x632A,/* 0xB8-0xBF */
-	0x632B,0x6328,0x634D,0x634C,0x6548,0x6549,0xF9BE,0x65C1,/* 0xC0-0xC7 */
-	0xF983,0x6642,0x6649,0x664F,0x6643,0x6652,0x664C,0x6645,/* 0xC8-0xCF */
-	0x6641,0x66F8,0x6714,0x6715,0xF929,0x6821,0x6838,0x6848,/* 0xD0-0xD7 */
-	0x6846,0x6853,0x6839,0x6842,0x6854,0x6829,0x68B3,0xF9DA,/* 0xD8-0xDF */
+	0x632B,0x6328,0x634D,0x634C,0x6548,0x6549,0x6599,0x65C1,/* 0xC0-0xC7 */
+	0x65C5,0x6642,0x6649,0x664F,0x6643,0x6652,0x664C,0x6645,/* 0xC8-0xCF */
+	0x6641,0x66F8,0x6714,0x6715,0x6717,0x6821,0x6838,0x6848,/* 0xD0-0xD7 */
+	0x6846,0x6853,0x6839,0x6842,0x6854,0x6829,0x68B3,0x6817,/* 0xD8-0xDF */
 	0x684C,0x6851,0x683D,0x67F4,0x6850,0x6840,0x683C,0x6843,/* 0xE0-0xE7 */
 	0x682A,0x6845,0x6813,0x6818,0x6841,0x6B8A,0x6B89,0x6BB7,/* 0xE8-0xEF */
-	0x6C23,0x6C27,0x6C28,0x6C26,0x6C24,0x6CF0,0xF92A,0x6D95,/* 0xF0-0xF7 */
+	0x6C23,0x6C27,0x6C28,0x6C26,0x6C24,0x6CF0,0x6D6A,0x6D95,/* 0xF0-0xF7 */
 	0x6D88,0x6D87,0x6D66,0x6D78,0x6D77,0x6D59,0x6D93,0x0000,/* 0xF8-0xFF */
 };
 
@@ -527,30 +524,30 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x30-0x37 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x38-0x3F */
 	0x6D6C,0x6D89,0x6D6E,0x6D5A,0x6D74,0x6D69,0x6D8C,0x6D8A,/* 0x40-0x47 */
-	0x6D79,0x6D85,0x6D65,0x6D94,0x70CA,0x70D8,0x70E4,0xF916,/* 0x48-0x4F */
-	0xF99F,0x70CF,0x7239,0x7279,0xF92B,0x72F9,0x72FD,0x72F8,/* 0x50-0x57 */
-	0x72F7,0x7386,0x73ED,0xF9CC,0x73EE,0x73E0,0x73EA,0xF917,/* 0x58-0x5F */
-	0x7554,0x755D,0x755C,0x755A,0xF9CD,0x75BE,0x75C5,0x75C7,/* 0x60-0x67 */
+	0x6D79,0x6D85,0x6D65,0x6D94,0x70CA,0x70D8,0x70E4,0x70D9,/* 0x48-0x4F */
+	0x70C8,0x70CF,0x7239,0x7279,0x72FC,0x72F9,0x72FD,0x72F8,/* 0x50-0x57 */
+	0x72F7,0x7386,0x73ED,0x7409,0x73EE,0x73E0,0x73EA,0x73DE,/* 0x58-0x5F */
+	0x7554,0x755D,0x755C,0x755A,0x7559,0x75BE,0x75C5,0x75C7,/* 0x60-0x67 */
 	0x75B2,0x75B3,0x75BD,0x75BC,0x75B9,0x75C2,0x75B8,0x768B,/* 0x68-0x6F */
-	0x76B0,0xFA17,0x76CD,0x76CE,0x7729,0x771F,0x7720,0x7728,/* 0x70-0x77 */
+	0x76B0,0x76CA,0x76CD,0x76CE,0x7729,0x771F,0x7720,0x7728,/* 0x70-0x77 */
 	0x77E9,0x7830,0x7827,0x7838,0x781D,0x7834,0x7837,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x98-0x9F */
 	0x0000,0x7825,0x782D,0x7820,0x781F,0x7832,0x7955,0x7950,/* 0xA0-0xA7 */
-	0x7960,0x795F,0x7956,0xFA19,0x795D,0x7957,0x795A,0x79E4,/* 0xA8-0xAF */
+	0x7960,0x795F,0x7956,0x795E,0x795D,0x7957,0x795A,0x79E4,/* 0xA8-0xAF */
 	0x79E3,0x79E7,0x79DF,0x79E6,0x79E9,0x79D8,0x7A84,0x7A88,/* 0xB0-0xB7 */
 	0x7AD9,0x7B06,0x7B11,0x7C89,0x7D21,0x7D17,0x7D0B,0x7D0A,/* 0xB8-0xBF */
-	0x7D20,0xF96A,0x7D14,0xF9CF,0x7D15,0x7D1A,0x7D1C,0x7D0D,/* 0xC0-0xC7 */
+	0x7D20,0x7D22,0x7D14,0x7D10,0x7D15,0x7D1A,0x7D1C,0x7D0D,/* 0xC0-0xC7 */
 	0x7D19,0x7D1B,0x7F3A,0x7F5F,0x7F94,0x7FC5,0x7FC1,0x8006,/* 0xC8-0xCF */
 	0x8018,0x8015,0x8019,0x8017,0x803D,0x803F,0x80F1,0x8102,/* 0xD0-0xD7 */
 	0x80F0,0x8105,0x80ED,0x80F4,0x8106,0x80F8,0x80F3,0x8108,/* 0xD8-0xDF */
 	0x80FD,0x810A,0x80FC,0x80EF,0x81ED,0x81EC,0x8200,0x8210,/* 0xE0-0xE7 */
 	0x822A,0x822B,0x8228,0x822C,0x82BB,0x832B,0x8352,0x8354,/* 0xE8-0xEF */
 	0x834A,0x8338,0x8350,0x8349,0x8335,0x8334,0x834F,0x8332,/* 0xF0-0xF7 */
-	0x8339,0xF9FE,0x8317,0x8340,0x8331,0x8328,0x8343,0x0000,/* 0xF8-0xFF */
+	0x8339,0x8336,0x8317,0x8340,0x8331,0x8328,0x8343,0x0000,/* 0xF8-0xFF */
 };
 
 static wchar_t c2u_B0[256] = {
@@ -565,12 +562,12 @@
 	0x8654,0x868A,0x86AA,0x8693,0x86A4,0x86A9,0x868C,0x86A3,/* 0x40-0x47 */
 	0x869C,0x8870,0x8877,0x8881,0x8882,0x887D,0x8879,0x8A18,/* 0x48-0x4F */
 	0x8A10,0x8A0E,0x8A0C,0x8A15,0x8A0A,0x8A17,0x8A13,0x8A16,/* 0x50-0x57 */
-	0x8A0F,0x8A11,0xF900,0x8C7A,0x8C79,0x8CA1,0x8CA2,0x8D77,/* 0x58-0x5F */
+	0x8A0F,0x8A11,0x8C48,0x8C7A,0x8C79,0x8CA1,0x8CA2,0x8D77,/* 0x58-0x5F */
 	0x8EAC,0x8ED2,0x8ED4,0x8ECF,0x8FB1,0x9001,0x9006,0x8FF7,/* 0x60-0x67 */
 	0x9000,0x8FFA,0x8FF4,0x9003,0x8FFD,0x9005,0x8FF8,0x9095,/* 0x68-0x6F */
 	0x90E1,0x90DD,0x90E2,0x9152,0x914D,0x914C,0x91D8,0x91DD,/* 0x70-0x77 */
 	0x91D7,0x91DC,0x91D9,0x9583,0x9662,0x9663,0x9661,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -579,9 +576,9 @@
 	0x99AC,0x9AA8,0x9AD8,0x9B25,0x9B32,0x9B3C,0x4E7E,0x507A,/* 0xA8-0xAF */
 	0x507D,0x505C,0x5047,0x5043,0x504C,0x505A,0x5049,0x5065,/* 0xB0-0xB7 */
 	0x5076,0x504E,0x5055,0x5075,0x5074,0x5077,0x504F,0x500F,/* 0xB8-0xBF */
-	0x506F,0x506D,0x515C,0x5195,0x51F0,0x526A,0x526F,0xF952,/* 0xC0-0xC7 */
-	0x52D9,0x52D8,0x52D5,0x5310,0x530F,0x5319,0xF9EB,0x5340,/* 0xC8-0xCF */
-	0x533E,0xF96B,0x66FC,0x5546,0x556A,0x5566,0x5544,0x555E,/* 0xD0-0xD7 */
+	0x506F,0x506D,0x515C,0x5195,0x51F0,0x526A,0x526F,0x52D2,/* 0xC0-0xC7 */
+	0x52D9,0x52D8,0x52D5,0x5310,0x530F,0x5319,0x533F,0x5340,/* 0xC8-0xCF */
+	0x533E,0x53C3,0x66FC,0x5546,0x556A,0x5566,0x5544,0x555E,/* 0xD0-0xD7 */
 	0x5561,0x5543,0x554A,0x5531,0x5556,0x554F,0x5555,0x552F,/* 0xD8-0xDF */
 	0x5564,0x5538,0x552E,0x555C,0x552C,0x5563,0x5533,0x5541,/* 0xE0-0xE7 */
 	0x5557,0x5708,0x570B,0x5709,0x57DF,0x5805,0x580A,0x5806,/* 0xE8-0xEF */
@@ -601,28 +598,28 @@
 	0x5A3C,0x5A62,0x5A5A,0x5A46,0x5A4A,0x5B70,0x5BC7,0x5BC5,/* 0x40-0x47 */
 	0x5BC4,0x5BC2,0x5BBF,0x5BC6,0x5C09,0x5C08,0x5C07,0x5C60,/* 0x48-0x4F */
 	0x5C5C,0x5C5D,0x5D07,0x5D06,0x5D0E,0x5D1B,0x5D16,0x5D22,/* 0x50-0x57 */
-	0x5D11,0x5D29,0x5D14,0xF9D5,0x5D24,0x5D27,0x5D17,0x5DE2,/* 0x58-0x5F */
+	0x5D11,0x5D29,0x5D14,0x5D19,0x5D24,0x5D27,0x5D17,0x5DE2,/* 0x58-0x5F */
 	0x5E38,0x5E36,0x5E33,0x5E37,0x5EB7,0x5EB8,0x5EB6,0x5EB5,/* 0x60-0x67 */
 	0x5EBE,0x5F35,0x5F37,0x5F57,0x5F6C,0x5F69,0x5F6B,0x5F97,/* 0x68-0x6F */
 	0x5F99,0x5F9E,0x5F98,0x5FA1,0x5FA0,0x5F9C,0x607F,0x60A3,/* 0x70-0x77 */
 	0x6089,0x60A0,0x60A8,0x60CB,0x60B4,0x60E6,0x60BD,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x98-0x9F */
 	0x0000,0x60C5,0x60BB,0x60B5,0x60DC,0x60BC,0x60D8,0x60D5,/* 0xA0-0xA7 */
 	0x60C6,0x60DF,0x60B8,0x60DA,0x60C7,0x621A,0x621B,0x6248,/* 0xA8-0xAF */
-	0xF975,0x63A7,0x6372,0x6396,0x63A2,0x63A5,0x6377,0x6367,/* 0xB0-0xB7 */
+	0x63A0,0x63A7,0x6372,0x6396,0x63A2,0x63A5,0x6377,0x6367,/* 0xB0-0xB7 */
 	0x6398,0x63AA,0x6371,0x63A9,0x6389,0x6383,0x639B,0x636B,/* 0xB8-0xBF */
 	0x63A8,0x6384,0x6388,0x6399,0x63A1,0x63AC,0x6392,0x638F,/* 0xC0-0xC7 */
-	0x6380,0xF9A4,0x6369,0x6368,0x637A,0x655D,0x6556,0x6551,/* 0xC8-0xCF */
+	0x6380,0x637B,0x6369,0x6368,0x637A,0x655D,0x6556,0x6551,/* 0xC8-0xCF */
 	0x6559,0x6557,0x555F,0x654F,0x6558,0x6555,0x6554,0x659C,/* 0xD0-0xD7 */
 	0x659B,0x65AC,0x65CF,0x65CB,0x65CC,0x65CE,0x665D,0x665A,/* 0xD8-0xDF */
-	0x6664,0x6668,0x6666,0x665E,0x66F9,0x52D7,0x671B,0xF97A,/* 0xE0-0xE7 */
+	0x6664,0x6668,0x6666,0x665E,0x66F9,0x52D7,0x671B,0x6881,/* 0xE0-0xE7 */
 	0x68AF,0x68A2,0x6893,0x68B5,0x687F,0x6876,0x68B1,0x68A7,/* 0xE8-0xEF */
 	0x6897,0x68B0,0x6883,0x68C4,0x68AD,0x6886,0x6885,0x6894,/* 0xF0-0xF7 */
-	0x689D,0xF9E2,0x689F,0x68A1,0x6882,0x6B32,0xF970,0x0000,/* 0xF8-0xFF */
+	0x689D,0x68A8,0x689F,0x68A1,0x6882,0x6B32,0x6BBA,0x0000,/* 0xF8-0xFF */
 };
 
 static wchar_t c2u_B2[256] = {
@@ -635,27 +632,27 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x30-0x37 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x38-0x3F */
 	0x6BEB,0x6BEC,0x6C2B,0x6D8E,0x6DBC,0x6DF3,0x6DD9,0x6DB2,/* 0x40-0x47 */
-	0x6DE1,0x6DCC,0x6DE4,0x6DFB,0x6DFA,0x6E05,0x6DC7,0xF9F5,/* 0x48-0x4F */
+	0x6DE1,0x6DCC,0x6DE4,0x6DFB,0x6DFA,0x6E05,0x6DC7,0x6DCB,/* 0x48-0x4F */
 	0x6DAF,0x6DD1,0x6DAE,0x6DDE,0x6DF9,0x6DB8,0x6DF7,0x6DF5,/* 0x50-0x57 */
-	0x6DC5,0x6DD2,0x6E1A,0x6DB5,0xF94D,0x6DEB,0x6DD8,0xF9D6,/* 0x58-0x5F */
+	0x6DC5,0x6DD2,0x6E1A,0x6DB5,0x6DDA,0x6DEB,0x6DD8,0x6DEA,/* 0x58-0x5F */
 	0x6DF1,0x6DEE,0x6DE8,0x6DC6,0x6DC4,0x6DAA,0x6DEC,0x6DBF,/* 0x60-0x67 */
 	0x6DE6,0x70F9,0x7109,0x710A,0x70FD,0x70EF,0x723D,0x727D,/* 0x68-0x6F */
-	0x7281,0x731C,0x731B,0x7316,0x7313,0x7319,0xF9DB,0x7405,/* 0x70-0x77 */
-	0x740A,0x7403,0xF9E4,0x73FE,0x740D,0x74E0,0x74F6,0x0000,/* 0x78-0x7F */
-	
+	0x7281,0x731C,0x731B,0x7316,0x7313,0x7319,0x7387,0x7405,/* 0x70-0x77 */
+	0x740A,0x7403,0x7406,0x73FE,0x740D,0x74E0,0x74F6,0x0000,/* 0x78-0x7F */
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x98-0x9F */
-	0x0000,0x74F7,0x751C,0x7522,0xF976,0x7566,0x7562,0xF962,/* 0xA0-0xA7 */
+	0x0000,0x74F7,0x751C,0x7522,0x7565,0x7566,0x7562,0x7570,/* 0xA0-0xA7 */
 	0x758F,0x75D4,0x75D5,0x75B5,0x75CA,0x75CD,0x768E,0x76D4,/* 0xA8-0xAF */
 	0x76D2,0x76DB,0x7737,0x773E,0x773C,0x7736,0x7738,0x773A,/* 0xB0-0xB7 */
-	0xF9CE,0x7843,0x784E,0xFA1A,0x7968,0x796D,0x79FB,0x7A92,/* 0xB8-0xBF */
-	0x7A95,0xF9F8,0x7B28,0x7B1B,0x7B2C,0x7B26,0x7B19,0x7B1E,/* 0xC0-0xC7 */
-	0x7B2E,0xF9F9,0x7C97,0x7C95,0x7D46,0x7D43,0x7D71,0x7D2E,/* 0xC8-0xCF */
-	0x7D39,0x7D3C,0x7D40,0x7D30,0x7D33,0x7D44,0xF94F,0x7D42,/* 0xD0-0xD7 */
-	0x7D32,0x7D31,0x7F3D,0x7F9E,0xF9AF,0x7FCC,0x7FCE,0x7FD2,/* 0xD8-0xDF */
-	0x801C,0x804A,0xF9B0,0x812F,0x8116,0x8123,0x812B,0x8129,/* 0xE0-0xE7 */
+	0x786B,0x7843,0x784E,0x7965,0x7968,0x796D,0x79FB,0x7A92,/* 0xB8-0xBF */
+	0x7A95,0x7B20,0x7B28,0x7B1B,0x7B2C,0x7B26,0x7B19,0x7B1E,/* 0xC0-0xC7 */
+	0x7B2E,0x7C92,0x7C97,0x7C95,0x7D46,0x7D43,0x7D71,0x7D2E,/* 0xC8-0xCF */
+	0x7D39,0x7D3C,0x7D40,0x7D30,0x7D33,0x7D44,0x7D2F,0x7D42,/* 0xD0-0xD7 */
+	0x7D32,0x7D31,0x7F3D,0x7F9E,0x7F9A,0x7FCC,0x7FCE,0x7FD2,/* 0xD8-0xDF */
+	0x801C,0x804A,0x8046,0x812F,0x8116,0x8123,0x812B,0x8129,/* 0xE0-0xE7 */
 	0x8130,0x8124,0x8202,0x8235,0x8237,0x8236,0x8239,0x838E,/* 0xE8-0xEF */
 	0x839E,0x8398,0x8378,0x83A2,0x8396,0x83BD,0x83AB,0x8392,/* 0xF0-0xF7 */
 	0x838A,0x8393,0x8389,0x83A0,0x8377,0x837B,0x837C,0x0000,/* 0xF8-0xFF */
@@ -676,22 +673,22 @@
 	0x8A2A,0x8A1D,0x8A23,0x8A25,0x8A31,0x8A2D,0x8A1F,0x8A1B,/* 0x58-0x5F */
 	0x8A22,0x8C49,0x8C5A,0x8CA9,0x8CAC,0x8CAB,0x8CA8,0x8CAA,/* 0x60-0x67 */
 	0x8CA7,0x8D67,0x8D66,0x8DBE,0x8DBA,0x8EDB,0x8EDF,0x9019,/* 0x68-0x6F */
-	0x900D,0x901A,0x9017,0xF99A,0x901F,0x901D,0x9010,0x9015,/* 0x70-0x77 */
+	0x900D,0x901A,0x9017,0x9023,0x901F,0x901D,0x9010,0x9015,/* 0x70-0x77 */
 	0x901E,0x9020,0x900F,0x9022,0x9016,0x901B,0x9014,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x98-0x9F */
-	0x0000,0x90E8,0x90ED,0xFA26,0x9157,0x91CE,0x91F5,0x91E6,/* 0xA0-0xA7 */
-	0x91E3,0x91E7,0x91ED,0x91E9,0x9589,0x966A,0xF959,0x9673,/* 0xA8-0xAF */
-	0xF9D3,0x9670,0x9674,0x9676,0x9677,0x966C,0x96C0,0x96EA,/* 0xB0-0xB7 */
+	0x0000,0x90E8,0x90ED,0x90FD,0x9157,0x91CE,0x91F5,0x91E6,/* 0xA0-0xA7 */
+	0x91E3,0x91E7,0x91ED,0x91E9,0x9589,0x966A,0x9675,0x9673,/* 0xA8-0xAF */
+	0x9678,0x9670,0x9674,0x9676,0x9677,0x966C,0x96C0,0x96EA,/* 0xB0-0xB7 */
 	0x96E9,0x7AE0,0x7ADF,0x9802,0x9803,0x9B5A,0x9CE5,0x9E75,/* 0xB8-0xBF */
-	0xF940,0x9EA5,0x9EBB,0x50A2,0x508D,0x5085,0x5099,0x5091,/* 0xC0-0xC7 */
+	0x9E7F,0x9EA5,0x9EBB,0x50A2,0x508D,0x5085,0x5099,0x5091,/* 0xC0-0xC7 */
 	0x5080,0x5096,0x5098,0x509A,0x6700,0x51F1,0x5272,0x5274,/* 0xC8-0xCF */
-	0x5275,0x5269,0xF92F,0x52DD,0x52DB,0x535A,0x53A5,0x557B,/* 0xD0-0xD7 */
+	0x5275,0x5269,0x52DE,0x52DD,0x52DB,0x535A,0x53A5,0x557B,/* 0xD0-0xD7 */
 	0x5580,0x55A7,0x557C,0x558A,0x559D,0x5598,0x5582,0x559C,/* 0xD8-0xDF */
-	0x55AA,0x5594,0xF90B,0x558B,0x5583,0x55B3,0x55AE,0x559F,/* 0xE0-0xE7 */
+	0x55AA,0x5594,0x5587,0x558B,0x5583,0x55B3,0x55AE,0x559F,/* 0xE0-0xE7 */
 	0x553E,0x55B2,0x559A,0x55BB,0x55AC,0x55B1,0x557E,0x5589,/* 0xE8-0xEF */
 	0x55AB,0x5599,0x570D,0x582F,0x582A,0x5834,0x5824,0x5830,/* 0xF0-0xF7 */
 	0x5831,0x5821,0x581D,0x5820,0x58F9,0x58FA,0x5960,0x0000,/* 0xF8-0xFF */
@@ -708,13 +705,13 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x38-0x3F */
 	0x5A77,0x5A9A,0x5A7F,0x5A92,0x5A9B,0x5AA7,0x5B73,0x5B71,/* 0x40-0x47 */
 	0x5BD2,0x5BCC,0x5BD3,0x5BD0,0x5C0A,0x5C0B,0x5C31,0x5D4C,/* 0x48-0x4F */
-	0xF921,0x5D34,0x5D47,0x5DFD,0x5E45,0x5E3D,0x5E40,0x5E43,/* 0x50-0x57 */
-	0x5E7E,0xF928,0x5EC1,0x5EC2,0x5EC4,0x5F3C,0x5F6D,0xF966,/* 0x58-0x5F */
-	0x5FAA,0x5FA8,0x60D1,0xF9B9,0x60B2,0x60B6,0x60E0,0x611C,/* 0x60-0x67 */
+	0x5D50,0x5D34,0x5D47,0x5DFD,0x5E45,0x5E3D,0x5E40,0x5E43,/* 0x50-0x57 */
+	0x5E7E,0x5ECA,0x5EC1,0x5EC2,0x5EC4,0x5F3C,0x5F6D,0x5FA9,/* 0x58-0x5F */
+	0x5FAA,0x5FA8,0x60D1,0x60E1,0x60B2,0x60B6,0x60E0,0x611C,/* 0x60-0x67 */
 	0x6123,0x60FA,0x6115,0x60F0,0x60FB,0x60F4,0x6168,0x60F1,/* 0x68-0x6F */
 	0x610E,0x60F6,0x6109,0x6100,0x6112,0x621F,0x6249,0x63A3,/* 0x70-0x77 */
 	0x638C,0x63CF,0x63C0,0x63E9,0x63C9,0x63C6,0x63CD,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -722,7 +719,7 @@
 	0x0000,0x63D2,0x63E3,0x63D0,0x63E1,0x63D6,0x63ED,0x63EE,/* 0xA0-0xA7 */
 	0x6376,0x63F4,0x63EA,0x63DB,0x6452,0x63DA,0x63F9,0x655E,/* 0xA8-0xAF */
 	0x6566,0x6562,0x6563,0x6591,0x6590,0x65AF,0x666E,0x6670,/* 0xB0-0xB7 */
-	0xFA12,0x6676,0x666F,0x6691,0x667A,0x667E,0x6677,0x66FE,/* 0xB8-0xBF */
+	0x6674,0x6676,0x666F,0x6691,0x667A,0x667E,0x6677,0x66FE,/* 0xB8-0xBF */
 	0x66FF,0x671F,0x671D,0x68FA,0x68D5,0x68E0,0x68D8,0x68D7,/* 0xC0-0xC7 */
 	0x6905,0x68DF,0x68F5,0x68EE,0x68E7,0x68F9,0x68D2,0x68F2,/* 0xC8-0xCF */
 	0x68E3,0x68CB,0x68CD,0x690D,0x6912,0x690E,0x68C9,0x68DA,/* 0xD0-0xD7 */
@@ -746,11 +743,11 @@
 	0x7119,0x711A,0x7126,0x7130,0x7121,0x7136,0x716E,0x711C,/* 0x48-0x4F */
 	0x724C,0x7284,0x7280,0x7336,0x7325,0x7334,0x7329,0x743A,/* 0x50-0x57 */
 	0x742A,0x7433,0x7422,0x7425,0x7435,0x7436,0x7434,0x742F,/* 0x58-0x5F */
-	0x741B,0x7426,0x7428,0x7525,0x7526,0x756B,0x756A,0xF9E5,/* 0x60-0x67 */
+	0x741B,0x7426,0x7428,0x7525,0x7526,0x756B,0x756A,0x75E2,/* 0x60-0x67 */
 	0x75DB,0x75E3,0x75D9,0x75D8,0x75DE,0x75E0,0x767B,0x767C,/* 0x68-0x6F */
 	0x7696,0x7693,0x76B4,0x76DC,0x774F,0x77ED,0x785D,0x786C,/* 0x70-0x77 */
 	0x786F,0x7A0D,0x7A08,0x7A0B,0x7A05,0x7A00,0x7A98,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -762,10 +759,10 @@
 	0x800B,0x8052,0x8085,0x8155,0x8154,0x814B,0x8151,0x814E,/* 0xC0-0xC7 */
 	0x8139,0x8146,0x813E,0x814C,0x8153,0x8174,0x8212,0x821C,/* 0xC8-0xCF */
 	0x83E9,0x8403,0x83F8,0x840D,0x83E0,0x83C5,0x840B,0x83C1,/* 0xD0-0xD7 */
-	0x83EF,0xF958,0x83F4,0x8457,0x840A,0x83F0,0x840C,0x83CC,/* 0xD8-0xDF */
+	0x83EF,0x83F1,0x83F4,0x8457,0x840A,0x83F0,0x840C,0x83CC,/* 0xD8-0xDF */
 	0x83FD,0x83F2,0x83CA,0x8438,0x840E,0x8404,0x83DC,0x8407,/* 0xE0-0xE7 */
 	0x83D4,0x83DF,0x865B,0x86DF,0x86D9,0x86ED,0x86D4,0x86DB,/* 0xE8-0xEF */
-	0x86E4,0x86D0,0x86DE,0x8857,0x88C1,0xF9A0,0x88B1,0x8983,/* 0xF0-0xF7 */
+	0x86E4,0x86D0,0x86DE,0x8857,0x88C1,0x88C2,0x88B1,0x8983,/* 0xF0-0xF7 */
 	0x8996,0x8A3B,0x8A60,0x8A55,0x8A5E,0x8A3C,0x8A41,0x0000,/* 0xF8-0xFF */
 };
 
@@ -783,24 +780,24 @@
 	0x8CC0,0x8CB4,0x8CB7,0x8CB6,0x8CBF,0x8CB8,0x8D8A,0x8D85,/* 0x50-0x57 */
 	0x8D81,0x8DCE,0x8DDD,0x8DCB,0x8DDA,0x8DD1,0x8DCC,0x8DDB,/* 0x58-0x5F */
 	0x8DC6,0x8EFB,0x8EF8,0x8EFC,0x8F9C,0x902E,0x9035,0x9031,/* 0x60-0x67 */
-	0xFA25,0x9032,0x9036,0x9102,0x90F5,0x9109,0x90FE,0x9163,/* 0x68-0x6F */
-	0x9165,0xF97E,0x9214,0x9215,0x9223,0x9209,0x921E,0x920D,/* 0x70-0x77 */
+	0x9038,0x9032,0x9036,0x9102,0x90F5,0x9109,0x90FE,0x9163,/* 0x68-0x6F */
+	0x9165,0x91CF,0x9214,0x9215,0x9223,0x9209,0x921E,0x920D,/* 0x70-0x77 */
 	0x9210,0x9207,0x9211,0x9594,0x958F,0x958B,0x9591,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x98-0x9F */
 	0x0000,0x9593,0x9592,0x958E,0x968A,0x968E,0x968B,0x967D,/* 0xA0-0xA7 */
-	0x9685,0xF9DC,0x968D,0x9672,0x9684,0x96C1,0x96C5,0x96C4,/* 0xA8-0xAF */
+	0x9685,0x9686,0x968D,0x9672,0x9684,0x96C1,0x96C5,0x96C4,/* 0xA8-0xAF */
 	0x96C6,0x96C7,0x96EF,0x96F2,0x97CC,0x9805,0x9806,0x9808,/* 0xB0-0xB7 */
-	0x98E7,0x98EA,0xFA2A,0x98E9,0x98F2,0x98ED,0x99AE,0x99AD,/* 0xB8-0xBF */
-	0x9EC3,0x9ECD,0x9ED1,0xF91B,0x50AD,0x50B5,0x50B2,0x50B3,/* 0xC0-0xC7 */
+	0x98E7,0x98EA,0x98EF,0x98E9,0x98F2,0x98ED,0x99AE,0x99AD,/* 0xB8-0xBF */
+	0x9EC3,0x9ECD,0x9ED1,0x4E82,0x50AD,0x50B5,0x50B2,0x50B3,/* 0xC0-0xC7 */
 	0x50C5,0x50BE,0x50AC,0x50B7,0x50BB,0x50AF,0x50C7,0x527F,/* 0xC8-0xCF */
 	0x5277,0x527D,0x52DF,0x52E6,0x52E4,0x52E2,0x52E3,0x532F,/* 0xD0-0xD7 */
 	0x55DF,0x55E8,0x55D3,0x55E6,0x55CE,0x55DC,0x55C7,0x55D1,/* 0xD8-0xDF */
 	0x55E3,0x55E4,0x55EF,0x55DA,0x55E1,0x55C5,0x55C6,0x55E5,/* 0xE0-0xE7 */
-	0x55C9,0x5712,0x5713,0xF96C,0x5851,0x5858,0x5857,0xFA10,/* 0xE8-0xEF */
+	0x55C9,0x5712,0x5713,0x585E,0x5851,0x5858,0x5857,0x585A,/* 0xE8-0xEF */
 	0x5854,0x586B,0x584C,0x586D,0x584A,0x5862,0x5852,0x584B,/* 0xF0-0xF7 */
 	0x5967,0x5AC1,0x5AC9,0x5ACC,0x5ABE,0x5ABD,0x5ABC,0x0000,/* 0xF8-0xFF */
 };
@@ -814,15 +811,15 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x28-0x2F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x30-0x37 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x38-0x3F */
-	0x5AB3,0x5AC2,0x5AB2,0x5D69,0x5D6F,0x5E4C,0x5E79,0xF9A2,/* 0x40-0x47 */
+	0x5AB3,0x5AC2,0x5AB2,0x5D69,0x5D6F,0x5E4C,0x5E79,0x5EC9,/* 0x40-0x47 */
 	0x5EC8,0x5F12,0x5F59,0x5FAC,0x5FAE,0x611A,0x610F,0x6148,/* 0x48-0x4F */
 	0x611F,0x60F3,0x611B,0x60F9,0x6101,0x6108,0x614E,0x614C,/* 0x50-0x57 */
-	0xF9D9,0x614D,0x613E,0x6134,0x6127,0x610D,0x6106,0x6137,/* 0x58-0x5F */
+	0x6144,0x614D,0x613E,0x6134,0x6127,0x610D,0x6106,0x6137,/* 0x58-0x5F */
 	0x6221,0x6222,0x6413,0x643E,0x641E,0x642A,0x642D,0x643D,/* 0x60-0x67 */
 	0x642C,0x640F,0x641C,0x6414,0x640D,0x6436,0x6416,0x6417,/* 0x68-0x6F */
-	0x6406,0x656C,0x659F,0x65B0,0x6697,0x6689,0x6687,0xF9C5,/* 0x70-0x77 */
+	0x6406,0x656C,0x659F,0x65B0,0x6697,0x6689,0x6687,0x6688,/* 0x70-0x77 */
 	0x6696,0x6684,0x6698,0x668D,0x6703,0x6994,0x696D,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -831,9 +828,9 @@
 	0x694A,0x6968,0x696B,0x695E,0x6953,0x6979,0x6986,0x695D,/* 0xA8-0xAF */
 	0x6963,0x695B,0x6B47,0x6B72,0x6BC0,0x6BBF,0x6BD3,0x6BFD,/* 0xB0-0xB7 */
 	0x6EA2,0x6EAF,0x6ED3,0x6EB6,0x6EC2,0x6E90,0x6E9D,0x6EC7,/* 0xB8-0xBF */
-	0x6EC5,0x6EA5,0x6E98,0x6EBC,0xF9EC,0x6EAB,0xF904,0x6E96,/* 0xC0-0xC7 */
-	0xF9CB,0x6EC4,0x6ED4,0x6EAA,0x6EA7,0x6EB4,0x714E,0x7159,/* 0xC8-0xCF */
-	0x7169,0x7164,0xF993,0x7167,0x715C,0x716C,0x7166,0x714C,/* 0xD0-0xD7 */
+	0x6EC5,0x6EA5,0x6E98,0x6EBC,0x6EBA,0x6EAB,0x6ED1,0x6E96,/* 0xC0-0xC7 */
+	0x6E9C,0x6EC4,0x6ED4,0x6EAA,0x6EA7,0x6EB4,0x714E,0x7159,/* 0xC8-0xCF */
+	0x7169,0x7164,0x7149,0x7167,0x715C,0x716C,0x7166,0x714C,/* 0xD0-0xD7 */
 	0x7165,0x715E,0x7146,0x7168,0x7156,0x723A,0x7252,0x7337,/* 0xD8-0xDF */
 	0x7345,0x733F,0x733E,0x746F,0x745A,0x7455,0x745F,0x745E,/* 0xE0-0xE7 */
 	0x7441,0x743F,0x7459,0x745B,0x745C,0x7576,0x7578,0x7600,/* 0xE8-0xEF */
@@ -851,29 +848,29 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x30-0x37 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x38-0x3F */
 	0x7779,0x776A,0x776C,0x775C,0x7765,0x7768,0x7762,0x77EE,/* 0x40-0x47 */
-	0x788E,0x78B0,0x7897,0x7898,0xF93B,0x7889,0x787C,0x7891,/* 0x48-0x4F */
-	0x7893,0x787F,0x797A,0xF93C,0x7981,0x842C,0x79BD,0xF956,/* 0x50-0x57 */
+	0x788E,0x78B0,0x7897,0x7898,0x788C,0x7889,0x787C,0x7891,/* 0x48-0x4F */
+	0x7893,0x787F,0x797A,0x797F,0x7981,0x842C,0x79BD,0x7A1C,/* 0x50-0x57 */
 	0x7A1A,0x7A20,0x7A14,0x7A1F,0x7A1E,0x7A9F,0x7AA0,0x7B77,/* 0x58-0x5F */
 	0x7BC0,0x7B60,0x7B6E,0x7B67,0x7CB1,0x7CB3,0x7CB5,0x7D93,/* 0x60-0x67 */
 	0x7D79,0x7D91,0x7D81,0x7D8F,0x7D5B,0x7F6E,0x7F69,0x7F6A,/* 0x68-0x6F */
 	0x7F72,0x7FA9,0x7FA8,0x7FA4,0x8056,0x8058,0x8086,0x8084,/* 0x70-0x77 */
 	0x8171,0x8170,0x8178,0x8165,0x816E,0x8173,0x816B,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x98-0x9F */
 	0x0000,0x8179,0x817A,0x8166,0x8205,0x8247,0x8482,0x8477,/* 0xA0-0xA7 */
-	0xF918,0x8431,0x8475,0x8466,0x846B,0xF96E,0x846C,0x845B,/* 0xA8-0xAF */
+	0x843D,0x8431,0x8475,0x8466,0x846B,0x8449,0x846C,0x845B,/* 0xA8-0xAF */
 	0x843C,0x8435,0x8461,0x8463,0x8469,0x846D,0x8446,0x865E,/* 0xB0-0xB7 */
-	0xF936,0x865F,0x86F9,0x8713,0x8708,0x8707,0x8700,0x86FE,/* 0xB8-0xBF */
+	0x865C,0x865F,0x86F9,0x8713,0x8708,0x8707,0x8700,0x86FE,/* 0xB8-0xBF */
 	0x86FB,0x8702,0x8703,0x8706,0x870A,0x8859,0x88DF,0x88D4,/* 0xC0-0xC7 */
-	0x88D9,0x88DC,0x88D8,0x88DD,0xF9E8,0x88CA,0x88D5,0x88D2,/* 0xC8-0xCF */
+	0x88D9,0x88DC,0x88D8,0x88DD,0x88E1,0x88CA,0x88D5,0x88D2,/* 0xC8-0xCF */
 	0x899C,0x89E3,0x8A6B,0x8A72,0x8A73,0x8A66,0x8A69,0x8A70,/* 0xD0-0xD7 */
 	0x8A87,0x8A7C,0x8A63,0x8AA0,0x8A71,0x8A85,0x8A6D,0x8A62,/* 0xD8-0xDF */
 	0x8A6E,0x8A6C,0x8A79,0x8A7B,0x8A3E,0x8A68,0x8C62,0x8C8A,/* 0xE0-0xE7 */
-	0x8C89,0x8CCA,0x8CC7,0xF903,0x8CC4,0x8CB2,0x8CC3,0xF948,/* 0xE8-0xEF */
-	0x8CC5,0x8DE1,0x8DDF,0x8DE8,0xF937,0x8DF3,0x8DFA,0x8DEA,/* 0xF0-0xF7 */
+	0x8C89,0x8CCA,0x8CC7,0x8CC8,0x8CC4,0x8CB2,0x8CC3,0x8CC2,/* 0xE8-0xEF */
+	0x8CC5,0x8DE1,0x8DDF,0x8DE8,0x8DEF,0x8DF3,0x8DFA,0x8DEA,/* 0xF0-0xF7 */
 	0x8DE4,0x8DE6,0x8EB2,0x8F03,0x8F09,0x8EFE,0x8F0A,0x0000,/* 0xF8-0xFF */
 };
 
@@ -888,29 +885,29 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x38-0x3F */
 	0x8F9F,0x8FB2,0x904B,0x904A,0x9053,0x9042,0x9054,0x903C,/* 0x40-0x47 */
 	0x9055,0x9050,0x9047,0x904F,0x904E,0x904D,0x9051,0x903E,/* 0x48-0x4F */
-	0x9041,0x9112,0x9117,0x916C,0xF919,0x9169,0x91C9,0x9237,/* 0x50-0x57 */
+	0x9041,0x9112,0x9117,0x916C,0x916A,0x9169,0x91C9,0x9237,/* 0x50-0x57 */
 	0x9257,0x9238,0x923D,0x9240,0x923E,0x925B,0x924B,0x9264,/* 0x58-0x5F */
-	0x9251,0xF9B1,0x9249,0x924D,0x9245,0x9239,0x923F,0x925A,/* 0x60-0x67 */
+	0x9251,0x9234,0x9249,0x924D,0x9245,0x9239,0x923F,0x925A,/* 0x60-0x67 */
 	0x9598,0x9698,0x9694,0x9695,0x96CD,0x96CB,0x96C9,0x96CA,/* 0x68-0x6F */
-	0xF949,0x96FB,0x96F9,0xF9B2,0xFA1C,0x9774,0x9776,0x9810,/* 0x70-0x77 */
-	0x9811,0x9813,0x980A,0x9812,0x980C,0xFA2B,0x98F4,0x0000,/* 0x78-0x7F */
-	
+	0x96F7,0x96FB,0x96F9,0x96F6,0x9756,0x9774,0x9776,0x9810,/* 0x70-0x77 */
+	0x9811,0x9813,0x980A,0x9812,0x980C,0x98FC,0x98F4,0x0000,/* 0x78-0x7F */
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x98-0x9F */
 	0x0000,0x98FD,0x98FE,0x99B3,0x99B1,0x99B4,0x9AE1,0x9CE9,/* 0xA0-0xA7 */
 	0x9E82,0x9F0E,0x9F13,0x9F20,0x50E7,0x50EE,0x50E5,0x50D6,/* 0xA8-0xAF */
-	0x50ED,0xF9BB,0x50D5,0x50CF,0x50D1,0x50F1,0x50CE,0x50E9,/* 0xB0-0xB7 */
+	0x50ED,0x50DA,0x50D5,0x50CF,0x50D1,0x50F1,0x50CE,0x50E9,/* 0xB0-0xB7 */
 	0x5162,0x51F3,0x5283,0x5282,0x5331,0x53AD,0x55FE,0x5600,/* 0xB8-0xBF */
 	0x561B,0x5617,0x55FD,0x5614,0x5606,0x5609,0x560D,0x560E,/* 0xC0-0xC7 */
 	0x55F7,0x5616,0x561F,0x5608,0x5610,0x55F6,0x5718,0x5716,/* 0xC8-0xCF */
 	0x5875,0x587E,0x5883,0x5893,0x588A,0x5879,0x5885,0x587D,/* 0xD0-0xD7 */
 	0x58FD,0x5925,0x5922,0x5924,0x596A,0x5969,0x5AE1,0x5AE6,/* 0xD8-0xDF */
-	0x5AE9,0x5AD7,0x5AD6,0x5AD8,0x5AE3,0x5B75,0x5BDE,0xF9AA,/* 0xE0-0xE7 */
+	0x5AE9,0x5AD7,0x5AD6,0x5AD8,0x5AE3,0x5B75,0x5BDE,0x5BE7,/* 0xE0-0xE7 */
 	0x5BE1,0x5BE5,0x5BE6,0x5BE8,0x5BE2,0x5BE4,0x5BDF,0x5C0D,/* 0xE8-0xEF */
-	0xF94B,0x5D84,0x5D87,0x5E5B,0x5E63,0x5E55,0x5E57,0x5E54,/* 0xF0-0xF7 */
-	0xFA0B,0x5ED6,0x5F0A,0x5F46,0x5F70,0x5FB9,0x6147,0x0000,/* 0xF8-0xFF */
+	0x5C62,0x5D84,0x5D87,0x5E5B,0x5E63,0x5E55,0x5E57,0x5E54,/* 0xF0-0xF7 */
+	0x5ED3,0x5ED6,0x5F0A,0x5F46,0x5F70,0x5FB9,0x6147,0x0000,/* 0xF8-0xFF */
 };
 
 static wchar_t c2u_BA[256] = {
@@ -929,23 +926,23 @@
 	0x69C1,0x69AE,0x69D3,0x69CB,0x699B,0x69B7,0x69BB,0x69AB,/* 0x60-0x67 */
 	0x69B4,0x69D0,0x69CD,0x69AD,0x69CC,0x69A6,0x69C3,0x69A3,/* 0x68-0x6F */
 	0x6B49,0x6B4C,0x6C33,0x6F33,0x6F14,0x6EFE,0x6F13,0x6EF4,/* 0x70-0x77 */
-	0x6F29,0x6F3E,0x6F20,0x6F2C,0xF94E,0x6F02,0x6F22,0x0000,/* 0x78-0x7F */
-	
+	0x6F29,0x6F3E,0x6F20,0x6F2C,0x6F0F,0x6F02,0x6F22,0x0000,/* 0x78-0x7F */
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x98-0x9F */
-	0x0000,0x6EFF,0x6EEF,0x6F06,0x6F31,0x6F38,0x6F32,0xF992,/* 0xA0-0xA7 */
+	0x0000,0x6EFF,0x6EEF,0x6F06,0x6F31,0x6F38,0x6F32,0x6F23,/* 0xA0-0xA7 */
 	0x6F15,0x6F2B,0x6F2F,0x6F88,0x6F2A,0x6EEC,0x6F01,0x6EF2,/* 0xA8-0xAF */
 	0x6ECC,0x6EF7,0x7194,0x7199,0x717D,0x718A,0x7184,0x7192,/* 0xB0-0xB7 */
 	0x723E,0x7292,0x7296,0x7344,0x7350,0x7464,0x7463,0x746A,/* 0xB8-0xBF */
 	0x7470,0x746D,0x7504,0x7591,0x7627,0x760D,0x760B,0x7609,/* 0xC0-0xC7 */
 	0x7613,0x76E1,0x76E3,0x7784,0x777D,0x777F,0x7761,0x78C1,/* 0xC8-0xCF */
-	0x789F,0x78A7,0x78B3,0x78A9,0x78A3,0x798E,0xFA1B,0x798D,/* 0xD0-0xD7 */
+	0x789F,0x78A7,0x78B3,0x78A9,0x78A3,0x798E,0x798F,0x798D,/* 0xD0-0xD7 */
 	0x7A2E,0x7A31,0x7AAA,0x7AA9,0x7AED,0x7AEF,0x7BA1,0x7B95,/* 0xD8-0xDF */
 	0x7B8B,0x7B75,0x7B97,0x7B9D,0x7B94,0x7B8F,0x7BB8,0x7B87,/* 0xE0-0xE7 */
-	0x7B84,0x7CB9,0x7CBD,0xFA1D,0x7DBB,0x7DB0,0x7D9C,0x7DBD,/* 0xE8-0xEF */
-	0xF957,0xF93D,0x7DCA,0x7DB4,0x7DB2,0x7DB1,0x7DBA,0x7DA2,/* 0xF0-0xF7 */
+	0x7B84,0x7CB9,0x7CBD,0x7CBE,0x7DBB,0x7DB0,0x7D9C,0x7DBD,/* 0xE8-0xEF */
+	0x7DBE,0x7DA0,0x7DCA,0x7DB4,0x7DB2,0x7DB1,0x7DBA,0x7DA2,/* 0xF0-0xF7 */
 	0x7DBF,0x7DB5,0x7DB8,0x7DAD,0x7DD2,0x7DC7,0x7DAC,0x0000,/* 0xF8-0xFF */
 };
 
@@ -964,14 +961,14 @@
 	0x8499,0x849E,0x84B2,0x849C,0x84CB,0x84B8,0x84C0,0x84D3,/* 0x58-0x5F */
 	0x8490,0x84BC,0x84D1,0x84CA,0x873F,0x871C,0x873B,0x8722,/* 0x60-0x67 */
 	0x8725,0x8734,0x8718,0x8755,0x8737,0x8729,0x88F3,0x8902,/* 0x68-0x6F */
-	0x88F4,0x88F9,0xF912,0x88FD,0x88E8,0x891A,0x88EF,0x8AA6,/* 0x70-0x77 */
+	0x88F4,0x88F9,0x88F8,0x88FD,0x88E8,0x891A,0x88EF,0x8AA6,/* 0x70-0x77 */
 	0x8A8C,0x8A9E,0x8AA3,0x8A8D,0x8AA1,0x8A93,0x8AA4,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x98-0x9F */
-	0x0000,0xF9A1,0x8AA5,0x8AA8,0x8A98,0x8A91,0x8A9A,0x8AA7,/* 0xA0-0xA7 */
+	0x0000,0x8AAA,0x8AA5,0x8AA8,0x8A98,0x8A91,0x8A9A,0x8AA7,/* 0xA0-0xA7 */
 	0x8C6A,0x8C8D,0x8C8C,0x8CD3,0x8CD1,0x8CD2,0x8D6B,0x8D99,/* 0xA8-0xAF */
 	0x8D95,0x8DFC,0x8F14,0x8F12,0x8F15,0x8F13,0x8FA3,0x9060,/* 0xB0-0xB7 */
 	0x9058,0x905C,0x9063,0x9059,0x905E,0x9062,0x905D,0x905B,/* 0xB8-0xBF */
@@ -979,10 +976,10 @@
 	0x9280,0x9285,0x9298,0x9296,0x927B,0x9293,0x929C,0x92A8,/* 0xC8-0xCF */
 	0x927C,0x9291,0x95A1,0x95A8,0x95A9,0x95A3,0x95A5,0x95A4,/* 0xD0-0xD7 */
 	0x9699,0x969C,0x969B,0x96CC,0x96D2,0x9700,0x977C,0x9785,/* 0xD8-0xDF */
-	0x97F6,0x9817,0xF9B4,0x98AF,0x98B1,0x9903,0x9905,0x990C,/* 0xE0-0xE7 */
+	0x97F6,0x9817,0x9818,0x98AF,0x98B1,0x9903,0x9905,0x990C,/* 0xE0-0xE7 */
 	0x9909,0x99C1,0x9AAF,0x9AB0,0x9AE6,0x9B41,0x9B42,0x9CF4,/* 0xE8-0xEF */
 	0x9CF6,0x9CF3,0x9EBC,0x9F3B,0x9F4A,0x5104,0x5100,0x50FB,/* 0xF0-0xF7 */
-	0x50F5,0x50F9,0x5102,0x5108,0x5109,0x5105,0xF954,0x0000,/* 0xF8-0xFF */
+	0x50F5,0x50F9,0x5102,0x5108,0x5109,0x5105,0x51DC,0x0000,/* 0xF8-0xFF */
 };
 
 static wchar_t c2u_BC[256] = {
@@ -994,31 +991,31 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x28-0x2F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x30-0x37 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x38-0x3F */
-	0x5287,0x5288,0xF9C7,0x528D,0x528A,0x52F0,0x53B2,0x562E,/* 0x40-0x47 */
+	0x5287,0x5288,0x5289,0x528D,0x528A,0x52F0,0x53B2,0x562E,/* 0x40-0x47 */
 	0x563B,0x5639,0x5632,0x563F,0x5634,0x5629,0x5653,0x564E,/* 0x48-0x4F */
 	0x5657,0x5674,0x5636,0x562F,0x5630,0x5880,0x589F,0x589E,/* 0x50-0x57 */
 	0x58B3,0x589C,0x58AE,0x58A9,0x58A6,0x596D,0x5B09,0x5AFB,/* 0x58-0x5F */
-	0x5B0B,0x5AF5,0x5B0C,0x5B08,0xF9BC,0x5BEC,0x5BE9,0x5BEB,/* 0x60-0x67 */
-	0x5C64,0xF9DF,0x5D9D,0x5D94,0x5E62,0x5E5F,0x5E61,0x5EE2,/* 0x68-0x6F */
+	0x5B0B,0x5AF5,0x5B0C,0x5B08,0x5BEE,0x5BEC,0x5BE9,0x5BEB,/* 0x60-0x67 */
+	0x5C64,0x5C65,0x5D9D,0x5D94,0x5E62,0x5E5F,0x5E61,0x5EE2,/* 0x68-0x6F */
 	0x5EDA,0x5EDF,0x5EDD,0x5EE3,0x5EE0,0x5F48,0x5F71,0x5FB7,/* 0x70-0x77 */
 	0x5FB5,0x6176,0x6167,0x616E,0x615D,0x6155,0x6182,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x98-0x9F */
-	0x0000,0x617C,0x6170,0x616B,0x617E,0x61A7,0xF98F,0x61AB,/* 0xA0-0xA7 */
-	0x618E,0x61AC,0x619A,0x61A4,0x6194,0x61AE,0xF9D2,0x6469,/* 0xA8-0xAF */
+	0x0000,0x617C,0x6170,0x616B,0x617E,0x61A7,0x6190,0x61AB,/* 0xA0-0xA7 */
+	0x618E,0x61AC,0x619A,0x61A4,0x6194,0x61AE,0x622E,0x6469,/* 0xA8-0xAF */
 	0x646F,0x6479,0x649E,0x64B2,0x6488,0x6490,0x64B0,0x64A5,/* 0xB0-0xB7 */
-	0x6493,0x6495,0x64A9,0x6492,0x64AE,0x64AD,0x64AB,0xF991,/* 0xB8-0xBF */
-	0x64AC,0x6499,0x64A2,0x64B3,0x6575,0x6577,0xF969,0x66AE,/* 0xC0-0xC7 */
-	0x66AB,0xFA06,0x66B1,0x6A23,0x6A1F,0x69E8,0x6A01,0x6A1E,/* 0xC8-0xCF */
-	0x6A19,0x69FD,0x6A21,0xF94C,0x6A0A,0x69F3,0xF9BF,0x6A05,/* 0xD0-0xD7 */
+	0x6493,0x6495,0x64A9,0x6492,0x64AE,0x64AD,0x64AB,0x649A,/* 0xB8-0xBF */
+	0x64AC,0x6499,0x64A2,0x64B3,0x6575,0x6577,0x6578,0x66AE,/* 0xC0-0xC7 */
+	0x66AB,0x66B4,0x66B1,0x6A23,0x6A1F,0x69E8,0x6A01,0x6A1E,/* 0xC8-0xCF */
+	0x6A19,0x69FD,0x6A21,0x6A13,0x6A0A,0x69F3,0x6A02,0x6A05,/* 0xD0-0xD7 */
 	0x69ED,0x6A11,0x6B50,0x6B4E,0x6BA4,0x6BC5,0x6BC6,0x6F3F,/* 0xD8-0xDF */
 	0x6F7C,0x6F84,0x6F51,0x6F66,0x6F54,0x6F86,0x6F6D,0x6F5B,/* 0xE0-0xE7 */
 	0x6F78,0x6F6E,0x6F8E,0x6F7A,0x6F70,0x6F64,0x6F97,0x6F58,/* 0xE8-0xEF */
 	0x6ED5,0x6F6F,0x6F60,0x6F5F,0x719F,0x71AC,0x71B1,0x71A8,/* 0xF0-0xF7 */
-	0x7256,0x729B,0x734E,0x7357,0xF9AE,0x748B,0x7483,0x0000,/* 0xF8-0xFF */
+	0x7256,0x729B,0x734E,0x7357,0x7469,0x748B,0x7483,0x0000,/* 0xF8-0xFF */
 };
 
 static wchar_t c2u_BD[256] = {
@@ -1032,29 +1029,29 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x38-0x3F */
 	0x747E,0x7480,0x757F,0x7620,0x7629,0x761F,0x7624,0x7626,/* 0x40-0x47 */
 	0x7621,0x7622,0x769A,0x76BA,0x76E4,0x778E,0x7787,0x778C,/* 0x48-0x4F */
-	0x7791,0x778B,0x78CB,0x78C5,0x78BA,0xF947,0x78BE,0x78D5,/* 0x50-0x57 */
+	0x7791,0x778B,0x78CB,0x78C5,0x78BA,0x78CA,0x78BE,0x78D5,/* 0x50-0x57 */
 	0x78BC,0x78D0,0x7A3F,0x7A3C,0x7A40,0x7A3D,0x7A37,0x7A3B,/* 0x58-0x5F */
 	0x7AAF,0x7AAE,0x7BAD,0x7BB1,0x7BC4,0x7BB4,0x7BC6,0x7BC7,/* 0x60-0x67 */
-	0x7BC1,0x7BA0,0x7BCC,0x7CCA,0x7DE0,0xF996,0x7DEF,0x7DFB,/* 0x68-0x6F */
+	0x7BC1,0x7BA0,0x7BCC,0x7CCA,0x7DE0,0x7DF4,0x7DEF,0x7DFB,/* 0x68-0x6F */
 	0x7DD8,0x7DEC,0x7DDD,0x7DE8,0x7DE3,0x7DDA,0x7DDE,0x7DE9,/* 0x70-0x77 */
 	0x7D9E,0x7DD9,0x7DF2,0x7DF9,0x7F75,0x7F77,0x7FAF,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x98-0x9F */
 	0x0000,0x7FE9,0x8026,0x819B,0x819C,0x819D,0x81A0,0x819A,/* 0xA0-0xA7 */
-	0x8198,0x8517,0x853D,0x851A,0xF999,0x852C,0x852D,0x8513,/* 0xA8-0xAF */
+	0x8198,0x8517,0x853D,0x851A,0x84EE,0x852C,0x852D,0x8513,/* 0xA8-0xAF */
 	0x8511,0x8523,0x8521,0x8514,0x84EC,0x8525,0x84FF,0x8506,/* 0xB0-0xB7 */
 	0x8782,0x8774,0x8776,0x8760,0x8766,0x8778,0x8768,0x8759,/* 0xB8-0xBF */
 	0x8757,0x874C,0x8753,0x885B,0x885D,0x8910,0x8907,0x8912,/* 0xC0-0xC7 */
-	0x8913,0x8915,0x890A,0x8ABC,0xF97D,0x8AC7,0x8AC4,0x8A95,/* 0xC8-0xCF */
-	0x8ACB,0xFA22,0x8AB2,0x8AC9,0x8AC2,0x8ABF,0x8AB0,0xF941,/* 0xD0-0xD7 */
-	0x8ACD,0x8AB6,0x8AB9,0x8ADB,0x8C4C,0x8C4E,0xFA16,0x8CE0,/* 0xD8-0xDF */
+	0x8913,0x8915,0x890A,0x8ABC,0x8AD2,0x8AC7,0x8AC4,0x8A95,/* 0xC8-0xCF */
+	0x8ACB,0x8AF8,0x8AB2,0x8AC9,0x8AC2,0x8ABF,0x8AB0,0x8AD6,/* 0xD0-0xD7 */
+	0x8ACD,0x8AB6,0x8AB9,0x8ADB,0x8C4C,0x8C4E,0x8C6C,0x8CE0,/* 0xD8-0xDF */
 	0x8CDE,0x8CE6,0x8CE4,0x8CEC,0x8CED,0x8CE2,0x8CE3,0x8CDC,/* 0xE0-0xE7 */
 	0x8CEA,0x8CE1,0x8D6D,0x8D9F,0x8DA3,0x8E2B,0x8E10,0x8E1D,/* 0xE8-0xEF */
 	0x8E22,0x8E0F,0x8E29,0x8E1F,0x8E21,0x8E1E,0x8EBA,0x8F1D,/* 0xF0-0xF7 */
-	0x8F1B,0x8F1F,0x8F29,0xF998,0xF9D7,0x8F1C,0x8F1E,0x0000,/* 0xF8-0xFF */
+	0x8F1B,0x8F1F,0x8F29,0x8F26,0x8F2A,0x8F1C,0x8F1E,0x0000,/* 0xF8-0xFF */
 };
 
 static wchar_t c2u_BE[256] = {
@@ -1069,28 +1066,28 @@
 	0x8F25,0x9069,0x906E,0x9068,0x906D,0x9077,0x9130,0x912D,/* 0x40-0x47 */
 	0x9127,0x9131,0x9187,0x9189,0x918B,0x9183,0x92C5,0x92BB,/* 0x48-0x4F */
 	0x92B7,0x92EA,0x92AC,0x92E4,0x92C1,0x92B3,0x92BC,0x92D2,/* 0x50-0x57 */
-	0x92C7,0x92F0,0x92B2,0xF986,0x95B1,0x9704,0x9706,0x9707,/* 0x58-0x5F */
+	0x92C7,0x92F0,0x92B2,0x95AD,0x95B1,0x9704,0x9706,0x9707,/* 0x58-0x5F */
 	0x9709,0x9760,0x978D,0x978B,0x978F,0x9821,0x982B,0x981C,/* 0x60-0x67 */
 	0x98B3,0x990A,0x9913,0x9912,0x9918,0x99DD,0x99D0,0x99DF,/* 0x68-0x6F */
 	0x99DB,0x99D1,0x99D5,0x99D2,0x99D9,0x9AB7,0x9AEE,0x9AEF,/* 0x70-0x77 */
-	0x9B27,0x9B45,0x9B44,0x9B77,0xF939,0x9D06,0x9D09,0x0000,/* 0x78-0x7F */
-	
+	0x9B27,0x9B45,0x9B44,0x9B77,0x9B6F,0x9D06,0x9D09,0x0000,/* 0x78-0x7F */
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x98-0x9F */
-	0x0000,0x9D03,0x9EA9,0x9EBE,0xF989,0x58A8,0x9F52,0x5112,/* 0xA0-0xA7 */
+	0x0000,0x9D03,0x9EA9,0x9EBE,0x9ECE,0x58A8,0x9F52,0x5112,/* 0xA0-0xA7 */
 	0x5118,0x5114,0x5110,0x5115,0x5180,0x51AA,0x51DD,0x5291,/* 0xA8-0xAF */
 	0x5293,0x52F3,0x5659,0x566B,0x5679,0x5669,0x5664,0x5678,/* 0xB0-0xB7 */
 	0x566A,0x5668,0x5665,0x5671,0x566F,0x566C,0x5662,0x5676,/* 0xB8-0xBF */
 	0x58C1,0x58BE,0x58C7,0x58C5,0x596E,0x5B1D,0x5B34,0x5B78,/* 0xC0-0xC7 */
 	0x5BF0,0x5C0E,0x5F4A,0x61B2,0x6191,0x61A9,0x618A,0x61CD,/* 0xC8-0xCF */
 	0x61B6,0x61BE,0x61CA,0x61C8,0x6230,0x64C5,0x64C1,0x64CB,/* 0xD0-0xD7 */
-	0x64BB,0x64BC,0x64DA,0xF930,0x64C7,0x64C2,0x64CD,0x64BF,/* 0xD8-0xDF */
-	0x64D2,0x64D4,0x64BE,0x6574,0xF98B,0x66C9,0x66B9,0x66C4,/* 0xE0-0xE7 */
+	0x64BB,0x64BC,0x64DA,0x64C4,0x64C7,0x64C2,0x64CD,0x64BF,/* 0xD8-0xDF */
+	0x64D2,0x64D4,0x64BE,0x6574,0x66C6,0x66C9,0x66B9,0x66C4,/* 0xE0-0xE7 */
 	0x66C7,0x66B8,0x6A3D,0x6A38,0x6A3A,0x6A59,0x6A6B,0x6A58,/* 0xE8-0xEF */
 	0x6A39,0x6A44,0x6A62,0x6A61,0x6A4B,0x6A47,0x6A35,0x6A5F,/* 0xF0-0xF7 */
-	0x6A48,0x6B59,0xF98C,0x6C05,0x6FC2,0x6FB1,0x6FA1,0x0000,/* 0xF8-0xFF */
+	0x6A48,0x6B59,0x6B77,0x6C05,0x6FC2,0x6FB1,0x6FA1,0x0000,/* 0xF8-0xFF */
 };
 
 static wchar_t c2u_BF[256] = {
@@ -1103,30 +1100,30 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x30-0x37 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x38-0x3F */
 	0x6FC3,0x6FA4,0x6FC1,0x6FA7,0x6FB3,0x6FC0,0x6FB9,0x6FB6,/* 0x40-0x47 */
-	0x6FA6,0x6FA0,0x6FB4,0x71BE,0x71C9,0xF9EE,0x71D2,0x71C8,/* 0x48-0x4F */
-	0x71D5,0x71B9,0xF9C0,0x71D9,0x71DC,0x71C3,0x71C4,0x7368,/* 0x50-0x57 */
-	0x749C,0x74A3,0xF9EF,0x749F,0x749E,0x74E2,0x750C,0x750D,/* 0x58-0x5F */
-	0x7634,0x7638,0x763A,0xF933,0x76E5,0x77A0,0x779E,0x779F,/* 0x60-0x67 */
+	0x6FA6,0x6FA0,0x6FB4,0x71BE,0x71C9,0x71D0,0x71D2,0x71C8,/* 0x48-0x4F */
+	0x71D5,0x71B9,0x71CE,0x71D9,0x71DC,0x71C3,0x71C4,0x7368,/* 0x50-0x57 */
+	0x749C,0x74A3,0x7498,0x749F,0x749E,0x74E2,0x750C,0x750D,/* 0x58-0x5F */
+	0x7634,0x7638,0x763A,0x76E7,0x76E5,0x77A0,0x779E,0x779F,/* 0x60-0x67 */
 	0x77A5,0x78E8,0x78DA,0x78EC,0x78E7,0x79A6,0x7A4D,0x7A4E,/* 0x68-0x6F */
 	0x7A46,0x7A4C,0x7A4B,0x7ABA,0x7BD9,0x7C11,0x7BC9,0x7BE4,/* 0x70-0x77 */
-	0x7BDB,0x7BE1,0x7BE9,0x7BE6,0x7CD5,0xFA03,0x7E0A,0x0000,/* 0x78-0x7F */
-	
+	0x7BDB,0x7BE1,0x7BE9,0x7BE6,0x7CD5,0x7CD6,0x7E0A,0x0000,/* 0x78-0x7F */
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x98-0x9F */
 	0x0000,0x7E11,0x7E08,0x7E1B,0x7E23,0x7E1E,0x7E1D,0x7E09,/* 0xA0-0xA7 */
-	0x7E10,0xF9E6,0x7FB2,0x7FF0,0x7FF1,0x7FEE,0x8028,0x81B3,/* 0xA8-0xAF */
+	0x7E10,0x7F79,0x7FB2,0x7FF0,0x7FF1,0x7FEE,0x8028,0x81B3,/* 0xA8-0xAF */
 	0x81A9,0x81A8,0x81FB,0x8208,0x8258,0x8259,0x854A,0x8559,/* 0xB0-0xB7 */
 	0x8548,0x8568,0x8569,0x8543,0x8549,0x856D,0x856A,0x855E,/* 0xB8-0xBF */
 	0x8783,0x879F,0x879E,0x87A2,0x878D,0x8861,0x892A,0x8932,/* 0xC0-0xC7 */
 	0x8925,0x892B,0x8921,0x89AA,0x89A6,0x8AE6,0x8AFA,0x8AEB,/* 0xC8-0xCF */
-	0x8AF1,0x8B00,0x8ADC,0x8AE7,0x8AEE,0xF95D,0x8B01,0x8B02,/* 0xD0-0xD7 */
+	0x8AF1,0x8B00,0x8ADC,0x8AE7,0x8AEE,0x8AFE,0x8B01,0x8B02,/* 0xD0-0xD7 */
 	0x8AF7,0x8AED,0x8AF3,0x8AF6,0x8AFC,0x8C6B,0x8C6D,0x8C93,/* 0xD8-0xDF */
-	0x8CF4,0x8E44,0x8E31,0x8E34,0x8E42,0x8E39,0x8E35,0xFA07,/* 0xE0-0xE7 */
+	0x8CF4,0x8E44,0x8E31,0x8E34,0x8E42,0x8E39,0x8E35,0x8F3B,/* 0xE0-0xE7 */
 	0x8F2F,0x8F38,0x8F33,0x8FA8,0x8FA6,0x9075,0x9074,0x9078,/* 0xE8-0xEF */
-	0x9072,0xF9C3,0x907A,0x9134,0x9192,0x9320,0x9336,0x92F8,/* 0xF0-0xF7 */
-	0x9333,0x932F,0x9322,0x92FC,0x932B,0xF93F,0x931A,0x0000,/* 0xF8-0xFF */
+	0x9072,0x907C,0x907A,0x9134,0x9192,0x9320,0x9336,0x92F8,/* 0xF0-0xF7 */
+	0x9333,0x932F,0x9322,0x92FC,0x932B,0x9304,0x931A,0x0000,/* 0xF8-0xFF */
 };
 
 static wchar_t c2u_C0[256] = {
@@ -1141,28 +1138,28 @@
 	0x9310,0x9326,0x9321,0x9315,0x932E,0x9319,0x95BB,0x96A7,/* 0x40-0x47 */
 	0x96A8,0x96AA,0x96D5,0x970E,0x9711,0x9716,0x970D,0x9713,/* 0x48-0x4F */
 	0x970F,0x975B,0x975C,0x9766,0x9798,0x9830,0x9838,0x983B,/* 0x50-0x57 */
-	0x9837,0x982D,0x9839,0x9824,0x9910,0xFA2C,0x991E,0x991B,/* 0x58-0x5F */
-	0x9921,0x991A,0x99ED,0x99E2,0xF91A,0x9AB8,0x9ABC,0x9AFB,/* 0x60-0x67 */
+	0x9837,0x982D,0x9839,0x9824,0x9910,0x9928,0x991E,0x991B,/* 0x58-0x5F */
+	0x9921,0x991A,0x99ED,0x99E2,0x99F1,0x9AB8,0x9ABC,0x9AFB,/* 0x60-0x67 */
 	0x9AED,0x9B28,0x9B91,0x9D15,0x9D23,0x9D26,0x9D28,0x9D12,/* 0x68-0x6F */
-	0x9D1B,0x9ED8,0x9ED4,0xF9C4,0xF908,0x512A,0x511F,0x5121,/* 0x70-0x77 */
-	0x5132,0xF97F,0x568E,0x5680,0x5690,0x5685,0x5687,0x0000,/* 0x78-0x7F */
-	
+	0x9D1B,0x9ED8,0x9ED4,0x9F8D,0x9F9C,0x512A,0x511F,0x5121,/* 0x70-0x77 */
+	0x5132,0x52F5,0x568E,0x5680,0x5690,0x5685,0x5687,0x0000,/* 0x78-0x7F */
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x98-0x9F */
 	0x0000,0x568F,0x58D5,0x58D3,0x58D1,0x58CE,0x5B30,0x5B2A,/* 0xA0-0xA7 */
-	0x5B24,0x5B7A,0x5C37,0x5C68,0x5DBC,0xF9AB,0x5DBD,0x5DB8,/* 0xA8-0xAF */
+	0x5B24,0x5B7A,0x5C37,0x5C68,0x5DBC,0x5DBA,0x5DBD,0x5DB8,/* 0xA8-0xAF */
 	0x5E6B,0x5F4C,0x5FBD,0x61C9,0x61C2,0x61C7,0x61E6,0x61CB,/* 0xB0-0xB7 */
 	0x6232,0x6234,0x64CE,0x64CA,0x64D8,0x64E0,0x64F0,0x64E6,/* 0xB8-0xBF */
 	0x64EC,0x64F1,0x64E2,0x64ED,0x6582,0x6583,0x66D9,0x66D6,/* 0xC0-0xC7 */
 	0x6A80,0x6A94,0x6A84,0x6AA2,0x6A9C,0x6ADB,0x6AA3,0x6A7E,/* 0xC8-0xCF */
-	0x6A97,0x6A90,0x6AA0,0x6B5C,0xF9A5,0x6BDA,0x6C08,0x6FD8,/* 0xD0-0xD7 */
-	0x6FF1,0x6FDF,0x6FE0,0x6FDB,0x6FE4,0xF922,0x6FEF,0x6F80,/* 0xD8-0xDF */
+	0x6A97,0x6A90,0x6AA0,0x6B5C,0x6BAE,0x6BDA,0x6C08,0x6FD8,/* 0xD0-0xD7 */
+	0x6FF1,0x6FDF,0x6FE0,0x6FDB,0x6FE4,0x6FEB,0x6FEF,0x6F80,/* 0xD8-0xDF */
 	0x6FEC,0x6FE1,0x6FE9,0x6FD5,0x6FEE,0x6FF0,0x71E7,0x71DF,/* 0xE0-0xE7 */
 	0x71EE,0x71E6,0x71E5,0x71ED,0x71EC,0x71F4,0x71E0,0x7235,/* 0xE8-0xEF */
 	0x7246,0x7370,0x7372,0x74A9,0x74B0,0x74A6,0x74A8,0x7646,/* 0xF0-0xF7 */
-	0xF9C1,0x764C,0x76EA,0x77B3,0x77AA,0x77B0,0x77AC,0x0000,/* 0xF8-0xFF */
+	0x7642,0x764C,0x76EA,0x77B3,0x77AA,0x77B0,0x77AC,0x0000,/* 0xF8-0xFF */
 };
 
 static wchar_t c2u_C1[256] = {
@@ -1177,27 +1174,27 @@
 	0x77A7,0x77AD,0x77EF,0x78F7,0x78FA,0x78F4,0x78EF,0x7901,/* 0x40-0x47 */
 	0x79A7,0x79AA,0x7A57,0x7ABF,0x7C07,0x7C0D,0x7BFE,0x7BF7,/* 0x48-0x4F */
 	0x7C0C,0x7BE0,0x7CE0,0x7CDC,0x7CDE,0x7CE2,0x7CDF,0x7CD9,/* 0x50-0x57 */
-	0x7CDD,0x7E2E,0x7E3E,0x7E46,0xF950,0x7E32,0x7E43,0x7E2B,/* 0x58-0x5F */
+	0x7CDD,0x7E2E,0x7E3E,0x7E46,0x7E37,0x7E32,0x7E43,0x7E2B,/* 0x58-0x5F */
 	0x7E3D,0x7E31,0x7E45,0x7E41,0x7E34,0x7E39,0x7E48,0x7E35,/* 0x60-0x67 */
 	0x7E3F,0x7E2F,0x7F44,0x7FF3,0x7FFC,0x8071,0x8072,0x8070,/* 0x68-0x6F */
-	0xF997,0x8073,0x81C6,0x81C3,0x81BA,0x81C2,0x81C0,0x81BF,/* 0x70-0x77 */
-	0x81BD,0x81C9,0x81BE,0xF9F6,0x8209,0x8271,0x85AA,0x0000,/* 0x78-0x7F */
-	
+	0x806F,0x8073,0x81C6,0x81C3,0x81BA,0x81C2,0x81C0,0x81BF,/* 0x70-0x77 */
+	0x81BD,0x81C9,0x81BE,0x81E8,0x8209,0x8271,0x85AA,0x0000,/* 0x78-0x7F */
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x98-0x9F */
 	0x0000,0x8584,0x857E,0x859C,0x8591,0x8594,0x85AF,0x859B,/* 0xA0-0xA7 */
 	0x8587,0x85A8,0x858A,0x8667,0x87C0,0x87D1,0x87B3,0x87D2,/* 0xA8-0xAF */
-	0x87C6,0x87AB,0x87BB,0xF911,0x87C8,0x87CB,0x893B,0x8936,/* 0xB0-0xB7 */
+	0x87C6,0x87AB,0x87BB,0x87BA,0x87C8,0x87CB,0x893B,0x8936,/* 0xB0-0xB7 */
 	0x8944,0x8938,0x893D,0x89AC,0x8B0E,0x8B17,0x8B19,0x8B1B,/* 0xB8-0xBF */
 	0x8B0A,0x8B20,0x8B1D,0x8B04,0x8B10,0x8C41,0x8C3F,0x8C73,/* 0xC0-0xC7 */
 	0x8CFA,0x8CFD,0x8CFC,0x8CF8,0x8CFB,0x8DA8,0x8E49,0x8E4B,/* 0xC8-0xCF */
 	0x8E48,0x8E4A,0x8F44,0x8F3E,0x8F42,0x8F45,0x8F3F,0x907F,/* 0xD0-0xD7 */
 	0x907D,0x9084,0x9081,0x9082,0x9080,0x9139,0x91A3,0x919E,/* 0xD8-0xDF */
-	0x919C,0x934D,0x9382,0x9328,0x9375,0xF99B,0x9365,0x934B,/* 0xE0-0xE7 */
+	0x919C,0x934D,0x9382,0x9328,0x9375,0x934A,0x9365,0x934B,/* 0xE0-0xE7 */
 	0x9318,0x937E,0x936C,0x935B,0x9370,0x935A,0x9354,0x95CA,/* 0xE8-0xEF */
-	0x95CB,0x95CC,0x95C8,0x95C6,0x96B1,0xF9B8,0x96D6,0x971C,/* 0xF0-0xF7 */
+	0x95CB,0x95CC,0x95C8,0x95C6,0x96B1,0x96B8,0x96D6,0x971C,/* 0xF0-0xF7 */
 	0x971E,0x97A0,0x97D3,0x9846,0x98B6,0x9935,0x9A01,0x0000,/* 0xF8-0xFF */
 };
 
@@ -1212,28 +1209,28 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x38-0x3F */
 	0x99FF,0x9BAE,0x9BAB,0x9BAA,0x9BAD,0x9D3B,0x9D3F,0x9E8B,/* 0x40-0x47 */
 	0x9ECF,0x9EDE,0x9EDC,0x9EDD,0x9EDB,0x9F3E,0x9F4B,0x53E2,/* 0x48-0x4F */
-	0x5695,0x56AE,0x58D9,0xF94A,0x5B38,0x5F5D,0x61E3,0x6233,/* 0x50-0x57 */
+	0x5695,0x56AE,0x58D9,0x58D8,0x5B38,0x5F5D,0x61E3,0x6233,/* 0x50-0x57 */
 	0x64F4,0x64F2,0x64FE,0x6506,0x64FA,0x64FB,0x64F7,0x65B7,/* 0x58-0x5F */
 	0x66DC,0x6726,0x6AB3,0x6AAC,0x6AC3,0x6ABB,0x6AB8,0x6AC2,/* 0x60-0x67 */
-	0x6AAE,0x6AAF,0x6B5F,0x6B78,0x6BAF,0x7009,0x700B,0xF984,/* 0x68-0x6F */
+	0x6AAE,0x6AAF,0x6B5F,0x6B78,0x6BAF,0x7009,0x700B,0x6FFE,/* 0x68-0x6F */
 	0x7006,0x6FFA,0x7011,0x700F,0x71FB,0x71FC,0x71FE,0x71F8,/* 0x70-0x77 */
-	0x7377,0xF9A7,0x74A7,0x74BF,0x7515,0x7656,0x7658,0x0000,/* 0x78-0x7F */
-	
+	0x7377,0x7375,0x74A7,0x74BF,0x7515,0x7656,0x7658,0x0000,/* 0x78-0x7F */
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x98-0x9F */
-	0x0000,0x7652,0x77BD,0x77BF,0x77BB,0x77BC,0x790E,0xF9B6,/* 0xA0-0xA7 */
+	0x0000,0x7652,0x77BD,0x77BF,0x77BB,0x77BC,0x790E,0x79AE,/* 0xA0-0xA7 */
 	0x7A61,0x7A62,0x7A60,0x7AC4,0x7AC5,0x7C2B,0x7C27,0x7C2A,/* 0xA8-0xAF */
-	0x7C1E,0x7C23,0x7C21,0xF97B,0x7E54,0x7E55,0x7E5E,0x7E5A,/* 0xB0-0xB7 */
+	0x7C1E,0x7C23,0x7C21,0x7CE7,0x7E54,0x7E55,0x7E5E,0x7E5A,/* 0xB0-0xB7 */
 	0x7E61,0x7E52,0x7E59,0x7F48,0x7FF9,0x7FFB,0x8077,0x8076,/* 0xB8-0xBF */
-	0x81CD,0x81CF,0x820A,0x85CF,0x85A9,0xF923,0x85D0,0x85C9,/* 0xC0-0xC7 */
+	0x81CD,0x81CF,0x820A,0x85CF,0x85A9,0x85CD,0x85D0,0x85C9,/* 0xC0-0xC7 */
 	0x85B0,0x85BA,0x85B9,0x85A6,0x87EF,0x87EC,0x87F2,0x87E0,/* 0xC8-0xCF */
 	0x8986,0x89B2,0x89F4,0x8B28,0x8B39,0x8B2C,0x8B2B,0x8C50,/* 0xD0-0xD7 */
 	0x8D05,0x8E59,0x8E63,0x8E66,0x8E64,0x8E5F,0x8E55,0x8EC0,/* 0xD8-0xDF */
 	0x8F49,0x8F4D,0x9087,0x9083,0x9088,0x91AB,0x91AC,0x91D0,/* 0xE0-0xE7 */
 	0x9394,0x938A,0x9396,0x93A2,0x93B3,0x93AE,0x93AC,0x93B0,/* 0xE8-0xEF */
-	0x9398,0x939A,0x9397,0x95D4,0x95D6,0x95D0,0x95D5,0xF9EA,/* 0xF0-0xF7 */
+	0x9398,0x939A,0x9397,0x95D4,0x95D6,0x95D0,0x95D5,0x96E2,/* 0xF0-0xF7 */
 	0x96DC,0x96D9,0x96DB,0x96DE,0x9724,0x97A3,0x97A6,0x0000,/* 0xF8-0xFF */
 };
 
@@ -1250,27 +1247,27 @@
 	0x993E,0x993F,0x993D,0x992E,0x99A5,0x9A0E,0x9AC1,0x9B03,/* 0x48-0x4F */
 	0x9B06,0x9B4F,0x9B4E,0x9B4D,0x9BCA,0x9BC9,0x9BFD,0x9BC8,/* 0x50-0x57 */
 	0x9BC0,0x9D51,0x9D5D,0x9D60,0x9EE0,0x9F15,0x9F2C,0x5133,/* 0x58-0x5F */
-	0x56A5,0x58DE,0xF942,0x58E2,0x5BF5,0x9F90,0xF982,0x61F2,/* 0x60-0x67 */
-	0x61F7,0xF90D,0x61F5,0x6500,0x650F,0x66E0,0x66DD,0x6AE5,/* 0x68-0x6F */
-	0x6ADD,0x6ADA,0xF931,0x701B,0x701F,0x7028,0x701A,0x701D,/* 0x70-0x77 */
+	0x56A5,0x58DE,0x58DF,0x58E2,0x5BF5,0x9F90,0x5EEC,0x61F2,/* 0x60-0x67 */
+	0x61F7,0x61F6,0x61F5,0x6500,0x650F,0x66E0,0x66DD,0x6AE5,/* 0x68-0x6F */
+	0x6ADD,0x6ADA,0x6AD3,0x701B,0x701F,0x7028,0x701A,0x701D,/* 0x70-0x77 */
 	0x7015,0x7018,0x7206,0x720D,0x7258,0x72A2,0x7378,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x98-0x9F */
 	0x0000,0x737A,0x74BD,0x74CA,0x74E3,0x7587,0x7586,0x765F,/* 0xA0-0xA7 */
-	0x7661,0x77C7,0x7919,0x79B1,0x7A6B,0x7A69,0xF9A6,0x7C3F,/* 0xA8-0xAF */
+	0x7661,0x77C7,0x7919,0x79B1,0x7A6B,0x7A69,0x7C3E,0x7C3F,/* 0xA8-0xAF */
 	0x7C38,0x7C3D,0x7C37,0x7C40,0x7E6B,0x7E6D,0x7E79,0x7E69,/* 0xB0-0xB7 */
-	0x7E6A,0xF90F,0x7E73,0x7FB6,0x7FB9,0x7FB8,0xF926,0x85E9,/* 0xB8-0xBF */
+	0x7E6A,0x7F85,0x7E73,0x7FB6,0x7FB9,0x7FB8,0x81D8,0x85E9,/* 0xB8-0xBF */
 	0x85DD,0x85EA,0x85D5,0x85E4,0x85E5,0x85F7,0x87FB,0x8805,/* 0xC0-0xC7 */
 	0x880D,0x87F9,0x87FE,0x8960,0x895F,0x8956,0x895E,0x8B41,/* 0xC8-0xCF */
-	0x8B5C,0xF9FC,0x8B49,0x8B5A,0x8B4E,0x8B4F,0x8B46,0x8B59,/* 0xD0-0xD7 */
+	0x8B5C,0x8B58,0x8B49,0x8B5A,0x8B4E,0x8B4F,0x8B46,0x8B59,/* 0xD0-0xD7 */
 	0x8D08,0x8D0A,0x8E7C,0x8E72,0x8E87,0x8E76,0x8E6C,0x8E7A,/* 0xD8-0xDF */
 	0x8E74,0x8F54,0x8F4E,0x8FAD,0x908A,0x908B,0x91B1,0x91AE,/* 0xE0-0xE7 */
 	0x93E1,0x93D1,0x93DF,0x93C3,0x93C8,0x93DC,0x93DD,0x93D6,/* 0xE8-0xEF */
 	0x93E2,0x93CD,0x93D8,0x93E4,0x93D7,0x93E8,0x95DC,0x96B4,/* 0xF0-0xF7 */
-	0x96E3,0x972A,0x9727,0x9761,0x97DC,0x97FB,0xF9D0,0x0000,/* 0xF8-0xFF */
+	0x96E3,0x972A,0x9727,0x9761,0x97DC,0x97FB,0x985E,0x0000,/* 0xF8-0xFF */
 };
 
 static wchar_t c2u_C4[256] = {
@@ -1284,29 +1281,29 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x38-0x3F */
 	0x9858,0x985B,0x98BC,0x9945,0x9949,0x9A16,0x9A19,0x9B0D,/* 0x40-0x47 */
 	0x9BE8,0x9BE7,0x9BD6,0x9BDB,0x9D89,0x9D61,0x9D72,0x9D6A,/* 0x48-0x4F */
-	0x9D6C,0x9E92,0xF988,0x9E93,0x9EB4,0x52F8,0x56A8,0x56B7,/* 0x50-0x57 */
+	0x9D6C,0x9E92,0x9E97,0x9E93,0x9EB4,0x52F8,0x56A8,0x56B7,/* 0x50-0x57 */
 	0x56B6,0x56B4,0x56BC,0x58E4,0x5B40,0x5B43,0x5B7D,0x5BF6,/* 0x58-0x5F */
 	0x5DC9,0x61F8,0x61FA,0x6518,0x6514,0x6519,0x66E6,0x6727,/* 0x60-0x67 */
-	0x6AEC,0x703E,0x7030,0x7032,0xF932,0x737B,0x74CF,0x7662,/* 0x68-0x6F */
-	0x7665,0x7926,0xF985,0x792C,0x792B,0x7AC7,0x7AF6,0x7C4C,/* 0x70-0x77 */
+	0x6AEC,0x703E,0x7030,0x7032,0x7210,0x737B,0x74CF,0x7662,/* 0x68-0x6F */
+	0x7665,0x7926,0x792A,0x792C,0x792B,0x7AC7,0x7AF6,0x7C4C,/* 0x70-0x77 */
 	0x7C43,0x7C4D,0x7CEF,0x7CF0,0x8FAE,0x7E7D,0x7E7C,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x98-0x9F */
 	0x0000,0x7E82,0x7F4C,0x8000,0x81DA,0x8266,0x85FB,0x85F9,/* 0xA0-0xA7 */
-	0x8611,0xF9F0,0xF935,0x860B,0x8607,0x860A,0x8814,0x8815,/* 0xA8-0xAF */
-	0xF924,0x89BA,0x89F8,0x8B70,0x8B6C,0x8B66,0x8B6F,0x8B5F,/* 0xB0-0xB7 */
-	0x8B6B,0x8D0F,0x8D0D,0x8E89,0x8E81,0x8E85,0x8E82,0xF9B7,/* 0xB8-0xBF */
+	0x8611,0x85FA,0x8606,0x860B,0x8607,0x860A,0x8814,0x8815,/* 0xA8-0xAF */
+	0x8964,0x89BA,0x89F8,0x8B70,0x8B6C,0x8B66,0x8B6F,0x8B5F,/* 0xB0-0xB7 */
+	0x8B6B,0x8D0F,0x8D0D,0x8E89,0x8E81,0x8E85,0x8E82,0x91B4,/* 0xB8-0xBF */
 	0x91CB,0x9418,0x9403,0x93FD,0x95E1,0x9730,0x98C4,0x9952,/* 0xC0-0xC7 */
 	0x9951,0x99A8,0x9A2B,0x9A30,0x9A37,0x9A35,0x9C13,0x9C0D,/* 0xC8-0xCF */
 	0x9E79,0x9EB5,0x9EE8,0x9F2F,0x9F5F,0x9F63,0x9F61,0x5137,/* 0xD0-0xD7 */
 	0x5138,0x56C1,0x56C0,0x56C2,0x5914,0x5C6C,0x5DCD,0x61FC,/* 0xD8-0xDF */
-	0x61FE,0x651D,0x651C,0x6595,0x66E9,0x6AFB,0xF91D,0x6AFA,/* 0xE0-0xE7 */
-	0x6BB2,0x704C,0xF91E,0x72A7,0x74D6,0x74D4,0xF90E,0x77D3,/* 0xE8-0xEF */
-	0x7C50,0x7E8F,0x7E8C,0x7FBC,0x8617,0xF91F,0x861A,0x8823,/* 0xF0-0xF7 */
-	0x8822,0x8821,0xF927,0x896A,0x896C,0x89BD,0x8B74,0x0000,/* 0xF8-0xFF */
+	0x61FE,0x651D,0x651C,0x6595,0x66E9,0x6AFB,0x6B04,0x6AFA,/* 0xE0-0xE7 */
+	0x6BB2,0x704C,0x721B,0x72A7,0x74D6,0x74D4,0x7669,0x77D3,/* 0xE8-0xEF */
+	0x7C50,0x7E8F,0x7E8C,0x7FBC,0x8617,0x862D,0x861A,0x8823,/* 0xF0-0xF7 */
+	0x8822,0x8821,0x881F,0x896A,0x896C,0x89BD,0x8B74,0x0000,/* 0xF8-0xFF */
 };
 
 static wchar_t c2u_C5[256] = {
@@ -1320,27 +1317,27 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x38-0x3F */
 	0x8B77,0x8B7D,0x8D13,0x8E8A,0x8E8D,0x8E8B,0x8F5F,0x8FAF,/* 0x40-0x47 */
 	0x91BA,0x942E,0x9433,0x9435,0x943A,0x9438,0x9432,0x942B,/* 0x48-0x4F */
-	0x95E2,0x9738,0x9739,0xF938,0x97FF,0x9867,0x9865,0x9957,/* 0x50-0x57 */
+	0x95E2,0x9738,0x9739,0x9732,0x97FF,0x9867,0x9865,0x9957,/* 0x50-0x57 */
 	0x9A45,0x9A43,0x9A40,0x9A3E,0x9ACF,0x9B54,0x9B51,0x9C2D,/* 0x58-0x5F */
-	0x9C25,0x9DAF,0xFA2D,0x9DC2,0x9DB8,0x9E9D,0x9EEF,0x9F19,/* 0x60-0x67 */
+	0x9C25,0x9DAF,0x9DB4,0x9DC2,0x9DB8,0x9E9D,0x9EEF,0x9F19,/* 0x60-0x67 */
 	0x9F5C,0x9F66,0x9F67,0x513C,0x513B,0x56C8,0x56CA,0x56C9,/* 0x68-0x6F */
 	0x5B7F,0x5DD4,0x5DD2,0x5F4E,0x61FF,0x6524,0x6B0A,0x6B61,/* 0x70-0x77 */
 	0x7051,0x7058,0x7380,0x74E4,0x758A,0x766E,0x766C,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x98-0x9F */
-	0x0000,0x79B3,0xF944,0x7C5F,0xF945,0x807D,0x81DF,0x8972,/* 0xA0-0xA7 */
-	0x896F,0x89FC,0xF95A,0x8D16,0x8D17,0x8E91,0x8E93,0x8F61,/* 0xA8-0xAF */
+	0x0000,0x79B3,0x7C60,0x7C5F,0x807E,0x807D,0x81DF,0x8972,/* 0xA0-0xA7 */
+	0x896F,0x89FC,0x8B80,0x8D16,0x8D17,0x8E91,0x8E93,0x8F61,/* 0xA8-0xAF */
 	0x9148,0x9444,0x9451,0x9452,0x973D,0x973E,0x97C3,0x97C1,/* 0xB0-0xB7 */
 	0x986B,0x9955,0x9A55,0x9A4D,0x9AD2,0x9B1A,0x9C49,0x9C31,/* 0xB8-0xBF */
 	0x9C3E,0x9C3B,0x9DD3,0x9DD7,0x9F34,0x9F6C,0x9F6A,0x9F94,/* 0xC0-0xC7 */
-	0x56CC,0x5DD6,0xF990,0x6523,0x652B,0x652A,0x66EC,0x6B10,/* 0xC8-0xCF */
+	0x56CC,0x5DD6,0x6200,0x6523,0x652B,0x652A,0x66EC,0x6B10,/* 0xC8-0xCF */
 	0x74DA,0x7ACA,0x7C64,0x7C63,0x7C65,0x7E93,0x7E96,0x7E94,/* 0xD0-0xD7 */
-	0x81E2,0x8638,0xF910,0x8831,0x8B8A,0x9090,0xF913,0x9463,/* 0xD8-0xDF */
+	0x81E2,0x8638,0x863F,0x8831,0x8B8A,0x9090,0x908F,0x9463,/* 0xD8-0xDF */
 	0x9460,0x9464,0x9768,0x986F,0x995C,0x9A5A,0x9A5B,0x9A57,/* 0xE0-0xE7 */
-	0x9AD3,0x9AD4,0x9AD1,0x9C54,0xF9F2,0x9C56,0x9DE5,0xF9F3,/* 0xE8-0xEF */
+	0x9AD3,0x9AD4,0x9AD1,0x9C54,0x9C57,0x9C56,0x9DE5,0x9E9F,/* 0xE8-0xEF */
 	0x9EF4,0x56D1,0x58E9,0x652C,0x705E,0x7671,0x7672,0x77D7,/* 0xF0-0xF7 */
 	0x7F50,0x7F88,0x8836,0x8839,0x8862,0x8B93,0x8B92,0x0000,/* 0xF8-0xFF */
 };
@@ -1354,14 +1351,14 @@
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x28-0x2F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x30-0x37 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x38-0x3F */
-	0x8B96,0x8277,0x8D1B,0x91C0,0x946A,0x9742,0xF9B3,0x9744,/* 0x40-0x47 */
-	0x97C6,0x9870,0x9A5F,0x9B22,0x9B58,0x9C5F,0x9DF9,0xF93A,/* 0x48-0x4F */
+	0x8B96,0x8277,0x8D1B,0x91C0,0x946A,0x9742,0x9748,0x9744,/* 0x40-0x47 */
+	0x97C6,0x9870,0x9A5F,0x9B22,0x9B58,0x9C5F,0x9DF9,0x9DFA,/* 0x48-0x4F */
 	0x9E7C,0x9E7D,0x9F07,0x9F77,0x9F72,0x5EF3,0x6B16,0x7063,/* 0x50-0x57 */
 	0x7C6C,0x7C6E,0x883B,0x89C0,0x8EA1,0x91C1,0x9472,0x9470,/* 0x58-0x5F */
 	0x9871,0x995E,0x9AD6,0x9B23,0x9ECC,0x7064,0x77DA,0x8B9A,/* 0x60-0x67 */
 	0x9477,0x97C9,0x9A62,0x9A65,0x7E9C,0x8B9C,0x8EAA,0x91C5,/* 0x68-0x6F */
 	0x947D,0x947E,0x947C,0x9C77,0x9C78,0x9EF7,0x8C54,0x947F,/* 0x70-0x77 */
-	0x9E1A,0x7228,0xF987,0x9B31,0x9E1B,0xF920,0x7C72,0x0000,/* 0x78-0x7F */
+	0x9E1A,0x7228,0x9A6A,0x9B31,0x9E1B,0x9E1E,0x7C72,0x0000,/* 0x78-0x7F */
 };
 
 static wchar_t c2u_C9[256] = {
@@ -1381,7 +1378,7 @@
 	0x4EE1,0x4EDD,0x4EDA,0x520C,0x531C,0x534C,0x5722,0x5723,/* 0x68-0x6F */
 	0x5917,0x592F,0x5B81,0x5B84,0x5C12,0x5C3B,0x5C74,0x5C73,/* 0x70-0x77 */
 	0x5E04,0x5E80,0x5E82,0x5FC9,0x6209,0x6250,0x6C15,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -1417,7 +1414,7 @@
 	0x4F3F,0x4F61,0x518F,0x51B9,0x521C,0x521E,0x5221,0x52AD,/* 0x68-0x6F */
 	0x52AE,0x5309,0x5363,0x5372,0x538E,0x538F,0x5430,0x5437,/* 0x70-0x77 */
 	0x542A,0x5454,0x5445,0x5419,0x541C,0x5425,0x5418,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -1453,7 +1450,7 @@
 	0x7395,0x7397,0x7393,0x7394,0x7392,0x753A,0x7539,0x7594,/* 0x68-0x6F */
 	0x7595,0x7681,0x793D,0x8034,0x8095,0x8099,0x8090,0x8092,/* 0x70-0x77 */
 	0x809C,0x8290,0x828F,0x8285,0x828E,0x8291,0x8293,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -1468,7 +1465,7 @@
 	0x533C,0x5392,0x5394,0x5487,0x547F,0x5481,0x5491,0x5482,/* 0xD8-0xDF */
 	0x5488,0x546B,0x547A,0x547E,0x5465,0x546C,0x5474,0x5466,/* 0xE0-0xE7 */
 	0x548D,0x546F,0x5461,0x5460,0x5498,0x5463,0x5467,0x5464,/* 0xE8-0xEF */
-	0x56F7,0xF9A9,0x576F,0x5772,0x576D,0x576B,0x5771,0x5770,/* 0xF0-0xF7 */
+	0x56F7,0x56F9,0x576F,0x5772,0x576D,0x576B,0x5771,0x5770,/* 0xF0-0xF7 */
 	0x5776,0x5780,0x5775,0x577B,0x5773,0x5774,0x5762,0x0000,/* 0xF8-0xFF */
 };
 
@@ -1489,19 +1486,19 @@
 	0x5C9D,0x5CA5,0x5CB6,0x5CB0,0x5CA6,0x5E17,0x5E14,0x5E19,/* 0x68-0x6F */
 	0x5F28,0x5F22,0x5F23,0x5F24,0x5F54,0x5F82,0x5F7E,0x5F7D,/* 0x70-0x77 */
 	0x5FDE,0x5FE5,0x602D,0x6026,0x6019,0x6032,0x600B,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x98-0x9F */
 	0x0000,0x6034,0x600A,0x6017,0x6033,0x601A,0x601E,0x602C,/* 0xA0-0xA7 */
 	0x6022,0x600D,0x6010,0x602E,0x6013,0x6011,0x600C,0x6009,/* 0xA8-0xAF */
-	0xF9AC,0x6214,0x623D,0x62AD,0x62B4,0x62D1,0x62BE,0x62AA,/* 0xB0-0xB7 */
+	0x601C,0x6214,0x623D,0x62AD,0x62B4,0x62D1,0x62BE,0x62AA,/* 0xB0-0xB7 */
 	0x62B6,0x62CA,0x62AE,0x62B3,0x62AF,0x62BB,0x62A9,0x62B0,/* 0xB8-0xBF */
 	0x62B8,0x653D,0x65A8,0x65BB,0x6609,0x65FC,0x6604,0x6612,/* 0xC0-0xC7 */
 	0x6608,0x65FB,0x6603,0x660B,0x660D,0x6605,0x65FD,0x6611,/* 0xC8-0xCF */
 	0x6610,0x66F6,0x670A,0x6785,0x676C,0x678E,0x6792,0x6776,/* 0xD0-0xD7 */
-	0xF9C8,0x6798,0x6786,0x6784,0x6774,0x678D,0x678C,0x677A,/* 0xD8-0xDF */
+	0x677B,0x6798,0x6786,0x6784,0x6774,0x678D,0x678C,0x677A,/* 0xD8-0xDF */
 	0x679F,0x6791,0x6799,0x6783,0x677D,0x6781,0x6778,0x6779,/* 0xE0-0xE7 */
 	0x6794,0x6B25,0x6B80,0x6B7E,0x6BDE,0x6C1D,0x6C93,0x6CEC,/* 0xE8-0xEF */
 	0x6CEB,0x6CEE,0x6CD9,0x6CB6,0x6CD4,0x6CAD,0x6CE7,0x6CB7,/* 0xF0-0xF7 */
@@ -1525,7 +1522,7 @@
 	0x73AD,0x73A6,0x73A2,0x73A0,0x73AC,0x739D,0x74DD,0x74E8,/* 0x68-0x6F */
 	0x753F,0x7540,0x753E,0x758C,0x7598,0x76AF,0x76F3,0x76F1,/* 0x70-0x77 */
 	0x76F0,0x76F5,0x77F8,0x77FC,0x77F9,0x77FB,0x77FA,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -1561,7 +1558,7 @@
 	0x59FA,0x59FD,0x59FC,0x59F6,0x59E4,0x59F2,0x59F7,0x59DB,/* 0x68-0x6F */
 	0x59E9,0x59F3,0x59F5,0x59E0,0x59FE,0x59F4,0x59ED,0x5BA8,/* 0x70-0x77 */
 	0x5C4C,0x5CD0,0x5CD8,0x5CCC,0x5CD7,0x5CCB,0x5CDB,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -1572,7 +1569,7 @@
 	0x5E9B,0x5EA3,0x5EA5,0x5F07,0x5F2E,0x5F56,0x5F86,0x6037,/* 0xB8-0xBF */
 	0x6039,0x6054,0x6072,0x605E,0x6045,0x6053,0x6047,0x6049,/* 0xC0-0xC7 */
 	0x605B,0x604C,0x6040,0x6042,0x605F,0x6024,0x6044,0x6058,/* 0xC8-0xCF */
-	0x6066,0x606E,0x6242,0x6243,0xF95B,0x630D,0x630B,0x62F5,/* 0xD0-0xD7 */
+	0x6066,0x606E,0x6242,0x6243,0x62CF,0x630D,0x630B,0x62F5,/* 0xD0-0xD7 */
 	0x630E,0x6303,0x62EB,0x62F9,0x630F,0x630C,0x62F8,0x62F6,/* 0xD8-0xDF */
 	0x6300,0x6313,0x6314,0x62FA,0x6315,0x62FB,0x62F0,0x6541,/* 0xE0-0xE7 */
 	0x6543,0x65AA,0x65BF,0x6636,0x6621,0x6632,0x6635,0x661C,/* 0xE8-0xEF */
@@ -1597,7 +1594,7 @@
 	0x6BD6,0x6BD8,0x6BE0,0x6C20,0x6C21,0x6D28,0x6D34,0x6D2D,/* 0x68-0x6F */
 	0x6D1F,0x6D3C,0x6D3F,0x6D12,0x6D0A,0x6CDA,0x6D33,0x6D04,/* 0x70-0x77 */
 	0x6D19,0x6D3A,0x6D1A,0x6D11,0x6D00,0x6D1D,0x6D42,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -1633,7 +1630,7 @@
 	0x81FF,0x8221,0x8294,0x82D9,0x82FE,0x82F9,0x8307,0x82E8,/* 0x68-0x6F */
 	0x8300,0x82D5,0x833A,0x82EB,0x82D6,0x82F4,0x82EC,0x82E1,/* 0x70-0x77 */
 	0x82F2,0x82F5,0x830C,0x82FB,0x82F6,0x82F0,0x82EA,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -1669,7 +1666,7 @@
 	0x5BAC,0x5C03,0x5C56,0x5C54,0x5CEC,0x5CFF,0x5CEE,0x5CF1,/* 0x68-0x6F */
 	0x5CF7,0x5D00,0x5CF9,0x5E29,0x5E28,0x5EA8,0x5EAE,0x5EAA,/* 0x70-0x77 */
 	0x5EAC,0x5F33,0x5F30,0x5F67,0x605D,0x605A,0x6067,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -1705,7 +1702,7 @@
 	0x6D75,0x6D90,0x70DC,0x70D3,0x70D1,0x70DD,0x70CB,0x7F39,/* 0x68-0x6F */
 	0x70E2,0x70D7,0x70D2,0x70DE,0x70E0,0x70D4,0x70CD,0x70C5,/* 0x70-0x77 */
 	0x70C6,0x70C7,0x70DA,0x70CE,0x70E1,0x7242,0x7278,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -1741,7 +1738,7 @@
 	0x8039,0x80FA,0x80F2,0x80F9,0x80F5,0x8101,0x80FB,0x8100,/* 0x68-0x6F */
 	0x8201,0x822F,0x8225,0x8333,0x832D,0x8344,0x8319,0x8351,/* 0x70-0x77 */
 	0x8325,0x8356,0x833F,0x8341,0x8326,0x831C,0x8322,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -1777,7 +1774,7 @@
 	0x51D0,0x526B,0x526D,0x526C,0x526E,0x52D6,0x52D3,0x532D,/* 0x68-0x6F */
 	0x539C,0x5575,0x5576,0x553C,0x554D,0x5550,0x5534,0x552A,/* 0x70-0x77 */
 	0x5551,0x5562,0x5536,0x5535,0x5530,0x5552,0x5545,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -1813,7 +1810,7 @@
 	0x638A,0x6382,0x637D,0x63BD,0x639E,0x63AD,0x639D,0x6397,/* 0x68-0x6F */
 	0x63AB,0x638E,0x636F,0x6387,0x6390,0x636E,0x63AF,0x6375,/* 0x70-0x77 */
 	0x639C,0x636D,0x63AE,0x637C,0x63A4,0x633B,0x639F,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -1849,7 +1846,7 @@
 	0x730F,0x731E,0x7388,0x73F6,0x73F8,0x73F5,0x7404,0x7401,/* 0x68-0x6F */
 	0x73FD,0x7407,0x7400,0x73FA,0x73FC,0x73FF,0x740C,0x740B,/* 0x70-0x77 */
 	0x73F4,0x7408,0x7564,0x7563,0x75CE,0x75D2,0x75CF,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -1885,7 +1882,7 @@
 	0x837D,0x8383,0x838C,0x839D,0x839B,0x83AA,0x838B,0x837E,/* 0x68-0x6F */
 	0x83A5,0x83AF,0x8388,0x8397,0x83B0,0x837F,0x83A6,0x8387,/* 0x70-0x77 */
 	0x83AE,0x8376,0x839A,0x8659,0x8656,0x86BF,0x86B7,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -1921,7 +1918,7 @@
 	0x55A5,0x55AD,0x5577,0x5645,0x55A2,0x5593,0x5588,0x558F,/* 0x68-0x6F */
 	0x55B5,0x5581,0x55A3,0x5592,0x55A4,0x557D,0x558C,0x55A6,/* 0x70-0x77 */
 	0x557F,0x5595,0x55A1,0x558E,0x570C,0x5829,0x5837,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -1957,7 +1954,7 @@
 	0x63D8,0x63D3,0x63C2,0x63C7,0x63CC,0x63CB,0x63C8,0x63F0,/* 0x68-0x6F */
 	0x63D7,0x63D9,0x6532,0x6567,0x656A,0x6564,0x655C,0x6568,/* 0x70-0x77 */
 	0x6565,0x658C,0x659D,0x659E,0x65AE,0x65D0,0x65D2,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -1993,7 +1990,7 @@
 	0x7288,0x7289,0x7286,0x7285,0x728B,0x7312,0x730B,0x7330,/* 0x68-0x6F */
 	0x7322,0x7331,0x7333,0x7327,0x7332,0x732D,0x7326,0x7323,/* 0x70-0x77 */
 	0x7335,0x730C,0x742E,0x742C,0x7430,0x742B,0x7416,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -2027,9 +2024,9 @@
 	0x823C,0x823D,0x823F,0x8275,0x833B,0x83CF,0x83F9,0x8423,/* 0x58-0x5F */
 	0x83C0,0x83E8,0x8412,0x83E7,0x83E4,0x83FC,0x83F6,0x8410,/* 0x60-0x67 */
 	0x83C6,0x83C8,0x83EB,0x83E3,0x83BF,0x8401,0x83DD,0x83E5,/* 0x68-0x6F */
-	0x83D8,0x83FF,0x83E1,0x83CB,0x83CE,0x83D6,0x83F5,0xF93E,/* 0x70-0x77 */
+	0x83D8,0x83FF,0x83E1,0x83CB,0x83CE,0x83D6,0x83F5,0x83C9,/* 0x70-0x77 */
 	0x8409,0x840F,0x83DE,0x8411,0x8406,0x83C2,0x83F3,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -2065,7 +2062,7 @@
 	0x920F,0x920C,0x9200,0x9212,0x91FF,0x91FD,0x9206,0x9204,/* 0x68-0x6F */
 	0x9227,0x9202,0x921C,0x9224,0x9219,0x9217,0x9205,0x9216,/* 0x70-0x77 */
 	0x957B,0x958D,0x958C,0x9590,0x9687,0x967E,0x9688,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -2101,7 +2098,7 @@
 	0x612B,0x6145,0x6136,0x6132,0x612E,0x6146,0x612F,0x614F,/* 0x68-0x6F */
 	0x6129,0x6140,0x6220,0x9168,0x6223,0x6225,0x6224,0x63C5,/* 0x70-0x77 */
 	0x63F1,0x63EB,0x6410,0x6412,0x6409,0x6420,0x6424,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -2137,7 +2134,7 @@
 	0x6E97,0x6EAE,0x6EA3,0x7147,0x7154,0x7152,0x7163,0x7160,/* 0x68-0x6F */
 	0x7141,0x715D,0x7162,0x7172,0x7178,0x716A,0x7161,0x7142,/* 0x70-0x77 */
 	0x7158,0x7143,0x714B,0x7170,0x715F,0x7150,0x7153,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -2173,7 +2170,7 @@
 	0x7F6B,0x7F67,0x7F68,0x7F6C,0x7FA6,0x7FA5,0x7FA7,0x7FDB,/* 0x68-0x6F */
 	0x7FDC,0x8021,0x8164,0x8160,0x8177,0x815C,0x8169,0x815B,/* 0x70-0x77 */
 	0x8162,0x8172,0x6721,0x815E,0x8176,0x8167,0x816F,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -2209,7 +2206,7 @@
 	0x8DE0,0x8DEC,0x8DF1,0x8DEE,0x8DD0,0x8DE9,0x8DE3,0x8DE2,/* 0x68-0x6F */
 	0x8DE7,0x8DF2,0x8DEB,0x8DF4,0x8F06,0x8EFF,0x8F01,0x8F00,/* 0x70-0x77 */
 	0x8F05,0x8F07,0x8F08,0x8F02,0x8F0B,0x9052,0x903F,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -2245,7 +2242,7 @@
 	0x588F,0x58FE,0x596B,0x5ADC,0x5AEE,0x5AE5,0x5AD5,0x5AEA,/* 0x68-0x6F */
 	0x5ADA,0x5AED,0x5AEB,0x5AF3,0x5AE2,0x5AE0,0x5ADB,0x5AEC,/* 0x70-0x77 */
 	0x5ADE,0x5ADD,0x5AD9,0x5AE8,0x5ADF,0x5B77,0x5BE0,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -2281,7 +2278,7 @@
 	0x6BA0,0x6BC3,0x6BC4,0x6BFE,0x6ECE,0x6EF5,0x6EF1,0x6F03,/* 0x68-0x6F */
 	0x6F25,0x6EF8,0x6F37,0x6EFB,0x6F2E,0x6F09,0x6F4E,0x6F19,/* 0x70-0x77 */
 	0x6F1A,0x6F27,0x6F18,0x6F3B,0x6F12,0x6EED,0x6F0A,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -2317,7 +2314,7 @@
 	0x7DC0,0x7DC5,0x7D9D,0x7DCE,0x7DC4,0x7DC6,0x7DCB,0x7DCC,/* 0x68-0x6F */
 	0x7DAF,0x7DB9,0x7D96,0x7DBC,0x7D9F,0x7DA6,0x7DAE,0x7DA9,/* 0x70-0x77 */
 	0x7DA1,0x7DC9,0x7F73,0x7FE2,0x7FE3,0x7FE5,0x7FDE,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -2353,7 +2350,7 @@
 	0x9123,0x911C,0x9120,0x9122,0x911F,0x911D,0x911A,0x9124,/* 0x68-0x6F */
 	0x9121,0x911B,0x917A,0x9172,0x9179,0x9173,0x92A5,0x92A4,/* 0x70-0x77 */
 	0x9276,0x929B,0x927A,0x92A0,0x9294,0x92AA,0x928D,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -2389,7 +2386,7 @@
 	0x5D95,0x5DA0,0x5D9C,0x5DA1,0x5D9A,0x5D9E,0x5E69,0x5E5D,/* 0x68-0x6F */
 	0x5E60,0x5E5C,0x7DF3,0x5EDB,0x5EDE,0x5EE1,0x5F49,0x5FB2,/* 0x70-0x77 */
 	0x618B,0x6183,0x6179,0x61B1,0x61B0,0x61A2,0x6189,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -2425,12 +2422,12 @@
 	0x71A9,0x71B5,0x719D,0x71A5,0x719E,0x71A4,0x71A1,0x71AA,/* 0x68-0x6F */
 	0x719C,0x71A7,0x71B3,0x7298,0x729A,0x7358,0x7352,0x735E,/* 0x70-0x77 */
 	0x735F,0x7360,0x735D,0x735B,0x7361,0x735A,0x7359,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x98-0x9F */
-	0x0000,0x7362,0x7487,0xF994,0x748A,0x7486,0x7481,0x747D,/* 0xA0-0xA7 */
+	0x0000,0x7362,0x7487,0x7489,0x748A,0x7486,0x7481,0x747D,/* 0xA0-0xA7 */
 	0x7485,0x7488,0x747C,0x7479,0x7508,0x7507,0x757E,0x7625,/* 0xA8-0xAF */
 	0x761E,0x7619,0x761D,0x761C,0x7623,0x761A,0x7628,0x761B,/* 0xB0-0xB7 */
 	0x769C,0x769D,0x769E,0x769B,0x778D,0x778F,0x7789,0x7788,/* 0xB8-0xBF */
@@ -2457,11 +2454,11 @@
 	0x8252,0x8250,0x824E,0x8251,0x8524,0x853B,0x850F,0x8500,/* 0x48-0x4F */
 	0x8529,0x850E,0x8509,0x850D,0x851F,0x850A,0x8527,0x851C,/* 0x50-0x57 */
 	0x84FB,0x852B,0x84FA,0x8508,0x850C,0x84F4,0x852A,0x84F2,/* 0x58-0x5F */
-	0x8515,0x84F7,0x84EB,0x84F3,0xF9C2,0x8512,0x84EA,0x84E9,/* 0x60-0x67 */
+	0x8515,0x84F7,0x84EB,0x84F3,0x84FC,0x8512,0x84EA,0x84E9,/* 0x60-0x67 */
 	0x8516,0x84FE,0x8528,0x851D,0x852E,0x8502,0x84FD,0x851E,/* 0x68-0x6F */
 	0x84F6,0x8531,0x8526,0x84E7,0x84E8,0x84F0,0x84EF,0x84F9,/* 0x70-0x77 */
 	0x8518,0x8520,0x8530,0x850B,0x8519,0x852F,0x8662,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -2497,7 +2494,7 @@
 	0x92CF,0x92F1,0x92DF,0x92D8,0x92E9,0x92D7,0x92DD,0x92CC,/* 0x68-0x6F */
 	0x92EF,0x92C2,0x92E8,0x92CA,0x92C8,0x92CE,0x92E6,0x92CD,/* 0x70-0x77 */
 	0x92D5,0x92C9,0x92E0,0x92DE,0x92E7,0x92D1,0x92D3,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -2513,7 +2510,7 @@
 	0x9B70,0x9B68,0x9B64,0x9B6C,0x9CFC,0x9CFA,0x9CFD,0x9CFF,/* 0xE0-0xE7 */
 	0x9CF7,0x9D07,0x9D00,0x9CF9,0x9CFB,0x9D08,0x9D05,0x9D04,/* 0xE8-0xEF */
 	0x9E83,0x9ED3,0x9F0F,0x9F10,0x511C,0x5113,0x5117,0x511A,/* 0xF0-0xF7 */
-	0x5111,0xFA15,0x5334,0x53E1,0x5670,0x5660,0x566E,0x0000,/* 0xF8-0xFF */
+	0x5111,0x51DE,0x5334,0x53E1,0x5670,0x5660,0x566E,0x0000,/* 0xF8-0xFF */
 };
 
 static wchar_t c2u_E9[256] = {
@@ -2533,7 +2530,7 @@
 	0x5DAD,0x5DAF,0x5DB4,0x5E67,0x5E68,0x5E66,0x5E6F,0x5EE9,/* 0x68-0x6F */
 	0x5EE7,0x5EE6,0x5EE8,0x5EE5,0x5F4B,0x5FBC,0x619D,0x61A8,/* 0x70-0x77 */
 	0x6196,0x61C5,0x61B4,0x61C6,0x61C1,0x61CC,0x61BA,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -2569,7 +2566,7 @@
 	0x74A1,0x750B,0x7580,0x762F,0x762D,0x7631,0x763D,0x7633,/* 0x68-0x6F */
 	0x763C,0x7635,0x7632,0x7630,0x76BB,0x76E6,0x779A,0x779D,/* 0x70-0x77 */
 	0x77A1,0x779C,0x779B,0x77A2,0x77A3,0x7795,0x7799,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -2605,7 +2602,7 @@
 	0x8790,0x8791,0x879D,0x8784,0x8794,0x879C,0x879A,0x8789,/* 0x68-0x6F */
 	0x891E,0x8926,0x8930,0x892D,0x892E,0x8927,0x8931,0x8922,/* 0x70-0x77 */
 	0x8929,0x8923,0x892F,0x892C,0x891F,0x89F1,0x8AE0,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -2641,7 +2638,7 @@
 	0x99E9,0x99E7,0x9AB9,0x9ABF,0x9AB4,0x9ABB,0x9AF6,0x9AFA,/* 0x68-0x6F */
 	0x9AF9,0x9AF7,0x9B33,0x9B80,0x9B85,0x9B87,0x9B7C,0x9B7E,/* 0x70-0x77 */
 	0x9B7B,0x9B82,0x9B93,0x9B92,0x9B90,0x9B7A,0x9B95,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -2677,13 +2674,13 @@
 	0x74AB,0x7490,0x74AA,0x74AD,0x74B1,0x74A5,0x74AF,0x7510,/* 0x68-0x6F */
 	0x7511,0x7512,0x750F,0x7584,0x7643,0x7648,0x7649,0x7647,/* 0x70-0x77 */
 	0x76A4,0x76E9,0x77B5,0x77AB,0x77B2,0x77B7,0x77B6,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x98-0x9F */
 	0x0000,0x77B4,0x77B1,0x77A8,0x77F0,0x78F3,0x78FD,0x7902,/* 0xA0-0xA7 */
-	0xF964,0x78FC,0x78F2,0x7905,0x78F9,0x78FE,0x7904,0x79AB,/* 0xA8-0xAF */
+	0x78FB,0x78FC,0x78F2,0x7905,0x78F9,0x78FE,0x7904,0x79AB,/* 0xA8-0xAF */
 	0x79A8,0x7A5C,0x7A5B,0x7A56,0x7A58,0x7A54,0x7A5A,0x7ABE,/* 0xB0-0xB7 */
 	0x7AC0,0x7AC1,0x7C05,0x7C0F,0x7BF2,0x7C00,0x7BFF,0x7BFB,/* 0xB8-0xBF */
 	0x7C0E,0x7BF4,0x7C0B,0x7BF3,0x7C02,0x7C09,0x7C03,0x7C01,/* 0xC0-0xC7 */
@@ -2713,7 +2710,7 @@
 	0x87C4,0x87CA,0x87B4,0x87B6,0x87BF,0x87B8,0x87BD,0x87DE,/* 0x68-0x6F */
 	0x87B2,0x8935,0x8933,0x893C,0x893E,0x8941,0x8952,0x8937,/* 0x70-0x77 */
 	0x8942,0x89AD,0x89AF,0x89AE,0x89F2,0x89F3,0x8B1E,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -2749,7 +2746,7 @@
 	0x9AFC,0x9B48,0x9B9A,0x9BA8,0x9B9E,0x9B9B,0x9BA6,0x9BA1,/* 0x68-0x6F */
 	0x9BA5,0x9BA4,0x9B86,0x9BA2,0x9BA0,0x9BAF,0x9D33,0x9D41,/* 0x70-0x77 */
 	0x9D67,0x9D36,0x9D2E,0x9D2F,0x9D31,0x9D38,0x9D30,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -2785,7 +2782,7 @@
 	0x7C26,0x7C28,0x7C22,0x7C25,0x7C30,0x7E5C,0x7E50,0x7E56,/* 0x68-0x6F */
 	0x7E63,0x7E58,0x7E62,0x7E5F,0x7E51,0x7E60,0x7E57,0x7E53,/* 0x70-0x77 */
 	0x7FB5,0x7FB3,0x7FF7,0x7FF8,0x8075,0x81D1,0x81D2,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -2821,7 +2818,7 @@
 	0x93A8,0x93B4,0x93A3,0x93A5,0x95D2,0x95D3,0x95D1,0x96B3,/* 0x68-0x6F */
 	0x96D7,0x96DA,0x5DC2,0x96DF,0x96D8,0x96DD,0x9723,0x9722,/* 0x70-0x77 */
 	0x9725,0x97AC,0x97AE,0x97A8,0x97AB,0x97A4,0x97AA,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -2857,7 +2854,7 @@
 	0x702A,0x720C,0x720A,0x7207,0x7202,0x7205,0x72A5,0x72A6,/* 0x68-0x6F */
 	0x72A4,0x72A3,0x72A1,0x74CB,0x74C5,0x74B7,0x74C3,0x7516,/* 0x70-0x77 */
 	0x7660,0x77C9,0x77CA,0x77C4,0x77F1,0x791D,0x791B,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -2893,7 +2890,7 @@
 	0x93CC,0x93D9,0x93A9,0x93E6,0x93CA,0x93D4,0x93EE,0x93E3,/* 0x68-0x6F */
 	0x93D5,0x93C4,0x93CE,0x93C0,0x93D2,0x93E7,0x957D,0x95DA,/* 0x70-0x77 */
 	0x95DB,0x96E1,0x9729,0x972B,0x972C,0x9728,0x9726,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -2929,7 +2926,7 @@
 	0x7033,0x7041,0x7213,0x7214,0x72A8,0x737D,0x737C,0x74BA,/* 0x68-0x6F */
 	0x76AB,0x76AA,0x76BE,0x76ED,0x77CC,0x77CE,0x77CF,0x77CD,/* 0x70-0x77 */
 	0x77F2,0x7925,0x7923,0x7927,0x7928,0x7924,0x7929,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -2965,7 +2962,7 @@
 	0x9B12,0x9B11,0x9C0B,0x9C08,0x9BF7,0x9C05,0x9C12,0x9BF8,/* 0x68-0x6F */
 	0x9C40,0x9C07,0x9C0E,0x9C06,0x9C17,0x9C14,0x9C09,0x9D9F,/* 0x70-0x77 */
 	0x9D99,0x9DA4,0x9D9D,0x9D92,0x9D98,0x9D90,0x9D9B,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -3001,7 +2998,7 @@
 	0x942C,0x9440,0x9431,0x95E5,0x95E4,0x95E3,0x9735,0x973A,/* 0x68-0x6F */
 	0x97BF,0x97E1,0x9864,0x98C9,0x98C6,0x98C0,0x9958,0x9956,/* 0x70-0x77 */
 	0x9A39,0x9A3D,0x9A46,0x9A44,0x9A42,0x9A41,0x9A3A,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -3033,11 +3030,11 @@
 	0x8635,0x8633,0x862C,0x8632,0x8636,0x882C,0x8828,0x8826,/* 0x48-0x4F */
 	0x882A,0x8825,0x8971,0x89BF,0x89BE,0x89FB,0x8B7E,0x8B84,/* 0x50-0x57 */
 	0x8B82,0x8B86,0x8B85,0x8B7F,0x8D15,0x8E95,0x8E94,0x8E9A,/* 0x58-0x5F */
-	0x8E92,0x8E90,0x8E96,0x8E97,0x8F60,0xF98D,0x9147,0x944C,/* 0x60-0x67 */
+	0x8E92,0x8E90,0x8E96,0x8E97,0x8F60,0x8F62,0x9147,0x944C,/* 0x60-0x67 */
 	0x9450,0x944A,0x944B,0x944F,0x9447,0x9445,0x9448,0x9449,/* 0x68-0x6F */
 	0x9446,0x973F,0x97E3,0x986A,0x9869,0x98CB,0x9954,0x995B,/* 0x70-0x77 */
 	0x9A4E,0x9A53,0x9A54,0x9A4C,0x9A4F,0x9A48,0x9A4A,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -3073,7 +3070,7 @@
 	0x9DF6,0x9DE1,0x9DEE,0x9DE6,0x9DF2,0x9DF0,0x9DE2,0x9DEC,/* 0x68-0x6F */
 	0x9DF4,0x9DF3,0x9DE8,0x9DED,0x9EC2,0x9ED0,0x9EF2,0x9EF3,/* 0x70-0x77 */
 	0x9F06,0x9F1C,0x9F38,0x9F37,0x9F36,0x9F43,0x9F4F,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -3109,7 +3106,7 @@
 	0x9F7B,0x9F7A,0x9F79,0x571E,0x7066,0x7C6F,0x883C,0x8DB2,/* 0x68-0x6F */
 	0x8EA6,0x91C3,0x9474,0x9478,0x9476,0x9475,0x9A60,0x9C74,/* 0x70-0x77 */
 	0x9C73,0x9C71,0x9C75,0x9E14,0x9E13,0x9EF6,0x9F0A,0x0000,/* 0x78-0x7F */
-	
+
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x80-0x87 */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x88-0x8F */
 	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x90-0x97 */
@@ -3125,7 +3122,7 @@
 	0x2560,0x256C,0x2563,0x255A,0x2569,0x255D,0x2552,0x2564,/* 0xE0-0xE7 */
 	0x2555,0x255E,0x256A,0x2561,0x2558,0x2567,0x255B,0x2553,/* 0xE8-0xEF */
 	0x2565,0x2556,0x255F,0x256B,0x2562,0x2559,0x2568,0x255C,/* 0xF0-0xF7 */
-	0x2551,0x2550,0x0000,0x0000,0x0000,0x0000,0x2593,0x0000,/* 0xF8-0xFF */
+	0x2551,0x2550,0x256D,0x256E,0x2570,0x256F,0x2593,0x0000,/* 0xF8-0xFF */
 };
 
 static wchar_t *page_charset2uni[256] = {
diff -Nru a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog
--- a/fs/ntfs/ChangeLog	2005-03-01 23:38:54 -08:00
+++ b/fs/ntfs/ChangeLog	2005-03-01 23:38:54 -08:00
@@ -25,6 +25,13 @@
 	- Enable the code for setting the NT4 compatibility flag when we start
 	  making NTFS 1.2 specific modifications.
 
+2.1.23-WIP
+
+	- 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.
+
 2.1.22 - Many bug and race fixes and error handling improvements.
 
 	- Improve error handling in fs/ntfs/inode.c::ntfs_truncate().
diff -Nru a/fs/ntfs/aops.c b/fs/ntfs/aops.c
--- a/fs/ntfs/aops.c	2005-03-01 23:39:08 -08:00
+++ b/fs/ntfs/aops.c	2005-03-01 23:39:08 -08:00
@@ -55,7 +55,7 @@
  */
 static void ntfs_end_buffer_async_read(struct buffer_head *bh, int uptodate)
 {
-	static spinlock_t page_uptodate_lock = SPIN_LOCK_UNLOCKED;
+	static DEFINE_SPINLOCK(page_uptodate_lock);
 	unsigned long flags;
 	struct buffer_head *tmp;
 	struct page *page;
diff -Nru a/fs/ntfs/compress.c b/fs/ntfs/compress.c
--- a/fs/ntfs/compress.c	2005-03-01 23:38:57 -08:00
+++ b/fs/ntfs/compress.c	2005-03-01 23:38:57 -08:00
@@ -62,7 +62,7 @@
 /**
  * ntfs_cb_lock - spinlock which protects ntfs_compression_buffer
  */
-static spinlock_t ntfs_cb_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(ntfs_cb_lock);
 
 /**
  * allocate_compression_buffers - allocate the decompression buffers
diff -Nru a/fs/ntfs/debug.c b/fs/ntfs/debug.c
--- a/fs/ntfs/debug.c	2005-03-01 23:39:18 -08:00
+++ b/fs/ntfs/debug.c	2005-03-01 23:39:18 -08:00
@@ -26,7 +26,7 @@
  * to protect concurrent accesses to it.
  */
 static char err_buf[1024];
-static spinlock_t err_buf_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(err_buf_lock);
 
 /**
  * __ntfs_warning - output a warning to the syslog
@@ -53,6 +53,10 @@
 	va_list args;
 	int flen = 0;
 
+#ifndef DEBUG
+	if (!printk_ratelimit())
+		return;
+#endif
 	if (function)
 		flen = strlen(function);
 	spin_lock(&err_buf_lock);
@@ -93,6 +97,10 @@
 	va_list args;
 	int flen = 0;
 
+#ifndef DEBUG
+	if (!printk_ratelimit())
+		return;
+#endif
 	if (function)
 		flen = strlen(function);
 	spin_lock(&err_buf_lock);
diff -Nru a/fs/ntfs/mft.c b/fs/ntfs/mft.c
--- a/fs/ntfs/mft.c	2005-03-01 23:39:07 -08:00
+++ b/fs/ntfs/mft.c	2005-03-01 23:39:07 -08:00
@@ -2605,7 +2605,8 @@
 			vi->i_mode &= ~S_IWUGO;
 
 		/* Set the inode times to the current time. */
-		vi->i_atime = vi->i_mtime = vi->i_ctime = current_kernel_time();
+		vi->i_atime = vi->i_mtime = vi->i_ctime =
+			current_fs_time(vi->i_sb);
 		/*
 		 * Set the file size to 0, the ntfs inode sizes are set to 0 by
 		 * the call to ntfs_init_big_inode() below.
diff -Nru a/fs/ntfs/super.c b/fs/ntfs/super.c
--- a/fs/ntfs/super.c	2005-03-01 23:39:07 -08:00
+++ b/fs/ntfs/super.c	2005-03-01 23:39:07 -08:00
@@ -2392,6 +2392,8 @@
 	 */
 	sb->s_maxbytes = MAX_LFS_FILESIZE;
 
+	sb->s_time_gran = 100;
+
 	/*
 	 * Now load the metadata required for the page cache and our address
 	 * space operations to function. We do this by setting up a specialised
diff -Nru a/fs/open.c b/fs/open.c
--- a/fs/open.c	2005-03-01 23:38:51 -08:00
+++ b/fs/open.c	2005-03-01 23:38:51 -08:00
@@ -203,10 +203,9 @@
 
 	newattrs.ia_size = length;
 	newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
+
 	down(&dentry->d_inode->i_sem);
-	down_write(&dentry->d_inode->i_alloc_sem);
 	err = notify_change(dentry, &newattrs);
-	up_write(&dentry->d_inode->i_alloc_sem);
 	up(&dentry->d_inode->i_sem);
 	return err;
 }
@@ -856,26 +855,18 @@
 	if (fd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
 		goto out;
 
-	/* Do we need to expand the fdset array? */
-	if (fd >= files->max_fdset) {
-		error = expand_fdset(files, fd);
-		if (!error) {
-			error = -EMFILE;
-			goto repeat;
-		}
-		goto out;
-	}
-	
-	/* 
-	 * Check whether we need to expand the fd array.
-	 */
-	if (fd >= files->max_fds) {
-		error = expand_fd_array(files, fd);
-		if (!error) {
-			error = -EMFILE;
-			goto repeat;
-		}
+	/* Do we need to expand the fd array or fd set?  */
+	error = expand_files(files, fd);
+	if (error < 0)
 		goto out;
+
+	if (error) {
+		/*
+	 	 * If we needed to expand the fs array we
+		 * might have blocked - try again.
+		 */
+		error = -EMFILE;
+		goto repeat;
 	}
 
 	FD_SET(fd, files->open_fds);
diff -Nru a/fs/openpromfs/inode.c b/fs/openpromfs/inode.c
--- a/fs/openpromfs/inode.c	2005-03-01 23:38:57 -08:00
+++ b/fs/openpromfs/inode.c	2005-03-01 23:38:57 -08:00
@@ -94,8 +94,6 @@
 	openprom_property *op;
 	char buffer[64];
 	
-	if (*ppos >= 0xffffff || count >= 0xffffff)
-		return -EINVAL;
 	if (!filp->private_data) {
 		node = nodes[(u16)((long)inode->u.generic_ip)].node;
 		i = ((u32)(long)inode->u.generic_ip) >> 16;
@@ -168,6 +166,8 @@
 		op = (openprom_property *)filp->private_data;
 	if (!count || !(op->len || (op->flag & OPP_ASCIIZ)))
 		return 0;
+	if (*ppos >= 0xffffff || count >= 0xffffff)
+		return -EINVAL;
 	if (op->flag & OPP_STRINGLIST) {
 		for (k = 0, p = op->value; p < op->value + op->len; p++)
 			if (!*p)
@@ -1039,6 +1039,7 @@
 	s->s_blocksize_bits = 10;
 	s->s_magic = OPENPROM_SUPER_MAGIC;
 	s->s_op = &openprom_sops;
+	s->s_time_gran = 1;
 	root_inode = iget(s, OPENPROM_ROOT_INO);
 	if (!root_inode)
 		goto out_no_root;
diff -Nru a/fs/partitions/Kconfig b/fs/partitions/Kconfig
--- a/fs/partitions/Kconfig	2005-03-01 23:39:10 -08:00
+++ b/fs/partitions/Kconfig	2005-03-01 23:39:10 -08:00
@@ -188,14 +188,14 @@
 
 config SGI_PARTITION
 	bool "SGI partition support" if PARTITION_ADVANCED
-	default y if (SGI_IP22 || SGI_IP27)
+	default y if (SGI_IP22 || SGI_IP27 || ((MACH_JAZZ || SNI_RM200_PCI) && !CPU_LITTLE_ENDIAN))
 	help
 	  Say Y here if you would like to be able to read the hard disk
 	  partition table format used by SGI machines.
 
 config ULTRIX_PARTITION
 	bool "Ultrix partition table support" if PARTITION_ADVANCED
-	default y if DECSTATION
+	default y if MACH_DECSTATION
 	help
 	  Say Y here if you would like to be able to read the hard disk
 	  partition table format used by DEC (now Compaq) Ultrix machines.
diff -Nru a/fs/partitions/check.c b/fs/partitions/check.c
--- a/fs/partitions/check.c	2005-03-01 23:39:16 -08:00
+++ b/fs/partitions/check.c	2005-03-01 23:39:16 -08:00
@@ -73,6 +73,9 @@
 #ifdef CONFIG_EFI_PARTITION
 	efi_partition,		/* this must come before msdos */
 #endif
+#ifdef CONFIG_SGI_PARTITION
+	sgi_partition,
+#endif
 #ifdef CONFIG_LDM_PARTITION
 	ldm_partition,		/* this must come before msdos */
 #endif
@@ -96,9 +99,6 @@
 #endif
 #ifdef CONFIG_MAC_PARTITION
 	mac_partition,
-#endif
-#ifdef CONFIG_SGI_PARTITION
-	sgi_partition,
 #endif
 #ifdef CONFIG_ULTRIX_PARTITION
 	ultrix_partition,
diff -Nru a/fs/partitions/ibm.c b/fs/partitions/ibm.c
--- a/fs/partitions/ibm.c	2005-03-01 23:39:17 -08:00
+++ b/fs/partitions/ibm.c	2005-03-01 23:39:17 -08:00
@@ -114,7 +114,8 @@
 		}
 		put_partition(state, 1, offset*(blocksize >> 9),
 				 size-offset*(blocksize >> 9));
-	} else if (strncmp(type, "VOL1", 4) == 0) {
+	} else if ((strncmp(type, "VOL1", 4) == 0) &&
+		(!info->FBA_layout) && (!strcmp(info->type, "ECKD"))) {
 		/*
 		 * New style VOL1 labeled disk
 		 */
diff -Nru a/fs/partitions/sgi.c b/fs/partitions/sgi.c
--- a/fs/partitions/sgi.c	2005-03-01 23:38:53 -08:00
+++ b/fs/partitions/sgi.c	2005-03-01 23:38:53 -08:00
@@ -69,8 +69,12 @@
 	for(i = 0; i < 16; i++, p++) {
 		blocks = be32_to_cpu(p->num_blocks);
 		start  = be32_to_cpu(p->first_block);
-		if (blocks)
-			put_partition(state, slot++, start, blocks);
+		if (blocks) {
+			put_partition(state, slot, start, blocks);
+			if (be32_to_cpu(p->type) == LINUX_RAID_PARTITION)
+				state->parts[slot].flags = 1;
+		}
+		slot++;
 	}
 	printk("\n");
 	put_dev_sector(sect);
diff -Nru a/fs/pipe.c b/fs/pipe.c
--- a/fs/pipe.c	2005-03-01 23:38:58 -08:00
+++ b/fs/pipe.c	2005-03-01 23:38:58 -08:00
@@ -14,6 +14,8 @@
 #include <linux/mount.h>
 #include <linux/pipe_fs_i.h>
 #include <linux/uio.h>
+#include <linux/highmem.h>
+
 #include <asm/uaccess.h>
 #include <asm/ioctls.h>
 
@@ -84,11 +86,40 @@
 	return 0;
 }
 
+static void anon_pipe_buf_release(struct pipe_inode_info *info, struct pipe_buffer *buf)
+{
+	struct page *page = buf->page;
+
+	if (info->tmp_page) {
+		__free_page(page);
+		return;
+	}
+	info->tmp_page = page;
+}
+
+static void *anon_pipe_buf_map(struct file *file, struct pipe_inode_info *info, struct pipe_buffer *buf)
+{
+	return kmap(buf->page);
+}
+
+static void anon_pipe_buf_unmap(struct pipe_inode_info *info, struct pipe_buffer *buf)
+{
+	kunmap(buf->page);
+}
+
+static struct pipe_buf_operations anon_pipe_buf_ops = {
+	.can_merge = 1,
+	.map = anon_pipe_buf_map,
+	.unmap = anon_pipe_buf_unmap,
+	.release = anon_pipe_buf_release,
+};
+
 static ssize_t
 pipe_readv(struct file *filp, const struct iovec *_iov,
 	   unsigned long nr_segs, loff_t *ppos)
 {
 	struct inode *inode = filp->f_dentry->d_inode;
+	struct pipe_inode_info *info;
 	int do_wakeup;
 	ssize_t ret;
 	struct iovec *iov = (struct iovec *)_iov;
@@ -102,32 +133,43 @@
 	do_wakeup = 0;
 	ret = 0;
 	down(PIPE_SEM(*inode));
+	info = inode->i_pipe;
 	for (;;) {
-		int size = PIPE_LEN(*inode);
-		if (size) {
-			char *pipebuf = PIPE_BASE(*inode) + PIPE_START(*inode);
-			ssize_t chars = PIPE_MAX_RCHUNK(*inode);
+		int bufs = info->nrbufs;
+		if (bufs) {
+			int curbuf = info->curbuf;
+			struct pipe_buffer *buf = info->bufs + curbuf;
+			struct pipe_buf_operations *ops = buf->ops;
+			void *addr;
+			size_t chars = buf->len;
+			int error;
 
 			if (chars > total_len)
 				chars = total_len;
-			if (chars > size)
-				chars = size;
 
-			if (pipe_iov_copy_to_user(iov, pipebuf, chars)) {
+			addr = ops->map(filp, info, buf);
+			error = pipe_iov_copy_to_user(iov, addr + buf->offset, chars);
+			ops->unmap(info, buf);
+			if (unlikely(error)) {
 				if (!ret) ret = -EFAULT;
 				break;
 			}
 			ret += chars;
-
-			PIPE_START(*inode) += chars;
-			PIPE_START(*inode) &= (PIPE_SIZE - 1);
-			PIPE_LEN(*inode) -= chars;
+			buf->offset += chars;
+			buf->len -= chars;
+			if (!buf->len) {
+				buf->ops = NULL;
+				ops->release(info, buf);
+				curbuf = (curbuf + 1) & (PIPE_BUFFERS-1);
+				info->curbuf = curbuf;
+				info->nrbufs = --bufs;
+				do_wakeup = 1;
+			}
 			total_len -= chars;
-			do_wakeup = 1;
 			if (!total_len)
 				break;	/* common path: read succeeded */
 		}
-		if (PIPE_LEN(*inode)) /* test for cyclic buffers */
+		if (bufs)	/* More to do? */
 			continue;
 		if (!PIPE_WRITERS(*inode))
 			break;
@@ -177,8 +219,8 @@
 	    unsigned long nr_segs, loff_t *ppos)
 {
 	struct inode *inode = filp->f_dentry->d_inode;
+	struct pipe_inode_info *info;
 	ssize_t ret;
-	size_t min;
 	int do_wakeup;
 	struct iovec *iov = (struct iovec *)_iov;
 	size_t total_len;
@@ -190,48 +232,91 @@
 
 	do_wakeup = 0;
 	ret = 0;
-	min = total_len;
-	if (min > PIPE_BUF)
-		min = 1;
 	down(PIPE_SEM(*inode));
+	info = inode->i_pipe;
+
+	if (!PIPE_READERS(*inode)) {
+		send_sig(SIGPIPE, current, 0);
+		ret = -EPIPE;
+		goto out;
+	}
+
+	/* We try to merge small writes */
+	if (info->nrbufs && total_len < PAGE_SIZE) {
+		int lastbuf = (info->curbuf + info->nrbufs - 1) & (PIPE_BUFFERS-1);
+		struct pipe_buffer *buf = info->bufs + lastbuf;
+		struct pipe_buf_operations *ops = buf->ops;
+		int offset = buf->offset + buf->len;
+		if (ops->can_merge && offset + total_len <= PAGE_SIZE) {
+			void *addr = ops->map(filp, info, buf);
+			int error = pipe_iov_copy_from_user(offset + addr, iov, total_len);
+			ops->unmap(info, buf);
+			ret = error;
+			do_wakeup = 1;
+			if (error)
+				goto out;
+			buf->len += total_len;
+			ret = total_len;
+			goto out;
+		}
+			
+	}
+
 	for (;;) {
-		int free;
+		int bufs;
 		if (!PIPE_READERS(*inode)) {
 			send_sig(SIGPIPE, current, 0);
 			if (!ret) ret = -EPIPE;
 			break;
 		}
-		free = PIPE_FREE(*inode);
-		if (free >= min) {
-			/* transfer data */
-			ssize_t chars = PIPE_MAX_WCHUNK(*inode);
-			char *pipebuf = PIPE_BASE(*inode) + PIPE_END(*inode);
+		bufs = info->nrbufs;
+		if (bufs < PIPE_BUFFERS) {
+			ssize_t chars;
+			int newbuf = (info->curbuf + bufs) & (PIPE_BUFFERS-1);
+			struct pipe_buffer *buf = info->bufs + newbuf;
+			struct page *page = info->tmp_page;
+			int error;
+
+			if (!page) {
+				page = alloc_page(GFP_HIGHUSER);
+				if (unlikely(!page)) {
+					ret = ret ? : -ENOMEM;
+					break;
+				}
+				info->tmp_page = page;
+			}
 			/* Always wakeup, even if the copy fails. Otherwise
 			 * we lock up (O_NONBLOCK-)readers that sleep due to
 			 * syscall merging.
+			 * FIXME! Is this really true?
 			 */
 			do_wakeup = 1;
+			chars = PAGE_SIZE;
 			if (chars > total_len)
 				chars = total_len;
-			if (chars > free)
-				chars = free;
 
-			if (pipe_iov_copy_from_user(pipebuf, iov, chars)) {
+			error = pipe_iov_copy_from_user(kmap(page), iov, chars);
+			kunmap(page);
+			if (unlikely(error)) {
 				if (!ret) ret = -EFAULT;
 				break;
 			}
 			ret += chars;
 
-			PIPE_LEN(*inode) += chars;
+			/* Insert it into the buffer array */
+			buf->page = page;
+			buf->ops = &anon_pipe_buf_ops;
+			buf->offset = 0;
+			buf->len = chars;
+			info->nrbufs = ++bufs;
+			info->tmp_page = NULL;
+
 			total_len -= chars;
 			if (!total_len)
 				break;
 		}
-		if (PIPE_FREE(*inode) && ret) {
-			/* handle cyclic data buffers */
-			min = 1;
+		if (bufs < PIPE_BUFFERS)
 			continue;
-		}
 		if (filp->f_flags & O_NONBLOCK) {
 			if (!ret) ret = -EAGAIN;
 			break;
@@ -249,6 +334,7 @@
 		pipe_wait(inode);
 		PIPE_WAITING_WRITERS(*inode)--;
 	}
+out:
 	up(PIPE_SEM(*inode));
 	if (do_wakeup) {
 		wake_up_interruptible(PIPE_WAIT(*inode));
@@ -283,9 +369,23 @@
 pipe_ioctl(struct inode *pino, struct file *filp,
 	   unsigned int cmd, unsigned long arg)
 {
+	struct inode *inode = filp->f_dentry->d_inode;
+	struct pipe_inode_info *info;
+	int count, buf, nrbufs;
+
 	switch (cmd) {
 		case FIONREAD:
-			return put_user(PIPE_LEN(*pino), (int __user *)arg);
+			down(PIPE_SEM(*inode));
+			info =  inode->i_pipe;
+			count = 0;
+			buf = info->curbuf;
+			nrbufs = info->nrbufs;
+			while (--nrbufs >= 0) {
+				count += info->bufs[buf].len;
+				buf = (buf+1) & (PIPE_BUFFERS-1);
+			}
+			up(PIPE_SEM(*inode));
+			return put_user(count, (int __user *)arg);
 		default:
 			return -EINVAL;
 	}
@@ -297,17 +397,25 @@
 {
 	unsigned int mask;
 	struct inode *inode = filp->f_dentry->d_inode;
+	struct pipe_inode_info *info = inode->i_pipe;
+	int nrbufs;
 
 	poll_wait(filp, PIPE_WAIT(*inode), wait);
 
 	/* Reading only -- no need for acquiring the semaphore.  */
-	mask = POLLIN | POLLRDNORM;
-	if (PIPE_EMPTY(*inode))
-		mask = POLLOUT | POLLWRNORM;
-	if (!PIPE_WRITERS(*inode) && filp->f_version != PIPE_WCOUNTER(*inode))
-		mask |= POLLHUP;
-	if (!PIPE_READERS(*inode))
-		mask |= POLLERR;
+	nrbufs = info->nrbufs;
+	mask = 0;
+	if (filp->f_mode & FMODE_READ) {
+		mask = (nrbufs > 0) ? POLLIN | POLLRDNORM : 0;
+		if (!PIPE_WRITERS(*inode) && filp->f_version != PIPE_WCOUNTER(*inode))
+			mask |= POLLHUP;
+	}
+
+	if (filp->f_mode & FMODE_WRITE) {
+		mask |= (nrbufs < PIPE_BUFFERS) ? POLLOUT | POLLWRNORM : 0;
+		if (!PIPE_READERS(*inode))
+			mask |= POLLERR;
+	}
 
 	return mask;
 }
@@ -322,10 +430,7 @@
 	PIPE_READERS(*inode) -= decr;
 	PIPE_WRITERS(*inode) -= decw;
 	if (!PIPE_READERS(*inode) && !PIPE_WRITERS(*inode)) {
-		struct pipe_inode_info *info = inode->i_pipe;
-		inode->i_pipe = NULL;
-		free_page((unsigned long) info->base);
-		kfree(info);
+		free_pipe_info(inode);
 	} else {
 		wake_up_interruptible(PIPE_WAIT(*inode));
 		kill_fasync(PIPE_FASYNC_READERS(*inode), SIGIO, POLL_IN);
@@ -530,29 +635,37 @@
 	.fasync		= pipe_rdwr_fasync,
 };
 
-struct inode* pipe_new(struct inode* inode)
+void free_pipe_info(struct inode *inode)
 {
-	unsigned long page;
+	int i;
+	struct pipe_inode_info *info = inode->i_pipe;
+
+	inode->i_pipe = NULL;
+	for (i = 0; i < PIPE_BUFFERS; i++) {
+		struct pipe_buffer *buf = info->bufs + i;
+		if (buf->ops)
+			buf->ops->release(info, buf);
+	}
+	if (info->tmp_page)
+		__free_page(info->tmp_page);
+	kfree(info);
+}
 
-	page = __get_free_page(GFP_USER);
-	if (!page)
-		return NULL;
+struct inode* pipe_new(struct inode* inode)
+{
+	struct pipe_inode_info *info;
 
-	inode->i_pipe = kmalloc(sizeof(struct pipe_inode_info), GFP_KERNEL);
-	if (!inode->i_pipe)
+	info = kmalloc(sizeof(struct pipe_inode_info), GFP_KERNEL);
+	if (!info)
 		goto fail_page;
+	memset(info, 0, sizeof(*info));
+	inode->i_pipe = info;
 
 	init_waitqueue_head(PIPE_WAIT(*inode));
-	PIPE_BASE(*inode) = (char*) page;
-	PIPE_START(*inode) = PIPE_LEN(*inode) = 0;
-	PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 0;
-	PIPE_WAITING_WRITERS(*inode) = 0;
 	PIPE_RCOUNTER(*inode) = PIPE_WCOUNTER(*inode) = 1;
-	*PIPE_FASYNC_READERS(*inode) = *PIPE_FASYNC_WRITERS(*inode) = NULL;
 
 	return inode;
 fail_page:
-	free_page(page);
 	return NULL;
 }
 
@@ -668,9 +781,7 @@
 close_f12_inode_i:
 	put_unused_fd(i);
 close_f12_inode:
-	free_page((unsigned long) PIPE_BASE(*inode));
-	kfree(inode->i_pipe);
-	inode->i_pipe = NULL;
+	free_pipe_info(inode);
 	iput(inode);
 close_f12:
 	put_filp(f2);
diff -Nru a/fs/proc/Makefile b/fs/proc/Makefile
--- a/fs/proc/Makefile	2005-03-01 23:38:52 -08:00
+++ b/fs/proc/Makefile	2005-03-01 23:38:52 -08:00
@@ -4,8 +4,8 @@
 
 obj-$(CONFIG_PROC_FS) += proc.o
 
-proc-y			:= task_nommu.o
-proc-$(CONFIG_MMU)	:= task_mmu.o
+proc-y			:= nommu.o task_nommu.o
+proc-$(CONFIG_MMU)	:= mmu.o task_mmu.o
 
 proc-y       += inode.o root.o base.o generic.o array.o \
 		kmsg.o proc_tty.o proc_misc.o
diff -Nru a/fs/proc/array.c b/fs/proc/array.c
--- a/fs/proc/array.c	2005-03-01 23:38:58 -08:00
+++ b/fs/proc/array.c	2005-03-01 23:38:58 -08:00
@@ -78,6 +78,7 @@
 #include <asm/pgtable.h>
 #include <asm/io.h>
 #include <asm/processor.h>
+#include "internal.h"
 
 /* Gcc optimizes away "strlen(x)" for constant x */
 #define ADDBUF(buffer, string) \
@@ -312,8 +313,9 @@
 	int num_threads = 0;
 	struct mm_struct *mm;
 	unsigned long long start_time;
-	unsigned long cmin_flt = 0, cmaj_flt = 0, cutime = 0, cstime = 0;
-	unsigned long  min_flt = 0,  maj_flt = 0,  utime = 0,  stime = 0;
+	unsigned long cmin_flt = 0, cmaj_flt = 0;
+	unsigned long  min_flt = 0,  maj_flt = 0;
+	cputime_t cutime, cstime, utime, stime;
 	unsigned long rsslim = 0;
 	struct task_struct *t;
 	char tcomm[sizeof(task->comm)];
@@ -331,6 +333,7 @@
 
 	sigemptyset(&sigign);
 	sigemptyset(&sigcatch);
+	cutime = cstime = utime = stime = cputime_zero;
 	read_lock(&tasklist_lock);
 	if (task->sighand) {
 		spin_lock_irq(&task->sighand->siglock);
@@ -343,8 +346,8 @@
 			do {
 				min_flt += t->min_flt;
 				maj_flt += t->maj_flt;
-				utime += t->utime;
-				stime += t->stime;
+				utime = cputime_add(utime, t->utime);
+				stime = cputime_add(stime, t->stime);
 				t = next_thread(t);
 			} while (t != task);
 		}
@@ -366,8 +369,8 @@
 		if (whole) {
 			min_flt += task->signal->min_flt;
 			maj_flt += task->signal->maj_flt;
-			utime += task->signal->utime;
-			stime += task->signal->stime;
+			utime = cputime_add(utime, task->signal->utime);
+			stime = cputime_add(stime, task->signal->stime);
 		}
 	}
 	ppid = pid_alive(task) ? task->group_leader->real_parent->tgid : 0;
@@ -410,10 +413,10 @@
 		cmin_flt,
 		maj_flt,
 		cmaj_flt,
-		jiffies_to_clock_t(utime),
-		jiffies_to_clock_t(stime),
-		jiffies_to_clock_t(cutime),
-		jiffies_to_clock_t(cstime),
+		cputime_to_clock_t(utime),
+		cputime_to_clock_t(stime),
+		cputime_to_clock_t(cutime),
+		cputime_to_clock_t(cstime),
 		priority,
 		nice,
 		num_threads,
diff -Nru a/fs/proc/base.c b/fs/proc/base.c
--- a/fs/proc/base.c	2005-03-01 23:39:07 -08:00
+++ b/fs/proc/base.c	2005-03-01 23:39:07 -08:00
@@ -32,6 +32,7 @@
 #include <linux/mount.h>
 #include <linux/security.h>
 #include <linux/ptrace.h>
+#include "internal.h"
 
 /*
  * For hysterical raisins we keep the same inumbers as in the old procfs.
@@ -70,7 +71,12 @@
 	PROC_TGID_ATTR_EXEC,
 	PROC_TGID_ATTR_FSCREATE,
 #endif
+#ifdef CONFIG_AUDITSYSCALL
+	PROC_TGID_LOGINUID,
+#endif
 	PROC_TGID_FD_DIR,
+	PROC_TGID_OOM_SCORE,
+	PROC_TGID_OOM_ADJUST,
 	PROC_TID_INO,
 	PROC_TID_STATUS,
 	PROC_TID_MEM,
@@ -96,7 +102,12 @@
 	PROC_TID_ATTR_EXEC,
 	PROC_TID_ATTR_FSCREATE,
 #endif
+#ifdef CONFIG_AUDITSYSCALL
+	PROC_TID_LOGINUID,
+#endif
 	PROC_TID_FD_DIR = 0x8000,	/* 0x8000-0xffff */
+	PROC_TID_OOM_SCORE,
+	PROC_TID_OOM_ADJUST,
 };
 
 struct pid_entry {
@@ -132,6 +143,11 @@
 #ifdef CONFIG_SCHEDSTATS
 	E(PROC_TGID_SCHEDSTAT, "schedstat", S_IFREG|S_IRUGO),
 #endif
+	E(PROC_TGID_OOM_SCORE, "oom_score",S_IFREG|S_IRUGO),
+	E(PROC_TGID_OOM_ADJUST,"oom_adj", S_IFREG|S_IRUGO|S_IWUSR),
+#ifdef CONFIG_AUDITSYSCALL
+	E(PROC_TGID_LOGINUID, "loginuid", S_IFREG|S_IWUSR|S_IRUGO),
+#endif
 	{0,0,NULL,0}
 };
 static struct pid_entry tid_base_stuff[] = {
@@ -157,6 +173,11 @@
 #ifdef CONFIG_SCHEDSTATS
 	E(PROC_TID_SCHEDSTAT, "schedstat",S_IFREG|S_IRUGO),
 #endif
+	E(PROC_TID_OOM_SCORE,  "oom_score",S_IFREG|S_IRUGO),
+	E(PROC_TID_OOM_ADJUST, "oom_adj", S_IFREG|S_IRUGO|S_IWUSR),
+#ifdef CONFIG_AUDITSYSCALL
+	E(PROC_TID_LOGINUID, "loginuid", S_IFREG|S_IWUSR|S_IRUGO),
+#endif
 	{0,0,NULL,0}
 };
 
@@ -179,21 +200,6 @@
 
 #undef E
 
-static inline struct task_struct *proc_task(struct inode *inode)
-{
-	return PROC_I(inode)->task;
-}
-
-static inline int proc_type(struct inode *inode)
-{
-	return PROC_I(inode)->type;
-}
-
-int proc_tid_stat(struct task_struct*,char*);
-int proc_tgid_stat(struct task_struct*,char*);
-int proc_pid_status(struct task_struct*,char*);
-int proc_pid_statm(struct task_struct*,char*);
-
 static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt)
 {
 	struct task_struct *task = proc_task(inode);
@@ -218,33 +224,6 @@
 	return -ENOENT;
 }
 
-static int proc_exe_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt)
-{
-	struct vm_area_struct * vma;
-	int result = -ENOENT;
-	struct task_struct *task = proc_task(inode);
-	struct mm_struct * mm = get_task_mm(task);
-
-	if (!mm)
-		goto out;
-	down_read(&mm->mmap_sem);
-	vma = mm->mmap;
-	while (vma) {
-		if ((vma->vm_flags & VM_EXECUTABLE) && 
-		    vma->vm_file) {
-			*mnt = mntget(vma->vm_file->f_vfsmnt);
-			*dentry = dget(vma->vm_file->f_dentry);
-			result = 0;
-			break;
-		}
-		vma = vma->vm_next;
-	}
-	up_read(&mm->mmap_sem);
-	mmput(mm);
-out:
-	return result;
-}
-
 static int proc_cwd_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt)
 {
 	struct fs_struct *fs;
@@ -401,7 +380,7 @@
 	char *modname;
 	const char *sym_name;
 	unsigned long wchan, size, offset;
-	char namebuf[128];
+	char namebuf[KSYM_NAME_LEN+1];
 
 	wchan = get_wchan(task);
 
@@ -425,6 +404,18 @@
 }
 #endif
 
+/* The badness from the OOM killer */
+unsigned long badness(struct task_struct *p, unsigned long uptime);
+static int proc_oom_score(struct task_struct *task, char *buffer)
+{
+	unsigned long points;
+	struct timespec uptime;
+
+	do_posix_clock_monotonic_gettime(&uptime);
+	points = badness(task, uptime.tv_sec);
+	return sprintf(buffer, "%lu\n", points);
+}
+
 /************************************************************************/
 /*                       Here the fs part begins                        */
 /************************************************************************/
@@ -698,10 +689,125 @@
 	.open		= mem_open,
 };
 
+static ssize_t oom_adjust_read(struct file *file, char *buf,
+				size_t count, loff_t *ppos)
+{
+	struct task_struct *task = proc_task(file->f_dentry->d_inode);
+	char buffer[8];
+	size_t len;
+	int oom_adjust = task->oomkilladj;
+	loff_t __ppos = *ppos;
+
+	len = sprintf(buffer, "%i\n", oom_adjust);
+	if (__ppos >= len)
+		return 0;
+	if (count > len-__ppos)
+		count = len-__ppos;
+	if (copy_to_user(buf, buffer + __ppos, count))
+		return -EFAULT;
+	*ppos = __ppos + count;
+	return count;
+}
+
+static ssize_t oom_adjust_write(struct file *file, const char *buf,
+				size_t count, loff_t *ppos)
+{
+	struct task_struct *task = proc_task(file->f_dentry->d_inode);
+	char buffer[8], *end;
+	int oom_adjust;
+
+	if (!capable(CAP_SYS_RESOURCE))
+		return -EPERM;
+	memset(buffer, 0, 8);
+	if (count > 6)
+		count = 6;
+	if (copy_from_user(buffer, buf, count))
+		return -EFAULT;
+	oom_adjust = simple_strtol(buffer, &end, 0);
+	if (oom_adjust < -16 || oom_adjust > 15)
+		return -EINVAL;
+	if (*end == '\n')
+		end++;
+	task->oomkilladj = oom_adjust;
+	if (end - buffer == 0)
+		return -EIO;
+	return end - buffer;
+}
+
+static struct file_operations proc_oom_adjust_operations = {
+	read:		oom_adjust_read,
+	write:		oom_adjust_write,
+};
+
 static struct inode_operations proc_mem_inode_operations = {
 	.permission	= proc_permission,
 };
 
+#ifdef CONFIG_AUDITSYSCALL
+#define TMPBUFLEN 21
+static ssize_t proc_loginuid_read(struct file * file, char __user * buf,
+				  size_t count, loff_t *ppos)
+{
+	struct inode * inode = file->f_dentry->d_inode;
+	struct task_struct *task = proc_task(inode);
+	ssize_t length;
+	char tmpbuf[TMPBUFLEN];
+
+	length = scnprintf(tmpbuf, TMPBUFLEN, "%u",
+				audit_get_loginuid(task->audit_context));
+	return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
+}
+
+static ssize_t proc_loginuid_write(struct file * file, const char __user * buf,
+				   size_t count, loff_t *ppos)
+{
+	struct inode * inode = file->f_dentry->d_inode;
+	char *page, *tmp;
+	ssize_t length;
+	struct task_struct *task = proc_task(inode);
+	uid_t loginuid;
+
+	if (!capable(CAP_AUDIT_CONTROL))
+		return -EPERM;
+
+	if (current != task)
+		return -EPERM;
+
+	if (count > PAGE_SIZE)
+		count = PAGE_SIZE;
+
+	if (*ppos != 0) {
+		/* No partial writes. */
+		return -EINVAL;
+	}
+	page = (char*)__get_free_page(GFP_USER);
+	if (!page)
+		return -ENOMEM;
+	length = -EFAULT;
+	if (copy_from_user(page, buf, count))
+		goto out_free_page;
+
+	loginuid = simple_strtoul(page, &tmp, 10);
+	if (tmp == page) {
+		length = -EINVAL;
+		goto out_free_page;
+
+	}
+	length = audit_set_loginuid(task->audit_context, loginuid);
+	if (likely(length == 0))
+		length = count;
+
+out_free_page:
+	free_page((unsigned long) page);
+	return length;
+}
+
+static struct file_operations proc_loginuid_operations = {
+	.read		= proc_loginuid_read,
+	.write		= proc_loginuid_write,
+};
+#endif
+
 static int proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd)
 {
 	struct inode *inode = dentry->d_inode;
@@ -1375,6 +1481,21 @@
 		case PROC_TGID_SCHEDSTAT:
 			inode->i_fop = &proc_info_file_operations;
 			ei->op.proc_read = proc_pid_schedstat;
+			break;
+#endif
+		case PROC_TID_OOM_SCORE:
+		case PROC_TGID_OOM_SCORE:
+			inode->i_fop = &proc_info_file_operations;
+			ei->op.proc_read = proc_oom_score;
+			break;
+		case PROC_TID_OOM_ADJUST:
+		case PROC_TGID_OOM_ADJUST:
+			inode->i_fop = &proc_oom_adjust_operations;
+			break;
+#ifdef CONFIG_AUDITSYSCALL
+		case PROC_TID_LOGINUID:
+		case PROC_TGID_LOGINUID:
+			inode->i_fop = &proc_loginuid_operations;
 			break;
 #endif
 		default:
diff -Nru a/fs/proc/generic.c b/fs/proc/generic.c
--- a/fs/proc/generic.c	2005-03-01 23:39:17 -08:00
+++ b/fs/proc/generic.c	2005-03-01 23:39:17 -08:00
@@ -60,7 +60,7 @@
 		return -ENOMEM;
 
 	while ((nbytes > 0) && !eof) {
-		count = min_t(ssize_t, PROC_BLOCK_SIZE, nbytes);
+		count = min_t(size_t, PROC_BLOCK_SIZE, nbytes);
 
 		start = NULL;
 		if (dp->get_info) {
@@ -286,7 +286,7 @@
 }
 
 static DEFINE_IDR(proc_inum_idr);
-static spinlock_t proc_inum_lock = SPIN_LOCK_UNLOCKED; /* protects the above */
+static DEFINE_SPINLOCK(proc_inum_lock); /* protects the above */
 
 #define PROC_DYNAMIC_FIRST 0xF0000000UL
 
@@ -551,6 +551,11 @@
 
 	if (!(*parent) && xlate_proc_name(name, parent, &fn) != 0)
 		goto out;
+
+	/* At this point there must not be any '/' characters beyond *fn */
+	if (strchr(fn, '/'))
+		goto out;
+
 	len = strlen(fn);
 
 	ent = kmalloc(sizeof(struct proc_dir_entry) + len + 1, GFP_KERNEL);
diff -Nru a/fs/proc/inode.c b/fs/proc/inode.c
--- a/fs/proc/inode.c	2005-03-01 23:39:10 -08:00
+++ b/fs/proc/inode.c	2005-03-01 23:39:10 -08:00
@@ -240,6 +240,7 @@
 	s->s_blocksize_bits = 10;
 	s->s_magic = PROC_SUPER_MAGIC;
 	s->s_op = &proc_sops;
+	s->s_time_gran = 1;
 	
 	root_inode = proc_get_inode(s, PROC_ROOT_INO, &proc_root);
 	if (!root_inode)
diff -Nru a/fs/proc/internal.h b/fs/proc/internal.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/fs/proc/internal.h	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,48 @@
+/* internal.h: internal procfs definitions
+ *
+ * Copyright (C) 2004 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/proc_fs.h>
+
+struct vmalloc_info {
+	unsigned long	used;
+	unsigned long	largest_chunk;
+};
+
+#ifdef CONFIG_MMU
+#define VMALLOC_TOTAL (VMALLOC_END - VMALLOC_START)
+extern void get_vmalloc_info(struct vmalloc_info *vmi);
+#else
+
+#define VMALLOC_TOTAL 0UL
+#define get_vmalloc_info(vmi)			\
+do {						\
+	(vmi)->used = 0;			\
+	(vmi)->largest_chunk = 0;		\
+} while(0)
+
+#endif
+
+extern void create_seq_entry(char *name, mode_t mode, struct file_operations *f);
+extern int proc_exe_link(struct inode *, struct dentry **, struct vfsmount **);
+extern int proc_tid_stat(struct task_struct *,  char *);
+extern int proc_tgid_stat(struct task_struct *, char *);
+extern int proc_pid_status(struct task_struct *, char *);
+extern int proc_pid_statm(struct task_struct *, char *);
+
+static inline struct task_struct *proc_task(struct inode *inode)
+{
+	return PROC_I(inode)->task;
+}
+
+static inline int proc_type(struct inode *inode)
+{
+	return PROC_I(inode)->type;
+}
diff -Nru a/fs/proc/kcore.c b/fs/proc/kcore.c
--- a/fs/proc/kcore.c	2005-03-01 23:38:58 -08:00
+++ b/fs/proc/kcore.c	2005-03-01 23:38:58 -08:00
@@ -54,7 +54,7 @@
 };
 
 static struct kcore_list *kclist;
-static rwlock_t kclist_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(kclist_lock);
 
 void
 kclist_add(struct kcore_list *new, void *addr, size_t size)
@@ -68,23 +68,6 @@
 	write_unlock(&kclist_lock);
 }
 
-struct kcore_list *
-kclist_del(void *addr)
-{
-	struct kcore_list *m, **p = &kclist;
-
-	write_lock(&kclist_lock);
-	for (m = *p; m; p = &m->next) {
-		if (m->addr == (unsigned long)addr) {
-			*p = m->next;
-			write_unlock(&kclist_lock);
-			return m;
-		}
-	}
-	write_unlock(&kclist_lock);
-	return NULL;
-}
-
 static size_t get_kcore_size(int *nphdr, size_t *elf_buflen)
 {
 	size_t try, size;
@@ -281,8 +264,7 @@
 	unsigned long start;
 
 	read_lock(&kclist_lock);
-	tsz =  get_kcore_size(&nphdr, &elf_buflen);
-	proc_root_kcore->size = size = tsz + elf_buflen;
+	proc_root_kcore->size = size = get_kcore_size(&nphdr, &elf_buflen);
 	if (buflen == 0 || *fpos >= size) {
 		read_unlock(&kclist_lock);
 		return 0;
diff -Nru a/fs/proc/mmu.c b/fs/proc/mmu.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/fs/proc/mmu.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,67 @@
+/* mmu.c: mmu memory info files
+ *
+ * Copyright (C) 2004 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/types.h>
+#include <linux/errno.h>
+#include <linux/time.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/mman.h>
+#include <linux/proc_fs.h>
+#include <linux/mm.h>
+#include <linux/mmzone.h>
+#include <linux/pagemap.h>
+#include <linux/swap.h>
+#include <linux/slab.h>
+#include <linux/smp.h>
+#include <linux/seq_file.h>
+#include <linux/hugetlb.h>
+#include <linux/vmalloc.h>
+#include <asm/uaccess.h>
+#include <asm/pgtable.h>
+#include <asm/tlb.h>
+#include <asm/div64.h>
+#include "internal.h"
+
+void get_vmalloc_info(struct vmalloc_info *vmi)
+{
+	struct vm_struct *vma;
+	unsigned long free_area_size;
+	unsigned long prev_end;
+
+	vmi->used = 0;
+
+	if (!vmlist) {
+		vmi->largest_chunk = VMALLOC_TOTAL;
+	}
+	else {
+		vmi->largest_chunk = 0;
+
+		prev_end = VMALLOC_START;
+
+		read_lock(&vmlist_lock);
+
+		for (vma = vmlist; vma; vma = vma->next) {
+			vmi->used += vma->size;
+
+			free_area_size = (unsigned long) vma->addr - prev_end;
+			if (vmi->largest_chunk < free_area_size)
+				vmi->largest_chunk = free_area_size;
+
+			prev_end = vma->size + (unsigned long) vma->addr;
+		}
+
+		if (VMALLOC_END - prev_end > vmi->largest_chunk)
+			vmi->largest_chunk = VMALLOC_END - prev_end;
+
+		read_unlock(&vmlist_lock);
+	}
+}
diff -Nru a/fs/proc/nommu.c b/fs/proc/nommu.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/fs/proc/nommu.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,135 @@
+/* nommu.c: mmu-less memory info files
+ *
+ * Copyright (C) 2004 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/init.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/time.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/mman.h>
+#include <linux/proc_fs.h>
+#include <linux/mm.h>
+#include <linux/mmzone.h>
+#include <linux/pagemap.h>
+#include <linux/swap.h>
+#include <linux/slab.h>
+#include <linux/smp.h>
+#include <linux/seq_file.h>
+#include <linux/hugetlb.h>
+#include <linux/vmalloc.h>
+#include <asm/uaccess.h>
+#include <asm/pgtable.h>
+#include <asm/tlb.h>
+#include <asm/div64.h>
+#include "internal.h"
+
+/*
+ * display a list of all the VMAs the kernel knows about
+ * - nommu kernals have a single flat list
+ */
+static int nommu_vma_list_show(struct seq_file *m, void *v)
+{
+	struct vm_area_struct *vma;
+	unsigned long ino = 0;
+	struct file *file;
+	dev_t dev = 0;
+	int flags, len;
+
+	vma = rb_entry((struct rb_node *) v, struct vm_area_struct, vm_rb);
+
+	flags = vma->vm_flags;
+	file = vma->vm_file;
+
+	if (file) {
+		struct inode *inode = vma->vm_file->f_dentry->d_inode;
+		dev = inode->i_sb->s_dev;
+		ino = inode->i_ino;
+	}
+
+	seq_printf(m,
+		   "%08lx-%08lx %c%c%c%c %08lx %02x:%02x %lu %n",
+		   vma->vm_start,
+		   vma->vm_end,
+		   flags & VM_READ ? 'r' : '-',
+		   flags & VM_WRITE ? 'w' : '-',
+		   flags & VM_EXEC ? 'x' : '-',
+		   flags & VM_MAYSHARE ? flags & VM_SHARED ? 'S' : 's' : 'p',
+		   vma->vm_pgoff << PAGE_SHIFT,
+		   MAJOR(dev), MINOR(dev), ino, &len);
+
+	if (file) {
+		len = 25 + sizeof(void *) * 6 - len;
+		if (len < 1)
+			len = 1;
+		seq_printf(m, "%*c", len, ' ');
+		seq_path(m, file->f_vfsmnt, file->f_dentry, "");
+	}
+
+	seq_putc(m, '\n');
+	return 0;
+}
+
+static void *nommu_vma_list_start(struct seq_file *m, loff_t *_pos)
+{
+	struct rb_node *_rb;
+	loff_t pos = *_pos;
+	void *next = NULL;
+
+	down_read(&nommu_vma_sem);
+
+	for (_rb = rb_first(&nommu_vma_tree); _rb; _rb = rb_next(_rb)) {
+		if (pos == 0) {
+			next = _rb;
+			break;
+		}
+	}
+
+	return next;
+}
+
+static void nommu_vma_list_stop(struct seq_file *m, void *v)
+{
+	up_read(&nommu_vma_sem);
+}
+
+static void *nommu_vma_list_next(struct seq_file *m, void *v, loff_t *pos)
+{
+	(*pos)++;
+	return rb_next((struct rb_node *) v);
+}
+
+static struct seq_operations proc_nommu_vma_list_seqop = {
+	.start	= nommu_vma_list_start,
+	.next	= nommu_vma_list_next,
+	.stop	= nommu_vma_list_stop,
+	.show	= nommu_vma_list_show
+};
+
+static int proc_nommu_vma_list_open(struct inode *inode, struct file *file)
+{
+	return seq_open(file, &proc_nommu_vma_list_seqop);
+}
+
+static struct file_operations proc_nommu_vma_list_operations = {
+	.open    = proc_nommu_vma_list_open,
+	.read    = seq_read,
+	.llseek  = seq_lseek,
+	.release = seq_release,
+};
+
+static int __init proc_nommu_init(void)
+{
+	create_seq_entry("maps", S_IRUGO, &proc_nommu_vma_list_operations);
+	return 0;
+}
+
+module_init(proc_nommu_init);
diff -Nru a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
--- a/fs/proc/proc_misc.c	2005-03-01 23:38:52 -08:00
+++ b/fs/proc/proc_misc.c	2005-03-01 23:38:52 -08:00
@@ -49,6 +49,7 @@
 #include <asm/io.h>
 #include <asm/tlb.h>
 #include <asm/div64.h>
+#include "internal.h"
 
 #define LOAD_INT(x) ((x) >> FSHIFT)
 #define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100)
@@ -61,7 +62,6 @@
 extern int get_hardware_list(char *);
 extern int get_stram_list(char *);
 extern int get_chrdev_list(char *);
-extern int get_blkdev_list(char *);
 extern int get_filesystem_list(char *);
 extern int get_exec_domain_list(char *);
 extern int get_dma_list(char *);
@@ -95,51 +95,16 @@
 	return proc_calc_metrics(page, start, off, count, eof, len);
 }
 
-struct vmalloc_info {
-	unsigned long used;
-	unsigned long largest_chunk;
-};
-
-static struct vmalloc_info get_vmalloc_info(void)
-{
-	unsigned long prev_end = VMALLOC_START;
-	struct vm_struct* vma;
-	struct vmalloc_info vmi;
-	vmi.used = 0;
-
-	read_lock(&vmlist_lock);
-
-	if(!vmlist)
-		vmi.largest_chunk = (VMALLOC_END-VMALLOC_START);
-	else
-		vmi.largest_chunk = 0;
-
-	for (vma = vmlist; vma; vma = vma->next) {
-		unsigned long free_area_size =
-			(unsigned long)vma->addr - prev_end;
-		vmi.used += vma->size;
-		if (vmi.largest_chunk < free_area_size )
-
-			vmi.largest_chunk = free_area_size;
-		prev_end = vma->size + (unsigned long)vma->addr;
-	}
-	if(VMALLOC_END-prev_end > vmi.largest_chunk)
-		vmi.largest_chunk = VMALLOC_END-prev_end;
-
-	read_unlock(&vmlist_lock);
-	return vmi;
-}
-
 static int uptime_read_proc(char *page, char **start, off_t off,
 				 int count, int *eof, void *data)
 {
 	struct timespec uptime;
 	struct timespec idle;
 	int len;
-	u64 idle_jiffies = init_task.utime + init_task.stime;
+	cputime_t idletime = cputime_add(init_task.utime, init_task.stime);
 
 	do_posix_clock_monotonic_gettime(&uptime);
-	jiffies_to_timespec(idle_jiffies, &idle);
+	cputime_to_timespec(idletime, &idle);
 	len = sprintf(page,"%lu.%02lu %lu.%02lu\n",
 			(unsigned long) uptime.tv_sec,
 			(uptime.tv_nsec / (NSEC_PER_SEC / 100)),
@@ -158,7 +123,6 @@
 	unsigned long inactive;
 	unsigned long active;
 	unsigned long free;
-	unsigned long vmtot;
 	unsigned long committed;
 	unsigned long allowed;
 	struct vmalloc_info vmi;
@@ -176,10 +140,7 @@
 	allowed = ((totalram_pages - hugetlb_total_pages())
 		* sysctl_overcommit_ratio / 100) + total_swap_pages;
 
-	vmtot = (VMALLOC_END-VMALLOC_START)>>10;
-	vmi = get_vmalloc_info();
-	vmi.used >>= 10;
-	vmi.largest_chunk >>= 10;
+	get_vmalloc_info(&vmi);
 
 	/*
 	 * Tagged format, for easy grepping and expansion.
@@ -228,9 +189,9 @@
 		K(allowed),
 		K(committed),
 		K(ps.nr_page_table_pages),
-		vmtot,
-		vmi.used,
-		vmi.largest_chunk
+		VMALLOC_TOTAL >> 10,
+		vmi.used >> 10,
+		vmi.largest_chunk >> 10
 		);
 
 		len += hugetlb_report_meminfo(page + len);
@@ -256,7 +217,6 @@
 static int version_read_proc(char *page, char **start, off_t off,
 				 int count, int *eof, void *data)
 {
-	extern char *linux_banner;
 	int len;
 
 	strcpy(page, linux_banner);
@@ -358,14 +318,15 @@
 	.release	= seq_release,
 };
 
-int show_stat(struct seq_file *p, void *v)
+static int show_stat(struct seq_file *p, void *v)
 {
 	int i;
-	extern unsigned long total_forks;
 	unsigned long jif;
-	u64	sum = 0, user = 0, nice = 0, system = 0,
-		idle = 0, iowait = 0, irq = 0, softirq = 0;
+	cputime64_t user, nice, system, idle, iowait, irq, softirq, steal;
+	u64 sum = 0;
 
+	user = nice = system = idle = iowait =
+		irq = softirq = steal = cputime64_zero;
 	jif = - wall_to_monotonic.tv_sec;
 	if (wall_to_monotonic.tv_nsec)
 		--jif;
@@ -373,25 +334,27 @@
 	for_each_cpu(i) {
 		int j;
 
-		user += kstat_cpu(i).cpustat.user;
-		nice += kstat_cpu(i).cpustat.nice;
-		system += kstat_cpu(i).cpustat.system;
-		idle += kstat_cpu(i).cpustat.idle;
-		iowait += kstat_cpu(i).cpustat.iowait;
-		irq += kstat_cpu(i).cpustat.irq;
-		softirq += kstat_cpu(i).cpustat.softirq;
+		user = cputime64_add(user, kstat_cpu(i).cpustat.user);
+		nice = cputime64_add(nice, kstat_cpu(i).cpustat.nice);
+		system = cputime64_add(system, kstat_cpu(i).cpustat.system);
+		idle = cputime64_add(idle, kstat_cpu(i).cpustat.idle);
+		iowait = cputime64_add(iowait, kstat_cpu(i).cpustat.iowait);
+		irq = cputime64_add(irq, kstat_cpu(i).cpustat.irq);
+		softirq = cputime64_add(softirq, kstat_cpu(i).cpustat.softirq);
+		steal = cputime64_add(steal, kstat_cpu(i).cpustat.steal);
 		for (j = 0 ; j < NR_IRQS ; j++)
 			sum += kstat_cpu(i).irqs[j];
 	}
 
-	seq_printf(p, "cpu  %llu %llu %llu %llu %llu %llu %llu\n",
-		(unsigned long long)jiffies_64_to_clock_t(user),
-		(unsigned long long)jiffies_64_to_clock_t(nice),
-		(unsigned long long)jiffies_64_to_clock_t(system),
-		(unsigned long long)jiffies_64_to_clock_t(idle),
-		(unsigned long long)jiffies_64_to_clock_t(iowait),
-		(unsigned long long)jiffies_64_to_clock_t(irq),
-		(unsigned long long)jiffies_64_to_clock_t(softirq));
+	seq_printf(p, "cpu  %llu %llu %llu %llu %llu %llu %llu %llu\n",
+		(unsigned long long)cputime64_to_clock_t(user),
+		(unsigned long long)cputime64_to_clock_t(nice),
+		(unsigned long long)cputime64_to_clock_t(system),
+		(unsigned long long)cputime64_to_clock_t(idle),
+		(unsigned long long)cputime64_to_clock_t(iowait),
+		(unsigned long long)cputime64_to_clock_t(irq),
+		(unsigned long long)cputime64_to_clock_t(softirq),
+		(unsigned long long)cputime64_to_clock_t(steal));
 	for_each_online_cpu(i) {
 
 		/* Copy values here to work around gcc-2.95.3, gcc-2.96 */
@@ -402,15 +365,17 @@
 		iowait = kstat_cpu(i).cpustat.iowait;
 		irq = kstat_cpu(i).cpustat.irq;
 		softirq = kstat_cpu(i).cpustat.softirq;
-		seq_printf(p, "cpu%d %llu %llu %llu %llu %llu %llu %llu\n",
+		steal = kstat_cpu(i).cpustat.steal;
+		seq_printf(p, "cpu%d %llu %llu %llu %llu %llu %llu %llu %llu\n",
 			i,
-			(unsigned long long)jiffies_64_to_clock_t(user),
-			(unsigned long long)jiffies_64_to_clock_t(nice),
-			(unsigned long long)jiffies_64_to_clock_t(system),
-			(unsigned long long)jiffies_64_to_clock_t(idle),
-			(unsigned long long)jiffies_64_to_clock_t(iowait),
-			(unsigned long long)jiffies_64_to_clock_t(irq),
-			(unsigned long long)jiffies_64_to_clock_t(softirq));
+			(unsigned long long)cputime64_to_clock_t(user),
+			(unsigned long long)cputime64_to_clock_t(nice),
+			(unsigned long long)cputime64_to_clock_t(system),
+			(unsigned long long)cputime64_to_clock_t(idle),
+			(unsigned long long)cputime64_to_clock_t(iowait),
+			(unsigned long long)cputime64_to_clock_t(irq),
+			(unsigned long long)cputime64_to_clock_t(softirq),
+			(unsigned long long)cputime64_to_clock_t(steal));
 	}
 	seq_printf(p, "intr %llu", (unsigned long long)sum);
 
@@ -502,7 +467,7 @@
 	.show  = show_interrupts
 };
 
-int interrupts_open(struct inode *inode, struct file *filp)
+static int interrupts_open(struct inode *inode, struct file *filp)
 {
 	return seq_open(filp, &int_seq_ops);
 }
@@ -571,7 +536,7 @@
 
 struct proc_dir_entry *proc_root_kcore;
 
-static void create_seq_entry(char *name, mode_t mode, struct file_operations *f)
+void create_seq_entry(char *name, mode_t mode, struct file_operations *f)
 {
 	struct proc_dir_entry *entry;
 	entry = create_proc_entry(name, mode, NULL);
diff -Nru a/fs/proc/proc_tty.c b/fs/proc/proc_tty.c
--- a/fs/proc/proc_tty.c	2005-03-01 23:39:18 -08:00
+++ b/fs/proc/proc_tty.c	2005-03-01 23:39:18 -08:00
@@ -32,10 +32,8 @@
 	seq_printf(m, "%-20s ", p->driver_name ? p->driver_name : "unknown");
 	seq_printf(m, "/dev/%-8s ", p->name);
 	if (p->num > 1) {
-		char	range[20];
-		sprintf(range, "%d-%d", MINOR(from),
+		seq_printf(m, "%3d %d-%d ", MAJOR(from), MINOR(from),
 			MINOR(from) + num - 1);
-		seq_printf(m, "%3d %7s ", MAJOR(from), range);
 	} else {
 		seq_printf(m, "%3d %7d ", MAJOR(from), MINOR(from));
 	}
diff -Nru a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
--- a/fs/proc/task_mmu.c	2005-03-01 23:38:52 -08:00
+++ b/fs/proc/task_mmu.c	2005-03-01 23:38:52 -08:00
@@ -1,8 +1,10 @@
 #include <linux/mm.h>
 #include <linux/hugetlb.h>
+#include <linux/mount.h>
 #include <linux/seq_file.h>
 #include <asm/elf.h>
 #include <asm/uaccess.h>
+#include "internal.h"
 
 char *task_mem(struct mm_struct *mm, char *buffer)
 {
@@ -43,6 +45,36 @@
 	*data = mm->total_vm - mm->shared_vm;
 	*resident = mm->rss;
 	return mm->total_vm;
+}
+
+int proc_exe_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt)
+{
+	struct vm_area_struct * vma;
+	int result = -ENOENT;
+	struct task_struct *task = proc_task(inode);
+	struct mm_struct * mm = get_task_mm(task);
+
+	if (!mm)
+		goto out;
+	down_read(&mm->mmap_sem);
+
+	vma = mm->mmap;
+	while (vma) {
+		if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file)
+			break;
+		vma = vma->vm_next;
+	}
+
+	if (vma) {
+		*mnt = mntget(vma->vm_file->f_vfsmnt);
+		*dentry = dget(vma->vm_file->f_dentry);
+		result = 0;
+	}
+
+	up_read(&mm->mmap_sem);
+	mmput(mm);
+out:
+	return result;
 }
 
 static int show_map(struct seq_file *m, void *v)
diff -Nru a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c
--- a/fs/proc/task_nommu.c	2005-03-01 23:38:58 -08:00
+++ b/fs/proc/task_nommu.c	2005-03-01 23:38:58 -08:00
@@ -1,7 +1,9 @@
 
 #include <linux/mm.h>
 #include <linux/file.h>
+#include <linux/mount.h>
 #include <linux/seq_file.h>
+#include "internal.h"
 
 /*
  * Logic: we've got two memory sums for each process, "shared", and
@@ -11,23 +13,25 @@
  */
 char *task_mem(struct mm_struct *mm, char *buffer)
 {
+	struct vm_list_struct *vml;
 	unsigned long bytes = 0, sbytes = 0, slack = 0;
-	struct mm_tblock_struct *tblock;
         
 	down_read(&mm->mmap_sem);
-	for (tblock = &mm->context.tblock; tblock; tblock = tblock->next) {
-		if (!tblock->rblock)
+	for (vml = mm->context.vmlist; vml; vml = vml->next) {
+		if (!vml->vma)
 			continue;
-		bytes += kobjsize(tblock);
+
+		bytes += kobjsize(vml);
 		if (atomic_read(&mm->mm_count) > 1 ||
-		    tblock->rblock->refcount > 1) {
-			sbytes += kobjsize(tblock->rblock->kblock);
-			sbytes += kobjsize(tblock->rblock);
+		    atomic_read(&vml->vma->vm_usage) > 1
+		    ) {
+			sbytes += kobjsize((void *) vml->vma->vm_start);
+			sbytes += kobjsize(vml->vma);
 		} else {
-			bytes += kobjsize(tblock->rblock->kblock);
-			bytes += kobjsize(tblock->rblock);
-			slack += kobjsize(tblock->rblock->kblock) -
-					tblock->rblock->size;
+			bytes += kobjsize((void *) vml->vma->vm_start);
+			bytes += kobjsize(vml->vma);
+			slack += kobjsize((void *) vml->vma->vm_start) -
+				(vml->vma->vm_end - vml->vma->vm_start);
 		}
 	}
 
@@ -65,13 +69,13 @@
 
 unsigned long task_vsize(struct mm_struct *mm)
 {
-	struct mm_tblock_struct *tbp;
+	struct vm_list_struct *tbp;
 	unsigned long vsize = 0;
 
 	down_read(&mm->mmap_sem);
-	for (tbp = &mm->context.tblock; tbp; tbp = tbp->next) {
-		if (tbp->rblock)
-			vsize += kobjsize(tbp->rblock->kblock);
+	for (tbp = mm->context.vmlist; tbp; tbp = tbp->next) {
+		if (tbp->vma)
+			vsize += kobjsize((void *) tbp->vma->vm_start);
 	}
 	up_read(&mm->mmap_sem);
 	return vsize;
@@ -80,16 +84,15 @@
 int task_statm(struct mm_struct *mm, int *shared, int *text,
 	       int *data, int *resident)
 {
-	struct mm_tblock_struct *tbp;
+	struct vm_list_struct *tbp;
 	int size = kobjsize(mm);
 
 	down_read(&mm->mmap_sem);
-	for (tbp = &mm->context.tblock; tbp; tbp = tbp->next) {
-		if (tbp->next)
-			size += kobjsize(tbp->next);
-		if (tbp->rblock) {
-			size += kobjsize(tbp->rblock);
-			size += kobjsize(tbp->rblock->kblock);
+	for (tbp = mm->context.vmlist; tbp; tbp = tbp->next) {
+		size += kobjsize(tbp);
+		if (tbp->vma) {
+			size += kobjsize(tbp->vma);
+			size += kobjsize((void *) tbp->vma->vm_start);
 		}
 	}
 
@@ -98,6 +101,40 @@
 	up_read(&mm->mmap_sem);
 	*resident = size;
 	return size;
+}
+
+int proc_exe_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt)
+{
+	struct vm_list_struct *vml;
+	struct vm_area_struct *vma;
+	struct task_struct *task = proc_task(inode);
+	struct mm_struct *mm = get_task_mm(task);
+	int result = -ENOENT;
+
+	if (!mm)
+		goto out;
+	down_read(&mm->mmap_sem);
+
+	vml = mm->context.vmlist;
+	vma = NULL;
+	while (vml) {
+		if ((vml->vma->vm_flags & VM_EXECUTABLE) && vml->vma->vm_file) {
+			vma = vml->vma;
+			break;
+		}
+		vml = vml->next;
+	}
+
+	if (vma) {
+		*mnt = mntget(vma->vm_file->f_vfsmnt);
+		*dentry = dget(vma->vm_file->f_dentry);
+		result = 0;
+	}
+
+	up_read(&mm->mmap_sem);
+	mmput(mm);
+out:
+	return result;
 }
 
 /*
diff -Nru a/fs/qnx4/inode.c b/fs/qnx4/inode.c
--- a/fs/qnx4/inode.c	2005-03-01 23:39:09 -08:00
+++ b/fs/qnx4/inode.c	2005-03-01 23:39:09 -08:00
@@ -189,7 +189,7 @@
 	}
 	tst = tmp;
 #endif
-	inode->i_ctime = CURRENT_TIME;
+	inode->i_ctime = CURRENT_TIME_SEC;
 	mark_inode_dirty(inode);
 	return result;
 }
diff -Nru a/fs/qnx4/namei.c b/fs/qnx4/namei.c
--- a/fs/qnx4/namei.c	2005-03-01 23:39:07 -08:00
+++ b/fs/qnx4/namei.c	2005-03-01 23:39:07 -08:00
@@ -189,7 +189,7 @@
 	mark_buffer_dirty(bh);
 	inode->i_nlink = 0;
 	mark_inode_dirty(inode);
-	inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+	inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
 	dir->i_nlink--;
 	mark_inode_dirty(dir);
 	retval = 0;
@@ -233,7 +233,7 @@
 	memset(de->di_fname, 0, sizeof de->di_fname);
 	de->di_mode = 0;
 	mark_buffer_dirty(bh);
-	dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+	dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
 	mark_inode_dirty(dir);
 	inode->i_nlink--;
 	inode->i_ctime = dir->i_ctime;
diff -Nru a/fs/qnx4/truncate.c b/fs/qnx4/truncate.c
--- a/fs/qnx4/truncate.c	2005-03-01 23:38:56 -08:00
+++ b/fs/qnx4/truncate.c	2005-03-01 23:38:56 -08:00
@@ -31,7 +31,7 @@
 		/* TODO */
 	}
 	QNX4DEBUG(("qnx4: qnx4_truncate called\n"));
-	inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+	inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC;
 	mark_inode_dirty(inode);
 	unlock_kernel();
 }
diff -Nru a/fs/quota.c b/fs/quota.c
--- a/fs/quota.c	2005-03-01 23:39:17 -08:00
+++ b/fs/quota.c	2005-03-01 23:39:17 -08:00
@@ -14,6 +14,7 @@
 #include <linux/smp_lock.h>
 #include <linux/security.h>
 #include <linux/syscalls.h>
+#include <linux/buffer_head.h>
 
 /* Check validity of quotactl */
 static int check_quotactl_valid(struct super_block *sb, int type, int cmd, qid_t id)
@@ -135,16 +136,54 @@
 	return NULL;
 }
 
+static void quota_sync_sb(struct super_block *sb, int type)
+{
+	int cnt;
+	struct inode *discard[MAXQUOTAS];
+
+	sb->s_qcop->quota_sync(sb, type);
+	/* This is not very clever (and fast) but currently I don't know about
+	 * any other simple way of getting quota data to disk and we must get
+	 * them there for userspace to be visible... */
+	if (sb->s_op->sync_fs)
+		sb->s_op->sync_fs(sb, 1);
+	sync_blockdev(sb->s_bdev);
+
+	/* Now when everything is written we can discard the pagecache so
+	 * that userspace sees the changes. We need i_sem and so we could
+	 * not do it inside dqonoff_sem. Moreover we need to be carefull
+	 * about races with quotaoff() (that is the reason why we have own
+	 * reference to inode). */
+	down(&sb_dqopt(sb)->dqonoff_sem);
+	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
+		discard[cnt] = NULL;
+		if (type != -1 && cnt != type)
+			continue;
+		if (!sb_has_quota_enabled(sb, cnt))
+			continue;
+		discard[cnt] = igrab(sb_dqopt(sb)->files[cnt]);
+	}
+	up(&sb_dqopt(sb)->dqonoff_sem);
+	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
+		if (discard[cnt]) {
+			down(&discard[cnt]->i_sem);
+			truncate_inode_pages(&discard[cnt]->i_data, 0);
+			up(&discard[cnt]->i_sem);
+			iput(discard[cnt]);
+		}
+	}
+}
+
 void sync_dquots(struct super_block *sb, int type)
 {
 	if (sb) {
 		if (sb->s_qcop->quota_sync)
-			sb->s_qcop->quota_sync(sb, type);
+			quota_sync_sb(sb, type);
 	}
 	else {
-		while ((sb = get_super_to_sync(type)) != 0) {
+		while ((sb = get_super_to_sync(type)) != NULL) {
 			if (sb->s_qcop->quota_sync)
-				sb->s_qcop->quota_sync(sb, type);
+				quota_sync_sb(sb, type);
 			drop_super(sb);
 		}
 	}
diff -Nru a/fs/quota_v1.c b/fs/quota_v1.c
--- a/fs/quota_v1.c	2005-03-01 23:39:08 -08:00
+++ b/fs/quota_v1.c	2005-03-01 23:39:08 -08:00
@@ -7,7 +7,6 @@
 #include <linux/init.h>
 #include <linux/module.h>
 
-#include <asm/uaccess.h>
 #include <asm/byteorder.h>
 
 MODULE_AUTHOR("Jan Kara");
@@ -41,23 +40,14 @@
 static int v1_read_dqblk(struct dquot *dquot)
 {
 	int type = dquot->dq_type;
-	struct file *filp;
-	mm_segment_t fs;
-	loff_t offset;
 	struct v1_disk_dqblk dqblk;
 
-	filp = sb_dqopt(dquot->dq_sb)->files[type];
-	if (filp == (struct file *)NULL)
+	if (!sb_dqopt(dquot->dq_sb)->files[type])
 		return -EINVAL;
 
-	/* Now we are sure filp is valid */
-	offset = v1_dqoff(dquot->dq_id);
 	/* Set structure to 0s in case read fails/is after end of file */
 	memset(&dqblk, 0, sizeof(struct v1_disk_dqblk));
-	fs = get_fs();
-	set_fs(KERNEL_DS);
-	filp->f_op->read(filp, (char *)&dqblk, sizeof(struct v1_disk_dqblk), &offset);
-	set_fs(fs);
+	dquot->dq_sb->s_op->quota_read(dquot->dq_sb, type, (char *)&dqblk, sizeof(struct v1_disk_dqblk), v1_dqoff(dquot->dq_id));
 
 	v1_disk2mem_dqblk(&dquot->dq_dqb, &dqblk);
 	if (dquot->dq_dqb.dqb_bhardlimit == 0 && dquot->dq_dqb.dqb_bsoftlimit == 0 &&
@@ -71,26 +61,18 @@
 static int v1_commit_dqblk(struct dquot *dquot)
 {
 	short type = dquot->dq_type;
-	struct file *filp;
-	mm_segment_t fs;
-	loff_t offset;
 	ssize_t ret;
 	struct v1_disk_dqblk dqblk;
 
-	filp = sb_dqopt(dquot->dq_sb)->files[type];
-	offset = v1_dqoff(dquot->dq_id);
-	fs = get_fs();
-	set_fs(KERNEL_DS);
-
 	v1_mem2disk_dqblk(&dqblk, &dquot->dq_dqb);
 	if (dquot->dq_id == 0) {
 		dqblk.dqb_btime = sb_dqopt(dquot->dq_sb)->info[type].dqi_bgrace;
 		dqblk.dqb_itime = sb_dqopt(dquot->dq_sb)->info[type].dqi_igrace;
 	}
 	ret = 0;
-	if (filp)
-		ret = filp->f_op->write(filp, (char *)&dqblk,
-					sizeof(struct v1_disk_dqblk), &offset);
+	if (sb_dqopt(dquot->dq_sb)->files[type])
+		ret = dquot->dq_sb->s_op->quota_write(dquot->dq_sb, type, (char *)&dqblk,
+					sizeof(struct v1_disk_dqblk), v1_dqoff(dquot->dq_id));
 	if (ret != sizeof(struct v1_disk_dqblk)) {
 		printk(KERN_WARNING "VFS: dquota write failed on dev %s\n",
 			dquot->dq_sb->s_id);
@@ -101,7 +83,6 @@
 	ret = 0;
 
 out:
-	set_fs(fs);
 	dqstats.writes++;
 
 	return ret;
@@ -121,14 +102,11 @@
 
 static int v1_check_quota_file(struct super_block *sb, int type)
 {
-	struct file *f = sb_dqopt(sb)->files[type];
-	struct inode *inode = f->f_dentry->d_inode;
+	struct inode *inode = sb_dqopt(sb)->files[type];
 	ulong blocks;
 	size_t off; 
 	struct v2_disk_dqheader dqhead;
-	mm_segment_t fs;
 	ssize_t size;
-	loff_t offset = 0;
 	loff_t isize;
 	static const uint quota_magics[] = V2_INITQMAGICS;
 
@@ -140,10 +118,7 @@
 	if ((blocks % sizeof(struct v1_disk_dqblk) * BLOCK_SIZE + off) % sizeof(struct v1_disk_dqblk))
 		return 0;
 	/* Doublecheck whether we didn't get file with new format - with old quotactl() this could happen */
-	fs = get_fs();
-	set_fs(KERNEL_DS);
-	size = f->f_op->read(f, (char *)&dqhead, sizeof(struct v2_disk_dqheader), &offset);
-	set_fs(fs);
+	size = sb->s_op->quota_read(sb, type, (char *)&dqhead, sizeof(struct v2_disk_dqheader), 0);
 	if (size != sizeof(struct v2_disk_dqheader))
 		return 1;	/* Probably not new format */
 	if (le32_to_cpu(dqhead.dqh_magic) != quota_magics[type])
@@ -155,16 +130,10 @@
 static int v1_read_file_info(struct super_block *sb, int type)
 {
 	struct quota_info *dqopt = sb_dqopt(sb);
-	mm_segment_t fs;
-	loff_t offset;
-	struct file *filp = dqopt->files[type];
 	struct v1_disk_dqblk dqblk;
 	int ret;
 
-	offset = v1_dqoff(0);
-	fs = get_fs();
-	set_fs(KERNEL_DS);
-	if ((ret = filp->f_op->read(filp, (char *)&dqblk, sizeof(struct v1_disk_dqblk), &offset)) != sizeof(struct v1_disk_dqblk)) {
+	if ((ret = sb->s_op->quota_read(sb, type, (char *)&dqblk, sizeof(struct v1_disk_dqblk), v1_dqoff(0))) != sizeof(struct v1_disk_dqblk)) {
 		if (ret >= 0)
 			ret = -EIO;
 		goto out;
@@ -173,38 +142,31 @@
 	dqopt->info[type].dqi_igrace = dqblk.dqb_itime ? dqblk.dqb_itime : MAX_IQ_TIME;
 	dqopt->info[type].dqi_bgrace = dqblk.dqb_btime ? dqblk.dqb_btime : MAX_DQ_TIME;
 out:
-	set_fs(fs);
 	return ret;
 }
 
 static int v1_write_file_info(struct super_block *sb, int type)
 {
 	struct quota_info *dqopt = sb_dqopt(sb);
-	mm_segment_t fs;
-	struct file *filp = dqopt->files[type];
 	struct v1_disk_dqblk dqblk;
-	loff_t offset;
 	int ret;
 
 	dqopt->info[type].dqi_flags &= ~DQF_INFO_DIRTY;
-	offset = v1_dqoff(0);
-	fs = get_fs();
-	set_fs(KERNEL_DS);
-	if ((ret = filp->f_op->read(filp, (char *)&dqblk, sizeof(struct v1_disk_dqblk), &offset)) != sizeof(struct v1_disk_dqblk)) {
+	if ((ret = sb->s_op->quota_read(sb, type, (char *)&dqblk,
+	    sizeof(struct v1_disk_dqblk), v1_dqoff(0))) != sizeof(struct v1_disk_dqblk)) {
 		if (ret >= 0)
 			ret = -EIO;
 		goto out;
 	}
 	dqblk.dqb_itime = dqopt->info[type].dqi_igrace;
 	dqblk.dqb_btime = dqopt->info[type].dqi_bgrace;
-	offset = v1_dqoff(0);
-	ret = filp->f_op->write(filp, (char *)&dqblk, sizeof(struct v1_disk_dqblk), &offset);
+	ret = sb->s_op->quota_write(sb, type, (char *)&dqblk,
+	      sizeof(struct v1_disk_dqblk), v1_dqoff(0));
 	if (ret == sizeof(struct v1_disk_dqblk))
 		ret = 0;
 	else if (ret > 0)
 		ret = -EIO;
 out:
-	set_fs(fs);
 	return ret;
 }
 
diff -Nru a/fs/quota_v2.c b/fs/quota_v2.c
--- a/fs/quota_v2.c	2005-03-01 23:39:09 -08:00
+++ b/fs/quota_v2.c	2005-03-01 23:39:09 -08:00
@@ -13,7 +13,6 @@
 #include <linux/slab.h>
 
 #include <asm/byteorder.h>
-#include <asm/uaccess.h>
 
 MODULE_AUTHOR("Jan Kara");
 MODULE_DESCRIPTION("Quota format v2 support");
@@ -30,19 +29,15 @@
 static int v2_check_quota_file(struct super_block *sb, int type)
 {
 	struct v2_disk_dqheader dqhead;
-	struct file *f = sb_dqopt(sb)->files[type];
-	mm_segment_t fs;
 	ssize_t size;
-	loff_t offset = 0;
 	static const uint quota_magics[] = V2_INITQMAGICS;
 	static const uint quota_versions[] = V2_INITQVERSIONS;
  
-	fs = get_fs();
-	set_fs(KERNEL_DS);
-	size = f->f_op->read(f, (char *)&dqhead, sizeof(struct v2_disk_dqheader), &offset);
-	set_fs(fs);
-	if (size != sizeof(struct v2_disk_dqheader))
+	size = sb->s_op->quota_read(sb, type, (char *)&dqhead, sizeof(struct v2_disk_dqheader), 0);
+	if (size != sizeof(struct v2_disk_dqheader)) {
+		printk("failed read\n");
 		return 0;
+	}
 	if (le32_to_cpu(dqhead.dqh_magic) != quota_magics[type] ||
 	    le32_to_cpu(dqhead.dqh_version) != quota_versions[type])
 		return 0;
@@ -52,20 +47,15 @@
 /* Read information header from quota file */
 static int v2_read_file_info(struct super_block *sb, int type)
 {
-	mm_segment_t fs;
 	struct v2_disk_dqinfo dinfo;
 	struct mem_dqinfo *info = sb_dqopt(sb)->info+type;
-	struct file *f = sb_dqopt(sb)->files[type];
 	ssize_t size;
-	loff_t offset = V2_DQINFOOFF;
 
-	fs = get_fs();
-	set_fs(KERNEL_DS);
-	size = f->f_op->read(f, (char *)&dinfo, sizeof(struct v2_disk_dqinfo), &offset);
-	set_fs(fs);
+	size = sb->s_op->quota_read(sb, type, (char *)&dinfo,
+	       sizeof(struct v2_disk_dqinfo), V2_DQINFOOFF);
 	if (size != sizeof(struct v2_disk_dqinfo)) {
 		printk(KERN_WARNING "Can't read info structure on device %s.\n",
-			f->f_dentry->d_sb->s_id);
+			sb->s_id);
 		return -1;
 	}
 	info->dqi_bgrace = le32_to_cpu(dinfo.dqi_bgrace);
@@ -80,12 +70,9 @@
 /* Write information header to quota file */
 static int v2_write_file_info(struct super_block *sb, int type)
 {
-	mm_segment_t fs;
 	struct v2_disk_dqinfo dinfo;
 	struct mem_dqinfo *info = sb_dqopt(sb)->info+type;
-	struct file *f = sb_dqopt(sb)->files[type];
 	ssize_t size;
-	loff_t offset = V2_DQINFOOFF;
 
 	spin_lock(&dq_data_lock);
 	info->dqi_flags &= ~DQF_INFO_DIRTY;
@@ -96,13 +83,11 @@
 	dinfo.dqi_blocks = cpu_to_le32(info->u.v2_i.dqi_blocks);
 	dinfo.dqi_free_blk = cpu_to_le32(info->u.v2_i.dqi_free_blk);
 	dinfo.dqi_free_entry = cpu_to_le32(info->u.v2_i.dqi_free_entry);
-	fs = get_fs();
-	set_fs(KERNEL_DS);
-	size = f->f_op->write(f, (char *)&dinfo, sizeof(struct v2_disk_dqinfo), &offset);
-	set_fs(fs);
+	size = sb->s_op->quota_write(sb, type, (char *)&dinfo,
+	       sizeof(struct v2_disk_dqinfo), V2_DQINFOOFF);
 	if (size != sizeof(struct v2_disk_dqinfo)) {
 		printk(KERN_WARNING "Can't write info structure on device %s.\n",
-			f->f_dentry->d_sb->s_id);
+			sb->s_id);
 		return -1;
 	}
 	return 0;
@@ -146,39 +131,24 @@
 	kfree(buf);
 }
 
-static ssize_t read_blk(struct file *filp, uint blk, dqbuf_t buf)
+static inline ssize_t read_blk(struct super_block *sb, int type, uint blk, dqbuf_t buf)
 {
-	mm_segment_t fs;
-	ssize_t ret;
-	loff_t offset = blk<<V2_DQBLKSIZE_BITS;
-
 	memset(buf, 0, V2_DQBLKSIZE);
-	fs = get_fs();
-	set_fs(KERNEL_DS);
-	ret = filp->f_op->read(filp, (char *)buf, V2_DQBLKSIZE, &offset);
-	set_fs(fs);
-	return ret;
+	return sb->s_op->quota_read(sb, type, (char *)buf,
+	       V2_DQBLKSIZE, blk << V2_DQBLKSIZE_BITS);
 }
 
-static ssize_t write_blk(struct file *filp, uint blk, dqbuf_t buf)
+static inline ssize_t write_blk(struct super_block *sb, int type, uint blk, dqbuf_t buf)
 {
-	mm_segment_t fs;
-	ssize_t ret;
-	loff_t offset = blk<<V2_DQBLKSIZE_BITS;
-
-	fs = get_fs();
-	set_fs(KERNEL_DS);
-	ret = filp->f_op->write(filp, (char *)buf, V2_DQBLKSIZE, &offset);
-	set_fs(fs);
-	return ret;
-
+	return sb->s_op->quota_write(sb, type, (char *)buf,
+	       V2_DQBLKSIZE, blk << V2_DQBLKSIZE_BITS);
 }
 
 /* Remove empty block from list and return it */
-static int get_free_dqblk(struct file *filp, int type)
+static int get_free_dqblk(struct super_block *sb, int type)
 {
 	dqbuf_t buf = getdqbuf();
-	struct mem_dqinfo *info = sb_dqinfo(filp->f_dentry->d_sb, type);
+	struct mem_dqinfo *info = sb_dqinfo(sb, type);
 	struct v2_disk_dqdbheader *dh = (struct v2_disk_dqdbheader *)buf;
 	int ret, blk;
 
@@ -186,17 +156,18 @@
 		return -ENOMEM;
 	if (info->u.v2_i.dqi_free_blk) {
 		blk = info->u.v2_i.dqi_free_blk;
-		if ((ret = read_blk(filp, blk, buf)) < 0)
+		if ((ret = read_blk(sb, type, blk, buf)) < 0)
 			goto out_buf;
 		info->u.v2_i.dqi_free_blk = le32_to_cpu(dh->dqdh_next_free);
 	}
 	else {
 		memset(buf, 0, V2_DQBLKSIZE);
-		if ((ret = write_blk(filp, info->u.v2_i.dqi_blocks, buf)) < 0)	/* Assure block allocation... */
+		/* Assure block allocation... */
+		if ((ret = write_blk(sb, type, info->u.v2_i.dqi_blocks, buf)) < 0)
 			goto out_buf;
 		blk = info->u.v2_i.dqi_blocks++;
 	}
-	mark_info_dirty(filp->f_dentry->d_sb, type);
+	mark_info_dirty(sb, type);
 	ret = blk;
 out_buf:
 	freedqbuf(buf);
@@ -204,9 +175,9 @@
 }
 
 /* Insert empty block to the list */
-static int put_free_dqblk(struct file *filp, int type, dqbuf_t buf, uint blk)
+static int put_free_dqblk(struct super_block *sb, int type, dqbuf_t buf, uint blk)
 {
-	struct mem_dqinfo *info = sb_dqinfo(filp->f_dentry->d_sb, type);
+	struct mem_dqinfo *info = sb_dqinfo(sb, type);
 	struct v2_disk_dqdbheader *dh = (struct v2_disk_dqdbheader *)buf;
 	int err;
 
@@ -214,17 +185,18 @@
 	dh->dqdh_prev_free = cpu_to_le32(0);
 	dh->dqdh_entries = cpu_to_le16(0);
 	info->u.v2_i.dqi_free_blk = blk;
-	mark_info_dirty(filp->f_dentry->d_sb, type);
-	if ((err = write_blk(filp, blk, buf)) < 0)	/* Some strange block. We had better leave it... */
+	mark_info_dirty(sb, type);
+	/* Some strange block. We had better leave it... */
+	if ((err = write_blk(sb, type, blk, buf)) < 0)
 		return err;
 	return 0;
 }
 
 /* Remove given block from the list of blocks with free entries */
-static int remove_free_dqentry(struct file *filp, int type, dqbuf_t buf, uint blk)
+static int remove_free_dqentry(struct super_block *sb, int type, dqbuf_t buf, uint blk)
 {
 	dqbuf_t tmpbuf = getdqbuf();
-	struct mem_dqinfo *info = sb_dqinfo(filp->f_dentry->d_sb, type);
+	struct mem_dqinfo *info = sb_dqinfo(sb, type);
 	struct v2_disk_dqdbheader *dh = (struct v2_disk_dqdbheader *)buf;
 	uint nextblk = le32_to_cpu(dh->dqdh_next_free), prevblk = le32_to_cpu(dh->dqdh_prev_free);
 	int err;
@@ -232,26 +204,27 @@
 	if (!tmpbuf)
 		return -ENOMEM;
 	if (nextblk) {
-		if ((err = read_blk(filp, nextblk, tmpbuf)) < 0)
+		if ((err = read_blk(sb, type, nextblk, tmpbuf)) < 0)
 			goto out_buf;
 		((struct v2_disk_dqdbheader *)tmpbuf)->dqdh_prev_free = dh->dqdh_prev_free;
-		if ((err = write_blk(filp, nextblk, tmpbuf)) < 0)
+		if ((err = write_blk(sb, type, nextblk, tmpbuf)) < 0)
 			goto out_buf;
 	}
 	if (prevblk) {
-		if ((err = read_blk(filp, prevblk, tmpbuf)) < 0)
+		if ((err = read_blk(sb, type, prevblk, tmpbuf)) < 0)
 			goto out_buf;
 		((struct v2_disk_dqdbheader *)tmpbuf)->dqdh_next_free = dh->dqdh_next_free;
-		if ((err = write_blk(filp, prevblk, tmpbuf)) < 0)
+		if ((err = write_blk(sb, type, prevblk, tmpbuf)) < 0)
 			goto out_buf;
 	}
 	else {
 		info->u.v2_i.dqi_free_entry = nextblk;
-		mark_info_dirty(filp->f_dentry->d_sb, type);
+		mark_info_dirty(sb, type);
 	}
 	freedqbuf(tmpbuf);
 	dh->dqdh_next_free = dh->dqdh_prev_free = cpu_to_le32(0);
-	if (write_blk(filp, blk, buf) < 0)	/* No matter whether write succeeds block is out of list */
+	/* No matter whether write succeeds block is out of list */
+	if (write_blk(sb, type, blk, buf) < 0)
 		printk(KERN_ERR "VFS: Can't write block (%u) with free entries.\n", blk);
 	return 0;
 out_buf:
@@ -260,10 +233,10 @@
 }
 
 /* Insert given block to the beginning of list with free entries */
-static int insert_free_dqentry(struct file *filp, int type, dqbuf_t buf, uint blk)
+static int insert_free_dqentry(struct super_block *sb, int type, dqbuf_t buf, uint blk)
 {
 	dqbuf_t tmpbuf = getdqbuf();
-	struct mem_dqinfo *info = sb_dqinfo(filp->f_dentry->d_sb, type);
+	struct mem_dqinfo *info = sb_dqinfo(sb, type);
 	struct v2_disk_dqdbheader *dh = (struct v2_disk_dqdbheader *)buf;
 	int err;
 
@@ -271,18 +244,18 @@
 		return -ENOMEM;
 	dh->dqdh_next_free = cpu_to_le32(info->u.v2_i.dqi_free_entry);
 	dh->dqdh_prev_free = cpu_to_le32(0);
-	if ((err = write_blk(filp, blk, buf)) < 0)
+	if ((err = write_blk(sb, type, blk, buf)) < 0)
 		goto out_buf;
 	if (info->u.v2_i.dqi_free_entry) {
-		if ((err = read_blk(filp, info->u.v2_i.dqi_free_entry, tmpbuf)) < 0)
+		if ((err = read_blk(sb, type, info->u.v2_i.dqi_free_entry, tmpbuf)) < 0)
 			goto out_buf;
 		((struct v2_disk_dqdbheader *)tmpbuf)->dqdh_prev_free = cpu_to_le32(blk);
-		if ((err = write_blk(filp, info->u.v2_i.dqi_free_entry, tmpbuf)) < 0)
+		if ((err = write_blk(sb, type, info->u.v2_i.dqi_free_entry, tmpbuf)) < 0)
 			goto out_buf;
 	}
 	freedqbuf(tmpbuf);
 	info->u.v2_i.dqi_free_entry = blk;
-	mark_info_dirty(filp->f_dentry->d_sb, type);
+	mark_info_dirty(sb, type);
 	return 0;
 out_buf:
 	freedqbuf(tmpbuf);
@@ -292,8 +265,8 @@
 /* Find space for dquot */
 static uint find_free_dqentry(struct dquot *dquot, int *err)
 {
-	struct file *filp = sb_dqopt(dquot->dq_sb)->files[dquot->dq_type];
-	struct mem_dqinfo *info = sb_dqopt(dquot->dq_sb)->info+dquot->dq_type;
+	struct super_block *sb = dquot->dq_sb;
+	struct mem_dqinfo *info = sb_dqopt(sb)->info+dquot->dq_type;
 	uint blk, i;
 	struct v2_disk_dqdbheader *dh;
 	struct v2_disk_dqblk *ddquot;
@@ -309,22 +282,23 @@
 	ddquot = GETENTRIES(buf);
 	if (info->u.v2_i.dqi_free_entry) {
 		blk = info->u.v2_i.dqi_free_entry;
-		if ((*err = read_blk(filp, blk, buf)) < 0)
+		if ((*err = read_blk(sb, dquot->dq_type, blk, buf)) < 0)
 			goto out_buf;
 	}
 	else {
-		blk = get_free_dqblk(filp, dquot->dq_type);
+		blk = get_free_dqblk(sb, dquot->dq_type);
 		if ((int)blk < 0) {
 			*err = blk;
 			freedqbuf(buf);
 			return 0;
 		}
 		memset(buf, 0, V2_DQBLKSIZE);
-		info->u.v2_i.dqi_free_entry = blk;	/* This is enough as block is already zeroed and entry list is empty... */
-		mark_info_dirty(dquot->dq_sb, dquot->dq_type);
+		/* This is enough as block is already zeroed and entry list is empty... */
+		info->u.v2_i.dqi_free_entry = blk;
+		mark_info_dirty(sb, dquot->dq_type);
 	}
 	if (le16_to_cpu(dh->dqdh_entries)+1 >= V2_DQSTRINBLK)	/* Block will be full? */
-		if ((*err = remove_free_dqentry(filp, dquot->dq_type, buf, blk)) < 0) {
+		if ((*err = remove_free_dqentry(sb, dquot->dq_type, buf, blk)) < 0) {
 			printk(KERN_ERR "VFS: find_free_dqentry(): Can't remove block (%u) from entry free list.\n", blk);
 			goto out_buf;
 		}
@@ -339,7 +313,7 @@
 		goto out_buf;
 	}
 #endif
-	if ((*err = write_blk(filp, blk, buf)) < 0) {
+	if ((*err = write_blk(sb, dquot->dq_type, blk, buf)) < 0) {
 		printk(KERN_ERR "VFS: find_free_dqentry(): Can't write quota data block %u.\n", blk);
 		goto out_buf;
 	}
@@ -354,7 +328,7 @@
 /* Insert reference to structure into the trie */
 static int do_insert_tree(struct dquot *dquot, uint *treeblk, int depth)
 {
-	struct file *filp = sb_dqopt(dquot->dq_sb)->files[dquot->dq_type];
+	struct super_block *sb = dquot->dq_sb;
 	dqbuf_t buf;
 	int ret = 0, newson = 0, newact = 0;
 	__le32 *ref;
@@ -363,7 +337,7 @@
 	if (!(buf = getdqbuf()))
 		return -ENOMEM;
 	if (!*treeblk) {
-		ret = get_free_dqblk(filp, dquot->dq_type);
+		ret = get_free_dqblk(sb, dquot->dq_type);
 		if (ret < 0)
 			goto out_buf;
 		*treeblk = ret;
@@ -371,7 +345,7 @@
 		newact = 1;
 	}
 	else {
-		if ((ret = read_blk(filp, *treeblk, buf)) < 0) {
+		if ((ret = read_blk(sb, dquot->dq_type, *treeblk, buf)) < 0) {
 			printk(KERN_ERR "VFS: Can't read tree quota block %u.\n", *treeblk);
 			goto out_buf;
 		}
@@ -394,10 +368,10 @@
 		ret = do_insert_tree(dquot, &newblk, depth+1);
 	if (newson && ret >= 0) {
 		ref[GETIDINDEX(dquot->dq_id, depth)] = cpu_to_le32(newblk);
-		ret = write_blk(filp, *treeblk, buf);
+		ret = write_blk(sb, dquot->dq_type, *treeblk, buf);
 	}
 	else if (newact && ret < 0)
-		put_free_dqblk(filp, dquot->dq_type, buf, *treeblk);
+		put_free_dqblk(sb, dquot->dq_type, buf, *treeblk);
 out_buf:
 	freedqbuf(buf);
 	return ret;
@@ -416,20 +390,15 @@
 static int v2_write_dquot(struct dquot *dquot)
 {
 	int type = dquot->dq_type;
-	struct file *filp;
-	mm_segment_t fs;
-	loff_t offset;
 	ssize_t ret;
 	struct v2_disk_dqblk ddquot, empty;
 
 	/* dq_off is guarded by dqio_sem */
 	if (!dquot->dq_off)
 		if ((ret = dq_insert_tree(dquot)) < 0) {
-			printk(KERN_ERR "VFS: Error %Zd occurred while creating quota.\n", ret);
+			printk(KERN_ERR "VFS: Error %zd occurred while creating quota.\n", ret);
 			return ret;
 		}
-	filp = sb_dqopt(dquot->dq_sb)->files[type];
-	offset = dquot->dq_off;
 	spin_lock(&dq_data_lock);
 	mem2diskdqb(&ddquot, &dquot->dq_dqb, dquot->dq_id);
 	/* Argh... We may need to write structure full of zeroes but that would be
@@ -439,10 +408,8 @@
 	if (!memcmp(&empty, &ddquot, sizeof(struct v2_disk_dqblk)))
 		ddquot.dqb_itime = cpu_to_le64(1);
 	spin_unlock(&dq_data_lock);
-	fs = get_fs();
-	set_fs(KERNEL_DS);
-	ret = filp->f_op->write(filp, (char *)&ddquot, sizeof(struct v2_disk_dqblk), &offset);
-	set_fs(fs);
+	ret = dquot->dq_sb->s_op->quota_write(dquot->dq_sb, type,
+	      (char *)&ddquot, sizeof(struct v2_disk_dqblk), dquot->dq_off);
 	if (ret != sizeof(struct v2_disk_dqblk)) {
 		printk(KERN_WARNING "VFS: dquota write failed on dev %s\n", dquot->dq_sb->s_id);
 		if (ret >= 0)
@@ -458,7 +425,8 @@
 /* Free dquot entry in data block */
 static int free_dqentry(struct dquot *dquot, uint blk)
 {
-	struct file *filp = sb_dqopt(dquot->dq_sb)->files[dquot->dq_type];
+	struct super_block *sb = dquot->dq_sb;
+	int type = dquot->dq_type;
 	struct v2_disk_dqdbheader *dh;
 	dqbuf_t buf = getdqbuf();
 	int ret = 0;
@@ -466,34 +434,39 @@
 	if (!buf)
 		return -ENOMEM;
 	if (dquot->dq_off >> V2_DQBLKSIZE_BITS != blk) {
-		printk(KERN_ERR "VFS: Quota structure has offset to other block (%u) than it should (%u).\n", blk, (uint)(dquot->dq_off >> V2_DQBLKSIZE_BITS));
+		printk(KERN_ERR "VFS: Quota structure has offset to other "
+		  "block (%u) than it should (%u).\n", blk,
+		  (uint)(dquot->dq_off >> V2_DQBLKSIZE_BITS));
 		goto out_buf;
 	}
-	if ((ret = read_blk(filp, blk, buf)) < 0) {
+	if ((ret = read_blk(sb, type, blk, buf)) < 0) {
 		printk(KERN_ERR "VFS: Can't read quota data block %u\n", blk);
 		goto out_buf;
 	}
 	dh = (struct v2_disk_dqdbheader *)buf;
 	dh->dqdh_entries = cpu_to_le16(le16_to_cpu(dh->dqdh_entries)-1);
 	if (!le16_to_cpu(dh->dqdh_entries)) {	/* Block got free? */
-		if ((ret = remove_free_dqentry(filp, dquot->dq_type, buf, blk)) < 0 ||
-		    (ret = put_free_dqblk(filp, dquot->dq_type, buf, blk)) < 0) {
-			printk(KERN_ERR "VFS: Can't move quota data block (%u) to free list.\n", blk);
+		if ((ret = remove_free_dqentry(sb, type, buf, blk)) < 0 ||
+		    (ret = put_free_dqblk(sb, type, buf, blk)) < 0) {
+			printk(KERN_ERR "VFS: Can't move quota data block (%u) "
+			  "to free list.\n", blk);
 			goto out_buf;
 		}
 	}
 	else {
-		memset(buf+(dquot->dq_off & ((1 << V2_DQBLKSIZE_BITS)-1)), 0, sizeof(struct v2_disk_dqblk));
+		memset(buf+(dquot->dq_off & ((1 << V2_DQBLKSIZE_BITS)-1)), 0,
+		  sizeof(struct v2_disk_dqblk));
 		if (le16_to_cpu(dh->dqdh_entries) == V2_DQSTRINBLK-1) {
 			/* Insert will write block itself */
-			if ((ret = insert_free_dqentry(filp, dquot->dq_type, buf, blk)) < 0) {
+			if ((ret = insert_free_dqentry(sb, type, buf, blk)) < 0) {
 				printk(KERN_ERR "VFS: Can't insert quota data block (%u) to free entry list.\n", blk);
 				goto out_buf;
 			}
 		}
 		else
-			if ((ret = write_blk(filp, blk, buf)) < 0) {
-				printk(KERN_ERR "VFS: Can't write quota data block %u\n", blk);
+			if ((ret = write_blk(sb, type, blk, buf)) < 0) {
+				printk(KERN_ERR "VFS: Can't write quota data "
+				  "block %u\n", blk);
 				goto out_buf;
 			}
 	}
@@ -506,7 +479,8 @@
 /* Remove reference to dquot from tree */
 static int remove_tree(struct dquot *dquot, uint *blk, int depth)
 {
-	struct file *filp = sb_dqopt(dquot->dq_sb)->files[dquot->dq_type];
+	struct super_block *sb = dquot->dq_sb;
+	int type = dquot->dq_type;
 	dqbuf_t buf = getdqbuf();
 	int ret = 0;
 	uint newblk;
@@ -514,7 +488,7 @@
 	
 	if (!buf)
 		return -ENOMEM;
-	if ((ret = read_blk(filp, *blk, buf)) < 0) {
+	if ((ret = read_blk(sb, type, *blk, buf)) < 0) {
 		printk(KERN_ERR "VFS: Can't read quota data block %u\n", *blk);
 		goto out_buf;
 	}
@@ -530,12 +504,13 @@
 		ref[GETIDINDEX(dquot->dq_id, depth)] = cpu_to_le32(0);
 		for (i = 0; i < V2_DQBLKSIZE && !buf[i]; i++);	/* Block got empty? */
 		if (i == V2_DQBLKSIZE) {
-			put_free_dqblk(filp, dquot->dq_type, buf, *blk);
+			put_free_dqblk(sb, type, buf, *blk);
 			*blk = 0;
 		}
 		else
-			if ((ret = write_blk(filp, *blk, buf)) < 0)
-				printk(KERN_ERR "VFS: Can't write quota tree block %u.\n", *blk);
+			if ((ret = write_blk(sb, type, *blk, buf)) < 0)
+				printk(KERN_ERR "VFS: Can't write quota tree "
+				  "block %u.\n", *blk);
 	}
 out_buf:
 	freedqbuf(buf);
@@ -555,7 +530,6 @@
 /* Find entry in block */
 static loff_t find_block_dqentry(struct dquot *dquot, uint blk)
 {
-	struct file *filp = sb_dqopt(dquot->dq_sb)->files[dquot->dq_type];
 	dqbuf_t buf = getdqbuf();
 	loff_t ret = 0;
 	int i;
@@ -563,27 +537,31 @@
 
 	if (!buf)
 		return -ENOMEM;
-	if ((ret = read_blk(filp, blk, buf)) < 0) {
+	if ((ret = read_blk(dquot->dq_sb, dquot->dq_type, blk, buf)) < 0) {
 		printk(KERN_ERR "VFS: Can't read quota tree block %u.\n", blk);
 		goto out_buf;
 	}
 	if (dquot->dq_id)
-		for (i = 0; i < V2_DQSTRINBLK && le32_to_cpu(ddquot[i].dqb_id) != dquot->dq_id; i++);
+		for (i = 0; i < V2_DQSTRINBLK &&
+		     le32_to_cpu(ddquot[i].dqb_id) != dquot->dq_id; i++);
 	else {	/* ID 0 as a bit more complicated searching... */
 		struct v2_disk_dqblk fakedquot;
 
 		memset(&fakedquot, 0, sizeof(struct v2_disk_dqblk));
 		for (i = 0; i < V2_DQSTRINBLK; i++)
-			if (!le32_to_cpu(ddquot[i].dqb_id) && memcmp(&fakedquot, ddquot+i, sizeof(struct v2_disk_dqblk)))
+			if (!le32_to_cpu(ddquot[i].dqb_id) &&
+			    memcmp(&fakedquot, ddquot+i, sizeof(struct v2_disk_dqblk)))
 				break;
 	}
 	if (i == V2_DQSTRINBLK) {
-		printk(KERN_ERR "VFS: Quota for id %u referenced but not present.\n", dquot->dq_id);
+		printk(KERN_ERR "VFS: Quota for id %u referenced "
+		  "but not present.\n", dquot->dq_id);
 		ret = -EIO;
 		goto out_buf;
 	}
 	else
-		ret = (blk << V2_DQBLKSIZE_BITS) + sizeof(struct v2_disk_dqdbheader) + i * sizeof(struct v2_disk_dqblk);
+		ret = (blk << V2_DQBLKSIZE_BITS) + sizeof(struct
+		  v2_disk_dqdbheader) + i * sizeof(struct v2_disk_dqblk);
 out_buf:
 	freedqbuf(buf);
 	return ret;
@@ -592,14 +570,13 @@
 /* Find entry for given id in the tree */
 static loff_t find_tree_dqentry(struct dquot *dquot, uint blk, int depth)
 {
-	struct file *filp = sb_dqopt(dquot->dq_sb)->files[dquot->dq_type];
 	dqbuf_t buf = getdqbuf();
 	loff_t ret = 0;
 	__le32 *ref = (__le32 *)buf;
 
 	if (!buf)
 		return -ENOMEM;
-	if ((ret = read_blk(filp, blk, buf)) < 0) {
+	if ((ret = read_blk(dquot->dq_sb, dquot->dq_type, blk, buf)) < 0) {
 		printk(KERN_ERR "VFS: Can't read quota tree block %u.\n", blk);
 		goto out_buf;
 	}
@@ -625,16 +602,13 @@
 static int v2_read_dquot(struct dquot *dquot)
 {
 	int type = dquot->dq_type;
-	struct file *filp;
-	mm_segment_t fs;
 	loff_t offset;
 	struct v2_disk_dqblk ddquot, empty;
 	int ret = 0;
 
-	filp = sb_dqopt(dquot->dq_sb)->files[type];
-
 #ifdef __QUOTA_V2_PARANOIA
-	if (!filp || !dquot->dq_sb) {	/* Invalidated quota? */
+	/* Invalidated quota? */
+	if (!dquot->dq_sb || !sb_dqopt(dquot->dq_sb)->files[type]) {
 		printk(KERN_ERR "VFS: Quota invalidated while reading!\n");
 		return -EIO;
 	}
@@ -642,7 +616,8 @@
 	offset = find_dqentry(dquot);
 	if (offset <= 0) {	/* Entry not present? */
 		if (offset < 0)
-			printk(KERN_ERR "VFS: Can't read quota structure for id %u.\n", dquot->dq_id);
+			printk(KERN_ERR "VFS: Can't read quota "
+			  "structure for id %u.\n", dquot->dq_id);
 		dquot->dq_off = 0;
 		set_bit(DQ_FAKE_B, &dquot->dq_flags);
 		memset(&dquot->dq_dqb, 0, sizeof(struct mem_dqblk));
@@ -650,12 +625,13 @@
 	}
 	else {
 		dquot->dq_off = offset;
-		fs = get_fs();
-		set_fs(KERNEL_DS);
-		if ((ret = filp->f_op->read(filp, (char *)&ddquot, sizeof(struct v2_disk_dqblk), &offset)) != sizeof(struct v2_disk_dqblk)) {
+		if ((ret = dquot->dq_sb->s_op->quota_read(dquot->dq_sb, type,
+		    (char *)&ddquot, sizeof(struct v2_disk_dqblk), offset))
+		    != sizeof(struct v2_disk_dqblk)) {
 			if (ret >= 0)
 				ret = -EIO;
-			printk(KERN_ERR "VFS: Error while reading quota structure for id %u.\n", dquot->dq_id);
+			printk(KERN_ERR "VFS: Error while reading quota "
+			  "structure for id %u.\n", dquot->dq_id);
 			memset(&ddquot, 0, sizeof(struct v2_disk_dqblk));
 		}
 		else {
@@ -666,7 +642,6 @@
 			if (!memcmp(&empty, &ddquot, sizeof(struct v2_disk_dqblk)))
 				ddquot.dqb_itime = 0;
 		}
-		set_fs(fs);
 		disk2memdqb(&dquot->dq_dqb, &ddquot);
 		if (!dquot->dq_dqb.dqb_bhardlimit &&
 			!dquot->dq_dqb.dqb_bsoftlimit &&
diff -Nru a/fs/ramfs/inode.c b/fs/ramfs/inode.c
--- a/fs/ramfs/inode.c	2005-03-01 23:38:55 -08:00
+++ b/fs/ramfs/inode.c	2005-03-01 23:38:55 -08:00
@@ -186,6 +186,7 @@
 	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
 	sb->s_magic = RAMFS_MAGIC;
 	sb->s_op = &ramfs_ops;
+	sb->s_time_gran = 1;
 	inode = ramfs_get_inode(sb, S_IFDIR | 0755, 0);
 	if (!inode)
 		return -ENOMEM;
diff -Nru a/fs/read_write.c b/fs/read_write.c
--- a/fs/read_write.c	2005-03-01 23:39:07 -08:00
+++ b/fs/read_write.c	2005-03-01 23:39:07 -08:00
@@ -182,6 +182,27 @@
 }
 #endif
 
+
+int rw_verify_area(int read_write, struct file *file, loff_t *ppos, size_t count)
+{
+	struct inode *inode;
+	loff_t pos;
+
+	if (unlikely(count > file->f_maxcount))
+		goto Einval;
+	pos = *ppos;
+	if (unlikely((pos < 0) || (loff_t) (pos + count) < 0))
+		goto Einval;
+
+	inode = file->f_dentry->d_inode;
+	if (inode->i_flock && MANDATORY_LOCK(inode))
+		return locks_mandatory_area(read_write == READ ? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE, inode, file, pos, count);
+	return 0;
+
+Einval:
+	return -EINVAL;
+}
+
 ssize_t do_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos)
 {
 	struct kiocb kiocb;
@@ -200,15 +221,16 @@
 
 ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos)
 {
-	struct inode *inode = file->f_dentry->d_inode;
 	ssize_t ret;
 
 	if (!(file->f_mode & FMODE_READ))
 		return -EBADF;
 	if (!file->f_op || (!file->f_op->read && !file->f_op->aio_read))
 		return -EINVAL;
+	if (unlikely(!access_ok(VERIFY_WRITE, buf, count)))
+		return -EFAULT;
 
-	ret = locks_verify_area(FLOCK_VERIFY_READ, inode, file, *pos, count);
+	ret = rw_verify_area(READ, file, pos, count);
 	if (!ret) {
 		ret = security_file_permission (file, MAY_READ);
 		if (!ret) {
@@ -216,8 +238,11 @@
 				ret = file->f_op->read(file, buf, count, pos);
 			else
 				ret = do_sync_read(file, buf, count, pos);
-			if (ret > 0)
+			if (ret > 0) {
 				dnotify_parent(file->f_dentry, DN_ACCESS);
+				current->rchar += ret;
+			}
+			current->syscr++;
 		}
 	}
 
@@ -244,15 +269,16 @@
 
 ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_t *pos)
 {
-	struct inode *inode = file->f_dentry->d_inode;
 	ssize_t ret;
 
 	if (!(file->f_mode & FMODE_WRITE))
 		return -EBADF;
 	if (!file->f_op || (!file->f_op->write && !file->f_op->aio_write))
 		return -EINVAL;
+	if (unlikely(!access_ok(VERIFY_READ, buf, count)))
+		return -EFAULT;
 
-	ret = locks_verify_area(FLOCK_VERIFY_WRITE, inode, file, *pos, count);
+	ret = rw_verify_area(WRITE, file, pos, count);
 	if (!ret) {
 		ret = security_file_permission (file, MAY_WRITE);
 		if (!ret) {
@@ -260,8 +286,11 @@
 				ret = file->f_op->write(file, buf, count, pos);
 			else
 				ret = do_sync_write(file, buf, count, pos);
-			if (ret > 0)
+			if (ret > 0) {
 				dnotify_parent(file->f_dentry, DN_MODIFY);
+				current->wchar += ret;
+			}
+			current->syscw++;
 		}
 	}
 
@@ -379,6 +408,9 @@
 
 EXPORT_SYMBOL(iov_shorten);
 
+/* A write operation does a read from user space and vice versa */
+#define vrfy_dir(type) ((type) == READ ? VERIFY_WRITE : VERIFY_READ)
+
 static ssize_t do_readv_writev(int type, struct file *file,
 			       const struct iovec __user * uvector,
 			       unsigned long nr_segs, loff_t *pos)
@@ -393,7 +425,6 @@
 	int seg;
 	io_fn_t fn;
 	iov_fn_t fnv;
-	struct inode *inode;
 
 	/*
 	 * SuS says "The readv() function *may* fail if the iovcnt argument
@@ -433,8 +464,11 @@
 	tot_len = 0;
 	ret = -EINVAL;
 	for (seg = 0; seg < nr_segs; seg++) {
+		void __user *buf = iov[seg].iov_base;
 		ssize_t len = (ssize_t)iov[seg].iov_len;
 
+		if (unlikely(!access_ok(vrfy_dir(type), buf, len)))
+			goto Efault;
 		if (len < 0)	/* size_t not fitting an ssize_t .. */
 			goto out;
 		tot_len += len;
@@ -446,11 +480,7 @@
 		goto out;
 	}
 
-	inode = file->f_dentry->d_inode;
-	/* VERIFY_WRITE actually means a read, as we write to user space */
-	ret = locks_verify_area((type == READ 
-				 ? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE),
-				inode, file, *pos, tot_len);
+	ret = rw_verify_area(type, file, pos, tot_len);
 	if (ret)
 		goto out;
 
@@ -497,6 +527,9 @@
 		dnotify_parent(file->f_dentry,
 				(type == READ) ? DN_ACCESS : DN_MODIFY);
 	return ret;
+Efault:
+	ret = -EFAULT;
+	goto out;
 }
 
 ssize_t vfs_readv(struct file *file, const struct iovec __user *vec,
@@ -540,6 +573,9 @@
 		fput_light(file, fput_needed);
 	}
 
+	if (ret > 0)
+		current->rchar += ret;
+	current->syscr++;
 	return ret;
 }
 
@@ -558,6 +594,9 @@
 		fput_light(file, fput_needed);
 	}
 
+	if (ret > 0)
+		current->wchar += ret;
+	current->syscw++;
 	return ret;
 }
 
@@ -591,7 +630,7 @@
 	else
 		if (!(in_file->f_mode & FMODE_PREAD))
 			goto fput_in;
-	retval = locks_verify_area(FLOCK_VERIFY_READ, in_inode, in_file, *ppos, count);
+	retval = rw_verify_area(READ, in_file, ppos, count);
 	if (retval)
 		goto fput_in;
 
@@ -612,7 +651,7 @@
 	if (!out_file->f_op || !out_file->f_op->sendpage)
 		goto fput_out;
 	out_inode = out_file->f_dentry->d_inode;
-	retval = locks_verify_area(FLOCK_VERIFY_WRITE, out_inode, out_file, out_file->f_pos, count);
+	retval = rw_verify_area(WRITE, out_file, &out_file->f_pos, count);
 	if (retval)
 		goto fput_out;
 
@@ -635,6 +674,13 @@
 	}
 
 	retval = in_file->f_op->sendfile(in_file, ppos, count, file_send_actor, out_file);
+
+	if (retval > 0) {
+		current->rchar += retval;
+		current->wchar += retval;
+	}
+	current->syscr++;
+	current->syscw++;
 
 	if (*ppos > max)
 		retval = -EOVERFLOW;
diff -Nru a/fs/readdir.c b/fs/readdir.c
--- a/fs/readdir.c	2005-03-01 23:38:57 -08:00
+++ b/fs/readdir.c	2005-03-01 23:38:57 -08:00
@@ -287,7 +287,9 @@
 	lastdirent = buf.previous;
 	if (lastdirent) {
 		typeof(lastdirent->d_off) d_off = file->f_pos;
-		__put_user(d_off, &lastdirent->d_off);
+		error = -EFAULT;
+		if (__put_user(d_off, &lastdirent->d_off))
+			goto out_putf;
 		error = count - buf.count;
 	}
 
diff -Nru a/fs/reiserfs/bitmap.c b/fs/reiserfs/bitmap.c
--- a/fs/reiserfs/bitmap.c	2005-03-01 23:39:07 -08:00
+++ b/fs/reiserfs/bitmap.c	2005-03-01 23:39:07 -08:00
@@ -405,7 +405,7 @@
 }
 
 /* preallocated blocks don't need to be run through journal_mark_freed */
-void reiserfs_free_prealloc_block (struct reiserfs_transaction_handle *th, 
+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");
@@ -956,14 +956,14 @@
     if (!hint->formatted_node) {
         int quota_ret;
 #ifdef REISERQUOTA_DEBUG
-	reiserfs_debug (s, "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 ) {
 #ifdef REISERQUOTA_DEBUG
-	    reiserfs_debug (s, "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)
@@ -1009,7 +1009,7 @@
 	    /* Free the blocks */
 	    if (!hint->formatted_node) {
 #ifdef REISERQUOTA_DEBUG
-		reiserfs_debug (s, "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 */
 	    }
@@ -1029,7 +1029,7 @@
 	 nr_allocated + REISERFS_I(hint->inode)->i_prealloc_count) {
     /* Some of preallocation blocks were not allocated */
 #ifdef REISERQUOTA_DEBUG
-	reiserfs_debug (s, "reiserquota: freeing (failed prealloc) %d blocks id=%u", amount_needed + hint->prealloc_size - nr_allocated - INODE_INFO(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 -
diff -Nru a/fs/reiserfs/dir.c b/fs/reiserfs/dir.c
--- a/fs/reiserfs/dir.c	2005-03-01 23:38:58 -08:00
+++ b/fs/reiserfs/dir.c	2005-03-01 23:38:58 -08:00
@@ -15,7 +15,7 @@
 extern struct reiserfs_key  MIN_KEY;
 
 static int reiserfs_readdir (struct file *, void *, filldir_t);
-int reiserfs_dir_fsync(struct file *filp, struct dentry *dentry, int datasync) ;
+static int reiserfs_dir_fsync(struct file *filp, struct dentry *dentry, int datasync) ;
 
 struct file_operations reiserfs_dir_operations = {
     .read	= generic_read_dir,
@@ -24,7 +24,7 @@
     .ioctl	= reiserfs_ioctl,
 };
 
-int reiserfs_dir_fsync(struct file *filp, struct dentry *dentry, int datasync) {
+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);
diff -Nru a/fs/reiserfs/do_balan.c b/fs/reiserfs/do_balan.c
--- a/fs/reiserfs/do_balan.c	2005-03-01 23:38:53 -08:00
+++ b/fs/reiserfs/do_balan.c	2005-03-01 23:38:53 -08:00
@@ -1382,7 +1382,7 @@
 }
 
 
-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]) != 
@@ -1422,14 +1422,14 @@
 }
 
 
-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));
 }
 
-void check_internal_levels (struct tree_balance * tb)
+static void check_internal_levels (struct tree_balance * tb)
 {
   int h;
 
diff -Nru a/fs/reiserfs/file.c b/fs/reiserfs/file.c
--- a/fs/reiserfs/file.c	2005-03-01 23:38:44 -08:00
+++ b/fs/reiserfs/file.c	2005-03-01 23:38:44 -08:00
@@ -54,7 +54,7 @@
     /* 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
+     * us to log any additional blocks (including quota blocks)
      */
     err = journal_begin(&th, inode->i_sb, 1);
     if (err) {
@@ -147,7 +147,7 @@
 /* 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 */
-int reiserfs_allocate_blocks_for_region(
+static int reiserfs_allocate_blocks_for_region(
 				struct reiserfs_transaction_handle *th,
 				struct inode *inode, /* Inode we work with */
 				loff_t pos, /* Writing position */
@@ -201,7 +201,7 @@
     /* 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); // Wish I know if this number enough
+    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) ;
@@ -576,7 +576,7 @@
         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);
+        err = journal_end(th, inode->i_sb, JOURNAL_PER_BALANCE_CNT * 3 + 1 + 2 * REISERFS_QUOTA_TRANS_BLOCKS);
         if (err)
             res = err;
     }
@@ -587,8 +587,8 @@
 }
 
 /* Unlock pages prepared by reiserfs_prepare_file_region_for_write */
-void reiserfs_unprepare_pages(struct page **prepared_pages, /* list of locked pages */
-			      int num_pages /* amount of pages */) {
+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++) {
@@ -602,7 +602,7 @@
 
 /* This function will copy data from userspace to specified pages within
    supplied byte range */
-int reiserfs_copy_from_user_to_file_region(
+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 */
@@ -619,7 +619,7 @@
     int offset; // offset in page
 
     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
+	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);
@@ -714,12 +714,12 @@
 /* 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. */
-int reiserfs_submit_file_region_for_write(
+static int reiserfs_submit_file_region_for_write(
 				struct reiserfs_transaction_handle *th,
 				struct inode *inode,
 				loff_t pos, /* Writing position offset */
-				int num_pages, /* Number of pages to write */
-				int write_bytes, /* number of bytes to write */
+				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 */
 				)
 {
@@ -795,7 +795,7 @@
 
 /* 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 */
-int reiserfs_check_for_tail_and_convert( struct inode *inode, /* inode to deal with */
+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 */
 				        )
@@ -851,12 +851,12 @@
    append), it is zeroed, then. 
    Returns number of unallocated blocks that should be allocated to cover
    new file data.*/
-int reiserfs_prepare_file_region_for_write(
+static int reiserfs_prepare_file_region_for_write(
 				struct inode *inode /* Inode of the file */,
 				loff_t pos, /* position in the file */
-				int num_pages, /* number of pages to
+				size_t num_pages, /* number of pages to
 					          prepare */
-				int write_bytes, /* Amount of bytes to be
+				size_t write_bytes, /* Amount of bytes to be
 						    overwritten from
 						    @pos */
 				struct page **prepared_pages /* pointer to array
@@ -1148,7 +1148,7 @@
    Future Features: providing search_by_key with hints.
 
 */
-ssize_t reiserfs_file_write( struct file *file, /* the file we are going to write into */
+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 */
@@ -1252,10 +1252,9 @@
     while ( count > 0) {
 	/* This is the main loop in which we running until some error occures
 	   or until we write all of the data. */
-	int num_pages;/* amount of pages we are going to write this iteration */
-	int write_bytes; /* amount of bytes to write during this iteration */
-	int blocks_to_allocate; /* how much blocks we need to allocate for
-				   this iteration */
+	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
@@ -1269,7 +1268,7 @@
 	    /* 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(int, REISERFS_WRITE_PAGES_AT_A_TIME, reiserfs_can_fit_pages(inode->i_sb));
+	    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));
@@ -1295,7 +1294,7 @@
 	    // 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(int, count, inode->i_sb->s_blocksize - (pos & (inode->i_sb->s_blocksize - 1)));
+	    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));
diff -Nru a/fs/reiserfs/fix_node.c b/fs/reiserfs/fix_node.c
--- a/fs/reiserfs/fix_node.c	2005-03-01 23:38:54 -08:00
+++ b/fs/reiserfs/fix_node.c	2005-03-01 23:38:54 -08:00
@@ -510,9 +510,10 @@
 	// 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)
+	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 item");
+			      "directory or indirect item");
     }
 
     /* now we know S2bytes, calculate S1bytes */
@@ -724,7 +725,7 @@
 }
 
 
-void free_buffers_in_tb (
+static void free_buffers_in_tb (
 		       struct tree_balance * p_s_tb
 		       ) {
   int n_counter;
diff -Nru a/fs/reiserfs/ibalance.c b/fs/reiserfs/ibalance.c
--- a/fs/reiserfs/ibalance.c	2005-03-01 23:38:58 -08:00
+++ b/fs/reiserfs/ibalance.c	2005-03-01 23:38:58 -08:00
@@ -698,7 +698,7 @@
 
 
 /* Replace delimiting key of buffers L[h] and S[h] by the given key.*/
-void	replace_lkey (
+static void replace_lkey (
 		      struct tree_balance * tb,
 		      int h,
 		      struct item_head * key
@@ -718,7 +718,7 @@
 
 
 /* Replace delimiting key of buffers S[h] and R[h] by the given key.*/
-void	replace_rkey (
+static void replace_rkey (
 		      struct tree_balance * tb,
 		      int h,
 		      struct item_head * key
diff -Nru a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
--- a/fs/reiserfs/inode.c	2005-03-01 23:38:55 -08:00
+++ b/fs/reiserfs/inode.c	2005-03-01 23:38:55 -08:00
@@ -20,27 +20,19 @@
 
 extern int reiserfs_default_io_size; /* default io size devuned in super.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 */
-
-static int reiserfs_get_block (struct inode * inode, sector_t block,
-			       struct buffer_head * bh_result, int create);
 static int reiserfs_commit_write(struct file *f, struct page *page,
                                  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)
 {
-    int jbegin_count = JOURNAL_PER_BALANCE_CNT * 2; 
+    /* 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);
 
-    DQUOT_FREE_INODE(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); 
@@ -58,6 +50,11 @@
 	    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;
@@ -408,8 +405,8 @@
 
 // this is called to create file map. So, _get_block_create_0 will not
 // read direct item
-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;
@@ -592,8 +589,9 @@
         . 3 balancings in direct->indirect conversion
         . 1 block involved into reiserfs_update_sd()
        XXX in practically impossible worst case direct2indirect()
-       can incur (much) more that 3 balancings. */
-    int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3 + 1;
+       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 ;
@@ -1569,16 +1567,6 @@
     return 0;
 }
 
-/* FIXME: no need any more. right? */
-int reiserfs_sync_inode (struct reiserfs_transaction_handle *th, struct inode * inode)
-{
-  int err = 0;
-
-  reiserfs_update_sd (th, inode);
-  return err;
-}
-
-
 /* 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, 
@@ -1699,6 +1687,10 @@
 
     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;
@@ -1736,7 +1728,8 @@
     if( S_ISLNK( inode -> i_mode ) )
 	    inode -> i_flags &= ~ ( S_IMMUTABLE | S_APPEND );
 
-    inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
+    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;
@@ -1866,9 +1859,12 @@
     /* Invalidate the object, nothing was inserted yet */
     INODE_PKEY(inode)->k_objectid = 0;
 
-    /* dquot_drop must be done outside a transaction */
-    journal_end(th, th->t_super, th->t_blocks_allocated) ;
+    /* 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);
@@ -2416,7 +2412,7 @@
     return reiserfs_write_full_page(page, wbc) ;
 }
 
-int reiserfs_prepare_write(struct file *f, struct page *page, 
+static int reiserfs_prepare_write(struct file *f, struct page *page,
 			   unsigned from, unsigned to) {
     struct inode *inode = page->mapping->host ;
     int ret;
@@ -2796,8 +2792,25 @@
 	    (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) {
                 error = reiserfs_chown_xattrs (inode, attr);
 
-                if (!error)
+                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) ;
diff -Nru a/fs/reiserfs/ioctl.c b/fs/reiserfs/ioctl.c
--- a/fs/reiserfs/ioctl.c	2005-03-01 23:38:56 -08:00
+++ b/fs/reiserfs/ioctl.c	2005-03-01 23:38:56 -08:00
@@ -9,6 +9,8 @@
 #include <linux/pagemap.h>
 #include <linux/smp_lock.h>
 
+static int reiserfs_unpack (struct inode * inode, struct file * filp);
+
 /*
 ** reiserfs_ioctl - handler for ioctl for inode
 ** supported commands:
@@ -61,7 +63,7 @@
 		}
 		sd_attrs_to_i_attrs( flags, inode );
 		REISERFS_I(inode) -> i_attrs = flags;
-		inode->i_ctime = CURRENT_TIME;
+		inode->i_ctime = CURRENT_TIME_SEC;
 		mark_inode_dirty(inode);
 		return 0;
 	}
@@ -74,7 +76,7 @@
 			return -EROFS;
 		if (get_user(inode->i_generation, (int __user *) arg))
 			return -EFAULT;	
-		inode->i_ctime = CURRENT_TIME;
+		inode->i_ctime = CURRENT_TIME_SEC;
 		mark_inode_dirty(inode);
 		return 0;
 	default:
@@ -87,7 +89,7 @@
 ** Function try to convert tail from direct item into indirect.
 ** It set up nopack attribute in the REISERFS_I(inode)->nopack
 */
-int reiserfs_unpack (struct inode * inode, struct file * filp)
+static int reiserfs_unpack (struct inode * inode, struct file * filp)
 {
     int retval = 0;
     int index ;
diff -Nru a/fs/reiserfs/item_ops.c b/fs/reiserfs/item_ops.c
--- a/fs/reiserfs/item_ops.c	2005-03-01 23:39:07 -08:00
+++ b/fs/reiserfs/item_ops.c	2005-03-01 23:39:07 -08:00
@@ -110,7 +110,7 @@
 		      vi->vi_index, vi->vi_type, vi->vi_ih);
 }
 
-struct item_operations stat_data_ops = {
+static struct item_operations stat_data_ops = {
 	.bytes_number		= sd_bytes_number,
 	.decrement_key		= sd_decrement_key,
 	.is_left_mergeable	= sd_is_left_mergeable,
@@ -213,7 +213,7 @@
 		      vi->vi_index, vi->vi_type, vi->vi_ih);
 }
 
-struct item_operations direct_ops = {
+static struct item_operations direct_ops = {
 	.bytes_number		= direct_bytes_number,
 	.decrement_key		= direct_decrement_key,
 	.is_left_mergeable	= direct_is_left_mergeable,
@@ -367,7 +367,7 @@
 		      vi->vi_index, vi->vi_type, vi->vi_ih);
 }
 
-struct item_operations indirect_ops = {
+static struct item_operations indirect_ops = {
 	.bytes_number		= indirect_bytes_number,
 	.decrement_key		= indirect_decrement_key,
 	.is_left_mergeable	= indirect_is_left_mergeable,
@@ -660,7 +660,7 @@
     printk ("\n");
 }
 
-struct item_operations direntry_ops = {
+static struct item_operations direntry_ops = {
 	.bytes_number		= direntry_bytes_number,
 	.decrement_key		= direntry_decrement_key,
 	.is_left_mergeable	= direntry_is_left_mergeable,
@@ -750,7 +750,7 @@
     reiserfs_warning (NULL, "green-16011: Invalid item type observed, run fsck ASAP");
 }
 
-struct item_operations errcatch_ops = {
+static struct item_operations errcatch_ops = {
     errcatch_bytes_number,
     errcatch_decrement_key,
     errcatch_is_left_mergeable,
diff -Nru a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c
--- a/fs/reiserfs/journal.c	2005-03-01 23:38:59 -08:00
+++ b/fs/reiserfs/journal.c	2005-03-01 23:38:59 -08:00
@@ -50,7 +50,6 @@
 #include <linux/stat.h>
 #include <linux/string.h>
 #include <linux/smp_lock.h>
-#include <linux/suspend.h>
 #include <linux/buffer_head.h>
 #include <linux/workqueue.h>
 #include <linux/writeback.h>
@@ -436,19 +435,6 @@
   return (struct reiserfs_journal_cnode *)0 ;
 }
 
-/* returns a cnode with same size, block number and dev as bh in the current transaction hash.  NULL if not found */
-static inline struct reiserfs_journal_cnode *get_journal_hash(struct super_block *p_s_sb, struct buffer_head *bh) {
-  struct reiserfs_journal *journal = SB_JOURNAL (p_s_sb);
-  struct reiserfs_journal_cnode *cn ;
-  if (bh) {
-    cn =  get_journal_hash_dev(p_s_sb, journal->j_hash_table, bh->b_blocknr);
-  }
-  else {
-    return (struct reiserfs_journal_cnode *)0 ;
-  }
-  return cn ;
-}
-
 /*
 ** this actually means 'can this block be reallocated yet?'.  If you set search_all, a block can only be allocated
 ** if it is not in the current transaction, was not freed by the current transaction, and has no chance of ever
@@ -516,7 +502,7 @@
 
 /* insert cn into table
 */
-inline void insert_journal_hash(struct reiserfs_journal_cnode **table, struct reiserfs_journal_cnode *cn) {
+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) ;
@@ -693,7 +679,7 @@
 }
 
 
-atomic_t nr_reiserfs_jh = ATOMIC_INIT(0);
+static atomic_t nr_reiserfs_jh = ATOMIC_INIT(0);
 static struct reiserfs_jh *alloc_jh(void) {
     struct reiserfs_jh *jh;
     while(1) {
@@ -1090,7 +1076,7 @@
   return NULL ;
 }
 
-void remove_journal_hash(struct super_block *, struct reiserfs_journal_cnode **,
+static void remove_journal_hash(struct super_block *, struct reiserfs_journal_cnode **,
 struct reiserfs_journal_list *, unsigned long, int);
 
 /*
@@ -2028,7 +2014,7 @@
    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! */
-struct buffer_head * reiserfs_breada (struct block_device *dev, int block, int bufsize,
+static struct buffer_head * reiserfs_breada (struct block_device *dev, int block, int bufsize,
 			    unsigned int max_block)
 {
 	struct buffer_head * bhlist[BUFNR];
@@ -3848,7 +3834,7 @@
   return journal->j_errno;
 }
 
-void
+static void
 __reiserfs_journal_abort_hard (struct super_block *sb)
 {
     struct reiserfs_journal *journal = SB_JOURNAL (sb);
@@ -3866,7 +3852,7 @@
 #endif
 }
 
-void
+static void
 __reiserfs_journal_abort_soft (struct super_block *sb, int errno)
 {
     struct reiserfs_journal *journal = SB_JOURNAL (sb);
diff -Nru a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c
--- a/fs/reiserfs/namei.c	2005-03-01 23:38:58 -08:00
+++ b/fs/reiserfs/namei.c	2005-03-01 23:38:58 -08:00
@@ -534,7 +534,7 @@
     }
 
     dir->i_size += paste_size;
-    dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+    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);
@@ -545,7 +545,7 @@
 
 /* quota utility function, call if you've had to abort after calling
 ** new_inode_init, and have not called reiserfs_new_inode yet.
-** This should only be called on inodes that do not hav stat data
+** 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) {
@@ -557,10 +557,9 @@
 }
 
 /* utility function that does setup for reiserfs_new_inode.  
-** DQUOT_ALLOC_INODE cannot be called inside a transaction, so we had
-** to pull some bits of reiserfs_new_inode out into this func.
-** Yes, the actual quota calls are missing, they are part of the quota
-** patch.
+** DQUOT_INIT needs lots of credits so it's better to have it
+** 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) {
 
@@ -578,10 +577,6 @@
         inode->i_gid = current->fsgid;
     }
     DQUOT_INIT(inode);
-    if (DQUOT_ALLOC_INODE(inode)) {
-        drop_new_inode(inode);
-	return -EDQUOT;
-    }
     return 0 ;
 }
 
@@ -590,16 +585,15 @@
 {
     int retval;
     struct inode * inode;
-    int jbegin_count = JOURNAL_PER_BALANCE_CNT * 2 ;
+    /* 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 ;
     }
-    retval = new_inode_init(inode, dir, mode);
-    if (retval)
-        return retval;
+    new_inode_init(inode, dir, mode);
 
     locked = reiserfs_cache_default_acl (dir);
 
@@ -658,7 +652,8 @@
     int retval;
     struct inode * inode;
     struct reiserfs_transaction_handle th ;
-    int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3; 
+    /* 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;
 
     if (!new_valid_dev(rdev))
@@ -667,9 +662,7 @@
     if (!(inode = new_inode(dir->i_sb))) {
 	return -ENOMEM ;
     }
-    retval = new_inode_init(inode, dir, mode);
-    if (retval)
-        return retval;
+    new_inode_init(inode, dir, mode);
 
     locked = reiserfs_cache_default_acl (dir);
 
@@ -733,7 +726,8 @@
     int retval;
     struct inode * inode;
     struct reiserfs_transaction_handle th ;
-    int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3; 
+    /* 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;
 
 #ifdef DISPLACE_NEW_PACKING_LOCALITIES
@@ -744,9 +738,7 @@
     if (!(inode = new_inode(dir->i_sb))) {
 	return -ENOMEM ;
     }
-    retval = new_inode_init(inode, dir, mode);
-    if (retval)
-        return retval;
+    new_inode_init(inode, dir, mode);
 
     locked = reiserfs_cache_default_acl (dir);
 
@@ -836,8 +828,9 @@
     struct reiserfs_dir_entry de;
 
 
-    /* we will be doing 2 balancings and update 2 stat data */
-    jbegin_count = JOURNAL_PER_BALANCE_CNT * 2 + 2;
+    /* 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) ;
@@ -881,7 +874,7 @@
 			  "!= 2 (%d)", __FUNCTION__, inode->i_nlink);
 
     inode->i_nlink = 0;
-    inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+    inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
     reiserfs_update_sd (&th, inode);
 
     DEC_DIR_INODE_NLINK(dir)
@@ -920,8 +913,9 @@
     inode = dentry->d_inode;
 
     /* in this transaction we can be doing at max two balancings and update
-       two stat datas */
-    jbegin_count = JOURNAL_PER_BALANCE_CNT * 2 + 2;
+       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) ;
@@ -969,11 +963,11 @@
 	inode->i_nlink++;
 	goto end_unlink;
     }
-    inode->i_ctime = CURRENT_TIME;
+    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;
+    dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
     reiserfs_update_sd (&th, dir);
 
     if (!savelink)
@@ -1005,15 +999,13 @@
     int item_len;
     struct reiserfs_transaction_handle th ;
     int mode = S_IFLNK | S_IRWXUGO;
-    int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3; 
+    /* 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 ;
     }
-    retval = new_inode_init(inode, parent_dir, mode);
-    if (retval) {
-        return retval;
-    }
+    new_inode_init(inode, parent_dir, mode);
 
     reiserfs_write_lock(parent_dir->i_sb);
     item_len = ROUND_UP (strlen (symname));
@@ -1083,7 +1075,8 @@
     int retval;
     struct inode *inode = old_dentry->d_inode;
     struct reiserfs_transaction_handle th ;
-    int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3; 
+    /* 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) {
@@ -1121,7 +1114,7 @@
 	return err ? err : retval;
     }
 
-    inode->i_ctime = CURRENT_TIME;
+    inode->i_ctime = CURRENT_TIME_SEC;
     reiserfs_update_sd (&th, inode);
 
     atomic_inc(&inode->i_count) ;
@@ -1201,8 +1194,9 @@
        (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 */
-    jbegin_count = JOURNAL_PER_BALANCE_CNT * 3 + 5;
+       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;
@@ -1368,7 +1362,7 @@
 
     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;
+    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
diff -Nru a/fs/reiserfs/prints.c b/fs/reiserfs/prints.c
--- a/fs/reiserfs/prints.c	2005-03-01 23:38:59 -08:00
+++ b/fs/reiserfs/prints.c	2005-03-01 23:38:59 -08:00
@@ -286,7 +286,7 @@
 }
 
 /* No newline.. reiserfs_printk calls can be followed by printk's */
-void reiserfs_printk (const char * fmt, ...)
+static void reiserfs_printk (const char * fmt, ...)
 {
   do_reiserfs_warning(fmt);
   printk (error_buf);
@@ -366,30 +366,6 @@
 	 reiserfs_bdevname (sb), error_buf);
 }
 
-static void
-do_handle_error (struct super_block *sb, int errno)
-{
-    if (reiserfs_error_panic (sb)) {
-        panic ("REISERFS: panic (device %s): Panic forced after error\n",
-               reiserfs_bdevname (sb));
-    }
-
-    if (reiserfs_error_ro (sb)) {
-        printk (KERN_CRIT "REISERFS: error (device %s): Re-mounting fs "
-                "readonly\n", reiserfs_bdevname (sb));
-        reiserfs_journal_abort (sb, errno);
-    }
-}
-
-void
-reiserfs_error (struct super_block * sb, int errno, const char *fmt, ...)
-{
-    do_reiserfs_warning (fmt);
-    printk (KERN_CRIT "REISERFS: error (device %s): %s\n",
-            reiserfs_bdevname (sb), error_buf);
-    do_handle_error (sb, errno);
-}
-
 void
 reiserfs_abort (struct super_block *sb, int errno, const char *fmt, ...)
 {
@@ -410,53 +386,6 @@
     reiserfs_journal_abort (sb, errno);
 }
 
-void print_virtual_node (struct virtual_node * vn)
-{
-    int i;
-    struct virtual_item * vi;
-
-    printk ("VIRTUAL NODE CONTAINS %d items, has size %d,%s,%s, ITEM_POS=%d POS_IN_ITEM=%d MODE=\'%c\'\n",
-	    vn->vn_nr_item, vn->vn_size,
-	    (vn->vn_vi[0].vi_type & VI_TYPE_LEFT_MERGEABLE )? "left mergeable" : "", 
-	    (vn->vn_vi[vn->vn_nr_item - 1].vi_type & VI_TYPE_RIGHT_MERGEABLE) ? "right mergeable" : "",
-	    vn->vn_affected_item_num, vn->vn_pos_in_item, vn->vn_mode);
-    
-    vi = vn->vn_vi;
-    for (i = 0; i < vn->vn_nr_item; i ++, vi ++)
-	op_print_vi (vi);
-	
-}
-
-
-void print_path (struct tree_balance * tb, struct path * path)
-{
-    int h = 0;
-    struct buffer_head * bh;
-    
-    if (tb) {
-	while (tb->insert_size[h]) {
-	    bh = PATH_H_PBUFFER (path, h);
-	    printk ("block %llu (level=%d), position %d\n", bh ? (unsigned long long)bh->b_blocknr : 0LL,
-		    bh ? B_LEVEL (bh) : 0, PATH_H_POSITION (path, h));
-	    h ++;
-	}
-  } else {
-      int offset = path->path_length;
-      struct buffer_head * bh;
-      printk ("Offset    Bh     (b_blocknr, b_count) Position Nr_item\n");
-      while ( offset > ILLEGAL_PATH_ELEMENT_OFFSET ) {
-	  bh = PATH_OFFSET_PBUFFER (path, offset);
-	  printk ("%6d %10p (%9llu, %7d) %8d %7d\n", offset, 
-		  bh, bh ? (unsigned long long)bh->b_blocknr : 0LL, bh ? atomic_read (&(bh->b_count)) : 0,
-		  PATH_OFFSET_POSITION (path, offset), bh ? B_NR_ITEMS (bh) : -1);
-	  
-	  offset --;
-      }
-  }
-
-}
-
-
 /* 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)...*/
@@ -648,7 +577,7 @@
 
 
 
-char print_tb_buf[2048];
+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)
diff -Nru a/fs/reiserfs/stree.c b/fs/reiserfs/stree.c
--- a/fs/reiserfs/stree.c	2005-03-01 23:39:08 -08:00
+++ b/fs/reiserfs/stree.c	2005-03-01 23:39:08 -08:00
@@ -12,14 +12,10 @@
  *  This file contains functions dealing with S+tree
  *
  * B_IS_IN_TREE
- * copy_short_key
  * copy_item_head
  * comp_short_keys
  * comp_keys
- * comp_cpu_keys
  * comp_short_le_keys
- * comp_short_cpu_keys
- * cpu_key2cpu_key
  * le_key2cpu_key
  * comp_le_keys
  * bin_search
@@ -72,11 +68,6 @@
   return ( B_LEVEL (p_s_bh) != FREE_LEVEL );
 }
 
-inline void copy_short_key (void * to, const void * from)
-{
-    memcpy (to, from, SHORT_KEY_SIZE);
-}
-
 //
 // to gets item head in le form
 //
@@ -117,7 +108,7 @@
    Compare keys using all 4 key fields.
    Returns: -1 if key1 < key2 0
    if key1 = key2 1 if key1 > key2 */
-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;
 
@@ -143,37 +134,6 @@
 }
 
 
-//
-// FIXME: not used yet
-//
-inline int comp_cpu_keys (const struct cpu_key * key1, 
-			  const struct cpu_key * key2)
-{
-    if (key1->on_disk_key.k_dir_id < key2->on_disk_key.k_dir_id)
-	return -1;
-    if (key1->on_disk_key.k_dir_id > key2->on_disk_key.k_dir_id)
-	return 1;
-
-    if (key1->on_disk_key.k_objectid < key2->on_disk_key.k_objectid)
-	return -1;
-    if (key1->on_disk_key.k_objectid > key2->on_disk_key.k_objectid)
-	return 1;
-
-    if (cpu_key_k_offset (key1) < cpu_key_k_offset (key2))
-	return -1;
-    if (cpu_key_k_offset (key1) > cpu_key_k_offset (key2))
-	return 1;
-
-    reiserfs_warning (NULL, "comp_cpu_keys: type are compared for %K and %K",
-		      key1, key2);
-
-    if (cpu_key_k_type (key1) < cpu_key_k_type (key2))
-	return -1;
-    if (cpu_key_k_type (key1) > cpu_key_k_type (key2))
-	return 1;
-    return 0;
-}
-
 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;
@@ -190,32 +150,6 @@
   return 0;
 }
 
-inline int comp_short_cpu_keys (const struct cpu_key * key1, 
-				const struct cpu_key * key2)
-{
-  __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 ( *p_s_1_u32 < *p_s_2_u32 )
-      return -1;
-    if ( *p_s_1_u32 > *p_s_2_u32 )
-      return 1;
-  }
-  return 0;
-}
-
-
-
-inline void cpu_key2cpu_key (struct cpu_key * to, const struct cpu_key * from)
-{
-    memcpy (to, from, sizeof (struct cpu_key));
-}
-
-
 inline void le_key2cpu_key (struct cpu_key * to, const struct reiserfs_key * from)
 {
     to->on_disk_key.k_dir_id = le32_to_cpu (from->k_dir_id);
@@ -255,7 +189,7 @@
  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. */
-inline	int bin_search (
+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.        */
@@ -272,7 +206,7 @@
     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) )  {
+     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.  */
@@ -301,7 +235,7 @@
    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. */
-inline	const struct  reiserfs_key * get_lkey  (
+static inline	const struct  reiserfs_key * get_lkey  (
 	                const struct path         * p_s_chk_path,
                         const struct super_block  * p_s_sb
                       ) {
@@ -396,11 +330,11 @@
   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 )
+  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 )
+  //  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;
@@ -745,7 +679,7 @@
         /* 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 ) && 
+        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
@@ -1192,7 +1126,7 @@
 }
 
 /* Calculate number of bytes which will be deleted or cut during balance */
-int calc_deleted_bytes_number(
+static int calc_deleted_bytes_number(
     struct  tree_balance  * p_s_tb,
     char                    c_mode
     ) {
@@ -1388,7 +1322,7 @@
     do_balance(&s_del_balance, NULL, NULL, M_DELETE);
 
 #ifdef REISERQUOTA_DEBUG
-    reiserfs_debug (p_s_sb, "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);
 
@@ -1465,7 +1399,7 @@
 	    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, "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);
 	    }
@@ -1786,7 +1720,7 @@
 	REISERFS_I(p_s_inode)->i_flags &= ~i_pack_on_close_mask ;
     }
 #ifdef REISERQUOTA_DEBUG
-    reiserfs_debug (p_s_inode->i_sb, "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;
@@ -1922,7 +1856,7 @@
 	  decrement_counters_in_path(&s_search_path) ;
 
 	  if (update_timestamps) {
-	      p_s_inode->i_mtime = p_s_inode->i_ctime = CURRENT_TIME;
+	      p_s_inode->i_mtime = p_s_inode->i_ctime = CURRENT_TIME_SEC;
 	  } 
 	  reiserfs_update_sd(th, p_s_inode) ;
 
@@ -1945,7 +1879,7 @@
 update_and_out:
     if (update_timestamps) {
 	// this is truncate, not file closing
-	p_s_inode->i_mtime = p_s_inode->i_ctime = CURRENT_TIME;
+	    p_s_inode->i_mtime = p_s_inode->i_ctime = CURRENT_TIME_SEC;
     }
     reiserfs_update_sd (th, p_s_inode);
 
@@ -1999,7 +1933,7 @@
     fs_gen = get_generation(inode->i_sb) ;
 
 #ifdef REISERQUOTA_DEBUG
-    reiserfs_debug (inode->i_sb, "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)) {
@@ -2048,7 +1982,7 @@
     /* this also releases the path */
     unfix_nodes(&s_paste_balance);
 #ifdef REISERQUOTA_DEBUG
-    reiserfs_debug (inode->i_sb, "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 ;
@@ -2081,7 +2015,7 @@
 	    quota_bytes = inode->i_sb->s_blocksize + UNFM_P_SIZE ;
 	}
 #ifdef REISERQUOTA_DEBUG
-	reiserfs_debug (inode->i_sb, "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... */
@@ -2127,7 +2061,7 @@
     /* also releases the path */
     unfix_nodes(&s_ins_balance);
 #ifdef REISERQUOTA_DEBUG
-    reiserfs_debug (th->t_super, "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) ;
diff -Nru a/fs/reiserfs/super.c b/fs/reiserfs/super.c
--- a/fs/reiserfs/super.c	2005-03-01 23:38:56 -08:00
+++ b/fs/reiserfs/super.c	2005-03-01 23:38:56 -08:00
@@ -25,12 +25,15 @@
 #include <linux/buffer_head.h>
 #include <linux/vfs.h>
 #include <linux/namespace.h>
+#include <linux/mount.h>
+#include <linux/namei.h>
+#include <linux/quotaops.h>
 
 struct file_system_type reiserfs_fs_type;
 
-const char reiserfs_3_5_magic_string[] = REISERFS_SUPER_MAGIC_STRING;
-const char reiserfs_3_6_magic_string[] = REISER2FS_SUPER_MAGIC_STRING;
-const char reiserfs_jr_magic_string[] = REISER2FS_JR_SUPER_MAGIC_STRING;
+static const char reiserfs_3_5_magic_string[] = REISERFS_SUPER_MAGIC_STRING;
+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)
 {
@@ -62,7 +65,7 @@
 static int reiserfs_remount (struct super_block * s, int * flags, char * data);
 static int reiserfs_statfs (struct super_block * s, struct kstatfs * buf);
 
-static void reiserfs_sync_fs (struct super_block * s)
+static int reiserfs_sync_fs (struct super_block * s, int wait)
 {
     if (!(s->s_flags & MS_RDONLY)) {
         struct reiserfs_transaction_handle th;
@@ -76,11 +79,12 @@
     } else {
         s->s_dirt = 0;
     }
+    return 0;
 }
 
 static void reiserfs_write_super(struct super_block *s)
 {
-    reiserfs_sync_fs(s);
+    reiserfs_sync_fs(s, 1);
 }
 
 static void reiserfs_write_super_lockfs (struct super_block * s)
@@ -102,7 +106,7 @@
   reiserfs_write_unlock(s);
 }
 
-void reiserfs_unlockfs(struct super_block *s) {
+static void reiserfs_unlockfs(struct super_block *s) {
   reiserfs_allow_writes(s) ;
 }
 
@@ -134,6 +138,9 @@
      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)
@@ -149,12 +156,34 @@
     int done;
     struct inode * inode;
     int truncate;
+#ifdef CONFIG_QUOTA
+    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 = MAX_KEY;
     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);
+	}
+    }
+#endif
  
     done = 0;
     REISERFS_SB(s)->s_is_unlinked_ok = 1;
@@ -211,6 +240,7 @@
             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.
@@ -246,6 +276,16 @@
     }
     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;
+#endif
     pathrelse (&path);
     if (done)
         reiserfs_info (s, "There were %d uncompleted unlinks/truncates. "
@@ -516,7 +556,12 @@
     REISERFS_I(inode)->i_acl_default = NULL;
 }
 
-struct super_operations reiserfs_sops = 
+#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);
+#endif
+
+static struct super_operations reiserfs_sops =
 {
   .alloc_inode = reiserfs_alloc_inode,
   .destroy_inode = reiserfs_destroy_inode,
@@ -526,13 +571,57 @@
   .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,
+#endif
+};
+
+#ifdef CONFIG_QUOTA
+#define QTYPE2NAME(t) ((t)==USRQUOTA?"user":"group")
 
+static int reiserfs_dquot_initialize(struct inode *, int);
+static int reiserfs_dquot_drop(struct inode *);
+static int reiserfs_write_dquot(struct dquot *);
+static int reiserfs_acquire_dquot(struct dquot *);
+static int reiserfs_release_dquot(struct dquot *);
+static int reiserfs_mark_dquot_dirty(struct dquot *);
+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 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,
@@ -551,6 +640,8 @@
 		    applied BEFORE setmask */
 } arg_desc_t;
 
+/* Set this bit in arg_required to allow empty arguments */
+#define REISERFS_OPT_ALLOWEMPTY 31
 
 /* this struct is used in reiserfs_getopt() for describing the set of reiserfs
    mount options */
@@ -703,8 +794,8 @@
     /* move to the argument, or to next option if argument is not required */
     p ++;
     
-    if ( opt->arg_required && !strlen (p) ) {
-	/* this catches "option=," */
+    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;
     }
@@ -712,7 +803,7 @@
     if (!opt->values) {
 	/* *=NULLopt_arg contains pointer to argument */
 	*opt_arg = p;
-	return opt->arg_required;
+	return opt->arg_required & ~(1<<REISERFS_OPT_ALLOWEMPTY);
     }
     
     /* values possible for this option are listed in opt->values */
@@ -776,6 +867,9 @@
 	{"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,}
     };
 	
@@ -837,8 +931,62 @@
 		*jdev_name = arg;
 	    }
 	}
+
+#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.");
+		return 0;
+	    }
+	}
+#else
+	if (c == 'u' || c == 'g' || c == 'f') {
+	    reiserfs_warning(s, "reiserfs_parse_options: journalled quota options not supported.");
+	    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;
 }
 
@@ -914,11 +1062,22 @@
   unsigned int commit_max_age = (unsigned int)-1;
   struct reiserfs_journal *journal = SB_JOURNAL(s);
   int err;
+#ifdef CONFIG_QUOTA
+  int i;
+#endif
 
   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;
+	}
+#endif
     return -EINVAL;
+  }
   
   handle_attrs(s);
 
@@ -1125,24 +1284,6 @@
   return 0;
 }
 
-void check_bitmap (struct super_block * s)
-{
-  int i = 0;
-  int free = 0;
-  char * buf;
-
-  while (i < SB_BLOCK_COUNT (s)) {
-    buf = SB_AP_BITMAP (s)[i / (s->s_blocksize * 8)].bh->b_data;
-    if (!reiserfs_test_le_bit (i % (s->s_blocksize * 8), buf))
-      free ++;
-    i ++;
-  }
-
-  if (free != SB_FREE_BLOCKS (s))
-    reiserfs_warning (s,"vs-4000: check_bitmap: %d free blocks, must be %d",
-		      free, SB_FREE_BLOCKS (s));
-}
-
 static int read_super_block (struct super_block * s, int offset)
 {
     struct buffer_head * bh;
@@ -1223,6 +1364,10 @@
 
     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;
+#endif
 
     /* new format is limited by the 32 bit wide i_blocks field, want to
     ** be one full block below that.
@@ -1266,7 +1411,7 @@
 // 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
-__u32 find_hash_out (struct super_block * s)
+static __u32 find_hash_out (struct super_block * s)
 {
     int retval;
     struct inode * inode;
@@ -1397,7 +1542,7 @@
 }
 
 // this is used to set up correct value for old partitions
-int function2code (hashf_t func)
+static int function2code (hashf_t func)
 {
     if (func == keyed_hash)
 	return TEA_HASH;
@@ -1636,7 +1781,7 @@
     reiserfs_proc_info_init( s );
 
     init_waitqueue_head (&(sbi->s_wait));
-    sbi->bitmap_lock = SPIN_LOCK_UNLOCKED;
+    spin_lock_init(&sbi->bitmap_lock);
 
     return (0);
 
@@ -1654,7 +1799,12 @@
     }
     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]);
+    }
+#endif
     if (sbi != NULL) {
 	kfree(sbi);
     }
@@ -1677,6 +1827,262 @@
   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;
+
+    /* 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;
+}
+
+static int reiserfs_dquot_drop(struct inode *inode)
+{
+    struct reiserfs_transaction_handle th;
+    int ret;
+
+    /* 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;
+}
+
+static int reiserfs_write_dquot(struct dquot *dquot)
+{
+    struct reiserfs_transaction_handle th;
+    int ret;
+
+    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;
+}
+
+static int reiserfs_acquire_dquot(struct dquot *dquot)
+{
+    struct reiserfs_transaction_handle th;
+    int ret;
+
+    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;
+}
+
+static int reiserfs_release_dquot(struct dquot *dquot)
+{
+    struct reiserfs_transaction_handle th;
+    int ret;
+
+    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;
+}
+
+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);
+}
+
+static int reiserfs_write_info(struct super_block *sb, int type)
+{
+    struct reiserfs_transaction_handle th;
+    int ret;
+
+    /* 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;
+}
+
+/*
+ * 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;
+}
+
+/*
+ * Standard function to be called on quota_on
+ */
+static int reiserfs_quota_on(struct super_block *sb, int type, int format_id, char *path)
+{
+    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]) {
+	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);
+}
+
+/* Read data from quotafile - avoid pagecache and such because we cannot afford
+ * acquiring the locks... As quota files are never truncated and quota code
+ * itself serializes the operations (and noone else should touch the files)
+ * we don't have to be afraid of races */
+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);
+
+    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
+ * enough credits) */
+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;
+}
+
+#endif
 
 static struct super_block*
 get_super_block (struct file_system_type *fs_type, int flags,
diff -Nru a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c
--- a/fs/reiserfs/xattr.c	2005-03-01 23:39:17 -08:00
+++ b/fs/reiserfs/xattr.c	2005-03-01 23:39:17 -08:00
@@ -594,7 +594,7 @@
      * 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;
+        inode->i_ctime = CURRENT_TIME_SEC;
         mark_inode_dirty (inode);
     }
 
@@ -768,7 +768,7 @@
     dput (dir);
 
     if (!err) {
-        inode->i_ctime = CURRENT_TIME;
+        inode->i_ctime = CURRENT_TIME_SEC;
         mark_inode_dirty (inode);
     }
 
@@ -1040,7 +1040,7 @@
 
     err = reiserfs_xattr_del (dentry->d_inode, name);
 
-    dentry->d_inode->i_ctime = CURRENT_TIME;
+    dentry->d_inode->i_ctime = CURRENT_TIME_SEC;
     mark_inode_dirty (dentry->d_inode);
 
 out:
@@ -1152,7 +1152,7 @@
 
 /* This is the implementation for the xattr plugin infrastructure */
 static struct list_head xattr_handlers = LIST_HEAD_INIT (xattr_handlers);
-static rwlock_t handler_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(handler_lock);
 
 static struct reiserfs_xattr_handler *
 find_xattr_handler_prefix (const char *prefix)
diff -Nru a/fs/reiserfs/xattr_acl.c b/fs/reiserfs/xattr_acl.c
--- a/fs/reiserfs/xattr_acl.c	2005-03-01 23:39:08 -08:00
+++ b/fs/reiserfs/xattr_acl.c	2005-03-01 23:39:08 -08:00
@@ -9,6 +9,8 @@
 #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
 xattr_set_acl(struct inode *inode, int type, const void *value, size_t size)
 {
@@ -243,7 +245,7 @@
  * inode->i_sem: down
  * BKL held [before 2.5.x]
  */
-int
+static int
 reiserfs_set_acl(struct inode *inode, int type, struct posix_acl *acl)
 {
         char *name;
diff -Nru a/fs/romfs/inode.c b/fs/romfs/inode.c
--- a/fs/romfs/inode.c	2005-03-01 23:39:07 -08:00
+++ b/fs/romfs/inode.c	2005-03-01 23:39:07 -08:00
@@ -161,8 +161,7 @@
 	if (!root)
 		goto out;
 
-	s->s_root = d_alloc_root(iget(s, sz));
-
+	s->s_root = d_alloc_root(root);
 	if (!s->s_root)
 		goto outiput;
 
diff -Nru a/fs/select.c b/fs/select.c
--- a/fs/select.c	2005-03-01 23:38:51 -08:00
+++ b/fs/select.c	2005-03-01 23:38:51 -08:00
@@ -240,6 +240,7 @@
 						retval++;
 					}
 				}
+				cond_resched();
 			}
 			if (res_in)
 				*rinp = res_in;
diff -Nru a/fs/smbfs/ChangeLog b/fs/smbfs/ChangeLog
--- a/fs/smbfs/ChangeLog	2005-03-01 23:39:09 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,160 +0,0 @@
-ChangeLog for smbfs.
-
-2002-04-19 John Newbigin <jn@it.swin.edu.au>
-
-	* Implementation of CIFS Extensions for UNIX systems, including soft
-	  and hard links.
-
-2001-08-03 Urban Widmark <urban@teststation.com>
-
-	* *.c: Unicode support
-
-2001-08-23 Jochen Dolze <dolze@epcnet.de>
-
-	* proc.c: Correct rsize/wsize computation for readX/writeX
-
-2001-0?-?? Urban Widmark <urban@teststation.com>
-
-	* *.c: Add LFS
-	* *.c: Move to a "driver" style handling of different servertypes.
-	       (Not all operations are done this way. yet.)
-2001-12-31 René Scharfe <l.s.r@web.de>
-
-	* inode.c: added smb_show_options to show mount options in /proc/mounts
-	* inode.c, getopt.c, getopt.h: merged flag and has_arg in struct option
-	* inode.c: use S_IRWXUGO where appropriate
-
-2001-12-22 Urban Widmark <urban@teststation.com>
-
-	* file.c, proc.c: Fix problems triggered by the "fsx test"
-
-2001-09-17 Urban Widmark <urban@teststation.com>
-
-	* proc.c: Use 4096 (was 512) as the blocksize for better write
-	  performance (patch originally by Jan Kratochvil)
-	* proc.c: Skip disconnect smb, allows umount on unreachable servers.
-	* proc.c: Go back to the interruptible sleep as reconnects seem to
-	  handle it now.
-	* *.c: use autogenerated and private proto.h
-
-2000-11-22 Igor Zhbanov <bsg@uniyar.ac.ru>
-
-	* proc.c: fixed date_unix2dos for dates earlier than 01/01/1980
-	  and date_dos2unix for date==0 (from 2.2)
-
-2001-07-13 Rob Radez <rob@osinvestor.com>
-
-	* proc.c: make smb_errno return negative error values
-
-2001-07-09 Jochen Dolze <dolze@epcnet.de>
-
-	* inode.c: smb_statfs always returned success.
-	* proc.c, ioctl.c: Allow smbmount to signal failure to reconnect with
-	  a NULL argument to SMB_IOC_NEWCONN (speeds up error detection).
-	* proc.c: Add some of the missing error codes to smb_errno
-
-2001-06-12 Urban Widmark <urban@teststation.com>
-
-	* proc.c: replace the win95-flush fix with smb_seek, when needed.
-	* proc.c: readdir 'lastname' bug (NetApp dir listing fix)
-
-2001-05-08 Urban Widmark <urban@teststation.com>
-
-	* inode.c: Fix for changes on the server side not being detected
-	  properly. Must always drop cached pages when updating an inode with
-	  new size.
-
-2001-05-05 Urban Widmark <urban@teststation.com>
-
-	* file.c, proc.c: Drop SMB_F_LOCALWRITE to detect changes made on
-	  both server and client, using flush with to force win9x to remember
-	  the right filesize.
-
-2001-04-25 René Scharfe <l.s.r@web.de>
-
-	* inode.c: Don't clear s_flags and allow ro mounts
-
-2001-04-21 Urban Widmark <urban@teststation.com>
-
-	* dir.c, proc.c: replace tests on conn_pid with tests on state to
-	  fix smbmount reconnect on smb_retry timeout and up the timeout to 30s.
-	* proc.c: smb_newconn must have the server locked while updating it.
-	* inode.c, proc.c: need flush after truncate on some servers (win9x)
-	* file.c: add call to send SMBflush on fsync
-	  (as suggested by Jochen Dolze <dolze@epcnet.de>)
-
-2001-03-06 Urban Widmark <urban@teststation.com>
-
-	* cache.c: d_add on hashed dentries corrupts d_hash list and
-	  causes loops in d_lookup. Inherited bug. :)
-	* inode.c: tail -f fix for non-readonly opened files
-	  (related to the smb_proc_open change).
-	* inode.c: tail -f fix for fast size changes with the same mtime.
-
-2001-03-02 Michael Kockelkorn <m.kockelkorn@biodata.com>
-
-	* proc.c: fix smb_proc_open to allow open being called more than once
-	  with different modes (O_RDONLY -> O_WRONLY) without closing.
-
-2001-02-10 Urban Widmark <urban@teststation.com>
-
-	* dir.c, cache.c: replace non-bigmem safe cache with cache code
-	  from ncpfs and fix some other bigmem bugs in smbfs.
-	* inode.c: root dentry not properly initialized
-	* proc.c, sock.c: adjust max parameters & max data to follow max_xmit
-	  lots of servers were having find_next trouble with this.
-	* proc.c: use documented write method of truncating (NetApp fix)
-
-2000-08-14 Urban Widmark <urban@svenskatest.se>
-
-	* dir.c: support case sensitive shares
-	* inode.c: ascii mount options
-	* proc.c: check length of paths to avoid buffer overflow
-	* proc.c: don't do interruptable_sleep in smb_retry to avoid signal
-	  problem/race.
-	* proc.c: O_RDONLY & smb_revalidate_inode fix (tail -f)
-	* proc.c: add nls support
-	* sock.c: attempt to fix smb_data_callback (avoid infinite loop)
-
-2000-07-25 Urban Widmark <urban@svenskatest.se>
-
-	* proc.c: fix 3 places where bad server responses could cause an Oops.
-
-2000-07-15 Urban Widmark <urban@svenskatest.se>
-
-	* *.c: more debug (%.*s) & indent fixes
-
-2000-06-24: Matt Maynard <matthewm@corel.com>
-
-	* dir.c: dentry->d_inode->i_mtime isn't updated for all servers
-	  (NT?) and all operations (mv oldfile.txt newfile.txt) Removed for
-	  less efficient but better working directory cache.
-	* proc.c: included aDIR smbclient fix for renaming directories on
-	  OS/2 servers (win95/98?) (orig by John Janosik)
-
-2000-07-01 Urban Widmark <urban@svenskatest.se>
-
-	* *.c: replace ugly #ifdef's with less ugly debug macros.
-
-2000-01-03 Christian Groessler <cpg@aladdin.de>
-
-	* proc.c: added posix semantics for unlink
-
-1999-11-16 Andrew Tridgell
-
-	* proc.c: use level 260 for most conns, or level 1 for <NT1
-	* proc.c: don't sleep every time with win95 on a FINDNEXT
-	* proc.c: fixed loop_count bug
-	* proc.c: got rid of resume_key
-
-[there are a few missing here :) ]
-
-1997-09-28 Riccardo Facchetti
-
-	* proc.c: Fixed smb_d_path [now smb_build_path()] to be non-recursive
-
-1996-06-28 Yuri Per
-
-	* proc.c: Fixed long file name support (smb_proc_readdir_long)
-
-You are in the wrong end for adding new entries. New entries at the top.
diff -Nru a/fs/smbfs/file.c b/fs/smbfs/file.c
--- a/fs/smbfs/file.c	2005-03-01 23:39:10 -08:00
+++ b/fs/smbfs/file.c	2005-03-01 23:39:10 -08:00
@@ -78,7 +78,8 @@
 		count -= result;
 		offset += result;
 		buffer += result;
-		dentry->d_inode->i_atime = CURRENT_TIME;
+		dentry->d_inode->i_atime =
+			current_fs_time(dentry->d_inode->i_sb);
 		if (result < rsize)
 			break;
 	} while (count);
@@ -152,7 +153,7 @@
 		/*
 		 * Update the inode now rather than waiting for a refresh.
 		 */
-		inode->i_mtime = inode->i_atime = CURRENT_TIME;
+		inode->i_mtime = inode->i_atime = current_fs_time(inode->i_sb);
 		SMB_I(inode)->flags |= SMB_F_LOCALWRITE;
 		if (offset > inode->i_size)
 			inode->i_size = offset;
@@ -362,7 +363,7 @@
 	SMB_I(inode)->openers++;
 out:
 	unlock_kernel();
-	return 0;
+	return result;
 }
 
 static int
diff -Nru a/fs/smbfs/inode.c b/fs/smbfs/inode.c
--- a/fs/smbfs/inode.c	2005-03-01 23:38:52 -08:00
+++ b/fs/smbfs/inode.c	2005-03-01 23:38:52 -08:00
@@ -493,7 +493,7 @@
 	smb_kfree(server);
 }
 
-int smb_fill_super(struct super_block *sb, void *raw_data, int silent)
+static int smb_fill_super(struct super_block *sb, void *raw_data, int silent)
 {
 	struct smb_sb_info *server;
 	struct smb_mount_data_kernel *mnt;
@@ -516,6 +516,7 @@
 	sb->s_blocksize_bits = 10;
 	sb->s_magic = SMB_SUPER_MAGIC;
 	sb->s_op = &smb_sops;
+	sb->s_time_gran = 100;
 
 	server = smb_kmalloc(sizeof(struct smb_sb_info), GFP_KERNEL);
 	if (!server)
@@ -601,7 +602,7 @@
 	/*
 	 * Keep the super block locked while we get the root inode.
 	 */
-	smb_init_root_dirent(server, &root);
+	smb_init_root_dirent(server, &root, sb);
 	root_inode = smb_iget(sb, &root);
 	if (!root_inode)
 		goto out_no_root;
diff -Nru a/fs/smbfs/proc.c b/fs/smbfs/proc.c
--- a/fs/smbfs/proc.c	2005-03-01 23:38:52 -08:00
+++ b/fs/smbfs/proc.c	2005-03-01 23:38:52 -08:00
@@ -74,7 +74,7 @@
 static int
 smb_proc_setattr_ext(struct smb_sb_info *server,
 		     struct inode *inode, struct smb_fattr *fattr);
-int
+static int
 smb_proc_query_cifsunix(struct smb_sb_info *server);
 static void
 install_ops(struct smb_ops *dst, struct smb_ops *src);
@@ -1427,9 +1427,9 @@
 	 * So we must first calculate the amount of padding used by the server.
 	 */
 	data_off -= hdrlen;
-	if (data_off > SMB_READX_MAX_PAD) {
-		PARANOIA("offset is larger than max pad!\n");
-		PARANOIA("%d > %d\n", data_off, SMB_READX_MAX_PAD);
+	if (data_off > SMB_READX_MAX_PAD || data_off < 0) {
+		PARANOIA("offset is larger than SMB_READX_MAX_PAD or negative!\n");
+		PARANOIA("%d > %d || %d < 0\n", data_off, SMB_READX_MAX_PAD, data_off);
 		req->rq_rlen = req->rq_bufsize + 1;
 		return;
 	}
@@ -1852,12 +1852,13 @@
 }
 
 void
-smb_init_root_dirent(struct smb_sb_info *server, struct smb_fattr *fattr)
+smb_init_root_dirent(struct smb_sb_info *server, struct smb_fattr *fattr,
+		     struct super_block *sb)
 {
 	smb_init_dirent(server, fattr);
 	fattr->attr = aDIR;
 	fattr->f_ino = 2; /* traditional root inode number */
-	fattr->f_mtime = CURRENT_TIME;
+	fattr->f_mtime = current_fs_time(sb);
 	smb_finish_dirent(server, fattr);
 }
 
@@ -2074,7 +2075,7 @@
 	return result;
 }
 
-void smb_decode_unix_basic(struct smb_fattr *fattr, struct smb_sb_info *server, char *p)
+static void smb_decode_unix_basic(struct smb_fattr *fattr, struct smb_sb_info *server, char *p)
 {
 	u64 size, disk_bytes;
 
@@ -3391,7 +3392,7 @@
 	return result;
 }
 
-int
+static int
 smb_proc_query_cifsunix(struct smb_sb_info *server)
 {
 	int result;
diff -Nru a/fs/smbfs/proto.h b/fs/smbfs/proto.h
--- a/fs/smbfs/proto.h	2005-03-01 23:38:59 -08:00
+++ b/fs/smbfs/proto.h	2005-03-01 23:38:59 -08:00
@@ -23,8 +23,8 @@
 extern int smb_proc_rmdir(struct dentry *dentry);
 extern int smb_proc_unlink(struct dentry *dentry);
 extern int smb_proc_flush(struct smb_sb_info *server, __u16 fileid);
-extern void smb_init_root_dirent(struct smb_sb_info *server, struct smb_fattr *fattr);
-extern void smb_decode_unix_basic(struct smb_fattr *fattr, struct smb_sb_info *server, char *p);
+extern void smb_init_root_dirent(struct smb_sb_info *server, struct smb_fattr *fattr,
+				 struct super_block *sb);
 extern int smb_proc_getattr(struct dentry *dir, struct smb_fattr *fattr);
 extern int smb_proc_setattr(struct dentry *dir, struct smb_fattr *fattr);
 extern int smb_proc_setattr_unix(struct dentry *d, struct iattr *attr, unsigned int major, unsigned int minor);
@@ -33,7 +33,6 @@
 extern int smb_proc_read_link(struct smb_sb_info *server, struct dentry *d, char *buffer, int len);
 extern int smb_proc_symlink(struct smb_sb_info *server, struct dentry *d, const char *oldpath);
 extern int smb_proc_link(struct smb_sb_info *server, struct dentry *dentry, struct dentry *new_dentry);
-extern int smb_proc_query_cifsunix(struct smb_sb_info *server);
 extern void smb_install_null_ops(struct smb_ops *ops);
 /* dir.c */
 extern struct file_operations smb_dir_operations;
@@ -61,7 +60,6 @@
 extern void smb_set_inode_attr(struct inode *inode, struct smb_fattr *fattr);
 extern void smb_invalidate_inodes(struct smb_sb_info *server);
 extern int smb_revalidate_inode(struct dentry *dentry);
-extern int smb_fill_super(struct super_block *sb, void *raw_data, int silent);
 extern int smb_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat);
 extern int smb_notify_change(struct dentry *dentry, struct iattr *attr);
 /* file.c */
@@ -80,10 +78,8 @@
 extern int smb_init_request_cache(void);
 extern void smb_destroy_request_cache(void);
 extern struct smb_request *smb_alloc_request(struct smb_sb_info *server, int bufsize);
-extern void smb_rget(struct smb_request *req);
 extern void smb_rput(struct smb_request *req);
 extern int smb_add_request(struct smb_request *req);
-extern int smb_request_send_req(struct smb_request *req);
 extern int smb_request_send_server(struct smb_sb_info *server);
 extern int smb_request_recv(struct smb_sb_info *server);
 /* symlink.c */
diff -Nru a/fs/smbfs/request.c b/fs/smbfs/request.c
--- a/fs/smbfs/request.c	2005-03-01 23:39:17 -08:00
+++ b/fs/smbfs/request.c	2005-03-01 23:39:17 -08:00
@@ -27,6 +27,8 @@
 /* cache for request structures */
 static kmem_cache_t *req_cachep;
 
+static int smb_request_send_req(struct smb_request *req);
+
 /*
   /proc/slabinfo:
   name, active, num, objsize, active_slabs, num_slaps, #pages
@@ -132,7 +134,7 @@
  * What prevents a rget to race with a rput? The count must never drop to zero
  * while it is in use. Only rput if it is ok that it is free'd.
  */
-void smb_rget(struct smb_request *req)
+static void smb_rget(struct smb_request *req)
 {
 	atomic_inc(&req->rq_count);
 }
@@ -379,7 +381,7 @@
  * Send a request and place it on the recvq if successfully sent.
  * Must be called with the server lock held.
  */
-int smb_request_send_req(struct smb_request *req)
+static int smb_request_send_req(struct smb_request *req)
 {
 	struct smb_sb_info *server = req->rq_server;
 	int result;
@@ -588,8 +590,18 @@
 	data_count  = WVAL(inbuf, smb_drcnt);
 
 	/* Modify offset for the split header/buffer we use */
-	data_offset -= hdrlen;
-	parm_offset -= hdrlen;
+	if (data_count || data_offset) {
+		if (unlikely(data_offset < hdrlen))
+			goto out_bad_data;
+		else
+			data_offset -= hdrlen;
+	}
+	if (parm_count || parm_offset) {
+		if (unlikely(parm_offset < hdrlen))
+			goto out_bad_parm;
+		else
+			parm_offset -= hdrlen;
+	}
 
 	if (parm_count == parm_tot && data_count == data_tot) {
 		/*
@@ -600,18 +612,22 @@
 		 * response that fits.
 		 */
 		VERBOSE("single trans2 response  "
-			"dcnt=%d, pcnt=%d, doff=%d, poff=%d\n",
+			"dcnt=%u, pcnt=%u, doff=%u, poff=%u\n",
 			data_count, parm_count,
 			data_offset, parm_offset);
 		req->rq_ldata = data_count;
 		req->rq_lparm = parm_count;
 		req->rq_data = req->rq_buffer + data_offset;
 		req->rq_parm = req->rq_buffer + parm_offset;
+		if (unlikely(parm_offset + parm_count > req->rq_rlen))
+			goto out_bad_parm;
+		if (unlikely(data_offset + data_count > req->rq_rlen))
+			goto out_bad_data;
 		return 0;
 	}
 
 	VERBOSE("multi trans2 response  "
-		"frag=%d, dcnt=%d, pcnt=%d, doff=%d, poff=%d\n",
+		"frag=%d, dcnt=%u, pcnt=%u, doff=%u, poff=%u\n",
 		req->rq_fragment,
 		data_count, parm_count,
 		data_offset, parm_offset);
@@ -638,13 +654,15 @@
 
 		req->rq_parm = req->rq_trans2buffer;
 		req->rq_data = req->rq_trans2buffer + parm_tot;
-	} else if (req->rq_total_data < data_tot ||
-		   req->rq_total_parm < parm_tot)
+	} else if (unlikely(req->rq_total_data < data_tot ||
+			    req->rq_total_parm < parm_tot))
 		goto out_data_grew;
 
-	if (parm_disp + parm_count > req->rq_total_parm)
+	if (unlikely(parm_disp + parm_count > req->rq_total_parm ||
+		     parm_offset + parm_count > req->rq_rlen))
 		goto out_bad_parm;
-	if (data_disp + data_count > req->rq_total_data)
+	if (unlikely(data_disp + data_count > req->rq_total_data ||
+		     data_offset + data_count > req->rq_rlen))
 		goto out_bad_data;
 
 	inbuf = req->rq_buffer;
@@ -666,10 +684,9 @@
 	return 1;
 
 out_too_long:
-	printk(KERN_ERR "smb_trans2: data/param too long, data=%d, parm=%d\n",
+	printk(KERN_ERR "smb_trans2: data/param too long, data=%u, parm=%u\n",
 		data_tot, parm_tot);
-	req->rq_errno = -EIO;
-	goto out;
+	goto out_EIO;
 out_no_mem:
 	printk(KERN_ERR "smb_trans2: couldn't allocate data area of %d bytes\n",
 	       req->rq_trans2bufsize);
@@ -677,16 +694,15 @@
 	goto out;
 out_data_grew:
 	printk(KERN_ERR "smb_trans2: data/params grew!\n");
-	req->rq_errno = -EIO;
-	goto out;
+	goto out_EIO;
 out_bad_parm:
-	printk(KERN_ERR "smb_trans2: invalid parms, disp=%d, cnt=%d, tot=%d\n",
-	       parm_disp, parm_count, parm_tot);
-	req->rq_errno = -EIO;
-	goto out;
+	printk(KERN_ERR "smb_trans2: invalid parms, disp=%u, cnt=%u, tot=%u, ofs=%u\n",
+	       parm_disp, parm_count, parm_tot, parm_offset);
+	goto out_EIO;
 out_bad_data:
-	printk(KERN_ERR "smb_trans2: invalid data, disp=%d, cnt=%d, tot=%d\n",
-	       data_disp, data_count, data_tot);
+	printk(KERN_ERR "smb_trans2: invalid data, disp=%u, cnt=%u, tot=%u, ofs=%u\n",
+	       data_disp, data_count, data_tot, data_offset);
+out_EIO:
 	req->rq_errno = -EIO;
 out:
 	return req->rq_errno;
diff -Nru a/fs/smbfs/smbiod.c b/fs/smbfs/smbiod.c
--- a/fs/smbfs/smbiod.c	2005-03-01 23:39:07 -08:00
+++ b/fs/smbfs/smbiod.c	2005-03-01 23:39:07 -08:00
@@ -43,7 +43,7 @@
 static pid_t smbiod_pid;
 static DECLARE_WAIT_QUEUE_HEAD(smbiod_wait);
 static LIST_HEAD(smb_servers);
-static spinlock_t servers_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(servers_lock);
 
 #define SMBIOD_DATA_READY	(1<<0)
 static long smbiod_flags;
diff -Nru a/fs/super.c b/fs/super.c
--- a/fs/super.c	2005-03-01 23:38:56 -08:00
+++ b/fs/super.c	2005-03-01 23:38:56 -08:00
@@ -45,7 +45,7 @@
 struct file_system_type *get_fs_type(const char *name);
 
 LIST_HEAD(super_blocks);
-spinlock_t sb_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(sb_lock);
 
 /**
  *	alloc_super	-	create new superblock
@@ -70,6 +70,7 @@
 		INIT_LIST_HEAD(&s->s_files);
 		INIT_LIST_HEAD(&s->s_instances);
 		INIT_HLIST_HEAD(&s->s_anon);
+		INIT_LIST_HEAD(&s->s_inodes);
 		init_rwsem(&s->s_umount);
 		sema_init(&s->s_lock, 1);
 		down_write(&s->s_umount);
@@ -84,6 +85,7 @@
 		s->dq_op = sb_dquot_ops;
 		s->s_qcop = sb_quotactl_ops;
 		s->s_op = &default_op;
+		s->s_time_gran = 1000000000;
 	}
 out:
 	return s;
@@ -232,10 +234,10 @@
 		dput(root);
 		fsync_super(sb);
 		lock_super(sb);
-		lock_kernel();
 		sb->s_flags &= ~MS_ACTIVE;
 		/* bad name - it should be evict_inodes() */
 		invalidate_inodes(sb);
+		lock_kernel();
 
 		if (sop->write_super && sb->s_dirt)
 			sop->write_super(sb);
@@ -588,7 +590,7 @@
  */
 
 static struct idr unnamed_dev_idr;
-static spinlock_t unnamed_dev_lock = SPIN_LOCK_UNLOCKED;/* protects the above */
+static DEFINE_SPINLOCK(unnamed_dev_lock);/* protects the above */
 
 int set_anon_super(struct super_block *s, void *data)
 {
diff -Nru a/fs/sysfs/bin.c b/fs/sysfs/bin.c
--- a/fs/sysfs/bin.c	2005-03-01 23:38:57 -08:00
+++ b/fs/sysfs/bin.c	2005-03-01 23:38:57 -08:00
@@ -1,5 +1,9 @@
 /*
  * bin.c - binary file operations for sysfs.
+ *
+ * Copyright (c) 2003 Patrick Mochel
+ * Copyright (c) 2003 Matthew Wilcox
+ * Copyright (c) 2004 Silicon Graphics, Inc.
  */
 
 #undef DEBUG
@@ -20,6 +24,9 @@
 	struct bin_attribute * attr = to_bin_attr(dentry);
 	struct kobject * kobj = to_kobj(dentry->d_parent);
 
+	if (!attr->read)
+		return -EINVAL;
+
 	return attr->read(kobj, buffer, off, count);
 }
 
@@ -63,6 +70,9 @@
 	struct bin_attribute *attr = to_bin_attr(dentry);
 	struct kobject *kobj = to_kobj(dentry->d_parent);
 
+	if (!attr->write)
+		return -EINVAL;
+
 	return attr->write(kobj, buffer, offset, count);
 }
 
@@ -92,6 +102,18 @@
 	return count;
 }
 
+static int mmap(struct file *file, struct vm_area_struct *vma)
+{
+	struct dentry *dentry = file->f_dentry;
+	struct bin_attribute *attr = to_bin_attr(dentry);
+	struct kobject *kobj = to_kobj(dentry->d_parent);
+
+	if (!attr->mmap)
+		return -EINVAL;
+
+	return attr->mmap(kobj, attr, vma);
+}
+
 static int open(struct inode * inode, struct file * file)
 {
 	struct kobject *kobj = sysfs_get_kobject(file->f_dentry->d_parent);
@@ -107,9 +129,9 @@
 		goto Done;
 
 	error = -EACCES;
-	if ((file->f_mode & FMODE_WRITE) && !attr->write)
+	if ((file->f_mode & FMODE_WRITE) && !(attr->write || attr->mmap))
 		goto Error;
-	if ((file->f_mode & FMODE_READ) && !attr->read)
+	if ((file->f_mode & FMODE_READ) && !(attr->read || attr->mmap))
 		goto Error;
 
 	error = -ENOMEM;
@@ -144,6 +166,7 @@
 struct file_operations bin_fops = {
 	.read		= read,
 	.write		= write,
+	.mmap		= mmap,
 	.llseek		= generic_file_llseek,
 	.open		= open,
 	.release	= release,
diff -Nru a/fs/sysfs/dir.c b/fs/sysfs/dir.c
--- a/fs/sysfs/dir.c	2005-03-01 23:38:56 -08:00
+++ b/fs/sysfs/dir.c	2005-03-01 23:38:56 -08:00
@@ -36,7 +36,7 @@
 {
 	struct sysfs_dirent * sd;
 
-	sd = kmalloc(sizeof(*sd), GFP_KERNEL);
+	sd = kmem_cache_alloc(sysfs_dir_cachep, GFP_KERNEL);
 	if (!sd)
 		return NULL;
 
diff -Nru a/fs/sysfs/file.c b/fs/sysfs/file.c
--- a/fs/sysfs/file.c	2005-03-01 23:38:51 -08:00
+++ b/fs/sysfs/file.c	2005-03-01 23:38:51 -08:00
@@ -231,15 +231,16 @@
 sysfs_write_file(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
 {
 	struct sysfs_buffer * buffer = file->private_data;
+	ssize_t len;
 
 	down(&buffer->sem);
-	count = fill_write_buffer(buffer,buf,count);
-	if (count > 0)
-		count = flush_write_buffer(file->f_dentry,buffer,count);
-	if (count > 0)
-		*ppos += count;
+	len = fill_write_buffer(buffer, buf, count);
+	if (len > 0)
+		len = flush_write_buffer(file->f_dentry, buffer, len);
+	if (len > 0)
+		*ppos += len;
 	up(&buffer->sem);
-	return count;
+	return len;
 }
 
 static int check_perm(struct inode * inode, struct file * file)
diff -Nru a/fs/sysfs/mount.c b/fs/sysfs/mount.c
--- a/fs/sysfs/mount.c	2005-03-01 23:39:09 -08:00
+++ b/fs/sysfs/mount.c	2005-03-01 23:39:09 -08:00
@@ -16,6 +16,7 @@
 
 struct vfsmount *sysfs_mount;
 struct super_block * sysfs_sb = NULL;
+kmem_cache_t *sysfs_dir_cachep;
 
 static struct super_operations sysfs_ops = {
 	.statfs		= simple_statfs,
@@ -38,6 +39,7 @@
 	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
 	sb->s_magic = SYSFS_MAGIC;
 	sb->s_op = &sysfs_ops;
+	sb->s_time_gran = 1;
 	sysfs_sb = sb;
 
 	inode = sysfs_new_inode(S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO);
@@ -76,7 +78,13 @@
 
 int __init sysfs_init(void)
 {
-	int err;
+	int err = -ENOMEM;
+
+	sysfs_dir_cachep = kmem_cache_create("sysfs_dir_cache",
+					      sizeof(struct sysfs_dirent),
+					      0, 0, NULL, NULL);
+	if (!sysfs_dir_cachep)
+		goto out;
 
 	err = register_filesystem(&sysfs_fs_type);
 	if (!err) {
@@ -85,7 +93,13 @@
 			printk(KERN_ERR "sysfs: could not mount!\n");
 			err = PTR_ERR(sysfs_mount);
 			sysfs_mount = NULL;
+			goto out_err;
 		}
-	}
+	} else
+		goto out_err;
+out:
 	return err;
+out_err:
+	kmem_cache_destroy(sysfs_dir_cachep);
+	goto out;
 }
diff -Nru a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h
--- a/fs/sysfs/sysfs.h	2005-03-01 23:39:09 -08:00
+++ b/fs/sysfs/sysfs.h	2005-03-01 23:39:09 -08:00
@@ -1,5 +1,6 @@
 
 extern struct vfsmount * sysfs_mount;
+extern kmem_cache_t *sysfs_dir_cachep;
 
 extern struct inode * sysfs_new_inode(mode_t mode);
 extern int sysfs_create(struct dentry *, int mode, int (*init)(struct inode *));
@@ -74,7 +75,7 @@
 		kobject_put(sl->target_kobj);
 		kfree(sl);
 	}
-	kfree(sd);
+	kmem_cache_free(sysfs_dir_cachep, sd);
 }
 
 static inline struct sysfs_dirent * sysfs_get(struct sysfs_dirent * sd)
diff -Nru a/fs/sysv/dir.c b/fs/sysv/dir.c
--- a/fs/sysv/dir.c	2005-03-01 23:38:54 -08:00
+++ b/fs/sysv/dir.c	2005-03-01 23:38:54 -08:00
@@ -231,7 +231,7 @@
 	memset (de->name + namelen, 0, SYSV_DIRSIZE - namelen - 2);
 	de->inode = cpu_to_fs16(SYSV_SB(inode->i_sb), inode->i_ino);
 	err = dir_commit_chunk(page, from, to);
-	dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+	dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
 	mark_inode_dirty(dir);
 out_page:
 	dir_put_page(page);
@@ -258,7 +258,7 @@
 	de->inode = 0;
 	err = dir_commit_chunk(page, from, to);
 	dir_put_page(page);
-	inode->i_ctime = inode->i_mtime = CURRENT_TIME;
+	inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC;
 	mark_inode_dirty(inode);
 	return err;
 }
@@ -358,7 +358,7 @@
 	de->inode = cpu_to_fs16(SYSV_SB(inode->i_sb), inode->i_ino);
 	err = dir_commit_chunk(page, from, to);
 	dir_put_page(page);
-	dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+	dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
 	mark_inode_dirty(dir);
 }
 
diff -Nru a/fs/sysv/ialloc.c b/fs/sysv/ialloc.c
--- a/fs/sysv/ialloc.c	2005-03-01 23:38:53 -08:00
+++ b/fs/sysv/ialloc.c	2005-03-01 23:38:53 -08:00
@@ -169,7 +169,7 @@
 
 	inode->i_uid = current->fsuid;
 	inode->i_ino = fs16_to_cpu(sbi, ino);
-	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
+	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
 	inode->i_blocks = inode->i_blksize = 0;
 	memset(SYSV_I(inode)->i_data, 0, sizeof(SYSV_I(inode)->i_data));
 	SYSV_I(inode)->i_dir_start_lookup = 0;
diff -Nru a/fs/sysv/itree.c b/fs/sysv/itree.c
--- a/fs/sysv/itree.c	2005-03-01 23:38:54 -08:00
+++ b/fs/sysv/itree.c	2005-03-01 23:38:54 -08:00
@@ -61,7 +61,7 @@
 	struct buffer_head *bh;
 } Indirect;
 
-static rwlock_t pointers_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(pointers_lock);
 
 static inline void add_chain(Indirect *p, struct buffer_head *bh, sysv_zone_t *v)
 {
@@ -178,7 +178,7 @@
 	*where->p = where->key;
 	write_unlock(&pointers_lock);
 
-	inode->i_ctime = CURRENT_TIME;
+	inode->i_ctime = CURRENT_TIME_SEC;
 
 	/* had we spliced it onto indirect block? */
 	if (where->bh)
@@ -418,7 +418,7 @@
 		}
 		n++;
 	}
-	inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+	inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC;
 	if (IS_SYNC(inode))
 		sysv_sync_inode (inode);
 	else
diff -Nru a/fs/sysv/namei.c b/fs/sysv/namei.c
--- a/fs/sysv/namei.c	2005-03-01 23:38:58 -08:00
+++ b/fs/sysv/namei.c	2005-03-01 23:38:58 -08:00
@@ -137,7 +137,7 @@
 	if (inode->i_nlink >= SYSV_SB(inode->i_sb)->s_link_max)
 		return -EMLINK;
 
-	inode->i_ctime = CURRENT_TIME;
+	inode->i_ctime = CURRENT_TIME_SEC;
 	inc_count(inode);
 	atomic_inc(&inode->i_count);
 
@@ -260,7 +260,7 @@
 			goto out_dir;
 		inc_count(old_inode);
 		sysv_set_link(new_de, new_page, old_inode);
-		new_inode->i_ctime = CURRENT_TIME;
+		new_inode->i_ctime = CURRENT_TIME_SEC;
 		if (dir_de)
 			new_inode->i_nlink--;
 		dec_count(new_inode);
diff -Nru a/fs/udf/balloc.c b/fs/udf/balloc.c
--- a/fs/udf/balloc.c	2005-03-01 23:38:54 -08:00
+++ b/fs/udf/balloc.c	2005-03-01 23:38:54 -08:00
@@ -148,6 +148,7 @@
 	struct udf_bitmap *bitmap,
 	kernel_lb_addr bloc, uint32_t offset, uint32_t count)
 {
+	struct udf_sb_info *sbi = UDF_SB(sb);
 	struct buffer_head * bh = NULL;
 	unsigned long block;
 	unsigned long block_group;
@@ -156,7 +157,7 @@
 	int bitmap_nr;
 	unsigned long overflow;
 
-	lock_super(sb);
+	down(&sbi->s_alloc_sem);
 	if (bloc.logicalBlockNum < 0 ||
 		(bloc.logicalBlockNum + count) > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum))
 	{
@@ -215,7 +216,7 @@
 	sb->s_dirt = 1;
 	if (UDF_SB_LVIDBH(sb))
 		mark_buffer_dirty(UDF_SB_LVIDBH(sb));
-	unlock_super(sb);
+	up(&sbi->s_alloc_sem);
 	return;
 }
 
@@ -224,13 +225,13 @@
 	struct udf_bitmap *bitmap, uint16_t partition, uint32_t first_block,
 	uint32_t block_count)
 {
+	struct udf_sb_info *sbi = UDF_SB(sb);
 	int alloc_count = 0;
 	int bit, block, block_group, group_start;
 	int nr_groups, bitmap_nr;
 	struct buffer_head *bh;
 
-	lock_super(sb);
-
+	down(&sbi->s_alloc_sem);
 	if (first_block < 0 || first_block >= UDF_SB_PARTLEN(sb, partition))
 		goto out;
 
@@ -279,7 +280,7 @@
 		mark_buffer_dirty(UDF_SB_LVIDBH(sb));
 	}
 	sb->s_dirt = 1;
-	unlock_super(sb);
+	up(&sbi->s_alloc_sem);
 	return alloc_count;
 }
 
@@ -287,6 +288,7 @@
 	struct inode * inode,
 	struct udf_bitmap *bitmap, uint16_t partition, uint32_t goal, int *err)
 {
+	struct udf_sb_info *sbi = UDF_SB(sb);
 	int newbit, bit=0, block, block_group, group_start;
 	int end_goal, nr_groups, bitmap_nr, i;
 	struct buffer_head *bh = NULL;
@@ -294,7 +296,7 @@
 	int newblock = 0;
 
 	*err = -ENOSPC;
-	lock_super(sb);
+	down(&sbi->s_alloc_sem);
 
 repeat:
 	if (goal < 0 || goal >= UDF_SB_PARTLEN(sb, partition))
@@ -367,7 +369,7 @@
 	}
 	if (i >= (nr_groups*2))
 	{
-		unlock_super(sb);
+		up(&sbi->s_alloc_sem);
 		return newblock;
 	}
 	if (bit < sb->s_blocksize << 3)
@@ -376,7 +378,7 @@
 		bit = udf_find_next_one_bit(bh->b_data, sb->s_blocksize << 3, group_start << 3);
 	if (bit >= sb->s_blocksize << 3)
 	{
-		unlock_super(sb);
+		up(&sbi->s_alloc_sem);
 		return 0;
 	}
 
@@ -390,7 +392,7 @@
 	 */
 	if (inode && DQUOT_ALLOC_BLOCK(inode, 1))
 	{
-		unlock_super(sb);
+		up(&sbi->s_alloc_sem);
 		*err = -EDQUOT;
 		return 0;
 	}
@@ -413,13 +415,13 @@
 		mark_buffer_dirty(UDF_SB_LVIDBH(sb));
 	}
 	sb->s_dirt = 1;
-	unlock_super(sb);
+	up(&sbi->s_alloc_sem);
 	*err = 0;
 	return newblock;
 
 error_return:
 	*err = -EIO;
-	unlock_super(sb);
+	up(&sbi->s_alloc_sem);
 	return 0;
 }
 
@@ -428,6 +430,7 @@
 	struct inode * table,
 	kernel_lb_addr bloc, uint32_t offset, uint32_t count)
 {
+	struct udf_sb_info *sbi = UDF_SB(sb);
 	uint32_t start, end;
 	uint32_t nextoffset, oextoffset, elen;
 	kernel_lb_addr nbloc, obloc, eloc;
@@ -435,7 +438,7 @@
 	int8_t etype;
 	int i;
 
-	lock_super(sb);
+	down(&sbi->s_alloc_sem);
 	if (bloc.logicalBlockNum < 0 ||
 		(bloc.logicalBlockNum + count) > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum))
 	{
@@ -669,7 +672,7 @@
 
 error_return:
 	sb->s_dirt = 1;
-	unlock_super(sb);
+	up(&sbi->s_alloc_sem);
 	return;
 }
 
@@ -678,6 +681,7 @@
 	struct inode *table, uint16_t partition, uint32_t first_block,
 	uint32_t block_count)
 {
+	struct udf_sb_info *sbi = UDF_SB(sb);
 	int alloc_count = 0;
 	uint32_t extoffset, elen, adsize;
 	kernel_lb_addr bloc, eloc;
@@ -694,8 +698,7 @@
 	else
 		return 0;
 
-	lock_super(sb);
-
+	down(&sbi->s_alloc_sem);
 	extoffset = sizeof(struct unallocSpaceEntry);
 	bloc = UDF_I_LOCATION(table);
 
@@ -739,7 +742,7 @@
 		mark_buffer_dirty(UDF_SB_LVIDBH(sb));
 		sb->s_dirt = 1;
 	}
-	unlock_super(sb);
+	up(&sbi->s_alloc_sem);
 	return alloc_count;
 }
 
@@ -747,6 +750,7 @@
 	struct inode * inode,
 	struct inode *table, uint16_t partition, uint32_t goal, int *err)
 {
+	struct udf_sb_info *sbi = UDF_SB(sb);
 	uint32_t spread = 0xFFFFFFFF, nspread = 0xFFFFFFFF;
 	uint32_t newblock = 0, adsize;
 	uint32_t extoffset, goal_extoffset, elen, goal_elen = 0;
@@ -763,8 +767,7 @@
 	else
 		return newblock;
 
-	lock_super(sb);
-
+	down(&sbi->s_alloc_sem);
 	if (goal < 0 || goal >= UDF_SB_PARTLEN(sb, partition))
 		goal = 0;
 
@@ -814,7 +817,7 @@
 	if (spread == 0xFFFFFFFF)
 	{
 		udf_release_data(goal_bh);
-		unlock_super(sb);
+		up(&sbi->s_alloc_sem);
 		return 0;
 	}
 
@@ -830,7 +833,7 @@
 	if (inode && DQUOT_ALLOC_BLOCK(inode, 1))
 	{
 		udf_release_data(goal_bh);
-		unlock_super(sb);
+		up(&sbi->s_alloc_sem);
 		*err = -EDQUOT;
 		return 0;
 	}
@@ -849,7 +852,7 @@
 	}
 
 	sb->s_dirt = 1;
-	unlock_super(sb);
+	up(&sbi->s_alloc_sem);
 	*err = 0;
 	return newblock;
 }
diff -Nru a/fs/udf/ialloc.c b/fs/udf/ialloc.c
--- a/fs/udf/ialloc.c	2005-03-01 23:38:56 -08:00
+++ b/fs/udf/ialloc.c	2005-03-01 23:38:56 -08:00
@@ -35,11 +35,8 @@
 
 void udf_free_inode(struct inode * inode)
 {
-	struct super_block * sb = inode->i_sb;
-	int is_directory;
-	unsigned long ino;
-
-	ino = inode->i_ino;
+	struct super_block *sb = inode->i_sb;
+	struct udf_sb_info *sbi = UDF_SB(sb);
 
 	/*
 	 * Note: we must free any quota before locking the superblock,
@@ -48,36 +45,32 @@
 	DQUOT_FREE_INODE(inode);
 	DQUOT_DROP(inode);
 
-	lock_super(sb);
-
-	is_directory = S_ISDIR(inode->i_mode);
-
 	clear_inode(inode);
 
-	if (UDF_SB_LVIDBH(sb))
-	{
-		if (is_directory)
+	down(&sbi->s_alloc_sem);
+	if (sbi->s_lvidbh) {
+		if (S_ISDIR(inode->i_mode))
 			UDF_SB_LVIDIU(sb)->numDirs =
 				cpu_to_le32(le32_to_cpu(UDF_SB_LVIDIU(sb)->numDirs) - 1);
 		else
 			UDF_SB_LVIDIU(sb)->numFiles =
 				cpu_to_le32(le32_to_cpu(UDF_SB_LVIDIU(sb)->numFiles) - 1);
 		
-		mark_buffer_dirty(UDF_SB_LVIDBH(sb));
+		mark_buffer_dirty(sbi->s_lvidbh);
 	}
-	unlock_super(sb);
+	up(&sbi->s_alloc_sem);
 
 	udf_free_blocks(sb, NULL, UDF_I_LOCATION(inode), 0, 1);
 }
 
 struct inode * udf_new_inode (struct inode *dir, int mode, int * err)
 {
-	struct super_block *sb;
+	struct super_block *sb = dir->i_sb;
+	struct udf_sb_info *sbi = UDF_SB(sb);
 	struct inode * inode;
 	int block;
 	uint32_t start = UDF_I_LOCATION(dir).logicalBlockNum;
 
-	sb = dir->i_sb;
 	inode = new_inode(sb);
 
 	if (!inode)
@@ -94,8 +87,8 @@
 		iput(inode);
 		return NULL;
 	}
-	lock_super(sb);
 
+	down(&sbi->s_alloc_sem);
 	UDF_I_UNIQUE(inode) = 0;
 	UDF_I_LENEXTENTS(inode) = 0;
 	UDF_I_NEXT_ALLOC_BLOCK(inode) = 0;
@@ -157,11 +150,11 @@
 	else
 		UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_LONG;
 	inode->i_mtime = inode->i_atime = inode->i_ctime =
-		UDF_I_CRTIME(inode) = CURRENT_TIME;
+		UDF_I_CRTIME(inode) = current_fs_time(inode->i_sb);
 	insert_inode_hash(inode);
 	mark_inode_dirty(inode);
+	up(&sbi->s_alloc_sem);
 
-	unlock_super(sb);
 	if (DQUOT_ALLOC_INODE(inode))
 	{
 		DQUOT_DROP(inode);
diff -Nru a/fs/udf/inode.c b/fs/udf/inode.c
--- a/fs/udf/inode.c	2005-03-01 23:39:18 -08:00
+++ b/fs/udf/inode.c	2005-03-01 23:39:18 -08:00
@@ -70,30 +70,6 @@
 static int udf_get_block(struct inode *, sector_t, struct buffer_head *, int);
 
 /*
- * udf_put_inode
- *
- * PURPOSE
- *
- * DESCRIPTION
- *	This routine is called whenever the kernel no longer needs the inode.
- *
- * HISTORY
- *	July 1, 1997 - Andrew E. Mileski
- *	Written, tested, and released.
- *
- *  Called at each iput()
- */
-void udf_put_inode(struct inode * inode)
-{
-	if (!(inode->i_sb->s_flags & MS_RDONLY))
-	{
-		lock_kernel();
-		udf_discard_prealloc(inode);
-		unlock_kernel();
-	}
-}
-
-/*
  * udf_delete_inode
  *
  * PURPOSE
@@ -129,6 +105,12 @@
 
 void udf_clear_inode(struct inode *inode)
 {
+	if (!(inode->i_sb->s_flags & MS_RDONLY)) {
+		lock_kernel();
+		udf_discard_prealloc(inode);
+		unlock_kernel();
+	}
+
 	kfree(UDF_I_DATA(inode));
 	UDF_I_DATA(inode) = NULL;
 }
@@ -568,7 +550,7 @@
 	*new = 1;
 	UDF_I_NEXT_ALLOC_BLOCK(inode) = block;
 	UDF_I_NEXT_ALLOC_GOAL(inode) = newblocknum;
-	inode->i_ctime = CURRENT_TIME;
+	inode->i_ctime = current_fs_time(inode->i_sb);
 
 	if (IS_SYNC(inode))
 		udf_sync_inode(inode);
@@ -912,7 +894,7 @@
 		udf_truncate_extents(inode);
 	}	
 
-	inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+	inode->i_mtime = inode->i_ctime = current_fs_time(inode->i_sb);
 	if (IS_SYNC(inode))
 		udf_sync_inode (inode);
 	else
@@ -920,30 +902,6 @@
 	unlock_kernel();
 }
 
-/*
- * udf_read_inode
- *
- * PURPOSE
- *	Read an inode.
- *
- * DESCRIPTION
- *	This routine is called by iget() [which is called by udf_iget()]
- *      (clean_inode() will have been called first)
- *	when an inode is first read into memory.
- *
- * HISTORY
- *	July 1, 1997 - Andrew E. Mileski
- *	Written, tested, and released.
- *
- * 12/19/98 dgb  Updated to fix size problems.
- */
-
-void
-udf_read_inode(struct inode *inode)
-{
-	memset(&UDF_I_LOCATION(inode), 0xFF, sizeof(kernel_lb_addr));
-}
-
 static void
 __udf_read_inode(struct inode *inode)
 {
@@ -1567,66 +1525,36 @@
 	return err;
 }
 
-/*
- * udf_iget
- *
- * PURPOSE
- *	Get an inode.
- *
- * DESCRIPTION
- *	This routine replaces iget() and read_inode().
- *
- * HISTORY
- *	October 3, 1997 - Andrew E. Mileski
- *	Written, tested, and released.
- *
- * 12/19/98 dgb  Added semaphore and changed to be a wrapper of iget
- */
 struct inode *
 udf_iget(struct super_block *sb, kernel_lb_addr ino)
 {
-	struct inode *inode;
-	unsigned long block;
-
-	block = udf_get_lb_pblock(sb, ino, 0);
-
-	/* Get the inode */
-
-	inode = iget(sb, block);
-		/* calls udf_read_inode() ! */
+	unsigned long block = udf_get_lb_pblock(sb, ino, 0);
+	struct inode *inode = iget_locked(sb, block);
 
 	if (!inode)
-	{
-		printk(KERN_ERR "udf: iget() failed\n");
 		return NULL;
-	}
-	else if (is_bad_inode(inode))
-	{
-		iput(inode);
-		return NULL;
-	}
-	else if (UDF_I_LOCATION(inode).logicalBlockNum == 0xFFFFFFFF &&
-		UDF_I_LOCATION(inode).partitionReferenceNum == 0xFFFF)
-	{
+
+	if (inode->i_state & I_NEW) {
 		memcpy(&UDF_I_LOCATION(inode), &ino, sizeof(kernel_lb_addr));
 		__udf_read_inode(inode);
-		if (is_bad_inode(inode))
-		{
-			iput(inode);
-			return NULL;
-		}
+		unlock_new_inode(inode);
 	}
 
-	if ( ino.logicalBlockNum >= UDF_SB_PARTLEN(sb, ino.partitionReferenceNum) )
-	{
+	if (is_bad_inode(inode))
+		goto out_iput;
+
+	if (ino.logicalBlockNum >= UDF_SB_PARTLEN(sb, ino.partitionReferenceNum)) {
 		udf_debug("block=%d, partition=%d out of range\n",
 			ino.logicalBlockNum, ino.partitionReferenceNum);
 		make_bad_inode(inode);
-		iput(inode);
-		return NULL;
- 	}
+		goto out_iput;
+	}
 
 	return inode;
+
+ out_iput:
+	iput(inode);
+	return NULL;
 }
 
 int8_t udf_add_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset,
diff -Nru a/fs/udf/namei.c b/fs/udf/namei.c
--- a/fs/udf/namei.c	2005-03-01 23:39:09 -08:00
+++ b/fs/udf/namei.c	2005-03-01 23:39:09 -08:00
@@ -887,7 +887,7 @@
 	inode->i_size = 0;
 	mark_inode_dirty(inode);
 	dir->i_nlink --;
-	inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+	inode->i_ctime = dir->i_ctime = dir->i_mtime = current_fs_time(dir->i_sb);
 	mark_inode_dirty(dir);
 
 end_rmdir:
@@ -928,7 +928,7 @@
 	retval = udf_delete_entry(dir, fi, &fibh, &cfi);
 	if (retval)
 		goto end_unlink;
-	dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+	dir->i_ctime = dir->i_mtime = current_fs_time(dir->i_sb);
 	mark_inode_dirty(dir);
 	inode->i_nlink--;
 	mark_inode_dirty(inode);
@@ -1158,7 +1158,7 @@
 		udf_release_data(fibh.ebh);
 	udf_release_data(fibh.sbh);
 	inode->i_nlink ++;
-	inode->i_ctime = CURRENT_TIME;
+	inode->i_ctime = current_fs_time(inode->i_sb);
 	mark_inode_dirty(inode);
 	atomic_inc(&inode->i_count);
 	d_instantiate(dentry, inode);
@@ -1251,7 +1251,7 @@
 	 * Like most other Unix systems, set the ctime for inodes on a
 	 * rename.
 	 */
-	old_inode->i_ctime = CURRENT_TIME;
+	old_inode->i_ctime = current_fs_time(old_inode->i_sb);
 	mark_inode_dirty(old_inode);
 
 	/*
@@ -1269,10 +1269,10 @@
 	if (new_inode)
 	{
 		new_inode->i_nlink--;
-		new_inode->i_ctime = CURRENT_TIME;
+		new_inode->i_ctime = current_fs_time(new_inode->i_sb);
 		mark_inode_dirty(new_inode);
 	}
-	old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
+	old_dir->i_ctime = old_dir->i_mtime = current_fs_time(old_dir->i_sb);
 	mark_inode_dirty(old_dir);
 
 	if (dir_fi)
diff -Nru a/fs/udf/super.c b/fs/udf/super.c
--- a/fs/udf/super.c	2005-03-01 23:39:07 -08:00
+++ b/fs/udf/super.c	2005-03-01 23:39:07 -08:00
@@ -162,9 +162,7 @@
 static struct super_operations udf_sb_ops = {
 	.alloc_inode		= udf_alloc_inode,
 	.destroy_inode		= udf_destroy_inode,
-	.read_inode		= udf_read_inode,
 	.write_inode		= udf_write_inode,
-	.put_inode		= udf_put_inode,
 	.delete_inode		= udf_delete_inode,
 	.clear_inode		= udf_clear_inode,
 	.put_super		= udf_put_super,
@@ -1506,6 +1504,8 @@
 	sb->s_fs_info = sbi;
 	memset(UDF_SB(sb), 0x00, sizeof(struct udf_sb_info));
 
+	init_MUTEX(&sbi->s_alloc_sem);
+
 	if (!udf_parse_options((char *)options, &uopt))
 		goto error_out;
 
@@ -1567,6 +1567,7 @@
 	sb->dq_op = NULL;
 	sb->s_dirt = 0;
 	sb->s_magic = UDF_SUPER_MAGIC;
+	sb->s_time_gran = 1000;
 
 	if (udf_load_partition(sb, &fileset))
 	{
diff -Nru a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h
--- a/fs/udf/udfdecl.h	2005-03-01 23:38:56 -08:00
+++ b/fs/udf/udfdecl.h	2005-03-01 23:38:56 -08:00
@@ -96,7 +96,6 @@
 extern struct buffer_head * udf_bread(struct inode *, int, int, int *);
 extern void udf_truncate(struct inode *);
 extern void udf_read_inode(struct inode *);
-extern void udf_put_inode(struct inode *);
 extern void udf_delete_inode(struct inode *);
 extern void udf_clear_inode(struct inode *);
 extern int udf_write_inode(struct inode *, int);
diff -Nru a/fs/ufs/dir.c b/fs/ufs/dir.c
--- a/fs/ufs/dir.c	2005-03-01 23:39:09 -08:00
+++ b/fs/ufs/dir.c	2005-03-01 23:39:09 -08:00
@@ -462,7 +462,7 @@
 	if (IS_DIRSYNC(dir))
 		sync_dirty_buffer(bh);
 	brelse (bh);
-	dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+	dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
 	dir->i_version++;
 	mark_inode_dirty(dir);
 
@@ -505,7 +505,7 @@
 					fs16_to_cpu(sb, dir->d_reclen));
 			dir->d_ino = 0;
 			inode->i_version++;
-			inode->i_ctime = inode->i_mtime = CURRENT_TIME;
+			inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC;
 			mark_inode_dirty(inode);
 			mark_buffer_dirty(bh);
 			if (IS_DIRSYNC(inode))
diff -Nru a/fs/ufs/ialloc.c b/fs/ufs/ialloc.c
--- a/fs/ufs/ialloc.c	2005-03-01 23:39:09 -08:00
+++ b/fs/ufs/ialloc.c	2005-03-01 23:39:09 -08:00
@@ -267,7 +267,7 @@
 	inode->i_ino = cg * uspi->s_ipg + bit;
 	inode->i_blksize = PAGE_SIZE;	/* This is the optimal IO size (for stat), not the fs block size */
 	inode->i_blocks = 0;
-	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
+	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
 	ufsi->i_flags = UFS_I(dir)->i_flags;
 	ufsi->i_lastfrag = 0;
 	ufsi->i_gen = 0;
diff -Nru a/fs/ufs/inode.c b/fs/ufs/inode.c
--- a/fs/ufs/inode.c	2005-03-01 23:39:18 -08:00
+++ b/fs/ufs/inode.c	2005-03-01 23:39:18 -08:00
@@ -272,7 +272,7 @@
 		*new = 1;
 	}
 
-	inode->i_ctime = CURRENT_TIME;
+	inode->i_ctime = CURRENT_TIME_SEC;
 	if (IS_SYNC(inode))
 		ufs_sync_inode (inode);
 	mark_inode_dirty(inode);
@@ -363,7 +363,7 @@
 	mark_buffer_dirty(bh);
 	if (IS_SYNC(inode))
 		sync_dirty_buffer(bh);
-	inode->i_ctime = CURRENT_TIME;
+	inode->i_ctime = CURRENT_TIME_SEC;
 	mark_inode_dirty(inode);
 out:
 	brelse (bh);
diff -Nru a/fs/ufs/namei.c b/fs/ufs/namei.c
--- a/fs/ufs/namei.c	2005-03-01 23:39:18 -08:00
+++ b/fs/ufs/namei.c	2005-03-01 23:39:18 -08:00
@@ -190,7 +190,7 @@
 		return -EMLINK;
 	}
 
-	inode->i_ctime = CURRENT_TIME;
+	inode->i_ctime = CURRENT_TIME_SEC;
 	ufs_inc_count(inode);
 	atomic_inc(&inode->i_count);
 
@@ -321,7 +321,7 @@
 			goto out_dir;
 		ufs_inc_count(old_inode);
 		ufs_set_link(new_dir, new_de, new_bh, old_inode);
-		new_inode->i_ctime = CURRENT_TIME;
+		new_inode->i_ctime = CURRENT_TIME_SEC;
 		if (dir_de)
 			new_inode->i_nlink--;
 		ufs_dec_count(new_inode);
diff -Nru a/fs/ufs/truncate.c b/fs/ufs/truncate.c
--- a/fs/ufs/truncate.c	2005-03-01 23:38:57 -08:00
+++ b/fs/ufs/truncate.c	2005-03-01 23:38:57 -08:00
@@ -469,7 +469,7 @@
 			brelse (bh);
 		}
 	}
-	inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+	inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC;
 	ufsi->i_lastfrag = DIRECT_FRAGMENT;
 	unlock_kernel();
 	mark_inode_dirty(inode);
diff -Nru a/fs/umsdos/Makefile b/fs/umsdos/Makefile
--- a/fs/umsdos/Makefile	2005-03-01 23:38:54 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,13 +0,0 @@
-#
-# Makefile for the umsdos Unix-like filesystem routines.
-#
-
-obj-$(CONFIG_UMSDOS) += umsdos.o
-
-umsdos-objs := dir.o  inode.o ioctl.o mangle.o namei.o rdir.o emd.o
-
-p:
-	proto *.c >/usr/include/linux/umsdos_fs.p
-
-doc:
-	nadoc -i -p umsdos.doc - /tmp/umsdos.mpg
diff -Nru a/fs/umsdos/README-WIP.txt b/fs/umsdos/README-WIP.txt
--- a/fs/umsdos/README-WIP.txt	2005-03-01 23:39:18 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,114 +0,0 @@
-Changes by Matija Nalis (mnalis@jagor.srce.hr) on umsdos dentry fixing
-(started by Peter T. Waltenberg <peterw@karaka.chch.cri.nz>)
-(Final conversion to dentries Bill Hawes <whawes@star.net>)
-
-There is no warning any more.
-Both read-only and read-write stuff is fixed, both in
-msdos-compatibile mode, and in umsdos EMD mode, and it seems stable.
-
-Userland NOTE: new umsdos_progs (umssync, umssetup, udosctl & friends) that
-will compile and work on 2.2.x+ kernels and glibc based systems, as well as
-kernel patches and other umsdos related information may be found at
-http://linux.voyager.hr/umsdos/
-
-Information below is getting outdated slowly -- I'll fix it one day when I
-get enough time - there are more important things to fix right now.
-
-Legend: those lines marked with '+' on the beggining of line indicates it
-passed all of my tests, and performed perfect in all of them.
-
-Current status (010125) - UMSDOS 0.86j:
-
-(1) pure MSDOS (no --linux-.--- EMD file):
-
-READ:
-+ readdir			- works
-+ lookup			- works
-+ read file			- works
-
-WRITE:
-+ creat file			- works
-+ unlink file			- works
-+ write file			- works
-+ rename file (same dir)	- works
-+ rename file (dif. dir)	- works
-+ rename dir (same dir)		- works
-+ rename dir (dif. dir)		- works
-+ mkdir				- works
-+ rmdir 			- works
-
-
-(2) umsdos (with --linux-.--- EMD file):
-
-READ:
-+ readdir			- works
-+ lookup 			- works
-+ permissions/owners stuff	- works
-+ long file names		- works
-+ read file			- works
-+ switching MSDOS/UMSDOS	- works
-+ switching UMSDOS/MSDOS	- works
-- pseudo root things		- works mostly. See notes below.
-+ resolve symlink		- works
-+ dereference symlink		- works
-+ dangling symlink		- works
-+ hard links			- works
-+ special files (block/char devices, FIFOs, sockets...)	- works
-+ various umsdos ioctls		- works
-
-
-WRITE:
-+ create symlink		- works
-+ create hardlink		- works
-+ create file			- works
-+ create special file		- works
-+ write to file			- works
-+ rename file (same dir)	- works
-+ rename file (dif. dir)	- works
-+ rename hardlink (same dir)	- works
-- rename hardlink (dif. dir)	- works, but see notes below.
-+ rename symlink (same dir)	- works
-+ rename symlink (dif. dir)	- works
-+ rename dir (same dir)		- works
-+ rename dir (dif. dir)		- works
-+ unlink file			- works
-+ notify_change (chown,perms)	- works
-+ notify_change for hardlinks	- works
-+ unlink hardlink		- works
-+ mkdir				- works
-+ rmdir 			- works
-+ umssyncing (many ioctls)	- works
-
-
-- CVF-FAT stuff (compressed DOS filesystem) - there is some support from Frank
-  Gockel <gockel@sent13.uni-duisburg.de> to use it even under umsdosfs, but I
-  have no way of testing it -- please let me know if there are problems specific
-  to umsdos (for instance, it works under msdosfs, but not under umsdosfs).
-
-
-Some current notes:
-
-Note: creating and using pseudo-hardlinks is always non-perfect, especially
-in filesystems that might be externally modified like umsdos. There is
-example is specs file about it. Specifically, moving directory which
-contains hardlinks will break them.
-
-Note: (about creating hardlinks in pseudoroot mode) - hardlinks created in
-pseudoroot mode are now again compatibile with 'normal' hardlinks, and vice
-versa. Thanks to Sorin Iordachescu <sorin@rodae.ro> for providing fix.
-See http://linux.voyager.hr/umsdos/hlbug.html for more info and upgrade
-procedure if you used broken versions...
-
-------------------------------------------------------------------------------
-
-Some general notes:
-
-Good idea when running development kernels is to have SysRq support compiled
-in kernel, and use Sync/Emergency-remount-RO if you bump into problems (like
-not being able to umount(2) umsdosfs, and because of it root partition also,
-or panics which force you to reboot etc.)
-
-I'm unfortunately somewhat out of time to read linux-kernel@vger, but I do
-check for messages having "UMSDOS" in the subject, and read them.  I might
-miss some in all that volume, though.  I should reply to any direct e-mail
-in few days.  If I don't, probably I never got your message.
diff -Nru a/fs/umsdos/dir.c b/fs/umsdos/dir.c
--- a/fs/umsdos/dir.c	2005-03-01 23:38:57 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,810 +0,0 @@
-/*
- *  linux/fs/umsdos/dir.c
- *
- *  Written 1993 by Jacques Gelinas
- *      Inspired from linux/fs/msdos/... : Werner Almesberger
- *
- *  Extended MS-DOS directory handling functions
- */
-
-#include <linux/time.h>
-#include <linux/string.h>
-#include <linux/fs.h>
-#include <linux/msdos_fs.h>
-#include <linux/errno.h>
-#include <linux/stat.h>
-#include <linux/limits.h>
-#include <linux/umsdos_fs.h>
-#include <linux/slab.h>
-#include <linux/pagemap.h>
-#include <linux/smp_lock.h>
-
-#define UMSDOS_SPECIAL_DIRFPOS	3
-extern struct dentry *saved_root;
-extern struct inode *pseudo_root;
-
-/* #define UMSDOS_DEBUG_VERBOSE 1 */
-
-/*
- * Dentry operations routines
- */
-
-/* nothing for now ... */
-static int umsdos_dentry_validate(struct dentry *dentry, struct nameidata *nd)
-{
-	return 1;
-}
-
-/* for now, drop everything to force lookups ... */
-/* ITYM s/everything/& positive/... */
-static int umsdos_dentry_dput(struct dentry *dentry)
-{
-	struct inode *inode = dentry->d_inode;
-	if (inode) {
-		return 1;
-	}
-	return 0;
-}
-
-struct dentry_operations umsdos_dentry_operations =
-{
-	.d_revalidate	= umsdos_dentry_validate,
-	.d_delete	= umsdos_dentry_dput,
-};
-
-struct UMSDOS_DIR_ONCE {
-	void *dirbuf;
-	filldir_t filldir;
-	int count;
-	int stop;
-};
-
-/*
- * Record a single entry the first call.
- * Return -EINVAL the next one.
- * NOTE: filldir DOES NOT use a dentry
- */
-
-static int umsdos_dir_once (	void *buf,
-				const char *name,
-				int len,
-				loff_t offset,
-				ino_t ino,
-				unsigned type)
-{
-	int ret = -EINVAL;
-	struct UMSDOS_DIR_ONCE *d = (struct UMSDOS_DIR_ONCE *) buf;
-
-	if (d->count == 0) {
-		PRINTK ((KERN_DEBUG "dir_once :%.*s: offset %Ld\n", 
-			len, name, offset));
-		ret = d->filldir (d->dirbuf, name, len, offset, ino, DT_UNKNOWN);
-		d->stop = ret < 0;
-		d->count = 1;
-	}
-	return ret;
-}
-
-
-/*
- * Read count directory entries from directory filp
- * Return a negative value from linux/errno.h.
- * Return > 0 if success (the number of bytes written by filldir).
- * 
- * This function is used by the normal readdir VFS entry point,
- * and in order to get the directory entry from a file's dentry.
- * See umsdos_dentry_to_entry() below.
- */
- 
-static int umsdos_readdir_x (struct inode *dir, struct file *filp,
-				void *dirbuf, struct umsdos_dirent *u_entry,
-				filldir_t filldir)
-{
-	struct dentry *demd;
-	off_t start_fpos;
-	int ret = 0;
-	loff_t pos;
-
-	umsdos_startlookup (dir);
-
-	if (filp->f_pos == UMSDOS_SPECIAL_DIRFPOS && dir == pseudo_root) {
-
-		/*
-		 * We don't need to simulate this pseudo directory
-		 * when umsdos_readdir_x is called for internal operation
-		 * of umsdos. This is why dirent_in_fs is tested
-		 */
-		/* #Specification: pseudo root / directory /DOS
-		 * When umsdos operates in pseudo root mode (C:\linux is the
-		 * linux root), it simulate a directory /DOS which points to
-		 * the real root of the file system.
-		 */
-
-		Printk ((KERN_WARNING "umsdos_readdir_x: pseudo_root thing UMSDOS_SPECIAL_DIRFPOS\n"));
-		if (filldir (dirbuf, "DOS", 3, 
-				UMSDOS_SPECIAL_DIRFPOS, UMSDOS_ROOT_INO, DT_DIR) == 0) {
-			filp->f_pos++;
-		}
-		goto out_end;
-	}
-
-	if (filp->f_pos < 2 || 
-	    (dir->i_ino != UMSDOS_ROOT_INO && filp->f_pos == 32)) {
-	
-		int last_f_pos = filp->f_pos;
-		struct UMSDOS_DIR_ONCE bufk;
-
-		Printk (("umsdos_readdir_x: . or .. /mn/?\n"));
-
-		bufk.dirbuf = dirbuf;
-		bufk.filldir = filldir;
-		bufk.count = 0;
-
-		ret = fat_readdir (filp, &bufk, umsdos_dir_once);
-		if (last_f_pos > 0 && filp->f_pos > last_f_pos)
-			filp->f_pos = UMSDOS_SPECIAL_DIRFPOS;
-		if (u_entry != NULL)
-			u_entry->flags = 0;
-		goto out_end;
-	}
-
-	Printk (("umsdos_readdir_x: normal file /mn/?\n"));
-
-	/* get the EMD dentry */
-	demd = umsdos_get_emd_dentry(filp->f_dentry);
-	ret = PTR_ERR(demd);
-	if (IS_ERR(demd))
-		goto out_end;
-	ret = -EIO;
-	if (!demd->d_inode) {
-		printk(KERN_WARNING 
-			"umsdos_readir_x: EMD file %s/%s not found\n",
-			demd->d_parent->d_name.name, demd->d_name.name);
-		goto out_dput;
-	}
-
-	pos = filp->f_pos;
-	start_fpos = filp->f_pos;
-
-	if (pos <= UMSDOS_SPECIAL_DIRFPOS + 1)
-		pos = 0;
-	ret = 0;
-	while (pos < demd->d_inode->i_size) {
-		off_t cur_f_pos = pos;
-		struct dentry *dret;
-		struct inode *inode;
-		struct umsdos_dirent entry;
-		struct umsdos_info info;
-
-		ret = -EIO;
-		if (umsdos_emd_dir_readentry (demd, &pos, &entry) != 0)
-			break;
-		if (entry.name_len == 0)
-			continue;
-#ifdef UMSDOS_DEBUG_VERBOSE
-if (entry.flags & UMSDOS_HLINK)
-printk("umsdos_readdir_x: %s/%s is hardlink\n",
-filp->f_dentry->d_name.name, entry.name);
-#endif
-
-		umsdos_parse (entry.name, entry.name_len, &info);
-		info.f_pos = cur_f_pos;
-		umsdos_manglename (&info);
-		/*
-		 * Do a real lookup on the short name.
-		 */
-		dret = umsdos_covered(filp->f_dentry, info.fake.fname,
-						 info.fake.len);
-		ret = PTR_ERR(dret);
-		if (IS_ERR(dret))
-			break;
-		/*
-		 * If the file wasn't found, remove it from the EMD.
-		 */
-		inode = dret->d_inode;
-		if (!inode)
-			goto remove_name;
-#ifdef UMSDOS_DEBUG_VERBOSE
-if (UMSDOS_I(inode)->i_is_hlink)
-printk("umsdos_readdir_x: %s/%s already resolved, ino=%ld\n",
-dret->d_parent->d_name.name, dret->d_name.name, inode->i_ino);
-#endif
-
-Printk (("Found %s/%s, ino=%ld, flags=%x\n",
-dret->d_parent->d_name.name, info.fake.fname, dret->d_inode->i_ino,
-entry.flags));
-		/* check whether to resolve a hard-link */
-		if ((entry.flags & UMSDOS_HLINK) &&
-		    !UMSDOS_I(inode)->i_is_hlink) {
-			dret = umsdos_solve_hlink (dret);
-			ret = PTR_ERR(dret);
-			if (IS_ERR(dret))
-				break;
-			inode = dret->d_inode;
-			if (!inode) {
-printk("umsdos_readdir_x: %s/%s negative after link\n",
-dret->d_parent->d_name.name, dret->d_name.name);
-				goto clean_up;
-			}
-		}
-
-		/* #Specification:  pseudo root / reading real root
-		 * The pseudo root (/linux) is logically
-		 * erased from the real root.  This means that
-		 * ls /DOS, won't show "linux". This avoids
-		 * infinite recursion (/DOS/linux/DOS/linux/...) while
-		 * walking the file system.
-		 */
-		if (inode != pseudo_root && !(entry.flags & UMSDOS_HIDDEN)) {
-			if (filldir (dirbuf, entry.name, entry.name_len,
-				 cur_f_pos, inode->i_ino, DT_UNKNOWN) < 0) {
-				pos = cur_f_pos;
-			}
-Printk(("umsdos_readdir_x: got %s/%s, ino=%ld\n",
-dret->d_parent->d_name.name, dret->d_name.name, inode->i_ino));
-			if (u_entry != NULL)
-				*u_entry = entry;
-			dput(dret);
-			ret = 0;
-			break;
-		}
-	clean_up:
-		dput(dret);
-		continue;
-
-	remove_name:
-		/* #Specification:  umsdos / readdir / not in MSDOS
-		 * During a readdir operation, if the file is not
-		 * in the MS-DOS directory any more, the entry is
-		 * removed from the EMD file silently.
-		 */
-#ifdef UMSDOS_PARANOIA
-printk("umsdos_readdir_x: %s/%s out of sync, erasing\n",
-filp->f_dentry->d_name.name, info.entry.name);
-#endif
-		ret = umsdos_delentry(filp->f_dentry, &info, 
-					S_ISDIR(info.entry.mode));
-		if (ret)
-			printk(KERN_WARNING 
-				"umsdos_readdir_x: delentry %s, err=%d\n",
-				info.entry.name, ret);
-		goto clean_up;
-	}
-	/*
-	 * If the fillbuf has failed, f_pos is back to 0.
-	 * To avoid getting back into the . and .. state
-	 * (see comments at the beginning), we put back
-	 * the special offset.
-	 */
-	filp->f_pos = pos;
-	if (filp->f_pos == 0)
-		filp->f_pos = start_fpos;
-out_dput:
-	dput(demd);
-
-out_end:
-	umsdos_endlookup (dir);
-	
-	Printk ((KERN_DEBUG "read dir %p pos %Ld ret %d\n",
-		dir, filp->f_pos, ret));
-	return ret;
-}
-
-
-/*
- * Read count directory entries from directory filp.
- * Return a negative value from linux/errno.h.
- * Return 0 or positive if successful.
- */
- 
-static int UMSDOS_readdir (struct file *filp, void *dirbuf, filldir_t filldir)
-{
-	struct inode *dir = filp->f_dentry->d_inode;
-	int ret = 0, count = 0;
-	struct UMSDOS_DIR_ONCE bufk;
-
-	lock_kernel();
-
-	bufk.dirbuf = dirbuf;
-	bufk.filldir = filldir;
-	bufk.stop = 0;
-
-	Printk (("UMSDOS_readdir in\n"));
-	while (ret == 0 && bufk.stop == 0) {
-		struct umsdos_dirent entry;
-
-		bufk.count = 0;
-		ret = umsdos_readdir_x (dir, filp, &bufk, &entry, 
-					umsdos_dir_once);
-		if (bufk.count == 0)
-			break;
-		count += bufk.count;
-	}
-	unlock_kernel();
-	Printk (("UMSDOS_readdir out %d count %d pos %Ld\n", 
-		ret, count, filp->f_pos));
-	return count ? : ret;
-}
-
-
-/*
- * Complete the inode content with info from the EMD file.
- *
- * This function modifies the state of a dir inode.  It decides
- * whether the dir is a UMSDOS or DOS directory.  This is done
- * deeper in umsdos_patch_inode() called at the end of this function.
- * 
- * Because it is does disk access, umsdos_patch_inode() may block.
- * At the same time, another process may get here to initialise
- * the same directory inode. There are three cases.
- * 
- * 1) The inode is already initialised.  We do nothing.
- * 2) The inode is not initialised.  We lock access and do it.
- * 3) Like 2 but another process has locked the inode, so we try
- * to lock it and check right afterward check whether
- * initialisation is still needed.
- * 
- * 
- * Thanks to the "mem" option of the kernel command line, it was
- * possible to consistently reproduce this problem by limiting
- * my memory to 4 MB and running X.
- *
- * Do this only if the inode is freshly read, because we will lose
- * the current (updated) content.
- *
- * A lookup of a mount point directory yield the inode into
- * the other fs, so we don't care about initialising it. iget()
- * does this automatically.
- */
-
-void umsdos_lookup_patch_new(struct dentry *dentry, struct umsdos_info *info)
-{
-	struct inode *inode = dentry->d_inode;
-	struct umsdos_dirent *entry = &info->entry;
-
-	/*
-	 * This part of the initialization depends only on i_patched.
-	 */
-	if (UMSDOS_I(inode)->i_patched)
-		goto out;
-	UMSDOS_I(inode)->i_patched = 1;
-	if (S_ISREG (entry->mode))
-		entry->mtime = inode->i_mtime;
-	inode->i_mode = entry->mode;
-	inode->i_rdev = to_kdev_t (entry->rdev);
-	inode->i_atime = entry->atime;
-	inode->i_ctime = entry->ctime;
-	inode->i_mtime = entry->mtime;
-	inode->i_uid = entry->uid;
-	inode->i_gid = entry->gid;
-
-	/* #Specification: umsdos / i_nlink
-	 * The nlink field of an inode is maintained by the MSDOS file system
-	 * for directory and by UMSDOS for other files.  The logic is that
-	 * MSDOS is already figuring out what to do for directories and
-	 * does nothing for other files.  For MSDOS, there are no hard links
-	 * so all file carry nlink==1.  UMSDOS use some info in the
-	 * EMD file to plug the correct value.
-	 */
-	if (!S_ISDIR (entry->mode)) {
-		if (entry->nlink > 0) {
-			inode->i_nlink = entry->nlink;
-		} else {
-			printk (KERN_ERR 
-				"UMSDOS:  lookup_patch entry->nlink < 1 ???\n");
-		}
-	}
-	/*
-	 * The mode may have changed, so patch the inode again.
-	 */
-	umsdos_patch_dentry_inode(dentry, info->f_pos);
-	umsdos_set_dirinfo_new(dentry, info->f_pos);
-
-out:
-	return;
-}
-
-
-/*
- * Return != 0 if an entry is the pseudo DOS entry in the pseudo root.
- */
-
-int umsdos_is_pseudodos (struct inode *dir, struct dentry *dentry)
-{
-	/* #Specification: pseudo root / DOS hard coded
-	 * The pseudo sub-directory DOS in the pseudo root is hard coded.
-	 * The name is DOS. This is done this way to help standardised
-	 * the umsdos layout. The idea is that from now on /DOS is
-	 * a reserved path and nobody will think of using such a path
-	 * for a package.
-	 */
-	return dir == pseudo_root
-	    && dentry->d_name.len == 3
-	    && dentry->d_name.name[0] == 'D'
-	    && dentry->d_name.name[1] == 'O'
-	    && dentry->d_name.name[2] == 'S';
-}
-
-
-/*
- * Check whether a file exists in the current directory.
- * Return 0 if OK, negative error code if not (ex: -ENOENT).
- *
- * fills dentry->d_inode with found inode, and increments its count.
- * if not found, return -ENOENT.
- */
-/* #Specification: umsdos / lookup
- * A lookup for a file is done in two steps.  First, we
- * locate the file in the EMD file.  If not present, we
- * return an error code (-ENOENT).  If it is there, we
- * repeat the operation on the msdos file system. If
- * this fails, it means that the file system is not in
- * sync with the EMD file.   We silently remove this
- * entry from the EMD file, and return ENOENT.
- */
-
-struct dentry *umsdos_lookup_x (struct inode *dir, struct dentry *dentry, int nopseudo)
-{				
-	struct dentry *dret = NULL;
-	struct inode *inode;
-	int ret = -ENOENT;
-	struct umsdos_info info;
-
-#ifdef UMSDOS_DEBUG_VERBOSE
-printk("umsdos_lookup_x: looking for %s/%s\n", 
-dentry->d_parent->d_name.name, dentry->d_name.name);
-#endif
-
-	umsdos_startlookup (dir);
-	if (umsdos_is_pseudodos (dir, dentry)) {
-		/* #Specification: pseudo root / lookup(DOS)
-		 * A lookup of DOS in the pseudo root will always succeed
-		 * and return the inode of the real root.
-		 */
-		Printk ((KERN_DEBUG "umsdos_lookup_x: following /DOS\n"));
-		inode = saved_root->d_inode;
-		goto out_add;
-	}
-
-	ret = umsdos_parse (dentry->d_name.name, dentry->d_name.len, &info);
-	if (ret) {
-printk("umsdos_lookup_x: %s/%s parse failed, ret=%d\n", 
-dentry->d_parent->d_name.name, dentry->d_name.name, ret);
-		goto out;
-	}
-
-	ret = umsdos_findentry (dentry->d_parent, &info, 0);
-	if (ret) {
-if (ret != -ENOENT)
-printk("umsdos_lookup_x: %s/%s findentry failed, ret=%d\n", 
-dentry->d_parent->d_name.name, dentry->d_name.name, ret);
-		goto out;
-	}
-Printk (("lookup %.*s pos %lu ret %d len %d ", 
-info.fake.len, info.fake.fname, info.f_pos, ret, info.fake.len));
-
-	/* do a real lookup to get the short name ... */
-	dret = umsdos_covered(dentry->d_parent, info.fake.fname, info.fake.len);
-	ret = PTR_ERR(dret);
-	if (IS_ERR(dret)) {
-printk("umsdos_lookup_x: %s/%s real lookup failed, ret=%d\n", 
-dentry->d_parent->d_name.name, dentry->d_name.name, ret);
-		goto out;
-	}
-	inode = dret->d_inode;
-	if (!inode)
-		goto out_remove;
-	umsdos_lookup_patch_new(dret, &info);
-#ifdef UMSDOS_DEBUG_VERBOSE
-printk("umsdos_lookup_x: found %s/%s, ino=%ld\n", 
-dret->d_parent->d_name.name, dret->d_name.name, dret->d_inode->i_ino);
-#endif
-
-	/* Check for a hard link */
-	if ((info.entry.flags & UMSDOS_HLINK) &&
-	    !UMSDOS_I(inode)->i_is_hlink) {
-		dret = umsdos_solve_hlink (dret);
-		ret = PTR_ERR(dret);
-		if (IS_ERR(dret))
-			goto out;
-		ret = -ENOENT;
-		inode = dret->d_inode;
-		if (!inode) {
-printk("umsdos_lookup_x: %s/%s negative after link\n", 
-dret->d_parent->d_name.name, dret->d_name.name);
-			goto out_dput;
-		}
-	}
-
-	if (inode == pseudo_root && !nopseudo) {
-		/* #Specification: pseudo root / dir lookup
-		 * For the same reason as readdir, a lookup in /DOS for
-		 * the pseudo root directory (linux) will fail.
-		 */
-		/*
-		 * This has to be allowed for resolving hard links
-		 * which are recorded independently of the pseudo-root
-		 * mode.
-		 */
-printk("umsdos_lookup_x: skipping DOS/linux\n");
-		ret = -ENOENT;
-		goto out_dput;
-	}
-
-	/*
-	 * We've found it OK.  Now hash the dentry with the inode.
-	 */
-out_add:
-	atomic_inc(&inode->i_count);
-	d_add (dentry, inode);
-	dentry->d_op = &umsdos_dentry_operations;
-	ret = 0;
-
-out_dput:
-	if (dret && dret != dentry)
-		d_drop(dret);
-	dput(dret);
-out:
-	umsdos_endlookup (dir);
-	return ERR_PTR(ret);
-
-out_remove:
-	printk(KERN_WARNING "UMSDOS:  entry %s/%s out of sync, erased\n",
-		dentry->d_parent->d_name.name, dentry->d_name.name);
-	umsdos_delentry (dentry->d_parent, &info, S_ISDIR (info.entry.mode));
-	ret = -ENOENT;
-	goto out_dput;
-}
-
-
-/*
- * Check whether a file exists in the current directory.
- * Return 0 if OK, negative error code if not (ex: -ENOENT).
- * 
- * Called by VFS; should fill dentry->d_inode via d_add.
- */
-
-struct dentry *UMSDOS_lookup (struct inode *dir, struct dentry *dentry, struct nameidata *nd)
-{
-	struct dentry *ret;
-
-	ret = umsdos_lookup_x (dir, dentry, 0);
-
-	/* Create negative dentry if not found. */
-	if (ret == ERR_PTR(-ENOENT)) {
-		Printk ((KERN_DEBUG 
-			"UMSDOS_lookup: converting -ENOENT to negative\n"));
-		d_add (dentry, NULL);
-		dentry->d_op = &umsdos_dentry_operations;
-		ret = NULL;
-	}
-	return ret;
-}
-
-struct dentry *umsdos_covered(struct dentry *parent, char *name, int len)
-{
-	struct dentry *result, *dentry;
-	struct qstr qstr;
-
-	qstr.name = name;
-	qstr.len  = len;
-	qstr.hash = full_name_hash(name, len);
-	result = ERR_PTR(-ENOMEM);
-	dentry = d_alloc(parent, &qstr);
-	if (dentry) {
-		/* XXXXXXXXXXXXXXXXXXX Race alert! */
-		result = UMSDOS_rlookup(parent->d_inode, dentry);
-		d_drop(dentry);
-		if (result)
-			goto out_fail;
-		return dentry;
-	}
-out:
-	return result;
-
-out_fail:
-	dput(dentry);
-	goto out;
-}
-
-/*
- * Lookup or create a dentry from within the filesystem.
- *
- * We need to use this instead of lookup_dentry, as the 
- * directory semaphore lock is already held.
- */
-struct dentry *umsdos_lookup_dentry(struct dentry *parent, char *name, int len,
-					int real)
-{
-	struct dentry *result, *dentry;
-	struct qstr qstr;
-
-	qstr.name = name;
-	qstr.len  = len;
-	qstr.hash = full_name_hash(name, len);
-	result = d_lookup(parent, &qstr);
-	if (!result) {
-		result = ERR_PTR(-ENOMEM);
-		dentry = d_alloc(parent, &qstr);
-		if (dentry) {
-			result = real ?
-				UMSDOS_rlookup(parent->d_inode, dentry) :
-				UMSDOS_lookup(parent->d_inode, dentry);
-			if (result)
-				goto out_fail;
-			return dentry;
-		}
-	}
-out:
-	return result;
-
-out_fail:
-	dput(dentry);
-	goto out;
-}
-
-/*
- * Return a path relative to our root.
- */
-char * umsdos_d_path(struct dentry *dentry, char * buffer, int len)
-{
-	struct dentry * old_root;
-	char * path;
-
-	read_lock(&current->fs->lock);
-	old_root = dget(current->fs->root);
-	read_unlock(&current->fs->lock);
-	spin_lock(&dcache_lock);
-	path = __d_path(dentry, current->fs->rootmnt, dentry->d_sb->s_root, current->fs->rootmnt, buffer, len); /* FIXME: current->fs->rootmnt */
-	spin_unlock(&dcache_lock);
-
-	if (*path == '/')
-		path++; /* skip leading '/' */
-
-	if (current->fs->root->d_inode == pseudo_root)
-	{
-		*(path-1) = '/';
-		path -= (UMSDOS_PSDROOT_LEN+1);
-		memcpy(path, UMSDOS_PSDROOT_NAME, UMSDOS_PSDROOT_LEN);
-	}
-	dput(old_root);
-
-	return path;
-}
-
-/*
- * Return the dentry which points to a pseudo-hardlink.
- *
- * it should try to find file it points to
- * if file is found, return new dentry/inode
- * The resolved inode will have i_is_hlink set.
- *
- * Note: the original dentry is always dput(), even if an error occurs.
- */
-
-struct dentry *umsdos_solve_hlink (struct dentry *hlink)
-{
-	/* root is our root for resolving pseudo-hardlink */
-	struct dentry *base = hlink->d_sb->s_root;
-	struct dentry *dentry_dst;
-	char *path, *pt;
-	int len;
-	struct address_space *mapping = hlink->d_inode->i_mapping;
-	struct page *page;
-
-	page=read_cache_page(mapping,0,(filler_t *)mapping->a_ops->readpage,NULL);
-	dentry_dst=(struct dentry *)page;
-	if (IS_ERR(page))
-		goto out;
-	wait_on_page_locked(page);
-	if (!PageUptodate(page))
-		goto async_fail;
-
-	dentry_dst = ERR_PTR(-ENOMEM);
-	path = (char *) kmalloc (PATH_MAX, GFP_KERNEL);
-	if (path == NULL)
-		goto out_release;
-	memcpy(path, kmap(page), hlink->d_inode->i_size);
-	kunmap(page);
-	page_cache_release(page);
-
-	len = hlink->d_inode->i_size;
-
-	/* start at root dentry */
-	dentry_dst = dget(base);
-	path[len] = '\0';
-	
-	pt = path;
-	if (*path == '/')
-		pt++; /* skip leading '/' */
-	
-	if (base->d_inode == pseudo_root)
-		pt += (UMSDOS_PSDROOT_LEN + 1);
-	
-	while (1) {
-		struct dentry *dir = dentry_dst, *demd;
-		char *start = pt;
-		int real;
-
-		while (*pt != '\0' && *pt != '/') pt++;
-		len = (int) (pt - start);
-		if (*pt == '/') *pt++ = '\0';
-
-		real = 1;
-		demd = umsdos_get_emd_dentry(dir);
-		if (!IS_ERR(demd)) {
-			if (demd->d_inode)
-				real = 0;
-			dput(demd);
-		}
-
-#ifdef UMSDOS_DEBUG_VERBOSE
-printk ("umsdos_solve_hlink: dir %s/%s, name=%s, real=%d\n",
-dir->d_parent->d_name.name, dir->d_name.name, start, real);
-#endif
-		dentry_dst = umsdos_lookup_dentry(dir, start, len, real);
-/* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
-		if (real)
-			d_drop(dir);
-		dput (dir);
-		if (IS_ERR(dentry_dst))
-			break;
-		/* not found? stop search ... */
-		if (!dentry_dst->d_inode) {
-			break;
-		}
-		if (*pt == '\0')	/* we're finished! */
-			break;
-	} /* end while */
-
-	if (!IS_ERR(dentry_dst)) {
-		struct inode *inode = dentry_dst->d_inode;
-		if (inode) {
-			UMSDOS_I(inode)->i_is_hlink = 1;
-#ifdef UMSDOS_DEBUG_VERBOSE
-printk ("umsdos_solve_hlink: resolved link %s/%s, ino=%ld\n",
-dentry_dst->d_parent->d_name.name, dentry_dst->d_name.name, inode->i_ino);
-#endif
-		} else {
-#ifdef UMSDOS_DEBUG_VERBOSE
-printk ("umsdos_solve_hlink: resolved link %s/%s negative!\n",
-dentry_dst->d_parent->d_name.name, dentry_dst->d_name.name);
-#endif
-		}
-	} else
-		printk(KERN_WARNING
-			"umsdos_solve_hlink: err=%ld\n", PTR_ERR(dentry_dst));
-	kfree (path);
-
-out:
-	dput(hlink);	/* original hlink no longer needed */
-	return dentry_dst;
-
-async_fail:
-	dentry_dst = ERR_PTR(-EIO);
-out_release:
-	page_cache_release(page);
-	goto out;
-}	
-
-
-struct file_operations umsdos_dir_operations =
-{
-	.read		= generic_read_dir,
-	.readdir	= UMSDOS_readdir,
-	.ioctl		= UMSDOS_ioctl_dir,
-};
-
-struct inode_operations umsdos_dir_inode_operations =
-{
-	.create		= UMSDOS_create,
-	.lookup		= UMSDOS_lookup,
-	.link		= UMSDOS_link,
-	.unlink		= UMSDOS_unlink,
-	.symlink	= UMSDOS_symlink,
-	.mkdir		= UMSDOS_mkdir,
-	.rmdir		= UMSDOS_rmdir,
-	.mknod		= UMSDOS_mknod,
-	.rename		= UMSDOS_rename,
-	.setattr	= UMSDOS_notify_change,
-};
diff -Nru a/fs/umsdos/emd.c b/fs/umsdos/emd.c
--- a/fs/umsdos/emd.c	2005-03-01 23:39:16 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,660 +0,0 @@
-/*
- *  linux/fs/umsdos/emd.c
- *
- *  Written 1993 by Jacques Gelinas
- *
- *  Extended MS-DOS directory handling functions
- */
-
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/kernel.h>
-#include <linux/time.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/msdos_fs.h>
-#include <linux/umsdos_fs.h>
-#include <linux/dcache.h>
-#include <linux/pagemap.h>
-#include <linux/delay.h>
-
-void put_entry (struct umsdos_dirent *p, struct umsdos_dirent *q)
-{
-	p->name_len = q->name_len;
-	p->flags = q->flags;
-	p->nlink = cpu_to_le16(q->nlink);
-	p->uid = cpu_to_le16(q->uid);
-	p->gid = cpu_to_le16(q->gid);
-	p->atime = cpu_to_le32(q->atime);
-	p->mtime = cpu_to_le32(q->mtime);
-	p->ctime = cpu_to_le32(q->ctime);
-	p->rdev = cpu_to_le16(q->rdev);
-	p->mode = cpu_to_le16(q->mode);
-}
-
-static void get_entry(struct umsdos_dirent *p, struct umsdos_dirent *q)
-{
-	p->name_len = q->name_len;
-	p->name[p->name_len]='\0';
-	p->flags = q->flags;
-	p->nlink = le16_to_cpu (q->nlink);
-	/* FIXME -- 32bit UID/GID issues */
-	p->uid = le16_to_cpu (q->uid);
-	p->gid = le16_to_cpu (q->gid);
-	p->atime = le32_to_cpu (q->atime);
-	p->mtime = le32_to_cpu (q->mtime);
-	p->ctime = le32_to_cpu (q->ctime);
-	p->rdev = le16_to_cpu (q->rdev);
-	p->mode = le16_to_cpu (q->mode);
-}
-
-/*
- * Lookup the EMD dentry for a directory.
- *
- * Note: the caller must hold a lock on the parent directory.
- */
-struct dentry *umsdos_get_emd_dentry(struct dentry *parent)
-{
-	struct dentry *demd;
-
-	demd = umsdos_lookup_dentry(parent, UMSDOS_EMD_FILE, 
-					UMSDOS_EMD_NAMELEN, 1);
-	return demd;
-}
-
-/*
- * Check whether a directory has an EMD file.
- *
- * Note: the caller must hold a lock on the parent directory.
- */
-int umsdos_have_emd(struct dentry *dir)
-{
-	struct dentry *demd = umsdos_get_emd_dentry (dir);
-	int found = 0;
-
-	if (!IS_ERR(demd)) {
-		if (demd->d_inode)
-			found = 1;
-		dput(demd);
-	}
-	return found;
-}
-
-/*
- * Create the EMD file for a directory if it doesn't
- * already exist. Returns 0 or an error code.
- *
- * Note: the caller must hold a lock on the parent directory.
- */
-int umsdos_make_emd(struct dentry *parent)
-{
-	struct dentry *demd = umsdos_get_emd_dentry(parent);
-	int err = PTR_ERR(demd);
-
-	if (IS_ERR(demd)) {
-		printk("umsdos_make_emd: can't get dentry in %s, err=%d\n",
-			parent->d_name.name, err);
-		goto out;
-	}
-
-	/* already created? */
-	err = 0;
-	if (demd->d_inode)
-		goto out_set;
-
-Printk(("umsdos_make_emd: creating EMD %s/%s\n",
-parent->d_name.name, demd->d_name.name));
-
-	err = msdos_create(parent->d_inode, demd, S_IFREG | 0777, NULL);
-	if (err) {
-		printk (KERN_WARNING
-			"umsdos_make_emd: create %s/%s failed, err=%d\n",
-			parent->d_name.name, demd->d_name.name, err);
-	}
-out_set:
-	dput(demd);
-out:
-	return err;
-}
-
-
-/*
- * Read an entry from the EMD file.
- * Support variable length record.
- * Return -EIO if error, 0 if OK.
- *
- * does not change {d,i}_count
- */
-
-int umsdos_emd_dir_readentry (struct dentry *demd, loff_t *pos, struct umsdos_dirent *entry)
-{
-	struct address_space *mapping = demd->d_inode->i_mapping;
-	struct page *page;
-	struct umsdos_dirent *p;
-	int offs = *pos & ~PAGE_CACHE_MASK;
-	int recsize;
-	int ret = 0;
-
-	page = read_cache_page(mapping, *pos>>PAGE_CACHE_SHIFT,
-			(filler_t*)mapping->a_ops->readpage, NULL);
-	if (IS_ERR(page))
-		goto sync_fail;
-	wait_on_page_locked(page);
-	if (!PageUptodate(page))
-		goto async_fail;
-	p = (struct umsdos_dirent*)(kmap(page)+offs);
-
-	/* if this is an invalid entry (invalid name length), ignore it */
-	if( p->name_len > UMSDOS_MAXNAME )
-	{
-		printk (KERN_WARNING "Ignoring invalid EMD entry with size %d\n", entry->name_len);
-		p->name_len = 0; 
-		ret = -ENAMETOOLONG; /* notify umssync(8) code that something is wrong */
-		/* FIXME: does not work if we did 'ls -l' before 'udosctl uls' ?! */
-	}
-
-	recsize = umsdos_evalrecsize(p->name_len);
-	if (offs + recsize > PAGE_CACHE_SIZE) {
-		struct page *page2;
-		int part = (char *)(page_address(page) + PAGE_CACHE_SIZE) - p->spare;
-		page2 = read_cache_page(mapping, 1+(*pos>>PAGE_CACHE_SHIFT),
-				(filler_t*)mapping->a_ops->readpage, NULL);
-		if (IS_ERR(page2)) {
-			kunmap(page);
-			page_cache_release(page);
-			page = page2;
-			goto sync_fail;
-		}
-		wait_on_page_locked(page2);
-		if (!PageUptodate(page2)) {
-			kunmap(page);
-			page_cache_release(page2);
-			goto async_fail;
-		}
-		memcpy(entry->spare,p->spare,part);
-		memcpy(entry->spare+part,kmap(page2),
-				recsize+offs-PAGE_CACHE_SIZE);
-		kunmap(page2);
-		page_cache_release(page2);
-	} else
-		memcpy(entry->spare,p->spare,((char*)p+recsize)-p->spare);
-	get_entry(entry, p);
-	kunmap(page);
-	page_cache_release(page);
-	*pos += recsize;
-	return ret;
-async_fail:
-	page_cache_release(page);
-	page = ERR_PTR(-EIO);
-sync_fail:
-	return PTR_ERR(page);
-}
-
-
-/*
- * Write an entry in the EMD file.
- * Return 0 if OK, -EIO if some error.
- *
- * Note: the caller must hold a lock on the parent directory.
- */
-int umsdos_writeentry (struct dentry *parent, struct umsdos_info *info,
-				int free_entry)
-{
-	struct inode *dir = parent->d_inode;
-	struct umsdos_dirent *entry = &info->entry;
-	struct dentry *emd_dentry;
-	int ret;
-	struct umsdos_dirent entry0,*p;
-	struct address_space *mapping;
-	struct page *page, *page2 = NULL;
-	int offs;
-
-	emd_dentry = umsdos_get_emd_dentry(parent);
-	ret = PTR_ERR(emd_dentry);
-	if (IS_ERR(emd_dentry))
-		goto out;
-	/* make sure there's an EMD file */
-	ret = -EIO;
-	if (!emd_dentry->d_inode) {
-		printk(KERN_WARNING
-			"umsdos_writeentry: no EMD file in %s/%s\n",
-			parent->d_parent->d_name.name, parent->d_name.name);
-		goto out_dput;
-	}
-
-	if (free_entry) {
-		/* #Specification: EMD file / empty entries
-		 * Unused entries in the EMD file are identified
-		 * by the name_len field equal to 0. However to
-		 * help future extension (or bug correction :-( ),
-		 * empty entries are filled with 0.
-		 */
-		memset (&entry0, 0, sizeof (entry0));
-		entry = &entry0;
-	} else if (entry->name_len > 0) {
-		memset (entry->name + entry->name_len, '\0', 
-			sizeof (entry->name) - entry->name_len);
-		/* #Specification: EMD file / spare bytes
-		 * 10 bytes are unused in each record of the EMD. They
-		 * are set to 0 all the time, so it will be possible
-		 * to do new stuff and rely on the state of those
-		 * bytes in old EMD files.
-		 */
-		memset (entry->spare, 0, sizeof (entry->spare));
-	}
-
-	/* write the entry and update the parent timestamps */
-	mapping = emd_dentry->d_inode->i_mapping;
-	offs = info->f_pos & ~PAGE_CACHE_MASK;
-	ret = -ENOMEM;
-	page = grab_cache_page(mapping, info->f_pos>>PAGE_CACHE_SHIFT);
-	if (!page)
-		goto out_dput;
-	p = (struct umsdos_dirent *) (page_address(page) + offs);
-	if (offs + info->recsize > PAGE_CACHE_SIZE) {
-		ret = mapping->a_ops->prepare_write(NULL,page,offs,
-					PAGE_CACHE_SIZE);
-		if (ret)
-			goto out_unlock;
-		page2 = grab_cache_page(mapping,
-					(info->f_pos>>PAGE_CACHE_SHIFT)+1);
-		if (!page2)
-			goto out_unlock2;
-		ret = mapping->a_ops->prepare_write(NULL,page2,0,
-					offs+info->recsize-PAGE_CACHE_SIZE);
-		if (ret)
-			goto out_unlock3;
-		put_entry (p, entry);
-		memcpy(p->spare,entry->spare,
-			(char *)(page_address(page) + PAGE_CACHE_SIZE) - p->spare);
-		memcpy(page_address(page2),
-				((char*)entry)+PAGE_CACHE_SIZE-offs,
-				offs+info->recsize-PAGE_CACHE_SIZE);
-		ret = mapping->a_ops->commit_write(NULL,page2,0,
-					offs+info->recsize-PAGE_CACHE_SIZE);
-		if (ret)
-			goto out_unlock3;
-		ret = mapping->a_ops->commit_write(NULL,page,offs,
-					PAGE_CACHE_SIZE);
-		unlock_page(page2);
-		page_cache_release(page2);
-		if (ret)
-			goto out_unlock;
-	} else {
-		ret = mapping->a_ops->prepare_write(NULL,page,offs,
-					offs + info->recsize);
-		if (ret)
-			goto out_unlock;
-		put_entry (p, entry);
-		memcpy(p->spare,entry->spare,((char*)p+info->recsize)-p->spare);
-		ret = mapping->a_ops->commit_write(NULL,page,offs,
-					offs + info->recsize);
-		if (ret)
-			goto out_unlock;
-	}
-	unlock_page(page);
-	page_cache_release(page);
-		
-	dir->i_ctime = dir->i_mtime = CURRENT_TIME;
-	mark_inode_dirty(dir);
-
-out_dput:
-	dput(emd_dentry);
-out:
-	Printk (("umsdos_writeentry /mn/: returning %d...\n", ret));
-	return ret;
-out_unlock3:
-	unlock_page(page2);
-	page_cache_release(page2);
-out_unlock2:
-	ClearPageUptodate(page);
-	kunmap(page);
-out_unlock:
-	unlock_page(page);
-	page_cache_release(page);
-	printk ("UMSDOS:  problem with EMD file:  can't write\n");
-	goto out_dput;
-}
-
-/*
- * General search, locate a name in the EMD file or an empty slot to
- * store it. if info->entry.name_len == 0, search the first empty
- * slot (of the proper size).
- * 
- * Return 0 if found, -ENOENT if not found, another error code if
- * other problem.
- * 
- * So this routine is used to either find an existing entry or to
- * create a new one, while making sure it is a new one. After you
- * get -ENOENT, you make sure the entry is stuffed correctly and
- * call umsdos_writeentry().
- * 
- * To delete an entry, you find it, zero out the entry (memset)
- * and call umsdos_writeentry().
- * 
- * All this to say that umsdos_writeentry must be called after this
- * function since it relies on the f_pos field of info.
- *
- * Note: the caller must hold a lock on the parent directory.
- */
-/* #Specification: EMD file structure
- * The EMD file uses a fairly simple layout.  It is made of records
- * (UMSDOS_REC_SIZE == 64).  When a name can't be written in a single
- * record, multiple contiguous records are allocated.
- */
-
-static int umsdos_find (struct dentry *demd, struct umsdos_info *info)
-{
-	struct umsdos_dirent *entry = &info->entry;
-	int recsize = info->recsize;
-	struct inode *emd_dir;
-	int ret = -ENOENT;
-	struct {
-		off_t posok;	/* Position available to store the entry */
-		off_t one;	/* One empty position -> maybe <- large enough */
-	} empty;
-	int found = 0;
-	int empty_size = 0;
-	struct address_space *mapping;
-	filler_t *readpage;
-	struct page *page = NULL;
-	int index = -1;
-	int offs = PAGE_CACHE_SIZE,max_offs = PAGE_CACHE_SIZE;
-	char *p = NULL;
-	loff_t pos = 0;
-
-	/* make sure there's an EMD file ... */
-	ret = -ENOENT;
-	emd_dir = demd->d_inode;
-	if (!emd_dir)
-		goto out_dput;
-	mapping = emd_dir->i_mapping;
-	readpage = (filler_t*)mapping->a_ops->readpage;
-
-	empty.posok = emd_dir->i_size;
-	while (1) {
-		struct umsdos_dirent *rentry;
-		int entry_size;
-
-		if (offs >= max_offs) {
-			if (page) {
-				kunmap(page);
-				page_cache_release(page);
-				page = NULL;
-			}
-			if (pos >= emd_dir->i_size) {
-				info->f_pos = empty.posok;
-				break;
-			}
-			if (++index == (emd_dir->i_size>>PAGE_CACHE_SHIFT))
-				max_offs = emd_dir->i_size & ~PAGE_CACHE_MASK;
-			offs -= PAGE_CACHE_SIZE;
-			page = read_cache_page(mapping,index,readpage,NULL);
-			if (IS_ERR(page))
-				goto sync_fail;
-			wait_on_page_locked(page);
-			if (!PageUptodate(page))
-				goto async_fail;
-			p = kmap(page);
-		}
-
-		rentry = (struct umsdos_dirent *)(p+offs);
-
-		if (rentry->name_len == 0) {
-			/* We are looking for an empty section at least */
-			/* as large as recsize. */
-			if (entry->name_len == 0) {
-				info->f_pos = pos;
-				ret = 0;
-				break;
-			}
-			offs += UMSDOS_REC_SIZE;
-			pos += UMSDOS_REC_SIZE;
-			if (found)
-				continue;
-			if (!empty_size)
-				empty.one = pos-UMSDOS_REC_SIZE;
-			empty_size += UMSDOS_REC_SIZE;
-			if (empty_size == recsize) {
-				/* Here is a large enough section. */
-				empty.posok = empty.one;
-				found = 1;
-			}
-			continue;
-		}
-
-		entry_size = umsdos_evalrecsize(rentry->name_len);
-		if (entry_size > PAGE_CACHE_SIZE)
-			goto async_fail;
-		empty_size = 0;
-		if (entry->name_len != rentry->name_len)
-			goto skip_it;
-
-		if (entry_size + offs > PAGE_CACHE_SIZE) {
-			/* Sucker spans the page boundary */
-			int len = (p+PAGE_CACHE_SIZE)-rentry->name;
-			struct page *next_page;
-			char *q;
-			next_page = read_cache_page(mapping,index+1,readpage,NULL);
-			if (IS_ERR(next_page)) {
-				page_cache_release(page);
-				page = next_page;
-				goto sync_fail;
-			}
-			wait_on_page_locked(next_page);
-			if (!PageUptodate(next_page)) {
-				page_cache_release(page);
-				page = next_page;
-				goto async_fail;
-			}
-			q = kmap(next_page);
-			if (memcmp(entry->name, rentry->name, len) ||
-			    memcmp(entry->name+len, q, entry->name_len-len)) {
-				kunmap(next_page);
-				page_cache_release(next_page);
-				goto skip_it;
-			}
-			kunmap(next_page);
-			page_cache_release(next_page);
-		} else if (memcmp (entry->name, rentry->name, entry->name_len))
-			goto skip_it;
-
-		info->f_pos = pos;
-		get_entry(entry, rentry);
-		ret = 0;
-		break;
-skip_it:
-		offs+=entry_size;
-		pos+=entry_size;
-	}
-	if (page) {
-		kunmap(page);
-		page_cache_release(page);
-	}
-	umsdos_manglename (info);
-
-out_dput:
-	dput(demd);
-	return ret;
-
-async_fail:
-	page_cache_release(page);
-	page = ERR_PTR(-EIO);
-sync_fail:
-	return PTR_ERR(page);
-}
-
-
-/*
- * Add a new entry in the EMD file.
- * Return 0 if OK or a negative error code.
- * Return -EEXIST if the entry already exists.
- *
- * Complete the information missing in info.
- * 
- * N.B. What if the EMD file doesn't exist?
- */
-
-int umsdos_newentry (struct dentry *parent, struct umsdos_info *info)
-{
-	int err, ret = -EEXIST;
-	struct dentry *demd = umsdos_get_emd_dentry(parent);
-
-	ret = PTR_ERR(demd);
-	if (IS_ERR(demd))
-		goto out;
-	err = umsdos_find (demd, info);
-	if (err && err == -ENOENT) {
-		ret = umsdos_writeentry (parent, info, 0);
-		Printk (("umsdos_writeentry EMD ret = %d\n", ret));
-	}
-out:
-	return ret;
-}
-
-
-/*
- * Create a new hidden link.
- * Return 0 if OK, an error code if not.
- */
-
-/* #Specification: hard link / hidden name
- * When a hard link is created, the original file is renamed
- * to a hidden name. The name is "..LINKNNN" where NNN is a
- * number define from the entry offset in the EMD file.
- */
-int umsdos_newhidden (struct dentry *parent, struct umsdos_info *info)
-{
-	int ret;
-	struct dentry *demd = umsdos_get_emd_dentry(parent);
-	ret = PTR_ERR(demd);
-	if (IS_ERR(demd))
-		goto out;
-
-	umsdos_parse ("..LINK", 6, info);
-	info->entry.name_len = 0;
-	ret = umsdos_find (demd, info);
-	if (ret == -ENOENT || ret == 0) {
-		info->entry.name_len = sprintf (info->entry.name,
-						"..LINK%ld", info->f_pos);
-		ret = 0;
-	}
-out:
-	return ret;
-}
-
-
-/*
- * Remove an entry from the EMD file.
- * Return 0 if OK, a negative error code otherwise.
- * 
- * Complete the information missing in info.
- */
-
-int umsdos_delentry (struct dentry *parent, struct umsdos_info *info, int isdir)
-{
-	int ret;
-	struct dentry *demd = umsdos_get_emd_dentry(parent);
-
-	ret = PTR_ERR(demd);
-	if (IS_ERR(demd))
-		goto out;
-	ret = umsdos_find (demd, info);
-	if (ret)
-		goto out;
-	if (info->entry.name_len == 0)
-		goto out;
-
-	if ((isdir != 0) != (S_ISDIR (info->entry.mode) != 0)) {
-		if (S_ISDIR (info->entry.mode)) {
-			ret = -EISDIR;
-		} else {
-			ret = -ENOTDIR;
-		}
-		goto out;
-	}
-	ret = umsdos_writeentry (parent, info, 1);
-
-out:
-	return ret;
-}
-
-
-/*
- * Verify that an EMD directory is empty.
- * Return: 
- * 0 if not empty,
- * 1 if empty (except for EMD file),
- * 2 if empty or no EMD file.
- */
-
-int umsdos_isempty (struct dentry *dentry)
-{
-	struct dentry *demd;
-	int ret = 2;
-	loff_t pos = 0;
-
-	demd = umsdos_get_emd_dentry(dentry);
-	if (IS_ERR(demd))
-		goto out;
-	/* If the EMD file does not exist, it is certainly empty. :-) */
-	if (!demd->d_inode)
-		goto out_dput;
-
-	ret = 1;
-	while (pos < demd->d_inode->i_size) {
-		struct umsdos_dirent entry;
-
-		if (umsdos_emd_dir_readentry (demd, &pos, &entry) != 0) {
-			ret = 0;
-			break;
-		}
-		if (entry.name_len != 0) {
-			ret = 0;
-			break;
-		}
-	}
-
-out_dput:
-	dput(demd);
-out:
-	return ret;
-}
-
-/*
- * Locate an entry in a EMD directory.
- * Return 0 if OK, error code if not, generally -ENOENT.
- *
- * expect argument:
- * 	0: anything
- * 	1: file
- * 	2: directory
- */
-
-int umsdos_findentry (struct dentry *parent, struct umsdos_info *info,
-			int expect)
-{		
-	int ret;
-	struct dentry *demd = umsdos_get_emd_dentry(parent);
-
-	ret = PTR_ERR(demd);
-	if (IS_ERR(demd))
-		goto out;
-	ret = umsdos_find (demd, info);
-	if (ret)
-		goto out;
-
-	switch (expect) {
-	case 1:
-		if (S_ISDIR (info->entry.mode))
-			ret = -EISDIR;
-		break;
-	case 2:
-		if (!S_ISDIR (info->entry.mode))
-			ret = -ENOTDIR;
-	}
-
-out:
-	Printk (("umsdos_findentry: returning %d\n", ret));
-	return ret;
-}
diff -Nru a/fs/umsdos/inode.c b/fs/umsdos/inode.c
--- a/fs/umsdos/inode.c	2005-03-01 23:38:52 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,483 +0,0 @@
-/*
- *  linux/fs/umsdos/inode.c
- *
- *      Written 1993 by Jacques Gelinas
- *      Inspired from linux/fs/msdos/... by Werner Almesberger
- */
-
-#include <linux/module.h>
-
-#include <linux/init.h>
-#include <linux/fs.h>
-#include <linux/msdos_fs.h>
-#include <linux/kernel.h>
-#include <linux/time.h>
-#include <linux/errno.h>
-#include <asm/uaccess.h>
-#include <linux/string.h>
-#include <linux/stat.h>
-#include <linux/umsdos_fs.h>
-#include <linux/list.h>
-#include <linux/pagemap.h>
-
-extern struct dentry_operations umsdos_dentry_operations;
-
-struct dentry *saved_root;	/* Original root if changed */
-struct inode *pseudo_root;	/* Useful to simulate the pseudo DOS */
-					/* directory. See UMSDOS_readdir_x() */
-
-static struct dentry *check_pseudo_root(struct super_block *);
-
-
-void UMSDOS_put_inode (struct inode *inode)
-{
-	PRINTK ((KERN_DEBUG 
-		"put inode %p (%lu) pos %lu count=%d\n"
-		 ,inode, inode->i_ino
-		 ,UMSDOS_I(inode)->pos
-		 ,atomic_read(&inode->i_count)));
-
-	if (inode == pseudo_root) {
-		Printk ((KERN_ERR "Umsdos: debug: releasing pseudo_root - ino=%lu count=%d\n", inode->i_ino, atomic_read(&inode->i_count)));
-	}
-
-	if (atomic_read(&inode->i_count) == 1)
-		UMSDOS_I(inode)->i_patched = 0;
-}
-
-
-void UMSDOS_put_super (struct super_block *sb)
-{
-	Printk ((KERN_DEBUG "UMSDOS_put_super: entering\n"));
-	if (saved_root && pseudo_root && kdev_same(sb->s_dev, ROOT_DEV)) {
-		shrink_dcache_parent(saved_root);
-		dput(saved_root);
-		saved_root = NULL;
-		pseudo_root = NULL;
-	}
-	fat_put_super (sb);
-}
-
-
-/*
- * Complete the setup of a directory dentry based on its
- * EMD/non-EMD status.  If it has an EMD, then plug the
- * umsdos function table. If not, use the msdos one.
- */
-void umsdos_setup_dir(struct dentry *dir)
-{
-	struct inode *inode = dir->d_inode;
-	struct umsdos_inode_info *ui = UMSDOS_I(inode);
-
-	if (!S_ISDIR(inode->i_mode))
-		printk(KERN_ERR "umsdos_setup_dir: %s/%s not a dir!\n",
-			dir->d_parent->d_name.name, dir->d_name.name);
-
-	init_waitqueue_head (&ui->dir_info.p);
-	ui->dir_info.looking = 0;
-	ui->dir_info.creating = 0;
-	ui->dir_info.pid = 0;
-
-	inode->i_op = &umsdos_rdir_inode_operations;
-	inode->i_fop = &umsdos_rdir_operations;
-	if (umsdos_have_emd(dir)) {
-Printk((KERN_DEBUG "umsdos_setup_dir: %s/%s using EMD\n",
-dir->d_parent->d_name.name, dir->d_name.name));
-		inode->i_op = &umsdos_dir_inode_operations;
-		inode->i_fop = &umsdos_dir_operations;
-	}
-}
-
-
-/*
- * Add some info into an inode so it can find its owner quickly
- */
-void umsdos_set_dirinfo_new (struct dentry *dentry, off_t f_pos)
-{
-	struct inode *inode = dentry->d_inode;
-	struct dentry *demd;
-
-	UMSDOS_I(inode)->pos = f_pos;
-
-	/* now check the EMD file */
-	demd = umsdos_get_emd_dentry(dentry->d_parent);
-	if (!IS_ERR(demd)) {
-		dput(demd);
-	}
-	return;
-}
-
-static struct inode_operations umsdos_file_inode_operations = {
-	.truncate	= fat_truncate,
-	.setattr	= UMSDOS_notify_change,
-};
-
-static struct inode_operations umsdos_symlink_inode_operations = {
-	.readlink	= page_readlink,
-	.follow_link	= page_follow_link,
-	.setattr	= UMSDOS_notify_change,
-};
-
-/*
- * Connect the proper tables in the inode and add some info.
- */
-/* #Specification: inode / umsdos info
- * The first time an inode is seen (inode->i_count == 1),
- * the inode number of the EMD file which controls this inode
- * is tagged to this inode. It allows operations such as
- * notify_change to be handled.
- */
-void umsdos_patch_dentry_inode(struct dentry *dentry, off_t f_pos)
-{
-	struct inode *inode = dentry->d_inode;
-
-PRINTK (("umsdos_patch_dentry_inode: inode=%lu\n", inode->i_ino));
-
-	/*
-	 * Classify the inode based on EMD/non-EMD status.
-	 */
-PRINTK (("umsdos_patch_inode: call umsdos_set_dirinfo_new(%p,%lu)\n",
-dentry, f_pos));
-	umsdos_set_dirinfo_new(dentry, f_pos);
-
-	inode->i_op = &umsdos_file_inode_operations;
-	if (S_ISREG (inode->i_mode)) {
-		/* address_space operations already set */
-	} else if (S_ISDIR (inode->i_mode)) {
-		umsdos_setup_dir(dentry);
-	} else if (S_ISLNK (inode->i_mode)) {
-		/* address_space operations already set */
-		inode->i_op = &umsdos_symlink_inode_operations;
-	} else
-		init_special_inode(inode, inode->i_mode,
-					kdev_t_to_nr(inode->i_rdev));
-}
-
-
-/*
- * lock the parent dir before starting ...
- * also handles hardlink converting
- */
-int UMSDOS_notify_change (struct dentry *dentry, struct iattr *attr)
-{
-	struct inode *dir, *inode;
-	struct umsdos_info info;
-	struct dentry *temp, *old_dentry = NULL;
-	int ret;
-
-	lock_kernel();
-
-	ret = umsdos_parse (dentry->d_name.name, dentry->d_name.len,
-				&info);
-	if (ret)
-		goto out;
-	ret = umsdos_findentry (dentry->d_parent, &info, 0);
-	if (ret) {
-printk("UMSDOS_notify_change: %s/%s not in EMD, ret=%d\n",
-dentry->d_parent->d_name.name, dentry->d_name.name, ret);
-		goto out;
-	}
-
-	if (info.entry.flags & UMSDOS_HLINK) {
-		/*
-		 * In order to get the correct (real) inode, we just drop
-		 * the original dentry.
-		 */ 
-		d_drop(dentry);
-Printk(("UMSDOS_notify_change: hard link %s/%s, fake=%s\n",
-dentry->d_parent->d_name.name, dentry->d_name.name, info.fake.fname));
-	
-		/* Do a real lookup to get the short name dentry */
-		temp = umsdos_covered(dentry->d_parent, info.fake.fname,
-						info.fake.len);
-		ret = PTR_ERR(temp);
-		if (IS_ERR(temp))
-			goto out;
-	
-		/* now resolve the link ... */
-		temp = umsdos_solve_hlink(temp);
-		ret = PTR_ERR(temp);
-		if (IS_ERR(temp))
-			goto out;
-		old_dentry = dentry;
-		dentry = temp;	/* so umsdos_notify_change_locked will operate on that */
-	}
-
-	dir = dentry->d_parent->d_inode;
-	inode = dentry->d_inode;
-
-	ret = inode_change_ok (inode, attr);
-	if (ret)
-		goto out;
-
-	ret = umsdos_notify_change_locked(dentry, attr);
-	if (ret == 0)
-		ret = inode_setattr (inode, attr);
-out:
-	if (old_dentry)
-		dput (dentry);	/* if we had to use fake dentry for hardlinks, dput() it now */
-	unlock_kernel();
-	return ret;
-}
-
-
-/*
- * Must be called with the parent lock held.
- */
-int umsdos_notify_change_locked(struct dentry *dentry, struct iattr *attr)
-{
-	struct inode *inode = dentry->d_inode;
-	struct dentry *demd;
-	struct address_space *mapping;
-	struct page *page;
-	int ret = 0;
-	struct umsdos_dirent *entry;
-	int offs;
-
-Printk(("UMSDOS_notify_change: entering for %s/%s (%d)\n",
-dentry->d_parent->d_name.name, dentry->d_name.name, UMSDOS_I(inode)->i_patched));
-
-	if (inode->i_nlink == 0)
-		goto out;
-	if (inode->i_ino == UMSDOS_ROOT_INO)
-		goto out;
-
-	/* get the EMD file dentry */
-	demd = umsdos_get_emd_dentry(dentry->d_parent);
-	ret = PTR_ERR(demd);
-	if (IS_ERR(demd))
-		goto out;
-	ret = 0;
-	/* don't do anything if directory is not promoted to umsdos yet */
-	if (!demd->d_inode) { 
-		Printk((KERN_DEBUG
-			"UMSDOS_notify_change: no EMD file %s/%s\n",
-			demd->d_parent->d_name.name, demd->d_name.name));
-		goto out_dput;
-	}
-
-	/* don't do anything if this is the EMD itself */
-	if (inode == demd->d_inode)
-		goto out_dput;
-
-	/* This inode is not a EMD file nor an inode used internally
-	 * by MSDOS, so we can update its status.
-	 * See emd.c
-	 */
-
-	/* Read only the start of the entry since we don't touch the name */
-	mapping = demd->d_inode->i_mapping;
-	offs = UMSDOS_I(inode)->pos & ~PAGE_CACHE_MASK;
-	ret = -ENOMEM;
-	page=grab_cache_page(mapping,UMSDOS_I(inode)->pos>>PAGE_CACHE_SHIFT);
-	if (!page)
-		goto out_dput;
-	ret=mapping->a_ops->prepare_write(NULL,page,offs,offs+UMSDOS_REC_SIZE);
-	if (ret)
-		goto out_unlock;
-	entry = (struct umsdos_dirent *) (page_address(page) + offs);
-	if (attr->ia_valid & ATTR_UID)
-		entry->uid = cpu_to_le16(attr->ia_uid);
-	if (attr->ia_valid & ATTR_GID)
-		entry->gid = cpu_to_le16(attr->ia_gid);
-	if (attr->ia_valid & ATTR_MODE)
-		entry->mode = cpu_to_le16(attr->ia_mode);
-	if (attr->ia_valid & ATTR_ATIME)
-		entry->atime = cpu_to_le32(attr->ia_atime);
-	if (attr->ia_valid & ATTR_MTIME)
-		entry->mtime = cpu_to_le32(attr->ia_mtime);
-	if (attr->ia_valid & ATTR_CTIME)
-		entry->ctime = cpu_to_le32(attr->ia_ctime);
-	entry->nlink = cpu_to_le16(inode->i_nlink);
-	ret=mapping->a_ops->commit_write(NULL,page,offs,offs+UMSDOS_REC_SIZE);
-	if (ret)
-		printk(KERN_WARNING
-			"umsdos_notify_change: %s/%s EMD write error, ret=%d\n",
-			dentry->d_parent->d_name.name, dentry->d_name.name,ret);
-
-	/* #Specification: notify_change / msdos fs
-	 * notify_change operation are done only on the
-	 * EMD file. The msdos fs is not even called.
-	 */
-out_unlock:
-	unlock_page(page);
-	page_cache_release(page);
-out_dput:
-	dput(demd);
-out:
-	return ret;
-}
-
-
-/*
- * Update the disk with the inode content
- */
-int UMSDOS_write_inode (struct inode *inode, int wait)
-{
-	struct iattr newattrs;
-	int ret;
-
-	ret = fat_write_inode (inode, wait);
-	newattrs.ia_mtime = inode->i_mtime;
-	newattrs.ia_atime = inode->i_atime;
-	newattrs.ia_ctime = inode->i_ctime;
-	newattrs.ia_valid = ATTR_MTIME | ATTR_ATIME | ATTR_CTIME;
-	/*
-	 * UMSDOS_notify_change is convenient to call here
-	 * to update the EMD entry associated with this inode.
-	 * But it has the side effect to re"dirt" the inode.
-	 */
-/*      
- * UMSDOS_notify_change (inode, &newattrs);
-
- * inode->i_state &= ~I_DIRTY; / * FIXME: this doesn't work.  We need to remove ourselves from list on dirty inodes. /mn/ */
-	return ret;
-}
-
-
-static struct super_operations umsdos_sops =
-{
-	.write_inode	= UMSDOS_write_inode,
-	.put_inode	= UMSDOS_put_inode,
-	.delete_inode	= fat_delete_inode,
-	.put_super	= UMSDOS_put_super,
-	.statfs		= UMSDOS_statfs,
-	.clear_inode	= fat_clear_inode,
-};
-
-int UMSDOS_statfs(struct super_block *sb,struct statfs *buf)
-{
-	int ret;
-	ret = fat_statfs (sb, buf);
-	if (!ret)	
-		buf->f_namelen = UMSDOS_MAXNAME;
-	return ret;
-}
-
-/*
- * Read the super block of an Extended MS-DOS FS.
- */
-struct super_block *UMSDOS_read_super (struct super_block *sb, void *data,
-				      int silent)
-{
-	struct super_block *res;
-	struct dentry *new_root;
-
-	/*
-	 * Call msdos-fs to mount the disk.
-	 * Note: this returns res == sb or NULL
-	 */
-	MSDOS_SB(sb)->options.isvfat = 0;
-	res = fat_read_super(sb, data, silent, &umsdos_rdir_inode_operations);
-
-	if (IS_ERR(res))
-		return NULL;
-	if (res == NULL) {
-		if (!silent)
-			printk(KERN_INFO "VFS: Can't find a valid "
-			       "UMSDOS filesystem on dev %s.\n", sb->s_id);
-		return NULL;
-	}
-
-	printk (KERN_INFO "UMSDOS 0.86k "
-		"(compatibility level %d.%d, fast msdos)\n", 
-		UMSDOS_VERSION, UMSDOS_RELEASE);
-
-	sb->s_op = &umsdos_sops;
-	MSDOS_SB(sb)->options.dotsOK = 0;	/* disable hidden==dotfile */
-
-	/* install our dentry operations ... */
-	sb->s_root->d_op = &umsdos_dentry_operations;
-
-	umsdos_patch_dentry_inode(sb->s_root, 0);
-
-	/* Check whether to change to the /linux root */
-	new_root = check_pseudo_root(sb);
-
-	if (new_root) {
-		/* sanity check */
-		if (new_root->d_op != &umsdos_dentry_operations)
-			printk("umsdos_read_super: pseudo-root wrong ops!\n");
-
-		pseudo_root = new_root->d_inode;
-		saved_root = sb->s_root;
-		printk(KERN_INFO "UMSDOS: changed to alternate root\n");
-		dget (sb->s_root); sb->s_root = dget(new_root);
-	}
-	return sb;
-}
-
-/*
- * Check for an alternate root if we're the root device.
- */
-
-extern kdev_t ROOT_DEV;
-static struct dentry *check_pseudo_root(struct super_block *sb)
-{
-	struct dentry *root, *sbin, *init;
-
-	/*
-	 * Check whether we're mounted as the root device.
-	 * must check like this, because we can be used with initrd
-	 */
-		
-	if (!kdev_same(sb->s_dev, ROOT_DEV))
-		goto out_noroot;
-
-	/* 
-	 * lookup_dentry needs a (so far non-existent) root. 
-	 */
-	printk(KERN_INFO "check_pseudo_root: mounted as root\n");
-	root = lookup_one_len(UMSDOS_PSDROOT_NAME, sb->s_root,UMSDOS_PSDROOT_LEN); 
-	if (IS_ERR(root))
-		goto out_noroot;
-		
-	if (!root->d_inode || !S_ISDIR(root->d_inode->i_mode))
-		goto out_dput;
-
-printk(KERN_INFO "check_pseudo_root: found %s/%s\n",
-root->d_parent->d_name.name, root->d_name.name);
-
-	/* look for /sbin/init */
-	sbin = lookup_one_len("sbin", root, 4);
-	if (IS_ERR(sbin))
-		goto out_dput;
-	if (!sbin->d_inode || !S_ISDIR(sbin->d_inode->i_mode))
-		goto out_dput_sbin;
-	init = lookup_one_len("init", sbin, 4);
-	if (IS_ERR(init))
-		goto out_dput_sbin;
-	if (!init->d_inode)
-		goto out_dput_init;
-	printk(KERN_INFO "check_pseudo_root: found %s/%s, enabling pseudo-root\n", init->d_parent->d_name.name, init->d_name.name);
-	dput(sbin);
-	dput(init);
-	return root;
-
-	/* Alternate root not found ... */
-out_dput_init:
-	dput(init);
-out_dput_sbin:
-	dput(sbin);
-out_dput:
-	dput(root);
-out_noroot:
-	return NULL;
-}
-
-
-static DECLARE_FSTYPE_DEV(umsdos_fs_type, "umsdos", UMSDOS_read_super);
-
-static int __init init_umsdos_fs (void)
-{
-	return register_filesystem (&umsdos_fs_type);
-}
-
-static void __exit exit_umsdos_fs (void)
-{
-	unregister_filesystem (&umsdos_fs_type);
-}
-
-module_init(init_umsdos_fs)
-module_exit(exit_umsdos_fs)
-MODULE_LICENSE("GPL");
diff -Nru a/fs/umsdos/ioctl.c b/fs/umsdos/ioctl.c
--- a/fs/umsdos/ioctl.c	2005-03-01 23:38:52 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,446 +0,0 @@
-/*
- *  linux/fs/umsdos/ioctl.c
- *
- *  Written 1993 by Jacques Gelinas
- *
- *  Extended MS-DOS ioctl directory handling functions
- *
- *  Changes:
- *  11/07/2003      Daniele Bellucci <bellucda@tiscali.it>
- *                  - audit copy_to_user/put_user in umsdos_ioctl_fill.
- */
-
-#include <asm/uaccess.h>
-#include <linux/errno.h>
-#include <linux/mm.h>
-#include <linux/kernel.h>
-#include <linux/time.h>
-#include <linux/fs.h>
-#include <linux/msdos_fs.h>
-#include <linux/umsdos_fs.h>
-
-struct UMSDOS_DIR_ONCE {
-	struct dirent *ent;
-	int count;
-};
-
-/*
- * Record a single entry the first call.
- * Return -EINVAL the next one.
- */
-static int umsdos_ioctl_fill (
-				     void *buf,
-				     const char *name,
-				     int name_len,
-				     loff_t offset,
-				     ino_t ino,
-				     unsigned type)
-{
-	int ret = -EINVAL;
-	struct UMSDOS_DIR_ONCE *d = (struct UMSDOS_DIR_ONCE *) buf;
-
-	if (d->count == 0) {
-		if (copy_to_user (d->ent->d_name, name, name_len) ||
-		    put_user ('\0', d->ent->d_name + name_len) ||
-		    put_user (name_len, &d->ent->d_reclen) ||
-		    put_user (ino, &d->ent->d_ino) ||
-		    put_user (offset, &d->ent->d_off))
-			return -EFAULT;
-		d->count = 1;
-		ret = 0;
-	}
-	return ret;
-}
-
-
-/*
- * Perform special function on a directory
- */
-/* #Specification: ioctl / prototypes
- * The official prototype for the umsdos ioctl on directory
- * is:
- * 
- * int ioctl (
- * int fd,          // File handle of the directory
- * int cmd, // command
- * struct umsdos_ioctl *data)
- * 
- * The struct and the commands are defined in linux/umsdos_fs.h.
- * 
- * umsdos_progs/umsdosio.c provide an interface in C++ to all
- * these ioctl. umsdos_progs/udosctl is a small utility showing
- * all this.
- * 
- * These ioctl generally allow one to work on the EMD or the
- * DOS directory independently. These are essential to implement
- * the synchronise.
- */
-int UMSDOS_ioctl_dir(struct inode *dir, struct file *filp, unsigned int cmd,
-			unsigned long data_ptr)
-{
-	struct dentry *dentry = filp->f_dentry;
-	struct umsdos_ioctl *idata = (struct umsdos_ioctl *) data_ptr;
-	int ret;
-	struct umsdos_ioctl data;
-
-Printk(("UMSDOS_ioctl_dir: %s/%s, cmd=%d, data=%08lx\n",
-dentry->d_parent->d_name.name, dentry->d_name.name, cmd, data_ptr));
-
-	/* forward non-umsdos ioctls - this hopefully doesn't cause conflicts */
-	if (cmd != UMSDOS_GETVERSION
-	    && cmd != UMSDOS_READDIR_DOS
-	    && cmd != UMSDOS_READDIR_EMD
-	    && cmd != UMSDOS_INIT_EMD
-	    && cmd != UMSDOS_CREAT_EMD
-	    && cmd != UMSDOS_RENAME_DOS
-	    && cmd != UMSDOS_UNLINK_EMD
-	    && cmd != UMSDOS_UNLINK_DOS
-	    && cmd != UMSDOS_RMDIR_DOS
-	    && cmd != UMSDOS_STAT_DOS
-	    && cmd != UMSDOS_DOS_SETUP)
-		return fat_dir_ioctl (dir, filp, cmd, data_ptr);
-
-	/* #Specification: ioctl / access
-	 * Only root (effective id) is allowed to do IOCTL on directory
-	 * in UMSDOS. EPERM is returned for other user.
-	 */
-	/*
-	 * Well, not all cases require write access, but it simplifies
-	 * the code, and let's face it, there is only one client (umssync)
-	 * for all this.
-	 */
-	ret = verify_area (VERIFY_WRITE, (void *) data_ptr, 
-				sizeof (struct umsdos_ioctl));
-	if (ret < 0)
-		goto out;
-
-	ret = -EPERM;
-	if (current->euid != 0 && cmd != UMSDOS_GETVERSION)
-		goto out;
-
-	ret = -EINVAL;
-	if (cmd == UMSDOS_GETVERSION) {
-		/* #Specification: ioctl / UMSDOS_GETVERSION
-		 * The field version and release of the structure
-		 * umsdos_ioctl are filled with the version and release
-		 * number of the fs code in the kernel. This will allow
-		 * some form of checking. Users won't be able to run
-		 * incompatible utility such as the synchroniser (umssync).
-		 * umsdos_progs/umsdosio.c enforce this checking.
-		 * 
-		 * Return always 0.
-		 */
-		put_user (UMSDOS_VERSION, &idata->version);
-		put_user (UMSDOS_RELEASE, &idata->release);
-		ret = 0;
-		goto out;
-	}
-	if (cmd == UMSDOS_READDIR_DOS) {
-		/* #Specification: ioctl / UMSDOS_READDIR_DOS
-		 * One entry is read from the DOS directory at the current
-		 * file position. The entry is put as is in the dos_dirent
-		 * field of struct umsdos_ioctl.
-		 * 
-		 * Return > 0 if success.
-		 */
-		struct UMSDOS_DIR_ONCE bufk;
-
-		bufk.count = 0;
-		bufk.ent = &idata->dos_dirent;
-
-		fat_readdir (filp, &bufk, umsdos_ioctl_fill);
-
-		ret = bufk.count == 1 ? 1 : 0;
-		goto out;
-	}
-	if (cmd == UMSDOS_READDIR_EMD) {
-		/* #Specification: ioctl / UMSDOS_READDIR_EMD
-		 * One entry is read from the EMD at the current
-		 * file position. The entry is put as is in the umsdos_dirent
-		 * field of struct umsdos_ioctl. The corresponding mangled
-		 * DOS entry name is put in the dos_dirent field.
-		 * 
-		 * All entries are read including hidden links. Blank
-		 * entries are skipped.
-		 * 
-		 * Return > 0 if success.
-		 */
-		struct dentry *demd;
-		loff_t pos = filp->f_pos;
-
-		/* The absence of the EMD is simply seen as an EOF */
-		demd = umsdos_get_emd_dentry(dentry);
-		ret = PTR_ERR(demd);
-		if (IS_ERR(demd))
-			goto out;
-		ret = 0;
-		if (!demd->d_inode)
-			goto read_dput;
-
-		while (pos < demd->d_inode->i_size) {
-			off_t f_pos = pos;
-			struct umsdos_dirent entry;
-			struct umsdos_info info;
-
-			ret = umsdos_emd_dir_readentry (demd, &pos, &entry);
-
-			if (ret == -ENAMETOOLONG) {
-				printk (KERN_INFO "Fixing EMD entry with invalid size -- zeroing out\n");
-				memset (&info, 0, sizeof (info));
-				info.f_pos = f_pos;
-				info.recsize = UMSDOS_REC_SIZE;
-				ret = umsdos_writeentry (dentry, &info, 1);
-				continue;
-			}
-
-			if (ret)
-				break;
-			if (entry.name_len <= 0)
-				continue;
-
-			umsdos_parse (entry.name, entry.name_len, &info);
-			info.f_pos = f_pos;
-			umsdos_manglename (&info);
-			ret = -EFAULT;
-			if (copy_to_user (&idata->umsdos_dirent, &entry,
-							sizeof (entry)))
-				break;
-			if (copy_to_user (&idata->dos_dirent.d_name,
-							info.fake.fname,
-				 			info.fake.len + 1))
-				break;
-			ret = entry.name_len;
-			break;
-		}
-		/* update the original f_pos */
-		filp->f_pos = pos;
-	read_dput:
-		d_drop(demd);
-		dput(demd);
-		goto out;
-	}
-	if (cmd == UMSDOS_INIT_EMD) {
-		/* #Specification: ioctl / UMSDOS_INIT_EMD
-		 * The UMSDOS_INIT_EMD command makes sure the EMD
-		 * exists for a directory. If it does not, it is
-		 * created. Also, it makes sure the directory function
-		 * table (struct inode_operations) is set to the UMSDOS
-		 * semantic. This mean that umssync may be applied to
-		 * an "opened" msdos directory, and it will change behavior
-		 * on the fly.
-		 * 
-		 * Return 0 if success.
-		 */
-
-		ret = umsdos_make_emd(dentry);
-Printk(("UMSDOS_ioctl_dir: INIT_EMD %s/%s, ret=%d\n",
-dentry->d_parent->d_name.name, dentry->d_name.name, ret));
-		umsdos_setup_dir (dentry);
-		goto out;
-	}
-
-	ret = -EFAULT;
-	if (copy_from_user (&data, idata, sizeof (data)))
-		goto out;
-
-	if (cmd == UMSDOS_CREAT_EMD) {
-		/* #Specification: ioctl / UMSDOS_CREAT_EMD
-		 * The umsdos_dirent field of the struct umsdos_ioctl is used
-		 * as is to create a new entry in the EMD of the directory.
-		 * The DOS directory is not modified.
-		 * No validation is done (yet).
-		 * 
-		 * Return 0 if success.
-		 */
-		struct umsdos_info info;
-
-		/* This makes sure info.entry and info in general
-		 * is correctly initialised
-		 */
-		memcpy (&info.entry, &data.umsdos_dirent,
-			sizeof (data.umsdos_dirent));
-		umsdos_parse (data.umsdos_dirent.name
-		    ,data.umsdos_dirent.name_len, &info);
-		ret = umsdos_newentry (dentry, &info);
-		goto out;
-	}
-	else if (cmd == UMSDOS_RENAME_DOS) {
-		struct dentry *old_dentry, *new_dentry;		/* FIXME */
-
-		/* #Specification: ioctl / UMSDOS_RENAME_DOS
-		 * A file or directory is renamed in a DOS directory
-		 * (not moved across directory). The source name
-		 * is in the dos_dirent.name field and the destination
-		 * is in umsdos_dirent.name field.
-		 * 
-		 * This ioctl allows umssync to rename a mangled file
-		 * name before syncing it back in the EMD.
-		 */
-		old_dentry = umsdos_lookup_dentry (dentry, 
-						data.dos_dirent.d_name,
-						data.dos_dirent.d_reclen ,1);
-		ret = PTR_ERR(old_dentry);
-		if (IS_ERR(old_dentry))
-			goto out;
-		new_dentry = umsdos_lookup_dentry (dentry,
-						data.umsdos_dirent.name,
-						data.umsdos_dirent.name_len, 1);
-		ret = PTR_ERR(new_dentry);
-		if (!IS_ERR(new_dentry)) {
-printk("umsdos_ioctl: renaming %s/%s to %s/%s\n",
-old_dentry->d_parent->d_name.name, old_dentry->d_name.name,
-new_dentry->d_parent->d_name.name, new_dentry->d_name.name);
-			ret = msdos_rename (dir, old_dentry, dir, new_dentry);
-			d_drop(new_dentry);
-			d_drop(old_dentry);
-			dput(new_dentry);
-		}
-		dput(old_dentry);
-		goto out;
-	}
-	else if (cmd == UMSDOS_UNLINK_EMD) {
-		/* #Specification: ioctl / UMSDOS_UNLINK_EMD
-		 * The umsdos_dirent field of the struct umsdos_ioctl is used
-		 * as is to remove an entry from the EMD of the directory.
-		 * No validation is done (yet). The mode field is used
-		 * to validate S_ISDIR or S_ISREG.
-		 * 
-		 * Return 0 if success.
-		 */
-		struct umsdos_info info;
-
-		/* This makes sure info.entry and info in general
-		 * is correctly initialised
-		 */
-		memcpy (&info.entry, &data.umsdos_dirent,
-			sizeof (data.umsdos_dirent));
-		umsdos_parse (data.umsdos_dirent.name,
-				data.umsdos_dirent.name_len, &info);
-		ret = umsdos_delentry (dentry, &info,
-				S_ISDIR (data.umsdos_dirent.mode));
-		if (ret) {
-			printk(KERN_WARNING
-				"umsdos_ioctl: delentry %s/%s failed, ret=%d\n",
-				dentry->d_name.name, info.entry.name, ret);
-		}
-		goto out;
-	}
-	else if (cmd == UMSDOS_UNLINK_DOS) {
-		struct dentry *temp;
-
-		/* #Specification: ioctl / UMSDOS_UNLINK_DOS
-		 * The dos_dirent field of the struct umsdos_ioctl is used to
-		 * execute a msdos_unlink operation. The d_name and d_reclen
-		 * fields are used.
-		 * 
-		 * Return 0 if success.
-		 */
-		temp = umsdos_lookup_dentry(dentry, data.dos_dirent.d_name,
-						data.dos_dirent.d_reclen, 1);
-		ret = PTR_ERR(temp);
-		if (IS_ERR(temp))
-			goto out;
-		ret = -ENOENT;
-		if (temp->d_inode) {
-			ret = -EISDIR;
-			if (!S_ISDIR(temp->d_inode->i_mode))
-				ret = msdos_unlink (dir, temp);
-			if (!ret)
-				d_delete(temp);
-		}
-		dput (temp);
-		goto out;
-	}
-	else if (cmd == UMSDOS_RMDIR_DOS) {
-		struct dentry *temp;
-
-		/* #Specification: ioctl / UMSDOS_RMDIR_DOS
-		 * The dos_dirent field of the struct umsdos_ioctl is used to
-		 * execute a msdos_rmdir operation. The d_name and d_reclen
-		 * fields are used.
-		 * 
-		 * Return 0 if success.
-		 */
-		temp = umsdos_lookup_dentry(dentry, data.dos_dirent.d_name,
-					    data.dos_dirent.d_reclen, 1);
-		ret = PTR_ERR(temp);
-		if (IS_ERR(temp))
-			goto out;
-		ret = -ENOENT;
-		if (temp->d_inode) {
-			ret = -ENOTDIR;
-			if (S_ISDIR(temp->d_inode->i_mode))
-				ret = msdos_rmdir (dir, temp);
-			if (!ret)
-				d_delete(temp);
-		}
-		dput (temp);
-		goto out;
-
-	} else if (cmd == UMSDOS_STAT_DOS) {
-		/* #Specification: ioctl / UMSDOS_STAT_DOS
-		 * The dos_dirent field of the struct umsdos_ioctl is
-		 * used to execute a stat operation in the DOS directory.
-		 * The d_name and d_reclen fields are used.
-		 * 
-		 * The following field of umsdos_ioctl.stat are filled.
-		 * 
-		 * st_ino,st_mode,st_size,st_atime,st_mtime,st_ctime,
-		 * Return 0 if success.
-		 */
-		struct dentry *dret;
-		struct inode *inode;
-
-		dret = umsdos_lookup_dentry(dentry, data.dos_dirent.d_name,
-					    data.dos_dirent.d_reclen, 1);
-		ret = PTR_ERR(dret);
-		if (IS_ERR(dret))
-			goto out;
-		ret = -ENOENT;
-		inode = dret->d_inode;
-		if (inode) {
-			data.stat.st_ino = inode->i_ino;
-			data.stat.st_mode = inode->i_mode;
-			data.stat.st_size = inode->i_size;
-			data.stat.st_atime = inode->i_atime;
-			data.stat.st_ctime = inode->i_ctime;
-			data.stat.st_mtime = inode->i_mtime;
-			ret = -EFAULT;
-			if (!copy_to_user (&idata->stat, &data.stat, 
-						sizeof (data.stat)))
-				ret = 0;
-		}
-		dput(dret);
-		goto out;
-	}
-	else if (cmd == UMSDOS_DOS_SETUP) {
-		/* #Specification: ioctl / UMSDOS_DOS_SETUP
-		 * The UMSDOS_DOS_SETUP ioctl allow changing the
-		 * default permission of the MS-DOS filesystem driver
-		 * on the fly.  The MS-DOS driver applies global permissions
-		 * to every file and directory. Normally these permissions
-		 * are controlled by a mount option. This is not
-		 * available for root partition, so a special utility
-		 * (umssetup) is provided to do this, normally in
-		 * /etc/rc.local.
-		 * 
-		 * Be aware that this applies ONLY to MS-DOS directories
-		 * (those without EMD --linux-.---). Umsdos directory
-		 * have independent (standard) permission for each
-		 * and every file.
-		 * 
-		 * The field umsdos_dirent provide the information needed.
-		 * umsdos_dirent.uid and gid sets the owner and group.
-		 * umsdos_dirent.mode set the permissions flags.
-		 */
-		dir->i_sb->u.msdos_sb.options.fs_uid = data.umsdos_dirent.uid;
-		dir->i_sb->u.msdos_sb.options.fs_gid = data.umsdos_dirent.gid;
-		dir->i_sb->u.msdos_sb.options.fs_fmask =
-			dir->i_sb->u.msdos_sb.options.fs_dmask =
-				data.umsdos_dirent.mode;
-		ret = 0;
-	}
-out:
-	Printk (("ioctl %d, returning %d\n", cmd, ret));
-	return ret;
-}
diff -Nru a/fs/umsdos/mangle.c b/fs/umsdos/mangle.c
--- a/fs/umsdos/mangle.c	2005-03-01 23:39:09 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,522 +0,0 @@
-/*
- *  linux/fs/umsdos/mangle.c
- *
- *      Written 1993 by Jacques Gelinas 
- *
- * Control the mangling of file name to fit msdos name space.
- * Many optimisations by GLU == dglaude@is1.vub.ac.be (Glaude David)
- */
-
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/umsdos_fs.h>
-
-/* (This file is used outside of the kernel) */
-#ifndef __KERNEL__
-#define KERN_WARNING
-#endif
-
-/*
- * Complete the mangling of the MSDOS fake name
- * based on the position of the entry in the EMD file.
- * 
- * Simply complete the job of umsdos_parse; fill the extension.
- * 
- * Beware that info->f_pos must be set.
- */
-void umsdos_manglename (struct umsdos_info *info)
-{
-	if (info->msdos_reject) {
-		/* #Specification: file name / non MSDOS conforming / mangling
-		 * Each non MSDOS conforming file has a special extension
-		 * build from the entry position in the EMD file.
-		 * 
-		 * This number is then transform in a base 32 number, where
-		 * each digit is expressed like hexadecimal number, using
-		 * digit and letter, except it uses 22 letters from 'a' to 'v'.
-		 * The number 32 comes from 2**5. It is faster to split a binary
-		 * number using a base which is a power of two. And I was 32
-		 * when I started this project. Pick your answer :-) .
-		 * 
-		 * If the result is '0', it is replace with '_', simply
-		 * to make it odd.
-		 * 
-		 * This is true for the first two character of the extension.
-		 * The last one is taken from a list of odd character, which
-		 * are:
-		 * 
-		 * { } ( ) ! ` ^ & @
-		 * 
-		 * With this scheme, we can produce 9216 ( 9* 32 * 32)
-		 * different extensions which should not clash with any useful
-		 * extension already popular or meaningful. Since most directory
-		 * have much less than 32 * 32 files in it, the first character
-		 * of the extension of any mangled name will be {.
-		 * 
-		 * Here are the reason to do this (this kind of mangling).
-		 * 
-		 * -The mangling is deterministic. Just by the extension, we
-		 * are able to locate the entry in the EMD file.
-		 * 
-		 * -By keeping to beginning of the file name almost unchanged,
-		 * we are helping the MSDOS user.
-		 * 
-		 * -The mangling produces names not too ugly, so an msdos user
-		 * may live with it (remember it, type it, etc...).
-		 * 
-		 * -The mangling produces names ugly enough so no one will
-		 * ever think of using such a name in real life. This is not
-		 * fool proof. I don't think there is a total solution to this.
-		 */
-		int entry_num;
-		char *pt = info->fake.fname + info->fake.len;
-		/* lookup for encoding the last character of the extension 
-		 * It contains valid character after the ugly one to make sure 
-		 * even if someone overflows the 32 * 32 * 9 limit, it still 
-		 * does something 
-		 */
-#define SPECIAL_MANGLING '{','}','(',')','!','`','^','&','@'
-		static char lookup3[] =
-		{
-			SPECIAL_MANGLING,
-		/* This is the start of lookup12 */
-			'_', '1', '2', '3', '4', '5', '6', '7', '8', '9',
-			'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
-			'p', 'q', 'r', 's', 't', 'u', 'v'
-		};
-
-#define lookup12 (lookup3+9)
-		entry_num = info->f_pos / UMSDOS_REC_SIZE;
-		if (entry_num > (9* 32 * 32)){
-			printk (KERN_WARNING "UMSDOS: more than 9216 files in a directory.\n"
-				"This may break the mangling strategy.\n"
-				"Not a killer problem. See doc.\n");
-		}
-		*pt++ = '.';
-		*pt++ = lookup3 [(entry_num >> 10) & 31];
-		*pt++ = lookup12[(entry_num >> 5) & 31];
-		*pt++ = lookup12[entry_num & 31];
-		*pt = '\0';		/* help doing printk */	
-		info->fake.len += 4;
-		info->msdos_reject = 0;		/* Avoid mangling twice */
-	}
-}
-
-/*
- * Evaluate the record size needed to store of name of len character.
- * The value returned is a multiple of UMSDOS_REC_SIZE.
- */
-int umsdos_evalrecsize (int len)
-{
-	struct umsdos_dirent dirent;
-	int nbrec = 1 + ((len - 1 + (dirent.name - (char *) &dirent))
-			 / UMSDOS_REC_SIZE);
-
-	return nbrec * UMSDOS_REC_SIZE;
-	/*
-	 * GLU        This should be inlined or something to speed it up to the max.
-	 * GLU        nbrec is absolutely not needed to return the value.
-	 */
-}
-#ifdef TEST
-int umsdos_evalrecsize_old (int len)
-{
-	struct umsdos_dirent dirent;
-	int size = len + (dirent.name - (char *) &dirent);
-	int nbrec = size / UMSDOS_REC_SIZE;
-	int extra = size % UMSDOS_REC_SIZE;
-
-	if (extra > 0)
-		nbrec++;
-	return nbrec * UMSDOS_REC_SIZE;
-}
-#endif
-
-
-/*
- * Fill the struct info with the full and msdos name of a file
- * Return 0 if all is OK, a negative error code otherwise.
- */
-int umsdos_parse (
-			 const char *fname,
-			 int len,
-			 struct umsdos_info *info)
-{
-	int ret = -ENAMETOOLONG;
-
-	/* #Specification: file name / too long
-	 * If a file name exceed UMSDOS maxima, the file name is silently
-	 * truncated. This makes it conformant with the other file system
-	 * of Linux (minix and ext2 at least).
-	 */
-	if (len > UMSDOS_MAXNAME)
-		len = UMSDOS_MAXNAME;
-	{
-		const char *firstpt = NULL;	/* First place we saw a "." in fname */
-
-		/* #Specification: file name / non MSDOS conforming / base length 0
-		 * file names beginning with a period '.' are invalid for MS-DOS.
-		 * It needs absolutely a base name. So the file name is mangled
-		 */
-		int ivldchar = fname[0] == '.';		/* At least one invalid character */
-		int msdos_len = len;
-		int base_len;
-
-		/*
-		 * cardinal_per_size tells if there exists at least one
-		 * DOS pseudo device on length n.  See the test below.
-		 */
-		static const char cardinal_per_size[9] =
-		{
-			0, 0, 0, 1, 1, 0, 1, 0, 1
-		};
-
-		/*
-		 * lkp translate all character to acceptable character (for DOS).
-		 * When lkp[n] == n, it means also it is an acceptable one.
-		 * So it serves both as a flag and as a translator.
-		 */
-		static char lkp[256];
-		static char is_init;
-
-		if (!is_init) {
-			/*
-			 * Initialisation of the array is easier and less error
-                         * prone like this.
-			 */
-			int i;
-			static const char *spc = "\"*+,/:;<=>?[\\]|~";
-
-			is_init = 1;
-			for (i = 0; i <= 32; i++)
-				lkp[i] = '#';
-			for (i = 33; i < 'A'; i++)
-				lkp[i] = (char) i;
-			for (i = 'A'; i <= 'Z'; i++)
-				lkp[i] = (char) (i + ('a' - 'A'));
-			for (i = 'Z' + 1; i < 127; i++)
-				lkp[i] = (char) i;
-			for (i = 128; i < 256; i++)
-				lkp[i] = '#';
-
-			lkp['.'] = '_';
-			while (*spc != '\0')
-				lkp[(unsigned char) (*spc++)] = '#';
-		}
-		/*  GLU
-		 * File names longer than 8+'.'+3 are invalid for MS-DOS,
-		 * so the file name is to be mangled--no further test is needed.
-		 * This speeds up handling of long names.
-		 * The position of the last point is no more necessary anyway.
-		 */
-		if (len <= (8 + 1 + 3)) {
-			const char *pt = fname;
-			const char *endpt = fname + len;
-
-			while (pt < endpt) {
-				if (*pt == '.') {
-					if (firstpt != NULL) {
-						/* 2 . in a file name. Reject */
-						ivldchar = 1;
-						break;
-					} else {
-						int extlen = (int) (endpt - pt);
-
-						firstpt = pt;
-						if (firstpt - fname > 8) {
-							/* base name longer than 8: reject */
-							ivldchar = 1;
-							break;
-						} else if (extlen > 4) {
-							/* Extension longer than 4 (including .): reject */
-							ivldchar = 1;
-							break;
-						} else if (extlen == 1) {
-							/* #Specification: file name / non MSDOS conforming / last char == .
-							 * If the last character of a file name is
-							 * a period, mangling is applied. MS-DOS does
-							 * not support those file names.
-							 */
-							ivldchar = 1;
-							break;
-						} else if (extlen == 4) {
-							/* #Specification: file name / non MSDOS conforming / mangling clash
-							 * To avoid clash with    the umsdos mangling, any file
-							 * with a special character as the first character
-							 * of the extension will be mangled. This solves the
-							 * following problem:
-							 * 
-							 * #
-							 * touch FILE
-							 * # FILE is invalid for DOS, so mangling is applied
-							 * # file.{_1 is created in the DOS directory
-							 * touch file.{_1
-							 * # To UMSDOS file point to a single DOS entry.
-							 * # So file.{_1 has to be mangled.
-							 * #
-							 */
-							static char special[] =
-							{
-								SPECIAL_MANGLING, '\0'
-							};
-
-							if (strchr (special, firstpt[1]) != NULL) {
-								ivldchar = 1;
-								break;
-							}
-						}
-					}
-				} else if (lkp[(unsigned char) (*pt)] != *pt) {
-					ivldchar = 1;
-					break;
-				}
-				pt++;
-			}
-		} else {
-			ivldchar = 1;
-		}
-		if (ivldchar
-		    || (firstpt == NULL && len > 8)
-		    || (len == UMSDOS_EMD_NAMELEN
-			&& memcmp (fname, UMSDOS_EMD_FILE, UMSDOS_EMD_NAMELEN) == 0)) {
-			/* #Specification: file name / --linux-.---
-			 * The name of the EMD file --linux-.--- is map to a mangled
-			 * name. So UMSDOS does not restrict its use.
-			 */
-			/* #Specification: file name / non MSDOS conforming / mangling
-			 * Non MSDOS conforming file names must use some alias to fit
-			 * in the MSDOS name space.
-			 * 
-			 * The strategy is simple. The name is simply truncated to
-			 * 8 char. points are replace with underscore and a
-			 * number is given as an extension. This number correspond
-			 * to the entry number in the EMD file. The EMD file
-			 * only need to carry the real name.
-			 * 
-			 * Upper case is also converted to lower case.
-			 * Control character are converted to #.
-			 * Spaces are converted to #.
-			 * The following characters are also converted to #.
-			 * #
-			 * " * + , / : ; < = > ? [ \ ] | ~
-			 * #
-			 * 
-			 * Sometimes the problem is not in MS-DOS itself but in
-			 * command.com.
-			 */
-			int i;
-			char *pt = info->fake.fname;
-
-			base_len = msdos_len = (msdos_len > 8) ? 8 : msdos_len;
-			/*
-			 * There is no '.' any more so we know for a fact that
-			 * the base length is the length.
-			 */
-			memcpy (info->fake.fname, fname, msdos_len);
-			for (i = 0; i < msdos_len; i++, pt++)
-				*pt = lkp[(unsigned char) (*pt)];
-			*pt = '\0';	/* GLU  We force null termination. */
-			info->msdos_reject = 1;
-			/*
-			 * The numeric extension is added only when we know
-			 * the position in the EMD file, in umsdos_newentry(),
-			 * umsdos_delentry(), and umsdos_findentry().
-			 * See umsdos_manglename().
-			 */
-		} else {
-			/* Conforming MSDOS file name */
-			strncpy (info->fake.fname, fname, len);
-			info->msdos_reject = 0;
-			base_len = firstpt != NULL ? (int) (firstpt - fname) : len;
-		}
-		if (cardinal_per_size[base_len]) {
-			/* #Specification: file name / MSDOS devices / mangling
-			 * To avoid unreachable file from MS-DOS, any MS-DOS conforming
-			 * file with a basename equal to one of the MS-DOS pseudo
-			 * devices will be mangled.
-			 * 
-			 * If a file such as "prn" was created, it would be unreachable
-			 * under MS-DOS because "prn" is assumed to be the printer, even
-			 * if the file does have an extension.
-			 * 
-			 * Since the extension is unimportant to MS-DOS, we must patch
-			 * the basename also. We simply insert a minus '-'. To avoid
-			 * conflict with valid file with a minus in front (such as
-			 * "-prn"), we add an mangled extension like any other
-			 * mangled file name.
-			 * 
-			 * Here is the list of DOS pseudo devices:
-			 * 
-			 * #
-			 * "prn","con","aux","nul",
-			 * "lpt1","lpt2","lpt3","lpt4",
-			 * "com1","com2","com3","com4",
-			 * "clock$"
-			 * #
-			 * 
-			 * and some standard ones for common DOS programs
-			 * 
-			 * "emmxxxx0","xmsxxxx0","setverxx"
-			 * 
-			 * (Thanks to Chris Hall <cah17@phoenix.cambridge.ac.uk>
-			 * for pointing these out to me).
-			 * 
-			 * Is there one missing?
-			 */
-			/* This table must be ordered by length */
-			static const char *tbdev[] =
-			{
-				"prn", "con", "aux", "nul",
-				"lpt1", "lpt2", "lpt3", "lpt4",
-				"com1", "com2", "com3", "com4",
-				"clock$",
-				"emmxxxx0", "xmsxxxx0", "setverxx"
-			};
-
-			/* Tell where to find in tbdev[], the first name of */
-			/* a certain length */
-			static const char start_ind_dev[9] =
-			{
-				0, 0, 0, 4, 12, 12, 13, 13, 16
-			};
-			char basen[9];
-			int i;
-
-			for (i = start_ind_dev[base_len - 1]; i < start_ind_dev[base_len]; i++) {
-				if (memcmp (info->fake.fname, tbdev[i], base_len) == 0) {
-					memcpy (basen, info->fake.fname, base_len);
-					basen[base_len] = '\0';		/* GLU  We force null termination. */
-					/*
-					 * GLU        We do that only if necessary; we try to do the
-					 * GLU        simple thing in the usual circumstance. 
-					 */
-					info->fake.fname[0] = '-';
-					strcpy (info->fake.fname + 1, basen);	/* GLU  We already guaranteed a null would be at the end. */
-					msdos_len = (base_len == 8) ? 8 : base_len + 1;
-					info->msdos_reject = 1;
-					break;
-				}
-			}
-		}
-		info->fake.fname[msdos_len] = '\0';	/* Help doing printk */
-		/* GLU      This zero should (always?) be there already. */
-		info->fake.len = msdos_len;
-		/* Why not use info->fake.len everywhere? Is it longer?
-                 */
-		memcpy (info->entry.name, fname, len);
-		info->entry.name[len] = '\0';	/* for printk */
-		info->entry.name_len = len;
-		ret = 0;
-	}
-	/*
-	 * Evaluate how many records are needed to store this entry.
-	 */
-	info->recsize = umsdos_evalrecsize (len);
-	return ret;
-}
-
-#ifdef TEST
-
-struct MANG_TEST {
-	char *fname;		/* Name to validate */
-	int msdos_reject;	/* Expected msdos_reject flag */
-	char *msname;		/* Expected msdos name */
-};
-
-struct MANG_TEST tb[] =
-{
-	"hello", 0, "hello",
-	"hello.1", 0, "hello.1",
-	"hello.1_", 0, "hello.1_",
-	"prm", 0, "prm",
-
-#ifdef PROPOSITION
-	"HELLO", 1, "hello",
-	"Hello.1", 1, "hello.1",
-	"Hello.c", 1, "hello.c",
-#else
-/*
- * I find the three examples below very unfortunate.  I propose to
- * convert them to lower case in a quick preliminary pass, then test
- * whether there are other troublesome characters.  I have not made
- * this change, because it is not easy, but I wanted to mention the 
- * principle.  Obviously something like that would increase the chance
- * of collisions, for example between "HELLO" and "Hello", but these
- * can be treated elsewhere along with the other collisions.
- */
-
-	"HELLO", 1, "hello",
-	"Hello.1", 1, "hello_1",
-	"Hello.c", 1, "hello_c",
-#endif
-
-	"hello.{_1", 1, "hello_{_",
-	"hello\t", 1, "hello#",
-	"hello.1.1", 1, "hello_1_",
-	"hel,lo", 1, "hel#lo",
-	"Salut.Tu.vas.bien?", 1, "salut_tu",
-	".profile", 1, "_profile",
-	".xv", 1, "_xv",
-	"toto.", 1, "toto_",
-	"clock$.x", 1, "-clock$",
-	"emmxxxx0", 1, "-emmxxxx",
-	"emmxxxx0.abcd", 1, "-emmxxxx",
-	"aux", 1, "-aux",
-	"prn", 1, "-prn",
-	"prn.abc", 1, "-prn",
-	"PRN", 1, "-prn",
-  /* 
-   * GLU        WARNING:  the results of these are different with my version
-   * GLU        of mangling compared to the original one.
-   * GLU        CAUSE:  the manner of calculating the baselen variable.
-   * GLU                For you they are always 3.
-   * GLU                For me they are respectively 7, 8, and 8.
-
-   */
-	"PRN.abc", 1, "prn_abc",
-	"Prn.abcd", 1, "prn_abcd",
-	"prn.abcd", 1, "prn_abcd",
-	"Prn.abcdefghij", 1, "prn_abcd"
-};
-
-int main (int argc, char *argv[])
-{
-	int i, rold, rnew;
-
-	printf ("Testing the umsdos_parse.\n");
-	for (i = 0; i < sizeof (tb) / sizeof (tb[0]); i++) {
-		struct MANG_TEST *pttb = tb + i;
-		struct umsdos_info info;
-		int ok = umsdos_parse (pttb->fname, strlen (pttb->fname), &info);
-
-		if (strcmp (info.fake.fname, pttb->msname) != 0) {
-			printf ("**** %s -> ", pttb->fname);
-			printf ("%s <> %s\n", info.fake.fname, pttb->msname);
-		} else if (info.msdos_reject != pttb->msdos_reject) {
-			printf ("**** %s -> %s ", pttb->fname, pttb->msname);
-			printf ("%d <> %d\n", info.msdos_reject, pttb->msdos_reject);
-		} else {
-			printf ("     %s -> %s %d\n", pttb->fname, pttb->msname
-				,pttb->msdos_reject);
-		}
-	}
-	printf ("Testing the new umsdos_evalrecsize.");
-	for (i = 0; i < UMSDOS_MAXNAME; i++) {
-		rnew = umsdos_evalrecsize (i);
-		rold = umsdos_evalrecsize_old (i);
-		if (!(i % UMSDOS_REC_SIZE)) {
-			printf ("\n%d:\t", i);
-		}
-		if (rnew != rold) {
-			printf ("**** %d newres: %d != %d \n", i, rnew, rold);
-		} else {
-			printf (".");
-		}
-	}
-	printf ("\nEnd of Testing.\n");
-
-	return 0;
-}
-
-#endif
diff -Nru a/fs/umsdos/namei.c b/fs/umsdos/namei.c
--- a/fs/umsdos/namei.c	2005-03-01 23:39:08 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,1124 +0,0 @@
-/*
- *  linux/fs/umsdos/namei.c
- *
- *      Written 1993 by Jacques Gelinas 
- *      Inspired from linux/fs/msdos/... by Werner Almesberger
- *
- * Maintain and access the --linux alternate directory file.
- */
- /*
-  * You are in the maze of twisted functions - half of them shouldn't
-  * be here...
-  */
-
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/time.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/stat.h>
-#include <linux/string.h>
-#include <linux/msdos_fs.h>
-#include <linux/umsdos_fs.h>
-#include <linux/slab.h>
-
-#define UMSDOS_DIR_LOCK
-
-#ifdef UMSDOS_DIR_LOCK
-
-static inline void u_sleep_on (struct inode *dir)
-{
-	sleep_on (&UMSDOS_I(dir)->dir_info.p);
-}
-
-static inline void u_wake_up (struct inode *dir)
-{
-    	wake_up (&UMSDOS_I(dir)->dir_info.p);
-}
-
-/*
- * Wait for creation exclusivity.
- * Return 0 if the dir was already available.
- * Return 1 if a wait was necessary.
- * When 1 is return, it means a wait was done. It does not
- * mean the directory is available.
- */
-static int umsdos_waitcreate (struct inode *dir)
-{
-	int ret = 0;
-
-	if (UMSDOS_I(dir)->dir_info.creating
-	    && UMSDOS_I(dir)->dir_info.pid != current->pid) {
-	    	PRINTK (("creating && dir_info.pid=%lu, current->pid=%u\n", UMSDOS_I(dir)->dir_info.pid, current->pid));
-	    	u_sleep_on (dir);
-		ret = 1;
-	}
-	return ret;
-}
-
-/*
- * Wait for any lookup process to finish
- */
-static void umsdos_waitlookup (struct inode *dir)
-{
-	while (UMSDOS_I(dir)->dir_info.looking) {
-	    	u_sleep_on (dir);
-	}
-}
-
-/*
- * Lock all other process out of this directory.
- */
-/* #Specification: file creation / not atomic
- * File creation is a two step process. First we create (allocate)
- * an entry in the EMD file and then (using the entry offset) we
- * build a unique name for MSDOS. We create this name in the msdos
- * space.
- * 
- * We have to use semaphore (sleep_on/wake_up) to prevent lookup
- * into a directory when we create a file or directory and to
- * prevent creation while a lookup is going on. Since many lookup
- * may happen at the same time, the semaphore is a counter.
- * 
- * Only one creation is allowed at the same time. This protection
- * may not be necessary. The problem arise mainly when a lookup
- * or a readdir is done while a file is partially created. The
- * lookup process see that as a "normal" problem and silently
- * erase the file from the EMD file. Normal because a file
- * may be erased during a MSDOS session, but not removed from
- * the EMD file.
- * 
- * The locking is done on a directory per directory basis. Each
- * directory inode has its wait_queue.
- * 
- * For some operation like hard link, things even get worse. Many
- * creation must occur at once (atomic). To simplify the design
- * a process is allowed to recursively lock the directory for
- * creation. The pid of the locking process is kept along with
- * a counter so a second level of locking is granted or not.
- */
-void umsdos_lockcreate (struct inode *dir)
-{
-	/*
-	 * Wait for any creation process to finish except
-	 * if we (the process) own the lock
-	 */
-	while (umsdos_waitcreate (dir) != 0);
-	UMSDOS_I(dir)->dir_info.creating++;
-	UMSDOS_I(dir)->dir_info.pid = current->pid;
-	umsdos_waitlookup (dir);
-}
-
-/*
- * Lock all other process out of those two directories.
- */
-static void umsdos_lockcreate2 (struct inode *dir1, struct inode *dir2)
-{
-	/*
-	 * We must check that both directory are available before
-	 * locking anyone of them. This is to avoid some deadlock.
-	 * Thanks to dglaude@is1.vub.ac.be (GLAUDE DAVID) for pointing
-	 * this to me.
-	 */
-	while (1) {
-		if (umsdos_waitcreate (dir1) == 0
-		    && umsdos_waitcreate (dir2) == 0) {
-			/* We own both now */
-			UMSDOS_I(dir1)->dir_info.creating++;
-			UMSDOS_I(dir1)->dir_info.pid = current->pid;
-			UMSDOS_I(dir2)->dir_info.creating++;
-			UMSDOS_I(dir2)->dir_info.pid = current->pid;
-			break;
-		}
-	}
-	umsdos_waitlookup (dir1);
-	umsdos_waitlookup (dir2);
-}
-
-/*
- * Wait until creation is finish in this directory.
- */
-void umsdos_startlookup (struct inode *dir)
-{
-	while (umsdos_waitcreate (dir) != 0);
-	UMSDOS_I(dir)->dir_info.looking++;
-}
-
-/*
- * Unlock the directory.
- */
-void umsdos_unlockcreate (struct inode *dir)
-{
-	UMSDOS_I(dir)->dir_info.creating--;
-	if (UMSDOS_I(dir)->dir_info.creating < 0) {
-		printk ("UMSDOS: UMSDOS_I(dir)->dir_info.creating < 0: %d"
-			,UMSDOS_I(dir)->dir_info.creating);
-	}
-    	u_wake_up (dir);
-}
-
-/*
- * Tell directory lookup is over.
- */
-void umsdos_endlookup (struct inode *dir)
-{
-	UMSDOS_I(dir)->dir_info.looking--;
-	if (UMSDOS_I(dir)->dir_info.looking < 0) {
-		printk ("UMSDOS: UMSDOS_I(dir)->dir_info.looking < 0: %d"
-			,UMSDOS_I(dir)->dir_info.looking);
-	}
-    	u_wake_up (dir);
-}
-
-#else
-static void umsdos_lockcreate (struct inode *dir)
-{
-}
-static void umsdos_lockcreate2 (struct inode *dir1, struct inode *dir2)
-{
-}
-void umsdos_startlookup (struct inode *dir)
-{
-}
-static void umsdos_unlockcreate (struct inode *dir)
-{
-}
-void umsdos_endlookup (struct inode *dir)
-{
-}
-
-#endif
-
-static int umsdos_nevercreat (struct inode *dir, struct dentry *dentry,
-				int errcod)
-{
-	int ret = 0;
-
-	if (umsdos_is_pseudodos (dir, dentry)) {
-		/* #Specification: pseudo root / any file creation /DOS
-		 * The pseudo sub-directory /DOS can't be created!
-		 * EEXIST is returned.
-		 * 
-		 * The pseudo sub-directory /DOS can't be removed!
-		 * EPERM is returned.
-		 */
-		ret = errcod;
-	}
-	return ret;
-}
-
-/*
- * Add a new file (ordinary or special) into the alternate directory.
- * The file is added to the real MSDOS directory. If successful, it
- * is then added to the EMD file.
- * 
- * Return the status of the operation. 0 mean success.
- *
- * #Specification: create / file exists in DOS
- * Here is a situation: we are trying to create a file with
- * UMSDOS. The file is unknown to UMSDOS but already
- * exists in the DOS directory.
- * 
- * Here is what we are NOT doing:
- * 
- * We could silently assume that everything is fine
- * and allows the creation to succeed.
- * 
- * It is possible not all files in the partition
- * are meant to be visible from linux. By trying to create
- * those file in some directory, one user may get access
- * to those file without proper permissions. Looks like
- * a security hole to me. Off course sharing a file system
- * with DOS is some kind of security hole :-)
- * 
- * So ?
- * 
- * We return EEXIST in this case.
- * The same is true for directory creation.
- */
-static int umsdos_create_any (struct inode *dir, struct dentry *dentry,
-				int mode, dev_t rdev, char flags)
-{
-	struct dentry *fake;
-	struct inode *inode;
-	int ret;
-	struct umsdos_info info;
-
-	ret = umsdos_nevercreat (dir, dentry, -EEXIST);
-	if (ret)
-		goto out;
-
-	ret = umsdos_parse (dentry->d_name.name, dentry->d_name.len, &info);
-	if (ret)
-		goto out;
-
-	info.entry.mode = mode;
-	info.entry.rdev = rdev;
-	info.entry.flags = flags;
-	info.entry.uid = current->fsuid;
-	info.entry.gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid;
-	info.entry.ctime = info.entry.atime = info.entry.mtime = get_seconds();
-	info.entry.nlink = 1;
-	ret = umsdos_newentry (dentry->d_parent, &info);
-	if (ret)
-		goto out;
-
-	/* do a real lookup to get the short name dentry */
-	fake = umsdos_covered(dentry->d_parent, info.fake.fname, info.fake.len);
-	ret = PTR_ERR(fake);
-	if (IS_ERR(fake))
-		goto out_remove;
-
-	/* should not exist yet ... */
-	ret = -EEXIST;
-	if (fake->d_inode)
-		goto out_remove_dput;
-
-	ret = msdos_create (dir, fake, S_IFREG | 0777, NULL);
-	if (ret)
-		goto out_remove_dput;
-
-	inode = fake->d_inode;
-	atomic_inc(&inode->i_count);
-	d_instantiate (dentry, inode);
-	dput(fake);
-	if (atomic_read(&inode->i_count) > 1) {
-		printk(KERN_WARNING
-			"umsdos_create_any: %s/%s, ino=%ld, icount=%d??\n",
-			dentry->d_parent->d_name.name, dentry->d_name.name,
-			inode->i_ino, atomic_read(&inode->i_count));
-	}
-	umsdos_lookup_patch_new(dentry, &info);
-
-out:
-	return ret;
-
-	/* Creation failed ... remove the EMD entry */
-out_remove_dput:
-	dput(fake);
-out_remove:
-	if (ret == -EEXIST)
-		printk(KERN_WARNING "UMSDOS: out of sync, deleting %s/%s\n",
-			dentry->d_parent->d_name.name, info.fake.fname);
-	umsdos_delentry (dentry->d_parent, &info, S_ISDIR (info.entry.mode));
-	goto out;
-}
-
-/*
- * Add a new file into the alternate directory.
- * The file is added to the real MSDOS directory. If successful, it
- * is then added to the EMD file.
- * 
- * Return the status of the operation. 0 mean success.
- */
-int UMSDOS_create (struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd)
-{
-	return umsdos_create_any (dir, dentry, mode, 0, 0);
-}
-
-
-/*
- * Initialise the new_entry from the old for a rename operation.
- * (Only useful for umsdos_rename_f() below).
- */
-static void umsdos_ren_init (struct umsdos_info *new_info,
-			     struct umsdos_info *old_info)
-{
-	new_info->entry.mode = old_info->entry.mode;
-	new_info->entry.rdev = old_info->entry.rdev;
-	new_info->entry.uid = old_info->entry.uid;
-	new_info->entry.gid = old_info->entry.gid;
-	new_info->entry.ctime = old_info->entry.ctime;
-	new_info->entry.atime = old_info->entry.atime;
-	new_info->entry.mtime = old_info->entry.mtime;
-	new_info->entry.flags = old_info->entry.flags;
-	new_info->entry.nlink = old_info->entry.nlink;
-}
-
-/*
- * Rename a file (move) in the file system.
- */
- 
-static int umsdos_rename_f (struct inode *old_dir, struct dentry *old_dentry,
-			    struct inode *new_dir, struct dentry *new_dentry,
-			    int flags)
-{
-	struct inode *old_inode = old_dentry->d_inode;
-	struct dentry *old, *new, *old_emd;
-	int err, ret;
-	struct umsdos_info old_info;
-	struct umsdos_info new_info;
-
- 	ret = -EPERM;
-	err = umsdos_parse (old_dentry->d_name.name,
-				old_dentry->d_name.len, &old_info);
-	if (err)
-		goto out;
-	err = umsdos_parse (new_dentry->d_name.name,
-				new_dentry->d_name.len, &new_info);
-	if (err)
-		goto out;
-
-	/* Get the EMD dentry for the old parent */
-	old_emd = umsdos_get_emd_dentry(old_dentry->d_parent);
-	ret = PTR_ERR(old_emd);
-	if (IS_ERR(old_emd))
-		goto out;
-
-	umsdos_lockcreate2 (old_dir, new_dir);
-
-	ret = umsdos_findentry(old_emd->d_parent, &old_info, 0);
-	if (ret)
-		goto out_unlock;
-
-	err = umsdos_findentry(new_dentry->d_parent, &new_info, 0);
-	if (err == 0) {
-		/* check whether it _really_ exists ... */
-		ret = -EEXIST;
-		if (new_dentry->d_inode)
-			goto out_unlock;
-
-		/* bogus lookup? complain and fix up the EMD ... */
-		printk(KERN_WARNING
-			"umsdos_rename_f: entry %s/%s exists, inode NULL??\n",
-			new_dentry->d_parent->d_name.name, new_info.entry.name);
-		err = umsdos_delentry(new_dentry->d_parent, &new_info,
-					S_ISDIR(new_info.entry.mode));
-	}
-
-	umsdos_ren_init (&new_info, &old_info);
-	if (flags)
-		new_info.entry.flags = flags;
-	ret = umsdos_newentry (new_dentry->d_parent, &new_info);
-	if (ret)
-		goto out_unlock;
-
-	/* If we're moving a hardlink, drop it first */
-	if (old_info.entry.flags & UMSDOS_HLINK) {
-		d_drop(old_dentry);
-	}
-
-	old = umsdos_covered(old_dentry->d_parent, old_info.fake.fname, 
-					old_info.fake.len);
-	ret = PTR_ERR(old);
-	if (IS_ERR(old))
-		goto out_unlock;
-	/* make sure it's the same inode! */
-	ret = -ENOENT;
-	/*
-	 * note: for hardlinks they will be different!
-	 *  old_inode will contain inode of .LINKxxx file containing data, and
-	 *  old->d_inode will contain inode of file containing path to .LINKxxx file
-	 */
-	if (!(old_info.entry.flags & UMSDOS_HLINK)) {
-	 	if (old->d_inode != old_inode)
- 			goto out_dput;
-	}
-
-	new = umsdos_covered(new_dentry->d_parent, new_info.fake.fname, 
-					new_info.fake.len);
-	ret = PTR_ERR(new);
-	if (IS_ERR(new))
-		goto out_dput;
-
-	/* Do the msdos-level rename */
-	ret = msdos_rename (old_dir, old, new_dir, new);
-
-	dput(new);
-
-	/* If the rename failed, remove the new EMD entry */
-	if (ret != 0) {
-		umsdos_delentry (new_dentry->d_parent, &new_info,
-				 S_ISDIR (new_info.entry.mode));
-		goto out_dput;
-	}
-
-	/*
-	 * Rename successful ... remove the old name from the EMD.
-	 * Note that we use the EMD parent here, as the old dentry
-	 * may have moved to a new parent ...
-	 */
-	err = umsdos_delentry (old_emd->d_parent, &old_info,
-				S_ISDIR (old_info.entry.mode));
-	if (err) {
-		/* Failed? Complain a bit, but don't fail the operation */
-		printk(KERN_WARNING 
-			"umsdos_rename_f: delentry %s/%s failed, error=%d\n",
-			old_emd->d_parent->d_name.name, old_info.entry.name,
-			err);
-	}
-
-	/*
-	 * Update f_pos so notify_change will succeed
-	 * if the file was already in use.
-	 */
-	umsdos_set_dirinfo_new(old_dentry, new_info.f_pos);
-
-	/* dput() the dentry if we haven't already */
-out_dput:
-	dput(old);
-
-out_unlock:
-	dput(old_emd);
-	umsdos_unlockcreate (old_dir);
-	umsdos_unlockcreate (new_dir);
-
-out:
-	Printk ((" _ret=%d\n", ret));
-	return ret;
-}
-
-/*
- * Setup a Symbolic link or a (pseudo) hard link
- * Return a negative error code or 0 if OK.
- */
-/* #Specification: symbolic links / strategy
- * A symbolic link is simply a file which holds a path. It is
- * implemented as a normal MSDOS file (not very space efficient :-()
- * 
- * I see two different ways to do this: One is to place the link data
- * in unused entries of the EMD file; the other is to have a separate
- * file dedicated to hold all symbolic links data.
- * 
- * Let's go for simplicity...
- */
-
-/*
- * AV. Should be called with dir->i_sem down.
- */
-static int umsdos_symlink_x (struct inode *dir, struct dentry *dentry,
-			const char *symname, int mode, char flags)
-{
-	int ret, len;
-
-	ret = umsdos_create_any (dir, dentry, mode, 0, flags);
-	if (ret) {
-		printk(KERN_WARNING
-			"umsdos_symlink: create failed, ret=%d\n", ret);
-		goto out;
-	}
-
-	len = strlen (symname) + 1;
-	ret = page_symlink(dentry->d_inode, symname, len);
-	if (ret < 0)
-		goto out_unlink;
-out:
-	return ret;
-
-out_unlink:
-	printk(KERN_WARNING "umsdos_symlink: write failed, unlinking\n");
-	UMSDOS_unlink (dir, dentry);
-	d_drop(dentry);
-	goto out;
-}
-
-/*
- * Setup a Symbolic link.
- * Return a negative error code or 0 if OK.
- */
-int UMSDOS_symlink ( struct inode *dir, struct dentry *dentry,
-		 const char *symname)
-{
-	return umsdos_symlink_x (dir, dentry, symname, S_IFLNK | 0777, 0);
-}
-
-/*
- * Add a link to an inode in a directory
- */
-int UMSDOS_link (struct dentry *olddentry, struct inode *dir,
-		 struct dentry *dentry)
-{
-	struct inode *oldinode = olddentry->d_inode;
-	struct inode *olddir = olddentry->d_parent->d_inode;
-	struct dentry *temp;
-	char *path;
-	unsigned long buffer;
-	int ret;
-	struct umsdos_info old_info;
-	struct umsdos_info hid_info;
-
-#ifdef UMSDOS_DEBUG_VERBOSE
-printk("umsdos_link: new %s/%s -> %s/%s\n",
-dentry->d_parent->d_name.name, dentry->d_name.name, 
-olddentry->d_parent->d_name.name, olddentry->d_name.name);
-#endif
- 
-	ret = -EPERM;
-	if (S_ISDIR (oldinode->i_mode))
-		goto out;
-
-	ret = umsdos_nevercreat (dir, dentry, -EPERM);
-	if (ret)
-		goto out;
-
-	ret = -ENOMEM;
-	buffer = get_zeroed_page(GFP_KERNEL);
-	if (!buffer)
-		goto out;
-
-	/*
-	 * Lock the link parent if it's not the same directory.
-	 */
-	ret = -EDEADLOCK;
-	if (olddir != dir) {
-		if (atomic_read(&olddir->i_sem.count) < 1)
-			goto out_free;
-		down(&olddir->i_sem);
-	}
-
-	/*
-	 * Parse the name and get the visible directory entry.
-	 */
-	ret = umsdos_parse (olddentry->d_name.name, olddentry->d_name.len,
-				&old_info);
-	if (ret)
-		goto out_unlock;
-	ret = umsdos_findentry (olddentry->d_parent, &old_info, 1);
-	if (ret) {
-printk("UMSDOS_link: %s/%s not in EMD, ret=%d\n",
-olddentry->d_parent->d_name.name, olddentry->d_name.name, ret);
-		goto out_unlock;
-	}
-
-	/*
-	 * If the visible dentry is a pseudo-hardlink, the original
-	 * file must be already hidden.
-	 */
-	if (!(old_info.entry.flags & UMSDOS_HLINK)) {
-		int err;
-
-		/* create a hidden link name */
-		ret = umsdos_newhidden (olddentry->d_parent, &hid_info);
-		if (ret) {
-printk("umsdos_link: can't make hidden %s/%s, ret=%d\n",
-olddentry->d_parent->d_name.name, hid_info.entry.name, ret);
-			goto out_unlock;
-		}
-
-		/*
-		 * Make a dentry and rename the original file ...
-		 */
-		temp = umsdos_lookup_dentry(olddentry->d_parent,
-						hid_info.entry.name,
-						hid_info.entry.name_len, 0); 
-		ret = PTR_ERR(temp);
-		if (IS_ERR(temp)) {
-printk("umsdos_link: lookup %s/%s failed, ret=%d\n",
-dentry->d_parent->d_name.name, hid_info.entry.name, ret);
-			goto cleanup;
-		}
-		/* rename the link to the hidden location ... */
-		ret = umsdos_rename_f(olddir, olddentry, olddir, temp,
-					UMSDOS_HIDDEN);
-		d_move(olddentry, temp);
-		dput(temp);
-		if (ret) {
-printk("umsdos_link: rename to %s/%s failed, ret=%d\n",
-temp->d_parent->d_name.name, temp->d_name.name, ret);
-			goto cleanup;
-		}
-		/* mark the inode as a hardlink */
-		UMSDOS_I(oldinode)->i_is_hlink = 1;
-
-		/*
-		 * Capture the path to the hidden link.
-		 */
-		path = umsdos_d_path(olddentry, (char *) buffer, PAGE_SIZE);
-Printk(("umsdos_link: hidden link path=%s\n", path));
-
-		/*
-		 * Recreate a dentry for the original name and symlink it,
-		 * then symlink the new dentry. Don't give up if one fails,
-		 * or we'll lose the file completely!
-		 *
-		 * Note: this counts as the "original" reference, so we 
-		 * don't increment i_nlink for this one.
-		 */ 
-		temp = umsdos_lookup_dentry(olddentry->d_parent,
-						old_info.entry.name,
-						old_info.entry.name_len, 0); 
-		ret = PTR_ERR(temp);
-		if (!IS_ERR(temp)) {
-			ret = umsdos_symlink_x (olddir, temp, path, 
-						S_IFREG | 0777, UMSDOS_HLINK);
-			dput(temp);
-		}
-
-		/* This symlink increments i_nlink (see below.) */
-		err = umsdos_symlink_x (dir, dentry, path,
-					S_IFREG | 0777, UMSDOS_HLINK);
-		/* fold the two errors */
-		if (!ret)
-			ret = err;
-		goto out_unlock;
-
-		/* creation failed ... remove the link entry */
-	cleanup:
-printk("umsdos_link: link failed, ret=%d, removing %s/%s\n",
-ret, olddentry->d_parent->d_name.name, hid_info.entry.name);
-		err = umsdos_delentry(olddentry->d_parent, &hid_info, 0);
-		goto out_unlock;
-	}
-
-Printk(("UMSDOS_link: %s/%s already hidden\n",
-olddentry->d_parent->d_name.name, olddentry->d_name.name));
-	/*
-	 * The original file is already hidden, and we need to get 
-	 * the dentry for its real name, not the visible name.
-	 * N.B. make sure it's the hidden inode ...
-	 */
-	if (!UMSDOS_I(oldinode)->i_is_hlink)
-		printk("UMSDOS_link: %s/%s hidden, ino=%ld not hlink??\n",
-			olddentry->d_parent->d_name.name,
-			olddentry->d_name.name, oldinode->i_ino);
-
-	/*
-	 * In order to get the correct (real) inode, we just drop
-	 * the original dentry.
-	 */ 
-	d_drop(olddentry);
-Printk(("UMSDOS_link: hard link %s/%s, fake=%s\n",
-olddentry->d_parent->d_name.name, olddentry->d_name.name, old_info.fake.fname));
-
-	/* Do a real lookup to get the short name dentry */
-	temp = umsdos_covered(olddentry->d_parent, old_info.fake.fname, 
-					old_info.fake.len);
-	ret = PTR_ERR(temp);
-	if (IS_ERR(temp))
-		goto out_unlock;
-
-	/* now resolve the link ... */
-	temp = umsdos_solve_hlink(temp);
-	ret = PTR_ERR(temp);
-	if (IS_ERR(temp))
-		goto out_unlock;
-	path = umsdos_d_path(temp, (char *) buffer, PAGE_SIZE);
-	dput(temp);
-Printk(("umsdos_link: %s/%s already hidden, path=%s\n",
-olddentry->d_parent->d_name.name, olddentry->d_name.name, path));
-
-	/* finally we can symlink it ... */
-	ret = umsdos_symlink_x (dir, dentry, path, S_IFREG | 0777,UMSDOS_HLINK);
-
-out_unlock:
-	/* remain locked for the call to notify_change ... */
-	if (ret == 0) {
-		struct iattr newattrs;
-
-		/* Do a real lookup to get the short name dentry */
-		temp = umsdos_covered(olddentry->d_parent,
-					old_info.fake.fname,
-					old_info.fake.len);
-		ret = PTR_ERR(temp);
-		if (IS_ERR(temp))
-			goto out_unlock2;
-
-		/* now resolve the link ... */
-		temp = umsdos_solve_hlink(temp);
-		ret = PTR_ERR(temp);
-		if (IS_ERR(temp))
-			goto out_unlock2;
-
-
-#ifdef UMSDOS_PARANOIA
-if (!UMSDOS_I(oldinode)->i_is_hlink)
-printk("UMSDOS_link: %s/%s, ino=%ld, not marked as hlink!\n",
-olddentry->d_parent->d_name.name, olddentry->d_name.name, oldinode->i_ino);
-#endif
-		temp->d_inode->i_nlink++;
-Printk(("UMSDOS_link: linked %s/%s, ino=%ld, nlink=%d\n",
-olddentry->d_parent->d_name.name, olddentry->d_name.name,
-oldinode->i_ino, oldinode->i_nlink));
-		newattrs.ia_valid = 0;
-		ret = umsdos_notify_change_locked(temp, &newattrs);
- 		if (ret == 0)
-			mark_inode_dirty(temp->d_inode);
-		dput(temp);
-out_unlock2:	
-		if (ret == 0)
-			mark_inode_dirty(olddentry->d_inode);
-	}
-	if (olddir != dir)
-		up(&olddir->i_sem);
-
-out_free:
-	free_page(buffer);
-out:
-	Printk (("umsdos_link %d\n", ret));
-	return ret;
-}
-
-
-/*
- * Add a sub-directory in a directory
- */
-/* #Specification: mkdir / Directory already exist in DOS
- * We do the same thing as for file creation.
- * For all user it is an error.
- */
-/* #Specification: mkdir / umsdos directory / create EMD
- * When we created a new sub-directory in a UMSDOS
- * directory (one with full UMSDOS semantics), we
- * create immediately an EMD file in the new
- * sub-directory so it inherits UMSDOS semantics.
- */
-int UMSDOS_mkdir (struct inode *dir, struct dentry *dentry, int mode)
-{
-	struct dentry *temp;
-	struct inode *inode;
-	int ret, err;
-	struct umsdos_info info;
-
-	ret = umsdos_nevercreat (dir, dentry, -EEXIST);
-	if (ret)
-		goto out;
-
-	ret = umsdos_parse (dentry->d_name.name, dentry->d_name.len, &info);
-	if (ret)
-		goto out;
-
-	info.entry.mode = mode | S_IFDIR;
-	info.entry.rdev = 0;
-	info.entry.uid = current->fsuid;
-	info.entry.gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid;
-	info.entry.ctime = info.entry.atime = info.entry.mtime = get_seconds();
-	info.entry.flags = 0;
-	info.entry.nlink = 1;
-	ret = umsdos_newentry (dentry->d_parent, &info);
-	if (ret)
-		goto out;
-
-	/* lookup the short name dentry */
-	temp = umsdos_covered(dentry->d_parent, info.fake.fname, info.fake.len);
-	ret = PTR_ERR(temp);
-	if (IS_ERR(temp))
-		goto out_remove;
-
-	/* Make sure the short name doesn't exist */
-	ret = -EEXIST;
-	if (temp->d_inode) {
-printk("umsdos_mkdir: short name %s/%s exists\n",
-dentry->d_parent->d_name.name, info.fake.fname);
-		goto out_remove_dput;
-	}
-
-	ret = msdos_mkdir (dir, temp, mode);
-	if (ret)
-		goto out_remove_dput;
-
-	/*
-	 * Lock the inode to protect the EMD creation ...
-	 */
-	inode = temp->d_inode;
-	down(&inode->i_sem);
-
-	atomic_inc(&inode->i_count);
-	d_instantiate(dentry, inode);
-
-	/* N.B. this should have an option to create the EMD ... */
-	umsdos_lookup_patch_new(dentry, &info);
-
-	/* 
-	 * Create the EMD file, and set up the dir so it is
-	 * promoted to EMD with the EMD file invisible.
-	 *
-	 * N.B. error return if EMD fails?
-	 */
-	err = umsdos_make_emd(dentry);
-	umsdos_setup_dir(dentry);
-
-	up(&inode->i_sem);
-	dput(temp);
-
-out:
-	Printk(("umsdos_mkdir: %s/%s, ret=%d\n",
-		dentry->d_parent->d_name.name, dentry->d_name.name, ret));
-	return ret;
-
-	/* an error occurred ... remove EMD entry. */
-out_remove_dput:
-	dput(temp);
-out_remove:
-	umsdos_delentry (dentry->d_parent, &info, 1);
-	goto out;
-}
-
-/*
- * Add a new device special file into a directory.
- *
- * #Specification: Special files / strategy
- * Device special file, pipes, etc ... are created like normal
- * file in the msdos file system. Of course they remain empty.
- * 
- * One strategy was to create those files only in the EMD file
- * since they were not important for MSDOS. The problem with
- * that, is that there were not getting inode number allocated.
- * The MSDOS filesystems is playing a nice game to fake inode
- * number, so why not use it.
- * 
- * The absence of inode number compatible with those allocated
- * for ordinary files was causing major trouble with hard link
- * in particular and other parts of the kernel I guess.
- */
-int UMSDOS_mknod (struct inode *dir, struct dentry *dentry,
-		 int mode, dev_t rdev)
-{
-	return umsdos_create_any (dir, dentry, mode, rdev, 0);
-}
-
-/*
- * Remove a sub-directory.
- */
-int UMSDOS_rmdir (struct inode *dir, struct dentry *dentry)
-{
-	struct dentry *temp;
-	int ret, err, empty;
-	struct umsdos_info info;
-
-	ret = umsdos_nevercreat (dir, dentry, -EPERM);
-	if (ret)
-		goto out;
-
-	ret = -EBUSY;
-	if (!d_unhashed(dentry))
-		goto out;
-
-	/* check whether the EMD is empty */
-	ret = -ENOTEMPTY;
-	empty = umsdos_isempty (dentry);
-
-	/* Have to remove the EMD file? */
-	if (empty == 1) {
-		struct dentry *demd;
-
-		demd = umsdos_get_emd_dentry(dentry);
-		if (!IS_ERR(demd)) {
-			err = -ENOENT;
-			if (demd->d_inode)
-				err = msdos_unlink (dentry->d_inode, demd);
-Printk (("UMSDOS_rmdir: unlinking empty EMD err=%d", err));
-#ifdef UMSDOS_PARANOIA
-if (err)
-printk("umsdos_rmdir: EMD %s/%s unlink failed, err=%d\n",
-demd->d_parent->d_name.name, demd->d_name.name, err);
-#endif
-			if (!err) {
-				d_delete(demd);
-				ret = 0;
-			}
-			dput(demd);
-		}
-	} else if (empty == 2)
-		ret = 0;
-	if (ret)
-		goto out;
-
-	umsdos_parse (dentry->d_name.name, dentry->d_name.len, &info);
-	/* Call findentry to complete the mangling */
-	umsdos_findentry (dentry->d_parent, &info, 2);
-	temp = umsdos_covered(dentry->d_parent, info.fake.fname, info.fake.len);
-	ret = PTR_ERR(temp);
-	if (IS_ERR(temp))
-		goto out;
-	/*
-	 * Attempt to remove the msdos name.
-	 */
-	ret = msdos_rmdir (dir, temp);
-	if (ret && ret != -ENOENT)
-		goto out_dput;
-
-	d_delete(temp);
-	/* OK so far ... remove the name from the EMD */
-	ret = umsdos_delentry (dentry->d_parent, &info, 1);
-#ifdef UMSDOS_PARANOIA
-if (ret)
-printk("umsdos_rmdir: delentry %s failed, ret=%d\n", info.entry.name, ret);
-#endif
-
-	/* dput() temp if we didn't do it above */
-out_dput:
-	dput(temp);
-
-out:
-	Printk (("umsdos_rmdir %d\n", ret));
-	return ret;
-}
-
-
-/*
- * Remove a file from the directory.
- *
- * #Specification: hard link / deleting a link
- * When we delete a file and this file is a link,
- * we must subtract 1 from the nlink field of the
- * hidden link.
- * 
- * If the count goes to 0, we delete this hidden
- * link too.
- */
-int UMSDOS_unlink (struct inode *dir, struct dentry *dentry)
-{
-	struct dentry *temp, *link = NULL;
-	struct inode *inode;
-	int ret;
-	struct umsdos_info info;
-
-Printk(("UMSDOS_unlink: entering %s/%s\n",
-dentry->d_parent->d_name.name, dentry->d_name.name));
-
-	ret = umsdos_nevercreat (dir, dentry, -EPERM);
-	if (ret)
-		goto out;
-
-	ret = umsdos_parse (dentry->d_name.name, dentry->d_name.len, &info);
-	if (ret)
-		goto out;
-
-	umsdos_lockcreate (dir);
-	ret = umsdos_findentry (dentry->d_parent, &info, 1);
-	if (ret) {
-printk("UMSDOS_unlink: %s/%s not in EMD, ret=%d\n",
-dentry->d_parent->d_name.name, dentry->d_name.name, ret);
-		goto out_unlock;
-	}
-
-Printk (("UMSDOS_unlink %.*s ", info.fake.len, info.fake.fname));
-
-	/*
-	 * Note! If this is a hardlink and the names are aliased,
-	 * the short-name lookup will return the hardlink dentry.
-	 * In order to get the correct (real) inode, we just drop
-	 * the original dentry.
-	 */ 
-	if (info.entry.flags & UMSDOS_HLINK) {
-		d_drop(dentry);
-	}
-
-	/* Do a real lookup to get the short name dentry */
-	temp = umsdos_covered(dentry->d_parent, info.fake.fname, info.fake.len);
-	ret = PTR_ERR(temp);
-	if (IS_ERR(temp))
-		goto out_unlock;
-
-	/*
-	 * Resolve hardlinks now, but defer processing until later.
-	 */
-	if (info.entry.flags & UMSDOS_HLINK) {
-		link = umsdos_solve_hlink(dget(temp));
-	}
-
-	/* Delete the EMD entry */
-	ret = umsdos_delentry (dentry->d_parent, &info, 0);
-	if (ret && ret != -ENOENT) {
-		printk(KERN_WARNING "UMSDOS_unlink: delentry %s, error=%d\n",
-			info.entry.name, ret);
-		goto out_dput;
-	}
-
-	ret = msdos_unlink(dir, temp);
-	if (!ret)
-		d_delete(temp);
-#ifdef UMSDOS_PARANOIA
-if (ret)
-printk("umsdos_unlink: %s/%s unlink failed, ret=%d\n",
-temp->d_parent->d_name.name, temp->d_name.name, ret);
-#endif
-
-	/* dput() temp if we didn't do it above */
-out_dput:
-	dput(temp);
-
-out_unlock:
-	umsdos_unlockcreate (dir);
-
-	/*
-	 * Now check for deferred handling of a hardlink.
-	 */
-	if (!link)
-		goto out;
-
-	if (IS_ERR(link)) {
-printk("umsdos_unlink: failed to resolve %s/%s\n",
-dentry->d_parent->d_name.name, dentry->d_name.name);
-		if (!ret)
-			ret = PTR_ERR(link);
-		goto out;
-	}
-
-Printk(("umsdos_unlink: link %s/%s deferred, pending ret=%d\n",
-link->d_parent->d_name.name, link->d_name.name, ret));
-
-	/* already have an error? */
-	if (ret)
-		goto out_cleanup;
-
-	/* make sure the link exists ... */
-	inode = link->d_inode;
-	if (!inode) {
-		printk(KERN_WARNING "umsdos_unlink: hard link not found\n");
-		goto out_cleanup;
-	}
-
-	/*
-	 * If this was the last linked reference, delete it now.
-	 *
-	 * N.B. Deadlock problem? We should be holding the lock
-	 * for the hardlink's parent, but another process might
-	 * be holding that lock waiting for us to finish ...
-	 */
-	if (inode->i_nlink <= 1) {
-		ret = UMSDOS_unlink (link->d_parent->d_inode, link);
-		if (ret) {
-			printk(KERN_WARNING
-				"umsdos_unlink: link removal failed, ret=%d\n",
-				 ret);
-		} else
-			d_delete(link);
-	} else {
-		struct iattr newattrs;
-		inode->i_nlink--;
-		newattrs.ia_valid = 0;
-		ret = umsdos_notify_change_locked(link, &newattrs);
-		if (!ret)
-			mark_inode_dirty(link->d_inode);
-	}
-
-out_cleanup:
-	d_drop(link);
-	dput(link);
-
-out:
-	Printk (("umsdos_unlink %d\n", ret));
-	return ret;
-}
-
-/*
- * Rename (move) a file.
- */
-int UMSDOS_rename (struct inode *old_dir, struct dentry *old_dentry,
-		   struct inode *new_dir, struct dentry *new_dentry)
-{
-	int ret;
-
-	ret = umsdos_nevercreat (new_dir, new_dentry, -EEXIST);
-	if (ret)
-		return ret;
-
-		/*
-		 * If the target already exists, delete it first.
-		 */
-	if (new_dentry->d_inode) {
-		dget(new_dentry);
-		if (S_ISDIR(old_dentry->d_inode->i_mode))
-			ret = UMSDOS_rmdir (new_dir, new_dentry);
-		else
-			ret = UMSDOS_unlink (new_dir, new_dentry);
-		if (!ret)
-			d_drop(new_dentry);
-		dput(new_dentry);
-		if (ret)
-			return ret;
-	}
-	ret = umsdos_rename_f(old_dir, old_dentry, new_dir, new_dentry, 0);
-	return ret;
-}
diff -Nru a/fs/umsdos/rdir.c b/fs/umsdos/rdir.c
--- a/fs/umsdos/rdir.c	2005-03-01 23:38:53 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,248 +0,0 @@
-/*
- *  linux/fs/umsdos/rdir.c
- *
- *  Written 1994 by Jacques Gelinas
- *
- *  Extended MS-DOS directory pure MS-DOS handling functions
- *  (For directory without EMD file).
- */
-
-#include <linux/time.h>
-#include <linux/fs.h>
-#include <linux/msdos_fs.h>
-#include <linux/errno.h>
-#include <linux/stat.h>
-#include <linux/limits.h>
-#include <linux/umsdos_fs.h>
-#include <linux/slab.h>
-#include <linux/smp_lock.h>
-
-#include <asm/uaccess.h>
-
-
-extern struct dentry *saved_root;
-extern struct inode *pseudo_root;
-extern struct dentry_operations umsdos_dentry_operations;
-
-struct RDIR_FILLDIR {
-	void *dirbuf;
-	filldir_t filldir;
-	int real_root;
-};
-
-static int rdir_filldir (	void *buf,
-				const char *name,
-				int name_len,
-				loff_t offset,
-				ino_t ino,
-				unsigned int d_type)
-{
-	int ret = 0;
-	struct RDIR_FILLDIR *d = (struct RDIR_FILLDIR *) buf;
-
-	if (d->real_root) {
-		PRINTK ((KERN_DEBUG "rdir_filldir /mn/: real root!\n"));
-		/* real root of a pseudo_rooted partition */
-		if (name_len != UMSDOS_PSDROOT_LEN
-		    || memcmp (name, UMSDOS_PSDROOT_NAME, UMSDOS_PSDROOT_LEN) != 0) {
-			/* So it is not the /linux directory */
-			if (name_len == 2 && name[0] == '.' && name[1] == '.') {
-				/* Make sure the .. entry points back to the pseudo_root */
-				ino = pseudo_root->i_ino;
-			}
-			ret = d->filldir (d->dirbuf, name, name_len, offset, ino, DT_UNKNOWN);
-		}
-	} else {
-		/* Any DOS directory */
-		ret = d->filldir (d->dirbuf, name, name_len, offset, ino, DT_UNKNOWN);
-	}
-	return ret;
-}
-
-
-static int UMSDOS_rreaddir (struct file *filp, void *dirbuf, filldir_t filldir)
-{
-	struct inode *dir = filp->f_dentry->d_inode;
-	struct RDIR_FILLDIR bufk;
-	int ret;
-
-	lock_kernel();
-	bufk.filldir = filldir;
-	bufk.dirbuf = dirbuf;
-	bufk.real_root = pseudo_root && (dir == saved_root->d_inode);
-	ret = fat_readdir (filp, &bufk, rdir_filldir);
-	unlock_kernel();
-	return ret;
-}
-
-
-/*
- * Lookup into a non promoted directory.
- * If the result is a directory, make sure we find out if it is
- * a promoted one or not (calling umsdos_setup_dir_inode(inode)).
- */
-/* #Specification: pseudo root / DOS/..
- * In the real root directory (c:\), the directory ..
- * is the pseudo root (c:\linux).
- */
-struct dentry *umsdos_rlookup_x ( struct inode *dir, struct dentry *dentry, int nopseudo)
-{
-	struct dentry *ret;
-
-	if (saved_root && dir == saved_root->d_inode && !nopseudo &&
-	    dentry->d_name.len == UMSDOS_PSDROOT_LEN &&
-	    memcmp (dentry->d_name.name, UMSDOS_PSDROOT_NAME, UMSDOS_PSDROOT_LEN) == 0) {
-		/* #Specification: pseudo root / DOS/linux
-		 * Even in the real root directory (c:\), the directory
-		 * /linux won't show
-		 */
-		 
-		ret = ERR_PTR(-ENOENT);
-		goto out;
-	}
-
-	ret = msdos_lookup (dir, dentry, NULL);
-	if (ret) {
-		printk(KERN_WARNING
-			"umsdos_rlookup_x: %s/%s failed, ret=%ld\n",
-			dentry->d_parent->d_name.name, dentry->d_name.name,
-			PTR_ERR(ret));
-		goto out;
-	}
-	if (dentry->d_inode) {
-		/* We must install the proper function table
-		 * depending on whether this is an MS-DOS or 
-		 * a UMSDOS directory
-		 */
-Printk ((KERN_DEBUG "umsdos_rlookup_x: patch_dentry_inode %s/%s\n",
-dentry->d_parent->d_name.name, dentry->d_name.name));
-/* only patch if needed (because we get called even for lookup
-   (not only rlookup) stuff sometimes, like in umsdos_covered() */
-		if (UMSDOS_I(dentry->d_inode)->i_patched == 0)	
-		umsdos_patch_dentry_inode(dentry, 0);
-
-	}
-out:
-	/* always install our dentry ops ... */
-	dentry->d_op = &umsdos_dentry_operations;
-	return ret;
-}
-
-
-struct dentry *UMSDOS_rlookup ( struct inode *dir, struct dentry *dentry, struct nameidata *nd)
-{
-	return umsdos_rlookup_x (dir, dentry, 0);
-}
-
-
-/* #Specification: dual mode / rmdir in a DOS directory
- * In a DOS (not EMD in it) directory, we use a reverse strategy
- * compared with a UMSDOS directory. We assume that a subdirectory
- * of a DOS directory is also a DOS directory. This is not always
- * true (umssync may be used anywhere), but makes sense.
- * 
- * So we call msdos_rmdir() directly. If it failed with a -ENOTEMPTY
- * then we check if it is a Umsdos directory. We check if it is
- * really empty (only . .. and --linux-.--- in it). If it is true
- * we remove the EMD and do a msdos_rmdir() again.
- * 
- * In a Umsdos directory, we assume all subdirectories are also
- * Umsdos directories, so we check the EMD file first.
- */
-/* #Specification: pseudo root / rmdir /DOS
- * The pseudo sub-directory /DOS can't be removed!
- * This is done even if the pseudo root is not a Umsdos
- * directory anymore (very unlikely), but an accident (under
- * MS-DOS) is always possible.
- * 
- * EPERM is returned.
- */
-static int UMSDOS_rrmdir ( struct inode *dir, struct dentry *dentry)
-{
-	int ret, empty;
-
-	ret = -EPERM;
-	if (umsdos_is_pseudodos (dir, dentry))
-		goto out;
-
-	ret = -EBUSY;
-	if (!d_unhashed(dentry))
-		goto out;
-
-	ret = msdos_rmdir (dir, dentry);
-	if (ret != -ENOTEMPTY)
-		goto out;
-
-	empty = umsdos_isempty (dentry);
-	if (empty == 1) {
-		struct dentry *demd;
-		/* We have to remove the EMD file. */
-		demd = umsdos_get_emd_dentry(dentry);
-		ret = PTR_ERR(demd);
-		if (!IS_ERR(demd)) {
-			ret = 0;
-			if (demd->d_inode)
-				ret = msdos_unlink (dentry->d_inode, demd);
-			if (!ret)
-				d_delete(demd);
-			dput(demd);
-		}
-	}
-	if (ret)
-		goto out;
-
-	/* now retry the original ... */
-	ret = msdos_rmdir (dir, dentry);
-
-out:
-	return ret;
-}
-
-/* #Specification: dual mode / introduction
- * One goal of UMSDOS is to allow a practical and simple coexistence
- * between MS-DOS and Linux in a single partition. Using the EMD file
- * in each directory, UMSDOS adds Unix semantics and capabilities to
- * a normal DOS filesystem. To help and simplify coexistence, here is
- * the logic related to the EMD file.
- * 
- * If it is missing, then the directory is managed by the MS-DOS driver.
- * The names are limited to DOS limits (8.3). No links, no device special
- * and pipe and so on.
- * 
- * If it is there, it is the directory. If it is there but empty, then
- * the directory looks empty. The utility umssync allows synchronisation
- * of the real DOS directory and the EMD.
- * 
- * Whenever umssync is applied to a directory without EMD, one is
- * created on the fly.  The directory is promoted to full Unix semantics.
- * Of course, the ls command will show exactly the same content as before
- * the umssync session.
- * 
- * It is believed that the user/admin will promote directories to Unix
- * semantics as needed.
- * 
- * The strategy to implement this is to use two function table (struct
- * inode_operations). One for true UMSDOS directory and one for directory
- * with missing EMD.
- * 
- * Functions related to the DOS semantic (but aware of UMSDOS) generally
- * have a "r" prefix (r for real) such as UMSDOS_rlookup, to differentiate
- * from the one with full UMSDOS semantics.
- */
-struct file_operations umsdos_rdir_operations =
-{
-	.read		= generic_read_dir,
-	.readdir	= UMSDOS_rreaddir,
-	.ioctl		= UMSDOS_ioctl_dir,
-};
-
-struct inode_operations umsdos_rdir_inode_operations =
-{
-	.create		= msdos_create,
-	.lookup		= UMSDOS_rlookup,
-	.unlink		= msdos_unlink,
-	.mkdir		= msdos_mkdir,
-	.rmdir		= UMSDOS_rrmdir,
-	.rename		= msdos_rename,
-	.setattr	= UMSDOS_notify_change,
-};
diff -Nru a/fs/umsdos/specs b/fs/umsdos/specs
--- a/fs/umsdos/specs	2005-03-01 23:39:16 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,289 +0,0 @@
-/* #Specification: umsdos / readdir
- * umsdos_readdir() should fill a struct dirent with
- * an inode number. The cheap way to get it is to
- * do a lookup in the MSDOS directory for each
- * entry processed by the readdir() function.
- * This is not very efficient, but very simple. The
- * other way around is to maintain a copy of the inode
- * number in the EMD file. This is a problem because
- * this has to be maintained in sync using tricks.
- * Remember that MSDOS (the OS) does not update the
- * modification time (mtime) of a directory. There is
- * no easy way to tell that a directory was modified
- * during a DOS session and synchronise the EMD file.
- */
-		/* #Specification: readdir / . and ..
-		 * The msdos filesystem manages the . and .. entry properly
-		 * so the EMD file won't hold any info about it.
-		 * 
-		 * In readdir, we assume that for the root directory
-		 * the read position will be 0 for ".", 1 for "..". For
-		 * a non root directory, the read position will be 0 for "."
-		 * and 32 for "..".
-		 */
-		/*
-		 * This is a trick used by the msdos file system (fs/msdos/dir.c)
-		 * to manage . and .. for the root directory of a file system.
-		 * Since there is no such entry in the root, fs/msdos/dir.c
-		 * use the following:
-		 * 
-		 * if f_pos == 0, return ".".
-		 * if f_pos == 1, return "..".
-		 * 
-		 * So let msdos handle it
-		 * 
-		 * Since umsdos entries are much larger, we share the same f_pos.
-		 * if f_pos is 0 or 1 or 32, we are clearly looking at . and
-		 * ..
-		 * 
-		 * As soon as we get f_pos == 2 or f_pos == 64, then back to
-		 * 0, but this time we are reading the EMD file.
-		 * 
-		 * Well, not so true. The problem, is that UMSDOS_REC_SIZE is
-		 * also 64, so as soon as we read the first record in the
-		 * EMD, we are back at offset 64. So we set the offset
-		 * to UMSDOS_SPECIAL_DIRFPOS(3) as soon as we have read the
-		 * .. entry from msdos.
-		 * 
-		 * Now (linux 1.3), umsdos_readdir can read more than one
-		 * entry even if we limit (umsdos_dir_once) to only one:
-		 * It skips over hidden file. So we switch to
-		 * UMSDOS_SPECIAL_DIRFPOS as soon as we have read successfully
-		 * the .. entry.
-		 */
-			/* #Specification: umsdos / lookup / inode info
-			 * After successfully reading an inode from the MSDOS
-			 * filesystem, we use the EMD file to complete it.
-			 * We update the following field.
-			 * 
-			 * uid, gid, atime, ctime, mtime, mode.
-			 * 
-			 * We rely on MSDOS for mtime. If the file
-			 * was modified during an MSDOS session, at least
-			 * mtime will be meaningful. We do this only for regular
-			 * file.
-			 * 
-			 * We don't rely on MS-DOS for mtime for directories
-			 * because the MS-DOS date on a directory is its
-			 * creation time (strange MSDOS behavior) which
-			 * corresponds to none of the three Unix time stamps.
-			 */
-	/* #Specification: umsdos / conversion mode
-	 * The msdos filesystem can do some inline conversion
-	 * of the data of a file.  It can translate silently
-	 * from the MS-DOS text file format to the Unix one
-	 * (CRLF -> LF) while reading, and the reverse
-	 * while writing. This is activated using the mount
-	 * option conv=....
-	 * 
-	 * This is not useful for Linux files in a promoted
-	 * directory.  It can even be harmful.  For this
-	 * reason, the binary (no conversion) mode is
-	 * always activated.
-	 */
-	/* #Specification: umsdos / conversion mode / todo
-	 * A flag could be added to file and directories
-	 * forcing an automatic conversion mode (as
-	 * done with the msdos filesystem).
-	 * 
-	 * This flag could be setup on a directory basis
-	 * (instead of file) and all files in it would
-	 * logically inherit it.  If the conversion mode
-	 * is active (conv=) then the i_binary flag would
-	 * be left untouched in those directories.
-	 * 
-	 * It was proposed that the sticky bit be used to set
-	 * this.  A problem with that is that new files would
-	 * be written incorrectly.  The other problem is that
-	 * the sticky bit has a meaning for directories. So
-	 * another bit should be used (there is some space
-	 * in the EMD file for it) and a special utility
-	 * would be used to assign the flag to a directory).
-	 * I don't think it is useful to assign this flag
-	 * on a single file.
-	 */
- * #Specification: weakness / rename
- * There is a case where UMSDOS rename has a different behavior
- * than a normal Unix file system.  Renaming an open file across
- * directory boundary does not work.  Renaming an open file within
- * a directory does work, however.
- * 
- * The problem may is in Linux VFS driver for msdos.
- * I believe this is not a bug but a design feature, because
- * an inode number represents some sort of directory address
- * in the MSDOS directory structure, so moving the file into
- * another directory does not preserve the inode number.
- */
-/* #Specification: rename / new name exist
- * If the destination name already exists, it will
- * silently be removed.  EXT2 does it this way
- * and this is the spec of SunOS.  So does UMSDOS.
- * 
- * If the destination is an empty directory it will
- * also be removed.
- */
-/* #Specification: rename / new name exist / possible flaw
- * The code to handle the deletion of the target (file
- * and directory) use to be in umsdos_rename_f, surrounded
- * by proper directory locking.  This was ensuring that only
- * one process could achieve a rename (modification) operation
- * in the source and destination directory.  This was also
- * ensuring the operation was "atomic".
- * 
- * This has been changed because this was creating a
- * stack overflow (the stack is only 4 kB) in the kernel.  To avoid
- * the code doing the deletion of the target (if exist) has
- * been moved to a upper layer. umsdos_rename_f is tried
- * once and if it fails with EEXIST, the target is removed
- * and umsdos_rename_f is done again.
- * 
- * This makes the code cleaner and may solve a
- * deadlock problem one tester was experiencing.
- * 
- * The point is to mention that possibly, the semantic of
- * "rename" may be wrong. Anyone dare to check that :-)
- * Be aware that IF it is wrong, to produce the problem you
- * will need two process trying to rename a file to the
- * same target at the same time. Again, I am not sure it
- * is a problem at all.
- */
-
-/* #Specification: hard link / strategy
- * Hard links are difficult to implement on top of an MS-DOS FAT file
- * system. Unlike Unix file systems, there are no inodes. A directory
- * entry holds the functionality of the inode and the entry.
- * 
- * We will used the same strategy as a normal Unix file system
- * (with inodes) except we will do it symbolically (using paths).
- * 
- * Because anything can happen during a DOS session (defragment,
- * directory sorting, etc.), we can't rely on an MS-DOS pseudo
- * inode number to record the link. For this reason, the link
- * will be done using hidden symbolic links. The following
- * scenario illustrates how it works.
- * 
- * Given a file /foo/file
- * 
- * #
- * ln /foo/file /tmp/file2
- * 
- * become internally
- * 
- * mv /foo/file /foo/-LINK1
- * ln -s /foo/-LINK1 /foo/file
- * ln -s /foo/-LINK1 /tmp/file2
- * #
- * 
- * Using this strategy, we can operate on /foo/file or /foo/file2.
- * We can remove one and keep the other, like a normal Unix hard link.
- * We can rename /foo/file or /tmp/file2 independently.
- * 
- * The entry -LINK1 will be hidden. It will hold a link count.
- * When all link are erased, the hidden file is erased too.
- */
-
-/* #Specification: weakness / hard link
- * The strategy for hard link introduces a side effect that
- * may or may not be acceptable. Here is the sequence
- * 
- * #
- * mkdir subdir1
- * touch subdir1/file
- * mkdir subdir2
- * ln    subdir1/file subdir2/file
- * rm    subdir1/file
- * rmdir subdir1
- * rmdir: subdir1: Directory not empty
- * #
- * 
- * This happen because there is an invisible file (--link) in
- * subdir1 which is referenced by subdir2/file.
- * 
- * Any idea ?
- */
-/* #Specification: weakness / hard link / rename directory
- * Another weakness of hard link come from the fact that
- * it is based on hidden symbolic links. Here is an example.
- * 
- * #
- * mkdir /subdir1
- * touch /subdir1/file
- * mkdir /subdir2
- * ln    /subdir1/file subdir2/file
- * mv    /subdir1 subdir3
- * ls -l /subdir2/file
- * #
- * 
- * Since /subdir2/file is a hidden symbolic link
- * to /subdir1/..hlinkNNN, accessing it will fail since
- * /subdir1 does not exist anymore (has been renamed).
- */
-/* #Specification: hard link / directory
- * A hard link can't be made on a directory. EPERM is returned
- * in this case.
- */
-/* #Specification: hard link / first hard link
- * The first time a hard link is done on a file, this
- * file must be renamed and hidden. Then an internal
- * symbolic link must be done on the hidden file.
- * 
- * The second link is done after on this hidden file.
- * 
- * It is expected that the Linux MSDOS file system
- * keeps the same pseudo inode when a rename operation
- * is done on a file in the same directory.
- */
-/* #Specification: function name / convention
- * A simple convention for function names has been used in
- * the UMSDOS filesystem. First, all functions use the prefix
- * umsdos_ to avoid name clashes with other parts of the kernel.
- * 
- * Standard VFS entry points use the prefix UMSDOS (upper case)
- * so it's easier to tell them apart.
- * N.B. (FIXME) PTW, the order and contents of this struct changed.
- */
-
-/* #Specification: mount / options
- * Umsdos run on top of msdos. Currently, it supports no
- * mount option, but happily pass all option received to
- * the msdos driver. I am not sure if all msdos mount option
- * make sense with Umsdos. Here are at least those who
- * are useful.
- * uid=
- * gid=
- * 
- * These options affect the operation of umsdos in directories
- * which do not have an EMD file. They behave like normal
- * msdos directory, with all limitation of msdos.
- */
-
-/* #Specification: pseudo root / mount
- * When a umsdos fs is mounted, a special handling is done
- * if it is the root partition. We check for the presence
- * of the file /linux/etc/init or /linux/etc/rc or
- * /linux/sbin/init. If one is there, we do a chroot("/linux").
- * 
- * We check both because (see init/main.c) the kernel
- * try to exec init at different place and if it fails
- * it tries /bin/sh /etc/rc. To be consistent with
- * init/main.c, many more test would have to be done
- * to locate init. Any complain ?
- * 
- * The chroot is done manually in init/main.c but the
- * info (the inode) is located at mount time and store
- * in a global variable (pseudo_root) which is used at
- * different place in the umsdos driver. There is no
- * need to store this variable elsewhere because it
- * will always be one, not one per mount.
- * 
- * This feature allows the installation
- * of a linux system within a DOS system in a subdirectory.
- * 
- * A user may install its linux stuff in c:\linux
- * avoiding any clash with existing DOS file and subdirectory.
- * When linux boots, it hides this fact, showing a normal
- * root directory with /etc /bin /tmp ...
- * 
- * The word "linux" is hardcoded in /usr/include/linux/umsdos_fs.h
- * in the macro UMSDOS_PSDROOT_NAME.
- */
diff -Nru a/fs/vfat/namei.c b/fs/vfat/namei.c
--- a/fs/vfat/namei.c	2005-03-01 23:39:07 -08:00
+++ b/fs/vfat/namei.c	2005-03-01 23:39:07 -08:00
@@ -11,8 +11,8 @@
  *
  *  Short name translation 1999, 2001 by Wolfram Pienkoss <wp@bszh.de>
  *
- *  Support Multibyte character and cleanup by
- *  				OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
+ *  Support Multibyte characters and cleanup by
+ *				OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
  */
 
 #include <linux/module.h>
@@ -25,33 +25,6 @@
 #include <linux/buffer_head.h>
 #include <linux/namei.h>
 
-static int vfat_hashi(struct dentry *parent, struct qstr *qstr);
-static int vfat_hash(struct dentry *parent, struct qstr *qstr);
-static int vfat_cmpi(struct dentry *dentry, struct qstr *a, struct qstr *b);
-static int vfat_cmp(struct dentry *dentry, struct qstr *a, struct qstr *b);
-static int vfat_revalidate(struct dentry *dentry, struct nameidata *nd);
-
-static struct dentry_operations vfat_dentry_ops[4] = {
-	{
-		.d_hash		= vfat_hashi,
-		.d_compare	= vfat_cmpi,
-	},
-	{
-		.d_revalidate	= vfat_revalidate,
-		.d_hash		= vfat_hashi,
-		.d_compare	= vfat_cmpi,
-	},
-	{
-		.d_hash		= vfat_hash,
-		.d_compare	= vfat_cmp,
-	},
-	{
-		.d_revalidate	= vfat_revalidate,
-		.d_hash		= vfat_hash,
-		.d_compare	= vfat_cmp,
-	}
-};
-
 static int vfat_revalidate(struct dentry *dentry, struct nameidata *nd)
 {
 	int ret = 1;
@@ -78,9 +51,8 @@
 {
 	unsigned int len = qstr->len;
 
-	while (len && qstr->name[len-1] == '.')
+	while (len && qstr->name[len - 1] == '.')
 		len--;
-
 	return len;
 }
 
@@ -93,7 +65,6 @@
 static int vfat_hash(struct dentry *dentry, struct qstr *qstr)
 {
 	qstr->hash = full_name_hash(qstr->name, vfat_striptail_len(qstr));
-
 	return 0;
 }
 
@@ -156,53 +127,64 @@
 	return 1;
 }
 
-/* Characters that are undesirable in an MS-DOS file name */
-
-static wchar_t bad_chars[] = {
-	/*  `*'     `?'     `<'    `>'      `|'     `"'     `:'     `/' */
-	0x002A, 0x003F, 0x003C, 0x003E, 0x007C, 0x0022, 0x003A, 0x002F,
-	/*  `\' */
-	0x005C, 0,
+static struct dentry_operations vfat_dentry_ops[4] = {
+	{
+		.d_hash		= vfat_hashi,
+		.d_compare	= vfat_cmpi,
+	},
+	{
+		.d_revalidate	= vfat_revalidate,
+		.d_hash		= vfat_hashi,
+		.d_compare	= vfat_cmpi,
+	},
+	{
+		.d_hash		= vfat_hash,
+		.d_compare	= vfat_cmp,
+	},
+	{
+		.d_revalidate	= vfat_revalidate,
+		.d_hash		= vfat_hash,
+		.d_compare	= vfat_cmp,
+	}
 };
-#define IS_BADCHAR(uni)	(vfat_unistrchr(bad_chars, (uni)) != NULL)
 
-static wchar_t replace_chars[] = {
-	/*  `['     `]'    `;'     `,'     `+'      `=' */
-	0x005B, 0x005D, 0x003B, 0x002C, 0x002B, 0x003D, 0,
-};
-#define IS_REPLACECHAR(uni)	(vfat_unistrchr(replace_chars, (uni)) != NULL)
+/* Characters that are undesirable in an MS-DOS file name */
 
-static wchar_t skip_chars[] = {
-	/*  `.'     ` ' */
-	0x002E, 0x0020, 0,
-};
-#define IS_SKIPCHAR(uni) \
-	((wchar_t)(uni) == skip_chars[0] || (wchar_t)(uni) == skip_chars[1])
+static inline wchar_t vfat_bad_char(wchar_t w)
+{
+	return (w < 0x0020)
+	    || (w == '*') || (w == '?') || (w == '<') || (w == '>')
+	    || (w == '|') || (w == '"') || (w == ':') || (w == '/')
+	    || (w == '\\');
+}
+
+static inline wchar_t vfat_replace_char(wchar_t w)
+{
+	return (w == '[') || (w == ']') || (w == ';') || (w == ',')
+	    || (w == '+') || (w == '=');
+}
 
-static inline wchar_t *vfat_unistrchr(const wchar_t *s, const wchar_t c)
+static wchar_t vfat_skip_char(wchar_t w)
 {
-	for(; *s != c; ++s)
-		if (*s == 0)
-			return NULL;
-	return (wchar_t *) s;
+	return (w == '.') || (w == ' ');
 }
 
 static inline int vfat_is_used_badchars(const wchar_t *s, int len)
 {
 	int i;
-	
+
 	for (i = 0; i < len; i++)
-		if (s[i] < 0x0020 || IS_BADCHAR(s[i]))
+		if (vfat_bad_char(s[i]))
 			return -EINVAL;
 	return 0;
 }
 
 static int vfat_valid_longname(const unsigned char *name, unsigned int len)
 {
-	if (len && name[len-1] == ' ')
-		return 0;
+	if (name[len - 1] == ' ')
+		return -EINVAL;
 	if (len >= 256)
-		return 0;
+		return -ENAMETOOLONG;
 
 	/* MS-DOS "device special files" */
 	if (len == 3 || (len > 3 && name[3] == '.')) {	/* basename == 3 */
@@ -210,18 +192,18 @@
 		    !strnicmp(name, "con", 3) ||
 		    !strnicmp(name, "nul", 3) ||
 		    !strnicmp(name, "prn", 3))
-			return 0;
+			return -EINVAL;
 	}
 	if (len == 4 || (len > 4 && name[4] == '.')) {	/* basename == 4 */
 		/* "com1", "com2", ... */
 		if ('1' <= name[3] && name[3] <= '9') {
 			if (!strnicmp(name, "com", 3) ||
 			    !strnicmp(name, "lpt", 3))
-				return 0;
+				return -EINVAL;
 		}
 	}
 
-	return 1;
+	return 0;
 }
 
 static int vfat_find_form(struct inode *dir, unsigned char *name)
@@ -238,7 +220,7 @@
 	return 0;
 }
 
-/* 
+/*
  * 1) Valid characters for the 8.3 format alias are any combination of
  * letters, uppercase alphabets, digits, any of the
  * following special characters:
@@ -248,11 +230,11 @@
  * WinNT's Extension:
  * File name and extension name is contain uppercase/lowercase
  * only. And it is expressed by CASE_LOWER_BASE and CASE_LOWER_EXT.
- *     
+ *
  * 2) File name is 8.3 format, but it contain the uppercase and
  * lowercase char, muliti bytes char, etc. In this case numtail is not
  * added, but Longfilename is stored.
- * 
+ *
  * 3) When the one except for the above, or the following special
  * character are contained:
  *        .   [ ] ; , + =
@@ -269,38 +251,22 @@
 	(x)->valid = 1;				\
 } while (0)
 
-static inline unsigned char
-shortname_info_to_lcase(struct shortname_info *base,
-			struct shortname_info *ext)
-{
-	unsigned char lcase = 0;
-
-	if (base->valid && ext->valid) {
-		if (!base->upper && base->lower && (ext->lower || ext->upper))
-			lcase |= CASE_LOWER_BASE;
-		if (!ext->upper && ext->lower && (base->lower || base->upper))
-			lcase |= CASE_LOWER_EXT;
-	}
-
-	return lcase;
-}
-
 static inline int to_shortname_char(struct nls_table *nls,
-				    unsigned char *buf, int buf_size, wchar_t *src,
-				    struct shortname_info *info)
+				    unsigned char *buf, int buf_size,
+				    wchar_t *src, struct shortname_info *info)
 {
 	int len;
 
-	if (IS_SKIPCHAR(*src)) {
+	if (vfat_skip_char(*src)) {
 		info->valid = 0;
 		return 0;
 	}
-	if (IS_REPLACECHAR(*src)) {
+	if (vfat_replace_char(*src)) {
 		info->valid = 0;
 		buf[0] = '_';
 		return 1;
 	}
-	
+
 	len = nls->uni2char(*src, buf, buf_size);
 	if (len <= 0) {
 		info->valid = 0;
@@ -325,7 +291,7 @@
 		info->lower = 0;
 		info->upper = 0;
 	}
-	
+
 	return len;
 }
 
@@ -355,7 +321,7 @@
 	/* Now, we need to create a shortname from the long name */
 	ext_start = end = &uname[ulen];
 	while (--ext_start >= uname) {
-		if (*ext_start == 0x002E) { /* is `.' */
+		if (*ext_start == 0x002E) {	/* is `.' */
 			if (ext_start == end - 1) {
 				sz = ulen;
 				ext_start = NULL;
@@ -375,7 +341,7 @@
 		 */
 		name_start = &uname[0];
 		while (name_start < ext_start) {
-			if (!IS_SKIPCHAR(*name_start))
+			if (!vfat_skip_char(*name_start))
 				break;
 			name_start++;
 		}
@@ -384,7 +350,7 @@
 			ext_start++;
 		} else {
 			sz = ulen;
-			ext_start=NULL;
+			ext_start = NULL;
 		}
 	}
 
@@ -400,7 +366,7 @@
 			numtail2_baselen = baselen;
 		if (baselen < 6 && (baselen + chl) > 6)
 			numtail_baselen = baselen;
-		for (chi = 0; chi < chl; chi++){
+		for (chi = 0; chi < chl; chi++) {
 			*p++ = charbuf[chi];
 			baselen++;
 			if (baselen >= 8)
@@ -462,10 +428,12 @@
 		if (opt_shortname & VFAT_SFN_CREATE_WIN95) {
 			return (base_info.upper && ext_info.upper);
 		} else if (opt_shortname & VFAT_SFN_CREATE_WINNT) {
-			if ((base_info.upper || base_info.lower)
-			    && (ext_info.upper || ext_info.lower)) {
-				*lcase = shortname_info_to_lcase(&base_info,
-								 &ext_info);
+			if ((base_info.upper || base_info.lower) &&
+			    (ext_info.upper || ext_info.lower)) {
+				if (!base_info.upper && base_info.lower)
+					*lcase |= CASE_LOWER_BASE;
+				if (!ext_info.upper && ext_info.lower)
+					*lcase |= CASE_LOWER_EXT;
 				return 1;
 			}
 			return 0;
@@ -473,7 +441,7 @@
 			BUG();
 		}
 	}
-	
+
 	if (MSDOS_SB(dir->i_sb)->options.numtail == 0)
 		if (vfat_find_form(dir, name_res) < 0)
 			return 0;
@@ -486,25 +454,25 @@
 	 * values for part of the base.
 	 */
 
-	if (baselen>6) {
+	if (baselen > 6) {
 		baselen = numtail_baselen;
 		name_res[7] = ' ';
 	}
 	name_res[baselen] = '~';
 	for (i = 1; i < 10; i++) {
-		name_res[baselen+1] = i + '0';
+		name_res[baselen + 1] = i + '0';
 		if (vfat_find_form(dir, name_res) < 0)
 			return 0;
 	}
 
 	i = jiffies & 0xffff;
 	sz = (jiffies >> 16) & 0x7;
-	if (baselen>2) {
+	if (baselen > 2) {
 		baselen = numtail2_baselen;
 		name_res[7] = ' ';
 	}
-	name_res[baselen+4] = '~';
-	name_res[baselen+5] = '1' + sz;
+	name_res[baselen + 4] = '~';
+	name_res[baselen + 5] = '1' + sz;
 	while (1) {
 		sprintf(buf, "%04X", i);
 		memcpy(&name_res[baselen], buf, 4);
@@ -537,13 +505,14 @@
 		 * We stripped '.'s before and set len appropriately,
 		 * but utf8_mbstowcs doesn't care about len
 		 */
-		*outlen -= (name_len-len);
+		*outlen -= (name_len - len);
 
 		op = &outname[*outlen * sizeof(wchar_t)];
 	} else {
 		if (nls) {
 			for (i = 0, ip = name, op = outname, *outlen = 0;
-			     i < len && *outlen <= 260; *outlen += 1)
+			     i < len && *outlen <= 260;
+			     *outlen += 1)
 			{
 				if (escape && (*ip == ':')) {
 					if (i > len - 5)
@@ -571,7 +540,7 @@
 					ip += 5;
 					i += 5;
 				} else {
-					if ((charlen = nls->char2uni(ip, len-i, (wchar_t *)op)) < 0)
+					if ((charlen = nls->char2uni(ip, len - i, (wchar_t *)op)) < 0)
 						return -EINVAL;
 					ip += charlen;
 					i += charlen;
@@ -580,7 +549,8 @@
 			}
 		} else {
 			for (i = 0, ip = name, op = outname, *outlen = 0;
-			     i < len && *outlen <= 260; i++, *outlen += 1)
+			     i < len && *outlen <= 260;
+			     i++, *outlen += 1)
 			{
 				*op++ = *ip++;
 				*op++ = 0;
@@ -624,10 +594,12 @@
 	loff_t offset;
 
 	*slots = 0;
-	if (!vfat_valid_longname(name, len))
-		return -EINVAL;
+	res = vfat_valid_longname(name, len);
+	if (res)
+		return res;
 
-	if(!(page = __get_free_page(GFP_KERNEL)))
+	page = __get_free_page(GFP_KERNEL);
+	if (!page)
 		return -ENOMEM;
 
 	uname = (wchar_t *)page;
@@ -652,9 +624,8 @@
 
 	/* build the entry of long file name */
 	*slots = usize / 13;
-	for (cksum = i = 0; i < 11; i++) {
+	for (cksum = i = 0; i < 11; i++)
 		cksum = (((cksum&1)<<7)|((cksum&0xfe)>>1)) + msdos_name[i];
-	}
 
 	for (ps = ds, slot = *slots; slot > 0; slot--, ps++) {
 		ps->id = slot;
@@ -668,7 +639,7 @@
 		fatwchar_to16(ps->name11_12, uname + offset + 11, 2);
 	}
 	ds[0].id |= 0x40;
-	de = (struct msdos_dir_entry *) ps;
+	de = (struct msdos_dir_entry *)ps;
 
 shortname:
 	/* build the entry of 8.3 alias name */
@@ -688,7 +659,7 @@
 	return res;
 }
 
-static int vfat_add_entry(struct inode *dir,struct qstr* qname,
+static int vfat_add_entry(struct inode *dir, struct qstr *qname,
 			  int is_dir, struct vfat_slot_info *sinfo_out,
 			  struct buffer_head **bh, struct msdos_dir_entry **de)
 {
@@ -704,8 +675,7 @@
 	if (len == 0)
 		return -ENOENT;
 
-	dir_slots =
-	       kmalloc(sizeof(struct msdos_dir_slot) * MSDOS_SLOTS, GFP_KERNEL);
+	dir_slots = kmalloc(sizeof(*dir_slots) * MSDOS_SLOTS, GFP_KERNEL);
 	if (dir_slots == NULL)
 		return -ENOMEM;
 
@@ -715,7 +685,8 @@
 		goto cleanup;
 
 	/* build the empty directory entry of number of slots */
-	offset = fat_add_entries(dir, slots, &dummy_bh, &dummy_de, &dummy_i_pos);
+	offset =
+	    fat_add_entries(dir, slots, &dummy_bh, &dummy_de, &dummy_i_pos);
 	if (offset < 0) {
 		res = offset;
 		goto cleanup;
@@ -735,10 +706,11 @@
 
 	res = 0;
 	/* update timestamp */
-	dir->i_ctime = dir->i_mtime = dir->i_atime = CURRENT_TIME;
+	dir->i_ctime = dir->i_mtime = dir->i_atime = CURRENT_TIME_SEC;
 	mark_inode_dirty(dir);
 
 	fat_date_unix2dos(dir->i_mtime.tv_sec, &(*de)->time, &(*de)->date);
+	dir->i_mtime.tv_nsec = 0;
 	(*de)->ctime = (*de)->time;
 	(*de)->adate = (*de)->cdate = (*de)->date;
 
@@ -754,9 +726,9 @@
 	return res;
 }
 
-static int vfat_find(struct inode *dir,struct qstr* qname,
-	struct vfat_slot_info *sinfo, struct buffer_head **last_bh,
-	struct msdos_dir_entry **last_de)
+static int vfat_find(struct inode *dir, struct qstr *qname,
+		     struct vfat_slot_info *sinfo, struct buffer_head **last_bh,
+		     struct msdos_dir_entry **last_de)
 {
 	struct super_block *sb = dir->i_sb;
 	loff_t offset;
@@ -770,17 +742,17 @@
 	res = fat_search_long(dir, qname->name, len,
 			      (MSDOS_SB(sb)->options.name_check != 's'),
 			      &offset, &sinfo->longname_offset);
-	if (res>0) {
-		sinfo->long_slots = res-1;
-		if (fat_get_entry(dir,&offset,last_bh,last_de,&sinfo->i_pos)>=0)
+	if (res > 0) {
+		sinfo->long_slots = res - 1;
+		if (fat_get_entry(dir, &offset, last_bh, last_de, &sinfo->i_pos) >= 0)
 			return 0;
 		res = -EIO;
-	} 
+	}
 	return res ? res : -ENOENT;
 }
 
 static struct dentry *vfat_lookup(struct inode *dir, struct dentry *dentry,
-		struct nameidata *nd)
+				  struct nameidata *nd)
 {
 	int res;
 	struct vfat_slot_info sinfo;
@@ -789,13 +761,13 @@
 	struct buffer_head *bh = NULL;
 	struct msdos_dir_entry *de;
 	int table;
-	
+
 	lock_kernel();
 	table = (MSDOS_SB(dir->i_sb)->options.name_check == 's') ? 2 : 0;
 	dentry->d_op = &vfat_dentry_ops[table];
 
 	inode = NULL;
-	res = vfat_find(dir,&dentry->d_name,&sinfo,&bh,&de);
+	res = vfat_find(dir, &dentry->d_name, &sinfo, &bh, &de);
 	if (res < 0) {
 		table++;
 		goto error;
@@ -808,14 +780,14 @@
 	}
 	alias = d_find_alias(inode);
 	if (alias) {
-		if (d_invalidate(alias)==0)
+		if (d_invalidate(alias) == 0)
 			dput(alias);
 		else {
 			iput(inode);
 			unlock_kernel();
 			return alias;
 		}
-		
+
 	}
 error:
 	unlock_kernel();
@@ -829,8 +801,8 @@
 	return dentry;
 }
 
-static int vfat_create(struct inode *dir, struct dentry* dentry, int mode,
-		struct nameidata *nd)
+static int vfat_create(struct inode *dir, struct dentry *dentry, int mode,
+		       struct nameidata *nd)
 {
 	struct super_block *sb = dir->i_sb;
 	struct inode *inode = NULL;
@@ -848,31 +820,33 @@
 	if (!inode)
 		goto out;
 	res = 0;
-	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
+	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
 	mark_inode_dirty(inode);
 	inode->i_version++;
 	dir->i_version++;
 	dentry->d_time = dentry->d_parent->d_inode->i_version;
-	d_instantiate(dentry,inode);
+	d_instantiate(dentry, inode);
 out:
 	unlock_kernel();
 	return res;
 }
 
-static void vfat_remove_entry(struct inode *dir,struct vfat_slot_info *sinfo,
-     struct buffer_head *bh, struct msdos_dir_entry *de)
+static void vfat_remove_entry(struct inode *dir, struct vfat_slot_info *sinfo,
+			      struct buffer_head *bh,
+			      struct msdos_dir_entry *de)
 {
 	loff_t offset, i_pos;
 	int i;
 
 	/* remove the shortname */
-	dir->i_mtime = dir->i_atime = CURRENT_TIME;
+	dir->i_mtime = dir->i_atime = CURRENT_TIME_SEC;
 	dir->i_version++;
 	mark_inode_dirty(dir);
 	de->name[0] = DELETED_FLAG;
 	mark_buffer_dirty(bh);
 	/* remove the longname */
-	offset = sinfo->longname_offset; de = NULL;
+	offset = sinfo->longname_offset;
+	de = NULL;
 	for (i = sinfo->long_slots; i > 0; --i) {
 		if (fat_get_entry(dir, &offset, &bh, &de, &i_pos) < 0)
 			continue;
@@ -883,28 +857,30 @@
 	brelse(bh);
 }
 
-static int vfat_rmdir(struct inode *dir, struct dentry* dentry)
+static int vfat_rmdir(struct inode *dir, struct dentry *dentry)
 {
-	int res;
+	struct inode *inode = dentry->d_inode;
 	struct vfat_slot_info sinfo;
 	struct buffer_head *bh = NULL;
 	struct msdos_dir_entry *de;
+	int res;
 
 	lock_kernel();
-	res = fat_dir_empty(dentry->d_inode);
+	res = fat_dir_empty(inode);
 	if (res)
 		goto out;
 
-	res = vfat_find(dir,&dentry->d_name,&sinfo, &bh, &de);
+	res = vfat_find(dir, &dentry->d_name, &sinfo, &bh, &de);
 	if (res < 0)
 		goto out;
+
 	res = 0;
-	dentry->d_inode->i_nlink = 0;
-	dentry->d_inode->i_mtime = dentry->d_inode->i_atime = CURRENT_TIME;
-	fat_detach(dentry->d_inode);
-	mark_inode_dirty(dentry->d_inode);
+	inode->i_nlink = 0;
+	inode->i_mtime = inode->i_atime = CURRENT_TIME_SEC;
+	fat_detach(inode);
+	mark_inode_dirty(inode);
 	/* releases bh */
-	vfat_remove_entry(dir,&sinfo,bh,de);
+	vfat_remove_entry(dir, &sinfo, bh, de);
 	dir->i_nlink--;
 out:
 	unlock_kernel();
@@ -913,28 +889,29 @@
 
 static int vfat_unlink(struct inode *dir, struct dentry *dentry)
 {
-	int res;
+	struct inode *inode = dentry->d_inode;
 	struct vfat_slot_info sinfo;
 	struct buffer_head *bh = NULL;
 	struct msdos_dir_entry *de;
+	int res;
 
 	lock_kernel();
-	res = vfat_find(dir,&dentry->d_name,&sinfo,&bh,&de);
+	res = vfat_find(dir, &dentry->d_name, &sinfo, &bh, &de);
 	if (res < 0)
 		goto out;
-	dentry->d_inode->i_nlink = 0;
-	dentry->d_inode->i_mtime = dentry->d_inode->i_atime = CURRENT_TIME;
-	fat_detach(dentry->d_inode);
-	mark_inode_dirty(dentry->d_inode);
+	inode->i_nlink = 0;
+	inode->i_mtime = inode->i_atime = CURRENT_TIME_SEC;
+	fat_detach(inode);
+	mark_inode_dirty(inode);
 	/* releases bh */
-	vfat_remove_entry(dir,&sinfo,bh,de);
+	vfat_remove_entry(dir, &sinfo, bh, de);
 out:
 	unlock_kernel();
 
 	return res;
 }
 
-static int vfat_mkdir(struct inode *dir,struct dentry* dentry,int mode)
+static int vfat_mkdir(struct inode *dir, struct dentry *dentry, int mode)
 {
 	struct super_block *sb = dir->i_sb;
 	struct inode *inode = NULL;
@@ -950,17 +927,17 @@
 	inode = fat_build_inode(sb, de, sinfo.i_pos, &res);
 	if (!inode)
 		goto out_brelse;
-	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
+	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
 	mark_inode_dirty(inode);
 	inode->i_version++;
 	dir->i_version++;
 	dir->i_nlink++;
-	inode->i_nlink = 2; /* no need to mark them dirty */
+	inode->i_nlink = 2;	/* no need to mark them dirty */
 	res = fat_new_dir(inode, dir, 1);
 	if (res < 0)
 		goto mkdir_failed;
 	dentry->d_time = dentry->d_parent->d_inode->i_version;
-	d_instantiate(dentry,inode);
+	d_instantiate(dentry, inode);
 out_brelse:
 	brelse(bh);
 out:
@@ -969,31 +946,32 @@
 
 mkdir_failed:
 	inode->i_nlink = 0;
-	inode->i_mtime = inode->i_atime = CURRENT_TIME;
+	inode->i_mtime = inode->i_atime = CURRENT_TIME_SEC;
 	fat_detach(inode);
 	mark_inode_dirty(inode);
 	/* releases bh */
-	vfat_remove_entry(dir,&sinfo,bh,de);
+	vfat_remove_entry(dir, &sinfo, bh, de);
 	iput(inode);
 	dir->i_nlink--;
 	goto out;
 }
- 
+
 static int vfat_rename(struct inode *old_dir, struct dentry *old_dentry,
-		struct inode *new_dir, struct dentry *new_dentry)
+		       struct inode *new_dir, struct dentry *new_dentry)
 {
-	struct buffer_head *old_bh,*new_bh,*dotdot_bh;
-	struct msdos_dir_entry *old_de,*new_de,*dotdot_de;
+	struct buffer_head *old_bh, *new_bh, *dotdot_bh;
+	struct msdos_dir_entry *old_de, *new_de, *dotdot_de;
 	loff_t dotdot_i_pos;
 	struct inode *old_inode, *new_inode;
 	int res, is_dir;
-	struct vfat_slot_info old_sinfo,sinfo;
+	struct vfat_slot_info old_sinfo, sinfo;
 
 	old_bh = new_bh = dotdot_bh = NULL;
 	old_inode = old_dentry->d_inode;
 	new_inode = new_dentry->d_inode;
 	lock_kernel();
-	res = vfat_find(old_dir,&old_dentry->d_name,&old_sinfo,&old_bh,&old_de);
+	res = vfat_find(old_dir, &old_dentry->d_name, &old_sinfo, &old_bh,
+			&old_de);
 	if (res < 0)
 		goto rename_done;
 
@@ -1008,7 +986,7 @@
 	}
 
 	if (new_dentry->d_inode) {
-		res = vfat_find(new_dir,&new_dentry->d_name,&sinfo,&new_bh,
+		res = vfat_find(new_dir, &new_dentry->d_name, &sinfo, &new_bh,
 				&new_de);
 		if (res < 0 || MSDOS_I(new_inode)->i_pos != sinfo.i_pos) {
 			/* WTF??? Cry and fail. */
@@ -1023,26 +1001,27 @@
 		}
 		fat_detach(new_inode);
 	} else {
-		res = vfat_add_entry(new_dir,&new_dentry->d_name,is_dir,&sinfo,
-					&new_bh,&new_de);
-		if (res < 0) goto rename_done;
+		res = vfat_add_entry(new_dir, &new_dentry->d_name, is_dir,
+				     &sinfo, &new_bh, &new_de);
+		if (res < 0)
+			goto rename_done;
 	}
 
 	new_dir->i_version++;
 
 	/* releases old_bh */
-	vfat_remove_entry(old_dir,&old_sinfo,old_bh,old_de);
-	old_bh=NULL;
+	vfat_remove_entry(old_dir, &old_sinfo, old_bh, old_de);
+	old_bh = NULL;
 	fat_detach(old_inode);
 	fat_attach(old_inode, sinfo.i_pos);
 	mark_inode_dirty(old_inode);
 
 	old_dir->i_version++;
-	old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
+	old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME_SEC;
 	mark_inode_dirty(old_dir);
 	if (new_inode) {
 		new_inode->i_nlink--;
-		new_inode->i_ctime=CURRENT_TIME;
+		new_inode->i_ctime = CURRENT_TIME_SEC;
 	}
 
 	if (is_dir) {
@@ -1065,7 +1044,6 @@
 	brelse(new_bh);
 	unlock_kernel();
 	return res;
-
 }
 
 static struct inode_operations vfat_dir_inode_operations = {
@@ -1095,7 +1073,8 @@
 }
 
 static struct super_block *vfat_get_sb(struct file_system_type *fs_type,
-	int flags, const char *dev_name, void *data)
+				       int flags, const char *dev_name,
+				       void *data)
 {
 	return get_sb_bdev(fs_type, flags, dev_name, data, vfat_fill_super);
 }
diff -Nru a/fs/xfs/Kconfig b/fs/xfs/Kconfig
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/fs/xfs/Kconfig	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,85 @@
+menu "XFS support"
+
+config XFS_FS
+	tristate "XFS filesystem support"
+	select EXPORTFS if NFSD!=n
+	help
+	  XFS is a high performance journaling filesystem which originated
+	  on the SGI IRIX platform.  It is completely multi-threaded, can
+	  support large files and large filesystems, extended attributes,
+	  variable block sizes, is extent based, and makes extensive use of
+	  Btrees (directories, extents, free space) to aid both performance
+	  and scalability.
+
+	  Refer to the documentation at <http://oss.sgi.com/projects/xfs/>
+	  for complete details.  This implementation is on-disk compatible
+	  with the IRIX version of XFS.
+
+	  To compile this file system support as a module, choose M here: the
+	  module will be called xfs.  Be aware, however, that if the file
+	  system of your root partition is compiled as a module, you'll need
+	  to use an initial ramdisk (initrd) to boot.
+
+config XFS_EXPORT
+	bool
+	default y if XFS_FS && EXPORTFS
+
+config XFS_RT
+	bool "Realtime support (EXPERIMENTAL)"
+	depends on XFS_FS && EXPERIMENTAL
+	help
+	  If you say Y here you will be able to mount and use XFS filesystems
+	  which contain a realtime subvolume. The realtime subvolume is a
+	  separate area of disk space where only file data is stored. The
+	  realtime subvolume is designed to provide very deterministic
+	  data rates suitable for media streaming applications.
+
+	  See the xfs man page in section 5 for a bit more information.
+
+	  This feature is unsupported at this time, is not yet fully
+	  functional, and may cause serious problems.
+
+	  If unsure, say N.
+
+config XFS_QUOTA
+	bool "Quota support"
+	depends on XFS_FS
+	help
+	  If you say Y here, you will be able to set limits for disk usage on
+	  a per user and/or a per group basis under XFS.  XFS considers quota
+	  information as filesystem metadata and uses journaling to provide a
+	  higher level guarantee of consistency.  The on-disk data format for
+	  quota is also compatible with the IRIX version of XFS, allowing a
+	  filesystem to be migrated between Linux and IRIX without any need
+	  for conversion.
+
+	  If unsure, say N.  More comprehensive documentation can be found in
+	  README.quota in the xfsprogs package.  XFS quota can be used either
+	  with or without the generic quota support enabled (CONFIG_QUOTA) -
+	  they are completely independent subsystems.
+
+config XFS_SECURITY
+	bool "Security Label support"
+	depends on XFS_FS
+	help
+	  Security labels support alternative access control models
+	  implemented by security modules like SELinux.  This option
+	  enables an extended attribute namespace for inode security
+	  labels in the XFS filesystem.
+
+	  If you are not using a security module that requires using
+	  extended attributes for inode security labels, say N.
+
+config XFS_POSIX_ACL
+	bool "POSIX ACL support"
+	depends on XFS_FS
+	help
+	  POSIX Access Control Lists (ACLs) support permissions for users and
+	  groups beyond the owner/group/world scheme.
+
+	  To learn more about Access Control Lists, visit the POSIX ACLs for
+	  Linux website <http://acl.bestbits.at/>.
+
+	  If you don't know what Access Control Lists are, say N.
+
+endmenu
diff -Nru a/fs/xfs/Makefile b/fs/xfs/Makefile
--- a/fs/xfs/Makefile	2005-03-01 23:39:08 -08:00
+++ b/fs/xfs/Makefile	2005-03-01 23:39:08 -08:00
@@ -70,6 +70,7 @@
 xfs-$(CONFIG_PROC_FS)		+= linux-2.6/xfs_stats.o
 xfs-$(CONFIG_SYSCTL)		+= linux-2.6/xfs_sysctl.o
 xfs-$(CONFIG_COMPAT)		+= linux-2.6/xfs_ioctl32.o
+xfs-$(CONFIG_XFS_EXPORT)	+= linux-2.6/xfs_export.o
 
 
 xfs-y				+= xfs_alloc.o \
diff -Nru a/fs/xfs/linux-2.6/kmem.h b/fs/xfs/linux-2.6/kmem.h
--- a/fs/xfs/linux-2.6/kmem.h	2005-03-01 23:39:18 -08:00
+++ b/fs/xfs/linux-2.6/kmem.h	2005-03-01 23:39:18 -08:00
@@ -94,9 +94,9 @@
 #endif
 
 	if (flags & KM_NOSLEEP) {
-		lflags = GFP_ATOMIC;
+		lflags |= GFP_ATOMIC;
 	} else {
-		lflags = GFP_KERNEL;
+		lflags |= GFP_KERNEL;
 
 		/* avoid recusive callbacks to filesystem during transactions */
 		if (PFLAGS_TEST_FSTRANS() || (flags & KM_NOFS))
diff -Nru 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	2005-03-01 23:39:16 -08:00
+++ b/fs/xfs/linux-2.6/xfs_aops.c	2005-03-01 23:39:16 -08:00
@@ -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
@@ -71,7 +71,7 @@
 	bhv_desc_t	*bdp;
 	vnode_t		*vp = LINVFS_GET_VP(inode);
 	loff_t		isize = i_size_read(inode);
-	loff_t		offset = page->index << PAGE_CACHE_SHIFT;
+	loff_t		offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
 	int		delalloc = -1, unmapped = -1, unwritten = -1;
 
 	if (page_has_buffers(page))
@@ -156,9 +156,7 @@
 {
 	ASSERT(!private || inode == (struct inode *)private);
 
-	/* private indicates an unwritten extent lay beneath this IO,
-	 * see linvfs_get_block_core.
-	 */
+	/* private indicates an unwritten extent lay beneath this IO */
 	if (private && size > 0) {
 		vnode_t	*vp = LINVFS_GET_VP(inode);
 		int	error;
@@ -728,11 +726,9 @@
 	pgoff_t                 end_index, last_index, tlast;
 	int			len, err, i, cnt = 0, uptodate = 1;
 	int			flags = startio ? 0 : BMAPI_TRYLOCK;
-	int			page_dirty = 1;
-	int                     delalloc = 0;
-
+	int			page_dirty, delalloc = 0;
 
-	/* Are we off the end of the file ? */
+	/* Is this page beyond the end of the file? */
 	offset = i_size_read(inode);
 	end_index = offset >> PAGE_CACHE_SHIFT;
 	last_index = (offset - 1) >> PAGE_CACHE_SHIFT;
@@ -751,7 +747,13 @@
 	bh = head = page_buffers(page);
 	iomp = NULL;
 
+	/*
+	 * page_dirty is initially a count of buffers on the page and
+	 * is decrememted as we move each into a cleanable state.
+	 */
 	len = bh->b_size;
+	page_dirty = PAGE_CACHE_SIZE / len;
+
 	do {
 		if (offset >= end_offset)
 			break;
@@ -794,7 +796,7 @@
 				}
 				BUG_ON(!buffer_locked(bh));
 				bh_arr[cnt++] = bh;
-				page_dirty = 0;
+				page_dirty--;
 			}
 		/*
 		 * Second case, allocate space for a delalloc buffer.
@@ -821,7 +823,7 @@
 					unlock_buffer(bh);
 					mark_buffer_dirty(bh);
 				}
-				page_dirty = 0;
+				page_dirty--;
 			}
 		} else if ((buffer_uptodate(bh) || PageUptodate(page)) &&
 			   (unmapped || startio)) {
@@ -857,13 +859,13 @@
 						unlock_buffer(bh);
 						mark_buffer_dirty(bh);
 					}
-					page_dirty = 0;
+					page_dirty--;
 				}
 			} else if (startio) {
 				if (buffer_uptodate(bh) &&
 				    !test_and_set_bit(BH_Lock, &bh->b_state)) {
 					bh_arr[cnt++] = bh;
-					page_dirty = 0;
+					page_dirty--;
 				}
 			}
 		}
@@ -907,7 +909,7 @@
 }
 
 STATIC int
-linvfs_get_block_core(
+__linvfs_get_block(
 	struct inode		*inode,
 	sector_t		iblock,
 	unsigned long		blocks,
@@ -977,10 +979,10 @@
 	if (iomap.iomap_flags & IOMAP_DELAY) {
 		BUG_ON(direct);
 		if (create) {
-			set_buffer_mapped(bh_result);
 			set_buffer_uptodate(bh_result);
+			set_buffer_mapped(bh_result);
+			set_buffer_delay(bh_result);
 		}
-		set_buffer_delay(bh_result);
 	}
 
 	if (blocks) {
@@ -999,7 +1001,7 @@
 	struct buffer_head	*bh_result,
 	int			create)
 {
-	return linvfs_get_block_core(inode, iblock, 0, bh_result,
+	return __linvfs_get_block(inode, iblock, 0, bh_result,
 					create, 0, BMAPI_WRITE);
 }
 
@@ -1011,7 +1013,7 @@
 	struct buffer_head	*bh_result,
 	int			create)
 {
-	return linvfs_get_block_core(inode, iblock, max_blocks, bh_result,
+	return __linvfs_get_block(inode, iblock, max_blocks, bh_result,
 					create, 1, BMAPI_WRITE|BMAPI_DIRECT);
 }
 
diff -Nru 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	2005-03-01 23:38:51 -08:00
+++ b/fs/xfs/linux-2.6/xfs_buf.c	2005-03-01 23:38:51 -08:00
@@ -51,9 +51,9 @@
 #include <linux/sysctl.h>
 #include <linux/proc_fs.h>
 #include <linux/workqueue.h>
-#include <linux/suspend.h>
 #include <linux/percpu.h>
 #include <linux/blkdev.h>
+#include <linux/hash.h>
 
 #include "xfs_linux.h"
 
@@ -128,34 +128,71 @@
 	kmem_zone_free(pagebuf_cache, (pb));
 
 /*
- * Pagebuf hashing
- */
+ * Page Region interfaces.
+ *
+ * For pages in filesystems where the blocksize is smaller than the
+ * pagesize, we use the page->private field (long) to hold a bitmap
+ * of uptodate regions within the page.
+ *
+ * Each such region is "bytes per page / bits per long" bytes long.
+ *
+ * NBPPR == number-of-bytes-per-page-region
+ * BTOPR == bytes-to-page-region (rounded up)
+ * BTOPRT == bytes-to-page-region-truncated (rounded down)
+ */
+#if (BITS_PER_LONG == 32)
+#define PRSHIFT		(PAGE_CACHE_SHIFT - 5)	/* (32 == 1<<5) */
+#elif (BITS_PER_LONG == 64)
+#define PRSHIFT		(PAGE_CACHE_SHIFT - 6)	/* (64 == 1<<6) */
+#else
+#error BITS_PER_LONG must be 32 or 64
+#endif
+#define NBPPR		(PAGE_CACHE_SIZE/BITS_PER_LONG)
+#define BTOPR(b)	(((unsigned int)(b) + (NBPPR - 1)) >> PRSHIFT)
+#define BTOPRT(b)	(((unsigned int)(b) >> PRSHIFT))
 
-#define NBITS	8
-#define NHASH	(1<<NBITS)
+STATIC unsigned long
+page_region_mask(
+	size_t		offset,
+	size_t		length)
+{
+	unsigned long	mask;
+	int		first, final;
 
-typedef struct {
-	struct list_head	pb_hash;
-	spinlock_t		pb_hash_lock;
-} pb_hash_t;
+	first = BTOPR(offset);
+	final = BTOPRT(offset + length - 1);
+	first = min(first, final);
 
-STATIC pb_hash_t	pbhash[NHASH];
-#define pb_hash(pb)	&pbhash[pb->pb_hash_index]
+	mask = ~0UL;
+	mask <<= BITS_PER_LONG - (final - first);
+	mask >>= BITS_PER_LONG - (final);
 
-STATIC int
-_bhash(
-	struct block_device *bdev,
-	loff_t		base)
-{
-	int		bit, hval;
-
-	base >>= 9;
-	base ^= (unsigned long)bdev / L1_CACHE_BYTES;
-	for (bit = hval = 0; base && bit < sizeof(base) * 8; bit += NBITS) {
-		hval ^= (int)base & (NHASH-1);
-		base >>= NBITS;
-	}
-	return hval;
+	ASSERT(offset + length <= PAGE_CACHE_SIZE);
+	ASSERT((final - first) < BITS_PER_LONG && (final - first) >= 0);
+
+	return mask;
+}
+
+STATIC inline void
+set_page_region(
+	struct page	*page,
+	size_t		offset,
+	size_t		length)
+{
+	page->private |= page_region_mask(offset, length);
+	if (page->private == ~0UL)
+		SetPageUptodate(page);
+}
+
+STATIC inline int
+test_page_region(
+	struct page	*page,
+	size_t		offset,
+	size_t		length)
+{
+	unsigned long	mask = page_region_mask(offset, length);
+
+	return (mask && (page->private & mask) == mask);
 }
 
 /*
@@ -169,7 +206,7 @@
 
 STATIC a_list_t		*as_free_head;
 STATIC int		as_list_len;
-STATIC spinlock_t	as_lock = SPIN_LOCK_UNLOCKED;
+STATIC DEFINE_SPINLOCK(as_lock);
 
 /*
  * Try to batch vunmaps because they are costly.
@@ -180,8 +217,8 @@
 {
 	a_list_t	*aentry;
 
-	aentry = kmalloc(sizeof(a_list_t), GFP_ATOMIC);
-	if (aentry) {
+	aentry = kmalloc(sizeof(a_list_t), GFP_ATOMIC & ~__GFP_HIGH);
+	if (likely(aentry)) {
 		spin_lock(&as_lock);
 		aentry->next = as_free_head;
 		aentry->vm_addr = addr;
@@ -341,7 +378,6 @@
 	uint			flags)
 {
 	struct address_space	*mapping = bp->pb_target->pbr_mapping;
-	unsigned int		sectorshift = bp->pb_target->pbr_sshift;
 	size_t			blocksize = bp->pb_target->pbr_bsize;
 	size_t			size = bp->pb_count_desired;
 	size_t			nbytes, offset;
@@ -401,22 +437,11 @@
 
 		if (!PageUptodate(page)) {
 			page_count--;
-			if (blocksize == PAGE_CACHE_SIZE) {
+			if (blocksize >= PAGE_CACHE_SIZE) {
 				if (flags & PBF_READ)
 					bp->pb_locked = 1;
 			} else if (!PagePrivate(page)) {
-				unsigned long	j, range;
-
-				/*
-				 * In this case page->private holds a bitmap
-				 * of uptodate sectors within the page
-				 */
-				ASSERT(blocksize < PAGE_CACHE_SIZE);
-				range = (offset + nbytes) >> sectorshift;
-				for (j = offset >> sectorshift; j < range; j++)
-					if (!test_bit(j, &page->private))
-						break;
-				if (j == range)
+				if (test_page_region(page, offset, nbytes))
 					page_count++;
 			}
 		}
@@ -484,8 +509,8 @@
  *	are unlocked.  No I/O is implied by this call.
  */
 xfs_buf_t *
-_pagebuf_find(				/* find buffer for block	*/
-	xfs_buftarg_t		*target,/* target for block		*/
+_pagebuf_find(
+	xfs_buftarg_t		*btp,	/* block device target		*/
 	loff_t			ioff,	/* starting offset of range	*/
 	size_t			isize,	/* length of range		*/
 	page_buf_flags_t	flags,	/* PBF_TRYLOCK			*/
@@ -493,59 +518,55 @@
 {
 	loff_t			range_base;
 	size_t			range_length;
-	int			hval;
-	pb_hash_t		*h;
+	xfs_bufhash_t		*hash;
 	xfs_buf_t		*pb, *n;
-	int			not_locked;
 
 	range_base = (ioff << BBSHIFT);
 	range_length = (isize << BBSHIFT);
 
-	/* Ensure we never do IOs smaller than the sector size */
-	BUG_ON(range_length < (1 << target->pbr_sshift));
+	/* Check for IOs smaller than the sector size / not sector aligned */
+	ASSERT(!(range_length < (1 << btp->pbr_sshift)));
+	ASSERT(!(range_base & (loff_t)btp->pbr_smask));
 
-	/* Ensure we never do IOs that are not sector aligned */
-	BUG_ON(range_base & (loff_t)target->pbr_smask);
+	hash = &btp->bt_hash[hash_long((unsigned long)ioff, btp->bt_hashshift)];
 
-	hval = _bhash(target->pbr_bdev, range_base);
-	h = &pbhash[hval];
+	spin_lock(&hash->bh_lock);
 
-	spin_lock(&h->pb_hash_lock);
-	list_for_each_entry_safe(pb, n, &h->pb_hash, pb_hash_list) {
-		if (pb->pb_target == target &&
-		    pb->pb_file_offset == range_base &&
+	list_for_each_entry_safe(pb, n, &hash->bh_list, pb_hash_list) {
+		ASSERT(btp == pb->pb_target);
+		if (pb->pb_file_offset == range_base &&
 		    pb->pb_buffer_length == range_length) {
-			/* If we look at something bring it to the
-			 * front of the list for next time
+			/*
+			 * If we look at something bring it to the
+			 * front of the list for next time.
 			 */
 			atomic_inc(&pb->pb_hold);
-			list_move(&pb->pb_hash_list, &h->pb_hash);
+			list_move(&pb->pb_hash_list, &hash->bh_list);
 			goto found;
 		}
 	}
 
 	/* No match found */
 	if (new_pb) {
-		_pagebuf_initialize(new_pb, target, range_base,
+		_pagebuf_initialize(new_pb, btp, range_base,
 				range_length, flags);
-		new_pb->pb_hash_index = hval;
-		list_add(&new_pb->pb_hash_list, &h->pb_hash);
+		new_pb->pb_hash = hash;
+		list_add(&new_pb->pb_hash_list, &hash->bh_list);
 	} else {
 		XFS_STATS_INC(pb_miss_locked);
 	}
 
-	spin_unlock(&h->pb_hash_lock);
-	return (new_pb);
+	spin_unlock(&hash->bh_lock);
+	return new_pb;
 
 found:
-	spin_unlock(&h->pb_hash_lock);
+	spin_unlock(&hash->bh_lock);
 
 	/* Attempt to get the semaphore without sleeping,
 	 * if this does not work then we need to drop the
 	 * spinlock and do a hard attempt on the semaphore.
 	 */
-	not_locked = down_trylock(&pb->pb_sema);
-	if (not_locked) {
+	if (down_trylock(&pb->pb_sema)) {
 		if (!(flags & PBF_TRYLOCK)) {
 			/* wait for buffer ownership */
 			PB_TRACE(pb, "get_lock", 0);
@@ -712,8 +733,6 @@
 	bdi = target->pbr_mapping->backing_dev_info;
 	if (bdi_read_congested(bdi))
 		return;
-	if (bdi_write_congested(bdi))
-		return;
 
 	flags |= (PBF_TRYLOCK|PBF_ASYNC|PBF_READ_AHEAD);
 	xfs_buf_read_flags(target, ioff, isize, flags);
@@ -867,18 +886,29 @@
 pagebuf_rele(
 	xfs_buf_t		*pb)
 {
-	pb_hash_t		*hash = pb_hash(pb);
+	xfs_bufhash_t		*hash = pb->pb_hash;
 
 	PB_TRACE(pb, "rele", pb->pb_relse);
 
-	if (atomic_dec_and_lock(&pb->pb_hold, &hash->pb_hash_lock)) {
+	/*
+	 * pagebuf_lookup buffers are not hashed, not delayed write,
+	 * and don't have their own release routines.  Special case.
+	 */
+	if (unlikely(!hash)) {
+		ASSERT(!pb->pb_relse);
+		if (atomic_dec_and_test(&pb->pb_hold))
+			xfs_buf_free(pb);
+		return;
+	}
+
+	if (atomic_dec_and_lock(&pb->pb_hold, &hash->bh_lock)) {
 		int		do_free = 1;
 
 		if (pb->pb_relse) {
 			atomic_inc(&pb->pb_hold);
-			spin_unlock(&hash->pb_hash_lock);
+			spin_unlock(&hash->bh_lock);
 			(*(pb->pb_relse)) (pb);
-			spin_lock(&hash->pb_hash_lock);
+			spin_lock(&hash->bh_lock);
 			do_free = 0;
 		}
 
@@ -893,10 +923,10 @@
 
 		if (do_free) {
 			list_del_init(&pb->pb_hash_list);
-			spin_unlock(&hash->pb_hash_lock);
+			spin_unlock(&hash->bh_lock);
 			pagebuf_free(pb);
 		} else {
-			spin_unlock(&hash->pb_hash_lock);
+			spin_unlock(&hash->bh_lock);
 		}
 	}
 }
@@ -936,6 +966,7 @@
 	return(locked ? 0 : -EBUSY);
 }
 
+#ifdef DEBUG
 /*
  *	pagebuf_lock_value
  *
@@ -947,6 +978,7 @@
 {
 	return(atomic_read(&pb->pb_sema.count));
 }
+#endif
 
 /*
  *	pagebuf_lock
@@ -1217,7 +1249,6 @@
 {
 	xfs_buf_t		*pb = (xfs_buf_t *)bio->bi_private;
 	unsigned int		i, blocksize = pb->pb_target->pbr_bsize;
-	unsigned int		sectorshift = pb->pb_target->pbr_sshift;
 	struct bio_vec		*bvec = bio->bi_io_vec;
 
 	if (bio->bi_size)
@@ -1235,14 +1266,7 @@
 			SetPageUptodate(page);
 		} else if (!PagePrivate(page) &&
 				(pb->pb_flags & _PBF_PAGE_CACHE)) {
-			unsigned long	j, range;
-
-			ASSERT(blocksize < PAGE_CACHE_SIZE);
-			range = (bvec->bv_offset + bvec->bv_len) >> sectorshift;
-			for (j = bvec->bv_offset >> sectorshift; j < range; j++)
-				set_bit(j, &page->private);
-			if (page->private == (unsigned long)(PAGE_CACHE_SIZE-1))
-				SetPageUptodate(page);
+			set_page_region(page, bvec->bv_offset, bvec->bv_len);
 		}
 
 		if (_pagebuf_iolocked(pb)) {
@@ -1471,28 +1495,59 @@
  */
 void
 xfs_wait_buftarg(
-	xfs_buftarg_t *target)
+	xfs_buftarg_t	*btp)
 {
-	xfs_buf_t	*pb, *n;
-	pb_hash_t	*h;
-	int		i;
+	xfs_buf_t	*bp, *n;
+	xfs_bufhash_t	*hash;
+	uint		i;
 
-	for (i = 0; i < NHASH; i++) {
-		h = &pbhash[i];
+	for (i = 0; i < (1 << btp->bt_hashshift); i++) {
+		hash = &btp->bt_hash[i];
 again:
-		spin_lock(&h->pb_hash_lock);
-		list_for_each_entry_safe(pb, n, &h->pb_hash, pb_hash_list) {
-			if (pb->pb_target == target &&
-					!(pb->pb_flags & PBF_FS_MANAGED)) {
-				spin_unlock(&h->pb_hash_lock);
+		spin_lock(&hash->bh_lock);
+		list_for_each_entry_safe(bp, n, &hash->bh_list, pb_hash_list) {
+			ASSERT(btp == bp->pb_target);
+			if (!(bp->pb_flags & PBF_FS_MANAGED)) {
+				spin_unlock(&hash->bh_lock);
 				delay(100);
 				goto again;
 			}
 		}
-		spin_unlock(&h->pb_hash_lock);
+		spin_unlock(&hash->bh_lock);
 	}
 }
 
+/*
+ * Allocate buffer hash table for a given target.
+ * For devices containing metadata (i.e. not the log/realtime devices)
+ * we need to allocate a much larger hash table.
+ */
+STATIC void
+xfs_alloc_bufhash(
+	xfs_buftarg_t		*btp,
+	int			external)
+{
+	unsigned int		i;
+
+	btp->bt_hashshift = external ? 3 : 8;	/* 8 or 256 buckets */
+	btp->bt_hashmask = (1 << btp->bt_hashshift) - 1;
+	btp->bt_hash = kmem_zalloc((1 << btp->bt_hashshift) *
+					sizeof(xfs_bufhash_t), KM_SLEEP);
+	for (i = 0; i < (1 << btp->bt_hashshift); i++) {
+		spin_lock_init(&btp->bt_hash[i].bh_lock);
+		INIT_LIST_HEAD(&btp->bt_hash[i].bh_list);
+	}
+}
+
+STATIC void
+xfs_free_bufhash(
+	xfs_buftarg_t		*btp)
+{
+	kmem_free(btp->bt_hash,
+			(1 << btp->bt_hashshift) * sizeof(xfs_bufhash_t));
+	btp->bt_hash = NULL;
+}
+
 void
 xfs_free_buftarg(
 	xfs_buftarg_t		*btp,
@@ -1501,6 +1556,7 @@
 	xfs_flush_buftarg(btp, 1);
 	if (external)
 		xfs_blkdev_put(btp->pbr_bdev);
+	xfs_free_bufhash(btp);
 	iput(btp->pbr_mapping->host);
 	kmem_free(btp, sizeof(*btp));
 }
@@ -1515,11 +1571,12 @@
 	truncate_inode_pages(btp->pbr_mapping, 0LL);
 }
 
-int
-xfs_setsize_buftarg(
+STATIC int
+xfs_setsize_buftarg_flags(
 	xfs_buftarg_t		*btp,
 	unsigned int		blocksize,
-	unsigned int		sectorsize)
+	unsigned int		sectorsize,
+	int			verbose)
 {
 	btp->pbr_bsize = blocksize;
 	btp->pbr_sshift = ffs(sectorsize) - 1;
@@ -1531,9 +1588,42 @@
 			sectorsize, XFS_BUFTARG_NAME(btp));
 		return EINVAL;
 	}
+
+	if (verbose &&
+	    (PAGE_CACHE_SIZE / BITS_PER_LONG) > sectorsize) {
+		printk(KERN_WARNING
+			"XFS: %u byte sectors in use on device %s.  "
+			"This is suboptimal; %u or greater is ideal.\n",
+			sectorsize, XFS_BUFTARG_NAME(btp),
+			(unsigned int)PAGE_CACHE_SIZE / BITS_PER_LONG);
+	}
+
 	return 0;
 }
 
+/*
+* When allocating the initial buffer target we have not yet
+* read in the superblock, so don't know what sized sectors
+* are being used is at this early stage.  Play safe.
+*/
+STATIC int
+xfs_setsize_buftarg_early(
+	xfs_buftarg_t		*btp,
+	struct block_device	*bdev)
+{
+	return xfs_setsize_buftarg_flags(btp,
+			PAGE_CACHE_SIZE, bdev_hardsect_size(bdev), 0);
+}
+
+int
+xfs_setsize_buftarg(
+	xfs_buftarg_t		*btp,
+	unsigned int		blocksize,
+	unsigned int		sectorsize)
+{
+	return xfs_setsize_buftarg_flags(btp, blocksize, sectorsize, 1);
+}
+
 STATIC int
 xfs_mapping_buftarg(
 	xfs_buftarg_t		*btp,
@@ -1562,14 +1652,15 @@
 	mapping = &inode->i_data;
 	mapping->a_ops = &mapping_aops;
 	mapping->backing_dev_info = bdi;
-	mapping_set_gfp_mask(mapping, GFP_KERNEL);
+	mapping_set_gfp_mask(mapping, GFP_NOFS);
 	btp->pbr_mapping = mapping;
 	return 0;
 }
 
 xfs_buftarg_t *
 xfs_alloc_buftarg(
-	struct block_device	*bdev)
+	struct block_device	*bdev,
+	int			external)
 {
 	xfs_buftarg_t		*btp;
 
@@ -1577,10 +1668,11 @@
 
 	btp->pbr_dev =  bdev->bd_dev;
 	btp->pbr_bdev = bdev;
-	if (xfs_setsize_buftarg(btp, PAGE_CACHE_SIZE, bdev_hardsect_size(bdev)))
+	if (xfs_setsize_buftarg_early(btp, bdev))
 		goto error;
 	if (xfs_mapping_buftarg(btp, bdev))
 		goto error;
+	xfs_alloc_bufhash(btp, external);
 	return btp;
 
 error:
@@ -1594,7 +1686,7 @@
  */
 
 STATIC LIST_HEAD(pbd_delwrite_queue);
-STATIC spinlock_t pbd_delwrite_lock = SPIN_LOCK_UNLOCKED;
+STATIC DEFINE_SPINLOCK(pbd_delwrite_lock);
 
 STATIC void
 pagebuf_delwri_queue(
@@ -1685,9 +1777,7 @@
 
 	INIT_LIST_HEAD(&tmp);
 	do {
-		/* swsusp */
-		if (current->flags & PF_FREEZE)
-			refrigerator(PF_FREEZE);
+		try_to_freeze(PF_FREEZE);
 
 		set_current_state(TASK_INTERRUPTIBLE);
 		schedule_timeout((xfs_buf_timer_centisecs * HZ) / 100);
@@ -1846,8 +1936,6 @@
 int __init
 pagebuf_init(void)
 {
-	int			i;
-
 	pagebuf_cache = kmem_cache_create("xfs_buf_t", sizeof(xfs_buf_t), 0,
 			SLAB_HWCACHE_ALIGN, NULL, NULL);
 	if (pagebuf_cache == NULL) {
@@ -1866,11 +1954,6 @@
 	if (pagebuf_shake == NULL) {
 		pagebuf_terminate();
 		return -ENOMEM;
-	}
-
-	for (i = 0; i < NHASH; i++) {
-		spin_lock_init(&pbhash[i].pb_hash_lock);
-		INIT_LIST_HEAD(&pbhash[i].pb_hash);
 	}
 
 	return 0;
diff -Nru 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	2005-03-01 23:38:58 -08:00
+++ b/fs/xfs/linux-2.6/xfs_buf.h	2005-03-01 23:38:58 -08:00
@@ -95,6 +95,11 @@
 #define PBF_NOT_DONE(pb) (((pb)->pb_flags & (PBF_PARTIAL|PBF_NONE)) != 0)
 #define PBF_DONE(pb) (((pb)->pb_flags & (PBF_PARTIAL|PBF_NONE)) == 0)
 
+typedef struct xfs_bufhash {
+	struct list_head	bh_list;
+	spinlock_t		bh_lock;
+} xfs_bufhash_t;
+
 typedef struct xfs_buftarg {
 	dev_t			pbr_dev;
 	struct block_device	*pbr_bdev;
@@ -102,32 +107,35 @@
 	unsigned int		pbr_bsize;
 	unsigned int		pbr_sshift;
 	size_t			pbr_smask;
+
+	/* per-device buffer hash table */
+	uint			bt_hashmask;
+	uint			bt_hashshift;
+	xfs_bufhash_t		*bt_hash;
 } xfs_buftarg_t;
 
 /*
  *	xfs_buf_t:  Buffer structure for page cache-based buffers
  *
  * This buffer structure is used by the page cache buffer management routines
- * to refer to an assembly of pages forming a logical buffer.  The actual
- * I/O is performed with buffer_head or bio structures, as required by drivers,
- * for drivers which do not understand this structure.  The buffer structure is
- * used on temporary basis only, and discarded when released.
- *
- * The real data storage is recorded in the page cache.  Metadata is
- * hashed to the inode for the block device on which the file system resides.
- * File data is hashed to the inode for the file.  Pages which are only
- * partially filled with data have bits set in their block_map entry
- * to indicate which disk blocks in the page are not valid.
+ * to refer to an assembly of pages forming a logical buffer.  The actual I/O
+ * is performed with buffer_head structures, as required by drivers.
+ * 
+ * The buffer structure is used on temporary basis only, and discarded when
+ * released.  The real data storage is recorded in the page cache.  Metadata is
+ * hashed to the block device on which the file system resides.
  */
 
 struct xfs_buf;
+
+/* call-back function on I/O completion */
 typedef void (*page_buf_iodone_t)(struct xfs_buf *);
-			/* call-back function on I/O completion */
+/* call-back function on I/O completion */
 typedef void (*page_buf_relse_t)(struct xfs_buf *);
-			/* call-back function on I/O completion */
+/* pre-write function */
 typedef int (*page_buf_bdstrat_t)(struct xfs_buf *);
 
-#define PB_PAGES	4
+#define PB_PAGES	2
 
 typedef struct xfs_buf {
 	struct semaphore	pb_sema;	/* semaphore for lockables  */
@@ -136,8 +144,9 @@
 	wait_queue_head_t	pb_waiters;	/* unpin waiters	    */
 	struct list_head	pb_list;
 	page_buf_flags_t	pb_flags;	/* status flags */
-	struct list_head	pb_hash_list;
-	xfs_buftarg_t		*pb_target;	/* logical object */
+	struct list_head	pb_hash_list;	/* hash table list */
+	xfs_bufhash_t		*pb_hash;	/* hash table list start */
+	xfs_buftarg_t		*pb_target;	/* buffer target (device) */
 	atomic_t		pb_hold;	/* reference count */
 	xfs_daddr_t		pb_bn;		/* block number for I/O */
 	loff_t			pb_file_offset;	/* offset in file */
@@ -154,10 +163,9 @@
 	void			*pb_fspriv2;
 	void			*pb_fspriv3;
 	unsigned short		pb_error;	/* error code on I/O */
-	unsigned short		pb_page_count;	/* size of page array */
-	unsigned short		pb_offset;	/* page offset in first page */
-	unsigned char		pb_locked;	/* page array is locked */
-	unsigned char		pb_hash_index;	/* hash table index	*/
+ 	unsigned short		pb_locked;	/* page array is locked */
+ 	unsigned int		pb_page_count;	/* size of page array */
+	unsigned int		pb_offset;	/* page offset in first page */
 	struct page		**pb_pages;	/* array of page pointers */
 	struct page		*pb_page_array[PB_PAGES]; /* inline pages */
 #ifdef PAGEBUF_LOCK_TRACKING
@@ -455,7 +463,7 @@
 				pagebuf_associate_memory(bp, val, count)
 #define XFS_BUF_ADDR(bp)	((bp)->pb_bn)
 #define XFS_BUF_SET_ADDR(bp, blk)		\
-			((bp)->pb_bn = (blk))
+			((bp)->pb_bn = (xfs_daddr_t)(blk))
 #define XFS_BUF_OFFSET(bp)	((bp)->pb_file_offset)
 #define XFS_BUF_SET_OFFSET(bp, off)		\
 			((bp)->pb_file_offset = (off))
@@ -564,7 +572,7 @@
  *	Handling of buftargs.
  */
 
-extern xfs_buftarg_t *xfs_alloc_buftarg(struct block_device *);
+extern xfs_buftarg_t *xfs_alloc_buftarg(struct block_device *, int);
 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);
diff -Nru a/fs/xfs/linux-2.6/xfs_export.c b/fs/xfs/linux-2.6/xfs_export.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/fs/xfs/linux-2.6/xfs_export.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2004-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.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like.  Any license provided herein, whether implied or
+ * otherwise, applies only to this software file.  Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA  94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ */
+
+#include "xfs.h"
+
+
+STATIC struct dentry *
+linvfs_decode_fh(
+	struct super_block	*sb,
+	__u32			*fh,
+	int			fh_len,
+	int			fileid_type,
+	int (*acceptable)(
+		void		*context,
+		struct dentry	*de),
+	void			*context)
+{
+	__u32 parent[2];
+	parent[0] = parent[1] = 0;
+	
+	if (fh_len < 2 || fileid_type > 2)
+		return NULL;
+	
+	if (fileid_type == 2 && fh_len > 2) {
+		if (fh_len == 3) {
+			printk(KERN_WARNING
+			       "XFS: detected filehandle without "
+			       "parent inode generation information.");
+			return ERR_PTR(-ESTALE);
+		}
+			
+		parent[0] = fh[2];
+		parent[1] = fh[3];
+	}
+	
+	return find_exported_dentry(sb, fh, parent, acceptable, context);
+
+}
+
+STATIC struct dentry *
+linvfs_get_dentry(
+	struct super_block	*sb,
+	void			*data)
+{
+	vnode_t			*vp;
+	struct inode		*inode;
+	struct dentry		*result;
+	xfs_fid2_t		xfid;
+	vfs_t			*vfsp = LINVFS_GET_VFS(sb);
+	int			error;
+
+	xfid.fid_len = sizeof(xfs_fid2_t) - sizeof(xfid.fid_len);
+	xfid.fid_pad = 0;
+	xfid.fid_gen = ((__u32 *)data)[1];
+	xfid.fid_ino = ((__u32 *)data)[0];
+
+	VFS_VGET(vfsp, &vp, (fid_t *)&xfid, error);
+	if (error || vp == NULL)
+		return ERR_PTR(-ESTALE) ;
+
+	inode = LINVFS_GET_IP(vp);
+	result = d_alloc_anon(inode);
+        if (!result) {
+		iput(inode);
+		return ERR_PTR(-ENOMEM);
+	}
+	return result;
+}
+
+STATIC struct dentry *
+linvfs_get_parent(
+	struct dentry		*child)
+{
+	int			error;
+	vnode_t			*vp, *cvp;
+	struct dentry		*parent;
+	struct dentry		dotdot;
+
+	dotdot.d_name.name = "..";
+	dotdot.d_name.len = 2;
+	dotdot.d_inode = NULL;
+
+	cvp = NULL;
+	vp = LINVFS_GET_VP(child->d_inode);
+	VOP_LOOKUP(vp, &dotdot, &cvp, 0, NULL, NULL, error);
+	if (unlikely(error))
+		return ERR_PTR(-error);
+
+	parent = d_alloc_anon(LINVFS_GET_IP(cvp));
+	if (unlikely(!parent)) {
+		VN_RELE(cvp);
+		return ERR_PTR(-ENOMEM);
+	}
+	return parent;
+}
+
+struct export_operations linvfs_export_ops = {
+	.decode_fh		= linvfs_decode_fh,
+	.get_parent		= linvfs_get_parent,
+	.get_dentry		= linvfs_get_dentry,
+};
diff -Nru 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	2005-03-01 23:38:57 -08:00
+++ b/fs/xfs/linux-2.6/xfs_file.c	2005-03-01 23:38:57 -08:00
@@ -51,6 +51,7 @@
 #include "xfs_inode.h"
 #include "xfs_error.h"
 #include "xfs_rw.h"
+#include "xfs_ioctl32.h"
 
 #include <linux/dcache.h>
 #include <linux/smp_lock.h>
@@ -81,23 +82,23 @@
 
 
 STATIC ssize_t
-linvfs_read(
+linvfs_aio_read(
 	struct kiocb		*iocb,
 	char			__user *buf,
 	size_t			count,
 	loff_t			pos)
 {
-	return __linvfs_read(iocb, buf, 0, count, pos);
+	return __linvfs_read(iocb, buf, IO_ISAIO, count, pos);
 }
 
 STATIC ssize_t
-linvfs_read_invis(
+linvfs_aio_read_invis(
 	struct kiocb		*iocb,
 	char			__user *buf,
 	size_t			count,
 	loff_t			pos)
 {
-	return __linvfs_read(iocb, buf, IO_INVIS, count, pos);
+	return __linvfs_read(iocb, buf, IO_ISAIO|IO_INVIS, count, pos);
 }
 
 
@@ -125,23 +126,23 @@
 
 
 STATIC ssize_t
-linvfs_write(
+linvfs_aio_write(
 	struct kiocb		*iocb,
 	const char		__user *buf,
 	size_t			count,
 	loff_t			pos)
 {
-	return __linvfs_write(iocb, buf, 0, count, pos);
+	return __linvfs_write(iocb, buf, IO_ISAIO, count, pos);
 }
 
 STATIC ssize_t
-linvfs_write_invis(
+linvfs_aio_write_invis(
 	struct kiocb		*iocb,
 	const char		__user *buf,
 	size_t			count,
 	loff_t			pos)
 {
-	return __linvfs_write(iocb, buf, IO_INVIS, count, pos);
+	return __linvfs_write(iocb, buf, IO_ISAIO|IO_INVIS, count, pos);
 }
 
 
@@ -415,20 +416,18 @@
 }
 
 
-STATIC int
+STATIC long
 linvfs_ioctl(
-	struct inode	*inode,
 	struct file	*filp,
 	unsigned int	cmd,
 	unsigned long	arg)
 {
 	int		error;
+	struct inode *inode = filp->f_dentry->d_inode;
 	vnode_t		*vp = LINVFS_GET_VP(inode);
 
-	unlock_kernel();
 	VOP_IOCTL(vp, inode, filp, 0, cmd, (void __user *)arg, error);
 	VMODIFY(vp);
-	lock_kernel();
 
 	/* NOTE:  some of the ioctl's return positive #'s as a
 	 *	  byte count indicating success, such as
@@ -439,21 +438,19 @@
 	return error;
 }
 
-STATIC int
+STATIC long
 linvfs_ioctl_invis(
-	struct inode	*inode,
 	struct file	*filp,
 	unsigned int	cmd,
 	unsigned long	arg)
 {
 	int		error;
+	struct inode *inode = filp->f_dentry->d_inode;
 	vnode_t		*vp = LINVFS_GET_VP(inode);
 
-	unlock_kernel();
 	ASSERT(vp);
 	VOP_IOCTL(vp, inode, filp, IO_INVIS, cmd, (void __user *)arg, error);
 	VMODIFY(vp);
-	lock_kernel();
 
 	/* NOTE:  some of the ioctl's return positive #'s as a
 	 *	  byte count indicating success, such as
@@ -492,10 +489,13 @@
 	.write		= do_sync_write,
 	.readv		= linvfs_readv,
 	.writev		= linvfs_writev,
-	.aio_read	= linvfs_read,
-	.aio_write	= linvfs_write,
+	.aio_read	= linvfs_aio_read,
+	.aio_write	= linvfs_aio_write,
 	.sendfile	= linvfs_sendfile,
-	.ioctl		= linvfs_ioctl,
+	.unlocked_ioctl	= linvfs_ioctl,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl   = xfs_compat_ioctl,
+#endif
 	.mmap		= linvfs_file_mmap,
 	.open		= linvfs_open,
 	.release	= linvfs_release,
@@ -508,10 +508,13 @@
 	.write		= do_sync_write,
 	.readv		= linvfs_readv_invis,
 	.writev		= linvfs_writev_invis,
-	.aio_read	= linvfs_read_invis,
-	.aio_write	= linvfs_write_invis,
+	.aio_read	= linvfs_aio_read_invis,
+	.aio_write	= linvfs_aio_write_invis,
 	.sendfile	= linvfs_sendfile,
-	.ioctl		= linvfs_ioctl_invis,
+	.unlocked_ioctl	= linvfs_ioctl_invis,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl   = xfs_compat_invis_ioctl,
+#endif
 	.mmap		= linvfs_file_mmap,
 	.open		= linvfs_open,
 	.release	= linvfs_release,
@@ -522,12 +525,13 @@
 struct file_operations linvfs_dir_operations = {
 	.read		= generic_read_dir,
 	.readdir	= linvfs_readdir,
-	.ioctl		= linvfs_ioctl,
+	.unlocked_ioctl	= linvfs_ioctl,
 	.fsync		= linvfs_fsync,
 };
 
 static struct vm_operations_struct linvfs_file_vm_ops = {
 	.nopage		= filemap_nopage,
+	.populate	= filemap_populate,
 #ifdef HAVE_VMOP_MPROTECT
 	.mprotect	= linvfs_mprotect,
 #endif
diff -Nru 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	2005-03-01 23:39:18 -08:00
+++ b/fs/xfs/linux-2.6/xfs_ioctl.c	2005-03-01 23:39:18 -08:00
@@ -499,7 +499,7 @@
 	xfs_fsop_attrmulti_handlereq_t am_hreq;
 	struct inode		*inode;
 	vnode_t			*vp;
-	int			i, size;
+	unsigned int		i, size;
 
 	error = xfs_vget_fsop_handlereq(mp, parinode, CAP_SYS_ADMIN, arg,
 					sizeof(xfs_fsop_attrmulti_handlereq_t),
@@ -509,6 +509,11 @@
 		return -error;
 
 	size = am_hreq.opcount * sizeof(attr_multiop_t);
+	if (!size || size > 16 * PAGE_SIZE) {
+		VN_RELE(vp);
+		return -XFS_ERROR(E2BIG);
+	}
+
 	ops = (xfs_attr_multiop_t *)kmalloc(size, GFP_KERNEL);
 	if (!ops) {
 		VN_RELE(vp);
diff -Nru a/fs/xfs/linux-2.6/xfs_ioctl32.c b/fs/xfs/linux-2.6/xfs_ioctl32.c
--- a/fs/xfs/linux-2.6/xfs_ioctl32.c	2005-03-01 23:39:18 -08:00
+++ b/fs/xfs/linux-2.6/xfs_ioctl32.c	2005-03-01 23:39:18 -08:00
@@ -37,10 +37,14 @@
 #include <linux/ioctl32.h>
 #include <linux/syscalls.h>
 #include <linux/types.h>
+#include <linux/fs.h>
 #include <asm/uaccess.h>
 
+#include "xfs.h"
 #include "xfs_types.h"
 #include "xfs_fs.h"
+#include "xfs_vfs.h"
+#include "xfs_vnode.h"
 #include "xfs_dfrag.h"
 
 #if defined(CONFIG_IA64) || defined(CONFIG_X86_64)
@@ -54,12 +58,8 @@
 	__s32		ocount;		/* output count pointer		*/
 } xfs_fsop_bulkreq32_t;
 
-static int
-xfs_ioctl32_bulkstat(
-	unsigned int		fd,
-	unsigned int		cmd,
-	unsigned long		arg,
-	struct file *		file)
+static unsigned long
+xfs_ioctl32_bulkstat(unsigned long arg)
 {
 	xfs_fsop_bulkreq32_t	__user *p32 = (void __user *)arg;
 	xfs_fsop_bulkreq_t	__user *p = compat_alloc_user_space(sizeof(*p));
@@ -74,89 +74,90 @@
 	    put_user(compat_ptr(addr), &p->ocount))
 		return -EFAULT;
 
-	return sys_ioctl(fd, cmd, (unsigned long)p);
+	return (unsigned long)p;
 }
 #endif
 
-struct ioctl_trans xfs_ioctl32_trans[] = {
-	{ XFS_IOC_DIOINFO, },
-	{ XFS_IOC_FSGEOMETRY_V1, },
-	{ XFS_IOC_FSGEOMETRY, },
-	{ XFS_IOC_GETVERSION, },
-	{ XFS_IOC_GETXFLAGS, },
-	{ XFS_IOC_SETXFLAGS, },
-	{ XFS_IOC_FSGETXATTR, },
-	{ XFS_IOC_FSSETXATTR, },
-	{ XFS_IOC_FSGETXATTRA, },
-	{ XFS_IOC_FSSETDM, },
-	{ XFS_IOC_GETBMAP, },
-	{ XFS_IOC_GETBMAPA, },
-	{ XFS_IOC_GETBMAPX, },
+static long
+__xfs_compat_ioctl(int mode, struct file *f, unsigned cmd, unsigned long arg)
+{
+	int		error;
+	struct inode *inode = f->f_dentry->d_inode;
+	vnode_t		*vp = LINVFS_GET_VP(inode);
+
+	switch (cmd) {
+	case XFS_IOC_DIOINFO:
+	case XFS_IOC_FSGEOMETRY_V1:
+	case XFS_IOC_FSGEOMETRY:
+	case XFS_IOC_GETVERSION:
+	case XFS_IOC_GETXFLAGS:
+	case XFS_IOC_SETXFLAGS:
+	case XFS_IOC_FSGETXATTR:
+	case XFS_IOC_FSSETXATTR:
+	case XFS_IOC_FSGETXATTRA:
+	case XFS_IOC_FSSETDM:
+	case XFS_IOC_GETBMAP:
+	case XFS_IOC_GETBMAPA:
+	case XFS_IOC_GETBMAPX:
 /* not handled
-	{ XFS_IOC_FD_TO_HANDLE, },
-	{ XFS_IOC_PATH_TO_HANDLE, },
-	{ XFS_IOC_PATH_TO_HANDLE, },
-	{ XFS_IOC_PATH_TO_FSHANDLE, },
-	{ XFS_IOC_OPEN_BY_HANDLE, },
-	{ XFS_IOC_FSSETDM_BY_HANDLE, },
-	{ XFS_IOC_READLINK_BY_HANDLE, },
-	{ XFS_IOC_ATTRLIST_BY_HANDLE, },
-	{ XFS_IOC_ATTRMULTI_BY_HANDLE, },
+	case XFS_IOC_FD_TO_HANDLE:
+	case XFS_IOC_PATH_TO_HANDLE:
+	case XFS_IOC_PATH_TO_HANDLE:
+	case XFS_IOC_PATH_TO_FSHANDLE:
+	case XFS_IOC_OPEN_BY_HANDLE:
+	case XFS_IOC_FSSETDM_BY_HANDLE:
+	case XFS_IOC_READLINK_BY_HANDLE:
+	case XFS_IOC_ATTRLIST_BY_HANDLE:
+	case XFS_IOC_ATTRMULTI_BY_HANDLE:
 */
-	{ XFS_IOC_FSCOUNTS, NULL, },
-	{ XFS_IOC_SET_RESBLKS, NULL, },
-	{ XFS_IOC_GET_RESBLKS, NULL, },
-	{ XFS_IOC_FSGROWFSDATA, NULL, },
-	{ XFS_IOC_FSGROWFSLOG, NULL, },
-	{ XFS_IOC_FSGROWFSRT, NULL, },
-	{ XFS_IOC_FREEZE, NULL, },
-	{ XFS_IOC_THAW, NULL, },
-	{ XFS_IOC_GOINGDOWN, NULL, },
-	{ XFS_IOC_ERROR_INJECTION, NULL, },
-	{ XFS_IOC_ERROR_CLEARALL, NULL, },
+	case XFS_IOC_FSCOUNTS:
+	case XFS_IOC_SET_RESBLKS:
+	case XFS_IOC_GET_RESBLKS:
+	case XFS_IOC_FSGROWFSDATA:
+	case XFS_IOC_FSGROWFSLOG:
+	case XFS_IOC_FSGROWFSRT:
+	case XFS_IOC_FREEZE:
+	case XFS_IOC_THAW:
+	case XFS_IOC_GOINGDOWN:
+	case XFS_IOC_ERROR_INJECTION:
+	case XFS_IOC_ERROR_CLEARALL:
+		break;
+
 #ifndef BROKEN_X86_ALIGNMENT
 	/* xfs_flock_t and xfs_bstat_t have wrong u32 vs u64 alignment */
-	{ XFS_IOC_ALLOCSP, },
-	{ XFS_IOC_FREESP, },
-	{ XFS_IOC_RESVSP, },
-	{ XFS_IOC_UNRESVSP, },
-	{ XFS_IOC_ALLOCSP64, },
-	{ XFS_IOC_FREESP64, },
-	{ XFS_IOC_RESVSP64, },
-	{ XFS_IOC_UNRESVSP64, },
-	{ XFS_IOC_SWAPEXT, },
-	{ XFS_IOC_FSBULKSTAT_SINGLE, xfs_ioctl32_bulkstat },
-	{ XFS_IOC_FSBULKSTAT, xfs_ioctl32_bulkstat},
-	{ XFS_IOC_FSINUMBERS, xfs_ioctl32_bulkstat},
+	case XFS_IOC_ALLOCSP:
+	case XFS_IOC_FREESP:
+	case XFS_IOC_RESVSP:
+	case XFS_IOC_UNRESVSP:
+	case XFS_IOC_ALLOCSP64:
+	case XFS_IOC_FREESP64:
+	case XFS_IOC_RESVSP64:
+	case XFS_IOC_UNRESVSP64:
+	case XFS_IOC_SWAPEXT:
+		break;
+
+	case XFS_IOC_FSBULKSTAT_SINGLE:
+	case XFS_IOC_FSBULKSTAT:
+	case XFS_IOC_FSINUMBERS:
+		arg = xfs_ioctl32_bulkstat(arg);
+		break;
 #endif
-	{ 0, },
-};
-
-int __init
-xfs_ioctl32_init(void)
-{
-	int error, i;
-
-	for (i = 0; xfs_ioctl32_trans[i].cmd != 0; i++) {
-		error = register_ioctl32_conversion(xfs_ioctl32_trans[i].cmd,
-				xfs_ioctl32_trans[i].handler);
-		if (error)
-			goto fail;
+	default:
+		return -ENOIOCTLCMD;
 	}
 
-	return 0;
+	VOP_IOCTL(vp, inode, f, mode, cmd, (void __user *)arg, error);
+	VMODIFY(vp);
 
- fail:
-	while (--i)
-		unregister_ioctl32_conversion(xfs_ioctl32_trans[i].cmd);
 	return error;
 }
 
-void
-xfs_ioctl32_exit(void)
+long xfs_compat_ioctl(struct file *f, unsigned cmd, unsigned long arg)
 {
-	int i;
+	return __xfs_compat_ioctl(0, f, cmd, arg);
+}
 
-	for (i = 0; xfs_ioctl32_trans[i].cmd != 0; i++)
-		unregister_ioctl32_conversion(xfs_ioctl32_trans[i].cmd);
+long xfs_compat_invis_ioctl(struct file *f, unsigned cmd, unsigned long arg)
+{
+	return __xfs_compat_ioctl(IO_INVIS, f, cmd, arg);
 }
diff -Nru a/fs/xfs/linux-2.6/xfs_ioctl32.h b/fs/xfs/linux-2.6/xfs_ioctl32.h
--- a/fs/xfs/linux-2.6/xfs_ioctl32.h	2005-03-01 23:38:54 -08:00
+++ b/fs/xfs/linux-2.6/xfs_ioctl32.h	2005-03-01 23:38:54 -08:00
@@ -30,12 +30,5 @@
  * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
  */
 
-#include <linux/config.h>
-
-#ifdef CONFIG_COMPAT
-extern int xfs_ioctl32_init(void);
-extern void xfs_ioctl32_exit(void);
-#else
-static inline int xfs_ioctl32_init(void) { return 0; }
-static inline void xfs_ioctl32_exit(void) { }
-#endif
+long xfs_compat_ioctl(struct file *f, unsigned cmd, unsigned long arg);
+long xfs_compat_invis_ioctl(struct file *f, unsigned cmd, unsigned long arg);
diff -Nru 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	2005-03-01 23:38:55 -08:00
+++ b/fs/xfs/linux-2.6/xfs_iops.c	2005-03-01 23:38:55 -08:00
@@ -369,33 +369,6 @@
 	return 0;
 }
 
-STATIC int
-linvfs_readlink(
-	struct dentry	*dentry,
-	char		__user *buf,
-	int		size)
-{
-	vnode_t		*vp = LINVFS_GET_VP(dentry->d_inode);
-	uio_t		uio;
-	iovec_t		iov;
-	int		error;
-
-	iov.iov_base = buf;
-	iov.iov_len = size;
-
-	uio.uio_iov = &iov;
-	uio.uio_offset = 0;
-	uio.uio_segflg = UIO_USERSPACE;
-	uio.uio_resid = size;
-	uio.uio_iovcnt = 1;
-
-	VOP_READLINK(vp, &uio, 0, NULL, error);
-	if (error)
-		return -error;
-
-	return (size - uio.uio_resid);
-}
-
 /*
  * careful here - this function can get called recursively, so
  * we need to be very careful about how much stack we use.
@@ -694,7 +667,7 @@
 };
 
 struct inode_operations linvfs_symlink_inode_operations = {
-	.readlink		= linvfs_readlink,
+	.readlink		= generic_readlink,
 	.follow_link		= linvfs_follow_link,
 	.put_link		= linvfs_put_link,
 	.permission		= linvfs_permission,
diff -Nru 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	2005-03-01 23:39:18 -08:00
+++ b/fs/xfs/linux-2.6/xfs_linux.h	2005-03-01 23:39:18 -08:00
@@ -144,7 +144,10 @@
 #define xfs_inherit_nosymlinks	xfs_params.inherit_nosym.val
 #define xfs_rotorstep		xfs_params.rotorstep.val
 
-#define current_cpu()		smp_processor_id()
+#ifndef __smp_processor_id
+#define __smp_processor_id()	smp_processor_id()
+#endif
+#define current_cpu()		__smp_processor_id()
 #define current_pid()		(current->pid)
 #define current_fsuid(cred)	(current->fsuid)
 #define current_fsgid(cred)	(current->fsgid)
diff -Nru 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	2005-03-01 23:38:43 -08:00
+++ b/fs/xfs/linux-2.6/xfs_lrw.c	2005-03-01 23:38:43 -08:00
@@ -317,7 +317,7 @@
 	xfs_rw_enter_trace(XFS_READ_ENTER, &ip->i_iocore,
 				(void *)iovp, segs, *offset, ioflags);
 	ret = __generic_file_aio_read(iocb, iovp, segs, offset);
-	if (ret == -EIOCBQUEUED)
+	if (ret == -EIOCBQUEUED && !(ioflags & IO_ISAIO))
 		ret = wait_on_sync_kiocb(iocb);
 	if (ret > 0)
 		XFS_STATS_ADD(xs_read_bytes, ret);
@@ -676,6 +676,8 @@
 	if (XFS_FORCED_SHUTDOWN(mp))
 		return -EIO;
 
+	fs_check_frozen(vp->v_vfsp, SB_FREEZE_WRITE);
+
 	if (ioflags & IO_ISDIRECT) {
 		xfs_buftarg_t	*target =
 			(xip->i_d.di_flags & XFS_DIFLAG_REALTIME) ?
@@ -854,7 +856,7 @@
 
 	current->backing_dev_info = NULL;
 
-	if (ret == -EIOCBQUEUED)
+	if (ret == -EIOCBQUEUED && !(ioflags & IO_ISAIO))
 		ret = wait_on_sync_kiocb(iocb);
 
 	if ((ret == -ENOSPC) &&
@@ -960,9 +962,9 @@
 				xfs_trans_set_sync(tp);
 				error = xfs_trans_commit(tp, 0, NULL);
 				xfs_iunlock(xip, XFS_ILOCK_EXCL);
-				if (error)
-					goto out_unlock_internal;
 			}
+			if (error)
+				goto out_unlock_internal;
 		}
 	
 		xfs_rwunlock(bdp, locktype);
diff -Nru a/fs/xfs/linux-2.6/xfs_stats.h b/fs/xfs/linux-2.6/xfs_stats.h
--- a/fs/xfs/linux-2.6/xfs_stats.h	2005-03-01 23:38:54 -08:00
+++ b/fs/xfs/linux-2.6/xfs_stats.h	2005-03-01 23:38:54 -08:00
@@ -140,11 +140,13 @@
 
 DECLARE_PER_CPU(struct xfsstats, xfsstats);
 
-/* We don't disable preempt, not too worried about poking the
- * wrong cpu's stat for now */
-#define XFS_STATS_INC(count)		(__get_cpu_var(xfsstats).count++)
-#define XFS_STATS_DEC(count)		(__get_cpu_var(xfsstats).count--)
-#define XFS_STATS_ADD(count, inc)	(__get_cpu_var(xfsstats).count += (inc))
+/*
+ * We don't disable preempt, not too worried about poking the
+ * wrong CPU's stat for now (also aggregated before reporting).
+ */
+#define XFS_STATS_INC(v)	(per_cpu(xfsstats, current_cpu()).v++)
+#define XFS_STATS_DEC(v)	(per_cpu(xfsstats, current_cpu()).v--)
+#define XFS_STATS_ADD(v, inc)	(per_cpu(xfsstats, current_cpu()).v += (inc))
 
 extern void xfs_init_procfs(void);
 extern void xfs_cleanup_procfs(void);
diff -Nru 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	2005-03-01 23:39:16 -08:00
+++ b/fs/xfs/linux-2.6/xfs_super.c	2005-03-01 23:39:16 -08:00
@@ -71,12 +71,10 @@
 #include <linux/namei.h>
 #include <linux/init.h>
 #include <linux/mount.h>
-#include <linux/suspend.h>
 #include <linux/writeback.h>
 
 STATIC struct quotactl_ops linvfs_qops;
 STATIC struct super_operations linvfs_sops;
-STATIC struct export_operations linvfs_export_ops;
 STATIC kmem_zone_t *linvfs_inode_zone;
 STATIC kmem_shaker_t xfs_inode_shaker;
 
@@ -350,6 +348,12 @@
 		if (sync)
 			flags |= FLUSH_SYNC;
 		VOP_IFLUSH(vp, flags, error);
+		if (error == EAGAIN) {
+			if (sync)
+				VOP_IFLUSH(vp, flags | FLUSH_LOG, error);
+			else
+				error = 0;
+		}
 	}
 
 	return -error;
@@ -489,8 +493,7 @@
 		set_current_state(TASK_INTERRUPTIBLE);
 		timeleft = schedule_timeout(timeleft);
 		/* swsusp */
-		if (current->flags & PF_FREEZE)
-			refrigerator(PF_FREEZE);
+		try_to_freeze(PF_FREEZE);
 		if (vfsp->vfs_flag & VFS_UMOUNT)
 			break;
 
@@ -661,63 +664,6 @@
 	VFS_FREEZE(LINVFS_GET_VFS(sb));
 }
 
-STATIC struct dentry *
-linvfs_get_parent(
-	struct dentry		*child)
-{
-	int			error;
-	vnode_t			*vp, *cvp;
-	struct dentry		*parent;
-	struct dentry		dotdot;
-
-	dotdot.d_name.name = "..";
-	dotdot.d_name.len = 2;
-	dotdot.d_inode = NULL;
-
-	cvp = NULL;
-	vp = LINVFS_GET_VP(child->d_inode);
-	VOP_LOOKUP(vp, &dotdot, &cvp, 0, NULL, NULL, error);
-	if (unlikely(error))
-		return ERR_PTR(-error);
-
-	parent = d_alloc_anon(LINVFS_GET_IP(cvp));
-	if (unlikely(!parent)) {
-		VN_RELE(cvp);
-		return ERR_PTR(-ENOMEM);
-	}
-	return parent;
-}
-
-STATIC struct dentry *
-linvfs_get_dentry(
-	struct super_block	*sb,
-	void			*data)
-{
-	vnode_t			*vp;
-	struct inode		*inode;
-	struct dentry		*result;
-	xfs_fid2_t		xfid;
-	vfs_t			*vfsp = LINVFS_GET_VFS(sb);
-	int			error;
-
-	xfid.fid_len = sizeof(xfs_fid2_t) - sizeof(xfid.fid_len);
-	xfid.fid_pad = 0;
-	xfid.fid_gen = ((__u32 *)data)[1];
-	xfid.fid_ino = ((__u32 *)data)[0];
-
-	VFS_VGET(vfsp, &vp, (fid_t *)&xfid, error);
-	if (error || vp == NULL)
-		return ERR_PTR(-ESTALE) ;
-
-	inode = LINVFS_GET_IP(vp);
-	result = d_alloc_anon(inode);
-        if (!result) {
-		iput(inode);
-		return ERR_PTR(-ENOMEM);
-	}
-	return result;
-}
-
 STATIC int
 linvfs_show_options(
 	struct seq_file		*m,
@@ -810,7 +756,9 @@
 	}
 
 	sb_min_blocksize(sb, BBSIZE);
+#ifdef CONFIG_XFS_EXPORT
 	sb->s_export_op = &linvfs_export_ops;
+#endif
 	sb->s_qcop = &linvfs_qops;
 	sb->s_op = &linvfs_sops;
 
@@ -829,6 +777,7 @@
 	sb->s_blocksize = statvfs.f_bsize;
 	sb->s_blocksize_bits = ffs(statvfs.f_bsize) - 1;
 	sb->s_maxbytes = xfs_max_file_offset(sb->s_blocksize_bits);
+	sb->s_time_gran = 1;
 	set_posix_acl_flag(sb);
 
 	VFS_ROOT(vfsp, &rootvp, error);
@@ -878,12 +827,6 @@
 	return get_sb_bdev(fs_type, flags, dev_name, data, linvfs_fill_super);
 }
 
-
-STATIC struct export_operations linvfs_export_ops = {
-	.get_parent		= linvfs_get_parent,
-	.get_dentry		= linvfs_get_dentry,
-};
-
 STATIC struct super_operations linvfs_sops = {
 	.alloc_inode		= linvfs_alloc_inode,
 	.destroy_inode		= linvfs_destroy_inode,
@@ -948,10 +891,6 @@
 		goto undo_shaker;
 	}
 
-	error = xfs_ioctl32_init();
-	if (error)
-		goto undo_ioctl32;
-
 	error = register_filesystem(&xfs_fs_type);
 	if (error)
 		goto undo_register;
@@ -959,9 +898,6 @@
 	return 0;
 
 undo_register:
-	xfs_ioctl32_exit();
-
-undo_ioctl32:
 	kmem_shake_deregister(xfs_inode_shaker);
 
 undo_shaker:
@@ -980,7 +916,6 @@
 	vfs_exitquota();
 	XFS_DM_EXIT(&xfs_fs_type);
 	unregister_filesystem(&xfs_fs_type);
-	xfs_ioctl32_exit();
 	kmem_shake_deregister(xfs_inode_shaker);
 	xfs_cleanup();
 	pagebuf_terminate();
diff -Nru a/fs/xfs/linux-2.6/xfs_super.h b/fs/xfs/linux-2.6/xfs_super.h
--- a/fs/xfs/linux-2.6/xfs_super.h	2005-03-01 23:38:54 -08:00
+++ b/fs/xfs/linux-2.6/xfs_super.h	2005-03-01 23:38:54 -08:00
@@ -133,4 +133,6 @@
 				struct block_device **);
 extern void xfs_blkdev_put(struct block_device *);
 
+extern struct export_operations linvfs_export_ops;
+
 #endif	/* __XFS_SUPER_H__ */
diff -Nru a/fs/xfs/linux-2.6/xfs_vfs.c b/fs/xfs/linux-2.6/xfs_vfs.c
--- a/fs/xfs/linux-2.6/xfs_vfs.c	2005-03-01 23:39:18 -08:00
+++ b/fs/xfs/linux-2.6/xfs_vfs.c	2005-03-01 23:39:18 -08:00
@@ -250,7 +250,7 @@
 	vfsp = kmem_zalloc(sizeof(vfs_t), KM_SLEEP);
 	bhv_head_init(VFS_BHVHEAD(vfsp), "vfs");
 	INIT_LIST_HEAD(&vfsp->vfs_sync_list);
-	vfsp->vfs_sync_lock = SPIN_LOCK_UNLOCKED;
+	spin_lock_init(&vfsp->vfs_sync_lock);
 	init_waitqueue_head(&vfsp->vfs_wait_sync_task);
 	init_waitqueue_head(&vfsp->vfs_wait_single_sync_task);
 	return vfsp;
diff -Nru 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	2005-03-01 23:38:55 -08:00
+++ b/fs/xfs/linux-2.6/xfs_vnode.c	2005-03-01 23:38:55 -08:00
@@ -34,7 +34,7 @@
 
 
 uint64_t vn_generation;		/* vnode generation number */
-spinlock_t vnumber_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(vnumber_lock);
 
 /*
  * Dedicated vnode inactive/reclaim sync semaphores.
@@ -199,7 +199,6 @@
 {
 	struct inode	*inode = LINVFS_GET_IP(vp);
 
-	inode = LINVFS_GET_IP(vp);
 	inode->i_mode	    = VTTOIF(vap->va_type) | vap->va_mode;
 	inode->i_nlink	    = vap->va_nlink;
 	inode->i_uid	    = vap->va_uid;
@@ -416,8 +415,8 @@
 /*  3 */		(void *)(vn_count(vp)), \
 /*  4 */		(void *)(ra),				\
 /*  5 */		(void *)(__psunsigned_t)(vp)->v_flag,	\
-/*  6 */		(void *)(__psint_t)smp_processor_id(),	\
-/*  7 */		(void *)(__psint_t)(current->pid),	\
+/*  6 */		(void *)(__psint_t)current_cpu(),	\
+/*  7 */		(void *)(__psint_t)current_pid(),	\
 /*  8 */		(void *)__return_address,		\
 /*  9 */		0, 0, 0, 0, 0, 0, 0)
 
diff -Nru 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	2005-03-01 23:39:17 -08:00
+++ b/fs/xfs/linux-2.6/xfs_vnode.h	2005-03-01 23:39:17 -08:00
@@ -379,6 +379,7 @@
 /*
  * Flags for read/write calls - same values as IRIX
  */
+#define IO_ISAIO	0x00001		/* don't wait for completion */
 #define IO_ISDIRECT	0x00004		/* bypass page cache */
 #define IO_INVIS	0x00020		/* don't update inode timestamps */
 
diff -Nru a/fs/xfs/support/debug.c b/fs/xfs/support/debug.c
--- a/fs/xfs/support/debug.c	2005-03-01 23:38:52 -08:00
+++ b/fs/xfs/support/debug.c	2005-03-01 23:38:52 -08:00
@@ -38,7 +38,7 @@
 
 int			doass = 1;
 static char		message[256];	/* keep it off the stack */
-static spinlock_t	xfs_err_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(xfs_err_lock);
 
 /* Translate from CE_FOO to KERN_FOO, err_level(CE_FOO) == KERN_FOO */
 #define XFS_MAX_ERR_LEVEL	7
diff -Nru a/fs/xfs/xfs_clnt.h b/fs/xfs/xfs_clnt.h
--- a/fs/xfs/xfs_clnt.h	2005-03-01 23:39:07 -08:00
+++ b/fs/xfs/xfs_clnt.h	2005-03-01 23:39:07 -08:00
@@ -64,6 +64,7 @@
 	int	sunit;		/* stripe unit (BBs) */
 	int	swidth;		/* stripe width (BBs), multiple of sunit */
 	uchar_t iosizelog;	/* log2 of the preferred I/O size */
+	int	ihashsize;	/* inode hash table size (buckets) */
 };
 
 /*
diff -Nru a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c
--- a/fs/xfs/xfs_iget.c	2005-03-01 23:39:17 -08:00
+++ b/fs/xfs/xfs_iget.c	2005-03-01 23:39:17 -08:00
@@ -55,22 +55,32 @@
 #include "xfs_inode.h"
 #include "xfs_quota.h"
 #include "xfs_utils.h"
+#include "xfs_bit.h"
 
 /*
  * Initialize the inode hash table for the newly mounted file system.
- *
- * mp -- this is the mount point structure for the file system being
- *       initialized
+ * Choose an initial table size based on user specified value, else
+ * use a simple algorithm using the maximum number of inodes as an
+ * indicator for table size, and cap it at 16 pages (gettin' big).
  */
 void
 xfs_ihash_init(xfs_mount_t *mp)
 {
-	int	i;
+	__uint64_t	icount;
+	uint		i, flags = KM_SLEEP | KM_MAYFAIL;
 
-	mp->m_ihsize = XFS_BUCKETS(mp);
-	mp->m_ihash = (xfs_ihash_t *)kmem_zalloc(mp->m_ihsize
-				      * sizeof(xfs_ihash_t), KM_SLEEP);
-	ASSERT(mp->m_ihash != NULL);
+	if (!mp->m_ihsize) {
+		icount = mp->m_maxicount ? mp->m_maxicount :
+			 (mp->m_sb.sb_dblocks << mp->m_sb.sb_inopblog);
+		mp->m_ihsize = 1 << max_t(uint, xfs_highbit64(icount) / 3, 8);
+		mp->m_ihsize = min_t(uint, mp->m_ihsize, 16 * PAGE_SIZE);
+	}
+
+	while (!(mp->m_ihash = (xfs_ihash_t *)kmem_zalloc(mp->m_ihsize *
+						sizeof(xfs_ihash_t), flags))) {
+		if ((mp->m_ihsize >>= 1) <= NBPP)
+			flags = KM_SLEEP;
+	}
 	for (i = 0; i < mp->m_ihsize; i++) {
 		rwlock_init(&(mp->m_ihash[i].ih_lock));
 	}
@@ -88,29 +98,19 @@
 
 /*
  * Initialize the inode cluster hash table for the newly mounted file system.
- *
- * mp -- this is the mount point structure for the file system being
- *       initialized
+ * Its size is derived from the ihash table size.
  */
 void
 xfs_chash_init(xfs_mount_t *mp)
 {
-	int	i;
+	uint	i;
 
-	/*
-	 * m_chash size is based on m_ihash
-	 * with a minimum of 37 entries
-	 */
-	mp->m_chsize = (XFS_BUCKETS(mp)) /
-			 (XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog);
-	if (mp->m_chsize < 37) {
-		mp->m_chsize = 37;
-	}
+	mp->m_chsize = max_t(uint, 1, mp->m_ihsize /
+			 (XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog));
+	mp->m_chsize = min_t(uint, mp->m_chsize, mp->m_ihsize);
 	mp->m_chash = (xfs_chash_t *)kmem_zalloc(mp->m_chsize
 						 * sizeof(xfs_chash_t),
 						 KM_SLEEP);
-	ASSERT(mp->m_chash != NULL);
-
 	for (i = 0; i < mp->m_chsize; i++) {
 		spinlock_init(&mp->m_chash[i].ch_lock,"xfshash");
 	}
diff -Nru a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
--- a/fs/xfs/xfs_inode.h	2005-03-01 23:39:08 -08:00
+++ b/fs/xfs/xfs_inode.h	2005-03-01 23:39:08 -08:00
@@ -182,10 +182,6 @@
 	uint			ih_version;
 } xfs_ihash_t;
 
-/*
- * Inode hashing and hash bucket locking.
- */
-#define XFS_BUCKETS(mp) (37*(mp)->m_sb.sb_agcount-1)
 #define XFS_IHASH(mp,ino) ((mp)->m_ihash + (((uint)(ino)) % (mp)->m_ihsize))
 
 /*
@@ -193,7 +189,6 @@
  * find inodes that share a cluster and can be flushed to disk at the same
  * time.
  */
-
 typedef struct xfs_chashlist {
 	struct xfs_chashlist	*chl_next;
 	struct xfs_inode	*chl_ip;
@@ -207,6 +202,8 @@
 	lock_t			ch_lock;
 } xfs_chash_t;
 
+#define XFS_CHASH(mp,blk) ((mp)->m_chash + (((uint)blk) % (mp)->m_chsize))
+
 
 /*
  * This is the xfs in-core inode structure.
@@ -448,12 +445,6 @@
 #endif
 
 #define BHV_IS_XFS(bdp)		(BHV_OPS(bdp) == &xfs_vnodeops)
-
-/*
- * Pick the inode cluster hash bucket
- * (m_chash is the same size as m_ihash)
- */
-#define XFS_CHASH(mp,blk) ((mp)->m_chash + (((uint)blk) % (mp)->m_chsize))
 
 /*
  * For multiple groups support: if S_ISGID bit is set in the parent
diff -Nru a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
--- a/fs/xfs/xfs_mount.h	2005-03-01 23:38:44 -08:00
+++ b/fs/xfs/xfs_mount.h	2005-03-01 23:38:44 -08:00
@@ -296,7 +296,7 @@
 	xfs_agnumber_t		m_agirotor;	/* last ag dir inode alloced */
 	lock_t			m_agirotor_lock;/* .. and lock protecting it */
 	xfs_agnumber_t		m_maxagi;	/* highest inode alloc group */
-	int			m_ihsize;	/* size of next field */
+	uint			m_ihsize;	/* size of next field */
 	struct xfs_ihash	*m_ihash;	/* fs private inode hash table*/
 	struct xfs_inode	*m_inodes;	/* active inode list */
 	struct list_head	m_del_inodes;	/* inodes to reclaim */
@@ -376,7 +376,7 @@
 	xfs_dablk_t		m_dirdatablk;	/* blockno of dir data v2 */
 	xfs_dablk_t		m_dirleafblk;	/* blockno of dir non-data v2 */
 	xfs_dablk_t		m_dirfreeblk;	/* blockno of dirfreeindex v2 */
-	int			m_chsize;	/* size of next field */
+	uint			m_chsize;	/* size of next field */
 	struct xfs_chash	*m_chash;	/* fs private inode per-cluster
 						 * hash table */
 	struct xfs_dmops	m_dm_ops;	/* vector of DMI ops */
diff -Nru a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c
--- a/fs/xfs/xfs_vfsops.c	2005-03-01 23:38:53 -08:00
+++ b/fs/xfs/xfs_vfsops.c	2005-03-01 23:38:53 -08:00
@@ -252,6 +252,7 @@
 			ap->logbufsize);
 		return XFS_ERROR(EINVAL);
 	}
+	mp->m_ihsize = ap->ihashsize;
 	mp->m_logbsize = ap->logbufsize;
 	mp->m_fsname_len = strlen(ap->fsname) + 1;
 	mp->m_fsname = kmem_alloc(mp->m_fsname_len, KM_SLEEP);
@@ -468,19 +469,19 @@
 	 * Setup xfs_mount buffer target pointers
 	 */
 	error = ENOMEM;
-	mp->m_ddev_targp = xfs_alloc_buftarg(ddev);
+	mp->m_ddev_targp = xfs_alloc_buftarg(ddev, 0);
 	if (!mp->m_ddev_targp) {
 		xfs_blkdev_put(logdev);
 		xfs_blkdev_put(rtdev);
 		return error;
 	}
 	if (rtdev) {
-		mp->m_rtdev_targp = xfs_alloc_buftarg(rtdev);
+		mp->m_rtdev_targp = xfs_alloc_buftarg(rtdev, 1);
 		if (!mp->m_rtdev_targp)
 			goto error0;
 	}
 	mp->m_logdev_targp = (logdev && logdev != ddev) ?
-				xfs_alloc_buftarg(logdev) : mp->m_ddev_targp;
+				xfs_alloc_buftarg(logdev, 1) : mp->m_ddev_targp;
 	if (!mp->m_logdev_targp)
 		goto error0;
 
@@ -1579,7 +1580,7 @@
 }
 
 /*
- * xfs_vget - called by DMAPI to get vnode from file handle
+ * xfs_vget - called by DMAPI and NFSD to get vnode from file handle
  */
 STATIC int
 xfs_vget(
@@ -1621,7 +1622,7 @@
 		return XFS_ERROR(EIO);
 	}
 
-	if (ip->i_d.di_mode == 0 || (igen && (ip->i_d.di_gen != igen))) {
+	if (ip->i_d.di_mode == 0 || ip->i_d.di_gen != igen) {
 		xfs_iput_new(ip, XFS_ILOCK_SHARED);
 		*vpp = NULL;
 		return XFS_ERROR(ENOENT);
@@ -1646,6 +1647,7 @@
 #define MNTOPT_SWIDTH	"swidth"	/* data volume stripe width */
 #define MNTOPT_NOUUID	"nouuid"	/* ignore filesystem UUID */
 #define MNTOPT_MTPT	"mtpt"		/* filesystem mount point */
+#define MNTOPT_IHASHSIZE    "ihashsize"    /* size of inode hash table */
 #define MNTOPT_NORECOVERY   "norecovery"   /* don't run XFS recovery */
 #define MNTOPT_NOLOGFLUSH   "nologflush"   /* don't hard flush on log writes */
 #define MNTOPT_OSYNCISOSYNC "osyncisosync" /* o_sync is REALLY o_sync */
@@ -1734,6 +1736,13 @@
 			iosize = simple_strtoul(value, &eov, 10);
 			args->flags |= XFSMNT_IOSIZE;
 			args->iosizelog = (uint8_t) iosize;
+		} else if (!strcmp(this_char, MNTOPT_IHASHSIZE)) {
+			if (!value || !*value) {
+				printk("XFS: %s option requires an argument\n",
+					this_char); 
+				return EINVAL;
+			}
+			args->ihashsize = simple_strtoul(value, &eov, 10);
 		} else if (!strcmp(this_char, MNTOPT_WSYNC)) {
 			args->flags |= XFSMNT_WSYNC;
 		} else if (!strcmp(this_char, MNTOPT_OSYNCISOSYNC)) {
diff -Nru a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
--- a/fs/xfs/xfs_vnodeops.c	2005-03-01 23:39:18 -08:00
+++ b/fs/xfs/xfs_vnodeops.c	2005-03-01 23:39:18 -08:00
@@ -3681,27 +3681,27 @@
 {
 	xfs_inode_t	*ip;
 	xfs_mount_t	*mp;
+	xfs_inode_log_item_t *iip;
 	int		error = 0;
 
 	ip = XFS_BHVTOI(bdp);
 	mp = ip->i_mount;
+	iip = ip->i_itemp;
 
 	if (XFS_FORCED_SHUTDOWN(mp))
 		return XFS_ERROR(EIO);
 
-	/* Bypass inodes which have already been cleaned by
+	/*
+	 * Bypass inodes which have already been cleaned by
 	 * the inode flush clustering code inside xfs_iflush
 	 */
 	if ((ip->i_update_core == 0) &&
-	    ((ip->i_itemp == NULL) ||
-	     !(ip->i_itemp->ili_format.ilf_fields & XFS_ILOG_ALL)))
+	    ((iip == NULL) || !(iip->ili_format.ilf_fields & XFS_ILOG_ALL)))
 		return 0;
 
 	if (flags & FLUSH_LOG) {
-		xfs_inode_log_item_t *iip = ip->i_itemp;
-
 		if (iip && iip->ili_last_lsn) {
-			xlog_t	*log = mp->m_log;
+			xlog_t		*log = mp->m_log;
 			xfs_lsn_t	sync_lsn;
 			int		s, log_flags = XFS_LOG_FORCE;
 
@@ -3714,12 +3714,12 @@
 
 			if (flags & FLUSH_SYNC)
 				log_flags |= XFS_LOG_SYNC;
-			return xfs_log_force(mp, iip->ili_last_lsn,
-						log_flags);
+			return xfs_log_force(mp, iip->ili_last_lsn, log_flags);
 		}
 	}
 
-	/* We make this non-blocking if the inode is contended,
+	/*
+	 * We make this non-blocking if the inode is contended,
 	 * return EAGAIN to indicate to the caller that they
 	 * did not succeed. This prevents the flush path from
 	 * blocking on inodes inside another operation right
@@ -3900,7 +3900,7 @@
 	int		error;
 
 	if (vp && VN_BAD(vp))
-		return 0;
+		goto reclaim;
 
 	/* The hash lock here protects a thread in xfs_iget_core from
 	 * racing with us on linking the inode back with a vnode.
@@ -3948,8 +3948,7 @@
 			 */
 			if (error) {
 				xfs_iunlock(ip, XFS_ILOCK_EXCL);
-				xfs_ireclaim(ip);
-				return (0);
+				goto reclaim;
 			}
 			xfs_iflock(ip); /* synchronize with xfs_iflush_done */
 		}
@@ -3968,6 +3967,7 @@
 		xfs_iunlock(ip, XFS_ILOCK_EXCL);
 	}
 
+ reclaim:
 	xfs_ireclaim(ip);
 	return 0;
 }
diff -Nru a/include/acpi/acconfig.h b/include/acpi/acconfig.h
--- a/include/acpi/acconfig.h	2005-03-01 23:39:08 -08:00
+++ b/include/acpi/acconfig.h	2005-03-01 23:39:08 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -64,7 +64,7 @@
 
 /* Version string */
 
-#define ACPI_CA_VERSION                 0x20041105
+#define ACPI_CA_VERSION                 0x20050211
 
 /*
  * OS name, used for the _OS object.  The _OS object is essentially obsolete,
@@ -99,7 +99,7 @@
 
 /* Version of ACPI supported */
 
-#define ACPI_CA_SUPPORT_LEVEL           2
+#define ACPI_CA_SUPPORT_LEVEL           3
 
 /* String size constants */
 
diff -Nru a/include/acpi/acdebug.h b/include/acpi/acdebug.h
--- a/include/acpi/acdebug.h	2005-03-01 23:38:53 -08:00
+++ b/include/acpi/acdebug.h	2005-03-01 23:38:53 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/include/acpi/acdisasm.h b/include/acpi/acdisasm.h
--- a/include/acpi/acdisasm.h	2005-03-01 23:38:57 -08:00
+++ b/include/acpi/acdisasm.h	2005-03-01 23:38:57 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -313,6 +313,12 @@
 void
 acpi_dm_dword_descriptor (
 	struct asl_dword_address_desc   *resource,
+	u32                             length,
+	u32                             level);
+
+void
+acpi_dm_extended_descriptor (
+	struct asl_extended_address_desc   *resource,
 	u32                             length,
 	u32                             level);
 
diff -Nru a/include/acpi/acdispat.h b/include/acpi/acdispat.h
--- a/include/acpi/acdispat.h	2005-03-01 23:39:08 -08:00
+++ b/include/acpi/acdispat.h	2005-03-01 23:39:08 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -484,9 +484,11 @@
 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
diff -Nru a/include/acpi/acevents.h b/include/acpi/acevents.h
--- a/include/acpi/acevents.h	2005-03-01 23:38:58 -08:00
+++ b/include/acpi/acevents.h	2005-03-01 23:38:58 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/include/acpi/acexcep.h b/include/acpi/acexcep.h
--- a/include/acpi/acexcep.h	2005-03-01 23:38:52 -08:00
+++ b/include/acpi/acexcep.h	2005-03-01 23:38:52 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/include/acpi/acglobal.h b/include/acpi/acglobal.h
--- a/include/acpi/acglobal.h	2005-03-01 23:38:43 -08:00
+++ b/include/acpi/acglobal.h	2005-03-01 23:38:43 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -96,6 +96,7 @@
  * 1) Allow "implicit return" of last value in a control method
  * 2) Allow access beyond end of operation region
  * 3) Allow access to uninitialized locals/args (auto-init to integer 0)
+ * 4) Allow ANY object type to be a source operand for the Store() operator
  */
 ACPI_EXTERN u8       ACPI_INIT_GLOBAL (acpi_gbl_enable_interpreter_slack, FALSE);
 
diff -Nru a/include/acpi/achware.h b/include/acpi/achware.h
--- a/include/acpi/achware.h	2005-03-01 23:38:58 -08:00
+++ b/include/acpi/achware.h	2005-03-01 23:38:58 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/include/acpi/acinterp.h b/include/acpi/acinterp.h
--- a/include/acpi/acinterp.h	2005-03-01 23:39:10 -08:00
+++ b/include/acpi/acinterp.h	2005-03-01 23:39:10 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -217,8 +217,8 @@
 u8
 acpi_ex_do_match (
 	u32                             match_op,
-	acpi_integer                    package_value,
-	acpi_integer                    match_value);
+	union acpi_operand_object       *package_obj,
+	union acpi_operand_object       *match_obj);
 
 acpi_status
 acpi_ex_get_object_reference (
@@ -617,6 +617,7 @@
 
 acpi_status
 acpi_ex_store_buffer_to_buffer (
+	acpi_object_type                original_src_type,
 	union acpi_operand_object       *source_desc,
 	union acpi_operand_object       *target_desc);
 
diff -Nru a/include/acpi/aclocal.h b/include/acpi/aclocal.h
--- a/include/acpi/aclocal.h	2005-03-01 23:39:06 -08:00
+++ b/include/acpi/aclocal.h	2005-03-01 23:39:06 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -862,7 +862,6 @@
 /*
  * Large resource descriptor types
  */
-
 #define ACPI_RDESC_TYPE_MEMORY_24               0x81
 #define ACPI_RDESC_TYPE_GENERAL_REGISTER        0x82
 #define ACPI_RDESC_TYPE_LARGE_VENDOR            0x84
@@ -872,6 +871,7 @@
 #define ACPI_RDESC_TYPE_WORD_ADDRESS_SPACE      0x88
 #define ACPI_RDESC_TYPE_EXTENDED_XRUPT          0x89
 #define ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE     0x8A
+#define ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE  0x8B
 
 
 /*****************************************************************************
diff -Nru a/include/acpi/acmacros.h b/include/acpi/acmacros.h
--- a/include/acpi/acmacros.h	2005-03-01 23:38:58 -08:00
+++ b/include/acpi/acmacros.h	2005-03-01 23:38:58 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -55,6 +55,7 @@
 
 #define ACPI_SET_BIT(target,bit)        ((target) |= (bit))
 #define ACPI_CLEAR_BIT(target,bit)      ((target) &= ~(bit))
+#define ACPI_MIN(a,b)                   (((a)<(b))?(a):(b))
 
 
 #if ACPI_MACHINE_WIDTH == 16
@@ -487,19 +488,19 @@
  * The first parameter should be the procedure name as a quoted string.  This is declared
  * as a local string ("_proc_name) so that it can be also used by the function exit macros below.
  */
-#define ACPI_FUNCTION_NAME(a)               struct acpi_debug_print_info _dbg; \
-												_dbg.component_id = _COMPONENT; \
-												_dbg.proc_name   = a; \
-												_dbg.module_name = _THIS_MODULE;
+#define ACPI_FUNCTION_NAME(a)               struct acpi_debug_print_info _debug_info; \
+												_debug_info.component_id = _COMPONENT; \
+												_debug_info.proc_name  = a; \
+												_debug_info.module_name = _THIS_MODULE;
 
 #define ACPI_FUNCTION_TRACE(a)              ACPI_FUNCTION_NAME(a) \
-												acpi_ut_trace(__LINE__,&_dbg)
+												acpi_ut_trace(__LINE__,&_debug_info)
 #define ACPI_FUNCTION_TRACE_PTR(a,b)        ACPI_FUNCTION_NAME(a) \
-												acpi_ut_trace_ptr(__LINE__,&_dbg,(void *)b)
+												acpi_ut_trace_ptr(__LINE__,&_debug_info,(void *)b)
 #define ACPI_FUNCTION_TRACE_U32(a,b)        ACPI_FUNCTION_NAME(a) \
-												acpi_ut_trace_u32(__LINE__,&_dbg,(u32)b)
+												acpi_ut_trace_u32(__LINE__,&_debug_info,(u32)b)
 #define ACPI_FUNCTION_TRACE_STR(a,b)        ACPI_FUNCTION_NAME(a) \
-												acpi_ut_trace_str(__LINE__,&_dbg,(char *)b)
+												acpi_ut_trace_str(__LINE__,&_debug_info,(char *)b)
 
 #define ACPI_FUNCTION_ENTRY()               acpi_ut_track_stack_ptr()
 
@@ -516,10 +517,10 @@
 #define ACPI_DO_WHILE0(a)               a
 #endif
 
-#define return_VOID                     ACPI_DO_WHILE0 ({acpi_ut_exit(__LINE__,&_dbg);return;})
-#define return_ACPI_STATUS(s)           ACPI_DO_WHILE0 ({acpi_ut_status_exit(__LINE__,&_dbg,(s));return((s));})
-#define return_VALUE(s)                 ACPI_DO_WHILE0 ({acpi_ut_value_exit(__LINE__,&_dbg,(acpi_integer)(s));return((s));})
-#define return_PTR(s)                   ACPI_DO_WHILE0 ({acpi_ut_ptr_exit(__LINE__,&_dbg,(u8 *)(s));return((s));})
+#define return_VOID                     ACPI_DO_WHILE0 ({acpi_ut_exit(__LINE__,&_debug_info);return;})
+#define return_ACPI_STATUS(s)           ACPI_DO_WHILE0 ({acpi_ut_status_exit(__LINE__,&_debug_info,(s));return((s));})
+#define return_VALUE(s)                 ACPI_DO_WHILE0 ({acpi_ut_value_exit(__LINE__,&_debug_info,(acpi_integer)(s));return((s));})
+#define return_PTR(s)                   ACPI_DO_WHILE0 ({acpi_ut_ptr_exit(__LINE__,&_debug_info,(u8 *)(s));return((s));})
 
 /* Conditional execution */
 
diff -Nru a/include/acpi/acnamesp.h b/include/acpi/acnamesp.h
--- a/include/acpi/acnamesp.h	2005-03-01 23:38:52 -08:00
+++ b/include/acpi/acnamesp.h	2005-03-01 23:38:52 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/include/acpi/acobject.h b/include/acpi/acobject.h
--- a/include/acpi/acobject.h	2005-03-01 23:38:52 -08:00
+++ b/include/acpi/acobject.h	2005-03-01 23:38:52 -08:00
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -94,9 +94,7 @@
 	u32                                     bit_length;         /* Length of field in bits */\
 	u32                                     base_byte_offset;   /* Byte offset within containing object */\
 	u8                                      start_field_bit_offset;/* Bit offset within first field datum (0-63) */\
-	u8                                      datum_valid_bits;   /* Valid bit in first "Field datum" */\
-	u8                                      end_field_valid_bits; /* Valid bits in the last "field datum" */\
-	u8                                      end_buffer_valid_bits; /* Valid bits in the last "buffer datum" */\
+	u8                                      access_bit_width;   /* Read/Write size in bits (8-64) */\
 	u32                                     value;              /* Value to store into the Bank or Index register */\
 	struct acpi_namespace_node              *node;              /* Link back to parent node */
 
diff -Nru a/include/acpi/acoutput.h b/include/acpi/acoutput.h
--- a/include/acpi/acoutput.h	2005-03-01 23:38:55 -08:00
+++ b/include/acpi/acoutput.h	2005-03-01 23:38:55 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -136,7 +136,7 @@
 /*
  * Debug level macros that are used in the DEBUG_PRINT macros
  */
-#define ACPI_DEBUG_LEVEL(dl)        (u32) dl,__LINE__,&_dbg
+#define ACPI_DEBUG_LEVEL(dl)        (u32) dl,__LINE__,&_debug_info
 
 /* Exception level -- used in the global "debug_level" */
 
diff -Nru a/include/acpi/acparser.h b/include/acpi/acparser.h
--- a/include/acpi/acparser.h	2005-03-01 23:39:07 -08:00
+++ b/include/acpi/acparser.h	2005-03-01 23:39:07 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -303,9 +303,11 @@
 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 (
diff -Nru a/include/acpi/acpi.h b/include/acpi/acpi.h
--- a/include/acpi/acpi.h	2005-03-01 23:38:57 -08:00
+++ b/include/acpi/acpi.h	2005-03-01 23:38:57 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
--- a/include/acpi/acpi_bus.h	2005-03-01 23:39:18 -08:00
+++ b/include/acpi/acpi_bus.h	2005-03-01 23:39:18 -08:00
@@ -104,6 +104,7 @@
 typedef int (*acpi_op_resume)	(struct acpi_device *device, int state);
 typedef int (*acpi_op_scan)	(struct acpi_device *device);
 typedef int (*acpi_op_bind)	(struct acpi_device *device);
+typedef int (*acpi_op_unbind)	(struct acpi_device *device);
 typedef int (*acpi_op_match)	(struct acpi_device *device,
 				 struct acpi_driver *driver);
 
@@ -117,6 +118,7 @@
 	acpi_op_resume		resume;
 	acpi_op_scan		scan;
 	acpi_op_bind		bind;
+	acpi_op_unbind		unbind;
 	acpi_op_match		match;
 };
 
@@ -316,7 +318,8 @@
  * External Functions
  */
 
-int acpi_bus_get_device(acpi_handle, struct acpi_device **device);
+int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device);
+void acpi_bus_data_handler(acpi_handle handle, u32 function, void *context);
 int acpi_bus_get_status (struct acpi_device *device);
 int acpi_bus_get_power (acpi_handle handle, int *state);
 int acpi_bus_set_power (acpi_handle handle, int state);
@@ -324,6 +327,11 @@
 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_trim(struct acpi_device *start, int rmdevice);
+int acpi_bus_add (struct acpi_device **child, struct acpi_device *parent,
+		acpi_handle handle, int type);
+
 
 int acpi_match_ids (struct acpi_device	*device, char	*ids);
 int acpi_create_dir(struct acpi_device *);
diff -Nru a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h
--- a/include/acpi/acpi_drivers.h	2005-03-01 23:39:08 -08:00
+++ b/include/acpi/acpi_drivers.h	2005-03-01 23:39:08 -08:00
@@ -61,12 +61,14 @@
 /* ACPI PCI Interrupt Routing (pci_irq.c) */
 
 int acpi_pci_irq_add_prt (acpi_handle handle, int segment, int bus);
+void acpi_pci_irq_del_prt (int segment, int bus);
 
 /* ACPI PCI Device Binding (pci_bind.c) */
 
 struct pci_bus;
 
 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);
 
 /* Arch-defined function to add a bus to the system */
diff -Nru a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h
--- a/include/acpi/acpiosxf.h	2005-03-01 23:38:51 -08:00
+++ b/include/acpi/acpiosxf.h	2005-03-01 23:38:51 -08:00
@@ -9,7 +9,7 @@
 
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/include/acpi/acpixf.h b/include/acpi/acpixf.h
--- a/include/acpi/acpixf.h	2005-03-01 23:38:44 -08:00
+++ b/include/acpi/acpixf.h	2005-03-01 23:38:44 -08:00
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -345,11 +345,11 @@
 	u32                             event,
 	u32                             flags);
 
-#ifdef ACPI_FUTURE_USAGE
 acpi_status
 acpi_clear_event (
 	u32                             event);
 
+#ifdef ACPI_FUTURE_USAGE
 acpi_status
 acpi_get_event_status (
 	u32                             event,
diff -Nru a/include/acpi/acresrc.h b/include/acpi/acresrc.h
--- a/include/acpi/acresrc.h	2005-03-01 23:38:52 -08:00
+++ b/include/acpi/acresrc.h	2005-03-01 23:38:52 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/include/acpi/acstruct.h b/include/acpi/acstruct.h
--- a/include/acpi/acstruct.h	2005-03-01 23:38:52 -08:00
+++ b/include/acpi/acstruct.h	2005-03-01 23:38:52 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/include/acpi/actables.h b/include/acpi/actables.h
--- a/include/acpi/actables.h	2005-03-01 23:38:54 -08:00
+++ b/include/acpi/actables.h	2005-03-01 23:38:54 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/include/acpi/actbl.h b/include/acpi/actbl.h
--- a/include/acpi/actbl.h	2005-03-01 23:38:57 -08:00
+++ b/include/acpi/actbl.h	2005-03-01 23:38:57 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/include/acpi/actbl1.h b/include/acpi/actbl1.h
--- a/include/acpi/actbl1.h	2005-03-01 23:38:53 -08:00
+++ b/include/acpi/actbl1.h	2005-03-01 23:38:53 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/include/acpi/actbl2.h b/include/acpi/actbl2.h
--- a/include/acpi/actbl2.h	2005-03-01 23:38:59 -08:00
+++ b/include/acpi/actbl2.h	2005-03-01 23:38:59 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -115,7 +115,7 @@
 	u8                              address_space_id;       /* Address space where struct or register exists. */
 	u8                              register_bit_width;     /* Size in bits of given register */
 	u8                              register_bit_offset;    /* Bit offset within the register */
-	u8                              reserved;               /* Must be 0 */
+	u8                              access_width;           /* Minimum Access size (ACPI 3.0) */
 	u64                             address;                /* 64-bit address of struct or register */
 };
 
diff -Nru a/include/acpi/actypes.h b/include/acpi/actypes.h
--- a/include/acpi/actypes.h	2005-03-01 23:38:58 -08:00
+++ b/include/acpi/actypes.h	2005-03-01 23:38:58 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/include/acpi/acutils.h b/include/acpi/acutils.h
--- a/include/acpi/acutils.h	2005-03-01 23:38:44 -08:00
+++ b/include/acpi/acutils.h	2005-03-01 23:38:44 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -683,6 +683,7 @@
 acpi_ut_delete_generic_state (
 	union acpi_generic_state        *state);
 
+#ifdef ACPI_ENABLE_OBJECT_CACHE
 void
 acpi_ut_delete_generic_state_cache (
 	void);
@@ -690,6 +691,7 @@
 void
 acpi_ut_delete_object_cache (
 	void);
+#endif
 
 /*
  * utmisc
@@ -778,9 +780,11 @@
 	u32                             list_id,
 	void                            *object);
 
+#ifdef ACPI_ENABLE_OBJECT_CACHE
 void
 acpi_ut_delete_generic_cache (
 	u32                             list_id);
+#endif
 
 acpi_status
 acpi_ut_validate_buffer (
diff -Nru a/include/acpi/amlcode.h b/include/acpi/amlcode.h
--- a/include/acpi/amlcode.h	2005-03-01 23:39:07 -08:00
+++ b/include/acpi/amlcode.h	2005-03-01 23:39:07 -08:00
@@ -7,7 +7,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -278,6 +278,7 @@
 #define ARGI_COMPLEXOBJ             0x13    /* Buffer, String, or package (Used by INDEX op only) */
 #define ARGI_REF_OR_STRING          0x14    /* Reference or String (Used by DEREFOF op only) */
 #define ARGI_REGION_OR_FIELD        0x15    /* Used by LOAD op only */
+#define ARGI_DATAREFOBJ             0x16
 
 /* Note: types above can expand to 0x1F maximum */
 
@@ -320,6 +321,7 @@
 #define AML_HAS_TARGET              0x0800
 #define AML_HAS_ARGS                0x1000
 #define AML_CONSTANT                0x2000
+#define AML_NO_OPERAND_RESOLVE      0x4000
 
 /* Convenient flag groupings */
 
diff -Nru a/include/acpi/amlresrc.h b/include/acpi/amlresrc.h
--- a/include/acpi/amlresrc.h	2005-03-01 23:39:16 -08:00
+++ b/include/acpi/amlresrc.h	2005-03-01 23:39:16 -08:00
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -50,6 +50,8 @@
 #define ASL_RESNAME_ADDRESS                     "_ADR"
 #define ASL_RESNAME_ALIGNMENT                   "_ALN"
 #define ASL_RESNAME_ADDRESSSPACE                "_ASI"
+#define ASL_RESNAME_ACCESSSIZE                  "_ASZ"
+#define ASL_RESNAME_TYPESPECIFICATTRIBUTES      "_ATT"
 #define ASL_RESNAME_BASEADDRESS                 "_BAS"
 #define ASL_RESNAME_BUSMASTER                   "_BM_"  /* Master(1), Slave(0) */
 #define ASL_RESNAME_DECODE                      "_DEC"
@@ -223,6 +225,27 @@
 };
 
 
+struct asl_extended_address_desc
+{
+	u8                                  descriptor_type;
+	u16                                 length;
+	u8                                  resource_type;
+	u8                                  flags;
+	u8                                  specific_flags;
+	u8                                  revision_iD;
+	u8                                  reserved;
+	u64                                 granularity;
+	u64                                 address_min;
+	u64                                 address_max;
+	u64                                 translation_offset;
+	u64                                 address_length;
+	u64                                 type_specific_attributes;
+	u8                                  optional_fields[2]; /* Used for length calculation only */
+};
+
+#define ASL_EXTENDED_ADDRESS_DESC_REVISION          1       /* ACPI 3.0 */
+
+
 struct asl_qword_address_desc
 {
 	u8                                  descriptor_type;
@@ -289,7 +312,7 @@
 	u8                                  address_space_id;
 	u8                                  bit_width;
 	u8                                  bit_offset;
-	u8                                  reserved;
+	u8                                  access_size; /* ACPI 3.0, was Reserved */
 	u64                                 address;
 };
 
@@ -317,6 +340,7 @@
 	struct asl_qword_address_desc       qas;
 	struct asl_dword_address_desc       das;
 	struct asl_word_address_desc        was;
+	struct asl_extended_address_desc    eas;
 	struct asl_extended_xrupt_desc      exx;
 	struct asl_general_register_desc    grg;
 	u32                                 u32_item;
diff -Nru a/include/acpi/container.h b/include/acpi/container.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/acpi/container.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,13 @@
+#ifndef __ACPI_CONTAINER_H
+#define __ACPI_CONTAINER_H
+
+#include <linux/kernel.h>
+
+struct acpi_container {
+	acpi_handle handle;
+	unsigned long sun;
+	int state;
+};
+
+#endif /* __ACPI_CONTAINER_H */
+
diff -Nru a/include/acpi/platform/acenv.h b/include/acpi/platform/acenv.h
--- a/include/acpi/platform/acenv.h	2005-03-01 23:38:53 -08:00
+++ b/include/acpi/platform/acenv.h	2005-03-01 23:38:53 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -57,6 +57,7 @@
 #define ACPI_DISASSEMBLER
 #define ACPI_NO_METHOD_EXECUTION
 #define ACPI_USE_SYSTEM_CLIBRARY
+#define ACPI_ENABLE_OBJECT_CACHE
 #endif
 
 #ifdef _ACPI_EXEC_APP
@@ -67,6 +68,7 @@
 #define ACPI_DEBUGGER
 #define ACPI_DISASSEMBLER
 #define ACPI_USE_SYSTEM_CLIBRARY
+#define ACPI_ENABLE_OBJECT_CACHE
 #endif
 
 #ifdef _ACPI_ASL_COMPILER
@@ -75,6 +77,7 @@
 #define ACPI_DISASSEMBLER
 #define ACPI_CONSTANT_EVAL_ONLY
 #define ACPI_USE_SYSTEM_CLIBRARY
+#define ACPI_ENABLE_OBJECT_CACHE
 #endif
 
 /*
diff -Nru a/include/acpi/platform/acgcc.h b/include/acpi/platform/acgcc.h
--- a/include/acpi/platform/acgcc.h	2005-03-01 23:39:17 -08:00
+++ b/include/acpi/platform/acgcc.h	2005-03-01 23:39:17 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru a/include/acpi/platform/aclinux.h b/include/acpi/platform/aclinux.h
--- a/include/acpi/platform/aclinux.h	2005-03-01 23:39:08 -08:00
+++ b/include/acpi/platform/aclinux.h	2005-03-01 23:39:08 -08:00
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2004, R. Byron Moore
+ * Copyright (C) 2000 - 2005, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -81,6 +81,8 @@
 #define ACPI_USE_NATIVE_DIVIDE
 #endif
 
+#define __cdecl
+#define ACPI_FLUSH_CPU_CACHE()
 #endif /* __KERNEL__ */
 
 /* Linux uses GCC */
diff -Nru a/include/acpi/processor.h b/include/acpi/processor.h
--- a/include/acpi/processor.h	2005-03-01 23:38:56 -08:00
+++ b/include/acpi/processor.h	2005-03-01 23:38:56 -08:00
@@ -2,10 +2,11 @@
 #define __ACPI_PROCESSOR_H
 
 #include <linux/kernel.h>
+#include <linux/config.h>
 
 #define ACPI_PROCESSOR_BUSY_METRIC	10
 
-#define ACPI_PROCESSOR_MAX_POWER	ACPI_C_STATE_COUNT
+#define ACPI_PROCESSOR_MAX_POWER	8
 #define ACPI_PROCESSOR_MAX_C2_LATENCY	100
 #define ACPI_PROCESSOR_MAX_C3_LATENCY	1000
 
@@ -15,9 +16,22 @@
 
 /* Power Management */
 
+struct acpi_processor_cx;
+
+struct acpi_power_register {
+	u8			descriptor;
+	u16			length;
+	u8			space_id;
+	u8			bit_width;
+	u8			bit_offset;
+	u8			reserved;
+	u64			address;
+} __attribute__ ((packed));
+
+
 struct acpi_processor_cx_policy {
 	u32			count;
-	u32			state;
+	struct acpi_processor_cx *state;
 	struct {
 		u32			time;
 		u32			ticks;
@@ -28,6 +42,7 @@
 
 struct acpi_processor_cx {
 	u8			valid;
+	u8			type;
 	u32			address;
 	u32			latency;
 	u32			latency_ticks;
@@ -38,9 +53,11 @@
 };
 
 struct acpi_processor_power {
-	u32			state;
+	struct acpi_processor_cx *state;
+	unsigned long		bm_check_timestamp;
 	u32			default_state;
 	u32			bm_activity;
+	int			count;
 	struct acpi_processor_cx states[ACPI_PROCESSOR_MAX_POWER];
 };
 
@@ -118,13 +135,15 @@
 	u8			limit:1;
 	u8			bm_control:1;
 	u8			bm_check:1;
-	u8			reserved:2;
+	u8			has_cst:1;
+	u8			power_setup_done:1;
 };
 
 struct acpi_processor {
 	acpi_handle		handle;
 	u32			acpi_id;
 	u32			id;
+	u32			pblk;
 	int			performance_platform_limit;
 	struct acpi_processor_flags flags;
 	struct acpi_processor_power power;
@@ -133,6 +152,16 @@
 	struct acpi_processor_limit limit;
 };
 
+struct acpi_processor_errata {
+	u8			smp;
+	struct {
+		u8			throttle:1;
+		u8			fdma:1;
+		u8			reserved:6;
+		u32			bmisx;
+	}			piix4;
+};
+
 extern int acpi_processor_register_performance (
 	struct acpi_processor_performance * performance,
 	unsigned int cpu);
@@ -143,5 +172,66 @@
 /* note: this locks both the calling module and the processor module
          if a _PPC object exists, rmmod is disallowed then */
 int acpi_processor_notify_smm(struct module *calling_module);
+
+
+
+/* for communication between multiple parts of the processor kernel module */
+extern struct acpi_processor	*processors[NR_CPUS];
+extern struct acpi_processor_errata errata;
+
+/* in processor_perflib.c */
+#ifdef CONFIG_CPU_FREQ
+void acpi_processor_ppc_init(void);
+void acpi_processor_ppc_exit(void);
+int acpi_processor_ppc_has_changed(struct acpi_processor *pr);
+#else
+static inline void acpi_processor_ppc_init(void) { return; }
+static inline void acpi_processor_ppc_exit(void) { return; }
+static inline int acpi_processor_ppc_has_changed(struct acpi_processor *pr) {
+	static unsigned int printout = 1;
+	if (printout) {
+		printk(KERN_WARNING "Warning: Processor Platform Limit event detected, but not handled.\n");
+		printk(KERN_WARNING "Consider compiling CPUfreq support into your kernel.\n");
+		printout = 0;
+	}
+	return 0;
+}
+#endif /* CONFIG_CPU_FREQ */
+
+/* in processor_throttling.c */
+int acpi_processor_get_throttling_info (struct acpi_processor *pr);
+int acpi_processor_set_throttling (struct acpi_processor *pr, int state);
+int acpi_processor_throttling_open_fs(struct inode *inode, struct file *file);
+ssize_t acpi_processor_write_throttling (
+        struct file		*file,
+        const char		__user *buffer,
+        size_t			count,
+        loff_t			*data);
+extern struct file_operations acpi_processor_throttling_fops;
+
+/* in processor_idle.c */
+int acpi_processor_power_init(struct acpi_processor *pr, struct acpi_device *device);
+int acpi_processor_cst_has_changed (struct acpi_processor *pr);
+int acpi_processor_power_exit(struct acpi_processor *pr, struct acpi_device *device);
+
+
+/* in processor_thermal.c */
+int acpi_processor_get_limit_info (struct acpi_processor *pr);
+int acpi_processor_limit_open_fs(struct inode *inode, struct file *file);
+ssize_t acpi_processor_write_limit (
+	struct file		*file,
+	const char		__user *buffer,
+	size_t			count,
+	loff_t			*data);
+extern struct file_operations acpi_processor_limit_fops;
+
+#ifdef CONFIG_CPU_FREQ
+void acpi_thermal_cpufreq_init(void);
+void acpi_thermal_cpufreq_exit(void);
+#else
+static inline void acpi_thermal_cpufreq_init(void) { return; }
+static inline void acpi_thermal_cpufreq_exit(void) { return; }
+#endif
+
 
 #endif
diff -Nru a/include/asm-alpha/bitops.h b/include/asm-alpha/bitops.h
--- a/include/asm-alpha/bitops.h	2005-03-01 23:38:57 -08:00
+++ b/include/asm-alpha/bitops.h	2005-03-01 23:38:57 -08:00
@@ -376,12 +376,13 @@
  * Find next zero bit in a bitmap reasonably efficiently..
  */
 static inline unsigned long
-find_next_zero_bit(void * addr, unsigned long size, unsigned long offset)
+find_next_zero_bit(const void *addr, unsigned long size, unsigned long offset)
 {
-	unsigned long * p = ((unsigned long *) addr) + (offset >> 6);
+	const unsigned long *p = addr;
 	unsigned long result = offset & ~63UL;
 	unsigned long tmp;
 
+	p += offset >> 6;
 	if (offset >= size)
 		return size;
 	size -= result;
@@ -419,10 +420,11 @@
 static inline unsigned long
 find_next_bit(const void * addr, unsigned long size, unsigned long offset)
 {
-	const unsigned long * p = ((const unsigned long *) addr) + (offset >> 6);
+	const unsigned long *p = addr;
 	unsigned long result = offset & ~63UL;
 	unsigned long tmp;
 
+	p += offset >> 6;
 	if (offset >= size)
 		return size;
 	size -= result;
diff -Nru a/include/asm-alpha/cputime.h b/include/asm-alpha/cputime.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-alpha/cputime.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,6 @@
+#ifndef __ALPHA_CPUTIME_H
+#define __ALPHA_CPUTIME_H
+
+#include <asm-generic/cputime.h>
+
+#endif /* __ALPHA_CPUTIME_H */
diff -Nru a/include/asm-alpha/dma-mapping.h b/include/asm-alpha/dma-mapping.h
--- a/include/asm-alpha/dma-mapping.h	2005-03-01 23:39:18 -08:00
+++ b/include/asm-alpha/dma-mapping.h	2005-03-01 23:39:18 -08:00
@@ -25,6 +25,8 @@
 		pci_unmap_sg(alpha_gendev_to_pci(dev), sg, nents, dir)
 #define dma_supported(dev, mask)			\
 		pci_dma_supported(alpha_gendev_to_pci(dev), mask)
+#define dma_mapping_error(addr)				\
+		pci_dma_mapping_error(addr)
 
 #else	/* no PCI - no IOMMU. */
 
@@ -42,6 +44,8 @@
 #define dma_unmap_single(dev, addr, size, dir)	do { } while (0)
 #define dma_unmap_page(dev, addr, size, dir)	do { } while (0)
 #define dma_unmap_sg(dev, sg, nents, dir)	do { } while (0)
+
+#define dma_mapping_error(addr)  (0)
 
 #endif	/* !CONFIG_PCI */
 
diff -Nru a/include/asm-alpha/hardirq.h b/include/asm-alpha/hardirq.h
--- a/include/asm-alpha/hardirq.h	2005-03-01 23:39:07 -08:00
+++ b/include/asm-alpha/hardirq.h	2005-03-01 23:39:07 -08:00
@@ -9,9 +9,6 @@
 /* entry.S is sensitive to the offsets of these fields */
 typedef struct {
 	unsigned long __softirq_pending;
-	unsigned int __syscall_count;
-	unsigned long idle_timestamp;
-	struct task_struct * __ksoftirqd_task;
 } ____cacheline_aligned irq_cpustat_t;
 
 #include <linux/irq_cpustat.h>	/* Standard mappings for irq_cpustat_t above */
@@ -28,15 +25,5 @@
 #if (1 << HARDIRQ_BITS) < 16
 #error HARDIRQ_BITS is too low!
 #endif
-
-#define irq_enter()		(preempt_count() += HARDIRQ_OFFSET)
-#define irq_exit()						\
-do {								\
-		preempt_count() -= IRQ_EXIT_OFFSET;		\
-		if (!in_interrupt() &&				\
-		    softirq_pending(smp_processor_id()))	\
-			do_softirq();				\
-		preempt_enable_no_resched();			\
-} while (0)
 
 #endif /* _ALPHA_HARDIRQ_H */
diff -Nru a/include/asm-alpha/io_trivial.h b/include/asm-alpha/io_trivial.h
--- a/include/asm-alpha/io_trivial.h	2005-03-01 23:38:56 -08:00
+++ b/include/asm-alpha/io_trivial.h	2005-03-01 23:38:56 -08:00
@@ -26,7 +26,7 @@
 __EXTERN_INLINE void
 IO_CONCAT(__IO_PREFIX,iowrite16)(u16 b, void __iomem *a)
 {
-	__kernel_stb(b, *(volatile u16 __force *)a);
+	__kernel_stw(b, *(volatile u16 __force *)a);
 }
 #endif
 
@@ -66,7 +66,7 @@
 __EXTERN_INLINE void
 IO_CONCAT(__IO_PREFIX,writew)(u16 b, volatile void __iomem *a)
 {
-	__kernel_stb(b, *(volatile u16 __force *)a);
+	__kernel_stw(b, *(volatile u16 __force *)a);
 }
 #elif IO_CONCAT(__IO_PREFIX,trivial_rw_bw) == 2
 __EXTERN_INLINE u8
diff -Nru a/include/asm-alpha/page.h b/include/asm-alpha/page.h
--- a/include/asm-alpha/page.h	2005-03-01 23:39:08 -08:00
+++ b/include/asm-alpha/page.h	2005-03-01 23:39:08 -08:00
@@ -18,6 +18,9 @@
 extern void clear_page(void *page);
 #define clear_user_page(page, vaddr, pg)	clear_page(page)
 
+#define alloc_zeroed_user_highpage(vma, vaddr) alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO, vma, vmaddr)
+#define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE
+
 extern void copy_page(void * _to, void * _from);
 #define copy_user_page(to, from, vaddr, pg)	copy_page(to, from)
 
diff -Nru a/include/asm-alpha/pgalloc.h b/include/asm-alpha/pgalloc.h
--- a/include/asm-alpha/pgalloc.h	2005-03-01 23:39:18 -08:00
+++ b/include/asm-alpha/pgalloc.h	2005-03-01 23:39:18 -08:00
@@ -40,9 +40,7 @@
 static inline pmd_t *
 pmd_alloc_one(struct mm_struct *mm, unsigned long address)
 {
-	pmd_t *ret = (pmd_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT);
-	if (ret)
-		clear_page(ret);
+	pmd_t *ret = (pmd_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO);
 	return ret;
 }
 
diff -Nru a/include/asm-alpha/pgtable.h b/include/asm-alpha/pgtable.h
--- a/include/asm-alpha/pgtable.h	2005-03-01 23:38:54 -08:00
+++ b/include/asm-alpha/pgtable.h	2005-03-01 23:38:54 -08:00
@@ -1,6 +1,8 @@
 #ifndef _ALPHA_PGTABLE_H
 #define _ALPHA_PGTABLE_H
 
+#include <asm-generic/4level-fixup.h>
+
 /*
  * This file contains the functions and defines necessary to modify and use
  * the Alpha page table tree.
@@ -192,7 +194,7 @@
  * and a page entry and page directory to the page they refer to.
  */
 #ifndef CONFIG_DISCONTIGMEM
-#define page_to_pa(page)	((page - mem_map) << PAGE_SHIFT)
+#define page_to_pa(page)	(((page) - mem_map) << PAGE_SHIFT)
 
 #define pte_pfn(pte)	(pte_val(pte) >> 32)
 #define pte_page(pte)	pfn_to_page(pte_pfn(pte))
@@ -270,10 +272,10 @@
 #define PAGE_DIR_OFFSET(tsk,address) pgd_offset((tsk),(address))
 
 /* to find an entry in a kernel page-table-directory */
-#define pgd_offset_k(address) pgd_offset(&init_mm, address)
+#define pgd_offset_k(address) pgd_offset(&init_mm, (address))
 
 /* 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))
 #define pgd_offset(mm, address)	((mm)->pgd+pgd_index(address))
 
 /* Find an entry in the second-level page table.. */
diff -Nru a/include/asm-alpha/processor.h b/include/asm-alpha/processor.h
--- a/include/asm-alpha/processor.h	2005-03-01 23:39:17 -08:00
+++ b/include/asm-alpha/processor.h	2005-03-01 23:39:17 -08:00
@@ -26,12 +26,6 @@
 #define TASK_UNMAPPED_BASE \
   ((current->personality & ADDR_LIMIT_32BIT) ? 0x40000000 : TASK_SIZE / 2)
 
-/*
- * Bus types
- */
-#define MCA_bus 0
-#define MCA_bus__is_a_macro /* for versions in ksyms.c */
-
 typedef struct {
 	unsigned long seg;
 } mm_segment_t;
diff -Nru a/include/asm-alpha/resource.h b/include/asm-alpha/resource.h
--- a/include/asm-alpha/resource.h	2005-03-01 23:38:52 -08:00
+++ b/include/asm-alpha/resource.h	2005-03-01 23:38:52 -08:00
@@ -20,6 +20,7 @@
 #define RLIMIT_MSGQUEUE 12		/* maximum bytes in POSIX mqueues */
 
 #define RLIM_NLIMITS	13
+#define __ARCH_RLIMIT_ORDER
 
 /*
  * SuS says limits have to be unsigned.  Fine, it's unsigned, but
@@ -28,25 +29,6 @@
  */
 #define RLIM_INFINITY	0x7ffffffffffffffful
 
-#ifdef __KERNEL__
-
-#define INIT_RLIMITS							\
-{									\
-    {LONG_MAX, LONG_MAX},			/* RLIMIT_CPU */	\
-    {LONG_MAX, LONG_MAX},			/* RLIMIT_FSIZE */	\
-    {LONG_MAX, LONG_MAX},			/* RLIMIT_DATA */	\
-    {_STK_LIM, LONG_MAX},			/* RLIMIT_STACK */	\
-    {       0, LONG_MAX},			/* RLIMIT_CORE */	\
-    {LONG_MAX, LONG_MAX},			/* RLIMIT_RSS */	\
-    {INR_OPEN, INR_OPEN},			/* RLIMIT_NOFILE */	\
-    {LONG_MAX, LONG_MAX},			/* RLIMIT_AS */		\
-    {LONG_MAX, LONG_MAX},			/* RLIMIT_NPROC */	\
-    {MLOCK_LIMIT, MLOCK_LIMIT },		/* RLIMIT_MEMLOCK */	\
-    {LONG_MAX, LONG_MAX},			/* RLIMIT_LOCKS */	\
-    {MAX_SIGPENDING, MAX_SIGPENDING},		/* RLIMIT_SIGPENDING */ \
-    {MQ_BYTES_MAX, MQ_BYTES_MAX},		/* RLIMIT_MSGQUEUE */	\
-}
-
-#endif /* __KERNEL__ */
+#include <asm-generic/resource.h>
 
 #endif /* _ALPHA_RESOURCE_H */
diff -Nru a/include/asm-alpha/spinlock.h b/include/asm-alpha/spinlock.h
--- a/include/asm-alpha/spinlock.h	2005-03-01 23:39:07 -08:00
+++ b/include/asm-alpha/spinlock.h	2005-03-01 23:39:07 -08:00
@@ -23,6 +23,9 @@
 	struct task_struct * task;
 	const char *base_file;
 #endif
+#ifdef CONFIG_PREEMPT
+	unsigned int break_lock;
+#endif
 } spinlock_t;
 
 #ifdef CONFIG_DEBUG_SPINLOCK
@@ -96,12 +99,14 @@
 
 typedef struct {
 	volatile unsigned int write_lock:1, read_counter:31;
+#ifdef CONFIG_PREEMPT
+	unsigned int break_lock;
+#endif
 } /*__attribute__((aligned(32)))*/ rwlock_t;
 
 #define RW_LOCK_UNLOCKED (rwlock_t) { 0, 0 }
 
 #define rwlock_init(x)	do { *(x) = RW_LOCK_UNLOCKED; } while(0)
-#define rwlock_is_locked(x)	(*(volatile int *)(x) != 0)
 
 #ifdef CONFIG_DEBUG_RWLOCK
 extern void _raw_write_lock(rwlock_t * lock);
diff -Nru a/include/asm-alpha/string.h b/include/asm-alpha/string.h
--- a/include/asm-alpha/string.h	2005-03-01 23:38:55 -08:00
+++ b/include/asm-alpha/string.h	2005-03-01 23:38:55 -08:00
@@ -13,7 +13,6 @@
 #define __HAVE_ARCH_MEMCPY
 extern void * memcpy(void *, const void *, size_t);
 #define __HAVE_ARCH_MEMMOVE
-#define __HAVE_ARCH_BCOPY
 extern void * memmove(void *, const void *, size_t);
 
 /* For backward compatibility with modules.  Unused otherwise.  */
diff -Nru a/include/asm-alpha/thread_info.h b/include/asm-alpha/thread_info.h
--- a/include/asm-alpha/thread_info.h	2005-03-01 23:39:16 -08:00
+++ b/include/asm-alpha/thread_info.h	2005-03-01 23:39:16 -08:00
@@ -77,6 +77,7 @@
 #define TIF_UAC_NOPRINT		6	/* see sysinfo.h */
 #define TIF_UAC_NOFIX		7
 #define TIF_UAC_SIGBUS		8
+#define TIF_MEMDIE		9
 
 #define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE)
 #define _TIF_NOTIFY_RESUME	(1<<TIF_NOTIFY_RESUME)
diff -Nru a/include/asm-alpha/uaccess.h b/include/asm-alpha/uaccess.h
--- a/include/asm-alpha/uaccess.h	2005-03-01 23:39:09 -08:00
+++ b/include/asm-alpha/uaccess.h	2005-03-01 23:39:09 -08:00
@@ -91,7 +91,8 @@
 
 #define __get_user_nocheck(x,ptr,size)				\
 ({								\
-	long __gu_err = 0, __gu_val;				\
+	long __gu_err = 0;					\
+	unsigned long __gu_val;					\
 	__chk_user_ptr(ptr);					\
 	switch (size) {						\
 	  case 1: __get_user_8(ptr); break;			\
@@ -106,7 +107,8 @@
 
 #define __get_user_check(x,ptr,size,segment)				\
 ({									\
-	long __gu_err = -EFAULT, __gu_val = 0;				\
+	long __gu_err = -EFAULT;					\
+	unsigned long __gu_val = 0;					\
 	const __typeof__(*(ptr)) __user *__gu_addr = (ptr);		\
 	if (__access_ok((unsigned long)__gu_addr,size,segment)) {	\
 		__gu_err = 0;						\
@@ -123,7 +125,7 @@
 })
 
 struct __large_struct { unsigned long buf[100]; };
-#define __m(x) (*(struct __large_struct *)(x))
+#define __m(x) (*(struct __large_struct __user *)(x))
 
 #define __get_user_64(addr)				\
 	__asm__("1: ldq %0,%2\n"			\
diff -Nru a/include/asm-arm/arch-cl7500/debug-macro.S b/include/asm-arm/arch-cl7500/debug-macro.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-arm/arch-cl7500/debug-macro.S	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,31 @@
+/* linux/include/asm-arm/arch-cl7500/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ *  Copyright (C) 1994-1999 Russell King
+ *  Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+		.macro	addruart,rx
+		mov	\rx, #0xe0000000
+		orr	\rx, \rx, #0x00010000
+		orr	\rx, \rx, #0x00000be0
+		.endm
+
+		.macro	senduart,rd,rx
+		strb	\rd, [\rx]
+		.endm
+
+		.macro	busyuart,rd,rx
+		.endm
+
+		.macro	waituart,rd,rx
+1001:		ldrb	\rd, [\rx, #0x14]
+		tst	\rd, #0x20
+		beq	1001b
+		.endm
diff -Nru a/include/asm-arm/arch-cl7500/entry-macro.S b/include/asm-arm/arch-cl7500/entry-macro.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-arm/arch-cl7500/entry-macro.S	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,3 @@
+
+#include <asm/hardware/entry-macro-iomd.S>
+
diff -Nru a/include/asm-arm/arch-clps711x/debug-macro.S b/include/asm-arm/arch-clps711x/debug-macro.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-arm/arch-clps711x/debug-macro.S	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,46 @@
+/* linux/include/asm-arm/arch-clps711x/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ *  Copyright (C) 1994-1999 Russell King
+ *  Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+#include <asm/hardware/clps7111.h>
+
+		.macro	addruart,rx
+		mrc	p15, 0, \rx, c1, c0
+		tst	\rx, #1			@ MMU enabled?
+		moveq	\rx, #CLPS7111_PHYS_BASE
+		movne	\rx, #CLPS7111_VIRT_BASE
+#ifndef CONFIG_DEBUG_CLPS711X_UART2
+		add	\rx, \rx, #0x0000	@ UART1
+#else
+		add	\rx, \rx, #0x1000	@ UART2
+#endif
+		.endm
+
+		.macro	senduart,rd,rx
+		str	\rd, [\rx, #0x0480]	@ UARTDR
+		.endm
+
+		.macro	waituart,rd,rx
+1001:		ldr	\rd, [\rx, #0x0140]	@ SYSFLGx
+		tst	\rd, #1 << 11		@ UBUSYx
+		bne	1001b
+		.endm
+
+		.macro	busyuart,rd,rx
+		tst	\rx, #0x1000		@ UART2 does not have CTS here
+		bne	1002f
+1001:		ldr	\rd, [\rx, #0x0140]	@ SYSFLGx
+		tst	\rd, #1 << 8		@ CTS
+		bne	1001b
+1002:
+		.endm
+
diff -Nru a/include/asm-arm/arch-clps711x/entry-macro.S b/include/asm-arm/arch-clps711x/entry-macro.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-arm/arch-clps711x/entry-macro.S	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,51 @@
+/*
+ * include/asm-arm/arch-CLPS711x/entry-macro.S
+ *
+ * Low-level IRQ helper macros for CLPS711X-based platforms
+ *
+ * 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 <asm/hardware/clps7111.h>
+
+		.macro	disable_fiq
+		.endm
+
+#if (INTSR2 - INTSR1) != (INTMR2 - INTMR1)
+#error INTSR stride != INTMR stride
+#endif
+
+		.macro	get_irqnr_and_base, irqnr, stat, base, mask
+		mov	\base, #CLPS7111_BASE
+		ldr	\stat, [\base, #INTSR1]
+		ldr	\mask, [\base, #INTMR1]
+		mov	\irqnr, #4
+		mov	\mask, \mask, lsl #16
+		and	\stat, \stat, \mask, lsr #16
+		movs	\stat, \stat, lsr #4
+		bne	1001f
+
+		add	\base, \base, #INTSR2 - INTSR1
+		ldr	\stat, [\base, #INTSR1]
+		ldr	\mask, [\base, #INTMR1]
+		mov	\irqnr, #16
+		mov	\mask, \mask, lsl #16
+		and	\stat, \stat, \mask, lsr #16
+
+1001:		tst	\stat, #255
+		addeq	\irqnr, \irqnr, #8
+		moveq	\stat, \stat, lsr #8
+		tst	\stat, #15
+		addeq	\irqnr, \irqnr, #4
+		moveq	\stat, \stat, lsr #4
+		tst	\stat, #3
+		addeq	\irqnr, \irqnr, #2
+		moveq	\stat, \stat, lsr #2
+		tst	\stat, #1
+		addeq	\irqnr, \irqnr, #1
+		moveq	\stat, \stat, lsr #1
+		tst	\stat, #1			@ bit 0 should be set
+		.endm
+
+
diff -Nru a/include/asm-arm/arch-ebsa110/debug-macro.S b/include/asm-arm/arch-ebsa110/debug-macro.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-arm/arch-ebsa110/debug-macro.S	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,34 @@
+/* linux/include/asm-arm/arch-ebsa110/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ *  Copyright (C) 1994-1999 Russell King
+ *  Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+**/
+
+		.macro	addruart,rx
+		mov	\rx, #0xf0000000
+		orr	\rx, \rx, #0x00000be0
+		.endm
+
+		.macro	senduart,rd,rx
+		strb	\rd, [\rx]
+		.endm
+
+		.macro	busyuart,rd,rx
+1002:		ldrb	\rd, [\rx, #0x14]
+		and	\rd, \rd, #0x60
+		teq	\rd, #0x60
+		bne	1002b
+		.endm
+
+		.macro	waituart,rd,rx
+1001:		ldrb	\rd, [\rx, #0x18]
+		tst	\rd, #0x10
+		beq	1001b
+		.endm
diff -Nru a/include/asm-arm/arch-ebsa110/entry-macro.S b/include/asm-arm/arch-ebsa110/entry-macro.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-arm/arch-ebsa110/entry-macro.S	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,33 @@
+/*
+ * include/asm-arm/arch-ebsa110/entry-macro.S
+ *
+ * Low-level IRQ helper macros for ebsa110 platform.
+ *
+ * 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.
+ */
+
+
+
+#define IRQ_STAT		0xff000000	/* read */
+
+	.macro	disable_fiq
+	.endm
+
+	.macro	get_irqnr_and_base, irqnr, stat, base, tmp
+	mov	\base, #IRQ_STAT
+	ldrb	\stat, [\base]			@ get interrupts
+	mov	\irqnr, #0
+	tst	\stat, #15
+	addeq	\irqnr, \irqnr, #4
+	moveq	\stat, \stat, lsr #4
+	tst	\stat, #3
+	addeq	\irqnr, \irqnr, #2
+	moveq	\stat, \stat, lsr #2
+	tst	\stat, #1
+	addeq	\irqnr, \irqnr, #1
+	moveq	\stat, \stat, lsr #1
+	tst	\stat, #1			@ bit 0 should be set
+	.endm
+
diff -Nru a/include/asm-arm/arch-ebsa285/debug-macro.S b/include/asm-arm/arch-ebsa285/debug-macro.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-arm/arch-ebsa285/debug-macro.S	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,66 @@
+/* linux/include/asm-arm/arch-ebsa285/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ *  Copyright (C) 1994-1999 Russell King
+ *  Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+#include <asm/hardware/dec21285.h>
+
+#ifndef CONFIG_DEBUG_DC21285_PORT
+	/* For NetWinder debugging */
+		.macro	addruart,rx
+		mrc	p15, 0, \rx, c1, c0
+		tst	\rx, #1			@ MMU enabled?
+		moveq	\rx, #0x7c000000	@ physical
+		movne	\rx, #0xff000000	@ virtual
+		orr	\rx, \rx, #0x000003f8
+		.endm
+
+		.macro	senduart,rd,rx
+		strb	\rd, [\rx]
+		.endm
+
+		.macro	busyuart,rd,rx
+1002:		ldrb	\rd, [\rx, #0x5]
+		and	\rd, \rd, #0x60
+		teq	\rd, #0x60
+		bne	1002b
+		.endm
+
+		.macro	waituart,rd,rx
+1001:		ldrb	\rd, [\rx, #0x6]
+		tst	\rd, #0x10
+		beq	1001b
+		.endm
+#else
+	/* For EBSA285 debugging */
+		.equ	dc21285_high, ARMCSR_BASE & 0xff000000
+		.equ	dc21285_low,  ARMCSR_BASE & 0x00ffffff
+
+		.macro	addruart,rx
+		mov	\rx, #dc21285_high
+		.if	dc21285_low
+		orr	\rx, \rx, #dc21285_low
+		.endif
+		.endm
+
+		.macro	senduart,rd,rx
+		str	\rd, [\rx, #0x160]	@ UARTDR
+		.endm
+
+		.macro	busyuart,rd,rx
+1001:		ldr	\rd, [\rx, #0x178]	@ UARTFLG
+		tst	\rd, #1 << 3
+		bne	1001b
+		.endm
+
+		.macro	waituart,rd,rx
+		.endm
+#endif
diff -Nru a/include/asm-arm/arch-ebsa285/entry-macro.S b/include/asm-arm/arch-ebsa285/entry-macro.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-arm/arch-ebsa285/entry-macro.S	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,105 @@
+/*
+ * include/asm-arm/arch-footbridge/entry-macro.S
+ *
+ * Low-level IRQ helper macros for footbridge-based platforms
+ *
+ * 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 <asm/hardware/dec21285.h>
+
+		.macro	disable_fiq
+		.endm
+
+		.equ	dc21285_high, ARMCSR_BASE & 0xff000000
+		.equ	dc21285_low, ARMCSR_BASE & 0x00ffffff
+
+		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+		mov	r4, #dc21285_high
+		.if	dc21285_low
+		orr	r4, r4, #dc21285_low
+		.endif
+		ldr	\irqstat, [r4, #0x180]		@ get interrupts
+
+		mov	\irqnr, #IRQ_SDRAMPARITY
+		tst	\irqstat, #IRQ_MASK_SDRAMPARITY
+		bne	1001f
+
+		tst	\irqstat, #IRQ_MASK_UART_RX
+		movne	\irqnr, #IRQ_CONRX
+		bne	1001f
+
+		tst	\irqstat, #IRQ_MASK_DMA1
+		movne	\irqnr, #IRQ_DMA1
+		bne	1001f
+
+		tst	\irqstat, #IRQ_MASK_DMA2
+		movne	\irqnr, #IRQ_DMA2
+		bne	1001f
+
+		tst	\irqstat, #IRQ_MASK_IN0
+		movne	\irqnr, #IRQ_IN0
+		bne	1001f
+
+		tst	\irqstat, #IRQ_MASK_IN1
+		movne	\irqnr, #IRQ_IN1
+		bne	1001f
+
+		tst	\irqstat, #IRQ_MASK_IN2
+		movne	\irqnr, #IRQ_IN2
+		bne	1001f
+
+		tst	\irqstat, #IRQ_MASK_IN3
+		movne	\irqnr, #IRQ_IN3
+		bne	1001f
+
+		tst	\irqstat, #IRQ_MASK_PCI
+		movne	\irqnr, #IRQ_PCI
+		bne	1001f
+
+		tst	\irqstat, #IRQ_MASK_DOORBELLHOST
+		movne	\irqnr, #IRQ_DOORBELLHOST
+		bne     1001f
+
+		tst	\irqstat, #IRQ_MASK_I2OINPOST
+		movne	\irqnr, #IRQ_I2OINPOST
+		bne	1001f
+
+		tst	\irqstat, #IRQ_MASK_TIMER1
+		movne	\irqnr, #IRQ_TIMER1
+		bne	1001f
+
+		tst	\irqstat, #IRQ_MASK_TIMER2
+		movne	\irqnr, #IRQ_TIMER2
+		bne	1001f
+
+		tst	\irqstat, #IRQ_MASK_TIMER3
+		movne	\irqnr, #IRQ_TIMER3
+		bne	1001f
+
+		tst	\irqstat, #IRQ_MASK_UART_TX
+		movne	\irqnr, #IRQ_CONTX
+		bne	1001f
+
+		tst	\irqstat, #IRQ_MASK_PCI_ABORT
+		movne	\irqnr, #IRQ_PCI_ABORT
+		bne	1001f
+
+		tst	\irqstat, #IRQ_MASK_PCI_SERR
+		movne	\irqnr, #IRQ_PCI_SERR
+		bne	1001f
+
+		tst	\irqstat, #IRQ_MASK_DISCARD_TIMER
+		movne	\irqnr, #IRQ_DISCARD_TIMER
+		bne	1001f
+
+		tst	\irqstat, #IRQ_MASK_PCI_DPERR
+		movne	\irqnr, #IRQ_PCI_DPERR
+		bne	1001f
+
+		tst	\irqstat, #IRQ_MASK_PCI_PERR
+		movne	\irqnr, #IRQ_PCI_PERR
+1001:
+		.endm
+
diff -Nru a/include/asm-arm/arch-epxa10db/debug-macro.S b/include/asm-arm/arch-epxa10db/debug-macro.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-arm/arch-epxa10db/debug-macro.S	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,41 @@
+/* linux/include/asm-arm/arch-epxa10db/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ *  Copyright (C) 1994-1999 Russell King
+ *  Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+#include <asm/arch/excalibur.h>
+#define UART00_TYPE
+#include <asm/arch/uart00.h>
+
+		.macro	addruart,rx
+		mrc	p15, 0, \rx, c1, c0
+		tst	\rx, #1			@ MMU enabled?
+		ldr	\rx, =EXC_UART00_BASE	@ physical base address
+		orrne	\rx, \rx, #0xff000000	@ virtual base
+		orrne	\rx, \rx, #0x00f00000
+		.endm
+
+		.macro	senduart,rd,rx
+		str	\rd, [\rx, #UART_TD(0)]
+		.endm
+
+		.macro	waituart,rd,rx
+1001:		ldr	\rd, [\rx, #UART_TSR(0)]
+		and 	\rd, \rd,  #UART_TSR_TX_LEVEL_MSK
+		cmp	\rd, #15
+		beq	1001b
+		.endm
+
+		.macro	busyuart,rd,rx
+1001:		ldr	\rd, [\rx, #UART_TSR(0)]
+		ands 	\rd, \rd,  #UART_TSR_TX_LEVEL_MSK
+		bne	1001b
+		.endm
diff -Nru a/include/asm-arm/arch-epxa10db/entry-macro.S b/include/asm-arm/arch-epxa10db/entry-macro.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-arm/arch-epxa10db/entry-macro.S	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,25 @@
+/*
+ * include/asm-arm/arch-epxa10db/entry-macro.S
+ *
+ * Low-level IRQ helper macros for epxa10db platform
+ *
+ * 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 <asm/arch/platform.h>
+#undef IRQ_MODE /* same name defined in asm/proc/ptrace.h */
+#include <asm/arch/int_ctrl00.h>
+
+		.macro	disable_fiq
+		.endm
+
+		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+
+		ldr	\irqstat, =INT_ID(IO_ADDRESS(EXC_INT_CTRL00_BASE))
+		ldr	\irqnr,[\irqstat]
+		cmp	\irqnr,#0
+		subne	\irqnr,\irqnr,#1
+
+		.endm
+
diff -Nru a/include/asm-arm/arch-h720x/debug-macro.S b/include/asm-arm/arch-h720x/debug-macro.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-arm/arch-h720x/debug-macro.S	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,40 @@
+/* linux/include/asm-arm/arch-h720x/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ *  Copyright (C) 1994-1999 Russell King
+ *  Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+		.equ    io_virt, IO_BASE
+		.equ    io_phys, IO_START
+
+		.macro  addruart,rx
+		mrc     p15, 0, \rx, c1, c0
+		tst     \rx, #1  	       @ MMU enabled?
+		moveq   \rx, #io_phys	       @ physical base address
+		movne   \rx, #io_virt	       @ virtual address
+		add     \rx, \rx, #0x00020000   @ UART1
+		.endm
+
+		.macro  senduart,rd,rx
+		str     \rd, [\rx, #0x0]        @ UARTDR
+
+		.endm
+
+		.macro  waituart,rd,rx
+1001:		ldr     \rd, [\rx, #0x18]       @ UARTFLG
+		tst     \rd, #1 << 5	       @ UARTFLGUTXFF - 1 when full
+		bne     1001b
+		.endm
+
+		.macro  busyuart,rd,rx
+1001:		ldr     \rd, [\rx, #0x18]       @ UARTFLG
+		tst     \rd, #1 << 3	       @ UARTFLGUBUSY - 1 when busy
+		bne     1001b
+		.endm
diff -Nru a/include/asm-arm/arch-h720x/entry-macro.S b/include/asm-arm/arch-h720x/entry-macro.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-arm/arch-h720x/entry-macro.S	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,60 @@
+/*
+ * include/asm-arm/arch-h720x/entry-macro.S
+ *
+ * Low-level IRQ helper macros for Hynix HMS720x based platforms
+ *
+ * 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.
+ */
+
+		.macro  disable_fiq
+		.endm
+
+		.macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
+#if defined (CONFIG_CPU_H7201) || defined (CONFIG_CPU_H7202)
+		@ we could use the id register on H7202, but this is not
+		@ properly updated when we come back from asm_do_irq
+		@ without a previous return from interrupt
+		@ (see loops below in irq_svc, irq_usr)
+		@ We see unmasked pending ints only, as the masked pending ints
+		@ are not visible here
+
+		mov     \base, #0xf0000000	       @ base register
+		orr     \base, \base, #0x24000	       @ irqbase
+		ldr     \irqstat, [\base, #0x04]        @ get interrupt status
+#if defined (CONFIG_CPU_H7201)
+		ldr	\tmp, =0x001fffff
+#else
+		mvn     \tmp, #0xc0000000
+#endif
+		and     \irqstat, \irqstat, \tmp        @ mask out unused ints
+		mov     \irqnr, #0
+
+		mov     \tmp, #0xff00
+		orr     \tmp, \tmp, #0xff
+		tst     \irqstat, \tmp
+		addeq   \irqnr, \irqnr, #16
+		moveq   \irqstat, \irqstat, lsr #16
+		tst     \irqstat, #255
+		addeq   \irqnr, \irqnr, #8
+		moveq   \irqstat, \irqstat, lsr #8
+		tst     \irqstat, #15
+		addeq   \irqnr, \irqnr, #4
+		moveq   \irqstat, \irqstat, lsr #4
+		tst     \irqstat, #3
+		addeq   \irqnr, \irqnr, #2
+		moveq   \irqstat, \irqstat, lsr #2
+		tst     \irqstat, #1
+		addeq   \irqnr, \irqnr, #1
+		moveq   \irqstat, \irqstat, lsr #1
+		tst     \irqstat, #1		       @ bit 0 should be set
+		.endm
+
+		.macro  irq_prio_table
+		.endm
+
+#else
+#error hynix processor selection missmatch
+#endif
+
diff -Nru a/include/asm-arm/arch-h720x/h7202-regs.h b/include/asm-arm/arch-h720x/h7202-regs.h
--- a/include/asm-arm/arch-h720x/h7202-regs.h	2005-03-01 23:38:57 -08:00
+++ b/include/asm-arm/arch-h720x/h7202-regs.h	2005-03-01 23:38:57 -08:00
@@ -17,8 +17,12 @@
  * which is included by this file.
  */
 
-#define SERIAL2_VIRT 		(IO_VIRT + 0x2d000)
-#define SERIAL3_VIRT 		(IO_VIRT + 0x2e000)
+#define SERIAL2_OFS		0x2d000
+#define SERIAL2_BASE		(IO_PHYS + SERIAL2_OFS)
+#define SERIAL2_VIRT 		(IO_VIRT + SERIAL2_OFS)
+#define SERIAL3_OFS		0x2e000
+#define SERIAL3_BASE		(IO_PHYS + SERIAL3_OFS)
+#define SERIAL3_VIRT 		(IO_VIRT + SERIAL3_OFS)
 
 /* Matrix Keyboard Controller */
 #define KBD_VIRT		(IO_VIRT + 0x22000)
diff -Nru a/include/asm-arm/arch-h720x/hardware.h b/include/asm-arm/arch-h720x/hardware.h
--- a/include/asm-arm/arch-h720x/hardware.h	2005-03-01 23:39:08 -08:00
+++ b/include/asm-arm/arch-h720x/hardware.h	2005-03-01 23:39:08 -08:00
@@ -52,7 +52,15 @@
 #define GPIO_C_VIRT		(GPIO_VIRT(2))
 #define GPIO_D_VIRT		(GPIO_VIRT(3))
 #define GPIO_E_VIRT		(GPIO_VIRT(4))
-#define GPIO_AMULSEL		(GPIO_VIRT + 0xA4)
+#define GPIO_AMULSEL		(GPIO_VIRT(0) + 0xA4)
+
+#define AMULSEL_USIN2	(1<<5)
+#define AMULSEL_USOUT2	(1<<6)
+#define AMULSEL_USIN3	(1<<13)
+#define AMULSEL_USOUT3	(1<<14)
+#define AMULSEL_IRDIN	(1<<15)
+#define AMULSEL_IRDOUT	(1<<7)
+
 /* Register offsets general purpose I/O */
 #define GPIO_DATA		0x00
 #define GPIO_DIR		0x04
@@ -162,14 +170,16 @@
 #define LCD_PALETTE_BASE 	(IO_VIRT + 0x10400)
 
 /* Serial ports */
-#define SERIAL0_VIRT 		(IO_VIRT + 0x20000)
-#define SERIAL1_VIRT 		(IO_VIRT + 0x21000)
-
-#define SERIAL0_BASE		SERIAL0_VIRT
-#define SERIAL1_BASE		SERIAL1_VIRT
-#define SERIAL2_BASE		SERIAL2_VIRT
-#define SERIAL3_BASE		SERIAL3_VIRT
+#define SERIAL0_OFS		0x20000
+#define SERIAL0_VIRT 		(IO_VIRT + SERIAL0_OFS)
+#define SERIAL0_BASE		(IO_PHYS + SERIAL0_OFS)
+
+#define SERIAL1_OFS		0x21000
+#define SERIAL1_VIRT 		(IO_VIRT + SERIAL1_OFS)
+#define SERIAL1_BASE		(IO_PHYS + SERIAL1_OFS)
 
+#define SERIAL_ENABLE		0x30
+#define SERIAL_ENABLE_EN	(1<<0)
 
 /* General defines to pacify gcc */
 #define PCIO_BASE 		(0)	/* for inb, outb and friends */
diff -Nru a/include/asm-arm/arch-imx/debug-macro.S b/include/asm-arm/arch-imx/debug-macro.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-arm/arch-imx/debug-macro.S	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,34 @@
+/* linux/include/asm-arm/arch-imx/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ *  Copyright (C) 1994-1999 Russell King
+ *  Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+		.macro	addruart,rx
+		mrc	p15, 0, \rx, c1, c0
+		tst	\rx, #1			@ MMU enabled?
+		moveq	\rx, #0x00000000	@ physical
+		movne	\rx, #0xe0000000	@ virtual
+		orr	\rx, \rx, #0x00200000
+		orr	\rx, \rx, #0x00006000	@ UART1 offset
+		.endm
+
+		.macro	senduart,rd,rx
+		str	\rd, [\rx, #0x40]	@ TXDATA
+		.endm
+
+		.macro	waituart,rd,rx
+		.endm
+
+		.macro	busyuart,rd,rx
+1002:		ldr	\rd, [\rx, #0x98]	@ SR2
+		tst	\rd, #1 << 3		@ TXDC
+		beq	1002b			@ wait until transmit done
+		.endm
diff -Nru a/include/asm-arm/arch-imx/entry-macro.S b/include/asm-arm/arch-imx/entry-macro.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-arm/arch-imx/entry-macro.S	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,29 @@
+/*
+ * include/asm-arm/arch-imx/entry-macro.S
+ *
+ * Low-level IRQ helper macros for iMX-based platforms
+ *
+ * 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.
+ */
+		.macro	disable_fiq
+		.endm
+#define AITC_NIVECSR   0x40
+		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+		ldr	\irqstat, =IO_ADDRESS(IMX_AITC_BASE)
+		@ Load offset & priority of the highest priority
+		@ interrupt pending.
+		ldr	\irqnr, [\irqstat, #AITC_NIVECSR]
+		@ Shift off the priority leaving the offset or
+		@ "interrupt number"
+		mov	\irqnr, \irqnr, lsr #16
+ 		ldr	\irqstat, =1	@ dummy compare
+		ldr	\base, =0xFFFF		// invalid interrupt
+		cmp	\irqnr, \base
+		bne	1001f
+		ldr	\irqstat, =0
+1001:
+		tst	\irqstat, #1	@ to make the condition code = TRUE
+		.endm
+
diff -Nru a/include/asm-arm/arch-integrator/debug-macro.S b/include/asm-arm/arch-integrator/debug-macro.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-arm/arch-integrator/debug-macro.S	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,38 @@
+/* linux/include/asm-arm/arch-integrator/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ *  Copyright (C) 1994-1999 Russell King
+ *  Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+#include <asm/hardware/amba_serial.h>
+
+		.macro	addruart,rx
+		mrc	p15, 0, \rx, c1, c0
+		tst	\rx, #1			@ MMU enabled?
+		moveq	\rx, #0x16000000	@ physical base address
+		movne	\rx, #0xf0000000	@ virtual base
+		addne	\rx, \rx, #0x16000000 >> 4
+		.endm
+
+		.macro	senduart,rd,rx
+		strb	\rd, [\rx, #UART01x_DR]
+		.endm
+
+		.macro	waituart,rd,rx
+1001:		ldr	\rd, [\rx, #0x18]	@ UARTFLG
+		tst	\rd, #1 << 5		@ UARTFLGUTXFF - 1 when full
+		bne	1001b
+		.endm
+
+		.macro	busyuart,rd,rx
+1001:		ldr	\rd, [\rx, #0x18]	@ UARTFLG
+		tst	\rd, #1 << 3		@ UARTFLGUBUSY - 1 when busy
+		bne	1001b
+		.endm
diff -Nru a/include/asm-arm/arch-integrator/entry-macro.S b/include/asm-arm/arch-integrator/entry-macro.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-arm/arch-integrator/entry-macro.S	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,36 @@
+/*
+ * include/asm-arm/arch-integrator/entry-macro.S
+ *
+ * Low-level IRQ helper macros for Integrator platforms
+ *
+ * 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.
+ */
+
+ 		.macro	disable_fiq
+		.endm
+
+		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+/* FIXME: should not be using soo many LDRs here */
+		ldr	\base, =IO_ADDRESS(INTEGRATOR_IC_BASE)
+		mov	\irqnr, #IRQ_PIC_START
+		ldr	\irqstat, [\base, #IRQ_STATUS]		@ get masked status
+		ldr	\base, =IO_ADDRESS(INTEGRATOR_HDR_BASE)
+		teq	\irqstat, #0
+		ldreq	\irqstat, [\base, #(INTEGRATOR_HDR_IC_OFFSET+IRQ_STATUS)]
+		moveq	\irqnr, #IRQ_CIC_START
+
+1001:		tst	\irqstat, #15
+		bne	1002f
+		add	\irqnr, \irqnr, #4
+		movs	\irqstat, \irqstat, lsr #4
+		bne	1001b
+1002:		tst	\irqstat, #1
+		bne	1003f
+		add	\irqnr, \irqnr, #1
+		movs	\irqstat, \irqstat, lsr #1
+		bne	1002b
+1003:		/* EQ will be set if no irqs pending */
+		.endm
+
diff -Nru a/include/asm-arm/arch-iop3xx/debug-macro.S b/include/asm-arm/arch-iop3xx/debug-macro.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-arm/arch-iop3xx/debug-macro.S	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,48 @@
+/* linux/include/asm-arm/arch-iop3xx/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ *  Copyright (C) 1994-1999 Russell King
+ *  Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+		.macro	addruart,rx
+		mov	\rx, #0xfe000000	@ physical
+#if defined(CONFIG_ARCH_IQ80321) || defined(CONFIG_ARCH_IQ31244)
+		orr	\rx, \rx, #0x00800000	@ location of the UART
+#elif defined(CONFIG_ARCH_IOP331)
+		mrc	p15, 0, \rx, c1, c0
+		tst	\rx, #1			@ MMU enabled?
+		moveq	\rx, #0x000fe000	@ Physical Base
+		movne	\rx, #0
+		orr	\rx, \rx, #0xfe000000
+		orr	\rx, \rx, #0x00f00000	@ Virtual Base
+		orr	\rx, \rx, #0x00001700   @ location of the UART
+#else
+#error Unknown IOP3XX implementation
+#endif
+		.endm
+
+		.macro	senduart,rd,rx
+		strb	\rd, [\rx]
+		.endm
+
+		.macro	busyuart,rd,rx
+1002:		ldrb	\rd, [\rx, #0x5]
+		and	\rd, \rd, #0x60
+		teq	\rd, #0x60
+		bne	1002b
+		.endm
+
+		.macro	waituart,rd,rx
+#if !defined(CONFIG_ARCH_IQ80321) || !defined(CONFIG_ARCH_IQ31244) || !defined(CONFIG_ARCH_IQ80331)
+1001:		ldrb	\rd, [\rx, #0x6]
+		tst	\rd, #0x10
+		beq	1001b
+#endif
+		.endm
diff -Nru a/include/asm-arm/arch-iop3xx/entry-macro.S b/include/asm-arm/arch-iop3xx/entry-macro.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-arm/arch-iop3xx/entry-macro.S	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,56 @@
+/*
+ * include/asm-arm/arch-iop3xx/entry-macro.S
+ *
+ * Low-level IRQ helper macros for IOP3xx-based platforms
+ *
+ * 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.
+ */
+
+#if defined(CONFIG_ARCH_IOP321)
+		.macro  disable_fiq
+		.endm
+
+		/*
+		 * Note: only deal with normal interrupts, not FIQ
+		 */
+		.macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
+		mov     \irqnr, #0
+		mrc     p6, 0, \irqstat, c8, c0, 0      @ Read IINTSRC
+		cmp     \irqstat, #0
+		beq     1001f
+		clz     \irqnr, \irqstat
+		mov     \base, #31
+		subs    \irqnr,\base,\irqnr
+		add     \irqnr,\irqnr,#IRQ_IOP321_DMA0_EOT
+1001:
+		.endm
+
+#elif defined(CONFIG_ARCH_IOP331)
+		.macro  disable_fiq
+		.endm
+
+		/*
+		 * Note: only deal with normal interrupts, not FIQ
+		 */
+		.macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
+		mov     \irqnr, #0
+		mrc     p6, 0, \irqstat, c4, c0, 0      @ Read IINTSRC0
+		cmp     \irqstat, #0
+		bne     1002f
+		mrc     p6, 0, \irqstat, c5, c0, 0      @ Read IINTSRC1
+		cmp	\irqstat, #0
+		beq	1001f
+		clz	\irqnr, \irqstat
+		rsbs    \irqnr,\irqnr,#31   @ recommend by RMK
+		add	\irqnr,\irqnr,#IRQ_IOP331_XINT8
+		b	1001f
+1002:	clz     \irqnr, \irqstat
+		rsbs    \irqnr,\irqnr,#31   @ recommend by RMK
+		add     \irqnr,\irqnr,#IRQ_IOP331_DMA0_EOT
+1001:
+		.endm
+
+#endif
+
diff -Nru a/include/asm-arm/arch-iop3xx/hardware.h b/include/asm-arm/arch-iop3xx/hardware.h
--- a/include/asm-arm/arch-iop3xx/hardware.h	2005-03-01 23:38:53 -08:00
+++ b/include/asm-arm/arch-iop3xx/hardware.h	2005-03-01 23:38:53 -08:00
@@ -52,5 +52,6 @@
 #include "iq80321.h"
 #include "iq31244.h"
 #include "iq80331.h"
+#include "iq80332.h"
 
 #endif  /* _ASM_ARCH_HARDWARE_H */
diff -Nru a/include/asm-arm/arch-iop3xx/iop321.h b/include/asm-arm/arch-iop3xx/iop321.h
--- a/include/asm-arm/arch-iop3xx/iop321.h	2005-03-01 23:39:18 -08:00
+++ b/include/asm-arm/arch-iop3xx/iop321.h	2005-03-01 23:39:18 -08:00
@@ -5,6 +5,7 @@
  *
  * Author: Rory Bolt <rorybolt@pacbell.net>
  * Copyright (C) 2002 Rory Bolt
+ * Copyright (C) 2004 Intel Corp.
  *
  * 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
@@ -30,21 +31,29 @@
 /*
  * IOP321 I/O and Mem space regions for PCI autoconfiguration
  */
-#define IOP321_PCI_LOWER_IO             0x90000000
-#define IOP321_PCI_UPPER_IO             0x9000ffff
-#define IOP321_PCI_LOWER_MEM            0x80000000
-#define IOP321_PCI_UPPER_MEM            0x83ffffff
-
-#define IOP321_PCI_WINDOW_SIZE          64 * 0x100000
+#define IOP321_PCI_IO_WINDOW_SIZE   0x00010000
+#define IOP321_PCI_LOWER_IO_PA      0x90000000
+#define IOP321_PCI_LOWER_IO_VA      0xfe000000
+#define IOP321_PCI_LOWER_IO_BA      (*IOP321_OIOWTVR)
+#define IOP321_PCI_UPPER_IO_PA      (IOP321_PCI_LOWER_IO_PA + IOP321_PCI_IO_WINDOW_SIZE - 1)
+#define IOP321_PCI_UPPER_IO_VA      (IOP321_PCI_LOWER_IO_VA + IOP321_PCI_IO_WINDOW_SIZE - 1)
+#define IOP321_PCI_UPPER_IO_BA      (IOP321_PCI_LOWER_IO_BA + IOP321_PCI_IO_WINDOW_SIZE - 1)
+#define IOP321_PCI_IO_OFFSET        (IOP321_PCI_LOWER_IO_VA - IOP321_PCI_LOWER_IO_BA)
+
+//#define IOP321_PCI_MEM_WINDOW_SIZE  (~*IOP321_IALR1 + 1)
+#define IOP321_PCI_MEM_WINDOW_SIZE  0x04000000 /* 64M outbound window */
+#define IOP321_PCI_LOWER_MEM_PA     0x80000000
+#define IOP321_PCI_LOWER_MEM_BA     (*IOP321_OMWTVR0)
+#define IOP321_PCI_UPPER_MEM_PA     (IOP321_PCI_LOWER_MEM_PA + IOP321_PCI_MEM_WINDOW_SIZE - 1)
+#define IOP321_PCI_UPPER_MEM_BA     (IOP321_PCI_LOWER_MEM_BA + IOP321_PCI_MEM_WINDOW_SIZE - 1)
+#define IOP321_PCI_MEM_OFFSET       (IOP321_PCI_LOWER_MEM_PA - IOP321_PCI_LOWER_MEM_BA)
 
 
 /*
  * IOP321 chipset registers
  */
 #define IOP321_VIRT_MEM_BASE 0xfeffe000  /* chip virtual mem address*/
-//#define IOP321_VIRT_MEM_BASE 0xfff00000  /* chip virtual mem address*/
-
-#define IOP321_PHY_MEM_BASE  0xffffe000  /* chip physical memory address */
+#define IOP321_PHYS_MEM_BASE 0xffffe000  /* chip physical memory address */
 #define IOP321_REG_ADDR(reg) (IOP321_VIRT_MEM_BASE | (reg))
 
 /* Reserved 0x00000000 through 0x000000FF */
diff -Nru a/include/asm-arm/arch-iop3xx/iop331-irqs.h b/include/asm-arm/arch-iop3xx/iop331-irqs.h
--- a/include/asm-arm/arch-iop3xx/iop331-irqs.h	2005-03-01 23:38:54 -08:00
+++ b/include/asm-arm/arch-iop3xx/iop331-irqs.h	2005-03-01 23:38:54 -08:00
@@ -91,6 +91,7 @@
 #define NR_IRQS			NR_IOP331_IRQS
 
 
+#if defined(CONFIG_ARCH_IQ80331)
 /*
  * Interrupts available on the IQ80331 board
  */
@@ -109,5 +110,27 @@
 #define	IRQ_IQ80331_INTB	IRQ_IOP331_XINT1
 #define	IRQ_IQ80331_INTC	IRQ_IOP331_XINT2
 #define	IRQ_IQ80331_INTD	IRQ_IOP331_XINT3
+
+#elif defined(CONFIG_MACH_IQ80332)
+/*
+ * Interrupts available on the IQ80332 board
+ */
+
+/*
+ * On board devices
+ */
+#define	IRQ_IQ80332_I82544	IRQ_IOP331_XINT0
+#define IRQ_IQ80332_UART0	IRQ_IOP331_UART0
+#define IRQ_IQ80332_UART1	IRQ_IOP331_UART1
+
+/*
+ * PCI interrupts
+ */
+#define	IRQ_IQ80332_INTA	IRQ_IOP331_XINT0
+#define	IRQ_IQ80332_INTB	IRQ_IOP331_XINT1
+#define	IRQ_IQ80332_INTC	IRQ_IOP331_XINT2
+#define	IRQ_IQ80332_INTD	IRQ_IOP331_XINT3
+
+#endif
 
 #endif // _IOP331_IRQ_H_
diff -Nru a/include/asm-arm/arch-iop3xx/iop331.h b/include/asm-arm/arch-iop3xx/iop331.h
--- a/include/asm-arm/arch-iop3xx/iop331.h	2005-03-01 23:38:54 -08:00
+++ b/include/asm-arm/arch-iop3xx/iop331.h	2005-03-01 23:38:54 -08:00
@@ -4,7 +4,7 @@
  * Intel IOP331 Chip definitions
  *
  * Author: Dave Jiang (dave.jiang@intel.com)
- * Copyright (C) 2003 Intel Corp.
+ * Copyright (C) 2003, 2004 Intel Corp.
  *
  * 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
@@ -21,7 +21,8 @@
  */
 #ifndef __ASSEMBLY__
 #ifdef	CONFIG_ARCH_IOP331
-#define	iop_is_331()	((processor_id & 0xffffffb0) == 0x69054090)
+/*#define	iop_is_331()	((processor_id & 0xffffffb0) == 0x69054090) */
+#define	iop_is_331()	((processor_id & 0xffffff30) == 0x69054010)
 #else
 #define	iop_is_331()	0
 #endif
@@ -30,20 +31,28 @@
 /*
  * IOP331 I/O and Mem space regions for PCI autoconfiguration
  */
-#define IOP331_PCI_LOWER_IO             0x90000000
-#define IOP331_PCI_UPPER_IO             0x900fffff
-#define IOP331_PCI_LOWER_MEM            0x80000000
-#define IOP331_PCI_UPPER_MEM            0x87ffffff
-
-#define IOP331_PCI_WINDOW_SIZE          128 * 0x100000
-
+#define IOP331_PCI_IO_WINDOW_SIZE   0x00010000
+#define IOP331_PCI_LOWER_IO_PA      0x90000000
+#define IOP331_PCI_LOWER_IO_VA      0xfe000000
+#define IOP331_PCI_LOWER_IO_BA      (*IOP331_OIOWTVR)
+#define IOP331_PCI_UPPER_IO_PA      (IOP331_PCI_LOWER_IO_PA + IOP331_PCI_IO_WINDOW_SIZE - 1)
+#define IOP331_PCI_UPPER_IO_VA      (IOP331_PCI_LOWER_IO_VA + IOP331_PCI_IO_WINDOW_SIZE - 1)
+#define IOP331_PCI_UPPER_IO_BA      (IOP331_PCI_LOWER_IO_BA + IOP331_PCI_IO_WINDOW_SIZE - 1)
+#define IOP331_PCI_IO_OFFSET        (IOP331_PCI_LOWER_IO_VA - IOP331_PCI_LOWER_IO_BA)
+
+/* this can be 128M if OMWTVR1 is set */
+#define IOP331_PCI_MEM_WINDOW_SIZE	0x04000000 /* 64M outbound window */
+//#define IOP331_PCI_MEM_WINDOW_SIZE  (~*IOP331_IALR1 + 1)
+#define IOP331_PCI_LOWER_MEM_PA     0x80000000
+#define IOP331_PCI_LOWER_MEM_BA     (*IOP331_OMWTVR0)
+#define IOP331_PCI_UPPER_MEM_PA     (IOP331_PCI_LOWER_MEM_PA + IOP331_PCI_MEM_WINDOW_SIZE - 1)
+#define IOP331_PCI_UPPER_MEM_BA     (IOP331_PCI_LOWER_MEM_BA + IOP331_PCI_MEM_WINDOW_SIZE - 1)
+#define IOP331_PCI_MEM_OFFSET       (IOP331_PCI_LOWER_MEM_PA - IOP331_PCI_LOWER_MEM_BA)
 
 /*
  * IOP331 chipset registers
  */
-#define IOP331_VIRT_MEM_BASE 0xfeffe000  /* chip virtual mem address*/
-// #define IOP331_VIRT_MEM_BASE 0xfff00000  /* chip virtual mem address*/
-
+#define IOP331_VIRT_MEM_BASE  0xfeffe000  /* chip virtual mem address*/
 #define IOP331_PHYS_MEM_BASE  0xffffe000  /* chip physical memory address */
 #define IOP331_REG_ADDR(reg) (IOP331_VIRT_MEM_BASE | (reg))
 
@@ -248,8 +257,14 @@
 #define IOP331_TU_TISR    (volatile u32 *)IOP331_REG_ADDR(0x000007E8)
 #define IOP331_TU_WDTCR   (volatile u32 *)IOP331_REG_ADDR(0x000007EC)
 
-#define	IOP331_TICK_RATE	266000000	/* 266 MHz clock */
+#if defined(CONFIG_ARCH_IOP331)
+#define	IOP331_TICK_RATE	266000000	/* 266 MHz IB clock */
+#endif
 
+#if defined(CONFIG_IOP331_STEPD) || defined(CONFIG_ARCH_IQ80333)
+#undef IOP331_TICK_RATE
+#define IOP331_TICK_RATE	333000000	/* 333 Mhz IB clock */
+#endif
 
 /* Application accelerator unit 0x00000800 - 0x000008FF */
 #define IOP331_AAU_ACR     (volatile u32 *)IOP331_REG_ADDR(0x00000800)
@@ -324,6 +339,11 @@
 
 /* 0x00001740 through 0x0000176C UART 1 */
 
+#define IOP331_UART0_PHYS  (IOP331_PHYS_MEM_BASE | 0x00001700)	/* UART #1 physical */
+#define IOP331_UART1_PHYS  (IOP331_PHYS_MEM_BASE | 0x00001740)	/* UART #2 physical */
+#define IOP331_UART0_VIRT  (IOP331_VIRT_MEM_BASE | 0x00001700) /* UART #1 virtual addr */
+#define IOP331_UART1_VIRT  (IOP331_VIRT_MEM_BASE | 0x00001740) /* UART #2 virtual addr */
+
 /* Reserved 0x00001770 through 0x0000177F */
 
 /* General Purpose I/O Registers */
@@ -332,6 +352,7 @@
 #define IOP331_GPOD       (volatile u32 *)IOP331_REG_ADDR(0x00001788)
 
 /* Reserved 0x0000178c through 0x000019ff */
+
 
 #ifndef __ASSEMBLY__
 extern void iop331_map_io(void);
diff -Nru a/include/asm-arm/arch-iop3xx/iq31244.h b/include/asm-arm/arch-iop3xx/iq31244.h
--- a/include/asm-arm/arch-iop3xx/iq31244.h	2005-03-01 23:39:09 -08:00
+++ b/include/asm-arm/arch-iop3xx/iq31244.h	2005-03-01 23:39:09 -08:00
@@ -7,8 +7,6 @@
 #ifndef _IQ31244_H_
 #define _IQ31244_H_
 
-#define IQ31244_RAMBASE		0xa0000000
-
 #define	IQ31244_FLASHBASE	0xf0000000	/* Flash */
 #define	IQ31244_FLASHSIZE	0x00800000
 #define	IQ31244_FLASHWIDTH	2
@@ -18,16 +16,6 @@
 #define IQ31244_7SEG_0		0xfe850000	/* 7-Segment LSB (WO) */
 #define IQ31244_ROTARY_SW	0xfe8d0000	/* Rotary Switch */
 #define IQ31244_BATT_STAT	0xfe8f0000	/* Battery Status */
-
-/*
- * IQ31244 PCI I/O and Mem space regions
- */
-#define IQ31244_PCI_IO_BASE	0x90000000
-#define IQ31244_PCI_IO_SIZE	0x00010000
-#define IQ31244_PCI_MEM_BASE	0x80000000
-//#define IQ31244_PCI_MEM_SIZE	0x04000000
-#define IQ31244_PCI_MEM_SIZE	0x08000000
-#define	IQ31244_PCI_IO_OFFSET	0x6e000000
 
 #ifndef __ASSEMBLY__
 extern void iq31244_map_io(void);
diff -Nru a/include/asm-arm/arch-iop3xx/iq80321.h b/include/asm-arm/arch-iop3xx/iq80321.h
--- a/include/asm-arm/arch-iop3xx/iq80321.h	2005-03-01 23:38:56 -08:00
+++ b/include/asm-arm/arch-iop3xx/iq80321.h	2005-03-01 23:38:56 -08:00
@@ -7,8 +7,6 @@
 #ifndef _IQ80321_H_
 #define _IQ80321_H_
 
-#define IQ80321_RAMBASE		0xa0000000
-
 #define	IQ80321_FLASHBASE	0xf0000000	/* Flash */
 #define	IQ80321_FLASHSIZE	0x00800000
 #define	IQ80321_FLASHWIDTH	1
@@ -18,15 +16,6 @@
 #define IQ80321_7SEG_0		0xfe850000	/* 7-Segment LSB (WO) */
 #define IQ80321_ROTARY_SW	0xfe8d0000	/* Rotary Switch */
 #define IQ80321_BATT_STAT	0xfe8f0000	/* Battery Status */
-
-/*
- * IQ80321 PCI I/O and Mem space regions
- */
-#define IQ80321_PCI_IO_BASE	0x90000000
-#define IQ80321_PCI_IO_SIZE	0x00010000
-#define IQ80321_PCI_MEM_BASE	0x80000000
-#define IQ80321_PCI_MEM_SIZE	0x04000000
-#define	IQ80321_PCI_IO_OFFSET	0x6e000000
 
 #ifndef __ASSEMBLY__
 extern void iq80321_map_io(void);
diff -Nru a/include/asm-arm/arch-iop3xx/iq80331.h b/include/asm-arm/arch-iop3xx/iq80331.h
--- a/include/asm-arm/arch-iop3xx/iq80331.h	2005-03-01 23:38:57 -08:00
+++ b/include/asm-arm/arch-iop3xx/iq80331.h	2005-03-01 23:38:57 -08:00
@@ -7,29 +7,14 @@
 #ifndef _IQ80331_H_
 #define _IQ80331_H_
 
-#define IQ80331_RAMBASE		0x00000000
-
 #define	IQ80331_FLASHBASE	0xc0000000	/* Flash */
 #define	IQ80331_FLASHSIZE	0x00800000
 #define	IQ80331_FLASHWIDTH	1
 
-#define IQ80331_UART0_PHYS  (IOP331_PHYS_MEM_BASE | 0x00001700)	/* UART #1 physical */
-#define IQ80331_UART1_PHYS  (IOP331_PHYS_MEM_BASE | 0x00001740)	/* UART #2 physical */
-#define IQ80331_UART0_VIRT  (IOP331_VIRT_MEM_BASE | 0x00001700) /* UART #1 virtual addr */
-#define IQ80331_UART1_VIRT  (IOP331_VIRT_MEM_BASE | 0x00001740) /* UART #2 virtual addr */
 #define IQ80331_7SEG_1		0xce840000	/* 7-Segment MSB */
 #define IQ80331_7SEG_0		0xce850000	/* 7-Segment LSB (WO) */
 #define IQ80331_ROTARY_SW	0xce8d0000	/* Rotary Switch */
 #define IQ80331_BATT_STAT	0xce8f0000	/* Battery Status */
-
-/*
- * IQ80331 PCI I/O and Mem space regions
- */
-#define IQ80331_PCI_IO_BASE	0x90000000
-#define IQ80331_PCI_IO_SIZE	0x00010000
-#define IQ80331_PCI_MEM_BASE	0x80000000
-#define IQ80331_PCI_MEM_SIZE	0x08000000
-#define	IQ80331_PCI_IO_OFFSET	0x6e000000
 
 #ifndef __ASSEMBLY__
 extern void iq80331_map_io(void);
diff -Nru a/include/asm-arm/arch-iop3xx/iq80332.h b/include/asm-arm/arch-iop3xx/iq80332.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-arm/arch-iop3xx/iq80332.h	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,23 @@
+/*
+ * linux/include/asm/arch-iop3xx/iq80332.h
+ *
+ * Intel IQ80332 evaluation board registers
+ */
+
+#ifndef _IQ80332_H_
+#define _IQ80332_H_
+
+#define	IQ80332_FLASHBASE	0xc0000000	/* Flash */
+#define	IQ80332_FLASHSIZE	0x00800000
+#define	IQ80332_FLASHWIDTH	1
+
+#define IQ80332_7SEG_1		0xce840000	/* 7-Segment MSB */
+#define IQ80332_7SEG_0		0xce850000	/* 7-Segment LSB (WO) */
+#define IQ80332_ROTARY_SW	0xce8d0000	/* Rotary Switch */
+#define IQ80332_BATT_STAT	0xce8f0000	/* Battery Status */
+
+#ifndef __ASSEMBLY__
+extern void iq80332_map_io(void);
+#endif
+
+#endif	// _IQ80332_H_
diff -Nru a/include/asm-arm/arch-iop3xx/timex.h b/include/asm-arm/arch-iop3xx/timex.h
--- a/include/asm-arm/arch-iop3xx/timex.h	2005-03-01 23:38:58 -08:00
+++ b/include/asm-arm/arch-iop3xx/timex.h	2005-03-01 23:38:58 -08:00
@@ -10,7 +10,7 @@
 
 #define CLOCK_TICK_RATE IOP321_TICK_RATE
 
-#elif defined(CONFIG_ARCH_IQ80331)
+#elif defined(CONFIG_ARCH_IQ80331) || defined(CONFIG_MACH_IQ80332)
 
 #define CLOCK_TICK_RATE IOP331_TICK_RATE
 
diff -Nru a/include/asm-arm/arch-iop3xx/uncompress.h b/include/asm-arm/arch-iop3xx/uncompress.h
--- a/include/asm-arm/arch-iop3xx/uncompress.h	2005-03-01 23:38:57 -08:00
+++ b/include/asm-arm/arch-iop3xx/uncompress.h	2005-03-01 23:38:57 -08:00
@@ -9,8 +9,10 @@
 
 #ifdef CONFIG_ARCH_IOP321
 #define UTYPE unsigned char *
-#else
+#elif defined(CONFIG_ARCH_IOP331)
 #define UTYPE u32 *
+#else
+#error "Missing IOP3xx arch type def"
 #endif
 
 static volatile UTYPE uart_base;
@@ -42,8 +44,8 @@
 			uart_base = (volatile UTYPE)IQ80321_UART;
 		else if(machine_is_iq31244())
 			uart_base = (volatile UTYPE)IQ31244_UART;
-		else if(machine_is_iq80331())
-			uart_base = (volatile UTYPE)IQ80331_UART0_PHYS;
+		else if(machine_is_iq80331() || machine_is_iq80332())
+			uart_base = (volatile UTYPE)IOP331_UART0_PHYS;
 		else
 			uart_base = (volatile UTYPE)0xfe800000;
 }
diff -Nru a/include/asm-arm/arch-iop3xx/vmalloc.h b/include/asm-arm/arch-iop3xx/vmalloc.h
--- a/include/asm-arm/arch-iop3xx/vmalloc.h	2005-03-01 23:39:07 -08:00
+++ b/include/asm-arm/arch-iop3xx/vmalloc.h	2005-03-01 23:39:07 -08:00
@@ -13,4 +13,7 @@
 #define VMALLOC_OFFSET	  (8*1024*1024)
 #define VMALLOC_START	  (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
 #define VMALLOC_VMADDR(x) ((unsigned long)(x))
-#define VMALLOC_END       (0xe8000000)
+//#define VMALLOC_END       (0xe8000000)
+/* increase usable physical RAM to ~992M per RMK */
+#define VMALLOC_END       (0xfe000000)
+
diff -Nru a/include/asm-arm/arch-ixp2000/debug-macro.S b/include/asm-arm/arch-ixp2000/debug-macro.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-arm/arch-ixp2000/debug-macro.S	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,40 @@
+/* linux/include/asm-arm/arch-ixp2000/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ *  Copyright (C) 1994-1999 Russell King
+ *  Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+		.macro  addruart,rx
+		mrc	p15, 0, \rx, c1, c0
+		tst	\rx, #1			@ MMU enabled?
+		moveq	\rx, #0xc0000000	@ Physical base
+		movne	\rx, #0xfe000000	@ virtual base
+		orrne	\rx, \rx, #0x00f00000
+		orr	\rx, \rx, #0x00030000
+#ifdef	__ARMEB__
+		orr	\rx, \rx, #0x00000003
+#endif
+		.endm
+
+		.macro	senduart,rd,rx
+		strb	\rd, [\rx]
+		.endm
+
+		.macro	busyuart,rd,rx
+1002:		ldrb	\rd, [\rx, #0x14]
+		tst	\rd, #0x20
+		beq	1002b
+		.endm
+
+		.macro	waituart,rd,rx
+		nop
+		nop
+		nop
+		.endm
diff -Nru a/include/asm-arm/arch-ixp2000/entry-macro.S b/include/asm-arm/arch-ixp2000/entry-macro.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-arm/arch-ixp2000/entry-macro.S	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,54 @@
+/*
+ * include/asm-arm/arch-ixp2000/entry-macro.S
+ *
+ * Low-level IRQ helper macros for IXP2000-based platforms
+ *
+ * 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.
+ */
+
+		.macro  disable_fiq
+		.endm
+
+		.macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
+
+		mov	\irqnr, #0x0              @clear out irqnr as default
+                mov	\base, #0xfe000000
+		orr	\base, \base, #0x00ff0000
+		orr	\base, \base, #0x0000a000
+		orr	\base, \base, #0x08
+		ldr	\irqstat, [\base]         @ get interrupts
+
+		cmp	\irqstat, #0
+		beq	1001f
+
+		clz     \irqnr, \irqstat
+		mov     \base, #31
+		subs    \irqnr, \base, \irqnr
+
+		/*
+		 * We handle PCIA and PCIB here so we don't have an
+		 * extra layer of code just to check these two bits.
+		 */
+		cmp	\irqnr, #IRQ_IXP2000_PCI
+		bne	1001f
+
+		mov	\base, #0xfe000000
+		orr	\base, \base, #0x00fd0000
+		orr	\base, \base, #0x0000e100
+		orr	\base, \base, #0x00000058
+		ldr	\irqstat, [\base]
+
+		mov	\tmp, #(1<<26)
+		tst	\irqstat, \tmp
+		movne	\irqnr, #IRQ_IXP2000_PCIA
+		bne	1001f
+
+		mov	\tmp, #(1<<27)
+		tst	\irqstat, \tmp
+		movne	\irqnr, #IRQ_IXP2000_PCIB
+
+1001:
+		.endm
+
diff -Nru a/include/asm-arm/arch-ixp2000/io.h b/include/asm-arm/arch-ixp2000/io.h
--- a/include/asm-arm/arch-ixp2000/io.h	2005-03-01 23:38:51 -08:00
+++ b/include/asm-arm/arch-ixp2000/io.h	2005-03-01 23:38:51 -08:00
@@ -21,14 +21,14 @@
 /*
  * Pick up VMALLOC_END
  */
-#define ___io(p)		((unsigned long)((p)+IXP2000_PCI_IO_VIRT_BASE))
+#define ___io(p)		((void __iomem *)((p)+IXP2000_PCI_IO_VIRT_BASE))
 
 /*
  * IXP2000 does not do proper byte-lane conversion for PCI addresses,
  * so we need to override standard functions.
  */
-#define alignb(addr)		((addr & ~3) + (3 - (addr & 3)))
-#define alignw(addr)		((addr & ~2) + (2 - (addr & 2)))
+#define alignb(addr)		(((unsigned long)addr & ~3) + (3 - ((unsigned long)addr & 3)))
+#define alignw(addr)		(((unsigned long)addr & ~2) + (2 - ((unsigned long)addr & 2)))
 
 #define outb(v,p)		__raw_writeb(v,alignb(___io(p)))
 #define outw(v,p)		__raw_writew((v),alignw(___io(p)))
diff -Nru 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	2005-03-01 23:38:44 -08:00
+++ b/include/asm-arm/arch-ixp2000/ixp2000-regs.h	2005-03-01 23:38:44 -08:00
@@ -98,6 +98,7 @@
 #define	WDT_ENABLE			0x00000001
 #define	TIMER_DIVIDER_256		0x00000008
 #define	TIMER_ENABLE			0x00000080
+#define	IRQ_MASK_TIMER1         	(1 << 4)
 
 /*
  * Interrupt controller registers
diff -Nru a/include/asm-arm/arch-ixp2000/system.h b/include/asm-arm/arch-ixp2000/system.h
--- a/include/asm-arm/arch-ixp2000/system.h	2005-03-01 23:39:18 -08:00
+++ b/include/asm-arm/arch-ixp2000/system.h	2005-03-01 23:39:18 -08:00
@@ -2,6 +2,7 @@
  * linux/include/asm-arm/arch-ixp2000/system.h
  *
  * Copyright (C) 2002 Intel Corp.
+ * Copyricht (C) 2003-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
@@ -20,9 +21,27 @@
 {
 	cli();
 
-	if (machine_is_ixdp2401() || machine_is_ixdp2801()) {
-		*IXDP2X01_CPLD_FLASH_REG = ((0 >> IXDP2X01_FLASH_WINDOW_BITS) | IXDP2X01_CPLD_FLASH_INTERN);
+	/*
+	 * Reset flash banking register so that we are pointing at
+	 * RedBoot bank.
+	 */
+	if (machine_is_ixdp2401()) {
+		*IXDP2X01_CPLD_FLASH_REG = ((0 >> IXDP2X01_FLASH_WINDOW_BITS)
+						| IXDP2X01_CPLD_FLASH_INTERN);
 		*IXDP2X01_CPLD_RESET_REG = 0xffffffff;
+	}
+
+	/*
+	 * On IXDP2801 we need to write this magic sequence to the CPLD
+	 * to cause a complete reset of the CPU and all external devices
+	 * and moves the flash bank register back to 0.
+	 */
+	if (machine_is_ixdp2801()) {
+		unsigned long reset_reg = *IXDP2X01_CPLD_RESET_REG;
+		reset_reg = 0x55AA0000 | (reset_reg & 0x0000FFFF);
+		*IXDP2X01_CPLD_RESET_REG = reset_reg;
+		mb();
+		*IXDP2X01_CPLD_RESET_REG = 0x80000000;
 	}
 
 	/*
diff -Nru a/include/asm-arm/arch-ixp4xx/debug-macro.S b/include/asm-arm/arch-ixp4xx/debug-macro.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-arm/arch-ixp4xx/debug-macro.S	2005-03-01 23:39:26 -08:00
@@ -0,0 +1,34 @@
+/* linux/include/asm-arm/arch-ixp4xx/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ *  Copyright (C) 1994-1999 Russell King
+ *  Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+                .macro  addruart,rx
+                mrc     p15, 0, \rx, c1, c0
+                tst     \rx, #1                 @ MMU enabled?
+                moveq   \rx, #0xc8000000
+                movne   \rx, #0xff000000
+                add     \rx,\rx,#3              @ Uart regs are at off set of 3 if
+						@ byte writes used - Big Endian.
+                .endm
+
+               .macro  senduart,rd,rx
+                strb    \rd, [\rx]
+                .endm
+
+                .macro  waituart,rd,rx
+1002:           ldrb    \rd, [\rx, #0x14]
+                and     \rd, \rd, #0x60		@ check THRE and TEMT bits
+                teq     \rd, #0x60
+                bne     1002b
+                .endm
+
+                .macro  busyuart,rd,rx
+                .endm
diff -Nru a/include/asm-arm/arch-ixp4xx/entry-macro.S b/include/asm-arm/arch-ixp4xx/entry-macro.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-arm/arch-ixp4xx/entry-macro.S	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,39 @@
+/*
+ * include/asm-arm/arch-ixp4xx/entry-macro.S
+ *
+ * Low-level IRQ helper macros for IXP4xx-based platforms
+ *
+ * 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.
+ */
+
+		.macro	disable_fiq
+		.endm
+
+		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+		ldr	\irqstat, =(IXP4XX_INTC_BASE_VIRT+IXP4XX_ICIP_OFFSET)
+		ldr	\irqstat, [\irqstat]		@ get interrupts
+		cmp	\irqstat, #0
+		beq	1001f
+		clz     \irqnr, \irqstat
+		mov     \base, #31
+		subs    \irqnr, \base, \irqnr
+
+1001:
+		/*
+		 * IXP465 has an upper IRQ status register
+		 */
+#if defined(CONFIG_CPU_IXP46X)
+		bne 	1002f
+		ldr	\irqstat, =(IXP4XX_INTC_BASE_VIRT+IXP4XX_ICIP2_OFFSET)
+		ldr	\irqstat, [\irqstat]		@ get upper interrupts
+		mov	\irqnr, #63
+		clz	\irqstat, \irqstat
+ 		cmp	\irqstat, #32
+		subne	\irqnr, \irqnr, \irqstat
+1002:
+#endif
+		.endm
+
+
diff -Nru a/include/asm-arm/arch-ixp4xx/gtwx5715.h b/include/asm-arm/arch-ixp4xx/gtwx5715.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-arm/arch-ixp4xx/gtwx5715.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,120 @@
+/*
+ * include/asm-arm/arch-ixp4xx/gtwx5715.h
+ *
+ * Gemtek GTWX5715 Gateway (Linksys WRV54G)
+ *
+ * Copyright 2004 (c) George T. Joseph
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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 __ASM_ARCH_HARDWARE_H__
+#error "Do not include this directly, instead #include <asm/hardware.h>"
+#endif
+#include "irqs.h"
+
+#define GTWX5715_GPIO0	0
+#define GTWX5715_GPIO1	1
+#define GTWX5715_GPIO2	2
+#define GTWX5715_GPIO3	3
+#define GTWX5715_GPIO4	4
+#define GTWX5715_GPIO5	5
+#define GTWX5715_GPIO6	6
+#define GTWX5715_GPIO7	7
+#define GTWX5715_GPIO8	8
+#define GTWX5715_GPIO9	9
+#define GTWX5715_GPIO10	10
+#define GTWX5715_GPIO11	11
+#define GTWX5715_GPIO12	12
+#define GTWX5715_GPIO13	13
+#define GTWX5715_GPIO14	14
+
+#define GTWX5715_GPIO0_IRQ			IRQ_IXP4XX_GPIO0
+#define GTWX5715_GPIO1_IRQ			IRQ_IXP4XX_GPIO1
+#define GTWX5715_GPIO2_IRQ			IRQ_IXP4XX_GPIO2
+#define GTWX5715_GPIO3_IRQ			IRQ_IXP4XX_GPIO3
+#define GTWX5715_GPIO4_IRQ			IRQ_IXP4XX_GPIO4
+#define GTWX5715_GPIO5_IRQ			IRQ_IXP4XX_GPIO5
+#define GTWX5715_GPIO6_IRQ			IRQ_IXP4XX_GPIO6
+#define GTWX5715_GPIO7_IRQ			IRQ_IXP4XX_GPIO7
+#define GTWX5715_GPIO8_IRQ			IRQ_IXP4XX_GPIO8
+#define GTWX5715_GPIO9_IRQ			IRQ_IXP4XX_GPIO9
+#define GTWX5715_GPIO10_IRQ		IRQ_IXP4XX_GPIO10
+#define GTWX5715_GPIO11_IRQ		IRQ_IXP4XX_GPIO11
+#define GTWX5715_GPIO12_IRQ		IRQ_IXP4XX_GPIO12
+#define GTWX5715_GPIO13_IRQ		IRQ_IXP4XX_SW_INT1
+#define GTWX5715_GPIO14_IRQ		IRQ_IXP4XX_SW_INT2
+
+
+#define	GTWX5715_FLASH_BASE	IXP4XX_EXP_BUS_CS0_BASE_PHYS
+#define	GTWX5715_FLASH_SIZE	(0x00800000)
+
+/* PCI controller GPIO to IRQ pin mappings
+
+			INTA	INTB
+SLOT 0	10		11
+SLOT 1	11		10
+
+*/
+
+#define	GTWX5715_PCI_SLOT0_DEVID	0
+#define	GTWX5715_PCI_SLOT0_INTA_GPIO	GTWX5715_GPIO10
+#define	GTWX5715_PCI_SLOT0_INTB_GPIO	GTWX5715_GPIO11
+#define	GTWX5715_PCI_SLOT0_INTA_IRQ	GTWX5715_GPIO10_IRQ
+#define	GTWX5715_PCI_SLOT0_INTB_IRQ	GTWX5715_GPIO11_IRQ
+
+#define	GTWX5715_PCI_SLOT1_DEVID	1
+#define	GTWX5715_PCI_SLOT1_INTA_GPIO	GTWX5715_GPIO11
+#define	GTWX5715_PCI_SLOT1_INTB_GPIO	GTWX5715_GPIO10
+#define	GTWX5715_PCI_SLOT1_INTA_IRQ	GTWX5715_GPIO11_IRQ
+#define	GTWX5715_PCI_SLOT1_INTB_IRQ	GTWX5715_GPIO10_IRQ
+
+#define GTWX5715_PCI_SLOT_COUNT			2
+#define GTWX5715_PCI_INT_PIN_COUNT		2
+
+/*
+ * GPIO 5,6,7 and12 are hard wired to the Kendin KS8995M Switch
+ * and operate as an SPI type interface.  The details of the interface
+ * are available on Kendin/Micrel's web site.
+ */
+
+#define GTWX5715_KSSPI_SELECT	GTWX5715_GPIO5
+#define GTWX5715_KSSPI_TXD		GTWX5715_GPIO6
+#define GTWX5715_KSSPI_CLOCK	GTWX5715_GPIO7
+#define GTWX5715_KSSPI_RXD		GTWX5715_GPIO12
+
+/*
+ * The "reset" button is wired to GPIO 3.
+ * The GPIO is brought "low" when the button is pushed.
+ */
+
+#define GTWX5715_BUTTON_GPIO	GTWX5715_GPIO3
+#define GTWX5715_BUTTON_IRQ	GTWX5715_GPIO3_IRQ
+
+/*
+ *  Board Label      Front Label
+ *  LED1             Power
+ *  LED2             Wireless-G
+ *  LED3             not populated but could be
+ *  LED4             Internet
+ *  LED5 - LED8      Controlled by KS8995M Switch
+ *  LED9             DMZ
+ */
+
+#define GTWX5715_LED1_GPIO		GTWX5715_GPIO2
+#define GTWX5715_LED2_GPIO		GTWX5715_GPIO9
+#define GTWX5715_LED3_GPIO		GTWX5715_GPIO8
+#define GTWX5715_LED4_GPIO		GTWX5715_GPIO1
+#define GTWX5715_LED9_GPIO		GTWX5715_GPIO4
diff -Nru a/include/asm-arm/arch-ixp4xx/hardware.h b/include/asm-arm/arch-ixp4xx/hardware.h
--- a/include/asm-arm/arch-ixp4xx/hardware.h	2005-03-01 23:38:54 -08:00
+++ b/include/asm-arm/arch-ixp4xx/hardware.h	2005-03-01 23:38:54 -08:00
@@ -27,6 +27,13 @@
 
 #define pcibios_assign_all_busses()	1
 
+#if defined(CONFIG_CPU_IXP465) && !defined(__ASSEMBLY__)
+extern unsigned int processor_id;
+#define cpu_is_ixp465() ((processor_id & 0xffffffc0) == 0x69054200)
+#else
+#define	cpu_is_ixp465()	(0)
+#endif
+
 /* Register locations and bits */
 #include "ixp4xx-regs.h"
 
diff -Nru a/include/asm-arm/arch-ixp4xx/irqs.h b/include/asm-arm/arch-ixp4xx/irqs.h
--- a/include/asm-arm/arch-ixp4xx/irqs.h	2005-03-01 23:39:07 -08:00
+++ b/include/asm-arm/arch-ixp4xx/irqs.h	2005-03-01 23:39:07 -08:00
@@ -15,7 +15,6 @@
 #ifndef _ARCH_IXP4XX_IRQS_H_
 #define _ARCH_IXP4XX_IRQS_H_
 
-#define NR_IRQS			32
 
 #define IRQ_IXP4XX_NPEA		0
 #define IRQ_IXP4XX_NPEB		1
@@ -49,6 +48,25 @@
 #define IRQ_IXP4XX_GPIO12	29
 #define IRQ_IXP4XX_SW_INT1	30
 #define IRQ_IXP4XX_SW_INT2	31
+#define IRQ_IXP4XX_USB_HOST	32
+#define IRQ_IXP4XX_I2C		33
+#define IRQ_IXP4XX_SSP		34
+#define IRQ_IXP4XX_TSYNC	35
+#define IRQ_IXP4XX_EAU_DONE	36
+#define IRQ_IXP4XX_SHA_DONE	37
+#define IRQ_IXP4XX_SWCP_PE	58
+#define IRQ_IXP4XX_QM_PE	60
+#define IRQ_IXP4XX_MCU_ECC	61
+#define IRQ_IXP4XX_EXP_PE	62
+
+/*
+ * Only first 32 sources are valid if running on IXP42x systems
+ */
+#ifndef	CONFIG_CPU_IXP46X
+#define NR_IRQS			32
+#else
+#define NR_IRQS			64
+#endif
 
 #define	XSCALE_PMU_IRQ		(IRQ_IXP4XX_XSCALE_PMU)
 
diff -Nru 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	2005-03-01 23:38:53 -08:00
+++ b/include/asm-arm/arch-ixp4xx/ixp4xx-regs.h	2005-03-01 23:38:53 -08:00
@@ -43,6 +43,10 @@
  * 0xC8000000	0x0000C000	0xffbf2000	On-Chip Peripherals
  */
 
+/*
+ * Queue Manager
+ */
+#define IXP4XX_QMGR_BASE_PHYS		(0x60000000)
 
 /*
  * Expansion BUS Configuration registers
@@ -107,7 +111,9 @@
 #define IXP4XX_INTC_BASE_PHYS	(IXP4XX_PERIPHERAL_BASE_PHYS + 0x3000)
 #define IXP4XX_GPIO_BASE_PHYS	(IXP4XX_PERIPHERAL_BASE_PHYS + 0x4000)
 #define IXP4XX_TIMER_BASE_PHYS	(IXP4XX_PERIPHERAL_BASE_PHYS + 0x5000)
-#define IXP4XX_USB_BASE_PHYS	(IXP4XX_PERIPHERAL_BASE_PHYS + 0x5000)
+#define IXP4XX_EthA_BASE_PHYS	(IXP4XX_PERIPHERAL_BASE_PHYS + 0x9000)
+#define IXP4XX_EthB_BASE_PHYS	(IXP4XX_PERIPHERAL_BASE_PHYS + 0xA000)
+#define IXP4XX_USB_BASE_PHYS	(IXP4XX_PERIPHERAL_BASE_PHYS + 0xB000)
 
 #define IXP4XX_UART1_BASE_VIRT	(IXP4XX_PERIPHERAL_BASE_VIRT + 0x0000)
 #define IXP4XX_UART2_BASE_VIRT	(IXP4XX_PERIPHERAL_BASE_VIRT + 0x1000)
@@ -115,7 +121,9 @@
 #define IXP4XX_INTC_BASE_VIRT	(IXP4XX_PERIPHERAL_BASE_VIRT + 0x3000)
 #define IXP4XX_GPIO_BASE_VIRT	(IXP4XX_PERIPHERAL_BASE_VIRT + 0x4000)
 #define IXP4XX_TIMER_BASE_VIRT	(IXP4XX_PERIPHERAL_BASE_VIRT + 0x5000)
-#define IXP4XX_USB_BASE_VIRT	(IXP4XX_PERIPHERAL_BASE_VIRT + 0x5000)
+#define IXP4XX_EthA_BASE_VIRT	(IXP4XX_PERIPHERAL_BASE_VIRT + 0x9000)
+#define IXP4XX_EthB_BASE_VIRT	(IXP4XX_PERIPHERAL_BASE_VIRT + 0xA000)
+#define IXP4XX_USB_BASE_VIRT	(IXP4XX_PERIPHERAL_BASE_VIRT + 0xB000)
 
 /*
  * Constants to make it easy to access  Interrupt Controller registers
@@ -130,6 +138,17 @@
 #define IXP4XX_ICFH_OFFSET	0x1C /* FIQ Highest Pri Int */
 
 /*
+ * IXP465-only
+ */
+#define	IXP4XX_ICPR2_OFFSET	0x20 /* Interrupt Status 2 */
+#define	IXP4XX_ICMR2_OFFSET	0x24 /* Interrupt Enable 2 */
+#define	IXP4XX_ICLR2_OFFSET	0x28 /* Interrupt IRQ/FIQ Select 2 */
+#define IXP4XX_ICIP2_OFFSET     0x2C /* IRQ Status */
+#define IXP4XX_ICFP2_OFFSET	0x30 /* FIQ Status */
+#define IXP4XX_ICEEN_OFFSET	0x34 /* Error High Pri Enable */
+
+
+/*
  * Interrupt Controller Register Definitions.
  */
 
@@ -143,6 +162,12 @@
 #define IXP4XX_ICHR     IXP4XX_INTC_REG(IXP4XX_ICHR_OFFSET)
 #define IXP4XX_ICIH     IXP4XX_INTC_REG(IXP4XX_ICIH_OFFSET) 
 #define IXP4XX_ICFH     IXP4XX_INTC_REG(IXP4XX_ICFH_OFFSET)
+#define IXP4XX_ICPR2	IXP4XX_INTC_REG(IXP4XX_ICPR2_OFFSET)
+#define IXP4XX_ICMR2    IXP4XX_INTC_REG(IXP4XX_ICMR2_OFFSET)
+#define IXP4XX_ICLR2    IXP4XX_INTC_REG(IXP4XX_ICLR2_OFFSET)
+#define IXP4XX_ICIP2    IXP4XX_INTC_REG(IXP4XX_ICIP2_OFFSET)
+#define IXP4XX_ICFP2    IXP4XX_INTC_REG(IXP4XX_ICFP2_OFFSET)
+#define IXP4XX_ICEEN    IXP4XX_INTC_REG(IXP4XX_ICEEN_OFFSET)
                                                                                 
 /*
  * Constants to make it easy to access GPIO registers
@@ -547,5 +572,20 @@
 #define USIR1_IR15	(1 << 7)	/* Interrup request ep 15 */
 
 #define DCMD_LENGTH	0x01fff		/* length mask (max = 8K - 1) */
+
+#ifndef __ASSEMBLY__
+static inline int cpu_is_ixp46x(void)
+{
+#ifdef CONFIG_CPU_IXP46X
+	unsigned int processor_id;
+
+	asm("mrc p15, 0, %0, cr0, cr0, 0;" : "=r"(processor_id) :);
+
+	if ((processor_id & 0xffffff00) == 0x69054200)
+		return 1;
+#endif
+	return 0;
+}
+#endif
 
 #endif
diff -Nru a/include/asm-arm/arch-ixp4xx/platform.h b/include/asm-arm/arch-ixp4xx/platform.h
--- a/include/asm-arm/arch-ixp4xx/platform.h	2005-03-01 23:38:51 -08:00
+++ b/include/asm-arm/arch-ixp4xx/platform.h	2005-03-01 23:38:51 -08:00
@@ -60,6 +60,7 @@
  */
 extern void ixp4xx_map_io(void);
 extern void ixp4xx_init_irq(void);
+extern void ixp4xx_sys_init(void);
 extern struct sys_timer ixp4xx_timer;
 extern void ixp4xx_pci_preinit(void);
 struct pci_sys_data;
diff -Nru a/include/asm-arm/arch-ixp4xx/system.h b/include/asm-arm/arch-ixp4xx/system.h
--- a/include/asm-arm/arch-ixp4xx/system.h	2005-03-01 23:38:57 -08:00
+++ b/include/asm-arm/arch-ixp4xx/system.h	2005-03-01 23:38:57 -08:00
@@ -31,13 +31,12 @@
 		/* set the "key" register to enable access to
 		 * "timer" and "enable" registers
 		 */
-		*IXP4XX_OSWK = 0x482e; 	    
+		*IXP4XX_OSWK = IXP4XX_WDT_KEY;
 
-		/* write 0 to the timer register for an immidiate reset */
+		/* write 0 to the timer register for an immediate reset */
 		*IXP4XX_OSWT = 0;
 
-		/* disable watchdog interrupt, enable reset, enable count */
-		*IXP4XX_OSWE = 0x3;
+		*IXP4XX_OSWE = IXP4XX_WDT_RESET_ENABLE | IXP4XX_WDT_COUNT_ENABLE;
 	}
 }
 
diff -Nru a/include/asm-arm/arch-ixp4xx/uncompress.h b/include/asm-arm/arch-ixp4xx/uncompress.h
--- a/include/asm-arm/arch-ixp4xx/uncompress.h	2005-03-01 23:38:52 -08:00
+++ b/include/asm-arm/arch-ixp4xx/uncompress.h	2005-03-01 23:38:52 -08:00
@@ -46,9 +46,9 @@
 static __inline__ void __arch_decomp_setup(unsigned long arch_id)
 {
 	/*
-	 * Coyote only has UART2 connected
+	 * Coyote and gtwx5715 only have UART2 connected
 	 */
-	if (machine_is_adi_coyote())
+	if (machine_is_adi_coyote() || machine_is_gtwx5715())
 		uart_base = (volatile u32*) IXP4XX_UART2_BASE_PHYS;
 	else
 		uart_base = (volatile u32*) IXP4XX_UART1_BASE_PHYS;
diff -Nru a/include/asm-arm/arch-l7200/debug-macro.S b/include/asm-arm/arch-l7200/debug-macro.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-arm/arch-l7200/debug-macro.S	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,40 @@
+/* linux/include/asm-arm/arch-l7200/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ *  Copyright (C) 1994-1999 Russell King
+ *  Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+		.equ	io_virt, IO_BASE
+		.equ	io_phys, IO_START
+
+		.macro	addruart,rx
+		mrc	p15, 0, \rx, c1, c0
+		tst	\rx, #1			@ MMU enabled?
+		moveq	\rx, #io_phys		@ physical base address
+		movne	\rx, #io_virt		@ virtual address
+		add	\rx, \rx, #0x00044000	@ UART1
+@		add	\rx, \rx, #0x00045000	@ UART2
+		.endm
+
+		.macro	senduart,rd,rx
+		str	\rd, [\rx, #0x0]	@ UARTDR
+		.endm
+
+		.macro	waituart,rd,rx
+1001:		ldr	\rd, [\rx, #0x18]	@ UARTFLG
+		tst	\rd, #1 << 5		@ UARTFLGUTXFF - 1 when full
+		bne	1001b
+		.endm
+
+		.macro	busyuart,rd,rx
+1001:		ldr	\rd, [\rx, #0x18]	@ UARTFLG
+		tst	\rd, #1 << 3		@ UARTFLGUBUSY - 1 when busy
+		bne	1001b
+		.endm
diff -Nru a/include/asm-arm/arch-l7200/entry-macro.S b/include/asm-arm/arch-l7200/entry-macro.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-arm/arch-l7200/entry-macro.S	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,29 @@
+/*
+ * include/asm-arm/arch-l7200/entry-macro.S
+ *
+ * Low-level IRQ helper macros for L7200-based platforms
+ *
+ * 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 <asm/hardware.h>
+
+		.equ	irq_base_addr,	IO_BASE_2
+
+		.macro  disable_fiq
+		.endm
+
+		.macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
+		mov     \irqstat, #irq_base_addr		@ Virt addr IRQ regs
+		add	\irqstat, \irqstat, #0x00001000		@ Status reg
+		ldr     \irqstat, [\irqstat, #0]		@ get interrupts
+		mov     \irqnr, #0
+1001:		tst     \irqstat, #1
+		addeq   \irqnr, \irqnr, #1
+		moveq   \irqstat, \irqstat, lsr #1
+		tsteq   \irqnr, #32
+		beq     1001b
+		teq     \irqnr, #32
+		.endm
+
diff -Nru a/include/asm-arm/arch-lh7a40x/debug-macro.S b/include/asm-arm/arch-lh7a40x/debug-macro.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-arm/arch-lh7a40x/debug-macro.S	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,39 @@
+/* linux/include/asm-arm/arch-lh7a40x/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ *  Copyright (C) 1994-1999 Russell King
+ *  Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+	@ It is not known if this will be appropriate for every 40x
+	@ board.
+
+		.macro  addruart,rx
+		mrc     p15, 0, \rx, c1, c0
+		tst     \rx, #1                 @ MMU enabled?
+		mov     \rx, #0x00000700        @ offset from base
+		orreq   \rx, \rx, #0x80000000   @ physical base
+		orrne   \rx, \rx, #0xf8000000   @ virtual base
+		.endm
+
+		.macro  senduart,rd,rx
+		strb    \rd, [\rx]              @ DATA
+		.endm
+
+		.macro  busyuart,rd,rx          @ spin while busy
+1001:		ldr     \rd, [\rx, #0x10]       @ STATUS
+		tst     \rd, #1 << 3            @ BUSY (TX FIFO not empty)
+		bne     1001b                   @ yes, spin
+		.endm
+
+		.macro  waituart,rd,rx          @ wait for Tx FIFO room
+1001:		ldrb    \rd, [\rx, #0x10]       @ STATUS
+		tst     \rd, #1 << 5            @ TXFF (TX FIFO full)
+		bne     1001b                   @ yes, spin
+		.endm
diff -Nru a/include/asm-arm/arch-lh7a40x/entry-macro.S b/include/asm-arm/arch-lh7a40x/entry-macro.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-arm/arch-lh7a40x/entry-macro.S	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,67 @@
+/*
+ * include/asm-arm/arch-lh7a40x/entry-macro.S
+ *
+ * Low-level IRQ helper macros for LH7A40x platforms
+ *
+ * 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.
+ */
+
+# if defined (CONFIG_ARCH_LH7A400) && defined (CONFIG_ARCH_LH7A404)
+#  error "LH7A400 and LH7A404 are mutually exclusive"
+# endif
+
+# if defined (CONFIG_ARCH_LH7A400)
+		.macro	disable_fiq
+		.endm
+
+		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+		mov	\irqnr, #0
+		mov	\base, #io_p2v(0x80000000)	@ APB registers
+		ldr	\irqstat, [\base, #0x500]	@ PIC INTSR
+
+1001:		movs	\irqstat, \irqstat, lsr #1	@ Shift into carry
+		bcs	1008f				@ Bit set; irq found
+		add	\irqnr, \irqnr, #1
+		bne	1001b				@ Until no bits
+		b	1009f				@ Nothing?  Hmm.
+1008:		movs	\irqstat, #1			@ Force !Z
+1009:
+               .endm
+
+#elif defined(CONFIG_ARCH_LH7A404)
+
+		.macro	disable_fiq
+		.endm
+
+		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+		mov	\irqnr, #0			@ VIC1 irq base
+		mov	\base, #io_p2v(0x80000000)	@ APB registers
+		add	\base, \base, #0x8000
+		ldr	\tmp, [\base, #0x0030]		@ VIC1_VECTADDR
+		tst	\tmp, #VA_VECTORED		@ Direct vectored
+		bne	1002f
+		tst	\tmp, #VA_VIC1DEFAULT		@ Default vectored VIC1
+		ldrne	\irqstat, [\base, #0]		@ VIC1_IRQSTATUS
+		bne	1001f
+		add	\base, \base, #(0xa000 - 0x8000)
+		ldr	\tmp, [\base, #0x0030]		@ VIC2_VECTADDR
+		tst	\tmp, #VA_VECTORED		@ Direct vectored
+		bne	1002f
+		ldr	\irqstat, [\base, #0]		@ VIC2_IRQSTATUS
+		mov	\irqnr, #32			@ VIC2 irq base
+
+1001:		movs	\irqstat, \irqstat, lsr #1	@ Shift into carry
+		bcs	1008f				@ Bit set; irq found
+		add	\irqnr, \irqnr, #1
+		bne	1001b				@ Until no bits
+		b	1009f				@ Nothing?  Hmm.
+1002:		and	\irqnr, \tmp, #0x3f		@ Mask for valid bits
+1008:		movs	\irqstat, #1			@ Force !Z
+		str	\tmp, [\base, #0x0030]		@ Clear vector
+1009:
+               .endm
+#endif
+
+
diff -Nru a/include/asm-arm/arch-lh7a40x/memory.h b/include/asm-arm/arch-lh7a40x/memory.h
--- a/include/asm-arm/arch-lh7a40x/memory.h	2005-03-01 23:38:53 -08:00
+++ b/include/asm-arm/arch-lh7a40x/memory.h	2005-03-01 23:38:53 -08:00
@@ -31,6 +31,8 @@
 
 #ifdef CONFIG_DISCONTIGMEM
 
+#define NODES_SHIFT	4	/* Up to 16 nodes */
+
 /*
  * Given a kernel address, find the home node of the underlying memory.
  */
diff -Nru a/include/asm-arm/arch-omap/debug-macro.S b/include/asm-arm/arch-omap/debug-macro.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-arm/arch-omap/debug-macro.S	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,45 @@
+/* linux/include/asm-arm/arch-omap/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ *  Copyright (C) 1994-1999 Russell King
+ *  Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+		.macro	addruart,rx
+		mrc	p15, 0, \rx, c1, c0
+		tst	\rx, #1			@ MMU enabled?
+		moveq	\rx, #0xff000000	@ physical base address
+		movne	\rx, #0xfe000000	@ virtual base
+		orr	\rx, \rx, #0x00fb0000
+#ifdef CONFIG_OMAP_LL_DEBUG_UART3
+		orr	\rx, \rx, #0x00009000	@ UART 3
+#endif
+#if defined(CONFIG_OMAP_LL_DEBUG_UART2) || defined(CONFIG_OMAP_LL_DEBUG_UART3)
+		orr	\rx, \rx, #0x00000800	@ UART 2 & 3
+#endif
+		.endm
+
+		.macro	senduart,rd,rx
+		strb	\rd, [\rx]
+		.endm
+
+		.macro	busyuart,rd,rx
+1001:		ldrb	\rd, [\rx, #(0x5 << 2)]	@ OMAP-1510 and friends
+		and	\rd, \rd, #0x60
+		teq	\rd, #0x60
+		beq	1002f
+		ldrb	\rd, [\rx, #(0x5 << 0)]	@ OMAP-730 only
+		and	\rd, \rd, #0x60
+		teq	\rd, #0x60
+		bne	1001b
+1002:
+		.endm
+
+		.macro	waituart,rd,rx
+		.endm
diff -Nru a/include/asm-arm/arch-omap/dma.h b/include/asm-arm/arch-omap/dma.h
--- a/include/asm-arm/arch-omap/dma.h	2005-03-01 23:38:52 -08:00
+++ b/include/asm-arm/arch-omap/dma.h	2005-03-01 23:38:52 -08:00
@@ -238,6 +238,10 @@
 extern void omap_dma_link_lch (int lch_head, int lch_queue);
 extern void omap_dma_unlink_lch (int lch_head, int lch_queue);
 
+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);
+
 /* Returns 1 if the DMA module is in OMAP1510-compatible mode, 0 otherwise */
 extern int omap_dma_in_1510_mode(void);
 
diff -Nru a/include/asm-arm/arch-omap/entry-macro.S b/include/asm-arm/arch-omap/entry-macro.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-arm/arch-omap/entry-macro.S	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,32 @@
+/*
+ * include/asm-arm/arch-omap/entry-macro.S
+ *
+ * Low-level IRQ helper macros for OMAP-based platforms
+ *
+ * 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.
+ */
+
+ 		.macro	disable_fiq
+		.endm
+
+		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+		ldr	\base, =IO_ADDRESS(OMAP_IH1_BASE)
+		ldr	\irqnr, [\base, #IRQ_ITR_REG_OFFSET]
+		ldr	\tmp, [\base, #IRQ_MIR_REG_OFFSET]
+		mov	\irqstat, #0xffffffff
+		bic	\tmp, \irqstat, \tmp
+		tst	\irqnr, \tmp
+		beq	1510f
+
+		ldr	\irqnr, [\base, #IRQ_SIR_FIQ_REG_OFFSET]
+		cmp	\irqnr, #0
+		ldreq	\irqnr, [\base, #IRQ_SIR_IRQ_REG_OFFSET]
+		cmpeq	\irqnr, #INT_IH2_IRQ
+		ldreq	\base, =IO_ADDRESS(OMAP_IH2_BASE)
+		ldreq	\irqnr, [\base, #IRQ_SIR_IRQ_REG_OFFSET]
+		addeqs	\irqnr, \irqnr, #32
+1510:
+		.endm
+
diff -Nru a/include/asm-arm/arch-omap/gpio.h b/include/asm-arm/arch-omap/gpio.h
--- a/include/asm-arm/arch-omap/gpio.h	2005-03-01 23:38:54 -08:00
+++ b/include/asm-arm/arch-omap/gpio.h	2005-03-01 23:38:54 -08:00
@@ -58,6 +58,7 @@
 #define OMAP_GPIO_RISING_EDGE	  0x02
 #define OMAP_GPIO_BOTH_EDGES	  0x03
 
+extern int omap_gpio_init(void);	/* Call from board init only */
 extern int omap_request_gpio(int gpio);
 extern void omap_free_gpio(int gpio);
 extern void omap_set_gpio_direction(int gpio, int is_input);
diff -Nru a/include/asm-arm/arch-omap/hardware.h b/include/asm-arm/arch-omap/hardware.h
--- a/include/asm-arm/arch-omap/hardware.h	2005-03-01 23:38:52 -08:00
+++ b/include/asm-arm/arch-omap/hardware.h	2005-03-01 23:38:52 -08:00
@@ -137,7 +137,7 @@
 /* CNTL_TIMER register bits */
 #define MPUTIM_FREE		(1<<6)
 #define MPUTIM_CLOCK_ENABLE	(1<<5)
-#define MPUTIM_PTV_MASK		(0x7<<PTV_BIT)
+#define MPUTIM_PTV_MASK		(0x7<<MPUTIM_PTV_BIT)
 #define MPUTIM_PTV_BIT		2
 #define MPUTIM_AR		(1<<1)
 #define MPUTIM_ST		(1<<0)
diff -Nru a/include/asm-arm/arch-omap/irqs.h b/include/asm-arm/arch-omap/irqs.h
--- a/include/asm-arm/arch-omap/irqs.h	2005-03-01 23:38:44 -08:00
+++ b/include/asm-arm/arch-omap/irqs.h	2005-03-01 23:38:44 -08:00
@@ -147,6 +147,8 @@
 #define INT_1610_SoSSI		(9 + IH2_BASE)
 #define INT_1610_SoSSI_MATCH	(19 + IH2_BASE)
 #define INT_1610_McBSP2RX_OF	(31 + IH2_BASE)
+#define INT_1610_STI		(32 + IH2_BASE)
+#define INT_1610_STI_WAKEUP	(33 + IH2_BASE)
 #define INT_1610_GPIO_BANK2	(40 + IH2_BASE)
 #define INT_1610_GPIO_BANK3	(41 + IH2_BASE)
 #define INT_1610_MMC2		(42 + IH2_BASE)
diff -Nru a/include/asm-arm/arch-omap/mux.h b/include/asm-arm/arch-omap/mux.h
--- a/include/asm-arm/arch-omap/mux.h	2005-03-01 23:38:55 -08:00
+++ b/include/asm-arm/arch-omap/mux.h	2005-03-01 23:38:55 -08:00
@@ -310,6 +310,12 @@
 	/* Power management */
 	T20_1610_LOW_PWR,
 
+	/* MCLK Settings */
+	V5_1710_MCLK_ON,
+	V5_1710_MCLK_OFF,
+	R10_1610_MCLK_ON,
+	R10_1610_MCLK_OFF,
+
 } reg_cfg_t;
 
 #if defined(__MUX_C__) && defined(CONFIG_OMAP_MUX)
@@ -516,6 +522,12 @@
 
 /* Power management */
 MUX_CFG("T20_1610_LOW_PWR",	 7,   12,    1,	  NA,   0,   0,   NA,	 0,  0)
+
+/* MCLK Settings */
+MUX_CFG("V5_1710_MCLK_ON",	 B,   15,    0,	  NA,   0,   0,   NA,	 0,  0)
+MUX_CFG("V5_1710_MCLK_OFF",	 B,   15,    6,	  NA,   0,   0,   NA,	 0,  0)
+MUX_CFG("R10_1610_MCLK_ON",	 B,   18,    0,	  NA,  22,   0,	  NA,	 1,  0)
+MUX_CFG("R10_1610_MCLK_OFF",	 B,   18,    6,	  2,   22,   1,	  2,	 1,  1)
 };
 
 #endif	/* __MUX_C__ */
diff -Nru a/include/asm-arm/arch-omap/omap16xx.h b/include/asm-arm/arch-omap/omap16xx.h
--- a/include/asm-arm/arch-omap/omap16xx.h	2005-03-01 23:38:51 -08:00
+++ b/include/asm-arm/arch-omap/omap16xx.h	2005-03-01 23:38:51 -08:00
@@ -56,8 +56,9 @@
  */
 
 #define OMAP1610_SRAM_IDLE_SUSPEND	(OMAP16XX_SRAM_BASE + OMAP1610_SRAM_SIZE - 0x200)
-#define OMAP5912_SRAM_IDLE_SUSPEND	(OMAP16XX_SRAM_BASE + OMAP5912_SRAM_SIZE - 0x200)
 #define OMAP1610_SRAM_API_SUSPEND	(OMAP1610_SRAM_IDLE_SUSPEND + 0x100)
+#define OMAP5912_SRAM_IDLE_SUSPEND	(OMAP16XX_SRAM_BASE + OMAP5912_SRAM_SIZE - 0x200)
+#define OMAP5912_SRAM_API_SUSPEND	(OMAP5912_SRAM_IDLE_SUSPEND + 0x100)
 
 /*
  * ---------------------------------------------------------------------------
diff -Nru a/include/asm-arm/arch-pxa/audio.h b/include/asm-arm/arch-pxa/audio.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-arm/arch-pxa/audio.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,16 @@
+#ifndef __ASM_ARCH_AUDIO_H__
+#define __ASM_ARCH_AUDIO_H__
+
+#include <sound/driver.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+
+typedef struct {
+	int (*startup)(snd_pcm_substream_t *, void *);
+	void (*shutdown)(snd_pcm_substream_t *, void *);
+	void (*suspend)(void *);
+	void (*resume)(void *);
+	void *priv;
+} pxa2xx_audio_ops_t;
+
+#endif
diff -Nru a/include/asm-arm/arch-pxa/corgi.h b/include/asm-arm/arch-pxa/corgi.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-arm/arch-pxa/corgi.h	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,150 @@
+/*
+ * Hardware specific definitions for SL-C7xx series of PDAs
+ *
+ * Copyright (c) 2004-2005 Richard Purdie
+ *
+ * Based on Sharp's 2.4 kernel patches
+ *
+ * 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_CORGI_H
+#define __ASM_ARCH_CORGI_H  1
+
+
+/*
+ * Corgi (Non Standard) GPIO Definitions
+ */
+#define CORGI_GPIO_KEY_INT			(0)	/* Keyboard Interrupt */
+#define CORGI_GPIO_AC_IN			(1) /* Charger Detection */
+#define CORGI_GPIO_WAKEUP			(3) /* System wakeup notification? */
+#define CORGI_GPIO_AK_INT			(4)	/* Headphone Jack Control Interrupt */
+#define CORGI_GPIO_TP_INT			(5)	/* Touch Panel Interrupt */
+#define CORGI_GPIO_nSD_WP			(7) /* SD Write Protect? */
+#define CORGI_GPIO_nSD_DETECT		(9) /* MMC/SD Card Detect */
+#define CORGI_GPIO_nSD_INT			(10) /* SD Interrupt for SDIO? */
+#define CORGI_GPIO_MAIN_BAT_LOW		(11) /* Main Battery Low Notification */
+#define CORGI_GPIO_BAT_COVER		(11) /* Battery Cover Detect */
+#define CORGI_GPIO_LED_ORANGE		(13) /* Orange LED Control */
+#define CORGI_GPIO_CF_CD			(14) /* Compact Flash Card Detect */
+#define CORGI_GPIO_CHRG_FULL		(16) /* Charging Complete Notification */
+#define CORGI_GPIO_CF_IRQ			(17) /* Compact Flash Interrupt */
+#define CORGI_GPIO_LCDCON_CS		(19) /* LCD Control Chip Select */
+#define CORGI_GPIO_MAX1111_CS		(20) /* MAX1111 Chip Select */
+#define CORGI_GPIO_ADC_TEMP_ON		(21) /* Select battery voltage or temperature */
+#define CORGI_GPIO_IR_ON			(22) /* Enable IR Transciever */
+#define CORGI_GPIO_ADS7846_CS		(24) /* ADS7846 Chip Select */
+#define CORGI_GPIO_SD_PWR			(33) /* MMC/SD Power */
+#define CORGI_GPIO_CHRG_ON			(38) /* Enable battery Charging */
+#define CORGI_GPIO_DISCHARGE_ON		(42) /* Enable battery Discharge */
+#define CORGI_GPIO_CHRG_UKN			(43) /* Unknown Charging (Bypass Control?) */
+#define CORGI_GPIO_HSYNC			(44) /* LCD HSync Pulse */
+#define CORGI_GPIO_USB_PULLUP		(45) /* USB show presence to host */
+
+
+/*
+ * Corgi Keyboard Definitions
+ */
+#define CORGI_KEY_STROBE_NUM		(12)
+#define CORGI_KEY_SENSE_NUM			(8)
+#define CORGI_GPIO_ALL_STROBE_BIT	(0x00003ffc)
+#define CORGI_GPIO_HIGH_SENSE_BIT	(0xfc000000)
+#define CORGI_GPIO_HIGH_SENSE_RSHIFT	(26)
+#define CORGI_GPIO_LOW_SENSE_BIT	(0x00000003)
+#define CORGI_GPIO_LOW_SENSE_LSHIFT	(6)
+#define CORGI_GPIO_STROBE_BIT(a)	GPIO_bit(66+(a))
+#define CORGI_GPIO_SENSE_BIT(a)		GPIO_bit(58+(a))
+#define CORGI_GAFR_ALL_STROBE_BIT	(0x0ffffff0)
+#define CORGI_GAFR_HIGH_SENSE_BIT	(0xfff00000)
+#define CORGI_GAFR_LOW_SENSE_BIT	(0x0000000f)
+#define CORGI_GPIO_KEY_SENSE(a)		(58+(a))
+#define CORGI_GPIO_KEY_STROBE(a)	(66+(a))
+
+
+/*
+ * Corgi Interrupts
+ */
+#define CORGI_IRQ_GPIO_KEY_INT		IRQ_GPIO(0)
+#define CORGI_IRQ_GPIO_AC_IN		IRQ_GPIO(1)
+#define CORGI_IRQ_GPIO_WAKEUP		IRQ_GPIO(3)
+#define CORGI_IRQ_GPIO_AK_INT		IRQ_GPIO(4)
+#define CORGI_IRQ_GPIO_TP_INT		IRQ_GPIO(5)
+#define CORGI_IRQ_GPIO_nSD_DETECT	IRQ_GPIO(9)
+#define CORGI_IRQ_GPIO_nSD_INT		IRQ_GPIO(10)
+#define CORGI_IRQ_GPIO_MAIN_BAT_LOW	IRQ_GPIO(11)
+#define CORGI_IRQ_GPIO_CF_CD		IRQ_GPIO(14)
+#define CORGI_IRQ_GPIO_CHRG_FULL	IRQ_GPIO(16)	/* Battery fully charged */
+#define CORGI_IRQ_GPIO_CF_IRQ		IRQ_GPIO(17)
+#define CORGI_IRQ_GPIO_KEY_SENSE(a)	IRQ_GPIO(58+(a))	/* Keyboard Sense lines */
+
+
+/*
+ * Corgi SCOOP GPIOs and Config
+ */
+#define CORGI_SCP_LED_GREEN		SCOOP_GPCR_PA11
+#define CORGI_SCP_SWA			SCOOP_GPCR_PA12  /* Hinge Switch A */
+#define CORGI_SCP_SWB			SCOOP_GPCR_PA13  /* Hinge Switch B */
+#define CORGI_SCP_MUTE_L		SCOOP_GPCR_PA14
+#define CORGI_SCP_MUTE_R		SCOOP_GPCR_PA15
+#define CORGI_SCP_AKIN_PULLUP	SCOOP_GPCR_PA16
+#define CORGI_SCP_APM_ON		SCOOP_GPCR_PA17
+#define CORGI_SCP_BACKLIGHT_CONT	SCOOP_GPCR_PA18
+#define CORGI_SCP_MIC_BIAS		SCOOP_GPCR_PA19
+
+#define CORGI_SCOOP_IO_DIR	( CORGI_SCP_LED_GREEN | CORGI_SCP_MUTE_L | CORGI_SCP_MUTE_R | \
+			CORGI_SCP_AKIN_PULLUP | CORGI_SCP_APM_ON | CORGI_SCP_BACKLIGHT_CONT | \
+			CORGI_SCP_MIC_BIAS )
+#define CORGI_SCOOP_IO_OUT	( CORGI_SCP_MUTE_L | CORGI_SCP_MUTE_R )
+
+
+/*
+ * Corgi Parameter Area Definitions
+ */
+#define FLASH_MEM_BASE	0xa0000a00
+#define FLASH_MAGIC_CHG(a,b,c,d) ( ( d << 24 ) | ( c << 16 )  | ( b << 8 ) | a )
+
+#define FLASH_COMADJ_MAJIC	FLASH_MAGIC_CHG('C','M','A','D')
+#define	FLASH_COMADJ_MAGIC_ADR	0x00
+#define	FLASH_COMADJ_DATA_ADR	0x04
+
+#define FLASH_PHAD_MAJIC	FLASH_MAGIC_CHG('P','H','A','D')
+#define	FLASH_PHAD_MAGIC_ADR	0x38
+#define	FLASH_PHAD_DATA_ADR	0x3C
+
+struct sharpsl_flash_param_info {
+  unsigned int comadj_keyword;
+  unsigned int comadj;
+
+  unsigned int uuid_keyword;
+  unsigned char uuid[16];
+
+  unsigned int touch_keyword;
+  unsigned int touch1;
+  unsigned int touch2;
+  unsigned int touch3;
+  unsigned int touch4;
+
+  unsigned int adadj_keyword;
+  unsigned int adadj;
+
+  unsigned int phad_keyword;
+  unsigned int phadadj;
+};
+
+
+/*
+ * External Functions
+ */
+extern unsigned long corgi_ssp_ads7846_putget(unsigned long);
+extern unsigned long corgi_ssp_ads7846_get(void);
+extern void corgi_ssp_ads7846_put(ulong data);
+extern void corgi_ssp_ads7846_lock(void);
+extern void corgi_ssp_ads7846_unlock(void);
+extern void corgi_ssp_lcdtg_send (u8 adrs, u8 data);
+extern void corgi_ssp_blduty_set(int duty);
+extern int corgi_ssp_max1111_get(ulong data);
+
+#endif /* __ASM_ARCH_CORGI_H  */
+
diff -Nru a/include/asm-arm/arch-pxa/debug-macro.S b/include/asm-arm/arch-pxa/debug-macro.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-arm/arch-pxa/debug-macro.S	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,36 @@
+/* linux/include/asm-arm/arch-pxa/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ *  Copyright (C) 1994-1999 Russell King
+ *  Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+		.macro	addruart,rx
+		mrc	p15, 0, \rx, c1, c0
+		tst	\rx, #1			@ MMU enabled?
+		moveq	\rx, #0x40000000		@ physical
+		movne	\rx, #io_p2v(0x40000000)	@ virtual
+		orr	\rx, \rx, #0x00100000
+		.endm
+
+		.macro	senduart,rd,rx
+		str	\rd, [\rx, #0]
+		.endm
+
+		.macro	busyuart,rd,rx
+1002:		ldr	\rd, [\rx, #0x14]
+		tst	\rd, #(1 << 6)
+		beq	1002b
+		.endm
+
+		.macro	waituart,rd,rx
+1001:		ldr	\rd, [\rx, #0x14]
+		tst	\rd, #(1 << 5)
+		beq	1001b
+		.endm
diff -Nru a/include/asm-arm/arch-pxa/entry-macro.S b/include/asm-arm/arch-pxa/entry-macro.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-arm/arch-pxa/entry-macro.S	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,31 @@
+/*
+ * include/asm-arm/arch-pxa/entry-macro.S
+ *
+ * Low-level IRQ helper macros for PXA-based platforms
+ *
+ * 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.
+ */
+
+		.macro	disable_fiq
+		.endm
+
+		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+#ifdef CONFIG_PXA27x
+		mrc	p6, 0, \irqstat, c0, c0, 0		@ ICIP
+		mrc	p6, 0, \irqnr, c1, c0, 0		@ ICMR
+#else
+		mov	\base, #io_p2v(0x40000000)	@ IIR Ctl = 0x40d00000
+		add	\base, \base, #0x00d00000
+		ldr	\irqstat, [\base, #0]		@ ICIP
+		ldr	\irqnr, [\base, #4]		@ ICMR
+#endif
+		ands	\irqnr, \irqstat, \irqnr
+		beq	1001f
+		rsb	\irqstat, \irqnr, #0
+		and	\irqstat, \irqstat, \irqnr
+		clz	\irqnr, \irqstat
+		rsb	\irqnr, \irqnr, #(31 - PXA_IRQ_SKIP)
+1001:
+		.endm
diff -Nru a/include/asm-arm/arch-pxa/memory.h b/include/asm-arm/arch-pxa/memory.h
--- a/include/asm-arm/arch-pxa/memory.h	2005-03-01 23:38:56 -08:00
+++ b/include/asm-arm/arch-pxa/memory.h	2005-03-01 23:38:56 -08:00
@@ -37,8 +37,6 @@
  * 	node 3:  0xac000000-0xafffffff	-->  0xcc000000-0xcfffffff
  */
 
-#define NR_NODES	4
-
 /*
  * Given a kernel address, find the home node of the underlying memory.
  */
diff -Nru 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	2005-03-01 23:39:07 -08:00
+++ b/include/asm-arm/arch-pxa/pxa-regs.h	2005-03-01 23:39:07 -08:00
@@ -272,11 +272,6 @@
 #define DCMD_WIDTH4	(3 << 14)	/* 4 byte width (Word) */
 #define DCMD_LENGTH	0x01fff		/* length mask (max = 8K - 1) */
 
-/* default combinations */
-#define DCMD_RXPCDR	(DCMD_INCTRGADDR|DCMD_FLOWSRC|DCMD_BURST32|DCMD_WIDTH4)
-#define DCMD_RXMCDR	(DCMD_INCTRGADDR|DCMD_FLOWSRC|DCMD_BURST32|DCMD_WIDTH4)
-#define DCMD_TXPCDR	(DCMD_INCSRCADDR|DCMD_FLOWTRG|DCMD_BURST32|DCMD_WIDTH4)
-
 
 /*
  * UARTs
@@ -449,7 +444,8 @@
  */
 
 /* FIXME: This clash with SA1111 defines */
-#ifndef CONFIG_SA1111
+#ifndef _ASM_ARCH_SA1111
+
 #define SACR0		__REG(0x40400000)  /* Global Control Register */
 #define SACR1		__REG(0x40400004)  /* Serial Audio I 2 S/MSB-Justified Control Register */
 #define SASR0		__REG(0x4040000C)  /* Serial Audio I 2 S/MSB-Justified Interface and FIFO Status Register */
@@ -457,45 +453,37 @@
 #define SAICR		__REG(0x40400018)  /* Serial Audio Interrupt Clear Register */
 #define SADIV		__REG(0x40400060)  /* Audio Clock Divider Register. */
 #define SADR		__REG(0x40400080)  /* Serial Audio Data Register (TX and RX FIFO access Register). */
-#endif
 
-#define SACR0_RFTH(x)	(x << 12)		/* Rx FIFO Interrupt or DMA Trigger Threshold */
-#define SACR0_TFTH(x)	(x << 8)		/* Tx FIFO Interrupt or DMA Trigger Threshold */
-#define SACR0_STRF		(1 << 5)		/* FIFO Select for EFWR Special Function */
-#define SACR0_EFWR		(1 << 4)		/* Enable EFWR Function  */
-#define SACR0_RST		(1 << 3)		/* FIFO, i2s Register Reset */
-#define SACR0_BCKD		(1 << 2) 		/* Bit Clock Direction */
-#define SACR0_ENB		(1 << 0)		/* Enable I2S Link */
-
-#define SACR1_ENLBF		(1 << 5)		/* Enable Loopback */
-#define SACR1_DRPL		(1 << 4) 		/* Disable Replaying Function */
-#define SACR1_DREC		(1 << 3)		/* Disable Recording Function */
-#define SACR1_AMSL		(1 << 1)		/* Specify Alternate Mode */
-
-#define SASR0_I2SOFF	(1 << 7)		/* Controller Status */
-#define SASR0_ROR		(1 << 6)		/* Rx FIFO Overrun */
-#define SASR0_TUR		(1 << 5)		/* Tx FIFO Underrun */
-#define SASR0_RFS		(1 << 4)		/* Rx FIFO Service Request */
-#define SASR0_TFS		(1 << 3)		/* Tx FIFO Service Request */
-#define SASR0_BSY		(1 << 2)		/* I2S Busy */
-#define SASR0_RNE		(1 << 1)		/* Rx FIFO Not Empty */
-#define SASR0_TNF		(1 << 0) 		/* Tx FIFO Not Empty */
-
-#define SADIV_3_058M	0x0c			/* Serial Clock Divider 3.058MHz */
-#define SADIV_2_836M	0x0d			/* 2.836 MHz */
-#define SADIV_1_405M	0x1a			/* 1.405 MHz */
-#define SADIV_1_026M	0x24			/* 1.026 MHz */
-#define SADIV_702K		0x34			/* 702 kHz */
-#define SADIV_513K		0x48			/* 513 kHz */
-
-#define SAICR_ROR		(1 << 6)		/* Clear Rx FIFO Overrun Interrupt */
-#define SAICR_TUR		(1 << 5)		/* Clear Tx FIFO Underrun Interrupt */
-
-#define SAIMR_ROR		(1 << 6)		/* Enable Rx FIFO Overrun Condition Interrupt */
-#define SAIMR_TUR		(1 << 5)		/* Enable Tx FIFO Underrun Condition Interrupt */
-#define SAIMR_RFS		(1 << 4)		/* Enable Rx FIFO Service Interrupt */
-#define SAIMR_TFS		(1 << 3)		/* Enable Tx FIFO Service Interrupt */
+#define SACR0_RFTH(x)	(x << 12)	/* Rx FIFO Interrupt or DMA Trigger Threshold */
+#define SACR0_TFTH(x)	(x << 8)	/* Tx FIFO Interrupt or DMA Trigger Threshold */
+#define SACR0_STRF	(1 << 5)	/* FIFO Select for EFWR Special Function */
+#define SACR0_EFWR	(1 << 4)	/* Enable EFWR Function  */
+#define SACR0_RST	(1 << 3)	/* FIFO, i2s Register Reset */
+#define SACR0_BCKD	(1 << 2) 	/* Bit Clock Direction */
+#define SACR0_ENB	(1 << 0)	/* Enable I2S Link */
+#define SACR1_ENLBF	(1 << 5)	/* Enable Loopback */
+#define SACR1_DRPL	(1 << 4) 	/* Disable Replaying Function */
+#define SACR1_DREC	(1 << 3)	/* Disable Recording Function */
+#define SACR1_AMSL	(1 << 1)	/* Specify Alternate Mode */
+
+#define SASR0_I2SOFF	(1 << 7)	/* Controller Status */
+#define SASR0_ROR	(1 << 6)	/* Rx FIFO Overrun */
+#define SASR0_TUR	(1 << 5)	/* Tx FIFO Underrun */
+#define SASR0_RFS	(1 << 4)	/* Rx FIFO Service Request */
+#define SASR0_TFS	(1 << 3)	/* Tx FIFO Service Request */
+#define SASR0_BSY	(1 << 2)	/* I2S Busy */
+#define SASR0_RNE	(1 << 1)	/* Rx FIFO Not Empty */
+#define SASR0_TNF	(1 << 0) 	/* Tx FIFO Not Empty */
+
+#define SAICR_ROR	(1 << 6)	/* Clear Rx FIFO Overrun Interrupt */
+#define SAICR_TUR	(1 << 5)	/* Clear Tx FIFO Underrun Interrupt */
+
+#define SAIMR_ROR	(1 << 6)	/* Enable Rx FIFO Overrun Condition Interrupt */
+#define SAIMR_TUR	(1 << 5)	/* Enable Tx FIFO Underrun Condition Interrupt */
+#define SAIMR_RFS	(1 << 4)	/* Enable Rx FIFO Service Interrupt */
+#define SAIMR_TFS	(1 << 3)	/* Enable Tx FIFO Service Interrupt */
 
+#endif
 
 /*
  * AC97 Controller registers
@@ -503,14 +491,18 @@
 
 #define POCR		__REG(0x40500000)  /* PCM Out Control Register */
 #define POCR_FEIE	(1 << 3)	/* FIFO Error Interrupt Enable */
+#define POCR_FSRIE	(1 << 1)	/* FIFO Service Request Interrupt Enable */
 
 #define PICR		__REG(0x40500004)  /* PCM In Control Register */
 #define PICR_FEIE	(1 << 3)	/* FIFO Error Interrupt Enable */
+#define PICR_FSRIE	(1 << 1)	/* FIFO Service Request Interrupt Enable */
 
 #define MCCR		__REG(0x40500008)  /* Mic In Control Register */
 #define MCCR_FEIE	(1 << 3)	/* FIFO Error Interrupt Enable */
+#define MCCR_FSRIE	(1 << 1)	/* FIFO Service Request Interrupt Enable */
 
 #define GCR		__REG(0x4050000C)  /* Global Control Register */
+#define GCR_nDMAEN	(1 << 24)	/* non DMA Enable */
 #define GCR_CDONE_IE	(1 << 19)	/* Command Done Interrupt Enable */
 #define GCR_SDONE_IE	(1 << 18)	/* Status Done Interrupt Enable */
 #define GCR_SECRDY_IEN	(1 << 9)	/* Secondary Ready Interrupt Enable */
@@ -524,12 +516,17 @@
 
 #define POSR		__REG(0x40500010)  /* PCM Out Status Register */
 #define POSR_FIFOE	(1 << 4)	/* FIFO error */
+#define POSR_FSR	(1 << 2)	/* FIFO Service Request */
 
 #define PISR		__REG(0x40500014)  /* PCM In Status Register */
 #define PISR_FIFOE	(1 << 4)	/* FIFO error */
+#define PISR_EOC	(1 << 3)	/* DMA End-of-Chain (exclusive clear) */
+#define PISR_FSR	(1 << 2)	/* FIFO Service Request */
 
 #define MCSR		__REG(0x40500018)  /* Mic In Status Register */
 #define MCSR_FIFOE	(1 << 4)	/* FIFO error */
+#define MCSR_EOC	(1 << 3)	/* DMA End-of-Chain (exclusive clear) */
+#define MCSR_FSR	(1 << 2)	/* FIFO Service Request */
 
 #define GSR		__REG(0x4050001C)  /* Global Status Register */
 #define GSR_CDONE	(1 << 19)	/* Command Done */
@@ -542,9 +539,10 @@
 #define GSR_PRIRES	(1 << 10)	/* Primary Resume Interrupt */
 #define GSR_SCR		(1 << 9)	/* Secondary Codec Ready */
 #define GSR_PCR		(1 << 8)	/*  Primary Codec Ready */
-#define GSR_MINT	(1 << 7)	/* Mic In Interrupt */
+#define GSR_MCINT	(1 << 7)	/* Mic In Interrupt */
 #define GSR_POINT	(1 << 6)	/* PCM Out Interrupt */
 #define GSR_PIINT	(1 << 5)	/* PCM In Interrupt */
+#define GSR_ACOFFD	(1 << 3)	/* AC-link Shut Off Done */
 #define GSR_MOINT	(1 << 2)	/* Modem Out Interrupt */
 #define GSR_MIINT	(1 << 1)	/* Modem In Interrupt */
 #define GSR_GSCI	(1 << 0)	/* Codec GPI Status Change Interrupt */
@@ -557,15 +555,20 @@
 
 #define MOCR		__REG(0x40500100)  /* Modem Out Control Register */
 #define MOCR_FEIE	(1 << 3)	/* FIFO Error */
+#define MOCR_FSRIE	(1 << 1)	/* FIFO Service Request Interrupt Enable */
 
 #define MICR		__REG(0x40500108)  /* Modem In Control Register */
 #define MICR_FEIE	(1 << 3)	/* FIFO Error */
+#define MICR_FSRIE	(1 << 1)	/* FIFO Service Request Interrupt Enable */
 
 #define MOSR		__REG(0x40500110)  /* Modem Out Status Register */
 #define MOSR_FIFOE	(1 << 4)	/* FIFO error */
+#define MOSR_FSR	(1 << 2)	/* FIFO Service Request */
 
 #define MISR		__REG(0x40500118)  /* Modem In Status Register */
 #define MISR_FIFOE	(1 << 4)	/* FIFO error */
+#define MISR_EOC	(1 << 3)	/* DMA End-of-Chain (exclusive clear) */
+#define MISR_FSR	(1 << 2)	/* FIFO Service Request */
 
 #define MODR		__REG(0x40500140)  /* Modem FIFO Data Register */
 
@@ -1215,6 +1218,7 @@
 #define GPIO30_SDATA_OUT	30	/* AC97/I2S Sdata_out */
 #define GPIO31_SYNC		31	/* AC97/I2S sync */
 #define GPIO32_SDATA_IN1	32	/* AC97 Sdata_in1 */
+#define GPIO32_SYSCLK		32	/* I2S System Clock */
 #define GPIO32_MMCCLK		32	/* MMC Clock (PXA270) */
 #define GPIO33_nCS_5		33	/* chip select 5 */
 #define GPIO34_FFRXD		34	/* FFUART receive */
@@ -1326,20 +1330,22 @@
 #define GPIO18_RDY_MD		(18 | GPIO_ALT_FN_1_IN)
 #define GPIO19_DREQ1_MD		(19 | GPIO_ALT_FN_1_IN)
 #define GPIO20_DREQ0_MD		(20 | GPIO_ALT_FN_1_IN)
-#define GPIO23_SCLK_md		(23 | GPIO_ALT_FN_2_OUT)
+#define GPIO23_SCLK_MD		(23 | GPIO_ALT_FN_2_OUT)
 #define GPIO24_SFRM_MD		(24 | GPIO_ALT_FN_2_OUT)
 #define GPIO25_STXD_MD		(25 | GPIO_ALT_FN_2_OUT)
 #define GPIO26_SRXD_MD		(26 | GPIO_ALT_FN_1_IN)
 #define GPIO27_SEXTCLK_MD	(27 | GPIO_ALT_FN_1_IN)
 #define GPIO28_BITCLK_AC97_MD	(28 | GPIO_ALT_FN_1_IN)
-#define GPIO28_BITCLK_I2S_MD	(28 | GPIO_ALT_FN_2_IN)
+#define GPIO28_BITCLK_IN_I2S_MD	(28 | GPIO_ALT_FN_2_IN)
+#define GPIO28_BITCLK_OUT_I2S_MD	(28 | GPIO_ALT_FN_1_OUT)
 #define GPIO29_SDATA_IN_AC97_MD	(29 | GPIO_ALT_FN_1_IN)
 #define GPIO29_SDATA_IN_I2S_MD	(29 | GPIO_ALT_FN_2_IN)
 #define GPIO30_SDATA_OUT_AC97_MD	(30 | GPIO_ALT_FN_2_OUT)
 #define GPIO30_SDATA_OUT_I2S_MD	(30 | GPIO_ALT_FN_1_OUT)
-#define GPIO31_SYNC_AC97_MD	(31 | GPIO_ALT_FN_2_OUT)
 #define GPIO31_SYNC_I2S_MD	(31 | GPIO_ALT_FN_1_OUT)
+#define GPIO31_SYNC_AC97_MD	(31 | GPIO_ALT_FN_2_OUT)
 #define GPIO32_SDATA_IN1_AC97_MD	(32 | GPIO_ALT_FN_1_IN)
+#define GPIO32_SYSCLK_I2S_MD	(32 | GPIO_ALT_FN_1_OUT)
 #define GPIO32_MMCCLK_MD		( 32 | GPIO_ALT_FN_2_OUT)
 #define GPIO33_nCS_5_MD		(33 | GPIO_ALT_FN_2_OUT)
 #define GPIO34_FFRXD_MD		(34 | GPIO_ALT_FN_1_IN)
@@ -1580,6 +1586,7 @@
 #define SSCR0_EDSS		(1 << 20)	/* Extended Data Size Select */
 
 /* extra bits in PXA255, PXA26x and PXA27x SSP ports */
+#define SSCR0_PSP		(3 << 4)	/* PSP - Programmable Serial Protocol */
 #define SSCR1_TTELP		(1 << 31)	/* TXD Tristate Enable Last Phase */
 #define SSCR1_TTE		(1 << 30)	/* TXD Tristate Enable */
 #define SSCR1_EBCEI		(1 << 29)	/* Enable Bit Count Error interrupt */
diff -Nru a/include/asm-arm/arch-pxa/ssp.h b/include/asm-arm/arch-pxa/ssp.h
--- a/include/asm-arm/arch-pxa/ssp.h	2005-03-01 23:38:52 -08:00
+++ b/include/asm-arm/arch-pxa/ssp.h	2005-03-01 23:38:52 -08:00
@@ -40,8 +40,8 @@
 void ssp_disable(struct ssp_dev *dev);
 void ssp_save_state(struct ssp_dev *dev, struct ssp_state *ssp);
 void ssp_restore_state(struct ssp_dev *dev, struct ssp_state *ssp);
-int ssp_init(struct ssp_dev *dev, u32 port, u32 mode, u32 flags, u32 psp_flags,
-						u32 speed);
+int ssp_init(struct ssp_dev *dev, u32 port);
+int ssp_config(struct ssp_dev *dev, u32 mode, u32 flags, u32 psp_flags, u32 speed);
 void ssp_exit(struct ssp_dev *dev);
 
 #endif
diff -Nru a/include/asm-arm/arch-rpc/debug-macro.S b/include/asm-arm/arch-rpc/debug-macro.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-arm/arch-rpc/debug-macro.S	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,35 @@
+/* linux/include/asm-arm/arch-rpc/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ *  Copyright (C) 1994-1999 Russell King
+ *  Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+		.macro	addruart,rx
+		mov	\rx, #0xe0000000
+		orr	\rx, \rx, #0x00010000
+		orr	\rx, \rx, #0x00000fe0
+		.endm
+
+		.macro	senduart,rd,rx
+		strb	\rd, [\rx]
+		.endm
+
+		.macro	busyuart,rd,rx
+1001:		ldrb	\rd, [\rx, #0x14]
+		and	\rd, \rd, #0x60
+		teq	\rd, #0x60
+		bne	1001b
+		.endm
+
+		.macro	waituart,rd,rx
+1001:		ldrb	\rd, [\rx, #0x18]
+		tst	\rd, #0x10
+		beq	1001b
+		.endm
diff -Nru a/include/asm-arm/arch-rpc/entry-macro.S b/include/asm-arm/arch-rpc/entry-macro.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-arm/arch-rpc/entry-macro.S	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,3 @@
+
+#include <asm/hardware/entry-macro-iomd.S>
+
diff -Nru a/include/asm-arm/arch-rpc/io.h b/include/asm-arm/arch-rpc/io.h
--- a/include/asm-arm/arch-rpc/io.h	2005-03-01 23:38:58 -08:00
+++ b/include/asm-arm/arch-rpc/io.h	2005-03-01 23:38:58 -08:00
@@ -124,12 +124,14 @@
 	return (unsigned sz)value;						\
 }
 
-static inline unsigned int __ioaddr (unsigned int port)			\
-{										\
-	if (__PORT_PCIO(port))							\
-		return (unsigned int)(PCIO_BASE + (port << 2));			\
-	else									\
-		return (unsigned int)(IO_BASE + (port << 2));			\
+static inline void __iomem *__ioaddr(unsigned int port)
+{
+	void __iomem *ret;
+	if (__PORT_PCIO(port))
+		ret = (void __iomem *)PCIO_BASE;
+	else
+		ret = (void __iomem *)IO_BASE;
+	return ret + (port << 2);
 }
 
 #define DECLARE_IO(sz,fnsuffix,instr)	\
@@ -211,7 +213,7 @@
 	else									\
 		__asm__ __volatile__(						\
 		"str	%0, [%1, %2]	@ outlc"				\
-		: : "r" (__v), "r" (IO_BASE), "r" ((port) << 2));			\
+		: : "r" (__v), "r" (IO_BASE), "r" ((port) << 2));		\
 })
 
 #define __inlc(port)								\
@@ -229,7 +231,7 @@
 })
 
 #define __ioaddrc(port)								\
-	(__PORT_PCIO((port)) ? PCIO_BASE + ((port) << 2) : IO_BASE + ((port) << 2))
+	((void __iomem *)(__PORT_PCIO((port)) ? PCIO_BASE : IO_BASE) + ((port) << 2))
 
 #define inb(p)	 	(__builtin_constant_p((p)) ? __inbc(p)    : __inb(p))
 #define inw(p)	 	(__builtin_constant_p((p)) ? __inwc(p)    : __inw(p))
@@ -239,7 +241,7 @@
 #define outl(v,p)	(__builtin_constant_p((p)) ? __outlc(v,p) : __outl(v,p))
 #define __ioaddr(p)	(__builtin_constant_p((p)) ? __ioaddr(p)  : __ioaddrc(p))
 /* the following macro is deprecated */
-#define ioaddr(port)			__ioaddr((port))
+#define ioaddr(port)	((unsigned long)__ioaddr((port)))
 
 #define insb(p,d,l)	__raw_readsb(__ioaddr(p),d,l)
 #define insw(p,d,l)	__raw_readsw(__ioaddr(p),d,l)
diff -Nru a/include/asm-arm/arch-s3c2410/debug-macro.S b/include/asm-arm/arch-s3c2410/debug-macro.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-arm/arch-s3c2410/debug-macro.S	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,97 @@
+/* linux/include/asm-arm/arch-s3c2410/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ *  Copyright (C) 1994-1999 Russell King
+ *  Copyright (C) 2005 Simtec Electronics
+ *
+ *  Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+#include <asm/arch/map.h>
+#include <asm/arch/regs-serial.h>
+#include <asm/arch/regs-gpio.h>
+
+#define S3C2410_UART1_OFF (0x4000)
+#define SHIFT_2440TXF (14-9)
+
+		.macro addruart, rx
+		mrc	p15, 0, \rx, c1, c0
+		tst	\rx, #1
+		ldreq	\rx, = S3C2410_PA_UART
+		ldrne	\rx, = S3C2410_VA_UART
+#if CONFIG_DEBUG_S3C2410_UART != 0
+		add	\rx, \rx, #(S3C2410_UART1_OFF * CONFIG_DEBUG_S3C2410_UART)
+#endif
+		.endm
+
+		.macro	senduart,rd,rx
+		str	\rd, [\rx, # S3C2410_UTXH ]
+		.endm
+
+		.macro	busyuart, rd, rx
+		ldr	\rd, [ \rx, # S3C2410_UFCON ]
+		tst	\rd, #S3C2410_UFCON_FIFOMODE	@ fifo enabled?
+		beq	1001f				@
+		@ FIFO enabled...
+1003:
+		mrc	p15, 0, \rd, c1, c0
+		tst	\rd, #1
+		addeq	\rd, \rx, #(S3C2410_PA_GPIO - S3C2410_PA_UART)
+		addne	\rd, \rx, #(S3C2410_VA_GPIO - S3C2410_VA_UART)
+		bic	\rd, \rd, #0xff000
+		ldr	\rd, [ \rd, # S3C2410_GSTATUS1 - S3C2410_GPIOREG(0) ]
+		and	\rd, \rd, #0x00ff0000
+		teq	\rd, #0x00440000		@ is it 2440?
+
+		ldr	\rd, [ \rx, # S3C2410_UFSTAT ]
+		moveq	\rd, \rd, lsr #SHIFT_2440TXF
+		tst	\rd, #S3C2410_UFSTAT_TXFULL
+		bne	1003b
+		b	1002f
+
+1001:
+		@ busy waiting for non fifo
+		ldr	\rd, [ \rx, # S3C2410_UTRSTAT ]
+		tst	\rd, #S3C2410_UTRSTAT_TXFE
+		beq	1001b
+
+1002:		@ exit busyuart
+		.endm
+
+		.macro	waituart,rd,rx
+
+		ldr	\rd, [ \rx, # S3C2410_UFCON ]
+		tst	\rd, #S3C2410_UFCON_FIFOMODE	@ fifo enabled?
+		beq	1001f				@
+		@ FIFO enabled...
+1003:
+		mrc	p15, 0, \rd, c1, c0
+		tst	\rd, #1
+		addeq	\rd, \rx, #(S3C2410_PA_GPIO - S3C2410_PA_UART)
+		addne	\rd, \rx, #(S3C2410_VA_GPIO - S3C2410_VA_UART)
+		bic	\rd, \rd, #0xff000
+		ldr	\rd, [ \rd, # S3C2410_GSTATUS1 - S3C2410_GPIOREG(0) ]
+		and	\rd, \rd, #0x00ff0000
+		teq	\rd, #0x00440000		@ is it 2440?
+
+		ldr	\rd, [ \rx, # S3C2410_UFSTAT ]
+		andne	\rd, \rd, #S3C2410_UFSTAT_TXMASK
+		andeq	\rd, \rd, #S3C2440_UFSTAT_TXMASK
+		teq	\rd, #0
+		bne	1003b
+		b	1002f
+
+1001:
+		@ idle waiting for non fifo
+		ldr	\rd, [ \rx, # S3C2410_UTRSTAT ]
+		tst	\rd, #S3C2410_UTRSTAT_TXFE
+		beq	1001b
+
+1002:		@ exit busyuart
+		.endm
diff -Nru a/include/asm-arm/arch-s3c2410/dma.h b/include/asm-arm/arch-s3c2410/dma.h
--- a/include/asm-arm/arch-s3c2410/dma.h	2005-03-01 23:38:55 -08:00
+++ b/include/asm-arm/arch-s3c2410/dma.h	2005-03-01 23:38:55 -08:00
@@ -285,6 +285,14 @@
 extern int s3c2410_dma_devconfig(int channel, s3c2410_dmasrc_t source,
 				 int hwcfg, unsigned long devaddr);
 
+/* s3c2410_dma_getposition
+ *
+ * get the position that the dma transfer is currently at
+*/
+
+extern int s3c2410_dma_getposition(dmach_t channel,
+				   dma_addr_t *src, dma_addr_t *dest);
+
 extern int s3c2410_dma_set_opfn(dmach_t, s3c2410_dma_opfn_t rtn);
 extern int s3c2410_dma_set_buffdone_fn(dmach_t, s3c2410_dma_cbfn_t rtn);
 
diff -Nru a/include/asm-arm/arch-s3c2410/entry-macro.S b/include/asm-arm/arch-s3c2410/entry-macro.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-arm/arch-s3c2410/entry-macro.S	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,116 @@
+/*
+ * include/asm-arm/arch-s3c2410/entry-macro.S
+ *
+ * Low-level IRQ helper macros for S3C2410-based platforms
+ *
+ * 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.
+ */
+
+
+	.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+
+		mov	\tmp, #S3C2410_VA_IRQ
+		ldr	\irqnr, [ \tmp, #0x14 ]		@ get irq no
+30000:
+		teq	\irqnr, #4
+		teqne	\irqnr, #5
+		beq	1002f				@ external irq reg
+
+		@ debug check to see if interrupt reported is the same
+		@ as the offset....
+
+		teq	\irqnr, #0
+		beq	20002f
+		ldr	\irqstat, [ \tmp, #0x10 ]	@ INTPND
+		mov	\irqstat, \irqstat, lsr \irqnr
+		tst	\irqstat, #1
+		bne	20002f
+
+		/* debug/warning if we get an invalud response from the
+		 * INTOFFSET register */
+#if 1
+		stmfd	r13!, { r0 - r4 , r8-r12, r14 }
+		ldr	r1,	[ \tmp, #0x14 ]		@ INTOFFSET
+		ldr	r2,	[ \tmp, #0x10 ]		@ INTPND
+		ldr	r3,	[ \tmp, #0x00 ]		@ SRCPND
+		adr	r0, 20003f
+		bl	printk
+		b	20004f
+
+20003:
+		.ascii	"<7>irq: err - bad offset %d, intpnd=%08x, srcpnd=%08x\n"
+		.byte	0
+		.align	4
+20004:
+		mov	r1, #1
+		mov	\tmp, #S3C2410_VA_IRQ
+		ldmfd	r13!, { r0 - r4 , r8-r12, r14 }
+#endif
+
+		@ try working out interrupt number for ourselves
+		mov	\irqnr, #0
+		ldr	\irqstat, [ \tmp, #0x10 ]	@ INTPND
+10021:
+		movs	\irqstat, \irqstat, lsr#1
+		bcs	30000b		@ try and re-start the proccess
+		add	\irqnr, \irqnr, #1
+		cmp	\irqnr, #32
+		ble	10021b
+
+		@ found no interrupt, set Z flag and leave
+		movs	\irqnr, #0
+		b	1001f
+
+20005:
+20002:		@ exit
+		@ we base the s3c2410x interrupts at 16 and above to allow
+		@ isa peripherals to have their standard interrupts, also
+		@ ensure that Z flag is un-set on exit
+
+		@ note, we cannot be sure if we get IRQ_EINT0 (0) that
+		@ there is simply no interrupt pending, so in all other
+		@ cases we jump to say we have found something, otherwise
+		@ we check to see if the interrupt really is assrted
+		adds	\irqnr, \irqnr, #IRQ_EINT0
+		teq	\irqnr, #IRQ_EINT0
+		bne	1001f				@ exit
+		ldr	\irqstat, [ \tmp, #0x10 ]	@ INTPND
+		teq	\irqstat, #0
+		moveq	\irqnr, #0
+		b	1001f
+
+		@ we get here from no main or external interrupts pending
+1002:
+		add	\tmp, \tmp, #S3C2410_VA_GPIO - S3C2410_VA_IRQ
+		ldr	\irqstat, [ \tmp, # 0xa8 ]	@ EXTINTPEND
+		ldr	\irqnr, [ \tmp, # 0xa4 ]	@ EXTINTMASK
+
+		bic	\irqstat, \irqstat, \irqnr	@ clear masked irqs
+
+		mov	\irqnr, #IRQ_EINT4		@ start extint nos
+		mov	\irqstat, \irqstat, lsr#4	@ ignore bottom 4 bits
+10021:
+		movs	\irqstat, \irqstat, lsr#1
+		bcs	1004f
+		add	\irqnr, \irqnr, #1
+		cmp	\irqnr, #IRQ_EINT23
+		ble	10021b
+
+		@ found no interrupt, set Z flag and leave
+		movs	\irqnr, #0
+
+1004:		@ ensure Z flag clear in case our MOVS shifted out the last bit
+		teq	\irqnr, #0
+1001:
+		@ exit irq routine
+		.endm
+
+
+		/* currently don't need an disable_fiq macro */
+
+		.macro	disable_fiq
+		.endm
+
+
diff -Nru a/include/asm-arm/arch-s3c2410/io.h b/include/asm-arm/arch-s3c2410/io.h
--- a/include/asm-arm/arch-s3c2410/io.h	2005-03-01 23:39:09 -08:00
+++ b/include/asm-arm/arch-s3c2410/io.h	2005-03-01 23:39:09 -08:00
@@ -65,12 +65,9 @@
 	return (unsigned sz)value;					\
 }
 
-static inline unsigned int __ioaddr (unsigned int port)
+static inline void __iomem *__ioaddr (unsigned int port)
 {
-	if (__PORT_PCIO(port))
-		return (unsigned int)(PCIO_BASE + (port));
-	else
-		return (unsigned int)(0 + (port));
+	return (void __iomem *)(__PORT_PCIO(port) ? PCIO_BASE + port : port);
 }
 
 #define DECLARE_IO(sz,fnsuffix,instr)	\
@@ -170,7 +167,7 @@
 	result;								\
 })
 
-#define __ioaddrc(port)	(__PORT_PCIO((port)) ? PCIO_BASE + ((port)) : ((port)))
+#define __ioaddrc(port)	((void __iomem *)(__PORT_PCIO(port) ? PCIO_BASE + (port) : (port)))
 
 #define inb(p)		(__builtin_constant_p((p)) ? __inbc(p)	   : __inb(p))
 #define inw(p)		(__builtin_constant_p((p)) ? __inwc(p)	   : __inw(p))
diff -Nru a/include/asm-arm/arch-s3c2410/regs-clock.h b/include/asm-arm/arch-s3c2410/regs-clock.h
--- a/include/asm-arm/arch-s3c2410/regs-clock.h	2005-03-01 23:38:51 -08:00
+++ b/include/asm-arm/arch-s3c2410/regs-clock.h	2005-03-01 23:38:51 -08:00
@@ -15,6 +15,7 @@
  *    19-06-2003  Ben Dooks      Created file
  *    12-03-2004  Ben Dooks      Updated include protection
  *    29-Sep-2004 Ben Dooks	 Fixed usage for assembly inclusion
+ *    10-Feb-2005 Ben Dooks	 Fixed CAMDIVN address (Guillaume Gourat)
  */
 
 #ifndef __ASM_ARM_REGS_CLOCK
@@ -77,17 +78,17 @@
 static inline unsigned int
 s3c2410_get_pll(int pllval, int baseclk)
 {
-  int mdiv, pdiv, sdiv;
+	int mdiv, pdiv, sdiv;
 
-  mdiv = pllval >> S3C2410_PLLCON_MDIVSHIFT;
-  pdiv = pllval >> S3C2410_PLLCON_PDIVSHIFT;
-  sdiv = pllval >> S3C2410_PLLCON_SDIVSHIFT;
+	mdiv = pllval >> S3C2410_PLLCON_MDIVSHIFT;
+	pdiv = pllval >> S3C2410_PLLCON_PDIVSHIFT;
+	sdiv = pllval >> S3C2410_PLLCON_SDIVSHIFT;
 
-  mdiv &= S3C2410_PLLCON_MDIVMASK;
-  pdiv &= S3C2410_PLLCON_PDIVMASK;
-  sdiv &= S3C2410_PLLCON_SDIVMASK;
+	mdiv &= S3C2410_PLLCON_MDIVMASK;
+	pdiv &= S3C2410_PLLCON_PDIVMASK;
+	sdiv &= S3C2410_PLLCON_SDIVMASK;
 
-  return (baseclk * (mdiv + 8)) / ((pdiv + 2) << sdiv);
+	return (baseclk * (mdiv + 8)) / ((pdiv + 2) << sdiv);
 }
 
 #endif /* __ASSEMBLY__ */
@@ -95,7 +96,7 @@
 #ifdef CONFIG_CPU_S3C2440
 
 /* extra registers */
-#define S3C2440_CAMDIVN	    S3C2410_CLKREG(0x14)
+#define S3C2440_CAMDIVN	    S3C2410_CLKREG(0x18)
 
 #define S3C2440_CLKCON_CAMERA        (1<<19)
 #define S3C2440_CLKCON_AC97          (1<<20)
diff -Nru a/include/asm-arm/arch-s3c2410/regs-gpioj.h b/include/asm-arm/arch-s3c2410/regs-gpioj.h
--- a/include/asm-arm/arch-s3c2410/regs-gpioj.h	2005-03-01 23:39:09 -08:00
+++ b/include/asm-arm/arch-s3c2410/regs-gpioj.h	2005-03-01 23:39:09 -08:00
@@ -11,6 +11,7 @@
  *
  *  Changelog:
  *    11-Aug-2004     BJD     Created file
+ *    10-Feb-2005     BJD     Fix GPJ12 definition (Guillaume Gourat)
 */
 
 
@@ -94,7 +95,7 @@
 #define S3C2440_GPJ12           S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 12)
 #define S3C2440_GPJ12_INP       (0x00 << 24)
 #define S3C2440_GPJ12_OUTP      (0x01 << 24)
-#define S3C2440_GPJ12_CAMCLKOUT (0x02 << 24)
+#define S3C2440_GPJ12_CAMRESET  (0x02 << 24)
 
 #endif	/* __ASM_ARCH_REGS_GPIOJ_H */
 
diff -Nru 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	2005-03-01 23:38:54 -08:00
+++ b/include/asm-arm/arch-s3c2410/regs-iis.h	2005-03-01 23:38:54 -08:00
@@ -18,7 +18,7 @@
 #ifndef __ASM_ARCH_REGS_IIS_H
 #define __ASM_ARCH_REGS_IIS_H
 
-#define S3C2410_IISCON	 (S3C2410_VA_IIS + 0x00)
+#define S3C2410_IISCON	 (0x00)
 
 #define S3C2410_IISCON_LRINDEX	  (1<<8)
 #define S3C2410_IISCON_TXFIFORDY  (1<<7)
@@ -29,7 +29,7 @@
 #define S3C2410_IISCON_RXIDLE	  (1<<2)
 #define S3C2410_IISCON_IISEN	  (1<<0)
 
-#define S3C2410_IISMOD	 (S3C2410_VA_IIS + 0x04)
+#define S3C2410_IISMOD	 (0x04)
 
 #define S3C2410_IISMOD_SLAVE	  (1<<8)
 #define S3C2410_IISMOD_NOXFER	  (0<<6)
@@ -48,16 +48,20 @@
 #define S3C2410_IISMOD_32FS	  (1<<0)
 #define S3C2410_IISMOD_48FS	  (2<<0)
 
-#define S3C2410_IISPSR	 (S3C2410_VA_IIS + 0x08)
+#define S3C2410_IISPSR		(0x08)
+#define S3C2410_IISPSR_INTMASK	(31<<5)
+#define S3C2410_IISPSR_INTSHFIT	(5)
+#define S3C2410_IISPSR_EXTMASK	(31<<0)
+#define S3C2410_IISPSR_EXTSHFIT	(0)
 
-#define S3C2410_IISFCON  (S3C2410_VA_IIS + 0x0c)
+#define S3C2410_IISFCON  (0x0c)
 
 #define S3C2410_IISFCON_TXDMA	  (1<<15)
 #define S3C2410_IISFCON_RXDMA	  (1<<14)
 #define S3C2410_IISFCON_TXENABLE  (1<<13)
 #define S3C2410_IISFCON_RXENABLE  (1<<12)
 
-#define S3C2410_IISFIFO  (S3C2410_VA_IIS + 0x10)
+#define S3C2410_IISFIFO  (0x10)
 
 #endif /* __ASM_ARCH_REGS_IIS_H */
 
diff -Nru a/include/asm-arm/arch-s3c2410/regs-serial.h b/include/asm-arm/arch-s3c2410/regs-serial.h
--- a/include/asm-arm/arch-s3c2410/regs-serial.h	2005-03-01 23:38:58 -08:00
+++ b/include/asm-arm/arch-s3c2410/regs-serial.h	2005-03-01 23:38:58 -08:00
@@ -113,6 +113,9 @@
 				   S3C2410_UFCON_TXTRIG0  | \
 				   S3C2410_UFCON_RXTRIG8 )
 
+#define	S3C2410_UMCOM_AFC	  (1<<4)
+#define	S3C2410_UMCOM_RTS_LOW	  (1<<0)
+
 #define S3C2410_UFSTAT_TXFULL	  (1<<9)
 #define S3C2410_UFSTAT_RXFULL	  (1<<8)
 #define S3C2410_UFSTAT_TXMASK	  (15<<4)
diff -Nru a/include/asm-arm/arch-s3c2410/timex.h b/include/asm-arm/arch-s3c2410/timex.h
--- a/include/asm-arm/arch-s3c2410/timex.h	2005-03-01 23:39:09 -08:00
+++ b/include/asm-arm/arch-s3c2410/timex.h	2005-03-01 23:39:09 -08:00
@@ -1,6 +1,6 @@
 /* linux/include/asm-arm/arch-s3c2410/timex.h
  *
- * (c) 2003,2004 Simtec Electronics
+ * (c) 2003-2005 Simtec Electronics
  *  Ben Dooks <ben@simtec.co.uk>
  *
  * S3C2410 - time parameters
@@ -13,21 +13,19 @@
  *  02-Sep-2003 BJD  Created file
  *  05-Jan-2004 BJD  Updated for Linux 2.6.0
  *  22-Nov-2004 BJD  Fixed CLOCK_TICK_RATE
+ *  10-Jan-2004 BJD  Removed s3c2410_clock_tick_rate
 */
 
 #ifndef __ASM_ARCH_TIMEX_H
 #define __ASM_ARCH_TIMEX_H
 
-#if 0
-/* todo - this does not seem to work with 2.6.0 -> division by zero
- * in header files
- */
-extern int s3c2410_clock_tick_rate;
+/* CLOCK_TICK_RATE needs to be evaluatable by the cpp, so making it
+ * a variable is useless. It seems as long as we make our timers an
+ * exact multiple of HZ, any value that makes a 1->1 correspondence
+ * for the time conversion functions to/from jiffies is acceptable.
+*/
 
-#define CLOCK_TICK_RATE (s3c2410_clock_tick_rate)
-#endif
 
-/* currently, the BAST uses 12MHz as a base clock rate */
 #define CLOCK_TICK_RATE 12000000
 
 
diff -Nru a/include/asm-arm/arch-s3c2410/vr1000-map.h b/include/asm-arm/arch-s3c2410/vr1000-map.h
--- a/include/asm-arm/arch-s3c2410/vr1000-map.h	2005-03-01 23:39:16 -08:00
+++ b/include/asm-arm/arch-s3c2410/vr1000-map.h	2005-03-01 23:39:16 -08:00
@@ -1,6 +1,6 @@
 /* linux/include/asm-arm/arch-s3c2410/vr1000-map.h
  *
- * (c) 2003,2004 Simtec Electronics
+ * (c) 2003-2005 Simtec Electronics
  *  Ben Dooks <ben@simtec.co.uk>
  *
  * Machine VR1000 - Memory map definitions
@@ -13,6 +13,7 @@
  *  06-Jan-2003 BJD  Linux 2.6.0 version, split specifics from arch/map.h
  *  12-Mar-2004 BJD  Fixed header include protection
  *  19-Mar-2004 BJD  Copied to VR1000 machine headers.
+ *  19-Jan-2005 BJD  Updated map definitions
 */
 
 /* needs arch/map.h including with this */
@@ -94,7 +95,6 @@
 #define VR1000_VA_DM9000	   (VR1000_VA_MULTISPACE + 0x02500000)
 #define VR1000_VA_SUPERIO	   (VR1000_VA_MULTISPACE + 0x02600000)
 
-
 /* physical offset addresses for the peripherals */
 
 #define VR1000_PA_IDEPRI	   (0x02000000)
@@ -104,6 +104,10 @@
 #define VR1000_PA_DM9000	   (0x05000000)
 
 #define VR1000_PA_SERIAL	   (0x11800000)
+#define VR1000_VA_SERIAL	   (VR1000_IOADDR(0x00700000))
+
+/* VR1000 ram is in CS1, with A26..A24 = 2_101 */
+#define VR1000_PA_SRAM		   (S3C2410_CS1 | 0x05000000)
 
 /* some configurations for the peripherals */
 
diff -Nru a/include/asm-arm/arch-sa1100/collie.h b/include/asm-arm/arch-sa1100/collie.h
--- a/include/asm-arm/arch-sa1100/collie.h	2005-03-01 23:38:52 -08:00
+++ b/include/asm-arm/arch-sa1100/collie.h	2005-03-01 23:38:52 -08:00
@@ -15,57 +15,20 @@
 
 #include <linux/config.h>
 
-#define CF_BUF_CTRL_BASE 0xF0800000
-#define	COLLIE_SCP_REG(adr) (*(volatile unsigned short*)(CF_BUF_CTRL_BASE+(adr)))
-#define	COLLIE_SCP_MCR	0x00
-#define	COLLIE_SCP_CDR	0x04
-#define	COLLIE_SCP_CSR	0x08
-#define	COLLIE_SCP_CPR	0x0C
-#define	COLLIE_SCP_CCR	0x10
-#define	COLLIE_SCP_IRR	0x14
-#define	COLLIE_SCP_IRM	0x14
-#define	COLLIE_SCP_IMR	0x18
-#define	COLLIE_SCP_ISR	0x1C
-#define	COLLIE_SCP_GPCR	0x20
-#define	COLLIE_SCP_GPWR	0x24
-#define	COLLIE_SCP_GPRR	0x28
-#define	COLLIE_SCP_REG_MCR	COLLIE_SCP_REG(COLLIE_SCP_MCR)
-#define	COLLIE_SCP_REG_CDR	COLLIE_SCP_REG(COLLIE_SCP_CDR)
-#define	COLLIE_SCP_REG_CSR	COLLIE_SCP_REG(COLLIE_SCP_CSR)
-#define	COLLIE_SCP_REG_CPR	COLLIE_SCP_REG(COLLIE_SCP_CPR)
-#define	COLLIE_SCP_REG_CCR	COLLIE_SCP_REG(COLLIE_SCP_CCR)
-#define	COLLIE_SCP_REG_IRR	COLLIE_SCP_REG(COLLIE_SCP_IRR)
-#define	COLLIE_SCP_REG_IRM	COLLIE_SCP_REG(COLLIE_SCP_IRM)
-#define	COLLIE_SCP_REG_IMR	COLLIE_SCP_REG(COLLIE_SCP_IMR)
-#define	COLLIE_SCP_REG_ISR	COLLIE_SCP_REG(COLLIE_SCP_ISR)
-#define	COLLIE_SCP_REG_GPCR	COLLIE_SCP_REG(COLLIE_SCP_GPCR)
-#define	COLLIE_SCP_REG_GPWR	COLLIE_SCP_REG(COLLIE_SCP_GPWR)
-#define	COLLIE_SCP_REG_GPRR	COLLIE_SCP_REG(COLLIE_SCP_GPRR)
+#define COLLIE_SCP_CHARGE_ON	SCOOP_GPCR_PA11
+#define COLLIE_SCP_DIAG_BOOT1	SCOOP_GPCR_PA12
+#define COLLIE_SCP_DIAG_BOOT2	SCOOP_GPCR_PA13
+#define COLLIE_SCP_MUTE_L	SCOOP_GPCR_PA14
+#define COLLIE_SCP_MUTE_R	SCOOP_GPCR_PA15
+#define COLLIE_SCP_5VON		SCOOP_GPCR_PA16
+#define COLLIE_SCP_AMP_ON	SCOOP_GPCR_PA17
+#define COLLIE_SCP_VPEN		SCOOP_GPCR_PA18
+#define COLLIE_SCP_LB_VOL_CHG	SCOOP_GPCR_PA19
 
-#define COLLIE_SCP_GPCR_PA19	( 1 << 9 )
-#define COLLIE_SCP_GPCR_PA18	( 1 << 8 )
-#define COLLIE_SCP_GPCR_PA17	( 1 << 7 )
-#define COLLIE_SCP_GPCR_PA16	( 1 << 6 )
-#define COLLIE_SCP_GPCR_PA15	( 1 << 5 )
-#define COLLIE_SCP_GPCR_PA14	( 1 << 4 )
-#define COLLIE_SCP_GPCR_PA13	( 1 << 3 )
-#define COLLIE_SCP_GPCR_PA12	( 1 << 2 )
-#define COLLIE_SCP_GPCR_PA11	( 1 << 1 )
-
-#define COLLIE_SCP_CHARGE_ON	COLLIE_SCP_GPCR_PA11
-#define COLLIE_SCP_DIAG_BOOT1	COLLIE_SCP_GPCR_PA12
-#define COLLIE_SCP_DIAG_BOOT2	COLLIE_SCP_GPCR_PA13
-#define COLLIE_SCP_MUTE_L	COLLIE_SCP_GPCR_PA14
-#define COLLIE_SCP_MUTE_R	COLLIE_SCP_GPCR_PA15
-#define COLLIE_SCP_5VON	COLLIE_SCP_GPCR_PA16
-#define COLLIE_SCP_AMP_ON	COLLIE_SCP_GPCR_PA17
-#define COLLIE_SCP_VPEN	COLLIE_SCP_GPCR_PA18
-#define COLLIE_SCP_LB_VOL_CHG	COLLIE_SCP_GPCR_PA19
-
-#define COLLIE_SCP_IO_DIR	( COLLIE_SCP_CHARGE_ON | COLLIE_SCP_MUTE_L | COLLIE_SCP_MUTE_R | \
+#define COLLIE_SCOOP_IO_DIR	( COLLIE_SCP_CHARGE_ON | COLLIE_SCP_MUTE_L | COLLIE_SCP_MUTE_R | \
 				COLLIE_SCP_5VON | COLLIE_SCP_AMP_ON | COLLIE_SCP_VPEN | \
 				COLLIE_SCP_LB_VOL_CHG )
-#define COLLIE_SCP_IO_OUT	( COLLIE_SCP_MUTE_L | COLLIE_SCP_MUTE_R | COLLIE_SCP_VPEN | \
+#define COLLIE_SCOOP_IO_OUT	( COLLIE_SCP_MUTE_L | COLLIE_SCP_MUTE_R | COLLIE_SCP_VPEN | \
 				COLLIE_SCP_CHARGE_ON )
 
 /* GPIOs for which the generic definition doesn't say much */
diff -Nru a/include/asm-arm/arch-sa1100/debug-macro.S b/include/asm-arm/arch-sa1100/debug-macro.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-arm/arch-sa1100/debug-macro.S	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,57 @@
+/* linux/include/asm-arm/arch-sa1100/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ *  Copyright (C) 1994-1999 Russell King
+ *  Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+		.macro	addruart,rx
+		mrc	p15, 0, \rx, c1, c0
+		tst	\rx, #1			@ MMU enabled?
+		moveq	\rx, #0x80000000	@ physical base address
+		movne	\rx, #0xf8000000	@ virtual address
+
+		@ We probe for the active serial port here, coherently with
+		@ the comment in include/asm-arm/arch-sa1100/uncompress.h.
+		@ We assume r1 can be clobbered.
+
+		@ see if Ser3 is active
+		add	\rx, \rx, #0x00050000
+		ldr	r1, [\rx, #UTCR3]
+		tst	r1, #UTCR3_TXE
+
+		@ if Ser3 is inactive, then try Ser1
+		addeq	\rx, \rx, #(0x00010000 - 0x00050000)
+		ldreq	r1, [\rx, #UTCR3]
+		tsteq	r1, #UTCR3_TXE
+
+		@ if Ser1 is inactive, then try Ser2
+		addeq	\rx, \rx, #(0x00030000 - 0x00010000)
+		ldreq	r1, [\rx, #UTCR3]
+		tsteq	r1, #UTCR3_TXE
+
+		@ if all ports are inactive, then there is nothing we can do
+		moveq	pc, lr
+		.endm
+
+		.macro	senduart,rd,rx
+		str	\rd, [\rx, #UTDR]
+		.endm
+
+		.macro	waituart,rd,rx
+1001:		ldr	\rd, [\rx, #UTSR1]
+		tst	\rd, #UTSR1_TNF
+		beq	1001b
+		.endm
+
+		.macro	busyuart,rd,rx
+1001:		ldr	\rd, [\rx, #UTSR1]
+		tst	\rd, #UTSR1_TBY
+		bne	1001b
+		.endm
diff -Nru a/include/asm-arm/arch-sa1100/entry-macro.S b/include/asm-arm/arch-sa1100/entry-macro.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-arm/arch-sa1100/entry-macro.S	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,41 @@
+/*
+ * include/asm-arm/arch-sa1100/entry-macro.S
+ *
+ * Low-level IRQ helper macros for SA1100-based platforms
+ *
+ * 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.
+ */
+
+ 		.macro	disable_fiq
+		.endm
+
+		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+		mov	r4, #0xfa000000			@ ICIP = 0xfa050000
+		add	r4, r4, #0x00050000
+		ldr	\irqstat, [r4]			@ get irqs
+		ldr	\irqnr, [r4, #4]		@ ICMR = 0xfa050004
+		ands	\irqstat, \irqstat, \irqnr
+		mov	\irqnr, #0
+		beq	1001f
+		tst	\irqstat, #0xff
+		moveq	\irqstat, \irqstat, lsr #8
+		addeq	\irqnr, \irqnr, #8
+		tsteq	\irqstat, #0xff
+		moveq	\irqstat, \irqstat, lsr #8
+		addeq	\irqnr, \irqnr, #8
+		tsteq	\irqstat, #0xff
+		moveq	\irqstat, \irqstat, lsr #8
+		addeq	\irqnr, \irqnr, #8
+		tst	\irqstat, #0x0f
+		moveq	\irqstat, \irqstat, lsr #4
+		addeq	\irqnr, \irqnr, #4
+		tst	\irqstat, #0x03
+		moveq	\irqstat, \irqstat, lsr #2
+		addeq	\irqnr, \irqnr, #2
+		tst	\irqstat, #0x01
+		addeqs	\irqnr, \irqnr, #1
+1001:
+		.endm
+
diff -Nru a/include/asm-arm/arch-shark/debug-macro.S b/include/asm-arm/arch-shark/debug-macro.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-arm/arch-shark/debug-macro.S	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,31 @@
+/* linux/include/asm-arm/arch-shark/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ *  Copyright (C) 1994-1999 Russell King
+ *  Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+		.macro	addruart,rx
+		mov	\rx, #0xe0000000
+		orr	\rx, \rx, #0x000003f8
+		.endm
+
+		.macro	senduart,rd,rx
+		strb	\rd, [\rx]
+		.endm
+
+		.macro	busyuart,rd,rx
+		mov	\rd, #0
+1001:		add	\rd, \rd, #1
+		teq	\rd, #0x10000
+		bne	1001b
+		.endm
+
+		.macro	waituart,rd,rx
+		.endm
diff -Nru a/include/asm-arm/arch-shark/entry-macro.S b/include/asm-arm/arch-shark/entry-macro.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-arm/arch-shark/entry-macro.S	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,35 @@
+/*
+ * include/asm-arm/arch-shark/entry-macro.S
+ *
+ * Low-level IRQ helper macros for Shark platform
+ *
+ * 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.
+ */
+		.macro	disable_fiq
+		.endm
+
+		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+		mov	r4, #0xe0000000
+
+		mov	\irqstat, #0x0C
+		strb	\irqstat, [r4, #0x20]		@outb(0x0C, 0x20) /* Poll command */
+		ldrb	\irqnr, [r4, #0x20]		@irq = inb(0x20) & 7
+		and	\irqstat, \irqnr, #0x80
+		teq	\irqstat, #0
+		beq	43f
+		and	\irqnr, \irqnr, #7
+		teq	\irqnr, #2
+		bne	44f
+43:		mov	\irqstat, #0x0C
+		strb	\irqstat, [r4, #0xa0]		@outb(0x0C, 0xA0) /* Poll command */
+		ldrb	\irqnr, [r4, #0xa0]		@irq = (inb(0xA0) & 7) + 8
+		and	\irqstat, \irqnr, #0x80
+		teq	\irqstat, #0
+		beq	44f
+		and	\irqnr, \irqnr, #7
+		add	\irqnr, \irqnr, #8
+44:		teq	\irqstat, #0
+		.endm
+
diff -Nru a/include/asm-arm/arch-versatile/debug-macro.S b/include/asm-arm/arch-versatile/debug-macro.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-arm/arch-versatile/debug-macro.S	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,39 @@
+/* linux/include/asm-arm/arch-versatile/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ *  Copyright (C) 1994-1999 Russell King
+ *  Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+#include <asm/hardware/amba_serial.h>
+
+		.macro	addruart,rx
+		mrc	p15, 0, \rx, c1, c0
+		tst	\rx, #1			@ MMU enabled?
+		moveq	\rx,      #0x10000000
+		movne	\rx,      #0xf1000000	@ virtual base
+		orr	\rx, \rx, #0x001F0000
+		orr	\rx, \rx, #0x00001000
+		.endm
+
+		.macro	senduart,rd,rx
+		strb	\rd, [\rx, #UART01x_DR]
+		.endm
+
+		.macro	waituart,rd,rx
+1001:		ldr	\rd, [\rx, #0x18]	@ UARTFLG
+		tst	\rd, #1 << 5		@ UARTFLGUTXFF - 1 when full
+		bne	1001b
+		.endm
+
+		.macro	busyuart,rd,rx
+1001:		ldr	\rd, [\rx, #0x18]	@ UARTFLG
+		tst	\rd, #1 << 3		@ UARTFLGUBUSY - 1 when busy
+		bne	1001b
+		.endm
diff -Nru a/include/asm-arm/arch-versatile/entry-macro.S b/include/asm-arm/arch-versatile/entry-macro.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-arm/arch-versatile/entry-macro.S	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,35 @@
+/*
+ * include/asm-arm/arch-versatile/entry-macro.S
+ *
+ * Low-level IRQ helper macros for Versatile platforms
+ *
+ * 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.
+ */
+			.macro	disable_fiq
+		.endm
+
+		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+		ldr	\base, =IO_ADDRESS(VERSATILE_VIC_BASE)
+		ldr	\irqstat, [\base, #VIC_IRQ_STATUS]	@ get masked status
+		mov	\irqnr, #0
+		teq	\irqstat, #0
+		beq	1003f
+
+1001:		tst	\irqstat, #15
+		bne	1002f
+		add	\irqnr, \irqnr, #4
+		movs	\irqstat, \irqstat, lsr #4
+		bne	1001b
+1002:		tst	\irqstat, #1
+		bne	1003f
+		add	\irqnr, \irqnr, #1
+		movs	\irqstat, \irqstat, lsr #1
+		bne	1002b
+1003:		/* EQ will be set if no irqs pending */
+
+@		clz	\irqnr, \irqstat
+@1003:		/* EQ will be set if we reach MAXIRQNUM */
+		.endm
+
diff -Nru a/include/asm-arm/bitops.h b/include/asm-arm/bitops.h
--- a/include/asm-arm/bitops.h	2005-03-01 23:38:51 -08:00
+++ b/include/asm-arm/bitops.h	2005-03-01 23:38:51 -08:00
@@ -210,8 +210,8 @@
 extern int _test_and_set_bit_le(int nr, volatile unsigned long * p);
 extern int _test_and_clear_bit_le(int nr, volatile unsigned long * p);
 extern int _test_and_change_bit_le(int nr, volatile unsigned long * p);
-extern int _find_first_zero_bit_le(void * p, unsigned size);
-extern int _find_next_zero_bit_le(void * p, int size, int offset);
+extern int _find_first_zero_bit_le(const void * p, unsigned size);
+extern int _find_next_zero_bit_le(const void * p, int size, int offset);
 extern int _find_first_bit_le(const unsigned long *p, unsigned size);
 extern int _find_next_bit_le(const unsigned long *p, int size, int offset);
 
@@ -224,8 +224,8 @@
 extern int _test_and_set_bit_be(int nr, volatile unsigned long * p);
 extern int _test_and_clear_bit_be(int nr, volatile unsigned long * p);
 extern int _test_and_change_bit_be(int nr, volatile unsigned long * p);
-extern int _find_first_zero_bit_be(void * p, unsigned size);
-extern int _find_next_zero_bit_be(void * p, int size, int offset);
+extern int _find_first_zero_bit_be(const void * p, unsigned size);
+extern int _find_next_zero_bit_be(const void * p, int size, int offset);
 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);
 
@@ -356,7 +356,7 @@
  * Find first bit set in a 168-bit bitmap, where the first
  * 128 bits are unlikely to be set.
  */
-static inline int sched_find_first_bit(unsigned long *b)
+static inline int sched_find_first_bit(const unsigned long *b)
 {
 	unsigned long v;
 	unsigned int off;
diff -Nru a/include/asm-arm/cpu.h b/include/asm-arm/cpu.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-arm/cpu.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,25 @@
+/*
+ *  linux/include/asm-arm/cpu.h
+ *
+ *  Copyright (C) 2004-2005 ARM Ltd.
+ *
+ * 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_ARM_CPU_H
+#define __ASM_ARM_CPU_H
+
+#include <linux/config.h>
+#include <linux/percpu.h>
+
+struct cpuinfo_arm {
+	struct cpu	cpu;
+#ifdef CONFIG_SMP
+	unsigned int	loops_per_jiffy;
+#endif
+};
+
+DECLARE_PER_CPU(struct cpuinfo_arm, cpu_data);
+
+#endif
diff -Nru a/include/asm-arm/cputime.h b/include/asm-arm/cputime.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-arm/cputime.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,6 @@
+#ifndef __ARM_CPUTIME_H
+#define __ARM_CPUTIME_H
+
+#include <asm-generic/cputime.h>
+
+#endif /* __ARM_CPUTIME_H */
diff -Nru a/include/asm-arm/dma-mapping.h b/include/asm-arm/dma-mapping.h
--- a/include/asm-arm/dma-mapping.h	2005-03-01 23:38:51 -08:00
+++ b/include/asm-arm/dma-mapping.h	2005-03-01 23:38:51 -08:00
@@ -87,6 +87,22 @@
 		  dma_addr_t handle);
 
 /**
+ * dma_mmap_coherent - map a coherent DMA allocation into user space
+ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
+ * @vma: vm_area_struct describing requested user mapping
+ * @cpu_addr: kernel CPU-view address returned from dma_alloc_coherent
+ * @handle: device-view address returned from dma_alloc_coherent
+ * @size: size of memory originally requested in dma_alloc_coherent
+ *
+ * Map a coherent DMA buffer previously allocated by dma_alloc_coherent
+ * into user space.  The coherent DMA buffer must not be freed by the
+ * driver until the user space mapping has been released.
+ */
+int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+		      void *cpu_addr, dma_addr_t handle, size_t size);
+
+
+/**
  * dma_alloc_writecombine - allocate writecombining memory for DMA
  * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
  * @size: required memory size
@@ -102,6 +118,9 @@
 
 #define dma_free_writecombine(dev,size,cpu_addr,handle) \
 	dma_free_coherent(dev,size,cpu_addr,handle)
+
+int dma_mmap_writecombine(struct device *dev, struct vm_area_struct *vma,
+			  void *cpu_addr, dma_addr_t handle, size_t size);
 
 
 /**
diff -Nru a/include/asm-arm/domain.h b/include/asm-arm/domain.h
--- a/include/asm-arm/domain.h	2005-03-01 23:39:08 -08:00
+++ b/include/asm-arm/domain.h	2005-03-01 23:39:08 -08:00
@@ -14,12 +14,12 @@
  * Domain numbers
  *
  *  DOMAIN_IO     - domain 2 includes all IO only
- *  DOMAIN_KERNEL - domain 1 includes all kernel memory only
- *  DOMAIN_USER   - domain 0 includes all user memory only
+ *  DOMAIN_USER   - domain 1 includes all user memory only
+ *  DOMAIN_KERNEL - domain 0 includes all kernel memory only
  */
-#define DOMAIN_USER	0
-#define DOMAIN_KERNEL	1
-#define DOMAIN_TABLE	1
+#define DOMAIN_KERNEL	0
+#define DOMAIN_TABLE	0
+#define DOMAIN_USER	1
 #define DOMAIN_IO	2
 
 /*
@@ -29,8 +29,9 @@
 #define DOMAIN_CLIENT	1
 #define DOMAIN_MANAGER	3
 
-#define domain_val(dom,type)	((type) << 2*(dom))
+#define domain_val(dom,type)	((type) << (2*(dom)))
 
+#ifndef __ASSEMBLY__
 #define set_domain(x)					\
 	do {						\
 	__asm__ __volatile__(				\
@@ -48,3 +49,4 @@
 	} while (0)
 
 #endif
+#endif /* !__ASSEMBLY__ */
diff -Nru a/include/asm-arm/elf.h b/include/asm-arm/elf.h
--- a/include/asm-arm/elf.h	2005-03-01 23:39:16 -08:00
+++ b/include/asm-arm/elf.h	2005-03-01 23:39:16 -08:00
@@ -17,6 +17,7 @@
 #define EM_ARM	40
 #define EF_ARM_APCS26 0x08
 #define EF_ARM_SOFT_FLOAT 0x200
+#define EF_ARM_EABI_MASK 0xFF000000
 
 #define R_ARM_NONE	0
 #define R_ARM_PC24	1
@@ -120,7 +121,8 @@
 #define SET_PERSONALITY(ex,ibcs2) \
 do { \
 	set_personality(PER_LINUX_32BIT); \
-	if ((ex).e_flags & EF_ARM_SOFT_FLOAT) \
+	if (((ex).e_flags & EF_ARM_EABI_MASK) || \
+	    ((ex).e_flags & EF_ARM_SOFT_FLOAT)) \
 		set_thread_flag(TIF_USING_IWMMXT); \
 } while (0)
 
diff -Nru a/include/asm-arm/hardirq.h b/include/asm-arm/hardirq.h
--- a/include/asm-arm/hardirq.h	2005-03-01 23:38:58 -08:00
+++ b/include/asm-arm/hardirq.h	2005-03-01 23:38:58 -08:00
@@ -27,16 +27,6 @@
 # error HARDIRQ_BITS is too low!
 #endif
 
-#define irq_enter()		(preempt_count() += HARDIRQ_OFFSET)
-
-extern asmlinkage void __do_softirq(void);
-
-#define irq_exit()							\
-	do {								\
-		preempt_count() -= IRQ_EXIT_OFFSET;			\
-		if (!in_interrupt() && local_softirq_pending())		\
-			__do_softirq();					\
-		preempt_enable_no_resched();				\
-	} while (0)
+#define __ARCH_IRQ_EXIT_IRQS_DISABLED	1
 
 #endif /* __ASM_HARDIRQ_H */
diff -Nru a/include/asm-arm/hardware/amba_clcd.h b/include/asm-arm/hardware/amba_clcd.h
--- a/include/asm-arm/hardware/amba_clcd.h	2005-03-01 23:38:56 -08:00
+++ b/include/asm-arm/hardware/amba_clcd.h	2005-03-01 23:38:56 -08:00
@@ -125,6 +125,11 @@
 	int	(*setup)(struct clcd_fb *);
 
 	/*
+	 * mmap the framebuffer memory
+	 */
+	int	(*mmap)(struct clcd_fb *, struct vm_area_struct *);
+
+	/*
 	 * Remove platform specific parts of CLCD driver
 	 */
 	void	(*remove)(struct clcd_fb *);
diff -Nru a/include/asm-arm/hardware/entry-macro-iomd.S b/include/asm-arm/hardware/entry-macro-iomd.S
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-arm/hardware/entry-macro-iomd.S	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,145 @@
+/*
+ * arch/arm/commond/entry-macro-iomd.S
+ *
+ * Low-level IRQ helper macros for IOC/IOMD based platforms
+ *
+ * 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.
+ */
+
+/* IOC / IOMD based hardware */
+#include <asm/hardware/iomd.h>
+
+		.equ	ioc_base_high, IOC_BASE & 0xff000000
+		.equ	ioc_base_low, IOC_BASE & 0x00ff0000
+		.macro	disable_fiq
+		mov	r12, #ioc_base_high
+		.if	ioc_base_low
+		orr	r12, r12, #ioc_base_low
+		.endif
+		strb	r12, [r12, #0x38]	@ Disable FIQ register
+		.endm
+
+		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+		mov	r4, #ioc_base_high		@ point at IOC
+		.if	ioc_base_low
+		orr	r4, r4, #ioc_base_low
+		.endif
+		ldrb	\irqstat, [r4, #IOMD_IRQREQB]	@ get high priority first
+		ldr	\base, =irq_prio_h
+		teq	\irqstat, #0
+#ifdef IOMD_BASE
+		ldreqb	\irqstat, [r4, #IOMD_DMAREQ]	@ get dma
+		addeq	\base, \base, #256		@ irq_prio_h table size
+		teqeq	\irqstat, #0
+		bne	2406f
+#endif
+		ldreqb	\irqstat, [r4, #IOMD_IRQREQA]	@ get low priority
+		addeq	\base, \base, #256		@ irq_prio_d table size
+		teqeq	\irqstat, #0
+#ifdef IOMD_IRQREQC
+		ldreqb	\irqstat, [r4, #IOMD_IRQREQC]
+		addeq	\base, \base, #256		@ irq_prio_l table size
+		teqeq	\irqstat, #0
+#endif
+#ifdef IOMD_IRQREQD
+		ldreqb	\irqstat, [r4, #IOMD_IRQREQD]
+		addeq	\base, \base, #256		@ irq_prio_lc table size
+		teqeq	\irqstat, #0
+#endif
+2406:		ldrneb	\irqnr, [\base, \irqstat]	@ get IRQ number
+		.endm
+
+/*
+ * Interrupt table (incorporates priority).  Please note that we
+ * rely on the order of these tables (see above code).
+ */
+		.align	5
+irq_prio_h:	.byte	 0, 8, 9, 8,10,10,10,10,11,11,11,11,10,10,10,10
+		.byte	12, 8, 9, 8,10,10,10,10,11,11,11,11,10,10,10,10
+		.byte	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
+		.byte	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
+		.byte	14,14,14,14,10,10,10,10,11,11,11,11,10,10,10,10
+		.byte	14,14,14,14,10,10,10,10,11,11,11,11,10,10,10,10
+		.byte	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
+		.byte	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
+		.byte	15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
+		.byte	15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
+		.byte	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
+		.byte	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
+		.byte	15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
+		.byte	15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
+		.byte	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
+		.byte	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
+#ifdef IOMD_BASE
+irq_prio_d:	.byte	 0,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
+		.byte	20,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
+		.byte	21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
+		.byte	21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
+		.byte	22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
+		.byte	22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
+		.byte	21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
+		.byte	21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
+		.byte	23,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
+		.byte	23,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
+		.byte	21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
+		.byte	21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
+		.byte	22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
+		.byte	22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
+		.byte	21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
+		.byte	21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
+#endif
+irq_prio_l:	.byte	 0, 0, 1, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3
+		.byte	 4, 0, 1, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3
+		.byte	 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
+		.byte	 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
+		.byte	 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3
+		.byte	 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3
+		.byte	 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
+		.byte	 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
+		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
+		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
+		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
+		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
+		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
+		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
+		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
+		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
+#ifdef IOMD_IRQREQC
+irq_prio_lc:	.byte	24,24,25,24,26,26,26,26,27,27,27,27,27,27,27,27
+		.byte	28,24,25,24,26,26,26,26,27,27,27,27,27,27,27,27
+		.byte	29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29
+		.byte	29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29
+		.byte	30,30,30,30,30,30,30,30,27,27,27,27,27,27,27,27
+		.byte	30,30,30,30,30,30,30,30,27,27,27,27,27,27,27,27
+		.byte	29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29
+		.byte	29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29
+		.byte	31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
+		.byte	31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
+		.byte	31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
+		.byte	31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
+		.byte	31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
+		.byte	31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
+		.byte	31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
+		.byte	31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
+#endif
+#ifdef IOMD_IRQREQD
+irq_prio_ld:	.byte	40,40,41,40,42,42,42,42,43,43,43,43,43,43,43,43
+		.byte	44,40,41,40,42,42,42,42,43,43,43,43,43,43,43,43
+		.byte	45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45
+		.byte	45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45
+		.byte	46,46,46,46,46,46,46,46,43,43,43,43,43,43,43,43
+		.byte	46,46,46,46,46,46,46,46,43,43,43,43,43,43,43,43
+		.byte	45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45
+		.byte	45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45
+		.byte	47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
+		.byte	47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
+		.byte	47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
+		.byte	47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
+		.byte	47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
+		.byte	47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
+		.byte	47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
+		.byte	47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
+#endif
+
diff -Nru a/include/asm-arm/hardware/sa1111.h b/include/asm-arm/hardware/sa1111.h
--- a/include/asm-arm/hardware/sa1111.h	2005-03-01 23:39:17 -08:00
+++ b/include/asm-arm/hardware/sa1111.h	2005-03-01 23:39:17 -08:00
@@ -49,8 +49,8 @@
  */
 #define __CCREG(x)	__REGP(SA1111_VBASE + (x))
 
-#define sa1111_writel(val,addr)	({ *(volatile unsigned int *)(addr) = (val); })
-#define sa1111_readl(addr)	(*(volatile unsigned int *)(addr))
+#define sa1111_writel(val,addr)	__raw_writel(val, addr)
+#define sa1111_readl(addr)	__raw_readl(addr)
 
 /*
  * System Bus Interface (SBI)
@@ -551,7 +551,7 @@
 	struct device	dev;
 	unsigned int	devid;
 	struct resource	res;
-	void		*mapbase;
+	void __iomem	*mapbase;
 	unsigned int	skpcr_mask;
 	unsigned int	irq[6];
 	u64		dma_mask;
diff -Nru a/include/asm-arm/hardware/scoop.h b/include/asm-arm/hardware/scoop.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-arm/hardware/scoop.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,47 @@
+/*
+ *  Definitions for the SCOOP interface found on various Sharp PDAs
+ *
+ *  Copyright (c) 2004 Richard Purdie
+ *
+ *  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 SCOOP_MCR  0x00
+#define SCOOP_CDR  0x04
+#define SCOOP_CSR  0x08
+#define SCOOP_CPR  0x0C
+#define SCOOP_CCR  0x10
+#define SCOOP_IRR  0x14
+#define SCOOP_IRM  0x14
+#define SCOOP_IMR  0x18
+#define SCOOP_ISR  0x1C
+#define SCOOP_GPCR 0x20
+#define SCOOP_GPWR 0x24
+#define SCOOP_GPRR 0x28
+
+#define SCOOP_GPCR_PA22	( 1 << 12 )
+#define SCOOP_GPCR_PA21	( 1 << 11 )
+#define SCOOP_GPCR_PA20	( 1 << 10 )
+#define SCOOP_GPCR_PA19	( 1 << 9 )
+#define SCOOP_GPCR_PA18	( 1 << 8 )
+#define SCOOP_GPCR_PA17	( 1 << 7 )
+#define SCOOP_GPCR_PA16	( 1 << 6 )
+#define SCOOP_GPCR_PA15	( 1 << 5 )
+#define SCOOP_GPCR_PA14	( 1 << 4 )
+#define SCOOP_GPCR_PA13	( 1 << 3 )
+#define SCOOP_GPCR_PA12	( 1 << 2 )
+#define SCOOP_GPCR_PA11	( 1 << 1 )
+
+struct scoop_config {
+	unsigned short io_out;
+	unsigned short io_dir;
+};
+
+void reset_scoop(void);
+unsigned short set_scoop_gpio(unsigned short bit);
+unsigned short reset_scoop_gpio(unsigned short bit);
+unsigned short read_scoop_reg(unsigned short reg);
+void write_scoop_reg(unsigned short reg, unsigned short data);
diff -Nru a/include/asm-arm/mach/irq.h b/include/asm-arm/mach/irq.h
--- a/include/asm-arm/mach/irq.h	2005-03-01 23:38:54 -08:00
+++ b/include/asm-arm/mach/irq.h	2005-03-01 23:38:54 -08:00
@@ -47,6 +47,13 @@
 	 * Set wakeup-enable on the selected IRQ
 	 */
 	int (*wake)(unsigned int, unsigned int);
+
+#ifdef CONFIG_SMP
+	/*
+	 * Route an interrupt to a CPU
+	 */
+	void (*set_cpu)(struct irqdesc *desc, unsigned int irq, unsigned int cpu);
+#endif
 };
 
 struct irqdesc {
@@ -66,6 +73,13 @@
 	unsigned int	valid    : 1;		/* IRQ claimable	      */
 	unsigned int	noautoenable : 1;	/* don't automatically enable IRQ */
 	unsigned int	unused   :25;
+
+	struct proc_dir_entry *procdir;
+
+#ifdef CONFIG_SMP
+	cpumask_t	affinity;
+	unsigned int	cpu;
+#endif
 
 	/*
 	 * IRQ lock detection
diff -Nru a/include/asm-arm/numnodes.h b/include/asm-arm/numnodes.h
--- a/include/asm-arm/numnodes.h	2005-03-01 23:38:55 -08:00
+++ b/include/asm-arm/numnodes.h	2005-03-01 23:38:55 -08:00
@@ -7,12 +7,17 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
+
+/* This declaration for the size of the NUMA (CONFIG_DISCONTIGMEM)
+ * memory node table is the default.
+ *
+ * A good place to override this value is include/asm/arch/memory.h.
+ */
+
 #ifndef __ASM_ARM_NUMNODES_H
 #define __ASM_ARM_NUMNODES_H
 
-#ifdef CONFIG_ARCH_LH7A40X
-# define NODES_SHIFT	4	/* Max 16 nodes for the Sharp CPUs */
-#else
+#ifndef NODES_SHIFT
 # define NODES_SHIFT	2	/* Normally, Max 4 Nodes */
 #endif
 
diff -Nru a/include/asm-arm/pgalloc.h b/include/asm-arm/pgalloc.h
--- a/include/asm-arm/pgalloc.h	2005-03-01 23:39:16 -08:00
+++ b/include/asm-arm/pgalloc.h	2005-03-01 23:39:16 -08:00
@@ -50,9 +50,8 @@
 {
 	pte_t *pte;
 
-	pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT);
+	pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO);
 	if (pte) {
-		clear_page(pte);
 		clean_dcache_area(pte, sizeof(pte_t) * PTRS_PER_PTE);
 		pte += PTRS_PER_PTE;
 	}
@@ -65,10 +64,9 @@
 {
 	struct page *pte;
 
-	pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT, 0);
+	pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0);
 	if (pte) {
 		void *page = page_address(pte);
-		clear_page(page);
 		clean_dcache_area(page, sizeof(pte_t) * PTRS_PER_PTE);
 	}
 
diff -Nru a/include/asm-arm/pgtable.h b/include/asm-arm/pgtable.h
--- a/include/asm-arm/pgtable.h	2005-03-01 23:38:54 -08:00
+++ b/include/asm-arm/pgtable.h	2005-03-01 23:38:54 -08:00
@@ -10,6 +10,8 @@
 #ifndef _ASMARM_PGTABLE_H
 #define _ASMARM_PGTABLE_H
 
+#include <asm-generic/4level-fixup.h>
+
 #include <asm/memory.h>
 #include <asm/proc-fns.h>
 #include <asm/arch/vmalloc.h>
@@ -80,7 +82,7 @@
  * PMD_SHIFT determines the size of the area a second-level page table can map
  * PGDIR_SHIFT determines what a third-level page table entry can map
  */
-#define PMD_SHIFT		20
+#define PMD_SHIFT		21
 #define PGDIR_SHIFT		21
 
 #define LIBRARY_TEXT_START	0x0c000000
@@ -308,7 +310,7 @@
 
 #define set_pmd(pmdp,pmd)		\
 	do {				\
-		*pmdp = pmd;		\
+		*(pmdp) = pmd;		\
 		flush_pmd_entry(pmdp);	\
 	} while (0)
 
diff -Nru a/include/asm-arm/processor.h b/include/asm-arm/processor.h
--- a/include/asm-arm/processor.h	2005-03-01 23:39:18 -08:00
+++ b/include/asm-arm/processor.h	2005-03-01 23:39:18 -08:00
@@ -19,10 +19,6 @@
 
 #ifdef __KERNEL__
 
-#define MCA_bus 0
-#define MCA_bus__is_a_macro
-
-#include <asm/atomic.h>
 #include <asm/ptrace.h>
 #include <asm/procinfo.h>
 #include <asm/types.h>
diff -Nru a/include/asm-arm/ptrace.h b/include/asm-arm/ptrace.h
--- a/include/asm-arm/ptrace.h	2005-03-01 23:38:58 -08:00
+++ b/include/asm-arm/ptrace.h	2005-03-01 23:38:58 -08:00
@@ -19,6 +19,7 @@
 
 #define PTRACE_OLDSETOPTIONS	21
 
+#define PTRACE_GET_THREAD_AREA	22
 /*
  * PSR bits
  */
diff -Nru a/include/asm-arm/resource.h b/include/asm-arm/resource.h
--- a/include/asm-arm/resource.h	2005-03-01 23:39:09 -08:00
+++ b/include/asm-arm/resource.h	2005-03-01 23:39:09 -08:00
@@ -1,51 +1,6 @@
 #ifndef _ARM_RESOURCE_H
 #define _ARM_RESOURCE_H
 
-/*
- * Resource limits
- */
-
-#define RLIMIT_CPU	0		/* CPU time in ms */
-#define RLIMIT_FSIZE	1		/* Maximum filesize */
-#define RLIMIT_DATA	2		/* max data size */
-#define RLIMIT_STACK	3		/* max stack size */
-#define RLIMIT_CORE	4		/* max core file size */
-#define RLIMIT_RSS	5		/* max resident set size */
-#define RLIMIT_NPROC	6		/* max number of processes */
-#define RLIMIT_NOFILE	7		/* max number of open files */
-#define RLIMIT_MEMLOCK	8		/* max locked-in-memory address space */
-#define RLIMIT_AS	9		/* address space limit */
-#define RLIMIT_LOCKS	10		/* maximum file locks held */
-#define RLIMIT_SIGPENDING 11		/* max number of pending signals */
-#define RLIMIT_MSGQUEUE 12		/* maximum bytes in POSIX mqueues */
-
-#define RLIM_NLIMITS	13
-
-#ifdef __KERNEL__
-
-/*
- * SuS says limits have to be unsigned.
- * Which makes a ton more sense anyway.
- */
-#define RLIM_INFINITY	(~0UL)
-
-#define INIT_RLIMITS				\
-{						\
-	{ RLIM_INFINITY, RLIM_INFINITY },	\
-	{ RLIM_INFINITY, RLIM_INFINITY },	\
-	{ RLIM_INFINITY, RLIM_INFINITY },	\
-	{ _STK_LIM,      RLIM_INFINITY },	\
-	{ 0,             RLIM_INFINITY },	\
-	{ RLIM_INFINITY, RLIM_INFINITY },	\
-	{ 0,             0             },	\
-	{ INR_OPEN,      INR_OPEN      },	\
-	{ MLOCK_LIMIT,	 MLOCK_LIMIT   },	\
-	{ RLIM_INFINITY, RLIM_INFINITY },	\
-	{ RLIM_INFINITY, RLIM_INFINITY },	\
-	{ MAX_SIGPENDING, MAX_SIGPENDING},	\
-	{ MQ_BYTES_MAX, MQ_BYTES_MAX},		\
-}
-
-#endif /* __KERNEL__ */
+#include <asm-generic/resource.h>
 
 #endif
diff -Nru a/include/asm-arm/smp.h b/include/asm-arm/smp.h
--- a/include/asm-arm/smp.h	2005-03-01 23:39:18 -08:00
+++ b/include/asm-arm/smp.h	2005-03-01 23:39:18 -08:00
@@ -1,10 +1,58 @@
-#ifndef __ASM_SMP_H
-#define __ASM_SMP_H
+/*
+ *  linux/include/asm-arm/smp.h
+ *
+ *  Copyright (C) 2004-2005 ARM Ltd.
+ *
+ * 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_ARM_SMP_H
+#define __ASM_ARM_SMP_H
 
 #include <linux/config.h>
+#include <linux/threads.h>
+#include <linux/cpumask.h>
+#include <linux/thread_info.h>
 
-#ifdef CONFIG_SMP
-#error SMP not supported
-#endif
+#include <asm/arch/smp.h>
 
+#ifndef CONFIG_SMP
+# 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
+
+/*
+ * at the moment, there's not a big penalty for changing CPUs
+ * (the >big< penalty is running SMP in the first place)
+ */
+#define PROC_CHANGE_PENALTY		15
+
+struct seq_file;
+
+/*
+ * generate IPI list text
+ */
+extern void show_ipi_list(struct seq_file *p);
+
+/*
+ * Move global data into per-processor storage.
+ */
+extern void smp_store_cpu_info(unsigned int cpuid);
+
+/*
+ * Raise an IPI cross call on CPUs in callmap.
+ */
+extern void smp_cross_call(cpumask_t callmap);
+
+/*
+ * Boot a secondary CPU, and assign it the specified idle task.
+ * This also gives us the initial stack to use for this CPU.
+ */
+extern int boot_secondary(unsigned int cpu, struct task_struct *);
+
+#endif /* ifndef __ASM_ARM_SMP_H */
diff -Nru a/include/asm-arm/spinlock.h b/include/asm-arm/spinlock.h
--- a/include/asm-arm/spinlock.h	2005-03-01 23:38:52 -08:00
+++ b/include/asm-arm/spinlock.h	2005-03-01 23:38:52 -08:00
@@ -17,6 +17,9 @@
  */
 typedef struct {
 	volatile unsigned int lock;
+#ifdef CONFIG_PREEMPT
+	unsigned int break_lock;
+#endif
 } spinlock_t;
 
 #define SPIN_LOCK_UNLOCKED	(spinlock_t) { 0 }
@@ -70,6 +73,9 @@
  */
 typedef struct {
 	volatile unsigned int lock;
+#ifdef CONFIG_PREEMPT
+	unsigned int break_lock;
+#endif
 } rwlock_t;
 
 #define RW_LOCK_UNLOCKED	(rwlock_t) { 0 }
@@ -142,6 +148,8 @@
 	: "r" (&rw->lock)
 	: "cc", "memory");
 }
+
+#define _raw_read_trylock(lock) generic_raw_read_trylock(lock)
 
 static inline int _raw_write_trylock(rwlock_t *rw)
 {
diff -Nru a/include/asm-arm/string.h b/include/asm-arm/string.h
--- a/include/asm-arm/string.h	2005-03-01 23:38:57 -08:00
+++ b/include/asm-arm/string.h	2005-03-01 23:38:57 -08:00
@@ -25,8 +25,6 @@
 #define __HAVE_ARCH_MEMSET
 extern void * memset(void *, int, __kernel_size_t);
 
-#define __HAVE_ARCH_BCOPY
-
 extern void __memzero(void *ptr, __kernel_size_t n);
 
 #define memset(p,v,n)							\
diff -Nru a/include/asm-arm/thread_info.h b/include/asm-arm/thread_info.h
--- a/include/asm-arm/thread_info.h	2005-03-01 23:38:57 -08:00
+++ b/include/asm-arm/thread_info.h	2005-03-01 23:38:57 -08:00
@@ -53,6 +53,7 @@
 	__u32			cpu_domain;	/* cpu domain */
 	struct cpu_context_save	cpu_context;	/* cpu context */
 	__u8			used_cp[16];	/* thread used copro */
+	unsigned long		tp_value;
 	union fp_state		fpstate;
 	union vfp_state		vfpstate;
 	struct restart_block	restart_block;
@@ -128,6 +129,7 @@
 #define TIF_SYSCALL_TRACE	8
 #define TIF_POLLING_NRFLAG	16
 #define TIF_USING_IWMMXT	17
+#define TIF_MEMDIE		18
 
 #define _TIF_NOTIFY_RESUME	(1 << TIF_NOTIFY_RESUME)
 #define _TIF_SIGPENDING		(1 << TIF_SIGPENDING)
diff -Nru a/include/asm-arm/tlb.h b/include/asm-arm/tlb.h
--- a/include/asm-arm/tlb.h	2005-03-01 23:38:51 -08:00
+++ b/include/asm-arm/tlb.h	2005-03-01 23:38:51 -08:00
@@ -91,4 +91,6 @@
 #define pte_free_tlb(tlb,ptep)		pte_free(ptep)
 #define pmd_free_tlb(tlb,pmdp)		pmd_free(pmdp)
 
+#define tlb_migrate_finish(mm)		do { } while (0)
+
 #endif
diff -Nru a/include/asm-arm/unistd.h b/include/asm-arm/unistd.h
--- a/include/asm-arm/unistd.h	2005-03-01 23:39:16 -08:00
+++ b/include/asm-arm/unistd.h	2005-03-01 23:39:16 -08:00
@@ -281,7 +281,7 @@
 #define __NR_remap_file_pages		(__NR_SYSCALL_BASE+253)
 					/* 254 for set_thread_area */
 					/* 255 for get_thread_area */
-					/* 256 for set_tid_address */
+#define __NR_set_tid_address		(__NR_SYSCALL_BASE+256)
 #define __NR_timer_create		(__NR_SYSCALL_BASE+257)
 #define __NR_timer_settime		(__NR_SYSCALL_BASE+258)
 #define __NR_timer_gettime		(__NR_SYSCALL_BASE+259)
@@ -315,6 +315,8 @@
 #define __ARM_NR_cacheflush		(__ARM_NR_BASE+2)
 #define __ARM_NR_usr26			(__ARM_NR_BASE+3)
 #define __ARM_NR_usr32			(__ARM_NR_BASE+4)
+
+#define __ARM_NR_set_tls		(__ARM_NR_BASE+0x800)
 
 #define __sys2(x) #x
 #define __sys1(x) __sys2(x)
diff -Nru a/include/asm-arm26/atomic.h b/include/asm-arm26/atomic.h
--- a/include/asm-arm26/atomic.h	2005-03-01 23:38:56 -08:00
+++ b/include/asm-arm26/atomic.h	2005-03-01 23:38:56 -08:00
@@ -2,12 +2,14 @@
  *  linux/include/asm-arm26/atomic.h
  *
  *  Copyright (c) 1996 Russell King.
+ *  Modified for arm26 by Ian Molton
  *
  * 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:
+ *   25-11-2004 IM	Updated for 2.6.9
  *   27-06-1996	RMK	Created
  *   13-04-1997	RMK	Made functions atomic!
  *   07-12-1997	RMK	Upgraded for v2.1.
@@ -31,102 +33,57 @@
 #ifdef __KERNEL__
 #include <asm/system.h>
 
-#define atomic_read(v)	((v)->counter)
+#define atomic_read(v) ((v)->counter)
 #define atomic_set(v,i)	(((v)->counter) = (i))
 
-static inline void atomic_add(int i, volatile atomic_t *v)
+static inline int atomic_add_return(int i, atomic_t *v)
 {
-	unsigned long flags;
+        unsigned long flags;
+        int val;
 
-	local_irq_save(flags);
-	v->counter += i;
-	local_irq_restore(flags);
-}
-
-static inline void atomic_sub(int i, volatile atomic_t *v)
-{
-	unsigned long flags;
-
-	local_irq_save(flags);
-	v->counter -= i;
-	local_irq_restore(flags);
-}
-
-static inline void atomic_inc(volatile atomic_t *v)
-{
-	unsigned long flags;
-
-	local_irq_save(flags);
-	v->counter += 1;
-	local_irq_restore(flags);
-}
-
-static inline void atomic_dec(volatile atomic_t *v)
-{
-	unsigned long flags;
+        local_irq_save(flags);
+        val = v->counter;
+        v->counter = val += i;
+        local_irq_restore(flags);
 
-	local_irq_save(flags);
-	v->counter -= 1;
-	local_irq_restore(flags);
+        return val;
 }
 
-static inline int atomic_dec_and_test(volatile atomic_t *v)
+static inline int atomic_sub_return(int i, atomic_t *v)
 {
-	unsigned long flags;
-	int val;
+        unsigned long flags;
+        int val;
 
-	local_irq_save(flags);
-	val = v->counter;
-	v->counter = val -= 1;
-	local_irq_restore(flags);
+        local_irq_save(flags);
+        val = v->counter;
+        v->counter = val -= i;
+        local_irq_restore(flags);
 
-	return val == 0;
-}
-
-static inline int atomic_add_negative(int i, volatile atomic_t *v)
-{
-	unsigned long flags;
-	int val;
-
-	local_irq_save(flags);
-	val = v->counter;
-	v->counter = val += i;
-	local_irq_restore(flags);
-
-	return val < 0;
+        return val;
 }
 
 static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr)
 {
-	unsigned long flags;
+        unsigned long flags;
 
-	local_irq_save(flags);
-	*addr &= ~mask;
-	local_irq_restore(flags);
+        local_irq_save(flags);
+        *addr &= ~mask;
+        local_irq_restore(flags);
 }
 
-static inline int atomic_add_return(int i, volatile atomic_t *v)
-{
-	unsigned long flags;
-	int val;
+#define atomic_add(i, v)        (void) atomic_add_return(i, v)
+#define atomic_inc(v)           (void) atomic_add_return(1, v)
+#define atomic_sub(i, v)        (void) atomic_sub_return(i, v)
+#define atomic_dec(v)           (void) atomic_sub_return(1, v)
 
-	local_irq_save(flags);
-	val = v->counter + i;
-	v->counter = val;
-	local_irq_restore(flags);
-
-	return val;
-}
-
-static inline int atomic_sub_return(int i, volatile atomic_t *v)
-{
-	return atomic_add_return(-i, v);
-}
+#define atomic_inc_and_test(v)  (atomic_add_return(1, v) == 0)
+#define atomic_dec_and_test(v)  (atomic_sub_return(1, v) == 0)
+#define atomic_inc_return(v)    (atomic_add_return(1, v))
+#define atomic_dec_return(v)    (atomic_sub_return(1, v))
 
-#define atomic_inc_return(v)  (atomic_add_return(1,v))
-#define atomic_dec_return(v)  (atomic_sub_return(1,v))
+#define atomic_add_negative(i,v) (atomic_add_return(i, v) < 0)
 
-/* Atomic operations are already serializing on ARM */
+/* Atomic operations are already serializing on ARM26 */
 #define smp_mb__before_atomic_dec()	barrier()
 #define smp_mb__after_atomic_dec()	barrier()
 #define smp_mb__before_atomic_inc()	barrier()
diff -Nru a/include/asm-arm26/bitops.h b/include/asm-arm26/bitops.h
--- a/include/asm-arm26/bitops.h	2005-03-01 23:39:16 -08:00
+++ b/include/asm-arm26/bitops.h	2005-03-01 23:39:16 -08:00
@@ -1,15 +1,15 @@
 /*
  * Copyright 1995, Russell King.
- * Various bits and pieces copyrights include:
- *  Linus Torvalds (test_bit).
- * Big endian support: Copyright 2001, Nicolas Pitre
- *  reworked by rmk.
  *
- * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1).
+ * Based on the arm32 version by RMK (and others). Their copyrights apply to
+ * Those parts.
+ * Modified for arm26 by Ian Molton on 25/11/04
+ *
+ * bit 0 is the LSB of an "unsigned long" quantity.
  *
  * Please note that the code in this file should never be included
  * from user space.  Many of these are not implemented in assembler
- * since they would be too costly.  Also, they require priviledged
+ * since they would be too costly.  Also, they require privileged
  * instructions (which are not available from user mode) to ensure
  * that they are atomic.
  */
@@ -19,6 +19,7 @@
 
 #ifdef __KERNEL__
 
+#include <linux/compiler.h>
 #include <asm/system.h>
 
 #define smp_mb__before_clear_bit()	do { } while (0)
@@ -26,12 +27,10 @@
 
 /*
  * These functions are the basis of our bit ops.
- * First, the atomic bitops.
  *
- * The endian issue for these functions is handled by the macros below.
+ * First, the atomic bitops. These use native endian.
  */
-static inline void
-____atomic_set_bit(unsigned int bit, volatile unsigned long *p)
+static inline void ____atomic_set_bit(unsigned int bit, volatile unsigned long *p)
 {
 	unsigned long flags;
 	unsigned long mask = 1UL << (bit & 31);
@@ -43,8 +42,7 @@
 	local_irq_restore(flags);
 }
 
-static inline void
-____atomic_clear_bit(unsigned int bit, volatile unsigned long *p)
+static inline void ____atomic_clear_bit(unsigned int bit, volatile unsigned long *p)
 {
 	unsigned long flags;
 	unsigned long mask = 1UL << (bit & 31);
@@ -56,8 +54,7 @@
 	local_irq_restore(flags);
 }
 
-static inline void
-____atomic_change_bit(unsigned int bit, volatile unsigned long *p)
+static inline void ____atomic_change_bit(unsigned int bit, volatile unsigned long *p)
 {
 	unsigned long flags;
 	unsigned long mask = 1UL << (bit & 31);
@@ -104,7 +101,7 @@
 }
 
 static inline int
-____atomic_test_and_change_bit_mask(unsigned int bit, volatile unsigned long *p)
+____atomic_test_and_change_bit(unsigned int bit, volatile unsigned long *p)
 {
 	unsigned long flags;
 	unsigned int res;
@@ -158,7 +155,6 @@
 
 	oldval = *p;
 	*p = oldval & ~mask;
-
 	return oldval & mask;
 }
 
@@ -170,30 +166,18 @@
 
 	oldval = *p;
 	*p = oldval ^ mask;
-
 	return oldval & mask;
 }
 
 /*
  * This routine doesn't need to be atomic.
  */
-static inline int __test_bit(int nr, const unsigned long * p)
+static inline int __test_bit(int nr, const volatile unsigned long * p)
 {
-	return p[nr >> 5] & (1UL << (nr & 31));
+	return (p[nr >> 5] >> (nr & 31)) & 1UL;
 }
 
 /*
- *  A note about Endian-ness.
- *  -------------------------
- *
- *          ------------ physical data bus bits -----------
- *          D31 ... D24  D23 ... D16  D15 ... D8  D7 ... D0
- *            byte 3       byte 2       byte 1      byte 0
- *
- * Note that bit 0 is defined to be 32-bit word bit 0, not byte 0 bit 0.
- */
-
-/*
  * Little endian assembly bitops.  nr = 0 -> byte 0 bit 0.
  */
 extern void _set_bit_le(int nr, volatile unsigned long * p);
@@ -204,6 +188,8 @@
 extern int _test_and_change_bit_le(int nr, volatile unsigned long * p);
 extern int _find_first_zero_bit_le(void * p, unsigned size);
 extern int _find_next_zero_bit_le(void * p, int size, int offset);
+extern int _find_first_bit_le(const unsigned long *p, unsigned size);
+extern int _find_next_bit_le(const unsigned long *p, int size, int offset);
 
 /*
  * The __* form of bitops are non-atomic and may be reordered.
@@ -213,11 +199,6 @@
 	 ____atomic_##name(nr, p) :		\
 	 _##name##_le(nr,p))
 
-#define	ATOMIC_BITOP_BE(name,nr,p)		\
-	(__builtin_constant_p(nr) ?		\
-	 ____atomic_##name(nr, p) :		\
-	 _##name##_be(nr,p))
-
 #define NONATOMIC_BITOP(name,nr,p)		\
 	(____nonatomic_##name(nr, p))
 
@@ -233,6 +214,8 @@
 #define test_bit(nr,p)			__test_bit(nr,p)
 #define find_first_zero_bit(p,sz)	_find_first_zero_bit_le(p,sz)
 #define find_next_zero_bit(p,sz,off)	_find_next_zero_bit_le(p,sz,off)
+#define find_first_bit(p,sz)		_find_first_bit_le(p,sz)
+#define find_next_bit(p,sz,off)		_find_next_bit_le(p,sz,off)
 
 #define WORD_BITOFF_TO_LE(x)		((x))
 
@@ -315,15 +298,15 @@
  * These do not need to be atomic.
  */
 #define ext2_set_bit(nr,p)			\
-		__test_and_set_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)p)
-#define ext2_set_bit_atomic(lock,nr,p)		\
-		test_and_set_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
+		__test_and_set_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
+#define ext2_set_bit_atomic(lock,nr,p)          \
+                test_and_set_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
 #define ext2_clear_bit(nr,p)			\
-		__test_and_clear_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)p)
+		__test_and_clear_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
 #define ext2_clear_bit_atomic(lock,nr,p)        \
-		test_and_clear_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
+                test_and_clear_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
 #define ext2_test_bit(nr,p)			\
-		__test_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)p)
+		__test_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
 #define ext2_find_first_zero_bit(p,sz)		\
 		_find_first_zero_bit_le(p,sz)
 #define ext2_find_next_zero_bit(p,sz,off)	\
@@ -334,13 +317,13 @@
  * These do not need to be atomic.
  */
 #define minix_set_bit(nr,p)			\
-		__set_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)p)
+		__set_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
 #define minix_test_bit(nr,p)			\
-		__test_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)p)
+		__test_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
 #define minix_test_and_set_bit(nr,p)		\
-		__test_and_set_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)p)
+		__test_and_set_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
 #define minix_test_and_clear_bit(nr,p)		\
-		__test_and_clear_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)p)
+		__test_and_clear_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
 #define minix_find_first_zero_bit(p,sz)		\
 		_find_first_zero_bit_le(p,sz)
 
diff -Nru a/include/asm-arm26/calls.h b/include/asm-arm26/calls.h
--- a/include/asm-arm26/calls.h	2005-03-01 23:38:44 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,262 +0,0 @@
-/*
- *  linux/arch/arm26/lib/calls.h
- *
- *  Copyright (C) 2003 Ian Molton
- *
- * 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.
- *
- *  FIXME
- *  This file is included twice in entry-common.S which may not be necessary
- */
-#ifndef NR_syscalls
-#define NR_syscalls 256
-#else
-
-__syscall_start:
-/* 0 */		.long	sys_ni_syscall
-		.long	sys_exit
-		.long	sys_fork_wrapper
-		.long	sys_read
-		.long	sys_write
-/* 5 */		.long	sys_open
-		.long	sys_close
-		.long	sys_ni_syscall		/* was sys_waitpid */
-		.long	sys_creat
-		.long	sys_link
-/* 10 */	.long	sys_unlink
-		.long	sys_execve_wrapper
-		.long	sys_chdir
-		.long	sys_time		/* used by libc4 */
-		.long	sys_mknod
-/* 15 */	.long	sys_chmod
-		.long	sys_lchown16
-		.long	sys_ni_syscall		/* was sys_break */
-		.long	sys_ni_syscall		/* was sys_stat */
-		.long	sys_lseek
-/* 20 */	.long	sys_getpid
-		.long	sys_mount
-		.long	sys_oldumount		/* used by libc4 */
-		.long	sys_setuid16
-		.long	sys_getuid16
-/* 25 */	.long	sys_stime
-		.long	sys_ptrace
-		.long	sys_alarm		/* used by libc4 */
-		.long	sys_ni_syscall		/* was sys_fstat */
-		.long	sys_pause
-/* 30 */	.long	sys_utime		/* used by libc4 */
-		.long	sys_ni_syscall		/* was sys_stty */
-		.long	sys_ni_syscall		/* was sys_getty */
-		.long	sys_access
-		.long	sys_nice
-/* 35 */	.long	sys_ni_syscall		/* was sys_ftime */
-		.long	sys_sync
-		.long	sys_kill
-		.long	sys_rename
-		.long	sys_mkdir
-/* 40 */	.long	sys_rmdir
-		.long	sys_dup
-		.long	sys_pipe
-		.long	sys_times
-		.long	sys_ni_syscall		/* was sys_prof */
-/* 45 */	.long	sys_brk
-		.long	sys_setgid16
-		.long	sys_getgid16
-		.long	sys_ni_syscall		/* was sys_signal */
-		.long	sys_geteuid16
-/* 50 */	.long	sys_getegid16
-		.long	sys_acct
-		.long	sys_umount
-		.long	sys_ni_syscall		/* was sys_lock */
-		.long	sys_ioctl
-/* 55 */	.long	sys_fcntl
-		.long	sys_ni_syscall		/* was sys_mpx */
-		.long	sys_setpgid
-		.long	sys_ni_syscall		/* was sys_ulimit */
-		.long	sys_ni_syscall		/* was sys_olduname */
-/* 60 */	.long	sys_umask
-		.long	sys_chroot
-		.long	sys_ustat
-		.long	sys_dup2
-		.long	sys_getppid
-/* 65 */	.long	sys_getpgrp
-		.long	sys_setsid
-		.long	sys_sigaction
-		.long	sys_ni_syscall		/* was sys_sgetmask */
-		.long	sys_ni_syscall		/* was sys_ssetmask */
-/* 70 */	.long	sys_setreuid16
-		.long	sys_setregid16
-		.long	sys_sigsuspend_wrapper
-		.long	sys_sigpending
-		.long	sys_sethostname
-/* 75 */	.long	sys_setrlimit
-		.long	sys_old_getrlimit	/* used by libc4 */
-		.long	sys_getrusage
-		.long	sys_gettimeofday
-		.long	sys_settimeofday
-/* 80 */	.long	sys_getgroups16
-		.long	sys_setgroups16
-		.long	old_select		/* used by libc4 */
-		.long	sys_symlink
-		.long	sys_ni_syscall		/* was sys_lstat */
-/* 85 */	.long	sys_readlink
-		.long	sys_uselib
-		.long	sys_swapon
-		.long	sys_reboot
-		.long	old_readdir		/* used by libc4 */
-/* 90 */	.long	old_mmap		/* used by libc4 */
-		.long	sys_munmap
-		.long	sys_truncate
-		.long	sys_ftruncate
-		.long	sys_fchmod
-/* 95 */	.long	sys_fchown16
-		.long	sys_getpriority
-		.long	sys_setpriority
-		.long	sys_ni_syscall		/* was sys_profil */
-		.long	sys_statfs
-/* 100 */	.long	sys_fstatfs
-		.long	sys_ni_syscall
-		.long	sys_socketcall
-		.long	sys_syslog
-		.long	sys_setitimer
-/* 105 */	.long	sys_getitimer
-		.long	sys_newstat
-		.long	sys_newlstat
-		.long	sys_newfstat
-		.long	sys_ni_syscall		/* was sys_uname */
-/* 110 */	.long	sys_ni_syscall		/* was sys_iopl */
-		.long	sys_vhangup
-		.long	sys_ni_syscall
-		.long	sys_syscall		/* call a syscall */
-		.long	sys_wait4
-/* 115 */	.long	sys_swapoff
-		.long	sys_sysinfo
-		.long	sys_ipc
-		.long	sys_fsync
-		.long	sys_sigreturn_wrapper
-/* 120 */	.long	sys_clone_wapper
-		.long	sys_setdomainname
-		.long	sys_newuname
-		.long	sys_ni_syscall
-		.long	sys_adjtimex
-/* 125 */	.long	sys_mprotect
-		.long	sys_sigprocmask
-		.long	sys_ni_syscall  /* WAS: sys_create_module */
-		.long	sys_init_module
-		.long	sys_delete_module
-/* 130 */	.long	sys_ni_syscall  /* WAS: sys_get_kernel_syms */
-		.long	sys_quotactl
-		.long	sys_getpgid
-		.long	sys_fchdir
-		.long	sys_bdflush
-/* 135 */	.long	sys_sysfs
-		.long	sys_personality
-		.long	sys_ni_syscall		/* .long	_sys_afs_syscall */
-		.long	sys_setfsuid16
-		.long	sys_setfsgid16
-/* 140 */	.long	sys_llseek
-		.long	sys_getdents
-		.long	sys_select
-		.long	sys_flock
-		.long	sys_msync
-/* 145 */	.long	sys_readv
-		.long	sys_writev
-		.long	sys_getsid
-		.long	sys_fdatasync
-		.long	sys_sysctl
-/* 150 */	.long	sys_mlock
-		.long	sys_munlock
-		.long	sys_mlockall
-		.long	sys_munlockall
-		.long	sys_sched_setparam
-/* 155 */	.long	sys_sched_getparam
-		.long	sys_sched_setscheduler
-		.long	sys_sched_getscheduler
-		.long	sys_sched_yield
-		.long	sys_sched_get_priority_max
-/* 160 */	.long	sys_sched_get_priority_min
-		.long	sys_sched_rr_get_interval
-		.long	sys_nanosleep
-		.long	sys_arm_mremap
-		.long	sys_setresuid16
-/* 165 */	.long	sys_getresuid16
-		.long	sys_ni_syscall
-		.long	sys_ni_syscall /* WAS: sys_query_module */
-		.long	sys_poll
-		.long	sys_nfsservctl
-/* 170 */	.long	sys_setresgid16
-		.long	sys_getresgid16
-		.long	sys_prctl
-		.long	sys_rt_sigreturn_wrapper
-		.long	sys_rt_sigaction
-/* 175 */	.long	sys_rt_sigprocmask
-		.long	sys_rt_sigpending
-		.long	sys_rt_sigtimedwait
-		.long	sys_rt_sigqueueinfo
-		.long	sys_rt_sigsuspend_wrapper
-/* 180 */	.long	sys_pread64
-		.long	sys_pwrite64
-		.long	sys_chown16
-		.long	sys_getcwd
-		.long	sys_capget
-/* 185 */	.long	sys_capset
-		.long	sys_sigaltstack_wrapper
-		.long	sys_sendfile
-		.long	sys_ni_syscall
-		.long	sys_ni_syscall
-/* 190 */	.long	sys_vfork_wrapper
-		.long	sys_getrlimit
-		.long	sys_mmap2
-		.long	sys_truncate64
-		.long	sys_ftruncate64
-/* 195 */	.long	sys_stat64
-		.long	sys_lstat64
-		.long	sys_fstat64
-		.long	sys_lchown
-		.long	sys_getuid
-/* 200 */	.long	sys_getgid
-		.long	sys_geteuid
-		.long	sys_getegid
-		.long	sys_setreuid
-		.long	sys_setregid
-/* 205 */	.long	sys_getgroups
-		.long	sys_setgroups
-		.long	sys_fchown
-		.long	sys_setresuid
-		.long	sys_getresuid
-/* 210 */	.long	sys_setresgid
-		.long	sys_getresgid
-		.long	sys_chown
-		.long	sys_setuid
-		.long	sys_setgid
-/* 215 */	.long	sys_setfsuid
-		.long	sys_setfsgid
-		.long	sys_getdents64
-		.long	sys_pivot_root
-		.long	sys_mincore
-/* 220 */	.long	sys_madvise
-		.long	sys_fcntl64
-		.long	sys_ni_syscall /* TUX */
-		.long	sys_ni_syscall /* WAS: sys_security */
-		.long	sys_gettid
-/* 225 */	.long	sys_readahead
-		.long	sys_setxattr
-		.long	sys_lsetxattr
-		.long	sys_fsetxattr
-		.long	sys_getxattr
-/* 230 */	.long	sys_lgetxattr
-		.long	sys_fgetxattr
-		.long	sys_listxattr
-		.long	sys_llistxattr
-		.long	sys_flistxattr
-/* 235 */	.long	sys_removexattr
-		.long	sys_lremovexattr
-		.long	sys_fremovexattr
-		.long	sys_tkill
-__syscall_end:
-
-		.rept	NR_syscalls - (__syscall_end - __syscall_start) / 4
-			.long	sys_ni_syscall
-		.endr
-#endif
diff -Nru a/include/asm-arm26/checksum.h b/include/asm-arm26/checksum.h
--- a/include/asm-arm26/checksum.h	2005-03-01 23:39:18 -08:00
+++ b/include/asm-arm26/checksum.h	2005-03-01 23:39:18 -08:00
@@ -9,6 +9,8 @@
 #ifndef __ASM_ARM_CHECKSUM_H
 #define __ASM_ARM_CHECKSUM_H
 
+#include <linux/in6.h>
+
 /*
  * computes the checksum of a memory block at buff, length len,
  * and adds in "sum" (32-bit)
@@ -35,13 +37,13 @@
 csum_partial_copy_nocheck(const char *src, char *dst, int len, int sum);
 
 unsigned int
-csum_partial_copy_from_user(const char *src, char *dst, int len, int sum, int *err_ptr);
+csum_partial_copy_from_user(const char __user *src, char *dst, int len, int sum, int *err_ptr);
 
 /*
- * These are the old (and unsafe) way of doing checksums, a warning message will be
- * printed if they are used and an exception occurs.
+ * This is the old (and unsafe) way of doing checksums, a warning message will
+ * be printed if it is used and an exception occurs.
  *
- * these functions should go away after some time.
+ * this functions should go away after some time.
  */
 #define csum_partial_copy(src,dst,len,sum)	csum_partial_copy_nocheck(src,dst,len,sum)
 
@@ -105,7 +107,7 @@
 	adcs	%0, %0, %5					\n\
 	adc	%0, %0, #0"
 	: "=&r"(sum)
-	: "r" (sum), "r" (daddr), "r" (saddr), "r" (ntohs(len) << 16), "Ir" (proto << 8)
+	: "r" (sum), "r" (daddr), "r" (saddr), "r" (ntohs(len)), "Ir" (ntohs(proto))
 	: "cc");
 	return sum;
 }	
@@ -127,7 +129,7 @@
 	addcs	%0, %0, #0x10000				\n\
 	mvn	%0, %0"
 	: "=&r"(sum)
-	: "r" (sum), "r" (daddr), "r" (saddr), "r" (ntohs(len)), "Ir" (proto << 8)
+	: "r" (sum), "r" (daddr), "r" (saddr), "r" (ntohs(len)), "Ir" (ntohs(proto))
 	: "cc");
 	return sum >> 16;
 }
diff -Nru a/include/asm-arm26/constants.h b/include/asm-arm26/constants.h
--- a/include/asm-arm26/constants.h	2005-03-01 23:39:09 -08:00
+++ b/include/asm-arm26/constants.h	2005-03-01 23:39:09 -08:00
@@ -7,7 +7,6 @@
  *
  */
 
-#define TSK_USED_MATH 788 /* offsetof(struct task_struct, used_math) */
 #define TSK_ACTIVE_MM 96 /* offsetof(struct task_struct, active_mm) */
 
 #define VMA_VM_MM 0 /* offsetof(struct vm_area_struct, vm_mm) */
diff -Nru a/include/asm-arm26/cputime.h b/include/asm-arm26/cputime.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-arm26/cputime.h	2005-03-01 23:39:26 -08:00
@@ -0,0 +1,6 @@
+#ifndef __ARM26_CPUTIME_H
+#define __ARM26_CPUTIME_H
+
+#include <asm-generic/cputime.h>
+
+#endif /* __ARM26_CPUTIME_H */
diff -Nru a/include/asm-arm26/dma-mapping.h b/include/asm-arm26/dma-mapping.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-arm26/dma-mapping.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,2 @@
+#include <asm-generic/dma-mapping-broken.h>
+
diff -Nru a/include/asm-arm26/hardirq.h b/include/asm-arm26/hardirq.h
--- a/include/asm-arm26/hardirq.h	2005-03-01 23:38:55 -08:00
+++ b/include/asm-arm26/hardirq.h	2005-03-01 23:38:55 -08:00
@@ -7,10 +7,6 @@
 
 typedef struct {
 	unsigned int __softirq_pending;
-	unsigned int __local_irq_count;
-	unsigned int __local_bh_count;
-	unsigned int __syscall_count;
-	struct task_struct * __ksoftirqd_task; /* waitqueue is too large */
 } ____cacheline_aligned irq_cpustat_t;
 
 #include <linux/irq_cpustat.h>	/* Standard mappings for irq_cpustat_t above */
@@ -29,14 +25,17 @@
 #define irq_enter()		(preempt_count() += HARDIRQ_OFFSET)
 
 #ifndef CONFIG_SMP
-#define irq_exit()							\
-	do {								\
-		preempt_count() -= HARDIRQ_OFFSET;			\
-		if (!in_interrupt() && softirq_pending(smp_processor_id())) \
-			__asm__("bl%? __do_softirq": : : "lr");/* out of line */\
-		preempt_enable_no_resched();				\
-	} while (0)
 
+extern asmlinkage void __do_softirq(void);
+
+#define irq_exit()                                                      \
+        do {                                                            \
+                preempt_count() -= IRQ_EXIT_OFFSET;                     \
+                if (!in_interrupt() && local_softirq_pending())         \
+                        __do_softirq();                                 \
+                preempt_enable_no_resched();                            \
+        } while (0)
 #endif
+
 
 #endif /* __ASM_HARDIRQ_H */
diff -Nru a/include/asm-arm26/hardware.h b/include/asm-arm26/hardware.h
--- a/include/asm-arm26/hardware.h	2005-03-01 23:38:53 -08:00
+++ b/include/asm-arm26/hardware.h	2005-03-01 23:38:53 -08:00
@@ -90,6 +90,7 @@
 #define IOEB_PSCLR		(IOEB_BASE + 0x58)
 #define IOEB_MONTYPE		(IOEB_BASE + 0x70)
 
+//FIXME - These adresses are weird - ISTR some weirdo address shifting stuff was going on here...
 #define IO_EC_IOC_BASE		0x80090000
 #define IO_EC_MEMC_BASE		0x80000000
 
diff -Nru a/include/asm-arm26/ian_char.h b/include/asm-arm26/ian_char.h
--- a/include/asm-arm26/ian_char.h	2005-03-01 23:39:16 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,79 +0,0 @@
-#ifndef _ian_char_h_included
-#define _ian_char_h_included
-static int charset[256*8] = {0x777700, 0x7700770, 0x7700770, 0x7777770, 0x7700770, 0x7700770, 0x7700770, 0x0, 0x777770, 0x7700770, 0x7700770, 0x777770, 0x7700770, 0x7700770, 0x777770, 0x0, 0x777700, 0x7700770, 0x770, 0x770, 0x770, 0x7700770, 0x777700, 0x0, 0x77770, 0x770770, 0x7700770, 0x7700770, 0x7700770, 0x770770, 0x77770, 0x0, 0x7777770, 0x770, 0x770, 0x777770, 0x770, 0x770, 0x7777770, 0x0, 0x7777770, 0x770, 0x770, 0x777770, 0x770, 0x770, 0x770, 0x0, 0x777700, 0x7700770, 0x770, 0x7770770, 0x7700770, 0x7700770, 0x777700, 0x0, 0x7700770, 0x7700770, 0x7700770, 0x7777770, 0x7700770, 0x7700770, 0x7700770, 0x0, 0x7777770, 0x77000, 0x77000, 0x77000, 0x77000, 0x77000, 0x7777770, 0x0, 0x7777700, 0x770000, 0x770000, 0x770000, 0x770000, 0x770770, 0x77700, 0x0, 0x7700770, 0x770770, 0x77770, 0x7770, 0x77770, 0x770770, 0x7700770, 0x0, 0x770, 0x770, 0x770, 0x770, 0x770, 0x770, 0x7777770, 0x0, 0x77000770, 0x77707770, 0x77777770, 0x77070770, 0x77070770, 0x77000770, 0x77000770, 0x0, 0x7700770, 0x7700770, 0x7707770, 0x7777770, 0x7770770, 0x7700770, 0x7700770, 0x0, 0x777700, 0x7700770, 0x7700770, 0x7700770, 0x7700770, 0x7700770, 0x777700, 0x0, 0x777770, 0x7700770, 0x7700770, 0x777770, 0x770, 0x770, 0x770, 0x0, 0x777700, 0x7700770, 0x7700770, 0x7700770, 0x7070770, 0x770770, 0x7707700, 0x0, 0x777770, 0x7700770, 0x7700770, 0x777770, 0x770770, 0x7700770, 0x7700770, 0x0, 0x777700, 0x7700770, 0x770, 0x777700, 0x7700000, 0x7700770, 0x777700, 0x0, 0x7777770, 0x77000, 0x77000, 0x77000, 0x77000, 0x77000, 0x77000, 0x0, 0x7700770, 0x7700770, 0x7700770, 0x7700770, 0x7700770, 0x7700770, 0x777700, 0x0, 0x7700770, 0x7700770, 0x7700770, 0x7700770, 0x7700770, 0x777700, 0x77000, 0x0, 0x77000770, 0x77000770, 0x77070770, 0x77070770, 0x77777770, 0x77707770, 0x77000770, 0x0, 0x7700770, 0x7700770, 0x777700, 0x77000, 0x777700, 0x7700770, 0x7700770, 0x0, 0x7700770, 0x7700770, 0x7700770, 0x777700, 0x77000, 0x77000, 0x77000, 0x0, 0x7777770, 0x7700000, 0x770000, 0x77000, 0x7700, 0x770, 0x7777770, 0x0, 0x777770, 0x770, 0x770, 0x770, 0x770, 0x770, 0x777770, 0x0, 0x0, 0x770, 0x7700, 0x77000, 0x770000, 0x7700000, 0x0, 0x0, 0x7777700, 0x7700000, 0x7700000, 0x7700000, 0x7700000, 0x7700000, 0x7777700, 0x0, 0x777700, 0x7700770, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x77777777, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x77000, 0x77000, 0x77000, 0x77000, 0x77000, 0x0, 0x77000, 0x0, 0x770770, 0x770770, 0x770770, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7707700, 0x7707700, 0x77777770, 0x7707700, 0x77777770, 0x7707700, 0x7707700, 0x0, 0x770000, 0x77777700, 0x70770, 0x7777700, 0x77070000, 0x7777770, 0x77000, 0x0, 0x770, 0x7700770, 0x770000, 0x77000, 0x7700, 0x7700770, 0x7700000, 0x0, 0x77700, 0x770770, 0x770770, 0x77700, 0x70770770, 0x7700770, 0x77077700, 0x0, 0x77000, 0x77000, 0x77000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x770000, 0x77000, 0x7700, 0x7700, 0x7700, 0x77000, 0x770000, 0x0, 0x7700, 0x77000, 0x770000, 0x770000, 0x770000, 0x77000, 0x7700, 0x0, 0x0, 0x77000, 0x7777770, 0x777700, 0x7777770, 0x77000, 0x0, 0x0, 0x0, 0x77000, 0x77000, 0x7777770, 0x77000, 0x77000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x77000, 0x77000, 0x7700, 0x0, 0x0, 0x0, 0x7777770, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x77000, 0x77000, 0x0, 0x0, 0x7700000, 0x770000, 0x77000, 0x7700, 0x770, 0x0, 0x0, 0x777700, 0x7700770, 0x7770770, 0x7777770, 0x7707770, 0x7700770, 0x777700, 0x0, 0x77000, 0x77700, 0x77000, 0x77000, 0x77000, 0x77000, 0x7777770, 0x0, 0x777700, 0x7700770, 0x7700000, 0x770000, 0x77000, 0x7700, 0x7777770, 0x0, 0x777700, 0x7700770, 0x7700000, 0x777000, 0x7700000, 0x7700770, 0x777700, 0x0, 0x770000, 0x777000, 0x777700, 0x770770, 0x7777770, 0x770000, 0x770000, 0x0, 0x7777770, 0x770, 0x777770, 0x7700000, 0x7700000, 0x7700770, 0x777700, 0x0, 0x777000, 0x7700, 0x770, 0x777770, 0x7700770, 0x7700770, 0x777700, 0x0, 0x7777770, 0x7700000, 0x770000, 0x77000, 0x7700, 0x7700, 0x7700, 0x0, 0x777700, 0x7700770, 0x7700770, 0x777700, 0x7700770, 0x7700770, 0x777700, 0x0, 0x777700, 0x7700770, 0x7700770, 0x7777700, 0x7700000, 0x770000, 0x77700, 0x0, 0x0, 0x0, 0x77000, 0x77000, 0x0, 0x77000, 0x77000, 0x0, 0x0, 0x0, 0x77000, 0x77000, 0x0, 0x77000, 0x77000, 0x7700, 0x770000, 0x77000, 0x7700, 0x770, 0x7700, 0x77000, 0x770000, 0x0, 0x0, 0x0, 0x7777770, 0x0, 0x7777770, 0x0, 0x0, 0x0, 0x7700, 0x77000, 0x770000, 0x7700000, 0x770000, 0x77000, 0x7700, 0x0, 0x777700, 0x7700770, 0x770000, 0x77000, 0x77000, 0x0, 0x77000, 0x0, 0x777700, 0x7700770, 0x7770770, 0x7070770, 0x7770770, 0x770, 0x777700, 0x0, 0x777700, 0x7700770, 0x7700770, 0x7777770, 0x7700770, 0x7700770, 0x7700770, 0x0, 0x777770, 0x7700770, 0x7700770, 0x777770, 0x7700770, 0x7700770, 0x777770, 0x0, 0x777700, 0x7700770, 0x770, 0x770, 0x770, 0x7700770, 0x777700, 0x0, 0x77770, 0x770770, 0x7700770, 0x7700770, 0x7700770, 0x770770, 0x77770, 0x0, 0x7777770, 0x770, 0x770, 0x777770, 0x770, 0x770, 0x7777770, 0x0, 0x7777770, 0x770, 0x770, 0x777770, 0x770, 0x770, 0x770, 0x0, 0x777700, 0x7700770, 0x770, 0x7770770, 0x7700770, 0x7700770, 0x777700, 0x0, 0x7700770, 0x7700770, 0x7700770, 0x7777770, 0x7700770, 0x7700770, 0x7700770, 0x0, 0x7777770, 0x77000, 0x77000, 0x77000, 0x77000, 0x77000, 0x7777770, 0x0, 0x7777700, 0x770000, 0x770000, 0x770000, 0x770000, 0x770770, 0x77700, 0x0, 0x7700770, 0x770770, 0x77770, 0x7770, 0x77770, 0x770770, 0x7700770, 0x0, 0x770, 0x770, 0x770, 0x770, 0x770, 0x770, 0x7777770, 0x0, 0x77000770, 0x77707770, 0x77777770, 0x77070770, 0x77070770, 0x77000770, 0x77000770, 0x0, 0x7700770, 0x7700770, 0x7707770, 0x7777770, 0x7770770, 0x7700770, 0x7700770, 0x0, 0x777700, 0x7700770, 0x7700770, 0x7700770, 0x7700770, 0x7700770, 0x777700, 0x0, 0x777770, 0x7700770, 0x7700770, 0x777770, 0x770, 0x770, 0x770, 0x0, 0x777700, 0x7700770, 0x7700770, 0x7700770, 0x7070770, 0x770770, 0x7707700, 0x0, 0x777770, 0x7700770, 0x7700770, 0x777770, 0x770770, 0x7700770, 0x7700770, 0x0, 0x777700, 0x7700770, 0x770, 0x777700, 0x7700000, 0x7700770, 0x777700, 0x0, 0x7777770, 0x77000, 0x77000, 0x77000, 0x77000, 0x77000, 0x77000, 0x0, 0x7700770, 0x7700770, 0x7700770, 0x7700770, 0x7700770, 0x7700770, 0x777700, 0x0, 0x7700770, 0x7700770, 0x7700770, 0x7700770, 0x7700770, 0x777700, 0x77000, 0x0, 0x77000770, 0x77000770, 0x77070770, 0x77070770, 0x77777770, 0x77707770, 0x77000770, 0x0, 0x7700770, 0x7700770, 0x777700, 0x77000, 0x777700, 0x7700770, 0x7700770, 0x0, 0x7700770, 0x7700770, 0x7700770, 0x777700, 0x77000, 0x77000, 0x77000, 0x0, 0x7777770, 0x7700000, 0x770000, 0x77000, 0x7700, 0x770, 0x7777770, 0x0, 0x777770, 0x770, 0x770, 0x770, 0x770, 0x770, 0x777770, 0x0, 0x0, 0x770, 0x7700, 0x77000, 0x770000, 0x7700000, 0x0, 0x0, 0x7777700, 0x7700000, 0x7700000, 0x7700000, 0x7700000, 0x7700000, 0x7777700, 0x0, 0x777700, 0x7700770, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x77777777, 0x7700, 0x77000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x777700, 0x7700000, 0x7777700, 0x7700770, 0x7777700, 0x0, 0x770, 0x770, 0x777770, 0x7700770, 0x7700770, 0x7700770, 0x777770, 0x0, 0x0, 0x0, 0x777700, 0x7700770, 0x770, 0x7700770, 0x777700, 0x0, 0x7700000, 0x7700000, 0x7777700, 0x7700770, 0x7700770, 0x7700770, 0x7777700, 0x0, 0x0, 0x0, 0x777700, 0x7700770, 0x7777770, 0x770, 0x777700, 0x0, 0x777000, 0x7700, 0x7700, 0x777770, 0x7700, 0x7700, 0x7700, 0x0, 0x0, 0x0, 0x7777700, 0x7700770, 0x7700770, 0x7777700, 0x7700000, 0x777700, 0x770, 0x770, 0x777770, 0x7700770, 0x7700770, 0x7700770, 0x7700770, 0x0, 0x77000, 0x0, 0x77700, 0x77000, 0x77000, 0x77000, 0x777700, 0x0, 0x77000, 0x0, 0x77700, 0x77000, 0x77000, 0x77000, 0x77000, 0x7770, 0x770, 0x770, 0x7700770, 0x770770, 0x77770, 0x770770, 0x7700770, 0x0, 0x77700, 0x77000, 0x77000, 0x77000, 0x77000, 0x77000, 0x777700, 0x0, 0x0, 0x0, 0x7707700, 0x77777770, 0x77070770, 0x77070770, 0x77000770, 0x0, 0x0, 0x0, 0x777770, 0x7700770, 0x7700770, 0x7700770, 0x7700770, 0x0, 0x0, 0x0, 0x777700, 0x7700770, 0x7700770, 0x7700770, 0x777700, 0x0, 0x0, 0x0, 0x777770, 0x7700770, 0x7700770, 0x777770, 0x770, 0x770, 0x0, 0x0, 0x7777700, 0x7700770, 0x7700770, 0x7777700, 0x7700000, 0x77700000, 0x0, 0x0, 0x770770, 0x7707770, 0x770, 0x770, 0x770, 0x0, 0x0, 0x0, 0x7777700, 0x770, 0x777700, 0x7700000, 0x777770, 0x0, 0x7700, 0x7700, 0x777770, 0x7700, 0x7700, 0x7700, 0x777000, 0x0, 0x0, 0x0, 0x7700770, 0x7700770, 0x7700770, 0x7700770, 0x7777700, 0x0, 0x0, 0x0, 0x7700770, 0x7700770, 0x7700770, 0x777700, 0x77000, 0x0, 0x0, 0x0, 0x77000770, 0x77070770, 0x77070770, 0x77777770, 0x7707700, 0x0, 0x0, 0x0, 0x7700770, 0x777700, 0x77000, 0x777700, 0x7700770, 0x0, 0x0, 0x0, 0x7700770, 0x7700770, 0x7700770, 0x7777700, 0x7700000, 0x777700, 0x0, 0x0, 0x7777770, 0x770000, 0x77000, 0x7700, 0x7777770, 0x0, 0x770000, 0x77000, 0x77000, 0x7770, 0x77000, 0x77000, 0x770000, 0x0, 0x77000, 0x77000, 0x77000, 0x77000, 0x77000, 0x77000, 0x77000, 0x0, 0x7700, 0x77000, 0x77000, 0x7770000, 0x77000, 0x77000, 0x7700, 0x0, 0x70007700, 0x77070770, 0x7700070, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x77000000, 0x77000000, 0x7700000, 0x7700000, 0x7707770, 0x777000, 0x770000, 0x0, 0x777000, 0x77000770, 0x77070770, 0x77070770, 0x77777770, 0x77707770, 0x77000770, 0x0, 0x777000, 0x7707700, 0x0, 0x77070770, 0x77070770, 0x77777770, 0x7707700, 0x0, 0x7777777, 0x7007007, 0x7007007, 0x7007777, 0x7000007, 0x7000007, 0x7777777, 0x0, 0x7700770, 0x70077007, 0x70000007, 0x7000070, 0x70000007, 0x70077007, 0x7700770, 0x0, 0x77000, 0x7700770, 0x7000070, 0x7700770, 0x777700, 0x77000, 0x77000, 0x0, 0x77000, 0x7700770, 0x0, 0x7700770, 0x7700770, 0x7777700, 0x7700000, 0x777700, 0x77700000, 0x70000000, 0x7000000, 0x700770, 0x707007, 0x770, 0x7007, 0x770, 0x77000, 0x70700, 0x77770070, 0x70000007, 0x77770070, 0x70700, 0x77000, 0x0, 0x77000, 0x707000, 0x7007777, 0x70000007, 0x7007777, 0x707000, 0x77000, 0x0, 0x777700, 0x700700, 0x700700, 0x77700777, 0x7000070, 0x700700, 0x77000, 0x0, 0x77000, 0x700700, 0x7000070, 0x77700777, 0x700700, 0x700700, 0x777700, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x77077077, 0x77077077, 0x0, 0x70007777, 0x77077070, 0x70707070, 0x70007070, 0x0, 0x0, 0x0, 0x0, 0x77, 0x770077, 0x77000, 0x7700, 0x770, 0x77077077, 0x77077000, 0x0, 0x0, 0x0, 0x777700, 0x7777770, 0x7777770, 0x777700, 0x0, 0x0, 0x770000, 0x77000, 0x77000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x770000, 0x770000, 0x77000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x770000, 0x77000, 0x7700, 0x7700, 0x77000, 0x770000, 0x0, 0x0, 0x7700, 0x77000, 0x770000, 0x770000, 0x77000, 0x7700, 0x0, 0x77077000, 0x7707700, 0x7707700, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7707700, 0x7707700, 0x770770, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7707700, 0x7707700, 0x770770, 0x0, 0x0, 0x0, 0x777700, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x77777777, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7777770, 0x0, 0x0, 0x0, 0x0, 0x77707770, 0x770077, 0x770077, 0x77770077, 0x770077, 0x770077, 0x77707770, 0x0, 0x0, 0x0, 0x7770770, 0x77077077, 0x77777077, 0x77077, 0x7770770, 0x0, 0x77000, 0x77000, 0x7777770, 0x77000, 0x77000, 0x77000, 0x77000, 0x77000, 0x77000, 0x77000, 0x7777770, 0x77000, 0x7777770, 0x77000, 0x77000, 0x77000, 0x777700, 0x7700770, 0x770, 0x7707777, 0x7700770, 0x7700770, 0x7700770, 0x0, 0x7777700, 0x7700770, 0x7700770, 0x7707777, 0x7700770, 0x7700770, 0x7700770, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x77000, 0x0, 0x77000, 0x77000, 0x77000, 0x77000, 0x77000, 0x0, 0x70000, 0x7777700, 0x77070770, 0x70770, 0x77070770, 0x7777700, 0x70000, 0x0, 0x777000, 0x7707700, 0x7700, 0x777770, 0x7700, 0x7700, 0x7777770, 0x0, 0x0, 0x7700770, 0x777700, 0x7700770, 0x7700770, 0x777700, 0x7700770, 0x0, 0x7700770, 0x777700, 0x77000, 0x77000, 0x7777770, 0x77000, 0x77000, 0x0, 0x77000, 0x77000, 0x77000, 0x0, 0x77000, 0x77000, 0x77000, 0x0, 0x777700, 0x770, 0x777700, 0x7700770, 0x777700, 0x7700000, 0x777700, 0x0, 0x7700770, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x777700, 0x7000070, 0x70077007, 0x70000707, 0x70000707, 0x70077007, 0x7000070, 0x777700, 0x777000, 0x7700000, 0x7777000, 0x7707700, 0x7777000, 0x0, 0x7777700, 0x0, 0x0, 0x77007700, 0x7700770, 0x770077, 0x770077, 0x7700770, 0x77007700, 0x0, 0x7777770, 0x7700000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7777770, 0x0, 0x0, 0x0, 0x0, 0x777700, 0x7000070, 0x70077707, 0x70700707, 0x70077707, 0x70700707, 0x7000070, 0x777700, 0x7777770, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x777700, 0x7700770, 0x777700, 0x0, 0x0, 0x0, 0x0, 0x0, 0x77000, 0x77000, 0x7777770, 0x77000, 0x77000, 0x0, 0x7777770, 0x0, 0x77700, 0x700000, 0x77000, 0x700, 0x777700, 0x0, 0x0, 0x0, 0x77700, 0x700000, 0x77000, 0x700000, 0x77700, 0x0, 0x0, 0x0, 0x770000, 0x77000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x77007700, 0x77007700, 0x77007700, 0x77007700, 0x7777700, 0x770, 0x77000000, 0x7777700, 0x7707770, 0x7707770, 0x7707700, 0x7707700, 0x7777700, 0x0, 0x0, 0x0, 0x0, 0x77000, 0x77000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x77000, 0x7700, 0x7000, 0x7700, 0x7000, 0x7000, 0x77700, 0x0, 0x0, 0x0, 0x777000, 0x7707700, 0x7707700, 0x7707700, 0x777000, 0x0, 0x7777700, 0x0, 0x0, 0x770077, 0x7700770, 0x77007700, 0x77007700, 0x7700770, 0x770077, 0x0, 0x70, 0x77, 0x70, 0x70070, 0x70070, 0x7070000, 0x77770000, 0x7000000, 0x70, 0x77, 0x70, 0x77770070, 0x70000070, 0x77770000, 0x70000, 0x77770000, 0x777, 0x700, 0x777, 0x70700, 0x70777, 0x7070000, 0x77770000, 0x7000000, 0x77000, 0x0, 0x77000, 0x77000, 0x7700, 0x7700770, 0x777700, 0x0, 0x7700, 0x77000, 0x0, 0x777700, 0x7700770, 0x7777770, 0x7700770, 0x0, 0x770000, 0x77000, 0x0, 0x777700, 0x7700770, 0x7777770, 0x7700770, 0x0, 0x77000, 0x7700770, 0x0, 0x777700, 0x7700770, 0x7777770, 0x7700770, 0x0, 0x7707700, 0x770770, 0x0, 0x777700, 0x7700770, 0x7777770, 0x7700770, 0x0, 0x7700770, 0x7700770, 0x0, 0x777700, 0x7700770, 0x7777770, 0x7700770, 0x0, 0x777700, 0x7700770, 0x777700, 0x777700, 0x7700770, 0x7777770, 0x7700770, 0x0, 0x77777700, 0x7700770, 0x7700770, 0x77777770, 0x7700770, 0x7700770, 0x77700770, 0x0, 0x777700, 0x7700770, 0x770, 0x770, 0x7700770, 0x777700, 0x7700, 0x770, 0x7700, 0x77000, 0x7777770, 0x770, 0x777770, 0x770, 0x7777770, 0x0, 0x770000, 0x77000, 0x7777770, 0x770, 0x777770, 0x770, 0x7777770, 0x0, 0x777700, 0x7700770, 0x7777770, 0x770, 0x777770, 0x770, 0x7777770, 0x0, 0x7700770, 0x0, 0x7777770, 0x770, 0x777770, 0x770, 0x7777770, 0x0, 0x7700, 0x77000, 0x0, 0x7777770, 0x77000, 0x77000, 0x7777770, 0x0, 0x770000, 0x77000, 0x0, 0x7777770, 0x77000, 0x77000, 0x7777770, 0x0, 0x777700, 0x7700770, 0x0, 0x7777770, 0x77000, 0x77000, 0x7777770, 0x0, 0x7700770, 0x7700770, 0x0, 0x7777770, 0x77000, 0x77000, 0x7777770, 0x0, 0x77770, 0x770770, 0x7700770, 0x7707777, 0x7700770, 0x770770, 0x77770, 0x0, 0x7707700, 0x770770, 0x0, 0x7700770, 0x7707770, 0x7770770, 0x7700770, 0x0, 0x7700, 0x77000, 0x777700, 0x7700770, 0x7700770, 0x7700770, 0x777700, 0x0, 0x770000, 0x77000, 0x777700, 0x7700770, 0x7700770, 0x7700770, 0x777700, 0x0, 0x777700, 0x7700770, 0x777700, 0x7700770, 0x7700770, 0x7700770, 0x777700, 0x0, 0x7707700, 0x770770, 0x777700, 0x7700770, 0x7700770, 0x7700770, 0x777700, 0x0, 0x7700770, 0x0, 0x777700, 0x7700770, 0x7700770, 0x7700770, 0x777700, 0x0, 0x0, 0x77000770, 0x7707700, 0x777000, 0x777000, 0x7707700, 0x77000770, 0x0, 0x70777700, 0x7700770, 0x7770770, 0x7777770, 0x7707770, 0x7700770, 0x777707, 0x0, 0x7700, 0x77000, 0x7700770, 0x7700770, 0x7700770, 0x7700770, 0x777700, 0x0, 0x770000, 0x77000, 0x7700770, 0x7700770, 0x7700770, 0x7700770, 0x777700, 0x0, 0x777700, 0x7700770, 0x0, 0x7700770, 0x7700770, 0x7700770, 0x777700, 0x0, 0x7700770, 0x0, 0x7700770, 0x7700770, 0x7700770, 0x7700770, 0x777700, 0x0, 0x770000, 0x77000, 0x7700770, 0x7700770, 0x777700, 0x77000, 0x77000, 0x0, 0x7777, 0x770, 0x777770, 0x7700770, 0x777770, 0x770, 0x7777, 0x0, 0x777700, 0x7700770, 0x7700770, 0x770770, 0x7700770, 0x7700770, 0x770770, 0x77, 0x7700, 0x77000, 0x777700, 0x7700000, 0x7777700, 0x7700770, 0x7777700, 0x0, 0x770000, 0x77000, 0x777700, 0x7700000, 0x7777700, 0x7700770, 0x7777700, 0x0, 0x77000, 0x7700770, 0x777700, 0x7700000, 0x7777700, 0x7700770, 0x7777700, 0x0, 0x7707700, 0x770770, 0x777700, 0x7700000, 0x7777700, 0x7700770, 0x7777700, 0x0, 0x7700770, 0x0, 0x777700, 0x7700000, 0x7777700, 0x7700770, 0x7777700, 0x0, 0x777700, 0x7700770, 0x777700, 0x7700000, 0x7777700, 0x7700770, 0x7777700, 0x0, 0x0, 0x0, 0x77777700, 0x70770000, 0x77777700, 0x770770, 0x77777700, 0x0, 0x0, 0x0, 0x777700, 0x7700770, 0x770, 0x7700770, 0x777700, 0x770, 0x7700, 0x77000, 0x777700, 0x7700770, 0x7777770, 0x770, 0x777700, 0x0, 0x770000, 0x77000, 0x777700, 0x7700770, 0x7777770, 0x770, 0x777700, 0x0, 0x777700, 0x7700770, 0x777700, 0x7700770, 0x7777770, 0x770, 0x777700, 0x0, 0x7700770, 0x0, 0x777700, 0x7700770, 0x7777770, 0x770, 0x777700, 0x0, 0x7700, 0x77000, 0x0, 0x77700, 0x77000, 0x77000, 0x777700, 0x0, 0x770000, 0x77000, 0x0, 0x77700, 0x77000, 0x77000, 0x777700, 0x0, 0x777700, 0x7700770, 0x0, 0x77700, 0x77000, 0x77000, 0x777700, 0x0, 0x7700770, 0x0, 0x0, 0x77700, 0x77000, 0x77000, 0x777700, 0x0, 0x77000, 0x7777700, 0x770000, 0x7700000, 0x7777700, 0x7700770, 0x7777700, 0x0, 0x7707700, 0x770770, 0x0, 0x777770, 0x7700770, 0x7700770, 0x7700770, 0x0, 0x7700, 0x77000, 0x0, 0x777700, 0x7700770, 0x7700770, 0x777700, 0x0, 0x770000, 0x77000, 0x0, 0x777700, 0x7700770, 0x7700770, 0x777700, 0x0, 0x777700, 0x7700770, 0x0, 0x777700, 0x7700770, 0x7700770, 0x777700, 0x0, 0x7707700, 0x770770, 0x0, 0x777700, 0x7700770, 0x7700770, 0x777700, 0x0, 0x7700770, 0x0, 0x0, 0x777700, 0x7700770, 0x7700770, 0x777700, 0x0, 0x0, 0x77000, 0x0, 0x77777777, 0x0, 0x77000, 0x0, 0x0, 0x0, 0x7000000, 0x777700, 0x7770770, 0x7707770, 0x7700770, 0x777707, 0x0, 0x7700, 0x77000, 0x0, 0x7700770, 0x7700770, 0x7700770, 0x7777700, 0x0, 0x770000, 0x77000, 0x0, 0x7700770, 0x7700770, 0x7700770, 0x7777700, 0x0, 0x777700, 0x7700770, 0x0, 0x7700770, 0x7700770, 0x7700770, 0x7777700, 0x0, 0x7700770, 0x0, 0x0, 0x7700770, 0x7700770, 0x7700770, 0x7777700, 0x0, 0x770000, 0x77000, 0x7700770, 0x7700770, 0x7700770, 0x7777700, 0x7700000, 0x777700, 0x770, 0x770, 0x777770, 0x7700770, 0x777770, 0x770, 0x770, 0x0, 0x7700770, 0x0, 0x7700770, 0x7700770, 0x7700770, 0x7777700, 0x7700000, 0x777700}; 
-
-
-static void ian_scroll_screen(void){
-	int i;
-	char *j;
-	char *screen_base = (char*)0x2000000;//1F88000;
-	for(i = 8; i < 480 ; i++)
-		for(j = screen_base + i*(640/2) ; j < screen_base + (i+1)*(640/2) ; j++)
-			*(j-(8*(640/2))) = *j;
-	for(i = 479 ; i >= 472 ; i--)
-		for(j = screen_base + i*(640/2) ; j < screen_base + (i+1)*(640/2) ; j++)
-			*j = 0;
-
-}
-
-static void ian_print(char *string){
-        char *screen_base = (char*)0x2000000;
-        static int x, y, first, page;
-        int *temp;
-        int i;
-
-	if(first == 0){
-		first = 1;
-		for(i = 0 ; i < (640/2)*480 ; i++) screen_base[i] = 0;
-	}
-
-        while(*string){
-                if(*string==10){
-                        y++;
-                        x = 0;
-			if(y > 59){
-				y = 59;
-				ian_scroll_screen();
-			}
-		}
-		else if(*string == 8){
-			if(x)
-				x--;
-		}
-		else{
-			if(x > 79){
-				y++;
-				x = 0;
-				if(y > 59){
-					y = 59;
-					ian_scroll_screen();
-				}
-			}
-	
-			temp = (int *)(screen_base + ((640/2)*8*y) + (x * 4));
-			for(i = 0 ; i < 8 ; i++){
-				*temp = charset[i + (*string * 8)];
-				temp += 640/8;
-			}
-			x++;
-		}
-                string++;
-        }
-}
-
-static void ian_print_num(unsigned long value){
-        int i;
-        char out[9];
-
-        for(i = 7; i >= 0 ; i--){
-                out[i] = value & 0x0F;
-                out[i] = out[i]<10?out[i]+'0':out[i]+'A'-10;
-                value = value >> 4;
-        }
-        out[8] = 0;
-
-        ian_print(out);
-
-}
-
-#endif
diff -Nru a/include/asm-arm26/irqchip.h b/include/asm-arm26/irqchip.h
--- a/include/asm-arm26/irqchip.h	2005-03-01 23:39:10 -08:00
+++ b/include/asm-arm26/irqchip.h	2005-03-01 23:39:10 -08:00
@@ -85,23 +85,6 @@
 void set_irq_chip(unsigned int irq, struct irqchip *);
 void set_irq_flags(unsigned int irq, unsigned int flags);
 
-#ifdef not_yet
-/*
- * This is to be used by the top-level machine IRQ decoder only.
- */
-static inline void call_irq(struct pt_regs *regs, unsigned int irq)
-{
-	struct irqdesc *desc = irq_desc + irq;
-
-	spin_lock(&irq_controller_lock);
-	desc->handle(irq, desc, regs);
-	spin_unlock(&irq_controller_lock);
-
-	if (softirq_pending(smp_processor_id()))
-		do_softirq();
-}
-#endif
-
 #define IRQF_VALID	(1 << 0)
 #define IRQF_PROBE	(1 << 1)
 #define IRQF_NOAUTOEN	(1 << 2)
diff -Nru a/include/asm-arm26/pgtable.h b/include/asm-arm26/pgtable.h
--- a/include/asm-arm26/pgtable.h	2005-03-01 23:38:52 -08:00
+++ b/include/asm-arm26/pgtable.h	2005-03-01 23:38:52 -08:00
@@ -11,6 +11,8 @@
 #ifndef _ASMARM_PGTABLE_H
 #define _ASMARM_PGTABLE_H
 
+#include <asm-generic/4level-fixup.h>
+
 #include <linux/config.h>
 #include <asm/memory.h>
 
diff -Nru a/include/asm-arm26/posix_types.h b/include/asm-arm26/posix_types.h
--- a/include/asm-arm26/posix_types.h	2005-03-01 23:39:07 -08:00
+++ b/include/asm-arm26/posix_types.h	2005-03-01 23:39:07 -08:00
@@ -61,19 +61,19 @@
 
 #undef	__FD_SET
 #define __FD_SET(fd, fdsetp) \
-		(((fd_set *)fdsetp)->fds_bits[fd >> 5] |= (1<<(fd & 31)))
+		(((fd_set *)(fdsetp))->fds_bits[(fd) >> 5] |= (1<<((fd) & 31)))
 
 #undef	__FD_CLR
 #define __FD_CLR(fd, fdsetp) \
-		(((fd_set *)fdsetp)->fds_bits[fd >> 5] &= ~(1<<(fd & 31)))
+		(((fd_set *)(fdsetp))->fds_bits[(fd) >> 5] &= ~(1<<((fd) & 31)))
 
 #undef	__FD_ISSET
 #define __FD_ISSET(fd, fdsetp) \
-		((((fd_set *)fdsetp)->fds_bits[fd >> 5] & (1<<(fd & 31))) != 0)
+		((((fd_set *)(fdsetp))->fds_bits[(fd) >> 5] & (1<<((fd) & 31))) != 0)
 
 #undef	__FD_ZERO
 #define __FD_ZERO(fdsetp) \
-		(memset (fdsetp, 0, sizeof (*(fd_set *)fdsetp)))
+		(memset ((fdsetp), 0, sizeof (*(fd_set *)(fdsetp))))
 
 #endif
 
diff -Nru a/include/asm-arm26/processor.h b/include/asm-arm26/processor.h
--- a/include/asm-arm26/processor.h	2005-03-01 23:38:58 -08:00
+++ b/include/asm-arm26/processor.h	2005-03-01 23:38:58 -08:00
@@ -20,9 +20,6 @@
 
 #ifdef __KERNEL__
 
-#define MCA_bus 0
-#define MCA_bus__is_a_macro
-
 #include <asm/atomic.h>
 #include <asm/ptrace.h>
 #include <linux/string.h>
diff -Nru a/include/asm-arm26/resource.h b/include/asm-arm26/resource.h
--- a/include/asm-arm26/resource.h	2005-03-01 23:38:44 -08:00
+++ b/include/asm-arm26/resource.h	2005-03-01 23:38:44 -08:00
@@ -1,51 +1,6 @@
 #ifndef _ARM_RESOURCE_H
 #define _ARM_RESOURCE_H
 
-/*
- * Resource limits
- */
-
-#define RLIMIT_CPU	0		/* CPU time in ms */
-#define RLIMIT_FSIZE	1		/* Maximum filesize */
-#define RLIMIT_DATA	2		/* max data size */
-#define RLIMIT_STACK	3		/* max stack size */
-#define RLIMIT_CORE	4		/* max core file size */
-#define RLIMIT_RSS	5		/* max resident set size */
-#define RLIMIT_NPROC	6		/* max number of processes */
-#define RLIMIT_NOFILE	7		/* max number of open files */
-#define RLIMIT_MEMLOCK	8		/* max locked-in-memory address space */
-#define RLIMIT_AS	9		/* address space limit */
-#define RLIMIT_LOCKS	10		/* maximum file locks held */
-#define RLIMIT_SIGPENDING 11		/* max number of pending signals */
-#define RLIMIT_MSGQUEUE 12		/* maximum bytes in POSIX mqueues */
-
-#define RLIM_NLIMITS	13
-
-#ifdef __KERNEL__
-
-/*
- * SuS says limits have to be unsigned.
- * Which makes a ton more sense anyway.
- */
-#define RLIM_INFINITY	(~0UL)
-
-#define INIT_RLIMITS				\
-{						\
-	{ RLIM_INFINITY, RLIM_INFINITY },	\
-	{ RLIM_INFINITY, RLIM_INFINITY },	\
-	{ RLIM_INFINITY, RLIM_INFINITY },	\
-	{ _STK_LIM,      RLIM_INFINITY },	\
-	{ 0,             RLIM_INFINITY },	\
-	{ RLIM_INFINITY, RLIM_INFINITY },	\
-	{ 0,             0             },	\
-	{ INR_OPEN,      INR_OPEN      },	\
-	{ MLOCK_LIMIT,	 MLOCK_LIMIT   },	\
-	{ RLIM_INFINITY, RLIM_INFINITY },	\
-	{ RLIM_INFINITY, RLIM_INFINITY },	\
-	{ MAX_SIGPENDING, MAX_SIGPENDING},	\
-	{ MQ_BYTES_MAX, MQ_BYTES_MAX},		\
-}
-
-#endif /* __KERNEL__ */
+#include <asm-generic/resource.h>
 
 #endif
diff -Nru a/include/asm-arm26/setup.h b/include/asm-arm26/setup.h
--- a/include/asm-arm26/setup.h	2005-03-01 23:38:53 -08:00
+++ b/include/asm-arm26/setup.h	2005-03-01 23:38:53 -08:00
@@ -171,7 +171,7 @@
 	int (*parse)(const struct tag *);
 };
 
-#define __tag __attribute__((unused, __section__(".taglist")))
+#define __tag __attribute_used__ __attribute__((__section__(".taglist")))
 #define __tagtable(tag, fn) \
 static struct tagtable __tagtable_##fn __tag = { tag, fn }
 
diff -Nru a/include/asm-arm26/system.h b/include/asm-arm26/system.h
--- a/include/asm-arm26/system.h	2005-03-01 23:39:17 -08:00
+++ b/include/asm-arm26/system.h	2005-03-01 23:39:17 -08:00
@@ -4,32 +4,131 @@
 #ifdef __KERNEL__
 
 #include <linux/config.h>
-#include <linux/kernel.h>
-#include <asm/proc-fns.h>
 
-#define vectors_base()  (0)
+/*
+ * This is used to ensure the compiler did actually allocate the register we
+ * asked it for some inline assembly sequences.  Apparently we can't trust
+ * the compiler from one version to another so a bit of paranoia won't hurt.
+ * This string is meant to be concatenated with the inline asm string and
+ * will cause compilation to stop on mismatch. (From ARM32 - may come in handy)
+ */
+#define __asmeq(x, y)  ".ifnc " x "," y " ; .err ; .endif\n\t"
 
-static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size)
-{
-        extern void __bad_xchg(volatile void *, int);
+#ifndef __ASSEMBLY__
 
-        switch (size) {
-                case 1: return cpu_xchg_1(x, ptr);
-                case 4: return cpu_xchg_4(x, ptr);
-                default: __bad_xchg(ptr, size);
-        }
-        return 0;
-}
+#include <linux/linkage.h>
+
+struct thread_info;
+struct task_struct;
+
+#if 0
+/* information about the system we're running on */
+extern unsigned int system_rev;
+extern unsigned int system_serial_low;
+extern unsigned int system_serial_high;
+extern unsigned int mem_fclk_21285;
 
+FIXME - sort this
 /*
  * We need to turn the caches off before calling the reset vector - RiscOS
  * messes up if we don't
  */
 #define proc_hard_reset()       cpu_proc_fin()
 
+#endif
+
+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);
+
+void hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int,
+				       struct pt_regs *),
+		     int sig, const char *name);
+
+#include <asm/proc-fns.h>
+
+#define xchg(ptr,x) \
+	((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
+
+#define tas(ptr) (xchg((ptr),1))
+
+extern asmlinkage void __backtrace(void);
+
+#define set_cr(x)					\
+	__asm__ __volatile__(				\
+	"mcr	p15, 0, %0, c1, c0, 0	@ set CR"	\
+	: : "r" (x) : "cc")
+
+#define get_cr()					\
+	({						\
+	unsigned int __val;				\
+	__asm__ __volatile__(				\
+	"mrc	p15, 0, %0, c1, c0, 0	@ get CR"	\
+	: "=r" (__val) : : "cc");			\
+	__val;						\
+	})
+
+extern unsigned long cr_no_alignment;	/* defined in entry-armv.S */
+extern unsigned long cr_alignment;	/* defined in entry-armv.S */
+
+#define UDBG_UNDEFINED	(1 << 0)
+#define UDBG_SYSCALL	(1 << 1)
+#define UDBG_BADABORT	(1 << 2)
+#define UDBG_SEGV	(1 << 3)
+#define UDBG_BUS	(1 << 4)
+
+extern unsigned int user_debug;
+
+#define vectors_base()	(0)
+
+#define mb() __asm__ __volatile__ ("" : : : "memory")
+#define rmb() mb()
+#define wmb() mb()
+#define nop() __asm__ __volatile__("mov\tr0,r0\t@ nop\n\t");
+
+#define read_barrier_depends() do { } while(0)
+#define set_mb(var, value)  do { var = value; mb(); } while (0)
+#define set_wmb(var, value) do { var = value; wmb(); } while (0)
+
 /*
- * A couple of speedups for the ARM
+ * 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))
+
+/*
+ * switch_to(prev, next) should switch from task `prev' to `next'
+ * `prev' will never be the same as `next'.  schedule() itself
+ * contains the memory barrier to tell GCC not to cache `current'.
+ */
+extern struct task_struct *__switch_to(struct task_struct *, struct thread_info *, struct thread_info *);
+
+#define switch_to(prev,next,last)					\
+do {									\
+	last = __switch_to(prev,prev->thread_info,next->thread_info);	\
+} while (0)
+
+/*
+ * Save the current interrupt enable state & disable IRQs
+ */
+#define local_irq_save(x)                               \
+        do {                                            \
+          unsigned long temp;                           \
+          __asm__ __volatile__(                         \
+"       mov     %0, pc          @ save_flags_cli\n"     \
+"       orr     %1, %0, #0x08000000\n"                  \
+"       and     %0, %0, #0x0c000000\n"                  \
+"       teqp    %1, #0\n"                               \
+          : "=r" (x), "=r" (temp)                       \
+          :                                             \
+          : "memory");                                  \
+        } while (0)
 
 /*
  * Enable IRQs  (sti)
@@ -61,30 +160,31 @@
           : "memory");                          \
         } while(0)
 
-/* Disable FIQs  (clf) */
+/* Enable FIQs (stf) */
 
-#define __clf() do {                            \
+#define __stf() do {                            \
         unsigned long temp;                     \
         __asm__ __volatile__(                   \
-"       mov     %0, pc          @ clf\n"        \
-"       orr     %0, %0, #0x04000000\n"          \
+"       mov     %0, pc          @ stf\n"        \
+"       bic     %0, %0, #0x04000000\n"          \
 "       teqp    %0, #0\n"                       \
         : "=r" (temp));                         \
     } while(0)
 
-/* Enable FIQs (stf) */
+/* Disable FIQs  (clf) */
 
-#define __stf() do {                            \
+#define __clf() do {                            \
         unsigned long temp;                     \
         __asm__ __volatile__(                   \
-"       mov     %0, pc          @ stf\n"        \
-"       bic     %0, %0, #0x04000000\n"          \
+"       mov     %0, pc          @ clf\n"        \
+"       orr     %0, %0, #0x04000000\n"          \
 "       teqp    %0, #0\n"                       \
         : "=r" (temp));                         \
     } while(0)
 
+
 /*
- * save current IRQ & FIQ state
+ * Save the current interrupt enable state.
  */
 #define local_save_flags(x)                             \
         do {                                    \
@@ -94,21 +194,6 @@
           : "=r" (x));                          \
         } while (0)
 
-/*
- * Save the current interrupt enable state & disable IRQs
- */
-#define local_irq_save(x)                               \
-        do {                                            \
-          unsigned long temp;                           \
-          __asm__ __volatile__(                         \
-"       mov     %0, pc          @ save_flags_cli\n"     \
-"       orr     %1, %0, #0x08000000\n"                  \
-"       and     %0, %0, #0x0c000000\n"                  \
-"       teqp    %1, #0\n"                               \
-          : "=r" (x), "=r" (temp)                       \
-          :                                             \
-          : "memory");                                  \
-        } while (0)
 
 /*
  * restore saved IRQ & FIQ state
@@ -127,77 +212,38 @@
         } while (0)
 
 
-struct thread_info;
-
-/* information about the system we're running on */
-extern unsigned int system_rev;
-extern unsigned int system_serial_low;
-extern unsigned int system_serial_high;
-
-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);
-
-void hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int,
-				       struct pt_regs *),
-		     int sig, const char *name);
-
-#define xchg(ptr,x) \
-	((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
-
-#define tas(ptr) (xchg((ptr),1))
-
-extern asmlinkage void __backtrace(void);
-
-/*
- * Include processor dependent parts
- */
-
-#define mb() __asm__ __volatile__ ("" : : : "memory")
-#define rmb() mb()
-#define wmb() mb()
-#define nop() __asm__ __volatile__("mov\tr0,r0\t@ nop\n\t");
-
-#define prepare_to_switch()    do { } while(0)
-
-/*
- * switch_to(prev, next) should switch from task `prev' to `next'
- * `prev' will never be the same as `next'.
- * The `mb' is to tell GCC not to cache `current' across this call.
- */
-struct thread_info;
-
-extern struct task_struct *__switch_to(struct thread_info *, struct thread_info *);
-
-#define switch_to(prev,next,last)                                       \
-        do {                                                            \
-                __switch_to(prev->thread_info,next->thread_info);       \
-                mb();                                                   \
-        } while (0)
-
-
 #ifdef CONFIG_SMP
 #error SMP not supported
-#endif /* CONFIG_SMP */
+#endif
 
-#define irqs_disabled()                 \
-({                                      \
-        unsigned long flags;            \
-        local_save_flags(flags);        \
-        flags & PSR_I_BIT;              \
-})
-
-#define set_mb(var, value)  do { var = value; mb(); } while (0)
 #define smp_mb()		barrier()
 #define smp_rmb()		barrier()
 #define smp_wmb()		barrier()
-#define smp_read_barrier_depends()              do { } while(0)
+#define smp_read_barrier_depends()		do { } while(0)
 
 #define clf()			__clf()
 #define stf()			__stf()
+
+#define irqs_disabled()			\
+({					\
+	unsigned long flags;		\
+	local_save_flags(flags);	\
+	flags & PSR_I_BIT;		\
+})
+
+static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size)
+{
+        extern void __bad_xchg(volatile void *, int);
+
+        switch (size) {
+                case 1: return cpu_xchg_1(x, ptr);
+                case 4: return cpu_xchg_4(x, ptr);
+                default: __bad_xchg(ptr, size);
+        }
+        return 0;
+}
+
+#endif /* __ASSEMBLY__ */
 
 #endif /* __KERNEL__ */
 
diff -Nru a/include/asm-arm26/thread_info.h b/include/asm-arm26/thread_info.h
--- a/include/asm-arm26/thread_info.h	2005-03-01 23:38:54 -08:00
+++ b/include/asm-arm26/thread_info.h	2005-03-01 23:38:54 -08:00
@@ -18,6 +18,7 @@
 struct task_struct;
 struct exec_domain;
 
+#include <linux/compiler.h>
 #include <asm/fpstate.h>
 #include <asm/ptrace.h>
 #include <asm/types.h>
@@ -80,7 +81,7 @@
 }
 
 /* FIXME - PAGE_SIZE < 32K */
-#define THREAD_SIZE		(8192)
+#define THREAD_SIZE		(8*32768) // FIXME - this needs attention (see kernel/fork.c which gets a nice div by zero if this is lower than 8*32768
 #define __get_user_regs(x) (((struct pt_regs *)((unsigned long)(x) + THREAD_SIZE - 8)) - 1)
 
 extern struct thread_info *alloc_thread_info(struct task_struct *task);
@@ -125,6 +126,7 @@
 #define TIF_SYSCALL_TRACE	8
 #define TIF_USED_FPU		16
 #define TIF_POLLING_NRFLAG	17
+#define TIF_MEMDIE		18
 
 #define _TIF_NOTIFY_RESUME	(1 << TIF_NOTIFY_RESUME)
 #define _TIF_SIGPENDING		(1 << TIF_SIGPENDING)
diff -Nru a/include/asm-arm26/tlb.h b/include/asm-arm26/tlb.h
--- a/include/asm-arm26/tlb.h	2005-03-01 23:39:17 -08:00
+++ b/include/asm-arm26/tlb.h	2005-03-01 23:39:17 -08:00
@@ -11,6 +11,7 @@
 struct mmu_gather {
         struct mm_struct        *mm;
         unsigned int            freed;
+	unsigned int            fullmm;
 
         unsigned int            flushes;
         unsigned int            avoided_flushes;
@@ -26,6 +27,7 @@
 
         tlb->mm = mm;
         tlb->freed = 0;
+	tlb->fullmm = full_mm_flush;
 
         return tlb;
 }
@@ -52,8 +54,21 @@
         check_pgt_cache();
 }
 
+
+static inline unsigned int
+tlb_is_full_mm(struct mmu_gather *tlb)
+{
+     return tlb->fullmm;
+}
+
 #define tlb_remove_tlb_entry(tlb,ptep,address)  do { } while (0)
-#define tlb_start_vma(tlb,vma)                  do { } while (0)
+//#define tlb_start_vma(tlb,vma)                  do { } while (0)
+//FIXME - ARM32 uses this now that things changed in the kernel. seems like it may be pointless on arm26, however to get things compiling...
+#define tlb_start_vma(tlb,vma)                                          \
+        do {                                                            \
+                if (!tlb->fullmm)                                       \
+                        flush_cache_range(vma, vma->vm_start, vma->vm_end); \
+        } while (0)
 #define tlb_end_vma(tlb,vma)                    do { } while (0)
 
 #define tlb_remove_page(tlb,page)       free_page_and_swap_cache(page)
diff -Nru a/include/asm-arm26/uaccess.h b/include/asm-arm26/uaccess.h
--- a/include/asm-arm26/uaccess.h	2005-03-01 23:38:52 -08:00
+++ b/include/asm-arm26/uaccess.h	2005-03-01 23:38:52 -08:00
@@ -134,6 +134,39 @@
 extern int __put_user_8(void *, unsigned long long);
 extern int __put_user_bad(void);
 
+#define __put_user_x(__r1,__p,__e,__s)                                  \
+           __asm__ __volatile__ (                                       \
+                __asmeq("%0", "r0") __asmeq("%2", "r1")                 \
+                "bl     __put_user_" #__s                               \
+                : "=&r" (__e)                                           \
+                : "0" (__p), "r" (__r1)                                 \
+                : "ip", "lr", "cc")
+
+#define put_user(x,p)                                                   \
+        ({                                                              \
+                const register typeof(*(p)) __r1 asm("r1") = (x);       \
+                const register typeof(*(p)) *__p asm("r0") = (p);       \
+                register int __e asm("r0");                             \
+                switch (sizeof(*(__p))) {                               \
+                case 1:                                                 \
+                        __put_user_x(__r1, __p, __e, 1);                \
+                        break;                                          \
+                case 2:                                                 \
+                        __put_user_x(__r1, __p, __e, 2);                \
+                        break;                                          \
+                case 4:                                                 \
+                        __put_user_x(__r1, __p, __e, 4);                \
+                        break;                                          \
+                case 8:                                                 \
+                        __put_user_x(__r1, __p, __e, 8);                \
+                        break;                                          \
+                default: __e = __put_user_bad(); break;                 \
+                }                                                       \
+                __e;                                                    \
+        })
+
+#if 0
+/*********************   OLD METHOD *******************/
 #define __put_user_x(__r1,__p,__e,__s,__i...)				\
 	   __asm__ __volatile__ ("bl	__put_user_" #__s		\
 		: "=&r" (__e)						\
@@ -156,12 +189,14 @@
 			__put_user_x(__r1, __p, __e, 4, "r2", "lr");	\
 			break;						\
 		case 8:							\
-			__put_user_x(__r1, __p, __e, 8, "ip", "lr");	\
+			__put_user_x(__r1, __p, __e, 8, "r2", "ip", "lr");	\
 			break;						\
 		default: __e = __put_user_bad(); break;			\
 		}							\
 		__e;							\
 	})
+/*************************************************/
+#endif
 
 #define __put_user(x,ptr)                                               \
 ({                                                                      \
diff -Nru a/include/asm-arm26/unistd.h b/include/asm-arm26/unistd.h
--- a/include/asm-arm26/unistd.h	2005-03-01 23:39:18 -08:00
+++ b/include/asm-arm26/unistd.h	2005-03-01 23:39:18 -08:00
@@ -1,13 +1,14 @@
 /*
  *  linux/include/asm-arm/unistd.h
  *
- *  Copyright (C) 2001 Russell King
+ *  Copyright (C) 2001-2003 Russell King
+ *  Modified 25/11/04 Ian Molton for arm26.
  *
  * 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.
  *
- * Please forward _all_ changes to this file to rmk@arm.linux.org.uk,
+ * Please forward _all_ changes to this file to spyro@f2s.com
  * no matter what the change is.  Thanks!
  */
 #ifndef __ASM_ARM_UNISTD_H
@@ -28,7 +29,7 @@
 #define __NR_write			(__NR_SYSCALL_BASE+  4)
 #define __NR_open			(__NR_SYSCALL_BASE+  5)
 #define __NR_close			(__NR_SYSCALL_BASE+  6)
-#define __NR_waitpid			(__NR_SYSCALL_BASE+  7)
+					/* 7 was sys_waitpid */
 #define __NR_creat			(__NR_SYSCALL_BASE+  8)
 #define __NR_link			(__NR_SYSCALL_BASE+  9)
 #define __NR_unlink			(__NR_SYSCALL_BASE+ 10)
@@ -38,8 +39,8 @@
 #define __NR_mknod			(__NR_SYSCALL_BASE+ 14)
 #define __NR_chmod			(__NR_SYSCALL_BASE+ 15)
 #define __NR_lchown			(__NR_SYSCALL_BASE+ 16)
-#define __NR_break			(__NR_SYSCALL_BASE+ 17)
-
+					/* 17 was sys_break */
+					/* 18 was sys_stat */
 #define __NR_lseek			(__NR_SYSCALL_BASE+ 19)
 #define __NR_getpid			(__NR_SYSCALL_BASE+ 20)
 #define __NR_mount			(__NR_SYSCALL_BASE+ 21)
@@ -49,14 +50,14 @@
 #define __NR_stime			(__NR_SYSCALL_BASE+ 25)
 #define __NR_ptrace			(__NR_SYSCALL_BASE+ 26)
 #define __NR_alarm			(__NR_SYSCALL_BASE+ 27)
-
+					/* 28 was sys_fstat */
 #define __NR_pause			(__NR_SYSCALL_BASE+ 29)
 #define __NR_utime			(__NR_SYSCALL_BASE+ 30)
-#define __NR_stty			(__NR_SYSCALL_BASE+ 31)
-#define __NR_gtty			(__NR_SYSCALL_BASE+ 32)
+					/* 31 was sys_stty */
+					/* 32 was sys_gtty */
 #define __NR_access			(__NR_SYSCALL_BASE+ 33)
 #define __NR_nice			(__NR_SYSCALL_BASE+ 34)
-#define __NR_ftime			(__NR_SYSCALL_BASE+ 35)
+					/* 35 was sys_ftime */
 #define __NR_sync			(__NR_SYSCALL_BASE+ 36)
 #define __NR_kill			(__NR_SYSCALL_BASE+ 37)
 #define __NR_rename			(__NR_SYSCALL_BASE+ 38)
@@ -65,22 +66,22 @@
 #define __NR_dup			(__NR_SYSCALL_BASE+ 41)
 #define __NR_pipe			(__NR_SYSCALL_BASE+ 42)
 #define __NR_times			(__NR_SYSCALL_BASE+ 43)
-#define __NR_prof			(__NR_SYSCALL_BASE+ 44)
+					/* 44 was sys_prof */
 #define __NR_brk			(__NR_SYSCALL_BASE+ 45)
 #define __NR_setgid			(__NR_SYSCALL_BASE+ 46)
 #define __NR_getgid			(__NR_SYSCALL_BASE+ 47)
-#define __NR_signal			(__NR_SYSCALL_BASE+ 48)
+					/* 48 was sys_signal */
 #define __NR_geteuid			(__NR_SYSCALL_BASE+ 49)
 #define __NR_getegid			(__NR_SYSCALL_BASE+ 50)
 #define __NR_acct			(__NR_SYSCALL_BASE+ 51)
 #define __NR_umount2			(__NR_SYSCALL_BASE+ 52)
-#define __NR_lock			(__NR_SYSCALL_BASE+ 53)
+					/* 53 was sys_lock */
 #define __NR_ioctl			(__NR_SYSCALL_BASE+ 54)
 #define __NR_fcntl			(__NR_SYSCALL_BASE+ 55)
-#define __NR_mpx			(__NR_SYSCALL_BASE+ 56)
+					/* 56 was sys_mpx */
 #define __NR_setpgid			(__NR_SYSCALL_BASE+ 57)
-#define __NR_ulimit			(__NR_SYSCALL_BASE+ 58)
-
+					/* 58 was sys_ulimit */
+					/* 59 was sys_olduname */
 #define __NR_umask			(__NR_SYSCALL_BASE+ 60)
 #define __NR_chroot			(__NR_SYSCALL_BASE+ 61)
 #define __NR_ustat			(__NR_SYSCALL_BASE+ 62)
@@ -89,8 +90,8 @@
 #define __NR_getpgrp			(__NR_SYSCALL_BASE+ 65)
 #define __NR_setsid			(__NR_SYSCALL_BASE+ 66)
 #define __NR_sigaction			(__NR_SYSCALL_BASE+ 67)
-#define __NR_sgetmask			(__NR_SYSCALL_BASE+ 68)
-#define __NR_ssetmask			(__NR_SYSCALL_BASE+ 69)
+					/* 68 was sys_sgetmask */
+					/* 69 was sys_ssetmask */
 #define __NR_setreuid			(__NR_SYSCALL_BASE+ 70)
 #define __NR_setregid			(__NR_SYSCALL_BASE+ 71)
 #define __NR_sigsuspend			(__NR_SYSCALL_BASE+ 72)
@@ -105,7 +106,7 @@
 #define __NR_setgroups			(__NR_SYSCALL_BASE+ 81)
 #define __NR_select			(__NR_SYSCALL_BASE+ 82)
 #define __NR_symlink			(__NR_SYSCALL_BASE+ 83)
-
+					/* 84 was sys_lstat */
 #define __NR_readlink			(__NR_SYSCALL_BASE+ 85)
 #define __NR_uselib			(__NR_SYSCALL_BASE+ 86)
 #define __NR_swapon			(__NR_SYSCALL_BASE+ 87)
@@ -119,10 +120,10 @@
 #define __NR_fchown			(__NR_SYSCALL_BASE+ 95)
 #define __NR_getpriority		(__NR_SYSCALL_BASE+ 96)
 #define __NR_setpriority		(__NR_SYSCALL_BASE+ 97)
-#define __NR_profil			(__NR_SYSCALL_BASE+ 98)
+					/* 98 was sys_profil */
 #define __NR_statfs			(__NR_SYSCALL_BASE+ 99)
 #define __NR_fstatfs			(__NR_SYSCALL_BASE+100)
-#define __NR_ioperm			(__NR_SYSCALL_BASE+101)
+					/* 101 was sys_ioperm */
 #define __NR_socketcall			(__NR_SYSCALL_BASE+102)
 #define __NR_syslog			(__NR_SYSCALL_BASE+103)
 #define __NR_setitimer			(__NR_SYSCALL_BASE+104)
@@ -130,10 +131,10 @@
 #define __NR_stat			(__NR_SYSCALL_BASE+106)
 #define __NR_lstat			(__NR_SYSCALL_BASE+107)
 #define __NR_fstat			(__NR_SYSCALL_BASE+108)
-
-
+					/* 109 was sys_uname */
+					/* 110 was sys_iopl */
 #define __NR_vhangup			(__NR_SYSCALL_BASE+111)
-#define __NR_idle			(__NR_SYSCALL_BASE+112)
+					/* 112 was sys_idle */
 #define __NR_syscall			(__NR_SYSCALL_BASE+113) /* syscall to call a syscall! */
 #define __NR_wait4			(__NR_SYSCALL_BASE+114)
 #define __NR_swapoff			(__NR_SYSCALL_BASE+115)
@@ -144,21 +145,21 @@
 #define __NR_clone			(__NR_SYSCALL_BASE+120)
 #define __NR_setdomainname		(__NR_SYSCALL_BASE+121)
 #define __NR_uname			(__NR_SYSCALL_BASE+122)
-#define __NR_modify_ldt			(__NR_SYSCALL_BASE+123)
+					/* 123 was sys_modify_ldt */
 #define __NR_adjtimex			(__NR_SYSCALL_BASE+124)
 #define __NR_mprotect			(__NR_SYSCALL_BASE+125)
 #define __NR_sigprocmask		(__NR_SYSCALL_BASE+126)
-#define __NR_create_module		(__NR_SYSCALL_BASE+127)
+					/* 127 was sys_create_module */
 #define __NR_init_module		(__NR_SYSCALL_BASE+128)
 #define __NR_delete_module		(__NR_SYSCALL_BASE+129)
-#define __NR_get_kernel_syms		(__NR_SYSCALL_BASE+130)
+					/* 130 was sys_get_kernel_syms */
 #define __NR_quotactl			(__NR_SYSCALL_BASE+131)
 #define __NR_getpgid			(__NR_SYSCALL_BASE+132)
 #define __NR_fchdir			(__NR_SYSCALL_BASE+133)
 #define __NR_bdflush			(__NR_SYSCALL_BASE+134)
 #define __NR_sysfs			(__NR_SYSCALL_BASE+135)
 #define __NR_personality		(__NR_SYSCALL_BASE+136)
-#define __NR_afs_syscall		(__NR_SYSCALL_BASE+137) /* Syscall for Andrew File System */
+					/* 137 was sys_afs_syscall */
 #define __NR_setfsuid			(__NR_SYSCALL_BASE+138)
 #define __NR_setfsgid			(__NR_SYSCALL_BASE+139)
 #define __NR__llseek			(__NR_SYSCALL_BASE+140)
@@ -187,8 +188,8 @@
 #define __NR_mremap			(__NR_SYSCALL_BASE+163)
 #define __NR_setresuid			(__NR_SYSCALL_BASE+164)
 #define __NR_getresuid			(__NR_SYSCALL_BASE+165)
-#define __NR_vm86			(__NR_SYSCALL_BASE+166)
-#define __NR_query_module		(__NR_SYSCALL_BASE+167)
+					/* 166 was sys_vm86 */
+					/* 167 was sys_query_module */
 #define __NR_poll			(__NR_SYSCALL_BASE+168)
 #define __NR_nfsservctl			(__NR_SYSCALL_BASE+169)
 #define __NR_setresgid			(__NR_SYSCALL_BASE+170)
@@ -244,7 +245,7 @@
 #define __NR_madvise			(__NR_SYSCALL_BASE+220)
 #define __NR_fcntl64			(__NR_SYSCALL_BASE+221)
 					/* 222 for tux */
-#define __NR_security			(__NR_SYSCALL_BASE+223)
+					/* 223 is unused */
 #define __NR_gettid			(__NR_SYSCALL_BASE+224)
 #define __NR_readahead			(__NR_SYSCALL_BASE+225)
 #define __NR_setxattr			(__NR_SYSCALL_BASE+226)
@@ -260,21 +261,62 @@
 #define __NR_lremovexattr		(__NR_SYSCALL_BASE+236)
 #define __NR_fremovexattr		(__NR_SYSCALL_BASE+237)
 #define __NR_tkill			(__NR_SYSCALL_BASE+238)
+#define __NR_sendfile64			(__NR_SYSCALL_BASE+239)
+#define __NR_futex			(__NR_SYSCALL_BASE+240)
+#define __NR_sched_setaffinity		(__NR_SYSCALL_BASE+241)
+#define __NR_sched_getaffinity		(__NR_SYSCALL_BASE+242)
+#define __NR_io_setup			(__NR_SYSCALL_BASE+243)
+#define __NR_io_destroy			(__NR_SYSCALL_BASE+244)
+#define __NR_io_getevents		(__NR_SYSCALL_BASE+245)
+#define __NR_io_submit			(__NR_SYSCALL_BASE+246)
+#define __NR_io_cancel			(__NR_SYSCALL_BASE+247)
+#define __NR_exit_group			(__NR_SYSCALL_BASE+248)
+#define __NR_lookup_dcookie		(__NR_SYSCALL_BASE+249)
+#define __NR_epoll_create		(__NR_SYSCALL_BASE+250)
+#define __NR_epoll_ctl			(__NR_SYSCALL_BASE+251)
+#define __NR_epoll_wait			(__NR_SYSCALL_BASE+252)
+#define __NR_remap_file_pages		(__NR_SYSCALL_BASE+253)
+					/* 254 for set_thread_area */
+					/* 255 for get_thread_area */
+					/* 256 for set_tid_address */
+#define __NR_timer_create		(__NR_SYSCALL_BASE+257)
+#define __NR_timer_settime		(__NR_SYSCALL_BASE+258)
+#define __NR_timer_gettime		(__NR_SYSCALL_BASE+259)
+#define __NR_timer_getoverrun		(__NR_SYSCALL_BASE+260)
+#define __NR_timer_delete		(__NR_SYSCALL_BASE+261)
+#define __NR_clock_settime		(__NR_SYSCALL_BASE+262)
+#define __NR_clock_gettime		(__NR_SYSCALL_BASE+263)
+#define __NR_clock_getres		(__NR_SYSCALL_BASE+264)
+#define __NR_clock_nanosleep		(__NR_SYSCALL_BASE+265)
+#define __NR_statfs64			(__NR_SYSCALL_BASE+266)
+#define __NR_fstatfs64			(__NR_SYSCALL_BASE+267)
+#define __NR_tgkill			(__NR_SYSCALL_BASE+268)
+#define __NR_utimes			(__NR_SYSCALL_BASE+269)
+#define __NR_fadvise64_64		(__NR_SYSCALL_BASE+270)
+#define __NR_pciconfig_iobase		(__NR_SYSCALL_BASE+271)
+#define __NR_pciconfig_read		(__NR_SYSCALL_BASE+272)
+#define __NR_pciconfig_write		(__NR_SYSCALL_BASE+273)
+#define __NR_mq_open			(__NR_SYSCALL_BASE+274)
+#define __NR_mq_unlink			(__NR_SYSCALL_BASE+275)
+#define __NR_mq_timedsend		(__NR_SYSCALL_BASE+276)
+#define __NR_mq_timedreceive		(__NR_SYSCALL_BASE+277)
+#define __NR_mq_notify			(__NR_SYSCALL_BASE+278)
+#define __NR_mq_getsetattr		(__NR_SYSCALL_BASE+279)
+#define __NR_waitid			(__NR_SYSCALL_BASE+280)
 
 /*
- * The following SWIs are ARM private.
+ * The following SWIs are ARM private. FIXME - make appropriate for arm26
  */
 #define __ARM_NR_BASE			(__NR_SYSCALL_BASE+0x0f0000)
 #define __ARM_NR_breakpoint		(__ARM_NR_BASE+1)
 #define __ARM_NR_cacheflush		(__ARM_NR_BASE+2)
 #define __ARM_NR_usr26			(__ARM_NR_BASE+3)
-#define __ARM_NR_usr32			(__ARM_NR_BASE+4)
 
 #define __sys2(x) #x
 #define __sys1(x) __sys2(x)
 
 #ifndef __syscall
-#define __syscall(name) "swi\t" __sys1(__NR_##name) "\n\t"
+#define __syscall(name) "swi\t" __sys1(__NR_##name) ""
 #endif
 
 #define __syscall_return(type, res)					\
@@ -288,106 +330,128 @@
 
 #define _syscall0(type,name)						\
 type name(void) {							\
+  register long __res_r0 __asm__("r0");					\
   long __res;								\
   __asm__ __volatile__ (						\
   __syscall(name)							\
-  "mov %0,r0"								\
-  :"=r" (__res) : : "r0","lr");						\
+	: "=r" (__res_r0)						\
+	:								\
+	: "lr");							\
+  __res = __res_r0;							\
   __syscall_return(type,__res);						\
 }
 
-#define _syscall1(type,name,type1,arg1)					\
-type name(type1 arg1) {							\
+#define _syscall1(type,name,type1,arg1) 				\
+type name(type1 arg1) { 						\
+  register long __r0 __asm__("r0") = (long)arg1;			\
+  register long __res_r0 __asm__("r0");					\
   long __res;								\
   __asm__ __volatile__ (						\
-  "mov\tr0,%1\n\t"							\
   __syscall(name)							\
-  "mov %0,r0"								\
-        : "=r" (__res)							\
-        : "r" ((long)(arg1))						\
-	: "r0","lr");							\
+	: "=r" (__res_r0)						\
+	: "r" (__r0)							\
+	: "lr");							\
+  __res = __res_r0;							\
   __syscall_return(type,__res);						\
 }
 
 #define _syscall2(type,name,type1,arg1,type2,arg2)			\
 type name(type1 arg1,type2 arg2) {					\
+  register long __r0 __asm__("r0") = (long)arg1;			\
+  register long __r1 __asm__("r1") = (long)arg2;			\
+  register long __res_r0 __asm__("r0");					\
   long __res;								\
   __asm__ __volatile__ (						\
-  "mov\tr0,%1\n\t"							\
-  "mov\tr1,%2\n\t"							\
   __syscall(name)							\
-  "mov\t%0,r0"								\
-        : "=r" (__res)							\
-        : "r" ((long)(arg1)),"r" ((long)(arg2))				\
-	: "r0","r1","lr");						\
+	: "=r" (__res_r0)						\
+	: "r" (__r0),"r" (__r1) 					\
+	: "lr");							\
+  __res = __res_r0;							\
   __syscall_return(type,__res);						\
 }
 
 
 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3)		\
 type name(type1 arg1,type2 arg2,type3 arg3) {				\
+  register long __r0 __asm__("r0") = (long)arg1;			\
+  register long __r1 __asm__("r1") = (long)arg2;			\
+  register long __r2 __asm__("r2") = (long)arg3;			\
+  register long __res_r0 __asm__("r0");					\
   long __res;								\
   __asm__ __volatile__ (						\
-  "mov\tr0,%1\n\t"							\
-  "mov\tr1,%2\n\t"							\
-  "mov\tr2,%3\n\t"							\
   __syscall(name)							\
-  "mov\t%0,r0"								\
-        : "=r" (__res)							\
-        : "r" ((long)(arg1)),"r" ((long)(arg2)),"r" ((long)(arg3))	\
-        : "r0","r1","r2","lr");						\
+	: "=r" (__res_r0)						\
+	: "r" (__r0),"r" (__r1),"r" (__r2)				\
+	: "lr");							\
+  __res = __res_r0;							\
   __syscall_return(type,__res);						\
 }
 
 
-#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4)		\
-type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4) {				\
-  long __res;										\
-  __asm__ __volatile__ (								\
-  "mov\tr0,%1\n\t"									\
-  "mov\tr1,%2\n\t"									\
-  "mov\tr2,%3\n\t"									\
-  "mov\tr3,%4\n\t"									\
-  __syscall(name)									\
-  "mov\t%0,r0"										\
-  	: "=r" (__res)									\
-  	: "r" ((long)(arg1)),"r" ((long)(arg2)),"r" ((long)(arg3)),"r" ((long)(arg4))	\
-  	: "r0","r1","r2","r3","lr");							\
-  __syscall_return(type,__res);								\
+#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4)\
+type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4) {		\
+  register long __r0 __asm__("r0") = (long)arg1;			\
+  register long __r1 __asm__("r1") = (long)arg2;			\
+  register long __r2 __asm__("r2") = (long)arg3;			\
+  register long __r3 __asm__("r3") = (long)arg4;			\
+  register long __res_r0 __asm__("r0");					\
+  long __res;								\
+  __asm__ __volatile__ (						\
+  __syscall(name)							\
+	: "=r" (__res_r0)						\
+	: "r" (__r0),"r" (__r1),"r" (__r2),"r" (__r3)			\
+	: "lr");							\
+  __res = __res_r0;							\
+  __syscall_return(type,__res);						\
 }
   
 
 #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) {			\
-  long __res;										\
-  __asm__ __volatile__ (								\
-  "mov\tr0,%1\n\t"									\
-  "mov\tr1,%2\n\t"									\
-  "mov\tr2,%3\n\t"									\
-  "mov\tr3,%4\n\t"									\
-  "mov\tr4,%5\n\t"									\
-  __syscall(name)									\
-  "mov\t%0,r0"										\
-  	: "=r" (__res)									\
-  	: "r" ((long)(arg1)),"r" ((long)(arg2)),"r" ((long)(arg3)),"r" ((long)(arg4)),	\
-	  "r" ((long)(arg5))								\
-	: "r0","r1","r2","r3","r4","lr");						\
-  __syscall_return(type,__res);								\
+type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) {	\
+  register long __r0 __asm__("r0") = (long)arg1;			\
+  register long __r1 __asm__("r1") = (long)arg2;			\
+  register long __r2 __asm__("r2") = (long)arg3;			\
+  register long __r3 __asm__("r3") = (long)arg4;			\
+  register long __r4 __asm__("r4") = (long)arg5;			\
+  register long __res_r0 __asm__("r0");					\
+  long __res;								\
+  __asm__ __volatile__ (						\
+  __syscall(name)							\
+	: "=r" (__res_r0)						\
+	: "r" (__r0),"r" (__r1),"r" (__r2),"r" (__r3),"r" (__r4)	\
+	: "lr");							\
+  __res = __res_r0;							\
+  __syscall_return(type,__res);						\
+}
+
+#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 __r0 __asm__("r0") = (long)arg1;			\
+  register long __r1 __asm__("r1") = (long)arg2;			\
+  register long __r2 __asm__("r2") = (long)arg3;			\
+  register long __r3 __asm__("r3") = (long)arg4;			\
+  register long __r4 __asm__("r4") = (long)arg5;			\
+  register long __r5 __asm__("r5") = (long)arg6;			\
+  register long __res_r0 __asm__("r0");					\
+  long __res;								\
+  __asm__ __volatile__ (						\
+  __syscall(name)							\
+	: "=r" (__res_r0)						\
+	: "r" (__r0),"r" (__r1),"r" (__r2),"r" (__r3), "r" (__r4),"r" (__r5)		\
+	: "lr");							\
+  __res = __res_r0;							\
+  __syscall_return(type,__res);						\
 }
 
 #ifdef __KERNEL__
 #define __ARCH_WANT_IPC_PARSE_VERSION
 #define __ARCH_WANT_OLD_READDIR
-#define __ARCH_WANT_OLD_STAT
 #define __ARCH_WANT_STAT64
 #define __ARCH_WANT_SYS_ALARM
 #define __ARCH_WANT_SYS_GETHOSTNAME
 #define __ARCH_WANT_SYS_PAUSE
-#define __ARCH_WANT_SYS_SGETMASK
-#define __ARCH_WANT_SYS_SIGNAL
 #define __ARCH_WANT_SYS_TIME
 #define __ARCH_WANT_SYS_UTIME
-#define __ARCH_WANT_SYS_WAITPID
 #define __ARCH_WANT_SYS_SOCKETCALL
 #define __ARCH_WANT_SYS_FADVISE64
 #define __ARCH_WANT_SYS_GETPGRP
@@ -406,76 +470,7 @@
 #include <linux/types.h>
 #include <linux/syscalls.h>
 
-static inline long idle(void)
-{
-	extern long sys_idle(void);
-	return sys_idle();
-}
-
-static inline long pause(void)
-{
-	return sys_pause();
-}
-
-static inline long sync(void)
-{
-	return sys_sync();
-}
-
-static inline pid_t setsid(void)
-{
-	return sys_setsid();
-}
-
-static inline long write(int fd, const char *buf, off_t count)
-{
-	return sys_write(fd, buf, count);
-}
-
-static inline long read(int fd, char *buf, off_t count)
-{
-	return sys_read(fd, buf, count);
-}
-
-static inline off_t lseek(int fd, off_t offset, int count)
-{
-	return sys_lseek(fd, offset, count);
-}
-
-static inline long dup(int fd)
-{
-	return sys_dup(fd);
-}
-
-static inline long open(const char *file, int flag, int mode)
-{
-	return sys_open(file, flag, mode);
-}
-
-static inline long close(int fd)
-{
-	return sys_close(fd);
-}
-
-static inline long _exit(int exitcode)
-{
-	return sys_exit(exitcode);
-}
-
-static inline pid_t waitpid(pid_t pid, int *wait_stat, int options)
-{
-	return sys_wait4((int)pid, wait_stat, options, NULL);
-}
-
-static inline long delete_module(const char *name)
-{
-	return sys_delete_module(name, 0);
-}
-
-static inline pid_t wait(int * wait_stat)
-{
-	return sys_wait4(-1, wait_stat, 0, NULL);
-}
+extern long execve(const char *file, char **argv, char **envp);
 
 struct pt_regs;
 asmlinkage int sys_execve(char *filenamei, char **argv, char **envp,
@@ -491,12 +486,6 @@
 				const struct sigaction __user *act,
 				struct sigaction __user *oact,
 				size_t sigsetsize);
-
-/*
- * The following two can't be eliminated yet - they rely on
- * specific conditions.
- */
-static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp);
 
 #endif
 
diff -Nru a/include/asm-cris/cputime.h b/include/asm-cris/cputime.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-cris/cputime.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,6 @@
+#ifndef __CRIS_CPUTIME_H
+#define __CRIS_CPUTIME_H
+
+#include <asm-generic/cputime.h>
+
+#endif /* __CRIS_CPUTIME_H */
diff -Nru a/include/asm-cris/hardirq.h b/include/asm-cris/hardirq.h
--- a/include/asm-cris/hardirq.h	2005-03-01 23:38:55 -08:00
+++ b/include/asm-cris/hardirq.h	2005-03-01 23:38:55 -08:00
@@ -9,10 +9,6 @@
 /* entry.S is sensitive to the offsets of these fields */
 typedef struct {
 	unsigned int __softirq_pending;
-	unsigned int __local_irq_count;
-	unsigned int __local_bh_count;
-	unsigned int __syscall_count;
-	struct task_struct * __ksoftirqd_task; /* waitqueue is too large */
 } ____cacheline_aligned irq_cpustat_t;
 
 #include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
@@ -27,14 +23,5 @@
 #if (1 << HARDIRQ_BITS) < NR_IRQS
 # error HARDIRQ_BITS is too low!
 #endif
-
-#define irq_enter()		(preempt_count() += HARDIRQ_OFFSET)
-#define irq_exit()							\
-do {									\
-		preempt_count() -= IRQ_EXIT_OFFSET;			\
-		if (!in_interrupt() && softirq_pending(smp_processor_id())) \
-			do_softirq();					\
-		preempt_enable_no_resched();				\
-} while (0)
 
 #endif /* __ASM_HARDIRQ_H */
diff -Nru a/include/asm-cris/page.h b/include/asm-cris/page.h
--- a/include/asm-cris/page.h	2005-03-01 23:38:54 -08:00
+++ b/include/asm-cris/page.h	2005-03-01 23:38:54 -08:00
@@ -21,6 +21,9 @@
 #define clear_user_page(page, vaddr, pg)    clear_page(page)
 #define copy_user_page(to, from, vaddr, pg) copy_page(to, from)
 
+#define alloc_zeroed_user_highpage(vma, vaddr) alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO, vma, vaddr)
+#define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE
+
 /*
  * These are used to make use of C type-checking..
  */
diff -Nru a/include/asm-cris/pgalloc.h b/include/asm-cris/pgalloc.h
--- a/include/asm-cris/pgalloc.h	2005-03-01 23:39:09 -08:00
+++ b/include/asm-cris/pgalloc.h	2005-03-01 23:39:09 -08:00
@@ -24,18 +24,14 @@
 
 extern inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
 {
-  	pte_t *pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT);
-	if (pte)
-		clear_page(pte);
+  	pte_t *pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO);
  	return pte;
 }
 
 extern inline struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address)
 {
 	struct page *pte;
-	pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT, 0);
-	if (pte)
-		clear_page(page_address(pte));
+	pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0);
 	return pte;
 }
 
diff -Nru a/include/asm-cris/pgtable.h b/include/asm-cris/pgtable.h
--- a/include/asm-cris/pgtable.h	2005-03-01 23:38:51 -08:00
+++ b/include/asm-cris/pgtable.h	2005-03-01 23:38:51 -08:00
@@ -5,6 +5,8 @@
 #ifndef _CRIS_PGTABLE_H
 #define _CRIS_PGTABLE_H
 
+#include <asm-generic/4level-fixup.h>
+
 #ifndef __ASSEMBLY__
 #include <linux/config.h>
 #include <linux/sched.h>
diff -Nru a/include/asm-cris/resource.h b/include/asm-cris/resource.h
--- a/include/asm-cris/resource.h	2005-03-01 23:39:07 -08:00
+++ b/include/asm-cris/resource.h	2005-03-01 23:39:07 -08:00
@@ -1,51 +1,6 @@
 #ifndef _CRIS_RESOURCE_H
 #define _CRIS_RESOURCE_H
 
-/*
- * Resource limits
- */
-
-#define RLIMIT_CPU	0		/* CPU time in ms */
-#define RLIMIT_FSIZE	1		/* Maximum filesize */
-#define RLIMIT_DATA	2		/* max data size */
-#define RLIMIT_STACK	3		/* max stack size */
-#define RLIMIT_CORE	4		/* max core file size */
-#define RLIMIT_RSS	5		/* max resident set size */
-#define RLIMIT_NPROC	6		/* max number of processes */
-#define RLIMIT_NOFILE	7		/* max number of open files */
-#define RLIMIT_MEMLOCK	8		/* max locked-in-memory address space */
-#define RLIMIT_AS	9		/* address space limit */
-#define RLIMIT_LOCKS	10		/* maximum file locks held */
-#define RLIMIT_SIGPENDING 11		/* max number of pending signals */
-#define RLIMIT_MSGQUEUE 12		/* maximum bytes in POSIX mqueues */
-
-#define RLIM_NLIMITS	13
-
-/*
- * SuS says limits have to be unsigned.
- * Which makes a ton more sense anyway.
- */
-#define RLIM_INFINITY	(~0UL)
-
-#ifdef __KERNEL__
-
-#define INIT_RLIMITS					\
-{							\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{      _STK_LIM, RLIM_INFINITY },		\
-	{             0, RLIM_INFINITY },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{             0,             0 },		\
-	{      INR_OPEN,     INR_OPEN  },		\
-	{   MLOCK_LIMIT,   MLOCK_LIMIT },               \
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{ MAX_SIGPENDING, MAX_SIGPENDING },		\
-	{ MQ_BYTES_MAX, MQ_BYTES_MAX },			\
-}
-
-#endif /* __KERNEL__ */
+#include <asm-generic/resource.h>
 
 #endif
diff -Nru a/include/asm-cris/thread_info.h b/include/asm-cris/thread_info.h
--- a/include/asm-cris/thread_info.h	2005-03-01 23:39:17 -08:00
+++ b/include/asm-cris/thread_info.h	2005-03-01 23:39:17 -08:00
@@ -85,6 +85,7 @@
 #define TIF_SIGPENDING		2	/* signal pending */
 #define TIF_NEED_RESCHED	3	/* rescheduling necessary */
 #define TIF_POLLING_NRFLAG	16	/* true if poll_idle() is polling TIF_NEED_RESCHED */
+#define TIF_MEMDIE		17
 
 #define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE)
 #define _TIF_NOTIFY_RESUME	(1<<TIF_NOTIFY_RESUME)
diff -Nru a/include/asm-frv/a.out.h b/include/asm-frv/a.out.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/a.out.h	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,5 @@
+/*
+ * FRV doesn't do AOUT format. This header file should be removed as
+ * soon as fs/exec.c and fs/proc/kcore.c and the archs that require
+ * them to include linux/a.out.h are fixed.
+ */
diff -Nru a/include/asm-frv/atomic.h b/include/asm-frv/atomic.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/atomic.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,417 @@
+/* atomic.h: atomic operation emulation for FR-V
+ *
+ * For an explanation of how atomic ops work in this arch, see:
+ *   Documentation/fujitsu/frv/atomic-ops.txt
+ *
+ * Copyright (C) 2004 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.
+ */
+#ifndef _ASM_ATOMIC_H
+#define _ASM_ATOMIC_H
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <asm/spr-regs.h>
+
+#ifdef CONFIG_SMP
+#error not SMP safe
+#endif
+
+/*
+ * Atomic operations that C can't guarantee us.  Useful for
+ * resource counting etc..
+ *
+ * We do not have SMP systems, so we don't have to deal with that.
+ */
+
+/* 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()
+
+typedef struct {
+	int counter;
+} atomic_t;
+
+#define ATOMIC_INIT(i)		{ (i) }
+#define atomic_read(v)		((v)->counter)
+#define atomic_set(v, i)	(((v)->counter) = (i))
+
+#ifndef CONFIG_FRV_OUTOFLINE_ATOMIC_OPS
+static inline int atomic_add_return(int i, atomic_t *v)
+{
+	unsigned long val;
+
+	asm("0:						\n"
+	    "	orcc		gr0,gr0,gr0,icc3	\n"	/* set ICC3.Z */
+	    "	ckeq		icc3,cc7		\n"
+	    "	ld.p		%M0,%1			\n"	/* LD.P/ORCR must be atomic */
+	    "	orcr		cc7,cc7,cc3		\n"	/* set CC3 to true */
+	    "	add%I2		%1,%2,%1		\n"
+	    "	cst.p		%1,%M0		,cc3,#1	\n"
+	    "	corcc		gr29,gr29,gr0	,cc3,#1	\n"	/* clear ICC3.Z if store happens */
+	    "	beq		icc3,#0,0b		\n"
+	    : "+U"(v->counter), "=&r"(val)
+	    : "NPr"(i)
+	    : "memory", "cc7", "cc3", "icc3"
+	    );
+
+	return val;
+}
+
+static inline int atomic_sub_return(int i, atomic_t *v)
+{
+	unsigned long val;
+
+	asm("0:						\n"
+	    "	orcc		gr0,gr0,gr0,icc3	\n"	/* set ICC3.Z */
+	    "	ckeq		icc3,cc7		\n"
+	    "	ld.p		%M0,%1			\n"	/* LD.P/ORCR must be atomic */
+	    "	orcr		cc7,cc7,cc3		\n"	/* set CC3 to true */
+	    "	sub%I2		%1,%2,%1		\n"
+	    "	cst.p		%1,%M0		,cc3,#1	\n"
+	    "	corcc		gr29,gr29,gr0	,cc3,#1	\n"	/* clear ICC3.Z if store happens */
+	    "	beq		icc3,#0,0b		\n"
+	    : "+U"(v->counter), "=&r"(val)
+	    : "NPr"(i)
+	    : "memory", "cc7", "cc3", "icc3"
+	    );
+
+	return val;
+}
+
+#else
+
+extern int atomic_add_return(int i, atomic_t *v);
+extern int atomic_sub_return(int i, atomic_t *v);
+
+#endif
+
+static inline int atomic_add_negative(int i, atomic_t *v)
+{
+	return atomic_add_return(i, v) < 0;
+}
+
+static inline void atomic_add(int i, atomic_t *v)
+{
+	atomic_add_return(i, v);
+}
+
+static inline void atomic_sub(int i, atomic_t *v)
+{
+	atomic_sub_return(i, v);
+}
+
+static inline void atomic_inc(atomic_t *v)
+{
+	atomic_add_return(1, v);
+}
+
+static inline void atomic_dec(atomic_t *v)
+{
+	atomic_sub_return(1, v);
+}
+
+#define atomic_dec_return(v)		atomic_sub_return(1, (v))
+#define atomic_inc_return(v)		atomic_add_return(1, (v))
+
+#define atomic_sub_and_test(i,v)	(atomic_sub_return((i), (v)) == 0)
+#define atomic_dec_and_test(v)		(atomic_sub_return(1, (v)) == 0)
+#define atomic_inc_and_test(v)		(atomic_add_return(1, (v)) == 0)
+
+#ifndef CONFIG_FRV_OUTOFLINE_ATOMIC_OPS
+static inline
+unsigned long atomic_test_and_ANDNOT_mask(unsigned long mask, volatile unsigned long *v)
+{
+	unsigned long old, tmp;
+
+	asm volatile(
+		"0:						\n"
+		"	orcc		gr0,gr0,gr0,icc3	\n"	/* set ICC3.Z */
+		"	ckeq		icc3,cc7		\n"
+		"	ld.p		%M0,%1			\n"	/* LD.P/ORCR are atomic */
+		"	orcr		cc7,cc7,cc3		\n"	/* set CC3 to true */
+		"	and%I3		%1,%3,%2		\n"
+		"	cst.p		%2,%M0		,cc3,#1	\n"	/* if store happens... */
+		"	corcc		gr29,gr29,gr0	,cc3,#1	\n"	/* ... clear ICC3.Z */
+		"	beq		icc3,#0,0b		\n"
+		: "+U"(*v), "=&r"(old), "=r"(tmp)
+		: "NPr"(~mask)
+		: "memory", "cc7", "cc3", "icc3"
+		);
+
+	return old;
+}
+
+static inline
+unsigned long atomic_test_and_OR_mask(unsigned long mask, volatile unsigned long *v)
+{
+	unsigned long old, tmp;
+
+	asm volatile(
+		"0:						\n"
+		"	orcc		gr0,gr0,gr0,icc3	\n"	/* set ICC3.Z */
+		"	ckeq		icc3,cc7		\n"
+		"	ld.p		%M0,%1			\n"	/* LD.P/ORCR are atomic */
+		"	orcr		cc7,cc7,cc3		\n"	/* set CC3 to true */
+		"	or%I3		%1,%3,%2		\n"
+		"	cst.p		%2,%M0		,cc3,#1	\n"	/* if store happens... */
+		"	corcc		gr29,gr29,gr0	,cc3,#1	\n"	/* ... clear ICC3.Z */
+		"	beq		icc3,#0,0b		\n"
+		: "+U"(*v), "=&r"(old), "=r"(tmp)
+		: "NPr"(mask)
+		: "memory", "cc7", "cc3", "icc3"
+		);
+
+	return old;
+}
+
+static inline
+unsigned long atomic_test_and_XOR_mask(unsigned long mask, volatile unsigned long *v)
+{
+	unsigned long old, tmp;
+
+	asm volatile(
+		"0:						\n"
+		"	orcc		gr0,gr0,gr0,icc3	\n"	/* set ICC3.Z */
+		"	ckeq		icc3,cc7		\n"
+		"	ld.p		%M0,%1			\n"	/* LD.P/ORCR are atomic */
+		"	orcr		cc7,cc7,cc3		\n"	/* set CC3 to true */
+		"	xor%I3		%1,%3,%2		\n"
+		"	cst.p		%2,%M0		,cc3,#1	\n"	/* if store happens... */
+		"	corcc		gr29,gr29,gr0	,cc3,#1	\n"	/* ... clear ICC3.Z */
+		"	beq		icc3,#0,0b		\n"
+		: "+U"(*v), "=&r"(old), "=r"(tmp)
+		: "NPr"(mask)
+		: "memory", "cc7", "cc3", "icc3"
+		);
+
+	return old;
+}
+
+#else
+
+extern unsigned long atomic_test_and_ANDNOT_mask(unsigned long mask, volatile unsigned long *v);
+extern unsigned long atomic_test_and_OR_mask(unsigned long mask, volatile unsigned long *v);
+extern unsigned long atomic_test_and_XOR_mask(unsigned long mask, volatile unsigned long *v);
+
+#endif
+
+#define atomic_clear_mask(mask, v)	atomic_test_and_ANDNOT_mask((mask), (v))
+#define atomic_set_mask(mask, v)	atomic_test_and_OR_mask((mask), (v))
+
+/*****************************************************************************/
+/*
+ * exchange value with memory
+ */
+#ifndef CONFIG_FRV_OUTOFLINE_ATOMIC_OPS
+
+#define xchg(ptr, x)								\
+({										\
+	__typeof__(ptr) __xg_ptr = (ptr);					\
+	__typeof__(*(ptr)) __xg_orig;						\
+										\
+	switch (sizeof(__xg_orig)) {						\
+	case 1:									\
+		asm volatile(							\
+			"0:						\n"	\
+			"	orcc		gr0,gr0,gr0,icc3	\n"	\
+			"	ckeq		icc3,cc7		\n"	\
+			"	ldub.p		%M0,%1			\n"	\
+			"	orcr		cc7,cc7,cc3		\n"	\
+			"	cstb.p		%2,%M0		,cc3,#1	\n"	\
+			"	corcc		gr29,gr29,gr0	,cc3,#1	\n"	\
+			"	beq		icc3,#0,0b		\n"	\
+			: "+U"(*__xg_ptr), "=&r"(__xg_orig)			\
+			: "r"(x)						\
+			: "memory", "cc7", "cc3", "icc3"			\
+			);							\
+		break;								\
+										\
+	case 2:									\
+		asm volatile(							\
+			"0:						\n"	\
+			"	orcc		gr0,gr0,gr0,icc3	\n"	\
+			"	ckeq		icc3,cc7		\n"	\
+			"	lduh.p		%M0,%1			\n"	\
+			"	orcr		cc7,cc7,cc3		\n"	\
+			"	csth.p		%2,%M0		,cc3,#1	\n"	\
+			"	corcc		gr29,gr29,gr0	,cc3,#1	\n"	\
+			"	beq		icc3,#0,0b		\n"	\
+			: "+U"(*__xg_ptr), "=&r"(__xg_orig)			\
+			: "r"(x)						\
+			: "memory", "cc7", "cc3", "icc3"			\
+			);							\
+		break;								\
+										\
+	case 4:									\
+		asm volatile(							\
+			"0:						\n"	\
+			"	orcc		gr0,gr0,gr0,icc3	\n"	\
+			"	ckeq		icc3,cc7		\n"	\
+			"	ld.p		%M0,%1			\n"	\
+			"	orcr		cc7,cc7,cc3		\n"	\
+			"	cst.p		%2,%M0		,cc3,#1	\n"	\
+			"	corcc		gr29,gr29,gr0	,cc3,#1	\n"	\
+			"	beq		icc3,#0,0b		\n"	\
+			: "+U"(*__xg_ptr), "=&r"(__xg_orig)			\
+			: "r"(x)						\
+			: "memory", "cc7", "cc3", "icc3"			\
+			);							\
+		break;								\
+										\
+	default:								\
+		__xg_orig = 0;							\
+		asm volatile("break");						\
+		break;								\
+	}									\
+										\
+	__xg_orig;								\
+})
+
+#else
+
+extern uint8_t  __xchg_8 (uint8_t i,  volatile void *v);
+extern uint16_t __xchg_16(uint16_t i, volatile void *v);
+extern uint32_t __xchg_32(uint32_t i, volatile void *v);
+
+#define xchg(ptr, x)										\
+({												\
+	__typeof__(ptr) __xg_ptr = (ptr);							\
+	__typeof__(*(ptr)) __xg_orig;								\
+												\
+	switch (sizeof(__xg_orig)) {								\
+	case 1: __xg_orig = (__typeof__(*(ptr))) __xchg_8 ((uint8_t)  x, __xg_ptr);	break;	\
+	case 2: __xg_orig = (__typeof__(*(ptr))) __xchg_16((uint16_t) x, __xg_ptr);	break;	\
+	case 4: __xg_orig = (__typeof__(*(ptr))) __xchg_32((uint32_t) x, __xg_ptr);	break;	\
+	default:										\
+		__xg_orig = 0;									\
+		asm volatile("break");								\
+		break;										\
+	}											\
+	__xg_orig;										\
+})
+
+#endif
+
+#define tas(ptr) (xchg((ptr), 1))
+
+/*****************************************************************************/
+/*
+ * compare and conditionally exchange value with memory
+ * - if (*ptr == test) then orig = *ptr; *ptr = test;
+ * - if (*ptr != test) then orig = *ptr;
+ */
+#ifndef CONFIG_FRV_OUTOFLINE_ATOMIC_OPS
+
+#define cmpxchg(ptr, test, new)							\
+({										\
+	__typeof__(ptr) __xg_ptr = (ptr);					\
+	__typeof__(*(ptr)) __xg_orig, __xg_tmp;					\
+	__typeof__(*(ptr)) __xg_test = (test);					\
+	__typeof__(*(ptr)) __xg_new = (new);					\
+										\
+	switch (sizeof(__xg_orig)) {						\
+	case 1:									\
+		asm volatile(							\
+			"0:						\n"	\
+			"	orcc		gr0,gr0,gr0,icc3	\n"	\
+			"	ckeq		icc3,cc7		\n"	\
+			"	ldub.p		%M0,%1			\n"	\
+			"	orcr		cc7,cc7,cc3		\n"	\
+			"	sub%I4		%1,%4,%2		\n"	\
+			"	sllcc		%2,#24,gr0,icc0		\n"	\
+			"	bne		icc0,#0,1f		\n"	\
+			"	cstb.p		%3,%M0		,cc3,#1	\n"	\
+			"	corcc		gr29,gr29,gr0	,cc3,#1	\n"	\
+			"	beq		icc3,#0,0b		\n"	\
+			"1:						\n"	\
+			: "+U"(*__xg_ptr), "=&r"(__xg_orig), "=&r"(__xg_tmp)	\
+			: "r"(__xg_new), "NPr"(__xg_test)			\
+			: "memory", "cc7", "cc3", "icc3", "icc0"		\
+			);							\
+		break;								\
+										\
+	case 2:									\
+		asm volatile(							\
+			"0:						\n"	\
+			"	orcc		gr0,gr0,gr0,icc3	\n"	\
+			"	ckeq		icc3,cc7		\n"	\
+			"	lduh.p		%M0,%1			\n"	\
+			"	orcr		cc7,cc7,cc3		\n"	\
+			"	sub%I4		%1,%4,%2		\n"	\
+			"	sllcc		%2,#16,gr0,icc0		\n"	\
+			"	bne		icc0,#0,1f		\n"	\
+			"	csth.p		%3,%M0		,cc3,#1	\n"	\
+			"	corcc		gr29,gr29,gr0	,cc3,#1	\n"	\
+			"	beq		icc3,#0,0b		\n"	\
+			"1:						\n"	\
+			: "+U"(*__xg_ptr), "=&r"(__xg_orig), "=&r"(__xg_tmp)	\
+			: "r"(__xg_new), "NPr"(__xg_test)			\
+			: "memory", "cc7", "cc3", "icc3", "icc0"		\
+			);							\
+		break;								\
+										\
+	case 4:									\
+		asm volatile(							\
+			"0:						\n"	\
+			"	orcc		gr0,gr0,gr0,icc3	\n"	\
+			"	ckeq		icc3,cc7		\n"	\
+			"	ld.p		%M0,%1			\n"	\
+			"	orcr		cc7,cc7,cc3		\n"	\
+			"	sub%I4cc	%1,%4,%2,icc0		\n"	\
+			"	bne		icc0,#0,1f		\n"	\
+			"	cst.p		%3,%M0		,cc3,#1	\n"	\
+			"	corcc		gr29,gr29,gr0	,cc3,#1	\n"	\
+			"	beq		icc3,#0,0b		\n"	\
+			"1:						\n"	\
+			: "+U"(*__xg_ptr), "=&r"(__xg_orig), "=&r"(__xg_tmp)	\
+			: "r"(__xg_new), "NPr"(__xg_test)			\
+			: "memory", "cc7", "cc3", "icc3", "icc0"		\
+			);							\
+		break;								\
+										\
+	default:								\
+		__xg_orig = 0;							\
+		asm volatile("break");						\
+		break;								\
+	}									\
+										\
+	__xg_orig;								\
+})
+
+#else
+
+extern uint8_t  __cmpxchg_8 (uint8_t *v,  uint8_t test,  uint8_t new);
+extern uint16_t __cmpxchg_16(uint16_t *v, uint16_t test, uint16_t new);
+extern uint32_t __cmpxchg_32(uint32_t *v, uint32_t test, uint32_t new);
+
+#define cmpxchg(ptr, test, new)							\
+({										\
+	__typeof__(ptr) __xg_ptr = (ptr);					\
+	__typeof__(*(ptr)) __xg_orig;						\
+	__typeof__(*(ptr)) __xg_test = (test);					\
+	__typeof__(*(ptr)) __xg_new = (new);					\
+										\
+	switch (sizeof(__xg_orig)) {						\
+	case 1: __xg_orig = __cmpxchg_8 (__xg_ptr, __xg_test, __xg_new); break;	\
+	case 2: __xg_orig = __cmpxchg_16(__xg_ptr, __xg_test, __xg_new); break;	\
+	case 4: __xg_orig = __cmpxchg_32(__xg_ptr, __xg_test, __xg_new); break;	\
+	default:								\
+		__xg_orig = 0;							\
+		asm volatile("break");						\
+		break;								\
+	}									\
+										\
+	__xg_orig;								\
+})
+
+#endif
+
+#endif /* _ASM_ATOMIC_H */
diff -Nru a/include/asm-frv/ax88796.h b/include/asm-frv/ax88796.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/ax88796.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,22 @@
+/* ax88796.h: access points to the driver for the AX88796 NE2000 clone
+ *
+ * Copyright (C) 2004 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.
+ */
+
+#ifndef _ASM_AX88796_H
+#define _ASM_AX88796_H
+
+#include <asm/mb-regs.h>
+
+#define AX88796_IOADDR		(__region_CS1 + 0x200)
+#define AX88796_IRQ		IRQ_CPU_EXTERNAL7
+#define AX88796_FULL_DUPLEX	0			/* force full duplex */
+#define AX88796_BUS_INFO	"CS1#+0x200"		/* bus info for ethtool */
+
+#endif /* _ASM_AX88796_H */
diff -Nru a/include/asm-frv/bitops.h b/include/asm-frv/bitops.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/bitops.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,341 @@
+/* bitops.h: bit operations for the Fujitsu FR-V CPUs
+ *
+ * For an explanation of how atomic ops work in this arch, see:
+ *   Documentation/fujitsu/frv/atomic-ops.txt
+ *
+ * Copyright (C) 2004 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.
+ */
+#ifndef _ASM_BITOPS_H
+#define _ASM_BITOPS_H
+
+#include <linux/config.h>
+#include <linux/compiler.h>
+#include <asm/byteorder.h>
+#include <asm/system.h>
+#include <asm/atomic.h>
+
+#ifdef __KERNEL__
+
+/*
+ * 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 result = 0;
+
+	while (word & 1) {
+		result++;
+		word >>= 1;
+	}
+	return result;
+}
+
+/*
+ * 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 int test_and_clear_bit(int nr, volatile void *addr)
+{
+	volatile unsigned long *ptr = addr;
+	unsigned long mask = 1UL << (nr & 31);
+	ptr += nr >> 5;
+	return (atomic_test_and_ANDNOT_mask(mask, ptr) & mask) != 0;
+}
+
+static inline int test_and_set_bit(int nr, volatile void *addr)
+{
+	volatile unsigned long *ptr = addr;
+	unsigned long mask = 1UL << (nr & 31);
+	ptr += nr >> 5;
+	return (atomic_test_and_OR_mask(mask, ptr) & mask) != 0;
+}
+
+static inline int test_and_change_bit(int nr, volatile void *addr)
+{
+	volatile unsigned long *ptr = addr;
+	unsigned long mask = 1UL << (nr & 31);
+	ptr += nr >> 5;
+	return (atomic_test_and_XOR_mask(mask, ptr) & mask) != 0;
+}
+
+static inline void clear_bit(int nr, volatile void *addr)
+{
+	test_and_clear_bit(nr, addr);
+}
+
+static inline void set_bit(int nr, volatile void *addr)
+{
+	test_and_set_bit(nr, addr);
+}
+
+static inline void change_bit(int nr, volatile void * addr)
+{
+	test_and_change_bit(nr, addr);
+}
+
+static inline void __clear_bit(int nr, volatile void * addr)
+{
+	volatile unsigned long *a = addr;
+	int mask;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 31);
+	*a &= ~mask;
+}
+
+static inline void __set_bit(int nr, volatile void * addr)
+{
+	volatile unsigned long *a = addr;
+	int mask;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 31);
+	*a |= mask;
+}
+
+static inline void __change_bit(int nr, volatile void *addr)
+{
+	volatile unsigned long *a = addr;
+	int mask;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 31);
+	*a ^= mask;
+}
+
+static inline int __test_and_clear_bit(int nr, volatile void * addr)
+{
+	volatile unsigned long *a = addr;
+	int mask, retval;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 31);
+	retval = (mask & *a) != 0;
+	*a &= ~mask;
+	return retval;
+}
+
+static inline int __test_and_set_bit(int nr, volatile void * addr)
+{
+	volatile unsigned long *a = addr;
+	int mask, retval;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 31);
+	retval = (mask & *a) != 0;
+	*a |= mask;
+	return retval;
+}
+
+static inline int __test_and_change_bit(int nr, volatile void * addr)
+{
+	volatile unsigned long *a = addr;
+	int mask, retval;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 31);
+	retval = (mask & *a) != 0;
+	*a ^= mask;
+	return retval;
+}
+
+/*
+ * This routine doesn't need to be atomic.
+ */
+static inline int __constant_test_bit(int nr, const volatile void * addr)
+{
+	return ((1UL << (nr & 31)) & (((const volatile unsigned int *) addr)[nr >> 5])) != 0;
+}
+
+static inline int __test_bit(int nr, const volatile void * addr)
+{
+	int 	* a = (int *) addr;
+	int	mask;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	return ((mask & *a) != 0);
+}
+
+#define test_bit(nr,addr) \
+(__builtin_constant_p(nr) ? \
+ __constant_test_bit((nr),(addr)) : \
+ __test_bit((nr),(addr)))
+
+extern int find_next_bit(const unsigned long *addr, int size, int offset);
+
+#define find_first_bit(addr, size) find_next_bit(addr, size, 0)
+
+#define find_first_zero_bit(addr, size) \
+        find_next_zero_bit((addr), (size), 0)
+
+static inline int find_next_zero_bit(const void *addr, int size, int offset)
+{
+	const unsigned long *p = ((const unsigned long *) 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 ffs(x) generic_ffs(x)
+#define __ffs(x) (ffs(x) - 1)
+
+/*
+ * fls: find last bit set.
+ */
+#define fls(x)						\
+({							\
+	int bit;					\
+							\
+	asm("scan %1,gr0,%0" : "=r"(bit) : "r"(x));	\
+							\
+	bit ? 33 - bit : bit;				\
+})
+
+/*
+ * Every architecture must define this function. It's the fastest
+ * way of searching a 140-bit bitmap where the first 100 bits are
+ * unlikely to be set. It's guaranteed that at least one of the 140
+ * bits is cleared.
+ */
+static inline int sched_find_first_bit(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;
+}
+
+
+/*
+ * hweightN: returns the hamming weight (i.e. the number
+ * of bits set) of a N-bit word
+ */
+
+#define hweight32(x) generic_hweight32(x)
+#define hweight16(x) generic_hweight16(x)
+#define hweight8(x) generic_hweight8(x)
+
+#define ext2_set_bit(nr, addr)		test_and_set_bit  ((nr) ^ 0x18, (addr))
+#define ext2_clear_bit(nr, addr)	test_and_clear_bit((nr) ^ 0x18, (addr))
+
+#define ext2_set_bit_atomic(lock,nr,addr)	ext2_set_bit((nr), addr)
+#define ext2_clear_bit_atomic(lock,nr,addr)	ext2_clear_bit((nr), addr)
+
+static inline int ext2_test_bit(int nr, const volatile void * addr)
+{
+	const volatile unsigned char *ADDR = (const unsigned char *) addr;
+	int mask;
+
+	ADDR += nr >> 3;
+	mask = 1 << (nr & 0x07);
+	return ((mask & *ADDR) != 0);
+}
+
+#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(const void *addr,
+						    unsigned long size,
+						    unsigned long offset)
+{
+	const unsigned long *p = ((const 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));
+}
+
+/* Bitmap functions for the minix filesystem.  */
+#define minix_test_and_set_bit(nr,addr)		ext2_set_bit(nr,addr)
+#define minix_set_bit(nr,addr)			ext2_set_bit(nr,addr)
+#define minix_test_and_clear_bit(nr,addr)	ext2_clear_bit(nr,addr)
+#define minix_test_bit(nr,addr)			ext2_test_bit(nr,addr)
+#define minix_find_first_zero_bit(addr,size)	ext2_find_first_zero_bit(addr,size)
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_BITOPS_H */
diff -Nru a/include/asm-frv/bug.h b/include/asm-frv/bug.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/bug.h	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,51 @@
+/* bug.h: FRV bug trapping
+ *
+ * Copyright (C) 2004 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.
+ */
+#ifndef _ASM_BUG_H
+#define _ASM_BUG_H
+
+#include <linux/config.h>
+
+/*
+ * Tell the user there is some problem.
+ */
+extern asmlinkage void __debug_bug_trap(int signr);
+
+#ifdef CONFIG_NO_KERNEL_MSG
+#define	_debug_bug_printk()
+#else
+extern void __debug_bug_printk(const char *file, unsigned line);
+#define	_debug_bug_printk() __debug_bug_printk(__FILE__, __LINE__)
+#endif
+
+#define _debug_bug_trap(signr)			\
+do {						\
+	__debug_bug_trap(signr);		\
+	asm volatile("nop");			\
+} while(0)
+
+#define HAVE_ARCH_BUG
+#define BUG()					\
+do {						\
+	_debug_bug_printk();			\
+	_debug_bug_trap(6 /*SIGABRT*/);		\
+} while (0)
+
+#ifdef CONFIG_GDBSTUB
+#define HAVE_ARCH_KGDB_RAISE
+#define kgdb_raise(signr) do { _debug_bug_trap(signr); } while(0)
+
+#define HAVE_ARCH_KGDB_BAD_PAGE
+#define kgdb_bad_page(page) do { kgdb_raise(SIGABRT); } while(0)
+#endif
+
+#include <asm-generic/bug.h>
+
+#endif
diff -Nru a/include/asm-frv/bugs.h b/include/asm-frv/bugs.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/bugs.h	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,14 @@
+/* bugs.h: arch bug checking entry
+ *
+ * Copyright (C) 2003 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.
+ */
+
+static inline void check_bugs(void)
+{
+}
diff -Nru a/include/asm-frv/busctl-regs.h b/include/asm-frv/busctl-regs.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/busctl-regs.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,41 @@
+/* busctl-regs.h: FR400-series CPU bus controller registers
+ *
+ * Copyright (C) 2003 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.
+ */
+
+#ifndef _ASM_BUSCTL_REGS_H
+#define _ASM_BUSCTL_REGS_H
+
+/* bus controller registers */
+#define __get_LGCR()	({ *(volatile unsigned long *)(0xfe000010); })
+#define __get_LMAICR()	({ *(volatile unsigned long *)(0xfe000030); })
+#define __get_LEMBR()	({ *(volatile unsigned long *)(0xfe000040); })
+#define __get_LEMAM()	({ *(volatile unsigned long *)(0xfe000048); })
+#define __get_LCR(R)	({ *(volatile unsigned long *)(0xfe000100 + 8*(R)); })
+#define __get_LSBR(R)	({ *(volatile unsigned long *)(0xfe000c00 + 8*(R)); })
+#define __get_LSAM(R)	({ *(volatile unsigned long *)(0xfe000d00 + 8*(R)); })
+
+#define __set_LGCR(V)	do { *(volatile unsigned long *)(0xfe000010) = (V); } while(0)
+#define __set_LMAICR(V)	do { *(volatile unsigned long *)(0xfe000030) = (V); } while(0)
+#define __set_LEMBR(V)	do { *(volatile unsigned long *)(0xfe000040) = (V); } while(0)
+#define __set_LEMAM(V)	do { *(volatile unsigned long *)(0xfe000048) = (V); } while(0)
+#define __set_LCR(R,V)	do { *(volatile unsigned long *)(0xfe000100 + 8*(R)) = (V); } while(0)
+#define __set_LSBR(R,V)	do { *(volatile unsigned long *)(0xfe000c00 + 8*(R)) = (V); } while(0)
+#define __set_LSAM(R,V)	do { *(volatile unsigned long *)(0xfe000d00 + 8*(R)) = (V); } while(0)
+
+/* FR401 SDRAM controller registers */
+#define __get_DBR(R)	({ *(volatile unsigned long *)(0xfe000e00 + 8*(R)); })
+#define __get_DAM(R)	({ *(volatile unsigned long *)(0xfe000f00 + 8*(R)); })
+
+/* FR551 SDRAM controller registers */
+#define __get_DARS(R)	({ *(volatile unsigned long *)(0xfeff0100 + 8*(R)); })
+#define __get_DAMK(R)	({ *(volatile unsigned long *)(0xfeff0110 + 8*(R)); })
+
+
+#endif /* _ASM_BUSCTL_REGS_H */
diff -Nru a/include/asm-frv/byteorder.h b/include/asm-frv/byteorder.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/byteorder.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,13 @@
+#ifndef _ASM_BYTEORDER_H
+#define _ASM_BYTEORDER_H
+
+#include <asm/types.h>
+
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__) || defined(__KERNEL__)
+#  define __BYTEORDER_HAS_U64__
+#  define __SWAB_64_THRU_32__
+#endif
+
+#include <linux/byteorder/big_endian.h>
+
+#endif /* _ASM_BYTEORDER_H */
diff -Nru a/include/asm-frv/cache.h b/include/asm-frv/cache.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/cache.h	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,24 @@
+/* cache.h: FRV cache definitions
+ *
+ * Copyright (C) 2004 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.
+ */
+
+#ifndef __ASM_CACHE_H
+#define __ASM_CACHE_H
+
+#include <linux/config.h>
+
+/* bytes per L1 cache line */
+#define L1_CACHE_SHIFT		(CONFIG_FRV_L1_CACHE_SHIFT)
+#define L1_CACHE_BYTES		(1 << L1_CACHE_SHIFT)
+
+#define __cacheline_aligned	__attribute__((aligned(L1_CACHE_BYTES)))
+#define ____cacheline_aligned	__attribute__((aligned(L1_CACHE_BYTES)))
+
+#endif
diff -Nru a/include/asm-frv/cacheflush.h b/include/asm-frv/cacheflush.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/cacheflush.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,91 @@
+/* cacheflush.h: FRV cache flushing routines
+ *
+ * Copyright (C) 2004 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.
+ */
+
+#ifndef _ASM_CACHEFLUSH_H
+#define _ASM_CACHEFLUSH_H
+
+/* Keep includes the same across arches.  */
+#include <linux/mm.h>
+
+/*
+ * virtually-indexed cache management (our cache is physically indexed)
+ */
+#define flush_cache_all()			do {} while(0)
+#define flush_cache_mm(mm)			do {} while(0)
+#define flush_cache_range(mm, start, end)	do {} while(0)
+#define flush_cache_page(vma, vmaddr)		do {} while(0)
+#define flush_cache_vmap(start, end)		do {} while(0)
+#define flush_cache_vunmap(start, end)		do {} while(0)
+#define flush_dcache_mmap_lock(mapping)		do {} while(0)
+#define flush_dcache_mmap_unlock(mapping)	do {} while(0)
+
+/*
+ * physically-indexed cache managment
+ * - see arch/frv/lib/cache.S
+ */
+extern void frv_dcache_writeback(unsigned long start, unsigned long size);
+extern void frv_cache_invalidate(unsigned long start, unsigned long size);
+extern void frv_icache_invalidate(unsigned long start, unsigned long size);
+extern void frv_cache_wback_inv(unsigned long start, unsigned long size);
+
+static inline void __flush_cache_all(void)
+{
+	asm volatile("	dcef	@(gr0,gr0),#1	\n"
+		     "	icei	@(gr0,gr0),#1	\n"
+		     "	membar			\n"
+		     : : : "memory"
+		     );
+}
+
+/* dcache/icache coherency... */
+#ifdef CONFIG_MMU
+extern void flush_dcache_page(struct page *page);
+#else
+static inline void flush_dcache_page(struct page *page)
+{
+	unsigned long addr = page_to_phys(page);
+	frv_dcache_writeback(addr, addr + PAGE_SIZE);
+}
+#endif
+
+static inline void flush_page_to_ram(struct page *page)
+{
+	flush_dcache_page(page);
+}
+
+static inline void flush_icache(void)
+{
+	__flush_cache_all();
+}
+
+static inline void flush_icache_range(unsigned long start, unsigned long end)
+{
+	frv_cache_wback_inv(start, end);
+}
+
+#ifdef CONFIG_MMU
+extern void flush_icache_user_range(struct vm_area_struct *vma, struct page *page,
+				    unsigned long start, unsigned long len);
+#else
+static inline void flush_icache_user_range(struct vm_area_struct *vma, struct page *page,
+					   unsigned long start, unsigned long len)
+{
+	frv_cache_wback_inv(start, start + len);
+}
+#endif
+
+static inline void flush_icache_page(struct vm_area_struct *vma, struct page *page)
+{
+	flush_icache_user_range(vma, page, page_to_phys(page), PAGE_SIZE);
+}
+
+
+#endif /* _ASM_CACHEFLUSH_H */
diff -Nru a/include/asm-frv/checksum.h b/include/asm-frv/checksum.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/checksum.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,183 @@
+/* checksum.h: FRV checksumming
+ *
+ * Copyright (C) 2004 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.
+ */
+
+#ifndef _ASM_CHECKSUM_H
+#define _ASM_CHECKSUM_H
+
+#include <linux/in6.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
+ */
+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
+ *
+ * here even more important to align src and dst on a 32-bit (or even
+ * better 64-bit) boundary
+ */
+unsigned int csum_partial_copy(const char *src, char *dst, int len, int sum);
+
+/*
+ * the same as csum_partial_copy, but copies from user space.
+ *
+ * here even more important to align src and dst on a 32-bit (or even
+ * better 64-bit) boundary
+ */
+extern unsigned int csum_partial_copy_from_user(const char *src, char *dst,
+						int len, int sum, int *csum_err);
+
+#define csum_partial_copy_nocheck(src, dst, len, sum)	\
+	csum_partial_copy((src), (dst), (len), (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 tmp, inc, sum = 0;
+
+	asm("	addcc		gr0,gr0,gr0,icc0\n" /* clear icc0.C */
+	    "	subi		%1,#4,%1	\n"
+	    "0:					\n"
+	    "	ldu.p		@(%1,%3),%4	\n"
+	    "	subicc		%2,#1,%2,icc1	\n"
+	    "	addxcc.p	%4,%0,%0,icc0	\n"
+	    "	bhi		icc1,#2,0b	\n"
+
+	    /* fold the 33-bit result into 16-bits */
+	    "	addxcc		gr0,%0,%0,icc0	\n"
+	    "	srli		%0,#16,%1	\n"
+	    "	sethi		#0,%0		\n"
+	    "	add		%1,%0,%0	\n"
+	    "	srli		%0,#16,%1	\n"
+	    "	add		%1,%0,%0	\n"
+
+	    : "=r" (sum), "=r" (iph), "=r" (ihl), "=r" (inc), "=&r"(tmp)
+	    : "0" (sum), "1" (iph), "2" (ihl), "3" (4),
+	    "m"(*(volatile struct { int _[100]; } *)iph)
+	    : "icc0", "icc1"
+	    );
+
+	return ~sum;
+}
+
+/*
+ *	Fold a partial checksum
+ */
+static inline unsigned int csum_fold(unsigned int sum)
+{
+	unsigned int tmp;
+
+	asm("	srli		%0,#16,%1	\n"
+	    "	sethi		#0,%0		\n"
+	    "	add		%1,%0,%0	\n"
+	    "	srli		%0,#16,%1	\n"
+	    "	add		%1,%0,%0	\n"
+	    : "=r"(sum), "=&r"(tmp)
+	    : "0"(sum)
+	    );
+
+	return ~sum;
+}
+
+/*
+ * computes the checksum of the TCP/UDP pseudo-header
+ * returns a 16-bit checksum, already complemented
+ */
+static inline unsigned int
+csum_tcpudp_nofold(unsigned long saddr, unsigned long daddr, unsigned short len,
+		  unsigned short proto, unsigned int sum)
+{
+	asm("	addcc		%1,%0,%0,icc0	\n"
+	    "	addxcc		%2,%0,%0,icc0	\n"
+	    "	addxcc		%3,%0,%0,icc0	\n"
+	    "	addxcc		gr0,%0,%0,icc0	\n"
+	    : "=r" (sum)
+	    : "r" (daddr), "r" (saddr), "r" (len + proto), "0"(sum)
+	    : "icc0"
+	    );
+	return sum;
+}
+
+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
+ */
+extern unsigned short ip_compute_csum(const unsigned char * buff, int len);
+
+#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 long tmp, tmp2;
+
+	asm("	addcc		%2,%0,%0,icc0	\n"
+
+	    /* add up the source addr */
+	    "	ldi		@(%3,0),%1	\n"
+	    "	addxcc		%1,%0,%0,icc0	\n"
+	    "	ldi		@(%3,4),%2	\n"
+	    "	addxcc		%2,%0,%0,icc0	\n"
+	    "	ldi		@(%3,8),%1	\n"
+	    "	addxcc		%1,%0,%0,icc0	\n"
+	    "	ldi		@(%3,12),%2	\n"
+	    "	addxcc		%2,%0,%0,icc0	\n"
+
+	    /* add up the dest addr */
+	    "	ldi		@(%4,0),%1	\n"
+	    "	addxcc		%1,%0,%0,icc0	\n"
+	    "	ldi		@(%4,4),%2	\n"
+	    "	addxcc		%2,%0,%0,icc0	\n"
+	    "	ldi		@(%4,8),%1	\n"
+	    "	addxcc		%1,%0,%0,icc0	\n"
+	    "	ldi		@(%4,12),%2	\n"
+	    "	addxcc		%2,%0,%0,icc0	\n"
+
+	    /* fold the 33-bit result into 16-bits */
+	    "	addxcc		gr0,%0,%0,icc0	\n"
+	    "	srli		%0,#16,%1	\n"
+	    "	sethi		#0,%0		\n"
+	    "	add		%1,%0,%0	\n"
+	    "	srli		%0,#16,%1	\n"
+	    "	add		%1,%0,%0	\n"
+
+	    : "=r" (sum), "=&r" (tmp), "=r" (tmp2)
+	    : "r" (saddr), "r" (daddr), "0" (sum), "2" (len + proto)
+	    : "icc0"
+	    );
+
+	return ~sum;
+}
+
+#endif /* _ASM_CHECKSUM_H */
diff -Nru a/include/asm-frv/cpu-irqs.h b/include/asm-frv/cpu-irqs.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/cpu-irqs.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,87 @@
+/* cpu-irqs.h: on-CPU peripheral irqs
+ *
+ * Copyright (C) 2004 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.
+ */
+
+#ifndef _ASM_CPU_IRQS_H
+#define _ASM_CPU_IRQS_H
+
+#ifndef __ASSEMBLY__
+
+#include <asm/irq-routing.h>
+
+#define IRQ_BASE_CPU		(NR_IRQ_ACTIONS_PER_GROUP * 0)
+
+/* IRQ IDs presented to drivers */
+enum {
+	IRQ_CPU__UNUSED = IRQ_BASE_CPU,
+	IRQ_CPU_UART0,
+	IRQ_CPU_UART1,
+	IRQ_CPU_TIMER0,
+	IRQ_CPU_TIMER1,
+	IRQ_CPU_TIMER2,
+	IRQ_CPU_DMA0,
+	IRQ_CPU_DMA1,
+	IRQ_CPU_DMA2,
+	IRQ_CPU_DMA3,
+	IRQ_CPU_DMA4,
+	IRQ_CPU_DMA5,
+	IRQ_CPU_DMA6,
+	IRQ_CPU_DMA7,
+	IRQ_CPU_EXTERNAL0,
+	IRQ_CPU_EXTERNAL1,
+	IRQ_CPU_EXTERNAL2,
+	IRQ_CPU_EXTERNAL3,
+	IRQ_CPU_EXTERNAL4,
+	IRQ_CPU_EXTERNAL5,
+	IRQ_CPU_EXTERNAL6,
+	IRQ_CPU_EXTERNAL7,
+};
+
+/* IRQ to level mappings */
+#define IRQ_GDBSTUB_LEVEL	15
+#define IRQ_UART_LEVEL		13
+
+#ifdef CONFIG_GDBSTUB_UART0
+#define IRQ_UART0_LEVEL		IRQ_GDBSTUB_LEVEL
+#else
+#define IRQ_UART0_LEVEL		IRQ_UART_LEVEL
+#endif
+
+#ifdef CONFIG_GDBSTUB_UART1
+#define IRQ_UART1_LEVEL		IRQ_GDBSTUB_LEVEL
+#else
+#define IRQ_UART1_LEVEL		IRQ_UART_LEVEL
+#endif
+
+#define IRQ_DMA0_LEVEL		14
+#define IRQ_DMA1_LEVEL		14
+#define IRQ_DMA2_LEVEL		14
+#define IRQ_DMA3_LEVEL		14
+#define IRQ_DMA4_LEVEL		14
+#define IRQ_DMA5_LEVEL		14
+#define IRQ_DMA6_LEVEL		14
+#define IRQ_DMA7_LEVEL		14
+
+#define IRQ_TIMER0_LEVEL	12
+#define IRQ_TIMER1_LEVEL	11
+#define IRQ_TIMER2_LEVEL	10
+
+#define IRQ_XIRQ0_LEVEL		1
+#define IRQ_XIRQ1_LEVEL		2
+#define IRQ_XIRQ2_LEVEL		3
+#define IRQ_XIRQ3_LEVEL		4
+#define IRQ_XIRQ4_LEVEL		5
+#define IRQ_XIRQ5_LEVEL		6
+#define IRQ_XIRQ6_LEVEL		7
+#define IRQ_XIRQ7_LEVEL		8
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _ASM_CPU_IRQS_H */
diff -Nru a/include/asm-frv/cpumask.h b/include/asm-frv/cpumask.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/cpumask.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,6 @@
+#ifndef _ASM_CPUMASK_H
+#define _ASM_CPUMASK_H
+
+#include <asm-generic/cpumask.h>
+
+#endif /* _ASM_CPUMASK_H */
diff -Nru a/include/asm-frv/cputime.h b/include/asm-frv/cputime.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/cputime.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,6 @@
+#ifndef _ASM_CPUTIME_H
+#define _ASM_CPUTIME_H
+
+#include <asm-generic/cputime.h>
+
+#endif /* _ASM_CPUTIME_H */
diff -Nru a/include/asm-frv/current.h b/include/asm-frv/current.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/current.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,30 @@
+/* current.h: FRV current task pointer
+ *
+ * Copyright (C) 2004 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.
+ */
+
+#ifndef _ASM_CURRENT_H
+#define _ASM_CURRENT_H
+
+#ifndef __ASSEMBLY__
+
+/*
+ * dedicate GR29 to keeping the current task pointer
+ */
+register struct task_struct *current asm("gr29");
+
+#define get_current() current
+
+#else
+
+#define CURRENT gr29
+
+#endif
+
+#endif /* _ASM_CURRENT_H */
diff -Nru a/include/asm-frv/delay.h b/include/asm-frv/delay.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/delay.h	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,50 @@
+/* delay.h: FRV delay code
+ *
+ * Copyright (C) 2003 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.
+ */
+
+#ifndef _ASM_DELAY_H
+#define _ASM_DELAY_H
+
+#include <asm/param.h>
+#include <asm/timer-regs.h>
+
+/*
+ * delay loop - runs at __core_clock_speed_HZ / 2 [there are 2 insns in the loop]
+ */
+extern unsigned long __delay_loops_MHz;
+
+static inline void __delay(unsigned long loops)
+{
+	asm volatile("1:	subicc	%0,#1,%0,icc0	\n"
+		     "		bnc	icc0,#2,1b	\n"
+		     : "=r" (loops)
+		     : "0" (loops)
+		     : "icc0"
+		     );
+}
+
+/*
+ * Use only for very small delays ( < 1 msec).  Should probably use a
+ * lookup table, really, as the multiplications take much too long with
+ * short delays.  This is a "reasonable" implementation, though (and the
+ * first constant multiplications gets optimized away if the delay is
+ * a constant)
+ */
+
+extern unsigned long loops_per_jiffy;
+
+static inline void udelay(unsigned long usecs)
+{
+	__delay(usecs * __delay_loops_MHz);
+}
+
+#define ndelay(n)	udelay((n) * 5)
+
+#endif /* _ASM_DELAY_H */
diff -Nru a/include/asm-frv/div64.h b/include/asm-frv/div64.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/div64.h	2005-03-01 23:39:19 -08:00
@@ -0,0 +1 @@
+#include <asm-generic/div64.h>
diff -Nru a/include/asm-frv/dm9000.h b/include/asm-frv/dm9000.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/dm9000.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,37 @@
+/* dm9000.h: Davicom DM9000 adapter configuration
+ *
+ * Copyright (C) 2004 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.
+ */
+
+#ifndef _ASM_DM9000_H
+#define _ASM_DM9000_H
+
+#include <asm/mb-regs.h>
+
+#define DM9000_ARCH_IOBASE	(__region_CS6 + 0x300)
+#define DM9000_ARCH_IRQ		IRQ_CPU_EXTERNAL3	/* XIRQ #3 (shared with FPGA) */
+#undef DM9000_ARCH_IRQ_ACTLOW				/* IRQ pin active high */
+#define DM9000_ARCH_BUS_INFO	"CS6#+0x300"		/* bus info for ethtool */
+
+#undef __is_PCI_IO
+#define __is_PCI_IO(addr)	0	/* not PCI */
+
+#undef inl
+#define inl(addr)										\
+({												\
+	unsigned long __ioaddr = (unsigned long) addr;						\
+	uint32_t x = readl(__ioaddr);								\
+	((x & 0xff) << 24) | ((x & 0xff00) << 8) | ((x >> 8) & 0xff00) | ((x >> 24) & 0xff);	\
+})
+
+#undef insl
+#define insl(a,b,l)	__insl(a,b,l,0) /* don't byte-swap */
+
+
+#endif /* _ASM_DM9000_H */
diff -Nru a/include/asm-frv/dma-mapping.h b/include/asm-frv/dma-mapping.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/dma-mapping.h	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,184 @@
+#ifndef _ASM_DMA_MAPPING_H
+#define _ASM_DMA_MAPPING_H
+
+#include <linux/device.h>
+#include <asm/cache.h>
+#include <asm/cacheflush.h>
+#include <asm/scatterlist.h>
+#include <asm/io.h>
+
+#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)
+
+extern unsigned long __nongprelbss dma_coherent_mem_start;
+extern unsigned long __nongprelbss dma_coherent_mem_end;
+
+void *dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, int gfp);
+void dma_free_coherent(struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle);
+
+/*
+ * 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)	((unsigned long) (page_to_phys((sg)->page) + (sg)->offset))
+#define sg_dma_len(sg)		((sg)->length)
+
+/*
+ * Map a single buffer of the indicated size for DMA in streaming mode.
+ * The 32-bit bus address to use is returned.
+ *
+ * Once the device is given the dma address, the device owns this memory
+ * until either pci_unmap_single or pci_dma_sync_single is performed.
+ */
+extern dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
+				 enum dma_data_direction direction);
+
+/*
+ * Unmap a single streaming mode DMA translation.  The dma_addr and size
+ * must match what was provided for in a previous pci_map_single call.  All
+ * other usages are undefined.
+ *
+ * After this call, reads by the cpu to the buffer are guarenteed to see
+ * whatever the device wrote there.
+ */
+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);
+}
+
+/*
+ * Map a set of buffers described by scatterlist in streaming
+ * mode for DMA.  This is the scather-gather version of the
+ * above pci_map_single interface.  Here the scatter gather list
+ * elements are each tagged with the appropriate dma address
+ * and length.  They are obtained via sg_dma_{address,length}(SG).
+ *
+ * NOTE: An implementation may be able to use a smaller number of
+ *       DMA address/length pairs than there are SG table elements.
+ *       (for example via virtual mapping capabilities)
+ *       The routine returns the number of addr/length pairs actually
+ *       used, at most nents.
+ *
+ * Device ownership issues as mentioned above for pci_map_single are
+ * the same here.
+ */
+extern int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+		      enum dma_data_direction direction);
+
+/*
+ * Unmap a set of streaming mode DMA translations.
+ * Again, cpu read rules concerning calls here are the same as for
+ * pci_unmap_single() above.
+ */
+static inline
+void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
+	     enum dma_data_direction direction)
+{
+	BUG_ON(direction == DMA_NONE);
+}
+
+extern
+dma_addr_t dma_map_page(struct device *dev, struct page *page, unsigned long offset,
+			size_t size, enum dma_data_direction direction);
+
+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_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size,
+			     enum dma_data_direction 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)
+{
+	flush_write_buffers();
+}
+
+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)
+{
+}
+
+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)
+{
+	flush_write_buffers();
+}
+
+static inline
+void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
+			 enum dma_data_direction direction)
+{
+}
+
+static inline
+void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems,
+			    enum dma_data_direction direction)
+{
+	flush_write_buffers();
+}
+
+static inline
+int dma_mapping_error(dma_addr_t dma_addr)
+{
+	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;
+}
+
+#define dma_is_consistent(d)	(1)
+
+static inline
+void dma_cache_sync(void *vaddr, size_t size,
+		    enum dma_data_direction direction)
+{
+	flush_write_buffers();
+}
+
+#endif  /* _ASM_DMA_MAPPING_H */
diff -Nru a/include/asm-frv/dma.h b/include/asm-frv/dma.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/dma.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,129 @@
+/* dma.h: FRV DMA controller management
+ *
+ * Copyright (C) 2004 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.
+ */
+
+#ifndef _ASM_DMA_H
+#define _ASM_DMA_H
+
+//#define DMA_DEBUG 1
+
+#include <linux/config.h>
+#include <linux/interrupt.h>
+
+#undef MAX_DMA_CHANNELS		/* don't use kernel/dma.c */
+
+/* under 2.4 this is actually needed by the new bootmem allocator */
+#define MAX_DMA_ADDRESS		PAGE_OFFSET
+
+/*
+ * FRV DMA controller management
+ */
+struct pt_regs;
+
+typedef irqreturn_t (*dma_irq_handler_t)(int dmachan, unsigned long cstr, void *data,
+					 struct pt_regs *regs);
+
+extern void frv_dma_init(void);
+
+extern int frv_dma_open(const char *devname,
+			unsigned long dmamask,
+			int dmacap,
+			dma_irq_handler_t handler,
+			unsigned long irq_flags,
+			void *data);
+
+/* channels required */
+#define FRV_DMA_MASK_ANY	ULONG_MAX	/* any channel */
+
+/* capabilities required */
+#define FRV_DMA_CAP_DREQ	0x01		/* DMA request pin */
+#define FRV_DMA_CAP_DACK	0x02		/* DMA ACK pin */
+#define FRV_DMA_CAP_DONE	0x04		/* DMA done pin */
+
+extern void frv_dma_close(int dma);
+
+extern void frv_dma_config(int dma, unsigned long ccfr, unsigned long cctr, unsigned long apr);
+
+extern void frv_dma_start(int dma,
+			  unsigned long sba, unsigned long dba,
+			  unsigned long pix, unsigned long six, unsigned long bcl);
+
+extern void frv_dma_restart_circular(int dma, unsigned long six);
+
+extern void frv_dma_stop(int dma);
+
+extern int is_frv_dma_interrupting(int dma);
+
+extern void frv_dma_dump(int dma);
+
+extern void frv_dma_status_clear(int dma);
+
+#define FRV_DMA_NCHANS	8
+#define FRV_DMA_4CHANS	4
+#define FRV_DMA_8CHANS	8
+
+#define DMAC_CCFRx		0x00	/* channel configuration reg */
+#define DMAC_CCFRx_CM_SHIFT	16
+#define DMAC_CCFRx_CM_DA	0x00000000
+#define DMAC_CCFRx_CM_SCA	0x00010000
+#define DMAC_CCFRx_CM_DCA	0x00020000
+#define DMAC_CCFRx_CM_2D	0x00030000
+#define DMAC_CCFRx_ATS_SHIFT	8
+#define DMAC_CCFRx_RS_INTERN	0x00000000
+#define DMAC_CCFRx_RS_EXTERN	0x00000001
+#define DMAC_CCFRx_RS_SHIFT	0
+
+#define DMAC_CSTRx		0x08	/* channel status reg */
+#define DMAC_CSTRx_FS		0x0000003f
+#define DMAC_CSTRx_NE		0x00000100
+#define DMAC_CSTRx_FED		0x00000200
+#define DMAC_CSTRx_WER		0x00000800
+#define DMAC_CSTRx_RER		0x00001000
+#define DMAC_CSTRx_CE		0x00002000
+#define DMAC_CSTRx_INT		0x00800000
+#define DMAC_CSTRx_BUSY		0x80000000
+
+#define DMAC_CCTRx		0x10	/* channel control reg */
+#define DMAC_CCTRx_DSIZ_1	0x00000000
+#define DMAC_CCTRx_DSIZ_2	0x00000001
+#define DMAC_CCTRx_DSIZ_4	0x00000002
+#define DMAC_CCTRx_DSIZ_32	0x00000005
+#define DMAC_CCTRx_DAU_HOLD	0x00000000
+#define DMAC_CCTRx_DAU_INC	0x00000010
+#define DMAC_CCTRx_DAU_DEC	0x00000020
+#define DMAC_CCTRx_SSIZ_1	0x00000000
+#define DMAC_CCTRx_SSIZ_2	0x00000100
+#define DMAC_CCTRx_SSIZ_4	0x00000200
+#define DMAC_CCTRx_SSIZ_32	0x00000500
+#define DMAC_CCTRx_SAU_HOLD	0x00000000
+#define DMAC_CCTRx_SAU_INC	0x00001000
+#define DMAC_CCTRx_SAU_DEC	0x00002000
+#define DMAC_CCTRx_FC		0x08000000
+#define DMAC_CCTRx_ICE		0x10000000
+#define DMAC_CCTRx_IE		0x40000000
+#define DMAC_CCTRx_ACT		0x80000000
+
+#define DMAC_SBAx		0x18	/* source base address reg */
+#define DMAC_DBAx		0x20	/* data base address reg */
+#define DMAC_PIXx		0x28	/* primary index reg */
+#define DMAC_SIXx		0x30	/* secondary index reg */
+#define DMAC_BCLx		0x38	/* byte count limit reg */
+#define DMAC_APRx		0x40	/* alternate pointer reg */
+
+/*
+ * required for PCI + MODULES
+ */
+#ifdef CONFIG_PCI
+extern int isa_dma_bridge_buggy;
+#else
+#define isa_dma_bridge_buggy 	(0)
+#endif
+
+#endif /* _ASM_DMA_H */
diff -Nru a/include/asm-frv/elf.h b/include/asm-frv/elf.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/elf.h	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,147 @@
+/* elf.h: FR-V ELF definitions
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ * - Derived from include/asm-m68knommu/elf.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 __ASM_ELF_H
+#define __ASM_ELF_H
+
+#include <linux/config.h>
+#include <asm/ptrace.h>
+#include <asm/user.h>
+
+struct elf32_hdr;
+
+/*
+ * ELF header e_flags defines.
+ */
+#define EF_FRV_GPR_MASK         0x00000003 /* mask for # of gprs */
+#define EF_FRV_GPR32		0x00000001 /* Only uses GR on 32-register */
+#define EF_FRV_GPR64		0x00000002 /* Only uses GR on 64-register */
+#define EF_FRV_FPR_MASK         0x0000000c /* mask for # of fprs */
+#define EF_FRV_FPR32		0x00000004 /* Only uses FR on 32-register */
+#define EF_FRV_FPR64		0x00000008 /* Only uses FR on 64-register */
+#define EF_FRV_FPR_NONE		0x0000000C /* Uses software floating-point */
+#define EF_FRV_DWORD_MASK       0x00000030 /* mask for dword support */
+#define EF_FRV_DWORD_YES	0x00000010 /* Assumes stack aligned to 8-byte boundaries. */
+#define EF_FRV_DWORD_NO		0x00000020 /* Assumes stack aligned to 4-byte boundaries. */
+#define EF_FRV_DOUBLE		0x00000040 /* Uses double instructions. */
+#define EF_FRV_MEDIA		0x00000080 /* Uses media instructions. */
+#define EF_FRV_PIC		0x00000100 /* Uses position independent code. */
+#define EF_FRV_NON_PIC_RELOCS	0x00000200 /* Does not use position Independent code. */
+#define EF_FRV_MULADD           0x00000400 /* -mmuladd */
+#define EF_FRV_BIGPIC           0x00000800 /* -fPIC */
+#define EF_FRV_LIBPIC           0x00001000 /* -mlibrary-pic */
+#define EF_FRV_G0               0x00002000 /* -G 0, no small data ptr */
+#define EF_FRV_NOPACK           0x00004000 /* -mnopack */
+#define EF_FRV_FDPIC            0x00008000 /* -mfdpic */
+#define EF_FRV_CPU_MASK         0xff000000 /* specific cpu bits */
+#define EF_FRV_CPU_GENERIC	0x00000000 /* Set CPU type is FR-V */
+#define EF_FRV_CPU_FR500	0x01000000 /* Set CPU type is FR500 */
+#define EF_FRV_CPU_FR300	0x02000000 /* Set CPU type is FR300 */
+#define EF_FRV_CPU_SIMPLE       0x03000000 /* SIMPLE */
+#define EF_FRV_CPU_TOMCAT       0x04000000 /* Tomcat, FR500 prototype */
+#define EF_FRV_CPU_FR400	0x05000000 /* Set CPU type is FR400 */
+#define EF_FRV_CPU_FR550        0x06000000 /* Set CPU type is FR550 */
+#define EF_FRV_CPU_FR405	0x07000000 /* Set CPU type is FR405 */
+#define EF_FRV_CPU_FR450	0x08000000 /* Set CPU type is FR450 */
+
+/*
+ * FR-V ELF relocation types
+ */
+
+
+/*
+ * ELF register definitions..
+ */
+typedef unsigned long elf_greg_t;
+
+#define ELF_NGREG (sizeof(struct pt_regs) / sizeof(elf_greg_t))
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+typedef struct fpmedia_struct elf_fpregset_t;
+
+/*
+ * This is used to ensure we don't load something for the wrong architecture.
+ */
+extern int elf_check_arch(const struct elf32_hdr *hdr);
+
+#define elf_check_fdpic(x) ((x)->e_flags & EF_FRV_FDPIC && !((x)->e_flags & EF_FRV_NON_PIC_RELOCS))
+#define elf_check_const_displacement(x) ((x)->e_flags & EF_FRV_PIC)
+
+/*
+ * These are used to set parameters in the core dumps.
+ */
+#define ELF_CLASS	ELFCLASS32
+#define ELF_DATA	ELFDATA2MSB
+#define ELF_ARCH	EM_FRV
+
+#define ELF_PLAT_INIT(_r)			\
+do {						\
+	__kernel_frame0_ptr->gr16	= 0;	\
+	__kernel_frame0_ptr->gr17	= 0;	\
+	__kernel_frame0_ptr->gr18	= 0;	\
+	__kernel_frame0_ptr->gr19	= 0;	\
+	__kernel_frame0_ptr->gr20	= 0;	\
+	__kernel_frame0_ptr->gr21	= 0;	\
+	__kernel_frame0_ptr->gr22	= 0;	\
+	__kernel_frame0_ptr->gr23	= 0;	\
+	__kernel_frame0_ptr->gr24	= 0;	\
+	__kernel_frame0_ptr->gr25	= 0;	\
+	__kernel_frame0_ptr->gr26	= 0;	\
+	__kernel_frame0_ptr->gr27	= 0;	\
+	__kernel_frame0_ptr->gr29	= 0;	\
+} while(0)
+
+#define ELF_FDPIC_PLAT_INIT(_regs, _exec_map_addr, _interp_map_addr, _dynamic_addr)	\
+do {											\
+	__kernel_frame0_ptr->gr16	= _exec_map_addr;				\
+	__kernel_frame0_ptr->gr17	= _interp_map_addr;				\
+	__kernel_frame0_ptr->gr18	= _dynamic_addr;				\
+	__kernel_frame0_ptr->gr19	= 0;						\
+	__kernel_frame0_ptr->gr20	= 0;						\
+	__kernel_frame0_ptr->gr21	= 0;						\
+	__kernel_frame0_ptr->gr22	= 0;						\
+	__kernel_frame0_ptr->gr23	= 0;						\
+	__kernel_frame0_ptr->gr24	= 0;						\
+	__kernel_frame0_ptr->gr25	= 0;						\
+	__kernel_frame0_ptr->gr26	= 0;						\
+	__kernel_frame0_ptr->gr27	= 0;						\
+	__kernel_frame0_ptr->gr29	= 0;						\
+} while(0)
+
+#define USE_ELF_CORE_DUMP
+#define ELF_EXEC_PAGESIZE	16384
+
+/* 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         0x08000000UL
+
+#define ELF_CORE_COPY_REGS(pr_reg, regs)				\
+	memcpy(&pr_reg[0], &regs->sp, 31 * sizeof(uint32_t));
+
+/* This yields a mask that user programs can use to figure out what
+   instruction set this cpu supports.  */
+
+#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.  */
+
+#define ELF_PLATFORM  (NULL)
+
+#ifdef __KERNEL__
+#define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX)
+#endif
+
+#endif
diff -Nru a/include/asm-frv/errno.h b/include/asm-frv/errno.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/errno.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,7 @@
+#ifndef _ASM_ERRNO_H
+#define _ASM_ERRNO_H
+
+#include <asm-generic/errno.h>
+
+#endif /* _ASM_ERRNO_H */
+
diff -Nru a/include/asm-frv/fcntl.h b/include/asm-frv/fcntl.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/fcntl.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,88 @@
+#ifndef _ASM_FCNTL_H
+#define _ASM_FCNTL_H
+
+/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
+   located on an ext2 file system */
+#define O_ACCMODE	   0003
+#define O_RDONLY	     00
+#define O_WRONLY	     01
+#define O_RDWR		     02
+#define O_CREAT		   0100	/* not fcntl */
+#define O_EXCL		   0200	/* not fcntl */
+#define O_NOCTTY	   0400	/* not fcntl */
+#define O_TRUNC		  01000	/* not fcntl */
+#define O_APPEND	  02000
+#define O_NONBLOCK	  04000
+#define O_NDELAY	O_NONBLOCK
+#define O_SYNC		 010000
+#define FASYNC		 020000	/* fcntl, for BSD compatibility */
+#define O_DIRECT	 040000	/* direct disk access hint */
+#define O_LARGEFILE	0100000
+#define O_DIRECTORY	0200000	/* must be a directory */
+#define O_NOFOLLOW	0400000 /* don't follow links */
+#define O_NOATIME	01000000
+
+#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		5
+#define F_SETLK		6
+#define F_SETLKW	7
+
+#define F_SETOWN	8	/*  for sockets. */
+#define F_GETOWN	9	/*  for sockets. */
+#define F_SETSIG	10	/*  for sockets. */
+#define F_GETSIG	11	/*  for sockets. */
+
+#define F_GETLK64	12	/*  using 'struct flock64' */
+#define F_SETLK64	13
+#define F_SETLKW64	14
+
+/* 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 */
+
+struct flock {
+	short l_type;
+	short l_whence;
+	off_t l_start;
+	off_t l_len;
+	pid_t l_pid;
+};
+
+struct flock64 {
+	short  l_type;
+	short  l_whence;
+	loff_t l_start;
+	loff_t l_len;
+	pid_t  l_pid;
+};
+
+#define F_LINUX_SPECIFIC_BASE	1024
+#endif /* _ASM_FCNTL_H */
+
diff -Nru a/include/asm-frv/fpu.h b/include/asm-frv/fpu.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/fpu.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,12 @@
+#ifndef __ASM_FPU_H
+#define __ASM_FPU_H
+
+#include <linux/config.h>
+
+/*
+ * MAX floating point unit state size (FSAVE/FRESTORE)
+ */
+
+#define kernel_fpu_end() do { asm volatile("bar":::"memory"); preempt_enable(); } while(0)
+
+#endif /* __ASM_FPU_H */
diff -Nru a/include/asm-frv/gdb-stub.h b/include/asm-frv/gdb-stub.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/gdb-stub.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,118 @@
+/* gdb-stub.h: FRV GDB stub
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ * - Derived from asm-mips/gdb-stub.h (c) 1995 Andreas Busse
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the 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 __ASM_GDB_STUB_H
+#define __ASM_GDB_STUB_H
+
+#undef GDBSTUB_DEBUG_PROTOCOL
+
+#include <asm/ptrace.h>
+
+/*
+ * important register numbers in GDB protocol
+ * - GR0,  GR1,  GR2,  GR3,  GR4,  GR5,  GR6,  GR7,
+ * - GR8,  GR9,  GR10, GR11, GR12, GR13, GR14, GR15,
+ * - GR16, GR17, GR18, GR19, GR20, GR21, GR22, GR23,
+ * - GR24, GR25, GR26, GR27, GR28, GR29, GR30, GR31,
+ * - GR32, GR33, GR34, GR35, GR36, GR37, GR38, GR39,
+ * - GR40, GR41, GR42, GR43, GR44, GR45, GR46, GR47,
+ * - GR48, GR49, GR50, GR51, GR52, GR53, GR54, GR55,
+ * - GR56, GR57, GR58, GR59, GR60, GR61, GR62, GR63,
+ * - FR0,  FR1,  FR2,  FR3,  FR4,  FR5,  FR6,  FR7,
+ * - FR8,  FR9,  FR10, FR11, FR12, FR13, FR14, FR15,
+ * - FR16, FR17, FR18, FR19, FR20, FR21, FR22, FR23,
+ * - FR24, FR25, FR26, FR27, FR28, FR29, FR30, FR31,
+ * - FR32, FR33, FR34, FR35, FR36, FR37, FR38, FR39,
+ * - FR40, FR41, FR42, FR43, FR44, FR45, FR46, FR47,
+ * - FR48, FR49, FR50, FR51, FR52, FR53, FR54, FR55,
+ * - FR56, FR57, FR58, FR59, FR60, FR61, FR62, FR63,
+ * - PC, PSR, CCR, CCCR,
+ * - _X132, _X133, _X134
+ * - TBR, BRR, DBAR0, DBAR1, DBAR2, DBAR3,
+ * - SCR0, SCR1, SCR2, SCR3,
+ * - LR, LCR,
+ * - IACC0H, IACC0L,
+ * - FSR0,
+ * - ACC0, ACC1, ACC2, ACC3, ACC4, ACC5, ACC6, ACC7,
+ * - ACCG0123, ACCG4567,
+ * - MSR0, MSR1,
+ * - GNER0, GNER1,
+ * - FNER0, FNER1,
+ */
+#define GDB_REG_GR(N)	(N)
+#define GDB_REG_FR(N)	(64+(N))
+#define GDB_REG_PC	128
+#define GDB_REG_PSR	129
+#define GDB_REG_CCR	130
+#define GDB_REG_CCCR	131
+#define GDB_REG_TBR	135
+#define GDB_REG_BRR	136
+#define GDB_REG_DBAR(N)	(137+(N))
+#define GDB_REG_SCR(N)	(141+(N))
+#define GDB_REG_LR	145
+#define GDB_REG_LCR	146
+#define GDB_REG_FSR0	149
+#define GDB_REG_ACC(N)	(150+(N))
+#define GDB_REG_ACCG(N)	(158+(N)/4)
+#define GDB_REG_MSR(N)	(160+(N))
+#define GDB_REG_GNER(N)	(162+(N))
+#define GDB_REG_FNER(N)	(164+(N))
+
+#define GDB_REG_SP	GDB_REG_GR(1)
+#define GDB_REG_FP	GDB_REG_GR(2)
+
+#ifndef _LANGUAGE_ASSEMBLY
+
+/*
+ * Prototypes
+ */
+extern void show_registers_only(struct pt_regs *regs);
+
+extern void gdbstub_init(void);
+extern void gdbstub(int type);
+extern void gdbstub_exit(int status);
+
+extern void gdbstub_io_init(void);
+extern void gdbstub_set_baud(unsigned baud);
+extern int gdbstub_rx_char(unsigned char *_ch, int nonblock);
+extern void gdbstub_tx_char(unsigned char ch);
+extern void gdbstub_tx_flush(void);
+extern void gdbstub_do_rx(void);
+
+extern asmlinkage void __debug_stub_init_break(void);
+extern asmlinkage void __break_hijack_kernel_event(void);
+extern asmlinkage void start_kernel(void);
+
+extern asmlinkage void gdbstub_rx_handler(void);
+extern asmlinkage void gdbstub_rx_irq(void);
+extern asmlinkage void gdbstub_intercept(void);
+
+extern uint32_t __entry_usertrap_table[];
+extern uint32_t __entry_kerneltrap_table[];
+
+extern volatile u8	gdbstub_rx_buffer[PAGE_SIZE];
+extern volatile u32	gdbstub_rx_inp;
+extern volatile u32	gdbstub_rx_outp;
+extern volatile u8	gdbstub_rx_overflow;
+extern u8		gdbstub_rx_unget;
+
+extern void gdbstub_printk(const char *fmt, ...);
+extern void debug_to_serial(const char *p, int n);
+extern void console_set_baud(unsigned baud);
+
+#ifdef GDBSTUB_DEBUG_PROTOCOL
+#define gdbstub_proto(FMT,...) gdbstub_printk(FMT,##__VA_ARGS__)
+#else
+#define gdbstub_proto(FMT,...) ({ 0; })
+#endif
+
+#endif /* _LANGUAGE_ASSEMBLY */
+#endif /* __ASM_GDB_STUB_H */
diff -Nru a/include/asm-frv/gpio-regs.h b/include/asm-frv/gpio-regs.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/gpio-regs.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,116 @@
+/* gpio-regs.h: on-chip general purpose I/O registers
+ *
+ * Copyright (C) 2003 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.
+ */
+
+#ifndef _ASM_GPIO_REGS
+#define _ASM_GPIO_REGS
+
+#define __reg(ADDR) (*(volatile unsigned long *)(ADDR))
+
+#define __get_PDR()	({ __reg(0xfeff0400); })
+#define __set_PDR(V)	do { __reg(0xfeff0400) = (V); mb(); } while(0)
+
+#define __get_GPDR()	({ __reg(0xfeff0408); })
+#define __set_GPDR(V)	do { __reg(0xfeff0408) = (V); mb(); } while(0)
+
+#define __get_SIR()	({ __reg(0xfeff0410); })
+#define __set_SIR(V)	do { __reg(0xfeff0410) = (V); mb(); } while(0)
+
+#define __get_SOR()	({ __reg(0xfeff0418); })
+#define __set_SOR(V)	do { __reg(0xfeff0418) = (V); mb(); } while(0)
+
+#define __set_PDSR(V)	do { __reg(0xfeff0420) = (V); mb(); } while(0)
+
+#define __set_PDCR(V)	do { __reg(0xfeff0428) = (V); mb(); } while(0)
+
+#define __get_RSTR()	({ __reg(0xfeff0500); })
+#define __set_RSTR(V)	do { __reg(0xfeff0500) = (V); mb(); } while(0)
+
+
+
+/* PDR definitions */
+#define PDR_GPIO_DATA(X)	(1 << (X))
+
+/* GPDR definitions */
+#define GPDR_INPUT		0
+#define GPDR_OUTPUT		1
+#define GPDR_DREQ0_BIT		0x00001000
+#define GPDR_DREQ1_BIT		0x00008000
+#define GPDR_DREQ2_BIT		0x00040000
+#define GPDR_DREQ3_BIT		0x00080000
+#define GPDR_DREQ4_BIT		0x00004000
+#define GPDR_DREQ5_BIT		0x00020000
+#define GPDR_DREQ6_BIT		0x00100000
+#define GPDR_DREQ7_BIT		0x00200000
+#define GPDR_DACK0_BIT		0x00002000
+#define GPDR_DACK1_BIT		0x00010000
+#define GPDR_DACK2_BIT		0x00100000
+#define GPDR_DACK3_BIT		0x00200000
+#define GPDR_DONE0_BIT		0x00004000
+#define GPDR_DONE1_BIT		0x00020000
+#define GPDR_GPIO_DIR(X,D)	((D) << (X))
+
+/* SIR definitions */
+#define SIR_GPIO_INPUT		0
+#define SIR_DREQ7_INPUT		0x00200000
+#define SIR_DREQ6_INPUT		0x00100000
+#define SIR_DREQ3_INPUT		0x00080000
+#define SIR_DREQ2_INPUT		0x00040000
+#define SIR_DREQ5_INPUT		0x00020000
+#define SIR_DREQ1_INPUT		0x00008000
+#define SIR_DREQ4_INPUT		0x00004000
+#define SIR_DREQ0_INPUT		0x00001000
+#define SIR_RXD1_INPUT		0x00000400
+#define SIR_CTS0_INPUT		0x00000100
+#define SIR_RXD0_INPUT		0x00000040
+#define SIR_GATE1_INPUT		0x00000020
+#define SIR_GATE0_INPUT		0x00000010
+#define SIR_IRQ3_INPUT		0x00000008
+#define SIR_IRQ2_INPUT		0x00000004
+#define SIR_IRQ1_INPUT		0x00000002
+#define SIR_IRQ0_INPUT		0x00000001
+#define SIR_DREQ_BITS		(SIR_DREQ0_INPUT | SIR_DREQ1_INPUT | \
+				 SIR_DREQ2_INPUT | SIR_DREQ3_INPUT | \
+				 SIR_DREQ4_INPUT | SIR_DREQ5_INPUT | \
+				 SIR_DREQ6_INPUT | SIR_DREQ7_INPUT)
+
+/* SOR definitions */
+#define SOR_GPIO_OUTPUT		0
+#define SOR_DACK3_OUTPUT	0x00200000
+#define SOR_DACK2_OUTPUT	0x00100000
+#define SOR_DONE1_OUTPUT	0x00020000
+#define SOR_DACK1_OUTPUT	0x00010000
+#define SOR_DONE0_OUTPUT	0x00004000
+#define SOR_DACK0_OUTPUT	0x00002000
+#define SOR_TXD1_OUTPUT		0x00000800
+#define SOR_RTS0_OUTPUT		0x00000200
+#define SOR_TXD0_OUTPUT		0x00000080
+#define SOR_TOUT1_OUTPUT	0x00000020
+#define SOR_TOUT0_OUTPUT	0x00000010
+#define SOR_DONE_BITS		(SOR_DONE0_OUTPUT | SOR_DONE1_OUTPUT)
+#define SOR_DACK_BITS		(SOR_DACK0_OUTPUT | SOR_DACK1_OUTPUT | \
+				 SOR_DACK2_OUTPUT | SOR_DACK3_OUTPUT)
+
+/* PDSR definitions */
+#define PDSR_UNCHANGED		0
+#define PDSR_SET_BIT(X)		(1 << (X))
+
+/* PDCR definitions */
+#define PDCR_UNCHANGED		0
+#define PDCR_CLEAR_BIT(X)	(1 << (X))
+
+/* RSTR definitions */
+/* Read Only */
+#define RSTR_POWERON		0x00000400
+#define RSTR_SOFTRESET_STATUS	0x00000100
+/* Write Only */
+#define RSTR_SOFTRESET		0x00000001
+
+#endif /* _ASM_GPIO_REGS */
diff -Nru a/include/asm-frv/hardirq.h b/include/asm-frv/hardirq.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/hardirq.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,30 @@
+/* hardirq.h: FRV hardware IRQ management
+ *
+ * Copyright (C) 2004 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.
+ */
+
+#ifndef __ASM_HARDIRQ_H
+#define __ASM_HARDIRQ_H
+
+#include <linux/config.h>
+#include <linux/threads.h>
+
+typedef struct {
+	unsigned int __softirq_pending;
+	unsigned long idle_timestamp;
+} ____cacheline_aligned irq_cpustat_t;
+
+#include <linux/irq_cpustat.h>	/* Standard mappings for irq_cpustat_t above */
+
+#ifdef CONFIG_SMP
+#error SMP not available on FR-V
+#endif /* CONFIG_SMP */
+
+
+#endif
diff -Nru a/include/asm-frv/highmem.h b/include/asm-frv/highmem.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/highmem.h	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,183 @@
+/* highmem.h: virtual kernel memory mappings for high memory
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ * - Derived from include/asm-i386/highmem.h
+ *
+ * See Documentation/fujitsu/frv/mmu-layout.txt for more 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.
+ */
+
+#ifndef _ASM_HIGHMEM_H
+#define _ASM_HIGHMEM_H
+
+#ifdef __KERNEL__
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <asm/mem-layout.h>
+#include <asm/spr-regs.h>
+#include <asm/mb-regs.h>
+
+#define NR_TLB_LINES		64	/* number of lines in the TLB */
+
+#ifndef __ASSEMBLY__
+
+#include <linux/interrupt.h>
+#include <asm/kmap_types.h>
+#include <asm/pgtable.h>
+
+#ifdef CONFIG_DEBUG_HIGHMEM
+#define HIGHMEM_DEBUG 1
+#else
+#define HIGHMEM_DEBUG 0
+#endif
+
+/* declarations for highmem.c */
+extern unsigned long highstart_pfn, highend_pfn;
+
+#define kmap_prot PAGE_KERNEL
+#define kmap_pte ______kmap_pte_in_TLB
+extern pte_t *pkmap_page_table;
+
+extern void kmap_init(void);
+
+#define flush_cache_kmaps()  do { } while (0)
+
+/*
+ * Right now we initialize only a single pte table. It can be extended
+ * easily, subsequent pte tables have to be allocated in one physical
+ * chunk of RAM.
+ */
+#define LAST_PKMAP	PTRS_PER_PTE
+#define LAST_PKMAP_MASK	(LAST_PKMAP - 1)
+#define PKMAP_NR(virt)	((virt - PKMAP_BASE) >> PAGE_SHIFT)
+#define PKMAP_ADDR(nr)	(PKMAP_BASE + ((nr) << PAGE_SHIFT))
+
+extern void *kmap_high(struct page *page);
+extern void kunmap_high(struct page *page);
+
+extern void *kmap(struct page *page);
+extern void kunmap(struct page *page);
+
+extern struct page *kmap_atomic_to_page(void *ptr);
+
+#endif /* !__ASSEMBLY__ */
+
+/*
+ * The use of kmap_atomic/kunmap_atomic is discouraged - kmap/kunmap
+ * gives a more generic (and caching) interface. But kmap_atomic can
+ * be used in IRQ contexts, so in some (very limited) cases we need
+ * it.
+ */
+#define KMAP_ATOMIC_CACHE_DAMR		8
+
+#ifndef __ASSEMBLY__
+
+#define __kmap_atomic_primary(type, paddr, ampr)						\
+({												\
+	unsigned long damlr, dampr;								\
+												\
+	dampr = paddr | xAMPRx_L | xAMPRx_M | xAMPRx_S | xAMPRx_SS_16Kb | xAMPRx_V;		\
+												\
+	if (type != __KM_CACHE)									\
+		asm volatile("movgs %0,dampr"#ampr :: "r"(dampr));				\
+	else											\
+		asm volatile("movgs %0,iampr"#ampr"\n"						\
+			     "movgs %0,dampr"#ampr"\n"						\
+			     :: "r"(dampr)							\
+			     );									\
+												\
+	asm("movsg damlr"#ampr",%0" : "=r"(damlr));						\
+												\
+	/*printk("DAMR"#ampr": PRIM sl=%d L=%08lx P=%08lx\n", type, damlr, dampr);*/		\
+												\
+	(void *) damlr;										\
+})
+
+#define __kmap_atomic_secondary(slot, paddr)							  \
+({												  \
+	unsigned long damlr = KMAP_ATOMIC_SECONDARY_FRAME + (slot) * PAGE_SIZE;			  \
+	unsigned long dampr = paddr | xAMPRx_L | xAMPRx_M | xAMPRx_S | xAMPRx_SS_16Kb | xAMPRx_V; \
+												  \
+	asm volatile("movgs %0,tplr \n"								  \
+		     "movgs %1,tppr \n"								  \
+		     "tlbpr %0,gr0,#2,#1"							  \
+		     : : "r"(damlr), "r"(dampr));						  \
+												  \
+	/*printk("TLB: SECN sl=%d L=%08lx P=%08lx\n", slot, damlr, dampr);*/			  \
+												  \
+	(void *) damlr;										  \
+})
+
+static inline void *kmap_atomic(struct page *page, enum km_type type)
+{
+	unsigned long paddr;
+
+	preempt_disable();
+	paddr = page_to_phys(page);
+
+	switch (type) {
+        case 0:		return __kmap_atomic_primary(0, paddr, 2);
+        case 1:		return __kmap_atomic_primary(1, paddr, 3);
+        case 2:		return __kmap_atomic_primary(2, paddr, 4);
+        case 3:		return __kmap_atomic_primary(3, paddr, 5);
+        case 4:		return __kmap_atomic_primary(4, paddr, 6);
+        case 5:		return __kmap_atomic_primary(5, paddr, 7);
+        case 6:		return __kmap_atomic_primary(6, paddr, 8);
+        case 7:		return __kmap_atomic_primary(7, paddr, 9);
+        case 8:		return __kmap_atomic_primary(8, paddr, 10);
+
+	case 9 ... 9 + NR_TLB_LINES - 1:
+		return __kmap_atomic_secondary(type - 9, paddr);
+
+	default:
+		BUG();
+		return 0;
+	}
+}
+
+#define __kunmap_atomic_primary(type, ampr)			\
+do {								\
+	asm volatile("movgs gr0,dampr"#ampr"\n");		\
+	if (type == __KM_CACHE)					\
+		asm volatile("movgs gr0,iampr"#ampr"\n");	\
+} while(0)
+
+#define __kunmap_atomic_secondary(slot, vaddr)			\
+do {								\
+	asm volatile("tlbpr %0,gr0,#4,#1" : : "r"(vaddr));	\
+} while(0)
+
+static inline void kunmap_atomic(void *kvaddr, enum km_type type)
+{
+	switch (type) {
+        case 0:		__kunmap_atomic_primary(0, 2);	break;
+        case 1:		__kunmap_atomic_primary(1, 3);	break;
+        case 2:		__kunmap_atomic_primary(2, 4);	break;
+        case 3:		__kunmap_atomic_primary(3, 5);	break;
+        case 4:		__kunmap_atomic_primary(4, 6);	break;
+        case 5:		__kunmap_atomic_primary(5, 7);	break;
+        case 6:		__kunmap_atomic_primary(6, 8);	break;
+        case 7:		__kunmap_atomic_primary(7, 9);	break;
+        case 8:		__kunmap_atomic_primary(8, 10);	break;
+
+	case 9 ... 9 + NR_TLB_LINES - 1:
+		__kunmap_atomic_secondary(type - 9, kvaddr);
+		break;
+
+	default:
+		BUG();
+	}
+	preempt_enable();
+}
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_HIGHMEM_H */
diff -Nru a/include/asm-frv/hw_irq.h b/include/asm-frv/hw_irq.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/hw_irq.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,16 @@
+/* hw_irq.h: FR-V specific h/w IRQ stuff
+ *
+ * Copyright (C) 2003 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.
+ */
+
+#ifndef _ASM_HW_IRQ_H
+#define _ASM_HW_IRQ_H
+
+
+#endif /* _ASM_HW_IRQ_H */
diff -Nru a/include/asm-frv/ide.h b/include/asm-frv/ide.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/ide.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,43 @@
+/* ide.h: FRV IDE declarations
+ *
+ * Copyright (C) 2004 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.
+ */
+
+#ifndef _ASM_IDE_H
+#define _ASM_IDE_H
+
+#ifdef __KERNEL__
+
+#include <linux/config.h>
+#include <asm/setup.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#undef SUPPORT_SLOW_DATA_PORTS
+#define SUPPORT_SLOW_DATA_PORTS 0
+
+#undef SUPPORT_VLB_SYNC
+#define SUPPORT_VLB_SYNC 0
+
+#ifndef MAX_HWIFS
+#define MAX_HWIFS 8
+#endif
+
+/****************************************************************************/
+/*
+ * some bits needed for parts of the IDE subsystem to compile
+ */
+#define __ide_mm_insw(port, addr, n)	insw(port, addr, n)
+#define __ide_mm_insl(port, addr, n)	insl(port, addr, n)
+#define __ide_mm_outsw(port, addr, n)	outsw(port, addr, n)
+#define __ide_mm_outsl(port, addr, n)	outsl(port, addr, n)
+
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_IDE_H */
diff -Nru a/include/asm-frv/init.h b/include/asm-frv/init.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/init.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,12 @@
+#ifndef _ASM_INIT_H
+#define _ASM_INIT_H
+
+#define __init __attribute__ ((__section__ (".text.init")))
+#define __initdata __attribute__ ((__section__ (".data.init")))
+/* For assembly routines */
+#define __INIT		.section	".text.init",#alloc,#execinstr
+#define __FINIT		.previous
+#define __INITDATA	.section	".data.init",#alloc,#write
+
+#endif
+
diff -Nru a/include/asm-frv/io.h b/include/asm-frv/io.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/io.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,278 @@
+/* io.h: FRV I/O operations
+ *
+ * Copyright (C) 2004 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.
+ *
+ * This gets interesting when talking to the PCI bus - the CPU is in big endian
+ * mode, the PCI bus is little endian and the hardware in the middle can do
+ * byte swapping
+ */
+#ifndef _ASM_IO_H
+#define _ASM_IO_H
+
+#ifdef __KERNEL__
+
+#include <linux/config.h>
+#include <asm/virtconvert.h>
+#include <asm/string.h>
+#include <asm/mb-regs.h>
+#include <linux/delay.h>
+
+/*
+ * swap functions are sometimes needed to interface little-endian hardware
+ */
+
+static inline unsigned short _swapw(unsigned short v)
+{
+    return ((v << 8) | (v >> 8));
+}
+
+static inline unsigned long _swapl(unsigned long v)
+{
+    return ((v << 24) | ((v & 0xff00) << 8) | ((v & 0xff0000) >> 8) | (v >> 24));
+}
+
+//#define __iormb() asm volatile("membar")
+//#define __iowmb() asm volatile("membar")
+
+#define __raw_readb(addr) __builtin_read8((void *) (addr))
+#define __raw_readw(addr) __builtin_read16((void *) (addr))
+#define __raw_readl(addr) __builtin_read32((void *) (addr))
+
+#define __raw_writeb(datum, addr) __builtin_write8((void *) (addr), datum)
+#define __raw_writew(datum, addr) __builtin_write16((void *) (addr), datum)
+#define __raw_writel(datum, addr) __builtin_write32((void *) (addr), datum)
+
+static inline void io_outsb(unsigned int addr, const void *buf, int len)
+{
+	unsigned long __ioaddr = (unsigned long) addr;
+	const uint8_t *bp = buf;
+
+	while (len--)
+		__builtin_write8((volatile void __iomem *) __ioaddr, *bp++);
+}
+
+static inline void io_outsw(unsigned int addr, const void *buf, int len)
+{
+	unsigned long __ioaddr = (unsigned long) addr;
+	const uint16_t *bp = buf;
+
+	while (len--)
+		__builtin_write16((volatile void __iomem *) __ioaddr, (*bp++));
+}
+
+extern void __outsl_ns(unsigned int addr, const void *buf, int len);
+extern void __outsl_sw(unsigned int addr, const void *buf, int len);
+static inline void __outsl(unsigned int addr, const void *buf, int len, int swap)
+{
+	unsigned long __ioaddr = (unsigned long) addr;
+
+	if (!swap)
+		__outsl_ns(__ioaddr, buf, len);
+	else
+		__outsl_sw(__ioaddr, buf, len);
+}
+
+static inline void io_insb(unsigned long addr, void *buf, int len)
+{
+	uint8_t *bp = buf;
+
+	while (len--)
+		*bp++ = __builtin_read8((volatile void __iomem *) addr);
+}
+
+static inline void io_insw(unsigned long addr, void *buf, int len)
+{
+	uint16_t *bp = buf;
+
+	while (len--)
+		*bp++ = __builtin_read16((volatile void __iomem *) addr);
+}
+
+extern void __insl_ns(unsigned long addr, void *buf, int len);
+extern void __insl_sw(unsigned long addr, void *buf, int len);
+static inline void __insl(unsigned long addr, void *buf, int len, int swap)
+{
+	if (!swap)
+		__insl_ns(addr, buf, len);
+	else
+		__insl_sw(addr, buf, len);
+}
+
+/*
+ *	make the short names macros so specific devices
+ *	can override them as required
+ */
+
+static inline void memset_io(volatile void __iomem *addr, unsigned char val, int count)
+{
+	memset((void __force *) addr, val, count);
+}
+
+static inline void memcpy_fromio(void *dst, volatile void __iomem *src, int count)
+{
+	memcpy(dst, (void __force *) src, count);
+}
+
+static inline void memcpy_toio(volatile void __iomem *dst, const void *src, int count)
+{
+	memcpy((void __force *) dst, src, count);
+}
+
+static inline uint8_t inb(unsigned long addr)
+{
+	return __builtin_read8((void *)addr);
+}
+
+static inline uint16_t inw(unsigned long addr)
+{
+	uint16_t ret = __builtin_read16((void *)addr);
+
+	if (__is_PCI_IO(addr))
+		ret = _swapw(ret);
+
+	return ret;
+}
+
+static inline uint32_t inl(unsigned long addr)
+{
+	uint32_t ret = __builtin_read32((void *)addr);
+
+	if (__is_PCI_IO(addr))
+		ret = _swapl(ret);
+
+	return ret;
+}
+
+static inline void outb(uint8_t datum, unsigned long addr)
+{
+	__builtin_write8((void *)addr, datum);
+}
+
+static inline void outw(uint16_t datum, unsigned long addr)
+{
+	if (__is_PCI_IO(addr))
+		datum = _swapw(datum);
+	__builtin_write16((void *)addr, datum);
+}
+
+static inline void outl(uint32_t datum, unsigned long addr)
+{
+	if (__is_PCI_IO(addr))
+		datum = _swapl(datum);
+	__builtin_write32((void *)addr, datum);
+}
+
+#define inb_p(addr)	inb(addr)
+#define inw_p(addr)	inw(addr)
+#define inl_p(addr)	inl(addr)
+#define outb_p(x,addr)	outb(x,addr)
+#define outw_p(x,addr)	outw(x,addr)
+#define outl_p(x,addr)	outl(x,addr)
+
+#define outsb(a,b,l)	io_outsb(a,b,l)
+#define outsw(a,b,l)	io_outsw(a,b,l)
+#define outsl(a,b,l)	__outsl(a,b,l,0)
+
+#define insb(a,b,l)	io_insb(a,b,l)
+#define insw(a,b,l)	io_insw(a,b,l)
+#define insl(a,b,l)	__insl(a,b,l,0)
+
+#define IO_SPACE_LIMIT	0xffffffff
+
+static inline uint8_t readb(const volatile void __iomem *addr)
+{
+	return __builtin_read8((volatile uint8_t __force *) addr);
+}
+
+static inline uint16_t readw(const volatile void __iomem *addr)
+{
+	uint16_t ret =	__builtin_read16((volatile uint16_t __force *)addr);
+
+	if (__is_PCI_MEM(addr))
+		ret = _swapw(ret);
+	return ret;
+}
+
+static inline uint32_t readl(const volatile void __iomem *addr)
+{
+	uint32_t ret =	__builtin_read32((volatile uint32_t __force *)addr);
+
+	if (__is_PCI_MEM(addr))
+		ret = _swapl(ret);
+
+	return ret;
+}
+
+static inline void writeb(uint8_t datum, volatile void __iomem *addr)
+{
+	__builtin_write8((volatile uint8_t __force *) addr, datum);
+	if (__is_PCI_MEM(addr))
+		__flush_PCI_writes();
+}
+
+static inline void writew(uint16_t datum, volatile void __iomem *addr)
+{
+	if (__is_PCI_MEM(addr))
+		datum = _swapw(datum);
+
+	__builtin_write16((volatile uint16_t __force *) addr, datum);
+	if (__is_PCI_MEM(addr))
+		__flush_PCI_writes();
+}
+
+static inline void writel(uint32_t datum, volatile void __iomem *addr)
+{
+	if (__is_PCI_MEM(addr))
+		datum = _swapl(datum);
+
+	__builtin_write32((volatile uint32_t __force *) addr, datum);
+	if (__is_PCI_MEM(addr))
+		__flush_PCI_writes();
+}
+
+
+/* Values for nocacheflag and cmode */
+#define IOMAP_FULL_CACHING		0
+#define IOMAP_NOCACHE_SER		1
+#define IOMAP_NOCACHE_NONSER		2
+#define IOMAP_WRITETHROUGH		3
+
+extern void __iomem *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag);
+extern void __iounmap(void __iomem *addr, unsigned long size);
+
+static inline void __iomem *ioremap(unsigned long physaddr, unsigned long size)
+{
+	return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
+}
+
+static inline void __iomem *ioremap_nocache(unsigned long physaddr, unsigned long size)
+{
+	return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
+}
+
+static inline void __iomem *ioremap_writethrough(unsigned long physaddr, unsigned long size)
+{
+	return __ioremap(physaddr, size, IOMAP_WRITETHROUGH);
+}
+
+static inline void __iomem *ioremap_fullcache(unsigned long physaddr, unsigned long size)
+{
+	return __ioremap(physaddr, size, IOMAP_FULL_CACHING);
+}
+
+extern void iounmap(void __iomem *addr);
+
+static inline void flush_write_buffers(void)
+{
+	__asm__ __volatile__ ("membar" : : :"memory");
+}
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_IO_H */
diff -Nru a/include/asm-frv/ioctl.h b/include/asm-frv/ioctl.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/ioctl.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,80 @@
+/*
+ * linux/ioctl.h for Linux by H.H. Bergman.
+ */
+
+#ifndef _ASM_IOCTL_H
+#define _ASM_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 !
+ */
+
+/*
+ * I don't really have any idea about what this should look like, so
+ * for the time being, this is heavily based on the PC definitions.
+ */
+
+/*
+ * 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 /* _ASM_IOCTL_H */
+
diff -Nru a/include/asm-frv/ioctls.h b/include/asm-frv/ioctls.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/ioctls.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,82 @@
+#ifndef __ASM_IOCTLS_H__
+#define __ASM_IOCTLS_H__
+
+#include <asm/ioctl.h>
+
+/* 0x54 is just a magic number to make these relatively unique ('T') */
+
+#define TCGETS		0x5401
+#define TCSETS		0x5402
+#define TCSETSW		0x5403
+#define TCSETSF		0x5404
+#define TCGETA		0x5405
+#define TCSETA		0x5406
+#define TCSETAW		0x5407
+#define TCSETAF		0x5408
+#define TCSBRK		0x5409
+#define TCXONC		0x540A
+#define TCFLSH		0x540B
+#define TIOCEXCL	0x540C
+#define TIOCNXCL	0x540D
+#define TIOCSCTTY	0x540E
+#define TIOCGPGRP	0x540F
+#define TIOCSPGRP	0x5410
+#define TIOCOUTQ	0x5411
+#define TIOCSTI		0x5412
+#define TIOCGWINSZ	0x5413
+#define TIOCSWINSZ	0x5414
+#define TIOCMGET	0x5415
+#define TIOCMBIS	0x5416
+#define TIOCMBIC	0x5417
+#define TIOCMSET	0x5418
+#define TIOCGSOFTCAR	0x5419
+#define TIOCSSOFTCAR	0x541A
+#define FIONREAD	0x541B
+#define TIOCINQ		FIONREAD
+#define TIOCLINUX	0x541C
+#define TIOCCONS	0x541D
+#define TIOCGSERIAL	0x541E
+#define TIOCSSERIAL	0x541F
+#define TIOCPKT		0x5420
+#define FIONBIO		0x5421
+#define TIOCNOTTY	0x5422
+#define TIOCSETD	0x5423
+#define TIOCGETD	0x5424
+#define TCSBRKP		0x5425	/* Needed for POSIX tcsendbreak() */
+#define TIOCTTYGSTRUCT	0x5426  /* For debugging only */
+#define TIOCSBRK	0x5427  /* BSD compatibility */
+#define TIOCCBRK	0x5428  /* BSD compatibility */
+#define TIOCGSID	0x5429  /* 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 FIONCLEX	0x5450  /* these numbers need to be adjusted. */
+#define FIOCLEX		0x5451
+#define FIOASYNC	0x5452
+#define TIOCSERCONFIG	0x5453
+#define TIOCSERGWILD	0x5454
+#define TIOCSERSWILD	0x5455
+#define TIOCGLCKTRMIOS	0x5456
+#define TIOCSLCKTRMIOS	0x5457
+#define TIOCSERGSTRUCT	0x5458 /* For debugging only */
+#define TIOCSERGETLSR   0x5459 /* Get line status register */
+#define TIOCSERGETMULTI 0x545A /* Get multiport config  */
+#define TIOCSERSETMULTI 0x545B /* Set multiport config */
+
+#define TIOCMIWAIT	0x545C	/* wait for a change on serial input line(s) */
+#define TIOCGICOUNT	0x545D	/* read serial port inline interrupt counts */
+#define FIOQSIZE	0x545E
+
+/* Used for packet mode */
+#define TIOCPKT_DATA		 0
+#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 TIOCSER_TEMT    0x01	/* Transmitter physically empty */
+
+#endif /* __ASM_IOCTLS_H__ */
+
diff -Nru a/include/asm-frv/ipc.h b/include/asm-frv/ipc.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/ipc.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,33 @@
+#ifndef __ASM_IPC_H__
+#define __ASM_IPC_H__
+
+/*
+ * These are used to wrap system calls on FR-V
+ *
+ * See arch/frv/kernel/sys_frv.c for ugly details..
+ */
+struct ipc_kludge {
+	struct msgbuf __user *msgp;
+	long msgtyp;
+};
+
+#define SEMOP		 1
+#define SEMGET		 2
+#define SEMCTL		 3
+#define SEMTIMEDOP	 4
+#define MSGSND		11
+#define MSGRCV		12
+#define MSGGET		13
+#define MSGCTL		14
+#define SHMAT		21
+#define SHMDT		22
+#define SHMGET		23
+#define SHMCTL		24
+
+/* Used by the DIPC package, try and avoid reusing it */
+#define DIPC		25
+
+#define IPCCALL(version,op)	((version)<<16 | (op))
+
+#endif
+
diff -Nru a/include/asm-frv/ipcbuf.h b/include/asm-frv/ipcbuf.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/ipcbuf.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,30 @@
+#ifndef __ASM_IPCBUF_H__
+#define __ASM_IPCBUF_H__
+
+/*
+ * The user_ipc_perm structure for FR-V architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 32-bit mode_t and seq
+ * - 2 miscellaneous 32-bit values
+ */
+
+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 short		__pad1;
+	unsigned short		seq;
+	unsigned short		__pad2;
+	unsigned long		__unused1;
+	unsigned long		__unused2;
+};
+
+#endif /* __ASM_IPCBUF_H__ */
+
diff -Nru a/include/asm-frv/irc-regs.h b/include/asm-frv/irc-regs.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/irc-regs.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,53 @@
+/* irc-regs.h: on-chip interrupt controller registers
+ *
+ * Copyright (C) 2003 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.
+ */
+
+#ifndef _ASM_IRC_REGS
+#define _ASM_IRC_REGS
+
+#define __reg(ADDR) (*(volatile unsigned long *)(ADDR))
+
+#define __get_TM0()	({ __reg(0xfeff9800); })
+#define __get_TM1()	({ __reg(0xfeff9808); })
+#define __set_TM1(V)	do { __reg(0xfeff9808) = (V); mb(); } while(0)
+
+#define __set_TM1x(XI,V)			\
+do {						\
+	int shift = (XI) * 2 + 16;		\
+	unsigned long tm1 = __reg(0xfeff9808);	\
+	tm1 &= ~(0x3 << shift);			\
+	tm1 |= (V) << shift;			\
+	__reg(0xfeff9808) = tm1;		\
+	mb();					\
+} while(0)
+
+#define __get_RS(C)	({ (__reg(0xfeff9810) >> ((C)+16)) & 1; })
+
+#define __clr_RC(C)	do { __reg(0xfeff9818) = 1 << ((C)+16); mb(); } while(0)
+
+#define __get_MASK(C)	({ (__reg(0xfeff9820) >> ((C)+16)) & 1; })
+#define __set_MASK(C)	do { __reg(0xfeff9820) |=  1 << ((C)+16); mb(); } while(0)
+#define __clr_MASK(C)	do { __reg(0xfeff9820) &=  ~(1 << ((C)+16)); mb(); } while(0)
+
+#define __get_MASK_all() __get_MASK(0)
+#define __set_MASK_all() __set_MASK(0)
+#define __clr_MASK_all() __clr_MASK(0)
+
+#define __get_IRL()	({ (__reg(0xfeff9828) >> 16) & 0xf; })
+#define __clr_IRL()	do { __reg(0xfeff9828) = 0x100000; mb(); } while(0)
+
+#define __get_IRR(N)	({ __reg(0xfeff9840 + (N) * 8); })
+#define __set_IRR(N,V)	do { __reg(0xfeff9840 + (N) * 8) = (V); } while(0)
+
+#define __get_IITMR(N)	({ __reg(0xfeff9880 + (N) * 8); })
+#define __set_IITMR(N,V) do { __reg(0xfeff9880 + (N) * 8) = (V); } while(0)
+
+
+#endif /* _ASM_IRC_REGS */
diff -Nru a/include/asm-frv/irq-routing.h b/include/asm-frv/irq-routing.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/irq-routing.h	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,70 @@
+/* irq-routing.h: multiplexed IRQ routing
+ *
+ * Copyright (C) 2004 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.
+ */
+
+#ifndef _ASM_IRQ_ROUTING_H
+#define _ASM_IRQ_ROUTING_H
+
+#ifndef __ASSEMBLY__
+
+#include <linux/spinlock.h>
+#include <asm/irq.h>
+
+struct irq_source;
+struct irq_level;
+
+/*
+ * IRQ action distribution sets
+ */
+struct irq_group {
+	int			first_irq;	/* first IRQ distributed here */
+	void (*control)(struct irq_group *group, int index, int on);
+
+	struct irqaction	*actions[NR_IRQ_ACTIONS_PER_GROUP];	/* IRQ action chains */
+	struct irq_source	*sources[NR_IRQ_ACTIONS_PER_GROUP];	/* IRQ sources */
+	int			disable_cnt[NR_IRQ_ACTIONS_PER_GROUP];	/* disable counts */
+};
+
+/*
+ * IRQ source manager
+ */
+struct irq_source {
+	struct irq_source	*next;
+	struct irq_level	*level;
+	const char		*muxname;
+	volatile void __iomem	*muxdata;
+	unsigned long		irqmask;
+
+	void (*doirq)(struct irq_source *source);
+};
+
+/*
+ * IRQ level management (per CPU IRQ priority / entry vector)
+ */
+struct irq_level {
+	int			usage;
+	int			disable_count;
+	unsigned long		flags;		/* current SA_INTERRUPT and SA_SHIRQ settings */
+	spinlock_t		lock;
+	struct irq_source	*sources;
+};
+
+extern struct irq_level frv_irq_levels[16];
+extern struct irq_group *irq_groups[NR_IRQ_GROUPS];
+
+extern void frv_irq_route(struct irq_source *source, int irqlevel);
+extern void frv_irq_route_external(struct irq_source *source, int irq);
+extern void frv_irq_set_group(struct irq_group *group);
+extern void distribute_irqs(struct irq_group *group, unsigned long irqmask);
+extern void route_cpu_irqs(void);
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _ASM_IRQ_ROUTING_H */
diff -Nru a/include/asm-frv/irq.h b/include/asm-frv/irq.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/irq.h	2005-03-01 23:39:26 -08:00
@@ -0,0 +1,44 @@
+/* irq.h: FRV IRQ definitions
+ *
+ * Copyright (C) 2004 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.
+ */
+
+#ifndef _ASM_IRQ_H_
+#define _ASM_IRQ_H_
+
+#include <linux/config.h>
+
+/*
+ * the system has an on-CPU PIC and another PIC on the FPGA and other PICs on other peripherals,
+ * so we do some routing in irq-routing.[ch] to reduce the number of false-positives seen by
+ * drivers
+ */
+
+/* this number is used when no interrupt has been assigned */
+#define NO_IRQ				(-1)
+
+#define NR_IRQ_LOG2_ACTIONS_PER_GROUP	5
+#define NR_IRQ_ACTIONS_PER_GROUP	(1 << NR_IRQ_LOG2_ACTIONS_PER_GROUP)
+#define NR_IRQ_GROUPS			4
+#define NR_IRQS				(NR_IRQ_ACTIONS_PER_GROUP * NR_IRQ_GROUPS)
+
+/* probe returns a 32-bit IRQ mask:-/ */
+#define MIN_PROBE_IRQ	(NR_IRQS - 32)
+
+static inline int irq_canonicalize(int irq)
+{
+	return irq;
+}
+
+extern void disable_irq_nosync(unsigned int irq);
+extern void disable_irq(unsigned int irq);
+extern void enable_irq(unsigned int irq);
+
+
+#endif /* _ASM_IRQ_H_ */
diff -Nru a/include/asm-frv/kmap_types.h b/include/asm-frv/kmap_types.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/kmap_types.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,29 @@
+
+#ifndef _ASM_KMAP_TYPES_H
+#define _ASM_KMAP_TYPES_H
+
+enum km_type {
+	/* arch specific kmaps - change the numbers attached to these at your peril */
+	__KM_CACHE,		/* cache flush page attachment point */
+	__KM_PGD,		/* current page directory */
+	__KM_ITLB_PTD,		/* current instruction TLB miss page table lookup */
+	__KM_DTLB_PTD,		/* current data TLB miss page table lookup */
+
+	/* general kmaps */
+        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
diff -Nru a/include/asm-frv/linkage.h b/include/asm-frv/linkage.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/linkage.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,7 @@
+#ifndef __ASM_LINKAGE_H
+#define __ASM_LINKAGE_H
+
+#define __ALIGN		.align 4
+#define __ALIGN_STR	".align 4"
+
+#endif
diff -Nru a/include/asm-frv/local.h b/include/asm-frv/local.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/local.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,6 @@
+#ifndef _ASM_LOCAL_H
+#define _ASM_LOCAL_H
+
+#include <asm-generic/local.h>
+
+#endif /* _ASM_LOCAL_H */
diff -Nru a/include/asm-frv/math-emu.h b/include/asm-frv/math-emu.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/math-emu.h	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,301 @@
+#ifndef _ASM_MATH_EMU_H
+#define _ASM_MATH_EMU_H
+
+#include <asm/setup.h>
+#include <linux/linkage.h>
+
+/* Status Register bits */
+
+/* accrued exception bits */
+#define FPSR_AEXC_INEX	3
+#define FPSR_AEXC_DZ	4
+#define FPSR_AEXC_UNFL	5
+#define FPSR_AEXC_OVFL	6
+#define FPSR_AEXC_IOP	7
+
+/* exception status bits */
+#define FPSR_EXC_INEX1	8
+#define FPSR_EXC_INEX2	9
+#define FPSR_EXC_DZ	10
+#define FPSR_EXC_UNFL	11
+#define FPSR_EXC_OVFL	12
+#define FPSR_EXC_OPERR	13
+#define FPSR_EXC_SNAN	14
+#define FPSR_EXC_BSUN	15
+
+/* quotient byte, assumes big-endian, of course */
+#define FPSR_QUOTIENT(fpsr) (*((signed char *) &(fpsr) + 1))
+
+/* condition code bits */
+#define FPSR_CC_NAN	24
+#define FPSR_CC_INF	25
+#define FPSR_CC_Z	26
+#define FPSR_CC_NEG	27
+
+
+/* Control register bits */
+
+/* rounding mode */
+#define	FPCR_ROUND_RN	0		/* round to nearest/even */
+#define FPCR_ROUND_RZ	1		/* round to zero */
+#define FPCR_ROUND_RM	2		/* minus infinity */
+#define FPCR_ROUND_RP	3		/* plus infinity */
+
+/* rounding precision */
+#define FPCR_PRECISION_X	0	/* long double */
+#define FPCR_PRECISION_S	1	/* double */
+#define FPCR_PRECISION_D	2	/* float */
+
+
+/* Flags to select the debugging output */
+#define PDECODE		0
+#define PEXECUTE	1
+#define PCONV		2
+#define PNORM		3
+#define PREGISTER	4
+#define PINSTR		5
+#define PUNIMPL		6
+#define PMOVEM		7
+
+#define PMDECODE	(1<<PDECODE)
+#define PMEXECUTE	(1<<PEXECUTE)
+#define PMCONV		(1<<PCONV)
+#define PMNORM		(1<<PNORM)
+#define PMREGISTER	(1<<PREGISTER)
+#define PMINSTR		(1<<PINSTR)
+#define PMUNIMPL	(1<<PUNIMPL)
+#define PMMOVEM		(1<<PMOVEM)
+
+#ifndef __ASSEMBLY__
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+union fp_mant64 {
+	unsigned long long m64;
+	unsigned long m32[2];
+};
+
+union fp_mant128 {
+	unsigned long long m64[2];
+	unsigned long m32[4];
+};
+
+/* internal representation of extended fp numbers */
+struct fp_ext {
+	unsigned char lowmant;
+	unsigned char sign;
+	unsigned short exp;
+	union fp_mant64 mant;
+};
+
+/* C representation of FPU registers */
+/* NOTE: if you change this, you have to change the assembler offsets
+   below and the size in <asm/fpu.h>, too */
+struct fp_data {
+	struct fp_ext fpreg[8];
+	unsigned int fpcr;
+	unsigned int fpsr;
+	unsigned int fpiar;
+	unsigned short prec;
+	unsigned short rnd;
+	struct fp_ext temp[2];
+};
+
+#if FPU_EMU_DEBUG
+extern unsigned int fp_debugprint;
+
+#define dprint(bit, fmt, args...) ({			\
+	if (fp_debugprint & (1 << (bit)))		\
+		printk(fmt, ## args);			\
+})
+#else
+#define dprint(bit, fmt, args...)
+#endif
+
+#define uprint(str) ({					\
+	static int __count = 3;				\
+							\
+	if (__count > 0) {				\
+		printk("You just hit an unimplemented "	\
+		       "fpu instruction (%s)\n", str);	\
+		printk("Please report this to ....\n");	\
+		__count--;				\
+	}						\
+})
+
+#define FPDATA		((struct fp_data *)current->thread.fp)
+
+#else	/* __ASSEMBLY__ */
+
+#define FPDATA		%a2
+
+/* offsets from the base register to the floating point data in the task struct */
+#define FPD_FPREG	(TASK_THREAD+THREAD_FPREG+0)
+#define FPD_FPCR	(TASK_THREAD+THREAD_FPREG+96)
+#define FPD_FPSR	(TASK_THREAD+THREAD_FPREG+100)
+#define FPD_FPIAR	(TASK_THREAD+THREAD_FPREG+104)
+#define FPD_PREC	(TASK_THREAD+THREAD_FPREG+108)
+#define FPD_RND		(TASK_THREAD+THREAD_FPREG+110)
+#define FPD_TEMPFP1	(TASK_THREAD+THREAD_FPREG+112)
+#define FPD_TEMPFP2	(TASK_THREAD+THREAD_FPREG+124)
+#define FPD_SIZEOF	(TASK_THREAD+THREAD_FPREG+136)
+
+/* offsets on the stack to access saved registers,
+ * these are only used during instruction decoding
+ * where we always know how deep we're on the stack.
+ */
+#define FPS_DO		(PT_D0)
+#define FPS_D1		(PT_D1)
+#define FPS_D2		(PT_D2)
+#define FPS_A0		(PT_A0)
+#define FPS_A1		(PT_A1)
+#define FPS_A2		(PT_A2)
+#define FPS_SR		(PT_SR)
+#define FPS_PC		(PT_PC)
+#define FPS_EA		(PT_PC+6)
+#define FPS_PC2		(PT_PC+10)
+
+.macro	fp_get_fp_reg
+	lea	(FPD_FPREG,FPDATA,%d0.w*4),%a0
+	lea	(%a0,%d0.w*8),%a0
+.endm
+
+/* Macros used to get/put the current program counter.
+ * 020/030 use a different stack frame then 040/060, for the
+ * 040/060 the return pc points already to the next location,
+ * so this only needs to be modified for jump instructions.
+ */
+.macro	fp_get_pc dest
+	move.l	(FPS_PC+4,%sp),\dest
+.endm
+
+.macro	fp_put_pc src,jump=0
+	move.l	\src,(FPS_PC+4,%sp)
+.endm
+
+.macro	fp_get_instr_data	f,s,dest,label
+	getuser	\f,%sp@(FPS_PC+4)@(0),\dest,\label,%sp@(FPS_PC+4)
+	addq.l	#\s,%sp@(FPS_PC+4)
+.endm
+
+.macro	fp_get_instr_word	dest,label,addr
+	fp_get_instr_data	w,2,\dest,\label,\addr
+.endm
+
+.macro	fp_get_instr_long	dest,label,addr
+	fp_get_instr_data	l,4,\dest,\label,\addr
+.endm
+
+/* These macros are used to read from/write to user space
+ * on error we jump to the fixup section, load the fault
+ * address into %a0 and jump to the exit.
+ * (derived from <asm/uaccess.h>)
+ */
+.macro	getuser	size,src,dest,label,addr
+|	printf	,"[\size<%08x]",1,\addr
+.Lu1\@:	moves\size	\src,\dest
+
+	.section .fixup,"ax"
+	.even
+.Lu2\@:	move.l	\addr,%a0
+	jra	\label
+	.previous
+
+	.section __ex_table,"a"
+	.align	4
+	.long	.Lu1\@,.Lu2\@
+	.previous
+.endm
+
+.macro	putuser	size,src,dest,label,addr
+|	printf	,"[\size>%08x]",1,\addr
+.Lu1\@:	moves\size	\src,\dest
+.Lu2\@:
+
+	.section .fixup,"ax"
+	.even
+.Lu3\@:	move.l	\addr,%a0
+	jra	\label
+	.previous
+
+	.section __ex_table,"a"
+	.align	4
+	.long	.Lu1\@,.Lu3\@
+	.long	.Lu2\@,.Lu3\@
+	.previous
+.endm
+
+
+.macro	movestack	nr,arg1,arg2,arg3,arg4,arg5
+	.if	\nr
+	movestack	(\nr-1),\arg2,\arg3,\arg4,\arg5
+	move.l	\arg1,-(%sp)
+	.endif
+.endm
+
+.macro	printf	bit=-1,string,nr=0,arg1,arg2,arg3,arg4,arg5
+#ifdef FPU_EMU_DEBUG
+	.data
+.Lpdata\@:
+	.string	"\string"
+	.previous
+
+	movem.l	%d0/%d1/%a0/%a1,-(%sp)
+	.if	\bit+1
+#if 0
+	moveq	#\bit,%d0
+	andw	#7,%d0
+	btst	%d0,fp_debugprint+((31-\bit)/8)
+#else
+	btst	#\bit,fp_debugprint+((31-\bit)/8)
+#endif
+	jeq	.Lpskip\@
+	.endif
+	movestack	\nr,\arg1,\arg2,\arg3,\arg4,\arg5
+	pea	.Lpdata\@
+	jsr	printk
+	lea	((\nr+1)*4,%sp),%sp
+.Lpskip\@:
+	movem.l	(%sp)+,%d0/%d1/%a0/%a1
+#endif
+.endm
+
+.macro	printx	bit,fp
+#ifdef FPU_EMU_DEBUG
+	movem.l	%d0/%a0,-(%sp)
+	lea	\fp,%a0
+#if 0
+	moveq	#'+',%d0
+	tst.w	(%a0)
+	jeq	.Lx1\@
+	moveq	#'-',%d0
+.Lx1\@:	printf	\bit," %c",1,%d0
+	move.l	(4,%a0),%d0
+	bclr	#31,%d0
+	jne	.Lx2\@
+	printf	\bit,"0."
+	jra	.Lx3\@
+.Lx2\@:	printf	\bit,"1."
+.Lx3\@:	printf	\bit,"%08x%08x",2,%d0,%a0@(8)
+	move.w	(2,%a0),%d0
+	ext.l	%d0
+	printf	\bit,"E%04x",1,%d0
+#else
+	printf	\bit," %08x%08x%08x",3,%a0@,%a0@(4),%a0@(8)
+#endif
+	movem.l	(%sp)+,%d0/%a0
+#endif
+.endm
+
+.macro	debug	instr,args
+#ifdef FPU_EMU_DEBUG
+	\instr	\args
+#endif
+.endm
+
+
+#endif	/* __ASSEMBLY__ */
+
+#endif	/* _ASM_FRV_MATH_EMU_H */
+
diff -Nru a/include/asm-frv/mb-regs.h b/include/asm-frv/mb-regs.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/mb-regs.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,185 @@
+/* mb-regs.h: motherboard registers
+ *
+ * Copyright (C) 2003, 2004 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.
+ */
+
+#ifndef _ASM_MB_REGS_H
+#define _ASM_MB_REGS_H
+
+#include <asm/cpu-irqs.h>
+#include <asm/sections.h>
+#include <asm/mem-layout.h>
+
+#define __region_IO	KERNEL_IO_START	/* the region from 0xe0000000 to 0xffffffff has suitable
+					 * protection laid over the top for use in memory-mapped
+					 * I/O
+					 */
+
+#define __region_CS0	0xff000000	/* Boot ROMs area */
+
+#ifdef CONFIG_MB93091_VDK
+/*
+ * VDK motherboard and CPU card specific stuff
+ */
+
+#include <asm/mb93091-fpga-irqs.h>
+
+#define IRQ_CPU_MB93493_0	IRQ_CPU_EXTERNAL0
+#define IRQ_CPU_MB93493_1	IRQ_CPU_EXTERNAL1
+
+#define __region_CS2	0xe0000000	/* SLBUS/PCI I/O space */
+#define __region_CS2_M		0x0fffffff /* mask */
+#define __region_CS2_C		0x00000000 /* control */
+#define __region_CS5	0xf0000000	/* MB93493 CSC area (DAV daughter board) */
+#define __region_CS5_M		0x00ffffff
+#define __region_CS5_C		0x00010000
+#define __region_CS7	0xf1000000	/* CB70 CPU-card PCMCIA port I/O space */
+#define __region_CS7_M		0x00ffffff
+#define __region_CS7_C		0x00410701
+#define __region_CS1	0xfc000000	/* SLBUS/PCI bridge control registers */
+#define __region_CS1_M		0x000fffff
+#define __region_CS1_C		0x00000000
+#define __region_CS6	0xfc100000	/* CB70 CPU-card DM9000 LAN I/O space */
+#define __region_CS6_M		0x000fffff
+#define __region_CS6_C		0x00400707
+#define __region_CS3	0xfc200000	/* MB93493 CSR area (DAV daughter board) */
+#define __region_CS3_M		0x000fffff
+#define __region_CS3_C		0xc8100000
+#define __region_CS4	0xfd000000	/* CB70 CPU-card extra flash space */
+#define __region_CS4_M		0x00ffffff
+#define __region_CS4_C		0x00000f07
+
+#define __region_PCI_IO		(__region_CS2 + 0x04000000UL)
+#define __region_PCI_MEM	(__region_CS2 + 0x08000000UL)
+#define __flush_PCI_writes()						\
+do {									\
+	__builtin_write8((volatile void *) __region_PCI_MEM, 0);	\
+} while(0)
+
+#define __is_PCI_IO(addr) \
+	(((unsigned long)(addr) >> 24) - (__region_PCI_IO >> 24)  < (0x04000000UL >> 24))
+
+#define __is_PCI_MEM(addr) \
+	((unsigned long)(addr) - __region_PCI_MEM < 0x08000000UL)
+
+#define __get_CLKSW()	({ *(volatile unsigned long *)(__region_CS2 + 0x0130000cUL) & 0xffUL; })
+#define __get_CLKIN()	(__get_CLKSW() * 125U * 100000U / 24U)
+
+#ifndef __ASSEMBLY__
+extern int __nongprelbss mb93090_mb00_detected;
+#endif
+
+#define __addr_LEDS()		(__region_CS2 + 0x01200004UL)
+#ifdef CONFIG_MB93090_MB00
+#define __set_LEDS(X)							\
+do {									\
+	if (mb93090_mb00_detected)					\
+		__builtin_write32((void *) __addr_LEDS(), ~(X));	\
+} while (0)
+#else
+#define __set_LEDS(X)
+#endif
+
+#define __addr_LCD()		(__region_CS2 + 0x01200008UL)
+#define __get_LCD(B)		__builtin_read32((volatile void *) (B))
+#define __set_LCD(B,X)		__builtin_write32((volatile void *) (B), (X))
+
+#define LCD_D			0x000000ff		/* LCD data bus */
+#define LCD_RW			0x00000100		/* LCD R/W signal */
+#define LCD_RS			0x00000200		/* LCD Register Select */
+#define LCD_E			0x00000400		/* LCD Start Enable Signal */
+
+#define LCD_CMD_CLEAR		(LCD_E|0x001)
+#define LCD_CMD_HOME		(LCD_E|0x002)
+#define LCD_CMD_CURSOR_INC	(LCD_E|0x004)
+#define LCD_CMD_SCROLL_INC	(LCD_E|0x005)
+#define LCD_CMD_CURSOR_DEC	(LCD_E|0x006)
+#define LCD_CMD_SCROLL_DEC	(LCD_E|0x007)
+#define LCD_CMD_OFF		(LCD_E|0x008)
+#define LCD_CMD_ON(CRSR,BLINK)	(LCD_E|0x00c|(CRSR<<1)|BLINK)
+#define LCD_CMD_CURSOR_MOVE_L	(LCD_E|0x010)
+#define LCD_CMD_CURSOR_MOVE_R	(LCD_E|0x014)
+#define LCD_CMD_DISPLAY_SHIFT_L	(LCD_E|0x018)
+#define LCD_CMD_DISPLAY_SHIFT_R	(LCD_E|0x01c)
+#define LCD_CMD_FUNCSET(DL,N,F)	(LCD_E|0x020|(DL<<4)|(N<<3)|(F<<2))
+#define LCD_CMD_SET_CG_ADDR(X)	(LCD_E|0x040|X)
+#define LCD_CMD_SET_DD_ADDR(X)	(LCD_E|0x080|X)
+#define LCD_CMD_READ_BUSY	(LCD_E|LCD_RW)
+#define LCD_DATA_WRITE(X)	(LCD_E|LCD_RS|(X))
+#define LCD_DATA_READ		(LCD_E|LCD_RS|LCD_RW)
+
+#else
+/*
+ * PDK unit specific stuff
+ */
+
+#include <asm/mb93093-fpga-irqs.h>
+
+#define IRQ_CPU_MB93493_0	IRQ_CPU_EXTERNAL0
+#define IRQ_CPU_MB93493_1	IRQ_CPU_EXTERNAL1
+
+#define __region_CS5	0xf0000000	/* MB93493 CSC area (DAV daughter board) */
+#define __region_CS5_M		0x00ffffff /* mask */
+#define __region_CS5_C		0x00010000 /* control */
+#define __region_CS2	0x20000000	/* FPGA registers */
+#define __region_CS2_M		0x000fffff
+#define __region_CS2_C		0x00000000
+#define __region_CS1	0xfc100000	/* LAN registers */
+#define __region_CS1_M		0x000fffff
+#define __region_CS1_C		0x00010404
+#define __region_CS3	0xfc200000	/* MB93493 CSR area (DAV daughter board) */
+#define __region_CS3_M		0x000fffff
+#define __region_CS3_C		0xc8000000
+#define __region_CS4	0xfd000000	/* extra ROMs area */
+#define __region_CS4_M		0x00ffffff
+#define __region_CS4_C		0x00000f07
+
+#define __region_CS6	0xfe000000	/* not used - hide behind CPU resource I/O regs */
+#define __region_CS6_M		0x000fffff
+#define __region_CS6_C		0x00000f07
+#define __region_CS7	0xfe000000	/* not used - hide behind CPU resource I/O regs */
+#define __region_CS7_M		0x000fffff
+#define __region_CS7_C		0x00000f07
+
+#define __is_PCI_IO(addr)	0	/* no PCI */
+#define __is_PCI_MEM(addr)	0
+#define __region_PCI_IO		0
+#define __region_PCI_MEM	0
+#define __flush_PCI_writes()	do { } while(0)
+
+#define __get_CLKSW()		0UL
+#define __get_CLKIN()		66000000UL
+
+#define __addr_LEDS()		(__region_CS2 + 0x00000023UL)
+#define __set_LEDS(X)		__builtin_write8((volatile void *) __addr_LEDS(), (X))
+
+#define __addr_FPGATR()		(__region_CS2 + 0x00000030UL)
+#define __set_FPGATR(X)		__builtin_write32((volatile void *) __addr_FPGATR(), (X))
+#define __get_FPGATR()		__builtin_read32((volatile void *) __addr_FPGATR())
+
+#define MB93093_FPGA_FPGATR_AUDIO_CLK	0x00000003
+
+#define __set_FPGATR_AUDIO_CLK(V) \
+	__set_FPGATR((__get_FPGATR() & ~MB93093_FPGA_FPGATR_AUDIO_CLK) | (V))
+
+#define MB93093_FPGA_FPGATR_AUDIO_CLK_OFF	0x0
+#define MB93093_FPGA_FPGATR_AUDIO_CLK_11MHz	0x1
+#define MB93093_FPGA_FPGATR_AUDIO_CLK_12MHz	0x2
+#define MB93093_FPGA_FPGATR_AUDIO_CLK_02MHz	0x3
+
+#define MB93093_FPGA_SWR_PUSHSWMASK	(0x1F<<26)
+#define MB93093_FPGA_SWR_PUSHSW4	(1<<29)
+
+#define __addr_FPGA_SWR		((volatile void *)(__region_CS2 + 0x28UL))
+#define __get_FPGA_PUSHSW1_5()	(__builtin_read32(__addr_FPGA_SWR) & MB93093_FPGA_SWR_PUSHSWMASK)
+
+
+#endif
+
+#endif /* _ASM_MB_REGS_H */
diff -Nru a/include/asm-frv/mb86943a.h b/include/asm-frv/mb86943a.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/mb86943a.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,39 @@
+/* mb86943a.h: MB86943 SPARClite <-> PCI bridge registers
+ *
+ * Copyright (C) 2003 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.
+ */
+
+#ifndef _ASM_MB86943A_H
+#define _ASM_MB86943A_H
+
+#include <asm/mb-regs.h>
+
+#define __reg_MB86943_sl_ctl		*(volatile uint32_t *) (__region_CS1 + 0x00)
+
+#define MB86943_SL_CTL_BUS_WIDTH_64	0x00000001
+#define MB86943_SL_CTL_AS_HOST		0x00000002
+#define MB86943_SL_CTL_DRCT_MASTER_SWAP	0x00000004
+#define MB86943_SL_CTL_DRCT_SLAVE_SWAP	0x00000008
+#define MB86943_SL_CTL_PCI_CONFIG_SWAP	0x00000010
+#define MB86943_SL_CTL_ECS0_ENABLE	0x00000020
+#define MB86943_SL_CTL_ECS1_ENABLE	0x00000040
+#define MB86943_SL_CTL_ECS2_ENABLE	0x00000080
+
+#define __reg_MB86943_ecs_ctl(N)	*(volatile uint32_t *) (__region_CS1 + 0x08 + (0x08*(N)))
+#define __reg_MB86943_ecs_range(N)	*(volatile uint32_t *) (__region_CS1 + 0x20 + (0x10*(N)))
+#define __reg_MB86943_ecs_base(N)	*(volatile uint32_t *) (__region_CS1 + 0x28 + (0x10*(N)))
+
+#define __reg_MB86943_sl_pci_io_range	*(volatile uint32_t *) (__region_CS1 + 0x50)
+#define __reg_MB86943_sl_pci_io_base	*(volatile uint32_t *) (__region_CS1 + 0x58)
+#define __reg_MB86943_sl_pci_mem_range	*(volatile uint32_t *) (__region_CS1 + 0x60)
+#define __reg_MB86943_sl_pci_mem_base	*(volatile uint32_t *) (__region_CS1 + 0x68)
+#define __reg_MB86943_pci_sl_io_base	*(volatile uint32_t *) (__region_CS1 + 0x70)
+#define __reg_MB86943_pci_sl_mem_base	*(volatile uint32_t *) (__region_CS1 + 0x78)
+
+#endif /* _ASM_MB86943A_H */
diff -Nru a/include/asm-frv/mb93091-fpga-irqs.h b/include/asm-frv/mb93091-fpga-irqs.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/mb93091-fpga-irqs.h	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,44 @@
+/* mb93091-fpga-irqs.h: MB93091 CPU board FPGA IRQs
+ *
+ * Copyright (C) 2004 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.
+ */
+
+#ifndef _ASM_MB93091_FPGA_IRQS_H
+#define _ASM_MB93091_FPGA_IRQS_H
+
+#ifndef __ASSEMBLY__
+
+#include <asm/irq-routing.h>
+
+#define IRQ_BASE_FPGA		(NR_IRQ_ACTIONS_PER_GROUP * 1)
+
+/* IRQ IDs presented to drivers */
+enum {
+	IRQ_FPGA__UNUSED			= IRQ_BASE_FPGA,
+	IRQ_FPGA_SYSINT_BUS_EXPANSION_1,
+	IRQ_FPGA_SL_BUS_EXPANSION_2,
+	IRQ_FPGA_PCI_INTD,
+	IRQ_FPGA_PCI_INTC,
+	IRQ_FPGA_PCI_INTB,
+	IRQ_FPGA_PCI_INTA,
+	IRQ_FPGA_SL_BUS_EXPANSION_7,
+	IRQ_FPGA_SYSINT_BUS_EXPANSION_8,
+	IRQ_FPGA_SL_BUS_EXPANSION_9,
+	IRQ_FPGA_MB86943_PCI_INTA,
+	IRQ_FPGA_MB86943_SLBUS_SIDE,
+	IRQ_FPGA_RTL8029_INTA,
+	IRQ_FPGA_SYSINT_BUS_EXPANSION_13,
+	IRQ_FPGA_SL_BUS_EXPANSION_14,
+	IRQ_FPGA_NMI,
+};
+
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _ASM_MB93091_FPGA_IRQS_H */
diff -Nru a/include/asm-frv/mb93093-fpga-irqs.h b/include/asm-frv/mb93093-fpga-irqs.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/mb93093-fpga-irqs.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,31 @@
+/* mb93093-fpga-irqs.h: MB93093 CPU board FPGA IRQs
+ *
+ * Copyright (C) 2004 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.
+ */
+
+#ifndef _ASM_MB93093_FPGA_IRQS_H
+#define _ASM_MB93093_FPGA_IRQS_H
+
+#ifndef __ASSEMBLY__
+
+#include <asm/irq-routing.h>
+
+#define IRQ_BASE_FPGA		(NR_IRQ_ACTIONS_PER_GROUP * 1)
+
+/* IRQ IDs presented to drivers */
+enum {
+	IRQ_FPGA_PUSH_BUTTON_SW1_5		= IRQ_BASE_FPGA + 8,
+	IRQ_FPGA_ROCKER_C_SW8			= IRQ_BASE_FPGA + 9,
+	IRQ_FPGA_ROCKER_C_SW9			= IRQ_BASE_FPGA + 10,
+};
+
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _ASM_MB93093_FPGA_IRQS_H */
diff -Nru a/include/asm-frv/mb93493-irqs.h b/include/asm-frv/mb93493-irqs.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/mb93493-irqs.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,52 @@
+/* mb93493-irqs.h: MB93493 companion chip IRQs
+ *
+ * Copyright (C) 2004 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.
+ */
+
+#ifndef _ASM_MB93493_IRQS_H
+#define _ASM_MB93493_IRQS_H
+
+#ifndef __ASSEMBLY__
+
+#include <asm/irq-routing.h>
+
+#define IRQ_BASE_MB93493	(NR_IRQ_ACTIONS_PER_GROUP * 2)
+
+/* IRQ IDs presented to drivers */
+enum {
+	IRQ_MB93493_VDC			= IRQ_BASE_MB93493 + 0,
+	IRQ_MB93493_VCC			= IRQ_BASE_MB93493 + 1,
+	IRQ_MB93493_AUDIO_OUT		= IRQ_BASE_MB93493 + 2,
+	IRQ_MB93493_I2C_0		= IRQ_BASE_MB93493 + 3,
+	IRQ_MB93493_I2C_1		= IRQ_BASE_MB93493 + 4,
+	IRQ_MB93493_USB			= IRQ_BASE_MB93493 + 5,
+	IRQ_MB93493_LOCAL_BUS		= IRQ_BASE_MB93493 + 7,
+	IRQ_MB93493_PCMCIA		= IRQ_BASE_MB93493 + 8,
+	IRQ_MB93493_GPIO		= IRQ_BASE_MB93493 + 9,
+	IRQ_MB93493_AUDIO_IN		= IRQ_BASE_MB93493 + 10,
+};
+
+/* IRQ multiplexor mappings */
+#define ROUTE_VIA_IRQ0	0	/* route IRQ by way of CPU external IRQ 0 */
+#define ROUTE_VIA_IRQ1	1	/* route IRQ by way of CPU external IRQ 1 */
+
+#define IRQ_MB93493_VDC_ROUTE		ROUTE_VIA_IRQ0
+#define IRQ_MB93493_VCC_ROUTE		ROUTE_VIA_IRQ1
+#define IRQ_MB93493_AUDIO_OUT_ROUTE	ROUTE_VIA_IRQ1
+#define IRQ_MB93493_I2C_0_ROUTE		ROUTE_VIA_IRQ1
+#define IRQ_MB93493_I2C_1_ROUTE		ROUTE_VIA_IRQ1
+#define IRQ_MB93493_USB_ROUTE		ROUTE_VIA_IRQ1
+#define IRQ_MB93493_LOCAL_BUS_ROUTE	ROUTE_VIA_IRQ1
+#define IRQ_MB93493_PCMCIA_ROUTE	ROUTE_VIA_IRQ1
+#define IRQ_MB93493_GPIO_ROUTE		ROUTE_VIA_IRQ1
+#define IRQ_MB93493_AUDIO_IN_ROUTE	ROUTE_VIA_IRQ1
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _ASM_MB93493_IRQS_H */
diff -Nru a/include/asm-frv/mb93493-regs.h b/include/asm-frv/mb93493-regs.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/mb93493-regs.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,279 @@
+/* mb93493-regs.h: MB93493 companion chip registers
+ *
+ * Copyright (C) 2004 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.
+ */
+
+#ifndef _ASM_MB93493_REGS_H
+#define _ASM_MB93493_REGS_H
+
+#include <asm/mb-regs.h>
+#include <asm/mb93493-irqs.h>
+
+#define __get_MB93493(X)	({ *(volatile unsigned long *)(__region_CS3 + (X)); })
+
+#define __set_MB93493(X,V)						\
+do {									\
+	*(volatile unsigned long *)(__region_CS3 + (X)) = (V); mb();	\
+} while(0)
+
+#define __get_MB93493_STSR(X)	__get_MB93493(0x3c0 + (X) * 4)
+#define __set_MB93493_STSR(X,V)	__set_MB93493(0x3c0 + (X) * 4, (V))
+#define MB93493_STSR_EN
+
+#define __get_MB93493_IQSR(X)	__get_MB93493(0x3d0 + (X) * 4)
+#define __set_MB93493_IQSR(X,V)	__set_MB93493(0x3d0 + (X) * 4, (V))
+
+#define __get_MB93493_DQSR(X)	__get_MB93493(0x3e0 + (X) * 4)
+#define __set_MB93493_DQSR(X,V)	__set_MB93493(0x3e0 + (X) * 4, (V))
+
+#define __get_MB93493_LBSER()	__get_MB93493(0x3f0)
+#define __set_MB93493_LBSER(V)	__set_MB93493(0x3f0, (V))
+
+#define MB93493_LBSER_VDC	0x00010000
+#define MB93493_LBSER_VCC	0x00020000
+#define MB93493_LBSER_AUDIO	0x00040000
+#define MB93493_LBSER_I2C_0	0x00080000
+#define MB93493_LBSER_I2C_1	0x00100000
+#define MB93493_LBSER_USB	0x00200000
+#define MB93493_LBSER_GPIO	0x00800000
+#define MB93493_LBSER_PCMCIA	0x01000000
+
+#define __get_MB93493_LBSR()	__get_MB93493(0x3fc)
+#define __set_MB93493_LBSR(V)	__set_MB93493(0x3fc, (V))
+
+/*
+ * video display controller
+ */
+#define __get_MB93493_VDC(X)	__get_MB93493(MB93493_VDC_##X)
+#define __set_MB93493_VDC(X,V)	__set_MB93493(MB93493_VDC_##X, (V))
+
+#define MB93493_VDC_RCURSOR	0x140	/* cursor position */
+#define MB93493_VDC_RCT1	0x144	/* cursor colour 1 */
+#define MB93493_VDC_RCT2	0x148	/* cursor colour 2 */
+#define MB93493_VDC_RHDC	0x150	/* horizontal display period */
+#define MB93493_VDC_RH_MARGINS	0x154	/* horizontal margin sizes */
+#define MB93493_VDC_RVDC	0x158	/* vertical display period */
+#define MB93493_VDC_RV_MARGINS	0x15c	/* vertical margin sizes */
+#define MB93493_VDC_RC		0x170	/* VDC control */
+#define MB93493_VDC_RCLOCK	0x174	/* clock divider, DMA req delay */
+#define MB93493_VDC_RBLACK	0x178	/* black insert sizes */
+#define MB93493_VDC_RS		0x17c	/* VDC status */
+
+#define __addr_MB93493_VDC_BCI(X)  ({ (volatile unsigned long *)(__region_CS3 + 0x000 + (X)); })
+#define __addr_MB93493_VDC_TPO(X)  (__region_CS3 + 0x1c0 + (X))
+
+#define VDC_TPO_WIDTH		32
+
+#define VDC_RC_DSR		0x00000080	/* VDC master reset */
+
+#define VDC_RS_IT		0x00060000	/* interrupt indicators */
+#define VDC_RS_IT_UNDERFLOW	0x00040000	/* - underflow event */
+#define VDC_RS_IT_VSYNC		0x00020000	/* - VSYNC event */
+#define VDC_RS_DFI		0x00010000	/* current interlace field number */
+#define VDC_RS_DFI_TOP		0x00000000	/* - top field */
+#define VDC_RS_DFI_BOTTOM	0x00010000	/* - bottom field */
+#define VDC_RS_DCSR		0x00000010	/* cursor state */
+#define VDC_RS_DCM		0x00000003	/* display mode */
+#define VDC_RS_DCM_DISABLED	0x00000000	/* - display disabled */
+#define VDC_RS_DCM_STOPPED	0x00000001	/* - VDC stopped */
+#define VDC_RS_DCM_FREERUNNING	0x00000002	/* - VDC free-running */
+#define VDC_RS_DCM_TRANSFERRING	0x00000003	/* - data being transferred to VDC */
+
+/*
+ * video capture controller
+ */
+#define __get_MB93493_VCC(X)	__get_MB93493(MB93493_VCC_##X)
+#define __set_MB93493_VCC(X,V)	__set_MB93493(MB93493_VCC_##X, (V))
+
+#define MB93493_VCC_RREDUCT	0x104	/* reduction rate */
+#define MB93493_VCC_RHY		0x108	/* horizontal brightness filter coefficients */
+#define MB93493_VCC_RHC		0x10c	/* horizontal colour-difference filter coefficients */
+#define MB93493_VCC_RHSIZE	0x110	/* horizontal cycle sizes */
+#define MB93493_VCC_RHBC	0x114	/* horizontal back porch size */
+#define MB93493_VCC_RVCC	0x118	/* vertical capture period */
+#define MB93493_VCC_RVBC	0x11c	/* vertical back porch period */
+#define MB93493_VCC_RV		0x120	/* vertical filter coefficients */
+#define MB93493_VCC_RDTS	0x128	/* DMA transfer size */
+#define MB93493_VCC_RDTS_4B	0x01000000	/* 4-byte transfer */
+#define MB93493_VCC_RDTS_32B	0x03000000	/* 32-byte transfer */
+#define MB93493_VCC_RDTS_SHIFT	24
+#define MB93493_VCC_RCC		0x130	/* VCC control */
+#define MB93493_VCC_RIS		0x134	/* VCC interrupt status */
+
+#define __addr_MB93493_VCC_TPI(X)  (__region_CS3 + 0x180 + (X))
+
+#define VCC_RHSIZE_RHCC		0x000007ff
+#define VCC_RHSIZE_RHCC_SHIFT	0
+#define VCC_RHSIZE_RHTCC	0x0fff0000
+#define VCC_RHSIZE_RHTCC_SHIFT	16
+
+#define VCC_RVBC_RVBC		0x00003f00
+#define VCC_RVBC_RVBC_SHIFT	8
+
+#define VCC_RREDUCT_RHR		0x07ff0000
+#define VCC_RREDUCT_RHR_SHIFT	16
+#define VCC_RREDUCT_RVR		0x000007ff
+#define VCC_RREDUCT_RVR_SHIFT	0
+
+#define VCC_RCC_CE		0x00000001	/* VCC enable */
+#define VCC_RCC_CS		0x00000002	/* request video capture start */
+#define VCC_RCC_CPF		0x0000000c	/* pixel format */
+#define VCC_RCC_CPF_YCBCR_16	0x00000000	/* - YCbCr 4:2:2 16-bit format */
+#define VCC_RCC_CPF_RGB		0x00000004	/* - RGB 4:4:4 format */
+#define VCC_RCC_CPF_YCBCR_24	0x00000008	/* - YCbCr 4:2:2 24-bit format */
+#define VCC_RCC_CPF_BT656	0x0000000c	/* - ITU R-BT.656 format */
+#define VCC_RCC_CPF_SHIFT	2
+#define VCC_RCC_CSR		0x00000080	/* request reset */
+#define VCC_RCC_HSIP		0x00000100	/* HSYNC polarity */
+#define VCC_RCC_HSIP_LOACT	0x00000000	/* - low active */
+#define VCC_RCC_HSIP_HIACT	0x00000100	/* - high active */
+#define VCC_RCC_VSIP		0x00000200	/* VSYNC polarity */
+#define VCC_RCC_VSIP_LOACT	0x00000000	/* - low active */
+#define VCC_RCC_VSIP_HIACT	0x00000200	/* - high active */
+#define VCC_RCC_CIE		0x00000800	/* interrupt enable */
+#define VCC_RCC_CFP		0x00001000	/* RGB pixel packing */
+#define VCC_RCC_CFP_4TO3	0x00000000	/* - pack 4 pixels into 3 words */
+#define VCC_RCC_CFP_1TO1	0x00001000	/* - pack 1 pixel into 1 words */
+#define VCC_RCC_CSM		0x00006000	/* interlace specification */
+#define VCC_RCC_CSM_ONEPASS	0x00002000	/* - non-interlaced */
+#define VCC_RCC_CSM_INTERLACE	0x00004000	/* - interlaced */
+#define VCC_RCC_CSM_SHIFT	13
+#define VCC_RCC_ES		0x00008000	/* capture start polarity */
+#define VCC_RCC_ES_NEG		0x00000000	/* - negative edge */
+#define VCC_RCC_ES_POS		0x00008000	/* - positive edge */
+#define VCC_RCC_IFI		0x00080000	/* inferlace field evaluation reverse */
+#define VCC_RCC_FDTS		0x00300000	/* interlace field start */
+#define VCC_RCC_FDTS_3_8	0x00000000	/* - 3/8 of horizontal entire cycle */
+#define VCC_RCC_FDTS_1_4	0x00100000	/* - 1/4 of horizontal entire cycle */
+#define VCC_RCC_FDTS_7_16	0x00200000	/* - 7/16 of horizontal entire cycle */
+#define VCC_RCC_FDTS_SHIFT	20
+#define VCC_RCC_MOV		0x00400000	/* test bit - always set to 1 */
+#define VCC_RCC_STP		0x00800000	/* request video capture stop */
+#define VCC_RCC_TO		0x01000000	/* input during top-field only */
+
+#define VCC_RIS_VSYNC		0x01000000	/* VSYNC interrupt */
+#define VCC_RIS_OV		0x02000000	/* overflow interrupt */
+#define VCC_RIS_BOTTOM		0x08000000	/* interlace bottom field */
+#define VCC_RIS_STARTED		0x10000000	/* capture started */
+
+/*
+ * I2C
+ */
+#define MB93493_I2C_BSR 	0x340		/* bus status */
+#define MB93493_I2C_BCR		0x344		/* bus control */
+#define MB93493_I2C_CCR		0x348		/* clock control */
+#define MB93493_I2C_ADR		0x34c		/* address */
+#define MB93493_I2C_DTR		0x350		/* data */
+#define MB93493_I2C_BC2R	0x35c		/* bus control 2 */
+
+#define __addr_MB93493_I2C(port,X)   (__region_CS3 + MB93493_I2C_##X + ((port)*0x20))
+#define __get_MB93493_I2C(port,X)    __get_MB93493(MB93493_I2C_##X + ((port)*0x20))
+#define __set_MB93493_I2C(port,X,V)  __set_MB93493(MB93493_I2C_##X + ((port)*0x20), (V))
+
+#define I2C_BSR_BB	(1 << 7)
+
+/*
+ * audio controller (I2S) registers
+ */
+#define __get_MB93493_I2S(X)	__get_MB93493(MB93493_I2S_##X)
+#define __set_MB93493_I2S(X,V)	__set_MB93493(MB93493_I2S_##X, (V))
+
+#define MB93493_I2S_ALDR	0x300		/* L-channel data */
+#define MB93493_I2S_ARDR	0x304		/* R-channel data */
+#define MB93493_I2S_APDR	0x308		/* 16-bit packed data */
+#define MB93493_I2S_AISTR	0x310		/* status */
+#define MB93493_I2S_AICR	0x314		/* control */
+
+#define __addr_MB93493_I2S_ALDR(X)	(__region_CS3 + MB93493_I2S_ALDR + (X))
+#define __addr_MB93493_I2S_ARDR(X)	(__region_CS3 + MB93493_I2S_ARDR + (X))
+#define __addr_MB93493_I2S_APDR(X)	(__region_CS3 + MB93493_I2S_APDR + (X))
+#define __addr_MB93493_I2S_ADR(X)	(__region_CS3 + 0x320 + (X))
+
+#define I2S_AISTR_OTST		0x00000003	/* status of output data transfer */
+#define I2S_AISTR_OTR		0x00000010	/* output transfer request pending */
+#define I2S_AISTR_OUR		0x00000020	/* output FIFO underrun detected */
+#define I2S_AISTR_OOR		0x00000040	/* output FIFO overrun detected */
+#define I2S_AISTR_ODS		0x00000100	/* output DMA transfer size */
+#define I2S_AISTR_ODE		0x00000400	/* output DMA transfer request enable */
+#define I2S_AISTR_OTRIE		0x00001000	/* output transfer request interrupt enable */
+#define I2S_AISTR_OURIE		0x00002000	/* output FIFO underrun interrupt enable */
+#define I2S_AISTR_OORIE		0x00004000	/* output FIFO overrun interrupt enable */
+#define I2S_AISTR__OUT_MASK	0x00007570
+#define I2S_AISTR_ITST		0x00030000	/* status of input data transfer */
+#define I2S_AISTR_ITST_SHIFT	16
+#define I2S_AISTR_ITR		0x00100000	/* input transfer request pending */
+#define I2S_AISTR_IUR		0x00200000	/* input FIFO underrun detected */
+#define I2S_AISTR_IOR		0x00400000	/* input FIFO overrun detected */
+#define I2S_AISTR_IDS		0x01000000	/* input DMA transfer size */
+#define I2S_AISTR_IDE		0x04000000	/* input DMA transfer request enable */
+#define I2S_AISTR_ITRIE		0x10000000	/* input transfer request interrupt enable */
+#define I2S_AISTR_IURIE		0x20000000	/* input FIFO underrun interrupt enable */
+#define I2S_AISTR_IORIE		0x40000000	/* input FIFO overrun interrupt enable */
+#define I2S_AISTR__IN_MASK	0x75700000
+
+#define I2S_AICR_MI		0x00000001	/* mono input requested */
+#define I2S_AICR_AMI		0x00000002	/* relation between LRCKI/FS1 and SDI */
+#define I2S_AICR_LRI		0x00000004	/* function of LRCKI pin */
+#define I2S_AICR_SDMI		0x00000070	/* format of input audio data */
+#define I2S_AICR_SDMI_SHIFT	4
+#define I2S_AICR_CLI		0x00000080	/* input FIFO clearing control */
+#define I2S_AICR_IM		0x00000300	/* input state control */
+#define I2S_AICR_IM_SHIFT	8
+#define I2S_AICR__IN_MASK	0x000003f7
+#define I2S_AICR_MO		0x00001000	/* mono output requested */
+#define I2S_AICR_AMO		0x00002000	/* relation between LRCKO/FS0 and SDO */
+#define I2S_AICR_AMO_SHIFT	13
+#define I2S_AICR_LRO		0x00004000	/* function of LRCKO pin */
+#define I2S_AICR_SDMO		0x00070000	/* format of output audio data */
+#define I2S_AICR_SDMO_SHIFT	16
+#define I2S_AICR_CLO		0x00080000	/* output FIFO clearing control */
+#define I2S_AICR_OM		0x00100000	/* output state control */
+#define I2S_AICR__OUT_MASK	0x001f7000
+#define I2S_AICR_DIV		0x03000000	/* frequency division rate */
+#define I2S_AICR_DIV_SHIFT	24
+#define I2S_AICR_FL		0x20000000	/* frame length */
+#define I2S_AICR_FS		0x40000000	/* frame sync method */
+#define I2S_AICR_ME		0x80000000	/* master enable */
+
+/*
+ * PCMCIA
+ */
+#define __addr_MB93493_PCMCIA(X)  ((volatile unsigned long *)(__region_CS5 + (X)))
+
+/*
+ * GPIO
+ */
+#define __get_MB93493_GPIO_PDR(X)	__get_MB93493(0x380 + (X) * 0xc0)
+#define __set_MB93493_GPIO_PDR(X,V)	__set_MB93493(0x380 + (X) * 0xc0, (V))
+
+#define __get_MB93493_GPIO_GPDR(X)	__get_MB93493(0x384 + (X) * 0xc0)
+#define __set_MB93493_GPIO_GPDR(X,V)	__set_MB93493(0x384 + (X) * 0xc0, (V))
+
+#define __get_MB93493_GPIO_SIR(X)	__get_MB93493(0x388 + (X) * 0xc0)
+#define __set_MB93493_GPIO_SIR(X,V)	__set_MB93493(0x388 + (X) * 0xc0, (V))
+
+#define __get_MB93493_GPIO_SOR(X)	__get_MB93493(0x38c + (X) * 0xc0)
+#define __set_MB93493_GPIO_SOR(X,V)	__set_MB93493(0x38c + (X) * 0xc0, (V))
+
+#define __get_MB93493_GPIO_PDSR(X)	__get_MB93493(0x390 + (X) * 0xc0)
+#define __set_MB93493_GPIO_PDSR(X,V)	__set_MB93493(0x390 + (X) * 0xc0, (V))
+
+#define __get_MB93493_GPIO_PDCR(X)	__get_MB93493(0x394 + (X) * 0xc0)
+#define __set_MB93493_GPIO_PDCR(X,V)	__set_MB93493(0x394 + (X) * 0xc0, (V))
+
+#define __get_MB93493_GPIO_INTST(X)	__get_MB93493(0x398 + (X) * 0xc0)
+#define __set_MB93493_GPIO_INTST(X,V)	__set_MB93493(0x398 + (X) * 0xc0, (V))
+
+#define __get_MB93493_GPIO_IEHL(X)	__get_MB93493(0x39c + (X) * 0xc0)
+#define __set_MB93493_GPIO_IEHL(X,V)	__set_MB93493(0x39c + (X) * 0xc0, (V))
+
+#define __get_MB93493_GPIO_IELH(X)	__get_MB93493(0x3a0 + (X) * 0xc0)
+#define __set_MB93493_GPIO_IELH(X,V)	__set_MB93493(0x3a0 + (X) * 0xc0, (V))
+
+#endif /* _ASM_MB93493_REGS_H */
diff -Nru a/include/asm-frv/mem-layout.h b/include/asm-frv/mem-layout.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/mem-layout.h	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,78 @@
+/* mem-layout.h: memory layout
+ *
+ * Copyright (C) 2004 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.
+ */
+
+#ifndef _ASM_MEM_LAYOUT_H
+#define _ASM_MEM_LAYOUT_H
+
+#ifndef __ASSEMBLY__
+#define __UL(X)	((unsigned long) (X))
+#else
+#define __UL(X)	(X)
+#endif
+
+/*
+ * PAGE_SHIFT determines the page size
+ */
+#define PAGE_SHIFT			14
+
+#ifndef __ASSEMBLY__
+#define PAGE_SIZE			(1UL << PAGE_SHIFT)
+#else
+#define PAGE_SIZE			(1 << PAGE_SHIFT)
+#endif
+
+#define PAGE_MASK			(~(PAGE_SIZE-1))
+
+/*****************************************************************************/
+/*
+ * virtual memory layout from kernel's point of view
+ */
+#define PAGE_OFFSET			((unsigned long) &__page_offset)
+
+#ifdef CONFIG_MMU
+
+/* see Documentation/fujitsu/frv/mmu-layout.txt */
+#define KERNEL_LOWMEM_START		__UL(0xc0000000)
+#define KERNEL_LOWMEM_END		__UL(0xd0000000)
+#define VMALLOC_START			__UL(0xd0000000)
+#define VMALLOC_END			__UL(0xd8000000)
+#define PKMAP_BASE			__UL(0xd8000000)
+#define PKMAP_END			__UL(0xdc000000)
+#define KMAP_ATOMIC_SECONDARY_FRAME	__UL(0xdc000000)
+#define KMAP_ATOMIC_PRIMARY_FRAME	__UL(0xdd000000)
+
+#endif
+
+#define KERNEL_IO_START			__UL(0xe0000000)
+
+
+/*****************************************************************************/
+/*
+ * memory layout from userspace's point of view
+ */
+#define BRK_BASE			__UL(2 * 1024 * 1024 + PAGE_SIZE)
+#define STACK_TOP			__UL(2 * 1024 * 1024)
+
+/* userspace process size */
+#ifdef CONFIG_MMU
+#define TASK_SIZE			(PAGE_OFFSET)
+#else
+#define TASK_SIZE			__UL(0xFFFFFFFFUL)
+#endif
+
+/* base of area at which unspecified mmaps will start */
+#ifdef CONFIG_BINFMT_ELF_FDPIC
+#define TASK_UNMAPPED_BASE		__UL(16 * 1024 * 1024)
+#else
+#define TASK_UNMAPPED_BASE		__UL(TASK_SIZE / 3)
+#endif
+
+#endif /* _ASM_MEM_LAYOUT_H */
diff -Nru a/include/asm-frv/mman.h b/include/asm-frv/mman.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/mman.h	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,44 @@
+#ifndef __ASM_MMAN_H__
+#define __ASM_MMAN_H__
+
+#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	0x8		/* page may be used for atomic ops */
+#define PROT_NONE	0x0		/* page can not be accessed */
+#define PROT_GROWSDOWN	0x01000000	/* mprotect flag: extend change to start of growsdown vma */
+#define PROT_GROWSUP	0x02000000	/* mprotect flag: extend change to end of growsup vma */
+
+#define MAP_SHARED	0x01		/* Share changes */
+#define MAP_PRIVATE	0x02		/* Changes are private */
+#define MAP_TYPE	0x0f		/* Mask for type of mapping */
+#define MAP_FIXED	0x10		/* Interpret addr exactly */
+#define MAP_ANONYMOUS	0x20		/* don't use a file */
+
+#define MAP_GROWSDOWN	0x0100		/* stack-like segment */
+#define MAP_DENYWRITE	0x0800		/* ETXTBSY */
+#define MAP_EXECUTABLE	0x1000		/* mark it as an executable */
+#define MAP_LOCKED	0x2000		/* pages are locked */
+#define MAP_NORESERVE	0x4000		/* don't check for reservations */
+#define MAP_POPULATE	0x8000		/* populate (prefault) pagetables */
+#define MAP_NONBLOCK	0x10000		/* do not block on IO */
+
+#define MS_ASYNC	1		/* sync memory asynchronously */
+#define MS_INVALIDATE	2		/* invalidate the caches */
+#define MS_SYNC		4		/* synchronous memory sync */
+
+#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 /* __ASM_MMAN_H__ */
+
diff -Nru a/include/asm-frv/mmu.h b/include/asm-frv/mmu.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/mmu.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,42 @@
+/* mmu.h: memory management context for FR-V with or without MMU support
+ *
+ * Copyright (C) 2004 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.
+ */
+#ifndef _ASM_MMU_H
+#define _ASM_MMU_H
+
+typedef struct {
+#ifdef CONFIG_MMU
+	struct list_head id_link;		/* link in list of context ID owners */
+	unsigned short	id;			/* MMU context ID */
+	unsigned short	id_busy;		/* true if ID is in CXNR */
+	unsigned long	itlb_cached_pge;	/* [SCR0] PGE cached for insn TLB handler */
+	unsigned long	itlb_ptd_mapping;	/* [DAMR4] PTD mapping for itlb cached PGE */
+	unsigned long	dtlb_cached_pge;	/* [SCR1] PGE cached for data TLB handler */
+	unsigned long	dtlb_ptd_mapping;	/* [DAMR5] PTD mapping for dtlb cached PGE */
+
+#else
+	struct vm_list_struct	*vmlist;
+	unsigned long		end_brk;
+
+#endif
+
+#ifdef CONFIG_BINFMT_ELF_FDPIC
+	unsigned long	exec_fdpic_loadmap;
+	unsigned long	interp_fdpic_loadmap;
+#endif
+
+} mm_context_t;
+
+#ifdef CONFIG_MMU
+extern int __nongpreldata cxn_pinned;
+extern int cxn_pin_by_pid(pid_t pid);
+#endif
+
+#endif /* _ASM_MMU_H */
diff -Nru a/include/asm-frv/mmu_context.h b/include/asm-frv/mmu_context.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/mmu_context.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,50 @@
+/* mmu_context.h: MMU context management routines
+ *
+ * Copyright (C) 2004 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.
+ */
+
+#ifndef _ASM_MMU_CONTEXT_H
+#define _ASM_MMU_CONTEXT_H
+
+#include <linux/config.h>
+#include <asm/setup.h>
+#include <asm/page.h>
+#include <asm/pgalloc.h>
+
+static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
+{
+}
+
+#ifdef CONFIG_MMU
+extern int init_new_context(struct task_struct *tsk, struct mm_struct *mm);
+extern void change_mm_context(mm_context_t *old, mm_context_t *ctx, pgd_t *_pgd);
+extern void destroy_context(struct mm_struct *mm);
+
+#else
+#define init_new_context(tsk, mm)		({ 0; })
+#define change_mm_context(old, ctx, _pml4)	do {} while(0)
+#define destroy_context(mm)			do {} while(0)
+#endif
+
+#define switch_mm(prev, next, tsk)						\
+do {										\
+	if (prev != next)							\
+		change_mm_context(&prev->context, &next->context, next->pgd);	\
+} while(0)
+
+#define activate_mm(prev, next)						\
+do {									\
+	change_mm_context(&prev->context, &next->context, next->pgd);	\
+} while(0)
+
+#define deactivate_mm(tsk, mm)			\
+do {						\
+} while(0)
+
+#endif
diff -Nru a/include/asm-frv/module.h b/include/asm-frv/module.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/module.h	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,20 @@
+/* module.h: FRV module stuff
+ *
+ * Copyright (C) 2004 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.
+ */
+#ifndef _ASM_MODULE_H
+#define _ASM_MODULE_H
+
+#define module_map(x)		vmalloc(x)
+#define module_unmap(x)		vfree(x)
+#define module_arch_init(x)	(0)
+#define arch_init_modules(x)	do { } while (0)
+
+#endif /* _ASM_MODULE_H */
+
diff -Nru a/include/asm-frv/msgbuf.h b/include/asm-frv/msgbuf.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/msgbuf.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,32 @@
+#ifndef _ASM_MSGBUF_H
+#define _ASM_MSGBUF_H
+
+/*
+ * The msqid64_ds structure for FR-V 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
+ */
+
+struct msqid64_ds {
+	struct ipc64_perm	msg_perm;
+	__kernel_time_t		msg_stime;	/* last msgsnd time */
+	unsigned long		__unused1;
+	__kernel_time_t		msg_rtime;	/* last msgrcv time */
+	unsigned long		__unused2;
+	__kernel_time_t		msg_ctime;	/* last change time */
+	unsigned long		__unused3;
+	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 /* _ASM_MSGBUF_H */
+
diff -Nru a/include/asm-frv/namei.h b/include/asm-frv/namei.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/namei.h	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,18 @@
+/*
+ * asm/namei.h
+ *
+ * Included from linux/fs/namei.c
+ */
+
+#ifndef __ASM_NAMEI_H
+#define __ASM_NAMEI_H
+
+/* 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
+
diff -Nru a/include/asm-frv/page.h b/include/asm-frv/page.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/page.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,105 @@
+#ifndef _ASM_PAGE_H
+#define _ASM_PAGE_H
+
+#ifdef __KERNEL__
+
+#include <linux/config.h>
+#include <asm/virtconvert.h>
+#include <asm/mem-layout.h>
+#include <asm/sections.h>
+#include <asm/setup.h>
+
+#ifndef __ASSEMBLY__
+
+#define get_user_page(vaddr)			__get_free_page(GFP_KERNEL)
+#define free_user_page(page, addr)		free_page(addr)
+
+#define clear_page(pgaddr)			memset((pgaddr), 0, PAGE_SIZE)
+#define copy_page(to,from)			memcpy((to), (from), PAGE_SIZE)
+
+#define clear_user_page(pgaddr, vaddr, page)	memset((pgaddr), 0, PAGE_SIZE)
+#define copy_user_page(vto, vfrom, vaddr, topg)	memcpy((vto), (vfrom), PAGE_SIZE)
+
+/*
+ * These are used to make use of C type-checking..
+ */
+typedef struct { unsigned long	pte;	} pte_t;
+typedef struct { unsigned long	ste[64];} pmd_t;
+typedef struct { pmd_t		pue[1]; } pud_t;
+typedef struct { pud_t		pge[1];	} pgd_t;
+typedef struct { unsigned long	pgprot;	} pgprot_t;
+
+#define pte_val(x)	((x).pte)
+#define pmd_val(x)	((x).ste[0])
+#define pud_val(x)	((x).pue[0])
+#define pgd_val(x)	((x).pge[0])
+#define pgprot_val(x)	((x).pgprot)
+
+#define __pte(x)	((pte_t) { (x) } )
+#define __pmd(x)	((pmd_t) { (x) } )
+#define __pud(x)	((pud_t) { (x) } )
+#define __pgd(x)	((pgd_t) { (x) } )
+#define __pgprot(x)	((pgprot_t) { (x) } )
+#define PTE_MASK	PAGE_MASK
+
+/* to align the pointer to the (next) page boundary */
+#define PAGE_ALIGN(addr)	(((addr) + PAGE_SIZE - 1) & PAGE_MASK)
+
+/* Pure 2^n version of get_order */
+static inline int get_order(unsigned long size) __attribute_const__;
+static inline int get_order(unsigned long size)
+{
+	int order;
+
+	size = (size - 1) >> (PAGE_SHIFT - 1);
+	order = -1;
+	do {
+		size >>= 1;
+		order++;
+	} while (size);
+	return order;
+}
+
+#define devmem_is_allowed(pfn)	1
+
+#define __pa(vaddr)		virt_to_phys((void *) vaddr)
+#define __va(paddr)		phys_to_virt((unsigned long) paddr)
+
+#define pfn_to_kaddr(pfn)	__va((pfn) << PAGE_SHIFT)
+
+extern unsigned long max_low_pfn;
+extern unsigned long min_low_pfn;
+extern unsigned long max_pfn;
+
+#ifdef CONFIG_MMU
+#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)
+
+#else
+#define pfn_to_page(pfn)	(&mem_map[(pfn) - (PAGE_OFFSET >> PAGE_SHIFT)])
+#define page_to_pfn(page)	((PAGE_OFFSET >> PAGE_SHIFT) + (unsigned long) ((page) - mem_map))
+#define pfn_valid(pfn)		((pfn) >= min_low_pfn && (pfn) < max_low_pfn)
+
+#endif
+
+#define virt_to_page(kaddr)	pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
+#define virt_addr_valid(kaddr)	pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
+
+
+#ifdef CONFIG_MMU
+#define VM_DATA_DEFAULT_FLAGS \
+	(VM_READ | VM_WRITE | \
+	((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
+		 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+#endif
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __KERNEL__ */
+
+#ifdef CONFIG_CONTIGUOUS_PAGE_ALLOC
+#define WANT_PAGE_VIRTUAL	1
+#endif
+
+#endif /* _ASM_PAGE_H */
diff -Nru a/include/asm-frv/param.h b/include/asm-frv/param.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/param.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,23 @@
+#ifndef _ASM_PARAM_H
+#define _ASM_PARAM_H
+
+#ifdef __KERNEL__
+#define HZ		1000		/* Internal kernel timer frequency */
+#define USER_HZ		100		/* .. some user interfaces are in "ticks" */
+#define CLOCKS_PER_SEC	(USER_HZ)	/* like times() */
+#endif
+
+#ifndef HZ
+#define HZ 100
+#endif
+
+#define EXEC_PAGESIZE	16384
+
+#ifndef NOGROUP
+#define NOGROUP		(-1)
+#endif
+
+#define MAXHOSTNAMELEN		64	/* max length of hostname */
+#define COMMAND_LINE_SIZE	512
+
+#endif /* _ASM_PARAM_H */
diff -Nru a/include/asm-frv/pci.h b/include/asm-frv/pci.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/pci.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,108 @@
+/* pci.h: FR-V specific PCI declarations
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ * - Derived from include/asm-m68k/pci.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 ASM_PCI_H
+#define	ASM_PCI_H
+
+#include <linux/config.h>
+#include <linux/mm.h>
+#include <asm/scatterlist.h>
+#include <asm-generic/pci-dma-compat.h>
+#include <asm-generic/pci.h>
+
+struct pci_dev;
+
+#define pcibios_assign_all_busses()	0
+
+static inline void pcibios_add_platform_entries(struct pci_dev *dev)
+{
+}
+
+extern void pcibios_set_master(struct pci_dev *dev);
+
+extern void pcibios_penalize_isa_irq(int irq);
+
+#ifdef CONFIG_MMU
+extern void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle);
+extern void consistent_free(void *vaddr);
+extern void consistent_sync(void *vaddr, size_t size, int direction);
+extern void consistent_sync_page(struct page *page, unsigned long offset,
+				 size_t size, int direction);
+#endif
+
+extern void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
+				  dma_addr_t *dma_handle);
+
+extern void pci_free_consistent(struct pci_dev *hwdev, size_t size,
+				void *vaddr, dma_addr_t dma_handle);
+
+/* This is always fine. */
+#define pci_dac_dma_supported(pci_dev, mask)	(1)
+
+/* Return the index of the PCI controller for device PDEV. */
+#define pci_controller_num(PDEV)	(0)
+
+/* The PCI address space does equal the physical memory
+ * address space.  The networking and block device layers use
+ * this boolean for bounce buffer decisions.
+ */
+#define PCI_DMA_BUS_IS_PHYS	(1)
+
+/*
+ *	These are pretty much arbitary with the CoMEM implementation.
+ *	We have the whole address space to ourselves.
+ */
+#define PCIBIOS_MIN_IO		0x100
+#define PCIBIOS_MIN_MEM		0x00010000
+
+/* Make physical memory consistent for a single
+ * streaming mode DMA translation after a transfer.
+ *
+ * If you perform a pci_map_single() but wish to interrogate the
+ * buffer using the cpu, yet do not wish to teardown the PCI dma
+ * mapping, you must call this function before doing so.  At the
+ * next point you give the PCI dma address back to the card, the
+ * device again owns the buffer.
+ */
+static inline void pci_dma_sync_single(struct pci_dev *hwdev,
+				       dma_addr_t dma_handle,
+				       size_t size, int direction)
+{
+	if (direction == PCI_DMA_NONE)
+                BUG();
+
+	frv_cache_wback_inv((unsigned long)bus_to_virt(dma_handle),
+			    (unsigned long)bus_to_virt(dma_handle) + size);
+}
+
+/* Make physical memory consistent for a set of streaming
+ * mode DMA translations after a transfer.
+ *
+ * The same as pci_dma_sync_single but for a scatter-gather list,
+ * same rules and usage.
+ */
+static inline void pci_dma_sync_sg(struct pci_dev *hwdev,
+				   struct scatterlist *sg,
+				   int nelems, int direction)
+{
+	int i;
+
+	if (direction == PCI_DMA_NONE)
+                BUG();
+
+	for (i = 0; i < nelems; i++)
+		frv_cache_wback_inv(sg_dma_address(&sg[i]),
+				    sg_dma_address(&sg[i])+sg_dma_len(&sg[i]));
+}
+
+
+#endif
diff -Nru a/include/asm-frv/percpu.h b/include/asm-frv/percpu.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/percpu.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,6 @@
+#ifndef __ASM_PERCPU_H
+#define __ASM_PERCPU_H
+
+#include <asm-generic/percpu.h>
+
+#endif	/* __ASM_PERCPU_H */
diff -Nru a/include/asm-frv/pgalloc.h b/include/asm-frv/pgalloc.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/pgalloc.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,64 @@
+/* pgalloc.h: Page allocation routines for FRV
+ *
+ * Copyright (C) 2004 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.
+ *
+ * Derived from:
+ *	include/asm-m68knommu/pgalloc.h
+ *	include/asm-i386/pgalloc.h
+ */
+#ifndef _ASM_PGALLOC_H
+#define _ASM_PGALLOC_H
+
+#include <linux/config.h>
+#include <asm/setup.h>
+#include <asm/virtconvert.h>
+
+#ifdef CONFIG_MMU
+
+#define pmd_populate_kernel(mm, pmd, pte) __set_pmd(pmd, __pa(pte) | _PAGE_TABLE)
+#define pmd_populate(MM, PMD, PAGE)						\
+do {										\
+	__set_pmd((PMD), page_to_pfn(PAGE) << PAGE_SHIFT | _PAGE_TABLE);	\
+} while(0)
+
+/*
+ * Allocate and free page tables.
+ */
+
+extern pgd_t *pgd_alloc(struct mm_struct *);
+extern void pgd_free(pgd_t *);
+
+extern pte_t *pte_alloc_one_kernel(struct mm_struct *, unsigned long);
+
+extern struct page *pte_alloc_one(struct mm_struct *, unsigned long);
+
+static inline void pte_free_kernel(pte_t *pte)
+{
+	free_page((unsigned long)pte);
+}
+
+static inline void pte_free(struct page *pte)
+{
+	__free_page(pte);
+}
+
+#define __pte_free_tlb(tlb,pte)		tlb_remove_page((tlb),(pte))
+
+/*
+ * allocating and freeing a pmd is trivial: the 1-entry pmd is
+ * inside the pgd, so has no extra memory associated with it.
+ * (In the PAE case we free the pmds as part of the pgd.)
+ */
+#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)
+
+#endif /* CONFIG_MMU */
+
+#endif /* _ASM_PGALLOC_H */
diff -Nru a/include/asm-frv/pgtable.h b/include/asm-frv/pgtable.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/pgtable.h	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,554 @@
+/* pgtable.h: FR-V page table mangling
+ *
+ * Copyright (C) 2004 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.
+ *
+ * Derived from:
+ *	include/asm-m68knommu/pgtable.h
+ *	include/asm-i386/pgtable.h
+ */
+
+#ifndef _ASM_PGTABLE_H
+#define _ASM_PGTABLE_H
+
+#include <linux/config.h>
+#include <asm/mem-layout.h>
+#include <asm/setup.h>
+#include <asm/processor.h>
+
+#ifndef __ASSEMBLY__
+#include <linux/threads.h>
+#include <linux/slab.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#endif
+
+#ifndef __ASSEMBLY__
+#if defined(CONFIG_HIGHPTE)
+typedef unsigned long pte_addr_t;
+#else
+typedef pte_t *pte_addr_t;
+#endif
+#endif
+
+/*****************************************************************************/
+/*
+ * MMU-less operation case first
+ */
+#ifndef CONFIG_MMU
+
+#define pgd_present(pgd)	(1)		/* pages are always present on NO_MM */
+#define pgd_none(pgd)		(0)
+#define pgd_bad(pgd)		(0)
+#define pgd_clear(pgdp)
+#define kern_addr_valid(addr)	(1)
+#define	pmd_offset(a, b)	((void *) 0)
+
+#define PAGE_NONE		__pgprot(0)	/* these mean nothing to NO_MM */
+#define PAGE_SHARED		__pgprot(0)	/* these mean nothing to NO_MM */
+#define PAGE_COPY		__pgprot(0)	/* these mean nothing to NO_MM */
+#define PAGE_READONLY		__pgprot(0)	/* these mean nothing to NO_MM */
+#define PAGE_KERNEL		__pgprot(0)	/* these mean nothing to NO_MM */
+
+#define __swp_type(x)		(0)
+#define __swp_offset(x)		(0)
+#define __swp_entry(typ,off)	((swp_entry_t) { ((typ) | ((off) << 7)) })
+#define __pte_to_swp_entry(pte)	((swp_entry_t) { pte_val(pte) })
+#define __swp_entry_to_pte(x)	((pte_t) { (x).val })
+
+#ifndef __ASSEMBLY__
+static inline int pte_file(pte_t pte) { return 0; }
+#endif
+
+#define ZERO_PAGE(vaddr)	({ BUG(); NULL; })
+
+#define swapper_pg_dir		((pgd_t *) NULL)
+
+#define pgtable_cache_init()	do {} while(0)
+
+#else /* !CONFIG_MMU */
+/*****************************************************************************/
+/*
+ * then MMU operation
+ */
+
+/*
+ * ZERO_PAGE is a global shared page that is always zero: used
+ * for zero-mapped memory areas etc..
+ */
+#ifndef __ASSEMBLY__
+extern unsigned long empty_zero_page;
+#define ZERO_PAGE(vaddr)	virt_to_page(empty_zero_page)
+#endif
+
+/*
+ * we use 2-level page tables, folding the PMD (mid-level table) into the PGE (top-level entry)
+ * [see Documentation/fujitsu/frv/mmu-layout.txt]
+ *
+ * Page Directory:
+ *  - Size: 16KB
+ *  - 64 PGEs per PGD
+ *  - Each PGE holds 1 PUD and covers 64MB
+ *
+ * Page Upper Directory:
+ *  - Size: 256B
+ *  - 1 PUE per PUD
+ *  - Each PUE holds 1 PMD and covers 64MB
+ *
+ * Page Mid-Level Directory
+ *  - Size: 256B
+ *  - 1 PME per PMD
+ *  - Each PME holds 64 STEs, all of which point to separate chunks of the same Page Table
+ *  - All STEs are instantiated at the same time
+ *
+ * Page Table
+ *  - Size: 16KB
+ *  - 4096 PTEs per PT
+ *  - Each Linux PT is subdivided into 64 FR451 PT's, each of which holds 64 entries
+ *
+ * Pages
+ *  - Size: 4KB
+ *
+ * total PTEs
+ *	= 1 PML4E * 64 PGEs * 1 PUEs * 1 PMEs * 4096 PTEs
+ *	= 1 PML4E * 64 PGEs * 64 STEs * 64 PTEs/FR451-PT
+ *	= 262144 (or 256 * 1024)
+ */
+#define PGDIR_SHIFT		26
+#define PGDIR_SIZE		(1UL << PGDIR_SHIFT)
+#define PGDIR_MASK		(~(PGDIR_SIZE - 1))
+#define PTRS_PER_PGD		64
+
+#define PUD_SHIFT		26
+#define PTRS_PER_PUD		1
+#define PUD_SIZE		(1UL << PUD_SHIFT)
+#define PUD_MASK		(~(PUD_SIZE - 1))
+#define PUE_SIZE		256
+
+#define PMD_SHIFT		26
+#define PMD_SIZE		(1UL << PMD_SHIFT)
+#define PMD_MASK		(~(PMD_SIZE - 1))
+#define PTRS_PER_PMD		1
+#define PME_SIZE		256
+
+#define __frv_PT_SIZE		256
+
+#define PTRS_PER_PTE		4096
+
+#define USER_PGDS_IN_LAST_PML4	(TASK_SIZE / PGDIR_SIZE)
+#define FIRST_USER_PGD_NR	0
+
+#define USER_PGD_PTRS		(PAGE_OFFSET >> PGDIR_SHIFT)
+#define KERNEL_PGD_PTRS		(PTRS_PER_PGD - USER_PGD_PTRS)
+
+#define TWOLEVEL_PGDIR_SHIFT	26
+#define BOOT_USER_PGD_PTRS	(__PAGE_OFFSET >> TWOLEVEL_PGDIR_SHIFT)
+#define BOOT_KERNEL_PGD_PTRS	(PTRS_PER_PGD - BOOT_USER_PGD_PTRS)
+
+#ifndef __ASSEMBLY__
+
+extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
+
+#define pte_ERROR(e) \
+	printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, (e).pte)
+#define pmd_ERROR(e) \
+	printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e))
+#define pud_ERROR(e) \
+	printk("%s:%d: bad pud %08lx.\n", __FILE__, __LINE__, pmd_val(pud_val(e)))
+#define pgd_ERROR(e) \
+	printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pmd_val(pud_val(pgd_val(e))))
+
+/*
+ * Certain architectures need to do special things when PTEs
+ * within a page table are directly modified.  Thus, the following
+ * hook is made available.
+ */
+#define set_pte(pteptr, pteval)				\
+do {							\
+	*(pteptr) = (pteval);				\
+	asm volatile("dcf %M0" :: "U"(*pteptr));	\
+} while(0)
+
+#define set_pte_atomic(pteptr, pteval)		set_pte((pteptr), (pteval))
+
+/*
+ * pgd_offset() returns a (pgd_t *)
+ * pgd_index() is used get the offset into the pgd page's array of pgd_t's;
+ */
+#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address))
+
+/*
+ * a shortcut which implies the use of the kernel's pgd, instead
+ * of a process's
+ */
+#define pgd_offset_k(address) pgd_offset(&init_mm, address)
+
+/*
+ * The "pgd_xxx()" functions here are trivial for a folded two-level
+ * setup: the pud is never bad, and a pud always exists (as it's folded
+ * into the pgd entry)
+ */
+static inline int pgd_none(pgd_t pgd)		{ return 0; }
+static inline int pgd_bad(pgd_t pgd)		{ return 0; }
+static inline int pgd_present(pgd_t pgd)	{ return 1; }
+static inline void pgd_clear(pgd_t *pgd)	{ }
+
+#define pgd_populate(mm, pgd, pud)		do { } while (0)
+/*
+ * (puds are folded into pgds so this doesn't get actually called,
+ * but the define is needed for a generic inline function.)
+ */
+#define set_pgd(pgdptr, pgdval)				\
+do {							\
+	memcpy((pgdptr), &(pgdval), sizeof(pgd_t));	\
+	asm volatile("dcf %M0" :: "U"(*(pgdptr)));	\
+} while(0)
+
+static inline pud_t *pud_offset(pgd_t *pgd, unsigned long address)
+{
+	return (pud_t *) pgd;
+}
+
+#define pgd_page(pgd)				(pud_page((pud_t){ pgd }))
+#define pgd_page_kernel(pgd)			(pud_page_kernel((pud_t){ pgd }))
+
+/*
+ * allocating and freeing a pud is trivial: the 1-entry pud is
+ * inside the pgd, so has no extra memory associated with it.
+ */
+#define pud_alloc_one(mm, address)		NULL
+#define pud_free(x)				do { } while (0)
+#define __pud_free_tlb(tlb, x)			do { } while (0)
+
+/*
+ * The "pud_xxx()" functions here are trivial for a folded two-level
+ * setup: the pmd is never bad, and a pmd always exists (as it's folded
+ * into the pud entry)
+ */
+static inline int pud_none(pud_t pud)		{ return 0; }
+static inline int pud_bad(pud_t pud)		{ return 0; }
+static inline int pud_present(pud_t pud)	{ return 1; }
+static inline void pud_clear(pud_t *pud)	{ }
+
+#define pud_populate(mm, pmd, pte)		do { } while (0)
+
+/*
+ * (pmds are folded into puds so this doesn't get actually called,
+ * but the define is needed for a generic inline function.)
+ */
+#define set_pud(pudptr, pudval)			set_pmd((pmd_t *)(pudptr), (pmd_t) { pudval })
+
+#define pud_page(pud)				(pmd_page((pmd_t){ pud }))
+#define pud_page_kernel(pud)			(pmd_page_kernel((pmd_t){ pud }))
+
+/*
+ * (pmds are folded into pgds so this doesn't get actually called,
+ * but the define is needed for a generic inline function.)
+ */
+extern void __set_pmd(pmd_t *pmdptr, unsigned long __pmd);
+
+#define set_pmd(pmdptr, pmdval)			\
+do {						\
+	__set_pmd((pmdptr), (pmdval).ste[0]);	\
+} while(0)
+
+#define __pmd_index(address)			0
+
+static inline pmd_t *pmd_offset(pud_t *dir, unsigned long address)
+{
+	return (pmd_t *) dir + __pmd_index(address);
+}
+
+#define pte_same(a, b)		((a).pte == (b).pte)
+#define pte_page(x)		(mem_map + ((unsigned long)(((x).pte >> PAGE_SHIFT))))
+#define pte_none(x)		(!(x).pte)
+#define pte_pfn(x)		((unsigned long)(((x).pte >> PAGE_SHIFT)))
+#define pfn_pte(pfn, prot)	__pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
+#define pfn_pmd(pfn, prot)	__pmd(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
+
+#define VMALLOC_VMADDR(x)	((unsigned long) (x))
+
+#endif /* !__ASSEMBLY__ */
+
+/*
+ * control flags in AMPR registers and TLB entries
+ */
+#define _PAGE_BIT_PRESENT	xAMPRx_V_BIT
+#define _PAGE_BIT_WP		DAMPRx_WP_BIT
+#define _PAGE_BIT_NOCACHE	xAMPRx_C_BIT
+#define _PAGE_BIT_SUPER		xAMPRx_S_BIT
+#define _PAGE_BIT_ACCESSED	xAMPRx_RESERVED8_BIT
+#define _PAGE_BIT_DIRTY		xAMPRx_M_BIT
+#define _PAGE_BIT_NOTGLOBAL	xAMPRx_NG_BIT
+
+#define _PAGE_PRESENT		xAMPRx_V
+#define _PAGE_WP		DAMPRx_WP
+#define _PAGE_NOCACHE		xAMPRx_C
+#define _PAGE_SUPER		xAMPRx_S
+#define _PAGE_ACCESSED		xAMPRx_RESERVED8	/* accessed if set */
+#define _PAGE_DIRTY		xAMPRx_M
+#define _PAGE_NOTGLOBAL		xAMPRx_NG
+
+#define _PAGE_RESERVED_MASK	(xAMPRx_RESERVED8 | xAMPRx_RESERVED13)
+
+#define _PAGE_FILE		0x002	/* set:pagecache unset:swap */
+#define _PAGE_PROTNONE		0x000	/* If not present */
+
+#define _PAGE_CHG_MASK		(PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
+
+#define __PGPROT_BASE \
+	(_PAGE_PRESENT | xAMPRx_SS_16Kb | xAMPRx_D | _PAGE_NOTGLOBAL | _PAGE_ACCESSED)
+
+#define PAGE_NONE	__pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED)
+#define PAGE_SHARED	__pgprot(__PGPROT_BASE)
+#define PAGE_COPY	__pgprot(__PGPROT_BASE | _PAGE_WP)
+#define PAGE_READONLY	__pgprot(__PGPROT_BASE | _PAGE_WP)
+
+#define __PAGE_KERNEL		(__PGPROT_BASE | _PAGE_SUPER | _PAGE_DIRTY)
+#define __PAGE_KERNEL_NOCACHE	(__PGPROT_BASE | _PAGE_SUPER | _PAGE_DIRTY | _PAGE_NOCACHE)
+#define __PAGE_KERNEL_RO	(__PGPROT_BASE | _PAGE_SUPER | _PAGE_DIRTY | _PAGE_WP)
+
+#define MAKE_GLOBAL(x) __pgprot((x) & ~_PAGE_NOTGLOBAL)
+
+#define PAGE_KERNEL		MAKE_GLOBAL(__PAGE_KERNEL)
+#define PAGE_KERNEL_RO		MAKE_GLOBAL(__PAGE_KERNEL_RO)
+#define PAGE_KERNEL_NOCACHE	MAKE_GLOBAL(__PAGE_KERNEL_NOCACHE)
+
+#define _PAGE_TABLE		(_PAGE_PRESENT | xAMPRx_SS_16Kb)
+
+#ifndef __ASSEMBLY__
+
+/*
+ * The FR451 can do execute protection by virtue of having separate TLB miss handlers for
+ * instruction access and for data access. However, we don't have enough reserved bits to say
+ * "execute only", so we don't bother. If you can read it, you can execute it and vice versa.
+ */
+#define __P000	PAGE_NONE
+#define __P001	PAGE_READONLY
+#define __P010	PAGE_COPY
+#define __P011	PAGE_COPY
+#define __P100	PAGE_READONLY
+#define __P101	PAGE_READONLY
+#define __P110	PAGE_COPY
+#define __P111	PAGE_COPY
+
+#define __S000	PAGE_NONE
+#define __S001	PAGE_READONLY
+#define __S010	PAGE_SHARED
+#define __S011	PAGE_SHARED
+#define __S100	PAGE_READONLY
+#define __S101	PAGE_READONLY
+#define __S110	PAGE_SHARED
+#define __S111	PAGE_SHARED
+
+/*
+ * Define this to warn about kernel memory accesses that are
+ * done without a 'verify_area(VERIFY_WRITE,..)'
+ */
+#undef TEST_VERIFY_AREA
+
+#define pte_present(x)	(pte_val(x) & _PAGE_PRESENT)
+#define pte_clear(xp)	do { set_pte(xp, __pte(0)); } while (0)
+
+#define pmd_none(x)	(!pmd_val(x))
+#define pmd_present(x)	(pmd_val(x) & _PAGE_PRESENT)
+#define	pmd_bad(x)	(pmd_val(x) & xAMPRx_SS)
+#define pmd_clear(xp)	do { __set_pmd(xp, 0); } while(0)
+
+#define pmd_page_kernel(pmd) \
+	((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
+
+#ifndef CONFIG_DISCONTIGMEM
+#define pmd_page(pmd)	(pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT))
+#endif
+
+#define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT))
+
+/*
+ * The following only work if pte_present() is true.
+ * Undefined behaviour if not..
+ */
+static inline int pte_read(pte_t pte)		{ return !((pte).pte & _PAGE_SUPER); }
+static inline int pte_exec(pte_t pte)		{ return !((pte).pte & _PAGE_SUPER); }
+static inline int pte_dirty(pte_t pte)		{ return (pte).pte & _PAGE_DIRTY; }
+static inline int pte_young(pte_t pte)		{ return (pte).pte & _PAGE_ACCESSED; }
+static inline int pte_write(pte_t pte)		{ return !((pte).pte & _PAGE_WP); }
+
+static inline pte_t pte_rdprotect(pte_t pte)	{ (pte).pte |= _PAGE_SUPER; return pte; }
+static inline pte_t pte_exprotect(pte_t pte)	{ (pte).pte |= _PAGE_SUPER; return pte; }
+static inline pte_t pte_mkclean(pte_t pte)	{ (pte).pte &= ~_PAGE_DIRTY; return pte; }
+static inline pte_t pte_mkold(pte_t pte)	{ (pte).pte &= ~_PAGE_ACCESSED; return pte; }
+static inline pte_t pte_wrprotect(pte_t pte)	{ (pte).pte |= _PAGE_WP; return pte; }
+static inline pte_t pte_mkread(pte_t pte)	{ (pte).pte &= ~_PAGE_SUPER; return pte; }
+static inline pte_t pte_mkexec(pte_t pte)	{ (pte).pte &= ~_PAGE_SUPER; return pte; }
+static inline pte_t pte_mkdirty(pte_t pte)	{ (pte).pte |= _PAGE_DIRTY; return pte; }
+static inline pte_t pte_mkyoung(pte_t pte)	{ (pte).pte |= _PAGE_ACCESSED; return pte; }
+static inline pte_t pte_mkwrite(pte_t pte)	{ (pte).pte &= ~_PAGE_WP; return pte; }
+
+static inline int ptep_test_and_clear_dirty(pte_t *ptep)
+{
+	int i = test_and_clear_bit(_PAGE_BIT_DIRTY, ptep);
+	asm volatile("dcf %M0" :: "U"(*ptep));
+	return i;
+}
+
+static inline int ptep_test_and_clear_young(pte_t *ptep)
+{
+	int i = test_and_clear_bit(_PAGE_BIT_ACCESSED, ptep);
+	asm volatile("dcf %M0" :: "U"(*ptep));
+	return i;
+}
+
+static inline pte_t ptep_get_and_clear(pte_t *ptep)
+{
+	unsigned long x = xchg(&ptep->pte, 0);
+	asm volatile("dcf %M0" :: "U"(*ptep));
+	return __pte(x);
+}
+
+static inline void ptep_set_wrprotect(pte_t *ptep)
+{
+	set_bit(_PAGE_BIT_WP, ptep);
+	asm volatile("dcf %M0" :: "U"(*ptep));
+}
+
+static inline void ptep_mkdirty(pte_t *ptep)
+{
+	set_bit(_PAGE_BIT_DIRTY, ptep);
+	asm volatile("dcf %M0" :: "U"(*ptep));
+}
+
+/*
+ * 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 mk_pte(page, pgprot)	pfn_pte(page_to_pfn(page), (pgprot))
+#define mk_pte_huge(entry)	((entry).pte_low |= _PAGE_PRESENT | _PAGE_PSE)
+
+/* This takes a physical page address that is used by the remapping functions */
+#define mk_pte_phys(physpage, pgprot)	pfn_pte((physpage) >> PAGE_SHIFT, pgprot)
+
+static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
+{
+	pte.pte &= _PAGE_CHG_MASK;
+	pte.pte |= pgprot_val(newprot);
+	return pte;
+}
+
+#define page_pte(page)	page_pte_prot((page), __pgprot(0))
+
+/* to find an entry in a page-table-directory. */
+#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1))
+#define pgd_index_k(addr) pgd_index(addr)
+
+/* Find an entry in the bottom-level page table.. */
+#define __pte_index(address) (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
+
+/*
+ * the pte page can be thought of an array like this: pte_t[PTRS_PER_PTE]
+ *
+ * this macro returns the index of the entry in the pte page which would
+ * control the given virtual address
+ */
+#define pte_index(address) \
+		(((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
+#define pte_offset_kernel(dir, address) \
+	((pte_t *) pmd_page_kernel(*(dir)) +  pte_index(address))
+
+#if defined(CONFIG_HIGHPTE)
+#define pte_offset_map(dir, address) \
+	((pte_t *)kmap_atomic(pmd_page(*(dir)),KM_PTE0) + pte_index(address))
+#define pte_offset_map_nested(dir, address) \
+	((pte_t *)kmap_atomic(pmd_page(*(dir)),KM_PTE1) + pte_index(address))
+#define pte_unmap(pte) kunmap_atomic(pte, KM_PTE0)
+#define pte_unmap_nested(pte) kunmap_atomic((pte), KM_PTE1)
+#else
+#define pte_offset_map(dir, address) \
+	((pte_t *)page_address(pmd_page(*(dir))) + pte_index(address))
+#define pte_offset_map_nested(dir, address) pte_offset_map((dir), (address))
+#define pte_unmap(pte) do { } while (0)
+#define pte_unmap_nested(pte) do { } while (0)
+#endif
+
+/*
+ * Handle swap and file entries
+ * - the PTE is encoded in the following format:
+ *	bit 0:		Must be 0 (!_PAGE_PRESENT)
+ *	bit 1:		Type: 0 for swap, 1 for file (_PAGE_FILE)
+ *	bits 2-7:	Swap type
+ *	bits 8-31:	Swap offset
+ *	bits 2-31:	File pgoff
+ */
+#define __swp_type(x)			(((x).val >> 2) & 0x1f)
+#define __swp_offset(x)			((x).val >> 8)
+#define __swp_entry(type, offset)	((swp_entry_t) { ((type) << 2) | ((offset) << 8) })
+#define __pte_to_swp_entry(pte)		((swp_entry_t) { (pte).pte })
+#define __swp_entry_to_pte(x)		((pte_t) { (x).val })
+
+static inline int pte_file(pte_t pte)
+{
+	return pte.pte & _PAGE_FILE;
+}
+
+#define PTE_FILE_MAX_BITS	29
+
+#define pte_to_pgoff(PTE)	((PTE).pte >> 2)
+#define pgoff_to_pte(off)	__pte((off) << 2 | _PAGE_FILE)
+
+/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
+#define PageSkip(page)		(0)
+#define kern_addr_valid(addr)	(1)
+
+#define io_remap_page_range(vma, vaddr, paddr, size, prot)		\
+		remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot)
+
+#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>
+
+/*
+ * preload information about a newly instantiated PTE into the SCR0/SCR1 PGE cache
+ */
+static inline void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t pte)
+{
+	unsigned long ampr;
+	pgd_t *pge = pgd_offset(current->mm, address);
+	pud_t *pue = pud_offset(pge, address);
+	pmd_t *pme = pmd_offset(pue, address);
+
+	ampr = pme->ste[0] & 0xffffff00;
+	ampr |= xAMPRx_L | xAMPRx_SS_16Kb | xAMPRx_S | xAMPRx_C | xAMPRx_V;
+
+	asm volatile("movgs %0,scr0\n"
+		     "movgs %0,scr1\n"
+		     "movgs %1,dampr4\n"
+		     "movgs %1,dampr5\n"
+		     :
+		     : "r"(address), "r"(ampr)
+		     );
+}
+
+#ifdef CONFIG_PROC_FS
+extern char *proc_pid_status_frv_cxnr(struct mm_struct *mm, char *buffer);
+#endif
+
+extern void __init pgtable_cache_init(void);
+
+#endif /* !__ASSEMBLY__ */
+#endif /* !CONFIG_MMU */
+
+#ifndef __ASSEMBLY__
+extern void __init paging_init(void);
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _ASM_PGTABLE_H */
diff -Nru a/include/asm-frv/poll.h b/include/asm-frv/poll.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/poll.h	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,23 @@
+#ifndef _ASM_POLL_H
+#define _ASM_POLL_H
+
+#define POLLIN		  1
+#define POLLPRI		  2
+#define POLLOUT		  4
+#define POLLERR		  8
+#define POLLHUP		 16
+#define POLLNVAL	 32
+#define POLLRDNORM	 64
+#define POLLWRNORM	POLLOUT
+#define POLLRDBAND	128
+#define POLLWRBAND	256
+#define POLLMSG		0x0400
+
+struct pollfd {
+	int fd;
+	short events;
+	short revents;
+};
+
+#endif
+
diff -Nru a/include/asm-frv/posix_types.h b/include/asm-frv/posix_types.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/posix_types.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,66 @@
+#ifndef _ASM_POSIX_TYPES_H
+#define _ASM_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 short	__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 short	__kernel_uid_t;
+typedef unsigned short	__kernel_gid_t;
+typedef unsigned int	__kernel_size_t;
+typedef int		__kernel_ssize_t;
+typedef int		__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 {
+#if defined(__KERNEL__) || defined(__USE_ALL)
+	int	val[2];
+#else /* !defined(__KERNEL__) && !defined(__USE_ALL) */
+	int	__val[2];
+#endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */
+} __kernel_fsid_t;
+
+#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
+
+#undef	__FD_SET
+#define	__FD_SET(d, set)	((set)->fds_bits[__FDELT(d)] |= __FDMASK(d))
+
+#undef	__FD_CLR
+#define	__FD_CLR(d, set)	((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d))
+
+#undef	__FD_ISSET
+#define	__FD_ISSET(d, set)	(!!((set)->fds_bits[__FDELT(d)] & __FDMASK(d)))
+
+#undef	__FD_ZERO
+#define __FD_ZERO(fdsetp) (memset (fdsetp, 0, sizeof(*(fd_set *)fdsetp)))
+
+#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */
+
+#endif
+
diff -Nru a/include/asm-frv/processor.h b/include/asm-frv/processor.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/processor.h	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,153 @@
+/* processor.h: FRV processor definitions
+ *
+ * Copyright (C) 2003 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.
+ */
+
+#ifndef _ASM_PROCESSOR_H
+#define _ASM_PROCESSOR_H
+
+#include <linux/config.h>
+#include <asm/mem-layout.h>
+
+#ifndef __ASSEMBLY__
+/*
+ * Default implementation of macro that returns current
+ * instruction pointer ("program counter").
+ */
+#define current_text_addr() ({ __label__ _l; _l: &&_l;})
+
+#include <linux/linkage.h>
+#include <asm/sections.h>
+#include <asm/segment.h>
+#include <asm/fpu.h>
+#include <asm/registers.h>
+#include <asm/ptrace.h>
+#include <asm/current.h>
+#include <asm/cache.h>
+
+/* Forward declaration, a strange C thing */
+struct task_struct;
+
+/*
+ *  CPU type and hardware bug flags. Kept separately for each CPU.
+ */
+struct cpuinfo_frv {
+#ifdef CONFIG_MMU
+	unsigned long	*pgd_quick;
+	unsigned long	*pte_quick;
+	unsigned long	pgtable_cache_sz;
+#endif
+} __cacheline_aligned;
+
+extern struct cpuinfo_frv __nongprelbss boot_cpu_data;
+
+#define cpu_data		(&boot_cpu_data)
+#define current_cpu_data	boot_cpu_data
+
+/*
+ * Bus types
+ */
+#define EISA_bus 0
+#define MCA_bus 0
+
+struct thread_struct {
+	struct pt_regs		*frame;		/* [GR28] exception frame ptr for this thread */
+	struct task_struct	*curr;		/* [GR29] current pointer for this thread */
+	unsigned long		sp;		/* [GR1 ] kernel stack pointer */
+	unsigned long		fp;		/* [GR2 ] kernel frame pointer */
+	unsigned long		lr;		/* link register */
+	unsigned long		pc;		/* program counter */
+	unsigned long		gr[12];		/* [GR16-GR27] */
+	unsigned long		sched_lr;	/* LR from schedule() */
+
+	union {
+		struct pt_regs		*frame0;	/* top (user) stack frame */
+		struct user_context	*user;		/* userspace context */
+	};
+} __attribute__((aligned(8)));
+
+extern struct pt_regs *__kernel_frame0_ptr;
+extern struct task_struct *__kernel_current_task;
+
+#endif
+
+#ifndef __ASSEMBLY__
+#define INIT_THREAD_FRAME0 \
+	((struct pt_regs *) \
+	(sizeof(init_stack) + (unsigned long) init_stack - sizeof(struct user_context)))
+
+#define INIT_THREAD {				\
+	NULL,					\
+	(struct task_struct *) init_stack,	\
+	0, 0, 0, 0,				\
+	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },	\
+	0,					\
+	{ INIT_THREAD_FRAME0 },			\
+}
+
+/*
+ * do necessary setup to start up a newly executed thread.
+ * - need to discard the frame stacked by init() invoking the execve syscall
+ */
+#define start_thread(_regs, _pc, _usp)			\
+do {							\
+	set_fs(USER_DS); /* reads from user space */	\
+	__frame = __kernel_frame0_ptr;			\
+	__frame->pc	= (_pc);			\
+	__frame->psr	&= ~PSR_S;			\
+	__frame->sp	= (_usp);			\
+} while(0)
+
+extern void prepare_to_copy(struct task_struct *tsk);
+
+/* Free all resources held by a thread. */
+static inline void release_thread(struct task_struct *dead_task)
+{
+}
+
+extern asmlinkage int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
+extern asmlinkage void save_user_regs(struct user_context *target);
+extern asmlinkage void *restore_user_regs(const struct user_context *target, ...);
+
+#define copy_segments(tsk, mm)		do { } while (0)
+#define release_segments(mm)		do { } while (0)
+#define forget_segments()		do { } while (0)
+
+/*
+ * Free current thread data structures etc..
+ */
+static inline void exit_thread(void)
+{
+}
+
+/*
+ * Return saved PC of a blocked thread.
+ */
+extern unsigned long thread_saved_pc(struct task_struct *tsk);
+
+unsigned long get_wchan(struct task_struct *p);
+
+#define	KSTK_EIP(tsk)	((tsk)->thread.frame0->pc)
+#define	KSTK_ESP(tsk)	((tsk)->thread.frame0->sp)
+
+/* Allocation and freeing of basic task resources. */
+extern struct task_struct *alloc_task_struct(void);
+extern void free_task_struct(struct task_struct *p);
+
+#define cpu_relax()    do { } while (0)
+
+/* data cache prefetch */
+#define ARCH_HAS_PREFETCH
+static inline void prefetch(const void *x)
+{
+	asm volatile("dcpl %0,gr0,#0" : : "r"(x));
+}
+
+#endif /* __ASSEMBLY__ */
+#endif /* _ASM_PROCESSOR_H */
diff -Nru a/include/asm-frv/ptrace.h b/include/asm-frv/ptrace.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/ptrace.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,86 @@
+/* ptrace.h: ptrace() relevant definitions
+ *
+ * Copyright (C) 2003 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.
+ */
+#ifndef _ASM_PTRACE_H
+#define _ASM_PTRACE_H
+
+#include <asm/registers.h>
+
+#define in_syscall(regs) (((regs)->tbr & TBR_TT) == TBR_TT_TRAP0)
+
+
+#define PT_PSR		0
+#define	PT_ISR		1
+#define PT_CCR		2
+#define PT_CCCR		3
+#define PT_LR		4
+#define PT_LCR		5
+#define PT_PC		6
+
+#define PT__STATUS	7	/* exception status */
+#define PT_SYSCALLNO	8	/* syscall number or -1 */
+#define PT_ORIG_GR8	9	/* saved GR8 for signal handling */
+#define PT_GNER0	10
+#define PT_GNER1	11
+#define PT_IACC0H	12
+#define PT_IACC0L	13
+
+#define PT_GR(j)	( 14 + (j))	/* GRj for 0<=j<=63 */
+#define PT_FR(j)	( 78 + (j))	/* FRj for 0<=j<=63 */
+#define PT_FNER(j)	(142 + (j))	/* FNERj for 0<=j<=1 */
+#define PT_MSR(j)	(144 + (j))	/* MSRj for 0<=j<=2 */
+#define PT_ACC(j)	(146 + (j))	/* ACCj for 0<=j<=7 */
+#define PT_ACCG(jklm)	(154 + (jklm))	/* ACCGjklm for 0<=jklm<=1 (reads four regs per slot) */
+#define PT_FSR(j)	(156 + (j))	/* FSRj for 0<=j<=0 */
+#define PT__GPEND	78
+#define PT__END		157
+
+#define PT_TBR		PT_GR(0)
+#define PT_SP		PT_GR(1)
+#define PT_FP		PT_GR(2)
+#define PT_PREV_FRAME	PT_GR(28)	/* previous exception frame pointer (old gr28 value) */
+#define PT_CURR_TASK	PT_GR(29)	/* current task */
+
+
+/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
+#define PTRACE_GETREGS		12
+#define PTRACE_SETREGS		13
+#define PTRACE_GETFPREGS	14
+#define PTRACE_SETFPREGS	15
+#define PTRACE_GETFDPIC		31	/* get the ELF fdpic loadmap address */
+
+#define PTRACE_GETFDPIC_EXEC	0	/* [addr] request the executable loadmap */
+#define PTRACE_GETFDPIC_INTERP	1	/* [addr] request the interpreter loadmap */
+
+#ifndef __ASSEMBLY__
+
+/*
+ * dedicate GR28; to keeping the a pointer to the current exception frame
+ */
+register struct pt_regs *__frame asm("gr28");
+register struct pt_regs *__debug_frame asm("gr31");
+
+#ifndef container_of
+#define container_of(ptr, type, member) ({			\
+        const typeof( ((type *)0)->member ) *__mptr = (ptr);	\
+        (type *)( (char *)__mptr - offsetof(type,member) );})
+#endif
+
+#define __debug_regs container_of(__debug_frame, struct pt_debug_regs, normal_regs)
+
+#define user_mode(regs)			(!((regs)->psr & PSR_S))
+#define instruction_pointer(regs)	((regs)->pc)
+
+extern unsigned long user_stack(const struct pt_regs *);
+extern void show_regs(struct pt_regs *);
+#define profile_pc(regs) ((regs)->pc)
+
+#endif /* !__ASSEMBLY__ */
+#endif /* _ASM_PTRACE_H */
diff -Nru a/include/asm-frv/registers.h b/include/asm-frv/registers.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/registers.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,255 @@
+/* registers.h: register frame declarations
+ *
+ * Copyright (C) 2003 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.
+ */
+
+/*
+ * notes:
+ *
+ * (1) that the members of all these structures are carefully aligned to permit
+ *     usage of STD/STDF instructions
+ *
+ * (2) if you change these structures, you must change the code in
+ *     arch/frvnommu/kernel/{break.S,entry.S,switch_to.S,gdb-stub.c}
+ *
+ *
+ * the kernel stack space block looks like this:
+ *
+ *	+0x2000	+----------------------
+ *		| union {
+ *		|	struct user_context
+ *		|	struct pt_regs [user exception]
+ *		| }
+ *		+---------------------- <-- __kernel_frame0_ptr (maybe GR28)
+ *		|
+ *		| kernel stack
+ *		|
+ *		|......................
+ *		| struct pt_regs [kernel exception]
+ *		|...................... <-- __kernel_frame0_ptr (maybe GR28)
+ *		|
+ *		| kernel stack
+ *		|
+ *		|...................... <-- stack pointer (GR1)
+ *		|
+ *		| unused stack space
+ *		|
+ *		+----------------------
+ *		| struct thread_info
+ *	+0x0000	+---------------------- <-- __current_thread_info (GR15);
+ *
+ * note that GR28 points to the current exception frame
+ */
+
+#ifndef _ASM_REGISTERS_H
+#define _ASM_REGISTERS_H
+
+#ifndef __ASSEMBLY__
+#define __OFFSET(X)	(X)
+#define __OFFSETC(X,N)	xxxxxxxxxxxxxxxxxxxxxxxx
+#else
+#define __OFFSET(X)	((X)*4)
+#define __OFFSETC(X,N)	((X)*4+(N))
+#endif
+
+/*****************************************************************************/
+/*
+ * Exception/Interrupt frame
+ * - held on kernel stack
+ * - 8-byte aligned on stack (old SP is saved in frame)
+ * - GR0 is fixed 0, so we don't save it
+ */
+#ifndef __ASSEMBLY__
+
+struct pt_regs {
+	unsigned long		psr;		/* Processor Status Register */
+	unsigned long		isr;		/* Integer Status Register */
+	unsigned long		ccr;		/* Condition Code Register */
+	unsigned long		cccr;		/* Condition Code for Conditional Insns Register */
+	unsigned long		lr;		/* Link Register */
+	unsigned long		lcr;		/* Loop Count Register */
+	unsigned long		pc;		/* Program Counter Register */
+	unsigned long		__status;	/* exception status */
+	unsigned long		syscallno;	/* syscall number or -1 */
+	unsigned long		orig_gr8;	/* original syscall arg #1 */
+	unsigned long		gner0;
+	unsigned long		gner1;
+	unsigned long long	iacc0;
+	unsigned long		tbr;		/* GR0 is fixed zero, so we use this for TBR */
+	unsigned long		sp;		/* GR1: USP/KSP */
+	unsigned long		fp;		/* GR2: FP */
+	unsigned long		gr3;
+	unsigned long		gr4;
+	unsigned long		gr5;
+	unsigned long		gr6;
+	unsigned long		gr7;		/* syscall number */
+	unsigned long		gr8;		/* 1st syscall param; syscall return */
+	unsigned long		gr9;		/* 2nd syscall param */
+	unsigned long		gr10;		/* 3rd syscall param */
+	unsigned long		gr11;		/* 4th syscall param */
+	unsigned long		gr12;		/* 5th syscall param */
+	unsigned long		gr13;		/* 6th syscall param */
+	unsigned long		gr14;
+	unsigned long		gr15;
+	unsigned long		gr16;		/* GP pointer */
+	unsigned long		gr17;		/* small data */
+	unsigned long		gr18;		/* PIC/PID */
+	unsigned long		gr19;
+	unsigned long		gr20;
+	unsigned long		gr21;
+	unsigned long		gr22;
+	unsigned long		gr23;
+	unsigned long		gr24;
+	unsigned long		gr25;
+	unsigned long		gr26;
+	unsigned long		gr27;
+	struct pt_regs		*next_frame;	/* GR28 - next exception frame */
+	unsigned long		gr29;		/* GR29 - OS reserved */
+	unsigned long		gr30;		/* GR30 - OS reserved */
+	unsigned long		gr31;		/* GR31 - OS reserved */
+} __attribute__((aligned(8)));
+
+#endif
+
+#define REG_PSR		__OFFSET( 0)	/* Processor Status Register */
+#define REG_ISR		__OFFSET( 1)	/* Integer Status Register */
+#define REG_CCR		__OFFSET( 2)	/* Condition Code Register */
+#define REG_CCCR	__OFFSET( 3)	/* Condition Code for Conditional Insns Register */
+#define REG_LR		__OFFSET( 4)	/* Link Register */
+#define REG_LCR		__OFFSET( 5)	/* Loop Count Register */
+#define REG_PC		__OFFSET( 6)	/* Program Counter */
+
+#define REG__STATUS	__OFFSET( 7)	/* exception status */
+#define REG__STATUS_STEP	0x00000001	/* - reenable single stepping on return */
+#define REG__STATUS_STEPPED	0x00000002	/* - single step caused exception */
+#define REG__STATUS_BROKE	0x00000004	/* - BREAK insn caused exception */
+#define REG__STATUS_SYSC_ENTRY	0x40000000	/* - T on syscall entry (ptrace.c only) */
+#define REG__STATUS_SYSC_EXIT	0x80000000	/* - T on syscall exit (ptrace.c only) */
+
+#define REG_SYSCALLNO	__OFFSET( 8)	/* syscall number or -1 */
+#define REG_ORIG_GR8	__OFFSET( 9)	/* saved GR8 for signal handling */
+#define REG_GNER0	__OFFSET(10)
+#define REG_GNER1	__OFFSET(11)
+#define REG_IACC0	__OFFSET(12)
+
+#define REG_TBR		__OFFSET(14)	/* Trap Vector Register */
+#define REG_GR(R)	__OFFSET((14+(R)))
+#define REG__END	REG_GR(32)
+
+#define REG_SP		REG_GR(1)
+#define REG_FP		REG_GR(2)
+#define REG_PREV_FRAME	REG_GR(28)	/* previous exception frame pointer (old gr28 value) */
+#define REG_CURR_TASK	REG_GR(29)	/* current task */
+
+/*****************************************************************************/
+/*
+ * extension tacked in front of the exception frame in debug mode
+ */
+#ifndef __ASSEMBLY__
+
+struct pt_debug_regs
+{
+	unsigned long		bpsr;
+	unsigned long		dcr;
+	unsigned long		brr;
+	unsigned long		nmar;
+	struct pt_regs		normal_regs;
+} __attribute__((aligned(8)));
+
+#endif
+
+#define REG_NMAR		__OFFSET(-1)
+#define REG_BRR			__OFFSET(-2)
+#define REG_DCR			__OFFSET(-3)
+#define REG_BPSR		__OFFSET(-4)
+#define REG__DEBUG_XTRA		__OFFSET(4)
+
+/*****************************************************************************/
+/*
+ * userspace registers
+ */
+#ifndef __ASSEMBLY__
+
+struct user_int_regs
+{
+	/* integer registers
+	 * - up to gr[31] mirror pt_regs
+	 * - total size must be multiple of 8 bytes
+	 */
+	unsigned long		psr;		/* Processor Status Register */
+	unsigned long		isr;		/* Integer Status Register */
+	unsigned long		ccr;		/* Condition Code Register */
+	unsigned long		cccr;		/* Condition Code for Conditional Insns Register */
+	unsigned long		lr;		/* Link Register */
+	unsigned long		lcr;		/* Loop Count Register */
+	unsigned long		pc;		/* Program Counter Register */
+	unsigned long		__status;	/* exception status */
+	unsigned long		syscallno;	/* syscall number or -1 */
+	unsigned long		orig_gr8;	/* original syscall arg #1 */
+	unsigned long		gner[2];
+	unsigned long long	iacc[1];
+
+	union {
+		unsigned long	tbr;
+		unsigned long	gr[64];
+	};
+};
+
+struct user_fpmedia_regs
+{
+	/* FP/Media registers */
+	unsigned long	fr[64];
+	unsigned long	fner[2];
+	unsigned long	msr[2];
+	unsigned long	acc[8];
+	unsigned char	accg[8];
+	unsigned long	fsr[1];
+};
+
+struct user_context
+{
+	struct user_int_regs		i;
+	struct user_fpmedia_regs	f;
+
+	/* we provide a context extension so that we can save the regs for CPUs that
+	 * implement many more of Fujitsu's lavish register spec
+	 */
+	void *extension;
+} __attribute__((aligned(8)));
+
+#endif
+
+#define NR_USER_INT_REGS	(14 + 64)
+#define NR_USER_FPMEDIA_REGS	(64 + 2 + 2 + 8 + 8/4 + 1)
+#define NR_USER_CONTEXT		(NR_USER_INT_REGS + NR_USER_FPMEDIA_REGS + 1)
+
+#define USER_CONTEXT_SIZE	(((NR_USER_CONTEXT + 1) & ~1) * 4)
+
+#define __THREAD_FRAME		__OFFSET(0)
+#define __THREAD_CURR		__OFFSET(1)
+#define __THREAD_SP		__OFFSET(2)
+#define __THREAD_FP		__OFFSET(3)
+#define __THREAD_LR		__OFFSET(4)
+#define __THREAD_PC		__OFFSET(5)
+#define __THREAD_GR(R)		__OFFSET(6 + (R) - 16)
+#define __THREAD_FRAME0		__OFFSET(19)
+#define __THREAD_USER		__OFFSET(19)
+
+#define __USER_INT		__OFFSET(0)
+#define __INT_GR(R)		__OFFSET(14 + (R))
+
+#define __USER_FPMEDIA		__OFFSET(NR_USER_INT_REGS)
+#define __FPMEDIA_FR(R)		__OFFSET(NR_USER_INT_REGS + (R))
+#define __FPMEDIA_FNER(R)	__OFFSET(NR_USER_INT_REGS + 64 + (R))
+#define __FPMEDIA_MSR(R)	__OFFSET(NR_USER_INT_REGS + 66 + (R))
+#define __FPMEDIA_ACC(R)	__OFFSET(NR_USER_INT_REGS + 68 + (R))
+#define __FPMEDIA_ACCG(R)	__OFFSETC(NR_USER_INT_REGS + 76, (R))
+#define __FPMEDIA_FSR(R)	__OFFSET(NR_USER_INT_REGS + 78 + (R))
+
+#endif /* _ASM_REGISTERS_H */
diff -Nru a/include/asm-frv/resource.h b/include/asm-frv/resource.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/resource.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,7 @@
+#ifndef _ASM_RESOURCE_H
+#define _ASM_RESOURCE_H
+
+#include <asm-generic/resource.h>
+
+#endif /* _ASM_RESOURCE_H */
+
diff -Nru a/include/asm-frv/scatterlist.h b/include/asm-frv/scatterlist.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/scatterlist.h	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,32 @@
+#ifndef _ASM_SCATTERLIST_H
+#define _ASM_SCATTERLIST_H
+
+/*
+ * Drivers must set either ->address or (preferred) ->page and ->offset
+ * to indicate where data must be transferred to/from.
+ *
+ * Using ->page is recommended since it handles highmem data as well as
+ * low mem. ->address is restricted to data which has a virtual mapping, and
+ * it will go away in the future. Updating to ->page can be automated very
+ * easily -- something like
+ *
+ * sg->address = some_ptr;
+ *
+ * can be rewritten as
+ *
+ * sg->page = virt_to_page(some_ptr);
+ * sg->offset = (unsigned long) some_ptr & ~PAGE_MASK;
+ *
+ * and that's it. There's no excuse for not highmem enabling YOUR driver. /jens
+ */
+struct scatterlist {
+	struct page	*page;		/* Location for highmem page, if any */
+	unsigned int	offset;		/* for highmem, page offset */
+
+	dma_addr_t	dma_address;
+	unsigned int	length;
+};
+
+#define ISA_DMA_THRESHOLD (0xffffffffUL)
+
+#endif /* !_ASM_SCATTERLIST_H */
diff -Nru a/include/asm-frv/sections.h b/include/asm-frv/sections.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/sections.h	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,46 @@
+/* sections.h: linkage layout variables
+ *
+ * Copyright (C) 2004 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.
+ */
+
+#ifndef _ASM_SECTIONS_H
+#define _ASM_SECTIONS_H
+
+#ifndef __ASSEMBLY__
+
+#include <linux/types.h>
+#include <asm-generic/sections.h>
+
+#ifdef __KERNEL__
+
+/*
+ * we don't want to put variables in the GP-REL section if they're not used very much - that would
+ * be waste since GP-REL addressing is limited to GP16+/-2048
+ */
+#define __nongpreldata	__attribute__((section(".data")))
+#define __nongprelbss	__attribute__((section(".bss")))
+
+/*
+ * linker symbols
+ */
+extern const void __kernel_image_start, __kernel_image_end, __page_offset;
+
+extern unsigned long __nongprelbss memory_start;
+extern unsigned long __nongprelbss memory_end;
+extern unsigned long __nongprelbss rom_length;
+
+/* determine if we're running from ROM */
+static inline int is_in_rom(unsigned long addr)
+{
+	return 0; /* default case: not in ROM */
+}
+
+#endif
+#endif
+#endif /* _ASM_SECTIONS_H */
diff -Nru a/include/asm-frv/segment.h b/include/asm-frv/segment.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/segment.h	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,46 @@
+/* segment.h: MMU segment settings
+ *
+ * Copyright (C) 2003 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.
+ */
+
+#ifndef _ASM_SEGMENT_H
+#define _ASM_SEGMENT_H
+
+#include <linux/config.h>
+
+#ifndef __ASSEMBLY__
+
+typedef struct {
+	unsigned long seg;
+} mm_segment_t;
+
+#define MAKE_MM_SEG(s)	((mm_segment_t) { (s) })
+
+#define KERNEL_DS		MAKE_MM_SEG(0xdfffffffUL)
+
+#ifdef CONFIG_MMU
+#define USER_DS			MAKE_MM_SEG(TASK_SIZE - 1)
+#else
+#define USER_DS			KERNEL_DS
+#endif
+
+#define get_ds()		(KERNEL_DS)
+#define get_fs()		(__current_thread_info->addr_limit)
+#define segment_eq(a,b)		((a).seg == (b).seg)
+#define __kernel_ds_p()		segment_eq(get_fs(), KERNEL_DS)
+#define get_addr_limit()	(get_fs().seg)
+
+#define set_fs(_x)					\
+do {							\
+	__current_thread_info->addr_limit = (_x);	\
+} while(0)
+
+
+#endif /* __ASSEMBLY__ */
+#endif /* _ASM_SEGMENT_H */
diff -Nru a/include/asm-frv/semaphore.h b/include/asm-frv/semaphore.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/semaphore.h	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,161 @@
+/* semaphore.h: semaphores for the FR-V
+ *
+ * Copyright (C) 2003 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.
+ */
+#ifndef _ASM_SEMAPHORE_H
+#define _ASM_SEMAPHORE_H
+
+#define RW_LOCK_BIAS		 0x01000000
+
+#ifndef __ASSEMBLY__
+
+#include <linux/linkage.h>
+#include <linux/wait.h>
+#include <linux/spinlock.h>
+#include <linux/rwsem.h>
+
+#define SEMAPHORE_DEBUG		WAITQUEUE_DEBUG
+
+/*
+ * the semaphore definition
+ * - if counter is >0 then there are tokens available on the semaphore for down to collect
+ * - if counter is <=0 then there are no spare tokens, and anyone that wants one must wait
+ * - if wait_list is not empty, then there are processes waiting for the semaphore
+ */
+struct semaphore {
+	unsigned		counter;
+	spinlock_t		wait_lock;
+	struct list_head	wait_list;
+#if SEMAPHORE_DEBUG
+	unsigned		__magic;
+#endif
+};
+
+#if SEMAPHORE_DEBUG
+# define __SEM_DEBUG_INIT(name) , (long)&(name).__magic
+#else
+# define __SEM_DEBUG_INIT(name)
+#endif
+
+
+#define __SEMAPHORE_INITIALIZER(name,count) \
+{ count, SPIN_LOCK_UNLOCKED, LIST_HEAD_INIT((name).wait_list) __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)
+
+static inline void sema_init (struct semaphore *sem, int val)
+{
+	*sem = (struct semaphore) __SEMAPHORE_INITIALIZER(*sem, val);
+}
+
+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);
+}
+
+extern void __down(struct semaphore *sem, unsigned long flags);
+extern int  __down_interruptible(struct semaphore *sem, unsigned long flags);
+extern void __up(struct semaphore *sem);
+
+static inline void down(struct semaphore *sem)
+{
+	unsigned long flags;
+
+#if SEMAPHORE_DEBUG
+	CHECK_MAGIC(sem->__magic);
+#endif
+
+	spin_lock_irqsave(&sem->wait_lock, flags);
+	if (likely(sem->counter > 0)) {
+		sem->counter--;
+		spin_unlock_irqrestore(&sem->wait_lock, flags);
+	}
+	else {
+		__down(sem, flags);
+	}
+}
+
+static inline int down_interruptible(struct semaphore *sem)
+{
+	unsigned long flags;
+	int ret = 0;
+
+#if SEMAPHORE_DEBUG
+	CHECK_MAGIC(sem->__magic);
+#endif
+
+	spin_lock_irqsave(&sem->wait_lock, flags);
+	if (likely(sem->counter > 0)) {
+		sem->counter--;
+		spin_unlock_irqrestore(&sem->wait_lock, flags);
+	}
+	else {
+		ret = __down_interruptible(sem, flags);
+	}
+	return ret;
+}
+
+/*
+ * non-blockingly attempt to down() a semaphore.
+ * - returns zero if we acquired it
+ */
+static inline int down_trylock(struct semaphore *sem)
+{
+	unsigned long flags;
+	int success = 0;
+
+#if SEMAPHORE_DEBUG
+	CHECK_MAGIC(sem->__magic);
+#endif
+
+	spin_lock_irqsave(&sem->wait_lock, flags);
+	if (sem->counter > 0) {
+		sem->counter--;
+		success = 1;
+	}
+	spin_unlock_irqrestore(&sem->wait_lock, flags);
+	return !success;
+}
+
+static inline void up(struct semaphore *sem)
+{
+	unsigned long flags;
+
+#if SEMAPHORE_DEBUG
+	CHECK_MAGIC(sem->__magic);
+#endif
+
+	spin_lock_irqsave(&sem->wait_lock, flags);
+	if (!list_empty(&sem->wait_list))
+		__up(sem);
+	else
+		sem->counter++;
+	spin_unlock_irqrestore(&sem->wait_lock, flags);
+}
+
+static inline int sem_getcount(struct semaphore *sem)
+{
+	return sem->counter;
+}
+
+#endif /* __ASSEMBLY__ */
+
+#endif
diff -Nru a/include/asm-frv/sembuf.h b/include/asm-frv/sembuf.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/sembuf.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,26 @@
+#ifndef _ASM_SEMBUF_H
+#define _ASM_SEMBUF_H
+
+/*
+ * The semid64_ds structure for FR-V 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
+ */
+
+struct semid64_ds {
+	struct ipc64_perm	sem_perm;	/* permissions .. see ipc.h */
+	__kernel_time_t		sem_otime;	/* last semop time */
+	unsigned long		__unused1;
+	__kernel_time_t		sem_ctime;	/* last change time */
+	unsigned long		__unused2;
+	unsigned long		sem_nsems;	/* no. of semaphores in array */
+	unsigned long		__unused3;
+	unsigned long		__unused4;
+};
+
+#endif /* _ASM_SEMBUF_H */
+
diff -Nru a/include/asm-frv/serial-regs.h b/include/asm-frv/serial-regs.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/serial-regs.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,44 @@
+/* serial-regs.h: serial port registers
+ *
+ * Copyright (C) 2003 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.
+ */
+
+#ifndef _ASM_SERIAL_REGS_H
+#define _ASM_SERIAL_REGS_H
+
+#include <linux/serial_reg.h>
+#include <asm/irc-regs.h>
+
+#define SERIAL_ICLK	33333333	/* the target serial input clock */
+#define UART0_BASE	0xfeff9c00
+#define UART1_BASE	0xfeff9c40
+
+#define __get_UART0(R) ({ __reg(UART0_BASE + (R) * 8) >> 24; })
+#define __get_UART1(R) ({ __reg(UART1_BASE + (R) * 8) >> 24; })
+#define __set_UART0(R,V) do { __reg(UART0_BASE + (R) * 8) = (V) << 24; } while(0)
+#define __set_UART1(R,V) do { __reg(UART1_BASE + (R) * 8) = (V) << 24; } while(0)
+
+#define __get_UART0_LSR() ({ __get_UART0(UART_LSR); })
+#define __get_UART1_LSR() ({ __get_UART1(UART_LSR); })
+
+#define __set_UART0_IER(V) __set_UART0(UART_IER,(V))
+#define __set_UART1_IER(V) __set_UART1(UART_IER,(V))
+
+/* serial prescaler select register */
+#define __get_UCPSR()	({ *(volatile unsigned long *)(0xfeff9c90); })
+#define __set_UCPSR(V)	do { *(volatile unsigned long *)(0xfeff9c90) = (V); } while(0)
+#define UCPSR_SELECT0	0x07000000
+#define UCPSR_SELECT1	0x38000000
+
+/* serial prescaler base value register */
+#define __get_UCPVR()	({ *(volatile unsigned long *)(0xfeff9c98); mb(); })
+#define __set_UCPVR(V)	do { *(volatile unsigned long *)(0xfeff9c98) = (V) << 24; mb(); } while(0)
+
+
+#endif /* _ASM_SERIAL_REGS_H */
diff -Nru a/include/asm-frv/serial.h b/include/asm-frv/serial.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/serial.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,19 @@
+/*
+ * serial.h
+ *
+ * Copyright (C) 2003 Develer S.r.l. (http://www.develer.com/)
+ * Author: Bernardo Innocenti <bernie@codewiz.org>
+ *
+ * Based on linux/include/asm-i386/serial.h
+ */
+#include <linux/config.h>
+#include <asm/serial-regs.h>
+
+/*
+ * the base baud is derived from the clock speed and so is variable
+ */
+#define BASE_BAUD 0
+
+#define STD_COM_FLAGS		ASYNC_BOOT_AUTOCONF
+
+#define SERIAL_PORT_DFNS
diff -Nru a/include/asm-frv/setup.h b/include/asm-frv/setup.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/setup.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,25 @@
+/* setup.h: setup stuff
+ *
+ * Copyright (C) 2004 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.
+ */
+
+#ifndef _ASM_SETUP_H
+#define _ASM_SETUP_H
+
+#include <linux/init.h>
+
+#ifndef __ASSEMBLY__
+
+#ifdef CONFIG_MMU
+extern unsigned long __initdata num_mappedpages;
+#endif
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _ASM_SETUP_H */
diff -Nru a/include/asm-frv/shmbuf.h b/include/asm-frv/shmbuf.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/shmbuf.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,43 @@
+#ifndef _ASM_SHMBUF_H
+#define _ASM_SHMBUF_H
+
+/*
+ * The shmid64_ds structure for FR-V 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
+ */
+
+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 /* _ASM_SHMBUF_H */
+
diff -Nru a/include/asm-frv/shmparam.h b/include/asm-frv/shmparam.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/shmparam.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,7 @@
+#ifndef _ASM_SHMPARAM_H
+#define _ASM_SHMPARAM_H
+
+#define	SHMLBA PAGE_SIZE		 /* attach addr a multiple of this */
+
+#endif /* _ASM_SHMPARAM_H */
+
diff -Nru a/include/asm-frv/sigcontext.h b/include/asm-frv/sigcontext.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/sigcontext.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,26 @@
+/* sigcontext.h: FRV signal context
+ *
+ * Copyright (C) 2003 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.
+ */
+#ifndef _ASM_SIGCONTEXT_H
+#define _ASM_SIGCONTEXT_H
+
+#include <asm/registers.h>
+
+/*
+ * Signal context structure - contains all info to do with the state
+ * before the signal handler was invoked.  Note: only add new entries
+ * to the end of the structure.
+ */
+struct sigcontext {
+	struct user_context	sc_context;
+	unsigned long		sc_oldmask; 	/* old sigmask */
+} __attribute__((aligned(8)));
+
+#endif
diff -Nru a/include/asm-frv/siginfo.h b/include/asm-frv/siginfo.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/siginfo.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,12 @@
+#ifndef _ASM_SIGINFO_H
+#define _ASM_SIGINFO_H
+
+#include <linux/types.h>
+#include <asm-generic/siginfo.h>
+
+#define FPE_MDAOVF	(__SI_FAULT|9)	/* media overflow */
+#undef NSIGFPE
+#define NSIGFPE		9
+
+#endif
+
diff -Nru a/include/asm-frv/signal.h b/include/asm-frv/signal.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/signal.h	2005-03-01 23:39:26 -08:00
@@ -0,0 +1,187 @@
+#ifndef _ASM_SIGNAL_H
+#define _ASM_SIGNAL_H
+
+#include <linux/types.h>
+
+/* Avoid too many header ordering problems.  */
+struct siginfo;
+
+#ifdef __KERNEL__
+/* Most things should be clean enough to redefine this at will, if care
+   is taken to make libc match.  */
+
+#define _NSIG		64
+#define _NSIG_BPW	32
+#define _NSIG_WORDS	(_NSIG / _NSIG_BPW)
+
+typedef unsigned long old_sigset_t;		/* at least 32 bits */
+
+typedef struct {
+	unsigned long sig[_NSIG_WORDS];
+} sigset_t;
+
+#else
+/* Here we must cater to libcs that poke about in kernel headers.  */
+
+#define NSIG		32
+typedef unsigned long sigset_t;
+
+#endif /* __KERNEL__ */
+
+#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
+
+#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;
+
+extern int do_signal(struct pt_regs *regs, sigset_t *oldset);
+#define ptrace_signal_deliver(regs, cookie) do { } while (0)
+
+#ifdef __KERNEL__
+
+#include <asm/sigcontext.h>
+#undef __HAVE_ARCH_SIG_BITOPS
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_SIGNAL_H */
diff -Nru a/include/asm-frv/smp.h b/include/asm-frv/smp.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/smp.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,10 @@
+#ifndef __ASM_SMP_H
+#define __ASM_SMP_H
+
+#include <linux/config.h>
+
+#ifdef CONFIG_SMP
+#error SMP not supported
+#endif
+
+#endif
diff -Nru a/include/asm-frv/socket.h b/include/asm-frv/socket.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/socket.h	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,51 @@
+#ifndef _ASM_SOCKET_H
+#define _ASM_SOCKET_H
+
+#include <asm/sockios.h>
+
+/* For setsockopt(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 /* _ASM_SOCKET_H */
+
diff -Nru a/include/asm-frv/sockios.h b/include/asm-frv/sockios.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/sockios.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,13 @@
+#ifndef _ASM_SOCKIOS__
+#define _ASM_SOCKIOS__
+
+/* Socket-level I/O control calls. */
+#define FIOSETOWN 	0x8901
+#define SIOCSPGRP	0x8902
+#define FIOGETOWN	0x8903
+#define SIOCGPGRP	0x8904
+#define SIOCATMARK	0x8905
+#define SIOCGSTAMP	0x8906		/* Get stamp */
+
+#endif /* _ASM_SOCKIOS__ */
+
diff -Nru a/include/asm-frv/spinlock.h b/include/asm-frv/spinlock.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/spinlock.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,17 @@
+/* spinlock.h: spinlocks for FR-V
+ *
+ * Copyright (C) 2003 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.
+ */
+
+#ifndef _ASM_SPINLOCK_H
+#define _ASM_SPINLOCK_H
+
+#error no spinlocks for FR-V yet
+
+#endif /* _ASM_SPINLOCK_H */
diff -Nru a/include/asm-frv/spr-regs.h b/include/asm-frv/spr-regs.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/spr-regs.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,401 @@
+/* spr-regs.h: special-purpose registers on the FRV
+ *
+ * Copyright (C) 2003, 2004 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.
+ */
+
+#ifndef _ASM_SPR_REGS_H
+#define _ASM_SPR_REGS_H
+
+/*
+ * PSR - Processor Status Register
+ */
+#define PSR_ET			0x00000001	/* enable interrupts/exceptions flag */
+#define PSR_PS			0x00000002	/* previous supervisor mode flag */
+#define PSR_S			0x00000004	/* supervisor mode flag */
+#define PSR_PIL			0x00000078	/* processor external interrupt level */
+#define PSR_PIL_0		0x00000000	/* - no interrupt in progress */
+#define PSR_PIL_13		0x00000068	/* - debugging only */
+#define PSR_PIL_14		0x00000070	/* - debugging in progress */
+#define PSR_PIL_15		0x00000078	/* - NMI in progress */
+#define PSR_EM			0x00000080	/* enable media operation */
+#define PSR_EF			0x00000100	/* enable FPU operation */
+#define PSR_BE			0x00001000	/* endianness mode */
+#define PSR_BE_LE		0x00000000	/* - little endian mode */
+#define PSR_BE_BE		0x00001000	/* - big endian mode */
+#define PSR_CM			0x00002000	/* conditional mode */
+#define PSR_NEM			0x00004000	/* non-excepting mode */
+#define PSR_ICE			0x00010000	/* in-circuit emulation mode */
+#define PSR_VERSION_SHIFT	24		/* CPU silicon ID */
+#define PSR_IMPLE_SHIFT		28		/* CPU core ID */
+
+#define PSR_VERSION(psr)	(((psr) >> PSR_VERSION_SHIFT) & 0xf)
+#define PSR_IMPLE(psr)		(((psr) >> PSR_IMPLE_SHIFT) & 0xf)
+
+#define PSR_IMPLE_FR401		0x2
+#define PSR_VERSION_FR401_MB93401	0x0
+#define PSR_VERSION_FR401_MB93401A	0x1
+#define PSR_VERSION_FR401_MB93403	0x2
+
+#define PSR_IMPLE_FR405		0x4
+#define PSR_VERSION_FR405_MB93405	0x0
+
+#define PSR_IMPLE_FR451		0x5
+#define PSR_VERSION_FR451_MB93451	0x0
+
+#define PSR_IMPLE_FR501		0x1
+#define PSR_VERSION_FR501_MB93501	0x1
+#define PSR_VERSION_FR501_MB93501A	0x2
+
+#define PSR_IMPLE_FR551		0x3
+#define PSR_VERSION_FR551_MB93555	0x1
+
+#define __get_PSR()	({ unsigned long x; asm volatile("movsg psr,%0" : "=r"(x)); x; })
+#define __set_PSR(V)	do { asm volatile("movgs %0,psr" : : "r"(V)); } while(0)
+
+/*
+ * TBR - Trap Base Register
+ */
+#define TBR_TT			0x00000ff0
+#define TBR_TT_INSTR_MMU_MISS	(0x01 << 4)
+#define TBR_TT_INSTR_ACC_ERROR	(0x02 << 4)
+#define TBR_TT_INSTR_ACC_EXCEP	(0x03 << 4)
+#define TBR_TT_PRIV_INSTR	(0x06 << 4)
+#define TBR_TT_ILLEGAL_INSTR	(0x07 << 4)
+#define TBR_TT_FP_EXCEPTION	(0x0d << 4)
+#define TBR_TT_MP_EXCEPTION	(0x0e << 4)
+#define TBR_TT_DATA_ACC_ERROR	(0x11 << 4)
+#define TBR_TT_DATA_MMU_MISS	(0x12 << 4)
+#define TBR_TT_DATA_ACC_EXCEP	(0x13 << 4)
+#define TBR_TT_DATA_STR_ERROR	(0x14 << 4)
+#define TBR_TT_DIVISION_EXCEP	(0x17 << 4)
+#define TBR_TT_COMMIT_EXCEP	(0x19 << 4)
+#define TBR_TT_INSTR_TLB_MISS	(0x1a << 4)
+#define TBR_TT_DATA_TLB_MISS	(0x1b << 4)
+#define TBR_TT_DATA_DAT_EXCEP	(0x1d << 4)
+#define TBR_TT_DECREMENT_TIMER	(0x1f << 4)
+#define TBR_TT_COMPOUND_EXCEP	(0x20 << 4)
+#define TBR_TT_INTERRUPT_1	(0x21 << 4)
+#define TBR_TT_INTERRUPT_2	(0x22 << 4)
+#define TBR_TT_INTERRUPT_3	(0x23 << 4)
+#define TBR_TT_INTERRUPT_4	(0x24 << 4)
+#define TBR_TT_INTERRUPT_5	(0x25 << 4)
+#define TBR_TT_INTERRUPT_6	(0x26 << 4)
+#define TBR_TT_INTERRUPT_7	(0x27 << 4)
+#define TBR_TT_INTERRUPT_8	(0x28 << 4)
+#define TBR_TT_INTERRUPT_9	(0x29 << 4)
+#define TBR_TT_INTERRUPT_10	(0x2a << 4)
+#define TBR_TT_INTERRUPT_11	(0x2b << 4)
+#define TBR_TT_INTERRUPT_12	(0x2c << 4)
+#define TBR_TT_INTERRUPT_13	(0x2d << 4)
+#define TBR_TT_INTERRUPT_14	(0x2e << 4)
+#define TBR_TT_INTERRUPT_15	(0x2f << 4)
+#define TBR_TT_TRAP0		(0x80 << 4)
+#define TBR_TT_TRAP1		(0x81 << 4)
+#define TBR_TT_TRAP2		(0x82 << 4)
+#define TBR_TT_TRAP126		(0xfe << 4)
+#define TBR_TT_BREAK		(0xff << 4)
+
+#define __get_TBR()	({ unsigned long x; asm volatile("movsg tbr,%0" : "=r"(x)); x; })
+
+/*
+ * HSR0 - Hardware Status Register 0
+ */
+#define HSR0_PDM		0x00000007	/* power down mode */
+#define HSR0_PDM_NORMAL		0x00000000	/* - normal mode */
+#define HSR0_PDM_CORE_SLEEP	0x00000001	/* - CPU core sleep mode */
+#define HSR0_PDM_BUS_SLEEP	0x00000003	/* - bus sleep mode */
+#define HSR0_PDM_PLL_RUN	0x00000005	/* - PLL run */
+#define HSR0_PDM_PLL_STOP	0x00000007	/* - PLL stop */
+#define HSR0_GRLE		0x00000040	/* GR lower register set enable */
+#define HSR0_GRHE		0x00000080	/* GR higher register set enable */
+#define HSR0_FRLE		0x00000100	/* FR lower register set enable */
+#define HSR0_FRHE		0x00000200	/* FR higher register set enable */
+#define HSR0_GRN		0x00000400	/* GR quantity */
+#define HSR0_GRN_64		0x00000000	/* - 64 GR registers */
+#define HSR0_GRN_32		0x00000400	/* - 32 GR registers */
+#define HSR0_FRN		0x00000800	/* FR quantity */
+#define HSR0_FRN_64		0x00000000	/* - 64 FR registers */
+#define HSR0_FRN_32		0x00000800	/* - 32 FR registers */
+#define HSR0_SA			0x00001000	/* start address (RAMBOOT#) */
+#define HSR0_ETMI		0x00008000	/* enable TIMERI (64-bit up timer) */
+#define HSR0_ETMD		0x00004000	/* enable TIMERD (32-bit down timer) */
+#define HSR0_PEDAT		0x00010000	/* previous DAT mode */
+#define HSR0_XEDAT		0x00020000	/* exception DAT mode */
+#define HSR0_EDAT		0x00080000	/* enable DAT mode */
+#define HSR0_RME		0x00400000	/* enable RAM mode */
+#define HSR0_EMEM		0x00800000	/* enable MMU_Miss mask */
+#define HSR0_EXMMU		0x01000000	/* enable extended MMU mode */
+#define HSR0_EDMMU		0x02000000	/* enable data MMU */
+#define HSR0_EIMMU		0x04000000	/* enable instruction MMU */
+#define HSR0_CBM		0x08000000	/* copy back mode */
+#define HSR0_CBM_WRITE_THRU	0x00000000	/* - write through */
+#define HSR0_CBM_COPY_BACK	0x08000000	/* - copy back */
+#define HSR0_NWA		0x10000000	/* no write allocate */
+#define HSR0_DCE		0x40000000	/* data cache enable */
+#define HSR0_ICE		0x80000000	/* instruction cache enable */
+
+#define __get_HSR(R)	({ unsigned long x; asm volatile("movsg hsr"#R",%0" : "=r"(x)); x; })
+#define __set_HSR(R,V)	do { asm volatile("movgs %0,hsr"#R : : "r"(V)); } while(0)
+
+/*
+ * CCR - Condition Codes Register
+ */
+#define CCR_FCC0		0x0000000f	/* FP/Media condition 0 (fcc0 reg) */
+#define CCR_FCC1		0x000000f0	/* FP/Media condition 1 (fcc1 reg) */
+#define CCR_FCC2		0x00000f00	/* FP/Media condition 2 (fcc2 reg) */
+#define CCR_FCC3		0x0000f000	/* FP/Media condition 3 (fcc3 reg) */
+#define CCR_ICC0		0x000f0000	/* Integer condition 0 (icc0 reg) */
+#define CCR_ICC0_C		0x00010000	/* - Carry flag */
+#define CCR_ICC0_V		0x00020000	/* - Overflow flag */
+#define CCR_ICC0_Z		0x00040000	/* - Zero flag */
+#define CCR_ICC0_N		0x00080000	/* - Negative flag */
+#define CCR_ICC1		0x00f00000	/* Integer condition 1 (icc1 reg) */
+#define CCR_ICC2		0x0f000000	/* Integer condition 2 (icc2 reg) */
+#define CCR_ICC3		0xf0000000	/* Integer condition 3 (icc3 reg) */
+
+/*
+ * CCCR - Condition Codes for Conditional Instructions Register
+ */
+#define CCCR_CC0		0x00000003	/* condition 0 (cc0 reg) */
+#define CCCR_CC0_FALSE		0x00000002	/* - condition is false */
+#define CCCR_CC0_TRUE		0x00000003	/* - condition is true */
+#define CCCR_CC1		0x0000000c	/* condition 1 (cc1 reg) */
+#define CCCR_CC2		0x00000030	/* condition 2 (cc2 reg) */
+#define CCCR_CC3		0x000000c0	/* condition 3 (cc3 reg) */
+#define CCCR_CC4		0x00000300	/* condition 4 (cc4 reg) */
+#define CCCR_CC5		0x00000c00	/* condition 5 (cc5 reg) */
+#define CCCR_CC6		0x00003000	/* condition 6 (cc6 reg) */
+#define CCCR_CC7		0x0000c000	/* condition 7 (cc7 reg) */
+
+/*
+ * ISR - Integer Status Register
+ */
+#define ISR_EMAM		0x00000001	/* memory misaligned access handling */
+#define ISR_EMAM_EXCEPTION	0x00000000	/* - generate exception */
+#define ISR_EMAM_FUDGE		0x00000001	/* - mask out invalid address bits */
+#define ISR_AEXC		0x00000004	/* accrued [overflow] exception */
+#define ISR_DTT			0x00000018	/* division type trap */
+#define ISR_DTT_IGNORE		0x00000000	/* - ignore division error */
+#define ISR_DTT_DIVBYZERO	0x00000008	/* - generate exception */
+#define ISR_DTT_OVERFLOW	0x00000010	/* - record overflow */
+#define ISR_EDE			0x00000020	/* enable division exception */
+#define ISR_PLI			0x20000000	/* pre-load instruction information */
+#define ISR_QI			0x80000000	/* quad data implementation information */
+
+/*
+ * EPCR0 - Exception PC Register
+ */
+#define EPCR0_V			0x00000001	/* register content validity indicator */
+#define EPCR0_PC		0xfffffffc	/* faulting instruction address */
+
+/*
+ * ESR0/14/15 - Exception Status Register
+ */
+#define ESRx_VALID		0x00000001	/* register content validity indicator */
+#define ESRx_EC			0x0000003e	/* exception type */
+#define ESRx_EC_DATA_STORE	0x00000000	/* - data_store_error */
+#define ESRx_EC_INSN_ACCESS	0x00000006	/* - instruction_access_error */
+#define ESRx_EC_PRIV_INSN	0x00000008	/* - privileged_instruction */
+#define ESRx_EC_ILL_INSN	0x0000000a	/* - illegal_instruction */
+#define ESRx_EC_MP_EXCEP	0x0000001c	/* - mp_exception */
+#define ESRx_EC_DATA_ACCESS	0x00000020	/* - data_access_error */
+#define ESRx_EC_DIVISION	0x00000026	/* - division_exception */
+#define ESRx_EC_ITLB_MISS	0x00000034	/* - instruction_access_TLB_miss */
+#define ESRx_EC_DTLB_MISS	0x00000036	/* - data_access_TLB_miss */
+#define ESRx_EC_DATA_ACCESS_DAT	0x0000003a	/* - data_access_DAT_exception */
+
+#define ESR0_IAEC		0x00000100	/* info for instruction-access-exception */
+#define ESR0_IAEC_RESV		0x00000000	/* - reserved */
+#define ESR0_IAEC_PROT_VIOL	0x00000100	/* - protection violation */
+
+#define ESR0_ATXC		0x00f00000	/* address translation exception code */
+#define ESR0_ATXC_MMU_MISS	0x00000000	/* - MMU miss exception and more (?) */
+#define ESR0_ATXC_MULTI_DAT	0x00800000	/* - multiple DAT entry hit */
+#define ESR0_ATXC_MULTI_SAT	0x00900000	/* - multiple SAT entry hit */
+#define ESR0_ATXC_AMRTLB_MISS	0x00a00000	/* - MMU/TLB miss exception */
+#define ESR0_ATXC_PRIV_EXCEP	0x00c00000	/* - privilege protection fault */
+#define ESR0_ATXC_WP_EXCEP	0x00d00000	/* - write protection fault */
+
+#define ESR0_EAV		0x00000800	/* true if EAR0 register valid */
+#define ESR15_EAV		0x00000800	/* true if EAR15 register valid */
+
+/*
+ * ESFR1 - Exception Status Valid Flag Register
+ */
+#define ESFR1_ESR0		0x00000001	/* true if ESR0 is valid */
+#define ESFR1_ESR14		0x00004000	/* true if ESR14 is valid */
+#define ESFR1_ESR15		0x00008000	/* true if ESR15 is valid */
+
+/*
+ * MSR - Media Status Register
+ */
+#define MSR0_AOVF		0x00000001	/* overflow exception accrued */
+#define MSRx_OVF		0x00000002	/* overflow exception detected */
+#define MSRx_SIE		0x0000003c	/* last SIMD instruction exception detected */
+#define MSRx_SIE_NONE		0x00000000	/* - none detected */
+#define MSRx_SIE_FRkHI_ACCk	0x00000020	/* - exception at FRkHI or ACCk */
+#define MSRx_SIE_FRkLO_ACCk1	0x00000010	/* - exception at FRkLO or ACCk+1 */
+#define MSRx_SIE_FRk1HI_ACCk2	0x00000008	/* - exception at FRk+1HI or ACCk+2 */
+#define MSRx_SIE_FRk1LO_ACCk3	0x00000004	/* - exception at FRk+1LO or ACCk+3 */
+#define MSR0_MTT		0x00007000	/* type of last media trap detected */
+#define MSR0_MTT_NONE		0x00000000	/* - none detected */
+#define MSR0_MTT_OVERFLOW	0x00001000	/* - overflow detected */
+#define MSR0_HI			0x00c00000	/* hardware implementation */
+#define MSR0_HI_ROUNDING	0x00000000	/* - rounding mode */
+#define MSR0_HI_NONROUNDING	0x00c00000	/* - non-rounding mode */
+#define MSR0_EMCI		0x01000000	/* enable media custom instructions */
+#define MSR0_SRDAV		0x10000000	/* select rounding mode of MAVEH */
+#define MSR0_SRDAV_RDAV		0x00000000	/* - controlled by MSR.RDAV */
+#define MSR0_SRDAV_RD		0x10000000	/* - controlled by MSR.RD */
+#define MSR0_RDAV		0x20000000	/* rounding mode of MAVEH */
+#define MSR0_RDAV_NEAREST_MI	0x00000000	/* - round to nearest minus */
+#define MSR0_RDAV_NEAREST_PL	0x20000000	/* - round to nearest plus */
+#define MSR0_RD			0xc0000000	/* rounding mode */
+#define MSR0_RD_NEAREST		0x00000000	/* - nearest */
+#define MSR0_RD_ZERO		0x40000000	/* - zero */
+#define MSR0_RD_POS_INF		0x80000000	/* - postive infinity */
+#define MSR0_RD_NEG_INF		0xc0000000	/* - negative infinity */
+
+/*
+ * IAMPR0-7 - Instruction Address Mapping Register
+ * DAMPR0-7 - Data Address Mapping Register
+ */
+#define xAMPRx_V		0x00000001	/* register content validity indicator */
+#define DAMPRx_WP		0x00000002	/* write protect */
+#define DAMPRx_WP_RW		0x00000000	/* - read/write */
+#define DAMPRx_WP_RO		0x00000002	/* - read-only */
+#define xAMPRx_C		0x00000004	/* cached/uncached */
+#define xAMPRx_C_CACHED		0x00000000	/* - cached */
+#define xAMPRx_C_UNCACHED	0x00000004	/* - uncached */
+#define xAMPRx_S		0x00000008	/* supervisor only */
+#define xAMPRx_S_USER		0x00000000	/* - userspace can access */
+#define xAMPRx_S_KERNEL		0x00000008	/* - kernel only */
+#define xAMPRx_SS		0x000000f0	/* segment size */
+#define xAMPRx_SS_16Kb		0x00000000	/* - 16 kilobytes */
+#define xAMPRx_SS_64Kb		0x00000010	/* - 64 kilobytes */
+#define xAMPRx_SS_256Kb		0x00000020	/* - 256 kilobytes */
+#define xAMPRx_SS_1Mb		0x00000030	/* - 1 megabyte */
+#define xAMPRx_SS_2Mb		0x00000040	/* - 2 megabytes */
+#define xAMPRx_SS_4Mb		0x00000050	/* - 4 megabytes */
+#define xAMPRx_SS_8Mb		0x00000060	/* - 8 megabytes */
+#define xAMPRx_SS_16Mb		0x00000070	/* - 16 megabytes */
+#define xAMPRx_SS_32Mb		0x00000080	/* - 32 megabytes */
+#define xAMPRx_SS_64Mb		0x00000090	/* - 64 megabytes */
+#define xAMPRx_SS_128Mb		0x000000a0	/* - 128 megabytes */
+#define xAMPRx_SS_256Mb		0x000000b0	/* - 256 megabytes */
+#define xAMPRx_SS_512Mb		0x000000c0	/* - 512 megabytes */
+#define xAMPRx_RESERVED8	0x00000100	/* reserved bit */
+#define xAMPRx_NG		0x00000200	/* non-global */
+#define xAMPRx_L		0x00000400	/* locked */
+#define xAMPRx_M		0x00000800	/* modified */
+#define xAMPRx_D		0x00001000	/* DAT entry */
+#define xAMPRx_RESERVED13	0x00002000	/* reserved bit */
+#define xAMPRx_PPFN		0xfff00000	/* physical page frame number */
+
+#define xAMPRx_V_BIT		0
+#define DAMPRx_WP_BIT		1
+#define xAMPRx_C_BIT		2
+#define xAMPRx_S_BIT		3
+#define xAMPRx_RESERVED8_BIT	8
+#define xAMPRx_NG_BIT		9
+#define xAMPRx_L_BIT		10
+#define xAMPRx_M_BIT		11
+#define xAMPRx_D_BIT		12
+#define xAMPRx_RESERVED13_BIT	13
+
+#define __get_IAMPR(R) ({ unsigned long x; asm volatile("movsg iampr"#R",%0" : "=r"(x)); x; })
+#define __get_DAMPR(R) ({ unsigned long x; asm volatile("movsg dampr"#R",%0" : "=r"(x)); x; })
+
+#define __get_IAMLR(R) ({ unsigned long x; asm volatile("movsg iamlr"#R",%0" : "=r"(x)); x; })
+#define __get_DAMLR(R) ({ unsigned long x; asm volatile("movsg damlr"#R",%0" : "=r"(x)); x; })
+
+#define __set_IAMPR(R,V) 	do { asm volatile("movgs %0,iampr"#R : : "r"(V)); } while(0)
+#define __set_DAMPR(R,V)  	do { asm volatile("movgs %0,dampr"#R : : "r"(V)); } while(0)
+
+#define __set_IAMLR(R,V) 	do { asm volatile("movgs %0,iamlr"#R : : "r"(V)); } while(0)
+#define __set_DAMLR(R,V)  	do { asm volatile("movgs %0,damlr"#R : : "r"(V)); } while(0)
+
+#define save_dampr(R, _dampr)					\
+do {								\
+	asm volatile("movsg dampr"R",%0" : "=r"(_dampr));	\
+} while(0)
+
+#define restore_dampr(R, _dampr)			\
+do {							\
+	asm volatile("movgs %0,dampr"R :: "r"(_dampr));	\
+} while(0)
+
+/*
+ * AMCR - Address Mapping Control Register
+ */
+#define AMCR_IAMRN		0x000000ff	/* quantity of IAMPR registers */
+#define AMCR_DAMRN		0x0000ff00	/* quantity of DAMPR registers */
+
+/*
+ * TTBR - Address Translation Table Base Register
+ */
+#define __get_TTBR()		({ unsigned long x; asm volatile("movsg ttbr,%0" : "=r"(x)); x; })
+
+/*
+ * TPXR - TLB Probe Extend Register
+ */
+#define TPXR_E			0x00000001
+#define TPXR_LMAX_SHIFT		20
+#define TPXR_LMAX_SMASK		0xf
+#define TPXR_WMAX_SHIFT		24
+#define TPXR_WMAX_SMASK		0xf
+#define TPXR_WAY_SHIFT		28
+#define TPXR_WAY_SMASK		0xf
+
+/*
+ * DCR - Debug Control Register
+ */
+#define DCR_IBCE3		0x00000001	/* break on conditional insn pointed to by IBAR3 */
+#define DCR_IBE3		0x00000002	/* break on insn pointed to by IBAR3 */
+#define DCR_IBCE1		0x00000004	/* break on conditional insn pointed to by IBAR2 */
+#define DCR_IBE1		0x00000008	/* break on insn pointed to by IBAR2 */
+#define DCR_IBCE2		0x00000010	/* break on conditional insn pointed to by IBAR1 */
+#define DCR_IBE2		0x00000020	/* break on insn pointed to by IBAR1 */
+#define DCR_IBCE0		0x00000040	/* break on conditional insn pointed to by IBAR0 */
+#define DCR_IBE0		0x00000080	/* break on insn pointed to by IBAR0 */
+
+#define DCR_DDBE1		0x00004000	/* use DBDR1x when checking DBAR1 */
+#define DCR_DWBE1		0x00008000	/* break on store to address in DBAR1/DBMR1x */
+#define DCR_DRBE1		0x00010000	/* break on load from address in DBAR1/DBMR1x */
+#define DCR_DDBE0		0x00020000	/* use DBDR0x when checking DBAR0 */
+#define DCR_DWBE0		0x00040000	/* break on store to address in DBAR0/DBMR0x */
+#define DCR_DRBE0		0x00080000	/* break on load from address in DBAR0/DBMR0x */
+
+#define DCR_EIM			0x0c000000	/* external interrupt disable */
+#define DCR_IBM			0x10000000	/* instruction break disable */
+#define DCR_SE			0x20000000	/* single step enable */
+#define DCR_EBE			0x40000000	/* exception break enable */
+
+/*
+ * BRR - Break Interrupt Request Register
+ */
+#define BRR_ST			0x00000001	/* single-step detected */
+#define BRR_SB			0x00000002	/* break instruction detected */
+#define BRR_BB			0x00000004	/* branch with hint detected */
+#define BRR_CBB			0x00000008	/* branch to LR detected */
+#define BRR_IBx			0x000000f0	/* hardware breakpoint detected */
+#define BRR_DBx			0x00000f00	/* hardware watchpoint detected */
+#define BRR_DBNEx		0x0000f000	/* ? */
+#define BRR_EBTT		0x00ff0000	/* trap type of exception break */
+#define BRR_TB			0x10000000	/* external break request detected */
+#define BRR_CB			0x20000000	/* ICE break command detected */
+#define BRR_EB			0x40000000	/* exception break detected */
+
+/*
+ * BPSR - Break PSR Save Register
+ */
+#define BPSR_BET		0x00000001	/* former PSR.ET */
+#define BPSR_BS			0x00001000	/* former PSR.S */
+
+#endif /* _ASM_SPR_REGS_H */
diff -Nru a/include/asm-frv/stat.h b/include/asm-frv/stat.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/stat.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,100 @@
+#ifndef _ASM_STAT_H
+#define _ASM_STAT_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;
+};
+
+/* This matches struct stat in uClibc/glibc.  */
+struct stat {
+	unsigned char __pad1[6];
+	unsigned short st_dev;
+
+	unsigned long __pad2;
+	unsigned long st_ino;
+
+	unsigned short __pad3;
+	unsigned short st_mode;
+	unsigned short __pad4;
+	unsigned short st_nlink;
+
+	unsigned short __pad5;
+	unsigned short st_uid;
+	unsigned short __pad6;
+	unsigned short st_gid;
+
+	unsigned char __pad7[6];
+	unsigned short st_rdev;
+
+	unsigned long __pad8;
+	unsigned long st_size;
+
+	unsigned long __pad9;		/* align 64-bit st_blocks to 2-word */
+	unsigned long st_blksize;
+
+	unsigned long __pad10;	/* future possible st_blocks high bits */
+	unsigned long st_blocks;	/* Number 512-byte blocks allocated. */
+
+	unsigned long __unused1;
+	unsigned long st_atime;
+
+	unsigned long __unused2;
+	unsigned long st_mtime;
+
+	unsigned long __unused3;
+	unsigned long st_ctime;
+
+	unsigned long long __unused4;
+};
+
+/* This matches struct stat64 in uClibc/glibc.  The layout is exactly
+   the same as that of struct stat above, with 64-bit types taking up
+   space that was formerly used by padding.  stat syscalls are still
+   different from stat64, though, in that the former tests for
+   overflow.  */
+struct stat64 {
+	unsigned char __pad1[6];
+	unsigned short st_dev;
+
+	unsigned long long st_ino;
+
+	unsigned int st_mode;
+	unsigned int st_nlink;
+
+	unsigned long st_uid;
+	unsigned long st_gid;
+
+	unsigned char __pad2[6];
+	unsigned short st_rdev;
+
+	long long st_size;
+
+	unsigned long __pad3;		/* align 64-bit st_blocks to 2-word */
+	unsigned long st_blksize;
+
+	unsigned long __pad4;		/* future possible st_blocks high bits */
+	unsigned long st_blocks;	/* Number 512-byte blocks allocated. */
+
+	unsigned long st_atime_nsec;
+	unsigned long st_atime;
+
+	unsigned int st_mtime_nsec;
+	unsigned long st_mtime;
+
+	unsigned long st_ctime_nsec;
+	unsigned long st_ctime;
+
+	unsigned long long __unused4;
+};
+
+#endif /* _ASM_STAT_H */
diff -Nru a/include/asm-frv/statfs.h b/include/asm-frv/statfs.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/statfs.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,7 @@
+#ifndef _ASM_STATFS_H
+#define _ASM_STATFS_H
+
+#include <asm-generic/statfs.h>
+
+#endif /* _ASM_STATFS_H */
+
diff -Nru a/include/asm-frv/string.h b/include/asm-frv/string.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/string.h	2005-03-01 23:39:26 -08:00
@@ -0,0 +1,51 @@
+/* string.h: FRV string handling
+ *
+ * Copyright (C) 2004 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.
+ */
+
+#ifndef _ASM_STRING_H_
+#define _ASM_STRING_H_
+
+#ifdef __KERNEL__ /* only set these up for kernel code */
+
+#define __HAVE_ARCH_MEMSET 1
+#define __HAVE_ARCH_MEMCPY 1
+
+extern void *memset(void *, int, __kernel_size_t);
+extern void *memcpy(void *, const void *, __kernel_size_t);
+
+#else /* KERNEL */
+
+/*
+ *	let user libraries deal with these,
+ *	IMHO the kernel has no place defining these functions for user apps
+ */
+
+#define __HAVE_ARCH_STRCPY 1
+#define __HAVE_ARCH_STRNCPY 1
+#define __HAVE_ARCH_STRCAT 1
+#define __HAVE_ARCH_STRNCAT 1
+#define __HAVE_ARCH_STRCMP 1
+#define __HAVE_ARCH_STRNCMP 1
+#define __HAVE_ARCH_STRNICMP 1
+#define __HAVE_ARCH_STRCHR 1
+#define __HAVE_ARCH_STRRCHR 1
+#define __HAVE_ARCH_STRSTR 1
+#define __HAVE_ARCH_STRLEN 1
+#define __HAVE_ARCH_STRNLEN 1
+#define __HAVE_ARCH_MEMSET 1
+#define __HAVE_ARCH_MEMCPY 1
+#define __HAVE_ARCH_MEMMOVE 1
+#define __HAVE_ARCH_MEMSCAN 1
+#define __HAVE_ARCH_MEMCMP 1
+#define __HAVE_ARCH_MEMCHR 1
+#define __HAVE_ARCH_STRTOK 1
+
+#endif /* KERNEL */
+#endif /* _ASM_STRING_H_ */
diff -Nru a/include/asm-frv/suspend.h b/include/asm-frv/suspend.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/suspend.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,20 @@
+/* suspend.h: suspension stuff
+ *
+ * Copyright (C) 2004 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.
+ */
+
+#ifndef _ASM_SUSPEND_H
+#define _ASM_SUSPEND_H
+
+static inline int arch_prepare_suspend(void)
+{
+	return 0;
+}
+
+#endif /* _ASM_SUSPEND_H */
diff -Nru a/include/asm-frv/system.h b/include/asm-frv/system.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/system.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,126 @@
+/* system.h: FR-V CPU control definitions
+ *
+ * Copyright (C) 2003 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.
+ */
+
+#ifndef _ASM_SYSTEM_H
+#define _ASM_SYSTEM_H
+
+#include <linux/config.h> /* get configuration macros */
+#include <linux/linkage.h>
+#include <asm/atomic.h>
+
+struct thread_struct;
+
+#define prepare_to_switch()    do { } while(0)
+
+/*
+ * switch_to(prev, next) should switch from task `prev' to `next'
+ * `prev' will never be the same as `next'.
+ * The `mb' is to tell GCC not to cache `current' across this call.
+ */
+extern asmlinkage
+struct task_struct *__switch_to(struct thread_struct *prev_thread,
+				struct thread_struct *next_thread,
+				struct task_struct *prev);
+
+#define switch_to(prev, next, last)					\
+do {									\
+	(prev)->thread.sched_lr =					\
+		(unsigned long) __builtin_return_address(0);		\
+	(last) = __switch_to(&(prev)->thread, &(next)->thread, (prev));	\
+	mb();								\
+} while(0)
+
+/*
+ * interrupt flag manipulation
+ */
+#define local_irq_disable()				\
+do {							\
+	unsigned long psr;				\
+	asm volatile("	movsg	psr,%0		\n"	\
+		     "	andi	%0,%2,%0	\n"	\
+		     "	ori	%0,%1,%0	\n"	\
+		     "	movgs	%0,psr		\n"	\
+		     : "=r"(psr)			\
+		     : "i" (PSR_PIL_14), "i" (~PSR_PIL)	\
+		     : "memory");			\
+} while(0)
+
+#define local_irq_enable()				\
+do {							\
+	unsigned long psr;				\
+	asm volatile("	movsg	psr,%0		\n"	\
+		     "	andi	%0,%1,%0	\n"	\
+		     "	movgs	%0,psr		\n"	\
+		     : "=r"(psr)			\
+		     : "i" (~PSR_PIL)			\
+		     : "memory");			\
+} while(0)
+
+#define local_save_flags(flags)			\
+do {						\
+	typecheck(unsigned long, flags);	\
+	asm("movsg psr,%0"			\
+	    : "=r"(flags)			\
+	    :					\
+	    : "memory");			\
+} while(0)
+
+#define	local_irq_save(flags)				\
+do {							\
+	unsigned long npsr;				\
+	typecheck(unsigned long, flags);		\
+	asm volatile("	movsg	psr,%0		\n"	\
+		     "	andi	%0,%3,%1	\n"	\
+		     "	ori	%1,%2,%1	\n"	\
+		     "	movgs	%1,psr		\n"	\
+		     : "=r"(flags), "=r"(npsr)		\
+		     : "i" (PSR_PIL_14), "i" (~PSR_PIL)	\
+		     : "memory");			\
+} while(0)
+
+#define	local_irq_restore(flags)			\
+do {							\
+	typecheck(unsigned long, flags);		\
+	asm volatile("	movgs	%0,psr		\n"	\
+		     :					\
+		     : "r" (flags)			\
+		     : "memory");			\
+} while(0)
+
+#define irqs_disabled() \
+	((__get_PSR() & PSR_PIL) >= PSR_PIL_14)
+
+/*
+ * Force strict CPU ordering.
+ */
+#define nop()			asm volatile ("nop"::)
+#define mb()			asm volatile ("membar" : : :"memory")
+#define rmb()			asm volatile ("membar" : : :"memory")
+#define wmb()			asm volatile ("membar" : : :"memory")
+#define set_mb(var, value)	do { var = value; mb(); } while (0)
+#define set_wmb(var, value)	do { var = value; wmb(); } while (0)
+
+#define smp_mb()		mb()
+#define smp_rmb()		rmb()
+#define smp_wmb()		wmb()
+
+#define read_barrier_depends()		do {} while(0)
+#define smp_read_barrier_depends()	read_barrier_depends()
+
+#define HARD_RESET_NOW()			\
+do {						\
+	cli();					\
+} while(1)
+
+extern void die_if_kernel(const char *, ...) __attribute__((format(printf, 1, 2)));
+extern void free_initmem(void);
+
+#endif /* _ASM_SYSTEM_H */
diff -Nru a/include/asm-frv/termbits.h b/include/asm-frv/termbits.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/termbits.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,177 @@
+#ifndef _ASM_TERMBITS_H__
+#define _ASM_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 CTVB	  004000000000		/* VisioBraille Terminal flow control */
+#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 /* _ASM_TERMBITS_H__ */
+
diff -Nru a/include/asm-frv/termios.h b/include/asm-frv/termios.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/termios.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,74 @@
+#ifndef _ASM_TERMIOS_H
+#define _ASM_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 */
+};
+
+#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"
+#endif
+
+/* 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
+
+#define TIOCM_MODEM_BITS       TIOCM_OUT2      /* IRDA support */
+
+/* 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 IrDa - 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 */
+
+#include <asm-generic/termios.h>
+
+#endif /* _ASM_TERMIOS_H */
diff -Nru a/include/asm-frv/thread_info.h b/include/asm-frv/thread_info.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/thread_info.h	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,159 @@
+/* thread_info.h: description
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ * Derived from include/asm-i386/thread_info.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 _ASM_THREAD_INFO_H
+#define _ASM_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:
+					 	   0-0xBFFFFFFF for user-thead
+						   0-0xFFFFFFFF for kernel-thread
+						*/
+	struct restart_block    restart_block;
+
+	__u8			supervisor_stack[0];
+};
+
+#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	0x0000001C
+
+#endif
+
+#define PREEMPT_ACTIVE		0x4000000
+
+/*
+ * 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)
+
+#ifdef CONFIG_SMALL_TASKS
+#define THREAD_SIZE		4096
+#else
+#define THREAD_SIZE		8192
+#endif
+
+/* how to get the thread information struct from C */
+register struct thread_info *__current_thread_info asm("gr15");
+
+#define current_thread_info() ({ __current_thread_info; })
+
+/* thread information allocation */
+#ifdef CONFIG_DEBUG_STACK_USAGE
+#define alloc_thread_info(tsk)					\
+	({							\
+		struct thread_info *ret;			\
+								\
+		ret = kmalloc(THREAD_SIZE, GFP_KERNEL);		\
+		if (ret)					\
+			memset(ret, 0, THREAD_SIZE);		\
+		ret;						\
+	})
+#else
+#define alloc_thread_info(tsk)	kmalloc(THREAD_SIZE, GFP_KERNEL)
+#endif
+
+#define free_thread_info(info)	kfree(info)
+#define get_thread_info(ti)	get_task_struct((ti)->task)
+#define put_thread_info(ti)	put_task_struct((ti)->task)
+
+#else /* !__ASSEMBLY__ */
+
+#define THREAD_SIZE	8192
+
+#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_POLLING_NRFLAG	16	/* true if poll_idle() is polling TIF_NEED_RESCHED */
+#define TIF_MEMDIE		17	/* OOM killer killed process */
+
+#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_USEDFPM		0x0001	/* FPU/Media was used by this task this quantum (SMP) */
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_THREAD_INFO_H */
diff -Nru a/include/asm-frv/timer-regs.h b/include/asm-frv/timer-regs.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/timer-regs.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,106 @@
+/* timer-regs.h: hardware timer register definitions
+ *
+ * Copyright (C) 2003 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.
+ */
+
+#ifndef _ASM_TIMER_REGS_H
+#define _ASM_TIMER_REGS_H
+
+#include <asm/sections.h>
+
+extern unsigned long __nongprelbss __clkin_clock_speed_HZ;
+extern unsigned long __nongprelbss __ext_bus_clock_speed_HZ;
+extern unsigned long __nongprelbss __res_bus_clock_speed_HZ;
+extern unsigned long __nongprelbss __sdram_clock_speed_HZ;
+extern unsigned long __nongprelbss __core_bus_clock_speed_HZ;
+extern unsigned long __nongprelbss __core_clock_speed_HZ;
+extern unsigned long __nongprelbss __dsu_clock_speed_HZ;
+extern unsigned long __nongprelbss __serial_clock_speed_HZ;
+
+#define __get_CLKC()	({ *(volatile unsigned long *)(0xfeff9a00); })
+
+static inline void __set_CLKC(unsigned long v)
+{
+	int tmp;
+
+	asm volatile("	st%I0.p	%2,%M0		\n"
+		     "	setlos	%3,%1		\n"
+		     "	membar			\n"
+		     "0:			\n"
+		     "	subicc	%1,#1,%1,icc0	\n"
+		     "	bnc	icc0,#1,0b	\n"
+		     : "=m"(*(volatile unsigned long *) 0xfeff9a00), "=r"(tmp)
+		     : "r"(v), "i"(256)
+		     : "icc0");
+}
+
+#define __get_TCTR()	({ *(volatile unsigned long *)(0xfeff9418); })
+#define __get_TPRV()	({ *(volatile unsigned long *)(0xfeff9420); })
+#define __get_TPRCKSL()	({ *(volatile unsigned long *)(0xfeff9428); })
+#define __get_TCSR(T)	({ *(volatile unsigned long *)(0xfeff9400 + 8 * (T)); })
+#define __get_TxCKSL(T)	({ *(volatile unsigned long *)(0xfeff9430 + 8 * (T)); })
+
+#define __get_TCSR_DATA(T) ({ __get_TCSR(T) >> 24; })
+
+#define __set_TCTR(V)	do { *(volatile unsigned long *)(0xfeff9418) = (V); mb(); } while(0)
+#define __set_TPRV(V)	do { *(volatile unsigned long *)(0xfeff9420) = (V) << 24; mb(); } while(0)
+#define __set_TPRCKSL(V) do { *(volatile unsigned long *)(0xfeff9428) = (V); mb(); } while(0)
+#define __set_TCSR(T,V)	\
+do { *(volatile unsigned long *)(0xfeff9400 + 8 * (T)) = (V); mb(); } while(0)
+
+#define __set_TxCKSL(T,V) \
+do { *(volatile unsigned long *)(0xfeff9430 + 8 * (T)) = (V); mb(); } while(0)
+
+#define __set_TCSR_DATA(T,V) __set_TCSR(T, (V) << 24)
+#define __set_TxCKSL_DATA(T,V) __set_TxCKSL(T, TxCKSL_EIGHT | __TxCKSL_SELECT((V)))
+
+/* clock control register */
+#define CLKC_CMODE		0x0f000000
+#define CLKC_SLPL		0x000f0000
+#define CLKC_P0			0x00000100
+#define CLKC_CM			0x00000003
+
+#define CLKC_CMODE_s		24
+
+/* timer control register - non-readback mode */
+#define TCTR_MODE_0		0x00000000
+#define TCTR_MODE_2		0x04000000
+#define TCTR_MODE_4		0x08000000
+#define TCTR_MODE_5		0x0a000000
+#define TCTR_RL_LATCH		0x00000000
+#define TCTR_RL_RW_LOW8		0x10000000
+#define TCTR_RL_RW_HIGH8	0x20000000
+#define TCTR_RL_RW_LH8		0x30000000
+#define TCTR_SC_CTR0		0x00000000
+#define TCTR_SC_CTR1		0x40000000
+#define TCTR_SC_CTR2		0x80000000
+
+/* timer control register - readback mode */
+#define TCTR_CNT0		0x02000000
+#define TCTR_CNT1		0x04000000
+#define TCTR_CNT2		0x08000000
+#define TCTR_NSTATUS		0x10000000
+#define TCTR_NCOUNT		0x20000000
+#define TCTR_SC_READBACK	0xc0000000
+
+/* timer control status registers - non-readback mode */
+#define TCSRx_DATA		0xff000000
+
+/* timer control status registers - readback mode */
+#define TCSRx_OUTPUT		0x80000000
+#define TCSRx_NULLCOUNT		0x40000000
+#define TCSRx_RL		0x30000000
+#define TCSRx_MODE		0x07000000
+
+/* timer clock select registers */
+#define TxCKSL_SELECT		0x0f000000
+#define __TxCKSL_SELECT(X)	((X) << 24)
+#define TxCKSL_EIGHT		0xf0000000
+
+#endif /* _ASM_TIMER_REGS_H */
diff -Nru a/include/asm-frv/timex.h b/include/asm-frv/timex.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/timex.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,25 @@
+/* timex.h: FR-V architecture timex specifications
+ */
+#ifndef _ASM_TIMEX_H
+#define _ASM_TIMEX_H
+
+#define CLOCK_TICK_RATE		1193180 /* Underlying HZ */
+#define CLOCK_TICK_FACTOR	20	/* Factor of both 1000000 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)
+
+typedef unsigned long cycles_t;
+
+static inline cycles_t get_cycles(void)
+{
+	return 0;
+}
+
+#define vxtime_lock()		do {} while (0)
+#define vxtime_unlock()		do {} while (0)
+
+#endif
+
diff -Nru a/include/asm-frv/tlb.h b/include/asm-frv/tlb.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/tlb.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,23 @@
+#ifndef _ASM_TLB_H
+#define _ASM_TLB_H
+
+#include <asm/tlbflush.h>
+
+#define check_pgt_cache() do {} while(0)
+
+/*
+ * we don't need any special per-pte or per-vma handling...
+ */
+#define tlb_start_vma(tlb, vma)				do { } while (0)
+#define tlb_end_vma(tlb, vma)				do { } while (0)
+#define __tlb_remove_tlb_entry(tlb, ptep, address)	do { } while (0)
+
+/*
+ * .. because we flush the whole mm when it fills up
+ */
+#define tlb_flush(tlb)		flush_tlb_mm((tlb)->mm)
+
+#include <asm-generic/tlb.h>
+
+#endif /* _ASM_TLB_H */
+
diff -Nru a/include/asm-frv/tlbflush.h b/include/asm-frv/tlbflush.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/tlbflush.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,76 @@
+/* tlbflush.h: TLB flushing functions
+ *
+ * Copyright (C) 2004 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.
+ */
+
+#ifndef _ASM_TLBFLUSH_H
+#define _ASM_TLBFLUSH_H
+
+#include <linux/config.h>
+#include <linux/mm.h>
+#include <asm/processor.h>
+
+#ifdef CONFIG_MMU
+
+#ifndef __ASSEMBLY__
+extern void asmlinkage __flush_tlb_all(void);
+extern void asmlinkage __flush_tlb_mm(unsigned long contextid);
+extern void asmlinkage __flush_tlb_page(unsigned long contextid, unsigned long start);
+extern void asmlinkage __flush_tlb_range(unsigned long contextid,
+					 unsigned long start, unsigned long end);
+#endif /* !__ASSEMBLY__ */
+
+#define flush_tlb_all()				\
+do {						\
+	preempt_disable();			\
+	__flush_tlb_all();			\
+	preempt_enable();			\
+} while(0)
+
+#define flush_tlb_mm(mm)			\
+do {						\
+	preempt_disable();			\
+	__flush_tlb_mm((mm)->context.id);	\
+	preempt_enable();			\
+} while(0)
+
+#define flush_tlb_range(vma,start,end)					\
+do {									\
+	preempt_disable();						\
+	__flush_tlb_range((vma)->vm_mm->context.id, start, end);	\
+	preempt_enable();						\
+} while(0)
+
+#define flush_tlb_page(vma,addr)				\
+do {								\
+	preempt_disable();					\
+	__flush_tlb_page((vma)->vm_mm->context.id, addr);	\
+	preempt_enable();					\
+} while(0)
+
+
+#define __flush_tlb_global()			flush_tlb_all()
+#define flush_tlb()				flush_tlb_all()
+#define flush_tlb_kernel_range(start, end)	flush_tlb_all()
+#define flush_tlb_pgtables(mm,start,end)	asm volatile("movgs gr0,scr0 ! movgs gr0,scr1");
+
+#else
+
+#define flush_tlb()				BUG()
+#define flush_tlb_all()				BUG()
+#define flush_tlb_mm(mm)			BUG()
+#define flush_tlb_page(vma,addr)		BUG()
+#define flush_tlb_range(mm,start,end)		BUG()
+#define flush_tlb_pgtables(mm,start,end)	BUG()
+#define flush_tlb_kernel_range(start, end)	BUG()
+
+#endif
+
+
+#endif /* _ASM_TLBFLUSH_H */
diff -Nru a/include/asm-frv/topology.h b/include/asm-frv/topology.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/topology.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,14 @@
+#ifndef _ASM_TOPOLOGY_H
+#define _ASM_TOPOLOGY_H
+
+#ifdef CONFIG_NUMA
+
+#error NUMA not supported yet
+
+#else /* !CONFIG_NUMA */
+
+#include <asm-generic/topology.h>
+
+#endif /* CONFIG_NUMA */
+
+#endif /* _ASM_TOPOLOGY_H */
diff -Nru a/include/asm-frv/types.h b/include/asm-frv/types.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/types.h	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,74 @@
+/* types.h: FRV types
+ *
+ * Copyright (C) 2004 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.
+ */
+
+#ifndef _ASM_TYPES_H
+#define _ASM_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
+
+#endif /* __ASSEMBLY__ */
+
+/*
+ * These aren't exported outside the kernel to avoid name space clashes
+ */
+#ifdef __KERNEL__
+
+#define BITS_PER_LONG 32
+
+#ifndef __ASSEMBLY__
+
+#include <linux/config.h>
+
+typedef signed char s8;
+typedef unsigned char u8;
+
+typedef signed short s16;
+typedef unsigned short u16;
+
+typedef signed int s32;
+typedef unsigned int u32;
+
+typedef signed long long s64;
+typedef unsigned long long u64;
+typedef u64 u_quad_t;
+
+/* Dma addresses are 32-bits wide.  */
+
+typedef u32 dma_addr_t;
+
+typedef unsigned short kmem_bufctl_t;
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_TYPES_H */
diff -Nru a/include/asm-frv/uaccess.h b/include/asm-frv/uaccess.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/uaccess.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,317 @@
+/* uaccess.h: userspace accessor functions
+ *
+ * Copyright (C) 2004 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.
+ */
+
+#ifndef _ASM_UACCESS_H
+#define _ASM_UACCESS_H
+
+/*
+ * User space memory access functions
+ */
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <asm/segment.h>
+#include <asm/sections.h>
+
+#define HAVE_ARCH_UNMAPPED_AREA	/* we decide where to put mmaps */
+
+#define __ptr(x) ((unsigned long *)(x))
+
+#define VERIFY_READ	0
+#define VERIFY_WRITE	1
+
+#define __addr_ok(addr) ((unsigned long)(addr) < get_addr_limit())
+
+/*
+ * check that a range of addresses falls within the current address limit
+ */
+static inline int ___range_ok(unsigned long addr, unsigned long size)
+{
+#ifdef CONFIG_MMU
+	int flag = -EFAULT, tmp;
+
+	asm volatile (
+		"	addcc	%3,%2,%1,icc0	\n"	/* set C-flag if addr+size>4GB */
+		"	subcc.p	%1,%4,gr0,icc1	\n"	/* jump if addr+size>limit */
+		"	bc	icc0,#0,0f	\n"
+		"	bhi	icc1,#0,0f	\n"
+		"	setlos	#0,%0		\n"	/* mark okay */
+		"0:				\n"
+		: "=r"(flag), "=&r"(tmp)
+		: "r"(addr), "r"(size), "r"(get_addr_limit()), "0"(flag)
+		);
+
+	return flag;
+
+#else
+
+	if (addr < memory_start ||
+	    addr > memory_end ||
+	    size > memory_end - memory_start ||
+	    addr + size > memory_end)
+		return -EFAULT;
+
+	return 0;
+#endif
+}
+
+#define __range_ok(addr,size) ___range_ok((unsigned long) (addr), (unsigned long) (size))
+
+#define access_ok(type,addr,size) (__range_ok((addr), (size)) == 0)
+#define __access_ok(addr,size) (__range_ok((addr), (size)) == 0)
+
+static inline int verify_area(int type, const void * addr, unsigned long size)
+{
+	return __range_ok(addr, size);
+}
+
+/*
+ * The exception table consists of pairs of addresses: the first is the
+ * address of an instruction that is allowed to fault, and the second is
+ * the address at which the program should continue.  No registers are
+ * modified, so it is entirely up to the continuation code to figure out
+ * what to do.
+ *
+ * All the routines below use bits of fixup code that are out of line
+ * with the main instruction path.  This means when everything is well,
+ * we don't even have to jump over them.  Further, they do not intrude
+ * on our cache or tlb entries.
+ */
+struct exception_table_entry
+{
+	unsigned long insn, fixup;
+};
+
+/* Returns 0 if exception not found and fixup otherwise.  */
+extern unsigned long search_exception_table(unsigned long);
+
+
+/*
+ * These are the main single-value transfer routines.  They automatically
+ * use the right size if we just have the right pointer type.
+ */
+#define __put_user(x, ptr)						\
+({									\
+	int __pu_err = 0;						\
+									\
+	typeof(*(ptr)) __pu_val = (x);					\
+									\
+	switch (sizeof (*(ptr))) {					\
+	case 1:								\
+		__put_user_asm(__pu_err, __pu_val, ptr, "b", "r");	\
+		break;							\
+	case 2:								\
+		__put_user_asm(__pu_err, __pu_val, ptr, "h", "r");	\
+		break;							\
+	case 4:								\
+		__put_user_asm(__pu_err, __pu_val, ptr, "",  "r");	\
+		break;							\
+	case 8:								\
+		__put_user_asm(__pu_err, __pu_val, ptr, "d", "e");	\
+		break;							\
+	default:							\
+		__pu_err = __put_user_bad();				\
+		break;							\
+	}								\
+	__pu_err;							\
+})
+
+#define put_user(x, ptr)			\
+({						\
+	typeof(&*ptr) _p = (ptr);		\
+	int _e;					\
+						\
+	_e = __range_ok(_p, sizeof(*_p));	\
+	if (_e == 0)				\
+		_e = __put_user((x), _p);	\
+	_e;					\
+})
+
+extern int __put_user_bad(void);
+
+/*
+ * Tell gcc we read from memory instead of writing: this is because
+ * we do not write to any memory gcc knows about, so there are no
+ * aliasing issues.
+ */
+
+#ifdef CONFIG_MMU
+
+#define __put_user_asm(err,x,ptr,dsize,constraint)					\
+do {											\
+	asm volatile("1:	st"dsize"%I1	%2,%M1	\n"				\
+		     "2:				\n"				\
+		     ".subsection 2			\n"				\
+		     "3:	setlos		%3,%0	\n"				\
+		     "		bra		2b	\n"				\
+		     ".previous				\n"				\
+		     ".section __ex_table,\"a\"		\n"				\
+		     "		.balign		8	\n"				\
+		     "		.long		1b,3b	\n"				\
+		     ".previous"							\
+		     : "=r" (err)							\
+		     : "m" (*__ptr(ptr)), constraint (x), "i"(-EFAULT), "0"(err)	\
+		     : "memory");							\
+} while (0)
+
+#else
+
+#define __put_user_asm(err,x,ptr,bwl,con)	\
+do {						\
+	asm("	st"bwl"%I0	%1,%M0	\n"	\
+	    "	membar			\n"	\
+	    :					\
+	    : "m" (*__ptr(ptr)), con (x)	\
+	    : "memory");			\
+} while (0)
+
+#endif
+
+/*****************************************************************************/
+/*
+ *
+ */
+#define __get_user(x, ptr)						\
+({									\
+	typeof(*(ptr)) __gu_val = 0;					\
+	int __gu_err = 0;						\
+									\
+	switch (sizeof(*(ptr))) {					\
+	case 1:								\
+		__get_user_asm(__gu_err, __gu_val, ptr, "ub", "=r");	\
+		break;							\
+	case 2:								\
+		__get_user_asm(__gu_err, __gu_val, ptr, "uh", "=r");	\
+		break;							\
+	case 4:								\
+		__get_user_asm(__gu_err, __gu_val, ptr, "", "=r");	\
+		break;							\
+	case 8:								\
+		__get_user_asm(__gu_err, __gu_val, ptr, "d", "=e");	\
+		break;							\
+	default:							\
+		__gu_err = __get_user_bad();				\
+		break;							\
+	}								\
+	(x) = __gu_val;							\
+	__gu_err;							\
+})
+
+#define get_user(x, ptr)			\
+({						\
+	typeof(&*ptr) _p = (ptr);		\
+	int _e;					\
+						\
+	_e = __range_ok(_p, sizeof(*_p));	\
+	if (likely(_e == 0))			\
+		_e = __get_user((x), _p);	\
+	else					\
+		(x) = (typeof(x)) 0;		\
+	_e;					\
+})
+
+extern int __get_user_bad(void);
+
+#ifdef CONFIG_MMU
+
+#define __get_user_asm(err,x,ptr,dtype,constraint)	\
+do {							\
+	asm("1:		ld"dtype"%I2	%M2,%1	\n"	\
+	    "2:					\n"	\
+	    ".subsection 2			\n"	\
+	    "3:		setlos		%3,%0	\n"	\
+	    "		setlos		#0,%1	\n"	\
+	    "		bra		2b	\n"	\
+	    ".previous				\n"	\
+	    ".section __ex_table,\"a\"		\n"	\
+	    "		.balign		8	\n"	\
+	    "		.long		1b,3b	\n"	\
+	    ".previous"					\
+	    : "=r" (err), constraint (x)		\
+	    : "m" (*__ptr(ptr)), "i"(-EFAULT), "0"(err)	\
+	    );						\
+} while(0)
+
+#else
+
+#define __get_user_asm(err,x,ptr,bwl,con)	\
+	asm("	ld"bwl"%I1	%M1,%0	\n"	\
+	    "	membar			\n"	\
+	    : con(x)				\
+	    : "m" (*__ptr(ptr)))
+
+#endif
+
+/*****************************************************************************/
+/*
+ *
+ */
+#ifdef CONFIG_MMU
+extern long __memset_user(void *dst, unsigned long count);
+extern long __memcpy_user(void *dst, const void *src, unsigned long count);
+
+#define clear_user(dst,count)			__memset_user((dst), (count))
+#define __copy_from_user_inatomic(to, from, n)	__memcpy_user((to), (from), (n))
+#define __copy_to_user_inatomic(to, from, n)	__memcpy_user((to), (from), (n))
+
+#else
+
+#define clear_user(dst,count)			(memset((dst), 0, (count)), 0)
+#define __copy_from_user_inatomic(to, from, n)	(memcpy((to), (from), (n)), 0)
+#define __copy_to_user_inatomic(to, from, n)	(memcpy((to), (from), (n)), 0)
+
+#endif
+
+static inline unsigned long __must_check
+__copy_to_user(void __user *to, const void *from, unsigned long n)
+{
+       might_sleep();
+       return __copy_to_user_inatomic(to, from, n);
+}
+
+static inline unsigned long
+__copy_from_user(void *to, const void __user *from, unsigned long n)
+{
+       might_sleep();
+       return __copy_from_user_inatomic(to, from, n);
+}
+
+static inline long copy_from_user(void *to, const void *from, unsigned long n)
+{
+	unsigned long ret = n;
+
+	if (likely(__access_ok(from, n)))
+		ret = __copy_from_user(to, from, n);
+
+	if (unlikely(ret != 0))
+		memset(to + (n - ret), 0, ret);
+
+	return ret;
+}
+
+static inline long copy_to_user(void *to, const void *from, unsigned long n)
+{
+	return likely(__access_ok(to, n)) ? __copy_to_user(to, from, n) : n;
+}
+
+#define copy_to_user_ret(to,from,n,retval)	({ if (copy_to_user(to,from,n)) return retval; })
+#define copy_from_user_ret(to,from,n,retval)	({ if (copy_from_user(to,from,n)) return retval; })
+
+extern long strncpy_from_user(char *dst, const char *src, long count);
+extern long strnlen_user(const char *src, long count);
+
+#define strlen_user(str) strnlen_user(str, 32767)
+
+extern unsigned long search_exception_table(unsigned long addr);
+
+#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 /* _ASM_UACCESS_H */
diff -Nru a/include/asm-frv/ucontext.h b/include/asm-frv/ucontext.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/ucontext.h	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,12 @@
+#ifndef _ASM_UCONTEXT_H
+#define _ASM_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
diff -Nru a/include/asm-frv/unaligned.h b/include/asm-frv/unaligned.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/unaligned.h	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,203 @@
+/* unaligned.h: unaligned access handler
+ *
+ * Copyright (C) 2004 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.
+ */
+
+#ifndef _ASM_UNALIGNED_H
+#define _ASM_UNALIGNED_H
+
+#include <linux/config.h>
+
+/*
+ * Unaligned accesses on uClinux can't be performed in a fault handler - the
+ * CPU detects them as imprecise exceptions making this impossible.
+ *
+ * With the FR451, however, they are precise, and so we used to fix them up in
+ * the memory access fault handler.  However, instruction bundling make this
+ * impractical.  So, now we fall back to using memcpy.
+ */
+#ifdef CONFIG_MMU
+
+/*
+ * The asm statement in the macros below is a way to get GCC to copy a
+ * value from one variable to another without having any clue it's
+ * actually doing so, so that it won't have any idea that the values
+ * in the two variables are related.
+ */
+
+#define get_unaligned(ptr) ({				\
+	typeof((*(ptr))) __x;				\
+	void *__ptrcopy;				\
+	asm("" : "=r" (__ptrcopy) : "0" (ptr));		\
+	memcpy(&__x, __ptrcopy, sizeof(*(ptr)));	\
+	__x;						\
+})
+
+#define put_unaligned(val, ptr) ({			\
+	typeof((*(ptr))) __x = (val);			\
+	void *__ptrcopy;				\
+	asm("" : "=r" (__ptrcopy) : "0" (ptr));		\
+	memcpy(__ptrcopy, &__x, sizeof(*(ptr)));	\
+})
+
+extern int handle_misalignment(unsigned long esr0, unsigned long ear0, unsigned long epcr0);
+
+#else
+
+#define get_unaligned(ptr)							\
+({										\
+	typeof(*(ptr)) x;							\
+	const char *__p = (const char *) (ptr);					\
+										\
+	switch (sizeof(x)) {							\
+	case 1:									\
+		x = *(ptr);							\
+		break;								\
+	case 2:									\
+	{									\
+		uint8_t a;							\
+		asm("	ldub%I2		%M2,%0		\n"			\
+		    "	ldub%I3.p	%M3,%1		\n"			\
+		    "	slli		%0,#8,%0	\n"			\
+		    "	or		%0,%1,%0	\n"			\
+		    : "=&r"(x), "=&r"(a)					\
+		    : "m"(__p[0]),  "m"(__p[1])					\
+		    );								\
+		break;								\
+	}									\
+										\
+	case 4:									\
+	{									\
+		uint8_t a;							\
+		asm("	ldub%I2		%M2,%0		\n"			\
+		    "	ldub%I3.p	%M3,%1		\n"			\
+		    "	slli		%0,#8,%0	\n"			\
+		    "	or		%0,%1,%0	\n"			\
+		    "	ldub%I4.p	%M4,%1		\n"			\
+		    "	slli		%0,#8,%0	\n"			\
+		    "	or		%0,%1,%0	\n"			\
+		    "	ldub%I5.p	%M5,%1		\n"			\
+		    "	slli		%0,#8,%0	\n"			\
+		    "	or		%0,%1,%0	\n"			\
+		    : "=&r"(x), "=&r"(a)					\
+		    : "m"(__p[0]),  "m"(__p[1]), "m"(__p[2]), "m"(__p[3])	\
+		    );								\
+		break;								\
+	}									\
+										\
+	case 8:									\
+	{									\
+		union { uint64_t x; u32 y[2]; } z;				\
+		uint8_t a;							\
+		asm("	ldub%I3		%M3,%0		\n"			\
+		    "	ldub%I4.p	%M4,%2		\n"			\
+		    "	slli		%0,#8,%0	\n"			\
+		    "	or		%0,%2,%0	\n"			\
+		    "	ldub%I5.p	%M5,%2		\n"			\
+		    "	slli		%0,#8,%0	\n"			\
+		    "	or		%0,%2,%0	\n"			\
+		    "	ldub%I6.p	%M6,%2		\n"			\
+		    "	slli		%0,#8,%0	\n"			\
+		    "	or		%0,%2,%0	\n"			\
+		    "	ldub%I7		%M7,%1		\n"			\
+		    "	ldub%I8.p	%M8,%2		\n"			\
+		    "	slli		%1,#8,%1	\n"			\
+		    "	or		%1,%2,%1	\n"			\
+		    "	ldub%I9.p	%M9,%2		\n"			\
+		    "	slli		%1,#8,%1	\n"			\
+		    "	or		%1,%2,%1	\n"			\
+		    "	ldub%I10.p	%M10,%2		\n"			\
+		    "	slli		%1,#8,%1	\n"			\
+		    "	or		%1,%2,%1	\n"			\
+		    : "=&r"(z.y[0]), "=&r"(z.y[1]), "=&r"(a)			\
+		    : "m"(__p[0]), "m"(__p[1]), "m"(__p[2]), "m"(__p[3]),	\
+		      "m"(__p[4]), "m"(__p[5]), "m"(__p[6]), "m"(__p[7])	\
+		    );								\
+		x = z.x;							\
+		break;								\
+	}									\
+										\
+	default:								\
+		x = 0;								\
+		BUG();								\
+		break;								\
+	}									\
+										\
+	x;									\
+})
+
+#define put_unaligned(val, ptr)								\
+do {											\
+	char *__p = (char *) (ptr);							\
+	int x;										\
+											\
+	switch (sizeof(*ptr)) {								\
+	case 2:										\
+	{										\
+		asm("	stb%I1.p	%0,%M1		\n"				\
+		    "	srli		%0,#8,%0	\n"				\
+		    "	stb%I2		%0,%M2		\n"				\
+		    : "=r"(x), "=m"(__p[1]),  "=m"(__p[0])				\
+		    : "0"(val)								\
+		    );									\
+		break;									\
+	}										\
+											\
+	case 4:										\
+	{										\
+		asm("	stb%I1.p	%0,%M1		\n"				\
+		    "	srli		%0,#8,%0	\n"				\
+		    "	stb%I2.p	%0,%M2		\n"				\
+		    "	srli		%0,#8,%0	\n"				\
+		    "	stb%I3.p	%0,%M3		\n"				\
+		    "	srli		%0,#8,%0	\n"				\
+		    "	stb%I4		%0,%M4		\n"				\
+		    : "=r"(x), "=m"(__p[3]),  "=m"(__p[2]), "=m"(__p[1]), "=m"(__p[0])	\
+		    : "0"(val)								\
+		    );									\
+		break;									\
+	}										\
+											\
+	case 8:										\
+	{										\
+		uint32_t __high, __low;							\
+		__high = (uint64_t)val >> 32;						\
+		__low = val & 0xffffffff;						\
+		asm("	stb%I2.p	%0,%M2		\n"				\
+		    "	srli		%0,#8,%0	\n"				\
+		    "	stb%I3.p	%0,%M3		\n"				\
+		    "	srli		%0,#8,%0	\n"				\
+		    "	stb%I4.p	%0,%M4		\n"				\
+		    "	srli		%0,#8,%0	\n"				\
+		    "	stb%I5.p	%0,%M5		\n"				\
+		    "	srli		%0,#8,%0	\n"				\
+		    "	stb%I6.p	%1,%M6		\n"				\
+		    "	srli		%1,#8,%1	\n"				\
+		    "	stb%I7.p	%1,%M7		\n"				\
+		    "	srli		%1,#8,%1	\n"				\
+		    "	stb%I8.p	%1,%M8		\n"				\
+		    "	srli		%1,#8,%1	\n"				\
+		    "	stb%I9		%1,%M9		\n"				\
+		    : "=&r"(__low), "=&r"(__high), "=m"(__p[7]), "=m"(__p[6]), 		\
+		      "=m"(__p[5]), "=m"(__p[4]), "=m"(__p[3]), "=m"(__p[2]), 		\
+		      "=m"(__p[1]), "=m"(__p[0])					\
+		    : "0"(__low), "1"(__high)						\
+		    );									\
+		break;									\
+	}										\
+											\
+        default:									\
+		*(ptr) = (val);								\
+		break;									\
+	}										\
+} while(0)
+
+#endif
+
+#endif
diff -Nru a/include/asm-frv/unistd.h b/include/asm-frv/unistd.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/unistd.h	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,501 @@
+#ifndef _ASM_UNISTD_H_
+#define _ASM_UNISTD_H_
+
+/*
+ * This file contains the system call numbers.
+ */
+
+#define __NR_restart_syscall      0
+#define __NR_exit		  1
+#define __NR_fork		  2
+#define __NR_read		  3
+#define __NR_write		  4
+#define __NR_open		  5
+#define __NR_close		  6
+#define __NR_waitpid		  7
+#define __NR_creat		  8
+#define __NR_link		  9
+#define __NR_unlink		 10
+#define __NR_execve		 11
+#define __NR_chdir		 12
+#define __NR_time		 13
+#define __NR_mknod		 14
+#define __NR_chmod		 15
+#define __NR_lchown		 16
+#define __NR_break		 17
+#define __NR_oldstat		 18
+#define __NR_lseek		 19
+#define __NR_getpid		 20
+#define __NR_mount		 21
+#define __NR_umount		 22
+#define __NR_setuid		 23
+#define __NR_getuid		 24
+#define __NR_stime		 25
+#define __NR_ptrace		 26
+#define __NR_alarm		 27
+#define __NR_oldfstat		 28
+#define __NR_pause		 29
+#define __NR_utime		 30
+#define __NR_stty		 31
+#define __NR_gtty		 32
+#define __NR_access		 33
+#define __NR_nice		 34
+#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_umount2		 52
+#define __NR_lock		 53
+#define __NR_ioctl		 54
+#define __NR_fcntl		 55
+#define __NR_mpx		 56
+#define __NR_setpgid		 57
+#define __NR_ulimit		 58
+// #define __NR_oldolduname	 /* 59 */ obsolete
+#define __NR_umask		 60
+#define __NR_chroot		 61
+#define __NR_ustat		 62
+#define __NR_dup2		 63
+#define __NR_getppid		 64
+#define __NR_getpgrp		 65
+#define __NR_setsid		 66
+#define __NR_sigaction		 67
+#define __NR_sgetmask		 68
+#define __NR_ssetmask		 69
+#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_oldlstat		 84
+#define __NR_readlink		 85
+#define __NR_uselib		 86
+#define __NR_swapon		 87
+#define __NR_reboot		 88
+#define __NR_readdir		 89
+// #define __NR_mmap		 90	/* obsolete - not implemented */
+#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 */ obsolete
+#define __NR_statfs		 99
+#define __NR_fstatfs		100
+// #define __NR_ioperm		/* 101 */ not supported
+#define __NR_socketcall		102
+#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_olduname		/* 109 */ obsolete
+// #define __NR_iopl		/* 110 */ not supported
+#define __NR_vhangup		111
+// #define __NR_idle		/* 112 */ Obsolete
+// #define __NR_vm86old		/* 113 */ not supported
+#define __NR_wait4		114
+#define __NR_swapoff		115
+#define __NR_sysinfo		116
+#define __NR_ipc		117
+#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 */ not supported
+#define __NR_cacheflush		123
+#define __NR_adjtimex		124
+#define __NR_mprotect		125
+#define __NR_sigprocmask	126
+#define __NR_create_module	127
+#define __NR_init_module	128
+#define __NR_delete_module	129
+#define __NR_get_kernel_syms	130
+#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_afs_syscall	137 /* Syscall for Andrew File System */
+#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_getsid		147
+#define __NR_fdatasync		148
+#define __NR__sysctl		149
+#define __NR_mlock		150
+#define __NR_munlock		151
+#define __NR_mlockall		152
+#define __NR_munlockall		153
+#define __NR_sched_setparam		154
+#define __NR_sched_getparam		155
+#define __NR_sched_setscheduler		156
+#define __NR_sched_getscheduler		157
+#define __NR_sched_yield		158
+#define __NR_sched_get_priority_max	159
+#define __NR_sched_get_priority_min	160
+#define __NR_sched_rr_get_interval	161
+#define __NR_nanosleep		162
+#define __NR_mremap		163
+#define __NR_setresuid		164
+#define __NR_getresuid		165
+// #define __NR_vm86		/* 166 */ not supported
+#define __NR_query_module	167
+#define __NR_poll		168
+#define __NR_nfsservctl		169
+#define __NR_setresgid		170
+#define __NR_getresgid		171
+#define __NR_prctl		172
+#define __NR_rt_sigreturn	173
+#define __NR_rt_sigaction	174
+#define __NR_rt_sigprocmask	175
+#define __NR_rt_sigpending	176
+#define __NR_rt_sigtimedwait	177
+#define __NR_rt_sigqueueinfo	178
+#define __NR_rt_sigsuspend	179
+#define __NR_pread		180
+#define __NR_pwrite		181
+#define __NR_chown		182
+#define __NR_getcwd		183
+#define __NR_capget		184
+#define __NR_capset		185
+#define __NR_sigaltstack	186
+#define __NR_sendfile		187
+#define __NR_getpmsg		188	/* some people actually want streams */
+#define __NR_putpmsg		189	/* some people actually want streams */
+#define __NR_vfork		190
+#define __NR_ugetrlimit		191	/* SuS compliant getrlimit */
+#define __NR_mmap2		192
+#define __NR_truncate64		193
+#define __NR_ftruncate64	194
+#define __NR_stat64		195
+#define __NR_lstat64		196
+#define __NR_fstat64		197
+#define __NR_lchown32		198
+#define __NR_getuid32		199
+#define __NR_getgid32		200
+#define __NR_geteuid32		201
+#define __NR_getegid32		202
+#define __NR_setreuid32		203
+#define __NR_setregid32		204
+#define __NR_getgroups32	205
+#define __NR_setgroups32	206
+#define __NR_fchown32		207
+#define __NR_setresuid32	208
+#define __NR_getresuid32	209
+#define __NR_setresgid32	210
+#define __NR_getresgid32	211
+#define __NR_chown32		212
+#define __NR_setuid32		213
+#define __NR_setgid32		214
+#define __NR_setfsuid32		215
+#define __NR_setfsgid32		216
+#define __NR_pivot_root		217
+#define __NR_mincore		218
+#define __NR_madvise		219
+
+#define __NR_getdents64		220
+#define __NR_fcntl64		221
+#define __NR_security		223	/* syscall for security modules */
+#define __NR_gettid		224
+#define __NR_readahead		225
+#define __NR_setxattr		226
+#define __NR_lsetxattr		227
+#define __NR_fsetxattr		228
+#define __NR_getxattr		229
+#define __NR_lgetxattr		230
+#define __NR_fgetxattr		231
+#define __NR_listxattr		232
+#define __NR_llistxattr		233
+#define __NR_flistxattr		234
+#define __NR_removexattr	235
+#define __NR_lremovexattr	236
+#define __NR_fremovexattr	237
+#define __NR_tkill		238
+#define __NR_sendfile64		239
+#define __NR_futex		240
+#define __NR_sched_setaffinity	241
+#define __NR_sched_getaffinity	242
+#define __NR_set_thread_area	243
+#define __NR_get_thread_area	244
+#define __NR_io_setup		245
+#define __NR_io_destroy		246
+#define __NR_io_getevents	247
+#define __NR_io_submit		248
+#define __NR_io_cancel		249
+#define __NR_fadvise64		250
+
+#define __NR_exit_group		252
+#define __NR_lookup_dcookie	253
+#define __NR_epoll_create	254
+#define __NR_epoll_ctl		255
+#define __NR_epoll_wait		256
+#define __NR_remap_file_pages	257
+#define __NR_set_tid_address	258
+#define __NR_timer_create	259
+#define __NR_timer_settime	(__NR_timer_create+1)
+#define __NR_timer_gettime	(__NR_timer_create+2)
+#define __NR_timer_getoverrun	(__NR_timer_create+3)
+#define __NR_timer_delete	(__NR_timer_create+4)
+#define __NR_clock_settime	(__NR_timer_create+5)
+#define __NR_clock_gettime	(__NR_timer_create+6)
+#define __NR_clock_getres	(__NR_timer_create+7)
+#define __NR_clock_nanosleep	(__NR_timer_create+8)
+#define __NR_statfs64		268
+#define __NR_fstatfs64		269
+#define __NR_tgkill		270
+#define __NR_utimes		271
+#define __NR_fadvise64_64	272
+#define __NR_vserver		273
+#define __NR_mbind		274
+#define __NR_get_mempolicy	275
+#define __NR_set_mempolicy	276
+#define __NR_mq_open 		277
+#define __NR_mq_unlink		(__NR_mq_open+1)
+#define __NR_mq_timedsend	(__NR_mq_open+2)
+#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_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_vperfctr_open	289
+#define __NR_vperfctr_control	(__NR_perfctr_info+1)
+#define __NR_vperfctr_unlink	(__NR_perfctr_info+2)
+#define __NR_vperfctr_iresume	(__NR_perfctr_info+3)
+#define __NR_vperfctr_read	(__NR_perfctr_info+4)
+
+#define NR_syscalls 294
+
+/*
+ * process the return value of a syscall, consigning it to one of two possible fates
+ * - user-visible error numbers are in the range -1 - -4095: see <asm-frv/errno.h>
+ */
+#undef __syscall_return
+#define __syscall_return(type, res)					\
+do {									\
+        unsigned long __sr2 = (res);					\
+	if (__builtin_expect(__sr2 >= (unsigned long)(-4095), 0)) {	\
+		errno = (-__sr2);					\
+		__sr2 = ULONG_MAX;					\
+	}								\
+	return (type) __sr2;						\
+} while (0)
+
+/* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */
+
+#undef _syscall0
+#define _syscall0(type,name)						\
+type name(void)								\
+{									\
+	register unsigned long __scnum __asm__ ("gr7") = (__NR_##name);	\
+	register unsigned long __sc0 __asm__ ("gr8");			\
+	__asm__ __volatile__ ("tira gr0,#0"				\
+			      : "=r" (__sc0)				\
+			      : "r" (__scnum));				\
+	__syscall_return(type, __sc0);					\
+}
+
+#undef _syscall1
+#define _syscall1(type,name,type1,arg1)						\
+type name(type1 arg1)								\
+{										\
+	register unsigned long __scnum __asm__ ("gr7") = (__NR_##name);		\
+	register unsigned long __sc0 __asm__ ("gr8") = (unsigned long) arg1;	\
+	__asm__ __volatile__ ("tira gr0,#0"					\
+			      : "+r" (__sc0)					\
+			      : "r" (__scnum));					\
+	__syscall_return(type, __sc0);						\
+}
+
+#undef _syscall2
+#define _syscall2(type,name,type1,arg1,type2,arg2)				\
+type name(type1 arg1,type2 arg2)						\
+{										\
+	register unsigned long __scnum __asm__ ("gr7") = (__NR_##name);		\
+	register unsigned long __sc0 __asm__ ("gr8") = (unsigned long) arg1;	\
+	register unsigned long __sc1 __asm__ ("gr9") = (unsigned long) arg2;	\
+	__asm__ __volatile__ ("tira gr0,#0"					\
+			      : "+r" (__sc0)					\
+			      : "r" (__scnum), "r" (__sc1));			\
+	__syscall_return(type, __sc0);						\
+}
+
+#undef _syscall3
+#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3)			\
+type name(type1 arg1,type2 arg2,type3 arg3)					\
+{										\
+	register unsigned long __scnum __asm__ ("gr7") = (__NR_##name);		\
+	register unsigned long __sc0 __asm__ ("gr8") = (unsigned long) arg1;	\
+	register unsigned long __sc1 __asm__ ("gr9") = (unsigned long) arg2;	\
+	register unsigned long __sc2 __asm__ ("gr10") = (unsigned long) arg3;	\
+	__asm__ __volatile__ ("tira gr0,#0"					\
+			      : "+r" (__sc0)					\
+			      : "r" (__scnum), "r" (__sc1), "r" (__sc2));	\
+	__syscall_return(type, __sc0);						\
+}
+
+#undef _syscall4
+#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4)		\
+type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4)				\
+{											\
+	register unsigned long __scnum __asm__ ("gr7") = (__NR_##name);			\
+	register unsigned long __sc0 __asm__ ("gr8") = (unsigned long) arg1;		\
+	register unsigned long __sc1 __asm__ ("gr9") = (unsigned long) arg2;		\
+	register unsigned long __sc2 __asm__ ("gr10") = (unsigned long) arg3;		\
+	register unsigned long __sc3 __asm__ ("gr11") = (unsigned long) arg4;		\
+	__asm__ __volatile__ ("tira gr0,#0"						\
+			      : "+r" (__sc0)						\
+			      : "r" (__scnum), "r" (__sc1), "r" (__sc2), "r" (__sc3));	\
+	__syscall_return(type, __sc0);							\
+}
+
+#undef _syscall5
+#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 unsigned long __scnum __asm__ ("gr7") = (__NR_##name);			\
+	register unsigned long __sc0 __asm__ ("gr8") = (unsigned long) arg1;		\
+	register unsigned long __sc1 __asm__ ("gr9") = (unsigned long) arg2;		\
+	register unsigned long __sc2 __asm__ ("gr10") = (unsigned long) arg3;		\
+	register unsigned long __sc3 __asm__ ("gr11") = (unsigned long) arg4;		\
+	register unsigned long __sc4 __asm__ ("gr12") = (unsigned long) arg5;		\
+	__asm__ __volatile__ ("tira gr0,#0"						\
+			      : "+r" (__sc0)						\
+			      : "r" (__scnum), "r" (__sc1), "r" (__sc2),		\
+			      "r" (__sc3), "r" (__sc4));				\
+	__syscall_return(type, __sc0);							\
+}
+
+#undef _syscall6
+#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 unsigned long __scnum __asm__ ("gr7") = (__NR_##name);				 \
+	register unsigned long __sc0 __asm__ ("gr8") = (unsigned long) arg1;			 \
+	register unsigned long __sc1 __asm__ ("gr9") = (unsigned long) arg2;			 \
+	register unsigned long __sc2 __asm__ ("gr10") = (unsigned long) arg3;			 \
+	register unsigned long __sc3 __asm__ ("gr11") = (unsigned long) arg4;			 \
+	register unsigned long __sc4 __asm__ ("gr12") = (unsigned long) arg5;			 \
+	register unsigned long __sc5 __asm__ ("gr13") = (unsigned long) arg6;			 \
+	__asm__ __volatile__ ("tira gr0,#0"							 \
+			      : "+r" (__sc0)							 \
+			      : "r" (__scnum), "r" (__sc1), "r" (__sc2),			 \
+			      "r" (__sc3), "r" (__sc4), "r" (__sc5));				 \
+	__syscall_return(type, __sc0);								 \
+}
+
+
+#ifdef __KERNEL_SYSCALLS__
+
+#include <linux/compiler.h>
+#include <linux/types.h>
+#include <linux/linkage.h>
+#include <asm/ptrace.h>
+
+/*
+ * we need this inline - forking from kernel space will result
+ * in NO COPY ON WRITE (!!!), until an execve is executed. This
+ * is no problem, but for the stack. This is handled by not letting
+ * main() use the stack at all after fork(). Thus, no function
+ * calls - which means inline code for fork too, as otherwise we
+ * would use the stack upon exit from 'fork()'.
+ *
+ * Actually only pause and fork are needed inline, so that there
+ * won't be any messing with the stack from main(), but we define
+ * some others too.
+ */
+#define __NR__exit __NR_exit
+static inline _syscall0(int,pause)
+static inline _syscall0(int,sync)
+static inline _syscall0(pid_t,setsid)
+static inline _syscall3(int,write,int,fd,const char *,buf,off_t,count)
+static inline _syscall3(int,read,int,fd,char *,buf,off_t,count)
+static inline _syscall3(off_t,lseek,int,fd,off_t,offset,int,count)
+static inline _syscall1(int,dup,int,fd)
+static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
+static inline _syscall3(int,open,const char *,file,int,flag,int,mode)
+static inline _syscall1(int,close,int,fd)
+static inline _syscall1(int,_exit,int,exitcode)
+static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
+static inline _syscall1(int,delete_module,const char *,name)
+
+static inline pid_t wait(int * wait_stat)
+{
+	return waitpid(-1,wait_stat,0);
+}
+
+#endif
+
+#ifdef __KERNEL__
+#define __ARCH_WANT_IPC_PARSE_VERSION
+/* #define __ARCH_WANT_OLD_READDIR */
+#define __ARCH_WANT_OLD_STAT
+#define __ARCH_WANT_STAT64
+#define __ARCH_WANT_SYS_ALARM
+/* #define __ARCH_WANT_SYS_GETHOSTNAME */
+#define __ARCH_WANT_SYS_PAUSE
+/* #define __ARCH_WANT_SYS_SGETMASK */
+/* #define __ARCH_WANT_SYS_SIGNAL */
+#define __ARCH_WANT_SYS_TIME
+#define __ARCH_WANT_SYS_UTIME
+#define __ARCH_WANT_SYS_WAITPID
+#define __ARCH_WANT_SYS_SOCKETCALL
+#define __ARCH_WANT_SYS_FADVISE64
+#define __ARCH_WANT_SYS_GETPGRP
+#define __ARCH_WANT_SYS_LLSEEK
+#define __ARCH_WANT_SYS_NICE
+/* #define __ARCH_WANT_SYS_OLD_GETRLIMIT */
+#define __ARCH_WANT_SYS_OLDUMOUNT
+/* #define __ARCH_WANT_SYS_SIGPENDING */
+#define __ARCH_WANT_SYS_SIGPROCMASK
+#define __ARCH_WANT_SYS_RT_SIGACTION
+#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
+ */
+#ifndef cond_syscall
+#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall");
+#endif
+
+#endif /* _ASM_UNISTD_H_ */
diff -Nru a/include/asm-frv/user.h b/include/asm-frv/user.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/user.h	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,80 @@
+/* user.h: FR-V core file format stuff
+ *
+ * Copyright (C) 2003 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.
+ */
+#ifndef _ASM_USER_H
+#define _ASM_USER_H
+
+#include <asm/page.h>
+#include <asm/registers.h>
+
+/* Core file format: The core file is written in such a way that gdb
+ * can understand it and provide useful information to the user (under
+ * linux we use the 'trad-core' bfd).  There are quite a number of
+ * obstacles to being able to view the contents of the floating point
+ * registers, and until these are solved you will not be able to view
+ * the contents of them.  Actually, you can read in the core file and
+ * look at the contents of the user struct to find out what the
+ * floating point registers contain.
+ *
+ * The actual file contents are as follows:
+ * UPAGE:
+ *   1 page consisting of a user struct that tells gdb what is present
+ *   in the file.  Directly after this is a copy of the task_struct,
+ *   which is currently not used by gdb, but it may come in useful at
+ *   some point.  All of the registers are stored as part of the
+ *   upage.  The upage should always be only one page.
+ *
+ * DATA:
+ *   The data area is stored.  We use current->end_text to
+ *   current->brk to pick up all of the user variables, plus any
+ *   memory that may have been malloced.  No attempt is made to
+ *   determine if a page is demand-zero or if a page is totally
+ *   unused, we just cover the entire range.  All of the addresses are
+ *   rounded in such a way that an integral number of pages is
+ *   written.
+ *
+ * STACK:
+ *   We need the stack information in order to get a meaningful
+ *   backtrace.  We need to write the data from (esp) to
+ *   current->start_stack, so we round each of these off in order to
+ *   be able to write an integer number of pages.  The minimum core
+ *   file size is 3 pages, or 12288 bytes.
+ */
+
+/* When the kernel dumps core, it starts by dumping the user struct -
+ * this will be used by gdb to figure out where the data and stack segments
+ *  are within the file, and what virtual addresses to use.
+ */
+struct user {
+	/* We start with the registers, to mimic the way that "memory" is returned
+	 * from the ptrace(3,...) function.  */
+	struct user_context	regs;
+
+	/* The rest of this junk is to help gdb figure out what goes where */
+	unsigned long		u_tsize;	/* Text segment size (pages). */
+	unsigned long		u_dsize;	/* Data segment size (pages). */
+	unsigned long		u_ssize;	/* Stack segment size (pages). */
+	unsigned long		start_code;     /* Starting virtual address of text. */
+	unsigned long		start_stack;	/* Starting virtual address of stack area.
+						 * This is actually the bottom of the stack,
+						 * the top of the stack is always found in the
+						 * esp register.  */
+	long int		signal;		/* Signal that caused the core dump. */
+
+	unsigned long		magic;		/* To uniquely identify a core file */
+	char			u_comm[32];	/* User command that was responsible */
+};
+
+#define NBPG			PAGE_SIZE
+#define UPAGES			1
+#define HOST_TEXT_START_ADDR	(u.start_code)
+#define HOST_STACK_END_ADDR	(u.start_stack + u.u_ssize * NBPG)
+
+#endif
diff -Nru a/include/asm-frv/virtconvert.h b/include/asm-frv/virtconvert.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-frv/virtconvert.h	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,42 @@
+/* virtconvert.h: virtual/physical/page address convertion
+ *
+ * Copyright (C) 2004 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.
+ */
+#ifndef _ASM_VIRTCONVERT_H
+#define _ASM_VIRTCONVERT_H
+
+/*
+ * Macros used for converting between virtual and physical mappings.
+ */
+
+#ifdef __KERNEL__
+
+#include <linux/config.h>
+#include <asm/setup.h>
+
+#ifdef CONFIG_MMU
+
+#define phys_to_virt(vaddr)	((void *) ((unsigned long)(vaddr) + PAGE_OFFSET))
+#define virt_to_phys(vaddr)	((unsigned long) (vaddr) - PAGE_OFFSET)
+
+#else
+
+#define phys_to_virt(vaddr)	((void *) (vaddr))
+#define virt_to_phys(vaddr)	((unsigned long) (vaddr))
+
+#endif
+
+#define virt_to_bus virt_to_phys
+#define bus_to_virt phys_to_virt
+
+#define __page_address(page)	(PAGE_OFFSET + (((page) - mem_map) << PAGE_SHIFT))
+#define page_to_phys(page)	virt_to_phys((void *)__page_address(page))
+
+#endif
+#endif
diff -Nru a/include/asm-generic/4level-fixup.h b/include/asm-generic/4level-fixup.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-generic/4level-fixup.h	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,34 @@
+#ifndef _4LEVEL_FIXUP_H
+#define _4LEVEL_FIXUP_H
+
+#define __ARCH_HAS_4LEVEL_HACK
+
+#define PUD_SIZE			PGDIR_SIZE
+#define PUD_MASK			PGDIR_MASK
+#define PTRS_PER_PUD			1
+
+#define pud_t				pgd_t
+
+#define pmd_alloc(mm, pud, address)			\
+({	pmd_t *ret;					\
+	if (pgd_none(*pud))				\
+ 		ret = __pmd_alloc(mm, pud, address);	\
+ 	else						\
+		ret = pmd_offset(pud, address);		\
+ 	ret;						\
+})
+
+#define pud_alloc(mm, pgd, address)	(pgd)
+#define pud_offset(pgd, start)		(pgd)
+#define pud_none(pud)			0
+#define pud_bad(pud)			0
+#define pud_present(pud)		1
+#define pud_ERROR(pud)			do { } while (0)
+#define pud_clear(pud)			pgd_clear(pud)
+
+#undef pud_free_tlb
+#define pud_free_tlb(tlb, x)            do { } while (0)
+#define pud_free(x)			do { } while (0)
+#define __pud_free_tlb(tlb, x)		do { } while (0)
+
+#endif
diff -Nru a/include/asm-generic/cputime.h b/include/asm-generic/cputime.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-generic/cputime.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,64 @@
+#ifndef _ASM_GENERIC_CPUTIME_H
+#define _ASM_GENERIC_CPUTIME_H
+
+#include <linux/time.h>
+#include <linux/jiffies.h>
+
+typedef unsigned long cputime_t;
+
+#define cputime_zero			(0UL)
+#define cputime_max			((~0UL >> 1) - 1)
+#define cputime_add(__a, __b)		((__a) +  (__b))
+#define cputime_sub(__a, __b)		((__a) -  (__b))
+#define cputime_eq(__a, __b)		((__a) == (__b))
+#define cputime_gt(__a, __b)		((__a) >  (__b))
+#define cputime_ge(__a, __b)		((__a) >= (__b))
+#define cputime_lt(__a, __b)		((__a) <  (__b))
+#define cputime_le(__a, __b)		((__a) <= (__b))
+#define cputime_to_jiffies(__ct)	(__ct)
+#define jiffies_to_cputime(__hz)	(__hz)
+
+typedef u64 cputime64_t;
+
+#define cputime64_zero (0ULL)
+#define cputime64_add(__a, __b)		((__a) + (__b))
+#define cputime64_to_jiffies64(__ct)	(__ct)
+#define cputime_to_cputime64(__ct)	((u64) __ct)
+
+
+/*
+ * Convert cputime to milliseconds and back.
+ */
+#define cputime_to_msecs(__ct)		jiffies_to_msecs(__ct)
+#define msecs_to_cputime(__msecs)	msecs_to_jiffies(__msecs)
+
+/*
+ * Convert cputime to seconds and back.
+ */
+#define cputime_to_secs(jif)		((jif) / HZ)
+#define secs_to_cputime(sec)		((sec) * HZ)
+
+/*
+ * Convert cputime to timespec and back.
+ */
+#define timespec_to_cputime(__val)	timespec_to_jiffies(__val)
+#define cputime_to_timespec(__ct,__val)	jiffies_to_timespec(__ct,__val)
+
+/*
+ * Convert cputime to timeval and back.
+ */
+#define timeval_to_cputime(__val)	timeval_to_jiffies(__val)
+#define cputime_to_timeval(__ct,__val)	jiffies_to_timeval(__ct,__val)
+
+/*
+ * Convert cputime to clock and back.
+ */
+#define cputime_to_clock_t(__ct)	jiffies_to_clock_t(__ct)
+#define clock_t_to_cputime(__x)		clock_t_to_jiffies(__x)
+
+/*
+ * Convert cputime64 to clock.
+ */
+#define cputime64_to_clock_t(__ct)	jiffies_64_to_clock_t(__ct)
+
+#endif
diff -Nru a/include/asm-generic/pgtable-nopmd.h b/include/asm-generic/pgtable-nopmd.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-generic/pgtable-nopmd.h	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,60 @@
+#ifndef _PGTABLE_NOPMD_H
+#define _PGTABLE_NOPMD_H
+
+#ifndef __ASSEMBLY__
+
+#include <asm-generic/pgtable-nopud.h>
+
+/*
+ * Having the pmd type consist of a pud gets the size right, and allows
+ * us to conceptually access the pud entry that this pmd is folded into
+ * without casting.
+ */
+typedef struct { pud_t pud; } pmd_t;
+
+#define PMD_SHIFT	PUD_SHIFT
+#define PTRS_PER_PMD	1
+#define PMD_SIZE  	(1UL << PMD_SHIFT)
+#define PMD_MASK  	(~(PMD_SIZE-1))
+
+/*
+ * The "pud_xxx()" functions here are trivial for a folded two-level
+ * setup: the pmd is never bad, and a pmd always exists (as it's folded
+ * into the pud entry)
+ */
+static inline int pud_none(pud_t pud)		{ return 0; }
+static inline int pud_bad(pud_t pud)		{ return 0; }
+static inline int pud_present(pud_t pud)	{ return 1; }
+static inline void pud_clear(pud_t *pud)	{ }
+#define pmd_ERROR(pmd)				(pud_ERROR((pmd).pud))
+
+#define pud_populate(mm, pmd, pte)		do { } while (0)
+
+/*
+ * (pmds are folded into puds so this doesn't get actually called,
+ * but the define is needed for a generic inline function.)
+ */
+#define set_pud(pudptr, pudval)			set_pmd((pmd_t *)(pudptr), (pmd_t) { pudval })
+
+static inline pmd_t * pmd_offset(pud_t * pud, unsigned long address)
+{
+	return (pmd_t *)pud;
+}
+
+#define pmd_val(x)				(pud_val((x).pud))
+#define __pmd(x)				((pmd_t) { __pud(x) } )
+
+#define pud_page(pud)				(pmd_page((pmd_t){ pud }))
+#define pud_page_kernel(pud)			(pmd_page_kernel((pmd_t){ pud }))
+
+/*
+ * allocating and freeing a pmd is trivial: the 1-entry pmd is
+ * inside the pud, so has no extra memory associated with it.
+ */
+#define pmd_alloc_one(mm, address)		NULL
+#define pmd_free(x)				do { } while (0)
+#define __pmd_free_tlb(tlb, x)			do { } while (0)
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _PGTABLE_NOPMD_H */
diff -Nru a/include/asm-generic/pgtable-nopud.h b/include/asm-generic/pgtable-nopud.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-generic/pgtable-nopud.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,56 @@
+#ifndef _PGTABLE_NOPUD_H
+#define _PGTABLE_NOPUD_H
+
+#ifndef __ASSEMBLY__
+
+/*
+ * Having the pud type consist of a pgd gets the size right, and allows
+ * us to conceptually access the pgd entry that this pud is folded into
+ * without casting.
+ */
+typedef struct { pgd_t pgd; } pud_t;
+
+#define PUD_SHIFT	PGDIR_SHIFT
+#define PTRS_PER_PUD	1
+#define PUD_SIZE  	(1UL << PUD_SHIFT)
+#define PUD_MASK  	(~(PUD_SIZE-1))
+
+/*
+ * The "pgd_xxx()" functions here are trivial for a folded two-level
+ * setup: the pud is never bad, and a pud always exists (as it's folded
+ * into the pgd entry)
+ */
+static inline int pgd_none(pgd_t pgd)		{ return 0; }
+static inline int pgd_bad(pgd_t pgd)		{ return 0; }
+static inline int pgd_present(pgd_t pgd)	{ return 1; }
+static inline void pgd_clear(pgd_t *pgd)	{ }
+#define pud_ERROR(pud)				(pgd_ERROR((pud).pgd))
+
+#define pgd_populate(mm, pgd, pud)		do { } while (0)
+/*
+ * (puds are folded into pgds so this doesn't get actually called,
+ * but the define is needed for a generic inline function.)
+ */
+#define set_pgd(pgdptr, pgdval)			set_pud((pud_t *)(pgdptr), (pud_t) { pgdval })
+
+static inline pud_t * pud_offset(pgd_t * pgd, unsigned long address)
+{
+	return (pud_t *)pgd;
+}
+
+#define pud_val(x)				(pgd_val((x).pgd))
+#define __pud(x)				((pud_t) { __pgd(x) } )
+
+#define pgd_page(pgd)				(pud_page((pud_t){ pgd }))
+#define pgd_page_kernel(pgd)			(pud_page_kernel((pud_t){ pgd }))
+
+/*
+ * allocating and freeing a pud is trivial: the 1-entry pud is
+ * inside the pgd, so has no extra memory associated with it.
+ */
+#define pud_alloc_one(mm, address)		NULL
+#define pud_free(x)				do { } while (0)
+#define __pud_free_tlb(tlb, x)			do { } while (0)
+
+#endif /* __ASSEMBLY__ */
+#endif /* _PGTABLE_NOPUD_H */
diff -Nru a/include/asm-generic/resource.h b/include/asm-generic/resource.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-generic/resource.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,60 @@
+#ifndef _ASM_GENERIC_RESOURCE_H
+#define _ASM_GENERIC_RESOURCE_H
+
+/*
+ * Resource limits
+ */
+
+/* Allow arch to control resource order */
+#ifndef __ARCH_RLIMIT_ORDER
+#define RLIMIT_CPU		0	/* CPU time in ms */
+#define RLIMIT_FSIZE		1	/* Maximum filesize */
+#define RLIMIT_DATA		2	/* max data size */
+#define RLIMIT_STACK		3	/* max stack size */
+#define RLIMIT_CORE		4	/* max core file size */
+#define RLIMIT_RSS		5	/* max resident set size */
+#define RLIMIT_NPROC		6	/* max number of processes */
+#define RLIMIT_NOFILE		7	/* max number of open files */
+#define RLIMIT_MEMLOCK		8	/* max locked-in-memory address space */
+#define RLIMIT_AS		9	/* address space limit */
+#define RLIMIT_LOCKS		10	/* maximum file locks held */
+#define RLIMIT_SIGPENDING	11	/* max number of pending signals */
+#define RLIMIT_MSGQUEUE		12	/* maximum bytes in POSIX mqueues */
+
+#define RLIM_NLIMITS		13
+#endif
+
+/*
+ * SuS says limits have to be unsigned.
+ * Which makes a ton more sense anyway.
+ */
+#ifndef RLIM_INFINITY
+#define RLIM_INFINITY	(~0UL)
+#endif
+
+#ifndef _STK_LIM_MAX
+#define _STK_LIM_MAX	RLIM_INFINITY
+#endif
+
+#ifdef __KERNEL__
+
+#define INIT_RLIMITS							\
+{									\
+	[RLIMIT_CPU]		= { RLIM_INFINITY, RLIM_INFINITY },	\
+	[RLIMIT_FSIZE]		= { RLIM_INFINITY, RLIM_INFINITY },	\
+	[RLIMIT_DATA]		= { RLIM_INFINITY, RLIM_INFINITY },	\
+	[RLIMIT_STACK]		= {      _STK_LIM, _STK_LIM_MAX  },	\
+	[RLIMIT_CORE]		= {             0, RLIM_INFINITY },	\
+	[RLIMIT_RSS]		= { RLIM_INFINITY, RLIM_INFINITY },	\
+	[RLIMIT_NPROC]		= {             0,             0 },	\
+	[RLIMIT_NOFILE]		= {      INR_OPEN,     INR_OPEN  },	\
+	[RLIMIT_MEMLOCK]	= {   MLOCK_LIMIT,   MLOCK_LIMIT },	\
+	[RLIMIT_AS]		= { RLIM_INFINITY, RLIM_INFINITY },	\
+	[RLIMIT_LOCKS]		= { RLIM_INFINITY, RLIM_INFINITY },	\
+	[RLIMIT_SIGPENDING]	= { MAX_SIGPENDING, MAX_SIGPENDING },	\
+	[RLIMIT_MSGQUEUE]	= { MQ_BYTES_MAX, MQ_BYTES_MAX },	\
+}
+
+#endif	/* __KERNEL__ */
+
+#endif
diff -Nru a/include/asm-generic/sections.h b/include/asm-generic/sections.h
--- a/include/asm-generic/sections.h	2005-03-01 23:38:44 -08:00
+++ b/include/asm-generic/sections.h	2005-03-01 23:38:44 -08:00
@@ -8,5 +8,6 @@
 extern char __bss_start[], __bss_stop[];
 extern char __init_begin[], __init_end[];
 extern char _sinittext[], _einittext[];
+extern char _end[];
 
 #endif /* _ASM_GENERIC_SECTIONS_H_ */
diff -Nru a/include/asm-generic/siginfo.h b/include/asm-generic/siginfo.h
--- a/include/asm-generic/siginfo.h	2005-03-01 23:38:54 -08:00
+++ b/include/asm-generic/siginfo.h	2005-03-01 23:38:54 -08:00
@@ -154,7 +154,6 @@
 #define SI_FROMUSER(siptr)	((siptr)->si_code <= 0)
 #define SI_FROMKERNEL(siptr)	((siptr)->si_code > 0)
 
-#ifndef HAVE_ARCH_SI_CODES
 /*
  * SIGILL si_codes
  */
@@ -225,8 +224,6 @@
 #define POLL_HUP	(__SI_POLL|6)	/* device disconnected */
 #define NSIGPOLL	6
 
-#endif
-
 /*
  * sigevent definitions
  * 
@@ -245,8 +242,6 @@
 #define SIGEV_PAD_SIZE	((SIGEV_MAX_SIZE/sizeof(int)) - 3)
 #endif
 
-#ifndef HAVE_ARCH_SIGEVENT_T
-
 typedef struct sigevent {
 	sigval_t sigev_value;
 	int sigev_signo;
@@ -261,8 +256,6 @@
 		} _sigev_thread;
 	} _sigev_un;
 } sigevent_t;
-
-#endif
 
 #define sigev_notify_function	_sigev_un._sigev_thread._function
 #define sigev_notify_attributes	_sigev_un._sigev_thread._attribute
diff -Nru a/include/asm-generic/termios.h b/include/asm-generic/termios.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-generic/termios.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,69 @@
+/* termios.h: generic termios/termio user copying/translation
+ */
+
+#ifndef _ASM_GENERIC_TERMIOS_H
+#define _ASM_GENERIC_TERMIOS_H
+
+#include <asm/uaccess.h>
+
+#ifndef __ARCH_TERMIO_GETPUT
+
+/*
+ * Translate a "termio" structure into a "termios". Ugh.
+ */
+static inline int user_termio_to_kernel_termios(struct termios *termios,
+						struct termio __user *termio)
+{
+	unsigned short tmp;
+
+	if (get_user(tmp, &termio->c_iflag) < 0)
+		goto fault;
+	termios->c_iflag = (0xffff0000 & termios->c_iflag) | tmp;
+
+	if (get_user(tmp, &termio->c_oflag) < 0)
+		goto fault;
+	termios->c_oflag = (0xffff0000 & termios->c_oflag) | tmp;
+
+	if (get_user(tmp, &termio->c_cflag) < 0)
+		goto fault;
+	termios->c_cflag = (0xffff0000 & termios->c_cflag) | tmp;
+
+	if (get_user(tmp, &termio->c_lflag) < 0)
+		goto fault;
+	termios->c_lflag = (0xffff0000 & termios->c_lflag) | tmp;
+
+	if (get_user(termios->c_line, &termio->c_line) < 0)
+		goto fault;
+
+	if (copy_from_user(termios->c_cc, termio->c_cc, NCC) != 0)
+		goto fault;
+
+	return 0;
+
+ fault:
+	return -EFAULT;
+}
+
+/*
+ * Translate a "termios" structure into a "termio". Ugh.
+ */
+static inline int kernel_termios_to_user_termio(struct termio __user *termio,
+						struct termios *termios)
+{
+	if (put_user(termios->c_iflag, &termio->c_iflag) < 0 ||
+	    put_user(termios->c_oflag, &termio->c_oflag) < 0 ||
+	    put_user(termios->c_cflag, &termio->c_cflag) < 0 ||
+	    put_user(termios->c_lflag, &termio->c_lflag) < 0 ||
+	    put_user(termios->c_line,  &termio->c_line) < 0 ||
+	    copy_to_user(termio->c_cc, termios->c_cc, NCC) != 0)
+		return -EFAULT;
+
+	return 0;
+}
+
+#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	/* __ARCH_TERMIO_GETPUT */
+
+#endif /* _ASM_GENERIC_TERMIOS_H */
diff -Nru a/include/asm-generic/tlb.h b/include/asm-generic/tlb.h
--- a/include/asm-generic/tlb.h	2005-03-01 23:38:43 -08:00
+++ b/include/asm-generic/tlb.h	2005-03-01 23:38:43 -08:00
@@ -141,6 +141,14 @@
 		__pte_free_tlb(tlb, ptep);			\
 	} while (0)
 
+#ifndef __ARCH_HAS_4LEVEL_HACK
+#define pud_free_tlb(tlb, pudp)					\
+	do {							\
+		tlb->need_flush = 1;				\
+		__pud_free_tlb(tlb, pudp);			\
+	} while (0)
+#endif
+
 #define pmd_free_tlb(tlb, pmdp)					\
 	do {							\
 		tlb->need_flush = 1;				\
diff -Nru a/include/asm-h8300/bitops.h b/include/asm-h8300/bitops.h
--- a/include/asm-h8300/bitops.h	2005-03-01 23:38:55 -08:00
+++ b/include/asm-h8300/bitops.h	2005-03-01 23:38:55 -08:00
@@ -196,7 +196,7 @@
 	return result;
 }
 
-static __inline__ int find_next_zero_bit (void * addr, int size, int offset)
+static __inline__ int find_next_zero_bit (const unsigned long * addr, int size, int offset)
 {
 	unsigned long *p = (unsigned long *)(((unsigned long)addr + (offset >> 3)) & ~3);
 	unsigned long result = offset & ~31UL;
diff -Nru a/include/asm-h8300/cputime.h b/include/asm-h8300/cputime.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-h8300/cputime.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,6 @@
+#ifndef __H8300_CPUTIME_H
+#define __H8300_CPUTIME_H
+
+#include <asm-generic/cputime.h>
+
+#endif /* __H8300_CPUTIME_H */
diff -Nru a/include/asm-h8300/hardirq.h b/include/asm-h8300/hardirq.h
--- a/include/asm-h8300/hardirq.h	2005-03-01 23:38:58 -08:00
+++ b/include/asm-h8300/hardirq.h	2005-03-01 23:38:58 -08:00
@@ -9,8 +9,6 @@
 
 typedef struct {
 	unsigned int __softirq_pending;
-	unsigned int __syscall_count;
-	struct task_struct * __ksoftirqd_task;
 } ____cacheline_aligned irq_cpustat_t;
 
 #include <linux/irq_cpustat.h>	/* Standard mappings for irq_cpustat_t above */
@@ -25,14 +23,5 @@
 #if (1 << HARDIRQ_BITS) < NR_IRQS
 # error HARDIRQ_BITS is too low!
 #endif
-
-#define irq_enter()		(preempt_count() += HARDIRQ_OFFSET)
-#define irq_exit()							\
-do {									\
-		preempt_count() -= IRQ_EXIT_OFFSET;			\
-		if (!in_interrupt() && softirq_pending(smp_processor_id())) \
-			do_softirq();					\
-		preempt_enable_no_resched();				\
-} while (0)
 
 #endif
diff -Nru a/include/asm-h8300/mmu.h b/include/asm-h8300/mmu.h
--- a/include/asm-h8300/mmu.h	2005-03-01 23:38:44 -08:00
+++ b/include/asm-h8300/mmu.h	2005-03-01 23:38:44 -08:00
@@ -3,19 +3,8 @@
 
 /* Copyright (C) 2002, David McCullough <davidm@snapgear.com> */
 
-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;
+	struct vm_list_struct	*vmlist;
 	unsigned long		end_brk;
 } mm_context_t;
 
diff -Nru a/include/asm-h8300/page.h b/include/asm-h8300/page.h
--- a/include/asm-h8300/page.h	2005-03-01 23:39:09 -08:00
+++ b/include/asm-h8300/page.h	2005-03-01 23:39:09 -08:00
@@ -30,6 +30,9 @@
 #define clear_user_page(page, vaddr, pg)	clear_page(page)
 #define copy_user_page(to, from, vaddr, pg)	copy_page(to, from)
 
+#define alloc_zeroed_user_highpage(vma, vaddr) alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO, vma, vaddr)
+#define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE
+
 /*
  * These are used to make use of C type-checking..
  */
diff -Nru a/include/asm-h8300/pgtable.h b/include/asm-h8300/pgtable.h
--- a/include/asm-h8300/pgtable.h	2005-03-01 23:38:56 -08:00
+++ b/include/asm-h8300/pgtable.h	2005-03-01 23:38:56 -08:00
@@ -1,6 +1,8 @@
 #ifndef _H8300_PGTABLE_H
 #define _H8300_PGTABLE_H
 
+#include <asm-generic/4level-fixup.h>
+
 #include <linux/config.h>
 #include <linux/slab.h>
 #include <asm/processor.h>
diff -Nru a/include/asm-h8300/processor.h b/include/asm-h8300/processor.h
--- a/include/asm-h8300/processor.h	2005-03-01 23:38:53 -08:00
+++ b/include/asm-h8300/processor.h	2005-03-01 23:38:53 -08:00
@@ -45,11 +45,6 @@
  */
 #define TASK_UNMAPPED_BASE	0
 
-/*
- * Bus types
- */
-#define MCA_bus 0
-
 struct thread_struct {
 	unsigned long  ksp;		/* kernel stack pointer */
 	unsigned long  usp;		/* user stack pointer */
diff -Nru a/include/asm-h8300/resource.h b/include/asm-h8300/resource.h
--- a/include/asm-h8300/resource.h	2005-03-01 23:38:52 -08:00
+++ b/include/asm-h8300/resource.h	2005-03-01 23:38:52 -08:00
@@ -1,51 +1,6 @@
 #ifndef _H8300_RESOURCE_H
 #define _H8300_RESOURCE_H
 
-/*
- * Resource limits
- */
-
-#define RLIMIT_CPU	0		/* CPU time in ms */
-#define RLIMIT_FSIZE	1		/* Maximum filesize */
-#define RLIMIT_DATA	2		/* max data size */
-#define RLIMIT_STACK	3		/* max stack size */
-#define RLIMIT_CORE	4		/* max core file size */
-#define RLIMIT_RSS	5		/* max resident set size */
-#define RLIMIT_NPROC	6		/* max number of processes */
-#define RLIMIT_NOFILE	7		/* max number of open files */
-#define RLIMIT_MEMLOCK	8		/* max locked-in-memory address space */
-#define RLIMIT_AS	9		/* address space limit */
-#define RLIMIT_LOCKS	10		/* maximum file locks held */
-#define RLIMIT_SIGPENDING 11		/* max number of pending signals */
-#define RLIMIT_MSGQUEUE 12		/* maximum bytes in POSIX mqueues */
-
-#define RLIM_NLIMITS	13
-
-/*
- * SuS says limits have to be unsigned.
- * Which makes a ton more sense anyway.
- */
-#define RLIM_INFINITY	(~0UL)
-
-#ifdef __KERNEL__
-
-#define INIT_RLIMITS					\
-{							\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{      _STK_LIM, RLIM_INFINITY },		\
-	{             0, RLIM_INFINITY },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{             0,             0 },		\
-	{      INR_OPEN,     INR_OPEN  },		\
-	{   MLOCK_LIMIT,   MLOCK_LIMIT },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{ MAX_SIGPENDING, MAX_SIGPENDING },		\
-	{ MQ_BYTES_MAX, MQ_BYTES_MAX },			\
-}
-
-#endif /* __KERNEL__ */
+#include <asm-generic/resource.h>
 
 #endif /* _H8300_RESOURCE_H */
diff -Nru a/include/asm-h8300/thread_info.h b/include/asm-h8300/thread_info.h
--- a/include/asm-h8300/thread_info.h	2005-03-01 23:39:18 -08:00
+++ b/include/asm-h8300/thread_info.h	2005-03-01 23:39:18 -08:00
@@ -93,6 +93,7 @@
 #define TIF_NEED_RESCHED	3	/* rescheduling necessary */
 #define TIF_POLLING_NRFLAG	4	/* true if poll_idle() is polling
 					   TIF_NEED_RESCHED */
+#define TIF_MEMDIE		5
 
 /* as above, but as bit values */
 #define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE)
diff -Nru a/include/asm-h8300/unistd.h b/include/asm-h8300/unistd.h
--- a/include/asm-h8300/unistd.h	2005-03-01 23:38:57 -08:00
+++ b/include/asm-h8300/unistd.h	2005-03-01 23:38:57 -08:00
@@ -270,8 +270,29 @@
 #define __NR_clock_gettime	(__NR_timer_create+6)
 #define __NR_clock_getres	(__NR_timer_create+7)
 #define __NR_clock_nanosleep	(__NR_timer_create+8)
+#define __NR_statfs64		268
+#define __NR_fstatfs64		269
+#define __NR_tgkill		270
+#define __NR_utimes		271
+#define __NR_fadvise64_64	272
+#define __NR_vserver		273
+#define __NR_mbind		274
+#define __NR_get_mempolicy	275
+#define __NR_set_mempolicy	276
+#define __NR_mq_open 		277
+#define __NR_mq_unlink		(__NR_mq_open+1)
+#define __NR_mq_timedsend	(__NR_mq_open+2)
+#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_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 268
+#define NR_syscalls 289
 
 
 /* user-visible error numbers are in the range -1 - -122: see
diff -Nru a/include/asm-i386/acpi.h b/include/asm-i386/acpi.h
--- a/include/asm-i386/acpi.h	2005-03-01 23:39:09 -08:00
+++ b/include/asm-i386/acpi.h	2005-03-01 23:39:09 -08:00
@@ -104,12 +104,6 @@
 /*
  * Refer Intel ACPI _PDC support document for bit definitions
  */
-#define ACPI_PDC_EST_CAPABILITY_SMP	0xa
-#define ACPI_PDC_EST_CAPABILITY_MSR	0x1
-
-/*
- * Refer Intel ACPI _PDC support document for bit definitions
- */
 #define ACPI_PDC_EST_CAPABILITY_SMP 	0xa
 #define ACPI_PDC_EST_CAPABILITY_MSR	0x1
 
diff -Nru a/include/asm-i386/agp.h b/include/asm-i386/agp.h
--- a/include/asm-i386/agp.h	2005-03-01 23:38:44 -08:00
+++ b/include/asm-i386/agp.h	2005-03-01 23:38:44 -08:00
@@ -12,8 +12,8 @@
  * data corruption on some CPUs.
  */
 
-#define map_page_into_agp(page) change_page_attr(page, 1, PAGE_KERNEL_NOCACHE)
-#define unmap_page_from_agp(page) change_page_attr(page, 1, PAGE_KERNEL)
+int map_page_into_agp(struct page *page);
+int unmap_page_from_agp(struct page *page);
 #define flush_agp_mappings() global_flush_tlb()
 
 /* Could use CLFLUSH here if the cpu supports it. But then it would
diff -Nru a/include/asm-i386/bug.h b/include/asm-i386/bug.h
--- a/include/asm-i386/bug.h	2005-03-01 23:38:53 -08:00
+++ b/include/asm-i386/bug.h	2005-03-01 23:38:53 -08:00
@@ -9,7 +9,7 @@
  * undefined" opcode for parsing in the trap handler.
  */
 
-#if 1	/* Set to zero for a slightly smaller kernel */
+#ifdef CONFIG_DEBUG_BUGVERBOSE
 #define BUG()				\
  __asm__ __volatile__(	"ud2\n"		\
 			"\t.word %c0\n"	\
diff -Nru a/include/asm-i386/checksum.h b/include/asm-i386/checksum.h
--- a/include/asm-i386/checksum.h	2005-03-01 23:39:18 -08:00
+++ b/include/asm-i386/checksum.h	2005-03-01 23:39:18 -08:00
@@ -25,8 +25,8 @@
  * 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);
+asmlinkage unsigned int csum_partial_copy_generic(const unsigned char *src, unsigned 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
@@ -36,18 +36,18 @@
  *	verify_area().
  */
 static __inline__
-unsigned int csum_partial_copy_nocheck ( const char *src, char *dst,
+unsigned int csum_partial_copy_nocheck (const unsigned char *src, unsigned char *dst,
 					int len, int sum)
 {
 	return csum_partial_copy_generic ( src, dst, len, sum, NULL, NULL);
 }
 
 static __inline__
-unsigned int csum_partial_copy_from_user(const char __user *src, char *dst,
+unsigned int csum_partial_copy_from_user(const unsigned char __user *src, unsigned char *dst,
 						int len, int sum, int *err_ptr)
 {
 	might_sleep();
-	return csum_partial_copy_generic((__force char *)src, dst,
+	return csum_partial_copy_generic((__force unsigned char *)src, dst,
 					len, sum, err_ptr, NULL);
 }
 
@@ -174,14 +174,14 @@
  *	Copy and checksum to user
  */
 #define HAVE_CSUM_COPY_USER
-static __inline__ unsigned int csum_and_copy_to_user(const char *src, 
-						     char __user *dst,
+static __inline__ unsigned int csum_and_copy_to_user(const unsigned char *src,
+						     unsigned char __user *dst,
 						     int len, int sum, 
 						     int *err_ptr)
 {
 	might_sleep();
 	if (access_ok(VERIFY_WRITE, dst, len))
-		return csum_partial_copy_generic(src, (__force char *)dst, len, sum, NULL, err_ptr);
+		return csum_partial_copy_generic(src, (__force unsigned char *)dst, len, sum, NULL, err_ptr);
 
 	if (len)
 		*err_ptr = -EFAULT;
diff -Nru a/include/asm-i386/cpu.h b/include/asm-i386/cpu.h
--- a/include/asm-i386/cpu.h	2005-03-01 23:39:07 -08:00
+++ b/include/asm-i386/cpu.h	2005-03-01 23:39:07 -08:00
@@ -12,18 +12,9 @@
 	struct cpu cpu;
 };
 extern struct i386_cpu cpu_devices[NR_CPUS];
-
-
-static inline int arch_register_cpu(int num){
-	struct node *parent = NULL;
-	
-#ifdef CONFIG_NUMA
-	int node = cpu_to_node(num);
-	if (node_online(node))
-		parent = &node_devices[node].node;
-#endif /* CONFIG_NUMA */
-
-	return register_cpu(&cpu_devices[num].cpu, num, parent);
-}
+extern int arch_register_cpu(int num);
+#ifdef CONFIG_HOTPLUG_CPU
+extern void arch_unregister_cpu(int);
+#endif
 
 #endif /* _ASM_I386_CPU_H_ */
diff -Nru a/include/asm-i386/cpufeature.h b/include/asm-i386/cpufeature.h
--- a/include/asm-i386/cpufeature.h	2005-03-01 23:39:08 -08:00
+++ b/include/asm-i386/cpufeature.h	2005-03-01 23:39:08 -08:00
@@ -9,7 +9,7 @@
 
 #include <linux/bitops.h>
 
-#define NCAPINTS	6	/* Currently we have 6 32-bit words worth of info */
+#define NCAPINTS	7	/* N 32-bit words worth of info */
 
 /* Intel-defined CPU features, CPUID level 0x00000001 (edx), word 0 */
 #define X86_FEATURE_FPU		(0*32+ 0) /* Onboard FPU */
@@ -77,6 +77,7 @@
 #define X86_FEATURE_EST		(4*32+ 7) /* Enhanced SpeedStep */
 #define X86_FEATURE_TM2		(4*32+ 8) /* Thermal Monitor 2 */
 #define X86_FEATURE_CID		(4*32+10) /* Context ID */
+#define X86_FEATURE_CX16        (4*32+13) /* CMPXCHG16B */
 #define X86_FEATURE_XTPR	(4*32+14) /* Send Task Priority Messages */
 
 /* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, word 5 */
@@ -85,6 +86,9 @@
 #define X86_FEATURE_XCRYPT	(5*32+ 6) /* on-CPU crypto (xcrypt insn) */
 #define X86_FEATURE_XCRYPT_EN	(5*32+ 7) /* on-CPU crypto enabled */
 
+/* More extended AMD flags: CPUID level 0x80000001, ecx, word 6 */
+#define X86_FEATURE_LAHF_LM	(5*32+ 0) /* LAHF/SAHF in long mode */
+#define X86_FEATURE_CMP_LEGACY	(5*32+ 1) /* If yes HyperThreading not valid */
 
 #define cpu_has(c, bit)		test_bit(bit, (c)->x86_capability)
 #define boot_cpu_has(bit)	test_bit(bit, boot_cpu_data.x86_capability)
diff -Nru a/include/asm-i386/cputime.h b/include/asm-i386/cputime.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-i386/cputime.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,6 @@
+#ifndef __I386_CPUTIME_H
+#define __I386_CPUTIME_H
+
+#include <asm-generic/cputime.h>
+
+#endif /* __I386_CPUTIME_H */
diff -Nru a/include/asm-i386/desc.h b/include/asm-i386/desc.h
--- a/include/asm-i386/desc.h	2005-03-01 23:38:44 -08:00
+++ b/include/asm-i386/desc.h	2005-03-01 23:38:44 -08:00
@@ -126,6 +126,15 @@
 	put_cpu();
 }
 
+static inline unsigned long get_desc_base(unsigned long *desc)
+{
+	unsigned long base;
+	base = ((desc[0] >> 16)  & 0x0000ffff) |
+		((desc[1] << 16) & 0x00ff0000) |
+		(desc[1] & 0xff000000);
+	return base;
+}
+
 #endif /* !__ASSEMBLY__ */
 
 #endif
diff -Nru a/include/asm-i386/elf.h b/include/asm-i386/elf.h
--- a/include/asm-i386/elf.h	2005-03-01 23:39:07 -08:00
+++ b/include/asm-i386/elf.h	2005-03-01 23:39:07 -08:00
@@ -123,7 +123,7 @@
  * 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(ex, have_pt_gnu_stack)	(!(have_pt_gnu_stack))
+#define elf_read_implies_exec(ex, executable_stack)	(executable_stack != EXSTACK_DISABLE_X)
 
 extern int dump_task_regs (struct task_struct *, elf_gregset_t *);
 extern int dump_task_fpu (struct task_struct *, elf_fpregset_t *);
diff -Nru a/include/asm-i386/fixmap.h b/include/asm-i386/fixmap.h
--- a/include/asm-i386/fixmap.h	2005-03-01 23:38:52 -08:00
+++ b/include/asm-i386/fixmap.h	2005-03-01 23:38:52 -08:00
@@ -109,7 +109,9 @@
 #define FIXADDR_TOP	((unsigned long)__FIXADDR_TOP)
 
 #define __FIXADDR_SIZE	(__end_of_permanent_fixed_addresses << PAGE_SHIFT)
-#define FIXADDR_START	(FIXADDR_TOP - __FIXADDR_SIZE)
+#define __FIXADDR_BOOT_SIZE	(__end_of_fixed_addresses << PAGE_SHIFT)
+#define FIXADDR_START		(FIXADDR_TOP - __FIXADDR_SIZE)
+#define FIXADDR_BOOT_START	(FIXADDR_TOP - __FIXADDR_BOOT_SIZE)
 
 #define __fix_to_virt(x)	(FIXADDR_TOP - ((x) << PAGE_SHIFT))
 #define __virt_to_fix(x)	((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT)
diff -Nru a/include/asm-i386/highmem.h b/include/asm-i386/highmem.h
--- a/include/asm-i386/highmem.h	2005-03-01 23:38:52 -08:00
+++ b/include/asm-i386/highmem.h	2005-03-01 23:38:52 -08:00
@@ -40,16 +40,27 @@
  * easily, subsequent pte tables have to be allocated in one physical
  * chunk of RAM.
  */
-#if NR_CPUS <= 32
-#define PKMAP_BASE (0xff800000UL)
-#else
-#define PKMAP_BASE (0xff600000UL)
-#endif
 #ifdef CONFIG_X86_PAE
 #define LAST_PKMAP 512
 #else
 #define LAST_PKMAP 1024
 #endif
+/*
+ * Ordering is:
+ *
+ * FIXADDR_TOP
+ * 			fixed_addresses
+ * FIXADDR_START
+ * 			temp fixed addresses
+ * FIXADDR_BOOT_START
+ * 			Persistent kmap area
+ * PKMAP_BASE
+ * VMALLOC_END
+ * 			Vmalloc area
+ * VMALLOC_START
+ * high_memory
+ */
+#define PKMAP_BASE ( (FIXADDR_BOOT_START - PAGE_SIZE*(LAST_PKMAP + 1)) & PMD_MASK )
 #define LAST_PKMAP_MASK (LAST_PKMAP-1)
 #define PKMAP_NR(virt)  ((virt-PKMAP_BASE) >> PAGE_SHIFT)
 #define PKMAP_ADDR(nr)  (PKMAP_BASE + ((nr) << PAGE_SHIFT))
diff -Nru a/include/asm-i386/kprobes.h b/include/asm-i386/kprobes.h
--- a/include/asm-i386/kprobes.h	2005-03-01 23:39:07 -08:00
+++ b/include/asm-i386/kprobes.h	2005-03-01 23:39:07 -08:00
@@ -38,6 +38,8 @@
 	? (MAX_STACK_SIZE) \
 	: (((unsigned long)current_thread_info()) + THREAD_SIZE - (ADDR)))
 
+#define JPROBE_ENTRY(pentry)	(kprobe_opcode_t *)pentry
+
 /* Architecture specific copy of original instruction*/
 struct arch_specific_insn {
 	/* copy of the original instruction */
diff -Nru 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	2005-03-01 23:38:56 -08:00
+++ b/include/asm-i386/mach-numaq/mach_apic.h	2005-03-01 23:38:56 -08:00
@@ -3,6 +3,7 @@
 
 #include <asm/io.h>
 #include <linux/mmzone.h>
+#include <linux/nodemask.h>
 
 #define APIC_DFR_VALUE	(APIC_DFR_CLUSTER)
 
@@ -112,13 +113,15 @@
 
 static inline void setup_portio_remap(void)
 {
-	if (numnodes <= 1)
+	int num_quads = num_online_nodes();
+
+	if (num_quads <= 1)
        		return;
 
-	printk("Remapping cross-quad port I/O for %d quads\n", numnodes);
-	xquad_portio = ioremap (XQUAD_PORTIO_BASE, numnodes*XQUAD_PORTIO_QUAD);
+	printk("Remapping cross-quad port I/O for %d quads\n", num_quads);
+	xquad_portio = ioremap(XQUAD_PORTIO_BASE, num_quads*XQUAD_PORTIO_QUAD);
 	printk("xquad_portio vaddr 0x%08lx, len %08lx\n",
-		(u_long) xquad_portio, (u_long) numnodes*XQUAD_PORTIO_QUAD);
+		(u_long) xquad_portio, (u_long) num_quads*XQUAD_PORTIO_QUAD);
 }
 
 static inline int check_phys_apicid_present(int boot_cpu_physical_apicid)
diff -Nru a/include/asm-i386/mca.h b/include/asm-i386/mca.h
--- a/include/asm-i386/mca.h	2005-03-01 23:38:56 -08:00
+++ b/include/asm-i386/mca.h	2005-03-01 23:38:56 -08:00
@@ -40,7 +40,4 @@
  */
 #define MCA_NUMADAPTERS (MCA_MAX_SLOT_NR+3)
 
-/* lock to protect access to the MCA registers */
-extern spinlock_t mca_lock;
-
 #endif
diff -Nru a/include/asm-i386/mmzone.h b/include/asm-i386/mmzone.h
--- a/include/asm-i386/mmzone.h	2005-03-01 23:38:57 -08:00
+++ b/include/asm-i386/mmzone.h	2005-03-01 23:38:57 -08:00
@@ -48,12 +48,6 @@
 #endif
 }
 
-static inline struct pglist_data *pfn_to_pgdat(unsigned long pfn)
-{
-	return(NODE_DATA(pfn_to_nid(pfn)));
-}
-
-
 /*
  * Following are macros that are specific to this numa platform.
  */
@@ -116,7 +110,6 @@
 	(unsigned long)(__page - __zone->zone_mem_map)			\
 		+ __zone->zone_start_pfn;				\
 })
-#define pmd_page(pmd)		(pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT))
 
 #ifdef CONFIG_X86_NUMAQ            /* we have contiguous memory on NUMA-Q */
 #define pfn_valid(pfn)          ((pfn) < num_physpages)
diff -Nru a/include/asm-i386/page.h b/include/asm-i386/page.h
--- a/include/asm-i386/page.h	2005-03-01 23:38:53 -08:00
+++ b/include/asm-i386/page.h	2005-03-01 23:38:53 -08:00
@@ -36,6 +36,9 @@
 #define clear_user_page(page, vaddr, pg)	clear_page(page)
 #define copy_user_page(to, from, vaddr, pg)	copy_page(to, from)
 
+#define alloc_zeroed_user_highpage(vma, vaddr) alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO, vma, vaddr)
+#define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE
+
 /*
  * These are used to make use of C type-checking..
  */
@@ -46,11 +49,12 @@
 typedef struct { unsigned long long pmd; } pmd_t;
 typedef struct { unsigned long long pgd; } pgd_t;
 typedef struct { unsigned long long pgprot; } pgprot_t;
+#define pmd_val(x)	((x).pmd)
 #define pte_val(x)	((x).pte_low | ((unsigned long long)(x).pte_high << 32))
+#define __pmd(x) ((pmd_t) { (x) } )
 #define HPAGE_SHIFT	21
 #else
 typedef struct { unsigned long pte_low; } pte_t;
-typedef struct { unsigned long pmd; } pmd_t;
 typedef struct { unsigned long pgd; } pgd_t;
 typedef struct { unsigned long pgprot; } pgprot_t;
 #define boot_pte_t pte_t /* or would you rather have a typedef */
@@ -66,13 +70,10 @@
 #define HAVE_ARCH_HUGETLB_UNMAPPED_AREA
 #endif
 
-
-#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) } )
 
diff -Nru a/include/asm-i386/pgalloc.h b/include/asm-i386/pgalloc.h
--- a/include/asm-i386/pgalloc.h	2005-03-01 23:38:52 -08:00
+++ b/include/asm-i386/pgalloc.h	2005-03-01 23:38:52 -08:00
@@ -10,16 +10,13 @@
 #define pmd_populate_kernel(mm, pmd, pte) \
 		set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte)))
 
-static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, struct page *pte)
-{
-	set_pmd(pmd, __pmd(_PAGE_TABLE +
-		((unsigned long long)page_to_pfn(pte) <<
-			(unsigned long long) PAGE_SHIFT)));
-}
+#define pmd_populate(mm, pmd, pte) 				\
+	set_pmd(pmd, __pmd(_PAGE_TABLE +			\
+		((unsigned long long)page_to_pfn(pte) <<	\
+			(unsigned long long) PAGE_SHIFT)))
 /*
  * Allocate and free page tables.
  */
-
 extern pgd_t *pgd_alloc(struct mm_struct *);
 extern void pgd_free(pgd_t *pgd);
 
@@ -39,16 +36,15 @@
 
 #define __pte_free_tlb(tlb,pte) tlb_remove_page((tlb),(pte))
 
+#ifdef CONFIG_X86_PAE
 /*
- * allocating and freeing a pmd is trivial: the 1-entry pmd is
- * inside the pgd, so has no extra memory associated with it.
- * (In the PAE case we free the pmds as part of the pgd.)
+ * In the PAE case we free the pmds as part of the pgd.
  */
-
 #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 pud_populate(mm, pmd, pte)	BUG()
+#endif
 
 #define check_pgt_cache()	do { } while (0)
 
diff -Nru a/include/asm-i386/pgtable-2level-defs.h b/include/asm-i386/pgtable-2level-defs.h
--- a/include/asm-i386/pgtable-2level-defs.h	2005-03-01 23:39:09 -08:00
+++ b/include/asm-i386/pgtable-2level-defs.h	2005-03-01 23:39:09 -08:00
@@ -12,8 +12,6 @@
  * the i386 is two-level, so we don't really have any
  * PMD directory physically.
  */
-#define PMD_SHIFT	22
-#define PTRS_PER_PMD	1
 
 #define PTRS_PER_PTE	1024
 
diff -Nru a/include/asm-i386/pgtable-2level.h b/include/asm-i386/pgtable-2level.h
--- a/include/asm-i386/pgtable-2level.h	2005-03-01 23:38:58 -08:00
+++ b/include/asm-i386/pgtable-2level.h	2005-03-01 23:38:58 -08:00
@@ -1,44 +1,22 @@
 #ifndef _I386_PGTABLE_2LEVEL_H
 #define _I386_PGTABLE_2LEVEL_H
 
+#include <asm-generic/pgtable-nopmd.h>
+
 #define pte_ERROR(e) \
 	printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, (e).pte_low)
-#define pmd_ERROR(e) \
-	printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e))
 #define pgd_ERROR(e) \
 	printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))
 
 /*
- * 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)
- */
-static inline int pgd_none(pgd_t pgd)		{ return 0; }
-static inline int pgd_bad(pgd_t pgd)		{ return 0; }
-static inline int pgd_present(pgd_t pgd)	{ return 1; }
-#define pgd_clear(xp)				do { } while (0)
-
-/*
  * Certain architectures need to do special things when PTEs
  * within a page table are directly modified.  Thus, the following
  * hook is made available.
  */
 #define set_pte(pteptr, pteval) (*(pteptr) = pteval)
 #define set_pte_atomic(pteptr, pteval) set_pte(pteptr,pteval)
-/*
- * (pmds are folded into pgds so this doesn't get actually called,
- * 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 pgd_page(pgd) \
-((unsigned long) __va(pgd_val(pgd) & PAGE_MASK))
+#define set_pmd(pmdptr, pmdval) (*(pmdptr) = (pmdval))
 
-static inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
-{
-	return (pmd_t *) dir;
-}
 #define ptep_get_and_clear(xp)	__pte(xchg(&(xp)->pte_low, 0))
 #define pte_same(a, b)		((a).pte_low == (b).pte_low)
 #define pte_page(x)		pfn_to_page(pte_pfn(x))
@@ -46,6 +24,11 @@
 #define pte_pfn(x)		((unsigned long)(((x).pte_low >> PAGE_SHIFT)))
 #define pfn_pte(pfn, prot)	__pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
 #define pfn_pmd(pfn, prot)	__pmd(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
+
+#define pmd_page(pmd) (pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT))
+
+#define pmd_page_kernel(pmd) \
+((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
 
 /*
  * All present user pages are user-executable:
diff -Nru a/include/asm-i386/pgtable-3level.h b/include/asm-i386/pgtable-3level.h
--- a/include/asm-i386/pgtable-3level.h	2005-03-01 23:39:09 -08:00
+++ b/include/asm-i386/pgtable-3level.h	2005-03-01 23:39:09 -08:00
@@ -1,6 +1,8 @@
 #ifndef _I386_PGTABLE_3LEVEL_H
 #define _I386_PGTABLE_3LEVEL_H
 
+#include <asm-generic/pgtable-nopud.h>
+
 /*
  * Intel Physical Address Extension (PAE) Mode - three-level page
  * tables on PPro+ CPUs.
@@ -15,9 +17,9 @@
 #define pgd_ERROR(e) \
 	printk("%s:%d: bad pgd %p(%016Lx).\n", __FILE__, __LINE__, &(e), pgd_val(e))
 
-static inline int pgd_none(pgd_t pgd)		{ return 0; }
-static inline int pgd_bad(pgd_t pgd)		{ return 0; }
-static inline int pgd_present(pgd_t pgd)	{ return 1; }
+#define pud_none(pud)				0
+#define pud_bad(pud)				0
+#define pud_present(pud)			1
 
 /*
  * Is the pte executable?
@@ -59,8 +61,8 @@
 		set_64bit((unsigned long long *)(pteptr),pte_val(pteval))
 #define set_pmd(pmdptr,pmdval) \
 		set_64bit((unsigned long long *)(pmdptr),pmd_val(pmdval))
-#define set_pgd(pgdptr,pgdval) \
-		set_64bit((unsigned long long *)(pgdptr),pgd_val(pgdval))
+#define set_pud(pudptr,pudval) \
+		set_64bit((unsigned long long *)(pudptr),pud_val(pudval))
 
 /*
  * Pentium-II erratum A13: in PAE mode we explicitly have to flush
@@ -68,13 +70,22 @@
  * We do not let the generic code free and clear pgd entries due to
  * this erratum.
  */
-static inline void pgd_clear (pgd_t * pgd) { }
+static inline void pud_clear (pud_t * pud) { }
+
+#define pmd_page(pmd) (pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT))
+
+#define pmd_page_kernel(pmd) \
+((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
+
+#define pud_page(pud) \
+((struct page *) __va(pud_val(pud) & PAGE_MASK))
+
+#define pud_page_kernel(pud) \
+((unsigned long) __va(pud_val(pud) & PAGE_MASK))
 
-#define pgd_page(pgd) \
-((unsigned long) __va(pgd_val(pgd) & PAGE_MASK))
 
 /* Find an entry in the second-level page table.. */
-#define pmd_offset(dir, address) ((pmd_t *) pgd_page(*(dir)) + \
+#define pmd_offset(pud, address) ((pmd_t *) pud_page(*(pud)) + \
 			pmd_index(address))
 
 static inline pte_t ptep_get_and_clear(pte_t *ptep)
@@ -141,5 +152,7 @@
 #define __swp_entry(type, offset)	((swp_entry_t){(type) | (offset) << 5})
 #define __pte_to_swp_entry(pte)		((swp_entry_t){ (pte).pte_high })
 #define __swp_entry_to_pte(x)		((pte_t){ 0, (x).val })
+
+#define __pmd_free_tlb(tlb, x)		do { } while (0)
 
 #endif /* _I386_PGTABLE_3LEVEL_H */
diff -Nru a/include/asm-i386/pgtable.h b/include/asm-i386/pgtable.h
--- a/include/asm-i386/pgtable.h	2005-03-01 23:39:08 -08:00
+++ b/include/asm-i386/pgtable.h	2005-03-01 23:39:08 -08:00
@@ -50,12 +50,12 @@
  */
 #ifdef CONFIG_X86_PAE
 # include <asm/pgtable-3level-defs.h>
+# define PMD_SIZE	(1UL << PMD_SHIFT)
+# define PMD_MASK	(~(PMD_SIZE-1))
 #else
 # include <asm/pgtable-2level-defs.h>
 #endif
 
-#define PMD_SIZE	(1UL << PMD_SHIFT)
-#define PMD_MASK	(~(PMD_SIZE-1))
 #define PGDIR_SIZE	(1UL << PGDIR_SHIFT)
 #define PGDIR_MASK	(~(PGDIR_SIZE-1))
 
@@ -293,15 +293,8 @@
 
 #define page_pte(page) page_pte_prot(page, __pgprot(0))
 
-#define pmd_page_kernel(pmd) \
-((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
-
-#ifndef CONFIG_DISCONTIGMEM
-#define pmd_page(pmd) (pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT))
-#endif /* !CONFIG_DISCONTIGMEM */
-
 #define pmd_large(pmd) \
-	((pmd_val(pmd) & (_PAGE_PSE|_PAGE_PRESENT)) == (_PAGE_PSE|_PAGE_PRESENT))
+((pmd_val(pmd) & (_PAGE_PSE|_PAGE_PRESENT)) == (_PAGE_PSE|_PAGE_PRESENT))
 
 /*
  * the pgd page can be thought of an array like this: pgd_t[PTRS_PER_PGD]
@@ -310,6 +303,7 @@
  * control the given virtual address
  */
 #define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
+#define pgd_index_k(addr) pgd_index(addr)
 
 /*
  * pgd_offset() returns a (pgd_t *)
@@ -362,6 +356,8 @@
 #else
  static inline int set_kernel_exec(unsigned long vaddr, int enable) { return 0;}
 #endif
+
+extern void noexec_setup(const char *str);
 
 #if defined(CONFIG_HIGHPTE)
 #define pte_offset_map(dir, address) \
diff -Nru a/include/asm-i386/processor.h b/include/asm-i386/processor.h
--- a/include/asm-i386/processor.h	2005-03-01 23:38:51 -08:00
+++ b/include/asm-i386/processor.h	2005-03-01 23:38:51 -08:00
@@ -65,6 +65,7 @@
 	int	f00f_bug;
 	int	coma_bug;
 	unsigned long loops_per_jiffy;
+	unsigned char x86_num_cores;
 } __attribute__((__aligned__(SMP_CACHE_BYTES)));
 
 #define X86_VENDOR_INTEL 0
@@ -96,6 +97,7 @@
 #define current_cpu_data boot_cpu_data
 #endif
 
+extern	int phys_proc_id[NR_CPUS];
 extern char ignore_fpu_irq;
 
 extern void identify_cpu(struct cpuinfo_x86 *);
@@ -103,6 +105,12 @@
 extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c);
 extern void dodgy_tsc(void);
 
+#ifdef CONFIG_X86_HT
+extern void detect_ht(struct cpuinfo_x86 *c);
+#else
+static inline void detect_ht(struct cpuinfo_x86 *c) {}
+#endif
+
 /*
  * EFLAGS bits
  */
@@ -126,6 +134,8 @@
 
 /*
  * Generic CPUID function
+ * clear %ecx since some cpus (Cyrix MII) do not set or clear %ecx
+ * resulting in stale register contents being returned.
  */
 static inline void cpuid(int op, int *eax, int *ebx, int *ecx, int *edx)
 {
@@ -134,7 +144,7 @@
 		  "=b" (*ebx),
 		  "=c" (*ecx),
 		  "=d" (*edx)
-		: "0" (op));
+		: "0" (op), "c"(0));
 }
 
 /*
@@ -259,11 +269,6 @@
 	outb((data), 0x23); \
 } while (0)
 
-/*
- * Bus types (default is ISA, but people can check others with these..)
- */
-extern int MCA_bus;
-
 static inline void __monitor(const void *eax, unsigned long ecx,
 		unsigned long edx)
 {
@@ -287,6 +292,9 @@
 extern unsigned int machine_submodel_id;
 extern unsigned int BIOS_revision;
 extern unsigned int mca_pentium_flag;
+
+/* Boot loader type from the setup header */
+extern int bootloader_type;
 
 /*
  * User space process size: 3GB (default).
diff -Nru a/include/asm-i386/ptrace.h b/include/asm-i386/ptrace.h
--- a/include/asm-i386/ptrace.h	2005-03-01 23:38:52 -08:00
+++ b/include/asm-i386/ptrace.h	2005-03-01 23:38:52 -08:00
@@ -55,6 +55,8 @@
 #define PTRACE_SET_THREAD_AREA    26
 
 #ifdef __KERNEL__
+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))
 #define instruction_pointer(regs) ((regs)->eip)
 #if defined(CONFIG_SMP) && defined(CONFIG_FRAME_POINTER)
diff -Nru a/include/asm-i386/resource.h b/include/asm-i386/resource.h
--- a/include/asm-i386/resource.h	2005-03-01 23:39:18 -08:00
+++ b/include/asm-i386/resource.h	2005-03-01 23:39:18 -08:00
@@ -1,52 +1,6 @@
 #ifndef _I386_RESOURCE_H
 #define _I386_RESOURCE_H
 
-/*
- * Resource limits
- */
-
-#define RLIMIT_CPU	0		/* CPU time in ms */
-#define RLIMIT_FSIZE	1		/* Maximum filesize */
-#define RLIMIT_DATA	2		/* max data size */
-#define RLIMIT_STACK	3		/* max stack size */
-#define RLIMIT_CORE	4		/* max core file size */
-#define RLIMIT_RSS	5		/* max resident set size */
-#define RLIMIT_NPROC	6		/* max number of processes */
-#define RLIMIT_NOFILE	7		/* max number of open files */
-#define RLIMIT_MEMLOCK	8		/* max locked-in-memory address space */
-#define RLIMIT_AS	9		/* address space limit */
-#define RLIMIT_LOCKS	10		/* maximum file locks held */
-#define RLIMIT_SIGPENDING 11		/* max number of pending signals */
-#define RLIMIT_MSGQUEUE 12		/* maximum bytes in POSIX mqueues */
-
-#define RLIM_NLIMITS	13
-
-
-/*
- * SuS says limits have to be unsigned.
- * Which makes a ton more sense anyway.
- */
-#define RLIM_INFINITY	(~0UL)
-
-#ifdef __KERNEL__
-
-#define INIT_RLIMITS					\
-{							\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{      _STK_LIM, RLIM_INFINITY },		\
-	{             0, RLIM_INFINITY },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{             0,             0 },		\
-	{      INR_OPEN,     INR_OPEN  },		\
-	{   MLOCK_LIMIT,   MLOCK_LIMIT },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{ MAX_SIGPENDING, MAX_SIGPENDING },		\
-	{ MQ_BYTES_MAX, MQ_BYTES_MAX },			\
-}
-
-#endif /* __KERNEL__ */
+#include <asm-generic/resource.h>
 
 #endif
diff -Nru a/include/asm-i386/smp.h b/include/asm-i386/smp.h
--- a/include/asm-i386/smp.h	2005-03-01 23:39:18 -08:00
+++ b/include/asm-i386/smp.h	2005-03-01 23:39:18 -08:00
@@ -50,9 +50,10 @@
  * 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 __smp_processor_id() (current_thread_info()->cpu)
 
 extern cpumask_t cpu_callout_map;
+extern cpumask_t cpu_callin_map;
 #define cpu_possible_map cpu_callout_map
 
 /* We don't mark CPUs online until __cpu_up(), so we need another measure */
diff -Nru a/include/asm-i386/spinlock.h b/include/asm-i386/spinlock.h
--- a/include/asm-i386/spinlock.h	2005-03-01 23:38:54 -08:00
+++ b/include/asm-i386/spinlock.h	2005-03-01 23:38:54 -08:00
@@ -15,10 +15,13 @@
  */
 
 typedef struct {
-	volatile unsigned int lock;
+	volatile unsigned int slock;
 #ifdef CONFIG_DEBUG_SPINLOCK
 	unsigned magic;
 #endif
+#ifdef CONFIG_PREEMPT
+	unsigned int break_lock;
+#endif
 } spinlock_t;
 
 #define SPINLOCK_MAGIC	0xdead4ead
@@ -40,7 +43,7 @@
  * We make no fairness assumptions. They have a cost.
  */
 
-#define spin_is_locked(x)	(*(volatile signed char *)(&(x)->lock) <= 0)
+#define spin_is_locked(x)	(*(volatile signed char *)(&(x)->slock) <= 0)
 #define spin_unlock_wait(x)	do { barrier(); } while(spin_is_locked(x))
 
 #define spin_lock_string \
@@ -75,12 +78,12 @@
  * (except on PPro SMP or if we are using OOSTORE)
  * (PPro errata 66, 92)
  */
- 
+
 #if !defined(CONFIG_X86_OOSTORE) && !defined(CONFIG_X86_PPRO_FENCE)
 
 #define spin_unlock_string \
 	"movb $1,%0" \
-		:"=m" (lock->lock) : : "memory"
+		:"=m" (lock->slock) : : "memory"
 
 
 static inline void _raw_spin_unlock(spinlock_t *lock)
@@ -98,7 +101,7 @@
 
 #define spin_unlock_string \
 	"xchgb %b0, %1" \
-		:"=q" (oldval), "=m" (lock->lock) \
+		:"=q" (oldval), "=m" (lock->slock) \
 		:"0" (oldval) : "memory"
 
 static inline void _raw_spin_unlock(spinlock_t *lock)
@@ -120,7 +123,7 @@
 	char oldval;
 	__asm__ __volatile__(
 		"xchgb %b0,%1"
-		:"=q" (oldval), "=m" (lock->lock)
+		:"=q" (oldval), "=m" (lock->slock)
 		:"0" (0) : "memory");
 	return oldval > 0;
 }
@@ -135,7 +138,7 @@
 #endif
 	__asm__ __volatile__(
 		spin_lock_string
-		:"=m" (lock->lock) : : "memory");
+		:"=m" (lock->slock) : : "memory");
 }
 
 static inline void _raw_spin_lock_flags (spinlock_t *lock, unsigned long flags)
@@ -148,7 +151,7 @@
 #endif
 	__asm__ __volatile__(
 		spin_lock_string_flags
-		:"=m" (lock->lock) : "r" (flags) : "memory");
+		:"=m" (lock->slock) : "r" (flags) : "memory");
 }
 
 /*
@@ -166,6 +169,9 @@
 #ifdef CONFIG_DEBUG_SPINLOCK
 	unsigned magic;
 #endif
+#ifdef CONFIG_PREEMPT
+	unsigned int break_lock;
+#endif
 } rwlock_t;
 
 #define RWLOCK_MAGIC	0xdeaf1eed
@@ -180,7 +186,17 @@
 
 #define rwlock_init(x)	do { *(x) = RW_LOCK_UNLOCKED; } while(0)
 
-#define rwlock_is_locked(x) ((x)->lock != RW_LOCK_BIAS)
+/**
+ * read_can_lock - would read_trylock() succeed?
+ * @lock: the rwlock in question.
+ */
+#define read_can_lock(x) ((int)(x)->lock > 0)
+
+/**
+ * write_can_lock - would write_trylock() succeed?
+ * @lock: the rwlock in question.
+ */
+#define write_can_lock(x) ((x)->lock == RW_LOCK_BIAS)
 
 /*
  * On x86, we implement read-write locks as a 32-bit counter
@@ -211,6 +227,16 @@
 
 #define _raw_read_unlock(rw)		asm volatile("lock ; incl %0" :"=m" ((rw)->lock) : : "memory")
 #define _raw_write_unlock(rw)	asm volatile("lock ; addl $" RW_LOCK_BIAS_STR ",%0":"=m" ((rw)->lock) : : "memory")
+
+static inline int _raw_read_trylock(rwlock_t *lock)
+{
+	atomic_t *count = (atomic_t *)lock;
+	atomic_dec(count);
+	if (atomic_read(count) >= 0)
+		return 1;
+	atomic_inc(count);
+	return 0;
+}
 
 static inline int _raw_write_trylock(rwlock_t *lock)
 {
diff -Nru a/include/asm-i386/string.h b/include/asm-i386/string.h
--- a/include/asm-i386/string.h	2005-03-01 23:39:17 -08:00
+++ b/include/asm-i386/string.h	2005-03-01 23:39:17 -08:00
@@ -25,7 +25,6 @@
 
 /* AK: in fact I bet it would be better to move this stuff all out of line.
  */
-#if !defined(IN_STRING_C)
 
 #define __HAVE_ARCH_STRCPY
 static inline char * strcpy(char * dest,const char *src)
@@ -179,8 +178,6 @@
 	:"=g" (__res), "=&S" (d0), "=&a" (d1) :"0" (0),"1" (s),"2" (c));
 return __res;
 }
-
-#endif
 
 #define __HAVE_ARCH_STRLEN
 static inline size_t strlen(const char * s)
diff -Nru a/include/asm-i386/system.h b/include/asm-i386/system.h
--- a/include/asm-i386/system.h	2005-03-01 23:38:44 -08:00
+++ b/include/asm-i386/system.h	2005-03-01 23:38:44 -08:00
@@ -466,5 +466,6 @@
 void enable_hlt(void);
 
 extern int es7000_plat;
+void cpu_idle_wait(void);
 
 #endif
diff -Nru a/include/asm-i386/thread_info.h b/include/asm-i386/thread_info.h
--- a/include/asm-i386/thread_info.h	2005-03-01 23:38:52 -08:00
+++ b/include/asm-i386/thread_info.h	2005-03-01 23:38:52 -08:00
@@ -141,6 +141,7 @@
 #define TIF_IRET		5	/* return with iret */
 #define TIF_SYSCALL_AUDIT	7	/* syscall auditing active */
 #define TIF_POLLING_NRFLAG	16	/* true if poll_idle() is polling TIF_NEED_RESCHED */
+#define TIF_MEMDIE		17
 
 #define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE)
 #define _TIF_NOTIFY_RESUME	(1<<TIF_NOTIFY_RESUME)
diff -Nru a/include/asm-i386/topology.h b/include/asm-i386/topology.h
--- a/include/asm-i386/topology.h	2005-03-01 23:38:53 -08:00
+++ b/include/asm-i386/topology.h	2005-03-01 23:38:53 -08:00
@@ -66,9 +66,6 @@
 	return node_to_cpumask(mp_bus_id_to_node[bus]);
 }
 
-/* Node-to-Node distance */
-#define node_distance(from, to) ((from) != (to))
-
 /* sched_domains SD_NODE_INIT for NUMAQ machines */
 #define SD_NODE_INIT (struct sched_domain) {		\
 	.span			= CPU_MASK_NONE,	\
@@ -78,11 +75,13 @@
 	.max_interval		= 32,			\
 	.busy_factor		= 32,			\
 	.imbalance_pct		= 125,			\
-	.cache_hot_time		= (10*1000),		\
+	.cache_hot_time		= (10*1000000),		\
 	.cache_nice_tries	= 1,			\
 	.per_cpu_gain		= 100,			\
 	.flags			= SD_LOAD_BALANCE	\
 				| SD_BALANCE_EXEC	\
+				| SD_BALANCE_NEWIDLE	\
+				| SD_WAKE_IDLE		\
 				| SD_WAKE_BALANCE,	\
 	.last_balance		= jiffies,		\
 	.balance_interval	= 1,			\
diff -Nru a/include/asm-i386/uaccess.h b/include/asm-i386/uaccess.h
--- a/include/asm-i386/uaccess.h	2005-03-01 23:38:53 -08:00
+++ b/include/asm-i386/uaccess.h	2005-03-01 23:38:53 -08:00
@@ -170,7 +170,8 @@
  * On error, the variable @x is set to zero.
  */
 #define get_user(x,ptr)							\
-({	int __ret_gu,__val_gu;						\
+({	int __ret_gu;							\
+	unsigned long __val_gu;						\
 	__chk_user_ptr(ptr);						\
 	switch(sizeof (*(ptr))) {					\
 	case 1:  __get_user_x(1,__ret_gu,__val_gu,ptr); break;		\
@@ -313,7 +314,7 @@
 
 #endif
 struct __large_struct { unsigned long buf[100]; };
-#define __m(x) (*(struct __large_struct *)(x))
+#define __m(x) (*(struct __large_struct __user *)(x))
 
 /*
  * Tell gcc we read from memory instead of writing: this is because
@@ -338,7 +339,8 @@
 
 #define __get_user_nocheck(x,ptr,size)				\
 ({								\
-	long __gu_err, __gu_val;				\
+	long __gu_err;						\
+	unsigned long __gu_val;					\
 	__get_user_size(__gu_val,(ptr),(size),__gu_err,-EFAULT);\
 	(x) = (__typeof__(*(ptr)))__gu_val;			\
 	__gu_err;						\
diff -Nru a/include/asm-ia64/acpi.h b/include/asm-ia64/acpi.h
--- a/include/asm-ia64/acpi.h	2005-03-01 23:39:09 -08:00
+++ b/include/asm-ia64/acpi.h	2005-03-01 23:39:09 -08:00
@@ -101,7 +101,7 @@
 #ifdef CONFIG_ACPI_NUMA
 /* Proximity bitmap length; _PXM is at most 255 (8 bit)*/
 #define MAX_PXM_DOMAINS (256)
-extern int __initdata pxm_to_nid_map[MAX_PXM_DOMAINS];
+extern int __devinitdata pxm_to_nid_map[MAX_PXM_DOMAINS];
 extern int __initdata nid_to_pxm_map[MAX_NUMNODES];
 #endif
 
diff -Nru a/include/asm-ia64/bitops.h b/include/asm-ia64/bitops.h
--- a/include/asm-ia64/bitops.h	2005-03-01 23:39:16 -08:00
+++ b/include/asm-ia64/bitops.h	2005-03-01 23:39:16 -08:00
@@ -359,7 +359,7 @@
 
 #endif /* __KERNEL__ */
 
-extern int __find_next_zero_bit (void *addr, unsigned long size,
+extern int __find_next_zero_bit (const void *addr, unsigned long size,
 			unsigned long offset);
 extern int __find_next_bit(const void *addr, unsigned long size,
 			unsigned long offset);
diff -Nru a/include/asm-ia64/cpu.h b/include/asm-ia64/cpu.h
--- a/include/asm-ia64/cpu.h	2005-03-01 23:39:10 -08:00
+++ b/include/asm-ia64/cpu.h	2005-03-01 23:39:10 -08:00
@@ -14,4 +14,9 @@
 
 DECLARE_PER_CPU(int, cpu_state);
 
+extern int arch_register_cpu(int num);
+#ifdef CONFIG_HOTPLUG_CPU
+extern void arch_unregister_cpu(int);
+#endif
+
 #endif /* _ASM_IA64_CPU_H_ */
diff -Nru a/include/asm-ia64/cputime.h b/include/asm-ia64/cputime.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-ia64/cputime.h	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,6 @@
+#ifndef __IA64_CPUTIME_H
+#define __IA64_CPUTIME_H
+
+#include <asm-generic/cputime.h>
+
+#endif /* __IA64_CPUTIME_H */
diff -Nru a/include/asm-ia64/elf.h b/include/asm-ia64/elf.h
--- a/include/asm-ia64/elf.h	2005-03-01 23:39:07 -08:00
+++ b/include/asm-ia64/elf.h	2005-03-01 23:39:07 -08:00
@@ -186,8 +186,8 @@
 
 #ifdef __KERNEL__
 #define SET_PERSONALITY(ex, ibcs2)	set_personality(PER_LINUX)
-#define elf_read_implies_exec(ex, have_pt_gnu_stack)					\
-	(!(have_pt_gnu_stack) && ((ex).e_flags & EF_IA_64_LINUX_EXECUTABLE_STACK) != 0)
+#define elf_read_implies_exec(ex, executable_stack)					\
+	((executable_stack!=EXSTACK_DISABLE_X) && ((ex).e_flags & EF_IA_64_LINUX_EXECUTABLE_STACK) != 0)
 
 struct task_struct;
 
diff -Nru a/include/asm-ia64/hardirq.h b/include/asm-ia64/hardirq.h
--- a/include/asm-ia64/hardirq.h	2005-03-01 23:38:54 -08:00
+++ b/include/asm-ia64/hardirq.h	2005-03-01 23:38:54 -08:00
@@ -19,7 +19,6 @@
 
 #define __ARCH_IRQ_STAT	1
 
-#define softirq_pending(cpu)		(cpu_data(cpu)->softirq_pending)
 #define local_softirq_pending()		(local_cpu_data->softirq_pending)
 
 #define HARDIRQ_BITS	14
@@ -33,5 +32,7 @@
 #endif
 
 extern void __iomem *ipi_base_addr;
+
+void ack_bad_irq(unsigned int irq);
 
 #endif /* _ASM_IA64_HARDIRQ_H */
diff -Nru a/include/asm-ia64/hw_irq.h b/include/asm-ia64/hw_irq.h
--- a/include/asm-ia64/hw_irq.h	2005-03-01 23:38:57 -08:00
+++ b/include/asm-ia64/hw_irq.h	2005-03-01 23:38:57 -08:00
@@ -50,6 +50,7 @@
  */
 #define IA64_FIRST_DEVICE_VECTOR	0x30
 #define IA64_LAST_DEVICE_VECTOR		0xe7
+#define IA64_NUM_DEVICE_VECTORS		(IA64_LAST_DEVICE_VECTOR - IA64_FIRST_DEVICE_VECTOR + 1)
 
 #define IA64_MCA_RENDEZ_VECTOR		0xe8	/* MCA rendez interrupt */
 #define IA64_PERFMON_VECTOR		0xee	/* performanc monitor interrupt vector */
@@ -81,6 +82,7 @@
 extern struct hw_interrupt_type irq_type_ia64_lsapic;	/* CPU-internal interrupt controller */
 
 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);
 extern void register_percpu_irq (ia64_vector vec, struct irqaction *action);
 
@@ -94,21 +96,9 @@
  * Default implementations for the irq-descriptor API:
  */
 
-extern irq_desc_t _irq_desc[NR_IRQS];
+extern irq_desc_t irq_desc[NR_IRQS];
 
 #ifndef CONFIG_IA64_GENERIC
-static inline irq_desc_t *
-__ia64_irq_desc (unsigned int irq)
-{
-	return _irq_desc + irq;
-}
-
-static inline ia64_vector
-__ia64_irq_to_vector (unsigned int irq)
-{
-	return (ia64_vector) irq;
-}
-
 static inline unsigned int
 __ia64_local_vector_to_irq (ia64_vector vec)
 {
@@ -130,14 +120,14 @@
 static inline irq_desc_t *
 irq_descp (int irq)
 {
-	return platform_irq_desc(irq);
+	return irq_desc + irq;
 }
 
 /* Extract the IA-64 vector that corresponds to IRQ.  */
 static inline ia64_vector
 irq_to_vector (int irq)
 {
-	return platform_irq_to_vector(irq);
+	return (ia64_vector) irq;
 }
 
 /*
diff -Nru a/include/asm-ia64/io.h b/include/asm-ia64/io.h
--- a/include/asm-ia64/io.h	2005-03-01 23:38:52 -08:00
+++ b/include/asm-ia64/io.h	2005-03-01 23:38:52 -08:00
@@ -447,14 +447,9 @@
 /*
  * String version of IO memory access ops:
  */
-extern void __ia64_memcpy_fromio (void *, volatile void __iomem *, long);
-extern void __ia64_memcpy_toio (volatile void __iomem *, void *, long);
-extern void __ia64_memset_c_io (volatile void __iomem *, unsigned long, long);
-
-#define memcpy_fromio(to,from,len)	__ia64_memcpy_fromio((to), (from),(len))
-#define memcpy_toio(to,from,len)	__ia64_memcpy_toio((to),(from),(len))
-#define memset_io(addr,c,len)		__ia64_memset_c_io((addr), 0x0101010101010101UL*(u8)(c), \
-							   (len))
+extern void memcpy_fromio(void *dst, const volatile void __iomem *src, long n);
+extern void memcpy_toio(volatile void __iomem *dst, const void *src, long n);
+extern void memset_io(volatile void __iomem *s, int c, long n);
 
 #define dma_cache_inv(_start,_size)             do { } while (0)
 #define dma_cache_wback(_start,_size)           do { } while (0)
diff -Nru a/include/asm-ia64/iosapic.h b/include/asm-ia64/iosapic.h
--- a/include/asm-ia64/iosapic.h	2005-03-01 23:38:58 -08:00
+++ b/include/asm-ia64/iosapic.h	2005-03-01 23:38:58 -08:00
@@ -78,6 +78,9 @@
 extern void iosapic_enable_intr (unsigned int vector);
 extern int iosapic_register_intr (unsigned int gsi, unsigned long polarity,
 				  unsigned long trigger);
+#ifdef CONFIG_ACPI_DEALLOCATE_IRQ
+extern void iosapic_unregister_intr (unsigned int irq);
+#endif
 extern void __init iosapic_override_isa_irq (unsigned int isa_irq, unsigned int gsi,
 				      unsigned long polarity,
 				      unsigned long trigger);
@@ -97,6 +100,7 @@
 #define iosapic_system_init(pcat_compat)			do { } while (0)
 #define iosapic_init(address,gsi_base)				do { } while (0)
 #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)
 #define iosapic_register_platform_intr(type,gsi,pmi,eid,id, \
 	polarity,trigger)					(gsi)
diff -Nru a/include/asm-ia64/kregs.h b/include/asm-ia64/kregs.h
--- a/include/asm-ia64/kregs.h	2005-03-01 23:38:53 -08:00
+++ b/include/asm-ia64/kregs.h	2005-03-01 23:38:53 -08:00
@@ -14,6 +14,7 @@
  */
 #define IA64_KR_IO_BASE		0	/* ar.k0: legacy I/O base address */
 #define IA64_KR_TSSD		1	/* ar.k1: IVE uses this as the TSSD */
+#define IA64_KR_PER_CPU_DATA	3	/* ar.k3: physical per-CPU base */
 #define IA64_KR_CURRENT_STACK	4	/* ar.k4: what's mapped in IA64_TR_CURRENT_STACK */
 #define IA64_KR_FPU_OWNER	5	/* ar.k5: fpu-owner (UP only, at the moment) */
 #define IA64_KR_CURRENT		6	/* ar.k6: "current" task pointer */
diff -Nru a/include/asm-ia64/machvec.h b/include/asm-ia64/machvec.h
--- a/include/asm-ia64/machvec.h	2005-03-01 23:38:58 -08:00
+++ b/include/asm-ia64/machvec.h	2005-03-01 23:38:58 -08:00
@@ -17,9 +17,9 @@
 struct device;
 struct pt_regs;
 struct scatterlist;
-struct irq_desc;
 struct page;
 struct mm_struct;
+struct pci_bus;
 
 typedef void ia64_mv_setup_t (char **);
 typedef void ia64_mv_cpu_init_t (void);
@@ -28,9 +28,12 @@
 typedef void ia64_mv_timer_interrupt_t (int, void *, struct pt_regs *);
 typedef void ia64_mv_global_tlb_purge_t (unsigned long, unsigned long, unsigned long);
 typedef void ia64_mv_tlb_migrate_finish_t (struct mm_struct *);
-typedef struct irq_desc *ia64_mv_irq_desc (unsigned int);
-typedef u8 ia64_mv_irq_to_vector (unsigned int);
 typedef unsigned int ia64_mv_local_vector_to_irq (u8);
+typedef char *ia64_mv_pci_get_legacy_mem_t (struct pci_bus *);
+typedef int ia64_mv_pci_legacy_read_t (struct pci_bus *, u16 port, u32 *val,
+				       u8 size);
+typedef int ia64_mv_pci_legacy_write_t (struct pci_bus *, u16 port, u32 val,
+					u8 size);
 
 /* DMA-mapping interface: */
 typedef void ia64_mv_dma_init (void);
@@ -94,6 +97,8 @@
 #  include <asm/machvec_dig.h>
 # elif defined (CONFIG_IA64_HP_ZX1)
 #  include <asm/machvec_hpzx1.h>
+# elif defined (CONFIG_IA64_HP_ZX1_SWIOTLB)
+#  include <asm/machvec_hpzx1_swiotlb.h>
 # elif defined (CONFIG_IA64_SGI_SN2)
 #  include <asm/machvec_sn2.h>
 # elif defined (CONFIG_IA64_GENERIC)
@@ -122,9 +127,10 @@
 #  define platform_dma_sync_sg_for_device ia64_mv.dma_sync_sg_for_device
 #  define platform_dma_mapping_error		ia64_mv.dma_mapping_error
 #  define platform_dma_supported	ia64_mv.dma_supported
-#  define platform_irq_desc		ia64_mv.irq_desc
-#  define platform_irq_to_vector	ia64_mv.irq_to_vector
 #  define platform_local_vector_to_irq	ia64_mv.local_vector_to_irq
+#  define platform_pci_get_legacy_mem	ia64_mv.pci_get_legacy_mem
+#  define platform_pci_legacy_read	ia64_mv.pci_legacy_read
+#  define platform_pci_legacy_write	ia64_mv.pci_legacy_write
 #  define platform_inb		ia64_mv.inb
 #  define platform_inw		ia64_mv.inw
 #  define platform_inl		ia64_mv.inl
@@ -169,9 +175,10 @@
 	ia64_mv_dma_sync_sg_for_device *dma_sync_sg_for_device;
 	ia64_mv_dma_mapping_error *dma_mapping_error;
 	ia64_mv_dma_supported *dma_supported;
-	ia64_mv_irq_desc *irq_desc;
-	ia64_mv_irq_to_vector *irq_to_vector;
 	ia64_mv_local_vector_to_irq *local_vector_to_irq;
+	ia64_mv_pci_get_legacy_mem_t *pci_get_legacy_mem;
+	ia64_mv_pci_legacy_read_t *pci_legacy_read;
+	ia64_mv_pci_legacy_write_t *pci_legacy_write;
 	ia64_mv_inb_t *inb;
 	ia64_mv_inw_t *inw;
 	ia64_mv_inl_t *inl;
@@ -212,9 +219,10 @@
 	platform_dma_sync_sg_for_device,	\
 	platform_dma_mapping_error,			\
 	platform_dma_supported,			\
-	platform_irq_desc,			\
-	platform_irq_to_vector,			\
 	platform_local_vector_to_irq,		\
+	platform_pci_get_legacy_mem,		\
+	platform_pci_legacy_read,		\
+	platform_pci_legacy_write,		\
 	platform_inb,				\
 	platform_inw,				\
 	platform_inl,				\
@@ -321,14 +329,17 @@
 #ifndef platform_dma_supported
 # define  platform_dma_supported	swiotlb_dma_supported
 #endif
-#ifndef platform_irq_desc
-# define platform_irq_desc		__ia64_irq_desc
-#endif
-#ifndef platform_irq_to_vector
-# define platform_irq_to_vector		__ia64_irq_to_vector
-#endif
 #ifndef platform_local_vector_to_irq
 # define platform_local_vector_to_irq	__ia64_local_vector_to_irq
+#endif
+#ifndef platform_pci_get_legacy_mem
+# define platform_pci_get_legacy_mem	ia64_pci_get_legacy_mem
+#endif
+#ifndef platform_pci_legacy_read
+# define platform_pci_legacy_read	ia64_pci_legacy_read
+#endif
+#ifndef platform_pci_legacy_write
+# define platform_pci_legacy_write	ia64_pci_legacy_write
 #endif
 #ifndef platform_inb
 # define platform_inb		__ia64_inb
diff -Nru a/include/asm-ia64/machvec_hpzx1_swiotlb.h b/include/asm-ia64/machvec_hpzx1_swiotlb.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-ia64/machvec_hpzx1_swiotlb.h	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,43 @@
+#ifndef _ASM_IA64_MACHVEC_HPZX1_SWIOTLB_h
+#define _ASM_IA64_MACHVEC_HPZX1_SWIOTLB_h
+
+extern ia64_mv_setup_t				dig_setup;
+extern ia64_mv_dma_init				hwsw_init;
+extern ia64_mv_dma_alloc_coherent		hwsw_alloc_coherent;
+extern ia64_mv_dma_free_coherent		hwsw_free_coherent;
+extern ia64_mv_dma_map_single			hwsw_map_single;
+extern ia64_mv_dma_unmap_single			hwsw_unmap_single;
+extern ia64_mv_dma_map_sg			hwsw_map_sg;
+extern ia64_mv_dma_unmap_sg			hwsw_unmap_sg;
+extern ia64_mv_dma_supported			hwsw_dma_supported;
+extern ia64_mv_dma_mapping_error		hwsw_dma_mapping_error;
+extern ia64_mv_dma_sync_single_for_cpu		hwsw_sync_single_for_cpu;
+extern ia64_mv_dma_sync_sg_for_cpu		hwsw_sync_sg_for_cpu;
+extern ia64_mv_dma_sync_single_for_device	hwsw_sync_single_for_device;
+extern ia64_mv_dma_sync_sg_for_device		hwsw_sync_sg_for_device;
+
+/*
+ * This stuff has dual use!
+ *
+ * For a generic kernel, the macros are used to initialize the
+ * platform's machvec structure.  When compiling a non-generic kernel,
+ * the macros are used directly.
+ */
+#define platform_name				"hpzx1_swiotlb"
+
+#define platform_setup				dig_setup
+#define platform_dma_init			hwsw_init
+#define platform_dma_alloc_coherent		hwsw_alloc_coherent
+#define platform_dma_free_coherent		hwsw_free_coherent
+#define platform_dma_map_single			hwsw_map_single
+#define platform_dma_unmap_single		hwsw_unmap_single
+#define platform_dma_map_sg			hwsw_map_sg
+#define platform_dma_unmap_sg			hwsw_unmap_sg
+#define platform_dma_supported			hwsw_dma_supported
+#define platform_dma_mapping_error		hwsw_dma_mapping_error
+#define platform_dma_sync_single_for_cpu	hwsw_sync_single_for_cpu
+#define platform_dma_sync_sg_for_cpu		hwsw_sync_sg_for_cpu
+#define platform_dma_sync_single_for_device	hwsw_sync_single_for_device
+#define platform_dma_sync_sg_for_device		hwsw_sync_sg_for_device
+
+#endif /* _ASM_IA64_MACHVEC_HPZX1_SWIOTLB_h */
diff -Nru a/include/asm-ia64/machvec_init.h b/include/asm-ia64/machvec_init.h
--- a/include/asm-ia64/machvec_init.h	2005-03-01 23:39:18 -08:00
+++ b/include/asm-ia64/machvec_init.h	2005-03-01 23:39:18 -08:00
@@ -2,9 +2,10 @@
 
 extern ia64_mv_send_ipi_t ia64_send_ipi;
 extern ia64_mv_global_tlb_purge_t ia64_global_tlb_purge;
-extern ia64_mv_irq_desc __ia64_irq_desc;
-extern ia64_mv_irq_to_vector __ia64_irq_to_vector;
 extern ia64_mv_local_vector_to_irq __ia64_local_vector_to_irq;
+extern ia64_mv_pci_get_legacy_mem_t ia64_pci_get_legacy_mem;
+extern ia64_mv_pci_legacy_read_t ia64_pci_legacy_read;
+extern ia64_mv_pci_legacy_write_t ia64_pci_legacy_write;
 
 extern ia64_mv_inb_t __ia64_inb;
 extern ia64_mv_inw_t __ia64_inw;
diff -Nru a/include/asm-ia64/machvec_sn2.h b/include/asm-ia64/machvec_sn2.h
--- a/include/asm-ia64/machvec_sn2.h	2005-03-01 23:38:55 -08:00
+++ b/include/asm-ia64/machvec_sn2.h	2005-03-01 23:38:55 -08:00
@@ -40,9 +40,10 @@
 extern ia64_mv_timer_interrupt_t sn_timer_interrupt;
 extern ia64_mv_global_tlb_purge_t sn2_global_tlb_purge;
 extern ia64_mv_tlb_migrate_finish_t	sn_tlb_migrate_finish;
-extern ia64_mv_irq_desc sn_irq_desc;
-extern ia64_mv_irq_to_vector sn_irq_to_vector;
 extern ia64_mv_local_vector_to_irq sn_local_vector_to_irq;
+extern ia64_mv_pci_get_legacy_mem_t sn_pci_get_legacy_mem;
+extern ia64_mv_pci_legacy_read_t sn_pci_legacy_read;
+extern ia64_mv_pci_legacy_write_t sn_pci_legacy_write;
 extern ia64_mv_inb_t __sn_inb;
 extern ia64_mv_inw_t __sn_inw;
 extern ia64_mv_inl_t __sn_inl;
@@ -102,9 +103,10 @@
 #define platform_readw_relaxed		__sn_readw_relaxed
 #define platform_readl_relaxed		__sn_readl_relaxed
 #define platform_readq_relaxed		__sn_readq_relaxed
-#define platform_irq_desc		sn_irq_desc
-#define platform_irq_to_vector		sn_irq_to_vector
 #define platform_local_vector_to_irq	sn_local_vector_to_irq
+#define platform_pci_get_legacy_mem	sn_pci_get_legacy_mem
+#define platform_pci_legacy_read	sn_pci_legacy_read
+#define platform_pci_legacy_write	sn_pci_legacy_write
 #define platform_dma_init		machvec_noop
 #define platform_dma_alloc_coherent	sn_dma_alloc_coherent
 #define platform_dma_free_coherent	sn_dma_free_coherent
diff -Nru a/include/asm-ia64/mca.h b/include/asm-ia64/mca.h
--- a/include/asm-ia64/mca.h	2005-03-01 23:38:53 -08:00
+++ b/include/asm-ia64/mca.h	2005-03-01 23:38:53 -08:00
@@ -5,11 +5,14 @@
  * Copyright (C) 1999, 2004 Silicon Graphics, Inc.
  * Copyright (C) Vijay Chander (vijay@engr.sgi.com)
  * Copyright (C) Srinivasa Thirumalachar (sprasad@engr.sgi.com)
+ * Copyright (C) Russ Anderson (rja@sgi.com)
  */
 
 #ifndef _ASM_IA64_MCA_H
 #define _ASM_IA64_MCA_H
 
+#define IA64_MCA_STACK_SIZE	8192
+
 #if !defined(__ASSEMBLY__)
 
 #include <linux/interrupt.h>
@@ -48,17 +51,6 @@
 	IA64_MCA_RENDEZ_CHECKIN_DONE	=	0x1
 };
 
-/* the following data structure is used for TLB error recovery purposes */
-extern struct ia64_mca_tlb_info {
-	u64	cr_lid;
-	u64	percpu_paddr;
-	u64	ptce_base;
-	u32	ptce_count[2];
-	u32	ptce_stride[2];
-	u64	pal_paddr;
-	u64	pal_base;
-} ia64_mca_tlb_list[NR_CPUS];
-
 /* Information maintained by the MC infrastructure */
 typedef struct ia64_mc_info_s {
 	u64		imi_mca_handler;
@@ -112,7 +104,21 @@
 						 */
 } ia64_mca_os_to_sal_state_t;
 
+/* Per-CPU MCA state that is too big for normal per-CPU variables.  */
+
+struct ia64_mca_cpu {
+	u64 stack[IA64_MCA_STACK_SIZE/8];	/* MCA memory-stack */
+	u64 proc_state_dump[512];
+	u64 stackframe[32];
+	u64 rbstore[IA64_MCA_STACK_SIZE/8];	/* MCA reg.-backing store */
+	u64 init_stack[KERNEL_STACK_SIZE/8];
+} __attribute__ ((aligned(16)));
+
+/* Array of physical addresses of each CPU's MCA area.  */
+extern unsigned long __per_cpu_mca[NR_CPUS];
+
 extern void ia64_mca_init(void);
+extern void ia64_mca_cpu_init(void *);
 extern void ia64_os_mca_dispatch(void);
 extern void ia64_os_mca_dispatch_end(void);
 extern void ia64_mca_ucmc_handler(void);
diff -Nru a/include/asm-ia64/mca_asm.h b/include/asm-ia64/mca_asm.h
--- a/include/asm-ia64/mca_asm.h	2005-03-01 23:39:16 -08:00
+++ b/include/asm-ia64/mca_asm.h	2005-03-01 23:39:16 -08:00
@@ -46,6 +46,10 @@
 	mov	temp	= 0x7	;;							\
 	dep	addr	= temp, addr, 61, 3
 
+#define GET_THIS_PADDR(reg, var)		\
+	mov	reg = IA64_KR(PER_CPU_DATA);;	\
+        addl	reg = THIS_CPU(var), reg
+
 /*
  * This macro jumps to the instruction at the given virtual address
  * and starts execution in physical mode with all the address
diff -Nru a/include/asm-ia64/mmzone.h b/include/asm-ia64/mmzone.h
--- a/include/asm-ia64/mmzone.h	2005-03-01 23:39:18 -08:00
+++ b/include/asm-ia64/mmzone.h	2005-03-01 23:39:18 -08:00
@@ -11,7 +11,7 @@
 #ifndef _ASM_IA64_MMZONE_H
 #define _ASM_IA64_MMZONE_H
 
-#include <linux/config.h>
+#include <linux/numa.h>
 #include <asm/page.h>
 #include <asm/meminit.h>
 
@@ -19,15 +19,14 @@
 
 #ifdef CONFIG_IA64_DIG /* DIG systems are small */
 # define MAX_PHYSNODE_ID	8
-# define NR_NODES		8
-# define NR_NODE_MEMBLKS	(NR_NODES * 8)
+# define NR_NODE_MEMBLKS	(MAX_NUMNODES * 8)
 #else /* sn2 is the biggest case, so we use that if !DIG */
 # define MAX_PHYSNODE_ID	2048
-# define NR_NODES		256
-# define NR_NODE_MEMBLKS	(NR_NODES * 4)
+# define NR_NODE_MEMBLKS	(MAX_NUMNODES * 4)
 #endif
 
 #else /* CONFIG_DISCONTIGMEM */
-# define NR_NODE_MEMBLKS	4
+# define NR_NODE_MEMBLKS	(MAX_NUMNODES * 4)
 #endif /* CONFIG_DISCONTIGMEM */
+
 #endif /* _ASM_IA64_MMZONE_H */
diff -Nru a/include/asm-ia64/msi.h b/include/asm-ia64/msi.h
--- a/include/asm-ia64/msi.h	2005-03-01 23:39:07 -08:00
+++ b/include/asm-ia64/msi.h	2005-03-01 23:39:07 -08:00
@@ -12,7 +12,6 @@
 static inline void set_intr_gate (int nr, void *func) {}
 #define IO_APIC_VECTOR(irq)	(irq)
 #define ack_APIC_irq		ia64_eoi
-#define irq_desc		_irq_desc
 #define cpu_mask_to_apicid(mask) cpu_physical_id(first_cpu(mask))
 #define MSI_DEST_MODE		MSI_PHYSICAL_MODE
 #define MSI_TARGET_CPU	((ia64_getreg(_IA64_REG_CR_LID) >> 16) & 0xffff)
diff -Nru a/include/asm-ia64/nodedata.h b/include/asm-ia64/nodedata.h
--- a/include/asm-ia64/nodedata.h	2005-03-01 23:39:08 -08:00
+++ b/include/asm-ia64/nodedata.h	2005-03-01 23:39:08 -08:00
@@ -27,7 +27,7 @@
 struct ia64_node_data {
 	short			active_cpu_count;
 	short			node;
-	struct pglist_data	*pg_data_ptrs[NR_NODES];
+	struct pglist_data	*pg_data_ptrs[MAX_NUMNODES];
 };
 
 
diff -Nru a/include/asm-ia64/numa.h b/include/asm-ia64/numa.h
--- a/include/asm-ia64/numa.h	2005-03-01 23:38:55 -08:00
+++ b/include/asm-ia64/numa.h	2005-03-01 23:38:55 -08:00
@@ -59,7 +59,7 @@
  */
 
 extern u8 numa_slit[MAX_NUMNODES * MAX_NUMNODES];
-#define node_distance(from,to) (numa_slit[(from) * numnodes + (to)])
+#define node_distance(from,to) (numa_slit[(from) * num_online_nodes() + (to)])
 
 extern int paddr_to_nid(unsigned long paddr);
 
diff -Nru a/include/asm-ia64/numnodes.h b/include/asm-ia64/numnodes.h
--- a/include/asm-ia64/numnodes.h	2005-03-01 23:39:18 -08:00
+++ b/include/asm-ia64/numnodes.h	2005-03-01 23:39:18 -08:00
@@ -4,7 +4,7 @@
 #ifdef CONFIG_IA64_DIG
 /* Max 8 Nodes */
 #define NODES_SHIFT	3
-#elif defined(CONFIG_IA64_HP_ZX1)
+#elif defined(CONFIG_IA64_HP_ZX1) || defined(CONFIG_IA64_HP_ZX1_SWIOTLB)
 /* Max 32 Nodes */
 #define NODES_SHIFT	5
 #elif defined(CONFIG_IA64_SGI_SN2) || defined(CONFIG_IA64_GENERIC)
diff -Nru a/include/asm-ia64/page.h b/include/asm-ia64/page.h
--- a/include/asm-ia64/page.h	2005-03-01 23:38:52 -08:00
+++ b/include/asm-ia64/page.h	2005-03-01 23:38:52 -08:00
@@ -75,6 +75,17 @@
 	flush_dcache_page(page);		\
 } while (0)
 
+
+#define alloc_zeroed_user_highpage(vma, vaddr) \
+({						\
+	struct page *page = alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO, vma, vaddr); \
+	if (page)				\
+ 		flush_dcache_page(page);	\
+	page;					\
+})
+
+#define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE
+
 #define virt_addr_valid(kaddr)	pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
 
 #ifdef CONFIG_VIRTUAL_MEM_MAP
diff -Nru a/include/asm-ia64/pal.h b/include/asm-ia64/pal.h
--- a/include/asm-ia64/pal.h	2005-03-01 23:39:07 -08:00
+++ b/include/asm-ia64/pal.h	2005-03-01 23:39:07 -08:00
@@ -66,7 +66,7 @@
 #define PAL_CACHE_PROT_INFO	38	/* get i/d cache protection info */
 #define PAL_REGISTER_INFO	39	/* return AR and CR register information*/
 #define PAL_SHUTDOWN		40	/* enter processor shutdown state */
-#define PAL_PREFETCH_VISIBILITY	41
+#define PAL_PREFETCH_VISIBILITY	41	/* Make Processor Prefetches Visible */
 
 #define PAL_COPY_PAL		256	/* relocate PAL procedures and PAL PMI */
 #define PAL_HALT_INFO		257	/* return the low power capabilities of processor */
@@ -1537,11 +1537,25 @@
 	return iprv.status;
 }
 
+/*
+ * PAL_PREFETCH_VISIBILITY transaction types
+ */
+#define PAL_VISIBILITY_VIRTUAL		0
+#define PAL_VISIBILITY_PHYSICAL		1
+
+/*
+ * PAL_PREFETCH_VISIBILITY return codes
+ */
+#define PAL_VISIBILITY_OK		1
+#define PAL_VISIBILITY_OK_REMOTE_NEEDED	0
+#define PAL_VISIBILITY_INVAL_ARG	-2
+#define PAL_VISIBILITY_ERROR		-3
+
 static inline s64
-ia64_pal_prefetch_visibility (void)
+ia64_pal_prefetch_visibility (s64 trans_type)
 {
 	struct ia64_pal_retval iprv;
-	PAL_CALL(iprv, PAL_PREFETCH_VISIBILITY, 0, 0, 0);
+	PAL_CALL(iprv, PAL_PREFETCH_VISIBILITY, trans_type, 0, 0);
 	return iprv.status;
 }
 
diff -Nru a/include/asm-ia64/pci.h b/include/asm-ia64/pci.h
--- a/include/asm-ia64/pci.h	2005-03-01 23:39:16 -08:00
+++ b/include/asm-ia64/pci.h	2005-03-01 23:39:16 -08:00
@@ -85,6 +85,20 @@
 #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);
+#define HAVE_PCI_LEGACY
+extern int pci_mmap_legacy_page_range(struct pci_bus *bus,
+				      struct vm_area_struct *vma);
+extern ssize_t pci_read_legacy_io(struct kobject *kobj, char *buf, loff_t off,
+				  size_t count);
+extern ssize_t pci_write_legacy_io(struct kobject *kobj, char *buf, loff_t off,
+				   size_t count);
+extern int pci_mmap_legacy_mem(struct kobject *kobj,
+			       struct bin_attribute *attr,
+			       struct vm_area_struct *vma);
+
+#define pci_get_legacy_mem platform_pci_get_legacy_mem
+#define pci_legacy_read platform_pci_legacy_read
+#define pci_legacy_write platform_pci_legacy_write
 
 struct pci_window {
 	struct resource resource;
diff -Nru a/include/asm-ia64/pgalloc.h b/include/asm-ia64/pgalloc.h
--- a/include/asm-ia64/pgalloc.h	2005-03-01 23:38:51 -08:00
+++ b/include/asm-ia64/pgalloc.h	2005-03-01 23:38:51 -08:00
@@ -61,9 +61,7 @@
 	pgd_t *pgd = pgd_alloc_one_fast(mm);
 
 	if (unlikely(pgd == NULL)) {
-		pgd = (pgd_t *)__get_free_page(GFP_KERNEL);
-		if (likely(pgd != NULL))
-			clear_page(pgd);
+		pgd = (pgd_t *)__get_free_page(GFP_KERNEL|__GFP_ZERO);
 	}
 	return pgd;
 }
@@ -79,12 +77,11 @@
 }
 
 static inline void
-pgd_populate (struct mm_struct *mm, pgd_t *pgd_entry, pmd_t *pmd)
+pud_populate (struct mm_struct *mm, pud_t *pud_entry, pmd_t *pmd)
 {
-	pgd_val(*pgd_entry) = __pa(pmd);
+	pud_val(*pud_entry) = __pa(pmd);
 }
 
-
 static inline pmd_t*
 pmd_alloc_one_fast (struct mm_struct *mm, unsigned long addr)
 {
@@ -107,10 +104,8 @@
 static inline pmd_t*
 pmd_alloc_one (struct mm_struct *mm, unsigned long addr)
 {
-	pmd_t *pmd = (pmd_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT);
+	pmd_t *pmd = (pmd_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO);
 
-	if (likely(pmd != NULL))
-		clear_page(pmd);
 	return pmd;
 }
 
@@ -141,20 +136,16 @@
 static inline struct page *
 pte_alloc_one (struct mm_struct *mm, unsigned long addr)
 {
-	struct page *pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT, 0);
+	struct page *pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0);
 
-	if (likely(pte != NULL))
-		clear_page(page_address(pte));
 	return pte;
 }
 
 static inline pte_t *
 pte_alloc_one_kernel (struct mm_struct *mm, unsigned long addr)
 {
-	pte_t *pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT);
+	pte_t *pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO);
 
-	if (likely(pte != NULL))
-		clear_page(pte);
 	return pte;
 }
 
diff -Nru a/include/asm-ia64/pgtable.h b/include/asm-ia64/pgtable.h
--- a/include/asm-ia64/pgtable.h	2005-03-01 23:38:54 -08:00
+++ b/include/asm-ia64/pgtable.h	2005-03-01 23:38:54 -08:00
@@ -91,7 +91,7 @@
 #define PGDIR_SHIFT		(PAGE_SHIFT + 2*(PAGE_SHIFT-3))
 #define PGDIR_SIZE		(__IA64_UL(1) << PGDIR_SHIFT)
 #define PGDIR_MASK		(~(PGDIR_SIZE-1))
-#define PTRS_PER_PGD		(__IA64_UL(1) << (PAGE_SHIFT-3))
+#define PTRS_PER_PGD		(1UL << (PAGE_SHIFT-3))
 #define USER_PTRS_PER_PGD	(5*PTRS_PER_PGD/8)	/* regions 0-4 are user regions */
 #define FIRST_USER_PGD_NR	0
 
@@ -104,7 +104,7 @@
 #define PMD_SHIFT	(PAGE_SHIFT + (PAGE_SHIFT-3))
 #define PMD_SIZE	(1UL << PMD_SHIFT)
 #define PMD_MASK	(~(PMD_SIZE-1))
-#define PTRS_PER_PMD	(__IA64_UL(1) << (PAGE_SHIFT-3))
+#define PTRS_PER_PMD	(1UL << (PAGE_SHIFT-3))
 
 /*
  * Definitions for third level:
@@ -254,11 +254,12 @@
 #define pmd_page_kernel(pmd)		((unsigned long) __va(pmd_val(pmd) & _PFN_MASK))
 #define pmd_page(pmd)			virt_to_page((pmd_val(pmd) + PAGE_OFFSET))
 
-#define pgd_none(pgd)			(!pgd_val(pgd))
-#define pgd_bad(pgd)			(!ia64_phys_addr_valid(pgd_val(pgd)))
-#define pgd_present(pgd)		(pgd_val(pgd) != 0UL)
-#define pgd_clear(pgdp)			(pgd_val(*(pgdp)) = 0UL)
-#define pgd_page(pgd)			((unsigned long) __va(pgd_val(pgd) & _PFN_MASK))
+#define pud_none(pud)			(!pud_val(pud))
+#define pud_bad(pud)			(!ia64_phys_addr_valid(pud_val(pud)))
+#define pud_present(pud)		(pud_val(pud) != 0UL)
+#define pud_clear(pudp)			(pud_val(*(pudp)) = 0UL)
+
+#define pud_page(pud)			((unsigned long) __va(pud_val(pud) & _PFN_MASK))
 
 /*
  * The following have defined behavior only work if pte_present() is true.
@@ -328,7 +329,7 @@
 
 /* Find an entry in the second-level page table.. */
 #define pmd_offset(dir,addr) \
-	((pmd_t *) pgd_page(*(dir)) + (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1)))
+	((pmd_t *) pud_page(*(dir)) + (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1)))
 
 /*
  * Find an entry in the third-level page table.  This looks more complicated than it
@@ -561,5 +562,6 @@
 #define __HAVE_ARCH_PTE_SAME
 #define __HAVE_ARCH_PGD_OFFSET_GATE
 #include <asm-generic/pgtable.h>
+#include <asm-generic/pgtable-nopud.h>
 
 #endif /* _ASM_IA64_PGTABLE_H */
diff -Nru a/include/asm-ia64/resource.h b/include/asm-ia64/resource.h
--- a/include/asm-ia64/resource.h	2005-03-01 23:39:08 -08:00
+++ b/include/asm-ia64/resource.h	2005-03-01 23:39:08 -08:00
@@ -1,58 +1,8 @@
 #ifndef _ASM_IA64_RESOURCE_H
 #define _ASM_IA64_RESOURCE_H
 
-/*
- * Resource limits
- *
- * Based on <asm-i386/resource.h>.
- *
- * Modified 1998, 1999
- *	David Mosberger-Tang <davidm@hpl.hp.com>, Hewlett-Packard Co
- */
-
 #include <asm/ustack.h>
-
-#define RLIMIT_CPU	0		/* CPU time in ms */
-#define RLIMIT_FSIZE	1		/* Maximum filesize */
-#define RLIMIT_DATA	2		/* max data size */
-#define RLIMIT_STACK	3		/* max stack size */
-#define RLIMIT_CORE	4		/* max core file size */
-#define RLIMIT_RSS	5		/* max resident set size */
-#define RLIMIT_NPROC	6		/* max number of processes */
-#define RLIMIT_NOFILE	7		/* max number of open files */
-#define RLIMIT_MEMLOCK	8		/* max locked-in-memory address space */
-#define RLIMIT_AS	9		/* address space limit */
-#define RLIMIT_LOCKS	10		/* maximum file locks held */
-#define RLIMIT_SIGPENDING 11		/* max number of pending signals */
-#define RLIMIT_MSGQUEUE 12		/* maximum bytes in POSIX mqueues */
-
-#define RLIM_NLIMITS	13
-
-/*
- * SuS says limits have to be unsigned.
- * Which makes a ton more sense anyway.
- */
-#define RLIM_INFINITY  (~0UL)
-
-# ifdef __KERNEL__
-
-#define INIT_RLIMITS					\
-{							\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{      _STK_LIM, DEFAULT_USER_STACK_SIZE },	\
-	{             0, RLIM_INFINITY },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{             0,             0 },		\
-	{      INR_OPEN,     INR_OPEN  },		\
-	{   MLOCK_LIMIT,   MLOCK_LIMIT },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{ MAX_SIGPENDING, MAX_SIGPENDING },		\
-	{ MQ_BYTES_MAX, MQ_BYTES_MAX },			\
-}
-
-# endif /* __KERNEL__ */
+#define _STK_LIM_MAX	DEFAULT_USER_STACK_SIZE
+#include <asm-generic/resource.h>
 
 #endif /* _ASM_IA64_RESOURCE_H */
diff -Nru a/include/asm-ia64/sal.h b/include/asm-ia64/sal.h
--- a/include/asm-ia64/sal.h	2005-03-01 23:39:16 -08:00
+++ b/include/asm-ia64/sal.h	2005-03-01 23:39:16 -08:00
@@ -325,6 +325,10 @@
 	efi_guid_t platform_guid;	/* Unique OEM Platform ID */
 } sal_log_record_header_t;
 
+#define sal_log_severity_recoverable	0
+#define sal_log_severity_fatal		1
+#define sal_log_severity_corrected	2
+
 /* Definition of log section header structures */
 typedef struct sal_log_sec_header {
     efi_guid_t guid;			/* Unique Section ID */
@@ -828,6 +832,8 @@
 				   u64, u64, u64, u64, u64);
 extern int ia64_sal_oemcall_reentrant(struct ia64_sal_retval *, u64, u64, u64,
 				      u64, u64, u64, u64, u64);
+
+extern void ia64_sal_handler_init(void *entry_point, void *gpval);
 
 #endif /* __ASSEMBLY__ */
 
diff -Nru a/include/asm-ia64/sections.h b/include/asm-ia64/sections.h
--- a/include/asm-ia64/sections.h	2005-03-01 23:38:57 -08:00
+++ b/include/asm-ia64/sections.h	2005-03-01 23:38:57 -08:00
@@ -17,7 +17,6 @@
 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 _end[];		/* end of kernel image */
 
 #endif /* _ASM_IA64_SECTIONS_H */
 
diff -Nru a/include/asm-ia64/signal.h b/include/asm-ia64/signal.h
--- a/include/asm-ia64/signal.h	2005-03-01 23:38:52 -08:00
+++ b/include/asm-ia64/signal.h	2005-03-01 23:38:52 -08:00
@@ -177,6 +177,8 @@
 
 #define ptrace_signal_deliver(regs, cookie) do { } while (0)
 
+void set_sigdelayed(pid_t pid, int signo, int code, void __user *addr);
+
 #endif /* __KERNEL__ */
 
 # endif /* !__ASSEMBLY__ */
diff -Nru a/include/asm-ia64/sn/addrs.h b/include/asm-ia64/sn/addrs.h
--- a/include/asm-ia64/sn/addrs.h	2005-03-01 23:39:18 -08:00
+++ b/include/asm-ia64/sn/addrs.h	2005-03-01 23:39:18 -08:00
@@ -9,204 +9,175 @@
 #ifndef _ASM_IA64_SN_ADDRS_H
 #define _ASM_IA64_SN_ADDRS_H
 
+#include <asm/percpu.h>
+#include <asm/sn/types.h>
+#include <asm/sn/pda.h>
 
-/* McKinley Address Format:
- *
- *   4 4       3 3  3 3
- *   9 8       8 7  6 5             0
- *  +-+---------+----+--------------+
- *  |0| Node ID | AS | Node Offset  |
- *  +-+---------+----+--------------+
+/*
+ *  Memory/SHUB Address Format:
+ *  +-+---------+--+--------------+
+ *  |0|  NASID  |AS| NodeOffset   |
+ *  +-+---------+--+--------------+
  *
- *   Node ID: If bit 38 = 1, is ICE, else is SHUB
- *   AS: Address Space Identifier. Used only if bit 38 = 0.
- *     b'00: Local Resources and MMR space
- *           bit 35
+ *  NASID: (low NASID bit is 0) Memory and SHUB MMRs
+ *   AS: 2-bit Address Space Identifier. Used only if low NASID bit is 0
+ *     00: Local Resources and MMR space
+ *           Top bit of NodeOffset
  *               0: Local resources space
  *                  node id:
  *                        0: IA64/NT compatibility space
  *                        2: Local MMR Space
  *                        4: Local memory, regardless of local node id
  *               1: Global MMR space
- *     b'01: GET space.
- *     b'10: AMO space.
- *     b'11: Cacheable memory space.
+ *     01: GET space.
+ *     10: AMO space.
+ *     11: Cacheable memory space.
  *
  *   NodeOffset: byte offset
+ *
+ *
+ *  TIO address format:
+ *  +-+----------+--+--------------+
+ *  |0|  NASID   |AS| Nodeoffset   |
+ *  +-+----------+--+--------------+
+ *
+ *  NASID: (low NASID bit is 1) TIO
+ *   AS: 2-bit Chiplet Identifier
+ *     00: TIO LB (Indicates TIO MMR access.)
+ *     01: TIO ICE (indicates coretalk space access.)
+ * 
+ *   NodeOffset: top bit must be set.
+ *
+ *
+ * Note that in both of the above address formats, the low
+ * NASID bit indicates if the reference is to the SHUB or TIO MMRs.
  */
 
-/* TIO address format:
- *  4 4        3 3 3 3 3             0
- *  9 8        8 7 6 5 4
- * +-+----------+-+---+--------------+
- * |0| Node ID  |0|CID| Node offset  |
- * +-+----------+-+---+--------------+
- *
- * Node ID: if bit 38 == 1, is ICE.
- * Bit 37: Must be zero.
- * CID: Chiplet ID:
- *     b'01: TIO LB (Indicates TIO MMR access.)
- *     b'11: TIO ICE (indicates coretalk space access.)
- * Node offset: byte offest.
+
+/*
+ * Define basic shift & mask constants for manipulating NASIDs and AS values.
  */
+#define NASID_BITMASK		(pda->nasid_bitmask)
+#define NASID_SHIFT		(pda->nasid_shift)
+#define AS_SHIFT		(pda->as_shift)
+#define AS_BITMASK		0x3UL
+
+#define NASID_MASK              ((u64)NASID_BITMASK << NASID_SHIFT)
+#define AS_MASK			((u64)AS_BITMASK << AS_SHIFT)
+#define REGION_BITS		0xe000000000000000UL
+
 
 /*
- * Note that in both of the above address formats, bit
- * 35 set indicates that the reference is to the 
- * shub or tio MMRs.
- */
-
-#ifndef __ASSEMBLY__
-typedef union ia64_sn2_pa {
-	struct {
-		unsigned long off  : 36;
-		unsigned long as   : 2;
-		unsigned long nasid: 11;
-		unsigned long fill : 15;
-	} f;
-	unsigned long l;
-	void *p;
-} ia64_sn2_pa_t;
-#endif
-
-#define TO_PHYS_MASK		0x0001ffcfffffffffUL	/* Note - clear AS bits */
-
-
-/* Regions determined by AS */
-#define LOCAL_MMR_SPACE		0xc000008000000000UL	/* Local MMR space */
-#define LOCAL_PHYS_MMR_SPACE	0x8000008000000000UL	/* Local PhysicalMMR space */
-#define LOCAL_MEM_SPACE		0xc000010000000000UL	/* Local Memory space */
-/* It so happens that setting bit 35 indicates a reference to the SHUB or TIO
- * MMR space.  
- */
-#define GLOBAL_MMR_SPACE	0xc000000800000000UL	/* Global MMR space */
-#define TIO_MMR_SPACE		0xc000000800000000UL	/* TIO MMR space */
-#define ICE_MMR_SPACE		0xc000000000000000UL	/* ICE MMR space */
-#define GLOBAL_PHYS_MMR_SPACE	0x0000000800000000UL	/* Global Physical MMR space */
-#define GET_SPACE		0xe000001000000000UL	/* GET space */
-#define AMO_SPACE		0xc000002000000000UL	/* AMO space */
-#define CACHEABLE_MEM_SPACE	0xe000003000000000UL	/* Cacheable memory space */
-#define UNCACHED                0xc000000000000000UL	/* UnCacheable memory space */
-#define UNCACHED_PHYS           0x8000000000000000UL	/* UnCacheable physical memory space */
-
-#define PHYS_MEM_SPACE		0x0000003000000000UL	/* physical memory space */
-
-/* SN2 address macros */
-/* NID_SHFT has the right value for both SHUB and TIO addresses.*/
-#define NID_SHFT		38
-#define LOCAL_MMR_ADDR(a)	(UNCACHED | LOCAL_MMR_SPACE | (a))
-#define LOCAL_MMR_PHYS_ADDR(a)	(UNCACHED_PHYS | LOCAL_PHYS_MMR_SPACE | (a))
-#define LOCAL_MEM_ADDR(a)	(LOCAL_MEM_SPACE | (a))
-#define REMOTE_ADDR(n,a)	((((unsigned long)(n))<<NID_SHFT) | (a))
-#define GLOBAL_MMR_ADDR(n,a)	(UNCACHED | GLOBAL_MMR_SPACE | REMOTE_ADDR(n,a))
-#define GLOBAL_MMR_PHYS_ADDR(n,a) (UNCACHED_PHYS | GLOBAL_PHYS_MMR_SPACE | REMOTE_ADDR(n,a))
-#define GET_ADDR(n,a)		(GET_SPACE | REMOTE_ADDR(n,a))
-#define AMO_ADDR(n,a)		(UNCACHED | AMO_SPACE | REMOTE_ADDR(n,a))
-#define GLOBAL_MEM_ADDR(n,a)	(CACHEABLE_MEM_SPACE | REMOTE_ADDR(n,a))
+ * AS values. These are the same on both SHUB1 & SHUB2.
+ */
+#define AS_GET_VAL		1UL
+#define AS_AMO_VAL		2UL
+#define AS_CAC_VAL		3UL
+#define AS_GET_SPACE		(AS_GET_VAL << AS_SHIFT)
+#define AS_AMO_SPACE		(AS_AMO_VAL << AS_SHIFT)
+#define AS_CAC_SPACE		(AS_CAC_VAL << AS_SHIFT)
 
-/* non-II mmr's start at top of big window space (4G) */
-#define BWIN_TOP		0x0000000100000000UL
 
 /*
- * general address defines - for code common to SN0/SN1/SN2
+ * Base addresses for various address ranges.
+ */
+#define CACHED			0xe000000000000000UL
+#define UNCACHED                0xc000000000000000UL
+#define UNCACHED_PHYS           0x8000000000000000UL
+
+
+/* 
+ * Virtual Mode Local & Global MMR space.  
  */
-#define CAC_BASE		CACHEABLE_MEM_SPACE			/* cacheable memory space */
-#define IO_BASE			(UNCACHED | GLOBAL_MMR_SPACE)		/* lower 4G maps II's XIO space */
-#define TIO_BASE		(UNCACHED | ICE_MMR_SPACE)		/* lower 4G maps TIO space */
-#define AMO_BASE		(UNCACHED | AMO_SPACE)			/* fetch & op space */
-#define MSPEC_BASE		AMO_BASE				/* fetch & op space */
-#define UNCAC_BASE		(UNCACHED | CACHEABLE_MEM_SPACE)	/* uncached global memory */
-#define GET_BASE		GET_SPACE				/* momentarily coherent remote mem. */
-#define CALIAS_BASE             LOCAL_CACHEABLE_BASE			/* cached node-local memory */
-#define UALIAS_BASE             (UNCACHED | LOCAL_CACHEABLE_BASE)	/* uncached node-local memory */
-
-#define TO_PHYS(x)              (              ((x) & TO_PHYS_MASK))
-#define TO_CAC(x)               (CAC_BASE    | ((x) & TO_PHYS_MASK))
-#define TO_UNCAC(x)             (UNCAC_BASE  | ((x) & TO_PHYS_MASK))
-#define TO_MSPEC(x)             (MSPEC_BASE  | ((x) & TO_PHYS_MASK))
-#define TO_GET(x)		(GET_BASE    | ((x) & TO_PHYS_MASK))
-#define TO_CALIAS(x)            (CALIAS_BASE | TO_NODE_ADDRSPACE(x))
-#define TO_UALIAS(x)            (UALIAS_BASE | TO_NODE_ADDRSPACE(x))
-#define NODE_SIZE_BITS		36	/* node offset : bits <35:0> */
-#define BWIN_SIZE_BITS		29	/* big window size: 512M */
-#define TIO_BWIN_SIZE_BITS	30	/* big window size: 1G */
-#define NASID_BITS		11	/* bits <48:38> */
-#define NASID_BITMASK		(0x7ffULL)
-#define NASID_SHFT		NID_SHFT
-#define NASID_META_BITS		0	/* ???? */
-#define NASID_LOCAL_BITS	7	/* same router as SN1 */
-
-#define NODE_ADDRSPACE_SIZE     (1UL << NODE_SIZE_BITS)
-#define NASID_MASK              ((uint64_t) NASID_BITMASK << NASID_SHFT)
-#define NASID_GET(_pa)          (int) (((uint64_t) (_pa) >>            \
-                                        NASID_SHFT) & NASID_BITMASK)
-#define PHYS_TO_DMA(x)          ( ((x & NASID_MASK) >> 2) |             \
-                                  (x & (NODE_ADDRSPACE_SIZE - 1)) )
-
-/*
- * This address requires a chiplet id in bits 38-39.  For DMA to memory,
- * the chiplet id is zero.  If we implement TIO-TIO dma, we might need
- * to insert a chiplet id into this macro.  However, it is our belief
- * right now that this chiplet id will be ICE, which is also zero.
- */
-#define PHYS_TO_TIODMA(x)     ( ((x & NASID_MASK) << 2) |             \
-                                 (x & (NODE_ADDRSPACE_SIZE - 1)) )
-
-#define CHANGE_NASID(n,x)	({ia64_sn2_pa_t _v; _v.l = (long) (x); _v.f.nasid = n; _v.p;})
-
-
-#ifndef __ASSEMBLY__
-#define NODE_SWIN_BASE(nasid, widget)                                   \
-        ((widget == 0) ? NODE_BWIN_BASE((nasid), SWIN0_BIGWIN)          \
-        : RAW_NODE_SWIN_BASE(nasid, widget))
-#else
-#define NODE_SWIN_BASE(nasid, widget) \
-     (NODE_IO_BASE(nasid) + ((uint64_t) (widget) << SWIN_SIZE_BITS))
-#define LOCAL_SWIN_BASE(widget) \
-	(UNCACHED | LOCAL_MMR_SPACE | (((uint64_t) (widget) << SWIN_SIZE_BITS)))
-#endif /* __ASSEMBLY__ */
+#define SH1_LOCAL_MMR_OFFSET	0x8000000000UL
+#define SH2_LOCAL_MMR_OFFSET	0x0200000000UL
+#define LOCAL_MMR_OFFSET	(is_shub2() ? SH2_LOCAL_MMR_OFFSET : SH1_LOCAL_MMR_OFFSET)
+#define LOCAL_MMR_SPACE		(UNCACHED | LOCAL_MMR_OFFSET)
+#define LOCAL_PHYS_MMR_SPACE	(UNCACHED_PHYS | LOCAL_MMR_OFFSET)
+
+#define SH1_GLOBAL_MMR_OFFSET	0x0800000000UL
+#define SH2_GLOBAL_MMR_OFFSET	0x0300000000UL
+#define GLOBAL_MMR_OFFSET	(is_shub2() ? SH2_GLOBAL_MMR_OFFSET : SH1_GLOBAL_MMR_OFFSET)
+#define GLOBAL_MMR_SPACE	(UNCACHED | GLOBAL_MMR_OFFSET)
 
 /*
- * The following definitions pertain to the IO special address
- * space.  They define the location of the big and little windows
- * of any given node.
+ * Physical mode addresses
  */
+#define GLOBAL_PHYS_MMR_SPACE	(UNCACHED_PHYS | GLOBAL_MMR_OFFSET)
 
-#define BWIN_SIZE               (1UL << BWIN_SIZE_BITS)
-#define BWIN_SIZEMASK           (BWIN_SIZE - 1)
-#define BWIN_WIDGET_MASK        0x7
-#define NODE_BWIN_BASE0(nasid)  (NODE_IO_BASE(nasid) + BWIN_SIZE)
-#define NODE_BWIN_BASE(nasid, bigwin)   (NODE_BWIN_BASE0(nasid) +       \
-                        ((uint64_t) (bigwin) << BWIN_SIZE_BITS))
 
-#define BWIN_WIDGETADDR(addr)   ((addr) & BWIN_SIZEMASK)
-#define BWIN_WINDOWNUM(addr)    (((addr) >> BWIN_SIZE_BITS) & BWIN_WIDGET_MASK)
+/*
+ * Clear region & AS bits.
+ */
+#define TO_PHYS_MASK		(~(REGION_BITS | AS_MASK))
 
-#define TIO_BWIN_WINDOW_SELECT_MASK 0x7
-#define TIO_BWIN_WINDOWNUM(addr)    (((addr) >> TIO_BWIN_SIZE_BITS) & TIO_BWIN_WINDOW_SELECT_MASK)
 
+/*
+ * Misc NASID manipulation.
+ */
+#define NASID_SPACE(n)		((u64)(n) << NASID_SHIFT)
+#define REMOTE_ADDR(n,a)	(NASID_SPACE(n) | (a))
+#define NODE_OFFSET(x)		((x) & (NODE_ADDRSPACE_SIZE - 1))
+#define NODE_ADDRSPACE_SIZE     (1UL << AS_SHIFT)
+#define NASID_GET(x)		(int) (((u64) (x) >> NASID_SHIFT) & NASID_BITMASK)
+#define LOCAL_MMR_ADDR(a)	(LOCAL_MMR_SPACE | (a))
+#define GLOBAL_MMR_ADDR(n,a)	(GLOBAL_MMR_SPACE | REMOTE_ADDR(n,a))
+#define GLOBAL_MMR_PHYS_ADDR(n,a) (GLOBAL_PHYS_MMR_SPACE | REMOTE_ADDR(n,a))
+#define GLOBAL_CAC_ADDR(n,a)	(CAC_BASE | REMOTE_ADDR(n,a))
+#define CHANGE_NASID(n,x)	((void *)(((u64)(x) & ~NASID_MASK) | NASID_SPACE(n)))
 
-#ifndef __ASSEMBLY__
-#include <asm/sn/types.h>
-#endif 
+
+/* non-II mmr's start at top of big window space (4G) */
+#define BWIN_TOP		0x0000000100000000UL
 
 /*
- * The following macros are used to index to the beginning of a specific
- * node's address space.
+ * general address defines
  */
+#define CAC_BASE		(CACHED   | AS_CAC_SPACE)
+#define AMO_BASE		(UNCACHED | AS_AMO_SPACE)
+#define GET_BASE		(CACHED   | AS_GET_SPACE)
 
-#define NODE_OFFSET(_n)		((uint64_t) (_n) << NASID_SHFT)
+/*
+ * Convert Memory addresses between various addressing modes.
+ */
+#define TO_PHYS(x)		(TO_PHYS_MASK & (x))
+#define TO_CAC(x)		(CAC_BASE     | TO_PHYS(x))
+#define TO_AMO(x)		(AMO_BASE     | TO_PHYS(x))
+#define TO_GET(x)		(GET_BASE     | TO_PHYS(x))
 
-#define NODE_CAC_BASE(_n)	(CAC_BASE  + NODE_OFFSET(_n))
-#define NODE_HSPEC_BASE(_n)	(HSPEC_BASE + NODE_OFFSET(_n))
-#define NODE_IO_BASE(_n)	(IO_BASE    + NODE_OFFSET(_n))
-#define NODE_MSPEC_BASE(_n)	(MSPEC_BASE + NODE_OFFSET(_n))
-#define NODE_UNCAC_BASE(_n)	(UNCAC_BASE + NODE_OFFSET(_n))
 
-#define TO_NODE_CAC(_n, _x)	(NODE_CAC_BASE(_n) | ((_x) & TO_PHYS_MASK))
+/*
+ * Covert from processor physical address to II/TIO physical address:
+ *	II - squeeze out the AS bits
+ *	TIO- requires a chiplet id in bits 38-39.  For DMA to memory,
+ *           the chiplet id is zero.  If we implement TIO-TIO dma, we might need
+ *           to insert a chiplet id into this macro.  However, it is our belief
+ *           right now that this chiplet id will be ICE, which is also zero.
+ */
+#define PHYS_TO_TIODMA(x)	( (((u64)(x) & NASID_MASK) << 2) | NODE_OFFSET(x))
+#define PHYS_TO_DMA(x)          ( (((u64)(x) & NASID_MASK) >> 2) | NODE_OFFSET(x))
+
+
+/*
+ * The following definitions pertain to the IO special address
+ * space.  They define the location of the big and little windows
+ * of any given node.
+ */
+#define BWIN_SIZE_BITS			29	/* big window size: 512M */
+#define TIO_BWIN_SIZE_BITS		30	/* big window size: 1G */
+#define NODE_SWIN_BASE(n, w)		((w == 0) ? NODE_BWIN_BASE((n), SWIN0_BIGWIN) \
+		: RAW_NODE_SWIN_BASE(n, w))
+#define NODE_IO_BASE(n)			(GLOBAL_MMR_SPACE | NASID_SPACE(n))
+#define BWIN_SIZE			(1UL << BWIN_SIZE_BITS)
+#define NODE_BWIN_BASE0(n)		(NODE_IO_BASE(n) + BWIN_SIZE)
+#define NODE_BWIN_BASE(n, w)		(NODE_BWIN_BASE0(n) + ((u64) (w) << BWIN_SIZE_BITS))
+#define RAW_NODE_SWIN_BASE(n, w)	(NODE_IO_BASE(n) + ((u64) (w) << SWIN_SIZE_BITS))
+#define BWIN_WIDGET_MASK		0x7
+#define BWIN_WINDOWNUM(x)		(((x) >> BWIN_SIZE_BITS) & BWIN_WIDGET_MASK)
+
+#define TIO_BWIN_WINDOW_SELECT_MASK	0x7
+#define TIO_BWIN_WINDOWNUM(x)		(((x) >> TIO_BWIN_SIZE_BITS) & TIO_BWIN_WINDOW_SELECT_MASK)
 
-#define RAW_NODE_SWIN_BASE(nasid, widget)				\
-	(NODE_IO_BASE(nasid) + ((uint64_t) (widget) << SWIN_SIZE_BITS))
 
 
 /*
@@ -215,15 +186,12 @@
  * of any given node.
  */
 
-#define SWIN_SIZE_BITS		24
-#define SWIN_SIZE		(1UL << 24)
-#define	SWIN_SIZEMASK		(SWIN_SIZE - 1)
-#define	SWIN_WIDGET_MASK	0xF
-
-#define TIO_SWIN_SIZE_BITS	28
-#define TIO_SWIN_SIZE		(1UL << 28)
-#define TIO_SWIN_SIZEMASK	(SWIN_SIZE - 1)
-#define TIO_SWIN_WIDGET_MASK	0x3
+#define SWIN_SIZE_BITS			24
+#define	SWIN_WIDGET_MASK		0xF
+
+#define TIO_SWIN_SIZE_BITS		28
+#define TIO_SWIN_SIZE			(1UL << TIO_SWIN_SIZE_BITS)
+#define TIO_SWIN_WIDGET_MASK		0x3
 
 /*
  * Convert smallwindow address to xtalk address.
@@ -231,82 +199,39 @@
  * 'addr' can be physical or virtual address, but will be converted
  * to Xtalk address in the range 0 -> SWINZ_SIZEMASK
  */
-#define	SWIN_WIDGETNUM(addr)	(((addr)  >> SWIN_SIZE_BITS) & SWIN_WIDGET_MASK)
+#define	SWIN_WIDGETNUM(x)		(((x)  >> SWIN_SIZE_BITS) & SWIN_WIDGET_MASK)
+#define TIO_SWIN_WIDGETNUM(x)		(((x)  >> TIO_SWIN_SIZE_BITS) & TIO_SWIN_WIDGET_MASK)
 
-#define TIO_SWIN_WIDGETNUM(addr)	(((addr)  >> TIO_SWIN_SIZE_BITS) & TIO_SWIN_WIDGET_MASK)
 
 /*
  * The following macros produce the correct base virtual address for
- * the hub registers.  The LOCAL_HUB_* macros produce the appropriate
- * address for the local registers.  The REMOTE_HUB_* macro produce
+ * the hub registers. The REMOTE_HUB_* macro produce
  * the address for the specified hub's registers.  The intent is
  * that the appropriate PI, MD, NI, or II register would be substituted
- * for _x.
- */
-
-
-/*
- * SN2 has II mmr's located inside small window space.
- * As all other non-II mmr's located at the top of big window
- * space.
- */
-#define REMOTE_HUB_BASE(_x)						\
-        (UNCACHED | GLOBAL_MMR_SPACE |                                  \
-        (((~(_x)) & BWIN_TOP)>>8)    |                                       \
-        (((~(_x)) & BWIN_TOP)>>9)    | (_x))
-
-#define REMOTE_HUB(_n, _x)						\
-	((uint64_t *)(REMOTE_HUB_BASE(_x) | ((((long)(_n))<<NASID_SHFT))))
-
-
-/*
- * WARNING:
+ * for x.
+ *
+ *   WARNING:
  *	When certain Hub chip workaround are defined, it's not sufficient
  *	to dereference the *_HUB_ADDR() macros.  You should instead use
  *	HUB_L() and HUB_S() if you must deal with pointers to hub registers.
  *	Otherwise, the recommended approach is to use *_HUB_L() and *_HUB_S().
  *	They're always safe.
  */
-/*
- * LOCAL_HUB_ADDR doesn't need to be changed for TIO, since, by definition,
- * there are no "local" TIOs.
- */
-#define LOCAL_HUB_ADDR(_x)							\
-	(((_x) & BWIN_TOP) ? ((volatile uint64_t *)(LOCAL_MMR_ADDR(_x)))		\
-	: ((volatile uint64_t *)(IALIAS_BASE + (_x))))
-#define REMOTE_HUB_ADDR(_n, _x)						\
-	((_n & 1) ?							\
+#define REMOTE_HUB_ADDR(n,x)						\
+	((n & 1) ?							\
 	/* TIO: */							\
-	((volatile uint64_t *)(GLOBAL_MMR_ADDR(_n, _x)))				\
+	((volatile u64 *)(GLOBAL_MMR_ADDR(n,x)))			\
 	: /* SHUB: */							\
-	(((_x) & BWIN_TOP) ? ((volatile uint64_t *)(GLOBAL_MMR_ADDR(_n, _x)))	\
-	: ((volatile uint64_t *)(NODE_SWIN_BASE(_n, 1) + 0x800000 + (_x)))))
-
-#ifndef __ASSEMBLY__
+	(((x) & BWIN_TOP) ? ((volatile u64 *)(GLOBAL_MMR_ADDR(n,x)))\
+	: ((volatile u64 *)(NODE_SWIN_BASE(n,1) + 0x800000 + (x)))))
 
-#define HUB_L(_a)			(*((volatile typeof(*_a) *)_a))
-#define	HUB_S(_a, _d)			(*((volatile typeof(*_a) *)_a) = (_d))
 
-#define LOCAL_HUB_L(_r)			HUB_L(LOCAL_HUB_ADDR(_r))
-#define LOCAL_HUB_S(_r, _d)		HUB_S(LOCAL_HUB_ADDR(_r), (_d))
-#define REMOTE_HUB_L(_n, _r)		HUB_L(REMOTE_HUB_ADDR((_n), (_r)))
-#define REMOTE_HUB_S(_n, _r, _d)	HUB_S(REMOTE_HUB_ADDR((_n), (_r)), (_d))
-#define REMOTE_HUB_PI_L(_n, _sn, _r)	HUB_L(REMOTE_HUB_PI_ADDR((_n), (_sn), (_r)))
-#define REMOTE_HUB_PI_S(_n, _sn, _r, _d) HUB_S(REMOTE_HUB_PI_ADDR((_n), (_sn), (_r)), (_d))
 
-#endif /* __ASSEMBLY__ */
-
-/*
- * The following macros are used to get to a hub/bridge register, given
- * the base of the register space.
- */
-#define HUB_REG_PTR(_base, _off)	\
-	(volatile uint64_t *)((unsigned long)(_base) + (__psunsigned_t)(_off)))
+#define HUB_L(x)			(*((volatile typeof(*x) *)x))
+#define	HUB_S(x,d)			(*((volatile typeof(*x) *)x) = (d))
 
-#define HUB_REG_PTR_L(_base, _off)	\
-	HUB_L(HUB_REG_PTR((_base), (_off)))
+#define REMOTE_HUB_L(n, a)		HUB_L(REMOTE_HUB_ADDR((n), (a)))
+#define REMOTE_HUB_S(n, a, d)		HUB_S(REMOTE_HUB_ADDR((n), (a)), (d))
 
-#define HUB_REG_PTR_S(_base, _off, _data)	\
-	HUB_S(HUB_REG_PTR((_base), (_off)), (_data))
 
 #endif /* _ASM_IA64_SN_ADDRS_H */
diff -Nru a/include/asm-ia64/sn/arch.h b/include/asm-ia64/sn/arch.h
--- a/include/asm-ia64/sn/arch.h	2005-03-01 23:38:55 -08:00
+++ b/include/asm-ia64/sn/arch.h	2005-03-01 23:38:55 -08:00
@@ -20,7 +20,8 @@
  * Effectively, it's the maximum number of compact node ids (cnodeid_t).
  * This is not necessarily the same as MAX_NASIDS.
  */
-#define MAX_COMPACT_NODES       2048
+#define MAX_COMPACT_NODES	2048
+#define CPUS_PER_NODE		4
 
 extern void sn_flush_all_caches(long addr, long bytes);
 
diff -Nru a/include/asm-ia64/sn/klconfig.h b/include/asm-ia64/sn/klconfig.h
--- a/include/asm-ia64/sn/klconfig.h	2005-03-01 23:38:56 -08:00
+++ b/include/asm-ia64/sn/klconfig.h	2005-03-01 23:38:56 -08:00
@@ -29,7 +29,7 @@
 } kl_config_hdr_t;
 
 
-#define NODE_OFFSET_TO_LBOARD(nasid,off)        (lboard_t*)(NODE_CAC_BASE(nasid) + (off))
+#define NODE_OFFSET_TO_LBOARD(nasid,off)        (lboard_t*)(GLOBAL_CAC_ADDR((nasid), (off)))
 
 /*
  * The KLCONFIG area is organized as a LINKED LIST of BOARDs. A BOARD
diff -Nru a/include/asm-ia64/sn/leds.h b/include/asm-ia64/sn/leds.h
--- a/include/asm-ia64/sn/leds.h	2005-03-01 23:38:52 -08:00
+++ b/include/asm-ia64/sn/leds.h	2005-03-01 23:38:52 -08:00
@@ -9,6 +9,7 @@
 
 #include <asm/sn/addrs.h>
 #include <asm/sn/pda.h>
+#include <asm/sn/shub_mmr.h>
 
 #define LED0		(LOCAL_MMR_ADDR(SH_REAL_JUNK_BUS_LED0))
 #define LED_CPU_SHIFT	16
diff -Nru a/include/asm-ia64/sn/nodepda.h b/include/asm-ia64/sn/nodepda.h
--- a/include/asm-ia64/sn/nodepda.h	2005-03-01 23:39:18 -08:00
+++ b/include/asm-ia64/sn/nodepda.h	2005-03-01 23:39:18 -08:00
@@ -11,8 +11,8 @@
 
 #include <asm/semaphore.h>
 #include <asm/irq.h>
+#include <asm/sn/arch.h>
 #include <asm/sn/intr.h>
-#include <asm/sn/router.h>
 #include <asm/sn/pda.h>
 #include <asm/sn/bte.h>
 
diff -Nru a/include/asm-ia64/sn/pda.h b/include/asm-ia64/sn/pda.h
--- a/include/asm-ia64/sn/pda.h	2005-03-01 23:39:16 -08:00
+++ b/include/asm-ia64/sn/pda.h	2005-03-01 23:39:16 -08:00
@@ -37,17 +37,21 @@
 	 * Support for SN LEDs
 	 */
 	volatile short	*led_address;
+	u16		nasid_bitmask;
+	u8		shub2;
+	u8		nasid_shift;
+	u8		as_shift;
+	u8		shub_1_1_found;
 	u8		led_state;
 	u8		hb_state;	/* supports blinking heartbeat leds */
-	u8		shub_1_1_found;
 	unsigned int	hb_count;
 
 	unsigned int	idle_flag;
 	
 	volatile unsigned long *bedrock_rev_id;
 	volatile unsigned long *pio_write_status_addr;
+	unsigned long pio_write_status_val;
 	volatile unsigned long *pio_shub_war_cam_addr;
-	volatile unsigned long *mem_write_status_addr;
 
 	struct bteinfo_s *cpu_bte_if[BTES_PER_NODE];	/* cpu interface order */
 
@@ -76,7 +80,7 @@
  */
 DECLARE_PER_CPU(struct pda_s, pda_percpu);
 
-#define pda		(&__get_cpu_var(pda_percpu))
+#define pda		(&__ia64_per_cpu_var(pda_percpu))
 
 #define pdacpu(cpu)	(&per_cpu(pda_percpu, cpu))
 
@@ -84,5 +88,8 @@
  * Use this macro to test if shub 1.1 wars should be enabled
  */
 #define enable_shub_wars_1_1()	(pda->shub_1_1_found)
+
+#define is_shub2()	(pda->shub2)
+#define is_shub1()	(pda->shub2 == 0)
 
 #endif /* _ASM_IA64_SN_PDA_H */
diff -Nru a/include/asm-ia64/sn/router.h b/include/asm-ia64/sn/router.h
--- a/include/asm-ia64/sn/router.h	2005-03-01 23:38:54 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,618 +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_ROUTER_H
-#define _ASM_IA64_SN_ROUTER_H
-
-/*
- * Router Register definitions
- *
- * Macro argument _L always stands for a link number (1 to 8, inclusive).
- */
-
-#ifndef __ASSEMBLY__
-
-#include <asm/sn/arch.h>
-
-typedef uint64_t	router_reg_t;
-
-#define MAX_ROUTERS	64
-
-#define MAX_ROUTER_PATH	80
-
-#define ROUTER_REG_CAST		(volatile router_reg_t *)
-typedef signed char port_no_t;	 /* Type for router port number      */
-
-#else 
-
-#define ROUTERREG_CAST
-
-#endif /* __ASSEMBLY__ */
-
-#define MAX_ROUTER_PORTS	8	/* Max. number of ports on a router */
-
-#define ALL_PORTS ((1 << MAX_ROUTER_PORTS) - 1)	/* for 0 based references */
-
-#define PORT_INVALID		-1	/* Invalid port number              */
-
-#define	IS_META(_rp)	((_rp)->flags & PCFG_ROUTER_META)
-
-#define	IS_REPEATER(_rp)((_rp)->flags & PCFG_ROUTER_REPEATER)
-
-/*
- * RR_TURN makes a given number of clockwise turns (0 to 7) from an inport
- * port to generate an output port.
- *
- * RR_DISTANCE returns the number of turns necessary (0 to 7) to go from
- * an input port (_L1 = 1 to 8) to an output port ( _L2 = 1 to 8).
- *
- * These are written to work on unsigned data.
- */
-
-#define RR_TURN(_L, count)	((_L) + (count) > MAX_ROUTER_PORTS ?	\
-				 (_L) + (count) - MAX_ROUTER_PORTS :	\
-				 (_L) + (count))
-
-#define RR_DISTANCE(_LS, _LD)	((_LD) >= (_LS) ?			\
-				 (_LD) - (_LS) :			\
-				 (_LD) + MAX_ROUTER_PORTS - (_LS))
-
-/* Router register addresses */
-
-#define RR_STATUS_REV_ID	0x00000	/* Status register and Revision ID  */
-#define RR_PORT_RESET		0x00008	/* Multiple port reset              */
-#define RR_PROT_CONF		0x00010	/* Inter-partition protection conf. */
-#define RR_GLOBAL_PORT_DEF	0x00018 /* Global Port definitions          */
-#define RR_GLOBAL_PARMS0	0x00020	/* Parameters shared by all 8 ports */
-#define RR_GLOBAL_PARMS1	0x00028	/* Parameters shared by all 8 ports */
-#define RR_DIAG_PARMS		0x00030	/* Parameters for diag. testing     */
-#define RR_DEBUG_ADDR		0x00038 /* Debug address select - debug port*/
-#define RR_LB_TO_L2		0x00040 /* Local Block to L2 cntrl intf reg */ 
-#define RR_L2_TO_LB		0x00048 /* L2 cntrl intf to Local Block reg */
-#define RR_JBUS_CONTROL		0x00050 /* read/write timing for JBUS intf  */
-
-#define RR_SCRATCH_REG0		0x00100	/* Scratch 0 is 64 bits */
-#define RR_SCRATCH_REG1		0x00108	/* Scratch 1 is 64 bits */
-#define RR_SCRATCH_REG2		0x00110	/* Scratch 2 is 64 bits */
-#define RR_SCRATCH_REG3		0x00118	/* Scratch 3 is 1 bit */
-#define RR_SCRATCH_REG4		0x00120	/* Scratch 4 is 1 bit */
-
-#define RR_JBUS0(_D)		(((_D) & 0x7) << 3 | 0x00200) /* JBUS0 addresses   */
-#define RR_JBUS1(_D)		(((_D) & 0x7) << 3 | 0x00240) /* JBUS1 addresses   */
-
-#define RR_SCRATCH_REG0_WZ	0x00500	/* Scratch 0 is 64 bits */
-#define RR_SCRATCH_REG1_WZ	0x00508	/* Scratch 1 is 64 bits */
-#define RR_SCRATCH_REG2_WZ	0x00510	/* Scratch 2 is 64 bits */
-#define RR_SCRATCH_REG3_SZ	0x00518	/* Scratch 3 is 1 bit */
-#define RR_SCRATCH_REG4_SZ	0x00520	/* Scratch 4 is 1 bit */
-
-#define RR_VECTOR_HW_BAR(context) (0x08000 | (context)<<3) /* barrier config registers */
-/* Port-specific registers (_L is the link number from 1 to 8) */
-
-#define RR_PORT_PARMS(_L)	(((_L+1) & 0xe) << 15 | ((_L+1) & 0x1) << 11 | 0x0000) /* LLP parameters     */
-#define RR_STATUS_ERROR(_L)	(((_L+1) & 0xe) << 15 | ((_L+1) & 0x1) << 11 | 0x0008) /* Port-related errs  */
-#define RR_CHANNEL_TEST(_L)	(((_L+1) & 0xe) << 15 | ((_L+1) & 0x1) << 11 | 0x0010) /* Port LLP chan test */
-#define RR_RESET_MASK(_L)	(((_L+1) & 0xe) << 15 | ((_L+1) & 0x1) << 11 | 0x0018) /* Remote reset mask  */
-#define RR_HISTOGRAM0(_L)	(((_L+1) & 0xe) << 15 | ((_L+1) & 0x1) << 11 | 0x0020) /* Port usage histgrm */
-#define RR_HISTOGRAM1(_L)	(((_L+1) & 0xe) << 15 | ((_L+1) & 0x1) << 11 | 0x0028) /* Port usage histgrm */
-#define RR_HISTOGRAM0_WC(_L)	(((_L+1) & 0xe) << 15 | ((_L+1) & 0x1) << 11 | 0x0030) /* Port usage histgrm */
-#define RR_HISTOGRAM1_WC(_L)	(((_L+1) & 0xe) << 15 | ((_L+1) & 0x1) << 11 | 0x0038) /* Port usage histgrm */
-#define RR_ERROR_CLEAR(_L)	(((_L+1) & 0xe) << 15 | ((_L+1) & 0x1) << 11 | 0x0088) /* Read/clear errors  */
-#define RR_GLOBAL_TABLE0(_L)	(((_L+1) & 0xe) << 15 | ((_L+1) & 0x1) << 11 | 0x0100) /* starting address of global table for this port */
-#define RR_GLOBAL_TABLE(_L, _x) (RR_GLOBAL_TABLE0(_L) + ((_x) << 3))
-#define RR_LOCAL_TABLE0(_L)	(((_L+1) & 0xe) << 15 | ((_L+1) & 0x1) << 11 | 0x0200) /* starting address of local table for this port */
-#define RR_LOCAL_TABLE(_L, _x) (RR_LOCAL_TABLE0(_L) + ((_x) << 3))
-
-#define RR_META_ENTRIES		16
-
-#define RR_LOCAL_ENTRIES	128
-
-/*
- * RR_STATUS_REV_ID mask and shift definitions
- */
-
-#define RSRI_INPORT_SHFT	52
-#define RSRI_INPORT_MASK	(0xfUL << 52)
-#define RSRI_LINKWORKING_BIT(_L) (35 + 2 * (_L))
-#define RSRI_LINKWORKING(_L)	(1UL << (35 + 2 * (_L)))
-#define RSRI_LINKRESETFAIL(_L)	(1UL << (34 + 2 * (_L)))
-#define RSRI_LSTAT_SHFT(_L)	(34 + 2 * (_L))
-#define RSRI_LSTAT_MASK(_L)	(0x3UL << 34 + 2 * (_L))
-#define RSRI_LOCALSBERROR	(1UL << 35)
-#define RSRI_LOCALSTUCK		(1UL << 34)
-#define RSRI_LOCALBADVEC	(1UL << 33)
-#define RSRI_LOCALTAILERR	(1UL << 32)
-#define RSRI_LOCAL_SHFT 	32
-#define RSRI_LOCAL_MASK		(0xfUL << 32)
-#define RSRI_CHIPREV_SHFT	28
-#define RSRI_CHIPREV_MASK	(0xfUL << 28)
-#define RSRI_CHIPID_SHFT	12
-#define RSRI_CHIPID_MASK	(0xffffUL << 12)
-#define RSRI_MFGID_SHFT		1
-#define RSRI_MFGID_MASK		(0x7ffUL << 1)
-
-#define RSRI_LSTAT_WENTDOWN	0
-#define RSRI_LSTAT_RESETFAIL	1
-#define RSRI_LSTAT_LINKUP	2
-#define RSRI_LSTAT_NOTUSED	3
-
-/*
- * RR_PORT_RESET mask definitions
- */
-
-#define RPRESET_WARM		(1UL << 9)
-#define RPRESET_LINK(_L)	(1UL << (_L))
-#define RPRESET_LOCAL		1UL
-
-/*
- * RR_PROT_CONF mask and shift definitions
- */
-
-#define RPCONF_DIRCMPDIS_SHFT	13
-#define RPCONF_DIRCMPDIS_MASK	(1UL << 13)
-#define RPCONF_FORCELOCAL	(1UL << 12)
-#define RPCONF_FLOCAL_SHFT	12
-#define RPCONF_METAID_SHFT	8
-#define RPCONF_METAID_MASK	(0xfUL << 8)
-#define RPCONF_RESETOK(_L)	(1UL << ((_L) - 1))
-
-/*
- * RR_GLOBAL_PORT_DEF mask and shift definitions
- */
-
-#define RGPD_MGLBLNHBR_ID_SHFT	12	/* -global neighbor ID */
-#define RGPD_MGLBLNHBR_ID_MASK	(0xfUL << 12)
-#define RGPD_MGLBLNHBR_VLD_SHFT	11	/* -global neighbor Valid */
-#define RGPD_MGLBLNHBR_VLD_MASK	(0x1UL << 11)
-#define RGPD_MGLBLPORT_SHFT	8	/* -global neighbor Port */
-#define RGPD_MGLBLPORT_MASK	(0x7UL << 8)
-#define RGPD_PGLBLNHBR_ID_SHFT	4	/* +global neighbor ID */
-#define RGPD_PGLBLNHBR_ID_MASK	(0xfUL << 4)
-#define RGPD_PGLBLNHBR_VLD_SHFT	3	/* +global neighbor Valid */
-#define RGPD_PGLBLNHBR_VLD_MASK	(0x1UL << 3)
-#define RGPD_PGLBLPORT_SHFT	0	/* +global neighbor Port */
-#define RGPD_PGLBLPORT_MASK	(0x7UL << 0)
-
-#define GLBL_PARMS_REGS		2	/* Two Global Parms registers */
-
-/*
- * RR_GLOBAL_PARMS0 mask and shift definitions
- */
-
-#define RGPARM0_ARB_VALUE_SHFT	54	/* Local Block Arbitration State */
-#define RGPARM0_ARB_VALUE_MASK	(0x7UL << 54)
-#define RGPARM0_ROTATEARB_SHFT	53	/* Rotate Local Block Arbitration */
-#define RGPARM0_ROTATEARB_MASK	(1UL << 53)
-#define RGPARM0_FAIREN_SHFT	52	/* Fairness logic Enable */
-#define RGPARM0_FAIREN_MASK	(1UL << 52)
-#define RGPARM0_LOCGNTTO_SHFT	40	/* Local grant timeout */
-#define RGPARM0_LOCGNTTO_MASK	(0xfffUL << 40)
-#define RGPARM0_DATELINE_SHFT	38	/* Dateline crossing router */
-#define RGPARM0_DATELINE_MASK	(1UL << 38)
-#define RGPARM0_MAXRETRY_SHFT	28	/* Max retry count */
-#define RGPARM0_MAXRETRY_MASK	(0x3ffUL << 28)
-#define RGPARM0_URGWRAP_SHFT	20	/* Urgent wrap */
-#define RGPARM0_URGWRAP_MASK	(0xffUL << 20)
-#define RGPARM0_DEADLKTO_SHFT	16	/* Deadlock timeout */
-#define RGPARM0_DEADLKTO_MASK	(0xfUL << 16)
-#define RGPARM0_URGVAL_SHFT	12	/* Urgent value */
-#define RGPARM0_URGVAL_MASK	(0xfUL << 12)
-#define RGPARM0_VCHSELEN_SHFT	11	/* VCH_SEL_EN */
-#define RGPARM0_VCHSELEN_MASK	(1UL << 11)
-#define RGPARM0_LOCURGTO_SHFT	9	/* Local urgent timeout */
-#define RGPARM0_LOCURGTO_MASK	(0x3UL << 9)
-#define RGPARM0_TAILVAL_SHFT	5	/* Tail value */
-#define RGPARM0_TAILVAL_MASK	(0xfUL << 5)
-#define RGPARM0_CLOCK_SHFT	1	/* Global clock select */
-#define RGPARM0_CLOCK_MASK	(0xfUL << 1)
-#define RGPARM0_BYPEN_SHFT	0
-#define RGPARM0_BYPEN_MASK	1UL	/* Bypass enable */
-
-/*
- * RR_GLOBAL_PARMS1 shift and mask definitions
- */
-
-#define RGPARM1_TTOWRAP_SHFT	12	/* Tail timeout wrap */
-#define RGPARM1_TTOWRAP_MASK	(0xfffffUL << 12)
-#define RGPARM1_AGERATE_SHFT	8	/* Age rate */
-#define RGPARM1_AGERATE_MASK	(0xfUL << 8)
-#define RGPARM1_JSWSTAT_SHFT	0	/* JTAG Sw Register bits */
-#define RGPARM1_JSWSTAT_MASK	(0xffUL << 0)
-
-/*
- * RR_DIAG_PARMS mask and shift definitions
- */
-
-#define RDPARM_ABSHISTOGRAM	(1UL << 17)	/* Absolute histgrm */
-#define RDPARM_DEADLOCKRESET	(1UL << 16)	/* Reset on deadlck */
-#define RDPARM_DISABLE(_L)	(1UL << ((_L) +  7))
-#define RDPARM_SENDERROR(_L)	(1UL << ((_L) -  1))
-
-/*
- * RR_DEBUG_ADDR mask and shift definitions
- */
-
-#define RDA_DATA_SHFT		10	/* Observed debug data */
-#define RDA_DATA_MASK		(0xffffUL << 10)
-#define RDA_ADDR_SHFT		0	/* debug address for data */
-#define RDA_ADDR_MASK		(0x3ffUL << 0)
-
-/*
- * RR_LB_TO_L2 mask and shift definitions
- */
-
-#define RLBTOL2_DATA_VLD_SHFT	32	/* data is valid for JTAG controller */
-#define RLBTOL2_DATA_VLD_MASK	(1UL << 32)
-#define RLBTOL2_DATA_SHFT	0	/* data bits for JTAG controller */
-#define RLBTOL2_DATA_MASK	0xffffffffUL
-
-/*
- * RR_L2_TO_LB mask and shift definitions
- */
-
-#define RL2TOLB_DATA_VLD_SHFT	33	/* data is valid from JTAG controller */
-#define RL2TOLB_DATA_VLD_MASK	(1UL << 33)
-#define RL2TOLB_PARITY_SHFT	32	/* sw implemented parity for data */
-#define RL2TOLB_PARITY_MASK	(1UL << 32)
-#define RL2TOLB_DATA_SHFT	0	/* data bits from JTAG controller */
-#define RL2TOLB_DATA_MASK	0xffffffffUL
-
-/*
- * RR_JBUS_CONTROL mask and shift definitions
- */
-
-#define RJC_POS_BITS_SHFT	20	/* Router position bits */
-#define RJC_POS_BITS_MASK	(0xfUL << 20)
-#define RJC_RD_DATA_STROBE_SHFT	16	/* count when read data is strobed in */
-#define RJC_RD_DATA_STROBE_MASK	(0xfUL << 16)
-#define RJC_WE_OE_HOLD_SHFT	8	/* time OE or WE is held */
-#define RJC_WE_OE_HOLD_MASK	(0xffUL << 8)
-#define RJC_ADDR_SET_HLD_SHFT	0	/* time address driven around OE/WE */
-#define RJC_ADDR_SET_HLD_MASK	0xffUL
-
-/*
- * RR_SCRATCH_REGx mask and shift definitions
- *  note: these fields represent a software convention, and are not
- *        understood/interpreted by the hardware. 
- */
-
-#define	RSCR0_BOOTED_SHFT	63
-#define	RSCR0_BOOTED_MASK	(0x1UL << RSCR0_BOOTED_SHFT)
-#define RSCR0_LOCALID_SHFT	56
-#define RSCR0_LOCALID_MASK	(0x7fUL << RSCR0_LOCALID_SHFT)
-#define	RSCR0_UNUSED_SHFT	48
-#define	RSCR0_UNUSED_MASK	(0xffUL << RSCR0_UNUSED_SHFT)
-#define RSCR0_NIC_SHFT		0
-#define RSCR0_NIC_MASK		0xffffffffffffUL
-
-#define RSCR1_MODID_SHFT	0
-#define RSCR1_MODID_MASK	0xffffUL
-
-/*
- * RR_VECTOR_HW_BAR mask and shift definitions
- */
-
-#define BAR_TX_SHFT		27	/* Barrier in trans(m)it when read */
-#define BAR_TX_MASK		(1UL << BAR_TX_SHFT)
-#define BAR_VLD_SHFT		26	/* Valid Configuration */
-#define BAR_VLD_MASK		(1UL << BAR_VLD_SHFT)
-#define BAR_SEQ_SHFT		24	/* Sequence number */
-#define BAR_SEQ_MASK		(3UL << BAR_SEQ_SHFT)
-#define BAR_LEAFSTATE_SHFT	18	/* Leaf State */
-#define BAR_LEAFSTATE_MASK	(0x3fUL << BAR_LEAFSTATE_SHFT)
-#define BAR_PARENT_SHFT		14	/* Parent Port */
-#define BAR_PARENT_MASK		(0xfUL << BAR_PARENT_SHFT)
-#define BAR_CHILDREN_SHFT	6	/* Child Select port bits */
-#define BAR_CHILDREN_MASK	(0xffUL << BAR_CHILDREN_SHFT)
-#define BAR_LEAFCOUNT_SHFT	0	/* Leaf Count to trigger parent */
-#define BAR_LEAFCOUNT_MASK	0x3fUL
-
-/*
- * RR_PORT_PARMS(_L) mask and shift definitions
- */
-
-#define RPPARM_MIPRESETEN_SHFT	29	/* Message In Progress reset enable */
-#define RPPARM_MIPRESETEN_MASK	(0x1UL << 29)
-#define RPPARM_UBAREN_SHFT	28	/* Enable user barrier requests */
-#define RPPARM_UBAREN_MASK	(0x1UL << 28)
-#define RPPARM_OUTPDTO_SHFT	24	/* Output Port Deadlock TO value */
-#define RPPARM_OUTPDTO_MASK	(0xfUL << 24)
-#define RPPARM_PORTMATE_SHFT	21	/* Port Mate for the port */
-#define RPPARM_PORTMATE_MASK	(0x7UL << 21)
-#define RPPARM_HISTEN_SHFT	20	/* Histogram counter enable */
-#define RPPARM_HISTEN_MASK	(0x1UL << 20)
-#define RPPARM_HISTSEL_SHFT	18
-#define RPPARM_HISTSEL_MASK	(0x3UL << 18)
-#define RPPARM_DAMQHS_SHFT	16
-#define RPPARM_DAMQHS_MASK	(0x3UL << 16)
-#define RPPARM_NULLTO_SHFT	10
-#define RPPARM_NULLTO_MASK	(0x3fUL << 10)
-#define RPPARM_MAXBURST_SHFT	0
-#define RPPARM_MAXBURST_MASK	0x3ffUL
-
-/*
- * NOTE: Normally the kernel tracks only UTILIZATION statistics.
- * The other 2 should not be used, except during any experimentation
- * with the router.
- */
-#define RPPARM_HISTSEL_AGE	0	/* Histogram age characterization.  */
-#define RPPARM_HISTSEL_UTIL	1	/* Histogram link utilization 	    */
-#define RPPARM_HISTSEL_DAMQ	2	/* Histogram DAMQ characterization. */
-
-/*
- * RR_STATUS_ERROR(_L) and RR_ERROR_CLEAR(_L) mask and shift definitions
- */
-#define RSERR_POWERNOK		(1UL << 38)
-#define RSERR_PORT_DEADLOCK     (1UL << 37)
-#define RSERR_WARMRESET         (1UL << 36)
-#define RSERR_LINKRESET         (1UL << 35)
-#define RSERR_RETRYTIMEOUT      (1UL << 34)
-#define RSERR_FIFOOVERFLOW	(1UL << 33)
-#define RSERR_ILLEGALPORT	(1UL << 32)
-#define RSERR_DEADLOCKTO_SHFT	28
-#define RSERR_DEADLOCKTO_MASK	(0xfUL << 28)
-#define RSERR_RECVTAILTO_SHFT	24
-#define RSERR_RECVTAILTO_MASK	(0xfUL << 24)
-#define RSERR_RETRYCNT_SHFT	16
-#define RSERR_RETRYCNT_MASK	(0xffUL << 16)
-#define RSERR_CBERRCNT_SHFT	8
-#define RSERR_CBERRCNT_MASK	(0xffUL << 8)
-#define RSERR_SNERRCNT_SHFT	0
-#define RSERR_SNERRCNT_MASK	(0xffUL << 0)
-
-
-#define PORT_STATUS_UP		(1 << 0)	/* Router link up */
-#define PORT_STATUS_FENCE	(1 << 1)	/* Router link fenced */
-#define PORT_STATUS_RESETFAIL	(1 << 2)	/* Router link didnot 
-						 * come out of reset */
-#define PORT_STATUS_DISCFAIL	(1 << 3)	/* Router link failed after 
-						 * out of reset but before
-						 * router tables were
-						 * programmed
-						 */
-#define PORT_STATUS_KERNFAIL	(1 << 4)	/* Router link failed
-						 * after reset and the 
-						 * router tables were
-						 * programmed
-						 */
-#define PORT_STATUS_UNDEF	(1 << 5)	/* Unable to pinpoint
-						 * why the router link
-						 * went down
-						 */	
-#define PROBE_RESULT_BAD	-1		/* Set if any of the router
-						 * links failed after reset
-						 */
-#define PROBE_RESULT_GOOD	0		/* Set if all the router links
-						 * which came out of reset 
-						 * are up
-						 */
-
-/* Should be enough for 256 CPUs */
-#define MAX_RTR_BREADTH		64		/* Max # of routers possible */
-
-/* Get the require set of bits in a var. corr to a sequence of bits  */
-#define GET_FIELD(var, fname) \
-        ((var) >> fname##_SHFT & fname##_MASK >> fname##_SHFT)
-/* Set the require set of bits in a var. corr to a sequence of bits  */
-#define SET_FIELD(var, fname, fval) \
-        ((var) = (var) & ~fname##_MASK | (uint64_t) (fval) << fname##_SHFT)
-
-
-#ifndef __ASSEMBLY__
-
-typedef struct router_map_ent_s {
-	uint64_t	nic;
-	moduleid_t	module;
-	char		slot;
-} router_map_ent_t;
-
-struct rr_status_error_fmt {
-	uint64_t	rserr_unused		: 30,
-			rserr_fifooverflow	: 1,
-			rserr_illegalport	: 1,
-			rserr_deadlockto	: 4,
-			rserr_recvtailto	: 4,
-			rserr_retrycnt		: 8,
-			rserr_cberrcnt		: 8,
-			rserr_snerrcnt		: 8;
-};
-
-/*
- * This type is used to store "absolute" counts of router events
- */
-typedef int	router_count_t;
-
-/* All utilizations are on a scale from 0 - 1023. */
-#define RP_BYPASS_UTIL	0
-#define RP_RCV_UTIL	1
-#define RP_SEND_UTIL	2
-#define RP_TOTAL_PKTS	3	/* Free running clock/packet counter */
-
-#define RP_NUM_UTILS	3
-
-#define RP_HIST_REGS	2
-#define RP_NUM_BUCKETS  4
-#define RP_HIST_TYPES	3
-
-#define RP_AGE0		0
-#define RP_AGE1		1
-#define RP_AGE2		2
-#define RP_AGE3		3
-
-
-#define RR_UTIL_SCALE	1024
-
-/*
- * Router port-oriented information
- */
-typedef struct router_port_info_s {
-	router_reg_t	rp_histograms[RP_HIST_REGS];/* Port usage info */
-	router_reg_t	rp_port_error;		/* Port error info */
-	router_count_t	rp_retry_errors;	/* Total retry errors */
-	router_count_t	rp_sn_errors;		/* Total sn errors */
-	router_count_t	rp_cb_errors;		/* Total cb errors */
-	int		rp_overflows;		/* Total count overflows */
-	int		rp_excess_err;		/* Port has excessive errors */
-	ushort		rp_util[RP_NUM_BUCKETS];/* Port utilization */
-} router_port_info_t;
-
-#define ROUTER_INFO_VERSION	7
-
-struct lboard_s;
-
-/*
- * Router information
- */
-typedef struct router_info_s {
-	char		ri_version;	/* structure version		    */
-	cnodeid_t	ri_cnode;	/* cnode of its legal guardian hub  */
-	nasid_t		ri_nasid;	/* Nasid of same 		    */
-	char		ri_ledcache;	/* Last LED bitmap		    */
-	char		ri_leds;	/* Current LED bitmap		    */
-	char		ri_portmask;	/* Active port bitmap		    */
-	router_reg_t	ri_stat_rev_id;	/* Status rev ID value		    */
-	uint64_t	ri_vector;	/* vector from guardian to router   */
-	int		ri_writeid;	/* router's vector write ID	    */
-	int64_t	ri_timebase;	/* Time of first sample		    */
-	int64_t	ri_timestamp;	/* Time of last sample		    */
-	router_port_info_t ri_port[MAX_ROUTER_PORTS]; /* per port info      */
-	moduleid_t	ri_module;	/* Which module are we in?	    */
-	char		ri_slotnum;	/* Which slot are we in?	    */
-	router_reg_t	ri_glbl_parms[GLBL_PARMS_REGS];
-					/* Global parms0&1 register contents*/
-	void *		ri_vertex;	/* hardware graph vertex            */
-	router_reg_t	ri_prot_conf;	/* protection config. register	    */
-	int64_t	ri_per_minute;	/* Ticks per minute		    */
-
-	/*
-	 * Everything below here is for kernel use only and may change at	
-	 * at any time with or without a change in the revision number
-	 *
-	 * Any pointers or things that come and go with DEBUG must go at
- 	 * the bottom of the structure, below the user stuff.
-	 */
-	char		ri_hist_type;   /* histogram type		    */
-	void *		ri_guardian;	/* guardian node for the router	    */
-	int64_t	ri_last_print;	/* When did we last print	    */
-	char		ri_print;	/* Should we print 		    */
-	char 		ri_just_blink;	/* Should we blink the LEDs         */
-	
-#ifdef DEBUG
-	int64_t	ri_deltatime;	/* Time it took to sample	    */
-#endif
-	spinlock_t	ri_lock;	/* Lock for access to router info   */
-	uint64_t	*ri_vecarray;	/* Pointer to array of vectors	    */
-	struct lboard_s	*ri_brd;	/* Pointer to board structure	    */
-	char *		ri_name;	/* This board's hwg path 	    */
-        unsigned char	ri_port_maint[MAX_ROUTER_PORTS]; /* should we send a 
-					message to availmon */
-} router_info_t;
-
-
-/* Router info location specifiers */
-
-#define RIP_PROMLOG			2	/* Router info in promlog */
-#define RIP_CONSOLE			4	/* Router info on console */
-
-/* 
- * Router info hanging in the nodepda 
- */
-typedef struct nodepda_router_info_s {
-	void *	 	router_vhdl;	/* vertex handle of the router 	    */
-	short		router_port;	/* port thru which we entered       */
-	short		router_portmask;
-	moduleid_t	router_module;	/* module in which router is there  */
-	char		router_slot;	/* router slot			    */
-	unsigned char	router_type;	/* kind of router 		    */
-	uint64_t	router_vector;	/* vector from the guardian node    */
-
-	router_info_t	*router_infop;	/* info hanging off the hwg vertex  */
-	struct nodepda_router_info_s *router_next;
-	                                /* pointer to next element 	    */
-} nodepda_router_info_t;
-
-#define ROUTER_NAME_SIZE	20	/* Max size of a router name */
-
-#define NORMAL_ROUTER_NAME	"normal_router"
-#define NULL_ROUTER_NAME	"null_router"
-#define META_ROUTER_NAME	"meta_router"
-#define REPEATER_ROUTER_NAME	"repeater_router"
-#define UNKNOWN_ROUTER_NAME	"unknown_router" 
-
-/* The following definitions are needed by the router traversing
- * code either using the hardware graph or using vector operations.
- */
-/* Structure of the router queue element */
-typedef struct router_elt_s {
-	union {
-		/* queue element structure during router probing */
-		struct {
-			/* number-in-a-can (unique) for the router */
-			nic_t		nic;	
-			/* vector route from the master hub to 
-			 * this router.
-			 */
-			uint64_t	vec;	
-			/* port status */
-			uint64_t	status;	
-			char		port_status[MAX_ROUTER_PORTS + 1];
-		} r_elt;
-		/* queue element structure during router guardian 
-		 * assignment
-		 */
-		struct {
-			/* vertex handle for the router */
-			void *		vhdl;
-			/* guardian for this router */
-			void *		guard;	
-			/* vector router from the guardian to the router */
-			uint64_t	vec;
-		} k_elt;
-	} u;
-	                        /* easy to use port status interpretation */
-} router_elt_t;
-
-/* structure of the router queue */
-
-typedef struct router_queue_s {
-	char		head;	/* Point where a queue element is inserted */
-	char		tail;	/* Point where a queue element is removed */
-	int		type;
-	router_elt_t	array[MAX_RTR_BREADTH];
-	                        /* Entries for queue elements */
-} router_queue_t;
-
-
-#endif /* __ASSEMBLY__ */
-
-/*
- * RR_HISTOGRAM(_L) mask and shift definitions
- * There are two 64 bit histogram registers, so the following macros take
- * into account dealing with an array of 4 32 bit values indexed by _x
- */
-
-#define RHIST_BUCKET_SHFT(_x)	(32 * ((_x) & 0x1))
-#define RHIST_BUCKET_MASK(_x)	(0xffffffffUL << RHIST_BUCKET_SHFT((_x) & 0x1))
-#define RHIST_GET_BUCKET(_x, _reg)	\
-	((RHIST_BUCKET_MASK(_x) & ((_reg)[(_x) >> 1])) >> RHIST_BUCKET_SHFT(_x))
-
-/*
- * RR_RESET_MASK(_L) mask and shift definitions
- */
-
-#define RRM_RESETOK(_L)		(1UL << ((_L) - 1))
-#define RRM_RESETOK_ALL		ALL_PORTS
-
-/*
- * RR_META_TABLE(_x) and RR_LOCAL_TABLE(_x) mask and shift definitions
- */
-
-#define RTABLE_SHFT(_L)		(4 * ((_L) - 1))
-#define RTABLE_MASK(_L)		(0x7UL << RTABLE_SHFT(_L))
-
-#endif /* _ASM_IA64_SN_ROUTER_H */
diff -Nru a/include/asm-ia64/sn/rw_mmr.h b/include/asm-ia64/sn/rw_mmr.h
--- a/include/asm-ia64/sn/rw_mmr.h	2005-03-01 23:38:44 -08:00
+++ b/include/asm-ia64/sn/rw_mmr.h	2005-03-01 23:38:44 -08:00
@@ -14,8 +14,8 @@
  * uncached physical addresses.
  * 	pio_phys_read_mmr  - read an MMR
  * 	pio_phys_write_mmr - write an MMR
- * 	pio_atomic_phys_write_mmrs - atomically write 2 MMRs with psr.ic=0
- * 		(interrupt collection)
+ * 	pio_atomic_phys_write_mmrs - atomically write 1 or 2 MMRs with psr.ic=0
+ *		Second MMR will be skipped if address is NULL
  *
  * Addresses passed to these routines should be uncached physical addresses
  * ie., 0x80000....
@@ -61,13 +61,14 @@
         asm volatile
             ("mov r2=psr;;"
              "rsm psr.i | psr.dt | psr.ic;;"
+	     "cmp.ne p9,p0=%2,r0;"
              "srlz.i;;"
              "st8.rel [%0]=%1;"
-             "st8.rel [%2]=%3;;"
+             "(p9) st8.rel [%2]=%3;;"
              "mov psr.l=r2;;"
              "srlz.i;;"
 	     :: "r"(mmr1), "r"(val1), "r"(mmr2), "r"(val2)
-             : "r2", "memory");
+             : "p9", "r2", "memory");
 }            
 
 #endif /* _ASM_IA64_SN_RW_MMR_H */
diff -Nru a/include/asm-ia64/sn/shub_mmr.h b/include/asm-ia64/sn/shub_mmr.h
--- a/include/asm-ia64/sn/shub_mmr.h	2005-03-01 23:39:09 -08:00
+++ b/include/asm-ia64/sn/shub_mmr.h	2005-03-01 23:39:09 -08:00
@@ -14,117 +14,96 @@
 /*                        Register "SH_IPI_INT"                         */
 /*               SHub Inter-Processor Interrupt Registers               */
 /* ==================================================================== */
-#define SH_IPI_INT                               0x0000000110000380UL
-#define SH_IPI_INT_MASK                          0x8ff3ffffffefffffUL
-#define SH_IPI_INT_INIT                          0x0000000000000000UL
+#define SH1_IPI_INT                               0x0000000110000380
+#define SH2_IPI_INT                               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                     0x0000000000000007UL
+#define SH_IPI_INT_TYPE_MASK                     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                      0x0000000000000008UL
+#define SH_IPI_INT_AGT_MASK                      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                      0x00000000000ffff0UL
+#define SH_IPI_INT_PID_MASK                      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                     0x0003ffffffe00000UL
+#define SH_IPI_INT_BASE_MASK                     0x0003ffffffe00000
 
 /*   SH_IPI_INT_IDX                                                     */
 /*   Description:  Targeted McKinley interrupt vector                   */
 #define SH_IPI_INT_IDX_SHFT                      52
-#define SH_IPI_INT_IDX_MASK                      0x0ff0000000000000UL
+#define SH_IPI_INT_IDX_MASK                      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                     0x8000000000000000UL
+#define SH_IPI_INT_SEND_MASK                     0x8000000000000000
 
 /* ==================================================================== */
 /*                     Register "SH_EVENT_OCCURRED"                     */
 /*                    SHub Interrupt Event Occurred                     */
 /* ==================================================================== */
-#define SH_EVENT_OCCURRED                        0x0000000110010000UL
-#define SH_EVENT_OCCURRED_ALIAS                  0x0000000110010008UL
+#define SH1_EVENT_OCCURRED                        0x0000000110010000
+#define SH1_EVENT_OCCURRED_ALIAS                  0x0000000110010008
+#define SH2_EVENT_OCCURRED                        0x0000000010010000
+#define SH2_EVENT_OCCURRED_ALIAS                  0x0000000010010008
 
 /* ==================================================================== */
 /*                     Register "SH_PI_CAM_CONTROL"                     */
 /*                      CRB CAM MMR Access Control                      */
 /* ==================================================================== */
-#ifndef __ASSEMBLY__
-#define SH_PI_CAM_CONTROL                        0x0000000120050300UL
-#else
-#define SH_PI_CAM_CONTROL                        0x0000000120050300
-#endif
+#define SH1_PI_CAM_CONTROL                        0x0000000120050300
 
 /* ==================================================================== */
 /*                        Register "SH_SHUB_ID"                         */
 /*                            SHub ID Number                            */
 /* ==================================================================== */
-#define SH_SHUB_ID                               0x0000000110060580UL
-#define SH_SHUB_ID_REVISION_SHFT                 28
-#define SH_SHUB_ID_REVISION_MASK                 0x00000000f0000000
-
-/* ==================================================================== */
-/*                         Register "SH_PTC_0"                          */
-/*       Puge Translation Cache Message Configuration Information       */
-/* ==================================================================== */
-#define SH_PTC_0                                 0x00000001101a0000UL
-#define SH_PTC_1                                 0x00000001101a0080UL
+#define SH1_SHUB_ID                               0x0000000110060580
+#define SH1_SHUB_ID_REVISION_SHFT                 28
+#define SH1_SHUB_ID_REVISION_MASK                 0x00000000f0000000
 
 /* ==================================================================== */
 /*                          Register "SH_RTC"                           */
 /*                           Real-time Clock                            */
 /* ==================================================================== */
-#define SH_RTC                                   0x00000001101c0000UL
-#define SH_RTC_MASK                              0x007fffffffffffffUL
-
-/* ==================================================================== */
-/*                 Register "SH_MEMORY_WRITE_STATUS_0|1"                */
-/*                    Memory Write Status for CPU 0 & 1                 */
-/* ==================================================================== */
-#define SH_MEMORY_WRITE_STATUS_0                 0x0000000120070000UL
-#define SH_MEMORY_WRITE_STATUS_1                 0x0000000120070080UL
+#define SH1_RTC                                   0x00000001101c0000
+#define SH2_RTC					  0x00000002101c0000
+#define SH_RTC_MASK                               0x007fffffffffffff
 
 /* ==================================================================== */
 /*                   Register "SH_PIO_WRITE_STATUS_0|1"                 */
 /*                      PIO Write Status for CPU 0 & 1                  */
 /* ==================================================================== */
-#ifndef __ASSEMBLY__
-#define SH_PIO_WRITE_STATUS_0                    0x0000000120070200UL
-#define SH_PIO_WRITE_STATUS_1                    0x0000000120070280UL
+#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
 
 /*   SH_PIO_WRITE_STATUS_0_WRITE_DEADLOCK                               */
 /*   Description:  Deadlock response detected                           */
-#define SH_PIO_WRITE_STATUS_0_WRITE_DEADLOCK_SHFT 1
-#define SH_PIO_WRITE_STATUS_0_WRITE_DEADLOCK_MASK 0x0000000000000002
+#define SH_PIO_WRITE_STATUS_WRITE_DEADLOCK_SHFT 1
+#define SH_PIO_WRITE_STATUS_WRITE_DEADLOCK_MASK 0x0000000000000002
 
 /*   SH_PIO_WRITE_STATUS_0_PENDING_WRITE_COUNT                          */
 /*   Description:  Count of currently pending PIO writes                */
-#define SH_PIO_WRITE_STATUS_0_PENDING_WRITE_COUNT_SHFT 56
-#define SH_PIO_WRITE_STATUS_0_PENDING_WRITE_COUNT_MASK 0x3f00000000000000UL
-#else
-#define SH_PIO_WRITE_STATUS_0                    0x0000000120070200
-#define SH_PIO_WRITE_STATUS_0_PENDING_WRITE_COUNT_SHFT 56
-#define SH_PIO_WRITE_STATUS_0_WRITE_DEADLOCK_SHFT 1
-#endif
+#define SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_SHFT 56
+#define SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_MASK 0x3f00000000000000
 
 /* ==================================================================== */
 /*                Register "SH_PIO_WRITE_STATUS_0_ALIAS"                */
 /* ==================================================================== */
-#ifndef __ASSEMBLY__
-#define SH_PIO_WRITE_STATUS_0_ALIAS              0x0000000120070208UL
-#else
-#define SH_PIO_WRITE_STATUS_0_ALIAS              0x0000000120070208
-#endif
+#define SH1_PIO_WRITE_STATUS_0_ALIAS              0x0000000120070208
+#define SH2_PIO_WRITE_STATUS_0_ALIAS              0x0000000020070208
 
 /* ==================================================================== */
 /*                     Register "SH_EVENT_OCCURRED"                     */
@@ -151,61 +130,85 @@
 #define SH_EVENT_OCCURRED_II_INT1_MASK           0x0000000040000000
 
 /* ==================================================================== */
-/*                         Register "SH_PTC_0"                          */
+/*                         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
+
+/* ==================================================================== */
+/*                         Register "SH1_PTC_0"                         */
 /*       Puge Translation Cache Message Configuration Information       */
 /* ==================================================================== */
-#define SH_PTC_0                                 0x00000001101a0000UL
-#define SH_PTC_0_MASK                            0x80000000fffffffd
-#define SH_PTC_0_INIT                            0x0000000000000000
+#define SH1_PTC_0                                 0x00000001101a0000
 
-/*   SH_PTC_0_A                                                         */
+/*   SH1_PTC_0_A                                                        */
 /*   Description:  Type                                                 */
-#define SH_PTC_0_A_SHFT                          0
-#define SH_PTC_0_A_MASK                          0x0000000000000001
+#define SH1_PTC_0_A_SHFT                          0
 
-/*   SH_PTC_0_PS                                                        */
+/*   SH1_PTC_0_PS                                                       */
 /*   Description:  Page Size                                            */
-#define SH_PTC_0_PS_SHFT                         2
-#define SH_PTC_0_PS_MASK                         0x00000000000000fc
+#define SH1_PTC_0_PS_SHFT                         2
 
-/*   SH_PTC_0_RID                                                       */
+/*   SH1_PTC_0_RID                                                      */
 /*   Description:  Region ID                                            */
-#define SH_PTC_0_RID_SHFT                        8
-#define SH_PTC_0_RID_MASK                        0x00000000ffffff00
+#define SH1_PTC_0_RID_SHFT                        8
 
-/*   SH_PTC_0_START                                                     */
+/*   SH1_PTC_0_START                                                    */
 /*   Description:  Start                                                */
-#define SH_PTC_0_START_SHFT                      63
-#define SH_PTC_0_START_MASK                      0x8000000000000000
+#define SH1_PTC_0_START_SHFT                      63
 
 /* ==================================================================== */
-/*                         Register "SH_PTC_1"                          */
+/*                         Register "SH1_PTC_1"                         */
 /*       Puge Translation Cache Message Configuration Information       */
 /* ==================================================================== */
-#define SH_PTC_1                                 0x00000001101a0080UL
-#define SH_PTC_1_MASK                            0x9ffffffffffff000
-#define SH_PTC_1_INIT                            0x0000000000000000
-
-/*   SH_PTC_1_VPN                                                       */
-/*   Description:  Virtual page number                                  */
-#define SH_PTC_1_VPN_SHFT                        12
-#define SH_PTC_1_VPN_MASK                        0x1ffffffffffff000
+#define SH1_PTC_1                                 0x00000001101a0080
 
-/*   SH_PTC_1_START                                                     */
+/*   SH1_PTC_1_START                                                    */
 /*   Description:  PTC_1 Start                                          */
-#define SH_PTC_1_START_SHFT                      63
-#define SH_PTC_1_START_MASK                      0x8000000000000000
+#define SH1_PTC_1_START_SHFT                      63
+
+
+/* ==================================================================== */
+/*                         Register "SH2_PTC"                           */
+/*       Puge Translation Cache Message Configuration Information       */
+/* ==================================================================== */
+#define SH2_PTC                                   0x0000000170000000
+
+/*   SH2_PTC_A                                                          */
+/*   Description:  Type                                                 */
+#define SH2_PTC_A_SHFT                            0
+
+/*   SH2_PTC_PS                                                         */
+/*   Description:  Page Size                                            */
+#define SH2_PTC_PS_SHFT                           2
+
+/*   SH2_PTC_RID                                                      */
+/*   Description:  Region ID                                            */
+#define SH2_PTC_RID_SHFT                          4
+
+/*   SH2_PTC_START                                                      */
+/*   Description:  Start                                                */
+#define SH2_PTC_START_SHFT                        63
 
-/*
- * Register definitions
- */
+/*   SH2_PTC_ADDR_RID                                                   */
+/*   Description:  Region ID                                            */
+#define SH2_PTC_ADDR_SHFT                         4
+#define SH2_PTC_ADDR_MASK                         0x1ffffffffffff000
 
 /* ==================================================================== */
 /*                    Register "SH_RTC1_INT_CONFIG"                     */
 /*                SHub RTC 1 Interrupt Config Registers                 */
 /* ==================================================================== */
 
-#define SH_RTC1_INT_CONFIG                       0x0000000110001480
+#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
 
@@ -239,7 +242,8 @@
 /*                SHub RTC 1 Interrupt Enable Registers                 */
 /* ==================================================================== */
 
-#define SH_RTC1_INT_ENABLE                       0x0000000110001500
+#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
 
@@ -253,7 +257,8 @@
 /*                SHub RTC 2 Interrupt Config Registers                 */
 /* ==================================================================== */
 
-#define SH_RTC2_INT_CONFIG                       0x0000000110001580
+#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
 
@@ -287,7 +292,8 @@
 /*                SHub RTC 2 Interrupt Enable Registers                 */
 /* ==================================================================== */
 
-#define SH_RTC2_INT_ENABLE                       0x0000000110001600
+#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
 
@@ -301,7 +307,8 @@
 /*                SHub RTC 3 Interrupt Config Registers                 */
 /* ==================================================================== */
 
-#define SH_RTC3_INT_CONFIG                       0x0000000110001680
+#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
 
@@ -335,7 +342,8 @@
 /*                SHub RTC 3 Interrupt Enable Registers                 */
 /* ==================================================================== */
 
-#define SH_RTC3_INT_ENABLE                       0x0000000110001700
+#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
 
@@ -364,7 +372,8 @@
 /*                  RTC Compare Value for Processor B                   */
 /* ==================================================================== */
 
-#define SH_INT_CMPB                              0x00000001101b0080
+#define SH1_INT_CMPB                             0x00000001101b0080
+#define SH2_INT_CMPB                             0x00000000101b0080
 #define SH_INT_CMPB_MASK                         0x007fffffffffffff
 #define SH_INT_CMPB_INIT                         0x0000000000000000
 
@@ -378,7 +387,8 @@
 /*                  RTC Compare Value for Processor C                   */
 /* ==================================================================== */
 
-#define SH_INT_CMPC                              0x00000001101b0100
+#define SH1_INT_CMPC                             0x00000001101b0100
+#define SH2_INT_CMPC                             0x00000000101b0100
 #define SH_INT_CMPC_MASK                         0x007fffffffffffff
 #define SH_INT_CMPC_INIT                         0x0000000000000000
 
@@ -392,7 +402,8 @@
 /*                  RTC Compare Value for Processor D                   */
 /* ==================================================================== */
 
-#define SH_INT_CMPD                              0x00000001101b0180
+#define SH1_INT_CMPD                             0x00000001101b0180
+#define SH2_INT_CMPD                             0x00000000101b0180
 #define SH_INT_CMPD_MASK                         0x007fffffffffffff
 #define SH_INT_CMPD_INIT                         0x0000000000000000
 
@@ -400,5 +411,31 @@
 /*   Description:  Real Time Clock Compare                              */
 #define SH_INT_CMPD_REAL_TIME_CMPD_SHFT          0
 #define SH_INT_CMPD_REAL_TIME_CMPD_MASK          0x007fffffffffffff
+
+
+/* ==================================================================== */
+/* Some MMRs are functionally identical (or close enough) on both SHUB1 */
+/* and SHUB2 that it makes sense to define a geberic name for the MMR.  */
+/* It is acceptible to use (for example) SH_IPI_INT to reference the    */
+/* the IPI MMR. The value of SH_IPI_INT is determined at runtime based  */
+/* on the type of the SHUB. Do not use these #defines in performance    */
+/* critical code  or loops - there is a small performance penalty.      */
+/* ==================================================================== */
+#define shubmmr(a,b) 		(is_shub2() ? a##2_##b : a##1_##b)
+
+#define SH_REAL_JUNK_BUS_LED0	shubmmr(SH, REAL_JUNK_BUS_LED0)
+#define SH_IPI_INT		shubmmr(SH, IPI_INT)
+#define SH_EVENT_OCCURRED	shubmmr(SH, EVENT_OCCURRED)
+#define SH_EVENT_OCCURRED_ALIAS	shubmmr(SH, EVENT_OCCURRED_ALIAS)
+#define SH_RTC			shubmmr(SH, RTC)
+#define SH_RTC1_INT_CONFIG	shubmmr(SH, RTC1_INT_CONFIG)
+#define SH_RTC1_INT_ENABLE	shubmmr(SH, RTC1_INT_ENABLE)
+#define SH_RTC2_INT_CONFIG	shubmmr(SH, RTC2_INT_CONFIG)
+#define SH_RTC2_INT_ENABLE	shubmmr(SH, RTC2_INT_ENABLE)
+#define SH_RTC3_INT_CONFIG	shubmmr(SH, RTC3_INT_CONFIG)
+#define SH_RTC3_INT_ENABLE	shubmmr(SH, RTC3_INT_ENABLE)
+#define SH_INT_CMPB		shubmmr(SH, INT_CMPB)
+#define SH_INT_CMPC		shubmmr(SH, INT_CMPC)
+#define SH_INT_CMPD		shubmmr(SH, INT_CMPD)
 
 #endif /* _ASM_IA64_SN_SHUB_MMR_H */
diff -Nru a/include/asm-ia64/sn/shubio.h b/include/asm-ia64/sn/shubio.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-ia64/sn/shubio.h	2005-03-01 23:38:53 -08:00
@@ -0,0 +1,3476 @@
+/*
+ * This file 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_SHUBIO_H
+#define _ASM_IA64_SN_SHUBIO_H
+
+#define HUB_WIDGET_ID_MAX 0xf
+#define IIO_NUM_ITTES   7
+#define HUB_NUM_BIG_WINDOW      (IIO_NUM_ITTES - 1)
+
+#define    IIO_WID                   0x00400000    /* Crosstalk Widget Identification */
+                                                   /* This register is also accessible from
+                                                    * Crosstalk at address 0x0.  */
+#define    IIO_WSTAT                 0x00400008    /* Crosstalk Widget Status */
+#define    IIO_WCR                   0x00400020    /* Crosstalk Widget Control Register */
+#define    IIO_ILAPR                 0x00400100    /* IO Local Access Protection Register */
+#define    IIO_ILAPO                 0x00400108    /* IO Local Access Protection Override */
+#define    IIO_IOWA                  0x00400110    /* IO Outbound Widget Access */
+#define    IIO_IIWA                  0x00400118    /* IO Inbound Widget Access */
+#define    IIO_IIDEM                 0x00400120    /* IO Inbound Device Error Mask */
+#define    IIO_ILCSR                 0x00400128    /* IO LLP Control and Status Register */
+#define    IIO_ILLR                  0x00400130    /* IO LLP Log Register    */
+#define    IIO_IIDSR                 0x00400138    /* IO Interrupt Destination */
+
+#define    IIO_IGFX0                 0x00400140    /* IO Graphics Node-Widget Map 0 */
+#define    IIO_IGFX1                 0x00400148    /* IO Graphics Node-Widget Map 1 */
+
+#define    IIO_ISCR0                 0x00400150    /* IO Scratch Register 0 */
+#define    IIO_ISCR1                 0x00400158    /* IO Scratch Register 1 */
+
+#define    IIO_ITTE1                 0x00400160    /* IO Translation Table Entry 1 */
+#define    IIO_ITTE2                 0x00400168    /* IO Translation Table Entry 2 */
+#define    IIO_ITTE3                 0x00400170    /* IO Translation Table Entry 3 */
+#define    IIO_ITTE4                 0x00400178    /* IO Translation Table Entry 4 */
+#define    IIO_ITTE5                 0x00400180    /* IO Translation Table Entry 5 */
+#define    IIO_ITTE6                 0x00400188    /* IO Translation Table Entry 6 */
+#define    IIO_ITTE7                 0x00400190    /* IO Translation Table Entry 7 */
+
+#define    IIO_IPRB0                 0x00400198    /* IO PRB Entry 0         */
+#define    IIO_IPRB8                 0x004001A0    /* IO PRB Entry 8         */
+#define    IIO_IPRB9                 0x004001A8    /* IO PRB Entry 9         */
+#define    IIO_IPRBA                 0x004001B0    /* IO PRB Entry A         */
+#define    IIO_IPRBB                 0x004001B8    /* IO PRB Entry B         */
+#define    IIO_IPRBC                 0x004001C0    /* IO PRB Entry C         */
+#define    IIO_IPRBD                 0x004001C8    /* IO PRB Entry D         */
+#define    IIO_IPRBE                 0x004001D0    /* IO PRB Entry E         */
+#define    IIO_IPRBF                 0x004001D8    /* IO PRB Entry F         */
+
+#define    IIO_IXCC                  0x004001E0    /* IO Crosstalk Credit Count Timeout */
+#define    IIO_IMEM                  0x004001E8    /* IO Miscellaneous Error Mask */
+#define    IIO_IXTT                  0x004001F0    /* IO Crosstalk Timeout Threshold */
+#define    IIO_IECLR                 0x004001F8    /* IO Error Clear Register */
+#define    IIO_IBCR                  0x00400200    /* IO BTE Control Register */
+
+#define    IIO_IXSM                  0x00400208    /* IO Crosstalk Spurious Message */
+#define    IIO_IXSS                  0x00400210    /* IO Crosstalk Spurious Sideband */
+
+#define    IIO_ILCT                  0x00400218    /* IO LLP Channel Test    */
+
+#define    IIO_IIEPH1                0x00400220    /* IO Incoming Error Packet Header, Part 1 */
+#define    IIO_IIEPH2                0x00400228    /* IO Incoming Error Packet Header, Part 2 */
+
+
+#define    IIO_ISLAPR                0x00400230    /* IO SXB Local Access Protection Regster */
+#define    IIO_ISLAPO                0x00400238    /* IO SXB Local Access Protection Override */
+
+#define    IIO_IWI                   0x00400240    /* IO Wrapper Interrupt Register */
+#define    IIO_IWEL                  0x00400248    /* IO Wrapper Error Log Register */
+#define    IIO_IWC                   0x00400250    /* IO Wrapper Control Register */
+#define    IIO_IWS                   0x00400258    /* IO Wrapper Status Register */
+#define    IIO_IWEIM                 0x00400260    /* IO Wrapper Error Interrupt Masking Register */
+
+#define    IIO_IPCA                  0x00400300    /* IO PRB Counter Adjust */
+
+#define    IIO_IPRTE0_A              0x00400308    /* IO PIO Read Address Table Entry 0, Part A */
+#define    IIO_IPRTE1_A              0x00400310    /* IO PIO Read Address Table Entry 1, Part A */
+#define    IIO_IPRTE2_A              0x00400318    /* IO PIO Read Address Table Entry 2, Part A */
+#define    IIO_IPRTE3_A               0x00400320    /* IO PIO Read Address Table Entry 3, Part A */
+#define    IIO_IPRTE4_A               0x00400328    /* IO PIO Read Address Table Entry 4, Part A */
+#define    IIO_IPRTE5_A               0x00400330    /* IO PIO Read Address Table Entry 5, Part A */
+#define    IIO_IPRTE6_A               0x00400338    /* IO PIO Read Address Table Entry 6, Part A */
+#define    IIO_IPRTE7_A               0x00400340    /* IO PIO Read Address Table Entry 7, Part A */
+
+#define    IIO_IPRTE0_B              0x00400348    /* IO PIO Read Address Table Entry 0, Part B */
+#define    IIO_IPRTE1_B              0x00400350    /* IO PIO Read Address Table Entry 1, Part B */
+#define    IIO_IPRTE2_B              0x00400358    /* IO PIO Read Address Table Entry 2, Part B */
+#define    IIO_IPRTE3_B               0x00400360    /* IO PIO Read Address Table Entry 3, Part B */
+#define    IIO_IPRTE4_B               0x00400368    /* IO PIO Read Address Table Entry 4, Part B */
+#define    IIO_IPRTE5_B               0x00400370    /* IO PIO Read Address Table Entry 5, Part B */
+#define    IIO_IPRTE6_B               0x00400378    /* IO PIO Read Address Table Entry 6, Part B */
+#define    IIO_IPRTE7_B               0x00400380    /* IO PIO Read Address Table Entry 7, Part B */
+
+#define    IIO_IPDR                  0x00400388    /* IO PIO Deallocation Register */
+#define    IIO_ICDR                  0x00400390    /* IO CRB Entry Deallocation Register */
+#define    IIO_IFDR                  0x00400398    /* IO IOQ FIFO Depth Register */
+#define    IIO_IIAP                  0x004003A0    /* IO IIQ Arbitration Parameters */
+#define    IIO_ICMR                  0x004003A8    /* IO CRB Management Register */
+#define    IIO_ICCR                  0x004003B0    /* IO CRB Control Register */
+#define    IIO_ICTO                  0x004003B8    /* IO CRB Timeout         */
+#define    IIO_ICTP                  0x004003C0    /* IO CRB Timeout Prescalar */
+
+#define    IIO_ICRB0_A               0x00400400    /* IO CRB Entry 0_A       */
+#define    IIO_ICRB0_B               0x00400408    /* IO CRB Entry 0_B       */
+#define    IIO_ICRB0_C               0x00400410    /* IO CRB Entry 0_C       */
+#define    IIO_ICRB0_D               0x00400418    /* IO CRB Entry 0_D       */
+#define    IIO_ICRB0_E               0x00400420    /* IO CRB Entry 0_E       */
+
+#define    IIO_ICRB1_A               0x00400430    /* IO CRB Entry 1_A       */
+#define    IIO_ICRB1_B               0x00400438    /* IO CRB Entry 1_B       */
+#define    IIO_ICRB1_C               0x00400440    /* IO CRB Entry 1_C       */
+#define    IIO_ICRB1_D               0x00400448    /* IO CRB Entry 1_D       */
+#define    IIO_ICRB1_E               0x00400450    /* IO CRB Entry 1_E       */
+
+#define    IIO_ICRB2_A               0x00400460    /* IO CRB Entry 2_A       */
+#define    IIO_ICRB2_B               0x00400468    /* IO CRB Entry 2_B       */
+#define    IIO_ICRB2_C               0x00400470    /* IO CRB Entry 2_C       */
+#define    IIO_ICRB2_D               0x00400478    /* IO CRB Entry 2_D       */
+#define    IIO_ICRB2_E               0x00400480    /* IO CRB Entry 2_E       */
+
+#define    IIO_ICRB3_A               0x00400490    /* IO CRB Entry 3_A       */
+#define    IIO_ICRB3_B               0x00400498    /* IO CRB Entry 3_B       */
+#define    IIO_ICRB3_C               0x004004a0    /* IO CRB Entry 3_C       */
+#define    IIO_ICRB3_D               0x004004a8    /* IO CRB Entry 3_D       */
+#define    IIO_ICRB3_E               0x004004b0    /* IO CRB Entry 3_E       */
+
+#define    IIO_ICRB4_A               0x004004c0    /* IO CRB Entry 4_A       */
+#define    IIO_ICRB4_B               0x004004c8    /* IO CRB Entry 4_B       */
+#define    IIO_ICRB4_C               0x004004d0    /* IO CRB Entry 4_C       */
+#define    IIO_ICRB4_D               0x004004d8    /* IO CRB Entry 4_D       */
+#define    IIO_ICRB4_E               0x004004e0    /* IO CRB Entry 4_E       */
+
+#define    IIO_ICRB5_A               0x004004f0    /* IO CRB Entry 5_A       */
+#define    IIO_ICRB5_B               0x004004f8    /* IO CRB Entry 5_B       */
+#define    IIO_ICRB5_C               0x00400500    /* IO CRB Entry 5_C       */
+#define    IIO_ICRB5_D               0x00400508    /* IO CRB Entry 5_D       */
+#define    IIO_ICRB5_E               0x00400510    /* IO CRB Entry 5_E       */
+
+#define    IIO_ICRB6_A               0x00400520    /* IO CRB Entry 6_A       */
+#define    IIO_ICRB6_B               0x00400528    /* IO CRB Entry 6_B       */
+#define    IIO_ICRB6_C               0x00400530    /* IO CRB Entry 6_C       */
+#define    IIO_ICRB6_D               0x00400538    /* IO CRB Entry 6_D       */
+#define    IIO_ICRB6_E               0x00400540    /* IO CRB Entry 6_E       */
+
+#define    IIO_ICRB7_A               0x00400550    /* IO CRB Entry 7_A       */
+#define    IIO_ICRB7_B               0x00400558    /* IO CRB Entry 7_B       */
+#define    IIO_ICRB7_C               0x00400560    /* IO CRB Entry 7_C       */
+#define    IIO_ICRB7_D               0x00400568    /* IO CRB Entry 7_D       */
+#define    IIO_ICRB7_E               0x00400570    /* IO CRB Entry 7_E       */
+
+#define    IIO_ICRB8_A               0x00400580    /* IO CRB Entry 8_A       */
+#define    IIO_ICRB8_B               0x00400588    /* IO CRB Entry 8_B       */
+#define    IIO_ICRB8_C               0x00400590    /* IO CRB Entry 8_C       */
+#define    IIO_ICRB8_D               0x00400598    /* IO CRB Entry 8_D       */
+#define    IIO_ICRB8_E               0x004005a0    /* IO CRB Entry 8_E       */
+
+#define    IIO_ICRB9_A               0x004005b0    /* IO CRB Entry 9_A       */
+#define    IIO_ICRB9_B               0x004005b8    /* IO CRB Entry 9_B       */
+#define    IIO_ICRB9_C               0x004005c0    /* IO CRB Entry 9_C       */
+#define    IIO_ICRB9_D               0x004005c8    /* IO CRB Entry 9_D       */
+#define    IIO_ICRB9_E               0x004005d0    /* IO CRB Entry 9_E       */
+
+#define    IIO_ICRBA_A               0x004005e0    /* IO CRB Entry A_A       */
+#define    IIO_ICRBA_B               0x004005e8    /* IO CRB Entry A_B       */
+#define    IIO_ICRBA_C               0x004005f0    /* IO CRB Entry A_C       */
+#define    IIO_ICRBA_D               0x004005f8    /* IO CRB Entry A_D       */
+#define    IIO_ICRBA_E               0x00400600    /* IO CRB Entry A_E       */
+
+#define    IIO_ICRBB_A               0x00400610    /* IO CRB Entry B_A       */
+#define    IIO_ICRBB_B               0x00400618    /* IO CRB Entry B_B       */
+#define    IIO_ICRBB_C               0x00400620    /* IO CRB Entry B_C       */
+#define    IIO_ICRBB_D               0x00400628    /* IO CRB Entry B_D       */
+#define    IIO_ICRBB_E               0x00400630    /* IO CRB Entry B_E       */
+
+#define    IIO_ICRBC_A               0x00400640    /* IO CRB Entry C_A       */
+#define    IIO_ICRBC_B               0x00400648    /* IO CRB Entry C_B       */
+#define    IIO_ICRBC_C               0x00400650    /* IO CRB Entry C_C       */
+#define    IIO_ICRBC_D               0x00400658    /* IO CRB Entry C_D       */
+#define    IIO_ICRBC_E               0x00400660    /* IO CRB Entry C_E       */
+
+#define    IIO_ICRBD_A               0x00400670    /* IO CRB Entry D_A       */
+#define    IIO_ICRBD_B               0x00400678    /* IO CRB Entry D_B       */
+#define    IIO_ICRBD_C               0x00400680    /* IO CRB Entry D_C       */
+#define    IIO_ICRBD_D               0x00400688    /* IO CRB Entry D_D       */
+#define    IIO_ICRBD_E               0x00400690    /* IO CRB Entry D_E       */
+
+#define    IIO_ICRBE_A               0x004006a0    /* IO CRB Entry E_A       */
+#define    IIO_ICRBE_B               0x004006a8    /* IO CRB Entry E_B       */
+#define    IIO_ICRBE_C               0x004006b0    /* IO CRB Entry E_C       */
+#define    IIO_ICRBE_D               0x004006b8    /* IO CRB Entry E_D       */
+#define    IIO_ICRBE_E               0x004006c0    /* IO CRB Entry E_E       */
+
+#define    IIO_ICSML                 0x00400700    /* IO CRB Spurious Message Low */
+#define    IIO_ICSMM                 0x00400708    /* IO CRB Spurious Message Middle */
+#define    IIO_ICSMH                 0x00400710    /* IO CRB Spurious Message High */
+
+#define    IIO_IDBSS                 0x00400718    /* IO Debug Submenu Select */
+
+#define    IIO_IBLS0                 0x00410000    /* IO BTE Length Status 0 */
+#define    IIO_IBSA0                 0x00410008    /* IO BTE Source Address 0 */
+#define    IIO_IBDA0                 0x00410010    /* IO BTE Destination Address 0 */
+#define    IIO_IBCT0                 0x00410018    /* IO BTE Control Terminate 0 */
+#define    IIO_IBNA0                 0x00410020    /* IO BTE Notification Address 0 */
+#define    IIO_IBIA0                 0x00410028    /* IO BTE Interrupt Address 0 */
+#define    IIO_IBLS1                 0x00420000    /* IO BTE Length Status 1 */
+#define    IIO_IBSA1                 0x00420008    /* IO BTE Source Address 1 */
+#define    IIO_IBDA1                 0x00420010    /* IO BTE Destination Address 1 */
+#define    IIO_IBCT1                 0x00420018    /* IO BTE Control Terminate 1 */
+#define    IIO_IBNA1                 0x00420020    /* IO BTE Notification Address 1 */
+#define    IIO_IBIA1                 0x00420028    /* IO BTE Interrupt Address 1 */
+
+#define    IIO_IPCR                  0x00430000    /* IO Performance Control */
+#define    IIO_IPPR                  0x00430008    /* IO Performance Profiling */
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  This register echoes some information from the         *
+ * LB_REV_ID register. It is available through Crosstalk as described   *
+ * above. The REV_NUM and MFG_NUM fields receive their values from      *
+ * the REVISION and MANUFACTURER fields in the LB_REV_ID register.      *
+ * The PART_NUM field's value is the Crosstalk device ID number that    *
+ * Steve Miller assigned to the SHub chip.                              *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_wid_u {
+	uint64_t	ii_wid_regval;
+	struct	{
+		uint64_t	w_rsvd_1		  :	 1;
+		uint64_t	w_mfg_num		  :	11;
+		uint64_t	w_part_num		  :	16;
+		uint64_t	w_rev_num		  :	 4;
+		uint64_t	w_rsvd			  :	32;
+	} ii_wid_fld_s;
+} ii_wid_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  The fields in this register are set upon detection of an error      *
+ * and cleared by various mechanisms, as explained in the               *
+ * description.                                                         *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_wstat_u {
+	uint64_t	ii_wstat_regval;
+	struct	{
+		uint64_t	w_pending		  :	 4;
+		uint64_t	w_xt_crd_to		  :	 1;
+		uint64_t	w_xt_tail_to		  :	 1;
+		uint64_t	w_rsvd_3		  :	 3;
+		uint64_t       w_tx_mx_rty               :      1;
+		uint64_t	w_rsvd_2		  :	 6;
+		uint64_t	w_llp_tx_cnt		  :	 8;
+		uint64_t	w_rsvd_1		  :	 8;
+		uint64_t	w_crazy			  :	 1;
+		uint64_t	w_rsvd			  :	31;
+	} ii_wstat_fld_s;
+} ii_wstat_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  This is a read-write enabled register. It controls     *
+ * various aspects of the Crosstalk flow control.                       *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_wcr_u {
+	uint64_t	ii_wcr_regval;
+	struct	{
+		uint64_t	w_wid			  :	 4;
+		uint64_t	w_tag			  :	 1;
+		uint64_t	w_rsvd_1		  :	 8;
+		uint64_t	w_dst_crd		  :	 3;
+		uint64_t	w_f_bad_pkt		  :	 1;
+		uint64_t	w_dir_con		  :	 1;
+		uint64_t	w_e_thresh		  :	 5;
+		uint64_t	w_rsvd			  :	41;
+	} ii_wcr_fld_s;
+} ii_wcr_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  This register's value is a bit vector that guards      *
+ * access to local registers within the II as well as to external       *
+ * Crosstalk widgets. Each bit in the register corresponds to a         *
+ * particular region in the system; a region consists of one, two or    *
+ * four nodes (depending on the value of the REGION_SIZE field in the   *
+ * LB_REV_ID register, which is documented in Section 8.3.1.1). The     *
+ * protection provided by this register applies to PIO read             *
+ * operations as well as PIO write operations. The II will perform a    *
+ * PIO read or write request only if the bit for the requestor's        *
+ * region is set; otherwise, the II will not perform the requested      *
+ * operation and will return an error response. When a PIO read or      *
+ * write request targets an external Crosstalk widget, then not only    *
+ * must the bit for the requestor's region be set in the ILAPR, but     *
+ * also the target widget's bit in the IOWA register must be set in     *
+ * order for the II to perform the requested operation; otherwise,      *
+ * the II will return an error response. Hence, the protection          *
+ * provided by the IOWA register supplements the protection provided    *
+ * by the ILAPR for requests that target external Crosstalk widgets.    *
+ * This register itself can be accessed only by the nodes whose         *
+ * region ID bits are enabled in this same register. It can also be     *
+ * accessed through the IAlias space by the local processors.           *
+ * The reset value of this register allows access by all nodes.         *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_ilapr_u {
+	uint64_t	ii_ilapr_regval;
+	struct  {
+		uint64_t	i_region                  :	64;
+	} ii_ilapr_fld_s;
+} ii_ilapr_u_t;
+
+
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  A write to this register of the 64-bit value           *
+ * "SGIrules" in ASCII, will cause the bit in the ILAPR register        *
+ * corresponding to the region of the requestor to be set (allow        *
+ * access). A write of any other value will be ignored. Access          *
+ * protection for this register is "SGIrules".                          *
+ * This register can also be accessed through the IAlias space.         *
+ * However, this access will not change the access permissions in the   *
+ * ILAPR.                                                               *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_ilapo_u {
+	uint64_t	ii_ilapo_regval;
+	struct	{
+		uint64_t	i_io_ovrride            :	64;
+	} ii_ilapo_fld_s;
+} ii_ilapo_u_t;
+
+
+
+/************************************************************************
+ *                                                                      *
+ *  This register qualifies all the PIO and Graphics writes launched    *
+ * from the SHUB towards a widget.                                      *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iowa_u {
+	uint64_t	ii_iowa_regval;
+	struct	{
+		uint64_t	i_w0_oac		  :	 1;
+		uint64_t	i_rsvd_1		  :	 7;
+                uint64_t       i_wx_oac                  :      8;
+		uint64_t	i_rsvd			  :	48;
+	} ii_iowa_fld_s;
+} ii_iowa_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  This register qualifies all the requests launched      *
+ * from a widget towards the Shub. This register is intended to be      *
+ * used by software in case of misbehaving widgets.                     *
+ *                                                                      *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iiwa_u {
+	uint64_t	ii_iiwa_regval;
+	struct  {
+		uint64_t	i_w0_iac                  :	 1;
+		uint64_t	i_rsvd_1		  :	 7;
+		uint64_t	i_wx_iac		  :	 8;
+		uint64_t	i_rsvd			  :	48;
+	} ii_iiwa_fld_s;
+} ii_iiwa_u_t;
+
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  This register qualifies all the operations launched    *
+ * from a widget towards the SHub. It allows individual access          *
+ * control for up to 8 devices per widget. A device refers to           *
+ * individual DMA master hosted by a widget.                            *
+ * The bits in each field of this register are cleared by the Shub      *
+ * upon detection of an error which requires the device to be           *
+ * disabled. These fields assume that 0=TNUM=7 (i.e., Bridge-centric    *
+ * Crosstalk). Whether or not a device has access rights to this        *
+ * Shub is determined by an AND of the device enable bit in the         *
+ * appropriate field of this register and the corresponding bit in      *
+ * the Wx_IAC field (for the widget which this device belongs to).      *
+ * The bits in this field are set by writing a 1 to them. Incoming      *
+ * replies from Crosstalk are not subject to this access control        *
+ * mechanism.                                                           *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iidem_u {
+	uint64_t	ii_iidem_regval;
+	struct	{
+		uint64_t	i_w8_dxs		  :	 8;
+		uint64_t	i_w9_dxs		  :	 8;
+		uint64_t	i_wa_dxs		  :	 8;
+		uint64_t	i_wb_dxs		  :	 8;
+		uint64_t	i_wc_dxs		  :	 8;
+		uint64_t	i_wd_dxs		  :	 8;
+		uint64_t	i_we_dxs		  :	 8;
+		uint64_t	i_wf_dxs		  :	 8;
+	} ii_iidem_fld_s;
+} ii_iidem_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  This register contains the various programmable fields necessary    *
+ * for controlling and observing the LLP signals.                       *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_ilcsr_u {
+	uint64_t	ii_ilcsr_regval;
+	struct  {
+		uint64_t	i_nullto                  :	 6;
+		uint64_t	i_rsvd_4		  :	 2;
+		uint64_t	i_wrmrst		  :	 1;
+		uint64_t	i_rsvd_3		  :	 1;
+		uint64_t	i_llp_en		  :	 1;
+		uint64_t	i_bm8			  :	 1;
+		uint64_t	i_llp_stat		  :	 2;
+		uint64_t	i_remote_power		  :	 1;
+		uint64_t	i_rsvd_2		  :	 1;
+		uint64_t	i_maxrtry		  :	10;
+		uint64_t	i_d_avail_sel		  :	 2;
+		uint64_t	i_rsvd_1		  :	 4;
+		uint64_t	i_maxbrst		  :	10;
+                uint64_t       i_rsvd                    :     22;
+
+	} ii_ilcsr_fld_s;
+} ii_ilcsr_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  This is simply a status registers that monitors the LLP error       *
+ * rate.                                                                *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_illr_u {
+	uint64_t	ii_illr_regval;
+	struct	{
+		uint64_t	i_sn_cnt		  :	16;
+		uint64_t	i_cb_cnt		  :	16;
+		uint64_t	i_rsvd			  :	32;
+	} ii_illr_fld_s;
+} ii_illr_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  All II-detected non-BTE error interrupts are           *
+ * specified via this register.                                         *
+ * NOTE: The PI interrupt register address is hardcoded in the II. If   *
+ * PI_ID==0, then the II sends an interrupt request (Duplonet PWRI      *
+ * packet) to address offset 0x0180_0090 within the local register      *
+ * address space of PI0 on the node specified by the NODE field. If     *
+ * PI_ID==1, then the II sends the interrupt request to address         *
+ * offset 0x01A0_0090 within the local register address space of PI1    *
+ * on the node specified by the NODE field.                             *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iidsr_u {
+	uint64_t	ii_iidsr_regval;
+	struct  {
+		uint64_t	i_level                   :	 8;
+		uint64_t	i_pi_id			  :	 1;
+		uint64_t	i_node			  :	11;
+		uint64_t       i_rsvd_3                  :      4;
+		uint64_t	i_enable		  :	 1;
+		uint64_t	i_rsvd_2		  :	 3;
+		uint64_t	i_int_sent		  :	 2;
+		uint64_t       i_rsvd_1                  :      2;
+		uint64_t	i_pi0_forward_int	  :	 1;
+		uint64_t	i_pi1_forward_int	  :	 1;
+		uint64_t	i_rsvd			  :	30;
+	} ii_iidsr_fld_s;
+} ii_iidsr_u_t;
+
+
+
+/************************************************************************
+ *                                                                      *
+ *  There are two instances of this register. This register is used     *
+ * for matching up the incoming responses from the graphics widget to   *
+ * the processor that initiated the graphics operation. The             *
+ * write-responses are converted to graphics credits and returned to    *
+ * the processor so that the processor interface can manage the flow    *
+ * control.                                                             *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_igfx0_u {
+	uint64_t	ii_igfx0_regval;
+	struct	{
+		uint64_t	i_w_num			  :	 4;
+		uint64_t       i_pi_id                   :      1;
+		uint64_t	i_n_num			  :	12;
+		uint64_t       i_p_num                   :      1;
+		uint64_t       i_rsvd                    :     46;
+	} ii_igfx0_fld_s;
+} ii_igfx0_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  There are two instances of this register. This register is used     *
+ * for matching up the incoming responses from the graphics widget to   *
+ * the processor that initiated the graphics operation. The             *
+ * write-responses are converted to graphics credits and returned to    *
+ * the processor so that the processor interface can manage the flow    *
+ * control.                                                             *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_igfx1_u {
+	uint64_t	ii_igfx1_regval;
+	struct  {
+		uint64_t	i_w_num			  :	 4;
+		uint64_t       i_pi_id                   :      1;
+		uint64_t	i_n_num			  :	12;
+		uint64_t       i_p_num                   :      1;
+		uint64_t       i_rsvd                    :     46;
+	} ii_igfx1_fld_s;
+} ii_igfx1_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  There are two instances of this registers. These registers are      *
+ * used as scratch registers for software use.                          *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iscr0_u {
+	uint64_t	ii_iscr0_regval;
+	struct  {
+		uint64_t	i_scratch                 :	64;
+	} ii_iscr0_fld_s;
+} ii_iscr0_u_t;
+
+
+
+/************************************************************************
+ *                                                                      *
+ *  There are two instances of this registers. These registers are      *
+ * used as scratch registers for software use.                          *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iscr1_u {
+	uint64_t	ii_iscr1_regval;
+	struct  {
+		uint64_t	i_scratch                 :	64;
+	} ii_iscr1_fld_s;
+} ii_iscr1_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  There are seven instances of translation table entry   *
+ * registers. Each register maps a Shub Big Window to a 48-bit          *
+ * address on Crosstalk.                                                *
+ * For M-mode (128 nodes, 8 GBytes/node), SysAD[31:29] (Big Window      *
+ * number) are used to select one of these 7 registers. The Widget      *
+ * number field is then derived from the W_NUM field for synthesizing   *
+ * a Crosstalk packet. The 5 bits of OFFSET are concatenated with       *
+ * SysAD[28:0] to form Crosstalk[33:0]. The upper Crosstalk[47:34]      *
+ * are padded with zeros. Although the maximum Crosstalk space          *
+ * addressable by the SHub is thus the lower 16 GBytes per widget       * 
+ * (M-mode), however only <SUP >7</SUP>/<SUB >32nds</SUB> of this       *
+ * space can be accessed.                                               *
+ * For the N-mode (256 nodes, 4 GBytes/node), SysAD[30:28] (Big         *
+ * Window number) are used to select one of these 7 registers. The      *
+ * Widget number field is then derived from the W_NUM field for         *
+ * synthesizing a Crosstalk packet. The 5 bits of OFFSET are            *
+ * concatenated with SysAD[27:0] to form Crosstalk[33:0]. The IOSP      *
+ * field is used as Crosstalk[47], and remainder of the Crosstalk       *
+ * address bits (Crosstalk[46:34]) are always zero. While the maximum   *
+ * Crosstalk space addressable by the Shub is thus the lower            *
+ * 8-GBytes per widget (N-mode), only <SUP >7</SUP>/<SUB >32nds</SUB>   *
+ * of this space can be accessed.                                       *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_itte1_u {
+	uint64_t	ii_itte1_regval;
+	struct  {
+		uint64_t	i_offset                  :	 5;
+		uint64_t	i_rsvd_1		  :	 3;
+		uint64_t	i_w_num			  :	 4;
+		uint64_t	i_iosp			  :	 1;
+		uint64_t	i_rsvd			  :	51;
+	} ii_itte1_fld_s;
+} ii_itte1_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  There are seven instances of translation table entry   *
+ * registers. Each register maps a Shub Big Window to a 48-bit          *
+ * address on Crosstalk.                                                *
+ * For M-mode (128 nodes, 8 GBytes/node), SysAD[31:29] (Big Window      *
+ * number) are used to select one of these 7 registers. The Widget      *
+ * number field is then derived from the W_NUM field for synthesizing   *
+ * a Crosstalk packet. The 5 bits of OFFSET are concatenated with       *
+ * SysAD[28:0] to form Crosstalk[33:0]. The upper Crosstalk[47:34]      *
+ * are padded with zeros. Although the maximum Crosstalk space          *
+ * addressable by the Shub is thus the lower 16 GBytes per widget       *
+ * (M-mode), however only <SUP >7</SUP>/<SUB >32nds</SUB> of this       *
+ * space can be accessed.                                               *
+ * For the N-mode (256 nodes, 4 GBytes/node), SysAD[30:28] (Big         *
+ * Window number) are used to select one of these 7 registers. The      *
+ * Widget number field is then derived from the W_NUM field for         *
+ * synthesizing a Crosstalk packet. The 5 bits of OFFSET are            *
+ * concatenated with SysAD[27:0] to form Crosstalk[33:0]. The IOSP      *
+ * field is used as Crosstalk[47], and remainder of the Crosstalk       *
+ * address bits (Crosstalk[46:34]) are always zero. While the maximum   *
+ * Crosstalk space addressable by the Shub is thus the lower            *
+ * 8-GBytes per widget (N-mode), only <SUP >7</SUP>/<SUB >32nds</SUB>   *
+ * of this space can be accessed.                                       *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_itte2_u {
+	uint64_t	ii_itte2_regval;
+	struct	{
+		uint64_t	i_offset		  :	 5;
+		uint64_t	i_rsvd_1		  :	 3;
+		uint64_t	i_w_num			  :	 4;
+		uint64_t	i_iosp			  :	 1;
+		uint64_t       i_rsvd                    :     51;
+	} ii_itte2_fld_s;
+} ii_itte2_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  There are seven instances of translation table entry   *
+ * registers. Each register maps a Shub Big Window to a 48-bit          *
+ * address on Crosstalk.                                                *
+ * For M-mode (128 nodes, 8 GBytes/node), SysAD[31:29] (Big Window      *
+ * number) are used to select one of these 7 registers. The Widget      *
+ * number field is then derived from the W_NUM field for synthesizing   *
+ * a Crosstalk packet. The 5 bits of OFFSET are concatenated with       *
+ * SysAD[28:0] to form Crosstalk[33:0]. The upper Crosstalk[47:34]      *
+ * are padded with zeros. Although the maximum Crosstalk space          *
+ * addressable by the Shub is thus the lower 16 GBytes per widget       *
+ * (M-mode), however only <SUP >7</SUP>/<SUB >32nds</SUB> of this       *
+ * space can be accessed.                                               *
+ * For the N-mode (256 nodes, 4 GBytes/node), SysAD[30:28] (Big         *
+ * Window number) are used to select one of these 7 registers. The      *
+ * Widget number field is then derived from the W_NUM field for         *
+ * synthesizing a Crosstalk packet. The 5 bits of OFFSET are            *
+ * concatenated with SysAD[27:0] to form Crosstalk[33:0]. The IOSP      *
+ * field is used as Crosstalk[47], and remainder of the Crosstalk       *
+ * address bits (Crosstalk[46:34]) are always zero. While the maximum   *
+ * Crosstalk space addressable by the SHub is thus the lower            *
+ * 8-GBytes per widget (N-mode), only <SUP >7</SUP>/<SUB >32nds</SUB>   *
+ * of this space can be accessed.                                       *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_itte3_u {
+	uint64_t	ii_itte3_regval;
+	struct  {
+		uint64_t	i_offset                  :	 5;
+		uint64_t       i_rsvd_1                  :      3;
+		uint64_t       i_w_num                   :      4;
+		uint64_t       i_iosp                    :      1;
+		uint64_t       i_rsvd                    :     51;
+	} ii_itte3_fld_s;
+} ii_itte3_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  There are seven instances of translation table entry   *
+ * registers. Each register maps a SHub Big Window to a 48-bit          *
+ * address on Crosstalk.                                                *
+ * For M-mode (128 nodes, 8 GBytes/node), SysAD[31:29] (Big Window      *
+ * number) are used to select one of these 7 registers. The Widget      *
+ * number field is then derived from the W_NUM field for synthesizing   *
+ * a Crosstalk packet. The 5 bits of OFFSET are concatenated with       *
+ * SysAD[28:0] to form Crosstalk[33:0]. The upper Crosstalk[47:34]      *
+ * are padded with zeros. Although the maximum Crosstalk space          *
+ * addressable by the SHub is thus the lower 16 GBytes per widget       *
+ * (M-mode), however only <SUP >7</SUP>/<SUB >32nds</SUB> of this       *
+ * space can be accessed.                                               *
+ * For the N-mode (256 nodes, 4 GBytes/node), SysAD[30:28] (Big         *
+ * Window number) are used to select one of these 7 registers. The      *
+ * Widget number field is then derived from the W_NUM field for         *
+ * synthesizing a Crosstalk packet. The 5 bits of OFFSET are            *
+ * concatenated with SysAD[27:0] to form Crosstalk[33:0]. The IOSP      *
+ * field is used as Crosstalk[47], and remainder of the Crosstalk       *
+ * address bits (Crosstalk[46:34]) are always zero. While the maximum   *
+ * Crosstalk space addressable by the SHub is thus the lower            *
+ * 8-GBytes per widget (N-mode), only <SUP >7</SUP>/<SUB >32nds</SUB>   *
+ * of this space can be accessed.                                       *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_itte4_u {
+	uint64_t	ii_itte4_regval;
+	struct  {
+		uint64_t	i_offset                  :	 5;
+		uint64_t	i_rsvd_1		  :	 3;
+		uint64_t       i_w_num                   :      4;
+		uint64_t       i_iosp                    :      1;
+		uint64_t       i_rsvd                    :     51;
+	} ii_itte4_fld_s;
+} ii_itte4_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  There are seven instances of translation table entry   *
+ * registers. Each register maps a SHub Big Window to a 48-bit          *
+ * address on Crosstalk.                                                *
+ * For M-mode (128 nodes, 8 GBytes/node), SysAD[31:29] (Big Window      *
+ * number) are used to select one of these 7 registers. The Widget      *
+ * number field is then derived from the W_NUM field for synthesizing   *
+ * a Crosstalk packet. The 5 bits of OFFSET are concatenated with       *
+ * SysAD[28:0] to form Crosstalk[33:0]. The upper Crosstalk[47:34]      *
+ * are padded with zeros. Although the maximum Crosstalk space          *
+ * addressable by the Shub is thus the lower 16 GBytes per widget       *
+ * (M-mode), however only <SUP >7</SUP>/<SUB >32nds</SUB> of this       *
+ * space can be accessed.                                               *
+ * For the N-mode (256 nodes, 4 GBytes/node), SysAD[30:28] (Big         *
+ * Window number) are used to select one of these 7 registers. The      *
+ * Widget number field is then derived from the W_NUM field for         *
+ * synthesizing a Crosstalk packet. The 5 bits of OFFSET are            *
+ * concatenated with SysAD[27:0] to form Crosstalk[33:0]. The IOSP      *
+ * field is used as Crosstalk[47], and remainder of the Crosstalk       *
+ * address bits (Crosstalk[46:34]) are always zero. While the maximum   *
+ * Crosstalk space addressable by the Shub is thus the lower            *
+ * 8-GBytes per widget (N-mode), only <SUP >7</SUP>/<SUB >32nds</SUB>   *
+ * of this space can be accessed.                                       *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_itte5_u {
+	uint64_t	ii_itte5_regval;
+	struct  {
+		uint64_t	i_offset                  :	 5;
+		uint64_t       i_rsvd_1                  :      3;
+		uint64_t       i_w_num                   :      4;
+		uint64_t       i_iosp                    :      1;
+		uint64_t       i_rsvd                    :     51;
+	} ii_itte5_fld_s;
+} ii_itte5_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  There are seven instances of translation table entry   *
+ * registers. Each register maps a Shub Big Window to a 48-bit          *
+ * address on Crosstalk.                                                *
+ * For M-mode (128 nodes, 8 GBytes/node), SysAD[31:29] (Big Window      *
+ * number) are used to select one of these 7 registers. The Widget      *
+ * number field is then derived from the W_NUM field for synthesizing   *
+ * a Crosstalk packet. The 5 bits of OFFSET are concatenated with       *
+ * SysAD[28:0] to form Crosstalk[33:0]. The upper Crosstalk[47:34]      *
+ * are padded with zeros. Although the maximum Crosstalk space          *
+ * addressable by the Shub is thus the lower 16 GBytes per widget       *
+ * (M-mode), however only <SUP >7</SUP>/<SUB >32nds</SUB> of this       *
+ * space can be accessed.                                               *
+ * For the N-mode (256 nodes, 4 GBytes/node), SysAD[30:28] (Big         *
+ * Window number) are used to select one of these 7 registers. The      *
+ * Widget number field is then derived from the W_NUM field for         *
+ * synthesizing a Crosstalk packet. The 5 bits of OFFSET are            *
+ * concatenated with SysAD[27:0] to form Crosstalk[33:0]. The IOSP      *
+ * field is used as Crosstalk[47], and remainder of the Crosstalk       *
+ * address bits (Crosstalk[46:34]) are always zero. While the maximum   *
+ * Crosstalk space addressable by the Shub is thus the lower            *
+ * 8-GBytes per widget (N-mode), only <SUP >7</SUP>/<SUB >32nds</SUB>   *
+ * of this space can be accessed.                                       *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_itte6_u {
+	uint64_t	ii_itte6_regval;
+	struct  {
+		uint64_t	i_offset                  :	 5;
+		uint64_t       i_rsvd_1                  :      3;
+		uint64_t       i_w_num                   :      4;
+		uint64_t       i_iosp                    :      1;
+		uint64_t       i_rsvd                    :     51;
+	} ii_itte6_fld_s;
+} ii_itte6_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  There are seven instances of translation table entry   *
+ * registers. Each register maps a Shub Big Window to a 48-bit          *
+ * address on Crosstalk.                                                *
+ * For M-mode (128 nodes, 8 GBytes/node), SysAD[31:29] (Big Window      *
+ * number) are used to select one of these 7 registers. The Widget      *
+ * number field is then derived from the W_NUM field for synthesizing   *
+ * a Crosstalk packet. The 5 bits of OFFSET are concatenated with       *
+ * SysAD[28:0] to form Crosstalk[33:0]. The upper Crosstalk[47:34]      *
+ * are padded with zeros. Although the maximum Crosstalk space          *
+ * addressable by the Shub is thus the lower 16 GBytes per widget       *
+ * (M-mode), however only <SUP >7</SUP>/<SUB >32nds</SUB> of this       *
+ * space can be accessed.                                               *
+ * For the N-mode (256 nodes, 4 GBytes/node), SysAD[30:28] (Big         *
+ * Window number) are used to select one of these 7 registers. The      *
+ * Widget number field is then derived from the W_NUM field for         *
+ * synthesizing a Crosstalk packet. The 5 bits of OFFSET are            *
+ * concatenated with SysAD[27:0] to form Crosstalk[33:0]. The IOSP      *
+ * field is used as Crosstalk[47], and remainder of the Crosstalk       *
+ * address bits (Crosstalk[46:34]) are always zero. While the maximum   *
+ * Crosstalk space addressable by the SHub is thus the lower            *
+ * 8-GBytes per widget (N-mode), only <SUP >7</SUP>/<SUB >32nds</SUB>   *
+ * of this space can be accessed.                                       *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_itte7_u {
+	uint64_t	ii_itte7_regval;
+	struct  {
+		uint64_t	i_offset                  :	 5;
+		uint64_t	i_rsvd_1		  :	 3;
+		uint64_t       i_w_num                   :      4;
+		uint64_t       i_iosp                    :      1;
+		uint64_t       i_rsvd                    :     51;
+	} ii_itte7_fld_s;
+} ii_itte7_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  There are 9 instances of this register, one per        *
+ * actual widget in this implementation of SHub and Crossbow.           *
+ * Note: Crossbow only has ports for Widgets 8 through F, widget 0      *
+ * refers to Crossbow's internal space.                                 *
+ * This register contains the state elements per widget that are        *
+ * necessary to manage the PIO flow control on Crosstalk and on the     *
+ * Router Network. See the PIO Flow Control chapter for a complete      *
+ * description of this register                                         *
+ * The SPUR_WR bit requires some explanation. When this register is     *
+ * written, the new value of the C field is captured in an internal     *
+ * register so the hardware can remember what the programmer wrote      *
+ * into the credit counter. The SPUR_WR bit sets whenever the C field   *
+ * increments above this stored value, which indicates that there       *
+ * have been more responses received than requests sent. The SPUR_WR    *
+ * bit cannot be cleared until a value is written to the IPRBx          *
+ * register; the write will correct the C field and capture its new     *
+ * value in the internal register. Even if IECLR[E_PRB_x] is set, the   *
+ * SPUR_WR bit will persist if IPRBx hasn't yet been written.           *
+ * .                                                                    *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iprb0_u {
+	uint64_t	ii_iprb0_regval;
+	struct  {
+		uint64_t	i_c                       :	 8;
+		uint64_t	i_na			  :	14;
+		uint64_t       i_rsvd_2                  :      2;
+		uint64_t	i_nb			  :	14;
+		uint64_t	i_rsvd_1		  :	 2;
+		uint64_t	i_m			  :	 2;
+		uint64_t	i_f			  :	 1;
+		uint64_t	i_of_cnt		  :	 5;
+		uint64_t	i_error			  :	 1;
+		uint64_t	i_rd_to			  :	 1;
+		uint64_t	i_spur_wr		  :	 1;
+		uint64_t	i_spur_rd		  :	 1;
+		uint64_t	i_rsvd			  :	11;
+		uint64_t	i_mult_err		  :	 1;
+	} ii_iprb0_fld_s;
+} ii_iprb0_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  There are 9 instances of this register, one per        *
+ * actual widget in this implementation of SHub and Crossbow.           *
+ * Note: Crossbow only has ports for Widgets 8 through F, widget 0      *
+ * refers to Crossbow's internal space.                                 *
+ * This register contains the state elements per widget that are        *
+ * necessary to manage the PIO flow control on Crosstalk and on the     *
+ * Router Network. See the PIO Flow Control chapter for a complete      *
+ * description of this register                                         *
+ * The SPUR_WR bit requires some explanation. When this register is     *
+ * written, the new value of the C field is captured in an internal     *
+ * register so the hardware can remember what the programmer wrote      *
+ * into the credit counter. The SPUR_WR bit sets whenever the C field   *
+ * increments above this stored value, which indicates that there       *
+ * have been more responses received than requests sent. The SPUR_WR    *
+ * bit cannot be cleared until a value is written to the IPRBx          *
+ * register; the write will correct the C field and capture its new     *
+ * value in the internal register. Even if IECLR[E_PRB_x] is set, the   *
+ * SPUR_WR bit will persist if IPRBx hasn't yet been written.           *
+ * .                                                                    *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iprb8_u {
+	uint64_t	ii_iprb8_regval;
+	struct  {
+		uint64_t	i_c                       :	 8;
+		uint64_t	i_na			  :	14;
+		uint64_t       i_rsvd_2                  :      2;
+		uint64_t	i_nb			  :	14;
+		uint64_t       i_rsvd_1                  :      2;
+		uint64_t       i_m                       :      2;
+		uint64_t       i_f                       :      1;
+		uint64_t       i_of_cnt                  :      5;
+		uint64_t       i_error                   :      1;
+		uint64_t       i_rd_to                   :      1;
+		uint64_t       i_spur_wr                 :      1;
+		uint64_t	i_spur_rd		  :	 1;
+		uint64_t       i_rsvd                    :     11;
+		uint64_t	i_mult_err		  :	 1;
+	} ii_iprb8_fld_s;
+} ii_iprb8_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  There are 9 instances of this register, one per        *
+ * actual widget in this implementation of SHub and Crossbow.           *
+ * Note: Crossbow only has ports for Widgets 8 through F, widget 0      *
+ * refers to Crossbow's internal space.                                 *
+ * This register contains the state elements per widget that are        *
+ * necessary to manage the PIO flow control on Crosstalk and on the     *
+ * Router Network. See the PIO Flow Control chapter for a complete      *
+ * description of this register                                         *
+ * The SPUR_WR bit requires some explanation. When this register is     *
+ * written, the new value of the C field is captured in an internal     *
+ * register so the hardware can remember what the programmer wrote      *
+ * into the credit counter. The SPUR_WR bit sets whenever the C field   *
+ * increments above this stored value, which indicates that there       *
+ * have been more responses received than requests sent. The SPUR_WR    *
+ * bit cannot be cleared until a value is written to the IPRBx          *
+ * register; the write will correct the C field and capture its new     *
+ * value in the internal register. Even if IECLR[E_PRB_x] is set, the   *
+ * SPUR_WR bit will persist if IPRBx hasn't yet been written.           *
+ * .                                                                    *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iprb9_u {
+	uint64_t	ii_iprb9_regval;
+	struct	{
+		uint64_t	i_c			  :	 8;
+		uint64_t	i_na			  :	14;
+		uint64_t	i_rsvd_2		  :	 2;
+		uint64_t	i_nb			  :	14;
+		uint64_t	i_rsvd_1		  :	 2;
+		uint64_t	i_m			  :	 2;
+		uint64_t	i_f			  :	 1;
+		uint64_t	i_of_cnt		  :	 5;
+		uint64_t	i_error			  :	 1;
+		uint64_t	i_rd_to			  :	 1;
+		uint64_t	i_spur_wr		  :	 1;
+		uint64_t	i_spur_rd		  :	 1;
+		uint64_t	i_rsvd			  :	11;
+		uint64_t	i_mult_err		  :	 1;
+	} ii_iprb9_fld_s;
+} ii_iprb9_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  There are 9 instances of this register, one per        *
+ * actual widget in this implementation of SHub and Crossbow.        *
+ * Note: Crossbow only has ports for Widgets 8 through F, widget 0      *
+ * refers to Crossbow's internal space.                                 *
+ * This register contains the state elements per widget that are        *
+ * necessary to manage the PIO flow control on Crosstalk and on the     *
+ * Router Network. See the PIO Flow Control chapter for a complete      *
+ * description of this register                                         *
+ * The SPUR_WR bit requires some explanation. When this register is     *
+ * written, the new value of the C field is captured in an internal     *
+ * register so the hardware can remember what the programmer wrote      *
+ * into the credit counter. The SPUR_WR bit sets whenever the C field   *
+ * increments above this stored value, which indicates that there       *
+ * have been more responses received than requests sent. The SPUR_WR    *
+ * bit cannot be cleared until a value is written to the IPRBx          *
+ * register; the write will correct the C field and capture its new     *
+ * value in the internal register. Even if IECLR[E_PRB_x] is set, the   *
+ * SPUR_WR bit will persist if IPRBx hasn't yet been written.           *
+ *                                                                      *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iprba_u {
+	uint64_t	ii_iprba_regval;
+	struct  {
+		uint64_t	i_c                       :	 8;
+		uint64_t	i_na			  :	14;
+		uint64_t       i_rsvd_2                  :      2;
+		uint64_t	i_nb			  :	14;
+		uint64_t	i_rsvd_1		  :	 2;
+		uint64_t	i_m			  :	 2;
+		uint64_t	i_f			  :	 1;
+		uint64_t	i_of_cnt		  :	 5;
+		uint64_t	i_error			  :	 1;
+		uint64_t	i_rd_to			  :	 1;
+		uint64_t	i_spur_wr		  :	 1;
+		uint64_t	i_spur_rd		  :	 1;
+		uint64_t	i_rsvd			  :	11;
+		uint64_t	i_mult_err		  :	 1;
+	} ii_iprba_fld_s;
+} ii_iprba_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  There are 9 instances of this register, one per        *
+ * actual widget in this implementation of SHub and Crossbow.           *
+ * Note: Crossbow only has ports for Widgets 8 through F, widget 0      *
+ * refers to Crossbow's internal space.                                 *
+ * This register contains the state elements per widget that are        *
+ * necessary to manage the PIO flow control on Crosstalk and on the     *
+ * Router Network. See the PIO Flow Control chapter for a complete      *
+ * description of this register                                         *
+ * The SPUR_WR bit requires some explanation. When this register is     *
+ * written, the new value of the C field is captured in an internal     *
+ * register so the hardware can remember what the programmer wrote      *
+ * into the credit counter. The SPUR_WR bit sets whenever the C field   *
+ * increments above this stored value, which indicates that there       *
+ * have been more responses received than requests sent. The SPUR_WR    *
+ * bit cannot be cleared until a value is written to the IPRBx          *
+ * register; the write will correct the C field and capture its new     *
+ * value in the internal register. Even if IECLR[E_PRB_x] is set, the   *
+ * SPUR_WR bit will persist if IPRBx hasn't yet been written.           *
+ * .                                                                    *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iprbb_u {
+	uint64_t	ii_iprbb_regval;
+	struct	{
+		uint64_t	i_c			  :	 8;
+		uint64_t	i_na			  :	14;
+		uint64_t	i_rsvd_2		  :	 2;
+		uint64_t	i_nb			  :	14;
+		uint64_t	i_rsvd_1		  :	 2;
+		uint64_t	i_m			  :	 2;
+		uint64_t	i_f			  :	 1;
+		uint64_t	i_of_cnt		  :	 5;
+		uint64_t	i_error			  :	 1;
+		uint64_t	i_rd_to			  :	 1;
+		uint64_t	i_spur_wr		  :	 1;
+		uint64_t	i_spur_rd		  :	 1;
+		uint64_t	i_rsvd			  :	11;
+		uint64_t	i_mult_err		  :	 1;
+	} ii_iprbb_fld_s;
+} ii_iprbb_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  There are 9 instances of this register, one per        *
+ * actual widget in this implementation of SHub and Crossbow.           *
+ * Note: Crossbow only has ports for Widgets 8 through F, widget 0      *
+ * refers to Crossbow's internal space.                                 *
+ * This register contains the state elements per widget that are        *
+ * necessary to manage the PIO flow control on Crosstalk and on the     *
+ * Router Network. See the PIO Flow Control chapter for a complete      *
+ * description of this register                                         *
+ * The SPUR_WR bit requires some explanation. When this register is     *
+ * written, the new value of the C field is captured in an internal     *
+ * register so the hardware can remember what the programmer wrote      *
+ * into the credit counter. The SPUR_WR bit sets whenever the C field   *
+ * increments above this stored value, which indicates that there       *
+ * have been more responses received than requests sent. The SPUR_WR    *
+ * bit cannot be cleared until a value is written to the IPRBx          *
+ * register; the write will correct the C field and capture its new     *
+ * value in the internal register. Even if IECLR[E_PRB_x] is set, the   *
+ * SPUR_WR bit will persist if IPRBx hasn't yet been written.           *
+ * .                                                                    *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iprbc_u {
+	uint64_t	ii_iprbc_regval;
+	struct	{
+		uint64_t	i_c			  :	 8;
+		uint64_t	i_na			  :	14;
+		uint64_t	i_rsvd_2		  :	 2;
+		uint64_t	i_nb			  :	14;
+		uint64_t	i_rsvd_1		  :	 2;
+		uint64_t	i_m			  :	 2;
+		uint64_t	i_f			  :	 1;
+		uint64_t	i_of_cnt		  :	 5;
+		uint64_t	i_error			  :	 1;
+		uint64_t	i_rd_to			  :	 1;
+		uint64_t	i_spur_wr		  :	 1;
+		uint64_t	i_spur_rd		  :	 1;
+		uint64_t	i_rsvd			  :	11;
+		uint64_t	i_mult_err		  :	 1;
+	} ii_iprbc_fld_s;
+} ii_iprbc_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  There are 9 instances of this register, one per        *
+ * actual widget in this implementation of SHub and Crossbow.           *
+ * Note: Crossbow only has ports for Widgets 8 through F, widget 0      *
+ * refers to Crossbow's internal space.                                 *
+ * This register contains the state elements per widget that are        *
+ * necessary to manage the PIO flow control on Crosstalk and on the     *
+ * Router Network. See the PIO Flow Control chapter for a complete      *
+ * description of this register                                         *
+ * The SPUR_WR bit requires some explanation. When this register is     *
+ * written, the new value of the C field is captured in an internal     *
+ * register so the hardware can remember what the programmer wrote      *
+ * into the credit counter. The SPUR_WR bit sets whenever the C field   *
+ * increments above this stored value, which indicates that there       *
+ * have been more responses received than requests sent. The SPUR_WR    *
+ * bit cannot be cleared until a value is written to the IPRBx          *
+ * register; the write will correct the C field and capture its new     *
+ * value in the internal register. Even if IECLR[E_PRB_x] is set, the   *
+ * SPUR_WR bit will persist if IPRBx hasn't yet been written.           *
+ * .                                                                    *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iprbd_u {
+	uint64_t	ii_iprbd_regval;
+	struct	{
+		uint64_t	i_c			  :	 8;
+		uint64_t	i_na			  :	14;
+		uint64_t	i_rsvd_2		  :	 2;
+		uint64_t	i_nb			  :	14;
+		uint64_t	i_rsvd_1		  :	 2;
+		uint64_t	i_m			  :	 2;
+		uint64_t	i_f			  :	 1;
+		uint64_t	i_of_cnt		  :	 5;
+		uint64_t	i_error			  :	 1;
+		uint64_t	i_rd_to			  :	 1;
+		uint64_t	i_spur_wr		  :	 1;
+		uint64_t	i_spur_rd		  :	 1;
+		uint64_t	i_rsvd			  :	11;
+		uint64_t	i_mult_err		  :	 1;
+	} ii_iprbd_fld_s;
+} ii_iprbd_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  There are 9 instances of this register, one per        *
+ * actual widget in this implementation of SHub and Crossbow.           *
+ * Note: Crossbow only has ports for Widgets 8 through F, widget 0      *
+ * refers to Crossbow's internal space.                                 *
+ * This register contains the state elements per widget that are        *
+ * necessary to manage the PIO flow control on Crosstalk and on the     *
+ * Router Network. See the PIO Flow Control chapter for a complete      *
+ * description of this register                                         *
+ * The SPUR_WR bit requires some explanation. When this register is     *
+ * written, the new value of the C field is captured in an internal     *
+ * register so the hardware can remember what the programmer wrote      *
+ * into the credit counter. The SPUR_WR bit sets whenever the C field   *
+ * increments above this stored value, which indicates that there       *
+ * have been more responses received than requests sent. The SPUR_WR    *
+ * bit cannot be cleared until a value is written to the IPRBx          *
+ * register; the write will correct the C field and capture its new     *
+ * value in the internal register. Even if IECLR[E_PRB_x] is set, the   *
+ * SPUR_WR bit will persist if IPRBx hasn't yet been written.           *
+ * .                                                                    *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iprbe_u {
+	uint64_t	ii_iprbe_regval;
+	struct	{
+		uint64_t	i_c			  :	 8;
+		uint64_t	i_na			  :	14;
+		uint64_t	i_rsvd_2		  :	 2;
+		uint64_t	i_nb			  :	14;
+		uint64_t	i_rsvd_1		  :	 2;
+		uint64_t	i_m			  :	 2;
+		uint64_t	i_f			  :	 1;
+		uint64_t	i_of_cnt		  :	 5;
+		uint64_t	i_error			  :	 1;
+		uint64_t	i_rd_to			  :	 1;
+		uint64_t	i_spur_wr		  :	 1;
+		uint64_t	i_spur_rd		  :	 1;
+		uint64_t	i_rsvd			  :	11;
+		uint64_t	i_mult_err		  :	 1;
+	} ii_iprbe_fld_s;
+} ii_iprbe_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  There are 9 instances of this register, one per        *
+ * actual widget in this implementation of Shub and Crossbow.           *
+ * Note: Crossbow only has ports for Widgets 8 through F, widget 0      *
+ * refers to Crossbow's internal space.                                 *
+ * This register contains the state elements per widget that are        *
+ * necessary to manage the PIO flow control on Crosstalk and on the     *
+ * Router Network. See the PIO Flow Control chapter for a complete      *
+ * description of this register                                         *
+ * The SPUR_WR bit requires some explanation. When this register is     *
+ * written, the new value of the C field is captured in an internal     *
+ * register so the hardware can remember what the programmer wrote      *
+ * into the credit counter. The SPUR_WR bit sets whenever the C field   *
+ * increments above this stored value, which indicates that there       *
+ * have been more responses received than requests sent. The SPUR_WR    *
+ * bit cannot be cleared until a value is written to the IPRBx          *
+ * register; the write will correct the C field and capture its new     *
+ * value in the internal register. Even if IECLR[E_PRB_x] is set, the   *
+ * SPUR_WR bit will persist if IPRBx hasn't yet been written.           *
+ * .                                                                    *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iprbf_u {
+        uint64_t       ii_iprbf_regval;
+        struct  {
+                uint64_t       i_c                       :      8;
+                uint64_t       i_na                      :     14;
+                uint64_t       i_rsvd_2                  :      2;
+                uint64_t       i_nb                      :     14;
+                uint64_t       i_rsvd_1                  :      2;
+                uint64_t       i_m                       :      2;
+                uint64_t       i_f                       :      1;
+                uint64_t       i_of_cnt                  :      5;
+                uint64_t       i_error                   :      1;
+                uint64_t       i_rd_to                   :      1;
+                uint64_t       i_spur_wr                 :      1;
+                uint64_t       i_spur_rd                 :      1;
+                uint64_t       i_rsvd                    :     11;
+                uint64_t       i_mult_err                :      1;
+        } ii_iprbe_fld_s;
+} ii_iprbf_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  This register specifies the timeout value to use for monitoring     *
+ * Crosstalk credits which are used outbound to Crosstalk. An           *
+ * internal counter called the Crosstalk Credit Timeout Counter         *
+ * increments every 128 II clocks. The counter starts counting          *
+ * anytime the credit count drops below a threshold, and resets to      *
+ * zero (stops counting) anytime the credit count is at or above the    *
+ * threshold. The threshold is 1 credit in direct connect mode and 2    *
+ * in Crossbow connect mode. When the internal Crosstalk Credit         *
+ * Timeout Counter reaches the value programmed in this register, a     *
+ * Crosstalk Credit Timeout has occurred. The internal counter is not   *
+ * readable from software, and stops counting at its maximum value,     *
+ * so it cannot cause more than one interrupt.                          *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_ixcc_u {
+	uint64_t	ii_ixcc_regval;
+	struct  {
+		uint64_t	i_time_out                :	26;
+		uint64_t	i_rsvd			  :	38;
+	} ii_ixcc_fld_s;
+} ii_ixcc_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  This register qualifies all the PIO and DMA            *
+ * operations launched from widget 0 towards the SHub. In               *
+ * addition, it also qualifies accesses by the BTE streams.             *
+ * The bits in each field of this register are cleared by the SHub      *
+ * upon detection of an error which requires widget 0 or the BTE        *
+ * streams to be terminated. Whether or not widget x has access         *
+ * rights to this SHub is determined by an AND of the device            *
+ * enable bit in the appropriate field of this register and bit 0 in    *
+ * the Wx_IAC field. The bits in this field are set by writing a 1 to   *
+ * them. Incoming replies from Crosstalk are not subject to this        *
+ * access control mechanism.                                            *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_imem_u {
+	uint64_t	ii_imem_regval;
+	struct  {
+		uint64_t	i_w0_esd                  :	 1;
+		uint64_t	i_rsvd_3		  :	 3;
+		uint64_t	i_b0_esd		  :	 1;
+		uint64_t	i_rsvd_2		  :	 3;
+		uint64_t	i_b1_esd		  :	 1;
+		uint64_t	i_rsvd_1		  :	 3;
+		uint64_t	i_clr_precise		  :	 1;
+		uint64_t       i_rsvd                    :     51;
+	} ii_imem_fld_s;
+} ii_imem_u_t;
+
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  This register specifies the timeout value to use for   *
+ * monitoring Crosstalk tail flits coming into the Shub in the          *
+ * TAIL_TO field. An internal counter associated with this register     *
+ * is incremented every 128 II internal clocks (7 bits). The counter    *
+ * starts counting anytime a header micropacket is received and stops   *
+ * counting (and resets to zero) any time a micropacket with a Tail     *
+ * bit is received. Once the counter reaches the threshold value        *
+ * programmed in this register, it generates an interrupt to the        *
+ * processor that is programmed into the IIDSR. The counter saturates   *
+ * (does not roll over) at its maximum value, so it cannot cause        *
+ * another interrupt until after it is cleared.                         *
+ * The register also contains the Read Response Timeout values. The     *
+ * Prescalar is 23 bits, and counts II clocks. An internal counter      *
+ * increments on every II clock and when it reaches the value in the    *
+ * Prescalar field, all IPRTE registers with their valid bits set       *
+ * have their Read Response timers bumped. Whenever any of them match   *
+ * the value in the RRSP_TO field, a Read Response Timeout has          *
+ * occurred, and error handling occurs as described in the Error        *
+ * Handling section of this document.                                   *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_ixtt_u {
+	uint64_t	ii_ixtt_regval;
+	struct  {
+		uint64_t	i_tail_to                 :	26;
+		uint64_t	i_rsvd_1		  :	 6;
+		uint64_t	i_rrsp_ps		  :	23;
+		uint64_t	i_rrsp_to		  :	 5;
+		uint64_t	i_rsvd			  :	 4;
+	} ii_ixtt_fld_s;
+} ii_ixtt_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  Writing a 1 to the fields of this register clears the appropriate   *
+ * error bits in other areas of SHub. Note that when the                *
+ * E_PRB_x bits are used to clear error bits in PRB registers,          *
+ * SPUR_RD and SPUR_WR may persist, because they require additional     *
+ * action to clear them. See the IPRBx and IXSS Register                *
+ * specifications.                                                      *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_ieclr_u {
+	uint64_t	ii_ieclr_regval;
+	struct  {
+		uint64_t	i_e_prb_0                 :	 1;
+		uint64_t	i_rsvd			  :	 7;
+		uint64_t	i_e_prb_8		  :	 1;
+		uint64_t	i_e_prb_9		  :	 1;
+		uint64_t	i_e_prb_a		  :	 1;
+		uint64_t	i_e_prb_b		  :	 1;
+		uint64_t	i_e_prb_c		  :	 1;
+		uint64_t	i_e_prb_d		  :	 1;
+		uint64_t	i_e_prb_e		  :	 1;
+		uint64_t	i_e_prb_f		  :	 1;
+		uint64_t	i_e_crazy		  :	 1;
+		uint64_t	i_e_bte_0		  :	 1;
+		uint64_t	i_e_bte_1		  :	 1;
+		uint64_t	i_reserved_1		  :	10;
+		uint64_t	i_spur_rd_hdr		  :	 1;
+		uint64_t	i_cam_intr_to		  :	 1;
+		uint64_t	i_cam_overflow		  :	 1;
+		uint64_t	i_cam_read_miss		  :	 1;
+		uint64_t	i_ioq_rep_underflow	  :	 1;
+		uint64_t	i_ioq_req_underflow	  :	 1;
+		uint64_t	i_ioq_rep_overflow	  :	 1;
+		uint64_t	i_ioq_req_overflow	  :	 1;
+		uint64_t	i_iiq_rep_overflow	  :	 1;
+		uint64_t	i_iiq_req_overflow	  :	 1;
+		uint64_t	i_ii_xn_rep_cred_overflow :	 1;
+		uint64_t	i_ii_xn_req_cred_overflow :	 1;
+		uint64_t	i_ii_xn_invalid_cmd	  :	 1;
+		uint64_t	i_xn_ii_invalid_cmd	  :	 1;
+		uint64_t	i_reserved_2		  :	21;
+	} ii_ieclr_fld_s;
+} ii_ieclr_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  This register controls both BTEs. SOFT_RESET is intended for        *
+ * recovery after an error. COUNT controls the total number of CRBs     *
+ * that both BTEs (combined) can use, which affects total BTE           *
+ * bandwidth.                                                           *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_ibcr_u {
+	uint64_t	ii_ibcr_regval;
+	struct  {
+		uint64_t	i_count                   :	 4;
+		uint64_t	i_rsvd_1		  :	 4;
+		uint64_t	i_soft_reset		  :	 1;
+		uint64_t	i_rsvd			  :	55;
+	} ii_ibcr_fld_s;
+} ii_ibcr_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  This register contains the header of a spurious read response       *
+ * received from Crosstalk. A spurious read response is defined as a    *
+ * read response received by II from a widget for which (1) the SIDN    *
+ * has a value between 1 and 7, inclusive (II never sends requests to   *
+ * these widgets (2) there is no valid IPRTE register which             *
+ * corresponds to the TNUM, or (3) the widget indicated in SIDN is      *
+ * not the same as the widget recorded in the IPRTE register            *
+ * referenced by the TNUM. If this condition is true, and if the        *
+ * IXSS[VALID] bit is clear, then the header of the spurious read       *
+ * response is capture in IXSM and IXSS, and IXSS[VALID] is set. The    *
+ * errant header is thereby captured, and no further spurious read      *
+ * respones are captured until IXSS[VALID] is cleared by setting the    *
+ * appropriate bit in IECLR.Everytime a spurious read response is       *
+ * detected, the SPUR_RD bit of the PRB corresponding to the incoming   *
+ * message's SIDN field is set. This always happens, regarless of       *
+ * whether a header is captured. The programmer should check            *
+ * IXSM[SIDN] to determine which widget sent the spurious response,     *
+ * because there may be more than one SPUR_RD bit set in the PRB        *
+ * registers. The widget indicated by IXSM[SIDN] was the first          *
+ * spurious read response to be received since the last time            *
+ * IXSS[VALID] was clear. The SPUR_RD bit of the corresponding PRB      *
+ * will be set. Any SPUR_RD bits in any other PRB registers indicate    *
+ * spurious messages from other widets which were detected after the    *
+ * header was captured..                                                *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_ixsm_u {
+	uint64_t	ii_ixsm_regval;
+	struct  {
+		uint64_t	i_byte_en                 :	32;
+		uint64_t	i_reserved		  :	 1;
+		uint64_t	i_tag			  :	 3;
+		uint64_t	i_alt_pactyp		  :	 4;
+		uint64_t	i_bo			  :	 1;
+		uint64_t	i_error			  :	 1;
+		uint64_t	i_vbpm			  :	 1;
+		uint64_t	i_gbr			  :	 1;
+		uint64_t	i_ds			  :	 2;
+		uint64_t	i_ct			  :	 1;
+		uint64_t	i_tnum			  :	 5;
+		uint64_t	i_pactyp		  :	 4;
+		uint64_t	i_sidn			  :	 4;
+		uint64_t	i_didn			  :	 4;
+	} ii_ixsm_fld_s;
+} ii_ixsm_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  This register contains the sideband bits of a spurious read         *
+ * response received from Crosstalk.                                    *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_ixss_u {
+	uint64_t	ii_ixss_regval;
+	struct  {
+		uint64_t	i_sideband                :	 8;
+		uint64_t	i_rsvd			  :	55;
+		uint64_t	i_valid			  :	 1;
+	} ii_ixss_fld_s;
+} ii_ixss_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  This register enables software to access the II LLP's test port.    *
+ * Refer to the LLP 2.5 documentation for an explanation of the test    *
+ * port. Software can write to this register to program the values      *
+ * for the control fields (TestErrCapture, TestClear, TestFlit,         *
+ * TestMask and TestSeed). Similarly, software can read from this       *
+ * register to obtain the values of the test port's status outputs      *
+ * (TestCBerr, TestValid and TestData).                                 *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_ilct_u {
+	uint64_t	ii_ilct_regval;
+	struct  {
+		uint64_t	i_test_seed               :	20;
+		uint64_t	i_test_mask               :	 8;
+		uint64_t	i_test_data               :	20;
+		uint64_t	i_test_valid              :	 1;
+		uint64_t	i_test_cberr              :	 1;
+		uint64_t	i_test_flit               :	 3;
+		uint64_t	i_test_clear              :	 1;
+		uint64_t	i_test_err_capture        :	 1;
+		uint64_t	i_rsvd                    :	 9;
+	} ii_ilct_fld_s;
+} ii_ilct_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  If the II detects an illegal incoming Duplonet packet (request or   *
+ * reply) when VALID==0 in the IIEPH1 register, then it saves the       *
+ * contents of the packet's header flit in the IIEPH1 and IIEPH2        *
+ * registers, sets the VALID bit in IIEPH1, clears the OVERRUN bit,     *
+ * and assigns a value to the ERR_TYPE field which indicates the        *
+ * specific nature of the error. The II recognizes four different       *
+ * types of errors: short request packets (ERR_TYPE==2), short reply    *
+ * packets (ERR_TYPE==3), long request packets (ERR_TYPE==4) and long   *
+ * reply packets (ERR_TYPE==5). The encodings for these types of        *
+ * errors were chosen to be consistent with the same types of errors    *
+ * indicated by the ERR_TYPE field in the LB_ERROR_HDR1 register (in    *
+ * the LB unit). If the II detects an illegal incoming Duplonet         *
+ * packet when VALID==1 in the IIEPH1 register, then it merely sets     *
+ * the OVERRUN bit to indicate that a subsequent error has happened,    *
+ * and does nothing further.                                            *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iieph1_u {
+	uint64_t	ii_iieph1_regval;
+	struct	{
+		uint64_t	i_command		  :	 7;
+		uint64_t	i_rsvd_5		  :	 1;
+		uint64_t	i_suppl			  :	14;
+		uint64_t	i_rsvd_4		  :	 1;
+		uint64_t	i_source		  :	14;
+		uint64_t	i_rsvd_3		  :	 1;
+		uint64_t	i_err_type		  :	 4;
+		uint64_t	i_rsvd_2		  :	 4;
+		uint64_t	i_overrun		  :	 1;
+		uint64_t	i_rsvd_1		  :	 3;
+		uint64_t	i_valid			  :	 1;
+		uint64_t	i_rsvd			  :	13;
+	} ii_iieph1_fld_s;
+} ii_iieph1_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  This register holds the Address field from the header flit of an    *
+ * incoming erroneous Duplonet packet, along with the tail bit which    *
+ * accompanied this header flit. This register is essentially an        *
+ * extension of IIEPH1. Two registers were necessary because the 64     *
+ * bits available in only a single register were insufficient to        *
+ * capture the entire header flit of an erroneous packet.               *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iieph2_u {
+	uint64_t	ii_iieph2_regval;
+	struct  {
+		uint64_t	i_rsvd_0		  :	 3;
+		uint64_t	i_address                 :	47;
+		uint64_t	i_rsvd_1		  :	10;
+		uint64_t	i_tail			  :	 1;
+		uint64_t	i_rsvd			  :	 3;
+	} ii_iieph2_fld_s;
+} ii_iieph2_u_t;
+
+
+/******************************/
+
+
+
+/************************************************************************
+ *                                                                      *
+ *  This register's value is a bit vector that guards access from SXBs  *
+ * to local registers within the II as well as to external Crosstalk    *
+ * widgets								*
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_islapr_u {
+	uint64_t	ii_islapr_regval;
+	struct  {
+		uint64_t	i_region		  :	64;
+	} ii_islapr_fld_s;
+} ii_islapr_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  A write to this register of the 56-bit value "Pup+Bun" will cause	*
+ * the bit in the ISLAPR register corresponding to the region of the	*
+ * requestor to be set (access allowed).				(
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_islapo_u {
+	uint64_t	ii_islapo_regval;
+	struct  {
+		uint64_t	i_io_sbx_ovrride	  :	56;
+		uint64_t	i_rsvd			  :	 8;
+	} ii_islapo_fld_s;
+} ii_islapo_u_t;
+
+/************************************************************************
+ *                                                                      *
+ *  Determines how long the wrapper will wait aftr an interrupt is	*
+ * initially issued from the II before it times out the outstanding	*
+ * interrupt and drops it from the interrupt queue.			* 
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iwi_u {
+	uint64_t	ii_iwi_regval;
+	struct  {
+		uint64_t	i_prescale		  :	24;
+		uint64_t	i_rsvd			  :	 8;
+		uint64_t	i_timeout		  :	 8;
+		uint64_t	i_rsvd1			  :	 8;
+		uint64_t	i_intrpt_retry_period	  :	 8;
+		uint64_t	i_rsvd2			  :	 8;
+	} ii_iwi_fld_s;
+} ii_iwi_u_t;
+
+/************************************************************************
+ *                                                                      *
+ *  Log errors which have occurred in the II wrapper. The errors are	*
+ * cleared by writing to the IECLR register.				* 
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iwel_u {
+	uint64_t	ii_iwel_regval;
+	struct  {
+		uint64_t	i_intr_timed_out	  :	 1;
+		uint64_t	i_rsvd			  :	 7;
+		uint64_t	i_cam_overflow		  :	 1;
+		uint64_t	i_cam_read_miss		  :	 1;
+		uint64_t	i_rsvd1			  :	 2;
+		uint64_t	i_ioq_rep_underflow	  :	 1;
+		uint64_t	i_ioq_req_underflow	  :	 1;
+		uint64_t	i_ioq_rep_overflow	  :	 1;
+		uint64_t	i_ioq_req_overflow	  :	 1;
+		uint64_t	i_iiq_rep_overflow	  :	 1;
+		uint64_t	i_iiq_req_overflow	  :	 1;
+		uint64_t	i_rsvd2			  :	 6;
+		uint64_t	i_ii_xn_rep_cred_over_under:	 1;
+		uint64_t	i_ii_xn_req_cred_over_under:	 1;
+		uint64_t	i_rsvd3			  :	 6;
+		uint64_t	i_ii_xn_invalid_cmd	  :	 1;
+		uint64_t	i_xn_ii_invalid_cmd	  :	 1;
+		uint64_t	i_rsvd4			  :	30;
+	} ii_iwel_fld_s;
+} ii_iwel_u_t;
+
+/************************************************************************
+ *                                                                      *
+ *  Controls the II wrapper.						* 
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iwc_u {
+	uint64_t	ii_iwc_regval;
+	struct  {
+		uint64_t	i_dma_byte_swap		  :	 1;
+		uint64_t	i_rsvd			  :	 3;
+		uint64_t	i_cam_read_lines_reset	  :	 1;
+		uint64_t	i_rsvd1			  :	 3;
+		uint64_t	i_ii_xn_cred_over_under_log:	 1;
+		uint64_t	i_rsvd2			  :	19;
+		uint64_t	i_xn_rep_iq_depth	  :	 5;
+		uint64_t	i_rsvd3			  :	 3;
+		uint64_t	i_xn_req_iq_depth	  :	 5;
+		uint64_t	i_rsvd4			  :	 3;
+		uint64_t	i_iiq_depth		  :	 6;
+		uint64_t	i_rsvd5			  :	12;
+		uint64_t	i_force_rep_cred	  :	 1;
+		uint64_t	i_force_req_cred	  :	 1;
+	} ii_iwc_fld_s;
+} ii_iwc_u_t;
+
+/************************************************************************
+ *                                                                      *
+ *  Status in the II wrapper.						* 
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iws_u {
+	uint64_t	ii_iws_regval;
+	struct  {
+		uint64_t	i_xn_rep_iq_credits	  :	 5;
+		uint64_t	i_rsvd			  :	 3;
+		uint64_t	i_xn_req_iq_credits	  :	 5;
+		uint64_t	i_rsvd1			  :	51;
+	} ii_iws_fld_s;
+} ii_iws_u_t;
+
+/************************************************************************
+ *                                                                      *
+ *  Masks errors in the IWEL register.					*
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iweim_u {
+	uint64_t	ii_iweim_regval;
+	struct  {
+		uint64_t	i_intr_timed_out	  :	 1;
+		uint64_t	i_rsvd			  :	 7;
+		uint64_t	i_cam_overflow		  :	 1;
+		uint64_t	i_cam_read_miss		  :	 1;
+		uint64_t	i_rsvd1			  :	 2;
+		uint64_t	i_ioq_rep_underflow	  :	 1;
+		uint64_t	i_ioq_req_underflow	  :	 1;
+		uint64_t	i_ioq_rep_overflow	  :	 1;
+		uint64_t	i_ioq_req_overflow	  :	 1;
+		uint64_t	i_iiq_rep_overflow	  :	 1;
+		uint64_t	i_iiq_req_overflow	  :	 1;
+		uint64_t	i_rsvd2			  :	 6;
+		uint64_t	i_ii_xn_rep_cred_overflow :	 1;
+		uint64_t	i_ii_xn_req_cred_overflow :	 1;
+		uint64_t	i_rsvd3			  :	 6;
+		uint64_t	i_ii_xn_invalid_cmd	  :	 1;
+		uint64_t	i_xn_ii_invalid_cmd	  :	 1;
+		uint64_t	i_rsvd4			  :	30;
+	} ii_iweim_fld_s;
+} ii_iweim_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  A write to this register causes a particular field in the           *
+ * corresponding widget's PRB entry to be adjusted up or down by 1.     *
+ * This counter should be used when recovering from error and reset     *
+ * conditions. Note that software would be capable of causing           *
+ * inadvertent overflow or underflow of these counters.                 *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_ipca_u {
+	uint64_t	ii_ipca_regval;
+	struct  {
+		uint64_t	i_wid                     :	 4;
+		uint64_t	i_adjust		  :	 1;
+		uint64_t	i_rsvd_1		  :	 3;
+		uint64_t	i_field			  :	 2;
+		uint64_t	i_rsvd			  :	54;
+	} ii_ipca_fld_s;
+} ii_ipca_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  There are 8 instances of this register. This register contains      *
+ * the information that the II has to remember once it has launched a   *
+ * PIO Read operation. The contents are used to form the correct        *
+ * Router Network packet and direct the Crosstalk reply to the          *
+ * appropriate processor.                                               *
+ *                                                                      *
+ ************************************************************************/
+
+
+typedef union ii_iprte0a_u {
+	uint64_t	ii_iprte0a_regval;
+	struct  {
+		uint64_t	i_rsvd_1                  :	54;
+		uint64_t	i_widget		  :	 4;
+		uint64_t	i_to_cnt		  :	 5;
+		uint64_t       i_vld                     :      1;
+	} ii_iprte0a_fld_s;
+} ii_iprte0a_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  There are 8 instances of this register. This register contains      *
+ * the information that the II has to remember once it has launched a   *
+ * PIO Read operation. The contents are used to form the correct        *
+ * Router Network packet and direct the Crosstalk reply to the          *
+ * appropriate processor.                                               *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iprte1a_u {
+	uint64_t	ii_iprte1a_regval;
+	struct  {
+		uint64_t	i_rsvd_1                  :	54;
+		uint64_t	i_widget		  :	 4;
+		uint64_t	i_to_cnt		  :	 5;
+		uint64_t       i_vld                     :      1;
+	} ii_iprte1a_fld_s;
+} ii_iprte1a_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  There are 8 instances of this register. This register contains      *
+ * the information that the II has to remember once it has launched a   *
+ * PIO Read operation. The contents are used to form the correct        *
+ * Router Network packet and direct the Crosstalk reply to the          *
+ * appropriate processor.                                               *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iprte2a_u {
+	uint64_t	ii_iprte2a_regval;
+	struct  {
+		uint64_t	i_rsvd_1                  :	54;
+		uint64_t	i_widget		  :	 4;
+		uint64_t	i_to_cnt		  :	 5;
+		uint64_t       i_vld                     :      1;
+	} ii_iprte2a_fld_s;
+} ii_iprte2a_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  There are 8 instances of this register. This register contains      *
+ * the information that the II has to remember once it has launched a   *
+ * PIO Read operation. The contents are used to form the correct        *
+ * Router Network packet and direct the Crosstalk reply to the          *
+ * appropriate processor.                                               *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iprte3a_u {
+	uint64_t	ii_iprte3a_regval;
+	struct  {
+		uint64_t	i_rsvd_1                  :	54;
+		uint64_t	i_widget		  :	 4;
+		uint64_t	i_to_cnt		  :	 5;
+		uint64_t	i_vld			  :	 1;
+	} ii_iprte3a_fld_s;
+} ii_iprte3a_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  There are 8 instances of this register. This register contains      *
+ * the information that the II has to remember once it has launched a   *
+ * PIO Read operation. The contents are used to form the correct        *
+ * Router Network packet and direct the Crosstalk reply to the          *
+ * appropriate processor.                                               *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iprte4a_u {
+	uint64_t	ii_iprte4a_regval;
+	struct	{
+		uint64_t	i_rsvd_1		  :	54;
+		uint64_t	i_widget		  :	 4;
+		uint64_t	i_to_cnt		  :	 5;
+		uint64_t	i_vld			  :	 1;
+	} ii_iprte4a_fld_s;
+} ii_iprte4a_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  There are 8 instances of this register. This register contains      *
+ * the information that the II has to remember once it has launched a   *
+ * PIO Read operation. The contents are used to form the correct        *
+ * Router Network packet and direct the Crosstalk reply to the          *
+ * appropriate processor.                                               *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iprte5a_u {
+	uint64_t	ii_iprte5a_regval;
+	struct	{
+		uint64_t	i_rsvd_1		  :	54;
+		uint64_t	i_widget		  :	 4;
+		uint64_t	i_to_cnt		  :	 5;
+		uint64_t	i_vld			  :	 1;
+	} ii_iprte5a_fld_s;
+} ii_iprte5a_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  There are 8 instances of this register. This register contains      *
+ * the information that the II has to remember once it has launched a   *
+ * PIO Read operation. The contents are used to form the correct        *
+ * Router Network packet and direct the Crosstalk reply to the          *
+ * appropriate processor.                                               *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iprte6a_u {
+	uint64_t	ii_iprte6a_regval;
+	struct	{
+		uint64_t	i_rsvd_1		  :	54;
+		uint64_t	i_widget		  :	 4;
+		uint64_t	i_to_cnt		  :	 5;
+		uint64_t	i_vld			  :	 1;
+	} ii_iprte6a_fld_s;
+} ii_iprte6a_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  There are 8 instances of this register. This register contains      *
+ * the information that the II has to remember once it has launched a   *
+ * PIO Read operation. The contents are used to form the correct        *
+ * Router Network packet and direct the Crosstalk reply to the          *
+ * appropriate processor.                                               *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iprte7a_u {
+        uint64_t       ii_iprte7a_regval;
+        struct  {
+                uint64_t       i_rsvd_1                  :     54;
+                uint64_t       i_widget                  :      4;
+                uint64_t       i_to_cnt                  :      5;
+                uint64_t       i_vld                     :      1;
+        } ii_iprtea7_fld_s;
+} ii_iprte7a_u_t;
+
+
+
+/************************************************************************
+ *                                                                      *
+ *  There are 8 instances of this register. This register contains      *
+ * the information that the II has to remember once it has launched a   *
+ * PIO Read operation. The contents are used to form the correct        *
+ * Router Network packet and direct the Crosstalk reply to the          *
+ * appropriate processor.                                               *
+ *                                                                      *
+ ************************************************************************/
+
+
+typedef union ii_iprte0b_u {
+	uint64_t	ii_iprte0b_regval;
+	struct  {
+		uint64_t	i_rsvd_1                  :	 3;
+		uint64_t	i_address		  :	47;
+		uint64_t	i_init			  :	 3;
+		uint64_t       i_source                  :     11;
+	} ii_iprte0b_fld_s;
+} ii_iprte0b_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  There are 8 instances of this register. This register contains      *
+ * the information that the II has to remember once it has launched a   *
+ * PIO Read operation. The contents are used to form the correct        *
+ * Router Network packet and direct the Crosstalk reply to the          *
+ * appropriate processor.                                               *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iprte1b_u {
+	uint64_t	ii_iprte1b_regval;
+	struct  {
+		uint64_t	i_rsvd_1                  :	 3;
+		uint64_t	i_address		  :	47;
+		uint64_t	i_init			  :	 3;
+		uint64_t       i_source                  :     11;
+	} ii_iprte1b_fld_s;
+} ii_iprte1b_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  There are 8 instances of this register. This register contains      *
+ * the information that the II has to remember once it has launched a   *
+ * PIO Read operation. The contents are used to form the correct        *
+ * Router Network packet and direct the Crosstalk reply to the          *
+ * appropriate processor.                                               *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iprte2b_u {
+	uint64_t	ii_iprte2b_regval;
+	struct  {
+		uint64_t	i_rsvd_1                  :	 3;
+		uint64_t	i_address		  :	47;
+		uint64_t	i_init			  :	 3;
+		uint64_t       i_source                  :     11;
+	} ii_iprte2b_fld_s;
+} ii_iprte2b_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  There are 8 instances of this register. This register contains      *
+ * the information that the II has to remember once it has launched a   *
+ * PIO Read operation. The contents are used to form the correct        *
+ * Router Network packet and direct the Crosstalk reply to the          *
+ * appropriate processor.                                               *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iprte3b_u {
+	uint64_t	ii_iprte3b_regval;
+	struct  {
+		uint64_t	i_rsvd_1                  :	 3;
+		uint64_t	i_address		  :	47;
+		uint64_t	i_init			  :	 3;
+		uint64_t       i_source                  :     11;
+	} ii_iprte3b_fld_s;
+} ii_iprte3b_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  There are 8 instances of this register. This register contains      *
+ * the information that the II has to remember once it has launched a   *
+ * PIO Read operation. The contents are used to form the correct        *
+ * Router Network packet and direct the Crosstalk reply to the          *
+ * appropriate processor.                                               *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iprte4b_u {
+	uint64_t	ii_iprte4b_regval;
+	struct	{
+		uint64_t	i_rsvd_1                  :	 3;
+		uint64_t	i_address		  :	47;
+		uint64_t	i_init			  :	 3;
+		uint64_t       i_source                  :     11;
+	} ii_iprte4b_fld_s;
+} ii_iprte4b_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  There are 8 instances of this register. This register contains      *
+ * the information that the II has to remember once it has launched a   *
+ * PIO Read operation. The contents are used to form the correct        *
+ * Router Network packet and direct the Crosstalk reply to the          *
+ * appropriate processor.                                               *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iprte5b_u {
+	uint64_t	ii_iprte5b_regval;
+	struct	{
+		uint64_t	i_rsvd_1                  :	 3;
+		uint64_t	i_address		  :	47;
+		uint64_t	i_init			  :	 3;
+		uint64_t       i_source                  :     11;
+	} ii_iprte5b_fld_s;
+} ii_iprte5b_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  There are 8 instances of this register. This register contains      *
+ * the information that the II has to remember once it has launched a   *
+ * PIO Read operation. The contents are used to form the correct        *
+ * Router Network packet and direct the Crosstalk reply to the          *
+ * appropriate processor.                                               *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iprte6b_u {
+	uint64_t	ii_iprte6b_regval;
+	struct	{
+		uint64_t	i_rsvd_1                  :	 3;
+		uint64_t	i_address		  :	47;
+		uint64_t	i_init			  :	 3;
+		uint64_t       i_source                  :     11;
+
+	} ii_iprte6b_fld_s;
+} ii_iprte6b_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  There are 8 instances of this register. This register contains      *
+ * the information that the II has to remember once it has launched a   *
+ * PIO Read operation. The contents are used to form the correct        *
+ * Router Network packet and direct the Crosstalk reply to the          *
+ * appropriate processor.                                               *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iprte7b_u {
+        uint64_t       ii_iprte7b_regval;
+        struct  {
+		uint64_t	i_rsvd_1                  :	 3;
+		uint64_t	i_address		  :	47;
+		uint64_t	i_init			  :	 3;
+		uint64_t       i_source                  :     11;
+        } ii_iprte7b_fld_s;
+} ii_iprte7b_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  SHub II contains a feature which did not exist in      *
+ * the Hub which automatically cleans up after a Read Response          *
+ * timeout, including deallocation of the IPRTE and recovery of IBuf    *
+ * space. The inclusion of this register in SHub is for backward        *
+ * compatibility                                                        *
+ * A write to this register causes an entry from the table of           *
+ * outstanding PIO Read Requests to be freed and returned to the        *
+ * stack of free entries. This register is used in handling the         *
+ * timeout errors that result in a PIO Reply never returning from       *
+ * Crosstalk.                                                           *
+ * Note that this register does not affect the contents of the IPRTE    *
+ * registers. The Valid bits in those registers have to be              *
+ * specifically turned off by software.                                 *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_ipdr_u {
+	uint64_t	ii_ipdr_regval;
+	struct  {
+		uint64_t	i_te                      :	 3;
+		uint64_t	i_rsvd_1		  :	 1;
+		uint64_t	i_pnd			  :	 1;
+		uint64_t	i_init_rpcnt		  :	 1;
+		uint64_t	i_rsvd			  :	58;
+	} ii_ipdr_fld_s;
+} ii_ipdr_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  A write to this register causes a CRB entry to be returned to the   *
+ * queue of free CRBs. The entry should have previously been cleared    *
+ * (mark bit) via backdoor access to the pertinent CRB entry. This      *
+ * register is used in the last step of handling the errors that are    *
+ * captured and marked in CRB entries.  Briefly: 1) first error for     *
+ * DMA write from a particular device, and first error for a            *
+ * particular BTE stream, lead to a marked CRB entry, and processor     *
+ * interrupt, 2) software reads the error information captured in the   *
+ * CRB entry, and presumably takes some corrective action, 3)           *
+ * software clears the mark bit, and finally 4) software writes to      *
+ * the ICDR register to return the CRB entry to the list of free CRB    *
+ * entries.                                                             *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_icdr_u {
+	uint64_t	ii_icdr_regval;
+	struct  {
+		uint64_t	i_crb_num                 :	 4;
+		uint64_t	i_pnd			  :	 1;
+		uint64_t       i_rsvd                    :     59;
+	} ii_icdr_fld_s;
+} ii_icdr_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  This register provides debug access to two FIFOs inside of II.      *
+ * Both IOQ_MAX* fields of this register contain the instantaneous      *
+ * depth (in units of the number of available entries) of the           *
+ * associated IOQ FIFO.  A read of this register will return the        *
+ * number of free entries on each FIFO at the time of the read.  So     *
+ * when a FIFO is idle, the associated field contains the maximum       *
+ * depth of the FIFO.  This register is writable for debug reasons      *
+ * and is intended to be written with the maximum desired FIFO depth    *
+ * while the FIFO is idle. Software must assure that II is idle when    *
+ * this register is written. If there are any active entries in any     *
+ * of these FIFOs when this register is written, the results are        *
+ * undefined.                                                           *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_ifdr_u {
+	uint64_t	ii_ifdr_regval;
+	struct  {
+		uint64_t	i_ioq_max_rq              :	 7;
+		uint64_t	i_set_ioq_rq		  :	 1;
+		uint64_t	i_ioq_max_rp		  :	 7;
+		uint64_t	i_set_ioq_rp		  :	 1;
+		uint64_t	i_rsvd			  :	48;
+	} ii_ifdr_fld_s;
+} ii_ifdr_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  This register allows the II to become sluggish in removing          *
+ * messages from its inbound queue (IIQ). This will cause messages to   *
+ * back up in either virtual channel. Disabling the "molasses" mode     *
+ * subsequently allows the II to be tested under stress. In the         *
+ * sluggish ("Molasses") mode, the localized effects of congestion      *
+ * can be observed.                                                     *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iiap_u {
+        uint64_t       ii_iiap_regval;
+        struct  {
+                uint64_t       i_rq_mls                  :      6;
+		uint64_t	i_rsvd_1		  :	 2;
+		uint64_t	i_rp_mls		  :	 6;
+		uint64_t       i_rsvd                    :     50;
+        } ii_iiap_fld_s;
+} ii_iiap_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  This register allows several parameters of CRB operation to be      *
+ * set. Note that writing to this register can have catastrophic side   *
+ * effects, if the CRB is not quiescent, i.e. if the CRB is             *
+ * processing protocol messages when the write occurs.                  *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_icmr_u {
+	uint64_t	ii_icmr_regval;
+	struct  {
+		uint64_t	i_sp_msg                  :	 1;
+		uint64_t	i_rd_hdr		  :	 1;
+		uint64_t	i_rsvd_4		  :	 2;
+		uint64_t	i_c_cnt			  :	 4;
+		uint64_t	i_rsvd_3		  :	 4;
+		uint64_t	i_clr_rqpd		  :	 1;
+		uint64_t	i_clr_rppd		  :	 1;
+		uint64_t	i_rsvd_2		  :	 2;
+		uint64_t	i_fc_cnt		  :	 4;
+		uint64_t	i_crb_vld		  :	15;
+		uint64_t	i_crb_mark		  :	15;
+		uint64_t	i_rsvd_1		  :	 2;
+		uint64_t	i_precise		  :	 1;
+		uint64_t	i_rsvd			  :	11;
+	} ii_icmr_fld_s;
+} ii_icmr_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  This register allows control of the table portion of the CRB        *
+ * logic via software. Control operations from this register have       *
+ * priority over all incoming Crosstalk or BTE requests.                *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_iccr_u {
+	uint64_t	ii_iccr_regval;
+	struct  {
+		uint64_t	i_crb_num                 :	 4;
+		uint64_t	i_rsvd_1		  :	 4;
+		uint64_t	i_cmd			  :	 8;
+		uint64_t	i_pending		  :	 1;
+		uint64_t	i_rsvd			  :	47;
+	} ii_iccr_fld_s;
+} ii_iccr_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  This register allows the maximum timeout value to be programmed.    *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_icto_u {
+	uint64_t	ii_icto_regval;
+	struct  {
+		uint64_t	i_timeout                 :	 8;
+		uint64_t	i_rsvd			  :	56;
+	} ii_icto_fld_s;
+} ii_icto_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  This register allows the timeout prescalar to be programmed. An     *
+ * internal counter is associated with this register. When the          *
+ * internal counter reaches the value of the PRESCALE field, the        *
+ * timer registers in all valid CRBs are incremented (CRBx_D[TIMEOUT]   *
+ * field). The internal counter resets to zero, and then continues      *
+ * counting.                                                            *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_ictp_u {
+	uint64_t	ii_ictp_regval;
+	struct  {
+		uint64_t	i_prescale                :	24;
+		uint64_t	i_rsvd			  :	40;
+	} ii_ictp_fld_s;
+} ii_ictp_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  There are 15 CRB Entries (ICRB0 to ICRBE) that are     *
+ * used for Crosstalk operations (both cacheline and partial            *
+ * operations) or BTE/IO. Because the CRB entries are very wide, five   *
+ * registers (_A to _E) are required to read and write each entry.      *
+ * The CRB Entry registers can be conceptualized as rows and columns    *
+ * (illustrated in the table above). Each row contains the 4            *
+ * registers required for a single CRB Entry. The first doubleword      *
+ * (column) for each entry is labeled A, and the second doubleword      *
+ * (higher address) is labeled B, the third doubleword is labeled C,    *
+ * the fourth doubleword is labeled D and the fifth doubleword is       *
+ * labeled E. All CRB entries have their addresses on a quarter         *
+ * cacheline aligned boundary.                   *
+ * Upon reset, only the following fields are initialized: valid         *
+ * (VLD), priority count, timeout, timeout valid, and context valid.    *
+ * All other bits should be cleared by software before use (after       *
+ * recovering any potential error state from before the reset).         *
+ * The following four tables summarize the format for the four          *
+ * registers that are used for each ICRB# Entry.                        *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_icrb0_a_u {
+	uint64_t	ii_icrb0_a_regval;
+	struct  {
+		uint64_t	ia_iow                    :	 1;
+		uint64_t	ia_vld			  :	 1;
+		uint64_t	ia_addr			  :	47;
+		uint64_t	ia_tnum			  :	 5;
+		uint64_t	ia_sidn			  :	 4;
+		uint64_t       ia_rsvd                   :      6;
+	} ii_icrb0_a_fld_s;
+} ii_icrb0_a_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  There are 15 CRB Entries (ICRB0 to ICRBE) that are     *
+ * used for Crosstalk operations (both cacheline and partial            *
+ * operations) or BTE/IO. Because the CRB entries are very wide, five   *
+ * registers (_A to _E) are required to read and write each entry.      *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_icrb0_b_u {
+	uint64_t	ii_icrb0_b_regval;
+	struct	{
+		uint64_t	ib_xt_err		  :	 1;
+		uint64_t	ib_mark			  :	 1;
+		uint64_t	ib_ln_uce		  :	 1;
+		uint64_t	ib_errcode		  :	 3;
+		uint64_t	ib_error		  :	 1;
+		uint64_t	ib_stall__bte_1		  :	 1;
+		uint64_t	ib_stall__bte_0		  :	 1;
+		uint64_t	ib_stall__intr		  :	 1;
+		uint64_t	ib_stall_ib		  :	 1;
+		uint64_t	ib_intvn		  :	 1;
+		uint64_t	ib_wb			  :	 1;
+		uint64_t	ib_hold			  :	 1;
+		uint64_t	ib_ack			  :	 1;
+		uint64_t	ib_resp			  :	 1;
+		uint64_t	ib_ack_cnt		  :	11;
+		uint64_t	ib_rsvd			  :	 7;
+		uint64_t	ib_exc			  :	 5;
+		uint64_t	ib_init			  :	 3;
+		uint64_t	ib_imsg			  :	 8;
+		uint64_t	ib_imsgtype		  :	 2;
+		uint64_t	ib_use_old		  :	 1;
+		uint64_t	ib_rsvd_1		  :	11;
+	} ii_icrb0_b_fld_s;
+} ii_icrb0_b_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  There are 15 CRB Entries (ICRB0 to ICRBE) that are     *
+ * used for Crosstalk operations (both cacheline and partial            *
+ * operations) or BTE/IO. Because the CRB entries are very wide, five   *
+ * registers (_A to _E) are required to read and write each entry.      *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_icrb0_c_u {
+	uint64_t	ii_icrb0_c_regval;
+	struct	{
+		uint64_t	ic_source		  :	15;
+		uint64_t	ic_size			  :	 2;
+		uint64_t	ic_ct			  :	 1;
+		uint64_t	ic_bte_num		  :	 1;
+		uint64_t	ic_gbr			  :	 1;
+		uint64_t	ic_resprqd		  :	 1;
+		uint64_t	ic_bo			  :	 1;
+		uint64_t	ic_suppl		  :	15;
+		uint64_t	ic_rsvd			  :	27;
+	} ii_icrb0_c_fld_s;
+} ii_icrb0_c_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  There are 15 CRB Entries (ICRB0 to ICRBE) that are     *
+ * used for Crosstalk operations (both cacheline and partial            *
+ * operations) or BTE/IO. Because the CRB entries are very wide, five   *
+ * registers (_A to _E) are required to read and write each entry.      *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_icrb0_d_u {
+	uint64_t	ii_icrb0_d_regval;
+	struct  {
+		uint64_t	id_pa_be                  :	43;
+		uint64_t	id_bte_op		  :	 1;
+		uint64_t	id_pr_psc		  :	 4;
+		uint64_t	id_pr_cnt		  :	 4;
+		uint64_t	id_sleep		  :	 1;
+		uint64_t	id_rsvd			  :	11;
+	} ii_icrb0_d_fld_s;
+} ii_icrb0_d_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  There are 15 CRB Entries (ICRB0 to ICRBE) that are     *
+ * used for Crosstalk operations (both cacheline and partial            *
+ * operations) or BTE/IO. Because the CRB entries are very wide, five   *
+ * registers (_A to _E) are required to read and write each entry.      *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_icrb0_e_u {
+	uint64_t	ii_icrb0_e_regval;
+	struct  {
+		uint64_t	ie_timeout                :	 8;
+		uint64_t	ie_context		  :	15;
+		uint64_t	ie_rsvd			  :	 1;
+		uint64_t	ie_tvld			  :	 1;
+		uint64_t	ie_cvld			  :	 1;
+		uint64_t	ie_rsvd_0		  :	38;
+	} ii_icrb0_e_fld_s;
+} ii_icrb0_e_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  This register contains the lower 64 bits of the header of the       *
+ * spurious message captured by II. Valid when the SP_MSG bit in ICMR   *
+ * register is set.                                                     *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_icsml_u {
+	uint64_t	ii_icsml_regval;
+	struct  {
+		uint64_t	i_tt_addr                 :	47;
+		uint64_t	i_newsuppl_ex		  :	14;
+		uint64_t	i_reserved		  :	 2;
+		uint64_t       i_overflow                :      1;
+	} ii_icsml_fld_s;
+} ii_icsml_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  This register contains the middle 64 bits of the header of the      *
+ * spurious message captured by II. Valid when the SP_MSG bit in ICMR   *
+ * register is set.                                                     *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_icsmm_u {
+	uint64_t	ii_icsmm_regval;
+	struct  {
+		uint64_t	i_tt_ack_cnt              :	11;
+		uint64_t	i_reserved		  :	53;
+	} ii_icsmm_fld_s;
+} ii_icsmm_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  This register contains the microscopic state, all the inputs to     *
+ * the protocol table, captured with the spurious message. Valid when   *
+ * the SP_MSG bit in the ICMR register is set.                          *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_icsmh_u {
+	uint64_t	ii_icsmh_regval;
+	struct  {
+		uint64_t	i_tt_vld                  :	 1;
+		uint64_t	i_xerr			  :	 1;
+		uint64_t	i_ft_cwact_o		  :	 1;
+		uint64_t	i_ft_wact_o		  :	 1;
+		uint64_t       i_ft_active_o             :      1;
+		uint64_t	i_sync			  :	 1;
+		uint64_t	i_mnusg			  :	 1;
+		uint64_t	i_mnusz			  :	 1;
+		uint64_t	i_plusz			  :	 1;
+		uint64_t	i_plusg			  :	 1;
+		uint64_t	i_tt_exc		  :	 5;
+		uint64_t	i_tt_wb			  :	 1;
+		uint64_t	i_tt_hold		  :	 1;
+		uint64_t	i_tt_ack		  :	 1;
+		uint64_t	i_tt_resp		  :	 1;
+		uint64_t	i_tt_intvn		  :	 1;
+		uint64_t	i_g_stall_bte1		  :	 1;
+		uint64_t	i_g_stall_bte0		  :	 1;
+		uint64_t	i_g_stall_il		  :	 1;
+		uint64_t	i_g_stall_ib		  :	 1;
+		uint64_t	i_tt_imsg		  :	 8;
+		uint64_t	i_tt_imsgtype		  :	 2;
+		uint64_t	i_tt_use_old		  :	 1;
+		uint64_t	i_tt_respreqd		  :	 1;
+		uint64_t	i_tt_bte_num		  :	 1;
+		uint64_t	i_cbn			  :	 1;
+		uint64_t	i_match			  :	 1;
+		uint64_t	i_rpcnt_lt_34		  :	 1;
+		uint64_t	i_rpcnt_ge_34		  :	 1;
+		uint64_t	i_rpcnt_lt_18		  :	 1;
+		uint64_t	i_rpcnt_ge_18		  :	 1;
+		uint64_t       i_rpcnt_lt_2              :      1;
+		uint64_t	i_rpcnt_ge_2		  :	 1;
+		uint64_t	i_rqcnt_lt_18		  :	 1;
+		uint64_t	i_rqcnt_ge_18		  :	 1;
+		uint64_t	i_rqcnt_lt_2		  :	 1;
+		uint64_t	i_rqcnt_ge_2		  :	 1;
+		uint64_t	i_tt_device		  :	 7;
+		uint64_t	i_tt_init		  :	 3;
+		uint64_t	i_reserved		  :	 5;
+	} ii_icsmh_fld_s;
+} ii_icsmh_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  The Shub DEBUG unit provides a 3-bit selection signal to the        *
+ * II core and a 3-bit selection signal to the fsbclk domain in the II  *
+ * wrapper.                                                             *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_idbss_u {
+	uint64_t	ii_idbss_regval;
+	struct  {
+		uint64_t	i_iioclk_core_submenu     :	 3;
+		uint64_t	i_rsvd			  :	 5;
+		uint64_t	i_fsbclk_wrapper_submenu  :	 3;
+		uint64_t	i_rsvd_1		  :	 5;
+		uint64_t	i_iioclk_menu		  :	 5;
+		uint64_t	i_rsvd_2		  :	43;
+	} ii_idbss_fld_s;
+} ii_idbss_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  This register is used to set up the length for a       *
+ * transfer and then to monitor the progress of that transfer. This     *
+ * register needs to be initialized before a transfer is started. A     *
+ * legitimate write to this register will set the Busy bit, clear the   *
+ * Error bit, and initialize the length to the value desired.           *
+ * While the transfer is in progress, hardware will decrement the       *
+ * length field with each successful block that is copied. Once the     *
+ * transfer completes, hardware will clear the Busy bit. The length     *
+ * field will also contain the number of cache lines left to be         *
+ * transferred.                                                         *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_ibls0_u {
+	uint64_t	ii_ibls0_regval;
+	struct	{
+		uint64_t	i_length		  :	16;
+		uint64_t	i_error			  :	 1;
+		uint64_t	i_rsvd_1		  :	 3;
+		uint64_t	i_busy			  :	 1;
+		uint64_t       i_rsvd                    :     43;
+	} ii_ibls0_fld_s;
+} ii_ibls0_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  This register should be loaded before a transfer is started. The    *
+ * address to be loaded in bits 39:0 is the 40-bit TRex+ physical       *
+ * address as described in Section 1.3, Figure2 and Figure3. Since      *
+ * the bottom 7 bits of the address are always taken to be zero, BTE    *
+ * transfers are always cacheline-aligned.                              *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_ibsa0_u {
+	uint64_t	ii_ibsa0_regval;
+	struct  {
+		uint64_t	i_rsvd_1                  :	 7;
+		uint64_t	i_addr			  :	42;
+		uint64_t       i_rsvd                    :     15;
+	} ii_ibsa0_fld_s;
+} ii_ibsa0_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  This register should be loaded before a transfer is started. The    *
+ * address to be loaded in bits 39:0 is the 40-bit TRex+ physical       *
+ * address as described in Section 1.3, Figure2 and Figure3. Since      *
+ * the bottom 7 bits of the address are always taken to be zero, BTE    *
+ * transfers are always cacheline-aligned.                              *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_ibda0_u {
+	uint64_t	ii_ibda0_regval;
+	struct  {
+		uint64_t	i_rsvd_1                  :	 7;
+		uint64_t	i_addr			  :	42;
+		uint64_t	i_rsvd			  :	15;
+	} ii_ibda0_fld_s;
+} ii_ibda0_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  Writing to this register sets up the attributes of the transfer     *
+ * and initiates the transfer operation. Reading this register has      *
+ * the side effect of terminating any transfer in progress. Note:       *
+ * stopping a transfer midstream could have an adverse impact on the    *
+ * other BTE. If a BTE stream has to be stopped (due to error           *
+ * handling for example), both BTE streams should be stopped and        *
+ * their transfers discarded.                                           *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_ibct0_u {
+	uint64_t	ii_ibct0_regval;
+	struct  {
+		uint64_t	i_zerofill                :	 1;
+		uint64_t	i_rsvd_2		  :	 3;
+		uint64_t	i_notify		  :	 1;
+		uint64_t	i_rsvd_1		  :	 3;
+		uint64_t       i_poison                  :      1;
+		uint64_t       i_rsvd                    :     55;
+	} ii_ibct0_fld_s;
+} ii_ibct0_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  This register contains the address to which the WINV is sent.       *
+ * This address has to be cache line aligned.                           *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_ibna0_u {
+	uint64_t	ii_ibna0_regval;
+	struct  {
+		uint64_t	i_rsvd_1                  :	 7;
+		uint64_t	i_addr			  :	42;
+		uint64_t	i_rsvd			  :	15;
+	} ii_ibna0_fld_s;
+} ii_ibna0_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  This register contains the programmable level as well as the node   *
+ * ID and PI unit of the processor to which the interrupt will be       *
+ * sent.                                                                *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_ibia0_u {
+	uint64_t	ii_ibia0_regval;
+	struct  {
+		uint64_t	i_rsvd_2                   :	 1;
+		uint64_t	i_node_id		  :	11;
+		uint64_t	i_rsvd_1		  :	 4;
+		uint64_t	i_level			  :	 7;
+		uint64_t       i_rsvd                    :     41;
+	} ii_ibia0_fld_s;
+} ii_ibia0_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ * Description:  This register is used to set up the length for a       *
+ * transfer and then to monitor the progress of that transfer. This     *
+ * register needs to be initialized before a transfer is started. A     *
+ * legitimate write to this register will set the Busy bit, clear the   *
+ * Error bit, and initialize the length to the value desired.           *
+ * While the transfer is in progress, hardware will decrement the       *
+ * length field with each successful block that is copied. Once the     *
+ * transfer completes, hardware will clear the Busy bit. The length     *
+ * field will also contain the number of cache lines left to be         *
+ * transferred.                                                         *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_ibls1_u {
+	uint64_t	ii_ibls1_regval;
+	struct  {
+		uint64_t	i_length                  :	16;
+		uint64_t	i_error			  :	 1;
+		uint64_t	i_rsvd_1		  :	 3;
+		uint64_t	i_busy			  :	 1;
+		uint64_t       i_rsvd                    :     43;
+	} ii_ibls1_fld_s;
+} ii_ibls1_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  This register should be loaded before a transfer is started. The    *
+ * address to be loaded in bits 39:0 is the 40-bit TRex+ physical       *
+ * address as described in Section 1.3, Figure2 and Figure3. Since      *
+ * the bottom 7 bits of the address are always taken to be zero, BTE    *
+ * transfers are always cacheline-aligned.                              *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_ibsa1_u {
+	uint64_t	ii_ibsa1_regval;
+	struct  {
+		uint64_t	i_rsvd_1                  :	 7;
+		uint64_t	i_addr			  :	33;
+		uint64_t	i_rsvd			  :	24;
+	} ii_ibsa1_fld_s;
+} ii_ibsa1_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  This register should be loaded before a transfer is started. The    *
+ * address to be loaded in bits 39:0 is the 40-bit TRex+ physical       *
+ * address as described in Section 1.3, Figure2 and Figure3. Since      *
+ * the bottom 7 bits of the address are always taken to be zero, BTE    *
+ * transfers are always cacheline-aligned.                              *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_ibda1_u {
+	uint64_t	ii_ibda1_regval;
+	struct  {
+		uint64_t	i_rsvd_1                  :	 7;
+		uint64_t	i_addr			  :	33;
+		uint64_t	i_rsvd			  :	24;
+	} ii_ibda1_fld_s;
+} ii_ibda1_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  Writing to this register sets up the attributes of the transfer     *
+ * and initiates the transfer operation. Reading this register has      *
+ * the side effect of terminating any transfer in progress. Note:       *
+ * stopping a transfer midstream could have an adverse impact on the    *
+ * other BTE. If a BTE stream has to be stopped (due to error           *
+ * handling for example), both BTE streams should be stopped and        *
+ * their transfers discarded.                                           *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_ibct1_u {
+	uint64_t	ii_ibct1_regval;
+	struct  {
+		uint64_t	i_zerofill                :	 1;
+		uint64_t	i_rsvd_2		  :	 3;
+		uint64_t	i_notify		  :	 1;
+		uint64_t	i_rsvd_1		  :	 3;
+		uint64_t	i_poison		  :	 1;
+		uint64_t	i_rsvd			  :	55;
+	} ii_ibct1_fld_s;
+} ii_ibct1_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  This register contains the address to which the WINV is sent.       *
+ * This address has to be cache line aligned.                           *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_ibna1_u {
+	uint64_t	ii_ibna1_regval;
+	struct  {
+		uint64_t	i_rsvd_1                  :	 7;
+		uint64_t	i_addr			  :	33;
+		uint64_t       i_rsvd                    :     24;
+	} ii_ibna1_fld_s;
+} ii_ibna1_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  This register contains the programmable level as well as the node   *
+ * ID and PI unit of the processor to which the interrupt will be       *
+ * sent.                                                                *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_ibia1_u {
+	uint64_t	ii_ibia1_regval;
+	struct  {
+		uint64_t	i_pi_id                   :	 1;
+		uint64_t	i_node_id		  :	 8;
+		uint64_t	i_rsvd_1		  :	 7;
+		uint64_t	i_level			  :	 7;
+		uint64_t	i_rsvd			  :	41;
+	} ii_ibia1_fld_s;
+} ii_ibia1_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *  This register defines the resources that feed information into      *
+ * the two performance counters located in the IO Performance           *
+ * Profiling Register. There are 17 different quantities that can be    *
+ * measured. Given these 17 different options, the two performance      *
+ * counters have 15 of them in common; menu selections 0 through 0xE    *
+ * are identical for each performance counter. As for the other two     *
+ * options, one is available from one performance counter and the       *
+ * other is available from the other performance counter. Hence, the    *
+ * II supports all 17*16=272 possible combinations of quantities to     *
+ * measure.                                                             *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_ipcr_u {
+	uint64_t	ii_ipcr_regval;
+	struct  {
+		uint64_t	i_ippr0_c                 :	 4;
+		uint64_t	i_ippr1_c		  :	 4;
+		uint64_t	i_icct			  :	 8;
+		uint64_t       i_rsvd                    :     48;
+	} ii_ipcr_fld_s;
+} ii_ipcr_u_t;
+
+
+/************************************************************************
+ *                                                                      *
+ *                                                                      *
+ *                                                                      *
+ ************************************************************************/
+
+typedef union ii_ippr_u {
+	uint64_t	ii_ippr_regval;
+	struct  {
+		uint64_t	i_ippr0                   :	32;
+		uint64_t	i_ippr1			  :	32;
+	} ii_ippr_fld_s;
+} ii_ippr_u_t;
+
+
+
+/**************************************************************************
+ *                                                                        *
+ * The following defines which were not formed into structures are        *
+ * probably indentical to another register, and the name of the           *
+ * register is provided against each of these registers. This             *
+ * information needs to be checked carefully                              *
+ *                                                                        *
+ *           IIO_ICRB1_A                IIO_ICRB0_A                       *
+ *           IIO_ICRB1_B                IIO_ICRB0_B                       *
+ *           IIO_ICRB1_C                IIO_ICRB0_C                       *
+ *           IIO_ICRB1_D                IIO_ICRB0_D                       *
+ *           IIO_ICRB1_E                IIO_ICRB0_E                       *
+ *           IIO_ICRB2_A                IIO_ICRB0_A                       *
+ *           IIO_ICRB2_B                IIO_ICRB0_B                       *
+ *           IIO_ICRB2_C                IIO_ICRB0_C                       *
+ *           IIO_ICRB2_D                IIO_ICRB0_D                       *
+ *           IIO_ICRB2_E                IIO_ICRB0_E                       *
+ *           IIO_ICRB3_A                IIO_ICRB0_A                       *
+ *           IIO_ICRB3_B                IIO_ICRB0_B                       *
+ *           IIO_ICRB3_C                IIO_ICRB0_C                       *
+ *           IIO_ICRB3_D                IIO_ICRB0_D                       *
+ *           IIO_ICRB3_E                IIO_ICRB0_E                       *
+ *           IIO_ICRB4_A                IIO_ICRB0_A                       *
+ *           IIO_ICRB4_B                IIO_ICRB0_B                       *
+ *           IIO_ICRB4_C                IIO_ICRB0_C                       *
+ *           IIO_ICRB4_D                IIO_ICRB0_D                       *
+ *           IIO_ICRB4_E                IIO_ICRB0_E                       *
+ *           IIO_ICRB5_A                IIO_ICRB0_A                       *
+ *           IIO_ICRB5_B                IIO_ICRB0_B                       *
+ *           IIO_ICRB5_C                IIO_ICRB0_C                       *
+ *           IIO_ICRB5_D                IIO_ICRB0_D                       *
+ *           IIO_ICRB5_E                IIO_ICRB0_E                       *
+ *           IIO_ICRB6_A                IIO_ICRB0_A                       *
+ *           IIO_ICRB6_B                IIO_ICRB0_B                       *
+ *           IIO_ICRB6_C                IIO_ICRB0_C                       *
+ *           IIO_ICRB6_D                IIO_ICRB0_D                       *
+ *           IIO_ICRB6_E                IIO_ICRB0_E                       *
+ *           IIO_ICRB7_A                IIO_ICRB0_A                       *
+ *           IIO_ICRB7_B                IIO_ICRB0_B                       *
+ *           IIO_ICRB7_C                IIO_ICRB0_C                       *
+ *           IIO_ICRB7_D                IIO_ICRB0_D                       *
+ *           IIO_ICRB7_E                IIO_ICRB0_E                       *
+ *           IIO_ICRB8_A                IIO_ICRB0_A                       *
+ *           IIO_ICRB8_B                IIO_ICRB0_B                       *
+ *           IIO_ICRB8_C                IIO_ICRB0_C                       *
+ *           IIO_ICRB8_D                IIO_ICRB0_D                       *
+ *           IIO_ICRB8_E                IIO_ICRB0_E                       *
+ *           IIO_ICRB9_A                IIO_ICRB0_A                       *
+ *           IIO_ICRB9_B                IIO_ICRB0_B                       *
+ *           IIO_ICRB9_C                IIO_ICRB0_C                       *
+ *           IIO_ICRB9_D                IIO_ICRB0_D                       *
+ *           IIO_ICRB9_E                IIO_ICRB0_E                       *
+ *           IIO_ICRBA_A                IIO_ICRB0_A                       *
+ *           IIO_ICRBA_B                IIO_ICRB0_B                       *
+ *           IIO_ICRBA_C                IIO_ICRB0_C                       *
+ *           IIO_ICRBA_D                IIO_ICRB0_D                       *
+ *           IIO_ICRBA_E                IIO_ICRB0_E                       *
+ *           IIO_ICRBB_A                IIO_ICRB0_A                       *
+ *           IIO_ICRBB_B                IIO_ICRB0_B                       *
+ *           IIO_ICRBB_C                IIO_ICRB0_C                       *
+ *           IIO_ICRBB_D                IIO_ICRB0_D                       *
+ *           IIO_ICRBB_E                IIO_ICRB0_E                       *
+ *           IIO_ICRBC_A                IIO_ICRB0_A                       *
+ *           IIO_ICRBC_B                IIO_ICRB0_B                       *
+ *           IIO_ICRBC_C                IIO_ICRB0_C                       *
+ *           IIO_ICRBC_D                IIO_ICRB0_D                       *
+ *           IIO_ICRBC_E                IIO_ICRB0_E                       *
+ *           IIO_ICRBD_A                IIO_ICRB0_A                       *
+ *           IIO_ICRBD_B                IIO_ICRB0_B                       *
+ *           IIO_ICRBD_C                IIO_ICRB0_C                       *
+ *           IIO_ICRBD_D                IIO_ICRB0_D                       *
+ *           IIO_ICRBD_E                IIO_ICRB0_E                       *
+ *           IIO_ICRBE_A                IIO_ICRB0_A                       *
+ *           IIO_ICRBE_B                IIO_ICRB0_B                       *
+ *           IIO_ICRBE_C                IIO_ICRB0_C                       *
+ *           IIO_ICRBE_D                IIO_ICRB0_D                       *
+ *           IIO_ICRBE_E                IIO_ICRB0_E                       *
+ *                                                                        *
+ **************************************************************************/
+
+
+/*
+ * Slightly friendlier names for some common registers.
+ */
+#define IIO_WIDGET              IIO_WID      /* Widget identification */
+#define IIO_WIDGET_STAT         IIO_WSTAT    /* Widget status register */
+#define IIO_WIDGET_CTRL         IIO_WCR      /* Widget control register */
+#define IIO_PROTECT             IIO_ILAPR    /* IO interface protection */
+#define IIO_PROTECT_OVRRD       IIO_ILAPO    /* IO protect override */
+#define IIO_OUTWIDGET_ACCESS    IIO_IOWA     /* Outbound widget access */
+#define IIO_INWIDGET_ACCESS     IIO_IIWA     /* Inbound widget access */
+#define IIO_INDEV_ERR_MASK      IIO_IIDEM    /* Inbound device error mask */
+#define IIO_LLP_CSR             IIO_ILCSR    /* LLP control and status */
+#define IIO_LLP_LOG             IIO_ILLR     /* LLP log */
+#define IIO_XTALKCC_TOUT        IIO_IXCC     /* Xtalk credit count timeout*/
+#define IIO_XTALKTT_TOUT        IIO_IXTT     /* Xtalk tail timeout */
+#define IIO_IO_ERR_CLR          IIO_IECLR    /* IO error clear */
+#define IIO_IGFX_0 		IIO_IGFX0
+#define IIO_IGFX_1 		IIO_IGFX1
+#define IIO_IBCT_0		IIO_IBCT0
+#define IIO_IBCT_1		IIO_IBCT1
+#define IIO_IBLS_0		IIO_IBLS0
+#define IIO_IBLS_1		IIO_IBLS1
+#define IIO_IBSA_0		IIO_IBSA0
+#define IIO_IBSA_1		IIO_IBSA1
+#define IIO_IBDA_0		IIO_IBDA0
+#define IIO_IBDA_1		IIO_IBDA1
+#define IIO_IBNA_0		IIO_IBNA0
+#define IIO_IBNA_1		IIO_IBNA1
+#define IIO_IBIA_0		IIO_IBIA0
+#define IIO_IBIA_1		IIO_IBIA1
+#define IIO_IOPRB_0		IIO_IPRB0
+
+#define IIO_PRTE_A(_x)		(IIO_IPRTE0_A + (8 * (_x)))
+#define IIO_PRTE_B(_x)		(IIO_IPRTE0_B + (8 * (_x)))
+#define IIO_NUM_PRTES		8	/* Total number of PRB table entries */
+#define IIO_WIDPRTE_A(x)	IIO_PRTE_A(((x) - 8)) /* widget ID to its PRTE num */
+#define IIO_WIDPRTE_B(x)	IIO_PRTE_B(((x) - 8)) /* widget ID to its PRTE num */
+
+#define IIO_NUM_IPRBS 		(9) 
+
+#define IIO_LLP_CSR_IS_UP               0x00002000
+#define IIO_LLP_CSR_LLP_STAT_MASK       0x00003000
+#define IIO_LLP_CSR_LLP_STAT_SHFT       12
+
+#define IIO_LLP_CB_MAX  0xffff	/* in ILLR CB_CNT, Max Check Bit errors */
+#define IIO_LLP_SN_MAX  0xffff	/* in ILLR SN_CNT, Max Sequence Number errors */
+
+/* key to IIO_PROTECT_OVRRD */
+#define IIO_PROTECT_OVRRD_KEY   0x53474972756c6573ull   /* "SGIrules" */
+
+/* BTE register names */
+#define IIO_BTE_STAT_0          IIO_IBLS_0   /* Also BTE length/status 0 */
+#define IIO_BTE_SRC_0           IIO_IBSA_0   /* Also BTE source address  0 */
+#define IIO_BTE_DEST_0          IIO_IBDA_0   /* Also BTE dest. address 0 */
+#define IIO_BTE_CTRL_0          IIO_IBCT_0   /* Also BTE control/terminate 0 */
+#define IIO_BTE_NOTIFY_0        IIO_IBNA_0   /* Also BTE notification 0 */
+#define IIO_BTE_INT_0           IIO_IBIA_0   /* Also BTE interrupt 0 */
+#define IIO_BTE_OFF_0           0            /* Base offset from BTE 0 regs. */
+#define IIO_BTE_OFF_1   	(IIO_IBLS_1 - IIO_IBLS_0) /* Offset from base to BTE 1 */
+
+/* BTE register offsets from base */
+#define BTEOFF_STAT             0
+#define BTEOFF_SRC              (IIO_BTE_SRC_0 - IIO_BTE_STAT_0)
+#define BTEOFF_DEST             (IIO_BTE_DEST_0 - IIO_BTE_STAT_0)
+#define BTEOFF_CTRL             (IIO_BTE_CTRL_0 - IIO_BTE_STAT_0)
+#define BTEOFF_NOTIFY           (IIO_BTE_NOTIFY_0 - IIO_BTE_STAT_0)
+#define BTEOFF_INT              (IIO_BTE_INT_0 - IIO_BTE_STAT_0)
+
+
+/* names used in shub diags */
+#define IIO_BASE_BTE0   IIO_IBLS_0		
+#define IIO_BASE_BTE1   IIO_IBLS_1		
+
+/*
+ * Macro which takes the widget number, and returns the
+ * IO PRB address of that widget.
+ * value _x is expected to be a widget number in the range
+ * 0, 8 - 0xF
+ */
+#define IIO_IOPRB(_x)   (IIO_IOPRB_0 + ( ( (_x) < HUB_WIDGET_ID_MIN ? \
+                        (_x) : \
+                        (_x) - (HUB_WIDGET_ID_MIN-1)) << 3) )
+
+
+/* GFX Flow Control Node/Widget Register */
+#define IIO_IGFX_W_NUM_BITS	4	/* size of widget num field */
+#define IIO_IGFX_W_NUM_MASK	((1<<IIO_IGFX_W_NUM_BITS)-1)
+#define IIO_IGFX_W_NUM_SHIFT	0
+#define IIO_IGFX_PI_NUM_BITS	1	/* size of PI num field */
+#define IIO_IGFX_PI_NUM_MASK	((1<<IIO_IGFX_PI_NUM_BITS)-1)
+#define IIO_IGFX_PI_NUM_SHIFT	4
+#define IIO_IGFX_N_NUM_BITS	8	/* size of node num field */
+#define IIO_IGFX_N_NUM_MASK	((1<<IIO_IGFX_N_NUM_BITS)-1)
+#define IIO_IGFX_N_NUM_SHIFT	5
+#define IIO_IGFX_P_NUM_BITS	1	/* size of processor num field */
+#define IIO_IGFX_P_NUM_MASK	((1<<IIO_IGFX_P_NUM_BITS)-1)
+#define IIO_IGFX_P_NUM_SHIFT	16
+#define IIO_IGFX_INIT(widget, pi, node, cpu)				(\
+	(((widget) & IIO_IGFX_W_NUM_MASK) << IIO_IGFX_W_NUM_SHIFT) |	 \
+	(((pi)     & IIO_IGFX_PI_NUM_MASK)<< IIO_IGFX_PI_NUM_SHIFT)|	 \
+	(((node)   & IIO_IGFX_N_NUM_MASK) << IIO_IGFX_N_NUM_SHIFT) |	 \
+	(((cpu)    & IIO_IGFX_P_NUM_MASK) << IIO_IGFX_P_NUM_SHIFT))
+
+
+/* Scratch registers (all bits available) */
+#define IIO_SCRATCH_REG0        IIO_ISCR0
+#define IIO_SCRATCH_REG1        IIO_ISCR1
+#define IIO_SCRATCH_MASK        0xffffffffffffffffUL
+
+#define IIO_SCRATCH_BIT0_0      0x0000000000000001UL
+#define IIO_SCRATCH_BIT0_1      0x0000000000000002UL
+#define IIO_SCRATCH_BIT0_2      0x0000000000000004UL
+#define IIO_SCRATCH_BIT0_3      0x0000000000000008UL
+#define IIO_SCRATCH_BIT0_4      0x0000000000000010UL
+#define IIO_SCRATCH_BIT0_5      0x0000000000000020UL
+#define IIO_SCRATCH_BIT0_6      0x0000000000000040UL
+#define IIO_SCRATCH_BIT0_7      0x0000000000000080UL
+#define IIO_SCRATCH_BIT0_8      0x0000000000000100UL
+#define IIO_SCRATCH_BIT0_9      0x0000000000000200UL
+#define IIO_SCRATCH_BIT0_A      0x0000000000000400UL
+
+#define IIO_SCRATCH_BIT1_0      0x0000000000000001UL
+#define IIO_SCRATCH_BIT1_1      0x0000000000000002UL
+/* IO Translation Table Entries */
+#define IIO_NUM_ITTES   7               /* ITTEs numbered 0..6 */
+                                        /* Hw manuals number them 1..7! */
+/*
+ * IIO_IMEM Register fields.
+ */
+#define IIO_IMEM_W0ESD  0x1UL             /* Widget 0 shut down due to error */
+#define IIO_IMEM_B0ESD  (1UL << 4)        /* BTE 0 shut down due to error */
+#define IIO_IMEM_B1ESD  (1UL << 8)        /* BTE 1 Shut down due to error */
+
+/*
+ * As a permanent workaround for a bug in the PI side of the shub, we've
+ * redefined big window 7 as small window 0.
+ XXX does this still apply for SN1??
+ */
+#define HUB_NUM_BIG_WINDOW      (IIO_NUM_ITTES - 1)
+
+/*
+ * Use the top big window as a surrogate for the first small window
+ */
+#define SWIN0_BIGWIN            HUB_NUM_BIG_WINDOW
+
+#define ILCSR_WARM_RESET        0x100
+
+/*
+ * CRB manipulation macros
+ *      The CRB macros are slightly complicated, since there are up to
+ *      four registers associated with each CRB entry.
+ */
+#define IIO_NUM_CRBS            15      /* Number of CRBs */
+#define IIO_NUM_PC_CRBS         4       /* Number of partial cache CRBs */
+#define IIO_ICRB_OFFSET         8
+#define IIO_ICRB_0              IIO_ICRB0_A
+#define IIO_ICRB_ADDR_SHFT	2	/* Shift to get proper address */
+/* XXX - This is now tuneable:
+        #define IIO_FIRST_PC_ENTRY 12
+ */
+
+#define IIO_ICRB_A(_x)  ((u64)(IIO_ICRB_0 + (6 * IIO_ICRB_OFFSET * (_x))))
+#define IIO_ICRB_B(_x)  ((u64)((char *)IIO_ICRB_A(_x) + 1*IIO_ICRB_OFFSET))
+#define IIO_ICRB_C(_x)  ((u64)((char *)IIO_ICRB_A(_x) + 2*IIO_ICRB_OFFSET))
+#define IIO_ICRB_D(_x)  ((u64)((char *)IIO_ICRB_A(_x) + 3*IIO_ICRB_OFFSET))
+#define IIO_ICRB_E(_x)  ((u64)((char *)IIO_ICRB_A(_x) + 4*IIO_ICRB_OFFSET))
+
+#define TNUM_TO_WIDGET_DEV(_tnum)	(_tnum & 0x7)
+
+/*
+ * values for "ecode" field
+ */
+#define IIO_ICRB_ECODE_DERR     0       /* Directory error due to IIO access */
+#define IIO_ICRB_ECODE_PERR     1       /* Poison error on IO access */
+#define IIO_ICRB_ECODE_WERR     2       /* Write error by IIO access
+                                         * e.g. WINV to a Read only line. */
+#define IIO_ICRB_ECODE_AERR     3       /* Access error caused by IIO access */
+#define IIO_ICRB_ECODE_PWERR    4       /* Error on partial write       */
+#define IIO_ICRB_ECODE_PRERR    5       /* Error on partial read        */
+#define IIO_ICRB_ECODE_TOUT     6       /* CRB timeout before deallocating */
+#define IIO_ICRB_ECODE_XTERR    7       /* Incoming xtalk pkt had error bit */
+
+/*
+ * Values for field imsgtype
+ */
+#define IIO_ICRB_IMSGT_XTALK    0       /* Incoming Meessage from Xtalk */
+#define IIO_ICRB_IMSGT_BTE      1       /* Incoming message from BTE    */
+#define IIO_ICRB_IMSGT_SN1NET   2       /* Incoming message from SN1 net */
+#define IIO_ICRB_IMSGT_CRB      3       /* Incoming message from CRB ???  */
+
+/*
+ * values for field initiator.
+ */
+#define IIO_ICRB_INIT_XTALK     0       /* Message originated in xtalk  */
+#define IIO_ICRB_INIT_BTE0      0x1     /* Message originated in BTE 0  */
+#define IIO_ICRB_INIT_SN1NET    0x2     /* Message originated in SN1net */
+#define IIO_ICRB_INIT_CRB       0x3     /* Message originated in CRB ?  */
+#define IIO_ICRB_INIT_BTE1      0x5     /* MEssage originated in BTE 1  */
+
+/*
+ * Number of credits Hub widget has while sending req/response to
+ * xbow.
+ * Value of 3 is required by Xbow 1.1
+ * We may be able to increase this to 4 with Xbow 1.2.
+ */
+#define       HUBII_XBOW_CREDIT       3
+#define       HUBII_XBOW_REV2_CREDIT  4
+
+/*
+ * Number of credits that xtalk devices should use when communicating
+ * with a SHub (depth of SHub's queue).
+ */
+#define HUB_CREDIT 4
+
+/*
+ * Some IIO_PRB fields
+ */
+#define IIO_PRB_MULTI_ERR	(1LL << 63)
+#define IIO_PRB_SPUR_RD		(1LL << 51)
+#define IIO_PRB_SPUR_WR		(1LL << 50)
+#define IIO_PRB_RD_TO		(1LL << 49)
+#define IIO_PRB_ERROR		(1LL << 48)
+
+/*************************************************************************
+
+ Some of the IIO field masks and shifts are defined here.
+ This is in order to maintain compatibility in SN0 and SN1 code
+ 
+**************************************************************************/
+
+/*
+ * ICMR register fields
+ * (Note: the IIO_ICMR_P_CNT and IIO_ICMR_PC_VLD from Hub are not
+ * present in SHub)
+ */
+
+#define IIO_ICMR_CRB_VLD_SHFT   20
+#define IIO_ICMR_CRB_VLD_MASK   (0x7fffUL << IIO_ICMR_CRB_VLD_SHFT)
+
+#define IIO_ICMR_FC_CNT_SHFT    16
+#define IIO_ICMR_FC_CNT_MASK    (0xf << IIO_ICMR_FC_CNT_SHFT)
+
+#define IIO_ICMR_C_CNT_SHFT     4
+#define IIO_ICMR_C_CNT_MASK     (0xf << IIO_ICMR_C_CNT_SHFT)
+
+#define IIO_ICMR_PRECISE        (1UL << 52)
+#define IIO_ICMR_CLR_RPPD       (1UL << 13)
+#define IIO_ICMR_CLR_RQPD       (1UL << 12)
+
+/*
+ * IIO PIO Deallocation register field masks : (IIO_IPDR)
+ XXX present but not needed in bedrock?  See the manual.
+ */
+#define IIO_IPDR_PND    (1 << 4)
+
+/*
+ * IIO CRB deallocation register field masks: (IIO_ICDR)
+ */
+#define IIO_ICDR_PND    (1 << 4)
+
+/* 
+ * IO BTE Length/Status (IIO_IBLS) register bit field definitions
+ */
+#define IBLS_BUSY		(0x1UL << 20)
+#define IBLS_ERROR_SHFT		16
+#define IBLS_ERROR		(0x1UL << IBLS_ERROR_SHFT)
+#define IBLS_LENGTH_MASK	0xffff
+
+/*
+ * IO BTE Control/Terminate register (IBCT) register bit field definitions
+ */
+#define IBCT_POISON		(0x1UL << 8)
+#define IBCT_NOTIFY		(0x1UL << 4)
+#define IBCT_ZFIL_MODE		(0x1UL << 0)
+
+/*
+ * IIO Incoming Error Packet Header (IIO_IIEPH1/IIO_IIEPH2)
+ */
+#define IIEPH1_VALID		(1UL << 44)
+#define IIEPH1_OVERRUN		(1UL << 40)
+#define IIEPH1_ERR_TYPE_SHFT	32
+#define IIEPH1_ERR_TYPE_MASK	0xf
+#define IIEPH1_SOURCE_SHFT	20
+#define IIEPH1_SOURCE_MASK	11
+#define IIEPH1_SUPPL_SHFT	8
+#define IIEPH1_SUPPL_MASK	11
+#define IIEPH1_CMD_SHFT		0
+#define IIEPH1_CMD_MASK		7
+
+#define IIEPH2_TAIL		(1UL << 40)
+#define IIEPH2_ADDRESS_SHFT	0
+#define IIEPH2_ADDRESS_MASK	38
+
+#define IIEPH1_ERR_SHORT_REQ	2
+#define IIEPH1_ERR_SHORT_REPLY	3
+#define IIEPH1_ERR_LONG_REQ	4
+#define IIEPH1_ERR_LONG_REPLY	5
+
+/*
+ * IO Error Clear register bit field definitions
+ */
+#define IECLR_PI1_FWD_INT	(1UL << 31)  /* clear PI1_FORWARD_INT in iidsr */
+#define IECLR_PI0_FWD_INT	(1UL << 30)  /* clear PI0_FORWARD_INT in iidsr */
+#define IECLR_SPUR_RD_HDR	(1UL << 29)  /* clear valid bit in ixss reg */
+#define IECLR_BTE1		(1UL << 18)  /* clear bte error 1 */
+#define IECLR_BTE0		(1UL << 17)  /* clear bte error 0 */
+#define IECLR_CRAZY		(1UL << 16)  /* clear crazy bit in wstat reg */
+#define IECLR_PRB_F		(1UL << 15)  /* clear err bit in PRB_F reg */
+#define IECLR_PRB_E		(1UL << 14)  /* clear err bit in PRB_E reg */
+#define IECLR_PRB_D		(1UL << 13)  /* clear err bit in PRB_D reg */
+#define IECLR_PRB_C		(1UL << 12)  /* clear err bit in PRB_C reg */
+#define IECLR_PRB_B		(1UL << 11)  /* clear err bit in PRB_B reg */
+#define IECLR_PRB_A		(1UL << 10)  /* clear err bit in PRB_A reg */
+#define IECLR_PRB_9		(1UL << 9)   /* clear err bit in PRB_9 reg */
+#define IECLR_PRB_8		(1UL << 8)   /* clear err bit in PRB_8 reg */
+#define IECLR_PRB_0		(1UL << 0)   /* clear err bit in PRB_0 reg */
+
+/*
+ * IIO CRB control register Fields: IIO_ICCR 
+ */
+#define	IIO_ICCR_PENDING	(0x10000)
+#define	IIO_ICCR_CMD_MASK	(0xFF)
+#define	IIO_ICCR_CMD_SHFT	(7)
+#define	IIO_ICCR_CMD_NOP	(0x0)	/* No Op */
+#define	IIO_ICCR_CMD_WAKE	(0x100) /* Reactivate CRB entry and process */
+#define	IIO_ICCR_CMD_TIMEOUT	(0x200)	/* Make CRB timeout & mark invalid */
+#define	IIO_ICCR_CMD_EJECT	(0x400)	/* Contents of entry written to memory 
+					 * via a WB
+					 */
+#define	IIO_ICCR_CMD_FLUSH	(0x800)
+
+/*
+ *
+ * CRB Register description.
+ *
+ * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING
+ * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING
+ * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING
+ * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING
+ * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING
+ *
+ * Many of the fields in CRB are status bits used by hardware
+ * for implementation of the protocol. It's very dangerous to
+ * mess around with the CRB registers.
+ *
+ * It's OK to read the CRB registers and try to make sense out of the
+ * fields in CRB.
+ *
+ * Updating CRB requires all activities in Hub IIO to be quiesced.
+ * otherwise, a write to CRB could corrupt other CRB entries.
+ * CRBs are here only as a back door peek to shub IIO's status.
+ * Quiescing implies  no dmas no PIOs
+ * either directly from the cpu or from sn0net.
+ * this is not something that can be done easily. So, AVOID updating
+ * CRBs.
+ */
+
+/*
+ * Easy access macros for CRBs, all 5 registers (A-E)
+ */
+typedef ii_icrb0_a_u_t icrba_t;
+#define a_sidn          ii_icrb0_a_fld_s.ia_sidn
+#define a_tnum          ii_icrb0_a_fld_s.ia_tnum
+#define a_addr          ii_icrb0_a_fld_s.ia_addr
+#define a_valid         ii_icrb0_a_fld_s.ia_vld
+#define a_iow           ii_icrb0_a_fld_s.ia_iow
+#define a_regvalue	ii_icrb0_a_regval
+
+typedef ii_icrb0_b_u_t icrbb_t;
+#define b_use_old       ii_icrb0_b_fld_s.ib_use_old
+#define b_imsgtype      ii_icrb0_b_fld_s.ib_imsgtype
+#define b_imsg          ii_icrb0_b_fld_s.ib_imsg
+#define b_initiator     ii_icrb0_b_fld_s.ib_init
+#define b_exc           ii_icrb0_b_fld_s.ib_exc
+#define b_ackcnt        ii_icrb0_b_fld_s.ib_ack_cnt
+#define b_resp          ii_icrb0_b_fld_s.ib_resp
+#define b_ack           ii_icrb0_b_fld_s.ib_ack
+#define b_hold          ii_icrb0_b_fld_s.ib_hold
+#define b_wb            ii_icrb0_b_fld_s.ib_wb
+#define b_intvn         ii_icrb0_b_fld_s.ib_intvn
+#define b_stall_ib      ii_icrb0_b_fld_s.ib_stall_ib
+#define b_stall_int     ii_icrb0_b_fld_s.ib_stall__intr
+#define b_stall_bte_0   ii_icrb0_b_fld_s.ib_stall__bte_0
+#define b_stall_bte_1   ii_icrb0_b_fld_s.ib_stall__bte_1
+#define b_error         ii_icrb0_b_fld_s.ib_error
+#define b_ecode         ii_icrb0_b_fld_s.ib_errcode
+#define b_lnetuce       ii_icrb0_b_fld_s.ib_ln_uce
+#define b_mark          ii_icrb0_b_fld_s.ib_mark
+#define b_xerr          ii_icrb0_b_fld_s.ib_xt_err
+#define b_regvalue	ii_icrb0_b_regval
+
+typedef ii_icrb0_c_u_t icrbc_t;
+#define c_suppl         ii_icrb0_c_fld_s.ic_suppl
+#define c_barrop        ii_icrb0_c_fld_s.ic_bo
+#define c_doresp        ii_icrb0_c_fld_s.ic_resprqd
+#define c_gbr           ii_icrb0_c_fld_s.ic_gbr
+#define c_btenum        ii_icrb0_c_fld_s.ic_bte_num
+#define c_cohtrans      ii_icrb0_c_fld_s.ic_ct
+#define c_xtsize        ii_icrb0_c_fld_s.ic_size
+#define c_source        ii_icrb0_c_fld_s.ic_source
+#define c_regvalue	ii_icrb0_c_regval
+
+
+typedef ii_icrb0_d_u_t icrbd_t;
+#define d_sleep         ii_icrb0_d_fld_s.id_sleep
+#define d_pricnt        ii_icrb0_d_fld_s.id_pr_cnt
+#define d_pripsc        ii_icrb0_d_fld_s.id_pr_psc
+#define d_bteop         ii_icrb0_d_fld_s.id_bte_op
+#define d_bteaddr       ii_icrb0_d_fld_s.id_pa_be /* ic_pa_be fld has 2 names*/
+#define d_benable       ii_icrb0_d_fld_s.id_pa_be /* ic_pa_be fld has 2 names*/
+#define d_regvalue	ii_icrb0_d_regval
+
+typedef ii_icrb0_e_u_t icrbe_t;
+#define icrbe_ctxtvld   ii_icrb0_e_fld_s.ie_cvld
+#define icrbe_toutvld   ii_icrb0_e_fld_s.ie_tvld
+#define icrbe_context   ii_icrb0_e_fld_s.ie_context
+#define icrbe_timeout   ii_icrb0_e_fld_s.ie_timeout
+#define e_regvalue	ii_icrb0_e_regval
+
+
+/* Number of widgets supported by shub */
+#define HUB_NUM_WIDGET          9
+#define HUB_WIDGET_ID_MIN       0x8
+#define HUB_WIDGET_ID_MAX       0xf
+
+#define HUB_WIDGET_PART_NUM     0xc120
+#define MAX_HUBS_PER_XBOW       2
+
+/* A few more #defines for backwards compatibility */
+#define iprb_t          ii_iprb0_u_t
+#define iprb_regval     ii_iprb0_regval
+#define iprb_mult_err	ii_iprb0_fld_s.i_mult_err
+#define iprb_spur_rd	ii_iprb0_fld_s.i_spur_rd
+#define iprb_spur_wr	ii_iprb0_fld_s.i_spur_wr
+#define iprb_rd_to	ii_iprb0_fld_s.i_rd_to
+#define iprb_ovflow     ii_iprb0_fld_s.i_of_cnt
+#define iprb_error      ii_iprb0_fld_s.i_error
+#define iprb_ff         ii_iprb0_fld_s.i_f
+#define iprb_mode       ii_iprb0_fld_s.i_m
+#define iprb_bnakctr    ii_iprb0_fld_s.i_nb
+#define iprb_anakctr    ii_iprb0_fld_s.i_na
+#define iprb_xtalkctr   ii_iprb0_fld_s.i_c
+
+#define LNK_STAT_WORKING        0x2		/* LLP is working */
+
+#define IIO_WSTAT_ECRAZY        (1ULL << 32)    /* Hub gone crazy */
+#define IIO_WSTAT_TXRETRY       (1ULL << 9)     /* Hub Tx Retry timeout */
+#define IIO_WSTAT_TXRETRY_MASK  (0x7F)   /* should be 0xFF?? */
+#define IIO_WSTAT_TXRETRY_SHFT  (16)
+#define IIO_WSTAT_TXRETRY_CNT(w)        (((w) >> IIO_WSTAT_TXRETRY_SHFT) & \
+                                          IIO_WSTAT_TXRETRY_MASK)
+
+/* Number of II perf. counters we can multiplex at once */
+
+#define IO_PERF_SETS	32
+
+/* Bit for the widget in inbound access register */
+#define IIO_IIWA_WIDGET(_w)     ((uint64_t)(1ULL << _w))
+/* Bit for the widget in outbound access register */
+#define IIO_IOWA_WIDGET(_w)     ((uint64_t)(1ULL << _w))
+
+/* NOTE: The following define assumes that we are going to get
+ * widget numbers from 8 thru F and the device numbers within
+ * widget from 0 thru 7.
+ */
+#define IIO_IIDEM_WIDGETDEV_MASK(w, d)  ((uint64_t)(1ULL << (8 * ((w) - 8) + (d))))
+
+/* IO Interrupt Destination Register */
+#define IIO_IIDSR_SENT_SHIFT    28
+#define IIO_IIDSR_SENT_MASK     0x30000000
+#define IIO_IIDSR_ENB_SHIFT     24
+#define IIO_IIDSR_ENB_MASK      0x01000000
+#define IIO_IIDSR_NODE_SHIFT    9
+#define IIO_IIDSR_NODE_MASK     0x000ff700
+#define IIO_IIDSR_PI_ID_SHIFT   8
+#define IIO_IIDSR_PI_ID_MASK    0x00000100
+#define IIO_IIDSR_LVL_SHIFT     0
+#define IIO_IIDSR_LVL_MASK      0x000000ff
+
+/* Xtalk timeout threshhold register (IIO_IXTT) */
+#define IXTT_RRSP_TO_SHFT	55	   /* read response timeout */
+#define IXTT_RRSP_TO_MASK	(0x1FULL << IXTT_RRSP_TO_SHFT)
+#define IXTT_RRSP_PS_SHFT	32	   /* read responsed TO prescalar */
+#define IXTT_RRSP_PS_MASK	(0x7FFFFFULL << IXTT_RRSP_PS_SHFT)
+#define IXTT_TAIL_TO_SHFT	0	   /* tail timeout counter threshold */
+#define IXTT_TAIL_TO_MASK	(0x3FFFFFFULL << IXTT_TAIL_TO_SHFT)
+
+/*
+ * The IO LLP control status register and widget control register
+ */
+
+typedef union hubii_wcr_u {
+        uint64_t      wcr_reg_value;
+        struct {
+	  uint64_t	wcr_widget_id:   4,     /* LLP crossbar credit */
+			wcr_tag_mode:	 1,	/* Tag mode */
+			wcr_rsvd1:	 8,	/* Reserved */
+			wcr_xbar_crd:	 3,	/* LLP crossbar credit */
+			wcr_f_bad_pkt:	 1,	/* Force bad llp pkt enable */
+			wcr_dir_con:	 1,	/* widget direct connect */
+			wcr_e_thresh:	 5,	/* elasticity threshold */
+			wcr_rsvd:	41;	/* unused */
+        } wcr_fields_s;
+} hubii_wcr_t;
+
+#define iwcr_dir_con    wcr_fields_s.wcr_dir_con
+
+/* The structures below are defined to extract and modify the ii
+performance registers */
+
+/* io_perf_sel allows the caller to specify what tests will be
+   performed */
+
+typedef union io_perf_sel {
+        uint64_t perf_sel_reg;
+        struct {
+               uint64_t	perf_ippr0 :  4,
+				perf_ippr1 :  4,
+				perf_icct  :  8,
+				perf_rsvd  : 48;
+        } perf_sel_bits;
+} io_perf_sel_t;
+
+/* io_perf_cnt is to extract the count from the shub registers. Due to
+   hardware problems there is only one counter, not two. */
+
+typedef union io_perf_cnt {
+        uint64_t      perf_cnt;
+        struct {
+               uint64_t	perf_cnt   : 20,
+				perf_rsvd2 : 12,
+				perf_rsvd1 : 32;
+        } perf_cnt_bits;
+
+} io_perf_cnt_t;
+
+typedef union iprte_a {
+	uint64_t	entry;
+	struct {
+		uint64_t	i_rsvd_1                  :	 3;
+		uint64_t	i_addr			  :	38;
+		uint64_t	i_init			  :	 3;
+		uint64_t	i_source		  :	 8;
+		uint64_t	i_rsvd			  :	 2;
+		uint64_t	i_widget		  :	 4;
+		uint64_t	i_to_cnt		  :	 5;
+		uint64_t       i_vld                     :      1;
+	} iprte_fields;
+} iprte_a_t;
+
+#endif /* _ASM_IA64_SN_SHUBIO_H */
+
diff -Nru a/include/asm-ia64/sn/sn_cpuid.h b/include/asm-ia64/sn/sn_cpuid.h
--- a/include/asm-ia64/sn/sn_cpuid.h	2005-03-01 23:38:52 -08:00
+++ b/include/asm-ia64/sn/sn_cpuid.h	2005-03-01 23:38:52 -08:00
@@ -13,6 +13,7 @@
 
 #include <linux/config.h>
 #include <linux/smp.h>
+#include <asm/sn/addrs.h>
 #include <asm/sn/pda.h>
 #include <asm/intrinsics.h>
 
@@ -81,16 +82,13 @@
  */
 
 #ifndef CONFIG_SMP
-#define cpu_logical_id(cpu)			0
 #define cpu_physical_id(cpuid)			((ia64_getreg(_IA64_REG_CR_LID) >> 16) & 0xffff)
 #endif
 
 
-#define get_node_number(addr)			(((unsigned long)(addr)>>38) & 0x7ff)
+#define get_node_number(addr)			NASID_GET(addr)
 
 /*
- * NOTE: id & eid refer to Intel's definitions of the LID register
- * 
  * NOTE: on non-MP systems, only cpuid 0 exists
  */
 
diff -Nru a/include/asm-ia64/sn/sn_sal.h b/include/asm-ia64/sn/sn_sal.h
--- a/include/asm-ia64/sn/sn_sal.h	2005-03-01 23:39:18 -08:00
+++ b/include/asm-ia64/sn/sn_sal.h	2005-03-01 23:39:18 -08:00
@@ -32,9 +32,10 @@
 #define  SN_SAL_NO_FAULT_ZONE_VIRTUAL		   0x02000010
 #define  SN_SAL_NO_FAULT_ZONE_PHYSICAL		   0x02000011
 #define  SN_SAL_PRINT_ERROR			   0x02000012
-#define  SN_SAL_GET_SAPIC_INFO                     0x02009999	//ZZZZ fix
 #define  SN_SAL_SET_ERROR_HANDLING_FEATURES	   0x0200001a	// reentrant
 #define  SN_SAL_GET_FIT_COMPT			   0x0200001b	// reentrant
+#define  SN_SAL_GET_HUB_INFO                       0x0200001c
+#define  SN_SAL_GET_SAPIC_INFO                     0x0200001d
 #define  SN_SAL_CONSOLE_PUTC                       0x02000021
 #define  SN_SAL_CONSOLE_GETC                       0x02000022
 #define  SN_SAL_CONSOLE_PUTS                       0x02000023
@@ -203,7 +204,7 @@
 	return ret_stuff.v0;
 }
 
-static inline u64
+static inline char *
 ia64_sn_get_klconfig_addr(nasid_t nasid)
 {
 	struct ia64_sal_retval ret_stuff;
@@ -223,7 +224,7 @@
 	if (ret_stuff.status != 0) {
 		panic("ia64_sn_get_klconfig_addr: Returned error %lx\n", ret_stuff.status);
 	}
-	return(ret_stuff.v0);
+	return ret_stuff.v0 ? __va(ret_stuff.v0) : NULL;
 }
 
 /*
@@ -474,6 +475,52 @@
 	return isrv.v0;
 }
 
+/**
+ * ia64_sn_probe_mem - read from memory safely
+ * @addr: address to probe
+ * @size: number bytes to read (1,2,4,8)
+ * @data_ptr: address to store value read by probe (-1 returned if probe fails)
+ *
+ * Call into the SAL to do a memory read.  If the read generates a machine
+ * check, this routine will recover gracefully and return -1 to the caller.
+ * @addr is usually a kernel virtual address in uncached space (i.e. the
+ * address starts with 0xc), but if called in physical mode, @addr should
+ * be a physical address.
+ *
+ * Return values:
+ *  0 - probe successful
+ *  1 - probe failed (generated MCA)
+ *  2 - Bad arg
+ * <0 - PAL error
+ */
+static inline u64
+ia64_sn_probe_mem(long addr, long size, void *data_ptr)
+{
+	struct ia64_sal_retval isrv;
+
+	SAL_CALL(isrv, SN_SAL_PROBE, addr, size, 0, 0, 0, 0, 0);
+
+	if (data_ptr) {
+		switch (size) {
+		case 1:
+			*((u8*)data_ptr) = (u8)isrv.v0;
+			break;
+		case 2:
+			*((u16*)data_ptr) = (u16)isrv.v0;
+			break;
+		case 4:
+			*((u32*)data_ptr) = (u32)isrv.v0;
+			break;
+		case 8:
+			*((u64*)data_ptr) = (u64)isrv.v0;
+			break;
+		default:
+			isrv.status = 2;
+		}
+	}
+	return isrv.status;
+}
+
 /*
  * Retrieve the system serial number as an ASCII string.
  */
@@ -847,6 +894,14 @@
 
 /*
  * Returns the nasid, subnode & slice corresponding to a SAPIC ID
+ *
+ *  In:
+ *	arg0 - SN_SAL_GET_SAPIC_INFO
+ *	arg1 - sapicid (lid >> 16) 
+ *  Out:
+ *	v0 - nasid
+ *	v1 - subnode
+ *	v2 - slice
  */
 static inline u64
 ia64_sn_get_sapic_info(int sapicid, int *nasid, int *subnode, int *slice)
@@ -859,7 +914,7 @@
 	ret_stuff.v2 = 0;
 	SAL_CALL_NOLOCK(ret_stuff, SN_SAL_GET_SAPIC_INFO, sapicid, 0, 0, 0, 0, 0, 0);
 
-/***** BEGIN HACK - temp til new proms available ********/
+/***** BEGIN HACK - temp til old proms no longer supported ********/
 	if (ret_stuff.status == SALRET_NOT_IMPLEMENTED) {
 		if (nasid) *nasid = sapicid & 0xfff;
 		if (subnode) *subnode = (sapicid >> 13) & 1;
@@ -876,6 +931,46 @@
 	if (slice) *slice = (int) ret_stuff.v2;
 	return 0;
 }
+ 
+/*
+ * Returns information about the HUB/SHUB.
+ *  In:
+ *	arg0 - SN_SAL_GET_HUB_INFO
+ * 	arg1 - 0 (other values reserved for future use)
+ *  Out:
+ *	v0 - shub type (0=shub1, 1=shub2)
+ *	v1 - masid mask (ex., 0x7ff for 11 bit nasid)
+ *	v2 - bit position of low nasid bit
+ */
+static inline u64
+ia64_sn_get_hub_info(int fc, u64 *arg1, u64 *arg2, u64 *arg3)
+{
+	struct ia64_sal_retval ret_stuff;
+
+	ret_stuff.status = 0;
+	ret_stuff.v0 = 0;
+	ret_stuff.v1 = 0;
+	ret_stuff.v2 = 0;
+	SAL_CALL_NOLOCK(ret_stuff, SN_SAL_GET_HUB_INFO, fc, 0, 0, 0, 0, 0, 0);
+
+/***** BEGIN HACK - temp til old proms no longer supported ********/
+	if (ret_stuff.status == SALRET_NOT_IMPLEMENTED) {
+		if (arg1) *arg1 = 0;
+		if (arg2) *arg2 = 0x7ff;
+		if (arg3) *arg3 = 38;
+		return 0;
+	}
+/***** END HACK *******/
+
+	if (ret_stuff.status < 0)
+		return ret_stuff.status;
+
+	if (arg1) *arg1 = ret_stuff.v0;
+	if (arg2) *arg2 = ret_stuff.v1;
+	if (arg3) *arg3 = ret_stuff.v2;
+	return 0;
+}
+ 
 /*
  * This is the access point to the Altix PROM hardware performance
  * and status monitoring interface. For info on using this, see
diff -Nru a/include/asm-ia64/spinlock.h b/include/asm-ia64/spinlock.h
--- a/include/asm-ia64/spinlock.h	2005-03-01 23:38:52 -08:00
+++ b/include/asm-ia64/spinlock.h	2005-03-01 23:38:52 -08:00
@@ -19,6 +19,9 @@
 
 typedef struct {
 	volatile unsigned int lock;
+#ifdef CONFIG_PREEMPT
+	unsigned int break_lock;
+#endif
 } spinlock_t;
 
 #define SPIN_LOCK_UNLOCKED			(spinlock_t) { 0 }
@@ -116,11 +119,15 @@
 typedef struct {
 	volatile unsigned int read_counter	: 31;
 	volatile unsigned int write_lock	:  1;
+#ifdef CONFIG_PREEMPT
+	unsigned int break_lock;
+#endif
 } rwlock_t;
 #define RW_LOCK_UNLOCKED (rwlock_t) { 0, 0 }
 
 #define rwlock_init(x)		do { *(x) = RW_LOCK_UNLOCKED; } while(0)
-#define rwlock_is_locked(x)	(*(volatile int *) (x) != 0)
+#define read_can_lock(rw)	(*(volatile int *)(rw) >= 0)
+#define write_can_lock(rw)	(*(volatile int *)(rw) == 0)
 
 #define _raw_read_lock(rw)								\
 do {											\
@@ -189,6 +196,8 @@
 })
 
 #endif /* !ASM_SUPPORTED */
+
+#define _raw_read_trylock(lock) generic_raw_read_trylock(lock)
 
 #define _raw_write_unlock(x)								\
 ({											\
diff -Nru a/include/asm-ia64/string.h b/include/asm-ia64/string.h
--- a/include/asm-ia64/string.h	2005-03-01 23:39:10 -08:00
+++ b/include/asm-ia64/string.h	2005-03-01 23:39:10 -08:00
@@ -14,7 +14,6 @@
 #define __HAVE_ARCH_STRLEN	1 /* see arch/ia64/lib/strlen.S */
 #define __HAVE_ARCH_MEMSET	1 /* see arch/ia64/lib/memset.S */
 #define __HAVE_ARCH_MEMCPY	1 /* see arch/ia64/lib/memcpy.S */
-#define __HAVE_ARCH_BCOPY	1 /* see arch/ia64/lib/memcpy.S */
 
 extern __kernel_size_t strlen (const char *);
 extern void *memcpy (void *, const void *, __kernel_size_t);
diff -Nru a/include/asm-ia64/system.h b/include/asm-ia64/system.h
--- a/include/asm-ia64/system.h	2005-03-01 23:38:56 -08:00
+++ b/include/asm-ia64/system.h	2005-03-01 23:38:56 -08:00
@@ -284,6 +284,7 @@
 
 #define ia64_platform_is(x) (strcmp(x, platform_name) == 0)
 
+void cpu_idle_wait(void);
 #endif /* __KERNEL__ */
 
 #endif /* __ASSEMBLY__ */
diff -Nru a/include/asm-ia64/thread_info.h b/include/asm-ia64/thread_info.h
--- a/include/asm-ia64/thread_info.h	2005-03-01 23:39:18 -08:00
+++ b/include/asm-ia64/thread_info.h	2005-03-01 23:39:18 -08:00
@@ -27,6 +27,13 @@
 	mm_segment_t addr_limit;	/* user-level address space limit */
 	__s32 preempt_count;		/* 0=premptable, <0=BUG; will also serve as bh-counter */
 	struct restart_block restart_block;
+	struct {
+		int signo;
+		int code;
+		void __user *addr;
+		unsigned long start_time;
+		pid_t pid;
+	} sigdelayed;			/* Saved information for TIF_SIGDELAYED */
 };
 
 #define THREAD_SIZE			KERNEL_STACK_SIZE
@@ -66,10 +73,9 @@
 #define TIF_NEED_RESCHED	2	/* rescheduling necessary */
 #define TIF_SYSCALL_TRACE	3	/* syscall trace active */
 #define TIF_SYSCALL_AUDIT	4	/* syscall auditing active */
+#define TIF_SIGDELAYED		5	/* signal delayed from MCA/INIT/NMI/PMI context */
 #define TIF_POLLING_NRFLAG	16	/* true if poll_idle() is polling TIF_NEED_RESCHED */
-
-#define TIF_WORK_MASK		0x7	/* like TIF_ALLWORK_BITS but sans TIF_SYSCALL_TRACE */
-#define TIF_ALLWORK_MASK	0x1f	/* bits 0..4 are "work to do on user-return" bits */
+#define TIF_MEMDIE		17
 
 #define _TIF_SYSCALL_TRACE	(1 << TIF_SYSCALL_TRACE)
 #define _TIF_SYSCALL_AUDIT	(1 << TIF_SYSCALL_AUDIT)
@@ -77,7 +83,12 @@
 #define _TIF_NOTIFY_RESUME	(1 << TIF_NOTIFY_RESUME)
 #define _TIF_SIGPENDING		(1 << TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED	(1 << TIF_NEED_RESCHED)
-#define _TIF_USEDFPU		(1 << TIF_USEDFPU)
+#define _TIF_SIGDELAYED	(1 << TIF_SIGDELAYED)
 #define _TIF_POLLING_NRFLAG	(1 << TIF_POLLING_NRFLAG)
+
+/* "work to do on user-return" bits */
+#define TIF_ALLWORK_MASK	(_TIF_NOTIFY_RESUME|_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SIGDELAYED)
+/* like TIF_ALLWORK_BITS but sans TIF_SYSCALL_TRACE or TIF_SYSCALL_AUDIT */
+#define TIF_WORK_MASK		(TIF_ALLWORK_MASK&~(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT))
 
 #endif /* _ASM_IA64_THREAD_INFO_H */
diff -Nru a/include/asm-ia64/tlb.h b/include/asm-ia64/tlb.h
--- a/include/asm-ia64/tlb.h	2005-03-01 23:38:56 -08:00
+++ b/include/asm-ia64/tlb.h	2005-03-01 23:38:56 -08:00
@@ -236,4 +236,10 @@
 	__pmd_free_tlb(tlb, ptep);			\
 } while (0)
 
+#define pud_free_tlb(tlb, pudp)				\
+do {							\
+	tlb->need_flush = 1;				\
+	__pud_free_tlb(tlb, pudp);			\
+} while (0)
+
 #endif /* _ASM_IA64_TLB_H */
diff -Nru a/include/asm-ia64/topology.h b/include/asm-ia64/topology.h
--- a/include/asm-ia64/topology.h	2005-03-01 23:38:44 -08:00
+++ b/include/asm-ia64/topology.h	2005-03-01 23:38:44 -08:00
@@ -56,6 +56,8 @@
 	.per_cpu_gain		= 100,			\
 	.flags			= SD_LOAD_BALANCE	\
 				| SD_BALANCE_EXEC	\
+				| SD_BALANCE_NEWIDLE	\
+				| SD_WAKE_IDLE		\
 				| SD_WAKE_BALANCE,	\
 	.last_balance		= jiffies,		\
 	.balance_interval	= 1,			\
diff -Nru a/include/asm-ia64/uaccess.h b/include/asm-ia64/uaccess.h
--- a/include/asm-ia64/uaccess.h	2005-03-01 23:38:54 -08:00
+++ b/include/asm-ia64/uaccess.h	2005-03-01 23:38:54 -08:00
@@ -132,7 +132,7 @@
 
 #ifdef ASM_SUPPORTED
   struct __large_struct { unsigned long buf[100]; };
-# define __m(x) (*(struct __large_struct *)(x))
+# define __m(x) (*(struct __large_struct __user *)(x))
 
 /* We need to declare the __ex_table section before we can use it in .xdata.  */
 asm (".section \"__ex_table\", \"a\"\n\t.previous");
diff -Nru a/include/asm-ia64/unistd.h b/include/asm-ia64/unistd.h
--- a/include/asm-ia64/unistd.h	2005-03-01 23:38:52 -08:00
+++ b/include/asm-ia64/unistd.h	2005-03-01 23:38:52 -08:00
@@ -4,7 +4,7 @@
 /*
  * IA-64 Linux syscall numbers and inline-functions.
  *
- * Copyright (C) 1998-2004 Hewlett-Packard Co
+ * Copyright (C) 1998-2005 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  */
 
@@ -281,6 +281,7 @@
 # define __ARCH_WANT_SYS_OLDUMOUNT
 # define __ARCH_WANT_SYS_SIGPENDING
 # define __ARCH_WANT_SYS_SIGPROCMASK
+# define __ARCH_WANT_COMPAT_SYS_TIME
 #endif
 
 #if !defined(__ASSEMBLY__) && !defined(ASSEMBLER)
@@ -373,17 +374,15 @@
 				int fd, long pgoff);
 struct pt_regs;
 struct sigaction;
-asmlinkage long sys_execve(char __user *filename, char __user * __user *argv,
+long sys_execve(char __user *filename, char __user * __user *argv,
 			   char __user * __user *envp, struct pt_regs *regs);
-asmlinkage long sys_pipe(long arg0, long arg1, long arg2, long arg3,
-			long arg4, long arg5, long arg6, long arg7, long stack);
+asmlinkage long sys_pipe(void);
 asmlinkage long sys_ptrace(long request, pid_t pid,
-			unsigned long addr, unsigned long data,
-			long arg4, long arg5, long arg6, long arg7, long stack);
+			   unsigned long addr, unsigned long data);
 asmlinkage long sys_rt_sigaction(int sig,
-				const struct sigaction __user *act,
-				struct sigaction __user *oact,
-				size_t sigsetsize);
+				 const struct sigaction __user *act,
+				 struct sigaction __user *oact,
+				 size_t sigsetsize);
 
 /*
  * "Conditional" syscalls
diff -Nru a/include/asm-m32r/assembler.h b/include/asm-m32r/assembler.h
--- a/include/asm-m32r/assembler.h	2005-03-01 23:38:44 -08:00
+++ b/include/asm-m32r/assembler.h	2005-03-01 23:38:44 -08:00
@@ -1,20 +1,33 @@
 #ifndef _ASM_M32R_ASSEMBLER_H
 #define _ASM_M32R_ASSEMBLER_H
 
-/* $Id$ */
-
 /*
  * linux/asm-m32r/assembler.h
  *
- * This file contains M32R architecture specific defines.
+ * Copyright (C) 2004  Hirokazu Takata <takata at linux-m32r.org>
  *
- * Do not include any C declarations in this file - it is included by
- * assembler source.
+ * This file contains M32R architecture specific macro definitions.
  */
 
 #include <linux/config.h>
 
+#ifndef __STR
+#ifdef __ASSEMBLY__
+#define __STR(x) x
+#else
+#define __STR(x) #x
+#endif
+#endif /* __STR */
+
+#ifdef CONFIG_SMP
+#define M32R_LOCK	__STR(lock)
+#define M32R_UNLOCK	__STR(unlock)
+#else
+#define M32R_LOCK	__STR(ld)
+#define M32R_UNLOCK	__STR(st)
+#endif
 
+#ifdef __ASSEMBLY__
 #undef ENTRY
 #define ENTRY(name) ENTRY_M name
 	.macro  ENTRY_M name
@@ -22,12 +35,13 @@
 	ALIGN
 \name:
 	.endm
+#endif
 
-/*
- * LDIMM: load immediate value
- *
- * STI: enable interruption
- * CLI: disable interruption
+
+/**
+ * LDIMM - load immediate value
+ * STI - enable interruption
+ * CLI - disable interruption
  */
 
 #ifdef __ASSEMBLY__
@@ -209,4 +223,3 @@
 #endif	/* __ASSEMBLY__ */
 
 #endif	/* _ASM_M32R_ASSEMBLER_H */
-
diff -Nru a/include/asm-m32r/atomic.h b/include/asm-m32r/atomic.h
--- a/include/asm-m32r/atomic.h	2005-03-01 23:38:57 -08:00
+++ b/include/asm-m32r/atomic.h	2005-03-01 23:38:57 -08:00
@@ -10,6 +10,7 @@
  */
 
 #include <linux/config.h>
+#include <asm/assembler.h>
 #include <asm/system.h>
 
 /*
@@ -17,16 +18,6 @@
  * resource counting etc..
  */
 
-#undef LOAD
-#undef STORE
-#ifdef CONFIG_SMP
-#define LOAD	"lock"
-#define STORE	"unlock"
-#else
-#define LOAD	"ld"
-#define STORE	"st"
-#endif
-
 /*
  * 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,
@@ -60,7 +51,7 @@
  *
  * Atomically adds @i to @v and return (@i + @v).
  */
-static inline int atomic_add_return(int i, atomic_t *v)
+static __inline__ int atomic_add_return(int i, atomic_t *v)
 {
 	unsigned long flags;
 	int result;
@@ -69,9 +60,9 @@
 	__asm__ __volatile__ (
 		"# atomic_add_return		\n\t"
 		DCACHE_CLEAR("%0", "r4", "%1")
-		LOAD"	%0, @%1;		\n\t"
+		M32R_LOCK" %0, @%1;		\n\t"
 		"add	%0, %2;			\n\t"
-		STORE"	%0, @%1;		\n\t"
+		M32R_UNLOCK" %0, @%1;		\n\t"
 		: "=&r" (result)
 		: "r" (&v->counter), "r" (i)
 		: "memory"
@@ -91,7 +82,7 @@
  *
  * Atomically subtracts @i from @v and return (@v - @i).
  */
-static inline int atomic_sub_return(int i, atomic_t *v)
+static __inline__ int atomic_sub_return(int i, atomic_t *v)
 {
 	unsigned long flags;
 	int result;
@@ -100,9 +91,9 @@
 	__asm__ __volatile__ (
 		"# atomic_sub_return		\n\t"
 		DCACHE_CLEAR("%0", "r4", "%1")
-		LOAD"	%0, @%1;		\n\t"
+		M32R_LOCK" %0, @%1;		\n\t"
 		"sub	%0, %2;			\n\t"
-		STORE"	%0, @%1;		\n\t"
+		M32R_UNLOCK" %0, @%1;		\n\t"
 		: "=&r" (result)
 		: "r" (&v->counter), "r" (i)
 		: "memory"
@@ -150,7 +141,7 @@
  *
  * Atomically increments @v by 1 and returns the result.
  */
-static inline int atomic_inc_return(atomic_t *v)
+static __inline__ int atomic_inc_return(atomic_t *v)
 {
 	unsigned long flags;
 	int result;
@@ -159,9 +150,9 @@
 	__asm__ __volatile__ (
 		"# atomic_inc_return		\n\t"
 		DCACHE_CLEAR("%0", "r4", "%1")
-		LOAD"	%0, @%1;		\n\t"
+		M32R_LOCK" %0, @%1;		\n\t"
 		"addi	%0, #1;			\n\t"
-		STORE"	%0, @%1;		\n\t"
+		M32R_UNLOCK" %0, @%1;		\n\t"
 		: "=&r" (result)
 		: "r" (&v->counter)
 		: "memory"
@@ -180,7 +171,7 @@
  *
  * Atomically decrements @v by 1 and returns the result.
  */
-static inline int atomic_dec_return(atomic_t *v)
+static __inline__ int atomic_dec_return(atomic_t *v)
 {
 	unsigned long flags;
 	int result;
@@ -189,9 +180,9 @@
 	__asm__ __volatile__ (
 		"# atomic_dec_return		\n\t"
 		DCACHE_CLEAR("%0", "r4", "%1")
-		LOAD"	%0, @%1;		\n\t"
+		M32R_LOCK" %0, @%1;		\n\t"
 		"addi	%0, #-1;		\n\t"
-		STORE"	%0, @%1;		\n\t"
+		M32R_UNLOCK" %0, @%1;		\n\t"
 		: "=&r" (result)
 		: "r" (&v->counter)
 		: "memory"
@@ -251,7 +242,7 @@
  */
 #define atomic_add_negative(i,v) (atomic_add_return((i), (v)) < 0)
 
-static inline void atomic_clear_mask(unsigned long  mask, atomic_t *addr)
+static __inline__ void atomic_clear_mask(unsigned long  mask, atomic_t *addr)
 {
 	unsigned long flags;
 	unsigned long tmp;
@@ -260,9 +251,9 @@
 	__asm__ __volatile__ (
 		"# atomic_clear_mask		\n\t"
 		DCACHE_CLEAR("%0", "r5", "%1")
-		LOAD"	%0, @%1;		\n\t"
+		M32R_LOCK" %0, @%1;		\n\t"
 		"and	%0, %2;			\n\t"
-		STORE"	%0, @%1;		\n\t"
+		M32R_UNLOCK" %0, @%1;		\n\t"
 		: "=&r" (tmp)
 		: "r" (addr), "r" (~mask)
 		: "memory"
@@ -273,7 +264,7 @@
 	local_irq_restore(flags);
 }
 
-static inline void atomic_set_mask(unsigned long  mask, atomic_t *addr)
+static __inline__ void atomic_set_mask(unsigned long  mask, atomic_t *addr)
 {
 	unsigned long flags;
 	unsigned long tmp;
@@ -282,9 +273,9 @@
 	__asm__ __volatile__ (
 		"# atomic_set_mask		\n\t"
 		DCACHE_CLEAR("%0", "r5", "%1")
-		LOAD"	%0, @%1;		\n\t"
+		M32R_LOCK" %0, @%1;		\n\t"
 		"or	%0, %2;			\n\t"
-		STORE"	%0, @%1;		\n\t"
+		M32R_UNLOCK" %0, @%1;		\n\t"
 		: "=&r" (tmp)
 		: "r" (addr), "r" (mask)
 		: "memory"
@@ -302,4 +293,3 @@
 #define smp_mb__after_atomic_inc()	barrier()
 
 #endif	/* _ASM_M32R_ATOMIC_H */
-
diff -Nru a/include/asm-m32r/bitops.h b/include/asm-m32r/bitops.h
--- a/include/asm-m32r/bitops.h	2005-03-01 23:38:58 -08:00
+++ b/include/asm-m32r/bitops.h	2005-03-01 23:38:58 -08:00
@@ -13,6 +13,7 @@
 
 #include <linux/config.h>
 #include <linux/compiler.h>
+#include <asm/assembler.h>
 #include <asm/system.h>
 #include <asm/byteorder.h>
 #include <asm/types.h>
@@ -25,18 +26,6 @@
  * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1).
  */
 
-#undef LOAD
-#undef STORE
-#ifdef CONFIG_SMP
-#define LOAD	"lock"
-#define STORE	"unlock"
-#else
-#define LOAD	"ld"
-#define STORE	"st"
-#endif
-
-/* #define ADDR (*(volatile long *) addr) */
-
 /**
  * set_bit - Atomically set a bit in memory
  * @nr: the bit to set
@@ -47,7 +36,7 @@
  * Note that @nr may be almost arbitrarily large; this function is not
  * restricted to acting on a single-word quantity.
  */
-static inline void set_bit(int nr, volatile void * addr)
+static __inline__ void set_bit(int nr, volatile void * addr)
 {
 	__u32 mask;
 	volatile __u32 *a = addr;
@@ -60,9 +49,9 @@
 	local_irq_save(flags);
 	__asm__ __volatile__ (
 		DCACHE_CLEAR("%0", "r6", "%1")
-		LOAD"	%0, @%1;		\n\t"
+		M32R_LOCK" %0, @%1;		\n\t"
 		"or	%0, %2;			\n\t"
-		STORE"	%0, @%1;		\n\t"
+		M32R_UNLOCK" %0, @%1;		\n\t"
 		: "=&r" (tmp)
 		: "r" (a), "r" (mask)
 		: "memory"
@@ -82,7 +71,7 @@
  * If it's called on the same region of memory simultaneously, the effect
  * may be that only one operation succeeds.
  */
-static inline void __set_bit(int nr, volatile void * addr)
+static __inline__ void __set_bit(int nr, volatile void * addr)
 {
 	__u32 mask;
 	volatile __u32 *a = addr;
@@ -102,7 +91,7 @@
  * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit()
  * in order to ensure changes are visible on other processors.
  */
-static inline void clear_bit(int nr, volatile void * addr)
+static __inline__ void clear_bit(int nr, volatile void * addr)
 {
 	__u32 mask;
 	volatile __u32 *a = addr;
@@ -116,9 +105,9 @@
 
 	__asm__ __volatile__ (
 		DCACHE_CLEAR("%0", "r6", "%1")
-		LOAD"	%0, @%1;		\n\t"
+		M32R_LOCK" %0, @%1;		\n\t"
 		"and	%0, %2;			\n\t"
-		STORE"	%0, @%1;		\n\t"
+		M32R_UNLOCK" %0, @%1;		\n\t"
 		: "=&r" (tmp)
 		: "r" (a), "r" (~mask)
 		: "memory"
@@ -129,7 +118,7 @@
 	local_irq_restore(flags);
 }
 
-static inline void __clear_bit(int nr, volatile unsigned long * addr)
+static __inline__ void __clear_bit(int nr, volatile unsigned long * addr)
 {
 	unsigned long mask;
 	volatile unsigned long *a = addr;
@@ -151,7 +140,7 @@
  * If it's called on the same region of memory simultaneously, the effect
  * may be that only one operation succeeds.
  */
-static inline void __change_bit(int nr, volatile void * addr)
+static __inline__ void __change_bit(int nr, volatile void * addr)
 {
 	__u32 mask;
 	volatile __u32 *a = addr;
@@ -170,7 +159,7 @@
  * Note that @nr may be almost arbitrarily large; this function is not
  * restricted to acting on a single-word quantity.
  */
-static inline void change_bit(int nr, volatile void * addr)
+static __inline__ void change_bit(int nr, volatile void * addr)
 {
 	__u32  mask;
 	volatile __u32  *a = addr;
@@ -183,9 +172,9 @@
 	local_irq_save(flags);
 	__asm__ __volatile__ (
 		DCACHE_CLEAR("%0", "r6", "%1")
-		LOAD"	%0, @%1;		\n\t"
+		M32R_LOCK" %0, @%1;		\n\t"
 		"xor	%0, %2;			\n\t"
-		STORE"	%0, @%1;		\n\t"
+		M32R_UNLOCK" %0, @%1;		\n\t"
 		: "=&r" (tmp)
 		: "r" (a), "r" (mask)
 		: "memory"
@@ -204,7 +193,7 @@
  * This operation is atomic and cannot be reordered.
  * It also implies a memory barrier.
  */
-static inline int test_and_set_bit(int nr, volatile void * addr)
+static __inline__ int test_and_set_bit(int nr, volatile void * addr)
 {
 	__u32 mask, oldbit;
 	volatile __u32 *a = addr;
@@ -217,11 +206,11 @@
 	local_irq_save(flags);
 	__asm__ __volatile__ (
 		DCACHE_CLEAR("%0", "%1", "%2")
-		LOAD"	%0, @%2;		\n\t"
+		M32R_LOCK" %0, @%2;		\n\t"
 		"mv	%1, %0;			\n\t"
 		"and	%0, %3;			\n\t"
 		"or	%1, %3;			\n\t"
-		STORE"	%1, @%2;		\n\t"
+		M32R_UNLOCK" %1, @%2;		\n\t"
 		: "=&r" (oldbit), "=&r" (tmp)
 		: "r" (a), "r" (mask)
 		: "memory"
@@ -240,7 +229,7 @@
  * If two examples of this operation race, one can appear to succeed
  * but actually fail.  You must protect multiple accesses with a lock.
  */
-static inline int __test_and_set_bit(int nr, volatile void * addr)
+static __inline__ int __test_and_set_bit(int nr, volatile void * addr)
 {
 	__u32 mask, oldbit;
 	volatile __u32 *a = addr;
@@ -261,7 +250,7 @@
  * This operation is atomic and cannot be reordered.
  * It also implies a memory barrier.
  */
-static inline int test_and_clear_bit(int nr, volatile void * addr)
+static __inline__ int test_and_clear_bit(int nr, volatile void * addr)
 {
 	__u32 mask, oldbit;
 	volatile __u32 *a = addr;
@@ -275,12 +264,12 @@
 
 	__asm__ __volatile__ (
 		DCACHE_CLEAR("%0", "%1", "%3")
-		LOAD"	%0, @%3;		\n\t"
-		"mv	%1, %0; \n\t"
-		"and	%0, %2; \n\t"
-		"not	%2, %2; \n\t"
-		"and	%1, %2; \n\t"
-		STORE"	%1, @%3;		\n\t"
+		M32R_LOCK" %0, @%3;		\n\t"
+		"mv	%1, %0;			\n\t"
+		"and	%0, %2;			\n\t"
+		"not	%2, %2;			\n\t"
+		"and	%1, %2;			\n\t"
+		M32R_UNLOCK" %1, @%3;		\n\t"
 		: "=&r" (oldbit), "=&r" (tmp), "+r" (mask)
 		: "r" (a)
 		: "memory"
@@ -299,7 +288,7 @@
  * If two examples of this operation race, one can appear to succeed
  * but actually fail.  You must protect multiple accesses with a lock.
  */
-static inline int __test_and_clear_bit(int nr, volatile void * addr)
+static __inline__ int __test_and_clear_bit(int nr, volatile void * addr)
 {
 	__u32 mask, oldbit;
 	volatile __u32 *a = addr;
@@ -313,7 +302,7 @@
 }
 
 /* WARNING: non atomic and it can be reordered! */
-static inline int __test_and_change_bit(int nr, volatile void * addr)
+static __inline__ int __test_and_change_bit(int nr, volatile void * addr)
 {
 	__u32 mask, oldbit;
 	volatile __u32 *a = addr;
@@ -334,7 +323,7 @@
  * This operation is atomic and cannot be reordered.
  * It also implies a memory barrier.
  */
-static inline int test_and_change_bit(int nr, volatile void * addr)
+static __inline__ int test_and_change_bit(int nr, volatile void * addr)
 {
 	__u32 mask, oldbit;
 	volatile __u32 *a = addr;
@@ -347,11 +336,11 @@
 	local_irq_save(flags);
 	__asm__ __volatile__ (
 		DCACHE_CLEAR("%0", "%1", "%2")
-		LOAD"	%0, @%2;		\n\t"
+		M32R_LOCK" %0, @%2;		\n\t"
 		"mv	%1, %0;			\n\t"
 		"and	%0, %3;			\n\t"
 		"xor	%1, %3;			\n\t"
-		STORE"	%1, @%2;		\n\t"
+		M32R_UNLOCK" %1, @%2;		\n\t"
 		: "=&r" (oldbit), "=&r" (tmp)
 		: "r" (a), "r" (mask)
 		: "memory"
@@ -361,16 +350,12 @@
 	return (oldbit != 0);
 }
 
-#if 0 /* Fool kernel-doc since it doesn't do macros yet */
 /**
  * test_bit - Determine whether a bit is set
  * @nr: bit number to test
  * @addr: Address to start counting from
  */
-static int test_bit(int nr, const volatile void * addr);
-#endif
-
-static inline int test_bit(int nr, const volatile void * addr)
+static __inline__ int test_bit(int nr, const volatile void * addr)
 {
 	__u32 mask;
 	const volatile __u32 *a = addr;
@@ -387,7 +372,7 @@
  *
  * Undefined if no zero exists, so code should check against ~0UL first.
  */
-static inline unsigned long ffz(unsigned long word)
+static __inline__ unsigned long ffz(unsigned long word)
 {
 	int k;
 
@@ -420,9 +405,10 @@
  * @offset: The bitnumber to start searching at
  * @size: The maximum size to search
  */
-static inline int find_next_zero_bit(void *addr, int size, int offset)
+static __inline__ int find_next_zero_bit(const unsigned long *addr,
+					 int size, int offset)
 {
-	unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
+	const unsigned long *p = addr + (offset >> 5);
 	unsigned long result = offset & ~31UL;
 	unsigned long tmp;
 
@@ -462,7 +448,7 @@
  *
  * 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)
 {
 	int k = 0;
 
diff -Nru a/include/asm-m32r/checksum.h b/include/asm-m32r/checksum.h
--- a/include/asm-m32r/checksum.h	2005-03-01 23:38:51 -08:00
+++ b/include/asm-m32r/checksum.h	2005-03-01 23:38:51 -08:00
@@ -31,7 +31,8 @@
  *
  * 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);
+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.
@@ -39,15 +40,16 @@
  * Here even more important to align src and dst on a 32-bit (or even
  * better 64-bit) boundary
  */
-extern unsigned int csum_partial_copy_nocheck(const char *src, char *dst,
+extern unsigned int csum_partial_copy_nocheck(const unsigned char *src,
+					      unsigned char *dst,
                                               int len, unsigned int sum);
 
 /*
  * This is a new version of the above that records errors it finds in *errp,
  * but continues and zeros thre rest of the buffer.
  */
-extern unsigned int csum_partial_copy_from_user(const char __user *src,
-                                                char *dst,
+extern unsigned int csum_partial_copy_from_user(const unsigned char __user *src,
+                                                unsigned char *dst,
                                                 int len, unsigned int sum,
                                                 int *err_ptr);
 
diff -Nru a/include/asm-m32r/cputime.h b/include/asm-m32r/cputime.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-m32r/cputime.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,6 @@
+#ifndef __M32R_CPUTIME_H
+#define __M32R_CPUTIME_H
+
+#include <asm-generic/cputime.h>
+
+#endif /* __M32R_CPUTIME_H */
diff -Nru a/include/asm-m32r/elf.h b/include/asm-m32r/elf.h
--- a/include/asm-m32r/elf.h	2005-03-01 23:38:59 -08:00
+++ b/include/asm-m32r/elf.h	2005-03-01 23:38:59 -08:00
@@ -54,6 +54,9 @@
 #define R_M32R_GOTPC_HI_ULO	59
 #define R_M32R_GOTPC_HI_SLO	60
 #define R_M32R_GOTPC_LO		61
+#define R_M32R_GOTOFF_HI_ULO	62
+#define R_M32R_GOTOFF_HI_SLO	63
+#define R_M32R_GOTOFF_LO	64
 
 #define R_M32R_NUM		256
 
diff -Nru a/include/asm-m32r/hardirq.h b/include/asm-m32r/hardirq.h
--- a/include/asm-m32r/hardirq.h	2005-03-01 23:39:08 -08:00
+++ b/include/asm-m32r/hardirq.h	2005-03-01 23:39:08 -08:00
@@ -1,3 +1,4 @@
+#ifdef __KERNEL__
 #ifndef __ASM_HARDIRQ_H
 #define __ASM_HARDIRQ_H
 
@@ -7,8 +8,6 @@
 
 typedef struct {
 	unsigned int __softirq_pending;
-	unsigned int __syscall_count;
-	struct task_struct * __ksoftirqd_task; /* waitqueue is too large */
 } ____cacheline_aligned irq_cpustat_t;
 
 #include <linux/irq_cpustat.h>	/* Standard mappings for irq_cpustat_t above */
@@ -28,16 +27,11 @@
 # error HARDIRQ_BITS is too low!
 #endif
 
-#define irq_enter()		(preempt_count() += HARDIRQ_OFFSET)
-#define nmi_enter()		(irq_enter())
-#define nmi_exit()		(preempt_count() -= HARDIRQ_OFFSET)
-
-#define irq_exit()							\
-do {									\
-		preempt_count() -= IRQ_EXIT_OFFSET;			\
-		if (!in_interrupt() && softirq_pending(smp_processor_id())) \
-			do_softirq();					\
-		preempt_enable_no_resched();				\
-} while (0)
+static inline void ack_bad_irq(int irq)
+{
+	printk(KERN_CRIT "unexpected IRQ trap at vector %02x\n", irq);
+	BUG();
+}
 
 #endif /* __ASM_HARDIRQ_H */
+#endif /* __KERNEL__ */
diff -Nru a/include/asm-m32r/irq.h b/include/asm-m32r/irq.h
--- a/include/asm-m32r/irq.h	2005-03-01 23:38:52 -08:00
+++ b/include/asm-m32r/irq.h	2005-03-01 23:38:52 -08:00
@@ -1,8 +1,7 @@
+#ifdef __KERNEL__
 #ifndef _ASM_M32R_IRQ_H
 #define _ASM_M32R_IRQ_H
 
-/* $Id$ */
-
 #include <linux/config.h>
 
 #if defined(CONFIG_PLAT_M32700UT_Alpha) || defined(CONFIG_PLAT_USRV)
@@ -72,15 +71,5 @@
 
 #define irq_canonicalize(irq)	(irq)
 
-#ifndef __ASSEMBLY__
-extern void disable_irq(unsigned int);
-extern void disable_irq_nosync(unsigned int);
-extern void enable_irq(unsigned int);
-
-struct irqaction;
-struct pt_regs;
-int handle_IRQ_event(unsigned int, struct pt_regs *, struct irqaction *);
-#endif
-
-#endif	/* _ASM_M32R_IRQ_H */
-
+#endif /* _ASM_M32R_IRQ_H */
+#endif /* __KERNEL__ */
diff -Nru a/include/asm-m32r/mmu_context.h b/include/asm-m32r/mmu_context.h
--- a/include/asm-m32r/mmu_context.h	2005-03-01 23:39:17 -08:00
+++ b/include/asm-m32r/mmu_context.h	2005-03-01 23:39:17 -08:00
@@ -1,7 +1,7 @@
 #ifndef _ASM_M32R_MMU_CONTEXT_H
 #define _ASM_M32R_MMU_CONTEXT_H
 
-/* $Id */
+#ifdef __KERNEL__
 
 #include <linux/config.h>
 
@@ -34,13 +34,13 @@
 #define mm_context(mm)		mm->context[smp_processor_id()]
 #endif /* not CONFIG_SMP */
 
-#define set_tlb_tag(entry, tag)	(*entry = (tag & PAGE_MASK)|get_asid())
+#define set_tlb_tag(entry, tag)		(*entry = (tag & PAGE_MASK)|get_asid())
 #define set_tlb_data(entry, data)	(*entry = (data | _PAGE_PRESENT))
 
 #ifdef CONFIG_MMU
 #define enter_lazy_tlb(mm, tsk)	do { } while (0)
 
-static __inline__ void get_new_mmu_context(struct mm_struct *mm)
+static inline void get_new_mmu_context(struct mm_struct *mm)
 {
 	unsigned long mc = ++mmu_context_cache;
 
@@ -59,7 +59,7 @@
 /*
  * Get MMU context if needed.
  */
-static __inline__ void get_mmu_context(struct mm_struct *mm)
+static inline void get_mmu_context(struct mm_struct *mm)
 {
 	if (mm) {
 		unsigned long mc = mmu_context_cache;
@@ -75,7 +75,7 @@
  * Initialize the context related info for a new mm_struct
  * instance.
  */
-static __inline__ int init_new_context(struct task_struct *tsk,
+static inline int init_new_context(struct task_struct *tsk,
 	struct mm_struct *mm)
 {
 #ifndef CONFIG_SMP
@@ -97,12 +97,12 @@
  */
 #define destroy_context(mm)	do { } while (0)
 
-static __inline__ void set_asid(unsigned long asid)
+static inline void set_asid(unsigned long asid)
 {
 	*(volatile unsigned long *)MASID = (asid & MMU_CONTEXT_ASID_MASK);
 }
 
-static __inline__ unsigned long get_asid(void)
+static inline unsigned long get_asid(void)
 {
 	unsigned long asid;
 
@@ -116,13 +116,13 @@
  * After we have set current->mm to a new value, this activates
  * the context for the new mm so we see the new mappings.
  */
-static __inline__ void activate_context(struct mm_struct *mm)
+static inline void activate_context(struct mm_struct *mm)
 {
 	get_mmu_context(mm);
 	set_asid(mm_context(mm) & MMU_CONTEXT_ASID_MASK);
 }
 
-static __inline__ void switch_mm(struct mm_struct *prev,
+static inline void switch_mm(struct mm_struct *prev,
 	struct mm_struct *next, struct task_struct *tsk)
 {
 #ifdef CONFIG_SMP
@@ -165,5 +165,6 @@
 
 #endif /* not __ASSEMBLY__ */
 
-#endif /* _ASM_M32R_MMU_CONTEXT_H */
+#endif /* __KERNEL__ */
 
+#endif /* _ASM_M32R_MMU_CONTEXT_H */
diff -Nru a/include/asm-m32r/page.h b/include/asm-m32r/page.h
--- a/include/asm-m32r/page.h	2005-03-01 23:38:54 -08:00
+++ b/include/asm-m32r/page.h	2005-03-01 23:38:54 -08:00
@@ -17,6 +17,9 @@
 #define clear_user_page(page, vaddr, pg)	clear_page(page)
 #define copy_user_page(to, from, vaddr, pg)	copy_page(to, from)
 
+#define alloc_zeroed_user_highpage(vma, vaddr) alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO, vma, vaddr)
+#define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE
+
 /*
  * These are used to make use of C type-checking..
  */
diff -Nru a/include/asm-m32r/pgalloc.h b/include/asm-m32r/pgalloc.h
--- a/include/asm-m32r/pgalloc.h	2005-03-01 23:39:10 -08:00
+++ b/include/asm-m32r/pgalloc.h	2005-03-01 23:39:10 -08:00
@@ -23,10 +23,7 @@
  */
 static __inline__ pgd_t *pgd_alloc(struct mm_struct *mm)
 {
-	pgd_t *pgd = (pgd_t *)__get_free_page(GFP_KERNEL);
-
-	if (pgd)
-		clear_page(pgd);
+	pgd_t *pgd = (pgd_t *)__get_free_page(GFP_KERNEL|__GFP_ZERO);
 
 	return pgd;
 }
@@ -39,10 +36,7 @@
 static __inline__ pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
 	unsigned long address)
 {
-	pte_t *pte = (pte_t *)__get_free_page(GFP_KERNEL);
-
-	if (pte)
-		clear_page(pte);
+	pte_t *pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_ZERO);
 
 	return pte;
 }
@@ -50,10 +44,8 @@
 static __inline__ struct page *pte_alloc_one(struct mm_struct *mm,
 	unsigned long address)
 {
-	struct page *pte = alloc_page(GFP_KERNEL);
+	struct page *pte = alloc_page(GFP_KERNEL|__GFP_ZERO);
 
-	if (pte)
-		clear_page(page_address(pte));
 
 	return pte;
 }
diff -Nru a/include/asm-m32r/pgtable-2level.h b/include/asm-m32r/pgtable-2level.h
--- a/include/asm-m32r/pgtable-2level.h	2005-03-01 23:38:54 -08:00
+++ b/include/asm-m32r/pgtable-2level.h	2005-03-01 23:38:54 -08:00
@@ -1,7 +1,7 @@
 #ifndef _ASM_M32R_PGTABLE_2LEVEL_H
 #define _ASM_M32R_PGTABLE_2LEVEL_H
 
-/* $Id$ */
+#ifdef __KERNEL__
 
 #include <linux/config.h>
 
@@ -33,9 +33,9 @@
  * setup: the pgd is never bad, and a pmd always exists (as it's folded
  * into the pgd entry)
  */
-static __inline__ int pgd_none(pgd_t pgd)	{ return 0; }
-static __inline__ int pgd_bad(pgd_t pgd)	{ return 0; }
-static __inline__ int pgd_present(pgd_t pgd)	{ return 1; }
+static inline int pgd_none(pgd_t pgd)	{ return 0; }
+static inline int pgd_bad(pgd_t pgd)	{ return 0; }
+static inline int pgd_present(pgd_t pgd)	{ return 1; }
 #define pgd_clear(xp)				do { } while (0)
 
 /*
@@ -55,7 +55,7 @@
 #define pgd_page(pgd) \
 ((unsigned long) __va(pgd_val(pgd) & PAGE_MASK))
 
-static __inline__ pmd_t *pmd_offset(pgd_t * dir, unsigned long address)
+static inline pmd_t *pmd_offset(pgd_t * dir, unsigned long address)
 {
 	return (pmd_t *) dir;
 }
@@ -68,10 +68,10 @@
 #define pfn_pte(pfn, prot)	__pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
 #define pfn_pmd(pfn, prot)	__pmd(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
 
-/* M32R_FIXME : PTE_FILE_MAX_BITS, pte_to_pgoff, pgoff_to_pte */
-#define PTE_FILE_MAX_BITS	31
-#define pte_to_pgoff(pte)	(pte_val(pte) >> 1)
-#define pgoff_to_pte(off)	((pte_t) { ((off) << 1) | _PAGE_FILE })
+#define PTE_FILE_MAX_BITS	29
+#define pte_to_pgoff(pte)	(((pte_val(pte) >> 2) & 0xef) | (((pte_val(pte) >> 10)) << 7))
+#define pgoff_to_pte(off)	((pte_t) { (((off) & 0xef) << 2) | (((off) >> 7) << 10) | _PAGE_FILE })
 
-#endif /* _ASM_M32R_PGTABLE_2LEVEL_H */
+#endif /* __KERNEL__ */
 
+#endif /* _ASM_M32R_PGTABLE_2LEVEL_H */
diff -Nru a/include/asm-m32r/pgtable.h b/include/asm-m32r/pgtable.h
--- a/include/asm-m32r/pgtable.h	2005-03-01 23:38:44 -08:00
+++ b/include/asm-m32r/pgtable.h	2005-03-01 23:38:44 -08:00
@@ -1,8 +1,9 @@
 #ifndef _ASM_M32R_PGTABLE_H
 #define _ASM_M32R_PGTABLE_H
 
-/* $Id$ */
+#include <asm-generic/4level-fixup.h>
 
+#ifdef __KERNEL__
 /*
  * The Linux memory management assumes a three-level page table setup. On
  * the M32R, we use that, but "fold" the mid level into the top-level page
@@ -38,11 +39,6 @@
 
 #endif /* !__ASSEMBLY__ */
 
-/*
- * The Linux x86 paging architecture is 'compile-time dual-mode', it
- * implements both the traditional 2-level x86 page tables and the
- * newer 3-level PAE-mode page tables.
- */
 #ifndef __ASSEMBLY__
 #include <asm/pgtable-2level.h>
 #endif
@@ -69,14 +65,6 @@
 #define VMALLOC_END		KSEG3
 
 /*
- * The 4MB page is guessing..  Detailed in the infamous "Chapter H"
- * of the Pentium details, but assuming intel did the straightforward
- * thing, this bit set in the page directory entry just means that
- * the page directory entry points directly to a 4MB-aligned block of
- * memory.
- */
-
-/*
  *     M32R TLB format
  *
  *     [0]    [1:19]           [20:23]       [24:31]
@@ -89,47 +77,34 @@
  *                                     RWX
  */
 
-#define _PAGE_BIT_DIRTY		0	/* software */
+#define _PAGE_BIT_DIRTY		0	/* software: page changed */
 #define _PAGE_BIT_FILE		0	/* when !present: nonlinear file
 					   mapping */
-#define _PAGE_BIT_PRESENT	1	/* Valid */
+#define _PAGE_BIT_PRESENT	1	/* Valid: page is valid */
 #define _PAGE_BIT_GLOBAL	2	/* Global */
 #define _PAGE_BIT_LARGE		3	/* Large */
 #define _PAGE_BIT_EXEC		4	/* Execute */
 #define _PAGE_BIT_WRITE		5	/* Write */
 #define _PAGE_BIT_READ		6	/* Read */
 #define _PAGE_BIT_NONCACHABLE	7	/* Non cachable */
-#define _PAGE_BIT_USER		8	/* software */
-#define _PAGE_BIT_ACCESSED	9	/* software */
+#define _PAGE_BIT_ACCESSED	8	/* software: page referenced */
+#define _PAGE_BIT_PROTNONE	9	/* software: if not present */
 
-#define _PAGE_DIRTY	\
-	(1UL << _PAGE_BIT_DIRTY)	/* software : page changed */
-#define _PAGE_FILE	\
-	(1UL << _PAGE_BIT_FILE)		/* when !present: nonlinear file
-					   mapping */
-#define _PAGE_PRESENT	\
-	(1UL << _PAGE_BIT_PRESENT)	/* Valid : Page is Valid */
-#define _PAGE_GLOBAL	\
-	(1UL << _PAGE_BIT_GLOBAL)	/* Global */
-#define _PAGE_LARGE	\
-	(1UL << _PAGE_BIT_LARGE)	/* Large */
-#define _PAGE_EXEC	\
-	(1UL << _PAGE_BIT_EXEC)		/* Execute */
-#define _PAGE_WRITE	\
-	(1UL << _PAGE_BIT_WRITE)	/* Write */
-#define _PAGE_READ	\
-	(1UL << _PAGE_BIT_READ)		/* Read */
-#define _PAGE_NONCACHABLE	\
-	(1UL<<_PAGE_BIT_NONCACHABLE)	/* Non cachable */
-#define _PAGE_USER	\
-	(1UL << _PAGE_BIT_USER)		/* software : user space access
-					   allowed */
-#define _PAGE_ACCESSED	\
-	(1UL << _PAGE_BIT_ACCESSED)	/* software : page referenced */
+#define _PAGE_DIRTY		(1UL << _PAGE_BIT_DIRTY)
+#define _PAGE_FILE		(1UL << _PAGE_BIT_FILE)
+#define _PAGE_PRESENT		(1UL << _PAGE_BIT_PRESENT)
+#define _PAGE_GLOBAL		(1UL << _PAGE_BIT_GLOBAL)
+#define _PAGE_LARGE		(1UL << _PAGE_BIT_LARGE)
+#define _PAGE_EXEC		(1UL << _PAGE_BIT_EXEC)
+#define _PAGE_WRITE		(1UL << _PAGE_BIT_WRITE)
+#define _PAGE_READ		(1UL << _PAGE_BIT_READ)
+#define _PAGE_NONCACHABLE	(1UL << _PAGE_BIT_NONCACHABLE)
+#define _PAGE_ACCESSED		(1UL << _PAGE_BIT_ACCESSED)
+#define _PAGE_PROTNONE		(1UL << _PAGE_BIT_PROTNONE)
 
 #define _PAGE_TABLE	\
-	( _PAGE_PRESENT | _PAGE_WRITE | _PAGE_READ | _PAGE_USER \
-	| _PAGE_ACCESSED | _PAGE_DIRTY )
+	( _PAGE_PRESENT | _PAGE_WRITE | _PAGE_READ | _PAGE_ACCESSED \
+	| _PAGE_DIRTY )
 #define _KERNPG_TABLE	\
 	( _PAGE_PRESENT | _PAGE_WRITE | _PAGE_READ | _PAGE_ACCESSED \
 	| _PAGE_DIRTY )
@@ -138,24 +113,20 @@
 
 #ifdef CONFIG_MMU
 #define PAGE_NONE	\
-	__pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
+	__pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED)
 #define PAGE_SHARED	\
-	__pgprot(_PAGE_PRESENT | _PAGE_WRITE | _PAGE_READ | _PAGE_USER \
-		| _PAGE_ACCESSED)
-#define PAGE_SHARED_X	\
+	__pgprot(_PAGE_PRESENT | _PAGE_WRITE | _PAGE_READ | _PAGE_ACCESSED)
+#define PAGE_SHARED_EXEC \
 	__pgprot(_PAGE_PRESENT | _PAGE_EXEC | _PAGE_WRITE | _PAGE_READ \
-		| _PAGE_USER | _PAGE_ACCESSED)
-#define PAGE_COPY	\
-	__pgprot(_PAGE_PRESENT | _PAGE_EXEC | _PAGE_READ | _PAGE_USER \
-		| _PAGE_ACCESSED)
-#define PAGE_COPY_X	\
-	__pgprot(_PAGE_PRESENT | _PAGE_EXEC | _PAGE_READ | _PAGE_USER \
 		| _PAGE_ACCESSED)
+#define PAGE_COPY	\
+	__pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_ACCESSED)
+#define PAGE_COPY_EXEC	\
+	__pgprot(_PAGE_PRESENT | _PAGE_EXEC | _PAGE_READ | _PAGE_ACCESSED)
 #define PAGE_READONLY	\
-	__pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_USER | _PAGE_ACCESSED)
-#define PAGE_READONLY_X	\
-	__pgprot(_PAGE_PRESENT | _PAGE_EXEC | _PAGE_READ | _PAGE_USER \
-		| _PAGE_ACCESSED)
+	__pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_ACCESSED)
+#define PAGE_READONLY_EXEC \
+	__pgprot(_PAGE_PRESENT | _PAGE_EXEC | _PAGE_READ | _PAGE_ACCESSED)
 
 #define __PAGE_KERNEL	\
 	( _PAGE_PRESENT | _PAGE_EXEC | _PAGE_WRITE | _PAGE_READ | _PAGE_DIRTY \
@@ -170,53 +141,47 @@
 #define PAGE_KERNEL_NOCACHE	MAKE_GLOBAL(__PAGE_KERNEL_NOCACHE)
 
 #else
-#define PAGE_NONE               __pgprot(0)
-#define PAGE_SHARED             __pgprot(0)
-#define PAGE_SHARED_X           __pgprot(0)
-#define PAGE_COPY               __pgprot(0)
-#define PAGE_COPY_X             __pgprot(0)
-#define PAGE_READONLY           __pgprot(0)
-#define PAGE_READONLY_X         __pgprot(0)
-
-#define PAGE_KERNEL             __pgprot(0)
-#define PAGE_KERNEL_RO          __pgprot(0)
-#define PAGE_KERNEL_NOCACHE     __pgprot(0)
+#define PAGE_NONE		__pgprot(0)
+#define PAGE_SHARED		__pgprot(0)
+#define PAGE_SHARED_EXEC	__pgprot(0)
+#define PAGE_COPY		__pgprot(0)
+#define PAGE_COPY_EXEC		__pgprot(0)
+#define PAGE_READONLY		__pgprot(0)
+#define PAGE_READONLY_EXEC	__pgprot(0)
+
+#define PAGE_KERNEL		__pgprot(0)
+#define PAGE_KERNEL_RO		__pgprot(0)
+#define PAGE_KERNEL_NOCACHE	__pgprot(0)
 #endif /* CONFIG_MMU */
 
-/*
- * The i386 can't do page protection for execute, and considers that
- * the same are read. Also, write permissions imply read permissions.
- * This is the closest we can get..
- */
-	/* rwx */
+	/* xwr */
 #define __P000	PAGE_NONE
-#define __P001	PAGE_READONLY_X
-#define __P010	PAGE_COPY_X
-#define __P011	PAGE_COPY_X
-#define __P100	PAGE_READONLY
-#define __P101	PAGE_READONLY_X
-#define __P110	PAGE_COPY_X
-#define __P111	PAGE_COPY_X
+#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_X
+#define __S001	PAGE_READONLY
 #define __S010	PAGE_SHARED
-#define __S011	PAGE_SHARED_X
-#define __S100	PAGE_READONLY
-#define __S101	PAGE_READONLY_X
-#define __S110	PAGE_SHARED
-#define __S111	PAGE_SHARED_X
+#define __S011	PAGE_SHARED
+#define __S100	PAGE_READONLY_EXEC
+#define __S101	PAGE_READONLY_EXEC
+#define __S110	PAGE_SHARED_EXEC
+#define __S111	PAGE_SHARED_EXEC
 
 /* page table for 0-4MB for everybody */
 
-#define pte_present(x)	(pte_val(x) & _PAGE_PRESENT)
+#define pte_present(x)	(pte_val(x) & (_PAGE_PRESENT | _PAGE_PROTNONE))
 #define pte_clear(xp)	do { set_pte(xp, __pte(0)); } while (0)
 
 #define pmd_none(x)	(!pmd_val(x))
 #define pmd_present(x)	(pmd_val(x) & _PAGE_PRESENT)
 #define pmd_clear(xp)	do { set_pmd(xp, __pmd(0)); } while (0)
-#define	pmd_bad(x)	((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER)) \
-	!= _KERNPG_TABLE)
+#define	pmd_bad(x)	((pmd_val(x) & ~PAGE_MASK) != _KERNPG_TABLE)
 
 #define pages_to_mb(x)	((x) >> (20 - PAGE_SHIFT))
 
@@ -224,32 +189,27 @@
  * The following only work if pte_present() is true.
  * Undefined behaviour if not..
  */
-static __inline__ int pte_user(pte_t pte)
-{
-	return pte_val(pte) & _PAGE_USER;
-}
-
-static __inline__ int pte_read(pte_t pte)
+static inline int pte_read(pte_t pte)
 {
 	return pte_val(pte) & _PAGE_READ;
 }
 
-static __inline__ int pte_exec(pte_t pte)
+static inline int pte_exec(pte_t pte)
 {
 	return pte_val(pte) & _PAGE_EXEC;
 }
 
-static __inline__ int pte_dirty(pte_t pte)
+static inline int pte_dirty(pte_t pte)
 {
 	return pte_val(pte) & _PAGE_DIRTY;
 }
 
-static __inline__ int pte_young(pte_t pte)
+static inline int pte_young(pte_t pte)
 {
 	return pte_val(pte) & _PAGE_ACCESSED;
 }
 
-static __inline__ int pte_write(pte_t pte)
+static inline int pte_write(pte_t pte)
 {
 	return pte_val(pte) & _PAGE_WRITE;
 }
@@ -257,96 +217,111 @@
 /*
  * The following only works if pte_present() is not true.
  */
-static __inline__ int pte_file(pte_t pte)
+static inline int pte_file(pte_t pte)
 {
 	return pte_val(pte) & _PAGE_FILE;
 }
 
-static __inline__ pte_t pte_rdprotect(pte_t pte)
+static inline pte_t pte_rdprotect(pte_t pte)
 {
 	pte_val(pte) &= ~_PAGE_READ;
 	return pte;
 }
 
-static __inline__ pte_t pte_exprotect(pte_t pte)
+static inline pte_t pte_exprotect(pte_t pte)
 {
 	pte_val(pte) &= ~_PAGE_EXEC;
 	return pte;
 }
 
-static __inline__ pte_t pte_mkclean(pte_t 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)
+static inline pte_t pte_mkold(pte_t pte)
 {
-	pte_val(pte) &= ~_PAGE_ACCESSED;return pte;}
+	pte_val(pte) &= ~_PAGE_ACCESSED;
+	return pte;
+}
 
-static __inline__ pte_t pte_wrprotect(pte_t pte)
+static inline pte_t pte_wrprotect(pte_t pte)
 {
 	pte_val(pte) &= ~_PAGE_WRITE;
 	return pte;
 }
 
-static __inline__ pte_t pte_mkread(pte_t pte)
+static inline pte_t pte_mkread(pte_t pte)
 {
 	pte_val(pte) |= _PAGE_READ;
 	return pte;
 }
 
-static __inline__ pte_t pte_mkexec(pte_t pte)
+static inline pte_t pte_mkexec(pte_t pte)
 {
 	pte_val(pte) |= _PAGE_EXEC;
 	return pte;
 }
 
-static __inline__ pte_t pte_mkdirty(pte_t 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)
+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)
+static inline pte_t pte_mkwrite(pte_t pte)
 {
 	pte_val(pte) |= _PAGE_WRITE;
 	return pte;
 }
 
-static __inline__  int ptep_test_and_clear_dirty(pte_t *ptep)
+static inline  int ptep_test_and_clear_dirty(pte_t *ptep)
 {
 	return test_and_clear_bit(_PAGE_BIT_DIRTY, ptep);
 }
 
-static __inline__  int ptep_test_and_clear_young(pte_t *ptep)
+static inline  int ptep_test_and_clear_young(pte_t *ptep)
 {
 	return test_and_clear_bit(_PAGE_BIT_ACCESSED, ptep);
 }
 
-static __inline__ void ptep_set_wrprotect(pte_t *ptep)
+static inline void ptep_set_wrprotect(pte_t *ptep)
 {
 	clear_bit(_PAGE_BIT_WRITE, ptep);
 }
 
-static __inline__ void ptep_mkdirty(pte_t *ptep)
+static inline void ptep_mkdirty(pte_t *ptep)
 {
 	set_bit(_PAGE_BIT_DIRTY, ptep);
 }
 
 /*
+ * Macro and implementation to make a page protection as uncachable.
+ */
+static inline pgprot_t pgprot_noncached(pgprot_t _prot)
+{
+	unsigned long prot = pgprot_val(_prot);
+
+	prot |= _PAGE_NONCACHABLE;
+	return __pgprot(prot);
+}
+
+#define pgprot_writecombine(prot) pgprot_noncached(prot)
+
+/*
  * 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 mk_pte(page, pgprot)	pfn_pte(page_to_pfn(page), pgprot)
 
-static __inline__ pte_t pte_modify(pte_t pte, pgprot_t newprot)
+static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
 {
 	set_pte(&pte, __pte((pte_val(pte) & _PAGE_CHG_MASK) \
 		| pgprot_val(newprot)));
@@ -361,7 +336,7 @@
  * and a page entry and page directory to the page they refer to.
  */
 
-static __inline__ void pmd_set(pmd_t * pmdp, pte_t * ptep)
+static inline void pmd_set(pmd_t * pmdp, pte_t * ptep)
 {
 	pmd_val(*pmdp) = (((unsigned long) ptep) & PAGE_MASK);
 }
@@ -396,10 +371,10 @@
 #define pte_unmap_nested(pte)	do { } while (0)
 
 /* Encode and de-code a swap entry */
-#define __swp_type(x)			(((x).val >> 1) & 0x3f)
-#define __swp_offset(x)			((x).val >> 8)
+#define __swp_type(x)			(((x).val >> 2) & 0x3f)
+#define __swp_offset(x)			((x).val >> 10)
 #define __swp_entry(type, offset)	\
-	((swp_entry_t) { ((type) << 1) | ((offset) << 8) })
+	((swp_entry_t) { ((type) << 2) | ((offset) << 10) })
 #define __pte_to_swp_entry(pte)		((swp_entry_t) { pte_val(pte) })
 #define __swp_entry_to_pte(x)		((pte_t) { (x).val })
 
@@ -408,8 +383,8 @@
 /* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
 #define kern_addr_valid(addr)	(1)
 
-#define io_remap_page_range(vma, vaddr, paddr, size, prot)		\
-		remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot)
+#define io_remap_page_range(vma, vaddr, paddr, size, prot)	\
+	remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot)
 
 #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
 #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_DIRTY
@@ -419,5 +394,6 @@
 #define __HAVE_ARCH_PTE_SAME
 #include <asm-generic/pgtable.h>
 
-#endif /* _ASM_M32R_PGTABLE_H */
+#endif /* __KERNEL__ */
 
+#endif /* _ASM_M32R_PGTABLE_H */
diff -Nru a/include/asm-m32r/processor.h b/include/asm-m32r/processor.h
--- a/include/asm-m32r/processor.h	2005-03-01 23:38:51 -08:00
+++ b/include/asm-m32r/processor.h	2005-03-01 23:38:51 -08:00
@@ -70,10 +70,12 @@
 	unsigned long seg;
 } mm_segment_t;
 
+#define MAX_TRAPS 10
+
 struct debug_trap {
 	int nr_trap;
-	unsigned long	addr;
-	unsigned long	insn;
+	unsigned long	addr[MAX_TRAPS];
+	unsigned long	insn[MAX_TRAPS];
 };
 
 struct thread_struct {
diff -Nru a/include/asm-m32r/resource.h b/include/asm-m32r/resource.h
--- a/include/asm-m32r/resource.h	2005-03-01 23:38:54 -08:00
+++ b/include/asm-m32r/resource.h	2005-03-01 23:38:54 -08:00
@@ -1,55 +1,6 @@
 #ifndef _ASM_M32R_RESOURCE_H
 #define _ASM_M32R_RESOURCE_H
 
-/* $Id$ */
-
-/* orig : i386 2.4.18 */
-
-/*
- * Resource limits
- */
-
-#define RLIMIT_CPU	0		/* CPU time in ms */
-#define RLIMIT_FSIZE	1		/* Maximum filesize */
-#define RLIMIT_DATA	2		/* max data size */
-#define RLIMIT_STACK	3		/* max stack size */
-#define RLIMIT_CORE	4		/* max core file size */
-#define RLIMIT_RSS	5		/* max resident set size */
-#define RLIMIT_NPROC	6		/* max number of processes */
-#define RLIMIT_NOFILE	7		/* max number of open files */
-#define RLIMIT_MEMLOCK	8		/* max locked-in-memory address space */
-#define RLIMIT_AS	9		/* address space limit */
-#define RLIMIT_LOCKS	10		/* maximum file locks held */
-#define RLIMIT_SIGPENDING 11		/* max number of pending signals */
-#define RLIMIT_MSGQUEUE	12		/* maximum bytes in POSIX mqueues */
-
-#define RLIM_NLIMITS	13
-
-/*
- * SuS says limits have to be unsigned.
- * Which makes a ton more sense anyway.
- */
-#define RLIM_INFINITY	(~0UL)
-
-#ifdef __KERNEL__
-
-#define INIT_RLIMITS					\
-{							\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{      _STK_LIM, RLIM_INFINITY },		\
-	{             0, RLIM_INFINITY },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{             0,             0 },		\
-	{      INR_OPEN,     INR_OPEN  },		\
-	{ MLOCK_LIMIT,   MLOCK_LIMIT   },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{ MAX_SIGPENDING, MAX_SIGPENDING },		\
-	{ MQ_BYTES_MAX, MQ_BYTES_MAX },			\
-}
-
-#endif /* __KERNEL__ */
+#include <asm-generic/resource.h>
 
 #endif  /* _ASM_M32R_RESOURCE_H */
diff -Nru a/include/asm-m32r/semaphore.h b/include/asm-m32r/semaphore.h
--- a/include/asm-m32r/semaphore.h	2005-03-01 23:38:53 -08:00
+++ b/include/asm-m32r/semaphore.h	2005-03-01 23:38:53 -08:00
@@ -15,19 +15,10 @@
 #include <linux/config.h>
 #include <linux/wait.h>
 #include <linux/rwsem.h>
+#include <asm/assembler.h>
 #include <asm/system.h>
 #include <asm/atomic.h>
 
-#undef LOAD
-#undef STORE
-#ifdef CONFIG_SMP
-#define LOAD	"lock"
-#define STORE	"unlock"
-#else
-#define LOAD	"ld"
-#define STORE	"st"
-#endif
-
 struct semaphore {
 	atomic_t count;
 	int sleepers;
@@ -97,9 +88,9 @@
 	__asm__ __volatile__ (
 		"# down				\n\t"
 		DCACHE_CLEAR("%0", "r4", "%1")
-		LOAD"	%0, @%1;		\n\t"
+		M32R_LOCK" %0, @%1;		\n\t"
 		"addi	%0, #-1;		\n\t"
-		STORE"	%0, @%1;		\n\t"
+		M32R_UNLOCK" %0, @%1;		\n\t"
 		: "=&r" (count)
 		: "r" (&sem->count)
 		: "memory"
@@ -128,9 +119,9 @@
 	__asm__ __volatile__ (
 		"# down_interruptible		\n\t"
 		DCACHE_CLEAR("%0", "r4", "%1")
-		LOAD"	%0, @%1;		\n\t"
+		M32R_LOCK" %0, @%1;		\n\t"
 		"addi	%0, #-1;		\n\t"
-		STORE"	%0, @%1;		\n\t"
+		M32R_UNLOCK" %0, @%1;		\n\t"
 		: "=&r" (count)
 		: "r" (&sem->count)
 		: "memory"
@@ -160,9 +151,9 @@
 	__asm__ __volatile__ (
 		"# down_trylock			\n\t"
 		DCACHE_CLEAR("%0", "r4", "%1")
-		LOAD"	%0, @%1;		\n\t"
+		M32R_LOCK" %0, @%1;		\n\t"
 		"addi	%0, #-1;		\n\t"
-		STORE"	%0, @%1;		\n\t"
+		M32R_UNLOCK" %0, @%1;		\n\t"
 		: "=&r" (count)
 		: "r" (&sem->count)
 		: "memory"
@@ -193,9 +184,9 @@
 	__asm__ __volatile__ (
 		"# up				\n\t"
 		DCACHE_CLEAR("%0", "r4", "%1")
-		LOAD"	%0, @%1;		\n\t"
+		M32R_LOCK" %0, @%1;		\n\t"
 		"addi	%0, #1;			\n\t"
-		STORE"	%0, @%1;		\n\t"
+		M32R_UNLOCK" %0, @%1;		\n\t"
 		: "=&r" (count)
 		: "r" (&sem->count)
 		: "memory"
diff -Nru a/include/asm-m32r/smp.h b/include/asm-m32r/smp.h
--- a/include/asm-m32r/smp.h	2005-03-01 23:38:51 -08:00
+++ b/include/asm-m32r/smp.h	2005-03-01 23:38:51 -08:00
@@ -92,7 +92,6 @@
 }
 
 extern void smp_send_timer(void);
-extern void calibrate_delay(void);
 extern unsigned long send_IPI_mask_phys(cpumask_t, int, int);
 
 #endif	/* not __ASSEMBLY__ */
diff -Nru a/include/asm-m32r/spinlock.h b/include/asm-m32r/spinlock.h
--- a/include/asm-m32r/spinlock.h	2005-03-01 23:39:08 -08:00
+++ b/include/asm-m32r/spinlock.h	2005-03-01 23:39:08 -08:00
@@ -20,23 +20,13 @@
 #define RW_LOCK_BIAS		 0x01000000
 #define RW_LOCK_BIAS_STR	"0x01000000"
 
-/* It seems that people are forgetting to
- * initialize their spinlocks properly, tsk tsk.
- * Remember to turn this off in 2.4. -ben
- */
-#if defined(CONFIG_DEBUG_SPINLOCK)
-#define SPINLOCK_DEBUG	1
-#else
-#define SPINLOCK_DEBUG	0
-#endif
-
 /*
  * Your basic SMP spinlocks, allowing only a single CPU anywhere
  */
 
 typedef struct {
-	volatile int lock;
-#if SPINLOCK_DEBUG
+	volatile int slock;
+#ifdef CONFIG_DEBUG_SPINLOCK
 	unsigned magic;
 #endif
 #ifdef CONFIG_PREEMPT
@@ -46,7 +36,7 @@
 
 #define SPINLOCK_MAGIC	0xdead4ead
 
-#if SPINLOCK_DEBUG
+#ifdef CONFIG_DEBUG_SPINLOCK
 #define SPINLOCK_MAGIC_INIT	, SPINLOCK_MAGIC
 #else
 #define SPINLOCK_MAGIC_INIT	/* */
@@ -63,7 +53,7 @@
  * We make no fairness assumptions. They have a cost.
  */
 
-#define spin_is_locked(x)	(*(volatile int *)(&(x)->lock) <= 0)
+#define spin_is_locked(x)	(*(volatile int *)(&(x)->slock) <= 0)
 #define spin_unlock_wait(x)	do { barrier(); } while(spin_is_locked(x))
 #define _raw_spin_lock_flags(lock, flags) _raw_spin_lock(lock)
 
@@ -80,11 +70,11 @@
 	unsigned long tmp1, tmp2;
 
 	/*
-	 * lock->lock :  =1 : unlock
-	 *            : <=0 : lock
+	 * lock->slock :  =1 : unlock
+	 *             : <=0 : lock
 	 * {
-	 *   oldval = lock->lock; <--+ need atomic operation
-	 *   lock->lock = 0;      <--+
+	 *   oldval = lock->slock; <--+ need atomic operation
+	 *   lock->slock = 0;      <--+
 	 * }
 	 */
 	__asm__ __volatile__ (
@@ -97,7 +87,7 @@
 		"unlock	%1, @%3;		\n\t"
 		"mvtc	%2, psw;		\n\t"
 		: "=&r" (oldval), "=&r" (tmp1), "=&r" (tmp2)
-		: "r" (&lock->lock)
+		: "r" (&lock->slock)
 		: "memory"
 #ifdef CONFIG_CHIP_M32700_TS1
 		, "r6"
@@ -111,22 +101,22 @@
 {
 	unsigned long tmp0, tmp1;
 
-#if SPINLOCK_DEBUG
+#ifdef CONFIG_DEBUG_SPINLOCK
 	__label__ here;
 here:
 	if (lock->magic != SPINLOCK_MAGIC) {
-		printk("eip: %p\n", &&here);
+		printk("pc: %p\n", &&here);
 		BUG();
 	}
 #endif
 	/*
-	 * lock->lock :  =1 : unlock
-	 *            : <=0 : lock
+	 * lock->slock :  =1 : unlock
+	 *             : <=0 : lock
 	 *
 	 * for ( ; ; ) {
-	 *   lock->lock -= 1;  <-- need atomic operation
-	 *   if (lock->lock == 0) break;
-	 *   for ( ; lock->lock <= 0 ; );
+	 *   lock->slock -= 1;  <-- need atomic operation
+	 *   if (lock->slock == 0) break;
+	 *   for ( ; lock->slock <= 0 ; );
 	 * }
 	 */
 	__asm__ __volatile__ (
@@ -149,7 +139,7 @@
 		"bra	2b;			\n\t"
 		LOCK_SECTION_END
 		: "=&r" (tmp0), "=&r" (tmp1)
-		: "r" (&lock->lock)
+		: "r" (&lock->slock)
 		: "memory"
 #ifdef CONFIG_CHIP_M32700_TS1
 		, "r6"
@@ -159,12 +149,12 @@
 
 static inline void _raw_spin_unlock(spinlock_t *lock)
 {
-#if SPINLOCK_DEBUG
+#ifdef CONFIG_DEBUG_SPINLOCK
 	BUG_ON(lock->magic != SPINLOCK_MAGIC);
 	BUG_ON(!spin_is_locked(lock));
 #endif
 	mb();
-	lock->lock = 1;
+	lock->slock = 1;
 }
 
 /*
@@ -179,7 +169,7 @@
  */
 typedef struct {
 	volatile int lock;
-#if SPINLOCK_DEBUG
+#ifdef CONFIG_DEBUG_SPINLOCK
 	unsigned magic;
 #endif
 #ifdef CONFIG_PREEMPT
@@ -189,7 +179,7 @@
 
 #define RWLOCK_MAGIC	0xdeaf1eed
 
-#if SPINLOCK_DEBUG
+#ifdef CONFIG_DEBUG_SPINLOCK
 #define RWLOCK_MAGIC_INIT	, RWLOCK_MAGIC
 #else
 #define RWLOCK_MAGIC_INIT	/* */
@@ -199,7 +189,17 @@
 
 #define rwlock_init(x)	do { *(x) = RW_LOCK_UNLOCKED; } while(0)
 
-#define rwlock_is_locked(x)	((x)->lock != RW_LOCK_BIAS)
+/**
+ * read_can_lock - would read_trylock() succeed?
+ * @lock: the rwlock in question.
+ */
+#define read_can_lock(x) ((int)(x)->lock > 0)
+
+/**
+ * write_can_lock - would write_trylock() succeed?
+ * @lock: the rwlock in question.
+ */
+#define write_can_lock(x) ((x)->lock == RW_LOCK_BIAS)
 
 /*
  * On x86, we implement read-write locks as a 32-bit counter
@@ -216,7 +216,7 @@
 {
 	unsigned long tmp0, tmp1;
 
-#if SPINLOCK_DEBUG
+#ifdef CONFIG_DEBUG_SPINLOCK
 	BUG_ON(rw->magic != RWLOCK_MAGIC);
 #endif
 	/*
@@ -270,7 +270,7 @@
 {
 	unsigned long tmp0, tmp1, tmp2;
 
-#if SPINLOCK_DEBUG
+#ifdef CONFIG_DEBUG_SPINLOCK
 	BUG_ON(rw->magic != RWLOCK_MAGIC);
 #endif
 	/*
diff -Nru a/include/asm-m32r/system.h b/include/asm-m32r/system.h
--- a/include/asm-m32r/system.h	2005-03-01 23:38:51 -08:00
+++ b/include/asm-m32r/system.h	2005-03-01 23:38:51 -08:00
@@ -7,6 +7,7 @@
  * for more details.
  *
  * Copyright (C) 2001  by Hiroyuki Kondo, Hirokazu Takata, and Hitoshi Yamamoto
+ * Copyright (C) 2004  Hirokazu Takata <takata at linux-m32r.org>
  */
 
 #include <linux/config.h>
@@ -73,7 +74,7 @@
 #define local_irq_disable() \
 	__asm__ __volatile__ ("clrpsw #0x40 -> nop": : :"memory")
 #else	/* CONFIG_CHIP_M32102 */
-static __inline__ void local_irq_enable(void)
+static inline void local_irq_enable(void)
 {
 	unsigned long tmpreg;
 	__asm__ __volatile__(
@@ -83,7 +84,7 @@
 	: "=&r" (tmpreg) : : "cbit", "memory");
 }
 
-static __inline__ void local_irq_disable(void)
+static inline void local_irq_disable(void)
 {
 	unsigned long tmpreg0, tmpreg1;
 	__asm__ __volatile__(
@@ -219,11 +220,7 @@
  * rmb() prevents loads being reordered across this point.
  * wmb() prevents stores being reordered across this point.
  */
-#if 0
-#define mb()   __asm__ __volatile__ ("push r0; \n\t pop r0;" : : : "memory")
-#else
-#define mb()   __asm__ __volatile__ ("" : : : "memory")
-#endif
+#define mb()   barrier()
 #define rmb()  mb()
 #define wmb()  mb()
 
@@ -298,4 +295,3 @@
 #define set_wmb(var, value) do { var = value; wmb(); } while (0)
 
 #endif  /* _ASM_M32R_SYSTEM_H */
-
diff -Nru a/include/asm-m32r/thread_info.h b/include/asm-m32r/thread_info.h
--- a/include/asm-m32r/thread_info.h	2005-03-01 23:39:16 -08:00
+++ b/include/asm-m32r/thread_info.h	2005-03-01 23:39:16 -08:00
@@ -1,12 +1,13 @@
-/* thread_info.h: i386 low-level thread information
+#ifndef _ASM_M32R_THREAD_INFO_H
+#define _ASM_M32R_THREAD_INFO_H
+
+/* thread_info.h: m32r low-level thread information
  *
  * Copyright (C) 2002  David Howells (dhowells@redhat.com)
  * - Incorporating suggestions made by Linus Torvalds and Dave Miller
+ * Copyright (C) 2004  Hirokazu Takata <takata at linux-m32r.org>
  */
 
-#ifndef _ASM_THREAD_INFO_H
-#define _ASM_THREAD_INFO_H
-
 #ifdef __KERNEL__
 
 #ifndef __ASSEMBLY__
@@ -30,7 +31,7 @@
 	__s32			preempt_count; /* 0 => preemptable, <0 => BUG */
 
 	mm_segment_t		addr_limit;	/* thread address space:
-					 	   0-0xBFFFFFFF for user-thead
+					 	   0-0xBFFFFFFF for user-thread
 						   0-0xFFFFFFFF for kernel-thread
 						*/
 	struct restart_block    restart_block;
@@ -52,7 +53,7 @@
 
 #endif
 
-#define PREEMPT_ACTIVE		0x4000000
+#define PREEMPT_ACTIVE		0x10000000
 
 /*
  * macros/functions for gaining access to the thread information structure
@@ -77,34 +78,64 @@
 #define init_thread_info	(init_thread_union.thread_info)
 #define init_stack		(init_thread_union.stack)
 
+#define THREAD_SIZE (2*PAGE_SIZE)
+
 /* how to get the thread information struct from C */
 static inline struct thread_info *current_thread_info(void)
 {
 	struct thread_info *ti;
 
 	__asm__ __volatile__ (
-		"ldi	%0, #0xffffe000;	\n\t"
-		"and	%0, sp;			\n\t"
-		: "=r" (ti)
+		"ldi	%0, #%1			\n\t"
+		"and	%0, sp			\n\t"
+		: "=r" (ti) : "i" (~(THREAD_SIZE - 1))
 	);
 
 	return ti;
 }
 
 /* thread information allocation */
-#define THREAD_SIZE (2*PAGE_SIZE)
-#define alloc_thread_info(task) \
-	((struct thread_info *) __get_free_pages(GFP_KERNEL,1))
-#define free_thread_info(ti) free_pages((unsigned long) (ti), 1)
+#if CONFIG_DEBUG_STACK_USAGE
+#define alloc_thread_info(tsk)					\
+	({							\
+		struct thread_info *ret;			\
+	 							\
+	 	ret = kmalloc(THREAD_SIZE, GFP_KERNEL);		\
+	 	if (ret)					\
+	 		memset(ret, 0, THREAD_SIZE);		\
+	 	ret;						\
+	 })
+#else
+#define alloc_thread_info(tsk) kmalloc(THREAD_SIZE, GFP_KERNEL)
+#endif
+
+#define free_thread_info(info) kfree(info)
 #define get_thread_info(ti) get_task_struct((ti)->task)
 #define put_thread_info(ti) put_task_struct((ti)->task)
 
+#define TI_FLAG_FAULT_CODE_SHIFT	28
+
+static inline void set_thread_fault_code(unsigned int val)
+{
+	struct thread_info *ti = current_thread_info();
+	ti->flags = (ti->flags & (~0 >> (32 - TI_FLAG_FAULT_CODE_SHIFT)))
+		| (val << TI_FLAG_FAULT_CODE_SHIFT);
+}
+
+static inline unsigned int get_thread_fault_code(void)
+{
+	struct thread_info *ti = current_thread_info();
+	return ti->flags >> TI_FLAG_FAULT_CODE_SHIFT;
+}
+
 #else /* !__ASSEMBLY__ */
 
+#define THREAD_SIZE	8192
+
 /* how to get the thread information struct from ASM */
 #define GET_THREAD_INFO(reg)	GET_THREAD_INFO reg
 	.macro GET_THREAD_INFO reg
-	ldi	\reg, #0xffffe000
+	ldi	\reg, #-THREAD_SIZE
 	and	\reg, sp
 	.endm
 
@@ -123,6 +154,8 @@
 #define TIF_SINGLESTEP		4	/* restore singlestep on return to user mode */
 #define TIF_IRET		5	/* return with iret */
 #define TIF_POLLING_NRFLAG	16	/* true if poll_idle() is polling TIF_NEED_RESCHED */
+					/* 31..28 fault code */
+#define TIF_MEMDIE		17
 
 #define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE)
 #define _TIF_NOTIFY_RESUME	(1<<TIF_NOTIFY_RESUME)
@@ -146,4 +179,4 @@
 
 #endif /* __KERNEL__ */
 
-#endif /* _ASM_THREAD_INFO_H */
+#endif /* _ASM_M32R_THREAD_INFO_H */
diff -Nru a/include/asm-m32r/unistd.h b/include/asm-m32r/unistd.h
--- a/include/asm-m32r/unistd.h	2005-03-01 23:38:59 -08:00
+++ b/include/asm-m32r/unistd.h	2005-03-01 23:38:59 -08:00
@@ -25,26 +25,26 @@
 #define __NR_time		 13
 #define __NR_mknod		 14
 #define __NR_chmod		 15
-#define __NR_lchown		 16
-#define __NR_break		 17
-#define __NR_oldstat		 18
+/* 16 is unused */
+/* 17 is unused */
+/* 18 is unused */
 #define __NR_lseek		 19
 #define __NR_getpid		 20
 #define __NR_mount		 21
 #define __NR_umount		 22
-#define __NR_setuid		 23
-#define __NR_getuid		 24
+/* 23 is unused */
+/* 24 is unused */
 #define __NR_stime		 25
 #define __NR_ptrace		 26
 #define __NR_alarm		 27
-#define __NR_oldfstat		 28
+/* 28 is unused */
 #define __NR_pause		 29
 #define __NR_utime		 30
-#define __NR_cacheflush		 31 /* old #define __NR_stty		 31*/
+/* 31 is unused */
 #define __NR_cachectl		 32 /* old #define __NR_gtty		 32*/
 #define __NR_access		 33
-#define __NR_nice		 34
-#define __NR_ftime		 35
+/* 34 is unused */
+/* 35 is unused */
 #define __NR_sync		 36
 #define __NR_kill		 37
 #define __NR_rename		 38
@@ -53,22 +53,22 @@
 #define __NR_dup		 41
 #define __NR_pipe		 42
 #define __NR_times		 43
-#define __NR_prof		 44
+/* 44 is unused */
 #define __NR_brk		 45
-#define __NR_setgid		 46
-#define __NR_getgid		 47
-#define __NR_signal		 48
-#define __NR_geteuid		 49
-#define __NR_getegid		 50
+/* 46 is unused */
+/* 47 is unused (getgid16) */
+/* 48 is unused */
+/* 49 is unused */
+/* 50 is unused */
 #define __NR_acct		 51
 #define __NR_umount2		 52
-#define __NR_lock		 53
+/* 53 is unused */
 #define __NR_ioctl		 54
-#define __NR_fcntl		 55
-#define __NR_mpx		 56
+/* 55 is unused (fcntl) */
+/* 56 is unused */
 #define __NR_setpgid		 57
-#define __NR_ulimit		 58
-#define __NR_oldolduname	 59
+/* 58 is unused */
+/* 59 is unused */
 #define __NR_umask		 60
 #define __NR_chroot		 61
 #define __NR_ustat		 62
@@ -76,41 +76,41 @@
 #define __NR_getppid		 64
 #define __NR_getpgrp		 65
 #define __NR_setsid		 66
-#define __NR_sigaction		 67
-#define __NR_sgetmask		 68
-#define __NR_ssetmask		 69
-#define __NR_setreuid		 70
-#define __NR_setregid		 71
-#define __NR_sigsuspend		 72
-#define __NR_sigpending		 73
+/* 67 is unused */
+/* 68 is unused*/
+/* 69 is unused*/
+/* 70 is unused */
+/* 71 is unused */
+/* 72 is unused */
+/* 73 is unused */
 #define __NR_sethostname	 74
 #define __NR_setrlimit		 75
-#define __NR_getrlimit		 76	/* Back compatible 2Gig limited rlimit */
+/* 76 is unused (old getrlimit) */
 #define __NR_getrusage		 77
 #define __NR_gettimeofday	 78
 #define __NR_settimeofday	 79
-#define __NR_getgroups		 80
-#define __NR_setgroups		 81
-#define __NR_select		 82
+/* 80 is unused */
+/* 81 is unused */
+/* 82 is unused */
 #define __NR_symlink		 83
-#define __NR_oldlstat		 84
+/* 84 is unused */
 #define __NR_readlink		 85
 #define __NR_uselib		 86
 #define __NR_swapon		 87
 #define __NR_reboot		 88
-#define __NR_readdir		 89
-#define __NR_mmap		 90
+/* 89 is unused */
+/* 90 is unused */
 #define __NR_munmap		 91
 #define __NR_truncate		 92
 #define __NR_ftruncate		 93
 #define __NR_fchmod		 94
-#define __NR_fchown		 95
+/* 95 is unused */
 #define __NR_getpriority	 96
 #define __NR_setpriority	 97
-#define __NR_profil		 98
+/* 98 is unused */
 #define __NR_statfs		 99
 #define __NR_fstatfs		100
-#define __NR_ioperm		101
+/* 101 is unused */
 #define __NR_socketcall		102
 #define __NR_syslog		103
 #define __NR_setitimer		104
@@ -118,37 +118,37 @@
 #define __NR_stat		106
 #define __NR_lstat		107
 #define __NR_fstat		108
-#define __NR_olduname		109
-#define __NR_iopl		110
+/* 109 is unused */
+/* 110 is unused */
 #define __NR_vhangup		111
-#define __NR_idle		112
-#define __NR_vm86old		113
+/* 112 is unused */
+/* 113 is unused */
 #define __NR_wait4		114
 #define __NR_swapoff		115
 #define __NR_sysinfo		116
 #define __NR_ipc		117
 #define __NR_fsync		118
-#define __NR_sigreturn		119
+/* 119 is unused */
 #define __NR_clone		120
 #define __NR_setdomainname	121
 #define __NR_uname		122
-#define __NR_modify_ldt		123
+/* 123 is unused */
 #define __NR_adjtimex		124
 #define __NR_mprotect		125
-#define __NR_sigprocmask	126
-#define __NR_create_module	127
+/* 126 is unused */
+/* 127 is unused */
 #define __NR_init_module	128
 #define __NR_delete_module	129
-#define __NR_get_kernel_syms	130
+/* 130 is unused */
 #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_afs_syscall	137 /* Syscall for Andrew File System */
-#define __NR_setfsuid		138
-#define __NR_setfsgid		139
+/* 137 is unused */
+/* 138 is unused */
+/* 139 is unused */
 #define __NR__llseek		140
 #define __NR_getdents		141
 #define __NR__newselect		142
@@ -173,14 +173,14 @@
 #define __NR_sched_rr_get_interval	161
 #define __NR_nanosleep		162
 #define __NR_mremap		163
-#define __NR_setresuid		164
-#define __NR_getresuid		165
+/* 164 is unused */
+/* 165 is unused */
 #define __NR_tas		166
-#define __NR_query_module	167
+/* 167 is unused */
 #define __NR_poll		168
 #define __NR_nfsservctl		169
-#define __NR_setresgid		170
-#define __NR_getresgid		171
+/* 170 is unused */
+/* 171 is unused */
 #define __NR_prctl              172
 #define __NR_rt_sigreturn	173
 #define __NR_rt_sigaction	174
@@ -191,14 +191,14 @@
 #define __NR_rt_sigsuspend	179
 #define __NR_pread64		180
 #define __NR_pwrite64		181
-#define __NR_chown		182
+/* 182 is unused */
 #define __NR_getcwd		183
 #define __NR_capget		184
 #define __NR_capset		185
 #define __NR_sigaltstack	186
 #define __NR_sendfile		187
-#define __NR_getpmsg		188	/* some people actually want streams */
-#define __NR_putpmsg		189	/* some people actually want streams */
+/* 188 is unused */
+/* 189 is unused */
 #define __NR_vfork		190
 #define __NR_ugetrlimit		191	/* SuS compliant getrlimit */
 #define __NR_mmap2		192
@@ -229,71 +229,71 @@
 #define __NR_pivot_root		217
 #define __NR_mincore		218
 #define __NR_madvise		219
-#define __NR_madvise1		219	/* delete when C lib stub is removed */
 #define __NR_getdents64		220
 #define __NR_fcntl64		221
-#define __NR_security           223     /* syscall for security modules */
-#define __NR_gettid             224
-#define __NR_readahead          225
-#define __NR_setxattr           226
-#define __NR_lsetxattr          227
-#define __NR_fsetxattr          228
-#define __NR_getxattr           229
-#define __NR_lgetxattr          230
-#define __NR_fgetxattr          231
-#define __NR_listxattr          232
-#define __NR_llistxattr         233
-#define __NR_flistxattr         234
-#define __NR_removexattr        235
-#define __NR_lremovexattr       236
-#define __NR_fremovexattr       237
+/* 222 is unused */
+/* 223 is unused */
+#define __NR_gettid		224
+#define __NR_readahead		225
+#define __NR_setxattr		226
+#define __NR_lsetxattr		227
+#define __NR_fsetxattr		228
+#define __NR_getxattr		229
+#define __NR_lgetxattr		230
+#define __NR_fgetxattr		231
+#define __NR_listxattr		232
+#define __NR_llistxattr		233
+#define __NR_flistxattr		234
+#define __NR_removexattr	235
+#define __NR_lremovexattr	236
+#define __NR_fremovexattr	237
 #define __NR_tkill		238
 #define __NR_sendfile64		239
 #define __NR_futex		240
 #define __NR_sched_setaffinity	241
 #define __NR_sched_getaffinity	242
-#define __NR_set_thread_area    243
-#define __NR_get_thread_area    244
-#define __NR_io_setup           245
-#define __NR_io_destroy         246
-#define __NR_io_getevents       247
-#define __NR_io_submit          248
-#define __NR_io_cancel          249
-#define __NR_fadvise64          250
-
-#define __NR_exit_group         252
-#define __NR_lookup_dcookie     253
-#define __NR_epoll_create       254
-#define __NR_epoll_ctl          255
-#define __NR_epoll_wait         256
-#define __NR_remap_file_pages   257
-#define __NR_set_tid_address    258
-#define __NR_timer_create       259
-#define __NR_timer_settime      (__NR_timer_create+1)
-#define __NR_timer_gettime      (__NR_timer_create+2)
-#define __NR_timer_getoverrun   (__NR_timer_create+3)
-#define __NR_timer_delete       (__NR_timer_create+4)
-#define __NR_clock_settime      (__NR_timer_create+5)
-#define __NR_clock_gettime      (__NR_timer_create+6)
-#define __NR_clock_getres       (__NR_timer_create+7)
-#define __NR_clock_nanosleep    (__NR_timer_create+8)
-#define __NR_statfs64           268
-#define __NR_fstatfs64          269
-#define __NR_tgkill             270
-#define __NR_utimes             271
-#define __NR_fadvise64_64       272
-#define __NR_vserver            273
-#define __NR_mbind              274
-#define __NR_get_mempolicy      275
-#define __NR_set_mempolicy      276
-#define __NR_mq_open            277
-#define __NR_mq_unlink          (__NR_mq_open+1)
-#define __NR_mq_timedsend       (__NR_mq_open+2)
-#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_sys_kexec_load    283
-#define __NR_waitid            284
+#define __NR_set_thread_area	243
+#define __NR_get_thread_area	244
+#define __NR_io_setup		245
+#define __NR_io_destroy		246
+#define __NR_io_getevents	247
+#define __NR_io_submit		248
+#define __NR_io_cancel		249
+#define __NR_fadvise64		250
+/* 251 is unused */
+#define __NR_exit_group		252
+#define __NR_lookup_dcookie	253
+#define __NR_epoll_create	254
+#define __NR_epoll_ctl		255
+#define __NR_epoll_wait		256
+#define __NR_remap_file_pages	257
+#define __NR_set_tid_address	258
+#define __NR_timer_create	259
+#define __NR_timer_settime	(__NR_timer_create+1)
+#define __NR_timer_gettime	(__NR_timer_create+2)
+#define __NR_timer_getoverrun	(__NR_timer_create+3)
+#define __NR_timer_delete	(__NR_timer_create+4)
+#define __NR_clock_settime	(__NR_timer_create+5)
+#define __NR_clock_gettime	(__NR_timer_create+6)
+#define __NR_clock_getres	(__NR_timer_create+7)
+#define __NR_clock_nanosleep	(__NR_timer_create+8)
+#define __NR_statfs64		268
+#define __NR_fstatfs64		269
+#define __NR_tgkill		270
+#define __NR_utimes		271
+#define __NR_fadvise64_64	272
+#define __NR_vserver		273
+#define __NR_mbind		274
+#define __NR_get_mempolicy	275
+#define __NR_set_mempolicy	276
+#define __NR_mq_open		277
+#define __NR_mq_unlink		(__NR_mq_open+1)
+#define __NR_mq_timedsend	(__NR_mq_open+2)
+#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_sys_kexec_load	283
+#define __NR_waitid		284
 
 #define NR_syscalls 285
 
@@ -407,14 +407,10 @@
 
 #ifdef __KERNEL__
 #define __ARCH_WANT_IPC_PARSE_VERSION
-#define __ARCH_WANT_OLD_READDIR
-#define __ARCH_WANT_OLD_STAT
 #define __ARCH_WANT_STAT64
 #define __ARCH_WANT_SYS_ALARM
 #define __ARCH_WANT_SYS_GETHOSTNAME
 #define __ARCH_WANT_SYS_PAUSE
-#define __ARCH_WANT_SYS_SGETMASK
-#define __ARCH_WANT_SYS_SIGNAL
 #define __ARCH_WANT_SYS_TIME
 #define __ARCH_WANT_SYS_UTIME
 #define __ARCH_WANT_SYS_WAITPID
@@ -422,11 +418,8 @@
 #define __ARCH_WANT_SYS_FADVISE64
 #define __ARCH_WANT_SYS_GETPGRP
 #define __ARCH_WANT_SYS_LLSEEK
-#define __ARCH_WANT_SYS_NICE
-#define __ARCH_WANT_SYS_OLD_GETRLIMIT
+#define __ARCH_WANT_SYS_OLD_GETRLIMIT /*will be unused*/
 #define __ARCH_WANT_SYS_OLDUMOUNT
-#define __ARCH_WANT_SYS_SIGPENDING
-#define __ARCH_WANT_SYS_SIGPROCMASK
 #define __ARCH_WANT_SYS_RT_SIGACTION
 #endif
 
@@ -451,7 +444,6 @@
  */
 static __inline__ _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
 
-asmlinkage int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount);
 asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
 			  unsigned long prot, unsigned long flags,
 			  unsigned long fd, unsigned long pgoff);
@@ -461,7 +453,6 @@
 asmlinkage int sys_vfork(struct pt_regs regs);
 asmlinkage int sys_pipe(unsigned long __user *fildes);
 asmlinkage int sys_ptrace(long request, long pid, long addr, long data);
-asmlinkage long sys_iopl(unsigned long unused);
 struct sigaction;
 asmlinkage long sys_rt_sigaction(int sig,
 				 const struct sigaction __user *act,
diff -Nru a/include/asm-m68k/adb_mouse.h b/include/asm-m68k/adb_mouse.h
--- a/include/asm-m68k/adb_mouse.h	2005-03-01 23:39:08 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,23 +0,0 @@
-#ifndef _ASM_ADB_MOUSE_H
-#define _ASM_ADB_MOUSE_H
-
-/*
- * linux/include/asm-m68k/adb_mouse.h
- * header file for Macintosh ADB mouse driver
- * 27-10-97 Michael Schmitz
- * copied from:
- * header file for Atari Mouse driver
- * by Robert de Vries (robert@and.nl) on 19Jul93
- */
-
-struct mouse_status {
-	char		buttons;
-	short		dx;
-	short		dy;
-	int		ready;
-	int		active;
-	wait_queue_head_t wait;
-	struct fasync_struct *fasyncptr;
-};
-
-#endif
diff -Nru a/include/asm-m68k/atari_SCCserial.h b/include/asm-m68k/atari_SCCserial.h
--- a/include/asm-m68k/atari_SCCserial.h	2005-03-01 23:38:43 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,67 +0,0 @@
-#ifndef _ATARI_SCCSERIAL_H
-#define _ATARI_SCCSERIAL_H
-
-/* Special configuration ioctls for the Atari SCC5380 Serial
- * Communications Controller
- */
-
-/* ioctl command codes */
-
-#define TIOCGATSCC	0x54c0	/* get SCC configuration */
-#define TIOCSATSCC	0x54c1	/* set SCC configuration */
-#define TIOCDATSCC	0x54c2	/* reset configuration to defaults */
-
-/* Clock sources */
-
-#define CLK_RTxC	0
-#define CLK_TRxC	1
-#define CLK_PCLK	2
-
-/* baud_bases for the common clocks in the Atari. These are the real
- * frequencies divided by 16.
- */
-
-#define SCC_BAUD_BASE_TIMC	19200	/* 0.3072 MHz from TT-MFP, Timer C */
-#define SCC_BAUD_BASE_BCLK	153600	/* 2.4576 MHz */
-#define SCC_BAUD_BASE_PCLK4	229500	/* 3.6720 MHz */
-#define SCC_BAUD_BASE_PCLK	503374	/* 8.0539763 MHz */
-#define SCC_BAUD_BASE_NONE	0		/* for not connected or unused
-						 * clock sources */
-
-#define SCC_BAUD_BASE_M147_PCLK	312500	/* 5 MHz */
-#define SCC_BAUD_BASE_M147	312500	/* 5 MHz */
-#define SCC_BAUD_BASE_MVME_PCLK	781250	/* 12.5 MHz */
-#define SCC_BAUD_BASE_MVME	625000	/* 10.000 MHz */
-#define SCC_BAUD_BASE_BVME_PCLK	781250	/* 12.5 MHz */   /* XXX ??? */
-#define SCC_BAUD_BASE_BVME	460800	/* 7.3728 MHz */
-
-/* The SCC configuration structure */
-
-struct atari_SCCserial {
-	unsigned	RTxC_base;	/* base_baud of RTxC */
-	unsigned	TRxC_base;	/* base_baud of TRxC */
-	unsigned	PCLK_base;	/* base_baud of PCLK, for both channels! */
-	struct {
-		unsigned clksrc;	/* CLK_RTxC, CLK_TRxC or CLK_PCLK */
-		unsigned divisor;	/* divisor for base baud, valid values:
-					 * see below */
-	} baud_table[17];		/* For 50, 75, 110, 135, 150, 200, 300,
-					 * 600, 1200, 1800, 2400, 4800, 9600,
-					 * 19200, 38400, 57600 and 115200 bps. The
-					 * last two could be replaced by other
-					 * rates > 38400 if they're not possible.
-					 */
-};
-
-/* The following divisors are valid:
- *
- *   - CLK_RTxC: 1 or even (1, 2 and 4 are the direct modes, > 4 use
- *               the BRG)
- *
- *   - CLK_TRxC: 1, 2 or 4 (no BRG, only direct modes possible)
- *
- *   - CLK_PCLK: >= 4 and even (no direct modes, only BRG)
- *
- */
-
-#endif /* _ATARI_SCCSERIAL_H */
diff -Nru a/include/asm-m68k/checksum.h b/include/asm-m68k/checksum.h
--- a/include/asm-m68k/checksum.h	2005-03-01 23:39:18 -08:00
+++ b/include/asm-m68k/checksum.h	2005-03-01 23:39:18 -08:00
@@ -25,11 +25,14 @@
  * better 64-bit) boundary
  */
 
-extern unsigned int csum_partial_copy_from_user(const char *src, char *dst,
-						int len, int sum, int *csum_err);
+extern unsigned int csum_partial_copy_from_user(const unsigned char *src,
+						unsigned char *dst,
+						int len, int sum,
+						int *csum_err);
 
-extern unsigned int csum_partial_copy_nocheck(const char *src, char *dst,
-					      int len, int sum);
+extern unsigned int csum_partial_copy_nocheck(const unsigned char *src,
+					      unsigned char *dst, int len,
+					      int sum);
 
 /*
  *	This is a version of ip_compute_csum() optimized for IP headers,
diff -Nru a/include/asm-m68k/cputime.h b/include/asm-m68k/cputime.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-m68k/cputime.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,6 @@
+#ifndef __M68K_CPUTIME_H
+#define __M68K_CPUTIME_H
+
+#include <asm-generic/cputime.h>
+
+#endif /* __M68K_CPUTIME_H */
diff -Nru a/include/asm-m68k/hardirq.h b/include/asm-m68k/hardirq.h
--- a/include/asm-m68k/hardirq.h	2005-03-01 23:38:57 -08:00
+++ b/include/asm-m68k/hardirq.h	2005-03-01 23:38:57 -08:00
@@ -23,13 +23,4 @@
 # error HARDIRQ_BITS is too low!
 #endif
 
-#define irq_enter()		(preempt_count() += HARDIRQ_OFFSET)
-#define irq_exit()							\
-do {									\
-		preempt_count() -= IRQ_EXIT_OFFSET;			\
-		if (!in_interrupt() && softirq_pending(smp_processor_id())) \
-			do_softirq();					\
-		preempt_enable_no_resched();				\
-} while (0)
-
 #endif
diff -Nru a/include/asm-m68k/motorola_pgalloc.h b/include/asm-m68k/motorola_pgalloc.h
--- a/include/asm-m68k/motorola_pgalloc.h	2005-03-01 23:39:18 -08:00
+++ b/include/asm-m68k/motorola_pgalloc.h	2005-03-01 23:39:18 -08:00
@@ -12,9 +12,8 @@
 {
 	pte_t *pte;
 
-	pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT);
+	pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO);
 	if (pte) {
-		clear_page(pte);
 		__flush_page_to_ram(pte);
 		flush_tlb_kernel_page(pte);
 		nocache_page(pte);
@@ -31,7 +30,7 @@
 
 static inline struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address)
 {
-	struct page *page = alloc_pages(GFP_KERNEL|__GFP_REPEAT, 0);
+	struct page *page = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0);
 	pte_t *pte;
 
 	if(!page)
@@ -39,7 +38,6 @@
 
 	pte = kmap(page);
 	if (pte) {
-		clear_page(pte);
 		__flush_page_to_ram(pte);
 		flush_tlb_kernel_page(pte);
 		nocache_page(pte);
diff -Nru a/include/asm-m68k/pgtable.h b/include/asm-m68k/pgtable.h
--- a/include/asm-m68k/pgtable.h	2005-03-01 23:39:09 -08:00
+++ b/include/asm-m68k/pgtable.h	2005-03-01 23:39:09 -08:00
@@ -1,6 +1,8 @@
 #ifndef _M68K_PGTABLE_H
 #define _M68K_PGTABLE_H
 
+#include <asm-generic/4level-fixup.h>
+
 #include <linux/config.h>
 #include <asm/setup.h>
 
diff -Nru a/include/asm-m68k/resource.h b/include/asm-m68k/resource.h
--- a/include/asm-m68k/resource.h	2005-03-01 23:38:51 -08:00
+++ b/include/asm-m68k/resource.h	2005-03-01 23:38:51 -08:00
@@ -1,51 +1,6 @@
 #ifndef _M68K_RESOURCE_H
 #define _M68K_RESOURCE_H
 
-/*
- * Resource limits
- */
-
-#define RLIMIT_CPU	0		/* CPU time in ms */
-#define RLIMIT_FSIZE	1		/* Maximum filesize */
-#define RLIMIT_DATA	2		/* max data size */
-#define RLIMIT_STACK	3		/* max stack size */
-#define RLIMIT_CORE	4		/* max core file size */
-#define RLIMIT_RSS	5		/* max resident set size */
-#define RLIMIT_NPROC	6		/* max number of processes */
-#define RLIMIT_NOFILE	7		/* max number of open files */
-#define RLIMIT_MEMLOCK	8		/* max locked-in-memory address space */
-#define RLIMIT_AS	9		/* address space limit */
-#define RLIMIT_LOCKS	10		/* maximum file locks held */
-#define RLIMIT_SIGPENDING 11		/* max number of pending signals */
-#define RLIMIT_MSGQUEUE 12		/* maximum bytes in POSIX mqueues */
-
-#define RLIM_NLIMITS	13
-
-/*
- * SuS says limits have to be unsigned.
- * Which makes a ton more sense anyway.
- */
-#define RLIM_INFINITY	(~0UL)
-
-#ifdef __KERNEL__
-
-#define INIT_RLIMITS					\
-{							\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{      _STK_LIM, RLIM_INFINITY },		\
-	{             0, RLIM_INFINITY },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{             0,             0 },		\
-	{      INR_OPEN,     INR_OPEN  },		\
-	{   MLOCK_LIMIT,   MLOCK_LIMIT },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{ MAX_SIGPENDING, MAX_SIGPENDING },		\
-	{ MQ_BYTES_MAX, MQ_BYTES_MAX },			\
-}
-
-#endif /* __KERNEL__ */
+#include <asm-generic/resource.h>
 
 #endif /* _M68K_RESOURCE_H */
diff -Nru a/include/asm-m68k/thread_info.h b/include/asm-m68k/thread_info.h
--- a/include/asm-m68k/thread_info.h	2005-03-01 23:39:07 -08:00
+++ b/include/asm-m68k/thread_info.h	2005-03-01 23:39:07 -08:00
@@ -48,6 +48,7 @@
 #define TIF_NOTIFY_RESUME	2	/* resumption notification requested */
 #define TIF_SIGPENDING		3	/* signal pending */
 #define TIF_NEED_RESCHED	4	/* rescheduling necessary */
+#define TIF_MEMDIE		5
 
 extern int thread_flag_fixme(void);
 
diff -Nru a/include/asm-m68knommu/atomic.h b/include/asm-m68knommu/atomic.h
--- a/include/asm-m68knommu/atomic.h	2005-03-01 23:38:56 -08:00
+++ b/include/asm-m68knommu/atomic.h	2005-03-01 23:38:56 -08:00
@@ -20,36 +20,79 @@
 
 static __inline__ void atomic_add(int i, atomic_t *v)
 {
-	__asm__ __volatile__("addl %1,%0" : "=m" (*v) : "d" (i), "0" (*v));
+#ifdef CONFIG_COLDFIRE
+	__asm__ __volatile__("addl %1,%0" : "+m" (*v) : "d" (i));
+#else
+	__asm__ __volatile__("addl %1,%0" : "+m" (*v) : "di" (i));
+#endif
 }
 
 static __inline__ void atomic_sub(int i, atomic_t *v)
 {
-	__asm__ __volatile__("subl %1,%0" : "=m" (*v) : "d" (i), "0" (*v));
+#ifdef CONFIG_COLDFIRE
+	__asm__ __volatile__("subl %1,%0" : "+m" (*v) : "d" (i));
+#else
+	__asm__ __volatile__("subl %1,%0" : "+m" (*v) : "di" (i));
+#endif
+}
+
+static __inline__ int atomic_sub_and_test(int i, atomic_t * v)
+{
+	char c;
+#ifdef CONFIG_COLDFIRE
+	__asm__ __volatile__("subl %2,%1; seq %0"
+			     : "=d" (c), "+m" (*v)
+			     : "d" (i));
+#else
+	__asm__ __volatile__("subl %2,%1; seq %0"
+			     : "=d" (c), "+m" (*v)
+			     : "di" (i));
+#endif
+	return c != 0;
 }
 
 static __inline__ void atomic_inc(volatile atomic_t *v)
 {
-	__asm__ __volatile__("addql #1,%0" : "=m" (*v): "0" (*v));
+	__asm__ __volatile__("addql #1,%0" : "+m" (*v));
+}
+
+/*
+ * 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.
+ */
+
+static __inline__ int atomic_inc_and_test(volatile atomic_t *v)
+{
+	char c;
+	__asm__ __volatile__("addql #1,%1; seq %0" : "=d" (c), "+m" (*v));
+	return c != 0;
 }
 
 static __inline__ void atomic_dec(volatile atomic_t *v)
 {
-	__asm__ __volatile__("subql #1,%0" : "=m" (*v): "0" (*v));
+	__asm__ __volatile__("subql #1,%0" : "+m" (*v));
 }
 
 static __inline__ int atomic_dec_and_test(volatile atomic_t *v)
 {
 	char c;
-	__asm__ __volatile__("subql #1,%1; seq %0" : "=d" (c), "=m" (*v): "1" (*v));
+	__asm__ __volatile__("subql #1,%1; seq %0" : "=d" (c), "+m" (*v));
 	return c != 0;
 }
 
-#define atomic_clear_mask(mask, v) \
-	__asm__ __volatile__("andl %1,%0" : "=m" (*v) : "id" (~(mask)),"0"(*v))
+static __inline__ void atomic_clear_mask(unsigned long mask, unsigned long *v)
+{
+	__asm__ __volatile__("andl %1,%0" : "+m" (*v) : "id" (~(mask)));
+}
 
-#define atomic_set_mask(mask, v) \
-	__asm__ __volatile__("orl %1,%0" : "=m" (*v) : "id" (mask),"0"(*v))
+static __inline__ void atomic_set_mask(unsigned long mask, unsigned long *v)
+{
+	__asm__ __volatile__("orl %1,%0" : "+m" (*v) : "id" (mask));
+}
 
 /* Atomic operations are already serializing */
 #define smp_mb__before_atomic_dec()    barrier()
@@ -87,18 +130,5 @@
 
 #define atomic_dec_return(v) atomic_sub_return(1,(v))
 #define atomic_inc_return(v) atomic_add_return(1,(v))
-
-/*
- * 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_inc_return(v) == 0)
-
-#define atomic_sub_and_test(i,v) (atomic_sub_return((i), (v)) == 0)
-#define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0)
 
 #endif /* __ARCH_M68KNOMMU_ATOMIC __ */
diff -Nru a/include/asm-m68knommu/bitops.h b/include/asm-m68knommu/bitops.h
--- a/include/asm-m68knommu/bitops.h	2005-03-01 23:38:52 -08:00
+++ b/include/asm-m68knommu/bitops.h	2005-03-01 23:38:52 -08:00
@@ -113,26 +113,20 @@
 
 static __inline__ void set_bit(int nr, volatile unsigned long * addr)
 {
-	int 	* a = (int *) addr;
-	int	mask;
-	unsigned long flags;
-
-	a += nr >> 5;
-	mask = 1 << (nr & 0x1f);
-	local_irq_save(flags);
-	*a |= mask;
-	local_irq_restore(flags);
+#ifdef CONFIG_COLDFIRE
+	__asm__ __volatile__ ("lea %0,%%a0; bset %1,(%%a0)"
+	     : "+m" (((volatile char *)addr)[(nr^31) >> 3])
+	     : "d" (nr)
+	     : "%a0", "cc");
+#else
+	__asm__ __volatile__ ("bset %1,%0"
+	     : "+m" (((volatile char *)addr)[(nr^31) >> 3])
+	     : "di" (nr)
+	     : "cc");
+#endif
 }
 
-static __inline__ void __set_bit(int nr, volatile unsigned long * addr)
-{
-	int 	* a = (int *) addr;
-	int	mask;
-
-	a += nr >> 5;
-	mask = 1 << (nr & 0x1f);
-	*a |= mask;
-}
+#define __set_bit(nr, addr) set_bit(nr, addr)
 
 /*
  * clear_bit() doesn't provide any barrier for the compiler.
@@ -142,132 +136,100 @@
 
 static __inline__ void clear_bit(int nr, volatile unsigned long * addr)
 {
-	int 	* a = (int *) addr;
-	int	mask;
-	unsigned long flags;
-
-	a += nr >> 5;
-	mask = 1 << (nr & 0x1f);
-	local_irq_save(flags);
-	*a &= ~mask;
-	local_irq_restore(flags);
+#ifdef CONFIG_COLDFIRE
+	__asm__ __volatile__ ("lea %0,%%a0; bclr %1,(%%a0)"
+	     : "+m" (((volatile char *)addr)[(nr^31) >> 3])
+	     : "d" (nr)
+	     : "%a0", "cc");
+#else
+	__asm__ __volatile__ ("bclr %1,%0"
+	     : "+m" (((volatile char *)addr)[(nr^31) >> 3])
+	     : "di" (nr)
+	     : "cc");
+#endif
 }
 
-static __inline__ void __clear_bit(int nr, volatile unsigned long * addr)
-{
-	int 	* a = (int *) addr;
-	int	mask;
-
-	a += nr >> 5;
-	mask = 1 << (nr & 0x1f);
-	*a &= ~mask;
-}
+#define __clear_bit(nr, addr) clear_bit(nr, addr)
 
 static __inline__ void change_bit(int nr, volatile unsigned long * addr)
 {
-	int mask, flags;
-	unsigned long *ADDR = (unsigned long *) addr;
-
-	ADDR += nr >> 5;
-	mask = 1 << (nr & 31);
-	local_irq_save(flags);
-	*ADDR ^= mask;
-	local_irq_restore(flags);
+#ifdef CONFIG_COLDFIRE
+	__asm__ __volatile__ ("lea %0,%%a0; bchg %1,(%%a0)"
+	     : "+m" (((volatile char *)addr)[(nr^31) >> 3])
+	     : "d" (nr)
+	     : "%a0", "cc");
+#else
+	__asm__ __volatile__ ("bchg %1,%0"
+	     : "+m" (((volatile char *)addr)[(nr^31) >> 3])
+	     : "di" (nr)
+	     : "cc");
+#endif
 }
 
-static __inline__ void __change_bit(int nr, volatile unsigned long * addr)
-{
-	int mask;
-	unsigned long *ADDR = (unsigned long *) addr;
-
-	ADDR += nr >> 5;
-	mask = 1 << (nr & 31);
-	*ADDR ^= mask;
-}
+#define __change_bit(nr, addr) change_bit(nr, addr)
 
 static __inline__ int test_and_set_bit(int nr, volatile unsigned long * addr)
 {
-	int	mask, retval;
-	volatile unsigned int *a = (volatile unsigned int *) addr;
-	unsigned long flags;
+	char retval;
 
-	a += nr >> 5;
-	mask = 1 << (nr & 0x1f);
-	local_irq_save(flags);
-	retval = (mask & *a) != 0;
-	*a |= mask;
-	local_irq_restore(flags);
+#ifdef CONFIG_COLDFIRE
+	__asm__ __volatile__ ("lea %1,%%a0; bset %2,(%%a0); sne %0"
+	     : "=d" (retval), "+m" (((volatile char *)addr)[(nr^31) >> 3])
+	     : "d" (nr)
+	     : "%a0");
+#else
+	__asm__ __volatile__ ("bset %2,%1; sne %0"
+	     : "=d" (retval), "+m" (((volatile char *)addr)[(nr^31) >> 3])
+	     : "di" (nr)
+	     /* No clobber */);
+#endif
 
 	return retval;
 }
 
-static __inline__ int __test_and_set_bit(int nr, volatile unsigned long * addr)
-{
-	int	mask, retval;
-	volatile unsigned int *a = (volatile unsigned int *) addr;
-
-	a += nr >> 5;
-	mask = 1 << (nr & 0x1f);
-	retval = (mask & *a) != 0;
-	*a |= mask;
-	return retval;
-}
+#define __test_and_set_bit(nr, addr) test_and_set_bit(nr, addr)
 
 static __inline__ int test_and_clear_bit(int nr, volatile unsigned long * addr)
 {
-	int	mask, retval;
-	volatile unsigned int *a = (volatile unsigned int *) addr;
-	unsigned long flags;
+	char retval;
 
-	a += nr >> 5;
-	mask = 1 << (nr & 0x1f);
-	local_irq_save(flags);
-	retval = (mask & *a) != 0;
-	*a &= ~mask;
-	local_irq_restore(flags);
+#ifdef CONFIG_COLDFIRE
+	__asm__ __volatile__ ("lea %1,%%a0; bclr %2,(%%a0); sne %0"
+	     : "=d" (retval), "+m" (((volatile char *)addr)[(nr^31) >> 3])
+	     : "d" (nr)
+	     : "%a0");
+#else
+	__asm__ __volatile__ ("bclr %2,%1; sne %0"
+	     : "=d" (retval), "+m" (((volatile char *)addr)[(nr^31) >> 3])
+	     : "di" (nr)
+	     /* No clobber */);
+#endif
 
 	return retval;
 }
 
-static __inline__ int __test_and_clear_bit(int nr, volatile unsigned long * addr)
-{
-	int	mask, retval;
-	volatile unsigned int *a = (volatile unsigned int *) addr;
-
-	a += nr >> 5;
-	mask = 1 << (nr & 0x1f);
-	retval = (mask & *a) != 0;
-	*a &= ~mask;
-	return retval;
-}
+#define __test_and_clear_bit(nr, addr) test_and_clear_bit(nr, addr)
 
 static __inline__ int test_and_change_bit(int nr, volatile unsigned long * addr)
 {
-	int	mask, retval;
-	volatile unsigned int *a = (volatile unsigned int *) addr;
-	unsigned long flags;
+	char retval;
 
-	a += nr >> 5;
-	mask = 1 << (nr & 0x1f);
-	local_irq_save(flags);
-	retval = (mask & *a) != 0;
-	*a ^= mask;
-	local_irq_restore(flags);
+#ifdef CONFIG_COLDFIRE
+	__asm__ __volatile__ ("lea %1,%%a0\n\tbchg %2,(%%a0)\n\tsne %0"
+	     : "=d" (retval), "+m" (((volatile char *)addr)[(nr^31) >> 3])
+	     : "d" (nr)
+	     : "%a0");
+#else
+	__asm__ __volatile__ ("bchg %2,%1; sne %0"
+	     : "=d" (retval), "+m" (((volatile char *)addr)[(nr^31) >> 3])
+	     : "di" (nr)
+	     /* No clobber */);
+#endif
 
 	return retval;
 }
 
-static __inline__ int __test_and_change_bit(int nr, volatile unsigned long * addr)
-{
-	int	mask, retval;
-	volatile unsigned int *a = (volatile unsigned int *) addr;
-
-	a += nr >> 5;
-	mask = 1 << (nr & 0x1f);
-	retval = (mask & *a) != 0;
-	*a ^= mask;
-	return retval;
-}
+#define __test_and_change_bit(nr, addr) test_and_change_bit(nr, addr)
 
 /*
  * This routine doesn't need to be atomic.
@@ -294,6 +256,8 @@
 
 #define find_first_zero_bit(addr, size) \
         find_next_zero_bit((addr), (size), 0)
+#define find_first_bit(addr, size) \
+        find_next_bit((addr), (size), 0)
 
 static __inline__ int find_next_zero_bit (void * addr, int size, int offset)
 {
@@ -385,31 +349,39 @@
 
 static __inline__ int ext2_set_bit(int nr, volatile void * addr)
 {
-	int		mask, retval;
-	unsigned long	flags;
-	volatile unsigned char	*ADDR = (unsigned char *) addr;
-
-	ADDR += nr >> 3;
-	mask = 1 << (nr & 0x07);
-	local_irq_save(flags);
-	retval = (mask & *ADDR) != 0;
-	*ADDR |= mask;
-	local_irq_restore(flags);
+	char retval;
+
+#ifdef CONFIG_COLDFIRE
+	__asm__ __volatile__ ("lea %1,%%a0; bset %2,(%%a0); sne %0"
+	     : "=d" (retval), "+m" (((volatile char *)addr)[nr >> 3])
+	     : "d" (nr)
+	     : "%a0");
+#else
+	__asm__ __volatile__ ("bset %2,%1; sne %0"
+	     : "=d" (retval), "+m" (((volatile char *)addr)[nr >> 3])
+	     : "di" (nr)
+	     /* No clobber */);
+#endif
+
 	return retval;
 }
 
 static __inline__ int ext2_clear_bit(int nr, volatile void * addr)
 {
-	int		mask, retval;
-	unsigned long	flags;
-	volatile unsigned char	*ADDR = (unsigned char *) addr;
-
-	ADDR += nr >> 3;
-	mask = 1 << (nr & 0x07);
-	local_irq_save(flags);
-	retval = (mask & *ADDR) != 0;
-	*ADDR &= ~mask;
-	local_irq_restore(flags);
+	char retval;
+
+#ifdef CONFIG_COLDFIRE
+	__asm__ __volatile__ ("lea %1,%%a0; bclr %2,(%%a0); sne %0"
+	     : "=d" (retval), "+m" (((volatile char *)addr)[nr >> 3])
+	     : "d" (nr)
+	     : "%a0");
+#else
+	__asm__ __volatile__ ("bclr %2,%1; sne %0"
+	     : "=d" (retval), "+m" (((volatile char *)addr)[nr >> 3])
+	     : "di" (nr)
+	     /* No clobber */);
+#endif
+
 	return retval;
 }
 
@@ -433,12 +405,21 @@
 
 static __inline__ int ext2_test_bit(int nr, const volatile void * addr)
 {
-	int	mask;
-	const volatile unsigned char	*ADDR = (const unsigned char *) addr;
+	char retval;
+
+#ifdef CONFIG_COLDFIRE
+	__asm__ __volatile__ ("lea %1,%%a0; btst %2,(%%a0); sne %0"
+	     : "=d" (retval)
+	     : "m" (((const volatile char *)addr)[nr >> 3]), "d" (nr)
+	     : "%a0");
+#else
+	__asm__ __volatile__ ("btst %2,%1; sne %0"
+	     : "=d" (retval)
+	     : "m" (((const volatile char *)addr)[nr >> 3]), "di" (nr)
+	     /* No clobber */);
+#endif
 
-	ADDR += nr >> 3;
-	mask = 1 << (nr & 0x07);
-	return ((mask & *ADDR) != 0);
+	return retval;
 }
 
 #define ext2_find_first_zero_bit(addr, size) \
diff -Nru a/include/asm-m68knommu/cputime.h b/include/asm-m68knommu/cputime.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-m68knommu/cputime.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,6 @@
+#ifndef __M68KNOMMU_CPUTIME_H
+#define __M68KNOMMU_CPUTIME_H
+
+#include <asm-generic/cputime.h>
+
+#endif /* __M68KNOMMU_CPUTIME_H */
diff -Nru a/include/asm-m68knommu/elf.h b/include/asm-m68knommu/elf.h
--- a/include/asm-m68knommu/elf.h	2005-03-01 23:39:09 -08:00
+++ b/include/asm-m68knommu/elf.h	2005-03-01 23:39:09 -08:00
@@ -61,22 +61,14 @@
 #define ELF_PLAT_INIT(_r, load_addr)	_r->a1 = 0
 
 #define USE_ELF_CORE_DUMP
-#ifndef CONFIG_SUN3
 #define ELF_EXEC_PAGESIZE	4096
-#else
-#define ELF_EXEC_PAGESIZE	8192
-#endif
 
 /* 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.  */
 
-#ifndef CONFIG_SUN3
 #define ELF_ET_DYN_BASE         0xD0000000UL
-#else
-#define ELF_ET_DYN_BASE         0x0D800000UL
-#endif
 
 #define ELF_CORE_COPY_REGS(pr_reg, regs)				\
 	/* Bleech. */							\
diff -Nru a/include/asm-m68knommu/hardirq.h b/include/asm-m68knommu/hardirq.h
--- a/include/asm-m68knommu/hardirq.h	2005-03-01 23:38:52 -08:00
+++ b/include/asm-m68knommu/hardirq.h	2005-03-01 23:38:52 -08:00
@@ -7,8 +7,6 @@
 
 typedef struct {
 	unsigned int __softirq_pending;
-	unsigned int __syscall_count;
-	struct task_struct * __ksoftirqd_task;
 } ____cacheline_aligned irq_cpustat_t;
 
 #include <linux/irq_cpustat.h>	/* Standard mappings for irq_cpustat_t above */
@@ -23,14 +21,5 @@
 #if (1 << HARDIRQ_BITS) < NR_IRQS
 # error HARDIRQ_BITS is too low!
 #endif
-
-#define irq_enter()		(preempt_count() += HARDIRQ_OFFSET)
-#define irq_exit()							\
-do {									\
-		preempt_count() -= IRQ_EXIT_OFFSET;			\
-		if (!in_interrupt() && softirq_pending(smp_processor_id())) \
-			do_softirq();					\
-		preempt_enable_no_resched();				\
-} while (0)
 
 #endif /* __M68K_HARDIRQ_H */
diff -Nru a/include/asm-m68knommu/keyboard.h b/include/asm-m68knommu/keyboard.h
--- a/include/asm-m68knommu/keyboard.h	2005-03-01 23:38:52 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1 +0,0 @@
-#include <asm-m68k/keyboard.h>
diff -Nru a/include/asm-m68knommu/m5206sim.h b/include/asm-m68knommu/m5206sim.h
--- a/include/asm-m68knommu/m5206sim.h	2005-03-01 23:39:17 -08:00
+++ b/include/asm-m68knommu/m5206sim.h	2005-03-01 23:39:17 -08:00
@@ -47,12 +47,12 @@
 
 #define	MCFSIM_DCRR		0x46		/* DRAM Refresh reg (r/w) */
 #define	MCFSIM_DCTR		0x4a		/* DRAM Timing reg (r/w) */
-#define	MCFSIM_DCAR0		0x4c		/* DRAM 0 Address reg(r/w) */
-#define	MCFSIM_DCMR0		0x50		/* DRAM 0 Mask reg (r/w) */
-#define	MCFSIM_DCCR0		0x57		/* DRAM 0 Control reg (r/w) */
-#define	MCFSIM_DCAR1		0x58		/* DRAM 1 Address reg (r/w) */
-#define	MCFSIM_DCMR1		0x5c		/* DRAM 1 Mask reg (r/w) */
-#define	MCFSIM_DCCR1		0x63		/* DRAM 1 Control reg (r/w) */
+#define	MCFSIM_DAR0		0x4c		/* DRAM 0 Address reg(r/w) */
+#define	MCFSIM_DMR0		0x50		/* DRAM 0 Mask reg (r/w) */
+#define	MCFSIM_DCR0		0x57		/* DRAM 0 Control reg (r/w) */
+#define	MCFSIM_DAR1		0x58		/* DRAM 1 Address reg (r/w) */
+#define	MCFSIM_DMR1		0x5c		/* DRAM 1 Mask reg (r/w) */
+#define	MCFSIM_DCR1		0x63		/* DRAM 1 Control reg (r/w) */
 
 #define	MCFSIM_CSAR0		0x64		/* CS 0 Address 0 reg (r/w) */
 #define	MCFSIM_CSMR0		0x68		/* CS 0 Mask 0 reg (r/w) */
diff -Nru a/include/asm-m68knommu/m5249sim.h b/include/asm-m68knommu/m5249sim.h
--- a/include/asm-m68knommu/m5249sim.h	2005-03-01 23:39:09 -08:00
+++ b/include/asm-m68knommu/m5249sim.h	2005-03-01 23:39:09 -08:00
@@ -116,4 +116,94 @@
 	*((volatile unsigned long *) (MCF_MBAR + MCFSIM_IPR))
 
 /****************************************************************************/
+
+#ifdef __ASSEMBLER__
+
+/*
+ *	The M5249C3 board needs a little help getting all its SIM devices
+ *	initialized at kernel start time. dBUG doesn't set much up, so
+ *	we need to do it manually.
+ */
+.macro m5249c3_setup
+	/*
+	 *	Set MBAR1 and MBAR2, just incase they are not set.
+	 */
+	movel	#0x10000001,%a0
+	movec	%a0,%MBAR			/* map MBAR region */
+	subql	#1,%a0				/* get MBAR address in a0 */
+
+	movel	#0x80000001,%a1
+	movec	%a1,#3086			/* map MBAR2 region */
+	subql	#1,%a1				/* get MBAR2 address in a1 */
+
+	/*
+	 *      Move secondary interrupts to base at 128.
+	 */
+	moveb	#0x80,%d0
+	moveb	%d0,0x16b(%a1)			/* interrupt base register */
+
+	/*
+	 *      Work around broken CSMR0/DRAM vector problem.
+	 */
+	movel	#0x001F0021,%d0			/* disable C/I bit */
+	movel	%d0,0x84(%a0)			/* set CSMR0 */
+
+	/*
+	 *	Disable the PLL firstly. (Who knows what state it is
+	 *	in here!).
+	 */
+	movel	0x180(%a1),%d0			/* get current PLL value */
+	andl	#0xfffffffe,%d0			/* PLL bypass first */
+	movel	%d0,0x180(%a1)			/* set PLL register */
+	nop
+
+#ifdef CONFIG_CLOCK_140MHz
+	/*
+	 *	Set initial clock frequency. This assumes M5249C3 board
+	 *	is fitted with 11.2896MHz crystal. It will program the
+	 *	PLL for 140MHz. Lets go fast :-)
+	 */
+	movel	#0x125a40f0,%d0			/* set for 140MHz */
+	movel	%d0,0x180(%a1)			/* set PLL register */
+	orl	#0x1,%d0
+	movel	%d0,0x180(%a1)			/* set PLL register */
+#endif
+
+	/*
+	 *	Setup CS1 for ethernet controller.
+	 *	(Setup as per M5249C3 doco).
+	 */
+	movel  #0xe0000000,%d0			/* CS1 mapped at 0xe0000000 */
+	movel  %d0,0x8c(%a0)
+	movel  #0x001f0021,%d0			/* CS1 size of 1Mb */
+	movel  %d0,0x90(%a0)
+	movew  #0x0080,%d0			/* CS1 = 16bit port, AA */
+	movew  %d0,0x96(%a0)
+
+	/*
+	 *	Setup CS2 for IDE interface.
+	 */
+	movel	#0x50000000,%d0			/* CS2 mapped at 0x50000000 */
+	movel	%d0,0x98(%a0)
+	movel	#0x001f0001,%d0			/* CS2 size of 1MB */
+	movel	%d0,0x9c(%a0)
+	movew	#0x0080,%d0			/* CS2 = 16bit, TA */
+	movew	%d0,0xa2(%a0)
+
+	movel	#0x00107000,%d0			/* IDEconfig1 */
+	movel	%d0,0x18c(%a1)
+	movel	#0x000c0400,%d0			/* IDEconfig2 */
+	movel	%d0,0x190(%a1)
+
+	movel	#0x00080000,%d0			/* GPIO19, IDE reset bit */
+	orl	%d0,0xc(%a1)			/* function GPIO19 */
+	orl	%d0,0x8(%a1)			/* enable GPIO19 as output */
+        orl	%d0,0x4(%a1)			/* de-assert IDE reset */
+.endm
+
+#define	PLATFORM_SETUP	m5249c3_setup
+
+#endif /* __ASSEMBLER__ */
+
+/****************************************************************************/
 #endif	/* m5249sim_h */
diff -Nru a/include/asm-m68knommu/m527xsim.h b/include/asm-m68knommu/m527xsim.h
--- a/include/asm-m68knommu/m527xsim.h	2005-03-01 23:39:18 -08:00
+++ b/include/asm-m68knommu/m527xsim.h	2005-03-01 23:39:18 -08:00
@@ -34,5 +34,25 @@
 #define	MCFINT_UART2		15		/* Interrupt number for UART2 */
 #define	MCFINT_PIT1		36		/* Interrupt number for PIT1 */
 
+/*
+ *	SDRAM configuration registers.
+ */
+#ifdef CONFIG_M5271EVB
+#define	MCFSIM_DCR		0x40		/* SDRAM control */
+#define	MCFSIM_DACR0		0x48		/* SDRAM base address 0 */
+#define	MCFSIM_DMR0		0x4c		/* SDRAM address mask 0 */
+#define	MCFSIM_DACR1		0x50		/* SDRAM base address 1 */
+#define	MCFSIM_DMR1		0x54		/* SDRAM address mask 1 */
+#else
+#define	MCFSIM_DMR		0x40		/* SDRAM mode */
+#define	MCFSIM_DCR		0x44		/* SDRAM control */
+#define	MCFSIM_DCFG1		0x48		/* SDRAM configuration 1 */
+#define	MCFSIM_DCFG2		0x4c		/* SDRAM configuration 2 */
+#define	MCFSIM_DBAR0		0x50		/* SDRAM base address 0 */
+#define	MCFSIM_DMR0		0x54		/* SDRAM address mask 0 */
+#define	MCFSIM_DBAR1		0x58		/* SDRAM base address 1 */
+#define	MCFSIM_DMR1		0x5c		/* SDRAM address mask 1 */
+#endif
+
 /****************************************************************************/
 #endif	/* m527xsim_h */
diff -Nru a/include/asm-m68knommu/m528xsim.h b/include/asm-m68knommu/m528xsim.h
--- a/include/asm-m68knommu/m528xsim.h	2005-03-01 23:38:44 -08:00
+++ b/include/asm-m68knommu/m528xsim.h	2005-03-01 23:38:44 -08:00
@@ -32,5 +32,14 @@
 #define	MCFINT_UART0		13		/* Interrupt number for UART0 */
 #define	MCFINT_PIT1		55		/* Interrupt number for PIT1 */
 
+/*
+ *	SDRAM configuration registers.
+ */
+#define	MCFSIM_DCR		0x44		/* SDRAM control */
+#define	MCFSIM_DACR0		0x48		/* SDRAM base address 0 */
+#define	MCFSIM_DMR0		0x4c		/* SDRAM address mask 0 */
+#define	MCFSIM_DACR1		0x50		/* SDRAM base address 1 */
+#define	MCFSIM_DMR1		0x54		/* SDRAM address mask 1 */
+
 /****************************************************************************/
 #endif	/* m528xsim_h */
diff -Nru a/include/asm-m68knommu/mcfcache.h b/include/asm-m68knommu/mcfcache.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-m68knommu/mcfcache.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,125 @@
+/****************************************************************************/
+
+/*
+ *	mcfcache.h -- ColdFire CPU cache support code
+ *
+ *	(C) Copyright 2004, Greg Ungerer <gerg@snapgear.com>
+ */
+
+/****************************************************************************/
+#ifndef	__M68KNOMMU_MCFCACHE_H
+#define	__M68KNOMMU_MCFCACHE_H
+/****************************************************************************/
+
+#include <linux/config.h>
+
+/*
+ *	The different ColdFire families have different cache arrangments.
+ *	Everything from a small linstruction only cache, to configurable
+ *	data and/or instruction cache, to unified instruction/data, to 
+ *	harvard style separate instruction and data caches.
+ */
+
+#if defined(CONFIG_M5206) || defined(CONFIG_M5206e) || defined(CONFIG_M5272)
+/*
+ *	Simple verion 2 core cache. These have instruction cache only,
+ *	we just need to invalidate it and enable it.
+ */
+.macro CACHE_ENABLE
+	movel	#0x01000000,%d0		/* invalidate cache cmd */
+	movec	%d0,%CACR		/* do invalidate cache */
+	movel	#0x80000100,%d0		/* setup cache mask */
+	movec	%d0,%CACR		/* enable cache */
+.endm
+#endif /* CONFIG_M5206 || CONFIG_M5206e || CONFIG_M5272 */
+
+#if defined(CONFIG_M527x)
+/*
+ *	New version 2 cores have a configurable split cache arrangement.
+ *	For now I am just enabling instruction cache - but ultimately I
+ *	think a split instruction/data cache would be better.
+ */
+.macro CACHE_ENABLE
+	movel	#0x01400000,%d0
+	movec	%d0,%CACR		/* invalidate cache */
+	nop
+	movel	#0x0000c000,%d0		/* set SDRAM cached only */
+	movec	%d0,%ACR0
+	movel	#0x00000000,%d0		/* no other regions cached */
+	movec	%d0,%ACR1
+	movel	#0x80400100,%d0		/* configure cache */
+	movec	%d0,%CACR		/* enable cache */
+	nop
+.endm
+#endif /* CONFIG_M527x */
+
+#if defined(CONFIG_M528x)
+/*
+ *	Cache is totally broken on early 5282 silicon. So far now we
+ *	disable its cache all together.
+ */
+.macro CACHE_ENABLE
+	movel	#0x01000000,%d0
+	movec	%d0,%CACR		/* invalidate cache */
+	nop
+	movel	#0x0000c000,%d0		/* set SDRAM cached only */
+	movec	%d0,%ACR0
+	movel	#0x00000000,%d0		/* no other regions cached */
+	movec	%d0,%ACR1
+	movel	#0x00000000,%d0		/* configure cache */
+	movec	%d0,%CACR		/* enable cache */
+	nop
+.endm
+#endif /* CONFIG_M528x */
+
+#if defined(CONFIG_M5249) || defined(CONFIG_M5307)
+/*
+ *	The version 3 core cache. Oddly enough the version 2 core 5249
+ *	has the same SDRAM and cache setup as the version 3 cores.
+ *	This is a single unified instruction/data cache.
+ */
+.macro CACHE_ENABLE
+	movel	#0x01000000,%d0		/* invalidate whole cache */
+	movec	%d0,%CACR
+	nop
+#if defined(DEBUGGER_COMPATIBLE_CACHE) || defined(CONFIG_SECUREEDGEMP3)
+	movel	#0x0000c000,%d0		/* set SDRAM cached (write-thru) */
+#else
+	movel	#0x0000c020,%d0		/* set SDRAM cached (copyback) */
+#endif
+	movec	%d0,%ACR0
+	movel	#0x00000000,%d0		/* no other regions cached */
+	movec	%d0,%ACR1
+	movel	#0xa0000200,%d0		/* enable cache */
+	movec	%d0,%CACR
+	nop
+.endm
+#endif /* CONFIG_M5249 || CONFIG_M5307 */
+
+#if defined(CONFIG_M5407)
+/*
+ *	Version 4 cores have a true hardvard style separate instruction
+ *	and data cache. Invalidate and enable cache, also enable write
+ *	buffers and branch accelerator.
+ */
+.macro CACHE_ENABLE
+	movel	#0x01040100,%d0		/* invalidate whole cache */
+	movec	%d0,%CACR
+	nop
+	movel	#0x000fc000,%d0		/* set SDRAM cached only */
+	movec	%d0, %ACR0
+	movel	#0x00000000,%d0		/* no other regions cached */
+	movec	%d0, %ACR1
+	movel	#0x000fc000,%d0		/* set SDRAM cached only */
+	movec	%d0, %ACR2
+	movel	#0x00000000,%d0		/* no other regions cached */
+	movec	%d0, %ACR3
+	movel	#0xb6088400,%d0		/* enable caches */
+	movec	%d0,%CACR
+	nop
+.endm
+#endif /* CONFIG_M5407 */
+
+
+/****************************************************************************/
+#endif	/* __M68KNOMMU_MCFCACHE_H */
diff -Nru a/include/asm-m68knommu/nap.h b/include/asm-m68knommu/nap.h
--- a/include/asm-m68knommu/nap.h	2005-03-01 23:38:52 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,96 +0,0 @@
-/****************************************************************************/
-
-/*
- *	nap.h -- Marconi/NAP support.
- *
- * 	(C) Copyright 2001, SnapGear (www.snapgear.com) 
- */
-
-/****************************************************************************/
-#ifndef	nap_h
-#define	nap_h
-/****************************************************************************/
-
-#include <linux/config.h>
-
-/****************************************************************************/
-#ifdef CONFIG_MARCONINAP
-/****************************************************************************/
-
-#ifdef CONFIG_COLDFIRE
-#include <asm/coldfire.h>
-#include <asm/mcfsim.h>
-#endif
-
-/*
- *	Command to support selecting RS232 or RS422 mode on the
- *	second COM port.
- */
-#define	TIOCSET422	0x4d01		/* Set port mode 232 or 422 */
-#define	TIOCGET422	0x4d02		/* Get current port mode */
-
-/*
- *	Low level control of the RS232/422 enable.
- */
-#define	MCFPP_PA11	0x0800
-
-#ifndef __ASSEMBLY__
-/*
- *	RS232/422 control is via the single PA11 line. Low is the RS422
- *	enable, high is RS232 mode.
- */
-static __inline__ unsigned int mcf_getpa(void)
-{
-	volatile unsigned short *pp;
-	pp = (volatile unsigned short *) (MCF_MBAR + MCFSIM_PADAT);
-	return((unsigned int) *pp);
-}
-
-static __inline__ void mcf_setpa(unsigned int mask, unsigned int bits)
-{
-	volatile unsigned short *pp;
-	unsigned long		flags;
-
-	pp = (volatile unsigned short *) (MCF_MBAR + MCFSIM_PADAT);
-	save_flags(flags); cli();
-	*pp = (*pp & ~mask) | bits;
-	restore_flags(flags);
-}
-#endif /* __ASSEMBLY__ */
-
-/****************************************************************************/
-
-#if defined(CONFIG_M5272)
-/*
- *	Marconi/NAP based hardware. DTR/DCD lines are wired to GPB lines.
- */
-#define	MCFPP_DCD0	0x0080
-#define	MCFPP_DCD1	0x0020
-#define	MCFPP_DTR0	0x0040
-#define	MCFPP_DTR1	0x0010
-
-#ifndef __ASSEMBLY__
-/*
- *	These functions defined to give quasi generic access to the
- *	PPIO bits used for DTR/DCD.
- */
-static __inline__ unsigned int mcf_getppdata(void)
-{
-	volatile unsigned short *pp;
-	pp = (volatile unsigned short *) (MCF_MBAR + MCFSIM_PBDAT);
-	return((unsigned int) *pp);
-}
-
-static __inline__ void mcf_setppdata(unsigned int mask, unsigned int bits)
-{
-	volatile unsigned short *pp;
-	pp = (volatile unsigned short *) (MCF_MBAR + MCFSIM_PBDAT);
-	*pp = (*pp & ~mask) | bits;
-}
-#endif /* __ASSEMBLY__ */
-#endif /* CONFIG_M5272 */
-
-/****************************************************************************/
-#endif /* CONFIG_MARCONINAP */
-/****************************************************************************/
-#endif	/* nap_h */
diff -Nru a/include/asm-m68knommu/page.h b/include/asm-m68knommu/page.h
--- a/include/asm-m68knommu/page.h	2005-03-01 23:38:56 -08:00
+++ b/include/asm-m68knommu/page.h	2005-03-01 23:38:56 -08:00
@@ -14,9 +14,9 @@
 #include <asm/setup.h>
 
 #if !defined(CONFIG_SMALL_TASKS) && PAGE_SHIFT < 13
-#define KTHREAD_SIZE (8192)
+#define THREAD_SIZE (8192)
 #else
-#define KTHREAD_SIZE PAGE_SIZE
+#define THREAD_SIZE PAGE_SIZE
 #endif
  
 #ifndef __ASSEMBLY__
@@ -30,6 +30,9 @@
 #define clear_user_page(page, vaddr, pg)	clear_page(page)
 #define copy_user_page(to, from, vaddr, pg)	copy_page(to, from)
 
+#define alloc_zeroed_user_highpage(vma, vaddr) alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO, vma, vaddr)
+#define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE
+
 /*
  * These are used to make use of C type-checking..
  */
@@ -79,14 +82,11 @@
 #define __pa(vaddr)		virt_to_phys((void *)vaddr)
 #define __va(paddr)		phys_to_virt((unsigned long)paddr)
 
-#define MAP_NR(addr)		(((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT)
-
 #define virt_to_pfn(kaddr)	(__pa(kaddr) >> PAGE_SHIFT)
 #define pfn_to_virt(pfn)	__va((pfn) << PAGE_SHIFT)
 
 #define virt_to_page(addr)	(mem_map + (((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT))
 #define page_to_virt(page)	((((page) - mem_map) << PAGE_SHIFT) + PAGE_OFFSET)
-#define VALID_PAGE(page)	((page - mem_map) < max_mapnr)
 
 #define pfn_to_page(pfn)	virt_to_page(pfn_to_virt(pfn))
 #define page_to_pfn(page)	virt_to_pfn(page_to_virt(page))
diff -Nru a/include/asm-m68knommu/pgtable.h b/include/asm-m68knommu/pgtable.h
--- a/include/asm-m68knommu/pgtable.h	2005-03-01 23:38:58 -08:00
+++ b/include/asm-m68knommu/pgtable.h	2005-03-01 23:38:58 -08:00
@@ -1,6 +1,8 @@
 #ifndef _M68KNOMMU_PGTABLE_H
 #define _M68KNOMMU_PGTABLE_H
 
+#include <asm-generic/4level-fixup.h>
+
 /*
  * (C) Copyright 2000-2002, Greg Ungerer <gerg@snapgear.com>
  */
diff -Nru a/include/asm-m68knommu/processor.h b/include/asm-m68knommu/processor.h
--- a/include/asm-m68knommu/processor.h	2005-03-01 23:38:58 -08:00
+++ b/include/asm-m68knommu/processor.h	2005-03-01 23:38:58 -08:00
@@ -55,11 +55,6 @@
  */
 #define TASK_UNMAPPED_BASE	0
 
-/*
- * Bus types
- */
-#define MCA_bus 0
-
 /* 
  * if you change this structure, you must change the code and offsets
  * in m68k/machasm.S
@@ -126,7 +121,7 @@
     ({			\
 	unsigned long eip = 0;	 \
 	if ((tsk)->thread.esp0 > PAGE_SIZE && \
-	    MAP_NR((tsk)->thread.esp0) < max_mapnr) \
+	    (virt_addr_valid((tsk)->thread.esp0))) \
 	      eip = ((struct pt_regs *) (tsk)->thread.esp0)->pc; \
 	eip; })
 #define	KSTK_ESP(tsk)	((tsk) == current ? rdusp() : (tsk)->thread.usp)
diff -Nru a/include/asm-m68knommu/thread_info.h b/include/asm-m68knommu/thread_info.h
--- a/include/asm-m68knommu/thread_info.h	2005-03-01 23:38:56 -08:00
+++ b/include/asm-m68knommu/thread_info.h	2005-03-01 23:38:56 -08:00
@@ -12,12 +12,6 @@
 
 #ifdef __KERNEL__
 
-/*
- * Size of kernel stack for each process. This must be a power of 2...
- */
-#define THREAD_SIZE		8192	/* 2 pages */
-
-
 #ifndef __ASSEMBLY__
 
 /*
@@ -59,7 +53,7 @@
 		"move.l	%%sp, %0 \n\t"
 		"and.l	%1, %0"
 		: "=&d"(ti)
-		: "d" (~(THREAD_SIZE-1))
+		: "di" (~(THREAD_SIZE-1))
 		);
 	return ti;
 }
@@ -91,6 +85,7 @@
 #define TIF_NEED_RESCHED	3	/* rescheduling necessary */
 #define TIF_POLLING_NRFLAG	4	/* true if poll_idle() is polling
 					   TIF_NEED_RESCHED */
+#define TIF_MEMDIE		5
 
 /* as above, but as bit values */
 #define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE)
diff -Nru a/include/asm-mips/addrspace.h b/include/asm-mips/addrspace.h
--- a/include/asm-mips/addrspace.h	2005-03-01 23:38:44 -08:00
+++ b/include/asm-mips/addrspace.h	2005-03-01 23:38:44 -08:00
@@ -126,6 +126,7 @@
     || defined (CONFIG_CPU_R4X00)					\
     || defined (CONFIG_CPU_R5000)					\
     || defined (CONFIG_CPU_NEVADA)					\
+    || defined (CONFIG_CPU_TX49XX)					\
     || defined (CONFIG_CPU_MIPS64)
 #define	KUSIZE			0x0000010000000000	/* 2^^40 */
 #define	KUSIZE_64		0x0000010000000000	/* 2^^40 */
diff -Nru a/include/asm-mips/bitops.h b/include/asm-mips/bitops.h
--- a/include/asm-mips/bitops.h	2005-03-01 23:38:52 -08:00
+++ b/include/asm-mips/bitops.h	2005-03-01 23:38:52 -08:00
@@ -92,7 +92,7 @@
 		__bi_flags;
 
 		a += nr >> SZLONG_LOG;
-		mask = 1 << (nr & SZLONG_MASK);
+		mask = 1UL << (nr & SZLONG_MASK);
 		__bi_local_irq_save(flags);
 		*a |= mask;
 		__bi_local_irq_restore(flags);
@@ -152,7 +152,7 @@
 		__bi_flags;
 
 		a += nr >> SZLONG_LOG;
-		mask = 1 << (nr & SZLONG_MASK);
+		mask = 1UL << (nr & SZLONG_MASK);
 		__bi_local_irq_save(flags);
 		*a &= ~mask;
 		__bi_local_irq_restore(flags);
@@ -214,7 +214,7 @@
 		__bi_flags;
 
 		a += nr >> SZLONG_LOG;
-		mask = 1 << (nr & SZLONG_MASK);
+		mask = 1UL << (nr & SZLONG_MASK);
 		__bi_local_irq_save(flags);
 		*a ^= mask;
 		__bi_local_irq_restore(flags);
@@ -293,7 +293,7 @@
 		__bi_flags;
 
 		a += nr >> SZLONG_LOG;
-		mask = 1 << (nr & SZLONG_MASK);
+		mask = 1UL << (nr & SZLONG_MASK);
 		__bi_local_irq_save(flags);
 		retval = (mask & *a) != 0;
 		*a |= mask;
@@ -320,7 +320,7 @@
 	int retval;
 
 	a += nr >> SZLONG_LOG;
-	mask = 1 << (nr & SZLONG_MASK);
+	mask = 1UL << (nr & SZLONG_MASK);
 	retval = (mask & *a) != 0;
 	*a |= mask;
 
@@ -385,7 +385,7 @@
 		__bi_flags;
 
 		a += nr >> SZLONG_LOG;
-		mask = 1 << (nr & SZLONG_MASK);
+		mask = 1UL << (nr & SZLONG_MASK);
 		__bi_local_irq_save(flags);
 		retval = (mask & *a) != 0;
 		*a &= ~mask;
@@ -474,7 +474,7 @@
 		__bi_flags;
 
 		a += nr >> SZLONG_LOG;
-		mask = 1 << (nr & SZLONG_MASK);
+		mask = 1UL << (nr & SZLONG_MASK);
 		__bi_local_irq_save(flags);
 		retval = (mask & *a) != 0;
 		*a ^= mask;
diff -Nru a/include/asm-mips/bootinfo.h b/include/asm-mips/bootinfo.h
--- a/include/asm-mips/bootinfo.h	2005-03-01 23:38:53 -08:00
+++ b/include/asm-mips/bootinfo.h	2005-03-01 23:38:53 -08:00
@@ -195,6 +195,7 @@
 #define  MACH_CASIO_E55		5	/* CASIO CASSIOPEIA E-10/15/55/65 */
 #define  MACH_TANBAC_TB0226	6	/* TANBAC TB0226 (Mbase) */
 #define  MACH_TANBAC_TB0229	7	/* TANBAC TB0229 (VR4131DIMM) */
+#define  MACH_NEC_CMBVR4133	8	/* CMB VR4133 Board */
 
 #define MACH_GROUP_HP_LJ	20	/* Hewlett Packard LaserJet	*/
 #define  MACH_HP_LASERJET	1
diff -Nru a/include/asm-mips/break.h b/include/asm-mips/break.h
--- a/include/asm-mips/break.h	2005-03-01 23:39:08 -08:00
+++ b/include/asm-mips/break.h	2005-03-01 23:39:08 -08:00
@@ -27,7 +27,7 @@
 #define BRK_STACKOVERFLOW 9	/* For Ada stackchecking */
 #define BRK_NORLD	10	/* No rld found - not used by Linux/MIPS */
 #define _BRK_THREADBP	11	/* For threads, user bp (used by debuggers) */
-#define BRK_MULOVF	1023	/* Multiply overflow */
 #define BRK_BUG		512	/* Used by BUG() */
+#define BRK_MULOVF	1023	/* Multiply overflow */
 
 #endif /* __ASM_BREAK_H */
diff -Nru a/include/asm-mips/checksum.h b/include/asm-mips/checksum.h
--- a/include/asm-mips/checksum.h	2005-03-01 23:38:52 -08:00
+++ b/include/asm-mips/checksum.h	2005-03-01 23:38:52 -08:00
@@ -34,15 +34,15 @@
  * this is a new version of the above that records errors it finds in *errp,
  * but continues and zeros the rest of the buffer.
  */
-unsigned int csum_partial_copy_from_user(const char *src, char *dst, int len,
+unsigned int csum_partial_copy_from_user(const unsigned char *src, unsigned char *dst, int len,
                                          unsigned int sum, int *errp);
 
 /*
  * Copy and checksum to user
  */
 #define HAVE_CSUM_COPY_USER
-static inline unsigned int csum_and_copy_to_user (const char *src, 
-						  char __user *dst,
+static inline unsigned int csum_and_copy_to_user (const unsigned char *src,
+						  unsigned char __user *dst,
 						  int len, int sum,
 						  int *err_ptr)
 {
@@ -61,8 +61,8 @@
  * the same as csum_partial, but copies from user space (but on MIPS
  * we have just one address space, so this is identical to the above)
  */
-unsigned int csum_partial_copy_nocheck(const char *src, char *dst, int len,
-				       unsigned int sum);
+unsigned int csum_partial_copy_nocheck(const unsigned char *src, unsigned char *dst,
+				       int len, unsigned int sum);
 
 /*
  *	Fold a partial checksum without adding pseudo headers
diff -Nru a/include/asm-mips/compat.h b/include/asm-mips/compat.h
--- a/include/asm-mips/compat.h	2005-03-01 23:39:07 -08:00
+++ b/include/asm-mips/compat.h	2005-03-01 23:39:07 -08:00
@@ -137,5 +137,8 @@
 
 	return (void *) (regs->regs[29] - len);
 }
+#if defined (__MIPSEL__)
+#define __COMPAT_ENDIAN_SWAP__ 	1
+#endif
 
 #endif /* _ASM_COMPAT_H */
diff -Nru a/include/asm-mips/cpu-features.h b/include/asm-mips/cpu-features.h
--- a/include/asm-mips/cpu-features.h	2005-03-01 23:39:09 -08:00
+++ b/include/asm-mips/cpu-features.h	2005-03-01 23:39:09 -08:00
@@ -3,11 +3,13 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2003 Ralf Baechle
+ * Copyright (C) 2003, 2004 Ralf Baechle
  */
 #ifndef __ASM_CPU_FEATURES_H
 #define __ASM_CPU_FEATURES_H
 
+#include <linux/config.h>
+
 #include <asm/cpu.h>
 #include <asm/cpu-info.h>
 #include <cpu-feature-overrides.h>
@@ -72,6 +74,25 @@
 #endif
 #ifndef cpu_has_ic_fills_f_dc
 #define cpu_has_ic_fills_f_dc	(cpu_data[0].icache.flags & MIPS_CACHE_IC_F_DC)
+#endif
+
+/*
+ * I-Cache snoops remote store.  This only matters on SMP.  Some multiprocessors
+ * such as the R10000 have I-Caches that snoop local stores; the embedded ones
+ * don't.  For maintaining I-cache coherency this means we need to flush the
+ * D-cache all the way back to whever the I-cache does refills from, so the
+ * I-cache has a chance to see the new data at all.  Then we have to flush the
+ * I-cache also.
+ * Note we may have been rescheduled and may no longer be running on the CPU
+ * that did the store so we can't optimize this into only doing the flush on
+ * the local CPU.
+ */
+#ifndef cpu_icache_snoops_remote_store
+#ifdef CONFIG_SMP
+#define cpu_icache_snoops_remote_store	(cpu_data[0].icache.flags & MIPS_IC_SNOOPS_REMOTE)
+#else
+#define cpu_icache_snoops_remote_store	1
+#endif
 #endif
 
 /*
diff -Nru a/include/asm-mips/cpu-info.h b/include/asm-mips/cpu-info.h
--- a/include/asm-mips/cpu-info.h	2005-03-01 23:38:57 -08:00
+++ b/include/asm-mips/cpu-info.h	2005-03-01 23:38:57 -08:00
@@ -37,6 +37,7 @@
 #define MIPS_CACHE_VTAG		0x00000002	/* Virtually tagged cache */
 #define MIPS_CACHE_ALIASES	0x00000004	/* Cache could have aliases */
 #define MIPS_CACHE_IC_F_DC	0x00000008	/* Ic can refill from D-cache */
+#define MIPS_IC_SNOOPS_REMOTE	0x00000010	/* Ic snoops remote stores */
 
 struct cpuinfo_mips {
 	unsigned long		udelay_val;
diff -Nru a/include/asm-mips/cputime.h b/include/asm-mips/cputime.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-mips/cputime.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,6 @@
+#ifndef __MIPS_CPUTIME_H
+#define __MIPS_CPUTIME_H
+
+#include <asm-generic/cputime.h>
+
+#endif /* __MIPS_CPUTIME_H */
diff -Nru a/include/asm-mips/debug.h b/include/asm-mips/debug.h
--- a/include/asm-mips/debug.h	2005-03-01 23:38:54 -08:00
+++ b/include/asm-mips/debug.h	2005-03-01 23:38:54 -08:00
@@ -29,9 +29,9 @@
 #include <linux/kernel.h>
 
 #define db_assert(x)  if (!(x)) { \
-	panic("assertion failed at %s:%d: %s\n", __FILE__, __LINE__, #x); }
+	panic("assertion failed at %s:%d: %s", __FILE__, __LINE__, #x); }
 #define db_warn(x)  if (!(x)) { \
-	printk(KERN_WARNING "warning at %s:%d: %s\n", __FILE__, __LINE__, #x); }
+	printk(KERN_WARNING "warning at %s:%d: %s", __FILE__, __LINE__, #x); }
 #define db_verify(x, y) db_assert(x y)
 #define db_verify_warn(x, y) db_warn(x y)
 #define db_run(x)  do { x; } while (0)
diff -Nru a/include/asm-mips/elf.h b/include/asm-mips/elf.h
--- a/include/asm-mips/elf.h	2005-03-01 23:38:56 -08:00
+++ b/include/asm-mips/elf.h	2005-03-01 23:38:56 -08:00
@@ -23,7 +23,8 @@
 #define EF_MIPS_ABI_O64		0x00002000	/* O32 extended for 64 bit.  */
 
 #define PT_MIPS_REGINFO		0x70000000
-#define PT_MIPS_OPTIONS		0x70000001
+#define PT_MIPS_RTPROC		0x70000001
+#define PT_MIPS_OPTIONS		0x70000002
 
 /* Flags in the e_flags field of the header */
 #define EF_MIPS_NOREORDER	0x00000001
@@ -40,9 +41,10 @@
 #define DT_MIPS_ICHECKSUM	0x70000003
 #define DT_MIPS_IVERSION	0x70000004
 #define DT_MIPS_FLAGS		0x70000005
-  #define RHF_NONE		  0
-  #define RHF_HARDWAY		  1
-  #define RHF_NOTPOT		  2
+	#define RHF_NONE	0x00000000
+	#define RHF_HARDWAY	0x00000001
+	#define RHF_NOTPOT	0x00000002
+	#define RHF_SGI_ONLY	0x00000010
 #define DT_MIPS_BASE_ADDRESS	0x70000006
 #define DT_MIPS_CONFLICT	0x70000008
 #define DT_MIPS_LIBLIST		0x70000009
@@ -222,17 +224,21 @@
 
 #endif /* CONFIG_MIPS64 */
 
+extern void dump_regs(elf_greg_t *, struct pt_regs *regs);
+extern int dump_task_fpu(struct task_struct *, elf_fpregset_t *);
+
+#define ELF_CORE_COPY_REGS(elf_regs, regs)			\
+	dump_regs((elf_greg_t *)&(elf_regs), regs);
+#define ELF_CORE_COPY_FPREGS(tsk, elf_fpregs)			\
+	dump_task_fpu(tsk, elf_fpregs)
+
 #endif /* __KERNEL__ */
 
 /* This one accepts IRIX binaries.  */
-#define irix_elf_check_arch(hdr)	((hdr)->e_machine == EM_MIPS)
+#define irix_elf_check_arch(hdr)	((hdr)->e_flags & RHF_SGI_ONLY)
 
 #define USE_ELF_CORE_DUMP
 #define ELF_EXEC_PAGESIZE	PAGE_SIZE
-
-#define ELF_CORE_COPY_REGS(_dest,_regs)				\
-	memcpy((char *) &_dest, (char *) _regs,			\
-	       sizeof(struct pt_regs));
 
 /* This yields a mask that user programs can use to figure out what
    instruction set this cpu supports.  This could be done in userspace,
diff -Nru a/include/asm-mips/gt64120.h b/include/asm-mips/gt64120.h
--- a/include/asm-mips/gt64120.h	2005-03-01 23:39:07 -08:00
+++ b/include/asm-mips/gt64120.h	2005-03-01 23:39:07 -08:00
@@ -1,6 +1,9 @@
 /*
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+ * Copyright (C) 2000, 2004, 2005  MIPS Technologies, Inc.
+ *	All rights reserved.
+ *	Authors: Carsten Langgaard <carstenl@mips.com>
+ *		 Maciej W. Rozycki <macro@mips.com>
+ * Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org)
  *
  *  This program is free software; you can distribute it and/or modify it
  *  under the terms of the GNU General Public License (Version 2) as
@@ -18,20 +21,20 @@
 #ifndef _ASM_GT64120_H
 #define _ASM_GT64120_H
 
-#include <linux/config.h>
 #include <asm/addrspace.h>
 #include <asm/byteorder.h>
 
-#define MSK(n)                    ((1 << (n)) - 1)
+#define MSK(n)			((1 << (n)) - 1)
 
 /*
  *  Register offset addresses
  */
+/* CPU Configuration.  */
 #define GT_CPU_OFS		0x000
 
-/*
- * Interrupt Registers
- */
+#define GT_MULTI_OFS		0x120
+
+/* CPU Address Decode.  */
 #define GT_SCS10LD_OFS		0x008
 #define GT_SCS10HD_OFS		0x010
 #define GT_SCS32LD_OFS		0x018
@@ -45,6 +48,7 @@
 #define GT_PCI0M0LD_OFS		0x058
 #define GT_PCI0M0HD_OFS		0x060
 #define GT_ISD_OFS		0x068
+
 #define GT_PCI0M1LD_OFS		0x080
 #define GT_PCI0M1HD_OFS		0x088
 #define GT_PCI1IOLD_OFS		0x090
@@ -53,10 +57,14 @@
 #define GT_PCI1M0HD_OFS		0x0a8
 #define GT_PCI1M1LD_OFS		0x0b0
 #define GT_PCI1M1HD_OFS		0x0b8
+#define GT_PCI1M1LD_OFS		0x0b0
+#define GT_PCI1M1HD_OFS		0x0b8
+
+#define GT_SCS10AR_OFS		0x0d0
+#define GT_SCS32AR_OFS		0x0d8
+#define GT_CS20R_OFS		0x0e0
+#define GT_CS3BOOTR_OFS		0x0e8
 
-/*
- * GT64120A only
- */
 #define GT_PCI0IOREMAP_OFS	0x0f0
 #define GT_PCI0M0REMAP_OFS	0x0f8
 #define GT_PCI0M1REMAP_OFS	0x100
@@ -64,6 +72,19 @@
 #define GT_PCI1M0REMAP_OFS	0x110
 #define GT_PCI1M1REMAP_OFS	0x118
 
+/* CPU Error Report.  */
+#define GT_CPUERR_ADDRLO_OFS	0x070
+#define GT_CPUERR_ADDRHI_OFS	0x078
+
+#define GT_CPUERR_DATALO_OFS	0x128			/* GT-64120A only  */
+#define GT_CPUERR_DATAHI_OFS	0x130			/* GT-64120A only  */
+#define GT_CPUERR_PARITY_OFS	0x138			/* GT-64120A only  */
+
+/* CPU Sync Barrier.  */
+#define GT_PCI0SYNC_OFS		0x0c0
+#define GT_PCI1SYNC_OFS		0x0c8
+
+/* SDRAM and Device Address Decode.  */
 #define GT_SCS0LD_OFS		0x400
 #define GT_SCS0HD_OFS		0x404
 #define GT_SCS1LD_OFS		0x408
@@ -83,37 +104,138 @@
 #define GT_BOOTLD_OFS		0x440
 #define GT_BOOTHD_OFS		0x444
 
-#define GT_SDRAM_B0_OFS	    	0x44c
+#define GT_ADERR_OFS		0x470
+
+/* SDRAM Configuration.  */
 #define GT_SDRAM_CFG_OFS	0x448
-#define GT_SDRAM_B2_OFS		0x454
+
 #define GT_SDRAM_OPMODE_OFS	0x474
 #define GT_SDRAM_BM_OFS		0x478
 #define GT_SDRAM_ADDRDECODE_OFS	0x47c
 
-#define GT_PCI0_CMD_OFS		0xc00	/* GT64120A only */
+/* SDRAM Parameters.  */
+#define GT_SDRAM_B0_OFS		0x44c
+#define GT_SDRAM_B1_OFS		0x450
+#define GT_SDRAM_B2_OFS		0x454
+#define GT_SDRAM_B3_OFS		0x458
+
+/* Device Parameters.  */
+#define GT_DEV_B0_OFS		0x45c
+#define GT_DEV_B1_OFS		0x460
+#define GT_DEV_B2_OFS		0x464
+#define GT_DEV_B3_OFS		0x468
+#define GT_DEV_BOOT_OFS		0x46c
+
+/* ECC.  */
+#define GT_ECC_ERRDATALO	0x480			/* GT-64120A only  */
+#define GT_ECC_ERRDATAHI	0x484			/* GT-64120A only  */
+#define GT_ECC_MEM		0x488			/* GT-64120A only  */
+#define GT_ECC_CALC		0x48c			/* GT-64120A only  */
+#define GT_ECC_ERRADDR		0x490			/* GT-64120A only  */
+
+/* DMA Record.  */
+#define GT_DMA0_CNT_OFS		0x800
+#define GT_DMA1_CNT_OFS		0x804
+#define GT_DMA2_CNT_OFS		0x808
+#define GT_DMA3_CNT_OFS		0x80c
+#define GT_DMA0_SA_OFS		0x810
+#define GT_DMA1_SA_OFS		0x814
+#define GT_DMA2_SA_OFS		0x818
+#define GT_DMA3_SA_OFS		0x81c
+#define GT_DMA0_DA_OFS		0x820
+#define GT_DMA1_DA_OFS		0x824
+#define GT_DMA2_DA_OFS		0x828
+#define GT_DMA3_DA_OFS		0x82c
+#define GT_DMA0_NEXT_OFS	0x830
+#define GT_DMA1_NEXT_OFS	0x834
+#define GT_DMA2_NEXT_OFS	0x838
+#define GT_DMA3_NEXT_OFS	0x83c
+
+#define GT_DMA0_CUR_OFS		0x870
+#define GT_DMA1_CUR_OFS		0x874
+#define GT_DMA2_CUR_OFS		0x878
+#define GT_DMA3_CUR_OFS		0x87c
+
+/* DMA Channel Control.  */
+#define GT_DMA0_CTRL_OFS	0x840
+#define GT_DMA1_CTRL_OFS	0x844
+#define GT_DMA2_CTRL_OFS	0x848
+#define GT_DMA3_CTRL_OFS	0x84c
+
+/* DMA Arbiter.  */
+#define GT_DMA_ARB_OFS		0x860
+
+/* Timer/Counter.  */
+#define GT_TC0_OFS		0x850
+#define GT_TC1_OFS		0x854
+#define GT_TC2_OFS		0x858
+#define GT_TC3_OFS		0x85c
+
+#define GT_TC_CONTROL_OFS	0x864
+
+/* PCI Internal.  */
+#define GT_PCI0_CMD_OFS		0xc00
 #define GT_PCI0_TOR_OFS		0xc04
-#define GT_PCI0_BS_SCS10_OFS    0xc08
-#define GT_PCI0_BS_SCS32_OFS    0xc0c
-#define GT_INTRCAUSE_OFS	0xc18
-#define GT_INTRMASK_OFS		0xc1c	/* GT64120A only */
+#define GT_PCI0_BS_SCS10_OFS	0xc08
+#define GT_PCI0_BS_SCS32_OFS	0xc0c
+#define GT_PCI0_BS_CS20_OFS	0xc10
+#define GT_PCI0_BS_CS3BT_OFS	0xc14
+
+#define GT_PCI1_IACK_OFS	0xc30
 #define GT_PCI0_IACK_OFS	0xc34
+
 #define GT_PCI0_BARE_OFS	0xc3c
-#define GT_HINTRCAUSE_OFS	0xc98	/* GT64120A only */
-#define GT_HINTRMASK_OFS	0xc9c	/* GT64120A only */
-#define GT_PCI1_CFGADDR_OFS	0xcf0	/* GT64120A only */
-#define GT_PCI1_CFGDATA_OFS	0xcf4	/* GT64120A only */
+#define GT_PCI0_PREFMBR_OFS	0xc40
+
+#define GT_PCI0_SCS10_BAR_OFS	0xc48
+#define GT_PCI0_SCS32_BAR_OFS	0xc4c
+#define GT_PCI0_CS20_BAR_OFS	0xc50
+#define GT_PCI0_CS3BT_BAR_OFS	0xc54
+#define GT_PCI0_SSCS10_BAR_OFS	0xc58
+#define GT_PCI0_SSCS32_BAR_OFS	0xc5c
+
+#define GT_PCI0_SCS3BT_BAR_OFS	0xc64
+
+#define GT_PCI1_CMD_OFS		0xc80
+#define GT_PCI1_TOR_OFS		0xc84
+#define GT_PCI1_BS_SCS10_OFS	0xc88
+#define GT_PCI1_BS_SCS32_OFS	0xc8c
+#define GT_PCI1_BS_CS20_OFS	0xc90
+#define GT_PCI1_BS_CS3BT_OFS	0xc94
+
+#define GT_PCI1_BARE_OFS	0xcbc
+#define GT_PCI1_PREFMBR_OFS	0xcc0
+
+#define GT_PCI1_SCS10_BAR_OFS	0xcc8
+#define GT_PCI1_SCS32_BAR_OFS	0xccc
+#define GT_PCI1_CS20_BAR_OFS	0xcd0
+#define GT_PCI1_CS3BT_BAR_OFS	0xcd4
+#define GT_PCI1_SSCS10_BAR_OFS	0xcd8
+#define GT_PCI1_SSCS32_BAR_OFS	0xcdc
+
+#define GT_PCI1_SCS3BT_BAR_OFS	0xce4
+
+#define GT_PCI1_CFGADDR_OFS	0xcf0
+#define GT_PCI1_CFGDATA_OFS	0xcf4
 #define GT_PCI0_CFGADDR_OFS	0xcf8
 #define GT_PCI0_CFGDATA_OFS	0xcfc
 
+/* Interrupts.  */
+#define GT_INTRCAUSE_OFS	0xc18
+#define GT_INTRMASK_OFS		0xc1c
+
+#define GT_PCI0_ICMASK_OFS	0xc24
+#define GT_PCI0_SERR0MASK_OFS	0xc28
+
+#define GT_CPU_INTSEL_OFS	0xc70
+#define GT_PCI0_INTSEL_OFS	0xc74
+
+#define GT_HINTRCAUSE_OFS	0xc98
+#define GT_HINTRMASK_OFS	0xc9c
+
+#define GT_PCI0_HICMASK_OFS	0xca4
+#define GT_PCI1_SERR1MASK_OFS	0xca8
 
-/*
- * Timer/Counter.  GT64120A only.
- */
-#define GT_TC0_OFS		0x850
-#define GT_TC1_OFS		0x854
-#define GT_TC2_OFS		0x858
-#define GT_TC3_OFS		0x85C
-#define GT_TC_CONTROL_OFS	0x864
 
 /*
  * I2O Support Registers
@@ -167,9 +289,9 @@
 /*
  *  Register encodings
  */
-#define GT_CPU_ENDIAN_SHF       12
-#define GT_CPU_ENDIAN_MSK       (MSK(1) << GT_CPU_ENDIAN_SHF)
-#define GT_CPU_ENDIAN_BIT       GT_CPU_ENDIAN_MSK
+#define GT_CPU_ENDIAN_SHF	12
+#define GT_CPU_ENDIAN_MSK	(MSK(1) << GT_CPU_ENDIAN_SHF)
+#define GT_CPU_ENDIAN_BIT	GT_CPU_ENDIAN_MSK
 #define GT_CPU_WR_SHF		16
 #define GT_CPU_WR_MSK		(MSK(1) << GT_CPU_WR_SHF)
 #define GT_CPU_WR_BIT		GT_CPU_WR_MSK
@@ -177,6 +299,15 @@
 #define GT_CPU_WR_DDDD		1
 
 
+#define GT_PCI_DCRM_SHF		21
+#define GT_PCI_LD_SHF		0
+#define GT_PCI_LD_MSK		(MSK(15) << GT_PCI_LD_SHF)
+#define GT_PCI_HD_SHF		0
+#define GT_PCI_HD_MSK		(MSK(7) << GT_PCI_HD_SHF)
+#define GT_PCI_REMAP_SHF	0
+#define GT_PCI_REMAP_MSK	(MSK(11) << GT_PCI_REMAP_SHF)
+
+
 #define GT_CFGADDR_CFGEN_SHF	31
 #define GT_CFGADDR_CFGEN_MSK	(MSK(1) << GT_CFGADDR_CFGEN_SHF)
 #define GT_CFGADDR_CFGEN_BIT	GT_CFGADDR_CFGEN_MSK
@@ -285,7 +416,7 @@
 #define GT_SDRAM_CFG_REFINT_MSK		(MSK(14) << GT_SDRAM_CFG_REFINT_SHF)
 
 #define GT_SDRAM_CFG_NINTERLEAVE_SHF	14
-#define GT_SDRAM_CFG_NINTERLEAVE_MSK    (MSK(1) << GT_SDRAM_CFG_NINTERLEAVE_SHF)
+#define GT_SDRAM_CFG_NINTERLEAVE_MSK	(MSK(1) << GT_SDRAM_CFG_NINTERLEAVE_SHF)
 #define GT_SDRAM_CFG_NINTERLEAVE_BIT	GT_SDRAM_CFG_NINTERLEAVE_MSK
 
 #define GT_SDRAM_CFG_RMW_SHF		15
@@ -370,7 +501,7 @@
 #define GT_PCI0_CFGADDR_REGNUM_SHF	2
 #define GT_PCI0_CFGADDR_REGNUM_MSK	(MSK(6) << GT_PCI0_CFGADDR_REGNUM_SHF)
 #define GT_PCI0_CFGADDR_FUNCTNUM_SHF	8
-#define GT_PCI0_CFGADDR_FUNCTNUM_MSK    (MSK(3) << GT_PCI0_CFGADDR_FUNCTNUM_SHF)
+#define GT_PCI0_CFGADDR_FUNCTNUM_MSK	(MSK(3) << GT_PCI0_CFGADDR_FUNCTNUM_SHF)
 #define GT_PCI0_CFGADDR_DEVNUM_SHF	11
 #define GT_PCI0_CFGADDR_DEVNUM_MSK	(MSK(5) << GT_PCI0_CFGADDR_DEVNUM_SHF)
 #define GT_PCI0_CFGADDR_BUSNUM_SHF	16
@@ -379,18 +510,18 @@
 #define GT_PCI0_CFGADDR_CONFIGEN_MSK	(MSK(1) << GT_PCI0_CFGADDR_CONFIGEN_SHF)
 #define GT_PCI0_CFGADDR_CONFIGEN_BIT	GT_PCI0_CFGADDR_CONFIGEN_MSK
 
-#define GT_PCI0_CMD_MBYTESWAP_SHF       0
-#define GT_PCI0_CMD_MBYTESWAP_MSK       (MSK(1) << GT_PCI0_CMD_MBYTESWAP_SHF)
-#define GT_PCI0_CMD_MBYTESWAP_BIT       GT_PCI0_CMD_MBYTESWAP_MSK
-#define GT_PCI0_CMD_MWORDSWAP_SHF       10
-#define GT_PCI0_CMD_MWORDSWAP_MSK       (MSK(1) << GT_PCI0_CMD_MWORDSWAP_SHF)
-#define GT_PCI0_CMD_MWORDSWAP_BIT       GT_PCI0_CMD_MWORDSWAP_MSK
-#define GT_PCI0_CMD_SBYTESWAP_SHF       16
-#define GT_PCI0_CMD_SBYTESWAP_MSK       (MSK(1) << GT_PCI0_CMD_SBYTESWAP_SHF)
-#define GT_PCI0_CMD_SBYTESWAP_BIT       GT_PCI0_CMD_SBYTESWAP_MSK
-#define GT_PCI0_CMD_SWORDSWAP_SHF       11
-#define GT_PCI0_CMD_SWORDSWAP_MSK       (MSK(1) << GT_PCI0_CMD_SWORDSWAP_SHF)
-#define GT_PCI0_CMD_SWORDSWAP_BIT       GT_PCI0_CMD_SWORDSWAP_MSK
+#define GT_PCI0_CMD_MBYTESWAP_SHF	0
+#define GT_PCI0_CMD_MBYTESWAP_MSK	(MSK(1) << GT_PCI0_CMD_MBYTESWAP_SHF)
+#define GT_PCI0_CMD_MBYTESWAP_BIT	GT_PCI0_CMD_MBYTESWAP_MSK
+#define GT_PCI0_CMD_MWORDSWAP_SHF	10
+#define GT_PCI0_CMD_MWORDSWAP_MSK	(MSK(1) << GT_PCI0_CMD_MWORDSWAP_SHF)
+#define GT_PCI0_CMD_MWORDSWAP_BIT	GT_PCI0_CMD_MWORDSWAP_MSK
+#define GT_PCI0_CMD_SBYTESWAP_SHF	16
+#define GT_PCI0_CMD_SBYTESWAP_MSK	(MSK(1) << GT_PCI0_CMD_SBYTESWAP_SHF)
+#define GT_PCI0_CMD_SBYTESWAP_BIT	GT_PCI0_CMD_SBYTESWAP_MSK
+#define GT_PCI0_CMD_SWORDSWAP_SHF	11
+#define GT_PCI0_CMD_SWORDSWAP_MSK	(MSK(1) << GT_PCI0_CMD_SWORDSWAP_SHF)
+#define GT_PCI0_CMD_SWORDSWAP_BIT	GT_PCI0_CMD_SWORDSWAP_MSK
 
 /*
  *  Misc
@@ -401,8 +532,8 @@
 #define GT_DEF_PCI0_MEM0_SIZE	0x02000000UL
 #define GT_DEF_BASE		0x14000000UL
 
-#define GT_MAX_BANKSIZE		(256 * 1024 * 1024)   /* Max 256MB bank */
-#define GT_LATTIM_MIN    	6		      /* Minimum lat	*/
+#define GT_MAX_BANKSIZE		(256 * 1024 * 1024)	/* Max 256MB bank  */
+#define GT_LATTIM_MIN		6			/* Minimum lat  */
 
 /*
  * The gt64120_dep.h file must define the following macros
diff -Nru a/include/asm-mips/hardirq.h b/include/asm-mips/hardirq.h
--- a/include/asm-mips/hardirq.h	2005-03-01 23:38:54 -08:00
+++ b/include/asm-mips/hardirq.h	2005-03-01 23:38:54 -08:00
@@ -3,14 +3,13 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1997, 1998, 1999, 2000, 2001 by Ralf Baechle
+ * Copyright (C) 1997, 98, 99, 2000, 01, 05 Ralf Baechle (ralf@linux-mips.org)
  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
  * Copyright (C) 2001 MIPS Technologies, Inc.
  */
 #ifndef _ASM_HARDIRQ_H
 #define _ASM_HARDIRQ_H
 
-#include <linux/config.h>
 #include <linux/threads.h>
 #include <linux/irq.h>
 
diff -Nru a/include/asm-mips/hazards.h b/include/asm-mips/hazards.h
--- a/include/asm-mips/hazards.h	2005-03-01 23:39:08 -08:00
+++ b/include/asm-mips/hazards.h	2005-03-01 23:39:08 -08:00
@@ -16,6 +16,10 @@
 	sll	$0, $0, 1
 	.endm
 
+	.macro	_ehb
+	sll	$0, $0, 3
+	.endm
+
 /*
  * RM9000 hazards.  When the JTLB is updated by tlbwi or tlbwr, a subsequent
  * use of the JTLB for instructions should not occur for 4 cpu cycles and use
@@ -23,17 +27,19 @@
  */
 #ifdef CONFIG_CPU_RM9000
 
-#define mtc0_tlbw_hazard						\
-	.set	push;							\
-	.set	mips32;							\
-	_ssnop; _ssnop; _ssnop; _ssnop;					\
+	.macro	mtc0_tlbw_hazard
+	.set	push
+	.set	mips32
+	_ssnop; _ssnop; _ssnop; _ssnop
 	.set	pop
+	.endm
 
-#define tlbw_eret_hazard						\
-	.set	push;							\
-	.set	mips32;							\
-	_ssnop; _ssnop; _ssnop; _ssnop;					\
+	.macro	tlbw_eret_hazard
+	.set	push
+	.set	mips32
+	_ssnop; _ssnop; _ssnop; _ssnop
 	.set	pop
+	.endm
 
 #else
 
@@ -43,9 +49,12 @@
  * hazard so this is nice trick to have an optimal code for a range of
  * processors.
  */
-#define mtc0_tlbw_hazard						\
+	.macro	mtc0_tlbw_hazard
 	b	. + 8
-#define tlbw_eret_hazard
+	.endm
+
+	.macro	tlbw_eret_hazard
+	.endm
 #endif
 
 /*
@@ -58,31 +67,51 @@
 /*
  * Use a macro for ehb unless explicit support for MIPSR2 is enabled
  */
-	.macro	ehb
-	sll	$0, $0, 3
-	.endm
 
-#define irq_enable_hazard						\
-	ehb		# irq_enable_hazard
+#define irq_enable_hazard
+	_ehb
 
-#define irq_disable_hazard						\
-	ehb		# irq_disable_hazard
+#define irq_disable_hazard
+	_ehb
 
-#else
+#elif defined(CONFIG_CPU_R10000) || defined(CONFIG_CPU_RM9000)
+
+/*
+ * R10000 rocks - all hazards handled in hardware, so this becomes a nobrainer.
+ */
 
 #define irq_enable_hazard
+
 #define irq_disable_hazard
 
+#else
+
+/*
+ * Classic MIPS needs 1 - 3 nops or ssnops
+ */
+#define irq_enable_hazard
+#define irq_disable_hazard						\
+	_ssnop; _ssnop; _ssnop
+
 #endif
 
 #else /* __ASSEMBLY__ */
 
+__asm__(
+	"	.macro	_ssnop					\n\t"
+	"	sll	$0, $2, 1				\n\t"
+	"	.endm						\n\t"
+	"							\n\t"
+	"	.macro	_ehb					\n\t"
+	"	sll	$0, $0, 3				\n\t"
+	"	.endm						\n\t");
+
+#ifdef CONFIG_CPU_RM9000
 /*
  * RM9000 hazards.  When the JTLB is updated by tlbwi or tlbwr, a subsequent
  * use of the JTLB for instructions should not occur for 4 cpu cycles and use
  * for data translations should not occur for 3 cpu cycles.
  */
-#ifdef CONFIG_CPU_RM9000
 
 #define mtc0_tlbw_hazard()						\
 	__asm__ __volatile__(						\
@@ -125,27 +154,23 @@
  * Use a macro for ehb unless explicit support for MIPSR2 is enabled
  */
 __asm__(
-	"	.macro	ehb					\n\t"
-	"	sll	$0, $0, 3				\n\t"
-	"	.endm						\n\t"
-	"							\n\t"
 	"	.macro\tirq_enable_hazard			\n\t"
-	"	ehb						\n\t"
+	"	_ehb						\n\t"
 	"	.endm						\n\t"
 	"							\n\t"
 	"	.macro\tirq_disable_hazard			\n\t"
-	"	ehb						\n\t"
+	"	_ehb						\n\t"
 	"	.endm");
 
 #define irq_enable_hazard()						\
 	__asm__ __volatile__(						\
-	"ehb\t\t\t\t# irq_enable_hazard")
+	"_ehb\t\t\t\t# irq_enable_hazard")
 
 #define irq_disable_hazard()						\
 	__asm__ __volatile__(						\
-	"ehb\t\t\t\t# irq_disable_hazard")
+	"_ehb\t\t\t\t# irq_disable_hazard")
 
-#elif defined(CONFIG_CPU_R10000)
+#elif defined(CONFIG_CPU_R10000) || defined(CONFIG_CPU_RM9000)
 
 /*
  * R10000 rocks - all hazards handled in hardware, so this becomes a nobrainer.
@@ -170,10 +195,6 @@
  */
 
 __asm__(
-	"	.macro	_ssnop					\n\t"
-	"	sll	$0, $2, 1				\n\t"
-	"	.endm						\n\t"
-	"							\n\t"
 	"	#						\n\t"
 	"	# There is a hazard but we do not care		\n\t"
 	"	#						\n\t"
diff -Nru a/include/asm-mips/io.h b/include/asm-mips/io.h
--- a/include/asm-mips/io.h	2005-03-01 23:38:55 -08:00
+++ b/include/asm-mips/io.h	2005-03-01 23:38:55 -08:00
@@ -6,21 +6,26 @@
  * Copyright (C) 1994, 1995 Waldorf GmbH
  * Copyright (C) 1994 - 2000 Ralf Baechle
  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ * Copyright (C) 2004, 2005  MIPS Technologies, Inc.  All rights reserved.
+ *	Author:	Maciej W. Rozycki <macro@mips.com>
  */
 #ifndef _ASM_IO_H
 #define _ASM_IO_H
 
 #include <linux/config.h>
 #include <linux/compiler.h>
+#include <linux/kernel.h>
 #include <linux/types.h>
 
 #include <asm/addrspace.h>
+#include <asm/bug.h>
+#include <asm/byteorder.h>
 #include <asm/cpu.h>
 #include <asm/cpu-features.h>
 #include <asm/page.h>
 #include <asm/pgtable-bits.h>
 #include <asm/processor.h>
-#include <asm/byteorder.h>
+
 #include <mangle-port.h>
 
 /*
@@ -29,34 +34,54 @@
 #undef CONF_SLOWDOWN_IO
 
 /*
- * Sane hardware offers swapping of I/O space accesses in hardware; less
- * sane hardware forces software to fiddle with this ...
+ * Raw operations are never swapped in software.  Otoh values that raw
+ * operations are working on may or may not have been swapped by the bus
+ * hardware.  An example use would be for flash memory that's used for
+ * execute in place.
  */
-#if defined(CONFIG_SWAP_IO_SPACE) && defined(__MIPSEB__)
+# define __raw_ioswabb(x)	(x)
+# define __raw_ioswabw(x)	(x)
+# define __raw_ioswabl(x)	(x)
+# define __raw_ioswabq(x)	(x)
 
-#define __ioswab8(x) (x)
+/*
+ * Sane hardware offers swapping of PCI/ISA I/O space accesses in hardware;
+ * less sane hardware forces software to fiddle with this...
+ */
+#if defined(CONFIG_SWAP_IO_SPACE)
 
-#ifdef CONFIG_SGI_IP22
+# define ioswabb(x)		(x)
+# ifdef CONFIG_SGI_IP22
 /*
  * IP22 seems braindead enough to swap 16bits values in hardware, but
  * not 32bits.  Go figure... Can't tell without documentation.
  */
-#define __ioswab16(x) (x)
-#else
-#define __ioswab16(x) swab16(x)
-#endif
-#define __ioswab32(x) swab32(x)
-#define __ioswab64(x) swab64(x)
+#  define ioswabw(x)		(x)
+# else
+#  define ioswabw(x)		le16_to_cpu(x)
+# endif
+# define ioswabl(x)		le32_to_cpu(x)
+# define ioswabq(x)		le64_to_cpu(x)
 
 #else
 
-#define __ioswab8(x) (x)
-#define __ioswab16(x) (x)
-#define __ioswab32(x) (x)
-#define __ioswab64(x) (x)
+# define ioswabb(x)		(x)
+# define ioswabw(x)		(x)
+# define ioswabl(x)		(x)
+# define ioswabq(x)		(x)
 
 #endif
 
+/*
+ * Native bus accesses never swapped.
+ */
+#define bus_ioswabb(x)		(x)
+#define bus_ioswabw(x)		(x)
+#define bus_ioswabl(x)		(x)
+#define bus_ioswabq(x)		(x)
+
+#define __bus_ioswabq		bus_ioswabq
+
 #define IO_SPACE_LIMIT 0xffff
 
 /*
@@ -239,114 +264,214 @@
 
 static inline void iounmap(volatile void __iomem *addr)
 {
-	if (cpu_has_64bits)
+	if (cpu_has_64bit_addresses)
 		return;
 
 	__iounmap(addr);
 }
 
-#define __raw_readb(addr)						\
-	(*(volatile unsigned char *) __swizzle_addr_b((unsigned long)(addr)))
-#define __raw_readw(addr)						\
-	(*(volatile unsigned short *) __swizzle_addr_w((unsigned long)(addr)))
-#define __raw_readl(addr)						\
-	(*(volatile unsigned int *) __swizzle_addr_l((unsigned long)(addr)))
-#ifdef CONFIG_MIPS32
-#define ____raw_readq(addr)						\
-({									\
-	u64 __res;							\
-									\
-	__asm__ __volatile__ (						\
-		"	.set	mips3		# ____raw_readq	\n"	\
-		"	ld	%L0, (%1)			\n"	\
-		"	dsra32	%M0, %L0, 0			\n"	\
-		"	sll	%L0, %L0, 0			\n"	\
-		"	.set	mips0				\n"	\
-		: "=r" (__res)						\
-		: "r" (__swizzle_addr_q((unsigned long)(addr))));	\
-	__res;								\
-})
-#define __raw_readq(addr)						\
-({									\
-	unsigned long __flags;						\
-	u64 __res;							\
-									\
-	local_irq_save(__flags);					\
-	__res = ____raw_readq(addr);					\
-	local_irq_restore(__flags);					\
-	__res;								\
-})
-#endif
-#ifdef CONFIG_MIPS64
-#define ____raw_readq(addr)						\
-	(*(volatile unsigned long *)__swizzle_addr_q((unsigned long)(addr)))
-#define __raw_readq(addr)	____raw_readq(addr)
-#endif
 
-#define readb(addr)		__ioswab8(__raw_readb(addr))
-#define readw(addr)		__ioswab16(__raw_readw(addr))
-#define readl(addr)		__ioswab32(__raw_readl(addr))
-#define readq(addr)		__ioswab64(__raw_readq(addr))
-#define readb_relaxed(addr)	readb(addr)
-#define readw_relaxed(addr)	readw(addr)
-#define readl_relaxed(addr)	readl(addr)
-#define readq_relaxed(addr)	readq(addr)
-
-#define __raw_writeb(b,addr)						\
-do {									\
-	((*(volatile unsigned char *)__swizzle_addr_b((unsigned long)(addr))) = (b));	\
-} while (0)
-
-#define __raw_writew(w,addr)						\
-do {									\
-	((*(volatile unsigned short *)__swizzle_addr_w((unsigned long)(addr))) = (w));	\
-} while (0)
-
-#define __raw_writel(l,addr)						\
-do {									\
-	((*(volatile unsigned int *)__swizzle_addr_l((unsigned long)(addr))) = (l));	\
-} while (0)
-
-#ifdef CONFIG_MIPS32
-#define ____raw_writeq(val,addr)					\
-do {									\
-	u64 __tmp;							\
-									\
-	__asm__ __volatile__ (						\
-		"	.set	mips3				\n"	\
-		"	dsll32	%L0, %L0, 0	# ____raw_writeq\n"	\
-		"	dsrl32	%L0, %L0, 0			\n"	\
-		"	dsll32	%M0, %M0, 0			\n"	\
-		"	or	%L0, %L0, %M0			\n"	\
-		"	sd	%L0, (%2)			\n"	\
-		"	.set	mips0				\n"	\
-		: "=r" (__tmp)						\
-		: "0" ((unsigned long long)val),			\
-		  "r" (__swizzle_addr_q((unsigned long)(addr))));	\
-} while (0)
-
-#define __raw_writeq(val,addr)						\
-do {									\
-	unsigned long __flags;						\
-									\
-	local_irq_save(__flags);					\
-	____raw_writeq(val, addr);					\
-	local_irq_restore(__flags);					\
-} while (0)
-#endif
-#ifdef CONFIG_MIPS64
-#define ____raw_writeq(q,addr)						\
-do {									\
-	*(volatile unsigned long *)__swizzle_addr_q((unsigned long)(addr)) = (q);	\
-} while (0)
+#define __BUILD_MEMORY_SINGLE(pfx, bwlq, type, irq)			\
+									\
+static inline void pfx##write##bwlq(type val,				\
+				    volatile void __iomem *mem)		\
+{									\
+	volatile type *__mem;						\
+	type __val;							\
+									\
+	__mem = (void *)__swizzle_addr_##bwlq((unsigned long)(mem));	\
+									\
+	__val = pfx##ioswab##bwlq(val);					\
+									\
+	if (sizeof(type) != sizeof(u64) || sizeof(u64) == sizeof(long))	\
+		*__mem = __val;						\
+	else if (cpu_has_64bits) {					\
+		unsigned long __flags;					\
+		type __tmp;						\
+									\
+		if (irq)						\
+			local_irq_save(__flags);			\
+		__asm__ __volatile__(					\
+			".set	mips3"		"\t\t# __writeq""\n\t"	\
+			"dsll32	%L0, %L0, 0"			"\n\t"	\
+			"dsrl32	%L0, %L0, 0"			"\n\t"	\
+			"dsll32	%M0, %M0, 0"			"\n\t"	\
+			"or	%L0, %L0, %M0"			"\n\t"	\
+			"sd	%L0, %2"			"\n\t"	\
+			".set	mips0"				"\n"	\
+			: "=r" (__tmp)					\
+			: "0" (__val), "m" (*__mem));			\
+		if (irq)						\
+			local_irq_restore(__flags);			\
+	} else								\
+		BUG();							\
+}									\
+									\
+static inline type pfx##read##bwlq(volatile void __iomem *mem)		\
+{									\
+	volatile type *__mem;						\
+	type __val;							\
+									\
+	__mem = (void *)__swizzle_addr_##bwlq((unsigned long)(mem));	\
+									\
+	if (sizeof(type) != sizeof(u64) || sizeof(u64) == sizeof(long))	\
+		__val = *__mem;						\
+	else if (cpu_has_64bits) {					\
+		unsigned long __flags;					\
+									\
+		local_irq_save(__flags);				\
+		__asm__ __volatile__(					\
+			".set	mips3"		"\t\t# __readq"	"\n\t"	\
+			"ld	%L0, %1"			"\n\t"	\
+			"dsra32	%M0, %L0, 0"			"\n\t"	\
+			"sll	%L0, %L0, 0"			"\n\t"	\
+			".set	mips0"				"\n"	\
+			: "=r" (__val)					\
+			: "m" (*__mem));				\
+		local_irq_restore(__flags);				\
+	} else {							\
+		__val = 0;						\
+		BUG();							\
+	}								\
+									\
+	return pfx##ioswab##bwlq(__val);				\
+}
 
-#define __raw_writeq(q,addr)	____raw_writeq(q, addr)
-#endif
+#define __BUILD_IOPORT_SINGLE(pfx, bwlq, type, p, slow)			\
+									\
+static inline void pfx##out##bwlq##p(type val, unsigned long port)	\
+{									\
+	volatile type *__addr;						\
+	type __val;							\
+									\
+	port = __swizzle_addr_##bwlq(port);				\
+	__addr = (void *)(mips_io_port_base + port);			\
+									\
+	__val = pfx##ioswab##bwlq(val);					\
+									\
+	if (sizeof(type) != sizeof(u64)) {				\
+		*__addr = __val;					\
+		slow;							\
+	} else								\
+		BUILD_BUG();						\
+}									\
+									\
+static inline type pfx##in##bwlq##p(unsigned long port)			\
+{									\
+	volatile type *__addr;						\
+	type __val;							\
+									\
+	port = __swizzle_addr_##bwlq(port);				\
+	__addr = (void *)(mips_io_port_base + port);			\
+									\
+	if (sizeof(type) != sizeof(u64)) {				\
+		__val = *__addr;					\
+		slow;							\
+	} else {							\
+		__val = 0;						\
+		BUILD_BUG();						\
+	}								\
+									\
+	return pfx##ioswab##bwlq(__val);				\
+}
+
+#define __BUILD_MEMORY_PFX(bus, bwlq, type)				\
+									\
+__BUILD_MEMORY_SINGLE(bus, bwlq, type, 1)
+
+#define __BUILD_IOPORT_PFX(bus, bwlq, type)				\
+									\
+__BUILD_IOPORT_SINGLE(bus, bwlq, type, ,)				\
+__BUILD_IOPORT_SINGLE(bus, bwlq, type, _p, SLOW_DOWN_IO)
+
+#define BUILDIO(bwlq, type)						\
+									\
+__BUILD_MEMORY_PFX(, bwlq, type)					\
+__BUILD_MEMORY_PFX(__raw_, bwlq, type)					\
+__BUILD_MEMORY_PFX(bus_, bwlq, type)					\
+__BUILD_IOPORT_PFX(, bwlq, type)					\
+__BUILD_IOPORT_PFX(__raw_, bwlq, type)
+
+#define __BUILDIO(bwlq, type)						\
+									\
+__BUILD_MEMORY_SINGLE(__bus_, bwlq, type, 0)
+
+BUILDIO(b, u8)
+BUILDIO(w, u16)
+BUILDIO(l, u32)
+BUILDIO(q, u64)
+
+__BUILDIO(q, u64)
+
+#define readb_relaxed			readb
+#define readw_relaxed			readw
+#define readl_relaxed			readl
+#define readq_relaxed			readq
+
+/*
+ * Some code tests for these symbols
+ */
+#define readq				readq
+#define writeq				writeq
+
+#define __BUILD_MEMORY_STRING(bwlq, type)				\
+									\
+static inline void writes##bwlq(volatile void __iomem *mem, void *addr,	\
+				unsigned int count)			\
+{									\
+	volatile type *__addr = addr;					\
+									\
+	while (count--) {						\
+		__raw_write##bwlq(*__addr, mem);			\
+		__addr++;						\
+	}								\
+}									\
+									\
+static inline void reads##bwlq(volatile void __iomem *mem, void *addr,	\
+			       unsigned int count)			\
+{									\
+	volatile type *__addr = addr;					\
+									\
+	while (count--) {						\
+		*__addr = __raw_read##bwlq(mem);			\
+		__addr++;						\
+	}								\
+}
+
+#define __BUILD_IOPORT_STRING(bwlq, type)				\
+									\
+static inline void outs##bwlq(unsigned long port, void *addr,		\
+			      unsigned int count)			\
+{									\
+	volatile type *__addr = addr;					\
+									\
+	while (count--) {						\
+		__raw_out##bwlq(*__addr, port);				\
+		__addr++;						\
+	}								\
+}									\
+									\
+static inline void ins##bwlq(unsigned long port, void *addr,		\
+			     unsigned int count)			\
+{									\
+	volatile type *__addr = addr;					\
+									\
+	while (count--) {						\
+		*__addr = __raw_in##bwlq(port);				\
+		__addr++;						\
+	}								\
+}
+
+#define BUILDSTRING(bwlq, type)						\
+									\
+__BUILD_MEMORY_STRING(bwlq, type)					\
+__BUILD_IOPORT_STRING(bwlq, type)
+
+BUILDSTRING(b, u8)
+BUILDSTRING(w, u16)
+BUILDSTRING(l, u32)
+BUILDSTRING(q, u64)
 
-#define writeb(b,addr)		__raw_writeb(__ioswab8(b),(addr))
-#define writew(w,addr)		__raw_writew(__ioswab16(w),(addr))
-#define writel(l,addr)		__raw_writel(__ioswab32(l),(addr))
-#define writeq(q,addr)		__raw_writeq(__ioswab64(q),(addr))
 
 /* Depends on MIPS II instruction set */
 #define mmiowb() asm volatile ("sync" ::: "memory")
@@ -356,6 +481,34 @@
 #define memcpy_toio(a,b,c)	memcpy((void *)(a),(b),(c))
 
 /*
+ * Memory Mapped I/O
+ */
+#define ioread8(addr)		readb(addr)
+#define ioread16(addr)		readw(addr)
+#define ioread32(addr)		readl(addr)
+
+#define iowrite8(b,addr)	writeb(b,addr)
+#define iowrite16(w,addr)	writew(w,addr)
+#define iowrite32(l,addr)	writel(l,addr)
+
+#define ioread8_rep(a,b,c)	readsb(a,b,c)
+#define ioread16_rep(a,b,c)	readsw(a,b,c)
+#define ioread32_rep(a,b,c)	readsl(a,b,c)
+
+#define iowrite8_rep(a,b,c)	writesb(a,b,c)
+#define iowrite16_rep(a,b,c)	writesw(a,b,c)
+#define iowrite32_rep(a,b,c)	writesl(a,b,c)
+
+/* Create a virtual mapping cookie for an IO port range */
+extern void __iomem *ioport_map(unsigned long port, unsigned int nr);
+extern void ioport_unmap(void __iomem *);
+
+/* Create a virtual mapping cookie for a PCI BAR (memory or IO) */
+struct pci_dev;
+extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max);
+extern void pci_iounmap(struct pci_dev *dev, void __iomem *);
+
+/*
  * ISA space is 'always mapped' on currently supported MIPS systems, no need
  * to explicitly ioremap() it. The fact that the ISA IO space is mapped
  * to PAGE_OFFSET is pure coincidence - it does not mean ISA values
@@ -394,7 +547,7 @@
  *     address should have been obtained by ioremap.
  *     Returns 1 on a match.
  */
-static inline int check_signature(unsigned long io_addr,
+static inline int check_signature(char __iomem *io_addr,
 	const unsigned char *signature, int length)
 {
 	int retval = 0;
@@ -409,177 +562,6 @@
 out:
 	return retval;
 }
-
-static inline void __outb(unsigned char val, unsigned long port)
-{
-	port = __swizzle_addr_b(port);
-
-	*(volatile u8 *)(mips_io_port_base + port) = __ioswab8(val);
-}
-
-static inline void __outw(unsigned short val, unsigned long port)
-{
-	port = __swizzle_addr_w(port);
-
-	*(volatile u16 *)(mips_io_port_base + port) = __ioswab16(val);
-}
-
-static inline void __outl(unsigned int val, unsigned long port)
-{
-	port = __swizzle_addr_l(port);
-
-	*(volatile u32 *)(mips_io_port_base + port) = __ioswab32(val);
-}
-
-static inline void __outb_p(unsigned char val, unsigned long port)
-{
-	port = __swizzle_addr_b(port);
-
-	*(volatile u8 *)(mips_io_port_base + port) = __ioswab8(val);
-	SLOW_DOWN_IO;
-}
-
-static inline void __outw_p(unsigned short val, unsigned long port)
-{
-	port = __swizzle_addr_w(port);
-
-	*(volatile u16 *)(mips_io_port_base + port) = __ioswab16(val);
-	SLOW_DOWN_IO;
-}
-
-static inline void __outl_p(unsigned int val, unsigned long port)
-{
-	port = __swizzle_addr_l(port);
-
-	*(volatile u32 *)(mips_io_port_base + port) = __ioswab32(val);
-	SLOW_DOWN_IO;
-}
-
-#define outb(val, port)		__outb(val, port)
-#define outw(val, port)		__outw(val, port)
-#define outl(val, port)		__outl(val, port)
-#define outb_p(val, port)	__outb_p(val, port)
-#define outw_p(val, port)	__outw_p(val, port)
-#define outl_p(val, port)	__outl_p(val, port)
-
-static inline unsigned char __inb(unsigned long port)
-{
-	port = __swizzle_addr_b(port);
-
-	return __ioswab8(*(volatile u8 *)(mips_io_port_base + port));
-}
-
-static inline unsigned short __inw(unsigned long port)
-{
-	port = __swizzle_addr_w(port);
-
-	return __ioswab16(*(volatile u16 *)(mips_io_port_base + port));
-}
-
-static inline unsigned int __inl(unsigned long port)
-{
-	port = __swizzle_addr_l(port);
-
-	return __ioswab32(*(volatile u32 *)(mips_io_port_base + port));
-}
-
-static inline unsigned char __inb_p(unsigned long port)
-{
-	u8 __val;
-
-	port = __swizzle_addr_b(port);
-
-	__val = *(volatile u8 *)(mips_io_port_base + port);
-	SLOW_DOWN_IO;
-
-	return __ioswab8(__val);
-}
-
-static inline unsigned short __inw_p(unsigned long port)
-{
-	u16 __val;
-
-	port = __swizzle_addr_w(port);
-
-	__val = *(volatile u16 *)(mips_io_port_base + port);
-	SLOW_DOWN_IO;
-
-	return __ioswab16(__val);
-}
-
-static inline unsigned int __inl_p(unsigned long port)
-{
-	u32 __val;
-
-	port = __swizzle_addr_l(port);
-
-	__val = *(volatile u32 *)(mips_io_port_base + port);
-	SLOW_DOWN_IO;
-
-	return __ioswab32(__val);
-}
-
-#define inb(port)	__inb(port)
-#define inw(port)	__inw(port)
-#define inl(port)	__inl(port)
-#define inb_p(port)	__inb_p(port)
-#define inw_p(port)	__inw_p(port)
-#define inl_p(port)	__inl_p(port)
-
-static inline void __outsb(unsigned long port, void *addr, unsigned int count)
-{
-	while (count--) {
-		outb(*(u8 *)addr, port);
-		addr++;
-	}
-}
-
-static inline void __insb(unsigned long port, void *addr, unsigned int count)
-{
-	while (count--) {
-		*(u8 *)addr = inb(port);
-		addr++;
-	}
-}
-
-static inline void __outsw(unsigned long port, void *addr, unsigned int count)
-{
-	while (count--) {
-		outw(*(u16 *)addr, port);
-		addr += 2;
-	}
-}
-
-static inline void __insw(unsigned long port, void *addr, unsigned int count)
-{
-	while (count--) {
-		*(u16 *)addr = inw(port);
-		addr += 2;
-	}
-}
-
-static inline void __outsl(unsigned long port, void *addr, unsigned int count)
-{
-	while (count--) {
-		outl(*(u32 *)addr, port);
-		addr += 4;
-	}
-}
-
-static inline void __insl(unsigned long port, void *addr, unsigned int count)
-{
-	while (count--) {
-		*(u32 *)addr = inl(port);
-		addr += 4;
-	}
-}
-
-#define outsb(port, addr, count)	__outsb(port, addr, count)
-#define insb(port, addr, count)		__insb(port, addr, count)
-#define outsw(port, addr, count)	__outsw(port, addr, count)
-#define insw(port, addr, count)		__insw(port, addr, count)
-#define outsl(port, addr, count)	__outsl(port, addr, count)
-#define insl(port, addr, count)		__insl(port, addr, count)
 
 /*
  * The caches on some architectures aren't dma-coherent and have need to
diff -Nru a/include/asm-mips/ip32/crime.h b/include/asm-mips/ip32/crime.h
--- a/include/asm-mips/ip32/crime.h	2005-03-01 23:39:08 -08:00
+++ b/include/asm-mips/ip32/crime.h	2005-03-01 23:39:08 -08:00
@@ -156,4 +156,6 @@
 
 extern struct sgi_crime *crime;
 
+#define CRIME_HI_MEM_BASE	0x40000000	/* this is where whole 1G of RAM is mapped */
+
 #endif /* __ASM_CRIME_H__ */
diff -Nru a/include/asm-mips/irq_cpu.h b/include/asm-mips/irq_cpu.h
--- a/include/asm-mips/irq_cpu.h	2005-03-01 23:38:56 -08:00
+++ b/include/asm-mips/irq_cpu.h	2005-03-01 23:38:56 -08:00
@@ -15,5 +15,6 @@
 
 extern void mips_cpu_irq_init(int irq_base);
 extern void rm7k_cpu_irq_init(int irq_base);
+extern void rm9k_cpu_irq_init(int irq_base);
 
 #endif /* _ASM_IRQ_CPU_H */
diff -Nru a/include/asm-mips/it8172/it8172_lpc.h b/include/asm-mips/it8172/it8172_lpc.h
--- a/include/asm-mips/it8172/it8172_lpc.h	2005-03-01 23:39:17 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,29 +0,0 @@
-/*
- *
- * BRIEF MODULE DESCRIPTION
- *	IT8172 system controller defines.
- *
- * Copyright 2000 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *         	ppopov@mvista.com or source@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.
- *
- *  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.
- */
diff -Nru a/include/asm-mips/m48t37.h b/include/asm-mips/m48t37.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-mips/m48t37.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,35 @@
+/*
+ *  Registers for the SGS-Thomson M48T37 Timekeeper RAM chip
+ */
+#ifndef _ASM_M48T37_H
+#define _ASM_M48T37_H
+
+#include <linux/spinlock.h>
+
+extern spinlock_t rtc_lock;
+
+struct m48t37_rtc {
+	volatile u8	pad[0x7ff0];    /* NVRAM */
+	volatile u8	flags;
+	volatile u8	century;
+	volatile u8	alarm_sec;
+	volatile u8	alarm_min;
+	volatile u8	alarm_hour;
+	volatile u8	alarm_data;
+	volatile u8	interrupts;
+	volatile u8	watchdog;
+	volatile u8	control;
+	volatile u8	sec;
+	volatile u8	min;
+	volatile u8	hour;
+	volatile u8	day;
+	volatile u8	date;
+	volatile u8	month;
+	volatile u8	year;
+};
+
+#define M48T37_RTC_SET		0x80
+#define M48T37_RTC_STOPPED	0x80
+#define M48T37_RTC_READ		0x40
+
+#endif /* _ASM_M48T37_H */
diff -Nru a/include/asm-mips/mach-atlas/mc146818rtc.h b/include/asm-mips/mach-atlas/mc146818rtc.h
--- a/include/asm-mips/mach-atlas/mc146818rtc.h	2005-03-01 23:39:16 -08:00
+++ b/include/asm-mips/mach-atlas/mc146818rtc.h	2005-03-01 23:39:16 -08:00
@@ -1,7 +1,9 @@
 /*
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
- * Copyright (C) 2003 by Ralf Baechle
+ * Copyright (C) 1999, 2000, 2005  MIPS Technologies, Inc.
+ *	All rights reserved.
+ *	Authors: Carsten Langgaard <carstenl@mips.com>
+ *		 Maciej W. Rozycki <macro@mips.com>
+ * Copyright (C) 2003, 05 Ralf Baechle (ralf@linux-mips.org)
  *
  * This program is free software; you can distribute it and/or modify it
  * under the terms of the GNU General Public License (Version 2) as
@@ -19,33 +21,34 @@
 #ifndef __ASM_MACH_ATLAS_MC146818RTC_H
 #define __ASM_MACH_ATLAS_MC146818RTC_H
 
-#include <asm/io.h>
+#include <linux/types.h>
+
+#include <asm/addrspace.h>
+
 #include <asm/mips-boards/atlas.h>
 #include <asm/mips-boards/atlasint.h>
 
-
-#define RTC_PORT(x)	(ATLAS_RTC_ADR_REG + (x)*8)
-#define RTC_IOMAPPED	1
-#define RTC_EXTENT	16
+#define RTC_PORT(x)	(ATLAS_RTC_ADR_REG + (x) * 8)
+#define RTC_IO_EXTENT	0x100
+#define RTC_IOMAPPED	0
 #define RTC_IRQ		ATLASINT_RTC
 
-#ifdef CONFIG_CPU_LITTLE_ENDIAN
-#define ATLAS_RTC_PORT(x) (RTC_PORT(x) + 0)
-#else
-#define ATLAS_RTC_PORT(x) (RTC_PORT(x) + 3)
-#endif
-
 static inline unsigned char CMOS_READ(unsigned long addr)
 {
-	outb(addr, ATLAS_RTC_PORT(0));
+	volatile u32 *ireg = (void *)CKSEG1ADDR(RTC_PORT(0));
+	volatile u32 *dreg = (void *)CKSEG1ADDR(RTC_PORT(1));
 
-	return inb(ATLAS_RTC_PORT(1));
+	*ireg = addr;
+	return *dreg;
 }
 
 static inline void CMOS_WRITE(unsigned char data, unsigned long addr)
 {
-	outb(addr, ATLAS_RTC_PORT(0));
-	outb(data, ATLAS_RTC_PORT(1));
+	volatile u32 *ireg = (void *)CKSEG1ADDR(RTC_PORT(0));
+	volatile u32 *dreg = (void *)CKSEG1ADDR(RTC_PORT(1));
+
+	*ireg = addr;
+	*dreg = data;
 }
 
 #define RTC_ALWAYS_BCD	0
diff -Nru a/include/asm-mips/mach-au1x00/au1000.h b/include/asm-mips/mach-au1x00/au1000.h
--- a/include/asm-mips/mach-au1x00/au1000.h	2005-03-01 23:38:53 -08:00
+++ b/include/asm-mips/mach-au1x00/au1000.h	2005-03-01 23:38:53 -08:00
@@ -35,6 +35,8 @@
 #ifndef _AU1000_H_
 #define _AU1000_H_
 
+#include <linux/config.h>
+
 #ifndef _LANGUAGE_ASSEMBLY
 
 #include <linux/delay.h>
diff -Nru a/include/asm-mips/mach-au1x00/au1xxx_dbdma.h b/include/asm-mips/mach-au1x00/au1xxx_dbdma.h
--- a/include/asm-mips/mach-au1x00/au1xxx_dbdma.h	2005-03-01 23:38:54 -08:00
+++ b/include/asm-mips/mach-au1x00/au1xxx_dbdma.h	2005-03-01 23:38:54 -08:00
@@ -34,6 +34,8 @@
 #ifndef _AU1000_DBDMA_H_
 #define _AU1000_DBDMA_H_
 
+#include <linux/config.h>
+
 #ifndef _LANGUAGE_ASSEMBLY
 
 /* The DMA base addresses.
diff -Nru a/include/asm-mips/mach-au1x00/au1xxx_psc.h b/include/asm-mips/mach-au1x00/au1xxx_psc.h
--- a/include/asm-mips/mach-au1x00/au1xxx_psc.h	2005-03-01 23:38:55 -08:00
+++ b/include/asm-mips/mach-au1x00/au1xxx_psc.h	2005-03-01 23:38:55 -08:00
@@ -33,27 +33,14 @@
 #ifndef _AU1000_PSC_H_
 #define _AU1000_PSC_H_
 
-/* The PSC base addresses.
-*/
-#define PSC_BASE0		0xb1a00000
-#define PSC_BASE1		0xb1b00000
-#define PSC_BASE2		0xb0a00000
-#define PSC_BASE3		0xb0d00000
-
-/* These should be defined in a board specific file!
-*/
-#ifdef CONFIG_MIPS_PB1550
-#define SPI_PSC_BASE		PSC_BASE0
-#define AC97_PSC_BASE		PSC_BASE1
-#define SMBUS_PSC_BASE		PSC_BASE2
-#endif
-#ifdef CONFIG_MIPS_DB1550
-#define SPI_PSC_BASE		PSC_BASE0
-#define AC97_PSC_BASE		PSC_BASE1
-#define SMBUS_PSC_BASE		PSC_BASE2
+/* The PSC base addresses.  */
+#ifdef CONFIG_SOC_AU1550
+#define PSC0_BASE_ADDR		0xb1a00000
+#define PSC1_BASE_ADDR		0xb1b00000
+#define PSC2_BASE_ADDR		0xb0a00000
+#define PSC3_BASE_ADDR		0xb0d00000
 #endif
 
-
 /* The PSC select and control registers are common to
  * all protocols.
  */
@@ -206,6 +193,330 @@
 */
 #define PSC_AC97RST_RST		(1 << 1)
 #define PSC_AC97RST_SNC		(1 << 0)
+
+
+/* PSC in I2S Mode.
+*/
+typedef struct	psc_i2s {
+	u32	psc_sel;
+	u32	psc_ctrl;
+	u32	psc_i2scfg;
+	u32	psc_i2smsk;
+	u32	psc_i2spcr;
+	u32	psc_i2sstat;
+	u32	psc_i2sevent;
+	u32	psc_i2stxrx;
+	u32	psc_i2sudf;
+} psc_i2s_t;
+
+/* I2S Config Register.
+*/
+#define PSC_I2SCFG_RT_MASK	(3 << 30)
+#define PSC_I2SCFG_RT_FIFO1	(0 << 30)
+#define PSC_I2SCFG_RT_FIFO2	(1 << 30)
+#define PSC_I2SCFG_RT_FIFO4	(2 << 30)
+#define PSC_I2SCFG_RT_FIFO8	(3 << 30)
+
+#define PSC_I2SCFG_TT_MASK	(3 << 28)
+#define PSC_I2SCFG_TT_FIFO1	(0 << 28)
+#define PSC_I2SCFG_TT_FIFO2	(1 << 28)
+#define PSC_I2SCFG_TT_FIFO4	(2 << 28)
+#define PSC_I2SCFG_TT_FIFO8	(3 << 28)
+
+#define PSC_I2SCFG_DD_DISABLE	(1 << 27)
+#define PSC_I2SCFG_DE_ENABLE	(1 << 26)
+#define PSC_I2SCFG_SET_WS(x)	(((((x) / 2) - 1) & 0x7f) << 16)
+#define PSC_I2SCFG_WI		(1 << 15)
+
+#define PSC_I2SCFG_DIV_MASK	(3 << 13)
+#define PSC_I2SCFG_DIV2		(0 << 13)
+#define PSC_I2SCFG_DIV4		(1 << 13)
+#define PSC_I2SCFG_DIV8		(2 << 13)
+#define PSC_I2SCFG_DIV16	(3 << 13)
+
+#define PSC_I2SCFG_BI		(1 << 12)
+#define PSC_I2SCFG_BUF		(1 << 11)
+#define PSC_I2SCFG_MLJ		(1 << 10)
+#define PSC_I2SCFG_XM		(1 << 9)
+
+/* The word length equation is simply LEN+1.
+ */
+#define PSC_I2SCFG_SET_LEN(x)	((((x) - 1) & 0x1f) << 4)
+#define PSC_I2SCFG_GET_LEN(x)	((((x) >> 4) & 0x1f) + 1)
+
+#define PSC_I2SCFG_LB		(1 << 2)
+#define PSC_I2SCFG_MLF		(1 << 1)
+#define PSC_I2SCFG_MS		(1 << 0)
+
+/* I2S Mask Register.
+*/
+#define PSC_I2SMSK_RR		(1 << 13)
+#define PSC_I2SMSK_RO		(1 << 12)
+#define PSC_I2SMSK_RU		(1 << 11)
+#define PSC_I2SMSK_TR		(1 << 10)
+#define PSC_I2SMSK_TO		(1 << 9)
+#define PSC_I2SMSK_TU		(1 << 8)
+#define PSC_I2SMSK_RD		(1 << 5)
+#define PSC_I2SMSK_TD		(1 << 4)
+#define PSC_I2SMSK_ALLMASK	(PSC_I2SMSK_RR | PSC_I2SMSK_RO | \
+				 PSC_I2SMSK_RU | PSC_I2SMSK_TR | \
+				 PSC_I2SMSK_TO | PSC_I2SMSK_TU | \
+				 PSC_I2SMSK_RD | PSC_I2SMSK_TD)
+
+/* I2S Protocol Control Register.
+*/
+#define PSC_I2SPCR_RC		(1 << 6)
+#define PSC_I2SPCR_RP		(1 << 5)
+#define PSC_I2SPCR_RS		(1 << 4)
+#define PSC_I2SPCR_TC		(1 << 2)
+#define PSC_I2SPCR_TP		(1 << 1)
+#define PSC_I2SPCR_TS		(1 << 0)
+
+/* I2S Status register (read only).
+*/
+#define PSC_I2SSTAT_RF		(1 << 13)
+#define PSC_I2SSTAT_RE		(1 << 12)
+#define PSC_I2SSTAT_RR		(1 << 11)
+#define PSC_I2SSTAT_TF		(1 << 10)
+#define PSC_I2SSTAT_TE		(1 << 9)
+#define PSC_I2SSTAT_TR		(1 << 8)
+#define PSC_I2SSTAT_RB		(1 << 5)
+#define PSC_I2SSTAT_TB		(1 << 4)
+#define PSC_I2SSTAT_DI		(1 << 2)
+#define PSC_I2SSTAT_DR		(1 << 1)
+#define PSC_I2SSTAT_SR		(1 << 0)
+
+/* I2S Event Register.
+*/
+#define PSC_I2SEVNT_RR		(1 << 13)
+#define PSC_I2SEVNT_RO		(1 << 12)
+#define PSC_I2SEVNT_RU		(1 << 11)
+#define PSC_I2SEVNT_TR		(1 << 10)
+#define PSC_I2SEVNT_TO		(1 << 9)
+#define PSC_I2SEVNT_TU		(1 << 8)
+#define PSC_I2SEVNT_RD		(1 << 5)
+#define PSC_I2SEVNT_TD		(1 << 4)
+
+/* PSC in SPI Mode.
+*/
+typedef struct	psc_spi {
+	u32	psc_sel;
+	u32	psc_ctrl;
+	u32	psc_spicfg;
+	u32	psc_spimsk;
+	u32	psc_spipcr;
+	u32	psc_spistat;
+	u32	psc_spievent;
+	u32	psc_spitxrx;
+} psc_spi_t;
+
+/* SPI Config Register.
+*/
+#define PSC_SPICFG_RT_MASK	(3 << 30)
+#define PSC_SPICFG_RT_FIFO1	(0 << 30)
+#define PSC_SPICFG_RT_FIFO2	(1 << 30)
+#define PSC_SPICFG_RT_FIFO4	(2 << 30)
+#define PSC_SPICFG_RT_FIFO8	(3 << 30)
+
+#define PSC_SPICFG_TT_MASK	(3 << 28)
+#define PSC_SPICFG_TT_FIFO1	(0 << 28)
+#define PSC_SPICFG_TT_FIFO2	(1 << 28)
+#define PSC_SPICFG_TT_FIFO4	(2 << 28)
+#define PSC_SPICFG_TT_FIFO8	(3 << 28)
+
+#define PSC_SPICFG_DD_DISABLE	(1 << 27)
+#define PSC_SPICFG_DE_ENABLE	(1 << 26)
+#define PSC_SPICFG_CLR_BAUD(x)	((x) & ~((0x3f) << 15))
+#define PSC_SPICFG_SET_BAUD(x)	(((x) & 0x3f) << 15)
+
+#define PSC_SPICFG_SET_DIV(x)	(((x) & 0x03) << 13)
+#define PSC_SPICFG_DIV2		0
+#define PSC_SPICFG_DIV4		1
+#define PSC_SPICFG_DIV8		2
+#define PSC_SPICFG_DIV16	3
+
+#define PSC_SPICFG_BI		(1 << 12)
+#define PSC_SPICFG_PSE		(1 << 11)
+#define PSC_SPICFG_CGE		(1 << 10)
+#define PSC_SPICFG_CDE		(1 << 9)
+
+#define PSC_SPICFG_CLR_LEN(x)	((x) & ~((0x1f) << 4))
+#define PSC_SPICFG_SET_LEN(x)	(((x-1) & 0x1f) << 4)
+
+#define PSC_SPICFG_LB		(1 << 3)
+#define PSC_SPICFG_MLF		(1 << 1)
+#define PSC_SPICFG_MO		(1 << 0)
+
+/* SPI Mask Register.
+*/
+#define PSC_SPIMSK_MM		(1 << 16)
+#define PSC_SPIMSK_RR		(1 << 13)
+#define PSC_SPIMSK_RO		(1 << 12)
+#define PSC_SPIMSK_RU		(1 << 11)
+#define PSC_SPIMSK_TR		(1 << 10)
+#define PSC_SPIMSK_TO		(1 << 9)
+#define PSC_SPIMSK_TU		(1 << 8)
+#define PSC_SPIMSK_SD		(1 << 5)
+#define PSC_SPIMSK_MD		(1 << 4)
+#define PSC_SPIMSK_ALLMASK	(PSC_SPIMSK_MM | PSC_SPIMSK_RR | \
+				 PSC_SPIMSK_RO | PSC_SPIMSK_TO | \
+				 PSC_SPIMSK_TU | PSC_SPIMSK_SD | \
+				 PSC_SPIMSK_MD)
+
+/* SPI Protocol Control Register.
+*/
+#define PSC_SPIPCR_RC		(1 << 6)
+#define PSC_SPIPCR_SP		(1 << 5)
+#define PSC_SPIPCR_SS		(1 << 4)
+#define PSC_SPIPCR_TC		(1 << 2)
+#define PSC_SPIPCR_MS		(1 << 0)
+
+/* SPI Status register (read only).
+*/
+#define PSC_SPISTAT_RF		(1 << 13)
+#define PSC_SPISTAT_RE		(1 << 12)
+#define PSC_SPISTAT_RR		(1 << 11)
+#define PSC_SPISTAT_TF		(1 << 10)
+#define PSC_SPISTAT_TE		(1 << 9)
+#define PSC_SPISTAT_TR		(1 << 8)
+#define PSC_SPISTAT_SB		(1 << 5)
+#define PSC_SPISTAT_MB		(1 << 4)
+#define PSC_SPISTAT_DI		(1 << 2)
+#define PSC_SPISTAT_DR		(1 << 1)
+#define PSC_SPISTAT_SR		(1 << 0)
+
+/* SPI Event Register.
+*/
+#define PSC_SPIEVNT_MM		(1 << 16)
+#define PSC_SPIEVNT_RR		(1 << 13)
+#define PSC_SPIEVNT_RO		(1 << 12)
+#define PSC_SPIEVNT_RU		(1 << 11)
+#define PSC_SPIEVNT_TR		(1 << 10)
+#define PSC_SPIEVNT_TO		(1 << 9)
+#define PSC_SPIEVNT_TU		(1 << 8)
+#define PSC_SPIEVNT_SD		(1 << 5)
+#define PSC_SPIEVNT_MD		(1 << 4)
+
+/* Transmit register control.
+*/
+#define PSC_SPITXRX_LC		(1 << 29)
+#define PSC_SPITXRX_SR		(1 << 28)
+
+/* PSC in SMBus (I2C) Mode.
+*/
+typedef struct	psc_smb {
+	u32	psc_sel;
+	u32	psc_ctrl;
+	u32	psc_smbcfg;
+	u32	psc_smbmsk;
+	u32	psc_smbpcr;
+	u32	psc_smbstat;
+	u32	psc_smbevnt;
+	u32	psc_smbtxrx;
+	u32	psc_smbtmr;
+} psc_smb_t;
+
+/* SMBus Config Register.
+*/
+#define PSC_SMBCFG_RT_MASK	(3 << 30)
+#define PSC_SMBCFG_RT_FIFO1	(0 << 30)
+#define PSC_SMBCFG_RT_FIFO2	(1 << 30)
+#define PSC_SMBCFG_RT_FIFO4	(2 << 30)
+#define PSC_SMBCFG_RT_FIFO8	(3 << 30)
+
+#define PSC_SMBCFG_TT_MASK	(3 << 28)
+#define PSC_SMBCFG_TT_FIFO1	(0 << 28)
+#define PSC_SMBCFG_TT_FIFO2	(1 << 28)
+#define PSC_SMBCFG_TT_FIFO4	(2 << 28)
+#define PSC_SMBCFG_TT_FIFO8	(3 << 28)
+
+#define PSC_SMBCFG_DD_DISABLE	(1 << 27)
+#define PSC_SMBCFG_DE_ENABLE	(1 << 26)
+
+#define PSC_SMBCFG_SET_DIV(x)	(((x) & 0x03) << 13)
+#define PSC_SMBCFG_DIV2		0
+#define PSC_SMBCFG_DIV4		1
+#define PSC_SMBCFG_DIV8		2
+#define PSC_SMBCFG_DIV16	3
+
+#define PSC_SMBCFG_GCE		(1 << 9)
+#define PSC_SMBCFG_SFM		(1 << 8)
+
+#define PSC_SMBCFG_SET_SLV(x)	(((x) & 0x7f) << 1)
+
+/* SMBus Mask Register.
+*/
+#define PSC_SMBMSK_DN		(1 << 30)
+#define PSC_SMBMSK_AN		(1 << 29)
+#define PSC_SMBMSK_AL		(1 << 28)
+#define PSC_SMBMSK_RR		(1 << 13)
+#define PSC_SMBMSK_RO		(1 << 12)
+#define PSC_SMBMSK_RU		(1 << 11)
+#define PSC_SMBMSK_TR		(1 << 10)
+#define PSC_SMBMSK_TO		(1 << 9)
+#define PSC_SMBMSK_TU		(1 << 8)
+#define PSC_SMBMSK_SD		(1 << 5)
+#define PSC_SMBMSK_MD		(1 << 4)
+#define PSC_SMBMSK_ALLMASK	(PSC_SMBMSK_DN | PSC_SMBMSK_AN | \
+				 PSC_SMBMSK_AL | PSC_SMBMSK_RR | \
+				 PSC_SMBMSK_RO | PSC_SMBMSK_TO | \
+				 PSC_SMBMSK_TU | PSC_SMBMSK_SD | \
+				 PSC_SMBMSK_MD)
+
+/* SMBus Protocol Control Register.
+*/
+#define PSC_SMBPCR_DC		(1 << 2)
+#define PSC_SMBPCR_MS		(1 << 0)
+
+/* SMBus Status register (read only).
+*/
+#define PSC_SMBSTAT_BB		(1 << 28)
+#define PSC_SMBSTAT_RF		(1 << 13)
+#define PSC_SMBSTAT_RE		(1 << 12)
+#define PSC_SMBSTAT_RR		(1 << 11)
+#define PSC_SMBSTAT_TF		(1 << 10)
+#define PSC_SMBSTAT_TE		(1 << 9)
+#define PSC_SMBSTAT_TR		(1 << 8)
+#define PSC_SMBSTAT_SB		(1 << 5)
+#define PSC_SMBSTAT_MB		(1 << 4)
+#define PSC_SMBSTAT_DI		(1 << 2)
+#define PSC_SMBSTAT_DR		(1 << 1)
+#define PSC_SMBSTAT_SR		(1 << 0)
+
+/* SMBus Event Register.
+*/
+#define PSC_SMBEVNT_DN		(1 << 30)
+#define PSC_SMBEVNT_AN		(1 << 29)
+#define PSC_SMBEVNT_AL		(1 << 28)
+#define PSC_SMBEVNT_RR		(1 << 13)
+#define PSC_SMBEVNT_RO		(1 << 12)
+#define PSC_SMBEVNT_RU		(1 << 11)
+#define PSC_SMBEVNT_TR		(1 << 10)
+#define PSC_SMBEVNT_TO		(1 << 9)
+#define PSC_SMBEVNT_TU		(1 << 8)
+#define PSC_SMBEVNT_SD		(1 << 5)
+#define PSC_SMBEVNT_MD		(1 << 4)
+#define PSC_SMBEVNT_ALLCLR	(PSC_SMBEVNT_DN | PSC_SMBEVNT_AN | \
+				 PSC_SMBEVNT_AL | PSC_SMBEVNT_RR | \
+				 PSC_SMBEVNT_RO | PSC_SMBEVNT_TO | \
+				 PSC_SMBEVNT_TU | PSC_SMBEVNT_SD | \
+				 PSC_SMBEVNT_MD)
+
+/* Transmit register control.
+*/
+#define PSC_SMBTXRX_RSR		(1 << 30)
+#define PSC_SMBTXRX_STP		(1 << 29)
+#define PSC_SMBTXRX_DATAMASK	(0xff)
+
+/* SMBus protocol timers register.
+*/
+#define PSC_SMBTMR_SET_TH(x)	(((x) & 0x3) << 30)
+#define PSC_SMBTMR_SET_PS(x)	(((x) & 0x1f) << 25)
+#define PSC_SMBTMR_SET_PU(x)	(((x) & 0x1f) << 20)
+#define PSC_SMBTMR_SET_SH(x)	(((x) & 0x1f) << 15)
+#define PSC_SMBTMR_SET_SU(x)	(((x) & 0x1f) << 10)
+#define PSC_SMBTMR_SET_CL(x)	(((x) & 0x1f) << 5)
+#define PSC_SMBTMR_SET_CH(x)	(((x) & 0x1f) << 0)
 
 
 #endif /* _AU1000_PSC_H_ */
diff -Nru a/include/asm-mips/mach-db1x00/db1x00.h b/include/asm-mips/mach-db1x00/db1x00.h
--- a/include/asm-mips/mach-db1x00/db1x00.h	2005-03-01 23:38:58 -08:00
+++ b/include/asm-mips/mach-db1x00/db1x00.h	2005-03-01 23:38:58 -08:00
@@ -4,6 +4,7 @@
  * Copyright 2001 MontaVista Software Inc.
  * Author: MontaVista Software, Inc.
  *         	ppopov@mvista.com or source@mvista.com
+ * Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org)
  *
  * ########################################################################
  *
@@ -26,6 +27,8 @@
  */
 #ifndef __ASM_DB1X00_H
 #define __ASM_DB1X00_H
+
+#include <linux/config.h>
 
 #ifdef CONFIG_MIPS_DB1550
 #define BCSR_KSEG1_ADDR 0xAF000000
diff -Nru a/include/asm-mips/mach-ev64120/mach-gt64120.h b/include/asm-mips/mach-ev64120/mach-gt64120.h
--- a/include/asm-mips/mach-ev64120/mach-gt64120.h	2005-03-01 23:39:08 -08:00
+++ b/include/asm-mips/mach-ev64120/mach-gt64120.h	2005-03-01 23:39:08 -08:00
@@ -18,29 +18,29 @@
 /*
  *   PCI Bus allocation
  */
-#define GT_PCI_MEM_BASE    0x12000000UL
-#define GT_PCI_MEM_SIZE    0x02000000UL
-#define GT_PCI_IO_BASE     0x10000000UL
-#define GT_PCI_IO_SIZE     0x02000000UL
-#define GT_ISA_IO_BASE     PCI_IO_BASE
+#define GT_PCI_MEM_BASE	0x12000000UL
+#define GT_PCI_MEM_SIZE	0x02000000UL
+#define GT_PCI_IO_BASE	0x10000000UL
+#define GT_PCI_IO_SIZE	0x02000000UL
+#define GT_ISA_IO_BASE	PCI_IO_BASE
 
 /*
  *   Duart I/O ports.
  */
-#define EV64120_COM1_BASE_ADDR  (0x1d000000 + 0x20)
-#define EV64120_COM2_BASE_ADDR  (0x1d000000 + 0x00)
+#define EV64120_COM1_BASE_ADDR	(0x1d000000 + 0x20)
+#define EV64120_COM2_BASE_ADDR	(0x1d000000 + 0x00)
 
 
 /*
  *   EV64120 interrupt controller register base.
  */
-#define EV64120_ICTRL_REGS_BASE   (KSEG1ADDR(0x1f000000))
+#define EV64120_ICTRL_REGS_BASE	(KSEG1ADDR(0x1f000000))
 
 /*
  *   EV64120 UART register base.
  */
-#define EV64120_UART0_REGS_BASE    (KSEG1ADDR(EV64120_COM1_BASE_ADDR))
-#define EV64120_UART1_REGS_BASE    (KSEG1ADDR(EV64120_COM2_BASE_ADDR))
+#define EV64120_UART0_REGS_BASE	(KSEG1ADDR(EV64120_COM1_BASE_ADDR))
+#define EV64120_UART1_REGS_BASE	(KSEG1ADDR(EV64120_COM2_BASE_ADDR))
 #define EV64120_BASE_BAUD ( 3686400 / 16 )
 
 /*
diff -Nru a/include/asm-mips/mach-ev96100/mach-gt64120.h b/include/asm-mips/mach-ev96100/mach-gt64120.h
--- a/include/asm-mips/mach-ev96100/mach-gt64120.h	2005-03-01 23:39:18 -08:00
+++ b/include/asm-mips/mach-ev96100/mach-gt64120.h	2005-03-01 23:39:18 -08:00
@@ -18,29 +18,29 @@
  *
  *   (Guessing ...)
  */
-#define GT_PCI_MEM_BASE    0x12000000UL
-#define GT_PCI_MEM_SIZE    0x02000000UL
-#define GT_PCI_IO_BASE     0x10000000UL
-#define GT_PCI_IO_SIZE     0x02000000UL
-#define GT_ISA_IO_BASE     PCI_IO_BASE
+#define GT_PCI_MEM_BASE	0x12000000UL
+#define GT_PCI_MEM_SIZE	0x02000000UL
+#define GT_PCI_IO_BASE	0x10000000UL
+#define GT_PCI_IO_SIZE	0x02000000UL
+#define GT_ISA_IO_BASE	PCI_IO_BASE
 
 /*
  *   Duart I/O ports.
  */
-#define EV96100_COM1_BASE_ADDR  (0xBD000000 + 0x20)
-#define EV96100_COM2_BASE_ADDR  (0xBD000000 + 0x00)
+#define EV96100_COM1_BASE_ADDR	(0xBD000000 + 0x20)
+#define EV96100_COM2_BASE_ADDR	(0xBD000000 + 0x00)
 
 
 /*
  *   EV96100 interrupt controller register base.
  */
-#define EV96100_ICTRL_REGS_BASE   (KSEG1ADDR(0x1f000000))
+#define EV96100_ICTRL_REGS_BASE	(KSEG1ADDR(0x1f000000))
 
 /*
  *   EV96100 UART register base.
  */
-#define EV96100_UART0_REGS_BASE    EV96100_COM1_BASE_ADDR
-#define EV96100_UART1_REGS_BASE    EV96100_COM2_BASE_ADDR
-#define EV96100_BASE_BAUD ( 3686400 / 16 )
+#define EV96100_UART0_REGS_BASE	EV96100_COM1_BASE_ADDR
+#define EV96100_UART1_REGS_BASE	EV96100_COM2_BASE_ADDR
+#define EV96100_BASE_BAUD	( 3686400 / 16 )
 
 #endif /* _ASM_GT64120_EV96100_GT64120_DEP_H */
diff -Nru a/include/asm-mips/mach-generic/ide.h b/include/asm-mips/mach-generic/ide.h
--- a/include/asm-mips/mach-generic/ide.h	2005-03-01 23:38:59 -08:00
+++ b/include/asm-mips/mach-generic/ide.h	2005-03-01 23:38:59 -08:00
@@ -16,6 +16,8 @@
 #ifdef __KERNEL__
 
 #include <linux/config.h>
+#include <linux/pci.h>
+#include <linux/stddef.h>
 
 #ifndef MAX_HWIFS
 # ifdef CONFIG_BLK_DEV_IDEPCI
@@ -27,32 +29,68 @@
 
 #define IDE_ARCH_OBSOLETE_DEFAULTS
 
+static __inline__ int ide_probe_legacy(void)
+{
+#ifdef CONFIG_PCI
+	struct pci_dev *dev;
+	if ((dev = pci_get_class(PCI_CLASS_BRIDGE_EISA << 8, NULL)) != NULL ||
+	    (dev = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, NULL)) != NULL) {
+		pci_dev_put(dev);
+
+		return 1;
+	}
+	return 0;
+#elif defined(CONFIG_EISA) || defined(CONFIG_ISA)
+	return 1;
+#else
+	return 0;
+#endif
+}
+
 static __inline__ int ide_default_irq(unsigned long base)
 {
-	switch (base) {
-		case 0x1f0: return 14;
-		case 0x170: return 15;
-		case 0x1e8: return 11;
-		case 0x168: return 10;
-		case 0x1e0: return 8;
-		case 0x160: return 12;
+	if (ide_probe_legacy())
+		switch (base) {
+		case 0x1f0:
+			return 14;
+		case 0x170:
+			return 15;
+		case 0x1e8:
+			return 11;
+		case 0x168:
+			return 10;
+		case 0x1e0:
+			return 8;
+		case 0x160:
+			return 12;
 		default:
 			return 0;
-	}
+		}
+	else
+		return 0;
 }
 
 static __inline__ unsigned long ide_default_io_base(int index)
 {
-	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;
+	if (ide_probe_legacy())
+		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;
-	}
+		}
+	else
+		return 0;
 }
 
 #define IDE_ARCH_OBSOLETE_INIT
@@ -64,7 +102,17 @@
 #define ide_init_default_irq(base)	ide_default_irq(base)
 #endif
 
-#include <asm-generic/ide_iops.h>
+/* MIPS port and memory-mapped I/O string operations.  */
+
+#define __ide_insw	insw
+#define __ide_insl	insl
+#define __ide_outsw	outsw
+#define __ide_outsl	outsl
+
+#define __ide_mm_insw	readsw
+#define __ide_mm_insl	readsl
+#define __ide_mm_outsw	writesw
+#define __ide_mm_outsl	writesl
 
 #endif /* __KERNEL__ */
 
diff -Nru a/include/asm-mips/mach-ip27/cpu-feature-overrides.h b/include/asm-mips/mach-ip27/cpu-feature-overrides.h
--- a/include/asm-mips/mach-ip27/cpu-feature-overrides.h	2005-03-01 23:39:08 -08:00
+++ b/include/asm-mips/mach-ip27/cpu-feature-overrides.h	2005-03-01 23:39:08 -08:00
@@ -25,6 +25,7 @@
 #define cpu_has_vtag_icache	0
 #define cpu_has_dc_aliases	0
 #define cpu_has_ic_fills_f_dc	0
+#define cpu_icache_snoops_remote_store	1
 
 #define cpu_has_nofpuex		0
 #define cpu_has_64bits		1
diff -Nru a/include/asm-mips/mach-ip32/cpu-feature-overrides.h b/include/asm-mips/mach-ip32/cpu-feature-overrides.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-mips/mach-ip32/cpu-feature-overrides.h	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,41 @@
+/*
+ * This file 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 Ilya A. Volynets-Evenbakh
+ * Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org)
+ */
+#ifndef __ASM_MACH_IP32_CPU_FEATURE_OVERRIDES_H
+#define __ASM_MACH_IP32_CPU_FEATURE_OVERRIDES_H
+
+#include <linux/config.h>
+
+/*
+ * R5000 has an interesting "restriction":  ll(d)/sc(d)
+ * instructions to XKPHYS region simply do uncached bus
+ * requests. This breaks all the atomic bitops functions.
+ * so, for 64bit IP32 kernel we just don't use ll/sc.
+ * This does not affect luserland.
+ */
+#if defined(CONFIG_CPU_R5000) && defined(CONFIG_MIPS64)
+#define cpu_has_llsc		0
+#else
+#define cpu_has_llsc		1
+#endif
+
+/* Settings which are common for all ip32 CPUs */
+#define cpu_has_tlb		1
+#define cpu_has_4kex		1
+#define cpu_has_fpu		1
+#define cpu_has_32fpr		1
+#define cpu_has_counter		1
+#define cpu_has_mips16		0
+#define cpu_has_vce		0
+#define cpu_has_cache_cdex_s	0
+#define cpu_has_mcheck		0
+#define cpu_has_ejtag		0
+#define cpu_has_vtag_icache	0
+#define cpu_has_ic_fills_f_dc	0
+
+#endif /* __ASM_MACH_IP32_CPU_FEATURE_OVERRIDES_H */
diff -Nru a/include/asm-mips/mach-ip32/mc146818rtc.h b/include/asm-mips/mach-ip32/mc146818rtc.h
--- a/include/asm-mips/mach-ip32/mc146818rtc.h	2005-03-01 23:38:52 -08:00
+++ b/include/asm-mips/mach-ip32/mc146818rtc.h	2005-03-01 23:38:52 -08:00
@@ -15,7 +15,6 @@
 #include <asm/ip32/mace.h>
 
 #define RTC_PORT(x)	(0x70 + (x))
-#define RTC_IRQ		MACEISA_RTC_IRQ
 
 static unsigned char CMOS_READ(unsigned long addr)
 {
diff -Nru a/include/asm-mips/mach-ip32/spaces.h b/include/asm-mips/mach-ip32/spaces.h
--- a/include/asm-mips/mach-ip32/spaces.h	2005-03-01 23:39:18 -08:00
+++ b/include/asm-mips/mach-ip32/spaces.h	2005-03-01 23:39:18 -08:00
@@ -3,20 +3,13 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1994 - 1999, 2000, 03, 04 Ralf Baechle
+ * Copyright (C) 1994 - 1999, 2000, 03, 04, 05 Ralf Baechle (ralf@linux-mips.org)
  * Copyright (C) 2000, 2002  Maciej W. Rozycki
  * Copyright (C) 1990, 1999, 2000 Silicon Graphics, Inc.
  */
 #ifndef _ASM_MACH_IP32_SPACES_H
 #define _ASM_MACH_IP32_SPACES_H
 
-#include <linux/config.h>
-
-/*
- * This handles the memory map.
- */
-#define PAGE_OFFSET		0xffffffff80000000
-
 /*
  * Memory above this physical address will be considered highmem.
  * Fixme: 59 bits is a fictive number and makes assumptions about processors
@@ -26,11 +19,7 @@
 #define HIGHMEM_START		(1UL << 59UL)
 #endif
 
-#ifdef CONFIG_DMA_NONCOHERENT
 #define CAC_BASE		0x9800000000000000
-#else
-#define CAC_BASE		0xa800000000000000
-#endif
 #define IO_BASE			0x9000000000000000
 #define UNCAC_BASE		0x9000000000000000
 #define MAP_BASE		0xc000000000000000
@@ -38,5 +27,10 @@
 #define TO_PHYS(x)		(             ((x) & TO_PHYS_MASK))
 #define TO_CAC(x)		(CAC_BASE   | ((x) & TO_PHYS_MASK))
 #define TO_UNCAC(x)		(UNCAC_BASE | ((x) & TO_PHYS_MASK))
+
+/*
+ * This handles the memory map.
+ */
+#define PAGE_OFFSET		CAC_BASE
 
 #endif /* __ASM_MACH_IP32_SPACES_H */
diff -Nru a/include/asm-mips/mach-ja/cpu-feature-overrides.h b/include/asm-mips/mach-ja/cpu-feature-overrides.h
--- a/include/asm-mips/mach-ja/cpu-feature-overrides.h	2005-03-01 23:39:08 -08:00
+++ b/include/asm-mips/mach-ja/cpu-feature-overrides.h	2005-03-01 23:39:08 -08:00
@@ -25,6 +25,7 @@
 #define cpu_has_vtag_icache	0
 #define cpu_has_dc_aliases	0
 #define cpu_has_ic_fills_f_dc	0
+#define cpu_icache_snoops_remote_store	0
 
 #define cpu_has_nofpuex		0
 #define cpu_has_64bits		1
diff -Nru a/include/asm-mips/mach-lasat/mach-gt64120.h b/include/asm-mips/mach-lasat/mach-gt64120.h
--- a/include/asm-mips/mach-lasat/mach-gt64120.h	2005-03-01 23:38:52 -08:00
+++ b/include/asm-mips/mach-lasat/mach-gt64120.h	2005-03-01 23:38:52 -08:00
@@ -18,10 +18,10 @@
  *
  *   (Guessing ...)
  */
-#define GT_PCI_MEM_BASE    0x12000000UL
-#define GT_PCI_MEM_SIZE    0x02000000UL
-#define GT_PCI_IO_BASE     0x10000000UL
-#define GT_PCI_IO_SIZE     0x02000000UL
-#define GT_ISA_IO_BASE     PCI_IO_BASE
+#define GT_PCI_MEM_BASE	0x12000000UL
+#define GT_PCI_MEM_SIZE	0x02000000UL
+#define GT_PCI_IO_BASE	0x10000000UL
+#define GT_PCI_IO_SIZE	0x02000000UL
+#define GT_ISA_IO_BASE	PCI_IO_BASE
 
 #endif /* _ASM_GT64120_LASAT_GT64120_DEP_H */
diff -Nru a/include/asm-mips/mach-mips/cpu-feature-overrides.h b/include/asm-mips/mach-mips/cpu-feature-overrides.h
--- a/include/asm-mips/mach-mips/cpu-feature-overrides.h	2005-03-01 23:38:54 -08:00
+++ b/include/asm-mips/mach-mips/cpu-feature-overrides.h	2005-03-01 23:38:54 -08:00
@@ -4,9 +4,12 @@
  * for more details.
  *
  * Copyright (C) 2003, 2004 Chris Dearman
+ * Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org)
  */
 #ifndef __ASM_MACH_MIPS_CPU_FEATURE_OVERRIDES_H
 #define __ASM_MACH_MIPS_CPU_FEATURE_OVERRIDES_H
+
+#include <linux/config.h>
 
 /*
  * CPU feature overrides for MIPS boards
diff -Nru a/include/asm-mips/mach-mips/mach-gt64120.h b/include/asm-mips/mach-mips/mach-gt64120.h
--- a/include/asm-mips/mach-mips/mach-gt64120.h	2005-03-01 23:38:57 -08:00
+++ b/include/asm-mips/mach-mips/mach-gt64120.h	2005-03-01 23:38:57 -08:00
@@ -8,7 +8,7 @@
 #ifndef _ASM_MACH_MIPS_MACH_GT64120_DEP_H
 #define _ASM_MACH_MIPS_MACH_GT64120_DEP_H
 
-#define MIPS_GT_BASE    0x1be00000
+#define MIPS_GT_BASE	0x1be00000
 
 extern unsigned long _pcictrl_gt64120;
 /*
@@ -19,10 +19,10 @@
 /*
  *   PCI Bus allocation
  */
-#define GT_PCI_MEM_BASE    0x12000000UL
-#define GT_PCI_MEM_SIZE    0x02000000UL
-#define GT_PCI_IO_BASE     0x10000000UL
-#define GT_PCI_IO_SIZE     0x02000000UL
-#define GT_ISA_IO_BASE     PCI_IO_BASE
+#define GT_PCI_MEM_BASE	0x12000000UL
+#define GT_PCI_MEM_SIZE	0x02000000UL
+#define GT_PCI_IO_BASE	0x10000000UL
+#define GT_PCI_IO_SIZE	0x02000000UL
+#define GT_ISA_IO_BASE	PCI_IO_BASE
 
 #endif /* _ASM_MACH_MIPS_MACH_GT64120_DEP_H */
diff -Nru a/include/asm-mips/mach-ocelot/mach-gt64120.h b/include/asm-mips/mach-ocelot/mach-gt64120.h
--- a/include/asm-mips/mach-ocelot/mach-gt64120.h	2005-03-01 23:38:59 -08:00
+++ b/include/asm-mips/mach-ocelot/mach-gt64120.h	2005-03-01 23:38:59 -08:00
@@ -13,14 +13,14 @@
 /*
  * PCI address allocation
  */
-#define GT_PCI_MEM_BASE    (0x22000000UL)
-#define GT_PCI_MEM_SIZE    GT_DEF_PCI0_MEM0_SIZE
-#define GT_PCI_IO_BASE     (0x20000000UL)
-#define GT_PCI_IO_SIZE     GT_DEF_PCI0_IO_SIZE
+#define GT_PCI_MEM_BASE	(0x22000000UL)
+#define GT_PCI_MEM_SIZE	GT_DEF_PCI0_MEM0_SIZE
+#define GT_PCI_IO_BASE	(0x20000000UL)
+#define GT_PCI_IO_SIZE	GT_DEF_PCI0_IO_SIZE
 
 extern unsigned long gt64120_base;
 
-#define GT64120_BASE       (gt64120_base)
+#define GT64120_BASE	(gt64120_base)
 
 /*
  * GT timer irq
diff -Nru a/include/asm-mips/mach-ocelot3/cpu-feature-overrides.h b/include/asm-mips/mach-ocelot3/cpu-feature-overrides.h
--- a/include/asm-mips/mach-ocelot3/cpu-feature-overrides.h	2005-03-01 23:38:53 -08:00
+++ b/include/asm-mips/mach-ocelot3/cpu-feature-overrides.h	2005-03-01 23:38:53 -08:00
@@ -28,6 +28,7 @@
 #define cpu_has_vtag_icache	0
 #define cpu_has_dc_aliases	0
 #define cpu_has_ic_fills_f_dc	0
+#define cpu_icache_snoops_remote_store	0
 
 #define cpu_has_nofpuex 	0
 #define cpu_has_64bits		1
diff -Nru a/include/asm-mips/mach-pb1x00/pb1550.h b/include/asm-mips/mach-pb1x00/pb1550.h
--- a/include/asm-mips/mach-pb1x00/pb1550.h	2005-03-01 23:39:09 -08:00
+++ b/include/asm-mips/mach-pb1x00/pb1550.h	2005-03-01 23:39:09 -08:00
@@ -3,6 +3,7 @@
  * Board Registers defines.
  *
  * Copyright 2004 Embedded Edge LLC.
+ * Copyright 2005 Ralf Baechle (ralf@linux-mips.org)
  *
  * ########################################################################
  *
@@ -26,7 +27,18 @@
 #ifndef __ASM_PB1550_H
 #define __ASM_PB1550_H
 
+#include <linux/config.h>
 #include <linux/types.h>
+
+#define DBDMA_AC97_TX_CHAN DSCR_CMD0_PSC1_TX
+#define DBDMA_AC97_RX_CHAN DSCR_CMD0_PSC1_RX
+#define DBDMA_I2S_TX_CHAN DSCR_CMD0_PSC3_TX
+#define DBDMA_I2S_RX_CHAN DSCR_CMD0_PSC3_RX
+
+#define SPI_PSC_BASE        PSC0_BASE_ADDR
+#define AC97_PSC_BASE       PSC1_BASE_ADDR
+#define SMBUS_PSC_BASE      PSC2_BASE_ADDR
+#define I2S_PSC_BASE        PSC3_BASE_ADDR
 
 #define BCSR_PHYS_ADDR 0xAF000000
 
diff -Nru a/include/asm-mips/mach-sibyte/cpu-feature-overrides.h b/include/asm-mips/mach-sibyte/cpu-feature-overrides.h
--- a/include/asm-mips/mach-sibyte/cpu-feature-overrides.h	2005-03-01 23:38:57 -08:00
+++ b/include/asm-mips/mach-sibyte/cpu-feature-overrides.h	2005-03-01 23:38:57 -08:00
@@ -25,6 +25,7 @@
 #define cpu_has_vtag_icache	1
 #define cpu_has_dc_aliases	0
 #define cpu_has_ic_fills_f_dc	0
+#define cpu_icache_snoops_remote_store	0
 
 #define cpu_has_nofpuex		0
 #define cpu_has_64bits		1
diff -Nru a/include/asm-mips/mach-yosemite/cpu-feature-overrides.h b/include/asm-mips/mach-yosemite/cpu-feature-overrides.h
--- a/include/asm-mips/mach-yosemite/cpu-feature-overrides.h	2005-03-01 23:39:06 -08:00
+++ b/include/asm-mips/mach-yosemite/cpu-feature-overrides.h	2005-03-01 23:39:06 -08:00
@@ -25,6 +25,7 @@
 #define cpu_has_vtag_icache	0
 #define cpu_has_dc_aliases	0
 #define cpu_has_ic_fills_f_dc	0
+#define cpu_icache_snoops_remote_store	0
 
 #define cpu_has_nofpuex		0
 #define cpu_has_64bits		1
diff -Nru a/include/asm-mips/mipsregs.h b/include/asm-mips/mipsregs.h
--- a/include/asm-mips/mipsregs.h	2005-03-01 23:38:57 -08:00
+++ b/include/asm-mips/mipsregs.h	2005-03-01 23:38:57 -08:00
@@ -533,31 +533,50 @@
 #ifndef __ASSEMBLY__
 
 /*
- * Functions to access the r10k performance counter and control registers
+ * Functions to access the R10000 performance counters.  These are basically
+ * mfc0 and mtc0 instructions from and to coprocessor register with a 5-bit
+ * performance counter number encoded into bits 1 ... 5 of the instruction.
+ * Only performance counters 0 to 1 actually exist, so for a non-R10000 aware
+ * disassembler these will look like an access to sel 0 or 1.
  */
-#define read_r10k_perf_cntr(counter)                            \
-({ unsigned int __res;                                          \
-        __asm__ __volatile__(                                   \
-        "mfpc\t%0, "STR(counter)                                \
-        : "=r" (__res));                                        \
-        __res;})
+#define read_r10k_perf_cntr(counter)				\
+({								\
+	unsigned int __res;					\
+	__asm__ __volatile__(					\
+	"mfpc\t%0, %1"						\
+        : "=r" (__res)						\
+	: "i" (counter));					\
+								\
+        __res;							\
+})
 
 #define write_r10k_perf_cntr(counter,val)                       \
-        __asm__ __volatile__(                                   \
-        "mtpc\t%0, "STR(counter)                                \
-        : : "r" (val));
-
-#define read_r10k_perf_cntl(counter)                            \
-({ unsigned int __res;                                          \
-        __asm__ __volatile__(                                   \
-        "mfps\t%0, "STR(counter)                                \
-        : "=r" (__res));                                        \
-        __res;})
+do {								\
+	__asm__ __volatile__(					\
+	"mtpc\t%0, %1"						\
+	:							\
+	: "r" (val), "i" (counter));				\
+} while (0)
+
+#define read_r10k_perf_event(counter)				\
+({								\
+	unsigned int __res;					\
+	__asm__ __volatile__(					\
+	"mfps\t%0, %1"						\
+        : "=r" (__res)						\
+	: "i" (counter));					\
+								\
+        __res;							\
+})
 
 #define write_r10k_perf_cntl(counter,val)                       \
-        __asm__ __volatile__(                                   \
-        "mtps\t%0, "STR(counter)                                \
-        : : "r" (val));
+do {								\
+	__asm__ __volatile__(					\
+	"mtps\t%0, %1"						\
+	:							\
+	: "r" (val), "i" (counter));				\
+} while (0)
+
 
 /*
  * Macros to access the system control coprocessor
@@ -579,8 +598,10 @@
 })
 
 #define __read_64bit_c0_register(source, sel)				\
-({ unsigned long __res;							\
-	if (sel == 0)							\
+({ unsigned long long __res;						\
+	if (sizeof(unsigned long) == 4)					\
+		__res = __read_64bit_c0_split(source, sel);		\
+	else if (sel == 0)						\
 		__asm__ __volatile__(					\
 			".set\tmips3\n\t"				\
 			"dmfc0\t%0, " #source "\n\t"			\
@@ -611,7 +632,9 @@
 
 #define __write_64bit_c0_register(register, sel, value)			\
 do {									\
-	if (sel == 0)							\
+	if (sizeof(unsigned long) == 4)					\
+		__write_64bit_c0_split(register, sel, value);		\
+	else if (sel == 0)						\
 		__asm__ __volatile__(					\
 			".set\tmips3\n\t"				\
 			"dmtc0\t%z0, " #register "\n\t"			\
@@ -627,8 +650,8 @@
 
 #define __read_ulong_c0_register(reg, sel)				\
 	((sizeof(unsigned long) == 4) ?					\
-	__read_32bit_c0_register(reg, sel) :				\
-	__read_64bit_c0_register(reg, sel))
+	(unsigned long) __read_32bit_c0_register(reg, sel) :		\
+	(unsigned long) __read_64bit_c0_register(reg, sel))
 
 #define __write_ulong_c0_register(reg, sel, val)			\
 do {									\
@@ -822,6 +845,10 @@
 #define read_c0_framemask()	__read_32bit_c0_register($21, 0)
 #define write_c0_framemask(val)	__write_32bit_c0_register($21, 0, val)
 
+/* RM9000 PerfControl performance counter control register */
+#define read_c0_perfcontrol()	__read_32bit_c0_register($22, 0)
+#define write_c0_perfcontrol(val) __write_32bit_c0_register($22, 0, val)
+
 #define read_c0_diag()		__read_32bit_c0_register($22, 0)
 #define write_c0_diag(val)	__write_32bit_c0_register($22, 0, val)
 
@@ -845,6 +872,30 @@
 
 #define read_c0_depc()		__read_ulong_c0_register($24, 0)
 #define write_c0_depc(val)	__write_ulong_c0_register($24, 0, val)
+
+/*
+ * MIPS32 / MIPS64 performance counters
+ */
+#define read_c0_perfctrl0()	__read_32bit_c0_register($25, 0)
+#define write_c0_perfctrl0(val)	__write_32bit_c0_register($25, 0, val)
+#define read_c0_perfcntr0()	__read_32bit_c0_register($25, 1)
+#define write_c0_perfcntr0(val)	__write_32bit_c0_register($25, 1, val)
+#define read_c0_perfctrl1()	__read_32bit_c0_register($25, 2)
+#define write_c0_perfctrl1(val)	__write_32bit_c0_register($25, 2, val)
+#define read_c0_perfcntr1()	__read_32bit_c0_register($25, 3)
+#define write_c0_perfcntr1(val)	__write_32bit_c0_register($25, 3, val)
+#define read_c0_perfctrl2()	__read_32bit_c0_register($25, 4)
+#define write_c0_perfctrl2(val)	__write_32bit_c0_register($25, 4, val)
+#define read_c0_perfcntr2()	__read_32bit_c0_register($25, 5)
+#define write_c0_perfcntr2(val)	__write_32bit_c0_register($25, 5, val)
+#define read_c0_perfctrl3()	__read_32bit_c0_register($25, 6)
+#define write_c0_perfctrl3(val)	__write_32bit_c0_register($25, 6, val)
+#define read_c0_perfcntr3()	__read_32bit_c0_register($25, 7)
+#define write_c0_perfcntr3(val)	__write_32bit_c0_register($25, 7, val)
+
+/* RM9000 PerfCount performance counter register */
+#define read_c0_perfcount()	__read_64bit_c0_register($25, 0)
+#define write_c0_perfcount(val)	__write_64bit_c0_register($25, 0, val)
 
 #define read_c0_ecc()		__read_32bit_c0_register($26, 0)
 #define write_c0_ecc(val)	__write_32bit_c0_register($26, 0, val)
diff -Nru a/include/asm-mips/mmu_context.h b/include/asm-mips/mmu_context.h
--- a/include/asm-mips/mmu_context.h	2005-03-01 23:38:56 -08:00
+++ b/include/asm-mips/mmu_context.h	2005-03-01 23:38:56 -08:00
@@ -19,26 +19,30 @@
 #include <asm/tlbflush.h>
 
 /*
- * For the fast tlb miss handlers, we currently keep a per cpu array
- * of pointers to the current pgd for each processor. Also, the proc.
- * id is stuffed into the context register. This should be changed to
- * use the processor id via current->processor, where current is stored
- * in watchhi/lo. The context register should be used to contiguously
- * map the page tables.
+ * For the fast tlb miss handlers, we keep a per cpu array of pointers
+ * to the current pgd for each processor. Also, the proc. id is stuffed
+ * into the context register.
  */
+extern unsigned long pgd_current[];
+
 #define TLBMISS_HANDLER_SETUP_PGD(pgd) \
 	pgd_current[smp_processor_id()] = (unsigned long)(pgd)
+
 #ifdef CONFIG_MIPS32
-#define TLBMISS_HANDLER_SETUP() \
-	write_c0_context((unsigned long) smp_processor_id() << 23); \
+#define TLBMISS_HANDLER_SETUP()						\
+	write_c0_context((unsigned long) smp_processor_id() << 23);	\
 	TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir)
 #endif
-#ifdef CONFIG_MIPS64
-#define TLBMISS_HANDLER_SETUP() \
+#if defined(CONFIG_MIPS64) && !defined(CONFIG_BUILD_ELF64)
+#define TLBMISS_HANDLER_SETUP()						\
 	write_c0_context((unsigned long) &pgd_current[smp_processor_id()] << 23); \
 	TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir)
 #endif
-extern unsigned long pgd_current[];
+#if defined(CONFIG_MIPS64) && defined(CONFIG_BUILD_ELF64)
+#define TLBMISS_HANDLER_SETUP()						\
+	write_c0_context((unsigned long) smp_processor_id() << 23);	\
+	TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir)
+#endif
 
 #if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
 
@@ -150,7 +154,7 @@
 activate_mm(struct mm_struct *prev, struct mm_struct *next)
 {
 	unsigned long flags;
-	int cpu = smp_processor_id();
+	unsigned int cpu = smp_processor_id();
 
 	local_irq_save(flags);
 
diff -Nru a/include/asm-mips/ng1.h b/include/asm-mips/ng1.h
--- a/include/asm-mips/ng1.h	2005-03-01 23:39:16 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,55 +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.
- *
- * SGI/Newport video card ioctl definitions
- */
-#ifndef _ASM_NG1_H
-#define _ASM_NG1_H
-
-typedef struct {
-        int flags;
-        __u16 w, h;
-        __u16 fields_sec;
-} ng1_vof_info_t;
-
-struct ng1_info {
-	struct gfx_info gfx_info;
-	__u8 boardrev;
-        __u8 rex3rev;
-        __u8 vc2rev;
-        __u8 monitortype;
-        __u8 videoinstalled;
-        __u8 mcrev;
-        __u8 bitplanes;
-        __u8 xmap9rev;
-        __u8 cmaprev;
-        ng1_vof_info_t ng1_vof_info;
-        __u8 bt445rev;
-        __u8 paneltype;
-};
-
-#define GFX_NAME_NEWPORT "NG1"
-
-/* ioctls */
-#define NG1_SET_CURSOR_HOTSPOT 21001
-struct ng1_set_cursor_hotspot {
-	unsigned short xhot;
-        unsigned short yhot;
-};
-
-#define NG1_SETDISPLAYMODE     21006
-struct ng1_setdisplaymode_args {
-        int wid;
-        unsigned int mode;
-};
-
-#define NG1_SETGAMMARAMP0      21007
-struct ng1_setgammaramp_args {
-        unsigned char red   [256];
-        unsigned char green [256];
-        unsigned char blue  [256];
-};
-
-#endif /* _ASM_NG1_H */
diff -Nru a/include/asm-mips/ng1hw.h b/include/asm-mips/ng1hw.h
--- a/include/asm-mips/ng1hw.h	2005-03-01 23:39:07 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,219 +0,0 @@
-/*
- * ng1hw.h: Tweaks the newport.h structures and definitions to be compatible
- * 	    with IRIX.  Quite ugly, but it works.
- *
- * Copyright (C) 1999 Ulf Carlsson (ulfc@thepuffingroup.com)
- */
-#ifndef _SGI_NG1HW_H
-#define _SGI_NG1HW_H
-
-#include <video/newport.h>
-
-#define rex3regs	newport_rexregs
-#define configregs	newport_cregs
-#define float_long	npfreg_t
-
-typedef struct newport_rexregs Rex3regs;
-typedef struct newport_cregs Configregs;
-typedef union np_dcb DCB_reg;
-
-
-/* It looks like I can't do a simple tweak with this structure because the IRIX
- * version is just *too* stupid.  Ok, here's a new version of it..
- */
-
-struct rex3chip {
-	struct newport_rexregs set;
-	unsigned long _unused0[0x16e];
-	struct newport_rexregs go;
-	unsigned long _unused1[0x22e];
-	struct {
-		struct newport_cregs set;
-		unsigned long _unused2[0x1ef];
-		struct newport_cregs go;
-	} p1;
-};
-
-typedef struct rex3chip rex3Chip;
-typedef struct rex3chip Rex3chip;
-
-/* Tweak the defines .. */
-
-#define DM0_OPCODE		NPORT_DMODE0_OPMASK
-#define DM0_NOP			NPORT_DMODE0_NOP
-#define DM0_READ		NPORT_DMODE0_RD
-#define DM0_DRAW		NPORT_DMODE0_DRAW
-#define DM0_SCR2SCR		NPORT_DMODE0_S2S
-
-#define DM0_ADRMODE_SHIFT	2
-#define DM0_ADRMODE		NPORT_DMODE0_AMMASK
-#define DM0_SPAN		NPORT_DMODE0_SPAN
-#define DM0_BLOCK		NPORT_DMODE0_BLOCK
-#define DM0_ILINE		NPORT_DMODE0_ILINE
-#define DM0_FLINE		NPORT_DMODE0_FLINE
-#define DM0_ALINE		NPORT_DMODE0_ALINE
-#define DM0_TLINE		NPORT_DMODE0_TLINE
-#define DM0_BLINE               NPORT_DMODE0_BLINE
-
-#define DM0_DOSETUP		NPORT_DMODE0_DOSETUP
-#define DM0_COLORHOST		NPORT_DMODE0_CHOST
-#define DM0_ALPHAHOST		NPORT_DMODE0_AHOST
-#define DM0_STOPONX		NPORT_DMODE0_STOPX
-#define DM0_STOPONY		NPORT_DMODE0_STOPY
-#define DM0_STOPONXY		(NPORT_DMODE0_STOPX | NPORT_DMODE0_STOPY)
-#define DM0_SKIPFIRST		NPORT_DMODE0_SK1ST
-#define DM0_SKIPLAST		NPORT_DMODE0_SKLST
-#define DM0_ENZPATTERN		NPORT_DMODE0_ZPENAB
-#define DM0_ENLSPATTERN		NPORT_DMODE0_LISPENAB
-#define DM0_LSADVLAST		NPORT_DMODE0_LISLST
-#define DM0_LENGTH32		NPORT_DMODE0_L32
-#define DM0_ZOPAQUE		NPORT_DMODE0_ZOPQ
-#define DM0_LSOPAQUE		NPORT_DMODE0_LISOPQ
-#define DM0_SHADE		NPORT_DMODE0_SHADE
-#define DM0_LRONLY		NPORT_DMODE0_LRONLY
-#define DM0_XYOFFSET		NPORT_DMODE0_XYOFF
-#define DM0_CICLAMP		NPORT_DMODE0_CLAMP
-#define DM0_ENDPTFILTER		NPORT_DMODE0_ENDPF
-#define	DM0_YSTRIDE		NPORT_DMODE0_YSTR
-
-#define DM1_PLANES_SHIFT	0
-/* The rest of the DM1 planes defines are in newport.h */
-
-#define DM1_DRAWDEPTH_SHIFT	3
-#define DM1_DRAWDEPTH_MASK	NPORT_DMODE1_DDMASK
-#define DM1_DRAWDEPTH		NPORT_DMODE1_DD24 /* An alias? */
-#define DM1_DRAWDEPTH4		NPORT_DMODE1_DD4
-#define DM1_DRAWDEPTH8		NPORT_DMODE1_DD8
-#define DM1_DRAWDEPTH12		NPORT_DMODE1_DD12
-#define DM1_DRAWDEPTH24		NPORT_DMODE1_DD24
-
-#define DM1_DBLSRC		NPORT_DMODE1_DSRC
-#define DM1_YFLIP		NPORT_DMODE1_YFLIP
-#define DM1_RWPACKED		NPORT_DMODE1_RWPCKD
-
-#define DM1_HOSTDEPTH_SHIFT 	8
-#define DM1_HOSTDEPTH_MASK	NPORT_DMODE1_HDMASK
-#define DM1_HOSTDEPTH		NPORT_DMODE1_HD32 /* An alias? */
-#define DM1_HOSTDEPTH4		NPORT_DMODE1_HD4
-#define DM1_HOSTDEPTH8		NPORT_DMODE1_HD8
-#define DM1_HOSTDEPTH12		NPORT_DMODE1_HD12
-#define DM1_HOSTDEPTH32		NPORT_DMODE1_HD32
-
-#define DM1_RWDOUBLE		NPORT_DMODE1_RWDBL
-#define DM1_SWAPENDIAN		NPORT_DMODE1_ESWAP
-
-#define DM1_COLORCOMPARE_SHIFT	12
-#define DM1_COLORCOMPARE_MASK	NPORT_DMODE1_CCMASK
-#define DM1_COLORCOMPARE	NPORT_DMODE1_CCMASK
-#define DM1_COLORCOMPLT		NPORT_DMODE1_CCLT
-#define DM1_COLORCOMPEQ		NPORT_DMODE1_CCEQ
-#define DM1_COLORCOMPGT		NPORT_DMODE1_CCGT
-
-#define DM1_RGBMODE		NPORT_DMODE1_RGBMD
-#define DM1_ENDITHER		NPORT_DMODE1_DENAB
-#define DM1_FASTCLEAR		NPORT_DMODE1_FCLR
-#define DM1_ENBLEND		NPORT_DMODE1_BENAB
-
-#define DM1_SF_SHIFT		19
-#define DM1_SF_MASK   		NPORT_DMODE1_SFMASK
-#define DM1_SF			NPORT_DMODE1_SFMASK
-#define DM1_SF_ZERO		NPORT_DMODE1_SF0
-#define DM1_SF_ONE		NPORT_DMODE1_SF1
-#define DM1_SF_DC		NPORT_DMODE1_SFDC
-#define DM1_SF_MDC		NPORT_DMODE1_SFMDC
-#define DM1_SF_SA		NPORT_DMODE1_SFSA
-#define DM1_SF_MSA		NPORT_DMODE1_SFMSA
-
-#define DM1_DF_SHIFT		22	/* dfactor(2:0)	*/
-#define DM1_DF_MASK		NPORT_DMODE1_DFMASK
-#define DM1_DF			NPORT_DMODE1_DFMASK
-#define DM1_DF_ZERO		NPORT_DMODE1_DF0
-#define DM1_DF_ONE		NPORT_DMODE1_DF1
-#define DM1_DF_SC		NPORT_DMODE1_DFSC
-#define DM1_DF_MSC		NPORT_DMODE1_DFMSC
-#define DM1_DF_SA		NPORT_DMODE1_DFSA
-#define DM1_DF_MSA		NPORT_DMODE1_DFMSA
-
-#define DM1_ENBACKBLEND		NPORT_DMODE1_BBENAB
-#define DM1_ENPREFETCH		NPORT_DMODE1_PFENAB
-#define DM1_BLENDALPHA		NPORT_DMODE1_ABLEND
-
-#define DM1_LO_SHIFT		28
-#define DM1_LO			NPORT_DMODE1_LOMASK
-#define DM1_LO_MASK      	NPORT_DMODE1_LOMASK
-#define DM1_LO_ZERO		NPORT_DMODE1_LOZERO
-#define DM1_LO_AND		NPORT_DMODE1_LOAND
-#define DM1_LO_ANDR		NPORT_DMODE1_LOANDR
-#define DM1_LO_SRC		NPORT_DMODE1_LOSRC
-#define DM1_LO_ANDI		NPORT_DMODE1_LOANDI
-#define DM1_LO_DST		NPORT_DMODE1_LODST
-#define DM1_LO_XOR		NPORT_DMODE1_LOXOR
-#define DM1_LO_OR		NPORT_DMODE1_LOOR
-#define DM1_LO_NOR		NPORT_DMODE1_LONOR
-#define DM1_LO_XNOR		NPORT_DMODE1_LOXNOR
-#define DM1_LO_NDST		NPORT_DMODE1_LONDST
-#define DM1_LO_ORR		NPORT_DMODE1_LOORR
-#define DM1_LO_NSRC		NPORT_DMODE1_LONSRC
-#define DM1_LO_ORI		NPORT_DMODE1_LOORI
-#define DM1_LO_NAND		NPORT_DMODE1_LONAND
-#define DM1_LO_ONE		NPORT_DMODE1_LOONE
-
-#define SMASK0			NPORT_CMODE_SM0
-#define SMASK1			NPORT_CMODE_SM1
-#define SMASK2			NPORT_CMODE_SM2
-#define SMASK3			NPORT_CMODE_SM3
-#define SMASK4			NPORT_CMODE_SM4
-#define ALL_SMASKS		0x1f
-
-#define CM_CIDMATCH_SHIFT       9
-#define CM_CIDMATCH_MASK        NPORT_CMODE_CMSK
-
-#define REX3VERSION_MASK	NPORT_STAT_VERS
-#define GFXBUSY        		NPORT_STAT_GBUSY
-#define BACKBUSY        	NPORT_STAT_BBUSY
-#define VRINT           	NPORT_STAT_VRINT
-#define VIDEOINT        	NPORT_STAT_VIDINT
-#define GFIFO_LEVEL_SHIFT       7
-#define GFIFO_LEVEL_MASK        NPORT_STAT_GLMSK
-#define BFIFO_LEVEL_SHIFT       13
-#define BFIFO_LEVEL_MASK        NPORT_STAT_BLMSK
-#define BFIFO_INT        	NPORT_STAT_BFIRQ
-#define GFIFO_INT        	NPORT_STAT_GFIRQ
-
-#define GIO32MODE		NPORT_CFG_G32MD
-#define BUSWIDTH		NPORT_CFG_BWIDTH
-#define EXTREGXCVR		NPORT_CFG_ERCVR
-#define BFIFODEPTH_SHIFT	3
-#define BFIFODEPTH_MASK		NPORT_CFG_BDMSK
-#define BFIFOABOVEINT		NPORT_CFG_BFAINT
-#define GFIFODEPTH_SHIFT        8
-#define GFIFODEPTH_MASK		NPORT_CFG_GDMSK
-#define GFIFOABOVEINT		NPORT_CFG_GFAINT
-#define TIMEOUT_SHIFT		14
-#define TIMEOUT_MASK		NPORT_CFG_TOMSK
-#define VREFRESH_SHIFT		17
-#define VREFRESH_MASK		NPORT_CFG_VRMSK
-#define FB_TYPE			NPORT_CFG_FBTYP
-
-#define DCB_DATAWIDTH_MASK	(0x3)
-
-#define DCB_CRS_MASK		(0x7 << DCB_CRS_SHIFT)
-#define DCB_ADDR_MASK		(0xf << DCB_ADDR_SHIFT)
-#define DCB_CSWIDTH_MASK	(0x1f << DCB_CSWIDTH_SHIFT)
-#define DCB_CSHOLD_MASK		(0x1f << DCB_CSHOLD_SHIFT)
-#define DCB_CSSETUP_MASK	(0x1f << DCB_CSSETUP_SHIFT)
-
-#define DCB_SWAPENDIAN		(1 << 28)
-
-#define REX3WAIT(rex3)  while ((rex3)->p1.set.status & GFXBUSY)
-#define BFIFOWAIT(rex3)  while ((rex3)->p1.set.status & BACKBUSY)
-
-#define REX3_GIO_ADDR_0         0x1f0f0000
-#define REX3_GIO_ADDR_1         0x1f4f0000
-#define REX3_GIO_ADDR_2         0x1f8f0000
-#define REX3_GIO_ADDR_3         0x1fcf0000
-
-#define NG1_XSIZE		1280
-#define NG1_YSIZE		1024
-
-#endif
diff -Nru a/include/asm-mips/pgalloc.h b/include/asm-mips/pgalloc.h
--- a/include/asm-mips/pgalloc.h	2005-03-01 23:38:57 -08:00
+++ b/include/asm-mips/pgalloc.h	2005-03-01 23:38:57 -08:00
@@ -56,9 +56,7 @@
 {
 	pte_t *pte;
 
-	pte = (pte_t *) __get_free_pages(GFP_KERNEL|__GFP_REPEAT, PTE_ORDER);
-	if (pte)
-		clear_page(pte);
+	pte = (pte_t *) __get_free_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, PTE_ORDER);
 
 	return pte;
 }
diff -Nru a/include/asm-mips/pgtable-32.h b/include/asm-mips/pgtable-32.h
--- a/include/asm-mips/pgtable-32.h	2005-03-01 23:38:57 -08:00
+++ b/include/asm-mips/pgtable-32.h	2005-03-01 23:38:57 -08:00
@@ -98,7 +98,7 @@
 
 extern void load_pgd(unsigned long pg_dir);
 
-extern pmd_t invalid_pte_table[PAGE_SIZE/sizeof(pmd_t)];
+extern pte_t invalid_pte_table[PAGE_SIZE/sizeof(pte_t)];
 
 /*
  * Empty pgd/pmd entries point to the invalid_pte_table.
diff -Nru a/include/asm-mips/pgtable.h b/include/asm-mips/pgtable.h
--- a/include/asm-mips/pgtable.h	2005-03-01 23:38:54 -08:00
+++ b/include/asm-mips/pgtable.h	2005-03-01 23:38:54 -08:00
@@ -8,6 +8,8 @@
 #ifndef _ASM_PGTABLE_H
 #define _ASM_PGTABLE_H
 
+#include <asm-generic/4level-fixup.h>
+
 #include <linux/config.h>
 #ifdef CONFIG_MIPS32
 #include <asm/pgtable-32.h>
diff -Nru a/include/asm-mips/pmon.h b/include/asm-mips/pmon.h
--- a/include/asm-mips/pmon.h	2005-03-01 23:38:53 -08:00
+++ b/include/asm-mips/pmon.h	2005-03-01 23:38:53 -08:00
@@ -4,22 +4,43 @@
  * for more details.
  *
  * Copyright (C) 2004 by Ralf Baechle
+ *
+ * The cpustart method is a PMC-Sierra's function to start the secondary CPU.
+ * Stock PMON 2000 has the smpfork, semlock and semunlock methods instead.
  */
 #ifndef _ASM_PMON_H
 #define _ASM_PMON_H
 
 struct callvectors {
-	int	(*open) (char*, int, int);		/*	 0 */
-	int	(*close) (int);				/*	 4 */
-	int	(*read) (int, void*, int);		/*	 8 */
-	int	(*write) (int, void*, int);		/*	12 */
-	off_t	(*lseek) (int, off_t, int);		/*	16 */
-	int	(*printf) (const char*, ...);		/*	20 */
-	void	(*cacheflush) (void);			/*	24 */
-	char*	(*gets) (char*);			/*	28 */
-	int	(*cpustart) (int, void *, int, int);	/*	32 */
+	int	(*open) (char*, int, int);
+	int	(*close) (int);
+	int	(*read) (int, void*, int);
+	int	(*write) (int, void*, int);
+	off_t	(*lseek) (int, off_t, int);
+	int	(*printf) (const char*, ...);
+	void	(*cacheflush) (void);
+	char*	(*gets) (char*);
+	union {
+		int	(*smpfork) (unsigned long cp, char *sp);
+		int	(*cpustart) (long, long, long, long);
+	} _s;
+	int	(*semlock) (int sem);
+	void	(*semunlock) (int sem);
 };
 
 extern struct callvectors *debug_vectors;
+
+#define pmon_open(name, flags, mode)	debug_vectors->open(name, flage, mode)
+#define pmon_close(fd)			debug_vectors->close(fd)
+#define pmon_read(fd, buf, count)	debug_vectors->read(fd, buf, count)
+#define pmon_write(fd, buf, count)	debug_vectors->write(fd, buf, count)
+#define pmon_lseek(fd, off, whence)	debug_vectors->lseek(fd, off, whence)
+#define pmon_printf(fmt...)		debug_vectors->printf(fmt)
+#define pmon_cacheflush()		debug_vectors->cacheflush()
+#define pmon_gets(s)			debug_vectors->gets(s)
+#define pmon_cpustart(n, f, sp, gp)	debug_vectors->_s.cpustart(n, f, sp, gp)
+#define pmon_smpfork(cp, sp)		debug_vectors->_s.smpfork(cp, sp)
+#define pmon_semlock(sem)		debug_vectors->semlock(sem)
+#define pmon_semunlock(sem)		debug_vectors->semunlock(sem)
 
 #endif /* _ASM_PMON_H */
diff -Nru a/include/asm-mips/prefetch.h b/include/asm-mips/prefetch.h
--- a/include/asm-mips/prefetch.h	2005-03-01 23:39:18 -08:00
+++ b/include/asm-mips/prefetch.h	2005-03-01 23:39:18 -08:00
@@ -8,6 +8,8 @@
 #ifndef __ASM_PREFETCH_H
 #define __ASM_PREFETCH_H
 
+#include <linux/config.h>
+
 /*
  * R5000 and RM5200 implements pref and prefx instructions but they're nops, so
  * rather than wasting time we pretend these processors don't support
@@ -40,5 +42,47 @@
 						/* 8 ... 24 are reserved */
 #define Pref_WriteBackInvalidate	25
 #define Pref_PrepareForStore		30
+
+#ifdef __ASSEMBLY__
+
+	.macro	__pref hint addr
+#ifdef CONFIG_CPU_HAS_PREFETCH
+	pref	\hint, \addr
+#endif
+	.endm
+
+	.macro	pref_load addr
+	__pref	Pref_Load, \addr
+	.endm
+
+	.macro	pref_store addr
+	__pref	Pref_Store, \addr
+	.endm
+
+	.macro	pref_load_streamed addr
+	__pref	Pref_LoadStreamed, \addr
+	.endm
+
+	.macro	pref_store_streamed addr
+	__pref	Pref_StoreStreamed, \addr
+	.endm
+
+	.macro	pref_load_retained addr
+	__pref	Pref_LoadRetained, \addr
+	.endm
+
+	.macro	pref_store_retained addr
+	__pref	Pref_StoreRetained, \addr
+	.endm
+
+	.macro	pref_wback_inv addr
+	__pref	Pref_WriteBackInvalidate, \addr
+	.endm
+
+	.macro	pref_prepare_for_store addr
+	__pref	Pref_PrepareForStore, \addr
+	.endm
+
+#endif
 
 #endif /* __ASM_PREFETCH_H */
diff -Nru a/include/asm-mips/processor.h b/include/asm-mips/processor.h
--- a/include/asm-mips/processor.h	2005-03-01 23:38:51 -08:00
+++ b/include/asm-mips/processor.h	2005-03-01 23:38:51 -08:00
@@ -33,12 +33,6 @@
 
 extern unsigned int vced_count, vcei_count;
 
-/*
- * Bus types (default is ISA, but people can check others with these..)
- */
-#define MCA_bus 0
-#define MCA_bus__is_a_macro /* for versions in ksyms.c */
-
 #ifdef CONFIG_MIPS32
 /*
  * User space process size: 2GB. This is hardcoded into a few places,
@@ -71,11 +65,6 @@
 #define TASK_UNMAPPED_BASE	((current->thread.mflags & MF_32BIT_ADDR) ? \
 	PAGE_ALIGN(TASK_SIZE32 / 3) : PAGE_ALIGN(TASK_SIZE / 3))
 #endif
-
-/*
- * Size of io_bitmap in longwords.
- */
-#define IO_BITMAP_SIZE	2048
 
 #define NUM_FPU_REGS	32
 
diff -Nru a/include/asm-mips/r4kcache.h b/include/asm-mips/r4kcache.h
--- a/include/asm-mips/r4kcache.h	2005-03-01 23:38:52 -08:00
+++ b/include/asm-mips/r4kcache.h	2005-03-01 23:38:52 -08:00
@@ -117,6 +117,21 @@
 		: "i" (Hit_Writeback_Inv_D), "r" (addr));
 }
 
+static inline void protected_writeback_scache_line(unsigned long addr)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		".set mips3\n"
+		"1:\tcache %0,(%1)\n"
+		"2:\t.set mips0\n\t"
+		".set reorder\n\t"
+		".section\t__ex_table,\"a\"\n\t"
+		STR(PTR)"\t1b,2b\n\t"
+		".previous"
+		:
+		: "i" (Hit_Writeback_Inv_SD), "r" (addr));
+}
+
 /*
  * This one is RM7000-specific
  */
diff -Nru a/include/asm-mips/reg.h b/include/asm-mips/reg.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-mips/reg.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,129 @@
+/*
+ * Various register offset definitions for debuggers, core file
+ * examiners and whatnot.
+ *
+ * This file 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, 1999 Ralf Baechle
+ * Copyright (C) 1995, 1999 Silicon Graphics
+ */
+#ifndef __ASM_MIPS_REG_H
+#define __ASM_MIPS_REG_H
+
+#include <linux/config.h>
+
+#if defined(CONFIG_MIPS32) || defined(WANT_COMPAT_REG_H)
+
+#define EF_R0			6
+#define EF_R1			7
+#define EF_R2			8
+#define EF_R3			9
+#define EF_R4			10
+#define EF_R5			11
+#define EF_R6			12
+#define EF_R7			13
+#define EF_R8			14
+#define EF_R9			15
+#define EF_R10			16
+#define EF_R11			17
+#define EF_R12			18
+#define EF_R13			19
+#define EF_R14			20
+#define EF_R15			21
+#define EF_R16			22
+#define EF_R17			23
+#define EF_R18			24
+#define EF_R19			25
+#define EF_R20			26
+#define EF_R21			27
+#define EF_R22			28
+#define EF_R23			29
+#define EF_R24			30
+#define EF_R25			31
+
+/*
+ * k0/k1 unsaved
+ */
+#define EF_R26			32
+#define EF_R27			33
+
+#define EF_R28			34
+#define EF_R29			35
+#define EF_R30			36
+#define EF_R31			37
+
+/*
+ * Saved special registers
+ */
+#define EF_LO			38
+#define EF_HI			39
+
+#define EF_CP0_EPC		40
+#define EF_CP0_BADVADDR		41
+#define EF_CP0_STATUS		42
+#define EF_CP0_CAUSE		43
+#define EF_UNUSED0		44
+
+#define EF_SIZE			180
+
+#endif
+
+#if CONFIG_MIPS64
+
+#define EF_R0			 0
+#define EF_R1			 1
+#define EF_R2			 2
+#define EF_R3			 3
+#define EF_R4			 4
+#define EF_R5			 5
+#define EF_R6			 6
+#define EF_R7			 7
+#define EF_R8			 8
+#define EF_R9			 9
+#define EF_R10			10
+#define EF_R11			11
+#define EF_R12			12
+#define EF_R13			13
+#define EF_R14			14
+#define EF_R15			15
+#define EF_R16			16
+#define EF_R17			17
+#define EF_R18			18
+#define EF_R19			19
+#define EF_R20			20
+#define EF_R21			21
+#define EF_R22			22
+#define EF_R23			23
+#define EF_R24			24
+#define EF_R25			25
+
+/*
+ * k0/k1 unsaved
+ */
+#define EF_R26			26
+#define EF_R27			27
+
+
+#define EF_R28			28
+#define EF_R29			29
+#define EF_R30			30
+#define EF_R31			31
+
+/*
+ * Saved special registers
+ */
+#define EF_LO			32
+#define EF_HI			33
+
+#define EF_CP0_EPC		34
+#define EF_CP0_BADVADDR		35
+#define EF_CP0_STATUS		36
+#define EF_CP0_CAUSE		37
+
+#define EF_SIZE			304	/* size in bytes */
+
+#endif /* CONFIG_MIPS64 */
+
+#endif /* __ASM_MIPS_REG_H */
diff -Nru a/include/asm-mips/resource.h b/include/asm-mips/resource.h
--- a/include/asm-mips/resource.h	2005-03-01 23:39:09 -08:00
+++ b/include/asm-mips/resource.h	2005-03-01 23:39:09 -08:00
@@ -27,15 +27,13 @@
 #define RLIMIT_MSGQUEUE 12		/* maximum bytes in POSIX mqueues */
 
 #define RLIM_NLIMITS 13			/* Number of limit flavors.  */
-
-#ifdef __KERNEL__
-
-#include <linux/config.h>
+#define __ARCH_RLIMIT_ORDER
 
 /*
  * SuS says limits have to be unsigned.
  * Which makes a ton more sense anyway.
  */
+#include <linux/config.h>
 #ifdef CONFIG_MIPS32
 #define RLIM_INFINITY	0x7fffffffUL
 #endif
@@ -43,23 +41,6 @@
 #define RLIM_INFINITY	(~0UL)
 #endif
 
-#define INIT_RLIMITS					\
-{							\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{ _STK_LIM,      RLIM_INFINITY },		\
-	{        0,      RLIM_INFINITY },		\
-	{ INR_OPEN,      INR_OPEN      },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{ MLOCK_LIMIT,     MLOCK_LIMIT },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{ MAX_SIGPENDING, MAX_SIGPENDING },		\
-	{ MQ_BYTES_MAX, MQ_BYTES_MAX },			\
-}
-
-#endif /* __KERNEL__ */
+#include <asm-generic/resource.h>
 
 #endif /* _ASM_RESOURCE_H */
diff -Nru a/include/asm-mips/sections.h b/include/asm-mips/sections.h
--- a/include/asm-mips/sections.h	2005-03-01 23:39:18 -08:00
+++ b/include/asm-mips/sections.h	2005-03-01 23:39:18 -08:00
@@ -4,6 +4,5 @@
 #include <asm-generic/sections.h>
 
 extern char _fdata;
-extern char _end;
 
 #endif /* _ASM_SECTIONS_H */
diff -Nru a/include/asm-mips/sgi/sgi.h b/include/asm-mips/sgi/sgi.h
--- a/include/asm-mips/sgi/sgi.h	2005-03-01 23:39:07 -08:00
+++ b/include/asm-mips/sgi/sgi.h	2005-03-01 23:39:07 -08:00
@@ -28,8 +28,8 @@
 	ip26,	/* TFP UP, Indigo2 */
 	ip27,	/* R10k MP, R12k MP, Origin */
 	ip28,	/* R10k UP, Indigo2 */
-	ip30,
-	ip32,
+	ip30,	/* Octane */
+	ip32,	/* O2 */
 };
 
 extern enum sgi_mach sgimach;
diff -Nru a/include/asm-mips/sibyte/sb1250.h b/include/asm-mips/sibyte/sb1250.h
--- a/include/asm-mips/sibyte/sb1250.h	2005-03-01 23:39:09 -08:00
+++ b/include/asm-mips/sibyte/sb1250.h	2005-03-01 23:39:09 -08:00
@@ -58,6 +58,6 @@
 
 #endif
 
-#define IOADDR(a) (UNCAC_BASE + (a))
+#define IOADDR(a) (IO_BASE + (a))
 
 #endif
diff -Nru a/include/asm-mips/sigcontext.h b/include/asm-mips/sigcontext.h
--- a/include/asm-mips/sigcontext.h	2005-03-01 23:39:18 -08:00
+++ b/include/asm-mips/sigcontext.h	2005-03-01 23:39:18 -08:00
@@ -41,8 +41,6 @@
                                                                                 
 #if _MIPS_SIM == _MIPS_SIM_ABI64 || _MIPS_SIM == _MIPS_SIM_NABI32
 
-#include <linux/types.h>
-
 /*
  * Keep this struct definition in sync with the sigcontext fragment
  * in arch/mips/tools/offset.c
@@ -66,6 +64,9 @@
 };
 
 #ifdef __KERNEL__
+
+#include <linux/posix_types.h>
+
 struct sigcontext32 {
 	__u32	sc_regmask;		/* Unused */
 	__u32	sc_status;
diff -Nru a/include/asm-mips/sn/mapped_kernel.h b/include/asm-mips/sn/mapped_kernel.h
--- a/include/asm-mips/sn/mapped_kernel.h	2005-03-01 23:38:56 -08:00
+++ b/include/asm-mips/sn/mapped_kernel.h	2005-03-01 23:38:56 -08:00
@@ -23,10 +23,16 @@
 #include <linux/config.h>
 #include <asm/addrspace.h>
 
+#ifdef CONFIG_BUILD_ELF64
+#define REP_BASE	CAC_BASE
+#else
+#define REP_BASE	CKSEG0
+#endif
+
 #ifdef CONFIG_MAPPED_KERNEL
 
-#define MAPPED_ADDR_RO_TO_PHYS(x)	(x - CKSSEG)
-#define MAPPED_ADDR_RW_TO_PHYS(x)	(x - CKSSEG - 16777216)
+#define MAPPED_ADDR_RO_TO_PHYS(x)	(x - REP_BASE)
+#define MAPPED_ADDR_RW_TO_PHYS(x)	(x - REP_BASE - 16777216)
 
 #define MAPPED_KERN_RO_PHYSBASE(n) \
 			(PLAT_NODE_DATA(n)->kern_vars.kv_ro_baseaddr)
@@ -42,8 +48,8 @@
 
 #else /* CONFIG_MAPPED_KERNEL */
 
-#define MAPPED_KERN_RO_TO_PHYS(x)	(x - CKSEG0)
-#define MAPPED_KERN_RW_TO_PHYS(x)	(x - CKSEG0)
+#define MAPPED_KERN_RO_TO_PHYS(x)	(x - REP_BASE)
+#define MAPPED_KERN_RW_TO_PHYS(x)	(x - REP_BASE)
 
 #endif /* CONFIG_MAPPED_KERNEL */
 
diff -Nru a/include/asm-mips/sn/sn0/hubio.h b/include/asm-mips/sn/sn0/hubio.h
--- a/include/asm-mips/sn/sn0/hubio.h	2005-03-01 23:38:52 -08:00
+++ b/include/asm-mips/sn/sn0/hubio.h	2005-03-01 23:38:52 -08:00
@@ -486,6 +486,7 @@
 #define ICRBN_A_CERR_SHFT	54
 #define ICRBN_A_ERR_MASK	0x3ff
 
+#if 0	/* Disabled, this causes namespace polution and break allmodconfig */
 /*
  * Easy access macros.
  */
@@ -499,6 +500,7 @@
 #define	a_addr		icrba_fields_s.addr
 #define	a_valid		icrba_fields_s.valid
 #define	a_iow		icrba_fields_s.iow
+#endif
 
 #endif /* !__ASSEMBLY__ */
 
diff -Nru a/include/asm-mips/sn/sn_private.h b/include/asm-mips/sn/sn_private.h
--- a/include/asm-mips/sn/sn_private.h	2005-03-01 23:39:08 -08:00
+++ b/include/asm-mips/sn/sn_private.h	2005-03-01 23:39:08 -08:00
@@ -12,8 +12,8 @@
 extern void per_cpu_init(void);
 extern void install_cpu_nmi_handler(int slice);
 extern void install_ipi(void);
-extern void setup_replication_mask(int);
-extern void replicate_kernel_text(int);
+extern void setup_replication_mask(void);
+extern void replicate_kernel_text(void);
 extern pfn_t node_getfirstfree(cnodeid_t);
 
 #endif /* __ASM_SN_SN_PRIVATE_H */
diff -Nru a/include/asm-mips/spinlock.h b/include/asm-mips/spinlock.h
--- a/include/asm-mips/spinlock.h	2005-03-01 23:39:17 -08:00
+++ b/include/asm-mips/spinlock.h	2005-03-01 23:39:17 -08:00
@@ -9,6 +9,7 @@
 #ifndef _ASM_SPINLOCK_H
 #define _ASM_SPINLOCK_H
 
+#include <linux/config.h>
 #include <asm/war.h>
 
 /*
@@ -17,6 +18,9 @@
 
 typedef struct {
 	volatile unsigned int lock;
+#ifdef CONFIG_PREEMPT
+	unsigned int break_lock;
+#endif
 } spinlock_t;
 
 #define SPIN_LOCK_UNLOCKED (spinlock_t) { 0 }
@@ -127,14 +131,15 @@
 
 typedef struct {
 	volatile unsigned int lock;
+#ifdef CONFIG_PREEMPT
+	unsigned int break_lock;
+#endif
 } rwlock_t;
 
 #define RW_LOCK_UNLOCKED (rwlock_t) { 0 }
 
 #define rwlock_init(x)  do { *(x) = RW_LOCK_UNLOCKED; } while(0)
 
-#define rwlock_is_locked(x) ((x)->lock)
-
 static inline void _raw_read_lock(rwlock_t *rw)
 {
 	unsigned int tmp;
@@ -245,6 +250,8 @@
 	: "m" (rw->lock)
 	: "memory");
 }
+
+#define _raw_read_trylock(lock) generic_raw_read_trylock(lock)
 
 static inline int _raw_write_trylock(rwlock_t *rw)
 {
diff -Nru a/include/asm-mips/stackframe.h b/include/asm-mips/stackframe.h
--- a/include/asm-mips/stackframe.h	2005-03-01 23:38:44 -08:00
+++ b/include/asm-mips/stackframe.h	2005-03-01 23:38:44 -08:00
@@ -64,7 +64,7 @@
 		addu	k1, k0
 		LONG_L	k1, %lo(kernelsp)(k1)
 #endif
-#ifdef CONFIG_MIPS64
+#if defined(CONFIG_MIPS64) && !defined(CONFIG_BUILD_ELF64)
 		MFC0	k1, CP0_CONTEXT
 		dsra	k1, 23
 		lui	k0, %hi(pgd_current)
@@ -74,6 +74,12 @@
 		daddu	k1, k0
 		LONG_L	k1, %lo(kernelsp)(k1)
 #endif
+#if defined(CONFIG_MIPS64) && defined(CONFIG_BUILD_ELF64)
+		MFC0	k1, CP0_CONTEXT
+		dsrl	k1, 23
+		dsll	k1, k1, 3
+		LONG_L	k1, kernelsp(k1)
+#endif
 		.endm
 
 		.macro	set_saved_sp stackp temp temp2
@@ -83,13 +89,18 @@
 		sll	\temp, 2
 		LONG_S	\stackp, kernelsp(\temp)
 #endif
-#ifdef CONFIG_MIPS64
+#if defined(CONFIG_MIPS64) && !defined(CONFIG_BUILD_ELF64)
 		lw	\temp, TI_CPU(gp)
 		dsll	\temp, 3
 		lui	\temp2, %hi(kernelsp)
 		daddu	\temp, \temp2
 		LONG_S	\stackp, %lo(kernelsp)(\temp)
 #endif
+#if defined(CONFIG_MIPS64) && defined(CONFIG_BUILD_ELF64)
+		lw	\temp, TI_CPU(gp)
+		dsll	\temp, 3
+		LONG_S	\stackp, kernelsp(\temp)
+#endif
 		.endm
 #else
 		.macro	get_saved_sp	/* Uniprocessor variation */
@@ -104,6 +115,7 @@
 
 		.macro	SAVE_SOME
 		.set	push
+		.set	noat
 		.set	reorder
 		mfc0	k0, CP0_STATUS
 		sll	k0, 3		/* extract cu0 bit */
@@ -278,16 +290,16 @@
 
 		.macro	RESTORE_ALL
 		RESTORE_TEMP
-		RESTORE_AT
 		RESTORE_STATIC
+		RESTORE_AT
 		RESTORE_SOME
 		RESTORE_SP
 		.endm
 
 		.macro	RESTORE_ALL_AND_RET
 		RESTORE_TEMP
-		RESTORE_AT
 		RESTORE_STATIC
+		RESTORE_AT
 		RESTORE_SOME
 		RESTORE_SP_AND_RET
 		.endm
diff -Nru a/include/asm-mips/string.h b/include/asm-mips/string.h
--- a/include/asm-mips/string.h	2005-03-01 23:38:44 -08:00
+++ b/include/asm-mips/string.h	2005-03-01 23:38:44 -08:00
@@ -18,6 +18,8 @@
  */
 #ifdef CONFIG_MIPS32
 
+#ifndef IN_STRING_C
+
 #define __HAVE_ARCH_STRCPY
 static __inline__ char *strcpy(char *__dest, __const__ char *__src)
 {
@@ -96,6 +98,8 @@
   return __res;
 }
 
+#endif /* !defined(IN_STRING_C) */
+
 #define __HAVE_ARCH_STRNCMP
 static __inline__ int
 strncmp(__const__ char *__cs, __const__ char *__ct, size_t __count)
@@ -136,9 +140,6 @@
 
 #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
 
 #ifdef CONFIG_MIPS32
 #define __HAVE_ARCH_MEMSCAN
diff -Nru a/include/asm-mips/thread_info.h b/include/asm-mips/thread_info.h
--- a/include/asm-mips/thread_info.h	2005-03-01 23:38:43 -08:00
+++ b/include/asm-mips/thread_info.h	2005-03-01 23:38:43 -08:00
@@ -116,6 +116,7 @@
 #define TIF_SYSCALL_AUDIT	4	/* syscall auditing active */
 #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 */
+#define TIF_MEMDIE		18
 #define TIF_SYSCALL_TRACE	31	/* syscall trace active */
 
 #define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE)
diff -Nru a/include/asm-mips/uaccess.h b/include/asm-mips/uaccess.h
--- a/include/asm-mips/uaccess.h	2005-03-01 23:38:51 -08:00
+++ b/include/asm-mips/uaccess.h	2005-03-01 23:38:51 -08:00
@@ -150,7 +150,7 @@
  * Returns zero on success, or -EFAULT on error.
  */
 #define put_user(x,ptr)	\
-	__put_user_check((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
+	__put_user_check((x),(ptr),sizeof(*(ptr)))
 
 /*
  * get_user: - Get a simple variable from user space.
@@ -170,7 +170,7 @@
  * On error, the variable @x is set to zero.
  */
 #define get_user(x,ptr) \
-	__get_user_check((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
+	__get_user_check((x),(ptr),sizeof(*(ptr)))
 
 /*
  * __put_user: - Write a simple value into user space, with less checking.
@@ -192,7 +192,7 @@
  * Returns zero on success, or -EFAULT on error.
  */
 #define __put_user(x,ptr) \
-	__put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
+	__put_user_nocheck((x),(ptr),sizeof(*(ptr)))
 
 /*
  * __get_user: - Get a simple variable from user space, with less checking.
@@ -215,7 +215,7 @@
  * On error, the variable @x is set to zero.
  */
 #define __get_user(x,ptr) \
-	__get_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
+	__get_user_nocheck((x),(ptr),sizeof(*(ptr)))
 
 struct __large_struct { unsigned long buf[100]; };
 #define __m(x) (*(struct __large_struct *)(x))
@@ -232,9 +232,10 @@
 
 #define __get_user_nocheck(x,ptr,size)					\
 ({									\
-	long __gu_err = 0;						\
 	__typeof(*(ptr)) __gu_val = 0;					\
 	long __gu_addr;							\
+	long __gu_err = 0;						\
+									\
 	might_sleep();							\
 	__gu_addr = (long) (ptr);					\
 	switch (size) {							\
@@ -244,17 +245,18 @@
 	case 8: __GET_USER_DW(__gu_err); break;				\
 	default: __get_user_unknown(); break;				\
 	}								\
-	 x = (__typeof__(*(ptr))) __gu_val;				\
+	x = (__typeof__(*(ptr))) __gu_val;				\
 	__gu_err;							\
 })
 
 #define __get_user_check(x,ptr,size)					\
 ({									\
 	__typeof__(*(ptr)) __gu_val = 0;				\
-	long __gu_addr = (long) (ptr);					\
+	long __gu_addr;							\
 	long __gu_err;							\
 									\
 	might_sleep();							\
+	__gu_addr = (long) (ptr);					\
 	__gu_err = verify_area(VERIFY_READ, (void *) __gu_addr, size);	\
 									\
 	if (likely(!__gu_err)) {					\
@@ -267,7 +269,7 @@
 		}							\
 	}								\
 	x = (__typeof__(*(ptr))) __gu_val;				\
-	 __gu_err;							\
+	__gu_err;							\
 })
 
 #define __get_user_asm(insn,__gu_err)					\
@@ -324,9 +326,10 @@
 
 #define __put_user_nocheck(x,ptr,size)					\
 ({									\
-	long __pu_err = 0;						\
 	__typeof__(*(ptr)) __pu_val;					\
 	long __pu_addr;							\
+	long __pu_err = 0;						\
+									\
 	might_sleep();							\
 	__pu_val = (x);							\
 	__pu_addr = (long) (ptr);					\
@@ -342,11 +345,13 @@
 
 #define __put_user_check(x,ptr,size)					\
 ({									\
-	__typeof__(*(ptr)) __pu_val = (x);				\
-	long __pu_addr = (long) (ptr);					\
+	__typeof__(*(ptr)) __pu_val;					\
+	long __pu_addr;							\
 	long __pu_err;							\
 									\
 	might_sleep();							\
+	__pu_val = (x);							\
+	__pu_addr = (long) (ptr);					\
 	__pu_err = verify_area(VERIFY_WRITE, (void *) __pu_addr, size);	\
 									\
 	if (likely(!__pu_err)) {					\
diff -Nru a/include/asm-mips/unistd.h b/include/asm-mips/unistd.h
--- a/include/asm-mips/unistd.h	2005-03-01 23:38:51 -08:00
+++ b/include/asm-mips/unistd.h	2005-03-01 23:38:51 -08:00
@@ -1100,13 +1100,15 @@
 #endif /* (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64) */
 
 #ifdef __KERNEL__
+
+#include <linux/config.h>
+
 #define __ARCH_WANT_IPC_PARSE_VERSION
 #define __ARCH_WANT_OLD_READDIR
 #define __ARCH_WANT_SYS_ALARM
 #define __ARCH_WANT_SYS_GETHOSTNAME
 #define __ARCH_WANT_SYS_PAUSE
 #define __ARCH_WANT_SYS_SGETMASK
-#define __ARCH_WANT_SYS_TIME
 #define __ARCH_WANT_SYS_UTIME
 #define __ARCH_WANT_SYS_WAITPID
 #define __ARCH_WANT_SYS_SOCKETCALL
@@ -1121,6 +1123,12 @@
 #define __ARCH_WANT_SYS_RT_SIGACTION
 # ifndef __mips64
 #  define __ARCH_WANT_STAT64
+# endif
+# ifdef CONFIG_MIPS32
+#  define __ARCH_WANT_SYS_TIME
+# endif
+# ifdef CONFIG_MIPS32_O32
+#  define __ARCH_WANT_COMPAT_SYS_TIME
 # endif
 #endif
 
diff -Nru a/include/asm-mips/vr41xx/cmbvr4133.h b/include/asm-mips/vr41xx/cmbvr4133.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-mips/vr41xx/cmbvr4133.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,61 @@
+/*
+ * include/asm-mips/vr41xx/cmbvr4133.h
+ *
+ * Include file for NEC CMB-VR4133.
+ *
+ * Author: Yoichi Yuasa <yyuasa@mvista.com, or source@mvista.com> and
+ *         Jun Sun <jsun@mvista.com, or source@mvista.com> and
+ *         Alex Sapkov <asapkov@ru.mvista.com>
+ *
+ * 2002-2004 (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.
+ */
+#ifndef __NEC_CMBVR4133_H
+#define __NEC_CMBVR4133_H
+
+#include <asm/addrspace.h>
+#include <asm/vr41xx/vr41xx.h>
+
+/*
+ * General-Purpose I/O Pin Number
+ */
+#define CMBVR41XX_INTA_PIN		1
+#define CMBVR41XX_INTB_PIN		1
+#define CMBVR41XX_INTC_PIN		3
+#define CMBVR41XX_INTD_PIN		1
+#define CMBVR41XX_INTE_PIN		1
+
+/*
+ * Interrupt Number
+ */
+#define CMBVR41XX_INTA_IRQ		GIU_IRQ(CMBVR41XX_INTA_PIN)
+#define CMBVR41XX_INTB_IRQ		GIU_IRQ(CMBVR41XX_INTB_PIN)
+#define CMBVR41XX_INTC_IRQ		GIU_IRQ(CMBVR41XX_INTC_PIN)
+#define CMBVR41XX_INTD_IRQ		GIU_IRQ(CMBVR41XX_INTD_PIN)
+#define CMBVR41XX_INTE_IRQ		GIU_IRQ(CMBVR41XX_INTE_PIN)
+
+#define I8259_IRQ_BASE			72
+#define I8259_IRQ(x)			(I8259_IRQ_BASE + (x))
+#define TIMER_IRQ			I8259_IRQ(0)
+#define KEYBOARD_IRQ			I8259_IRQ(1)
+#define I8259_SLAVE_IRQ			I8259_IRQ(2)
+#define UART3_IRQ			I8259_IRQ(3)
+#define UART1_IRQ			I8259_IRQ(4)
+#define UART2_IRQ			I8259_IRQ(5)
+#define FDC_IRQ				I8259_IRQ(6)
+#define PARPORT_IRQ			I8259_IRQ(7)
+#define RTC_IRQ				I8259_IRQ(8)
+#define USB_IRQ				I8259_IRQ(9)
+#define I8259_INTA_IRQ			I8259_IRQ(10)
+#define AUDIO_IRQ			I8259_IRQ(11)
+#define AUX_IRQ				I8259_IRQ(12)
+#define IDE_PRIMARY_IRQ			I8259_IRQ(14)
+#define IDE_SECONDARY_IRQ		I8259_IRQ(15)
+#define I8259_IRQ_LAST			IDE_SECONDARY_IRQ
+
+#define RTC_PORT(x)	(0xaf000100 + (x))
+#define RTC_IO_EXTENT	0x140
+
+#endif /* __NEC_CMBVR4133_H */
diff -Nru a/include/asm-mips/vr41xx/vrc4173.h b/include/asm-mips/vr41xx/vrc4173.h
--- a/include/asm-mips/vr41xx/vrc4173.h	2005-03-01 23:39:16 -08:00
+++ b/include/asm-mips/vr41xx/vrc4173.h	2005-03-01 23:39:16 -08:00
@@ -5,6 +5,7 @@
  *  Copyright (C) 2001-2003 Montavista Software Inc.
  *    Author: Yoichi Yuasa <yyuasa@mvista.com, or source@mvista.com>
  *  Copyright (C) 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
@@ -23,6 +24,7 @@
 #ifndef __NEC_VRC4173_H 
 #define __NEC_VRC4173_H 
 
+#include <linux/config.h>
 #include <asm/io.h>
 
 /*
diff -Nru a/include/asm-parisc/bootdata.h b/include/asm-parisc/bootdata.h
--- a/include/asm-parisc/bootdata.h	2005-03-01 23:39:18 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,16 +0,0 @@
-#ifndef _PARISC_BOOTDATA_H
-#define _PARISC_BOOTDATA_H
-
-/* structure given from bootloader... */
-typedef struct {
-    unsigned 	data_valid_signature,
-		initrd_start,
-		initrd_end;
-    char	commandline[1024];
-} bootdata_t;
-
-#define BOOTDATA_DATA_VALID_SIGNATURE 0xC0400000
-
-#define BOOTDATA_PTR ((bootdata_t*) 0xC0400000)
-
-#endif 
diff -Nru a/include/asm-parisc/cache.h b/include/asm-parisc/cache.h
--- a/include/asm-parisc/cache.h	2005-03-01 23:39:18 -08:00
+++ b/include/asm-parisc/cache.h	2005-03-01 23:39:18 -08:00
@@ -34,6 +34,7 @@
 extern void flush_instruction_cache_local(void); /* flushes local code-cache only */
 #ifdef CONFIG_SMP
 extern void flush_data_cache(void); /* flushes data-cache only (all processors) */
+extern void flush_instruction_cache(void); /* flushes i-cache only (all processors) */
 #else
 #define flush_data_cache flush_data_cache_local
 #define flush_instruction_cache flush_instruction_cache_local
diff -Nru a/include/asm-parisc/cacheflush.h b/include/asm-parisc/cacheflush.h
--- a/include/asm-parisc/cacheflush.h	2005-03-01 23:39:17 -08:00
+++ b/include/asm-parisc/cacheflush.h	2005-03-01 23:39:17 -08:00
@@ -33,36 +33,25 @@
 #define flush_cache_vmap(start, end)		flush_cache_all()
 #define flush_cache_vunmap(start, end)		flush_cache_all()
 
-/* The following value needs to be tuned and probably scaled with the
- * cache size.
- */
-
-#define FLUSH_THRESHOLD 0x80000
+extern int parisc_cache_flush_threshold;
+void parisc_setup_cache_timing(void);
 
 static inline void
 flush_user_dcache_range(unsigned long start, unsigned long end)
 {
-#ifdef CONFIG_SMP
-	flush_user_dcache_range_asm(start,end);
-#else
-	if ((end - start) < FLUSH_THRESHOLD)
+	if ((end - start) < parisc_cache_flush_threshold)
 		flush_user_dcache_range_asm(start,end);
 	else
 		flush_data_cache();
-#endif
 }
 
 static inline void
 flush_user_icache_range(unsigned long start, unsigned long end)
 {
-#ifdef CONFIG_SMP
-	flush_user_icache_range_asm(start,end);
-#else
-	if ((end - start) < FLUSH_THRESHOLD)
+	if ((end - start) < parisc_cache_flush_threshold)
 		flush_user_icache_range_asm(start,end);
 	else
 		flush_instruction_cache();
-#endif
 }
 
 extern void flush_dcache_page(struct page *page);
diff -Nru a/include/asm-parisc/checksum.h b/include/asm-parisc/checksum.h
--- a/include/asm-parisc/checksum.h	2005-03-01 23:38:52 -08:00
+++ b/include/asm-parisc/checksum.h	2005-03-01 23:38:52 -08:00
@@ -23,13 +23,15 @@
  * Here even more important to align src and dst on a 32-bit (or even
  * better 64-bit) boundary
  */
-extern unsigned int csum_partial_copy_nocheck(const char *, char *, int, unsigned int);
+extern unsigned int csum_partial_copy_nocheck(const unsigned char *, unsigned char *,
+					      int, unsigned int);
 
 /*
  * this is a new version of the above that records errors it finds in *errp,
  * but continues and zeros the rest of the buffer.
  */
-extern unsigned int csum_partial_copy_from_user(const char *src, char *dst, int len, unsigned int sum, int *errp);
+extern unsigned int csum_partial_copy_from_user(const unsigned char *src, unsigned char *dst,
+						int len, unsigned int sum, int *errp);
 
 /*
  *	Optimized for IP headers, which always checksum on 4 octet boundaries.
@@ -191,8 +193,8 @@
  *	Copy and checksum to user
  */
 #define HAVE_CSUM_COPY_USER
-static __inline__ unsigned int csum_and_copy_to_user (const char *src, 
-						      char __user *dst,
+static __inline__ unsigned int csum_and_copy_to_user (const unsigned char *src,
+						      unsigned char __user *dst,
 						      int len, int sum, 
 						      int *err_ptr)
 {
diff -Nru a/include/asm-parisc/cputime.h b/include/asm-parisc/cputime.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-parisc/cputime.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,6 @@
+#ifndef __PARISC_CPUTIME_H
+#define __PARISC_CPUTIME_H
+
+#include <asm-generic/cputime.h>
+
+#endif /* __PARISC_CPUTIME_H */
diff -Nru a/include/asm-parisc/hardirq.h b/include/asm-parisc/hardirq.h
--- a/include/asm-parisc/hardirq.h	2005-03-01 23:39:16 -08:00
+++ b/include/asm-parisc/hardirq.h	2005-03-01 23:39:16 -08:00
@@ -18,12 +18,10 @@
 #include <linux/config.h>
 #include <linux/threads.h>
 #include <linux/cache.h>
+#include <linux/irq.h>
 
 typedef struct {
 	unsigned long __softirq_pending; /* set_bit is used on this */
-	unsigned int __syscall_count;
-	struct task_struct * __ksoftirqd_task;
-	unsigned long idle_timestamp;
 } ____cacheline_aligned irq_cpustat_t;
 
 #include <linux/irq_cpustat.h>	/* Standard mappings for irq_cpustat_t above */
@@ -31,20 +29,13 @@
 #define HARDIRQ_BITS	16
 
 /*
- * The hardirq mask has to be large enough to have space for potentially all IRQ sources
- * in the system nesting on a single CPU:
+ * The hardirq mask has to be large enough to have space for potentially all
+ * IRQ sources in the system nesting on a single CPU:
  */
 #if (1 << HARDIRQ_BITS) < NR_IRQS
 # error HARDIRQ_BITS is too low!
 #endif
 
-#define irq_enter()		(preempt_count() += HARDIRQ_OFFSET)
-#define irq_exit()								\
-do {										\
-		preempt_count() -= IRQ_EXIT_OFFSET;				\
-		if (!in_interrupt() && softirq_pending(smp_processor_id()))	\
-			do_softirq();						\
-		preempt_enable_no_resched();					\
-} while (0)
+void ack_bad_irq(unsigned int irq);
 
 #endif /* _PARISC_HARDIRQ_H */
diff -Nru a/include/asm-parisc/hardware.h b/include/asm-parisc/hardware.h
--- a/include/asm-parisc/hardware.h	2005-03-01 23:39:08 -08:00
+++ b/include/asm-parisc/hardware.h	2005-03-01 23:39:08 -08:00
@@ -115,14 +115,13 @@
 extern int count_parisc_driver(struct parisc_driver *driver);
 extern int unregister_parisc_driver(struct parisc_driver *driver);
 extern void walk_central_bus(void);
-extern void fixup_child_irqs(struct parisc_device *parent, int irqbase,
-		int (*choose)(struct parisc_device *parent));
-extern void print_subdevices(struct parisc_device *dev);
 extern const struct parisc_device *find_pa_parent_type(const struct parisc_device *, int);
 extern void print_parisc_devices(void);
 extern char *print_pa_hwpath(struct parisc_device *dev, char *path);
 extern char *print_pci_hwpath(struct pci_dev *dev, char *path);
 extern void get_pci_node_path(struct pci_dev *dev, struct hardware_path *path);
+extern void init_parisc_bus(void);
+extern struct device *hwpath_to_device(struct hardware_path *modpath);
 
 
 /* inventory.c: */
diff -Nru a/include/asm-parisc/hw_irq.h b/include/asm-parisc/hw_irq.h
--- a/include/asm-parisc/hw_irq.h	2005-03-01 23:38:54 -08:00
+++ b/include/asm-parisc/hw_irq.h	2005-03-01 23:38:54 -08:00
@@ -12,6 +12,6 @@
  *	<tomsoft@informatik.tu-chemnitz.de>
  */
 
-#include <asm/irq.h>
+extern void hw_resend_irq(struct hw_interrupt_type *, unsigned int);
 
 #endif
diff -Nru a/include/asm-parisc/io.h b/include/asm-parisc/io.h
--- a/include/asm-parisc/io.h	2005-03-01 23:38:52 -08:00
+++ b/include/asm-parisc/io.h	2005-03-01 23:38:52 -08:00
@@ -1,14 +1,6 @@
 #ifndef _ASM_IO_H
 #define _ASM_IO_H
 
-/* USE_HPPA_IOREMAP IS THE MAGIC FLAG TO ENABLE OR DISABLE REAL IOREMAP() FUNCTIONALITY */
-/* FOR 712 or 715 MACHINES THIS SHOULD BE ENABLED, 
-   NEWER MACHINES STILL HAVE SOME ISSUES IN THE SCSI AND/OR NETWORK DRIVERS AND 
-   BECAUSE OF THAT I WILL LEAVE IT DISABLED FOR NOW <deller@gmx.de> */
-/* WHEN THOSE ISSUES ARE SOLVED, USE_HPPA_IOREMAP WILL GO AWAY */
-#define USE_HPPA_IOREMAP 0
-
-
 #include <linux/config.h>
 #include <linux/types.h>
 #include <asm/pgtable.h>
@@ -24,38 +16,44 @@
 #define virt_to_bus virt_to_phys
 #define bus_to_virt phys_to_virt
 
-/* Memory mapped IO */
-
-extern void * __ioremap(unsigned long offset, unsigned long size, unsigned long flags);
-
-extern inline void * ioremap(unsigned long offset, unsigned long size)
-{
-	return __ioremap(offset, size, 0);
-}
-
 /*
- * This one maps high address device memory and turns off caching for that area.
- * it's useful if some control registers are in such an area and write combining
- * or read caching is not desirable:
+ * Memory mapped I/O
+ *
+ * readX()/writeX() do byteswapping and take an ioremapped address
+ * __raw_readX()/__raw_writeX() don't byteswap and take an ioremapped address.
+ * gsc_*() don't byteswap and operate on physical addresses;
+ *   eg dev->hpa or 0xfee00000.
  */
-extern inline void * ioremap_nocache(unsigned long offset, unsigned long size)
-{
-        return __ioremap(offset, size, _PAGE_NO_CACHE /* _PAGE_PCD */);
-}
 
-extern void iounmap(void *addr);
+#ifdef CONFIG_DEBUG_IOREMAP
+#ifdef CONFIG_64BIT
+#define NYBBLE_SHIFT 60
+#else
+#define NYBBLE_SHIFT 28
+#endif
+extern void gsc_bad_addr(unsigned long addr);
+extern void __raw_bad_addr(const volatile void __iomem *addr);
+#define gsc_check_addr(addr)					\
+	if ((addr >> NYBBLE_SHIFT) != 0xf) {			\
+		gsc_bad_addr(addr);				\
+		addr |= 0xfUL << NYBBLE_SHIFT;			\
+	}
+#define __raw_check_addr(addr)					\
+	if (((unsigned long)addr >> NYBBLE_SHIFT) != 0xe)	\
+		__raw_bad_addr(addr);			\
+	addr = (void *)((unsigned long)addr | (0xfUL << NYBBLE_SHIFT));
+#else
+#define gsc_check_addr(addr)
+#define __raw_check_addr(addr)
+#endif
 
-/*
- * __raw_ variants have no defined meaning.  on hppa, it means `i was
- * too lazy to ioremap first'.  kind of like isa_, except that there's
- * no additional base address to add on.
- */
-#define __raw_readb(a) ___raw_readb((unsigned long)(a))
-extern __inline__ unsigned char ___raw_readb(unsigned long addr)
+static inline unsigned char gsc_readb(unsigned long addr)
 {
 	long flags;
 	unsigned char ret;
 
+	gsc_check_addr(addr);
+
 	__asm__ __volatile__(
 	"	rsm	2,%0\n"
 	"	ldbx	0(%2),%1\n"
@@ -65,12 +63,13 @@
 	return ret;
 }
 
-#define __raw_readw(a) ___raw_readw((unsigned long)(a))
-extern __inline__ unsigned short ___raw_readw(unsigned long addr)
+static inline unsigned short gsc_readw(unsigned long addr)
 {
 	long flags;
 	unsigned short ret;
 
+	gsc_check_addr(addr);
+
 	__asm__ __volatile__(
 	"	rsm	2,%0\n"
 	"	ldhx	0(%2),%1\n"
@@ -80,11 +79,12 @@
 	return ret;
 }
 
-#define __raw_readl(a) ___raw_readl((unsigned long)(a))
-extern __inline__ unsigned int ___raw_readl(unsigned long addr)
+static inline unsigned int gsc_readl(unsigned long addr)
 {
 	u32 ret;
 
+	gsc_check_addr(addr);
+
 	__asm__ __volatile__(
 	"	ldwax	0(%1),%0\n"
 	: "=r" (ret) : "r" (addr) );
@@ -92,26 +92,28 @@
 	return ret;
 }
 
-#define __raw_readq(a) ___raw_readq((unsigned long)(a))
-extern __inline__ unsigned long long ___raw_readq(unsigned long addr)
+static inline unsigned long long gsc_readq(unsigned long addr)
 {
 	unsigned long long ret;
+	gsc_check_addr(addr);
+
 #ifdef __LP64__
 	__asm__ __volatile__(
 	"	ldda	0(%1),%0\n"
 	:  "=r" (ret) : "r" (addr) );
 #else
 	/* two reads may have side effects.. */
-	ret = ((u64) __raw_readl(addr)) << 32;
-	ret |= __raw_readl(addr+4);
+	ret = ((u64) gsc_readl(addr)) << 32;
+	ret |= gsc_readl(addr+4);
 #endif
 	return ret;
 }
 
-#define __raw_writeb(a,b) ___raw_writeb(a, (unsigned long)(b))
-extern __inline__ void ___raw_writeb(unsigned char val, unsigned long addr)
+static inline void gsc_writeb(unsigned char val, unsigned long addr)
 {
 	long flags;
+	gsc_check_addr(addr);
+
 	__asm__ __volatile__(
 	"	rsm	2,%0\n"
 	"	stbs	%1,0(%2)\n"
@@ -119,10 +121,11 @@
 	: "=&r" (flags) :  "r" (val), "r" (addr) );
 }
 
-#define __raw_writew(a,b) ___raw_writew(a, (unsigned long)(b))
-extern __inline__ void ___raw_writew(unsigned short val, unsigned long addr)
+static inline void gsc_writew(unsigned short val, unsigned long addr)
 {
 	long flags;
+	gsc_check_addr(addr);
+
 	__asm__ __volatile__(
 	"	rsm	2,%0\n"
 	"	sths	%1,0(%2)\n"
@@ -130,88 +133,180 @@
 	: "=&r" (flags) :  "r" (val), "r" (addr) );
 }
 
-#define __raw_writel(a,b) ___raw_writel(a, (unsigned long)(b))
-extern __inline__ void ___raw_writel(unsigned int val, unsigned long addr)
+static inline void gsc_writel(unsigned int val, unsigned long addr)
 {
+	gsc_check_addr(addr);
+
 	__asm__ __volatile__(
 	"	stwas	%0,0(%1)\n"
 	: :  "r" (val), "r" (addr) );
 }
 
-#define __raw_writeq(a,b) ___raw_writeq(a, (unsigned long)(b))
-extern __inline__ void ___raw_writeq(unsigned long long val, unsigned long addr)
+static inline void gsc_writeq(unsigned long long val, unsigned long addr)
 {
+	gsc_check_addr(addr);
+
 #ifdef __LP64__
 	__asm__ __volatile__(
 	"	stda	%0,0(%1)\n"
 	: :  "r" (val), "r" (addr) );
 #else
 	/* two writes may have side effects.. */
-	__raw_writel(val >> 32, addr);
-	__raw_writel(val, addr+4);
+	gsc_writel(val >> 32, addr);
+	gsc_writel(val, addr+4);
 #endif
 }
 
+/*
+ * The standard PCI ioremap interfaces
+ */
+
+extern void __iomem * __ioremap(unsigned long offset, unsigned long size, unsigned long flags);
+
+extern inline void __iomem * ioremap(unsigned long offset, unsigned long size)
+{
+	return __ioremap(offset, size, 0);
+}
+
+/*
+ * This one maps high address device memory and turns off caching for that area.
+ * it's useful if some control registers are in such an area and write combining
+ * or read caching is not desirable:
+ */
+extern inline void * ioremap_nocache(unsigned long offset, unsigned long size)
+{
+        return __ioremap(offset, size, _PAGE_NO_CACHE /* _PAGE_PCD */);
+}
+
+extern void iounmap(void __iomem *addr);
+
+/*
+ * USE_HPPA_IOREMAP is the magic flag to enable or disable real ioremap()
+ * functionality.  It's currently disabled because it may not work on some
+ * machines.
+ */
+#define USE_HPPA_IOREMAP 0
+
 #if USE_HPPA_IOREMAP
-#define readb(addr) (*(volatile unsigned char *) (addr))
-#define readw(addr) (*(volatile unsigned short *) (addr))
-#define readl(addr) (*(volatile unsigned int *) (addr))
-#define readq(addr) (*(volatile u64 *) (addr))
-#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))
-#define writeq(b,addr) (*(volatile u64 *) (addr) = (b))
+static inline unsigned char __raw_readb(const volatile void __iomem *addr)
+{
+	return (*(volatile unsigned char __force *) (addr));
+}
+static inline unsigned short __raw_readw(const volatile void __iomem *addr)
+{
+	return *(volatile unsigned short __force *) addr;
+}
+static inline unsigned int __raw_readl(const volatile void __iomem *addr)
+{
+	return *(volatile unsigned int __force *) addr;
+}
+static inline unsigned long long __raw_readq(const volatile void __iomem *addr)
+{
+	return *(volatile unsigned long long __force *) addr;
+}
+
+static inline void __raw_writeb(unsigned char b, volatile void __iomem *addr)
+{
+	*(volatile unsigned char __force *) addr = b;
+}
+static inline void __raw_writew(unsigned short b, volatile void __iomem *addr)
+{
+	*(volatile unsigned short __force *) addr = b;
+}
+static inline void __raw_writel(unsigned int b, volatile void __iomem *addr)
+{
+	*(volatile unsigned int __force *) addr = b;
+}
+static inline void __raw_writeq(unsigned long long b, volatile void __iomem *addr)
+{
+	*(volatile unsigned long long __force *) addr = b;
+}
 #else /* !USE_HPPA_IOREMAP */
+static inline unsigned char __raw_readb(const volatile void __iomem *addr)
+{
+	__raw_check_addr(addr);
+
+	return gsc_readb((unsigned long) addr);
+}
+static inline unsigned short __raw_readw(const volatile void __iomem *addr)
+{
+	__raw_check_addr(addr);
+
+	return gsc_readw((unsigned long) addr);
+}
+static inline unsigned int __raw_readl(const volatile void __iomem *addr)
+{
+	__raw_check_addr(addr);
+
+	return gsc_readl((unsigned long) addr);
+}
+static inline unsigned long long __raw_readq(const volatile void __iomem *addr)
+{
+	__raw_check_addr(addr);
+
+	return gsc_readq((unsigned long) addr);
+}
+
+static inline void __raw_writeb(unsigned char b, volatile void __iomem *addr)
+{
+	__raw_check_addr(addr);
+
+	gsc_writeb(b, (unsigned long) addr);
+}
+static inline void __raw_writew(unsigned short b, volatile void __iomem *addr)
+{
+	__raw_check_addr(addr);
+
+	gsc_writew(b, (unsigned long) addr);
+}
+static inline void __raw_writel(unsigned int b, volatile void __iomem *addr)
+{
+	__raw_check_addr(addr);
+
+	gsc_writel(b, (unsigned long) addr);
+}
+static inline void __raw_writeq(unsigned long long b, volatile void __iomem *addr)
+{
+	__raw_check_addr(addr);
+
+	gsc_writeq(b, (unsigned long) addr);
+}
+#endif /* !USE_HPPA_IOREMAP */
+
 #define readb(addr) __raw_readb(addr)
 #define readw(addr) le16_to_cpu(__raw_readw(addr))
 #define readl(addr) le32_to_cpu(__raw_readl(addr))
 #define readq(addr) le64_to_cpu(__raw_readq(addr))
-#define writeb(b,addr) __raw_writeb(b,addr)
-#define writew(b,addr) __raw_writew(cpu_to_le16(b),addr)
-#define writel(b,addr) __raw_writel(cpu_to_le32(b),addr)
-#define writeq(b,addr) __raw_writeq(cpu_to_le64(b),addr)
-#endif /* !USE_HPPA_IOREMAP */
+#define writeb(b, addr) __raw_writeb(b, addr)
+#define writew(b, addr) __raw_writew(cpu_to_le16(b), addr)
+#define writel(b, addr) __raw_writel(cpu_to_le32(b), addr)
+#define writeq(b, addr) __raw_writeq(cpu_to_le64(b), addr)
 
 #define readb_relaxed(addr) readb(addr)
 #define readw_relaxed(addr) readw(addr)
 #define readl_relaxed(addr) readl(addr)
 #define readq_relaxed(addr) readq(addr)
 
-#define mmiowb()
+#define mmiowb() do { } while (0)
 
-extern void __memcpy_fromio(unsigned long dest, unsigned long src, int count);
-extern void __memcpy_toio(unsigned long dest, unsigned long src, int count);
-extern void __memset_io(unsigned long dest, char fill, int count);
-
-#define memcpy_fromio(a,b,c) __memcpy_fromio((unsigned long)(a), (unsigned long)(b), (c))
-#define memcpy_toio(a,b,c)   __memcpy_toio((unsigned long)(a), (unsigned long)(b), (c))
-#define memset_io(a,b,c)     __memset_io((unsigned long)(a), (b), (c))
+void memset_io(volatile void __iomem *addr, unsigned char val, int count);
+void memcpy_fromio(void *dst, const volatile void __iomem *src, int count);
+void memcpy_toio(volatile void __iomem *dst, const void *src, int count);
 
 /* Support old drivers which don't ioremap.
  * NB this interface is scheduled to disappear in 2.5
  */
 
-#define EISA_BASE 0xfffffffffc000000UL
-#define isa_readb(a) readb(EISA_BASE | (a))
-#define isa_readw(a) readw(EISA_BASE | (a))
-#define isa_readl(a) readl(EISA_BASE | (a))
-#define isa_writeb(b,a) writeb((b), EISA_BASE | (a))
-#define isa_writew(b,a) writew((b), EISA_BASE | (a))
-#define isa_writel(b,a) writel((b), EISA_BASE | (a))
-#define isa_memset_io(a,b,c) memset_io(EISA_BASE | (a), (b), (c))
-#define isa_memcpy_fromio(a,b,c) memcpy_fromio((a), EISA_BASE | (b), (c))
-#define isa_memcpy_toio(a,b,c) memcpy_toio(EISA_BASE | (a), (b), (c))
-
-/* 
- * These functions support PA-RISC drivers which don't yet call ioremap().
- * They will disappear once the last of these drivers is gone.
- */
-#define gsc_readb(x) __raw_readb(x)
-#define gsc_readw(x) __raw_readw(x)
-#define gsc_readl(x) __raw_readl(x)
-#define gsc_writeb(x, y) __raw_writeb(x, y)
-#define gsc_writew(x, y) __raw_writew(x, y)
-#define gsc_writel(x, y) __raw_writel(x, y)
+#define __isa_addr(x) (void __iomem *)(F_EXTEND(0xfc000000) | (x))
+#define isa_readb(a) readb(__isa_addr(a))
+#define isa_readw(a) readw(__isa_addr(a))
+#define isa_readl(a) readl(__isa_addr(a))
+#define isa_writeb(b,a) writeb((b), __isa_addr(a))
+#define isa_writew(b,a) writew((b), __isa_addr(a))
+#define isa_writel(b,a) writel((b), __isa_addr(a))
+#define isa_memset_io(a,b,c) memset_io(__isa_addr(a), (b), (c))
+#define isa_memcpy_fromio(a,b,c) memcpy_fromio((a), __isa_addr(b), (c))
+#define isa_memcpy_toio(a,b,c) memcpy_toio(__isa_addr(a), (b), (c))
 
 
 /*
@@ -305,5 +400,7 @@
  * bit I/O address (still with the leading f) and outputs the correct
  * value for either 32 or 64 bit mode */
 #define F_EXTEND(x) ((unsigned long)((x) | (0xffffffff00000000ULL)))
+
+#include <asm-generic/iomap.h>
 
 #endif
diff -Nru a/include/asm-parisc/irq.h b/include/asm-parisc/irq.h
--- a/include/asm-parisc/irq.h	2005-03-01 23:38:55 -08:00
+++ b/include/asm-parisc/irq.h	2005-03-01 23:38:55 -08:00
@@ -1,102 +1,53 @@
 /*
- *	linux/include/asm-parisc/irq.h
+ * include/asm-parisc/irq.h
  *
- *	(C) 1992, 1993 Linus Torvalds, (C) 1997 Ingo Molnar,
- *		Copyright 1999 SuSE GmbH
- *
- *	IRQ/IPI changes taken from work by Thomas Radke
- *	<tomsoft@informatik.tu-chemnitz.de>
+ * Copyright 2005 Matthew Wilcox <matthew@wil.cx>
  */
 
 #ifndef _ASM_PARISC_IRQ_H
 #define _ASM_PARISC_IRQ_H
 
-#include <asm/ptrace.h>
-#include <asm/types.h>
-#include <asm/errno.h>
-
-#include <linux/string.h>
-#include <linux/interrupt.h>
 #include <linux/config.h>
+#include <asm/types.h>
 
+#define NO_IRQ		(-1)
 
-#define CPU_IRQ_REGION		1
-#define TIMER_IRQ		(IRQ_FROM_REGION(CPU_IRQ_REGION) | 0)
-#define	IPI_IRQ			(IRQ_FROM_REGION(CPU_IRQ_REGION) | 1)
-
-/* This should be 31 for PA1.1 binaries and 63 for PA-2.0 wide mode */
-#define MAX_CPU_IRQ		(BITS_PER_LONG - 1)
-
-#if BITS_PER_LONG == 32
-#  define IRQ_REGION_SHIFT 	5
+#ifdef CONFIG_GSC
+#define GSC_IRQ_BASE	16
+#define GSC_IRQ_MAX	63
+#define CPU_IRQ_BASE	64
 #else
-#  define IRQ_REGION_SHIFT 	6
+#define CPU_IRQ_BASE	16
 #endif
 
-#define IRQ_PER_REGION		(1 << IRQ_REGION_SHIFT)
-#define NR_IRQ_REGS		16
-#define NR_IRQS			(NR_IRQ_REGS * IRQ_PER_REGION)
-
-#define IRQ_REGION(irq) 	((irq) >> IRQ_REGION_SHIFT)
-#define IRQ_OFFSET(irq)		((irq) & ((1<<IRQ_REGION_SHIFT)-1))
-#define	IRQ_FROM_REGION(reg)	((reg) << IRQ_REGION_SHIFT)
-
-#define EISA_IRQ_REGION		0 /* region 0 needs to be reserved for EISA */
-#define EISA_MAX_IRQS		16 /* max. (E)ISA irq line */
-
-struct irq_region_ops {
-	void (*disable_irq)(void *dev, int irq);
-	void (* enable_irq)(void *dev, int irq);
-	void (*   mask_irq)(void *dev, int irq);
-	void (* unmask_irq)(void *dev, int irq);
-};
-
-struct irq_region_data {
-	void *dev;
-	const char *name;
-	int irqbase;
-	unsigned int status[IRQ_PER_REGION]; /* IRQ status */
-};
-
-struct irq_region {
-	struct irq_region_ops ops;
-	struct irq_region_data data;
+#define TIMER_IRQ	(CPU_IRQ_BASE + 0)
+#define	IPI_IRQ		(CPU_IRQ_BASE + 1)
+#define CPU_IRQ_MAX	(CPU_IRQ_BASE + (BITS_PER_LONG - 1))
 
-	struct irqaction *action;
-};
-
-extern struct irq_region *irq_region[NR_IRQ_REGS];
+#define NR_IRQS		(CPU_IRQ_MAX + 1)
 
 static __inline__ int irq_canonicalize(int irq)
 {
-#ifdef CONFIG_EISA
-	return (irq == (IRQ_FROM_REGION(EISA_IRQ_REGION)+2) 
-		? (IRQ_FROM_REGION(EISA_IRQ_REGION)+9) : irq);
-#else
-	return irq;
-#endif
+	return (irq == 2) ? 9 : irq;
 }
 
-extern void disable_irq(int);
-#define disable_irq_nosync(i) disable_irq(i)
-extern void enable_irq(int);
-
-extern void do_irq(struct irqaction *a, int i, struct pt_regs *p);
-extern void do_irq_mask(unsigned long mask, struct irq_region *region,
-	struct pt_regs *regs);
+struct hw_interrupt_type;
 
-extern struct irq_region *alloc_irq_region(int count, struct irq_region_ops *ops,
-	const char *name, void *dev);
+/*
+ * Some useful "we don't have to do anything here" handlers.  Should
+ * probably be provided by the generic code.
+ */
+void no_ack_irq(unsigned int irq);
+void no_end_irq(unsigned int irq);
 
 extern int txn_alloc_irq(void);
 extern int txn_claim_irq(int);
 extern unsigned int txn_alloc_data(int, unsigned int);
 extern unsigned long txn_alloc_addr(int);
 
+extern int cpu_claim_irq(unsigned int irq, struct hw_interrupt_type *, void *);
+
 /* soft power switch support (power.c) */
 extern struct tasklet_struct power_tasklet;
-
-struct irqaction;
-int handle_IRQ_event(unsigned int, struct pt_regs *, struct irqaction *);
 
 #endif	/* _ASM_PARISC_IRQ_H */
diff -Nru a/include/asm-parisc/parisc-device.h b/include/asm-parisc/parisc-device.h
--- a/include/asm-parisc/parisc-device.h	2005-03-01 23:38:55 -08:00
+++ b/include/asm-parisc/parisc-device.h	2005-03-01 23:38:55 -08:00
@@ -3,11 +3,7 @@
 struct parisc_device {
 	unsigned long   hpa;		/* Hard Physical Address */
 	struct parisc_device_id id;
-	struct parisc_device *parent;
-	struct parisc_device *sibling;
-	struct parisc_device *child;
 	struct parisc_driver *driver;	/* Driver for this device */
-	void		*sysdata;	/* Driver instance private data */
 	char		name[80];	/* The hardware description */
 	int		irq;
 
@@ -40,5 +36,18 @@
 
 #define to_parisc_device(d)	container_of(d, struct parisc_device, dev)
 #define to_parisc_driver(d)	container_of(d, struct parisc_driver, drv)
+#define parisc_parent(d)	to_parisc_device(d->dev.parent)
+
+static inline void
+parisc_set_drvdata(struct parisc_device *d, void *p)
+{
+	dev_set_drvdata(&d->dev, p);
+}
+
+static inline void *
+parisc_get_drvdata(struct parisc_device *d)
+{
+	return dev_get_drvdata(&d->dev);
+}
 
 extern struct bus_type parisc_bus_type;
diff -Nru a/include/asm-parisc/pdc.h b/include/asm-parisc/pdc.h
--- a/include/asm-parisc/pdc.h	2005-03-01 23:38:43 -08:00
+++ b/include/asm-parisc/pdc.h	2005-03-01 23:38:43 -08:00
@@ -471,6 +471,13 @@
 	unsigned long mod_pgs;
 };
 
+struct pdc_initiator { /* PDC_INITIATOR */
+	int host_id;
+	int factor;
+	int width;
+	int mode;
+};
+
 struct hardware_path {
 	char  flags;	/* see bit definitions below */
 	char  bc[6];	/* Bus Converter routing info to a specific */
@@ -732,10 +739,16 @@
 #endif /* !CONFIG_PA20 */
 int pdc_lan_station_id(char *lan_addr, unsigned long net_hpa);
 
+int pdc_stable_read(unsigned long staddr, void *memaddr, unsigned long count);
+int pdc_stable_write(unsigned long staddr, void *memaddr, unsigned long count);
+int pdc_stable_get_size(unsigned long *size);
+int pdc_stable_verify_contents(void);
+int pdc_stable_initialize(void);
+
 int pdc_pci_irt_size(unsigned long *num_entries, unsigned long hpa);
 int pdc_pci_irt(unsigned long num_entries, unsigned long hpa, void *tbl);
 
-int pdc_get_initiator(struct hardware_path *hwpath, unsigned char *scsi_id, unsigned long *period, char *width, char *mode);
+int pdc_get_initiator(struct hardware_path *, struct pdc_initiator *);
 int pdc_tod_read(struct pdc_tod *tod);
 int pdc_tod_set(unsigned long sec, unsigned long usec);
 
diff -Nru a/include/asm-parisc/pgalloc.h b/include/asm-parisc/pgalloc.h
--- a/include/asm-parisc/pgalloc.h	2005-03-01 23:39:17 -08:00
+++ b/include/asm-parisc/pgalloc.h	2005-03-01 23:39:17 -08:00
@@ -120,18 +120,14 @@
 static inline struct page *
 pte_alloc_one(struct mm_struct *mm, unsigned long address)
 {
-	struct page *page = alloc_page(GFP_KERNEL|__GFP_REPEAT);
-	if (likely(page != NULL))
-		clear_page(page_address(page));
+	struct page *page = alloc_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO);
 	return page;
 }
 
 static inline pte_t *
 pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr)
 {
-	pte_t *pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT);
-	if (likely(pte != NULL))
-		clear_page(pte);
+	pte_t *pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO);
 	return pte;
 }
 
diff -Nru a/include/asm-parisc/pgtable.h b/include/asm-parisc/pgtable.h
--- a/include/asm-parisc/pgtable.h	2005-03-01 23:39:09 -08:00
+++ b/include/asm-parisc/pgtable.h	2005-03-01 23:39:09 -08:00
@@ -1,6 +1,8 @@
 #ifndef _PARISC_PGTABLE_H
 #define _PARISC_PGTABLE_H
 
+#include <asm-generic/4level-fixup.h>
+
 #include <linux/config.h>
 #include <asm/fixmap.h>
 
diff -Nru a/include/asm-parisc/processor.h b/include/asm-parisc/processor.h
--- a/include/asm-parisc/processor.h	2005-03-01 23:39:18 -08:00
+++ b/include/asm-parisc/processor.h	2005-03-01 23:39:18 -08:00
@@ -107,9 +107,6 @@
 
 #define CPU_HVERSION ((boot_cpu_data.hversion >> 4) & 0x0FFF)
 
-#define MCA_bus 0
-#define MCA_bus__is_a_macro /* for versions in ksyms.c */
-
 typedef struct {
 	int seg;  
 } mm_segment_t;
diff -Nru a/include/asm-parisc/ptrace.h b/include/asm-parisc/ptrace.h
--- a/include/asm-parisc/ptrace.h	2005-03-01 23:38:56 -08:00
+++ b/include/asm-parisc/ptrace.h	2005-03-01 23:38:56 -08:00
@@ -47,7 +47,7 @@
 
 /* XXX should we use iaoq[1] or iaoq[0] ? */
 #define user_mode(regs)			(((regs)->iaoq[0] & 3) ? 1 : 0)
-#define user_space(regs)		(((regs)->iasq[0] != 0) ? 1 : 0)
+#define user_space(regs)		(((regs)->iasq[1] != 0) ? 1 : 0)
 #define instruction_pointer(regs)	((regs)->iaoq[0] & ~3)
 #define profile_pc(regs) instruction_pointer(regs)
 extern void show_regs(struct pt_regs *);
diff -Nru a/include/asm-parisc/resource.h b/include/asm-parisc/resource.h
--- a/include/asm-parisc/resource.h	2005-03-01 23:39:08 -08:00
+++ b/include/asm-parisc/resource.h	2005-03-01 23:39:08 -08:00
@@ -1,51 +1,7 @@
 #ifndef _ASM_PARISC_RESOURCE_H
 #define _ASM_PARISC_RESOURCE_H
 
-/*
- * Resource limits
- */
-
-#define RLIMIT_CPU	0		/* CPU time in ms */
-#define RLIMIT_FSIZE	1		/* Maximum filesize */
-#define RLIMIT_DATA	2		/* max data size */
-#define RLIMIT_STACK	3		/* max stack size */
-#define RLIMIT_CORE	4		/* max core file size */
-#define RLIMIT_RSS	5		/* max resident set size */
-#define RLIMIT_NPROC	6		/* max number of processes */
-#define RLIMIT_NOFILE	7		/* max number of open files */
-#define RLIMIT_MEMLOCK	8		/* max locked-in-memory address space */
-#define RLIMIT_AS	9		/* address space limit */
-#define RLIMIT_LOCKS	10		/* maximum file locks held */
-#define RLIMIT_SIGPENDING 11		/* max number of pending signals */
-#define RLIMIT_MSGQUEUE 12		/* maximum bytes in POSIX mqueues */
-
-#define RLIM_NLIMITS	13
-
-/*
- * SuS says limits have to be unsigned.
- * Which makes a ton more sense anyway.
- */
-#define RLIM_INFINITY   (~0UL)
-
-#ifdef __KERNEL__
-
-#define INIT_RLIMITS					\
-{							\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{      _STK_LIM, 10 * _STK_LIM },		\
-	{             0, RLIM_INFINITY },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{             0,             0 },		\
-	{      INR_OPEN,     INR_OPEN  },		\
-	{   MLOCK_LIMIT,   MLOCK_LIMIT },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{ MAX_SIGPENDING, MAX_SIGPENDING },		\
-	{ MQ_BYTES_MAX, MQ_BYTES_MAX },			\
-}
-
-#endif /* __KERNEL__ */
+#define _STK_LIM_MAX	10 * _STK_LIM
+#include <asm-generic/resource.h>
 
 #endif
diff -Nru a/include/asm-parisc/serial.h b/include/asm-parisc/serial.h
--- a/include/asm-parisc/serial.h	2005-03-01 23:39:18 -08:00
+++ b/include/asm-parisc/serial.h	2005-03-01 23:39:18 -08:00
@@ -13,21 +13,6 @@
 #define LASI_BASE_BAUD ( 7272727 / 16 )
 #define BASE_BAUD  LASI_BASE_BAUD
 
-#ifdef CONFIG_SERIAL_DETECT_IRQ
-#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ)
-#define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_AUTO_IRQ)
-#else
-#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
-#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
-	
 /*
  * We don't use the ISA probing code, so these entries are just to reserve
  * space.  Some example (maximal) configurations:
diff -Nru a/include/asm-parisc/spinlock.h b/include/asm-parisc/spinlock.h
--- a/include/asm-parisc/spinlock.h	2005-03-01 23:39:18 -08:00
+++ b/include/asm-parisc/spinlock.h	2005-03-01 23:39:18 -08:00
@@ -142,13 +142,16 @@
 typedef struct {
 	spinlock_t lock;
 	volatile int counter;
+#ifdef CONFIG_PREEMPT
+	unsigned int break_lock;
+#endif
 } rwlock_t;
 
 #define RW_LOCK_UNLOCKED (rwlock_t) { __SPIN_LOCK_UNLOCKED, 0 }
 
 #define rwlock_init(lp)	do { *(lp) = RW_LOCK_UNLOCKED; } while (0)
 
-#define rwlock_is_locked(lp) ((lp)->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. */
diff -Nru a/include/asm-parisc/string.h b/include/asm-parisc/string.h
--- a/include/asm-parisc/string.h	2005-03-01 23:39:07 -08:00
+++ b/include/asm-parisc/string.h	2005-03-01 23:39:07 -08:00
@@ -7,7 +7,4 @@
 #define __HAVE_ARCH_MEMCPY
 void * memcpy(void * dest,const void *src,size_t count);
 
-#define __HAVE_ARCH_BCOPY
-void bcopy(const void * srcp, void * destp, size_t count);
-
 #endif
diff -Nru a/include/asm-parisc/superio.h b/include/asm-parisc/superio.h
--- a/include/asm-parisc/superio.h	2005-03-01 23:38:54 -08:00
+++ b/include/asm-parisc/superio.h	2005-03-01 23:38:54 -08:00
@@ -56,7 +56,6 @@
 	u32 pp_base;
 	u32 acpi_base;
 	int suckyio_irq_enabled;
-	struct irq_region *irq_region;
 	struct pci_dev *lio_pdev;       /* pci device for legacy IO (fn 1) */
 	struct pci_dev *usb_pdev;       /* pci device for USB (fn 2) */
 };
@@ -81,11 +80,6 @@
 	|| ((x)->device == PCI_DEVICE_ID_NS_87560_LIO) \
 	|| ((x)->device == PCI_DEVICE_ID_NS_87560_USB) ) )
 
-struct hwif_s;
-
-extern void superio_inform_irq(int irq);
-extern void superio_serial_init(void);		/* called by rs_init() */
 extern int superio_fixup_irq(struct pci_dev *pcidev); /* called by iosapic */
-extern void superio_fixup_pci(struct pci_dev *pdev);
 
 #endif /* _PARISC_SUPERIO_H */
diff -Nru a/include/asm-parisc/system.h b/include/asm-parisc/system.h
--- a/include/asm-parisc/system.h	2005-03-01 23:38:58 -08:00
+++ b/include/asm-parisc/system.h	2005-03-01 23:38:58 -08:00
@@ -176,6 +176,9 @@
 	void *previous;
 	struct task_struct * task;
 #endif
+#ifdef CONFIG_PREEMPT
+	unsigned int break_lock;
+#endif
 } spinlock_t;
 
 #define __lock_aligned __attribute__((__section__(".data.lock_aligned")))
diff -Nru a/include/asm-parisc/thread_info.h b/include/asm-parisc/thread_info.h
--- a/include/asm-parisc/thread_info.h	2005-03-01 23:38:54 -08:00
+++ b/include/asm-parisc/thread_info.h	2005-03-01 23:38:54 -08:00
@@ -63,6 +63,7 @@
 #define TIF_NEED_RESCHED	3	/* rescheduling necessary */
 #define TIF_POLLING_NRFLAG	4	/* true if poll_idle() is polling TIF_NEED_RESCHED */
 #define TIF_32BIT               5       /* 32 bit binary */
+#define TIF_MEMDIE		6
 
 #define _TIF_SYSCALL_TRACE	(1 << TIF_SYSCALL_TRACE)
 #define _TIF_NOTIFY_RESUME	(1 << TIF_NOTIFY_RESUME)
diff -Nru a/include/asm-parisc/unistd.h b/include/asm-parisc/unistd.h
--- a/include/asm-parisc/unistd.h	2005-03-01 23:38:44 -08:00
+++ b/include/asm-parisc/unistd.h	2005-03-01 23:38:44 -08:00
@@ -822,7 +822,7 @@
 		__sys_res = (long)__res;				\
 	}								\
 	if ( (unsigned long)__sys_res >= (unsigned long)-4095 ){	\
-		errno = -__sys_res);		        		\
+		errno = -__sys_res;		        		\
 		__sys_res = -1;						\
 	}								\
 	__sys_res;							\
@@ -912,6 +912,7 @@
 #define __ARCH_WANT_SYS_SGETMASK
 #define __ARCH_WANT_SYS_SIGNAL
 #define __ARCH_WANT_SYS_TIME
+#define __ARCH_WANT_COMPAT_SYS_TIME
 #define __ARCH_WANT_SYS_UTIME
 #define __ARCH_WANT_SYS_WAITPID
 #define __ARCH_WANT_SYS_SOCKETCALL
diff -Nru a/include/asm-ppc/cputime.h b/include/asm-ppc/cputime.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-ppc/cputime.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,6 @@
+#ifndef __PPC_CPUTIME_H
+#define __PPC_CPUTIME_H
+
+#include <asm-generic/cputime.h>
+
+#endif /* __PPC_CPUTIME_H */
diff -Nru a/include/asm-ppc/gg2.h b/include/asm-ppc/gg2.h
--- a/include/asm-ppc/gg2.h	2005-03-01 23:39:08 -08:00
+++ b/include/asm-ppc/gg2.h	2005-03-01 23:39:08 -08:00
@@ -34,7 +34,7 @@
      *  GG2 specific PCI Registers
      */
 
-extern unsigned long gg2_pci_config_base;	/* kernel virtual address */
+extern void __iomem *gg2_pci_config_base;	/* kernel virtual address */
 
 #define GG2_PCI_BUSNO		0x40	/* Bus number */
 #define GG2_PCI_SUBBUSNO	0x41	/* Subordinate bus number */
diff -Nru a/include/asm-ppc/highmem.h b/include/asm-ppc/highmem.h
--- a/include/asm-ppc/highmem.h	2005-03-01 23:39:17 -08:00
+++ b/include/asm-ppc/highmem.h	2005-03-01 23:39:17 -08:00
@@ -56,7 +56,7 @@
 static inline void *kmap(struct page *page)
 {
 	might_sleep();
-	if (page < highmem_start_page)
+	if (!PageHighMem(page))
 		return page_address(page);
 	return kmap_high(page);
 }
@@ -64,7 +64,7 @@
 static inline void kunmap(struct page *page)
 {
 	BUG_ON(in_interrupt());
-	if (page < highmem_start_page)
+	if (!PageHighMem(page))
 		return;
 	kunmap_high(page);
 }
@@ -82,7 +82,7 @@
 
 	/* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */
 	inc_preempt_count();
-	if (page < highmem_start_page)
+	if (!PageHighMem(page))
 		return page_address(page);
 
 	idx = type + KM_TYPE_NR*smp_processor_id();
diff -Nru a/include/asm-ppc/ibm44x.h b/include/asm-ppc/ibm44x.h
--- a/include/asm-ppc/ibm44x.h	2005-03-01 23:39:19 -08:00
+++ b/include/asm-ppc/ibm44x.h	2005-03-01 23:39:19 -08:00
@@ -3,9 +3,9 @@
  *
  * PPC44x definitions
  *
- * Matt Porter <mporter@mvista.com>
+ * Matt Porter <mporter@kernel.crashing.org>
  *
- * Copyright 2002-2003 MontaVista Software Inc.
+ * Copyright 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 as published by the
@@ -34,23 +34,55 @@
 /* Lowest TLB slot consumed by the default pinned TLBs */
 #define PPC44x_LOW_SLOT		63
 
+/* LS 32-bits of UART0 physical address location for early serial text debug */
+#ifdef CONFIG_440SP
+#define UART0_PHYS_IO_BASE	0xf0000200
+#else
+#define UART0_PHYS_IO_BASE	0x40000200
+#endif
+
+/*
+ * XXX This 36-bit trap stuff will move somewhere in syslib/
+ * when we rework/abstract the PPC44x PCI-X handling -mdp
+ */
+
 /*
  * Standard 4GB "page" definitions
  */
+#ifdef CONFIG_440SP
+#define	PPC44x_IO_PAGE		0x0000000100000000ULL
+#define	PPC44x_PCICFG_PAGE	0x0000000900000000ULL
+#define	PPC44x_PCIIO_PAGE	PPC44x_PCICFG_PAGE
+#define	PPC44x_PCIMEM_PAGE	0x0000000a00000000ULL
+#else
 #define	PPC44x_IO_PAGE		0x0000000100000000ULL
 #define	PPC44x_PCICFG_PAGE	0x0000000200000000ULL
 #define	PPC44x_PCIIO_PAGE	PPC44x_PCICFG_PAGE
 #define	PPC44x_PCIMEM_PAGE	0x0000000300000000ULL
+#endif
 
 /*
  * 36-bit trap ranges
  */
-#define PPC44x_IO_LO		0x40000000
-#define PPC44x_IO_HI		0x40001000
-#define PPC44x_PCICFG_LO	0x0ec00000
-#define PPC44x_PCICFG_HI	0x0ec7ffff
-#define PPC44x_PCIMEM_LO	0x80002000
-#define PPC44x_PCIMEM_HI	0xffffffff
+#ifdef CONFIG_440SP
+#define PPC44x_IO_LO		0xf0000000UL
+#define PPC44x_IO_HI		0xf0000fffUL
+#define PPC44x_PCI0CFG_LO	0x0ec00000UL
+#define PPC44x_PCI0CFG_HI	0x0ec00007UL
+#define PPC44x_PCI1CFG_LO	0x1ec00000UL
+#define PPC44x_PCI1CFG_HI	0x1ec00007UL
+#define PPC44x_PCI2CFG_LO	0x2ec00000UL
+#define PPC44x_PCI2CFG_HI	0x2ec00007UL
+#define PPC44x_PCIMEM_LO	0x80000000UL
+#define PPC44x_PCIMEM_HI	0xdfffffffUL
+#else
+#define PPC44x_IO_LO		0x40000000UL
+#define PPC44x_IO_HI		0x40000fffUL
+#define PPC44x_PCI0CFG_LO	0x0ec00000UL
+#define PPC44x_PCI0CFG_HI	0x0ec00007UL
+#define PPC44x_PCIMEM_LO	0x80002000UL
+#define PPC44x_PCIMEM_HI	0xffffffffUL
+#endif
 
 /*
  * The "residual" board information structure the boot loader passes
@@ -59,16 +91,11 @@
 #ifndef __ASSEMBLY__
 
 /*
- * SPRN definitions
- */
-#define SPRN_CPC0_GPIO		0xe5/BEARLRL
-
-/*
  * DCRN definitions
  */
 
-#ifdef CONFIG_440GX
-/* CPRs */
+
+/* CPRs (440GX and 440SP) */
 #define DCRN_CPR_CONFIG_ADDR	0xc
 #define DCRN_CPR_CONFIG_DATA	0xd
 
@@ -89,7 +116,7 @@
 	mtdcr(DCRN_CPR_CONFIG_ADDR, offset); \
 	mtdcr(DCRN_CPR_CONFIG_DATA, data);})
 
-/* SDRs */
+/* SDRs (440GX and 440SP) */
 #define DCRN_SDR_CONFIG_ADDR 	0xe
 #define DCRN_SDR_CONFIG_DATA	0xf
 #define DCRN_SDR_PFC0		0x4100
@@ -132,9 +159,8 @@
 #define SDR_WRITE(offset, data) ({\
 	mtdcr(DCRN_SDR_CONFIG_ADDR, offset); \
 	mtdcr(DCRN_SDR_CONFIG_DATA,data);})
-#endif /* CONFIG_440GX */
 
-/* Base DCRNs */
+/* DMA (excluding 440SP) */
 #define DCRN_DMA0_BASE		0x100
 #define DCRN_DMA1_BASE		0x108
 #define DCRN_DMA2_BASE		0x110
@@ -162,14 +188,13 @@
 #define DCRN_UIC_VR(base)       (base + 0x7)
 #define DCRN_UIC_VCR(base)      (base + 0x8)
 
-#define UIC0_UIC1NC		30	/* UIC1 non-critical interrupt */
-#define UIC0_UIC1CR      	31	/* UIC1 critical interrupt */
+#define UIC0_UIC1NC      	0x00000002
 
 #define UICB_UIC0NC		0x40000000
 #define UICB_UIC1NC		0x10000000
 #define UICB_UIC2NC		0x04000000
 
-/* 440GP MAL DCRs */
+/* 440 MAL DCRs */
 #define DCRN_MALCR(base)		(base + 0x0)	/* Configuration */
 #define DCRN_MALESR(base)		(base + 0x1)	/* Error Status */
 #define DCRN_MALIER(base)		(base + 0x2)	/* Interrupt Enable */
@@ -200,7 +225,6 @@
 #define DCRN_MALRCBS2(base)	((base) + 0x62)	/* Channel Rx 2 Channel Buffer Size */
 #define DCRN_MALRCBS3(base)	((base) + 0x63)	/* Channel Rx 3 Channel Buffer Size */
 
-
 #define MALCR_MMSR		0x80000000	/* MAL Software reset */
 #define MALCR_PLBP_1		0x00400000	/* MAL reqest priority: */
 #define MALCR_PLBP_2		0x00800000	/* lowsest is 00 */
@@ -245,7 +269,7 @@
 #define MALOBISR_CH0		0x80000000	/* EOB channel 1 bit */
 #define MALOBISR_CH2		0x40000000	/* EOB channel 2 bit */
 
-/* 440GP PLB Arbiter DCRs */
+/* 440GP/GX PLB Arbiter DCRs */
 #define DCRN_PLB0_REVID		0x082		/* PLB Arbiter Revision ID */
 #define DCRN_PLB0_ACR		0x083		/* PLB Arbiter Control */
 #define DCRN_PLB0_BESR		0x084		/* PLB Error Status */
@@ -253,6 +277,17 @@
 #define DCRN_PLB0_BEAR		DCRN_PLB0_BEARL	/* 40x compatibility */
 #define DCRN_PLB0_BEARH		0x087		/* PLB Error Address High */
 
+/* 440GP/GX PLB to OPB bridge DCRs */
+#define DCRN_POB0_BESR0		0x090
+#define DCRN_POB0_BESR1		0x094
+#define DCRN_POB0_BEARL		0x092
+#define DCRN_POB0_BEARH		0x093
+
+/* 440GP/GX OPB to PLB bridge DCRs */
+#define DCRN_OPB0_BSTAT		0x0a9
+#define DCRN_OPB0_BEARL		0x0aa
+#define DCRN_OPB0_BEARH		0x0ab
+
 /* 440GP Clock, PM, chip control */
 #define DCRN_CPC0_SR		0x0b0
 #define DCRN_CPC0_ER		0x0b1
@@ -315,7 +350,7 @@
 #define DCRN_SLP	(DCRN_DMASR_BASE + 0x5)	/* DMA Sleep Register */
 #define DCRN_POL	(DCRN_DMASR_BASE + 0x6)	/* DMA Polarity Register */
 
-/* 440GP DRAM controller DCRs */
+/* 440GP/440GX SDRAM controller DCRs */
 #define DCRN_SDRAM0_CFGADDR		0x010
 #define DCRN_SDRAM0_CFGDATA		0x011
 
@@ -341,13 +376,35 @@
 #define PPC44x_MEM_SIZE_128M		0x08000000
 #define PPC44x_MEM_SIZE_256M		0x10000000
 #define PPC44x_MEM_SIZE_512M		0x20000000
+#define PPC44x_MEM_SIZE_1G		0x40000000
+#define PPC44x_MEM_SIZE_2G		0x80000000
 
-#ifdef CONFIG_440GX
-/* Internal SRAM Controller */
-#define DCRN_SRAM0_SB0CR	0x020
-#define DCRN_SRAM0_SB1CR	0x021
-#define DCRN_SRAM0_SB2CR	0x022
-#define DCRN_SRAM0_SB3CR	0x023
+/* 440SP memory controller DCRs */
+#define DCRN_MQ0_BS0BAS			0x40
+#define DCRN_MQ0_BS1BAS			0x41
+
+#define MQ0_CONFIG_SIZE_MASK		0x0000fff0
+#define MQ0_CONFIG_SIZE_8M		0x0000ffc0
+#define MQ0_CONFIG_SIZE_16M		0x0000ff80
+#define MQ0_CONFIG_SIZE_32M		0x0000ff00
+#define MQ0_CONFIG_SIZE_64M		0x0000fe00
+#define MQ0_CONFIG_SIZE_128M		0x0000fc00
+#define MQ0_CONFIG_SIZE_256M		0x0000f800
+#define MQ0_CONFIG_SIZE_512M		0x0000f000
+#define MQ0_CONFIG_SIZE_1G		0x0000e000
+#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)
+#define DCRN_SRAM0_SB2CR	(DCRN_SRAM0_BASE + 0x022)
+#define DCRN_SRAM0_SB3CR	(DCRN_SRAM0_BASE + 0x023)
 #define  SRAM_SBCR_BAS0		0x80000000
 #define  SRAM_SBCR_BAS1		0x80010000
 #define  SRAM_SBCR_BAS2		0x80020000
@@ -356,16 +413,16 @@
 #define  SRAM_SBCR_BS_64KB	0x00000800
 #define  SRAM_SBCR_BU_RO	0x00000080
 #define  SRAM_SBCR_BU_RW	0x00000180
-#define DCRN_SRAM0_BEAR		0x024
-#define DCRN_SRAM0_BESR0	0x025
-#define DCRN_SRAM0_BESR1	0x026
-#define DCRN_SRAM0_PMEG		0x027
-#define DCRN_SRAM0_CID		0x028
-#define DCRN_SRAM0_REVID	0x029
-#define DCRN_SRAM0_DPC		0x02a
+#define DCRN_SRAM0_BEAR		(DCRN_SRAM0_BASE + 0x024)
+#define DCRN_SRAM0_BESR0	(DCRN_SRAM0_BASE + 0x025)
+#define DCRN_SRAM0_BESR1	(DCRN_SRAM0_BASE + 0x026)
+#define DCRN_SRAM0_PMEG		(DCRN_SRAM0_BASE + 0x027)
+#define DCRN_SRAM0_CID		(DCRN_SRAM0_BASE + 0x028)
+#define DCRN_SRAM0_REVID	(DCRN_SRAM0_BASE + 0x029)
+#define DCRN_SRAM0_DPC		(DCRN_SRAM0_BASE + 0x02a)
 #define  SRAM_DPC_ENABLE	0x80000000
 
-/* L2 Cache Controller */
+/* L2 Cache Controller 440GX/440SP */
 #define DCRN_L2C0_CFG		0x030
 #define  L2C_CFG_L2M		0x80000000
 #define  L2C_CFG_ICU		0x40000000
@@ -415,13 +472,29 @@
 #define  L2C_SNP_SSR_MASK	0x0000f000
 #define  L2C_SNP_SSR_32G	0x0000f000
 #define  L2C_SNP_ESR		0x00000800
-#endif /* CONFIG_440GX */
 
 /*
  * PCI-X definitions
  */
-#define PCIX0_REG_BASE		0x20ec80000ULL
-#define PCIX0_REG_SIZE		0x200
+#define PCIX0_CFGA		0x0ec00000UL
+#define PCIX1_CFGA		0x1ec00000UL
+#define PCIX2_CFGA		0x2ec00000UL
+#define PCIX0_CFGD		0x0ec00004UL
+#define PCIX1_CFGD		0x1ec00004UL
+#define PCIX2_CFGD		0x2ec00004UL
+
+#define PCIX0_IO_BASE		0x0000000908000000ULL
+#define PCIX1_IO_BASE		0x0000000908000000ULL
+#define PCIX2_IO_BASE		0x0000000908000000ULL
+#define PCIX_IO_SIZE		0x00010000
+
+#ifdef CONFIG_440SP
+#define PCIX0_REG_BASE		0x000000090ec80000ULL
+#else
+#define PCIX0_REG_BASE		0x000000020ec80000ULL
+#endif
+#define PCIX_REG_OFFSET		0x10000000
+#define PCIX_REG_SIZE		0x200
 
 #define PCIX0_VENDID		0x000
 #define PCIX0_DEVID		0x002
@@ -518,9 +591,6 @@
 #else
 #define NR_UICS 2
 #endif
-#define UIC_CASCADE_MASK	0x0003		/* bits 30 & 31 */
-
-#define BD_EMAC_ADDR(e,i) bi_enetaddr[e][i]
 
 #include <asm/ibm4xx.h>
 
diff -Nru a/include/asm-ppc/ibm4xx.h b/include/asm-ppc/ibm4xx.h
--- a/include/asm-ppc/ibm4xx.h	2005-03-01 23:38:57 -08:00
+++ b/include/asm-ppc/ibm4xx.h	2005-03-01 23:38:57 -08:00
@@ -101,6 +101,10 @@
 #include <platforms/4xx/ebony.h>
 #endif
 
+#if defined(CONFIG_LUAN)
+#include <platforms/4xx/luan.h>
+#endif
+
 #if defined(CONFIG_OCOTEA)
 #include <platforms/4xx/ocotea.h>
 #endif
diff -Nru a/include/asm-ppc/io.h b/include/asm-ppc/io.h
--- a/include/asm-ppc/io.h	2005-03-01 23:39:09 -08:00
+++ b/include/asm-ppc/io.h	2005-03-01 23:39:09 -08:00
@@ -133,7 +133,10 @@
 {
 	__asm__ __volatile__("stw%U0%X0 %1,%0; eieio" : "=m" (*addr) : "r" (val));
 }
-
+#if defined (CONFIG_8260_PCI9)
+#define readb(addr) in_8((volatile u8 *)(addr))
+#define writeb(b,addr) out_8((volatile u8 *)(addr), (b))
+#else
 static inline __u8 readb(volatile void __iomem *addr)
 {
 	return in_8(addr);
@@ -142,6 +145,8 @@
 {
 	out_8(addr, b);
 }
+#endif
+
 #if defined(CONFIG_APUS)
 static inline __u16 readw(volatile void __iomem *addr)
 {
@@ -159,6 +164,12 @@
 {
 	*(__force volatile __u32 *)(addr) = b;
 }
+#elif defined (CONFIG_8260_PCI9)
+/* Use macros if PCI9 workaround enabled */
+#define readw(addr) in_le16((volatile u16 *)(addr))
+#define readl(addr) in_le32((volatile u32 *)(addr))
+#define writew(b,addr) out_le16((volatile u16 *)(addr),(b))
+#define writel(b,addr) out_le32((volatile u32 *)(addr),(b))
 #else
 static inline __u16 readw(volatile void __iomem *addr)
 {
@@ -182,15 +193,15 @@
 #define readw_relaxed(addr) readw(addr)
 #define readl_relaxed(addr) readl(addr)
 
-static inline __u8 __raw_readb(volatile void __iomem *addr)
+static inline __u8 __raw_readb(const volatile void __iomem *addr)
 {
 	return *(__force volatile __u8 *)(addr);
 }
-static inline __u16 __raw_readw(volatile void __iomem *addr)
+static inline __u16 __raw_readw(const volatile void __iomem *addr)
 {
 	return *(__force volatile __u16 *)(addr);
 }
-static inline __u32 __raw_readl(volatile void __iomem *addr)
+static inline __u32 __raw_readl(const volatile void __iomem *addr)
 {
 	return *(__force volatile __u32 *)(addr);
 }
@@ -332,11 +343,16 @@
 
 #define IO_SPACE_LIMIT ~0
 
+#if defined (CONFIG_8260_PCI9)
+#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))
+#else
 static inline void memset_io(volatile void __iomem *addr, unsigned char val, int count)
 {
 	memset((void __force *)addr, val, count);
 }
-static inline void memcpy_fromio(void *dst, volatile void __iomem *src, int count)
+static inline void memcpy_fromio(void *dst,const volatile void __iomem *src, int count)
 {
 	memcpy(dst, (void __force *) src, count);
 }
@@ -344,6 +360,9 @@
 {
 	memcpy((void __force *) dst, src, count);
 }
+#endif
+
+#define eth_io_copy_and_sum(a,b,c,d)		eth_copy_and_sum((a),(void __force *)(void __iomem *)(b),(c),(d))
 
 /*
  * Map in an area of physical address space, for accessing
@@ -488,32 +507,32 @@
 
 static inline void ioread8_rep(void __iomem *addr, void *dst, unsigned long count)
 {
-	_insb((u8 __force *) addr, dst, count);
+	_insb(addr, dst, count);
 }
 
 static inline void ioread16_rep(void __iomem *addr, void *dst, unsigned long count)
 {
-	_insw_ns((u16 __force *) addr, dst, count);
+	_insw_ns(addr, dst, count);
 }
 
 static inline void ioread32_rep(void __iomem *addr, void *dst, unsigned long count)
 {
-	_insl_ns((u32 __force *) addr, dst, count);
+	_insl_ns(addr, dst, count);
 }
 
 static inline void iowrite8_rep(void __iomem *addr, const void *src, unsigned long count)
 {
-	_outsb((u8 __force *) addr, src, count);
+	_outsb(addr, src, count);
 }
 
 static inline void iowrite16_rep(void __iomem *addr, const void *src, unsigned long count)
 {
-	_outsw_ns((u16 __force *) addr, src, count);
+	_outsw_ns(addr, src, count);
 }
 
 static inline void iowrite32_rep(void __iomem *addr, const void *src, unsigned long count)
 {
-	_outsl_ns((u32 __force *) addr, src, count);
+	_outsl_ns(addr, src, count);
 }
 
 /* Create a virtual mapping cookie for an IO port range */
diff -Nru a/include/asm-ppc/irq.h b/include/asm-ppc/irq.h
--- a/include/asm-ppc/irq.h	2005-03-01 23:38:52 -08:00
+++ b/include/asm-ppc/irq.h	2005-03-01 23:38:52 -08:00
@@ -199,6 +199,7 @@
 #define	SIU_INT_RISC		((uint)0x03+CPM_IRQ_OFFSET)
 #define	SIU_INT_SMC1		((uint)0x04+CPM_IRQ_OFFSET)
 #define	SIU_INT_SMC2		((uint)0x05+CPM_IRQ_OFFSET)
+#define	SIU_INT_USB		((uint)0x0b+CPM_IRQ_OFFSET)
 #define	SIU_INT_TIMER1		((uint)0x0c+CPM_IRQ_OFFSET)
 #define	SIU_INT_TIMER2		((uint)0x0d+CPM_IRQ_OFFSET)
 #define	SIU_INT_TIMER3		((uint)0x0e+CPM_IRQ_OFFSET)
diff -Nru a/include/asm-ppc/mmu.h b/include/asm-ppc/mmu.h
--- a/include/asm-ppc/mmu.h	2005-03-01 23:39:16 -08:00
+++ b/include/asm-ppc/mmu.h	2005-03-01 23:39:16 -08:00
@@ -401,18 +401,17 @@
  * Freescale Book-E MMU support
  */
 
-#define MAS0_TLBSEL	0x10000000
-#define MAS0_ESEL	0x000F0000
-#define MAS0_NV		0x00000001
+#define MAS0_TLBSEL(x)	((x << 28) & 0x30000000)
+#define MAS0_ESEL(x)	((x << 16) & 0x0FFF0000)
+#define MAS0_NV		0x00000FFF
 
 #define MAS1_VALID 	0x80000000
 #define MAS1_IPROT	0x40000000
-#define MAS1_TID 	0x03FF0000
+#define MAS1_TID(x)	((x << 16) & 0x3FFF0000)
 #define MAS1_TS		0x00001000
-#define MAS1_TSIZE(x)	(x << 8)
+#define MAS1_TSIZE(x)	((x << 8) & 0x00000F00)
 
 #define MAS2_EPN	0xFFFFF000
-#define MAS2_SHAREN	0x00000200
 #define MAS2_X0		0x00000040
 #define MAS2_X1		0x00000020
 #define MAS2_W		0x00000010
@@ -433,10 +432,9 @@
 #define MAS3_UR		0x00000002
 #define MAS3_SR		0x00000001
 
-#define MAS4_TLBSELD	0x10000000
-#define MAS4_TIDDSEL	0x00030000
-#define MAS4_DSHAREN	0x00001000
-#define MAS4_TSIZED(x)	(x << 8)
+#define MAS4_TLBSELD(x) MAS0_TLBSEL(x)
+#define MAS4_TIDDSEL	0x000F0000
+#define MAS4_TSIZED(x)	MAS1_TSIZE(x)
 #define MAS4_X0D	0x00000040
 #define MAS4_X1D	0x00000020
 #define MAS4_WD		0x00000010
@@ -445,8 +443,12 @@
 #define MAS4_GD		0x00000002
 #define MAS4_ED		0x00000001
 
-#define MAS6_SPID	0x00FF0000
+#define MAS6_SPID0	0x3FFF0000
+#define MAS6_SPID1	0x00007FFE
 #define MAS6_SAS	0x00000001
+#define MAS6_SPID	MAS6_SPID0
+
+#define MAS7_RPN	0xFFFFFFFF
 
 #endif /* _PPC_MMU_H_ */
 #endif /* __KERNEL__ */
diff -Nru a/include/asm-ppc/mpc10x.h b/include/asm-ppc/mpc10x.h
--- a/include/asm-ppc/mpc10x.h	2005-03-01 23:39:08 -08:00
+++ b/include/asm-ppc/mpc10x.h	2005-03-01 23:39:08 -08:00
@@ -105,7 +105,11 @@
 #define	MPC10X_CFG_PICR1_ADDR_MAP_MASK	0x00010000
 #define	MPC10X_CFG_PICR1_ADDR_MAP_A	0x00010000
 #define	MPC10X_CFG_PICR1_ADDR_MAP_B	0x00000000
+#define	MPC10X_CFG_PICR1_SPEC_PCI_RD	0x00000004
 #define	MPC10X_CFG_PICR1_ST_GATH_EN	0x00000040
+
+#define	MPC10X_CFG_PICR2_REG		0xac
+#define	MPC10X_CFG_PICR2_COPYBACK_OPT	0x00000001
 
 #define	MPC10X_CFG_MAPB_OPTIONS_REG	0xe0
 #define	MPC10X_CFG_MAPB_OPTIONS_CFAE	0x80	/* CPU_FD_ALIAS_EN */
diff -Nru a/include/asm-ppc/mpc8260.h b/include/asm-ppc/mpc8260.h
--- a/include/asm-ppc/mpc8260.h	2005-03-01 23:38:44 -08:00
+++ b/include/asm-ppc/mpc8260.h	2005-03-01 23:38:44 -08:00
@@ -36,7 +36,7 @@
 #include <platforms/tqm8260.h>
 #endif
 
-#ifdef CONFIG_PQ2ADS
+#if defined(CONFIG_PQ2ADS) || defined (CONFIG_PQ2FADS)
 #include <platforms/pq2ads.h>
 #endif
 
diff -Nru a/include/asm-ppc/mpc85xx.h b/include/asm-ppc/mpc85xx.h
--- a/include/asm-ppc/mpc85xx.h	2005-03-01 23:39:18 -08:00
+++ b/include/asm-ppc/mpc85xx.h	2005-03-01 23:39:18 -08:00
@@ -34,6 +34,9 @@
 #ifdef CONFIG_SBC8560
 #include <platforms/85xx/sbc8560.h>
 #endif
+#ifdef CONFIG_STX_GP3
+#include <platforms/85xx/stx_gp3.h>
+#endif
 
 #define _IO_BASE        isa_io_base
 #define _ISA_MEM_BASE   isa_mem_base
@@ -103,6 +106,14 @@
 #define MPC85xx_CPM_SIZE	(0x40000)
 #define MPC85xx_DMA_OFFSET	(0x21000)
 #define MPC85xx_DMA_SIZE	(0x01000)
+#define MPC85xx_DMA0_OFFSET	(0x21100)
+#define MPC85xx_DMA0_SIZE	(0x00080)
+#define MPC85xx_DMA1_OFFSET	(0x21180)
+#define MPC85xx_DMA1_SIZE	(0x00080)
+#define MPC85xx_DMA2_OFFSET	(0x21200)
+#define MPC85xx_DMA2_SIZE	(0x00080)
+#define MPC85xx_DMA3_OFFSET	(0x21280)
+#define MPC85xx_DMA3_SIZE	(0x00080)
 #define MPC85xx_ENET1_OFFSET	(0x24000)
 #define MPC85xx_ENET1_SIZE	(0x01000)
 #define MPC85xx_ENET2_OFFSET	(0x25000)
@@ -138,6 +149,34 @@
 #else
 #define CCSRBAR BOARD_CCSRBAR
 #endif
+
+enum ppc_sys_devices {
+	MPC85xx_TSEC1,
+	MPC85xx_TSEC2,
+	MPC85xx_FEC,
+	MPC85xx_IIC1,
+	MPC85xx_DMA0,
+	MPC85xx_DMA1,
+	MPC85xx_DMA2,
+	MPC85xx_DMA3,
+	MPC85xx_DUART,
+	MPC85xx_PERFMON,
+	MPC85xx_SEC2,
+	MPC85xx_CPM_SPI,
+	MPC85xx_CPM_I2C,
+	MPC85xx_CPM_USB,
+	MPC85xx_CPM_SCC1,
+	MPC85xx_CPM_SCC2,
+	MPC85xx_CPM_SCC3,
+	MPC85xx_CPM_SCC4,
+	MPC85xx_CPM_FCC1,
+	MPC85xx_CPM_FCC2,
+	MPC85xx_CPM_FCC3,
+	MPC85xx_CPM_MCC1,
+	MPC85xx_CPM_MCC2,
+	MPC85xx_CPM_SMC1,
+	MPC85xx_CPM_SMC2,
+};
 
 #endif /* CONFIG_85xx */
 #endif /* __ASM_MPC85xx_H__ */
diff -Nru a/include/asm-ppc/mv64x60.h b/include/asm-ppc/mv64x60.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-ppc/mv64x60.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,345 @@
+/*
+ * include/asm-ppc/mv64x60.h
+ *
+ * Prototypes, etc. for the Marvell/Galileo MV64x60 host bridge routines.
+ *
+ * Author: Mark A. Greer <mgreer@mvista.com>
+ *
+ * 2001-2002 (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.
+ */
+#ifndef __ASMPPC_MV64x60_H
+#define __ASMPPC_MV64x60_H
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/config.h>
+
+#include <asm/byteorder.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+#include <asm/machdep.h>
+#include <asm/pci-bridge.h>
+#include <asm/mv64x60_defs.h>
+
+extern u8	mv64x60_pci_exclude_bridge;
+
+extern spinlock_t mv64x60_lock;
+
+/* 32-bit Window table entry defines */
+#define	MV64x60_CPU2MEM_0_WIN			0
+#define	MV64x60_CPU2MEM_1_WIN			1
+#define	MV64x60_CPU2MEM_2_WIN			2
+#define	MV64x60_CPU2MEM_3_WIN			3
+#define	MV64x60_CPU2DEV_0_WIN			4
+#define	MV64x60_CPU2DEV_1_WIN			5
+#define	MV64x60_CPU2DEV_2_WIN			6
+#define	MV64x60_CPU2DEV_3_WIN			7
+#define	MV64x60_CPU2BOOT_WIN			8
+#define	MV64x60_CPU2PCI0_IO_WIN			9
+#define	MV64x60_CPU2PCI0_MEM_0_WIN		10
+#define	MV64x60_CPU2PCI0_MEM_1_WIN		11
+#define	MV64x60_CPU2PCI0_MEM_2_WIN		12
+#define	MV64x60_CPU2PCI0_MEM_3_WIN		13
+#define	MV64x60_CPU2PCI1_IO_WIN			14
+#define	MV64x60_CPU2PCI1_MEM_0_WIN		15
+#define	MV64x60_CPU2PCI1_MEM_1_WIN		16
+#define	MV64x60_CPU2PCI1_MEM_2_WIN		17
+#define	MV64x60_CPU2PCI1_MEM_3_WIN		18
+#define	MV64x60_CPU2SRAM_WIN			19
+#define	MV64x60_CPU2PCI0_IO_REMAP_WIN		20
+#define	MV64x60_CPU2PCI1_IO_REMAP_WIN		21
+#define	MV64x60_CPU_PROT_0_WIN			22
+#define	MV64x60_CPU_PROT_1_WIN			23
+#define	MV64x60_CPU_PROT_2_WIN			24
+#define	MV64x60_CPU_PROT_3_WIN			25
+#define	MV64x60_CPU_SNOOP_0_WIN			26
+#define	MV64x60_CPU_SNOOP_1_WIN			27
+#define	MV64x60_CPU_SNOOP_2_WIN			28
+#define	MV64x60_CPU_SNOOP_3_WIN			29
+#define	MV64x60_PCI02MEM_REMAP_0_WIN		30
+#define	MV64x60_PCI02MEM_REMAP_1_WIN		31
+#define	MV64x60_PCI02MEM_REMAP_2_WIN		32
+#define	MV64x60_PCI02MEM_REMAP_3_WIN		33
+#define	MV64x60_PCI12MEM_REMAP_0_WIN		34
+#define	MV64x60_PCI12MEM_REMAP_1_WIN		35
+#define	MV64x60_PCI12MEM_REMAP_2_WIN		36
+#define	MV64x60_PCI12MEM_REMAP_3_WIN		37
+#define	MV64x60_ENET2MEM_0_WIN			38
+#define	MV64x60_ENET2MEM_1_WIN			39
+#define	MV64x60_ENET2MEM_2_WIN			40
+#define	MV64x60_ENET2MEM_3_WIN			41
+#define	MV64x60_ENET2MEM_4_WIN			42
+#define	MV64x60_ENET2MEM_5_WIN			43
+#define	MV64x60_MPSC2MEM_0_WIN			44
+#define	MV64x60_MPSC2MEM_1_WIN			45
+#define	MV64x60_MPSC2MEM_2_WIN			46
+#define	MV64x60_MPSC2MEM_3_WIN			47
+#define	MV64x60_IDMA2MEM_0_WIN			48
+#define	MV64x60_IDMA2MEM_1_WIN			49
+#define	MV64x60_IDMA2MEM_2_WIN			50
+#define	MV64x60_IDMA2MEM_3_WIN			51
+#define	MV64x60_IDMA2MEM_4_WIN			52
+#define	MV64x60_IDMA2MEM_5_WIN			53
+#define	MV64x60_IDMA2MEM_6_WIN			54
+#define	MV64x60_IDMA2MEM_7_WIN			55
+
+#define	MV64x60_32BIT_WIN_COUNT			56
+
+/* 64-bit Window table entry defines */
+#define	MV64x60_CPU2PCI0_MEM_0_REMAP_WIN	0
+#define	MV64x60_CPU2PCI0_MEM_1_REMAP_WIN	1
+#define	MV64x60_CPU2PCI0_MEM_2_REMAP_WIN	2
+#define	MV64x60_CPU2PCI0_MEM_3_REMAP_WIN	3
+#define	MV64x60_CPU2PCI1_MEM_0_REMAP_WIN	4
+#define	MV64x60_CPU2PCI1_MEM_1_REMAP_WIN	5
+#define	MV64x60_CPU2PCI1_MEM_2_REMAP_WIN	6
+#define	MV64x60_CPU2PCI1_MEM_3_REMAP_WIN	7
+#define	MV64x60_PCI02MEM_ACC_CNTL_0_WIN		8
+#define	MV64x60_PCI02MEM_ACC_CNTL_1_WIN		9
+#define	MV64x60_PCI02MEM_ACC_CNTL_2_WIN		10
+#define	MV64x60_PCI02MEM_ACC_CNTL_3_WIN		11
+#define	MV64x60_PCI12MEM_ACC_CNTL_0_WIN		12
+#define	MV64x60_PCI12MEM_ACC_CNTL_1_WIN		13
+#define	MV64x60_PCI12MEM_ACC_CNTL_2_WIN		14
+#define	MV64x60_PCI12MEM_ACC_CNTL_3_WIN		15
+#define	MV64x60_PCI02MEM_SNOOP_0_WIN		16
+#define	MV64x60_PCI02MEM_SNOOP_1_WIN		17
+#define	MV64x60_PCI02MEM_SNOOP_2_WIN		18
+#define	MV64x60_PCI02MEM_SNOOP_3_WIN		19
+#define	MV64x60_PCI12MEM_SNOOP_0_WIN		20
+#define	MV64x60_PCI12MEM_SNOOP_1_WIN		21
+#define	MV64x60_PCI12MEM_SNOOP_2_WIN		22
+#define	MV64x60_PCI12MEM_SNOOP_3_WIN		23
+
+#define	MV64x60_64BIT_WIN_COUNT			24
+
+/*
+ * Define a structure that's used to pass in config information to the
+ * core routines.
+ */
+struct mv64x60_pci_window {
+	u32	cpu_base;
+	u32	pci_base_hi;
+	u32	pci_base_lo;
+	u32	size;
+	u32	swap;
+};
+
+struct mv64x60_pci_info {
+	u8	enable_bus;	/* allow access to this PCI bus? */
+
+	struct mv64x60_pci_window	pci_io;
+	struct mv64x60_pci_window	pci_mem[3];
+
+	u32	acc_cntl_options[MV64x60_CPU2MEM_WINDOWS];
+	u32	snoop_options[MV64x60_CPU2MEM_WINDOWS];
+	u16	pci_cmd_bits;
+	u16	latency_timer;
+};
+
+struct mv64x60_setup_info {
+	u32	phys_reg_base;
+	u32	window_preserve_mask_32_hi;
+	u32	window_preserve_mask_32_lo;
+	u32	window_preserve_mask_64;
+
+	u32	cpu_prot_options[MV64x60_CPU2MEM_WINDOWS];
+	u32	cpu_snoop_options[MV64x60_CPU2MEM_WINDOWS];
+	u32	enet_options[MV64x60_CPU2MEM_WINDOWS];
+	u32	mpsc_options[MV64x60_CPU2MEM_WINDOWS];
+	u32	idma_options[MV64x60_CPU2MEM_WINDOWS];
+
+	struct mv64x60_pci_info	pci_0;
+	struct mv64x60_pci_info	pci_1;
+};
+
+/* Define what the top bits in the extra member of a window entry means. */
+#define	MV64x60_EXTRA_INVALID		0x00000000
+#define	MV64x60_EXTRA_CPUWIN_ENAB	0x10000000
+#define	MV64x60_EXTRA_CPUPROT_ENAB	0x20000000
+#define	MV64x60_EXTRA_ENET_ENAB		0x30000000
+#define	MV64x60_EXTRA_MPSC_ENAB		0x40000000
+#define	MV64x60_EXTRA_IDMA_ENAB		0x50000000
+#define	MV64x60_EXTRA_PCIACC_ENAB	0x60000000
+
+#define	MV64x60_EXTRA_MASK		0xf0000000
+
+/*
+ * Define the 'handle' struct that will be passed between the 64x60 core
+ * code and the platform-specific code that will use it.  The handle
+ * will contain pointers to chip-specific routines & information.
+ */
+struct mv64x60_32bit_window {
+	u32	base_reg;
+	u32	size_reg;
+	u8	base_bits;
+	u8	size_bits;
+	u32	(*get_from_field)(u32 val, u32 num_bits);
+	u32	(*map_to_field)(u32 val, u32 num_bits);
+	u32	extra;
+};
+
+struct mv64x60_64bit_window {
+	u32	base_hi_reg;
+	u32	base_lo_reg;
+	u32	size_reg;
+	u8	base_lo_bits;
+	u8	size_bits;
+	u32	(*get_from_field)(u32 val, u32 num_bits);
+	u32	(*map_to_field)(u32 val, u32 num_bits);
+	u32	extra;
+};
+
+typedef struct mv64x60_handle	mv64x60_handle_t;
+struct mv64x60_chip_info {
+	u32	(*translate_size)(u32 base, u32 size, u32 num_bits);
+	u32	(*untranslate_size)(u32 base, u32 size, u32 num_bits);
+	void	(*set_pci2mem_window)(struct pci_controller *hose, u32 bus,
+			u32 window, u32 base);
+	void 	(*set_pci2regs_window)(struct mv64x60_handle *bh,
+			struct pci_controller *hose, u32 bus, u32 base);
+	u32	(*is_enabled_32bit)(mv64x60_handle_t *bh, u32 window);
+	void	(*enable_window_32bit)(mv64x60_handle_t *bh, u32 window);
+	void	(*disable_window_32bit)(mv64x60_handle_t *bh, u32 window);
+	void	(*enable_window_64bit)(mv64x60_handle_t *bh, u32 window);
+	void	(*disable_window_64bit)(mv64x60_handle_t *bh, u32 window);
+	void	(*disable_all_windows)(mv64x60_handle_t *bh,
+			struct mv64x60_setup_info *si);
+	void	(*config_io2mem_windows)(mv64x60_handle_t *bh,
+			struct mv64x60_setup_info *si,
+			u32 mem_windows[MV64x60_CPU2MEM_WINDOWS][2]);
+	void 	(*set_mpsc2regs_window)(struct mv64x60_handle *bh, u32 base);
+	void	(*chip_specific_init)(mv64x60_handle_t *bh,
+			struct mv64x60_setup_info *si);
+
+	struct mv64x60_32bit_window	*window_tab_32bit;
+	struct mv64x60_64bit_window	*window_tab_64bit;
+};
+
+struct mv64x60_handle {
+	u32		type;		/* type of bridge */
+	u32		rev;		/* revision of bridge */
+	void		*v_base;	/* virtual base addr of bridge regs */
+	phys_addr_t	p_base;		/* physical base addr of bridge regs */
+
+	u32		pci_mode_a;	/* pci 0 mode: conventional pci, pci-x*/
+	u32		pci_mode_b;	/* pci 1 mode: conventional pci, pci-x*/
+
+	u32		io_base_a;	/* vaddr of pci 0's I/O space */
+	u32		io_base_b;	/* vaddr of pci 1's I/O space */
+
+	struct pci_controller	*hose_a;
+	struct pci_controller	*hose_b;
+
+	struct mv64x60_chip_info *ci;	/* chip/bridge-specific info */
+};
+
+
+/* Define I/O routines for accessing registers on the 64x60 bridge. */
+extern inline void
+mv64x60_write(struct mv64x60_handle *bh, u32 offset, u32 val) {
+	ulong	flags;
+
+	spin_lock_irqsave(&mv64x60_lock, flags);
+	out_le32(bh->v_base + offset, val);
+	spin_unlock_irqrestore(&mv64x60_lock, flags);
+}
+
+extern inline u32
+mv64x60_read(struct mv64x60_handle *bh, u32 offset) {
+	ulong	flags;
+	u32     reg;
+
+	spin_lock_irqsave(&mv64x60_lock, flags);
+	reg = in_le32(bh->v_base + offset);
+	spin_unlock_irqrestore(&mv64x60_lock, flags);
+	return reg;
+}
+
+extern inline void
+mv64x60_modify(struct mv64x60_handle *bh, u32 offs, u32 data, u32 mask)
+{
+	u32	reg;
+	ulong	flags;
+
+	spin_lock_irqsave(&mv64x60_lock, flags);
+	reg = in_le32(bh->v_base + offs) & (~mask);
+	reg |= data & mask;
+	out_le32(bh->v_base + offs, reg);
+	spin_unlock_irqrestore(&mv64x60_lock, flags);
+}
+
+#define	mv64x60_set_bits(bh, offs, bits) mv64x60_modify(bh, offs, ~0, bits)
+#define	mv64x60_clr_bits(bh, offs, bits) mv64x60_modify(bh, offs, 0, bits)
+
+
+/* Externally visible function prototypes */
+int mv64x60_init(struct mv64x60_handle *bh, struct mv64x60_setup_info *si);
+u32 mv64x60_get_mem_size(u32 bridge_base, u32 chip_type);
+void mv64x60_early_init(struct mv64x60_handle *bh,
+	struct mv64x60_setup_info *si);
+void mv64x60_alloc_hose(struct mv64x60_handle *bh, u32 cfg_addr,
+	u32 cfg_data, struct pci_controller **hose);
+int mv64x60_get_type(struct mv64x60_handle *bh);
+int mv64x60_setup_for_chip(struct mv64x60_handle *bh);
+void *mv64x60_get_bridge_vbase(void);
+u32 mv64x60_get_bridge_type(void);
+u32 mv64x60_get_bridge_rev(void);
+void mv64x60_get_mem_windows(struct mv64x60_handle *bh,
+	u32 mem_windows[MV64x60_CPU2MEM_WINDOWS][2]);
+void mv64x60_config_cpu2mem_windows(struct mv64x60_handle *bh,
+	struct mv64x60_setup_info *si,
+	u32 mem_windows[MV64x60_CPU2MEM_WINDOWS][2]);
+void mv64x60_config_cpu2pci_windows(struct mv64x60_handle *bh,
+	struct mv64x60_pci_info *pi, u32 bus);
+void mv64x60_config_pci2mem_windows(struct mv64x60_handle *bh,
+	struct pci_controller *hose, struct mv64x60_pci_info *pi, u32 bus,
+	u32 mem_windows[MV64x60_CPU2MEM_WINDOWS][2]);
+void mv64x60_config_resources(struct pci_controller *hose,
+	struct mv64x60_pci_info *pi, u32 io_base);
+void mv64x60_config_pci_params(struct pci_controller *hose,
+	struct mv64x60_pci_info *pi);
+void mv64x60_pd_fixup(struct mv64x60_handle *bh,
+	struct platform_device *pd_devs[], u32 entries);
+void mv64x60_get_32bit_window(struct mv64x60_handle *bh, u32 window,
+	u32 *base, u32 *size);
+void mv64x60_set_32bit_window(struct mv64x60_handle *bh, u32 window, u32 base,
+	u32 size, u32 other_bits);
+void mv64x60_get_64bit_window(struct mv64x60_handle *bh, u32 window,
+	u32 *base_hi, u32 *base_lo, u32 *size);
+void mv64x60_set_64bit_window(struct mv64x60_handle *bh, u32 window,
+	u32 base_hi, u32 base_lo, u32 size, u32 other_bits);
+void mv64x60_set_bus(struct mv64x60_handle *bh, u32 bus, u32 child_bus);
+int mv64x60_pci_exclude_device(u8 bus, u8 devfn);
+
+
+void gt64260_init_irq(void);
+int gt64260_get_irq(struct pt_regs *regs);
+void mv64360_init_irq(void);
+int mv64360_get_irq(struct pt_regs *regs);
+
+u32 mv64x60_mask(u32 val, u32 num_bits);
+u32 mv64x60_shift_left(u32 val, u32 num_bits);
+u32 mv64x60_shift_right(u32 val, u32 num_bits);
+u32 mv64x60_calc_mem_size(struct mv64x60_handle *bh,
+	u32 mem_windows[MV64x60_CPU2MEM_WINDOWS][2]);
+
+void mv64x60_progress_init(u32 base);
+void mv64x60_mpsc_progress(char *s, unsigned short hex);
+
+extern struct mv64x60_32bit_window
+	gt64260_32bit_windows[MV64x60_32BIT_WIN_COUNT];
+extern struct mv64x60_64bit_window
+	gt64260_64bit_windows[MV64x60_64BIT_WIN_COUNT];
+extern struct mv64x60_32bit_window
+	mv64360_32bit_windows[MV64x60_32BIT_WIN_COUNT];
+extern struct mv64x60_64bit_window
+	mv64360_64bit_windows[MV64x60_64BIT_WIN_COUNT];
+
+#endif /* __ASMPPC_MV64x60_H */
diff -Nru a/include/asm-ppc/mv64x60_defs.h b/include/asm-ppc/mv64x60_defs.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-ppc/mv64x60_defs.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,929 @@
+/*
+ * include/asm-ppc/gt64260_defs.h
+ *
+ * Register definitions for the Marvell/Galileo GT64260, MV64360, etc.
+ * host bridges.
+ *
+ * Author: Mark A. Greer <mgreer@mvista.com>
+ *
+ * 2001-2002 (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.
+ */
+#ifndef __ASMPPC_MV64x60_DEFS_H
+#define __ASMPPC_MV64x60_DEFS_H
+
+/*
+ * Define the Marvell bridges that are supported
+ */
+#define	MV64x60_TYPE_INVALID			0
+#define	MV64x60_TYPE_GT64260A			1
+#define	MV64x60_TYPE_GT64260B			2
+#define	MV64x60_TYPE_MV64360			3
+#define	MV64x60_TYPE_MV64361			4
+#define	MV64x60_TYPE_MV64362			5
+#define	MV64x60_TYPE_MV64460			6
+
+
+/* Revisions of each supported chip */
+#define	GT64260_REV_A				0x10
+#define	GT64260_REV_B				0x20
+#define	MV64360					0x01
+#define	MV64460					0x01
+
+/* Minimum window size supported by 64260 is 1MB */
+#define GT64260_WINDOW_SIZE_MIN			0x00100000
+#define MV64360_WINDOW_SIZE_MIN			0x00010000
+
+/* IRQ's for embedded controllers */
+#define	MV64x60_IRQ_DEV				1
+#define	MV64x60_IRQ_CPU_ERR			3
+#define	MV64x60_IRQ_TIMER_0_1			8
+#define	MV64x60_IRQ_TIMER_2_3			9
+#define	MV64x60_IRQ_TIMER_4_5			10
+#define	MV64x60_IRQ_TIMER_6_7			11
+#define	MV64x60_IRQ_ETH_0			32
+#define	MV64x60_IRQ_ETH_1			33
+#define	MV64x60_IRQ_ETH_2			34
+#define	MV64x60_IRQ_SDMA_0			36
+#define	MV64x60_IRQ_I2C				37
+#define	MV64x60_IRQ_BRG				39
+#define	MV64x60_IRQ_MPSC_0			40
+#define	MV64x60_IRQ_MPSC_1			42
+#define	MV64x60_IRQ_COMM			43
+
+#define	MV64360_IRQ_PCI0			12
+#define	MV64360_IRQ_SRAM_PAR_ERR		13
+#define	MV64360_IRQ_PCI1			16
+#define	MV64360_IRQ_SDMA_1			38
+
+/* Offsets for register blocks */
+#define	GT64260_ENET_PHY_ADDR			0x2000
+#define	GT64260_ENET_ESMIR			0x2010
+#define GT64260_ENET_0_OFFSET			0x2400
+#define GT64260_ENET_1_OFFSET			0x2800
+#define GT64260_ENET_2_OFFSET			0x2c00
+#define	MV64x60_SDMA_0_OFFSET			0x4000
+#define	MV64x60_SDMA_1_OFFSET			0x6000
+#define	MV64x60_MPSC_0_OFFSET			0x8000
+#define	MV64x60_MPSC_1_OFFSET			0x9000
+#define	MV64x60_MPSC_ROUTING_OFFSET		0xb400
+#define	MV64x60_SDMA_INTR_OFFSET		0xb800
+#define	MV64x60_BRG_0_OFFSET			0xb200
+#define	MV64x60_BRG_1_OFFSET			0xb208
+
+/*
+ *****************************************************************************
+ *
+ *	CPU Interface Registers
+ *
+ *****************************************************************************
+ */
+
+/* CPU physical address of bridge's registers */
+#define MV64x60_INTERNAL_SPACE_DECODE		0x0068
+#define MV64x60_INTERNAL_SPACE_SIZE		0x10000
+#define MV64x60_INTERNAL_SPACE_DEFAULT_ADDR	0x14000000
+
+#define	MV64360_CPU_BAR_ENABLE			0x0278
+
+/* CPU Memory Controller Window Registers (4 windows) */
+#define	MV64x60_CPU2MEM_WINDOWS			4
+
+#define	MV64x60_CPU2MEM_0_BASE			0x0008
+#define	MV64x60_CPU2MEM_0_SIZE			0x0010
+#define	MV64x60_CPU2MEM_1_BASE			0x0208
+#define	MV64x60_CPU2MEM_1_SIZE			0x0210
+#define	MV64x60_CPU2MEM_2_BASE			0x0018
+#define	MV64x60_CPU2MEM_2_SIZE			0x0020
+#define	MV64x60_CPU2MEM_3_BASE			0x0218
+#define	MV64x60_CPU2MEM_3_SIZE			0x0220
+
+/* CPU Device Controller Window Registers (4 windows) */
+#define	MV64x60_CPU2DEV_WINDOWS			4
+
+#define	MV64x60_CPU2DEV_0_BASE			0x0028
+#define	MV64x60_CPU2DEV_0_SIZE			0x0030
+#define	MV64x60_CPU2DEV_1_BASE			0x0228
+#define	MV64x60_CPU2DEV_1_SIZE			0x0230
+#define	MV64x60_CPU2DEV_2_BASE			0x0248
+#define	MV64x60_CPU2DEV_2_SIZE			0x0250
+#define	MV64x60_CPU2DEV_3_BASE			0x0038
+#define	MV64x60_CPU2DEV_3_SIZE			0x0040
+
+#define	MV64x60_CPU2BOOT_0_BASE			0x0238
+#define	MV64x60_CPU2BOOT_0_SIZE			0x0240
+
+#define	MV64360_CPU2SRAM_BASE			0x0268
+
+/* CPU Windows to PCI space (2 PCI buses each w/ 1 I/O & 4 MEM windows) */
+#define	MV64x60_PCI_BUSES			2
+#define	MV64x60_PCI_IO_WINDOWS_PER_BUS		1
+#define	MV64x60_PCI_MEM_WINDOWS_PER_BUS		4
+
+#define	MV64x60_CPU2PCI_SWAP_BYTE		0x00000000
+#define	MV64x60_CPU2PCI_SWAP_NONE		0x01000000
+#define	MV64x60_CPU2PCI_SWAP_BYTE_WORD		0x02000000
+#define	MV64x60_CPU2PCI_SWAP_WORD		0x03000000
+
+#define	MV64x60_CPU2PCI_MEM_REQ64		(1<<27)
+
+#define	MV64x60_CPU2PCI0_IO_BASE		0x0048
+#define	MV64x60_CPU2PCI0_IO_SIZE		0x0050
+#define	MV64x60_CPU2PCI0_MEM_0_BASE		0x0058
+#define	MV64x60_CPU2PCI0_MEM_0_SIZE		0x0060
+#define	MV64x60_CPU2PCI0_MEM_1_BASE		0x0080
+#define	MV64x60_CPU2PCI0_MEM_1_SIZE		0x0088
+#define	MV64x60_CPU2PCI0_MEM_2_BASE		0x0258
+#define	MV64x60_CPU2PCI0_MEM_2_SIZE		0x0260
+#define	MV64x60_CPU2PCI0_MEM_3_BASE		0x0280
+#define	MV64x60_CPU2PCI0_MEM_3_SIZE		0x0288
+
+#define	MV64x60_CPU2PCI0_IO_REMAP		0x00f0
+#define	MV64x60_CPU2PCI0_MEM_0_REMAP_LO		0x00f8
+#define	MV64x60_CPU2PCI0_MEM_0_REMAP_HI		0x0320
+#define	MV64x60_CPU2PCI0_MEM_1_REMAP_LO		0x0100
+#define	MV64x60_CPU2PCI0_MEM_1_REMAP_HI		0x0328
+#define	MV64x60_CPU2PCI0_MEM_2_REMAP_LO		0x02f8
+#define	MV64x60_CPU2PCI0_MEM_2_REMAP_HI		0x0330
+#define	MV64x60_CPU2PCI0_MEM_3_REMAP_LO		0x0300
+#define	MV64x60_CPU2PCI0_MEM_3_REMAP_HI		0x0338
+
+#define	MV64x60_CPU2PCI1_IO_BASE		0x0090
+#define	MV64x60_CPU2PCI1_IO_SIZE		0x0098
+#define	MV64x60_CPU2PCI1_MEM_0_BASE		0x00a0
+#define	MV64x60_CPU2PCI1_MEM_0_SIZE		0x00a8
+#define	MV64x60_CPU2PCI1_MEM_1_BASE		0x00b0
+#define	MV64x60_CPU2PCI1_MEM_1_SIZE		0x00b8
+#define	MV64x60_CPU2PCI1_MEM_2_BASE		0x02a0
+#define	MV64x60_CPU2PCI1_MEM_2_SIZE		0x02a8
+#define	MV64x60_CPU2PCI1_MEM_3_BASE		0x02b0
+#define	MV64x60_CPU2PCI1_MEM_3_SIZE		0x02b8
+
+#define	MV64x60_CPU2PCI1_IO_REMAP		0x0108
+#define	MV64x60_CPU2PCI1_MEM_0_REMAP_LO		0x0110
+#define	MV64x60_CPU2PCI1_MEM_0_REMAP_HI		0x0340
+#define	MV64x60_CPU2PCI1_MEM_1_REMAP_LO		0x0118
+#define	MV64x60_CPU2PCI1_MEM_1_REMAP_HI		0x0348
+#define	MV64x60_CPU2PCI1_MEM_2_REMAP_LO		0x0310
+#define	MV64x60_CPU2PCI1_MEM_2_REMAP_HI		0x0350
+#define	MV64x60_CPU2PCI1_MEM_3_REMAP_LO		0x0318
+#define	MV64x60_CPU2PCI1_MEM_3_REMAP_HI		0x0358
+
+/* CPU Control Registers */
+#define MV64x60_CPU_CONFIG			0x0000
+#define MV64x60_CPU_MODE			0x0120
+#define MV64x60_CPU_MASTER_CNTL			0x0160
+#define MV64x60_CPU_XBAR_CNTL_LO		0x0150
+#define MV64x60_CPU_XBAR_CNTL_HI		0x0158
+#define MV64x60_CPU_XBAR_TO			0x0168
+
+#define GT64260_CPU_RR_XBAR_CNTL_LO		0x0170
+#define GT64260_CPU_RR_XBAR_CNTL_HI		0x0178
+
+#define MV64360_CPU_PADS_CALIBRATION		0x03b4
+#define MV64360_CPU_RESET_SAMPLE_LO		0x03c4
+#define MV64360_CPU_RESET_SAMPLE_HI		0x03d4
+
+/* SMP Register Map */
+#define MV64360_WHO_AM_I			0x0200
+#define MV64360_CPU0_DOORBELL			0x0214
+#define MV64360_CPU0_DOORBELL_CLR		0x021c
+#define MV64360_CPU0_DOORBELL_MASK		0x0234
+#define MV64360_CPU1_DOORBELL			0x0224
+#define MV64360_CPU1_DOORBELL_CLR		0x022c
+#define MV64360_CPU1_DOORBELL_MASK		0x023c
+#define MV64360_CPUx_DOORBELL(x)		(0x0214 + ((x)*0x10))
+#define MV64360_CPUx_DOORBELL_CLR(x)		(0x021c + ((x)*0x10))
+#define MV64360_CPUx_DOORBELL_MASK(x)		(0x0234 + ((x)*0x08))
+#define MV64360_SEMAPHORE_0			0x0244
+#define MV64360_SEMAPHORE_1			0x024c
+#define MV64360_SEMAPHORE_2			0x0254
+#define MV64360_SEMAPHORE_3			0x025c
+#define MV64360_SEMAPHORE_4			0x0264
+#define MV64360_SEMAPHORE_5			0x026c
+#define MV64360_SEMAPHORE_6			0x0274
+#define MV64360_SEMAPHORE_7			0x027c
+
+/* CPU Sync Barrier Registers */
+#define GT64260_CPU_SYNC_BARRIER_PCI0		0x00c0
+#define GT64260_CPU_SYNC_BARRIER_PCI1		0x00c8
+
+#define MV64360_CPU0_SYNC_BARRIER_TRIG		0x00c0
+#define MV64360_CPU0_SYNC_BARRIER_VIRT		0x00c8
+#define MV64360_CPU1_SYNC_BARRIER_TRIG		0x00d0
+#define MV64360_CPU1_SYNC_BARRIER_VIRT		0x00d8
+
+/* CPU Deadlock and Ordering registers (Rev B part only) */
+#define GT64260_CPU_DEADLOCK_ORDERING			0x02d0
+#define GT64260_CPU_WB_PRIORITY_BUFFER_DEPTH		0x02d8
+#define GT64260_CPU_COUNTERS_SYNC_BARRIER_ATTRIBUTE	0x02e0
+
+/* CPU Access Protection Registers (gt64260 realy has 8 but don't need) */
+#define	MV64x260_CPU_PROT_WINDOWS		4
+
+#define	GT64260_CPU_PROT_ACCPROTECT		(1<<16)
+#define	GT64260_CPU_PROT_WRPROTECT		(1<<17)
+#define	GT64260_CPU_PROT_CACHEPROTECT		(1<<18)
+
+#define	MV64360_CPU_PROT_ACCPROTECT		(1<<20)
+#define	MV64360_CPU_PROT_WRPROTECT		(1<<21)
+#define	MV64360_CPU_PROT_CACHEPROTECT		(1<<22)
+#define	MV64360_CPU_PROT_WIN_ENABLE		(1<<31)
+
+#define MV64x60_CPU_PROT_BASE_0			0x0180
+#define MV64x60_CPU_PROT_SIZE_0			0x0188
+#define MV64x60_CPU_PROT_BASE_1			0x0190
+#define MV64x60_CPU_PROT_SIZE_1			0x0198
+#define MV64x60_CPU_PROT_BASE_2			0x01a0
+#define MV64x60_CPU_PROT_SIZE_2			0x01a8
+#define MV64x60_CPU_PROT_BASE_3			0x01b0
+#define MV64x60_CPU_PROT_SIZE_3			0x01b8
+
+#define GT64260_CPU_PROT_BASE_4			0x01c0
+#define GT64260_CPU_PROT_SIZE_4			0x01c8
+#define GT64260_CPU_PROT_BASE_5			0x01d0
+#define GT64260_CPU_PROT_SIZE_5			0x01d8
+#define GT64260_CPU_PROT_BASE_6			0x01e0
+#define GT64260_CPU_PROT_SIZE_6			0x01e8
+#define GT64260_CPU_PROT_BASE_7			0x01f0
+#define GT64260_CPU_PROT_SIZE_7			0x01f8
+
+/* CPU Snoop Control Registers (64260 only) */
+#define	GT64260_CPU_SNOOP_WINDOWS		4
+
+#define	GT64260_CPU_SNOOP_NONE			0x00000000
+#define	GT64260_CPU_SNOOP_WT			0x00010000
+#define	GT64260_CPU_SNOOP_WB			0x00020000
+#define	GT64260_CPU_SNOOP_MASK			0x00030000
+#define	GT64260_CPU_SNOOP_ALL_BITS		GT64260_CPU_SNOOP_MASK
+
+#define GT64260_CPU_SNOOP_BASE_0		0x0380
+#define GT64260_CPU_SNOOP_SIZE_0		0x0388
+#define GT64260_CPU_SNOOP_BASE_1		0x0390
+#define GT64260_CPU_SNOOP_SIZE_1		0x0398
+#define GT64260_CPU_SNOOP_BASE_2		0x03a0
+#define GT64260_CPU_SNOOP_SIZE_2		0x03a8
+#define GT64260_CPU_SNOOP_BASE_3		0x03b0
+#define GT64260_CPU_SNOOP_SIZE_3		0x03b8
+
+/* CPU Snoop Control Registers (64360 only) */
+#define	MV64360_CPU_SNOOP_WINDOWS		4
+#define	MV64360_CPU_SNOOP_NONE			0x00000000
+#define	MV64360_CPU_SNOOP_WT			0x00010000
+#define	MV64360_CPU_SNOOP_WB			0x00020000
+#define	MV64360_CPU_SNOOP_MASK			0x00030000
+#define	MV64360_CPU_SNOOP_ALL_BITS		MV64360_CPU_SNOOP_MASK
+
+
+/* CPU Error Report Registers */
+#define MV64x60_CPU_ERR_ADDR_LO			0x0070
+#define MV64x60_CPU_ERR_ADDR_HI			0x0078
+#define MV64x60_CPU_ERR_DATA_LO			0x0128
+#define MV64x60_CPU_ERR_DATA_HI			0x0130
+#define MV64x60_CPU_ERR_PARITY			0x0138
+#define MV64x60_CPU_ERR_CAUSE			0x0140
+#define MV64x60_CPU_ERR_MASK			0x0148
+
+/*
+ *****************************************************************************
+ *
+ *	SRAM Cotnroller Registers
+ *
+ *****************************************************************************
+ */
+
+#define	MV64360_SRAM_CONFIG			0x0380
+#define	MV64360_SRAM_TEST_MODE			0x03f4
+#define	MV64360_SRAM_ERR_CAUSE			0x0388
+#define	MV64360_SRAM_ERR_ADDR_LO		0x0390
+#define	MV64360_SRAM_ERR_ADDR_HI		0x03f8
+#define	MV64360_SRAM_ERR_DATA_LO		0x0398
+#define	MV64360_SRAM_ERR_DATA_HI		0x03a0
+#define	MV64360_SRAM_ERR_PARITY			0x03a8
+
+#define	MV64360_SRAM_SIZE			0x00040000 /* 256 KB of SRAM */
+
+/*
+ *****************************************************************************
+ *
+ *	SDRAM/MEM Cotnroller Registers
+ *
+ *****************************************************************************
+ */
+
+/* SDRAM Config Registers (64260) */
+#define	GT64260_SDRAM_CONFIG			0x0448
+
+/* SDRAM Error Report Registers (64260) */
+#define	GT64260_SDRAM_ERR_DATA_LO		0x0484
+#define	GT64260_SDRAM_ERR_DATA_HI		0x0480
+#define	GT64260_SDRAM_ERR_ADDR			0x0490
+#define	GT64260_SDRAM_ERR_ECC_RCVD		0x0488
+#define	GT64260_SDRAM_ERR_ECC_CALC		0x048c
+#define	GT64260_SDRAM_ERR_ECC_CNTL		0x0494
+#define	GT64260_SDRAM_ERR_ECC_ERR_CNT		0x0498
+
+/* SDRAM Config Registers (64360) */
+#define	MV64360_SDRAM_CONFIG			0x1400
+
+/* SDRAM Control Registers */
+#define MV64360_D_UNIT_CONTROL_LOW		0x1404
+#define MV64360_D_UNIT_CONTROL_HIGH		0x1424
+
+/* SDRAM Error Report Registers (64360) */
+#define	MV64360_SDRAM_ERR_DATA_LO		0x1444
+#define	MV64360_SDRAM_ERR_DATA_HI		0x1440
+#define	MV64360_SDRAM_ERR_ADDR			0x1450
+#define	MV64360_SDRAM_ERR_ECC_RCVD		0x1448
+#define	MV64360_SDRAM_ERR_ECC_CALC		0x144c
+#define	MV64360_SDRAM_ERR_ECC_CNTL		0x1454
+#define	MV64360_SDRAM_ERR_ECC_ERR_CNT		0x1458
+
+/*
+ *****************************************************************************
+ *
+ *	Device/BOOT Cotnroller Registers
+ *
+ *****************************************************************************
+ */
+
+/* Device Control Registers */
+#define	MV64x60_DEV_BANK_PARAMS_0		0x045c
+#define	MV64x60_DEV_BANK_PARAMS_1		0x0460
+#define	MV64x60_DEV_BANK_PARAMS_2		0x0464
+#define	MV64x60_DEV_BANK_PARAMS_3		0x0468
+#define	MV64x60_DEV_BOOT_PARAMS			0x046c
+#define	MV64x60_DEV_IF_CNTL			0x04c0
+#define	MV64x60_DEV_IF_XBAR_CNTL_LO		0x04c8
+#define	MV64x60_DEV_IF_XBAR_CNTL_HI		0x04cc
+#define	MV64x60_DEV_IF_XBAR_CNTL_TO		0x04c4
+
+/* Device Interrupt Registers */
+#define	MV64x60_DEV_INTR_CAUSE			0x04d0
+#define	MV64x60_DEV_INTR_MASK			0x04d4
+#define	MV64x60_DEV_INTR_ERR_ADDR		0x04d8
+
+#define	MV64360_DEV_INTR_ERR_DATA		0x04dc
+#define	MV64360_DEV_INTR_ERR_PAR		0x04e0
+
+/*
+ *****************************************************************************
+ *
+ *	PCI Bridge Interface Registers
+ *
+ *****************************************************************************
+ */
+
+/* PCI Configuration Access Registers */
+#define	MV64x60_PCI0_CONFIG_ADDR		0x0cf8
+#define	MV64x60_PCI0_CONFIG_DATA		0x0cfc
+#define	MV64x60_PCI0_IACK			0x0c34
+
+#define	MV64x60_PCI1_CONFIG_ADDR		0x0c78
+#define	MV64x60_PCI1_CONFIG_DATA		0x0c7c
+#define	MV64x60_PCI1_IACK			0x0cb4
+
+/* PCI Control Registers */
+#define	MV64x60_PCI0_CMD			0x0c00
+#define	MV64x60_PCI0_MODE			0x0d00
+#define	MV64x60_PCI0_TO_RETRY			0x0c04
+#define	MV64x60_PCI0_RD_BUF_DISCARD_TIMER	0x0d04
+#define	MV64x60_PCI0_MSI_TRIGGER_TIMER		0x0c38
+#define	MV64x60_PCI0_ARBITER_CNTL		0x1d00
+#define	MV64x60_PCI0_XBAR_CNTL_LO		0x1d08
+#define	MV64x60_PCI0_XBAR_CNTL_HI		0x1d0c
+#define	MV64x60_PCI0_XBAR_CNTL_TO		0x1d04
+#define	MV64x60_PCI0_RD_RESP_XBAR_CNTL_LO	0x1d18
+#define	MV64x60_PCI0_RD_RESP_XBAR_CNTL_HI	0x1d1c
+#define	MV64x60_PCI0_SYNC_BARRIER		0x1d10
+#define	MV64x60_PCI0_P2P_CONFIG			0x1d14
+#define	MV64x60_PCI0_INTR_MASK
+
+#define	GT64260_PCI0_P2P_SWAP_CNTL		0x1d54
+
+#define	MV64x60_PCI1_CMD			0x0c80
+#define	MV64x60_PCI1_MODE			0x0d80
+#define	MV64x60_PCI1_TO_RETRY			0x0c84
+#define	MV64x60_PCI1_RD_BUF_DISCARD_TIMER	0x0d84
+#define	MV64x60_PCI1_MSI_TRIGGER_TIMER		0x0cb8
+#define	MV64x60_PCI1_ARBITER_CNTL		0x1d80
+#define	MV64x60_PCI1_XBAR_CNTL_LO		0x1d88
+#define	MV64x60_PCI1_XBAR_CNTL_HI		0x1d8c
+#define	MV64x60_PCI1_XBAR_CNTL_TO		0x1d84
+#define	MV64x60_PCI1_RD_RESP_XBAR_CNTL_LO	0x1d98
+#define	MV64x60_PCI1_RD_RESP_XBAR_CNTL_HI	0x1d9c
+#define	MV64x60_PCI1_SYNC_BARRIER		0x1d90
+#define	MV64x60_PCI1_P2P_CONFIG			0x1d94
+
+#define	GT64260_PCI1_P2P_SWAP_CNTL		0x1dd4
+
+/* Different modes that the pci hoses can be in (bits 5:4 in PCI Mode reg) */
+#define	MV64x60_PCIMODE_CONVENTIONAL		0
+#define	MV64x60_PCIMODE_PCIX_66			(1 << 4)
+#define	MV64x60_PCIMODE_PCIX_100		(2 << 4)
+#define	MV64x60_PCIMODE_PCIX_133		(3 << 4)
+#define	MV64x60_PCIMODE_MASK			(0x3 << 4)
+
+/* PCI Access Control Regions Registers */
+#define	GT64260_PCI_ACC_CNTL_PREFETCHEN		(1<<12)
+#define	GT64260_PCI_ACC_CNTL_DREADEN		(1<<13)
+#define	GT64260_PCI_ACC_CNTL_RDPREFETCH		(1<<16)
+#define	GT64260_PCI_ACC_CNTL_RDLINEPREFETCH	(1<<17)
+#define	GT64260_PCI_ACC_CNTL_RDMULPREFETCH	(1<<18)
+#define	GT64260_PCI_ACC_CNTL_MBURST_32_BTYES	0x00000000
+#define	GT64260_PCI_ACC_CNTL_MBURST_64_BYTES	0x00100000
+#define	GT64260_PCI_ACC_CNTL_MBURST_128_BYTES	0x00200000
+#define	GT64260_PCI_ACC_CNTL_MBURST_MASK	0x00300000
+#define	GT64260_PCI_ACC_CNTL_SWAP_BYTE		0x00000000
+#define	GT64260_PCI_ACC_CNTL_SWAP_NONE		0x01000000
+#define	GT64260_PCI_ACC_CNTL_SWAP_BYTE_WORD	0x02000000
+#define	GT64260_PCI_ACC_CNTL_SWAP_WORD		0x03000000
+#define	GT64260_PCI_ACC_CNTL_SWAP_MASK		0x03000000
+#define	GT64260_PCI_ACC_CNTL_ACCPROT		(1<<28)
+#define	GT64260_PCI_ACC_CNTL_WRPROT		(1<<29)
+
+#define	GT64260_PCI_ACC_CNTL_ALL_BITS	(GT64260_PCI_ACC_CNTL_PREFETCHEN |    \
+					 GT64260_PCI_ACC_CNTL_DREADEN |       \
+					 GT64260_PCI_ACC_CNTL_RDPREFETCH |    \
+					 GT64260_PCI_ACC_CNTL_RDLINEPREFETCH |\
+					 GT64260_PCI_ACC_CNTL_RDMULPREFETCH | \
+					 GT64260_PCI_ACC_CNTL_MBURST_MASK |   \
+					 GT64260_PCI_ACC_CNTL_SWAP_MASK |     \
+					 GT64260_PCI_ACC_CNTL_ACCPROT|        \
+					 GT64260_PCI_ACC_CNTL_WRPROT)
+
+#define	MV64360_PCI_ACC_CNTL_ENABLE		(1<<0)
+#define	MV64360_PCI_ACC_CNTL_REQ64		(1<<1)
+#define	MV64360_PCI_ACC_CNTL_SNOOP_NONE		0x00000000
+#define	MV64360_PCI_ACC_CNTL_SNOOP_WT		0x00000004
+#define	MV64360_PCI_ACC_CNTL_SNOOP_WB		0x00000008
+#define	MV64360_PCI_ACC_CNTL_SNOOP_MASK		0x0000000c
+#define	MV64360_PCI_ACC_CNTL_ACCPROT		(1<<4)
+#define	MV64360_PCI_ACC_CNTL_WRPROT		(1<<5)
+#define	MV64360_PCI_ACC_CNTL_SWAP_BYTE		0x00000000
+#define	MV64360_PCI_ACC_CNTL_SWAP_NONE		0x00000040
+#define	MV64360_PCI_ACC_CNTL_SWAP_BYTE_WORD	0x00000080
+#define	MV64360_PCI_ACC_CNTL_SWAP_WORD		0x000000c0
+#define	MV64360_PCI_ACC_CNTL_SWAP_MASK		0x000000c0
+#define	MV64360_PCI_ACC_CNTL_MBURST_32_BYTES	0x00000000
+#define	MV64360_PCI_ACC_CNTL_MBURST_64_BYTES	0x00000100
+#define	MV64360_PCI_ACC_CNTL_MBURST_128_BYTES	0x00000200
+#define	MV64360_PCI_ACC_CNTL_MBURST_MASK	0x00000300
+#define	MV64360_PCI_ACC_CNTL_RDSIZE_32_BYTES	0x00000000
+#define	MV64360_PCI_ACC_CNTL_RDSIZE_64_BYTES	0x00000400
+#define	MV64360_PCI_ACC_CNTL_RDSIZE_128_BYTES	0x00000800
+#define	MV64360_PCI_ACC_CNTL_RDSIZE_256_BYTES	0x00000c00
+#define	MV64360_PCI_ACC_CNTL_RDSIZE_MASK	0x00000c00
+
+#define	MV64360_PCI_ACC_CNTL_ALL_BITS	(MV64360_PCI_ACC_CNTL_ENABLE |	    \
+					 MV64360_PCI_ACC_CNTL_REQ64 |	    \
+					 MV64360_PCI_ACC_CNTL_SNOOP_MASK |  \
+					 MV64360_PCI_ACC_CNTL_ACCPROT |	    \
+					 MV64360_PCI_ACC_CNTL_WRPROT |	    \
+					 MV64360_PCI_ACC_CNTL_SWAP_MASK |   \
+					 MV64360_PCI_ACC_CNTL_MBURST_MASK | \
+					 MV64360_PCI_ACC_CNTL_RDSIZE_MASK)
+
+#define	MV64x60_PCI0_ACC_CNTL_0_BASE_LO		0x1e00
+#define	MV64x60_PCI0_ACC_CNTL_0_BASE_HI		0x1e04
+#define	MV64x60_PCI0_ACC_CNTL_0_SIZE		0x1e08
+#define	MV64x60_PCI0_ACC_CNTL_1_BASE_LO		0x1e10
+#define	MV64x60_PCI0_ACC_CNTL_1_BASE_HI		0x1e14
+#define	MV64x60_PCI0_ACC_CNTL_1_SIZE		0x1e18
+#define	MV64x60_PCI0_ACC_CNTL_2_BASE_LO		0x1e20
+#define	MV64x60_PCI0_ACC_CNTL_2_BASE_HI		0x1e24
+#define	MV64x60_PCI0_ACC_CNTL_2_SIZE		0x1e28
+#define	MV64x60_PCI0_ACC_CNTL_3_BASE_LO		0x1e30
+#define	MV64x60_PCI0_ACC_CNTL_3_BASE_HI		0x1e34
+#define	MV64x60_PCI0_ACC_CNTL_3_SIZE		0x1e38
+#define	MV64x60_PCI0_ACC_CNTL_4_BASE_LO		0x1e40
+#define	MV64x60_PCI0_ACC_CNTL_4_BASE_HI		0x1e44
+#define	MV64x60_PCI0_ACC_CNTL_4_SIZE		0x1e48
+#define	MV64x60_PCI0_ACC_CNTL_5_BASE_LO		0x1e50
+#define	MV64x60_PCI0_ACC_CNTL_5_BASE_HI		0x1e54
+#define	MV64x60_PCI0_ACC_CNTL_5_SIZE		0x1e58
+
+#define	GT64260_PCI0_ACC_CNTL_6_BASE_LO		0x1e60
+#define	GT64260_PCI0_ACC_CNTL_6_BASE_HI		0x1e64
+#define	GT64260_PCI0_ACC_CNTL_6_SIZE		0x1e68
+#define	GT64260_PCI0_ACC_CNTL_7_BASE_LO		0x1e70
+#define	GT64260_PCI0_ACC_CNTL_7_BASE_HI		0x1e74
+#define	GT64260_PCI0_ACC_CNTL_7_SIZE		0x1e78
+
+#define	MV64x60_PCI1_ACC_CNTL_0_BASE_LO		0x1e80
+#define	MV64x60_PCI1_ACC_CNTL_0_BASE_HI		0x1e84
+#define	MV64x60_PCI1_ACC_CNTL_0_SIZE		0x1e88
+#define	MV64x60_PCI1_ACC_CNTL_1_BASE_LO		0x1e90
+#define	MV64x60_PCI1_ACC_CNTL_1_BASE_HI		0x1e94
+#define	MV64x60_PCI1_ACC_CNTL_1_SIZE		0x1e98
+#define	MV64x60_PCI1_ACC_CNTL_2_BASE_LO		0x1ea0
+#define	MV64x60_PCI1_ACC_CNTL_2_BASE_HI		0x1ea4
+#define	MV64x60_PCI1_ACC_CNTL_2_SIZE		0x1ea8
+#define	MV64x60_PCI1_ACC_CNTL_3_BASE_LO		0x1eb0
+#define	MV64x60_PCI1_ACC_CNTL_3_BASE_HI		0x1eb4
+#define	MV64x60_PCI1_ACC_CNTL_3_SIZE		0x1eb8
+#define	MV64x60_PCI1_ACC_CNTL_4_BASE_LO		0x1ec0
+#define	MV64x60_PCI1_ACC_CNTL_4_BASE_HI		0x1ec4
+#define	MV64x60_PCI1_ACC_CNTL_4_SIZE		0x1ec8
+#define	MV64x60_PCI1_ACC_CNTL_5_BASE_LO		0x1ed0
+#define	MV64x60_PCI1_ACC_CNTL_5_BASE_HI		0x1ed4
+#define	MV64x60_PCI1_ACC_CNTL_5_SIZE		0x1ed8
+
+#define	GT64260_PCI1_ACC_CNTL_6_BASE_LO		0x1ee0
+#define	GT64260_PCI1_ACC_CNTL_6_BASE_HI		0x1ee4
+#define	GT64260_PCI1_ACC_CNTL_6_SIZE		0x1ee8
+#define	GT64260_PCI1_ACC_CNTL_7_BASE_LO		0x1ef0
+#define	GT64260_PCI1_ACC_CNTL_7_BASE_HI		0x1ef4
+#define	GT64260_PCI1_ACC_CNTL_7_SIZE		0x1ef8
+
+/* PCI Snoop Control Registers (64260 only) */
+#define	GT64260_PCI_SNOOP_NONE			0x00000000
+#define	GT64260_PCI_SNOOP_WT			0x00001000
+#define	GT64260_PCI_SNOOP_WB			0x00002000
+
+#define	GT64260_PCI0_SNOOP_0_BASE_LO		0x1f00
+#define	GT64260_PCI0_SNOOP_0_BASE_HI		0x1f04
+#define	GT64260_PCI0_SNOOP_0_SIZE		0x1f08
+#define	GT64260_PCI0_SNOOP_1_BASE_LO		0x1f10
+#define	GT64260_PCI0_SNOOP_1_BASE_HI		0x1f14
+#define	GT64260_PCI0_SNOOP_1_SIZE		0x1f18
+#define	GT64260_PCI0_SNOOP_2_BASE_LO		0x1f20
+#define	GT64260_PCI0_SNOOP_2_BASE_HI		0x1f24
+#define	GT64260_PCI0_SNOOP_2_SIZE		0x1f28
+#define	GT64260_PCI0_SNOOP_3_BASE_LO		0x1f30
+#define	GT64260_PCI0_SNOOP_3_BASE_HI		0x1f34
+#define	GT64260_PCI0_SNOOP_3_SIZE		0x1f38
+
+#define	GT64260_PCI1_SNOOP_0_BASE_LO		0x1f80
+#define	GT64260_PCI1_SNOOP_0_BASE_HI		0x1f84
+#define	GT64260_PCI1_SNOOP_0_SIZE		0x1f88
+#define	GT64260_PCI1_SNOOP_1_BASE_LO		0x1f90
+#define	GT64260_PCI1_SNOOP_1_BASE_HI		0x1f94
+#define	GT64260_PCI1_SNOOP_1_SIZE		0x1f98
+#define	GT64260_PCI1_SNOOP_2_BASE_LO		0x1fa0
+#define	GT64260_PCI1_SNOOP_2_BASE_HI		0x1fa4
+#define	GT64260_PCI1_SNOOP_2_SIZE		0x1fa8
+#define	GT64260_PCI1_SNOOP_3_BASE_LO		0x1fb0
+#define	GT64260_PCI1_SNOOP_3_BASE_HI		0x1fb4
+#define	GT64260_PCI1_SNOOP_3_SIZE		0x1fb8
+
+/* PCI Error Report Registers */
+#define MV64x60_PCI0_ERR_SERR_MASK		0x0c28
+#define MV64x60_PCI0_ERR_ADDR_LO		0x1d40
+#define MV64x60_PCI0_ERR_ADDR_HI		0x1d44
+#define MV64x60_PCI0_ERR_DATA_LO		0x1d48
+#define MV64x60_PCI0_ERR_DATA_HI		0x1d4c
+#define MV64x60_PCI0_ERR_CMD			0x1d50
+#define MV64x60_PCI0_ERR_CAUSE			0x1d58
+#define MV64x60_PCI0_ERR_MASK			0x1d5c
+
+#define MV64x60_PCI1_ERR_SERR_MASK		0x0ca8
+#define MV64x60_PCI1_ERR_ADDR_LO		0x1dc0
+#define MV64x60_PCI1_ERR_ADDR_HI		0x1dc4
+#define MV64x60_PCI1_ERR_DATA_LO		0x1dc8
+#define MV64x60_PCI1_ERR_DATA_HI		0x1dcc
+#define MV64x60_PCI1_ERR_CMD			0x1dd0
+#define MV64x60_PCI1_ERR_CAUSE			0x1dd8
+#define MV64x60_PCI1_ERR_MASK			0x1ddc
+
+/* PCI Slave Address Decoding Registers */
+#define	MV64x60_PCI0_MEM_0_SIZE			0x0c08
+#define	MV64x60_PCI0_MEM_1_SIZE			0x0d08
+#define	MV64x60_PCI0_MEM_2_SIZE			0x0c0c
+#define	MV64x60_PCI0_MEM_3_SIZE			0x0d0c
+#define	MV64x60_PCI1_MEM_0_SIZE			0x0c88
+#define	MV64x60_PCI1_MEM_1_SIZE			0x0d88
+#define	MV64x60_PCI1_MEM_2_SIZE			0x0c8c
+#define	MV64x60_PCI1_MEM_3_SIZE			0x0d8c
+
+#define	MV64x60_PCI0_BAR_ENABLE			0x0c3c
+#define	MV64x60_PCI1_BAR_ENABLE			0x0cbc
+
+#define	MV64x60_PCI0_PCI_DECODE_CNTL		0x0d3c
+#define	MV64x60_PCI1_PCI_DECODE_CNTL		0x0dbc
+
+#define	MV64x60_PCI0_SLAVE_MEM_0_REMAP		0x0c48
+#define	MV64x60_PCI0_SLAVE_MEM_1_REMAP		0x0d48
+#define	MV64x60_PCI0_SLAVE_MEM_2_REMAP		0x0c4c
+#define	MV64x60_PCI0_SLAVE_MEM_3_REMAP		0x0d4c
+#define	MV64x60_PCI0_SLAVE_DEV_0_REMAP		0x0c50
+#define	MV64x60_PCI0_SLAVE_DEV_1_REMAP		0x0d50
+#define	MV64x60_PCI0_SLAVE_DEV_2_REMAP		0x0d58
+#define	MV64x60_PCI0_SLAVE_DEV_3_REMAP		0x0c54
+#define	MV64x60_PCI0_SLAVE_BOOT_REMAP		0x0d54
+#define	MV64x60_PCI0_SLAVE_P2P_MEM_0_REMAP_LO	0x0d5c
+#define	MV64x60_PCI0_SLAVE_P2P_MEM_0_REMAP_HI	0x0d60
+#define	MV64x60_PCI0_SLAVE_P2P_MEM_1_REMAP_LO	0x0d64
+#define	MV64x60_PCI0_SLAVE_P2P_MEM_1_REMAP_HI	0x0d68
+#define	MV64x60_PCI0_SLAVE_P2P_IO_REMAP		0x0d6c
+#define	MV64x60_PCI0_SLAVE_CPU_REMAP		0x0d70
+
+#define	MV64x60_PCI1_SLAVE_MEM_0_REMAP		0x0cc8
+#define	MV64x60_PCI1_SLAVE_MEM_1_REMAP		0x0dc8
+#define	MV64x60_PCI1_SLAVE_MEM_2_REMAP		0x0ccc
+#define	MV64x60_PCI1_SLAVE_MEM_3_REMAP		0x0dcc
+#define	MV64x60_PCI1_SLAVE_DEV_0_REMAP		0x0cd0
+#define	MV64x60_PCI1_SLAVE_DEV_1_REMAP		0x0dd0
+#define	MV64x60_PCI1_SLAVE_DEV_2_REMAP		0x0dd8
+#define	MV64x60_PCI1_SLAVE_DEV_3_REMAP		0x0cd4
+#define	MV64x60_PCI1_SLAVE_BOOT_REMAP		0x0dd4
+#define	MV64x60_PCI1_SLAVE_P2P_MEM_0_REMAP_LO	0x0ddc
+#define	MV64x60_PCI1_SLAVE_P2P_MEM_0_REMAP_HI	0x0de0
+#define	MV64x60_PCI1_SLAVE_P2P_MEM_1_REMAP_LO	0x0de4
+#define	MV64x60_PCI1_SLAVE_P2P_MEM_1_REMAP_HI	0x0de8
+#define	MV64x60_PCI1_SLAVE_P2P_IO_REMAP		0x0dec
+#define	MV64x60_PCI1_SLAVE_CPU_REMAP		0x0df0
+
+/*
+ *****************************************************************************
+ *
+ *	ENET Controller Interface Registers
+ *
+ *****************************************************************************
+ */
+
+/* ENET Controller Window Registers (6 windows) */
+#define	MV64360_ENET2MEM_WINDOWS		6
+
+#define	MV64360_ENET2MEM_0_BASE			0x2200
+#define	MV64360_ENET2MEM_0_SIZE			0x2204
+#define	MV64360_ENET2MEM_1_BASE			0x2208
+#define	MV64360_ENET2MEM_1_SIZE			0x220c
+#define	MV64360_ENET2MEM_2_BASE			0x2210
+#define	MV64360_ENET2MEM_2_SIZE			0x2214
+#define	MV64360_ENET2MEM_3_BASE			0x2218
+#define	MV64360_ENET2MEM_3_SIZE			0x221c
+#define	MV64360_ENET2MEM_4_BASE			0x2220
+#define	MV64360_ENET2MEM_4_SIZE			0x2224
+#define	MV64360_ENET2MEM_5_BASE			0x2228
+#define	MV64360_ENET2MEM_5_SIZE			0x222c
+
+#define	MV64360_ENET2MEM_SNOOP_NONE		0x00000000
+#define	MV64360_ENET2MEM_SNOOP_WT		0x00001000
+#define	MV64360_ENET2MEM_SNOOP_WB		0x00002000
+
+#define	MV64360_ENET2MEM_BAR_ENABLE		0x2290
+
+#define	MV64360_ENET2MEM_ACC_PROT_0		0x2294
+#define	MV64360_ENET2MEM_ACC_PROT_1		0x2298
+#define	MV64360_ENET2MEM_ACC_PROT_2		0x229c
+
+/*
+ *****************************************************************************
+ *
+ *	MPSC Controller Interface Registers
+ *
+ *****************************************************************************
+ */
+
+/* MPSC Controller Window Registers (4 windows) */
+#define	MV64360_MPSC2MEM_WINDOWS		4
+
+#define	MV64360_MPSC2MEM_0_BASE			0xf200
+#define	MV64360_MPSC2MEM_0_SIZE			0xf204
+#define	MV64360_MPSC2MEM_1_BASE			0xf208
+#define	MV64360_MPSC2MEM_1_SIZE			0xf20c
+#define	MV64360_MPSC2MEM_2_BASE			0xf210
+#define	MV64360_MPSC2MEM_2_SIZE			0xf214
+#define	MV64360_MPSC2MEM_3_BASE			0xf218
+#define	MV64360_MPSC2MEM_3_SIZE			0xf21c
+
+#define MV64360_MPSC_0_REMAP			0xf240
+#define MV64360_MPSC_1_REMAP			0xf244
+
+#define	MV64360_MPSC2MEM_SNOOP_NONE		0x00000000
+#define	MV64360_MPSC2MEM_SNOOP_WT		0x00001000
+#define	MV64360_MPSC2MEM_SNOOP_WB		0x00002000
+
+#define	MV64360_MPSC2MEM_BAR_ENABLE		0xf250
+
+#define	MV64360_MPSC2MEM_ACC_PROT_0		0xf254
+#define	MV64360_MPSC2MEM_ACC_PROT_1		0xf258
+
+#define	MV64360_MPSC2REGS_BASE			0xf25c
+
+/*
+ *****************************************************************************
+ *
+ *	Timer/Counter Interface Registers
+ *
+ *****************************************************************************
+ */
+
+#define	MV64x60_TIMR_CNTR_0			0x0850
+#define	MV64x60_TIMR_CNTR_1			0x0854
+#define	MV64x60_TIMR_CNTR_2			0x0858
+#define	MV64x60_TIMR_CNTR_3			0x085c
+#define	MV64x60_TIMR_CNTR_0_3_CNTL		0x0864
+#define	MV64x60_TIMR_CNTR_0_3_INTR_CAUSE	0x0868
+#define	MV64x60_TIMR_CNTR_0_3_INTR_MASK		0x086c
+
+#define	GT64260_TIMR_CNTR_4			0x0950
+#define	GT64260_TIMR_CNTR_5			0x0954
+#define	GT64260_TIMR_CNTR_6			0x0958
+#define	GT64260_TIMR_CNTR_7			0x095c
+#define	GT64260_TIMR_CNTR_4_7_CNTL		0x0964
+#define	GT64260_TIMR_CNTR_4_7_INTR_CAUSE	0x0968
+#define	GT64260_TIMR_CNTR_4_7_INTR_MASK		0x096c
+
+/*
+ *****************************************************************************
+ *
+ *	Communications Controller
+ *
+ *****************************************************************************
+ */
+
+#define	GT64260_SER_INIT_PCI_ADDR_HI		0xf320
+#define	GT64260_SER_INIT_LAST_DATA		0xf324
+#define	GT64260_SER_INIT_CONTROL		0xf328
+#define	GT64260_SER_INIT_STATUS			0xf32c
+
+#define	MV64x60_COMM_ARBITER_CNTL		0xf300
+#define	MV64x60_COMM_CONFIG			0xb40c
+#define	MV64x60_COMM_XBAR_TO			0xf304
+#define	MV64x60_COMM_INTR_CAUSE			0xf310
+#define	MV64x60_COMM_INTR_MASK			0xf314
+#define	MV64x60_COMM_ERR_ADDR			0xf318
+
+#define MV64360_COMM_ARBITER_CNTL		0xf300
+
+/*
+ *****************************************************************************
+ *
+ *	IDMA Controller Interface Registers
+ *
+ *****************************************************************************
+ */
+
+/* IDMA Controller Window Registers (8 windows) */
+#define	MV64360_IDMA2MEM_WINDOWS		8
+
+#define	MV64360_IDMA2MEM_0_BASE			0x0a00
+#define	MV64360_IDMA2MEM_0_SIZE			0x0a04
+#define	MV64360_IDMA2MEM_1_BASE			0x0a08
+#define	MV64360_IDMA2MEM_1_SIZE			0x0a0c
+#define	MV64360_IDMA2MEM_2_BASE			0x0a10
+#define	MV64360_IDMA2MEM_2_SIZE			0x0a14
+#define	MV64360_IDMA2MEM_3_BASE			0x0a18
+#define	MV64360_IDMA2MEM_3_SIZE			0x0a1c
+#define	MV64360_IDMA2MEM_4_BASE			0x0a20
+#define	MV64360_IDMA2MEM_4_SIZE			0x0a24
+#define	MV64360_IDMA2MEM_5_BASE			0x0a28
+#define	MV64360_IDMA2MEM_5_SIZE			0x0a2c
+#define	MV64360_IDMA2MEM_6_BASE			0x0a30
+#define	MV64360_IDMA2MEM_6_SIZE			0x0a34
+#define	MV64360_IDMA2MEM_7_BASE			0x0a38
+#define	MV64360_IDMA2MEM_7_SIZE			0x0a3c
+
+#define	MV64360_IDMA2MEM_SNOOP_NONE		0x00000000
+#define	MV64360_IDMA2MEM_SNOOP_WT		0x00001000
+#define	MV64360_IDMA2MEM_SNOOP_WB		0x00002000
+
+#define	MV64360_IDMA2MEM_BAR_ENABLE		0x0a80
+
+#define	MV64360_IDMA2MEM_ACC_PROT_0		0x0a70
+#define	MV64360_IDMA2MEM_ACC_PROT_1		0x0a74
+#define	MV64360_IDMA2MEM_ACC_PROT_2		0x0a78
+#define	MV64360_IDMA2MEM_ACC_PROT_3		0x0a7c
+
+#define	MV64x60_IDMA_0_OFFSET			0x0800
+#define	MV64x60_IDMA_1_OFFSET			0x0804
+#define	MV64x60_IDMA_2_OFFSET			0x0808
+#define	MV64x60_IDMA_3_OFFSET			0x080c
+#define	MV64x60_IDMA_4_OFFSET			0x0900
+#define	MV64x60_IDMA_5_OFFSET			0x0904
+#define	MV64x60_IDMA_6_OFFSET			0x0908
+#define	MV64x60_IDMA_7_OFFSET			0x090c
+
+#define	MV64x60_IDMA_BYTE_COUNT			(0x0800 - MV64x60_IDMA_0_OFFSET)
+#define	MV64x60_IDMA_SRC_ADDR			(0x0810 - MV64x60_IDMA_0_OFFSET)
+#define	MV64x60_IDMA_DST_ADDR			(0x0820 - MV64x60_IDMA_0_OFFSET)
+#define	MV64x60_IDMA_NEXT_DESC			(0x0830 - MV64x60_IDMA_0_OFFSET)
+#define	MV64x60_IDMA_CUR_DESC			(0x0870 - MV64x60_IDMA_0_OFFSET)
+#define	MV64x60_IDMA_SRC_PCI_ADDR_HI		(0x0890 - MV64x60_IDMA_0_OFFSET)
+#define	MV64x60_IDMA_DST_PCI_ADDR_HI		(0x08a0 - MV64x60_IDMA_0_OFFSET)
+#define	MV64x60_IDMA_NEXT_DESC_PCI_ADDR_HI	(0x08b0 - MV64x60_IDMA_0_OFFSET)
+#define	MV64x60_IDMA_CONTROL_LO			(0x0840 - MV64x60_IDMA_0_OFFSET)
+#define	MV64x60_IDMA_CONTROL_HI			(0x0880 - MV64x60_IDMA_0_OFFSET)
+
+#define	MV64x60_IDMA_0_3_ARBITER_CNTL		0x0860
+#define	MV64x60_IDMA_4_7_ARBITER_CNTL		0x0960
+
+#define	MV64x60_IDMA_0_3_XBAR_TO		0x08d0
+#define	MV64x60_IDMA_4_7_XBAR_TO		0x09d0
+
+#define	MV64x60_IDMA_0_3_INTR_CAUSE		0x08c0
+#define	MV64x60_IDMA_0_3_INTR_MASK		0x08c4
+#define	MV64x60_IDMA_0_3_ERROR_ADDR		0x08c8
+#define	MV64x60_IDMA_0_3_ERROR_SELECT		0x08cc
+#define	MV64x60_IDMA_4_7_INTR_CAUSE		0x09c0
+#define	MV64x60_IDMA_4_7_INTR_MASK		0x09c4
+#define	MV64x60_IDMA_4_7_ERROR_ADDR		0x09c8
+#define	MV64x60_IDMA_4_7_ERROR_SELECT		0x09cc
+
+/*
+ *****************************************************************************
+ *
+ *	Watchdog Timer Interface Registers
+ *
+ *****************************************************************************
+ */
+
+#define	MV64x60_WDT_WDC				0xb410
+#define	MV64x60_WDT_WDV				0xb414
+
+
+/*
+ *****************************************************************************
+ *
+ *	 General Purpose Pins Controller Interface Registers
+ *
+ *****************************************************************************
+ */
+
+#define	MV64x60_GPP_IO_CNTL			0xf100
+#define	MV64x60_GPP_LEVEL_CNTL			0xf110
+#define	MV64x60_GPP_VALUE			0xf104
+#define	MV64x60_GPP_INTR_CAUSE			0xf108
+#define	MV64x60_GPP_INTR_MASK			0xf10c
+#define	MV64x60_GPP_VALUE_SET			0xf118
+#define	MV64x60_GPP_VALUE_CLR			0xf11c
+
+
+/*
+ *****************************************************************************
+ *
+ *	Multi-Purpose Pins Controller Interface Registers
+ *
+ *****************************************************************************
+ */
+
+#define	MV64x60_MPP_CNTL_0			0xf000
+#define	MV64x60_MPP_CNTL_1			0xf004
+#define	MV64x60_MPP_CNTL_2			0xf008
+#define	MV64x60_MPP_CNTL_3			0xf00c
+#define	GT64260_MPP_SERIAL_PORTS_MULTIPLEX	0xf010
+
+#define MV64x60_ETH_BAR_GAP			0x8
+#define MV64x60_ETH_SIZE_REG_GAP		0x8
+#define MV64x60_ETH_HIGH_ADDR_REMAP_REG_GAP	0x4
+#define MV64x60_ETH_PORT_ACCESS_CTRL_GAP	0x4
+
+#define MV64x60_EBAR_ATTR_DRAM_CS0		0x00000E00
+#define MV64x60_EBAR_ATTR_DRAM_CS1		0x00000D00
+#define MV64x60_EBAR_ATTR_DRAM_CS2		0x00000B00
+#define MV64x60_EBAR_ATTR_DRAM_CS3		0x00000700
+
+#define MV64x60_EBAR_ATTR_CBS_SRAM_BLOCK0	0x00000000
+#define MV64x60_EBAR_ATTR_CBS_SRAM_BLOCK1	0x00000100
+#define MV64x60_EBAR_ATTR_CBS_SRAM		0x00000000
+#define MV64x60_EBAR_ATTR_CBS_CPU_BUS		0x00000800
+
+
+/*
+ *****************************************************************************
+ *
+ *	Interrupt Controller Interface Registers
+ *
+ *****************************************************************************
+ */
+
+#define	GT64260_IC_OFFSET			0x0c18
+
+#define	GT64260_IC_MAIN_CAUSE_LO		0x0c18
+#define	GT64260_IC_MAIN_CAUSE_HI		0x0c68
+#define	GT64260_IC_CPU_INTR_MASK_LO		0x0c1c
+#define	GT64260_IC_CPU_INTR_MASK_HI		0x0c6c
+#define	GT64260_IC_CPU_SELECT_CAUSE		0x0c70
+#define	GT64260_IC_PCI0_INTR_MASK_LO		0x0c24
+#define	GT64260_IC_PCI0_INTR_MASK_HI		0x0c64
+#define	GT64260_IC_PCI0_SELECT_CAUSE		0x0c74
+#define	GT64260_IC_PCI1_INTR_MASK_LO		0x0ca4
+#define	GT64260_IC_PCI1_INTR_MASK_HI		0x0ce4
+#define	GT64260_IC_PCI1_SELECT_CAUSE		0x0cf4
+#define	GT64260_IC_CPU_INT_0_MASK		0x0e60
+#define	GT64260_IC_CPU_INT_1_MASK		0x0e64
+#define	GT64260_IC_CPU_INT_2_MASK		0x0e68
+#define	GT64260_IC_CPU_INT_3_MASK		0x0e6c
+
+#define	MV64360_IC_OFFSET			0x0000
+
+#define	MV64360_IC_MAIN_CAUSE_LO		0x0004
+#define	MV64360_IC_MAIN_CAUSE_HI		0x000c
+#define	MV64360_IC_CPU0_INTR_MASK_LO		0x0014
+#define	MV64360_IC_CPU0_INTR_MASK_HI		0x001c
+#define	MV64360_IC_CPU0_SELECT_CAUSE		0x0024
+#define	MV64360_IC_CPU1_INTR_MASK_LO		0x0034
+#define	MV64360_IC_CPU1_INTR_MASK_HI		0x003c
+#define	MV64360_IC_CPU1_SELECT_CAUSE		0x0044
+#define	MV64360_IC_INT0_MASK_LO			0x0054
+#define	MV64360_IC_INT0_MASK_HI			0x005c
+#define	MV64360_IC_INT0_SELECT_CAUSE		0x0064
+#define	MV64360_IC_INT1_MASK_LO			0x0074
+#define	MV64360_IC_INT1_MASK_HI			0x007c
+#define	MV64360_IC_INT1_SELECT_CAUSE		0x0084
+
+#endif /* __ASMPPC_MV64x60_DEFS_H */
diff -Nru a/include/asm-ppc/open_pic.h b/include/asm-ppc/open_pic.h
--- a/include/asm-ppc/open_pic.h	2005-03-01 23:38:55 -08:00
+++ b/include/asm-ppc/open_pic.h	2005-03-01 23:38:55 -08:00
@@ -35,11 +35,11 @@
 
 extern u_int OpenPIC_NumInitSenses;
 extern u_char *OpenPIC_InitSenses;
-extern void* OpenPIC_Addr;
+extern void __iomem * OpenPIC_Addr;
 extern int epic_serial_mode;
 
 /* Exported functions */
-extern void openpic_set_sources(int first_irq, int num_irqs, void *isr);
+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_hookup_cascade(u_int irq, char *name,
diff -Nru a/include/asm-ppc/pci-bridge.h b/include/asm-ppc/pci-bridge.h
--- a/include/asm-ppc/pci-bridge.h	2005-03-01 23:38:52 -08:00
+++ b/include/asm-ppc/pci-bridge.h	2005-03-01 23:38:52 -08:00
@@ -57,8 +57,8 @@
 	unsigned long pci_mem_offset;
 
 	struct pci_ops *ops;
-	volatile unsigned int *cfg_addr;
-	volatile unsigned char *cfg_data;
+	volatile unsigned int __iomem *cfg_addr;
+	volatile void __iomem *cfg_data;
 	/*
 	 * If set, indirect method will set the cfg_type bit as
 	 * needed to generate type 1 configuration transactions.
@@ -95,7 +95,7 @@
 			     int where, u32 val);
 
 extern void setup_indirect_pci_nomap(struct pci_controller* hose,
-			       u32 cfg_addr, u32 cfg_data);
+			       void __iomem *cfg_addr, void __iomem *cfg_data);
 extern void setup_indirect_pci(struct pci_controller* hose,
 			       u32 cfg_addr, u32 cfg_data);
 extern void setup_grackle(struct pci_controller *hose);
diff -Nru a/include/asm-ppc/perfmon.h b/include/asm-ppc/perfmon.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-ppc/perfmon.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,22 @@
+#ifndef __PERFMON_H
+#define __PERFMON_H
+
+extern void (*perf_irq)(struct pt_regs *);
+
+int request_perfmon_irq(void (*handler)(struct pt_regs *));
+void free_perfmon_irq(void);
+
+#ifdef CONFIG_FSL_BOOKE
+void init_pmc_stop(int ctr);
+void set_pmc_event(int ctr, int event);
+void set_pmc_user_kernel(int ctr, int user, int kernel);
+void set_pmc_marked(int ctr, int mark0, int mark1);
+void pmc_start_ctr(int ctr, int enable);
+void pmc_start_ctrs(int enable);
+void pmc_stop_ctrs(void);
+void dump_pmcs(void);
+
+extern struct op_ppc32_model op_model_fsl_booke;
+#endif
+
+#endif /* __PERFMON_H */
diff -Nru a/include/asm-ppc/pgtable.h b/include/asm-ppc/pgtable.h
--- a/include/asm-ppc/pgtable.h	2005-03-01 23:38:53 -08:00
+++ b/include/asm-ppc/pgtable.h	2005-03-01 23:38:53 -08:00
@@ -2,6 +2,8 @@
 #ifndef _PPC_PGTABLE_H
 #define _PPC_PGTABLE_H
 
+#include <asm-generic/4level-fixup.h>
+
 #include <linux/config.h>
 
 #ifndef __ASSEMBLY__
@@ -125,6 +127,7 @@
  */
 #define VMALLOC_OFFSET (0x1000000) /* 16M */
 #ifdef CONFIG_44x
+#include <asm/ibm44x.h>
 #define VMALLOC_START (((_ALIGN((long)high_memory, PPC44x_PIN_SIZE) + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)))
 #else
 #define VMALLOC_START ((((long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)))
@@ -431,7 +434,7 @@
 #define pte_pfn(x)		(pte_val(x) >> PAGE_SHIFT)
 #define pte_page(x)		pfn_to_page(pte_pfn(x))
 
-#define pfn_pte(pfn, prot)	__pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
+#define pfn_pte(pfn, prot)	__pte(((pte_t)(pfn) << PAGE_SHIFT) | pgprot_val(prot))
 #define mk_pte(page, prot)	pfn_pte(page_to_pfn(page), prot)
 
 /*
@@ -557,12 +560,12 @@
 static inline int ptep_test_and_clear_young(pte_t *ptep)
 {
 	unsigned long old;
-	old = (pte_update(ptep, _PAGE_ACCESSED, 0) & _PAGE_ACCESSED);
+	old = pte_update(ptep, _PAGE_ACCESSED, 0);
 #if _PAGE_HASHPTE != 0
 	if (old & _PAGE_HASHPTE)
 		flush_hash_one_pte(ptep);
 #endif
-	return old != 0;
+	return (old & _PAGE_ACCESSED) != 0;
 }
 
 static inline int ptep_test_and_clear_dirty(pte_t *ptep)
@@ -714,8 +717,22 @@
 /* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
 #define kern_addr_valid(addr)	(1)
 
+#ifdef CONFIG_PHYS_64BIT
+extern int remap_pfn_range(struct vm_area_struct *vma, unsigned long from,
+			unsigned long paddr, unsigned long size, pgprot_t prot);
+static inline int io_remap_page_range(struct vm_area_struct *vma,
+					unsigned long vaddr,
+					unsigned long paddr,
+					unsigned long size,
+					pgprot_t prot)
+{
+	phys_addr_t paddr64 = fixup_bigphys_addr(paddr, size);
+	return remap_pfn_range(vma, vaddr, paddr64 >> PAGE_SHIFT, size, prot);
+}
+#else
 #define io_remap_page_range(vma, vaddr, paddr, size, prot)		\
 		remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot)
+#endif
 
 /*
  * No page table caches to initialise
diff -Nru a/include/asm-ppc/pmac_feature.h b/include/asm-ppc/pmac_feature.h
--- a/include/asm-ppc/pmac_feature.h	2005-03-01 23:39:18 -08:00
+++ b/include/asm-ppc/pmac_feature.h	2005-03-01 23:39:18 -08:00
@@ -125,6 +125,7 @@
 #define PMAC_MB_HAS_FW_POWER		0x00000002
 #define PMAC_MB_OLD_CORE99		0x00000004
 #define PMAC_MB_MOBILE			0x00000008
+#define PMAC_MB_MAY_SLEEP		0x00000010
 
 /*
  * Feature calls supported on pmac
@@ -238,7 +239,10 @@
 
 /* PMAC_FTR_SLEEP_STATE		(struct device_node* node, 0, int value)
  * set the sleep state of the motherboard.
+ *
  * Pass -1 as value to query for sleep capability
+ * Pass 1 to set IOs to sleep
+ * Pass 0 to set IOs to wake
  */
 #define PMAC_FTR_SLEEP_STATE		PMAC_FTR_DEF(15)
 
@@ -279,10 +283,21 @@
  */
 #define PMAC_FTR_AACK_DELAY_ENABLE     	PMAC_FTR_DEF(20)
 
+/* PMAC_FTR_DEVICE_CAN_WAKE
+ *
+ * Used by video drivers to inform system that they can actually perform
+ * wakeup from sleep
+ */
+#define PMAC_FTR_DEVICE_CAN_WAKE	PMAC_FTR_DEF(22)
+
 
 /* Don't use those directly, they are for the sake of pmac_setup.c */
 extern long pmac_do_feature_call(unsigned int selector, ...);
 extern void pmac_feature_init(void);
+
+/* Video suspend tweak */
+extern void pmac_set_early_video_resume(void (*proc)(void *data), void *data);
+extern void pmac_call_early_video_resume(void);
 
 #define PMAC_FTR_DEF(x) ((_MACH_Pmac << 16) | (x))
 
diff -Nru a/include/asm-ppc/ppc4xx_dma.h b/include/asm-ppc/ppc4xx_dma.h
--- a/include/asm-ppc/ppc4xx_dma.h	2005-03-01 23:39:07 -08:00
+++ b/include/asm-ppc/ppc4xx_dma.h	2005-03-01 23:39:07 -08:00
@@ -137,10 +137,11 @@
 #define DMA_TCE_ENABLE     (1<<(8-DMA_CR_OFFSET))
 #define SET_DMA_TCE(x)     (((x)&0x1)<<(8-DMA_CR_OFFSET))
 
-#define DMA_DEC            (1<<(2)	/* Address Decrement */
+#define DMA_DEC            (1<<(2))	/* Address Decrement */
 #define SET_DMA_DEC(x)     (((x)&0x1)<<2)
 #define GET_DMA_DEC(x)     (((x)&DMA_DEC)>>2)
 
+
 /*
  * Transfer Modes
  * These modes are defined in a way that makes it possible to
@@ -244,6 +245,14 @@
 #define DMA_SG2            (1<<5)
 #define DMA_SG3            (1<<4)
 
+/* DMA Channel Count Register */
+#define DMA_CTC_BTEN     (1<<23)    /* Burst Enable/Disable bit */
+#define DMA_CTC_BSIZ_MSK (3<<21)    /* Mask of the Burst size bits */
+#define DMA_CTC_BSIZ_2   (0)
+#define DMA_CTC_BSIZ_4   (1<<21)
+#define DMA_CTC_BSIZ_8   (2<<21)
+#define DMA_CTC_BSIZ_16  (3<<21)
+
 /*
  * DMA SG Command Register
  */
@@ -482,6 +491,7 @@
 	char td;		/* transfer direction */
 #endif
 
+	char int_on_final_sg;/* for scatter/gather - only interrupt on last sg */
 } ppc_dma_ch_t;
 
 /*
@@ -545,6 +555,9 @@
 extern int ppc4xx_alloc_dma_handle(sgl_handle_t *, unsigned int, unsigned int);
 extern void ppc4xx_free_dma_handle(sgl_handle_t);
 extern int ppc4xx_get_dma_status(void);
+extern int ppc4xx_enable_burst(unsigned int);
+extern int ppc4xx_disable_burst(unsigned int);
+extern int ppc4xx_set_burst_size(unsigned int, unsigned int);
 extern void ppc4xx_set_src_addr(int dmanr, phys_addr_t src_addr);
 extern void ppc4xx_set_dst_addr(int dmanr, phys_addr_t dst_addr);
 extern void ppc4xx_enable_dma(unsigned int dmanr);
diff -Nru a/include/asm-ppc/ppc4xx_pic.h b/include/asm-ppc/ppc4xx_pic.h
--- a/include/asm-ppc/ppc4xx_pic.h	2005-03-01 23:39:18 -08:00
+++ b/include/asm-ppc/ppc4xx_pic.h	2005-03-01 23:39:18 -08:00
@@ -1,28 +1,53 @@
 /*
+ * include/asm-ppc/ppc4xx_pic.h
  *
- *    Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
+ * Interrupt controller driver for PowerPC 4xx-based processors.
  *
- *    Module name: ppc4xx_pic.h
+ * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
  *
- *    Description:
- *      Interrupt controller driver for PowerPC 4xx-based processors.
+ * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
+ * Copyright (c) 2004 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
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
  */
 
 #ifndef	__PPC4XX_PIC_H__
 #define	__PPC4XX_PIC_H__
 
 #include <linux/config.h>
+#include <linux/types.h>
 #include <linux/irq.h>
 
-/* External Global Variables */
-
-extern struct hw_interrupt_type *ppc4xx_pic;
-extern unsigned int ibm4xxPIC_NumInitSenses;
-extern unsigned char *ibm4xxPIC_InitSenses;
-
-/* Function Prototypes */
+/* "Fixed" UIC settings (they are chip, not board specific),
+ * e.g. polarity/triggerring for internal interrupt sources.
+ *
+ * Platform port should provide NR_UICS-sized array named ppc4xx_core_uic_cfg
+ * with these "fixed" settings: .polarity contains exact value which will
+ * be written (masked with "ext_irq_mask") into UICx_PR register,
+ * .triggering - to UICx_TR.
+ *
+ * Settings for external IRQs can be specified separately by the
+ * board support code. In this case properly sized array of unsigned
+ * char named ppc4xx_uic_ext_irq_cfg should be filled with correct
+ * values using IRQ_SENSE_XXXXX and IRQ_POLARITY_XXXXXXX defines.
+ *
+ * If these arrays aren't provided, UIC initialization code keeps firmware
+ * configuration. Also, ppc4xx_uic_ext_irq_cfg implies ppc4xx_core_uic_cfg
+ * is defined.
+ *
+ * Both ppc4xx_core_uic_cfg and ppc4xx_uic_ext_irq_cfg are declared as
+ * "weak" symbols in ppc4xx_pic.c
+ *
+ */
+struct ppc4xx_uic_settings {
+	u32 	polarity;
+	u32 	triggering;
+	u32	ext_irq_mask;
+};
 
 extern void ppc4xx_pic_init(void);
-extern int ppc4xx_pic_get_irq(struct pt_regs *regs);
 
-#endif				/* __PPC4XX_PIC_H__ */
+#endif	/* __PPC4XX_PIC_H__ */
diff -Nru a/include/asm-ppc/ppc_sys.h b/include/asm-ppc/ppc_sys.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-ppc/ppc_sys.h	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,65 @@
+/*
+ * include/asm-ppc/ppc_sys.h
+ *
+ * PPC system definitions and library functions
+ *
+ * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ *
+ * Copyright 2005 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_PPC_SYS_H
+#define __ASM_PPC_SYS_H
+
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/types.h>
+
+#if defined(CONFIG_85xx)
+#include <asm/mpc85xx.h>
+#else
+#error "need definition of ppc_sys_devices"
+#endif
+
+struct ppc_sys_spec {
+	/* PPC sys is matched via (ID & mask) == value, id could be
+	 * PVR, SVR, IMMR, * etc. */
+	u32 			mask;
+	u32 			value;
+	u32 			num_devices;
+	char 			*ppc_sys_name;
+	enum ppc_sys_devices 	*device_list;
+};
+
+/* describes all specific chips and which devices they have on them */
+extern struct ppc_sys_spec ppc_sys_specs[];
+extern struct ppc_sys_spec *cur_ppc_sys_spec;
+
+/* determine which specific SOC we are */
+extern void identify_ppc_sys_by_id(u32 id) __init;
+extern void identify_ppc_sys_by_name(char *name) __init;
+
+/* describes all devices that may exist in a given family of processors */
+extern struct platform_device ppc_sys_platform_devices[];
+
+/* allow any platform_device fixup to occur before device is registered */
+extern int (*ppc_sys_device_fixup) (struct platform_device * pdev);
+
+/* Update all memory resources by paddr, call before platform_device_register */
+extern void ppc_sys_fixup_mem_resource(struct platform_device *pdev,
+				       phys_addr_t paddr) __init;
+
+/* Get platform_data pointer out of platform device, call before platform_device_register */
+extern void *ppc_sys_get_pdata(enum ppc_sys_devices dev) __init;
+
+/* remove a device from the system */
+extern void ppc_sys_device_remove(enum ppc_sys_devices dev);
+
+#endif				/* __ASM_PPC_SYS_H */
+#endif				/* __KERNEL__ */
diff -Nru a/include/asm-ppc/processor.h b/include/asm-ppc/processor.h
--- a/include/asm-ppc/processor.h	2005-03-01 23:38:44 -08:00
+++ b/include/asm-ppc/processor.h	2005-03-01 23:38:44 -08:00
@@ -34,6 +34,7 @@
 /* these are arbitrary */
 #define _CHRP_Motorola	0x04	/* motorola chrp, the cobra */
 #define _CHRP_IBM	0x05	/* IBM chrp, the longtrail and longtrail 2 */
+#define _CHRP_Pegasos	0x06	/* Genesi/bplan's Pegasos and Pegasos2 */
 
 #define _GLOBAL(n)\
 	.stabs __stringify(n:F-1),N_FUN,0,0,n;\
@@ -54,6 +55,7 @@
 
 /* what kind of prep workstation we are */
 extern int _prep_type;
+extern int _chrp_type;
 
 /*
  * This is used to identify the board type from a given PReP board
@@ -77,12 +79,6 @@
  * Create a new kernel thread.
  */
 extern long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
-
-/*
- * Bus types
- */
-#define MCA_bus 0
-#define MCA_bus__is_a_macro
 
 /* Lazy FPU handling on uni-processor */
 extern struct task_struct *last_task_used_math;
diff -Nru a/include/asm-ppc/reg.h b/include/asm-ppc/reg.h
--- a/include/asm-ppc/reg.h	2005-03-01 23:39:09 -08:00
+++ b/include/asm-ppc/reg.h	2005-03-01 23:39:09 -08:00
@@ -244,6 +244,10 @@
 #define L2CR_L2DF		0x00004000	/* L2 differential clock */
 #define L2CR_L2BYP		0x00002000	/* L2 DLL bypass */
 #define L2CR_L2IP		0x00000001	/* L2 GI in progress */
+#define L2CR_L2IO_745x		0x00100000	/* L2 instr. only (745x) */
+#define L2CR_L2DO_745x		0x00010000	/* L2 data only (745x) */
+#define L2CR_L2REP_745x		0x00001000	/* L2 repl. algorithm (745x) */
+#define L2CR_L2HWF_745x		0x00000800	/* L2 hardware flush (745x) */
 #define SPRN_L3CR		0x3FA	/* Level 3 Cache Control Regsiter */
 #define L3CR_L3E		0x80000000	/* L3 enable */
 #define L3CR_L3PE		0x40000000	/* L3 data parity enable */
@@ -329,6 +333,7 @@
 #define MMCR0_PMC2_CYCLES	0x1
 #define MMCR0_PMC2_ITLB		0x7
 #define MMCR0_PMC2_LOADMISSTIME	0x5
+#define MMCR0_PMXE	(1 << 26)
 
 /* Short-hand versions for a number of the above SPRNs */
 #define CTR	SPRN_CTR	/* Counter Register */
diff -Nru a/include/asm-ppc/reg_booke.h b/include/asm-ppc/reg_booke.h
--- a/include/asm-ppc/reg_booke.h	2005-03-01 23:39:08 -08:00
+++ b/include/asm-ppc/reg_booke.h	2005-03-01 23:39:08 -08:00
@@ -51,6 +51,59 @@
 #define mtpmr(rn, v)	asm volatile("mtpmr " __stringify(rn) ",%0" : : "r" (v))
 #endif /* __ASSEMBLY__ */
 
+/* Freescale Book E Performance Monitor APU Registers */
+#define PMRN_PMC0	0x010	/* Performance Monitor Counter 0 */
+#define PMRN_PMC1	0x011	/* Performance Monitor Counter 1 */
+#define PMRN_PMC2	0x012	/* Performance Monitor Counter 1 */
+#define PMRN_PMC3	0x013	/* Performance Monitor Counter 1 */
+#define PMRN_PMLCA0	0x090	/* PM Local Control A0 */
+#define PMRN_PMLCA1	0x091	/* PM Local Control A1 */
+#define PMRN_PMLCA2	0x092	/* PM Local Control A2 */
+#define PMRN_PMLCA3	0x093	/* PM Local Control A3 */
+
+#define PMLCA_FC	0x80000000	/* Freeze Counter */
+#define PMLCA_FCS	0x40000000	/* Freeze in Supervisor */
+#define PMLCA_FCU	0x20000000	/* Freeze in User */
+#define PMLCA_FCM1	0x10000000	/* Freeze when PMM==1 */
+#define PMLCA_FCM0	0x08000000	/* Freeze when PMM==0 */
+#define PMLCA_CE	0x04000000	/* Condition Enable */
+
+#define PMLCA_EVENT_MASK 0x007f0000	/* Event field */
+#define PMLCA_EVENT_SHIFT	16
+
+#define PMRN_PMLCB0	0x110	/* PM Local Control B0 */
+#define PMRN_PMLCB1	0x111	/* PM Local Control B1 */
+#define PMRN_PMLCB2	0x112	/* PM Local Control B2 */
+#define PMRN_PMLCB3	0x113	/* PM Local Control B3 */
+
+#define PMLCB_THRESHMUL_MASK	0x0700	/* Threshhold Multiple Field */
+#define PMLCB_THRESHMUL_SHIFT	8
+
+#define PMLCB_THRESHOLD_MASK	0x003f	/* Threshold Field */
+#define PMLCB_THRESHOLD_SHIFT	0
+
+#define PMRN_PMGC0	0x190	/* PM Global Control 0 */
+
+#define PMGC0_FAC	0x80000000	/* Freeze all Counters */
+#define PMGC0_PMIE	0x40000000	/* Interrupt Enable */
+#define PMGC0_FCECE	0x20000000	/* Freeze countes on
+					   Enabled Condition or
+					   Event */
+
+#define PMRN_UPMC0	0x000	/* User Performance Monitor Counter 0 */
+#define PMRN_UPMC1	0x001	/* User Performance Monitor Counter 1 */
+#define PMRN_UPMC2	0x002	/* User Performance Monitor Counter 1 */
+#define PMRN_UPMC3	0x003	/* User Performance Monitor Counter 1 */
+#define PMRN_UPMLCA0	0x080	/* User PM Local Control A0 */
+#define PMRN_UPMLCA1	0x081	/* User PM Local Control A1 */
+#define PMRN_UPMLCA2	0x082	/* User PM Local Control A2 */
+#define PMRN_UPMLCA3	0x083	/* User PM Local Control A3 */
+#define PMRN_UPMLCB0	0x100	/* User PM Local Control B0 */
+#define PMRN_UPMLCB1	0x101	/* User PM Local Control B1 */
+#define PMRN_UPMLCB2	0x102	/* User PM Local Control B2 */
+#define PMRN_UPMLCB3	0x103	/* User PM Local Control B3 */
+#define PMRN_UPMGC0	0x180	/* User PM Global Control 0 */
+
 
 /* Machine State Register (MSR) Fields */
 #define MSR_UCLE	(1<<26)	/* User-mode cache lock enable */
diff -Nru a/include/asm-ppc/resource.h b/include/asm-ppc/resource.h
--- a/include/asm-ppc/resource.h	2005-03-01 23:38:56 -08:00
+++ b/include/asm-ppc/resource.h	2005-03-01 23:38:56 -08:00
@@ -1,48 +1,6 @@
 #ifndef _PPC_RESOURCE_H
 #define _PPC_RESOURCE_H
 
-#define RLIMIT_CPU	0		/* CPU time in ms */
-#define RLIMIT_FSIZE	1		/* Maximum filesize */
-#define RLIMIT_DATA	2		/* max data size */
-#define RLIMIT_STACK	3		/* max stack size */
-#define RLIMIT_CORE	4		/* max core file size */
-#define RLIMIT_RSS	5		/* max resident set size */
-#define RLIMIT_NPROC	6		/* max number of processes */
-#define RLIMIT_NOFILE	7		/* max number of open files */
-#define RLIMIT_MEMLOCK	8		/* max locked-in-memory address space */
-#define RLIMIT_AS	9		/* address space limit(?) */
-#define RLIMIT_LOCKS	10		/* maximum file locks held */
-#define RLIMIT_SIGPENDING 11		/* max number of pending signals */
-#define RLIMIT_MSGQUEUE 12		/* maximum bytes in POSIX mqueues */
-
-#define RLIM_NLIMITS	13
-
-#ifdef __KERNEL__
-
-/*
- * SuS says limits have to be unsigned.
- * Which makes a ton more sense anyway.
- */
-#define RLIM_INFINITY	(~0UL)
-
-
-#define INIT_RLIMITS							\
-{									\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{      _STK_LIM, RLIM_INFINITY },		\
-	{             0, RLIM_INFINITY },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{             0,             0 },		\
-	{      INR_OPEN,     INR_OPEN  },		\
-	{   MLOCK_LIMIT,   MLOCK_LIMIT },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{ MAX_SIGPENDING, MAX_SIGPENDING },		\
-	{ MQ_BYTES_MAX, MQ_BYTES_MAX },			\
-}
-
-#endif /* __KERNEL__ */
+#include <asm-generic/resource.h>
 
 #endif
diff -Nru a/include/asm-ppc/rwsem.h b/include/asm-ppc/rwsem.h
--- a/include/asm-ppc/rwsem.h	2005-03-01 23:39:17 -08:00
+++ b/include/asm-ppc/rwsem.h	2005-03-01 23:39:17 -08:00
@@ -27,7 +27,7 @@
 #define RWSEM_ACTIVE_WRITE_BIAS		(RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS)
 	spinlock_t		wait_lock;
 	struct list_head	wait_list;
-#ifdef RWSEM_DEBUG
+#if RWSEM_DEBUG
 	int			debug;
 #endif
 };
@@ -35,7 +35,7 @@
 /*
  * initialisation
  */
-#ifdef RWSEM_DEBUG
+#if RWSEM_DEBUG
 #define __RWSEM_DEBUG_INIT      , 0
 #else
 #define __RWSEM_DEBUG_INIT	/* */
@@ -59,7 +59,7 @@
 	sem->count = RWSEM_UNLOCKED_VALUE;
 	spin_lock_init(&sem->wait_lock);
 	INIT_LIST_HEAD(&sem->wait_list);
-#ifdef RWSEM_DEBUG
+#if RWSEM_DEBUG
 	sem->debug = 0;
 #endif
 }
diff -Nru a/include/asm-ppc/sections.h b/include/asm-ppc/sections.h
--- a/include/asm-ppc/sections.h	2005-03-01 23:39:17 -08:00
+++ b/include/asm-ppc/sections.h	2005-03-01 23:39:17 -08:00
@@ -4,8 +4,6 @@
 
 #include <asm-generic/sections.h>
 
-extern char _end[];
-
 #define __pmac __attribute__ ((__section__ (".pmac.text")))
 #define __pmacdata __attribute__ ((__section__ (".pmac.data")))
 #define __pmacfunc(__argpmac) \
diff -Nru a/include/asm-ppc/serial.h b/include/asm-ppc/serial.h
--- a/include/asm-ppc/serial.h	2005-03-01 23:39:16 -08:00
+++ b/include/asm-ppc/serial.h	2005-03-01 23:39:16 -08:00
@@ -10,6 +10,8 @@
 
 #if defined(CONFIG_EV64260)
 #include <platforms/ev64260.h>
+#elif defined(CONFIG_CHESTNUT)
+#include <platforms/chestnut.h>
 #elif defined(CONFIG_GEMINI)
 #include <platforms/gemini_serial.h>
 #elif defined(CONFIG_POWERPMC250)
diff -Nru a/include/asm-ppc/signal.h b/include/asm-ppc/signal.h
--- a/include/asm-ppc/signal.h	2005-03-01 23:38:52 -08:00
+++ b/include/asm-ppc/signal.h	2005-03-01 23:38:52 -08:00
@@ -157,4 +157,23 @@
 #define ptrace_signal_deliver(regs, cookie) do { } while (0)
 #endif /* __KERNEL__ */
 
+/*
+ * These are parameters to dbg_sigreturn syscall.  They enable or
+ * disable certain debugging things that can be done from signal
+ * handlers.  The dbg_sigreturn syscall *must* be called from a
+ * SA_SIGINFO signal so the ucontext can be passed to it.  It takes an
+ * array of struct sig_dbg_op, which has the debug operations to
+ * perform before returning from the signal.
+ */
+struct sig_dbg_op {
+	int dbg_type;
+	unsigned long dbg_value;
+};
+
+/* Enable or disable single-stepping.  The value sets the state. */
+#define SIG_DBG_SINGLE_STEPPING		1
+
+/* Enable or disable branch tracing.  The value sets the state. */
+#define SIG_DBG_BRANCH_TRACING		2
+
 #endif
diff -Nru a/include/asm-ppc/smp.h b/include/asm-ppc/smp.h
--- a/include/asm-ppc/smp.h	2005-03-01 23:38:53 -08:00
+++ b/include/asm-ppc/smp.h	2005-03-01 23:38:53 -08:00
@@ -40,7 +40,6 @@
 extern void smp_send_xmon_break(int cpu);
 struct pt_regs;
 extern void smp_message_recv(int, struct pt_regs *);
-extern void smp_local_timer_interrupt(struct pt_regs *);
 
 #define NO_PROC_ID		0xFF            /* No processor magic marker */
 #define PROC_CHANGE_PENALTY	20
diff -Nru a/include/asm-ppc/spinlock.h b/include/asm-ppc/spinlock.h
--- a/include/asm-ppc/spinlock.h	2005-03-01 23:38:55 -08:00
+++ b/include/asm-ppc/spinlock.h	2005-03-01 23:38:55 -08:00
@@ -13,6 +13,9 @@
 	volatile unsigned long owner_pc;
 	volatile unsigned long owner_cpu;
 #endif
+#ifdef CONFIG_PREEMPT
+	unsigned int break_lock;
+#endif
 } spinlock_t;
 
 #ifdef __KERNEL__
@@ -79,28 +82,43 @@
  * read-locks.
  */
 typedef struct {
-	volatile unsigned long lock;
-#ifdef CONFIG_DEBUG_SPINLOCK
-	volatile unsigned long owner_pc;
+	volatile signed int lock;
+#ifdef CONFIG_PREEMPT
+	unsigned int break_lock;
 #endif
 } rwlock_t;
 
-#ifdef CONFIG_DEBUG_SPINLOCK
-#define RWLOCK_DEBUG_INIT     , 0
-#else
-#define RWLOCK_DEBUG_INIT     /* */
-#endif
-
-#define RW_LOCK_UNLOCKED (rwlock_t) { 0 RWLOCK_DEBUG_INIT }
+#define RW_LOCK_UNLOCKED (rwlock_t) { 0 }
 #define rwlock_init(lp) do { *(lp) = RW_LOCK_UNLOCKED; } while(0)
 
-#define rwlock_is_locked(x)	((x)->lock != 0)
+#define read_can_lock(rw)	((rw)->lock >= 0)
+#define write_can_lock(rw)	(!(rw)->lock)
 
 #ifndef CONFIG_DEBUG_SPINLOCK
 
+static __inline__ int _raw_read_trylock(rwlock_t *rw)
+{
+	signed int tmp;
+
+	__asm__ __volatile__(
+"2:	lwarx	%0,0,%1		# read_trylock\n\
+	addic.	%0,%0,1\n\
+	ble-	1f\n"
+	PPC405_ERR77(0,%1)
+"	stwcx.	%0,0,%1\n\
+	bne-	2b\n\
+	isync\n\
+1:"
+	: "=&r"(tmp)
+	: "r"(&rw->lock)
+	: "cr0", "memory");
+
+	return tmp > 0;
+}
+
 static __inline__ void _raw_read_lock(rwlock_t *rw)
 {
-	unsigned int tmp;
+	signed int tmp;
 
 	__asm__ __volatile__(
 	"b	2f		# read_lock\n\
@@ -121,7 +139,7 @@
 
 static __inline__ void _raw_read_unlock(rwlock_t *rw)
 {
-	unsigned int tmp;
+	signed int tmp;
 
 	__asm__ __volatile__(
 	"eieio			# read_unlock\n\
@@ -137,7 +155,7 @@
 
 static __inline__ int _raw_write_trylock(rwlock_t *rw)
 {
-	unsigned int tmp;
+	signed int tmp;
 
 	__asm__ __volatile__(
 "2:	lwarx	%0,0,%1		# write_trylock\n\
@@ -157,7 +175,7 @@
 
 static __inline__ void _raw_write_lock(rwlock_t *rw)
 {
-	unsigned int tmp;
+	signed int tmp;
 
 	__asm__ __volatile__(
 	"b	2f		# write_lock\n\
@@ -188,6 +206,7 @@
 extern void _raw_read_unlock(rwlock_t *rw);
 extern void _raw_write_lock(rwlock_t *rw);
 extern void _raw_write_unlock(rwlock_t *rw);
+extern int _raw_read_trylock(rwlock_t *rw);
 extern int _raw_write_trylock(rwlock_t *rw);
 
 #endif
diff -Nru a/include/asm-ppc/string.h b/include/asm-ppc/string.h
--- a/include/asm-ppc/string.h	2005-03-01 23:39:08 -08:00
+++ b/include/asm-ppc/string.h	2005-03-01 23:39:08 -08:00
@@ -9,7 +9,6 @@
 #define __HAVE_ARCH_STRCMP
 #define __HAVE_ARCH_STRCAT
 #define __HAVE_ARCH_MEMSET
-#define __HAVE_ARCH_BCOPY
 #define __HAVE_ARCH_MEMCPY
 #define __HAVE_ARCH_MEMMOVE
 #define __HAVE_ARCH_MEMCMP
diff -Nru a/include/asm-ppc/system.h b/include/asm-ppc/system.h
--- a/include/asm-ppc/system.h	2005-03-01 23:38:56 -08:00
+++ b/include/asm-ppc/system.h	2005-03-01 23:38:56 -08:00
@@ -74,6 +74,7 @@
 extern void pmac_find_display(void);
 extern void giveup_fpu(struct task_struct *);
 extern void enable_kernel_fp(void);
+extern void enable_kernel_altivec(void);
 extern void giveup_altivec(struct task_struct *);
 extern void load_up_altivec(struct task_struct *);
 extern void giveup_spe(struct task_struct *);
diff -Nru a/include/asm-ppc/thread_info.h b/include/asm-ppc/thread_info.h
--- a/include/asm-ppc/thread_info.h	2005-03-01 23:38:53 -08:00
+++ b/include/asm-ppc/thread_info.h	2005-03-01 23:38:53 -08:00
@@ -76,6 +76,7 @@
 #define TIF_NEED_RESCHED	3	/* rescheduling necessary */
 #define TIF_POLLING_NRFLAG	4	/* true if poll_idle() is polling
 					   TIF_NEED_RESCHED */
+#define TIF_MEMDIE		5
 /* as above, but as bit values */
 #define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE)
 #define _TIF_NOTIFY_RESUME	(1<<TIF_NOTIFY_RESUME)
diff -Nru a/include/asm-ppc/uaccess.h b/include/asm-ppc/uaccess.h
--- a/include/asm-ppc/uaccess.h	2005-03-01 23:38:51 -08:00
+++ b/include/asm-ppc/uaccess.h	2005-03-01 23:38:51 -08:00
@@ -180,7 +180,8 @@
 
 #define __get_user_nocheck(x, ptr, size)			\
 ({								\
-	long __gu_err, __gu_val;				\
+	long __gu_err;						\
+	unsigned long __gu_val;					\
 	__chk_user_ptr(ptr);					\
 	__get_user_size(__gu_val, (ptr), (size), __gu_err);	\
 	(x) = (__typeof__(*(ptr)))__gu_val;			\
@@ -199,7 +200,8 @@
 
 #define __get_user_check(x, ptr, size)					\
 ({									\
-	long __gu_err = -EFAULT, __gu_val = 0;				\
+	long __gu_err = -EFAULT;					\
+	unsigned long  __gu_val = 0;					\
 	const __typeof__(*(ptr)) __user *__gu_addr = (ptr);		\
 	if (access_ok(VERIFY_READ, __gu_addr, (size)))			\
 		__get_user_size(__gu_val, __gu_addr, (size), __gu_err);	\
@@ -305,10 +307,10 @@
 	unsigned long over;
 
 	if (access_ok(VERIFY_READ, from, n))
-		return __copy_tofrom_user((void __user *)to, from, n);
+		return __copy_tofrom_user((__force void __user *)to, from, n);
 	if ((unsigned long)from < TASK_SIZE) {
 		over = (unsigned long)from + n - TASK_SIZE;
-		return __copy_tofrom_user((void __user *)to, from, n - over) + over;
+		return __copy_tofrom_user((__force void __user *)to, from, n - over) + over;
 	}
 	return n;
 }
@@ -319,18 +321,24 @@
 	unsigned long over;
 
 	if (access_ok(VERIFY_WRITE, to, n))
-		return __copy_tofrom_user(to, (void __user *) from, n);
+		return __copy_tofrom_user(to, (__force void __user *) from, n);
 	if ((unsigned long)to < TASK_SIZE) {
 		over = (unsigned long)to + n - TASK_SIZE;
-		return __copy_tofrom_user(to, (void __user *) from, n - over) + over;
+		return __copy_tofrom_user(to, (__force void __user *) from, n - over) + over;
 	}
 	return n;
 }
 
-#define __copy_from_user(to, from, size) \
-	__copy_tofrom_user((void __user *)(to), (from), (size))
-#define __copy_to_user(to, from, size) \
-	__copy_tofrom_user((to), (void __user *)(from), (size))
+static inline unsigned long __copy_from_user(void *to, const void __user *from, unsigned long size)
+{
+	return __copy_tofrom_user((__force void __user *)to, from, size);
+}
+
+static inline unsigned long __copy_to_user(void __user *to, const void *from, unsigned long size)
+{
+	return __copy_tofrom_user(to, (__force void __user *)from, size);
+}
+
 #define __copy_to_user_inatomic __copy_to_user
 #define __copy_from_user_inatomic __copy_from_user
 
diff -Nru a/include/asm-ppc/uninorth.h b/include/asm-ppc/uninorth.h
--- a/include/asm-ppc/uninorth.h	2005-03-01 23:39:09 -08:00
+++ b/include/asm-ppc/uninorth.h	2005-03-01 23:39:09 -08:00
@@ -148,6 +148,55 @@
 #define UNI_N_AACK_DELAY		0x0100
 #define UNI_N_AACK_DELAY_ENABLE		0x00000001
 
+/* Clock status for Intrepid */
+#define UNI_N_CLOCK_STOP_STATUS0	0x0150
+#define UNI_N_CLOCK_STOPPED_EXTAGP	0x00200000
+#define UNI_N_CLOCK_STOPPED_AGPDEL	0x00100000
+#define UNI_N_CLOCK_STOPPED_I2S0_45_49	0x00080000
+#define UNI_N_CLOCK_STOPPED_I2S0_18	0x00040000
+#define UNI_N_CLOCK_STOPPED_I2S1_45_49	0x00020000
+#define UNI_N_CLOCK_STOPPED_I2S1_18	0x00010000
+#define UNI_N_CLOCK_STOPPED_TIMER	0x00008000
+#define UNI_N_CLOCK_STOPPED_SCC_RTCLK18	0x00004000
+#define UNI_N_CLOCK_STOPPED_SCC_RTCLK32	0x00002000
+#define UNI_N_CLOCK_STOPPED_SCC_VIA32	0x00001000
+#define UNI_N_CLOCK_STOPPED_SCC_SLOT0	0x00000800
+#define UNI_N_CLOCK_STOPPED_SCC_SLOT1	0x00000400
+#define UNI_N_CLOCK_STOPPED_SCC_SLOT2	0x00000200
+#define UNI_N_CLOCK_STOPPED_PCI_FBCLKO	0x00000100
+#define UNI_N_CLOCK_STOPPED_VEO0	0x00000080
+#define UNI_N_CLOCK_STOPPED_VEO1	0x00000040
+#define UNI_N_CLOCK_STOPPED_USB0	0x00000020
+#define UNI_N_CLOCK_STOPPED_USB1	0x00000010
+#define UNI_N_CLOCK_STOPPED_USB2	0x00000008
+#define UNI_N_CLOCK_STOPPED_32		0x00000004
+#define UNI_N_CLOCK_STOPPED_45		0x00000002
+#define UNI_N_CLOCK_STOPPED_49		0x00000001
+
+#define UNI_N_CLOCK_STOP_STATUS1	0x0160
+#define UNI_N_CLOCK_STOPPED_PLL4REF	0x00080000
+#define UNI_N_CLOCK_STOPPED_CPUDEL	0x00040000
+#define UNI_N_CLOCK_STOPPED_CPU		0x00020000
+#define UNI_N_CLOCK_STOPPED_BUF_REFCKO	0x00010000
+#define UNI_N_CLOCK_STOPPED_PCI2	0x00008000
+#define UNI_N_CLOCK_STOPPED_FW		0x00004000
+#define UNI_N_CLOCK_STOPPED_GB		0x00002000
+#define UNI_N_CLOCK_STOPPED_ATA66	0x00001000
+#define UNI_N_CLOCK_STOPPED_ATA100	0x00000800
+#define UNI_N_CLOCK_STOPPED_MAX		0x00000400
+#define UNI_N_CLOCK_STOPPED_PCI1	0x00000200
+#define UNI_N_CLOCK_STOPPED_KLPCI	0x00000100
+#define UNI_N_CLOCK_STOPPED_USB0PCI	0x00000080
+#define UNI_N_CLOCK_STOPPED_USB1PCI	0x00000040
+#define UNI_N_CLOCK_STOPPED_USB2PCI	0x00000020
+#define UNI_N_CLOCK_STOPPED_7PCI1	0x00000008
+#define UNI_N_CLOCK_STOPPED_AGP		0x00000004
+#define UNI_N_CLOCK_STOPPED_PCI0	0x00000002
+#define UNI_N_CLOCK_STOPPED_18		0x00000001
+
+/* Intrepid registe to OF do-platform-clockspreading */
+#define UNI_N_CLOCK_SPREADING		0x190
+
 /* Uninorth 1.5 rev. has additional perf. monitor registers at 0xf00-0xf50 */
 
 
diff -Nru a/include/asm-ppc/unistd.h b/include/asm-ppc/unistd.h
--- a/include/asm-ppc/unistd.h	2005-03-01 23:38:53 -08:00
+++ b/include/asm-ppc/unistd.h	2005-03-01 23:38:53 -08:00
@@ -260,7 +260,7 @@
 #define __NR_fstatfs64		253
 #define __NR_fadvise64_64	254
 #define __NR_rtas		255
-/* Number 256 is reserved for sys_debug_setcontext */
+#define __NR_sys_debug_setcontext 256
 /* Number 257 is reserved for vserver */
 /* Number 258 is reserved for new sys_remap_file_pages */
 /* Number 259 is reserved for new sys_mbind */
diff -Nru a/include/asm-ppc64/bug.h b/include/asm-ppc64/bug.h
--- a/include/asm-ppc64/bug.h	2005-03-01 23:39:18 -08:00
+++ b/include/asm-ppc64/bug.h	2005-03-01 23:39:18 -08:00
@@ -18,6 +18,8 @@
 	const char	*function;
 };
 
+struct bug_entry *find_bug(unsigned long bugaddr);
+
 /*
  * If this bit is set in the line number it means that the trap
  * is for WARN_ON rather than BUG or BUG_ON.
diff -Nru a/include/asm-ppc64/cache.h b/include/asm-ppc64/cache.h
--- a/include/asm-ppc64/cache.h	2005-03-01 23:39:07 -08:00
+++ b/include/asm-ppc64/cache.h	2005-03-01 23:39:07 -08:00
@@ -7,11 +7,30 @@
 #ifndef __ARCH_PPC64_CACHE_H
 #define __ARCH_PPC64_CACHE_H
 
+#include <asm/types.h>
+
 /* bytes per L1 cache line */
 #define L1_CACHE_SHIFT	7
 #define L1_CACHE_BYTES	(1 << L1_CACHE_SHIFT)
 
 #define SMP_CACHE_BYTES L1_CACHE_BYTES
 #define L1_CACHE_SHIFT_MAX 7	/* largest L1 which this arch supports */
+
+#ifndef __ASSEMBLY__
+
+struct ppc64_caches {
+	u32	dsize;			/* L1 d-cache size */
+	u32	dline_size;		/* L1 d-cache line size	*/
+	u32	log_dline_size;
+	u32	dlines_per_page;
+	u32	isize;			/* L1 i-cache size */
+	u32	iline_size;		/* L1 i-cache line size	*/
+	u32	log_iline_size;
+	u32	ilines_per_page;
+};
+
+extern struct ppc64_caches ppc64_caches;
+
+#endif
 
 #endif
diff -Nru a/include/asm-ppc64/cacheflush.h b/include/asm-ppc64/cacheflush.h
--- a/include/asm-ppc64/cacheflush.h	2005-03-01 23:38:52 -08:00
+++ b/include/asm-ppc64/cacheflush.h	2005-03-01 23:38:52 -08:00
@@ -40,7 +40,7 @@
 
 static inline void flush_icache_range(unsigned long start, unsigned long stop)
 {
-	if (!(cur_cpu_spec->cpu_features & ASM_CONST(CPU_FTR_COHERENT_ICACHE)))
+	if (!(cur_cpu_spec->cpu_features & CPU_FTR_COHERENT_ICACHE))
 		__flush_icache_range(start, stop);
 }
 
diff -Nru a/include/asm-ppc64/cputable.h b/include/asm-ppc64/cputable.h
--- a/include/asm-ppc64/cputable.h	2005-03-01 23:39:08 -08:00
+++ b/include/asm-ppc64/cputable.h	2005-03-01 23:39:08 -08:00
@@ -16,6 +16,7 @@
 #define __ASM_PPC_CPUTABLE_H
 
 #include <linux/config.h>
+#include <asm/page.h> /* for ASM_CONST */
 
 /* Exposed to userland CPU features - Must match ppc32 definitions */
 #define PPC_FEATURE_32			0x80000000
@@ -103,38 +104,38 @@
 /* CPU kernel features */
 
 /* Retain the 32b definitions for the time being - use bottom half of word */
-#define CPU_FTR_SPLIT_ID_CACHE		0x0000000000000001
-#define CPU_FTR_L2CR			0x0000000000000002
-#define CPU_FTR_SPEC7450		0x0000000000000004
-#define CPU_FTR_ALTIVEC			0x0000000000000008
-#define CPU_FTR_TAU			0x0000000000000010
-#define CPU_FTR_CAN_DOZE		0x0000000000000020
-#define CPU_FTR_USE_TB			0x0000000000000040
-#define CPU_FTR_604_PERF_MON		0x0000000000000080
-#define CPU_FTR_601			0x0000000000000100
-#define CPU_FTR_HPTE_TABLE		0x0000000000000200
-#define CPU_FTR_CAN_NAP			0x0000000000000400
-#define CPU_FTR_L3CR			0x0000000000000800
-#define CPU_FTR_L3_DISABLE_NAP		0x0000000000001000
-#define CPU_FTR_NAP_DISABLE_L2_PR	0x0000000000002000
-#define CPU_FTR_DUAL_PLL_750FX		0x0000000000004000
+#define CPU_FTR_SPLIT_ID_CACHE		ASM_CONST(0x0000000000000001)
+#define CPU_FTR_L2CR			ASM_CONST(0x0000000000000002)
+#define CPU_FTR_SPEC7450		ASM_CONST(0x0000000000000004)
+#define CPU_FTR_ALTIVEC			ASM_CONST(0x0000000000000008)
+#define CPU_FTR_TAU			ASM_CONST(0x0000000000000010)
+#define CPU_FTR_CAN_DOZE		ASM_CONST(0x0000000000000020)
+#define CPU_FTR_USE_TB			ASM_CONST(0x0000000000000040)
+#define CPU_FTR_604_PERF_MON		ASM_CONST(0x0000000000000080)
+#define CPU_FTR_601			ASM_CONST(0x0000000000000100)
+#define CPU_FTR_HPTE_TABLE		ASM_CONST(0x0000000000000200)
+#define CPU_FTR_CAN_NAP			ASM_CONST(0x0000000000000400)
+#define CPU_FTR_L3CR			ASM_CONST(0x0000000000000800)
+#define CPU_FTR_L3_DISABLE_NAP		ASM_CONST(0x0000000000001000)
+#define CPU_FTR_NAP_DISABLE_L2_PR	ASM_CONST(0x0000000000002000)
+#define CPU_FTR_DUAL_PLL_750FX		ASM_CONST(0x0000000000004000)
 
 /* Add the 64b processor unique features in the top half of the word */
-#define CPU_FTR_SLB           		0x0000000100000000
-#define CPU_FTR_16M_PAGE      		0x0000000200000000
-#define CPU_FTR_TLBIEL         		0x0000000400000000
-#define CPU_FTR_NOEXECUTE     		0x0000000800000000
-#define CPU_FTR_NODSISRALIGN  		0x0000001000000000
-#define CPU_FTR_IABR  			0x0000002000000000
-#define CPU_FTR_MMCRA  			0x0000004000000000
-#define CPU_FTR_PMC8  			0x0000008000000000
-#define CPU_FTR_SMT  			0x0000010000000000
-#define CPU_FTR_COHERENT_ICACHE  	0x0000020000000000
-#define CPU_FTR_LOCKLESS_TLBIE		0x0000040000000000
-#define CPU_FTR_MMCRA_SIHV		0x0000080000000000
+#define CPU_FTR_SLB           		ASM_CONST(0x0000000100000000)
+#define CPU_FTR_16M_PAGE      		ASM_CONST(0x0000000200000000)
+#define CPU_FTR_TLBIEL         		ASM_CONST(0x0000000400000000)
+#define CPU_FTR_NOEXECUTE     		ASM_CONST(0x0000000800000000)
+#define CPU_FTR_NODSISRALIGN  		ASM_CONST(0x0000001000000000)
+#define CPU_FTR_IABR  			ASM_CONST(0x0000002000000000)
+#define CPU_FTR_MMCRA  			ASM_CONST(0x0000004000000000)
+#define CPU_FTR_PMC8  			ASM_CONST(0x0000008000000000)
+#define CPU_FTR_SMT  			ASM_CONST(0x0000010000000000)
+#define CPU_FTR_COHERENT_ICACHE  	ASM_CONST(0x0000020000000000)
+#define CPU_FTR_LOCKLESS_TLBIE		ASM_CONST(0x0000040000000000)
+#define CPU_FTR_MMCRA_SIHV		ASM_CONST(0x0000080000000000)
 
 /* Platform firmware features */
-#define FW_FTR_                         0x0000000000000001
+#define FW_FTR_				ASM_CONST(0x0000000000000001)
 
 #ifndef __ASSEMBLY__
 #define COMMON_USER_PPC64	(PPC_FEATURE_32 | PPC_FEATURE_64 | \
diff -Nru a/include/asm-ppc64/cputime.h b/include/asm-ppc64/cputime.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-ppc64/cputime.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,6 @@
+#ifndef __PPC_CPUTIME_H
+#define __PPC_CPUTIME_H
+
+#include <asm-generic/cputime.h>
+
+#endif /* __PPC_CPUTIME_H */
diff -Nru a/include/asm-ppc64/eeh.h b/include/asm-ppc64/eeh.h
--- a/include/asm-ppc64/eeh.h	2005-03-01 23:39:16 -08:00
+++ b/include/asm-ppc64/eeh.h	2005-03-01 23:39:16 -08:00
@@ -20,28 +20,28 @@
 #ifndef _PPC64_EEH_H
 #define _PPC64_EEH_H
 
+#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/list.h>
 #include <linux/string.h>
-#include <linux/notifier.h>
 
 struct pci_dev;
 struct device_node;
+struct device_node;
+struct notifier_block;
+
+#ifdef CONFIG_EEH
 
 /* Values for eeh_mode bits in device_node */
 #define EEH_MODE_SUPPORTED	(1<<0)
 #define EEH_MODE_NOCHECK	(1<<1)
 #define EEH_MODE_ISOLATED	(1<<2)
 
-#ifdef CONFIG_PPC_PSERIES
-extern void __init eeh_init(void);
-unsigned long eeh_check_failure(const volatile void __iomem *token, unsigned long val);
-int eeh_dn_check_failure (struct device_node *dn, struct pci_dev *dev);
-void __iomem *eeh_ioremap(unsigned long addr, void __iomem *vaddr);
+void __init eeh_init(void);
+unsigned long eeh_check_failure(const volatile void __iomem *token,
+				unsigned long val);
+int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev);
 void __init pci_addr_cache_build(void);
-#else
-#define eeh_check_failure(token, val) (val)
-#endif
 
 /**
  * eeh_add_device_early
@@ -52,7 +52,6 @@
  * device (including config space i/o).  Call eeh_add_device_late
  * to finish the eeh setup for this device.
  */
-struct device_node;
 void eeh_add_device_early(struct device_node *);
 void eeh_add_device_late(struct pci_dev *);
 
@@ -69,8 +68,6 @@
 #define EEH_ENABLE		1
 #define EEH_RELEASE_LOADSTORE	2
 #define EEH_RELEASE_DMA		3
-int eeh_set_option(struct pci_dev *dev, int options);
-
 
 /**
  * Notifier event flags.
@@ -107,6 +104,18 @@
  */
 #define EEH_IO_ERROR_VALUE(size)	(~0U >> ((4 - (size)) * 8))
 
+#else
+#define eeh_init()
+#define eeh_check_failure(token, val) (val)
+#define eeh_dn_check_failure(dn, dev) (0)
+#define pci_addr_cache_build()
+#define eeh_add_device_early(dn)
+#define eeh_add_device_late(dev)
+#define eeh_remove_device(dev)
+#define EEH_POSSIBLE_ERROR(val, type) (0)
+#define EEH_IO_ERROR_VALUE(size) (-1UL)
+#endif
+
 /* 
  * MMIO read/write operations with EEH support.
  */
@@ -194,7 +203,8 @@
 #define EEH_CHECK_ALIGN(v,a) \
 	((((unsigned long)(v)) & ((a) - 1)) == 0)
 
-static inline void eeh_memset_io(volatile void __iomem *addr, int c, unsigned long n)
+static inline void eeh_memset_io(volatile void __iomem *addr, int c,
+				 unsigned long n)
 {
 	u32 lc = c;
 	lc |= lc << 8;
diff -Nru a/include/asm-ppc64/hardirq.h b/include/asm-ppc64/hardirq.h
--- a/include/asm-ppc64/hardirq.h	2005-03-01 23:38:53 -08:00
+++ b/include/asm-ppc64/hardirq.h	2005-03-01 23:38:53 -08:00
@@ -14,7 +14,6 @@
 
 typedef struct {
 	unsigned int __softirq_pending;
-	struct task_struct * __ksoftirqd_task;
 } ____cacheline_aligned irq_cpustat_t;
 
 #include <linux/irq_cpustat.h>	/* Standard mappings for irq_cpustat_t above */
diff -Nru a/include/asm-ppc64/iSeries/HvLpEvent.h b/include/asm-ppc64/iSeries/HvLpEvent.h
--- a/include/asm-ppc64/iSeries/HvLpEvent.h	2005-03-01 23:39:08 -08:00
+++ b/include/asm-ppc64/iSeries/HvLpEvent.h	2005-03-01 23:39:08 -08:00
@@ -75,6 +75,9 @@
 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 );
diff -Nru a/include/asm-ppc64/iSeries/HvReleaseData.h b/include/asm-ppc64/iSeries/HvReleaseData.h
--- a/include/asm-ppc64/iSeries/HvReleaseData.h	2005-03-01 23:39:18 -08:00
+++ b/include/asm-ppc64/iSeries/HvReleaseData.h	2005-03-01 23:39:18 -08:00
@@ -26,6 +26,7 @@
 //   address of the OS's NACA).
 //
 #include <asm/types.h>
+#include <asm/naca.h>
 
 //=============================================================================
 //
diff -Nru a/include/asm-ppc64/iSeries/ItLpPaca.h b/include/asm-ppc64/iSeries/ItLpPaca.h
--- a/include/asm-ppc64/iSeries/ItLpPaca.h	2005-03-01 23:39:09 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,134 +0,0 @@
-/*
- * ItLpPaca.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 _ITLPPACA_H
-#define _ITLPPACA_H
-
-//=============================================================================
-//                                   
-//	This control block contains the data that is shared between the 
-//	hypervisor (PLIC) and the OS.
-//    
-//
-//----------------------------------------------------------------------------
-#include <asm/types.h>
-
-struct ItLpPaca
-{
-//=============================================================================
-// CACHE_LINE_1 0x0000 - 0x007F Contains read-only data
-// NOTE: The xDynXyz fields are fields that will be dynamically changed by 
-// PLIC when preparing to bring a processor online or when dispatching a 
-// virtual processor!
-//=============================================================================
-	u32	xDesc;			// Eye catcher 0xD397D781	x00-x03
-	u16	xSize;			// Size of this struct		x04-x05
-	u16	xRsvd1_0;		// Reserved			x06-x07
-	u16	xRsvd1_1:14;		// Reserved			x08-x09
-	u8	xSharedProc:1;		// Shared processor indicator	...
-	u8	xSecondaryThread:1;	// Secondary thread indicator	...
-	volatile u8 xDynProcStatus:8;	// Dynamic Status of this proc	x0A-x0A
-	u8	xSecondaryThreadCnt;	// Secondary thread count	x0B-x0B
-	volatile u16 xDynHvPhysicalProcIndex;// Dynamic HV Physical Proc Index0C-x0D
-	volatile u16 xDynHvLogicalProcIndex;// Dynamic HV Logical Proc Indexx0E-x0F
-	u32	xDecrVal;   		// Value for Decr programming 	x10-x13
-	u32	xPMCVal;       		// Value for PMC regs         	x14-x17
-	volatile u32 xDynHwNodeId;	// Dynamic Hardware Node id	x18-x1B
-	volatile u32 xDynHwProcId;	// Dynamic Hardware Proc Id	x1C-x1F
-	volatile u32 xDynPIR;		// Dynamic ProcIdReg value	x20-x23
-	u32	xDseiData;           	// DSEI data                  	x24-x27
-	u64	xSPRG3;               	// SPRG3 value                	x28-x2F
-	u8	xRsvd1_3[80];		// Reserved			x30-x7F
-   
-//=============================================================================
-// CACHE_LINE_2 0x0080 - 0x00FF Contains local read-write data
-//=============================================================================
-	// This Dword contains a byte for each type of interrupt that can occur.  
-	// The IPI is a count while the others are just a binary 1 or 0.
-	union {
-		u64	xAnyInt;
-		struct {
-			u16	xRsvd;		// Reserved - cleared by #mpasmbl
-			u8	xXirrInt;	// Indicates xXirrValue is valid or Immed IO
-			u8	xIpiCnt;	// IPI Count
-			u8	xDecrInt;	// DECR interrupt occurred
-			u8	xPdcInt;	// PDC interrupt occurred
-			u8	xQuantumInt;	// Interrupt quantum reached
-			u8	xOldPlicDeferredExtInt;	// Old PLIC has a deferred XIRR pending
-		} xFields;
-	} xIntDword;
-
-	// Whenever any fields in this Dword are set then PLIC will defer the 
-	// processing of external interrupts.  Note that PLIC will store the 
-	// XIRR directly into the xXirrValue field so that another XIRR will 
-	// not be presented until this one clears.  The layout of the low 
-	// 4-bytes of this Dword is upto SLIC - PLIC just checks whether the 
-	// entire Dword is zero or not.  A non-zero value in the low order 
-	// 2-bytes will result in SLIC being granted the highest thread 
-	// priority upon return.  A 0 will return to SLIC as medium priority.
-	u64	xPlicDeferIntsArea;	// Entire Dword
-
-	// Used to pass the real SRR0/1 from PLIC to SLIC as well as to 
-	// pass the target SRR0/1 from SLIC to PLIC on a SetAsrAndRfid.
-	u64     xSavedSrr0;             // Saved SRR0                   x10-x17
-	u64     xSavedSrr1;             // Saved SRR1                   x18-x1F
-
-	// Used to pass parms from the OS to PLIC for SetAsrAndRfid
-	u64     xSavedGpr3;             // Saved GPR3                   x20-x27
-	u64     xSavedGpr4;             // Saved GPR4                   x28-x2F
-	u64     xSavedGpr5;             // Saved GPR5                   x30-x37
-
-	u8	xRsvd2_1;		// Reserved			x38-x38
-	u8      xCpuCtlsTaskAttributes; // Task attributes for cpuctls  x39-x39
-	u8      xFPRegsInUse;           // FP regs in use               x3A-x3A
-	u8      xPMCRegsInUse;          // PMC regs in use              x3B-x3B
-	volatile u32  xSavedDecr;	// Saved Decr Value             x3C-x3F
-	volatile u64  xEmulatedTimeBase;// Emulated TB for this thread  x40-x47
-	volatile u64  xCurPLICLatency;	// Unaccounted PLIC latency     x48-x4F
-	u64     xTotPLICLatency;        // Accumulated PLIC latency     x50-x57   
-	u64     xWaitStateCycles;       // Wait cycles for this proc    x58-x5F
-	u64     xEndOfQuantum;          // TB at end of quantum         x60-x67
-	u64     xPDCSavedSPRG1;         // Saved SPRG1 for PMC int      x68-x6F
-	u64     xPDCSavedSRR0;          // Saved SRR0 for PMC int       x70-x77
-	volatile u32 xVirtualDecr;	// Virtual DECR for shared procsx78-x7B
-	u16     xSLBCount;              // # of SLBs to maintain        x7C-x7D
-	u8      xIdle;                  // Indicate OS is idle          x7E
-	u8      xRsvd2_2;               // Reserved                     x7F
-
-
-//=============================================================================
-// CACHE_LINE_3 0x0100 - 0x007F: This line is shared with other processors
-//=============================================================================
-	// This is the xYieldCount.  An "odd" value (low bit on) means that 
-	// the processor is yielded (either because of an OS yield or a PLIC 
-	// preempt).  An even value implies that the processor is currently 
-	// executing.
-	// NOTE: This value will ALWAYS be zero for dedicated processors and 
-	// will NEVER be zero for shared processors (ie, initialized to a 1).
-	volatile u32 xYieldCount;	// PLIC increments each dispatchx00-x03
-	u8	xRsvd3_0[124];		// Reserved                     x04-x7F         
-
-//=============================================================================
-// CACHE_LINE_4-5 0x0100 - 0x01FF Contains PMC interrupt data
-//=============================================================================
-	u8      xPmcSaveArea[256];	// PMC interrupt Area           x00-xFF
-
-
-};
-
-#endif /* _ITLPPACA_H */
diff -Nru a/include/asm-ppc64/iSeries/LparData.h b/include/asm-ppc64/iSeries/LparData.h
--- a/include/asm-ppc64/iSeries/LparData.h	2005-03-01 23:38:52 -08:00
+++ b/include/asm-ppc64/iSeries/LparData.h	2005-03-01 23:38:52 -08:00
@@ -24,11 +24,8 @@
 #include <asm/page.h>
 #include <asm/abs_addr.h>
 
-#include <asm/naca.h>
 #include <asm/iSeries/ItLpNaca.h>
-#include <asm/iSeries/ItLpPaca.h>
 #include <asm/iSeries/ItLpRegSave.h>
-#include <asm/paca.h>
 #include <asm/iSeries/HvReleaseData.h>
 #include <asm/iSeries/LparMap.h>
 #include <asm/iSeries/ItVpdAreas.h>
diff -Nru a/include/asm-ppc64/iSeries/iSeries_VpdInfo.h b/include/asm-ppc64/iSeries/iSeries_VpdInfo.h
--- a/include/asm-ppc64/iSeries/iSeries_VpdInfo.h	2005-03-01 23:39:09 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,56 +0,0 @@
-#ifndef _ISERIES_VPDINFO_H
-#define _ISERIES_VPDINFO_H
-/************************************************************************/
-/* File iSeries_VpdInfo.h created by Allan Trautman Feb 08 2001.        */
-/************************************************************************/
-/* This code supports the location data fon 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, Feg  8, 2001                                              */
-/*   Reformated for Card, March 8, 2001                                 */
-/* End Change Activity                                                  */
-/************************************************************************/
-
-struct pci_dev; 		/* Forward Declare                      */
-/************************************************************************/
-/* Location Data extracted from the VPD list and device info.           */
-/************************************************************************/
-struct LocationDataStruct {	/* Location data structure for device   */
-	u16  Bus;		/* iSeries Bus Number		    0x00*/
-	u16  Board;		/* iSeries Board                    0x02*/
-	u8   FrameId;		/* iSeries spcn Frame Id            0x04*/
-	u8   PhbId;		/* iSeries Phb Location             0x05*/
-	u16  Card;		/* iSeries Card Slot                0x06*/
-	char CardLocation[4];	/* Char format of planar vpd        0x08*/
-	u8   AgentId;		/* iSeries AgentId                  0x0C*/
-	u8   SecondaryAgentId;	/* iSeries Secondary Agent Id       0x0D*/
-	u8   LinuxBus;		/* Linux Bus Number                 0x0E*/
-	u8   LinuxDevFn;	/* Linux Device Function            0x0F*/
-};
-typedef struct LocationDataStruct  LocationData;
-#define LOCATION_DATA_SIZE      16
-
-/************************************************************************/
-/* Protypes                                                             */
-/************************************************************************/
-extern LocationData* iSeries_GetLocationData(struct pci_dev* PciDev);
-extern int           iSeries_Device_Information(struct pci_dev*,char*, int);
-
-#endif /* _ISERIES_VPDINFO_H */
diff -Nru a/include/asm-ppc64/iSeries/iSeries_pci.h b/include/asm-ppc64/iSeries/iSeries_pci.h
--- a/include/asm-ppc64/iSeries/iSeries_pci.h	2005-03-01 23:38:52 -08:00
+++ b/include/asm-ppc64/iSeries/iSeries_pci.h	2005-03-01 23:38:52 -08:00
@@ -102,27 +102,9 @@
 };
 
 /************************************************************************/
-/* Location Data extracted from the VPD list and device info.           */
-/************************************************************************/
-
-struct LocationDataStruct { 	/* Location data structure for device  */
-	u16  Bus;               /* iSeries Bus Number              0x00*/
-	u16  Board;             /* iSeries Board                   0x02*/
-	u8   FrameId;           /* iSeries spcn Frame Id           0x04*/
-	u8   PhbId;             /* iSeries Phb Location            0x05*/
-	u8   AgentId;           /* iSeries AgentId                 0x06*/
-	u8   Card;
-	char CardLocation[4];      
-};
-
-typedef struct LocationDataStruct  LocationData;
-#define LOCATION_DATA_SIZE      48
-
-/************************************************************************/
 /* Functions                                                            */
 /************************************************************************/
 
-extern LocationData* iSeries_GetLocationData(struct pci_dev* PciDev);
 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);
diff -Nru a/include/asm-ppc64/io.h b/include/asm-ppc64/io.h
--- a/include/asm-ppc64/io.h	2005-03-01 23:39:16 -08:00
+++ b/include/asm-ppc64/io.h	2005-03-01 23:39:16 -08:00
@@ -1,4 +1,4 @@
- #ifndef _PPC64_IO_H
+#ifndef _PPC64_IO_H
 #define _PPC64_IO_H
 
 /* 
@@ -371,7 +371,7 @@
 {
 	unsigned long ret;
 
-	__asm__ __volatile__("ld %0,0(%1); twi 0,%0,0; isync"
+	__asm__ __volatile__("ld%U1%X1 %0,%1; twi 0,%0,0; isync"
 			     : "=r" (ret) : "m" (*addr));
 	return ret;
 }
diff -Nru a/include/asm-ppc64/iommu.h b/include/asm-ppc64/iommu.h
--- a/include/asm-ppc64/iommu.h	2005-03-01 23:39:08 -08:00
+++ b/include/asm-ppc64/iommu.h	2005-03-01 23:39:08 -08:00
@@ -69,18 +69,16 @@
 
 struct iommu_table {
 	unsigned long  it_busno;     /* Bus number this table belongs to */
-	unsigned long  it_size;      /* Size in pages of iommu table */
+	unsigned long  it_size;      /* Size of iommu table in entries */
 	unsigned long  it_offset;    /* Offset into global table */
 	unsigned long  it_base;      /* mapped address of tce table */
 	unsigned long  it_index;     /* which iommu table this is */
 	unsigned long  it_type;      /* type: PCI or Virtual Bus */
-	unsigned long  it_entrysize; /* Size of an entry in bytes */
 	unsigned long  it_blocksize; /* Entries in each block (cacheline) */
 	unsigned long  it_hint;      /* Hint for next alloc */
 	unsigned long  it_largehint; /* Hint for large allocs */
 	unsigned long  it_halfpoint; /* Breaking point for small/large allocs */
 	spinlock_t     it_lock;      /* Protects it_map */
-	unsigned long  it_mapsize;   /* Size of map in # of entries (bits) */
 	unsigned long *it_map;       /* A simple allocation bitmap for now */
 };
 
@@ -156,14 +154,13 @@
 extern void iommu_unmap_single(struct iommu_table *tbl, dma_addr_t dma_handle,
 		size_t size, enum dma_data_direction direction);
 
-extern void tce_init_pSeries(void);
-extern void tce_init_iSeries(void);
+extern void iommu_init_early_pSeries(void);
+extern void iommu_init_early_iSeries(void);
+extern void iommu_init_early_u3(void);
 
 extern void pci_iommu_init(void);
-extern void pci_dma_init_direct(void);
+extern void pci_direct_iommu_init(void);
 
 extern void alloc_u3_dart_table(void);
-
-extern int ppc64_iommu_off;
 
 #endif /* _ASM_IOMMU_H */
diff -Nru a/include/asm-ppc64/irq.h b/include/asm-ppc64/irq.h
--- a/include/asm-ppc64/irq.h	2005-03-01 23:39:17 -08:00
+++ b/include/asm-ppc64/irq.h	2005-03-01 23:39:17 -08:00
@@ -87,6 +87,8 @@
 	return irq;
 }
 
+extern int distribute_irqs;
+
 struct irqaction;
 struct pt_regs;
 
diff -Nru a/include/asm-ppc64/kdebug.h b/include/asm-ppc64/kdebug.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-ppc64/kdebug.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,43 @@
+#ifndef _PPC64_KDEBUG_H
+#define _PPC64_KDEBUG_H 1
+
+/* nearly identical to x86_64/i386 code */
+
+#include <linux/notifier.h>
+
+struct pt_regs;
+
+struct die_args {
+	struct pt_regs *regs;
+	const char *str;
+	long err;
+	int trapnr;
+	int signr;
+};
+
+/*
+   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.
+ */
+int register_die_notifier(struct notifier_block *nb);
+extern struct notifier_block *ppc64_die_chain;
+
+/* Grossly misnamed. */
+enum die_val {
+	DIE_OOPS = 1,
+	DIE_IABR_MATCH,
+	DIE_DABR_MATCH,
+	DIE_BPT,
+	DIE_SSTEP,
+	DIE_GPF,
+	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(&ppc64_die_chain, val, &args);
+}
+
+#endif
diff -Nru a/include/asm-ppc64/kprobes.h b/include/asm-ppc64/kprobes.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-ppc64/kprobes.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,56 @@
+#ifndef _ASM_KPROBES_H
+#define _ASM_KPROBES_H
+/*
+ *  Kernel Probes (KProbes)
+ *  include/asm-ppc64/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
+ *
+ * 2002-Oct	Created by Vamsi Krishna S <vamsi_krishna@in.ibm.com> Kernel
+ *		Probes initial implementation ( includes suggestions from
+ *		Rusty Russell).
+ * 2004-Nov	Modified for PPC64 by Ananth N Mavinakayanahalli
+ *		<ananth@in.ibm.com>
+ */
+#include <linux/types.h>
+#include <linux/ptrace.h>
+
+struct pt_regs;
+
+typedef unsigned int kprobe_opcode_t;
+#define BREAKPOINT_INSTRUCTION	0x7fe00008	/* trap */
+#define MAX_INSN_SIZE 1
+
+#define JPROBE_ENTRY(pentry)	(kprobe_opcode_t *)((func_descr_t *)pentry)
+
+/* Architecture specific copy of original instruction */
+struct arch_specific_insn {
+	/* copy of original instruction */
+	kprobe_opcode_t insn[MAX_INSN_SIZE];
+};
+
+#ifdef CONFIG_KPROBES
+extern int kprobe_exceptions_notify(struct notifier_block *self,
+				    unsigned long val, void *data);
+#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 -Nru a/include/asm-ppc64/lppaca.h b/include/asm-ppc64/lppaca.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-ppc64/lppaca.h	2005-03-01 23:39:09 -08:00
@@ -0,0 +1,132 @@
+/*
+ * lppaca.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 _ASM_LPPACA_H
+#define _ASM_LPPACA_H
+
+//=============================================================================
+//
+//	This control block contains the data that is shared between the
+//	hypervisor (PLIC) and the OS.
+//
+//
+//----------------------------------------------------------------------------
+#include <asm/types.h>
+
+struct lppaca
+{
+//=============================================================================
+// CACHE_LINE_1 0x0000 - 0x007F Contains read-only data
+// NOTE: The xDynXyz fields are fields that will be dynamically changed by
+// PLIC when preparing to bring a processor online or when dispatching a
+// virtual processor!
+//=============================================================================
+	u32	desc;			// Eye catcher 0xD397D781	x00-x03
+	u16	size;			// Size of this struct		x04-x05
+	u16	reserved1;		// Reserved			x06-x07
+	u16	reserved2:14;		// Reserved			x08-x09
+	u8	shared_proc:1;		// Shared processor indicator	...
+	u8	secondary_thread:1;	// Secondary thread indicator	...
+	volatile u8 dyn_proc_status:8;	// Dynamic Status of this proc	x0A-x0A
+	u8	secondary_thread_count;	// Secondary thread count	x0B-x0B
+	volatile u16 dyn_hv_phys_proc_index;// Dynamic HV Physical Proc Index0C-x0D
+	volatile u16 dyn_hv_log_proc_index;// Dynamic HV Logical Proc Indexx0E-x0F
+	u32	decr_val;   		// Value for Decr programming 	x10-x13
+	u32	pmc_val;       		// Value for PMC regs         	x14-x17
+	volatile u32 dyn_hw_node_id;	// Dynamic Hardware Node id	x18-x1B
+	volatile u32 dyn_hw_proc_id;	// Dynamic Hardware Proc Id	x1C-x1F
+	volatile u32 dyn_pir;		// Dynamic ProcIdReg value	x20-x23
+	u32	dsei_data;           	// DSEI data                  	x24-x27
+	u64	sprg3;               	// SPRG3 value                	x28-x2F
+	u8	reserved3[80];		// Reserved			x30-x7F
+
+//=============================================================================
+// CACHE_LINE_2 0x0080 - 0x00FF Contains local read-write data
+//=============================================================================
+	// This Dword contains a byte for each type of interrupt that can occur.
+	// The IPI is a count while the others are just a binary 1 or 0.
+	union {
+		u64	any_int;
+		struct {
+			u16	reserved;	// Reserved - cleared by #mpasmbl
+			u8	xirr_int;	// Indicates xXirrValue is valid or Immed IO
+			u8	ipi_cnt;	// IPI Count
+			u8	decr_int;	// DECR interrupt occurred
+			u8	pdc_int;	// PDC interrupt occurred
+			u8	quantum_int;	// Interrupt quantum reached
+			u8	old_plic_deferred_ext_int;	// Old PLIC has a deferred XIRR pending
+		} fields;
+	} int_dword;
+
+	// Whenever any fields in this Dword are set then PLIC will defer the
+	// processing of external interrupts.  Note that PLIC will store the
+	// XIRR directly into the xXirrValue field so that another XIRR will
+	// not be presented until this one clears.  The layout of the low
+	// 4-bytes of this Dword is upto SLIC - PLIC just checks whether the
+	// entire Dword is zero or not.  A non-zero value in the low order
+	// 2-bytes will result in SLIC being granted the highest thread
+	// priority upon return.  A 0 will return to SLIC as medium priority.
+	u64	plic_defer_ints_area;	// Entire Dword
+
+	// Used to pass the real SRR0/1 from PLIC to SLIC as well as to
+	// pass the target SRR0/1 from SLIC to PLIC on a SetAsrAndRfid.
+	u64	saved_srr0;		// Saved SRR0                   x10-x17
+	u64	saved_srr1;		// Saved SRR1                   x18-x1F
+
+	// Used to pass parms from the OS to PLIC for SetAsrAndRfid
+	u64	saved_gpr3;		// Saved GPR3                   x20-x27
+	u64	saved_gpr4;		// Saved GPR4                   x28-x2F
+	u64	saved_gpr5;		// Saved GPR5                   x30-x37
+
+	u8	reserved4;		// Reserved			x38-x38
+	u8	cpuctls_task_attrs;	// Task attributes for cpuctls  x39-x39
+	u8	fpregs_in_use;		// FP regs in use               x3A-x3A
+	u8	pmcregs_in_use;		// PMC regs in use              x3B-x3B
+	volatile u32 saved_decr;	// Saved Decr Value             x3C-x3F
+	volatile u64 emulated_time_base;// Emulated TB for this thread  x40-x47
+	volatile u64 cur_plic_latency;	// Unaccounted PLIC latency     x48-x4F
+	u64	tot_plic_latency;	// Accumulated PLIC latency     x50-x57
+	u64	wait_state_cycles;	// Wait cycles for this proc    x58-x5F
+	u64	end_of_quantum;		// TB at end of quantum         x60-x67
+	u64	pdc_saved_sprg1;	// Saved SPRG1 for PMC int      x68-x6F
+	u64	pdc_saved_srr0;		// Saved SRR0 for PMC int       x70-x77
+	volatile u32 virtual_decr;	// Virtual DECR for shared procsx78-x7B
+	u16	slb_count;		// # of SLBs to maintain        x7C-x7D
+	u8	idle;			// Indicate OS is idle          x7E
+	u8	reserved5;		// Reserved                     x7F
+
+
+//=============================================================================
+// CACHE_LINE_3 0x0100 - 0x007F: This line is shared with other processors
+//=============================================================================
+	// This is the yield_count.  An "odd" value (low bit on) means that
+	// the processor is yielded (either because of an OS yield or a PLIC
+	// preempt).  An even value implies that the processor is currently
+	// executing.
+	// NOTE: This value will ALWAYS be zero for dedicated processors and
+	// will NEVER be zero for shared processors (ie, initialized to a 1).
+	volatile u32 yield_count;	// PLIC increments each dispatchx00-x03
+	u8	reserved6[124];		// Reserved                     x04-x7F
+
+//=============================================================================
+// CACHE_LINE_4-5 0x0100 - 0x01FF Contains PMC interrupt data
+//=============================================================================
+	u8	pmc_save_area[256];	// PMC interrupt Area           x00-xFF
+};
+
+#endif /* _ASM_LPPACA_H */
diff -Nru a/include/asm-ppc64/machdep.h b/include/asm-ppc64/machdep.h
--- a/include/asm-ppc64/machdep.h	2005-03-01 23:38:54 -08:00
+++ b/include/asm-ppc64/machdep.h	2005-03-01 23:38:54 -08:00
@@ -28,9 +28,10 @@
 	int   (*probe)(void);
 	void  (*kick_cpu)(int nr);
 	void  (*setup_cpu)(int nr);
-	void  (*late_setup_cpu)(int nr);
 	void  (*take_timebase)(void);
 	void  (*give_timebase)(void);
+	int   (*cpu_disable)(void);
+	void  (*cpu_die)(unsigned int nr);
 };
 #endif
 
@@ -70,6 +71,8 @@
 				    long index,
 				    long npages);
 	void		(*tce_flush)(struct iommu_table *tbl);
+	void		(*iommu_dev_setup)(struct pci_dev *dev);
+	void		(*iommu_bus_setup)(struct pci_bus *bus);
 
 	int		(*probe)(int platform);
 	void		(*setup_arch)(void);
@@ -109,6 +112,10 @@
 	ssize_t		(*nvram_read)(char *buf, size_t count, loff_t *index);	
 	ssize_t		(*nvram_size)(void);		
 	int		(*nvram_sync)(void);
+
+	/* Exception handlers */
+	void		(*system_reset_exception)(struct pt_regs *regs);
+	int 		(*machine_check_exception)(struct pt_regs *regs);
 
 	/* Motherboard/chipset features. This is a kind of general purpose
 	 * hook used to control some machine specific features (like reset
diff -Nru a/include/asm-ppc64/mmu.h b/include/asm-ppc64/mmu.h
--- a/include/asm-ppc64/mmu.h	2005-03-01 23:39:07 -08:00
+++ b/include/asm-ppc64/mmu.h	2005-03-01 23:39:07 -08:00
@@ -98,15 +98,8 @@
 #define PP_RXRX 3	/* Supervisor read,       User read */
 
 
-typedef struct {
-	HPTE *		htab;
-	unsigned long	htab_num_ptegs;
-	unsigned long	htab_hash_mask;
-	unsigned long	next_round_robin;
-	unsigned long   last_kernel_address;
-} HTAB;
-
-extern HTAB htab_data;
+extern HPTE *		htab_address;
+extern unsigned long	htab_hash_mask;
 
 static inline unsigned long hpt_hash(unsigned long vpn, int large)
 {
@@ -129,10 +122,13 @@
 	/* clear top 16 bits, non SLS segment */
 	va &= ~(0xffffULL << 48);
 
-	if (large)
+	if (large) {
+		va &= HPAGE_MASK;
 		asm volatile("tlbie %0,1" : : "r"(va) : "memory");
-	else
+	} else {
+		va &= PAGE_MASK;
 		asm volatile("tlbie %0,0" : : "r"(va) : "memory");
+	}
 }
 
 static inline void tlbie(unsigned long va, int large)
@@ -146,6 +142,7 @@
 {
 	/* clear top 16 bits, non SLS segment */
 	va &= ~(0xffffULL << 48);
+	va &= PAGE_MASK;
 
 	/* 
 	 * Thanks to Alan Modra we are now able to use machine specific 
diff -Nru a/include/asm-ppc64/mmu_context.h b/include/asm-ppc64/mmu_context.h
--- a/include/asm-ppc64/mmu_context.h	2005-03-01 23:38:55 -08:00
+++ b/include/asm-ppc64/mmu_context.h	2005-03-01 23:38:55 -08:00
@@ -51,20 +51,17 @@
 static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
 			     struct task_struct *tsk)
 {
-#ifdef CONFIG_ALTIVEC
-	asm volatile (
- BEGIN_FTR_SECTION
-	"dssall;\n"
- END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
-	 : : );
-#endif /* CONFIG_ALTIVEC */
-
 	if (!cpu_isset(smp_processor_id(), next->cpu_vm_mask))
 		cpu_set(smp_processor_id(), next->cpu_vm_mask);
 
 	/* No need to flush userspace segments if the mm doesnt change */
 	if (prev == next)
 		return;
+
+#ifdef CONFIG_ALTIVEC
+	if (cur_cpu_spec->cpu_features & CPU_FTR_ALTIVEC)
+		asm volatile ("dssall");
+#endif /* CONFIG_ALTIVEC */
 
 	if (cur_cpu_spec->cpu_features & CPU_FTR_SLB)
 		switch_slb(tsk, next);
diff -Nru a/include/asm-ppc64/naca.h b/include/asm-ppc64/naca.h
--- a/include/asm-ppc64/naca.h	2005-03-01 23:38:57 -08:00
+++ b/include/asm-ppc64/naca.h	2005-03-01 23:38:57 -08:00
@@ -11,41 +11,21 @@
  */
 
 #include <asm/types.h>
-#include <asm/systemcfg.h>
 
 #ifndef __ASSEMBLY__
 
 struct naca_struct {
-	/*==================================================================
-	 * Cache line 1: 0x0000 - 0x007F
-	 * Kernel only data - undefined for user space
-	 *==================================================================
-	 */
+	/* Kernel only data - undefined for user space */
 	void *xItVpdAreas;              /* VPD Data                  0x00 */
 	void *xRamDisk;                 /* iSeries ramdisk           0x08 */
 	u64   xRamDiskSize;		/* In pages                  0x10 */
-	struct paca_struct *paca;	/* Ptr to an array of pacas  0x18 */
-	u64 debug_switch;		/* Debug print control       0x20 */
-	u64 banner;                     /* Ptr to banner string      0x28 */
-	u64 log;                        /* Ptr to log buffer         0x30 */
-	u64 serialPortAddr;		/* Phy addr of serial port   0x38 */
-	u64 interrupt_controller;	/* Type of int controller    0x40 */ 
-	u64 unused1;			/* was SLB size in entries   0x48 */
-	u64 pftSize;			/* Log 2 of page table size  0x50 */
-	void *systemcfg;		/* Pointer to systemcfg data 0x58 */
-	u32 dCacheL1LogLineSize;	/* L1 d-cache line size Log2 0x60 */
-	u32 dCacheL1LinesPerPage;	/* L1 d-cache lines / page   0x64 */
-	u32 iCacheL1LogLineSize;	/* L1 i-cache line size Log2 0x68 */
-	u32 iCacheL1LinesPerPage;	/* L1 i-cache lines / page   0x6c */
-	u8  resv0[15];                  /* Reserved           0x71 - 0x7F */
 };
 
-extern struct naca_struct *naca;
+extern struct naca_struct naca;
 
 #endif /* __ASSEMBLY__ */
 
 #define NACA_PAGE      0x4
 #define NACA_PHYS_ADDR (NACA_PAGE<<PAGE_SHIFT)
-#define NACA_VIRT_ADDR (KERNELBASE+NACA_PHYS_ADDR)
 
 #endif /* _NACA_H */
diff -Nru a/include/asm-ppc64/paca.h b/include/asm-ppc64/paca.h
--- a/include/asm-ppc64/paca.h	2005-03-01 23:38:56 -08:00
+++ b/include/asm-ppc64/paca.h	2005-03-01 23:38:56 -08:00
@@ -18,7 +18,7 @@
 
 #include	<linux/config.h>
 #include	<asm/types.h>
-#include	<asm/iSeries/ItLpPaca.h>
+#include	<asm/lppaca.h>
 #include	<asm/iSeries/ItLpRegSave.h>
 #include	<asm/mmu.h>
 
@@ -34,8 +34,8 @@
  *
  * This structure is not directly accessed by firmware or the service
  * processor except for the first two pointers that point to the
- * ItLpPaca area and the ItLpRegSave area for this CPU.  Both the
- * ItLpPaca and ItLpRegSave objects are currently contained within the
+ * lppaca area and the ItLpRegSave area for this CPU.  Both the
+ * lppaca and ItLpRegSave objects are currently contained within the
  * PACA but they do not need to be.
  */
 struct paca_struct {
@@ -50,7 +50,7 @@
 	 * MAGIC: These first two pointers can't be moved - they're
 	 * accessed by the firmware
 	 */
-	struct ItLpPaca *lppaca_ptr;	/* Pointer to LpPaca for PLIC */
+	struct lppaca *lppaca_ptr;	/* Pointer to LpPaca for PLIC */
 	struct ItLpRegSave *reg_save_ptr; /* Pointer to LpRegSave for PLIC */
 
 	/*
@@ -68,7 +68,7 @@
 	u64 stab_real;			/* Absolute address of segment table */
 	u64 stab_addr;			/* Virtual address of segment table */
 	void *emergency_sp;		/* pointer to emergency stack */
-	u16 hw_cpu_id;			/* Physical processor number */
+	s16 hw_cpu_id;			/* Physical processor number */
 	u8 cpu_start;			/* At startup, processor spins until */
 					/* this becomes non-zero. */
 
@@ -109,7 +109,7 @@
 	 * alignment will suffice to ensure that it doesn't
 	 * cross a page boundary.
 	 */
-	struct ItLpPaca lppaca __attribute__((__aligned__(0x400)));
+	struct lppaca lppaca __attribute__((__aligned__(0x400)));
 #ifdef CONFIG_PPC_ISERIES
 	struct ItLpRegSave reg_save;
 #endif
diff -Nru a/include/asm-ppc64/page.h b/include/asm-ppc64/page.h
--- a/include/asm-ppc64/page.h	2005-03-01 23:38:44 -08:00
+++ b/include/asm-ppc64/page.h	2005-03-01 23:38:44 -08:00
@@ -93,7 +93,7 @@
 
 #ifdef __KERNEL__
 #ifndef __ASSEMBLY__
-#include <asm/naca.h>
+#include <asm/cache.h>
 
 #undef STRICT_MM_TYPECHECKS
 
@@ -106,8 +106,8 @@
 {
 	unsigned long lines, line_size;
 
-	line_size = systemcfg->dCacheL1LineSize; 
-	lines = naca->dCacheL1LinesPerPage;
+	line_size = ppc64_caches.dline_size;
+	lines = ppc64_caches.dlines_per_page;
 
 	__asm__ __volatile__(
 	"mtctr  	%1	# clear_page\n\
@@ -183,6 +183,8 @@
 
 extern int page_is_ram(unsigned long pfn);
 
+extern u64 ppc64_pft_size;		/* Log 2 of page table size */
+
 #endif /* __ASSEMBLY__ */
 
 #ifdef MODULE
@@ -203,10 +205,8 @@
 #define KERNELBASE      PAGE_OFFSET
 #define VMALLOCBASE     ASM_CONST(0xD000000000000000)
 #define IOREGIONBASE    ASM_CONST(0xE000000000000000)
-#define EEHREGIONBASE   ASM_CONST(0xA000000000000000)
 
 #define IO_REGION_ID       (IOREGIONBASE>>REGION_SHIFT)
-#define EEH_REGION_ID      (EEHREGIONBASE>>REGION_SHIFT)
 #define VMALLOC_REGION_ID  (VMALLOCBASE>>REGION_SHIFT)
 #define KERNEL_REGION_ID   (KERNELBASE>>REGION_SHIFT)
 #define USER_REGION_ID     (0UL)
diff -Nru a/include/asm-ppc64/pci-bridge.h b/include/asm-ppc64/pci-bridge.h
--- a/include/asm-ppc64/pci-bridge.h	2005-03-01 23:38:52 -08:00
+++ b/include/asm-ppc64/pci-bridge.h	2005-03-01 23:38:52 -08:00
@@ -11,18 +11,10 @@
  * 2 of the License, or (at your option) any later version.
  */
 
-struct device_node;
-struct pci_controller;
-
-/* Get the PCI host controller for an OF device */
-extern struct pci_controller*
-pci_find_hose_for_OF_device(struct device_node* node);
-
 /*
  * Structure of a PCI controller (host bridge)
  */
 struct pci_controller {
-	char what[8];                     /* Eye catcher      */
 	struct pci_bus *bus;
 	char is_dynamic;
 	void *arch_data;
@@ -49,7 +41,6 @@
 	 */
 	struct resource io_resource;
 	struct resource mem_resources[3];
-	int mem_resource_count;
 	int global_number;		
 	int local_number;		
 	unsigned long buid;
@@ -57,14 +48,6 @@
 	unsigned long dma_window_size;
 };
 
-/*
- * pci_device_loc returns the bus number and device/function number
- * for a device on a PCI bus, given its device_node struct.
- * It returns 0 if OK, -1 on error.
- */
-extern int pci_device_loc(struct device_node *dev, unsigned char *bus_ptr,
-			  unsigned char *devfn_ptr);
-
 struct device_node *fetch_dev_dn(struct pci_dev *dev);
 
 /* Get a device_node from a pci_dev.  This code must be fast except in the case
@@ -72,13 +55,22 @@
  */
 static inline struct device_node *pci_device_to_OF_node(struct pci_dev *dev)
 {
-	struct device_node *dn = (struct device_node *)(dev->sysdata);
-	if (dn->devfn == dev->devfn && dn->busno == (dev->bus->number&0xff))
+	struct device_node *dn = dev->sysdata;
+
+	if (dn->devfn == dev->devfn && dn->busno == dev->bus->number)
 		return dn;	/* fast path.  sysdata is good */
 	else
 		return fetch_dev_dn(dev);
 }
 
+static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus)
+{
+	if (bus->self)
+		return pci_device_to_OF_node(bus->self);
+	else
+		return bus->sysdata; /* Must be root bus (PHB) */
+}
+
 extern void pci_process_bridge_OF_ranges(struct pci_controller *hose,
 					 struct device_node *dev);
 
@@ -93,7 +85,6 @@
 	BUG_ON(busdn == NULL);
 	return busdn->phb;
 }
-
 
 #endif
 #endif /* __KERNEL__ */
diff -Nru a/include/asm-ppc64/pgtable.h b/include/asm-ppc64/pgtable.h
--- a/include/asm-ppc64/pgtable.h	2005-03-01 23:39:16 -08:00
+++ b/include/asm-ppc64/pgtable.h	2005-03-01 23:39:16 -08:00
@@ -1,6 +1,8 @@
 #ifndef _PPC64_PGTABLE_H
 #define _PPC64_PGTABLE_H
 
+#include <asm-generic/4level-fixup.h>
+
 /*
  * This file contains the functions and defines necessary to modify and use
  * the ppc64 hashed page table.
diff -Nru a/include/asm-ppc64/ppcdebug.h b/include/asm-ppc64/ppcdebug.h
--- a/include/asm-ppc64/ppcdebug.h	2005-03-01 23:39:18 -08:00
+++ b/include/asm-ppc64/ppcdebug.h	2005-03-01 23:39:18 -08:00
@@ -16,13 +16,14 @@
  ********************************************************************/
 
 #include <linux/config.h>
+#include <linux/types.h>
 #include <asm/udbg.h>
 #include <stdarg.h>
 
 #define PPCDBG_BITVAL(X)     ((1UL)<<((unsigned long)(X)))
 
 /* Defined below are the bit positions of various debug flags in the
- * debug_switch variable (defined in naca.h).
+ * ppc64_debug_switch variable.
  * -- When adding new values, please enter them into trace names below -- 
  *
  * Values 62 & 63 can be used to stress the hardware page table management
@@ -63,6 +64,8 @@
 /* #define PPC_DEBUG_DEFAULT    PPCDBG_ALL        */
 
 #define PPCDBG_NUM_FLAGS     64
+
+extern u64 ppc64_debug_switch;
 
 #ifdef WANT_PPCDBG_TAB
 /* A table of debug switch names to allow name lookup in xmon 
diff -Nru a/include/asm-ppc64/processor.h b/include/asm-ppc64/processor.h
--- a/include/asm-ppc64/processor.h	2005-03-01 23:38:52 -08:00
+++ b/include/asm-ppc64/processor.h	2005-03-01 23:38:52 -08:00
@@ -19,6 +19,7 @@
 #endif
 #include <asm/ptrace.h>
 #include <asm/types.h>
+#include <asm/systemcfg.h>
 
 /* Machine State Register (MSR) Fields */
 #define MSR_SF_LG	63              /* Enable 64 bit mode */
@@ -44,6 +45,7 @@
 #define MSR_DR_LG	4 		/* Data Relocate */
 #define MSR_PE_LG	3		/* Protection Enable */
 #define MSR_PX_LG	2		/* Protection Exclusive Mode */
+#define MSR_PMM_LG	2		/* Performance monitor */
 #define MSR_RI_LG	1		/* Recoverable Exception */
 #define MSR_LE_LG	0 		/* Little Endian */
 
@@ -76,6 +78,7 @@
 #define MSR_DR		__MASK(MSR_DR_LG)	/* Data Relocate */
 #define MSR_PE		__MASK(MSR_PE_LG)	/* Protection Enable */
 #define MSR_PX		__MASK(MSR_PX_LG)	/* Protection Exclusive Mode */
+#define MSR_PMM		__MASK(MSR_PMM_LG)	/* Performance monitor */
 #define MSR_RI		__MASK(MSR_RI_LG)	/* Recoverable Exception */
 #define MSR_LE		__MASK(MSR_LE_LG)	/* Little Endian */
 
@@ -305,6 +308,9 @@
 #define SPRN_SIAR	780
 #define SPRN_SDAR	781
 #define SPRN_MMCRA	786
+#define   MMCRA_SIHV	0x10000000UL /* state of MSR HV when SIAR set */
+#define   MMCRA_SIPR	0x08000000UL /* state of MSR PR when SIAR set */
+#define   MMCRA_SAMPLE_ENABLE 0x00000001UL /* enable sampling */
 #define SPRN_PMC1	787
 #define SPRN_PMC2	788
 #define SPRN_PMC3	789
@@ -314,6 +320,26 @@
 #define SPRN_PMC7	793
 #define SPRN_PMC8	794
 #define SPRN_MMCR0	795
+#define   MMCR0_FC	0x80000000UL /* freeze counters. set to 1 on a perfmon exception */
+#define   MMCR0_FCS	0x40000000UL /* freeze in supervisor state */
+#define   MMCR0_KERNEL_DISABLE MMCR0_FCS
+#define   MMCR0_FCP	0x20000000UL /* freeze in problem state */
+#define   MMCR0_PROBLEM_DISABLE MMCR0_FCP
+#define   MMCR0_FCM1	0x10000000UL /* freeze counters while MSR mark = 1 */
+#define   MMCR0_FCM0	0x08000000UL /* freeze counters while MSR mark = 0 */
+#define   MMCR0_PMXE	0x04000000UL /* performance monitor exception enable */
+#define   MMCR0_FCECE	0x02000000UL /* freeze counters on enabled condition or event */
+/* time base exception enable */
+#define   MMCR0_TBEE	0x00400000UL /* time base exception enable */
+#define   MMCR0_PMC1CE	0x00008000UL /* PMC1 count enable*/
+#define   MMCR0_PMCjCE	0x00004000UL /* PMCj count enable*/
+#define   MMCR0_TRIGGER	0x00002000UL /* TRIGGER enable */
+#define   MMCR0_PMAO	0x00000080UL /* performance monitor alert has occurred, set to 0 after handling exception */
+#define   MMCR0_SHRFC	0x00000040UL /* SHRre freeze conditions between threads */
+#define   MMCR0_FCTI	0x00000008UL /* freeze counters in tags inactive mode */
+#define   MMCR0_FCTA	0x00000004UL /* freeze counters in tags active mode */
+#define   MMCR0_FCWAIT	0x00000002UL /* freeze counter in WAIT state */
+#define   MMCR0_FCHV	0x00000001UL /* freeze conditions in hypervisor mode */
 #define SPRN_MMCR1	798
 
 /* Short-hand versions for a number of the above SPRNs */
@@ -483,6 +509,7 @@
 #ifdef __KERNEL__
 
 extern int have_of;
+extern u64 ppc64_interrupt_controller;
 
 struct task_struct;
 void start_thread(struct pt_regs *regs, unsigned long fdptr, unsigned long sp);
@@ -494,12 +521,6 @@
 /* Create a new kernel thread. */
 extern long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
 
-/*
- * Bus types
- */
-#define MCA_bus 0
-#define MCA_bus__is_a_macro /* for versions in ksyms.c */
-
 /* Lazy FPU handling on uni-processor */
 extern struct task_struct *last_task_used_math;
 extern struct task_struct *last_task_used_altivec;
@@ -515,6 +536,10 @@
 
 #define TASK_SIZE (test_thread_flag(TIF_32BIT) ? \
 		TASK_SIZE_USER32 : TASK_SIZE_USER64)
+
+/* We can't actually tell the TASK_SIZE given just the mm, but default
+ * to the 64-bit case to make sure that enough gets cleaned up. */
+#define MM_VM_SIZE(mm)	TASK_SIZE_USER64
 
 /* This decides where the kernel will search for a free chunk of vm
  * space during mmap's.
diff -Nru a/include/asm-ppc64/prom.h b/include/asm-ppc64/prom.h
--- a/include/asm-ppc64/prom.h	2005-03-01 23:39:17 -08:00
+++ b/include/asm-ppc64/prom.h	2005-03-01 23:39:17 -08:00
@@ -21,9 +21,6 @@
 #define PTRUNRELOC(x)   ((typeof(x))((unsigned long)(x) + offset))
 #define RELOC(x)        (*PTRRELOC(&(x)))
 
-#define LONG_LSW(X) (((unsigned long)X) & 0xffffffff)
-#define LONG_MSW(X) (((unsigned long)X) >> 32)
-
 /* Definitions used by the flattened device tree */
 #define OF_DT_HEADER		0xd00dfeed	/* 4: version, 4: total size */
 #define OF_DT_BEGIN_NODE	0x1		/* Start node: full name */
@@ -64,8 +61,6 @@
 
 typedef u32 phandle;
 typedef u32 ihandle;
-typedef u32 phandle32;
-typedef u32 ihandle32;
 
 struct address_range {
 	unsigned long space;
@@ -95,13 +90,6 @@
 	unsigned int size;
 };
 
-struct of_tce_table {
-	phandle node;
-	unsigned long base;
-	unsigned long size;
-};
-extern struct of_tce_table of_tce_table[];
-
 struct reg_property {
 	unsigned long address;
 	unsigned long size;
@@ -117,19 +105,6 @@
 	unsigned long size;
 };
 
-struct reg_property_pmac {
-	unsigned int address_hi;
-	unsigned int address_lo;
-	unsigned int size;
-};
-
-struct translation_property {
-	unsigned long virt;
-	unsigned long size;
-	unsigned long phys;
-	unsigned int flags;
-};
-
 struct property {
 	char	*name;
 	int	length;
@@ -160,8 +135,6 @@
 	int	busno;			/* for pci devices */
 	int	bussubno;		/* for pci devices */
 	int	devfn;			/* for pci devices */
-#define DN_STATUS_BIST_FAILED (1<<0)
-	int	status;			/* Current device status (non-zero is bad) */
 	int	eeh_mode;		/* See eeh.h for possible EEH_MODEs */
 	int	eeh_config_addr;
 	struct  pci_controller *phb;	/* for pci devices */
@@ -176,18 +149,15 @@
 	struct  proc_dir_entry *pde;       /* this node's proc directory */
 	struct  proc_dir_entry *name_link; /* name symlink */
 	struct  proc_dir_entry *addr_link; /* addr symlink */
-	atomic_t _users;                 /* reference count */
+	struct  kref kref;
 	unsigned long _flags;
 };
 
 extern struct device_node *of_chosen;
 
 /* flag descriptions */
-#define OF_STALE   0 /* node is slated for deletion */
 #define OF_DYNAMIC 1 /* node and properties were allocated via kmalloc */
 
-#define OF_IS_STALE(x) test_bit(OF_STALE, &x->_flags)
-#define OF_MARK_STALE(x) set_bit(OF_STALE, &x->_flags)
 #define OF_IS_DYNAMIC(x) test_bit(OF_DYNAMIC, &x->_flags)
 #define OF_MARK_DYNAMIC(x) set_bit(OF_DYNAMIC, &x->_flags)
 
@@ -244,7 +214,6 @@
 /* Other Prototypes */
 extern unsigned long prom_init(unsigned long, unsigned long, unsigned long,
 	unsigned long, unsigned long);
-extern void relocate_nodes(void);
 extern void finish_device_tree(void);
 extern int device_is_compatible(struct device_node *device, const char *);
 extern int machine_is_compatible(const char *compat);
diff -Nru a/include/asm-ppc64/resource.h b/include/asm-ppc64/resource.h
--- a/include/asm-ppc64/resource.h	2005-03-01 23:39:08 -08:00
+++ b/include/asm-ppc64/resource.h	2005-03-01 23:39:08 -08:00
@@ -1,57 +1,6 @@
 #ifndef _PPC64_RESOURCE_H
 #define _PPC64_RESOURCE_H
 
-/*
- * Copyright (C) 2001 PPC 64 Team, IBM Corp
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#define RLIMIT_CPU	0		/* CPU time in ms */
-#define RLIMIT_FSIZE	1		/* Maximum filesize */
-#define RLIMIT_DATA	2		/* max data size */
-#define RLIMIT_STACK	3		/* max stack size */
-#define RLIMIT_CORE	4		/* max core file size */
-#define RLIMIT_RSS	5		/* max resident set size */
-#define RLIMIT_NPROC	6		/* max number of processes */
-#define RLIMIT_NOFILE	7		/* max number of open files */
-#define RLIMIT_MEMLOCK	8		/* max locked-in-memory address space */
-#define RLIMIT_AS	9		/* address space limit(?) */
-#define RLIMIT_LOCKS	10		/* maximum file locks held */
-#define RLIMIT_SIGPENDING 11		/* max number of pending signals */
-#define RLIMIT_MSGQUEUE 12		/* maximum bytes in POSIX mqueues */
-
-#define RLIM_NLIMITS	13
-
-#ifdef __KERNEL__
-
-/*
- * SuS says limits have to be unsigned.
- * Which makes a ton more sense anyway.
- */
-#define RLIM_INFINITY	(~0UL)
-
-
-#define INIT_RLIMITS							\
-{									\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{      _STK_LIM, RLIM_INFINITY },		\
-	{             0, RLIM_INFINITY },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{             0,             0 },		\
-	{      INR_OPEN,     INR_OPEN  },		\
-	{   MLOCK_LIMIT,   MLOCK_LIMIT },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{ MAX_SIGPENDING, MAX_SIGPENDING },		\
-	{ MQ_BYTES_MAX, MQ_BYTES_MAX },			\
-}
-
-#endif /* __KERNEL__ */
+#include <asm-generic/resource.h>
 
 #endif /* _PPC64_RESOURCE_H */
diff -Nru a/include/asm-ppc64/rtas.h b/include/asm-ppc64/rtas.h
--- a/include/asm-ppc64/rtas.h	2005-03-01 23:39:17 -08:00
+++ b/include/asm-ppc64/rtas.h	2005-03-01 23:39:17 -08:00
@@ -241,4 +241,6 @@
 /* RMO buffer reserved for user-space RTAS use */
 extern unsigned long rtas_rmo_buf;
 
+#define GLOBAL_INTERRUPT_QUEUE 9005
+
 #endif /* _PPC64_RTAS_H */
diff -Nru a/include/asm-ppc64/smp.h b/include/asm-ppc64/smp.h
--- a/include/asm-ppc64/smp.h	2005-03-01 23:38:43 -08:00
+++ b/include/asm-ppc64/smp.h	2005-03-01 23:38:43 -08:00
@@ -38,7 +38,7 @@
 extern void smp_message_recv(int, struct pt_regs *);
 
 
-#define smp_processor_id() (get_paca()->paca_index)
+#define __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];
diff -Nru a/include/asm-ppc64/spinlock.h b/include/asm-ppc64/spinlock.h
--- a/include/asm-ppc64/spinlock.h	2005-03-01 23:39:18 -08:00
+++ b/include/asm-ppc64/spinlock.h	2005-03-01 23:39:18 -08:00
@@ -23,10 +23,16 @@
 
 typedef struct {
 	volatile unsigned int lock;
+#ifdef CONFIG_PREEMPT
+	unsigned int break_lock;
+#endif
 } spinlock_t;
 
 typedef struct {
 	volatile signed int lock;
+#ifdef CONFIG_PREEMPT
+	unsigned int break_lock;
+#endif
 } rwlock_t;
 
 #ifdef __KERNEL__
@@ -57,7 +63,7 @@
 
 #if defined(CONFIG_PPC_SPLPAR) || defined(CONFIG_PPC_ISERIES)
 /* We only yield to the hypervisor if we are in shared processor mode */
-#define SHARED_PROCESSOR (get_paca()->lppaca.xSharedProc)
+#define SHARED_PROCESSOR (get_paca()->lppaca.shared_proc)
 extern void __spin_yield(spinlock_t *lock);
 extern void __rw_yield(rwlock_t *lock);
 #else /* SPLPAR || ISERIES */
@@ -141,17 +147,9 @@
 #define RW_LOCK_UNLOCKED (rwlock_t) { 0 }
 
 #define rwlock_init(x)		do { *(x) = RW_LOCK_UNLOCKED; } while(0)
-#define rwlock_is_locked(x)	((x)->lock)
 
-static __inline__ int is_read_locked(rwlock_t *rw)
-{
-	return rw->lock > 0;
-}
-
-static __inline__ int is_write_locked(rwlock_t *rw)
-{
-	return rw->lock < 0;
-}
+#define read_can_lock(rw)	((rw)->lock >= 0)
+#define write_can_lock(rw)	(!(rw)->lock)
 
 static __inline__ void _raw_write_unlock(rwlock_t *rw)
 {
diff -Nru a/include/asm-ppc64/sstep.h b/include/asm-ppc64/sstep.h
--- a/include/asm-ppc64/sstep.h	2005-03-01 23:38:52 -08:00
+++ b/include/asm-ppc64/sstep.h	2005-03-01 23:38:52 -08:00
@@ -9,5 +9,16 @@
 
 struct pt_regs;
 
+/*
+ * We don't allow single-stepping an mtmsrd that would clear
+ * MSR_RI, since that would make the exception unrecoverable.
+ * Since we need to single-step to proceed from a breakpoint,
+ * we don't allow putting a breakpoint on an mtmsrd instruction.
+ * Similarly we don't allow breakpoints on rfid instructions.
+ * These macros tell us if an instruction is a mtmsrd or rfid.
+ */
+#define IS_MTMSRD(instr)	(((instr) & 0xfc0007fe) == 0x7c000164)
+#define IS_RFID(instr)		(((instr) & 0xfc0007fe) == 0x4c000024)
+
 /* Emulate instructions that cause a transfer of control. */
 extern int emulate_step(struct pt_regs *regs, unsigned int instr);
diff -Nru a/include/asm-ppc64/string.h b/include/asm-ppc64/string.h
--- a/include/asm-ppc64/string.h	2005-03-01 23:39:07 -08:00
+++ b/include/asm-ppc64/string.h	2005-03-01 23:39:07 -08:00
@@ -14,7 +14,6 @@
 #define __HAVE_ARCH_STRCMP
 #define __HAVE_ARCH_STRCAT
 #define __HAVE_ARCH_MEMSET
-#define __HAVE_ARCH_BCOPY
 #define __HAVE_ARCH_MEMCPY
 #define __HAVE_ARCH_MEMMOVE
 #define __HAVE_ARCH_MEMCMP
diff -Nru a/include/asm-ppc64/system.h b/include/asm-ppc64/system.h
--- a/include/asm-ppc64/system.h	2005-03-01 23:39:17 -08:00
+++ b/include/asm-ppc64/system.h	2005-03-01 23:39:17 -08:00
@@ -108,7 +108,6 @@
 extern void low_hash_fault(struct pt_regs *regs, unsigned long address);
 extern int die(const char *str, struct pt_regs *regs, long err);
 
-extern void flush_instruction_cache(void);
 extern int _get_PVR(void);
 extern void giveup_fpu(struct task_struct *);
 extern void disable_kernel_fp(void);
diff -Nru a/include/asm-ppc64/systemcfg.h b/include/asm-ppc64/systemcfg.h
--- a/include/asm-ppc64/systemcfg.h	2005-03-01 23:38:57 -08:00
+++ b/include/asm-ppc64/systemcfg.h	2005-03-01 23:38:57 -08:00
@@ -15,14 +15,6 @@
  * End Change Activity 
  */
 
-
-#ifndef __KERNEL__
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/mman.h>
-#include <linux/types.h>
-#endif
-
 /*
  * If the major version changes we are incompatible.
  * Minor version changes are a hint.
@@ -50,10 +42,11 @@
 	__u64 tb_update_count;		/* Timebase atomicity ctr	0x50 */
 	__u32 tz_minuteswest;		/* Minutes west of Greenwich	0x58 */
 	__u32 tz_dsttime;		/* Type of dst correction	0x5C */
-	__u32 dCacheL1Size;		/* L1 d-cache size		0x60 */
-	__u32 dCacheL1LineSize;		/* L1 d-cache line size		0x64 */
-	__u32 iCacheL1Size;		/* L1 i-cache size		0x68 */
-	__u32 iCacheL1LineSize;		/* L1 i-cache line size		0x6C */
+	/* next four are no longer used except to be exported to /proc */
+	__u32 dcache_size;		/* L1 d-cache size		0x60 */
+	__u32 dcache_line_size;		/* L1 d-cache line size		0x64 */
+	__u32 icache_size;		/* L1 i-cache size		0x68 */
+	__u32 icache_line_size;		/* L1 i-cache line size		0x6C */
 	__u8  reserved0[3984];		/* Reserve rest of page		0x70 */
 };
 
diff -Nru a/include/asm-ppc64/thread_info.h b/include/asm-ppc64/thread_info.h
--- a/include/asm-ppc64/thread_info.h	2005-03-01 23:38:52 -08:00
+++ b/include/asm-ppc64/thread_info.h	2005-03-01 23:38:52 -08:00
@@ -12,6 +12,7 @@
 
 #ifndef __ASSEMBLY__
 #include <linux/config.h>
+#include <linux/cache.h>
 #include <asm/processor.h>
 #include <asm/page.h>
 #include <linux/stringify.h>
@@ -22,12 +23,13 @@
 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;
 	struct restart_block restart_block;
 	/* set by force_successful_syscall_return */
 	unsigned char	syscall_noerror;
+	/* low level flags - has atomic operations done on it */
+	unsigned long	flags ____cacheline_aligned_in_smp;
 };
 
 /*
@@ -39,12 +41,12 @@
 {						\
 	.task =		&tsk,			\
 	.exec_domain =	&default_exec_domain,	\
-	.flags =	0,			\
 	.cpu =		0,			\
 	.preempt_count = 1,			\
 	.restart_block = {			\
 		.fn = do_no_restart_syscall,	\
 	},					\
+	.flags =	0,			\
 }
 
 #define init_thread_info	(init_thread_union.thread_info)
@@ -98,6 +100,7 @@
 #define TIF_ABI_PENDING		7	/* 32/64 bit switch needed */
 #define TIF_SYSCALL_AUDIT	8	/* syscall auditing active */
 #define TIF_SINGLESTEP		9	/* singlestepping active */
+#define TIF_MEMDIE		10
 
 /* as above, but as bit values */
 #define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE)
diff -Nru a/include/asm-ppc64/time.h b/include/asm-ppc64/time.h
--- a/include/asm-ppc64/time.h	2005-03-01 23:38:56 -08:00
+++ b/include/asm-ppc64/time.h	2005-03-01 23:38:56 -08:00
@@ -78,8 +78,8 @@
 	struct paca_struct *lpaca = get_paca();
 	int cur_dec;
 
-	if (lpaca->lppaca.xSharedProc) {
-		lpaca->lppaca.xVirtualDecr = val;
+	if (lpaca->lppaca.shared_proc) {
+		lpaca->lppaca.virtual_decr = val;
 		cur_dec = get_dec();
 		if (cur_dec > val)
 			HvCall_setVirtualDecr();
diff -Nru a/include/asm-ppc64/tlbflush.h b/include/asm-ppc64/tlbflush.h
--- a/include/asm-ppc64/tlbflush.h	2005-03-01 23:38:43 -08:00
+++ b/include/asm-ppc64/tlbflush.h	2005-03-01 23:38:43 -08:00
@@ -32,10 +32,11 @@
 
 static inline void flush_tlb_pending(void)
 {
-	struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch);
+	struct ppc64_tlb_batch *batch = &get_cpu_var(ppc64_tlb_batch);
 
 	if (batch->index)
 		__flush_tlb_pending(batch);
+	put_cpu_var(ppc64_tlb_batch);
 }
 
 #define flush_tlb_mm(mm)			flush_tlb_pending()
diff -Nru a/include/asm-ppc64/topology.h b/include/asm-ppc64/topology.h
--- a/include/asm-ppc64/topology.h	2005-03-01 23:39:17 -08:00
+++ b/include/asm-ppc64/topology.h	2005-03-01 23:39:17 -08:00
@@ -46,11 +46,13 @@
 	.max_interval		= 32,			\
 	.busy_factor		= 32,			\
 	.imbalance_pct		= 125,			\
-	.cache_hot_time		= (10*1000),		\
+	.cache_hot_time		= (10*1000000),		\
 	.cache_nice_tries	= 1,			\
 	.per_cpu_gain		= 100,			\
 	.flags			= SD_LOAD_BALANCE	\
 				| SD_BALANCE_EXEC	\
+				| SD_BALANCE_NEWIDLE	\
+				| SD_WAKE_IDLE		\
 				| SD_WAKE_BALANCE,	\
 	.last_balance		= jiffies,		\
 	.balance_interval	= 1,			\
diff -Nru a/include/asm-ppc64/uaccess.h b/include/asm-ppc64/uaccess.h
--- a/include/asm-ppc64/uaccess.h	2005-03-01 23:38:57 -08:00
+++ b/include/asm-ppc64/uaccess.h	2005-03-01 23:38:57 -08:00
@@ -244,7 +244,7 @@
 			return ret;
 		}
 	}
-	return __copy_tofrom_user((void __user *) to, from, n);
+	return __copy_tofrom_user((__force void __user *) to, from, n);
 }
 
 static inline unsigned long
@@ -269,7 +269,7 @@
 			return ret;
 		}
 	}
-	return __copy_tofrom_user(to, (const void __user *) from, n);
+	return __copy_tofrom_user(to, (__force const void __user *) from, n);
 }
 
 #define __copy_in_user(to, from, size) \
diff -Nru a/include/asm-ppc64/unistd.h b/include/asm-ppc64/unistd.h
--- a/include/asm-ppc64/unistd.h	2005-03-01 23:38:44 -08:00
+++ b/include/asm-ppc64/unistd.h	2005-03-01 23:38:44 -08:00
@@ -431,6 +431,7 @@
 #define __ARCH_WANT_SYS_SGETMASK
 #define __ARCH_WANT_SYS_SIGNAL
 #define __ARCH_WANT_SYS_TIME
+#define __ARCH_WANT_COMPAT_SYS_TIME
 #define __ARCH_WANT_SYS_UTIME
 #define __ARCH_WANT_SYS_WAITPID
 #define __ARCH_WANT_SYS_SOCKETCALL
diff -Nru a/include/asm-ppc64/xics.h b/include/asm-ppc64/xics.h
--- a/include/asm-ppc64/xics.h	2005-03-01 23:38:57 -08:00
+++ b/include/asm-ppc64/xics.h	2005-03-01 23:38:57 -08:00
@@ -18,6 +18,8 @@
 int xics_get_irq(struct pt_regs *);
 void xics_setup_cpu(void);
 void xics_cause_IPI(int cpu);
+void xics_request_IPIs(void);
+void xics_migrate_irqs_away(void);
 
 /* first argument is ignored for now*/
 void pSeriesLP_cppr_info(int n_cpu, u8 value);
@@ -27,5 +29,8 @@
 } ____cacheline_aligned;
 
 extern struct xics_ipi_struct xics_ipi_message[NR_CPUS] __cacheline_aligned;
+
+extern unsigned int default_distrib_server;
+extern unsigned int interrupt_server_size;
 
 #endif /* _PPC64_KERNEL_XICS_H */
diff -Nru a/include/asm-s390/ccwdev.h b/include/asm-s390/ccwdev.h
--- a/include/asm-s390/ccwdev.h	2005-03-01 23:39:09 -08:00
+++ b/include/asm-s390/ccwdev.h	2005-03-01 23:39:09 -08:00
@@ -144,6 +144,19 @@
  */
 extern int ccw_device_start_timeout(struct ccw_device *, struct ccw1 *,
 				    unsigned long, __u8, unsigned long, int);
+/*
+ * ccw_device_start_key()
+ * ccw_device_start_key_timeout()
+ *
+ * Same as ccw_device_start() and ccw_device_start_timeout(), except a
+ * storage key != default key can be provided for the I/O.
+ */
+extern int ccw_device_start_key(struct ccw_device *, struct ccw1 *,
+				unsigned long, __u8, __u8, unsigned long);
+extern int ccw_device_start_timeout_key(struct ccw_device *, struct ccw1 *,
+					unsigned long, __u8, __u8,
+					unsigned long, int);
+
 
 extern int ccw_device_resume(struct ccw_device *);
 extern int ccw_device_halt(struct ccw_device *, unsigned long);
diff -Nru a/include/asm-s390/cio.h b/include/asm-s390/cio.h
--- a/include/asm-s390/cio.h	2005-03-01 23:39:10 -08:00
+++ b/include/asm-s390/cio.h	2005-03-01 23:39:10 -08:00
@@ -274,6 +274,8 @@
 
 extern void wait_cons_dev(void);
 
+extern void clear_all_subchannels(void);
+
 #endif
 
 #endif
diff -Nru a/include/asm-s390/cpcmd.h b/include/asm-s390/cpcmd.h
--- a/include/asm-s390/cpcmd.h	2005-03-01 23:39:07 -08:00
+++ b/include/asm-s390/cpcmd.h	2005-03-01 23:39:07 -08:00
@@ -4,11 +4,21 @@
  *  S390 version
  *    Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
  *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
+ *               Christian Borntraeger (cborntra@de.ibm.com),
  */
 
 #ifndef __CPCMD__
 #define __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);
+
+#ifndef __s390x__
+#define cpcmd __cpcmd
+#else
 extern void cpcmd(char *cmd, char *response, int rlen);
+#endif /*__s390x__*/
 
 #endif
diff -Nru a/include/asm-s390/cputime.h b/include/asm-s390/cputime.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-s390/cputime.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,168 @@
+/*
+ *  include/asm-s390/cputime.h
+ *
+ *  (C) Copyright IBM Corp. 2004
+ *
+ *  Author: Martin Schwidefsky <schwidefsky@de.ibm.com>
+ */
+
+#ifndef _S390_CPUTIME_H
+#define _S390_CPUTIME_H
+
+/* We want to use micro-second resolution. */
+
+typedef unsigned long long cputime_t;
+typedef unsigned long long cputime64_t;
+
+#ifndef __s390x__
+
+static inline unsigned int
+__div(unsigned long long n, unsigned int base)
+{
+	register_pair rp;
+
+	rp.pair = n >> 1;
+	asm ("dr %0,%1" : "+d" (rp) : "d" (base >> 1));
+	return rp.subreg.odd;
+}
+
+#else /* __s390x__ */
+
+static inline unsigned int
+__div(unsigned long long n, unsigned int base)
+{
+	return n / base;
+}
+
+#endif /* __s390x__ */
+
+#define cputime_zero			(0ULL)
+#define cputime_max			((~0UL >> 1) - 1)
+#define cputime_add(__a, __b)		((__a) +  (__b))
+#define cputime_sub(__a, __b)		((__a) -  (__b))
+#define cputime_eq(__a, __b)		((__a) == (__b))
+#define cputime_gt(__a, __b)		((__a) >  (__b))
+#define cputime_ge(__a, __b)		((__a) >= (__b))
+#define cputime_lt(__a, __b)		((__a) <  (__b))
+#define cputime_le(__a, __b)		((__a) <= (__b))
+#define cputime_to_jiffies(__ct)	(__div((__ct), 1000000 / HZ))
+#define jiffies_to_cputime(__hz)	((cputime_t)(__hz) * (1000000 / HZ))
+
+#define cputime64_zero			(0ULL)
+#define cputime64_add(__a, __b)		((__a) + (__b))
+#define cputime_to_cputime64(__ct)	(__ct)
+
+static inline u64
+cputime64_to_jiffies64(cputime64_t cputime)
+{
+	do_div(cputime, 1000000 / HZ);
+	return cputime;
+}
+
+/*
+ * Convert cputime to milliseconds and back.
+ */
+static inline unsigned int
+cputime_to_msecs(const cputime_t cputime)
+{
+	return __div(cputime, 1000);
+}
+
+static inline cputime_t
+msecs_to_cputime(const unsigned int m)
+{
+	return (cputime_t) m * 1000;
+}
+
+/*
+ * Convert cputime to milliseconds and back.
+ */
+static inline unsigned int
+cputime_to_secs(const cputime_t cputime)
+{
+	return __div(cputime, 1000000);
+}
+
+static inline cputime_t
+secs_to_cputime(const unsigned int s)
+{
+	return (cputime_t) s * 1000000;
+}
+
+/*
+ * Convert cputime to timespec and back.
+ */
+static inline cputime_t
+timespec_to_cputime(const struct timespec *value)
+{
+        return value->tv_nsec / 1000 + (u64) value->tv_sec * 1000000;
+}
+
+static inline void
+cputime_to_timespec(const cputime_t cputime, struct timespec *value)
+{
+#ifndef __s390x__
+	register_pair rp;
+
+	rp.pair = cputime >> 1;
+	asm ("dr %0,%1" : "+d" (rp) : "d" (1000000 >> 1));
+	value->tv_nsec = rp.subreg.even * 1000;
+	value->tv_sec = rp.subreg.odd;
+#else
+	value->tv_nsec = (cputime % 1000000) * 1000;
+	value->tv_sec = cputime / 1000000;
+#endif
+}
+
+/*
+ * Convert cputime to timeval and back.
+ * Since cputime and timeval have the same resolution (microseconds)
+ * this is easy.
+ */
+static inline cputime_t
+timeval_to_cputime(const struct timeval *value)
+{
+        return value->tv_usec + (u64) value->tv_sec * 1000000;
+}
+
+static inline void
+cputime_to_timeval(const cputime_t cputime, struct timeval *value)
+{
+#ifndef __s390x__
+	register_pair rp;
+
+	rp.pair = cputime >> 1;
+	asm ("dr %0,%1" : "+d" (rp) : "d" (1000000 >> 1));
+	value->tv_usec = rp.subreg.even;
+	value->tv_sec = rp.subreg.odd;
+#else
+	value->tv_usec = cputime % 1000000;
+	value->tv_sec = cputime / 1000000;
+#endif
+}
+
+/*
+ * Convert cputime to clock and back.
+ */
+static inline clock_t
+cputime_to_clock_t(cputime_t cputime)
+{
+	return __div(cputime, 1000000 / USER_HZ);
+}
+
+static inline cputime_t
+clock_t_to_cputime(unsigned long x)
+{
+	return (cputime_t) x * (1000000 / USER_HZ);
+}
+
+/*
+ * Convert cputime64 to clock.
+ */
+static inline clock_t
+cputime64_to_clock_t(cputime64_t cputime)
+{
+       return __div(cputime, 1000000 / USER_HZ);
+}
+
+#endif /* _S390_CPUTIME_H */
diff -Nru a/include/asm-s390/hardirq.h b/include/asm-s390/hardirq.h
--- a/include/asm-s390/hardirq.h	2005-03-01 23:39:17 -08:00
+++ b/include/asm-s390/hardirq.h	2005-03-01 23:39:17 -08:00
@@ -16,6 +16,7 @@
 #include <linux/threads.h>
 #include <linux/sched.h>
 #include <linux/cache.h>
+#include <linux/interrupt.h>
 #include <asm/lowcore.h>
 
 /* irq_cpustat_t is unused currently, but could be converted
@@ -27,34 +28,11 @@
 
 #define local_softirq_pending() (S390_lowcore.softirq_pending)
 
-/* this is always called with cpu == smp_processor_id() at the moment */
-static inline __u32
-softirq_pending(unsigned int cpu)
-{
-	if (cpu == smp_processor_id())
-		return local_softirq_pending();
-	return lowcore_ptr[cpu]->softirq_pending;
-}
-
 #define __ARCH_IRQ_STAT
+#define __ARCH_HAS_DO_SOFTIRQ
 
 #define HARDIRQ_BITS	8
 
 extern void account_ticks(struct pt_regs *);
-
-#define __ARCH_HAS_DO_SOFTIRQ
-
-#define irq_enter()							\
-do {									\
-	(preempt_count() += HARDIRQ_OFFSET);				\
-} while(0)
-#define irq_exit()							\
-do {									\
-	preempt_count() -= IRQ_EXIT_OFFSET;				\
-	if (!in_interrupt() && local_softirq_pending())			\
-		/* Use the async. stack for softirq */			\
-		do_softirq();						\
-	preempt_enable_no_resched();					\
-} while (0)
 
 #endif /* __ASM_HARDIRQ_H */
diff -Nru a/include/asm-s390/lowcore.h b/include/asm-s390/lowcore.h
--- a/include/asm-s390/lowcore.h	2005-03-01 23:38:57 -08:00
+++ b/include/asm-s390/lowcore.h	2005-03-01 23:38:57 -08:00
@@ -56,13 +56,18 @@
 
 #define __LC_RETURN_PSW                 0x200
 
-#define __LC_IRB			0x210
-
-#define __LC_DIAG44_OPCODE		0x250
-
 #define __LC_SAVE_AREA                  0xC00
 
 #ifndef __s390x__
+#define __LC_IRB			0x208
+#define __LC_SYNC_ENTER_TIMER		0x248
+#define __LC_ASYNC_ENTER_TIMER		0x250
+#define __LC_EXIT_TIMER			0x258
+#define __LC_LAST_UPDATE_TIMER		0x260
+#define __LC_USER_TIMER			0x268
+#define __LC_SYSTEM_TIMER		0x270
+#define __LC_LAST_UPDATE_CLOCK		0x278
+#define __LC_STEAL_CLOCK		0x280
 #define __LC_KERNEL_STACK               0xC40
 #define __LC_THREAD_INFO		0xC44
 #define __LC_ASYNC_STACK                0xC48
@@ -76,6 +81,16 @@
 #define __LC_CURRENT			0xC90
 #define __LC_INT_CLOCK			0xC98
 #else /* __s390x__ */
+#define __LC_IRB			0x210
+#define __LC_SYNC_ENTER_TIMER		0x250
+#define __LC_ASYNC_ENTER_TIMER		0x258
+#define __LC_EXIT_TIMER			0x260
+#define __LC_LAST_UPDATE_TIMER		0x268
+#define __LC_USER_TIMER			0x270
+#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
@@ -87,7 +102,7 @@
 #define __LC_IPLDEV                     0xDB8
 #define __LC_JIFFY_TIMER		0xDC0
 #define __LC_CURRENT			0xDD8
-#define __LC_INT_CLOCK			0xDe8
+#define __LC_INT_CLOCK			0xDE8
 #endif /* __s390x__ */
 
 #define __LC_PANIC_MAGIC                0xE00
@@ -169,7 +184,15 @@
 
         psw_t        return_psw;               /* 0x200 */
 	__u8	     irb[64];		       /* 0x208 */
-	__u8         pad8[0xc00-0x248];        /* 0x248 */
+	__u64        sync_enter_timer;         /* 0x248 */
+	__u64        async_enter_timer;        /* 0x250 */
+	__u64        exit_timer;               /* 0x258 */
+	__u64        last_update_timer;        /* 0x260 */
+	__u64        user_timer;               /* 0x268 */
+	__u64        system_timer;             /* 0x270 */
+	__u64        last_update_clock;        /* 0x278 */
+	__u64        steal_clock;              /* 0x280 */
+	__u8         pad8[0xc00-0x288];        /* 0x288 */
 
         /* System info area */
 	__u32        save_area[16];            /* 0xc00 */
@@ -250,8 +273,16 @@
 	psw_t        io_new_psw;               /* 0x1f0 */
         psw_t        return_psw;               /* 0x200 */
 	__u8	     irb[64];		       /* 0x210 */
-	__u32        diag44_opcode;            /* 0x250 */
-        __u8         pad8[0xc00-0x254];        /* 0x254 */
+	__u64        sync_enter_timer;         /* 0x250 */
+	__u64        async_enter_timer;        /* 0x258 */
+	__u64        exit_timer;               /* 0x260 */
+	__u64        last_update_timer;        /* 0x268 */
+	__u64        user_timer;               /* 0x270 */
+	__u64        system_timer;             /* 0x278 */
+	__u64        last_update_clock;        /* 0x280 */
+	__u64        steal_clock;              /* 0x288 */
+	__u32        diag44_opcode;            /* 0x290 */
+        __u8         pad8[0xc00-0x294];        /* 0x294 */
         /* System info area */
 	__u64        save_area[16];            /* 0xc00 */
         __u8         pad9[0xd40-0xc80];        /* 0xc80 */
diff -Nru a/include/asm-s390/page.h b/include/asm-s390/page.h
--- a/include/asm-s390/page.h	2005-03-01 23:38:53 -08:00
+++ b/include/asm-s390/page.h	2005-03-01 23:38:53 -08:00
@@ -106,6 +106,9 @@
 #define clear_user_page(page, vaddr, pg)	clear_page(page)
 #define copy_user_page(to, from, vaddr, pg)	copy_page(to, from)
 
+#define alloc_zeroed_user_highpage(vma, vaddr) alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO, vma, vaddr)
+#define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE
+
 /* Pure 2^n version of get_order */
 extern __inline__ int get_order(unsigned long size)
 {
diff -Nru a/include/asm-s390/pgtable.h b/include/asm-s390/pgtable.h
--- a/include/asm-s390/pgtable.h	2005-03-01 23:39:09 -08:00
+++ b/include/asm-s390/pgtable.h	2005-03-01 23:39:09 -08:00
@@ -13,6 +13,8 @@
 #ifndef _ASM_S390_PGTABLE_H
 #define _ASM_S390_PGTABLE_H
 
+#include <asm-generic/4level-fixup.h>
+
 /*
  * The Linux memory management assumes a three-level page table setup. For
  * s390 31 bit we "fold" the mid level into the top-level page table, so
@@ -416,6 +418,14 @@
 	return 0;
 }
 
+extern inline int pte_read(pte_t pte)
+{
+	/* All pages are readable since we don't use the fetch
+	 * protection bit in the storage key.
+	 */
+	return 1;
+}
+
 /*
  * pgd/pmd/pte modification functions
  */
@@ -679,7 +689,7 @@
 #define pgd_page_kernel(pgd) (pgd_val(pgd) & 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))
 #define pgd_offset(mm, address) ((mm)->pgd+pgd_index(address))
 
 /* to find an entry in a kernel page-table-directory */
diff -Nru a/include/asm-s390/resource.h b/include/asm-s390/resource.h
--- a/include/asm-s390/resource.h	2005-03-01 23:38:54 -08:00
+++ b/include/asm-s390/resource.h	2005-03-01 23:38:54 -08:00
@@ -9,52 +9,7 @@
 #ifndef _S390_RESOURCE_H
 #define _S390_RESOURCE_H
 
-/*
- * Resource limits
- */
-
-#define RLIMIT_CPU	0		/* CPU time in ms */
-#define RLIMIT_FSIZE	1		/* Maximum filesize */
-#define RLIMIT_DATA	2		/* max data size */
-#define RLIMIT_STACK	3		/* max stack size */
-#define RLIMIT_CORE	4		/* max core file size */
-#define RLIMIT_RSS	5		/* max resident set size */
-#define RLIMIT_NPROC	6		/* max number of processes */
-#define RLIMIT_NOFILE	7		/* max number of open files */
-#define RLIMIT_MEMLOCK	8		/* max locked-in-memory address space */
-#define RLIMIT_AS	9		/* address space limit */
-#define RLIMIT_LOCKS	10		/* maximum file locks held */
-#define RLIMIT_SIGPENDING 11		/* max number of pending signals */
-#define RLIMIT_MSGQUEUE 12		/* maximum bytes in POSIX mqueues */
-
-#define RLIM_NLIMITS	13
-
-/*
- * SuS says limits have to be unsigned.
- * Which makes a ton more sense anyway.
- */
-#define RLIM_INFINITY   (~0UL)
-
-#ifdef __KERNEL__
-
-#define INIT_RLIMITS					\
-{							\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{      _STK_LIM, RLIM_INFINITY },		\
-	{             0, RLIM_INFINITY },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{             0,             0 },		\
-	{ INR_OPEN, INR_OPEN },                         \
-	{   MLOCK_LIMIT,   MLOCK_LIMIT },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{ MAX_SIGPENDING, MAX_SIGPENDING },		\
-	{ MQ_BYTES_MAX, MQ_BYTES_MAX },			\
-}
-
-#endif /* __KERNEL__ */
+#include <asm-generic/resource.h>
 
 #endif
 
diff -Nru a/include/asm-s390/spinlock.h b/include/asm-s390/spinlock.h
--- a/include/asm-s390/spinlock.h	2005-03-01 23:39:18 -08:00
+++ b/include/asm-s390/spinlock.h	2005-03-01 23:39:18 -08:00
@@ -36,6 +36,9 @@
 
 typedef struct {
 	volatile unsigned int lock;
+#ifdef CONFIG_PREEMPT
+	unsigned int break_lock;
+#endif
 } __attribute__ ((aligned (4))) spinlock_t;
 
 #define SPIN_LOCK_UNLOCKED (spinlock_t) { 0 }
@@ -105,13 +108,26 @@
 typedef struct {
 	volatile unsigned long lock;
 	volatile unsigned long owner_pc;
+#ifdef CONFIG_PREEMPT
+	unsigned int break_lock;
+#endif
 } rwlock_t;
 
 #define RW_LOCK_UNLOCKED (rwlock_t) { 0, 0 }
 
 #define rwlock_init(x)	do { *(x) = RW_LOCK_UNLOCKED; } while(0)
 
-#define rwlock_is_locked(x) ((x)->lock != 0)
+/**
+ * read_can_lock - would read_trylock() succeed?
+ * @lock: the rwlock in question.
+ */
+#define read_can_lock(x) ((int)(x)->lock >= 0)
+
+/**
+ * write_can_lock - would write_trylock() succeed?
+ * @lock: the rwlock in question.
+ */
+#define write_can_lock(x) ((x)->lock == 0)
 
 #ifndef __s390x__
 #define _raw_read_lock(rw)   \
@@ -210,6 +226,8 @@
 		     : "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)
 {
diff -Nru a/include/asm-s390/string.h b/include/asm-s390/string.h
--- a/include/asm-s390/string.h	2005-03-01 23:39:18 -08:00
+++ b/include/asm-s390/string.h	2005-03-01 23:39:18 -08:00
@@ -15,7 +15,6 @@
 #include <linux/types.h>
 #endif
 
-#define __HAVE_ARCH_BCOPY	/* arch function */
 #define __HAVE_ARCH_MEMCHR	/* inline & arch function */
 #define __HAVE_ARCH_MEMCMP	/* arch function */
 #define __HAVE_ARCH_MEMCPY	/* gcc builtin & arch function */
diff -Nru a/include/asm-s390/system.h b/include/asm-s390/system.h
--- a/include/asm-s390/system.h	2005-03-01 23:39:17 -08:00
+++ b/include/asm-s390/system.h	2005-03-01 23:39:17 -08:00
@@ -105,10 +105,26 @@
 
 #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 *);
+
+#define finish_arch_switch(rq, 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")
 
diff -Nru a/include/asm-s390/thread_info.h b/include/asm-s390/thread_info.h
--- a/include/asm-s390/thread_info.h	2005-03-01 23:39:07 -08:00
+++ b/include/asm-s390/thread_info.h	2005-03-01 23:39:07 -08:00
@@ -100,6 +100,7 @@
 #define TIF_POLLING_NRFLAG	17	/* true if poll_idle() is polling 
 					   TIF_NEED_RESCHED */
 #define TIF_31BIT		18	/* 32bit process */ 
+#define TIF_MEMDIE		19
 
 #define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE)
 #define _TIF_NOTIFY_RESUME	(1<<TIF_NOTIFY_RESUME)
diff -Nru a/include/asm-s390/timer.h b/include/asm-s390/timer.h
--- a/include/asm-s390/timer.h	2005-03-01 23:38:53 -08:00
+++ b/include/asm-s390/timer.h	2005-03-01 23:38:53 -08:00
@@ -37,8 +37,6 @@
 	__u64 idle;		  /* temp var for idle */
 };
 
-void set_vtimer(__u64 expires);
-
 extern void init_virt_timer(struct vtimer_list *timer);
 extern void add_virt_timer(void *new);
 extern void add_virt_timer_periodic(void *new);
diff -Nru a/include/asm-s390/unistd.h b/include/asm-s390/unistd.h
--- a/include/asm-s390/unistd.h	2005-03-01 23:39:19 -08:00
+++ b/include/asm-s390/unistd.h	2005-03-01 23:39:19 -08:00
@@ -520,7 +520,6 @@
 #define __ARCH_WANT_SYS_GETHOSTNAME
 #define __ARCH_WANT_SYS_PAUSE
 #define __ARCH_WANT_SYS_SIGNAL
-#define __ARCH_WANT_SYS_TIME
 #define __ARCH_WANT_SYS_UTIME
 #define __ARCH_WANT_SYS_SOCKETCALL
 #define __ARCH_WANT_SYS_FADVISE64
@@ -532,9 +531,11 @@
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_SIGPROCMASK
 #define __ARCH_WANT_SYS_RT_SIGACTION
-# ifndef CONFIG_ARCH_S390X
+# ifdef CONFIG_ARCH_S390_31
 #   define __ARCH_WANT_STAT64
+#   define __ARCH_WANT_SYS_TIME
 # endif
+# define __ARCH_WANT_COMPAT_SYS_TIME
 #endif
 
 #ifdef __KERNEL_SYSCALLS__
diff -Nru a/include/asm-sh/checksum.h b/include/asm-sh/checksum.h
--- a/include/asm-sh/checksum.h	2005-03-01 23:38:53 -08:00
+++ b/include/asm-sh/checksum.h	2005-03-01 23:38:53 -08:00
@@ -34,8 +34,8 @@
  * 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);
+asmlinkage unsigned int csum_partial_copy_generic(const unsigned char *src, unsigned 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
@@ -45,14 +45,14 @@
  *	verify_area().
  */
 static __inline__
-unsigned int csum_partial_copy_nocheck ( const char *src, char *dst,
+unsigned int csum_partial_copy_nocheck (const unsigned char *src, unsigned char *dst,
 					int len, int sum)
 {
 	return csum_partial_copy_generic ( src, dst, len, sum, NULL, NULL);
 }
 
 static __inline__
-unsigned int csum_partial_copy_from_user ( const char *src, char *dst,
+unsigned int csum_partial_copy_from_user (const unsigned char *src, unsigned char *dst,
 						int len, int sum, int *err_ptr)
 {
 	return csum_partial_copy_generic ( src, dst, len, sum, err_ptr, NULL);
@@ -200,8 +200,8 @@
  *	Copy and checksum to user
  */
 #define HAVE_CSUM_COPY_USER
-static __inline__ unsigned int csum_and_copy_to_user (const char *src, 
-						      char __user *dst,
+static __inline__ unsigned int csum_and_copy_to_user (const unsigned char *src,
+						      unsigned char __user *dst,
 						      int len, int sum,
 						      int *err_ptr)
 {
diff -Nru a/include/asm-sh/cputime.h b/include/asm-sh/cputime.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-sh/cputime.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,6 @@
+#ifndef __SH_CPUTIME_H
+#define __SH_CPUTIME_H
+
+#include <asm-generic/cputime.h>
+
+#endif /* __SH_CPUTIME_H */
diff -Nru a/include/asm-sh/hardirq.h b/include/asm-sh/hardirq.h
--- a/include/asm-sh/hardirq.h	2005-03-01 23:38:55 -08:00
+++ b/include/asm-sh/hardirq.h	2005-03-01 23:38:55 -08:00
@@ -23,16 +23,4 @@
 # error HARDIRQ_BITS is too low!
 #endif
 
-#define nmi_enter()		(irq_enter())
-#define nmi_exit()		(preempt_count() -= HARDIRQ_OFFSET)
-
-#define irq_enter()		(preempt_count() += HARDIRQ_OFFSET)
-#define irq_exit()							\
-do {									\
-		preempt_count() -= IRQ_EXIT_OFFSET;			\
-		if (!in_interrupt() && softirq_pending(smp_processor_id())) \
-			do_softirq();					\
-		preempt_enable_no_resched();				\
-} while (0)
-
 #endif /* __ASM_SH_HARDIRQ_H */
diff -Nru a/include/asm-sh/mpc1211/keyboard.h b/include/asm-sh/mpc1211/keyboard.h
--- a/include/asm-sh/mpc1211/keyboard.h	2005-03-01 23:38:57 -08:00
+++ b/include/asm-sh/mpc1211/keyboard.h	2005-03-01 23:38:57 -08:00
@@ -57,7 +57,7 @@
 #define AUX_IRQ 12
 
 #define aux_request_irq(hand, dev_id)					\
-	request_irq(AUX_IRQ, hand, SA_SHIRQ, "PS/2 Mouse", dev_id)
+	request_irq(AUX_IRQ, hand, SA_SHIRQ, "PS2 Mouse", dev_id)
 
 #define aux_free_irq(dev_id) free_irq(AUX_IRQ, dev_id)
 
diff -Nru a/include/asm-sh/pgalloc.h b/include/asm-sh/pgalloc.h
--- a/include/asm-sh/pgalloc.h	2005-03-01 23:38:57 -08:00
+++ b/include/asm-sh/pgalloc.h	2005-03-01 23:38:57 -08:00
@@ -44,9 +44,7 @@
 {
 	pte_t *pte;
 
-	pte = (pte_t *) __get_free_page(GFP_KERNEL | __GFP_REPEAT);
-	if (pte)
-		clear_page(pte);
+	pte = (pte_t *) __get_free_page(GFP_KERNEL | __GFP_REPEAT | __GFP_ZERO);
 
 	return pte;
 }
@@ -56,9 +54,7 @@
 {
 	struct page *pte;
 
-   	pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT, 0);
-	if (pte)
-		clear_page(page_address(pte));
+   	pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0);
 
 	return pte;
 }
diff -Nru a/include/asm-sh/pgtable.h b/include/asm-sh/pgtable.h
--- a/include/asm-sh/pgtable.h	2005-03-01 23:39:18 -08:00
+++ b/include/asm-sh/pgtable.h	2005-03-01 23:39:18 -08:00
@@ -1,6 +1,8 @@
 #ifndef __ASM_SH_PGTABLE_H
 #define __ASM_SH_PGTABLE_H
 
+#include <asm-generic/4level-fixup.h>
+
 /*
  * Copyright (C) 1999 Niibe Yutaka
  * Copyright (C) 2002, 2003, 2004 Paul Mundt
diff -Nru a/include/asm-sh/processor.h b/include/asm-sh/processor.h
--- a/include/asm-sh/processor.h	2005-03-01 23:38:55 -08:00
+++ b/include/asm-sh/processor.h	2005-03-01 23:38:55 -08:00
@@ -191,12 +191,6 @@
  */
 extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
 
-/*
- * Bus types
- */
-#define MCA_bus 0
-#define MCA_bus__is_a_macro /* for versions in ksyms.c */
-
 /* 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)
diff -Nru a/include/asm-sh/resource.h b/include/asm-sh/resource.h
--- a/include/asm-sh/resource.h	2005-03-01 23:39:07 -08:00
+++ b/include/asm-sh/resource.h	2005-03-01 23:39:07 -08:00
@@ -1,51 +1,6 @@
 #ifndef __ASM_SH_RESOURCE_H
 #define __ASM_SH_RESOURCE_H
 
-/*
- * Resource limits
- */
-
-#define RLIMIT_CPU	0		/* CPU time in ms */
-#define RLIMIT_FSIZE	1		/* Maximum filesize */
-#define RLIMIT_DATA	2		/* max data size */
-#define RLIMIT_STACK	3		/* max stack size */
-#define RLIMIT_CORE	4		/* max core file size */
-#define RLIMIT_RSS	5		/* max resident set size */
-#define RLIMIT_NPROC	6		/* max number of processes */
-#define RLIMIT_NOFILE	7		/* max number of open files */
-#define RLIMIT_MEMLOCK	8		/* max locked-in-memory address space */
-#define RLIMIT_AS	9		/* address space limit */
-#define RLIMIT_LOCKS	10		/* maximum file locks held */
-#define RLIMIT_SIGPENDING 11		/* max number of pending signals */
-#define RLIMIT_MSGQUEUE 12		/* maximum bytes in POSIX mqueues */
-
-#define RLIM_NLIMITS	13
-
-#ifdef __KERNEL__
-
-/*
- * SuS says limits have to be unsigned.
- * Which makes a ton more sense anyway.
- */
-#define RLIM_INFINITY	(~0UL)
-
-#define INIT_RLIMITS					\
-{							\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{      _STK_LIM, RLIM_INFINITY },		\
-	{             0, RLIM_INFINITY },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{             0,             0 },		\
-	{      INR_OPEN,     INR_OPEN  },		\
-	{   MLOCK_LIMIT,   MLOCK_LIMIT },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{ MAX_SIGPENDING, MAX_SIGPENDING },		\
-	{ MQ_BYTES_MAX, MQ_BYTES_MAX },			\
-}
-
-#endif /* __KERNEL__ */
+#include <asm-generic/resource.h>
 
 #endif /* __ASM_SH_RESOURCE_H */
diff -Nru a/include/asm-sh/spinlock.h b/include/asm-sh/spinlock.h
--- a/include/asm-sh/spinlock.h	2005-03-01 23:38:54 -08:00
+++ b/include/asm-sh/spinlock.h	2005-03-01 23:38:54 -08:00
@@ -17,6 +17,9 @@
  */
 typedef struct {
 	volatile unsigned long lock;
+#ifdef CONFIG_PREEMPT
+	unsigned int break_lock;
+#endif
 } spinlock_t;
 
 #define SPIN_LOCK_UNLOCKED	(spinlock_t) { 0 }
@@ -48,9 +51,7 @@
 
 static inline void _raw_spin_unlock(spinlock_t *lock)
 {
-#ifdef CONFIG_DEBUG_SPINLOCK
-	BUG_ON(!spin_is_locked(lock));
-#endif
+	assert_spin_locked(lock);
 
 	lock->lock = 0;
 }
@@ -68,12 +69,14 @@
 typedef struct {
 	spinlock_t lock;
 	atomic_t counter;
+#ifdef CONFIG_PREEMPT
+	unsigned int break_lock;
+#endif
 } rwlock_t;
 
 #define RW_LOCK_BIAS		0x01000000
 #define RW_LOCK_UNLOCKED	(rwlock_t) { { 0 }, { RW_LOCK_BIAS } }
 #define rwlock_init(x)		do { *(x) = RW_LOCK_UNLOCKED; } while (0)
-#define rwlock_is_locked(x)	(atomic_read(&(x)->counter) != RW_LOCK_BIAS)
 
 static inline void _raw_read_lock(rwlock_t *rw)
 {
@@ -104,6 +107,8 @@
 	atomic_set(&rw->counter, 0);
 	_raw_spin_unlock(&rw->lock);
 }
+
+#define _raw_read_trylock(lock) generic_raw_read_trylock(lock)
 
 static inline int _raw_write_trylock(rwlock_t *rw)
 {
diff -Nru a/include/asm-sh/string.h b/include/asm-sh/string.h
--- a/include/asm-sh/string.h	2005-03-01 23:39:09 -08:00
+++ b/include/asm-sh/string.h	2005-03-01 23:39:09 -08:00
@@ -124,7 +124,4 @@
 #define __HAVE_ARCH_STRLEN
 extern size_t strlen(const char *);
 
-/* Don't build bcopy at all ...  */
-#define __HAVE_ARCH_BCOPY
-
 #endif /* __ASM_SH_STRING_H */
diff -Nru a/include/asm-sh/thread_info.h b/include/asm-sh/thread_info.h
--- a/include/asm-sh/thread_info.h	2005-03-01 23:39:07 -08:00
+++ b/include/asm-sh/thread_info.h	2005-03-01 23:39:07 -08:00
@@ -83,6 +83,7 @@
 #define TIF_NEED_RESCHED	3	/* rescheduling necessary */
 #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 */
+#define TIF_MEMDIE		18
 #define TIF_USERSPACE		31	/* true if FS sets userspace */
 
 #define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE)
diff -Nru a/include/asm-sh64/cputime.h b/include/asm-sh64/cputime.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-sh64/cputime.h	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,6 @@
+#ifndef __SH64_CPUTIME_H
+#define __SH64_CPUTIME_H
+
+#include <asm-generic/cputime.h>
+
+#endif /* __SH64_CPUTIME_H */
diff -Nru a/include/asm-sh64/keyboard.h b/include/asm-sh64/keyboard.h
--- a/include/asm-sh64/keyboard.h	2005-03-01 23:38:54 -08:00
+++ b/include/asm-sh64/keyboard.h	2005-03-01 23:38:54 -08:00
@@ -65,7 +65,7 @@
 #endif
 
 #define aux_request_irq(hand, dev_id)					\
-	request_irq(AUX_IRQ, hand, SA_SHIRQ, "PS/2 Mouse", dev_id)
+	request_irq(AUX_IRQ, hand, SA_SHIRQ, "PS2 Mouse", dev_id)
 
 #define aux_free_irq(dev_id) free_irq(AUX_IRQ, dev_id)
 
diff -Nru a/include/asm-sh64/pgalloc.h b/include/asm-sh64/pgalloc.h
--- a/include/asm-sh64/pgalloc.h	2005-03-01 23:38:52 -08:00
+++ b/include/asm-sh64/pgalloc.h	2005-03-01 23:38:52 -08:00
@@ -112,9 +112,7 @@
 {
 	pte_t *pte;
 
-	pte = (pte_t *)__get_free_page(GFP_KERNEL | __GFP_REPEAT);
-	if (pte)
-		clear_page(pte);
+	pte = (pte_t *)__get_free_page(GFP_KERNEL | __GFP_REPEAT|__GFP_ZERO);
 
 	return pte;
 }
@@ -123,9 +121,7 @@
 {
 	struct page *pte;
 
-	pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT, 0);
-	if (pte)
-		clear_page(page_address(pte));
+	pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0);
 
 	return pte;
 }
@@ -150,9 +146,7 @@
 static __inline__ pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address)
 {
 	pmd_t *pmd;
-	pmd = (pmd_t *) __get_free_page(GFP_KERNEL|__GFP_REPEAT);
-	if (pmd)
-		clear_page(pmd);
+	pmd = (pmd_t *) __get_free_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO);
 	return pmd;
 }
 
diff -Nru a/include/asm-sh64/pgtable.h b/include/asm-sh64/pgtable.h
--- a/include/asm-sh64/pgtable.h	2005-03-01 23:39:08 -08:00
+++ b/include/asm-sh64/pgtable.h	2005-03-01 23:39:08 -08:00
@@ -1,6 +1,8 @@
 #ifndef __ASM_SH64_PGTABLE_H
 #define __ASM_SH64_PGTABLE_H
 
+#include <asm-generic/4level-fixup.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
diff -Nru a/include/asm-sh64/processor.h b/include/asm-sh64/processor.h
--- a/include/asm-sh64/processor.h	2005-03-01 23:38:44 -08:00
+++ b/include/asm-sh64/processor.h	2005-03-01 23:38:44 -08:00
@@ -218,12 +218,6 @@
  */
 extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
 
-/*
- * Bus types
- */
-#define MCA_bus 0
-#define MCA_bus__is_a_macro /* for versions in ksyms.c */
-
 
 /* Copy and release all segment info associated with a VM */
 #define copy_segments(p, mm)	do { } while (0)
diff -Nru a/include/asm-sh64/thread_info.h b/include/asm-sh64/thread_info.h
--- a/include/asm-sh64/thread_info.h	2005-03-01 23:38:55 -08:00
+++ b/include/asm-sh64/thread_info.h	2005-03-01 23:38:55 -08:00
@@ -74,6 +74,7 @@
 #define TIF_SYSCALL_TRACE	0	/* syscall trace active */
 #define TIF_SIGPENDING		2	/* signal pending */
 #define TIF_NEED_RESCHED	3	/* rescheduling necessary */
+#define TIF_MEMDIE		4
 
 #define THREAD_SIZE	16384
 
diff -Nru a/include/asm-sparc/asi.h b/include/asm-sparc/asi.h
--- a/include/asm-sparc/asi.h	2005-03-01 23:38:56 -08:00
+++ b/include/asm-sparc/asi.h	2005-03-01 23:38:56 -08:00
@@ -104,7 +104,8 @@
 #define ASI_M_DCDR         0x39   /* Data Cache Diagnostics Register rw, ss */
 
 #define ASI_M_VIKING_TMP1  0x40	  /* Emulation temporary 1 on Viking */
-#define ASI_M_VIKING_TMP2  0x41	  /* Emulation temporary 2 on Viking */
+/* only available on SuperSparc I */
+/* #define ASI_M_VIKING_TMP2  0x41 */  /* Emulation temporary 2 on Viking */
 
 #define ASI_M_ACTION       0x4c   /* Breakpoint Action Register (GNU/Viking) */
 
diff -Nru a/include/asm-sparc/bitext.h b/include/asm-sparc/bitext.h
--- a/include/asm-sparc/bitext.h	2005-03-01 23:39:08 -08:00
+++ b/include/asm-sparc/bitext.h	2005-03-01 23:39:08 -08:00
@@ -17,6 +17,7 @@
 	int last_off;
 	int last_size;
 	int first_free;
+	int num_colors;
 };
 
 extern int bit_map_string_get(struct bit_map *t, int len, int align);
diff -Nru a/include/asm-sparc/bitops.h b/include/asm-sparc/bitops.h
--- a/include/asm-sparc/bitops.h	2005-03-01 23:39:10 -08:00
+++ b/include/asm-sparc/bitops.h	2005-03-01 23:39:10 -08:00
@@ -312,10 +312,10 @@
  * 'size' bits, starting the search at bit 'offset'. This is largely based
  * on Linus's ALPHA routines, which are pretty portable BTW.
  */
-static inline unsigned long find_next_zero_bit(unsigned long *addr,
+static inline unsigned long find_next_zero_bit(const unsigned long *addr,
     unsigned long size, unsigned long offset)
 {
-	unsigned long *p = addr + (offset >> 5);
+	const unsigned long *p = addr + (offset >> 5);
 	unsigned long result = offset & ~31UL;
 	unsigned long tmp;
 
@@ -446,10 +446,10 @@
 	return retval;
 }
 
-static inline unsigned long find_next_zero_le_bit(unsigned long *addr,
+static inline unsigned long find_next_zero_le_bit(const unsigned long *addr,
     unsigned long size, unsigned long offset)
 {
-	unsigned long *p = addr + (offset >> 5);
+	const unsigned long *p = addr + (offset >> 5);
 	unsigned long result = offset & ~31UL;
 	unsigned long tmp;
 
diff -Nru a/include/asm-sparc/checksum.h b/include/asm-sparc/checksum.h
--- a/include/asm-sparc/checksum.h	2005-03-01 23:38:43 -08:00
+++ b/include/asm-sparc/checksum.h	2005-03-01 23:38:43 -08:00
@@ -39,10 +39,10 @@
  * better 64-bit) boundary
  */
 
-extern unsigned int __csum_partial_copy_sparc_generic (const char *, char *);
+extern unsigned int __csum_partial_copy_sparc_generic (const unsigned char *, unsigned char *);
 
 static inline unsigned int 
-csum_partial_copy_nocheck (const char *src, char *dst, int len, 
+csum_partial_copy_nocheck (const unsigned char *src, unsigned char *dst, int len,
 			   unsigned int sum)
 {
 	register unsigned int ret asm("o0") = (unsigned int)src;
@@ -61,7 +61,7 @@
 }
 
 static inline unsigned int 
-csum_partial_copy_from_user(const char *src, char *dst, int len, 
+csum_partial_copy_from_user(const unsigned char __user *src, unsigned char *dst, int len,
 			    unsigned int sum, int *err)
   {
 	if (!access_ok (VERIFY_READ, src, len)) {
@@ -69,7 +69,7 @@
 		memset (dst, 0, len);
 		return sum;
 	} else {
-		register unsigned int ret asm("o0") = (unsigned int)src;
+		register unsigned long ret asm("o0") = (unsigned long)src;
 		register char *d asm("o1") = dst;
 		register int l asm("g1") = len;
 		register unsigned int s asm("g7") = sum;
@@ -91,15 +91,15 @@
   }
   
 static inline unsigned int 
-csum_partial_copy_to_user(const char *src, char __user *dst, int len, 
+csum_partial_copy_to_user(const unsigned char *src, unsigned char __user *dst, int len,
 			  unsigned int sum, int *err)
 {
 	if (!access_ok (VERIFY_WRITE, dst, len)) {
 		*err = -EFAULT;
 		return sum;
 	} else {
-		register unsigned int ret asm("o0") = (unsigned int)src;
-		register char *d asm("o1") = dst;
+		register unsigned long ret asm("o0") = (unsigned long)src;
+		register char __user *d asm("o1") = dst;
 		register int l asm("g1") = len;
 		register unsigned int s asm("g7") = sum;
 
diff -Nru a/include/asm-sparc/cputime.h b/include/asm-sparc/cputime.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-sparc/cputime.h	2005-03-01 23:39:26 -08:00
@@ -0,0 +1,6 @@
+#ifndef __SPARC_CPUTIME_H
+#define __SPARC_CPUTIME_H
+
+#include <asm-generic/cputime.h>
+
+#endif /* __SPARC_CPUTIME_H */
diff -Nru a/include/asm-sparc/elf.h b/include/asm-sparc/elf.h
--- a/include/asm-sparc/elf.h	2005-03-01 23:39:09 -08:00
+++ b/include/asm-sparc/elf.h	2005-03-01 23:39:09 -08:00
@@ -88,11 +88,11 @@
 #define ELF_CORE_COPY_REGS(__elf_regs, __pt_regs)	\
 do {	unsigned long *dest = &(__elf_regs[0]);		\
 	struct pt_regs *src = (__pt_regs);		\
-	unsigned long *sp;				\
+	unsigned long __user *sp;			\
 	memcpy(&dest[0], &src->u_regs[0],		\
 	       sizeof(unsigned long) * 16);		\
 	/* Don't try this at home kids... */		\
-	sp = (unsigned long *) src->u_regs[14];		\
+	sp = (unsigned long __user *) src->u_regs[14];	\
 	copy_from_user(&dest[16], sp,			\
 		       sizeof(unsigned long) * 16);	\
 	dest[32] = src->psr;				\
diff -Nru a/include/asm-sparc/floppy.h b/include/asm-sparc/floppy.h
--- a/include/asm-sparc/floppy.h	2005-03-01 23:38:44 -08:00
+++ b/include/asm-sparc/floppy.h	2005-03-01 23:38:44 -08:00
@@ -213,7 +213,7 @@
 volatile int doing_pdma = 0;
 
 /* This is software state */
-char *pdma_base = 0;
+char *pdma_base = NULL;
 unsigned long pdma_areasize;
 
 /* Common routines to all controller types on the Sparc. */
@@ -264,7 +264,7 @@
 }
 
 /* Our low-level entry point in arch/sparc/kernel/entry.S */
-extern void floppy_hardint(int irq, void *unused, struct pt_regs *regs);
+irqreturn_t floppy_hardint(int irq, void *unused, struct pt_regs *regs);
 
 static int sun_fd_request_irq(void)
 {
@@ -312,8 +312,8 @@
 	}
 
 	/* The sun4m lets us know if the controller is actually usable. */
-	if(sparc_cpu_model == sun4m) {
-		prom_getproperty(fd_node, "status", state, sizeof(state));
+	if(sparc_cpu_model == sun4m &&
+	   prom_getproperty(fd_node, "status", state, sizeof(state)) != -1) {
 		if(!strcmp(state, "disabled")) {
 			goto no_sun_fdc;
 		}
diff -Nru a/include/asm-sparc/hardirq.h b/include/asm-sparc/hardirq.h
--- a/include/asm-sparc/hardirq.h	2005-03-01 23:39:18 -08:00
+++ b/include/asm-sparc/hardirq.h	2005-03-01 23:39:18 -08:00
@@ -21,13 +21,4 @@
 
 #define HARDIRQ_BITS    8
 
-#define irq_enter()             (preempt_count() += HARDIRQ_OFFSET)
-#define irq_exit()                                                      \
-do {                                                                    \
-                preempt_count() -= IRQ_EXIT_OFFSET;                     \
-                if (!in_interrupt() && softirq_pending(smp_processor_id())) \
-                        do_softirq();                                   \
-                preempt_enable_no_resched();                            \
-} while (0)
-
 #endif /* __SPARC_HARDIRQ_H */
diff -Nru a/include/asm-sparc/highmem.h b/include/asm-sparc/highmem.h
--- a/include/asm-sparc/highmem.h	2005-03-01 23:39:17 -08:00
+++ b/include/asm-sparc/highmem.h	2005-03-01 23:39:17 -08:00
@@ -57,7 +57,7 @@
 static inline void *kmap(struct page *page)
 {
 	BUG_ON(in_interrupt());
-	if (page < highmem_start_page)
+	if (!PageHighMem(page))
 		return page_address(page);
 	return kmap_high(page);
 }
@@ -65,7 +65,7 @@
 static inline void kunmap(struct page *page)
 {
 	BUG_ON(in_interrupt());
-	if (page < highmem_start_page)
+	if (!PageHighMem(page))
 		return;
 	kunmap_high(page);
 }
diff -Nru a/include/asm-sparc/io.h b/include/asm-sparc/io.h
--- a/include/asm-sparc/io.h	2005-03-01 23:38:52 -08:00
+++ b/include/asm-sparc/io.h	2005-03-01 23:38:52 -08:00
@@ -134,12 +134,12 @@
 #define inl_p(__addr)		inl(__addr)
 #define outl_p(__l, __addr)	outl(__l, __addr)
 
-extern void outsb(unsigned long addr, const void *src, unsigned long cnt);
-extern void outsw(unsigned long addr, const void *src, unsigned long cnt);
-extern void outsl(unsigned long addr, const void *src, unsigned long cnt);
-extern void insb(unsigned long addr, void *dst, unsigned long count);
-extern void insw(unsigned long addr, void *dst, unsigned long count);
-extern void insl(unsigned long addr, void *dst, unsigned long count);
+void outsb(unsigned long addr, const void *src, unsigned long cnt);
+void outsw(unsigned long addr, const void *src, unsigned long cnt);
+void outsl(unsigned long addr, const void *src, unsigned long cnt);
+void insb(unsigned long addr, void *dst, unsigned long count);
+void insw(unsigned long addr, void *dst, unsigned long count);
+void insl(unsigned long addr, void *dst, unsigned long count);
 
 #define IO_SPACE_LIMIT 0xffffffff
 
diff -Nru a/include/asm-sparc/oplib.h b/include/asm-sparc/oplib.h
--- a/include/asm-sparc/oplib.h	2005-03-01 23:39:16 -08:00
+++ b/include/asm-sparc/oplib.h	2005-03-01 23:39:16 -08:00
@@ -10,6 +10,7 @@
 
 #include <asm/openprom.h>
 #include <linux/spinlock.h>
+#include <linux/compiler.h>
 
 /* The master romvec pointer... */
 extern struct linux_romvec *romvec;
@@ -244,8 +245,8 @@
 /* Fetch the requested property using the given buffer.  Returns
  * the number of bytes the prom put into your buffer or -1 on error.
  */
-extern int prom_getproperty(int thisnode, char *property,
-			    char *prop_buffer, int propbuf_size);
+extern int __must_check prom_getproperty(int thisnode, char *property,
+					 char *prop_buffer, int propbuf_size);
 
 /* Acquire an integer property. */
 extern int prom_getint(int node, char *property);
diff -Nru a/include/asm-sparc/pcic.h b/include/asm-sparc/pcic.h
--- a/include/asm-sparc/pcic.h	2005-03-01 23:38:56 -08:00
+++ b/include/asm-sparc/pcic.h	2005-03-01 23:38:56 -08:00
@@ -16,10 +16,10 @@
 #include <asm/pbm.h>
 
 struct linux_pcic {
-        unsigned long           pcic_regs;
+        void * __iomem          pcic_regs;
         unsigned long           pcic_io;
-        unsigned long           pcic_config_space_addr;
-        unsigned long           pcic_config_space_data;
+        void * __iomem          pcic_config_space_addr;
+        void * __iomem          pcic_config_space_data;
 	struct resource		pcic_res_regs;
 	struct resource		pcic_res_io;
 	struct resource		pcic_res_cfg_addr;
diff -Nru a/include/asm-sparc/pgtable.h b/include/asm-sparc/pgtable.h
--- a/include/asm-sparc/pgtable.h	2005-03-01 23:38:58 -08:00
+++ b/include/asm-sparc/pgtable.h	2005-03-01 23:38:58 -08:00
@@ -9,6 +9,8 @@
  *  Copyright (C) 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
  */
 
+#include <asm-generic/4level-fixup.h>
+
 #include <linux/config.h>
 #include <linux/spinlock.h>
 #include <linux/swap.h>
@@ -184,9 +186,30 @@
  * The following only work if pte_present() is true.
  * Undefined behaviour if not..
  */
+BTFIXUPDEF_HALF(pte_readi)
 BTFIXUPDEF_HALF(pte_writei)
 BTFIXUPDEF_HALF(pte_dirtyi)
 BTFIXUPDEF_HALF(pte_youngi)
+
+extern int pte_read(pte_t pte) __attribute_const__;
+extern __inline__ int pte_read(pte_t pte)
+{
+	switch (sparc_cpu_model){
+	case sun4:
+	case sun4c:
+		return pte_val(pte) & BTFIXUP_HALF(pte_readi);
+	case sun4d:
+	case sun4e:
+	case sun4m:
+		return !(pte_val(pte) & BTFIXUP_HALF(pte_readi));
+	/* pacify gcc warnings */
+	case sun4u:
+	case sun_unknown:
+	case ap1000:
+	default:
+		return 0;
+	}
+}
 
 extern int pte_write(pte_t pte) __attribute_const__;
 extern __inline__ int pte_write(pte_t pte)
diff -Nru a/include/asm-sparc/pgtsrmmu.h b/include/asm-sparc/pgtsrmmu.h
--- a/include/asm-sparc/pgtsrmmu.h	2005-03-01 23:38:55 -08:00
+++ b/include/asm-sparc/pgtsrmmu.h	2005-03-01 23:38:55 -08:00
@@ -73,6 +73,7 @@
 #define SRMMU_CACHE        0x80
 #define SRMMU_DIRTY        0x40
 #define SRMMU_REF          0x20
+#define SRMMU_NOREAD       0x10
 #define SRMMU_EXEC         0x08
 #define SRMMU_WRITE        0x04
 #define SRMMU_VALID        0x02 /* SRMMU_ET_PTE */
diff -Nru a/include/asm-sparc/processor.h b/include/asm-sparc/processor.h
--- a/include/asm-sparc/processor.h	2005-03-01 23:39:17 -08:00
+++ b/include/asm-sparc/processor.h	2005-03-01 23:39:17 -08:00
@@ -24,12 +24,6 @@
 #include <asm/page.h>
 
 /*
- * Bus types
- */
-#define MCA_bus 0
-#define MCA_bus__is_a_macro /* for versions in ksyms.c */
-
-/*
  * The sparc has no problems with write protection
  */
 #define wp_works_ok 1
diff -Nru a/include/asm-sparc/resource.h b/include/asm-sparc/resource.h
--- a/include/asm-sparc/resource.h	2005-03-01 23:38:52 -08:00
+++ b/include/asm-sparc/resource.h	2005-03-01 23:38:52 -08:00
@@ -26,6 +26,7 @@
 #define RLIMIT_MSGQUEUE 12		/* maximum bytes in POSIX mqueues */
 
 #define RLIM_NLIMITS	13
+#define __ARCH_RLIMIT_ORDER
 
 /*
  * SuS says limits have to be unsigned.
@@ -34,23 +35,6 @@
  */
 #define RLIM_INFINITY	0x7fffffff
 
-#ifdef __KERNEL__
-#define INIT_RLIMITS			\
-{					\
-    {RLIM_INFINITY, RLIM_INFINITY},	\
-    {RLIM_INFINITY, RLIM_INFINITY},	\
-    {RLIM_INFINITY, RLIM_INFINITY},	\
-    {_STK_LIM, RLIM_INFINITY},		\
-    {       0, RLIM_INFINITY},		\
-    {RLIM_INFINITY, RLIM_INFINITY},	\
-    {INR_OPEN, INR_OPEN}, {0, 0},	\
-    {MLOCK_LIMIT,   MLOCK_LIMIT},	\
-    {RLIM_INFINITY, RLIM_INFINITY},	\
-    {RLIM_INFINITY, RLIM_INFINITY},	\
-    {MAX_SIGPENDING, MAX_SIGPENDING},	\
-    {MQ_BYTES_MAX, MQ_BYTES_MAX},	\
-}
-
-#endif /* __KERNEL__ */
+#include <asm-generic/resource.h>
 
 #endif /* !(_SPARC_RESOURCE_H) */
diff -Nru a/include/asm-sparc/sbus.h b/include/asm-sparc/sbus.h
--- a/include/asm-sparc/sbus.h	2005-03-01 23:38:53 -08:00
+++ b/include/asm-sparc/sbus.h	2005-03-01 23:38:53 -08:00
@@ -106,6 +106,8 @@
 /* These yield IOMMU mappings in consistent mode. */
 extern void *sbus_alloc_consistent(struct sbus_dev *, long, u32 *dma_addrp);
 extern void sbus_free_consistent(struct sbus_dev *, long, void *, u32);
+void prom_adjust_ranges(struct linux_prom_ranges *, int,
+			struct linux_prom_ranges *, int);
 
 #define SBUS_DMA_BIDIRECTIONAL	DMA_BIDIRECTIONAL
 #define SBUS_DMA_TODEVICE	DMA_TO_DEVICE
diff -Nru a/include/asm-sparc/spinlock.h b/include/asm-sparc/spinlock.h
--- a/include/asm-sparc/spinlock.h	2005-03-01 23:39:08 -08:00
+++ b/include/asm-sparc/spinlock.h	2005-03-01 23:39:08 -08:00
@@ -16,6 +16,9 @@
 struct _spinlock_debug {
 	unsigned char lock;
 	unsigned long owner_pc;
+#ifdef CONFIG_PREEMPT
+	unsigned int break_lock;
+#endif
 };
 typedef struct _spinlock_debug spinlock_t;
 
@@ -36,13 +39,15 @@
 	volatile unsigned int lock;
 	unsigned long owner_pc;
 	unsigned long reader_pc[NR_CPUS];
+#ifdef CONFIG_PREEMPT
+	unsigned int break_lock;
+#endif
 };
 typedef struct _rwlock_debug rwlock_t;
 
 #define RW_LOCK_UNLOCKED (rwlock_t) { 0, 0, {0} }
 
 #define rwlock_init(lp)	do { *(lp)= RW_LOCK_UNLOCKED; } while(0)
-#define rwlock_is_locked(lp) ((lp)->lock != 0)
 
 extern void _do_read_lock(rwlock_t *rw, char *str);
 extern void _do_read_unlock(rwlock_t *rw, char *str);
@@ -79,8 +84,14 @@
 
 #else /* !CONFIG_DEBUG_SPINLOCK */
 
-typedef unsigned char spinlock_t;
-#define SPIN_LOCK_UNLOCKED	0
+typedef struct {
+	unsigned char lock;
+#ifdef CONFIG_PREEMPT
+	unsigned int break_lock;
+#endif
+} spinlock_t;
+
+#define SPIN_LOCK_UNLOCKED	(spinlock_t) { 0 }
 
 #define spin_lock_init(lock)   (*((unsigned char *)(lock)) = 0)
 #define spin_is_locked(lock)    (*((volatile unsigned char *)(lock)) != 0)
@@ -137,12 +148,16 @@
  * XXX This might create some problems with my dual spinlock
  * XXX scheme, deadlocks etc. -DaveM
  */
-typedef struct { volatile unsigned int lock; } rwlock_t;
+typedef struct {
+	volatile unsigned int lock;
+#ifdef CONFIG_PREEMPT
+	unsigned int break_lock;
+#endif
+} rwlock_t;
 
 #define RW_LOCK_UNLOCKED (rwlock_t) { 0 }
 
 #define rwlock_init(lp)	do { *(lp)= RW_LOCK_UNLOCKED; } while(0)
-#define rwlock_is_locked(lp) ((lp)->lock != 0)
 
 
 /* Sort of like atomic_t's on Sparc, but even more clever.
diff -Nru a/include/asm-sparc/string.h b/include/asm-sparc/string.h
--- a/include/asm-sparc/string.h	2005-03-01 23:38:44 -08:00
+++ b/include/asm-sparc/string.h	2005-03-01 23:38:44 -08:00
@@ -22,7 +22,6 @@
 #ifndef EXPORT_SYMTAB_STROPS
 
 /* First the mem*() things. */
-#define __HAVE_ARCH_BCOPY
 #define __HAVE_ARCH_MEMMOVE
 #undef memmove
 #define memmove(_to, _from, _n) \
@@ -40,6 +39,9 @@
 
 	if(n <= 32) {
 		__builtin_memcpy(to, from, n);
+	} else if (((unsigned int) to & 7) != 0) {
+		/* Destination is not aligned on the double-word boundary */
+		__memcpy(to, from, n);
 	} else {
 		switch(n) {
 		case PAGE_SIZE:
diff -Nru a/include/asm-sparc/svr4.h b/include/asm-sparc/svr4.h
--- a/include/asm-sparc/svr4.h	2005-03-01 23:38:58 -08:00
+++ b/include/asm-sparc/svr4.h	2005-03-01 23:38:58 -08:00
@@ -49,7 +49,7 @@
 
 typedef struct {
 	int            count;
-	int            *winptr [SVR4_MAXWIN]; /* pointer to the windows */
+	int            __user *winptr [SVR4_MAXWIN]; /* pointer to the windows */
 	svr4_rwindow_t win[SVR4_MAXWIN];      /* the windows */
 } svr4_gwindows_t;
 
@@ -72,7 +72,7 @@
 /* Machine dependent context */
 typedef struct {
 	svr4_gregset_t   greg;	/* registers 0..19 (see top) */
-	svr4_gwindows_t  *gwin;	/* may point to register windows */
+	svr4_gwindows_t  __user *gwin;	/* may point to register windows */
 	svr4_fregset_t   freg;	/* floating point registers */
 	svr4_xrs_t       xrs;	/* mhm? */
 	long             pad[19];
@@ -86,7 +86,7 @@
 
 /* signal stack exection place, unsupported */
 typedef struct svr4_stack_t {
-        char *sp;
+        char __user *sp;
         int  size;
         int  flags;
 } svr4_stack_t;
diff -Nru a/include/asm-sparc/system.h b/include/asm-sparc/system.h
--- a/include/asm-sparc/system.h	2005-03-01 23:39:08 -08:00
+++ b/include/asm-sparc/system.h	2005-03-01 23:39:08 -08:00
@@ -195,12 +195,12 @@
 #define read_barrier_depends()	do { } while(0)
 #define set_mb(__var, __value)  do { __var = __value; mb(); } while(0)
 #define set_wmb(__var, __value) set_mb(__var, __value)
-#define smp_mb()	__asm__ __volatile__("":::"memory");
-#define smp_rmb()	__asm__ __volatile__("":::"memory");
-#define smp_wmb()	__asm__ __volatile__("":::"memory");
+#define smp_mb()	__asm__ __volatile__("":::"memory")
+#define smp_rmb()	__asm__ __volatile__("":::"memory")
+#define smp_wmb()	__asm__ __volatile__("":::"memory")
 #define smp_read_barrier_depends()	do { } while(0)
 
-#define nop() __asm__ __volatile__ ("nop");
+#define nop() __asm__ __volatile__ ("nop")
 
 /* This has special calling conventions */
 #ifndef CONFIG_SMP
diff -Nru a/include/asm-sparc/thread_info.h b/include/asm-sparc/thread_info.h
--- a/include/asm-sparc/thread_info.h	2005-03-01 23:39:16 -08:00
+++ b/include/asm-sparc/thread_info.h	2005-03-01 23:39:16 -08:00
@@ -138,6 +138,7 @@
 					 * this quantum (SMP) */
 #define TIF_POLLING_NRFLAG	9	/* true if poll_idle() is polling
 					 * TIF_NEED_RESCHED */
+#define TIF_MEMDIE		10
 
 /* as above, but as bit values */
 #define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE)
diff -Nru a/include/asm-sparc/uaccess.h b/include/asm-sparc/uaccess.h
--- a/include/asm-sparc/uaccess.h	2005-03-01 23:39:10 -08:00
+++ b/include/asm-sparc/uaccess.h	2005-03-01 23:39:10 -08:00
@@ -111,7 +111,7 @@
 #define __get_user(x,ptr) __get_user_nocheck((x),(ptr),sizeof(*(ptr)),__typeof__(*(ptr)))
 
 struct __large_struct { unsigned long buf[100]; };
-#define __m(x) ((struct __large_struct *)(x))
+#define __m(x) ((struct __large_struct __user *)(x))
 
 #define __put_user_check(x,addr,size) ({ \
 register int __pu_ret; \
@@ -299,27 +299,27 @@
 static inline unsigned long copy_to_user(void __user *to, const void *from, unsigned long n)
 {
 	if (n && __access_ok((unsigned long) to, n))
-		return __copy_user(to, (void __user *) from, n);
+		return __copy_user(to, (__force void __user *) from, n);
 	else
 		return n;
 }
 
 static inline unsigned long __copy_to_user(void __user *to, const void *from, unsigned long n)
 {
-	return __copy_user(to, (void __user *) from, n);
+	return __copy_user(to, (__force void __user *) from, n);
 }
 
 static inline unsigned long copy_from_user(void *to, const void __user *from, unsigned long n)
 {
 	if (n && __access_ok((unsigned long) from, n))
-		return __copy_user((void __user *) to, from, n);
+		return __copy_user((__force void __user *) to, from, n);
 	else
 		return n;
 }
 
 static inline unsigned long __copy_from_user(void *to, const void __user *from, unsigned long n)
 {
-	return __copy_user((void __user *) to, from, n);
+	return __copy_user((__force void __user *) to, from, n);
 }
 
 #define __copy_to_user_inatomic __copy_to_user
diff -Nru a/include/asm-sparc/unistd.h b/include/asm-sparc/unistd.h
--- a/include/asm-sparc/unistd.h	2005-03-01 23:38:52 -08:00
+++ b/include/asm-sparc/unistd.h	2005-03-01 23:38:52 -08:00
@@ -486,7 +486,6 @@
 static __inline__ _syscall3(int,execve,__const__ char *,file,char **,argv,char **,envp)
 static __inline__ _syscall3(int,open,__const__ char *,file,int,flag,int,mode)
 static __inline__ _syscall1(int,close,int,fd)
-static __inline__ _syscall1(int,_exit,int,exitcode)
 static __inline__ _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
 
 #include <linux/linkage.h>
diff -Nru a/include/asm-sparc/winmacro.h b/include/asm-sparc/winmacro.h
--- a/include/asm-sparc/winmacro.h	2005-03-01 23:38:56 -08:00
+++ b/include/asm-sparc/winmacro.h	2005-03-01 23:38:56 -08:00
@@ -112,9 +112,12 @@
 	and      %idreg, 0xc, %idreg; \
 	ld       [%idreg + %dest_reg], %dest_reg;
 
-/* Sliiick. We have a Linux current register :) -jj */
-#define LOAD_CURRENT4D(dest_reg) \
-	lda	 [%g0] ASI_M_VIKING_TMP2, %dest_reg;
+#define LOAD_CURRENT4D(dest_reg, idreg) \
+	lda	 [%g0] ASI_M_VIKING_TMP1, %idreg; \
+	sethi	%hi(C_LABEL(current_set)), %dest_reg; \
+	sll	%idreg, 2, %idreg; \
+	or	%dest_reg, %lo(C_LABEL(current_set)), %dest_reg; \
+	ld	[%idreg + %dest_reg], %dest_reg;
 
 /* Blackbox - take care with this... - check smp4m and smp4d before changing this. */
 #define LOAD_CURRENT(dest_reg, idreg) 					\
diff -Nru a/include/asm-sparc64/atomic.h b/include/asm-sparc64/atomic.h
--- a/include/asm-sparc64/atomic.h	2005-03-01 23:39:16 -08:00
+++ b/include/asm-sparc64/atomic.h	2005-03-01 23:39:16 -08:00
@@ -8,6 +8,7 @@
 #ifndef __ARCH_SPARC64_ATOMIC__
 #define __ARCH_SPARC64_ATOMIC__
 
+#include <linux/config.h>
 #include <linux/types.h>
 
 typedef struct { volatile int counter; } atomic_t;
@@ -22,29 +23,27 @@
 #define atomic_set(v, i)	(((v)->counter) = i)
 #define atomic64_set(v, i)	(((v)->counter) = i)
 
-extern int __atomic_add(int, atomic_t *);
-extern int __atomic64_add(__s64, atomic64_t *);
+extern void atomic_add(int, atomic_t *);
+extern void atomic64_add(int, atomic64_t *);
+extern void atomic_sub(int, atomic_t *);
+extern void atomic64_sub(int, atomic64_t *);
+
+extern int atomic_add_ret(int, atomic_t *);
+extern int atomic64_add_ret(int, atomic64_t *);
+extern int atomic_sub_ret(int, atomic_t *);
+extern int atomic64_sub_ret(int, atomic64_t *);
+
+#define atomic_dec_return(v) atomic_sub_ret(1, v)
+#define atomic64_dec_return(v) atomic64_sub_ret(1, v)
 
-extern int __atomic_sub(int, atomic_t *);
-extern int __atomic64_sub(__s64, atomic64_t *);
+#define atomic_inc_return(v) atomic_add_ret(1, v)
+#define atomic64_inc_return(v) atomic64_add_ret(1, v)
 
-#define atomic_add(i, v) ((void)__atomic_add(i, v))
-#define atomic64_add(i, v) ((void)__atomic64_add(i, v))
+#define atomic_sub_return(i, v) atomic_sub_ret(i, v)
+#define atomic64_sub_return(i, v) atomic64_sub_ret(i, v)
 
-#define atomic_sub(i, v) ((void)__atomic_sub(i, v))
-#define atomic64_sub(i, v) ((void)__atomic64_sub(i, v))
-
-#define atomic_dec_return(v) __atomic_sub(1, v)
-#define atomic64_dec_return(v) __atomic64_sub(1, v)
-
-#define atomic_inc_return(v) __atomic_add(1, v)
-#define atomic64_inc_return(v) __atomic64_add(1, v)
-
-#define atomic_sub_return(i, v) __atomic_sub(i, v)
-#define atomic64_sub_return(i, v) __atomic64_sub(i, v)
-
-#define atomic_add_return(i, v) __atomic_add(i, v)
-#define atomic64_add_return(i, v) __atomic64_add(i, v)
+#define atomic_add_return(i, v) atomic_add_ret(i, v)
+#define atomic64_add_return(i, v) atomic64_add_ret(i, v)
 
 /*
  * atomic_inc_and_test - increment and test
@@ -56,25 +55,32 @@
  */
 #define atomic_inc_and_test(v) (atomic_inc_return(v) == 0)
 
-#define atomic_sub_and_test(i, v) (__atomic_sub(i, v) == 0)
-#define atomic64_sub_and_test(i, v) (__atomic64_sub(i, v) == 0)
+#define atomic_sub_and_test(i, v) (atomic_sub_ret(i, v) == 0)
+#define atomic64_sub_and_test(i, v) (atomic64_sub_ret(i, v) == 0)
 
-#define atomic_dec_and_test(v) (__atomic_sub(1, v) == 0)
-#define atomic64_dec_and_test(v) (__atomic64_sub(1, v) == 0)
+#define atomic_dec_and_test(v) (atomic_sub_ret(1, v) == 0)
+#define atomic64_dec_and_test(v) (atomic64_sub_ret(1, v) == 0)
 
-#define atomic_inc(v) ((void)__atomic_add(1, v))
-#define atomic64_inc(v) ((void)__atomic64_add(1, v))
+#define atomic_inc(v) atomic_add(1, v)
+#define atomic64_inc(v) atomic64_add(1, v)
 
-#define atomic_dec(v) ((void)__atomic_sub(1, v))
-#define atomic64_dec(v) ((void)__atomic64_sub(1, v))
+#define atomic_dec(v) atomic_sub(1, v)
+#define atomic64_dec(v) atomic64_sub(1, v)
 
-#define atomic_add_negative(i, v) (__atomic_add(i, v) < 0)
-#define atomic64_add_negative(i, v) (__atomic64_add(i, v) < 0)
+#define atomic_add_negative(i, v) (atomic_add_ret(i, v) < 0)
+#define atomic64_add_negative(i, v) (atomic64_add_ret(i, v) < 0)
 
 /* Atomic operations are already serializing */
+#ifdef CONFIG_SMP
+#define smp_mb__before_atomic_dec()	membar("#StoreLoad | #LoadLoad")
+#define smp_mb__after_atomic_dec()	membar("#StoreLoad | #StoreStore")
+#define smp_mb__before_atomic_inc()	membar("#StoreLoad | #LoadLoad")
+#define smp_mb__after_atomic_inc()	membar("#StoreLoad | #StoreStore")
+#else
 #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
 
 #endif /* !(__ARCH_SPARC64_ATOMIC__) */
diff -Nru a/include/asm-sparc64/bitops.h b/include/asm-sparc64/bitops.h
--- a/include/asm-sparc64/bitops.h	2005-03-01 23:38:53 -08:00
+++ b/include/asm-sparc64/bitops.h	2005-03-01 23:38:53 -08:00
@@ -7,19 +7,16 @@
 #ifndef _SPARC64_BITOPS_H
 #define _SPARC64_BITOPS_H
 
+#include <linux/config.h>
 #include <linux/compiler.h>
 #include <asm/byteorder.h>
 
-extern long ___test_and_set_bit(unsigned long nr, volatile unsigned long *addr);
-extern long ___test_and_clear_bit(unsigned long nr, volatile unsigned long *addr);
-extern long ___test_and_change_bit(unsigned long nr, volatile unsigned long *addr);
-
-#define test_and_set_bit(nr,addr)	({___test_and_set_bit(nr,addr)!=0;})
-#define test_and_clear_bit(nr,addr)	({___test_and_clear_bit(nr,addr)!=0;})
-#define test_and_change_bit(nr,addr)	({___test_and_change_bit(nr,addr)!=0;})
-#define set_bit(nr,addr)		((void)___test_and_set_bit(nr,addr))
-#define clear_bit(nr,addr)		((void)___test_and_clear_bit(nr,addr))
-#define change_bit(nr,addr)		((void)___test_and_change_bit(nr,addr))
+extern int test_and_set_bit(unsigned long nr, volatile unsigned long *addr);
+extern int test_and_clear_bit(unsigned long nr, volatile unsigned long *addr);
+extern int test_and_change_bit(unsigned long nr, volatile unsigned long *addr);
+extern void set_bit(unsigned long nr, volatile unsigned long *addr);
+extern void clear_bit(unsigned long nr, volatile unsigned long *addr);
+extern void change_bit(unsigned long nr, volatile unsigned long *addr);
 
 /* "non-atomic" versions... */
 
@@ -74,8 +71,13 @@
 	return ((old & mask) != 0);
 }
 
-#define smp_mb__before_clear_bit()	do { } while(0)
-#define smp_mb__after_clear_bit()	do { } while(0)
+#ifdef CONFIG_SMP
+#define smp_mb__before_clear_bit()	membar("#StoreLoad | #LoadLoad")
+#define smp_mb__after_clear_bit()	membar("#StoreLoad | #StoreStore")
+#else
+#define smp_mb__before_clear_bit()	barrier()
+#define smp_mb__after_clear_bit()	barrier()
+#endif
 
 static __inline__ int test_bit(int nr, __const__ volatile unsigned long *addr)
 {
@@ -223,15 +225,16 @@
  * on Linus's ALPHA routines, which are pretty portable BTW.
  */
 
-extern unsigned long find_next_zero_bit(unsigned long *, unsigned long, unsigned long);
+extern unsigned long find_next_zero_bit(const unsigned long *,
+					unsigned long, unsigned long);
 
 #define find_first_zero_bit(addr, size) \
         find_next_zero_bit((addr), (size), 0)
 
 #define test_and_set_le_bit(nr,addr)	\
-	({ ___test_and_set_bit((nr) ^ 0x38, (addr)) != 0; })
+	test_and_set_bit((nr) ^ 0x38, (addr))
 #define test_and_clear_le_bit(nr,addr)	\
-	({ ___test_and_clear_bit((nr) ^ 0x38, (addr)) != 0; })
+	test_and_clear_bit((nr) ^ 0x38, (addr))
 
 static __inline__ int test_le_bit(int nr, __const__ unsigned long * addr)
 {
@@ -250,12 +253,21 @@
 
 #ifdef __KERNEL__
 
+#define __set_le_bit(nr, addr) \
+	__set_bit((nr) ^ 0x38, (addr))
+#define __clear_le_bit(nr, addr) \
+	__clear_bit((nr) ^ 0x38, (addr))
+#define __test_and_clear_le_bit(nr, addr) \
+	__test_and_clear_bit((nr) ^ 0x38, (addr))
+#define __test_and_set_le_bit(nr, addr) \
+	__test_and_set_bit((nr) ^ 0x38, (addr))
+
 #define ext2_set_bit(nr,addr)	\
-	test_and_set_le_bit((nr),(unsigned long *)(addr))
+	__test_and_set_le_bit((nr),(unsigned long *)(addr))
 #define ext2_set_bit_atomic(lock,nr,addr) \
 	test_and_set_le_bit((nr),(unsigned long *)(addr))
 #define ext2_clear_bit(nr,addr)	\
-	test_and_clear_le_bit((nr),(unsigned long *)(addr))
+	__test_and_clear_le_bit((nr),(unsigned long *)(addr))
 #define ext2_clear_bit_atomic(lock,nr,addr) \
 	test_and_clear_le_bit((nr),(unsigned long *)(addr))
 #define ext2_test_bit(nr,addr)	\
diff -Nru a/include/asm-sparc64/checksum.h b/include/asm-sparc64/checksum.h
--- a/include/asm-sparc64/checksum.h	2005-03-01 23:38:55 -08:00
+++ b/include/asm-sparc64/checksum.h	2005-03-01 23:38:55 -08:00
@@ -38,10 +38,11 @@
  * here even more important to align src and dst on a 32-bit (or even
  * better 64-bit) boundary
  */
-extern unsigned int csum_partial_copy_sparc64(const char *src, char *dst, int len, unsigned int sum);
+extern unsigned int csum_partial_copy_sparc64(const unsigned char *src, unsigned char *dst,
+					      int len, unsigned int sum);
 			
 static inline unsigned int 
-csum_partial_copy_nocheck (const char *src, char *dst, int len, 
+csum_partial_copy_nocheck (const unsigned char *src, unsigned char *dst, int len,
 			   unsigned int sum)
 {
 	int ret;
@@ -53,7 +54,7 @@
 }
 
 static inline unsigned int 
-csum_partial_copy_from_user(const char __user *src, char *dst, int len, 
+csum_partial_copy_from_user(const unsigned char __user *src, unsigned char *dst, int len,
 			    unsigned int sum, int *err)
 {
 	__asm__ __volatile__ ("stx	%0, [%%sp + 0x7ff + 128]"
@@ -66,10 +67,11 @@
  *	Copy and checksum to user
  */
 #define HAVE_CSUM_COPY_USER
-extern unsigned int csum_partial_copy_user_sparc64(const char *src, char __user *dst, int len, unsigned int sum);
+extern unsigned int csum_partial_copy_user_sparc64(const unsigned char *src, unsigned char __user *dst,
+						   int len, unsigned int sum);
 
 static inline unsigned int 
-csum_and_copy_to_user(const char *src, char __user *dst, int len, 
+csum_and_copy_to_user(const unsigned char *src, unsigned char __user *dst, int len,
 		      unsigned int sum, int *err)
 {
 	__asm__ __volatile__ ("stx	%0, [%%sp + 0x7ff + 128]"
diff -Nru a/include/asm-sparc64/compat.h b/include/asm-sparc64/compat.h
--- a/include/asm-sparc64/compat.h	2005-03-01 23:39:07 -08:00
+++ b/include/asm-sparc64/compat.h	2005-03-01 23:39:07 -08:00
@@ -24,6 +24,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_int_t;
 typedef s32		compat_long_t;
@@ -121,6 +122,11 @@
 	return (void __user *)(unsigned long)uptr;
 }
 
+static inline compat_uptr_t ptr_to_compat(void __user *uptr)
+{
+	return (u32)(unsigned long)uptr;
+}
+
 static __inline__ void __user *compat_alloc_user_space(long len)
 {
 	struct pt_regs *regs = current_thread_info()->kregs;
@@ -128,8 +134,68 @@
 
 	if (!(test_thread_flag(TIF_32BIT)))
 		usp += STACK_BIAS;
+	else
+		usp &= 0xffffffffUL;
 
 	return (void __user *) (usp - len);
 }
+
+struct compat_ipc64_perm {
+	compat_key_t key;
+	__kernel_uid_t uid;
+	__kernel_gid_t gid;
+	__kernel_uid_t cuid;
+	__kernel_gid_t cgid;
+	unsigned short __pad1;
+	compat_mode_t mode;
+	unsigned short __pad2;
+	unsigned short seq;
+	unsigned long __unused1;	/* yes they really are 64bit pads */
+	unsigned long __unused2;
+};
+
+struct compat_semid64_ds {
+	struct compat_ipc64_perm sem_perm;
+	unsigned int	__pad1;
+	compat_time_t	sem_otime;
+	unsigned int	__pad2;
+	compat_time_t	sem_ctime;
+	u32		sem_nsems;
+	u32		__unused1;
+	u32		__unused2;
+};
+
+struct compat_msqid64_ds {
+	struct compat_ipc64_perm msg_perm;
+	unsigned int	__pad1;
+	compat_time_t	msg_stime;
+	unsigned int	__pad2;
+	compat_time_t	msg_rtime;
+	unsigned int	__pad3;
+	compat_time_t	msg_ctime;
+	unsigned int	msg_cbytes;
+	unsigned int	msg_qnum;
+	unsigned int	msg_qbytes;
+	compat_pid_t	msg_lspid;
+	compat_pid_t	msg_lrpid;
+	unsigned int	__unused1;
+	unsigned int	__unused2;
+};
+
+struct compat_shmid64_ds {
+	struct compat_ipc64_perm shm_perm;
+	unsigned int	__pad1;
+	compat_time_t	shm_atime;
+	unsigned int	__pad2;
+	compat_time_t	shm_dtime;
+	unsigned int	__pad3;
+	compat_time_t	shm_ctime;
+	compat_size_t	shm_segsz;
+	compat_pid_t	shm_cpid;
+	compat_pid_t	shm_lpid;
+	unsigned int	shm_nattch;
+	unsigned int	__unused1;
+	unsigned int	__unused2;
+};
 
 #endif /* _ASM_SPARC64_COMPAT_H */
diff -Nru a/include/asm-sparc64/cputime.h b/include/asm-sparc64/cputime.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-sparc64/cputime.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,6 @@
+#ifndef __SPARC64_CPUTIME_H
+#define __SPARC64_CPUTIME_H
+
+#include <asm-generic/cputime.h>
+
+#endif /* __SPARC64_CPUTIME_H */
diff -Nru a/include/asm-sparc64/fbio.h b/include/asm-sparc64/fbio.h
--- a/include/asm-sparc64/fbio.h	2005-03-01 23:38:44 -08:00
+++ b/include/asm-sparc64/fbio.h	2005-03-01 23:38:44 -08:00
@@ -102,8 +102,8 @@
         struct fbcurpos hot;    /* cursor hot spot */
         struct fbcmap cmap;     /* color map info */
         struct fbcurpos size;   /* cursor bit map size */
-        char *image;            /* cursor image bits */
-        char *mask;             /* cursor mask bits */
+        char __user *image;     /* cursor image bits */
+        char __user *mask;      /* cursor mask bits */
 };
 
 /* set/get cursor attributes/shape */
diff -Nru a/include/asm-sparc64/hardirq.h b/include/asm-sparc64/hardirq.h
--- a/include/asm-sparc64/hardirq.h	2005-03-01 23:39:08 -08:00
+++ b/include/asm-sparc64/hardirq.h	2005-03-01 23:39:08 -08:00
@@ -20,13 +20,4 @@
 
 #define HARDIRQ_BITS	8
 
-#define irq_enter()		(preempt_count() += HARDIRQ_OFFSET)
-#define irq_exit()							\
-do {									\
-		preempt_count() -= IRQ_EXIT_OFFSET;			\
-		if (!in_interrupt() && softirq_pending(smp_processor_id())) \
-			do_softirq();					\
-		preempt_enable_no_resched();				\
-} while (0)
-
 #endif /* !(__SPARC64_HARDIRQ_H) */
diff -Nru a/include/asm-sparc64/io.h b/include/asm-sparc64/io.h
--- a/include/asm-sparc64/io.h	2005-03-01 23:39:09 -08:00
+++ b/include/asm-sparc64/io.h	2005-03-01 23:39:09 -08:00
@@ -417,13 +417,13 @@
 
 #define memcpy_toio(d,s,sz)	_memcpy_toio(d,s,sz)
 
-static inline int check_signature(unsigned long io_addr,
+static inline int check_signature(void __iomem *io_addr,
 				  const unsigned char *signature,
 				  int length)
 {
 	int retval = 0;
 	do {
-		if (readb((void __iomem *)io_addr) != *signature++)
+		if (readb(io_addr) != *signature++)
 			goto out;
 		io_addr++;
 	} while (--length);
diff -Nru a/include/asm-sparc64/kprobes.h b/include/asm-sparc64/kprobes.h
--- a/include/asm-sparc64/kprobes.h	2005-03-01 23:38:59 -08:00
+++ b/include/asm-sparc64/kprobes.h	2005-03-01 23:38:59 -08:00
@@ -10,6 +10,8 @@
 #define BREAKPOINT_INSTRUCTION_2 0x91d02071 /* ta 0x71 */
 #define MAX_INSN_SIZE 2
 
+#define JPROBE_ENTRY(pentry)	(kprobe_opcode_t *)pentry
+
 /* Architecture specific copy of original instruction*/
 struct arch_specific_insn {
 	/* copy of the original instruction */
diff -Nru a/include/asm-sparc64/mmu_context.h b/include/asm-sparc64/mmu_context.h
--- a/include/asm-sparc64/mmu_context.h	2005-03-01 23:39:17 -08:00
+++ b/include/asm-sparc64/mmu_context.h	2005-03-01 23:39:17 -08:00
@@ -83,8 +83,7 @@
 	paddr = __pa((__mm)->pgd); \
 	pgd_cache = 0UL; \
 	if ((__tsk)->thread_info->flags & _TIF_32BIT) \
-		pgd_cache = \
-		  ((unsigned long)pgd_val((__mm)->pgd[0])) << 11UL; \
+		pgd_cache = get_pgd_cache((__mm)->pgd); \
 	__asm__ __volatile__("wrpr	%%g0, 0x494, %%pstate\n\t" \
 			     "mov	%3, %%g4\n\t" \
 			     "mov	%0, %%g7\n\t" \
diff -Nru a/include/asm-sparc64/page.h b/include/asm-sparc64/page.h
--- a/include/asm-sparc64/page.h	2005-03-01 23:38:56 -08:00
+++ b/include/asm-sparc64/page.h	2005-03-01 23:38:56 -08:00
@@ -21,11 +21,14 @@
 #define copy_page(X,Y)	memcpy((void *)(X), (void *)(Y), PAGE_SIZE)
 extern void copy_user_page(void *to, void *from, unsigned long vaddr, struct page *topage);
 
-/* GROSS, defining this makes gcc pass these types as aggregates,
- * and thus on the stack, turn this crap off... -DaveM
+/* Unlike sparc32, sparc64's parameter passing API is more
+ * sane in that structures which as small enough are passed
+ * in registers instead of on the stack.  Thus, setting
+ * STRICT_MM_TYPECHECKS does not generate worse code so
+ * let's enable it to get the type checking.
  */
 
-/* #define STRICT_MM_TYPECHECKS */
+#define STRICT_MM_TYPECHECKS
 
 #ifdef STRICT_MM_TYPECHECKS
 /* These are used to make use of C type-checking.. */
@@ -33,25 +36,19 @@
 typedef struct { unsigned long iopte; } iopte_t;
 typedef struct { unsigned int pmd; } pmd_t;
 typedef struct { unsigned int pgd; } pgd_t;
-typedef struct { unsigned long ctxd; } ctxd_t;
 typedef struct { unsigned long pgprot; } pgprot_t;
-typedef struct { unsigned long iopgprot; } iopgprot_t;
 
 #define pte_val(x)	((x).pte)
 #define iopte_val(x)	((x).iopte)
 #define pmd_val(x)      ((x).pmd)
 #define pgd_val(x)	((x).pgd)
-#define ctxd_val(x)	((x).ctxd)
 #define pgprot_val(x)	((x).pgprot)
-#define iopgprot_val(x)	((x).iopgprot)
 
 #define __pte(x)	((pte_t) { (x) } )
 #define __iopte(x)	((iopte_t) { (x) } )
 #define __pmd(x)        ((pmd_t) { (x) } )
 #define __pgd(x)	((pgd_t) { (x) } )
-#define __ctxd(x)	((ctxd_t) { (x) } )
 #define __pgprot(x)	((pgprot_t) { (x) } )
-#define __iopgprot(x)	((iopgprot_t) { (x) } )
 
 #else
 /* .. while these make it easier on the compiler */
@@ -59,25 +56,19 @@
 typedef unsigned long iopte_t;
 typedef unsigned int pmd_t;
 typedef unsigned int pgd_t;
-typedef unsigned long ctxd_t;
 typedef unsigned long pgprot_t;
-typedef unsigned long iopgprot_t;
 
 #define pte_val(x)	(x)
 #define iopte_val(x)	(x)
 #define pmd_val(x)      (x)
 #define pgd_val(x)	(x)
-#define ctxd_val(x)	(x)
 #define pgprot_val(x)	(x)
-#define iopgprot_val(x)	(x)
 
 #define __pte(x)	(x)
 #define __iopte(x)	(x)
 #define __pmd(x)        (x)
 #define __pgd(x)	(x)
-#define __ctxd(x)	(x)
 #define __pgprot(x)	(x)
-#define __iopgprot(x)	(x)
 
 #endif /* (STRICT_MM_TYPECHECKS) */
 
diff -Nru a/include/asm-sparc64/pgalloc.h b/include/asm-sparc64/pgalloc.h
--- a/include/asm-sparc64/pgalloc.h	2005-03-01 23:39:16 -08:00
+++ b/include/asm-sparc64/pgalloc.h	2005-03-01 23:39:16 -08:00
@@ -73,10 +73,9 @@
 		struct page *page;
 
 		preempt_enable();
-		page = alloc_page(GFP_KERNEL|__GFP_REPEAT);
+		page = alloc_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO);
 		if (page) {
 			ret = (struct page *)page_address(page);
-			clear_page(ret);
 			page->lru.prev = (void *) 2UL;
 
 			preempt_disable();
@@ -134,7 +133,7 @@
 #define DCACHE_COLOR(address)		0
 #endif
 
-#define pgd_populate(MM, PGD, PMD)	pgd_set(PGD, PMD)
+#define pud_populate(MM, PUD, PMD)	pud_set(PUD, PMD)
 
 static __inline__ pmd_t *pmd_alloc_one_fast(struct mm_struct *mm, unsigned long address)
 {
diff -Nru a/include/asm-sparc64/pgtable.h b/include/asm-sparc64/pgtable.h
--- a/include/asm-sparc64/pgtable.h	2005-03-01 23:38:51 -08:00
+++ b/include/asm-sparc64/pgtable.h	2005-03-01 23:38:51 -08:00
@@ -12,6 +12,8 @@
  * the SpitFire page tables.
  */
 
+#include <asm-generic/pgtable-nopud.h>
+
 #include <linux/config.h>
 #include <asm/spitfire.h>
 #include <asm/asi.h>
@@ -261,23 +263,23 @@
 }
 #define pmd_set(pmdp, ptep)	\
 	(pmd_val(*(pmdp)) = (__pa((unsigned long) (ptep)) >> 11UL))
-#define pgd_set(pgdp, pmdp)	\
-	(pgd_val(*(pgdp)) = (__pa((unsigned long) (pmdp)) >> 11UL))
+#define pud_set(pudp, pmdp)	\
+	(pud_val(*(pudp)) = (__pa((unsigned long) (pmdp)) >> 11UL))
 #define __pmd_page(pmd)		\
 	((unsigned long) __va((((unsigned long)pmd_val(pmd))<<11UL)))
 #define pmd_page(pmd) 			virt_to_page((void *)__pmd_page(pmd))
-#define pgd_page(pgd)		\
-	((unsigned long) __va((((unsigned long)pgd_val(pgd))<<11UL)))
+#define pud_page(pud)		\
+	((unsigned long) __va((((unsigned long)pud_val(pud))<<11UL)))
 #define pte_none(pte) 			(!pte_val(pte))
 #define pte_present(pte)		(pte_val(pte) & _PAGE_PRESENT)
 #define pmd_none(pmd)			(!pmd_val(pmd))
 #define pmd_bad(pmd)			(0)
 #define pmd_present(pmd)		(pmd_val(pmd) != 0U)
 #define pmd_clear(pmdp)			(pmd_val(*(pmdp)) = 0U)
-#define pgd_none(pgd)			(!pgd_val(pgd))
-#define pgd_bad(pgd)			(0)
-#define pgd_present(pgd)		(pgd_val(pgd) != 0U)
-#define pgd_clear(pgdp)			(pgd_val(*(pgdp)) = 0U)
+#define pud_none(pud)			(!pud_val(pud))
+#define pud_bad(pud)			(0)
+#define pud_present(pud)		(pud_val(pud) != 0U)
+#define pud_clear(pudp)			(pud_val(*(pudp)) = 0U)
 
 /* The following only work if pte_present() is true.
  * Undefined behaviour if not..
@@ -310,10 +312,15 @@
 /* to find an entry in a kernel page-table-directory */
 #define pgd_offset_k(address) pgd_offset(&init_mm, address)
 
+/* extract the pgd cache used for optimizing the tlb miss
+ * slow path when executing 32-bit compat processes
+ */
+#define get_pgd_cache(pgd)	((unsigned long) pgd_val(*pgd) << 11)
+
 /* Find an entry in the second-level page table.. */
-#define pmd_offset(dir, address)	\
-	((pmd_t *) pgd_page(*(dir)) + \
-	 ((address >> PMD_SHIFT) & (REAL_PTRS_PER_PMD-1)))
+#define pmd_offset(pudp, address)	\
+	((pmd_t *) pud_page(*(pudp)) + \
+	 (((address) >> PMD_SHIFT) & (REAL_PTRS_PER_PMD-1)))
 
 /* Find an entry in the third-level page table.. */
 #define pte_index(dir, address)	\
@@ -382,6 +389,7 @@
 sun4u_get_pte (unsigned long addr)
 {
 	pgd_t *pgdp;
+	pud_t *pudp;
 	pmd_t *pmdp;
 	pte_t *ptep;
 
@@ -390,7 +398,8 @@
 	if ((addr >= LOW_OBP_ADDRESS) && (addr < HI_OBP_ADDRESS))
 		return prom_virt_to_phys(addr, NULL);
 	pgdp = pgd_offset_k(addr);
-	pmdp = pmd_offset(pgdp, addr);
+	pudp = pud_offset(pgdp, addr);
+	pmdp = pmd_offset(pudp, addr);
 	ptep = pte_offset_kernel(pmdp, addr);
 	return pte_val(*ptep) & _PAGE_PADDR;
 }
diff -Nru a/include/asm-sparc64/processor.h b/include/asm-sparc64/processor.h
--- a/include/asm-sparc64/processor.h	2005-03-01 23:38:44 -08:00
+++ b/include/asm-sparc64/processor.h	2005-03-01 23:38:44 -08:00
@@ -21,10 +21,6 @@
 #include <asm/segment.h>
 #include <asm/page.h>
 
-/* Bus types */
-#define MCA_bus 0
-#define MCA_bus__is_a_macro /* for versions in ksyms.c */
-
 /* The sparc has no problems with write protection */
 #define wp_works_ok 1
 #define wp_works_ok__is_a_macro /* for versions in ksyms.c */
diff -Nru a/include/asm-sparc64/resource.h b/include/asm-sparc64/resource.h
--- a/include/asm-sparc64/resource.h	2005-03-01 23:38:51 -08:00
+++ b/include/asm-sparc64/resource.h	2005-03-01 23:38:51 -08:00
@@ -26,30 +26,8 @@
 #define RLIMIT_MSGQUEUE 12		/* maximum bytes in POSIX mqueues */
 
 #define RLIM_NLIMITS	13
+#define __ARCH_RLIMIT_ORDER
 
-/*
- * SuS says limits have to be unsigned.
- * Which makes a ton more sense anyway.
- */
-#define RLIM_INFINITY	(~0UL)
-
-#ifdef __KERNEL__
-#define INIT_RLIMITS			\
-{					\
-    {RLIM_INFINITY, RLIM_INFINITY},	\
-    {RLIM_INFINITY, RLIM_INFINITY},	\
-    {RLIM_INFINITY, RLIM_INFINITY},	\
-    {_STK_LIM, RLIM_INFINITY},		\
-    {       0, RLIM_INFINITY},		\
-    {RLIM_INFINITY, RLIM_INFINITY},	\
-    {INR_OPEN, INR_OPEN}, {0, 0},	\
-    {  MLOCK_LIMIT,   MLOCK_LIMIT},	\
-    {RLIM_INFINITY, RLIM_INFINITY},	\
-    {RLIM_INFINITY, RLIM_INFINITY},	\
-    {MAX_SIGPENDING, MAX_SIGPENDING},	\
-    {MQ_BYTES_MAX, MQ_BYTES_MAX},	\
-}
-
-#endif /* __KERNEL__ */
+#include <asm-generic/resource.h>
 
 #endif /* !(_SPARC64_RESOURCE_H) */
diff -Nru a/include/asm-sparc64/sections.h b/include/asm-sparc64/sections.h
--- a/include/asm-sparc64/sections.h	2005-03-01 23:38:53 -08:00
+++ b/include/asm-sparc64/sections.h	2005-03-01 23:38:53 -08:00
@@ -4,6 +4,6 @@
 /* nothing to see, move along */
 #include <asm-generic/sections.h>
 
-extern char _end[], _start[];
+extern char _start[];
 
 #endif
diff -Nru a/include/asm-sparc64/siginfo.h b/include/asm-sparc64/siginfo.h
--- a/include/asm-sparc64/siginfo.h	2005-03-01 23:39:08 -08:00
+++ b/include/asm-sparc64/siginfo.h	2005-03-01 23:39:08 -08:00
@@ -24,7 +24,7 @@
 	u32 sival_ptr;
 } sigval_t32;
 
-struct siginfo32;
+struct compat_siginfo;
 
 #endif /* CONFIG_COMPAT */
 
@@ -55,9 +55,6 @@
 		} _sigev_thread;
 	} _sigev_un;
 } sigevent_t32;
-
-extern int copy_siginfo_to_user32(struct siginfo32 __user *to, siginfo_t *from);
-extern int copy_siginfo_to_kernel32(siginfo_t *to, struct siginfo32 __user *from);
 
 #endif /* CONFIG_COMPAT */
 
diff -Nru a/include/asm-sparc64/spinlock.h b/include/asm-sparc64/spinlock.h
--- a/include/asm-sparc64/spinlock.h	2005-03-01 23:38:53 -08:00
+++ b/include/asm-sparc64/spinlock.h	2005-03-01 23:38:53 -08:00
@@ -142,7 +142,6 @@
 typedef unsigned int rwlock_t;
 #define RW_LOCK_UNLOCKED	0
 #define rwlock_init(lp) do { *(lp) = RW_LOCK_UNLOCKED; } while(0)
-#define rwlock_is_locked(x) (*(x) != RW_LOCK_UNLOCKED)
 
 static void inline __read_lock(rwlock_t *lock)
 {
@@ -172,12 +171,13 @@
 	unsigned long tmp1, tmp2;
 
 	__asm__ __volatile__(
+"	membar	#StoreLoad | #LoadLoad\n"
 "1:	lduw	[%2], %0\n"
 "	sub	%0, 1, %1\n"
 "	cas	[%2], %0, %1\n"
 "	cmp	%0, %1\n"
 "	bne,pn	%%xcc, 1b\n"
-"	 membar	#StoreLoad | #StoreStore"
+"	 nop"
 	: "=&r" (tmp1), "=&r" (tmp2)
 	: "r" (lock)
 	: "memory");
@@ -257,7 +257,6 @@
 } rwlock_t;
 #define RW_LOCK_UNLOCKED	(rwlock_t) { 0, 0, 0xff, { } }
 #define rwlock_init(lp) do { *(lp) = RW_LOCK_UNLOCKED; } while(0)
-#define rwlock_is_locked(x) ((x)->lock != 0)
 
 extern void _do_read_lock(rwlock_t *rw, char *str);
 extern void _do_read_unlock(rwlock_t *rw, char *str);
@@ -303,6 +302,8 @@
 })
 
 #endif /* CONFIG_DEBUG_SPINLOCK */
+
+#define _raw_read_trylock(lock) generic_raw_read_trylock(lock)
 
 #endif /* !(__ASSEMBLY__) */
 
diff -Nru a/include/asm-sparc64/system.h b/include/asm-sparc64/system.h
--- a/include/asm-sparc64/system.h	2005-03-01 23:38:44 -08:00
+++ b/include/asm-sparc64/system.h	2005-03-01 23:38:44 -08:00
@@ -78,9 +78,9 @@
 
 #define nop() 		__asm__ __volatile__ ("nop")
 
-#define membar(type)	__asm__ __volatile__ ("membar " type : : : "memory");
+#define membar(type)	__asm__ __volatile__ ("membar " type : : : "memory")
 #define mb()		\
-	membar("#LoadLoad | #LoadStore | #StoreStore | #StoreLoad");
+	membar("#LoadLoad | #LoadStore | #StoreStore | #StoreLoad")
 #define rmb()		membar("#LoadLoad")
 #define wmb()		membar("#StoreStore")
 #define read_barrier_depends()		do { } while(0)
@@ -95,9 +95,9 @@
 #define smp_wmb()	wmb()
 #define smp_read_barrier_depends()	read_barrier_depends()
 #else
-#define smp_mb()	__asm__ __volatile__("":::"memory");
-#define smp_rmb()	__asm__ __volatile__("":::"memory");
-#define smp_wmb()	__asm__ __volatile__("":::"memory");
+#define smp_mb()	__asm__ __volatile__("":::"memory")
+#define smp_rmb()	__asm__ __volatile__("":::"memory")
+#define smp_wmb()	__asm__ __volatile__("":::"memory")
 #define smp_read_barrier_depends()	do { } while(0)
 #endif
 
@@ -107,7 +107,7 @@
 
 /* Performance counter register access. */
 #define read_pcr(__p)  __asm__ __volatile__("rd	%%pcr, %0" : "=r" (__p))
-#define write_pcr(__p) __asm__ __volatile__("wr	%0, 0x0, %%pcr" : : "r" (__p));
+#define write_pcr(__p) __asm__ __volatile__("wr	%0, 0x0, %%pcr" : : "r" (__p))
 #define read_pic(__p)  __asm__ __volatile__("rd %%pic, %0" : "=r" (__p))
 
 /* Blackbird errata workaround.  See commentary in
@@ -229,6 +229,7 @@
 static __inline__ unsigned long xchg32(__volatile__ unsigned int *m, unsigned int val)
 {
 	__asm__ __volatile__(
+"	membar		#StoreLoad | #LoadLoad\n"
 "	mov		%0, %%g5\n"
 "1:	lduw		[%2], %%g7\n"
 "	cas		[%2], %%g7, %0\n"
@@ -245,6 +246,7 @@
 static __inline__ unsigned long xchg64(__volatile__ unsigned long *m, unsigned long val)
 {
 	__asm__ __volatile__(
+"	membar		#StoreLoad | #LoadLoad\n"
 "	mov		%0, %%g5\n"
 "1:	ldx		[%2], %%g7\n"
 "	casx		[%2], %%g7, %0\n"
@@ -289,7 +291,8 @@
 static __inline__ unsigned long
 __cmpxchg_u32(volatile int *m, int old, int new)
 {
-	__asm__ __volatile__("cas [%2], %3, %0\n\t"
+	__asm__ __volatile__("membar #StoreLoad | #LoadLoad\n"
+			     "cas [%2], %3, %0\n\t"
 			     "membar #StoreLoad | #StoreStore"
 			     : "=&r" (new)
 			     : "0" (new), "r" (m), "r" (old)
@@ -301,7 +304,8 @@
 static __inline__ unsigned long
 __cmpxchg_u64(volatile long *m, unsigned long old, unsigned long new)
 {
-	__asm__ __volatile__("casx [%2], %3, %0\n\t"
+	__asm__ __volatile__("membar #StoreLoad | #LoadLoad\n"
+			     "casx [%2], %3, %0\n\t"
 			     "membar #StoreLoad | #StoreStore"
 			     : "=&r" (new)
 			     : "0" (new), "r" (m), "r" (old)
diff -Nru a/include/asm-sparc64/thread_info.h b/include/asm-sparc64/thread_info.h
--- a/include/asm-sparc64/thread_info.h	2005-03-01 23:39:08 -08:00
+++ b/include/asm-sparc64/thread_info.h	2005-03-01 23:39:08 -08:00
@@ -228,6 +228,7 @@
  *       an immediate value in instructions such as andcc.
  */
 #define TIF_ABI_PENDING		12
+#define TIF_MEMDIE		13
 
 #define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE)
 #define _TIF_NOTIFY_RESUME	(1<<TIF_NOTIFY_RESUME)
diff -Nru a/include/asm-sparc64/tlb.h b/include/asm-sparc64/tlb.h
--- a/include/asm-sparc64/tlb.h	2005-03-01 23:39:08 -08:00
+++ b/include/asm-sparc64/tlb.h	2005-03-01 23:39:08 -08:00
@@ -121,6 +121,7 @@
 #define tlb_remove_tlb_entry(mp,ptep,addr) do { } while (0)
 #define pte_free_tlb(mp,ptepage) pte_free(ptepage)
 #define pmd_free_tlb(mp,pmdp) pmd_free(pmdp)
+#define pud_free_tlb(tlb,pudp) __pud_free_tlb(tlb,pudp)
 
 #define tlb_migrate_finish(mm)	do { } while (0)
 #define tlb_start_vma(tlb, vma) do { } while (0)
diff -Nru a/include/asm-sparc64/uaccess.h b/include/asm-sparc64/uaccess.h
--- a/include/asm-sparc64/uaccess.h	2005-03-01 23:39:18 -08:00
+++ b/include/asm-sparc64/uaccess.h	2005-03-01 23:39:18 -08:00
@@ -49,10 +49,10 @@
 	__asm__ __volatile__ ("wr %%g0, %0, %%asi" : : "r" ((val).seg));	\
 } while(0)
 
-#define __user_ok(addr,size) 1
+#define __user_ok(addr,size) ((void)(addr), (void)(size), 1)
 #define __kernel_ok (segment_eq(get_fs(), KERNEL_DS))
-#define __access_ok(addr,size) 1
-#define access_ok(type,addr,size) 1
+#define __access_ok(addr,size) ((void)(addr), (void)(size), 1)
+#define access_ok(type,addr,size) ((void)(type), (void)(addr), (void)(size), 1)
 
 static inline int verify_area(int type, const void __user * addr, unsigned long size)
 {
diff -Nru a/include/asm-sparc64/unistd.h b/include/asm-sparc64/unistd.h
--- a/include/asm-sparc64/unistd.h	2005-03-01 23:38:53 -08:00
+++ b/include/asm-sparc64/unistd.h	2005-03-01 23:38:53 -08:00
@@ -489,6 +489,7 @@
 #define __ARCH_WANT_SYS_SGETMASK
 #define __ARCH_WANT_SYS_SIGNAL
 #define __ARCH_WANT_SYS_TIME
+#define __ARCH_WANT_COMPAT_SYS_TIME
 #define __ARCH_WANT_SYS_UTIME
 #define __ARCH_WANT_SYS_WAITPID
 #define __ARCH_WANT_SYS_SOCKETCALL
diff -Nru a/include/asm-um/apic.h b/include/asm-um/apic.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-um/apic.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,4 @@
+#ifndef __UM_APIC_H
+#define __UM_APIC_H
+
+#endif
diff -Nru a/include/asm-um/archparam-i386.h b/include/asm-um/archparam-i386.h
--- a/include/asm-um/archparam-i386.h	2005-03-01 23:39:09 -08:00
+++ b/include/asm-um/archparam-i386.h	2005-03-01 23:39:09 -08:00
@@ -10,7 +10,8 @@
 
 #include "user.h"
 
-#define ELF_PLATFORM "i586"
+extern char * elf_aux_platform;
+#define ELF_PLATFORM (elf_aux_platform)
 
 #define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
 
@@ -56,15 +57,20 @@
 	pr_reg[16] = PT_REGS_SS(regs);		\
 } while(0);
 
-#if 0 /* Turn this back on when UML has VSYSCALL working */
-#define VSYSCALL_BASE	(__fix_to_virt(FIX_VSYSCALL))
-#else
-#define VSYSCALL_BASE	0
-#endif
-
-#define VSYSCALL_EHDR	((const struct elfhdr *) VSYSCALL_BASE)
-#define VSYSCALL_ENTRY	((unsigned long) &__kernel_vsyscall)
-extern void *__kernel_vsyscall;
+
+extern unsigned long vsyscall_ehdr;
+extern unsigned long vsyscall_end;
+extern unsigned long __kernel_vsyscall;
+
+#define VSYSCALL_BASE vsyscall_ehdr
+#define VSYSCALL_END vsyscall_end
+
+/*
+ * This is the range that is readable by user mode, and things
+ * acting like user mode such as get_user_pages.
+ */
+#define FIXADDR_USER_START      VSYSCALL_BASE
+#define FIXADDR_USER_END        VSYSCALL_END
 
 /*
  * Architecture-neutral AT_ values in 0-17, leave some room
@@ -75,8 +81,10 @@
 
 #define ARCH_DLINFO						\
 do {								\
-		NEW_AUX_ENT(AT_SYSINFO,	VSYSCALL_ENTRY);	\
-		NEW_AUX_ENT(AT_SYSINFO_EHDR, VSYSCALL_BASE);	\
+	if ( vsyscall_ehdr ) {					\
+		NEW_AUX_ENT(AT_SYSINFO,	__kernel_vsyscall);	\
+		NEW_AUX_ENT(AT_SYSINFO_EHDR, vsyscall_ehdr);	\
+	}							\
 } while (0)
 
 /*
@@ -87,22 +95,18 @@
  * Dumping its extra ELF program headers includes all the other information
  * a debugger needs to easily find how the vsyscall DSO was being used.
  */
-#if 0
-#define ELF_CORE_EXTRA_PHDRS		(VSYSCALL_EHDR->e_phnum)
-#endif
-
-#undef ELF_CORE_EXTRA_PHDRS
+#define ELF_CORE_EXTRA_PHDRS						      \
+	(vsyscall_ehdr ? (((struct elfhdr *)vsyscall_ehdr)->e_phnum) : 0 )
 
-#if 0
 #define ELF_CORE_WRITE_EXTRA_PHDRS					      \
-do {									      \
-	const struct elf_phdr *const vsyscall_phdrs =			      \
-		(const struct elf_phdr *) (VSYSCALL_BASE		      \
-					   + VSYSCALL_EHDR->e_phoff);	      \
+if ( vsyscall_ehdr ) {							      \
+	const struct elfhdr *const ehdrp = (struct elfhdr *)vsyscall_ehdr;    \
+	const struct elf_phdr *const phdrp =				      \
+		(const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff);   \
 	int i;								      \
 	Elf32_Off ofs = 0;						      \
-	for (i = 0; i < VSYSCALL_EHDR->e_phnum; ++i) {			      \
-		struct elf_phdr phdr = vsyscall_phdrs[i];		      \
+	for (i = 0; i < ehdrp->e_phnum; ++i) {				      \
+		struct elf_phdr phdr = phdrp[i];			      \
 		if (phdr.p_type == PT_LOAD) {				      \
 			ofs = phdr.p_offset = offset;			      \
 			offset += phdr.p_filesz;			      \
@@ -112,23 +116,19 @@
 		phdr.p_paddr = 0; /* match other core phdrs */		      \
 		DUMP_WRITE(&phdr, sizeof(phdr));			      \
 	}								      \
-} while (0)
+}
 #define ELF_CORE_WRITE_EXTRA_DATA					      \
-do {									      \
-	const struct elf_phdr *const vsyscall_phdrs =			      \
-		(const struct elf_phdr *) (VSYSCALL_BASE		      \
-					   + VSYSCALL_EHDR->e_phoff);	      \
+if ( vsyscall_ehdr ) {							      \
+	const struct elfhdr *const ehdrp = (struct elfhdr *)vsyscall_ehdr;    \
+	const struct elf_phdr *const phdrp =				      \
+		(const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff);   \
 	int i;								      \
-	for (i = 0; i < VSYSCALL_EHDR->e_phnum; ++i) {			      \
-		if (vsyscall_phdrs[i].p_type == PT_LOAD)		      \
-			DUMP_WRITE((void *) vsyscall_phdrs[i].p_vaddr,	      \
-				   vsyscall_phdrs[i].p_filesz);		      \
+	for (i = 0; i < ehdrp->e_phnum; ++i) {				      \
+		if (phdrp[i].p_type == PT_LOAD)				      \
+			DUMP_WRITE((void *) phdrp[i].p_vaddr,		      \
+				   phdrp[i].p_filesz);			      \
 	}								      \
-} while (0)
-#endif
-
-#undef ELF_CORE_WRITE_EXTRA_PHDRS
-#undef ELF_CORE_WRITE_EXTRA_DATA
+}
 
 #define R_386_NONE	0
 #define R_386_32	1
@@ -142,10 +142,6 @@
 #define R_386_GOTOFF	9
 #define R_386_GOTPC	10
 #define R_386_NUM	11
-
-/********* Bits for asm-um/delay.h **********/
-
-typedef unsigned long um_udelay_t;
 
 /********* Nothing for asm-um/hardirq.h **********/
 
diff -Nru a/include/asm-um/archparam-ppc.h b/include/asm-um/archparam-ppc.h
--- a/include/asm-um/archparam-ppc.h	2005-03-01 23:38:52 -08:00
+++ b/include/asm-um/archparam-ppc.h	2005-03-01 23:38:52 -08:00
@@ -21,10 +21,6 @@
 #define ELF_DATA        ELFDATA2MSB
 #define ELF_ARCH	EM_PPC
 
-/********* Bits for asm-um/delay.h **********/
-
-typedef unsigned int um_udelay_t;
-
 /********* Bits for asm-um/hw_irq.h **********/
 
 struct hw_interrupt_type;
diff -Nru a/include/asm-um/archparam-x86_64.h b/include/asm-um/archparam-x86_64.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-um/archparam-x86_64.h	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2003 PathScale, Inc.
+ *
+ * Licensed under the GPL
+ */
+
+#ifndef __UM_ARCHPARAM_X86_64_H
+#define __UM_ARCHPARAM_X86_64_H
+
+#include <asm/user.h>
+
+#define ELF_PLATFORM "x86_64"
+
+#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
+
+typedef unsigned long elf_greg_t;
+typedef struct { } elf_fpregset_t;
+
+#define ELF_NGREG (sizeof (struct user_regs_struct) / sizeof(elf_greg_t))
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+#define ELF_DATA        ELFDATA2LSB
+#define ELF_ARCH        EM_X86_64
+
+#define ELF_PLAT_INIT(regs, load_addr)    do { \
+	PT_REGS_RBX(regs) = 0; \
+	PT_REGS_RCX(regs) = 0; \
+	PT_REGS_RDX(regs) = 0; \
+	PT_REGS_RSI(regs) = 0; \
+	PT_REGS_RDI(regs) = 0; \
+	PT_REGS_RBP(regs) = 0; \
+	PT_REGS_RAX(regs) = 0; \
+	PT_REGS_R8(regs) = 0; \
+	PT_REGS_R9(regs) = 0; \
+	PT_REGS_R10(regs) = 0; \
+	PT_REGS_R11(regs) = 0; \
+	PT_REGS_R12(regs) = 0; \
+	PT_REGS_R13(regs) = 0; \
+	PT_REGS_R14(regs) = 0; \
+	PT_REGS_R15(regs) = 0; \
+} while (0)
+
+#ifdef TIF_IA32 /* XXX */
+        clear_thread_flag(TIF_IA32);
+#endif
+
+/* No user-accessible fixmap addresses, i.e. vsyscall */
+#define FIXADDR_USER_START	0
+#define FIXADDR_USER_END	0
+
+#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 -Nru a/include/asm-um/calling.h b/include/asm-um/calling.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-um/calling.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,9 @@
+# Copyright 2003 - 2004 Pathscale, Inc
+# Released under the GPL
+
+#ifndef __UM_CALLING_H /* XXX x86_64 */
+#define __UM_CALLING_H
+
+#include "asm/arch/calling.h"
+
+#endif
diff -Nru a/include/asm-um/cputime.h b/include/asm-um/cputime.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-um/cputime.h	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,6 @@
+#ifndef __UM_CPUTIME_H
+#define __UM_CPUTIME_H
+
+#include <asm-generic/cputime.h>
+
+#endif /* __UM_CPUTIME_H */
diff -Nru a/include/asm-um/dwarf2.h b/include/asm-um/dwarf2.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-um/dwarf2.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,11 @@
+/* Copyright 2003 - 2004 Pathscale, Inc
+ * Released under the GPL
+ */
+
+/* Needed on x86_64 by thunk.S */
+#ifndef __UM_DWARF2_H
+#define __UM_DWARF2_H
+
+#include "asm/arch/dwarf2.h"
+
+#endif
diff -Nru a/include/asm-um/elf.h b/include/asm-um/elf.h
--- a/include/asm-um/elf.h	2005-03-01 23:39:07 -08:00
+++ b/include/asm-um/elf.h	2005-03-01 23:39:07 -08:00
@@ -1,9 +1,11 @@
 #ifndef __UM_ELF_H
 #define __UM_ELF_H
 
+#include "linux/config.h"
 #include "asm/archparam.h"
 
-#define ELF_HWCAP (0)
+extern long elf_aux_hwcap;
+#define ELF_HWCAP (elf_aux_hwcap)
 
 #define SET_PERSONALITY(ex, ibcs2) do ; while(0)
 
@@ -11,7 +13,11 @@
 
 #define elf_check_arch(x) (1)
 
+#ifdef CONFIG_64_BIT
+#define ELF_CLASS ELFCLASS64
+#else
 #define ELF_CLASS ELFCLASS32
+#endif
 
 #define USE_ELF_CORE_DUMP
 
diff -Nru a/include/asm-um/fixmap.h b/include/asm-um/fixmap.h
--- a/include/asm-um/fixmap.h	2005-03-01 23:39:16 -08:00
+++ b/include/asm-um/fixmap.h	2005-03-01 23:39:16 -08:00
@@ -3,6 +3,7 @@
 
 #include <linux/config.h>
 #include <asm/kmap_types.h>
+#include <asm/archparam.h>
 
 /*
  * Here we define all the compile-time 'special' virtual
@@ -34,7 +35,6 @@
 	FIX_KMAP_BEGIN,	/* reserved pte's for temporary kernel mappings */
 	FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
 #endif
-	FIX_VSYSCALL,
 	__end_of_fixed_addresses
 };
 
@@ -63,13 +63,6 @@
 
 #define __fix_to_virt(x)	(FIXADDR_TOP - ((x) << PAGE_SHIFT))
 #define __virt_to_fix(x)      ((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT)
-
-/*
- * This is the range that is readable by user mode, and things
- * acting like user mode such as get_user_pages.
- */
-#define FIXADDR_USER_START	(__fix_to_virt(FIX_VSYSCALL))
-#define FIXADDR_USER_END	(FIXADDR_USER_START + PAGE_SIZE)
 
 extern void __this_fixmap_does_not_exist(void);
 
diff -Nru a/include/asm-um/module-x86_64.h b/include/asm-um/module-x86_64.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-um/module-x86_64.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2003 PathScale, Inc.
+ *
+ * Licensed under the GPL
+ */
+
+#ifndef __UM_MODULE_X86_64_H
+#define __UM_MODULE_X86_64_H
+
+/* UML is simple */
+struct mod_arch_specific
+{
+};
+
+#define Elf_Shdr Elf64_Shdr
+#define Elf_Sym Elf64_Sym
+#define Elf_Ehdr Elf64_Ehdr
+
+#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 -Nru a/include/asm-um/page.h b/include/asm-um/page.h
--- a/include/asm-um/page.h	2005-03-01 23:39:18 -08:00
+++ b/include/asm-um/page.h	2005-03-01 23:39:18 -08:00
@@ -1,5 +1,6 @@
 /*
- *  Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
+ * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
+ * Copyright 2003 PathScale, Inc.
  * Licensed under the GPL
  */
 
@@ -8,18 +9,82 @@
 
 struct page;
 
-#include "asm/arch/page.h"
+#include <linux/config.h>
+#include <asm/vm-flags.h>
 
-#undef __pa
-#undef __va
-#undef pfn_to_page
-#undef page_to_pfn
-#undef virt_to_page
-#undef pfn_valid
-#undef virt_addr_valid
-#undef VALID_PAGE
-#undef PAGE_OFFSET
-#undef KERNELBASE
+/* PAGE_SHIFT determines the page size */
+#define PAGE_SHIFT	12
+#define PAGE_SIZE	(1UL << PAGE_SHIFT)
+#define PAGE_MASK	(~(PAGE_SIZE-1))
+
+/*
+ * These are used to make use of C type-checking..
+ */
+
+#define clear_page(page)	memset((void *)(page), 0, PAGE_SIZE)
+#define copy_page(to,from)	memcpy((void *)(to), (void *)(from), PAGE_SIZE)
+
+#define clear_user_page(page, vaddr, pg)	clear_page(page)
+#define copy_user_page(to, from, vaddr, pg)	copy_page(to, from)
+
+#if defined(CONFIG_3_LEVEL_PGTABLES) && !defined(CONFIG_64_BIT)
+
+typedef struct { unsigned long pte_low, pte_high; } pte_t;
+typedef struct { unsigned long long pmd; } pmd_t;
+typedef struct { unsigned long pgd; } pgd_t;
+#define pte_val(x) ((x).pte_low | ((unsigned long long) (x).pte_high << 32))
+
+#define pte_get_bits(pte, bits) ((pte).pte_low & (bits))
+#define pte_set_bits(pte, bits) ((pte).pte_low |= (bits))
+#define pte_clear_bits(pte, bits) ((pte).pte_low &= ~(bits))
+#define pte_copy(to, from) ({ (to).pte_high = (from).pte_high; \
+			      smp_wmb(); \
+			      (to).pte_low = (from).pte_low; })
+#define pte_is_zero(pte) (!((pte).pte_low & ~_PAGE_NEWPAGE) && !(pte).pte_high)
+#define pte_set_val(pte, phys, prot) \
+	({ (pte).pte_high = (phys) >> 32; \
+	   (pte).pte_low = (phys) | pgprot_val(prot); })
+
+typedef unsigned long long pfn_t;
+typedef unsigned long long phys_t;
+
+#else
+
+typedef struct { unsigned long pte; } pte_t;
+typedef struct { unsigned long pgd; } pgd_t;
+
+#ifdef CONFIG_3_LEVEL_PGTABLES
+typedef struct { unsigned long pmd; } pmd_t;
+#define pmd_val(x)	((x).pmd)
+#define __pmd(x) ((pmd_t) { (x) } )
+#endif
+
+#define pte_val(x)	((x).pte)
+
+
+#define pte_get_bits(p, bits) ((p).pte & (bits))
+#define pte_set_bits(p, bits) ((p).pte |= (bits))
+#define pte_clear_bits(p, bits) ((p).pte &= ~(bits))
+#define pte_copy(to, from) ((to).pte = (from).pte)
+#define pte_is_zero(p) (!((p).pte & ~_PAGE_NEWPAGE))
+#define pte_set_val(p, phys, prot) (p).pte = (phys | pgprot_val(prot))
+
+typedef unsigned long pfn_t;
+typedef unsigned long phys_t;
+
+#endif
+
+typedef struct { unsigned long pgprot; } pgprot_t;
+
+#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) } )
+
+/* to align the pointer to the (next) page boundary */
+#define PAGE_ALIGN(addr)	(((addr)+PAGE_SIZE-1)&PAGE_MASK)
 
 extern unsigned long uml_physmem;
 
@@ -30,7 +95,6 @@
 
 extern unsigned long to_phys(void *virt);
 extern void *to_virt(unsigned long phys);
-
 #define __pa(virt) to_phys((void *) virt)
 #define __va(phys) to_virt((unsigned long) phys)
 
@@ -42,7 +106,21 @@
 
 #define pfn_valid(pfn) ((pfn) < max_mapnr)
 #define virt_addr_valid(v) pfn_valid(phys_to_pfn(__pa(v)))
-  
+
+/* Pure 2^n version of get_order */
+static __inline__ int get_order(unsigned long size)
+{
+	int order;
+
+	size = (size-1) >> (PAGE_SHIFT-1);
+	order = -1;
+	do {
+		size >>= 1;
+		order++;
+	} while (size);
+	return order;
+}
+
 extern struct page *arch_validate(struct page *page, int mask, int order);
 #define HAVE_ARCH_VALIDATE
 
diff -Nru a/include/asm-um/pda.h b/include/asm-um/pda.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-um/pda.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2003 PathScale, Inc.
+ *
+ * Licensed under the GPL
+ */
+
+#ifndef __UM_PDA_X86_64_H
+#define __UM_PDA_X86_64_H
+
+/* XXX */
+struct foo {
+	unsigned int __softirq_pending;
+	unsigned int __nmi_count;
+};
+
+extern struct foo me;
+
+#define read_pda(me) (&me)
+
+#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 -Nru a/include/asm-um/pgalloc.h b/include/asm-um/pgalloc.h
--- a/include/asm-um/pgalloc.h	2005-03-01 23:39:09 -08:00
+++ b/include/asm-um/pgalloc.h	2005-03-01 23:39:09 -08:00
@@ -1,5 +1,6 @@
 /* 
  * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
+ * Copyright 2003 PathScale, Inc.
  * Derived from include/asm-i386/pgalloc.h and include/asm-i386/pgtable.h
  * Licensed under the GPL
  */
@@ -7,18 +8,21 @@
 #ifndef __UM_PGALLOC_H
 #define __UM_PGALLOC_H
 
+#include "linux/config.h"
 #include "linux/mm.h"
 #include "asm/fixmap.h"
 
 #define pmd_populate_kernel(mm, pmd, pte) \
-		set_pmd(pmd, __pmd(_PAGE_TABLE + (unsigned long) __pa(pte)))
+	set_pmd(pmd, __pmd(_PAGE_TABLE + (unsigned long) __pa(pte)))
 
-static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, 
-				struct page *pte)
-{
-	set_pmd(pmd, __pmd(_PAGE_TABLE + page_to_phys(pte)));
-}
+#define pmd_populate(mm, pmd, pte) 				\
+	set_pmd(pmd, __pmd(_PAGE_TABLE +			\
+		((unsigned long long)page_to_pfn(pte) <<	\
+			(unsigned long long) PAGE_SHIFT)))
 
+/*
+ * Allocate and free page tables.
+ */
 extern pgd_t *pgd_alloc(struct mm_struct *);
 extern void pgd_free(pgd_t *pgd);
 
@@ -37,15 +41,13 @@
 
 #define __pte_free_tlb(tlb,pte) tlb_remove_page((tlb),(pte))
 
+#ifdef CONFIG_3_LEVEL_PGTABLES
 /*
- * allocating and freeing a pmd is trivial: the 1-entry pmd is
- * inside the pgd, so has no extra memory associated with it.
+ * In the 3-level case we free the pmds as part of the pgd.
  */
-
-#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()
+#endif
 
 #define check_pgt_cache()	do { } while (0)
 
diff -Nru a/include/asm-um/pgtable-2level.h b/include/asm-um/pgtable-2level.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-um/pgtable-2level.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
+ * Copyright 2003 PathScale, Inc.
+ * Derived from include/asm-i386/pgtable.h
+ * Licensed under the GPL
+ */
+
+#ifndef __UM_PGTABLE_2LEVEL_H
+#define __UM_PGTABLE_2LEVEL_H
+
+#include <asm-generic/pgtable-nopmd.h>
+
+/* PGDIR_SHIFT determines what a third-level page table entry can map */
+
+#define PGDIR_SHIFT	22
+#define PGDIR_SIZE	(1UL << PGDIR_SHIFT)
+#define PGDIR_MASK	(~(PGDIR_SIZE-1))
+
+/*
+ * entries per page directory level: the i386 is two-level, so
+ * we don't really have any PMD directory physically.
+ */
+#define PTRS_PER_PTE	1024
+#define PTRS_PER_PMD	1
+#define USER_PTRS_PER_PGD ((TASK_SIZE + (PGDIR_SIZE - 1)) / PGDIR_SIZE)
+#define PTRS_PER_PGD	1024
+#define FIRST_USER_PGD_NR       0
+
+#define pte_ERROR(e) \
+        printk("%s:%d: bad pte %p(%08lx).\n", __FILE__, __LINE__, &(e), \
+	       pte_val(e))
+#define pgd_ERROR(e) \
+        printk("%s:%d: bad pgd %p(%08lx).\n", __FILE__, __LINE__, &(e), \
+	       pgd_val(e))
+
+static inline int pgd_newpage(pgd_t pgd)	{ return 0; }
+static inline void pgd_mkuptodate(pgd_t pgd)	{ }
+
+#define pte_present(x)	(pte_val(x) & (_PAGE_PRESENT | _PAGE_PROTNONE))
+
+static inline pte_t pte_mknewprot(pte_t pte)
+{
+ 	pte_val(pte) |= _PAGE_NEWPROT;
+	return(pte);
+}
+
+static inline pte_t pte_mknewpage(pte_t pte)
+{
+	pte_val(pte) |= _PAGE_NEWPAGE;
+	return(pte);
+}
+
+static inline void set_pte(pte_t *pteptr, pte_t pteval)
+{
+	/* If it's a swap entry, it needs to be marked _PAGE_NEWPAGE so
+	 * fix_range knows to unmap it.  _PAGE_NEWPROT is specific to
+	 * mapped pages.
+	 */
+	*pteptr = pte_mknewpage(pteval);
+	if(pte_present(*pteptr)) *pteptr = pte_mknewprot(*pteptr);
+}
+
+#define set_pmd(pmdptr, pmdval) (*(pmdptr) = (pmdval))
+
+#define pte_page(x) pfn_to_page(pte_pfn(x))
+#define pte_none(x) !(pte_val(x) & ~_PAGE_NEWPAGE)
+#define pte_pfn(x) phys_to_pfn(pte_val(x))
+#define pfn_pte(pfn, prot) __pte(pfn_to_phys(pfn) | pgprot_val(prot))
+#define pfn_pmd(pfn, prot) __pmd(pfn_to_phys(pfn) | pgprot_val(prot))
+
+#define pmd_page_kernel(pmd) \
+	((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
+
+/*
+ * Bits 0 through 3 are taken
+ */
+#define PTE_FILE_MAX_BITS	28
+
+#define pte_to_pgoff(pte) (pte_val(pte) >> 4)
+
+#define pgoff_to_pte(off) ((pte_t) { ((off) << 4) + _PAGE_FILE })
+
+#endif
diff -Nru a/include/asm-um/pgtable-3level.h b/include/asm-um/pgtable-3level.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-um/pgtable-3level.h	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,172 @@
+/*
+ * Copyright 2003 PathScale Inc
+ * Derived from include/asm-i386/pgtable.h
+ * Licensed under the GPL
+ */
+
+#ifndef __UM_PGTABLE_3LEVEL_H
+#define __UM_PGTABLE_3LEVEL_H
+
+#include <asm-generic/pgtable-nopud.h>
+
+/* PGDIR_SHIFT determines what a third-level page table entry can map */
+
+#define PGDIR_SHIFT	30
+#define PGDIR_SIZE	(1UL << PGDIR_SHIFT)
+#define PGDIR_MASK	(~(PGDIR_SIZE-1))
+
+/* PMD_SHIFT determines the size of the area a second-level page table can
+ * map
+ */
+
+#define PMD_SHIFT	21
+#define PMD_SIZE	(1UL << PMD_SHIFT)
+#define PMD_MASK	(~(PMD_SIZE-1))
+
+/*
+ * entries per page directory level
+ */
+
+#define PTRS_PER_PTE 512
+#define PTRS_PER_PMD 512
+#define USER_PTRS_PER_PGD ((TASK_SIZE + (PGDIR_SIZE - 1)) / PGDIR_SIZE)
+#define PTRS_PER_PGD 512
+#define FIRST_USER_PGD_NR       0
+
+#define pte_ERROR(e) \
+        printk("%s:%d: bad pte %p(%016lx).\n", __FILE__, __LINE__, &(e), \
+	       pte_val(e))
+#define pmd_ERROR(e) \
+        printk("%s:%d: bad pmd %p(%016lx).\n", __FILE__, __LINE__, &(e), \
+	       pmd_val(e))
+#define pgd_ERROR(e) \
+        printk("%s:%d: bad pgd %p(%016lx).\n", __FILE__, __LINE__, &(e), \
+	       pgd_val(e))
+
+#define pud_none(x)	(!(pud_val(x) & ~_PAGE_NEWPAGE))
+#define	pud_bad(x)	((pud_val(x) & (~PAGE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE)
+#define pud_present(x)	(pud_val(x) & _PAGE_PRESENT)
+#define pud_populate(mm, pud, pmd) \
+	set_pud(pud, __pud(_PAGE_TABLE + __pa(pmd)))
+
+#define set_pud(pudptr, pudval) set_64bit((phys_t *) (pudptr), pud_val(pudval))
+static inline int pgd_newpage(pgd_t pgd)
+{
+	return(pgd_val(pgd) & _PAGE_NEWPAGE);
+}
+
+static inline void pgd_mkuptodate(pgd_t pgd) { pgd_val(pgd) &= ~_PAGE_NEWPAGE; }
+
+
+#define pte_present(x)	pte_get_bits(x, (_PAGE_PRESENT | _PAGE_PROTNONE))
+
+static inline pte_t pte_mknewprot(pte_t pte)
+{
+        pte_set_bits(pte, _PAGE_NEWPROT);
+	return(pte);
+}
+
+static inline pte_t pte_mknewpage(pte_t pte)
+{
+	pte_set_bits(pte, _PAGE_NEWPAGE);
+	return(pte);
+}
+
+static inline void set_pte(pte_t *pteptr, pte_t pteval)
+{
+	pte_copy(*pteptr, pteval);
+
+	/* If it's a swap entry, it needs to be marked _PAGE_NEWPAGE so
+	 * fix_range knows to unmap it.  _PAGE_NEWPROT is specific to
+	 * mapped pages.
+	 */
+
+	*pteptr = pte_mknewpage(*pteptr);
+	if(pte_present(*pteptr)) *pteptr = pte_mknewprot(*pteptr);
+}
+
+#define set_pmd(pmdptr, pmdval) set_64bit((phys_t *) (pmdptr), pmd_val(pmdval))
+
+static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address)
+{
+        pmd_t *pmd = (pmd_t *) __get_free_page(GFP_KERNEL);
+
+        if(pmd)
+                memset(pmd, 0, PAGE_SIZE);
+
+        return pmd;
+}
+
+static inline void pmd_free(pmd_t *pmd){
+	free_page((unsigned long) pmd);
+}
+
+#define __pmd_free_tlb(tlb,x)   do { } while (0)
+
+static inline void pud_clear (pud_t * pud) { }
+
+#define pud_page(pud) \
+	((struct page *) __va(pud_val(pud) & PAGE_MASK))
+
+/* Find an entry in the second-level page table.. */
+#define pmd_offset(pud, address) ((pmd_t *) pud_page(*(pud)) + \
+			pmd_index(address))
+
+#define pte_page(x) pfn_to_page(pte_pfn(x))
+
+static inline int pte_none(pte_t pte)
+{
+	return pte_is_zero(pte);
+}
+
+static inline unsigned long pte_pfn(pte_t pte)
+{
+	return phys_to_pfn(pte_val(pte));
+}
+
+static inline pte_t pfn_pte(pfn_t page_nr, pgprot_t pgprot)
+{
+	pte_t pte;
+	phys_t phys = pfn_to_phys(page_nr);
+
+	pte_set_val(pte, phys, pgprot);
+	return pte;
+}
+
+static inline pmd_t pfn_pmd(pfn_t page_nr, pgprot_t pgprot)
+{
+	return __pmd((page_nr << PAGE_SHIFT) | pgprot_val(pgprot));
+}
+
+/*
+ * Bits 0 through 3 are taken in the low part of the pte,
+ * put the 32 bits of offset into the high part.
+ */
+#define PTE_FILE_MAX_BITS	32
+
+#ifdef CONFIG_64_BIT
+
+#define pte_to_pgoff(p) ((p).pte >> 32)
+
+#define pgoff_to_pte(off) ((pte_t) { ((off) < 32) | _PAGE_FILE })
+
+#else
+
+#define pte_to_pgoff(pte) ((pte).pte_high)
+
+#define pgoff_to_pte(off) ((pte_t) { _PAGE_FILE, (off) })
+
+#endif
+
+#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 -Nru a/include/asm-um/pgtable.h b/include/asm-um/pgtable.h
--- a/include/asm-um/pgtable.h	2005-03-01 23:39:18 -08:00
+++ b/include/asm-um/pgtable.h	2005-03-01 23:39:18 -08:00
@@ -1,5 +1,6 @@
 /* 
  * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
+ * Copyright 2003 PathScale, Inc.
  * Derived from include/asm-i386/pgtable.h
  * Licensed under the GPL
  */
@@ -8,10 +9,29 @@
 #define __UM_PGTABLE_H
 
 #include "linux/sched.h"
+#include "linux/linkage.h"
 #include "asm/processor.h"
 #include "asm/page.h"
 #include "asm/fixmap.h"
 
+#define _PAGE_PRESENT	0x001
+#define _PAGE_NEWPAGE	0x002
+#define _PAGE_NEWPROT   0x004
+#define _PAGE_FILE	0x008   /* set:pagecache unset:swap */
+#define _PAGE_PROTNONE	0x010	/* If not present */
+#define _PAGE_RW	0x020
+#define _PAGE_USER	0x040
+#define _PAGE_ACCESSED	0x080
+#define _PAGE_DIRTY	0x100
+
+#ifdef CONFIG_3_LEVEL_PGTABLES
+#include "asm/pgtable-3level.h"
+#else
+#include "asm/pgtable-2level.h"
+#endif
+
+extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
+
 extern void *um_virt_to_phys(struct task_struct *task, unsigned long virt,
 			     pte_t *pte_out);
 
@@ -20,35 +40,6 @@
 
 #define pgtable_cache_init() do ; while (0)
 
-/* PMD_SHIFT determines the size of the area a second-level page table can map */
-#define PMD_SHIFT	22
-#define PMD_SIZE	(1UL << PMD_SHIFT)
-#define PMD_MASK	(~(PMD_SIZE-1))
-
-/* PGDIR_SHIFT determines what a third-level page table entry can map */
-#define PGDIR_SHIFT	22
-#define PGDIR_SIZE	(1UL << PGDIR_SHIFT)
-#define PGDIR_MASK	(~(PGDIR_SIZE-1))
-
-/*
- * entries per page directory level: the i386 is two-level, so
- * we don't really have any PMD directory physically.
- */
-#define PTRS_PER_PTE	1024
-#define PTRS_PER_PMD	1
-#define PTRS_PER_PGD	1024
-#define USER_PTRS_PER_PGD	(TASK_SIZE/PGDIR_SIZE)
-#define FIRST_USER_PGD_NR       0
-
-#define pte_ERROR(e) \
-        printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e))
-#define pmd_ERROR(e) \
-        printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e))
-#define pgd_ERROR(e) \
-        printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))
-
-extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
-
 /*
  * pgd entries used up by user/kernel:
  */
@@ -68,7 +59,7 @@
 extern unsigned long end_iomem;
 
 #define VMALLOC_OFFSET	(__va_space)
-#define VMALLOC_START	((end_iomem + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+#define VMALLOC_START ((end_iomem + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
 
 #ifdef CONFIG_HIGHMEM
 # define VMALLOC_END	(PKMAP_BASE-2*PAGE_SIZE)
@@ -76,18 +67,8 @@
 # define VMALLOC_END	(FIXADDR_START-2*PAGE_SIZE)
 #endif
 
-#define _PAGE_PRESENT	0x001
-#define _PAGE_NEWPAGE	0x002
-#define _PAGE_NEWPROT   0x004
-#define _PAGE_FILE	0x008   /* set:pagecache unset:swap */
-#define _PAGE_PROTNONE	0x010	/* If not present */
-#define _PAGE_RW	0x020
-#define _PAGE_USER	0x040
-#define _PAGE_ACCESSED	0x080
-#define _PAGE_DIRTY	0x100
-
-#define REGION_MASK	0xf0000000
-#define REGION_SHIFT	28
+#define REGION_SHIFT	(sizeof(pte_t) * 8 - 4)
+#define REGION_MASK	(((unsigned long) 0xf) << REGION_SHIFT)
 
 #define _PAGE_TABLE	(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY)
 #define _KERNPG_TABLE	(_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY)
@@ -155,16 +136,13 @@
 
 /* sizeof(void*)==1<<SIZEOF_PTR_LOG2 */
 /* 64-bit machines, beware!  SRB. */
-#define SIZEOF_PTR_LOG2			2
+#define SIZEOF_PTR_LOG2			3
 
 /* to find an entry in a page-table */
 #define PAGE_PTR(address) \
 ((unsigned long)(address)>>(PAGE_SHIFT-SIZEOF_PTR_LOG2)&PTR_MASK&~PAGE_MASK)
 
-#define pte_none(x)	!(pte_val(x) & ~_PAGE_NEWPAGE)
-#define pte_present(x)	(pte_val(x) & (_PAGE_PRESENT | _PAGE_PROTNONE))
-
-#define pte_clear(xp)	do { pte_val(*(xp)) = _PAGE_NEWPAGE; } while (0)
+#define pte_clear(xp) pte_set_val(*(xp), (phys_t) 0, __pgprot(_PAGE_NEWPAGE))
 
 #define pmd_none(x)	(!(pmd_val(x) & ~_PAGE_NEWPAGE))
 #define	pmd_bad(x)	((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE)
@@ -174,67 +152,16 @@
 #define pmd_newpage(x)  (pmd_val(x) & _PAGE_NEWPAGE)
 #define pmd_mkuptodate(x) (pmd_val(x) &= ~_PAGE_NEWPAGE)
 
-/*
- * 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)
- */
-static inline int pgd_none(pgd_t pgd)		{ return 0; }
-static inline int pgd_bad(pgd_t pgd)		{ return 0; }
-static inline int pgd_present(pgd_t pgd)	{ return 1; }
-static inline void pgd_clear(pgd_t * pgdp)	{ }
-
+#define pud_newpage(x)  (pud_val(x) & _PAGE_NEWPAGE)
+#define pud_mkuptodate(x) (pud_val(x) &= ~_PAGE_NEWPAGE)
 
 #define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT))
 
-#define pte_page(pte) phys_to_page(pte_val(pte))
 #define pmd_page(pmd) phys_to_page(pmd_val(pmd) & PAGE_MASK)
 
-#define pte_pfn(x) phys_to_pfn(pte_val(x))
-#define pfn_pte(pfn, prot) __pte(pfn_to_phys(pfn) | pgprot_val(prot))
-
-extern struct page *phys_to_page(const unsigned long phys);
-extern struct page *__virt_to_page(const unsigned long virt);
-#define virt_to_page(addr) __virt_to_page((const unsigned long) addr)
-
-/*
- * Bits 0 through 3 are taken
- */
-#define PTE_FILE_MAX_BITS	28
-
-#define pte_to_pgoff(pte) ((pte).pte_low >> 4)
-
-#define pgoff_to_pte(off) \
-	((pte_t) { ((off) << 4) + _PAGE_FILE })
-
-static inline pte_t pte_mknewprot(pte_t pte)
-{
- 	pte_val(pte) |= _PAGE_NEWPROT;
-	return(pte);
-}
-
-static inline pte_t pte_mknewpage(pte_t pte)
-{
-	pte_val(pte) |= _PAGE_NEWPAGE;
-	return(pte);
-}
-
-static inline void set_pte(pte_t *pteptr, pte_t pteval)
-{
-	/* If it's a swap entry, it needs to be marked _PAGE_NEWPAGE so
-	 * fix_range knows to unmap it.  _PAGE_NEWPROT is specific to
-	 * mapped pages.
-	 */
-	*pteptr = pte_mknewpage(pteval);
-	if(pte_present(*pteptr)) *pteptr = pte_mknewprot(*pteptr);
-}
-
-/*
- * (pmds are folded into pgds so this doesn't get actually called,
- * 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 pte_address(x) (__va(pte_val(x) & PAGE_MASK))
+#define mk_phys(a, r) ((a) + (((unsigned long) r) << REGION_SHIFT))
+#define phys_addr(p) ((p) & ~REGION_MASK)
 
 /*
  * The following only work if pte_present() is true.
@@ -242,25 +169,25 @@
  */
 static inline int pte_user(pte_t pte)
 {
-	return((pte_val(pte) & _PAGE_USER) &&
-	       !(pte_val(pte) & _PAGE_PROTNONE));
+	return((pte_get_bits(pte, _PAGE_USER)) &&
+	       !(pte_get_bits(pte, _PAGE_PROTNONE)));
 }
 
 static inline int pte_read(pte_t pte)
 { 
-	return((pte_val(pte) & _PAGE_USER) && 
-	       !(pte_val(pte) & _PAGE_PROTNONE));
+	return((pte_get_bits(pte, _PAGE_USER)) &&
+	       !(pte_get_bits(pte, _PAGE_PROTNONE)));
 }
 
 static inline int pte_exec(pte_t pte){
-	return((pte_val(pte) & _PAGE_USER) &&
-	       !(pte_val(pte) & _PAGE_PROTNONE));
+	return((pte_get_bits(pte, _PAGE_USER)) &&
+	       !(pte_get_bits(pte, _PAGE_PROTNONE)));
 }
 
 static inline int pte_write(pte_t pte)
 {
-	return((pte_val(pte) & _PAGE_RW) &&
-	       !(pte_val(pte) & _PAGE_PROTNONE));
+	return((pte_get_bits(pte, _PAGE_RW)) &&
+	       !(pte_get_bits(pte, _PAGE_PROTNONE)));
 }
 
 /*
@@ -268,85 +195,98 @@
  */
 static inline int pte_file(pte_t pte)
 {
-	return (pte).pte_low & _PAGE_FILE;
+	return pte_get_bits(pte, _PAGE_FILE);
+}
+
+static inline int pte_dirty(pte_t pte)
+{
+	return pte_get_bits(pte, _PAGE_DIRTY);
+}
+
+static inline int pte_young(pte_t pte)
+{
+	return pte_get_bits(pte, _PAGE_ACCESSED);
+}
+
+static inline int pte_newpage(pte_t pte)
+{
+	return pte_get_bits(pte, _PAGE_NEWPAGE);
 }
 
-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_newpage(pte_t pte) { return pte_val(pte) & _PAGE_NEWPAGE; }
 static inline int pte_newprot(pte_t pte)
 { 
-	return(pte_present(pte) && (pte_val(pte) & _PAGE_NEWPROT)); 
+	return(pte_present(pte) && (pte_get_bits(pte, _PAGE_NEWPROT)));
 }
 
 static inline pte_t pte_rdprotect(pte_t pte)
 { 
-	pte_val(pte) &= ~_PAGE_USER; 
+	pte_clear_bits(pte, _PAGE_USER);
 	return(pte_mknewprot(pte));
 }
 
 static inline pte_t pte_exprotect(pte_t pte)
 { 
-	pte_val(pte) &= ~_PAGE_USER;
+	pte_clear_bits(pte, _PAGE_USER);
 	return(pte_mknewprot(pte));
 }
 
 static inline pte_t pte_mkclean(pte_t pte)
 {
-	pte_val(pte) &= ~_PAGE_DIRTY; 
+	pte_clear_bits(pte, _PAGE_DIRTY);
 	return(pte);
 }
 
 static inline pte_t pte_mkold(pte_t pte)	
 { 
-	pte_val(pte) &= ~_PAGE_ACCESSED; 
+	pte_clear_bits(pte, _PAGE_ACCESSED);
 	return(pte);
 }
 
 static inline pte_t pte_wrprotect(pte_t pte)
 { 
-	pte_val(pte) &= ~_PAGE_RW; 
+	pte_clear_bits(pte, _PAGE_RW);
 	return(pte_mknewprot(pte)); 
 }
 
 static inline pte_t pte_mkread(pte_t pte)
 { 
-	pte_val(pte) |= _PAGE_USER; 
+	pte_set_bits(pte, _PAGE_RW);
 	return(pte_mknewprot(pte)); 
 }
 
 static inline pte_t pte_mkexec(pte_t pte)
 { 
-	pte_val(pte) |= _PAGE_USER; 
+	pte_set_bits(pte, _PAGE_USER);
 	return(pte_mknewprot(pte)); 
 }
 
 static inline pte_t pte_mkdirty(pte_t pte)
 { 
-	pte_val(pte) |= _PAGE_DIRTY; 
+	pte_set_bits(pte, _PAGE_DIRTY);
 	return(pte);
 }
 
 static inline pte_t pte_mkyoung(pte_t pte)
 {
-	pte_val(pte) |= _PAGE_ACCESSED; 
+	pte_set_bits(pte, _PAGE_ACCESSED);
 	return(pte);
 }
 
 static inline pte_t pte_mkwrite(pte_t pte)	
 {
-	pte_val(pte) |= _PAGE_RW; 
+	pte_set_bits(pte, _PAGE_RW);
 	return(pte_mknewprot(pte)); 
 }
 
 static inline pte_t pte_mkuptodate(pte_t pte)	
 {
-	pte_val(pte) &= ~_PAGE_NEWPAGE;
-	if(pte_present(pte)) pte_val(pte) &= ~_PAGE_NEWPROT;
+	pte_clear_bits(pte, _PAGE_NEWPAGE);
+	if(pte_present(pte))
+		pte_clear_bits(pte, _PAGE_NEWPROT);
 	return(pte); 
 }
 
-extern unsigned long page_to_phys(struct page *page);
+extern phys_t page_to_phys(struct page *page);
 
 /*
  * Conversion functions: convert a page and protection to a page entry,
@@ -357,7 +297,7 @@
 
 static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
 {
-	pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot);
+	pte_set_val(pte, (pte_val(pte) & _PAGE_CHG_MASK), newprot);
 	if(pte_present(pte)) pte = pte_mknewpage(pte_mknewprot(pte));
 	return pte; 
 }
@@ -370,15 +310,15 @@
  * this macro returns the index of the entry in the pgd page which would
  * control the given virtual address
  */
-#define pgd_index(address) ((address >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
+#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
+
+#define pgd_index_k(addr) pgd_index(addr)
 
 /*
  * pgd_offset() returns a (pgd_t *)
  * pgd_index() is used get the offset into the pgd page's array of pgd_t's;
  */
-#define pgd_offset(mm, address) \
-((mm)->pgd + ((address) >> PGDIR_SHIFT))
-
+#define pgd_offset(mm, address) ((mm)->pgd+pgd_index(address))
 
 /*
  * a shortcut which implies the use of the kernel's pgd, instead
@@ -386,14 +326,13 @@
  */
 #define pgd_offset_k(address) pgd_offset(&init_mm, address)
 
-#define pmd_index(address) \
-		(((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
-
-/* Find an entry in the second-level page table.. */
-static inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
-{
-	return (pmd_t *) dir;
-}
+/*
+ * the pmd page can be thought of an array like this: pmd_t[PTRS_PER_PMD]
+ *
+ * this macro returns the index of the entry in the pmd page which would
+ * control the given virtual address
+ */
+#define pmd_index(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
 
 /*
  * the pte page can be thought of an array like this: pte_t[PTRS_PER_PTE]
@@ -426,9 +365,15 @@
 
 #include <asm-generic/pgtable.h>
 
-#endif
+#include <asm-generic/pgtable-nopud.h>
 
 #endif
+#endif
+
+extern struct page *phys_to_page(const unsigned long phys);
+extern struct page *__virt_to_page(const unsigned long virt);
+#define virt_to_page(addr) __virt_to_page((const unsigned long) addr)
+
 /*
  * 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 -Nru a/include/asm-um/prctl.h b/include/asm-um/prctl.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-um/prctl.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,6 @@
+#ifndef __UM_PRCTL_H
+#define __UM_PRCTL_H
+
+#include "asm/arch/prctl.h"
+
+#endif
diff -Nru a/include/asm-um/processor-i386.h b/include/asm-um/processor-i386.h
--- a/include/asm-um/processor-i386.h	2005-03-01 23:38:52 -08:00
+++ b/include/asm-um/processor-i386.h	2005-03-01 23:38:52 -08:00
@@ -24,7 +24,11 @@
  * instruction pointer ("program counter"). Stolen
  * from asm-i386/processor.h
  */
-#define current_text_addr() ({ void *pc; __asm__("movl $1f,%0\n1:":"=g" (pc)); pc; })
+#define current_text_addr() \
+	({ void *pc; __asm__("movl $1f,%0\n1:":"=g" (pc)); pc; })
+
+#define ARCH_IS_STACKGROW(address) \
+       (address + 32 >= UPT_SP(&current->thread.regs.regs))
 
 #include "asm/processor-generic.h"
 
diff -Nru a/include/asm-um/processor-x86_64.h b/include/asm-um/processor-x86_64.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-um/processor-x86_64.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2003 PathScale, Inc.
+ *
+ * Licensed under the GPL
+ */
+
+#ifndef __UM_PROCESSOR_X86_64_H
+#define __UM_PROCESSOR_X86_64_H
+
+#include "asm/arch/user.h"
+
+struct arch_thread {
+};
+
+#define INIT_ARCH_THREAD { }
+
+#define current_text_addr() \
+	({ void *pc; __asm__("movq $1f,%0\n1:":"=g" (pc)); pc; })
+
+#define ARCH_IS_STACKGROW(address) \
+        (address + 128 >= UPT_SP(&current->thread.regs.regs))
+
+#include "asm/processor-generic.h"
+
+#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 -Nru a/include/asm-um/ptrace-generic.h b/include/asm-um/ptrace-generic.h
--- a/include/asm-um/ptrace-generic.h	2005-03-01 23:39:08 -08:00
+++ b/include/asm-um/ptrace-generic.h	2005-03-01 23:39:08 -08:00
@@ -12,16 +12,17 @@
 
 #define pt_regs pt_regs_subarch
 #define show_regs show_regs_subarch
+#define send_sigtrap send_sigtrap_subarch
 
 #include "asm/arch/ptrace.h"
 
 #undef pt_regs
 #undef show_regs
+#undef send_sigtrap
 #undef user_mode
 #undef instruction_pointer
 
 #include "sysdep/ptrace.h"
-#include "skas_ptrace.h"
 
 struct pt_regs {
 	union uml_pt_regs regs;
@@ -55,6 +56,9 @@
 extern int set_fpxregs(unsigned long buf, struct task_struct *tsk);
 
 extern void show_regs(struct pt_regs *regs);
+
+extern void send_sigtrap(struct task_struct *tsk, union uml_pt_regs *regs,
+			 int error_code);
 
 #endif
 
diff -Nru a/include/asm-um/ptrace-x86_64.h b/include/asm-um/ptrace-x86_64.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-um/ptrace-x86_64.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2003 PathScale, Inc.
+ *
+ * Licensed under the GPL
+ */
+
+#ifndef __UM_PTRACE_X86_64_H
+#define __UM_PTRACE_X86_64_H
+
+#include "linux/compiler.h"
+
+#define signal_fault signal_fault_x86_64
+#define __FRAME_OFFSETS /* Needed to get the R* macros */
+#include "asm/ptrace-generic.h"
+#undef signal_fault
+
+void signal_fault(struct pt_regs_subarch *regs, void *frame, char *where);
+
+#define FS_BASE (21 * sizeof(unsigned long))
+#define GS_BASE (22 * sizeof(unsigned long))
+#define DS (23 * sizeof(unsigned long))
+#define ES (24 * sizeof(unsigned long))
+#define FS (25 * sizeof(unsigned long))
+#define GS (26 * sizeof(unsigned long))
+
+#define PT_REGS_RBX(r) UPT_RBX(&(r)->regs)
+#define PT_REGS_RCX(r) UPT_RCX(&(r)->regs)
+#define PT_REGS_RDX(r) UPT_RDX(&(r)->regs)
+#define PT_REGS_RSI(r) UPT_RSI(&(r)->regs)
+#define PT_REGS_RDI(r) UPT_RDI(&(r)->regs)
+#define PT_REGS_RBP(r) UPT_RBP(&(r)->regs)
+#define PT_REGS_RAX(r) UPT_RAX(&(r)->regs)
+#define PT_REGS_R8(r) UPT_R8(&(r)->regs)
+#define PT_REGS_R9(r) UPT_R9(&(r)->regs)
+#define PT_REGS_R10(r) UPT_R10(&(r)->regs)
+#define PT_REGS_R11(r) UPT_R11(&(r)->regs)
+#define PT_REGS_R12(r) UPT_R12(&(r)->regs)
+#define PT_REGS_R13(r) UPT_R13(&(r)->regs)
+#define PT_REGS_R14(r) UPT_R14(&(r)->regs)
+#define PT_REGS_R15(r) UPT_R15(&(r)->regs)
+
+#define PT_REGS_FS(r) UPT_FS(&(r)->regs)
+#define PT_REGS_GS(r) UPT_GS(&(r)->regs)
+#define PT_REGS_DS(r) UPT_DS(&(r)->regs)
+#define PT_REGS_ES(r) UPT_ES(&(r)->regs)
+#define PT_REGS_SS(r) UPT_SS(&(r)->regs)
+#define PT_REGS_CS(r) UPT_CS(&(r)->regs)
+
+#define PT_REGS_ORIG_RAX(r) UPT_ORIG_RAX(&(r)->regs)
+#define PT_REGS_RIP(r) UPT_IP(&(r)->regs)
+#define PT_REGS_RSP(r) UPT_SP(&(r)->regs)
+
+#define PT_REGS_EFLAGS(r) UPT_EFLAGS(&(r)->regs)
+
+/* XXX */
+#define user_mode(r) UPT_IS_USER(&(r)->regs)
+#define PT_REGS_ORIG_SYSCALL(r) PT_REGS_RAX(r)
+#define PT_REGS_SYSCALL_RET(r) PT_REGS_RAX(r)
+
+#define PT_FIX_EXEC_STACK(sp) do ; while(0)
+
+#define profile_pc(regs) PT_REGS_IP(regs)
+
+#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 -Nru a/include/asm-um/sigcontext-x86_64.h b/include/asm-um/sigcontext-x86_64.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-um/sigcontext-x86_64.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,22 @@
+/* Copyright 2003 PathScale, Inc.
+ *
+ * Licensed under the GPL
+ */
+
+#ifndef __UM_SIGCONTEXT_X86_64_H
+#define __UM_SIGCONTEXT_X86_64_H
+
+#include "asm/sigcontext-generic.h"
+
+#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 -Nru a/include/asm-um/system-i386.h b/include/asm-um/system-i386.h
--- a/include/asm-um/system-i386.h	2005-03-01 23:38:55 -08:00
+++ b/include/asm-um/system-i386.h	2005-03-01 23:38:55 -08:00
@@ -3,4 +3,6 @@
 
 #include "asm/system-generic.h"
     
+#define __HAVE_ARCH_CMPXCHG 1
+
 #endif
diff -Nru a/include/asm-um/system-x86_64.h b/include/asm-um/system-x86_64.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-um/system-x86_64.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2003 PathScale, Inc.
+ *
+ * Licensed under the GPL
+ */
+
+#ifndef __UM_SYSTEM_X86_64_H
+#define __UM_SYSTEM_X86_64_H
+
+#include "asm/system-generic.h"
+
+#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 -Nru a/include/asm-um/thread_info.h b/include/asm-um/thread_info.h
--- a/include/asm-um/thread_info.h	2005-03-01 23:38:55 -08:00
+++ b/include/asm-um/thread_info.h	2005-03-01 23:38:55 -08:00
@@ -47,7 +47,7 @@
 	struct thread_info *ti;
 	unsigned long mask = PAGE_SIZE *
 		(1 << CONFIG_KERNEL_STACK_ORDER) - 1;
-	__asm__("andl %%esp,%0; ":"=r" (ti) : "0" (~mask));
+        ti = (struct thread_info *) (((unsigned long) &ti) & ~mask);
 	return ti;
 }
 
@@ -71,6 +71,7 @@
 					 * TIF_NEED_RESCHED 
 					 */
 #define TIF_RESTART_BLOCK 	4
+#define TIF_MEMDIE	 	5
 
 #define _TIF_SYSCALL_TRACE	(1 << TIF_SYSCALL_TRACE)
 #define _TIF_SIGPENDING		(1 << TIF_SIGPENDING)
diff -Nru a/include/asm-um/uaccess.h b/include/asm-um/uaccess.h
--- a/include/asm-um/uaccess.h	2005-03-01 23:39:07 -08:00
+++ b/include/asm-um/uaccess.h	2005-03-01 23:39:07 -08:00
@@ -55,7 +55,7 @@
 
 #define get_user(x, ptr) \
 ({ \
-        const __typeof__((*(ptr))) *private_ptr = (ptr); \
+        const __typeof__((*(ptr))) __user *private_ptr = (ptr); \
         (access_ok(VERIFY_READ, private_ptr, sizeof(*private_ptr)) ? \
 	 __get_user(x, private_ptr) : ((x) = 0, -EFAULT)); \
 })
@@ -75,7 +75,7 @@
 
 #define put_user(x, ptr) \
 ({ \
-        __typeof__(*(ptr)) *private_ptr = (ptr); \
+        __typeof__(*(ptr)) __user *private_ptr = (ptr); \
         (access_ok(VERIFY_WRITE, private_ptr, sizeof(*private_ptr)) ? \
 	 __put_user(x, private_ptr) : -EFAULT); \
 })
diff -Nru a/include/asm-um/unistd.h b/include/asm-um/unistd.h
--- a/include/asm-um/unistd.h	2005-03-01 23:39:09 -08:00
+++ b/include/asm-um/unistd.h	2005-03-01 23:39:09 -08:00
@@ -1,5 +1,5 @@
 /* 
- * Copyright (C) 2000, 2001  Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2000 - 2004  Jeff Dike (jdike@karaya.com)
  * Licensed under the GPL
  */
 
@@ -41,105 +41,29 @@
 #include <linux/compiler.h>
 #include <linux/types.h>
 
-#define KERNEL_CALL(ret_t, sys, args...)	\
-	mm_segment_t fs = get_fs();		\
-	ret_t ret;				\
-	set_fs(KERNEL_DS);			\
-	ret = sys(args);			\
-	set_fs(fs);				\
-	if (ret >= 0)				\
-		return ret;			\
-	errno = -(long)ret;			\
-	return -1;
-
-static inline long open(const char *pathname, int flags, int mode) 
-{
-	KERNEL_CALL(int, sys_open, pathname, flags, mode)
-}
-
-static inline long dup(unsigned int fd)
-{
-	KERNEL_CALL(int, sys_dup, fd);
-}
-
-static inline long close(unsigned int fd)
-{
-	KERNEL_CALL(int, sys_close, fd);
-}
-
-static inline int execve(const char *filename, char *const argv[], 
+static inline int execve(const char *filename, char *const argv[],
 			 char *const envp[])
 {
-	KERNEL_CALL(int, um_execve, filename, argv, envp);
-}
-
-static inline long waitpid(pid_t pid, unsigned int *status, int options)
-{
-	KERNEL_CALL(pid_t, sys_wait4, pid, status, options, NULL)
-}
-
-static inline pid_t setsid(void)
-{
-	KERNEL_CALL(pid_t, sys_setsid)
-}
+	mm_segment_t fs;
+	int ret;
 
-static inline off_t lseek(unsigned int fd, off_t offset, unsigned int whence)
-{
-	KERNEL_CALL(long, sys_lseek, fd, offset, whence)
-}
+	fs = get_fs();
+	set_fs(KERNEL_DS);
+	ret = um_execve(filename, argv, envp);
+	set_fs(fs);
 
-static inline int read(unsigned int fd, char * buf, int len)
-{
-	KERNEL_CALL(int, sys_read, fd, buf, len)
-}
+	if (ret >= 0)
+		return ret;
 
-static inline int write(unsigned int fd, char * buf, int len)
-{
-	KERNEL_CALL(int, sys_write, fd, buf, len)
+	errno = -(long)ret;
+	return -1;
 }
 
-long sys_mmap2(unsigned long addr, unsigned long len,
-		unsigned long prot, unsigned long flags,
-		unsigned long fd, unsigned long pgoff);
-long sys_execve(char *file, char **argv, char **env);
-long sys_clone(unsigned long clone_flags, unsigned long newsp,
-		int *parent_tid, int *child_tid);
-long sys_fork(void);
-long sys_vfork(void);
-long sys_pipe(unsigned long *fildes);
-struct sigaction;
-asmlinkage long sys_rt_sigaction(int sig,
-				const struct sigaction __user *act,
-				struct sigaction __user *oact,
-				size_t sigsetsize);
-
-#endif
-
-/* Save the value of __KERNEL_SYSCALLS__, undefine it, include the underlying
- * arch's unistd.h for the system call numbers, and restore the old 
- * __KERNEL_SYSCALLS__.
- */
+int sys_execve(char *file, char **argv, char **env);
 
-#ifdef __KERNEL_SYSCALLS__
-#define __SAVE_KERNEL_SYSCALLS__ __KERNEL_SYSCALLS__
-#endif
+#endif /* __KERNEL_SYSCALLS__ */
 
 #undef __KERNEL_SYSCALLS__
 #include "asm/arch/unistd.h"
 
-#ifdef __KERNEL_SYSCALLS__
-#define __KERNEL_SYSCALLS__ __SAVE_KERNEL_SYSCALLS__
-#endif
-
-#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:
- */
+#endif /* _UM_UNISTD_H_*/
diff -Nru a/include/asm-um/vm-flags-i386.h b/include/asm-um/vm-flags-i386.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-um/vm-flags-i386.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,14 @@
+/*
+ * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __VM_FLAGS_I386_H
+#define __VM_FLAGS_I386_H
+
+#define VM_DATA_DEFAULT_FLAGS \
+	(VM_READ | VM_WRITE | \
+	((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
+		 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+
+#endif
diff -Nru a/include/asm-um/vm-flags-x86_64.h b/include/asm-um/vm-flags-x86_64.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-um/vm-flags-x86_64.h	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com)
+ * Copyright 2003 PathScale, Inc.
+ * Licensed under the GPL
+ */
+
+#ifndef __VM_FLAGS_X86_64_H
+#define __VM_FLAGS_X86_64_H
+
+#define __VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
+				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+#define __VM_STACK_FLAGS 	(VM_GROWSDOWN | VM_READ | VM_WRITE | \
+				 VM_EXEC | VM_MAYREAD | VM_MAYWRITE | \
+				 VM_MAYEXEC)
+
+extern unsigned long vm_stack_flags, vm_stack_flags32;
+extern unsigned long vm_data_default_flags, vm_data_default_flags32;
+extern unsigned long vm_force_exec32;
+
+#ifdef TIF_IA32
+#define VM_DATA_DEFAULT_FLAGS \
+	(test_thread_flag(TIF_IA32) ? vm_data_default_flags32 : \
+	  vm_data_default_flags)
+
+#define VM_STACK_DEFAULT_FLAGS \
+	(test_thread_flag(TIF_IA32) ? vm_stack_flags32 : vm_stack_flags)
+#endif
+
+#define VM_DATA_DEFAULT_FLAGS vm_data_default_flags
+
+#define VM_STACK_DEFAULT_FLAGS vm_stack_flags
+
+#endif
diff -Nru a/include/asm-v850/cputime.h b/include/asm-v850/cputime.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-v850/cputime.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,6 @@
+#ifndef __V850_CPUTIME_H
+#define __V850_CPUTIME_H
+
+#include <asm-generic/cputime.h>
+
+#endif /* __V850_CPUTIME_H */
diff -Nru a/include/asm-v850/hardirq.h b/include/asm-v850/hardirq.h
--- a/include/asm-v850/hardirq.h	2005-03-01 23:38:52 -08:00
+++ b/include/asm-v850/hardirq.h	2005-03-01 23:38:52 -08:00
@@ -7,8 +7,6 @@
 
 typedef struct {
 	unsigned int __softirq_pending;
-	unsigned int __syscall_count;
-	struct task_struct * __ksoftirqd_task;
 } ____cacheline_aligned irq_cpustat_t;
 
 #include <linux/irq_cpustat.h>	/* Standard mappings for irq_cpustat_t above */
@@ -23,14 +21,5 @@
 #if (1 << HARDIRQ_BITS) < NR_IRQS
 # error HARDIRQ_BITS is too low!
 #endif
-
-#define irq_enter()		(preempt_count() += HARDIRQ_OFFSET)
-#define irq_exit()							      \
-do {									      \
-	preempt_count() -= IRQ_EXIT_OFFSET;				      \
-	if (!in_interrupt() && softirq_pending(smp_processor_id()))	      \
-		do_softirq();						      \
-	preempt_enable_no_resched();					      \
-} while (0)
 
 #endif /* __V850_HARDIRQ_H__ */
diff -Nru a/include/asm-v850/pgtable.h b/include/asm-v850/pgtable.h
--- a/include/asm-v850/pgtable.h	2005-03-01 23:39:07 -08:00
+++ b/include/asm-v850/pgtable.h	2005-03-01 23:39:07 -08:00
@@ -1,6 +1,8 @@
 #ifndef __V850_PGTABLE_H__
 #define __V850_PGTABLE_H__
 
+#include <asm-generic/4level-fixup.h>
+
 #include <linux/config.h>
 #include <asm/page.h>
 
diff -Nru a/include/asm-v850/processor.h b/include/asm-v850/processor.h
--- a/include/asm-v850/processor.h	2005-03-01 23:38:54 -08:00
+++ b/include/asm-v850/processor.h	2005-03-01 23:38:54 -08:00
@@ -48,13 +48,6 @@
  */
 #define current_text_addr()	({ __label__ _l; _l: &&_l;})
 
-
-/*
- * Bus types
- */
-#define MCA_bus 0
-#define MCA_bus__is_a_macro /* for versions in ksyms.c */
-
 /* If you change this, you must change the associated assembly-languages
    constants defined below, THREAD_*.  */
 struct thread_struct {
diff -Nru a/include/asm-v850/resource.h b/include/asm-v850/resource.h
--- a/include/asm-v850/resource.h	2005-03-01 23:38:52 -08:00
+++ b/include/asm-v850/resource.h	2005-03-01 23:38:52 -08:00
@@ -1,51 +1,6 @@
 #ifndef __V850_RESOURCE_H__
 #define __V850_RESOURCE_H__
 
-/*
- * Resource limits
- */
-
-#define RLIMIT_CPU	0		/* CPU time in ms */
-#define RLIMIT_FSIZE	1		/* Maximum filesize */
-#define RLIMIT_DATA	2		/* max data size */
-#define RLIMIT_STACK	3		/* max stack size */
-#define RLIMIT_CORE	4		/* max core file size */
-#define RLIMIT_RSS	5		/* max resident set size */
-#define RLIMIT_NPROC	6		/* max number of processes */
-#define RLIMIT_NOFILE	7		/* max number of open files */
-#define RLIMIT_MEMLOCK	8		/* max locked-in-memory address space */
-#define RLIMIT_AS	9		/* address space limit */
-#define RLIMIT_LOCKS	10		/* maximum file locks held */
-#define RLIMIT_SIGPENDING 11		/* max number of pending signals */
-#define RLIMIT_MSGQUEUE 12		/* maximum bytes in POSIX mqueues */
-
-#define RLIM_NLIMITS	13
-
-/*
- * SuS says limits have to be unsigned.
- * Which makes a ton more sense anyway.
- */
-#define RLIM_INFINITY	(~0UL)
-
-#ifdef __KERNEL__
-
-#define INIT_RLIMITS					\
-{							\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{      _STK_LIM, RLIM_INFINITY },		\
-	{             0, RLIM_INFINITY },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{             0,             0 },		\
-	{      INR_OPEN,     INR_OPEN  },		\
-	{   MLOCK_LIMIT,   MLOCK_LIMIT },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{ MAX_SIGPENDING, MAX_SIGPENDING },		\
-	{ MQ_BYTES_MAX, MQ_BYTES_MAX },			\
-}
-
-#endif /* __KERNEL__ */
+#include <asm-generic/resource.h>
 
 #endif /* __V850_RESOURCE_H__ */
diff -Nru a/include/asm-v850/string.h b/include/asm-v850/string.h
--- a/include/asm-v850/string.h	2005-03-01 23:39:18 -08:00
+++ b/include/asm-v850/string.h	2005-03-01 23:39:18 -08:00
@@ -14,13 +14,11 @@
 #ifndef __V850_STRING_H__
 #define __V850_STRING_H__
 
-#define __HAVE_ARCH_BCOPY
 #define __HAVE_ARCH_MEMCPY
 #define __HAVE_ARCH_MEMSET
 #define __HAVE_ARCH_MEMMOVE
 
 extern void *memcpy (void *, const void *, __kernel_size_t);
-extern void bcopy (const char *, char *, int);
 extern void *memset (void *, int, __kernel_size_t);
 extern void *memmove (void *, const void *, __kernel_size_t);
 
diff -Nru a/include/asm-v850/thread_info.h b/include/asm-v850/thread_info.h
--- a/include/asm-v850/thread_info.h	2005-03-01 23:38:55 -08:00
+++ b/include/asm-v850/thread_info.h	2005-03-01 23:38:55 -08:00
@@ -83,6 +83,7 @@
 #define TIF_NEED_RESCHED	3	/* rescheduling necessary */
 #define TIF_POLLING_NRFLAG	4	/* true if poll_idle() is polling
 					   TIF_NEED_RESCHED */
+#define TIF_MEMDIE		5
 
 /* as above, but as bit values */
 #define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE)
diff -Nru a/include/asm-x86_64/acpi.h b/include/asm-x86_64/acpi.h
--- a/include/asm-x86_64/acpi.h	2005-03-01 23:39:07 -08:00
+++ b/include/asm-x86_64/acpi.h	2005-03-01 23:39:07 -08:00
@@ -131,6 +131,10 @@
 #define acpi_ioapic 0
 #endif /* !CONFIG_ACPI_BOOT */
 
+extern int acpi_numa;
+extern int acpi_scan_nodes(unsigned long start, unsigned long end);
+#define NR_NODE_MEMBLKS (MAX_NUMNODES*2)
+
 #ifdef CONFIG_ACPI_PCI
 static inline void acpi_noirq_set(void) { acpi_noirq = 1; }
 static inline void acpi_disable_pci(void) 
diff -Nru a/include/asm-x86_64/agp.h b/include/asm-x86_64/agp.h
--- a/include/asm-x86_64/agp.h	2005-03-01 23:38:43 -08:00
+++ b/include/asm-x86_64/agp.h	2005-03-01 23:38:43 -08:00
@@ -10,9 +10,8 @@
  * with different cachability attributes for the same page.
  */
 
-#define map_page_into_agp(page) \
-      change_page_attr(page, 1, PAGE_KERNEL_NOCACHE)
-#define unmap_page_from_agp(page) change_page_attr(page, 1, PAGE_KERNEL)
+int map_page_into_agp(struct page *page);
+int unmap_page_from_agp(struct page *page);
 #define flush_agp_mappings() global_flush_tlb()
 
 /* Could use CLFLUSH here if the cpu supports it. But then it would
diff -Nru a/include/asm-x86_64/bitops.h b/include/asm-x86_64/bitops.h
--- a/include/asm-x86_64/bitops.h	2005-03-01 23:38:56 -08:00
+++ b/include/asm-x86_64/bitops.h	2005-03-01 23:38:56 -08:00
@@ -267,22 +267,22 @@
 }
 
 #define find_first_bit(addr,size) \
-((__builtin_constant_p(size) && size <= BITS_PER_LONG ? \
+((__builtin_constant_p(size) && (size) <= BITS_PER_LONG ? \
   (__scanbit(*(unsigned long *)addr,(size))) : \
   find_first_bit(addr,size)))
 
 #define find_next_bit(addr,size,off) \
-((__builtin_constant_p(size) && size <= BITS_PER_LONG ? 	  \
+((__builtin_constant_p(size) && (size) <= BITS_PER_LONG ? 	  \
   ((off) + (__scanbit((*(unsigned long *)addr) >> (off),(size)-(off)))) : \
 	find_next_bit(addr,size,off)))
 
 #define find_first_zero_bit(addr,size) \
-((__builtin_constant_p(size) && size <= BITS_PER_LONG ? \
+((__builtin_constant_p(size) && (size) <= BITS_PER_LONG ? \
   (__scanbit(~*(unsigned long *)addr,(size))) : \
   	find_first_zero_bit(addr,size)))
 	
 #define find_next_zero_bit(addr,size,off) \
-((__builtin_constant_p(size) && size <= BITS_PER_LONG ? 	  \
+((__builtin_constant_p(size) && (size) <= BITS_PER_LONG ? 	  \
   ((off)+(__scanbit(~(((*(unsigned long *)addr)) >> (off)),(size)-(off)))) : \
 	find_next_zero_bit(addr,size,off)))
 
diff -Nru a/include/asm-x86_64/cacheflush.h b/include/asm-x86_64/cacheflush.h
--- a/include/asm-x86_64/cacheflush.h	2005-03-01 23:38:53 -08:00
+++ b/include/asm-x86_64/cacheflush.h	2005-03-01 23:38:53 -08:00
@@ -25,5 +25,6 @@
 
 void global_flush_tlb(void); 
 int change_page_attr(struct page *page, int numpages, pgprot_t prot);
+int change_page_attr_addr(unsigned long addr, int numpages, pgprot_t prot);
 
 #endif /* _X8664_CACHEFLUSH_H */
diff -Nru a/include/asm-x86_64/calling.h b/include/asm-x86_64/calling.h
--- a/include/asm-x86_64/calling.h	2005-03-01 23:39:07 -08:00
+++ b/include/asm-x86_64/calling.h	2005-03-01 23:39:07 -08:00
@@ -143,22 +143,6 @@
 	RESTORE_ARGS 0,\addskip
 	.endm
 
-	/* push in order ss, rsp, eflags, cs, rip */
-	.macro FAKE_STACK_FRAME child_rip
-	xorl %eax,%eax
-	subq $6*8,%rsp
-	movq %rax,5*8(%rsp)  /* ss */
-	movq %rax,4*8(%rsp)  /* rsp */
-	movq $(1<<9),3*8(%rsp)  /* eflags */
-	movq $__KERNEL_CS,2*8(%rsp) /* cs */
-	movq \child_rip,1*8(%rsp)  /* rip */ 
-	movq %rax,(%rsp)   /* orig_rax */ 
-	.endm
-
-	.macro UNFAKE_STACK_FRAME
-	addq $8*6, %rsp
-	.endm
-
 	.macro icebp
 	.byte 0xf1
 	.endm
diff -Nru a/include/asm-x86_64/checksum.h b/include/asm-x86_64/checksum.h
--- a/include/asm-x86_64/checksum.h	2005-03-01 23:39:08 -08:00
+++ b/include/asm-x86_64/checksum.h	2005-03-01 23:39:08 -08:00
@@ -133,17 +133,17 @@
 
 
 /* Do not call this directly. Use the wrappers below */
-extern unsigned long csum_partial_copy_generic(const char *src, const char *dst, 
+extern unsigned long csum_partial_copy_generic(const unsigned char *src, const unsigned char *dst,
 					       unsigned len,
 					       unsigned sum, 
 					       int *src_err_ptr, int *dst_err_ptr);
 
 
-extern unsigned int csum_partial_copy_from_user(const char __user *src, char *dst, 
+extern unsigned int csum_partial_copy_from_user(const unsigned char __user *src, unsigned char *dst,
 				       int len, unsigned int isum, int *errp);
-extern unsigned int csum_partial_copy_to_user(const char *src, char __user *dst, 
+extern unsigned int csum_partial_copy_to_user(const unsigned char *src, unsigned char __user *dst,
 				      int len, unsigned int isum, int *errp);
-extern unsigned int csum_partial_copy_nocheck(const char *src, char *dst, int len, 
+extern unsigned int csum_partial_copy_nocheck(const unsigned char *src, unsigned char *dst, int len,
 					      unsigned int sum);
 
 /* Old names. To be removed. */
diff -Nru a/include/asm-x86_64/compat.h b/include/asm-x86_64/compat.h
--- a/include/asm-x86_64/compat.h	2005-03-01 23:39:08 -08:00
+++ b/include/asm-x86_64/compat.h	2005-03-01 23:39:08 -08:00
@@ -191,6 +191,11 @@
 	return (void __user *)(unsigned long)uptr;
 }
 
+static inline compat_uptr_t ptr_to_compat(void __user *uptr)
+{
+	return (u32)(unsigned long)uptr;
+}
+
 static __inline__ void __user *compat_alloc_user_space(long len)
 {
 	struct pt_regs *regs = (void *)current->thread.rsp0 - sizeof(struct pt_regs); 
diff -Nru a/include/asm-x86_64/cpufeature.h b/include/asm-x86_64/cpufeature.h
--- a/include/asm-x86_64/cpufeature.h	2005-03-01 23:38:58 -08:00
+++ b/include/asm-x86_64/cpufeature.h	2005-03-01 23:38:58 -08:00
@@ -75,7 +75,7 @@
 
 /* More extended AMD flags: CPUID level 0x80000001, ecx, word 5 */
 #define X86_FEATURE_LAHF_LM	(5*32+ 0) /* LAHF/SAHF in long mode */
-#define X86_FEATURE_HTVALID	(5*32+ 1) /* HyperThreading valid, otherwise CMP */
+#define X86_FEATURE_CMP_LEGACY	(5*32+ 1) /* If yes HyperThreading not valid */
 
 #define cpu_has(c, bit)                test_bit(bit, (c)->x86_capability)
 #define boot_cpu_has(bit)      test_bit(bit, boot_cpu_data.x86_capability)
diff -Nru a/include/asm-x86_64/cputime.h b/include/asm-x86_64/cputime.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-x86_64/cputime.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,6 @@
+#ifndef __X86_64_CPUTIME_H
+#define __X86_64_CPUTIME_H
+
+#include <asm-generic/cputime.h>
+
+#endif /* __X86_64_CPUTIME_H */
diff -Nru a/include/asm-x86_64/e820.h b/include/asm-x86_64/e820.h
--- a/include/asm-x86_64/e820.h	2005-03-01 23:39:07 -08:00
+++ b/include/asm-x86_64/e820.h	2005-03-01 23:39:07 -08:00
@@ -26,9 +26,6 @@
 
 #define LOWMEMSIZE()	(0x9f000)
 
-#define MAXMEM		(120UL * 1024 * 1024 * 1024 * 1024)  /* 120TB */ 
-
-
 #ifndef __ASSEMBLY__
 struct e820entry {
 	u64 addr;	/* start of memory segment */
diff -Nru a/include/asm-x86_64/elf.h b/include/asm-x86_64/elf.h
--- a/include/asm-x86_64/elf.h	2005-03-01 23:39:09 -08:00
+++ b/include/asm-x86_64/elf.h	2005-03-01 23:39:09 -08:00
@@ -147,14 +147,7 @@
  * 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(ex, have_pt_gnu_stack)	(!(have_pt_gnu_stack))
-	
-/*
- * 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))
+#define elf_read_implies_exec(ex, executable_stack)	(executable_stack != EXSTACK_DISABLE_X)
 
 extern int dump_task_regs (struct task_struct *, elf_gregset_t *);
 extern int dump_task_fpu (struct task_struct *, elf_fpregset_t *);
diff -Nru a/include/asm-x86_64/hardirq.h b/include/asm-x86_64/hardirq.h
--- a/include/asm-x86_64/hardirq.h	2005-03-01 23:38:53 -08:00
+++ b/include/asm-x86_64/hardirq.h	2005-03-01 23:38:53 -08:00
@@ -21,7 +21,6 @@
  */
 static inline void ack_bad_irq(unsigned int irq)
 {
-#ifdef CONFIG_X86
 	printk("unexpected IRQ trap at vector %02x\n", irq);
 #ifdef CONFIG_X86_LOCAL_APIC
 	/*
@@ -33,7 +32,6 @@
 	 * completely.
 	 */
 	ack_APIC_irq();
-#endif
 #endif
 }
 #endif /* __ASM_HARDIRQ_H */
diff -Nru a/include/asm-x86_64/hw_irq.h b/include/asm-x86_64/hw_irq.h
--- a/include/asm-x86_64/hw_irq.h	2005-03-01 23:39:17 -08:00
+++ b/include/asm-x86_64/hw_irq.h	2005-03-01 23:39:17 -08:00
@@ -87,8 +87,6 @@
  * Interrupt entry/exit code at both C and assembly level
  */
 
-extern void mask_irq(unsigned int irq);
-extern void unmask_irq(unsigned int irq);
 extern void disable_8259A_irq(unsigned int irq);
 extern void enable_8259A_irq(unsigned int irq);
 extern int i8259A_irq_pending(unsigned int irq);
diff -Nru a/include/asm-x86_64/i387.h b/include/asm-x86_64/i387.h
--- a/include/asm-x86_64/i387.h	2005-03-01 23:38:57 -08:00
+++ b/include/asm-x86_64/i387.h	2005-03-01 23:38:57 -08:00
@@ -25,16 +25,6 @@
 extern void init_fpu(struct task_struct *child);
 extern int save_i387(struct _fpstate __user *buf);
 
-static inline int need_signal_i387(struct task_struct *me) 
-{ 
-	if (!me->used_math)
-		return 0;
-	me->used_math = 0; 
-	if (me->thread_info->status & TS_USEDFPU)
-		return 0;
-	return 1;
-} 
-
 /*
  * FPU lazy state save handling...
  */
diff -Nru a/include/asm-x86_64/ia32.h b/include/asm-x86_64/ia32.h
--- a/include/asm-x86_64/ia32.h	2005-03-01 23:39:10 -08:00
+++ b/include/asm-x86_64/ia32.h	2005-03-01 23:39:10 -08:00
@@ -78,7 +78,7 @@
 	unsigned long long	st_ino;
 } __attribute__((packed));
 
-typedef struct siginfo32 {
+typedef struct compat_siginfo{
 	int si_signo;
 	int si_errno;
 	int si_code;
@@ -128,7 +128,7 @@
 			int _fd;
 		} _sigpoll;
 	} _sifields;
-} siginfo_t32;
+} compat_siginfo_t;
 
 struct sigframe32
 {
@@ -145,7 +145,7 @@
         int sig;
         u32 pinfo;
         u32 puc;
-        struct siginfo32 info;
+        compat_siginfo_t info;
         struct ucontext_ia32 uc;
         struct _fpstate_ia32 fpstate;
 };
@@ -165,8 +165,6 @@
 int do_get_thread_area(struct thread_struct *t, struct user_desc __user *info);
 int do_set_thread_area(struct thread_struct *t, struct user_desc __user *info);
 int ia32_child_tls(struct task_struct *p, struct pt_regs *childregs);
-int ia32_copy_siginfo_from_user(siginfo_t *to, siginfo_t32 __user *from);
-int ia32_copy_siginfo_to_user(siginfo_t32 __user *to, siginfo_t *from);
 #endif
 
 #endif /* !CONFIG_IA32_SUPPORT */
diff -Nru a/include/asm-x86_64/ia32_unistd.h b/include/asm-x86_64/ia32_unistd.h
--- a/include/asm-x86_64/ia32_unistd.h	2005-03-01 23:39:07 -08:00
+++ b/include/asm-x86_64/ia32_unistd.h	2005-03-01 23:39:07 -08:00
@@ -290,7 +290,11 @@
 #define __NR_ia32_mq_getsetattr	(__NR_ia32_mq_open+5)
 #define __NR_ia32_kexec		283
 #define __NR_ia32_waitid		284
+/* #define __NR_sys_setaltroot	285 */
+#define __NR_ia32_add_key		286
+#define __NR_ia32_request_key	287
+#define __NR_ia32_keyctl		288
 
-#define IA32_NR_syscalls 285	/* must be > than biggest syscall! */
+#define IA32_NR_syscalls 290	/* must be > than biggest syscall! */
 
 #endif /* _ASM_X86_64_IA32_UNISTD_H_ */
diff -Nru a/include/asm-x86_64/io.h b/include/asm-x86_64/io.h
--- a/include/asm-x86_64/io.h	2005-03-01 23:38:56 -08:00
+++ b/include/asm-x86_64/io.h	2005-03-01 23:38:56 -08:00
@@ -175,19 +175,19 @@
  * memory location directly.
  */
 
-static inline __u8 __readb(volatile void __iomem *addr)
+static inline __u8 __readb(const volatile void __iomem *addr)
 {
 	return *(__force volatile __u8 *)addr;
 }
-static inline __u16 __readw(volatile void __iomem *addr)
+static inline __u16 __readw(const volatile void __iomem *addr)
 {
 	return *(__force volatile __u16 *)addr;
 }
-static inline __u32 __readl(volatile void __iomem *addr)
+static inline __u32 __readl(const volatile void __iomem *addr)
 {
 	return *(__force volatile __u32 *)addr;
 }
-static inline __u64 __readq(volatile void __iomem *addr)
+static inline __u64 __readq(const volatile void __iomem *addr)
 {
 	return *(__force volatile __u64 *)addr;
 }
@@ -249,21 +249,19 @@
 #define __raw_writel writel
 #define __raw_writeq writeq
 
-void *__memcpy_fromio(void*,unsigned long,unsigned);
-void *__memcpy_toio(unsigned long,const void*,unsigned);
+void __memcpy_fromio(void*,unsigned long,unsigned);
+void __memcpy_toio(unsigned long,const void*,unsigned);
 
-static inline void *memcpy_fromio(void *to, volatile void __iomem *from, unsigned len)
+static inline void memcpy_fromio(void *to, const volatile void __iomem *from, unsigned len)
 {
-	return __memcpy_fromio(to,(unsigned long)from,len);
+	__memcpy_fromio(to,(unsigned long)from,len);
 }
-static inline void *memcpy_toio(volatile void __iomem *to, const void *from, unsigned len)
+static inline void memcpy_toio(volatile void __iomem *to, const void *from, unsigned len)
 {
-	return __memcpy_toio((unsigned long)to,from,len);
-}
-static inline void *memset_io(volatile void __iomem *a, int b, size_t c)
-{
-	return memset((__force void *)a,b,c);
+	__memcpy_toio((unsigned long)to,from,len);
 }
+
+void memset_io(volatile void __iomem *a, int b, size_t c);
 
 /*
  * ISA space is 'always mapped' on a typical x86 system, no need to
diff -Nru a/include/asm-x86_64/kdebug.h b/include/asm-x86_64/kdebug.h
--- a/include/asm-x86_64/kdebug.h	2005-03-01 23:38:52 -08:00
+++ b/include/asm-x86_64/kdebug.h	2005-03-01 23:38:52 -08:00
@@ -23,6 +23,7 @@
 	DIE_OOPS = 1,
 	DIE_INT3,
 	DIE_DEBUG,
+	DIE_DEBUGSTEP,
 	DIE_PANIC,
 	DIE_NMI,
 	DIE_DIE,
diff -Nru a/include/asm-x86_64/kprobes.h b/include/asm-x86_64/kprobes.h
--- a/include/asm-x86_64/kprobes.h	2005-03-01 23:38:52 -08:00
+++ b/include/asm-x86_64/kprobes.h	2005-03-01 23:38:52 -08:00
@@ -37,6 +37,8 @@
 	? (MAX_STACK_SIZE) \
 	: (((unsigned long)current_thread_info()) + THREAD_SIZE - (ADDR)))
 
+#define JPROBE_ENTRY(pentry)	(kprobe_opcode_t *)pentry
+
 /* Architecture specific copy of original instruction*/
 struct arch_specific_insn {
 	/* copy of the original instruction */
diff -Nru a/include/asm-x86_64/mce.h b/include/asm-x86_64/mce.h
--- a/include/asm-x86_64/mce.h	2005-03-01 23:38:52 -08:00
+++ b/include/asm-x86_64/mce.h	2005-03-01 23:38:52 -08:00
@@ -64,4 +64,17 @@
 #define MCE_GET_LOG_LEN      _IOR('M', 2, int)
 #define MCE_GETCLEAR_FLAGS   _IOR('M', 3, int)
 
+/* Software defined banks */
+#define MCE_EXTENDED_BANK	128
+#define MCE_THERMAL_BANK	MCE_EXTENDED_BANK + 0
+
+void mce_log(struct mce *m);
+#ifdef CONFIG_X86_MCE_INTEL
+void mce_intel_feature_init(struct cpuinfo_x86 *c);
+#else
+static inline void mce_intel_feature_init(struct cpuinfo_x86 *c)
+{
+}
+#endif
+
 #endif
diff -Nru a/include/asm-x86_64/mmu_context.h b/include/asm-x86_64/mmu_context.h
--- a/include/asm-x86_64/mmu_context.h	2005-03-01 23:38:54 -08:00
+++ b/include/asm-x86_64/mmu_context.h	2005-03-01 23:38:54 -08:00
@@ -40,10 +40,7 @@
 		write_pda(active_mm, next);
 #endif
 		set_bit(cpu, &next->cpu_vm_mask);
-		/* Re-load page tables */
-		*read_pda(level4_pgt) = __pa(next->pgd) | _PAGE_TABLE;
-		__flush_tlb();
-
+		asm volatile("movq %0,%%cr3" :: "r" (__pa(next->pgd)) : "memory");
 		if (unlikely(next->context.ldt != prev->context.ldt)) 
 			load_LDT_nolock(&next->context, cpu);
 	}
@@ -54,9 +51,10 @@
 			out_of_line_bug();
 		if(!test_and_set_bit(cpu, &next->cpu_vm_mask)) {
 			/* We were in lazy tlb mode and leave_mm disabled 
-			 * tlb flush IPI delivery. We must flush our tlb.
+			 * tlb flush IPI delivery. We must reload CR3
+			 * to make sure to use no freed page tables.
 			 */
-			local_flush_tlb();
+			asm volatile("movq %0,%%cr3" :: "r" (__pa(next->pgd)) : "memory");
 			load_LDT_nolock(&next->context, cpu);
 		}
 	}
diff -Nru a/include/asm-x86_64/mmzone.h b/include/asm-x86_64/mmzone.h
--- a/include/asm-x86_64/mmzone.h	2005-03-01 23:39:09 -08:00
+++ b/include/asm-x86_64/mmzone.h	2005-03-01 23:39:09 -08:00
@@ -12,7 +12,6 @@
 
 #include <asm/smp.h>
 
-#define MAXNODE 8 
 #define NODEMAPSIZE 0xff
 
 /* Simple perfect hash to map physical addresses to node numbers */
@@ -57,9 +56,8 @@
 #define page_to_pfn(page) \
 	(long)(((page) - page_zone(page)->zone_mem_map) + page_zone(page)->zone_start_pfn)
 
-/* AK: !DISCONTIGMEM just forces it to 1. Can't we too? */
-#define pfn_valid(pfn)          ((pfn) < num_physpages)
-
-
+#define pfn_valid(pfn) ((pfn) >= num_physpages ? 0 : \
+			({ u8 nid__ = pfn_to_nid(pfn); \
+			   nid__ != 0xff && (pfn) >= node_start_pfn(nid__) && (pfn) <= node_end_pfn(nid__); }))
 #endif
 #endif
diff -Nru a/include/asm-x86_64/msr.h b/include/asm-x86_64/msr.h
--- a/include/asm-x86_64/msr.h	2005-03-01 23:39:16 -08:00
+++ b/include/asm-x86_64/msr.h	2005-03-01 23:39:16 -08:00
@@ -67,7 +67,8 @@
 			  : "=a" (low), "=d" (high) \
 			  : "c" (counter))
 
-extern inline void cpuid(int op, int *eax, int *ebx, int *ecx, int *edx)
+extern inline void cpuid(int op, unsigned int *eax, unsigned int *ebx,
+			 unsigned int *ecx, unsigned int *edx)
 {
 	__asm__("cpuid"
 		: "=a" (*eax),
diff -Nru a/include/asm-x86_64/mtrr.h b/include/asm-x86_64/mtrr.h
--- a/include/asm-x86_64/mtrr.h	2005-03-01 23:38:53 -08:00
+++ b/include/asm-x86_64/mtrr.h	2005-03-01 23:38:53 -08:00
@@ -79,7 +79,6 @@
 		     unsigned int type, char increment);
 extern int mtrr_del (int reg, unsigned long base, unsigned long size);
 extern int mtrr_del_page (int reg, unsigned long base, unsigned long size);
-extern void mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi);
 #  else
 static __inline__ int mtrr_add (unsigned long base, unsigned long size,
 				unsigned int type, char increment)
@@ -101,8 +100,6 @@
 {
     return -ENODEV;
 }
-
-static __inline__ void mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi) {}
 
 #  endif
 
diff -Nru a/include/asm-x86_64/numa.h b/include/asm-x86_64/numa.h
--- a/include/asm-x86_64/numa.h	2005-03-01 23:38:44 -08:00
+++ b/include/asm-x86_64/numa.h	2005-03-01 23:38:44 -08:00
@@ -2,22 +2,20 @@
 #define _ASM_X8664_NUMA_H 1
 
 #include <linux/nodemask.h>
-
-#define MAXNODE 8 
-#define NODEMASK 0xff
+#include <asm/numnodes.h>
 
 struct node { 
 	u64 start,end; 
 };
 
-#define for_all_nodes(x) for ((x) = 0; (x) < numnodes; (x)++) \
-				if (node_online(x))
-
-extern int compute_hash_shift(struct node *nodes);
+extern int compute_hash_shift(struct node *nodes, int numnodes);
 
 #define ZONE_ALIGN (1UL << (MAX_ORDER+PAGE_SHIFT))
 
 extern void numa_add_cpu(int cpu);
 extern void numa_init_array(void);
+extern int numa_off;
+
+#define NUMA_NO_NODE 0xff
 
 #endif
diff -Nru a/include/asm-x86_64/numnodes.h b/include/asm-x86_64/numnodes.h
--- a/include/asm-x86_64/numnodes.h	2005-03-01 23:38:56 -08:00
+++ b/include/asm-x86_64/numnodes.h	2005-03-01 23:38:56 -08:00
@@ -3,7 +3,10 @@
 
 #include <linux/config.h>
 
-/* Max 8 Nodes - APIC limit currently */
-#define NODES_SHIFT	3
+#ifdef CONFIG_NUMA
+#define NODES_SHIFT	6
+#else
+#define NODES_SHIFT	0
+#endif
 
 #endif
diff -Nru a/include/asm-x86_64/page.h b/include/asm-x86_64/page.h
--- a/include/asm-x86_64/page.h	2005-03-01 23:38:51 -08:00
+++ b/include/asm-x86_64/page.h	2005-03-01 23:38:51 -08:00
@@ -38,27 +38,29 @@
 #define clear_user_page(page, vaddr, pg)	clear_page(page)
 #define copy_user_page(to, from, vaddr, pg)	copy_page(to, from)
 
+#define alloc_zeroed_user_highpage(vma, vaddr) alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO, vma, vaddr)
+#define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE
 /*
  * These are used to make use of C type-checking..
  */
 typedef struct { unsigned long pte; } pte_t;
 typedef struct { unsigned long pmd; } pmd_t;
+typedef struct { unsigned long pud; } pud_t;
 typedef struct { unsigned long pgd; } pgd_t;
-typedef struct { unsigned long pml4; } pml4_t;
 #define PTE_MASK	PHYSICAL_PAGE_MASK
 
 typedef struct { unsigned long pgprot; } pgprot_t;
 
 #define pte_val(x)	((x).pte)
 #define pmd_val(x)	((x).pmd)
+#define pud_val(x)	((x).pud)
 #define pgd_val(x)	((x).pgd)
-#define pml4_val(x)	((x).pml4)
 #define pgprot_val(x)	((x).pgprot)
 
 #define __pte(x) ((pte_t) { (x) } )
 #define __pmd(x) ((pmd_t) { (x) } )
+#define __pud(x) ((pud_t) { (x) } )
 #define __pgd(x) ((pgd_t) { (x) } )
-#define __pml4(x) ((pml4_t) { (x) } )
 #define __pgprot(x)	((pgprot_t) { (x) } )
 
 extern unsigned long vm_stack_flags, vm_stack_flags32;
@@ -67,19 +69,19 @@
 
 #define __START_KERNEL		0xffffffff80100000UL
 #define __START_KERNEL_map	0xffffffff80000000UL
-#define __PAGE_OFFSET           0x0000010000000000UL	/* 1 << 40 */
+#define __PAGE_OFFSET           0xffff810000000000UL
 
 #else
 #define __START_KERNEL		0xffffffff80100000
 #define __START_KERNEL_map	0xffffffff80000000
-#define __PAGE_OFFSET           0x0000010000000000	/* 1 << 40 */
+#define __PAGE_OFFSET           0xffff810000000000
 #endif /* !__ASSEMBLY__ */
 
 /* to align the pointer to the (next) page boundary */
 #define PAGE_ALIGN(addr)	(((addr)+PAGE_SIZE-1)&PAGE_MASK)
 
 /* See Documentation/x86_64/mm.txt for a description of the memory map. */
-#define __PHYSICAL_MASK_SHIFT	40
+#define __PHYSICAL_MASK_SHIFT	46
 #define __PHYSICAL_MASK		((1UL << __PHYSICAL_MASK_SHIFT) - 1)
 #define __VIRTUAL_MASK_SHIFT	48
 #define __VIRTUAL_MASK		((1UL << __VIRTUAL_MASK_SHIFT) - 1)
@@ -134,13 +136,7 @@
 	(((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
 	 VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
 
-#define CONFIG_ARCH_GATE_AREA 1	
-
-#ifndef __ASSEMBLY__
-struct task_struct;
-struct vm_area_struct *get_gate_vma(struct task_struct *tsk);
-int in_gate_area(struct task_struct *task, unsigned long addr);
-#endif
+#define __HAVE_ARCH_GATE_AREA 1	
 
 #endif /* __KERNEL__ */
 
diff -Nru a/include/asm-x86_64/pci.h b/include/asm-x86_64/pci.h
--- a/include/asm-x86_64/pci.h	2005-03-01 23:38:56 -08:00
+++ b/include/asm-x86_64/pci.h	2005-03-01 23:38:56 -08:00
@@ -41,7 +41,6 @@
 #include <linux/slab.h>
 #include <asm/scatterlist.h>
 #include <linux/string.h>
-#include <asm/io.h>
 #include <asm/page.h>
 
 extern int iommu_setup(char *opt);
diff -Nru a/include/asm-x86_64/pda.h b/include/asm-x86_64/pda.h
--- a/include/asm-x86_64/pda.h	2005-03-01 23:39:18 -08:00
+++ b/include/asm-x86_64/pda.h	2005-03-01 23:39:18 -08:00
@@ -17,7 +17,6 @@
         int irqcount;		    /* Irq nesting counter. Starts with -1 */  	
 	int cpunumber;		    /* Logical CPU number */
 	char *irqstackptr;	/* top of irqstack */
-	unsigned long volatile *level4_pgt; /* Per CPU top level page table */
 	unsigned int __softirq_pending;
 	unsigned int __nmi_count;	/* number of NMI on this CPUs */
 	struct mm_struct *active_mm;
diff -Nru a/include/asm-x86_64/pgalloc.h b/include/asm-x86_64/pgalloc.h
--- a/include/asm-x86_64/pgalloc.h	2005-03-01 23:38:57 -08:00
+++ b/include/asm-x86_64/pgalloc.h	2005-03-01 23:38:57 -08:00
@@ -9,8 +9,10 @@
 
 #define pmd_populate_kernel(mm, pmd, pte) \
 		set_pmd(pmd, __pmd(_PAGE_TABLE | __pa(pte)))
-#define pgd_populate(mm, pgd, pmd) \
-		set_pgd(pgd, __pgd(_PAGE_TABLE | __pa(pmd)))
+#define pud_populate(mm, pud, pmd) \
+		set_pud(pud, __pud(_PAGE_TABLE | __pa(pmd)))
+#define pgd_populate(mm, pgd, pud) \
+		set_pgd(pgd, __pgd(_PAGE_TABLE | __pa(pud)))
 
 static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, struct page *pte)
 {
@@ -33,12 +35,37 @@
 	return (pmd_t *)get_zeroed_page(GFP_KERNEL|__GFP_REPEAT);
 }
 
-static inline pgd_t *pgd_alloc (struct mm_struct *mm)
+static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr)
 {
-	return (pgd_t *)get_zeroed_page(GFP_KERNEL|__GFP_REPEAT);
+	return (pud_t *)get_zeroed_page(GFP_KERNEL|__GFP_REPEAT);
 }
 
-static inline void pgd_free (pgd_t *pgd)
+static inline void pud_free (pud_t *pud)
+{
+	BUG_ON((unsigned long)pud & (PAGE_SIZE-1));
+	free_page((unsigned long)pud);
+}
+
+static inline pgd_t *pgd_alloc(struct mm_struct *mm)
+{
+	unsigned boundary;
+	pgd_t *pgd = (pgd_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT);
+	if (!pgd)
+		return NULL;
+	/*
+	 * Copy kernel pointers in from init.
+	 * Could keep a freelist or slab cache of those because the kernel
+	 * part never changes.
+	 */
+	boundary = pgd_index(__PAGE_OFFSET);
+	memset(pgd, 0, boundary * sizeof(pgd_t));
+	memcpy(pgd + boundary,
+	       init_level4_pgt + boundary,
+	       (PTRS_PER_PGD - boundary) * sizeof(pgd_t));
+	return pgd;
+}
+
+static inline void pgd_free(pgd_t *pgd)
 {
 	BUG_ON((unsigned long)pgd & (PAGE_SIZE-1));
 	free_page((unsigned long)pgd);
@@ -73,5 +100,6 @@
 
 #define __pte_free_tlb(tlb,pte) tlb_remove_page((tlb),(pte))
 #define __pmd_free_tlb(tlb,x)   pmd_free(x)
+#define __pud_free_tlb(tlb,x)   pud_free(x)
 
 #endif /* _X86_64_PGALLOC_H */
diff -Nru a/include/asm-x86_64/pgtable.h b/include/asm-x86_64/pgtable.h
--- a/include/asm-x86_64/pgtable.h	2005-03-01 23:39:08 -08:00
+++ b/include/asm-x86_64/pgtable.h	2005-03-01 23:39:08 -08:00
@@ -4,12 +4,6 @@
 /*
  * This file contains the functions and defines necessary to modify and use
  * the x86-64 page table tree.
- * 
- * x86-64 has a 4 level table setup. Generic linux MM only supports
- * three levels. The fourth level is currently a single static page that
- * is shared by everybody and just contains a pointer to the current
- * three level page setup on the beginning and some kernel mappings at 
- * the end. For more details see Documentation/x86_64/mm.txt
  */
 #include <asm/processor.h>
 #include <asm/fixmap.h>
@@ -17,16 +11,16 @@
 #include <linux/threads.h>
 #include <asm/pda.h>
 
-extern pgd_t level3_kernel_pgt[512];
-extern pgd_t level3_physmem_pgt[512];
-extern pgd_t level3_ident_pgt[512];
+extern pud_t level3_kernel_pgt[512];
+extern pud_t level3_physmem_pgt[512];
+extern pud_t level3_ident_pgt[512];
 extern pmd_t level2_kernel_pgt[512];
-extern pml4_t init_level4_pgt[];
-extern pgd_t boot_vmalloc_pgt[];
+extern pgd_t init_level4_pgt[];
 extern unsigned long __supported_pte_mask;
 
-#define swapper_pg_dir NULL
+#define swapper_pg_dir init_level4_pgt
 
+extern int nonx_setup(char *str);
 extern void paging_init(void);
 extern void clear_kernel_mapping(unsigned long addr, unsigned long size);
 
@@ -39,16 +33,19 @@
 extern unsigned long empty_zero_page[PAGE_SIZE/sizeof(unsigned long)];
 #define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
 
-#define PML4_SHIFT	39
-#define PTRS_PER_PML4	512
-
 /*
  * PGDIR_SHIFT determines what a top-level page table entry can map
  */
-#define PGDIR_SHIFT	30
+#define PGDIR_SHIFT	39
 #define PTRS_PER_PGD	512
 
 /*
+ * 3rd level page
+ */
+#define PUD_SHIFT	30
+#define PTRS_PER_PUD	512
+
+/*
  * PMD_SHIFT determines the size of the area a middle-level
  * page table can map
  */
@@ -64,14 +61,13 @@
 	printk("%s:%d: bad pte %p(%016lx).\n", __FILE__, __LINE__, &(e), pte_val(e))
 #define pmd_ERROR(e) \
 	printk("%s:%d: bad pmd %p(%016lx).\n", __FILE__, __LINE__, &(e), pmd_val(e))
+#define pud_ERROR(e) \
+	printk("%s:%d: bad pud %p(%016lx).\n", __FILE__, __LINE__, &(e), pud_val(e))
 #define pgd_ERROR(e) \
 	printk("%s:%d: bad pgd %p(%016lx).\n", __FILE__, __LINE__, &(e), pgd_val(e))
 
-
-#define pml4_none(x)	(!pml4_val(x))
 #define pgd_none(x)	(!pgd_val(x))
-
-extern inline int pgd_present(pgd_t pgd)	{ return !pgd_none(pgd); }
+#define pud_none(x)	(!pud_val(x))
 
 static inline void set_pte(pte_t *dst, pte_t val)
 {
@@ -83,6 +79,16 @@
         pmd_val(*dst) = pmd_val(val); 
 } 
 
+static inline void set_pud(pud_t *dst, pud_t val)
+{
+	pud_val(*dst) = pud_val(val);
+}
+
+extern inline void pud_clear (pud_t *pud)
+{
+	set_pud(pud, __pud(0));
+}
+
 static inline void set_pgd(pgd_t *dst, pgd_t val)
 {
 	pgd_val(*dst) = pgd_val(val); 
@@ -93,45 +99,30 @@
 	set_pgd(pgd, __pgd(0));
 }
 
-static inline void set_pml4(pml4_t *dst, pml4_t val)
-{
-	pml4_val(*dst) = pml4_val(val); 
-}
-
-#define pgd_page(pgd) \
-((unsigned long) __va(pgd_val(pgd) & PHYSICAL_PAGE_MASK))
+#define pud_page(pud) \
+((unsigned long) __va(pud_val(pud) & PHYSICAL_PAGE_MASK))
 
 #define ptep_get_and_clear(xp)	__pte(xchg(&(xp)->pte, 0))
 #define pte_same(a, b)		((a).pte == (b).pte)
 
-#define PML4_SIZE	(1UL << PML4_SHIFT)
-#define PML4_MASK       (~(PML4_SIZE-1))
 #define PMD_SIZE	(1UL << PMD_SHIFT)
 #define PMD_MASK	(~(PMD_SIZE-1))
+#define PUD_SIZE	(1UL << PUD_SHIFT)
+#define PUD_MASK	(~(PUD_SIZE-1))
 #define PGDIR_SIZE	(1UL << PGDIR_SHIFT)
 #define PGDIR_MASK	(~(PGDIR_SIZE-1))
 
 #define USER_PTRS_PER_PGD	(TASK_SIZE/PGDIR_SIZE)
 #define FIRST_USER_PGD_NR	0
 
-#define USER_PGD_PTRS (PAGE_OFFSET >> PGDIR_SHIFT)
-#define KERNEL_PGD_PTRS (PTRS_PER_PGD-USER_PGD_PTRS)
-
-#define TWOLEVEL_PGDIR_SHIFT	20
-#define BOOT_USER_L4_PTRS 1
-#define BOOT_KERNEL_L4_PTRS 511	/* But we will do it in 4rd level */
-
-
-
 #ifndef __ASSEMBLY__
-#define VMALLOC_START    0xffffff0000000000UL
-#define VMALLOC_END      0xffffff7fffffffffUL
-#define MODULES_VADDR    0xffffffffa0000000UL
-#define MODULES_END      0xffffffffafffffffUL
+#define MAXMEM		 0x3fffffffffffUL
+#define VMALLOC_START    0xffffc20000000000UL
+#define VMALLOC_END      0xffffe1ffffffffffUL
+#define MODULES_VADDR    0xffffffff88000000UL
+#define MODULES_END      0xfffffffffff00000UL
 #define MODULES_LEN   (MODULES_END - MODULES_VADDR)
 
-#define IOMAP_START      0xfffffe8000000000UL
-
 #define _PAGE_BIT_PRESENT	0
 #define _PAGE_BIT_RW		1
 #define _PAGE_BIT_USER		2
@@ -191,6 +182,7 @@
 #define PAGE_KERNEL_EXEC MAKE_GLOBAL(__PAGE_KERNEL_EXEC)
 #define PAGE_KERNEL_RO MAKE_GLOBAL(__PAGE_KERNEL_RO)
 #define PAGE_KERNEL_NOCACHE MAKE_GLOBAL(__PAGE_KERNEL_NOCACHE)
+#define PAGE_KERNEL_VSYSCALL32 __pgprot(__PAGE_KERNEL_VSYSCALL)
 #define PAGE_KERNEL_VSYSCALL MAKE_GLOBAL(__PAGE_KERNEL_VSYSCALL)
 #define PAGE_KERNEL_LARGE MAKE_GLOBAL(__PAGE_KERNEL_LARGE)
 #define PAGE_KERNEL_VSYSCALL_NOCACHE MAKE_GLOBAL(__PAGE_KERNEL_VSYSCALL_NOCACHE)
@@ -222,6 +214,14 @@
        return val & ~(_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED);      
 } 
 
+static inline unsigned long pud_bad(pud_t pud)
+{
+       unsigned long val = pud_val(pud);
+       val &= ~PTE_MASK;
+       val &= ~(_PAGE_USER | _PAGE_DIRTY);
+       return val & ~(_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED);
+}
+
 #define pte_none(x)	(!pte_val(x))
 #define pte_present(x)	(pte_val(x) & (_PAGE_PRESENT | _PAGE_PROTNONE))
 #define pte_clear(xp)	do { set_pte(xp, __pte(0)); } while (0)
@@ -300,54 +300,32 @@
 
 /*
  * Level 4 access.
- * Never use these in the common code.
  */
-#define pml4_page(pml4) ((unsigned long) __va(pml4_val(pml4) & PTE_MASK))
-#define pml4_index(address) ((address >> PML4_SHIFT) & (PTRS_PER_PML4-1))
-#define pml4_offset_k(address) (init_level4_pgt + pml4_index(address))
-#define pml4_present(pml4) (pml4_val(pml4) & _PAGE_PRESENT)
-#define mk_kernel_pml4(address) ((pml4_t){ (address) | _KERNPG_TABLE })
-#define level3_offset_k(dir, address) ((pgd_t *) pml4_page(*(dir)) + pgd_index(address))
+#define pgd_page(pgd) ((unsigned long) __va((unsigned long)pgd_val(pgd) & PTE_MASK))
+#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
+#define pgd_offset(mm, addr) ((mm)->pgd + pgd_index(addr))
+#define pgd_offset_k(address) (init_level4_pgt + pgd_index(address))
+#define pgd_present(pgd) (pgd_val(pgd) & _PAGE_PRESENT)
+#define mk_kernel_pgd(address) ((pgd_t){ (address) | _KERNPG_TABLE })
 
-/* PGD - Level3 access */
+/* PUD - Level3 access */
 /* to find an entry in a page-table-directory. */
-#define pgd_index(address) ((address >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
-static inline pgd_t *__pgd_offset_k(pgd_t *pgd, unsigned long address)
+#define pud_index(address) (((address) >> PUD_SHIFT) & (PTRS_PER_PUD-1))
+#define pud_offset(pgd, address) ((pud_t *) pgd_page(*(pgd)) + pud_index(address))
+#define pud_offset_k(pgd, addr) pud_offset(pgd, addr)
+#define pud_present(pud) (pud_val(pud) & _PAGE_PRESENT)
+
+static inline pud_t *__pud_offset_k(pud_t *pud, unsigned long address)
 { 
-	return pgd + pgd_index(address);
+	return pud + pud_index(address);
 } 
 
-/* Find correct pgd via the hidden fourth level page level: */
-
-/* This accesses the reference page table of the boot cpu. 
-   Other CPUs get synced lazily via the page fault handler. */
-static inline pgd_t *pgd_offset_k(unsigned long address)
-{
-	unsigned long addr;
-
-	addr = pml4_val(init_level4_pgt[pml4_index(address)]);
-	addr &= PHYSICAL_PAGE_MASK;
-	return __pgd_offset_k((pgd_t *)__va(addr), address);
-}
-
-/* Access the pgd of the page table as seen by the current CPU. */ 
-static inline pgd_t *current_pgd_offset_k(unsigned long address)
-{
-	unsigned long addr;
-
-	addr = read_pda(level4_pgt)[pml4_index(address)];
-	addr &= PHYSICAL_PAGE_MASK;
-	return __pgd_offset_k((pgd_t *)__va(addr), address);
-}
-
-#define pgd_offset(mm, address) ((mm)->pgd+pgd_index(address))
-
 /* PMD  - Level 2 access */
 #define pmd_page_kernel(pmd) ((unsigned long) __va(pmd_val(pmd) & PTE_MASK))
 #define pmd_page(pmd)		(pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT))
 
 #define pmd_index(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
-#define pmd_offset(dir, address) ((pmd_t *) pgd_page(*(dir)) + \
+#define pmd_offset(dir, address) ((pmd_t *) pud_page(*(dir)) + \
 			pmd_index(address))
 #define pmd_none(x)	(!pmd_val(x))
 #define pmd_present(x)	(pmd_val(x) & _PAGE_PRESENT)
diff -Nru a/include/asm-x86_64/processor.h b/include/asm-x86_64/processor.h
--- a/include/asm-x86_64/processor.h	2005-03-01 23:39:17 -08:00
+++ b/include/asm-x86_64/processor.h	2005-03-01 23:39:17 -08:00
@@ -64,6 +64,7 @@
 	__u8	x86_num_cores;
 	__u8	x86_apicid;
         __u32   x86_power; 	
+	__u32   x86_cpuid_level;	/* Max CPUID function supported */
 	unsigned long loops_per_jiffy;
 } ____cacheline_aligned;
 
@@ -157,17 +158,11 @@
 		:"ax");
 }
 
-/*
- * Bus types
- */
-#define MCA_bus 0
-#define MCA_bus__is_a_macro
-
 
 /*
- * User space process size: 512GB - 1GB (default).
+ * User space process size. 47bits.
  */
-#define TASK_SIZE	(0x0000007fc0000000UL)
+#define TASK_SIZE	(0x800000000000UL)
 
 /* This decides where the kernel will search for a free chunk of vm
  * space during mmap's.
@@ -462,5 +457,7 @@
 #define cache_line_size() (boot_cpu_data.x86_cache_alignment)
 
 extern unsigned long boot_option_idle_override;
+/* Boot loader type from the setup header */
+extern int bootloader_type;
 
 #endif /* __ASM_X86_64_PROCESSOR_H */
diff -Nru a/include/asm-x86_64/proto.h b/include/asm-x86_64/proto.h
--- a/include/asm-x86_64/proto.h	2005-03-01 23:39:09 -08:00
+++ b/include/asm-x86_64/proto.h	2005-03-01 23:39:09 -08:00
@@ -15,7 +15,7 @@
 extern void early_idt_handler(void);
 
 extern void mcheck_init(struct cpuinfo_x86 *c);
-extern void init_memory_mapping(void);
+extern void init_memory_mapping(unsigned long start, unsigned long end);
 
 extern void system_call(void); 
 extern int kernel_syscall(void);
@@ -25,8 +25,6 @@
 extern void ia32_cstar_target(void); 
 extern void ia32_sysenter_target(void); 
 
-extern void calibrate_delay(void);
-extern void cpu_idle(void);
 extern void config_acpi_tables(void);
 extern void ia32_syscall(void);
 extern void iommu_hole_init(void);
@@ -54,7 +52,7 @@
 
 extern unsigned long end_pfn_map; 
 
-extern unsigned long cpu_initialized;
+extern cpumask_t cpu_initialized;
 
 extern void show_trace(unsigned long * rsp);
 extern void show_registers(struct pt_regs *regs);
@@ -107,6 +105,8 @@
 extern int iommu_aperture_allowed;
 extern int fix_aperture;
 extern int force_iommu;
+
+extern int reboot_force;
 
 extern void smp_local_timer_interrupt(struct pt_regs * regs);
 
diff -Nru a/include/asm-x86_64/resource.h b/include/asm-x86_64/resource.h
--- a/include/asm-x86_64/resource.h	2005-03-01 23:39:08 -08:00
+++ b/include/asm-x86_64/resource.h	2005-03-01 23:39:08 -08:00
@@ -1,51 +1,6 @@
 #ifndef _X8664_RESOURCE_H
 #define _X8664_RESOURCE_H
 
-/*
- * Resource limits
- */
-
-#define RLIMIT_CPU	0		/* CPU time in ms */
-#define RLIMIT_FSIZE	1		/* Maximum filesize */
-#define RLIMIT_DATA	2		/* max data size */
-#define RLIMIT_STACK	3		/* max stack size */
-#define RLIMIT_CORE	4		/* max core file size */
-#define RLIMIT_RSS	5		/* max resident set size */
-#define RLIMIT_NPROC	6		/* max number of processes */
-#define RLIMIT_NOFILE	7		/* max number of open files */
-#define RLIMIT_MEMLOCK	8		/* max locked-in-memory address space */
-#define RLIMIT_AS	9		/* address space limit */
-#define RLIMIT_LOCKS	10		/* maximum file locks held */
-#define RLIMIT_SIGPENDING 11		/* max number of pending signals */
-#define RLIMIT_MSGQUEUE 12		/* maximum bytes in POSIX mqueues */
-
-#define RLIM_NLIMITS	13
-
-/*
- * SuS says limits have to be unsigned.
- * Which makes a ton more sense anyway.
- */
-#define RLIM_INFINITY	(~0UL)
-
-#ifdef __KERNEL__
-
-#define INIT_RLIMITS					\
-{							\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{      _STK_LIM, RLIM_INFINITY },		\
-	{             0, RLIM_INFINITY },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{             0,             0 },		\
-	{      INR_OPEN,     INR_OPEN  },		\
-	{   MLOCK_LIMIT,   MLOCK_LIMIT },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{ MAX_SIGPENDING, MAX_SIGPENDING },		\
-	{ MQ_BYTES_MAX, MQ_BYTES_MAX },			\
-}
-
-#endif /* __KERNEL__ */
+#include <asm-generic/resource.h>
 
 #endif
diff -Nru a/include/asm-x86_64/smp.h b/include/asm-x86_64/smp.h
--- a/include/asm-x86_64/smp.h	2005-03-01 23:38:44 -08:00
+++ b/include/asm-x86_64/smp.h	2005-03-01 23:38:44 -08:00
@@ -59,6 +59,7 @@
  */
 
 extern cpumask_t cpu_callout_map;
+extern cpumask_t cpu_callin_map;
 #define cpu_possible_map cpu_callout_map
 
 static inline int num_booting_cpus(void)
@@ -66,7 +67,7 @@
 	return cpus_weight(cpu_callout_map);
 }
 
-#define smp_processor_id() read_pda(cpunumber)
+#define __smp_processor_id() read_pda(cpunumber)
 
 extern __inline int hard_smp_processor_id(void)
 {
diff -Nru a/include/asm-x86_64/spinlock.h b/include/asm-x86_64/spinlock.h
--- a/include/asm-x86_64/spinlock.h	2005-03-01 23:39:17 -08:00
+++ b/include/asm-x86_64/spinlock.h	2005-03-01 23:39:17 -08:00
@@ -18,6 +18,9 @@
 #ifdef CONFIG_DEBUG_SPINLOCK
 	unsigned magic;
 #endif
+#ifdef CONFIG_PREEMPT
+	unsigned int break_lock;
+#endif
 } spinlock_t;
 
 #define SPINLOCK_MAGIC	0xdead4ead
@@ -72,7 +75,7 @@
 {
 #ifdef CONFIG_DEBUG_SPINLOCK
 	BUG_ON(lock->magic != SPINLOCK_MAGIC);
-	BUG_ON(!spin_is_locked(lock));
+	assert_spin_locked(lock);
 #endif
 	__asm__ __volatile__(
 		spin_unlock_string
@@ -91,7 +94,7 @@
 	char oldval = 1;
 #ifdef CONFIG_DEBUG_SPINLOCK
 	BUG_ON(lock->magic != SPINLOCK_MAGIC);
-	BUG_ON(!spin_is_locked(lock));
+	assert_spin_locked(lock);
 #endif
 	__asm__ __volatile__(
 		spin_unlock_string
@@ -139,6 +142,9 @@
 #ifdef CONFIG_DEBUG_SPINLOCK
 	unsigned magic;
 #endif
+#ifdef CONFIG_PREEMPT
+	unsigned int break_lock;
+#endif
 } rwlock_t;
 
 #define RWLOCK_MAGIC	0xdeaf1eed
@@ -153,7 +159,8 @@
 
 #define rwlock_init(x)	do { *(x) = RW_LOCK_UNLOCKED; } while(0)
 
-#define rwlock_is_locked(x) ((x)->lock != RW_LOCK_BIAS)
+#define read_can_lock(x)	((int)(x)->lock > 0)
+#define write_can_lock(x)	((x)->lock == RW_LOCK_BIAS)
 
 /*
  * On x86, we implement read-write locks as a 32-bit counter
@@ -184,6 +191,16 @@
 
 #define _raw_read_unlock(rw)		asm volatile("lock ; incl %0" :"=m" ((rw)->lock) : : "memory")
 #define _raw_write_unlock(rw)	asm volatile("lock ; addl $" RW_LOCK_BIAS_STR ",%0":"=m" ((rw)->lock) : : "memory")
+
+static inline int _raw_read_trylock(rwlock_t *lock)
+{
+	atomic_t *count = (atomic_t *)lock;
+	atomic_dec(count);
+	if (atomic_read(count) >= 0)
+		return 1;
+	atomic_inc(count);
+	return 0;
+}
 
 static inline int _raw_write_trylock(rwlock_t *lock)
 {
diff -Nru a/include/asm-x86_64/system.h b/include/asm-x86_64/system.h
--- a/include/asm-x86_64/system.h	2005-03-01 23:39:09 -08:00
+++ b/include/asm-x86_64/system.h	2005-03-01 23:39:09 -08:00
@@ -35,7 +35,7 @@
 		     "thread_return:\n\t"					    \
 		     "movq %%gs:%P[pda_pcurrent],%%rsi\n\t"			  \
 		     "movq %P[thread_info](%%rsi),%%r8\n\t"			  \
-		     "btr  %[tif_fork],%P[ti_flags](%%r8)\n\t"			  \
+		     LOCK "btr  %[tif_fork],%P[ti_flags](%%r8)\n\t"		  \
 		     "movq %%rax,%%rdi\n\t" 					  \
 		     "jc   ret_from_fork\n\t"					  \
 		     RESTORE_CONTEXT						    \
@@ -325,6 +325,8 @@
 
 /* For spinlocks etc */
 #define local_irq_save(x) 	do { warn_if_not_ulong(x); __asm__ __volatile__("# local_irq_save \n\t pushfq ; popq %0 ; cli":"=g" (x): /* no input */ :"memory"); } while (0)
+
+void cpu_idle_wait(void);
 
 /*
  * disable hlt during certain critical i/o operations
diff -Nru a/include/asm-x86_64/thread_info.h b/include/asm-x86_64/thread_info.h
--- a/include/asm-x86_64/thread_info.h	2005-03-01 23:39:08 -08:00
+++ b/include/asm-x86_64/thread_info.h	2005-03-01 23:39:08 -08:00
@@ -106,6 +106,7 @@
 #define TIF_IA32		17	/* 32bit process */ 
 #define TIF_FORK		18	/* ret_from_fork */
 #define TIF_ABI_PENDING		19
+#define TIF_MEMDIE		20
 
 #define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE)
 #define _TIF_NOTIFY_RESUME	(1<<TIF_NOTIFY_RESUME)
diff -Nru a/include/asm-x86_64/topology.h b/include/asm-x86_64/topology.h
--- a/include/asm-x86_64/topology.h	2005-03-01 23:39:08 -08:00
+++ b/include/asm-x86_64/topology.h	2005-03-01 23:39:08 -08:00
@@ -16,6 +16,12 @@
 extern cpumask_t     node_to_cpumask[];
 extern cpumask_t pci_bus_to_cpumask[];
 
+#ifdef CONFIG_ACPI_NUMA
+extern int __node_distance(int, int);
+#define node_distance(a,b) __node_distance(a,b)
+/* #else fallback version */
+#endif
+
 #define cpu_to_node(cpu)		(cpu_to_node[cpu])
 #define parent_node(node)		(node)
 #define node_to_first_cpu(node) 	(__ffs(node_to_cpumask[node]))
@@ -42,11 +48,13 @@
 	.max_interval		= 32,			\
 	.busy_factor		= 32,			\
 	.imbalance_pct		= 125,			\
-	.cache_hot_time		= (10*1000),		\
+	.cache_hot_time		= (10*1000000),		\
 	.cache_nice_tries	= 1,			\
 	.per_cpu_gain		= 100,			\
 	.flags			= SD_LOAD_BALANCE	\
+				| SD_BALANCE_NEWIDLE	\
 				| SD_BALANCE_EXEC	\
+				| SD_WAKE_IDLE		\
 				| SD_WAKE_BALANCE,	\
 	.last_balance		= jiffies,		\
 	.balance_interval	= 1,			\
diff -Nru a/include/asm-x86_64/uaccess.h b/include/asm-x86_64/uaccess.h
--- a/include/asm-x86_64/uaccess.h	2005-03-01 23:39:18 -08:00
+++ b/include/asm-x86_64/uaccess.h	2005-03-01 23:39:18 -08:00
@@ -172,7 +172,7 @@
 
 /* FIXME: this hack is definitely wrong -AK */
 struct __large_struct { unsigned long buf[100]; };
-#define __m(x) (*(struct __large_struct *)(x))
+#define __m(x) (*(struct __large_struct __user *)(x))
 
 /*
  * Tell gcc we read from memory instead of writing: this is because
@@ -198,7 +198,7 @@
 #define __get_user_nocheck(x,ptr,size)				\
 ({								\
 	int __gu_err;						\
-	long __gu_val;						\
+	unsigned long __gu_val;					\
 	__get_user_size(__gu_val,(ptr),(size),__gu_err);	\
 	(x) = (__typeof__(*(ptr)))__gu_val;			\
 	__gu_err;						\
diff -Nru a/include/asm-x86_64/unistd.h b/include/asm-x86_64/unistd.h
--- a/include/asm-x86_64/unistd.h	2005-03-01 23:39:07 -08:00
+++ b/include/asm-x86_64/unistd.h	2005-03-01 23:39:07 -08:00
@@ -298,8 +298,9 @@
 #define __NR_mknod                             133
 __SYSCALL(__NR_mknod, sys_mknod)
 
+/* Only needed for a.out */
 #define __NR_uselib                            134
-__SYSCALL(__NR_uselib, sys_uselib)
+__SYSCALL(__NR_uselib, sys_ni_syscall)
 #define __NR_personality                       135
 __SYSCALL(__NR_personality, sys_personality)
 
@@ -556,8 +557,14 @@
 __SYSCALL(__NR_kexec_load, sys_ni_syscall)
 #define __NR_waitid		247
 __SYSCALL(__NR_waitid, sys_waitid)
+#define __NR_add_key		248
+__SYSCALL(__NR_add_key, sys_add_key)
+#define __NR_request_key	249
+__SYSCALL(__NR_request_key, sys_request_key)
+#define __NR_keyctl		250
+__SYSCALL(__NR_keyctl, sys_keyctl)
 
-#define __NR_syscall_max __NR_waitid
+#define __NR_syscall_max __NR_keyctl
 #ifndef __NO_STUBS
 
 /* user-visible error numbers are in the range -1 - -4095 */
@@ -581,7 +588,6 @@
 #define __ARCH_WANT_SYS_PAUSE
 #define __ARCH_WANT_SYS_SGETMASK
 #define __ARCH_WANT_SYS_SIGNAL
-#define __ARCH_WANT_SYS_TIME
 #define __ARCH_WANT_SYS_UTIME
 #define __ARCH_WANT_SYS_WAITPID
 #define __ARCH_WANT_SYS_SOCKETCALL
@@ -594,6 +600,7 @@
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_SIGPROCMASK
 #define __ARCH_WANT_SYS_RT_SIGACTION
+#define __ARCH_WANT_COMPAT_SYS_TIME
 #endif
 
 #ifndef __KERNEL_SYSCALLS__
@@ -724,7 +731,7 @@
 }
 
 /* implemented in asm in arch/x86_64/kernel/entry.S */
-extern long execve(char *, char **, char **);
+extern int execve(const char *, char * const *, char * const *);
 
 static inline long open(const char * filename, int flags, int mode)
 {
diff -Nru a/include/linux/ac97_codec.h b/include/linux/ac97_codec.h
--- a/include/linux/ac97_codec.h	2005-03-01 23:38:52 -08:00
+++ b/include/linux/ac97_codec.h	2005-03-01 23:38:52 -08:00
@@ -176,6 +176,39 @@
 #define AC97_EXTSTAT_PRK          0x2000
 #define AC97_EXTSTAT_PRL          0x4000
 
+/* extended audio ID register bit defines */
+#define AC97_EXTID_VRA            0x0001
+#define AC97_EXTID_DRA            0x0002
+#define AC97_EXTID_SPDIF          0x0004
+#define AC97_EXTID_VRM            0x0008
+#define AC97_EXTID_DSA0           0x0010
+#define AC97_EXTID_DSA1           0x0020
+#define AC97_EXTID_CDAC           0x0040
+#define AC97_EXTID_SDAC           0x0080
+#define AC97_EXTID_LDAC           0x0100
+#define AC97_EXTID_AMAP           0x0200
+#define AC97_EXTID_REV0           0x0400
+#define AC97_EXTID_REV1           0x0800
+#define AC97_EXTID_ID0            0x4000
+#define AC97_EXTID_ID1            0x8000
+
+/* extended status register bit defines */
+#define AC97_EXTSTAT_VRA          0x0001
+#define AC97_EXTSTAT_DRA          0x0002
+#define AC97_EXTSTAT_SPDIF        0x0004
+#define AC97_EXTSTAT_VRM          0x0008
+#define AC97_EXTSTAT_SPSA0        0x0010
+#define AC97_EXTSTAT_SPSA1        0x0020
+#define AC97_EXTSTAT_CDAC         0x0040
+#define AC97_EXTSTAT_SDAC         0x0080
+#define AC97_EXTSTAT_LDAC         0x0100
+#define AC97_EXTSTAT_MADC         0x0200
+#define AC97_EXTSTAT_SPCV         0x0400
+#define AC97_EXTSTAT_PRI          0x0800
+#define AC97_EXTSTAT_PRJ          0x1000
+#define AC97_EXTSTAT_PRK          0x2000
+#define AC97_EXTSTAT_PRL          0x4000
+
 /* useful power states */
 #define AC97_PWR_D0               0x0000      /* everything on */
 #define AC97_PWR_D1              AC97_PWR_PR0|AC97_PWR_PR1|AC97_PWR_PR4
@@ -314,5 +347,27 @@
 
 extern int ac97_register_driver(struct ac97_driver *driver);
 extern void ac97_unregister_driver(struct ac97_driver *driver);
+
+/* quirk types */
+enum {
+	AC97_TUNE_DEFAULT = -1, /* use default from quirk list (not valid in list) */
+	AC97_TUNE_NONE = 0,     /* nothing extra to do */
+	AC97_TUNE_HP_ONLY,      /* headphone (true line-out) control as master only */
+	AC97_TUNE_SWAP_HP,      /* swap headphone and master controls */
+	AC97_TUNE_SWAP_SURROUND, /* swap master and surround controls */
+	AC97_TUNE_AD_SHARING,   /* for AD1985, turn on OMS bit and use headphone */
+	AC97_TUNE_ALC_JACK,     /* for Realtek, enable JACK detection */
+};
+
+struct ac97_quirk {
+	unsigned short vendor;  /* PCI vendor id */
+	unsigned short device;  /* PCI device id */
+	unsigned short mask;    /* device id bit mask, 0 = accept all */
+	const char *name;       /* name shown as info */
+	int type;               /* quirk type above */
+};
+
+struct pci_dev;
+extern int ac97_tune_hardware(struct pci_dev *pdev, struct ac97_quirk *quirk, int override);
 
 #endif /* _AC97_CODEC_H_ */
diff -Nru a/include/linux/acct.h b/include/linux/acct.h
--- a/include/linux/acct.h	2005-03-01 23:39:18 -08:00
+++ b/include/linux/acct.h	2005-03-01 23:39:18 -08:00
@@ -120,9 +120,13 @@
 struct super_block;
 extern void acct_auto_close(struct super_block *sb);
 extern void acct_process(long exitcode);
+extern void acct_update_integrals(void);
+extern void acct_clear_integrals(struct task_struct *tsk);
 #else
 #define acct_auto_close(x)	do { } while (0)
 #define acct_process(x)		do { } while (0)
+#define acct_update_integrals()		do { } while (0)
+#define acct_clear_integrals(task)	do { } while (0)
 #endif
 
 /*
diff -Nru a/include/linux/acpi.h b/include/linux/acpi.h
--- a/include/linux/acpi.h	2005-03-01 23:38:44 -08:00
+++ b/include/linux/acpi.h	2005-03-01 23:38:44 -08:00
@@ -379,6 +379,7 @@
 char * __acpi_map_table (unsigned long phys_addr, unsigned long size);
 unsigned long acpi_find_rsdp (void);
 int acpi_boot_init (void);
+int acpi_boot_table_init (void);
 int acpi_numa_init (void);
 
 int acpi_table_init (void);
@@ -396,6 +397,12 @@
 void acpi_numa_memory_affinity_init (struct acpi_table_memory_affinity *ma);
 void acpi_numa_arch_fixup(void);
 
+#ifdef CONFIG_ACPI_HOTPLUG_CPU
+/* Arch dependent functions for cpu hotplug support */
+int acpi_map_lsapic(acpi_handle handle, int *pcpu);
+int acpi_unmap_lsapic(int cpu);
+#endif /* CONFIG_ACPI_HOTPLUG_CPU */
+
 extern int acpi_mp_config;
 
 extern u32 pci_mmcfg_base_addr;
@@ -411,11 +418,25 @@
 	return 0;
 }
 
+static inline int acpi_boot_table_init(void)
+{
+	return 0;
+}
+
 #endif 	/*!CONFIG_ACPI_BOOT*/
 
 unsigned int acpi_register_gsi (u32 gsi, int edge_level, int active_high_low);
 int acpi_gsi_to_irq (u32 gsi, unsigned int *irq);
 
+/*
+ * This function undoes the effect of one call to acpi_register_gsi().
+ * 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
 
 struct acpi_prt_entry {
@@ -441,6 +462,10 @@
 int acpi_pci_irq_enable (struct pci_dev *dev);
 void acpi_penalize_isa_irq(int irq);
 
+#ifdef CONFIG_ACPI_DEALLOCATE_IRQ
+void acpi_pci_irq_disable (struct pci_dev *dev);
+#endif
+
 struct acpi_pci_driver {
 	struct acpi_pci_driver *next;
 	int (*add)(acpi_handle handle);
@@ -498,5 +523,16 @@
 static inline unsigned int acpi_get_cstate_limit(void) { return 0; }
 static inline void acpi_set_cstate_limit(unsigned int new_limit) { return; }
 #endif
+
+#ifdef CONFIG_ACPI_NUMA
+int acpi_get_pxm(acpi_handle handle);
+#else
+static inline int acpi_get_pxm(acpi_handle handle)
+{
+	return 0;
+}
+#endif
+
+extern int pnpacpi_disabled;
 
 #endif /*_LINUX_ACPI_H*/
diff -Nru a/include/linux/affs_fs.h b/include/linux/affs_fs.h
--- a/include/linux/affs_fs.h	2005-03-01 23:39:18 -08:00
+++ b/include/linux/affs_fs.h	2005-03-01 23:39:18 -08:00
@@ -3,94 +3,5 @@
 /*
  * The affs filesystem constants/structures
  */
-
-#include <linux/types.h>
-
-#include <linux/affs_fs_i.h>
-#include <linux/affs_fs_sb.h>
-
 #define AFFS_SUPER_MAGIC 0xadff
-
-struct affs_date;
-
-/* --- Prototypes -----------------------------------------------------------------------------	*/
-
-/* amigaffs.c */
-
-extern int	affs_insert_hash(struct inode *inode, struct buffer_head *bh);
-extern int	affs_remove_hash(struct inode *dir, struct buffer_head *rem_bh);
-extern int	affs_remove_header(struct dentry *dentry);
-extern u32	affs_checksum_block(struct super_block *sb, struct buffer_head *bh);
-extern void	affs_fix_checksum(struct super_block *sb, struct buffer_head *bh);
-extern void	secs_to_datestamp(time_t secs, struct affs_date *ds);
-extern mode_t	prot_to_mode(u32 prot);
-extern void	mode_to_prot(struct inode *inode);
-extern void	affs_error(struct super_block *sb, const char *function, const char *fmt, ...);
-extern void	affs_warning(struct super_block *sb, const char *function, const char *fmt, ...);
-extern int	affs_check_name(const unsigned char *name, int len);
-extern int	affs_copy_name(unsigned char *bstr, struct dentry *dentry);
-
-/* bitmap. c */
-
-extern u32	affs_count_free_blocks(struct super_block *s);
-extern void	affs_free_block(struct super_block *sb, u32 block);
-extern u32	affs_alloc_block(struct inode *inode, u32 goal);
-extern int	affs_init_bitmap(struct super_block *sb, int *flags);
-extern void	affs_free_bitmap(struct super_block *sb);
-
-/* namei.c */
-
-extern int	affs_hash_name(struct super_block *sb, const u8 *name, unsigned int len);
-extern struct dentry *affs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *);
-extern int	affs_unlink(struct inode *dir, struct dentry *dentry);
-extern int	affs_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *);
-extern int	affs_mkdir(struct inode *dir, struct dentry *dentry, int mode);
-extern int	affs_rmdir(struct inode *dir, struct dentry *dentry);
-extern int	affs_link(struct dentry *olddentry, struct inode *dir,
-			  struct dentry *dentry);
-extern int	affs_symlink(struct inode *dir, struct dentry *dentry,
-			     const char *symname);
-extern int	affs_rename(struct inode *old_dir, struct dentry *old_dentry,
-			    struct inode *new_dir, struct dentry *new_dentry);
-
-/* inode.c */
-
-extern unsigned long		 affs_parent_ino(struct inode *dir);
-extern struct inode		*affs_new_inode(struct inode *dir);
-extern int			 affs_notify_change(struct dentry *dentry, struct iattr *attr);
-extern void			 affs_put_inode(struct inode *inode);
-extern void			 affs_delete_inode(struct inode *inode);
-extern void			 affs_clear_inode(struct inode *inode);
-extern void			 affs_read_inode(struct inode *inode);
-extern int			 affs_write_inode(struct inode *inode, int);
-extern int			 affs_add_entry(struct inode *dir, struct inode *inode, struct dentry *dentry, s32 type);
-
-/* super.c */
-
-extern int			 affs_fs(void);
-
-/* file.c */
-
-void		affs_free_prealloc(struct inode *inode);
-extern void	affs_truncate(struct inode *);
-
-/* dir.c */
-
-extern void   affs_dir_truncate(struct inode *);
-
-/* jump tables */
-
-extern struct inode_operations	 affs_file_inode_operations;
-extern struct inode_operations	 affs_dir_inode_operations;
-extern struct inode_operations   affs_symlink_inode_operations;
-extern struct file_operations	 affs_file_operations;
-extern struct file_operations	 affs_file_operations_ofs;
-extern struct file_operations	 affs_dir_operations;
-extern struct address_space_operations	 affs_symlink_aops;
-extern struct address_space_operations	 affs_aops;
-extern struct address_space_operations	 affs_aops_ofs;
-
-extern struct dentry_operations	 affs_dentry_operations;
-extern struct dentry_operations	 affs_dentry_operations_intl;
-
 #endif
diff -Nru a/include/linux/affs_fs_i.h b/include/linux/affs_fs_i.h
--- a/include/linux/affs_fs_i.h	2005-03-01 23:39:16 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,59 +0,0 @@
-#ifndef _AFFS_FS_I
-#define _AFFS_FS_I
-
-#include <linux/a.out.h>
-#include <linux/fs.h>
-#include <asm/semaphore.h>
-
-#define AFFS_CACHE_SIZE		PAGE_SIZE
-//#define AFFS_CACHE_SIZE		(4*4)
-
-#define AFFS_MAX_PREALLOC	32
-#define AFFS_LC_SIZE		(AFFS_CACHE_SIZE/sizeof(u32)/2)
-#define AFFS_AC_SIZE		(AFFS_CACHE_SIZE/sizeof(struct affs_ext_key)/2)
-#define AFFS_AC_MASK		(AFFS_AC_SIZE-1)
-
-struct affs_ext_key {
-	u32	ext;				/* idx of the extended block */
-	u32	key;				/* block number */
-};
-
-/*
- * affs fs inode data in memory
- */
-struct affs_inode_info {
-	u32	 i_opencnt;
-	struct semaphore i_link_lock;		/* Protects internal inode access. */
-	struct semaphore i_ext_lock;		/* Protects internal inode access. */
-#define i_hash_lock i_ext_lock
-	u32	 i_blkcnt;			/* block count */
-	u32	 i_extcnt;			/* extended block count */
-	u32	*i_lc;				/* linear cache of extended blocks */
-	u32	 i_lc_size;
-	u32	 i_lc_shift;
-	u32	 i_lc_mask;
-	struct affs_ext_key *i_ac;		/* associative cache of extended blocks */
-	u32	 i_ext_last;			/* last accessed extended block */
-	struct buffer_head *i_ext_bh;		/* bh of last extended block */
-	loff_t	 mmu_private;
-	u32	 i_protect;			/* unused attribute bits */
-	u32	 i_lastalloc;			/* last allocated block */
-	int	 i_pa_cnt;			/* number of preallocated blocks */
-#if 0
-	s32	 i_original;			/* if != 0, this is the key of the original */
-	u32	 i_data[AFFS_MAX_PREALLOC];	/* preallocated blocks */
-	int	 i_cache_users;			/* Cache cannot be freed while > 0 */
-	unsigned char i_hlink;			/* This is a fake */
-	unsigned char i_pad;
-	s32	 i_parent;			/* parent ino */
-#endif
-	struct inode vfs_inode;
-};
-
-/* short cut to get to the affs specific inode data */
-static inline struct affs_inode_info *AFFS_I(struct inode *inode)
-{
-	return list_entry(inode, struct affs_inode_info, vfs_inode);
-}
-
-#endif
diff -Nru a/include/linux/affs_fs_sb.h b/include/linux/affs_fs_sb.h
--- a/include/linux/affs_fs_sb.h	2005-03-01 23:38:53 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,57 +0,0 @@
-#ifndef _AFFS_FS_SB
-#define _AFFS_FS_SB
-
-/*
- * super-block data in memory
- *
- * Block numbers are adjusted for their actual size
- *
- */
-
-struct affs_bm_info {
-	u32 bm_key;			/* Disk block number */
-	u32 bm_free;			/* Free blocks in here */
-};
-
-struct affs_sb_info {
-	int s_partition_size;		/* Partition size in blocks. */
-	int s_reserved;			/* Number of reserved blocks. */
-	//u32 s_blksize;			/* Initial device blksize */
-	u32 s_data_blksize;		/* size of the data block w/o header */
-	u32 s_root_block;		/* FFS root block number. */
-	int s_hashsize;			/* Size of hash table. */
-	unsigned long s_flags;		/* See below. */
-	uid_t s_uid;			/* uid to override */
-	gid_t s_gid;			/* gid to override */
-	umode_t s_mode;			/* mode to override */
-	struct buffer_head *s_root_bh;	/* Cached root block. */
-	struct semaphore s_bmlock;	/* Protects bitmap access. */
-	struct affs_bm_info *s_bitmap;	/* Bitmap infos. */
-	u32 s_bmap_count;		/* # of bitmap blocks. */
-	u32 s_bmap_bits;		/* # of bits in one bitmap blocks */
-	u32 s_last_bmap;
-	struct buffer_head *s_bmap_bh;
-	char *s_prefix;			/* Prefix for volumes and assigns. */
-	int s_prefix_len;		/* Length of prefix. */
-	char s_volume[32];		/* Volume prefix for absolute symlinks. */
-};
-
-#define SF_INTL		0x0001		/* International filesystem. */
-#define SF_BM_VALID	0x0002		/* Bitmap is valid. */
-#define SF_IMMUTABLE	0x0004		/* Protection bits cannot be changed */
-#define SF_QUIET	0x0008		/* chmod errors will be not reported */
-#define SF_SETUID	0x0010		/* Ignore Amiga uid */
-#define SF_SETGID	0x0020		/* Ignore Amiga gid */
-#define SF_SETMODE	0x0040		/* Ignore Amiga protection bits */
-#define SF_MUFS		0x0100		/* Use MUFS uid/gid mapping */
-#define SF_OFS		0x0200		/* Old filesystem */
-#define SF_PREFIX	0x0400		/* Buffer for prefix is allocated */
-#define SF_VERBOSE	0x0800		/* Talk about fs when mounting */
-
-/* short cut to get to the affs specific sb data */
-static inline struct affs_sb_info *AFFS_SB(struct super_block *sb)
-{
-	return sb->s_fs_info;
-}
-
-#endif
diff -Nru a/include/linux/agp_backend.h b/include/linux/agp_backend.h
--- a/include/linux/agp_backend.h	2005-03-01 23:39:09 -08:00
+++ b/include/linux/agp_backend.h	2005-03-01 23:39:09 -08:00
@@ -54,7 +54,7 @@
 	struct pci_dev *device;
 	enum chipset_type chipset;
 	unsigned long mode;
-	off_t aper_base;
+	unsigned long aper_base;
 	size_t aper_size;
 	int max_memory;		/* In pages */
 	int current_memory;
@@ -95,24 +95,6 @@
 extern void agp_enable(u32);
 extern int agp_backend_acquire(void);
 extern void agp_backend_release(void);
-
-/*
- * Interface between drm and agp code.  When agp initializes, it makes
- * the below structure available via inter_module_register(), drm might
- * use it.  Keith Owens <kaos@ocs.com.au> 28 Oct 2000.
- */
-typedef struct {
-	void			(*free_memory)(struct agp_memory *);
-	struct agp_memory *	(*allocate_memory)(size_t, u32);
-	int			(*bind_memory)(struct agp_memory *, off_t);
-	int			(*unbind_memory)(struct agp_memory *);
-	void			(*enable)(u32);
-	int			(*acquire)(void);
-	void			(*release)(void);
-	int			(*copy_info)(struct agp_kern_info *);
-} drm_agp_t;
-
-extern const drm_agp_t *drm_agp_p;
 
 #endif				/* __KERNEL__ */
 #endif				/* _AGP_BACKEND_H */
diff -Nru a/include/linux/agpgart.h b/include/linux/agpgart.h
--- a/include/linux/agpgart.h	2005-03-01 23:38:44 -08:00
+++ b/include/linux/agpgart.h	2005-03-01 23:38:44 -08:00
@@ -64,7 +64,7 @@
 	struct agp_version version;	/* version of the driver        */
 	__u32 bridge_id;	/* bridge vendor/device         */
 	__u32 agp_mode;		/* mode info of bridge          */
-	off_t aper_base;	/* base of aperture             */
+	unsigned long aper_base;/* base of aperture             */
 	size_t aper_size;	/* size of aperture             */
 	size_t pg_total;	/* max pages (swap + system)    */
 	size_t pg_system;	/* max pages (system)           */
@@ -118,7 +118,7 @@
 	struct agp_version version;	/* version of the driver        */
 	u32 bridge_id;		/* bridge vendor/device         */
 	u32 agp_mode;		/* mode info of bridge          */
-	off_t aper_base;	/* base of aperture             */
+	unsigned long aper_base;/* base of aperture             */
 	size_t aper_size;	/* size of aperture             */
 	size_t pg_total;	/* max pages (swap + system)    */
 	size_t pg_system;	/* max pages (system)           */
diff -Nru a/include/linux/amigaffs.h b/include/linux/amigaffs.h
--- a/include/linux/amigaffs.h	2005-03-01 23:38:53 -08:00
+++ b/include/linux/amigaffs.h	2005-03-01 23:38:53 -08:00
@@ -2,133 +2,8 @@
 #define AMIGAFFS_H
 
 #include <linux/types.h>
-#include <linux/buffer_head.h>
-#include <linux/string.h>
 #include <asm/byteorder.h>
 
-/* AmigaOS allows file names with up to 30 characters length.
- * Names longer than that will be silently truncated. If you
- * want to disallow this, comment out the following #define.
- * Creating filesystem objects with longer names will then
- * result in an error (ENAMETOOLONG).
- */
-/*#define AFFS_NO_TRUNCATE */
-
-/* Ugly macros make the code more pretty. */
-
-#define GET_END_PTR(st,p,sz)		 ((st *)((char *)(p)+((sz)-sizeof(st))))
-#define AFFS_GET_HASHENTRY(data,hashkey) be32_to_cpu(((struct dir_front *)data)->hashtable[hashkey])
-#define AFFS_BLOCK(sb, bh, blk)		(AFFS_HEAD(bh)->table[AFFS_SB(sb)->s_hashsize-1-(blk)])
-
-static inline void
-affs_set_blocksize(struct super_block *sb, int size)
-{
-	sb_set_blocksize(sb, size);
-}
-static inline struct buffer_head *
-affs_bread(struct super_block *sb, int block)
-{
-	pr_debug("affs_bread: %d\n", block);
-	if (block >= AFFS_SB(sb)->s_reserved && block < AFFS_SB(sb)->s_partition_size)
-		return sb_bread(sb, block);
-	return NULL;
-}
-static inline struct buffer_head *
-affs_getblk(struct super_block *sb, int block)
-{
-	pr_debug("affs_getblk: %d\n", block);
-	if (block >= AFFS_SB(sb)->s_reserved && block < AFFS_SB(sb)->s_partition_size)
-		return sb_getblk(sb, block);
-	return NULL;
-}
-static inline struct buffer_head *
-affs_getzeroblk(struct super_block *sb, int block)
-{
-	struct buffer_head *bh;
-	pr_debug("affs_getzeroblk: %d\n", block);
-	if (block >= AFFS_SB(sb)->s_reserved && block < AFFS_SB(sb)->s_partition_size) {
-		bh = sb_getblk(sb, block);
-		lock_buffer(bh);
-		memset(bh->b_data, 0 , sb->s_blocksize);
-		set_buffer_uptodate(bh);
-		unlock_buffer(bh);
-		return bh;
-	}
-	return NULL;
-}
-static inline struct buffer_head *
-affs_getemptyblk(struct super_block *sb, int block)
-{
-	struct buffer_head *bh;
-	pr_debug("affs_getemptyblk: %d\n", block);
-	if (block >= AFFS_SB(sb)->s_reserved && block < AFFS_SB(sb)->s_partition_size) {
-		bh = sb_getblk(sb, block);
-		wait_on_buffer(bh);
-		set_buffer_uptodate(bh);
-		return bh;
-	}
-	return NULL;
-}
-static inline void
-affs_brelse(struct buffer_head *bh)
-{
-	if (bh)
-		pr_debug("affs_brelse: %lld\n", (long long) bh->b_blocknr);
-	brelse(bh);
-}
-
-static inline void
-affs_adjust_checksum(struct buffer_head *bh, u32 val)
-{
-	u32 tmp = be32_to_cpu(((__be32 *)bh->b_data)[5]);
-	((__be32 *)bh->b_data)[5] = cpu_to_be32(tmp - val);
-}
-static inline void
-affs_adjust_bitmapchecksum(struct buffer_head *bh, u32 val)
-{
-	u32 tmp = be32_to_cpu(((__be32 *)bh->b_data)[0]);
-	((__be32 *)bh->b_data)[0] = cpu_to_be32(tmp - val);
-}
-
-static inline void
-affs_lock_link(struct inode *inode)
-{
-	down(&AFFS_I(inode)->i_link_lock);
-}
-static inline void
-affs_unlock_link(struct inode *inode)
-{
-	up(&AFFS_I(inode)->i_link_lock);
-}
-static inline void
-affs_lock_dir(struct inode *inode)
-{
-	down(&AFFS_I(inode)->i_hash_lock);
-}
-static inline void
-affs_unlock_dir(struct inode *inode)
-{
-	up(&AFFS_I(inode)->i_hash_lock);
-}
-static inline void
-affs_lock_ext(struct inode *inode)
-{
-	down(&AFFS_I(inode)->i_ext_lock);
-}
-static inline void
-affs_unlock_ext(struct inode *inode)
-{
-	up(&AFFS_I(inode)->i_ext_lock);
-}
-
-#ifdef __LITTLE_ENDIAN
-#define BO_EXBITS	0x18UL
-#elif defined(__BIG_ENDIAN)
-#define BO_EXBITS	0x00UL
-#else
-#error Endianness must be known for affs to work.
-#endif
-
 #define FS_OFS		0x444F5300
 #define FS_FFS		0x444F5301
 #define FS_INTLOFS	0x444F5302
@@ -155,13 +30,6 @@
 #define ST_LINKDIR	4
 
 #define AFFS_ROOT_BMAPS		25
-
-#define AFFS_HEAD(bh)		((struct affs_head *)(bh)->b_data)
-#define AFFS_TAIL(sb, bh)	((struct affs_tail *)((bh)->b_data+(sb)->s_blocksize-sizeof(struct affs_tail)))
-#define AFFS_ROOT_HEAD(bh)	((struct affs_root_head *)(bh)->b_data)
-#define AFFS_ROOT_TAIL(sb, bh)	((struct affs_root_tail *)((bh)->b_data+(sb)->s_blocksize-sizeof(struct affs_root_tail)))
-#define AFFS_DATA_HEAD(bh)	((struct affs_data_head *)(bh)->b_data)
-#define AFFS_DATA(bh)		(((struct affs_data_head *)(bh)->b_data)->data)
 
 struct affs_date {
 	__be32 days;
diff -Nru a/include/linux/arcdevice.h b/include/linux/arcdevice.h
--- a/include/linux/arcdevice.h	2005-03-01 23:38:53 -08:00
+++ b/include/linux/arcdevice.h	2005-03-01 23:38:53 -08:00
@@ -25,7 +25,6 @@
 #define bool int
 #endif
 
-
 /*
  * RECON_THRESHOLD is the maximum number of RECON messages to receive
  * within one minute before printing a "cabling problem" warning. The
@@ -74,6 +73,7 @@
 #define D_SKB		1024	/* show skb's                             */
 #define D_SKB_SIZE	2048	/* show skb sizes			  */
 #define D_TIMING	4096	/* show time needed to copy buffers to card */
+#define D_DEBUG         8192    /* Very detailed debug line for line */
 
 #ifndef ARCNET_DEBUG_MAX
 #define ARCNET_DEBUG_MAX (127)	/* change to ~0 if you want detailed debugging */
@@ -135,6 +135,7 @@
 #define TXACKflag       0x02	/* transmitted msg. ackd */
 #define RECONflag       0x04	/* network reconfigured */
 #define TESTflag        0x08	/* test flag */
+#define EXCNAKflag      0x08    /* excesive nak flag */
 #define RESETflag       0x10	/* power-on-reset */
 #define RES1flag        0x20	/* reserved - usually set by jumper */
 #define RES2flag        0x40	/* reserved - usually set by jumper */
@@ -162,6 +163,8 @@
 #define RESETclear      0x08	/* power-on-reset */
 #define CONFIGclear     0x10	/* system reconfigured */
 
+#define EXCNAKclear     0x0E    /* Clear and acknowledge the excive nak bit */
+
 /* flags for "load test flags" command */
 #define TESTload        0x08	/* test flag (diagnostic) */
 
@@ -187,6 +190,7 @@
 struct ArcProto {
 	char suffix;		/* a for RFC1201, e for ether-encap, etc. */
 	int mtu;		/* largest possible packet */
+	int is_ip;              /* This is a ip plugin - not a raw thing */
 
 	void (*rx) (struct net_device * dev, int bufnum,
 		    struct archdr * pkthdr, int length);
@@ -197,9 +201,11 @@
 	int (*prepare_tx) (struct net_device * dev, struct archdr * pkt, int length,
 			   int bufnum);
 	int (*continue_tx) (struct net_device * dev, int bufnum);
+	int (*ack_tx) (struct net_device * dev, int acked);
 };
 
-extern struct ArcProto *arc_proto_map[256], *arc_proto_default, *arc_bcast_proto;
+extern struct ArcProto *arc_proto_map[256], *arc_proto_default,
+	*arc_bcast_proto, *arc_raw_proto;
 extern struct ArcProto arc_proto_null;
 
 
@@ -251,6 +257,10 @@
 	char *card_name;	/* card ident string */
 	int card_flags;		/* special card features */
 
+
+	/* On preemtive and SMB a lock is needed */
+	spinlock_t lock;
+
 	/*
 	 * Buffer management: an ARCnet card has 4 x 512-byte buffers, each of
 	 * which can be used for either sending or receiving.  The new dynamic
@@ -279,6 +289,8 @@
 	int num_recons;		/* number of RECONs between first and last. */
 	bool network_down;	/* do we think the network is down? */
 
+	bool excnak_pending;    /* We just got an excesive nak interrupt */
+
 	struct {
 		uint16_t sequence;	/* sequence number (incs with each packet) */
 		uint16_t aborted_seq;
@@ -323,14 +335,14 @@
 #endif
 
 #if (ARCNET_DEBUG_MAX & D_RX) || (ARCNET_DEBUG_MAX & D_TX)
-void arcnet_dump_packet(struct net_device *dev, int bufnum, char *desc);
+void arcnet_dump_packet(struct net_device *dev, int bufnum, char *desc,
+			int take_arcnet_lock);
 #else
-#define arcnet_dump_packet(dev, bufnum, desc) ;
+#define arcnet_dump_packet(dev, bufnum, desc,take_arcnet_lock) ;
 #endif
 
 void arcnet_unregister_proto(struct ArcProto *proto);
 irqreturn_t arcnet_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-void arcdev_setup(struct net_device *dev);
 struct net_device *alloc_arcdev(char *name);
 void arcnet_rx(struct net_device *dev, int bufnum);
 
diff -Nru a/include/linux/ata.h b/include/linux/ata.h
--- a/include/linux/ata.h	2005-03-01 23:38:59 -08:00
+++ b/include/linux/ata.h	2005-03-01 23:38:59 -08:00
@@ -123,6 +123,8 @@
 	ATA_CMD_PIO_WRITE_EXT	= 0x34,
 	ATA_CMD_SET_FEATURES	= 0xEF,
 	ATA_CMD_PACKET		= 0xA0,
+	ATA_CMD_VERIFY		= 0x40,
+	ATA_CMD_VERIFY_EXT	= 0x42,
 
 	/* SETFEATURES stuff */
 	SETFEATURES_XFER	= 0x03,
diff -Nru a/include/linux/atalk.h b/include/linux/atalk.h
--- a/include/linux/atalk.h	2005-03-01 23:39:09 -08:00
+++ b/include/linux/atalk.h	2005-03-01 23:39:09 -08:00
@@ -188,8 +188,6 @@
 extern int		 aarp_send_ddp(struct net_device *dev,
 				       struct sk_buff *skb,
 				       struct atalk_addr *sa, void *hwaddr);
-extern void		 aarp_send_probe(struct net_device *dev,
-					 struct atalk_addr *addr);
 extern void		 aarp_device_down(struct net_device *dev);
 extern void		 aarp_probe_network(struct atalk_iface *atif);
 extern int 		 aarp_proxy_probe_network(struct atalk_iface *atif,
@@ -231,7 +229,7 @@
 extern int atalk_proc_init(void);
 extern void atalk_proc_exit(void);
 #else
-#define atalk_proc_init()	0
+#define atalk_proc_init()	({ 0; })
 #define atalk_proc_exit()	do { } while(0)
 #endif /* CONFIG_PROC_FS */
 
diff -Nru a/include/linux/atmdev.h b/include/linux/atmdev.h
--- a/include/linux/atmdev.h	2005-03-01 23:39:09 -08:00
+++ b/include/linux/atmdev.h	2005-03-01 23:39:09 -08:00
@@ -313,7 +313,7 @@
 
 struct atm_dev_addr {
 	struct sockaddr_atmsvc addr;	/* ATM address */
-	struct atm_dev_addr *next;	/* next address */
+	struct list_head entry;		/* next address */
 };
 
 struct atm_dev {
@@ -325,7 +325,7 @@
 	void		*dev_data;	/* per-device data */
 	void		*phy_data;	/* private PHY date */
 	unsigned long	flags;		/* device flags (ATM_DF_*) */
-	struct atm_dev_addr *local;	/* local ATM addresses */
+	struct list_head local;		/* local ATM addresses */
 	unsigned char	esi[ESI_LEN];	/* ESI ("MAC" addr) */
 	struct atm_cirange ci_range;	/* VPI/VCI range */
 	struct k_atm_dev_stats stats;	/* statistics */
diff -Nru a/include/linux/attribute_container.h b/include/linux/attribute_container.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/linux/attribute_container.h	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,73 @@
+/*
+ * class_container.h - a generic container for all classes
+ *
+ * Copyright (c) 2005 - James Bottomley <James.Bottomley@steeleye.com>
+ *
+ * This file is licensed under GPLv2
+ */
+
+#ifndef _ATTRIBUTE_CONTAINER_H_
+#define _ATTRIBUTE_CONTAINER_H_
+
+#include <linux/device.h>
+#include <linux/list.h>
+
+struct attribute_container {
+	struct list_head	node;
+	struct list_head	containers;
+	struct class		*class;
+	struct class_device_attribute **attrs;
+	int (*match)(struct attribute_container *, struct device *);
+#define	ATTRIBUTE_CONTAINER_NO_CLASSDEVS	0x01
+	unsigned long		flags;
+};
+
+static inline int
+attribute_container_no_classdevs(struct attribute_container *atc)
+{
+	return atc->flags & ATTRIBUTE_CONTAINER_NO_CLASSDEVS;
+}
+
+static inline void
+attribute_container_set_no_classdevs(struct attribute_container *atc)
+{
+	atc->flags |= ATTRIBUTE_CONTAINER_NO_CLASSDEVS;
+}
+
+int attribute_container_register(struct attribute_container *cont);
+int attribute_container_unregister(struct attribute_container *cont);
+void attribute_container_create_device(struct device *dev,
+				       int (*fn)(struct attribute_container *,
+						 struct device *,
+						 struct class_device *));
+void attribute_container_add_device(struct device *dev,
+				    int (*fn)(struct attribute_container *,
+					      struct device *,
+					      struct class_device *));
+void attribute_container_remove_device(struct device *dev,
+				       void (*fn)(struct attribute_container *,
+						  struct device *,
+						  struct class_device *));
+void attribute_container_device_trigger(struct device *dev, 
+					int (*fn)(struct attribute_container *,
+						  struct device *,
+						  struct class_device *));
+void attribute_container_trigger(struct device *dev, 
+				 int (*fn)(struct attribute_container *,
+					   struct device *));
+int attribute_container_add_attrs(struct class_device *classdev);
+int attribute_container_add_class_device(struct class_device *classdev);
+int attribute_container_add_class_device_adapter(struct attribute_container *cont,
+						 struct device *dev,
+						 struct class_device *classdev);
+void attribute_container_remove_attrs(struct class_device *classdev);
+void attribute_container_class_device_del(struct class_device *classdev);
+
+
+
+
+
+
+struct class_device_attribute **attribute_container_classdev_to_attrs(const struct class_device *classdev);
+
+#endif
diff -Nru a/include/linux/audit.h b/include/linux/audit.h
--- a/include/linux/audit.h	2005-03-01 23:38:57 -08:00
+++ b/include/linux/audit.h	2005-03-01 23:38:57 -08:00
@@ -114,12 +114,6 @@
 	__u32		backlog;	/* messages waiting in queue */
 };
 
-struct audit_login {
-	__u32		loginuid;
-	int		msglen;
-	char		msg[1024];
-};
-
 struct audit_rule {		/* for AUDIT_LIST, AUDIT_ADD, and AUDIT_DEL */
 	__u32		flags;	/* AUDIT_PER_{TASK,CALL}, AUDIT_PREPEND */
 	__u32		action;	/* AUDIT_NEVER, AUDIT_POSSIBLE, AUDIT_ALWAYS */
@@ -155,6 +149,7 @@
 extern void audit_get_stamp(struct audit_context *ctx,
 			    struct timespec *t, int *serial);
 extern int  audit_set_loginuid(struct audit_context *ctx, uid_t loginuid);
+extern uid_t audit_get_loginuid(struct audit_context *ctx);
 #else
 #define audit_alloc(t) ({ 0; })
 #define audit_free(t) do { ; } while (0)
@@ -163,6 +158,7 @@
 #define audit_getname(n) do { ; } while (0)
 #define audit_putname(n) do { ; } while (0)
 #define audit_inode(n,i,d) do { ; } while (0)
+#define audit_get_loginuid(c) ({ -1; })
 #endif
 
 #ifdef CONFIG_AUDIT
diff -Nru a/include/linux/backlight.h b/include/linux/backlight.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/linux/backlight.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,57 @@
+/*
+ * Backlight Lowlevel Control Abstraction
+ *
+ * Copyright (C) 2003,2004 Hewlett-Packard Company
+ *
+ */
+
+#ifndef _LINUX_BACKLIGHT_H
+#define _LINUX_BACKLIGHT_H
+
+#include <linux/device.h>
+#include <linux/notifier.h>
+
+struct backlight_device;
+struct fb_info;
+
+/* This structure defines all the properties of a backlight
+   (usually attached to a LCD). */
+struct backlight_properties {
+	/* Owner module */
+	struct module *owner;
+	/* Get the backlight power status (0: full on, 1..3: power saving
+	   modes; 4: full off), see FB_BLANK_XXX */
+	int (*get_power)(struct backlight_device *);
+	/* Enable or disable power to the LCD (0: on; 4: off, see FB_BLANK_XXX) */
+	int (*set_power)(struct backlight_device *, int power);
+	/* Maximal value for brightness (read-only) */
+	int max_brightness;
+	/* Get current backlight brightness */
+	int (*get_brightness)(struct backlight_device *);
+	/* Set backlight brightness (0..max_brightness) */
+	int (*set_brightness)(struct backlight_device *, int brightness);
+	/* Check if given framebuffer device is the one bound to this backlight;
+	   return 0 if not, !=0 if it is. If NULL, backlight always matches the fb. */
+	int (*check_fb)(struct fb_info *);
+};
+
+struct backlight_device {
+	/* This protects the 'props' field. If 'props' is NULL, the driver that
+	   registered this device has been unloaded, and if class_get_devdata()
+	   points to something in the body of that driver, it is also invalid. */
+	struct semaphore sem;
+	/* If this is NULL, the backing module is unloaded */
+	struct backlight_properties *props;
+	/* The framebuffer notifier block */
+	struct notifier_block fb_notif;
+	/* The class device structure */
+	struct class_device class_dev;
+};
+
+extern struct backlight_device *backlight_device_register(const char *name,
+	void *devdata, struct backlight_properties *bp);
+extern void backlight_device_unregister(struct backlight_device *bd);
+
+#define to_backlight_device(obj) container_of(obj, struct backlight_device, class_dev)
+
+#endif
diff -Nru a/include/linux/binfmts.h b/include/linux/binfmts.h
--- a/include/linux/binfmts.h	2005-03-01 23:38:57 -08:00
+++ b/include/linux/binfmts.h	2005-03-01 23:38:57 -08:00
@@ -74,7 +74,9 @@
 #define EXSTACK_DISABLE_X 1	/* Disable executable stacks */
 #define EXSTACK_ENABLE_X  2	/* Enable executable stacks */
 
-extern int setup_arg_pages(struct linux_binprm * bprm, int executable_stack);
+extern int setup_arg_pages(struct linux_binprm * bprm,
+			   unsigned long stack_top,
+			   int executable_stack);
 extern int copy_strings(int argc,char __user * __user * argv,struct linux_binprm *bprm); 
 extern int copy_strings_kernel(int argc,char ** argv,struct linux_binprm *bprm);
 extern void compute_creds(struct linux_binprm *binprm);
diff -Nru a/include/linux/bitops.h b/include/linux/bitops.h
--- a/include/linux/bitops.h	2005-03-01 23:39:17 -08:00
+++ b/include/linux/bitops.h	2005-03-01 23:39:17 -08:00
@@ -1,7 +1,6 @@
 #ifndef _LINUX_BITOPS_H
 #define _LINUX_BITOPS_H
 #include <asm/types.h>
-#include <asm/bitops.h>
 
 /*
  * ffs: find first bit set. This is defined the same way as
@@ -70,6 +69,12 @@
 	}
 	return r;
 }
+
+/*
+ * Include this here because some architectures need generic_ffs/fls in
+ * scope
+ */
+#include <asm/bitops.h>
 
 static __inline__ int get_bitmask_order(unsigned int count)
 {
diff -Nru a/include/linux/blk.h b/include/linux/blk.h
--- a/include/linux/blk.h	2005-03-01 23:39:19 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,2 +0,0 @@
-#warning this file is obsolete, please use <linux/blkdev.h> instead
-#include <linux/blkdev.h>
diff -Nru a/include/linux/blkdev.h b/include/linux/blkdev.h
--- a/include/linux/blkdev.h	2005-03-01 23:38:53 -08:00
+++ b/include/linux/blkdev.h	2005-03-01 23:38:53 -08:00
@@ -95,6 +95,7 @@
 
 struct request_list {
 	int count[2];
+	int starved[2];
 	mempool_t *rq_pool;
 	wait_queue_head_t wait[2];
 	wait_queue_head_t drain;
diff -Nru a/include/linux/bootmem.h b/include/linux/bootmem.h
--- a/include/linux/bootmem.h	2005-03-01 23:39:09 -08:00
+++ b/include/linux/bootmem.h	2005-03-01 23:39:09 -08:00
@@ -74,8 +74,23 @@
 					    unsigned long bucketsize,
 					    unsigned long numentries,
 					    int scale,
-					    int consider_highmem,
+					    int flags,
 					    unsigned int *_hash_shift,
-					    unsigned int *_hash_mask);
+					    unsigned int *_hash_mask,
+					    unsigned long limit);
+
+#define HASH_HIGHMEM	0x00000001	/* Consider highmem? */
+#define HASH_EARLY	0x00000002	/* Allocating during early boot? */
+
+/* Only NUMA needs hash distribution.
+ * IA64 is known to have sufficient vmalloc space.
+ */
+#if defined(CONFIG_NUMA) && defined(CONFIG_IA64)
+#define HASHDIST_DEFAULT 1
+#else
+#define HASHDIST_DEFAULT 0
+#endif
+extern int __initdata hashdist;		/* Distribute hashes across NUMA nodes? */
+
 
 #endif /* _LINUX_BOOTMEM_H */
diff -Nru a/include/linux/capability.h b/include/linux/capability.h
--- a/include/linux/capability.h	2005-03-01 23:38:54 -08:00
+++ b/include/linux/capability.h	2005-03-01 23:38:54 -08:00
@@ -284,6 +284,10 @@
 
 #define CAP_LEASE            28
 
+#define CAP_AUDIT_WRITE      29
+
+#define CAP_AUDIT_CONTROL    30
+
 #ifdef __KERNEL__
 /* 
  * Bounding set
diff -Nru a/include/linux/cdrom.h b/include/linux/cdrom.h
--- a/include/linux/cdrom.h	2005-03-01 23:38:51 -08:00
+++ b/include/linux/cdrom.h	2005-03-01 23:38:51 -08:00
@@ -1186,8 +1186,6 @@
 };
 
 extern int cdrom_get_media_event(struct cdrom_device_info *cdi, struct media_event_desc *med);
-extern int cdrom_is_mrw(struct cdrom_device_info *cdi, int *write);
-extern int cdrom_is_random_writable(struct cdrom_device_info *cdi, int *write);
 
 #endif  /* End of kernel only stuff */ 
 
diff -Nru a/include/linux/coda.h b/include/linux/coda.h
--- a/include/linux/coda.h	2005-03-01 23:38:57 -08:00
+++ b/include/linux/coda.h	2005-03-01 23:38:57 -08:00
@@ -761,8 +761,8 @@
 struct ViceIoctl {
         void __user *in;        /* Data to be transferred in */
         void __user *out;       /* Data to be transferred out */
-        short in_size;          /* Size of input buffer <= 2K */
-        short out_size;         /* Maximum size of output buffer, <= 2K */
+        u_short in_size;        /* Size of input buffer <= 2K */
+        u_short out_size;       /* Maximum size of output buffer, <= 2K */
 };
 
 struct PioctlData {
diff -Nru a/include/linux/coda_proc.h b/include/linux/coda_proc.h
--- a/include/linux/coda_proc.h	2005-03-01 23:38:51 -08:00
+++ b/include/linux/coda_proc.h	2005-03-01 23:38:51 -08:00
@@ -72,26 +72,5 @@
 
 /* these global variables hold the actual statistics data */
 extern struct coda_vfs_stats		coda_vfs_stat;
-extern struct coda_cache_inv_stats	coda_cache_inv_stat;
-
-/* reset statistics to 0 */
-void reset_coda_vfs_stats( void );
-void reset_coda_cache_inv_stats( void );
-
-/* like coda_dointvec, these functions are to be registered in the ctl_table
- * data structure for /proc/sys/... files 
- */
-int do_reset_coda_vfs_stats( ctl_table * table, int write, struct file * filp,
-			     void __user * buffer, size_t * lenp, loff_t * ppos );
-int do_reset_coda_cache_inv_stats( ctl_table * table, int write, 
-				   struct file * filp, void __user * buffer, 
-				   size_t * lenp, loff_t * ppos );
-
-/* these functions are called to form the content of /proc/fs/coda/... files */
-int coda_vfs_stats_get_info( char * buffer, char ** start, off_t offset,
-			     int length);
-int coda_cache_inv_stats_get_info( char * buffer, char ** start, off_t offset,
-				   int length);
-
 
 #endif /* _CODA_PROC_H */
diff -Nru a/include/linux/coda_psdev.h b/include/linux/coda_psdev.h
--- a/include/linux/coda_psdev.h	2005-03-01 23:38:57 -08:00
+++ b/include/linux/coda_psdev.h	2005-03-01 23:38:57 -08:00
@@ -49,7 +49,7 @@
 		const char *name, int length, 
 		struct CodaFid *newfid, struct coda_vattr *attrs);
 int venus_create(struct super_block *sb, struct CodaFid *dirfid, 
-		 const char *name, int length, int excl, int mode, dev_t rdev,
+		 const char *name, int length, int excl, int mode,
 		 struct CodaFid *newfid, struct coda_vattr *attrs) ;
 int venus_rmdir(struct super_block *sb, struct CodaFid *dirfid, 
 		const char *name, int length);
diff -Nru a/include/linux/com20020.h b/include/linux/com20020.h
--- a/include/linux/com20020.h	2005-03-01 23:39:07 -08:00
+++ b/include/linux/com20020.h	2005-03-01 23:39:07 -08:00
@@ -34,17 +34,24 @@
 #define ARCNET_TOTAL_SIZE 8
 
 /* various register addresses */
-#define _INTMASK  (ioaddr+0)	/* writable */
-#define _STATUS   (ioaddr+0)	/* readable */
-#define _COMMAND  (ioaddr+1)	/* standard arcnet commands */
-#define _DIAGSTAT (ioaddr+1)	/* diagnostic status register */
-#define _ADDR_HI  (ioaddr+2)	/* control registers for IO-mapped memory */
-#define _ADDR_LO  (ioaddr+3)
-#define _MEMDATA  (ioaddr+4)	/* data port for IO-mapped memory */
-#define _SUBADR   (ioaddr+5)	/* the extended port _XREG refers to */
-#define _CONFIG   (ioaddr+6)	/* configuration register */
-#define _XREG     (ioaddr+7)	/* extra registers (indexed by _CONFIG 
-					or _SUBADR) */
+#ifdef CONFIG_SA1100_CT6001
+#define BUS_ALIGN  2  /* 8 bit device on a 16 bit bus - needs padding */
+#else
+#define BUS_ALIGN  1
+#endif
+
+
+#define _INTMASK  (ioaddr+BUS_ALIGN*0)	/* writable */
+#define _STATUS   (ioaddr+BUS_ALIGN*0)	/* readable */
+#define _COMMAND  (ioaddr+BUS_ALIGN*1)	/* standard arcnet commands */
+#define _DIAGSTAT (ioaddr+BUS_ALIGN*1)	/* diagnostic status register */
+#define _ADDR_HI  (ioaddr+BUS_ALIGN*2)	/* control registers for IO-mapped memory */
+#define _ADDR_LO  (ioaddr+BUS_ALIGN*3)
+#define _MEMDATA  (ioaddr+BUS_ALIGN*4)	/* data port for IO-mapped memory */
+#define _SUBADR   (ioaddr+BUS_ALIGN*5)	/* the extended port _XREG refers to */
+#define _CONFIG   (ioaddr+BUS_ALIGN*6)	/* configuration register */
+#define _XREG     (ioaddr+BUS_ALIGN*7)	/* extra registers (indexed by _CONFIG
+  					or _SUBADR) */
 
 /* in the ADDR_HI register */
 #define RDDATAflag	0x80	/* next access is a read (not a write) */
@@ -99,6 +106,7 @@
                   }
 
 #define ASTATUS()	inb(_STATUS)
+#define ADIAGSTATUS()	inb(_DIAGSTAT)
 #define ACOMMAND(cmd)	outb((cmd),_COMMAND)
 #define AINTMASK(msk)	outb((msk),_INTMASK)
 
diff -Nru a/include/linux/compat.h b/include/linux/compat.h
--- a/include/linux/compat.h	2005-03-01 23:38:57 -08:00
+++ b/include/linux/compat.h	2005-03-01 23:38:57 -08:00
@@ -18,6 +18,8 @@
 #define compat_jiffies_to_clock_t(x)	\
 		(((unsigned long)(x) * COMPAT_USER_HZ) / HZ)
 
+struct rusage;
+
 struct compat_itimerspec { 
 	struct compat_timespec it_interval;
 	struct compat_timespec it_value;
@@ -143,6 +145,8 @@
 		       unsigned long bitmap_size);
 long compat_put_bitmap(compat_ulong_t __user *umask, unsigned long *mask,
 		       unsigned long bitmap_size);
-
+struct compat_siginfo;
+int copy_siginfo_from_user32(siginfo_t *to, struct compat_siginfo __user *from);
+int copy_siginfo_to_user32(struct compat_siginfo __user *to, siginfo_t *from);
 #endif /* CONFIG_COMPAT */
 #endif /* _LINUX_COMPAT_H */
diff -Nru a/include/linux/compat_ioctl.h b/include/linux/compat_ioctl.h
--- a/include/linux/compat_ioctl.h	2005-03-01 23:39:16 -08:00
+++ b/include/linux/compat_ioctl.h	2005-03-01 23:39:16 -08:00
@@ -25,6 +25,8 @@
 COMPATIBLE_IOCTL(TIOCLINUX)
 COMPATIBLE_IOCTL(TIOCSBRK)
 COMPATIBLE_IOCTL(TIOCCBRK)
+ULONG_IOCTL(TIOCMIWAIT)
+COMPATIBLE_IOCTL(TIOCGICOUNT)
 /* Little t */
 COMPATIBLE_IOCTL(TIOCGETD)
 COMPATIBLE_IOCTL(TIOCSETD)
diff -Nru a/include/linux/completion.h b/include/linux/completion.h
--- a/include/linux/completion.h	2005-03-01 23:39:07 -08:00
+++ b/include/linux/completion.h	2005-03-01 23:39:07 -08:00
@@ -28,6 +28,12 @@
 }
 
 extern void FASTCALL(wait_for_completion(struct completion *));
+extern int FASTCALL(wait_for_completion_interruptible(struct completion *x));
+extern unsigned long FASTCALL(wait_for_completion_timeout(struct completion *x,
+						   unsigned long timeout));
+extern unsigned long FASTCALL(wait_for_completion_interruptible_timeout(
+			struct completion *x, unsigned long timeout));
+
 extern void FASTCALL(complete(struct completion *));
 extern void FASTCALL(complete_all(struct completion *));
 
diff -Nru a/include/linux/console.h b/include/linux/console.h
--- a/include/linux/console.h	2005-03-01 23:38:56 -08:00
+++ b/include/linux/console.h	2005-03-01 23:38:56 -08:00
@@ -105,6 +105,7 @@
 extern int unregister_console(struct console *);
 extern struct console *console_drivers;
 extern void acquire_console_sem(void);
+extern int try_acquire_console_sem(void);
 extern void release_console_sem(void);
 extern void console_conditional_schedule(void);
 extern void console_unblank(void);
diff -Nru a/include/linux/console_struct.h b/include/linux/console_struct.h
--- a/include/linux/console_struct.h	2005-03-01 23:38:44 -08:00
+++ b/include/linux/console_struct.h	2005-03-01 23:38:44 -08:00
@@ -9,6 +9,8 @@
  * to achieve effects such as fast scrolling by changing the origin.
  */
 
+struct vt_struct;
+
 #define NPAR 16
 
 struct vc_data {
@@ -87,6 +89,7 @@
 	struct vc_data **vc_display_fg;		/* [!] Ptr to var holding fg console for this display */
 	unsigned long	vc_uni_pagedir;
 	unsigned long	*vc_uni_pagedir_loc;  /* [!] Location of uni_pagedir variable for this console */
+	struct vt_struct *vc_vt;
 	/* additional information is in vt_kern.h */
 };
 
diff -Nru a/include/linux/cpu.h b/include/linux/cpu.h
--- a/include/linux/cpu.h	2005-03-01 23:38:53 -08:00
+++ b/include/linux/cpu.h	2005-03-01 23:38:53 -08:00
@@ -32,6 +32,9 @@
 };
 
 extern int register_cpu(struct cpu *, int, struct node *);
+#ifdef CONFIG_HOTPLUG_CPU
+extern void unregister_cpu(struct cpu *, struct node *);
+#endif
 struct notifier_block;
 
 #ifdef CONFIG_SMP
diff -Nru a/include/linux/cpufreq.h b/include/linux/cpufreq.h
--- a/include/linux/cpufreq.h	2005-03-01 23:38:59 -08:00
+++ b/include/linux/cpufreq.h	2005-03-01 23:38:59 -08:00
@@ -252,65 +252,6 @@
 /* query the current CPU frequency (in kHz). If zero, cpufreq couldn't detect it */
 unsigned int cpufreq_get(unsigned int cpu);
 
-/* the proc_intf.c needs this */
-int cpufreq_parse_governor (char *str_governor, unsigned int *policy, struct cpufreq_governor **governor);
-
-
-/*********************************************************************
- *                      CPUFREQ USERSPACE GOVERNOR                   *
- *********************************************************************/
-#ifdef CONFIG_CPU_FREQ_24_API
-
-int __deprecated cpufreq_setmax(unsigned int cpu);
-int __deprecated cpufreq_set(unsigned int kHz, unsigned int cpu);
-
-
-/* /proc/sys/cpu */
-enum {
-	CPU_NR   = 1,           /* compatibilty reasons */
-	CPU_NR_0 = 1,
-	CPU_NR_1 = 2,
-	CPU_NR_2 = 3,
-	CPU_NR_3 = 4,
-	CPU_NR_4 = 5,
-	CPU_NR_5 = 6,
-	CPU_NR_6 = 7,
-	CPU_NR_7 = 8,
-	CPU_NR_8 = 9,
-	CPU_NR_9 = 10,
-	CPU_NR_10 = 11,
-	CPU_NR_11 = 12,
-	CPU_NR_12 = 13,
-	CPU_NR_13 = 14,
-	CPU_NR_14 = 15,
-	CPU_NR_15 = 16,
-	CPU_NR_16 = 17,
-	CPU_NR_17 = 18,
-	CPU_NR_18 = 19,
-	CPU_NR_19 = 20,
-	CPU_NR_20 = 21,
-	CPU_NR_21 = 22,
-	CPU_NR_22 = 23,
-	CPU_NR_23 = 24,
-	CPU_NR_24 = 25,
-	CPU_NR_25 = 26,
-	CPU_NR_26 = 27,
-	CPU_NR_27 = 28,
-	CPU_NR_28 = 29,
-	CPU_NR_29 = 30,
-	CPU_NR_30 = 31,
-	CPU_NR_31 = 32,
-};
-
-/* /proc/sys/cpu/{0,1,...,(NR_CPUS-1)} */
-enum {
-	CPU_NR_FREQ_MAX = 1,
-	CPU_NR_FREQ_MIN = 2,
-	CPU_NR_FREQ = 3,
-};
-
-#endif /* CONFIG_CPU_FREQ_24_API */
-
 
 /*********************************************************************
  *                       CPUFREQ DEFAULT GOVERNOR                    *
@@ -350,6 +291,11 @@
 				   unsigned int target_freq,
 				   unsigned int relation,
 				   unsigned int *index);
+
+/* the following 3 funtions are for cpufreq core use only */
+struct cpufreq_frequency_table *cpufreq_frequency_get_table(unsigned int cpu);
+struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu);
+void   cpufreq_cpu_put (struct cpufreq_policy *data);
 
 /* the following are really really optional */
 extern struct freq_attr cpufreq_freq_attr_scaling_available_freqs;
diff -Nru a/include/linux/cpumask.h b/include/linux/cpumask.h
--- a/include/linux/cpumask.h	2005-03-01 23:38:55 -08:00
+++ b/include/linux/cpumask.h	2005-03-01 23:38:55 -08:00
@@ -234,29 +234,29 @@
 #if NR_CPUS <= BITS_PER_LONG
 
 #define CPU_MASK_ALL							\
-((cpumask_t) { {							\
+(cpumask_t) { {								\
 	[BITS_TO_LONGS(NR_CPUS)-1] = CPU_MASK_LAST_WORD			\
-} })
+} }
 
 #else
 
 #define CPU_MASK_ALL							\
-((cpumask_t) { {							\
+(cpumask_t) { {								\
 	[0 ... BITS_TO_LONGS(NR_CPUS)-2] = ~0UL,			\
 	[BITS_TO_LONGS(NR_CPUS)-1] = CPU_MASK_LAST_WORD			\
-} })
+} }
 
 #endif
 
 #define CPU_MASK_NONE							\
-((cpumask_t) { {							\
+(cpumask_t) { {								\
 	[0 ... BITS_TO_LONGS(NR_CPUS)-1] =  0UL				\
-} })
+} }
 
 #define CPU_MASK_CPU0							\
-((cpumask_t) { {							\
+(cpumask_t) { {								\
 	[0] =  1UL							\
-} })
+} }
 
 #define cpus_addr(src) ((src).bits)
 
diff -Nru a/include/linux/crypto.h b/include/linux/crypto.h
--- a/include/linux/crypto.h	2005-03-01 23:38:54 -08:00
+++ b/include/linux/crypto.h	2005-03-01 23:38:54 -08:00
@@ -16,6 +16,7 @@
 #ifndef _LINUX_CRYPTO_H
 #define _LINUX_CRYPTO_H
 
+#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
@@ -56,6 +57,9 @@
 #define CRYPTO_UNSPEC			0
 #define CRYPTO_MAX_ALG_NAME		64
 
+#define CRYPTO_DIR_ENCRYPT		1
+#define CRYPTO_DIR_DECRYPT		0
+
 struct scatterlist;
 
 /*
@@ -118,7 +122,14 @@
 /*
  * Algorithm query interface.
  */
+#ifdef CONFIG_CRYPTO
 int crypto_alg_available(const char *name, u32 flags);
+#else
+static inline int crypto_alg_available(const char *name, u32 flags)
+{
+	return 0;
+}
+#endif
 
 /*
  * Transforms: user-instantiated objects which encapsulate algorithms
diff -Nru a/include/linux/dcache.h b/include/linux/dcache.h
--- a/include/linux/dcache.h	2005-03-01 23:39:17 -08:00
+++ b/include/linux/dcache.h	2005-03-01 23:39:17 -08:00
@@ -199,6 +199,7 @@
  * These are the low-level FS interfaces to the dcache..
  */
 extern void d_instantiate(struct dentry *, struct inode *);
+extern struct dentry * d_instantiate_unique(struct dentry *, struct inode *);
 extern void d_delete(struct dentry *);
 
 /* allocate/de-allocate */
@@ -240,6 +241,23 @@
 {
 	d_instantiate(entry, inode);
 	d_rehash(entry);
+}
+
+/**
+ * d_add_unique - add dentry to hash queues without aliasing
+ * @entry: dentry to add
+ * @inode: The inode to attach to this dentry
+ *
+ * This adds the entry to the hash queues and initializes @inode.
+ * The entry was actually filled in earlier during d_alloc().
+ */
+static inline struct dentry *d_add_unique(struct dentry *entry, struct inode *inode)
+{
+	struct dentry *res;
+
+	res = d_instantiate_unique(entry, inode);
+	d_rehash(res != NULL ? res : entry);
+	return res;
 }
 
 /* used for rename() and baskets */
diff -Nru a/include/linux/debugfs.h b/include/linux/debugfs.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/linux/debugfs.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,90 @@
+/*
+ *  debugfs.h - a tiny little debug file system
+ *
+ *  Copyright (C) 2004 Greg Kroah-Hartman <greg@kroah.com>
+ *  Copyright (C) 2004 IBM 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.
+ *
+ *  debugfs is for people to use instead of /proc or /sys.
+ *  See Documentation/DocBook/kernel-api for more details.
+ */
+
+#ifndef _DEBUGFS_H_
+#define _DEBUGFS_H_
+
+#if defined(CONFIG_DEBUG_FS)
+struct dentry *debugfs_create_file(const char *name, mode_t mode,
+				   struct dentry *parent, void *data,
+				   struct file_operations *fops);
+
+struct dentry *debugfs_create_dir(const char *name, struct dentry *parent);
+
+void debugfs_remove(struct dentry *dentry);
+
+struct dentry *debugfs_create_u8(const char *name, mode_t mode,
+				 struct dentry *parent, u8 *value);
+struct dentry *debugfs_create_u16(const char *name, mode_t mode,
+				  struct dentry *parent, u16 *value);
+struct dentry *debugfs_create_u32(const char *name, mode_t mode,
+				  struct dentry *parent, u32 *value);
+struct dentry *debugfs_create_bool(const char *name, mode_t mode,
+				  struct dentry *parent, u32 *value);
+
+#else
+/* 
+ * We do not return NULL from these functions if CONFIG_DEBUG_FS is not enabled
+ * so users have a chance to detect if there was a real error or not.  We don't
+ * want to duplicate the design decision mistakes of procfs and devfs again.
+ */
+
+static inline struct dentry *debugfs_create_file(const char *name, mode_t mode,
+						 struct dentry *parent,
+						 void *data,
+						 struct file_operations *fops)
+{
+	return ERR_PTR(-ENODEV);
+}
+
+static inline struct dentry *debugfs_create_dir(const char *name,
+						struct dentry *parent)
+{
+	return ERR_PTR(-ENODEV);
+}
+
+static inline void debugfs_remove(struct dentry *dentry)
+{ }
+
+static inline struct dentry *debugfs_create_u8(const char *name, mode_t mode,
+					       struct dentry *parent,
+					       u8 *value)
+{
+	return ERR_PTR(-ENODEV);
+}
+
+static inline struct dentry *debugfs_create_u16(const char *name, mode_t mode,
+						struct dentry *parent,
+						u8 *value)
+{
+	return ERR_PTR(-ENODEV);
+}
+
+static inline struct dentry *debugfs_create_u32(const char *name, mode_t mode,
+						struct dentry *parent,
+						u8 *value)
+{
+	return ERR_PTR(-ENODEV);
+}
+
+static inline struct dentry *debugfs_create_bool(const char *name, mode_t mode,
+						 struct dentry *parent,
+						 u8 *value)
+{
+	return ERR_PTR(-ENODEV);
+}
+
+#endif
+
+#endif
diff -Nru a/include/linux/delay.h b/include/linux/delay.h
--- a/include/linux/delay.h	2005-03-01 23:38:54 -08:00
+++ b/include/linux/delay.h	2005-03-01 23:38:54 -08:00
@@ -38,6 +38,7 @@
 #define ndelay(x)	udelay(((x)+999)/1000)
 #endif
 
+void calibrate_delay(void);
 void msleep(unsigned int msecs);
 unsigned long msleep_interruptible(unsigned int msecs);
 
diff -Nru a/include/linux/device-mapper.h b/include/linux/device-mapper.h
--- a/include/linux/device-mapper.h	2005-03-01 23:39:07 -08:00
+++ b/include/linux/device-mapper.h	2005-03-01 23:39:07 -08:00
@@ -52,7 +52,8 @@
 			    struct bio *bio, int error,
 			    union map_info *map_context);
 
-typedef void (*dm_suspend_fn) (struct dm_target *ti);
+typedef void (*dm_presuspend_fn) (struct dm_target *ti);
+typedef void (*dm_postsuspend_fn) (struct dm_target *ti);
 typedef void (*dm_resume_fn) (struct dm_target *ti);
 
 typedef int (*dm_status_fn) (struct dm_target *ti, status_type_t status_type,
@@ -82,7 +83,8 @@
 	dm_dtr_fn dtr;
 	dm_map_fn map;
 	dm_endio_fn end_io;
-	dm_suspend_fn suspend;
+	dm_presuspend_fn presuspend;
+	dm_postsuspend_fn postsuspend;
 	dm_resume_fn resume;
 	dm_status_fn status;
 	dm_message_fn message;
@@ -106,6 +108,7 @@
 	sector_t len;
 
 	/* FIXME: turn this into a mask, and merge with io_restrictions */
+	/* Always a power of 2 */
 	sector_t split_io;
 
 	/*
diff -Nru a/include/linux/device.h b/include/linux/device.h
--- a/include/linux/device.h	2005-03-01 23:39:16 -08:00
+++ b/include/linux/device.h	2005-03-01 23:39:16 -08:00
@@ -61,7 +61,7 @@
 	int		(*match)(struct device * dev, struct device_driver * drv);
 	int		(*hotplug) (struct device *dev, char **envp, 
 				    int num_envp, char *buffer, int buffer_size);
-	int		(*suspend)(struct device * dev, u32 state);
+	int		(*suspend)(struct device * dev, pm_message_t state);
 	int		(*resume)(struct device * dev);
 };
 
@@ -228,7 +228,10 @@
 				    const struct class_device_attribute *);
 extern void class_device_remove_file(struct class_device *, 
 				     const struct class_device_attribute *);
-
+extern int class_device_create_bin_file(struct class_device *,
+					struct bin_attribute *);
+extern void class_device_remove_bin_file(struct class_device *,
+					 struct bin_attribute *);
 
 struct class_interface {
 	struct list_head	node;
@@ -382,6 +385,8 @@
 
 extern struct resource *platform_get_resource(struct platform_device *, unsigned int, unsigned int);
 extern int platform_get_irq(struct platform_device *, unsigned int);
+extern struct resource *platform_get_resource_byname(struct platform_device *, unsigned int, char *);
+extern int platform_get_irq_byname(struct platform_device *, char *);
 extern int platform_add_devices(struct platform_device **, int);
 
 extern struct platform_device *platform_device_register_simple(char *, unsigned int, struct resource *, unsigned int);
diff -Nru a/include/linux/dm-ioctl.h b/include/linux/dm-ioctl.h
--- a/include/linux/dm-ioctl.h	2005-03-01 23:38:44 -08:00
+++ b/include/linux/dm-ioctl.h	2005-03-01 23:38:44 -08:00
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2001 - 2003 Sistina Software (UK) Limited.
- * Copyright (C) 2004 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2004 - 2005 Red Hat, Inc. All rights reserved.
  *
  * This file is released under the LGPL.
  */
@@ -272,9 +272,9 @@
 #define DM_TARGET_MSG	 _IOWR(DM_IOCTL, DM_TARGET_MSG_CMD, struct dm_ioctl)
 
 #define DM_VERSION_MAJOR	4
-#define DM_VERSION_MINOR	3
+#define DM_VERSION_MINOR	4
 #define DM_VERSION_PATCHLEVEL	0
-#define DM_VERSION_EXTRA	"-ioctl (2004-09-30)"
+#define DM_VERSION_EXTRA	"-ioctl (2005-01-12)"
 
 /* Status bits */
 #define DM_READONLY_FLAG	(1 << 0) /* In/Out */
@@ -299,5 +299,10 @@
  * results.
  */
 #define DM_BUFFER_FULL_FLAG	(1 << 8) /* Out */
+
+/*
+ * Set this to improve performance when you aren't going to use open_count
+ */
+#define DM_SKIP_BDGET_FLAG	(1 << 9) /* In */
 
 #endif				/* _LINUX_DM_IOCTL_H */
diff -Nru a/include/linux/dvb/frontend.h b/include/linux/dvb/frontend.h
--- a/include/linux/dvb/frontend.h	2005-03-01 23:38:57 -08:00
+++ b/include/linux/dvb/frontend.h	2005-03-01 23:38:57 -08:00
@@ -158,10 +158,11 @@
         QAM_64,
         QAM_128,
         QAM_256,
-	QAM_AUTO
+	QAM_AUTO,
+	VSB_8,
+	VSB_16
 } fe_modulation_t;
 
-
 typedef enum fe_transmit_mode {
 	TRANSMISSION_MODE_2K,
 	TRANSMISSION_MODE_8K,
@@ -206,6 +207,9 @@
         fe_modulation_t  modulation;  /* modulation type (see above) */
 };
 
+struct dvb_vsb_parameters {
+	fe_modulation_t	modulation;  /* modulation type (see above) */
+};
 
 struct dvb_ofdm_parameters {
         fe_bandwidth_t      bandwidth;
@@ -219,13 +223,14 @@
 
 
 struct dvb_frontend_parameters {
-        __u32 frequency;     /* (absolute) frequency in Hz for QAM/OFDM */
+	__u32 frequency;     /* (absolute) frequency in Hz for QAM/OFDM/ATSC */
                                   /* intermediate frequency in kHz for QPSK */
 	fe_spectral_inversion_t inversion;
 	union {
 		struct dvb_qpsk_parameters qpsk;
 		struct dvb_qam_parameters  qam;
 		struct dvb_ofdm_parameters ofdm;
+		struct dvb_vsb_parameters vsb;
 	} u;
 };
 
diff -Nru a/include/linux/dvb/version.h b/include/linux/dvb/version.h
--- a/include/linux/dvb/version.h	2005-03-01 23:38:51 -08:00
+++ b/include/linux/dvb/version.h	2005-03-01 23:38:51 -08:00
@@ -24,6 +24,7 @@
 #define _DVBVERSION_H_
 
 #define DVB_API_VERSION 3
+#define DVB_API_VERSION_MINOR 1
 
 #endif /*_DVBVERSION_H_*/
 
diff -Nru a/include/linux/edd.h b/include/linux/edd.h
--- a/include/linux/edd.h	2005-03-01 23:38:51 -08:00
+++ b/include/linux/edd.h	2005-03-01 23:38:51 -08:00
@@ -49,6 +49,10 @@
 #define EDD_MBR_SIG_MAX 16        /* max number of signatures to store */
 #define EDD_MBR_SIG_NR_BUF 0x1ea  /* addr of number of MBR signtaures at EDD_MBR_SIG_BUF
 				     in boot_params - treat this as 1 byte  */
+#define EDD_CL_EQUALS   0x3d646465     /* "edd=" */
+#define EDD_CL_OFF      0x666f         /* "of" for off  */
+#define EDD_CL_SKIP     0x6b73         /* "sk" for skipmbr */
+
 #ifndef __ASSEMBLY__
 
 #define EDD_EXT_FIXED_DISK_ACCESS           (1 << 0)
diff -Nru a/include/linux/efi.h b/include/linux/efi.h
--- a/include/linux/efi.h	2005-03-01 23:39:16 -08:00
+++ b/include/linux/efi.h	2005-03-01 23:39:16 -08:00
@@ -289,6 +289,7 @@
 }
 
 extern void efi_init (void);
+extern void *efi_get_pal_addr (void);
 extern void efi_map_pal_code (void);
 extern void efi_map_memmap(void);
 extern void efi_memmap_walk (efi_freemem_callback_t callback, void *arg);
@@ -304,6 +305,27 @@
 extern unsigned long __init efi_get_time(void);
 extern int __init efi_set_rtc_mmss(unsigned long nowtime);
 extern struct efi_memory_map memmap;
+
+/**
+ * efi_range_is_wc - check the WC bit on an address range
+ * @start: starting kvirt address
+ * @len: length of range
+ *
+ * Consult the EFI memory map and make sure it's ok to set this range WC.
+ * Returns true or false.
+ */
+static inline int efi_range_is_wc(unsigned long start, unsigned long len)
+{
+	int i;
+
+	for (i = 0; i < len; i += (1UL << EFI_PAGE_SHIFT)) {
+		unsigned long paddr = __pa(start + i);
+		if (!(efi_mem_attributes(paddr) & EFI_MEMORY_WC))
+			return 0;
+	}
+	/* The range checked out */
+	return 1;
+}
 
 #ifdef CONFIG_EFI_PCDP
 extern int __init efi_setup_pcdp_console(char *);
diff -Nru a/include/linux/efs_vh.h b/include/linux/efs_vh.h
--- a/include/linux/efs_vh.h	2005-03-01 23:38:54 -08:00
+++ b/include/linux/efs_vh.h	2005-03-01 23:38:54 -08:00
@@ -47,23 +47,6 @@
 struct pt_types {
 	int	pt_type;
 	char	*pt_name;
-} sgi_pt_types[] = {
-	{0x00,		"SGI vh"},
-	{0x01,		"SGI trkrepl"},
-	{0x02,		"SGI secrepl"},
-	{0x03,		"SGI raw"},
-	{0x04,		"SGI bsd"},
-	{SGI_SYSV,	"SGI sysv"},
-	{0x06,		"SGI vol"},
-	{SGI_EFS,	"SGI efs"},
-	{0x08,		"SGI lv"},
-	{0x09,		"SGI rlv"},
-	{0x0A,		"SGI xfs"},
-	{0x0B,		"SGI xfslog"},
-	{0x0C,		"SGI xlv"},
-	{0x82,		"Linux swap"},
-	{0x83,		"Linux native"},
-	{0,		NULL}
 };
 
 #endif /* __EFS_VH_H__ */
diff -Nru a/include/linux/elf-fdpic.h b/include/linux/elf-fdpic.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/linux/elf-fdpic.h	2005-03-01 23:39:26 -08:00
@@ -0,0 +1,68 @@
+/* elf-fdpic.h: FDPIC ELF load map
+ *
+ * Copyright (C) 2003 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.
+ */
+
+#ifndef _LINUX_ELF_FDPIC_H
+#define _LINUX_ELF_FDPIC_H
+
+#include <linux/elf.h>
+
+#define PT_GNU_STACK    (PT_LOOS + 0x474e551)
+
+/* segment mappings for ELF FDPIC libraries/executables/interpreters */
+struct elf32_fdpic_loadseg {
+	Elf32_Addr	addr;		/* core address to which mapped */
+	Elf32_Addr	p_vaddr;	/* VMA recorded in file */
+	Elf32_Word	p_memsz;	/* allocation size recorded in file */
+};
+
+struct elf32_fdpic_loadmap {
+	Elf32_Half	version;	/* version of these structures, just in case... */
+	Elf32_Half	nsegs;		/* number of segments */
+	struct elf32_fdpic_loadseg segs[];
+};
+
+#define ELF32_FDPIC_LOADMAP_VERSION	0x0000
+
+/*
+ * binfmt binary parameters structure
+ */
+struct elf_fdpic_params {
+	struct elfhdr			hdr;		/* ref copy of ELF header */
+	struct elf_phdr			*phdrs;		/* ref copy of PT_PHDR table */
+	struct elf32_fdpic_loadmap	*loadmap;	/* loadmap to be passed to userspace */
+	unsigned long			elfhdr_addr;	/* mapped ELF header user address */
+	unsigned long			ph_addr;	/* mapped PT_PHDR user address */
+	unsigned long			map_addr;	/* mapped loadmap user address */
+	unsigned long			entry_addr;	/* mapped entry user address */
+	unsigned long			stack_size;	/* stack size requested (PT_GNU_STACK) */
+	unsigned long			dynamic_addr;	/* mapped PT_DYNAMIC user address */
+	unsigned long			load_addr;	/* user address at which to map binary */
+	unsigned long			flags;
+#define ELF_FDPIC_FLAG_ARRANGEMENT	0x0000000f	/* PT_LOAD arrangement flags */
+#define ELF_FDPIC_FLAG_INDEPENDENT	0x00000000	/* PT_LOADs can be put anywhere */
+#define ELF_FDPIC_FLAG_HONOURVADDR	0x00000001	/* PT_LOAD.vaddr must be honoured */
+#define ELF_FDPIC_FLAG_CONSTDISP	0x00000002	/* PT_LOADs require constant
+							 * displacement */
+#define ELF_FDPIC_FLAG_CONTIGUOUS	0x00000003	/* PT_LOADs should be contiguous */
+#define ELF_FDPIC_FLAG_EXEC_STACK	0x00000010	/* T if stack to be executable */
+#define ELF_FDPIC_FLAG_NOEXEC_STACK	0x00000020	/* T if stack not to be executable */
+#define ELF_FDPIC_FLAG_EXECUTABLE	0x00000040	/* T if this object is the executable */
+#define ELF_FDPIC_FLAG_PRESENT		0x80000000	/* T if this object is present */
+};
+
+#ifdef CONFIG_MMU
+extern void elf_fdpic_arch_lay_out_mm(struct elf_fdpic_params *exec_params,
+				      struct elf_fdpic_params *interp_params,
+				      unsigned long *start_stack,
+				      unsigned long *start_brk);
+#endif
+
+#endif /* _LINUX_ELF_FDPIC_H */
diff -Nru a/include/linux/elf.h b/include/linux/elf.h
--- a/include/linux/elf.h	2005-03-01 23:38:53 -08:00
+++ b/include/linux/elf.h	2005-03-01 23:38:53 -08:00
@@ -36,8 +36,9 @@
 #define PT_NOTE    4
 #define PT_SHLIB   5
 #define PT_PHDR    6
-#define PT_LOOS	   0x60000000
-#define PT_HIOS	   0x6fffffff
+#define PT_TLS     7               /* Thread local storage segment */
+#define PT_LOOS    0x60000000      /* OS-specific */
+#define PT_HIOS    0x6fffffff      /* OS-specific */
 #define PT_LOPROC  0x70000000
 #define PT_HIPROC  0x7fffffff
 #define PT_GNU_EH_FRAME		0x6474e550
@@ -108,6 +109,8 @@
  * This is the old interim value for S/390 architecture
  */
 #define EM_S390_OLD     0xA390
+
+#define EM_FRV		0x5441		/* Fujitsu FR-V */
 
 /* This is the info that is needed to parse the dynamic section of the file */
 #define DT_NULL		0
diff -Nru a/include/linux/etherdevice.h b/include/linux/etherdevice.h
--- a/include/linux/etherdevice.h	2005-03-01 23:39:09 -08:00
+++ b/include/linux/etherdevice.h	2005-03-01 23:39:09 -08:00
@@ -37,8 +37,6 @@
 						unsigned char * haddr);
 extern int		eth_header_cache(struct neighbour *neigh,
 					 struct hh_cache *hh);
-extern int		eth_header_parse(struct sk_buff *skb,
-					 unsigned char *haddr);
 
 extern struct net_device *alloc_etherdev(int sizeof_priv);
 static inline void eth_copy_and_sum (struct sk_buff *dest, 
diff -Nru a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h
--- a/include/linux/ext3_fs.h	2005-03-01 23:38:58 -08:00
+++ b/include/linux/ext3_fs.h	2005-03-01 23:38:58 -08:00
@@ -195,7 +195,7 @@
  */
 #define EXT3_STATE_JDATA		0x00000001 /* journaled data exists */
 #define EXT3_STATE_NEW			0x00000002 /* inode is newly created */
-
+#define EXT3_STATE_XATTR		0x00000004 /* has in-inode xattrs */
 
 /* Used to pass group descriptor data when online resize is done */
 struct ext3_new_group_input {
@@ -293,6 +293,8 @@
 			__u32	m_i_reserved2[2];
 		} masix2;
 	} osd2;				/* OS dependent 2 */
+	__le16	i_extra_isize;
+	__le16	i_pad1;
 };
 
 #define i_size_high	i_dir_acl
@@ -758,12 +760,12 @@
 extern void ext3_read_inode (struct inode *);
 extern int  ext3_write_inode (struct inode *, int);
 extern int  ext3_setattr (struct dentry *, struct iattr *);
-extern void ext3_put_inode (struct inode *);
 extern void ext3_delete_inode (struct inode *);
 extern int  ext3_sync_inode (handle_t *, struct inode *);
 extern void ext3_discard_reservation (struct inode *);
 extern void ext3_dirty_inode(struct inode *);
 extern int ext3_change_inode_journal_flag(struct inode *, int);
+extern int ext3_get_inode_loc(struct inode *, struct ext3_iloc *);
 extern void ext3_truncate (struct inode *);
 extern void ext3_set_inode_flags(struct inode *);
 extern void ext3_set_aops(struct inode *inode);
@@ -791,25 +793,15 @@
 extern void __ext3_std_error (struct super_block *, const char *, int);
 extern void ext3_abort (struct super_block *, const char *, const char *, ...)
 	__attribute__ ((format (printf, 3, 4)));
-extern NORET_TYPE void ext3_panic (struct super_block *, const char *,
-				   const char *, ...)
-	__attribute__ ((NORET_AND format (printf, 3, 4)));
 extern void ext3_warning (struct super_block *, const char *, const char *, ...)
 	__attribute__ ((format (printf, 3, 4)));
 extern void ext3_update_dynamic_rev (struct super_block *sb);
-extern void ext3_put_super (struct super_block *);
-extern void ext3_write_super (struct super_block *);
-extern void ext3_write_super_lockfs (struct super_block *);
-extern void ext3_unlockfs (struct super_block *);
-extern int ext3_remount (struct super_block *, int *, char *);
-extern int ext3_statfs (struct super_block *, struct kstatfs *);
 
 #define ext3_std_error(sb, errno)				\
 do {								\
 	if ((errno))						\
 		__ext3_std_error((sb), __FUNCTION__, (errno));	\
 } while (0)
-extern const char *ext3_decode_error(struct super_block *sb, int errno, char nbuf[16]);
 
 /*
  * Inodes and files operations
diff -Nru a/include/linux/ext3_fs_i.h b/include/linux/ext3_fs_i.h
--- a/include/linux/ext3_fs_i.h	2005-03-01 23:38:51 -08:00
+++ b/include/linux/ext3_fs_i.h	2005-03-01 23:38:51 -08:00
@@ -113,6 +113,9 @@
 	 */
 	loff_t	i_disksize;
 
+	/* on-disk additional length */
+	__u16 i_extra_isize;
+
 	/*
 	 * truncate_sem is for serialising ext3_truncate() against
 	 * ext3_getblock().  In the 2.4 ext2 design, great chunks of inode's
diff -Nru a/include/linux/ext3_jbd.h b/include/linux/ext3_jbd.h
--- a/include/linux/ext3_jbd.h	2005-03-01 23:38:52 -08:00
+++ b/include/linux/ext3_jbd.h	2005-03-01 23:38:52 -08:00
@@ -46,8 +46,6 @@
 					 EXT3_XATTR_TRANS_BLOCKS - 2 + \
 					 2*EXT3_QUOTA_TRANS_BLOCKS)
 
-extern int ext3_writepage_trans_blocks(struct inode *inode);
-
 /* 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. */
@@ -138,10 +136,13 @@
 	journal_release_buffer(handle, bh, credits);
 }
 
-static inline void
-ext3_journal_forget(handle_t *handle, struct buffer_head *bh)
+static inline int
+__ext3_journal_forget(const char *where, handle_t *handle, struct buffer_head *bh)
 {
-	journal_forget(handle, bh);
+	int err = journal_forget(handle, bh);
+	if (err)
+		ext3_journal_abort_handle(where, __FUNCTION__, bh, handle,err);
+	return err;
 }
 
 static inline int
@@ -187,6 +188,10 @@
 	__ext3_journal_get_create_access(__FUNCTION__, (handle), (bh))
 #define ext3_journal_dirty_metadata(handle, bh) \
 	__ext3_journal_dirty_metadata(__FUNCTION__, (handle), (bh))
+#define ext3_journal_forget(handle, bh) \
+	__ext3_journal_forget(__FUNCTION__, (handle), (bh))
+
+int ext3_journal_dirty_data(handle_t *handle, struct buffer_head *bh);
 
 handle_t *ext3_journal_start_sb(struct super_block *sb, int nblocks);
 int __ext3_journal_stop(const char *where, handle_t *handle);
diff -Nru a/include/linux/fb.h b/include/linux/fb.h
--- a/include/linux/fb.h	2005-03-01 23:38:54 -08:00
+++ b/include/linux/fb.h	2005-03-01 23:38:54 -08:00
@@ -488,7 +488,8 @@
 #define FB_EVENT_GET_CONSOLE_MAP        0x06
 /*      set console to framebuffer mapping */
 #define FB_EVENT_SET_CONSOLE_MAP        0x07
-
+/*      A display blank is requested       */
+#define FB_EVENT_BLANK                  0x08
 
 struct fb_event {
 	struct fb_info *info;
@@ -583,6 +584,10 @@
 	int (*fb_ioctl)(struct inode *inode, struct file *file, unsigned int cmd,
 			unsigned long arg, struct fb_info *info);
 
+	/* Handle 32bit compat ioctl (optional) */
+	int (*fb_compat_ioctl)(struct file *f, unsigned cmd, unsigned long arg,
+			       struct fb_info *info);
+
 	/* perform fb specific mmap */
 	int (*fb_mmap)(struct fb_info *info, struct file *file, struct vm_area_struct *vma);
 };
@@ -690,7 +695,7 @@
 #define FBINFO_HWACCEL_YPAN		0x2000 /* optional */
 #define FBINFO_HWACCEL_YWRAP		0x4000 /* optional */
 
-#define FBINFO_MISC_MODECHANGEUSER     0x10000 /* mode change request
+#define FBINFO_MISC_USEREVENT          0x10000 /* event request
 						  from userspace */
 #define FBINFO_MISC_MODESWITCH         0x20000 /* mode switch */
 #define FBINFO_MISC_MODESWITCHLATE     0x40000 /* init hardware later */
@@ -857,7 +862,6 @@
 
 /* drivers/video/modedb.c */
 #define VESA_MODEDB_SIZE 34
-extern const struct fb_videomode vesa_modes[];
 extern void fb_var_to_videomode(struct fb_videomode *mode,
 				struct fb_var_screeninfo *var);
 extern void fb_videomode_to_var(struct fb_var_screeninfo *var,
@@ -901,6 +905,8 @@
 	u32 vmode;
 	u32 flag;
 };
+
+extern const struct fb_videomode vesa_modes[];
 
 struct fb_modelist {
 	struct list_head list;
diff -Nru a/include/linux/fcdevice.h b/include/linux/fcdevice.h
--- a/include/linux/fcdevice.h	2005-03-01 23:38:54 -08:00
+++ b/include/linux/fcdevice.h	2005-03-01 23:38:54 -08:00
@@ -27,10 +27,6 @@
 #include <linux/if_fc.h>
 
 #ifdef __KERNEL__
-extern int		fc_header(struct sk_buff *skb, struct net_device *dev,
-				   unsigned short type, void *daddr,
-				   void *saddr, unsigned len);
-extern int		fc_rebuild_header(struct sk_buff *skb);
 extern unsigned short	fc_type_trans(struct sk_buff *skb, struct net_device *dev); 
 
 extern struct net_device *alloc_fcdev(int sizeof_priv);
diff -Nru a/include/linux/fddidevice.h b/include/linux/fddidevice.h
--- a/include/linux/fddidevice.h	2005-03-01 23:38:55 -08:00
+++ b/include/linux/fddidevice.h	2005-03-01 23:38:55 -08:00
@@ -25,13 +25,6 @@
 #include <linux/if_fddi.h>
 
 #ifdef __KERNEL__
-extern int		fddi_header(struct sk_buff *skb,
-				    struct net_device *dev,
-				    unsigned short type,
-				    void *daddr,
-				    void *saddr,
-				    unsigned len);
-extern int		fddi_rebuild_header(struct sk_buff *skb);
 extern unsigned short	fddi_type_trans(struct sk_buff *skb,
 				struct net_device *dev);
 extern struct net_device *alloc_fddidev(int sizeof_priv);
diff -Nru a/include/linux/file.h b/include/linux/file.h
--- a/include/linux/file.h	2005-03-01 23:39:18 -08:00
+++ b/include/linux/file.h	2005-03-01 23:39:18 -08:00
@@ -53,12 +53,12 @@
 extern void filp_dtor(void * objp, struct kmem_cache_s *cachep, unsigned long dflags);
 
 extern struct file ** alloc_fd_array(int);
-extern int expand_fd_array(struct files_struct *, int nr);
 extern void free_fd_array(struct file **, int);
 
 extern fd_set *alloc_fdset(int);
-extern int expand_fdset(struct files_struct *, int nr);
 extern void free_fdset(fd_set *, int);
+
+extern int expand_files(struct files_struct *, int nr);
 
 static inline struct file * fcheck_files(struct files_struct *files, unsigned int fd)
 {
diff -Nru a/include/linux/firmware.h b/include/linux/firmware.h
--- a/include/linux/firmware.h	2005-03-01 23:38:55 -08:00
+++ b/include/linux/firmware.h	2005-03-01 23:38:55 -08:00
@@ -7,6 +7,7 @@
 	size_t size;
 	u8 *data;
 };
+struct device;
 int request_firmware(const struct firmware **fw, const char *name,
 		     struct device *device);
 int request_firmware_nowait(
diff -Nru a/include/linux/fs.h b/include/linux/fs.h
--- a/include/linux/fs.h	2005-03-01 23:38:54 -08:00
+++ b/include/linux/fs.h	2005-03-01 23:38:54 -08:00
@@ -7,26 +7,8 @@
  */
 
 #include <linux/config.h>
-#include <linux/linkage.h>
 #include <linux/limits.h>
-#include <linux/wait.h>
-#include <linux/types.h>
-#include <linux/kdev_t.h>
 #include <linux/ioctl.h>
-#include <linux/dcache.h>
-#include <linux/stat.h>
-#include <linux/cache.h>
-#include <linux/prio_tree.h>
-#include <linux/kobject.h>
-#include <asm/atomic.h>
-
-struct iovec;
-struct nameidata;
-struct pipe_inode_info;
-struct poll_table_struct;
-struct kstatfs;
-struct vm_area_struct;
-struct vfsmount;
 
 /*
  * It's silly to have NR_OPEN bigger than NR_FILE, but you can change
@@ -68,8 +50,6 @@
 #endif
 
 #define NR_FILE  8192	/* this can well be larger on a larger system */
-#define NR_RESERVED_FILES 10 /* reserved for root */
-#define NR_SUPER 256
 
 #define MAY_EXEC 1
 #define MAY_WRITE 2
@@ -123,7 +103,6 @@
 #define MS_REC		16384
 #define MS_VERBOSE	32768
 #define MS_POSIXACL	(1<<16)	/* VFS does not apply the umask */
-#define MS_ONE_SECOND	(1<<17)	/* fs has 1 sec a/m/ctime resolution */
 #define MS_ACTIVE	(1<<30)
 #define MS_NOUSER	(1<<31)
 
@@ -179,7 +158,6 @@
 #define IS_NOATIME(inode)	(__IS_FLG(inode, MS_NOATIME) || ((inode)->i_flags & S_NOATIME))
 #define IS_NODIRATIME(inode)	__IS_FLG(inode, MS_NODIRATIME)
 #define IS_POSIXACL(inode)	__IS_FLG(inode, MS_POSIXACL)
-#define IS_ONE_SECOND(inode)	__IS_FLG(inode, MS_ONE_SECOND)
 
 #define IS_DEADDIR(inode)	((inode)->i_flags & S_DEAD)
 #define IS_NOCMTIME(inode)	((inode)->i_flags & S_NOCMTIME)
@@ -221,13 +199,32 @@
 
 #ifdef __KERNEL__
 
+#include <linux/linkage.h>
+#include <linux/wait.h>
+#include <linux/types.h>
+#include <linux/kdev_t.h>
+#include <linux/dcache.h>
+#include <linux/stat.h>
+#include <linux/cache.h>
+#include <linux/kobject.h>
 #include <linux/list.h>
 #include <linux/radix-tree.h>
+#include <linux/prio_tree.h>
 #include <linux/audit.h>
 #include <linux/init.h>
+
+#include <asm/atomic.h>
 #include <asm/semaphore.h>
 #include <asm/byteorder.h>
 
+struct iovec;
+struct nameidata;
+struct pipe_inode_info;
+struct poll_table_struct;
+struct kstatfs;
+struct vm_area_struct;
+struct vfsmount;
+
 /* Used to be a macro which just called the function, now just a function */
 extern void update_atime (struct inode *);
 
@@ -343,7 +340,7 @@
 	struct prio_tree_root	i_mmap;		/* tree of private and shared mappings */
 	struct list_head	i_mmap_nonlinear;/*list VM_NONLINEAR mappings */
 	spinlock_t		i_mmap_lock;	/* protect tree, count, list */
-	atomic_t		truncate_count;	/* Cover race condition with truncate */
+	unsigned int		truncate_count;	/* Cover race condition with truncate */
 	unsigned long		nrpages;	/* number of total pages */
 	pgoff_t			writeback_index;/* writeback starts here */
 	struct address_space_operations *a_ops;	/* methods */
@@ -429,6 +426,7 @@
 struct inode {
 	struct hlist_node	i_hash;
 	struct list_head	i_list;
+	struct list_head	i_sb_list;
 	struct list_head	i_dentry;
 	unsigned long		i_ino;
 	atomic_t		i_count;
@@ -563,16 +561,17 @@
 struct file_ra_state {
 	unsigned long start;		/* Current window */
 	unsigned long size;
-	unsigned long next_size;	/* Next window size */
+	unsigned long flags;		/* ra flags RA_FLAG_xxx*/
+	unsigned long cache_hit;	/* cache hit count*/
 	unsigned long prev_page;	/* Cache last read() position */
 	unsigned long ahead_start;	/* Ahead window */
 	unsigned long ahead_size;
-	unsigned long currnt_wnd_hit;	/* locality in the current window */
-	unsigned long average;		/* size of next current window */
 	unsigned long ra_pages;		/* Maximum readahead window */
 	unsigned long mmap_hit;		/* Cache hit stat for mmap accesses */
 	unsigned long mmap_miss;	/* Cache miss stat for mmap accesses */
 };
+#define RA_FLAG_MISS 0x01	/* a cache miss occured against this file */
+#define RA_FLAG_INCACHE 0x02	/* file is already in cache */
 
 struct file {
 	struct list_head	f_list;
@@ -588,6 +587,7 @@
 	unsigned int		f_uid, f_gid;
 	struct file_ra_state	f_ra;
 
+	size_t			f_maxcount;
 	unsigned long		f_version;
 	void			*f_security;
 
@@ -776,6 +776,7 @@
 	void                    *s_security;
 	struct xattr_handler	**s_xattr;
 
+	struct list_head	s_inodes;	/* all inodes */
 	struct list_head	s_dirty;	/* dirty inodes */
 	struct list_head	s_io;		/* parked for writeback */
 	struct hlist_head	s_anon;		/* anonymous dentries for (nfs) exporting */
@@ -797,8 +798,14 @@
 	 * even looking at it. You had been warned.
 	 */
 	struct semaphore s_vfs_rename_sem;	/* Kludge */
+
+	/* Granuality of c/m/atime in ns.
+	   Cannot be worse than a second */
+	u32		   s_time_gran;
 };
 
+extern struct timespec current_fs_time(struct super_block *sb);
+
 /*
  * Snapshotting support.
  */
@@ -874,6 +881,7 @@
 	int (*open) (struct inode *, struct file *);
 	int (*release) (struct inode *, struct file *);
 	int (*ioctl) (struct inode *, struct file *, unsigned, unsigned long);
+	long (*compat_ioctl) (struct file *, unsigned, unsigned long);
 	int (*media_changed) (struct gendisk *);
 	int (*revalidate_disk) (struct gendisk *);
 	struct module *owner;
@@ -900,10 +908,16 @@
 
 typedef int (*read_actor_t)(read_descriptor_t *, struct page *, unsigned long, unsigned long);
 
+/* These macros are for out of kernel modules to test that
+ * the kernel supports the unlocked_ioctl and compat_ioctl
+ * fields in struct file_operations. */
+#define HAVE_COMPAT_IOCTL 1
+#define HAVE_UNLOCKED_IOCTL 1
+
 /*
  * NOTE:
- * read, write, poll, fsync, readv, writev can be called
- *   without the big kernel lock held in all filesystems.
+ * read, write, poll, fsync, readv, writev, unlocked_ioctl and compat_ioctl
+ * can be called without the big kernel lock held in all filesystems.
  */
 struct file_operations {
 	struct module *owner;
@@ -915,6 +929,8 @@
 	int (*readdir) (struct file *, void *, filldir_t);
 	unsigned int (*poll) (struct file *, struct poll_table_struct *);
 	int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);
+	long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
+	long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
 	int (*mmap) (struct file *, struct vm_area_struct *);
 	int (*open) (struct inode *, struct file *);
 	int (*flush) (struct file *);
@@ -992,6 +1008,9 @@
 	void (*umount_begin) (struct super_block *);
 
 	int (*show_options)(struct seq_file *, struct vfsmount *);
+
+	ssize_t (*quota_read)(struct super_block *, int, char *, size_t, loff_t);
+	ssize_t (*quota_write)(struct super_block *, int, const char *, size_t, loff_t);
 };
 
 /* Inode state bits.  Protected by inode_lock. */
@@ -1133,6 +1152,10 @@
 
 };
 
+extern struct dentry *
+find_exported_dentry(struct super_block *sb, void *obj, void *parent,
+		     int (*acceptable)(void *context, struct dentry *de),
+		     void *context);
 
 struct file_system_type {
 	const char *name;
@@ -1185,11 +1208,6 @@
 
 extern int vfs_statfs(struct super_block *, struct kstatfs *);
 
-/* Return value for VFS lock functions - tells locks.c to lock conventionally
- * REALLY kosha for root NFS and nfs_lock
- */ 
-#define LOCK_USE_CLNT 1
-
 #define FLOCK_VERIFY_READ  1
 #define FLOCK_VERIFY_WRITE 2
 
@@ -1210,14 +1228,7 @@
 	return 0;
 }
 
-static inline int locks_verify_area(int read_write, struct inode *inode,
-				    struct file *filp, loff_t offset,
-				    size_t count)
-{
-	if (inode->i_flock && MANDATORY_LOCK(inode))
-		return locks_mandatory_area(read_write, inode, filp, offset, count);
-	return 0;
-}
+extern int rw_verify_area(int, struct file *, loff_t *, size_t);
 
 static inline int locks_verify_truncate(struct inode *inode,
 				    struct file *filp,
@@ -1280,6 +1291,7 @@
 extern struct file_operations def_fifo_fops;
 extern int ioctl_by_bdev(struct block_device *, unsigned, unsigned long);
 extern int blkdev_ioctl(struct inode *, struct file *, unsigned, unsigned long);
+extern long compat_blkdev_ioctl(struct file *, unsigned, unsigned long);
 extern int blkdev_get(struct block_device *, mode_t, unsigned);
 extern int blkdev_put(struct block_device *);
 extern int bd_claim(struct block_device *, void *);
@@ -1340,8 +1352,8 @@
 	    S_ISLNK(inode->i_mode))
 		invalidate_inode_pages(inode->i_mapping);
 }
-extern void invalidate_inode_pages2(struct address_space *mapping);
-extern void write_inode_now(struct inode *, int);
+extern int invalidate_inode_pages2(struct address_space *mapping);
+extern int write_inode_now(struct inode *, int);
 extern int filemap_fdatawrite(struct address_space *);
 extern int filemap_flush(struct address_space *);
 extern int filemap_fdatawait(struct address_space *);
@@ -1552,6 +1564,8 @@
 extern int vfs_stat(char __user *, struct kstat *);
 extern int vfs_lstat(char __user *, struct kstat *);
 extern int vfs_fstat(unsigned int, struct kstat *);
+
+extern int vfs_ioctl(struct file *, unsigned int, unsigned int, unsigned long);
 
 extern struct file_system_type *get_fs_type(const char *name);
 extern struct super_block *get_super(struct block_device *);
diff -Nru a/include/linux/fsl_devices.h b/include/linux/fsl_devices.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/linux/fsl_devices.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,78 @@
+/*
+ * include/linux/fsl_devices.h
+ *
+ * Definitions for any platform device related flags or structures for
+ * Freescale processor devices
+ *
+ * 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 _FSL_DEVICE_H_
+#define _FSL_DEVICE_H_
+
+#include <linux/types.h>
+
+/*
+ * Some conventions on how we handle peripherals on Freescale chips
+ *
+ * unique device: a platform_device entry in fsl_plat_devs[] plus
+ * associated device information in its platform_data structure.
+ *
+ * A chip is described by a set of unique devices.
+ *
+ * Each sub-arch has its own master list of unique devices and
+ * enumerates them by enum fsl_devices in a sub-arch specific header
+ *
+ * The platform data structure is broken into two parts.  The
+ * first is device specific information that help identify any
+ * unique features of a peripheral.  The second is any
+ * information that may be defined by the board or how the device
+ * is connected externally of the chip.
+ *
+ * naming conventions:
+ * - platform data structures: <driver>_platform_data
+ * - platform data device flags: FSL_<driver>_DEV_<FLAG>
+ * - platform data board flags: FSL_<driver>_BRD_<FLAG>
+ *
+ */
+
+struct gianfar_platform_data {
+	/* device specific information */
+	u32 device_flags;
+	u32 phy_reg_addr;
+
+	/* board specific information */
+	u32 board_flags;
+	u32 phyid;
+	u32 interruptPHY;
+	u8 mac_addr[6];
+};
+
+/* Flags related to gianfar device features */
+#define FSL_GIANFAR_DEV_HAS_GIGABIT		0x00000001
+#define FSL_GIANFAR_DEV_HAS_COALESCE		0x00000002
+#define FSL_GIANFAR_DEV_HAS_RMON		0x00000004
+#define FSL_GIANFAR_DEV_HAS_MULTI_INTR		0x00000008
+
+/* Flags in gianfar_platform_data */
+#define FSL_GIANFAR_BRD_HAS_PHY_INTR	0x00000001	/* if not set use a timer */
+
+struct fsl_i2c_platform_data {
+	/* device specific information */
+	u32 device_flags;
+};
+
+/* Flags related to I2C device features */
+#define FSL_I2C_DEV_SEPARATE_DFSRR	0x00000001
+#define FSL_I2C_DEV_CLOCK_5200		0x00000002
+
+#endif				/* _FSL_DEVICE_H_ */
+#endif				/* __KERNEL__ */
diff -Nru a/include/linux/generic_serial.h b/include/linux/generic_serial.h
--- a/include/linux/generic_serial.h	2005-03-01 23:39:09 -08:00
+++ b/include/linux/generic_serial.h	2005-03-01 23:39:09 -08:00
@@ -82,7 +82,6 @@
 void gs_stop(struct tty_struct *tty);
 void gs_start(struct tty_struct *tty);
 void gs_hangup(struct tty_struct *tty);
-void gs_do_softint(void *private_);
 int  gs_block_til_ready(void *port, struct file *filp);
 void gs_close(struct tty_struct *tty, struct file *filp);
 void gs_set_termios (struct tty_struct * tty, 
diff -Nru a/include/linux/genhd.h b/include/linux/genhd.h
--- a/include/linux/genhd.h	2005-03-01 23:38:53 -08:00
+++ b/include/linux/genhd.h	2005-03-01 23:38:53 -08:00
@@ -128,6 +128,12 @@
 #endif
 };
 
+/* Structure for sysfs attributes on block devices */
+struct disk_attribute {
+	struct attribute attr;
+	ssize_t (*show)(struct gendisk *, char *);
+};
+
 /* 
  * Macros to operate on percpu disk statistics:
  *
@@ -218,6 +224,7 @@
 extern void disk_round_stats(struct gendisk *disk);
 
 /* drivers/block/genhd.c */
+extern int get_blkdev_list(char *);
 extern void add_disk(struct gendisk *disk);
 extern void del_gendisk(struct gendisk *gp);
 extern void unlink_gendisk(struct gendisk *gp);
diff -Nru a/include/linux/gfp.h b/include/linux/gfp.h
--- a/include/linux/gfp.h	2005-03-01 23:38:54 -08:00
+++ b/include/linux/gfp.h	2005-03-01 23:38:54 -08:00
@@ -37,6 +37,7 @@
 #define __GFP_NORETRY	0x1000	/* Do not retry.  Might fail */
 #define __GFP_NO_GROW	0x2000	/* Slab internal usage */
 #define __GFP_COMP	0x4000	/* Add compound page metadata */
+#define __GFP_ZERO	0x8000	/* Return zeroed page on success */
 
 #define __GFP_BITS_SHIFT 16	/* Room for 16 __GFP_FOO bits */
 #define __GFP_BITS_MASK ((1 << __GFP_BITS_SHIFT) - 1)
diff -Nru a/include/linux/hardirq.h b/include/linux/hardirq.h
--- a/include/linux/hardirq.h	2005-03-01 23:38:55 -08:00
+++ b/include/linux/hardirq.h	2005-03-01 23:38:55 -08:00
@@ -4,6 +4,7 @@
 #include <linux/config.h>
 #include <linux/smp_lock.h>
 #include <asm/hardirq.h>
+#include <asm/system.h>
 
 /*
  * We put the hardirq and softirq counter into the preemption
@@ -61,12 +62,16 @@
 #define in_softirq()		(softirq_count())
 #define in_interrupt()		(irq_count())
 
-#ifdef CONFIG_PREEMPT
+#if defined(CONFIG_PREEMPT) && !defined(CONFIG_PREEMPT_BKL)
 # define in_atomic()	((preempt_count() & ~PREEMPT_ACTIVE) != kernel_locked())
+#else
+# define in_atomic()	((preempt_count() & ~PREEMPT_ACTIVE) != 0)
+#endif
+
+#ifdef CONFIG_PREEMPT
 # define preemptible()	(preempt_count() == 0 && !irqs_disabled())
 # define IRQ_EXIT_OFFSET (HARDIRQ_OFFSET-1)
 #else
-# define in_atomic()	(preempt_count() != 0)
 # define preemptible()	0
 # define IRQ_EXIT_OFFSET HARDIRQ_OFFSET
 #endif
@@ -77,12 +82,25 @@
 # define synchronize_irq(irq)	barrier()
 #endif
 
-#ifdef CONFIG_GENERIC_HARDIRQS
-#define nmi_enter()		(preempt_count() += HARDIRQ_OFFSET)
-#define nmi_exit()		(preempt_count() -= HARDIRQ_OFFSET)
+#define nmi_enter()		irq_enter()
+#define nmi_exit()		sub_preempt_count(HARDIRQ_OFFSET)
 
-#define irq_enter()		(preempt_count() += HARDIRQ_OFFSET)
-extern void irq_exit(void);
+#ifndef CONFIG_VIRT_CPU_ACCOUNTING
+static inline void account_user_vtime(struct task_struct *tsk)
+{
+}
+
+static inline void account_system_vtime(struct task_struct *tsk)
+{
+}
 #endif
+
+#define irq_enter()					\
+	do {						\
+		account_system_vtime(current);		\
+		add_preempt_count(HARDIRQ_OFFSET);	\
+	} while (0)
+
+extern void irq_exit(void);
 
 #endif /* LINUX_HARDIRQ_H */
diff -Nru a/include/linux/highmem.h b/include/linux/highmem.h
--- a/include/linux/highmem.h	2005-03-01 23:39:08 -08:00
+++ b/include/linux/highmem.h	2005-03-01 23:39:08 -08:00
@@ -9,8 +9,6 @@
 
 #ifdef CONFIG_HIGHMEM
 
-extern struct page *highmem_start_page;
-
 #include <asm/highmem.h>
 
 /* declarations for linux/mm/highmem.c */
@@ -43,6 +41,19 @@
 	/* Make sure this page is cleared on other CPU's too before using it */
 	smp_wmb();
 }
+
+#ifndef __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE
+static inline struct page *
+alloc_zeroed_user_highpage(struct vm_area_struct *vma, unsigned long vaddr)
+{
+	struct page *page = alloc_page_vma(GFP_HIGHUSER, vma, vaddr);
+
+	if (page)
+		clear_user_highpage(page, vaddr);
+
+	return page;
+}
+#endif
 
 static inline void clear_highpage(struct page *page)
 {
diff -Nru a/include/linux/hippidevice.h b/include/linux/hippidevice.h
--- a/include/linux/hippidevice.h	2005-03-01 23:39:17 -08:00
+++ b/include/linux/hippidevice.h	2005-03-01 23:39:17 -08:00
@@ -26,29 +26,8 @@
 #include <linux/if_hippi.h>
 
 #ifdef __KERNEL__
-extern int hippi_header(struct sk_buff *skb,
-			struct net_device *dev,
-			unsigned short type,
-			void *daddr,
-			void *saddr,
-			unsigned len);
-
-extern int hippi_rebuild_header(struct sk_buff *skb);
-
 extern unsigned short hippi_type_trans(struct sk_buff *skb,
 				       struct net_device *dev);
-
-extern void hippi_header_cache_bind(struct hh_cache ** hhp,
-				    struct net_device *dev,
-				    unsigned short htype,
-				    __u32 daddr);
-
-extern void hippi_header_cache_update(struct hh_cache *hh,
-				      struct net_device *dev,
-				      unsigned char * haddr);
-extern int hippi_header_parse(struct sk_buff *skb, unsigned char *haddr);
-
-extern void hippi_net_init(void);
 
 extern struct net_device *alloc_hippi_dev(int sizeof_priv);
 #endif
diff -Nru a/include/linux/i2c-algo-sgi.h b/include/linux/i2c-algo-sgi.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/linux/i2c-algo-sgi.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,27 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * Copyright (C) 2003 Ladislav Michl <ladis@linux-mips.org>
+ */
+
+#ifndef I2C_ALGO_SGI_H
+#define I2C_ALGO_SGI_H 1
+
+#include <linux/i2c.h>
+
+struct i2c_algo_sgi_data {
+	void *data;	/* private data for lowlevel routines */
+	unsigned (*getctrl)(void *data);
+	void (*setctrl)(void *data, unsigned val);
+	unsigned (*rdata)(void *data);
+	void (*wdata)(void *data, unsigned val);
+
+	int xfer_timeout;
+	int ack_timeout;
+};
+
+int i2c_sgi_add_bus(struct i2c_adapter *);
+int i2c_sgi_del_bus(struct i2c_adapter *);
+
+#endif /* I2C_ALGO_SGI_H */
diff -Nru a/include/linux/i2c-algo-sibyte.h b/include/linux/i2c-algo-sibyte.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/linux/i2c-algo-sibyte.h	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2001,2002,2003 Broadcom 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 I2C_ALGO_SIBYTE_H
+#define I2C_ALGO_SIBYTE_H 1
+
+#include <linux/i2c.h>
+
+struct i2c_algo_sibyte_data {
+	void *data;		/* private data */
+        int   bus;		/* which bus */
+        void *reg_base;		/* CSR base */
+};
+
+int i2c_sibyte_add_bus(struct i2c_adapter *, int speed);
+int i2c_sibyte_del_bus(struct i2c_adapter *);
+
+#endif /* I2C_ALGO_SIBYTE_H */
diff -Nru a/include/linux/i2c-id.h b/include/linux/i2c-id.h
--- a/include/linux/i2c-id.h	2005-03-01 23:38:52 -08:00
+++ b/include/linux/i2c-id.h	2005-03-01 23:38:52 -08:00
@@ -109,6 +109,7 @@
 #define I2C_DRIVERID_OVCAMCHIP	61	/* OmniVision CMOS image sens.	*/
 #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_EXP0	0xF0	/* experimental use id's	*/
@@ -166,6 +167,7 @@
 #define I2C_DRIVERID_ASB100 1043
 #define I2C_DRIVERID_FSCHER 1046
 #define I2C_DRIVERID_W83L785TS 1047
+#define I2C_DRIVERID_SMSC47B397 1050
 
 /*
  * ---- Adapter types ----------------------------------------------------
@@ -193,9 +195,13 @@
 #define I2C_ALGO_MPC8XX 0x110000	/* MPC8xx PowerPC I2C algorithm */
 #define I2C_ALGO_OCP    0x120000	/* IBM or otherwise On-chip I2C algorithm */
 #define I2C_ALGO_BITHS	0x130000	/* enhanced bit style adapters	*/
-#define I2C_ALGO_OCP_IOP3XX  0x140000	/* XSCALE IOP3XX On-chip I2C alg */
+#define I2C_ALGO_IOP3XX	0x140000	/* XSCALE IOP3XX On-chip I2C alg */
 #define I2C_ALGO_PCA	0x150000	/* PCA 9564 style adapters	*/
 
+#define I2C_ALGO_SIBYTE 0x150000	/* Broadcom SiByte SOCs		*/
+#define I2C_ALGO_SGI	0x160000        /* SGI algorithm                */
+#define I2C_ALGO_AU1550	0x170000        /* Au1550 PSC algorithm		*/
+
 #define I2C_ALGO_EXP	0x800000	/* experimental			*/
 
 #define I2C_ALGO_MASK	0xff0000	/* Mask for algorithms		*/
@@ -234,6 +240,7 @@
 #define I2C_HW_B_IXP4XX 0x17	/* GPIO on IXP4XX systems		*/
 #define I2C_HW_B_S3VIA	0x18	/* S3Via ProSavage adapter		*/
 #define I2C_HW_B_ZR36067 0x19	/* Zoran-36057/36067 based boards	*/
+#define I2C_HW_B_CX2388x 0x1b	/* connexant 2388x based tv cards	*/
 
 /* --- PCF 8584 based algorithms					*/
 #define I2C_HW_P_LP	0x00	/* Parallel port interface		*/
@@ -258,8 +265,18 @@
 /* --- PowerPC on-chip adapters						*/
 #define I2C_HW_OCP 0x00	/* IBM on-chip I2C adapter 	*/
 
+/* --- Broadcom SiByte adapters						*/
+#define I2C_HW_SIBYTE	0x00
+
+/* --- SGI adapters							*/
+#define I2C_HW_SGI_VINO	0x00
+#define I2C_HW_SGI_MACE	0x01
+
 /* --- XSCALE on-chip adapters                          */
-#define I2C_HW_IOP321 0x00
+#define I2C_HW_IOP3XX 0x00
+
+/* --- Au1550 PSC adapters adapters					*/
+#define I2C_HW_AU1550_PSC	0x00
 
 /* --- SMBus only adapters						*/
 #define I2C_HW_SMBUS_PIIX4	0x00
diff -Nru a/include/linux/i2o.h b/include/linux/i2o.h
--- a/include/linux/i2o.h	2005-03-01 23:38:53 -08:00
+++ b/include/linux/i2o.h	2005-03-01 23:38:53 -08:00
@@ -23,7 +23,7 @@
 #include <linux/i2o-dev.h>
 
 /* How many different OSM's are we allowing */
-#define I2O_MAX_DRIVERS		4
+#define I2O_MAX_DRIVERS		8
 
 #include <asm/io.h>
 #include <asm/semaphore.h>	/* Needed for MUTEX init macros */
@@ -631,15 +631,25 @@
 extern int i2o_parm_field_get(struct i2o_device *, int, int, void *, int);
 extern int i2o_parm_table_get(struct i2o_device *, int, int, int, void *, int,
 			      void *, int);
-/* FIXME: remove
-extern int i2o_query_table(int, struct i2o_controller *, int, int, int,
-			   void *, int, void *, int);
-extern int i2o_clear_table(struct i2o_controller *, int, int);
-extern int i2o_row_add_table(struct i2o_controller *, int, int, int,
-			     void *, int);
-extern int i2o_issue_params(int, struct i2o_controller *, int, void *, int,
-			    void *, int);
-*/
+
+/* debugging and troubleshooting/diagnostic helpers. */
+#define osm_printk(level, format, arg...)  \
+	printk(level "%s: " format, OSM_NAME , ## arg)
+
+#ifdef DEBUG
+#define osm_debug(format, arg...) \
+	osm_printk(KERN_DEBUG, format , ## arg)
+#else
+#define osm_debug(format, arg...) \
+        do { } while (0)
+#endif
+
+#define osm_err(format, arg...)		\
+	osm_printk(KERN_ERR, format , ## arg)
+#define osm_info(format, arg...)		\
+	osm_printk(KERN_INFO, format , ## arg)
+#define osm_warn(format, arg...)		\
+	osm_printk(KERN_WARNING, format , ## arg)
 
 /* debugging functions */
 extern void i2o_report_status(const char *, const char *, struct i2o_message *);
diff -Nru a/include/linux/ide.h b/include/linux/ide.h
--- a/include/linux/ide.h	2005-03-01 23:38:55 -08:00
+++ b/include/linux/ide.h	2005-03-01 23:38:55 -08:00
@@ -187,11 +187,7 @@
  * Timeouts for various operations:
  */
 #define WAIT_DRQ	(HZ/10)		/* 100msec - spec allows up to 20ms */
-#if defined(CONFIG_APM) || defined(CONFIG_APM_MODULE)
 #define WAIT_READY	(5*HZ)		/* 5sec - some laptops are very slow */
-#else
-#define WAIT_READY	(HZ/10)		/* 100msec - should be instantaneous */
-#endif /* CONFIG_APM || CONFIG_APM_MODULE */
 #define WAIT_PIDENTIFY	(10*HZ)	/* 10sec  - should be less than 3ms (?), if all ATAPI CD is closed at boot */
 #define WAIT_WORSTCASE	(30*HZ)	/* 30sec  - worst case when spinning up */
 #define WAIT_CMD	(10*HZ)	/* 10sec  - maximum wait for an IRQ to happen */
@@ -721,9 +717,9 @@
 					 *  3=64-bit
 					 */
 	unsigned scsi		: 1;	/* 0=default, 1=ide-scsi emulation */
+	unsigned sleeping	: 1;	/* 1=sleeping & sleep field valid */
 
         u8	quirk_list;	/* considered quirky, set for a specific host */
-        u8	suspend_reset;	/* drive suspend mode flag, soft-reset recovers */
         u8	init_speed;	/* transfer rate set at boot */
         u8	pio_speed;      /* unused by core, used by some drivers for fallback from DMA */
         u8	current_speed;	/* current transfer rate set */
@@ -801,7 +797,7 @@
 	struct pci_dev  *pci_dev;	/* for pci chipsets */
 	struct ide_pci_device_s	*cds;	/* chipset device struct */
 
-	ide_startstop_t (*rw_disk)(ide_drive_t *, struct request *, sector_t);
+	void (*rw_disk)(ide_drive_t *, struct request *);
 
 #if 0
 	ide_hwif_ops_t	*hwifops;
@@ -938,7 +934,9 @@
 		/* BOOL: protects all fields below */
 	volatile int busy;
 		/* BOOL: wake us up on timer expiry */
-	int sleeping;
+	unsigned int sleeping	: 1;
+		/* BOOL: polling active & poll_timeout field valid */
+	unsigned int polling	: 1;
 		/* current drive */
 	ide_drive_t *drive;
 		/* ptr to current hwif in linked-list */
@@ -1097,9 +1095,8 @@
 	int		(*cleanup)(ide_drive_t *);
 	ide_startstop_t	(*do_request)(ide_drive_t *, struct request *, sector_t);
 	int		(*end_request)(ide_drive_t *, int, int);
-	u8		(*sense)(ide_drive_t *, const char *, u8);
-	ide_startstop_t	(*error)(ide_drive_t *, const char *, u8);
-	ide_startstop_t	(*abort)(ide_drive_t *, const char *);
+	ide_startstop_t	(*error)(ide_drive_t *, struct request *rq, u8, u8);
+	ide_startstop_t	(*abort)(ide_drive_t *, struct request *rq);
 	int		(*ioctl)(ide_drive_t *, struct inode *, struct file *, unsigned int, unsigned long);
 	void		(*pre_reset)(ide_drive_t *);
 	sector_t	(*capacity)(ide_drive_t *);
@@ -1147,12 +1144,7 @@
  */
 extern void ide_execute_command(ide_drive_t *, task_ioreg_t cmd, ide_handler_t *, unsigned int, ide_expiry_t *);
 
-/*
- * Error reporting, in human readable form (luxurious, but a memory hog).
- *
- * (drive, msg, status)
- */
-byte ide_dump_status (ide_drive_t *drive, const char *msg, byte stat);
+ide_startstop_t __ide_error(ide_drive_t *, struct request *, u8, u8);
 
 /*
  * ide_error() takes action based on the error returned by the controller.
@@ -1162,6 +1154,8 @@
  */
 ide_startstop_t ide_error (ide_drive_t *drive, const char *msg, byte stat);
 
+ide_startstop_t __ide_abort(ide_drive_t *, struct request *);
+
 /*
  * Abort a running command on the controller triggering the abort
  * from a host side, non error situation
@@ -1192,11 +1186,6 @@
 extern int ide_wait_stat(ide_startstop_t *, ide_drive_t *, u8, u8, unsigned long);
 
 /*
- * Return the current idea about the total capacity of this drive.
- */
-extern sector_t current_capacity (ide_drive_t *drive);
-
-/*
  * Start a reset operation for an IDE interface.
  * The caller should return immediately after invoking this.
  */
@@ -1259,8 +1248,6 @@
  */
 extern void ide_end_drive_cmd(ide_drive_t *, u8, u8);
 
-extern void try_to_flush_leftover_data(ide_drive_t *);
-
 /*
  * Issue ATA command and wait for completion.
  * Use for implementing commands in kernel
@@ -1288,20 +1275,6 @@
 	void			*special;	/* valid_t generally */
 } ide_task_t;
 
-typedef struct pkt_task_s {
-/*
- *	struct hd_drive_task_hdr	pktf;
- *	task_struct_t		pktf;
- *	u8			pkcdb[12];
- */
-	task_ioreg_t		tfRegister[8];
-	int			data_phase;
-	int			command_type;
-	ide_handler_t		*handler;
-	struct request		*rq;		/* copy of request */
-	void			*special;
-} pkt_task_t;
-
 extern u32 ide_read_24(ide_drive_t *);
 
 extern void SELECT_DRIVE(ide_drive_t *);
@@ -1309,11 +1282,6 @@
 extern void SELECT_MASK(ide_drive_t *, int);
 extern void QUIRK_LIST(ide_drive_t *);
 
-extern void ata_input_data(ide_drive_t *, void *, u32);
-extern void ata_output_data(ide_drive_t *, void *, u32);
-extern void atapi_input_bytes(ide_drive_t *, void *, u32);
-extern void atapi_output_bytes(ide_drive_t *, void *, u32);
-
 extern int drive_is_ready(ide_drive_t *);
 extern int wait_for_ready(ide_drive_t *, int /* timeout */);
 
@@ -1350,15 +1318,6 @@
 extern int taskfile_lib_get_identify(ide_drive_t *drive, u8 *);
 
 extern int ide_wait_not_busy(ide_hwif_t *hwif, unsigned long timeout);
-ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq, sector_t block);
-
-/*
- * ide_system_bus_speed() returns what we think is the system VESA/PCI
- * bus speed (in MHz).  This is used for calculating interface PIO timings.
- * The default is 40 for known PCI systems, 50 otherwise.
- * The "idebus=xx" parameter can be used to override this value.
- */
-extern int ide_system_bus_speed(void);
 
 /*
  * ide_stall_queue() can be used by a drive to give excess bandwidth back
@@ -1373,7 +1332,6 @@
 extern void ide_init_subdrivers(void);
 
 extern struct block_device_operations ide_fops[];
-extern ide_proc_entry_t generic_subdriver_entries[];
 
 extern int ata_attach(ide_drive_t *);
 
@@ -1422,7 +1380,7 @@
 
 typedef struct ide_pci_device_s {
 	char			*name;
-	void			(*init_setup)(struct pci_dev *, struct ide_pci_device_s *);
+	int			(*init_setup)(struct pci_dev *, struct ide_pci_device_s *);
 	void			(*init_setup_dma)(struct pci_dev *, struct ide_pci_device_s *, ide_hwif_t *);
 	unsigned int		(*init_chipset)(struct pci_dev *, const char *);
 	void			(*init_iops)(ide_hwif_t *);
@@ -1438,8 +1396,8 @@
 	u8			flags;
 } ide_pci_device_t;
 
-extern void ide_setup_pci_device(struct pci_dev *, ide_pci_device_t *);
-extern void ide_setup_pci_devices(struct pci_dev *, struct pci_dev *, ide_pci_device_t *);
+extern int ide_setup_pci_device(struct pci_dev *, ide_pci_device_t *);
+extern int ide_setup_pci_devices(struct pci_dev *, struct pci_dev *, ide_pci_device_t *);
 
 void ide_map_sg(ide_drive_t *, struct request *);
 void ide_init_sg_cmd(ide_drive_t *, struct request *);
@@ -1453,12 +1411,12 @@
 int ide_use_dma(ide_drive_t *);
 int __ide_dma_off(ide_drive_t *);
 void ide_dma_verbose(ide_drive_t *);
+ide_startstop_t ide_dma_intr(ide_drive_t *);
 
 #ifdef CONFIG_BLK_DEV_IDEDMA_PCI
 extern int ide_build_sglist(ide_drive_t *, struct request *);
 extern int ide_build_dmatable(ide_drive_t *, struct request *);
 extern void ide_destroy_dmatable(ide_drive_t *);
-extern ide_startstop_t ide_dma_intr(ide_drive_t *);
 extern int ide_release_dma(ide_hwif_t *);
 extern void ide_setup_dma(ide_hwif_t *, unsigned long, unsigned int);
 
@@ -1470,7 +1428,6 @@
 extern int ide_dma_setup(ide_drive_t *);
 extern void ide_dma_start(ide_drive_t *);
 extern int __ide_dma_end(ide_drive_t *);
-extern int __ide_dma_test_irq(ide_drive_t *);
 extern int __ide_dma_lostirq(ide_drive_t *);
 extern int __ide_dma_timeout(ide_drive_t *);
 #endif /* CONFIG_BLK_DEV_IDEDMA_PCI */
@@ -1511,7 +1468,8 @@
 extern char *ide_xfer_verbose(u8 xfer_rate);
 extern void ide_toggle_bounce(ide_drive_t *drive, int on);
 extern int ide_set_xfer_rate(ide_drive_t *drive, u8 rate);
-extern byte ide_dump_atapi_status(ide_drive_t *drive, const char *msg, byte stat);
+
+u8 ide_dump_status(ide_drive_t *, const char *, u8);
 
 typedef struct ide_pio_timings_s {
 	int	setup_time;	/* Address setup (ns) minimum */
diff -Nru a/include/linux/if_arcnet.h b/include/linux/if_arcnet.h
--- a/include/linux/if_arcnet.h	2005-03-01 23:38:52 -08:00
+++ b/include/linux/if_arcnet.h	2005-03-01 23:38:52 -08:00
@@ -23,6 +23,9 @@
  *    These are the defined ARCnet Protocol ID's.
  */
 
+/* CAP mode */
+/* No macro but uses 1-8 */
+
 /* RFC1201 Protocol ID's */
 #define ARC_P_IP		212	/* 0xD4 */
 #define ARC_P_IPV6		196	/* 0xC4: RFC2497 */
@@ -86,6 +89,16 @@
 #define ETH_ENCAP_HDR_SIZE 14
 
 
+struct arc_cap
+{
+	uint8_t proto;
+	uint8_t cookie[sizeof(int)];   /* Actually NOT sent over the network */
+	union {
+		uint8_t ack;
+		uint8_t raw[0];		/* 507 bytes */
+	} mes;
+};
+
 /*
  * The data needed by the actual arcnet hardware.
  *
@@ -116,6 +129,7 @@
 	struct arc_rfc1201   rfc1201;
 	struct arc_rfc1051   rfc1051;
 	struct arc_eth_encap eth_encap;
+	struct arc_cap       cap;
 	uint8_t raw[0];		/* 508 bytes				*/
     } soft;
 };
diff -Nru a/include/linux/if_ether.h b/include/linux/if_ether.h
--- a/include/linux/if_ether.h	2005-03-01 23:39:06 -08:00
+++ b/include/linux/if_ether.h	2005-03-01 23:39:06 -08:00
@@ -69,7 +69,7 @@
 #define ETH_P_ATMFATE	0x8884		/* Frame-based ATM Transport
 					 * over Ethernet
 					 */
-#define ETH_P_EDP2	0x88A2		/* Coraid EDP2			*/
+#define ETH_P_AOE	0x88A2		/* ATA over Ethernet		*/
 
 /*
  *	Non DIX types. Won't clash for 1500 types.
@@ -91,6 +91,7 @@
 #define ETH_P_IRDA	0x0017		/* Linux-IrDA			*/
 #define ETH_P_ECONET	0x0018		/* Acorn Econet			*/
 #define ETH_P_HDLC	0x0019		/* HDLC frames			*/
+#define ETH_P_ARCNET	0x001A		/* 1A for ArcNet :-)            */
 
 /*
  *	This is an Ethernet frame header.
diff -Nru a/include/linux/if_infiniband.h b/include/linux/if_infiniband.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/linux/if_infiniband.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,29 @@
+/*
+ * 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 at
+ * <http://www.fsf.org/copyleft/gpl.html>, or the OpenIB.org BSD
+ * license, available in the LICENSE.TXT file accompanying this
+ * software.  These details are also available at
+ * <http://openib.org/license.html>.
+ *
+ * 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.
+ *
+ * Copyright (c) 2004 Topspin Communications.  All rights reserved.
+ *
+ * $Id$
+ */
+
+#ifndef _LINUX_IF_INFINIBAND_H
+#define _LINUX_IF_INFINIBAND_H
+
+#define INFINIBAND_ALEN		20	/* Octets in IPoIB HW addr	*/
+
+#endif /* _LINUX_IF_INFINIBAND_H */
diff -Nru a/include/linux/if_tun.h b/include/linux/if_tun.h
--- a/include/linux/if_tun.h	2005-03-01 23:38:54 -08:00
+++ b/include/linux/if_tun.h	2005-03-01 23:38:54 -08:00
@@ -45,6 +45,11 @@
 
 	struct fasync_struct    *fasync;
 
+	unsigned long if_flags;
+	u8 dev_addr[ETH_ALEN];
+	u32 chr_filter[2];
+	u32 net_filter[2];
+
 #ifdef TUN_DEBUG	
 	int debug;
 #endif  
@@ -53,7 +58,7 @@
 #endif /* __KERNEL__ */
 
 /* Read queue size */
-#define TUN_READQ_SIZE	10
+#define TUN_READQ_SIZE	500
 
 /* TUN device flags */
 #define TUN_TUN_DEV 	0x0001	
diff -Nru a/include/linux/in6.h b/include/linux/in6.h
--- a/include/linux/in6.h	2005-03-01 23:39:06 -08:00
+++ b/include/linux/in6.h	2005-03-01 23:39:06 -08:00
@@ -44,8 +44,10 @@
  * NOTE: Be aware the IN6ADDR_* constants and in6addr_* externals are defined
  * in network byte order, not in host byte order as are the IPv4 equivalents
  */
+#if 0
 extern const struct in6_addr in6addr_any;
 #define IN6ADDR_ANY_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } }
+#endif
 extern const struct in6_addr in6addr_loopback;
 #define IN6ADDR_LOOPBACK_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } }
 
diff -Nru a/include/linux/init.h b/include/linux/init.h
--- a/include/linux/init.h	2005-03-01 23:38:51 -08:00
+++ b/include/linux/init.h	2005-03-01 23:38:51 -08:00
@@ -64,8 +64,8 @@
 typedef int (*initcall_t)(void);
 typedef void (*exitcall_t)(void);
 
-extern initcall_t __con_initcall_start, __con_initcall_end;
-extern initcall_t __security_initcall_start, __security_initcall_end;
+extern initcall_t __con_initcall_start[], __con_initcall_end[];
+extern initcall_t __security_initcall_start[], __security_initcall_end[];
 
 /* Defined in init/main.c */
 extern char saved_command_line[];
diff -Nru a/include/linux/init_task.h b/include/linux/init_task.h
--- a/include/linux/init_task.h	2005-03-01 23:38:52 -08:00
+++ b/include/linux/init_task.h	2005-03-01 23:38:52 -08:00
@@ -46,6 +46,7 @@
 
 #define INIT_SIGNALS(sig) {	\
 	.count		= ATOMIC_INIT(1), 		\
+	.wait_chldexit	= __WAIT_QUEUE_HEAD_INITIALIZER(sig.wait_chldexit),\
 	.shared_pending	= { 				\
 		.list = LIST_HEAD_INIT(sig.shared_pending.list),	\
 		.signal =  {{0}}}, \
@@ -53,10 +54,10 @@
 	.rlim		= INIT_RLIMITS,					\
 }
 
-#define INIT_SIGHAND(sighand) {	\
-	.count		= ATOMIC_INIT(1), 		\
-	.action		= { {{NULL,}}, },		\
-	.siglock	= SPIN_LOCK_UNLOCKED, 		\
+#define INIT_SIGHAND(sighand) {						\
+	.count		= ATOMIC_INIT(1), 				\
+	.action		= { { { .sa_handler = NULL, } }, },		\
+	.siglock	= SPIN_LOCK_UNLOCKED, 				\
 }
 
 extern struct group_info init_groups;
@@ -88,7 +89,6 @@
 	.children	= LIST_HEAD_INIT(tsk.children),			\
 	.sibling	= LIST_HEAD_INIT(tsk.sibling),			\
 	.group_leader	= &tsk,						\
-	.wait_chldexit	= __WAIT_QUEUE_HEAD_INITIALIZER(tsk.wait_chldexit),\
 	.real_timer	= {						\
 		.function	= it_real_fn				\
 	},								\
diff -Nru a/include/linux/input.h b/include/linux/input.h
--- a/include/linux/input.h	2005-03-01 23:38:56 -08:00
+++ b/include/linux/input.h	2005-03-01 23:38:56 -08:00
@@ -504,6 +504,9 @@
 #define REL_X			0x00
 #define REL_Y			0x01
 #define REL_Z			0x02
+#define REL_RX			0x03
+#define REL_RY			0x04
+#define REL_RZ			0x05
 #define REL_HWHEEL		0x06
 #define REL_DIAL		0x07
 #define REL_WHEEL		0x08
@@ -566,6 +569,8 @@
 #define LED_SUSPEND		0x06
 #define LED_MUTE		0x07
 #define LED_MISC		0x08
+#define LED_MAIL		0x09
+#define LED_CHARGING		0x0a
 #define LED_MAX			0x0f
 
 /*
@@ -823,7 +828,6 @@
 	unsigned int repeat_key;
 	struct timer_list timer;
 
-	struct pm_dev *pm_dev;
 	struct pt_regs *regs;
 	int state;
 
diff -Nru a/include/linux/interrupt.h b/include/linux/interrupt.h
--- a/include/linux/interrupt.h	2005-03-01 23:38:58 -08:00
+++ b/include/linux/interrupt.h	2005-03-01 23:38:58 -08:00
@@ -61,18 +61,36 @@
  * Temporary defines for UP kernels, until all code gets fixed.
  */
 #ifndef CONFIG_SMP
-# define cli()			local_irq_disable()
-# define sti()			local_irq_enable()
-# define save_flags(x)		local_save_flags(x)
-# define restore_flags(x)	local_irq_restore(x)
-# define save_and_cli(x)	local_irq_save(x)
-#endif
+static inline void __deprecated cli(void)
+{
+	local_irq_disable();
+}
+static inline void __deprecated sti(void)
+{
+	local_irq_enable();
+}
+static inline void __deprecated save_flags(unsigned long *x)
+{
+	local_save_flags(*x);
+}
+#define save_flags(x) save_flags(&x);
+static inline void __deprecated restore_flags(unsigned long x)
+{
+	local_irq_restore(x);
+}
+
+static inline void __deprecated save_and_cli(unsigned long *x)
+{
+	local_irq_save(*x);
+}
+#define save_and_cli(x)	save_and_cli(&x)
+#endif /* CONFIG_SMP */
 
 /* SoftIRQ primitives.  */
 #define local_bh_disable() \
-		do { preempt_count() += SOFTIRQ_OFFSET; barrier(); } while (0)
+		do { add_preempt_count(SOFTIRQ_OFFSET); barrier(); } while (0)
 #define __local_bh_enable() \
-		do { barrier(); preempt_count() -= SOFTIRQ_OFFSET; } while (0)
+		do { barrier(); sub_preempt_count(SOFTIRQ_OFFSET); } while (0)
 
 extern void local_bh_enable(void);
 
diff -Nru a/include/linux/ip.h b/include/linux/ip.h
--- a/include/linux/ip.h	2005-03-01 23:38:54 -08:00
+++ b/include/linux/ip.h	2005-03-01 23:38:54 -08:00
@@ -107,7 +107,14 @@
 
 #define optlength(opt) (sizeof(struct ip_options) + opt->optlen)
 
-struct inet_opt {
+struct ipv6_pinfo;
+
+struct inet_sock {
+	/* sk and pinet6 has to be the first two members of inet_sock */
+	struct sock		sk;
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+	struct ipv6_pinfo	*pinet6;
+#endif
 	/* Socket demultiplex comparisons on incoming packets. */
 	__u32			daddr;		/* Foreign IPv4 addr */
 	__u32			rcv_saddr;	/* Bound local IPv4 addr */
@@ -146,22 +153,25 @@
 
 #define IPCORK_OPT	1	/* ip-options has been held in ipcork.opt */
 
-struct ipv6_pinfo;
-
-/* WARNING: don't change the layout of the members in inet_sock! */
-struct inet_sock {
-	struct sock	  sk;
-#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-	struct ipv6_pinfo *pinet6;
-#endif
-	struct inet_opt   inet;
-};
-
-static inline struct inet_opt * inet_sk(const struct sock *__sk)
+static inline struct inet_sock *inet_sk(const struct sock *sk)
 {
-	return &((struct inet_sock *)__sk)->inet;
+	return (struct inet_sock *)sk;
 }
 
+static inline void __inet_sk_copy_descendant(struct sock *sk_to,
+					     const struct sock *sk_from,
+					     const int ancestor_size)
+{
+	memcpy(inet_sk(sk_to) + 1, inet_sk(sk_from) + 1,
+	       sk_from->sk_prot->slab_obj_size - ancestor_size);
+}
+#if !(defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE))
+static inline void inet_sk_copy_descendant(struct sock *sk_to,
+					   const struct sock *sk_from)
+{
+	__inet_sk_copy_descendant(sk_to, sk_from, sizeof(struct inet_sock));
+}
+#endif
 #endif
 
 struct iphdr {
diff -Nru a/include/linux/ipmi.h b/include/linux/ipmi.h
--- a/include/linux/ipmi.h	2005-03-01 23:39:18 -08:00
+++ b/include/linux/ipmi.h	2005-03-01 23:39:18 -08:00
@@ -253,7 +253,6 @@
 {
 	msg->done(msg);
 }
-struct ipmi_recv_msg *ipmi_alloc_recv_msg(void);
 
 struct ipmi_user_hndl
 {
@@ -303,32 +302,6 @@
 unsigned char ipmi_get_my_LUN(ipmi_user_t user);
 
 /*
- * Send a command request from the given user.  The address is the
- * proper address for the channel type.  If this is a command, then
- * the message response comes back, the receive handler for this user
- * will be called with the given msgid value in the recv msg.  If this
- * is a response to a command, then the msgid will be used as the
- * sequence number for the response (truncated if necessary), so when
- * sending a response you should use the sequence number you received
- * in the msgid field of the received command.  If the priority is >
- * 0, the message will go into a high-priority queue and be sent
- * first.  Otherwise, it goes into a normal-priority queue.
- * The user_msg_data field will be returned in any response to this
- * message.
- *
- * Note that if you send a response (with the netfn lower bit set),
- * you *will* get back a SEND_MSG response telling you what happened
- * when the response was sent.  You will not get back a response to
- * the message itself.
- */
-int ipmi_request(ipmi_user_t      user,
-		 struct ipmi_addr *addr,
-		 long             msgid,
-		 struct kernel_ipmi_msg *msg,
-		 void             *user_msg_data,
-		 int              priority);
-
-/*
  * Like ipmi_request, but lets you specify the number of retries and
  * the retry time.  The retries is the number of times the message
  * will be resent if no reply is received.  If set to -1, the default
@@ -351,18 +324,6 @@
 			 unsigned int     retry_time_ms);
 
 /*
- * Like ipmi_request, but lets you specify the slave return address.
- */
-int ipmi_request_with_source(ipmi_user_t      user,
-			     struct ipmi_addr *addr,
-			     long             msgid,
-			     struct kernel_ipmi_msg  *msg,
-			     void             *user_msg_data,
-			     int              priority,
-			     unsigned char    source_address,
-			     unsigned char    source_lun);
-
-/*
  * Like ipmi_request, but with messages supplied.  This will not
  * allocate any memory, and the messages may be statically allocated
  * (just make sure to do the "done" handling on them).  Note that this
@@ -381,16 +342,6 @@
 			     int                  priority);
 
 /*
- * Do polling on the IPMI interface the user is attached to.  This
- * causes the IPMI code to do an immediate check for information from
- * the driver and handle anything that is immediately pending.  This
- * will not block in anyway.  This is useful if you need to implement
- * polling from the user like you need to send periodic watchdog pings
- * from a crash dump, or something like that.
- */
-void ipmi_poll_interface(ipmi_user_t user);
-
-/*
  * When commands come in to the SMS, the user can register to receive
  * them.  Only one user can be listening on a specific netfn/cmd pair
  * at a time, you will get an EBUSY error if the command is already
@@ -420,17 +371,6 @@
 int ipmi_set_gets_events(ipmi_user_t user, int val);
 
 /*
- * Register the given user to handle all received IPMI commands.  This
- * will fail if anyone is registered as a command receiver or if
- * another is already registered to receive all commands.  NOTE THAT
- * THIS IS FOR EMULATION USERS ONLY, DO NOT USER THIS FOR NORMAL
- * STUFF.
- */
-int ipmi_register_all_cmd_rcvr(ipmi_user_t user);
-int ipmi_unregister_all_cmd_rcvr(ipmi_user_t user);
-
-
-/*
  * Called when a new SMI is registered.  This will also be called on
  * every existing interface when a new watcher is registered with
  * ipmi_smi_watcher_register().
@@ -462,9 +402,6 @@
 
 /* Validate that the given IPMI address is valid. */
 int ipmi_validate_addr(struct ipmi_addr *addr, int len);
-
-/* Return 1 if the given addresses are equal, 0 if not. */
-int ipmi_addr_equal(struct ipmi_addr *addr1, struct ipmi_addr *addr2);
 
 #endif /* __KERNEL__ */
 
diff -Nru a/include/linux/ipv6.h b/include/linux/ipv6.h
--- a/include/linux/ipv6.h	2005-03-01 23:39:08 -08:00
+++ b/include/linux/ipv6.h	2005-03-01 23:39:08 -08:00
@@ -247,54 +247,67 @@
 	} cork;
 };
 
-struct raw6_opt {
+/* WARNING: don't change the layout of the members in {raw,udp,tcp}6_sock! */
+struct raw6_sock {
+	/* inet_sock has to be the first member of raw6_sock */
+	struct inet_sock	inet;
 	__u32			checksum;	/* perform checksum */
 	__u32			offset;		/* checksum offset  */
-
 	struct icmp6_filter	filter;
-};
-
-/* WARNING: don't change the layout of the members in {raw,udp,tcp}6_sock! */
-struct raw6_sock {
-	struct sock	  sk;
-	struct ipv6_pinfo *pinet6;
-	struct inet_opt   inet;
-	struct raw6_opt   raw6;
-	struct ipv6_pinfo inet6;
+	/* ipv6_pinfo has to be the last member of raw6_sock, see inet6_sk_generic */
+	struct ipv6_pinfo	inet6;
 };
 
 struct udp6_sock {
-	struct sock	  sk;
-	struct ipv6_pinfo *pinet6;
-	struct inet_opt   inet;
-	struct udp_opt	  udp;
+	struct udp_sock	  udp;
+	/* ipv6_pinfo has to be the last member of udp6_sock, see inet6_sk_generic */
 	struct ipv6_pinfo inet6;
 };
 
 struct tcp6_sock {
-	struct sock	  sk;
-	struct ipv6_pinfo *pinet6;
-	struct inet_opt   inet;
-	struct tcp_opt	  tcp;
+	struct tcp_sock	  tcp;
+	/* ipv6_pinfo has to be the last member of tcp6_sock, see inet6_sk_generic */
 	struct ipv6_pinfo inet6;
 };
 
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 static inline struct ipv6_pinfo * inet6_sk(const struct sock *__sk)
 {
-	return ((struct raw6_sock *)__sk)->pinet6;
+	return inet_sk(__sk)->pinet6;
 }
 
-static inline struct raw6_opt * raw6_sk(const struct sock *__sk)
+static inline struct raw6_sock *raw6_sk(const struct sock *sk)
 {
-	return &((struct raw6_sock *)__sk)->raw6;
+	return (struct raw6_sock *)sk;
+}
+
+static inline void inet_sk_copy_descendant(struct sock *sk_to,
+					   const struct sock *sk_from)
+{
+	int ancestor_size = sizeof(struct inet_sock);
+
+	if (sk_from->sk_family == PF_INET6)
+		ancestor_size += sizeof(struct ipv6_pinfo);
+
+	__inet_sk_copy_descendant(sk_to, sk_from, ancestor_size);
 }
 
-#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 #define __ipv6_only_sock(sk)	(inet6_sk(sk)->ipv6only)
 #define ipv6_only_sock(sk)	((sk)->sk_family == PF_INET6 && __ipv6_only_sock(sk))
 #else
 #define __ipv6_only_sock(sk)	0
 #define ipv6_only_sock(sk)	0
+
+static inline struct ipv6_pinfo * inet6_sk(const struct sock *__sk)
+{
+	return NULL;
+}
+
+static inline struct raw6_sock *raw6_sk(const struct sock *sk)
+{
+	return NULL;
+}
+
 #endif
 
 #endif
diff -Nru a/include/linux/irq.h b/include/linux/irq.h
--- a/include/linux/irq.h	2005-03-01 23:39:18 -08:00
+++ b/include/linux/irq.h	2005-03-01 23:39:18 -08:00
@@ -59,9 +59,10 @@
  * Pad this out to 32 bytes for cache and indexing reasons.
  */
 typedef struct irq_desc {
-	unsigned int status;		/* IRQ status */
 	hw_irq_controller *handler;
+	void *handler_data;
 	struct irqaction *action;	/* IRQ action list */
+	unsigned int status;		/* IRQ status */
 	unsigned int depth;		/* nested irq disables */
 	unsigned int irq_count;		/* For detecting broken interrupts */
 	unsigned int irqs_unhandled;
diff -Nru a/include/linux/irq_cpustat.h b/include/linux/irq_cpustat.h
--- a/include/linux/irq_cpustat.h	2005-03-01 23:39:16 -08:00
+++ b/include/linux/irq_cpustat.h	2005-03-01 23:39:16 -08:00
@@ -23,8 +23,8 @@
 #endif
 
   /* arch independent irq_stat fields */
-#define softirq_pending(cpu)	__IRQ_STAT((cpu), __softirq_pending)
-#define local_softirq_pending()	softirq_pending(smp_processor_id())
+#define local_softirq_pending() \
+	__IRQ_STAT(smp_processor_id(), __softirq_pending)
 
   /* arch dependent irq_stat fields */
 #define nmi_count(cpu)		__IRQ_STAT((cpu), __nmi_count)	/* i386 */
diff -Nru a/include/linux/isicom.h b/include/linux/isicom.h
--- a/include/linux/isicom.h	2005-03-01 23:38:55 -08:00
+++ b/include/linux/isicom.h	2005-03-01 23:38:55 -08:00
@@ -125,179 +125,6 @@
 
 #define		ISI_TXOK		0x0001 
  
-struct	isi_board {
-	unsigned short		base;
-	unsigned char		irq;
-	unsigned char		port_count;
-	unsigned short		status;
-	unsigned short		port_status; /* each bit represents a single port */
-	unsigned short		shift_count;
-	struct isi_port		* ports;
-	signed char		count;
-	unsigned char		isa;
-};
-
-struct	isi_port {
-	unsigned short		magic;
-	unsigned int		flags;
-	int			count;
-	int			blocked_open;
-	int			close_delay;
-	unsigned short		channel;
-	unsigned short		status;
-	unsigned short		closing_wait;
-	struct isi_board	* card;
-	struct tty_struct 	* tty;
-	wait_queue_head_t	close_wait;
-	wait_queue_head_t	open_wait;
-	struct work_struct	hangup_tq;
-	struct work_struct	bh_tqueue;
-	unsigned char		* xmit_buf;
-	int			xmit_head;
-	int			xmit_tail;
-	int			xmit_cnt;
-};
-
-
-/*
- *  ISI Card specific ops ...
- */
- 
-static inline void raise_dtr(struct isi_port * port)
-{
-	struct isi_board * card = port->card;
-	unsigned short base = card->base;
-	unsigned char channel = port->channel;
-	short wait=400;
-	while(((inw(base+0x0e) & 0x01) == 0) && (wait-- > 0));
-	if (wait <= 0) {
-		printk(KERN_WARNING "ISICOM: Card found busy in raise_dtr.\n");
-		return;
-	}
-#ifdef ISICOM_DEBUG_DTR_RTS	
-	printk(KERN_DEBUG "ISICOM: raise_dtr.\n");
-#endif	
-	outw(0x8000 | (channel << card->shift_count) | 0x02 , base);
-	outw(0x0504, base);
-	InterruptTheCard(base);
-	port->status |= ISI_DTR;
-}
-
-static inline void drop_dtr(struct isi_port * port)
-{	
-	struct isi_board * card = port->card;
-	unsigned short base = card->base;
-	unsigned char channel = port->channel;
-	short wait=400;
-	while(((inw(base+0x0e) & 0x01) == 0) && (wait-- > 0));
-	if (wait <= 0) {
-		printk(KERN_WARNING "ISICOM: Card found busy in drop_dtr.\n");
-		return;
-	}
-#ifdef ISICOM_DEBUG_DTR_RTS	
-	printk(KERN_DEBUG "ISICOM: drop_dtr.\n");
-#endif	
-	outw(0x8000 | (channel << card->shift_count) | 0x02 , base);
-	outw(0x0404, base);
-	InterruptTheCard(base);	
-	port->status &= ~ISI_DTR;
-}
-static inline void raise_rts(struct isi_port * port)
-{
-	struct isi_board * card = port->card;
-	unsigned short base = card->base;
-	unsigned char channel = port->channel;
-	short wait=400;
-	while(((inw(base+0x0e) & 0x01) == 0) && (wait-- > 0));
-	if (wait <= 0) {
-		printk(KERN_WARNING "ISICOM: Card found busy in raise_rts.\n");
-		return;
-	}
-#ifdef ISICOM_DEBUG_DTR_RTS	
-	printk(KERN_DEBUG "ISICOM: raise_rts.\n");
-#endif	
-	outw(0x8000 | (channel << card->shift_count) | 0x02 , base);
-	outw(0x0a04, base);
-	InterruptTheCard(base);	
-	port->status |= ISI_RTS;
-}
-static inline void drop_rts(struct isi_port * port)
-{
-	struct isi_board * card = port->card;
-	unsigned short base = card->base;
-	unsigned char channel = port->channel;
-	short wait=400;
-	while(((inw(base+0x0e) & 0x01) == 0) && (wait-- > 0));
-	if (wait <= 0) {
-		printk(KERN_WARNING "ISICOM: Card found busy in drop_rts.\n");
-		return;
-	}
-#ifdef ISICOM_DEBUG_DTR_RTS	
-	printk(KERN_DEBUG "ISICOM: drop_rts.\n");
-#endif	
-	outw(0x8000 | (channel << card->shift_count) | 0x02 , base);
-	outw(0x0804, base);
-	InterruptTheCard(base);	
-	port->status &= ~ISI_RTS;
-}
-static inline void raise_dtr_rts(struct isi_port * port)
-{
-	struct isi_board * card = port->card;
-	unsigned short base = card->base;
-	unsigned char channel = port->channel;
-	short wait=400;
-	while(((inw(base+0x0e) & 0x01) == 0) && (wait-- > 0));
-	if (wait <= 0) {
-		printk(KERN_WARNING "ISICOM: Card found busy in raise_dtr_rts.\n");
-		return;
-	}
-#ifdef ISICOM_DEBUG_DTR_RTS	
-	printk(KERN_DEBUG "ISICOM: raise_dtr_rts.\n");
-#endif	
-	outw(0x8000 | (channel << card->shift_count) | 0x02 , base);
-	outw(0x0f04, base);
-	InterruptTheCard(base);
-	port->status |= (ISI_DTR | ISI_RTS);
-}
-static inline void drop_dtr_rts(struct isi_port * port)
-{
-	struct isi_board * card = port->card;
-	unsigned short base = card->base;
-	unsigned char channel = port->channel;
-	short wait=400;
-	while(((inw(base+0x0e) & 0x01) == 0) && (wait-- > 0));
-	if (wait <= 0) {
-		printk(KERN_WARNING "ISICOM: Card found busy in drop_dtr_rts.\n");
-		return;
-	}
-#ifdef ISICOM_DEBUG_DTR_RTS	
-	printk(KERN_DEBUG "ISICOM: drop_dtr_rts.\n");
-#endif	
-	outw(0x8000 | (channel << card->shift_count) | 0x02 , base);
-	outw(0x0c04, base);
-	InterruptTheCard(base);	
-	port->status &= ~(ISI_RTS | ISI_DTR);
-}
-
-static inline void kill_queue(struct isi_port * port, short queue)
-{
-	struct isi_board * card = port->card;
-	unsigned short base = card->base;
-	unsigned char channel = port->channel;
-	short wait=400;
-	while(((inw(base+0x0e) & 0x01) == 0) && (wait-- > 0));
-	if (wait <= 0) {
-		printk(KERN_WARNING "ISICOM: Card found busy in kill_queue.\n");
-		return;
-	}
-#ifdef ISICOM_DEBUG	
-	printk(KERN_DEBUG "ISICOM: kill_queue 0x%x.\n", queue);
-#endif	
-	outw(0x8000 | (channel << card->shift_count) | 0x02 , base);
-	outw((queue << 8) | 0x06, base);
-	InterruptTheCard(base);	
-}
-
 #endif	/*	__KERNEL__	*/
 
 #endif	/*	ISICOM_H	*/
diff -Nru a/include/linux/jbd.h b/include/linux/jbd.h
--- a/include/linux/jbd.h	2005-03-01 23:39:09 -08:00
+++ b/include/linux/jbd.h	2005-03-01 23:39:09 -08:00
@@ -277,13 +277,15 @@
 #define J_EXPECT_JH(jh, expr, why...)	J_ASSERT_JH(jh, expr)
 #else
 #define __journal_expect(expr, why...)					     \
-	do {								     \
-		if (!(expr)) {						     \
+	({								     \
+		int val = (expr);					     \
+		if (!val) {						     \
 			printk(KERN_ERR					     \
 				"EXT3-fs unexpected failure: %s;\n",# expr); \
-			printk(KERN_ERR why);				     \
+			printk(KERN_ERR why "\n");			     \
 		}							     \
-	} while (0)
+		val;							     \
+	})
 #define J_EXPECT(expr, why...)		__journal_expect(expr, ## why)
 #define J_EXPECT_BH(bh, expr, why...)	__journal_expect(expr, ## why)
 #define J_EXPECT_JH(jh, expr, why...)	__journal_expect(expr, ## why)
@@ -874,7 +876,7 @@
 extern int	 journal_dirty_metadata (handle_t *, struct buffer_head *);
 extern void	 journal_release_buffer (handle_t *, struct buffer_head *,
 						int credits);
-extern void	 journal_forget (handle_t *, struct buffer_head *);
+extern int	 journal_forget (handle_t *, struct buffer_head *);
 extern void	 journal_sync_buffer (struct buffer_head *);
 extern int	 journal_invalidatepage(journal_t *,
 				struct page *, unsigned long);
@@ -1059,12 +1061,6 @@
 extern int jbd_blocks_per_page(struct inode *inode);
 
 #ifdef __KERNEL__
-
-#ifdef CONFIG_SMP
-#define assert_spin_locked(lock)	J_ASSERT(spin_is_locked(lock))
-#else
-#define assert_spin_locked(lock)	do {} while(0)
-#endif
 
 #define buffer_trace_init(bh)	do {} while (0)
 #define print_buffer_fields(bh)	do {} while (0)
diff -Nru a/include/linux/jffs2.h b/include/linux/jffs2.h
--- a/include/linux/jffs2.h	2005-03-01 23:39:09 -08:00
+++ b/include/linux/jffs2.h	2005-03-01 23:39:09 -08:00
@@ -3,12 +3,12 @@
  *
  * Copyright (C) 2001-2003 Red Hat, Inc.
  *
- * Created by David Woodhouse <dwmw2@redhat.com>
+ * Created by David Woodhouse <dwmw2@infradead.org>
  *
  * For licensing information, see the file 'LICENCE' in the 
  * jffs2 directory.
  *
- * $Id: jffs2.h,v 1.33 2004/05/25 11:31:55 havasi Exp $
+ * $Id: jffs2.h,v 1.34 2004/11/16 20:36:14 dwmw2 Exp $
  *
  */
 
diff -Nru a/include/linux/jffs2_fs_sb.h b/include/linux/jffs2_fs_sb.h
--- a/include/linux/jffs2_fs_sb.h	2005-03-01 23:38:51 -08:00
+++ b/include/linux/jffs2_fs_sb.h	2005-03-01 23:38:51 -08:00
@@ -1,4 +1,4 @@
-/* $Id: jffs2_fs_sb.h,v 1.45 2003/10/08 11:46:27 dwmw2 Exp $ */
+/* $Id: jffs2_fs_sb.h,v 1.48 2004/11/20 10:41:12 dwmw2 Exp $ */
 
 #ifndef _JFFS2_FS_SB
 #define _JFFS2_FS_SB
@@ -11,6 +11,7 @@
 #include <linux/timer.h>
 #include <linux/wait.h>
 #include <linux/list.h>
+#include <linux/rwsem.h>
 
 #define JFFS2_SB_FLAG_RO 1
 #define JFFS2_SB_FLAG_MOUNTING 2
@@ -35,9 +36,7 @@
 
 	struct semaphore alloc_sem;	/* Used to protect all the following 
 					   fields, and also to protect against
-					   out-of-order writing of nodes.
-					   And GC.
-					*/
+					   out-of-order writing of nodes. And GC. */
 	uint32_t cleanmarker_size;	/* Size of an _inline_ CLEANMARKER
 					 (i.e. zero for OOB CLEANMARKER */
 
@@ -95,13 +94,15 @@
 	   to an obsoleted node. I don't like this. Alternatives welcomed. */
 	struct semaphore erase_free_sem;
 
-#ifdef CONFIG_JFFS2_FS_NAND
+#if defined CONFIG_JFFS2_FS_NAND || defined CONFIG_JFFS2_FS_NOR_ECC
 	/* Write-behind buffer for NAND flash */
 	unsigned char *wbuf;
 	uint32_t wbuf_ofs;
 	uint32_t wbuf_len;
 	uint32_t wbuf_pagesize;
 	struct jffs2_inodirty *wbuf_inodes;
+
+	struct rw_semaphore wbuf_sem;	/* Protects the write buffer */
 
 	/* Information about out-of-band area usage... */
 	struct nand_oobinfo *oobinfo;
diff -Nru a/include/linux/jiffies.h b/include/linux/jiffies.h
--- a/include/linux/jiffies.h	2005-03-01 23:38:51 -08:00
+++ b/include/linux/jiffies.h	2005-03-01 23:38:51 -08:00
@@ -70,13 +70,19 @@
 /* a value TUSEC for TICK_USEC (can be set bij adjtimex)		*/
 #define TICK_USEC_TO_NSEC(TUSEC) (SH_DIV (TUSEC * USER_HZ * 1000, ACTHZ, 8))
 
+/* some arch's have a small-data section that can be accessed register-relative
+ * but that can only take up to, say, 4-byte variables. jiffies being part of
+ * an 8-byte variable may not be correctly accessed unless we force the issue
+ */
+#define __jiffy_data  __attribute__((section(".data")))
+
 /*
  * The 64-bit value is not volatile - you MUST NOT read it
  * without sampling the sequence number in xtime_lock.
  * get_jiffies_64() will do this for you as appropriate.
  */
-extern u64 jiffies_64;
-extern unsigned long volatile jiffies;
+extern u64 __jiffy_data jiffies_64;
+extern unsigned long volatile __jiffy_data jiffies;
 
 #if (BITS_PER_LONG < 64)
 u64 get_jiffies_64(void);
@@ -259,10 +265,10 @@
 
 static inline unsigned int jiffies_to_usecs(const unsigned long j)
 {
-#if HZ <= 1000 && !(1000 % HZ)
+#if HZ <= 1000000 && !(1000000 % HZ)
 	return (1000000 / HZ) * j;
-#elif HZ > 1000 && !(HZ % 1000)
-	return (j*1000 + (HZ - 1000))/(HZ / 1000);
+#elif HZ > 1000000 && !(HZ % 1000000)
+	return (j + (HZ / 1000000) - 1)/(HZ / 1000000);
 #else
 	return (j * 1000000) / HZ;
 #endif
@@ -278,6 +284,19 @@
 	return m * (HZ / 1000);
 #else
 	return (m * HZ + 999) / 1000;
+#endif
+}
+
+static inline unsigned long usecs_to_jiffies(const unsigned int u)
+{
+	if (u > jiffies_to_usecs(MAX_JIFFY_OFFSET))
+		return MAX_JIFFY_OFFSET;
+#if HZ <= 1000000 && !(1000000 % HZ)
+	return (u + (1000000 / HZ) - 1) / (1000000 / HZ);
+#elif HZ > 1000000 && !(HZ % 1000000)
+	return u * (HZ / 1000000);
+#else
+	return (u * HZ + 999999) / 1000000;
 #endif
 }
 
diff -Nru a/include/linux/kernel.h b/include/linux/kernel.h
--- a/include/linux/kernel.h	2005-03-01 23:38:44 -08:00
+++ b/include/linux/kernel.h	2005-03-01 23:38:44 -08:00
@@ -16,6 +16,8 @@
 #include <asm/byteorder.h>
 #include <asm/bug.h>
 
+extern const char linux_banner[];
+
 #define INT_MAX		((int)(~0U>>1))
 #define INT_MIN		(-INT_MAX - 1)
 #define UINT_MAX	(~0U)
@@ -134,6 +136,7 @@
 
 extern void bust_spinlocks(int yes);
 extern int oops_in_progress;		/* If set, an oops, panic(), BUG() or die() is in progress */
+extern int panic_timeout;
 extern int panic_on_oops;
 extern int tainted;
 extern const char *print_tainted(void);
diff -Nru a/include/linux/kernel_stat.h b/include/linux/kernel_stat.h
--- a/include/linux/kernel_stat.h	2005-03-01 23:39:16 -08:00
+++ b/include/linux/kernel_stat.h	2005-03-01 23:39:16 -08:00
@@ -6,6 +6,7 @@
 #include <linux/smp.h>
 #include <linux/threads.h>
 #include <linux/percpu.h>
+#include <asm/cputime.h>
 
 /*
  * 'kernel_stat.h' contains the definitions needed for doing
@@ -14,13 +15,14 @@
  */
 
 struct cpu_usage_stat {
-	u64 user;
-	u64 nice;
-	u64 system;
-	u64 softirq;
-	u64 irq;
-	u64 idle;
-	u64 iowait;
+	cputime64_t user;
+	cputime64_t nice;
+	cputime64_t system;
+	cputime64_t softirq;
+	cputime64_t irq;
+	cputime64_t idle;
+	cputime64_t iowait;
+	cputime64_t steal;
 };
 
 struct kernel_stat {
@@ -49,5 +51,9 @@
 
 	return sum;
 }
+
+extern void account_user_time(struct task_struct *, cputime_t);
+extern void account_system_time(struct task_struct *, int, cputime_t);
+extern void account_steal_time(struct task_struct *, cputime_t);
 
 #endif /* _LINUX_KERNEL_STAT_H */
diff -Nru a/include/linux/kobject.h b/include/linux/kobject.h
--- a/include/linux/kobject.h	2005-03-01 23:38:51 -08:00
+++ b/include/linux/kobject.h	2005-03-01 23:38:51 -08:00
@@ -23,6 +23,7 @@
 #include <linux/rwsem.h>
 #include <linux/kref.h>
 #include <linux/kobject_uevent.h>
+#include <linux/kernel.h>
 #include <asm/atomic.h>
 
 #define KOBJ_NAME_LEN	20
@@ -167,6 +168,8 @@
 	} \
 }
 
+/* The global /sys/kernel/ subsystem for people to chain off of */
+extern struct subsystem kernel_subsys;
 
 /**
  * Helpers for setting the kset of registered objects.
diff -Nru a/include/linux/kprobes.h b/include/linux/kprobes.h
--- a/include/linux/kprobes.h	2005-03-01 23:38:54 -08:00
+++ b/include/linux/kprobes.h	2005-03-01 23:38:54 -08:00
@@ -95,6 +95,7 @@
 }
 
 extern int arch_prepare_kprobe(struct kprobe *p);
+extern void arch_copy_kprobe(struct kprobe *p);
 extern void arch_remove_kprobe(struct kprobe *p);
 extern void show_registers(struct pt_regs *regs);
 
diff -Nru a/include/linux/lcd.h b/include/linux/lcd.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/linux/lcd.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,56 @@
+/*
+ * LCD Lowlevel Control Abstraction
+ *
+ * Copyright (C) 2003,2004 Hewlett-Packard Company
+ *
+ */
+
+#ifndef _LINUX_LCD_H
+#define _LINUX_LCD_H
+
+#include <linux/device.h>
+#include <linux/notifier.h>
+
+struct lcd_device;
+struct fb_info;
+
+/* This structure defines all the properties of a LCD flat panel. */
+struct lcd_properties {
+	/* Owner module */
+	struct module *owner;
+	/* Get the LCD panel power status (0: full on, 1..3: controller
+	   power on, flat panel power off, 4: full off), see FB_BLANK_XXX */
+	int (*get_power)(struct lcd_device *);
+	/* Enable or disable power to the LCD (0: on; 4: off, see FB_BLANK_XXX) */
+	int (*set_power)(struct lcd_device *, int power);
+	/* The maximum value for contrast (read-only) */
+	int max_contrast;
+	/* Get the current contrast setting (0-max_contrast) */
+	int (*get_contrast)(struct lcd_device *);
+	/* Set LCD panel contrast */
+        int (*set_contrast)(struct lcd_device *, int contrast);
+	/* Check if given framebuffer device is the one LCD is bound to;
+	   return 0 if not, !=0 if it is. If NULL, lcd always matches the fb. */
+	int (*check_fb)(struct fb_info *);
+};
+
+struct lcd_device {
+	/* This protects the 'props' field. If 'props' is NULL, the driver that
+	   registered this device has been unloaded, and if class_get_devdata()
+	   points to something in the body of that driver, it is also invalid. */
+	struct semaphore sem;
+	/* If this is NULL, the backing module is unloaded */
+	struct lcd_properties *props;
+	/* The framebuffer notifier block */
+	struct notifier_block fb_notif;
+	/* The class device structure */
+	struct class_device class_dev;
+};
+
+extern struct lcd_device *lcd_device_register(const char *name,
+	void *devdata, struct lcd_properties *lp);
+extern void lcd_device_unregister(struct lcd_device *ld);
+
+#define to_lcd_device(obj) container_of(obj, struct lcd_device, class_dev)
+
+#endif
diff -Nru a/include/linux/libata.h b/include/linux/libata.h
--- a/include/linux/libata.h	2005-03-01 23:38:51 -08:00
+++ b/include/linux/libata.h	2005-03-01 23:38:51 -08:00
@@ -334,11 +334,15 @@
 
 	void (*exec_command)(struct ata_port *ap, struct ata_taskfile *tf);
 	u8   (*check_status)(struct ata_port *ap);
+	u8   (*check_altstatus)(struct ata_port *ap);
+	u8   (*check_err)(struct ata_port *ap);
 	void (*dev_select)(struct ata_port *ap, unsigned int device);
 
 	void (*phy_reset) (struct ata_port *ap);
 	void (*post_set_mode) (struct ata_port *ap);
 
+	int (*check_atapi_dma) (struct ata_queued_cmd *qc);
+
 	void (*bmdma_setup) (struct ata_queued_cmd *qc);
 	void (*bmdma_start) (struct ata_queued_cmd *qc);
 
@@ -358,6 +362,9 @@
 	void (*port_stop) (struct ata_port *ap);
 
 	void (*host_stop) (struct ata_host_set *host_set);
+
+	void (*bmdma_stop) (struct ata_port *ap);
+	u8   (*bmdma_status) (struct ata_port *ap);
 };
 
 struct ata_port_info {
@@ -398,6 +405,8 @@
 extern void ata_noop_dev_select (struct ata_port *ap, unsigned int device);
 extern void ata_std_dev_select (struct ata_port *ap, unsigned int device);
 extern u8 ata_check_status(struct ata_port *ap);
+extern u8 ata_altstatus(struct ata_port *ap);
+extern u8 ata_chk_err(struct ata_port *ap);
 extern void ata_exec_command(struct ata_port *ap, struct ata_taskfile *tf);
 extern int ata_port_start (struct ata_port *ap);
 extern void ata_port_stop (struct ata_port *ap);
@@ -413,6 +422,8 @@
 			      unsigned int ofs, unsigned int len);
 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);
+extern u8   ata_bmdma_status(struct ata_port *ap);
 extern void ata_bmdma_irq_clear(struct ata_port *ap);
 extern void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat);
 extern void ata_eng_timeout(struct ata_port *ap);
@@ -434,8 +445,6 @@
 
 extern struct ata_probe_ent *
 ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port);
-extern struct ata_probe_ent *
-ata_pci_init_legacy_mode(struct pci_dev *pdev, struct ata_port_info **port);
 extern int pci_test_config_bits(struct pci_dev *pdev, struct pci_bits *bits);
 
 #endif /* CONFIG_PCI */
@@ -452,26 +461,11 @@
 		(dev->class == ATA_DEV_ATAPI));
 }
 
-static inline u8 ata_chk_err(struct ata_port *ap)
-{
-	if (ap->flags & ATA_FLAG_MMIO) {
-		return readb((void __iomem *) ap->ioaddr.error_addr);
-	}
-	return inb(ap->ioaddr.error_addr);
-}
-
 static inline u8 ata_chk_status(struct ata_port *ap)
 {
 	return ap->ops->check_status(ap);
 }
 
-static inline u8 ata_altstatus(struct ata_port *ap)
-{
-	if (ap->flags & ATA_FLAG_MMIO)
-		return readb((void __iomem *)ap->ioaddr.altstatus_addr);
-	return inb(ap->ioaddr.altstatus_addr);
-}
-
 static inline void ata_pause(struct ata_port *ap)
 {
 	ata_altstatus(ap);
@@ -593,46 +587,6 @@
 static inline unsigned int sata_dev_present(struct ata_port *ap)
 {
 	return ((scr_read(ap, SCR_STATUS) & 0xf) == 0x3) ? 1 : 0;
-}
-
-static inline void ata_bmdma_stop(struct ata_port *ap)
-{
-	if (ap->flags & ATA_FLAG_MMIO) {
-		void __iomem *mmio = (void __iomem *) ap->ioaddr.bmdma_addr;
-
-		/* clear start/stop bit */
-		writeb(readb(mmio + ATA_DMA_CMD) & ~ATA_DMA_START,
-		      mmio + ATA_DMA_CMD);
-	} else {
-		/* clear start/stop bit */
-		outb(inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD) & ~ATA_DMA_START,
-		    ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
-	}
-
-	/* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */
-	ata_altstatus(ap);	      /* dummy read */
-}
-
-static inline void ata_bmdma_ack_irq(struct ata_port *ap)
-{
-	if (ap->flags & ATA_FLAG_MMIO) {
-		void __iomem *mmio = ((void __iomem *) ap->ioaddr.bmdma_addr) + ATA_DMA_STATUS;
-		writeb(readb(mmio), mmio);
-	} else {
-		unsigned long addr = ap->ioaddr.bmdma_addr + ATA_DMA_STATUS;
-		outb(inb(addr), addr);
-	}
-}
-
-static inline u8 ata_bmdma_status(struct ata_port *ap)
-{
-	u8 host_stat;
-	if (ap->flags & ATA_FLAG_MMIO) {
-		void __iomem *mmio = (void __iomem *) ap->ioaddr.bmdma_addr;
-		host_stat = readb(mmio + ATA_DMA_STATUS);
-	} else
-		host_stat = inb(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
-	return host_stat;
 }
 
 static inline int ata_try_flush_cache(struct ata_device *dev)
diff -Nru a/include/linux/libps2.h b/include/linux/libps2.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/linux/libps2.h	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,50 @@
+#ifndef _LIBPS2_H
+#define _LIBPS2_H
+
+/*
+ * Copyright (C) 1999-2002 Vojtech Pavlik
+ * Copyright (C) 2004 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.
+ */
+
+
+#define PS2_CMD_GETID		0x02f2
+#define PS2_CMD_RESET_BAT	0x02ff
+
+#define PS2_RET_BAT		0xaa
+#define PS2_RET_ID		0x00
+#define PS2_RET_ACK		0xfa
+#define PS2_RET_NAK		0xfe
+
+#define PS2_FLAG_ACK		1	/* Waiting for ACK/NAK */
+#define PS2_FLAG_CMD		2	/* Waiting for command to finish */
+#define PS2_FLAG_CMD1		4	/* Waiting for the first byte of command response */
+#define PS2_FLAG_WAITID		8	/* Command execiting is GET ID */
+
+struct ps2dev {
+	struct serio *serio;
+
+	/* Ensures that only one command is executing at a time */
+	struct semaphore cmd_sem;
+
+	/* Used to signal completion from interrupt handler */
+	wait_queue_head_t wait;
+
+	unsigned long flags;
+	unsigned char cmdbuf[6];
+	unsigned char cmdcnt;
+	unsigned char nak;
+};
+
+void ps2_init(struct ps2dev *ps2dev, struct serio *serio);
+int ps2_sendbyte(struct ps2dev *ps2dev, unsigned char byte, 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);
+int ps2_handle_response(struct ps2dev *ps2dev, unsigned char data);
+void ps2_cmd_aborted(struct ps2dev *ps2dev);
+
+#endif /* _LIBPS2_H */
diff -Nru a/include/linux/list.h b/include/linux/list.h
--- a/include/linux/list.h	2005-03-01 23:38:58 -08:00
+++ b/include/linux/list.h	2005-03-01 23:38:58 -08:00
@@ -326,8 +326,8 @@
  * @head:	the head for your list.
  */
 #define list_for_each(pos, head) \
-	for (pos = (head)->next, prefetch(pos->next); pos != (head); \
-        	pos = pos->next, prefetch(pos->next))
+	for (pos = (head)->next; prefetch(pos->next), pos != (head); \
+        	pos = pos->next)
 
 /**
  * __list_for_each	-	iterate over a list
@@ -348,8 +348,8 @@
  * @head:	the head for your list.
  */
 #define list_for_each_prev(pos, head) \
-	for (pos = (head)->prev, prefetch(pos->prev); pos != (head); \
-        	pos = pos->prev, prefetch(pos->prev))
+	for (pos = (head)->prev; prefetch(pos->prev), pos != (head); \
+        	pos = pos->prev)
 
 /**
  * list_for_each_safe	-	iterate over a list safe against removal of list entry
@@ -368,11 +368,9 @@
  * @member:	the name of the list_struct within the struct.
  */
 #define list_for_each_entry(pos, head, member)				\
-	for (pos = list_entry((head)->next, typeof(*pos), member),	\
-		     prefetch(pos->member.next);			\
-	     &pos->member != (head); 					\
-	     pos = list_entry(pos->member.next, typeof(*pos), member),	\
-		     prefetch(pos->member.next))
+	for (pos = list_entry((head)->next, typeof(*pos), member);	\
+	     prefetch(pos->member.next), &pos->member != (head); 	\
+	     pos = list_entry(pos->member.next, typeof(*pos), member))
 
 /**
  * list_for_each_entry_reverse - iterate backwards over list of given type.
@@ -381,11 +379,9 @@
  * @member:	the name of the list_struct within the struct.
  */
 #define list_for_each_entry_reverse(pos, head, member)			\
-	for (pos = list_entry((head)->prev, typeof(*pos), member),	\
-		     prefetch(pos->member.prev);			\
-	     &pos->member != (head); 					\
-	     pos = list_entry(pos->member.prev, typeof(*pos), member),	\
-		     prefetch(pos->member.prev))
+	for (pos = list_entry((head)->prev, typeof(*pos), member);	\
+	     prefetch(pos->member.prev), &pos->member != (head); 	\
+	     pos = list_entry(pos->member.prev, typeof(*pos), member))
 
 /**
  * list_prepare_entry - prepare a pos entry for use as a start point in
@@ -405,11 +401,9 @@
  * @member:	the name of the list_struct within the struct.
  */
 #define list_for_each_entry_continue(pos, head, member) 		\
-	for (pos = list_entry(pos->member.next, typeof(*pos), member),	\
-		     prefetch(pos->member.next);			\
-	     &pos->member != (head);					\
-	     pos = list_entry(pos->member.next, typeof(*pos), member),	\
-		     prefetch(pos->member.next))
+	for (pos = list_entry(pos->member.next, typeof(*pos), member);	\
+	     prefetch(pos->member.next), &pos->member != (head);	\
+	     pos = list_entry(pos->member.next, typeof(*pos), member))
 
 /**
  * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
@@ -434,8 +428,8 @@
  * as long as the traversal is guarded by rcu_read_lock().
  */
 #define list_for_each_rcu(pos, head) \
-	for (pos = (head)->next, prefetch(pos->next); pos != (head); \
-        	pos = rcu_dereference(pos->next), prefetch(pos->next))
+	for (pos = (head)->next; prefetch(pos->next), pos != (head); \
+        	pos = rcu_dereference(pos->next))
 
 #define __list_for_each_rcu(pos, head) \
 	for (pos = (head)->next; pos != (head); \
@@ -467,12 +461,10 @@
  * as long as the traversal is guarded by rcu_read_lock().
  */
 #define list_for_each_entry_rcu(pos, head, member)			\
-	for (pos = list_entry((head)->next, typeof(*pos), member),	\
-		     prefetch(pos->member.next);			\
-	     &pos->member != (head); 					\
+	for (pos = list_entry((head)->next, typeof(*pos), member);	\
+	     prefetch(pos->member.next), &pos->member != (head); 	\
 	     pos = rcu_dereference(list_entry(pos->member.next, 	\
-					typeof(*pos), member)),		\
-		     prefetch(pos->member.next))
+					typeof(*pos), member)))
 
 
 /**
@@ -486,8 +478,8 @@
  * as long as the traversal is guarded by rcu_read_lock().
  */
 #define list_for_each_continue_rcu(pos, head) \
-	for ((pos) = (pos)->next, prefetch((pos)->next); (pos) != (head); \
-        	(pos) = rcu_dereference((pos)->next), prefetch((pos)->next))
+	for ((pos) = (pos)->next; prefetch((pos)->next), (pos) != (head); \
+        	(pos) = rcu_dereference((pos)->next))
 
 /*
  * Double linked lists with a single pointer list head.
diff -Nru a/include/linux/lp.h b/include/linux/lp.h
--- a/include/linux/lp.h	2005-03-01 23:39:08 -08:00
+++ b/include/linux/lp.h	2005-03-01 23:39:08 -08:00
@@ -186,12 +186,6 @@
  */
 #define LP_DELAY 	50
 
-/*
- * function prototypes
- */
-
-extern int lp_init(void);
-
 #endif
 
 #endif
diff -Nru a/include/linux/mbcache.h b/include/linux/mbcache.h
--- a/include/linux/mbcache.h	2005-03-01 23:39:17 -08:00
+++ b/include/linux/mbcache.h	2005-03-01 23:39:17 -08:00
@@ -7,39 +7,22 @@
 /* Hardwire the number of additional indexes */
 #define MB_CACHE_INDEXES_COUNT 1
 
-struct mb_cache_entry;
-
-struct mb_cache_op {
-	int (*free)(struct mb_cache_entry *, int);
-};
-
-struct mb_cache {
-	struct list_head		c_cache_list;
-	const char			*c_name;
-	struct mb_cache_op		c_op;
-	atomic_t			c_entry_count;
-	int				c_bucket_bits;
-#ifndef MB_CACHE_INDEXES_COUNT
-	int				c_indexes_count;
-#endif
-	kmem_cache_t			*c_entry_cache;
-	struct list_head		*c_block_hash;
-	struct list_head		*c_indexes_hash[0];
-};
-
-struct mb_cache_entry_index {
-	struct list_head		o_list;
-	unsigned int			o_key;
-};
-
 struct mb_cache_entry {
 	struct list_head		e_lru_list;
 	struct mb_cache			*e_cache;
-	atomic_t			e_used;
+	unsigned short			e_used;
+	unsigned short			e_queued;
 	struct block_device		*e_bdev;
 	sector_t			e_block;
 	struct list_head		e_block_list;
-	struct mb_cache_entry_index	e_indexes[0];
+	struct {
+		struct list_head	o_list;
+		unsigned int		o_key;
+	} e_indexes[0];
+};
+
+struct mb_cache_op {
+	int (*free)(struct mb_cache_entry *, int);
 };
 
 /* Functions on caches */
@@ -54,7 +37,6 @@
 struct mb_cache_entry *mb_cache_entry_alloc(struct mb_cache *);
 int mb_cache_entry_insert(struct mb_cache_entry *, struct block_device *,
 			  sector_t, unsigned int[]);
-void mb_cache_entry_rehash(struct mb_cache_entry *, unsigned int[]);
 void mb_cache_entry_release(struct mb_cache_entry *);
 void mb_cache_entry_free(struct mb_cache_entry *);
 struct mb_cache_entry *mb_cache_entry_get(struct mb_cache *,
diff -Nru a/include/linux/mca-legacy.h b/include/linux/mca-legacy.h
--- a/include/linux/mca-legacy.h	2005-03-01 23:39:17 -08:00
+++ b/include/linux/mca-legacy.h	2005-03-01 23:39:17 -08:00
@@ -34,10 +34,6 @@
 extern int mca_find_adapter(int id, int start);
 extern int mca_find_unused_adapter(int id, int start);
 
-/* adapter state info - returns 0 if no */
-extern int mca_isadapter(int slot);
-extern int mca_isenabled(int slot);
-
 extern int mca_is_adapter_used(int slot);
 extern int mca_mark_as_used(int slot);
 extern void mca_mark_as_unused(int slot);
@@ -50,7 +46,6 @@
  * so we can have a more interesting /proc/mca.
  */
 extern void mca_set_adapter_name(int slot, char* name);
-extern char* mca_get_adapter_name(int slot);
 
 /* These routines actually mess with the hardware POS registers.  They
  * temporarily disable the device (and interrupts), so make sure you know
diff -Nru a/include/linux/mca.h b/include/linux/mca.h
--- a/include/linux/mca.h	2005-03-01 23:38:54 -08:00
+++ b/include/linux/mca.h	2005-03-01 23:38:54 -08:00
@@ -6,22 +6,14 @@
 #ifndef _LINUX_MCA_H
 #define _LINUX_MCA_H
 
-/* FIXME: This shouldn't happen, but we need everything that previously
- * included mca.h to compile.  Take it out later when the MCA #includes
- * are sorted out */
 #include <linux/device.h>
 
-/* get the platform specific defines */
 #ifdef CONFIG_MCA
 #include <asm/mca.h>
-#endif
 
-/* The detection of MCA bus is done in the real mode (using BIOS).
- * The information is exported to the protected code, where this
- * variable is set to one in case MCA bus was detected.
- */
-#ifndef MCA_bus__is_a_macro
-extern int  MCA_bus;
+extern int MCA_bus;
+#else
+#define MCA_bus 0
 #endif
 
 /* This sets up an information callback for /proc/mca/slot?.  The
diff -Nru a/include/linux/miscdevice.h b/include/linux/miscdevice.h
--- a/include/linux/miscdevice.h	2005-03-01 23:38:58 -08:00
+++ b/include/linux/miscdevice.h	2005-03-01 23:38:58 -08:00
@@ -31,14 +31,15 @@
 #define	HPET_MINOR	     228
 
 struct device;
+struct class_device;
 
-struct miscdevice 
-{
+struct miscdevice  {
 	int minor;
 	const char *name;
 	struct file_operations *fops;
 	struct list_head list;
 	struct device *dev;
+	struct class_device *class;
 	char devfs_name[64];
 };
 
diff -Nru a/include/linux/mm.h b/include/linux/mm.h
--- a/include/linux/mm.h	2005-03-01 23:38:51 -08:00
+++ b/include/linux/mm.h	2005-03-01 23:38:51 -08:00
@@ -38,7 +38,7 @@
 #include <asm/atomic.h>
 
 #ifndef MM_VM_SIZE
-#define MM_VM_SIZE(mm)	TASK_SIZE
+#define MM_VM_SIZE(mm)	((TASK_SIZE + PGDIR_SIZE - 1) & PGDIR_MASK)
 #endif
 
 #define nth_page(page,n) pfn_to_page(page_to_pfn((page)) + (n))
@@ -85,7 +85,7 @@
 			struct vm_area_struct *head;
 		} vm_set;
 
-		struct prio_tree_node prio_tree_node;
+		struct raw_prio_tree_node prio_tree_node;
 	} shared;
 
 	/*
@@ -105,13 +105,34 @@
 					   units, *not* PAGE_CACHE_SIZE */
 	struct file * vm_file;		/* File we map to (can be NULL). */
 	void * vm_private_data;		/* was vm_pte (shared mem) */
+	unsigned long vm_truncate_count;/* truncate_count or restart_addr */
 
+#ifndef CONFIG_MMU
+	atomic_t vm_usage;		/* refcount (VMAs shared if !MMU) */
+#endif
 #ifdef CONFIG_NUMA
 	struct mempolicy *vm_policy;	/* NUMA policy for the VMA */
 #endif
 };
 
 /*
+ * This struct defines the per-mm list of VMAs for uClinux. If CONFIG_MMU is
+ * disabled, then there's a single shared list of VMAs maintained by the
+ * system, and mm's subscribe to these individually
+ */
+struct vm_list_struct {
+	struct vm_list_struct	*next;
+	struct vm_area_struct	*vma;
+};
+
+#ifndef CONFIG_MMU
+extern struct rb_root nommu_vma_tree;
+extern struct rw_semaphore nommu_vma_sem;
+
+extern unsigned int kobjsize(const void *objp);
+#endif
+
+/*
  * vm_flags..
  */
 #define VM_READ		0x00000001	/* currently active flags */
@@ -211,6 +232,8 @@
 					 * usually used for buffer_heads
 					 * if PagePrivate set; used for
 					 * swp_entry_t if PageSwapCache
+					 * When page is free, this indicates
+					 * order in the buddy system.
 					 */
 	struct address_space *mapping;	/* If low bit clear, points to
 					 * inode address_space, or NULL.
@@ -557,7 +580,9 @@
 	struct address_space *check_mapping;	/* Check page->mapping if set */
 	pgoff_t	first_index;			/* Lowest page->index to unmap */
 	pgoff_t last_index;			/* Highest page->index to unmap */
-	int atomic;				/* May not schedule() */
+	spinlock_t *i_mmap_lock;		/* For unmap_mapping_range: */
+	unsigned long break_addr;		/* Where unmap_vmas stopped */
+	unsigned long truncate_count;		/* Compare vm_truncate_count */
 };
 
 void zap_page_range(struct vm_area_struct *vma, unsigned long address,
@@ -566,7 +591,7 @@
 		struct vm_area_struct *start_vma, unsigned long start_addr,
 		unsigned long end_addr, unsigned long *nr_accounted,
 		struct zap_details *);
-void clear_page_tables(struct mmu_gather *tlb, unsigned long first, int nr);
+void clear_page_range(struct mmu_gather *tlb, unsigned long addr, unsigned long end);
 int copy_page_range(struct mm_struct *dst, struct mm_struct *src,
 			struct vm_area_struct *vma);
 int zeromap_page_range(struct vm_area_struct *vma, unsigned long from,
@@ -581,7 +606,8 @@
 }
 
 extern int vmtruncate(struct inode * inode, loff_t offset);
-extern pmd_t *FASTCALL(__pmd_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address));
+extern pud_t *FASTCALL(__pud_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address));
+extern pmd_t *FASTCALL(__pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address));
 extern pte_t *FASTCALL(pte_alloc_kernel(struct mm_struct *mm, pmd_t *pmd, unsigned long address));
 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);
@@ -602,6 +628,10 @@
 int set_page_dirty_lock(struct page *page);
 int clear_page_dirty_for_io(struct page *page);
 
+extern unsigned long do_mremap(unsigned long addr,
+			       unsigned long old_len, unsigned long new_len,
+			       unsigned long flags, unsigned long new_addr);
+
 /*
  * Prototype to add a shrinker callback for ageable caches.
  * 
@@ -626,17 +656,32 @@
 extern void remove_shrinker(struct shrinker *shrinker);
 
 /*
- * On a two-level page table, this ends up being trivial. Thus the
- * inlining and the symmetry break with pte_alloc_map() that does all
+ * On a two-level or three-level page table, this ends up being trivial. Thus
+ * the inlining and the symmetry break with pte_alloc_map() that does all
  * of this out-of-line.
  */
-static inline pmd_t *pmd_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address)
+/*
+ * The following ifdef needed to get the 4level-fixup.h header to work.
+ * Remove it when 4level-fixup.h has been removed.
+ */
+#ifdef CONFIG_MMU
+#ifndef __ARCH_HAS_4LEVEL_HACK 
+static inline pud_t *pud_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address)
 {
 	if (pgd_none(*pgd))
-		return __pmd_alloc(mm, pgd, address);
-	return pmd_offset(pgd, address);
+		return __pud_alloc(mm, pgd, address);
+	return pud_offset(pgd, address);
 }
 
+static inline pmd_t *pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address)
+{
+	if (pud_none(*pud))
+		return __pmd_alloc(mm, pud, address);
+	return pmd_offset(pud, address);
+}
+#endif
+#endif /* CONFIG_MMU */
+
 extern void free_area_init(unsigned long * zones_size);
 extern void free_area_init_node(int nid, pg_data_t *pgdat,
 	unsigned long * zones_size, unsigned long zone_start_pfn, 
@@ -666,6 +711,7 @@
 }
 
 /* mmap.c */
+extern int __vm_enough_memory(long pages, int cap_sys_admin);
 extern void vma_adjust(struct vm_area_struct *vma, unsigned long start,
 	unsigned long end, pgoff_t pgoff, struct vm_area_struct *insert);
 extern struct vm_area_struct *vma_merge(struct mm_struct *,
@@ -710,7 +756,9 @@
 extern void truncate_inode_pages(struct address_space *, loff_t);
 
 /* generic vm_area_ops exported for stackable file systems */
-struct page *filemap_nopage(struct vm_area_struct *, unsigned long, int *);
+extern struct page *filemap_nopage(struct vm_area_struct *, unsigned long, int *);
+extern int filemap_populate(struct vm_area_struct *, unsigned long,
+		unsigned long, pgprot_t, unsigned long, int);
 
 /* mm/page-writeback.c */
 int write_one_page(struct page *page, int wait);
@@ -718,15 +766,18 @@
 /* readahead.c */
 #define VM_MAX_READAHEAD	128	/* kbytes */
 #define VM_MIN_READAHEAD	16	/* kbytes (includes current page) */
+#define VM_MAX_CACHE_HIT    	256	/* max pages in a row in cache before
+					 * turning readahead off */
 
 int do_page_cache_readahead(struct address_space *mapping, struct file *filp,
 			unsigned long offset, unsigned long nr_to_read);
 int force_page_cache_readahead(struct address_space *mapping, struct file *filp,
 			unsigned long offset, unsigned long nr_to_read);
-void page_cache_readahead(struct address_space *mapping, 
+unsigned long  page_cache_readahead(struct address_space *mapping,
 			  struct file_ra_state *ra,
 			  struct file *filp,
-			  unsigned long offset);
+			  unsigned long offset,
+			  unsigned long size);
 void handle_ra_miss(struct address_space *mapping, 
 		    struct file_ra_state *ra, pgoff_t offset);
 unsigned long max_sane_readahead(unsigned long nr);
@@ -761,16 +812,10 @@
 extern unsigned long vmalloc_to_pfn(void *addr);
 extern struct page * follow_page(struct mm_struct *mm, unsigned long address,
 		int write);
+extern int check_user_page_readable(struct mm_struct *mm, unsigned long address);
 int remap_pfn_range(struct vm_area_struct *, unsigned long,
 		unsigned long, unsigned long, pgprot_t);
 
-static inline __deprecated /* since 25 Sept 2004 -- wli */
-int remap_page_range(struct vm_area_struct *vma, unsigned long uvaddr,
-			unsigned long paddr, unsigned long size, pgprot_t prot)
-{
-	return remap_pfn_range(vma, uvaddr, paddr >> PAGE_SHIFT, size, prot);
-}
-
 #ifdef CONFIG_PROC_FS
 void __vm_stat_account(struct mm_struct *, unsigned long, struct file *, long);
 #else
@@ -792,6 +837,9 @@
 							-vma_pages(vma));
 }
 
+/* update per process rss and vm hiwater data */
+extern void update_mem_hiwater(void);
+
 #ifndef CONFIG_DEBUG_PAGEALLOC
 static inline void
 kernel_map_pages(struct page *page, int numpages, int enable)
@@ -799,10 +847,14 @@
 }
 #endif
 
-#ifndef CONFIG_ARCH_GATE_AREA
 extern struct vm_area_struct *get_gate_vma(struct task_struct *tsk);
+#ifdef	__HAVE_ARCH_GATE_AREA
+int in_gate_area_no_task(unsigned long addr);
 int in_gate_area(struct task_struct *task, unsigned long addr);
-#endif
+#else
+int in_gate_area_no_task(unsigned long addr);
+#define in_gate_area(task, addr) ({(void)task; in_gate_area_no_task(addr);})
+#endif	/* __HAVE_ARCH_GATE_AREA */
 
 #endif /* __KERNEL__ */
 #endif /* _LINUX_MM_H */
diff -Nru a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h
--- a/include/linux/mmc/mmc.h	2005-03-01 23:38:57 -08:00
+++ b/include/linux/mmc/mmc.h	2005-03-01 23:38:57 -08:00
@@ -57,7 +57,6 @@
 	unsigned int		timeout_clks;	/* data timeout (in clocks) */
 	unsigned int		blksz_bits;	/* data block size */
 	unsigned int		blocks;		/* number of blocks */
-	struct request		*req __attribute__((deprecated));/* request structure (use the sg list instead) */
 	unsigned int		error;		/* data error */
 	unsigned int		flags;
 
diff -Nru a/include/linux/mmzone.h b/include/linux/mmzone.h
--- a/include/linux/mmzone.h	2005-03-01 23:38:58 -08:00
+++ b/include/linux/mmzone.h	2005-03-01 23:38:58 -08:00
@@ -22,7 +22,7 @@
 
 struct free_area {
 	struct list_head	free_list;
-	unsigned long		*map;
+	unsigned long		nr_free;
 };
 
 struct pglist_data;
@@ -112,18 +112,14 @@
 	unsigned long		free_pages;
 	unsigned long		pages_min, pages_low, pages_high;
 	/*
-	 * protection[] is a pre-calculated number of extra pages that must be
-	 * available in a zone in order for __alloc_pages() to allocate memory
-	 * from the zone. i.e., for a GFP_KERNEL alloc of "order" there must
-	 * be "(1<<order) + protection[ZONE_NORMAL]" free pages in the zone
-	 * for us to choose to allocate the page from that zone.
-	 *
-	 * It uses both min_free_kbytes and sysctl_lower_zone_protection.
-	 * The protection values are recalculated if either of these values
-	 * change.  The array elements are in zonelist order:
-	 *	[0] == GFP_DMA, [1] == GFP_KERNEL, [2] == GFP_HIGHMEM.
+	 * We don't know if the memory that we're going to allocate will be freeable
+	 * or/and it will be released eventually, so to avoid totally wasting several
+	 * GB of ram we must reserve some of the lower zone memory (otherwise we risk
+	 * to run OOM on the lower zones despite there's tons of freeable ram
+	 * on the higher zones). This array is recalculated at runtime if the
+	 * sysctl_lowmem_reserve_ratio sysctl changes.
 	 */
-	unsigned long		protection[MAX_NR_ZONES];
+	unsigned long		lowmem_reserve[MAX_NR_ZONES];
 
 	struct per_cpu_pageset	pageset[NR_CPUS];
 
@@ -263,14 +259,14 @@
 					     range, including holes */
 	int node_id;
 	struct pglist_data *pgdat_next;
-	wait_queue_head_t       kswapd_wait;
+	wait_queue_head_t kswapd_wait;
 	struct task_struct *kswapd;
+	int kswapd_max_order;
 } pg_data_t;
 
 #define node_present_pages(nid)	(NODE_DATA(nid)->node_present_pages)
 #define node_spanned_pages(nid)	(NODE_DATA(nid)->node_spanned_pages)
 
-extern int numnodes;
 extern struct pglist_data *pgdat_list;
 
 void __get_zone_counts(unsigned long *active, unsigned long *inactive,
@@ -278,7 +274,9 @@
 void get_zone_counts(unsigned long *active, unsigned long *inactive,
 			unsigned long *free);
 void build_all_zonelists(void);
-void wakeup_kswapd(struct zone *zone);
+void wakeup_kswapd(struct zone *zone, int order);
+int zone_watermark_ok(struct zone *z, int order, unsigned long mark,
+		int alloc_type, int can_try_harder, int gfp_high);
 
 /*
  * zone_idx() returns 0 for the ZONE_DMA zone, 1 for the ZONE_NORMAL zone, etc.
@@ -307,7 +305,7 @@
 {
 	pg_data_t *pgdat = zone->zone_pgdat;
 
-	if (zone - pgdat->node_zones < MAX_NR_ZONES - 1)
+	if (zone < pgdat->node_zones + MAX_NR_ZONES - 1)
 		zone++;
 	else if (pgdat->pgdat_next) {
 		pgdat = pgdat->pgdat_next;
@@ -353,12 +351,12 @@
  */
 static inline int is_highmem(struct zone *zone)
 {
-	return (is_highmem_idx(zone - zone->zone_pgdat->node_zones));
+	return zone == zone->zone_pgdat->node_zones + ZONE_HIGHMEM;
 }
 
 static inline int is_normal(struct zone *zone)
 {
-	return (is_normal_idx(zone - zone->zone_pgdat->node_zones));
+	return zone == zone->zone_pgdat->node_zones + ZONE_NORMAL;
 }
 
 /* These two functions are used to setup the per zone pages min values */
@@ -366,12 +364,13 @@
 struct file;
 int min_free_kbytes_sysctl_handler(struct ctl_table *, int, struct file *, 
 					void __user *, size_t *, loff_t *);
-int lower_zone_protection_sysctl_handler(struct ctl_table *, int, struct file *,
+extern int sysctl_lowmem_reserve_ratio[MAX_NR_ZONES-1];
+int lowmem_reserve_ratio_sysctl_handler(struct ctl_table *, int, struct file *,
 					void __user *, size_t *, loff_t *);
 
 #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(_smp_processor_id()))
 
 #ifndef CONFIG_DISCONTIGMEM
 
diff -Nru a/include/linux/module.h b/include/linux/module.h
--- a/include/linux/module.h	2005-03-01 23:39:09 -08:00
+++ b/include/linux/module.h	2005-03-01 23:39:09 -08:00
@@ -48,8 +48,9 @@
 
 struct module_attribute {
         struct attribute attr;
-        ssize_t (*show)(struct module *, char *);
-        ssize_t (*store)(struct module *, const char *, size_t count);
+        ssize_t (*show)(struct module_attribute *, struct module *, char *);
+        ssize_t (*store)(struct module_attribute *, struct module *,
+			 const char *, size_t count);
 };
 
 struct module_kobject
@@ -206,10 +207,6 @@
 
 #endif
 
-/* We don't mangle the actual symbol anymore, so no need for
- * special casing EXPORT_SYMBOL_NOVERS.  FIXME: Deprecated */
-#define EXPORT_SYMBOL_NOVERS(sym) EXPORT_SYMBOL(sym)
-
 struct module_ref
 {
 	local_t count;
@@ -226,18 +223,18 @@
 #define MODULE_SECT_NAME_LEN 32
 struct module_sect_attr
 {
-	struct attribute attr;
+	struct module_attribute mattr;
 	char name[MODULE_SECT_NAME_LEN];
 	unsigned long address;
 };
 
-struct module_sections
+struct module_sect_attrs
 {
-	struct kobject kobj;
+	struct attribute_group grp;
 	struct module_sect_attr attrs[0];
 };
 
-struct param_kobject;
+struct module_param_attrs;
 
 struct module
 {
@@ -250,8 +247,8 @@
 	char name[MODULE_NAME_LEN];
 
 	/* Sysfs stuff. */
-	struct module_kobject *mkobj;
-	struct param_kobject *params_kobject;
+	struct module_kobject mkobj;
+	struct module_param_attrs *param_attrs;
 
 	/* Exported symbols */
 	const struct kernel_symbol *syms;
@@ -312,7 +309,7 @@
 	char *strtab;
 
 	/* Section attributes */
-	struct module_sections *sect_attrs;
+	struct module_sect_attrs *sect_attrs;
 #endif
 
 	/* Per-cpu data. */
@@ -449,7 +446,6 @@
 #else /* !CONFIG_MODULES... */
 #define EXPORT_SYMBOL(sym)
 #define EXPORT_SYMBOL_GPL(sym)
-#define EXPORT_SYMBOL_NOVERS(sym)
 
 /* Given an address, look for it in the exception tables. */
 static inline const struct exception_table_entry *
diff -Nru a/include/linux/moduleparam.h b/include/linux/moduleparam.h
--- a/include/linux/moduleparam.h	2005-03-01 23:38:56 -08:00
+++ b/include/linux/moduleparam.h	2005-03-01 23:38:56 -08:00
@@ -64,7 +64,8 @@
    param_set_XXX and param_check_XXX. */
 #define module_param_named(name, value, type, perm)			   \
 	param_check_##type(name, &(value));				   \
-	module_param_call(name, param_set_##type, param_get_##type, &value, perm)
+	module_param_call(name, param_set_##type, param_get_##type, &value, perm); \
+	__MODULE_INFO(parmtype, name##type, #name ":" #type)
 
 #define module_param(name, type, perm)				\
 	module_param_named(name, name, type, perm)
@@ -74,7 +75,8 @@
 	static struct kparam_string __param_string_##name		\
 		= { len, string };					\
 	module_param_call(name, param_set_copystring, param_get_string,	\
-		   &__param_string_##name, perm)
+		   &__param_string_##name, perm);			\
+	__MODULE_INFO(parmtype, name##type, #name ":string")
 
 /* Called on module insert or kernel boot */
 extern int parse_args(const char *name,
@@ -135,7 +137,8 @@
 	= { ARRAY_SIZE(array), nump, param_set_##type, param_get_##type,\
 	    sizeof(array[0]), array };					\
 	module_param_call(name, param_array_set, param_array_get, 	\
-			  &__param_arr_##name, perm)
+			  &__param_arr_##name, perm);			\
+	__MODULE_INFO(parmtype, name##type, #name ":array of " #type)
 
 #define module_param_array(name, type, nump, perm)		\
 	module_param_array_named(name, name, type, nump, perm)
diff -Nru a/include/linux/msdos_fs.h b/include/linux/msdos_fs.h
--- a/include/linux/msdos_fs.h	2005-03-01 23:39:09 -08:00
+++ b/include/linux/msdos_fs.h	2005-03-01 23:39:09 -08:00
@@ -12,6 +12,10 @@
 #define MSDOS_DPB_BITS	4		/* log2(MSDOS_DPB) */
 #define MSDOS_DPS	(SECTOR_SIZE / sizeof(struct msdos_dir_entry))
 #define MSDOS_DPS_BITS	4		/* log2(MSDOS_DPS) */
+#define CF_LE_W(v)	le16_to_cpu(v)
+#define CF_LE_L(v)	le32_to_cpu(v)
+#define CT_LE_W(v)	cpu_to_le16(v)
+#define CT_LE_L(v)	cpu_to_le32(v)
 
 
 #define MSDOS_SUPER_MAGIC 0x4d44 /* MD */
@@ -23,62 +27,65 @@
 #define FAT_MAX_DIR_ENTRIES	(65536)
 #define FAT_MAX_DIR_SIZE	(FAT_MAX_DIR_ENTRIES << MSDOS_DIR_BITS)
 
-#define ATTR_NONE    0 /* no attribute bits */
-#define ATTR_RO      1  /* read-only */
-#define ATTR_HIDDEN  2  /* hidden */
-#define ATTR_SYS     4  /* system */
-#define ATTR_VOLUME  8  /* volume label */
-#define ATTR_DIR     16 /* directory */
-#define ATTR_ARCH    32 /* archived */
+#define ATTR_NONE	0	/* no attribute bits */
+#define ATTR_RO		1	/* read-only */
+#define ATTR_HIDDEN	2	/* hidden */
+#define ATTR_SYS	4	/* system */
+#define ATTR_VOLUME	8	/* volume label */
+#define ATTR_DIR	16	/* directory */
+#define ATTR_ARCH	32	/* archived */
 
 /* attribute bits that are copied "as is" */
-#define ATTR_UNUSED  (ATTR_VOLUME | ATTR_ARCH | ATTR_SYS | ATTR_HIDDEN)
+#define ATTR_UNUSED	(ATTR_VOLUME | ATTR_ARCH | ATTR_SYS | ATTR_HIDDEN)
 /* bits that are used by the Windows 95/Windows NT extended FAT */
-#define ATTR_EXT     (ATTR_RO | ATTR_HIDDEN | ATTR_SYS | ATTR_VOLUME)
+#define ATTR_EXT	(ATTR_RO | ATTR_HIDDEN | ATTR_SYS | ATTR_VOLUME)
 
-#define CASE_LOWER_BASE 8	/* base is lower case */
-#define CASE_LOWER_EXT  16	/* extension is lower case */
+#define CASE_LOWER_BASE	8	/* base is lower case */
+#define CASE_LOWER_EXT	16	/* extension is lower case */
 
-#define DELETED_FLAG 0xe5 /* marks file as deleted when in name[0] */
-#define IS_FREE(n) (!*(n) || *(n) == DELETED_FLAG)
+#define DELETED_FLAG	0xe5	/* marks file as deleted when in name[0] */
+#define IS_FREE(n)	(!*(n) || *(n) == DELETED_FLAG)
 
 /* valid file mode bits */
 #define MSDOS_VALID_MODE (S_IFREG | S_IFDIR | S_IRWXU | S_IRWXG | S_IRWXO)
 /* Convert attribute bits and a mask to the UNIX mode. */
 #define MSDOS_MKMODE(a, m) (m & (a & ATTR_RO ? S_IRUGO|S_IXUGO : S_IRWXUGO))
 /* Convert the UNIX mode to MS-DOS attribute bits. */
-#define MSDOS_MKATTR(m) ((m & S_IWUGO) ? ATTR_NONE : ATTR_RO)
+#define MSDOS_MKATTR(m)	((m & S_IWUGO) ? ATTR_NONE : ATTR_RO)
 
-#define MSDOS_NAME 11 /* maximum name length */
-#define MSDOS_LONGNAME 256 /* maximum name length */
-#define MSDOS_SLOTS 21  /* max # of slots needed for short and long names */
-#define MSDOS_DOT    ".          " /* ".", padded to MSDOS_NAME chars */
-#define MSDOS_DOTDOT "..         " /* "..", padded to MSDOS_NAME chars */
+#define MSDOS_NAME	11	/* maximum name length */
+#define MSDOS_LONGNAME	256	/* maximum name length */
+#define MSDOS_SLOTS	21	/* max # of slots for short and long names */
+#define MSDOS_DOT	".          "	/* ".", padded to MSDOS_NAME chars */
+#define MSDOS_DOTDOT	"..         "	/* "..", padded to MSDOS_NAME chars */
 
 /* media of boot sector */
 #define FAT_VALID_MEDIA(x)	((0xF8 <= (x) && (x) <= 0xFF) || (x) == 0xF0)
 #define FAT_FIRST_ENT(s, x)	((MSDOS_SB(s)->fat_bits == 32 ? 0x0FFFFF00 : \
 	MSDOS_SB(s)->fat_bits == 16 ? 0xFF00 : 0xF00) | (x))
 
+/* start of data cluster's entry (number of reserved clusters) */
+#define FAT_START_ENT	2
+
 /* maximum number of clusters */
-#define MAX_FAT12 0xFF4
-#define MAX_FAT16 0xFFF4
-#define MAX_FAT32 0x0FFFFFF6
-#define MAX_FAT(s) (MSDOS_SB(s)->fat_bits == 32 ? MAX_FAT32 : \
+#define MAX_FAT12	0xFF4
+#define MAX_FAT16	0xFFF4
+#define MAX_FAT32	0x0FFFFFF6
+#define MAX_FAT(s)	(MSDOS_SB(s)->fat_bits == 32 ? MAX_FAT32 : \
 	MSDOS_SB(s)->fat_bits == 16 ? MAX_FAT16 : MAX_FAT12)
 
 /* bad cluster mark */
-#define BAD_FAT12 0xFF7
-#define BAD_FAT16 0xFFF7
-#define BAD_FAT32 0x0FFFFFF7
-#define BAD_FAT(s) (MSDOS_SB(s)->fat_bits == 32 ? BAD_FAT32 : \
+#define BAD_FAT12	0xFF7
+#define BAD_FAT16	0xFFF7
+#define BAD_FAT32	0x0FFFFFF7
+#define BAD_FAT(s)	(MSDOS_SB(s)->fat_bits == 32 ? BAD_FAT32 : \
 	MSDOS_SB(s)->fat_bits == 16 ? BAD_FAT16 : BAD_FAT12)
 
 /* standard EOF */
-#define EOF_FAT12 0xFFF
-#define EOF_FAT16 0xFFFF
-#define EOF_FAT32 0x0FFFFFFF
-#define EOF_FAT(s) (MSDOS_SB(s)->fat_bits == 32 ? EOF_FAT32 : \
+#define EOF_FAT12	0xFFF
+#define EOF_FAT16	0xFFFF
+#define EOF_FAT32	0x0FFFFFFF
+#define EOF_FAT(s)	(MSDOS_SB(s)->fat_bits == 32 ? EOF_FAT32 : \
 	MSDOS_SB(s)->fat_bits == 16 ? EOF_FAT16 : EOF_FAT12)
 
 #define FAT_ENT_FREE	(0)
@@ -96,7 +103,7 @@
 #define	VFAT_IOCTL_READDIR_BOTH		_IOR('r', 1, struct dirent [2])
 #define	VFAT_IOCTL_READDIR_SHORT	_IOR('r', 2, struct dirent [2])
 
-/* 
+/*
  * vfat shortname flags
  */
 #define VFAT_SFN_DISPLAY_LOWER	0x0001 /* convert to lowercase for display */
@@ -105,18 +112,6 @@
 #define VFAT_SFN_CREATE_WIN95	0x0100 /* emulate win95 rule for create */
 #define VFAT_SFN_CREATE_WINNT	0x0200 /* emulate winnt rule for create */
 
-/*
- * Conversion from and to little-endian byte order. (no-op on i386/i486)
- *
- * Naming: Ca_b_c, where a: F = from, T = to, b: LE = little-endian,
- * BE = big-endian, c: W = word (16 bits), L = longword (32 bits)
- */
-
-#define CF_LE_W(v) le16_to_cpu(v)
-#define CF_LE_L(v) le32_to_cpu(v)
-#define CT_LE_W(v) cpu_to_le16(v)
-#define CT_LE_L(v) cpu_to_le32(v)
-
 struct fat_boot_sector {
 	__u8	ignored[3];	/* Boot strap short or near jump */
 	__u8	system_id[8];	/* Name - can be used to special case
@@ -161,7 +156,7 @@
 	__le16	ctime;		/* Creation time */
 	__le16	cdate;		/* Creation date */
 	__le16	adate;		/* Last access date */
-	__le16   starthi;	/* High 16 bits of cluster in FAT32 */
+	__le16	starthi;	/* High 16 bits of cluster in FAT32 */
 	__le16	time,date,start;/* time, date and first cluster */
 	__le32	size;		/* file size (in bytes) */
 };
@@ -179,9 +174,9 @@
 };
 
 struct vfat_slot_info {
-	int long_slots;		       /* number of long slots in filename */
-	loff_t longname_offset;	       /* dir offset for longname start */
-	loff_t i_pos;		       /* on-disk position of directory entry */
+	int long_slots;		/* number of long slots in filename */
+	loff_t longname_offset;	/* dir offset for longname start */
+	loff_t i_pos;		/* on-disk position of directory entry */
 };
 
 #ifdef __KERNEL__
@@ -189,8 +184,84 @@
 #include <linux/buffer_head.h>
 #include <linux/string.h>
 #include <linux/nls.h>
-#include <linux/msdos_fs_i.h>
-#include <linux/msdos_fs_sb.h>
+#include <linux/fs.h>
+
+struct fat_mount_options {
+	uid_t fs_uid;
+	gid_t fs_gid;
+	unsigned short fs_fmask;
+	unsigned short fs_dmask;
+	unsigned short codepage;  /* Codepage for shortname conversions */
+	char *iocharset;          /* Charset used for filename input/display */
+	unsigned short shortname; /* flags for shortname display/create rule */
+	unsigned char name_check; /* r = relaxed, n = normal, s = strict */
+	unsigned quiet:1,         /* set = fake successful chmods and chowns */
+		 showexec:1,      /* set = only set x bit for com/exe/bat */
+		 sys_immutable:1, /* set = system files are immutable */
+		 dotsOK:1,        /* set = hidden and system files are named '.filename' */
+		 isvfat:1,        /* 0=no vfat long filename support, 1=vfat support */
+		 utf8:1,	  /* Use of UTF8 character set (Default) */
+		 unicode_xlate:1, /* create escape sequences for unhandled Unicode */
+		 numtail:1,       /* Does first alias have a numeric '~1' type tail? */
+		 atari:1,         /* Use Atari GEMDOS variation of MS-DOS fs */
+		 nocase:1;	  /* Does this need case conversion? 0=need case conversion*/
+};
+
+#define FAT_HASH_BITS	8
+#define FAT_HASH_SIZE	(1UL << FAT_HASH_BITS)
+#define FAT_HASH_MASK	(FAT_HASH_SIZE-1)
+
+/*
+ * MS-DOS file system in-core superblock data
+ */
+struct msdos_sb_info {
+	unsigned short sec_per_clus; /* sectors/cluster */
+	unsigned short cluster_bits; /* log2(cluster_size) */
+	unsigned int cluster_size;   /* cluster size */
+	unsigned char fats,fat_bits; /* number of FATs, FAT bits (12 or 16) */
+	unsigned short fat_start;
+	unsigned long fat_length;    /* FAT start & length (sec.) */
+	unsigned long dir_start;
+	unsigned short dir_entries;  /* root dir start & entries */
+	unsigned long data_start;    /* first data sector */
+	unsigned long max_cluster;   /* maximum cluster number */
+	unsigned long root_cluster;  /* first cluster of the root directory */
+	unsigned long fsinfo_sector; /* sector number of FAT32 fsinfo */
+	struct semaphore fat_lock;
+	int prev_free;               /* previously allocated cluster number */
+	int free_clusters;           /* -1 if undefined */
+	struct fat_mount_options options;
+	struct nls_table *nls_disk;  /* Codepage used on disk */
+	struct nls_table *nls_io;    /* Charset used for input and display */
+	void *dir_ops;		     /* Opaque; default directory operations */
+	int dir_per_block;	     /* dir entries per block */
+	int dir_per_block_bits;	     /* log2(dir_per_block) */
+
+	spinlock_t inode_hash_lock;
+	struct hlist_head inode_hashtable[FAT_HASH_SIZE];
+};
+
+#define FAT_CACHE_VALID	0	/* special case for valid cache */
+
+/*
+ * MS-DOS file system inode data in memory
+ */
+struct msdos_inode_info {
+	spinlock_t cache_lru_lock;
+	struct list_head cache_lru;
+	int nr_caches;
+	/* for avoiding the race between fat_free() and fat_get_cluster() */
+	unsigned int cache_valid_id;
+
+	loff_t mmu_private;
+	int i_start;		/* first cluster or 0 */
+	int i_logstart;		/* logical first cluster */
+	int i_attrs;		/* unused attribute bits */
+	int i_ctime_ms;		/* unused change time in milliseconds */
+	loff_t i_pos;		/* on-disk position of directory entry or 0 */
+	struct hlist_node i_fat_hash;	/* hash by i_location */
+	struct inode vfs_inode;
+};
 
 static inline struct msdos_sb_info *MSDOS_SB(struct super_block *sb)
 {
@@ -202,6 +273,12 @@
 	return container_of(inode, struct msdos_inode_info, vfs_inode);
 }
 
+static inline sector_t fat_clus_to_blknr(struct msdos_sb_info *sbi, int clus)
+{
+	return ((sector_t)clus - FAT_START_ENT) * sbi->sec_per_clus
+		+ sbi->data_start;
+}
+
 static inline void fat16_towchar(wchar_t *dst, const __u8 *src, size_t len)
 {
 #ifdef __BIG_ENDIAN
@@ -229,21 +306,20 @@
 }
 
 /* fat/cache.c */
-extern int fat_access(struct super_block *sb, int nr, int new_value);
-extern int __fat_access(struct super_block *sb, int nr, int new_value);
-extern int fat_bmap(struct inode *inode, sector_t sector, sector_t *phys);
 extern void fat_cache_inval_inode(struct inode *inode);
+extern int fat_access(struct super_block *sb, int nr, int new_value);
 extern int fat_get_cluster(struct inode *inode, int cluster,
 			   int *fclus, int *dclus);
-extern int fat_free(struct inode *inode, int skip);
+extern int fat_bmap(struct inode *inode, sector_t sector, sector_t *phys);
 
 /* fat/dir.c */
 extern struct file_operations fat_dir_operations;
 extern int fat_search_long(struct inode *inode, const unsigned char *name,
 			   int name_len, int anycase,
 			   loff_t *spos, loff_t *lpos);
-extern int fat_add_entries(struct inode *dir, int slots, struct buffer_head **bh,
-			struct msdos_dir_entry **de, loff_t *i_pos);
+extern int fat_add_entries(struct inode *dir, int slots,
+			   struct buffer_head **bh,
+			   struct msdos_dir_entry **de, loff_t *i_pos);
 extern int fat_new_dir(struct inode *dir, struct inode *parent, int is_vfat);
 extern int fat_dir_empty(struct inode *dir);
 extern int fat_subdirs(struct inode *dir);
@@ -254,8 +330,7 @@
 /* fat/file.c */
 extern struct file_operations fat_file_operations;
 extern struct inode_operations fat_file_inode_operations;
-extern int fat_get_block(struct inode *inode, sector_t iblock,
-			 struct buffer_head *bh_result, int create);
+extern int fat_notify_change(struct dentry * dentry, struct iattr * attr);
 extern void fat_truncate(struct inode *inode);
 
 /* fat/inode.c */
@@ -266,7 +341,6 @@
 			struct msdos_dir_entry *de, loff_t i_pos, int *res);
 int fat_fill_super(struct super_block *sb, void *data, int silent,
 		   struct inode_operations *fs_dir_inode_ops, int isvfat);
-extern int fat_notify_change(struct dentry * dentry, struct iattr * attr);
 
 /* fat/misc.c */
 extern void fat_fs_panic(struct super_block *s, const char *fmt, ...);
@@ -274,7 +348,6 @@
 extern void unlock_fat(struct super_block *sb);
 extern void fat_clusters_flush(struct super_block *sb);
 extern int fat_add_cluster(struct inode *inode);
-extern struct buffer_head *fat_extend_dir(struct inode *inode);
 extern int date_dos2unix(unsigned short time, unsigned short date);
 extern void fat_date_unix2dos(int unix_date, __le16 *time, __le16 *date);
 extern int fat__get_entry(struct inode *dir, loff_t *pos,
diff -Nru a/include/linux/msdos_fs_i.h b/include/linux/msdos_fs_i.h
--- a/include/linux/msdos_fs_i.h	2005-03-01 23:39:17 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,29 +0,0 @@
-#ifndef _MSDOS_FS_I
-#define _MSDOS_FS_I
-
-#include <linux/fs.h>
-
-/*
- * MS-DOS file system inode data in memory
- */
-
-#define FAT_CACHE_VALID	0	/* special case for valid cache */
-
-struct msdos_inode_info {
-	spinlock_t cache_lru_lock;
-	struct list_head cache_lru;
-	int nr_caches;
-	/* for avoiding the race between fat_free() and fat_get_cluster() */
-	unsigned int cache_valid_id;
-
-	loff_t mmu_private;
-	int i_start;	/* first cluster or 0 */
-	int i_logstart;	/* logical first cluster */
-	int i_attrs;	/* unused attribute bits */
-	int i_ctime_ms;	/* unused change time in milliseconds */
-	loff_t i_pos;	/* on-disk position of directory entry or 0 */
-	struct hlist_node i_fat_hash;	/* hash by i_location */
-	struct inode vfs_inode;
-};
-
-#endif
diff -Nru a/include/linux/msdos_fs_sb.h b/include/linux/msdos_fs_sb.h
--- a/include/linux/msdos_fs_sb.h	2005-03-01 23:38:57 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,60 +0,0 @@
-#ifndef _MSDOS_FS_SB
-#define _MSDOS_FS_SB
-
-/*
- * MS-DOS file system in-core superblock data
- */
-
-struct fat_mount_options {
-	uid_t fs_uid;
-	gid_t fs_gid;
-	unsigned short fs_fmask;
-	unsigned short fs_dmask;
-	unsigned short codepage;  /* Codepage for shortname conversions */
-	char *iocharset;          /* Charset used for filename input/display */
-	unsigned short shortname; /* flags for shortname display/create rule */
-	unsigned char name_check; /* r = relaxed, n = normal, s = strict */
-	unsigned quiet:1,         /* set = fake successful chmods and chowns */
-		 showexec:1,      /* set = only set x bit for com/exe/bat */
-		 sys_immutable:1, /* set = system files are immutable */
-		 dotsOK:1,        /* set = hidden and system files are named '.filename' */
-		 isvfat:1,        /* 0=no vfat long filename support, 1=vfat support */
-		 utf8:1,	  /* Use of UTF8 character set (Default) */
-		 unicode_xlate:1, /* create escape sequences for unhandled Unicode */
-		 numtail:1,       /* Does first alias have a numeric '~1' type tail? */
-		 atari:1,         /* Use Atari GEMDOS variation of MS-DOS fs */
-		 nocase:1;	  /* Does this need case conversion? 0=need case conversion*/
-};
-
-#define FAT_HASH_BITS	8
-#define FAT_HASH_SIZE	(1UL << FAT_HASH_BITS)
-#define FAT_HASH_MASK	(FAT_HASH_SIZE-1)
-
-struct msdos_sb_info {
-	unsigned short sec_per_clus; /* sectors/cluster */
-	unsigned short cluster_bits; /* log2(cluster_size) */
-	unsigned int cluster_size;   /* cluster size */
-	unsigned char fats,fat_bits; /* number of FATs, FAT bits (12 or 16) */
-	unsigned short fat_start;
-	unsigned long fat_length;    /* FAT start & length (sec.) */
-	unsigned long dir_start;
-	unsigned short dir_entries;  /* root dir start & entries */
-	unsigned long data_start;    /* first data sector */
-	unsigned long clusters;      /* number of clusters */
-	unsigned long root_cluster;  /* first cluster of the root directory */
-	unsigned long fsinfo_sector; /* sector number of FAT32 fsinfo */
-	struct semaphore fat_lock;
-	int prev_free;               /* previously allocated cluster number */
-	int free_clusters;           /* -1 if undefined */
-	struct fat_mount_options options;
-	struct nls_table *nls_disk;  /* Codepage used on disk */
-	struct nls_table *nls_io;    /* Charset used for input and display */
-	void *dir_ops;		     /* Opaque; default directory operations */
-	int dir_per_block;	     /* dir entries per block */
-	int dir_per_block_bits;	     /* log2(dir_per_block) */
-
-	spinlock_t inode_hash_lock;
-	struct hlist_head inode_hashtable[FAT_HASH_SIZE];
-};
-
-#endif
diff -Nru a/include/linux/mtd/cfi.h b/include/linux/mtd/cfi.h
--- a/include/linux/mtd/cfi.h	2005-03-01 23:38:55 -08:00
+++ b/include/linux/mtd/cfi.h	2005-03-01 23:38:55 -08:00
@@ -1,7 +1,7 @@
 
 /* Common Flash Interface structures 
  * See http://support.intel.com/design/flash/technote/index.htm
- * $Id: cfi.h,v 1.49 2004/11/15 20:56:32 nico Exp $
+ * $Id: cfi.h,v 1.50 2004/11/20 12:46:51 dwmw2 Exp $
  */
 
 #ifndef __MTD_CFI_H__
@@ -349,14 +349,12 @@
 
 static inline void cfi_udelay(int us)
 {
-	unsigned long t = us * HZ / 1000000;
-	if (t) {
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(t);
-		return;
+	if (us >= 1000) {
+		msleep((us+999)/1000);
+	} else {
+		udelay(us);
+		cond_resched();
 	}
-	udelay(us);
-	cond_resched();
 }
 
 static inline void cfi_spin_lock(spinlock_t *mutex)
diff -Nru a/include/linux/mtd/doc2000.h b/include/linux/mtd/doc2000.h
--- a/include/linux/mtd/doc2000.h	2005-03-01 23:38:58 -08:00
+++ b/include/linux/mtd/doc2000.h	2005-03-01 23:38:58 -08:00
@@ -6,7 +6,7 @@
  * Copyright (C) 2002-2003 Greg Ungerer <gerg@snapgear.com>
  * Copyright (C) 2002-2003 SnapGear Inc
  *
- * $Id: doc2000.h,v 1.23 2004/09/16 23:26:08 gleixner Exp $ 
+ * $Id: doc2000.h,v 1.24 2005/01/05 12:40:38 dwmw2 Exp $ 
  *
  * Released under GPL
  */
@@ -89,8 +89,8 @@
 #define WriteDOC_(d, adr, reg)  do{ *(volatile __u16 *)(((unsigned long)adr)+((reg)<<1)) = (__u16)d; wmb();} while(0)
 #define DOC_IOREMAP_LEN 0x4000
 #else
-#define ReadDOC_(adr, reg)      readb((void __iomem *)(((unsigned long)adr) + (reg)))
-#define WriteDOC_(d, adr, reg)  writeb(d, (void __iomem *)(((unsigned long)adr) + (reg)))
+#define ReadDOC_(adr, reg)      readb((void __iomem *)(adr) + (reg))
+#define WriteDOC_(d, adr, reg)  writeb(d, (void __iomem *)(adr) + (reg))
 #define DOC_IOREMAP_LEN 0x2000
 
 #endif
diff -Nru a/include/linux/mtd/flashchip.h b/include/linux/mtd/flashchip.h
--- a/include/linux/mtd/flashchip.h	2005-03-01 23:39:10 -08:00
+++ b/include/linux/mtd/flashchip.h	2005-03-01 23:39:10 -08:00
@@ -6,7 +6,7 @@
  *
  * (C) 2000 Red Hat. GPLd.
  *
- * $Id: flashchip.h,v 1.14 2004/06/15 16:44:59 nico Exp $
+ * $Id: flashchip.h,v 1.15 2004/11/05 22:41:06 nico Exp $
  *
  */
 
@@ -37,6 +37,8 @@
 	FL_LOCKING,
 	FL_UNLOCKING,
 	FL_POINT,
+	FL_XIP_WHILE_ERASING,
+	FL_XIP_WHILE_WRITING,
 	FL_UNKNOWN
 } flstate_t;
 
diff -Nru a/include/linux/mtd/gen_probe.h b/include/linux/mtd/gen_probe.h
--- a/include/linux/mtd/gen_probe.h	2005-03-01 23:39:06 -08:00
+++ b/include/linux/mtd/gen_probe.h	2005-03-01 23:39:06 -08:00
@@ -1,7 +1,7 @@
 /*
  * (C) 2001, 2001 Red Hat, Inc.
  * GPL'd
- * $Id: gen_probe.h,v 1.2 2003/11/08 00:51:21 dsaxena Exp $
+ * $Id: gen_probe.h,v 1.3 2004/10/20 22:10:33 dwmw2 Exp $
  */
 
 #ifndef __LINUX_MTD_GEN_PROBE_H__
diff -Nru a/include/linux/mtd/map.h b/include/linux/mtd/map.h
--- a/include/linux/mtd/map.h	2005-03-01 23:38:55 -08:00
+++ b/include/linux/mtd/map.h	2005-03-01 23:38:55 -08:00
@@ -1,6 +1,6 @@
 
 /* Overhauled routines for dealing with different mmap regions of flash */
-/* $Id: map.h,v 1.45 2004/09/21 14:31:17 bjd Exp $ */
+/* $Id: map.h,v 1.46 2005/01/05 17:09:44 dwmw2 Exp $ */
 
 #ifndef __LINUX_MTD_MAP_H__
 #define __LINUX_MTD_MAP_H__
@@ -322,7 +322,7 @@
 			bitpos = (map_bankwidth(map)-1-i)*8;
 #endif
 			orig.x[0] &= ~(0xff << bitpos);
-			orig.x[0] |= buf[i] << bitpos;
+			orig.x[0] |= buf[i-start] << bitpos;
 		}
 	}
 	return orig;
diff -Nru a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
--- a/include/linux/mtd/nand.h	2005-03-01 23:39:10 -08:00
+++ b/include/linux/mtd/nand.h	2005-03-01 23:39:10 -08:00
@@ -5,7 +5,7 @@
  *                     Steven J. Hill <sjhill@realitydiluted.com>
  *		       Thomas Gleixner <tglx@linutronix.de>
  *
- * $Id: nand.h,v 1.66 2004/10/02 10:07:08 gleixner Exp $
+ * $Id: nand.h,v 1.68 2004/11/12 10:40:37 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
@@ -138,6 +138,8 @@
 #define NAND_ECC_HW6_512	4
 /* Hardware ECC 8 byte ECC per 512 Byte data */
 #define NAND_ECC_HW8_512	6
+/* Hardware ECC 12 byte ECC per 2048 Byte data */
+#define NAND_ECC_HW12_2048	7
 
 /*
  * Constants for Hardware ECC
@@ -253,6 +255,7 @@
  * @scan_bbt:		[REPLACEABLE] function to scan bad block table
  * @eccmode:		[BOARDSPECIFIC] mode of ecc, see defines 
  * @eccsize: 		[INTERN] databytes used per ecc-calculation
+ * @eccbytes: 		[INTERN] number of ecc bytes per ecc-calculation step
  * @eccsteps:		[INTERN] number of ecc calculation steps per page
  * @chip_delay:		[BOARDSPECIFIC] chip dependent delay for transfering data from array to read regs (tR)
  * @chip_lock:		[INTERN] spinlock used to protect access to this structure and the chip
@@ -277,6 +280,7 @@
  * @bbt:		[INTERN] bad block table pointer
  * @bbt_td:		[REPLACEABLE] bad block table descriptor for flash lookup
  * @bbt_md:		[REPLACEABLE] bad block table mirror descriptor
+ * @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
  */
@@ -307,6 +311,7 @@
 	int		(*scan_bbt)(struct mtd_info *mtd);
 	int		eccmode;
 	int		eccsize;
+	int		eccbytes;
 	int		eccsteps;
 	int 		chip_delay;
 	spinlock_t	chip_lock;
@@ -330,6 +335,7 @@
 	uint8_t		*bbt;
 	struct nand_bbt_descr	*bbt_td;
 	struct nand_bbt_descr	*bbt_md;
+	struct nand_bbt_descr	*badblock_pattern;
 	struct nand_hw_control  *controller;
 	void		*priv;
 };
diff -Nru a/include/linux/mtd/xip.h b/include/linux/mtd/xip.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/linux/mtd/xip.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,107 @@
+/*
+ * MTD primitives for XIP support
+ *
+ * Author:	Nicolas Pitre
+ * Created:	Nov 2, 2004
+ * Copyright:	(C) 2004 MontaVista Software, Inc.
+ *
+ * This XIP support for MTD has been loosely inspired
+ * by an earlier patch authored by David Woodhouse.
+ *
+ * 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 __LINUX_MTD_XIP_H__
+#define __LINUX_MTD_XIP_H__
+
+#include <linux/config.h>
+
+#ifdef CONFIG_MTD_XIP
+
+/*
+ * Function that are modifying the flash state away from array mode must
+ * obviously not be running from flash.  The __xipram is therefore marking
+ * those functions so they get relocated to ram.
+ */
+#define __xipram __attribute__ ((__section__ (".data")))
+
+/*
+ * We really don't want gcc to guess anything.
+ * We absolutely _need_ proper inlining.
+ */
+#include <linux/compiler.h>
+
+/*
+ * Each architecture has to provide the following macros.  They must access
+ * the hardware directly and not rely on any other (XIP) functions since they
+ * won't be available when used (flash not in array mode).
+ *
+ * xip_irqpending()
+ *
+ * 	return non zero when any hardware interrupt is pending.
+ *
+ * xip_currtime()
+ *
+ * 	return a platform specific time reference to be used with
+ * 	xip_elapsed_since().
+ *
+ * xip_elapsed_since(x)
+ *
+ * 	return in usecs the elapsed timebetween now and the reference x as
+ * 	returned by xip_currtime().
+ *
+ * 	note 1: convertion to usec can be approximated, as long as the
+ * 		returned value is <= the real elapsed time.
+ * 	note 2: this should be able to cope with a few seconds without
+ * 		overflowing.
+ */
+
+#if defined(CONFIG_ARCH_SA1100) || defined(CONFIG_ARCH_PXA)
+
+#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
+
+#warning "missing IRQ and timer primitives for XIP MTD support"
+#warning "some of the XIP MTD support code will be disabled"
+#warning "your system will therefore be unresponsive when writing or erasing flash"
+
+#define xip_irqpending()	(0)
+#define xip_currtime()		(0)
+#define xip_elapsed_since(x)	(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.
+ */
+
+#if defined(CONFIG_CPU_XSCALE)
+#define xip_cpu_idle()  asm volatile ("mcr p14, 0, %0, c7, c0, 0" :: "r" (1))
+#else
+#define xip_cpu_idle()  do { } while (0)
+#endif
+
+#else
+
+#define __xipram
+
+#endif /* CONFIG_MTD_XIP */
+
+#endif /* __LINUX_MTD_XIP_H__ */
diff -Nru a/include/linux/mv643xx.h b/include/linux/mv643xx.h
--- a/include/linux/mv643xx.h	2005-03-01 23:39:09 -08:00
+++ b/include/linux/mv643xx.h	2005-03-01 23:39:09 -08:00
@@ -13,8 +13,11 @@
 #ifndef __ASM_MV64340_H
 #define __ASM_MV64340_H
 
+#ifdef __MIPS__
 #include <asm/addrspace.h>
 #include <asm/marvell.h>
+#endif
+#include <asm/types.h>
 
 /****************************************/
 /* Processor Address Space              */
@@ -1035,5 +1038,51 @@
 #define MV64340_SERIAL_INIT_STATUS                                  0xf32c
 
 extern void mv64340_irq_init(unsigned int base);
+
+/* MPSC Platform Device, Driver Data (Shared register regions) */
+#define	MPSC_SHARED_NAME		"mpsc_shared"
+
+#define	MPSC_ROUTING_BASE_ORDER		0
+#define	MPSC_SDMA_INTR_BASE_ORDER	1
+
+#define MPSC_ROUTING_REG_BLOCK_SIZE	0x000c
+#define MPSC_SDMA_INTR_REG_BLOCK_SIZE	0x0084
+
+struct mpsc_shared_pdata {
+	u32	mrr_val;
+	u32	rcrr_val;
+	u32	tcrr_val;
+	u32	intr_cause_val;
+	u32	intr_mask_val;
+};
+
+/* MPSC Platform Device, Driver Data */
+#define	MPSC_CTLR_NAME			"mpsc"
+
+#define	MPSC_BASE_ORDER			0
+#define	MPSC_SDMA_BASE_ORDER		1
+#define	MPSC_BRG_BASE_ORDER		2
+
+#define MPSC_REG_BLOCK_SIZE		0x0038
+#define MPSC_SDMA_REG_BLOCK_SIZE	0x0c18
+#define MPSC_BRG_REG_BLOCK_SIZE		0x0008
+
+struct mpsc_pdata {
+	u8	mirror_regs;
+	u8	cache_mgmt;
+	u8	max_idle;
+	int	default_baud;
+	int	default_bits;
+	int	default_parity;
+	int	default_flow;
+	u32	chr_1_val;
+	u32	chr_2_val;
+	u32	chr_10_val;
+	u32	mpcr_val;
+	u32	bcr_val;
+	u8	brg_can_tune;
+	u8	brg_clk_src;
+	u32	brg_clk_freq;
+};
 
 #endif /* __ASM_MV64340_H */
diff -Nru a/include/linux/net.h b/include/linux/net.h
--- a/include/linux/net.h	2005-03-01 23:38:56 -08:00
+++ b/include/linux/net.h	2005-03-01 23:38:56 -08:00
@@ -187,10 +187,6 @@
 				  size_t len);
 extern int	     sock_recvmsg(struct socket *sock, struct msghdr *msg,
 				  size_t size, int flags);
-extern int	     sock_readv_writev(int type, struct inode *inode,
-				       struct file *file,
-				       const struct iovec *iov, long count,
-				       size_t size);
 extern int 	     sock_map_fd(struct socket *sock);
 extern struct socket *sockfd_lookup(int fd, int *err);
 #define		     sockfd_put(sock) fput(sock->file)
diff -Nru a/include/linux/netdevice.h b/include/linux/netdevice.h
--- a/include/linux/netdevice.h	2005-03-01 23:39:16 -08:00
+++ b/include/linux/netdevice.h	2005-03-01 23:39:16 -08:00
@@ -345,6 +345,7 @@
 	unsigned char		broadcast[MAX_ADDR_LEN];	/* hw bcast add	*/
 	unsigned char		dev_addr[MAX_ADDR_LEN];	/* hw address	*/
 	unsigned char		addr_len;	/* hardware address length	*/
+	unsigned short          dev_id;		/* for shared network cards */
 
 	struct dev_mc_list	*mc_list;	/* Multicast mac addresses	*/
 	int			mc_count;	/* Number of installed mcasts	*/
@@ -522,7 +523,6 @@
 extern struct net_device		*dev_base;		/* All devices */
 extern rwlock_t				dev_base_lock;		/* Device list lock */
 
-extern int			netdev_boot_setup_add(char *name, struct ifmap *map);
 extern int 			netdev_boot_setup_check(struct net_device *dev);
 extern unsigned long		netdev_boot_base(const char *prefix, int unit);
 extern struct net_device    *dev_getbyhwaddr(unsigned short type, char *hwaddr);
diff -Nru a/include/linux/netfilter.h b/include/linux/netfilter.h
--- a/include/linux/netfilter.h	2005-03-01 23:38:57 -08:00
+++ b/include/linux/netfilter.h	2005-03-01 23:38:57 -08:00
@@ -175,10 +175,6 @@
 extern void (*ip_ct_attach)(struct sk_buff *, struct sk_buff *);
 extern void nf_ct_attach(struct sk_buff *, struct sk_buff *);
 
-#ifdef CONFIG_NETFILTER_DEBUG
-extern void nf_dump_skb(int pf, struct sk_buff *skb);
-#endif
-
 /* FIXME: Before cache is ever used, this must be implemented for real. */
 extern void nf_invalidate_cache(int pf);
 
diff -Nru a/include/linux/netfilter_arp/arp_tables.h b/include/linux/netfilter_arp/arp_tables.h
--- a/include/linux/netfilter_arp/arp_tables.h	2005-03-01 23:38:54 -08:00
+++ b/include/linux/netfilter_arp/arp_tables.h	2005-03-01 23:38:54 -08:00
@@ -312,9 +312,6 @@
 	/* A unique name... */
 	char name[ARPT_TABLE_MAXNAMELEN];
 
-	/* Seed table: copied in register_table */
-	struct arpt_replace *table;
-
 	/* What hooks you will enter on */
 	unsigned int valid_hooks;
 
@@ -328,7 +325,8 @@
 	struct module *me;
 };
 
-extern int arpt_register_table(struct arpt_table *table);
+extern int arpt_register_table(struct arpt_table *table,
+			       const struct arpt_replace *repl);
 extern void arpt_unregister_table(struct arpt_table *table);
 extern unsigned int arpt_do_table(struct sk_buff **pskb,
 				  unsigned int hook,
diff -Nru a/include/linux/netfilter_bridge/ebt_ulog.h b/include/linux/netfilter_bridge/ebt_ulog.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/linux/netfilter_bridge/ebt_ulog.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,36 @@
+#ifndef _EBT_ULOG_H
+#define _EBT_ULOG_H
+
+#define EBT_ULOG_DEFAULT_NLGROUP 0
+#define EBT_ULOG_DEFAULT_QTHRESHOLD 1
+#define EBT_ULOG_MAXNLGROUPS 32 /* hardcoded netlink max */
+#define EBT_ULOG_PREFIX_LEN 32
+#define EBT_ULOG_MAX_QLEN 50
+#define EBT_ULOG_WATCHER "ulog"
+#define EBT_ULOG_VERSION 1
+
+struct ebt_ulog_info {
+	uint32_t nlgroup;
+	unsigned int cprange;
+	unsigned int qthreshold;
+	char prefix[EBT_ULOG_PREFIX_LEN];
+};
+
+typedef struct ebt_ulog_packet_msg {
+	int version;
+	char indev[IFNAMSIZ];
+	char outdev[IFNAMSIZ];
+	char physindev[IFNAMSIZ];
+	char physoutdev[IFNAMSIZ];
+	char prefix[EBT_ULOG_PREFIX_LEN];
+	struct timeval stamp;
+	unsigned long mark;
+	unsigned int hook;
+	size_t data_len;
+	/* The complete packet, including Ethernet header and perhaps
+	 * the VLAN header is appended */
+	unsigned char data[0] __attribute__
+	                      ((aligned (__alignof__(struct ebt_ulog_info))));
+} ebt_ulog_packet_msg_t;
+
+#endif /* _EBT_ULOG_H */
diff -Nru a/include/linux/netfilter_bridge/ebtables.h b/include/linux/netfilter_bridge/ebtables.h
--- a/include/linux/netfilter_bridge/ebtables.h	2005-03-01 23:39:16 -08:00
+++ b/include/linux/netfilter_bridge/ebtables.h	2005-03-01 23:39:16 -08:00
@@ -201,9 +201,9 @@
 {
 	struct list_head list;
 	const char name[EBT_FUNCTION_MAXNAMELEN];
-	void (*watcher)(const struct sk_buff *skb, const struct net_device *in,
-	   const struct net_device *out, const void *watcherdata,
-	   unsigned int datalen);
+	void (*watcher)(const struct sk_buff *skb, unsigned int hooknr,
+	   const struct net_device *in, const struct net_device *out,
+	   const void *watcherdata, unsigned int datalen);
 	/* 0 == let it in */
 	int (*check)(const char *tablename, unsigned int hookmask,
 	   const struct ebt_entry *e, void *watcherdata, unsigned int datalen);
diff -Nru a/include/linux/netfilter_ipv4/compat_firewall.h b/include/linux/netfilter_ipv4/compat_firewall.h
--- a/include/linux/netfilter_ipv4/compat_firewall.h	2005-03-01 23:39:08 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,45 +0,0 @@
-/* Minor modifications to fit on compatibility framework:
-   Rusty.Russell@rustcorp.com.au
-*/
-
-#ifndef __LINUX_FIREWALL_H
-#define __LINUX_FIREWALL_H
-
-/*
- *	Definitions for loadable firewall modules
- */
-
-#define FW_QUEUE	0
-#define FW_BLOCK	1
-#define FW_ACCEPT	2
-#define FW_REJECT	(-1)
-#define FW_REDIRECT	3
-#define FW_MASQUERADE	4
-#define FW_SKIP		5
-
-struct firewall_ops
-{
-	struct firewall_ops *next;
-	int (*fw_forward)(struct firewall_ops *this, int pf,
-			  struct net_device *dev, void *arg,
-			  struct sk_buff **pskb);
-	int (*fw_input)(struct firewall_ops *this, int pf,
-			struct net_device *dev, void *arg,
-			struct sk_buff **pskb);
-	int (*fw_output)(struct firewall_ops *this, int pf,
-			 struct net_device *dev, void *arg,
-			 struct sk_buff **pskb);
-	/* These may be NULL. */
-	int (*fw_acct_in)(struct firewall_ops *this, int pf,
-			  struct net_device *dev, void *arg,
-			  struct sk_buff **pskb);
-	int (*fw_acct_out)(struct firewall_ops *this, int pf,
-			   struct net_device *dev, void *arg,
-			   struct sk_buff **pskb);
-};
-
-extern int register_firewall(int pf, struct firewall_ops *fw);
-extern int unregister_firewall(int pf, struct firewall_ops *fw);
-
-extern int ip_fw_masq_timeouts(void *user, int len);
-#endif /* __LINUX_FIREWALL_H */
diff -Nru a/include/linux/netfilter_ipv4/ip_conntrack.h b/include/linux/netfilter_ipv4/ip_conntrack.h
--- a/include/linux/netfilter_ipv4/ip_conntrack.h	2005-03-01 23:39:16 -08:00
+++ b/include/linux/netfilter_ipv4/ip_conntrack.h	2005-03-01 23:39:16 -08:00
@@ -3,13 +3,6 @@
 /* Connection state tracking for netfilter.  This is separated from,
    but required by, the NAT layer; it can also be used by an iptables
    extension. */
-
-#include <linux/config.h>
-#include <linux/netfilter_ipv4/ip_conntrack_tuple.h>
-#include <linux/bitops.h>
-#include <linux/compiler.h>
-#include <asm/atomic.h>
-
 enum ip_conntrack_info
 {
 	/* Part of an established connection (either direction). */
@@ -47,8 +40,40 @@
 	/* Connection is confirmed: originating packet has left box */
 	IPS_CONFIRMED_BIT = 3,
 	IPS_CONFIRMED = (1 << IPS_CONFIRMED_BIT),
+
+	/* Connection needs src nat in orig dir.  This bit never changed. */
+	IPS_SRC_NAT_BIT = 4,
+	IPS_SRC_NAT = (1 << IPS_SRC_NAT_BIT),
+
+	/* Connection needs dst nat in orig dir.  This bit never changed. */
+	IPS_DST_NAT_BIT = 5,
+	IPS_DST_NAT = (1 << IPS_DST_NAT_BIT),
+
+	/* Both together. */
+	IPS_NAT_MASK = (IPS_DST_NAT | IPS_SRC_NAT),
+
+	/* Connection needs TCP sequence adjusted. */
+	IPS_SEQ_ADJUST_BIT = 6,
+	IPS_SEQ_ADJUST = (1 << IPS_SEQ_ADJUST_BIT),
+
+	/* NAT initialization bits. */
+	IPS_SRC_NAT_DONE_BIT = 7,
+	IPS_SRC_NAT_DONE = (1 << IPS_SRC_NAT_DONE_BIT),
+
+	IPS_DST_NAT_DONE_BIT = 8,
+	IPS_DST_NAT_DONE = (1 << IPS_DST_NAT_DONE_BIT),
+
+	/* Both together */
+	IPS_NAT_DONE_MASK = (IPS_DST_NAT_DONE | IPS_SRC_NAT_DONE),
 };
 
+#ifdef __KERNEL__
+#include <linux/config.h>
+#include <linux/netfilter_ipv4/ip_conntrack_tuple.h>
+#include <linux/bitops.h>
+#include <linux/compiler.h>
+#include <asm/atomic.h>
+
 #include <linux/netfilter_ipv4/ip_conntrack_tcp.h>
 #include <linux/netfilter_ipv4/ip_conntrack_icmp.h>
 #include <linux/netfilter_ipv4/ip_conntrack_sctp.h>
@@ -70,20 +95,6 @@
 #include <linux/netfilter_ipv4/ip_conntrack_ftp.h>
 #include <linux/netfilter_ipv4/ip_conntrack_irc.h>
 
-/* per expectation: application helper private data */
-union ip_conntrack_expect_help {
-	/* insert conntrack helper private data (expect) here */
-	struct ip_ct_amanda_expect exp_amanda_info;
-	struct ip_ct_ftp_expect exp_ftp_info;
-	struct ip_ct_irc_expect exp_irc_info;
-
-#ifdef CONFIG_IP_NF_NAT_NEEDED
-	union {
-		/* insert nat helper private data (expect) here */
-	} nat;
-#endif
-};
-
 /* per conntrack: application helper private data */
 union ip_conntrack_help {
 	/* insert conntrack helper private data (master) here */
@@ -93,15 +104,8 @@
 
 #ifdef CONFIG_IP_NF_NAT_NEEDED
 #include <linux/netfilter_ipv4/ip_nat.h>
-
-/* per conntrack: nat application helper private data */
-union ip_conntrack_nat_help {
-	/* insert nat helper private data here */
-};
 #endif
 
-#ifdef __KERNEL__
-
 #include <linux/types.h>
 #include <linux/skbuff.h>
 
@@ -118,46 +122,6 @@
 #define IP_NF_ASSERT(x)
 #endif
 
-struct ip_conntrack_expect
-{
-	/* Internal linked list (global expectation list) */
-	struct list_head list;
-
-	/* reference count */
-	atomic_t use;
-
-	/* expectation list for this master */
-	struct list_head expected_list;
-
-	/* The conntrack of the master connection */
-	struct ip_conntrack *expectant;
-
-	/* The conntrack of the sibling connection, set after
-	 * expectation arrived */
-	struct ip_conntrack *sibling;
-
-	/* Tuple saved for conntrack */
-	struct ip_conntrack_tuple ct_tuple;
-
-	/* Timer function; deletes the expectation. */
-	struct timer_list timeout;
-
-	/* Data filled out by the conntrack helpers follow: */
-
-	/* We expect this tuple, with the following mask */
-	struct ip_conntrack_tuple tuple, mask;
-
-	/* Function to call after setup and insertion */
-	int (*expectfn)(struct ip_conntrack *new);
-
-	/* At which sequence number did this expectation occur */
-	u_int32_t seq;
-  
-	union ip_conntrack_expect_proto proto;
-
-	union ip_conntrack_expect_help help;
-};
-
 struct ip_conntrack_counter
 {
 	u_int64_t packets;
@@ -182,17 +146,12 @@
 	/* Accounting Information (same cache line as other written members) */
 	struct ip_conntrack_counter counters[IP_CT_DIR_MAX];
 #endif
+	/* If we were expected by an expectation, this will be it */
+	struct ip_conntrack *master;
 
-	/* If we're expecting another related connection, this will be
-           in expected linked list */
-	struct list_head sibling_list;
-	
 	/* Current number of expected connections */
 	unsigned int expecting;
 
-	/* If we were expected by an expectation, this will be it */
-	struct ip_conntrack_expect *master;
-
 	/* Helper, if any. */
 	struct ip_conntrack_helper *helper;
 
@@ -204,7 +163,6 @@
 #ifdef CONFIG_IP_NF_NAT_NEEDED
 	struct {
 		struct ip_nat_info info;
-		union ip_conntrack_nat_help help;
 #if defined(CONFIG_IP_NF_TARGET_MASQUERADE) || \
 	defined(CONFIG_IP_NF_TARGET_MASQUERADE_MODULE)
 		int masq_index;
@@ -221,12 +179,45 @@
 	struct ip_conntrack_tuple_hash tuplehash[IP_CT_DIR_MAX];
 };
 
+struct ip_conntrack_expect
+{
+	/* Internal linked list (global expectation list) */
+	struct list_head list;
+
+	/* We expect this tuple, with the following mask */
+	struct ip_conntrack_tuple tuple, mask;
+ 
+	/* Function to call after setup and insertion */
+	void (*expectfn)(struct ip_conntrack *new,
+			 struct ip_conntrack_expect *this);
+
+	/* The conntrack of the master connection */
+	struct ip_conntrack *master;
+
+	/* Timer function; deletes the expectation. */
+	struct timer_list timeout;
+
+#ifdef CONFIG_IP_NF_NAT_NEEDED
+	/* This is the original per-proto part, used to map the
+	 * expected connection the way the recipient expects. */
+	union ip_conntrack_manip_proto saved_proto;
+	/* Direction relative to the master connection. */
+	enum ip_conntrack_dir dir;
+#endif
+};
+
+static inline struct ip_conntrack *
+tuplehash_to_ctrack(const struct ip_conntrack_tuple_hash *hash)
+{
+	return container_of(hash, struct ip_conntrack,
+			    tuplehash[hash->tuple.dst.dir]);
+}
+
 /* get master conntrack via master expectation */
-#define master_ct(conntr) (conntr->master ? conntr->master->expectant : NULL)
+#define master_ct(conntr) (conntr->master)
 
-/* Alter reply tuple (maybe alter helper).  If it's already taken,
-   return 0 and don't do alteration. */
-extern int
+/* Alter reply tuple (maybe alter helper). */
+extern void
 ip_conntrack_alter_reply(struct ip_conntrack *conntrack,
 			 const struct ip_conntrack_tuple *newreply);
 
@@ -247,13 +238,6 @@
 /* decrement reference count on a conntrack */
 extern inline void ip_conntrack_put(struct ip_conntrack *ct);
 
-/* find unconfirmed expectation based on tuple */
-struct ip_conntrack_expect *
-ip_conntrack_expect_find_get(const struct ip_conntrack_tuple *tuple);
-
-/* decrement reference count on an expectation */
-void ip_conntrack_expect_put(struct ip_conntrack_expect *exp);
-
 /* call to create an explicit dependency on ip_conntrack. */
 extern void need_ip_conntrack(void);
 
@@ -268,9 +252,9 @@
 
 /* These are for NAT.  Icky. */
 /* Update TCP window tracking data when NAT mangles the packet */
-extern int ip_conntrack_tcp_update(struct sk_buff *skb,
-				   struct ip_conntrack *conntrack,
-				   int dir);
+extern void ip_conntrack_tcp_update(struct sk_buff *skb,
+				    struct ip_conntrack *conntrack,
+				    enum ip_conntrack_dir dir);
 
 /* Call me when a conntrack is destroyed. */
 extern void (*ip_conntrack_destroyed)(struct ip_conntrack *conntrack);
@@ -278,15 +262,14 @@
 /* Fake conntrack entry for untracked connections */
 extern struct ip_conntrack ip_conntrack_untracked;
 
-extern int ip_ct_no_defrag;
 /* Returns new sk_buff, or NULL */
 struct sk_buff *
-ip_ct_gather_frags(struct sk_buff *skb);
+ip_ct_gather_frags(struct sk_buff *skb, u_int32_t user);
 
-/* Delete all conntracks which match. */
+/* Iterate over all conntracks: if iter returns true, it's deleted. */
 extern void
-ip_ct_selective_cleanup(int (*kill)(const struct ip_conntrack *i, void *data),
-			void *data);
+ip_ct_iterate_cleanup(int (*iter)(struct ip_conntrack *i, void *data),
+		      void *data);
 
 /* It's confirmed if it is, or has been in the hash table. */
 static inline int is_confirmed(struct ip_conntrack *ct)
@@ -317,15 +300,15 @@
 
 #define CONNTRACK_STAT_INC(count) (__get_cpu_var(ip_conntrack_stat).count++)
 
-/* eg. PROVIDES_CONNTRACK(ftp); */
-#define PROVIDES_CONNTRACK(name)                        \
-        int needs_ip_conntrack_##name;                  \
-        EXPORT_SYMBOL(needs_ip_conntrack_##name)
-
-/*. eg. NEEDS_CONNTRACK(ftp); */
-#define NEEDS_CONNTRACK(name)                                           \
-        extern int needs_ip_conntrack_##name;                           \
-        static int *need_ip_conntrack_##name __attribute_used__ = &needs_ip_conntrack_##name
+#ifdef CONFIG_IP_NF_NAT_NEEDED
+static inline int ip_nat_initialized(struct ip_conntrack *conntrack,
+				     enum ip_nat_manip_type manip)
+{
+	if (manip == IP_NAT_MANIP_SRC)
+		return test_bit(IPS_SRC_NAT_DONE_BIT, &conntrack->status);
+	return test_bit(IPS_DST_NAT_DONE_BIT, &conntrack->status);
+}
+#endif /* CONFIG_IP_NF_NAT_NEEDED */
 
 #endif /* __KERNEL__ */
 #endif /* _IP_CONNTRACK_H */
diff -Nru a/include/linux/netfilter_ipv4/ip_conntrack_amanda.h b/include/linux/netfilter_ipv4/ip_conntrack_amanda.h
--- a/include/linux/netfilter_ipv4/ip_conntrack_amanda.h	2005-03-01 23:38:52 -08:00
+++ b/include/linux/netfilter_ipv4/ip_conntrack_amanda.h	2005-03-01 23:38:52 -08:00
@@ -2,11 +2,10 @@
 #define _IP_CONNTRACK_AMANDA_H
 /* AMANDA tracking. */
 
-struct ip_ct_amanda_expect
-{
-	u_int16_t port;		/* port number of this expectation */
-	u_int16_t offset;	/* offset of port in ctrl packet */
-	u_int16_t len;		/* length of the port number string */
-};
-
+struct ip_conntrack_expect;
+extern unsigned int (*ip_nat_amanda_hook)(struct sk_buff **pskb,
+					  enum ip_conntrack_info ctinfo,
+					  unsigned int matchoff,
+					  unsigned int matchlen,
+					  struct ip_conntrack_expect *exp);
 #endif /* _IP_CONNTRACK_AMANDA_H */
diff -Nru 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	2005-03-01 23:39:17 -08:00
+++ b/include/linux/netfilter_ipv4/ip_conntrack_core.h	2005-03-01 23:39:17 -08:00
@@ -34,20 +34,19 @@
 ip_conntrack_find_get(const struct ip_conntrack_tuple *tuple,
 		      const struct ip_conntrack *ignored_conntrack);
 
-extern int __ip_conntrack_confirm(struct sk_buff *skb);
+extern int __ip_conntrack_confirm(struct sk_buff **pskb);
 
 /* Confirm a connection: returns NF_DROP if packet must be dropped. */
-static inline int ip_conntrack_confirm(struct sk_buff *skb)
+static inline int ip_conntrack_confirm(struct sk_buff **pskb)
 {
-	if (skb->nfct
-	    && !is_confirmed((struct ip_conntrack *)skb->nfct))
-		return __ip_conntrack_confirm(skb);
+	if ((*pskb)->nfct
+	    && !is_confirmed((struct ip_conntrack *)(*pskb)->nfct))
+		return __ip_conntrack_confirm(pskb);
 	return NF_ACCEPT;
 }
 
 extern struct list_head *ip_conntrack_hash;
 extern struct list_head ip_conntrack_expect_list;
 DECLARE_RWLOCK_EXTERN(ip_conntrack_lock);
-DECLARE_RWLOCK_EXTERN(ip_conntrack_expect_tuple_lock);
 #endif /* _IP_CONNTRACK_CORE_H */
 
diff -Nru a/include/linux/netfilter_ipv4/ip_conntrack_ftp.h b/include/linux/netfilter_ipv4/ip_conntrack_ftp.h
--- a/include/linux/netfilter_ipv4/ip_conntrack_ftp.h	2005-03-01 23:39:18 -08:00
+++ b/include/linux/netfilter_ipv4/ip_conntrack_ftp.h	2005-03-01 23:39:18 -08:00
@@ -20,24 +20,24 @@
 	IP_CT_FTP_EPSV,
 };
 
-/* This structure is per expected connection */
-struct ip_ct_ftp_expect
-{
-	/* We record seq number and length of ftp ip/port text here: all in
-	 * host order. */
-
- 	/* sequence number of IP address in packet is in ip_conntrack_expect */
-	u_int32_t len;			/* length of IP address */
-	enum ip_ct_ftp_type ftptype;	/* PORT or PASV ? */
-	u_int16_t port; 		/* TCP port that was to be used */
-};
-
+#define NUM_SEQ_TO_REMEMBER 2
 /* This structure exists only once per master */
 struct ip_ct_ftp_master {
-	/* Next valid seq position for cmd matching after newline */
-	u_int32_t seq_aft_nl[IP_CT_DIR_MAX];
+	/* Valid seq positions for cmd matching after newline */
+	u_int32_t seq_aft_nl[IP_CT_DIR_MAX][NUM_SEQ_TO_REMEMBER];
 	/* 0 means seq_match_aft_nl not set */
-	int seq_aft_nl_set[IP_CT_DIR_MAX];
+	int seq_aft_nl_num[IP_CT_DIR_MAX];
 };
 
+struct ip_conntrack_expect;
+
+/* For NAT to hook in when we find a packet which describes what other
+ * connection we should expect. */
+extern unsigned int (*ip_nat_ftp_hook)(struct sk_buff **pskb,
+				       enum ip_conntrack_info ctinfo,
+				       enum ip_ct_ftp_type type,
+				       unsigned int matchoff,
+				       unsigned int matchlen,
+				       struct ip_conntrack_expect *exp,
+				       u32 *seq);
 #endif /* _IP_CONNTRACK_FTP_H */
diff -Nru 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	2005-03-01 23:38:53 -08:00
+++ b/include/linux/netfilter_ipv4/ip_conntrack_helper.h	2005-03-01 23:38:53 -08:00
@@ -5,15 +5,11 @@
 
 struct module;
 
-/* Reuse expectation when max_expected reached */
-#define IP_CT_HELPER_F_REUSE_EXPECT	0x01
-
 struct ip_conntrack_helper
 {	
 	struct list_head list; 		/* Internal use. */
 
 	const char *name;		/* name of the module */
-	unsigned char flags;		/* Flags (see above) */
 	struct module *me;		/* pointer to self */
 	unsigned int max_expected;	/* Maximum number of concurrent 
 					 * expected connections */
@@ -25,7 +21,7 @@
 	
 	/* Function to call when data passes; return verdict, or -1 to
            invalidate. */
-	int (*help)(struct sk_buff *skb,
+	int (*help)(struct sk_buff **pskb,
 		    struct ip_conntrack *ct,
 		    enum ip_conntrack_info conntrackinfo);
 };
@@ -33,17 +29,13 @@
 extern int ip_conntrack_helper_register(struct ip_conntrack_helper *);
 extern void ip_conntrack_helper_unregister(struct ip_conntrack_helper *);
 
-extern struct ip_conntrack_helper *ip_ct_find_helper(const struct ip_conntrack_tuple *tuple);
-
-
 /* 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);
+
 /* Add an expected connection: can have more than one per connection */
-extern int ip_conntrack_expect_related(struct ip_conntrack_expect *exp,
-				       struct ip_conntrack *related_to);
-extern int ip_conntrack_change_expect(struct ip_conntrack_expect *expect,
-				      struct ip_conntrack_tuple *newtuple);
+extern int ip_conntrack_expect_related(struct ip_conntrack_expect *exp);
 extern void ip_conntrack_unexpect_related(struct ip_conntrack_expect *exp);
 
 #endif /*_IP_CONNTRACK_HELPER_H*/
diff -Nru a/include/linux/netfilter_ipv4/ip_conntrack_irc.h b/include/linux/netfilter_ipv4/ip_conntrack_irc.h
--- a/include/linux/netfilter_ipv4/ip_conntrack_irc.h	2005-03-01 23:39:18 -08:00
+++ b/include/linux/netfilter_ipv4/ip_conntrack_irc.h	2005-03-01 23:39:18 -08:00
@@ -14,24 +14,16 @@
 #ifndef _IP_CONNTRACK_IRC_H
 #define _IP_CONNTRACK_IRC_H
 
-/* We record seq number and length of irc ip/port text here: all in
-   host order. */
-
-/* This structure is per expected connection */
-struct ip_ct_irc_expect
-{
-	/* length of IP address */
-	u_int32_t len;
-	/* Port that was to be used */
-	u_int16_t port;
-};
-
 /* This structure exists only once per master */
 struct ip_ct_irc_master {
 };
 
-
 #ifdef __KERNEL__
+extern unsigned int (*ip_nat_irc_hook)(struct sk_buff **pskb,
+				       enum ip_conntrack_info ctinfo,
+				       unsigned int matchoff,
+				       unsigned int matchlen,
+				       struct ip_conntrack_expect *exp);
 
 #define IRC_PORT	6667
 
diff -Nru a/include/linux/netfilter_ipv4/ip_conntrack_protocol.h b/include/linux/netfilter_ipv4/ip_conntrack_protocol.h
--- a/include/linux/netfilter_ipv4/ip_conntrack_protocol.h	2005-03-01 23:39:16 -08:00
+++ b/include/linux/netfilter_ipv4/ip_conntrack_protocol.h	2005-03-01 23:39:16 -08:00
@@ -44,10 +44,6 @@
 	/* Called when a conntrack entry is destroyed */
 	void (*destroy)(struct ip_conntrack *conntrack);
 
-	/* Has to decide if a expectation matches one packet or not */
-	int (*exp_matches_pkt)(struct ip_conntrack_expect *exp,
-			       const struct sk_buff *skb);
-
 	int (*error)(struct sk_buff *skb, enum ip_conntrack_info *ctinfo,
 		     unsigned int hooknum);
 
diff -Nru a/include/linux/netfilter_ipv4/ip_conntrack_tcp.h b/include/linux/netfilter_ipv4/ip_conntrack_tcp.h
--- a/include/linux/netfilter_ipv4/ip_conntrack_tcp.h	2005-03-01 23:38:55 -08:00
+++ b/include/linux/netfilter_ipv4/ip_conntrack_tcp.h	2005-03-01 23:38:55 -08:00
@@ -41,6 +41,7 @@
 	u_int8_t	retrans;	/* Number of retransmitted packets */
 	u_int8_t	last_index;	/* Index of the last packet */
 	u_int32_t	last_seq;	/* Last sequence number seen in dir */
+	u_int32_t	last_ack;	/* Last sequence number seen in opposite dir */
 	u_int32_t	last_end;	/* Last seq + len */
 };
 
diff -Nru a/include/linux/netfilter_ipv4/ip_conntrack_tftp.h b/include/linux/netfilter_ipv4/ip_conntrack_tftp.h
--- a/include/linux/netfilter_ipv4/ip_conntrack_tftp.h	2005-03-01 23:38:54 -08:00
+++ b/include/linux/netfilter_ipv4/ip_conntrack_tftp.h	2005-03-01 23:38:54 -08:00
@@ -13,4 +13,8 @@
 #define TFTP_OPCODE_ACK		4
 #define TFTP_OPCODE_ERROR	5
 
+extern unsigned int (*ip_nat_tftp_hook)(struct sk_buff **pskb,
+				 enum ip_conntrack_info ctinfo,
+				 struct ip_conntrack_expect *exp);
+
 #endif /* _IP_CT_TFTP */
diff -Nru a/include/linux/netfilter_ipv4/ip_conntrack_tuple.h b/include/linux/netfilter_ipv4/ip_conntrack_tuple.h
--- a/include/linux/netfilter_ipv4/ip_conntrack_tuple.h	2005-03-01 23:39:08 -08:00
+++ b/include/linux/netfilter_ipv4/ip_conntrack_tuple.h	2005-03-01 23:39:08 -08:00
@@ -64,7 +64,10 @@
 		} u;
 
 		/* The protocol. */
-		u_int16_t protonum;
+		u_int8_t protonum;
+
+		/* The direction (for tuplehash) */
+		u_int8_t dir;
 	} dst;
 };
 
@@ -94,7 +97,7 @@
 #define CTINFO2DIR(ctinfo) ((ctinfo) >= IP_CT_IS_REPLY ? IP_CT_DIR_REPLY : IP_CT_DIR_ORIGINAL)
 
 /* If we're the first tuple, it's the original dir. */
-#define DIRECTION(h) ((enum ip_conntrack_dir)(&(h)->ctrack->tuplehash[1] == (h)))
+#define DIRECTION(h) ((enum ip_conntrack_dir)(h)->tuple.dst.dir)
 
 /* Connections have two entries in the hash table: one for each way */
 struct ip_conntrack_tuple_hash
@@ -102,9 +105,6 @@
 	struct list_head list;
 
 	struct ip_conntrack_tuple tuple;
-
-	/* this == &ctrack->tuplehash[DIRECTION(this)]. */
-	struct ip_conntrack *ctrack;
 };
 
 #endif /* __KERNEL__ */
diff -Nru a/include/linux/netfilter_ipv4/ip_nat.h b/include/linux/netfilter_ipv4/ip_nat.h
--- a/include/linux/netfilter_ipv4/ip_nat.h	2005-03-01 23:39:17 -08:00
+++ b/include/linux/netfilter_ipv4/ip_nat.h	2005-03-01 23:39:17 -08:00
@@ -11,18 +11,11 @@
 	IP_NAT_MANIP_DST
 };
 
-#ifndef CONFIG_IP_NF_NAT_LOCAL
-/* SRC manip occurs only on POST_ROUTING */
-#define HOOK2MANIP(hooknum) ((hooknum) != NF_IP_POST_ROUTING)
-#else
 /* SRC manip occurs POST_ROUTING or LOCAL_IN */
 #define HOOK2MANIP(hooknum) ((hooknum) != NF_IP_POST_ROUTING && (hooknum) != NF_IP_LOCAL_IN)
-#endif
 
 #define IP_NAT_RANGE_MAP_IPS 1
 #define IP_NAT_RANGE_PROTO_SPECIFIED 2
-/* Used internally by get_unique_tuple(). */
-#define IP_NAT_RANGE_FULL 4
 
 /* NAT sequence number modifications */
 struct ip_nat_seq {
@@ -46,33 +39,15 @@
 	union ip_conntrack_manip_proto min, max;
 };
 
-/* A range consists of an array of 1 or more ip_nat_range */
-struct ip_nat_multi_range
+/* For backwards compat: don't use in modern code. */
+struct ip_nat_multi_range_compat
 {
-	unsigned int rangesize;
+	unsigned int rangesize; /* Must be 1. */
 
 	/* hangs off end. */
 	struct ip_nat_range range[1];
 };
 
-/* Worst case: local-out manip + 1 post-routing, and reverse dirn. */
-#define IP_NAT_MAX_MANIPS (2*3)
-
-struct ip_nat_info_manip
-{
-	/* The direction. */
-	u_int8_t direction;
-
-	/* Which hook the manipulation happens on. */
-	u_int8_t hooknum;
-
-	/* The manipulation type. */
-	u_int8_t maniptype;
-
-	/* Manipulations to occur at each conntrack in this dirn. */
-	struct ip_conntrack_manip manip;
-};
-
 #ifdef __KERNEL__
 #include <linux/list.h>
 #include <linux/netfilter_ipv4/lockhelp.h>
@@ -83,15 +58,7 @@
 /* The structure embedded in the conntrack structure. */
 struct ip_nat_info
 {
-	/* Set to zero when conntrack created: bitmask of maniptypes */
-	u_int16_t initialized;
-
-	u_int16_t num_manips;
-
-	/* Manipulations to be done on this conntrack. */
-	struct ip_nat_info_manip manips[IP_NAT_MAX_MANIPS];
-
-	struct list_head bysource, byipsproto;
+	struct list_head bysource;
 
 	/* Helper (NULL if none). */
 	struct ip_nat_helper *helper;
@@ -99,9 +66,11 @@
 	struct ip_nat_seq seq[IP_CT_DIR_MAX];
 };
 
+struct ip_conntrack;
+
 /* Set up the info structure to map into this range. */
 extern unsigned int ip_nat_setup_info(struct ip_conntrack *conntrack,
-				      const struct ip_nat_multi_range *mr,
+				      const struct ip_nat_range *range,
 				      unsigned int hooknum);
 
 /* Is this tuple already taken? (not by us)*/
@@ -112,5 +81,7 @@
 extern u_int16_t ip_nat_cheat_check(u_int32_t oldvalinv,
 				    u_int32_t newval,
 				    u_int16_t oldcheck);
+#else  /* !__KERNEL__: iptables wants this to compile. */
+#define ip_nat_multi_range ip_nat_multi_range_compat
 #endif /*__KERNEL__*/
 #endif
diff -Nru a/include/linux/netfilter_ipv4/ip_nat_core.h b/include/linux/netfilter_ipv4/ip_nat_core.h
--- a/include/linux/netfilter_ipv4/ip_nat_core.h	2005-03-01 23:38:44 -08:00
+++ b/include/linux/netfilter_ipv4/ip_nat_core.h	2005-03-01 23:38:44 -08:00
@@ -8,20 +8,13 @@
 extern int ip_nat_init(void);
 extern void ip_nat_cleanup(void);
 
-extern unsigned int do_bindings(struct ip_conntrack *ct,
-				enum ip_conntrack_info conntrackinfo,
-				struct ip_nat_info *info,
-				unsigned int hooknum,
-				struct sk_buff **pskb);
+extern unsigned int nat_packet(struct ip_conntrack *ct,
+			       enum ip_conntrack_info conntrackinfo,
+			       unsigned int hooknum,
+			       struct sk_buff **pskb);
 
 extern int icmp_reply_translation(struct sk_buff **pskb,
-				  struct ip_conntrack *conntrack,
-				  unsigned int hooknum,
-				  int dir);
-
-extern void replace_in_hashes(struct ip_conntrack *conntrack,
-			      struct ip_nat_info *info);
-extern void place_in_hashes(struct ip_conntrack *conntrack,
-			    struct ip_nat_info *info);
-
+				  struct ip_conntrack *ct,
+				  enum ip_nat_manip_type manip,
+				  enum ip_conntrack_dir dir);
 #endif /* _IP_NAT_CORE_H */
diff -Nru a/include/linux/netfilter_ipv4/ip_nat_helper.h b/include/linux/netfilter_ipv4/ip_nat_helper.h
--- a/include/linux/netfilter_ipv4/ip_nat_helper.h	2005-03-01 23:38:54 -08:00
+++ b/include/linux/netfilter_ipv4/ip_nat_helper.h	2005-03-01 23:38:54 -08:00
@@ -7,46 +7,6 @@
 
 struct sk_buff;
 
-/* Flags */
-/* NAT helper must be called on every packet (for TCP) */
-#define IP_NAT_HELPER_F_ALWAYS		0x01
-
-struct ip_nat_helper
-{
-	struct list_head list;		/* Internal use */
-
-	const char *name;		/* name of the module */
-	unsigned char flags;		/* Flags (see above) */
-	struct module *me;		/* pointer to self */
-	
-	/* Mask of things we will help: vs. tuple from server */
-	struct ip_conntrack_tuple tuple;
-	struct ip_conntrack_tuple mask;
-	
-	/* Helper function: returns verdict */
-	unsigned int (*help)(struct ip_conntrack *ct,
-			     struct ip_conntrack_expect *exp,
-			     struct ip_nat_info *info,
-			     enum ip_conntrack_info ctinfo,
-			     unsigned int hooknum,
-			     struct sk_buff **pskb);
-
-	/* Returns verdict and sets up NAT for this connection */
-	unsigned int (*expect)(struct sk_buff **pskb,
-			       unsigned int hooknum,
-			       struct ip_conntrack *ct,
-			       struct ip_nat_info *info);
-};
-
-extern int ip_nat_helper_register(struct ip_nat_helper *me);
-extern void ip_nat_helper_unregister(struct ip_nat_helper *me);
-
-extern struct ip_nat_helper *
-ip_nat_find_helper(const struct ip_conntrack_tuple *tuple);
-
-extern struct ip_nat_helper *
-__ip_nat_find_helper(const struct ip_conntrack_tuple *tuple);
-
 /* These return true or false. */
 extern int ip_nat_mangle_tcp_packet(struct sk_buff **skb,
 				struct ip_conntrack *ct,
@@ -65,4 +25,9 @@
 extern int ip_nat_seq_adjust(struct sk_buff **pskb, 
 			     struct ip_conntrack *ct, 
 			     enum ip_conntrack_info ctinfo);
+
+/* Setup NAT on this expected conntrack so it follows master, but goes
+ * to port ct->master->saved_proto. */
+extern void ip_nat_follow_master(struct ip_conntrack *ct,
+				 struct ip_conntrack_expect *this);
 #endif
diff -Nru a/include/linux/netfilter_ipv4/ip_nat_protocol.h b/include/linux/netfilter_ipv4/ip_nat_protocol.h
--- a/include/linux/netfilter_ipv4/ip_nat_protocol.h	2005-03-01 23:38:58 -08:00
+++ b/include/linux/netfilter_ipv4/ip_nat_protocol.h	2005-03-01 23:38:58 -08:00
@@ -15,11 +15,11 @@
 	/* Protocol number. */
 	unsigned int protonum;
 
-	/* Do a packet translation according to the ip_nat_proto_manip
-	 * and manip type.  Return true if succeeded. */
+	/* Translate a packet to the target according to manip type.
+	   Return true if succeeded. */
 	int (*manip_pkt)(struct sk_buff **pskb,
 			 unsigned int iphdroff,
-			 const struct ip_conntrack_manip *manip,
+			 const struct ip_conntrack_tuple *tuple,
 			 enum ip_nat_manip_type maniptype);
 
 	/* Is the manipable part of the tuple between min and max incl? */
diff -Nru a/include/linux/netfilter_ipv4/ip_tables.h b/include/linux/netfilter_ipv4/ip_tables.h
--- a/include/linux/netfilter_ipv4/ip_tables.h	2005-03-01 23:38:58 -08:00
+++ b/include/linux/netfilter_ipv4/ip_tables.h	2005-03-01 23:38:58 -08:00
@@ -53,7 +53,9 @@
 			u_int16_t match_size;
 
 			/* Used by userspace */
-			char name[IPT_FUNCTION_MAXNAMELEN];
+			char name[IPT_FUNCTION_MAXNAMELEN-1];
+
+			u_int8_t revision;
 		} user;
 		struct {
 			u_int16_t match_size;
@@ -76,7 +78,9 @@
 			u_int16_t target_size;
 
 			/* Used by userspace */
-			char name[IPT_FUNCTION_MAXNAMELEN];
+			char name[IPT_FUNCTION_MAXNAMELEN-1];
+
+			u_int8_t revision;
 		} user;
 		struct {
 			u_int16_t target_size;
@@ -152,9 +156,11 @@
 #define IPT_SO_SET_ADD_COUNTERS	(IPT_BASE_CTL + 1)
 #define IPT_SO_SET_MAX		IPT_SO_SET_ADD_COUNTERS
 
-#define IPT_SO_GET_INFO		(IPT_BASE_CTL)
-#define IPT_SO_GET_ENTRIES	(IPT_BASE_CTL + 1)
-#define IPT_SO_GET_MAX		IPT_SO_GET_ENTRIES
+#define IPT_SO_GET_INFO			(IPT_BASE_CTL)
+#define IPT_SO_GET_ENTRIES		(IPT_BASE_CTL + 1)
+#define IPT_SO_GET_REVISION_MATCH	(IPT_BASE_CTL + 2)
+#define IPT_SO_GET_REVISION_TARGET	(IPT_BASE_CTL + 3)
+#define IPT_SO_GET_MAX			IPT_SO_GET_REVISION_TARGET
 
 /* CONTINUE verdict for targets */
 #define IPT_CONTINUE 0xFFFFFFFF
@@ -284,6 +290,15 @@
 	struct ipt_entry entrytable[0];
 };
 
+/* The argument to IPT_SO_GET_REVISION_*.  Returns highest revision
+ * kernel supports, if >= revision. */
+struct ipt_get_revision
+{
+	char name[IPT_FUNCTION_MAXNAMELEN-1];
+
+	u_int8_t revision;
+};
+
 /* Standard return verdict, or do jump. */
 #define IPT_STANDARD_TARGET ""
 /* Error verdict. */
@@ -344,7 +359,9 @@
 {
 	struct list_head list;
 
-	const char name[IPT_FUNCTION_MAXNAMELEN];
+	const char name[IPT_FUNCTION_MAXNAMELEN-1];
+
+	u_int8_t revision;
 
 	/* Return true or false: return FALSE and set *hotdrop = 1 to
            force immediate packet drop. */
@@ -378,7 +395,9 @@
 {
 	struct list_head list;
 
-	const char name[IPT_FUNCTION_MAXNAMELEN];
+	const char name[IPT_FUNCTION_MAXNAMELEN-1];
+
+	u_int8_t revision;
 
 	/* Called when user tries to insert an entry of this type:
            hook_mask is a bitmask of hooks from which it can be
@@ -413,10 +432,6 @@
 extern int ipt_register_match(struct ipt_match *match);
 extern void ipt_unregister_match(struct ipt_match *match);
 
-extern struct ipt_target *
-__ipt_find_target_lock(const char *name, int *error);
-extern void __ipt_mutex_up(void);
-
 /* Furniture shopping... */
 struct ipt_table
 {
@@ -425,9 +440,6 @@
 	/* A unique name... */
 	char name[IPT_TABLE_MAXNAMELEN];
 
-	/* Seed table: copied in register_table */
-	struct ipt_replace *table;
-
 	/* What hooks you will enter on */
 	unsigned int valid_hooks;
 
@@ -441,7 +453,30 @@
 	struct module *me;
 };
 
-extern int ipt_register_table(struct ipt_table *table);
+/* net/sched/ipt.c: Gimme access to your targets!  Gets target->me. */
+extern struct ipt_target *ipt_find_target(const char *name, u8 revision);
+
+/* Standard entry. */
+struct ipt_standard
+{
+	struct ipt_entry entry;
+	struct ipt_standard_target target;
+};
+
+struct ipt_error_target
+{
+	struct ipt_entry_target target;
+	char errorname[IPT_FUNCTION_MAXNAMELEN];
+};
+
+struct ipt_error
+{
+	struct ipt_entry entry;
+	struct ipt_error_target target;
+};
+
+extern int ipt_register_table(struct ipt_table *table,
+			      const struct ipt_replace *repl);
 extern void ipt_unregister_table(struct ipt_table *table);
 extern unsigned int ipt_do_table(struct sk_buff **pskb,
 				 unsigned int hook,
diff -Nru a/include/linux/netfilter_ipv4/ipchains_core.h b/include/linux/netfilter_ipv4/ipchains_core.h
--- a/include/linux/netfilter_ipv4/ipchains_core.h	2005-03-01 23:38:57 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,189 +0,0 @@
-/*
- * This code is heavily based on the code in ip_fw.h; see that file for
- * copyrights and attributions.  This code is basically GPL.
- *
- * 15-Feb-1997: Major changes to allow graphs for firewall rules.
- *              Paul Russell <Paul.Russell@rustcorp.com.au> and
- *		Michael Neuling <Michael.Neuling@rustcorp.com.au>
- * 2-Nov-1997: Changed types to __u16, etc.
- *             Removed IP_FW_F_TCPACK & IP_FW_F_BIDIR.
- *             Added inverse flags field.
- *             Removed multiple port specs.
- */
-
-/*
- * 	Format of an IP firewall descriptor
- *
- * 	src, dst, src_mask, dst_mask are always stored in network byte order.
- * 	flags are stored in host byte order (of course).
- * 	Port numbers are stored in HOST byte order.
- */
-
-#ifndef _IP_FWCHAINS_H
-#define _IP_FWCHAINS_H
-
-#ifdef __KERNEL__
-#include <linux/icmp.h>
-#include <linux/in.h>
-#include <linux/ip.h>
-#include <linux/tcp.h>
-#include <linux/udp.h>
-#endif /* __KERNEL__ */
-#define IP_FW_MAX_LABEL_LENGTH 8
-typedef char ip_chainlabel[IP_FW_MAX_LABEL_LENGTH+1];
-
-struct ip_fw
-{
-	struct in_addr fw_src, fw_dst;		/* Source and destination IP addr */
-	struct in_addr fw_smsk, fw_dmsk;	/* Mask for src and dest IP addr */
-	__u32 fw_mark;                          /* ID to stamp on packet */
-	__u16 fw_proto;                         /* Protocol, 0 = ANY */
-	__u16 fw_flg;			        /* Flags word */
-        __u16 fw_invflg;                        /* Inverse flags */
-	__u16 fw_spts[2];                       /* Source port range. */
-        __u16 fw_dpts[2];                       /* Destination port range. */
-	__u16 fw_redirpt;                       /* Port to redirect to. */
-	__u16 fw_outputsize;                    /* Max amount to output to
-						   NETLINK */
-	char           fw_vianame[IFNAMSIZ];	/* name of interface "via" */
-	__u8           fw_tosand, fw_tosxor;	/* Revised packet priority */
-};
-
-struct ip_fwuser
-{
-	struct ip_fw ipfw;
-	ip_chainlabel label;
-};
-
-/* Values for "fw_flg" field .  */
-#define IP_FW_F_PRN	0x0001	/* Print packet if it matches */
-#define IP_FW_F_TCPSYN	0x0002	/* For tcp packets-check SYN only */
-#define IP_FW_F_FRAG	0x0004  /* Set if rule is a fragment rule */
-#define IP_FW_F_MARKABS	0x0008  /* Set the mark to fw_mark, not add. */
-#define IP_FW_F_WILDIF	0x0010  /* Need only match start of interface name. */
-#define IP_FW_F_NETLINK 0x0020  /* Redirect to netlink: 2.1.x only */
-#define IP_FW_F_MASK	0x003F	/* All possible flag bits mask   */
-
-/* Values for "fw_invflg" field. */
-#define IP_FW_INV_SRCIP 0x0001  /* Invert the sense of fw_src. */
-#define IP_FW_INV_DSTIP 0x0002  /* Invert the sense of fw_dst. */
-#define IP_FW_INV_PROTO 0x0004  /* Invert the sense of fw_proto. */
-#define IP_FW_INV_SRCPT 0x0008  /* Invert the sense of source ports. */
-#define IP_FW_INV_DSTPT 0x0010  /* Invert the sense of destination ports. */
-#define IP_FW_INV_VIA   0x0020  /* Invert the sense of fw_vianame. */
-#define IP_FW_INV_SYN   0x0040  /* Invert the sense of IP_FW_F_TCPSYN. */
-#define IP_FW_INV_FRAG  0x0080  /* Invert the sense of IP_FW_F_FRAG. */
-
-/*
- *	New IP firewall options for [gs]etsockopt at the RAW IP level.
- *	Unlike BSD Linux inherits IP options so you don't have to use
- * a raw socket for this. Instead we check rights in the calls.  */
-
-#define IP_FW_BASE_CTL  	64	/* base for firewall socket options */
-
-#define IP_FW_APPEND		(IP_FW_BASE_CTL)    /* Takes ip_fwchange */
-#define IP_FW_REPLACE		(IP_FW_BASE_CTL+1)  /* Takes ip_fwnew */
-#define IP_FW_DELETE_NUM	(IP_FW_BASE_CTL+2)  /* Takes ip_fwdelnum */
-#define IP_FW_DELETE		(IP_FW_BASE_CTL+3)  /* Takes ip_fwchange */
-#define IP_FW_INSERT		(IP_FW_BASE_CTL+4)  /* Takes ip_fwnew */
-#define IP_FW_FLUSH		(IP_FW_BASE_CTL+5)  /* Takes ip_chainlabel */
-#define IP_FW_ZERO		(IP_FW_BASE_CTL+6)  /* Takes ip_chainlabel */
-#define IP_FW_CHECK		(IP_FW_BASE_CTL+7)  /* Takes ip_fwtest */
-#define IP_FW_MASQ_TIMEOUTS	(IP_FW_BASE_CTL+8)  /* Takes 3 ints */
-#define IP_FW_CREATECHAIN	(IP_FW_BASE_CTL+9)  /* Takes ip_chainlabel */
-#define IP_FW_DELETECHAIN	(IP_FW_BASE_CTL+10) /* Takes ip_chainlabel */
-#define IP_FW_POLICY		(IP_FW_BASE_CTL+11) /* Takes ip_fwpolicy */
-/* Masquerade control, only 1 optname */
-
-#define IP_FW_MASQ_CTL  	(IP_FW_BASE_CTL+12) /* General ip_masq ctl */
-
-/* Builtin chain labels */
-#define IP_FW_LABEL_FORWARD	"forward"
-#define IP_FW_LABEL_INPUT	"input"
-#define IP_FW_LABEL_OUTPUT	"output"
-
-/* Special targets */
-#define IP_FW_LABEL_MASQUERADE  "MASQ"
-#define IP_FW_LABEL_REDIRECT    "REDIRECT"
-#define IP_FW_LABEL_ACCEPT	"ACCEPT"
-#define IP_FW_LABEL_BLOCK	"DENY"
-#define IP_FW_LABEL_REJECT	"REJECT"
-#define IP_FW_LABEL_RETURN	"RETURN"
-#define IP_FW_LABEL_QUEUE       "QUEUE"
-
-/* Files in /proc/net */
-#define IP_FW_PROC_CHAINS	"ip_fwchains"
-#define IP_FW_PROC_CHAIN_NAMES	"ip_fwnames"
-
-
-struct ip_fwpkt
-{
-	struct iphdr fwp_iph;			/* IP header */
-	union {
-		struct tcphdr fwp_tcph;		/* TCP header or */
-		struct udphdr fwp_udph;		/* UDP header */
-		struct icmphdr fwp_icmph;	/* ICMP header */
-	} fwp_protoh;
-	struct in_addr fwp_via;			/* interface address */
-	char           fwp_vianame[IFNAMSIZ];	/* interface name */
-};
-
-/* The argument to IP_FW_DELETE and IP_FW_APPEND */
-struct ip_fwchange
-{
-	struct ip_fwuser fwc_rule;
-	ip_chainlabel fwc_label;
-};	
-
-/* The argument to IP_FW_CHECK. */
-struct ip_fwtest
-{
-	struct ip_fwpkt fwt_packet; /* Packet to be tested */
-	ip_chainlabel fwt_label;   /* Block to start test in */
-};
-						
-/* The argument to IP_FW_DELETE_NUM */
-struct ip_fwdelnum
-{
-	__u32 fwd_rulenum;
-	ip_chainlabel fwd_label;
-};
-
-/* The argument to IP_FW_REPLACE and IP_FW_INSERT */
-struct ip_fwnew
-{
-	__u32 fwn_rulenum;
-	struct ip_fwuser fwn_rule;
-	ip_chainlabel fwn_label;
-};
-
-/* The argument to IP_FW_POLICY */
-struct ip_fwpolicy
-{
-	ip_chainlabel fwp_policy;
-	ip_chainlabel fwp_label;
-};
-/*
- * timeouts for ip masquerading
- */
-
-extern int ip_fw_masq_timeouts(void *, int);
-
-
-/*
- *	Main firewall chains definitions and global var's definitions.
- */
-
-#ifdef __KERNEL__
-
-#include <linux/config.h>
-#include <linux/version.h>
-#include <linux/init.h>
-extern void ip_fw_init(void) __init;
-extern int ip_fw_ctl(int, void *, int);
-#ifdef CONFIG_IP_MASQUERADE
-extern int ip_masq_uctl(int, char *, int);
-#endif
-#endif /* KERNEL */
-
-#endif /* _IP_FWCHAINS_H */
diff -Nru a/include/linux/netfilter_ipv4/ipfwadm_core.h b/include/linux/netfilter_ipv4/ipfwadm_core.h
--- a/include/linux/netfilter_ipv4/ipfwadm_core.h	2005-03-01 23:39:09 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,256 +0,0 @@
-#ifndef _IPFWADM_CORE_H
-#define _IPFWADM_CORE_H
-/* Minor modifications to fit on compatibility framework:
-   Rusty.Russell@rustcorp.com.au
-*/
-
-/*
- *	IP firewalling code. This is taken from 4.4BSD. Please note the
- *	copyright message below. As per the GPL it must be maintained
- *	and the licenses thus do not conflict. While this port is subject
- *	to the GPL I also place my modifications under the original
- *	license in recognition of the original copyright.
- *
- *	Ported from BSD to Linux,
- *		Alan Cox 22/Nov/1994.
- *	Merged and included the FreeBSD-Current changes at Ugen's request
- *	(but hey it's a lot cleaner now). Ugen would prefer in some ways
- *	we waited for his final product but since Linux 1.2.0 is about to
- *	appear it's not practical - Read: It works, it's not clean but please
- *	don't consider it to be his standard of finished work.
- *		Alan.
- *
- * Fixes:
- *	Pauline Middelink	:	Added masquerading.
- *	Jos Vos			:	Separate input  and output firewall
- *					chains, new "insert" and "append"
- *					commands to replace "add" commands,
- *					add ICMP header to struct ip_fwpkt.
- *	Jos Vos			:	Add support for matching device names.
- *	Willy Konynenberg	:	Add transparent proxying support.
- *	Jos Vos			:	Add options for input/output accounting.
- *
- *	All the real work was done by .....
- */
-
-/*
- * Copyright (c) 1993 Daniel Boulet
- * Copyright (c) 1994 Ugen J.S.Antsilevich
- *
- * Redistribution and use in source forms, with and without modification,
- * are permitted provided that this entire comment appears intact.
- *
- * Redistribution in binary form may occur without any restrictions.
- * Obviously, it would be nice if you gave credit where credit is due
- * but requiring it would be too onerous.
- *
- * This software is provided ``AS IS'' without any warranties of any kind.
- */
-
-/*
- * 	Format of an IP firewall descriptor
- *
- * 	src, dst, src_mask, dst_mask are always stored in network byte order.
- * 	flags and num_*_ports are stored in host byte order (of course).
- * 	Port numbers are stored in HOST byte order.
- */
-
-#ifdef __KERNEL__
-#include <linux/icmp.h>
-#include <linux/in.h>
-#include <linux/ip.h>
-#include <linux/tcp.h>
-#include <linux/udp.h>
-#endif
-
-struct ip_fw
-{
-	struct ip_fw  *fw_next;			/* Next firewall on chain */
-	struct in_addr fw_src, fw_dst;		/* Source and destination IP addr */
-	struct in_addr fw_smsk, fw_dmsk;	/* Mask for src and dest IP addr */
-	struct in_addr fw_via;			/* IP address of interface "via" */
-	struct net_device *fw_viadev;		/* device of interface "via" */
-	__u16	fw_flg;				/* Flags word */
-	__u16 	fw_nsp, fw_ndp;			/* N'of src ports and # of dst ports */
-						/* in ports array (dst ports follow */
-    						/* src ports; max of 10 ports in all; */
-    						/* count of 0 means match all ports) */
-#define IP_FW_MAX_PORTS	10      		/* A reasonable maximum */
-	__u16	fw_pts[IP_FW_MAX_PORTS];	/* Array of port numbers to match */
-	unsigned long  fw_pcnt,fw_bcnt;		/* Packet and byte counters */
-	__u8	fw_tosand, fw_tosxor;		/* Revised packet priority */
-	char           fw_vianame[IFNAMSIZ];	/* name of interface "via" */
-};
-
-/*
- *	Values for "flags" field .
- */
-
-#define IP_FW_F_ALL	0x0000	/* This is a universal packet firewall*/
-#define IP_FW_F_TCP	0x0001	/* This is a TCP packet firewall      */
-#define IP_FW_F_UDP	0x0002	/* This is a UDP packet firewall      */
-#define IP_FW_F_ICMP	0x0003	/* This is a ICMP packet firewall     */
-#define IP_FW_F_KIND	0x0003	/* Mask to isolate firewall kind      */
-#define IP_FW_F_ACCEPT	0x0004	/* This is an accept firewall (as     *
-				 *         opposed to a deny firewall)*
-				 *                                    */
-#define IP_FW_F_SRNG	0x0008	/* The first two src ports are a min  *
-				 * and max range (stored in host byte *
-				 * order).                            *
-				 *                                    */
-#define IP_FW_F_DRNG	0x0010	/* The first two dst ports are a min  *
-				 * and max range (stored in host byte *
-				 * order).                            *
-				 * (ports[0] <= port <= ports[1])     *
-				 *                                    */
-#define IP_FW_F_PRN	0x0020	/* In verbose mode print this firewall*/
-#define IP_FW_F_BIDIR	0x0040	/* For bidirectional firewalls        */
-#define IP_FW_F_TCPSYN	0x0080	/* For tcp packets-check SYN only     */
-#define IP_FW_F_ICMPRPL 0x0100	/* Send back icmp unreachable packet  */
-#define IP_FW_F_MASQ	0x0200	/* Masquerading			      */
-#define IP_FW_F_TCPACK	0x0400	/* For tcp-packets match if ACK is set*/
-#define IP_FW_F_REDIR	0x0800	/* Redirect to local port fw_pts[n]   */
-#define IP_FW_F_ACCTIN  0x1000	/* Account incoming packets only.     */
-#define IP_FW_F_ACCTOUT 0x2000	/* Account outgoing packets only.     */
-
-#define IP_FW_F_MASK	0x3FFF	/* All possible flag bits mask        */
-
-/*
- *	New IP firewall options for [gs]etsockopt at the RAW IP level.
- *	Unlike BSD Linux inherits IP options so you don't have to use
- *	a raw socket for this. Instead we check rights in the calls.
- */
-
-#define IP_FW_BASE_CTL  	64	/* base for firewall socket options */
-
-#define IP_FW_COMMAND		0x00FF	/* mask for command without chain */
-#define IP_FW_TYPE		0x0300	/* mask for type (chain) */
-#define IP_FW_SHIFT		8	/* shift count for type (chain) */
-
-#define IP_FW_FWD		0
-#define IP_FW_IN		1
-#define IP_FW_OUT		2
-#define IP_FW_ACCT		3
-#define IP_FW_CHAINS		4	/* total number of ip_fw chains */
-#define IP_FW_MASQ		5
-
-#define IP_FW_INSERT		(IP_FW_BASE_CTL)
-#define IP_FW_APPEND		(IP_FW_BASE_CTL+1)
-#define IP_FW_DELETE		(IP_FW_BASE_CTL+2)
-#define IP_FW_FLUSH		(IP_FW_BASE_CTL+3)
-#define IP_FW_ZERO		(IP_FW_BASE_CTL+4)
-#define IP_FW_POLICY		(IP_FW_BASE_CTL+5)
-#define IP_FW_CHECK		(IP_FW_BASE_CTL+6)
-#define IP_FW_MASQ_TIMEOUTS	(IP_FW_BASE_CTL+7)
-
-#define IP_FW_INSERT_FWD	(IP_FW_INSERT | (IP_FW_FWD << IP_FW_SHIFT))
-#define IP_FW_APPEND_FWD	(IP_FW_APPEND | (IP_FW_FWD << IP_FW_SHIFT))
-#define IP_FW_DELETE_FWD	(IP_FW_DELETE | (IP_FW_FWD << IP_FW_SHIFT))
-#define IP_FW_FLUSH_FWD		(IP_FW_FLUSH  | (IP_FW_FWD << IP_FW_SHIFT))
-#define IP_FW_ZERO_FWD		(IP_FW_ZERO   | (IP_FW_FWD << IP_FW_SHIFT))
-#define IP_FW_POLICY_FWD	(IP_FW_POLICY | (IP_FW_FWD << IP_FW_SHIFT))
-#define IP_FW_CHECK_FWD		(IP_FW_CHECK  | (IP_FW_FWD << IP_FW_SHIFT))
-
-#define IP_FW_INSERT_IN		(IP_FW_INSERT | (IP_FW_IN << IP_FW_SHIFT))
-#define IP_FW_APPEND_IN		(IP_FW_APPEND | (IP_FW_IN << IP_FW_SHIFT))
-#define IP_FW_DELETE_IN		(IP_FW_DELETE | (IP_FW_IN << IP_FW_SHIFT))
-#define IP_FW_FLUSH_IN		(IP_FW_FLUSH  | (IP_FW_IN << IP_FW_SHIFT))
-#define IP_FW_ZERO_IN		(IP_FW_ZERO   | (IP_FW_IN << IP_FW_SHIFT))
-#define IP_FW_POLICY_IN		(IP_FW_POLICY | (IP_FW_IN << IP_FW_SHIFT))
-#define IP_FW_CHECK_IN		(IP_FW_CHECK  | (IP_FW_IN << IP_FW_SHIFT))
-
-#define IP_FW_INSERT_OUT	(IP_FW_INSERT | (IP_FW_OUT << IP_FW_SHIFT))
-#define IP_FW_APPEND_OUT	(IP_FW_APPEND | (IP_FW_OUT << IP_FW_SHIFT))
-#define IP_FW_DELETE_OUT	(IP_FW_DELETE | (IP_FW_OUT << IP_FW_SHIFT))
-#define IP_FW_FLUSH_OUT		(IP_FW_FLUSH  | (IP_FW_OUT << IP_FW_SHIFT))
-#define IP_FW_ZERO_OUT		(IP_FW_ZERO   | (IP_FW_OUT << IP_FW_SHIFT))
-#define IP_FW_POLICY_OUT	(IP_FW_POLICY | (IP_FW_OUT << IP_FW_SHIFT))
-#define IP_FW_CHECK_OUT		(IP_FW_CHECK  | (IP_FW_OUT << IP_FW_SHIFT))
-
-#define IP_ACCT_INSERT		(IP_FW_INSERT | (IP_FW_ACCT << IP_FW_SHIFT))
-#define IP_ACCT_APPEND		(IP_FW_APPEND | (IP_FW_ACCT << IP_FW_SHIFT))
-#define IP_ACCT_DELETE		(IP_FW_DELETE | (IP_FW_ACCT << IP_FW_SHIFT))
-#define IP_ACCT_FLUSH		(IP_FW_FLUSH  | (IP_FW_ACCT << IP_FW_SHIFT))
-#define IP_ACCT_ZERO		(IP_FW_ZERO   | (IP_FW_ACCT << IP_FW_SHIFT))
-
-#define IP_FW_MASQ_INSERT	(IP_FW_INSERT | (IP_FW_MASQ << IP_FW_SHIFT))
-#define IP_FW_MASQ_ADD		(IP_FW_APPEND | (IP_FW_MASQ << IP_FW_SHIFT))
-#define IP_FW_MASQ_DEL		(IP_FW_DELETE | (IP_FW_MASQ << IP_FW_SHIFT))
-#define IP_FW_MASQ_FLUSH  	(IP_FW_FLUSH  | (IP_FW_MASQ << IP_FW_SHIFT))
-
-#define IP_FW_MASQ_INSERT	(IP_FW_INSERT | (IP_FW_MASQ << IP_FW_SHIFT))
-#define IP_FW_MASQ_ADD		(IP_FW_APPEND | (IP_FW_MASQ << IP_FW_SHIFT))
-#define IP_FW_MASQ_DEL		(IP_FW_DELETE | (IP_FW_MASQ << IP_FW_SHIFT))
-#define IP_FW_MASQ_FLUSH  	(IP_FW_FLUSH  | (IP_FW_MASQ << IP_FW_SHIFT))
-
-struct ip_fwpkt
-{
-	struct iphdr fwp_iph;			/* IP header */
-	union {
-		struct tcphdr fwp_tcph;		/* TCP header or */
-		struct udphdr fwp_udph;		/* UDP header */
-		struct icmphdr fwp_icmph;	/* ICMP header */
-	} fwp_protoh;
-	struct in_addr fwp_via;			/* interface address */
-	char           fwp_vianame[IFNAMSIZ];	/* interface name */
-};
-
-#define IP_FW_MASQCTL_MAX 256
-#define IP_MASQ_MOD_NMAX  32
-
-struct ip_fw_masqctl
-{
-	int mctl_action;
-	union {
-		struct {
-			char name[IP_MASQ_MOD_NMAX];
-			char data[1];
-		} mod;
-	} u;
-};
-
-/*
- * timeouts for ip masquerading
- */
-
-struct ip_fw_masq;
-
-/*
- *	Main firewall chains definitions and global var's definitions.
- */
-
-#ifdef __KERNEL__
-
-/* Modes used in the ip_fw_chk() routine. */
-#define IP_FW_MODE_FW		0x00	/* kernel firewall check */
-#define IP_FW_MODE_ACCT_IN	0x01	/* accounting (incoming) */
-#define IP_FW_MODE_ACCT_OUT	0x02	/* accounting (outgoing) */
-#define IP_FW_MODE_CHK		0x04	/* check requested by user */
-
-#include <linux/config.h>
-#ifdef CONFIG_IP_FIREWALL
-extern struct ip_fw *ip_fw_in_chain;
-extern struct ip_fw *ip_fw_out_chain;
-extern struct ip_fw *ip_fw_fwd_chain;
-extern int ip_fw_in_policy;
-extern int ip_fw_out_policy;
-extern int ip_fw_fwd_policy;
-extern int ip_fw_ctl(int, void *, int);
-#endif
-#ifdef CONFIG_IP_ACCT
-extern struct ip_fw *ip_acct_chain;
-extern int ip_acct_ctl(int, void *, int);
-#endif
-#ifdef CONFIG_IP_MASQUERADE
-extern int ip_masq_ctl(int, void *, int);
-#endif
-#ifdef CONFIG_IP_MASQUERADE
-extern int ip_masq_ctl(int, void *, int);
-#endif
-
-extern int ip_fw_masq_timeouts(void *user, int len);
-
-extern int ip_fw_chk(struct sk_buff **, struct net_device *, __u16 *,
-		     struct ip_fw *, int, int);
-#endif /* KERNEL */
-#endif /* _IP_FW_H */
diff -Nru a/include/linux/netfilter_ipv4/ipt_LOG.h b/include/linux/netfilter_ipv4/ipt_LOG.h
--- a/include/linux/netfilter_ipv4/ipt_LOG.h	2005-03-01 23:39:16 -08:00
+++ b/include/linux/netfilter_ipv4/ipt_LOG.h	2005-03-01 23:39:16 -08:00
@@ -4,7 +4,8 @@
 #define IPT_LOG_TCPSEQ		0x01	/* Log TCP sequence numbers */
 #define IPT_LOG_TCPOPT		0x02	/* Log TCP options */
 #define IPT_LOG_IPOPT		0x04	/* Log IP options */
-#define IPT_LOG_MASK		0x07
+#define IPT_LOG_UID		0x08	/* Log UID owning local socket */
+#define IPT_LOG_MASK		0x0f
 
 struct ipt_log_info {
 	unsigned char level;
diff -Nru a/include/linux/netfilter_ipv4/ipt_MARK.h b/include/linux/netfilter_ipv4/ipt_MARK.h
--- a/include/linux/netfilter_ipv4/ipt_MARK.h	2005-03-01 23:38:54 -08:00
+++ b/include/linux/netfilter_ipv4/ipt_MARK.h	2005-03-01 23:38:54 -08:00
@@ -1,8 +1,20 @@
 #ifndef _IPT_MARK_H_target
 #define _IPT_MARK_H_target
 
+/* Version 0 */
 struct ipt_mark_target_info {
 	unsigned long mark;
 };
 
+/* Version 1 */
+enum {
+	IPT_MARK_SET=0,
+	IPT_MARK_AND,
+	IPT_MARK_OR
+};
+
+struct ipt_mark_target_info_v1 {
+	unsigned long mark;
+	u_int8_t mode;
+};
 #endif /*_IPT_MARK_H_target*/
diff -Nru a/include/linux/netfilter_ipv4/ipt_conntrack.h b/include/linux/netfilter_ipv4/ipt_conntrack.h
--- a/include/linux/netfilter_ipv4/ipt_conntrack.h	2005-03-01 23:39:08 -08:00
+++ b/include/linux/netfilter_ipv4/ipt_conntrack.h	2005-03-01 23:39:08 -08:00
@@ -22,11 +22,32 @@
 #define IPT_CONNTRACK_STATUS	0x40
 #define IPT_CONNTRACK_EXPIRES	0x80
 
+/* This is exposed to userspace, so remains frozen in time. */
+struct ip_conntrack_old_tuple
+{
+	struct {
+		__u32 ip;
+		union {
+			__u16 all;
+		} u;
+	} src;
+
+	struct {
+		__u32 ip;
+		union {
+			__u16 all;
+		} u;
+
+		/* The protocol. */
+		u16 protonum;
+	} dst;
+};
+
 struct ipt_conntrack_info
 {
 	unsigned int statemask, statusmask;
 
-	struct ip_conntrack_tuple tuple[IP_CT_DIR_MAX];
+	struct ip_conntrack_old_tuple tuple[IP_CT_DIR_MAX];
 	struct in_addr sipmsk[IP_CT_DIR_MAX], dipmsk[IP_CT_DIR_MAX];
 
 	unsigned long expires_min, expires_max;
diff -Nru a/include/linux/netfilter_ipv4/ipt_multiport.h b/include/linux/netfilter_ipv4/ipt_multiport.h
--- a/include/linux/netfilter_ipv4/ipt_multiport.h	2005-03-01 23:38:57 -08:00
+++ b/include/linux/netfilter_ipv4/ipt_multiport.h	2005-03-01 23:38:57 -08:00
@@ -18,4 +18,13 @@
 	u_int8_t count;				/* Number of ports */
 	u_int16_t ports[IPT_MULTI_PORTS];	/* Ports */
 };
+
+struct ipt_multiport_v1
+{
+	u_int8_t flags;				/* Type of comparison */
+	u_int8_t count;				/* Number of ports */
+	u_int16_t ports[IPT_MULTI_PORTS];	/* Ports */
+	u_int8_t pflags[IPT_MULTI_PORTS];	/* Port flags */
+	u_int8_t invert;			/* Invert flag */
+};
 #endif /*_IPT_MULTIPORT_H*/
diff -Nru a/include/linux/netfilter_ipv6/ip6_tables.h b/include/linux/netfilter_ipv6/ip6_tables.h
--- a/include/linux/netfilter_ipv6/ip6_tables.h	2005-03-01 23:39:16 -08:00
+++ b/include/linux/netfilter_ipv6/ip6_tables.h	2005-03-01 23:39:16 -08:00
@@ -429,9 +429,6 @@
 	/* A unique name... */
 	char name[IP6T_TABLE_MAXNAMELEN];
 
-	/* Seed table: copied in register_table */
-	struct ip6t_replace *table;
-
 	/* What hooks you will enter on */
 	unsigned int valid_hooks;
 
@@ -445,7 +442,8 @@
 	struct module *me;
 };
 
-extern int ip6t_register_table(struct ip6t_table *table);
+extern int ip6t_register_table(struct ip6t_table *table,
+			       const struct ip6t_replace *repl);
 extern void ip6t_unregister_table(struct ip6t_table *table);
 extern unsigned int ip6t_do_table(struct sk_buff **pskb,
 				  unsigned int hook,
diff -Nru a/include/linux/netfilter_ipv6/ip6t_LOG.h b/include/linux/netfilter_ipv6/ip6t_LOG.h
--- a/include/linux/netfilter_ipv6/ip6t_LOG.h	2005-03-01 23:39:07 -08:00
+++ b/include/linux/netfilter_ipv6/ip6t_LOG.h	2005-03-01 23:39:07 -08:00
@@ -4,7 +4,8 @@
 #define IP6T_LOG_TCPSEQ		0x01	/* Log TCP sequence numbers */
 #define IP6T_LOG_TCPOPT		0x02	/* Log TCP options */
 #define IP6T_LOG_IPOPT		0x04	/* Log IP options */
-#define IP6T_LOG_MASK		0x07
+#define IP6T_LOG_UID		0x08	/* Log UID owning local socket */
+#define IP6T_LOG_MASK		0x0f
 
 struct ip6t_log_info {
 	unsigned char level;
diff -Nru a/include/linux/netlink.h b/include/linux/netlink.h
--- a/include/linux/netlink.h	2005-03-01 23:39:09 -08:00
+++ b/include/linux/netlink.h	2005-03-01 23:39:09 -08:00
@@ -116,9 +116,6 @@
 #define NETLINK_CREDS(skb)	(&NETLINK_CB((skb)).creds)
 
 
-extern int netlink_attach(int unit, int (*function)(int,struct sk_buff *skb));
-extern void netlink_detach(int unit);
-extern int netlink_post(int unit, struct sk_buff *skb);
 extern struct sock *netlink_kernel_create(int unit, void (*input)(struct sock *sk, int len));
 extern void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err);
 extern int netlink_unicast(struct sock *ssk, struct sk_buff *skb, __u32 pid, int nonblock);
@@ -129,7 +126,6 @@
 extern int netlink_unregister_notifier(struct notifier_block *nb);
 
 /* finegrained unicast helpers: */
-struct sock *netlink_getsockbypid(struct sock *ssk, u32 pid);
 struct sock *netlink_getsockbyfilp(struct file *filp);
 int netlink_attachskb(struct sock *sk, struct sk_buff *skb, int nonblock, long timeo);
 void netlink_detachskb(struct sock *sk, struct sk_buff *skb);
@@ -137,10 +133,9 @@
 
 /*
  *	skb should fit one page. This choice is good for headerless malloc.
- *
- *      FIXME: What is the best size for SLAB???? --ANK
  */
-#define NLMSG_GOODSIZE (PAGE_SIZE - ((sizeof(struct sk_buff)+0xF)&~0xF))
+#define NLMSG_GOODORDER 0
+#define NLMSG_GOODSIZE (SKB_MAX_ORDER(0, NLMSG_GOODORDER))
 
 
 struct netlink_callback
diff -Nru a/include/linux/netpoll.h b/include/linux/netpoll.h
--- a/include/linux/netpoll.h	2005-03-01 23:38:53 -08:00
+++ b/include/linux/netpoll.h	2005-03-01 23:38:53 -08:00
@@ -24,7 +24,6 @@
 };
 
 void netpoll_poll(struct netpoll *np);
-void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb);
 void netpoll_send_udp(struct netpoll *np, const char *msg, int len);
 int netpoll_parse_options(struct netpoll *np, char *opt);
 int netpoll_setup(struct netpoll *np);
diff -Nru a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
--- a/include/linux/nfs_fs.h	2005-03-01 23:38:55 -08:00
+++ b/include/linux/nfs_fs.h	2005-03-01 23:38:55 -08:00
@@ -30,6 +30,7 @@
 #include <linux/nfs_xdr.h>
 #include <linux/rwsem.h>
 #include <linux/workqueue.h>
+#include <linux/mempool.h>
 
 /*
  * Enable debugging support for nfs client.
@@ -201,6 +202,7 @@
 #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 */
 
 static inline struct nfs_inode *NFS_I(struct inode *inode)
 {
@@ -239,7 +241,7 @@
 static inline void NFS_CACHEINV(struct inode *inode)
 {
 	if (!nfs_caches_unstable(inode))
-		NFS_FLAGS(inode) |= NFS_INO_INVALID_ATTR;
+		NFS_FLAGS(inode) |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS;
 }
 
 static inline int nfs_server_capable(struct inode *inode, int cap)
@@ -252,12 +254,6 @@
 	return NFS_FLAGS(inode) & NFS_INO_ADVISE_RDPLUS;
 }
 
-static inline
-loff_t page_offset(struct page *page)
-{
-	return ((loff_t)page->index) << PAGE_CACHE_SHIFT;
-}
-
 /**
  * nfs_save_change_attribute - Returns the inode attribute change cookie
  * @inode - pointer to inode
@@ -424,6 +420,44 @@
 	return nfs_wb_page_priority(inode, page, 0);
 }
 
+/*
+ * Allocate and free nfs_write_data structures
+ */
+extern mempool_t *nfs_wdata_mempool;
+extern mempool_t *nfs_commit_mempool;
+
+static inline struct nfs_write_data *nfs_writedata_alloc(void)
+{
+	struct nfs_write_data *p = mempool_alloc(nfs_wdata_mempool, SLAB_NOFS);
+	if (p) {
+		memset(p, 0, sizeof(*p));
+		INIT_LIST_HEAD(&p->pages);
+	}
+	return p;
+}
+
+static inline void nfs_writedata_free(struct nfs_write_data *p)
+{
+	mempool_free(p, nfs_wdata_mempool);
+}
+
+extern void  nfs_writedata_release(struct rpc_task *task);
+
+static inline struct nfs_write_data *nfs_commit_alloc(void)
+{
+	struct nfs_write_data *p = mempool_alloc(nfs_commit_mempool, SLAB_NOFS);
+	if (p) {
+		memset(p, 0, sizeof(*p));
+		INIT_LIST_HEAD(&p->pages);
+	}
+	return p;
+}
+
+static inline void nfs_commit_free(struct nfs_write_data *p)
+{
+	mempool_free(p, nfs_commit_mempool);
+}
+
 /* Hack for future NFS swap support */
 #ifndef IS_SWAPFILE
 # define IS_SWAPFILE(inode)	(0)
@@ -439,6 +473,26 @@
 extern void nfs_readpage_result(struct rpc_task *);
 
 /*
+ * Allocate and free nfs_read_data structures
+ */
+extern mempool_t *nfs_rdata_mempool;
+
+static inline struct nfs_read_data *nfs_readdata_alloc(void)
+{
+	struct nfs_read_data *p = mempool_alloc(nfs_rdata_mempool, SLAB_NOFS);
+	if (p)
+		memset(p, 0, sizeof(*p));
+	return p;
+}
+
+static inline void nfs_readdata_free(struct nfs_read_data *p)
+{
+	mempool_free(p, nfs_rdata_mempool);
+}
+
+extern void  nfs_readdata_release(struct rpc_task *task);
+
+/*
  * linux/fs/mount_clnt.c
  * (Used only by nfsroot module)
  */
@@ -651,8 +705,7 @@
 extern int nfs4_open_reclaim(struct nfs4_state_owner *, struct nfs4_state *);
 extern int nfs4_proc_async_renew(struct nfs4_client *);
 extern int nfs4_proc_renew(struct nfs4_client *);
-extern int nfs4_do_close(struct inode *, struct nfs4_state *);
-extern int nfs4_do_downgrade(struct inode *inode, struct nfs4_state *state, mode_t mode);
+extern int nfs4_do_close(struct inode *inode, struct nfs4_state *state, mode_t mode);
 extern int nfs4_wait_clnt_recover(struct rpc_clnt *, struct nfs4_client *);
 extern struct inode *nfs4_atomic_open(struct inode *, struct dentry *, struct nameidata *);
 extern int nfs4_open_revalidate(struct inode *, struct dentry *, int);
diff -Nru a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
--- a/include/linux/nfs_xdr.h	2005-03-01 23:39:09 -08:00
+++ b/include/linux/nfs_xdr.h	2005-03-01 23:39:09 -08:00
@@ -681,7 +681,7 @@
 	int	(*read)    (struct nfs_read_data *);
 	int	(*write)   (struct nfs_write_data *);
 	int	(*commit)  (struct nfs_write_data *);
-	struct inode *	(*create)  (struct inode *, struct qstr *,
+	struct inode *	(*create)  (struct inode *, struct dentry *,
 			    struct iattr *, int);
 	int	(*remove)  (struct inode *, struct qstr *);
 	int	(*unlink_setup)  (struct rpc_message *,
diff -Nru a/include/linux/nfsd/state.h b/include/linux/nfsd/state.h
--- a/include/linux/nfsd/state.h	2005-03-01 23:38:51 -08:00
+++ b/include/linux/nfsd/state.h	2005-03-01 23:38:51 -08:00
@@ -67,6 +67,41 @@
 #define ZERO_STATEID(stateid)       (!memcmp((stateid), &zerostateid, sizeof(stateid_t)))
 #define ONE_STATEID(stateid)        (!memcmp((stateid), &onestateid, sizeof(stateid_t)))
 
+/* Delegation recall states */
+#define NFS4_NO_RECALL			0x000
+#define NFS4_RECALL_IN_PROGRESS		0x001
+#define NFS4_RECALL_COMPLETE		0x002
+#define NFS4_REAP_DELEG			0x004
+
+struct nfs4_cb_recall {
+	u32			cbr_ident;
+	int			cbr_trunc;
+	stateid_t		cbr_stateid;
+	u32			cbr_fhlen;
+	u32			cbr_fhval[NFS4_FHSIZE];
+	struct nfs4_delegation	*cbr_dp;
+};
+
+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_recall_lru;  /* delegation recalled */
+	atomic_t		dl_recall_cnt;  /* resend cb_recall only once */
+	atomic_t		dl_count;       /* ref count */
+	atomic_t		dl_state;       /* recall state */
+	struct nfs4_client	*dl_client;
+	struct nfs4_file	*dl_file;
+	struct file_lock	*dl_flock;
+	struct nfs4_stateid	*dl_stp;
+	u32			dl_type;
+	time_t			dl_time;
+	struct nfs4_cb_recall	dl_recall;
+};
+
+#define dl_stateid      dl_recall.cbr_stateid
+#define dl_fhlen        dl_recall.cbr_fhlen
+#define dl_fhval        dl_recall.cbr_fhval
+
 /* client delegation callback info */
 struct nfs4_callback {
 	/* SETCLIENTID info */
@@ -75,9 +110,8 @@
 	unsigned short          cb_port;
 	u32                     cb_prog;
 	u32                     cb_ident;
-	struct xdr_netobj	cb_netid;
 	/* RPC client info */
-	u32			cb_set;     /* successful CB_NULL call */
+	atomic_t		cb_set;     /* successful CB_NULL call */
 	struct rpc_program      cb_program;
 	struct rpc_stat         cb_stat;
 	struct rpc_clnt *       cb_client;
@@ -97,6 +131,7 @@
 	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_lru;         /* tail queue */
 	struct xdr_netobj	cl_name; 	/* id generated by client */
 	nfs4_verifier		cl_verifier; 	/* generated by client */
@@ -107,6 +142,7 @@
 	nfs4_verifier		cl_confirm;	/* generated by server */
 	struct nfs4_callback	cl_callback;    /* callback info */
 	time_t			cl_first_state; /* first state aquisition*/
+	atomic_t		cl_count;	/* ref count */
 };
 
 /* struct nfs4_client_reset
@@ -194,6 +230,7 @@
 struct nfs4_file {
 	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 inode		*fi_inode;
 	u32                     fi_id;      /* used with stateowner->so_id 
 					     * for stateid_hashtbl hash */
@@ -231,8 +268,10 @@
 #define CONFIRM                 0x00000002
 #define OPEN_STATE              0x00000004
 #define LOCK_STATE              0x00000008
-#define RDWR_STATE              0x00000010
-#define CLOSE_STATE             0x00000020
+#define RD_STATE	        0x00000010
+#define WR_STATE	        0x00000020
+#define CLOSE_STATE             0x00000040
+#define DELEG_RET               0x00000080
 
 #define seqid_mutating_err(err)                       \
 	(((err) != nfserr_stale_clientid) &&    \
@@ -243,14 +282,17 @@
 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 nfs4_stateid **stpp);
+		stateid_t *stateid, int flags);
 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);
 extern int nfs4_check_open_reclaim(clientid_t *clid);
+extern void put_nfs4_client(struct nfs4_client *clp);
 extern void nfs4_free_stateowner(struct kref *kref);
+extern void nfsd4_probe_callback(struct nfs4_client *clp);
+extern int nfsd4_cb_recall(struct nfs4_delegation *dp);
 
 static inline void
 nfs4_put_stateowner(struct nfs4_stateowner *so)
diff -Nru a/include/linux/nfsd/xdr4.h b/include/linux/nfsd/xdr4.h
--- a/include/linux/nfsd/xdr4.h	2005-03-01 23:38:53 -08:00
+++ b/include/linux/nfsd/xdr4.h	2005-03-01 23:38:53 -08:00
@@ -44,16 +44,6 @@
 #define NFSD4_MAX_TAGLEN	128
 #define XDR_LEN(n)                     (((n) + 3) & ~3)
 
-typedef u32 delegation_zero_t;
-typedef u32 delegation_boot_t;
-typedef u64 delegation_id_t;
-
-typedef struct {
-	delegation_zero_t	ds_zero;
-	delegation_boot_t	ds_boot;
-	delegation_id_t		ds_id;
-} delegation_stateid_t;
-
 struct nfsd4_change_info {
 	u32		atomic;
 	u32		before_ctime_sec;
@@ -104,6 +94,10 @@
 #define cr_specdata1	u.dev.specdata1
 #define cr_specdata2	u.dev.specdata2
 
+struct nfsd4_delegreturn {
+	stateid_t	dr_stateid;
+};
+
 struct nfsd4_getattr {
 	u32		ga_bmval[2];        /* request */
 	struct svc_fh	*ga_fhp;            /* response */
@@ -202,13 +196,13 @@
 	u32		op_claim_type;      /* request */
 	struct xdr_netobj op_fname;	    /* request - everything but CLAIM_PREV */
 	u32		op_delegate_type;   /* request - CLAIM_PREV only */
-	delegation_stateid_t	op_delegate_stateid; /* request - CLAIM_DELEGATE_CUR only */
+	stateid_t       op_delegate_stateid; /* request - response */
 	u32		op_create;     	    /* request */
 	u32		op_createmode;      /* request */
 	u32		op_bmval[2];        /* request */
 	union {                             /* request */
-		struct iattr	iattr;		            /* UNCHECKED4,GUARDED4 */
-		nfs4_verifier	verf;		                     /* EXCLUSIVE4 */
+		struct iattr	iattr;                      /* UNCHECKED4,GUARDED4 */
+		nfs4_verifier	verf;                                /* EXCLUSIVE4 */
 	} u;
 	clientid_t	op_clientid;        /* request */
 	struct xdr_netobj op_owner;           /* request */
@@ -345,6 +339,7 @@
 		struct nfsd4_close		close;
 		struct nfsd4_commit		commit;
 		struct nfsd4_create		create;
+		struct nfsd4_delegreturn	delegreturn;
 		struct nfsd4_getattr		getattr;
 		struct svc_fh *			getfh;
 		struct nfsd4_link		link;
@@ -456,6 +451,8 @@
 nfsd4_release_lockowner(struct svc_rqst *rqstp,
 		struct nfsd4_release_lockowner *rlockowner);
 extern void nfsd4_release_compoundargs(struct nfsd4_compoundargs *);
+extern int nfsd4_delegreturn(struct svc_rqst *rqstp,
+		struct svc_fh *current_fh, struct nfsd4_delegreturn *dr);
 #endif
 
 /*
diff -Nru a/include/linux/nodemask.h b/include/linux/nodemask.h
--- a/include/linux/nodemask.h	2005-03-01 23:38:52 -08:00
+++ b/include/linux/nodemask.h	2005-03-01 23:38:52 -08:00
@@ -38,6 +38,8 @@
  *
  * int first_node(mask)			Number lowest set bit, or MAX_NUMNODES
  * int next_node(node, mask)		Next node past 'node', or MAX_NUMNODES
+ * int first_unset_node(mask)		First node not set in mask, or 
+ *					MAX_NUMNODES.
  *
  * nodemask_t nodemask_of_node(node)	Return nodemask with bit 'node' set
  * NODE_MASK_ALL			Initializer - all bits set
@@ -211,16 +213,19 @@
 	bitmap_shift_left(dstp->bits, srcp->bits, n, nbits);
 }
 
-#define first_node(src) __first_node(&(src), MAX_NUMNODES)
-static inline int __first_node(const nodemask_t *srcp, int nbits)
+/* FIXME: better would be to fix all architectures to never return
+          > MAX_NUMNODES, then the silly min_ts could be dropped. */
+
+#define first_node(src) __first_node(&(src))
+static inline int __first_node(const nodemask_t *srcp)
 {
-	return min_t(int, nbits, find_first_bit(srcp->bits, nbits));
+	return min_t(int, MAX_NUMNODES, find_first_bit(srcp->bits, MAX_NUMNODES));
 }
 
-#define next_node(n, src) __next_node((n), &(src), MAX_NUMNODES)
-static inline int __next_node(int n, const nodemask_t *srcp, int nbits)
+#define next_node(n, src) __next_node((n), &(src))
+static inline int __next_node(int n, const nodemask_t *srcp)
 {
-	return min_t(int, nbits, find_next_bit(srcp->bits, nbits, n+1));
+	return min_t(int,MAX_NUMNODES,find_next_bit(srcp->bits, MAX_NUMNODES, n+1));
 }
 
 #define nodemask_of_node(node)						\
@@ -234,6 +239,13 @@
 	}								\
 	m;								\
 })
+
+#define first_unset_node(mask) __first_unset_node(&(mask))
+static inline int __first_unset_node(const nodemask_t *maskp)
+{
+	return min_t(int,MAX_NUMNODES,
+			find_first_zero_bit(maskp->bits, MAX_NUMNODES));
+}
 
 #define NODE_MASK_LAST_WORD BITMAP_LAST_WORD_MASK(MAX_NUMNODES)
 
diff -Nru a/include/linux/oprofile.h b/include/linux/oprofile.h
--- a/include/linux/oprofile.h	2005-03-01 23:38:59 -08:00
+++ b/include/linux/oprofile.h	2005-03-01 23:38:59 -08:00
@@ -20,6 +20,7 @@
 struct super_block;
 struct dentry;
 struct file_operations;
+struct pt_regs;
  
 /* Operations structure to be filled in */
 struct oprofile_operations {
@@ -34,6 +35,8 @@
 	int (*start)(void);
 	/* Stop delivering interrupts. */
 	void (*stop)(void);
+	/* Initiate a stack backtrace. Optional. */
+	void (*backtrace)(struct pt_regs * const regs, unsigned int depth);
 	/* CPU identification string. */
 	char * cpu_type;
 };
@@ -41,11 +44,11 @@
 /**
  * One-time initialisation. *ops must be set to a filled-in
  * operations structure. This is called even in timer interrupt
- * mode.
+ * mode so an arch can set a backtrace callback.
  *
- * Return 0 on success.
+ * If an error occurs, the fields should be left untouched.
  */
-int oprofile_arch_init(struct oprofile_operations ** ops);
+int oprofile_arch_init(struct oprofile_operations * ops);
  
 /**
  * One-time exit/cleanup for the arch.
@@ -56,8 +59,15 @@
  * Add a sample. This may be called from any context. Pass
  * smp_processor_id() as cpu.
  */
-extern void oprofile_add_sample(unsigned long eip, unsigned int is_kernel, 
-	unsigned long event, int cpu);
+void oprofile_add_sample(struct pt_regs * const regs, unsigned long event);
+
+/* Use this instead when the PC value is not from the regs. Doesn't
+ * backtrace. */
+void oprofile_add_pc(unsigned long pc, int is_kernel, unsigned long event);
+
+/* add a backtrace entry, to be called from the ->backtrace callback */
+void oprofile_add_trace(unsigned long eip);
+
 
 /**
  * Create a file of the given name as a child of the given root, with
diff -Nru a/include/linux/page-flags.h b/include/linux/page-flags.h
--- a/include/linux/page-flags.h	2005-03-01 23:39:08 -08:00
+++ b/include/linux/page-flags.h	2005-03-01 23:39:08 -08:00
@@ -74,6 +74,7 @@
 #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 */
 
 
 /*
@@ -132,40 +133,32 @@
 	unsigned long pgrotated;	/* pages rotated to tail of the LRU */
 };
 
-DECLARE_PER_CPU(struct page_state, page_states);
-
 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);
 
 #define read_page_state(member) \
 	__read_page_state(offsetof(struct page_state, member))
 
-#define mod_page_state(member, delta)					\
-	do {								\
-		unsigned long flags;					\
-		local_irq_save(flags);					\
-		__get_cpu_var(page_states).member += (delta);		\
-		local_irq_restore(flags);				\
-	} while (0)
-
+#define mod_page_state(member, delta)	\
+	__mod_page_state(offsetof(struct page_state, member), (delta))
 
 #define inc_page_state(member)	mod_page_state(member, 1UL)
 #define dec_page_state(member)	mod_page_state(member, 0UL - 1)
 #define add_page_state(member,delta) mod_page_state(member, (delta))
 #define sub_page_state(member,delta) mod_page_state(member, 0UL - (delta))
 
-#define mod_page_state_zone(zone, member, delta)			\
-	do {								\
-		unsigned long flags;					\
-		local_irq_save(flags);					\
-		if (is_highmem(zone))					\
-			__get_cpu_var(page_states).member##_high += (delta);\
-		else if (is_normal(zone))				\
-			__get_cpu_var(page_states).member##_normal += (delta);\
-		else							\
-			__get_cpu_var(page_states).member##_dma += (delta);\
-		local_irq_restore(flags);				\
+#define mod_page_state_zone(zone, member, delta)				\
+	do {									\
+		unsigned offset;						\
+		if (is_highmem(zone))						\
+			offset = offsetof(struct page_state, member##_high);	\
+		else if (is_normal(zone))					\
+			offset = offsetof(struct page_state, member##_normal);	\
+		else								\
+			offset = offsetof(struct page_state, member##_dma);	\
+		__mod_page_state(offset, (delta));				\
 	} while (0)
 
 /*
@@ -238,6 +231,8 @@
 #define SetPagePrivate(page)	set_bit(PG_private, &(page)->flags)
 #define ClearPagePrivate(page)	clear_bit(PG_private, &(page)->flags)
 #define PagePrivate(page)	test_bit(PG_private, &(page)->flags)
+#define __SetPagePrivate(page)  __set_bit(PG_private, &(page)->flags)
+#define __ClearPagePrivate(page) __clear_bit(PG_private, &(page)->flags)
 
 #define PageWriteback(page)	test_bit(PG_writeback, &(page)->flags)
 #define SetPageWriteback(page)						\
@@ -277,6 +272,10 @@
 #define ClearPageNosave(page)		clear_bit(PG_nosave, &(page)->flags)
 #define TestClearPageNosave(page)	test_and_clear_bit(PG_nosave, &(page)->flags)
 
+#define PageNosaveFree(page)	test_bit(PG_nosave_free, &(page)->flags)
+#define SetPageNosaveFree(page)	set_bit(PG_nosave_free, &(page)->flags)
+#define ClearPageNosaveFree(page)		clear_bit(PG_nosave_free, &(page)->flags)
+
 #define PageMappedToDisk(page)	test_bit(PG_mappedtodisk, &(page)->flags)
 #define SetPageMappedToDisk(page) set_bit(PG_mappedtodisk, &(page)->flags)
 #define ClearPageMappedToDisk(page) clear_bit(PG_mappedtodisk, &(page)->flags)
@@ -286,7 +285,11 @@
 #define ClearPageReclaim(page)	clear_bit(PG_reclaim, &(page)->flags)
 #define TestClearPageReclaim(page) test_and_clear_bit(PG_reclaim, &(page)->flags)
 
+#ifdef CONFIG_HUGETLB_PAGE
 #define PageCompound(page)	test_bit(PG_compound, &(page)->flags)
+#else
+#define PageCompound(page)	0
+#endif
 #define SetPageCompound(page)	set_bit(PG_compound, &(page)->flags)
 #define ClearPageCompound(page)	clear_bit(PG_compound, &(page)->flags)
 
diff -Nru a/include/linux/pagemap.h b/include/linux/pagemap.h
--- a/include/linux/pagemap.h	2005-03-01 23:38:44 -08:00
+++ b/include/linux/pagemap.h	2005-03-01 23:38:44 -08:00
@@ -143,6 +143,14 @@
 	return ret;
 }
 
+/*
+ * Return byte-offset into filesystem object for page.
+ */
+static inline loff_t page_offset(struct page *page)
+{
+	return ((loff_t)page->index) << PAGE_CACHE_SHIFT;
+}
+
 static inline pgoff_t linear_page_index(struct vm_area_struct *vma,
 					unsigned long address)
 {
diff -Nru a/include/linux/parport_pc.h b/include/linux/parport_pc.h
--- a/include/linux/parport_pc.h	2005-03-01 23:39:09 -08:00
+++ b/include/linux/parport_pc.h	2005-03-01 23:39:09 -08:00
@@ -228,12 +228,6 @@
 
 extern int parport_pc_claim_resources(struct parport *p);
 
-extern void parport_pc_init_state(struct pardevice *, struct parport_state *s);
-
-extern void parport_pc_save_state(struct parport *p, struct parport_state *s);
-
-extern void parport_pc_restore_state(struct parport *p, struct parport_state *s);
-
 /* PCMCIA code will want to get us to look at a port.  Provide a mechanism. */
 extern struct parport *parport_pc_probe_port (unsigned long base,
 					      unsigned long base_hi,
diff -Nru a/include/linux/pci.h b/include/linux/pci.h
--- a/include/linux/pci.h	2005-03-01 23:38:57 -08:00
+++ b/include/linux/pci.h	2005-03-01 23:38:57 -08:00
@@ -364,6 +364,20 @@
 #define  PCI_EXP_DEVSTA_URD	0x08	/* Unsupported Request Detected */
 #define  PCI_EXP_DEVSTA_AUXPD	0x10	/* AUX Power Detected */
 #define  PCI_EXP_DEVSTA_TRPND	0x20	/* Transactions Pending */
+#define PCI_EXP_LNKCAP		12	/* Link Capabilities */
+#define PCI_EXP_LNKCTL		16	/* Link Control */
+#define PCI_EXP_LNKSTA		18	/* Link Status */
+#define PCI_EXP_SLTCAP		20	/* Slot Capabilities */
+#define PCI_EXP_SLTCTL		24	/* Slot Control */
+#define PCI_EXP_SLTSTA		26	/* Slot Status */
+#define PCI_EXP_RTCTL		28	/* Root Control */
+#define  PCI_EXP_RTCTL_SECEE	0x01	/* System Error on Correctable Error */
+#define  PCI_EXP_RTCTL_SENFEE	0x02	/* System Error on Non-Fatal Error */
+#define  PCI_EXP_RTCTL_SEFEE	0x04	/* System Error on Fatal Error */
+#define  PCI_EXP_RTCTL_PMEIE	0x08	/* PME Interrupt Enable */
+#define  PCI_EXP_RTCTL_CRSSVE	0x10	/* CRS Software Visibility Enable */
+#define PCI_EXP_RTCAP		30	/* Root Capabilities */
+#define PCI_EXP_RTSTA		32	/* Root Status */
 
 /* Extended Capabilities (PCI-X 2.0 and Express) */
 #define PCI_EXT_CAP_ID(header)		(header & 0x0000ffff)
@@ -480,6 +494,14 @@
 #define DEVICE_COUNT_COMPATIBLE	4
 #define DEVICE_COUNT_RESOURCE	12
 
+typedef int __bitwise pci_power_t;
+
+#define PCI_D0	((pci_power_t __force) 0)
+#define PCI_D1	((pci_power_t __force) 1)
+#define PCI_D2	((pci_power_t __force) 2)
+#define PCI_D3hot	((pci_power_t __force) 3)
+#define PCI_D3cold	((pci_power_t __force) 4)
+
 /*
  * The pci_dev structure is used to describe PCI devices.
  */
@@ -508,7 +530,7 @@
 					   this if your device has broken DMA
 					   or supports 64-bit transfers.  */
 
-	u32             current_state;  /* Current operating state. In ACPI-speak,
+	pci_power_t     current_state;  /* Current operating state. In ACPI-speak,
 					   this is D0-D3, D0 being fully functional,
 					   and D3 being off. */
 
@@ -539,6 +561,7 @@
 	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? */
+	struct bin_attribute *res_attr[DEVICE_COUNT_RESOURCE]; /* sysfs file for resources */
 #ifdef CONFIG_PCI_NAMES
 #define PCI_NAME_SIZE	96
 #define PCI_NAME_HALF	__stringify(43)	/* less than half to handle slop */
@@ -593,6 +616,8 @@
 	unsigned short  pad2;
 	struct device		*bridge;
 	struct class_device	class_dev;
+	struct bin_attribute	*legacy_io; /* legacy I/O for this bus */
+	struct bin_attribute	*legacy_mem; /* legacy mem */
 };
 
 #define pci_bus_b(n)	list_entry(n, struct pci_bus, node)
@@ -642,7 +667,7 @@
 	const struct pci_device_id *id_table;	/* must be non-NULL for probe to be called */
 	int  (*probe)  (struct pci_dev *dev, const struct pci_device_id *id);	/* New device inserted */
 	void (*remove) (struct pci_dev *dev);	/* Device removed (NULL if not a hot-plug capable driver) */
-	int  (*suspend) (struct pci_dev *dev, u32 state);	/* Device suspended */
+	int  (*suspend) (struct pci_dev *dev, pm_message_t state);	/* Device suspended */
 	int  (*resume) (struct pci_dev *dev);	                /* Device woken up */
 	int  (*enable_wake) (struct pci_dev *dev, u32 state, int enable);   /* Enable wake event */
 
@@ -797,8 +822,9 @@
 /* Power management related routines */
 int pci_save_state(struct pci_dev *dev);
 int pci_restore_state(struct pci_dev *dev);
-int pci_set_power_state(struct pci_dev *dev, int state);
-int pci_enable_wake(struct pci_dev *dev, u32 state, int enable);
+int pci_set_power_state(struct pci_dev *dev, pci_power_t state);
+pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state);
+int pci_enable_wake(struct pci_dev *dev, pci_power_t state, int enable);
 
 /* Helper functions for low-level code (drivers/pci/setup-[bus,res].c) */
 void pci_bus_assign_resources(struct pci_bus *bus);
@@ -925,8 +951,9 @@
 /* Power management related routines */
 static inline int pci_save_state(struct pci_dev *dev) { return 0; }
 static inline int pci_restore_state(struct pci_dev *dev) { return 0; }
-static inline int pci_set_power_state(struct pci_dev *dev, int state) { return 0; }
-static inline int pci_enable_wake(struct pci_dev *dev, u32 state, int enable) { return 0; }
+static inline int pci_set_power_state(struct pci_dev *dev, pci_power_t state) { return 0; }
+static inline pci_power_t pci_choose_state(struct pci_dev *dev, u32 state) { return PCI_D0; }
+static inline int pci_enable_wake(struct pci_dev *dev, pci_power_t state, int enable) { return 0; }
 
 #define	isa_bridge	((struct pci_dev *)NULL)
 
diff -Nru a/include/linux/pci_ids.h b/include/linux/pci_ids.h
--- a/include/linux/pci_ids.h	2005-03-01 23:39:18 -08:00
+++ b/include/linux/pci_ids.h	2005-03-01 23:39:18 -08:00
@@ -176,10 +176,20 @@
 #define PCI_DEVICE_ID_LSI_FC919		0x0624
 #define PCI_DEVICE_ID_LSI_FC919_LAN	0x0625
 #define PCI_DEVICE_ID_LSI_FC929X	0x0626
+#define PCI_DEVICE_ID_LSI_FC939X	0x0642
+#define PCI_DEVICE_ID_LSI_FC949X	0x0640
 #define PCI_DEVICE_ID_LSI_FC919X	0x0628
 #define PCI_DEVICE_ID_NCR_YELLOWFIN	0x0701
 #define PCI_DEVICE_ID_LSI_61C102	0x0901
 #define PCI_DEVICE_ID_LSI_63C815	0x1000
+#define PCI_DEVICE_ID_LSI_SAS1064	0x0050
+#define PCI_DEVICE_ID_LSI_SAS1066	0x005E
+#define PCI_DEVICE_ID_LSI_SAS1068	0x0054
+#define PCI_DEVICE_ID_LSI_SAS1064A	0x005C
+#define PCI_DEVICE_ID_LSI_SAS1064E	0x0056
+#define PCI_DEVICE_ID_LSI_SAS1066E	0x005A
+#define PCI_DEVICE_ID_LSI_SAS1068E	0x0058
+#define PCI_DEVICE_ID_LSI_SAS1078	0x0060
 
 #define PCI_VENDOR_ID_ATI		0x1002
 /* Mach64 */
@@ -343,8 +353,9 @@
 #define PCI_DEVICE_ID_ATI_RS300_166	0x5832
 #define PCI_DEVICE_ID_ATI_RS300_200	0x5833
 /* ATI IXP Chipset */
-#define PCI_DEVICE_ID_ATI_IXP_IDE	0x4349
-#define PCI_DEVICE_ID_ATI_IXP2_IDE	0x4369	/* True name not yet sure */
+#define PCI_DEVICE_ID_ATI_IXP200_IDE	0x4349
+#define PCI_DEVICE_ID_ATI_IXP300_IDE	0x4369
+#define PCI_DEVICE_ID_ATI_IXP400_IDE	0x4376
 
 #define PCI_VENDOR_ID_VLSI		0x1004
 #define PCI_DEVICE_ID_VLSI_82C592	0x0005
@@ -496,6 +507,8 @@
 #	define PCI_DEVICE_ID_AMD_VIPER_7449	PCI_DEVICE_ID_AMD_OPUS_7449
 #define PCI_DEVICE_ID_AMD_8111_LAN	0x7462
 #define PCI_DEVICE_ID_AMD_8111_IDE	0x7469
+#define PCI_DEVICE_ID_AMD_8111_SMBUS2	0x746a
+#define PCI_DEVICE_ID_AMD_8111_SMBUS	0x746b
 #define PCI_DEVICE_ID_AMD_8111_AUDIO	0x746d
 #define PCI_DEVICE_ID_AMD_8151_0	0x7454
 #define PCI_DEVICE_ID_AMD_8131_APIC     0x7450
@@ -569,6 +582,7 @@
 #define PCI_DEVICE_ID_NEC_CBUS_2	0x002d /* PCI-Cbus Bridge */
 #define PCI_DEVICE_ID_NEC_USB		0x0035 /* PCI-USB Host */
 #define PCI_DEVICE_ID_NEC_CBUS_3	0x003b
+#define PCI_DEVICE_ID_NEC_NAPCCARD	0x003e
 #define PCI_DEVICE_ID_NEC_PCX2		0x0046 /* PowerVR */
 #define PCI_DEVICE_ID_NEC_NILE4		0x005a
 #define PCI_DEVICE_ID_NEC_VRC5476       0x009b
@@ -585,6 +599,7 @@
 #define PCI_DEVICE_ID_SI_6202		0x0002
 #define PCI_DEVICE_ID_SI_503		0x0008
 #define PCI_DEVICE_ID_SI_ACPI		0x0009
+#define PCI_DEVICE_ID_SI_SMBUS		0x0016
 #define PCI_DEVICE_ID_SI_LPC		0x0018
 #define PCI_DEVICE_ID_SI_5597_VGA	0x0200
 #define PCI_DEVICE_ID_SI_6205		0x0205
@@ -680,7 +695,7 @@
 #define PCI_DEVICE_ID_HP_SX1000_IOC	0x127c
 #define PCI_DEVICE_ID_HP_DIVA_EVEREST	0x1282
 #define PCI_DEVICE_ID_HP_DIVA_AUX	0x1290
-#define PCI_DEVICE_ID_HP_CISS		0x3210
+#define PCI_DEVICE_ID_HP_CISSA		0x3220
 
 #define PCI_VENDOR_ID_PCTECH		0x1042
 #define PCI_DEVICE_ID_PCTECH_RZ1000	0x1000
@@ -1016,7 +1031,9 @@
 #define PCI_DEVICE_ID_AL_M1523		0x1523
 #define PCI_DEVICE_ID_AL_M1531		0x1531
 #define PCI_DEVICE_ID_AL_M1533		0x1533
+#define PCI_DEVICE_ID_AL_M1535 		0x1535
 #define PCI_DEVICE_ID_AL_M1541		0x1541
+#define PCI_DEVICE_ID_AL_M1543		0x1543
 #define PCI_DEVICE_ID_AL_M1563		0x1563
 #define PCI_DEVICE_ID_AL_M1621		0x1621
 #define PCI_DEVICE_ID_AL_M1631		0x1631
@@ -1026,7 +1043,9 @@
 #define PCI_DEVICE_ID_AL_M1647		0x1647
 #define PCI_DEVICE_ID_AL_M1651		0x1651
 #define PCI_DEVICE_ID_AL_M1671		0x1671
-#define PCI_DEVICE_ID_AL_M1543		0x1543
+#define PCI_DEVICE_ID_AL_M1681		0x1681
+#define PCI_DEVICE_ID_AL_M1683		0x1683
+#define PCI_DEVICE_ID_AL_M1689		0x1689
 #define PCI_DEVICE_ID_AL_M3307		0x3307
 #define PCI_DEVICE_ID_AL_M4803		0x5215
 #define PCI_DEVICE_ID_AL_M5219		0x5219
@@ -1097,7 +1116,6 @@
 #define PCI_DEVICE_ID_NVIDIA_ITNT2		0x00A0
 #define PCI_DEVICE_ID_NVIDIA_NFORCE3		0x00d1
 #define PCI_DEVICE_ID_NVIDIA_MCP3_AUDIO		0x00da
-#define PCI_DEVICE_ID_NVIDIA_NFORCE3S  		0x00e1
 #define PCI_DEVICE_ID_NVIDIA_NFORCE3_SMBUS	0x00d4
 #define PCI_DEVICE_ID_NVIDIA_NFORCE3_IDE	0x00d5
 #define PCI_DEVICE_ID_NVIDIA_NVENET_3		0x00d6
@@ -1105,6 +1123,7 @@
 #define PCI_DEVICE_ID_NVIDIA_NVENET_7		0x00df
 #define PCI_DEVICE_ID_NVIDIA_NFORCE3S		0x00e1
 #define PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA	0x00e3
+#define PCI_DEVICE_ID_NVIDIA_NFORCE3S_SMBUS	0x00e4
 #define PCI_DEVICE_ID_NVIDIA_NFORCE3S_IDE	0x00e5
 #define PCI_DEVICE_ID_NVIDIA_NVENET_6		0x00e6
 #define PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA2	0x00ee
@@ -1133,6 +1152,7 @@
 #define PCI_DEVICE_ID_NVIDIA_IGEFORCE2		0x01a0
 #define PCI_DEVICE_ID_NVIDIA_NFORCE		0x01a4
 #define PCI_DEVICE_ID_NVIDIA_MCP1_AUDIO		0x01b1
+#define PCI_DEVICE_ID_NVIDIA_NFORCE_SMBUS	0x01b4
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_IDE		0x01bc
 #define PCI_DEVICE_ID_NVIDIA_NVENET_1		0x01c3
 #define PCI_DEVICE_ID_NVIDIA_NFORCE2		0x01e0
@@ -1451,6 +1471,7 @@
 #define PCI_DEVICE_ID_TOSHIBA_TX3927	0x000a
 #define PCI_DEVICE_ID_TOSHIBA_TC35815CF	0x0030
 #define PCI_DEVICE_ID_TOSHIBA_TX4927	0x0180
+#define PCI_DEVICE_ID_TOSHIBA_TC86C001_MISC	0x0108
 
 #define PCI_VENDOR_ID_RICOH		0x1180
 #define PCI_DEVICE_ID_RICOH_RL5C465	0x0465
@@ -1906,6 +1927,9 @@
 #define PCI_DEVICE_ID_PANACOM_QUADMODEM	0x0400
 #define PCI_DEVICE_ID_PANACOM_DUALMODEM	0x0402
 
+#define PCI_VENDOR_ID_SIPACKETS		0x14d9
+#define PCI_DEVICE_ID_SP_HT		0x0010
+
 #define PCI_VENDOR_ID_AFAVLAB		0x14db
 #define PCI_DEVICE_ID_AFAVLAB_P028	0x2180
 #define PCI_DEVICE_ID_AFAVLAB_P030	0x2182
@@ -1948,6 +1972,9 @@
 #define PCI_DEVICE_ID_BCM4401		0x4401
 #define PCI_DEVICE_ID_BCM4401B0		0x4402
 
+#define PCI_VENDOR_ID_TOPIC		0x151f
+#define PCI_DEVICE_ID_TOPIC_TP560	0x0000
+
 #define PCI_VENDOR_ID_ENE		0x1524
 #define PCI_DEVICE_ID_ENE_1211		0x1211
 #define PCI_DEVICE_ID_ENE_1225		0x1225
@@ -1989,6 +2016,9 @@
 #define PCI_DEVICE_ID_FARSITE_TE1       0x1610
 #define PCI_DEVICE_ID_FARSITE_TE1C      0x1612
 
+#define PCI_VENDOR_ID_SIBYTE		0x166d
+#define PCI_DEVICE_ID_BCM1250_HT	0x0002
+
 #define PCI_VENDOR_ID_LINKSYS		0x1737
 #define PCI_DEVICE_ID_LINKSYS_EG1032	0x1032
 #define PCI_DEVICE_ID_LINKSYS_EG1064	0x1064
@@ -2061,9 +2091,11 @@
 #define PCI_DEVICE_ID_S3_PLATO_PXG	0x8902
 #define PCI_DEVICE_ID_S3_ViRGE_DXGX	0x8a01
 #define PCI_DEVICE_ID_S3_ViRGE_GX2	0x8a10
+#define PCI_DEVICE_ID_S3_SAVAGE4	0x8a25
 #define PCI_DEVICE_ID_S3_ViRGE_MX	0x8c01
 #define PCI_DEVICE_ID_S3_ViRGE_MXP	0x8c02
 #define PCI_DEVICE_ID_S3_ViRGE_MXPMV	0x8c03
+#define PCI_DEVICE_ID_S3_PROSAVAGE8	0x8d04
 #define PCI_DEVICE_ID_S3_SONICVIBES	0xca00
 
 #define PCI_VENDOR_ID_DUNORD		0x5544
@@ -2159,6 +2191,7 @@
 #define PCI_DEVICE_ID_INTEL_82801CA_11	0x248b
 #define PCI_DEVICE_ID_INTEL_82801CA_12	0x248c
 #define PCI_DEVICE_ID_INTEL_82801DB_0	0x24c0
+#define PCI_DEVICE_ID_INTEL_82801DB_1	0x24c1
 #define PCI_DEVICE_ID_INTEL_82801DB_2	0x24c2
 #define PCI_DEVICE_ID_INTEL_82801DB_3	0x24c3
 #define PCI_DEVICE_ID_INTEL_82801DB_4	0x24c4
@@ -2205,6 +2238,8 @@
 #define PCI_DEVICE_ID_INTEL_82875_IG	0x257b
 #define PCI_DEVICE_ID_INTEL_82915G_HB	0x2580
 #define PCI_DEVICE_ID_INTEL_82915G_IG	0x2582
+#define PCI_DEVICE_ID_INTEL_82915GM_HB	0x2590
+#define PCI_DEVICE_ID_INTEL_82915GM_IG	0x2592
 #define PCI_DEVICE_ID_INTEL_ICH6_0	0x2640
 #define PCI_DEVICE_ID_INTEL_ICH6_1	0x2641
 #define PCI_DEVICE_ID_INTEL_ICH6_2	0x2642
@@ -2225,6 +2260,30 @@
 #define PCI_DEVICE_ID_INTEL_ICH6_17	0x266d
 #define PCI_DEVICE_ID_INTEL_ICH6_18	0x266e
 #define PCI_DEVICE_ID_INTEL_ICH6_19	0x266f
+#define PCI_DEVICE_ID_INTEL_ICH7_0	0x27b8
+#define PCI_DEVICE_ID_INTEL_ICH7_1	0x27b1
+#define PCI_DEVICE_ID_INTEL_ICH7_2	0x27c0
+#define PCI_DEVICE_ID_INTEL_ICH7_3	0x27c1
+#define PCI_DEVICE_ID_INTEL_ICH7_4	0x27c2
+#define PCI_DEVICE_ID_INTEL_ICH7_5	0x27c4
+#define PCI_DEVICE_ID_INTEL_ICH7_6	0x27c5
+#define PCI_DEVICE_ID_INTEL_ICH7_7	0x27c8
+#define PCI_DEVICE_ID_INTEL_ICH7_8	0x27c9
+#define PCI_DEVICE_ID_INTEL_ICH7_9	0x27ca
+#define PCI_DEVICE_ID_INTEL_ICH7_10	0x27cb
+#define PCI_DEVICE_ID_INTEL_ICH7_11	0x27cc
+#define PCI_DEVICE_ID_INTEL_ICH7_12	0x27d0
+#define PCI_DEVICE_ID_INTEL_ICH7_13	0x27d2
+#define PCI_DEVICE_ID_INTEL_ICH7_14	0x27d4
+#define PCI_DEVICE_ID_INTEL_ICH7_15	0x27d6
+#define PCI_DEVICE_ID_INTEL_ICH7_16	0x27d8
+#define PCI_DEVICE_ID_INTEL_ICH7_17	0x27da
+#define PCI_DEVICE_ID_INTEL_ICH7_18	0x27dc
+#define PCI_DEVICE_ID_INTEL_ICH7_19	0x27dd
+#define PCI_DEVICE_ID_INTEL_ICH7_20	0x27de
+#define PCI_DEVICE_ID_INTEL_ICH7_21	0x27df
+#define PCI_DEVICE_ID_INTEL_ICH7_22	0x27e0
+#define PCI_DEVICE_ID_INTEL_ICH7_23	0x27e2
 #define PCI_DEVICE_ID_INTEL_82855PM_HB	0x3340
 #define PCI_DEVICE_ID_INTEL_82830_HB	0x3575
 #define PCI_DEVICE_ID_INTEL_82830_CGC	0x3577
@@ -2280,6 +2339,7 @@
 #define PCI_DEVICE_ID_INTEL_IXP4XX	0x8500
 #define PCI_DEVICE_ID_INTEL_IXP2400	0x9001
 #define PCI_DEVICE_ID_INTEL_IXP2800	0x9004
+#define PCI_DEVICE_ID_INTEL_S21152BB	0xb152
 
 #define PCI_VENDOR_ID_COMPUTONE		0x8e0e
 #define PCI_DEVICE_ID_COMPUTONE_IP2EX	0x0291
@@ -2359,6 +2419,9 @@
 #define PCI_VENDOR_ID_TIGERJET		0xe159
 #define PCI_DEVICE_ID_TIGERJET_300	0x0001
 #define PCI_DEVICE_ID_TIGERJET_100	0x0002
+
+#define PCI_VENDOR_ID_TTTECH		0x0357
+#define PCI_DEVICE_ID_TTTECH_MC322	0x000A
 
 #define PCI_VENDOR_ID_ARK		0xedd8
 #define PCI_DEVICE_ID_ARK_STING		0xa091
diff -Nru a/include/linux/pcieport_if.h b/include/linux/pcieport_if.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/linux/pcieport_if.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,74 @@
+/*
+ * File:	pcieport_if.h
+ * Purpose:	PCI Express Port Bus Driver's IF Data Structure
+ *
+ * Copyright (C) 2004 Intel
+ * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com)
+ */
+
+#ifndef _PCIEPORT_IF_H_
+#define _PCIEPORT_IF_H_
+
+/* Port Type */
+#define PCIE_RC_PORT			4	/* Root port of RC */
+#define PCIE_SW_UPSTREAM_PORT		5	/* Upstream port of Switch */
+#define PCIE_SW_DOWNSTREAM_PORT		6	/* Downstream port of Switch */
+#define PCIE_ANY_PORT			7
+
+/* Service Type */
+#define PCIE_PORT_SERVICE_PME		1	/* Power Management Event */
+#define PCIE_PORT_SERVICE_AER		2	/* Advanced Error Reporting */
+#define PCIE_PORT_SERVICE_HP		4	/* Native Hotplug */
+#define PCIE_PORT_SERVICE_VC		8	/* Virtual Channel */
+
+/* Root/Upstream/Downstream Port's Interrupt Mode */
+#define PCIE_PORT_INTx_MODE		0
+#define PCIE_PORT_MSI_MODE		1
+#define PCIE_PORT_MSIX_MODE		2
+
+struct pcie_port_service_id {
+	__u32 vendor, device;		/* Vendor and device ID or PCI_ANY_ID*/
+	__u32 subvendor, subdevice;	/* Subsystem ID's or PCI_ANY_ID */
+	__u32 class, class_mask;	/* (class,subclass,prog-if) triplet */
+	__u32 port_type, service_type;	/* Port Entity */
+	kernel_ulong_t driver_data;
+};
+
+struct pcie_device {
+	int 		irq;	    /* Service IRQ/MSI/MSI-X Vector */
+	int 		interrupt_mode;	/* [0:INTx | 1:MSI | 2:MSI-X] */	
+	struct pcie_port_service_id id;	/* Service ID */
+	struct pci_dev	*port;	    /* Root/Upstream/Downstream Port */
+	void		*priv_data; /* Service Private Data */
+	struct device	device;     /* Generic Device Interface */
+};
+#define to_pcie_device(d) container_of(d, struct pcie_device, device)
+
+static inline void set_service_data(struct pcie_device *dev, void *data)
+{
+	dev->priv_data = data;
+}
+
+static inline void* get_service_data(struct pcie_device *dev)
+{
+	return dev->priv_data;
+}
+
+struct pcie_port_service_driver {
+	const char *name;
+	int (*probe) (struct pcie_device *dev, 
+		const struct pcie_port_service_id *id);
+	void (*remove) (struct pcie_device *dev);
+	int (*suspend) (struct pcie_device *dev, u32 state);
+	int (*resume) (struct pcie_device *dev);
+
+	const struct pcie_port_service_id *id_table;
+	struct device_driver driver;
+};
+#define to_service_driver(d) \
+	container_of(d, struct pcie_port_service_driver, driver)
+
+extern int pcie_port_service_register(struct pcie_port_service_driver *new);
+extern void pcie_port_service_unregister(struct pcie_port_service_driver *new);
+
+#endif /* _PCIEPORT_IF_H_ */
diff -Nru a/include/linux/personality.h b/include/linux/personality.h
--- a/include/linux/personality.h	2005-03-01 23:38:57 -08:00
+++ b/include/linux/personality.h	2005-03-01 23:38:57 -08:00
@@ -18,6 +18,9 @@
  * These occupy the top three bytes.
  */
 enum {
+	FDPIC_FUNCPTRS =	0x0080000,	/* userspace function ptrs point to descriptors
+						 * (signal handling)
+						 */
 	MMAP_PAGE_ZERO =	0x0100000,
 	ADDR_COMPAT_LAYOUT =	0x0200000,
 	READ_IMPLIES_EXEC =	0x0400000,
@@ -43,6 +46,7 @@
 enum {
 	PER_LINUX =		0x0000,
 	PER_LINUX_32BIT =	0x0000 | ADDR_LIMIT_32BIT,
+	PER_LINUX_FDPIC =	0x0000 | FDPIC_FUNCPTRS,
 	PER_SVR4 =		0x0001 | STICKY_TIMEOUTS | MMAP_PAGE_ZERO,
 	PER_SVR3 =		0x0002 | STICKY_TIMEOUTS | SHORT_INODE,
 	PER_SCOSVR3 =		0x0003 | STICKY_TIMEOUTS |
diff -Nru a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h
--- a/include/linux/pipe_fs_i.h	2005-03-01 23:39:07 -08:00
+++ b/include/linux/pipe_fs_i.h	2005-03-01 23:39:07 -08:00
@@ -2,10 +2,27 @@
 #define _LINUX_PIPE_FS_I_H
 
 #define PIPEFS_MAGIC 0x50495045
+
+#define PIPE_BUFFERS (16)
+
+struct pipe_buffer {
+	struct page *page;
+	unsigned int offset, len;
+	struct pipe_buf_operations *ops;
+};
+
+struct pipe_buf_operations {
+	int can_merge;
+	void * (*map)(struct file *, struct pipe_inode_info *, struct pipe_buffer *);
+	void (*unmap)(struct pipe_inode_info *, struct pipe_buffer *);
+	void (*release)(struct pipe_inode_info *, struct pipe_buffer *);
+};
+
 struct pipe_inode_info {
 	wait_queue_head_t wait;
-	char *base;
-	unsigned int len;
+	unsigned int nrbufs, curbuf;
+	struct pipe_buffer bufs[PIPE_BUFFERS];
+	struct page *tmp_page;
 	unsigned int start;
 	unsigned int readers;
 	unsigned int writers;
@@ -33,16 +50,10 @@
 #define PIPE_FASYNC_READERS(inode)     (&((inode).i_pipe->fasync_readers))
 #define PIPE_FASYNC_WRITERS(inode)     (&((inode).i_pipe->fasync_writers))
 
-#define PIPE_EMPTY(inode)	(PIPE_LEN(inode) == 0)
-#define PIPE_FULL(inode)	(PIPE_LEN(inode) == PIPE_SIZE)
-#define PIPE_FREE(inode)	(PIPE_SIZE - PIPE_LEN(inode))
-#define PIPE_END(inode)	((PIPE_START(inode) + PIPE_LEN(inode)) & (PIPE_SIZE-1))
-#define PIPE_MAX_RCHUNK(inode)	(PIPE_SIZE - PIPE_START(inode))
-#define PIPE_MAX_WCHUNK(inode)	(PIPE_SIZE - PIPE_END(inode))
-
 /* Drop the inode semaphore and wait for a pipe event, atomically */
 void pipe_wait(struct inode * inode);
 
 struct inode* pipe_new(struct inode* inode);
+void free_pipe_info(struct inode* inode);
 
 #endif
diff -Nru a/include/linux/pkt_cls.h b/include/linux/pkt_cls.h
--- a/include/linux/pkt_cls.h	2005-03-01 23:38:51 -08:00
+++ b/include/linux/pkt_cls.h	2005-03-01 23:38:51 -08:00
@@ -192,6 +192,7 @@
 	TCA_U32_ACT,   
 	TCA_U32_INDEV,
 	TCA_U32_PCNT,
+	TCA_U32_MARK,
 	__TCA_U32_MAX
 };
 
@@ -248,6 +249,7 @@
 	TCA_RSVP_SRC,
 	TCA_RSVP_PINFO,
 	TCA_RSVP_POLICE,
+	TCA_RSVP_ACT,
 	__TCA_RSVP_MAX
 };
 
@@ -279,6 +281,7 @@
 	TCA_ROUTE4_FROM,
 	TCA_ROUTE4_IIF,
 	TCA_ROUTE4_POLICE,
+	TCA_ROUTE4_ACT,
 	__TCA_ROUTE4_MAX
 };
 
@@ -310,6 +313,7 @@
 	TCA_TCINDEX_FALL_THROUGH,
 	TCA_TCINDEX_CLASSID,
 	TCA_TCINDEX_POLICE,
+	TCA_TCINDEX_ACT,
 	__TCA_TCINDEX_MAX
 };
 
diff -Nru a/include/linux/pm.h b/include/linux/pm.h
--- a/include/linux/pm.h	2005-03-01 23:38:58 -08:00
+++ b/include/linux/pm.h	2005-03-01 23:38:58 -08:00
@@ -28,44 +28,28 @@
 #include <asm/atomic.h>
 
 /*
- * Power management requests
+ * Power management requests... these are passed to pm_send_all() and friends.
+ *
+ * these functions are old and deprecated, see below.
  */
-enum
-{
-	PM_SUSPEND, /* enter D1-D3 */
-	PM_RESUME,  /* enter D0 */
-
-	PM_SAVE_STATE,  /* save device's state */
+typedef int __bitwise pm_request_t;
 
-	/* enable wake-on */
-	PM_SET_WAKEUP,
+#define PM_SUSPEND	((__force pm_request_t) 1)	/* enter D1-D3 */
+#define PM_RESUME	((__force pm_request_t) 2)	/* enter D0 */
 
-	/* bus resource management */
-	PM_GET_RESOURCES,
-	PM_SET_RESOURCES,
-
-	/* base station management */
-	PM_EJECT,
-	PM_LOCK,
-};
-
-typedef int pm_request_t;
 
 /*
- * Device types
+ * Device types... these are passed to pm_register
  */
-enum
-{
-	PM_UNKNOWN_DEV = 0, /* generic */
-	PM_SYS_DEV,	    /* system device (fan, KB controller, ...) */
-	PM_PCI_DEV,	    /* PCI device */
-	PM_USB_DEV,	    /* USB device */
-	PM_SCSI_DEV,	    /* SCSI device */
-	PM_ISA_DEV,	    /* ISA device */
-	PM_MTD_DEV,	    /* Memory Technology Device */
-};
+typedef int __bitwise pm_dev_t;
 
-typedef int pm_dev_t;
+#define PM_UNKNOWN_DEV	((__force pm_dev_t) 0)	/* generic */
+#define PM_SYS_DEV	((__force pm_dev_t) 1)	/* system device (fan, KB controller, ...) */
+#define PM_PCI_DEV	((__force pm_dev_t) 2)	/* PCI device */
+#define PM_USB_DEV	((__force pm_dev_t) 3)	/* USB device */
+#define PM_SCSI_DEV	((__force pm_dev_t) 4)	/* SCSI device */
+#define PM_ISA_DEV	((__force pm_dev_t) 5)	/* ISA device */
+#define	PM_MTD_DEV	((__force pm_dev_t) 6)	/* Memory Technology Device */
 
 /*
  * System device hardware ID (PnP) values
@@ -119,32 +103,27 @@
 /*
  * Register a device with power management
  */
-struct pm_dev *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
  */
-void pm_unregister(struct pm_dev *dev);
+void __deprecated pm_unregister(struct pm_dev *dev);
 
 /*
  * Unregister all devices with matching callback
  */
-void pm_unregister_all(pm_callback callback);
+void __deprecated pm_unregister_all(pm_callback callback);
 
 /*
  * Send a request to a single device
  */
-int pm_send(struct pm_dev *dev, pm_request_t rqst, void *data);
+int __deprecated pm_send(struct pm_dev *dev, pm_request_t rqst, void *data);
 
 /*
  * Send a request to all devices
  */
-int pm_send_all(pm_request_t rqst, void *data);
-
-static inline void pm_access(struct pm_dev *dev) {}
-static inline void pm_dev_idle(struct pm_dev *dev) {}
+int __deprecated pm_send_all(pm_request_t rqst, void *data);
 
 #else /* CONFIG_PM */
 
@@ -171,16 +150,10 @@
 	return 0;
 }
 
-static inline struct pm_dev *pm_find(pm_dev_t type, struct pm_dev *from)
-{
-	return 0;
-}
-
-static inline void pm_access(struct pm_dev *dev) {}
-static inline void pm_dev_idle(struct pm_dev *dev) {}
-
 #endif /* CONFIG_PM */
 
+/* Functions above this comment are list-based old-style power
+ * managment. Please avoid using them.  */
 
 /*
  * Callbacks for platform drivers to implement.
@@ -222,11 +195,35 @@
 
 struct device;
 
+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.
+ *
+ * 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
+ *   typedef struct pm_message_t { int event; int flags; } pm_message_t
+ * or something similar soon.
+ */
+
+#define PMSG_FREEZE	((__force pm_message_t) 3)
+#define PMSG_SUSPEND	((__force pm_message_t) 3)
+#define PMSG_ON		((__force pm_message_t) 0)
+
 struct dev_pm_info {
-	u32			power_state;
+	pm_message_t		power_state;
 #ifdef	CONFIG_PM
-	u32			prev_state;
-	u8			* saved_state;
+	pm_message_t		prev_state;
+	void			* saved_state;
 	atomic_t		pm_users;
 	struct device		* pm_parent;
 	struct list_head	entry;
@@ -235,8 +232,8 @@
 
 extern void device_pm_set_parent(struct device * dev, struct device * parent);
 
-extern int device_suspend(u32 state);
-extern int device_power_down(u32 state);
+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);
 
diff -Nru a/include/linux/prctl.h b/include/linux/prctl.h
--- a/include/linux/prctl.h	2005-03-01 23:38:58 -08:00
+++ b/include/linux/prctl.h	2005-03-01 23:38:58 -08:00
@@ -50,5 +50,6 @@
                                                    process timing */
 
 #define PR_SET_NAME    15		/* Set process name */
+#define PR_GET_NAME    16		/* Get process name */
 
 #endif /* _LINUX_PRCTL_H */
diff -Nru a/include/linux/preempt.h b/include/linux/preempt.h
--- a/include/linux/preempt.h	2005-03-01 23:38:54 -08:00
+++ b/include/linux/preempt.h	2005-03-01 23:38:54 -08:00
@@ -9,17 +9,18 @@
 #include <linux/config.h>
 #include <linux/linkage.h>
 
-#define preempt_count()	(current_thread_info()->preempt_count)
+#ifdef CONFIG_DEBUG_PREEMPT
+  extern void fastcall add_preempt_count(int val);
+  extern void fastcall sub_preempt_count(int val);
+#else
+# define add_preempt_count(val)	do { preempt_count() += (val); } while (0)
+# define sub_preempt_count(val)	do { preempt_count() -= (val); } while (0)
+#endif
 
-#define inc_preempt_count() \
-do { \
-	preempt_count()++; \
-} while (0)
+#define inc_preempt_count() add_preempt_count(1)
+#define dec_preempt_count() sub_preempt_count(1)
 
-#define dec_preempt_count() \
-do { \
-	preempt_count()--; \
-} while (0)
+#define preempt_count()	(current_thread_info()->preempt_count)
 
 #ifdef CONFIG_PREEMPT
 
diff -Nru a/include/linux/prio_tree.h b/include/linux/prio_tree.h
--- a/include/linux/prio_tree.h	2005-03-01 23:38:57 -08:00
+++ b/include/linux/prio_tree.h	2005-03-01 23:38:57 -08:00
@@ -1,15 +1,38 @@
 #ifndef _LINUX_PRIO_TREE_H
 #define _LINUX_PRIO_TREE_H
 
+/*
+ * K&R 2nd ed. A8.3 somewhat obliquely hints that initial sequences of struct
+ * fields with identical types should end up at the same location. We'll use
+ * this until we can scrap struct raw_prio_tree_node.
+ *
+ * Note: all this could be done more elegantly by using unnamed union/struct
+ * fields. However, gcc 2.95.3 and apparently also gcc 3.0.4 don't support this
+ * language extension.
+ */
+
+struct raw_prio_tree_node {
+	struct prio_tree_node	*left;
+	struct prio_tree_node	*right;
+	struct prio_tree_node	*parent;
+};
+
 struct prio_tree_node {
 	struct prio_tree_node	*left;
 	struct prio_tree_node	*right;
 	struct prio_tree_node	*parent;
+	unsigned long		start;
+	unsigned long		last;	/* last location _in_ interval */
 };
 
 struct prio_tree_root {
 	struct prio_tree_node	*prio_tree_node;
-	unsigned int 		index_bits;
+	unsigned short 		index_bits;
+	unsigned short		raw;
+		/*
+		 * 0: nodes are of type struct prio_tree_node
+		 * 1: nodes are of type raw_prio_tree_node
+		 */
 };
 
 struct prio_tree_iter {
@@ -29,14 +52,19 @@
 	iter->root = root;
 	iter->r_index = r_index;
 	iter->h_index = h_index;
+	iter->cur = NULL;
 }
 
-#define INIT_PRIO_TREE_ROOT(ptr)	\
+#define __INIT_PRIO_TREE_ROOT(ptr, _raw)	\
 do {					\
 	(ptr)->prio_tree_node = NULL;	\
 	(ptr)->index_bits = 1;		\
+	(ptr)->raw = (_raw);		\
 } while (0)
 
+#define INIT_PRIO_TREE_ROOT(ptr)	__INIT_PRIO_TREE_ROOT(ptr, 0)
+#define INIT_RAW_PRIO_TREE_ROOT(ptr)	__INIT_PRIO_TREE_ROOT(ptr, 1)
+
 #define INIT_PRIO_TREE_NODE(ptr)				\
 do {								\
 	(ptr)->left = (ptr)->right = (ptr)->parent = (ptr);	\
@@ -72,5 +100,21 @@
 {
 	return node->right == node;
 }
+
+
+struct prio_tree_node *prio_tree_replace(struct prio_tree_root *root,
+                struct prio_tree_node *old, struct prio_tree_node *node);
+struct prio_tree_node *prio_tree_insert(struct prio_tree_root *root,
+                struct prio_tree_node *node);
+void prio_tree_remove(struct prio_tree_root *root, struct prio_tree_node *node);
+struct prio_tree_node *prio_tree_next(struct prio_tree_iter *iter);
+
+#define raw_prio_tree_replace(root, old, node) \
+	prio_tree_replace(root, (struct prio_tree_node *) (old), \
+	    (struct prio_tree_node *) (node))
+#define raw_prio_tree_insert(root, node) \
+	prio_tree_insert(root, (struct prio_tree_node *) (node))
+#define raw_prio_tree_remove(root, node) \
+	prio_tree_remove(root, (struct prio_tree_node *) (node))
 
 #endif /* _LINUX_PRIO_TREE_H */
diff -Nru a/include/linux/proc_fs.h b/include/linux/proc_fs.h
--- a/include/linux/proc_fs.h	2005-03-01 23:39:18 -08:00
+++ b/include/linux/proc_fs.h	2005-03-01 23:39:18 -08:00
@@ -231,13 +231,8 @@
 static inline void kclist_add(struct kcore_list *new, void *addr, size_t size)
 {
 }
-static inline struct kcore_list * kclist_del(void *addr)
-{
-	return NULL;
-}
 #else
 extern void kclist_add(struct kcore_list *, void *, size_t);
-extern struct kcore_list *kclist_del(void *);
 #endif
 
 struct proc_inode {
diff -Nru a/include/linux/ptrace.h b/include/linux/ptrace.h
--- a/include/linux/ptrace.h	2005-03-01 23:38:52 -08:00
+++ b/include/linux/ptrace.h	2005-03-01 23:38:52 -08:00
@@ -87,6 +87,7 @@
 extern void __ptrace_link(struct task_struct *child,
 			  struct task_struct *new_parent);
 extern void __ptrace_unlink(struct task_struct *child);
+extern void ptrace_untrace(struct task_struct *child);
 
 static inline void ptrace_link(struct task_struct *child,
 			       struct task_struct *new_parent)
diff -Nru a/include/linux/quota.h b/include/linux/quota.h
--- a/include/linux/quota.h	2005-03-01 23:39:08 -08:00
+++ b/include/linux/quota.h	2005-03-01 23:39:08 -08:00
@@ -285,7 +285,8 @@
 	struct semaphore dqio_sem;		/* lock device while I/O in progress */
 	struct semaphore dqonoff_sem;		/* Serialize quotaon & quotaoff */
 	struct rw_semaphore dqptr_sem;		/* serialize ops using quota_info struct, pointers from inode to dquots */
-	struct file *files[MAXQUOTAS];		/* fp's to quotafiles */
+	struct inode *files[MAXQUOTAS];		/* inodes of quotafiles */
+	struct vfsmount *mnt[MAXQUOTAS];	/* mountpoint entries of filesystems with quota files */
 	struct mem_dqinfo info[MAXQUOTAS];	/* Information for each quota type */
 	struct quota_format_ops *ops[MAXQUOTAS];	/* Operations for each type */
 };
diff -Nru a/include/linux/quotaops.h b/include/linux/quotaops.h
--- a/include/linux/quotaops.h	2005-03-01 23:38:54 -08:00
+++ b/include/linux/quotaops.h	2005-03-01 23:38:54 -08:00
@@ -177,7 +177,7 @@
 {
 	int ret = -ENOSYS;
 
-	if (sb->s_qcop && sb->s_qcop->quota_off)
+	if (sb_any_quota_enabled(sb) && sb->s_qcop && sb->s_qcop->quota_off)
 		ret = sb->s_qcop->quota_off(sb, -1);
 	return ret;
 }
diff -Nru a/include/linux/raid/linear.h b/include/linux/raid/linear.h
--- a/include/linux/raid/linear.h	2005-03-01 23:39:16 -08:00
+++ b/include/linux/raid/linear.h	2005-03-01 23:39:16 -08:00
@@ -11,14 +11,9 @@
 
 typedef struct dev_info dev_info_t;
 
-struct linear_hash
-{
-	dev_info_t *dev0, *dev1;
-};
-
 struct linear_private_data
 {
-	struct linear_hash	*hash_table;
+	dev_info_t		**hash_table;
 	dev_info_t		*smallest;
 	int			nr_zones;
 	dev_info_t		disks[0];
diff -Nru a/include/linux/raid/raid5.h b/include/linux/raid/raid5.h
--- a/include/linux/raid/raid5.h	2005-03-01 23:39:09 -08:00
+++ b/include/linux/raid/raid5.h	2005-03-01 23:39:09 -08:00
@@ -152,6 +152,7 @@
 #define	R5_Wantread	4	/* want to schedule a read */
 #define	R5_Wantwrite	5
 #define	R5_Syncio	6	/* this io need to be accounted as resync io */
+#define	R5_Overlap	7	/* There is a pending overlapping request on this block */
 
 /*
  * Write method
@@ -219,6 +220,7 @@
 	atomic_t		active_stripes;
 	struct list_head	inactive_list;
 	wait_queue_head_t	wait_for_stripe;
+	wait_queue_head_t	wait_for_overlap;
 	int			inactive_blocked;	/* release of inactive stripes blocked,
 							 * waiting for 25% to be free
 							 */        
diff -Nru a/include/linux/random.h b/include/linux/random.h
--- a/include/linux/random.h	2005-03-01 23:39:17 -08:00
+++ b/include/linux/random.h	2005-03-01 23:39:17 -08:00
@@ -44,14 +44,15 @@
 
 extern void rand_initialize_irq(int irq);
 
-extern void add_keyboard_randomness(unsigned char scancode);
-extern void add_mouse_randomness(__u32 mouse_data);
+extern void add_input_randomness(unsigned int type, unsigned int code,
+				 unsigned int value);
 extern void add_interrupt_randomness(int irq);
 
 extern void get_random_bytes(void *buf, int nbytes);
 void generate_random_uuid(unsigned char uuid_out[16]);
 
 extern __u32 secure_ip_id(__u32 daddr);
+extern u32 secure_tcp_port_ephemeral(__u32 saddr, __u32 daddr, __u16 dport);
 extern __u32 secure_tcp_sequence_number(__u32 saddr, __u32 daddr,
 					__u16 sport, __u16 dport);
 extern __u32 secure_tcp_syn_cookie(__u32 saddr, __u32 daddr,
diff -Nru a/include/linux/rcupdate.h b/include/linux/rcupdate.h
--- a/include/linux/rcupdate.h	2005-03-01 23:38:54 -08:00
+++ b/include/linux/rcupdate.h	2005-03-01 23:38:54 -08:00
@@ -65,7 +65,6 @@
 	long	cur;		/* Current batch number.                      */
 	long	completed;	/* Number of the last completed batch         */
 	int	next_pending;	/* Is the next batch already waiting?         */
-	seqcount_t lock;	/* For atomic reads of cur and next_pending.  */
 } ____cacheline_maxaligned_in_smp;
 
 /* Is batch a before batch b ? */
@@ -88,9 +87,7 @@
 struct rcu_data {
 	/* 1) quiescent state handling : */
 	long		quiescbatch;     /* Batch # for grace period */
-	long		qsctr;		 /* User-mode/idle loop etc. */
-	long            last_qsctr;	 /* value of qsctr at beginning */
-					 /* of rcu grace period */
+	int		passed_quiesc;	 /* User-mode/idle loop etc. */
 	int		qs_pending;	 /* core waits for quiesc state */
 
 	/* 2) batch handling */
@@ -110,17 +107,20 @@
 extern struct rcu_ctrlblk rcu_bh_ctrlblk;
 
 /*
- * Increment the quiscent state counter.
+ * Increment the quiescent state counter.
+ * The counter is a bit degenerated: We do not need to know
+ * how many quiescent states passed, just if there was at least
+ * one since the start of the grace period. Thus just a flag.
  */
 static inline void rcu_qsctr_inc(int cpu)
 {
 	struct rcu_data *rdp = &per_cpu(rcu_data, cpu);
-	rdp->qsctr++;
+	rdp->passed_quiesc = 1;
 }
 static inline void rcu_bh_qsctr_inc(int cpu)
 {
 	struct rcu_data *rdp = &per_cpu(rcu_bh_data, cpu);
-	rdp->qsctr++;
+	rdp->passed_quiesc = 1;
 }
 
 static inline int __rcu_pending(struct rcu_ctrlblk *rcp,
diff -Nru a/include/linux/reiserfs_acl.h b/include/linux/reiserfs_acl.h
--- a/include/linux/reiserfs_acl.h	2005-03-01 23:39:18 -08:00
+++ b/include/linux/reiserfs_acl.h	2005-03-01 23:39:18 -08:00
@@ -50,7 +50,6 @@
 
 #ifdef CONFIG_REISERFS_FS_POSIX_ACL
 struct posix_acl * reiserfs_get_acl(struct inode *inode, int type);
-int reiserfs_set_acl(struct inode *inode, int type, struct posix_acl *acl);
 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);
@@ -60,7 +59,6 @@
 extern struct reiserfs_xattr_handler posix_acl_access_handler;
 #else
 
-#define reiserfs_set_acl NULL
 #define reiserfs_get_acl NULL
 #define reiserfs_cache_default_acl(inode) 0
 
diff -Nru a/include/linux/reiserfs_fs.h b/include/linux/reiserfs_fs.h
--- a/include/linux/reiserfs_fs.h	2005-03-01 23:39:10 -08:00
+++ b/include/linux/reiserfs_fs.h	2005-03-01 23:39:10 -08:00
@@ -243,10 +243,6 @@
 #define REISER2FS_SUPER_MAGIC_STRING "ReIsEr2Fs"
 #define REISER2FS_JR_SUPER_MAGIC_STRING "ReIsEr3Fs"
 
-extern const char reiserfs_3_5_magic_string[];
-extern const char reiserfs_3_6_magic_string[];
-extern const char reiserfs_jr_magic_string[];
-
 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);
@@ -1559,8 +1555,6 @@
 };
 
 
-extern struct item_operations stat_data_ops, indirect_ops, direct_ops, 
-  direntry_ops;
 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)
@@ -1576,11 +1570,7 @@
 
 
 
-
-
-#define COMP_KEYS comp_keys
 #define COMP_SHORT_KEYS comp_short_keys
-/*#define keys_of_same_object comp_short_keys*/
 
 /* number of blocks pointed to by the indirect item */
 #define I_UNFM_NUM(p_s_ih)	( ih_item_len(p_s_ih) / UNFM_P_SIZE )
@@ -1688,6 +1678,13 @@
 #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 */
+#else
+#define REISERFS_QUOTA_TRANS_BLOCKS 0
+#define REISERFS_QUOTA_INIT_BLOCKS 0
+#endif
 
 /* both of these can be as low as 1, or as high as you want.  The min is the
 ** number of 4k bitmap nodes preallocated on mount. New nodes are allocated
@@ -1828,23 +1825,14 @@
 
 /* stree.c */
 int B_IS_IN_TREE(const struct buffer_head *);
-extern inline void copy_short_key (void * to, const void * 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_keys (const struct reiserfs_key * le_key,
-			     const struct cpu_key * cpu_key);
 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 cpu keys
-extern  int comp_cpu_keys (const struct cpu_key *, const struct cpu_key *);
-extern int comp_short_cpu_keys (const struct cpu_key *,
-				       const struct cpu_key *);
-extern void cpu_key2cpu_key (struct cpu_key *, const struct cpu_key *);
-
 // 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 *);
@@ -1874,8 +1862,6 @@
 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);
-inline int bin_search (const void * p_v_key, const void * p_v_base, 
-					   int p_n_num, int p_n_width, int * p_n_pos);
 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)
@@ -1930,12 +1916,21 @@
 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,
@@ -1944,7 +1939,6 @@
 int reiserfs_encode_fh( struct dentry *dentry, __u32 *data, int *lenp, 
 						int connectable );
 
-int reiserfs_prepare_write(struct file *, struct page *, unsigned, unsigned) ;
 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);
@@ -1960,9 +1954,6 @@
 				   const char * symname, loff_t i_size,
 				   struct dentry *dentry, struct inode *inode);
 
-int reiserfs_sync_inode (struct reiserfs_transaction_handle *th,
-                         struct inode * inode);
-
 void reiserfs_update_sd_size (struct reiserfs_transaction_handle *th,
                               struct inode * inode, loff_t size);
 
@@ -2061,15 +2052,12 @@
 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 *);
-void free_buffers_in_tb (struct tree_balance * p_s_tb);
 
 
 /* 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_printk (const char * fmt, ...);
 void reiserfs_debug (struct super_block *s, int level, const char * fmt, ...);
-void print_virtual_node (struct virtual_node * vn);
 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);
@@ -2079,7 +2067,6 @@
 #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_path (struct tree_balance * tb, struct path * path);
 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);*/
@@ -2120,8 +2107,6 @@
 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 replace_lkey (struct tree_balance *, int, struct item_head *);
-void replace_rkey (struct tree_balance *, int, struct item_head *);
 void make_empty_node (struct buffer_info *);
 struct buffer_head * get_FEB (struct tree_balance *);
 
@@ -2246,7 +2231,6 @@
 /* prototypes from ioctl.c */
 int reiserfs_ioctl (struct inode * inode, struct file * filp, 
  		    unsigned int cmd, unsigned long arg);
-int reiserfs_unpack (struct inode * inode, struct file * filp);
  
 /* ioctl's command */
 #define REISERFS_IOC_UNPACK		_IOW(0xCD,1,long)
diff -Nru a/include/linux/reiserfs_fs_sb.h b/include/linux/reiserfs_fs_sb.h
--- a/include/linux/reiserfs_fs_sb.h	2005-03-01 23:38:57 -08:00
+++ b/include/linux/reiserfs_fs_sb.h	2005-03-01 23:38:57 -08:00
@@ -410,6 +410,10 @@
     struct rw_semaphore xattr_dir_sem;
 
     int j_errno;
+#ifdef CONFIG_QUOTA
+    char *s_qf_names[MAXQUOTAS];
+    int s_jquota_fmt;
+#endif
 };
 
 /* Definitions of reiserfs on-disk properties: */
@@ -497,7 +501,6 @@
 
 #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))
-#define reiserfs_error_continue(s) (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_ERROR_CONTINUE))
 
 void reiserfs_file_buffer (struct buffer_head * bh, int list);
 extern struct file_system_type reiserfs_fs_type;
diff -Nru a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h
--- a/include/linux/rtnetlink.h	2005-03-01 23:39:09 -08:00
+++ b/include/linux/rtnetlink.h	2005-03-01 23:39:09 -08:00
@@ -748,6 +748,7 @@
 
 #include <linux/config.h>
 
+extern size_t rtattr_strlcpy(char *dest, const struct rtattr *rta, size_t size);
 static __inline__ int rtattr_strcmp(const struct rtattr *rta, const char *str)
 {
 	int len = strlen(str) + 1;
@@ -756,6 +757,9 @@
 
 extern int rtattr_parse(struct rtattr *tb[], int maxattr, struct rtattr *rta, int len);
 
+#define rtattr_parse_nested(tb, max, rta) \
+	rtattr_parse((tb), (max), RTA_DATA((rta)), RTA_PAYLOAD((rta)))
+
 extern struct sock *rtnl;
 
 struct rtnetlink_link
@@ -765,7 +769,6 @@
 };
 
 extern struct rtnetlink_link * rtnetlink_links[NPROTO];
-extern int rtnetlink_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb);
 extern int rtnetlink_send(struct sk_buff *skb, u32 pid, u32 group, int echo);
 extern int rtnetlink_put_metrics(struct sk_buff *skb, u32 *metrics);
 
@@ -806,6 +809,7 @@
 		        } while(0)
 
 extern void rtnl_lock(void);
+extern int rtnl_lock_interruptible(void);
 extern void rtnl_unlock(void);
 extern void rtnetlink_init(void);
 
diff -Nru a/include/linux/sched.h b/include/linux/sched.h
--- a/include/linux/sched.h	2005-03-01 23:38:52 -08:00
+++ b/include/linux/sched.h	2005-03-01 23:38:52 -08:00
@@ -13,12 +13,14 @@
 #include <linux/rbtree.h>
 #include <linux/thread_info.h>
 #include <linux/cpumask.h>
+#include <linux/errno.h>
 
 #include <asm/system.h>
 #include <asm/semaphore.h>
 #include <asm/page.h>
 #include <asm/ptrace.h>
 #include <asm/mmu.h>
+#include <asm/cputime.h>
 
 #include <linux/smp.h>
 #include <linux/sem.h>
@@ -85,9 +87,7 @@
 	load += n*(FIXED_1-exp); \
 	load >>= FSHIFT;
 
-#define CT_TO_SECS(x)	((x) / HZ)
-#define CT_TO_USECS(x)	(((x) % HZ) * 1000000/HZ)
-
+extern unsigned long total_forks;
 extern int nr_threads;
 extern int last_pid;
 DECLARE_PER_CPU(unsigned long, process_counts);
@@ -121,6 +121,9 @@
 #define set_current_state(state_value)		\
 	set_mb(current->state, (state_value))
 
+/* Task command name length */
+#define TASK_COMM_LEN 16
+
 /*
  * Scheduling policies
  */
@@ -169,7 +172,7 @@
 extern void cpu_init (void);
 extern void trap_init(void);
 extern void update_process_times(int user);
-extern void scheduler_tick(int user_tick, int system);
+extern void scheduler_tick(void);
 extern unsigned long cache_decay_ticks;
 
 /* Attach to any functions which should be ignored in wchan output. */
@@ -250,6 +253,9 @@
 	struct kioctx		*ioctx_list;
 
 	struct kioctx		default_kioctx;
+
+	unsigned long hiwater_rss;	/* High-water RSS usage */
+	unsigned long hiwater_vm;	/* High-water virtual memory usage */
 };
 
 struct sighand_struct {
@@ -269,6 +275,8 @@
 	atomic_t		count;
 	atomic_t		live;
 
+	wait_queue_head_t	wait_chldexit;	/* for wait4() */
+
 	/* current thread group signal load-balancing target: */
 	task_t			*curr_target;
 
@@ -276,7 +284,6 @@
 	struct sigpending	shared_pending;
 
 	/* thread group exit support */
-	int			group_exit;
 	int			group_exit_code;
 	/* overloaded:
 	 * - notify group_exit_task when ->count is equal to notify_count
@@ -288,8 +295,7 @@
 
 	/* thread group stop support, overloads group_exit_code too */
 	int			group_stop_count;
-	/* 1 if group stopped since last SIGCONT, -1 if SIGCONT since report */
-  	int			stop_state;
+	unsigned int		flags; /* see SIGNAL_* flags below */
 
 	/* POSIX.1b Interval Timers */
 	struct list_head posix_timers;
@@ -309,7 +315,7 @@
 	 * Live threads maintain their own counters and add to these
 	 * in __exit_signal, except for the group leader.
 	 */
-	unsigned long utime, stime, cutime, cstime;
+	cputime_t utime, stime, cutime, cstime;
 	unsigned long nvcsw, nivcsw, cnvcsw, cnivcsw;
 	unsigned long min_flt, maj_flt, cmin_flt, cmaj_flt;
 
@@ -326,6 +332,15 @@
 };
 
 /*
+ * Bits in flags field of signal_struct.
+ */
+#define SIGNAL_STOP_STOPPED	0x00000001 /* job control stop in effect */
+#define SIGNAL_STOP_DEQUEUED	0x00000002 /* stop signal dequeued */
+#define SIGNAL_STOP_CONTINUED	0x00000004 /* SIGCONT since WCONTINUED reap */
+#define SIGNAL_GROUP_EXIT	0x00000008 /* group exit in progress */
+
+
+/*
  * Priority of a process goes from 0..MAX_PRIO-1, valid RT
  * priority is 0..MAX_RT_PRIO-1, and SCHED_NORMAL tasks are
  * in the range MAX_RT_PRIO..MAX_PRIO-1. Priority values
@@ -524,7 +539,6 @@
 	prio_array_t *array;
 
 	unsigned long sleep_avg;
-	long interactive_credit;
 	unsigned long long timestamp, last_ran;
 	int activated;
 
@@ -574,16 +588,16 @@
 	/* PID/PID hash table linkage. */
 	struct pid pids[PIDTYPE_MAX];
 
-	wait_queue_head_t wait_chldexit;	/* for wait4() */
 	struct completion *vfork_done;		/* for vfork() */
 	int __user *set_child_tid;		/* CLONE_CHILD_SETTID */
 	int __user *clear_child_tid;		/* CLONE_CHILD_CLEARTID */
 
 	unsigned long rt_priority;
-	unsigned long it_real_value, it_prof_value, it_virt_value;
-	unsigned long it_real_incr, it_prof_incr, it_virt_incr;
+	unsigned long it_real_value, it_real_incr;
+	cputime_t it_virt_value, it_virt_incr;
+	cputime_t it_prof_value, it_prof_incr;
 	struct timer_list real_timer;
-	unsigned long utime, stime;
+	cputime_t utime, stime;
 	unsigned long nvcsw, nivcsw; /* context switch counts */
 	struct timespec start_time;
 /* mm fault and swap info: this can arguably be seen as either mm-specific or thread-specific */
@@ -600,8 +614,8 @@
 	struct key *process_keyring;	/* keyring private to this process (CLONE_THREAD) */
 	struct key *thread_keyring;	/* keyring private to this thread */
 #endif
-	unsigned short used_math;
-	char comm[16];
+	int oomkilladj; /* OOM kill score adjustment (bit shift). */
+	char comm[TASK_COMM_LEN];
 /* file system info */
 	int link_count, total_link_count;
 /* ipc stuff */
@@ -660,9 +674,16 @@
  * to a stack based synchronous wait) if its doing sync IO.
  */
 	wait_queue_t *io_wait;
+/* i/o counters(bytes read/written, #syscalls */
+	u64 rchar, wchar, syscr, syscw;
+#if defined(CONFIG_BSD_PROCESS_ACCT)
+	u64 acct_rss_mem1;	/* accumulated rss usage */
+	u64 acct_vm_mem1;	/* accumulated virtual memory usage */
+	clock_t acct_stimexpd;	/* clock_t-converted stime since last update */
+#endif
 #ifdef CONFIG_NUMA
   	struct mempolicy *mempolicy;
-  	short il_next;		/* could be shared with used_math */
+	short il_next;
 #endif
 };
 
@@ -703,10 +724,9 @@
 #define PF_DUMPCORE	0x00000200	/* dumped core */
 #define PF_SIGNALED	0x00000400	/* killed by a signal */
 #define PF_MEMALLOC	0x00000800	/* Allocating memory */
-#define PF_MEMDIE	0x00001000	/* Killed for out-of-memory */
-#define PF_FLUSHER	0x00002000	/* responsible for disk writeback */
-
-#define PF_FREEZE	0x00004000	/* this task should be frozen for suspend */
+#define PF_FLUSHER	0x00001000	/* responsible for disk writeback */
+#define PF_USED_MATH	0x00002000	/* if unset the fpu must be initialized before use */
+#define PF_FREEZE	0x00004000	/* this task is being frozen for suspend now */
 #define PF_NOFREEZE	0x00008000	/* this thread should not be frozen */
 #define PF_FROZEN	0x00010000	/* frozen for system suspend */
 #define PF_FSTRANS	0x00020000	/* inside a filesystem transaction */
@@ -716,11 +736,38 @@
 #define PF_SYNCWRITE	0x00200000	/* I am doing a sync write */
 #define PF_BORROWED_MM	0x00400000	/* I am a kthread doing use_mm */
 
+/*
+ * Only the _current_ task can read/write to tsk->flags, but other
+ * tasks can access tsk->flags in readonly mode for example
+ * with tsk_used_math (like during threaded core dumping).
+ * There is however an exception to this rule during ptrace
+ * or during fork: the ptracer task is allowed to write to the
+ * child->flags of its traced child (same goes for fork, the parent
+ * can write to the child->flags), because we're guaranteed the
+ * child is not running and in turn not changing child->flags
+ * at the same time the parent does it.
+ */
+#define clear_stopped_child_used_math(child) do { (child)->flags &= ~PF_USED_MATH; } while (0)
+#define set_stopped_child_used_math(child) do { (child)->flags |= PF_USED_MATH; } while (0)
+#define clear_used_math() clear_stopped_child_used_math(current)
+#define set_used_math() set_stopped_child_used_math(current)
+#define conditional_stopped_child_used_math(condition, child) \
+	do { (child)->flags &= ~PF_USED_MATH, (child)->flags |= (condition) ? PF_USED_MATH : 0; } while (0)
+#define conditional_used_math(condition) \
+	conditional_stopped_child_used_math(condition, current)
+#define copy_to_stopped_child_used_math(child) \
+	do { (child)->flags &= ~PF_USED_MATH, (child)->flags |= current->flags & PF_USED_MATH; } while (0)
+/* NOTE: this will return 0 or PF_USED_MATH, it will never return 1 */
+#define tsk_used_math(p) ((p)->flags & PF_USED_MATH)
+#define used_math() tsk_used_math(current)
+
 #ifdef CONFIG_SMP
 extern int set_cpus_allowed(task_t *p, cpumask_t new_mask);
 #else
 static inline int set_cpus_allowed(task_t *p, cpumask_t new_mask)
 {
+	if (!cpus_intersects(new_mask, cpu_online_map))
+		return -EINVAL;
 	return 0;
 }
 #endif
@@ -734,12 +781,20 @@
 #define sched_exec()   {}
 #endif
 
+#ifdef CONFIG_HOTPLUG_CPU
+extern void idle_task_exit(void);
+#else
+static inline void idle_task_exit(void) {}
+#endif
+
 extern void sched_idle_next(void);
 extern void set_user_nice(task_t *p, long nice);
 extern int task_prio(const task_t *p);
 extern int task_nice(const task_t *p);
 extern int task_curr(const task_t *p);
 extern int idle_cpu(int cpu);
+extern int sched_setscheduler(struct task_struct *, int, struct sched_param *);
+extern task_t *idle_task(int cpu);
 
 void yield(void);
 
@@ -1042,29 +1097,36 @@
 	return unlikely(test_thread_flag(TIF_NEED_RESCHED));
 }
 
-extern void __cond_resched(void);
-static inline void cond_resched(void)
-{
-	if (need_resched())
-		__cond_resched();
-}
+/*
+ * cond_resched() and cond_resched_lock(): latency reduction via
+ * explicit rescheduling in places that are safe. The return
+ * value indicates whether a reschedule was done in fact.
+ * cond_resched_lock() will drop the spinlock before scheduling,
+ * cond_resched_softirq() will enable bhs before scheduling.
+ */
+extern int cond_resched(void);
+extern int cond_resched_lock(spinlock_t * lock);
+extern int cond_resched_softirq(void);
 
 /*
- * cond_resched_lock() - if a reschedule is pending, drop the given lock,
- * call schedule, and on return reacquire the lock.
- *
- * This works OK both with and without CONFIG_PREEMPT.  We do strange low-level
- * operations here to prevent schedule() from being called twice (once via
- * spin_unlock(), once by hand).
- */
-static inline void cond_resched_lock(spinlock_t * lock)
-{
-	if (need_resched()) {
-		_raw_spin_unlock(lock);
-		preempt_enable_no_resched();
-		__cond_resched();
-		spin_lock(lock);
-	}
+ * Does a critical section need to be broken due to another
+ * task waiting?:
+ */
+#if defined(CONFIG_PREEMPT) && defined(CONFIG_SMP)
+# define need_lockbreak(lock) ((lock)->break_lock)
+#else
+# define need_lockbreak(lock) 0
+#endif
+
+/*
+ * Does a critical section need to be broken due to another
+ * task waiting or preemption being signalled:
+ */
+static inline int lock_need_resched(spinlock_t *lock)
+{
+	if (need_lockbreak(lock) || need_resched())
+		return 1;
+	return 0;
 }
 
 /* Reevaluate whether the task has signals pending delivery.
@@ -1124,6 +1186,34 @@
 
 #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);
+extern int freeze_processes(void);
+extern void thaw_processes(void);
+
+static inline int try_to_freeze(unsigned long refrigerator_flags)
+{
+	if (unlikely(current->flags & PF_FREEZE)) {
+		refrigerator(refrigerator_flags);
+		return 1;
+	} else
+		return 0;
+}
+#else
+static inline void refrigerator(unsigned long flag) {}
+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;
+}
+#endif /* CONFIG_PM */
 #endif /* __KERNEL__ */
 
 #endif
diff -Nru a/include/linux/sctp.h b/include/linux/sctp.h
--- a/include/linux/sctp.h	2005-03-01 23:38:59 -08:00
+++ b/include/linux/sctp.h	2005-03-01 23:38:59 -08:00
@@ -364,7 +364,7 @@
  */
 typedef struct sctp_abort_chunk {
         sctp_chunkhdr_t uh;
-} __attribute__((packed)) sctp_abort_chunkt_t;
+} __attribute__((packed)) sctp_abort_chunk_t;
 
 
 /* For the graceful shutdown we must carry the tag (in common header)
diff -Nru a/include/linux/security.h b/include/linux/security.h
--- a/include/linux/security.h	2005-03-01 23:39:08 -08:00
+++ b/include/linux/security.h	2005-03-01 23:39:08 -08:00
@@ -109,13 +109,20 @@
  *	and the information saved in @bprm->security by the set_security hook.
  *	Since this hook function (and its caller) are void, this hook can not
  *	return an error.  However, it can leave the security attributes of the
- *	process unchanged if an access failure occurs at this point. It can
- *	also perform other state changes on the process (e.g.  closing open
- *	file descriptors to which access is no longer granted if the attributes
- *	were changed). 
+ *	process unchanged if an access failure occurs at this point.
  *	bprm_apply_creds is called under task_lock.  @unsafe indicates various
  *	reasons why it may be unsafe to change security state.
  *	@bprm contains the linux_binprm structure.
+ * @bprm_post_apply_creds:
+ *	Runs after bprm_apply_creds with the task_lock dropped, so that
+ *	functions which cannot be called safely under the task_lock can
+ *	be used.  This hook is a good place to perform state changes on
+ *	the process such as closing open file descriptors to which access
+ *	is no longer granted if the attributes were changed.
+ *	Note that a security module might need to save state between
+ *	bprm_apply_creds and bprm_post_apply_creds to store the decision
+ *	on whether the process may proceed.
+ *	@bprm contains the linux_binprm structure.
  * @bprm_set_security:
  *	Save security information in the bprm->security field, typically based
  *	on information about the bprm->file, for later use by the apply_creds
@@ -1034,7 +1041,7 @@
 	int (*sysctl) (struct ctl_table * table, int op);
 	int (*capable) (struct task_struct * tsk, int cap);
 	int (*quotactl) (int cmds, int type, int id, struct super_block * sb);
-	int (*quota_on) (struct file * f);
+	int (*quota_on) (struct dentry * dentry);
 	int (*syslog) (int type);
 	int (*settime) (struct timespec *ts, struct timezone *tz);
 	int (*vm_enough_memory) (long pages);
@@ -1042,6 +1049,7 @@
 	int (*bprm_alloc_security) (struct linux_binprm * bprm);
 	void (*bprm_free_security) (struct linux_binprm * bprm);
 	void (*bprm_apply_creds) (struct linux_binprm * bprm, int unsafe);
+	void (*bprm_post_apply_creds) (struct linux_binprm * bprm);
 	int (*bprm_set_security) (struct linux_binprm * bprm);
 	int (*bprm_check_security) (struct linux_binprm * bprm);
 	int (*bprm_secureexec) (struct linux_binprm * bprm);
@@ -1281,9 +1289,9 @@
 	return security_ops->quotactl (cmds, type, id, sb);
 }
 
-static inline int security_quota_on (struct file * file)
+static inline int security_quota_on (struct dentry * dentry)
 {
-	return security_ops->quota_on (file);
+	return security_ops->quota_on (dentry);
 }
 
 static inline int security_syslog(int type)
@@ -1314,6 +1322,10 @@
 {
 	security_ops->bprm_apply_creds (bprm, unsafe);
 }
+static inline void security_bprm_post_apply_creds (struct linux_binprm *bprm)
+{
+	security_ops->bprm_post_apply_creds (bprm);
+}
 static inline int security_bprm_set (struct linux_binprm *bprm)
 {
 	return security_ops->bprm_set_security (bprm);
@@ -1959,7 +1971,7 @@
 	return 0;
 }
 
-static inline int security_quota_on (struct file * file)
+static inline int security_quota_on (struct dentry * dentry)
 {
 	return 0;
 }
@@ -1990,6 +2002,11 @@
 static inline void security_bprm_apply_creds (struct linux_binprm *bprm, int unsafe)
 { 
 	cap_bprm_apply_creds (bprm, unsafe);
+}
+
+static inline void security_bprm_post_apply_creds (struct linux_binprm *bprm)
+{
+	return;
 }
 
 static inline int security_bprm_set (struct linux_binprm *bprm)
diff -Nru a/include/linux/selection.h b/include/linux/selection.h
--- a/include/linux/selection.h	2005-03-01 23:38:58 -08:00
+++ b/include/linux/selection.h	2005-03-01 23:38:58 -08:00
@@ -10,7 +10,7 @@
 #include <linux/tiocl.h>
 #include <linux/vt_buffer.h>
 
-extern int sel_cons;
+extern struct vc_data *sel_cons;
 
 extern void clear_selection(void);
 extern int set_selection(const struct tiocl_selection __user *sel, struct tty_struct *tty);
@@ -19,11 +19,6 @@
 extern int mouse_reporting(void);
 extern void mouse_report(struct tty_struct * tty, int butt, int mrx, int mry);
 
-#define video_num_columns	(vc_cons[currcons].d->vc_cols)
-#define video_num_lines		(vc_cons[currcons].d->vc_rows)
-#define video_size_row		(vc_cons[currcons].d->vc_size_row)
-#define can_do_color		(vc_cons[currcons].d->vc_can_do_color)
-
 extern int console_blanked;
 
 extern unsigned char color_table[];
@@ -31,15 +26,15 @@
 extern int default_grn[];
 extern int default_blu[];
 
-extern unsigned short *screen_pos(int currcons, int w_offset, int viewed);
-extern u16 screen_glyph(int currcons, int offset);
-extern void complement_pos(int currcons, int offset);
-extern void invert_screen(int currcons, int offset, int count, int shift);
+extern unsigned short *screen_pos(struct vc_data *vc, int w_offset, int viewed);
+extern u16 screen_glyph(struct vc_data *vc, int offset);
+extern void complement_pos(struct vc_data *vc, int offset);
+extern void invert_screen(struct vc_data *vc, int offset, int count, int shift);
 
-extern void getconsxy(int currcons, unsigned char *p);
-extern void putconsxy(int currcons, unsigned char *p);
+extern void getconsxy(struct vc_data *vc, unsigned char *p);
+extern void putconsxy(struct vc_data *vc, unsigned char *p);
 
-extern u16 vcs_scr_readw(int currcons, const u16 *org);
-extern void vcs_scr_writew(int currcons, u16 val, u16 *org);
+extern u16 vcs_scr_readw(struct vc_data *vc, const u16 *org);
+extern void vcs_scr_writew(struct vc_data *vc, u16 val, u16 *org);
 
 #endif
diff -Nru a/include/linux/sem.h b/include/linux/sem.h
--- a/include/linux/sem.h	2005-03-01 23:38:55 -08:00
+++ b/include/linux/sem.h	2005-03-01 23:38:55 -08:00
@@ -109,6 +109,7 @@
 	int			id;	 /* internal sem id */
 	struct sembuf *		sops;	 /* array of pending operations */
 	int			nsops;	 /* number of operations */
+	int			alter;   /* does the operation alter the array? */
 };
 
 /* Each task has a list of undo requests. They are executed automatically
diff -Nru a/include/linux/serial_core.h b/include/linux/serial_core.h
--- a/include/linux/serial_core.h	2005-03-01 23:38:52 -08:00
+++ b/include/linux/serial_core.h	2005-03-01 23:38:52 -08:00
@@ -100,6 +100,12 @@
 /* Motorola i.MX SoC */
 #define PORT_IMX	62
 
+/* Marvell MPSC */
+#define PORT_MPSC	63
+
+/* TXX9 type number */
+#define PORT_TXX9       64
+
 #ifdef __KERNEL__
 
 #include <linux/config.h>
diff -Nru a/include/linux/serial_reg.h b/include/linux/serial_reg.h
--- a/include/linux/serial_reg.h	2005-03-01 23:39:08 -08:00
+++ b/include/linux/serial_reg.h	2005-03-01 23:39:08 -08:00
@@ -307,5 +307,19 @@
 #define SERIAL_RSA_BAUD_BASE (921600)
 #define SERIAL_RSA_BAUD_BASE_LO (SERIAL_RSA_BAUD_BASE / 8)
 
+/*
+ * Extra serial register definitions for the internal UARTs
+ * in TI OMAP processors.
+ */
+#define UART_OMAP_MDR1		0x08	/* Mode definition register */
+#define UART_OMAP_MDR2		0x09	/* Mode definition register 2 */
+#define UART_OMAP_SCR		0x10	/* Supplementary control register */
+#define UART_OMAP_SSR		0x11	/* Supplementary status register */
+#define UART_OMAP_EBLR		0x12	/* BOF length register */
+#define UART_OMAP_OSC_12M_SEL	0x13	/* OMAP1510 12MHz osc select */
+#define UART_OMAP_MVER		0x14	/* Module version register */
+#define UART_OMAP_SYSC		0x15	/* System configuration register */
+#define UART_OMAP_SYSS		0x16	/* System status register */
+
 #endif /* _LINUX_SERIAL_REG_H */
 
diff -Nru a/include/linux/serio.h b/include/linux/serio.h
--- a/include/linux/serio.h	2005-03-01 23:38:58 -08:00
+++ b/include/linux/serio.h	2005-03-01 23:38:58 -08:00
@@ -45,7 +45,8 @@
 
 	struct serio *parent, *child;
 
-	struct serio_driver *drv;	/* accessed from interrupt, must be protected by serio->lock */
+	struct serio_driver *drv;	/* accessed from interrupt, must be protected by serio->lock and serio->sem */
+	struct semaphore drv_sem;	/* protects serio->drv so attributes can pin driver */
 
 	struct device dev;
 
@@ -120,6 +121,19 @@
 static __inline__ void serio_continue_rx(struct serio *serio)
 {
 	spin_unlock_irq(&serio->lock);
+}
+
+/*
+ * Use the following fucntions to pin serio's driver in process context
+ */
+static __inline__ int serio_pin_driver(struct serio *serio)
+{
+	return down_interruptible(&serio->drv_sem);
+}
+
+static __inline__ void serio_unpin_driver(struct serio *serio)
+{
+	up(&serio->drv_sem);
 }
 
 
diff -Nru a/include/linux/skbuff.h b/include/linux/skbuff.h
--- a/include/linux/skbuff.h	2005-03-01 23:39:18 -08:00
+++ b/include/linux/skbuff.h	2005-03-01 23:39:18 -08:00
@@ -292,6 +292,8 @@
 
 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_from_cache(kmem_cache_t *cp,
+					    unsigned int size, int 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);
@@ -351,15 +353,11 @@
  */
 static inline void kfree_skb(struct sk_buff *skb)
 {
-	if (atomic_read(&skb->users) == 1 || atomic_dec_and_test(&skb->users))
-		__kfree_skb(skb);
-}
-
-/* Use this if you didn't touch the skb state [for fast switching] */
-static inline void kfree_skb_fast(struct sk_buff *skb)
-{
-	if (atomic_read(&skb->users) == 1 || atomic_dec_and_test(&skb->users))
-		kfree_skbmem(skb);
+	if (likely(atomic_read(&skb->users) == 1))
+		smp_rmb();
+	else if (likely(!atomic_dec_and_test(&skb->users)))
+		return;
+	__kfree_skb(skb);
 }
 
 /**
@@ -935,6 +933,7 @@
  *
  *	%NULL is returned in there is no free memory.
  */
+#ifndef CONFIG_HAVE_ARCH_DEV_ALLOC_SKB
 static inline struct sk_buff *__dev_alloc_skb(unsigned int length,
 					      int gfp_mask)
 {
@@ -943,6 +942,9 @@
 		skb_reserve(skb, 16);
 	return skb;
 }
+#else
+extern struct sk_buff *__dev_alloc_skb(unsigned int length, int gfp_mask);
+#endif
 
 /**
  *	dev_alloc_skb - allocate an skbuff for sending
@@ -1071,23 +1073,18 @@
 }
 
 #define skb_queue_walk(queue, skb) \
-		for (skb = (queue)->next, prefetch(skb->next);	\
-		     (skb != (struct sk_buff *)(queue));	\
-		     skb = skb->next, prefetch(skb->next))
+		for (skb = (queue)->next;					\
+		     prefetch(skb->next), (skb != (struct sk_buff *)(queue));	\
+		     skb = skb->next)
 
 
 extern struct sk_buff *skb_recv_datagram(struct sock *sk, unsigned flags,
 					 int noblock, int *err);
 extern unsigned int    datagram_poll(struct file *file, struct socket *sock,
 				     struct poll_table_struct *wait);
-extern int	       skb_copy_datagram(const struct sk_buff *from,
-					 int offset, char __user *to, int size);
 extern int	       skb_copy_datagram_iovec(const struct sk_buff *from,
 					       int offset, struct iovec *to,
 					       int size);
-extern int	       skb_copy_and_csum_datagram(const struct sk_buff *skb,
-						  int offset, u8 __user *to,
-						  int len, unsigned int *csump);
 extern int	       skb_copy_and_csum_datagram_iovec(const
 							struct sk_buff *skb,
 							int hlen,
diff -Nru a/include/linux/slab.h b/include/linux/slab.h
--- a/include/linux/slab.h	2005-03-01 23:39:17 -08:00
+++ b/include/linux/slab.h	2005-03-01 23:39:17 -08:00
@@ -118,7 +118,6 @@
 extern kmem_cache_t	*names_cachep;
 extern kmem_cache_t	*files_cachep;
 extern kmem_cache_t	*filp_cachep;
-extern kmem_cache_t	*dquot_cachep;
 extern kmem_cache_t	*fs_cachep;
 extern kmem_cache_t	*signal_cachep;
 extern kmem_cache_t	*sighand_cachep;
diff -Nru a/include/linux/smp.h b/include/linux/smp.h
--- a/include/linux/smp.h	2005-03-01 23:38:58 -08:00
+++ b/include/linux/smp.h	2005-03-01 23:38:58 -08:00
@@ -8,6 +8,8 @@
 
 #include <linux/config.h>
 
+extern void cpu_idle(void);
+
 #ifdef CONFIG_SMP
 
 #include <linux/preempt.h>
@@ -95,8 +97,10 @@
 /*
  *	These macros fold the SMP functionality into a single CPU system
  */
- 
-#define smp_processor_id()			0
+
+#if !defined(__smp_processor_id) || !defined(CONFIG_PREEMPT)
+# define smp_processor_id()			0
+#endif
 #define hard_smp_processor_id()			0
 #define smp_threads_ready			1
 #define smp_call_function(func,info,retry,wait)	({ 0; })
@@ -106,6 +110,33 @@
 #define smp_prepare_boot_cpu()			do {} while (0)
 
 #endif /* !SMP */
+
+/*
+ * DEBUG_PREEMPT support: check whether smp_processor_id() is being
+ * used in a preemption-safe way.
+ *
+ * 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.
+ *
+ * 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.
+ */
+#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()
+#else
+# define _smp_processor_id() smp_processor_id()
+#endif
 
 #define get_cpu()		({ preempt_disable(); smp_processor_id(); })
 #define put_cpu()		preempt_enable()
diff -Nru a/include/linux/smp_lock.h b/include/linux/smp_lock.h
--- a/include/linux/smp_lock.h	2005-03-01 23:39:09 -08:00
+++ b/include/linux/smp_lock.h	2005-03-01 23:39:09 -08:00
@@ -9,15 +9,15 @@
 
 #define kernel_locked()		(current->lock_depth >= 0)
 
-extern int __lockfunc get_kernel_lock(void);
-extern void __lockfunc put_kernel_lock(void);
+extern int __lockfunc __reacquire_kernel_lock(void);
+extern void __lockfunc __release_kernel_lock(void);
 
 /*
  * Release/re-acquire global kernel lock for the scheduler
  */
 #define release_kernel_lock(tsk) do { 		\
 	if (unlikely((tsk)->lock_depth >= 0))	\
-		put_kernel_lock();		\
+		__release_kernel_lock();	\
 } while (0)
 
 /*
@@ -26,16 +26,16 @@
  * reacquire_kernel_lock() so that the compiler can see
  * it at compile-time.
  */
-#ifdef CONFIG_SMP
-#define return_value_on_smp return
+#if defined(CONFIG_SMP) && !defined(CONFIG_PREEMPT_BKL)
+# define return_value_on_smp return
 #else
-#define return_value_on_smp
+# define return_value_on_smp
 #endif
 
 static inline int reacquire_kernel_lock(struct task_struct *task)
 {
 	if (unlikely(task->lock_depth >= 0))
-		return_value_on_smp get_kernel_lock();
+		return_value_on_smp __reacquire_kernel_lock();
 	return 0;
 }
 
diff -Nru a/include/linux/socket.h b/include/linux/socket.h
--- a/include/linux/socket.h	2005-03-01 23:39:08 -08:00
+++ b/include/linux/socket.h	2005-03-01 23:39:09 -08:00
@@ -120,7 +120,7 @@
  *	Now it always returns valid, not truncated ancillary object
  *	HEADER. But caller still MUST check, that cmsg->cmsg_len is
  *	inside range, given by msg->msg_controllen before using
- *	ansillary object DATA.				--ANK (980731)
+ *	ancillary object DATA.				--ANK (980731)
  */
  
 __KINLINE struct cmsghdr * __cmsg_nxthdr(void *__ctl, __kernel_size_t __size,
@@ -286,7 +286,6 @@
 
 extern int verify_iovec(struct msghdr *m, struct iovec *iov, char *address, int mode);
 extern int memcpy_toiovec(struct iovec *v, unsigned char *kdata, int len);
-extern void memcpy_tokerneliovec(struct iovec *iov, unsigned char *kdata, int len);
 extern int move_addr_to_user(void *kaddr, int klen, void __user *uaddr, int __user *ulen);
 extern int move_addr_to_kernel(void __user *uaddr, int ulen, void *kaddr);
 extern int put_cmsg(struct msghdr*, int level, int type, int len, void *data);
diff -Nru a/include/linux/sonypi.h b/include/linux/sonypi.h
--- a/include/linux/sonypi.h	2005-03-01 23:38:55 -08:00
+++ b/include/linux/sonypi.h	2005-03-01 23:38:55 -08:00
@@ -1,8 +1,10 @@
 /*
  * Sony Programmable I/O Control Device driver for VAIO
  *
- * Copyright (C) 2001-2004 Stelian Pop <stelian@popies.net>
+ * Copyright (C) 2001-2005 Stelian Pop <stelian@popies.net>
  *
+ * Copyright (C) 2005 Narayanan R S <nars@kadamba.org>
+
  * Copyright (C) 2001-2002 Alcôve <www.alcove.com>
  *
  * Copyright (C) 2001 Michael Ashley <m.ashley@unsw.edu.au>
@@ -117,6 +119,13 @@
 /* get/set bluetooth subsystem state on/off */
 #define SONYPI_IOCGBLUE		_IOR('v', 8, __u8)
 #define SONYPI_IOCSBLUE		_IOW('v', 9, __u8)
+
+/* get/set fan state on/off */
+#define SONYPI_IOCGFAN		_IOR('v', 10, __u8)
+#define SONYPI_IOCSFAN		_IOW('v', 11, __u8)
+
+/* get temperature (C) */
+#define SONYPI_IOCGTEMP		_IOR('v', 12, __u8)
 
 #ifdef __KERNEL__
 
diff -Nru a/include/linux/spinlock.h b/include/linux/spinlock.h
--- a/include/linux/spinlock.h	2005-03-01 23:38:57 -08:00
+++ b/include/linux/spinlock.h	2005-03-01 23:38:57 -08:00
@@ -38,9 +38,12 @@
  * If CONFIG_SMP is set, pull in the _raw_* definitions
  */
 #ifdef CONFIG_SMP
+
+#define assert_spin_locked(x)	BUG_ON(!spin_is_locked(x))
 #include <asm/spinlock.h>
 
 int __lockfunc _spin_trylock(spinlock_t *lock);
+int __lockfunc _read_trylock(rwlock_t *lock);
 int __lockfunc _write_trylock(rwlock_t *lock);
 
 void __lockfunc _spin_lock(spinlock_t *lock)	__acquires(spinlock_t);
@@ -73,6 +76,7 @@
 void __lockfunc _write_unlock_bh(rwlock_t *lock)				__releases(rwlock_t);
 
 int __lockfunc _spin_trylock_bh(spinlock_t *lock);
+int __lockfunc generic_raw_read_trylock(rwlock_t *lock);
 int in_lock_functions(unsigned long addr);
 
 #else
@@ -143,6 +147,14 @@
 		0; \
 	})
 
+/* with debugging, assert_spin_locked() on UP does check
+ * the lock value properly */
+#define assert_spin_locked(x) \
+	({ \
+		CHECK_LOCK(x); \
+		BUG_ON(!(x)->lock); \
+	})
+
 /* without debugging, spin_trylock on UP always says
  * TRUE. --> printk if already locked. */
 #define _raw_spin_trylock(x) \
@@ -199,8 +211,9 @@
 #define spin_lock_init(lock)	do { (void)(lock); } while(0)
 #define _raw_spin_lock(lock)	do { (void)(lock); } while(0)
 #define spin_is_locked(lock)	((void)(lock), 0)
+#define assert_spin_locked(lock)	do { (void)(lock); } while(0)
 #define _raw_spin_trylock(lock)	(((void)(lock), 1))
-#define spin_unlock_wait(lock)	(void)(lock);
+#define spin_unlock_wait(lock)	(void)(lock)
 #define _raw_spin_unlock(lock) do { (void)(lock); } while(0)
 #endif /* CONFIG_DEBUG_SPINLOCK */
 
@@ -219,11 +232,17 @@
 #define _raw_read_unlock(lock)	do { (void)(lock); } while(0)
 #define _raw_write_lock(lock)	do { (void)(lock); } while(0)
 #define _raw_write_unlock(lock)	do { (void)(lock); } while(0)
+#define read_can_lock(lock)	(((void)(lock), 1))
+#define write_can_lock(lock)	(((void)(lock), 1))
+#define _raw_read_trylock(lock) ({ (void)(lock); (1); })
 #define _raw_write_trylock(lock) ({ (void)(lock); (1); })
 
 #define _spin_trylock(lock)	({preempt_disable(); _raw_spin_trylock(lock) ? \
 				1 : ({preempt_enable(); 0;});})
 
+#define _read_trylock(lock)	({preempt_disable();_raw_read_trylock(lock) ? \
+				1 : ({preempt_enable(); 0;});})
+
 #define _write_trylock(lock)	({preempt_disable(); _raw_write_trylock(lock) ? \
 				1 : ({preempt_enable(); 0;});})
 
@@ -425,16 +444,12 @@
  * methods are defined as nops in the case they are not required.
  */
 #define spin_trylock(lock)	__cond_lock(_spin_trylock(lock))
+#define read_trylock(lock)	__cond_lock(_read_trylock(lock))
 #define write_trylock(lock)	__cond_lock(_write_trylock(lock))
 
-/* Where's read_trylock? */
-
 #define spin_lock(lock)		_spin_lock(lock)
 #define write_lock(lock)	_write_lock(lock)
 #define read_lock(lock)		_read_lock(lock)
-#define spin_unlock(lock)	_spin_unlock(lock)
-#define write_unlock(lock)	_write_unlock(lock)
-#define read_unlock(lock)	_read_unlock(lock)
 
 #ifdef CONFIG_SMP
 #define spin_lock_irqsave(lock, flags)	flags = _spin_lock_irqsave(lock)
@@ -454,6 +469,11 @@
 
 #define write_lock_irq(lock)		_write_lock_irq(lock)
 #define write_lock_bh(lock)		_write_lock_bh(lock)
+
+#define spin_unlock(lock)	_spin_unlock(lock)
+#define write_unlock(lock)	_write_unlock(lock)
+#define read_unlock(lock)	_read_unlock(lock)
+
 #define spin_unlock_irqrestore(lock, flags)	_spin_unlock_irqrestore(lock, flags)
 #define spin_unlock_irq(lock)		_spin_unlock_irq(lock)
 #define spin_unlock_bh(lock)		_spin_unlock_bh(lock)
@@ -468,6 +488,20 @@
 
 #define spin_trylock_bh(lock)			__cond_lock(_spin_trylock_bh(lock))
 
+#define spin_trylock_irq(lock) \
+({ \
+	local_irq_disable(); \
+	_spin_trylock(lock) ? \
+	1 : ({local_irq_enable(); 0; }); \
+})
+
+#define spin_trylock_irqsave(lock, flags) \
+({ \
+	local_irq_save(flags); \
+	_spin_trylock(lock) ? \
+	1 : ({local_irq_restore(flags); 0;}); \
+})
+
 #ifdef CONFIG_LOCKMETER
 extern void _metered_spin_lock   (spinlock_t *lock);
 extern void _metered_spin_unlock (spinlock_t *lock);
@@ -476,6 +510,7 @@
 extern void _metered_read_unlock  (rwlock_t *lock);
 extern void _metered_write_lock   (rwlock_t *lock);
 extern void _metered_write_unlock (rwlock_t *lock);
+extern int  _metered_read_trylock (rwlock_t *lock);
 extern int  _metered_write_trylock(rwlock_t *lock);
 #endif
 
@@ -505,8 +540,11 @@
 	preempt_disable();
 #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
 	while (test_and_set_bit(bitnum, addr)) {
-		while (test_bit(bitnum, addr))
+		while (test_bit(bitnum, addr)) {
+			preempt_enable();
 			cpu_relax();
+			preempt_disable();
+		}
 	}
 #endif
 	__acquire(bitlock);
@@ -555,5 +593,14 @@
 	return 1;
 #endif
 }
+
+#define DEFINE_SPINLOCK(x) spinlock_t x = SPIN_LOCK_UNLOCKED
+#define DEFINE_RWLOCK(x) rwlock_t x = RW_LOCK_UNLOCKED
+
+/**
+ * spin_can_lock - would spin_trylock() succeed?
+ * @lock: the spinlock in question.
+ */
+#define spin_can_lock(lock)		(!spin_is_locked(lock))
 
 #endif /* __LINUX_SPINLOCK_H */
diff -Nru a/include/linux/sunrpc/auth.h b/include/linux/sunrpc/auth.h
--- a/include/linux/sunrpc/auth.h	2005-03-01 23:38:57 -08:00
+++ b/include/linux/sunrpc/auth.h	2005-03-01 23:38:57 -08:00
@@ -51,7 +51,6 @@
 };
 #define RPCAUTH_CRED_LOCKED	0x0001
 #define RPCAUTH_CRED_UPTODATE	0x0002
-#define RPCAUTH_CRED_DEAD	0x0004
 
 #define RPCAUTH_CRED_MAGIC	0x0f4aa4f0
 
@@ -114,8 +113,6 @@
 extern struct rpc_authops	authdes_ops;
 #endif
 
-u32			pseudoflavor_to_flavor(rpc_authflavor_t);
-
 int			rpcauth_register(struct rpc_authops *);
 int			rpcauth_unregister(struct rpc_authops *);
 struct rpc_auth *	rpcauth_create(rpc_authflavor_t, struct rpc_clnt *);
@@ -133,7 +130,6 @@
 int			rpcauth_refreshcred(struct rpc_task *);
 void			rpcauth_invalcred(struct rpc_task *);
 int			rpcauth_uptodatecred(struct rpc_task *);
-int			rpcauth_deadcred(struct rpc_task *);
 void			rpcauth_init_credcache(struct rpc_auth *);
 void			rpcauth_free_credcache(struct rpc_auth *);
 
diff -Nru a/include/linux/sunrpc/cache.h b/include/linux/sunrpc/cache.h
--- a/include/linux/sunrpc/cache.h	2005-03-01 23:38:57 -08:00
+++ b/include/linux/sunrpc/cache.h	2005-03-01 23:38:57 -08:00
@@ -257,8 +257,6 @@
 
 	     
 
-extern void cache_defer_req(struct cache_req *req, struct cache_head *item);
-extern void cache_revisit_request(struct cache_head *item);
 extern void cache_clean_deferred(void *owner);
 
 static inline struct cache_head  *cache_get(struct cache_head *h)
@@ -286,14 +284,11 @@
 			struct cache_head *head, time_t expiry);
 extern int cache_check(struct cache_detail *detail,
 		       struct cache_head *h, struct cache_req *rqstp);
-extern int cache_clean(void);
 extern void cache_flush(void);
 extern void cache_purge(struct cache_detail *detail);
 #define NEVER (0x7FFFFFFF)
 extern void cache_register(struct cache_detail *cd);
 extern int cache_unregister(struct cache_detail *cd);
-extern struct cache_detail *cache_find(char *name);
-extern void cache_drop(struct cache_detail *detail);
 
 extern void qword_add(char **bpp, int *lp, char *str);
 extern void qword_addhex(char **bpp, int *lp, char *buf, int blen);
diff -Nru a/include/linux/sunrpc/gss_asn1.h b/include/linux/sunrpc/gss_asn1.h
--- a/include/linux/sunrpc/gss_asn1.h	2005-03-01 23:39:19 -08:00
+++ b/include/linux/sunrpc/gss_asn1.h	2005-03-01 23:39:19 -08:00
@@ -71,8 +71,6 @@
      unsigned char **buf_in,
      int toksize);
 
-u32 g_get_mech_oid(struct xdr_netobj *mech, struct xdr_netobj * in_buf);
-
 int g_token_size(
      struct xdr_netobj *mech,
      unsigned int body_size);
diff -Nru a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h
--- a/include/linux/sunrpc/sched.h	2005-03-01 23:39:07 -08:00
+++ b/include/linux/sunrpc/sched.h	2005-03-01 23:39:07 -08:00
@@ -11,7 +11,9 @@
 
 #include <linux/timer.h>
 #include <linux/sunrpc/types.h>
+#include <linux/spinlock.h>
 #include <linux/wait.h>
+#include <linux/workqueue.h>
 #include <linux/sunrpc/xdr.h>
 
 /*
@@ -25,11 +27,18 @@
 	struct rpc_cred *	rpc_cred;	/* Credentials */
 };
 
+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 */
+};
+
 /*
  * This is the RPC task struct
  */
 struct rpc_task {
-	struct list_head	tk_list;	/* wait queue links */
 #ifdef RPC_DEBUG
 	unsigned long		tk_magic;	/* 0xf00baa */
 #endif
@@ -37,7 +46,6 @@
 	struct rpc_clnt *	tk_client;	/* RPC client */
 	struct rpc_rqst *	tk_rqstp;	/* RPC request */
 	int			tk_status;	/* result of last operation */
-	struct rpc_wait_queue *	tk_rpcwait;	/* RPC wait queue we're on */
 
 	/*
 	 * RPC call state
@@ -70,13 +78,18 @@
 	 * you have a pathological interest in kernel oopses.
 	 */
 	struct timer_list	tk_timer;	/* kernel timer */
-	wait_queue_head_t	tk_wait;	/* sync: sleep on this q */
 	unsigned long		tk_timeout;	/* timeout for rpc_sleep() */
 	unsigned short		tk_flags;	/* misc flags */
 	unsigned char		tk_active   : 1;/* Task has been activated */
 	unsigned char		tk_priority : 2;/* Task priority */
 	unsigned long		tk_runstate;	/* Task run status */
-	struct list_head	tk_links;	/* links to related tasks */
+	struct workqueue_struct	*tk_workqueue;	/* Normally rpciod, but could
+						 * be any workqueue
+						 */
+	union {
+		struct work_struct	tk_work;	/* Async task work queue */
+		struct rpc_wait		tk_wait;	/* RPC wait */
+	} u;
 #ifdef RPC_DEBUG
 	unsigned short		tk_pid;		/* debugging aid */
 #endif
@@ -87,11 +100,11 @@
 /* support walking a list of tasks on a wait queue */
 #define	task_for_each(task, pos, head) \
 	list_for_each(pos, head) \
-		if ((task=list_entry(pos, struct rpc_task, tk_list)),1)
+		if ((task=list_entry(pos, struct rpc_task, u.tk_wait.list)),1)
 
 #define	task_for_first(task, head) \
 	if (!list_empty(head) &&  \
-	    ((task=list_entry((head)->next, struct rpc_task, tk_list)),1))
+	    ((task=list_entry((head)->next, struct rpc_task, u.tk_wait.list)),1))
 
 /* .. and walking list of all tasks */
 #define	alltask_for_each(task, pos, head) \
@@ -126,22 +139,39 @@
 #define RPC_IS_SOFT(t)		((t)->tk_flags & RPC_TASK_SOFT)
 #define RPC_TASK_UNINTERRUPTIBLE(t) ((t)->tk_flags & RPC_TASK_NOINTR)
 
-#define RPC_TASK_SLEEPING	0
-#define RPC_TASK_RUNNING	1
-#define RPC_IS_SLEEPING(t)	(test_bit(RPC_TASK_SLEEPING, &(t)->tk_runstate))
-#define RPC_IS_RUNNING(t)	(test_bit(RPC_TASK_RUNNING, &(t)->tk_runstate))
+#define RPC_TASK_RUNNING	0
+#define RPC_TASK_QUEUED		1
+#define RPC_TASK_WAKEUP		2
+#define RPC_TASK_HAS_TIMER	3
 
+#define RPC_IS_RUNNING(t)	(test_bit(RPC_TASK_RUNNING, &(t)->tk_runstate))
 #define rpc_set_running(t)	(set_bit(RPC_TASK_RUNNING, &(t)->tk_runstate))
-#define rpc_clear_running(t)	(clear_bit(RPC_TASK_RUNNING, &(t)->tk_runstate))
+#define rpc_test_and_set_running(t) \
+				(test_and_set_bit(RPC_TASK_RUNNING, &(t)->tk_runstate))
+#define rpc_clear_running(t)	\
+	do { \
+		smp_mb__before_clear_bit(); \
+		clear_bit(RPC_TASK_RUNNING, &(t)->tk_runstate); \
+		smp_mb__after_clear_bit(); \
+	} while (0)
 
-#define rpc_set_sleeping(t)	(set_bit(RPC_TASK_SLEEPING, &(t)->tk_runstate))
+#define RPC_IS_QUEUED(t)	(test_bit(RPC_TASK_QUEUED, &(t)->tk_runstate))
+#define rpc_set_queued(t)	(set_bit(RPC_TASK_QUEUED, &(t)->tk_runstate))
+#define rpc_clear_queued(t)	\
+	do { \
+		smp_mb__before_clear_bit(); \
+		clear_bit(RPC_TASK_QUEUED, &(t)->tk_runstate); \
+		smp_mb__after_clear_bit(); \
+	} while (0)
 
-#define rpc_clear_sleeping(t) \
+#define rpc_start_wakeup(t) \
+	(test_and_set_bit(RPC_TASK_WAKEUP, &(t)->tk_runstate) == 0)
+#define rpc_finish_wakeup(t) \
 	do { \
 		smp_mb__before_clear_bit(); \
-		clear_bit(RPC_TASK_SLEEPING, &(t)->tk_runstate); \
+		clear_bit(RPC_TASK_WAKEUP, &(t)->tk_runstate); \
 		smp_mb__after_clear_bit(); \
-	} while(0)
+	} while (0)
 
 /*
  * Task priorities.
@@ -157,6 +187,7 @@
  * RPC synchronization objects
  */
 struct rpc_wait_queue {
+	spinlock_t		lock;
 	struct list_head	tasks[RPC_NR_PRIORITY];	/* task queue for each priority level */
 	unsigned long		cookie;			/* cookie of last task serviced */
 	unsigned char		maxpriority;		/* maximum priority (0 if queue is not a priority queue) */
@@ -177,6 +208,7 @@
 
 #ifndef RPC_DEBUG
 # define RPC_WAITQ_INIT(var,qname) { \
+		.lock = SPIN_LOCK_UNLOCKED, \
 		.tasks = { \
 			[0] = LIST_HEAD_INIT(var.tasks[0]), \
 			[1] = LIST_HEAD_INIT(var.tasks[1]), \
@@ -185,6 +217,7 @@
 	}
 #else
 # define RPC_WAITQ_INIT(var,qname) { \
+		.lock = SPIN_LOCK_UNLOCKED, \
 		.tasks = { \
 			[0] = LIST_HEAD_INIT(var.tasks[0]), \
 			[1] = LIST_HEAD_INIT(var.tasks[1]), \
@@ -209,20 +242,16 @@
 int		rpc_execute(struct rpc_task *);
 void		rpc_run_child(struct rpc_task *parent, struct rpc_task *child,
 					rpc_action action);
-int		rpc_add_wait_queue(struct rpc_wait_queue *, struct rpc_task *);
-void		rpc_remove_wait_queue(struct rpc_task *);
 void		rpc_init_priority_wait_queue(struct rpc_wait_queue *, const char *);
 void		rpc_init_wait_queue(struct rpc_wait_queue *, const char *);
 void		rpc_sleep_on(struct rpc_wait_queue *, struct rpc_task *,
 					rpc_action action, rpc_action timer);
-void		rpc_add_timer(struct rpc_task *, rpc_action);
 void		rpc_wake_up_task(struct rpc_task *);
 void		rpc_wake_up(struct rpc_wait_queue *);
 struct rpc_task *rpc_wake_up_next(struct rpc_wait_queue *);
 void		rpc_wake_up_status(struct rpc_wait_queue *, int);
 void		rpc_delay(struct rpc_task *, unsigned long);
 void *		rpc_malloc(struct rpc_task *, size_t);
-void		rpc_free(struct rpc_task *);
 int		rpciod_up(void);
 void		rpciod_down(void);
 void		rpciod_wake_up(void);
diff -Nru a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h
--- a/include/linux/sunrpc/xdr.h	2005-03-01 23:39:17 -08:00
+++ b/include/linux/sunrpc/xdr.h	2005-03-01 23:39:17 -08:00
@@ -95,7 +95,6 @@
 u32 *	xdr_decode_string_inplace(u32 *p, char **sp, int *lenp, int maxlen);
 u32 *	xdr_encode_netobj(u32 *p, const struct xdr_netobj *);
 u32 *	xdr_decode_netobj(u32 *p, struct xdr_netobj *);
-u32 *	xdr_decode_netobj_fixed(u32 *p, void *obj, unsigned int len);
 
 void	xdr_encode_pages(struct xdr_buf *, struct page **, unsigned int,
 			 unsigned int);
@@ -135,8 +134,6 @@
 	return iov->iov_len = ((u8 *) p - (u8 *) iov->iov_base);
 }
 
-void xdr_shift_iovec(struct kvec *, int, size_t);
-
 /*
  * Maximum number of iov's we use.
  */
@@ -145,10 +142,7 @@
 /*
  * XDR buffer helper functions
  */
-extern int xdr_kmap(struct kvec *, struct xdr_buf *, size_t);
-extern void xdr_kunmap(struct xdr_buf *, size_t);
 extern void xdr_shift_buf(struct xdr_buf *, size_t);
-extern void _copy_from_pages(char *, struct page **, size_t, size_t);
 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);
diff -Nru a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h
--- a/include/linux/sunrpc/xprt.h	2005-03-01 23:39:08 -08:00
+++ b/include/linux/sunrpc/xprt.h	2005-03-01 23:39:08 -08:00
@@ -201,8 +201,6 @@
 struct rpc_xprt *	xprt_create_proto(int proto, struct sockaddr_in *addr,
 					struct rpc_timeout *toparms);
 int			xprt_destroy(struct rpc_xprt *);
-void			xprt_shutdown(struct rpc_xprt *);
-void			xprt_default_timeout(struct rpc_timeout *, int);
 void			xprt_set_timeout(struct rpc_timeout *, unsigned int,
 					unsigned long);
 
@@ -213,7 +211,6 @@
 int			xprt_adjust_timeout(struct rpc_rqst *req);
 void			xprt_release(struct rpc_task *);
 void			xprt_connect(struct rpc_task *);
-int			xprt_clear_backlog(struct rpc_xprt *);
 void			xprt_sock_setbufsize(struct rpc_xprt *);
 
 #define XPRT_LOCKED	0
diff -Nru a/include/linux/suspend.h b/include/linux/suspend.h
--- a/include/linux/suspend.h	2005-03-01 23:38:54 -08:00
+++ b/include/linux/suspend.h	2005-03-01 23:38:54 -08:00
@@ -1,7 +1,7 @@
 #ifndef _LINUX_SWSUSP_H
 #define _LINUX_SWSUSP_H
 
-#ifdef CONFIG_X86
+#if defined(CONFIG_X86) || defined(CONFIG_FRV)
 #include <asm/suspend.h>
 #endif
 #include <linux/swap.h>
@@ -10,7 +10,6 @@
 #include <linux/init.h>
 #include <linux/pm.h>
 
-#ifdef CONFIG_PM
 /* page backup entry */
 typedef struct pbe {
 	unsigned long address;		/* address of the copy */
@@ -31,30 +30,22 @@
 
 /* mm/page_alloc.c */
 extern void drain_local_pages(void);
+extern void mark_free_pages(struct zone *zone);
 
+#ifdef CONFIG_PM
 /* kernel/power/swsusp.c */
 extern int software_suspend(void);
 
-#else	/* CONFIG_SOFTWARE_SUSPEND */
+extern int pm_prepare_console(void);
+extern void pm_restore_console(void);
+
+#else
 static inline int software_suspend(void)
 {
 	printk("Warning: fake suspend called\n");
 	return -EPERM;
 }
-#endif	/* CONFIG_SOFTWARE_SUSPEND */
-
-
-#ifdef CONFIG_PM
-extern void refrigerator(unsigned long);
-extern int freeze_processes(void);
-extern void thaw_processes(void);
-
-extern int pm_prepare_console(void);
-extern void pm_restore_console(void);
-
-#else
-static inline void refrigerator(unsigned long flag) {}
-#endif	/* CONFIG_PM */
+#endif
 
 #ifdef CONFIG_SMP
 extern void disable_nonboot_cpus(void);
diff -Nru a/include/linux/syscalls.h b/include/linux/syscalls.h
--- a/include/linux/syscalls.h	2005-03-01 23:39:18 -08:00
+++ b/include/linux/syscalls.h	2005-03-01 23:39:18 -08:00
@@ -63,7 +63,7 @@
 #include <linux/quota.h>
 #include <linux/key.h>
 
-asmlinkage long sys_time(int __user *tloc);
+asmlinkage long sys_time(time_t __user *tloc);
 asmlinkage long sys_stime(time_t __user *tptr);
 asmlinkage long sys_gettimeofday(struct timeval __user *tv,
 				struct timezone __user *tz);
diff -Nru a/include/linux/sysctl.h b/include/linux/sysctl.h
--- a/include/linux/sysctl.h	2005-03-01 23:38:58 -08:00
+++ b/include/linux/sysctl.h	2005-03-01 23:38:58 -08:00
@@ -134,6 +134,7 @@
 	KERN_SPARC_SCONS_PWROFF=64, /* int: serial console power-off halt */
 	KERN_HZ_TIMER=65,	/* int: hz timer on or off */
 	KERN_UNKNOWN_NMI_PANIC=66, /* int: unknown nmi panic flag */
+	KERN_BOOTLOADER_TYPE=67, /* int: boot loader type */
 };
 
 
@@ -159,7 +160,7 @@
 	VM_PAGEBUF=17,		/* struct: Control pagebuf parameters */
 	VM_HUGETLB_PAGES=18,	/* int: Number of available Huge Pages */
 	VM_SWAPPINESS=19,	/* Tendency to steal mapped memory */
-	VM_LOWER_ZONE_PROTECTION=20,/* Amount of protection of lower zones */
+	VM_LOWMEM_RESERVE_RATIO=20,/* reservation ratio for lower memory zones */
 	VM_MIN_FREE_KBYTES=21,	/* Minimum free kilobytes to maintain */
 	VM_MAX_MAP_COUNT=22,	/* int: Maximum number of mmaps/address-space */
 	VM_LAPTOP_MODE=23,	/* vm laptop mode */
@@ -343,6 +344,7 @@
 	NET_TCP_DEFAULT_WIN_SCALE=105,
 	NET_TCP_MODERATE_RCVBUF=106,
 	NET_TCP_TSO_WIN_DIVISOR=107,
+	NET_TCP_BIC_BETA=108,
 };
 
 enum {
@@ -364,6 +366,7 @@
 	NET_IPV4_ROUTE_MIN_PMTU=16,
 	NET_IPV4_ROUTE_MIN_ADVMSS=17,
 	NET_IPV4_ROUTE_SECRET_INTERVAL=18,
+	NET_IPV4_ROUTE_GC_MIN_INTERVAL_MS=19,
 };
 
 enum
@@ -663,7 +666,7 @@
 	FS_LEASES=13,	/* int: leases enabled */
 	FS_DIR_NOTIFY=14,	/* int: directory notification enabled */
 	FS_LEASE_TIME=15,	/* int: maximum time to wait for a lease break */
-	FS_DQSTATS=16,	/* disc quota usage statistics */
+	FS_DQSTATS=16,	/* disc quota usage statistics and control */
 	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 */
@@ -679,6 +682,7 @@
 	FS_DQ_ALLOCATED = 6,
 	FS_DQ_FREE = 7,
 	FS_DQ_SYNCS = 8,
+	FS_DQ_WARNINGS = 9,
 };
 
 /* CTL_DEBUG names: */
@@ -793,6 +797,8 @@
 				 void __user *, size_t *, loff_t *);
 extern int proc_dointvec_userhz_jiffies(ctl_table *, int, struct file *,
 					void __user *, size_t *, loff_t *);
+extern int proc_dointvec_ms_jiffies(ctl_table *, int, struct file *,
+				    void __user *, size_t *, loff_t *);
 extern int proc_doulongvec_minmax(ctl_table *, int, struct file *,
 				  void __user *, size_t *, loff_t *);
 extern int proc_doulongvec_ms_jiffies_minmax(ctl_table *table, int,
@@ -810,6 +816,7 @@
 extern ctl_handler sysctl_string;
 extern ctl_handler sysctl_intvec;
 extern ctl_handler sysctl_jiffies;
+extern ctl_handler sysctl_ms_jiffies;
 
 
 /*
diff -Nru a/include/linux/sysfs.h b/include/linux/sysfs.h
--- a/include/linux/sysfs.h	2005-03-01 23:39:18 -08:00
+++ b/include/linux/sysfs.h	2005-03-01 23:39:18 -08:00
@@ -2,6 +2,7 @@
  * sysfs.h - definitions for the device driver filesystem
  *
  * Copyright (c) 2001,2002 Patrick Mochel
+ * Copyright (c) 2004 Silicon Graphics, Inc.
  *
  * Please see Documentation/filesystems/sysfs.txt for more information.
  */
@@ -47,11 +48,16 @@
 
 #define attr_name(_attr) (_attr).attr.name
 
+struct vm_area_struct;
+
 struct bin_attribute {
 	struct attribute	attr;
 	size_t			size;
+	void			*private;
 	ssize_t (*read)(struct kobject *, char *, loff_t, size_t);
 	ssize_t (*write)(struct kobject *, char *, loff_t, size_t);
+	int (*mmap)(struct kobject *, struct bin_attribute *attr,
+		    struct vm_area_struct *vma);
 };
 
 struct sysfs_ops {
diff -Nru a/include/linux/tcp.h b/include/linux/tcp.h
--- a/include/linux/tcp.h	2005-03-01 23:38:57 -08:00
+++ b/include/linux/tcp.h	2005-03-01 23:38:57 -08:00
@@ -203,10 +203,6 @@
 	__u32	end_seq;
 };
 
-typedef struct tcp_pcount {
-	__u32	val;
-} tcp_pcount_t;
-
 enum tcp_congestion_algo {
 	TCP_RENO=0,
 	TCP_VEGAS,
@@ -214,7 +210,30 @@
 	TCP_BIC,
 };
 
-struct tcp_opt {
+struct tcp_options_received {
+/*	PAWS/RTTM data	*/
+	long	ts_recent_stamp;/* Time we stored ts_recent (for aging) */
+	__u32	ts_recent;	/* Time stamp to echo next		*/
+	__u32	rcv_tsval;	/* Time stamp value             	*/
+	__u32	rcv_tsecr;	/* Time stamp echo reply        	*/
+	char	saw_tstamp;	/* Saw TIMESTAMP on last packet		*/
+	char	tstamp_ok;	/* TIMESTAMP seen on SYN packet		*/
+	char	sack_ok;	/* SACK seen on SYN packet		*/
+	char	wscale_ok;	/* Wscale seen on SYN packet		*/
+	__u8	snd_wscale;	/* Window scaling received from sender	*/
+	__u8	rcv_wscale;	/* Window scaling to send to receiver	*/
+/*	SACKs data	*/
+	__u8	dsack;		/* D-SACK is scheduled			*/
+	__u8	eff_sacks;	/* Size of SACK array to send with next packet */
+	__u8	num_sacks;	/* Number of SACK blocks		*/
+	__u8	__pad;
+	__u16	user_mss;  	/* mss requested by user in ioctl */
+	__u16	mss_clamp;	/* Maximal mss, negotiated at connection setup */
+};
+
+struct tcp_sock {
+	/* inet_sock has to be the first member of tcp_sock */
+	struct inet_sock	inet;
 	int	tcp_header_len;	/* Bytes of tcp header to send		*/
 
 /*
@@ -264,22 +283,19 @@
 	__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	mss_clamp;	/* Maximal mss, negotiated at connection setup */
 	__u16	ext_header_len;	/* Network protocol overhead (IP/IPv6 options) */
 	__u16	ext2_header_len;/* Options depending on route */
 	__u8	ca_state;	/* State of fast-retransmit machine 	*/
 	__u8	retransmits;	/* Number of unrecovered RTO timeouts.	*/
 
+	__u32	frto_highmark;	/* snd_nxt when RTO occurred */
 	__u8	reordering;	/* Packet reordering metric.		*/
 	__u8	frto_counter;	/* Number of new acks after RTO */
-	__u32	frto_highmark;	/* snd_nxt when RTO occurred */
 
 	__u8	adv_cong;	/* Using Vegas, Westwood, or BIC */
 	__u8	defer_accept;	/* User waits for some data after accept() */
-	/* one byte hole, try to pack */
 
 /* RTT measurement */
-	__u8	backoff;	/* backoff				*/
 	__u32	srtt;		/* smoothed round trip time << 3	*/
 	__u32	mdev;		/* medium deviation			*/
 	__u32	mdev_max;	/* maximal mdev for the last rtt period	*/
@@ -287,10 +303,18 @@
 	__u32	rtt_seq;	/* sequence number to update rttvar	*/
 	__u32	rto;		/* retransmit timeout			*/
 
-	tcp_pcount_t packets_out; /* Packets which are "in flight"	*/
-	tcp_pcount_t left_out;	  /* Packets which leaved network	*/
-	tcp_pcount_t retrans_out; /* Retransmitted packets out		*/
+	__u32	packets_out;	/* Packets which are "in flight"	*/
+	__u32	left_out;	/* Packets which leaved network	*/
+	__u32	retrans_out;	/* Retransmitted packets out		*/
+	__u8	backoff;	/* backoff				*/
+/*
+ *      Options received (usually on last packet, some only on SYN packets).
+ */
+	__u8	nonagle;	/* Disable Nagle algorithm?             */
+	__u8	keepalive_probes; /* num of allowed keep alive probes	*/
 
+	__u8	probes_out;	/* unanswered 0 window probes		*/
+	struct tcp_options_received rx_opt;
 
 /*
  *	Slow start and congestion control (see also Nagle, and Karn & Partridge)
@@ -316,43 +340,22 @@
 	__u32	write_seq;	/* Tail(+1) of data held in tcp send buffer */
 	__u32	pushed_seq;	/* Last pushed seq, required to talk to windows */
 	__u32	copied_seq;	/* Head of yet unread data		*/
-/*
- *      Options received (usually on last packet, some only on SYN packets).
- */
-	char	tstamp_ok,	/* TIMESTAMP seen on SYN packet		*/
-		wscale_ok,	/* Wscale seen on SYN packet		*/
-		sack_ok;	/* SACK seen on SYN packet		*/
-	char	saw_tstamp;	/* Saw TIMESTAMP on last packet		*/
-        __u8	snd_wscale;	/* Window scaling received from sender	*/
-        __u8	rcv_wscale;	/* Window scaling to send to receiver	*/
-	__u8	nonagle;	/* Disable Nagle algorithm?             */
-	__u8	keepalive_probes; /* num of allowed keep alive probes	*/
-
-/*	PAWS/RTTM data	*/
-        __u32	rcv_tsval;	/* Time stamp value             	*/
-        __u32	rcv_tsecr;	/* Time stamp echo reply        	*/
-        __u32	ts_recent;	/* Time stamp to echo next		*/
-        long	ts_recent_stamp;/* Time we stored ts_recent (for aging) */
 
 /*	SACKs data	*/
-	__u16	user_mss;  	/* mss requested by user in ioctl */
-	__u8	dsack;		/* D-SACK is scheduled			*/
-	__u8	eff_sacks;	/* Size of SACK array to send with next packet */
 	struct tcp_sack_block duplicate_sack[1]; /* D-SACK block */
 	struct tcp_sack_block selective_acks[4]; /* The SACKS themselves*/
 
 	__u32	window_clamp;	/* Maximal window to advertise		*/
 	__u32	rcv_ssthresh;	/* Current window clamp			*/
-	__u8	probes_out;	/* unanswered 0 window probes		*/
-	__u8	num_sacks;	/* Number of SACK blocks		*/
 	__u16	advmss;		/* Advertised MSS			*/
 
 	__u8	syn_retries;	/* num of allowed syn retries */
 	__u8	ecn_flags;	/* ECN status bits.			*/
 	__u16	prior_ssthresh; /* ssthresh saved at recovery start	*/
-	tcp_pcount_t lost_out;	/* Lost packets			*/
-	tcp_pcount_t sacked_out;/* SACK'd packets			*/
-	tcp_pcount_t fackets_out;/* FACK'd packets			*/
+	__u16	__pad1;
+	__u32	lost_out;	/* Lost packets			*/
+	__u32	sacked_out;	/* SACK'd packets			*/
+	__u32	fackets_out;	/* FACK'd packets			*/
 	__u32	high_seq;	/* snd_nxt at onset of congestion	*/
 
 	__u32	retrans_stamp;	/* Timestamp of the last retransmit,
@@ -438,19 +441,9 @@
 	} bictcp;
 };
 
-/* WARNING: don't change the layout of the members in tcp_sock! */
-struct tcp_sock {
-	struct sock	  sk;
-#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-	struct ipv6_pinfo *pinet6;
-#endif
-	struct inet_opt	  inet;
-	struct tcp_opt	  tcp;
-};
-
-static inline struct tcp_opt * tcp_sk(const struct sock *__sk)
+static inline struct tcp_sock *tcp_sk(const struct sock *sk)
 {
-	return &((struct tcp_sock *)__sk)->tcp;
+	return (struct tcp_sock *)sk;
 }
 
 #endif
diff -Nru a/include/linux/time.h b/include/linux/time.h
--- a/include/linux/time.h	2005-03-01 23:39:07 -08:00
+++ b/include/linux/time.h	2005-03-01 23:39:07 -08:00
@@ -90,6 +90,7 @@
 struct timespec current_kernel_time(void);
 
 #define CURRENT_TIME (current_kernel_time())
+#define CURRENT_TIME_SEC ((struct timespec) { xtime.tv_sec, 0 })
 
 extern void do_gettimeofday(struct timeval *tv);
 extern int do_settimeofday(struct timespec *tv);
@@ -102,6 +103,8 @@
 extern int do_setitimer(int which, struct itimerval *value, struct itimerval *ovalue);
 extern int do_getitimer(int which, struct itimerval *value);
 extern void getnstimeofday (struct timespec *tv);
+
+extern struct timespec timespec_trunc(struct timespec t, unsigned gran);
 
 static inline void
 set_normalized_timespec (struct timespec *ts, time_t sec, long nsec)
diff -Nru a/include/linux/topology.h b/include/linux/topology.h
--- a/include/linux/topology.h	2005-03-01 23:39:08 -08:00
+++ b/include/linux/topology.h	2005-03-01 23:39:08 -08:00
@@ -43,19 +43,15 @@
 	})
 #endif
 
-static inline int __next_node_with_cpus(int node)
-{
-	do
-		++node;
-	while (node < numnodes && !nr_cpus_node(node));
-	return node;
-}
-
-#define for_each_node_with_cpus(node) \
-	for (node = 0; node < numnodes; node = __next_node_with_cpus(node))
+#define for_each_node_with_cpus(node)						\
+	for_each_online_node(node)						\
+		if (nr_cpus_node(node))
 
 #ifndef node_distance
-#define node_distance(from,to)	((from) != (to))
+/* Conform to ACPI 2.0 SLIT distance definitions */
+#define LOCAL_DISTANCE		10
+#define REMOTE_DISTANCE		20
+#define node_distance(from,to)	((from) == (to) ? LOCAL_DISTANCE : REMOTE_DISTANCE)
 #endif
 #ifndef PENALTY_FOR_NODE_WITH_CPUS
 #define PENALTY_FOR_NODE_WITH_CPUS	(1)
@@ -113,13 +109,14 @@
 	.max_interval		= 4,			\
 	.busy_factor		= 64,			\
 	.imbalance_pct		= 125,			\
-	.cache_hot_time		= (5*1000/2),		\
+	.cache_hot_time		= (5*1000000/2),	\
 	.cache_nice_tries	= 1,			\
 	.per_cpu_gain		= 100,			\
 	.flags			= SD_LOAD_BALANCE	\
 				| SD_BALANCE_NEWIDLE	\
 				| SD_BALANCE_EXEC	\
 				| SD_WAKE_AFFINE	\
+				| SD_WAKE_IDLE		\
 				| SD_WAKE_BALANCE,	\
 	.last_balance		= jiffies,		\
 	.balance_interval	= 1,			\
diff -Nru a/include/linux/transport_class.h b/include/linux/transport_class.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/linux/transport_class.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,77 @@
+/*
+ * transport_class.h - a generic container for all transport classes
+ *
+ * Copyright (c) 2005 - James Bottomley <James.Bottomley@steeleye.com>
+ *
+ * This file is licensed under GPLv2
+ */
+
+#ifndef _TRANSPORT_CLASS_H_
+#define _TRANSPORT_CLASS_H_
+
+#include <linux/device.h>
+#include <linux/attribute_container.h>
+
+struct transport_class {
+	struct class class;
+	int (*setup)(struct device *);
+	int (*configure)(struct device *);
+	int (*remove)(struct device *);
+};
+
+#define DECLARE_TRANSPORT_CLASS(cls, nm, su, rm, cfg)			\
+struct transport_class cls = {						\
+	.class = {							\
+		.name = nm,						\
+	},								\
+	.setup = su,							\
+	.remove = rm,							\
+	.configure = cfg,						\
+}
+
+
+struct anon_transport_class {
+	struct transport_class tclass;
+	struct attribute_container container;
+};
+
+#define DECLARE_ANON_TRANSPORT_CLASS(cls, mtch, cfg)		\
+struct anon_transport_class cls = {				\
+	.tclass = {						\
+		.configure = cfg,				\
+	},							\
+	. container = {						\
+		.match = mtch,					\
+	},							\
+}
+
+#define class_to_transport_class(x) \
+	container_of(x, struct transport_class, class)
+
+void transport_remove_device(struct device *);
+void transport_add_device(struct device *);
+void transport_setup_device(struct device *);
+void transport_configure_device(struct device *);
+void transport_destroy_device(struct device *);
+
+static inline void
+transport_register_device(struct device *dev)
+{
+	transport_setup_device(dev);
+	transport_add_device(dev);
+}
+
+static inline void
+transport_unregister_device(struct device *dev)
+{
+	transport_remove_device(dev);
+	transport_destroy_device(dev);
+}
+
+int transport_class_register(struct transport_class *);
+int anon_transport_class_register(struct anon_transport_class *);
+void transport_class_unregister(struct transport_class *);
+void anon_transport_class_unregister(struct anon_transport_class *);
+
+
+#endif
diff -Nru a/include/linux/trdevice.h b/include/linux/trdevice.h
--- a/include/linux/trdevice.h	2005-03-01 23:38:54 -08:00
+++ b/include/linux/trdevice.h	2005-03-01 23:38:54 -08:00
@@ -28,10 +28,6 @@
 #include <linux/if_tr.h>
 
 #ifdef __KERNEL__
-extern int		tr_header(struct sk_buff *skb, struct net_device *dev,
-				   unsigned short type, void *daddr,
-				   void *saddr, unsigned len);
-extern int		tr_rebuild_header(struct sk_buff *skb);
 extern unsigned short	tr_type_trans(struct sk_buff *skb, struct net_device *dev);
 extern void tr_source_route(struct sk_buff *skb, struct trh_hdr *trh, struct net_device *dev);
 extern struct net_device *alloc_trdev(int sizeof_priv);
diff -Nru a/include/linux/udf_fs_sb.h b/include/linux/udf_fs_sb.h
--- a/include/linux/udf_fs_sb.h	2005-03-01 23:39:16 -08:00
+++ b/include/linux/udf_fs_sb.h	2005-03-01 23:39:16 -08:00
@@ -18,6 +18,8 @@
 #ifndef _UDF_FS_SB_H
 #define _UDF_FS_SB_H 1
 
+#include <asm/semaphore.h>
+
 #pragma pack(1)
 
 #define UDF_MAX_BLOCK_LOADED	8
@@ -113,6 +115,8 @@
 
 	/* VAT inode */
 	struct inode		*s_vat;
+
+	struct semaphore	s_alloc_sem;
 };
 
 #endif /* _UDF_FS_SB_H */
diff -Nru a/include/linux/udp.h b/include/linux/udp.h
--- a/include/linux/udp.h	2005-03-01 23:38:53 -08:00
+++ b/include/linux/udp.h	2005-03-01 23:38:53 -08:00
@@ -40,30 +40,22 @@
 #include <net/sock.h>
 #include <linux/ip.h>
 
-struct udp_opt {
-	int		pending;	/* Any pending frames ? */
-	unsigned int	corkflag;	/* Cork is required */
-  	__u16		encap_type;	/* Is this an Encapsulation socket? */
+struct udp_sock {
+	/* inet_sock has to be the first member */
+	struct inet_sock inet;
+	int		 pending;	/* Any pending frames ? */
+	unsigned int	 corkflag;	/* Cork is required */
+  	__u16		 encap_type;	/* Is this an Encapsulation socket? */
 	/*
 	 * Following member retains the infomation to create a UDP header
 	 * when the socket is uncorked.
 	 */
-	__u16		len;		/* total length of pending frames */
-};
-
-/* WARNING: don't change the layout of the members in udp_sock! */
-struct udp_sock {
-	struct sock	  sk;
-#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-	struct ipv6_pinfo *pinet6;
-#endif
-	struct inet_opt	  inet;
-	struct udp_opt	  udp;
+	__u16		 len;		/* total length of pending frames */
 };
 
-static inline struct udp_opt * udp_sk(const struct sock *__sk)
+static inline struct udp_sock *udp_sk(const struct sock *sk)
 {
-	return &((struct udp_sock *)__sk)->udp;
+	return (struct udp_sock *)sk;
 }
 
 #endif
diff -Nru a/include/linux/umsdos_fs.h b/include/linux/umsdos_fs.h
--- a/include/linux/umsdos_fs.h	2005-03-01 23:39:18 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,182 +0,0 @@
-#ifndef LINUX_UMSDOS_FS_H
-#define LINUX_UMSDOS_FS_H
-
-
-/*#define UMS_DEBUG 1	// define for check_* functions */
-/*#define UMSDOS_DEBUG 1*/
-#define UMSDOS_PARANOIA 1
-
-#define UMSDOS_VERSION	0
-#define UMSDOS_RELEASE	4
-
-#define UMSDOS_ROOT_INO 1
-
-/* This is the file acting as a directory extension */
-#define UMSDOS_EMD_FILE		"--linux-.---"
-#define UMSDOS_EMD_NAMELEN	12
-#define UMSDOS_PSDROOT_NAME	"linux"
-#define UMSDOS_PSDROOT_LEN	5
-
-#ifndef _LINUX_TYPES_H
-#include <linux/types.h>
-#endif
-#ifndef _LINUX_LIMITS_H
-#include <linux/limits.h>
-#endif
-#ifndef _LINUX_DIRENT_H
-#include <linux/dirent.h>
-#endif
-#ifndef _LINUX_IOCTL_H
-#include <linux/ioctl.h>
-#endif
-
-
-#ifdef __KERNEL__
-/* #Specification: convention / PRINTK Printk and printk
- * Here is the convention for the use of printk inside fs/umsdos
- * 
- * printk carry important message (error or status).
- * Printk is for debugging (it is a macro defined at the beginning of
- * most source.
- * PRINTK is a nulled Printk macro.
- * 
- * This convention makes the source easier to read, and Printk easier
- * to shut off.
- */
-#	define PRINTK(x)
-#	ifdef UMSDOS_DEBUG
-#		define Printk(x) printk x
-#	else
-#		define Printk(x)
-#	endif
-#endif	/* __KERNEL__ */
-
-
-struct umsdos_fake_info {
-	char fname[13];
-	int len;
-};
-
-#define UMSDOS_MAXNAME	220
-/* This structure is 256 bytes large, depending on the name, only part */
-/* of it is written to disk */
-/* nice though it would be, I can't change this and preserve backward compatibility */
-struct umsdos_dirent {
-	unsigned char name_len;	/* if == 0, then this entry is not used */
-	unsigned char flags;	/* UMSDOS_xxxx */
-	unsigned short nlink;	/* How many hard links point to this entry */
-	__kernel_uid_t uid;	/* Owner user id */
-	__kernel_gid_t gid;	/* Group id */
-	time_t atime;		/* Access time */
-	time_t mtime;		/* Last modification time */
-	time_t ctime;		/* Creation time */
-	unsigned short rdev;	/* major and minor of a device special file */
-	umode_t mode;		/* Standard UNIX permissions bits + type of */
-	char spare[12];		/* unused bytes for future extensions */
-				/* file, see linux/stat.h */
-	char name[UMSDOS_MAXNAME];	/* Not '\0' terminated */
-				/* but '\0' padded, so it will allow */
-				/* for adding news fields in this record */
-				/* by reducing the size of name[] */
-};
-
-#define UMSDOS_HIDDEN	1	/* Never show this entry in directory search */
-#define UMSDOS_HLINK	2	/* It is a (pseudo) hard link */
-
-/* #Specification: EMD file / record size
- * Entry are 64 bytes wide in the EMD file. It allows for a 30 characters
- * name. If a name is longer, contiguous entries are allocated. So a
- * umsdos_dirent may span multiple records.
- */
- 
-#define UMSDOS_REC_SIZE		64
-
-/* Translation between MSDOS name and UMSDOS name */
-
-struct umsdos_info {
-	int msdos_reject;	/* Tell if the file name is invalid for MSDOS */
-				/* See umsdos_parse */
-	struct umsdos_fake_info fake;
-	struct umsdos_dirent entry;
-	off_t f_pos;		/* offset of the entry in the EMD file
-				 * or offset where the entry may be store
-				 * if it is a new entry
-				 */
-	int recsize;		/* Record size needed to store entry */
-};
-
-/* Definitions for ioctl (number randomly chosen)
- * The next ioctl commands operate only on the DOS directory
- * The file umsdos_progs/umsdosio.c contain a string table
- * based on the order of those definition. Keep it in sync
- */
-#define UMSDOS_READDIR_DOS _IO(0x04,210)	/* Do a readdir of the DOS directory */
-#define UMSDOS_UNLINK_DOS  _IO(0x04,211)	/* Erase in the DOS directory only */
-#define UMSDOS_RMDIR_DOS   _IO(0x04,212)	/* rmdir in the DOS directory only */
-#define UMSDOS_STAT_DOS    _IO(0x04,213)	/* Get info about a file */
-
-/* The next ioctl commands operate only on the EMD file */
-#define UMSDOS_CREAT_EMD   _IO(0x04,214)	/* Create a file */
-#define UMSDOS_UNLINK_EMD  _IO(0x04,215)	/* unlink (rmdir) a file */
-#define UMSDOS_READDIR_EMD _IO(0x04,216)	/* read the EMD file only. */
-#define UMSDOS_GETVERSION  _IO(0x04,217)	/* Get the release number of UMSDOS */
-#define UMSDOS_INIT_EMD    _IO(0x04,218)	/* Create the EMD file if not there */
-#define UMSDOS_DOS_SETUP   _IO(0x04,219)	/* Set the defaults of the MS-DOS driver. */
-
-#define UMSDOS_RENAME_DOS  _IO(0x04,220)	/* rename a file/directory in the DOS
-						 * directory only */
-struct umsdos_ioctl {
-	struct dirent dos_dirent;
-	struct umsdos_dirent umsdos_dirent;
-	/* The following structure is used to exchange some data with
-	 * utilities (umsdos_progs/util/umsdosio.c). The first releases
-	 * were using struct stat from "sys/stat.h". This was causing
-	 * some problem for cross compilation of the kernel.
-	 * Since I am not really using the structure stat, but only
-	 * some fields of it, I have decided to replicate the structure
-	 * here for compatibility with the binaries out there.
-	 * FIXME PTW 1998, this has probably changed
-	 */
-	
-	struct {
-		unsigned long st_dev;
-		ino_t st_ino;			/* used */
-		umode_t st_mode;		/* used */
-		nlink_t st_nlink;
-		__kernel_uid_t st_uid;
-		__kernel_gid_t st_gid;
-		unsigned long st_rdev;
-		off_t st_size;			/* used */
-		unsigned long st_blksize;
-		unsigned long st_blocks;
-		time_t st_atime;		/* used */
-		unsigned long __unused1;
-		time_t st_mtime;		/* used */
-		unsigned long __unused2;
-		time_t st_ctime;		/* used */
-		unsigned long __unused3;
-		uid_t st_uid32;
-		gid_t st_gid32;
-	} stat;
-	char version, release;
-};
-
-/* Different macros to access struct umsdos_dirent */
-#define EDM_ENTRY_ISUSED(e) ((e)->name_len!=0)
-
-#ifdef __KERNEL__
-
-#ifndef LINUX_FS_H
-#include <linux/fs.h>
-#endif
-
-extern struct inode_operations umsdos_dir_inode_operations;
-extern struct inode_operations umsdos_rdir_inode_operations;
-extern struct file_operations umsdos_dir_operations;
-extern struct file_operations umsdos_rdir_operations;
-
-#include <linux/umsdos_fs.p>
-
-#endif				/* __KERNEL__ */
-
-#endif
diff -Nru a/include/linux/umsdos_fs.p b/include/linux/umsdos_fs.p
--- a/include/linux/umsdos_fs.p	2005-03-01 23:38:54 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,100 +0,0 @@
-/* check.c 23/01/95 03.38.30 */
-void check_page_tables (void);
-
-/* dir.c 22/06/95 00.22.12 */
-int  dummy_dir_read ( struct file *filp,
-	 char *buf,
-	 size_t size,
-	 loff_t *count);
-char * umsdos_d_path(struct dentry *, char *, int);
-void umsdos_lookup_patch_new(struct dentry *, struct umsdos_info *);
-int umsdos_is_pseudodos (struct inode *dir, struct dentry *dentry);
-struct dentry *umsdos_lookup_x ( struct inode *dir, struct dentry *dentry, int nopseudo);
-struct dentry *UMSDOS_lookup(struct inode *, struct dentry *, struct nameidata *);
-struct dentry *umsdos_lookup_dentry(struct dentry *, char *, int, int);
-struct dentry *umsdos_covered(struct dentry *, char *, int);
-
-struct dentry *umsdos_solve_hlink (struct dentry *hlink);
-
-/* emd.c 22/06/95 00.22.04 */
-struct dentry *umsdos_get_emd_dentry(struct dentry *);
-int umsdos_have_emd(struct dentry *);
-int umsdos_make_emd(struct dentry *);
-int umsdos_emd_dir_readentry (struct dentry *, loff_t *, struct umsdos_dirent *);
-int umsdos_newentry (struct dentry *, struct umsdos_info *);
-int umsdos_newhidden (struct dentry *, struct umsdos_info *);
-int umsdos_delentry (struct dentry *, struct umsdos_info *, int);
-int umsdos_findentry (struct dentry *, struct umsdos_info *, int);
-int umsdos_isempty (struct dentry *);
-int umsdos_writeentry (struct dentry *, struct umsdos_info *, int);
-
-/* file.c 25/01/95 02.25.38 */
-
-/* inode.c 12/06/95 09.49.40 */
-void fill_new_filp (struct file *filp, struct dentry *dentry);
-void UMSDOS_read_inode (struct inode *);
-void UMSDOS_write_inode (struct inode *, int);
-int UMSDOS_notify_change (struct dentry *, struct iattr *attr);
-int umsdos_notify_change_locked(struct dentry *, struct iattr *attr);
-void UMSDOS_put_inode (struct inode *);
-int UMSDOS_statfs (struct super_block *, struct statfs *);
-struct super_block *UMSDOS_read_super (struct super_block *, void *, int);
-void UMSDOS_put_super (struct super_block *);
-
-void umsdos_setup_dir(struct dentry *);
-void umsdos_set_dirinfo_new(struct dentry *, off_t);
-void umsdos_patch_dentry_inode (struct dentry *, off_t);
-int umsdos_get_dirowner (struct inode *inode, struct inode **result);
-
-/* ioctl.c 22/06/95 00.22.08 */
-int UMSDOS_ioctl_dir (struct inode *dir,
-	 struct file *filp,
-	 unsigned int cmd,
-	 unsigned long data);
-
-/* mangle.c 25/01/95 02.25.38 */
-void umsdos_manglename (struct umsdos_info *info);
-int umsdos_evalrecsize (int len);
-int umsdos_parse (const char *name,int len, struct umsdos_info *info);
-
-/* namei.c 25/01/95 02.25.38 */
-void umsdos_lockcreate (struct inode *dir);
-void umsdos_startlookup (struct inode *dir);
-void umsdos_unlockcreate (struct inode *dir);
-void umsdos_endlookup (struct inode *dir);
-
-int umsdos_readlink_x (	     struct dentry *dentry,
-			     char *buffer,
-			     int bufsiz);
-int UMSDOS_symlink (struct inode *dir,
-		    struct dentry *dentry,
-		    const char *symname);
-int UMSDOS_link (struct dentry *olddentry,
-		 struct inode *dir,
-		 struct dentry *dentry);
-int UMSDOS_create (struct inode *dir,
-		   struct dentry *dentry,
-		   int mode);
-
-int UMSDOS_mkdir (struct inode *dir,
-		  struct dentry *dentry,
-		  int mode);
-int UMSDOS_mknod (struct inode *dir,
-		  struct dentry *dentry,
-		  int mode,
-		  dev_t rdev);
-int UMSDOS_rmdir (struct inode *dir,struct dentry *dentry);
-int UMSDOS_unlink (struct inode *dir, struct dentry *dentry);
-int UMSDOS_rename (struct inode *old_dir,
-		   struct dentry *old_dentry,
-		   struct inode *new_dir,
-		   struct dentry *new_dentry);
-
-/* rdir.c 22/03/95 03.31.42 */
-struct dentry *umsdos_rlookup_x (struct inode *dir, struct dentry *dentry, int nopseudo);
-struct dentry *UMSDOS_rlookup (struct inode *dir, struct dentry *dentry, struct nameidata *nd);
-
-static inline struct umsdos_inode_info *UMSDOS_I(struct inode *inode)
-{
-	return &inode->u.umsdos_i;
-}
diff -Nru a/include/linux/umsdos_fs_i.h b/include/linux/umsdos_fs_i.h
--- a/include/linux/umsdos_fs_i.h	2005-03-01 23:39:08 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,58 +0,0 @@
-#ifndef UMSDOS_FS_I_H
-#define UMSDOS_FS_I_H
-
-#ifndef _LINUX_TYPES_H
-#include <linux/types.h>
-#endif
-
-#include <linux/msdos_fs_i.h>
-#include <linux/pipe_fs_i.h>
-
-/* #Specification: strategy / in memory inode
- * Here is the information specific to the inode of the UMSDOS file
- * system. This information is added to the end of the standard struct
- * inode. Each file system has its own extension to struct inode,
- * so do the umsdos file system.
- * 
- * The strategy is to have the umsdos_inode_info as a superset of
- * the msdos_inode_info, since most of the time the job is done
- * by the msdos fs code.
- * 
- * So we duplicate the msdos_inode_info, and add our own info at the
- * end.
- * 
- * The offset in this EMD file of the entry: pos
- * 
- * For directory, we have dir_locking_info to help synchronise
- * file creation and file lookup. See also msdos_fs_i.h for more 
- * information about msdos_inode_info.
- * 
- * Special file and fifo do have an inode which correspond to an
- * empty MSDOS file.
- * 
- * symlink are processed mostly like regular file. The content is the
- * link.
- * 
- * The UMSDOS specific extension is placed after the union.
- */
-
-struct dir_locking_info {
-	wait_queue_head_t p;
-	short int looking;	/* How many process doing a lookup */
-	short int creating;	/* Is there any creation going on here
-				 *  Only one at a time, although one
-				 *  may recursively lock, so it is a counter
-				 */
-	long pid;		/* pid of the process owning the creation
-				 * lock */
-};
-
-struct umsdos_inode_info {
-	struct msdos_inode_info msdos_info;
-	struct dir_locking_info dir_info;
-	int i_patched;		/* Inode has been patched */
-	int i_is_hlink;		/* Resolved hardlink inode? */
-	off_t pos;		/* Entry offset in the emd_owner file */
-};
-
-#endif
diff -Nru a/include/linux/usb.h b/include/linux/usb.h
--- a/include/linux/usb.h	2005-03-01 23:38:56 -08:00
+++ b/include/linux/usb.h	2005-03-01 23:38:56 -08:00
@@ -40,9 +40,22 @@
  * Devices may also have class-specific or vendor-specific descriptors.
  */
 
-/* host-side wrapper for parsed endpoint descriptors */
+/**
+ * struct usb_host_endpoint - host-side endpoint descriptor and queue
+ * @desc: descriptor for this endpoint, wMaxPacketSize in native byteorder
+ * @urb_list: urbs queued to this endpoint; maintained by usbcore
+ * @hcpriv: for use by HCD; typically holds hardware dma queue head (QH)
+ *	with one or more transfer descriptors (TDs) per urb
+ * @extra: descriptors following this endpoint in the configuration
+ * @extralen: how many bytes of "extra" are valid
+ *
+ * USB requests are always queued to a given endpoint, identified by a
+ * descriptor within an active interface in a given USB configuration.
+ */
 struct usb_host_endpoint {
 	struct usb_endpoint_descriptor	desc;
+	struct list_head		urb_list;
+	void				*hcpriv;
 
 	unsigned char *extra;   /* Extra descriptors */
 	int extralen;
@@ -224,11 +237,6 @@
 	int extralen;
 };
 
-// FIXME remove; exported only for drivers/usb/misc/auserwald.c
-// prefer usb_device->epnum[0..31]
-extern struct usb_endpoint_descriptor *
-	usb_epnum_to_ep_desc(struct usb_device *dev, unsigned epnum);
-
 int __usb_get_extra_descriptor(char *buffer, unsigned size,
 	unsigned char type, void **ptr);
 #define usb_get_extra_descriptor(ifpoint,type,ptr)\
@@ -311,25 +319,25 @@
 	struct semaphore serialize;
 
 	unsigned int toggle[2];		/* one bit for each endpoint ([0] = IN, [1] = OUT) */
-	int epmaxpacketin[16];		/* INput endpoint specific maximums */
-	int epmaxpacketout[16];		/* OUTput endpoint specific maximums */
 
 	struct usb_device *parent;	/* our hub, unless we're the root */
 	struct usb_bus *bus;		/* Bus we're part of */
+	struct usb_host_endpoint ep0;
 
 	struct device dev;		/* Generic device interface */
 
 	struct usb_device_descriptor descriptor;/* Descriptor */
 	struct usb_host_config *config;	/* All of the configs */
+
 	struct usb_host_config *actconfig;/* the active configuration */
+	struct usb_host_endpoint *ep_in[16];
+	struct usb_host_endpoint *ep_out[16];
 
 	char **rawdescriptors;		/* Raw descriptors for each config */
 
 	int have_langid;		/* whether string_langid is valid yet */
 	int string_langid;		/* language ID for strings */
 
-	void *hcpriv;			/* Host Controller private data */
-	
 	struct list_head filelist;
 	struct dentry *usbfs_dentry;	/* usbfs dentry entry for the device */
 
@@ -360,6 +368,8 @@
 
 extern struct usb_device *usb_find_device(u16 vendor_id, u16 product_id);
 
+/*-------------------------------------------------------------------------*/
+
 /* for drivers using iso endpoints */
 extern int usb_get_current_frame_number (struct usb_device *usb_dev);
 
@@ -729,8 +739,8 @@
  * to poll for transfers.  After the URB has been submitted, the interval
  * field reflects how the transfer was actually scheduled.
  * The polling interval may be more frequent than requested.
- * For example, some controllers have a maximum interval of 32 microseconds,
- * while others support intervals of up to 1024 microseconds.
+ * For example, some controllers have a maximum interval of 32 milliseconds,
+ * while others support intervals of up to 1024 milliseconds.
  * Isochronous URBs also have transfer intervals.  (Note that for isochronous
  * endpoints, as well as high speed interrupt endpoints, the encoding of
  * the transfer interval in the endpoint descriptor is logarithmic.
@@ -1040,55 +1050,35 @@
 /* -------------------------------------------------------------------------- */
 
 /*
- * Calling this entity a "pipe" is glorifying it. A USB pipe
- * is something embarrassingly simple: it basically consists
- * of the following information:
- *  - device number (7 bits)
- *  - endpoint number (4 bits)
- *  - current Data0/1 state (1 bit) [Historical; now gone]
- *  - direction (1 bit)
- *  - speed (1 bit) [Historical and specific to USB 1.1; now gone.]
- *  - max packet size (2 bits: 8, 16, 32 or 64) [Historical; now gone.]
- *  - pipe type (2 bits: control, interrupt, bulk, isochronous)
- *
- * That's 18 bits. Really. Nothing more. And the USB people have
- * documented these eighteen bits as some kind of glorious
- * virtual data structure.
+ * For various legacy reasons, Linux has a small cookie that's paired with
+ * a struct usb_device to identify an endpoint queue.  Queue characteristics
+ * are defined by the endpoint's descriptor.  This cookie is called a "pipe",
+ * an unsigned int encoded as:
  *
- * Let's not fall in that trap. We'll just encode it as a simple
- * unsigned int. The encoding is:
- *
- *  - max size:		bits 0-1	[Historical; now gone.]
  *  - direction:	bit 7		(0 = Host-to-Device [Out],
  *					 1 = Device-to-Host [In] ...
  *					like endpoint bEndpointAddress)
- *  - device:		bits 8-14       ... bit positions known to uhci-hcd
+ *  - device address:	bits 8-14       ... bit positions known to uhci-hcd
  *  - endpoint:		bits 15-18      ... bit positions known to uhci-hcd
- *  - Data0/1:		bit 19		[Historical; now gone. ]
- *  - lowspeed:		bit 26		[Historical; now gone. ]
  *  - pipe type:	bits 30-31	(00 = isochronous, 01 = interrupt,
  *					 10 = control, 11 = bulk)
  *
- * Why? Because it's arbitrary, and whatever encoding we select is really
- * up to us. This one happens to share a lot of bit positions with the UHCI
- * specification, so that much of the uhci driver can just mask the bits
- * appropriately.
+ * Given the device address and endpoint descriptor, pipes are redundant.
  */
 
 /* NOTE:  these are not the standard USB_ENDPOINT_XFER_* values!! */
+/* (yet ... they're the values used by usbfs) */
 #define PIPE_ISOCHRONOUS		0
 #define PIPE_INTERRUPT			1
 #define PIPE_CONTROL			2
 #define PIPE_BULK			3
 
-#define usb_maxpacket(dev, pipe, out)	(out \
-				? (dev)->epmaxpacketout[usb_pipeendpoint(pipe)] \
-				: (dev)->epmaxpacketin [usb_pipeendpoint(pipe)] )
-
 #define usb_pipein(pipe)	((pipe) & USB_DIR_IN)
 #define usb_pipeout(pipe)	(!usb_pipein(pipe))
+
 #define usb_pipedevice(pipe)	(((pipe) >> 8) & 0x7f)
 #define usb_pipeendpoint(pipe)	(((pipe) >> 15) & 0xf)
+
 #define usb_pipetype(pipe)	(((pipe) >> 30) & 3)
 #define usb_pipeisoc(pipe)	(usb_pipetype((pipe)) == PIPE_ISOCHRONOUS)
 #define usb_pipeint(pipe)	(usb_pipetype((pipe)) == PIPE_INTERRUPT)
@@ -1115,6 +1105,28 @@
 #define usb_rcvbulkpipe(dev,endpoint)	((PIPE_BULK << 30) | __create_pipe(dev,endpoint) | USB_DIR_IN)
 #define usb_sndintpipe(dev,endpoint)	((PIPE_INTERRUPT << 30) | __create_pipe(dev,endpoint))
 #define usb_rcvintpipe(dev,endpoint)	((PIPE_INTERRUPT << 30) | __create_pipe(dev,endpoint) | USB_DIR_IN)
+
+/*-------------------------------------------------------------------------*/
+
+static inline __u16
+usb_maxpacket(struct usb_device *udev, int pipe, int is_out)
+{
+	struct usb_host_endpoint	*ep;
+	unsigned			epnum = usb_pipeendpoint(pipe);
+
+	if (is_out) {
+		WARN_ON(usb_pipein(pipe));
+		ep = udev->ep_out[epnum];
+	} else {
+		WARN_ON(usb_pipeout(pipe));
+		ep = udev->ep_in[epnum];
+	}
+	if (!ep)
+		return 0;
+
+	/* NOTE:  only 0x07ff bits are for packet size... */
+	return le16_to_cpu(ep->desc.wMaxPacketSize);
+}
 
 /* -------------------------------------------------------------------------- */
 
diff -Nru a/include/linux/usb_ch9.h b/include/linux/usb_ch9.h
--- a/include/linux/usb_ch9.h	2005-03-01 23:38:56 -08:00
+++ b/include/linux/usb_ch9.h	2005-03-01 23:38:56 -08:00
@@ -79,6 +79,7 @@
 #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_DEBUG_MODE		6	/* (special devices only) */
 
 #define USB_ENDPOINT_HALT		0	/* IN/OUT will STALL */
 
@@ -156,14 +157,14 @@
 	__u8  bLength;
 	__u8  bDescriptorType;
 
-	__u16 bcdUSB;
+	__le16 bcdUSB;
 	__u8  bDeviceClass;
 	__u8  bDeviceSubClass;
 	__u8  bDeviceProtocol;
 	__u8  bMaxPacketSize0;
-	__u16 idVendor;
-	__u16 idProduct;
-	__u16 bcdDevice;
+	__le16 idVendor;
+	__le16 idProduct;
+	__le16 bcdDevice;
 	__u8  iManufacturer;
 	__u8  iProduct;
 	__u8  iSerialNumber;
@@ -208,7 +209,7 @@
 	__u8  bLength;
 	__u8  bDescriptorType;
 
-	__u16 wTotalLength;
+	__le16 wTotalLength;
 	__u8  bNumInterfaces;
 	__u8  bConfigurationValue;
 	__u8  iConfiguration;
@@ -264,7 +265,7 @@
 
 	__u8  bEndpointAddress;
 	__u8  bmAttributes;
-	__u16 wMaxPacketSize;
+	__le16 wMaxPacketSize;
 	__u8  bInterval;
 
 	// NOTE:  these two are _only_ in audio endpoints.
@@ -297,7 +298,7 @@
 	__u8  bLength;
 	__u8  bDescriptorType;
 
-	__u16 bcdUSB;
+	__le16 bcdUSB;
 	__u8  bDeviceClass;
 	__u8  bDeviceSubClass;
 	__u8  bDeviceProtocol;
@@ -320,6 +321,18 @@
 /* from usb_otg_descriptor.bmAttributes */
 #define USB_OTG_SRP		(1 << 0)
 #define USB_OTG_HNP		(1 << 1)	/* swap host/device roles */
+
+/*-------------------------------------------------------------------------*/
+
+/* USB_DT_DEBUG:  for special highspeed devices, replacing serial console */
+struct usb_debug_descriptor {
+	__u8  bLength;
+	__u8  bDescriptorType;
+
+	/* bulk endpoints with 8 byte maxpacket */
+	__u8  bDebugInEndpoint;
+	__u8  bDebugOutEndpoint;
+};
 
 /*-------------------------------------------------------------------------*/
 
diff -Nru a/include/linux/videodev2.h b/include/linux/videodev2.h
--- a/include/linux/videodev2.h	2005-03-01 23:39:07 -08:00
+++ b/include/linux/videodev2.h	2005-03-01 23:39:07 -08:00
@@ -78,6 +78,7 @@
 enum v4l2_tuner_type {
 	V4L2_TUNER_RADIO	     = 1,
 	V4L2_TUNER_ANALOG_TV	     = 2,
+	V4L2_TUNER_DIGITAL_TV	     = 3,
 };
 
 enum v4l2_memory {
diff -Nru a/include/linux/videotext.h b/include/linux/videotext.h
--- a/include/linux/videotext.h	2005-03-01 23:39:17 -08:00
+++ b/include/linux/videotext.h	2005-03-01 23:39:17 -08:00
@@ -1,7 +1,13 @@
 #ifndef _VTX_H
 #define _VTX_H
 
-/* $Id: videotext.h,v 1.1 1998/03/30 22:26:39 alan Exp $
+/*
+ * Teletext (=Videotext) hardware decoders using interface /dev/vtx
+ * Do not confuse with drivers using /dev/vbi which decode videotext by software
+ *
+ * Videotext IOCTLs changed in order to use _IO() macros defined in <linux/ioctl.h>,
+ * unused tuner IOCTLs cleaned up by
+ * Michael Geng <linux@MichaelGeng.de>
  *
  * Copyright (c) 1994-97 Martin Buck  <martin-2.buck@student.uni-ulm.de>
  * Read COPYING for more information
@@ -12,19 +18,32 @@
 /*
  *	Videotext ioctls
  */
-#define VTXIOCGETINFO  0x7101  /* get version of driver & capabilities of vtx-chipset */
-#define VTXIOCCLRPAGE  0x7102  /* clear page-buffer */
-#define VTXIOCCLRFOUND 0x7103  /* clear bits indicating that page was found */
-#define VTXIOCPAGEREQ  0x7104  /* search for page */
-#define VTXIOCGETSTAT  0x7105  /* get status of page-buffer */
-#define VTXIOCGETPAGE  0x7106  /* get contents of page-buffer */
-#define VTXIOCSTOPDAU  0x7107  /* stop data acquisition unit */
-#define VTXIOCPUTPAGE  0x7108  /* display page on TV-screen */
-#define VTXIOCSETDISP  0x7109  /* set TV-mode */
-#define VTXIOCPUTSTAT  0x710a  /* set status of TV-output-buffer */
-#define VTXIOCCLRCACHE 0x710b  /* clear cache on VTX-interface (if avail.) */
-#define VTXIOCSETVIRT  0x710c  /* turn on virtual mode (this disables TV-display) */
-
+#define VTXIOCGETINFO	_IOR  (0x81,  1, vtx_info_t)
+#define VTXIOCCLRPAGE	_IOW  (0x81,  2, vtx_pagereq_t)
+#define VTXIOCCLRFOUND	_IOW  (0x81,  3, vtx_pagereq_t)
+#define VTXIOCPAGEREQ	_IOW  (0x81,  4, vtx_pagereq_t)
+#define VTXIOCGETSTAT	_IOW  (0x81,  5, vtx_pagereq_t)
+#define VTXIOCGETPAGE	_IOW  (0x81,  6, vtx_pagereq_t)
+#define VTXIOCSTOPDAU	_IOW  (0x81,  7, vtx_pagereq_t)
+#define VTXIOCPUTPAGE	_IO   (0x81,  8)
+#define VTXIOCSETDISP	_IO   (0x81,  9)
+#define VTXIOCPUTSTAT	_IO   (0x81, 10)
+#define VTXIOCCLRCACHE	_IO   (0x81, 11)
+#define VTXIOCSETVIRT	_IOW  (0x81, 12, long)
+
+/* for compatibility, will go away some day */
+#define VTXIOCGETINFO_OLD  0x7101  /* get version of driver & capabilities of vtx-chipset */
+#define VTXIOCCLRPAGE_OLD  0x7102  /* clear page-buffer */
+#define VTXIOCCLRFOUND_OLD 0x7103  /* clear bits indicating that page was found */
+#define VTXIOCPAGEREQ_OLD  0x7104  /* search for page */
+#define VTXIOCGETSTAT_OLD  0x7105  /* get status of page-buffer */
+#define VTXIOCGETPAGE_OLD  0x7106  /* get contents of page-buffer */
+#define VTXIOCSTOPDAU_OLD  0x7107  /* stop data acquisition unit */
+#define VTXIOCPUTPAGE_OLD  0x7108  /* display page on TV-screen */
+#define VTXIOCSETDISP_OLD  0x7109  /* set TV-mode */
+#define VTXIOCPUTSTAT_OLD  0x710a  /* set status of TV-output-buffer */
+#define VTXIOCCLRCACHE_OLD 0x710b  /* clear cache on VTX-interface (if avail.) */
+#define VTXIOCSETVIRT_OLD  0x710c  /* turn on virtual mode (this disables TV-display) */
 
 /* 
  *	Definitions for VTXIOCGETINFO
@@ -102,43 +121,5 @@
 	unsigned hamming : 1;		/* hamming-error occurred */
 }
 vtx_pageinfo_t;
-
-
-/*
- *	Definitions for VTXIOCSETDISP
- */
  
-typedef enum { 
-	DISPOFF, DISPNORM, DISPTRANS, DISPINS, INTERLACE_OFFSET 
-} vtxdisp_t;
-
-
-
-/*
- *	Tuner ioctls
- */
- 
-#define TUNIOCGETINFO  0x7201  /* get version of driver & capabilities of tuner */
-#define TUNIOCRESET    0x7202  /* reset tuner */
-#define TUNIOCSETFREQ  0x7203  /* set tuning frequency (unit: kHz) */
-#define TUNIOCGETFREQ  0x7204  /* get tuning frequency (unit: kHz) */
-#define TUNIOCSETCHAN  0x7205  /* set tuning channel */
-#define TUNIOCGETCHAN  0x7206  /* get tuning channel */
-
-
-typedef struct 
-{
-	int version_major, version_minor;	/* version of driver; if version_major changes, driver */
-						/* is not backward compatible!!! CHECK THIS!!! */  
-	unsigned freq : 1;			/* tuner can be set to given frequency */
-	unsigned chan : 1;			/* tuner stores several channels */
-	unsigned scan : 1;			/* tuner supports scanning */
-	unsigned autoscan : 1;		/* tuner supports scanning with automatic stop */
-	unsigned afc : 1;			/* tuner supports AFC */
-	unsigned dummy1, dummy2, dummy3, dummy4, dummy5, dummy6, dummy7, dummy8, dummy9, dummy10,
- 		dummy11 : 1;
-	int dummy12, dummy13, dummy14, dummy15, dummy16, dummy17, dummy18, dummy19;
-} tuner_info_t;
-
-
 #endif /* _VTX_H */
diff -Nru a/include/linux/vmalloc.h b/include/linux/vmalloc.h
--- a/include/linux/vmalloc.h	2005-03-01 23:39:17 -08:00
+++ b/include/linux/vmalloc.h	2005-03-01 23:39:17 -08:00
@@ -8,6 +8,7 @@
 #define VM_IOREMAP	0x00000001	/* ioremap() and friends */
 #define VM_ALLOC	0x00000002	/* vmalloc() */
 #define VM_MAP		0x00000004	/* vmap()ed pages */
+/* bits [20..32] reserved for arch specific ioremap internals */
 
 struct vm_struct {
 	void			*addr;
diff -Nru a/include/media/tuner.h b/include/media/tuner.h
--- a/include/media/tuner.h	2005-03-01 23:39:08 -08:00
+++ b/include/media/tuner.h	2005-03-01 23:39:08 -08:00
@@ -77,6 +77,7 @@
 #define TUNER_MICROTUNE_4042FI5  49	/* FusionHDTV 3 Gold - 4042 FI5 (3X 8147) */
 #define TUNER_TCL_2002N          50
 #define TUNER_PHILIPS_FM1256_IH3   51
+#define TUNER_THOMSON_DTT7610    52
 
 #define NOTUNER 0
 #define PAL     1	/* PAL_BG */
@@ -97,6 +98,7 @@
 #define HITACHI 9
 #define Panasonic 10
 #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 */
@@ -108,10 +110,12 @@
 #define  TDA9887_SET_CONFIG          _IOW('t',5,int)
 /* tv card specific */
 # define TDA9887_PRESENT             (1<<0)
-# define TDA9887_PORT1               (1<<1)
-# define TDA9887_PORT2               (1<<2)
+# define TDA9887_PORT1_INACTIVE      (1<<1)
+# define TDA9887_PORT2_INACTIVE      (1<<2)
 # define TDA9887_QSS                 (1<<3)
 # define TDA9887_INTERCARRIER        (1<<4)
+# define TDA9887_PORT1_ACTIVE        (1<<5)
+# define TDA9887_PORT2_ACTIVE        (1<<6)
 /* config options */
 # define TDA9887_DEEMPHASIS_MASK     (3<<16)
 # define TDA9887_DEEMPHASIS_NONE     (1<<16)
diff -Nru a/include/media/tveeprom.h b/include/media/tveeprom.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/media/tveeprom.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,23 @@
+struct tveeprom {
+	u32 has_radio;
+
+	u32 tuner_type;
+	u32 tuner_formats;
+
+	u32 digitizer;
+	u32 digitizer_formats;
+
+	u32 audio_processor;
+	/* a_p_fmts? */
+
+	u32 model;
+	u32 revision;
+	u32 serial_number;
+	char rev_str[5];
+};
+
+void tveeprom_hauppauge_analog(struct tveeprom *tvee,
+			       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 -Nru a/include/media/video-buf-dvb.h b/include/media/video-buf-dvb.h
--- a/include/media/video-buf-dvb.h	2005-03-01 23:39:09 -08:00
+++ b/include/media/video-buf-dvb.h	2005-03-01 23:39:09 -08:00
@@ -24,7 +24,9 @@
 	struct dvb_net             net;
 };
 
-int videobuf_dvb_register(struct videobuf_dvb *dvb);
+int videobuf_dvb_register(struct videobuf_dvb *dvb,
+			  struct module *module,
+			  void *adapter_priv);
 void videobuf_dvb_unregister(struct videobuf_dvb *dvb);
 
 /*
diff -Nru a/include/mtd/mtd-abi.h b/include/mtd/mtd-abi.h
--- a/include/mtd/mtd-abi.h	2005-03-01 23:38:58 -08:00
+++ b/include/mtd/mtd-abi.h	2005-03-01 23:38:58 -08:00
@@ -1,5 +1,5 @@
 /*
- * $Id: mtd-abi.h,v 1.6 2004/08/09 13:38:30 dwmw2 Exp $
+ * $Id: mtd-abi.h,v 1.7 2004/11/23 15:37:32 gleixner Exp $
  *
  * Portions of MTD ABI definition which are shared by kernel and user space 
  */
@@ -40,6 +40,7 @@
 #define MTD_XIP			32	// eXecute-In-Place possible
 #define MTD_OOB			64	// Out-of-band data (NAND flash)
 #define MTD_ECC			128	// Device capable of automatic ECC
+#define MTD_NO_VIRTBLOCKS	256	// Virtual blocks not allowed
 
 // Some common devices / combinations of capabilities
 #define MTD_CAP_ROM		0
diff -Nru a/include/net/act_api.h b/include/net/act_api.h
--- a/include/net/act_api.h	2005-03-01 23:38:57 -08:00
+++ b/include/net/act_api.h	2005-03-01 23:38:57 -08:00
@@ -76,15 +76,12 @@
 extern int tcf_unregister_action(struct tc_action_ops *a);
 extern void tcf_action_destroy(struct tc_action *a, int bind);
 extern int tcf_action_exec(struct sk_buff *skb, struct tc_action *a, struct tcf_result *res);
-extern int tcf_action_init(struct rtattr *rta, struct rtattr *est, struct tc_action *a,char *n, int ovr, int bind);
-extern int tcf_action_init_1(struct rtattr *rta, struct rtattr *est, struct tc_action *a,char *n, int ovr, int bind);
+extern struct tc_action *tcf_action_init(struct rtattr *rta, struct rtattr *est, char *n, int ovr, int bind, int *err);
+extern struct tc_action *tcf_action_init_1(struct rtattr *rta, struct rtattr *est, char *n, int ovr, int bind, int *err);
 extern int tcf_action_dump(struct sk_buff *skb, struct tc_action *a, int, int);
 extern int tcf_action_dump_old(struct sk_buff *skb, struct tc_action *a, int, int);
 extern int tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int, int);
 extern int tcf_action_copy_stats (struct sk_buff *,struct tc_action *);
-extern int tcf_act_police_locate(struct rtattr *rta, struct rtattr *est,struct tc_action *,int , int );
-extern int tcf_act_police_dump(struct sk_buff *, struct tc_action *, int, int);
-extern int tcf_act_police(struct sk_buff **skb, struct tc_action *a);
 #endif /* CONFIG_NET_CLS_ACT */
 
 extern int tcf_police(struct sk_buff *skb, struct tcf_police *p);
diff -Nru a/include/net/addrconf.h b/include/net/addrconf.h
--- a/include/net/addrconf.h	2005-03-01 23:39:09 -08:00
+++ b/include/net/addrconf.h	2005-03-01 23:39:09 -08:00
@@ -112,7 +112,6 @@
 
 extern int ipv6_dev_ac_inc(struct net_device *dev, struct in6_addr *addr);
 extern int __ipv6_dev_ac_dec(struct inet6_dev *idev, struct in6_addr *addr);
-extern int ipv6_dev_ac_dec(struct net_device *dev, struct in6_addr *addr);
 extern int ipv6_chk_acast_addr(struct net_device *dev, struct in6_addr *addr);
 
 
diff -Nru a/include/net/ax25.h b/include/net/ax25.h
--- a/include/net/ax25.h	2005-03-01 23:39:07 -08:00
+++ b/include/net/ax25.h	2005-03-01 23:39:07 -08:00
@@ -231,7 +231,6 @@
 extern void ax25_destroy_socket(ax25_cb *);
 extern ax25_cb *ax25_create_cb(void);
 extern void ax25_fillin_cb(ax25_cb *, ax25_dev *);
-extern int  ax25_create(struct socket *, int);
 extern struct sock *ax25_make_new(struct sock *, struct ax25_dev *);
 
 /* ax25_addr.c */
@@ -268,7 +267,6 @@
 extern void ax25_ds_nr_error_recovery(ax25_cb *);
 extern void ax25_ds_enquiry_response(ax25_cb *);
 extern void ax25_ds_establish_data_link(ax25_cb *);
-extern void ax25_dev_dama_on(ax25_dev *);
 extern void ax25_dev_dama_off(ax25_dev *);
 extern void ax25_dama_on(ax25_cb *);
 extern void ax25_dama_off(ax25_cb *);
diff -Nru a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
--- a/include/net/bluetooth/hci.h	2005-03-01 23:39:16 -08:00
+++ b/include/net/bluetooth/hci.h	2005-03-01 23:39:16 -08:00
@@ -53,7 +53,8 @@
 
 /* HCI device quirks */
 enum {
-	HCI_QUIRK_RESET_ON_INIT
+	HCI_QUIRK_RESET_ON_INIT,
+	HCI_QUIRK_RAW_DEVICE
 };
 
 /* HCI device flags */
@@ -574,6 +575,13 @@
 	__u8     lmp_ver;
 	__u16    manufacturer;
 	__u16    lmp_subver;
+} __attribute__ ((packed));
+
+#define HCI_EV_CLOCK_OFFSET	0x01C
+struct hci_ev_clock_offset {
+	__u8     status;
+	__u16    handle;
+	__u16    clock_offset;
 } __attribute__ ((packed));
 
 /* Internal events generated by Bluetooth stack */
diff -Nru a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
--- a/include/net/bluetooth/hci_core.h	2005-03-01 23:38:57 -08:00
+++ b/include/net/bluetooth/hci_core.h	2005-03-01 23:38:57 -08:00
@@ -119,6 +119,8 @@
 
 	struct hci_dev_stats	stat;
 
+	struct sk_buff_head	driver_init;
+
 	void			*driver_data;
 	void			*core_data;
 
@@ -277,7 +279,6 @@
 	return NULL;
 }
 
-void hci_acl_connect(struct hci_conn *conn);
 void hci_acl_disconn(struct hci_conn *conn, __u8 reason);
 void hci_add_sco(struct hci_conn *conn, __u16 handle);
 
@@ -589,6 +590,5 @@
 #define hci_req_unlock(d)	up(&d->req_lock)
 
 void hci_req_complete(struct hci_dev *hdev, int result);
-void hci_req_cancel(struct hci_dev *hdev, int err);
 
 #endif /* __HCI_CORE_H */
diff -Nru a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
--- a/include/net/bluetooth/l2cap.h	2005-03-01 23:38:53 -08:00
+++ b/include/net/bluetooth/l2cap.h	2005-03-01 23:38:53 -08:00
@@ -38,17 +38,19 @@
 	bdaddr_t	l2_bdaddr;
 };
 
-/* Socket options */
+/* L2CAP socket options */
 #define L2CAP_OPTIONS	0x01
 struct l2cap_options {
 	__u16 omtu;
 	__u16 imtu;
 	__u16 flush_to;
+	__u8  mode;
 };
 
-#define L2CAP_CONNINFO  0x02
+#define L2CAP_CONNINFO	0x02
 struct l2cap_conninfo {
 	__u16 hci_handle;
+	__u8  dev_class[3];
 };
 
 #define L2CAP_LM	0x03
@@ -59,20 +61,6 @@
 #define L2CAP_LM_RELIABLE	0x0010
 #define L2CAP_LM_SECURE		0x0020
 
-#define L2CAP_QOS	0x04
-struct l2cap_qos {
-	__u16 service_type;
-	__u32 token_rate;
-	__u32 token_bucket_size;
-	__u32 peak_bandwidth;
-	__u32 latency;
-	__u32 delay_variation;
-};
-
-#define L2CAP_SERV_NO_TRAFFIC	0x00
-#define L2CAP_SERV_BEST_EFFORT	0x01
-#define L2CAP_SERV_GUARANTEED	0x02
-
 /* L2CAP command codes */
 #define L2CAP_COMMAND_REJ 0x01
 #define L2CAP_CONN_REQ    0x02
@@ -154,6 +142,7 @@
 #define L2CAP_CONF_MTU		0x01
 #define L2CAP_CONF_FLUSH_TO	0x02
 #define L2CAP_CONF_QOS		0x03
+#define L2CAP_CONF_RFC		0x04
 
 #define L2CAP_CONF_MAX_SIZE	22
 
@@ -198,11 +187,11 @@
 
 	bdaddr_t	*dst;
 	bdaddr_t	*src;
-	
+
 	unsigned int	mtu;
 
 	spinlock_t	lock;
-	
+
 	struct sk_buff *rx_skb;
 	__u32		rx_len;
 	__u8		rx_ident;
@@ -222,7 +211,7 @@
 	__u16		imtu;
 	__u16		omtu;
 	__u16		flush_to;
-	
+
 	__u32		link_mode;
 
 	__u8		conf_state;
diff -Nru a/include/net/bluetooth/rfcomm.h b/include/net/bluetooth/rfcomm.h
--- a/include/net/bluetooth/rfcomm.h	2005-03-01 23:39:09 -08:00
+++ b/include/net/bluetooth/rfcomm.h	2005-03-01 23:39:09 -08:00
@@ -28,6 +28,7 @@
 
 #define RFCOMM_CONN_TIMEOUT (HZ * 30)
 #define RFCOMM_DISC_TIMEOUT (HZ * 20)
+#define RFCOMM_AUTH_TIMEOUT (HZ * 25)
 
 #define RFCOMM_DEFAULT_MTU	127
 #define RFCOMM_DEFAULT_CREDITS	7
@@ -181,6 +182,8 @@
 	u8            v24_sig;
 	u8            mscex;
 
+	u32           link_mode;
+
 	uint          mtu;
 	uint          cfc;
 	uint          rx_credits;
@@ -196,14 +199,18 @@
 /* DLC and session flags */
 #define RFCOMM_RX_THROTTLED 0
 #define RFCOMM_TX_THROTTLED 1
-#define RFCOMM_MSC_PENDING  2
-#define RFCOMM_TIMED_OUT    3
+#define RFCOMM_TIMED_OUT    2
+#define RFCOMM_MSC_PENDING  3 
+#define RFCOMM_AUTH_PENDING 4
+#define RFCOMM_AUTH_ACCEPT  5
+#define RFCOMM_AUTH_REJECT  6
 
 /* Scheduling flags and events */
 #define RFCOMM_SCHED_STATE  0
 #define RFCOMM_SCHED_RX     1
 #define RFCOMM_SCHED_TX     2
 #define RFCOMM_SCHED_TIMEO  3
+#define RFCOMM_SCHED_AUTH   4
 #define RFCOMM_SCHED_WAKEUP 31
 
 /* MSC exchange flags */
@@ -216,22 +223,6 @@
 #define RFCOMM_CFC_DISABLED 0
 #define RFCOMM_CFC_ENABLED  RFCOMM_MAX_CREDITS
 
-extern struct task_struct *rfcomm_thread;
-extern unsigned long rfcomm_event;
-
-static inline void rfcomm_schedule(uint event)
-{
-	if (!rfcomm_thread)
-		return;
-	//set_bit(event, &rfcomm_event);
-	set_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event);
-	wake_up_process(rfcomm_thread);
-}
-
-extern struct semaphore rfcomm_sem;
-#define rfcomm_lock()	down(&rfcomm_sem);
-#define rfcomm_unlock()	up(&rfcomm_sem);
-
 /* ---- RFCOMM DLCs (channels) ---- */
 struct rfcomm_dlc *rfcomm_dlc_alloc(int prio);
 void rfcomm_dlc_free(struct rfcomm_dlc *d);
@@ -271,11 +262,6 @@
 }
 
 /* ---- RFCOMM sessions ---- */
-struct rfcomm_session *rfcomm_session_add(struct socket *sock, int state);
-struct rfcomm_session *rfcomm_session_get(bdaddr_t *src, bdaddr_t *dst);
-struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, bdaddr_t *dst, int *err);
-void   rfcomm_session_del(struct rfcomm_session *s);
-void   rfcomm_session_close(struct rfcomm_session *s, int err);
 void   rfcomm_session_getaddr(struct rfcomm_session *s, bdaddr_t *src, bdaddr_t *dst);
 
 static inline void rfcomm_session_hold(struct rfcomm_session *s)
@@ -283,27 +269,36 @@
 	atomic_inc(&s->refcnt);
 }
 
-static inline void rfcomm_session_put(struct rfcomm_session *s)
-{
-	if (atomic_dec_and_test(&s->refcnt))
-		rfcomm_session_del(s);
-}
-
 /* ---- RFCOMM chechsum ---- */
 extern u8 rfcomm_crc_table[];
 
 /* ---- RFCOMM sockets ---- */
 struct sockaddr_rc {
-	sa_family_t rc_family;
-	bdaddr_t    rc_bdaddr;
-	u8          rc_channel;
+	sa_family_t	rc_family;
+	bdaddr_t	rc_bdaddr;
+	u8		rc_channel;
 };
 
+#define RFCOMM_CONNINFO	0x02
+struct rfcomm_conninfo {
+	__u16 hci_handle;
+	__u8  dev_class[3];
+};
+
+#define RFCOMM_LM	0x03
+#define RFCOMM_LM_MASTER	0x0001
+#define RFCOMM_LM_AUTH		0x0002
+#define RFCOMM_LM_ENCRYPT	0x0004
+#define RFCOMM_LM_TRUSTED	0x0008
+#define RFCOMM_LM_RELIABLE	0x0010
+#define RFCOMM_LM_SECURE	0x0020
+
 #define rfcomm_pi(sk)   ((struct rfcomm_pinfo *)sk->sk_protinfo)
 
 struct rfcomm_pinfo {
 	struct rfcomm_dlc   *dlc;
 	u8     channel;
+	u32    link_mode;
 };
 
 int  rfcomm_init_sockets(void);
diff -Nru a/include/net/bluetooth/sco.h b/include/net/bluetooth/sco.h
--- a/include/net/bluetooth/sco.h	2005-03-01 23:38:53 -08:00
+++ b/include/net/bluetooth/sco.h	2005-03-01 23:38:53 -08:00
@@ -39,15 +39,16 @@
 	bdaddr_t	sco_bdaddr;
 };
 
-/* set/get sockopt defines */
-#define SCO_OPTIONS  0x01
+/* SCO socket options */
+#define SCO_OPTIONS	0x01
 struct sco_options {
 	__u16 mtu;
 };
 
-#define SCO_CONNINFO  0x02
+#define SCO_CONNINFO	0x02
 struct sco_conninfo {
 	__u16 hci_handle;
+	__u8  dev_class[3];
 };
 
 /* ---- SCO connections ---- */
diff -Nru a/include/net/checksum.h b/include/net/checksum.h
--- a/include/net/checksum.h	2005-03-01 23:38:53 -08:00
+++ b/include/net/checksum.h	2005-03-01 23:38:53 -08:00
@@ -27,7 +27,7 @@
 
 #ifndef _HAVE_ARCH_COPY_AND_CSUM_FROM_USER
 static inline
-unsigned int csum_and_copy_from_user (const char __user *src, char *dst,
+unsigned int csum_and_copy_from_user (const unsigned char __user *src, unsigned char *dst,
 				      int len, int sum, int *err_ptr)
 {
 	if (verify_area(VERIFY_READ, src, len) == 0)
@@ -42,7 +42,7 @@
 
 #ifndef HAVE_CSUM_COPY_USER
 static __inline__ unsigned int csum_and_copy_to_user
-(const char *src, char __user *dst, int len, unsigned int sum, int *err_ptr)
+(const unsigned char *src, unsigned char __user *dst, int len, unsigned int sum, int *err_ptr)
 {
 	sum = csum_partial(src, len, sum);
 
diff -Nru a/include/net/dn.h b/include/net/dn.h
--- a/include/net/dn.h	2005-03-01 23:39:07 -08:00
+++ b/include/net/dn.h	2005-03-01 23:39:07 -08:00
@@ -220,8 +220,6 @@
 
 extern void dn_start_slow_timer(struct sock *sk);
 extern void dn_stop_slow_timer(struct sock *sk);
-extern void dn_start_fast_timer(struct sock *sk);
-extern void dn_stop_fast_timer(struct sock *sk);
 
 extern dn_address decnet_address;
 extern int decnet_debug_level;
diff -Nru a/include/net/dn_fib.h b/include/net/dn_fib.h
--- a/include/net/dn_fib.h	2005-03-01 23:38:57 -08:00
+++ b/include/net/dn_fib.h	2005-03-01 23:38:57 -08:00
@@ -117,7 +117,6 @@
 extern void dn_fib_init(void);
 extern void dn_fib_cleanup(void);
 
-extern int dn_fib_rt_message(struct sk_buff *skb);
 extern int dn_fib_ioctl(struct socket *sock, unsigned int cmd, 
 			unsigned long arg);
 extern struct dn_fib_info *dn_fib_create_info(const struct rtmsg *r, 
diff -Nru a/include/net/dst.h b/include/net/dst.h
--- a/include/net/dst.h	2005-03-01 23:39:16 -08:00
+++ b/include/net/dst.h	2005-03-01 23:39:16 -08:00
@@ -89,7 +89,8 @@
 	int			(*gc)(void);
 	struct dst_entry *	(*check)(struct dst_entry *, __u32 cookie);
 	void			(*destroy)(struct dst_entry *);
-	void			(*ifdown)(struct dst_entry *, int how);
+	void			(*ifdown)(struct dst_entry *,
+					  struct net_device *dev, int how);
 	struct dst_entry *	(*negative_advice)(struct dst_entry *);
 	void			(*link_failure)(struct sk_buff *);
 	void			(*update_pmtu)(struct dst_entry *dst, u32 mtu);
@@ -147,6 +148,7 @@
 {
 	if (dst) {
 		WARN_ON(atomic_read(&dst->__refcnt) < 1);
+		smp_mb__before_atomic_dec();
 		atomic_dec(&dst->__refcnt);
 	}
 }
diff -Nru a/include/net/icmp.h b/include/net/icmp.h
--- a/include/net/icmp.h	2005-03-01 23:39:19 -08:00
+++ b/include/net/icmp.h	2005-03-01 23:39:19 -08:00
@@ -46,22 +46,15 @@
 /* Move into dst.h ? */
 extern int 	xrlim_allow(struct dst_entry *dst, int timeout);
 
-struct raw_opt {
-	struct icmp_filter filter;
-};
-
-struct ipv6_pinfo;
-
-/* WARNING: don't change the layout of the members in raw_sock! */
 struct raw_sock {
-	struct sock	  sk;
-#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-	struct ipv6_pinfo *pinet6;
-#endif
-	struct inet_opt	  inet;
-	struct raw_opt	  raw4;
+	/* inet_sock has to be the first member */
+	struct inet_sock   inet;
+	struct icmp_filter filter;
 };
 
-#define raw4_sk(__sk) (&((struct raw_sock *)__sk)->raw4)
+static inline struct raw_sock *raw_sk(const struct sock *sk)
+{
+	return (struct raw_sock *)sk;
+}
 
 #endif	/* _ICMP_H */
diff -Nru a/include/net/if_inet6.h b/include/net/if_inet6.h
--- a/include/net/if_inet6.h	2005-03-01 23:39:17 -08:00
+++ b/include/net/if_inet6.h	2005-03-01 23:39:17 -08:00
@@ -266,5 +266,20 @@
 {
 	buf[0] = 0x00;
 }
+
+static inline void ipv6_ib_mc_map(struct in6_addr *addr, char *buf)
+{
+	buf[0]  = 0;		/* Reserved */
+	buf[1]  = 0xff;		/* Multicast QPN */
+	buf[2]  = 0xff;
+	buf[3]  = 0xff;
+	buf[4]  = 0xff;
+	buf[5]  = 0x12;		/* link local scope */
+	buf[6]  = 0x60;		/* IPv6 signature */
+	buf[7]  = 0x1b;
+	buf[8]  = 0;		/* P_Key */
+	buf[9]  = 0;
+	memcpy(buf + 10, addr->s6_addr + 6, 10);
+}
 #endif
 #endif
diff -Nru a/include/net/ip.h b/include/net/ip.h
--- a/include/net/ip.h	2005-03-01 23:39:07 -08:00
+++ b/include/net/ip.h	2005-03-01 23:39:07 -08:00
@@ -229,6 +229,39 @@
 	buf[3]=addr&0x7F;
 }
 
+/*
+ *	Map a multicast IP onto multicast MAC for type IP-over-InfiniBand.
+ *	Leave P_Key as 0 to be filled in by driver.
+ */
+
+static inline void ip_ib_mc_map(u32 addr, char *buf)
+{
+	buf[0]  = 0;		/* Reserved */
+	buf[1]  = 0xff;		/* Multicast QPN */
+	buf[2]  = 0xff;
+	buf[3]  = 0xff;
+	addr    = ntohl(addr);
+	buf[4]  = 0xff;
+	buf[5]  = 0x12;		/* link local scope */
+	buf[6]  = 0x40;		/* IPv4 signature */
+	buf[7]  = 0x1b;
+	buf[8]  = 0;		/* P_Key */
+	buf[9]  = 0;
+	buf[10] = 0;
+	buf[11] = 0;
+	buf[12] = 0;
+	buf[13] = 0;
+	buf[14] = 0;
+	buf[15] = 0;
+	buf[19] = addr & 0xff;
+	addr  >>= 8;
+	buf[18] = addr & 0xff;
+	addr  >>= 8;
+	buf[17] = addr & 0xff;
+	addr  >>= 8;
+	buf[16] = addr & 0x0f;
+}
+
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 #include <linux/ipv6.h>
 #endif
@@ -253,9 +286,20 @@
 /*
  *	Functions provided by ip_fragment.o
  */
- 
-struct sk_buff *ip_defrag(struct sk_buff *skb);
-extern void ipfrag_flush(void);
+
+enum ip_defrag_users
+{
+	IP_DEFRAG_LOCAL_DELIVER,
+	IP_DEFRAG_CALL_RA_CHAIN,
+	IP_DEFRAG_CONNTRACK_IN,
+	IP_DEFRAG_CONNTRACK_OUT,
+	IP_DEFRAG_NAT_OUT,
+	IP_DEFRAG_VS_IN,
+	IP_DEFRAG_VS_OUT,
+	IP_DEFRAG_VS_FWD
+};
+
+struct sk_buff *ip_defrag(struct sk_buff *skb, u32 user);
 extern int ip_frag_nqueues;
 extern atomic_t ip_frag_mem;
 
@@ -294,8 +338,6 @@
 			      u16 port, u32 info, u8 *payload);
 extern void	ip_local_error(struct sock *sk, int err, u32 daddr, u16 dport,
 			       u32 info);
-
-extern int ipv4_proc_init(void);
 
 /* sysctl helpers - any sysctl which holds a value that ends up being
  * fed into the routing cache should use these handlers.
diff -Nru a/include/net/ip_fib.h b/include/net/ip_fib.h
--- a/include/net/ip_fib.h	2005-03-01 23:39:16 -08:00
+++ b/include/net/ip_fib.h	2005-03-01 23:39:16 -08:00
@@ -200,7 +200,6 @@
 
 /* Exported by fib_frontend.c */
 extern void		ip_fib_init(void);
-extern void		fib_flush(void);
 extern int inet_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg);
 extern int inet_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg);
 extern int inet_rtm_getroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg);
@@ -226,7 +225,6 @@
 extern int inet_rtm_delrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg);
 extern int inet_rtm_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg);
 extern int inet_dump_rules(struct sk_buff *skb, struct netlink_callback *cb);
-extern u32 fib_rules_map_destination(u32 daddr, struct fib_result *res);
 #ifdef CONFIG_NET_CLS_ROUTE
 extern u32 fib_rules_tclass(struct fib_result *res);
 #endif
diff -Nru a/include/net/ip_vs.h b/include/net/ip_vs.h
--- a/include/net/ip_vs.h	2005-03-01 23:38:44 -08:00
+++ b/include/net/ip_vs.h	2005-03-01 23:38:44 -08:00
@@ -701,8 +701,6 @@
  *      (from ip_vs_core.c)
  */
 extern const char *ip_vs_proto_name(unsigned proto);
-extern unsigned int check_for_ip_vs_out(struct sk_buff **skb_p,
-					int (*okfn)(struct sk_buff *));
 extern void ip_vs_init_hash_table(struct list_head *table, int rows);
 #define IP_VS_INIT_HASH_TABLE(t) ip_vs_init_hash_table(t, sizeof(t)/sizeof(t[0]))
 
diff -Nru a/include/net/ipconfig.h b/include/net/ipconfig.h
--- a/include/net/ipconfig.h	2005-03-01 23:38:58 -08:00
+++ b/include/net/ipconfig.h	2005-03-01 23:38:58 -08:00
@@ -8,14 +8,10 @@
 
 /* The following are initdata: */
 
-extern int ic_enable;		/* Enable or disable the whole shebang */
-
 extern int ic_proto_enabled;	/* Protocols enabled (see IC_xxx) */
-extern int ic_host_name_set;	/* Host name set by ipconfig? */
 extern int ic_set_manually;	/* IPconfig parameters set manually */
 
 extern u32 ic_myaddr;		/* My IP address */
-extern u32 ic_netmask;		/* Netmask for local subnet */
 extern u32 ic_gateway;		/* Gateway IP address */
 
 extern u32 ic_servaddr;		/* Boot server IP address */
@@ -23,13 +19,6 @@
 extern u32 root_server_addr;	/* Address of NFS server */
 extern u8 root_server_path[];	/* Path to mount as root */
 
-
-
-/* The following are persistent (not initdata): */
-
-extern int ic_proto_used;	/* Protocol used, if any */
-extern u32 ic_nameserver;	/* DNS server IP address */
-extern u8 ic_domain[];		/* DNS (not NIS) domain name */
 
 /* bits in ic_proto_{enabled,used} */
 #define IC_PROTO	0xFF	/* Protocols mask: */
diff -Nru a/include/net/ipv6.h b/include/net/ipv6.h
--- a/include/net/ipv6.h	2005-03-01 23:39:09 -08:00
+++ b/include/net/ipv6.h	2005-03-01 23:39:09 -08:00
@@ -149,6 +149,8 @@
 
 int snmp6_register_dev(struct inet6_dev *idev);
 int snmp6_unregister_dev(struct inet6_dev *idev);
+int snmp6_alloc_dev(struct inet6_dev *idev);
+int snmp6_free_dev(struct inet6_dev *idev);
 int snmp6_mib_init(void *ptr[2], size_t mibsize, size_t mibalign);
 void snmp6_mib_free(void *ptr[2]);
 
@@ -228,8 +230,6 @@
 extern int 			ip6_ra_control(struct sock *sk, int sel,
 					       void (*destructor)(struct sock *));
 
-
-extern int			ip6_call_ra_chain(struct sk_buff *skb, int sel);
 
 extern int			ipv6_parse_hopopts(struct sk_buff *skb, int);
 
diff -Nru a/include/net/ipx.h b/include/net/ipx.h
--- a/include/net/ipx.h	2005-03-01 23:38:52 -08:00
+++ b/include/net/ipx.h	2005-03-01 23:38:52 -08:00
@@ -90,7 +90,11 @@
 	} last_hop;
 };
 
-struct ipx_opt {
+#include <net/sock.h>
+
+struct ipx_sock {
+	/* struct sock has to be the first member of ipx_sock */
+	struct sock		sk;
 	struct ipx_address	dest_addr;
 	struct ipx_interface	*intrfc;
 	unsigned short		port;
@@ -105,9 +109,14 @@
 	unsigned short		ipx_ncp_conn;
 };
 
-#define ipx_sk(__sk) ((struct ipx_opt *)(__sk)->sk_protinfo)
+static inline struct ipx_sock *ipx_sk(struct sock *sk)
+{
+	return (struct ipx_sock *)sk;
+}
+
 #define IPX_SKB_CB(__skb) ((struct ipx_cb *)&((__skb)->cb[0]))
 #endif
+
 #define IPX_MIN_EPHEMERAL_SOCKET	0x4000
 #define IPX_MAX_EPHEMERAL_SOCKET	0x7fff
 
@@ -137,14 +146,6 @@
 {
 	if (atomic_dec_and_test(&intrfc->refcnt))
 		ipxitf_down(intrfc);
-}
-
-extern void __ipxitf_down(struct ipx_interface *intrfc);
-
-static __inline__ void __ipxitf_put(struct ipx_interface *intrfc)
-{
-	if (atomic_dec_and_test(&intrfc->refcnt))
-		__ipxitf_down(intrfc);
 }
 
 static __inline__ void ipxrtr_hold(struct ipx_route *rt)
diff -Nru a/include/net/irda/ircomm_event.h b/include/net/irda/ircomm_event.h
--- a/include/net/irda/ircomm_event.h	2005-03-01 23:38:57 -08:00
+++ b/include/net/irda/ircomm_event.h	2005-03-01 23:38:57 -08:00
@@ -75,7 +75,6 @@
 };
 
 extern char *ircomm_state[];
-extern char *ircomm_event[];
 
 struct ircomm_cb;   /* Forward decl. */
 
diff -Nru a/include/net/irda/ircomm_lmp.h b/include/net/irda/ircomm_lmp.h
--- a/include/net/irda/ircomm_lmp.h	2005-03-01 23:38:55 -08:00
+++ b/include/net/irda/ircomm_lmp.h	2005-03-01 23:38:55 -08:00
@@ -32,34 +32,7 @@
 #define IRCOMM_LMP_H
 
 #include <net/irda/ircomm_core.h>
-#include <net/irda/ircomm_event.h>
 
 int ircomm_open_lsap(struct ircomm_cb *self);
-int  ircomm_lmp_connect_request(struct ircomm_cb *self, 
-				struct sk_buff *userdata, 
-				struct ircomm_info *info);
-int  ircomm_lmp_connect_response(struct ircomm_cb *self, struct sk_buff *skb);
-int  ircomm_lmp_disconnect_request(struct ircomm_cb *self, 
-				   struct sk_buff *userdata, 
-				   struct ircomm_info *info);
-int  ircomm_lmp_data_request(struct ircomm_cb *self, struct sk_buff *skb, 
-			     int clen);
-int  ircomm_lmp_control_request(struct ircomm_cb *self, 
-			       struct sk_buff *userdata);
-int  ircomm_lmp_data_indication(void *instance, void *sap,
-				struct sk_buff *skb);
-void ircomm_lmp_connect_confirm(void *instance, void *sap,
-				struct qos_info *qos, 
-				__u32 max_sdu_size, 
-				__u8 max_header_size,
-				struct sk_buff *skb);
-void ircomm_lmp_connect_indication(void *instance, void *sap,
-				   struct qos_info *qos,
-				   __u32 max_sdu_size,
-				   __u8 max_header_size,
-				   struct sk_buff *skb);
-void ircomm_lmp_disconnect_indication(void *instance, void *sap, 
-				      LM_REASON reason,
-				      struct sk_buff *skb);
 
 #endif
diff -Nru a/include/net/irda/ircomm_param.h b/include/net/irda/ircomm_param.h
--- a/include/net/irda/ircomm_param.h	2005-03-01 23:39:17 -08:00
+++ b/include/net/irda/ircomm_param.h	2005-03-01 23:39:17 -08:00
@@ -141,7 +141,6 @@
 
 struct ircomm_tty_cb; /* Forward decl. */
 
-int ircomm_param_flush(struct ircomm_tty_cb *self);
 int ircomm_param_request(struct ircomm_tty_cb *self, __u8 pi, int flush);
 
 extern pi_param_info_t ircomm_param_info;
diff -Nru a/include/net/irda/ircomm_ttp.h b/include/net/irda/ircomm_ttp.h
--- a/include/net/irda/ircomm_ttp.h	2005-03-01 23:39:07 -08:00
+++ b/include/net/irda/ircomm_ttp.h	2005-03-01 23:39:07 -08:00
@@ -32,39 +32,8 @@
 #define IRCOMM_TTP_H
 
 #include <net/irda/ircomm_core.h>
-#include <net/irda/ircomm_event.h>
 
 int  ircomm_open_tsap(struct ircomm_cb *self);
-int  ircomm_ttp_connect_request(struct ircomm_cb *self, 
-				struct sk_buff *userdata, 
-				struct ircomm_info *info);
-int  ircomm_ttp_connect_response(struct ircomm_cb *self, struct sk_buff *skb);
-int  ircomm_ttp_disconnect_request(struct ircomm_cb *self, 
-				   struct sk_buff *userdata, 
-				   struct ircomm_info *info);
-int  ircomm_ttp_data_request(struct ircomm_cb *self, struct sk_buff *skb, 
-			     int clen);
-int  ircomm_ttp_control_request(struct ircomm_cb *self, 
-			       struct sk_buff *userdata);
-int  ircomm_ttp_data_indication(void *instance, void *sap,
-				struct sk_buff *skb);
-void ircomm_ttp_connect_confirm(void *instance, void *sap,
-				struct qos_info *qos, 
-				__u32 max_sdu_size, 
-				__u8 max_header_size,
-				struct sk_buff *skb);
-void ircomm_ttp_connect_indication(void *instance, void *sap,
-				   struct qos_info *qos,
-				   __u32 max_sdu_size,
-				   __u8 max_header_size,
-				   struct sk_buff *skb);
-void ircomm_ttp_disconnect_indication(void *instance, void *sap, 
-				      LM_REASON reason,
-				      struct sk_buff *skb);
-void ircomm_ttp_flow_indication(void *instance, void *sap, LOCAL_FLOW cmd);
 
 #endif
-
-
-
 
diff -Nru a/include/net/irda/ircomm_tty.h b/include/net/irda/ircomm_tty.h
--- a/include/net/irda/ircomm_tty.h	2005-03-01 23:38:56 -08:00
+++ b/include/net/irda/ircomm_tty.h	2005-03-01 23:38:56 -08:00
@@ -118,10 +118,8 @@
 };
 
 void ircomm_tty_start(struct tty_struct *tty);
-void ircomm_tty_stop(struct tty_struct *tty);
 void ircomm_tty_check_modem_status(struct ircomm_tty_cb *self);
 
-extern void ircomm_tty_change_speed(struct ircomm_tty_cb *self);
 extern int ircomm_tty_tiocmget(struct tty_struct *tty, struct file *file);
 extern int ircomm_tty_tiocmset(struct tty_struct *tty, struct file *file,
 			       unsigned int set, unsigned int clear);
diff -Nru a/include/net/irda/ircomm_tty_attach.h b/include/net/irda/ircomm_tty_attach.h
--- a/include/net/irda/ircomm_tty_attach.h	2005-03-01 23:39:16 -08:00
+++ b/include/net/irda/ircomm_tty_attach.h	2005-03-01 23:39:16 -08:00
@@ -67,7 +67,6 @@
 };
 
 extern char *ircomm_state[];
-extern char *ircomm_event[];
 extern char *ircomm_tty_state[];
 
 int ircomm_tty_do_event(struct ircomm_tty_cb *self, IRCOMM_TTY_EVENT event,
diff -Nru a/include/net/irda/irda_device.h b/include/net/irda/irda_device.h
--- a/include/net/irda/irda_device.h	2005-03-01 23:39:18 -08:00
+++ b/include/net/irda/irda_device.h	2005-03-01 23:39:18 -08:00
@@ -227,8 +227,6 @@
 	return (skb_queue_len(&dev->qdisc->q) == 0);
 }
 int  irda_device_set_raw_mode(struct net_device* self, int status);
-int  irda_device_set_dtr_rts(struct net_device *dev, int dtr, int rts);
-int  irda_device_change_speed(struct net_device *dev, __u32 speed);
 struct net_device *alloc_irdadev(int sizeof_priv);
 
 /* Dongle interface */
diff -Nru a/include/net/irda/iriap.h b/include/net/irda/iriap.h
--- a/include/net/irda/iriap.h	2005-03-01 23:38:54 -08:00
+++ b/include/net/irda/iriap.h	2005-03-01 23:38:54 -08:00
@@ -97,21 +97,11 @@
 int iriap_getvaluebyclass_request(struct iriap_cb *self, 
 				  __u32 saddr, __u32 daddr,
 				  char *name, char *attr);
-void iriap_getvaluebyclass_confirm(struct iriap_cb *self, struct sk_buff *skb);
 void iriap_connect_request(struct iriap_cb *self);
 void iriap_send_ack( struct iriap_cb *self);
 void iriap_call_indication(struct iriap_cb *self, struct sk_buff *skb);
 
 void iriap_register_server(void);
-
-void iriap_watchdog_timer_expired(void *data);
-
-static inline void iriap_start_watchdog_timer(struct iriap_cb *self, 
-					      int timeout) 
-{
-	irda_start_timer(&self->watchdog_timer, timeout, self, 
-			 iriap_watchdog_timer_expired);
-}
 
 #endif
 
diff -Nru a/include/net/irda/irlan_client.h b/include/net/irda/irlan_client.h
--- a/include/net/irda/irlan_client.h	2005-03-01 23:39:09 -08:00
+++ b/include/net/irda/irlan_client.h	2005-03-01 23:39:09 -08:00
@@ -33,11 +33,8 @@
 #include <net/irda/irias_object.h>
 #include <net/irda/irlan_event.h>
 
-void irlan_client_start_kick_timer(struct irlan_cb *self, int timeout);
 void irlan_client_discovery_indication(discinfo_t *, DISCOVERY_MODE, void *);
 void irlan_client_wakeup(struct irlan_cb *self, __u32 saddr, __u32 daddr);
-
-void irlan_client_open_ctrl_tsap( struct irlan_cb *self);
 
 void irlan_client_parse_response(struct irlan_cb *self, struct sk_buff *skb);
 void irlan_client_get_value_confirm(int result, __u16 obj_id, 
diff -Nru a/include/net/irda/irlan_common.h b/include/net/irda/irlan_common.h
--- a/include/net/irda/irlan_common.h	2005-03-01 23:39:08 -08:00
+++ b/include/net/irda/irlan_common.h	2005-03-01 23:39:08 -08:00
@@ -190,7 +190,6 @@
 	struct timer_list watchdog_timer;
 };
 
-struct irlan_cb *irlan_open(__u32 saddr, __u32 daddr);
 void irlan_close(struct irlan_cb *self);
 void irlan_close_tsaps(struct irlan_cb *self);
 
@@ -204,13 +203,11 @@
 
 struct irlan_cb *irlan_get_any(void);
 void irlan_get_provider_info(struct irlan_cb *self);
-void irlan_get_unicast_addr(struct irlan_cb *self);
 void irlan_get_media_char(struct irlan_cb *self);
 void irlan_open_data_channel(struct irlan_cb *self);
 void irlan_close_data_channel(struct irlan_cb *self);
 void irlan_set_multicast_filter(struct irlan_cb *self, int status);
 void irlan_set_broadcast_filter(struct irlan_cb *self, int status);
-void irlan_open_unicast_addr(struct irlan_cb *self);
 
 int irlan_insert_byte_param(struct sk_buff *skb, char *param, __u8 value);
 int irlan_insert_short_param(struct sk_buff *skb, char *param, __u16 value);
diff -Nru a/include/net/irda/irlap.h b/include/net/irda/irlap.h
--- a/include/net/irda/irlap.h	2005-03-01 23:39:18 -08:00
+++ b/include/net/irda/irlap.h	2005-03-01 23:39:18 -08:00
@@ -253,10 +253,8 @@
 int  irlap_generate_rand_time_slot(int S, int s);
 void irlap_initiate_connection_state(struct irlap_cb *);
 void irlap_flush_all_queues(struct irlap_cb *);
-void irlap_change_speed(struct irlap_cb *self, __u32 speed, int now);
 void irlap_wait_min_turn_around(struct irlap_cb *, struct qos_info *);
 
-void irlap_init_qos_capabilities(struct irlap_cb *, struct qos_info *);
 void irlap_apply_default_connection_parameters(struct irlap_cb *self);
 void irlap_apply_connection_parameters(struct irlap_cb *self, int now);
 
diff -Nru a/include/net/irda/irlap_frame.h b/include/net/irda/irlap_frame.h
--- a/include/net/irda/irlap_frame.h	2005-03-01 23:38:58 -08:00
+++ b/include/net/irda/irlap_frame.h	2005-03-01 23:38:58 -08:00
@@ -133,7 +133,6 @@
 void irlap_resend_rejected_frames(struct irlap_cb *, int command);
 void irlap_resend_rejected_frame(struct irlap_cb *self, int command);
 
-void irlap_send_i_frame(struct irlap_cb *, struct sk_buff *, int command);
 void irlap_send_ui_frame(struct irlap_cb *self, struct sk_buff *skb,
 			 __u8 caddr, int command);
 
diff -Nru a/include/net/irda/irlmp.h b/include/net/irda/irlmp.h
--- a/include/net/irda/irlmp.h	2005-03-01 23:38:51 -08:00
+++ b/include/net/irda/irlmp.h	2005-03-01 23:38:51 -08:00
@@ -242,12 +242,9 @@
 void irlmp_connless_data_indication(struct lsap_cb *, struct sk_buff *);
 #endif /* CONFIG_IRDA_ULTRA */
 
-void irlmp_status_request(void);
 void irlmp_status_indication(struct lap_cb *, LINK_STATUS link, LOCK_STATUS lock);
 void irlmp_flow_indication(struct lap_cb *self, LOCAL_FLOW flow);
 
-int  irlmp_slsap_inuse(__u8 slsap);
-__u8 irlmp_find_free_slsap(void);
 LM_REASON irlmp_convert_lap_reason(LAP_REASON);
 
 static inline __u32 irlmp_get_saddr(const struct lsap_cb *self)
diff -Nru a/include/net/irda/irttp.h b/include/net/irda/irttp.h
--- a/include/net/irda/irttp.h	2005-03-01 23:38:54 -08:00
+++ b/include/net/irda/irttp.h	2005-03-01 23:38:54 -08:00
@@ -167,9 +167,6 @@
 int irttp_disconnect_request(struct tsap_cb *self, struct sk_buff *skb,
 			     int priority);
 void irttp_flow_request(struct tsap_cb *self, LOCAL_FLOW flow);
-void irttp_status_indication(void *instance,
-			     LINK_STATUS link, LOCK_STATUS lock);
-void irttp_flow_indication(void *instance, void *sap, LOCAL_FLOW flow);
 struct tsap_cb *irttp_dup(struct tsap_cb *self, void *instance);
 
 static __inline __u32 irttp_get_saddr(struct tsap_cb *self)
diff -Nru a/include/net/irda/parameters.h b/include/net/irda/parameters.h
--- a/include/net/irda/parameters.h	2005-03-01 23:38:51 -08:00
+++ b/include/net/irda/parameters.h	2005-03-01 23:38:51 -08:00
@@ -90,11 +90,9 @@
 } pi_param_info_t;
 
 int irda_param_pack(__u8 *buf, char *fmt, ...);
-int irda_param_unpack(__u8 *buf, char *fmt, ...);
 
 int irda_param_insert(void *self, __u8 pi, __u8 *buf, int len, 
 		      pi_param_info_t *info);
-int irda_param_extract(void *self, __u8 *buf, int len, pi_param_info_t *info);
 int irda_param_extract_all(void *self, __u8 *buf, int len, 
 			   pi_param_info_t *info);
 
diff -Nru a/include/net/irda/qos.h b/include/net/irda/qos.h
--- a/include/net/irda/qos.h	2005-03-01 23:38:52 -08:00
+++ b/include/net/irda/qos.h	2005-03-01 23:38:52 -08:00
@@ -87,7 +87,6 @@
 void irda_qos_compute_intersection(struct qos_info *, struct qos_info *);
 
 __u32 irlap_max_line_capacity(__u32 speed, __u32 max_turn_time);
-__u32 irlap_requested_line_capacity(struct qos_info *qos);
 
 void irda_qos_bits_to_value(struct qos_info *qos);
 
diff -Nru a/include/net/iw_handler.h b/include/net/iw_handler.h
--- a/include/net/iw_handler.h	2005-03-01 23:39:18 -08:00
+++ b/include/net/iw_handler.h	2005-03-01 23:39:18 -08:00
@@ -418,9 +418,6 @@
  * Those may be called only within the kernel.
  */
 
-/* Data needed by fs/compat_ioctl.c for 32->64 bit conversion */
-extern const char iw_priv_type_size[];
-
 /* First : function strictly used inside the kernel */
 
 /* Handle /proc/net/wireless, called in net/code/dev.c */
diff -Nru a/include/net/llc_c_ac.h b/include/net/llc_c_ac.h
--- a/include/net/llc_c_ac.h	2005-03-01 23:39:17 -08:00
+++ b/include/net/llc_c_ac.h	2005-03-01 23:39:17 -08:00
@@ -96,7 +96,6 @@
 extern int llc_conn_ac_disc_ind(struct sock* sk, struct sk_buff *skb);
 extern int llc_conn_ac_rst_ind(struct sock* sk, struct sk_buff *skb);
 extern int llc_conn_ac_rst_confirm(struct sock* sk, struct sk_buff *skb);
-extern int llc_conn_ac_report_status(struct sock* sk, struct sk_buff *skb);
 extern int llc_conn_ac_clear_remote_busy_if_f_eq_1(struct sock* sk,
 						   struct sk_buff *skb);
 extern int llc_conn_ac_stop_rej_tmr_if_data_flag_eq_2(struct sock* sk,
@@ -107,8 +106,6 @@
 					   struct sk_buff *skb);
 extern int llc_conn_ac_send_dm_rsp_f_set_1(struct sock* sk,
 					   struct sk_buff *skb);
-extern int llc_conn_ac_send_dm_rsp_f_set_f_flag(struct sock* sk,
-						struct sk_buff *skb);
 extern int llc_conn_ac_send_frmr_rsp_f_set_x(struct sock* sk,
 					     struct sk_buff *skb);
 extern int llc_conn_ac_resend_frmr_rsp_f_set_0(struct sock* sk,
@@ -116,11 +113,6 @@
 extern int llc_conn_ac_resend_frmr_rsp_f_set_p(struct sock* sk,
 					       struct sk_buff *skb);
 extern int llc_conn_ac_send_i_cmd_p_set_1(struct sock* sk, struct sk_buff *skb);
-extern int llc_conn_ac_send_i_cmd_p_set_0(struct sock* sk, struct sk_buff *skb);
-extern int llc_conn_ac_resend_i_cmd_p_set_1(struct sock* sk,
-					    struct sk_buff *skb);
-extern int llc_conn_ac_resend_i_cmd_p_set_1_or_send_rr(struct sock* sk,
-						  struct sk_buff *skb);
 extern int llc_conn_ac_send_i_xxx_x_set_0(struct sock* sk, struct sk_buff *skb);
 extern int llc_conn_ac_resend_i_xxx_x_set_0(struct sock* sk,
 					    struct sk_buff *skb);
@@ -145,8 +137,6 @@
 						struct sk_buff *skb);
 extern int llc_conn_ac_send_rr_cmd_p_set_1(struct sock* sk,
 					   struct sk_buff *skb);
-extern int llc_conn_ac_send_ack_cmd_p_set_1(struct sock* sk,
-					    struct sk_buff *skb);
 extern int llc_conn_ac_send_rr_rsp_f_set_1(struct sock* sk,
 					   struct sk_buff *skb);
 extern int llc_conn_ac_send_ack_rsp_f_set_1(struct sock* sk,
@@ -157,8 +147,6 @@
 					    struct sk_buff *skb);
 extern int llc_conn_ac_send_sabme_cmd_p_set_x(struct sock* sk,
 					      struct sk_buff *skb);
-extern int llc_conn_ac_send_ua_rsp_f_set_f_flag(struct sock* sk,
-						struct sk_buff *skb);
 extern int llc_conn_ac_send_ua_rsp_f_set_p(struct sock* sk,
 					   struct sk_buff *skb);
 extern int llc_conn_ac_set_s_flag_0(struct sock* sk, struct sk_buff *skb);
@@ -183,7 +171,6 @@
 extern int llc_conn_ac_set_data_flag_1_if_data_flag_eq_0(struct sock* sk,
 							 struct sk_buff *skb);
 extern int llc_conn_ac_set_p_flag_0(struct sock* sk, struct sk_buff *skb);
-extern int llc_conn_ac_set_p_flag_1(struct sock* sk, struct sk_buff *skb);
 extern int llc_conn_ac_set_remote_busy_0(struct sock* sk, struct sk_buff *skb);
 extern int llc_conn_ac_set_retry_cnt_0(struct sock* sk, struct sk_buff *skb);
 extern int llc_conn_ac_set_cause_flag_0(struct sock* sk, struct sk_buff *skb);
@@ -195,20 +182,14 @@
 extern int llc_conn_ac_set_vs_nr(struct sock* sk, struct sk_buff *skb);
 extern int llc_conn_ac_rst_vs(struct sock* sk, struct sk_buff *skb);
 extern int llc_conn_ac_upd_vs(struct sock* sk, struct sk_buff *skb);
-extern int llc_conn_ac_set_f_flag_p(struct sock* sk, struct sk_buff *skb);
 extern int llc_conn_disc(struct sock* sk, struct sk_buff *skb);
 extern int llc_conn_reset(struct sock* sk, struct sk_buff *skb);
 extern int llc_conn_ac_disc_confirm(struct sock* sk, struct sk_buff *skb);
 extern u8 llc_circular_between(u8 a, u8 b, u8 c);
 extern int llc_conn_ac_send_ack_if_needed(struct sock* sk, struct sk_buff *skb);
-extern int llc_conn_ac_inc_npta_value(struct sock* sk, struct sk_buff *skb);
 extern int llc_conn_ac_adjust_npta_by_rr(struct sock* sk, struct sk_buff *skb);
 extern int llc_conn_ac_adjust_npta_by_rnr(struct sock* sk, struct sk_buff *skb);
 extern int llc_conn_ac_rst_sendack_flag(struct sock* sk, struct sk_buff *skb);
-extern int llc_conn_ac_send_rr_rsp_f_set_ackpf(struct sock* sk,
-					       struct sk_buff *skb);
-extern int llc_conn_ac_send_i_rsp_f_set_ackpf(struct sock* sk,
-					      struct sk_buff *skb);
 extern int llc_conn_ac_send_i_rsp_as_ack(struct sock* sk, struct sk_buff *skb);
 extern int llc_conn_ac_send_i_as_ack(struct sock* sk, struct sk_buff *skb);
 
diff -Nru a/include/net/llc_c_ev.h b/include/net/llc_c_ev.h
--- a/include/net/llc_c_ev.h	2005-03-01 23:38:52 -08:00
+++ b/include/net/llc_c_ev.h	2005-03-01 23:38:52 -08:00
@@ -129,11 +129,9 @@
 typedef int (*llc_conn_ev_qfyr_t)(struct sock *sk, struct sk_buff *skb);
 
 extern int llc_conn_ev_conn_req(struct sock *sk, struct sk_buff *skb);
-extern int llc_conn_ev_conn_resp(struct sock *sk, struct sk_buff *skb);
 extern int llc_conn_ev_data_req(struct sock *sk, struct sk_buff *skb);
 extern int llc_conn_ev_disc_req(struct sock *sk, struct sk_buff *skb);
 extern int llc_conn_ev_rst_req(struct sock *sk, struct sk_buff *skb);
-extern int llc_conn_ev_rst_resp(struct sock *sk, struct sk_buff *skb);
 extern int llc_conn_ev_local_busy_detected(struct sock *sk,
 					   struct sk_buff *skb);
 extern int llc_conn_ev_local_busy_cleared(struct sock *sk, struct sk_buff *skb);
@@ -162,7 +160,6 @@
 					     struct sk_buff *skb);
 extern int llc_conn_ev_rx_xxx_rsp_fbit_set_x(struct sock *sk,
 					     struct sk_buff *skb);
-extern int llc_conn_ev_rx_xxx_yyy(struct sock *sk, struct sk_buff *skb);
 extern int llc_conn_ev_rx_zzz_cmd_pbit_set_x_inval_nr(struct sock *sk,
 						      struct sk_buff *skb);
 extern int llc_conn_ev_rx_zzz_rsp_fbit_set_x_inval_nr(struct sock *sk,
@@ -171,13 +168,10 @@
 extern int llc_conn_ev_ack_tmr_exp(struct sock *sk, struct sk_buff *skb);
 extern int llc_conn_ev_rej_tmr_exp(struct sock *sk, struct sk_buff *skb);
 extern int llc_conn_ev_busy_tmr_exp(struct sock *sk, struct sk_buff *skb);
-extern int llc_conn_ev_any_tmr_exp(struct sock *sk, struct sk_buff *skb);
 extern int llc_conn_ev_sendack_tmr_exp(struct sock *sk, struct sk_buff *skb);
 /* NOT_USED functions and their variations */
 extern int llc_conn_ev_rx_xxx_cmd_pbit_set_1(struct sock *sk,
 					     struct sk_buff *skb);
-extern int llc_conn_ev_rx_xxx_cmd_pbit_set_0(struct sock *sk,
-					     struct sk_buff *skb);
 extern int llc_conn_ev_rx_xxx_rsp_fbit_set_1(struct sock *sk,
 					     struct sk_buff *skb);
 extern int llc_conn_ev_rx_i_cmd_pbit_set_0_unexpd_ns(struct sock *sk,
@@ -252,20 +246,14 @@
 					    struct sk_buff *skb);
 extern int llc_conn_ev_qlfy_cause_flag_eq_0(struct sock *sk,
 					    struct sk_buff *skb);
-extern int llc_conn_ev_qlfy_init_p_f_cycle(struct sock *sk,
-					   struct sk_buff *skb);
 extern int llc_conn_ev_qlfy_set_status_conn(struct sock *sk,
 					    struct sk_buff *skb);
 extern int llc_conn_ev_qlfy_set_status_disc(struct sock *sk,
 					    struct sk_buff *skb);
 extern int llc_conn_ev_qlfy_set_status_failed(struct sock *sk,
 					      struct sk_buff *skb);
-extern int llc_conn_ev_qlfy_set_status_impossible(struct sock *sk,
-						  struct sk_buff *skb);
 extern int llc_conn_ev_qlfy_set_status_remote_busy(struct sock *sk,
 						  struct sk_buff *skb);
-extern int llc_conn_ev_qlfy_set_status_received(struct sock *sk,
-						struct sk_buff *skb);
 extern int llc_conn_ev_qlfy_set_status_refuse(struct sock *sk,
 					      struct sk_buff *skb);
 extern int llc_conn_ev_qlfy_set_status_conflict(struct sock *sk,
diff -Nru a/include/net/llc_conn.h b/include/net/llc_conn.h
--- a/include/net/llc_conn.h	2005-03-01 23:39:09 -08:00
+++ b/include/net/llc_conn.h	2005-03-01 23:39:09 -08:00
@@ -91,7 +91,6 @@
 extern void llc_sk_free(struct sock *sk);
 
 extern void llc_sk_reset(struct sock *sk);
-extern int llc_sk_init(struct sock *sk);
 
 /* Access to a connection */
 extern int llc_conn_state_process(struct sock *sk, struct sk_buff *skb);
@@ -106,8 +105,6 @@
 extern struct sock *llc_lookup_established(struct llc_sap *sap,
 					   struct llc_addr *daddr,
 					   struct llc_addr *laddr);
-extern struct sock *llc_lookup_listener(struct llc_sap *sap,
-					struct llc_addr *laddr);
 extern void llc_sap_add_socket(struct llc_sap *sap, struct sock *sk);
 extern void llc_sap_remove_socket(struct llc_sap *sap, struct sock *sk);
 
diff -Nru a/include/net/llc_pdu.h b/include/net/llc_pdu.h
--- a/include/net/llc_pdu.h	2005-03-01 23:39:08 -08:00
+++ b/include/net/llc_pdu.h	2005-03-01 23:39:08 -08:00
@@ -419,7 +419,6 @@
 extern void llc_pdu_set_cmd_rsp(struct sk_buff *skb, u8 type);
 extern void llc_pdu_set_pf_bit(struct sk_buff *skb, u8 bit_value);
 extern void llc_pdu_decode_pf_bit(struct sk_buff *skb, u8 *pf_bit);
-extern void llc_pdu_decode_cr_bit(struct sk_buff *skb, u8 *cr_bit);
 extern void llc_pdu_init_as_disc_cmd(struct sk_buff *skb, u8 p_bit);
 extern void llc_pdu_init_as_i_cmd(struct sk_buff *skb, u8 p_bit, u8 ns, u8 nr);
 extern void llc_pdu_init_as_rej_cmd(struct sk_buff *skb, u8 p_bit, u8 nr);
diff -Nru a/include/net/llc_sap.h b/include/net/llc_sap.h
--- a/include/net/llc_sap.h	2005-03-01 23:38:44 -08:00
+++ b/include/net/llc_sap.h	2005-03-01 23:38:44 -08:00
@@ -14,7 +14,6 @@
 struct llc_sap;
 struct sk_buff;
 
-extern void llc_sap_state_process(struct llc_sap *sap, struct sk_buff *skb);
 extern void llc_sap_rtn_pdu(struct llc_sap *sap, struct sk_buff *skb);
 extern void llc_save_primitive(struct sk_buff* skb, unsigned char prim);
 extern struct sk_buff *llc_alloc_frame(void);
diff -Nru a/include/net/pkt_act.h b/include/net/pkt_act.h
--- a/include/net/pkt_act.h	2005-03-01 23:39:08 -08:00
+++ b/include/net/pkt_act.h	2005-03-01 23:39:08 -08:00
@@ -218,25 +218,22 @@
 
 #ifdef CONFIG_NET_ACT_INIT
 static inline struct tcf_st *
-tcf_hash_check(struct tc_st *parm, struct tc_action *a, int ovr, int bind)
+tcf_hash_check(u32 index, struct tc_action *a, int ovr, int bind)
 {
 	struct tcf_st *p = NULL;
-	if (parm->index && (p = tcf_hash_lookup(parm->index)) != NULL) {
-		spin_lock(&p->lock);
+	if (index && (p = tcf_hash_lookup(index)) != NULL) {
 		if (bind) {
 			p->bindcnt++;
 			p->refcnt++;
 		}
-		spin_unlock(&p->lock);
-		a->priv = (void *) p;
+		a->priv = p;
 	}
 	return p;
 }
 
 static inline struct tcf_st *
-tcf_hash_create(struct tc_st *parm, struct rtattr *est, struct tc_action *a, int size, int ovr, int bind)
+tcf_hash_create(u32 index, struct rtattr *est, struct tc_action *a, int size, int ovr, int bind)
 {
-	unsigned h;
 	struct tcf_st *p = NULL;
 
 	p = kmalloc(size, GFP_KERNEL);
@@ -252,31 +249,25 @@
 
 	spin_lock_init(&p->lock);
 	p->stats_lock = &p->lock;
-	p->index = parm->index ? : tcf_hash_new_index();
+	p->index = index ? : tcf_hash_new_index();
 	p->tm.install = jiffies;
 	p->tm.lastuse = jiffies;
 #ifdef CONFIG_NET_ESTIMATOR
 	if (est)
 		gen_new_estimator(&p->bstats, &p->rate_est, p->stats_lock, est);
 #endif
-	h = tcf_hash(p->index);
-	write_lock_bh(&tcf_t_lock);
-	p->next = tcf_ht[h];
-	tcf_ht[h] = p;
-	write_unlock_bh(&tcf_t_lock);
-
 	a->priv = (void *) p;
 	return p;
 }
 
-static inline struct tcf_st *
-tcf_hash_init(struct tc_st *parm, struct rtattr *est, struct tc_action *a, int size, int ovr, int bind)
+static inline void tcf_hash_insert(struct tcf_st *p)
 {
-	struct tcf_st *p = tcf_hash_check (parm,a,ovr,bind);
+	unsigned h = tcf_hash(p->index);
 
-	if (!p)
-		p = tcf_hash_create(parm, est, a, size, ovr, bind);
-	return p;
+	write_lock_bh(&tcf_t_lock);
+	p->next = tcf_ht[h];
+	tcf_ht[h] = p;
+	write_unlock_bh(&tcf_t_lock);
 }
 
 #endif
diff -Nru a/include/net/pkt_cls.h b/include/net/pkt_cls.h
--- a/include/net/pkt_cls.h	2005-03-01 23:39:08 -08:00
+++ b/include/net/pkt_cls.h	2005-03-01 23:39:08 -08:00
@@ -17,7 +17,6 @@
 
 extern int register_tcf_proto_ops(struct tcf_proto_ops *ops);
 extern int unregister_tcf_proto_ops(struct tcf_proto_ops *ops);
-extern int ing_filter(struct sk_buff *skb);
 
 static inline unsigned long
 __cls_set_class(unsigned long *clp, unsigned long cl)
@@ -62,114 +61,99 @@
 		tp->q->ops->cl_ops->unbind_tcf(tp->q, cl);
 }
 
+struct tcf_exts
+{
 #ifdef CONFIG_NET_CLS_ACT
+	struct tc_action *action;
+#elif defined CONFIG_NET_CLS_POLICE
+	struct tcf_police *police;
+#endif
+};
+
+/* Map to export classifier specific extension TLV types to the
+ * generic extensions API. Unsupported extensions must be set to 0.
+ */
+struct tcf_ext_map
+{
+	int action;
+	int police;
+};
+
+/**
+ * tcf_exts_is_predicative - check if a predicative extension is present
+ * @exts: tc filter extensions handle
+ *
+ * Returns 1 if a predicative extension is present, i.e. an extension which
+ * might cause further actions and thus overrule the regular tcf_result.
+ */
 static inline int
-tcf_change_act_police(struct tcf_proto *tp, struct tc_action **action,
-	struct rtattr *act_police_tlv, struct rtattr *rate_tlv)
+tcf_exts_is_predicative(struct tcf_exts *exts)
 {
-	int ret;
-	struct tc_action *act;
-
-	act = kmalloc(sizeof(*act), GFP_KERNEL);
-	if (NULL == act)
-		return -ENOMEM;
-	memset(act, 0, sizeof(*act));
-	
-	ret = tcf_action_init_1(act_police_tlv, rate_tlv, act, "police",
-		TCA_ACT_NOREPLACE, TCA_ACT_BIND);
-	if (ret < 0) {
-		tcf_action_destroy(act, TCA_ACT_UNBIND);
-		return ret;
-	}
-
-	act->type = TCA_OLD_COMPAT;
-
-	if (*action) {
-		tcf_tree_lock(tp);
-		act = xchg(action, act);
-		tcf_tree_unlock(tp);
-
-		tcf_action_destroy(act, TCA_ACT_UNBIND);
-	} else
-		*action = act;
-
-	return 0;
-}
-
+#ifdef CONFIG_NET_CLS_ACT
+	return !!exts->action;
+#elif defined CONFIG_NET_CLS_POLICE
+	return !!exts->police;
+#else
+	return 0;
+#endif
+}
+
+/**
+ * tcf_exts_is_available - check if at least one extension is present
+ * @exts: tc filter extensions handle
+ *
+ * Returns 1 if at least one extension is present.
+ */
+static inline int
+tcf_exts_is_available(struct tcf_exts *exts)
+{
+	/* All non-predicative extensions must be added here. */
+	return tcf_exts_is_predicative(exts);
+}
+
+/**
+ * tcf_exts_exec - execute tc filter extensions
+ * @skb: socket buffer
+ * @exts: tc filter extensions handle
+ * @res: desired result
+ *
+ * Executes all configured extensions. Returns 0 on a normal execution,
+ * a negative number if the filter must be considered unmatched or
+ * a positive action code (TC_ACT_*) which must be returned to the
+ * underlying layer.
+ */
 static inline int
-tcf_change_act(struct tcf_proto *tp, struct tc_action **action,
-	struct rtattr *act_tlv, struct rtattr *rate_tlv)
+tcf_exts_exec(struct sk_buff *skb, struct tcf_exts *exts,
+	       struct tcf_result *res)
 {
-	int ret;
-	struct tc_action *act;
-
-	act = kmalloc(sizeof(*act), GFP_KERNEL);
-	if (NULL == act)
-		return -ENOMEM;
-	memset(act, 0, sizeof(*act));
-
-	ret = tcf_action_init(act_tlv, rate_tlv, act, NULL,
-		TCA_ACT_NOREPLACE, TCA_ACT_BIND);
-	if (ret < 0) {
-		tcf_action_destroy(act, TCA_ACT_UNBIND);
-		return ret;
-	}
-
-	if (*action) {
-		tcf_tree_lock(tp);
-		act = xchg(action, act);
-		tcf_tree_unlock(tp);
-
-		tcf_action_destroy(act, TCA_ACT_UNBIND);
-	} else
-		*action = act;
+#ifdef CONFIG_NET_CLS_ACT
+	if (exts->action)
+		return tcf_action_exec(skb, exts->action, res);
+#elif defined CONFIG_NET_CLS_POLICE
+	if (exts->police)
+		return tcf_police(skb, exts->police);
+#endif
 
 	return 0;
 }
 
-static inline int
-tcf_dump_act(struct sk_buff *skb, struct tc_action *action,
-	int act_type, int compat_type)
-{
-	/*
-	 * again for backward compatible mode - we want
-	 * to work with both old and new modes of entering
-	 * tc data even if iproute2  was newer - jhs
-	 */
-	if (action) {
-		struct rtattr * p_rta = (struct rtattr*) skb->tail;
-
-		if (action->type != TCA_OLD_COMPAT) {
-			RTA_PUT(skb, act_type, 0, NULL);
-			if (tcf_action_dump(skb, action, 0, 0) < 0)
-				goto rtattr_failure;
-		} else {
-			RTA_PUT(skb, compat_type, 0, NULL);
-			if (tcf_action_dump_old(skb, action, 0, 0) < 0)
-				goto rtattr_failure;
-		}
-		
-		p_rta->rta_len = skb->tail - (u8*)p_rta;
-	}
-	return 0;
-
-rtattr_failure:
-	return -1;
-}
-#endif /* CONFIG_NET_CLS_ACT */
+extern int tcf_exts_validate(struct tcf_proto *tp, struct rtattr **tb,
+	                     struct rtattr *rate_tlv, struct tcf_exts *exts,
+	                     struct tcf_ext_map *map);
+extern void tcf_exts_destroy(struct tcf_proto *tp, struct tcf_exts *exts);
+extern void tcf_exts_change(struct tcf_proto *tp, struct tcf_exts *dst,
+	                     struct tcf_exts *src);
+extern int tcf_exts_dump(struct sk_buff *skb, struct tcf_exts *exts,
+	                 struct tcf_ext_map *map);
+extern int tcf_exts_dump_stats(struct sk_buff *skb, struct tcf_exts *exts,
+	                       struct tcf_ext_map *map);
 
 #ifdef CONFIG_NET_CLS_IND
 static inline int
 tcf_change_indev(struct tcf_proto *tp, char *indev, struct rtattr *indev_tlv)
 {
-	if (RTA_PAYLOAD(indev_tlv) >= IFNAMSIZ) {
-		printk("cls: bad indev name %s\n", (char *) RTA_DATA(indev_tlv));
+	if (rtattr_strlcpy(indev, indev_tlv, IFNAMSIZ) >= IFNAMSIZ)
 		return -EINVAL;
-	}
-
-	memset(indev, 0, IFNAMSIZ);
-	sprintf(indev, "%s", (char *) RTA_DATA(indev_tlv));
-
 	return 0;
 }
 
@@ -186,45 +170,5 @@
 	return 1;
 }
 #endif /* CONFIG_NET_CLS_IND */
-
-#ifdef CONFIG_NET_CLS_POLICE
-static inline int
-tcf_change_police(struct tcf_proto *tp, struct tcf_police **police,
-	struct rtattr *police_tlv, struct rtattr *rate_tlv)
-{
-	struct tcf_police *p = tcf_police_locate(police_tlv, rate_tlv);
-
-	if (*police) {
-		tcf_tree_lock(tp);
-		p = xchg(police, p);
-		tcf_tree_unlock(tp);
-
-		tcf_police_release(p, TCA_ACT_UNBIND);
-	} else
-		*police = p;
-
-	return 0;
-}
-
-static inline int
-tcf_dump_police(struct sk_buff *skb, struct tcf_police *police,
-	int police_type)
-{
-	if (police) {
-		struct rtattr * p_rta = (struct rtattr*) skb->tail;
-
-		RTA_PUT(skb, police_type, 0, NULL);
-
-		if (tcf_police_dump(skb, police) < 0)
-			goto rtattr_failure;
-
-		p_rta->rta_len = skb->tail - (u8*)p_rta;
-	}
-	return 0;
-
-rtattr_failure:
-	return -1;
-}
-#endif /* CONFIG_NET_CLS_POLICE */
 
 #endif
diff -Nru a/include/net/rose.h b/include/net/rose.h
--- a/include/net/rose.h	2005-03-01 23:38:52 -08:00
+++ b/include/net/rose.h	2005-03-01 23:38:52 -08:00
@@ -162,7 +162,6 @@
 extern void rose_destroy_socket(struct sock *);
 
 /* rose_dev.c */
-extern int  rose_rx_ip(struct sk_buff *, struct net_device *);
 extern void  rose_setup(struct net_device *);
 
 /* rose_in.c */
@@ -170,15 +169,10 @@
 
 /* rose_link.c */
 extern void rose_start_ftimer(struct rose_neigh *);
-extern void rose_start_t0timer(struct rose_neigh *);
 extern void rose_stop_ftimer(struct rose_neigh *);
 extern void rose_stop_t0timer(struct rose_neigh *);
 extern int  rose_ftimer_running(struct rose_neigh *);
-extern int  rose_t0timer_running(struct rose_neigh *);
 extern void rose_link_rx_restart(struct sk_buff *, struct rose_neigh *, unsigned short);
-extern void rose_transmit_restart_request(struct rose_neigh *);
-extern void rose_transmit_restart_confirmation(struct rose_neigh *);
-extern void rose_transmit_diagnostic(struct rose_neigh *, unsigned char);
 extern void rose_transmit_clear_request(struct rose_neigh *, unsigned int, unsigned char, unsigned char);
 extern void rose_transmit_link(struct sk_buff *, struct rose_neigh *);
 
@@ -205,7 +199,6 @@
 extern struct net_device *rose_dev_first(void);
 extern struct net_device *rose_dev_get(rose_address *);
 extern struct rose_route *rose_route_free_lci(unsigned int, struct rose_neigh *);
-extern struct net_device *rose_ax25_dev_get(char *);
 extern struct rose_neigh *rose_get_neigh(rose_address *, unsigned char *, unsigned char *);
 extern int  rose_rt_ioctl(unsigned int, void __user *);
 extern void rose_link_failed(ax25_cb *, int);
@@ -220,7 +213,6 @@
 extern void rose_write_internal(struct sock *, int);
 extern int  rose_decode(struct sk_buff *, int *, int *, int *, int *, int *);
 extern int  rose_parse_facilities(unsigned char *, struct rose_facilities_struct *);
-extern int  rose_create_facilities(unsigned char *, rose_cb *);
 extern void rose_disconnect(struct sock *, int, int, int);
 
 /* rose_timer.c */
diff -Nru a/include/net/route.h b/include/net/route.h
--- a/include/net/route.h	2005-03-01 23:38:44 -08:00
+++ b/include/net/route.h	2005-03-01 23:38:44 -08:00
@@ -105,7 +105,7 @@
 
 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, _smp_processor_id())->field++)
 
 extern struct ip_rt_acct *ip_rt_acct;
 
diff -Nru a/include/net/sctp/command.h b/include/net/sctp/command.h
--- a/include/net/sctp/command.h	2005-03-01 23:39:17 -08:00
+++ b/include/net/sctp/command.h	2005-03-01 23:39:17 -08:00
@@ -189,11 +189,6 @@
 } sctp_cmd_seq_t;
 
 
-/* Create a new sctp_command_sequence.
- * Return NULL if creating a new sequence fails.
- */
-sctp_cmd_seq_t *sctp_new_cmd_seq(int gfp);
-
 /* Initialize a block of memory as a command sequence.
  * Return 0 if the initialization fails.
  */
@@ -207,18 +202,10 @@
  */
 int sctp_add_cmd(sctp_cmd_seq_t *seq, sctp_verb_t verb, sctp_arg_t obj);
 
-/* Rewind an sctp_cmd_seq_t to iterate from the start.
- * Return 0 if the rewind fails.
- */
-int sctp_rewind_sequence(sctp_cmd_seq_t *seq);
-
 /* Return the next command structure in an sctp_cmd_seq.
  * Return NULL at the end of the sequence.
  */
 sctp_cmd_t *sctp_next_cmd(sctp_cmd_seq_t *seq);
-
-/* Dispose of a command sequence.  */
-void sctp_free_cmd_seq(sctp_cmd_seq_t *seq);
 
 #endif /* __net_sctp_command_h__ */
 
diff -Nru a/include/net/sctp/constants.h b/include/net/sctp/constants.h
--- a/include/net/sctp/constants.h	2005-03-01 23:38:55 -08:00
+++ b/include/net/sctp/constants.h	2005-03-01 23:38:55 -08:00
@@ -105,9 +105,10 @@
 
 typedef enum {
 	SCTP_EVENT_NO_PENDING_TSN = 0,
+	SCTP_EVENT_ICMP_PROTO_UNREACH,
 } sctp_event_other_t;
 
-#define SCTP_EVENT_OTHER_MAX		SCTP_EVENT_NO_PENDING_TSN
+#define SCTP_EVENT_OTHER_MAX		SCTP_EVENT_ICMP_PROTO_UNREACH
 #define SCTP_NUM_OTHER_TYPES		(SCTP_EVENT_OTHER_MAX + 1)
 
 /* These are primitive requests from the ULP.  */
@@ -155,10 +156,6 @@
 		       		- (unsigned long)(c->chunk_hdr)\
 				- sizeof(sctp_data_chunk_t)))
 
-/* This is a table of printable names of sctp_param_t's.  */
-extern const char *sctp_param_tbl[];
-
-
 #define SCTP_MAX_ERROR_CAUSE  SCTP_ERROR_NONEXIST_IP
 #define SCTP_NUM_ERROR_CAUSE  10
 
@@ -179,6 +176,7 @@
 	SCTP_IERROR_IGNORE_TSN,
 	SCTP_IERROR_NO_DATA,
 	SCTP_IERROR_BAD_STREAM,
+	SCTP_IERROR_BAD_PORTS,
 
 } sctp_ierror_t;
 
diff -Nru a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
--- a/include/net/sctp/sctp.h	2005-03-01 23:38:54 -08:00
+++ b/include/net/sctp/sctp.h	2005-03-01 23:38:54 -08:00
@@ -162,17 +162,9 @@
 int sctp_rcv(struct sk_buff *skb);
 void sctp_v4_err(struct sk_buff *skb, u32 info);
 void sctp_hash_established(struct sctp_association *);
-void __sctp_hash_established(struct sctp_association *);
 void sctp_unhash_established(struct sctp_association *);
-void __sctp_unhash_established(struct sctp_association *);
 void sctp_hash_endpoint(struct sctp_endpoint *);
-void __sctp_hash_endpoint(struct sctp_endpoint *);
 void sctp_unhash_endpoint(struct sctp_endpoint *);
-void __sctp_unhash_endpoint(struct sctp_endpoint *);
-struct sctp_association *__sctp_lookup_association(
-	const union sctp_addr *,
-	const union sctp_addr *,
-	struct sctp_transport **);
 struct sock *sctp_err_lookup(int family, struct sk_buff *,
 			     struct sctphdr *, struct sctp_endpoint **,
 			     struct sctp_association **,
@@ -181,6 +173,10 @@
 			    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);
 
 /*
  *  Section:  Macros, externs, and inlines
@@ -310,8 +306,6 @@
 
 int sctp_v6_init(void);
 void sctp_v6_exit(void);
-void sctp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
-			int type, int code, int offset, __u32 info);
 
 #else /* #ifdef defined(CONFIG_IPV6) */
 
@@ -429,7 +423,7 @@
 }
 
 /* Break down data chunks at this point.  */
-static inline int sctp_frag_point(const struct sctp_opt *sp, int pmtu)
+static inline int sctp_frag_point(const struct sctp_sock *sp, int pmtu)
 {
 	int frag = pmtu;
 
@@ -455,7 +449,8 @@
 #define _sctp_walk_params(pos, chunk, end, member)\
 for (pos.v = chunk->member;\
      pos.v <= (void *)chunk + end - sizeof(sctp_paramhdr_t) &&\
-     pos.v <= (void *)chunk + end - WORD_ROUND(ntohs(pos.p->length)); \
+     pos.v <= (void *)chunk + end - WORD_ROUND(ntohs(pos.p->length)) &&\
+     ntohs(pos.p->length) >= sizeof(sctp_paramhdr_t);\
      pos.v += WORD_ROUND(ntohs(pos.p->length)))
 
 #define sctp_walk_errors(err, chunk_hdr)\
@@ -465,10 +460,9 @@
 for (err = (sctp_errhdr_t *)((void *)chunk_hdr + \
 	    sizeof(sctp_chunkhdr_t));\
      (void *)err <= (void *)chunk_hdr + end - sizeof(sctp_errhdr_t) &&\
-     (void *)err <= (void *)chunk_hdr + end - \
-		    WORD_ROUND(ntohs(err->length));\
-     err = (sctp_errhdr_t *)((void *)err + \
-	    WORD_ROUND(ntohs(err->length))))
+     (void *)err <= (void *)chunk_hdr + end - WORD_ROUND(ntohs(err->length)) &&\
+     ntohs(err->length) >= sizeof(sctp_errhdr_t); \
+     err = (sctp_errhdr_t *)((void *)err + WORD_ROUND(ntohs(err->length))))
 
 #define sctp_walk_fwdtsn(pos, chunk)\
 _sctp_walk_fwdtsn((pos), (chunk), ntohs((chunk)->chunk_hdr->length) - sizeof(struct sctp_fwdtsn_chunk))
@@ -581,29 +575,6 @@
 	h ^= vtag;
 	return (h & (sctp_assoc_hashsize-1));
 }
-
-/* WARNING: Do not change the layout of the members in sctp_sock! */
-struct sctp_sock {
-	struct sock	  sk;
-#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-	struct ipv6_pinfo *pinet6;
-#endif /* CONFIG_IPV6 */
-	struct inet_opt	  inet;
-	struct sctp_opt	  sctp;
-};
-
-#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-struct sctp6_sock {
-	struct sock	  sk;
-	struct ipv6_pinfo *pinet6;
-	struct inet_opt	  inet;
-	struct sctp_opt	  sctp;
-	struct ipv6_pinfo inet6;
-};
-#endif /* CONFIG_IPV6 */
-
-#define sctp_sk(__sk) (&((struct sctp_sock *)__sk)->sctp)
-#define sctp_opt2sk(__sp) &container_of(__sp, struct sctp_sock, sctp)->sk
 
 /* Is a socket of this style? */
 #define sctp_style(sk, style) __sctp_style((sk), (SCTP_SOCKET_##style))
diff -Nru a/include/net/sctp/sm.h b/include/net/sctp/sm.h
--- a/include/net/sctp/sm.h	2005-03-01 23:38:56 -08:00
+++ b/include/net/sctp/sm.h	2005-03-01 23:38:56 -08:00
@@ -128,9 +128,9 @@
 sctp_state_fn_t sctp_sf_do_ecn_cwr;
 sctp_state_fn_t sctp_sf_do_ecne;
 sctp_state_fn_t sctp_sf_ootb;
-sctp_state_fn_t sctp_sf_shut_8_4_5;
 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;
@@ -138,7 +138,6 @@
 sctp_state_fn_t sctp_sf_unk_chunk;
 sctp_state_fn_t sctp_sf_do_8_5_1_E_sa;
 sctp_state_fn_t sctp_sf_cookie_echoed_err;
-sctp_state_fn_t sctp_sf_do_5_2_6_stale;
 sctp_state_fn_t sctp_sf_do_asconf;
 sctp_state_fn_t sctp_sf_do_asconf_ack;
 sctp_state_fn_t sctp_sf_do_9_2_reshutack;
@@ -167,6 +166,7 @@
 sctp_state_fn_t sctp_sf_do_9_2_start_shutdown;
 sctp_state_fn_t sctp_sf_do_9_2_shutdown_ack;
 sctp_state_fn_t sctp_sf_ignore_other;
+sctp_state_fn_t sctp_sf_cookie_wait_icmp_abort;
 
 /* Prototypes for timeout event state functions.  */
 sctp_state_fn_t sctp_sf_do_6_3_3_rtx;
@@ -200,19 +200,10 @@
 struct sctp_chunk *sctp_make_cwr(const struct sctp_association *,
 				 const __u32 lowest_tsn,
 				 const struct sctp_chunk *);
-struct sctp_chunk *sctp_make_datafrag(struct sctp_association *,
-				 const struct sctp_sndrcvinfo *sinfo,
-				 int len, const __u8 *data,
-				 __u8 flags, __u16 ssn);
 struct sctp_chunk * sctp_make_datafrag_empty(struct sctp_association *,
 					const struct sctp_sndrcvinfo *sinfo,
 					int len, const __u8 flags,
 					__u16 ssn);
-struct sctp_chunk *sctp_make_data(struct sctp_association *,
-			     const struct sctp_sndrcvinfo *sinfo,
-			     int len, const __u8 *data);
-struct sctp_chunk *sctp_make_data_empty(struct sctp_association *,
-				   const struct sctp_sndrcvinfo *, int len);
 struct sctp_chunk *sctp_make_ecne(const struct sctp_association *,
 				  const __u32);
 struct sctp_chunk *sctp_make_sack(const struct sctp_association *);
@@ -232,6 +223,10 @@
 struct sctp_chunk *sctp_make_abort_user(const struct sctp_association *,
 				   const struct sctp_chunk *,
 				   const struct msghdr *);
+struct sctp_chunk *sctp_make_abort_violation(const struct sctp_association *,
+				   const struct sctp_chunk *,
+				   const __u8 *,
+				   const size_t );
 struct sctp_chunk *sctp_make_heartbeat(const struct sctp_association *,
 				  const struct sctp_transport *,
 				  const void *payload,
@@ -246,17 +241,12 @@
 				 const void *payload,
 				 size_t paylen);
 
-struct sctp_chunk *sctp_make_asconf(struct sctp_association *asoc,
-				    union sctp_addr *addr,
-				    int vparam_len);
 struct sctp_chunk *sctp_make_asconf_update_ip(struct sctp_association *,
 					      union sctp_addr *,
 					      struct sockaddr *,
 					      int, __u16);
 struct sctp_chunk *sctp_make_asconf_set_prim(struct sctp_association *asoc,
 					     union sctp_addr *addr);
-struct sctp_chunk *sctp_make_asconf_ack(const struct sctp_association *asoc,
-					__u32 serial, int vparam_len);
 struct sctp_chunk *sctp_process_asconf(struct sctp_association *asoc,
 				       struct sctp_chunk *asconf);
 int sctp_process_asconf_ack(struct sctp_association *asoc,
@@ -268,6 +258,8 @@
 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,
@@ -277,70 +269,25 @@
                void *event_arg,
                int gfp);
 
-int sctp_side_effects(sctp_event_t event_type, sctp_subtype_t subtype,
-		      sctp_state_t state,
-                      struct sctp_endpoint *,
-                      struct sctp_association *asoc,
-                      void *event_arg,
-                      sctp_disposition_t status,
-		      sctp_cmd_seq_t *commands,
-                      int gfp);
-
 /* 2nd level prototypes */
-int sctp_cmd_interpreter(sctp_event_t, sctp_subtype_t, sctp_state_t,
-			 struct sctp_endpoint *, struct sctp_association *,
-			 void *event_arg, sctp_disposition_t,
-			 sctp_cmd_seq_t *retval, int gfp);
-
-
-int sctp_gen_sack(struct sctp_association *, int force, sctp_cmd_seq_t *);
 void sctp_generate_t3_rtx_event(unsigned long peer);
 void sctp_generate_heartbeat_event(unsigned long peer);
 
-sctp_sackhdr_t *sctp_sm_pull_sack(struct sctp_chunk *);
-struct sctp_packet *sctp_abort_pkt_new(const struct sctp_endpoint *,
-				       const struct sctp_association *,
-				       struct sctp_chunk *chunk,
-				       const void *payload,
-				       size_t paylen);
-struct sctp_packet *sctp_ootb_pkt_new(const struct sctp_association *,
-				      const struct sctp_chunk *);
 void sctp_ootb_pkt_free(struct sctp_packet *);
 
-struct sctp_cookie_param *
-sctp_pack_cookie(const struct sctp_endpoint *, const struct sctp_association *,
-		 const struct sctp_chunk *, int *cookie_len,
-		 const __u8 *, int addrs_len);
 struct sctp_association *sctp_unpack_cookie(const struct sctp_endpoint *,
 				       const struct sctp_association *,
 				       struct sctp_chunk *, int gfp, int *err,
 				       struct sctp_chunk **err_chk_p);
 int sctp_addip_addr_config(struct sctp_association *, sctp_param_t,
 			   struct sockaddr_storage*, int);
-void sctp_send_stale_cookie_err(const struct sctp_endpoint *ep,
-				const struct sctp_association *asoc,
-				const struct sctp_chunk *chunk,
-				sctp_cmd_seq_t *commands,
-				struct sctp_chunk *err_chunk);
-int sctp_eat_data(const struct sctp_association *asoc,
-		  struct sctp_chunk *chunk,
-		  sctp_cmd_seq_t *commands);
 
 /* 3rd level prototypes */
 __u32 sctp_generate_tag(const struct sctp_endpoint *);
 __u32 sctp_generate_tsn(const struct sctp_endpoint *);
 
 /* Extern declarations for major data structures.  */
-const sctp_sm_table_entry_t *sctp_chunk_event_lookup(sctp_cid_t, sctp_state_t);
-extern const sctp_sm_table_entry_t
-primitive_event_table[SCTP_NUM_PRIMITIVE_TYPES][SCTP_STATE_NUM_STATES];
-extern const sctp_sm_table_entry_t
-other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_STATE_NUM_STATES];
-extern const sctp_sm_table_entry_t
-timeout_event_table[SCTP_NUM_TIMEOUT_TYPES][SCTP_STATE_NUM_STATES];
 extern sctp_timer_event_t *sctp_timer_events[SCTP_NUM_TIMEOUT_TYPES];
-
-/* These are some handy utility macros... */
 
 
 /* Get the size of a DATA chunk payload. */
diff -Nru a/include/net/sctp/structs.h b/include/net/sctp/structs.h
--- a/include/net/sctp/structs.h	2005-03-01 23:39:17 -08:00
+++ b/include/net/sctp/structs.h	2005-03-01 23:39:17 -08:00
@@ -58,6 +58,7 @@
 #include <linux/socket.h>	/* linux/in.h needs this!!    */
 #include <linux/in.h>		/* We get struct sockaddr_in. */
 #include <linux/in6.h>		/* We get struct in6_addr     */
+#include <linux/ipv6.h>
 #include <asm/param.h>		/* We get MAXHOSTNAMELEN.     */
 #include <asm/atomic.h>		/* This gets us atomic counters.  */
 #include <linux/skbuff.h>	/* We need sk_buff_head. */
@@ -84,7 +85,6 @@
 struct sctp_outq;
 struct sctp_bind_addr;
 struct sctp_ulpq;
-struct sctp_opt;
 struct sctp_ep_common;
 struct sctp_ssnmap;
 
@@ -234,7 +234,9 @@
 } sctp_socket_type_t;
 
 /* Per socket SCTP information. */
-struct sctp_opt {
+struct sctp_sock {
+	/* inet_sock has to be the first member of sctp_sock */
+	struct inet_sock inet;
 	/* What kind of a socket is this? */
 	sctp_socket_type_t type;
 
@@ -272,6 +274,22 @@
 	struct sk_buff_head pd_lobby;
 };
 
+static inline struct sctp_sock *sctp_sk(const struct sock *sk)
+{
+       return (struct sctp_sock *)sk;
+}
+
+static inline struct sock *sctp_opt2sk(const struct sctp_sock *sp)
+{
+       return (struct sock *)sp;
+}
+
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+struct sctp6_sock {
+       struct sctp_sock  sctp;
+       struct ipv6_pinfo inet6;
+};
+#endif /* CONFIG_IPV6 */
 
 
 /* This is our APPLICATION-SPECIFIC state cookie.
@@ -322,10 +340,19 @@
 	/* This holds the originating address of the INIT packet.  */
 	union sctp_addr peer_addr;
 
+	/* IG Section 2.35.3 
+	 * Include the source port of the INIT-ACK
+	 */
+	__u16		my_port;
+
 	__u8 prsctp_capable;
 
+	/* Padding for future use */
+	__u8 padding;  		
+
 	__u32 adaption_ind;	
 
+
 	/* This is a shim for my peer's INIT packet, followed by
 	 * a copy of the raw address list of the association.
 	 * The length of the raw address list is saved in the
@@ -406,7 +433,6 @@
 	int malloced;
 };
 
-struct sctp_ssnmap *sctp_ssnmap_init(struct sctp_ssnmap *, __u16, __u16);
 struct sctp_ssnmap *sctp_ssnmap_new(__u16 in, __u16 out, int gfp);
 void sctp_ssnmap_free(struct sctp_ssnmap *map);
 void sctp_ssnmap_clear(struct sctp_ssnmap *map);
@@ -479,12 +505,12 @@
 	int		(*to_addr_param) (const union sctp_addr *,
 					  union sctp_addr_param *); 
 	int		(*addr_valid)	(union sctp_addr *,
-					 struct sctp_opt *);
+					 struct sctp_sock *);
 	sctp_scope_t	(*scope) (union sctp_addr *);
 	void		(*inaddr_any)	(union sctp_addr *, unsigned short);
 	int		(*is_any)	(const union sctp_addr *);
 	int		(*available)	(union sctp_addr *,
-					 struct sctp_opt *);
+					 struct sctp_sock *);
 	int		(*skb_iif)	(const struct sk_buff *sk);
 	int		(*is_ce)	(const struct sk_buff *sk);
 	void		(*seq_dump_addr)(struct seq_file *seq,
@@ -502,16 +528,16 @@
 struct sctp_pf {
 	void (*event_msgname)(struct sctp_ulpevent *, char *, int *);
 	void (*skb_msgname)  (struct sk_buff *, char *, int *);
-	int  (*af_supported) (sa_family_t, struct sctp_opt *);
+	int  (*af_supported) (sa_family_t, struct sctp_sock *);
 	int  (*cmp_addr) (const union sctp_addr *,
 			  const union sctp_addr *,
-			  struct sctp_opt *);
-	int  (*bind_verify) (struct sctp_opt *, union sctp_addr *);
-	int  (*send_verify) (struct sctp_opt *, union sctp_addr *);
-	int  (*supported_addrs)(const struct sctp_opt *, __u16 *);
+			  struct sctp_sock *);
+	int  (*bind_verify) (struct sctp_sock *, union sctp_addr *);
+	int  (*send_verify) (struct sctp_sock *, union sctp_addr *);
+	int  (*supported_addrs)(const struct sctp_sock *, __u16 *);
 	struct sock *(*create_accept_sk) (struct sock *sk,
 					  struct sctp_association *asoc);
-	void (*addr_v4map) (struct sctp_opt *, union sctp_addr *);
+	void (*addr_v4map) (struct sctp_sock *, union sctp_addr *);
 	struct sctp_af *af;
 };
 
@@ -538,12 +564,9 @@
 struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *,
 					    struct sctp_sndrcvinfo *,
 					    struct msghdr *, int len);
-struct sctp_datamsg *sctp_datamsg_new(int gfp);
 void sctp_datamsg_put(struct sctp_datamsg *);
-void sctp_datamsg_hold(struct sctp_datamsg *);
 void sctp_datamsg_free(struct sctp_datamsg *);
 void sctp_datamsg_track(struct sctp_chunk *);
-void sctp_datamsg_assign(struct sctp_datamsg *, struct sctp_chunk *);
 void sctp_chunk_fail(struct sctp_chunk *, int error);
 int sctp_chunk_abandoned(struct sctp_chunk *);
 
@@ -651,8 +674,6 @@
 void sctp_chunk_put(struct sctp_chunk *);
 int sctp_user_addto_chunk(struct sctp_chunk *chunk, int off, int len,
 			  struct iovec *data);
-struct sctp_chunk *sctp_make_chunk(const struct sctp_association *, __u8 type,
-				   __u8 flags, int size);
 void sctp_chunk_free(struct sctp_chunk *);
 void  *sctp_addto_chunk(struct sctp_chunk *, int len, const void *data);
 struct sctp_chunk *sctp_chunkify(struct sk_buff *,
@@ -853,12 +874,6 @@
 	/* Error count : The current error count for this destination.	*/
 	unsigned short error_count;
 
-	/* Error       : Current error threshold for this destination
-	 * Threshold   : i.e. what value marks the destination down if
-	 *	       : errorCount reaches this value.
-	 */
-	unsigned short error_threshold;
-
 	/* This is the max_retrans value for the transport and will
 	 * be initialized to proto.max_retrans.path.  This can be changed
 	 * using SCTP_SET_PEER_ADDR_PARAMS socket option.
@@ -922,15 +937,12 @@
 };
 
 struct sctp_transport *sctp_transport_new(const union sctp_addr *, int);
-struct sctp_transport *sctp_transport_init(struct sctp_transport *,
-					   const union sctp_addr *, int);
 void sctp_transport_set_owner(struct sctp_transport *,
 			      struct sctp_association *);
 void sctp_transport_route(struct sctp_transport *, union sctp_addr *,
-			  struct sctp_opt *);
+			  struct sctp_sock *);
 void sctp_transport_pmtu(struct sctp_transport *);
 void sctp_transport_free(struct sctp_transport *);
-void sctp_transport_destroy(struct sctp_transport *);
 void sctp_transport_reset_timers(struct sctp_transport *);
 void sctp_transport_hold(struct sctp_transport *);
 void sctp_transport_put(struct sctp_transport *);
@@ -961,7 +973,6 @@
 	int malloced;	     /* Is this structure kfree()able?	*/
 };
 
-struct sctp_inq *sctp_inq_new(void);
 void sctp_inq_init(struct sctp_inq *);
 void sctp_inq_free(struct sctp_inq *);
 void sctp_inq_push(struct sctp_inq *, struct sctp_chunk *packet);
@@ -1029,7 +1040,6 @@
 	char malloced;
 };
 
-struct sctp_outq *sctp_outq_new(struct sctp_association *);
 void sctp_outq_init(struct sctp_association *, struct sctp_outq *);
 void sctp_outq_teardown(struct sctp_outq *);
 void sctp_outq_free(struct sctp_outq*);
@@ -1070,7 +1080,6 @@
 	int malloced;	     /* Are we kfree()able?  */
 };
 
-struct sctp_bind_addr *sctp_bind_addr_new(int gfp_mask);
 void sctp_bind_addr_init(struct sctp_bind_addr *, __u16 port);
 void sctp_bind_addr_free(struct sctp_bind_addr *);
 int sctp_bind_addr_copy(struct sctp_bind_addr *dest,
@@ -1080,11 +1089,11 @@
 		       int 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_opt *);
+			 struct sctp_sock *);
 union sctp_addr *sctp_find_unmatch_addr(struct sctp_bind_addr	*bp,
 					const union sctp_addr	*addrs,
 					int			addrcnt,
-					struct sctp_opt		*opt);
+					struct sctp_sock	*opt);
 union sctp_params sctp_bind_addrs_to_raw(const struct sctp_bind_addr *bp,
 					 int *addrs_len, int gfp);
 int sctp_raw_to_bind_addrs(struct sctp_bind_addr *bp, __u8 *raw, int len,
@@ -1220,8 +1229,6 @@
 
 /* These are function signatures for manipulating endpoints.  */
 struct sctp_endpoint *sctp_endpoint_new(struct sock *, int);
-struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *,
-					 struct sock *, int gfp);
 void sctp_endpoint_free(struct sctp_endpoint *);
 void sctp_endpoint_put(struct sctp_endpoint *);
 void sctp_endpoint_hold(struct sctp_endpoint *);
@@ -1243,8 +1250,6 @@
 int sctp_process_init(struct sctp_association *, sctp_cid_t cid,
 		      const union sctp_addr *peer,
 		      sctp_init_chunk_t *init, int gfp);
-int sctp_process_param(struct sctp_association *, union sctp_params param,
-		       const union sctp_addr *from, int gfp);
 __u32 sctp_generate_tag(const struct sctp_endpoint *);
 __u32 sctp_generate_tsn(const struct sctp_endpoint *);
 
@@ -1690,10 +1695,6 @@
 struct sctp_association *
 sctp_association_new(const struct sctp_endpoint *, const struct sock *,
 		     sctp_scope_t scope, int gfp);
-struct sctp_association *
-sctp_association_init(struct sctp_association *, const struct sctp_endpoint *,
-		      const struct sock *, sctp_scope_t scope,
-		      int gfp);
 void sctp_association_free(struct sctp_association *);
 void sctp_association_put(struct sctp_association *);
 void sctp_association_hold(struct sctp_association *);
@@ -1722,7 +1723,6 @@
 		       struct sctp_association *new);
 
 __u32 sctp_association_get_next_tsn(struct sctp_association *);
-__u32 sctp_association_get_tsn_block(struct sctp_association *, int);
 
 void sctp_assoc_sync_pmtu(struct sctp_association *);
 void sctp_assoc_rwnd_increase(struct sctp_association *, unsigned);
@@ -1736,7 +1736,6 @@
 int sctp_cmp_addr_exact(const union sctp_addr *ss1,
 			const union sctp_addr *ss2);
 struct sctp_chunk *sctp_get_ecne_prepend(struct sctp_association *asoc);
-struct sctp_chunk *sctp_get_no_prepend(struct sctp_association *asoc);
 
 /* A convenience structure to parse out SCTP specific CMSGs. */
 typedef struct sctp_cmsgs {
diff -Nru a/include/net/sctp/tsnmap.h b/include/net/sctp/tsnmap.h
--- a/include/net/sctp/tsnmap.h	2005-03-01 23:39:07 -08:00
+++ b/include/net/sctp/tsnmap.h	2005-03-01 23:39:07 -08:00
@@ -120,12 +120,6 @@
 	__u32 start;
 };
 
-/* Create a new tsnmap.  */
-struct sctp_tsnmap *sctp_tsnmap_new(__u16 len, __u32 init_tsn, int gfp);
-
-/* Dispose of a tsnmap.  */
-void sctp_tsnmap_free(struct sctp_tsnmap *);
-
 /* This macro assists in creation of external storage for variable length
  * internal buffers.  We double allocate so the overflow map works.
  */
@@ -209,15 +203,5 @@
 
 /* Is there a gap in the TSN map? */
 int sctp_tsnmap_has_gap(const struct sctp_tsnmap *);
-
-/* Initialize a gap ack block interator from user-provided memory.  */
-void sctp_tsnmap_iter_init(const struct sctp_tsnmap *,
-			   struct sctp_tsnmap_iter *);
-
-/* Get the next gap ack blocks.  We return 0 if there are no more
- * gap ack blocks.
- */
-int sctp_tsnmap_next_gap_ack(const struct sctp_tsnmap *,
-	struct sctp_tsnmap_iter *,__u16 *start, __u16 *end);
 
 #endif /* __sctp_tsnmap_h__ */
diff -Nru a/include/net/sctp/ulpevent.h b/include/net/sctp/ulpevent.h
--- a/include/net/sctp/ulpevent.h	2005-03-01 23:38:52 -08:00
+++ b/include/net/sctp/ulpevent.h	2005-03-01 23:38:52 -08:00
@@ -77,8 +77,6 @@
 	return (struct sctp_ulpevent *)skb->cb;
 }
 
-struct sctp_ulpevent *sctp_ulpevent_new(int size, int flags, int gfp);
-void sctp_ulpevent_init(struct sctp_ulpevent *, int flags);
 void sctp_ulpevent_free(struct sctp_ulpevent *);
 int sctp_ulpevent_is_notification(const struct sctp_ulpevent *);
 void sctp_queue_purge_ulpevents(struct sk_buff_head *list);
diff -Nru a/include/net/sctp/ulpqueue.h b/include/net/sctp/ulpqueue.h
--- a/include/net/sctp/ulpqueue.h	2005-03-01 23:38:54 -08:00
+++ b/include/net/sctp/ulpqueue.h	2005-03-01 23:38:54 -08:00
@@ -57,7 +57,6 @@
 };
 
 /* Prototypes. */
-struct sctp_ulpq *sctp_ulpq_new(struct sctp_association *asoc, int gfp);
 struct sctp_ulpq *sctp_ulpq_init(struct sctp_ulpq *,
 				 struct sctp_association *);
 void sctp_ulpq_free(struct sctp_ulpq *);
diff -Nru a/include/net/snmp.h b/include/net/snmp.h
--- a/include/net/snmp.h	2005-03-01 23:38:55 -08:00
+++ b/include/net/snmp.h	2005-03-01 23:38:55 -08:00
@@ -128,18 +128,18 @@
 #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], _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], _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], _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()], _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()], _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], _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], _smp_processor_id())->mibs[field] += addend)
 
 #endif
diff -Nru a/include/net/sock.h b/include/net/sock.h
--- a/include/net/sock.h	2005-03-01 23:39:08 -08:00
+++ b/include/net/sock.h	2005-03-01 23:39:08 -08:00
@@ -733,11 +733,6 @@
 						     unsigned long size,
 						     int noblock,
 						     int *errcode);
-extern struct sk_buff 		*sock_alloc_send_pskb(struct sock *sk,
-						      unsigned long header_len,
-						      unsigned long data_len,
-						      int noblock,
-						      int *errcode);
 extern void *sock_kmalloc(struct sock *sk, int size, int priority);
 extern void sock_kfree_s(struct sock *sk, void *mem, int size);
 extern void sk_send_sigurg(struct sock *sk);
@@ -795,8 +790,6 @@
  *	Default socket callbacks and setup code
  */
  
-extern void sock_def_destruct(struct sock *);
-
 /* Initialise core socket variables */
 extern void sock_init_data(struct socket *sock, struct sock *sk);
 
diff -Nru a/include/net/tc_act/tc_pedit.h b/include/net/tc_act/tc_pedit.h
--- a/include/net/tc_act/tc_pedit.h	2005-03-01 23:39:07 -08:00
+++ b/include/net/tc_act/tc_pedit.h	2005-03-01 23:39:07 -08:00
@@ -8,7 +8,7 @@
 	tca_gen(pedit);
 	unsigned char           nkeys;
 	unsigned char           flags;
-	struct tc_pedit_key     keys[0];
+	struct tc_pedit_key     *keys;
 };
 
 #endif
diff -Nru a/include/net/tcp.h b/include/net/tcp.h
--- a/include/net/tcp.h	2005-03-01 23:38:52 -08:00
+++ b/include/net/tcp.h	2005-03-01 23:38:52 -08:00
@@ -196,7 +196,7 @@
 	unsigned char		tw_rcv_wscale;
 	__u16			tw_sport;
 	/* Socket demultiplex comparisons on incoming packets. */
-	/* these five are in inet_opt */
+	/* these five are in inet_sock */
 	__u32			tw_daddr
 		__attribute__((aligned(TCP_ADDRCMP_ALIGN_BYTES)));
 	__u32			tw_rcv_saddr;
@@ -315,7 +315,6 @@
 extern atomic_t tcp_orphan_count;
 extern int tcp_tw_count;
 extern void tcp_time_wait(struct sock *sk, int state, int timeo);
-extern void tcp_tw_schedule(struct tcp_tw_bucket *tw, int timeo);
 extern void tcp_tw_deschedule(struct tcp_tw_bucket *tw);
 
 
@@ -506,9 +505,8 @@
 # define TCP_TW_RECYCLE_TICK (12+2-TCP_TW_RECYCLE_SLOTS_LOG)
 #endif
 
-#define BICTCP_1_OVER_BETA	8	/*
-					 * Fast recovery
-					 * multiplicative decrease factor
+#define BICTCP_BETA_SCALE    1024	/* Scale factor beta calculation
+					 * max_cwnd = snd_cwnd * beta
 					 */
 #define BICTCP_MAX_INCREMENT 32		/*
 					 * Limit on the amount of
@@ -607,6 +605,7 @@
 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;
 
@@ -808,17 +807,17 @@
 	TCP_ACK_PUSHED= 4
 };
 
-static inline void tcp_schedule_ack(struct tcp_opt *tp)
+static inline void tcp_schedule_ack(struct tcp_sock *tp)
 {
 	tp->ack.pending |= TCP_ACK_SCHED;
 }
 
-static inline int tcp_ack_scheduled(struct tcp_opt *tp)
+static inline int tcp_ack_scheduled(struct tcp_sock *tp)
 {
 	return tp->ack.pending&TCP_ACK_SCHED;
 }
 
-static __inline__ void tcp_dec_quickack_mode(struct tcp_opt *tp)
+static __inline__ void tcp_dec_quickack_mode(struct tcp_sock *tp)
 {
 	if (tp->ack.quick && --tp->ack.quick == 0) {
 		/* Leaving quickack mode we deflate ATO. */
@@ -826,16 +825,16 @@
 	}
 }
 
-extern void tcp_enter_quickack_mode(struct tcp_opt *tp);
+extern void tcp_enter_quickack_mode(struct tcp_sock *tp);
 
-static __inline__ void tcp_delack_init(struct tcp_opt *tp)
+static __inline__ void tcp_delack_init(struct tcp_sock *tp)
 {
 	memset(&tp->ack, 0, sizeof(tp->ack));
 }
 
-static inline void tcp_clear_options(struct tcp_opt *tp)
+static inline void tcp_clear_options(struct tcp_options_received *rx_opt)
 {
- 	tp->tstamp_ok = tp->sack_ok = tp->wscale_ok = tp->snd_wscale = 0;
+ 	rx_opt->tstamp_ok = rx_opt->sack_ok = rx_opt->wscale_ok = rx_opt->snd_wscale = 0;
 }
 
 enum tcp_tw_status
@@ -860,7 +859,7 @@
 						  struct sk_buff *skb);
 extern void			tcp_enter_frto(struct sock *sk);
 extern void			tcp_enter_loss(struct sock *sk, int how);
-extern void			tcp_clear_retrans(struct tcp_opt *tp);
+extern void			tcp_clear_retrans(struct tcp_sock *tp);
 extern void			tcp_update_metrics(struct sock *sk);
 
 extern void			tcp_close(struct sock *sk, 
@@ -884,7 +883,7 @@
 extern int			tcp_listen_start(struct sock *sk);
 
 extern void			tcp_parse_options(struct sk_buff *skb,
-						  struct tcp_opt *tp,
+						  struct tcp_options_received *opt_rx,
 						  int estab);
 
 /*
@@ -980,7 +979,7 @@
 
 static inline void tcp_clear_xmit_timer(struct sock *sk, int what)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	
 	switch (what) {
 	case TCP_TIME_RETRANS:
@@ -1013,7 +1012,7 @@
  */
 static inline void tcp_reset_xmit_timer(struct sock *sk, int what, unsigned long when)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 
 	if (when > TCP_RTO_MAX) {
 #ifdef TCP_DEBUG
@@ -1053,7 +1052,7 @@
 
 static inline void tcp_initialize_rcv_mss(struct sock *sk)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	unsigned int hint = min(tp->advmss, tp->mss_cache_std);
 
 	hint = min(hint, tp->rcv_wnd/2);
@@ -1063,19 +1062,19 @@
 	tp->ack.rcv_mss = hint;
 }
 
-static __inline__ void __tcp_fast_path_on(struct tcp_opt *tp, u32 snd_wnd)
+static __inline__ void __tcp_fast_path_on(struct tcp_sock *tp, u32 snd_wnd)
 {
 	tp->pred_flags = htonl((tp->tcp_header_len << 26) |
 			       ntohl(TCP_FLAG_ACK) |
 			       snd_wnd);
 }
 
-static __inline__ void tcp_fast_path_on(struct tcp_opt *tp)
+static __inline__ void tcp_fast_path_on(struct tcp_sock *tp)
 {
-	__tcp_fast_path_on(tp, tp->snd_wnd>>tp->snd_wscale);
+	__tcp_fast_path_on(tp, tp->snd_wnd >> tp->rx_opt.snd_wscale);
 }
 
-static inline void tcp_fast_path_check(struct sock *sk, struct tcp_opt *tp)
+static inline void tcp_fast_path_check(struct sock *sk, struct tcp_sock *tp)
 {
 	if (skb_queue_len(&tp->out_of_order_queue) == 0 &&
 	    tp->rcv_wnd &&
@@ -1088,7 +1087,7 @@
  * Rcv_nxt can be after the window if our peer push more data
  * than the offered window.
  */
-static __inline__ u32 tcp_receive_window(const struct tcp_opt *tp)
+static __inline__ u32 tcp_receive_window(const struct tcp_sock *tp)
 {
 	s32 win = tp->rcv_wup + tp->rcv_wnd - tp->rcv_nxt;
 
@@ -1177,63 +1176,31 @@
 	return skb_shinfo(skb)->tso_size;
 }
 
-static inline void tcp_inc_pcount(tcp_pcount_t *count,
-				  const struct sk_buff *skb)
-{
-	count->val += tcp_skb_pcount(skb);
-}
-
-static inline void tcp_inc_pcount_explicit(tcp_pcount_t *count, int amt)
-{
-	count->val += amt;
-}
-
-static inline void tcp_dec_pcount_explicit(tcp_pcount_t *count, int amt)
-{
-	count->val -= amt;
-}
-
-static inline void tcp_dec_pcount(tcp_pcount_t *count, 
-				  const struct sk_buff *skb)
-{
-	count->val -= tcp_skb_pcount(skb);
-}
-
-static inline void tcp_dec_pcount_approx(tcp_pcount_t *count,
+static inline void tcp_dec_pcount_approx(__u32 *count,
 					 const struct sk_buff *skb)
 {
-	if (count->val) {
-		count->val -= tcp_skb_pcount(skb);
-		if ((int)count->val < 0)
-			count->val = 0;
+	if (*count) {
+		*count -= tcp_skb_pcount(skb);
+		if ((int)*count < 0)
+			*count = 0;
 	}
 }
 
-static inline __u32 tcp_get_pcount(const tcp_pcount_t *count)
-{
-	return count->val;
-}
-
-static inline void tcp_set_pcount(tcp_pcount_t *count, __u32 val)
-{
-	count->val = val;
-}
-
 static inline void tcp_packets_out_inc(struct sock *sk, 
-				       struct tcp_opt *tp,
+				       struct tcp_sock *tp,
 				       const struct sk_buff *skb)
 {
-	int orig = tcp_get_pcount(&tp->packets_out);
+	int orig = tp->packets_out;
 
-	tcp_inc_pcount(&tp->packets_out, skb);
+	tp->packets_out += tcp_skb_pcount(skb);
 	if (!orig)
 		tcp_reset_xmit_timer(sk, TCP_TIME_RETRANS, tp->rto);
 }
 
-static inline void tcp_packets_out_dec(struct tcp_opt *tp, 
+static inline void tcp_packets_out_dec(struct tcp_sock *tp, 
 				       const struct sk_buff *skb)
 {
-	tcp_dec_pcount(&tp->packets_out, skb);
+	tp->packets_out -= tcp_skb_pcount(skb);
 }
 
 /* This determines how many packets are "in the network" to the best
@@ -1250,11 +1217,9 @@
  *	"Packets left network, but not honestly ACKed yet" PLUS
  *	"Packets fast retransmitted"
  */
-static __inline__ unsigned int tcp_packets_in_flight(const struct tcp_opt *tp)
+static __inline__ unsigned int tcp_packets_in_flight(const struct tcp_sock *tp)
 {
-	return (tcp_get_pcount(&tp->packets_out) -
-		tcp_get_pcount(&tp->left_out) +
-		tcp_get_pcount(&tp->retrans_out));
+	return (tp->packets_out - tp->left_out + tp->retrans_out);
 }
 
 /*
@@ -1274,20 +1239,21 @@
  *	behave like Reno until low_window is reached,
  *	then increase congestion window slowly
  */
-static inline __u32 tcp_recalc_ssthresh(struct tcp_opt *tp)
+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 * (2*BICTCP_1_OVER_BETA-1))
-				/ (BICTCP_1_OVER_BETA/2);
+			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 - (tp->snd_cwnd/BICTCP_1_OVER_BETA),
-				   2U);
+			return max((tp->snd_cwnd * sysctl_tcp_bic_beta)
+				   / BICTCP_BETA_SCALE, 2U);
 	}
 
 	return max(tp->snd_cwnd >> 1U, 2U);
@@ -1296,7 +1262,7 @@
 /* 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_opt *tp)
+static inline void tcp_vegas_enable(struct tcp_sock *tp)
 {
 	/* There are several situations when we must "re-start" Vegas:
 	 *
@@ -1328,9 +1294,9 @@
 /* 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_opt *tp);
+extern void tcp_ca_init(struct tcp_sock *tp);
 
-static inline void tcp_set_ca_state(struct tcp_opt *tp, u8 ca_state)
+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) 
@@ -1345,7 +1311,7 @@
  * The exception is rate halving phase, when cwnd is decreasing towards
  * ssthresh.
  */
-static inline __u32 tcp_current_ssthresh(struct tcp_opt *tp)
+static inline __u32 tcp_current_ssthresh(struct tcp_sock *tp)
 {
 	if ((1<<tp->ca_state)&(TCPF_CA_CWR|TCPF_CA_Recovery))
 		return tp->snd_ssthresh;
@@ -1355,26 +1321,21 @@
 			    (tp->snd_cwnd >> 2)));
 }
 
-static inline void tcp_sync_left_out(struct tcp_opt *tp)
+static inline void tcp_sync_left_out(struct tcp_sock *tp)
 {
-	if (tp->sack_ok &&
-	    (tcp_get_pcount(&tp->sacked_out) >=
-	     tcp_get_pcount(&tp->packets_out) - tcp_get_pcount(&tp->lost_out)))
-		tcp_set_pcount(&tp->sacked_out,
-			       (tcp_get_pcount(&tp->packets_out) -
-				tcp_get_pcount(&tp->lost_out)));
-	tcp_set_pcount(&tp->left_out,
-		       (tcp_get_pcount(&tp->sacked_out) +
-			tcp_get_pcount(&tp->lost_out)));
+	if (tp->rx_opt.sack_ok &&
+	    (tp->sacked_out >= tp->packets_out - tp->lost_out))
+		tp->sacked_out = tp->packets_out - tp->lost_out;
+	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_opt *tp)
+static inline void tcp_cwnd_validate(struct sock *sk, struct tcp_sock *tp)
 {
-	__u32 packets_out = tcp_get_pcount(&tp->packets_out);
+	__u32 packets_out = tp->packets_out;
 
 	if (packets_out >= tp->snd_cwnd) {
 		/* Network is feed fully. */
@@ -1382,8 +1343,8 @@
 		tp->snd_cwnd_stamp = tcp_time_stamp;
 	} else {
 		/* Network starves. */
-		if (tcp_get_pcount(&tp->packets_out) > tp->snd_cwnd_used)
-			tp->snd_cwnd_used = tcp_get_pcount(&tp->packets_out);
+		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);
@@ -1391,7 +1352,7 @@
 }
 
 /* Set slow start threshould and cwnd not falling to slow start */
-static inline void __tcp_enter_cwr(struct tcp_opt *tp)
+static inline void __tcp_enter_cwr(struct tcp_sock *tp)
 {
 	tp->undo_marker = 0;
 	tp->snd_ssthresh = tcp_recalc_ssthresh(tp);
@@ -1403,7 +1364,7 @@
 	TCP_ECN_queue_cwr(tp);
 }
 
-static inline void tcp_enter_cwr(struct tcp_opt *tp)
+static inline void tcp_enter_cwr(struct tcp_sock *tp)
 {
 	tp->prior_ssthresh = 0;
 	if (tp->ca_state < TCP_CA_CWR) {
@@ -1412,23 +1373,23 @@
 	}
 }
 
-extern __u32 tcp_init_cwnd(struct tcp_opt *tp, struct dst_entry *dst);
+extern __u32 tcp_init_cwnd(struct tcp_sock *tp, struct dst_entry *dst);
 
 /* Slow start with delack produces 3 packets of burst, so that
  * it is safe "de facto".
  */
-static __inline__ __u32 tcp_max_burst(const struct tcp_opt *tp)
+static __inline__ __u32 tcp_max_burst(const struct tcp_sock *tp)
 {
 	return 3;
 }
 
-static __inline__ int tcp_minshall_check(const struct tcp_opt *tp)
+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_opt *tp, int mss, 
+static __inline__ void tcp_minshall_update(struct tcp_sock *tp, int mss, 
 					   const struct sk_buff *skb)
 {
 	if (skb->len < mss)
@@ -1444,14 +1405,14 @@
  */
 
 static __inline__ int
-tcp_nagle_check(const struct tcp_opt *tp, const struct sk_buff *skb, 
+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 &&
-		  tcp_get_pcount(&tp->packets_out) &&
+		  tp->packets_out &&
 		  tcp_minshall_check(tp))));
 }
 
@@ -1460,7 +1421,7 @@
 /* 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(const struct tcp_opt *tp, 
+static __inline__ int tcp_snd_test(const struct tcp_sock *tp, 
 				   struct sk_buff *skb,
 				   unsigned cur_mss, int nonagle)
 {
@@ -1502,9 +1463,9 @@
 		!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_opt *tp)
+static __inline__ void tcp_check_probe_timer(struct sock *sk, struct tcp_sock *tp)
 {
-	if (!tcp_get_pcount(&tp->packets_out) && !tp->pending)
+	if (!tp->packets_out && !tp->pending)
 		tcp_reset_xmit_timer(sk, TCP_TIME_PROBE0, tp->rto);
 }
 
@@ -1519,7 +1480,7 @@
  * The socket must be locked by the caller.
  */
 static __inline__ void __tcp_push_pending_frames(struct sock *sk,
-						 struct tcp_opt *tp,
+						 struct tcp_sock *tp,
 						 unsigned cur_mss,
 						 int nonagle)
 {
@@ -1536,12 +1497,12 @@
 }
 
 static __inline__ void tcp_push_pending_frames(struct sock *sk,
-					       struct tcp_opt *tp)
+					       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_opt *tp)
+static __inline__ int tcp_may_send_now(struct sock *sk, struct tcp_sock *tp)
 {
 	struct sk_buff *skb = sk->sk_send_head;
 
@@ -1550,12 +1511,12 @@
 			     tcp_skb_is_last(sk, skb) ? TCP_NAGLE_PUSH : tp->nonagle));
 }
 
-static __inline__ void tcp_init_wl(struct tcp_opt *tp, u32 ack, u32 seq)
+static __inline__ void tcp_init_wl(struct tcp_sock *tp, u32 ack, u32 seq)
 {
 	tp->snd_wl1 = seq;
 }
 
-static __inline__ void tcp_update_wl(struct tcp_opt *tp, u32 ack, u32 seq)
+static __inline__ void tcp_update_wl(struct tcp_sock *tp, u32 ack, u32 seq)
 {
 	tp->snd_wl1 = seq;
 }
@@ -1586,7 +1547,7 @@
 
 /* Prequeue for VJ style copy to user, combined with checksumming. */
 
-static __inline__ void tcp_prequeue_init(struct tcp_opt *tp)
+static __inline__ void tcp_prequeue_init(struct tcp_sock *tp)
 {
 	tp->ucopy.task = NULL;
 	tp->ucopy.len = 0;
@@ -1604,7 +1565,7 @@
  */
 static __inline__ int tcp_prequeue(struct sock *sk, struct sk_buff *skb)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 
 	if (!sysctl_tcp_low_latency && tp->ucopy.task) {
 		__skb_queue_tail(&tp->ucopy.prequeue, skb);
@@ -1688,39 +1649,39 @@
 		tcp_destroy_sock(sk);
 }
 
-static __inline__ void tcp_sack_reset(struct tcp_opt *tp)
+static __inline__ void tcp_sack_reset(struct tcp_options_received *rx_opt)
 {
-	tp->dsack = 0;
-	tp->eff_sacks = 0;
-	tp->num_sacks = 0;
+	rx_opt->dsack = 0;
+	rx_opt->eff_sacks = 0;
+	rx_opt->num_sacks = 0;
 }
 
-static __inline__ void tcp_build_and_update_options(__u32 *ptr, struct tcp_opt *tp, __u32 tstamp)
+static __inline__ void tcp_build_and_update_options(__u32 *ptr, struct tcp_sock *tp, __u32 tstamp)
 {
-	if (tp->tstamp_ok) {
+	if (tp->rx_opt.tstamp_ok) {
 		*ptr++ = __constant_htonl((TCPOPT_NOP << 24) |
 					  (TCPOPT_NOP << 16) |
 					  (TCPOPT_TIMESTAMP << 8) |
 					  TCPOLEN_TIMESTAMP);
 		*ptr++ = htonl(tstamp);
-		*ptr++ = htonl(tp->ts_recent);
+		*ptr++ = htonl(tp->rx_opt.ts_recent);
 	}
-	if (tp->eff_sacks) {
-		struct tcp_sack_block *sp = tp->dsack ? tp->duplicate_sack : tp->selective_acks;
+	if (tp->rx_opt.eff_sacks) {
+		struct tcp_sack_block *sp = tp->rx_opt.dsack ? tp->duplicate_sack : tp->selective_acks;
 		int this_sack;
 
 		*ptr++ = __constant_htonl((TCPOPT_NOP << 24) |
 					  (TCPOPT_NOP << 16) |
 					  (TCPOPT_SACK << 8) |
 					  (TCPOLEN_SACK_BASE +
-					   (tp->eff_sacks * TCPOLEN_SACK_PERBLOCK)));
-		for(this_sack = 0; this_sack < tp->eff_sacks; this_sack++) {
+					   (tp->rx_opt.eff_sacks * TCPOLEN_SACK_PERBLOCK)));
+		for(this_sack = 0; this_sack < tp->rx_opt.eff_sacks; this_sack++) {
 			*ptr++ = htonl(sp[this_sack].start_seq);
 			*ptr++ = htonl(sp[this_sack].end_seq);
 		}
-		if (tp->dsack) {
-			tp->dsack = 0;
-			tp->eff_sacks--;
+		if (tp->rx_opt.dsack) {
+			tp->rx_opt.dsack = 0;
+			tp->rx_opt.eff_sacks--;
 		}
 	}
 }
@@ -1790,7 +1751,7 @@
 static inline void tcp_acceptq_queue(struct sock *sk, struct open_request *req,
 					 struct sock *child)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 
 	req->sk = child;
 	sk_acceptq_added(sk);
@@ -1849,7 +1810,7 @@
 	return tcp_synq_len(sk) >> tcp_sk(sk)->listen_opt->max_qlen_log;
 }
 
-static inline void tcp_synq_unlink(struct tcp_opt *tp, struct open_request *req,
+static inline void tcp_synq_unlink(struct tcp_sock *tp, struct open_request *req,
 				       struct open_request **prev)
 {
 	write_lock(&tp->syn_wait_lock);
@@ -1866,17 +1827,17 @@
 }
 
 static __inline__ void tcp_openreq_init(struct open_request *req,
-					struct tcp_opt *tp,
+					struct tcp_options_received *rx_opt,
 					struct sk_buff *skb)
 {
 	req->rcv_wnd = 0;		/* So that tcp_send_synack() knows! */
 	req->rcv_isn = TCP_SKB_CB(skb)->seq;
-	req->mss = tp->mss_clamp;
-	req->ts_recent = tp->saw_tstamp ? tp->rcv_tsval : 0;
-	req->tstamp_ok = tp->tstamp_ok;
-	req->sack_ok = tp->sack_ok;
-	req->snd_wscale = tp->snd_wscale;
-	req->wscale_ok = tp->wscale_ok;
+	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;
@@ -1905,17 +1866,17 @@
 		wake_up(&tcp_lhash_wait);
 }
 
-static inline int keepalive_intvl_when(const struct tcp_opt *tp)
+static inline int keepalive_intvl_when(const struct tcp_sock *tp)
 {
 	return tp->keepalive_intvl ? : sysctl_tcp_keepalive_intvl;
 }
 
-static inline int keepalive_time_when(const struct tcp_opt *tp)
+static inline int keepalive_time_when(const struct tcp_sock *tp)
 {
 	return tp->keepalive_time ? : sysctl_tcp_keepalive_time;
 }
 
-static inline int tcp_fin_time(const struct tcp_opt *tp)
+static inline int tcp_fin_time(const struct tcp_sock *tp)
 {
 	int fin_timeout = tp->linger2 ? : sysctl_tcp_fin_timeout;
 
@@ -1925,11 +1886,11 @@
 	return fin_timeout;
 }
 
-static inline int tcp_paws_check(const struct tcp_opt *tp, int rst)
+static inline int tcp_paws_check(const struct tcp_options_received *rx_opt, int rst)
 {
-	if ((s32)(tp->rcv_tsval - tp->ts_recent) >= 0)
+	if ((s32)(rx_opt->rcv_tsval - rx_opt->ts_recent) >= 0)
 		return 0;
-	if (xtime.tv_sec >= tp->ts_recent_stamp + TCP_PAWS_24DAYS)
+	if (xtime.tv_sec >= rx_opt->ts_recent_stamp + TCP_PAWS_24DAYS)
 		return 0;
 
 	/* RST segments are not recommended to carry timestamp,
@@ -1944,7 +1905,7 @@
 
 	   However, we can relax time bounds for RST segments to MSL.
 	 */
-	if (rst && xtime.tv_sec >= tp->ts_recent_stamp + TCP_PAWS_MSL)
+	if (rst && xtime.tv_sec >= rx_opt->ts_recent_stamp + TCP_PAWS_MSL)
 		return 0;
 	return 1;
 }
@@ -1962,7 +1923,7 @@
 
 static inline int tcp_use_frto(const struct sock *sk)
 {
-	const struct tcp_opt *tp = tcp_sk(sk);
+	const struct tcp_sock *tp = tcp_sk(sk);
 	
 	/* F-RTO must be activated in sysctl and there must be some
 	 * unsent new data, and the advertised window should allow
@@ -2014,40 +1975,25 @@
 #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_opt *tp, __u32 rtt_seq)
+static inline void tcp_westwood_update_rtt(struct tcp_sock *tp, __u32 rtt_seq)
 {
         if (tcp_is_westwood(tp))
                 tp->westwood.rtt = rtt_seq;
 }
 
-void __tcp_westwood_fast_bw(struct sock *, struct sk_buff *);
-void __tcp_westwood_slow_bw(struct sock *, struct sk_buff *);
-
-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);
-}
-
-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);
-}
-
-static inline __u32 __tcp_westwood_bw_rttmin(const struct tcp_opt *tp)
+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_opt *tp)
+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_opt *tp)
+static inline int tcp_westwood_ssthresh(struct tcp_sock *tp)
 {
 	__u32 ssthresh = 0;
 
@@ -2060,7 +2006,7 @@
 	return (ssthresh != 0);
 }
 
-static inline int tcp_westwood_cwnd(struct tcp_opt *tp)
+static inline int tcp_westwood_cwnd(struct tcp_sock *tp)
 {
 	__u32 cwnd = 0;
 
diff -Nru a/include/net/tcp_ecn.h b/include/net/tcp_ecn.h
--- a/include/net/tcp_ecn.h	2005-03-01 23:39:08 -08:00
+++ b/include/net/tcp_ecn.h	2005-03-01 23:39:08 -08:00
@@ -9,8 +9,7 @@
 #define TCP_ECN_QUEUE_CWR	2
 #define TCP_ECN_DEMAND_CWR	4
 
-static __inline__ void
-TCP_ECN_queue_cwr(struct tcp_opt *tp)
+static inline void TCP_ECN_queue_cwr(struct tcp_sock *tp)
 {
 	if (tp->ecn_flags&TCP_ECN_OK)
 		tp->ecn_flags |= TCP_ECN_QUEUE_CWR;
@@ -19,16 +18,16 @@
 
 /* Output functions */
 
-static __inline__ void
-TCP_ECN_send_synack(struct tcp_opt *tp, struct sk_buff *skb)
+static inline void TCP_ECN_send_synack(struct tcp_sock *tp,
+				       struct sk_buff *skb)
 {
 	TCP_SKB_CB(skb)->flags &= ~TCPCB_FLAG_CWR;
 	if (!(tp->ecn_flags&TCP_ECN_OK))
 		TCP_SKB_CB(skb)->flags &= ~TCPCB_FLAG_ECE;
 }
 
-static __inline__ void
-TCP_ECN_send_syn(struct sock *sk, struct tcp_opt *tp, struct sk_buff *skb)
+static inline void TCP_ECN_send_syn(struct sock *sk, struct tcp_sock *tp,
+				    struct sk_buff *skb)
 {
 	tp->ecn_flags = 0;
 	if (sysctl_tcp_ecn && !(sk->sk_route_caps & NETIF_F_TSO)) {
@@ -45,8 +44,8 @@
 		th->ece = 1;
 }
 
-static __inline__ void
-TCP_ECN_send(struct sock *sk, struct tcp_opt *tp, struct sk_buff *skb, int tcp_header_len)
+static inline void TCP_ECN_send(struct sock *sk, struct tcp_sock *tp,
+				struct sk_buff *skb, int tcp_header_len)
 {
 	if (tp->ecn_flags & TCP_ECN_OK) {
 		/* Not-retransmitted data segment: set ECT and inject CWR. */
@@ -68,21 +67,18 @@
 
 /* Input functions */
 
-static __inline__ void
-TCP_ECN_accept_cwr(struct tcp_opt *tp, struct sk_buff *skb)
+static inline void TCP_ECN_accept_cwr(struct tcp_sock *tp, struct sk_buff *skb)
 {
 	if (skb->h.th->cwr)
 		tp->ecn_flags &= ~TCP_ECN_DEMAND_CWR;
 }
 
-static __inline__ void
-TCP_ECN_withdraw_cwr(struct tcp_opt *tp)
+static inline void TCP_ECN_withdraw_cwr(struct tcp_sock *tp)
 {
 	tp->ecn_flags &= ~TCP_ECN_DEMAND_CWR;
 }
 
-static __inline__ void
-TCP_ECN_check_ce(struct tcp_opt *tp, struct sk_buff *skb)
+static inline void TCP_ECN_check_ce(struct tcp_sock *tp, struct sk_buff *skb)
 {
 	if (tp->ecn_flags&TCP_ECN_OK) {
 		if (INET_ECN_is_ce(TCP_SKB_CB(skb)->flags))
@@ -95,30 +91,27 @@
 	}
 }
 
-static __inline__ void
-TCP_ECN_rcv_synack(struct tcp_opt *tp, struct tcphdr *th)
+static inline void TCP_ECN_rcv_synack(struct tcp_sock *tp, struct tcphdr *th)
 {
 	if ((tp->ecn_flags&TCP_ECN_OK) && (!th->ece || th->cwr))
 		tp->ecn_flags &= ~TCP_ECN_OK;
 }
 
-static __inline__ void
-TCP_ECN_rcv_syn(struct tcp_opt *tp, struct tcphdr *th)
+static inline void TCP_ECN_rcv_syn(struct tcp_sock *tp, struct tcphdr *th)
 {
 	if ((tp->ecn_flags&TCP_ECN_OK) && (!th->ece || !th->cwr))
 		tp->ecn_flags &= ~TCP_ECN_OK;
 }
 
-static __inline__ int
-TCP_ECN_rcv_ecn_echo(struct tcp_opt *tp, struct tcphdr *th)
+static inline int TCP_ECN_rcv_ecn_echo(struct tcp_sock *tp, struct tcphdr *th)
 {
 	if (th->ece && !th->syn && (tp->ecn_flags&TCP_ECN_OK))
 		return 1;
 	return 0;
 }
 
-static __inline__ void
-TCP_ECN_openreq_child(struct tcp_opt *tp, struct open_request *req)
+static inline void TCP_ECN_openreq_child(struct tcp_sock *tp,
+					 struct open_request *req)
 {
 	tp->ecn_flags = req->ecn_ok ? TCP_ECN_OK : 0;
 }
diff -Nru a/include/net/x25.h b/include/net/x25.h
--- a/include/net/x25.h	2005-03-01 23:39:07 -08:00
+++ b/include/net/x25.h	2005-03-01 23:39:07 -08:00
@@ -162,7 +162,6 @@
 			  struct x25_address *);
 extern int  x25_addr_aton(unsigned char *, struct x25_address *,
 			  struct x25_address *);
-extern unsigned int x25_new_lci(struct x25_neigh *);
 extern struct sock *x25_find_socket(unsigned int, struct x25_neigh *);
 extern void x25_destroy_socket(struct sock *);
 extern int  x25_rx_call_request(struct sk_buff *, struct x25_neigh *, unsigned int);
@@ -171,7 +170,6 @@
 /* x25_dev.c */
 extern void x25_send_frame(struct sk_buff *, struct x25_neigh *);
 extern int  x25_lapb_receive_frame(struct sk_buff *, struct net_device *, struct packet_type *);
-extern int  x25_llc_receive_frame(struct sk_buff *, struct net_device *, struct packet_type *);
 extern void x25_establish_link(struct x25_neigh *);
 extern void x25_terminate_link(struct x25_neigh *);
 
@@ -191,9 +189,6 @@
 extern void x25_link_device_down(struct net_device *);
 extern void x25_link_established(struct x25_neigh *);
 extern void x25_link_terminated(struct x25_neigh *);
-extern void x25_transmit_restart_request(struct x25_neigh *);
-extern void x25_transmit_restart_confirmation(struct x25_neigh *);
-extern void x25_transmit_diagnostic(struct x25_neigh *, unsigned char);
 extern void x25_transmit_clear_request(struct x25_neigh *, unsigned int, unsigned char);
 extern void x25_transmit_link(struct sk_buff *, struct x25_neigh *);
 extern int  x25_subscr_ioctl(unsigned int, void __user *);
@@ -243,6 +238,7 @@
 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 -Nru a/include/net/xfrm.h b/include/net/xfrm.h
--- a/include/net/xfrm.h	2005-03-01 23:39:09 -08:00
+++ b/include/net/xfrm.h	2005-03-01 23:39:09 -08:00
@@ -782,7 +782,6 @@
 
 extern void xfrm_init(void);
 extern void xfrm4_init(void);
-extern void xfrm4_fini(void);
 extern void xfrm6_init(void);
 extern void xfrm6_fini(void);
 extern void xfrm_state_init(void);
@@ -843,7 +842,6 @@
 } 
 #endif
 
-void xfrm_policy_init(void);
 struct xfrm_policy *xfrm_policy_alloc(int gfp);
 extern int xfrm_policy_walk(int (*func)(struct xfrm_policy *, int, int, void*), void *);
 int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl);
@@ -858,12 +856,9 @@
 				  int create, unsigned short family);
 extern void xfrm_policy_flush(void);
 extern int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol);
-extern struct xfrm_policy *xfrm_sk_policy_lookup(struct sock *sk, int dir, struct flowi *fl);
 extern int xfrm_flush_bundles(void);
 
 extern wait_queue_head_t km_waitq;
-extern void km_state_expired(struct xfrm_state *x, int hard);
-extern int km_query(struct xfrm_state *x, struct xfrm_tmpl *, struct xfrm_policy *pol);
 extern int km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, u16 sport);
 extern void km_policy_expired(struct xfrm_policy *pol, int dir, int hard);
 
@@ -875,13 +870,12 @@
 extern int xfrm_count_enc_supported(void);
 extern struct xfrm_algo_desc *xfrm_aalg_get_byidx(unsigned int idx);
 extern struct xfrm_algo_desc *xfrm_ealg_get_byidx(unsigned int idx);
-extern struct xfrm_algo_desc *xfrm_calg_get_byidx(unsigned int idx);
 extern struct xfrm_algo_desc *xfrm_aalg_get_byid(int alg_id);
 extern struct xfrm_algo_desc *xfrm_ealg_get_byid(int alg_id);
 extern struct xfrm_algo_desc *xfrm_calg_get_byid(int alg_id);
-extern struct xfrm_algo_desc *xfrm_aalg_get_byname(char *name);
-extern struct xfrm_algo_desc *xfrm_ealg_get_byname(char *name);
-extern struct xfrm_algo_desc *xfrm_calg_get_byname(char *name);
+extern struct xfrm_algo_desc *xfrm_aalg_get_byname(char *name, int probe);
+extern struct xfrm_algo_desc *xfrm_ealg_get_byname(char *name, int probe);
+extern struct xfrm_algo_desc *xfrm_calg_get_byname(char *name, int probe);
 
 struct crypto_tfm;
 typedef void (icv_update_fn_t)(struct crypto_tfm *, struct scatterlist *, unsigned int);
diff -Nru a/include/pcmcia/bulkmem.h b/include/pcmcia/bulkmem.h
--- a/include/pcmcia/bulkmem.h	2005-03-01 23:38:56 -08:00
+++ b/include/pcmcia/bulkmem.h	2005-03-01 23:38:56 -08:00
@@ -1,33 +1,15 @@
 /*
- * Definitions for bulk memory services
+ * bulkmem.h -- Definitions for bulk memory services
  *
- * bulkmem.h 1.12 2000/06/12 21:55:41
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License
- * at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and
- * limitations under the License. 
+ * 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.
  *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License version 2 (the "GPL"), in which
- * case the provisions of the GPL are applicable instead of the
- * above.  If you wish to allow the use of your version of this file
- * only under the terms of the GPL and not to allow others to use
- * your version of this file under the MPL, indicate your decision by
- * deleting the provisions above and replace them with the notice and
- * other provisions required by the GPL.  If you do not delete the
- * provisions above, a recipient may use your version of this file
- * under either the MPL or the GPL.
- * bulkmem.h 1.3 1995/05/27 04:49:49
+ * (C) 1999		David A. Hinds
  */
 
 #ifndef _LINUX_BULKMEM_H
diff -Nru a/include/pcmcia/ciscode.h b/include/pcmcia/ciscode.h
--- a/include/pcmcia/ciscode.h	2005-03-01 23:39:08 -08:00
+++ b/include/pcmcia/ciscode.h	2005-03-01 23:39:08 -08:00
@@ -1,30 +1,15 @@
 /*
- * ciscode.h 1.56 2002/10/25 06:37:30
+ * ciscode.h -- Definitions for bulk memory services
  *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License
- * at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and
- * limitations under the License. 
+ * 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.
  *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License version 2 (the "GPL"), in
- * which case the provisions of the GPL are applicable instead of the
- * above.  If you wish to allow the use of your version of this file
- * only under the terms of the GPL and not to allow others to use
- * your version of this file under the MPL, indicate your decision by
- * deleting the provisions above and replace them with the notice and
- * other provisions required by the GPL.  If you do not delete the
- * provisions above, a recipient may use your version of this file
- * under either the MPL or the GPL.
+ * (C) 1999		David A. Hinds
  */
 
 #ifndef _LINUX_CISCODE_H
diff -Nru a/include/pcmcia/cisreg.h b/include/pcmcia/cisreg.h
--- a/include/pcmcia/cisreg.h	2005-03-01 23:38:54 -08:00
+++ b/include/pcmcia/cisreg.h	2005-03-01 23:38:54 -08:00
@@ -1,30 +1,15 @@
 /*
- * cisreg.h 1.17 2000/06/12 21:55:41
+ * cisreg.h
  *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License
- * at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and
- * limitations under the License. 
+ * 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.
  *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License version 2 (the "GPL"), in which
- * case the provisions of the GPL are applicable instead of the
- * above.  If you wish to allow the use of your version of this file
- * only under the terms of the GPL and not to allow others to use
- * your version of this file under the MPL, indicate your decision by
- * deleting the provisions above and replace them with the notice and
- * other provisions required by the GPL.  If you do not delete the
- * provisions above, a recipient may use your version of this file
- * under either the MPL or the GPL.
+ * (C) 1999             David A. Hinds
  */
 
 #ifndef _LINUX_CISREG_H
diff -Nru a/include/pcmcia/cistpl.h b/include/pcmcia/cistpl.h
--- a/include/pcmcia/cistpl.h	2005-03-01 23:39:09 -08:00
+++ b/include/pcmcia/cistpl.h	2005-03-01 23:39:09 -08:00
@@ -1,30 +1,15 @@
 /*
- * cistpl.h 1.34 2000/06/19 23:18:12
+ * cistpl.h
  *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License
- * at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and
- * limitations under the License. 
+ * 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.
  *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License version 2 (the "GPL"), in which
- * case the provisions of the GPL are applicable instead of the
- * above.  If you wish to allow the use of your version of this file
- * only under the terms of the GPL and not to allow others to use
- * your version of this file under the MPL, indicate your decision by
- * deleting the provisions above and replace them with the notice and
- * other provisions required by the GPL.  If you do not delete the
- * provisions above, a recipient may use your version of this file
- * under either the MPL or the GPL.
+ * (C) 1999             David A. Hinds
  */
 
 #ifndef _LINUX_CISTPL_H
diff -Nru a/include/pcmcia/cs.h b/include/pcmcia/cs.h
--- a/include/pcmcia/cs.h	2005-03-01 23:38:44 -08:00
+++ b/include/pcmcia/cs.h	2005-03-01 23:38:44 -08:00
@@ -1,30 +1,15 @@
 /*
- * cs.h 1.71 2000/08/29 00:54:20
+ * cs.h
  *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License
- * at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and
- * limitations under the License. 
+ * 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.
  *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License version 2 (the "GPL"), in which
- * case the provisions of the GPL are applicable instead of the
- * above.  If you wish to allow the use of your version of this file
- * only under the terms of the GPL and not to allow others to use
- * your version of this file under the MPL, indicate your decision by
- * deleting the provisions above and replace them with the notice and
- * other provisions required by the GPL.  If you do not delete the
- * provisions above, a recipient may use your version of this file
- * under either the MPL or the GPL.
+ * (C) 1999             David A. Hinds
  */
 
 #ifndef _LINUX_CS_H
@@ -139,7 +124,7 @@
 /* For RegisterClient */
 typedef struct client_reg_t {
     dev_info_t	*dev_info;
-    u_int	Attributes;
+    u_int	Attributes;  /* UNUSED */
     u_int	EventMask;
     int		(*event_handler)(event_t event, int priority,
 				 event_callback_args_t *);
@@ -206,7 +191,7 @@
 typedef struct irq_req_t {
     u_int	Attributes;
     u_int	AssignedIRQ;
-    u_int	IRQInfo1, IRQInfo2;
+    u_int	IRQInfo1, IRQInfo2; /* IRQInfo2 is ignored */
     void	*Handler;
     void	*Instance;
 } irq_req_t;
@@ -294,7 +279,7 @@
 #define WIN_BAR_MASK		0xe000
 #define WIN_BAR_SHIFT		13
 
-/* Attributes for RegisterClient */
+/* Attributes for RegisterClient -- UNUSED -- */
 #define INFO_MASTER_CLIENT	0x01
 #define INFO_IO_CLIENT		0x02
 #define INFO_MTD_CLIENT		0x04
@@ -315,23 +300,9 @@
     int		retcode;
 } error_info_t;
 
-/* Special stuff for binding drivers to sockets */
-typedef struct bind_req_t {
-    struct pcmcia_socket	*Socket;
-    u_char	Function;
-    dev_info_t	*dev_info;
-} bind_req_t;
-
 /* Flag to bind to all functions */
 #define BIND_FN_ALL	0xff
 
-typedef struct mtd_bind_t {
-    struct pcmcia_socket	*Socket;
-    u_int	Attributes;
-    u_int	CardOffset;
-    dev_info_t	*dev_info;
-} mtd_bind_t;
-
 /* Events */
 #define CS_EVENT_PRI_LOW		0
 #define CS_EVENT_PRI_HIGH		1
@@ -420,6 +391,8 @@
     GetFirstWindow, GetNextWindow, GetMemPage
 };
 
+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);
@@ -446,12 +419,8 @@
 int pcmcia_insert_card(struct pcmcia_socket *skt);
 int pcmcia_report_error(client_handle_t handle, error_info_t *err);
 
-#ifdef CONFIG_PCMCIA_OBSOLETE
-int pcmcia_get_first_client(client_handle_t *handle, client_req_t *req);
-int pcmcia_get_next_client(client_handle_t *handle, client_req_t *req);
-int pcmcia_modify_window(window_handle_t win, modwin_t *req);
-int pcmcia_set_event_mask(client_handle_t handle, eventmask_t *mask);
-#endif
+struct pcmcia_socket * pcmcia_get_socket(struct pcmcia_socket *skt);
+void pcmcia_put_socket(struct pcmcia_socket *skt);
 
 #endif /* __KERNEL__ */
 
diff -Nru a/include/pcmcia/cs_types.h b/include/pcmcia/cs_types.h
--- a/include/pcmcia/cs_types.h	2005-03-01 23:38:54 -08:00
+++ b/include/pcmcia/cs_types.h	2005-03-01 23:38:54 -08:00
@@ -1,30 +1,15 @@
 /*
- * cs_types.h 1.18 2000/06/12 21:55:40
+ * cs_types.h
  *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License
- * at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and
- * limitations under the License. 
+ * 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.
  *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License version 2 (the "GPL"), in which
- * case the provisions of the GPL are applicable instead of the
- * above.  If you wish to allow the use of your version of this file
- * only under the terms of the GPL and not to allow others to use
- * your version of this file under the MPL, indicate your decision by
- * deleting the provisions above and replace them with the notice and
- * other provisions required by the GPL.  If you do not delete the
- * provisions above, a recipient may use your version of this file
- * under either the MPL or the GPL.
+ * (C) 1999             David A. Hinds
  */
 
 #ifndef _LINUX_CS_TYPES_H
@@ -37,10 +22,12 @@
 #endif
 
 #if defined(__arm__) || defined(__mips__)
+/* This (ioaddr_t) is exposed to userspace & hence cannot be changed. */
 typedef u_int   ioaddr_t;
 #else
 typedef u_short	ioaddr_t;
 #endif
+typedef unsigned long kio_addr_t;
 
 typedef u_short	socket_t;
 typedef u_int	event_t;
diff -Nru a/include/pcmcia/ds.h b/include/pcmcia/ds.h
--- a/include/pcmcia/ds.h	2005-03-01 23:38:44 -08:00
+++ b/include/pcmcia/ds.h	2005-03-01 23:38:44 -08:00
@@ -1,30 +1,16 @@
 /*
- * ds.h 1.56 2000/06/12 21:55:40
+ * ds.h -- 16-bit PCMCIA core support
  *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License
- * at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and
- * limitations under the License. 
+ * 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.
  *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License version 2 (the "GPL"), in which
- * case the provisions of the GPL are applicable instead of the
- * above.  If you wish to allow the use of your version of this file
- * only under the terms of the GPL and not to allow others to use
- * your version of this file under the MPL, indicate your decision by
- * deleting the provisions above and replace them with the notice and
- * other provisions required by the GPL.  If you do not delete the
- * provisions above, a recipient may use your version of this file
- * under either the MPL or the GPL.
+ * (C) 1999		David A. Hinds
+ * (C) 2003 - 2004	Dominik Brodowski
  */
 
 #ifndef _LINUX_DS_H
@@ -141,10 +127,11 @@
     ((l) && ((l->state & ~DEV_BUSY) == (DEV_CONFIG|DEV_PRESENT)))
 
 
+struct pcmcia_socket;
+
 extern struct bus_type pcmcia_bus_type;
 
 struct pcmcia_driver {
-	int			use_count;
 	dev_link_t		*(*attach)(void);
 	void			(*detach)(dev_link_t *);
 	struct module		*owner;
@@ -154,6 +141,42 @@
 /* driver registration */
 int pcmcia_register_driver(struct pcmcia_driver *driver);
 void pcmcia_unregister_driver(struct pcmcia_driver *driver);
+
+struct pcmcia_device {
+	/* the socket and the device_no [for multifunction devices]
+	   uniquely define a pcmcia_device */
+	struct pcmcia_socket	*socket;
+
+	u8			device_no;
+
+	/* the hardware "function" device; certain subdevices can
+	 * share one hardware "function" device. */
+	u8			func;
+
+	struct list_head	socket_device_list;
+
+	/* 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;
+
+	struct device		dev;
+};
+
+#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)
 
 /* error reporting */
 void cs_error(client_handle_t handle, int func, int ret);
diff -Nru a/include/pcmcia/mem_op.h b/include/pcmcia/mem_op.h
--- a/include/pcmcia/mem_op.h	2005-03-01 23:39:17 -08:00
+++ b/include/pcmcia/mem_op.h	2005-03-01 23:39:17 -08:00
@@ -1,30 +1,15 @@
 /*
- * mem_op.h 1.13 2000/06/12 21:55:40
+ * mem_op.h
  *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License
- * at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and
- * limitations under the License. 
+ * 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.
  *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License version 2 (the "GPL"), in which
- * case the provisions of the GPL are applicable instead of the
- * above.  If you wish to allow the use of your version of this file
- * only under the terms of the GPL and not to allow others to use
- * your version of this file under the MPL, indicate your decision by
- * deleting the provisions above and replace them with the notice and
- * other provisions required by the GPL.  If you do not delete the
- * provisions above, a recipient may use your version of this file
- * under either the MPL or the GPL.
+ * (C) 1999             David A. Hinds
  */
 
 #ifndef _LINUX_MEM_OP_H
@@ -76,67 +61,54 @@
 
 #else /* UNSAFE_MEMCPY */
 
-static inline void copy_from_pc(void *to, const void *from, size_t n)
+static inline void copy_from_pc(void *to, void __iomem *from, size_t n)
 {
-    size_t odd = (n & 1);
-    n -= odd;
-    while (n) {
-	u_short *t = to;
-
-	*t = __raw_readw(from);
-	to = (void *)((long)to + 2);
-	from = (const void *)((long)from + 2);
-	n -= 2;
-    }
-    if (odd)
-	*(u_char *)to = readb(from);
+	__u16 *t = to;
+	__u16 __iomem *f = from;
+	size_t odd = (n & 1);
+	for (n >>= 1; n; n--)
+		*t++ = __raw_readw(f++);
+	if (odd)
+		*(__u8 *)t = readb(f);
 }
 
-static inline void copy_to_pc(void *to, const void *from, size_t n)
+static inline void copy_to_pc(void __iomem *to, const void *from, size_t n)
 {
-    size_t odd = (n & 1);
-    n -= odd;
-    while (n) {
-	__raw_writew(*(u_short *)from, to);
-	to = (void *)((long)to + 2);
-	from = (const void *)((long)from + 2);
-	n -= 2;
-    }
-    if (odd)
-	writeb(*(u_char *)from, to);
+	__u16 __iomem *t = to;
+	const __u16 *f = from;
+	size_t odd = (n & 1);
+	for (n >>= 1; n ; n--)
+		__raw_writew(*f++, t++);
+	if (odd)
+		writeb(*(__u8 *)f, t);
 }
 
-static inline void copy_pc_to_user(void *to, const void *from, size_t n)
+static inline void copy_pc_to_user(void __user *to, void __iomem *from, size_t n)
 {
-    size_t odd = (n & 1);
-    n -= odd;
-    while (n) {
-	put_user(__raw_readw(from), (short *)to);
-	to = (void *)((long)to + 2);
-	from = (const void *)((long)from + 2);
-	n -= 2;
-    }
-    if (odd)
-	put_user(readb(from), (char *)to);
+	__u16 __user *t = to;
+	__u16 __iomem *f = from;
+	size_t odd = (n & 1);
+	for (n >>= 1; n ; n--)
+		put_user(__raw_readw(f++), t++);
+	if (odd)
+		put_user(readb(f), (char __user *)t);
 }
 
-static inline void copy_user_to_pc(void *to, const void *from, size_t n)
+static inline void copy_user_to_pc(void __iomem *to, void __user *from, size_t n)
 {
-    short s;
-    char c;
-    size_t odd = (n & 1);
-    n -= odd;
-    while (n) {
-	get_user(s, (short *)from);
-	__raw_writew(s, to);
-	to = (void *)((long)to + 2);
-	from = (const void *)((long)from + 2);
-	n -= 2;
-    }
-    if (odd) {
-	get_user(c, (char *)from);
-	writeb(c, to);
-    }
+	__u16 __user *f = from;
+	__u16 __iomem *t = to;
+	short s;
+	char c;
+	size_t odd = (n & 1);
+	for (n >>= 1; n; n--) {
+		get_user(s, f++);
+		__raw_writew(s, t++);
+	}
+	if (odd) {
+		get_user(c, (char __user *)f);
+		writeb(c, t);
+	}
 }
 
 #endif /* UNSAFE_MEMCPY */
diff -Nru a/include/pcmcia/ss.h b/include/pcmcia/ss.h
--- a/include/pcmcia/ss.h	2005-03-01 23:39:16 -08:00
+++ b/include/pcmcia/ss.h	2005-03-01 23:39:16 -08:00
@@ -1,30 +1,15 @@
 /*
- * ss.h 1.28 2000/06/12 21:55:40
+ * ss.h
  *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License
- * at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and
- * limitations under the License. 
+ * 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.
  *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License version 2 (the "GPL"), in which
- * case the provisions of the GPL are applicable instead of the
- * above.  If you wish to allow the use of your version of this file
- * only under the terms of the GPL and not to allow others to use
- * your version of this file under the MPL, indicate your decision by
- * deleting the provisions above and replace them with the notice and
- * other provisions required by the GPL.  If you do not delete the
- * provisions above, a recipient may use your version of this file
- * under either the MPL or the GPL.
+ * (C) 1999             David A. Hinds
  */
 
 #ifndef _LINUX_SS_H
@@ -96,7 +81,7 @@
     u_char	map;
     u_char	flags;
     u_short	speed;
-    ioaddr_t	start, stop;
+    kio_addr_t	start, stop;
 } pccard_io_map;
 
 typedef struct pccard_mem_map {
@@ -130,6 +115,28 @@
 	int (*set_mem_map)(struct pcmcia_socket *sock, struct pccard_mem_map *mem);
 };
 
+struct pccard_resource_ops {
+	void	(*validate_mem)		(struct pcmcia_socket *s);
+	int	(*adjust_io_region)	(struct resource *res,
+					 unsigned long r_start,
+					 unsigned long r_end,
+					 struct pcmcia_socket *s);
+	struct resource* (*find_io)	(unsigned long base, int num,
+					 unsigned long align,
+					 struct pcmcia_socket *s);
+	struct resource* (*find_mem)	(unsigned long base, unsigned long num,
+					 unsigned long align, int low,
+					 struct pcmcia_socket *s);
+	int	(*adjust_resource)	(struct pcmcia_socket *s,
+					 adjust_t *adj);
+	int	(*init)			(struct pcmcia_socket *s);
+	void	(*exit)			(struct pcmcia_socket *s);
+};
+/* SS_CAP_STATIC_MAP */
+extern struct pccard_resource_ops pccard_static_ops;
+/* !SS_CAP_STATIC_MAP */
+extern struct pccard_resource_ops pccard_nonstatic_ops;
+
 /*
  *  Calls to set up low-level "Socket Services" drivers
  */
@@ -137,8 +144,8 @@
 
 typedef struct io_window_t {
 	u_int			Attributes;
-	ioaddr_t		BasePort, NumPorts;
-	ioaddr_t		InUse, Config;
+	kio_addr_t		BasePort, NumPorts;
+	kio_addr_t		InUse, Config;
 	struct resource		*res;
 } io_window_t;
 
@@ -158,7 +165,8 @@
 #define MAX_WIN 4
 
 struct config_t;
-struct region_t;
+struct pcmcia_callback;
+
 
 struct pcmcia_socket {
 	struct module			*owner;
@@ -167,7 +175,6 @@
 	u_int				state;
 	u_short				functions;
 	u_short				lock_count;
-	client_handle_t			clients;
 	pccard_mem_map			cis_mem;
 	void __iomem 			*cis_virt;
 	struct config_t			*config;
@@ -177,7 +184,6 @@
 	} irq;
 	io_window_t			io[MAX_IO_WIN];
 	window_t			win[MAX_WIN];
-	struct region_t			*c_region, *a_region;
 	struct list_head		cis_cache;
 	u_int				fake_cis_len;
 	char				*fake_cis;
@@ -193,12 +199,14 @@
 	u_int				features;
 	u_int				irq_mask;
 	u_int				map_size;
-	ioaddr_t			io_offset;
+	kio_addr_t			io_offset;
 	u_char				pci_irq;
 	struct pci_dev *		cb_dev;
 
 	/* socket operations */
 	struct pccard_operations *	ops;
+	struct pccard_resource_ops *	resource_ops;
+	void *				resource_data;
 
 	/* Zoom video behaviour is so chip specific its not worth adding
 	   this to _ops */
@@ -215,6 +223,7 @@
 
 	/* pcmcia (16-bit) */
 	struct pcmcia_bus_socket	*pcmcia;
+	struct pcmcia_callback		*callback;
 
 	/* cardbus (32-bit) */
 #ifdef CONFIG_CARDBUS
diff -Nru a/include/rxrpc/call.h b/include/rxrpc/call.h
--- a/include/rxrpc/call.h	2005-03-01 23:38:52 -08:00
+++ b/include/rxrpc/call.h	2005-03-01 23:38:52 -08:00
@@ -20,9 +20,6 @@
 #define RXRPC_CALL_ACK_WINDOW_SIZE	16
 
 extern unsigned rxrpc_call_rcv_timeout;		/* receive activity timeout (secs) */
-extern unsigned rxrpc_call_acks_timeout;	/* pending ACK (retransmit) timeout (secs) */
-extern unsigned rxrpc_call_dfr_ack_timeout;	/* deferred ACK timeout (secs) */
-extern unsigned short rxrpc_call_max_resend;		/* maximum consecutive resend count */
 
 /* application call state
  * - only state 0 and ffff are reserved, the state is set to 1 after an opid is received
@@ -209,8 +206,6 @@
 				 int alloc_flags,
 				 int dup_data,
 				 size_t *size_sent);
-
-extern int rxrpc_call_flush(struct rxrpc_call *call);
 
 extern void rxrpc_call_handle_error(struct rxrpc_call *conn, int local, int errno);
 
diff -Nru a/include/rxrpc/packet.h b/include/rxrpc/packet.h
--- a/include/rxrpc/packet.h	2005-03-01 23:38:54 -08:00
+++ b/include/rxrpc/packet.h	2005-03-01 23:38:54 -08:00
@@ -124,6 +124,4 @@
 
 } __attribute__((packed));
 
-extern const char *rxrpc_acks[];
-
 #endif /* _LINUX_RXRPC_PACKET_H */
diff -Nru a/include/rxrpc/transport.h b/include/rxrpc/transport.h
--- a/include/rxrpc/transport.h	2005-03-01 23:39:18 -08:00
+++ b/include/rxrpc/transport.h	2005-03-01 23:39:18 -08:00
@@ -103,6 +103,4 @@
 				       struct rxrpc_message *msg,
 				       int error);
 
-extern void rxrpc_clear_transport(struct rxrpc_transport *trans);
-
 #endif /* _LINUX_RXRPC_TRANSPORT_H */
diff -Nru a/include/scsi/scsi_dbg.h b/include/scsi/scsi_dbg.h
--- a/include/scsi/scsi_dbg.h	2005-03-01 23:39:17 -08:00
+++ b/include/scsi/scsi_dbg.h	2005-03-01 23:39:17 -08:00
@@ -8,6 +8,9 @@
 extern void __scsi_print_command(unsigned char *);
 extern void scsi_print_sense(const char *, struct scsi_cmnd *);
 extern void scsi_print_req_sense(const char *, struct scsi_request *);
+extern void __scsi_print_sense(const char *name,
+			       const unsigned char *sense_buffer,
+			       int sense_len);
 extern void scsi_print_driverbyte(int);
 extern void scsi_print_hostbyte(int);
 extern void scsi_print_status(unsigned char);
diff -Nru a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
--- a/include/scsi/scsi_device.h	2005-03-01 23:38:51 -08:00
+++ b/include/scsi/scsi_device.h	2005-03-01 23:38:51 -08:00
@@ -123,8 +123,6 @@
 	struct device		sdev_gendev;
 	struct class_device	sdev_classdev;
 
-	struct class_device	transport_classdev;
-
 	enum scsi_device_state sdev_state;
 	unsigned long		sdev_data[0];
 } __attribute__((aligned(sizeof(unsigned long))));
@@ -133,7 +131,7 @@
 #define	class_to_sdev(d)	\
 	container_of(d, struct scsi_device, sdev_classdev)
 #define transport_class_to_sdev(class_dev) \
-	container_of(class_dev, struct scsi_device, transport_classdev)
+	to_scsi_device(class_dev->dev)
 
 /*
  * scsi_target: representation of a scsi target, for now, this is only
@@ -146,7 +144,6 @@
 	unsigned int		channel;
 	unsigned int		id; /* target id ... replace
 				     * scsi_device.id eventually */
-	struct class_device	transport_classdev;
 	unsigned long		create:1; /* signal that it needs to be added */
 	unsigned long		starget_data[0];
 } __attribute__((aligned(sizeof(unsigned long))));
@@ -157,7 +154,7 @@
 	return to_scsi_target(sdev->sdev_gendev.parent);
 }
 #define transport_class_to_starget(class_dev) \
-	container_of(class_dev, struct scsi_target, transport_classdev)
+	to_scsi_target(class_dev->dev)
 
 extern struct scsi_device *__scsi_add_device(struct Scsi_Host *,
 		uint, uint, uint, void *hostdata);
@@ -172,6 +169,8 @@
 					      uint, uint, uint);
 extern struct scsi_device *__scsi_device_lookup(struct Scsi_Host *,
 						uint, uint, uint);
+extern void starget_for_each_device(struct scsi_target *, void *,
+		     void (*fn)(struct scsi_device *, void *));
 
 /* only exposed to implement shost_for_each_device */
 extern struct scsi_device *__scsi_iterate_devices(struct Scsi_Host *,
@@ -224,6 +223,8 @@
 extern void scsi_target_quiesce(struct scsi_target *);
 extern void scsi_target_resume(struct scsi_target *);
 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 *);
 static inline int scsi_device_online(struct scsi_device *sdev)
 {
 	return sdev->sdev_state != SDEV_OFFLINE;
diff -Nru a/include/scsi/scsi_eh.h b/include/scsi/scsi_eh.h
--- a/include/scsi/scsi_eh.h	2005-03-01 23:39:19 -08:00
+++ b/include/scsi/scsi_eh.h	2005-03-01 23:39:19 -08:00
@@ -44,6 +44,12 @@
 {
 	return ((sshdr->response_code >= 0x70) && (sshdr->response_code & 1));
 }
+
+extern const u8 * scsi_sense_desc_find(const u8 * sense_buffer, int sb_len,
+				       int desc_type);
+
+extern int scsi_get_sense_info_fld(const u8 * sense_buffer, int sb_len,
+				   u64 * info_out);
  
 /*
  * Reset request from external source
diff -Nru a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
--- a/include/scsi/scsi_host.h	2005-03-01 23:38:53 -08:00
+++ b/include/scsi/scsi_host.h	2005-03-01 23:38:53 -08:00
@@ -71,7 +71,18 @@
 	 * Status: OPTIONAL
 	 */
 	int (* ioctl)(struct scsi_device *dev, int cmd, void __user *arg);
-	
+
+
+#ifdef CONFIG_COMPAT
+	/* 
+	 * Compat handler. Handle 32bit ABI.
+	 * When unknown ioctl is passed return -ENOIOCTLCMD.
+	 *
+	 * Status: OPTIONAL
+	 */
+	int (* compat_ioctl)(struct scsi_device *dev, int cmd, void __user *arg);
+#endif
+
 	/*
 	 * The queuecommand function is used to queue up a scsi
 	 * command block to the LLDD.  When the driver finished
@@ -216,13 +227,35 @@
 	void (* slave_destroy)(struct scsi_device *);
 
 	/*
+	 * 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
+	 * was passed in) or an error.  An error should only be
+	 * returned if the requested depth is legal but the driver was
+	 * unable to set it.  If the requested depth is illegal, the
+	 * driver should set and return the closest legal queue depth.
+	 *
+	 */
+	int (* change_queue_depth)(struct scsi_device *, int);
+
+	/*
+	 * fill in this function to allow the changing of tag types
+	 * (this also allows the enabling/disabling of tag command
+	 * queueing).  An error should only be returned if something
+	 * went wrong in the driver while trying to set the tag type.
+	 * If the driver doesn't support the requested tag type, then
+	 * it should set the closest type it does support without
+	 * returning an error.  Returns the actual tag type set.
+	 */
+	int (* change_queue_type)(struct scsi_device *, int);
+
+	/*
 	 * This function determines the bios parameters for a given
 	 * harddisk.  These tend to be numbers that are made up by
 	 * the host adapter.  Parameters:
 	 * size, device, list (heads, sectors, cylinders)
 	 *
-	 * Status: OPTIONAL
-	 */
+	 * Status: OPTIONAL */
 	int (* bios_param)(struct scsi_device *, struct block_device *,
 			sector_t, int []);
 
@@ -506,7 +539,6 @@
 	 * separately
 	 */
 	void *shost_data;
-	struct class_device transport_classdev;
 
 	/*
 	 * We should ensure that this is aligned, both for better performance
@@ -520,13 +552,14 @@
 	container_of(d, struct Scsi_Host, shost_gendev)
 #define		class_to_shost(d)	\
 	container_of(d, struct Scsi_Host, shost_classdev)
-#define		transport_class_to_shost(class_dev) \
-	container_of(class_dev, struct Scsi_Host, transport_classdev)
 
 
 extern struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *, int);
 extern int __must_check scsi_add_host(struct Scsi_Host *, struct device *);
 extern void scsi_scan_host(struct Scsi_Host *);
+extern void scsi_scan_single_target(struct Scsi_Host *, unsigned int,
+	unsigned int);
+extern void scsi_rescan_device(struct device *);
 extern void scsi_remove_host(struct Scsi_Host *);
 extern struct Scsi_Host *scsi_host_get(struct Scsi_Host *);
 extern void scsi_host_put(struct Scsi_Host *t);
@@ -553,6 +586,7 @@
 extern void scsi_unblock_requests(struct Scsi_Host *);
 extern void scsi_block_requests(struct Scsi_Host *);
 
+struct class_container;
 /*
  * These two functions are used to allocate and free a pseudo device
  * which will connect to the host adapter itself rather than any
@@ -562,6 +596,8 @@
  */
 extern void scsi_free_host_dev(struct scsi_device *);
 extern struct scsi_device *scsi_get_host_dev(struct Scsi_Host *);
+int scsi_is_host_device(const struct device *);
+
 
 /* legacy interfaces */
 extern struct Scsi_Host *scsi_register(struct scsi_host_template *, int);
diff -Nru a/include/scsi/scsi_tcq.h b/include/scsi/scsi_tcq.h
--- a/include/scsi/scsi_tcq.h	2005-03-01 23:39:09 -08:00
+++ b/include/scsi/scsi_tcq.h	2005-03-01 23:39:09 -08:00
@@ -13,6 +13,43 @@
 #define SCSI_NO_TAG	(-1)    /* identify no tag in use */
 
 
+
+/**
+ * scsi_get_tag_type - get the type of tag the device supports
+ * @sdev:	the scsi device
+ *
+ * Notes:
+ *	If the drive only supports simple tags, returns MSG_SIMPLE_TAG
+ *	if it supports all tag types, returns MSG_ORDERED_TAG.
+ */
+static inline int scsi_get_tag_type(struct scsi_device *sdev)
+{
+	if (!sdev->tagged_supported)
+		return 0;
+	if (sdev->ordered_tags)
+		return MSG_ORDERED_TAG;
+	if (sdev->simple_tags)
+		return MSG_SIMPLE_TAG;
+	return 0;
+}
+
+static inline void scsi_set_tag_type(struct scsi_device *sdev, int tag)
+{
+	switch (tag) {
+	case MSG_ORDERED_TAG:
+		sdev->ordered_tags = 1;
+		/* fall through */
+	case MSG_SIMPLE_TAG:
+		sdev->simple_tags = 1;
+		break;
+	case 0:
+		/* fall through */
+	default:
+		sdev->ordered_tags = 0;
+		sdev->simple_tags = 0;
+		break;
+	}
+}
 /**
  * scsi_activate_tcq - turn on tag command queueing
  * @SDpnt:	device to turn on TCQ for
@@ -25,11 +62,13 @@
  **/
 static inline void scsi_activate_tcq(struct scsi_device *sdev, int depth)
 {
-        if (sdev->tagged_supported) {
-		if (!blk_queue_tagged(sdev->request_queue))
-			blk_queue_init_tags(sdev->request_queue, depth, NULL);
-		scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, depth);
-        }
+	if (!sdev->tagged_supported)
+		return;
+
+	if (!blk_queue_tagged(sdev->request_queue))
+		blk_queue_init_tags(sdev->request_queue, depth, NULL);
+
+	scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), depth);
 }
 
 /**
@@ -56,9 +95,10 @@
 static inline int scsi_populate_tag_msg(struct scsi_cmnd *cmd, char *msg)
 {
         struct request *req = cmd->request;
+	struct scsi_device *sdev = cmd->device;
 
         if (blk_rq_tagged(req)) {
-		if (req->flags & REQ_HARDBARRIER)
+		if (sdev->ordered_tags && req->flags & REQ_HARDBARRIER)
         	        *msg++ = MSG_ORDERED_TAG;
         	else
         	        *msg++ = MSG_SIMPLE_TAG;
diff -Nru a/include/scsi/scsi_transport.h b/include/scsi/scsi_transport.h
--- a/include/scsi/scsi_transport.h	2005-03-01 23:39:08 -08:00
+++ b/include/scsi/scsi_transport.h	2005-03-01 23:39:08 -08:00
@@ -20,25 +20,16 @@
 #ifndef SCSI_TRANSPORT_H
 #define SCSI_TRANSPORT_H
 
-struct scsi_transport_template {
-	/* The NULL terminated list of transport attributes
-	 * that should be exported.
-	 */
-	struct class_device_attribute **device_attrs;
-	struct class_device_attribute **target_attrs;
-	struct class_device_attribute **host_attrs;
-
+#include <linux/transport_class.h>
 
-	/* The transport class that the device is in */
-	struct class *device_class;
-	struct class *target_class;
-	struct class *host_class;
+struct scsi_transport_template {
+	/* The statistics attached to the host class only */
+	struct attribute_group *host_statistics;
 
-	/* Constructor functions */
-	int (*device_setup)(struct scsi_device *);
-	int (*device_configure)(struct scsi_device *);
-	int (*target_setup)(struct scsi_target *);
-	int (*host_setup)(struct Scsi_Host *);
+	/* the attribute containers */
+	struct attribute_container host_attrs;
+	struct attribute_container target_attrs;
+	struct attribute_container device_attrs;
 
 	/* The size of the specific transport attribute structure (a
 	 * space of this size will be left at the end of the
@@ -47,5 +38,9 @@
 	int	target_size;
 	int	host_size;
 };
+
+#define transport_class_to_shost(tc) \
+	dev_to_shost((tc)->dev)
+
 
 #endif /* SCSI_TRANSPORT_H */
diff -Nru a/include/scsi/scsi_transport_fc.h b/include/scsi/scsi_transport_fc.h
--- a/include/scsi/scsi_transport_fc.h	2005-03-01 23:38:54 -08:00
+++ b/include/scsi/scsi_transport_fc.h	2005-03-01 23:38:54 -08:00
@@ -24,12 +24,102 @@
 
 struct scsi_transport_template;
 
+
+/*
+ * FC Port definitions - Following FC HBAAPI guidelines
+ *
+ * Note: Not all binary values for the different fields match HBAAPI.
+ *  Instead, we use densely packed ordinal values or enums.
+ *  We get away with this as we never present the actual binary values
+ *  externally. For sysfs, we always present the string that describes
+ *  the value. Thus, an admin doesn't need a magic HBAAPI decoder ring
+ *  to understand the values. The HBAAPI user-space library is free to
+ *  convert the strings into the HBAAPI-specified binary values.
+ *
+ * Note: Not all HBAAPI-defined values are contained in the definitions
+ *  below. Those not appropriate to an fc_host (e.g. FCP initiator) have
+ *  been removed.
+ */
+
+/*
+ * fc_port_type: If you alter this, you also need to alter scsi_transport_fc.c
+ * (for the ascii descriptions).
+ */
+enum fc_port_type {
+	FC_PORTTYPE_UNKNOWN,
+	FC_PORTTYPE_OTHER,
+	FC_PORTTYPE_NOTPRESENT,
+	FC_PORTTYPE_NPORT,		/* Attached to FPort */
+	FC_PORTTYPE_NLPORT,		/* (Public) Loop w/ FLPort */
+	FC_PORTTYPE_LPORT,		/* (Private) Loop w/o FLPort */
+	FC_PORTTYPE_PTP,		/* Point to Point w/ another NPort */
+};
+
+/*
+ * fc_port_state: If you alter this, you also need to alter scsi_transport_fc.c
+ * (for the ascii descriptions).
+ */
+enum fc_port_state {
+	FC_PORTSTATE_UNKNOWN,
+	FC_PORTSTATE_ONLINE,
+	FC_PORTSTATE_OFFLINE,		/* User has taken Port Offline */
+	FC_PORTSTATE_BYPASSED,
+	FC_PORTSTATE_DIAGNOSTICS,
+	FC_PORTSTATE_LINKDOWN,
+	FC_PORTSTATE_ERROR,
+	FC_PORTSTATE_LOOPBACK,
+};
+
+
+/* 
+ * FC Classes of Service
+ * Note: values are not enumerated, as they can be "or'd" together
+ * for reporting (e.g. report supported_classes). If you alter this list,
+ * you also need to alter scsi_transport_fc.c (for the ascii descriptions).
+ */
+#define FC_COS_UNSPECIFIED		0
+#define FC_COS_CLASS1			2
+#define FC_COS_CLASS2			4
+#define FC_COS_CLASS3			8
+#define FC_COS_CLASS4			0x10
+#define FC_COS_CLASS6			0x40
+
+/* 
+ * FC Port Speeds
+ * Note: values are not enumerated, as they can be "or'd" together
+ * for reporting (e.g. report supported_speeds). If you alter this list,
+ * you also need to alter scsi_transport_fc.c (for the ascii descriptions).
+ */
+#define FC_PORTSPEED_UNKNOWN		0 /* Unknown - transceiver
+					     incapable of reporting */
+#define FC_PORTSPEED_1GBIT		1
+#define FC_PORTSPEED_2GBIT		2
+#define FC_PORTSPEED_10GBIT		4
+#define FC_PORTSPEED_4GBIT		8
+#define FC_PORTSPEED_NOT_NEGOTIATED	(1 << 15) /* Speed not established */
+
+/*
+ * fc_tgtid_binding_type: If you alter this, you also need to alter
+ * scsi_transport_fc.c (for the ascii descriptions).
+ */
+enum fc_tgtid_binding_type  {
+	FC_TGTID_BIND_BY_WWPN,
+	FC_TGTID_BIND_BY_WWNN,
+	FC_TGTID_BIND_BY_ID,
+};
+
+
+
+/*
+ * FC Remote Port (Target) Attributes
+ */
+
 struct fc_starget_attrs {	/* aka fc_target_attrs */
 	int port_id;
-	uint64_t node_name;
-	uint64_t port_name;
-	uint32_t dev_loss_tmo;	/* Remote Port loss timeout in seconds. */
-	struct timer_list dev_loss_timer;
+	u64 node_name;
+	u64 port_name;
+	u32 dev_loss_tmo;	/* Remote Port loss timeout in seconds. */
+	struct work_struct dev_loss_work;
 };
 
 #define fc_starget_port_id(x) \
@@ -40,18 +130,137 @@
 	(((struct fc_starget_attrs *)&(x)->starget_data)->port_name)
 #define fc_starget_dev_loss_tmo(x) \
 	(((struct fc_starget_attrs *)&(x)->starget_data)->dev_loss_tmo)
-#define fc_starget_dev_loss_timer(x) \
-	(((struct fc_starget_attrs *)&(x)->starget_data)->dev_loss_timer)
+#define fc_starget_dev_loss_work(x) \
+	(((struct fc_starget_attrs *)&(x)->starget_data)->dev_loss_work)
+
+
+/*
+ * FC Local Port (Host) Statistics
+ */
+
+/* FC Statistics - Following FC HBAAPI v2.0 guidelines */
+struct fc_host_statistics {
+	/* port statistics */
+	u64 seconds_since_last_reset;
+	u64 tx_frames;
+	u64 tx_words;
+	u64 rx_frames;
+	u64 rx_words;
+	u64 lip_count;
+	u64 nos_count;
+	u64 error_frames;
+	u64 dumped_frames;
+	u64 link_failure_count;
+	u64 loss_of_sync_count;
+	u64 loss_of_signal_count;
+	u64 prim_seq_protocol_err_count;
+	u64 invalid_tx_word_count;
+	u64 invalid_crc_count;
+	
+	/* fc4 statistics  (only FCP supported currently) */
+	u64 fcp_input_requests;
+	u64 fcp_output_requests;
+	u64 fcp_control_requests;
+	u64 fcp_input_megabytes;
+	u64 fcp_output_megabytes;
+};
+
+
+/*
+ * FC Local Port (Host) Attributes
+ *
+ * Attributes are based on HBAAPI V2.0 definitions.
+ * Note: OSDeviceName is determined by user-space library
+ *
+ * Fixed attributes are not expected to change. The driver is
+ * expected to set these values after successfully calling scsi_add_host().
+ * The transport fully manages all get functions w/o driver interaction.
+ *
+ * Dynamic attributes are expected to change. The driver participates
+ * in all get/set operations via functions provided by the driver.
+ *
+ * Private attributes are transport-managed values. They are fully
+ * managed by the transport w/o driver interaction.
+ */
+
+#define FC_FC4_LIST_SIZE		32
+#define FC_SYMBOLIC_NAME_SIZE		256
+#define FC_VERSION_STRING_SIZE		64
+#define FC_SERIAL_NUMBER_SIZE		80
 
 struct fc_host_attrs {
-	uint32_t link_down_tmo;	/* Link Down timeout in seconds. */
-	struct timer_list link_down_timer;
+	/* Fixed Attributes */
+	u64 node_name;
+	u64 port_name;
+	u32 supported_classes;
+	u8  supported_fc4s[FC_FC4_LIST_SIZE];
+	char symbolic_name[FC_SYMBOLIC_NAME_SIZE];
+	u32 supported_speeds;
+	u32 maxframe_size;
+	char hardware_version[FC_VERSION_STRING_SIZE];
+	char firmware_version[FC_VERSION_STRING_SIZE];
+	char serial_number[FC_SERIAL_NUMBER_SIZE];
+	char opt_rom_version[FC_VERSION_STRING_SIZE];
+	char driver_version[FC_VERSION_STRING_SIZE];
+
+	/* Dynamic Attributes */
+	u32 port_id;
+	enum fc_port_type port_type;
+	enum fc_port_state port_state;
+	u8  active_fc4s[FC_FC4_LIST_SIZE];
+	u32 speed;
+	u64 fabric_name;
+	u32 link_down_tmo;	/* Link Down timeout in seconds. */
+
+	/* Private (Transport-managed) Attributes */
+	enum fc_tgtid_binding_type  tgtid_bind_type;
+
+	/* internal data */
+	struct work_struct link_down_work;
 };
 
+#define fc_host_node_name(x) \
+	(((struct fc_host_attrs *)(x)->shost_data)->node_name)
+#define fc_host_port_name(x)	\
+	(((struct fc_host_attrs *)(x)->shost_data)->port_name)
+#define fc_host_supported_classes(x)	\
+	(((struct fc_host_attrs *)(x)->shost_data)->supported_classes)
+#define fc_host_supported_fc4s(x)	\
+	(((struct fc_host_attrs *)(x)->shost_data)->supported_fc4s)
+#define fc_host_symbolic_name(x)	\
+	(((struct fc_host_attrs *)(x)->shost_data)->symbolic_name)
+#define fc_host_supported_speeds(x)	\
+	(((struct fc_host_attrs *)(x)->shost_data)->supported_speeds)
+#define fc_host_maxframe_size(x)	\
+	(((struct fc_host_attrs *)(x)->shost_data)->maxframe_size)
+#define fc_host_hardware_version(x)	\
+	(((struct fc_host_attrs *)(x)->shost_data)->hardware_version)
+#define fc_host_firmware_version(x)	\
+	(((struct fc_host_attrs *)(x)->shost_data)->firmware_version)
+#define fc_host_serial_number(x)	\
+	(((struct fc_host_attrs *)(x)->shost_data)->serial_number)
+#define fc_host_opt_rom_version(x)	\
+	(((struct fc_host_attrs *)(x)->shost_data)->opt_rom_version)
+#define fc_host_driver_version(x)	\
+	(((struct fc_host_attrs *)(x)->shost_data)->driver_version)
+#define fc_host_port_id(x)	\
+	(((struct fc_host_attrs *)(x)->shost_data)->port_id)
+#define fc_host_port_type(x)	\
+	(((struct fc_host_attrs *)(x)->shost_data)->port_type)
+#define fc_host_port_state(x)	\
+	(((struct fc_host_attrs *)(x)->shost_data)->port_state)
+#define fc_host_active_fc4s(x)	\
+	(((struct fc_host_attrs *)(x)->shost_data)->active_fc4s)
+#define fc_host_speed(x)	\
+	(((struct fc_host_attrs *)(x)->shost_data)->speed)
+#define fc_host_fabric_name(x)	\
+	(((struct fc_host_attrs *)(x)->shost_data)->fabric_name)
 #define fc_host_link_down_tmo(x) \
 	(((struct fc_host_attrs *)(x)->shost_data)->link_down_tmo)
-#define fc_host_link_down_timer(x) \
-	(((struct fc_host_attrs *)(x)->shost_data)->link_down_timer)
+#define fc_host_tgtid_bind_type(x) \
+	(((struct fc_host_attrs *)(x)->shost_data)->tgtid_bind_type)
+#define fc_host_link_down_work(x) \
+	(((struct fc_host_attrs *)(x)->shost_data)->link_down_work)
 
 
 /* The functions by which the transport class and the driver communicate */
@@ -60,10 +269,19 @@
 	void	(*get_starget_node_name)(struct scsi_target *);
 	void	(*get_starget_port_name)(struct scsi_target *);
 	void    (*get_starget_dev_loss_tmo)(struct scsi_target *);
-	void	(*set_starget_dev_loss_tmo)(struct scsi_target *, uint32_t);
+	void	(*set_starget_dev_loss_tmo)(struct scsi_target *, u32);
 
+	void 	(*get_host_port_id)(struct Scsi_Host *);
+	void	(*get_host_port_type)(struct Scsi_Host *);
+	void	(*get_host_port_state)(struct Scsi_Host *);
+	void	(*get_host_active_fc4s)(struct Scsi_Host *);
+	void	(*get_host_speed)(struct Scsi_Host *);
+	void	(*get_host_fabric_name)(struct Scsi_Host *);
 	void    (*get_host_link_down_tmo)(struct Scsi_Host *);
-	void	(*set_host_link_down_tmo)(struct Scsi_Host *, uint32_t);
+	void	(*set_host_link_down_tmo)(struct Scsi_Host *, u32);
+
+	struct fc_host_statistics * (*get_fc_host_stats)(struct Scsi_Host *);
+	void	(*reset_fc_host_stats)(struct Scsi_Host *);
 
 	/* 
 	 * The driver sets these to tell the transport class it
@@ -76,10 +294,29 @@
 	unsigned long	show_starget_port_name:1;
 	unsigned long   show_starget_dev_loss_tmo:1;
 
+	/* host fixed attributes */
+	unsigned long	show_host_node_name:1;
+	unsigned long	show_host_port_name:1;
+	unsigned long	show_host_supported_classes:1;
+	unsigned long	show_host_supported_fc4s:1;
+	unsigned long	show_host_symbolic_name:1;
+	unsigned long	show_host_supported_speeds:1;
+	unsigned long	show_host_maxframe_size:1;
+	unsigned long	show_host_hardware_version:1;
+	unsigned long	show_host_firmware_version:1;
+	unsigned long	show_host_serial_number:1;
+	unsigned long	show_host_opt_rom_version:1;
+	unsigned long	show_host_driver_version:1;
+	/* host dynamic attributes */
+	unsigned long	show_host_port_id:1;
+	unsigned long	show_host_port_type:1;
+	unsigned long	show_host_port_state:1;
+	unsigned long	show_host_active_fc4s:1;
+	unsigned long	show_host_speed:1;
+	unsigned long	show_host_fabric_name:1;
 	unsigned long   show_host_link_down_tmo:1;
-
-	/* Private Attributes */
 };
+
 
 struct scsi_transport_template *fc_attach_transport(struct fc_function_template *);
 void fc_release_transport(struct scsi_transport_template *);
diff -Nru a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/scsi/scsi_transport_iscsi.h	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,178 @@
+/* 
+ * iSCSI transport class definitions
+ *
+ * Copyright (C) IBM Corporation, 2004
+ * Copyright (C) Mike Christie, 2004
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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 SCSI_TRANSPORT_ISCSI_H
+#define SCSI_TRANSPORT_ISCSI_H
+
+#include <linux/config.h>
+#include <linux/in6.h>
+#include <linux/in.h>
+
+struct scsi_transport_template;
+
+struct iscsi_class_session {
+	uint8_t isid[6];
+	uint16_t tsih;
+	int header_digest;		/* 1 CRC32, 0 None */
+	int data_digest;		/* 1 CRC32, 0 None */
+	uint16_t tpgt;
+	union {
+		struct in6_addr sin6_addr;
+		struct in_addr sin_addr;
+	} u;
+	sa_family_t addr_type;		/* must be AF_INET or AF_INET6 */
+	uint16_t port;			/* must be in network byte order */
+	int initial_r2t;		/* 1 Yes, 0 No */
+	int immediate_data;		/* 1 Yes, 0 No */
+	uint32_t max_recv_data_segment_len;
+	uint32_t max_burst_len;
+	uint32_t first_burst_len;
+	uint16_t def_time2wait;
+	uint16_t def_time2retain;
+	uint16_t max_outstanding_r2t;
+	int data_pdu_in_order;		/* 1 Yes, 0 No */
+	int data_sequence_in_order;	/* 1 Yes, 0 No */
+	int erl;
+};
+
+/*
+ * accessor macros
+ */
+#define iscsi_isid(x) \
+	(((struct iscsi_class_session *)&(x)->starget_data)->isid)
+#define iscsi_tsih(x) \
+	(((struct iscsi_class_session *)&(x)->starget_data)->tsih)
+#define iscsi_header_digest(x) \
+	(((struct iscsi_class_session *)&(x)->starget_data)->header_digest)
+#define iscsi_data_digest(x) \
+	(((struct iscsi_class_session *)&(x)->starget_data)->data_digest)
+#define iscsi_port(x) \
+	(((struct iscsi_class_session *)&(x)->starget_data)->port)
+#define iscsi_addr_type(x) \
+	(((struct iscsi_class_session *)&(x)->starget_data)->addr_type)
+#define iscsi_sin_addr(x) \
+	(((struct iscsi_class_session *)&(x)->starget_data)->u.sin_addr)
+#define iscsi_sin6_addr(x) \
+	(((struct iscsi_class_session *)&(x)->starget_data)->u.sin6_addr)
+#define iscsi_tpgt(x) \
+	(((struct iscsi_class_session *)&(x)->starget_data)->tpgt)
+#define iscsi_initial_r2t(x) \
+	(((struct iscsi_class_session *)&(x)->starget_data)->initial_r2t)
+#define iscsi_immediate_data(x) \
+	(((struct iscsi_class_session *)&(x)->starget_data)->immediate_data)
+#define iscsi_max_recv_data_segment_len(x) \
+	(((struct iscsi_class_session *)&(x)->starget_data)->max_recv_data_segment_len)
+#define iscsi_max_burst_len(x) \
+	(((struct iscsi_class_session *)&(x)->starget_data)->max_burst_len)
+#define iscsi_first_burst_len(x) \
+	(((struct iscsi_class_session *)&(x)->starget_data)->first_burst_len)
+#define iscsi_def_time2wait(x) \
+	(((struct iscsi_class_session *)&(x)->starget_data)->def_time2wait)
+#define iscsi_def_time2retain(x) \
+	(((struct iscsi_class_session *)&(x)->starget_data)->def_time2retain)
+#define iscsi_max_outstanding_r2t(x) \
+	(((struct iscsi_class_session *)&(x)->starget_data)->max_outstanding_r2t)
+#define iscsi_data_pdu_in_order(x) \
+	(((struct iscsi_class_session *)&(x)->starget_data)->data_pdu_in_order)
+#define iscsi_data_sequence_in_order(x) \
+	(((struct iscsi_class_session *)&(x)->starget_data)->data_sequence_in_order)
+#define iscsi_erl(x) \
+	(((struct iscsi_class_session *)&(x)->starget_data)->erl)
+
+/*
+ * The functions by which the transport class and the driver communicate
+ */
+struct iscsi_function_template {
+	/*
+	 * target attrs
+	 */
+	void (*get_isid)(struct scsi_target *);
+	void (*get_tsih)(struct scsi_target *);
+	void (*get_header_digest)(struct scsi_target *);
+	void (*get_data_digest)(struct scsi_target *);
+	void (*get_port)(struct scsi_target *);
+	void (*get_tpgt)(struct scsi_target *);
+	/*
+	 * In get_ip_address the lld must set the address and
+	 * the address type
+	 */
+	void (*get_ip_address)(struct scsi_target *);
+	/*
+	 * The lld should snprintf the name or alias to the buffer
+	 */
+	ssize_t (*get_target_name)(struct scsi_target *, char *, ssize_t);
+	ssize_t (*get_target_alias)(struct scsi_target *, char *, ssize_t);
+	void (*get_initial_r2t)(struct scsi_target *);
+	void (*get_immediate_data)(struct scsi_target *);
+	void (*get_max_recv_data_segment_len)(struct scsi_target *);
+	void (*get_max_burst_len)(struct scsi_target *);
+	void (*get_first_burst_len)(struct scsi_target *);
+	void (*get_def_time2wait)(struct scsi_target *);
+	void (*get_def_time2retain)(struct scsi_target *);
+	void (*get_max_outstanding_r2t)(struct scsi_target *);
+	void (*get_data_pdu_in_order)(struct scsi_target *);
+	void (*get_data_sequence_in_order)(struct scsi_target *);
+	void (*get_erl)(struct scsi_target *);
+
+	/*
+	 * host atts
+	 */
+
+	/*
+	 * The lld should snprintf the name or alias to the buffer
+	 */
+	ssize_t (*get_initiator_alias)(struct Scsi_Host *, char *, ssize_t);
+	ssize_t (*get_initiator_name)(struct Scsi_Host *, char *, ssize_t);
+	/*
+	 * The driver sets these to tell the transport class it
+	 * wants the attributes displayed in sysfs.  If the show_ flag
+	 * is not set, the attribute will be private to the transport
+	 * class. We could probably just test if a get_ fn was set
+	 * since we only use the values for sysfs but this is how
+	 * fc does it too.
+	 */
+	unsigned long show_isid:1;
+	unsigned long show_tsih:1;
+	unsigned long show_header_digest:1;
+	unsigned long show_data_digest:1;
+	unsigned long show_port:1;
+	unsigned long show_tpgt:1;
+	unsigned long show_ip_address:1;
+	unsigned long show_target_name:1;
+	unsigned long show_target_alias:1;
+	unsigned long show_initial_r2t:1;
+	unsigned long show_immediate_data:1;
+	unsigned long show_max_recv_data_segment_len:1;
+	unsigned long show_max_burst_len:1;
+	unsigned long show_first_burst_len:1;
+	unsigned long show_def_time2wait:1;
+	unsigned long show_def_time2retain:1;
+	unsigned long show_max_outstanding_r2t:1;
+	unsigned long show_data_pdu_in_order:1;
+	unsigned long show_data_sequence_in_order:1;
+	unsigned long show_erl:1;
+	unsigned long show_initiator_name:1;
+	unsigned long show_initiator_alias:1;
+};
+
+struct scsi_transport_template *iscsi_attach_transport(struct iscsi_function_template *);
+void iscsi_release_transport(struct scsi_transport_template *);
+
+#endif
diff -Nru a/include/scsi/scsi_transport_spi.h b/include/scsi/scsi_transport_spi.h
--- a/include/scsi/scsi_transport_spi.h	2005-03-01 23:38:53 -08:00
+++ b/include/scsi/scsi_transport_spi.h	2005-03-01 23:38:53 -08:00
@@ -21,6 +21,7 @@
 #define SCSI_TRANSPORT_SPI_H
 
 #include <linux/config.h>
+#include <linux/transport_class.h>
 
 struct scsi_transport_template;
 
diff -Nru a/include/sound/ac97_codec.h b/include/sound/ac97_codec.h
--- a/include/sound/ac97_codec.h	2005-03-01 23:38:58 -08:00
+++ b/include/sound/ac97_codec.h	2005-03-01 23:38:58 -08:00
@@ -364,6 +364,8 @@
 #define AC97_CX_SPDIF		(1<<3)	/* Conexant's spdif interface */
 #define AC97_STEREO_MUTES	(1<<4)	/* has stereo mute bits */
 #define AC97_DOUBLE_RATE	(1<<5)	/* supports double rate playback */
+#define AC97_HAS_NO_MASTER_VOL	(1<<6)	/* no Master volume */
+#define AC97_HAS_NO_PCM_VOL	(1<<7)	/* no PCM volume */
 
 /* rates indexes */
 #define AC97_RATES_FRONT_DAC	0
@@ -423,6 +425,10 @@
 	int (*build_specific) (ac97_t *ac97);
 	int (*build_spdif) (ac97_t *ac97);
 	int (*build_post_spdif) (ac97_t *ac97);
+#ifdef CONFIG_PM
+	void (*suspend) (ac97_t *ac97);
+	void (*resume) (ac97_t *ac97);
+#endif
 };
 
 struct _snd_ac97_bus_ops {
@@ -477,8 +483,8 @@
 	snd_info_entry_t *proc_regs;
 	unsigned short subsystem_vendor;
 	unsigned short subsystem_device;
-	spinlock_t reg_lock;
-	struct semaphore mutex;	/* mutex for AD18xx multi-codecs and paging (2.3) */
+	struct semaphore reg_mutex;
+	struct semaphore page_mutex;	/* mutex for AD18xx multi-codecs and paging (2.3) */
 	unsigned short num;	/* number of codec: 0 = primary, 1 = secondary */
 	unsigned short addr;	/* physical address of codec [0-3] */
 	unsigned int id;	/* identification of codec */
@@ -551,6 +557,7 @@
 	AC97_TUNE_AD_SHARING,	/* for AD1985, turn on OMS bit and use headphone */
 	AC97_TUNE_ALC_JACK,	/* for Realtek, enable JACK detection */
 	AC97_TUNE_INV_EAPD,	/* inverted EAPD implementation */
+	AC97_TUNE_MUTE_LED,	/* EAPD bit works as mute LED */
 };
 
 struct ac97_quirk {
@@ -562,7 +569,7 @@
 	int type;		/* quirk type above */
 };
 
-int snd_ac97_tune_hardware(ac97_t *ac97, struct ac97_quirk *quirk, int override);
+int snd_ac97_tune_hardware(ac97_t *ac97, struct ac97_quirk *quirk, const char *override);
 int snd_ac97_set_rate(ac97_t *ac97, int reg, unsigned int rate);
 
 int snd_ac97_pcm_assign(ac97_bus_t *ac97,
diff -Nru a/include/sound/ad1848.h b/include/sound/ad1848.h
--- a/include/sound/ad1848.h	2005-03-01 23:38:54 -08:00
+++ b/include/sound/ad1848.h	2005-03-01 23:38:54 -08:00
@@ -157,10 +157,6 @@
 /* exported functions */
 
 void snd_ad1848_out(ad1848_t *chip, unsigned char reg, unsigned char value);
-void snd_ad1848_dout(ad1848_t *chip, unsigned char reg, unsigned char value);
-unsigned char snd_ad1848_in(ad1848_t *chip, unsigned char reg);
-void snd_ad1848_mce_up(ad1848_t *chip);
-void snd_ad1848_mce_down(ad1848_t *chip);
 
 int snd_ad1848_create(snd_card_t * card,
 		      unsigned long port,
@@ -171,7 +167,6 @@
 int snd_ad1848_pcm(ad1848_t * chip, int device, snd_pcm_t **rpcm);
 const snd_pcm_ops_t *snd_ad1848_get_pcm_ops(int direction);
 int snd_ad1848_mixer(ad1848_t * chip);
-irqreturn_t snd_ad1848_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 
 /* exported mixer stuffs */
 enum { AD1848_MIX_SINGLE, AD1848_MIX_DOUBLE, AD1848_MIX_CAPTURE };
@@ -207,9 +202,5 @@
 {
 	return snd_ad1848_add_ctl(chip, c->name, c->index, c->type, c->private_value);
 }
-
-#ifdef CONFIG_SND_DEBUG
-void snd_ad1848_debug(ad1848_t *chip);
-#endif
 
 #endif /* __SOUND_AD1848_H */
diff -Nru a/include/sound/ainstr_fm.h b/include/sound/ainstr_fm.h
--- a/include/sound/ainstr_fm.h	2005-03-01 23:38:57 -08:00
+++ b/include/sound/ainstr_fm.h	2005-03-01 23:38:57 -08:00
@@ -122,8 +122,6 @@
 
 #include "seq_instr.h"
 
-extern char *snd_seq_fm_id;
-
 int snd_seq_fm_init(snd_seq_kinstr_ops_t * ops,
 		    snd_seq_kinstr_ops_t * next);
 
diff -Nru a/include/sound/ainstr_gf1.h b/include/sound/ainstr_gf1.h
--- a/include/sound/ainstr_gf1.h	2005-03-01 23:39:08 -08:00
+++ b/include/sound/ainstr_gf1.h	2005-03-01 23:39:08 -08:00
@@ -203,8 +203,6 @@
 
 #include "seq_instr.h"
 
-extern char *snd_seq_gf1_id;
-
 typedef struct {
 	void *private_data;
 	int (*info)(void *private_data, gf1_info_t *info);
diff -Nru a/include/sound/ainstr_iw.h b/include/sound/ainstr_iw.h
--- a/include/sound/ainstr_iw.h	2005-03-01 23:39:18 -08:00
+++ b/include/sound/ainstr_iw.h	2005-03-01 23:39:18 -08:00
@@ -351,8 +351,6 @@
 
 #include "seq_instr.h"
 
-extern char *snd_seq_iwffff_id;
-
 typedef struct {
 	void *private_data;
 	int (*info)(void *private_data, iwffff_info_t *info);
diff -Nru a/include/sound/ainstr_simple.h b/include/sound/ainstr_simple.h
--- a/include/sound/ainstr_simple.h	2005-03-01 23:39:09 -08:00
+++ b/include/sound/ainstr_simple.h	2005-03-01 23:39:09 -08:00
@@ -134,8 +134,6 @@
 
 #include "seq_instr.h"
 
-extern char *snd_seq_simple_id;
-
 typedef struct {
 	void *private_data;
 	int (*info)(void *private_data, simple_instrument_info_t *info);
diff -Nru a/include/sound/ak4531_codec.h b/include/sound/ak4531_codec.h
--- a/include/sound/ak4531_codec.h	2005-03-01 23:38:54 -08:00
+++ b/include/sound/ak4531_codec.h	2005-03-01 23:38:54 -08:00
@@ -72,7 +72,7 @@
 	void (*private_free) (ak4531_t *ak4531);
 	/* --- */
 	unsigned char regs[0x20];
-	spinlock_t reg_lock;
+	struct semaphore reg_mutex;
 };
 
 int snd_ak4531_mixer(snd_card_t * card, ak4531_t * _ak4531, ak4531_t ** rak4531);
diff -Nru a/include/sound/asound.h b/include/sound/asound.h
--- a/include/sound/asound.h	2005-03-01 23:39:07 -08:00
+++ b/include/sound/asound.h	2005-03-01 23:39:07 -08:00
@@ -110,9 +110,12 @@
 	SNDRV_HWDEP_IFACE_MIXART,	/* Digigram miXart cards */
 	SNDRV_HWDEP_IFACE_USX2Y,	/* Tascam US122, US224 & US428 usb */
 	SNDRV_HWDEP_IFACE_EMUX_WAVETABLE, /* EmuX wavetable */	
+	SNDRV_HWDEP_IFACE_BLUETOOTH,	/* Bluetooth audio */
+	SNDRV_HWDEP_IFACE_USX2Y_PCM,	/* Tascam US122, US224 & US428 rawusb pcm */
+	SNDRV_HWDEP_IFACE_PCXHR,	/* Digigram PCXHR */
 
 	/* Don't forget to change the following: */
-	SNDRV_HWDEP_IFACE_LAST = SNDRV_HWDEP_IFACE_EMUX_WAVETABLE,
+	SNDRV_HWDEP_IFACE_LAST = SNDRV_HWDEP_IFACE_PCXHR
 };
 
 struct sndrv_hwdep_info {
diff -Nru a/include/sound/control.h b/include/sound/control.h
--- a/include/sound/control.h	2005-03-01 23:38:57 -08:00
+++ b/include/sound/control.h	2005-03-01 23:38:57 -08:00
@@ -115,12 +115,13 @@
 snd_kcontrol_t *snd_ctl_find_numid(snd_card_t * card, unsigned int numid);
 snd_kcontrol_t *snd_ctl_find_id(snd_card_t * card, snd_ctl_elem_id_t *id);
 
-int snd_ctl_register(snd_card_t *card);
-int snd_ctl_disconnect(snd_card_t *card);
-int snd_ctl_can_unregister(snd_card_t *card);
-int snd_ctl_unregister(snd_card_t *card);
+int snd_ctl_create(snd_card_t *card);
+
 int snd_ctl_register_ioctl(snd_kctl_ioctl_func_t fcn);
 int snd_ctl_unregister_ioctl(snd_kctl_ioctl_func_t fcn);
+
+int snd_ctl_elem_read(snd_card_t *card, snd_ctl_elem_value_t *control);
+int snd_ctl_elem_write(snd_card_t *card, snd_ctl_file_t *file, snd_ctl_elem_value_t *control);
 
 static inline unsigned int snd_ctl_get_ioffnum(snd_kcontrol_t *kctl, snd_ctl_elem_id_t *id)
 {
diff -Nru a/include/sound/core.h b/include/sound/core.h
--- a/include/sound/core.h	2005-03-01 23:39:17 -08:00
+++ b/include/sound/core.h	2005-03-01 23:39:17 -08:00
@@ -49,6 +49,7 @@
 
 typedef enum {
 	SNDRV_DEV_TOPLEVEL =		(0*SNDRV_DEV_TYPE_RANGE_SIZE),
+	SNDRV_DEV_CONTROL,
 	SNDRV_DEV_LOWLEVEL_PRE,
 	SNDRV_DEV_LOWLEVEL_NORMAL =	(1*SNDRV_DEV_TYPE_RANGE_SIZE),
 	SNDRV_DEV_PCM,
@@ -57,6 +58,8 @@
 	SNDRV_DEV_SEQUENCER,
 	SNDRV_DEV_HWDEP,
 	SNDRV_DEV_INFO,
+	SNDRV_DEV_BUS,
+	SNDRV_DEV_CODEC,
 	SNDRV_DEV_LOWLEVEL =		(2*SNDRV_DEV_TYPE_RANGE_SIZE)
 } snd_device_type_t;
 
@@ -147,6 +150,7 @@
 	struct rw_semaphore controls_rwsem;	/* controls list lock */
 	rwlock_t ctl_files_rwlock;	/* ctl_files list lock */
 	int controls_count;		/* count of all controls */
+	int user_ctl_count;		/* count of all user controls */
 	struct list_head controls;	/* all controls for this card */
 	struct list_head ctl_files;	/* active control files */
 
@@ -307,12 +311,11 @@
 #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 void __iomem *src, size_t count);
-int copy_from_user_toio(void __iomem *dst, const void __user *src, size_t count);
+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);
 
 /* init.c */
 
-extern int snd_cards_count;
 extern unsigned int snd_cards_lock;
 extern snd_card_t *snd_cards[SNDRV_CARDS];
 extern rwlock_t snd_card_rwlock;
diff -Nru a/include/sound/cs4231.h b/include/sound/cs4231.h
--- a/include/sound/cs4231.h	2005-03-01 23:38:57 -08:00
+++ b/include/sound/cs4231.h	2005-03-01 23:38:57 -08:00
@@ -309,7 +309,6 @@
 
 void snd_cs4231_out(cs4231_t *chip, unsigned char reg, unsigned char val);
 unsigned char snd_cs4231_in(cs4231_t *chip, unsigned char reg);
-void snd_cs4231_outm(cs4231_t *chip, unsigned char reg, unsigned char mask, unsigned char val);
 void snd_cs4236_ext_out(cs4231_t *chip, unsigned char reg, unsigned char val);
 unsigned char snd_cs4236_ext_in(cs4231_t *chip, unsigned char reg);
 void snd_cs4231_mce_up(cs4231_t *chip);
@@ -363,9 +362,5 @@
 int snd_cs4231_info_double(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo);
 int snd_cs4231_get_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol);
 int snd_cs4231_put_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol);
-
-#ifdef CONFIG_SND_DEBUG
-void snd_cs4231_debug(cs4231_t *chip);
-#endif
 
 #endif /* __SOUND_CS4231_H */
diff -Nru a/include/sound/cs8427.h b/include/sound/cs8427.h
--- a/include/sound/cs8427.h	2005-03-01 23:39:07 -08:00
+++ b/include/sound/cs8427.h	2005-03-01 23:39:07 -08:00
@@ -186,12 +186,9 @@
 #define CS8427_VERSHIFT		0
 #define CS8427_VER8427A		0x71
 
-int snd_cs8427_detect(snd_i2c_bus_t *bus, unsigned char addr);
 int snd_cs8427_create(snd_i2c_bus_t *bus, unsigned char addr,
 		      unsigned int reset_timeout, snd_i2c_device_t **r_cs8427);
-void snd_cs8427_reset(snd_i2c_device_t *cs8427);
 int snd_cs8427_reg_write(snd_i2c_device_t *device, unsigned char reg, unsigned char val);
-int snd_cs8427_reg_read(snd_i2c_device_t *device, unsigned char reg);
 int snd_cs8427_iec958_build(snd_i2c_device_t *cs8427, snd_pcm_substream_t *playback_substream, snd_pcm_substream_t *capture_substream);
 int snd_cs8427_iec958_active(snd_i2c_device_t *cs8427, int active);
 int snd_cs8427_iec958_pcm(snd_i2c_device_t *cs8427, unsigned int rate);
diff -Nru a/include/sound/emu10k1.h b/include/sound/emu10k1.h
--- a/include/sound/emu10k1.h	2005-03-01 23:38:54 -08:00
+++ b/include/sound/emu10k1.h	2005-03-01 23:38:54 -08:00
@@ -31,6 +31,7 @@
 #include <sound/ac97_codec.h>
 #include <sound/util_mem.h>
 #include <sound/pcm-indirect.h>
+#include <sound/timer.h>
 #include <linux/interrupt.h>
 #include <asm/io.h>
 
@@ -828,6 +829,7 @@
 };
 
 typedef struct {
+	/* mono, left, right x 8 sends (4 on emu10k1) */
 	unsigned char send_routing[3][8];
 	unsigned char send_volume[3][8];
 	unsigned short attn[3];
@@ -838,10 +840,10 @@
 ((route[0] | (route[1] << 4) | (route[2] << 8) | (route[3] << 12)) << 16)
 
 #define snd_emu10k1_compose_audigy_fxrt1(route) \
-(((unsigned int)route[0] | ((unsigned int)route[1] << 8) | ((unsigned int)route[2] << 16) | ((unsigned int)route[3] << 12)) << 24)
+((unsigned int)route[0] | ((unsigned int)route[1] << 8) | ((unsigned int)route[2] << 16) | ((unsigned int)route[3] << 24))
 
 #define snd_emu10k1_compose_audigy_fxrt2(route) \
-(((unsigned int)route[4] | ((unsigned int)route[5] << 8) | ((unsigned int)route[6] << 16) | ((unsigned int)route[7] << 12)) << 24)
+((unsigned int)route[4] | ((unsigned int)route[5] << 8) | ((unsigned int)route[6] << 16) | ((unsigned int)route[7] << 24))
 
 typedef struct snd_emu10k1_memblk {
 	snd_util_memblk_t mem;
@@ -1000,6 +1002,8 @@
 	snd_pcm_substream_t *pcm_capture_mic_substream;
 	snd_pcm_substream_t *pcm_capture_efx_substream;
 
+	snd_timer_t *timer;
+
 	emu10k1_midi_t midi;
 	emu10k1_midi_t midi2; /* for audigy */
 
@@ -1019,6 +1023,7 @@
 int snd_emu10k1_pcm_efx(emu10k1_t * emu, int device, snd_pcm_t ** rpcm);
 int snd_emu10k1_fx8010_pcm(emu10k1_t * emu, int device, snd_pcm_t ** rpcm);
 int snd_emu10k1_mixer(emu10k1_t * emu);
+int snd_emu10k1_timer(emu10k1_t * emu, int device);
 int snd_emu10k1_fx8010_new(emu10k1_t *emu, int device, snd_hwdep_t ** rhwdep);
 
 irqreturn_t snd_emu10k1_interrupt(int irq, void *dev_id, struct pt_regs *regs);
@@ -1032,7 +1037,6 @@
 /* I/O functions */
 unsigned int snd_emu10k1_ptr_read(emu10k1_t * emu, unsigned int reg, unsigned int chn);
 void snd_emu10k1_ptr_write(emu10k1_t *emu, unsigned int reg, unsigned int chn, unsigned int data);
-void snd_emu10k1_efx_write(emu10k1_t *emu, unsigned int pc, unsigned int data);
 unsigned int snd_emu10k1_efx_read(emu10k1_t *emu, unsigned int pc);
 void snd_emu10k1_intr_enable(emu10k1_t *emu, unsigned int intrenb);
 void snd_emu10k1_intr_disable(emu10k1_t *emu, unsigned int intrenb);
@@ -1046,7 +1050,6 @@
 unsigned short snd_emu10k1_ac97_read(ac97_t *ac97, unsigned short reg);
 void snd_emu10k1_ac97_write(ac97_t *ac97, unsigned short reg, unsigned short data);
 unsigned int snd_emu10k1_rate_to_pitch(unsigned int rate);
-unsigned char snd_emu10k1_sum_vol_attn(unsigned int value);
 
 /* memory allocation */
 snd_util_memblk_t *snd_emu10k1_alloc_pages(emu10k1_t *emu, snd_pcm_substream_t *substream);
@@ -1334,7 +1337,7 @@
 	char name[128];
 
 	DECLARE_BITMAP(gpr_valid, 0x200); /* bitmask of valid initializers */
-	unsigned int gpr_map[0x200];	  /* initializers */
+	u_int32_t __user *gpr_map;	  /* initializers */
 
 	unsigned int gpr_add_control_count; /* count of GPR controls to add/replace */
 	emu10k1_fx8010_control_gpr_t __user *gpr_add_controls; /* GPR controls to add/replace */
@@ -1347,11 +1350,11 @@
 	emu10k1_fx8010_control_gpr_t __user *gpr_list_controls; /* listed GPR controls */
 
 	DECLARE_BITMAP(tram_valid, 0x100); /* bitmask of valid initializers */
-	unsigned int tram_data_map[0x100]; /* data initializers */
-	unsigned int tram_addr_map[0x100]; /* map initializers */
+	u_int32_t __user *tram_data_map;  /* data initializers */
+	u_int32_t __user *tram_addr_map;  /* map initializers */
 
 	DECLARE_BITMAP(code_valid, 1024); /* bitmask of valid instructions */
-	unsigned int code[1024][2];	  /* one instruction - 64 bits */
+	u_int32_t __user *code;		  /* one instruction - 64 bits */
 } emu10k1_fx8010_code_t;
 
 typedef struct {
diff -Nru a/include/sound/es1688.h b/include/sound/es1688.h
--- a/include/sound/es1688.h	2005-03-01 23:39:07 -08:00
+++ b/include/sound/es1688.h	2005-03-01 23:39:07 -08:00
@@ -108,9 +108,6 @@
  */
 
 void snd_es1688_mixer_write(es1688_t *chip, unsigned char reg, unsigned char data);
-unsigned char snd_es1688_mixer_read(es1688_t *chip, unsigned char reg);
-
-irqreturn_t snd_es1688_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 
 int snd_es1688_create(snd_card_t * card,
 		      unsigned long port,
diff -Nru a/include/sound/gus.h b/include/sound/gus.h
--- a/include/sound/gus.h	2005-03-01 23:38:52 -08:00
+++ b/include/sound/gus.h	2005-03-01 23:38:52 -08:00
@@ -598,10 +598,6 @@
 
 /* gus_dma.c */
 
-void snd_gf1_dma_program(snd_gus_card_t * gus, unsigned int addr,
-			 unsigned long buf_addr, unsigned int count,
-			 unsigned int cmd);
-void snd_gf1_dma_ack(snd_gus_card_t * gus);
 int snd_gf1_dma_init(snd_gus_card_t * gus);
 int snd_gf1_dma_done(snd_gus_card_t * gus);
 int snd_gf1_dma_transfer_block(snd_gus_card_t * gus,
diff -Nru a/include/sound/info.h b/include/sound/info.h
--- a/include/sound/info.h	2005-03-01 23:39:08 -08:00
+++ b/include/sound/info.h	2005-03-01 23:39:08 -08:00
@@ -131,11 +131,6 @@
 int snd_info_register(snd_info_entry_t * entry);
 int snd_info_unregister(snd_info_entry_t * entry);
 
-struct proc_dir_entry *snd_create_proc_entry(const char *name, mode_t mode,
-					     struct proc_dir_entry *parent);
-void snd_remove_proc_entry(struct proc_dir_entry *parent,
-			   struct proc_dir_entry *de);
-
 /* for card drivers */
 int snd_card_proc_new(snd_card_t *card, const char *name, snd_info_entry_t **entryp);
 
@@ -170,10 +165,6 @@
 static inline int snd_info_card_free(snd_card_t * card) { return 0; }
 static inline int snd_info_register(snd_info_entry_t * entry) { return 0; }
 static inline int snd_info_unregister(snd_info_entry_t * entry) { return 0; }
-
-static inline struct proc_dir_entry *snd_create_proc_entry(const char *name, mode_t mode, struct proc_dir_entry *parent) { return NULL; }
-static inline void snd_remove_proc_entry(struct proc_dir_entry *parent,
-					 struct proc_dir_entry *de) { ; }
 
 #define snd_card_proc_new(card,name,entryp)  0 /* always success */
 #define snd_info_set_text_ops(entry,private_data,read_size,read) /*NOP*/
diff -Nru a/include/sound/pcm.h b/include/sound/pcm.h
--- a/include/sound/pcm.h	2005-03-01 23:38:57 -08:00
+++ b/include/sound/pcm.h	2005-03-01 23:38:57 -08:00
@@ -497,10 +497,6 @@
 int snd_pcm_kernel_playback_ioctl(snd_pcm_substream_t *substream, unsigned int cmd, void *arg);
 int snd_pcm_kernel_capture_ioctl(snd_pcm_substream_t *substream, unsigned int cmd, void *arg);
 int snd_pcm_kernel_ioctl(snd_pcm_substream_t *substream, unsigned int cmd, void *arg);
-int snd_pcm_open(struct inode *inode, struct file *file);
-int snd_pcm_release(struct inode *inode, struct file *file);
-unsigned int snd_pcm_playback_poll(struct file *file, poll_table * wait);
-unsigned int snd_pcm_capture_poll(struct file *file, poll_table * wait);
 int snd_pcm_open_substream(snd_pcm_t *pcm, int stream, snd_pcm_substream_t **rsubstream);
 void snd_pcm_release_substream(snd_pcm_substream_t *substream);
 void snd_pcm_vma_notify_data(void *client, void *data);
@@ -709,6 +705,80 @@
 	return runtime->buffer_size - snd_pcm_capture_avail(runtime);
 }
 
+/**
+ * snd_pcm_playback_ready - check whether the playback buffer is available
+ * @substream: the pcm substream instance
+ *
+ * Checks whether enough free space is available on the playback buffer.
+ *
+ * Returns non-zero if available, or zero if not.
+ */
+static inline int snd_pcm_playback_ready(snd_pcm_substream_t *substream)
+{
+	snd_pcm_runtime_t *runtime = substream->runtime;
+	return snd_pcm_playback_avail(runtime) >= runtime->control->avail_min;
+}
+
+/**
+ * snd_pcm_capture_ready - check whether the capture buffer is available
+ * @substream: the pcm substream instance
+ *
+ * Checks whether enough capture data is available on the capture buffer.
+ *
+ * Returns non-zero if available, or zero if not.
+ */
+static inline int snd_pcm_capture_ready(snd_pcm_substream_t *substream)
+{
+	snd_pcm_runtime_t *runtime = substream->runtime;
+	return snd_pcm_capture_avail(runtime) >= runtime->control->avail_min;
+}
+
+/**
+ * snd_pcm_playback_data - check whether any data exists on the playback buffer
+ * @substream: the pcm substream instance
+ *
+ * Checks whether any data exists on the playback buffer. If stop_threshold
+ * is bigger or equal to boundary, then this function returns always non-zero.
+ *
+ * Returns non-zero if exists, or zero if not.
+ */
+static inline int snd_pcm_playback_data(snd_pcm_substream_t *substream)
+{
+	snd_pcm_runtime_t *runtime = substream->runtime;
+	
+	if (runtime->stop_threshold >= runtime->boundary)
+		return 1;
+	return snd_pcm_playback_avail(runtime) < runtime->buffer_size;
+}
+
+/**
+ * snd_pcm_playback_empty - check whether the playback buffer is empty
+ * @substream: the pcm substream instance
+ *
+ * Checks whether the playback buffer is empty.
+ *
+ * Returns non-zero if empty, or zero if not.
+ */
+static inline int snd_pcm_playback_empty(snd_pcm_substream_t *substream)
+{
+	snd_pcm_runtime_t *runtime = substream->runtime;
+	return snd_pcm_playback_avail(runtime) >= runtime->buffer_size;
+}
+
+/**
+ * snd_pcm_capture_empty - check whether the capture buffer is empty
+ * @substream: the pcm substream instance
+ *
+ * Checks whether the capture buffer is empty.
+ *
+ * Returns non-zero if empty, or zero if not.
+ */
+static inline int snd_pcm_capture_empty(snd_pcm_substream_t *substream)
+{
+	snd_pcm_runtime_t *runtime = substream->runtime;
+	return snd_pcm_capture_avail(runtime) == 0;
+}
+
 static inline void snd_pcm_trigger_done(snd_pcm_substream_t *substream, 
 					snd_pcm_substream_t *master)
 {
@@ -772,13 +842,9 @@
 void snd_interval_mulkdiv(const snd_interval_t *a, unsigned int k,
 			  const snd_interval_t *b, snd_interval_t *c);
 int snd_interval_list(snd_interval_t *i, unsigned int count, unsigned int *list, unsigned int mask);
-int snd_interval_step(snd_interval_t *i, unsigned int min, unsigned int step);
 int snd_interval_ratnum(snd_interval_t *i,
 			unsigned int rats_count, ratnum_t *rats,
 			unsigned int *nump, unsigned int *denp);
-int snd_interval_ratden(snd_interval_t *i,
-			unsigned int rats_count, ratden_t *rats,
-			unsigned int *nump, unsigned int *denp);
 
 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);
@@ -810,6 +876,7 @@
 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);
@@ -860,9 +927,7 @@
 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);
-ssize_t snd_pcm_format_size(snd_pcm_format_t format, size_t samples);
 const char *snd_pcm_format_name(snd_pcm_format_t format);
-const char *snd_pcm_subformat_name(snd_pcm_subformat_t subformat);
 
 void snd_pcm_set_ops(snd_pcm_t * pcm, int direction, snd_pcm_ops_t *ops);
 void snd_pcm_set_sync(snd_pcm_substream_t * substream);
@@ -875,13 +940,6 @@
 int snd_pcm_playback_xrun_asap(snd_pcm_substream_t *substream);
 int snd_pcm_capture_xrun_asap(snd_pcm_substream_t *substream);
 void snd_pcm_playback_silence(snd_pcm_substream_t *substream, snd_pcm_uframes_t new_hw_ptr);
-int snd_pcm_playback_ready(snd_pcm_substream_t *substream);
-int snd_pcm_capture_ready(snd_pcm_substream_t *substream);
-long snd_pcm_playback_ready_jiffies(snd_pcm_substream_t *substream);
-long snd_pcm_capture_ready_jiffies(snd_pcm_substream_t *substream);
-int snd_pcm_playback_data(snd_pcm_substream_t *substream);
-int snd_pcm_playback_empty(snd_pcm_substream_t *substream);
-int snd_pcm_capture_empty(snd_pcm_substream_t *substream);
 void snd_pcm_tick_prepare(snd_pcm_substream_t *substream);
 void snd_pcm_tick_set(snd_pcm_substream_t *substream, unsigned long ticks);
 void snd_pcm_tick_elapsed(snd_pcm_substream_t *substream);
diff -Nru a/include/sound/rawmidi.h b/include/sound/rawmidi.h
--- a/include/sound/rawmidi.h	2005-03-01 23:39:09 -08:00
+++ b/include/sound/rawmidi.h	2005-03-01 23:39:09 -08:00
@@ -152,13 +152,6 @@
 		    snd_rawmidi_t ** rmidi);
 void snd_rawmidi_set_ops(snd_rawmidi_t * rmidi, int stream, snd_rawmidi_ops_t * ops);
 
-/* control functions */
-
-int snd_rawmidi_control_ioctl(snd_card_t * card,
-			      snd_ctl_file_t * control,
-			      unsigned int cmd,
-			      unsigned long arg);
-
 /* callbacks */
 
 void snd_rawmidi_receive_reset(snd_rawmidi_substream_t * substream);
diff -Nru a/include/sound/sb.h b/include/sound/sb.h
--- a/include/sound/sb.h	2005-03-01 23:38:56 -08:00
+++ b/include/sound/sb.h	2005-03-01 23:38:56 -08:00
@@ -311,10 +311,6 @@
 int snd_sb16dsp_configure(sb_t *chip);
 /* sb16.c */
 irqreturn_t snd_sb16dsp_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-int snd_sb16_playback_open(snd_pcm_substream_t *substream);
-int snd_sb16_capture_open(snd_pcm_substream_t *substream);
-int snd_sb16_playback_close(snd_pcm_substream_t *substream);
-int snd_sb16_capture_close(snd_pcm_substream_t *substream);
 
 /* exported mixer stuffs */
 enum {
diff -Nru a/include/sound/seq_midi_emul.h b/include/sound/seq_midi_emul.h
--- a/include/sound/seq_midi_emul.h	2005-03-01 23:39:08 -08:00
+++ b/include/sound/seq_midi_emul.h	2005-03-01 23:39:08 -08:00
@@ -189,8 +189,6 @@
 void snd_midi_process_event(snd_midi_op_t *ops, snd_seq_event_t *ev,
 			    snd_midi_channel_set_t *chanset);
 void snd_midi_channel_set_clear(snd_midi_channel_set_t *chset);
-void snd_midi_channel_init(snd_midi_channel_t *p, int n);
-snd_midi_channel_t *snd_midi_channel_init_set(int n);
 snd_midi_channel_set_t *snd_midi_channel_alloc_set(int n);
 void snd_midi_channel_free_set(snd_midi_channel_set_t *chset);
 
diff -Nru a/include/sound/snd_wavefront.h b/include/sound/snd_wavefront.h
--- a/include/sound/snd_wavefront.h	2005-03-01 23:38:53 -08:00
+++ b/include/sound/snd_wavefront.h	2005-03-01 23:38:53 -08:00
@@ -107,7 +107,6 @@
 };
 
 extern void snd_wavefront_internal_interrupt (snd_wavefront_card_t *card);
-extern int  snd_wavefront_interrupt_bits (int irq);
 extern int  snd_wavefront_detect_irq (snd_wavefront_t *dev) ;
 extern int  snd_wavefront_check_irq (snd_wavefront_t *dev, int irq);
 extern int  snd_wavefront_restart (snd_wavefront_t *dev);
diff -Nru a/include/sound/soundfont.h b/include/sound/soundfont.h
--- a/include/sound/soundfont.h	2005-03-01 23:39:17 -08:00
+++ b/include/sound/soundfont.h	2005-03-01 23:39:17 -08:00
@@ -112,7 +112,6 @@
 
 int snd_soundfont_remove_samples(snd_sf_list_t *sflist);
 int snd_soundfont_remove_unlocked(snd_sf_list_t *sflist);
-int snd_soundfont_mem_used(snd_sf_list_t *sflist);
 
 int snd_soundfont_search_zone(snd_sf_list_t *sflist, int *notep, int vel,
 			      int preset, int bank,
diff -Nru a/include/sound/soundmem.h b/include/sound/soundmem.h
--- a/include/sound/soundmem.h	2005-03-01 23:38:44 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,8 +0,0 @@
-/*
- *  Onboard memory management
- */
-
-struct SNDRV_STRU_BANK_INFO {
-	unsigned int address;
-	unsigned int size;
-};
diff -Nru a/include/sound/trident.h b/include/sound/trident.h
--- a/include/sound/trident.h	2005-03-01 23:38:58 -08:00
+++ b/include/sound/trident.h	2005-03-01 23:38:58 -08:00
@@ -457,27 +457,23 @@
 		       int pcm_spdif_device,
 		       int max_wavetable_size,
 		       trident_t ** rtrident);
-int snd_trident_free(trident_t *trident);
 void snd_trident_gameport(trident_t *trident);
 
 int snd_trident_pcm(trident_t * trident, int device, snd_pcm_t **rpcm);
 int snd_trident_foldback_pcm(trident_t * trident, int device, snd_pcm_t **rpcm);
 int snd_trident_spdif_pcm(trident_t * trident, int device, snd_pcm_t **rpcm);
 int snd_trident_attach_synthesizer(trident_t * trident);
-int snd_trident_detach_synthesizer(trident_t * trident);
 snd_trident_voice_t *snd_trident_alloc_voice(trident_t * trident, int type, int client, int port);
 void snd_trident_free_voice(trident_t * trident, snd_trident_voice_t *voice);
 void snd_trident_start_voice(trident_t * trident, unsigned int voice);
 void snd_trident_stop_voice(trident_t * trident, unsigned int voice);
 void snd_trident_write_voice_regs(trident_t * trident, snd_trident_voice_t *voice);
-void snd_trident_clear_voices(trident_t * trident, unsigned short v_min, unsigned short v_max);
 
 /* TLB memory allocation */
 snd_util_memblk_t *snd_trident_alloc_pages(trident_t *trident, snd_pcm_substream_t *substream);
 int snd_trident_free_pages(trident_t *trident, snd_util_memblk_t *blk);
 snd_util_memblk_t *snd_trident_synth_alloc(trident_t *trident, unsigned int size);
 int snd_trident_synth_free(trident_t *trident, snd_util_memblk_t *blk);
-int snd_trident_synth_bzero(trident_t *trident, snd_util_memblk_t *blk, int offset, int size);
 int snd_trident_synth_copy_from_user(trident_t *trident, snd_util_memblk_t *blk, int offset, const char __user *data, int size);
 
 #endif /* __SOUND_TRIDENT_H */
diff -Nru a/include/sound/version.h b/include/sound/version.h
--- a/include/sound/version.h	2005-03-01 23:39:18 -08:00
+++ b/include/sound/version.h	2005-03-01 23:39:18 -08:00
@@ -1,3 +1,3 @@
 /* include/version.h.  Generated by configure.  */
-#define CONFIG_SND_VERSION "1.0.6"
-#define CONFIG_SND_DATE " (Sun Aug 15 07:17:53 2004 UTC)"
+#define CONFIG_SND_VERSION "1.0.8"
+#define CONFIG_SND_DATE " (Thu Jan 13 09:39:32 2005 UTC)"
diff -Nru a/include/sound/vx_core.h b/include/sound/vx_core.h
--- a/include/sound/vx_core.h	2005-03-01 23:38:51 -08:00
+++ b/include/sound/vx_core.h	2005-03-01 23:38:51 -08:00
@@ -27,6 +27,15 @@
 #include <sound/hwdep.h>
 #include <linux/interrupt.h>
 
+#if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE)
+#if !defined(CONFIG_USE_VXLOADER) && !defined(CONFIG_SND_VX_LIB) /* built-in kernel */
+#define SND_VX_FW_LOADER	/* use the standard firmware loader */
+#endif
+#endif
+
+struct firmware;
+struct device;
+
 typedef struct snd_vx_core vx_core_t;
 typedef struct vx_pipe vx_pipe_t;
 
@@ -100,7 +109,7 @@
 	void (*change_audio_source)(vx_core_t *chip, int src);
 	void (*set_clock_source)(vx_core_t *chp, int src);
 	/* chip init */
-	int (*load_dsp)(vx_core_t *chip, const snd_hwdep_dsp_image_t *dsp);
+	int (*load_dsp)(vx_core_t *chip, int idx, const struct firmware *fw);
 	void (*reset_dsp)(vx_core_t *chip);
 	void (*reset_board)(vx_core_t *chip, int cold_reset);
 	int (*add_controls)(vx_core_t *chip);
@@ -169,6 +178,7 @@
 	unsigned int chip_status;
 	unsigned int pcm_running;
 
+	struct device *dev;
 	snd_hwdep_t *hwdep;
 
 	struct vx_rmh irq_rmh;	/* RMH used in interrupts */
@@ -198,6 +208,8 @@
 	unsigned char audio_monitor_active[4];	/* playback hw-monitor mute/unmute */
 
 	struct semaphore mixer_mutex;
+
+	const struct firmware *firmware[4]; /* loaded firmware data */
 };
 
 
@@ -206,10 +218,12 @@
  */
 vx_core_t *snd_vx_create(snd_card_t *card, struct snd_vx_hardware *hw,
 			 struct snd_vx_ops *ops, int extra_size);
-int snd_vx_hwdep_new(vx_core_t *chip);
-int snd_vx_load_boot_image(vx_core_t *chip, const snd_hwdep_dsp_image_t *boot);
-int snd_vx_dsp_boot(vx_core_t *chip, const snd_hwdep_dsp_image_t *boot);
-int snd_vx_dsp_load(vx_core_t *chip, const snd_hwdep_dsp_image_t *dsp);
+int snd_vx_setup_firmware(vx_core_t *chip);
+int snd_vx_load_boot_image(vx_core_t *chip, const struct firmware *dsp);
+int snd_vx_dsp_boot(vx_core_t *chip, const struct firmware *dsp);
+int snd_vx_dsp_load(vx_core_t *chip, const struct firmware *dsp);
+
+void snd_vx_free_firmware(vx_core_t *chip);
 
 /*
  * interrupt handler; exported for pcmcia
@@ -217,15 +231,6 @@
 irqreturn_t snd_vx_irq_handler(int irq, void *dev, struct pt_regs *regs);
 
 /*
- * power-management routines
- */
-#ifdef CONFIG_PM
-void snd_vx_suspend(vx_core_t *chip);
-void snd_vx_resume(vx_core_t *chip);
-#endif
-
-
-/*
  * lowlevel functions
  */
 inline static int vx_test_and_ack(vx_core_t *chip)
@@ -340,7 +345,6 @@
  */
 void vx_set_iec958_status(vx_core_t *chip, unsigned int bits);
 int vx_set_clock(vx_core_t *chip, unsigned int freq);
-void vx_change_clock_source(vx_core_t *chip, int source);
 void vx_set_internal_clock(vx_core_t *chip, unsigned int freq);
 int vx_change_frequency(vx_core_t *chip);
 
diff -Nru a/include/sound/ymfpci.h b/include/sound/ymfpci.h
--- a/include/sound/ymfpci.h	2005-03-01 23:38:55 -08:00
+++ b/include/sound/ymfpci.h	2005-03-01 23:38:55 -08:00
@@ -389,9 +389,6 @@
 int snd_ymfpci_mixer(ymfpci_t *chip, int rear_switch);
 int snd_ymfpci_timer(ymfpci_t *chip, int device);
 
-int snd_ymfpci_voice_alloc(ymfpci_t *chip, ymfpci_voice_type_t type, int pair, ymfpci_voice_t **rvoice);
-int snd_ymfpci_voice_free(ymfpci_t *chip, ymfpci_voice_t *pvoice);
-
 #if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
 #define SUPPORT_JOYSTICK
 #endif
diff -Nru a/include/video/maxinefb.h b/include/video/maxinefb.h
--- a/include/video/maxinefb.h	2005-03-01 23:38:53 -08:00
+++ b/include/video/maxinefb.h	2005-03-01 23:38:53 -08:00
@@ -8,17 +8,18 @@
  *      archive for more details.
  */
 
+#include <asm/addrspace.h>
 
 /*
  * IMS332 video controller register base address
  */
-#define MAXINEFB_IMS332_ADDRESS                  0xbc140000
+#define MAXINEFB_IMS332_ADDRESS		KSEG1ADDR(0x1c140000)
 
 /*
  * Begin of DECstation 5000/xx onboard framebuffer memory, default resolution
  * is 1024x768x8
  */
-#define DS5000_xx_ONBOARD_FBMEM_START	0xaa000000
+#define DS5000_xx_ONBOARD_FBMEM_START	KSEG1ADDR(0x0a000000)
 
 /*
  *      The IMS 332 video controller used in the DECstation 5000/xx series
diff -Nru a/include/video/newport.h b/include/video/newport.h
--- a/include/video/newport.h	2005-03-01 23:39:07 -08:00
+++ b/include/video/newport.h	2005-03-01 23:39:07 -08:00
@@ -291,8 +291,6 @@
 	unsigned int _unused2[0x1ef];
 	struct newport_cregs cgo;
 };
-extern struct newport_regs *npregs;
-
 
 typedef struct {
 	unsigned int drawmode1;
@@ -450,38 +448,26 @@
 
 /* Miscellaneous NEWPORT routines. */
 #define BUSY_TIMEOUT 100000
-static __inline__ int newport_wait(void)
+static __inline__ int newport_wait(struct newport_regs *regs)
 {
-	int i = 0;
+	int t = BUSY_TIMEOUT;
 
-	while(i < BUSY_TIMEOUT)
-		if(!(npregs->cset.status & NPORT_STAT_GBUSY))
+	while (t--)
+		if (!(regs->cset.status & NPORT_STAT_GBUSY))
 			break;
-	if(i == BUSY_TIMEOUT)
-		return 1;
-	return 0;
+	return !t;
 }
 
-static __inline__ int newport_bfwait(void)
+static __inline__ int newport_bfwait(struct newport_regs *regs)
 {
-	int i = 0;
+	int t = BUSY_TIMEOUT;
 
-	while(i < BUSY_TIMEOUT)
-		if(!(npregs->cset.status & NPORT_STAT_BBUSY))
+	while (t--)
+		if(!(regs->cset.status & NPORT_STAT_BBUSY))
 			break;
-	if(i == BUSY_TIMEOUT)
-		return 1;
-	return 0;
+	return !t;
 }
 
-/* newport.c and cons_newport.c routines */
-extern struct graphics_ops *newport_probe (int, const char **);
-
-void newport_save    (void *);
-void newport_restore (void *);
-void newport_reset   (void);
-int  newport_ioctl   (int card, int cmd, unsigned long arg);
-
 /*
  * DCBMODE register defines:
  */
@@ -564,7 +550,7 @@
 {
         rex->set.dcbmode = DCB_XMAP0 | XM9_CRS_FIFO_AVAIL |
 		DCB_DATAWIDTH_1 | R_DCB_XMAP9_PROTOCOL;
-        newport_bfwait ();
+        newport_bfwait (rex);
 	
         while ((rex->set.dcbdata0.bybytes.b3 & 3) != XM9_FIFO_EMPTY)
 		;
diff -Nru a/include/video/permedia2.h b/include/video/permedia2.h
--- a/include/video/permedia2.h	2005-03-01 23:39:09 -08:00
+++ b/include/video/permedia2.h	2005-03-01 23:39:09 -08:00
@@ -188,6 +188,14 @@
 #define PM2F_VSYNC_ACT_LOW				0x60
 #define PM2F_LINE_DOUBLE				0x04
 #define PM2F_VIDEO_ENABLE				0x01
+#define PM2F_RD_PIXELFORMAT_SVGA			0x01
+#define PM2F_RD_PIXELFORMAT_RGB232OFFSET		0x02
+#define PM2F_RD_PIXELFORMAT_RGBA2321			0x03
+#define PM2F_RD_PIXELFORMAT_RGBA5551			0x04
+#define PM2F_RD_PIXELFORMAT_RGBA4444			0x05
+#define PM2F_RD_PIXELFORMAT_RGB565			0x06
+#define PM2F_RD_PIXELFORMAT_RGBA8888			0x08
+#define PM2F_RD_PIXELFORMAT_RGB888			0x09
 #define PM2F_RD_GUI_ACTIVE				0x10
 #define PM2F_RD_COLOR_MODE_RGB				0x20
 #define PM2F_DELTA_ORDER_RGB				(1L<<18)
@@ -209,6 +217,9 @@
 #define PM2F_MEM_BANKS_2				(1L<<29)
 #define PM2F_MEM_BANKS_3				(2L<<29)
 #define PM2F_MEM_BANKS_4				(3L<<29)
+#define PM2F_APERTURE_STANDARD				0
+#define PM2F_APERTURE_BYTESWAP				1
+#define PM2F_APERTURE_HALFWORDSWAP			2
 
 typedef enum {
 	PM2_TYPE_PERMEDIA2,
diff -Nru a/include/video/radeon.h b/include/video/radeon.h
--- a/include/video/radeon.h	2005-03-01 23:39:17 -08:00
+++ b/include/video/radeon.h	2005-03-01 23:39:17 -08:00
@@ -21,6 +21,7 @@
 #define PAD_AGPINPUT_DELAY                     0x0164  
 #define PAD_CTLR_STRENGTH                      0x0168  
 #define PAD_CTLR_UPDATE                        0x016C
+#define PAD_CTLR_MISC                          0x0aa0
 #define AGP_CNTL                               0x0174
 #define BM_STATUS                              0x0160
 #define CAP0_TRIG_CNTL			       0x0950
@@ -68,18 +69,26 @@
 #define DAC_CNTL2                              0x007c
 #define CRTC_GEN_CNTL                          0x0050  
 #define MEM_CNTL                               0x0140  
+#define MC_CNTL                                0x0140
 #define EXT_MEM_CNTL                           0x0144  
+#define MC_TIMING_CNTL                         0x0144
 #define MC_AGP_LOCATION                        0x014C  
 #define MEM_IO_CNTL_A0                         0x0178  
+#define MEM_REFRESH_CNTL                       0x0178
 #define MEM_INIT_LATENCY_TIMER                 0x0154  
+#define MC_INIT_GFX_LAT_TIMER                  0x0154
 #define MEM_SDRAM_MODE_REG                     0x0158  
 #define AGP_BASE                               0x0170  
 #define MEM_IO_CNTL_A1                         0x017C  
+#define MC_READ_CNTL_AB                        0x017C
 #define MEM_IO_CNTL_B0                         0x0180
+#define MC_INIT_MISC_LAT_TIMER                 0x0180
 #define MEM_IO_CNTL_B1                         0x0184
+#define MC_IOPAD_CNTL                          0x0184
 #define MC_DEBUG                               0x0188
 #define MC_STATUS                              0x0150  
 #define MEM_IO_OE_CNTL                         0x018C  
+#define MC_CHIP_IO_OE_CNTL_AB                  0x018C
 #define MC_FB_LOCATION                         0x0148  
 #define HOST_PATH_CNTL                         0x0130  
 #define MEM_VGA_WP_SEL                         0x0038  
@@ -385,6 +394,13 @@
 #define TMDS_CRC			       0x02a0
 #define TMDS_TRANSMITTER_CNTL		       0x02a4
 #define MPP_TB_CONFIG            	       0x01c0
+#define PAMAC0_DLY_CNTL                        0x0a94
+#define PAMAC1_DLY_CNTL                        0x0a98
+#define PAMAC2_DLY_CNTL                        0x0a9c
+#define FW_CNTL                                0x0118
+#define FCP_CNTL                               0x0910
+#define VGA_DDA_ON_OFF                         0x02ec
+#define TV_MASTER_CNTL                         0x0800
 
 //#define BASE_CODE			       0x0f0b
 #define BIOS_0_SCRATCH			       0x0010
@@ -418,7 +434,7 @@
 #define PPLL_DIV_3                                 0x0007
 #define VCLK_ECP_CNTL                              0x0008
 #define HTOTAL_CNTL                                0x0009
-#define X_MPLL_REF_FB_DIV                          0x000a
+#define M_SPLL_REF_FB_DIV                          0x000a
 #define AGP_PLL_CNTL                               0x000b
 #define SPLL_CNTL                                  0x000c
 #define SCLK_CNTL                                  0x000d
@@ -497,6 +513,8 @@
 #define CFG_VGA_RAM_EN                             0x00000100
 #define CFG_ATI_REV_ID_MASK			   (0xf << 16)
 #define CFG_ATI_REV_A11				   (0 << 16)
+#define CFG_ATI_REV_A12				   (1 << 16)
+#define CFG_ATI_REV_A13				   (2 << 16)
 
 /* CRTC_EXT_CNTL bit constants */
 #define VGA_ATI_LINEAR                             0x00000008
@@ -573,9 +591,17 @@
 /* FP_GEN_CNTL bit constants */
 #define FP_FPON					   (1 << 0)
 #define FP_TMDS_EN				   (1 << 2)
+#define FP_PANEL_FORMAT                            (1 << 3)
 #define FP_EN_TMDS				   (1 << 7)
 #define FP_DETECT_SENSE				   (1 << 8)
+#define R200_FP_SOURCE_SEL_MASK                    (3 << 10)
+#define R200_FP_SOURCE_SEL_CRTC1                   (0 << 10)
+#define R200_FP_SOURCE_SEL_CRTC2                   (1 << 10)
+#define R200_FP_SOURCE_SEL_RMX                     (2 << 10)
+#define R200_FP_SOURCE_SEL_TRANS                   (3 << 10)
+#define FP_SEL_CRTC1				   (0 << 13)
 #define FP_SEL_CRTC2				   (1 << 13)
+#define FP_USE_VGA_HSYNC                           (1 << 14)
 #define FP_CRTC_DONT_SHADOW_HPAR		   (1 << 15)
 #define FP_CRTC_DONT_SHADOW_VPAR		   (1 << 16)
 #define FP_CRTC_DONT_SHADOW_HEND		   (1 << 17)
@@ -671,6 +697,7 @@
 #define DAC_CMP_OUTPUT                             (1 <<  7)
 
 /* DAC_CNTL2 bit constants */   
+#define DAC2_EXPAND_MODE			   (1 << 14)
 #define DAC2_CMP_EN                                (1 << 7)
 #define DAC2_PALETTE_ACCESS_CNTL                   (1 << 5)
 
@@ -697,6 +724,11 @@
 #define MEM_ARBITER_STATUS_BUSY                    0x00400000
 #define MEM_REQ_UNLOCK                             0x00000000
 #define MEM_REQ_LOCK                               0x00800000
+#define MEM_NUM_CHANNELS_MASK 			   0x00000001
+#define MEM_USE_B_CH_ONLY                          0x00000002
+#define RV100_MEM_HALF_MODE                        0x00000008
+#define R300_MEM_NUM_CHANNELS_MASK                 0x00000003
+#define R300_MEM_USE_CD_CH_ONLY                    0x00000004
 
 
 /* RBBM_SOFT_RESET bit constants */
@@ -963,9 +995,11 @@
 
 #define MC_IND_INDEX                           0x01F8
 #define MC_IND_DATA                            0x01FC
-#define MEM_REFRESH_CNTL                       0x0178
 
-// CLK_PIN_CNTL
+/* PAD_CTLR_STRENGTH */
+#define PAD_MANUAL_OVERRIDE		0x80000000
+
+// pllCLK_PIN_CNTL
 #define CLK_PIN_CNTL__OSC_EN_MASK                          0x00000001L
 #define CLK_PIN_CNTL__OSC_EN                               0x00000001L
 #define CLK_PIN_CNTL__XTL_LOW_GAIN_MASK                    0x00000004L
@@ -991,32 +1025,32 @@
 #define CLK_PIN_CNTL__XTALIN_ALWAYS_ONb                    0x00080000L
 #define CLK_PIN_CNTL__PWRSEQ_DELAY_MASK                    0xff000000L
 
-// CLK_PWRMGT_CNTL_M6
-#define	CLK_PWRMGT_CNTL_M6__MPLL_PWRMGT_OFF__SHIFT         0x00000000
-#define	CLK_PWRMGT_CNTL_M6__SPLL_PWRMGT_OFF__SHIFT         0x00000001
-#define	CLK_PWRMGT_CNTL_M6__PPLL_PWRMGT_OFF__SHIFT         0x00000002
-#define	CLK_PWRMGT_CNTL_M6__P2PLL_PWRMGT_OFF__SHIFT        0x00000003
-#define	CLK_PWRMGT_CNTL_M6__MCLK_TURNOFF__SHIFT            0x00000004
-#define	CLK_PWRMGT_CNTL_M6__SCLK_TURNOFF__SHIFT            0x00000005
-#define	CLK_PWRMGT_CNTL_M6__PCLK_TURNOFF__SHIFT            0x00000006
-#define	CLK_PWRMGT_CNTL_M6__P2CLK_TURNOFF__SHIFT           0x00000007
-#define	CLK_PWRMGT_CNTL_M6__MC_CH_MODE__SHIFT              0x00000008
-#define	CLK_PWRMGT_CNTL_M6__TEST_MODE__SHIFT               0x00000009
-#define	CLK_PWRMGT_CNTL_M6__GLOBAL_PMAN_EN__SHIFT          0x0000000a
-#define	CLK_PWRMGT_CNTL_M6__ENGINE_DYNCLK_MODE__SHIFT      0x0000000c
-#define	CLK_PWRMGT_CNTL_M6__ACTIVE_HILO_LAT__SHIFT         0x0000000d
-#define	CLK_PWRMGT_CNTL_M6__DISP_DYN_STOP_LAT__SHIFT       0x0000000f
-#define	CLK_PWRMGT_CNTL_M6__MC_BUSY__SHIFT                 0x00000010
-#define	CLK_PWRMGT_CNTL_M6__MC_INT_CNTL__SHIFT             0x00000011
-#define	CLK_PWRMGT_CNTL_M6__MC_SWITCH__SHIFT               0x00000012
-#define	CLK_PWRMGT_CNTL_M6__DLL_READY__SHIFT               0x00000013
-#define	CLK_PWRMGT_CNTL_M6__DISP_PM__SHIFT                 0x00000014
-#define	CLK_PWRMGT_CNTL_M6__DYN_STOP_MODE__SHIFT           0x00000015
-#define	CLK_PWRMGT_CNTL_M6__CG_NO1_DEBUG__SHIFT            0x00000018
-#define	CLK_PWRMGT_CNTL_M6__TVPLL_PWRMGT_OFF__SHIFT        0x0000001e
-#define	CLK_PWRMGT_CNTL_M6__TVCLK_TURNOFF__SHIFT           0x0000001f
+// pllCLK_PWRMGT_CNTL
+#define	CLK_PWRMGT_CNTL__MPLL_PWRMGT_OFF__SHIFT         0x00000000
+#define	CLK_PWRMGT_CNTL__SPLL_PWRMGT_OFF__SHIFT         0x00000001
+#define	CLK_PWRMGT_CNTL__PPLL_PWRMGT_OFF__SHIFT         0x00000002
+#define	CLK_PWRMGT_CNTL__P2PLL_PWRMGT_OFF__SHIFT        0x00000003
+#define	CLK_PWRMGT_CNTL__MCLK_TURNOFF__SHIFT            0x00000004
+#define	CLK_PWRMGT_CNTL__SCLK_TURNOFF__SHIFT            0x00000005
+#define	CLK_PWRMGT_CNTL__PCLK_TURNOFF__SHIFT            0x00000006
+#define	CLK_PWRMGT_CNTL__P2CLK_TURNOFF__SHIFT           0x00000007
+#define	CLK_PWRMGT_CNTL__MC_CH_MODE__SHIFT              0x00000008
+#define	CLK_PWRMGT_CNTL__TEST_MODE__SHIFT               0x00000009
+#define	CLK_PWRMGT_CNTL__GLOBAL_PMAN_EN__SHIFT          0x0000000a
+#define	CLK_PWRMGT_CNTL__ENGINE_DYNCLK_MODE__SHIFT      0x0000000c
+#define	CLK_PWRMGT_CNTL__ACTIVE_HILO_LAT__SHIFT         0x0000000d
+#define	CLK_PWRMGT_CNTL__DISP_DYN_STOP_LAT__SHIFT       0x0000000f
+#define	CLK_PWRMGT_CNTL__MC_BUSY__SHIFT                 0x00000010
+#define	CLK_PWRMGT_CNTL__MC_INT_CNTL__SHIFT             0x00000011
+#define	CLK_PWRMGT_CNTL__MC_SWITCH__SHIFT               0x00000012
+#define	CLK_PWRMGT_CNTL__DLL_READY__SHIFT               0x00000013
+#define	CLK_PWRMGT_CNTL__DISP_PM__SHIFT                 0x00000014
+#define	CLK_PWRMGT_CNTL__DYN_STOP_MODE__SHIFT           0x00000015
+#define	CLK_PWRMGT_CNTL__CG_NO1_DEBUG__SHIFT            0x00000018
+#define	CLK_PWRMGT_CNTL__TVPLL_PWRMGT_OFF__SHIFT        0x0000001e
+#define	CLK_PWRMGT_CNTL__TVCLK_TURNOFF__SHIFT           0x0000001f
 
-// P2PLL_CNTL
+// pllP2PLL_CNTL
 #define P2PLL_CNTL__P2PLL_RESET_MASK                       0x00000001L
 #define P2PLL_CNTL__P2PLL_RESET                            0x00000001L
 #define P2PLL_CNTL__P2PLL_SLEEP_MASK                       0x00000002L
@@ -1041,7 +1075,7 @@
 #define P2PLL_CNTL__P2PLL_DISABLE_AUTO_RESET_MASK          0x00080000L
 #define P2PLL_CNTL__P2PLL_DISABLE_AUTO_RESET               0x00080000L
 
-// PIXCLKS_CNTL
+// pllPIXCLKS_CNTL
 #define	PIXCLKS_CNTL__PIX2CLK_SRC_SEL__SHIFT               0x00000000
 #define	PIXCLKS_CNTL__PIX2CLK_INVERT__SHIFT                0x00000004
 #define	PIXCLKS_CNTL__PIX2CLK_SRC_INVERT__SHIFT            0x00000005
@@ -1055,31 +1089,29 @@
 #define	PIXCLKS_CNTL__PIXCLK_TMDS_ALWAYS_ONb__SHIFT        0x0000000f
 
 
-// PIXCLKS_CNTL
+// pllPIXCLKS_CNTL
 #define PIXCLKS_CNTL__PIX2CLK_SRC_SEL_MASK                 0x00000003L
-#define PIXCLKS_CNTL__PIX2CLK_INVERT_MASK                  0x00000010L
 #define PIXCLKS_CNTL__PIX2CLK_INVERT                       0x00000010L
-#define PIXCLKS_CNTL__PIX2CLK_SRC_INVERT_MASK              0x00000020L
 #define PIXCLKS_CNTL__PIX2CLK_SRC_INVERT                   0x00000020L
-#define PIXCLKS_CNTL__PIX2CLK_ALWAYS_ONb_MASK              0x00000040L
 #define PIXCLKS_CNTL__PIX2CLK_ALWAYS_ONb                   0x00000040L
-#define PIXCLKS_CNTL__PIX2CLK_DAC_ALWAYS_ONb_MASK          0x00000080L
 #define PIXCLKS_CNTL__PIX2CLK_DAC_ALWAYS_ONb               0x00000080L
-#define PIXCLKS_CNTL__PIXCLK_TV_SRC_SEL_MASK               0x00000100L
 #define PIXCLKS_CNTL__PIXCLK_TV_SRC_SEL                    0x00000100L
-#define PIXCLKS_CNTL__PIXCLK_BLEND_ALWAYS_ONb_MASK         0x00000800L
 #define PIXCLKS_CNTL__PIXCLK_BLEND_ALWAYS_ONb              0x00000800L
-#define PIXCLKS_CNTL__PIXCLK_GV_ALWAYS_ONb_MASK            0x00001000L
 #define PIXCLKS_CNTL__PIXCLK_GV_ALWAYS_ONb                 0x00001000L
-#define PIXCLKS_CNTL__PIXCLK_DIG_TMDS_ALWAYS_ONb_MASK      0x00002000L
 #define PIXCLKS_CNTL__PIXCLK_DIG_TMDS_ALWAYS_ONb           0x00002000L
-#define PIXCLKS_CNTL__PIXCLK_LVDS_ALWAYS_ONb_MASK          0x00004000L
 #define PIXCLKS_CNTL__PIXCLK_LVDS_ALWAYS_ONb               0x00004000L
-#define PIXCLKS_CNTL__PIXCLK_TMDS_ALWAYS_ONb_MASK          0x00008000L
 #define PIXCLKS_CNTL__PIXCLK_TMDS_ALWAYS_ONb               0x00008000L
+#define PIXCLKS_CNTL__DISP_TVOUT_PIXCLK_TV_ALWAYS_ONb      (1 << 9)
+#define PIXCLKS_CNTL__R300_DVOCLK_ALWAYS_ONb               (1 << 10)
+#define PIXCLKS_CNTL__R300_PIXCLK_DVO_ALWAYS_ONb           (1 << 13)
+#define PIXCLKS_CNTL__R300_PIXCLK_TRANS_ALWAYS_ONb         (1 << 16)
+#define PIXCLKS_CNTL__R300_PIXCLK_TVO_ALWAYS_ONb           (1 << 17)
+#define PIXCLKS_CNTL__R300_P2G2CLK_ALWAYS_ONb              (1 << 18)
+#define PIXCLKS_CNTL__R300_P2G2CLK_DAC_ALWAYS_ONb          (1 << 19)
+#define PIXCLKS_CNTL__R300_DISP_DAC_PIXCLK_DAC2_BLANK_OFF  (1 << 23)
 
 
-// P2PLL_DIV_0
+// pllP2PLL_DIV_0
 #define P2PLL_DIV_0__P2PLL_FB_DIV_MASK                     0x000007ffL
 #define P2PLL_DIV_0__P2PLL_ATOMIC_UPDATE_W_MASK            0x00008000L
 #define P2PLL_DIV_0__P2PLL_ATOMIC_UPDATE_W                 0x00008000L
@@ -1087,124 +1119,97 @@
 #define P2PLL_DIV_0__P2PLL_ATOMIC_UPDATE_R                 0x00008000L
 #define P2PLL_DIV_0__P2PLL_POST_DIV_MASK                   0x00070000L
 
-// SCLK_CNTL_M6
-#define SCLK_CNTL_M6__SCLK_SRC_SEL_MASK                    0x00000007L
-#define SCLK_CNTL_M6__CP_MAX_DYN_STOP_LAT_MASK             0x00000008L
-#define SCLK_CNTL_M6__CP_MAX_DYN_STOP_LAT                  0x00000008L
-#define SCLK_CNTL_M6__HDP_MAX_DYN_STOP_LAT_MASK            0x00000010L
-#define SCLK_CNTL_M6__HDP_MAX_DYN_STOP_LAT                 0x00000010L
-#define SCLK_CNTL_M6__TV_MAX_DYN_STOP_LAT_MASK             0x00000020L
-#define SCLK_CNTL_M6__TV_MAX_DYN_STOP_LAT                  0x00000020L
-#define SCLK_CNTL_M6__E2_MAX_DYN_STOP_LAT_MASK             0x00000040L
-#define SCLK_CNTL_M6__E2_MAX_DYN_STOP_LAT                  0x00000040L
-#define SCLK_CNTL_M6__SE_MAX_DYN_STOP_LAT_MASK             0x00000080L
-#define SCLK_CNTL_M6__SE_MAX_DYN_STOP_LAT                  0x00000080L
-#define SCLK_CNTL_M6__IDCT_MAX_DYN_STOP_LAT_MASK           0x00000100L
-#define SCLK_CNTL_M6__IDCT_MAX_DYN_STOP_LAT                0x00000100L
-#define SCLK_CNTL_M6__VIP_MAX_DYN_STOP_LAT_MASK            0x00000200L
-#define SCLK_CNTL_M6__VIP_MAX_DYN_STOP_LAT                 0x00000200L
-#define SCLK_CNTL_M6__RE_MAX_DYN_STOP_LAT_MASK             0x00000400L
-#define SCLK_CNTL_M6__RE_MAX_DYN_STOP_LAT                  0x00000400L
-#define SCLK_CNTL_M6__PB_MAX_DYN_STOP_LAT_MASK             0x00000800L
-#define SCLK_CNTL_M6__PB_MAX_DYN_STOP_LAT                  0x00000800L
-#define SCLK_CNTL_M6__TAM_MAX_DYN_STOP_LAT_MASK            0x00001000L
-#define SCLK_CNTL_M6__TAM_MAX_DYN_STOP_LAT                 0x00001000L
-#define SCLK_CNTL_M6__TDM_MAX_DYN_STOP_LAT_MASK            0x00002000L
-#define SCLK_CNTL_M6__TDM_MAX_DYN_STOP_LAT                 0x00002000L
-#define SCLK_CNTL_M6__RB_MAX_DYN_STOP_LAT_MASK             0x00004000L
-#define SCLK_CNTL_M6__RB_MAX_DYN_STOP_LAT                  0x00004000L
-#define SCLK_CNTL_M6__FORCE_DISP2_MASK                     0x00008000L
-#define SCLK_CNTL_M6__FORCE_DISP2                          0x00008000L
-#define SCLK_CNTL_M6__FORCE_CP_MASK                        0x00010000L
-#define SCLK_CNTL_M6__FORCE_CP                             0x00010000L
-#define SCLK_CNTL_M6__FORCE_HDP_MASK                       0x00020000L
-#define SCLK_CNTL_M6__FORCE_HDP                            0x00020000L
-#define SCLK_CNTL_M6__FORCE_DISP1_MASK                     0x00040000L
-#define SCLK_CNTL_M6__FORCE_DISP1                          0x00040000L
-#define SCLK_CNTL_M6__FORCE_TOP_MASK                       0x00080000L
-#define SCLK_CNTL_M6__FORCE_TOP                            0x00080000L
-#define SCLK_CNTL_M6__FORCE_E2_MASK                        0x00100000L
-#define SCLK_CNTL_M6__FORCE_E2                             0x00100000L
-#define SCLK_CNTL_M6__FORCE_SE_MASK                        0x00200000L
-#define SCLK_CNTL_M6__FORCE_SE                             0x00200000L
-#define SCLK_CNTL_M6__FORCE_IDCT_MASK                      0x00400000L
-#define SCLK_CNTL_M6__FORCE_IDCT                           0x00400000L
-#define SCLK_CNTL_M6__FORCE_VIP_MASK                       0x00800000L
-#define SCLK_CNTL_M6__FORCE_VIP                            0x00800000L
-#define SCLK_CNTL_M6__FORCE_RE_MASK                        0x01000000L
-#define SCLK_CNTL_M6__FORCE_RE                             0x01000000L
-#define SCLK_CNTL_M6__FORCE_PB_MASK                        0x02000000L
-#define SCLK_CNTL_M6__FORCE_PB                             0x02000000L
-#define SCLK_CNTL_M6__FORCE_TAM_MASK                       0x04000000L
-#define SCLK_CNTL_M6__FORCE_TAM                            0x04000000L
-#define SCLK_CNTL_M6__FORCE_TDM_MASK                       0x08000000L
-#define SCLK_CNTL_M6__FORCE_TDM                            0x08000000L
-#define SCLK_CNTL_M6__FORCE_RB_MASK                        0x10000000L
-#define SCLK_CNTL_M6__FORCE_RB                             0x10000000L
-#define SCLK_CNTL_M6__FORCE_TV_SCLK_MASK                   0x20000000L
-#define SCLK_CNTL_M6__FORCE_TV_SCLK                        0x20000000L
-#define SCLK_CNTL_M6__FORCE_SUBPIC_MASK                    0x40000000L
-#define SCLK_CNTL_M6__FORCE_SUBPIC                         0x40000000L
-#define SCLK_CNTL_M6__FORCE_OV0_MASK                       0x80000000L
-#define SCLK_CNTL_M6__FORCE_OV0                            0x80000000L
+// pllSCLK_CNTL
+#define SCLK_CNTL__SCLK_SRC_SEL_MASK                    0x00000007L
+#define SCLK_CNTL__CP_MAX_DYN_STOP_LAT                  0x00000008L
+#define SCLK_CNTL__HDP_MAX_DYN_STOP_LAT                 0x00000010L
+#define SCLK_CNTL__TV_MAX_DYN_STOP_LAT                  0x00000020L
+#define SCLK_CNTL__E2_MAX_DYN_STOP_LAT                  0x00000040L
+#define SCLK_CNTL__SE_MAX_DYN_STOP_LAT                  0x00000080L
+#define SCLK_CNTL__IDCT_MAX_DYN_STOP_LAT                0x00000100L
+#define SCLK_CNTL__VIP_MAX_DYN_STOP_LAT                 0x00000200L
+#define SCLK_CNTL__RE_MAX_DYN_STOP_LAT                  0x00000400L
+#define SCLK_CNTL__PB_MAX_DYN_STOP_LAT                  0x00000800L
+#define SCLK_CNTL__TAM_MAX_DYN_STOP_LAT                 0x00001000L
+#define SCLK_CNTL__TDM_MAX_DYN_STOP_LAT                 0x00002000L
+#define SCLK_CNTL__RB_MAX_DYN_STOP_LAT                  0x00004000L
+#define SCLK_CNTL__DYN_STOP_LAT_MASK                     0x00007ff8
+#define SCLK_CNTL__FORCE_DISP2                          0x00008000L
+#define SCLK_CNTL__FORCE_CP                             0x00010000L
+#define SCLK_CNTL__FORCE_HDP                            0x00020000L
+#define SCLK_CNTL__FORCE_DISP1                          0x00040000L
+#define SCLK_CNTL__FORCE_TOP                            0x00080000L
+#define SCLK_CNTL__FORCE_E2                             0x00100000L
+#define SCLK_CNTL__FORCE_SE                             0x00200000L
+#define SCLK_CNTL__FORCE_IDCT                           0x00400000L
+#define SCLK_CNTL__FORCE_VIP                            0x00800000L
+#define SCLK_CNTL__FORCE_RE                             0x01000000L
+#define SCLK_CNTL__FORCE_PB                             0x02000000L
+#define SCLK_CNTL__FORCE_TAM                            0x04000000L
+#define SCLK_CNTL__FORCE_TDM                            0x08000000L
+#define SCLK_CNTL__FORCE_RB                             0x10000000L
+#define SCLK_CNTL__FORCE_TV_SCLK                        0x20000000L
+#define SCLK_CNTL__FORCE_SUBPIC                         0x40000000L
+#define SCLK_CNTL__FORCE_OV0                            0x80000000L
+#define SCLK_CNTL__R300_FORCE_VAP                       (1<<21)
+#define SCLK_CNTL__R300_FORCE_SR                        (1<<25)
+#define SCLK_CNTL__R300_FORCE_PX                        (1<<26)
+#define SCLK_CNTL__R300_FORCE_TX                        (1<<27)
+#define SCLK_CNTL__R300_FORCE_US                        (1<<28)
+#define SCLK_CNTL__R300_FORCE_SU                        (1<<30)
+#define SCLK_CNTL__FORCEON_MASK                         0xffff8000L
+
+// pllSCLK_CNTL2
+#define SCLK_CNTL2__R300_TCL_MAX_DYN_STOP_LAT           (1<<10)
+#define SCLK_CNTL2__R300_GA_MAX_DYN_STOP_LAT            (1<<11)
+#define SCLK_CNTL2__R300_CBA_MAX_DYN_STOP_LAT           (1<<12)
+#define SCLK_CNTL2__R300_FORCE_TCL                      (1<<13)
+#define SCLK_CNTL2__R300_FORCE_CBA                      (1<<14)
+#define SCLK_CNTL2__R300_FORCE_GA                       (1<<15)
 
 // SCLK_MORE_CNTL
-#define SCLK_MORE_CNTL__DISPREGS_MAX_DYN_STOP_LAT_MASK     0x00000001L
 #define SCLK_MORE_CNTL__DISPREGS_MAX_DYN_STOP_LAT          0x00000001L
-#define SCLK_MORE_CNTL__MC_GUI_MAX_DYN_STOP_LAT_MASK       0x00000002L
 #define SCLK_MORE_CNTL__MC_GUI_MAX_DYN_STOP_LAT            0x00000002L
-#define SCLK_MORE_CNTL__MC_HOST_MAX_DYN_STOP_LAT_MASK      0x00000004L
 #define SCLK_MORE_CNTL__MC_HOST_MAX_DYN_STOP_LAT           0x00000004L
-#define SCLK_MORE_CNTL__FORCE_DISPREGS_MASK                0x00000100L
 #define SCLK_MORE_CNTL__FORCE_DISPREGS                     0x00000100L
-#define SCLK_MORE_CNTL__FORCE_MC_GUI_MASK                  0x00000200L
 #define SCLK_MORE_CNTL__FORCE_MC_GUI                       0x00000200L
-#define SCLK_MORE_CNTL__FORCE_MC_HOST_MASK                 0x00000400L
 #define SCLK_MORE_CNTL__FORCE_MC_HOST                      0x00000400L
-#define SCLK_MORE_CNTL__STOP_SCLK_EN_MASK                  0x00001000L
 #define SCLK_MORE_CNTL__STOP_SCLK_EN                       0x00001000L
-#define SCLK_MORE_CNTL__STOP_SCLK_A_MASK                   0x00002000L
 #define SCLK_MORE_CNTL__STOP_SCLK_A                        0x00002000L
-#define SCLK_MORE_CNTL__STOP_SCLK_B_MASK                   0x00004000L
 #define SCLK_MORE_CNTL__STOP_SCLK_B                        0x00004000L
-#define SCLK_MORE_CNTL__STOP_SCLK_C_MASK                   0x00008000L
 #define SCLK_MORE_CNTL__STOP_SCLK_C                        0x00008000L
-#define SCLK_MORE_CNTL__HALF_SPEED_SCLK_MASK               0x00010000L
 #define SCLK_MORE_CNTL__HALF_SPEED_SCLK                    0x00010000L
-#define SCLK_MORE_CNTL__IO_CG_VOLTAGE_DROP_MASK            0x00020000L
 #define SCLK_MORE_CNTL__IO_CG_VOLTAGE_DROP                 0x00020000L
-#define SCLK_MORE_CNTL__TVFB_SOFT_RESET_MASK               0x00040000L
 #define SCLK_MORE_CNTL__TVFB_SOFT_RESET                    0x00040000L
-#define SCLK_MORE_CNTL__VOLTAGE_DROP_SYNC_MASK             0x00080000L
 #define SCLK_MORE_CNTL__VOLTAGE_DROP_SYNC                  0x00080000L
-#define SCLK_MORE_CNTL__VOLTAGE_DELAY_SEL_MASK             0x00300000L
-#define SCLK_MORE_CNTL__IDLE_DELAY_HALF_SCLK_MASK          0x00400000L
 #define SCLK_MORE_CNTL__IDLE_DELAY_HALF_SCLK               0x00400000L
-#define SCLK_MORE_CNTL__AGP_BUSY_HALF_SCLK_MASK            0x00800000L
 #define SCLK_MORE_CNTL__AGP_BUSY_HALF_SCLK                 0x00800000L
 #define SCLK_MORE_CNTL__CG_SPARE_RD_C_MASK                 0xff000000L
+#define SCLK_MORE_CNTL__FORCEON                            0x00000700L
 
-// MCLK_CNTL_M6
-#define MCLK_CNTL_M6__MCLKA_SRC_SEL_MASK                   0x00000007L
-#define MCLK_CNTL_M6__YCLKA_SRC_SEL_MASK                   0x00000070L
-#define MCLK_CNTL_M6__MCLKB_SRC_SEL_MASK                   0x00000700L
-#define MCLK_CNTL_M6__YCLKB_SRC_SEL_MASK                   0x00007000L
-#define MCLK_CNTL_M6__FORCE_MCLKA_MASK                     0x00010000L
-#define MCLK_CNTL_M6__FORCE_MCLKA                          0x00010000L
-#define MCLK_CNTL_M6__FORCE_MCLKB_MASK                     0x00020000L
-#define MCLK_CNTL_M6__FORCE_MCLKB                          0x00020000L
-#define MCLK_CNTL_M6__FORCE_YCLKA_MASK                     0x00040000L
-#define MCLK_CNTL_M6__FORCE_YCLKA                          0x00040000L
-#define MCLK_CNTL_M6__FORCE_YCLKB_MASK                     0x00080000L
-#define MCLK_CNTL_M6__FORCE_YCLKB                          0x00080000L
-#define MCLK_CNTL_M6__FORCE_MC_MASK                        0x00100000L
-#define MCLK_CNTL_M6__FORCE_MC                             0x00100000L
-#define MCLK_CNTL_M6__FORCE_AIC_MASK                       0x00200000L
-#define MCLK_CNTL_M6__FORCE_AIC                            0x00200000L
-#define MCLK_CNTL_M6__MRDCKA0_SOUTSEL_MASK                 0x03000000L
-#define MCLK_CNTL_M6__MRDCKA1_SOUTSEL_MASK                 0x0c000000L
-#define MCLK_CNTL_M6__MRDCKB0_SOUTSEL_MASK                 0x30000000L
-#define MCLK_CNTL_M6__MRDCKB1_SOUTSEL_MASK                 0xc0000000L
+// MCLK_CNTL
+#define MCLK_CNTL__MCLKA_SRC_SEL_MASK                   0x00000007L
+#define MCLK_CNTL__YCLKA_SRC_SEL_MASK                   0x00000070L
+#define MCLK_CNTL__MCLKB_SRC_SEL_MASK                   0x00000700L
+#define MCLK_CNTL__YCLKB_SRC_SEL_MASK                   0x00007000L
+#define MCLK_CNTL__FORCE_MCLKA_MASK                     0x00010000L
+#define MCLK_CNTL__FORCE_MCLKA                          0x00010000L
+#define MCLK_CNTL__FORCE_MCLKB_MASK                     0x00020000L
+#define MCLK_CNTL__FORCE_MCLKB                          0x00020000L
+#define MCLK_CNTL__FORCE_YCLKA_MASK                     0x00040000L
+#define MCLK_CNTL__FORCE_YCLKA                          0x00040000L
+#define MCLK_CNTL__FORCE_YCLKB_MASK                     0x00080000L
+#define MCLK_CNTL__FORCE_YCLKB                          0x00080000L
+#define MCLK_CNTL__FORCE_MC_MASK                        0x00100000L
+#define MCLK_CNTL__FORCE_MC                             0x00100000L
+#define MCLK_CNTL__FORCE_AIC_MASK                       0x00200000L
+#define MCLK_CNTL__FORCE_AIC                            0x00200000L
+#define MCLK_CNTL__MRDCKA0_SOUTSEL_MASK                 0x03000000L
+#define MCLK_CNTL__MRDCKA1_SOUTSEL_MASK                 0x0c000000L
+#define MCLK_CNTL__MRDCKB0_SOUTSEL_MASK                 0x30000000L
+#define MCLK_CNTL__MRDCKB1_SOUTSEL_MASK                 0xc0000000L
+#define MCLK_CNTL__R300_DISABLE_MC_MCLKA                (1 << 21)
+#define MCLK_CNTL__R300_DISABLE_MC_MCLKB                (1 << 21)
 
 // MCLK_MISC
 #define MCLK_MISC__SCLK_SOURCED_FROM_MPLL_SEL_MASK         0x00000003L
@@ -1238,19 +1243,14 @@
 
 // VCLK_ECP_CNTL
 #define VCLK_ECP_CNTL__VCLK_SRC_SEL_MASK                   0x00000003L
-#define VCLK_ECP_CNTL__VCLK_INVERT_MASK                    0x00000010L
 #define VCLK_ECP_CNTL__VCLK_INVERT                         0x00000010L
-#define VCLK_ECP_CNTL__PIXCLK_SRC_INVERT_MASK              0x00000020L
 #define VCLK_ECP_CNTL__PIXCLK_SRC_INVERT                   0x00000020L
-#define VCLK_ECP_CNTL__PIXCLK_ALWAYS_ONb_MASK              0x00000040L
 #define VCLK_ECP_CNTL__PIXCLK_ALWAYS_ONb                   0x00000040L
-#define VCLK_ECP_CNTL__PIXCLK_DAC_ALWAYS_ONb_MASK          0x00000080L
 #define VCLK_ECP_CNTL__PIXCLK_DAC_ALWAYS_ONb               0x00000080L
 #define VCLK_ECP_CNTL__ECP_DIV_MASK                        0x00000300L
-#define VCLK_ECP_CNTL__ECP_FORCE_ON_MASK                   0x00040000L
 #define VCLK_ECP_CNTL__ECP_FORCE_ON                        0x00040000L
-#define VCLK_ECP_CNTL__SUBCLK_FORCE_ON_MASK                0x00080000L
 #define VCLK_ECP_CNTL__SUBCLK_FORCE_ON                     0x00080000L
+#define VCLK_ECP_CNTL__R300_DISP_DAC_PIXCLK_DAC_BLANK_OFF  (1<<23)
 
 // PLL_PWRMGT_CNTL
 #define PLL_PWRMGT_CNTL__MPLL_TURNOFF_MASK                 0x00000001L
@@ -1282,54 +1282,54 @@
 #define PLL_PWRMGT_CNTL__SU_SUSTAIN_DISABLE                0x00080000L
 #define PLL_PWRMGT_CNTL__TCL_BYPASS_DISABLE_MASK           0x00100000L
 #define PLL_PWRMGT_CNTL__TCL_BYPASS_DISABLE                0x00100000L
-#define PLL_PWRMGT_CNTL__TCL_CLOCK_ACTIVE_RD_MASK          0x00200000L
+#define PLL_PWRMGT_CNTL__TCL_CLOCK_CTIVE_RD_MASK          0x00200000L
 #define PLL_PWRMGT_CNTL__TCL_CLOCK_ACTIVE_RD               0x00200000L
 #define PLL_PWRMGT_CNTL__CG_NO2_DEBUG_MASK                 0xff000000L
 
-// CLK_PWRMGT_CNTL_M6
-#define CLK_PWRMGT_CNTL_M6__MPLL_PWRMGT_OFF_MASK           0x00000001L
-#define CLK_PWRMGT_CNTL_M6__MPLL_PWRMGT_OFF                0x00000001L
-#define CLK_PWRMGT_CNTL_M6__SPLL_PWRMGT_OFF_MASK           0x00000002L
-#define CLK_PWRMGT_CNTL_M6__SPLL_PWRMGT_OFF                0x00000002L
-#define CLK_PWRMGT_CNTL_M6__PPLL_PWRMGT_OFF_MASK           0x00000004L
-#define CLK_PWRMGT_CNTL_M6__PPLL_PWRMGT_OFF                0x00000004L
-#define CLK_PWRMGT_CNTL_M6__P2PLL_PWRMGT_OFF_MASK          0x00000008L
-#define CLK_PWRMGT_CNTL_M6__P2PLL_PWRMGT_OFF               0x00000008L
-#define CLK_PWRMGT_CNTL_M6__MCLK_TURNOFF_MASK              0x00000010L
-#define CLK_PWRMGT_CNTL_M6__MCLK_TURNOFF                   0x00000010L
-#define CLK_PWRMGT_CNTL_M6__SCLK_TURNOFF_MASK              0x00000020L
-#define CLK_PWRMGT_CNTL_M6__SCLK_TURNOFF                   0x00000020L
-#define CLK_PWRMGT_CNTL_M6__PCLK_TURNOFF_MASK              0x00000040L
-#define CLK_PWRMGT_CNTL_M6__PCLK_TURNOFF                   0x00000040L
-#define CLK_PWRMGT_CNTL_M6__P2CLK_TURNOFF_MASK             0x00000080L
-#define CLK_PWRMGT_CNTL_M6__P2CLK_TURNOFF                  0x00000080L
-#define CLK_PWRMGT_CNTL_M6__MC_CH_MODE_MASK                0x00000100L
-#define CLK_PWRMGT_CNTL_M6__MC_CH_MODE                     0x00000100L
-#define CLK_PWRMGT_CNTL_M6__TEST_MODE_MASK                 0x00000200L
-#define CLK_PWRMGT_CNTL_M6__TEST_MODE                      0x00000200L
-#define CLK_PWRMGT_CNTL_M6__GLOBAL_PMAN_EN_MASK            0x00000400L
-#define CLK_PWRMGT_CNTL_M6__GLOBAL_PMAN_EN                 0x00000400L
-#define CLK_PWRMGT_CNTL_M6__ENGINE_DYNCLK_MODE_MASK        0x00001000L
-#define CLK_PWRMGT_CNTL_M6__ENGINE_DYNCLK_MODE             0x00001000L
-#define CLK_PWRMGT_CNTL_M6__ACTIVE_HILO_LAT_MASK           0x00006000L
-#define CLK_PWRMGT_CNTL_M6__DISP_DYN_STOP_LAT_MASK         0x00008000L
-#define CLK_PWRMGT_CNTL_M6__DISP_DYN_STOP_LAT              0x00008000L
-#define CLK_PWRMGT_CNTL_M6__MC_BUSY_MASK                   0x00010000L
-#define CLK_PWRMGT_CNTL_M6__MC_BUSY                        0x00010000L
-#define CLK_PWRMGT_CNTL_M6__MC_INT_CNTL_MASK               0x00020000L
-#define CLK_PWRMGT_CNTL_M6__MC_INT_CNTL                    0x00020000L
-#define CLK_PWRMGT_CNTL_M6__MC_SWITCH_MASK                 0x00040000L
-#define CLK_PWRMGT_CNTL_M6__MC_SWITCH                      0x00040000L
-#define CLK_PWRMGT_CNTL_M6__DLL_READY_MASK                 0x00080000L
-#define CLK_PWRMGT_CNTL_M6__DLL_READY                      0x00080000L
-#define CLK_PWRMGT_CNTL_M6__DISP_PM_MASK                   0x00100000L
-#define CLK_PWRMGT_CNTL_M6__DISP_PM                        0x00100000L
-#define CLK_PWRMGT_CNTL_M6__DYN_STOP_MODE_MASK             0x00e00000L
-#define CLK_PWRMGT_CNTL_M6__CG_NO1_DEBUG_MASK              0x3f000000L
-#define CLK_PWRMGT_CNTL_M6__TVPLL_PWRMGT_OFF_MASK          0x40000000L
-#define CLK_PWRMGT_CNTL_M6__TVPLL_PWRMGT_OFF               0x40000000L
-#define CLK_PWRMGT_CNTL_M6__TVCLK_TURNOFF_MASK             0x80000000L
-#define CLK_PWRMGT_CNTL_M6__TVCLK_TURNOFF                  0x80000000L
+// CLK_PWRMGT_CNTL
+#define CLK_PWRMGT_CNTL__MPLL_PWRMGT_OFF_MASK           0x00000001L
+#define CLK_PWRMGT_CNTL__MPLL_PWRMGT_OFF                0x00000001L
+#define CLK_PWRMGT_CNTL__SPLL_PWRMGT_OFF_MASK           0x00000002L
+#define CLK_PWRMGT_CNTL__SPLL_PWRMGT_OFF                0x00000002L
+#define CLK_PWRMGT_CNTL__PPLL_PWRMGT_OFF_MASK           0x00000004L
+#define CLK_PWRMGT_CNTL__PPLL_PWRMGT_OFF                0x00000004L
+#define CLK_PWRMGT_CNTL__P2PLL_PWRMGT_OFF_MASK          0x00000008L
+#define CLK_PWRMGT_CNTL__P2PLL_PWRMGT_OFF               0x00000008L
+#define CLK_PWRMGT_CNTL__MCLK_TURNOFF_MASK              0x00000010L
+#define CLK_PWRMGT_CNTL__MCLK_TURNOFF                   0x00000010L
+#define CLK_PWRMGT_CNTL__SCLK_TURNOFF_MASK              0x00000020L
+#define CLK_PWRMGT_CNTL__SCLK_TURNOFF                   0x00000020L
+#define CLK_PWRMGT_CNTL__PCLK_TURNOFF_MASK              0x00000040L
+#define CLK_PWRMGT_CNTL__PCLK_TURNOFF                   0x00000040L
+#define CLK_PWRMGT_CNTL__P2CLK_TURNOFF_MASK             0x00000080L
+#define CLK_PWRMGT_CNTL__P2CLK_TURNOFF                  0x00000080L
+#define CLK_PWRMGT_CNTL__MC_CH_MODE_MASK                0x00000100L
+#define CLK_PWRMGT_CNTL__MC_CH_MODE                     0x00000100L
+#define CLK_PWRMGT_CNTL__TEST_MODE_MASK                 0x00000200L
+#define CLK_PWRMGT_CNTL__TEST_MODE                      0x00000200L
+#define CLK_PWRMGT_CNTL__GLOBAL_PMAN_EN_MASK            0x00000400L
+#define CLK_PWRMGT_CNTL__GLOBAL_PMAN_EN                 0x00000400L
+#define CLK_PWRMGT_CNTL__ENGINE_DYNCLK_MODE_MASK        0x00001000L
+#define CLK_PWRMGT_CNTL__ENGINE_DYNCLK_MODE             0x00001000L
+#define CLK_PWRMGT_CNTL__ACTIVE_HILO_LAT_MASK           0x00006000L
+#define CLK_PWRMGT_CNTL__DISP_DYN_STOP_LAT_MASK         0x00008000L
+#define CLK_PWRMGT_CNTL__DISP_DYN_STOP_LAT              0x00008000L
+#define CLK_PWRMGT_CNTL__MC_BUSY_MASK                   0x00010000L
+#define CLK_PWRMGT_CNTL__MC_BUSY                        0x00010000L
+#define CLK_PWRMGT_CNTL__MC_INT_CNTL_MASK               0x00020000L
+#define CLK_PWRMGT_CNTL__MC_INT_CNTL                    0x00020000L
+#define CLK_PWRMGT_CNTL__MC_SWITCH_MASK                 0x00040000L
+#define CLK_PWRMGT_CNTL__MC_SWITCH                      0x00040000L
+#define CLK_PWRMGT_CNTL__DLL_READY_MASK                 0x00080000L
+#define CLK_PWRMGT_CNTL__DLL_READY                      0x00080000L
+#define CLK_PWRMGT_CNTL__DISP_PM_MASK                   0x00100000L
+#define CLK_PWRMGT_CNTL__DISP_PM                        0x00100000L
+#define CLK_PWRMGT_CNTL__DYN_STOP_MODE_MASK             0x00e00000L
+#define CLK_PWRMGT_CNTL__CG_NO1_DEBUG_MASK              0x3f000000L
+#define CLK_PWRMGT_CNTL__TVPLL_PWRMGT_OFF_MASK          0x40000000L
+#define CLK_PWRMGT_CNTL__TVPLL_PWRMGT_OFF               0x40000000L
+#define CLK_PWRMGT_CNTL__TVCLK_TURNOFF_MASK             0x80000000L
+#define CLK_PWRMGT_CNTL__TVCLK_TURNOFF                  0x80000000L
 
 // BUS_CNTL1
 #define BUS_CNTL1__PMI_IO_DISABLE_MASK                     0x00000001L
@@ -1876,53 +1876,63 @@
 #define MDLL_RDCKB__MRDCKB1_BP_SEL_MASK                    0x80000000L
 #define MDLL_RDCKB__MRDCKB1_BP_SEL                         0x80000000L
 
-#define pllVCLK_ECP_CNTL                            0x0008
-#define pllDISP_TEST_MACRO_RW_WRITE                 0x001A
-#define pllDISP_TEST_MACRO_RW_READ                  0x001B
-#define pllDISP_TEST_MACRO_RW_DATA                  0x001C
-#define pllDISP_TEST_MACRO_RW_CNTL                  0x001D
-#define pllPIXCLKS_CNTL                             0x002D
+#define MDLL_R300_RDCK__MRDCKA_SLEEP                       0x00000001L
+#define MDLL_R300_RDCK__MRDCKA_RESET                       0x00000002L
+#define MDLL_R300_RDCK__MRDCKB_SLEEP                       0x00000004L
+#define MDLL_R300_RDCK__MRDCKB_RESET                       0x00000008L
+#define MDLL_R300_RDCK__MRDCKC_SLEEP                       0x00000010L
+#define MDLL_R300_RDCK__MRDCKC_RESET                       0x00000020L
+#define MDLL_R300_RDCK__MRDCKD_SLEEP                       0x00000040L
+#define MDLL_R300_RDCK__MRDCKD_RESET                       0x00000080L
+
+#define pllCLK_PIN_CNTL                             0x0001
+#define pllPPLL_CNTL                                0x0002
+#define pllPPLL_REF_DIV                             0x0003
 #define pllPPLL_DIV_0                               0x0004
 #define pllPPLL_DIV_1                               0x0005
 #define pllPPLL_DIV_2                               0x0006
 #define pllPPLL_DIV_3                               0x0007
+#define pllVCLK_ECP_CNTL                            0x0008
 #define pllHTOTAL_CNTL                              0x0009
-#define pllPLL_TEST_CNTL_M6                         0x0013
-#define pllP2PLL_DIV_0                              0x002C
-#define pllHTOTAL2_CNTL                             0x002E
-#define pllCLK_PIN_CNTL                             0x0001
-#define pllPPLL_CNTL                                0x0002
-#define pllPPLL_REF_DIV                             0x0003
-#define pllSPLL_CNTL                                0x000C
-#define pllSPLL_AUX_CNTL                            0x0024
-#define pllSCLK_CNTL_M6                             0x000D
+#define pllM_SPLL_REF_FB_DIV                        0x000A
 #define pllAGP_PLL_CNTL                             0x000B
+#define pllSPLL_CNTL                                0x000C
+#define pllSCLK_CNTL                                0x000D
+#define pllMPLL_CNTL                                0x000E
+#define pllMDLL_CKO                                 0x000F
+#define pllMDLL_RDCKA                               0x0010
+#define pllMDLL_RDCKB                               0x0011
+#define pllMCLK_CNTL                                0x0012
+#define pllPLL_TEST_CNTL                            0x0013
+#define pllCLK_PWRMGT_CNTL                          0x0014
+#define pllPLL_PWRMGT_CNTL                          0x0015
+#define pllCG_TEST_MACRO_RW_WRITE                   0x0016
+#define pllCG_TEST_MACRO_RW_READ                    0x0017
+#define pllCG_TEST_MACRO_RW_DATA                    0x0018
+#define pllCG_TEST_MACRO_RW_CNTL                    0x0019
+#define pllDISP_TEST_MACRO_RW_WRITE                 0x001A
+#define pllDISP_TEST_MACRO_RW_READ                  0x001B
+#define pllDISP_TEST_MACRO_RW_DATA                  0x001C
+#define pllDISP_TEST_MACRO_RW_CNTL                  0x001D
+#define pllSCLK_CNTL2                               0x001E
+#define pllMCLK_MISC                                0x001F
 #define pllTV_PLL_FINE_CNTL                         0x0020
 #define pllTV_PLL_CNTL                              0x0021
 #define pllTV_PLL_CNTL1                             0x0022
 #define pllTV_DTO_INCREMENTS                        0x0023
+#define pllSPLL_AUX_CNTL                            0x0024
+#define pllMPLL_AUX_CNTL                            0x0025
 #define pllP2PLL_CNTL                               0x002A
 #define pllP2PLL_REF_DIV                            0x002B
+#define pllP2PLL_DIV_0                              0x002C
+#define pllPIXCLKS_CNTL                             0x002D
+#define pllHTOTAL2_CNTL                             0x002E
 #define pllSSPLL_CNTL                               0x0030
 #define pllSSPLL_REF_DIV                            0x0031
 #define pllSSPLL_DIV_0                              0x0032
 #define pllSS_INT_CNTL                              0x0033
 #define pllSS_TST_CNTL                              0x0034
 #define pllSCLK_MORE_CNTL                           0x0035
-#define pllCLK_PWRMGT_CNTL_M6                       0x0014
-#define pllPLL_PWRMGT_CNTL                          0x0015
-#define pllM_SPLL_REF_FB_DIV                        0x000A
-#define pllMPLL_CNTL                                0x000E
-#define pllMPLL_AUX_CNTL                            0x0025
-#define pllMDLL_CKO                                 0x000F
-#define pllMDLL_RDCKA                               0x0010
-#define pllMDLL_RDCKB                               0x0011
-#define pllMCLK_CNTL_M6                             0x0012
-#define pllMCLK_MISC                                0x001F
-#define pllCG_TEST_MACRO_RW_WRITE                   0x0016
-#define pllCG_TEST_MACRO_RW_READ                    0x0017
-#define pllCG_TEST_MACRO_RW_DATA                    0x0018
-#define pllCG_TEST_MACRO_RW_CNTL                    0x0019
 
 #define ixMC_PERF_CNTL                             0x0000
 #define ixMC_PERF_SEL                              0x0001
@@ -1945,7 +1955,29 @@
 #define ixMC_BIST_CTRL                             0x0012
 #define ixREG_COLLAR_WRITE                         0x0013
 #define ixREG_COLLAR_READ                          0x0014
-
+#define ixR300_MC_IMP_CNTL                         0x0018
+#define ixR300_MC_CHP_IO_CNTL_A0                   0x0019
+#define ixR300_MC_CHP_IO_CNTL_A1                   0x001a
+#define ixR300_MC_CHP_IO_CNTL_B0                   0x001b
+#define ixR300_MC_CHP_IO_CNTL_B1                   0x001c
+#define ixR300_MC_CHP_IO_CNTL_C0                   0x001d
+#define ixR300_MC_CHP_IO_CNTL_C1                   0x001e
+#define ixR300_MC_CHP_IO_CNTL_D0                   0x001f
+#define ixR300_MC_CHP_IO_CNTL_D1                   0x0020
+#define ixR300_MC_IMP_CNTL_0                       0x0021
+#define ixR300_MC_ELPIDA_CNTL                      0x0022
+#define ixR300_MC_CHP_IO_OE_CNTL_CD                0x0023
+#define ixR300_MC_READ_CNTL_CD                     0x0024
+#define ixR300_MC_MC_INIT_WR_LAT_TIMER             0x0025
+#define ixR300_MC_DEBUG_CNTL                       0x0026
+#define ixR300_MC_BIST_CNTL_0                      0x0028
+#define ixR300_MC_BIST_CNTL_1                      0x0029
+#define ixR300_MC_BIST_CNTL_2                      0x002a
+#define ixR300_MC_BIST_CNTL_3                      0x002b
+#define ixR300_MC_BIST_CNTL_4                      0x002c
+#define ixR300_MC_BIST_CNTL_5                      0x002d
+#define ixR300_MC_IMP_STATUS                       0x002e
+#define ixR300_MC_DLL_CNTL                         0x002f
 #define NB_TOM                                     0x15C
 
 
diff -Nru a/include/video/w100fb.h b/include/video/w100fb.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/video/w100fb.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,21 @@
+/*
+ *  Support for the w100 frame buffer.
+ *
+ *  Copyright (c) 2004 Richard Purdie
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ */
+
+/*
+ * This structure describes the machine which we are running on.
+ * It is set by machine specific code and used in the probe routine
+ * of drivers/video/w100fb.c
+ */
+
+struct w100fb_mach_info {
+	void (*w100fb_ssp_send)(u8 adrs, u8 data);
+	int comadj;
+	int phadadj;
+};
diff -Nru a/init/Kconfig b/init/Kconfig
--- a/init/Kconfig	2005-03-01 23:39:09 -08:00
+++ b/init/Kconfig	2005-03-01 23:39:09 -08:00
@@ -195,20 +195,9 @@
 	bool "Support for hot-pluggable devices" if !ARCH_S390
 	default ARCH_S390
 	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.
+	  This option is provided for the case where no in-kernel-tree
+	  modules require HOTPLUG functionality, but a module built
+	  outside the kernel tree does. Such modules require Y here.
 
 config KOBJECT_UEVENT
 	bool "Kernel Userspace Events"
@@ -316,8 +305,9 @@
 	  If unsure, say N.
 
 config SHMEM
+	bool "Use full shmem filesystem" if EMBEDDED
 	default y
-	bool "Use full shmem filesystem" if EMBEDDED && MMU
+	depends on MMU
 	help
 	  The shmem is an internal filesystem used to manage shared memory.
 	  It is backed by swap and manages resource limits. It is also exported
@@ -420,7 +410,7 @@
 
 config MODVERSIONS
 	bool "Module versioning support (EXPERIMENTAL)"
-	depends on MODULES && EXPERIMENTAL
+	depends on MODULES && EXPERIMENTAL && !USERMODE
 	help
 	  Usually, you have to use modules compiled with your kernel.
 	  Saying Y here makes it sometimes possible to use modules
diff -Nru a/init/Makefile b/init/Makefile
--- a/init/Makefile	2005-03-01 23:38:56 -08:00
+++ b/init/Makefile	2005-03-01 23:38:56 -08:00
@@ -3,6 +3,8 @@
 #
 
 obj-y				:= main.o version.o mounts.o initramfs.o
+obj-$(CONFIG_GENERIC_CALIBRATE_DELAY) += calibrate.o
+
 mounts-y			:= do_mounts.o
 mounts-$(CONFIG_DEVFS_FS)	+= do_mounts_devfs.o
 mounts-$(CONFIG_BLK_DEV_RAM)	+= do_mounts_rd.o
diff -Nru a/init/calibrate.c b/init/calibrate.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/init/calibrate.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,79 @@
+/* calibrate.c: default delay calibration
+ *
+ * Excised from init/main.c
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ */
+
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+
+static unsigned long preset_lpj;
+static int __init lpj_setup(char *str)
+{
+	preset_lpj = simple_strtoul(str,NULL,0);
+	return 1;
+}
+
+__setup("lpj=", lpj_setup);
+
+/*
+ * 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
+ * better than 1%
+ */
+#define LPS_PREC 8
+
+void __devinit calibrate_delay(void)
+{
+	unsigned long ticks, loopbit;
+	int lps_precision = LPS_PREC;
+
+	if (preset_lpj) {
+		loops_per_jiffy = preset_lpj;
+		printk("Calibrating delay loop (skipped)... "
+			"%lu.%02lu BogoMIPS preset\n",
+			loops_per_jiffy/(500000/HZ),
+			(loops_per_jiffy/(5000/HZ)) % 100);
+	} else {
+		loops_per_jiffy = (1<<12);
+
+		printk(KERN_DEBUG "Calibrating delay loop... ");
+		while ((loops_per_jiffy <<= 1) != 0) {
+			/* wait for "start of" clock tick */
+			ticks = jiffies;
+			while (ticks == jiffies)
+				/* nothing */;
+			/* Go .. */
+			ticks = jiffies;
+			__delay(loops_per_jiffy);
+			ticks = jiffies - ticks;
+			if (ticks)
+				break;
+		}
+
+		/*
+		 * Do a binary approximation to get loops_per_jiffy set to
+		 * equal one clock (up to lps_precision bits)
+		 */
+		loops_per_jiffy >>= 1;
+		loopbit = loops_per_jiffy;
+		while (lps_precision-- && (loopbit >>= 1)) {
+			loops_per_jiffy |= loopbit;
+			ticks = jiffies;
+			while (ticks == jiffies)
+				/* nothing */;
+			ticks = jiffies;
+			__delay(loops_per_jiffy);
+			if (jiffies != ticks)	/* longer than 1 tick */
+				loops_per_jiffy &= ~loopbit;
+		}
+
+		/* Round the value and print it */
+		printk("%lu.%02lu BogoMIPS (lpj=%lu)\n",
+			loops_per_jiffy/(500000/HZ),
+			(loops_per_jiffy/(5000/HZ)) % 100,
+			loops_per_jiffy);
+	}
+
+}
diff -Nru a/init/do_mounts.c b/init/do_mounts.c
--- a/init/do_mounts.c	2005-03-01 23:38:55 -08:00
+++ b/init/do_mounts.c	2005-03-01 23:38:55 -08:00
@@ -6,6 +6,7 @@
 #include <linux/suspend.h>
 #include <linux/root_dev.h>
 #include <linux/security.h>
+#include <linux/delay.h>
 
 #include <linux/nfs_fs.h>
 #include <linux/nfs_fs_sb.h>
@@ -228,8 +229,16 @@
 	return 1;
 }
 
+static unsigned int __initdata root_delay;
+static int __init root_delay_setup(char *str)
+{
+	root_delay = simple_strtoul(str, NULL, 0);
+	return 1;
+}
+
 __setup("rootflags=", root_data_setup);
 __setup("rootfstype=", fs_names_setup);
+__setup("rootdelay=", root_delay_setup);
 
 static void __init get_fs_names(char *page)
 {
@@ -386,6 +395,12 @@
 	int is_floppy;
 
 	mount_devfs();
+
+	if (root_delay) {
+		printk(KERN_INFO "Waiting %dsec before mounting root device...\n",
+		       root_delay);
+		ssleep(root_delay);
+	}
 
 	md_run_setup();
 
diff -Nru a/init/do_mounts_md.c b/init/do_mounts_md.c
--- a/init/do_mounts_md.c	2005-03-01 23:39:16 -08:00
+++ b/init/do_mounts_md.c	2005-03-01 23:39:16 -08:00
@@ -232,6 +232,16 @@
 			err = sys_ioctl(fd, RUN_ARRAY, 0);
 		if (err)
 			printk(KERN_WARNING "md: starting md%d failed\n", minor);
+		else {
+			/* reread the partition table.
+			 * I (neilb) and not sure why this is needed, but I cannot
+			 * boot a kernel with devfs compiled in from partitioned md
+			 * array without it
+			 */
+			sys_close(fd);
+			fd = sys_open(name, 0, 0);
+			sys_ioctl(fd, BLKRRPART, 0);
+		}
 		sys_close(fd);
 	}
 }
diff -Nru a/init/initramfs.c b/init/initramfs.c
--- a/init/initramfs.c	2005-03-01 23:38:52 -08:00
+++ b/init/initramfs.c	2005-03-01 23:38:52 -08:00
@@ -26,7 +26,7 @@
 
 /* link hash */
 
-static struct hash {
+static __initdata struct hash {
 	int ino, minor, major;
 	struct hash *next;
 	char *name;
@@ -241,10 +241,9 @@
 static int __init do_name(void)
 {
 	state = SkipIt;
-	next_state = Start;
+	next_state = Reset;
 	if (strcmp(collected, "TRAILER!!!") == 0) {
 		free_hash();
-		next_state = Reset;
 		return 0;
 	}
 	if (dry_run)
@@ -295,7 +294,7 @@
 	sys_symlink(collected + N_ALIGN(name_len), collected);
 	sys_lchown(collected, uid, gid);
 	state = SkipIt;
-	next_state = Start;
+	next_state = Reset;
 	return 0;
 }
 
@@ -331,6 +330,10 @@
 			buf += written;
 			len -= written;
 			state = Start;
+		} else if (c == 0) {
+			buf += written;
+			len -= written;
+			state = Reset;
 		} else
 			error("junk in compressed archive");
 	}
@@ -410,7 +413,7 @@
 	outcnt = 0;
 }
 
-char * __init unpack_to_rootfs(char *buf, unsigned len, int check_only)
+static char * __init unpack_to_rootfs(char *buf, unsigned len, int check_only)
 {
 	int written;
 	dry_run = check_only;
@@ -460,15 +463,15 @@
 	return message;
 }
 
-extern char __initramfs_start, __initramfs_end;
+extern char __initramfs_start[], __initramfs_end[];
 #ifdef CONFIG_BLK_DEV_INITRD
 #include <linux/initrd.h>
 #endif
 
 void __init populate_rootfs(void)
 {
-	char *err = unpack_to_rootfs(&__initramfs_start,
-			 &__initramfs_end - &__initramfs_start, 0);
+	char *err = unpack_to_rootfs(__initramfs_start,
+			 __initramfs_end - __initramfs_start, 0);
 	if (err)
 		panic(err);
 #ifdef CONFIG_BLK_DEV_INITRD
diff -Nru a/init/main.c b/init/main.c
--- a/init/main.c	2005-03-01 23:38:53 -08:00
+++ b/init/main.c	2005-03-01 23:38:53 -08:00
@@ -75,8 +75,6 @@
 #error Sorry, your GCC is too old. It builds incorrect kernels.
 #endif
 
-extern char *linux_banner;
-
 static int init(void *);
 
 extern void init_IRQ(void);
@@ -157,12 +155,13 @@
 char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
 static const char *panic_later, *panic_param;
 
+extern struct obs_kernel_param __setup_start[], __setup_end[];
+
 static int __init obsolete_checksetup(char *line)
 {
 	struct obs_kernel_param *p;
-	extern struct obs_kernel_param __setup_start, __setup_end;
 
-	p = &__setup_start;
+	p = __setup_start;
 	do {
 		int n = strlen(p->str);
 		if (!strncmp(line, p->str, n)) {
@@ -179,19 +178,10 @@
 				return 1;
 		}
 		p++;
-	} while (p < &__setup_end);
+	} while (p < __setup_end);
 	return 0;
 }
 
-static unsigned long preset_lpj;
-static int __init lpj_setup(char *str)
-{
-	preset_lpj = simple_strtoul(str,NULL,0);
-	return 1;
-}
-
-__setup("lpj=", lpj_setup);
-
 /*
  * This should be approx 2 Bo*oMips to start (note initial shift), and will
  * still work even if initially too large, it will just take slightly longer
@@ -200,67 +190,6 @@
 
 EXPORT_SYMBOL(loops_per_jiffy);
 
-/*
- * 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
- * better than 1%
- */
-#define LPS_PREC 8
-
-void __devinit calibrate_delay(void)
-{
-	unsigned long ticks, loopbit;
-	int lps_precision = LPS_PREC;
-
-	if (preset_lpj) {
-		loops_per_jiffy = preset_lpj;
-		printk("Calibrating delay loop (skipped)... "
-			"%lu.%02lu BogoMIPS preset\n",
-			loops_per_jiffy/(500000/HZ),
-			(loops_per_jiffy/(5000/HZ)) % 100);
-	} else {
-		loops_per_jiffy = (1<<12);
-
-		printk(KERN_DEBUG "Calibrating delay loop... ");
-		while ((loops_per_jiffy <<= 1) != 0) {
-			/* wait for "start of" clock tick */
-			ticks = jiffies;
-			while (ticks == jiffies)
-				/* nothing */;
-			/* Go .. */
-			ticks = jiffies;
-			__delay(loops_per_jiffy);
-			ticks = jiffies - ticks;
-			if (ticks)
-				break;
-		}
-
-		/*
-		 * Do a binary approximation to get loops_per_jiffy set to
-		 * equal one clock (up to lps_precision bits)
-		 */
-		loops_per_jiffy >>= 1;
-		loopbit = loops_per_jiffy;
-		while (lps_precision-- && (loopbit >>= 1)) {
-			loops_per_jiffy |= loopbit;
-			ticks = jiffies;
-			while (ticks == jiffies)
-				/* nothing */;
-			ticks = jiffies;
-			__delay(loops_per_jiffy);
-			if (jiffies != ticks)	/* longer than 1 tick */
-				loops_per_jiffy &= ~loopbit;
-		}
-
-		/* Round the value and print it */
-		printk("%lu.%02lu BogoMIPS (lpj=%lu)\n",
-			loops_per_jiffy/(500000/HZ),
-			(loops_per_jiffy/(5000/HZ)) % 100,
-			loops_per_jiffy);
-	}
-
-}
-
 static int __init debug_kernel(char *str)
 {
 	if (*str)
@@ -359,7 +288,6 @@
 __setup("init=", init_setup);
 
 extern void setup_arch(char **);
-extern void cpu_idle(void);
 
 #ifndef CONFIG_SMP
 
@@ -446,16 +374,16 @@
 	kernel_thread(init, NULL, CLONE_FS | CLONE_SIGHAND);
 	numa_default_policy();
 	unlock_kernel();
- 	cpu_idle();
+	preempt_enable_no_resched();
+	cpu_idle();
 } 
 
 /* Check for early params. */
 static int __init do_early_param(char *param, char *val)
 {
 	struct obs_kernel_param *p;
-	extern struct obs_kernel_param __setup_start, __setup_end;
 
-	for (p = &__setup_start; p < &__setup_end; p++) {
+	for (p = __setup_start; p < __setup_end; p++) {
 		if (p->early && strcmp(param, p->str) == 0) {
 			if (p->setup_func(val) != 0)
 				printk(KERN_WARNING
@@ -511,6 +439,11 @@
 	 * time - but meanwhile we still have a functioning scheduler.
 	 */
 	sched_init();
+	/*
+	 * Disable preemption - early bootup scheduling is extremely
+	 * fragile until we cpu_idle() for the first time.
+	 */
+	preempt_disable();
 	build_all_zonelists();
 	page_alloc_init();
 	printk("Kernel command line: %s\n", saved_command_line);
@@ -592,14 +525,14 @@
 
 struct task_struct *child_reaper = &init_task;
 
-extern initcall_t __initcall_start, __initcall_end;
+extern initcall_t __initcall_start[], __initcall_end[];
 
 static void __init do_initcalls(void)
 {
 	initcall_t *call;
 	int count = preempt_count();
 
-	for (call = &__initcall_start; call < &__initcall_end; call++) {
+	for (call = __initcall_start; call < __initcall_end; call++) {
 		char *msg;
 
 		if (initcall_debug) {
@@ -761,16 +694,3 @@
 
 	panic("No init found.  Try passing init= option to kernel.");
 }
-
-static int early_param_test(char *rest)
-{
-	printk("early_parm_test: %s\n", rest ?: "(null)");
-	return rest ? 0 : -EINVAL;
-}
-early_param("testsetup", early_param_test);
-static int early_setup_test(char *rest)
-{
-	printk("early_setup_test: %s\n", rest ?: "(null)");
-	return 0;
-}
-__setup("testsetup_long", early_setup_test);
diff -Nru a/init/version.c b/init/version.c
--- a/init/version.c	2005-03-01 23:38:57 -08:00
+++ b/init/version.c	2005-03-01 23:38:57 -08:00
@@ -28,6 +28,6 @@
 
 EXPORT_SYMBOL(system_utsname);
 
-const char *linux_banner = 
+const char linux_banner[] =
 	"Linux version " UTS_RELEASE " (" LINUX_COMPILE_BY "@"
 	LINUX_COMPILE_HOST ") (" LINUX_COMPILER ") " UTS_VERSION "\n";
diff -Nru a/ipc/sem.c b/ipc/sem.c
--- a/ipc/sem.c	2005-03-01 23:38:55 -08:00
+++ b/ipc/sem.c	2005-03-01 23:38:55 -08:00
@@ -358,8 +358,22 @@
 		if (error <= 0) {
 			struct sem_queue *n;
 			remove_from_queue(sma,q);
-			n = q->next;
 			q->status = IN_WAKEUP;
+			/*
+			 * Continue scanning. The next operation
+			 * that must be checked depends on the type of the
+			 * completed operation:
+			 * - if the operation modified the array, then
+			 *   restart from the head of the queue and
+			 *   check for threads that might be waiting
+			 *   for semaphore values to become 0.
+			 * - if the operation didn't modify the array,
+			 *   then just continue.
+			 */
+			if (q->alter)
+				n = sma->sem_pending;
+			else
+				n = q->next;
 			wake_up_process(q->sleeper);
 			/* hands-off: q will disappear immediately after
 			 * writing q->status.
@@ -1119,8 +1133,11 @@
 		goto out_unlock_free;
 
 	error = try_atomic_semop (sma, sops, nsops, un, current->tgid);
-	if (error <= 0)
-		goto update;
+	if (error <= 0) {
+		if (alter && error == 0)
+			update_queue (sma);
+		goto out_unlock_free;
+	}
 
 	/* We need to sleep on this operation, so we put the current
 	 * task into the pending queue and go to sleep.
@@ -1132,6 +1149,7 @@
 	queue.undo = un;
 	queue.pid = current->tgid;
 	queue.id = semid;
+	queue.alter = alter;
 	if (alter)
 		append_to_queue(sma ,&queue);
 	else
@@ -1183,9 +1201,6 @@
 	remove_from_queue(sma,&queue);
 	goto out_unlock_free;
 
-update:
-	if (alter)
-		update_queue (sma);
 out_unlock_free:
 	sem_unlock(sma);
 out_free:
diff -Nru a/kernel/acct.c b/kernel/acct.c
--- a/kernel/acct.c	2005-03-01 23:38:58 -08:00
+++ b/kernel/acct.c	2005-03-01 23:38:58 -08:00
@@ -528,3 +528,36 @@
 	do_acct_process(exitcode, file);
 	fput(file);
 }
+
+
+/*
+ * acct_update_integrals
+ *    -  update mm integral fields in task_struct
+ */
+void acct_update_integrals(void)
+{
+	struct task_struct *tsk = current;
+
+	if (likely(tsk->mm)) {
+		long delta = tsk->stime - tsk->acct_stimexpd;
+
+		if (delta == 0)
+			return;
+		tsk->acct_stimexpd = tsk->stime;
+		tsk->acct_rss_mem1 += delta * tsk->mm->rss;
+		tsk->acct_vm_mem1 += delta * tsk->mm->total_vm;
+	}
+}
+
+/*
+ * acct_clear_integrals
+ *    - clear the mm integral fields in task_struct
+ */
+void acct_clear_integrals(struct task_struct *tsk)
+{
+	if (tsk) {
+		tsk->acct_stimexpd = 0;
+		tsk->acct_rss_mem1 = 0;
+		tsk->acct_vm_mem1 = 0;
+	}
+}
diff -Nru a/kernel/audit.c b/kernel/audit.c
--- a/kernel/audit.c	2005-03-01 23:39:18 -08:00
+++ b/kernel/audit.c	2005-03-01 23:39:18 -08:00
@@ -98,8 +98,8 @@
  * The second list 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 spinlock_t  audit_txlist_lock = SPIN_LOCK_UNLOCKED;
-static spinlock_t  audit_freelist_lock = SPIN_LOCK_UNLOCKED;
+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);
@@ -145,6 +145,11 @@
 	int		     count; /* Times requeued */
 };
 
+void audit_set_type(struct audit_buffer *ab, int type)
+{
+	ab->type = type;
+}
+
 struct audit_entry {
 	struct list_head  list;
 	struct audit_rule rule;
@@ -160,7 +165,7 @@
 		printk(KERN_ERR "audit: %s\n", message);
 		break;
 	case AUDIT_FAIL_PANIC:
-		panic(message);
+		panic("audit: %s\n", message);
 		break;
 	}
 }
@@ -169,7 +174,7 @@
 {
 	static unsigned long	last_check = 0;
 	static int		messages   = 0;
-	static spinlock_t	lock	   = SPIN_LOCK_UNLOCKED;
+	static DEFINE_SPINLOCK(lock);
 	unsigned long		flags;
 	unsigned long		now;
 	unsigned long		elapsed;
@@ -199,7 +204,7 @@
 void audit_log_lost(const char *message)
 {
 	static unsigned long	last_msg = 0;
-	static spinlock_t	lock     = SPIN_LOCK_UNLOCKED;
+	static DEFINE_SPINLOCK(lock);
 	unsigned long		flags;
 	unsigned long		now;
 	int			print;
@@ -300,21 +305,53 @@
 		kfree_skb(skb);
 }
 
+/*
+ * Check for appropriate CAP_AUDIT_ capabilities on incoming audit
+ * control messages.
+ */
+static int audit_netlink_ok(kernel_cap_t eff_cap, u16 msg_type)
+{
+	int err = 0;
+
+	switch (msg_type) {
+	case AUDIT_GET:
+	case AUDIT_LIST:
+	case AUDIT_SET:
+	case AUDIT_ADD:
+	case AUDIT_DEL:
+		if (!cap_raised(eff_cap, CAP_AUDIT_CONTROL))
+			err = -EPERM;
+		break;
+	case AUDIT_USER:
+		if (!cap_raised(eff_cap, CAP_AUDIT_WRITE))
+			err = -EPERM;
+		break;
+	default:  /* bad msg */
+		err = -EINVAL;
+	}
+
+	return err;
+}
+
 static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
 {
 	u32			uid, pid, seq;
 	void			*data;
 	struct audit_status	*status_get, status_set;
-	struct audit_login	*login;
-	int			err = 0;
+	int			err;
 	struct audit_buffer	*ab;
+	u16			msg_type = nlh->nlmsg_type;
+
+	err = audit_netlink_ok(NETLINK_CB(skb).eff_cap, msg_type);
+	if (err)
+		return err;
 
 	pid  = NETLINK_CREDS(skb)->pid;
 	uid  = NETLINK_CREDS(skb)->uid;
 	seq  = nlh->nlmsg_seq;
 	data = NLMSG_DATA(nlh);
 
-	switch (nlh->nlmsg_type) {
+	switch (msg_type) {
 	case AUDIT_GET:
 		status_set.enabled	 = audit_enabled;
 		status_set.failure	 = audit_failure;
@@ -323,12 +360,12 @@
 		status_set.backlog_limit = audit_backlog_limit;
 		status_set.lost		 = atomic_read(&audit_lost);
 		status_set.backlog	 = atomic_read(&audit_backlog);
-		audit_send_reply(pid, seq, AUDIT_GET, 0, 0,
+		audit_send_reply(NETLINK_CB(skb).pid, seq, AUDIT_GET, 0, 0,
 				 &status_set, sizeof(status_set));
 		break;
 	case AUDIT_SET:
-		if (!capable(CAP_SYS_ADMIN))
-			return -EPERM;
+		if (nlh->nlmsg_len < sizeof(struct audit_status))
+			return -EINVAL;
 		status_get   = (struct audit_status *)data;
 		if (status_get->mask & AUDIT_STATUS_ENABLED) {
 			err = audit_set_enabled(status_get->enabled);
@@ -363,33 +400,15 @@
 		ab->pid  = pid;
 		audit_log_end(ab);
 		break;
-	case AUDIT_LOGIN:
-		if (!capable(CAP_SYS_ADMIN))
-			return -EPERM;
-		login = (struct audit_login *)data;
-		ab = audit_log_start(NULL);
-		if (ab) {
-			audit_log_format(ab, "login pid=%d uid=%d loginuid=%d"
-					 " length=%d msg='%.1024s'",
-					 pid, uid,
-					 login->loginuid,
-					 login->msglen,
-					 login->msg);
-			ab->type = AUDIT_LOGIN;
-			ab->pid  = pid;
-			audit_log_end(ab);
-		}
-#ifdef CONFIG_AUDITSYSCALL
-		err = audit_set_loginuid(current->audit_context,
-					 login->loginuid);
-#endif
-		break;
-	case AUDIT_LIST:
 	case AUDIT_ADD:
 	case AUDIT_DEL:
+		if (nlh->nlmsg_len < sizeof(struct audit_rule))
+			return -EINVAL;
+		/* fallthrough */
+	case AUDIT_LIST:
 #ifdef CONFIG_AUDITSYSCALL
-		err = audit_receive_filter(nlh->nlmsg_type, pid, uid, seq,
-					   data);
+		err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid,
+					   uid, seq, data);
 #else
 		err = -EOPNOTSUPP;
 #endif
@@ -419,7 +438,7 @@
 		if (rlen > skb->len)
 			rlen = skb->len;
 		if ((err = audit_receive_msg(skb, nlh))) {
-			netlink_ack(skb, nlh, -err);
+			netlink_ack(skb, nlh, err);
 		} else if (nlh->nlmsg_flags & NLM_F_ACK)
 			netlink_ack(skb, nlh, 0);
 		skb_pull(skb, rlen);
@@ -457,6 +476,10 @@
 	char		*start;
 	int		extra = ab->nlh ? 0 : NLMSG_SPACE(0);
 
+	/* possible resubmission */
+	if (ab->len == 0)
+		return;
+
 	skb = skb_peek(&ab->sklist);
 	if (!skb || skb_tailroom(skb) <= ab->len + extra) {
 		skb = alloc_skb(2 * ab->len + extra, GFP_ATOMIC);
@@ -498,6 +521,7 @@
 		}
 		if (retval == -EAGAIN && ab->count < 5) {
 			++ab->count;
+			skb_queue_tail(&ab->sklist, skb);
 			audit_log_end_irq(ab);
 			return 1;
 		}
@@ -621,10 +645,10 @@
 
 	if (!ab)
 		ab = kmalloc(sizeof(*ab), GFP_ATOMIC);
-	if (!ab)
-		audit_log_lost("audit: out of memory in audit_log_start");
-	if (!ab)
+	if (!ab) {
+		audit_log_lost("out of memory in audit_log_start");
 		return NULL;
+	}
 
 	atomic_inc(&audit_backlog);
 	skb_queue_head_init(&ab->sklist);
diff -Nru a/kernel/auditsc.c b/kernel/auditsc.c
--- a/kernel/auditsc.c	2005-03-01 23:39:08 -08:00
+++ b/kernel/auditsc.c	2005-03-01 23:39:08 -08:00
@@ -250,8 +250,6 @@
 		audit_send_reply(pid, seq, AUDIT_LIST, 1, 1, NULL, 0);
 		break;
 	case AUDIT_ADD:
-		if (!capable(CAP_SYS_ADMIN))
-			return -EPERM;
 		if (!(entry = kmalloc(sizeof(*entry), GFP_KERNEL)))
 			return -ENOMEM;
 		if (audit_copy_rule(&entry->rule, data)) {
@@ -360,7 +358,7 @@
 		case AUDIT_INODE:
 			if (ctx) {
 				for (j = 0; j < ctx->name_count; j++) {
-					if (MINOR(ctx->names[j].ino)==value) {
+					if (ctx->names[j].ino == value) {
 						++result;
 						break;
 					}
@@ -549,8 +547,8 @@
 
 				/* Preserve login uid */
 	context->loginuid = -1;
-	if (tsk->audit_context)
-		context->loginuid = tsk->audit_context->loginuid;
+	if (current->audit_context)
+		context->loginuid = current->audit_context->loginuid;
 
 	tsk->audit_context  = context;
 	set_tsk_thread_flag(tsk, TIF_SYSCALL_AUDIT);
@@ -591,7 +589,7 @@
 	if (context->personality != PER_LINUX)
 		audit_log_format(ab, " per=%lx", context->personality);
 	if (context->return_valid)
-		audit_log_format(ab, " exit=%u", context->return_code);
+		audit_log_format(ab, " exit=%d", 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"
@@ -905,12 +903,27 @@
 	}
 }
 
+extern int audit_set_type(struct audit_buffer *ab, int type);
+
 int audit_set_loginuid(struct audit_context *ctx, uid_t loginuid)
 {
 	if (ctx) {
-		if (loginuid < 0)
-			return -EINVAL;
+		struct audit_buffer *ab;
+
+		ab = audit_log_start(NULL);
+		if (ab) {
+			audit_log_format(ab, "login pid=%d uid=%u "
+				"old loginuid=%u new loginuid=%u",
+				ctx->pid, ctx->uid, ctx->loginuid, loginuid);
+			audit_set_type(ab, AUDIT_LOGIN);
+			audit_log_end(ab);
+		}
 		ctx->loginuid = loginuid;
 	}
 	return 0;
+}
+
+uid_t audit_get_loginuid(struct audit_context *ctx)
+{
+	return ctx ? ctx->loginuid : -1;
 }
diff -Nru a/kernel/capability.c b/kernel/capability.c
--- a/kernel/capability.c	2005-03-01 23:39:07 -08:00
+++ b/kernel/capability.c	2005-03-01 23:39:07 -08:00
@@ -23,7 +23,7 @@
  * This global lock protects task->cap_* for all tasks including current.
  * Locking rule: acquire this prior to tasklist_lock.
  */
-spinlock_t task_capability_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(task_capability_lock);
 
 /*
  * For sys_getproccap() and sys_setproccap(), any of the three
@@ -85,34 +85,60 @@
  * cap_set_pg - set capabilities for all processes in a given process
  * group.  We call this holding task_capability_lock and tasklist_lock.
  */
-static inline void cap_set_pg(int pgrp, kernel_cap_t *effective,
+static inline int cap_set_pg(int pgrp, kernel_cap_t *effective,
 			      kernel_cap_t *inheritable,
 			      kernel_cap_t *permitted)
 {
 	task_t *g, *target;
+	int ret = -EPERM;
+	int found = 0;
 
 	do_each_task_pid(pgrp, PIDTYPE_PGID, g) {
 		target = g;
-		while_each_thread(g, target)
-			security_capset_set(target, effective, inheritable, permitted);
+		while_each_thread(g, target) {
+			if (!security_capset_check(target, effective,
+							inheritable,
+							permitted)) {
+				security_capset_set(target, effective,
+							inheritable,
+							permitted);
+				ret = 0;
+			}
+			found = 1;
+		}
 	} while_each_task_pid(pgrp, PIDTYPE_PGID, g);
+
+	if (!found)
+	     ret = 0;
+	return ret;
 }
 
 /*
  * cap_set_all - set capabilities for all processes other than init
  * and self.  We call this holding task_capability_lock and tasklist_lock.
  */
-static inline void cap_set_all(kernel_cap_t *effective,
+static inline int cap_set_all(kernel_cap_t *effective,
 			       kernel_cap_t *inheritable,
 			       kernel_cap_t *permitted)
 {
      task_t *g, *target;
+     int ret = -EPERM;
+     int found = 0;
 
      do_each_thread(g, target) {
              if (target == current || target->pid == 1)
                      continue;
+             found = 1;
+	     if (security_capset_check(target, effective, inheritable,
+						permitted))
+		     continue;
+	     ret = 0;
 	     security_capset_set(target, effective, inheritable, permitted);
      } while_each_thread(g, target);
+
+     if (!found)
+	     ret = 0;
+     return ret;
 }
 
 /*
@@ -147,7 +173,7 @@
      if (get_user(pid, &header->pid))
 	     return -EFAULT; 
 
-     if (pid && !capable(CAP_SETPCAP))
+     if (pid && pid != current->pid && !capable(CAP_SETPCAP))
              return -EPERM;
 
      if (copy_from_user(&effective, &data->effective, sizeof(effective)) ||
@@ -167,36 +193,23 @@
      } else
                target = current;
 
-     ret = -EPERM;
-
-     if (security_capset_check(target, &effective, &inheritable, &permitted))
-	     goto out;
-
-     if (!cap_issubset(inheritable, cap_combine(target->cap_inheritable,
-                       current->cap_permitted)))
-             goto out;
-
-     /* verify restrictions on target's new Permitted set */
-     if (!cap_issubset(permitted, cap_combine(target->cap_permitted,
-                       current->cap_permitted)))
-             goto out;
-
-     /* verify the _new_Effective_ is a subset of the _new_Permitted_ */
-     if (!cap_issubset(effective, permitted))
-             goto out;
-
      ret = 0;
 
      /* having verified that the proposed changes are legal,
            we now put them into effect. */
      if (pid < 0) {
              if (pid == -1)  /* all procs other than current and init */
-                     cap_set_all(&effective, &inheritable, &permitted);
+                     ret = cap_set_all(&effective, &inheritable, &permitted);
 
              else            /* all procs in process group */
-                     cap_set_pg(-pid, &effective, &inheritable, &permitted);
+                     ret = cap_set_pg(-pid, &effective, &inheritable,
+		     					&permitted);
      } else {
-	     security_capset_set(target, &effective, &inheritable, &permitted);
+	     ret = security_capset_check(target, &effective, &inheritable,
+	     						&permitted);
+	     if (!ret)
+		     security_capset_set(target, &effective, &inheritable,
+		     					&permitted);
      }
 
 out:
diff -Nru a/kernel/compat.c b/kernel/compat.c
--- a/kernel/compat.c	2005-03-01 23:38:57 -08:00
+++ b/kernel/compat.c	2005-03-01 23:38:57 -08:00
@@ -20,6 +20,7 @@
 #include <linux/futex.h>	/* for FUTEX_WAIT */
 #include <linux/syscalls.h>
 #include <linux/unistd.h>
+#include <linux/security.h>
 
 #include <asm/uaccess.h>
 
@@ -162,15 +163,15 @@
 		struct compat_tms tmp;
 		struct task_struct *tsk = current;
 		struct task_struct *t;
-		unsigned long utime, stime, cutime, cstime;
+		cputime_t utime, stime, cutime, cstime;
 
 		read_lock(&tasklist_lock);
 		utime = tsk->signal->utime;
 		stime = tsk->signal->stime;
 		t = tsk;
 		do {
-			utime += t->utime;
-			stime += t->stime;
+			utime = cputime_add(utime, t->utime);
+			stime = cputime_add(stime, t->stime);
 			t = next_thread(t);
 		} while (t != tsk);
 
@@ -189,10 +190,10 @@
 		spin_unlock_irq(&tsk->sighand->siglock);
 		read_unlock(&tasklist_lock);
 
-		tmp.tms_utime = compat_jiffies_to_clock_t(utime);
-		tmp.tms_stime = compat_jiffies_to_clock_t(stime);
-		tmp.tms_cutime = compat_jiffies_to_clock_t(cutime);
-		tmp.tms_cstime = compat_jiffies_to_clock_t(cstime);
+		tmp.tms_utime = compat_jiffies_to_clock_t(cputime_to_jiffies(utime));
+		tmp.tms_stime = compat_jiffies_to_clock_t(cputime_to_jiffies(stime));
+		tmp.tms_cutime = compat_jiffies_to_clock_t(cputime_to_jiffies(cutime));
+		tmp.tms_cstime = compat_jiffies_to_clock_t(cputime_to_jiffies(cstime));
 		if (copy_to_user(tbuf, &tmp, sizeof(tmp)))
 			return -EFAULT;
 	}
@@ -680,3 +681,128 @@
 
 	return 0;
 }
+
+void
+sigset_from_compat (sigset_t *set, compat_sigset_t *compat)
+{
+	switch (_NSIG_WORDS) {
+#if defined (__COMPAT_ENDIAN_SWAP__)
+	case 4: set->sig[3] = compat->sig[7] | (((long)compat->sig[6]) << 32 );
+	case 3: set->sig[2] = compat->sig[5] | (((long)compat->sig[4]) << 32 );
+	case 2: set->sig[1] = compat->sig[3] | (((long)compat->sig[2]) << 32 );
+	case 1: set->sig[0] = compat->sig[1] | (((long)compat->sig[0]) << 32 );
+#else
+	case 4: set->sig[3] = compat->sig[6] | (((long)compat->sig[7]) << 32 );
+	case 3: set->sig[2] = compat->sig[4] | (((long)compat->sig[5]) << 32 );
+	case 2: set->sig[1] = compat->sig[2] | (((long)compat->sig[3]) << 32 );
+	case 1: set->sig[0] = compat->sig[0] | (((long)compat->sig[1]) << 32 );
+#endif
+	}
+}
+
+asmlinkage long
+compat_sys_rt_sigtimedwait (compat_sigset_t __user *uthese,
+		struct compat_siginfo __user *uinfo,
+		struct compat_timespec __user *uts, compat_size_t sigsetsize)
+{
+	compat_sigset_t s32;
+	sigset_t s;
+	int sig;
+	struct timespec t;
+	siginfo_t info;
+	long ret, timeout = 0;
+
+	if (sigsetsize != sizeof(sigset_t))
+		return -EINVAL;
+
+	if (copy_from_user(&s32, uthese, sizeof(compat_sigset_t)))
+		return -EFAULT;
+	sigset_from_compat(&s, &s32);
+	sigdelsetmask(&s,sigmask(SIGKILL)|sigmask(SIGSTOP));
+	signotset(&s);
+
+	if (uts) {
+		if (get_compat_timespec (&t, uts))
+			return -EFAULT;
+		if (t.tv_nsec >= 1000000000L || t.tv_nsec < 0
+				|| t.tv_sec < 0)
+			return -EINVAL;
+	}
+
+	spin_lock_irq(&current->sighand->siglock);
+	sig = dequeue_signal(current, &s, &info);
+	if (!sig) {
+		timeout = MAX_SCHEDULE_TIMEOUT;
+		if (uts)
+			timeout = timespec_to_jiffies(&t)
+				+(t.tv_sec || t.tv_nsec);
+		if (timeout) {
+			current->real_blocked = current->blocked;
+			sigandsets(&current->blocked, &current->blocked, &s);
+
+			recalc_sigpending();
+			spin_unlock_irq(&current->sighand->siglock);
+
+			current->state = TASK_INTERRUPTIBLE;
+			timeout = schedule_timeout(timeout);
+
+			spin_lock_irq(&current->sighand->siglock);
+			sig = dequeue_signal(current, &s, &info);
+			current->blocked = current->real_blocked;
+			siginitset(&current->real_blocked, 0);
+			recalc_sigpending();
+		}
+	}
+	spin_unlock_irq(&current->sighand->siglock);
+
+	if (sig) {
+		ret = sig;
+		if (uinfo) {
+			if (copy_siginfo_to_user32(uinfo, &info))
+				ret = -EFAULT;
+		}
+	}else {
+		ret = timeout?-EINTR:-EAGAIN;
+	}
+	return ret;
+
+}
+
+#ifdef __ARCH_WANT_COMPAT_SYS_TIME
+
+/* compat_time_t is a 32 bit "long" and needs to get converted. */
+
+asmlinkage long compat_sys_time(compat_time_t __user * tloc)
+{
+	compat_time_t i;
+	struct timeval tv;
+
+	do_gettimeofday(&tv);
+	i = tv.tv_sec;
+
+	if (tloc) {
+		if (put_user(i,tloc))
+			i = -EFAULT;
+	}
+	return i;
+}
+
+asmlinkage long compat_sys_stime(compat_time_t __user *tptr)
+{
+	struct timespec tv;
+	int err;
+
+	if (get_user(tv.tv_sec, tptr))
+		return -EFAULT;
+
+	tv.tv_nsec = 0;
+
+	err = security_settime(&tv, NULL);
+	if (err)
+		return err;
+
+	do_settimeofday(&tv);
+	return 0;
+}
+
+#endif /* __ARCH_WANT_COMPAT_SYS_TIME */
diff -Nru a/kernel/cpu.c b/kernel/cpu.c
--- a/kernel/cpu.c	2005-03-01 23:39:10 -08:00
+++ b/kernel/cpu.c	2005-03-01 23:39:10 -08:00
@@ -48,7 +48,9 @@
 
 	write_lock_irq(&tasklist_lock);
 	for_each_process(p) {
-		if (task_cpu(p) == cpu && (p->utime != 0 || p->stime != 0))
+		if (task_cpu(p) == cpu &&
+		    (!cputime_eq(p->utime, cputime_zero) ||
+		     !cputime_eq(p->stime, cputime_zero)))
 			printk(KERN_WARNING "Task %s (pid = %d) is on cpu %d\
 				(state = %ld, flags = %lx) \n",
 				 p->comm, p->pid, cpu, p->state, p->flags);
@@ -132,7 +134,8 @@
 	__cpu_die(cpu);
 
 	/* Move it here so it can run. */
-	kthread_bind(p, smp_processor_id());
+	kthread_bind(p, get_cpu());
+	put_cpu();
 
 	/* CPU is completely dead: tell everyone.  Too late to complain. */
 	if (notifier_call_chain(&cpu_chain, CPU_DEAD, (void *)(long)cpu)
diff -Nru a/kernel/dma.c b/kernel/dma.c
--- a/kernel/dma.c	2005-03-01 23:38:53 -08:00
+++ b/kernel/dma.c	2005-03-01 23:38:53 -08:00
@@ -38,7 +38,7 @@
  */
 
 
-spinlock_t dma_spin_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(dma_spin_lock);
 
 /*
  *	If our port doesn't define this it has no PC like DMA
diff -Nru a/kernel/exec_domain.c b/kernel/exec_domain.c
--- a/kernel/exec_domain.c	2005-03-01 23:38:59 -08:00
+++ b/kernel/exec_domain.c	2005-03-01 23:38:59 -08:00
@@ -22,7 +22,7 @@
 static void default_handler(int, struct pt_regs *);
 
 static struct exec_domain *exec_domains = &default_exec_domain;
-static rwlock_t exec_domains_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(exec_domains_lock);
 
 
 static u_long ident_map[32] = {
diff -Nru a/kernel/exit.c b/kernel/exit.c
--- a/kernel/exit.c	2005-03-01 23:39:09 -08:00
+++ b/kernel/exit.c	2005-03-01 23:39:09 -08:00
@@ -159,7 +159,7 @@
 
 	do_each_task_pid(pgrp, PIDTYPE_PGID, p) {
 		if (p == ignored_task
-				|| p->exit_state >= EXIT_ZOMBIE
+				|| p->exit_state
 				|| p->real_parent->pid == 1)
 			continue;
 		if (process_group(p->real_parent) != pgrp
@@ -332,7 +332,9 @@
 	exit_mm(current);
 
 	set_special_pids(1, 1);
+	down(&tty_sem);
 	current->signal->tty = NULL;
+	up(&tty_sem);
 
 	/* Block and flush all signals */
 	sigfillset(&blocked);
@@ -470,7 +472,7 @@
  * Turn us into a lazy TLB process if we
  * aren't already..
  */
-static inline void __exit_mm(struct task_struct * tsk)
+void exit_mm(struct task_struct * tsk)
 {
 	struct mm_struct *mm = tsk->mm;
 
@@ -506,18 +508,13 @@
 	mmput(mm);
 }
 
-void exit_mm(struct task_struct *tsk)
-{
-	__exit_mm(tsk);
-}
-
 static inline void choose_new_parent(task_t *p, task_t *reaper, task_t *child_reaper)
 {
 	/*
 	 * Make sure we're not reparenting to ourselves and that
 	 * the parent is not a zombie.
 	 */
-	BUG_ON(p == reaper || reaper->state >= EXIT_ZOMBIE || reaper->exit_state >= EXIT_ZOMBIE);
+	BUG_ON(p == reaper || reaper->exit_state >= EXIT_ZOMBIE);
 	p->real_parent = reaper;
 	if (p->parent == p->real_parent)
 		BUG();
@@ -560,7 +557,7 @@
 			 * a normal stop since it's no longer being
 			 * traced.
 			 */
-			p->state = TASK_STOPPED;
+			ptrace_untrace(p);
 		}
 	}
 
@@ -599,7 +596,7 @@
 			reaper = child_reaper;
 			break;
 		}
-	} while (reaper->exit_state >= EXIT_ZOMBIE);
+	} while (reaper->exit_state);
 
 	/*
 	 * There are only two places where our children can be:
@@ -656,7 +653,7 @@
 	struct task_struct *t;
 	struct list_head ptrace_dead, *_p, *_n;
 
-	if (signal_pending(tsk) && !tsk->signal->group_exit
+	if (signal_pending(tsk) && !(tsk->signal->flags & SIGNAL_GROUP_EXIT)
 	    && !thread_group_empty(tsk)) {
 		/*
 		 * This occurs when there was a race between our exit
@@ -750,7 +747,9 @@
 	}
 
 	state = EXIT_ZOMBIE;
-	if (tsk->exit_signal == -1 && tsk->ptrace == 0)
+	if (tsk->exit_signal == -1 &&
+	    (likely(tsk->ptrace == 0) ||
+	     unlikely(tsk->parent->signal->flags & SIGNAL_GROUP_EXIT)))
 		state = EXIT_DEAD;
 	tsk->exit_state = state;
 
@@ -758,8 +757,8 @@
 	 * Clear these here so that update_process_times() won't try to deliver
 	 * itimer, profile or rlimit signals to this task while it is in late exit.
 	 */
-	tsk->it_virt_value = 0;
-	tsk->it_prof_value = 0;
+	tsk->it_virt_value = cputime_zero;
+	tsk->it_prof_value = cputime_zero;
 
 	write_unlock_irq(&tasklist_lock);
 
@@ -793,6 +792,12 @@
 		panic("Attempted to kill init!");
 	if (tsk->io_context)
 		exit_io_context();
+
+	if (unlikely(current->ptrace & PT_TRACE_EXIT)) {
+		current->ptrace_message = code;
+		ptrace_notify((PTRACE_EVENT_EXIT << 8) | SIGTRAP);
+	}
+
 	tsk->flags |= PF_EXITING;
 	del_timer_sync(&tsk->real_timer);
 
@@ -801,15 +806,12 @@
 				current->comm, current->pid,
 				preempt_count());
 
-	if (unlikely(current->ptrace & PT_TRACE_EXIT)) {
-		current->ptrace_message = code;
-		ptrace_notify((PTRACE_EVENT_EXIT << 8) | SIGTRAP);
-	}
-
+	acct_update_integrals();
+	update_mem_hiwater();
 	group_dead = atomic_dec_and_test(&tsk->signal->live);
 	if (group_dead)
 		acct_process(code);
-	__exit_mm(tsk);
+	exit_mm(tsk);
 
 	exit_sem(tsk);
 	__exit_files(tsk);
@@ -856,13 +858,6 @@
 
 task_t fastcall *next_thread(const task_t *p)
 {
-#ifdef CONFIG_SMP
-	if (!p->sighand)
-		BUG();
-	if (!spin_is_locked(&p->sighand->siglock) &&
-				!rwlock_is_locked(&tasklist_lock))
-		BUG();
-#endif
 	return pid_task(p->pids[PIDTYPE_TGID].pid_list.next, PIDTYPE_TGID);
 }
 
@@ -877,18 +872,18 @@
 {
 	BUG_ON(exit_code & 0x80); /* core dumps don't get here */
 
-	if (current->signal->group_exit)
+	if (current->signal->flags & SIGNAL_GROUP_EXIT)
 		exit_code = current->signal->group_exit_code;
 	else if (!thread_group_empty(current)) {
 		struct signal_struct *const sig = current->signal;
 		struct sighand_struct *const sighand = current->sighand;
 		read_lock(&tasklist_lock);
 		spin_lock_irq(&sighand->siglock);
-		if (sig->group_exit)
+		if (sig->flags & SIGNAL_GROUP_EXIT)
 			/* Another thread got here before we took the lock.  */
 			exit_code = sig->group_exit_code;
 		else {
-			sig->group_exit = 1;
+			sig->flags = SIGNAL_GROUP_EXIT;
 			sig->group_exit_code = exit_code;
 			zap_other_threads(current);
 		}
@@ -1046,10 +1041,16 @@
 		 * here reaping other children at the same time.
 		 */
 		spin_lock_irq(&p->parent->sighand->siglock);
-		p->parent->signal->cutime +=
-			p->utime + p->signal->utime + p->signal->cutime;
-		p->parent->signal->cstime +=
-			p->stime + p->signal->stime + p->signal->cstime;
+		p->parent->signal->cutime =
+			cputime_add(p->parent->signal->cutime,
+			cputime_add(p->utime,
+			cputime_add(p->signal->utime,
+				    p->signal->cutime)));
+		p->parent->signal->cstime =
+			cputime_add(p->parent->signal->cstime,
+			cputime_add(p->stime,
+			cputime_add(p->signal->stime,
+				    p->signal->cstime)));
 		p->parent->signal->cmin_flt +=
 			p->min_flt + p->signal->min_flt + p->signal->cmin_flt;
 		p->parent->signal->cmaj_flt +=
@@ -1068,7 +1069,7 @@
 	read_unlock(&tasklist_lock);
 
 	retval = ru ? getrusage(p, RUSAGE_BOTH, ru) : 0;
-	status = p->signal->group_exit
+	status = (p->signal->flags & SIGNAL_GROUP_EXIT)
 		? p->signal->group_exit_code : p->exit_code;
 	if (!retval && stat_addr)
 		retval = put_user(status, stat_addr);
@@ -1180,7 +1181,7 @@
 	 * race with the EXIT_ZOMBIE case.
 	 */
 	exit_code = xchg(&p->exit_code, 0);
-	if (unlikely(p->exit_state >= EXIT_ZOMBIE)) {
+	if (unlikely(p->exit_state)) {
 		/*
 		 * The task resumed and then died.  Let the next iteration
 		 * catch it in EXIT_ZOMBIE.  Note that exit_code might
@@ -1258,16 +1259,17 @@
 	if (unlikely(!p->signal))
 		return 0;
 
-	if (p->signal->stop_state >= 0)
+	if (!(p->signal->flags & SIGNAL_STOP_CONTINUED))
 		return 0;
 
 	spin_lock_irq(&p->sighand->siglock);
-	if (p->signal->stop_state >= 0) { /* Re-check with the lock held.  */
+	/* Re-check with the lock held.  */
+	if (!(p->signal->flags & SIGNAL_STOP_CONTINUED)) {
 		spin_unlock_irq(&p->sighand->siglock);
 		return 0;
 	}
 	if (!noreap)
-		p->signal->stop_state = 0;
+		p->signal->flags &= ~SIGNAL_STOP_CONTINUED;
 	spin_unlock_irq(&p->sighand->siglock);
 
 	pid = p->pid;
@@ -1316,7 +1318,7 @@
 	struct task_struct *tsk;
 	int flag, retval;
 
-	add_wait_queue(&current->wait_chldexit,&wait);
+	add_wait_queue(&current->signal->wait_chldexit,&wait);
 repeat:
 	/*
 	 * We will set this flag if we see any child that might later
@@ -1430,7 +1432,7 @@
 	retval = -ECHILD;
 end:
 	current->state = TASK_RUNNING;
-	remove_wait_queue(&current->wait_chldexit,&wait);
+	remove_wait_queue(&current->signal->wait_chldexit,&wait);
 	if (infop) {
 		if (retval > 0)
 		retval = 0;
diff -Nru a/kernel/fork.c b/kernel/fork.c
--- a/kernel/fork.c	2005-03-01 23:38:52 -08:00
+++ b/kernel/fork.c	2005-03-01 23:38:52 -08:00
@@ -39,6 +39,7 @@
 #include <linux/audit.h>
 #include <linux/profile.h>
 #include <linux/rmap.h>
+#include <linux/acct.h>
 
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
@@ -47,17 +48,17 @@
 #include <asm/cacheflush.h>
 #include <asm/tlbflush.h>
 
-/* The idle threads do not count..
- * Protected by write_lock_irq(&tasklist_lock)
+/*
+ * Protected counters by write_lock_irq(&tasklist_lock)
  */
-int nr_threads;
-
-int max_threads;
 unsigned long total_forks;	/* Handle normal Linux uptimes. */
+int nr_threads; 		/* The idle threads do not count.. */
+
+int max_threads;		/* tunable limit on nr_threads */
 
 DEFINE_PER_CPU(unsigned long, process_counts) = 0;
 
-rwlock_t tasklist_lock __cacheline_aligned = RW_LOCK_UNLOCKED;  /* outer */
+ __cacheline_aligned DEFINE_RWLOCK(tasklist_lock);  /* outer */
 
 EXPORT_SYMBOL(tasklist_lock);
 
@@ -218,6 +219,7 @@
       
 			/* insert tmp into the share list, just after mpnt */
 			spin_lock(&file->f_mapping->i_mmap_lock);
+			tmp->vm_truncate_count = mpnt->vm_truncate_count;
 			flush_dcache_mmap_lock(file->f_mapping);
 			vma_prio_tree_add(tmp, mpnt);
 			flush_dcache_mmap_unlock(file->f_mapping);
@@ -279,7 +281,7 @@
 #define mm_free_pgd(mm)
 #endif /* CONFIG_MMU */
 
-spinlock_t mmlist_lock __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
+ __cacheline_aligned_in_smp DEFINE_SPINLOCK(mmlist_lock);
 
 #define allocate_mm()	(kmem_cache_alloc(mm_cachep, SLAB_KERNEL))
 #define free_mm(mm)	(kmem_cache_free(mm_cachep, (mm)))
@@ -469,6 +471,9 @@
 	if (retval)
 		goto free_pt;
 
+	mm->hiwater_rss = mm->rss;
+	mm->hiwater_vm = mm->total_vm;
+
 good_mm:
 	tsk->mm = mm;
 	tsk->active_mm = mm;
@@ -550,7 +555,7 @@
 {
 	struct files_struct *oldf, *newf;
 	struct file **old_fds, **new_fds;
-	int open_files, nfds, size, i, error = 0;
+	int open_files, size, i, error = 0, expand;
 
 	/*
 	 * A background process may not have any files ...
@@ -585,36 +590,32 @@
 	newf->open_fds	    = &newf->open_fds_init;
 	newf->fd	    = &newf->fd_array[0];
 
-	/* We don't yet have the oldf readlock, but even if the old
-           fdset gets grown now, we'll only copy up to "size" fds */
-	size = oldf->max_fdset;
-	if (size > __FD_SETSIZE) {
-		newf->max_fdset = 0;
-		spin_lock(&newf->file_lock);
-		error = expand_fdset(newf, size-1);
-		spin_unlock(&newf->file_lock);
-		if (error)
-			goto out_release;
-	}
 	spin_lock(&oldf->file_lock);
 
-	open_files = count_open_files(oldf, size);
+	open_files = count_open_files(oldf, oldf->max_fdset);
+	expand = 0;
 
 	/*
-	 * Check whether we need to allocate a larger fd array.
-	 * Note: we're not a clone task, so the open count won't
-	 * change.
+	 * Check whether we need to allocate a larger fd array or fd set.
+	 * Note: we're not a clone task, so the open count won't  change.
 	 */
-	nfds = NR_OPEN_DEFAULT;
-	if (open_files > nfds) {
-		spin_unlock(&oldf->file_lock);
+	if (open_files > newf->max_fdset) {
+		newf->max_fdset = 0;
+		expand = 1;
+	}
+	if (open_files > newf->max_fds) {
 		newf->max_fds = 0;
+		expand = 1;
+	}
+
+	/* if the old fdset gets grown now, we'll only copy up to "size" fds */
+	if (expand) {
+		spin_unlock(&oldf->file_lock);
 		spin_lock(&newf->file_lock);
-		error = expand_fd_array(newf, open_files-1);
+		error = expand_files(newf, open_files-1);
 		spin_unlock(&newf->file_lock);
-		if (error) 
+		if (error < 0)
 			goto out_release;
-		nfds = newf->max_fds;
 		spin_lock(&oldf->file_lock);
 	}
 
@@ -663,6 +664,7 @@
 out_release:
 	free_fdset (newf->close_on_exec, newf->max_fdset);
 	free_fdset (newf->open_fds, newf->max_fdset);
+	free_fd_array(newf->fd, newf->max_fds);
 	kmem_cache_free(files_cachep, newf);
 	goto out;
 }
@@ -729,11 +731,11 @@
 		return -ENOMEM;
 	atomic_set(&sig->count, 1);
 	atomic_set(&sig->live, 1);
-	sig->group_exit = 0;
+	init_waitqueue_head(&sig->wait_chldexit);
+	sig->flags = 0;
 	sig->group_exit_code = 0;
 	sig->group_exit_task = NULL;
 	sig->group_stop_count = 0;
-	sig->stop_state = 0;
 	sig->curr_target = NULL;
 	init_sigpending(&sig->shared_pending);
 	INIT_LIST_HEAD(&sig->posix_timers);
@@ -744,7 +746,7 @@
 	sig->leader = 0;	/* session leadership doesn't inherit */
 	sig->tty_old_pgrp = 0;
 
-	sig->utime = sig->stime = sig->cutime = sig->cstime = 0;
+	sig->utime = sig->stime = sig->cutime = sig->cstime = cputime_zero;
 	sig->nvcsw = sig->nivcsw = sig->cnvcsw = sig->cnivcsw = 0;
 	sig->min_flt = sig->maj_flt = sig->cmin_flt = sig->cmaj_flt = 0;
 
@@ -857,7 +859,6 @@
 
 	INIT_LIST_HEAD(&p->children);
 	INIT_LIST_HEAD(&p->sibling);
-	init_waitqueue_head(&p->wait_chldexit);
 	p->vfork_done = NULL;
 	spin_lock_init(&p->alloc_lock);
 	spin_lock_init(&p->proc_lock);
@@ -865,12 +866,23 @@
 	clear_tsk_thread_flag(p, TIF_SIGPENDING);
 	init_sigpending(&p->pending);
 
-	p->it_real_value = p->it_virt_value = p->it_prof_value = 0;
-	p->it_real_incr = p->it_virt_incr = p->it_prof_incr = 0;
+	p->it_real_value = 0;
+	p->it_real_incr = 0;
+	p->it_virt_value = cputime_zero;
+	p->it_virt_incr = cputime_zero;
+	p->it_prof_value = cputime_zero;
+	p->it_prof_incr = cputime_zero;
 	init_timer(&p->real_timer);
 	p->real_timer.data = (unsigned long) p;
 
-	p->utime = p->stime = 0;
+	p->utime = cputime_zero;
+	p->stime = cputime_zero;
+	p->rchar = 0;		/* I/O counter: bytes read */
+	p->wchar = 0;		/* I/O counter: bytes written */
+	p->syscr = 0;		/* I/O counter: read syscalls */
+	p->syscw = 0;		/* I/O counter: write syscalls */
+	acct_clear_integrals(p);
+
 	p->lock_depth = -1;		/* -1 = no lock */
 	do_posix_clock_monotonic_gettime(&p->start_time);
 	p->security = NULL;
@@ -985,7 +997,7 @@
 		 * do not create this new thread - the whole thread
 		 * group is supposed to exit anyway.
 		 */
-		if (current->signal->group_exit) {
+		if (current->signal->flags & SIGNAL_GROUP_EXIT) {
 			spin_unlock(&current->sighand->siglock);
 			write_unlock_irq(&tasklist_lock);
 			retval = -EAGAIN;
@@ -1020,6 +1032,7 @@
 	}
 
 	nr_threads++;
+	total_forks++;
 	write_unlock_irq(&tasklist_lock);
 	retval = 0;
 
@@ -1152,7 +1165,6 @@
 			wake_up_new_task(p, clone_flags);
 		else
 			p->state = TASK_STOPPED;
-		++total_forks;
 
 		if (unlikely (trace)) {
 			current->ptrace_message = pid;
diff -Nru a/kernel/futex.c b/kernel/futex.c
--- a/kernel/futex.c	2005-03-01 23:38:54 -08:00
+++ b/kernel/futex.c	2005-03-01 23:38:54 -08:00
@@ -258,6 +258,18 @@
 	}
 }
 
+static inline int get_futex_value_locked(int *dest, int __user *from)
+{
+	int ret;
+
+	inc_preempt_count();
+	ret = __copy_from_user_inatomic(dest, from, sizeof(int));
+	dec_preempt_count();
+	preempt_check_resched();
+
+	return ret ? -EFAULT : 0;
+}
+
 /*
  * The hash bucket lock must be held when this is called.
  * Afterwards, the futex_q must not be accessed.
@@ -329,6 +341,7 @@
 	int ret, drop_count = 0;
 	unsigned int nqueued;
 
+ retry:
 	down_read(&current->mm->mmap_sem);
 
 	ret = get_futex_key(uaddr1, &key1);
@@ -355,9 +368,20 @@
 		   before *uaddr1.  */
 		smp_mb();
 
-		if (get_user(curval, (int __user *)uaddr1) != 0) {
-			ret = -EFAULT;
-			goto out;
+		ret = get_futex_value_locked(&curval, (int __user *)uaddr1);
+
+		if (unlikely(ret)) {
+			/* If we would have faulted, release mmap_sem, fault
+			 * it in and start all over again.
+			 */
+			up_read(&current->mm->mmap_sem);
+
+			ret = get_user(curval, (int __user *)uaddr1);
+
+			if (!ret)
+				goto retry;
+
+			return ret;
 		}
 		if (curval != *valp) {
 			ret = -EAGAIN;
@@ -480,6 +504,7 @@
 	int ret, curval;
 	struct futex_q q;
 
+ retry:
 	down_read(&current->mm->mmap_sem);
 
 	ret = get_futex_key(uaddr, &q.key);
@@ -508,9 +533,23 @@
 	 * We hold the mmap semaphore, so the mapping cannot have changed
 	 * since we looked it up in get_futex_key.
 	 */
-	if (get_user(curval, (int __user *)uaddr) != 0) {
-		ret = -EFAULT;
-		goto out_unqueue;
+
+	ret = get_futex_value_locked(&curval, (int __user *)uaddr);
+
+	if (unlikely(ret)) {
+		/* If we would have faulted, release mmap_sem, fault it in and
+		 * start all over again.
+		 */
+		up_read(&current->mm->mmap_sem);
+
+		if (!unqueue_me(&q)) /* There's a chance we got woken already */
+			return 0;
+
+		ret = get_user(curval, (int __user *)uaddr);
+
+		if (!ret)
+			goto retry;
+		return ret;
 	}
 	if (curval != val) {
 		ret = -EWOULDBLOCK;
diff -Nru a/kernel/intermodule.c b/kernel/intermodule.c
--- a/kernel/intermodule.c	2005-03-01 23:38:44 -08:00
+++ b/kernel/intermodule.c	2005-03-01 23:38:44 -08:00
@@ -14,7 +14,7 @@
  */
 
 static struct list_head ime_list = LIST_HEAD_INIT(ime_list);
-static spinlock_t ime_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(ime_lock);
 static int kmalloc_failed;
 
 struct inter_module_entry {
diff -Nru a/kernel/irq/autoprobe.c b/kernel/irq/autoprobe.c
--- a/kernel/irq/autoprobe.c	2005-03-01 23:38:57 -08:00
+++ b/kernel/irq/autoprobe.c	2005-03-01 23:38:57 -08:00
@@ -137,6 +137,7 @@
 
 	return mask & val;
 }
+EXPORT_SYMBOL(probe_irq_mask);
 
 /**
  *	probe_irq_off	- end an interrupt autodetect
diff -Nru a/kernel/irq/handle.c b/kernel/irq/handle.c
--- a/kernel/irq/handle.c	2005-03-01 23:39:18 -08:00
+++ b/kernel/irq/handle.c	2005-03-01 23:39:18 -08:00
@@ -73,17 +73,6 @@
 }
 
 /*
- * Exit an interrupt context. Process softirqs if needed and possible:
- */
-void irq_exit(void)
-{
-	preempt_count() -= IRQ_EXIT_OFFSET;
-	if (!in_interrupt() && local_softirq_pending())
-		do_softirq();
-	preempt_enable_no_resched();
-}
-
-/*
  * Have got an event to handle:
  */
 fastcall int handle_IRQ_event(unsigned int irq, struct pt_regs *regs,
diff -Nru a/kernel/irq/manage.c b/kernel/irq/manage.c
--- a/kernel/irq/manage.c	2005-03-01 23:39:18 -08:00
+++ b/kernel/irq/manage.c	2005-03-01 23:39:18 -08:00
@@ -15,6 +15,8 @@
 
 #ifdef CONFIG_SMP
 
+cpumask_t irq_affinity[NR_IRQS] = { [0 ... NR_IRQS-1] = CPU_MASK_ALL };
+
 /**
  *	synchronize_irq - wait for pending IRQ handlers (on other CPUs)
  *
diff -Nru a/kernel/irq/proc.c b/kernel/irq/proc.c
--- a/kernel/irq/proc.c	2005-03-01 23:38:54 -08:00
+++ b/kernel/irq/proc.c	2005-03-01 23:38:54 -08:00
@@ -19,8 +19,6 @@
  */
 static struct proc_dir_entry *smp_affinity_entry[NR_IRQS];
 
-cpumask_t irq_affinity[NR_IRQS] = { [0 ... NR_IRQS-1] = CPU_MASK_ALL };
-
 static int irq_affinity_read_proc(char *page, char **start, off_t off,
 				  int count, int *eof, void *data)
 {
diff -Nru a/kernel/itimer.c b/kernel/itimer.c
--- a/kernel/itimer.c	2005-03-01 23:38:56 -08:00
+++ b/kernel/itimer.c	2005-03-01 23:38:56 -08:00
@@ -16,11 +16,10 @@
 
 int do_getitimer(int which, struct itimerval *value)
 {
-	register unsigned long val, interval;
+	register unsigned long val;
 
 	switch (which) {
 	case ITIMER_REAL:
-		interval = current->it_real_incr;
 		val = 0;
 		/* 
 		 * FIXME! This needs to be atomic, in case the kernel timer happens!
@@ -32,20 +31,20 @@
 			if ((long) val <= 0)
 				val = 1;
 		}
+		jiffies_to_timeval(val, &value->it_value);
+		jiffies_to_timeval(current->it_real_incr, &value->it_interval);
 		break;
 	case ITIMER_VIRTUAL:
-		val = current->it_virt_value;
-		interval = current->it_virt_incr;
+		cputime_to_timeval(current->it_virt_value, &value->it_value);
+		cputime_to_timeval(current->it_virt_incr, &value->it_interval);
 		break;
 	case ITIMER_PROF:
-		val = current->it_prof_value;
-		interval = current->it_prof_incr;
+		cputime_to_timeval(current->it_prof_value, &value->it_value);
+		cputime_to_timeval(current->it_prof_incr, &value->it_interval);
 		break;
 	default:
 		return(-EINVAL);
 	}
-	jiffies_to_timeval(val, &value->it_value);
-	jiffies_to_timeval(interval, &value->it_interval);
 	return 0;
 }
 
@@ -81,37 +80,43 @@
 
 int do_setitimer(int which, struct itimerval *value, struct itimerval *ovalue)
 {
-	register unsigned long i, j;
+	unsigned long expire;
+	cputime_t cputime;
 	int k;
 
-	i = timeval_to_jiffies(&value->it_interval);
-	j = timeval_to_jiffies(&value->it_value);
 	if (ovalue && (k = do_getitimer(which, ovalue)) < 0)
 		return k;
 	switch (which) {
 		case ITIMER_REAL:
 			del_timer_sync(&current->real_timer);
-			current->it_real_value = j;
-			current->it_real_incr = i;
-			if (!j)
+			expire = timeval_to_jiffies(&value->it_value);
+			current->it_real_value = expire;
+			current->it_real_incr =
+				timeval_to_jiffies(&value->it_interval);
+			if (!expire)
 				break;
-			if (j > (unsigned long) LONG_MAX)
-				j = LONG_MAX;
-			i = j + jiffies;
-			current->real_timer.expires = i;
+			if (expire > (unsigned long) LONG_MAX)
+				expire = LONG_MAX;
+			current->real_timer.expires = jiffies + expire;
 			add_timer(&current->real_timer);
 			break;
 		case ITIMER_VIRTUAL:
-			if (j)
-				j++;
-			current->it_virt_value = j;
-			current->it_virt_incr = i;
+			cputime = timeval_to_cputime(&value->it_value);
+			if (cputime_gt(cputime, cputime_zero))
+				cputime = cputime_add(cputime,
+						      jiffies_to_cputime(1));
+			current->it_virt_value = cputime;
+			cputime = timeval_to_cputime(&value->it_interval);
+			current->it_virt_incr = cputime;
 			break;
 		case ITIMER_PROF:
-			if (j)
-				j++;
-			current->it_prof_value = j;
-			current->it_prof_incr = i;
+			cputime = timeval_to_cputime(&value->it_value);
+			if (cputime_gt(cputime, cputime_zero))
+				cputime = cputime_add(cputime,
+						      jiffies_to_cputime(1));
+			current->it_prof_value = cputime;
+			cputime = timeval_to_cputime(&value->it_interval);
+			current->it_prof_incr = cputime;
 			break;
 		default:
 			return -EINVAL;
diff -Nru a/kernel/kallsyms.c b/kernel/kallsyms.c
--- a/kernel/kallsyms.c	2005-03-01 23:39:17 -08:00
+++ b/kernel/kallsyms.c	2005-03-01 23:39:17 -08:00
@@ -18,10 +18,19 @@
 #include <linux/fs.h>
 #include <linux/err.h>
 #include <linux/proc_fs.h>
+#include <linux/mm.h>
+
+#include <asm/sections.h>
+
+#ifdef CONFIG_KALLSYMS_ALL
+#define all_var 1
+#else
+#define all_var 0
+#endif
 
 /* These will be re-linked against their real values during the second link stage */
 extern unsigned long kallsyms_addresses[] __attribute__((weak));
-extern unsigned long kallsyms_num_syms __attribute__((weak));
+extern unsigned long kallsyms_num_syms __attribute__((weak,section("data")));
 extern u8 kallsyms_names[] __attribute__((weak));
 
 extern u8 kallsyms_token_table[] __attribute__((weak));
@@ -29,9 +38,6 @@
 
 extern unsigned long kallsyms_markers[] __attribute__((weak));
 
-/* Defined by the linker script. */
-extern char _stext[], _etext[], _sinittext[], _einittext[];
-
 static inline int is_kernel_inittext(unsigned long addr)
 {
 	if (addr >= (unsigned long)_sinittext
@@ -44,7 +50,14 @@
 {
 	if (addr >= (unsigned long)_stext && addr <= (unsigned long)_etext)
 		return 1;
-	return 0;
+	return in_gate_area_no_task(addr);
+}
+
+static inline int is_kernel(unsigned long addr)
+{
+	if (addr >= (unsigned long)_stext && addr <= (unsigned long)_end)
+		return 1;
+	return in_gate_area_no_task(addr);
 }
 
 /* expand a compressed symbol data into the resulting uncompressed string,
@@ -147,7 +160,8 @@
 	namebuf[KSYM_NAME_LEN] = 0;
 	namebuf[0] = 0;
 
-	if (is_kernel_text(addr) || is_kernel_inittext(addr)) {
+	if ((all_var && is_kernel(addr)) ||
+	    (!all_var && (is_kernel_text(addr) || is_kernel_inittext(addr)))) {
 		unsigned long symbol_end=0;
 
 		/* do a binary search on the sorted kallsyms_addresses array */
@@ -181,7 +195,7 @@
 			if (is_kernel_inittext(addr))
 				symbol_end = (unsigned long)_einittext;
 			else
-				symbol_end = (unsigned long)_etext;
+				symbol_end = all_var ? (unsigned long)_end : (unsigned long)_etext;
 		}
 
 		*symbolsize = symbol_end - kallsyms_addresses[low];
diff -Nru a/kernel/kprobes.c b/kernel/kprobes.c
--- a/kernel/kprobes.c	2005-03-01 23:39:18 -08:00
+++ b/kernel/kprobes.c	2005-03-01 23:39:18 -08:00
@@ -43,7 +43,7 @@
 static struct hlist_head kprobe_table[KPROBE_TABLE_SIZE];
 
 unsigned int kprobe_cpu = NR_CPUS;
-static spinlock_t kprobe_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(kprobe_lock);
 
 /* Locks kprobe: irqs must be disabled */
 void lock_kprobes(void)
@@ -76,18 +76,19 @@
 int register_kprobe(struct kprobe *p)
 {
 	int ret = 0;
-	unsigned long flags;
+	unsigned long flags = 0;
 
+	if ((ret = arch_prepare_kprobe(p)) != 0) {
+		goto out;
+	}
 	spin_lock_irqsave(&kprobe_lock, flags);
 	INIT_HLIST_NODE(&p->hlist);
 	if (get_kprobe(p->addr)) {
 		ret = -EEXIST;
 		goto out;
 	}
+	arch_copy_kprobe(p);
 
-	if ((ret = arch_prepare_kprobe(p)) != 0) {
-		goto out;
-	}
 	hlist_add_head(&p->hlist,
 		       &kprobe_table[hash_ptr(p->addr, KPROBE_HASH_BITS)]);
 
@@ -97,14 +98,16 @@
 			   (unsigned long) p->addr + sizeof(kprobe_opcode_t));
       out:
 	spin_unlock_irqrestore(&kprobe_lock, flags);
+	if (ret == -EEXIST)
+		arch_remove_kprobe(p);
 	return ret;
 }
 
 void unregister_kprobe(struct kprobe *p)
 {
 	unsigned long flags;
-	spin_lock_irqsave(&kprobe_lock, flags);
 	arch_remove_kprobe(p);
+	spin_lock_irqsave(&kprobe_lock, flags);
 	*p->addr = p->opcode;
 	hlist_del(&p->hlist);
 	flush_icache_range((unsigned long) p->addr,
diff -Nru a/kernel/ksysfs.c b/kernel/ksysfs.c
--- a/kernel/ksysfs.c	2005-03-01 23:39:16 -08:00
+++ b/kernel/ksysfs.c	2005-03-01 23:39:16 -08:00
@@ -30,7 +30,8 @@
 KERNEL_ATTR_RO(hotplug_seqnum);
 #endif
 
-static decl_subsys(kernel, NULL, NULL);
+decl_subsys(kernel, NULL, NULL);
+EXPORT_SYMBOL_GPL(kernel_subsys);
 
 static struct attribute * kernel_attrs[] = {
 #ifdef CONFIG_HOTPLUG
diff -Nru a/kernel/kthread.c b/kernel/kthread.c
--- a/kernel/kthread.c	2005-03-01 23:39:16 -08:00
+++ b/kernel/kthread.c	2005-03-01 23:39:16 -08:00
@@ -14,6 +14,12 @@
 #include <linux/module.h>
 #include <asm/semaphore.h>
 
+/*
+ * We dont want to execute off keventd since it might
+ * hold a semaphore our callers hold too:
+ */
+static struct workqueue_struct *helper_wq;
+
 struct kthread_create_info
 {
 	/* Information passed to kthread() from keventd. */
@@ -126,12 +132,13 @@
 	init_completion(&create.started);
 	init_completion(&create.done);
 
-	/* If we're being called to start the first workqueue, we
-	 * can't use keventd. */
-	if (!keventd_up())
+	/*
+	 * The workqueue needs to start up first:
+	 */
+	if (!helper_wq)
 		work.func(work.data);
 	else {
-		schedule_work(&work);
+		queue_work(helper_wq, &work);
 		wait_for_completion(&create.done);
 	}
 	if (!IS_ERR(create.result)) {
@@ -183,3 +190,13 @@
 	return ret;
 }
 EXPORT_SYMBOL(kthread_stop);
+
+static __init int helper_init(void)
+{
+	helper_wq = create_singlethread_workqueue("kthread");
+	BUG_ON(!helper_wq);
+
+	return 0;
+}
+core_initcall(helper_init);
+
diff -Nru a/kernel/module.c b/kernel/module.c
--- a/kernel/module.c	2005-03-01 23:39:08 -08:00
+++ b/kernel/module.c	2005-03-01 23:39:08 -08:00
@@ -53,7 +53,7 @@
 #define INIT_OFFSET_MASK (1UL << (BITS_PER_LONG-1))
 
 /* Protects module list */
-static spinlock_t modlist_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(modlist_lock);
 
 /* List of modules, protected by module_mutex AND modlist_lock */
 static DECLARE_MUTEX(module_mutex);
@@ -379,7 +379,7 @@
 	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[_smp_processor_id()].count, 1);
 	/* Backwards compatibility macros put refcount during init. */
 	mod->waiter = current;
 }
@@ -651,7 +651,8 @@
 }
 EXPORT_SYMBOL_GPL(symbol_put_addr);
 
-static ssize_t show_refcnt(struct module *mod, char *buffer)
+static ssize_t show_refcnt(struct module_attribute *mattr,
+			   struct module *mod, char *buffer)
 {
 	/* sysfs holds a reference */
 	return sprintf(buffer, "%u\n", module_refcount(mod)-1);
@@ -681,13 +682,6 @@
 static inline void module_unload_init(struct module *mod)
 {
 }
-
-asmlinkage long
-sys_delete_module(const char __user *name_user, unsigned int flags)
-{
-	return -ENOSYS;
-}
-
 #endif /* CONFIG_MODULE_UNLOAD */
 
 #ifdef CONFIG_OBSOLETE_MODPARM
@@ -936,79 +930,71 @@
  * J. Corbet <corbet@lwn.net>
  */
 #ifdef CONFIG_KALLSYMS
-static void module_sect_attrs_release(struct kobject *kobj)
-{
-	kfree(container_of(kobj, struct module_sections, kobj));
-}
-
-static ssize_t module_sect_show(struct kobject *kobj, struct attribute *attr,
-		char *buf)
+static ssize_t module_sect_show(struct module_attribute *mattr,
+				struct module *mod, char *buf)
 {
 	struct module_sect_attr *sattr =
-		container_of(attr, struct module_sect_attr, attr);
+		container_of(mattr, struct module_sect_attr, mattr);
 	return sprintf(buf, "0x%lx\n", sattr->address);
 }
 
-static struct sysfs_ops module_sect_ops = {
-	.show = module_sect_show,
-};
-
-static struct kobj_type module_sect_ktype = {
-	.sysfs_ops = &module_sect_ops,
-	.release =   module_sect_attrs_release,
-};
-
 static void add_sect_attrs(struct module *mod, unsigned int nsect,
 		char *secstrings, Elf_Shdr *sechdrs)
 {
-	unsigned int nloaded = 0, i;
+	unsigned int nloaded = 0, i, size[2];
+	struct module_sect_attrs *sect_attrs;
 	struct module_sect_attr *sattr;
-	
-	if (!mod->mkobj)
-		return;
+	struct attribute **gattr;
 	
 	/* Count loaded sections and allocate structures */
 	for (i = 0; i < nsect; i++)
 		if (sechdrs[i].sh_flags & SHF_ALLOC)
 			nloaded++;
-	mod->sect_attrs = kmalloc(sizeof(struct module_sections) +
-			nloaded*sizeof(mod->sect_attrs->attrs[0]), GFP_KERNEL);
-	if (! mod->sect_attrs)
+	size[0] = ALIGN(sizeof(*sect_attrs)
+			+ nloaded * sizeof(sect_attrs->attrs[0]),
+			sizeof(sect_attrs->grp.attrs[0]));
+	size[1] = (nloaded + 1) * sizeof(sect_attrs->grp.attrs[0]);
+	if (! (sect_attrs = kmalloc(size[0] + size[1], GFP_KERNEL)))
 		return;
 
-	/* sections entry setup */
-	memset(mod->sect_attrs, 0, sizeof(struct module_sections));
-	if (kobject_set_name(&mod->sect_attrs->kobj, "sections"))
-		goto out;
-	mod->sect_attrs->kobj.parent = &mod->mkobj->kobj;
-	mod->sect_attrs->kobj.ktype = &module_sect_ktype;
-	if (kobject_register(&mod->sect_attrs->kobj))
-		goto out;
+	/* Setup section attributes. */
+	sect_attrs->grp.name = "sections";
+	sect_attrs->grp.attrs = (void *)sect_attrs + size[0];
 
-	/* And the section attributes. */
-	sattr = &mod->sect_attrs->attrs[0];
+	sattr = &sect_attrs->attrs[0];
+	gattr = &sect_attrs->grp.attrs[0];
 	for (i = 0; i < nsect; i++) {
 		if (! (sechdrs[i].sh_flags & SHF_ALLOC))
 			continue;
 		sattr->address = sechdrs[i].sh_addr;
 		strlcpy(sattr->name, secstrings + sechdrs[i].sh_name,
-				MODULE_SECT_NAME_LEN);
-		sattr->attr.name = sattr->name;
-		sattr->attr.owner = mod;
-		sattr->attr.mode = S_IRUGO;
-		(void) sysfs_create_file(&mod->sect_attrs->kobj, &sattr->attr);
-		sattr++;
+			MODULE_SECT_NAME_LEN);
+		sattr->mattr.show = module_sect_show;
+		sattr->mattr.store = NULL;
+		sattr->mattr.attr.name = sattr->name;
+		sattr->mattr.attr.owner = mod;
+		sattr->mattr.attr.mode = S_IRUGO;
+		*(gattr++) = &(sattr++)->mattr.attr;
 	}
+	*gattr = NULL;
+
+	if (sysfs_create_group(&mod->mkobj.kobj, &sect_attrs->grp))
+		goto out;
+
+	mod->sect_attrs = sect_attrs;
 	return;
   out:
-	kfree(mod->sect_attrs);
-	mod->sect_attrs = NULL;
+	kfree(sect_attrs);
 }
 
 static void remove_sect_attrs(struct module *mod)
 {
 	if (mod->sect_attrs) {
-		kobject_unregister(&mod->sect_attrs->kobj);
+		sysfs_remove_group(&mod->mkobj.kobj,
+				   &mod->sect_attrs->grp);
+		/* We are positive that no one is using any sect attrs
+		 * at this point.  Deallocate immediately. */
+		kfree(mod->sect_attrs);
 		mod->sect_attrs = NULL;
 	}
 }
@@ -1029,11 +1015,11 @@
 #ifdef CONFIG_MODULE_UNLOAD
 static inline int module_add_refcnt_attr(struct module *mod)
 {
-	return sysfs_create_file(&mod->mkobj->kobj, &refcnt.attr);
+	return sysfs_create_file(&mod->mkobj.kobj, &refcnt.attr);
 }
 static void module_remove_refcnt_attr(struct module *mod)
 {
-	return sysfs_remove_file(&mod->mkobj->kobj, &refcnt.attr);
+	return sysfs_remove_file(&mod->mkobj.kobj, &refcnt.attr);
 }
 #else
 static inline int module_add_refcnt_attr(struct module *mod)
@@ -1052,17 +1038,13 @@
 {
 	int err;
 
-	mod->mkobj = kmalloc(sizeof(struct module_kobject), GFP_KERNEL);
-	if (!mod->mkobj)
-		return -ENOMEM;
-
-	memset(&mod->mkobj->kobj, 0, sizeof(mod->mkobj->kobj));
-	err = kobject_set_name(&mod->mkobj->kobj, "%s", mod->name);
+	memset(&mod->mkobj.kobj, 0, sizeof(mod->mkobj.kobj));
+	err = kobject_set_name(&mod->mkobj.kobj, "%s", mod->name);
 	if (err)
 		goto out;
-	kobj_set_kset_s(mod->mkobj, module_subsys);
-	mod->mkobj->mod = mod;
-	err = kobject_register(&mod->mkobj->kobj);
+	kobj_set_kset_s(&mod->mkobj, module_subsys);
+	mod->mkobj.mod = mod;
+	err = kobject_register(&mod->mkobj.kobj);
 	if (err)
 		goto out;
 
@@ -1077,11 +1059,8 @@
 	return 0;
 
 out_unreg:
-	/* Calls module_kobj_release */
-	kobject_unregister(&mod->mkobj->kobj);
-	return err;
+	kobject_unregister(&mod->mkobj.kobj);
 out:
-	kfree(mod->mkobj);
 	return err;
 }
 
@@ -1090,8 +1069,7 @@
 	module_remove_refcnt_attr(mod);
 	module_param_sysfs_remove(mod);
 
-	/* Calls module_kobj_release */
-	kobject_unregister(&mod->mkobj->kobj);
+	kobject_unregister(&mod->mkobj.kobj);
 }
 
 /* Free a module, remove from lists, etc (must hold module mutex). */
@@ -1713,6 +1691,9 @@
 				 / sizeof(struct kernel_param),
 				 NULL);
 	}
+	if (err < 0)
+		goto arch_cleanup;
+
 	err = mod_sysfs_setup(mod, 
 			      (struct kernel_param *)
 			      sechdrs[setupindex].sh_addr,
@@ -2089,11 +2070,9 @@
 {
 	if (!mod || !drv)
 		return;
-	if (!mod->mkobj)
-		return;
 
 	/* Don't check return code; this call is idempotent */
-	sysfs_create_link(&drv->kobj, &mod->mkobj->kobj, "module");
+	sysfs_create_link(&drv->kobj, &mod->mkobj.kobj, "module");
 }
 EXPORT_SYMBOL(module_add_driver);
 
diff -Nru a/kernel/params.c b/kernel/params.c
--- a/kernel/params.c	2005-03-01 23:39:09 -08:00
+++ b/kernel/params.c	2005-03-01 23:39:09 -08:00
@@ -77,10 +77,16 @@
 static char *next_arg(char *args, char **param, char **val)
 {
 	unsigned int i, equals = 0;
-	int in_quote = 0;
+	int in_quote = 0, quoted = 0;
+	char *next;
 
 	/* Chew any extra spaces */
 	while (*args == ' ') args++;
+	if (*args == '"') {
+		args++;
+		in_quote = 1;
+		quoted = 1;
+	}
 
 	for (i = 0; args[i]; i++) {
 		if (args[i] == ' ' && !in_quote)
@@ -106,13 +112,16 @@
 			if (args[i-1] == '"')
 				args[i-1] = '\0';
 		}
+		if (quoted && args[i-1] == '"')
+			args[i-1] = '\0';
 	}
 
 	if (args[i]) {
 		args[i] = '\0';
-		return args + i + 1;
+		next = args + i + 1;
 	} else
-		return args + i;
+		next = args + i;
+	return next;
 }
 
 /* Args looks like "foo=bar,bar2 baz=fuz wiz". */
@@ -357,26 +366,23 @@
 
 struct param_attribute
 {
-	struct attribute attr;
+	struct module_attribute mattr;
 	struct kernel_param *param;
 };
 
-struct param_kobject
+struct module_param_attrs
 {
-	struct kobject kobj;
-
-	unsigned int num_attributes;
-	struct param_attribute attr[0];
+	struct attribute_group grp;
+	struct param_attribute attrs[0];
 };
 
-#define to_param_attr(n) container_of(n, struct param_attribute, attr);
+#define to_param_attr(n) container_of(n, struct param_attribute, mattr);
 
-static ssize_t param_attr_show(struct kobject *kobj,
-			       struct attribute *attr,
-			       char *buf)
+static ssize_t param_attr_show(struct module_attribute *mattr,
+			       struct module *mod, char *buf)
 {
 	int count;
-	struct param_attribute *attribute = to_param_attr(attr);
+	struct param_attribute *attribute = to_param_attr(mattr);
 
 	if (!attribute->param->get)
 		return -EPERM;
@@ -390,12 +396,12 @@
 }
 
 /* sysfs always hands a nul-terminated string in buf.  We rely on that. */
-static ssize_t param_attr_store(struct kobject *kobj,
-				struct attribute *attr,
+static ssize_t param_attr_store(struct module_attribute *mattr,
+				struct module *owner,
 				const char *buf, size_t len)
 {
  	int err;
-	struct param_attribute *attribute = to_param_attr(attr);
+	struct param_attribute *attribute = to_param_attr(mattr);
 
 	if (!attribute->param->set)
 		return -EPERM;
@@ -406,27 +412,6 @@
 	return err;
 }
 
-
-static struct sysfs_ops param_sysfs_ops = {
-	.show = param_attr_show,
-	.store = param_attr_store,
-};
-
-static void param_kobj_release(struct kobject *kobj)
-{
-	kfree(container_of(kobj, struct param_kobject, kobj));
-}
-
-static struct kobj_type param_ktype = {
-	.sysfs_ops =	&param_sysfs_ops,
-	.release =	&param_kobj_release,
-};
-
-static struct kset param_kset = {
-	.subsys =	&module_subsys,
-	.ktype =	&param_ktype,
-};
-
 #ifdef CONFIG_MODULES
 #define __modinit
 #else
@@ -434,54 +419,6 @@
 #endif
 
 /*
- * param_add_attribute - actually adds an parameter to sysfs
- * @mod: owner of parameter
- * @pk: param_kobject the attribute shall be assigned to.
- *      One per module, one per KBUILD_MODNAME.
- * @kp: kernel_param to be added
- * @skip: offset where the parameter name start in kp->name.
- * Needed for built-in modules
- *
- * Fill in data into appropriate &pk->attr[], and create sysfs file.
- */
-static __modinit int param_add_attribute(struct module *mod,
-					 struct param_kobject *pk,
-					 struct kernel_param *kp,
-					 unsigned int skip)
-{
-	struct param_attribute *a;
-	int err;
-
-	a = &pk->attr[pk->num_attributes];
-	a->attr.name = (char *) &kp->name[skip];
-	a->attr.owner = mod;
-	a->attr.mode = kp->perm;
-	a->param = kp;
-	err = sysfs_create_file(&pk->kobj, &a->attr);
-	if (!err)
-		pk->num_attributes++;
-	return err;
-}
-
-/*
- * param_sysfs_remove - remove sysfs support for one module or KBUILD_MODNAME
- * @pk: struct param_kobject which is to be removed
- *
- * Called when an error in registration occurs or a module is removed
- * from the system.
- */
-static __modinit void param_sysfs_remove(struct param_kobject *pk)
-{
-	unsigned int i;
-	for (i = 0; i < pk->num_attributes; i++)
-		sysfs_remove_file(&pk->kobj,&pk->attr[i].attr);
-
-	/* Calls param_kobj_release */
-	kobject_unregister(&pk->kobj);
-}
-
-
-/*
  * param_sysfs_setup - setup sysfs support for one module or KBUILD_MODNAME
  * @mk: struct module_kobject (contains parent kobject)
  * @kparam: array of struct kernel_param, the actual parameter definitions
@@ -492,15 +429,17 @@
  * in sysfs. A pointer to the param_kobject is returned on success,
  * NULL if there's no parameter to export, or other ERR_PTR(err).
  */
-static __modinit struct param_kobject *
+static __modinit struct module_param_attrs *
 param_sysfs_setup(struct module_kobject *mk,
 		  struct kernel_param *kparam,
 		  unsigned int num_params,
 		  unsigned int name_skip)
 {
-	struct param_kobject *pk;
+	struct module_param_attrs *mp;
 	unsigned int valid_attrs = 0;
-	unsigned int i;
+	unsigned int i, size[2];
+	struct param_attribute *pattr;
+	struct attribute **gattr;
 	int err;
 
 	for (i=0; i<num_params; i++) {
@@ -511,42 +450,39 @@
 	if (!valid_attrs)
 		return NULL;
 
-	pk = kmalloc(sizeof(struct param_kobject)
-		     + sizeof(struct param_attribute) * valid_attrs,
-		     GFP_KERNEL);
-	if (!pk)
+	size[0] = ALIGN(sizeof(*mp) +
+			valid_attrs * sizeof(mp->attrs[0]),
+			sizeof(mp->grp.attrs[0]));
+	size[1] = (valid_attrs + 1) * sizeof(mp->grp.attrs[0]);
+
+	mp = kmalloc(size[0] + size[1], GFP_KERNEL);
+	if (!mp)
 		return ERR_PTR(-ENOMEM);
-	memset(pk, 0, sizeof(struct param_kobject)
-	       + sizeof(struct param_attribute) * valid_attrs);
 
-	err = kobject_set_name(&pk->kobj, "parameters");
-	if (err)
-		goto out;
-
-	pk->kobj.kset = &param_kset;
-	pk->kobj.parent = &mk->kobj;
-	err = kobject_register(&pk->kobj);
-	if (err)
-		goto out;
+	mp->grp.name = "parameters";
+	mp->grp.attrs = (void *)mp + size[0];
 
+	pattr = &mp->attrs[0];
+	gattr = &mp->grp.attrs[0];
 	for (i = 0; i < num_params; i++) {
-		if (kparam[i].perm) {
-			err = param_add_attribute(mk->mod, pk,
-						  &kparam[i], name_skip);
-			if (err)
-				goto out_unreg;
+		struct kernel_param *kp = &kparam[i];
+		if (kp->perm) {
+			pattr->param = kp;
+			pattr->mattr.show = param_attr_show;
+			pattr->mattr.store = param_attr_store;
+			pattr->mattr.attr.name = (char *)&kp->name[name_skip];
+			pattr->mattr.attr.owner = mk->mod;
+			pattr->mattr.attr.mode = kp->perm;
+			*(gattr++) = &(pattr++)->mattr.attr;
 		}
 	}
+	*gattr = NULL;
 
-	return pk;
-
-out_unreg:
-	param_sysfs_remove(pk);
-	return ERR_PTR(err);
-
-out:
-	kfree(pk);
-	return ERR_PTR(err);
+	if ((err = sysfs_create_group(&mk->kobj, &mp->grp))) {
+		kfree(mp);
+		return ERR_PTR(err);
+	}
+	return mp;
 }
 
 
@@ -565,13 +501,13 @@
 			     struct kernel_param *kparam,
 			     unsigned int num_params)
 {
-	struct param_kobject *pk;
+	struct module_param_attrs *mp;
 
-	pk = param_sysfs_setup(mod->mkobj, kparam, num_params, 0);
-	if (IS_ERR(pk))
-		return PTR_ERR(pk);
+	mp = param_sysfs_setup(&mod->mkobj, kparam, num_params, 0);
+	if (IS_ERR(mp))
+		return PTR_ERR(mp);
 
-	mod->params_kobject = pk;
+	mod->param_attrs = mp;
 	return 0;
 }
 
@@ -584,9 +520,13 @@
  */
 void module_param_sysfs_remove(struct module *mod)
 {
-	if (mod->params_kobject) {
-		param_sysfs_remove(mod->params_kobject);
-		mod->params_kobject = NULL;
+	if (mod->param_attrs) {
+		sysfs_remove_group(&mod->mkobj.kobj,
+				   &mod->param_attrs->grp);
+		/* We are positive that no one is using any param
+		 * attrs at this point.  Deallocate immediately. */
+		kfree(mod->param_attrs);
+		mod->param_attrs = NULL;
 	}
 }
 #endif
@@ -610,8 +550,10 @@
 	kobject_register(&mk->kobj);
 
 	/* no need to keep the kobject if no parameter is exported */
-	if (!param_sysfs_setup(mk, kparam, num_params, name_skip))
+	if (!param_sysfs_setup(mk, kparam, num_params, name_skip)) {
 		kobject_unregister(&mk->kobj);
+		kfree(mk);
+	}
 }
 
 /*
@@ -691,7 +633,31 @@
 	if (!try_module_get(mk->mod))
 		return -ENODEV;
 
-	ret = attribute->show(mk->mod, buf);
+	ret = attribute->show(attribute, mk->mod, buf);
+
+	module_put(mk->mod);
+
+	return ret;
+}
+
+static ssize_t module_attr_store(struct kobject *kobj,
+				struct attribute *attr,
+				const char *buf, size_t len)
+{
+	struct module_attribute *attribute;
+	struct module_kobject *mk;
+	int ret;
+
+	attribute = to_module_attr(attr);
+	mk = to_module_kobject(kobj);
+
+	if (!attribute->store)
+		return -EPERM;
+
+	if (!try_module_get(mk->mod))
+		return -ENODEV;
+
+	ret = attribute->store(attribute, mk->mod, buf, len);
 
 	module_put(mk->mod);
 
@@ -700,7 +666,7 @@
 
 static struct sysfs_ops module_sysfs_ops = {
 	.show = module_attr_show,
-	.store = NULL,
+	.store = module_attr_store,
 };
 
 #else
@@ -710,14 +676,8 @@
 };
 #endif
 
-static void module_kobj_release(struct kobject *kobj)
-{
-	kfree(container_of(kobj, struct module_kobject, kobj));
-}
-
 static struct kobj_type module_ktype = {
 	.sysfs_ops =	&module_sysfs_ops,
-	.release =	&module_kobj_release,
 };
 
 decl_subsys(module, &module_ktype, NULL);
@@ -728,8 +688,6 @@
 static int __init param_sysfs_init(void)
 {
 	subsystem_register(&module_subsys);
-	kobject_set_name(&param_kset.kobj, "parameters");
-	kset_init(&param_kset);
 
 	param_sysfs_builtin();
 
diff -Nru a/kernel/pid.c b/kernel/pid.c
--- a/kernel/pid.c	2005-03-01 23:38:58 -08:00
+++ b/kernel/pid.c	2005-03-01 23:38:58 -08:00
@@ -60,7 +60,7 @@
 static pidmap_t pidmap_array[PIDMAP_ENTRIES] =
 	 { [ 0 ... PIDMAP_ENTRIES-1 ] = { ATOMIC_INIT(BITS_PER_PAGE), NULL } };
 
-static spinlock_t pidmap_lock __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
+static  __cacheline_aligned_in_smp DEFINE_SPINLOCK(pidmap_lock);
 
 fastcall void free_pidmap(int pid)
 {
diff -Nru a/kernel/posix-timers.c b/kernel/posix-timers.c
--- a/kernel/posix-timers.c	2005-03-01 23:38:57 -08:00
+++ b/kernel/posix-timers.c	2005-03-01 23:38:57 -08:00
@@ -85,7 +85,7 @@
  */
 static kmem_cache_t *posix_timers_cache;
 static struct idr posix_timers_id;
-static spinlock_t idr_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(idr_lock);
 
 /*
  * Just because the timer is not in the timer list does NOT mean it is
diff -Nru a/kernel/power/Kconfig b/kernel/power/Kconfig
--- a/kernel/power/Kconfig	2005-03-01 23:39:09 -08:00
+++ b/kernel/power/Kconfig	2005-03-01 23:39:09 -08:00
@@ -48,7 +48,7 @@
 	  involved in suspending. Also in this case there is a risk that buffers
 	  on disk won't match with saved ones.
 
-	  For more information take a look at Documentation/power/swsusp.txt.
+	  For more information take a look at <file:Documentation/power/swsusp.txt>.
 
 config PM_STD_PARTITION
 	string "Default resume partition"
diff -Nru a/kernel/power/disk.c b/kernel/power/disk.c
--- a/kernel/power/disk.c	2005-03-01 23:38:51 -08:00
+++ b/kernel/power/disk.c	2005-03-01 23:38:51 -08:00
@@ -51,7 +51,7 @@
 	local_irq_save(flags);
 	switch(mode) {
 	case PM_DISK_PLATFORM:
-		device_power_down(PM_SUSPEND_DISK);
+ 		device_power_down(PMSG_SUSPEND);
 		error = pm_ops->enter(PM_SUSPEND_DISK);
 		break;
 	case PM_DISK_SHUTDOWN:
@@ -144,8 +144,10 @@
 	free_some_memory();
 
 	disable_nonboot_cpus();
-	if ((error = device_suspend(PM_SUSPEND_DISK)))
+	if ((error = device_suspend(PMSG_FREEZE))) {
+		printk("Some devices failed to suspend\n");
 		goto Finish;
+	}
 
 	return 0;
  Finish:
@@ -163,7 +165,7 @@
  *
  *	If we're going through the firmware, then get it over with quickly.
  *
- *	If not, then call swsusp to do it's thing, then figure out how
+ *	If not, then call swsusp to do its thing, then figure out how
  *	to power down the system.
  */
 
@@ -201,7 +203,7 @@
  *	software_resume - Resume from a saved image.
  *
  *	Called as a late_initcall (so all devices are discovered and
- *	initialized), we call pmdisk to see if we have a saved image or not.
+ *	initialized), we call swsusp to see if we have a saved image or not.
  *	If so, we quiesce devices, the restore the saved image. We will
  *	return above (in pm_suspend_disk() ) if everything goes well.
  *	Otherwise, we fail gracefully and return to the normally
@@ -221,7 +223,7 @@
 		return 0;
 	}
 
-	pr_debug("PM: Reading pmdisk image.\n");
+	pr_debug("PM: Reading swsusp image.\n");
 
 	if ((error = swsusp_read()))
 		goto Done;
@@ -284,7 +286,7 @@
 
 static ssize_t disk_show(struct subsystem * subsys, char * buf)
 {
-	return sprintf(buf,"%s\n",pm_disk_modes[pm_disk_mode]);
+	return sprintf(buf, "%s\n", pm_disk_modes[pm_disk_mode]);
 }
 
 
diff -Nru a/kernel/power/main.c b/kernel/power/main.c
--- a/kernel/power/main.c	2005-03-01 23:38:53 -08:00
+++ b/kernel/power/main.c	2005-03-01 23:38:53 -08:00
@@ -65,7 +65,7 @@
 			goto Thaw;
 	}
 
-	if ((error = device_suspend(state)))
+	if ((error = device_suspend(PMSG_SUSPEND)))
 		goto Finish;
 	return 0;
  Finish:
@@ -78,13 +78,14 @@
 }
 
 
-static int suspend_enter(u32 state)
+static int suspend_enter(suspend_state_t state)
 {
 	int error = 0;
 	unsigned long flags;
 
 	local_irq_save(flags);
-	if ((error = device_power_down(state)))
+
+	if ((error = device_power_down(PMSG_SUSPEND)))
 		goto Done;
 	error = pm_ops->enter(state);
 	device_power_up();
@@ -99,7 +100,7 @@
  *	@state:		State we're coming out of.
  *
  *	Call platform code to clean up, restart processes, and free the 
- *	console that we've allocated.
+ *	console that we've allocated. This is not called for suspend-to-disk.
  */
 
 static void suspend_finish(suspend_state_t state)
@@ -140,14 +141,14 @@
 	if (down_trylock(&pm_sem))
 		return -EBUSY;
 
-	/* Suspend is hard to get right on SMP. */
-	if (num_online_cpus() != 1) {
-		error = -EPERM;
+	if (state == PM_SUSPEND_DISK) {
+		error = pm_suspend_disk();
 		goto Unlock;
 	}
 
-	if (state == PM_SUSPEND_DISK) {
-		error = pm_suspend_disk();
+	/* Suspend is hard to get right on SMP. */
+	if (num_online_cpus() != 1) {
+		error = -EPERM;
 		goto Unlock;
 	}
 
diff -Nru a/kernel/power/swsusp.c b/kernel/power/swsusp.c
--- a/kernel/power/swsusp.c	2005-03-01 23:38:54 -08:00
+++ b/kernel/power/swsusp.c	2005-03-01 23:38:54 -08:00
@@ -67,18 +67,17 @@
 #include <asm/uaccess.h>
 #include <asm/mmu_context.h>
 #include <asm/pgtable.h>
+#include <asm/tlbflush.h>
 #include <asm/io.h>
 
 #include "power.h"
 
 /* References to section boundaries */
-extern char __nosave_begin, __nosave_end;
-
-extern int is_head_of_free_region(struct page *);
+extern const void __nosave_begin, __nosave_end;
 
 /* Variables to be preserved over suspend */
-int pagedir_order_check;
-int nr_copy_pages_check;
+static int pagedir_order_check;
+static int nr_copy_pages_check;
 
 extern char resume_file[];
 static dev_t resume_device;
@@ -104,14 +103,14 @@
 
 #define SWSUSP_SIG	"S1SUSPEND"
 
-struct swsusp_header {
+static struct swsusp_header {
 	char reserved[PAGE_SIZE - 20 - sizeof(swp_entry_t)];
 	swp_entry_t swsusp_info;
 	char	orig_sig[10];
 	char	sig[10];
 } __attribute__((packed, aligned(PAGE_SIZE))) swsusp_header;
 
-struct swsusp_info swsusp_info;
+static struct swsusp_info swsusp_info;
 
 /*
  * XXX: We try to keep some more pages free so that I/O operations succeed
@@ -174,7 +173,7 @@
 		resume_device == MKDEV(imajor(inode), iminor(inode));
 }
 
-int swsusp_swap_check(void) /* This is called before saving image */
+static int swsusp_swap_check(void) /* This is called before saving image */
 {
 	int i, len;
 	
@@ -421,17 +420,17 @@
 	struct highmem_page *next;
 };
 
-struct highmem_page *highmem_copy = NULL;
+static struct highmem_page *highmem_copy;
 
 static int save_highmem_zone(struct zone *zone)
 {
 	unsigned long zone_pfn;
+	mark_free_pages(zone);
 	for (zone_pfn = 0; zone_pfn < zone->spanned_pages; ++zone_pfn) {
 		struct page *page;
 		struct highmem_page *save;
 		void *kaddr;
 		unsigned long pfn = zone_pfn + zone->zone_start_pfn;
-		int chunk_size;
 
 		if (!(pfn%1000))
 			printk(".");
@@ -448,11 +447,9 @@
 			printk("highmem reserved page?!\n");
 			continue;
 		}
-		if ((chunk_size = is_head_of_free_region(page))) {
-			pfn += chunk_size - 1;
-			zone_pfn += chunk_size - 1;
+		BUG_ON(PageNosave(page));
+		if (PageNosaveFree(page))
 			continue;
-		}
 		save = kmalloc(sizeof(struct highmem_page), GFP_ATOMIC);
 		if (!save)
 			return -ENOMEM;
@@ -524,21 +521,16 @@
  *	We save a page if it's Reserved, and not in the range of pages
  *	statically defined as 'unsaveable', or if it isn't reserved, and
  *	isn't part of a free chunk of pages.
- *	If it is part of a free chunk, we update @pfn to point to the last 
- *	page of the chunk.
  */
 
 static int saveable(struct zone * zone, unsigned long * zone_pfn)
 {
 	unsigned long pfn = *zone_pfn + zone->zone_start_pfn;
-	unsigned long chunk_size;
 	struct page * page;
 
 	if (!pfn_valid(pfn))
 		return 0;
 
-	if (!(pfn%1000))
-		printk(".");
 	page = pfn_to_page(pfn);
 	BUG_ON(PageReserved(page) && PageNosave(page));
 	if (PageNosave(page))
@@ -547,10 +539,8 @@
 		pr_debug("[nosave pfn 0x%lx]", pfn);
 		return 0;
 	}
-	if ((chunk_size = is_head_of_free_region(page))) {
-		*zone_pfn += chunk_size - 1;
+	if (PageNosaveFree(page))
 		return 0;
-	}
 
 	return 1;
 }
@@ -563,10 +553,11 @@
 	nr_copy_pages = 0;
 
 	for_each_zone(zone) {
-		if (!is_highmem(zone)) {
-			for (zone_pfn = 0; zone_pfn < zone->spanned_pages; ++zone_pfn)
-				nr_copy_pages += saveable(zone, &zone_pfn);
-		}
+		if (is_highmem(zone))
+			continue;
+		mark_free_pages(zone);
+		for (zone_pfn = 0; zone_pfn < zone->spanned_pages; ++zone_pfn)
+			nr_copy_pages += saveable(zone, &zone_pfn);
 	}
 }
 
@@ -576,52 +567,25 @@
 	struct zone *zone;
 	unsigned long zone_pfn;
 	struct pbe * pbe = pagedir_nosave;
+	int to_copy = nr_copy_pages;
 	
 	for_each_zone(zone) {
-		if (!is_highmem(zone))
-			for (zone_pfn = 0; zone_pfn < zone->spanned_pages; ++zone_pfn) {
-				if (saveable(zone, &zone_pfn)) {
-					struct page * page;
-					page = pfn_to_page(zone_pfn + zone->zone_start_pfn);
-					pbe->orig_address = (long) page_address(page);
-					/* copy_page is no usable for copying task structs. */
-					memcpy((void *)pbe->address, (void *)pbe->orig_address, PAGE_SIZE);
-					pbe++;
-				}
-			}
-	}
-}
-
-
-static void free_suspend_pagedir_zone(struct zone *zone, unsigned long pagedir)
-{
-	unsigned long zone_pfn, pagedir_end, pagedir_pfn, pagedir_end_pfn;
-	pagedir_end = pagedir + (PAGE_SIZE << pagedir_order);
-	pagedir_pfn = __pa(pagedir) >> PAGE_SHIFT;
-	pagedir_end_pfn = __pa(pagedir_end) >> PAGE_SHIFT;
-	for (zone_pfn = 0; zone_pfn < zone->spanned_pages; ++zone_pfn) {
-		struct page *page;
-		unsigned long pfn = zone_pfn + zone->zone_start_pfn;
-		if (!pfn_valid(pfn))
-			continue;
-		page = pfn_to_page(pfn);
-		if (!TestClearPageNosave(page))
-			continue;
-		else if (pfn >= pagedir_pfn && pfn < pagedir_end_pfn)
+		if (is_highmem(zone))
 			continue;
-		__free_page(page);
-	}
-}
-
-void swsusp_free(void)
-{
-	unsigned long p = (unsigned long)pagedir_save;
-	struct zone *zone;
-	for_each_zone(zone) {
-		if (!is_highmem(zone))
-			free_suspend_pagedir_zone(zone, p);
+		mark_free_pages(zone);
+		for (zone_pfn = 0; zone_pfn < zone->spanned_pages; ++zone_pfn) {
+			if (saveable(zone, &zone_pfn)) {
+				struct page * page;
+				page = pfn_to_page(zone_pfn + zone->zone_start_pfn);
+				pbe->orig_address = (long) page_address(page);
+				/* copy_page is not usable for copying task structs. */
+				memcpy((void *)pbe->address, (void *)pbe->orig_address, PAGE_SIZE);
+				pbe++;
+				to_copy--;
+			}
+		}
 	}
-	free_pages(p, pagedir_order);
+	BUG_ON(to_copy);
 }
 
 
@@ -687,6 +651,24 @@
 	return 0;
 }
 
+/**
+ *	free_image_pages - Free pages allocated for snapshot
+ */
+
+static void free_image_pages(void)
+{
+	struct pbe * p;
+	int i;
+
+	p = pagedir_save;
+	for (i = 0, p = pagedir_save; i < nr_copy_pages; i++, p++) {
+		if (p->address) {
+			ClearPageNosave(virt_to_page(p->address));
+			free_page(p->address);
+			p->address = 0;
+		}
+	}
+}
 
 /**
  *	alloc_image_pages - Allocate pages for the snapshot.
@@ -700,18 +682,19 @@
 
 	for (i = 0, p = pagedir_save; i < nr_copy_pages; i++, p++) {
 		p->address = get_zeroed_page(GFP_ATOMIC | __GFP_COLD);
-		if(!p->address)
-			goto Error;
+		if (!p->address)
+			return -ENOMEM;
 		SetPageNosave(virt_to_page(p->address));
 	}
 	return 0;
- Error:
-	do { 
-		if (p->address)
-			free_page(p->address);
-		p->address = 0;
-	} while (p-- > pagedir_save);
-	return -ENOMEM;
+}
+
+void swsusp_free(void)
+{
+	BUG_ON(PageNosave(virt_to_page(pagedir_save)));
+	BUG_ON(PageNosaveFree(virt_to_page(pagedir_save)));
+	free_image_pages();
+	free_pages((unsigned long) pagedir_save, pagedir_order);
 }
 
 
@@ -770,11 +753,11 @@
 		return -ENOSPC;
 
 	if ((error = alloc_pagedir())) {
-		pr_debug("suspend: Allocating pagedir failed.\n");
+		printk(KERN_ERR "suspend: Allocating pagedir failed.\n");
 		return error;
 	}
 	if ((error = alloc_image_pages())) {
-		pr_debug("suspend: Allocating image pages failed.\n");
+		printk(KERN_ERR "suspend: Allocating image pages failed.\n");
 		swsusp_free();
 		return error;
 	}
@@ -784,9 +767,8 @@
 	return 0;
 }
 
-int suspend_prepare_image(void)
+static int suspend_prepare_image(void)
 {
-	unsigned int nr_needed_pages;
 	int error;
 
 	pr_debug("swsusp: critical section: \n");
@@ -799,7 +781,6 @@
 	drain_local_pages();
 	count_data_pages();
 	printk("swsusp: Need to copy %u pages\n",nr_copy_pages);
-	nr_needed_pages = nr_copy_pages + PAGES_FOR_IO;
 
 	error = swsusp_alloc();
 	if (error)
@@ -862,11 +843,22 @@
 	if ((error = arch_prepare_suspend()))
 		return error;
 	local_irq_disable();
+	/* At this point, device_suspend() has been called, but *not*
+	 * device_power_down(). We *must* device_power_down() now.
+	 * Otherwise, drivers for some devices (e.g. interrupt controllers)
+	 * become desynchronized with the actual state of the hardware
+	 * at resume time, and evil weirdness ensues.
+	 */
+	if ((error = device_power_down(PMSG_FREEZE))) {
+		local_irq_enable();
+		return error;
+	}
 	save_processor_state();
 	error = swsusp_arch_suspend();
 	/* Restore control flow magically appears here */
 	restore_processor_state();
 	restore_highmem();
+	device_power_up();
 	local_irq_enable();
 	return error;
 }
@@ -886,6 +878,7 @@
 {
 	int error;
 	local_irq_disable();
+	device_power_down(PMSG_FREEZE);
 	/* We'll ignore saved state, but this gets preempt count (etc) right */
 	save_processor_state();
 	error = swsusp_arch_resume();
@@ -895,30 +888,23 @@
 	BUG_ON(!error);
 	restore_processor_state();
 	restore_highmem();
+	device_power_up();
 	local_irq_enable();
 	return error;
 }
 
-
-
 /* More restore stuff */
 
-#define does_collide(addr) does_collide_order(pagedir_nosave, addr, 0)
-
 /*
  * Returns true if given address/order collides with any orig_address 
  */
-static int __init does_collide_order(suspend_pagedir_t *pagedir, unsigned long addr,
-		int order)
+static int __init does_collide_order(unsigned long addr, int order)
 {
 	int i;
-	unsigned long addre = addr + (PAGE_SIZE<<order);
 	
-	for (i=0; i < nr_copy_pages; i++)
-		if ((pagedir+i)->orig_address >= addr &&
-			(pagedir+i)->orig_address < addre)
+	for (i=0; i < (1<<order); i++)
+		if (!PageNosaveFree(virt_to_page(addr + i * PAGE_SIZE)))
 			return 1;
-
 	return 0;
 }
 
@@ -937,7 +923,7 @@
 			addr = get_zeroed_page(GFP_ATOMIC);
 			if(!addr)
 				return -ENOMEM;
-		} while (does_collide(addr));
+		} while (does_collide_order(addr, 0));
 
 		(pagedir_nosave+i)->address = addr;
 	}
@@ -954,16 +940,34 @@
 	void **eaten_memory = NULL;
 	void **c = eaten_memory, *m, *f;
 	int ret = 0;
+	struct zone *zone;
+	int i;
+	struct pbe *p;
+	unsigned long zone_pfn;
 
 	printk("Relocating pagedir ");
 
-	if (!does_collide_order(old_pagedir, (unsigned long)old_pagedir, pagedir_order)) {
+	/* Set page flags */
+
+	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));
+	}
+
+	/* Clear orig address */
+
+	for(i = 0, p = pagedir_nosave; i < nr_copy_pages; i++, p++) {
+		ClearPageNosaveFree(virt_to_page(p->orig_address));
+	}
+
+	if (!does_collide_order((unsigned long)old_pagedir, pagedir_order)) {
 		printk("not necessary\n");
 		return check_pagedir();
 	}
 
 	while ((m = (void *) __get_free_pages(GFP_ATOMIC, pagedir_order)) != NULL) {
-		if (!does_collide_order(old_pagedir, (unsigned long)m, pagedir_order))
+		if (!does_collide_order((unsigned long)m, pagedir_order))
 			break;
 		eaten_memory = m;
 		printk( "." ); 
@@ -1003,24 +1007,14 @@
 
 static atomic_t io_done = ATOMIC_INIT(0);
 
-static void start_io(void)
-{
-	atomic_set(&io_done,1);
-}
-
 static int end_io(struct bio * bio, unsigned int num, int err)
 {
-	atomic_set(&io_done,0);
+	if (!test_bit(BIO_UPTODATE, &bio->bi_flags))
+		panic("I/O error reading memory image");
+	atomic_set(&io_done, 0);
 	return 0;
 }
 
-static void wait_io(void)
-{
-	while(atomic_read(&io_done))
-		io_schedule();
-}
-
-
 static struct block_device * resume_bdev;
 
 /**
@@ -1055,20 +1049,23 @@
 
 	if (rw == WRITE)
 		bio_set_pages_dirty(bio);
-	start_io();
+
+	atomic_set(&io_done, 1);
 	submit_bio(rw | (1 << BIO_RW_SYNC), bio);
-	wait_io();
+	while (atomic_read(&io_done))
+		yield();
+
  Done:
 	bio_put(bio);
 	return error;
 }
 
-int bio_read_page(pgoff_t page_off, void * page)
+static int bio_read_page(pgoff_t page_off, void * page)
 {
 	return submit(READ, page_off, page);
 }
 
-int bio_write_page(pgoff_t page_off, void * page)
+static int bio_write_page(pgoff_t page_off, void * page)
 {
 	return submit(WRITE, page_off, page);
 }
@@ -1113,6 +1110,7 @@
 		return -EPERM;
 	}
 	nr_copy_pages = swsusp_info.image_pages;
+	pagedir_order = get_bitmask_order(SUSPEND_PD_PAGES(nr_copy_pages));
 	return error;
 }
 
@@ -1179,14 +1177,12 @@
 	int i, n = swsusp_info.pagedir_pages;
 	int error = 0;
 
-	pagedir_order = get_bitmask_order(n);
-
-	addr =__get_free_pages(GFP_ATOMIC, pagedir_order);
+	addr = __get_free_pages(GFP_ATOMIC, pagedir_order);
 	if (!addr)
 		return -ENOMEM;
 	pagedir_nosave = (struct pbe *)addr;
 
-	pr_debug("pmdisk: Reading pagedir (%d Pages)\n",n);
+	pr_debug("swsusp: Reading pagedir (%d Pages)\n",n);
 
 	for (i = 0; i < n && !error; i++, addr += PAGE_SIZE) {
 		unsigned long offset = swp_offset(swsusp_info.pagedir[i]);
@@ -1216,7 +1212,7 @@
 }
 
 /**
- *	pmdisk_read - Read saved image from swap.
+ *	swsusp_read - Read saved image from swap.
  */
 
 int __init swsusp_read(void)
@@ -1240,6 +1236,6 @@
 	if (!error)
 		pr_debug("Reading resume file was successful\n");
 	else
-		pr_debug("pmdisk: Error %d resuming\n", error);
+		pr_debug("swsusp: Error %d resuming\n", error);
 	return error;
 }
diff -Nru a/kernel/printk.c b/kernel/printk.c
--- a/kernel/printk.c	2005-03-01 23:39:17 -08:00
+++ b/kernel/printk.c	2005-03-01 23:39:17 -08:00
@@ -78,7 +78,7 @@
  * It is also used in interesting ways to provide interlocking in
  * release_console_sem().
  */
-static spinlock_t logbuf_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(logbuf_lock);
 
 static char __log_buf[__LOG_BUF_LEN];
 static char *log_buf = __log_buf;
@@ -284,6 +284,7 @@
 			error = __put_user(c,buf);
 			buf++;
 			i++;
+			cond_resched();
 			spin_lock_irq(&logbuf_lock);
 		}
 		spin_unlock_irq(&logbuf_lock);
@@ -325,6 +326,7 @@
 			c = LOG_BUF(j);
 			spin_unlock_irq(&logbuf_lock);
 			error = __put_user(c,&buf[count-1-i]);
+			cond_resched();
 			spin_lock_irq(&logbuf_lock);
 		}
 		spin_unlock_irq(&logbuf_lock);
@@ -340,6 +342,7 @@
 					error = -EFAULT;
 					break;
 				}
+				cond_resched();
 			}
 		}
 		break;
@@ -608,6 +611,16 @@
 }
 EXPORT_SYMBOL(acquire_console_sem);
 
+int try_acquire_console_sem(void)
+{
+	if (down_trylock(&console_sem))
+		return -1;
+	console_locked = 1;
+	console_may_schedule = 0;
+	return 0;
+}
+EXPORT_SYMBOL(try_acquire_console_sem);
+
 int is_console_locked(void)
 {
 	return console_locked;
@@ -642,8 +655,9 @@
 		_con_start = con_start;
 		_log_end = log_end;
 		con_start = log_end;		/* Flush */
-		spin_unlock_irqrestore(&logbuf_lock, flags);
+		spin_unlock(&logbuf_lock);
 		call_console_drivers(_con_start, _log_end);
+		local_irq_restore(flags);
 	}
 	console_locked = 0;
 	console_may_schedule = 0;
@@ -871,7 +885,7 @@
  */
 int __printk_ratelimit(int ratelimit_jiffies, int ratelimit_burst)
 {
-	static spinlock_t ratelimit_lock = SPIN_LOCK_UNLOCKED;
+	static DEFINE_SPINLOCK(ratelimit_lock);
 	static unsigned long toks = 10*5*HZ;
 	static unsigned long last_msg;
 	static int missed;
diff -Nru a/kernel/profile.c b/kernel/profile.c
--- a/kernel/profile.c	2005-03-01 23:39:16 -08:00
+++ b/kernel/profile.c	2005-03-01 23:39:16 -08:00
@@ -83,7 +83,7 @@
 #ifdef CONFIG_PROFILING
  
 static DECLARE_RWSEM(profile_rwsem);
-static rwlock_t handoff_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(handoff_lock);
 static struct notifier_block * task_exit_notifier;
 static struct notifier_block * task_free_notifier;
 static struct notifier_block * munmap_notifier;
@@ -326,17 +326,15 @@
 		node = cpu_to_node(cpu);
 		per_cpu(cpu_profile_flip, cpu) = 0;
 		if (!per_cpu(cpu_profile_hits, cpu)[1]) {
-			page = alloc_pages_node(node, GFP_KERNEL, 0);
+			page = alloc_pages_node(node, GFP_KERNEL | __GFP_ZERO, 0);
 			if (!page)
 				return NOTIFY_BAD;
-			clear_highpage(page);
 			per_cpu(cpu_profile_hits, cpu)[1] = page_address(page);
 		}
 		if (!per_cpu(cpu_profile_hits, cpu)[0]) {
-			page = alloc_pages_node(node, GFP_KERNEL, 0);
+			page = alloc_pages_node(node, GFP_KERNEL | __GFP_ZERO, 0);
 			if (!page)
 				goto out_free;
-			clear_highpage(page);
 			per_cpu(cpu_profile_hits, cpu)[0] = page_address(page);
 		}
 		break;
@@ -510,16 +508,14 @@
 		int node = cpu_to_node(cpu);
 		struct page *page;
 
-		page = alloc_pages_node(node, GFP_KERNEL, 0);
+		page = alloc_pages_node(node, GFP_KERNEL | __GFP_ZERO, 0);
 		if (!page)
 			goto out_cleanup;
-		clear_highpage(page);
 		per_cpu(cpu_profile_hits, cpu)[1]
 				= (struct profile_hit *)page_address(page);
-		page = alloc_pages_node(node, GFP_KERNEL, 0);
+		page = alloc_pages_node(node, GFP_KERNEL | __GFP_ZERO, 0);
 		if (!page)
 			goto out_cleanup;
-		clear_highpage(page);
 		per_cpu(cpu_profile_hits, cpu)[0]
 				= (struct profile_hit *)page_address(page);
 	}
diff -Nru a/kernel/ptrace.c b/kernel/ptrace.c
--- a/kernel/ptrace.c	2005-03-01 23:39:18 -08:00
+++ b/kernel/ptrace.c	2005-03-01 23:39:18 -08:00
@@ -38,10 +38,24 @@
 	SET_LINKS(child);
 }
  
-static inline int pending_resume_signal(struct sigpending *pending)
+/*
+ * Turn a tracing stop into a normal stop now, since with no tracer there
+ * would be no way to wake it up with SIGCONT or SIGKILL.  If there was a
+ * signal sent that would resume the child, but didn't because it was in
+ * TASK_TRACED, resume it now.
+ * Requires that irqs be disabled.
+ */
+void ptrace_untrace(task_t *child)
 {
-#define M(sig) (1UL << ((sig)-1))
-	return sigtestsetmask(&pending->signal, M(SIGCONT) | M(SIGKILL));
+	spin_lock(&child->sighand->siglock);
+	if (child->state == TASK_TRACED) {
+		if (child->signal->flags & SIGNAL_STOP_STOPPED) {
+			child->state = TASK_STOPPED;
+		} else {
+			signal_wake_up(child, 1);
+		}
+	}
+	spin_unlock(&child->sighand->siglock);
 }
 
 /*
@@ -55,29 +69,15 @@
 	if (!child->ptrace)
 		BUG();
 	child->ptrace = 0;
-	if (list_empty(&child->ptrace_list))
-		return;
-	list_del_init(&child->ptrace_list);
-	REMOVE_LINKS(child);
-	child->parent = child->real_parent;
-	SET_LINKS(child);
-
-	if (child->state == TASK_TRACED) {
-		/*
-		 * Turn a tracing stop into a normal stop now,
-		 * since with no tracer there would be no way
-		 * to wake it up with SIGCONT or SIGKILL.
-		 * If there was a signal sent that would resume the child,
-		 * but didn't because it was in TASK_TRACED, resume it now.
-		 */
-		spin_lock(&child->sighand->siglock);
-		child->state = TASK_STOPPED;
-		if (pending_resume_signal(&child->pending) ||
-		    pending_resume_signal(&child->signal->shared_pending)) {
-			signal_wake_up(child, 1);
-		}
-		spin_unlock(&child->sighand->siglock);
+	if (!list_empty(&child->ptrace_list)) {
+		list_del_init(&child->ptrace_list);
+		REMOVE_LINKS(child);
+		child->parent = child->real_parent;
+		SET_LINKS(child);
 	}
+
+	if (child->state == TASK_TRACED)
+		ptrace_untrace(child);
 }
 
 /*
@@ -319,18 +319,45 @@
 
 static int ptrace_getsiginfo(struct task_struct *child, siginfo_t __user * data)
 {
-	if (child->last_siginfo == NULL)
-		return -EINVAL;
-	return copy_siginfo_to_user(data, child->last_siginfo);
+	siginfo_t lastinfo;
+	int error = -ESRCH;
+
+	read_lock(&tasklist_lock);
+	if (likely(child->sighand != NULL)) {
+		error = -EINVAL;
+		spin_lock_irq(&child->sighand->siglock);
+		if (likely(child->last_siginfo != NULL)) {
+			lastinfo = *child->last_siginfo;
+			error = 0;
+		}
+		spin_unlock_irq(&child->sighand->siglock);
+	}
+	read_unlock(&tasklist_lock);
+	if (!error)
+		return copy_siginfo_to_user(data, &lastinfo);
+	return error;
 }
 
 static int ptrace_setsiginfo(struct task_struct *child, siginfo_t __user * data)
 {
-	if (child->last_siginfo == NULL)
-		return -EINVAL;
-	if (copy_from_user(child->last_siginfo, data, sizeof (siginfo_t)) != 0)
+	siginfo_t newinfo;
+	int error = -ESRCH;
+
+	if (copy_from_user(&newinfo, data, sizeof (siginfo_t)))
 		return -EFAULT;
-	return 0;
+
+	read_lock(&tasklist_lock);
+	if (likely(child->sighand != NULL)) {
+		error = -EINVAL;
+		spin_lock_irq(&child->sighand->siglock);
+		if (likely(child->last_siginfo != NULL)) {
+			*child->last_siginfo = newinfo;
+			error = 0;
+		}
+		spin_unlock_irq(&child->sighand->siglock);
+	}
+	read_unlock(&tasklist_lock);
+	return error;
 }
 
 int ptrace_request(struct task_struct *child, long request,
diff -Nru a/kernel/rcupdate.c b/kernel/rcupdate.c
--- a/kernel/rcupdate.c	2005-03-01 23:38:44 -08:00
+++ b/kernel/rcupdate.c	2005-03-01 23:38:44 -08:00
@@ -49,9 +49,9 @@
 
 /* Definition for rcupdate control block. */
 struct rcu_ctrlblk rcu_ctrlblk = 
-	{ .cur = -300, .completed = -300 , .lock = SEQCNT_ZERO };
+	{ .cur = -300, .completed = -300 };
 struct rcu_ctrlblk rcu_bh_ctrlblk =
-	{ .cur = -300, .completed = -300 , .lock = SEQCNT_ZERO };
+	{ .cur = -300, .completed = -300 };
 
 /* Bookkeeping of the progress of the grace period */
 struct rcu_state {
@@ -60,9 +60,9 @@
 	                              /* for current batch to proceed.        */
 };
 
-struct rcu_state rcu_state ____cacheline_maxaligned_in_smp =
+static struct rcu_state rcu_state ____cacheline_maxaligned_in_smp =
 	  {.lock = SPIN_LOCK_UNLOCKED, .cpumask = CPU_MASK_NONE };
-struct rcu_state rcu_bh_state ____cacheline_maxaligned_in_smp =
+static struct rcu_state rcu_bh_state ____cacheline_maxaligned_in_smp =
 	  {.lock = SPIN_LOCK_UNLOCKED, .cpumask = CPU_MASK_NONE };
 
 DEFINE_PER_CPU(struct rcu_data, rcu_data) = { 0L };
@@ -185,10 +185,13 @@
 			rcp->completed == rcp->cur) {
 		/* Can't change, since spin lock held. */
 		cpus_andnot(rsp->cpumask, cpu_online_map, nohz_cpu_mask);
-		write_seqcount_begin(&rcp->lock);
+
 		rcp->next_pending = 0;
+		/* next_pending == 0 must be visible in __rcu_process_callbacks()
+		 * before it can see new value of cur.
+		 */
+		smp_wmb();
 		rcp->cur++;
-		write_seqcount_end(&rcp->lock);
 	}
 }
 
@@ -216,9 +219,9 @@
 			struct rcu_state *rsp, struct rcu_data *rdp)
 {
 	if (rdp->quiescbatch != rcp->cur) {
-		/* new grace period: record qsctr value. */
+		/* start new grace period: */
 		rdp->qs_pending = 1;
-		rdp->last_qsctr = rdp->qsctr;
+		rdp->passed_quiesc = 0;
 		rdp->quiescbatch = rcp->cur;
 		return;
 	}
@@ -231,11 +234,10 @@
 		return;
 
 	/* 
-	 * Races with local timer interrupt - in the worst case
-	 * we may miss one quiescent state of that CPU. That is
-	 * tolerable. So no need to disable interrupts.
+	 * Was there a quiescent state since the beginning of the grace
+	 * period? If no, then exit and wait for the next call.
 	 */
-	if (rdp->qsctr == rdp->last_qsctr)
+	if (!rdp->passed_quiesc)
 		return;
 	rdp->qs_pending = 0;
 
@@ -319,8 +321,6 @@
 
 	local_irq_disable();
 	if (rdp->nxtlist && !rdp->curlist) {
-		int next_pending, seq;
-
 		rdp->curlist = rdp->nxtlist;
 		rdp->curtail = rdp->nxttail;
 		rdp->nxtlist = NULL;
@@ -330,14 +330,15 @@
 		/*
 		 * start the next batch of callbacks
 		 */
-		do {
-			seq = read_seqcount_begin(&rcp->lock);
-			/* determine batch number */
-			rdp->batch = rcp->cur + 1;
-			next_pending = rcp->next_pending;
-		} while (read_seqcount_retry(&rcp->lock, seq));
 
-		if (!next_pending) {
+		/* determine batch number */
+		rdp->batch = rcp->cur + 1;
+		/* see the comment and corresponding wmb() in
+		 * the rcu_start_batch()
+		 */
+		smp_rmb();
+
+		if (!rcp->next_pending) {
 			/* and start it/schedule start if it's a new batch */
 			spin_lock(&rsp->lock);
 			rcu_start_batch(rcp, rsp, 1);
diff -Nru a/kernel/resource.c b/kernel/resource.c
--- a/kernel/resource.c	2005-03-01 23:39:07 -08:00
+++ b/kernel/resource.c	2005-03-01 23:39:07 -08:00
@@ -39,7 +39,7 @@
 
 EXPORT_SYMBOL(iomem_resource);
 
-static rwlock_t resource_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(resource_lock);
 
 #ifdef CONFIG_PROC_FS
 
diff -Nru a/kernel/sched.c b/kernel/sched.c
--- a/kernel/sched.c	2005-03-01 23:39:09 -08:00
+++ b/kernel/sched.c	2005-03-01 23:39:09 -08:00
@@ -36,6 +36,7 @@
 #include <linux/blkdev.h>
 #include <linux/delay.h>
 #include <linux/smp.h>
+#include <linux/threads.h>
 #include <linux/timer.h>
 #include <linux/rcupdate.h>
 #include <linux/cpu.h>
@@ -48,12 +49,6 @@
 
 #include <asm/unistd.h>
 
-#ifdef CONFIG_NUMA
-#define cpu_to_node_mask(cpu) node_to_cpumask(cpu_to_node(cpu))
-#else
-#define cpu_to_node_mask(cpu) (cpu_online_map)
-#endif
-
 /*
  * Convert user-nice values [ -20 ... 0 ... 19 ]
  * to static priority [ MAX_RT_PRIO..MAX_PRIO-1 ],
@@ -97,7 +92,6 @@
 #define MAX_SLEEP_AVG		(DEF_TIMESLICE * MAX_BONUS)
 #define STARVATION_LIMIT	(MAX_SLEEP_AVG)
 #define NS_MAX_SLEEP_AVG	(JIFFIES_TO_NS(MAX_SLEEP_AVG))
-#define CREDIT_LIMIT		100
 
 /*
  * If a task is 'interactive' then we reinsert it in the active
@@ -131,12 +125,14 @@
 	(NS_TO_JIFFIES((p)->sleep_avg) * MAX_BONUS / \
 		MAX_SLEEP_AVG)
 
+#define GRANULARITY	(10 * HZ / 1000 ? : 1)
+
 #ifdef CONFIG_SMP
-#define TIMESLICE_GRANULARITY(p)	(MIN_TIMESLICE * \
+#define TIMESLICE_GRANULARITY(p)	(GRANULARITY * \
 		(1 << (((MAX_BONUS - CURRENT_BONUS(p)) ? : 1) - 1)) * \
 			num_online_cpus())
 #else
-#define TIMESLICE_GRANULARITY(p)	(MIN_TIMESLICE * \
+#define TIMESLICE_GRANULARITY(p)	(GRANULARITY * \
 		(1 << (((MAX_BONUS - CURRENT_BONUS(p)) ? : 1) - 1)))
 #endif
 
@@ -153,12 +149,6 @@
 	(JIFFIES_TO_NS(MAX_SLEEP_AVG * \
 		(MAX_BONUS / 2 + DELTA((p)) + 1) / MAX_BONUS - 1))
 
-#define HIGH_CREDIT(p) \
-	((p)->interactive_credit > CREDIT_LIMIT)
-
-#define LOW_CREDIT(p) \
-	((p)->interactive_credit < -CREDIT_LIMIT)
-
 #define TASK_PREEMPTS_CURR(p, rq) \
 	((p)->prio < (rq)->curr->prio)
 
@@ -426,11 +416,11 @@
 	.release = single_release,
 };
 
-# define schedstat_inc(rq, field)	rq->field++;
-# define schedstat_add(rq, field, amt)	rq->field += amt;
+# define schedstat_inc(rq, field)	do { (rq)->field++; } while (0)
+# define schedstat_add(rq, field, amt)	do { (rq)->field += (amt); } while (0)
 #else /* !CONFIG_SCHEDSTATS */
-# define schedstat_inc(rq, field)	do { } while (0);
-# define schedstat_add(rq, field, amt)	do { } while (0);
+# define schedstat_inc(rq, field)	do { } while (0)
+# define schedstat_add(rq, field, amt)	do { } while (0)
 #endif
 
 /*
@@ -448,11 +438,21 @@
 	return rq;
 }
 
-static inline void rq_unlock(runqueue_t *rq)
-	__releases(rq->lock)
+#ifdef CONFIG_SCHED_SMT
+static int cpu_and_siblings_are_idle(int cpu)
 {
-	spin_unlock_irq(&rq->lock);
+	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
 /*
@@ -581,10 +581,14 @@
 }
 
 /*
- * Used by the migration code - we pull tasks from the head of the
- * remote queue so we want these tasks to show up at the head of the
- * local queue:
+ * Put task to the end of the run list without the overhead of dequeue
+ * followed by enqueue.
  */
+static void requeue_task(struct task_struct *p, prio_array_t *array)
+{
+	list_move_tail(&p->run_list, array->queue + p->prio);
+}
+
 static inline void enqueue_task_head(struct task_struct *p, prio_array_t *array)
 {
 	list_add(&p->run_list, array->queue + p->prio);
@@ -663,8 +667,6 @@
 			sleep_time > INTERACTIVE_SLEEP(p)) {
 				p->sleep_avg = JIFFIES_TO_NS(MAX_SLEEP_AVG -
 						DEF_TIMESLICE);
-				if (!HIGH_CREDIT(p))
-					p->interactive_credit++;
 		} else {
 			/*
 			 * The lower the sleep avg a task has the more
@@ -673,19 +675,11 @@
 			sleep_time *= (MAX_BONUS - CURRENT_BONUS(p)) ? : 1;
 
 			/*
-			 * Tasks with low interactive_credit are limited to
-			 * one timeslice worth of sleep avg bonus.
-			 */
-			if (LOW_CREDIT(p) &&
-			    sleep_time > JIFFIES_TO_NS(task_timeslice(p)))
-				sleep_time = JIFFIES_TO_NS(task_timeslice(p));
-
-			/*
-			 * Non high_credit tasks waking from uninterruptible
-			 * sleep are limited in their sleep_avg rise as they
-			 * are likely to be cpu hogs waiting on I/O
+			 * Tasks waking from uninterruptible sleep are
+			 * limited in their sleep_avg rise as they
+			 * are likely to be waiting on I/O
 			 */
-			if (p->activated == -1 && !HIGH_CREDIT(p) && p->mm) {
+			if (p->activated == -1 && p->mm) {
 				if (p->sleep_avg >= INTERACTIVE_SLEEP(p))
 					sleep_time = 0;
 				else if (p->sleep_avg + sleep_time >=
@@ -705,11 +699,8 @@
 			 */
 			p->sleep_avg += sleep_time;
 
-			if (p->sleep_avg > NS_MAX_SLEEP_AVG) {
+			if (p->sleep_avg > NS_MAX_SLEEP_AVG)
 				p->sleep_avg = NS_MAX_SLEEP_AVG;
-				if (!HIGH_CREDIT(p))
-					p->interactive_credit++;
-			}
 		}
 	}
 
@@ -787,7 +778,7 @@
 {
 	int need_resched, nrpolling;
 
-	BUG_ON(!spin_is_locked(&task_rq(p)->lock));
+	assert_spin_locked(&task_rq(p)->lock);
 
 	/* minimise the chance of sending an interrupt to poll_idle() */
 	nrpolling = test_tsk_thread_flag(p,TIF_POLLING_NRFLAG);
@@ -876,7 +867,7 @@
 repeat:
 	rq = task_rq_lock(p, &flags);
 	/* Must be off runqueue entirely, not preempted. */
-	if (unlikely(p->array)) {
+	if (unlikely(p->array || task_running(rq, p))) {
 		/* If it's preempted, we yield.  It could be a while. */
 		preempted = !task_running(rq, p);
 		task_rq_unlock(rq, &flags);
@@ -894,6 +885,12 @@
  *
  * Cause a process which is running on another CPU to enter
  * kernel-mode, without any delay. (to get signals handled.)
+ *
+ * NOTE: this function doesnt have to take the runqueue lock,
+ * because all it wants to ensure is that the remote task enters
+ * the kernel. If the IPI races and the task has been migrated
+ * to another CPU then no harm is done and the purpose has been
+ * achieved as well.
  */
 void kick_process(task_t *p)
 {
@@ -934,9 +931,10 @@
 #endif
 
 /*
- * wake_idle() is useful especially on SMT architectures to wake a
- * task onto an idle sibling if we would otherwise wake it onto a
- * busy sibling.
+ * wake_idle() will wake a task on an idle cpu if task->cpu is
+ * not idle and an idle cpu is available.  The span of cpus to
+ * search starts with cpus closest then further out as needed,
+ * so we always favor a closer, idle cpu.
  *
  * Returns the CPU we should wake onto.
  */
@@ -944,24 +942,23 @@
 static int wake_idle(int cpu, task_t *p)
 {
 	cpumask_t tmp;
-	runqueue_t *rq = cpu_rq(cpu);
 	struct sched_domain *sd;
 	int i;
 
 	if (idle_cpu(cpu))
 		return cpu;
 
-	sd = rq->sd;
-	if (!(sd->flags & SD_WAKE_IDLE))
-		return cpu;
-
-	cpus_and(tmp, sd->span, p->cpus_allowed);
-
-	for_each_cpu_mask(i, tmp) {
-		if (idle_cpu(i))
-			return i;
+	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);
+			for_each_cpu_mask(i, tmp) {
+				if (idle_cpu(i))
+					return i;
+			}
+		}
+		else break;
 	}
-
 	return cpu;
 }
 #else
@@ -1073,7 +1070,7 @@
 out_set_cpu:
 	schedstat_inc(rq, ttwu_attempts);
 	new_cpu = wake_idle(new_cpu, p);
-	if (new_cpu != cpu && cpu_isset(new_cpu, p->cpus_allowed)) {
+	if (new_cpu != cpu) {
 		schedstat_inc(rq, ttwu_moved);
 		set_task_cpu(p, new_cpu);
 		task_rq_unlock(rq, &flags);
@@ -1126,7 +1123,7 @@
 int fastcall wake_up_process(task_t * p)
 {
 	return try_to_wake_up(p, TASK_STOPPED | TASK_TRACED |
-		       		 TASK_INTERRUPTIBLE | TASK_UNINTERRUPTIBLE, 0);
+				 TASK_INTERRUPTIBLE | TASK_UNINTERRUPTIBLE, 0);
 }
 
 EXPORT_SYMBOL(wake_up_process);
@@ -1191,7 +1188,7 @@
 		 */
 		current->time_slice = 1;
 		preempt_disable();
-		scheduler_tick(0, 0);
+		scheduler_tick();
 		local_irq_enable();
 		preempt_enable();
 	} else
@@ -1227,8 +1224,6 @@
 	p->sleep_avg = JIFFIES_TO_NS(CURRENT_BONUS(p) *
 		CHILD_PENALTY / 100 * MAX_SLEEP_AVG / MAX_BONUS);
 
-	p->interactive_credit = 0;
-
 	p->prio = effective_prio(p);
 
 	if (likely(cpu == this_cpu)) {
@@ -1667,13 +1662,18 @@
 	if (!cpu_isset(this_cpu, p->cpus_allowed))
 		return 0;
 
-	/* Aggressive migration if we've failed balancing */
-	if (idle == NEWLY_IDLE ||
-			sd->nr_balance_failed < sd->cache_nice_tries) {
-		if (task_hot(p, rq->timestamp_last_tick, sd))
-			return 0;
-	}
+	/*
+	 * Aggressive migration if:
+	 * 1) the [whole] cpu is idle, or
+	 * 2) too many balance attempts have failed.
+	 */
+
+	if (cpu_and_siblings_are_idle(this_cpu) || \
+			sd->nr_balance_failed > sd->cache_nice_tries)
+		return 1;
 
+	if (task_hot(p, rq->timestamp_last_tick, sd))
+			return 0;
 	return 1;
 }
 
@@ -2009,7 +2009,7 @@
 		if (sd->balance_interval < sd->max_interval)
 			sd->balance_interval++;
 	} else {
-                sd->nr_balance_failed = 0;
+		sd->nr_balance_failed = 0;
 
 		/* We were unbalanced, so reset the balancing interval */
 		sd->balance_interval = sd->min_interval;
@@ -2088,23 +2088,6 @@
 	}
 }
 
-#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
-
-
 /*
  * active_load_balance is run by migration threads. It pushes running tasks
  * off the busiest CPU onto idle CPUs. It requires at least 1 task to be
@@ -2117,7 +2100,9 @@
 {
 	struct sched_domain *sd;
 	struct sched_group *cpu_group;
+	runqueue_t *target_rq;
 	cpumask_t visited_cpus;
+	int cpu;
 
 	schedstat_inc(busiest_rq, alb_cnt);
 	/*
@@ -2126,46 +2111,43 @@
 	 */
 	visited_cpus = CPU_MASK_NONE;
 	for_each_domain(busiest_cpu, sd) {
-		if (!(sd->flags & SD_LOAD_BALANCE) || busiest_rq->nr_running <= 1)
-			break; /* no more domains to search or no more tasks to move */
+		if (!(sd->flags & SD_LOAD_BALANCE))
+			/* no more domains to search */
+			break;
 
 		cpu_group = sd->groups;
-		do { /* sched_groups should either use list_heads or be merged into the domains structure */
-			int cpu, target_cpu = -1;
-			runqueue_t *target_rq;
-
+		do {
 			for_each_cpu_mask(cpu, cpu_group->cpumask) {
-				if (cpu_isset(cpu, visited_cpus) || cpu == busiest_cpu ||
-				    !cpu_and_siblings_are_idle(cpu)) {
-					cpu_set(cpu, visited_cpus);
+				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;
-				}
-				target_cpu = cpu;
-				break;
-			}
-			if (target_cpu == -1)
-				goto next_group; /* failed to find a suitable target cpu in this domain */
-
-			target_rq = cpu_rq(target_cpu);
-
-			/*
-			 * This condition is "impossible", if it occurs we need to fix it
-			 * Reported by Bjorn Helgaas on a 128-cpu setup.
-			 */
-			BUG_ON(busiest_rq == target_rq);
 
-			/* move a task from busiest_rq to target_rq */
-			double_lock_balance(busiest_rq, target_rq);
-			if (move_tasks(target_rq, target_cpu, busiest_rq, 1, sd, SCHED_IDLE)) {
-				schedstat_inc(busiest_rq, alb_lost);
-				schedstat_inc(target_rq, alb_gained);
-			} else {
-				schedstat_inc(busiest_rq, alb_failed);
+				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);
+
+				/* 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(busiest_rq, alb_lost);
+					schedstat_inc(target_rq, alb_gained);
+				} else {
+					schedstat_inc(busiest_rq, alb_failed);
+				}
+				spin_unlock(&target_rq->lock);
 			}
-			spin_unlock(&target_rq->lock);
-next_group:
 			cpu_group = cpu_group->next;
-		} while (cpu_group != sd->groups && busiest_rq->nr_running > 1);
+		} while (cpu_group != sd->groups);
 	}
 }
 
@@ -2275,48 +2257,172 @@
 			((rq)->curr->static_prio > (rq)->best_expired_prio))
 
 /*
+ * Do the virtual cpu time signal calculations.
+ * @p: the process that the cpu time gets accounted to
+ * @cputime: the cpu time spent in user space since the last update
+ */
+static inline void account_it_virt(struct task_struct * p, cputime_t cputime)
+{
+	cputime_t it_virt = p->it_virt_value;
+
+	if (cputime_gt(it_virt, cputime_zero) &&
+	    cputime_gt(cputime, cputime_zero)) {
+		if (cputime_ge(cputime, it_virt)) {
+			it_virt = cputime_add(it_virt, p->it_virt_incr);
+			send_sig(SIGVTALRM, p, 1);
+		}
+		it_virt = cputime_sub(it_virt, cputime);
+		p->it_virt_value = it_virt;
+	}
+}
+
+/*
+ * Do the virtual profiling signal calculations.
+ * @p: the process that the cpu time gets accounted to
+ * @cputime: the cpu time spent in user and kernel space since the last update
+ */
+static void account_it_prof(struct task_struct *p, cputime_t cputime)
+{
+	cputime_t it_prof = p->it_prof_value;
+
+	if (cputime_gt(it_prof, cputime_zero) &&
+	    cputime_gt(cputime, cputime_zero)) {
+		if (cputime_ge(cputime, it_prof)) {
+			it_prof = cputime_add(it_prof, p->it_prof_incr);
+			send_sig(SIGPROF, p, 1);
+		}
+		it_prof = cputime_sub(it_prof, cputime);
+		p->it_prof_value = it_prof;
+	}
+}
+
+/*
+ * Check if the process went over its cputime resource limit after
+ * some cpu time got added to utime/stime.
+ * @p: the process that the cpu time gets accounted to
+ * @cputime: the cpu time spent in user and kernel space since the last update
+ */
+static void check_rlimit(struct task_struct *p, cputime_t cputime)
+{
+	cputime_t total, tmp;
+	unsigned long secs;
+
+	total = cputime_add(p->utime, p->stime);
+	secs = cputime_to_secs(total);
+	if (unlikely(secs >= p->signal->rlim[RLIMIT_CPU].rlim_cur)) {
+		/* Send SIGXCPU every second. */
+		tmp = cputime_sub(total, cputime);
+		if (cputime_to_secs(tmp) < secs)
+			send_sig(SIGXCPU, p, 1);
+		/* and SIGKILL when we go over max.. */
+		if (secs >= p->signal->rlim[RLIMIT_CPU].rlim_max)
+			send_sig(SIGKILL, p, 1);
+	}
+}
+
+/*
+ * Account user cpu time to a process.
+ * @p: the process that the cpu time gets accounted to
+ * @hardirq_offset: the offset to subtract from hardirq_count()
+ * @cputime: the cpu time spent in user space since the last update
+ */
+void account_user_time(struct task_struct *p, cputime_t cputime)
+{
+	struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat;
+	cputime64_t tmp;
+
+	p->utime = cputime_add(p->utime, cputime);
+
+	/* Check for signals (SIGVTALRM, SIGPROF, SIGXCPU & SIGKILL). */
+	check_rlimit(p, cputime);
+	account_it_virt(p, cputime);
+	account_it_prof(p, cputime);
+
+	/* Add user time to cpustat. */
+	tmp = cputime_to_cputime64(cputime);
+	if (TASK_NICE(p) > 0)
+		cpustat->nice = cputime64_add(cpustat->nice, tmp);
+	else
+		cpustat->user = cputime64_add(cpustat->user, tmp);
+}
+
+/*
+ * Account system cpu time to a process.
+ * @p: the process that the cpu time gets accounted to
+ * @hardirq_offset: the offset to subtract from hardirq_count()
+ * @cputime: the cpu time spent in kernel space since the last update
+ */
+void account_system_time(struct task_struct *p, int hardirq_offset,
+			 cputime_t cputime)
+{
+	struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat;
+	runqueue_t *rq = this_rq();
+	cputime64_t tmp;
+
+	p->stime = cputime_add(p->stime, cputime);
+
+	/* Check for signals (SIGPROF, SIGXCPU & SIGKILL). */
+	if (likely(p->signal && p->exit_state < EXIT_ZOMBIE)) {
+		check_rlimit(p, cputime);
+		account_it_prof(p, cputime);
+	}
+
+	/* Add system time to cpustat. */
+	tmp = cputime_to_cputime64(cputime);
+	if (hardirq_count() - hardirq_offset)
+		cpustat->irq = cputime64_add(cpustat->irq, tmp);
+	else if (softirq_count())
+		cpustat->softirq = cputime64_add(cpustat->softirq, tmp);
+	else if (p != rq->idle)
+		cpustat->system = cputime64_add(cpustat->system, tmp);
+	else if (atomic_read(&rq->nr_iowait) > 0)
+		cpustat->iowait = cputime64_add(cpustat->iowait, tmp);
+	else
+		cpustat->idle = cputime64_add(cpustat->idle, tmp);
+}
+
+/*
+ * Account for involuntary wait time.
+ * @p: the process from which the cpu time has been stolen
+ * @steal: the cpu time spent in involuntary wait
+ */
+void account_steal_time(struct task_struct *p, cputime_t steal)
+{
+	struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat;
+	cputime64_t tmp = cputime_to_cputime64(steal);
+	runqueue_t *rq = this_rq();
+
+	if (p == rq->idle) {
+		p->stime = cputime_add(p->stime, steal);
+		if (atomic_read(&rq->nr_iowait) > 0)
+			cpustat->iowait = cputime64_add(cpustat->iowait, tmp);
+		else
+			cpustat->idle = cputime64_add(cpustat->idle, tmp);
+	} else
+		cpustat->steal = cputime64_add(cpustat->steal, tmp);
+}
+
+/*
  * This function gets called by the timer code, with HZ frequency.
  * We call it with interrupts disabled.
  *
  * It also gets called by the fork code, when changing the parent's
  * timeslices.
  */
-void scheduler_tick(int user_ticks, int sys_ticks)
+void scheduler_tick(void)
 {
 	int cpu = smp_processor_id();
-	struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat;
 	runqueue_t *rq = this_rq();
 	task_t *p = current;
 
 	rq->timestamp_last_tick = sched_clock();
 
-	if (rcu_pending(cpu))
-		rcu_check_callbacks(cpu, user_ticks);
-
-	/* note: this timer irq context must be accounted for as well */
-	if (hardirq_count() - HARDIRQ_OFFSET) {
-		cpustat->irq += sys_ticks;
-		sys_ticks = 0;
-	} else if (softirq_count()) {
-		cpustat->softirq += sys_ticks;
-		sys_ticks = 0;
-	}
-
 	if (p == rq->idle) {
-		if (atomic_read(&rq->nr_iowait) > 0)
-			cpustat->iowait += sys_ticks;
-		else
-			cpustat->idle += sys_ticks;
 		if (wake_priority_sleeper(rq))
 			goto out;
 		rebalance_tick(cpu, rq, SCHED_IDLE);
 		return;
 	}
-	if (TASK_NICE(p) > 0)
-		cpustat->nice += user_ticks;
-	else
-		cpustat->user += user_ticks;
-	cpustat->system += sys_ticks;
 
 	/* Task might have expired already, but not scheduled off yet */
 	if (p->array != rq->active) {
@@ -2342,8 +2448,7 @@
 			set_tsk_need_resched(p);
 
 			/* put it at the end of the queue: */
-			dequeue_task(p, rq->active);
-			enqueue_task(p, rq->active);
+			requeue_task(p, rq->active);
 		}
 		goto out_unlock;
 	}
@@ -2384,10 +2489,8 @@
 			(p->time_slice >= TIMESLICE_GRANULARITY(p)) &&
 			(p->array == rq->active)) {
 
-			dequeue_task(p, rq->active);
+			requeue_task(p, rq->active);
 			set_tsk_need_resched(p);
-			p->prio = effective_prio(p);
-			enqueue_task(p, rq->active);
 		}
 	}
 out_unlock:
@@ -2521,6 +2624,38 @@
 }
 #endif
 
+#if defined(CONFIG_PREEMPT) && defined(CONFIG_DEBUG_PREEMPT)
+
+void fastcall add_preempt_count(int val)
+{
+	/*
+	 * Underflow?
+	 */
+	BUG_ON(((int)preempt_count() < 0));
+	preempt_count() += val;
+	/*
+	 * Spinlock count overflowing soon?
+	 */
+	BUG_ON((preempt_count() & PREEMPT_MASK) >= PREEMPT_MASK-10);
+}
+EXPORT_SYMBOL(add_preempt_count);
+
+void fastcall sub_preempt_count(int val)
+{
+	/*
+	 * Underflow?
+	 */
+	BUG_ON(val > preempt_count());
+	/*
+	 * Is the spinlock portion underflowing?
+	 */
+	BUG_ON((val < PREEMPT_MASK) && !(preempt_count() & PREEMPT_MASK));
+	preempt_count() -= val;
+}
+EXPORT_SYMBOL(sub_preempt_count);
+
+#endif
+
 /*
  * schedule() is the main scheduler function.
  */
@@ -2540,7 +2675,7 @@
 	 * schedule() atomically, we ignore that path for now.
 	 * Otherwise, whine if we are scheduling when we should not be.
 	 */
-	if (likely(!(current->exit_state & (EXIT_DEAD | EXIT_ZOMBIE)))) {
+	if (likely(!current->exit_state)) {
 		if (unlikely(in_atomic())) {
 			printk(KERN_ERR "scheduling while atomic: "
 				"%s/0x%08x/%d\n",
@@ -2561,7 +2696,7 @@
 	 * The idle thread is not allowed to schedule!
 	 * Remove this check after it has been exercised a bit.
 	 */
-	if (unlikely(current == rq->idle) && current->state != TASK_RUNNING) {
+	if (unlikely(prev == rq->idle) && prev->state != TASK_RUNNING) {
 		printk(KERN_ERR "bad: scheduling from the idle thread!\n");
 		dump_stack();
 	}
@@ -2574,21 +2709,16 @@
 		run_time = NS_MAX_SLEEP_AVG;
 
 	/*
-	 * Tasks with interactive credits get charged less run_time
-	 * at high sleep_avg to delay them losing their interactive
-	 * status
+	 * Tasks charged proportionately less run_time at high sleep_avg to
+	 * delay them losing their interactive status
 	 */
-	if (HIGH_CREDIT(prev))
-		run_time /= (CURRENT_BONUS(prev) ? : 1);
+	run_time /= (CURRENT_BONUS(prev) ? : 1);
 
 	spin_lock_irq(&rq->lock);
 
-	if (unlikely(current->flags & PF_DEAD))
-		current->state = EXIT_DEAD;
-	/*
-	 * if entering off of a kernel preemption go straight
-	 * to picking the next task.
-	 */
+	if (unlikely(prev->flags & PF_DEAD))
+		prev->state = EXIT_DEAD;
+
 	switch_count = &prev->nivcsw;
 	if (prev->state && !(preempt_count() & PREEMPT_ACTIVE)) {
 		switch_count = &prev->nvcsw;
@@ -2670,11 +2800,8 @@
 	rcu_qsctr_inc(task_cpu(prev));
 
 	prev->sleep_avg -= run_time;
-	if ((long)prev->sleep_avg <= 0) {
+	if ((long)prev->sleep_avg <= 0)
 		prev->sleep_avg = 0;
-		if (!(HIGH_CREDIT(prev) || LOW_CREDIT(prev)))
-			prev->interactive_credit--;
-	}
 	prev->timestamp = prev->last_ran = now;
 
 	sched_info_switch(prev, next);
@@ -2711,7 +2838,10 @@
 asmlinkage void __sched preempt_schedule(void)
 {
 	struct thread_info *ti = current_thread_info();
-
+#ifdef CONFIG_PREEMPT_BKL
+	struct task_struct *task = current;
+	int saved_lock_depth;
+#endif
 	/*
 	 * If there is a non-zero preempt_count or interrupts are disabled,
 	 * we do not want to preempt the current task.  Just return..
@@ -2720,9 +2850,21 @@
 		return;
 
 need_resched:
-	ti->preempt_count = PREEMPT_ACTIVE;
+	add_preempt_count(PREEMPT_ACTIVE);
+	/*
+	 * We keep the big kernel semaphore locked, but we
+	 * clear ->lock_depth so that schedule() doesnt
+	 * auto-release the semaphore:
+	 */
+#ifdef CONFIG_PREEMPT_BKL
+	saved_lock_depth = task->lock_depth;
+	task->lock_depth = -1;
+#endif
 	schedule();
-	ti->preempt_count = 0;
+#ifdef CONFIG_PREEMPT_BKL
+	task->lock_depth = saved_lock_depth;
+#endif
+	sub_preempt_count(PREEMPT_ACTIVE);
 
 	/* we could miss a preemption opportunity between schedule and now */
 	barrier();
@@ -2731,6 +2873,48 @@
 }
 
 EXPORT_SYMBOL(preempt_schedule);
+
+/*
+ * this is is the entry point to schedule() from kernel preemption
+ * off of irq context.
+ * Note, that this is called and return with irqs disabled. This will
+ * protect us against recursive calling from irq.
+ */
+asmlinkage void __sched preempt_schedule_irq(void)
+{
+	struct thread_info *ti = current_thread_info();
+#ifdef CONFIG_PREEMPT_BKL
+	struct task_struct *task = current;
+	int saved_lock_depth;
+#endif
+	/* Catch callers which need to be fixed*/
+	BUG_ON(ti->preempt_count || !irqs_disabled());
+
+need_resched:
+	add_preempt_count(PREEMPT_ACTIVE);
+	/*
+	 * We keep the big kernel semaphore locked, but we
+	 * clear ->lock_depth so that schedule() doesnt
+	 * auto-release the semaphore:
+	 */
+#ifdef CONFIG_PREEMPT_BKL
+	saved_lock_depth = task->lock_depth;
+	task->lock_depth = -1;
+#endif
+	local_irq_enable();
+	schedule();
+	local_irq_disable();
+#ifdef CONFIG_PREEMPT_BKL
+	task->lock_depth = saved_lock_depth;
+#endif
+	sub_preempt_count(PREEMPT_ACTIVE);
+
+	/* we could miss a preemption opportunity between schedule and now */
+	barrier();
+	if (unlikely(test_thread_flag(TIF_NEED_RESCHED)))
+		goto need_resched;
+}
+
 #endif /* CONFIG_PREEMPT */
 
 int default_wake_function(wait_queue_t *curr, unsigned mode, int sync, void *key)
@@ -2869,6 +3053,106 @@
 }
 EXPORT_SYMBOL(wait_for_completion);
 
+unsigned long fastcall __sched
+wait_for_completion_timeout(struct completion *x, unsigned long timeout)
+{
+	might_sleep();
+
+	spin_lock_irq(&x->wait.lock);
+	if (!x->done) {
+		DECLARE_WAITQUEUE(wait, current);
+
+		wait.flags |= WQ_FLAG_EXCLUSIVE;
+		__add_wait_queue_tail(&x->wait, &wait);
+		do {
+			__set_current_state(TASK_UNINTERRUPTIBLE);
+			spin_unlock_irq(&x->wait.lock);
+			timeout = schedule_timeout(timeout);
+			spin_lock_irq(&x->wait.lock);
+			if (!timeout) {
+				__remove_wait_queue(&x->wait, &wait);
+				goto out;
+			}
+		} while (!x->done);
+		__remove_wait_queue(&x->wait, &wait);
+	}
+	x->done--;
+out:
+	spin_unlock_irq(&x->wait.lock);
+	return timeout;
+}
+EXPORT_SYMBOL(wait_for_completion_timeout);
+
+int fastcall __sched wait_for_completion_interruptible(struct completion *x)
+{
+	int ret = 0;
+
+	might_sleep();
+
+	spin_lock_irq(&x->wait.lock);
+	if (!x->done) {
+		DECLARE_WAITQUEUE(wait, current);
+
+		wait.flags |= WQ_FLAG_EXCLUSIVE;
+		__add_wait_queue_tail(&x->wait, &wait);
+		do {
+			if (signal_pending(current)) {
+				ret = -ERESTARTSYS;
+				__remove_wait_queue(&x->wait, &wait);
+				goto out;
+			}
+			__set_current_state(TASK_INTERRUPTIBLE);
+			spin_unlock_irq(&x->wait.lock);
+			schedule();
+			spin_lock_irq(&x->wait.lock);
+		} while (!x->done);
+		__remove_wait_queue(&x->wait, &wait);
+	}
+	x->done--;
+out:
+	spin_unlock_irq(&x->wait.lock);
+
+	return ret;
+}
+EXPORT_SYMBOL(wait_for_completion_interruptible);
+
+unsigned long fastcall __sched
+wait_for_completion_interruptible_timeout(struct completion *x,
+					  unsigned long timeout)
+{
+	might_sleep();
+
+	spin_lock_irq(&x->wait.lock);
+	if (!x->done) {
+		DECLARE_WAITQUEUE(wait, current);
+
+		wait.flags |= WQ_FLAG_EXCLUSIVE;
+		__add_wait_queue_tail(&x->wait, &wait);
+		do {
+			if (signal_pending(current)) {
+				timeout = -ERESTARTSYS;
+				__remove_wait_queue(&x->wait, &wait);
+				goto out;
+			}
+			__set_current_state(TASK_INTERRUPTIBLE);
+			spin_unlock_irq(&x->wait.lock);
+			timeout = schedule_timeout(timeout);
+			spin_lock_irq(&x->wait.lock);
+			if (!timeout) {
+				__remove_wait_queue(&x->wait, &wait);
+				goto out;
+			}
+		} while (!x->done);
+		__remove_wait_queue(&x->wait, &wait);
+	}
+	x->done--;
+out:
+	spin_unlock_irq(&x->wait.lock);
+	return timeout;
+}
+EXPORT_SYMBOL(wait_for_completion_interruptible_timeout);
+
+
 #define	SLEEP_ON_VAR					\
 	unsigned long flags;				\
 	wait_queue_t wait;				\
@@ -2955,7 +3239,7 @@
 	 */
 	rq = task_rq_lock(p, &flags);
 	/*
-	 * The RT priorities are set via setscheduler(), but we still
+	 * The RT priorities are set via sched_setscheduler(), but we still
 	 * allow the 'normal' nice value to be set - but as expected
 	 * it wont have any effect on scheduling until the task is
 	 * not SCHED_NORMAL:
@@ -3055,6 +3339,15 @@
 	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?
  * @cpu: the processor in question.
@@ -3067,6 +3360,15 @@
 EXPORT_SYMBOL_GPL(idle_cpu);
 
 /**
+ * idle_task - return the idle task for a given cpu.
+ * @cpu: the processor in question.
+ */
+task_t *idle_task(int cpu)
+{
+	return cpu_rq(cpu)->idle;
+}
+
+/**
  * find_process_by_pid - find a process with a matching PID value.
  * @pid: the pid in question.
  */
@@ -3087,67 +3389,48 @@
 		p->prio = p->static_prio;
 }
 
-/*
- * setscheduler - change the scheduling policy and/or RT priority of a thread.
+/**
+ * sched_setscheduler - change the scheduling policy and/or RT priority of
+ * a thread.
+ * @p: the task in question.
+ * @policy: new policy.
+ * @param: structure containing the new RT priority.
  */
-static int setscheduler(pid_t pid, int policy, struct sched_param __user *param)
+int sched_setscheduler(struct task_struct *p, int policy, struct sched_param *param)
 {
-	struct sched_param lp;
-	int retval = -EINVAL;
+	int retval;
 	int oldprio, oldpolicy = -1;
 	prio_array_t *array;
 	unsigned long flags;
 	runqueue_t *rq;
-	task_t *p;
-
-	if (!param || pid < 0)
-		goto out_nounlock;
 
-	retval = -EFAULT;
-	if (copy_from_user(&lp, param, sizeof(struct sched_param)))
-		goto out_nounlock;
-
-	/*
-	 * We play safe to avoid deadlocks.
-	 */
-	read_lock_irq(&tasklist_lock);
-
-	p = find_process_by_pid(pid);
-
-	retval = -ESRCH;
-	if (!p)
-		goto out_unlock;
 recheck:
 	/* double check policy once rq lock held */
 	if (policy < 0)
 		policy = oldpolicy = p->policy;
-	else {
-		retval = -EINVAL;
-		if (policy != SCHED_FIFO && policy != SCHED_RR &&
+	else if (policy != SCHED_FIFO && policy != SCHED_RR &&
 				policy != SCHED_NORMAL)
-			goto out_unlock;
-	}
+			return -EINVAL;
 	/*
 	 * Valid priorities for SCHED_FIFO and SCHED_RR are
 	 * 1..MAX_USER_RT_PRIO-1, valid priority for SCHED_NORMAL is 0.
 	 */
-	retval = -EINVAL;
-	if (lp.sched_priority < 0 || lp.sched_priority > MAX_USER_RT_PRIO-1)
-		goto out_unlock;
-	if ((policy == SCHED_NORMAL) != (lp.sched_priority == 0))
-		goto out_unlock;
+	if (param->sched_priority < 0 ||
+	    param->sched_priority > MAX_USER_RT_PRIO-1)
+		return -EINVAL;
+	if ((policy == SCHED_NORMAL) != (param->sched_priority == 0))
+		return -EINVAL;
 
-	retval = -EPERM;
 	if ((policy == SCHED_FIFO || policy == SCHED_RR) &&
 	    !capable(CAP_SYS_NICE))
-		goto out_unlock;
+		return -EPERM;
 	if ((current->euid != p->euid) && (current->euid != p->uid) &&
 	    !capable(CAP_SYS_NICE))
-		goto out_unlock;
+		return -EPERM;
 
-	retval = security_task_setscheduler(p, policy, &lp);
+	retval = security_task_setscheduler(p, policy, param);
 	if (retval)
-		goto out_unlock;
+		return retval;
 	/*
 	 * To be able to change p->policy safely, the apropriate
 	 * runqueue lock must be held.
@@ -3161,12 +3444,11 @@
 	}
 	array = p->array;
 	if (array)
-		deactivate_task(p, task_rq(p));
-	retval = 0;
+		deactivate_task(p, rq);
 	oldprio = p->prio;
-	__setscheduler(p, policy, lp.sched_priority);
+	__setscheduler(p, policy, param->sched_priority);
 	if (array) {
-		__activate_task(p, task_rq(p));
+		__activate_task(p, rq);
 		/*
 		 * Reschedule if we are currently running on this runqueue and
 		 * our priority decreased, or if we are not currently running on
@@ -3179,22 +3461,41 @@
 			resched_task(rq->curr);
 	}
 	task_rq_unlock(rq, &flags);
-out_unlock:
+	return 0;
+}
+EXPORT_SYMBOL_GPL(sched_setscheduler);
+
+static int do_sched_setscheduler(pid_t pid, int policy, struct sched_param __user *param)
+{
+	int retval;
+	struct sched_param lparam;
+	struct task_struct *p;
+
+	if (!param || pid < 0)
+		return -EINVAL;
+	if (copy_from_user(&lparam, param, sizeof(struct sched_param)))
+		return -EFAULT;
+	read_lock_irq(&tasklist_lock);
+	p = find_process_by_pid(pid);
+	if (!p) {
+		read_unlock_irq(&tasklist_lock);
+		return -ESRCH;
+	}
+	retval = sched_setscheduler(p, policy, &lparam);
 	read_unlock_irq(&tasklist_lock);
-out_nounlock:
 	return retval;
 }
 
 /**
  * sys_sched_setscheduler - set/change the scheduler policy and RT priority
  * @pid: the pid in question.
- * @policy: new policy
+ * @policy: new policy.
  * @param: structure containing the new RT priority.
  */
 asmlinkage long sys_sched_setscheduler(pid_t pid, int policy,
 				       struct sched_param __user *param)
 {
-	return setscheduler(pid, policy, param);
+	return do_sched_setscheduler(pid, policy, param);
 }
 
 /**
@@ -3204,7 +3505,7 @@
  */
 asmlinkage long sys_sched_setparam(pid_t pid, struct sched_param __user *param)
 {
-	return setscheduler(pid, -1, param);
+	return do_sched_setscheduler(pid, -1, param);
 }
 
 /**
@@ -3435,8 +3736,14 @@
 	} else if (!rq->expired->nr_active)
 		schedstat_inc(rq, yld_exp_empty);
 
-	dequeue_task(current, array);
-	enqueue_task(current, target);
+	if (array != target) {
+		dequeue_task(current, array);
+		enqueue_task(current, target);
+	} else
+		/*
+		 * requeue_task is cheaper so perform that if possible.
+		 */
+		requeue_task(current, array);
 
 	/*
 	 * Since we are going to call schedule() anyway, there's
@@ -3451,13 +3758,71 @@
 	return 0;
 }
 
-void __sched __cond_resched(void)
+static inline void __cond_resched(void)
 {
-	set_current_state(TASK_RUNNING);
-	schedule();
+	do {
+		add_preempt_count(PREEMPT_ACTIVE);
+		schedule();
+		sub_preempt_count(PREEMPT_ACTIVE);
+	} while (need_resched());
+}
+
+int __sched cond_resched(void)
+{
+	if (need_resched()) {
+		__cond_resched();
+		return 1;
+	}
+	return 0;
 }
 
-EXPORT_SYMBOL(__cond_resched);
+EXPORT_SYMBOL(cond_resched);
+
+/*
+ * cond_resched_lock() - if a reschedule is pending, drop the given lock,
+ * call schedule, and on return reacquire the lock.
+ *
+ * This works OK both with and without CONFIG_PREEMPT.  We do strange low-level
+ * operations here to prevent schedule() from being called twice (once via
+ * spin_unlock(), once by hand).
+ */
+int cond_resched_lock(spinlock_t * lock)
+{
+#if defined(CONFIG_SMP) && defined(CONFIG_PREEMPT)
+	if (lock->break_lock) {
+		lock->break_lock = 0;
+		spin_unlock(lock);
+		cpu_relax();
+		spin_lock(lock);
+	}
+#endif
+	if (need_resched()) {
+		_raw_spin_unlock(lock);
+		preempt_enable_no_resched();
+		__cond_resched();
+		spin_lock(lock);
+		return 1;
+	}
+	return 0;
+}
+
+EXPORT_SYMBOL(cond_resched_lock);
+
+int __sched cond_resched_softirq(void)
+{
+	BUG_ON(!in_softirq());
+
+	if (need_resched()) {
+		__local_bh_enable();
+		__cond_resched();
+		local_bh_disable();
+		return 1;
+	}
+	return 0;
+}
+
+EXPORT_SYMBOL(cond_resched_softirq);
+
 
 /**
  * yield - yield the current processor to other threads.
@@ -3482,7 +3847,7 @@
  */
 void __sched io_schedule(void)
 {
-	struct runqueue *rq = this_rq();
+	struct runqueue *rq = &per_cpu(runqueues, _smp_processor_id());
 
 	atomic_inc(&rq->nr_iowait);
 	schedule();
@@ -3493,7 +3858,7 @@
 
 long __sched io_schedule_timeout(long timeout)
 {
-	struct runqueue *rq = this_rq();
+	struct runqueue *rq = &per_cpu(runqueues, _smp_processor_id());
 	long ret;
 
 	atomic_inc(&rq->nr_iowait);
@@ -3690,7 +4055,6 @@
 	unsigned long flags;
 
 	idle->sleep_avg = 0;
-	idle->interactive_credit = 0;
 	idle->array = NULL;
 	idle->prio = MAX_PRIO;
 	idle->state = TASK_RUNNING;
@@ -3702,7 +4066,7 @@
 	spin_unlock_irqrestore(&rq->lock, flags);
 
 	/* Set the preempt count _outside_ the spinlocks! */
-#ifdef CONFIG_PREEMPT
+#if defined(CONFIG_PREEMPT) && !defined(CONFIG_PREEMPT_BKL)
 	idle->thread_info->preempt_count = (idle->lock_depth >= 0);
 #else
 	idle->thread_info->preempt_count = 0;
@@ -3870,8 +4234,7 @@
 
 		if (req->type == REQ_MOVE_TASK) {
 			spin_unlock(&rq->lock);
-			__migrate_task(req->task, smp_processor_id(),
-					req->dest_cpu);
+			__migrate_task(req->task, cpu, req->dest_cpu);
 			local_irq_enable();
 		} else if (req->type == REQ_SET_DOMAIN) {
 			rq->sd = req->sd;
@@ -3995,6 +4358,20 @@
 	spin_unlock_irqrestore(&rq->lock, flags);
 }
 
+/* Ensures that the idle task is using init_mm right before its cpu goes
+ * offline.
+ */
+void idle_task_exit(void)
+{
+	struct mm_struct *mm = current->active_mm;
+
+	BUG_ON(cpu_online(smp_processor_id()));
+
+	if (mm != &init_mm)
+		switch_mm(mm, &init_mm, current);
+	mmdrop(mm);
+}
+
 static void migrate_dead(unsigned int dead_cpu, task_t *tsk)
 {
 	struct runqueue *rq = cpu_rq(dead_cpu);
@@ -4127,6 +4504,94 @@
 #endif
 
 #ifdef CONFIG_SMP
+#define SCHED_DOMAIN_DEBUG
+#ifdef SCHED_DOMAIN_DEBUG
+static void sched_domain_debug(struct sched_domain *sd, int cpu)
+{
+	int level = 0;
+
+	printk(KERN_DEBUG "CPU%d attaching sched-domain:\n", cpu);
+
+	do {
+		int i;
+		char str[NR_CPUS];
+		struct sched_group *group = sd->groups;
+		cpumask_t groupmask;
+
+		cpumask_scnprintf(str, NR_CPUS, sd->span);
+		cpus_clear(groupmask);
+
+		printk(KERN_DEBUG);
+		for (i = 0; i < level + 1; i++)
+			printk(" ");
+		printk("domain %d: ", level);
+
+		if (!(sd->flags & SD_LOAD_BALANCE)) {
+			printk("does not load-balance\n");
+			if (sd->parent)
+				printk(KERN_ERR "ERROR: !SD_LOAD_BALANCE domain has parent");
+			break;
+		}
+
+		printk("span %s\n", str);
+
+		if (!cpu_isset(cpu, sd->span))
+			printk(KERN_ERR "ERROR: domain->span does not contain CPU%d\n", cpu);
+		if (!cpu_isset(cpu, group->cpumask))
+			printk(KERN_ERR "ERROR: domain->groups does not contain CPU%d\n", cpu);
+
+		printk(KERN_DEBUG);
+		for (i = 0; i < level + 2; i++)
+			printk(" ");
+		printk("groups:");
+		do {
+			if (!group) {
+				printk("\n");
+				printk(KERN_ERR "ERROR: group is NULL\n");
+				break;
+			}
+
+			if (!group->cpu_power) {
+				printk("\n");
+				printk(KERN_ERR "ERROR: domain->cpu_power not set\n");
+			}
+
+			if (!cpus_weight(group->cpumask)) {
+				printk("\n");
+				printk(KERN_ERR "ERROR: empty group\n");
+			}
+
+			if (cpus_intersects(groupmask, group->cpumask)) {
+				printk("\n");
+				printk(KERN_ERR "ERROR: repeated CPUs\n");
+			}
+
+			cpus_or(groupmask, groupmask, group->cpumask);
+
+			cpumask_scnprintf(str, NR_CPUS, group->cpumask);
+			printk(" %s", str);
+
+			group = group->next;
+		} while (group != sd->groups);
+		printk("\n");
+
+		if (!cpus_equal(sd->span, groupmask))
+			printk(KERN_ERR "ERROR: groups don't span domain->span\n");
+
+		level++;
+		sd = sd->parent;
+
+		if (sd) {
+			if (!cpus_subset(groupmask, sd->span))
+				printk(KERN_ERR "ERROR: parent span is not a superset of domain->span\n");
+		}
+
+	} while (sd);
+}
+#else
+#define sched_domain_debug(sd, cpu) {}
+#endif
+
 /*
  * Attach the domain 'sd' to 'cpu' as its base domain.  Callers must
  * hold the hotplug lock.
@@ -4138,6 +4603,8 @@
 	runqueue_t *rq = cpu_rq(cpu);
 	int local = 1;
 
+	sched_domain_debug(sd, cpu);
+
 	spin_lock_irqsave(&rq->lock, flags);
 
 	if (cpu == smp_processor_id() || !cpu_online(cpu)) {
@@ -4169,7 +4636,8 @@
 	str = get_options(str, ARRAY_SIZE(ints), ints);
 	cpus_clear(cpu_isolated_map);
 	for (i = 1; i <= ints[0]; i++)
-		cpu_set(ints[i], cpu_isolated_map);
+		if (ints[i] < NR_CPUS)
+			cpu_set(ints[i], cpu_isolated_map);
 	return 1;
 }
 
@@ -4412,96 +4880,6 @@
 
 #endif /* ARCH_HAS_SCHED_DOMAIN */
 
-#define SCHED_DOMAIN_DEBUG
-#ifdef SCHED_DOMAIN_DEBUG
-static void sched_domain_debug(void)
-{
-	int i;
-
-	for_each_online_cpu(i) {
-		runqueue_t *rq = cpu_rq(i);
-		struct sched_domain *sd;
-		int level = 0;
-
-		sd = rq->sd;
-
-		printk(KERN_DEBUG "CPU%d:\n", i);
-
-		do {
-			int j;
-			char str[NR_CPUS];
-			struct sched_group *group = sd->groups;
-			cpumask_t groupmask;
-
-			cpumask_scnprintf(str, NR_CPUS, sd->span);
-			cpus_clear(groupmask);
-
-			printk(KERN_DEBUG);
-			for (j = 0; j < level + 1; j++)
-				printk(" ");
-			printk("domain %d: ", level);
-
-			if (!(sd->flags & SD_LOAD_BALANCE)) {
-				printk("does not load-balance");
-				if (sd->parent)
-					printk(" ERROR !SD_LOAD_BALANCE domain has parent");
-				printk("\n");
-				break;
-			}
-
-			printk("span %s\n", str);
-
-			if (!cpu_isset(i, sd->span))
-				printk(KERN_DEBUG "ERROR domain->span does not contain CPU%d\n", i);
-			if (!cpu_isset(i, group->cpumask))
-				printk(KERN_DEBUG "ERROR domain->groups does not contain CPU%d\n", i);
-
-			printk(KERN_DEBUG);
-			for (j = 0; j < level + 2; j++)
-				printk(" ");
-			printk("groups:");
-			do {
-				if (!group) {
-					printk(" ERROR: NULL");
-					break;
-				}
-				
-				if (!group->cpu_power)
-					printk(KERN_DEBUG "ERROR group->cpu_power not set\n");
-
-				if (!cpus_weight(group->cpumask))
-					printk(" ERROR empty group:");
-
-				if (cpus_intersects(groupmask, group->cpumask))
-					printk(" ERROR repeated CPUs:");
-
-				cpus_or(groupmask, groupmask, group->cpumask);
-
-				cpumask_scnprintf(str, NR_CPUS, group->cpumask);
-				printk(" %s", str);
-
-				group = group->next;
-			} while (group != sd->groups);
-			printk("\n");
-
-			if (!cpus_equal(sd->span, groupmask))
-				printk(KERN_DEBUG "ERROR groups don't span domain->span\n");
-
-			level++;
-			sd = sd->parent;
-
-			if (sd) {
-				if (!cpus_subset(groupmask, sd->span))
-					printk(KERN_DEBUG "ERROR parent span is not a superset of domain->span\n");
-			}
-
-		} while (sd);
-	}
-}
-#else
-#define sched_domain_debug() {}
-#endif
-
 /*
  * 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
@@ -4544,8 +4922,6 @@
 	/* The hotplug lock is already held by cpu_up/cpu_down */
 	arch_init_sched_domains();
 
-	sched_domain_debug();
-
 	return NOTIFY_OK;
 }
 #endif
@@ -4554,7 +4930,6 @@
 {
 	lock_cpu_hotplug();
 	arch_init_sched_domains();
-	sched_domain_debug();
 	unlock_cpu_hotplug();
 	/* XXX: Theoretical race here - CPU may be hotplugged now */
 	hotcpu_notifier(update_sched_domains, 0);
@@ -4631,7 +5006,7 @@
 	static unsigned long prev_jiffy;	/* ratelimiting */
 
 	if ((in_atomic() || irqs_disabled()) &&
-	    system_state == SYSTEM_RUNNING) {
+	    system_state == SYSTEM_RUNNING && !oops_in_progress) {
 		if (time_before(jiffies, prev_jiffy + HZ) && prev_jiffy)
 			return;
 		prev_jiffy = jiffies;
diff -Nru a/kernel/signal.c b/kernel/signal.c
--- a/kernel/signal.c	2005-03-01 23:38:56 -08:00
+++ b/kernel/signal.c	2005-03-01 23:38:56 -08:00
@@ -153,11 +153,6 @@
 	(!T(signr, SIG_KERNEL_IGNORE_MASK|SIG_KERNEL_STOP_MASK) && \
 	 (t)->sighand->action[(signr)-1].sa.sa_handler == SIG_DFL)
 
-#define sig_avoid_stop_race() \
-	(sigtestsetmask(&current->pending.signal, M(SIGCONT) | M(SIGKILL)) || \
-	 sigtestsetmask(&current->signal->shared_pending.signal, \
-						  M(SIGCONT) | M(SIGKILL)))
-
 static int sig_ignored(struct task_struct *t, int sig)
 {
 	void __user * handler;
@@ -380,8 +375,8 @@
 		 * We won't ever get here for the group leader, since it
 		 * will have been the last reference on the signal_struct.
 		 */
-		sig->utime += tsk->utime;
-		sig->stime += tsk->stime;
+		sig->utime = cputime_add(sig->utime, tsk->utime);
+		sig->stime = cputime_add(sig->stime, tsk->stime);
 		sig->min_flt += tsk->min_flt;
 		sig->maj_flt += tsk->maj_flt;
 		sig->nvcsw += tsk->nvcsw;
@@ -551,6 +546,21 @@
 	if (!signr)
 		signr = __dequeue_signal(&tsk->signal->shared_pending,
 					 mask, info);
+ 	if (signr && unlikely(sig_kernel_stop(signr))) {
+ 		/*
+ 		 * Set a marker that we have dequeued a stop signal.  Our
+ 		 * caller might release the siglock and then the pending
+ 		 * stop signal it is about to process is no longer in the
+ 		 * pending bitmasks, but must still be cleared by a SIGCONT
+ 		 * (and overruled by a SIGKILL).  So those cases clear this
+ 		 * shared flag after we've set it.  Note that this flag may
+ 		 * remain set after the signal we return is ignored or
+ 		 * handled.  That doesn't matter because its only purpose
+ 		 * is to alert stop-signal processing code when another
+ 		 * processor has come along and cleared the flag.
+ 		 */
+ 		tsk->signal->flags |= SIGNAL_STOP_DEQUEUED;
+ 	}
 	if ( signr &&
 	     ((info->si_code & __SI_MASK) == __SI_TIMER) &&
 	     info->si_sys_private){
@@ -577,15 +587,15 @@
 	set_tsk_thread_flag(t, TIF_SIGPENDING);
 
 	/*
-	 * If resume is set, we want to wake it up in the TASK_STOPPED case.
-	 * We don't check for TASK_STOPPED because there is a race with it
+	 * For SIGKILL, we want to wake it up in the stopped/traced case.
+	 * We don't check t->state here because there is a race with it
 	 * executing another processor and just now entering stopped state.
-	 * By calling wake_up_process any time resume is set, we ensure
-	 * the process will wake up and handle its stop or death signal.
+	 * By using wake_up_state, we ensure the process will wake up and
+	 * handle its death signal.
 	 */
 	mask = TASK_INTERRUPTIBLE;
 	if (resume)
-		mask |= TASK_STOPPED;
+		mask |= TASK_STOPPED | TASK_TRACED;
 	if (!wake_up_state(t, mask))
 		kick_process(t);
 }
@@ -651,6 +661,12 @@
 {
 	struct task_struct *t;
 
+	if (p->flags & SIGNAL_GROUP_EXIT)
+		/*
+		 * The process is in the middle of dying already.
+		 */
+		return;
+
 	if (sig_kernel_stop(sig)) {
 		/*
 		 * This is a stop signal.  Remove SIGCONT from all queues.
@@ -680,7 +696,7 @@
 			 * the SIGCHLD was pending on entry to this kill.
 			 */
 			p->signal->group_stop_count = 0;
-			p->signal->stop_state = 1;
+			p->signal->flags = SIGNAL_STOP_CONTINUED;
 			spin_unlock(&p->sighand->siglock);
 			if (p->ptrace & PT_PTRACED)
 				do_notify_parent_cldstop(p, p->parent,
@@ -722,12 +738,12 @@
 			t = next_thread(t);
 		} while (t != p);
 
-		if (p->signal->stop_state > 0) {
+		if (p->signal->flags & SIGNAL_STOP_STOPPED) {
 			/*
 			 * We were in fact stopped, and are now continued.
 			 * Notify the parent with CLD_CONTINUED.
 			 */
-			p->signal->stop_state = -1;
+			p->signal->flags = SIGNAL_STOP_CONTINUED;
 			p->signal->group_exit_code = 0;
 			spin_unlock(&p->sighand->siglock);
 			if (p->ptrace & PT_PTRACED)
@@ -739,7 +755,20 @@
 					p->group_leader->real_parent,
 							 CLD_CONTINUED);
 			spin_lock(&p->sighand->siglock);
+		} else {
+			/*
+			 * We are not stopped, but there could be a stop
+			 * signal in the middle of being processed after
+			 * being removed from the queue.  Clear that too.
+			 */
+			p->signal->flags = 0;
 		}
+	} else if (sig == SIGKILL) {
+		/*
+		 * Make sure that any pending stop signal already dequeued
+		 * is undone by the wakeup for SIGKILL.
+		 */
+		p->signal->flags = 0;
 	}
 }
 
@@ -818,10 +847,7 @@
 
 	if (!irqs_disabled())
 		BUG();
-#ifdef CONFIG_SMP
-	if (!spin_is_locked(&t->sighand->siglock))
-		BUG();
-#endif
+	assert_spin_locked(&t->sighand->siglock);
 
 	if (((unsigned long)info > 2) && (info->si_code == SI_TIMER))
 		/*
@@ -905,12 +931,12 @@
 	struct task_struct *t;
 
 	/*
-	 * Don't bother zombies and stopped tasks (but
-	 * SIGKILL will punch through stopped state)
+	 * Don't bother traced and stopped tasks (but
+	 * SIGKILL will punch through that).
 	 */
-	mask = EXIT_DEAD | EXIT_ZOMBIE | TASK_TRACED;
-	if (sig != SIGKILL)
-		mask |= TASK_STOPPED;
+	mask = TASK_STOPPED | TASK_TRACED;
+	if (sig == SIGKILL)
+		mask = 0;
 
 	/*
 	 * Now find a thread we can wake up to take the signal off the queue.
@@ -953,7 +979,7 @@
 	 * Found a killable thread.  If the signal will be fatal,
 	 * then start taking the whole group down immediately.
 	 */
-	if (sig_fatal(p, sig) && !p->signal->group_exit &&
+	if (sig_fatal(p, sig) && !(p->signal->flags & SIGNAL_GROUP_EXIT) &&
 	    !sigismember(&t->real_blocked, sig) &&
 	    (sig == SIGKILL || !(t->ptrace & PT_PTRACED))) {
 		/*
@@ -966,7 +992,7 @@
 			 * running and doing things after a slower
 			 * thread has the fatal signal pending.
 			 */
-			p->signal->group_exit = 1;
+			p->signal->flags = SIGNAL_GROUP_EXIT;
 			p->signal->group_exit_code = sig;
 			p->signal->group_stop_count = 0;
 			t = p;
@@ -1015,10 +1041,7 @@
 {
 	int ret = 0;
 
-#ifdef CONFIG_SMP
-	if (!spin_is_locked(&p->sighand->siglock))
-		BUG();
-#endif
+	assert_spin_locked(&p->sighand->siglock);
 	handle_stop_signal(sig, p);
 
 	if (((unsigned long)info > 2) && (info->si_code == SI_TIMER))
@@ -1055,6 +1078,7 @@
 {
 	struct task_struct *t;
 
+	p->signal->flags = SIGNAL_GROUP_EXIT;
 	p->signal->group_stop_count = 0;
 
 	if (thread_group_empty(p))
@@ -1064,7 +1088,7 @@
 		/*
 		 * Don't bother with already dead threads
 		 */
-		if (t->exit_state & (EXIT_ZOMBIE|EXIT_DEAD))
+		if (t->exit_state)
 			continue;
 
 		/*
@@ -1407,28 +1431,12 @@
 }
 
 /*
- * Joy. Or not. Pthread wants us to wake up every thread
- * in our parent group.
+ * Wake up any threads in the parent blocked in wait* syscalls.
  */
-static void __wake_up_parent(struct task_struct *p,
+static inline void __wake_up_parent(struct task_struct *p,
 				    struct task_struct *parent)
 {
-	struct task_struct *tsk = parent;
-
-	/*
-	 * Fortunately this is not necessary for thread groups:
-	 */
-	if (p->tgid == tsk->tgid) {
-		wake_up_interruptible_sync(&tsk->wait_chldexit);
-		return;
-	}
-
-	do {
-		wake_up_interruptible_sync(&tsk->wait_chldexit);
-		tsk = next_thread(tsk);
-		if (tsk->signal != parent->signal)
-			BUG();
-	} while (tsk != parent);
+	wake_up_interruptible_sync(&parent->signal->wait_chldexit);
 }
 
 /*
@@ -1442,8 +1450,7 @@
 	unsigned long flags;
 	struct sighand_struct *psig;
 
-	if (sig == -1)
-		BUG();
+	BUG_ON(sig == -1);
 
  	/* do_notify_parent_cldstop should have been called instead.  */
  	BUG_ON(tsk->state & (TASK_STOPPED|TASK_TRACED));
@@ -1457,8 +1464,10 @@
 	info.si_uid = tsk->uid;
 
 	/* FIXME: find out whether or not this is supposed to be c*time. */
-	info.si_utime = tsk->utime + tsk->signal->utime;
-	info.si_stime = tsk->stime + tsk->signal->stime;
+	info.si_utime = cputime_to_jiffies(cputime_add(tsk->utime,
+						       tsk->signal->utime));
+	info.si_stime = cputime_to_jiffies(cputime_add(tsk->stime,
+						       tsk->signal->stime));
 
 	info.si_status = tsk->exit_code & 0x7f;
 	if (tsk->exit_code & 0x80)
@@ -1514,8 +1523,8 @@
 	info.si_uid = tsk->uid;
 
 	/* FIXME: find out whether or not this is supposed to be c*time. */
-	info.si_utime = tsk->utime;
-	info.si_stime = tsk->stime;
+	info.si_utime = cputime_to_jiffies(tsk->utime);
+	info.si_stime = cputime_to_jiffies(tsk->stime);
 
  	info.si_code = why;
  	switch (why) {
@@ -1551,11 +1560,12 @@
  * We always set current->last_siginfo while stopped here.
  * That makes it a way to test a stopped process for
  * being ptrace-stopped vs being job-control-stopped.
+ *
+ * If we actually decide not to stop at all because the tracer is gone,
+ * we leave nostop_code in current->exit_code.
  */
-static void ptrace_stop(int exit_code, siginfo_t *info)
+static void ptrace_stop(int exit_code, int nostop_code, siginfo_t *info)
 {
-	BUG_ON(!(current->ptrace & PT_PTRACED));
-
 	/*
 	 * If there is a group stop in progress,
 	 * we must participate in the bookkeeping.
@@ -1570,9 +1580,24 @@
 	set_current_state(TASK_TRACED);
 	spin_unlock_irq(&current->sighand->siglock);
 	read_lock(&tasklist_lock);
-	do_notify_parent_cldstop(current, current->parent, CLD_TRAPPED);
-	read_unlock(&tasklist_lock);
-	schedule();
+	if (likely(current->ptrace & PT_PTRACED) &&
+	    likely(current->parent != current->real_parent ||
+		   !(current->ptrace & PT_ATTACHED)) &&
+	    (likely(current->parent->signal != current->signal) ||
+	     !unlikely(current->signal->flags & SIGNAL_GROUP_EXIT))) {
+		do_notify_parent_cldstop(current, current->parent,
+					 CLD_TRAPPED);
+		read_unlock(&tasklist_lock);
+		schedule();
+	} else {
+		/*
+		 * By the time we got the lock, our tracer went away.
+		 * Don't stop here.
+		 */
+		read_unlock(&tasklist_lock);
+		set_current_state(TASK_RUNNING);
+		current->exit_code = nostop_code;
+	}
 
 	/*
 	 * We are back.  Now reacquire the siglock before touching
@@ -1603,7 +1628,7 @@
 
 	/* Let the debugger run.  */
 	spin_lock_irq(&current->sighand->siglock);
-	ptrace_stop(exit_code, &info);
+	ptrace_stop(exit_code, 0, &info);
 	spin_unlock_irq(&current->sighand->siglock);
 }
 
@@ -1641,15 +1666,18 @@
 /*
  * This performs the stopping for SIGSTOP and other stop signals.
  * We have to stop all threads in the thread group.
+ * Returns nonzero if we've actually stopped and released the siglock.
+ * Returns zero if we didn't stop and still hold the siglock.
  */
-static void
+static int
 do_signal_stop(int signr)
 {
 	struct signal_struct *sig = current->signal;
 	struct sighand_struct *sighand = current->sighand;
 	int stop_count = -1;
 
-	/* spin_lock_irq(&sighand->siglock) is now done in caller */
+	if (!likely(sig->flags & SIGNAL_STOP_DEQUEUED))
+		return 0;
 
 	if (sig->group_stop_count > 0) {
 		/*
@@ -1661,7 +1689,7 @@
 		current->exit_code = signr;
 		set_current_state(TASK_STOPPED);
 		if (stop_count == 0)
-			sig->stop_state = 1;
+			sig->flags = SIGNAL_STOP_STOPPED;
 		spin_unlock_irq(&sighand->siglock);
 	}
 	else if (thread_group_empty(current)) {
@@ -1670,7 +1698,7 @@
 		 */
 		current->exit_code = current->signal->group_exit_code = signr;
 		set_current_state(TASK_STOPPED);
-		sig->stop_state = 1;
+		sig->flags = SIGNAL_STOP_STOPPED;
 		spin_unlock_irq(&sighand->siglock);
 	}
 	else {
@@ -1691,25 +1719,16 @@
 		read_lock(&tasklist_lock);
 		spin_lock_irq(&sighand->siglock);
 
-		if (unlikely(sig->group_exit)) {
+		if (!likely(sig->flags & SIGNAL_STOP_DEQUEUED)) {
 			/*
-			 * There is a group exit in progress now.
-			 * We'll just ignore the stop and process the
-			 * associated fatal signal.
+			 * Another stop or continue happened while we
+			 * didn't have the lock.  We can just swallow this
+			 * signal now.  If we raced with a SIGCONT, that
+			 * should have just cleared it now.  If we raced
+			 * with another processor delivering a stop signal,
+			 * then the SIGCONT that wakes us up should clear it.
 			 */
-			spin_unlock_irq(&sighand->siglock);
-			read_unlock(&tasklist_lock);
-			return;
-		}
-
-		if (unlikely(sig_avoid_stop_race())) {
-			/*
-			 * Either a SIGCONT or a SIGKILL signal was
-			 * posted in the siglock-not-held window.
-			 */
-			spin_unlock_irq(&sighand->siglock);
-			read_unlock(&tasklist_lock);
-			return;
+			return 0;
 		}
 
 		if (sig->group_stop_count == 0) {
@@ -1737,13 +1756,14 @@
 		current->exit_code = signr;
 		set_current_state(TASK_STOPPED);
 		if (stop_count == 0)
-			sig->stop_state = 1;
+			sig->flags = SIGNAL_STOP_STOPPED;
 
 		spin_unlock_irq(&sighand->siglock);
 		read_unlock(&tasklist_lock);
 	}
 
 	finish_stop(stop_count);
+	return 1;
 }
 
 /*
@@ -1765,7 +1785,7 @@
 		return 0;
 	}
 
-	if (current->signal->group_exit)
+	if (current->signal->flags & SIGNAL_GROUP_EXIT)
 		/*
 		 * Group stop is so another thread can do a core dump,
 		 * or else we are racing against a death signal.
@@ -1779,7 +1799,7 @@
 	 */
 	stop_count = --current->signal->group_stop_count;
 	if (stop_count == 0)
-		current->signal->stop_state = 1;
+		current->signal->flags = SIGNAL_STOP_STOPPED;
 	current->exit_code = current->signal->group_exit_code;
 	set_current_state(TASK_STOPPED);
 	spin_unlock_irq(&current->sighand->siglock);
@@ -1811,7 +1831,7 @@
 			ptrace_signal_deliver(regs, cookie);
 
 			/* Let the debugger run.  */
-			ptrace_stop(signr, info);
+			ptrace_stop(signr, signr, info);
 
 			/* We're back.  Did the debugger cancel the sig?  */
 			signr = current->exit_code;
@@ -1873,28 +1893,27 @@
 			 * This allows an intervening SIGCONT to be posted.
 			 * We need to check for that and bail out if necessary.
 			 */
-			if (signr == SIGSTOP) {
-				do_signal_stop(signr); /* releases siglock */
-				goto relock;
-			}
-			spin_unlock_irq(&current->sighand->siglock);
+			if (signr != SIGSTOP) {
+				spin_unlock_irq(&current->sighand->siglock);
 
-			/* signals can be posted during this window */
+				/* signals can be posted during this window */
 
-			if (is_orphaned_pgrp(process_group(current)))
-				goto relock;
+				if (is_orphaned_pgrp(process_group(current)))
+					goto relock;
 
-			spin_lock_irq(&current->sighand->siglock);
-			if (unlikely(sig_avoid_stop_race())) {
-				/*
-				 * Either a SIGCONT or a SIGKILL signal was
-				 * posted in the siglock-not-held window.
-				 */
-				continue;
+				spin_lock_irq(&current->sighand->siglock);
 			}
 
-			do_signal_stop(signr); /* releases siglock */
-			goto relock;
+			if (likely(do_signal_stop(signr))) {
+				/* It released the siglock.  */
+				goto relock;
+			}
+
+			/*
+			 * We didn't actually stop, due to a race
+			 * with SIGCONT or something like that.
+			 */
+			continue;
 		}
 
 		spin_unlock_irq(&current->sighand->siglock);
diff -Nru a/kernel/softirq.c b/kernel/softirq.c
--- a/kernel/softirq.c	2005-03-01 23:38:54 -08:00
+++ b/kernel/softirq.c	2005-03-01 23:38:54 -08:00
@@ -142,7 +142,7 @@
 	 * Keep preemption disabled until we are done with
 	 * softirq processing:
  	 */
-	preempt_count() -= SOFTIRQ_OFFSET - 1;
+ 	sub_preempt_count(SOFTIRQ_OFFSET - 1);
 
 	if (unlikely(!in_interrupt() && local_softirq_pending()))
 		do_softirq();
@@ -151,6 +151,24 @@
 	preempt_check_resched();
 }
 EXPORT_SYMBOL(local_bh_enable);
+
+#ifdef __ARCH_IRQ_EXIT_IRQS_DISABLED
+# define invoke_softirq()	__do_softirq()
+#else
+# define invoke_softirq()	do_softirq()
+#endif
+
+/*
+ * Exit an interrupt context. Process softirqs if needed and possible:
+ */
+void irq_exit(void)
+{
+	account_system_vtime(current);
+	sub_preempt_count(IRQ_EXIT_OFFSET);
+	if (!in_interrupt() && local_softirq_pending())
+		invoke_softirq();
+	preempt_enable_no_resched();
+}
 
 /*
  * This function must run with irqs disabled!
diff -Nru a/kernel/spinlock.c b/kernel/spinlock.c
--- a/kernel/spinlock.c	2005-03-01 23:38:52 -08:00
+++ b/kernel/spinlock.c	2005-03-01 23:38:52 -08:00
@@ -2,6 +2,8 @@
  * Copyright (2004) Linus Torvalds
  *
  * Author: Zwane Mwaikambo <zwane@fsmlabs.com>
+ *
+ * Copyright (2004) Ingo Molnar
  */
 
 #include <linux/config.h>
@@ -11,6 +13,17 @@
 #include <linux/interrupt.h>
 #include <linux/module.h>
 
+/*
+ * Generic declaration of the raw read_trylock() function,
+ * architectures are supposed to optimize this:
+ */
+int __lockfunc generic_raw_read_trylock(rwlock_t *lock)
+{
+	_raw_read_lock(lock);
+	return 1;
+}
+EXPORT_SYMBOL(generic_raw_read_trylock);
+
 int __lockfunc _spin_trylock(spinlock_t *lock)
 {
 	preempt_disable();
@@ -22,86 +35,29 @@
 }
 EXPORT_SYMBOL(_spin_trylock);
 
-int __lockfunc _write_trylock(rwlock_t *lock)
+int __lockfunc _read_trylock(rwlock_t *lock)
 {
 	preempt_disable();
-	if (_raw_write_trylock(lock))
+	if (_raw_read_trylock(lock))
 		return 1;
 
 	preempt_enable();
 	return 0;
 }
-EXPORT_SYMBOL(_write_trylock);
-
-#ifdef CONFIG_PREEMPT
-/*
- * This could be a long-held lock.  If another CPU holds it for a long time,
- * and that CPU is not asked to reschedule then *this* CPU will spin on the
- * lock for a long time, even if *this* CPU is asked to reschedule.
- *
- * So what we do here, in the slow (contended) path is to spin on the lock by
- * hand while permitting preemption.
- *
- * Called inside preempt_disable().
- */
-static inline void __preempt_spin_lock(spinlock_t *lock)
-{
-	if (preempt_count() > 1) {
-		_raw_spin_lock(lock);
-		return;
-	}
-
-	do {
-		preempt_enable();
-		while (spin_is_locked(lock))
-			cpu_relax();
-		preempt_disable();
-	} while (!_raw_spin_trylock(lock));
-}
+EXPORT_SYMBOL(_read_trylock);
 
-void __lockfunc _spin_lock(spinlock_t *lock)
+int __lockfunc _write_trylock(rwlock_t *lock)
 {
 	preempt_disable();
-	if (unlikely(!_raw_spin_trylock(lock)))
-		__preempt_spin_lock(lock);
-}
-
-static inline void __preempt_write_lock(rwlock_t *lock)
-{
-	if (preempt_count() > 1) {
-		_raw_write_lock(lock);
-		return;
-	}
-
-	do {
-		preempt_enable();
-		while (rwlock_is_locked(lock))
-			cpu_relax();
-		preempt_disable();
-	} while (!_raw_write_trylock(lock));
-}
+	if (_raw_write_trylock(lock))
+		return 1;
 
-void __lockfunc _write_lock(rwlock_t *lock)
-{
-	preempt_disable();
-	if (unlikely(!_raw_write_trylock(lock)))
-		__preempt_write_lock(lock);
-}
-#else
-void __lockfunc _spin_lock(spinlock_t *lock)
-{
-	preempt_disable();
-	_raw_spin_lock(lock);
+	preempt_enable();
+	return 0;
 }
+EXPORT_SYMBOL(_write_trylock);
 
-void __lockfunc _write_lock(rwlock_t *lock)
-{
-	preempt_disable();
-	_raw_write_lock(lock);
-}
-#endif
-EXPORT_SYMBOL(_spin_lock);
-EXPORT_SYMBOL(_write_lock);
+#ifndef CONFIG_PREEMPT
 
 void __lockfunc _read_lock(rwlock_t *lock)
 {
@@ -110,27 +66,6 @@
 }
 EXPORT_SYMBOL(_read_lock);
 
-void __lockfunc _spin_unlock(spinlock_t *lock)
-{
-	_raw_spin_unlock(lock);
-	preempt_enable();
-}
-EXPORT_SYMBOL(_spin_unlock);
-
-void __lockfunc _write_unlock(rwlock_t *lock)
-{
-	_raw_write_unlock(lock);
-	preempt_enable();
-}
-EXPORT_SYMBOL(_write_unlock);
-
-void __lockfunc _read_unlock(rwlock_t *lock)
-{
-	_raw_read_unlock(lock);
-	preempt_enable();
-}
-EXPORT_SYMBOL(_read_unlock);
-
 unsigned long __lockfunc _spin_lock_irqsave(spinlock_t *lock)
 {
 	unsigned long flags;
@@ -211,6 +146,132 @@
 	_raw_write_lock(lock);
 }
 EXPORT_SYMBOL(_write_lock_bh);
+
+void __lockfunc _spin_lock(spinlock_t *lock)
+{
+	preempt_disable();
+	_raw_spin_lock(lock);
+}
+
+EXPORT_SYMBOL(_spin_lock);
+
+void __lockfunc _write_lock(rwlock_t *lock)
+{
+	preempt_disable();
+	_raw_write_lock(lock);
+}
+
+EXPORT_SYMBOL(_write_lock);
+
+#else /* CONFIG_PREEMPT: */
+
+/*
+ * This could be a long-held lock. We both prepare to spin for a long
+ * time (making _this_ CPU preemptable if possible), and we also signal
+ * towards that other CPU that it should break the lock ASAP.
+ *
+ * (We do this in a function because inlining it would be excessive.)
+ */
+
+#define BUILD_LOCK_OPS(op, locktype)					\
+void __lockfunc _##op##_lock(locktype##_t *lock)			\
+{									\
+	preempt_disable();						\
+	for (;;) {							\
+		if (likely(_raw_##op##_trylock(lock)))			\
+			break;						\
+		preempt_enable();					\
+		if (!(lock)->break_lock)				\
+			(lock)->break_lock = 1;				\
+		while (!op##_can_lock(lock) && (lock)->break_lock)	\
+			cpu_relax();					\
+		preempt_disable();					\
+	}								\
+}									\
+									\
+EXPORT_SYMBOL(_##op##_lock);						\
+									\
+unsigned long __lockfunc _##op##_lock_irqsave(locktype##_t *lock)	\
+{									\
+	unsigned long flags;						\
+									\
+	preempt_disable();						\
+	for (;;) {							\
+		local_irq_save(flags);					\
+		if (likely(_raw_##op##_trylock(lock)))			\
+			break;						\
+		local_irq_restore(flags);				\
+									\
+		preempt_enable();					\
+		if (!(lock)->break_lock)				\
+			(lock)->break_lock = 1;				\
+		while (!op##_can_lock(lock) && (lock)->break_lock)	\
+			cpu_relax();					\
+		preempt_disable();					\
+	}								\
+	return flags;							\
+}									\
+									\
+EXPORT_SYMBOL(_##op##_lock_irqsave);					\
+									\
+void __lockfunc _##op##_lock_irq(locktype##_t *lock)			\
+{									\
+	_##op##_lock_irqsave(lock);					\
+}									\
+									\
+EXPORT_SYMBOL(_##op##_lock_irq);					\
+									\
+void __lockfunc _##op##_lock_bh(locktype##_t *lock)			\
+{									\
+	unsigned long flags;						\
+									\
+	/*							*/	\
+	/* Careful: we must exclude softirqs too, hence the	*/	\
+	/* irq-disabling. We use the generic preemption-aware	*/	\
+	/* function:						*/	\
+	/**/								\
+	flags = _##op##_lock_irqsave(lock);				\
+	local_bh_disable();						\
+	local_irq_restore(flags);					\
+}									\
+									\
+EXPORT_SYMBOL(_##op##_lock_bh)
+
+/*
+ * Build preemption-friendly versions of the following
+ * lock-spinning functions:
+ *
+ *         _[spin|read|write]_lock()
+ *         _[spin|read|write]_lock_irq()
+ *         _[spin|read|write]_lock_irqsave()
+ *         _[spin|read|write]_lock_bh()
+ */
+BUILD_LOCK_OPS(spin, spinlock);
+BUILD_LOCK_OPS(read, rwlock);
+BUILD_LOCK_OPS(write, rwlock);
+
+#endif /* CONFIG_PREEMPT */
+
+void __lockfunc _spin_unlock(spinlock_t *lock)
+{
+	_raw_spin_unlock(lock);
+	preempt_enable();
+}
+EXPORT_SYMBOL(_spin_unlock);
+
+void __lockfunc _write_unlock(rwlock_t *lock)
+{
+	_raw_write_unlock(lock);
+	preempt_enable();
+}
+EXPORT_SYMBOL(_write_unlock);
+
+void __lockfunc _read_unlock(rwlock_t *lock)
+{
+	_raw_read_unlock(lock);
+	preempt_enable();
+}
+EXPORT_SYMBOL(_read_unlock);
 
 void __lockfunc _spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags)
 {
diff -Nru a/kernel/stop_machine.c b/kernel/stop_machine.c
--- a/kernel/stop_machine.c	2005-03-01 23:38:52 -08:00
+++ b/kernel/stop_machine.c	2005-03-01 23:38:52 -08:00
@@ -95,7 +95,7 @@
 	stopmachine_state = STOPMACHINE_WAIT;
 
 	for_each_online_cpu(i) {
-		if (i == smp_processor_id())
+		if (i == _smp_processor_id())
 			continue;
 		ret = kernel_thread(stopmachine, (void *)(long)i,CLONE_KERNEL);
 		if (ret < 0)
@@ -177,7 +177,7 @@
 
 	/* If they don't care which CPU fn runs on, bind to any online one. */
 	if (cpu == NR_CPUS)
-		cpu = smp_processor_id();
+		cpu = _smp_processor_id();
 
 	p = kthread_create(do_stop, &smdata, "kstopmachine");
 	if (!IS_ERR(p)) {
diff -Nru a/kernel/sys.c b/kernel/sys.c
--- a/kernel/sys.c	2005-03-01 23:38:52 -08:00
+++ b/kernel/sys.c	2005-03-01 23:38:52 -08:00
@@ -23,6 +23,7 @@
 #include <linux/security.h>
 #include <linux/dcookies.h>
 #include <linux/suspend.h>
+#include <linux/tty.h>
 
 #include <linux/compat.h>
 #include <linux/syscalls.h>
@@ -88,7 +89,7 @@
  */
 
 static struct notifier_block *reboot_notifier_list;
-rwlock_t notifier_lock = RW_LOCK_UNLOCKED;
+DEFINE_RWLOCK(notifier_lock);
 
 /**
  *	notifier_chain_register	- Add notifier to a notifier chain
@@ -892,15 +893,15 @@
 		struct tms tmp;
 		struct task_struct *tsk = current;
 		struct task_struct *t;
-		unsigned long utime, stime, cutime, cstime;
+		cputime_t utime, stime, cutime, cstime;
 
 		read_lock(&tasklist_lock);
 		utime = tsk->signal->utime;
 		stime = tsk->signal->stime;
 		t = tsk;
 		do {
-			utime += t->utime;
-			stime += t->stime;
+			utime = cputime_add(utime, t->utime);
+			stime = cputime_add(stime, t->stime);
 			t = next_thread(t);
 		} while (t != tsk);
 
@@ -919,10 +920,10 @@
 		spin_unlock_irq(&tsk->sighand->siglock);
 		read_unlock(&tasklist_lock);
 
-		tmp.tms_utime = jiffies_to_clock_t(utime);
-		tmp.tms_stime = jiffies_to_clock_t(stime);
-		tmp.tms_cutime = jiffies_to_clock_t(cutime);
-		tmp.tms_cstime = jiffies_to_clock_t(cstime);
+		tmp.tms_utime = cputime_to_clock_t(utime);
+		tmp.tms_stime = cputime_to_clock_t(stime);
+		tmp.tms_cutime = cputime_to_clock_t(cutime);
+		tmp.tms_cstime = cputime_to_clock_t(cstime);
 		if (copy_to_user(tbuf, &tmp, sizeof(struct tms)))
 			return -EFAULT;
 	}
@@ -1075,6 +1076,7 @@
 	if (!thread_group_leader(current))
 		return -EINVAL;
 
+	down(&tty_sem);
 	write_lock_irq(&tasklist_lock);
 
 	pid = find_pid(PIDTYPE_PGID, current->pid);
@@ -1088,6 +1090,7 @@
 	err = process_group(current);
 out:
 	write_unlock_irq(&tasklist_lock);
+	up(&tty_sem);
 	return err;
 }
 
@@ -1525,7 +1528,7 @@
 {
 	struct task_struct *t;
 	unsigned long flags;
-	unsigned long utime, stime;
+	cputime_t utime, stime;
 
 	memset((char *) r, 0, sizeof *r);
 
@@ -1542,12 +1545,12 @@
 			r->ru_minflt = p->signal->cmin_flt;
 			r->ru_majflt = p->signal->cmaj_flt;
 			spin_unlock_irqrestore(&p->sighand->siglock, flags);
-			jiffies_to_timeval(utime, &r->ru_utime);
-			jiffies_to_timeval(stime, &r->ru_stime);
+			cputime_to_timeval(utime, &r->ru_utime);
+			cputime_to_timeval(stime, &r->ru_stime);
 			break;
 		case RUSAGE_SELF:
 			spin_lock_irqsave(&p->sighand->siglock, flags);
-			utime = stime = 0;
+			utime = stime = cputime_zero;
 			goto sum_group;
 		case RUSAGE_BOTH:
 			spin_lock_irqsave(&p->sighand->siglock, flags);
@@ -1558,16 +1561,16 @@
 			r->ru_minflt = p->signal->cmin_flt;
 			r->ru_majflt = p->signal->cmaj_flt;
 		sum_group:
-			utime += p->signal->utime;
-			stime += p->signal->stime;
+			utime = cputime_add(utime, p->signal->utime);
+			stime = cputime_add(stime, p->signal->stime);
 			r->ru_nvcsw += p->signal->nvcsw;
 			r->ru_nivcsw += p->signal->nivcsw;
 			r->ru_minflt += p->signal->min_flt;
 			r->ru_majflt += p->signal->maj_flt;
 			t = p;
 			do {
-				utime += t->utime;
-				stime += t->stime;
+				utime = cputime_add(utime, t->utime);
+				stime = cputime_add(stime, t->stime);
 				r->ru_nvcsw += t->nvcsw;
 				r->ru_nivcsw += t->nivcsw;
 				r->ru_minflt += t->min_flt;
@@ -1575,8 +1578,8 @@
 				t = next_thread(t);
 			} while (t != p);
 			spin_unlock_irqrestore(&p->sighand->siglock, flags);
-			jiffies_to_timeval(utime, &r->ru_utime);
-			jiffies_to_timeval(stime, &r->ru_stime);
+			cputime_to_timeval(utime, &r->ru_utime);
+			cputime_to_timeval(stime, &r->ru_stime);
 			break;
 		default:
 			BUG();
@@ -1687,6 +1690,15 @@
 						sizeof(me->comm)-1) < 0)
 				return -EFAULT;
 			set_task_comm(me, ncomm);
+			return 0;
+		}
+		case PR_GET_NAME: {
+			struct task_struct *me = current;
+			unsigned char tcomm[sizeof(me->comm)];
+
+			get_task_comm(tcomm, me);
+			if (copy_to_user((char __user *)arg2, tcomm, sizeof(tcomm)))
+				return -EFAULT;
 			return 0;
 		}
 		default:
diff -Nru a/kernel/sys_ni.c b/kernel/sys_ni.c
--- a/kernel/sys_ni.c	2005-03-01 23:39:09 -08:00
+++ b/kernel/sys_ni.c	2005-03-01 23:39:09 -08:00
@@ -81,4 +81,5 @@
 cond_syscall(sys_pciconfig_read)
 cond_syscall(sys_pciconfig_write)
 cond_syscall(sys_pciconfig_iobase)
-
+cond_syscall(sys32_ipc)
+cond_syscall(sys32_sysctl)
diff -Nru a/kernel/sysctl.c b/kernel/sysctl.c
--- a/kernel/sysctl.c	2005-03-01 23:38:52 -08:00
+++ b/kernel/sysctl.c	2005-03-01 23:38:52 -08:00
@@ -52,7 +52,6 @@
 #if defined(CONFIG_SYSCTL)
 
 /* External variables not in a header file. */
-extern int panic_timeout;
 extern int C_A_D;
 extern int sysctl_overcommit_memory;
 extern int sysctl_overcommit_ratio;
@@ -62,7 +61,6 @@
 extern char core_pattern[];
 extern int cad_pid;
 extern int pid_max;
-extern int sysctl_lower_zone_protection;
 extern int min_free_kbytes;
 extern int printk_ratelimit_jiffies;
 extern int printk_ratelimit_burst;
@@ -624,6 +622,16 @@
 		.proc_handler   = &proc_unknown_nmi_panic,
 	},
 #endif
+#if defined(CONFIG_X86)
+	{
+		.ctl_name	= KERN_BOOTLOADER_TYPE,
+		.procname	= "bootloader_type",
+		.data		= &bootloader_type,
+		.maxlen		= sizeof (int),
+		.mode		= 0444,
+		.proc_handler	= &proc_dointvec,
+	},
+#endif
 	{ .ctl_name = 0 }
 };
 
@@ -736,14 +744,13 @@
 	 },
 #endif
 	{
-		.ctl_name	= VM_LOWER_ZONE_PROTECTION,
-		.procname	= "lower_zone_protection",
-		.data		= &sysctl_lower_zone_protection,
-		.maxlen		= sizeof(sysctl_lower_zone_protection),
+		.ctl_name	= VM_LOWMEM_RESERVE_RATIO,
+		.procname	= "lowmem_reserve_ratio",
+		.data		= &sysctl_lowmem_reserve_ratio,
+		.maxlen		= sizeof(sysctl_lowmem_reserve_ratio),
 		.mode		= 0644,
-		.proc_handler	= &lower_zone_protection_sysctl_handler,
+		.proc_handler	= &lowmem_reserve_ratio_sysctl_handler,
 		.strategy	= &sysctl_intvec,
-		.extra1		= &zero,
 	},
 	{
 		.ctl_name	= VM_MIN_FREE_KBYTES,
@@ -755,6 +762,7 @@
 		.strategy	= &sysctl_intvec,
 		.extra1		= &zero,
 	},
+#ifdef CONFIG_MMU
 	{
 		.ctl_name	= VM_MAX_MAP_COUNT,
 		.procname	= "max_map_count",
@@ -763,6 +771,7 @@
 		.mode		= 0644,
 		.proc_handler	= &proc_dointvec
 	},
+#endif
 	{
 		.ctl_name	= VM_LAPTOP_MODE,
 		.procname	= "laptop_mode",
@@ -904,6 +913,7 @@
 		.proc_handler	= &proc_dointvec,
 	},
 #endif
+#ifdef CONFIG_MMU
 	{
 		.ctl_name	= FS_LEASE_TIME,
 		.procname	= "lease-break-time",
@@ -928,6 +938,7 @@
 		.mode		= 0644,
 		.proc_handler	= &proc_dointvec,
 	},
+#endif
 	{ .ctl_name = 0 }
 };
 
@@ -1891,6 +1902,27 @@
 	return 0;
 }
 
+static int do_proc_dointvec_ms_jiffies_conv(int *negp, unsigned long *lvalp,
+					    int *valp,
+					    int write, void *data)
+{
+	if (write) {
+		*valp = msecs_to_jiffies(*negp ? -*lvalp : *lvalp);
+	} else {
+		int val = *valp;
+		unsigned long lval;
+		if (val < 0) {
+			*negp = -1;
+			lval = (unsigned long)-val;
+		} else {
+			*negp = 0;
+			lval = (unsigned long)val;
+		}
+		*lvalp = jiffies_to_msecs(lval);
+	}
+	return 0;
+}
+
 /**
  * proc_dointvec_jiffies - read a vector of integers as seconds
  * @table: the sysctl table
@@ -1935,6 +1967,28 @@
 		    	    do_proc_dointvec_userhz_jiffies_conv,NULL);
 }
 
+/**
+ * proc_dointvec_ms_jiffies - read a vector of integers as 1 milliseconds
+ * @table: the sysctl table
+ * @write: %TRUE if this is a write to the sysctl file
+ * @filp: the file structure
+ * @buffer: the user buffer
+ * @lenp: the size of the user buffer
+ *
+ * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
+ * values from/to the user buffer, treated as an ASCII string. 
+ * The values read are assumed to be in 1/1000 seconds, and 
+ * are converted into jiffies.
+ *
+ * Returns 0 on success.
+ */
+int proc_dointvec_ms_jiffies(ctl_table *table, int write, struct file *filp,
+			     void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+	return do_proc_dointvec(table, write, filp, buffer, lenp, ppos,
+				do_proc_dointvec_ms_jiffies_conv, NULL);
+}
+
 #else /* CONFIG_PROC_FS */
 
 int proc_dostring(ctl_table *table, int write, struct file *filp,
@@ -1979,6 +2033,12 @@
 	return -ENOSYS;
 }
 
+int proc_dointvec_ms_jiffies(ctl_table *table, int write, struct file *filp,
+			     void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+	return -ENOSYS;
+}
+
 int proc_doulongvec_minmax(ctl_table *table, int write, struct file *filp,
 		    void __user *buffer, size_t *lenp, loff_t *ppos)
 {
@@ -2108,6 +2168,33 @@
 	return 1;
 }
 
+/* Strategy function to convert jiffies to seconds */ 
+int sysctl_ms_jiffies(ctl_table *table, int __user *name, int nlen,
+		void __user *oldval, size_t __user *oldlenp,
+		void __user *newval, size_t newlen, void **context)
+{
+	if (oldval) {
+		size_t olen;
+		if (oldlenp) { 
+			if (get_user(olen, oldlenp))
+				return -EFAULT;
+			if (olen!=sizeof(int))
+				return -EINVAL; 
+		}
+		if (put_user(jiffies_to_msecs(*(int *)(table->data)), (int __user *)oldval) ||
+		    (oldlenp && put_user(sizeof(int),oldlenp)))
+			return -EFAULT;
+	}
+	if (newval && newlen) { 
+		int new;
+		if (newlen != sizeof(int))
+			return -EINVAL; 
+		if (get_user(new, (int __user *)newval))
+			return -EFAULT;
+		*(int *)(table->data) = msecs_to_jiffies(new);
+	}
+	return 1;
+}
 
 #else /* CONFIG_SYSCTL */
 
@@ -2138,6 +2225,13 @@
 	return -ENOSYS;
 }
 
+int sysctl_ms_jiffies(ctl_table *table, int __user *name, int nlen,
+		void __user *oldval, size_t __user *oldlenp,
+		void __user *newval, size_t newlen, void **context)
+{
+	return -ENOSYS;
+}
+
 int proc_dostring(ctl_table *table, int write, struct file *filp,
 		  void __user *buffer, size_t *lenp, loff_t *ppos)
 {
@@ -2174,6 +2268,12 @@
 	return -ENOSYS;
 }
 
+int proc_dointvec_ms_jiffies(ctl_table *table, int write, struct file *filp,
+			     void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+	return -ENOSYS;
+}
+
 int proc_doulongvec_minmax(ctl_table *table, int write, struct file *filp,
 		    void __user *buffer, size_t *lenp, loff_t *ppos)
 {
@@ -2208,11 +2308,13 @@
 EXPORT_SYMBOL(proc_dointvec_jiffies);
 EXPORT_SYMBOL(proc_dointvec_minmax);
 EXPORT_SYMBOL(proc_dointvec_userhz_jiffies);
+EXPORT_SYMBOL(proc_dointvec_ms_jiffies);
 EXPORT_SYMBOL(proc_dostring);
 EXPORT_SYMBOL(proc_doulongvec_minmax);
 EXPORT_SYMBOL(proc_doulongvec_ms_jiffies_minmax);
 EXPORT_SYMBOL(register_sysctl_table);
 EXPORT_SYMBOL(sysctl_intvec);
 EXPORT_SYMBOL(sysctl_jiffies);
+EXPORT_SYMBOL(sysctl_ms_jiffies);
 EXPORT_SYMBOL(sysctl_string);
 EXPORT_SYMBOL(unregister_sysctl_table);
diff -Nru a/kernel/time.c b/kernel/time.c
--- a/kernel/time.c	2005-03-01 23:38:53 -08:00
+++ b/kernel/time.c	2005-03-01 23:38:53 -08:00
@@ -33,6 +33,7 @@
 #include <linux/smp_lock.h>
 #include <linux/syscalls.h>
 #include <linux/security.h>
+#include <linux/fs.h>
 
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
@@ -52,12 +53,10 @@
  * sys_gettimeofday().  Is this for backwards compatibility?  If so,
  * why not move it into the appropriate arch directory (for those
  * architectures that need it).
- *
- * XXX This function is NOT 64-bit clean!
  */
-asmlinkage long sys_time(int __user * tloc)
+asmlinkage long sys_time(time_t __user * tloc)
 {
-	int i;
+	time_t i;
 	struct timeval tv;
 
 	do_gettimeofday(&tv);
@@ -417,7 +416,7 @@
 	return copy_to_user(txc_p, &txc, sizeof(struct timex)) ? -EFAULT : ret;
 }
 
-struct timespec current_kernel_time(void)
+inline struct timespec current_kernel_time(void)
 {
         struct timespec now;
         unsigned long seq;
@@ -432,6 +431,50 @@
 }
 
 EXPORT_SYMBOL(current_kernel_time);
+
+/**
+ * current_fs_time - Return FS time
+ * @sb: Superblock.
+ *
+ * Return the current time truncated to the time granuality supported by
+ * the fs.
+ */
+struct timespec current_fs_time(struct super_block *sb)
+{
+	struct timespec now = current_kernel_time();
+	return timespec_trunc(now, sb->s_time_gran);
+}
+EXPORT_SYMBOL(current_fs_time);
+
+/**
+ * timespec_trunc - Truncate timespec to a granuality
+ * @t: Timespec
+ * @gran: Granuality in ns.
+ *
+ * Truncate a timespec to a granuality. gran must be smaller than a second.
+ * Always rounds down.
+ *
+ * This function should be only used for timestamps returned by
+ * current_kernel_time() or CURRENT_TIME, not with do_gettimeofday() because
+ * it doesn't handle the better resolution of the later.
+ */
+struct timespec timespec_trunc(struct timespec t, unsigned gran)
+{
+	/*
+	 * Division is pretty slow so avoid it for common cases.
+	 * Currently current_kernel_time() never returns better than
+	 * jiffies resolution. Exploit that.
+	 */
+	if (gran <= jiffies_to_usecs(1) * 1000) {
+		/* nothing */
+	} else if (gran == 1000000000) {
+		t.tv_nsec = 0;
+	} else {
+		t.tv_nsec -= t.tv_nsec % gran;
+	}
+	return t;
+}
+EXPORT_SYMBOL(timespec_trunc);
 
 #ifdef CONFIG_TIME_INTERPOLATION
 void getnstimeofday (struct timespec *tv)
diff -Nru a/kernel/timer.c b/kernel/timer.c
--- a/kernel/timer.c	2005-03-01 23:39:09 -08:00
+++ b/kernel/timer.c	2005-03-01 23:39:09 -08:00
@@ -465,7 +465,14 @@
 			smp_wmb();
 			timer->base = NULL;
 			spin_unlock_irq(&base->lock);
-			fn(data);
+			{
+				u32 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());
+					BUG();
+				}
+			}
 			spin_lock_irq(&base->lock);
 			goto repeat;
 		}
@@ -554,7 +561,7 @@
 /* 
  * The current time 
  * wall_to_monotonic is what we need to add to xtime (or xtime corrected 
- * for sub jiffie times) to get to monotonic time.  Monotonic is pegged at zero
+ * for sub jiffie times) to get to monotonic time.  Monotonic is pegged
  * at zero at system boot time, so wall_to_monotonic will be negative,
  * however, we will ALWAYS keep the tv_nsec part positive so we can use
  * the usual normalization.
@@ -799,59 +806,6 @@
 	} while (ticks);
 }
 
-static inline void do_process_times(struct task_struct *p,
-	unsigned long user, unsigned long system)
-{
-	unsigned long psecs;
-
-	psecs = (p->utime += user);
-	psecs += (p->stime += system);
-	if (p->signal && !unlikely(p->state & (EXIT_DEAD|EXIT_ZOMBIE)) &&
-	    psecs / HZ >= p->signal->rlim[RLIMIT_CPU].rlim_cur) {
-		/* Send SIGXCPU every second.. */
-		if (!(psecs % HZ))
-			send_sig(SIGXCPU, p, 1);
-		/* and SIGKILL when we go over max.. */
-		if (psecs / HZ >= p->signal->rlim[RLIMIT_CPU].rlim_max)
-			send_sig(SIGKILL, p, 1);
-	}
-}
-
-static inline void do_it_virt(struct task_struct * p, unsigned long ticks)
-{
-	unsigned long it_virt = p->it_virt_value;
-
-	if (it_virt) {
-		it_virt -= ticks;
-		if (!it_virt) {
-			it_virt = p->it_virt_incr;
-			send_sig(SIGVTALRM, p, 1);
-		}
-		p->it_virt_value = it_virt;
-	}
-}
-
-static inline void do_it_prof(struct task_struct *p)
-{
-	unsigned long it_prof = p->it_prof_value;
-
-	if (it_prof) {
-		if (--it_prof == 0) {
-			it_prof = p->it_prof_incr;
-			send_sig(SIGPROF, p, 1);
-		}
-		p->it_prof_value = it_prof;
-	}
-}
-
-static void update_one_process(struct task_struct *p, unsigned long user,
-			unsigned long system, int cpu)
-{
-	do_process_times(p, user, system);
-	do_it_virt(p, user);
-	do_it_prof(p);
-}	
-
 /*
  * Called from the timer interrupt handler to charge one tick to the current 
  * process.  user_tick is 1 if the tick is user time, 0 for system.
@@ -859,11 +813,17 @@
 void update_process_times(int user_tick)
 {
 	struct task_struct *p = current;
-	int cpu = smp_processor_id(), system = user_tick ^ 1;
+	int cpu = smp_processor_id();
 
-	update_one_process(p, user_tick, system, cpu);
+	/* Note: this timer irq context must be accounted for as well. */
+	if (user_tick)
+		account_user_time(p, jiffies_to_cputime(1));
+	else
+		account_system_time(p, HARDIRQ_OFFSET, jiffies_to_cputime(1));
 	run_local_timers();
-	scheduler_tick(user_tick, system);
+	if (rcu_pending(cpu))
+		rcu_check_callbacks(cpu, user_tick);
+	scheduler_tick();
 }
 
 /*
@@ -1438,7 +1398,7 @@
 
 struct time_interpolator *time_interpolator;
 static struct time_interpolator *time_interpolator_list;
-static spinlock_t time_interpolator_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(time_interpolator_lock);
 
 static inline u64 time_interpolator_get_cycles(unsigned int src)
 {
@@ -1451,10 +1411,10 @@
 			return x();
 
 		case TIME_SOURCE_MMIO64	:
-			return readq(time_interpolator->addr);
+			return readq((void __iomem *) time_interpolator->addr);
 
 		case TIME_SOURCE_MMIO32	:
-			return readl(time_interpolator->addr);
+			return readl((void __iomem *) time_interpolator->addr);
 
 		default: return get_cycles();
 	}
diff -Nru a/kernel/user.c b/kernel/user.c
--- a/kernel/user.c	2005-03-01 23:38:55 -08:00
+++ b/kernel/user.c	2005-03-01 23:38:55 -08:00
@@ -26,7 +26,7 @@
 
 static kmem_cache_t *uid_cachep;
 static struct list_head uidhash_table[UIDHASH_SZ];
-static spinlock_t uidhash_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(uidhash_lock);
 
 struct user_struct root_user = {
 	.__count	= ATOMIC_INIT(1),
diff -Nru a/kernel/workqueue.c b/kernel/workqueue.c
--- a/kernel/workqueue.c	2005-03-01 23:39:17 -08:00
+++ b/kernel/workqueue.c	2005-03-01 23:39:17 -08:00
@@ -8,7 +8,7 @@
  *
  * Derived from the taskqueue/keventd code by:
  *
- *   David Woodhouse <dwmw2@redhat.com>
+ *   David Woodhouse <dwmw2@infradead.org>
  *   Andrew Morton <andrewm@uow.edu.au>
  *   Kai Petzke <wpp@marie.physik.tu-berlin.de>
  *   Theodore Ts'o <tytso@mit.edu>
@@ -64,7 +64,7 @@
 
 /* All the per-cpu workqueues on the system, for hotplug cpu to add/remove
    threads to each one as cpus come/go. */
-static spinlock_t workqueue_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(workqueue_lock);
 static LIST_HEAD(workqueues);
 
 /* If it's single threaded, it isn't in the list of workqueues. */
@@ -188,7 +188,7 @@
 
 	current->flags |= PF_NOFREEZE;
 
-	set_user_nice(current, -10);
+	set_user_nice(current, -5);
 
 	/* Block and flush all signals */
 	sigfillset(&blocked);
@@ -485,8 +485,10 @@
 
 	case CPU_ONLINE:
 		/* Kick off worker threads. */
-		list_for_each_entry(wq, &workqueues, list)
+		list_for_each_entry(wq, &workqueues, list) {
+			kthread_bind(wq->cpu_wq[hotcpu].thread, hotcpu);
 			wake_up_process(wq->cpu_wq[hotcpu].thread);
+		}
 		break;
 
 	case CPU_UP_CANCELED:
diff -Nru a/lib/Kconfig.debug b/lib/Kconfig.debug
--- a/lib/Kconfig.debug	2005-03-01 23:39:09 -08:00
+++ b/lib/Kconfig.debug	2005-03-01 23:39:09 -08:00
@@ -23,7 +23,6 @@
 config MAGIC_SYSRQ
 	bool "Magic SysRq key"
 	depends on DEBUG_KERNEL && (H8300 || M68KNOMMU || V850)
-	depends (USERMODE && MCONSOLE)
 	help
 	  Enables console device to interpret special characters as
 	  commands to dump state information.
@@ -48,6 +47,16 @@
 	  allocation as well as poisoning memory on free to catch use of freed
 	  memory. This can make kmalloc/kfree-intensive workloads much slower.
 
+config DEBUG_PREEMPT
+	bool "Debug preemptible kernel"
+	depends on PREEMPT
+	default y
+	help
+	  If you say Y here then the kernel will use a debug variant of the
+	  commonly used smp_processor_id() function and will print warnings
+	  if kernel code uses it in a preemption-unsafe way. Also, the kernel
+	  will detect preemption count underflows.
+
 config DEBUG_SPINLOCK
 	bool "Spinlock debugging"
 	depends on DEBUG_KERNEL && (ALPHA || ARM || X86 || IA64 || M32R || MIPS || PARISC || PPC32 || (SUPERH && !SUPERH64) || SPARC32 || SPARC64 || USERMODE || X86_64)
@@ -79,8 +88,9 @@
 	  Disable for production systems.
 
 config DEBUG_BUGVERBOSE
-	bool "Verbose BUG() reporting (adds 70K)"
-	depends on DEBUG_KERNEL && (ARM || ARM26 || M32R || M68K || SPARC32 || SPARC64)
+	bool "Verbose BUG() reporting (adds 70K)" if DEBUG_KERNEL && EMBEDDED
+	depends on ARM || ARM26 || M32R || M68K || SPARC32 || SPARC64 || (X86 && !X86_64)
+	default !EMBEDDED
 	help
 	  Say Y here to make BUG() panics output the file name and line number
 	  of the BUG call as well as the EIP and oops trace.  This aids
@@ -106,6 +116,29 @@
 
         If you're truly short on disk space or don't expect to report any
         bugs back to the UML developers, say N, otherwise say Y.
+
+config DEBUG_IOREMAP
+	bool "Enable ioremap() debugging"
+	depends on DEBUG_KERNEL && PARISC
+	help
+	  Enabling this option will cause the kernel to distinguish between
+	  ioremapped and physical addresses.  It will print a backtrace (at
+	  most one every 10 seconds), hopefully allowing you to see which
+	  drivers need work.  Fixing all these problems is a prerequisite
+	  for turning on USE_HPPA_IOREMAP.  The warnings are harmless;
+	  the kernel has enough information to fix the broken drivers
+	  automatically, but we'd like to make it more efficient by not
+	  having to do that.
+
+config DEBUG_FS
+	bool "Debug Filesystem"
+	depends on DEBUG_KERNEL
+	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
+	  write to these files.
+
+	  If unsure, say N.
 
 if !X86_64
 config FRAME_POINTER
diff -Nru a/lib/Makefile b/lib/Makefile
--- a/lib/Makefile	2005-03-01 23:38:51 -08:00
+++ b/lib/Makefile	2005-03-01 23:38:51 -08:00
@@ -5,7 +5,7 @@
 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 parser.o int_sqrt.o \
-	 bitmap.o extable.o kobject_uevent.o
+	 bitmap.o extable.o kobject_uevent.o prio_tree.o
 
 ifeq ($(CONFIG_DEBUG_KOBJECT),y)
 CFLAGS_kobject.o += -DDEBUG
@@ -14,6 +14,7 @@
 
 lib-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o
 lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o
+lib-$(CONFIG_GENERIC_FIND_NEXT_BIT) += find_next_bit.o
 obj-$(CONFIG_LOCK_KERNEL) += kernel_lock.o
 
 ifneq ($(CONFIG_HAVE_DEC_LOCK),y) 
diff -Nru a/lib/find_next_bit.c b/lib/find_next_bit.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/lib/find_next_bit.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,55 @@
+/* find_next_bit.c: fallback find next bit implementation
+ *
+ * Copyright (C) 2004 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/bitops.h>
+
+int find_next_bit(const unsigned long *addr, int size, int offset)
+{
+	const unsigned long *base;
+	const int NBITS = sizeof(*addr) * 8;
+	unsigned long tmp;
+
+	base = addr;
+	if (offset) {
+		int suboffset;
+
+		addr += offset / NBITS;
+
+		suboffset = offset % NBITS;
+		if (suboffset) {
+			tmp = *addr;
+			tmp >>= suboffset;
+			if (tmp)
+				goto finish;
+		}
+
+		addr++;
+	}
+
+	while ((tmp = *addr) == 0)
+		addr++;
+
+	offset = (addr - base) * NBITS;
+
+ finish:
+	/* count the remaining bits without using __ffs() since that takes a 32-bit arg */
+	while (!(tmp & 0xff)) {
+		offset += 8;
+		tmp >>= 8;
+	}
+
+	while (!(tmp & 1)) {
+		offset++;
+		tmp >>= 1;
+	}
+
+	return offset;
+}
diff -Nru a/lib/kernel_lock.c b/lib/kernel_lock.c
--- a/lib/kernel_lock.c	2005-03-01 23:38:58 -08:00
+++ b/lib/kernel_lock.c	2005-03-01 23:38:58 -08:00
@@ -7,6 +7,141 @@
  */
 #include <linux/smp_lock.h>
 #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'
+ *
+ * This mutex is taken and released recursively by lock_kernel()
+ * and unlock_kernel().  It is transparently dropped and reaquired
+ * over schedule().  It is used to protect legacy code that hasn't
+ * been migrated to a proper locking design yet.
+ *
+ * Note: code locked by this semaphore will only be serialized against
+ * other code using the same locking facility. The code guarantees that
+ * the task remains on the same CPU.
+ *
+ * Don't use in new code.
+ */
+DECLARE_MUTEX(kernel_sem);
+
+/*
+ * Re-acquire the kernel semaphore.
+ *
+ * This function is called with preemption off.
+ *
+ * We are executing in schedule() so the code must be extremely careful
+ * about recursion, both due to the down() and due to the enabling of
+ * preemption. schedule() will re-check the preemption flag after
+ * reacquiring the semaphore.
+ */
+int __lockfunc __reacquire_kernel_lock(void)
+{
+	struct task_struct *task = current;
+	int saved_lock_depth = task->lock_depth;
+
+	BUG_ON(saved_lock_depth < 0);
+
+	task->lock_depth = -1;
+	preempt_enable_no_resched();
+
+	down(&kernel_sem);
+
+	preempt_disable();
+	task->lock_depth = saved_lock_depth;
+
+	return 0;
+}
+
+void __lockfunc __release_kernel_lock(void)
+{
+	up(&kernel_sem);
+}
+
+/*
+ * Getting the big kernel semaphore.
+ */
+void __lockfunc lock_kernel(void)
+{
+	struct task_struct *task = current;
+	int depth = task->lock_depth + 1;
+
+	if (likely(!depth))
+		/*
+		 * No recursion worries - we set up lock_depth _after_
+		 */
+		down(&kernel_sem);
+
+	task->lock_depth = depth;
+}
+
+void __lockfunc unlock_kernel(void)
+{
+	struct task_struct *task = current;
+
+	BUG_ON(task->lock_depth < 0);
+
+	if (likely(--task->lock_depth < 0))
+		up(&kernel_sem);
+}
+
+#else
 
 /*
  * The 'big kernel lock'
@@ -18,7 +153,7 @@
  *
  * Don't use in new code.
  */
-static spinlock_t kernel_flag __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
+static  __cacheline_aligned_in_smp DEFINE_SPINLOCK(kernel_flag);
 
 
 /*
@@ -34,7 +169,7 @@
  * (This works on UP too - _raw_spin_trylock will never
  * return false in that case)
  */
-int __lockfunc get_kernel_lock(void)
+int __lockfunc __reacquire_kernel_lock(void)
 {
 	while (!_raw_spin_trylock(&kernel_flag)) {
 		if (test_thread_flag(TIF_NEED_RESCHED))
@@ -45,7 +180,7 @@
 	return 0;
 }
 
-void __lockfunc put_kernel_lock(void)
+void __lockfunc __release_kernel_lock(void)
 {
 	_raw_spin_unlock(&kernel_flag);
 	preempt_enable_no_resched();
@@ -122,5 +257,8 @@
 		__unlock_kernel();
 }
 
+#endif
+
 EXPORT_SYMBOL(lock_kernel);
 EXPORT_SYMBOL(unlock_kernel);
+
diff -Nru a/lib/kobject_uevent.c b/lib/kobject_uevent.c
--- a/lib/kobject_uevent.c	2005-03-01 23:38:57 -08:00
+++ b/lib/kobject_uevent.c	2005-03-01 23:38:57 -08:00
@@ -179,7 +179,7 @@
 #ifdef CONFIG_HOTPLUG
 char hotplug_path[HOTPLUG_PATH_LEN] = "/sbin/hotplug";
 u64 hotplug_seqnum;
-static spinlock_t sequence_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(sequence_lock);
 
 /**
  * kobject_hotplug - notify userspace by executing /sbin/hotplug
diff -Nru a/lib/prio_tree.c b/lib/prio_tree.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/lib/prio_tree.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,484 @@
+/*
+ * lib/prio_tree.c - priority search tree
+ *
+ * Copyright (C) 2004, Rajesh Venkatasubramanian <vrajesh@umich.edu>
+ *
+ * This file is released under the GPL v2.
+ *
+ * Based on the radix priority search tree proposed by Edward M. McCreight
+ * SIAM Journal of Computing, vol. 14, no.2, pages 257-276, May 1985
+ *
+ * 02Feb2004	Initial version
+ */
+
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/prio_tree.h>
+
+/*
+ * A clever mix of heap and radix trees forms a radix priority search tree (PST)
+ * which is useful for storing intervals, e.g, we can consider a vma as a closed
+ * interval of file pages [offset_begin, offset_end], and store all vmas that
+ * map a file in a PST. Then, using the PST, we can answer a stabbing query,
+ * i.e., selecting a set of stored intervals (vmas) that overlap with (map) a
+ * given input interval X (a set of consecutive file pages), in "O(log n + m)"
+ * time where 'log n' is the height of the PST, and 'm' is the number of stored
+ * intervals (vmas) that overlap (map) with the input interval X (the set of
+ * consecutive file pages).
+ *
+ * In our implementation, we store closed intervals of the form [radix_index,
+ * heap_index]. We assume that always radix_index <= heap_index. McCreight's PST
+ * is designed for storing intervals with unique radix indices, i.e., each
+ * interval have different radix_index. However, this limitation can be easily
+ * overcome by using the size, i.e., heap_index - radix_index, as part of the
+ * index, so we index the tree using [(radix_index,size), heap_index].
+ *
+ * When the above-mentioned indexing scheme is used, theoretically, in a 32 bit
+ * machine, the maximum height of a PST can be 64. We can use a balanced version
+ * of the priority search tree to optimize the tree height, but the balanced
+ * tree proposed by McCreight is too complex and memory-hungry for our purpose.
+ */
+
+/*
+ * The following macros are used for implementing prio_tree for i_mmap
+ */
+
+#define RADIX_INDEX(vma)  ((vma)->vm_pgoff)
+#define VMA_SIZE(vma)	  (((vma)->vm_end - (vma)->vm_start) >> PAGE_SHIFT)
+/* avoid overflow */
+#define HEAP_INDEX(vma)	  ((vma)->vm_pgoff + (VMA_SIZE(vma) - 1))
+
+
+static void get_index(const struct prio_tree_root *root,
+    const struct prio_tree_node *node,
+    unsigned long *radix, unsigned long *heap)
+{
+	if (root->raw) {
+		struct vm_area_struct *vma = prio_tree_entry(
+		    node, struct vm_area_struct, shared.prio_tree_node);
+
+		*radix = RADIX_INDEX(vma);
+		*heap = HEAP_INDEX(vma);
+	}
+	else {
+		*radix = node->start;
+		*heap = node->last;
+	}
+}
+
+static unsigned long index_bits_to_maxindex[BITS_PER_LONG];
+
+void __init prio_tree_init(void)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(index_bits_to_maxindex) - 1; i++)
+		index_bits_to_maxindex[i] = (1UL << (i + 1)) - 1;
+	index_bits_to_maxindex[ARRAY_SIZE(index_bits_to_maxindex) - 1] = ~0UL;
+}
+
+/*
+ * Maximum heap_index that can be stored in a PST with index_bits bits
+ */
+static inline unsigned long prio_tree_maxindex(unsigned int bits)
+{
+	return index_bits_to_maxindex[bits - 1];
+}
+
+/*
+ * Extend a priority search tree so that it can store a node with heap_index
+ * max_heap_index. In the worst case, this algorithm takes O((log n)^2).
+ * However, this function is used rarely and the common case performance is
+ * not bad.
+ */
+static struct prio_tree_node *prio_tree_expand(struct prio_tree_root *root,
+		struct prio_tree_node *node, unsigned long max_heap_index)
+{
+	struct prio_tree_node *first = NULL, *prev, *last = NULL;
+
+	if (max_heap_index > prio_tree_maxindex(root->index_bits))
+		root->index_bits++;
+
+	while (max_heap_index > prio_tree_maxindex(root->index_bits)) {
+		root->index_bits++;
+
+		if (prio_tree_empty(root))
+			continue;
+
+		if (first == NULL) {
+			first = root->prio_tree_node;
+			prio_tree_remove(root, root->prio_tree_node);
+			INIT_PRIO_TREE_NODE(first);
+			last = first;
+		} else {
+			prev = last;
+			last = root->prio_tree_node;
+			prio_tree_remove(root, root->prio_tree_node);
+			INIT_PRIO_TREE_NODE(last);
+			prev->left = last;
+			last->parent = prev;
+		}
+	}
+
+	INIT_PRIO_TREE_NODE(node);
+
+	if (first) {
+		node->left = first;
+		first->parent = node;
+	} else
+		last = node;
+
+	if (!prio_tree_empty(root)) {
+		last->left = root->prio_tree_node;
+		last->left->parent = last;
+	}
+
+	root->prio_tree_node = node;
+	return node;
+}
+
+/*
+ * Replace a prio_tree_node with a new node and return the old node
+ */
+struct prio_tree_node *prio_tree_replace(struct prio_tree_root *root,
+		struct prio_tree_node *old, struct prio_tree_node *node)
+{
+	INIT_PRIO_TREE_NODE(node);
+
+	if (prio_tree_root(old)) {
+		BUG_ON(root->prio_tree_node != old);
+		/*
+		 * We can reduce root->index_bits here. However, it is complex
+		 * and does not help much to improve performance (IMO).
+		 */
+		node->parent = node;
+		root->prio_tree_node = node;
+	} else {
+		node->parent = old->parent;
+		if (old->parent->left == old)
+			old->parent->left = node;
+		else
+			old->parent->right = node;
+	}
+
+	if (!prio_tree_left_empty(old)) {
+		node->left = old->left;
+		old->left->parent = node;
+	}
+
+	if (!prio_tree_right_empty(old)) {
+		node->right = old->right;
+		old->right->parent = node;
+	}
+
+	return old;
+}
+
+/*
+ * Insert a prio_tree_node @node into a radix priority search tree @root. The
+ * algorithm typically takes O(log n) time where 'log n' is the number of bits
+ * required to represent the maximum heap_index. In the worst case, the algo
+ * can take O((log n)^2) - check prio_tree_expand.
+ *
+ * If a prior node with same radix_index and heap_index is already found in
+ * the tree, then returns the address of the prior node. Otherwise, inserts
+ * @node into the tree and returns @node.
+ */
+struct prio_tree_node *prio_tree_insert(struct prio_tree_root *root,
+		struct prio_tree_node *node)
+{
+	struct prio_tree_node *cur, *res = node;
+	unsigned long radix_index, heap_index;
+	unsigned long r_index, h_index, index, mask;
+	int size_flag = 0;
+
+	get_index(root, node, &radix_index, &heap_index);
+
+	if (prio_tree_empty(root) ||
+			heap_index > prio_tree_maxindex(root->index_bits))
+		return prio_tree_expand(root, node, heap_index);
+
+	cur = root->prio_tree_node;
+	mask = 1UL << (root->index_bits - 1);
+
+	while (mask) {
+		get_index(root, cur, &r_index, &h_index);
+
+		if (r_index == radix_index && h_index == heap_index)
+			return cur;
+
+                if (h_index < heap_index ||
+		    (h_index == heap_index && r_index > radix_index)) {
+			struct prio_tree_node *tmp = node;
+			node = prio_tree_replace(root, cur, node);
+			cur = tmp;
+			/* swap indices */
+			index = r_index;
+			r_index = radix_index;
+			radix_index = index;
+			index = h_index;
+			h_index = heap_index;
+			heap_index = index;
+		}
+
+		if (size_flag)
+			index = heap_index - radix_index;
+		else
+			index = radix_index;
+
+		if (index & mask) {
+			if (prio_tree_right_empty(cur)) {
+				INIT_PRIO_TREE_NODE(node);
+				cur->right = node;
+				node->parent = cur;
+				return res;
+			} else
+				cur = cur->right;
+		} else {
+			if (prio_tree_left_empty(cur)) {
+				INIT_PRIO_TREE_NODE(node);
+				cur->left = node;
+				node->parent = cur;
+				return res;
+			} else
+				cur = cur->left;
+		}
+
+		mask >>= 1;
+
+		if (!mask) {
+			mask = 1UL << (BITS_PER_LONG - 1);
+			size_flag = 1;
+		}
+	}
+	/* Should not reach here */
+	BUG();
+	return NULL;
+}
+
+/*
+ * Remove a prio_tree_node @node from a radix priority search tree @root. The
+ * algorithm takes O(log n) time where 'log n' is the number of bits required
+ * to represent the maximum heap_index.
+ */
+void prio_tree_remove(struct prio_tree_root *root, struct prio_tree_node *node)
+{
+	struct prio_tree_node *cur;
+	unsigned long r_index, h_index_right, h_index_left;
+
+	cur = node;
+
+	while (!prio_tree_left_empty(cur) || !prio_tree_right_empty(cur)) {
+		if (!prio_tree_left_empty(cur))
+			get_index(root, cur->left, &r_index, &h_index_left);
+		else {
+			cur = cur->right;
+			continue;
+		}
+
+		if (!prio_tree_right_empty(cur))
+			get_index(root, cur->right, &r_index, &h_index_right);
+		else {
+			cur = cur->left;
+			continue;
+		}
+
+		/* both h_index_left and h_index_right cannot be 0 */
+		if (h_index_left >= h_index_right)
+			cur = cur->left;
+		else
+			cur = cur->right;
+	}
+
+	if (prio_tree_root(cur)) {
+		BUG_ON(root->prio_tree_node != cur);
+		__INIT_PRIO_TREE_ROOT(root, root->raw);
+		return;
+	}
+
+	if (cur->parent->right == cur)
+		cur->parent->right = cur->parent;
+	else
+		cur->parent->left = cur->parent;
+
+	while (cur != node)
+		cur = prio_tree_replace(root, cur->parent, cur);
+}
+
+/*
+ * Following functions help to enumerate all prio_tree_nodes in the tree that
+ * overlap with the input interval X [radix_index, heap_index]. The enumeration
+ * takes O(log n + m) time where 'log n' is the height of the tree (which is
+ * proportional to # of bits required to represent the maximum heap_index) and
+ * 'm' is the number of prio_tree_nodes that overlap the interval X.
+ */
+
+static struct prio_tree_node *prio_tree_left(struct prio_tree_iter *iter,
+		unsigned long *r_index, unsigned long *h_index)
+{
+	if (prio_tree_left_empty(iter->cur))
+		return NULL;
+
+	get_index(iter->root, iter->cur->left, r_index, h_index);
+
+	if (iter->r_index <= *h_index) {
+		iter->cur = iter->cur->left;
+		iter->mask >>= 1;
+		if (iter->mask) {
+			if (iter->size_level)
+				iter->size_level++;
+		} else {
+			if (iter->size_level) {
+				BUG_ON(!prio_tree_left_empty(iter->cur));
+				BUG_ON(!prio_tree_right_empty(iter->cur));
+				iter->size_level++;
+				iter->mask = ULONG_MAX;
+			} else {
+				iter->size_level = 1;
+				iter->mask = 1UL << (BITS_PER_LONG - 1);
+			}
+		}
+		return iter->cur;
+	}
+
+	return NULL;
+}
+
+static struct prio_tree_node *prio_tree_right(struct prio_tree_iter *iter,
+		unsigned long *r_index, unsigned long *h_index)
+{
+	unsigned long value;
+
+	if (prio_tree_right_empty(iter->cur))
+		return NULL;
+
+	if (iter->size_level)
+		value = iter->value;
+	else
+		value = iter->value | iter->mask;
+
+	if (iter->h_index < value)
+		return NULL;
+
+	get_index(iter->root, iter->cur->right, r_index, h_index);
+
+	if (iter->r_index <= *h_index) {
+		iter->cur = iter->cur->right;
+		iter->mask >>= 1;
+		iter->value = value;
+		if (iter->mask) {
+			if (iter->size_level)
+				iter->size_level++;
+		} else {
+			if (iter->size_level) {
+				BUG_ON(!prio_tree_left_empty(iter->cur));
+				BUG_ON(!prio_tree_right_empty(iter->cur));
+				iter->size_level++;
+				iter->mask = ULONG_MAX;
+			} else {
+				iter->size_level = 1;
+				iter->mask = 1UL << (BITS_PER_LONG - 1);
+			}
+		}
+		return iter->cur;
+	}
+
+	return NULL;
+}
+
+static struct prio_tree_node *prio_tree_parent(struct prio_tree_iter *iter)
+{
+	iter->cur = iter->cur->parent;
+	if (iter->mask == ULONG_MAX)
+		iter->mask = 1UL;
+	else if (iter->size_level == 1)
+		iter->mask = 1UL;
+	else
+		iter->mask <<= 1;
+	if (iter->size_level)
+		iter->size_level--;
+	if (!iter->size_level && (iter->value & iter->mask))
+		iter->value ^= iter->mask;
+	return iter->cur;
+}
+
+static inline int overlap(struct prio_tree_iter *iter,
+		unsigned long r_index, unsigned long h_index)
+{
+	return iter->h_index >= r_index && iter->r_index <= h_index;
+}
+
+/*
+ * prio_tree_first:
+ *
+ * Get the first prio_tree_node that overlaps with the interval [radix_index,
+ * heap_index]. Note that always radix_index <= heap_index. We do a pre-order
+ * traversal of the tree.
+ */
+static struct prio_tree_node *prio_tree_first(struct prio_tree_iter *iter)
+{
+	struct prio_tree_root *root;
+	unsigned long r_index, h_index;
+
+	INIT_PRIO_TREE_ITER(iter);
+
+	root = iter->root;
+	if (prio_tree_empty(root))
+		return NULL;
+
+	get_index(root, root->prio_tree_node, &r_index, &h_index);
+
+	if (iter->r_index > h_index)
+		return NULL;
+
+	iter->mask = 1UL << (root->index_bits - 1);
+	iter->cur = root->prio_tree_node;
+
+	while (1) {
+		if (overlap(iter, r_index, h_index))
+			return iter->cur;
+
+		if (prio_tree_left(iter, &r_index, &h_index))
+			continue;
+
+		if (prio_tree_right(iter, &r_index, &h_index))
+			continue;
+
+		break;
+	}
+	return NULL;
+}
+
+/*
+ * prio_tree_next:
+ *
+ * Get the next prio_tree_node that overlaps with the input interval in iter
+ */
+struct prio_tree_node *prio_tree_next(struct prio_tree_iter *iter)
+{
+	unsigned long r_index, h_index;
+
+	if (iter->cur == NULL)
+		return prio_tree_first(iter);
+
+repeat:
+	while (prio_tree_left(iter, &r_index, &h_index))
+		if (overlap(iter, r_index, h_index))
+			return iter->cur;
+
+	while (!prio_tree_right(iter, &r_index, &h_index)) {
+	    	while (!prio_tree_root(iter->cur) &&
+				iter->cur->parent->right == iter->cur)
+			prio_tree_parent(iter);
+
+		if (prio_tree_root(iter->cur))
+			return NULL;
+
+		prio_tree_parent(iter);
+	}
+
+	if (overlap(iter, r_index, h_index))
+		return iter->cur;
+
+	goto repeat;
+}
diff -Nru a/lib/reed_solomon/reed_solomon.c b/lib/reed_solomon/reed_solomon.c
--- a/lib/reed_solomon/reed_solomon.c	2005-03-01 23:38:56 -08:00
+++ b/lib/reed_solomon/reed_solomon.c	2005-03-01 23:38:56 -08:00
@@ -9,7 +9,7 @@
  * Reed Solomon code lifted from reed solomon library written by Phil Karn
  * Copyright 2002 Phil Karn, KA9Q
  *
- * $Id: rslib.c,v 1.4 2004/10/05 22:07:53 gleixner Exp $
+ * $Id: rslib.c,v 1.5 2004/10/22 15:41: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
@@ -22,19 +22,19 @@
  * Each user must call init_rs to get a pointer to a rs_control
  * structure for the given rs parameters. This structure is either
  * generated or a already available matching control structure is used.
- * If a structure is generated then the polynominal arrays for
+ * If a structure is generated then the polynomial arrays for
  * fast encoding / decoding are built. This can take some time so
- * make sure not to call this function from a timecritical path.
- * Usually a module / driver should initialize the neccecary 
+ * make sure not to call this function from a time critical path.
+ * Usually a module / driver should initialize the necessary 
  * rs_control structure on module / driver init and release it
  * on exit.
- * The encoding puts the calculated syndrome into a given syndrom 
+ * The encoding puts the calculated syndrome into a given syndrome 
  * buffer. 
  * The decoding is a two step process. The first step calculates
- * the syndrome over the received (data + syndrom) and calls the
+ * the syndrome over the received (data + syndrome) and calls the
  * second stage, which does the decoding / error correction itself.
- * Many hw encoders provide a syndrom calculation over the received
- * data + syndrom and can call the second stage directly.
+ * Many hw encoders provide a syndrome calculation over the received
+ * data + syndrome and can call the second stage directly.
  *
  */
 
diff -Nru a/lib/string.c b/lib/string.c
--- a/lib/string.c	2005-03-01 23:39:09 -08:00
+++ b/lib/string.c	2005-03-01 23:39:09 -08:00
@@ -19,8 +19,6 @@
  * -  Kissed strtok() goodbye
  */
 
-#define IN_STRING_C 1
- 
 #include <linux/types.h>
 #include <linux/string.h>
 #include <linux/ctype.h>
@@ -454,30 +452,6 @@
 	return s;
 }
 EXPORT_SYMBOL(memset);
-#endif
-
-#ifndef __HAVE_ARCH_BCOPY
-/**
- * bcopy - Copy one area of memory to another
- * @srcp: Where to copy from
- * @destp: Where to copy to
- * @count: The size of the area.
- *
- * Note that this is the same as memcpy(), with the arguments reversed.
- * memcpy() is the standard, bcopy() is a legacy BSD function.
- *
- * You should not use this function to access IO space, use memcpy_toio()
- * or memcpy_fromio() instead.
- */
-void bcopy(const void * srcp, void * destp, size_t count)
-{
-	const char *src = srcp;
-	char *dest = destp;
-
-	while (count--)
-		*dest++ = *src++;
-}
-EXPORT_SYMBOL(bcopy);
 #endif
 
 #ifndef __HAVE_ARCH_MEMCPY
diff -Nru a/mm/Makefile b/mm/Makefile
--- a/mm/Makefile	2005-03-01 23:39:07 -08:00
+++ b/mm/Makefile	2005-03-01 23:39:07 -08:00
@@ -8,9 +8,9 @@
 			   vmalloc.o
 
 obj-y			:= bootmem.o filemap.o mempool.o oom_kill.o fadvise.o \
-			   page_alloc.o page-writeback.o pdflush.o prio_tree.o \
+			   page_alloc.o page-writeback.o pdflush.o \
 			   readahead.o slab.o swap.o truncate.o vmscan.o \
-			   $(mmu-y)
+			   prio_tree.o $(mmu-y)
 
 obj-$(CONFIG_SWAP)	+= page_io.o swap_state.o swapfile.o thrash.o
 obj-$(CONFIG_HUGETLBFS)	+= hugetlb.o
diff -Nru a/mm/bootmem.c b/mm/bootmem.c
--- a/mm/bootmem.c	2005-03-01 23:38:54 -08:00
+++ b/mm/bootmem.c	2005-03-01 23:38:54 -08:00
@@ -19,6 +19,7 @@
 #include <linux/module.h>
 #include <asm/dma.h>
 #include <asm/io.h>
+#include "internal.h"
 
 /*
  * Access to this subsystem has to be serialized externally. (this is
@@ -275,17 +276,18 @@
 	for (i = 0; i < idx; ) {
 		unsigned long v = ~map[i / BITS_PER_LONG];
 		if (gofast && v == ~0UL) {
-			int j;
+			int j, order;
 
 			count += BITS_PER_LONG;
 			__ClearPageReserved(page);
-			set_page_count(page, 1);
+			order = ffs(BITS_PER_LONG) - 1;
+			set_page_refs(page, order);
 			for (j = 1; j < BITS_PER_LONG; j++) {
 				if (j + 16 < BITS_PER_LONG)
 					prefetchw(page + j + 16);
 				__ClearPageReserved(page + j);
 			}
-			__free_pages(page, ffs(BITS_PER_LONG)-1);
+			__free_pages(page, order);
 			i += BITS_PER_LONG;
 			page += BITS_PER_LONG;
 		} else if (v) {
@@ -294,7 +296,7 @@
 				if (v & m) {
 					count++;
 					__ClearPageReserved(page);
-					set_page_count(page, 1);
+					set_page_refs(page, 0);
 					__free_page(page);
 				}
 			}
diff -Nru a/mm/filemap.c b/mm/filemap.c
--- a/mm/filemap.c	2005-03-01 23:39:18 -08:00
+++ b/mm/filemap.c	2005-03-01 23:39:18 -08:00
@@ -688,7 +688,12 @@
 			     read_actor_t actor)
 {
 	struct inode *inode = mapping->host;
-	unsigned long index, end_index, offset;
+	unsigned long index;
+	unsigned long end_index;
+	unsigned long offset;
+	unsigned long req_size;
+	unsigned long next_index;
+	unsigned long prev_index;
 	loff_t isize;
 	struct page *cached_page;
 	int error;
@@ -696,6 +701,9 @@
 
 	cached_page = NULL;
 	index = *ppos >> PAGE_CACHE_SHIFT;
+	next_index = index;
+	prev_index = ra.prev_page;
+	req_size = (desc->count + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
 	offset = *ppos & ~PAGE_CACHE_MASK;
 
 	isize = i_size_read(inode);
@@ -705,7 +713,7 @@
 	end_index = (isize - 1) >> PAGE_CACHE_SHIFT;
 	for (;;) {
 		struct page *page;
-		unsigned long nr, ret;
+		unsigned long ret_size, nr, ret;
 
 		/* nr is the maximum number of bytes to copy from this page */
 		nr = PAGE_CACHE_SIZE;
@@ -720,7 +728,12 @@
 		nr = nr - offset;
 
 		cond_resched();
-		page_cache_readahead(mapping, &ra, filp, index);
+		if (index == next_index && req_size) {
+			ret_size = page_cache_readahead(mapping, &ra,
+					filp, index, req_size);
+			next_index += ret_size;
+			req_size -= ret_size;
+		}
 
 find_page:
 		page = find_get_page(mapping, index);
@@ -740,10 +753,12 @@
 			flush_dcache_page(page);
 
 		/*
-		 * Mark the page accessed if we read the beginning.
+		 * When (part of) the same page is read multiple times
+		 * in succession, only mark it as accessed the first time.
 		 */
-		if (!offset)
+		if (prev_index != index)
 			mark_page_accessed(page);
+		prev_index = index;
 
 		/*
 		 * Ok, we have the page, and it's up-to-date, so
@@ -790,11 +805,21 @@
 			goto readpage_error;
 
 		if (!PageUptodate(page)) {
-			wait_on_page_locked(page);
+			lock_page(page);
 			if (!PageUptodate(page)) {
+				if (page->mapping == NULL) {
+					/*
+					 * invalidate_inode_pages got it
+					 */
+					unlock_page(page);
+					page_cache_release(page);
+					goto find_page;
+				}
+				unlock_page(page);
 				error = -EIO;
 				goto readpage_error;
 			}
+			unlock_page(page);
 		}
 
 		/*
@@ -1166,7 +1191,7 @@
 	 * For sequential accesses, we use the generic readahead logic.
 	 */
 	if (VM_SequentialReadHint(area))
-		page_cache_readahead(mapping, ra, file, pgoff);
+		page_cache_readahead(mapping, ra, file, pgoff, 1);
 
 	/*
 	 * Do we have something in the page cache already?
@@ -1433,12 +1458,9 @@
 	return NULL;
 }
 
-static int filemap_populate(struct vm_area_struct *vma,
-			unsigned long addr,
-			unsigned long len,
-			pgprot_t prot,
-			unsigned long pgoff,
-			int nonblock)
+int filemap_populate(struct vm_area_struct *vma, unsigned long addr,
+		unsigned long len, pgprot_t prot, unsigned long pgoff,
+		int nonblock)
 {
 	struct file *file = vma->vm_file;
 	struct address_space *mapping = file->f_mapping;
@@ -1498,6 +1520,7 @@
 	vma->vm_ops = &generic_file_vm_ops;
 	return 0;
 }
+EXPORT_SYMBOL(filemap_populate);
 
 /*
  * This is for filesystems which do not implement ->writepage.
@@ -1908,7 +1931,16 @@
 
 	pagevec_init(&lru_pvec, 0);
 
-	buf = iov->iov_base + written;	/* handle partial DIO write */
+	/*
+	 * handle partial DIO write.  Adjust cur_iov if needed.
+	 */
+	if (likely(nr_segs == 1))
+		buf = iov->iov_base + written;
+	else {
+		filemap_set_next_iovec(&cur_iov, &iov_base, written);
+		buf = iov->iov_base + iov_base;
+	}
+
 	do {
 		unsigned long index;
 		unsigned long offset;
@@ -2046,6 +2078,8 @@
 	count = ocount;
 	pos = *ppos;
 
+	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;
 	written = 0;
@@ -2149,7 +2183,7 @@
 	BUG_ON(iocb->ki_pos != pos);
 
 	down(&inode->i_sem);
-	ret = generic_file_aio_write_nolock(iocb, &local_iov, 1,
+	ret = __generic_file_aio_write_nolock(iocb, &local_iov, 1,
 						&iocb->ki_pos);
 	up(&inode->i_sem);
 
@@ -2225,7 +2259,8 @@
 EXPORT_SYMBOL(generic_file_writev);
 
 /*
- * Called under i_sem for writes to S_ISREG files
+ * Called under i_sem for writes to S_ISREG files.   Returns -EIO if something
+ * went wrong during pagecache shootdown.
  */
 ssize_t
 generic_file_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
@@ -2235,12 +2270,23 @@
 	struct address_space *mapping = file->f_mapping;
 	ssize_t retval;
 
+	/*
+	 * If it's a write, unmap all mmappings of the file up-front.  This
+	 * will cause any pte dirty bits to be propagated into the pageframes
+	 * for the subsequent filemap_write_and_wait().
+	 */
+	if (rw == WRITE && mapping_mapped(mapping))
+		unmap_mapping_range(mapping, 0, -1, 0);
+
 	retval = filemap_write_and_wait(mapping);
 	if (retval == 0) {
 		retval = mapping->a_ops->direct_IO(rw, iocb, iov,
 						offset, nr_segs);
-		if (rw == WRITE && mapping->nrpages)
-			invalidate_inode_pages2(mapping);
+		if (rw == WRITE && mapping->nrpages) {
+			int err = invalidate_inode_pages2(mapping);
+			if (err)
+				retval = err;
+		}
 	}
 	return retval;
 }
diff -Nru a/mm/fremap.c b/mm/fremap.c
--- a/mm/fremap.c	2005-03-01 23:38:51 -08:00
+++ b/mm/fremap.c	2005-03-01 23:38:51 -08:00
@@ -60,14 +60,19 @@
 	pgoff_t size;
 	int err = -ENOMEM;
 	pte_t *pte;
-	pgd_t *pgd;
 	pmd_t *pmd;
+	pud_t *pud;
+	pgd_t *pgd;
 	pte_t pte_val;
 
 	pgd = pgd_offset(mm, addr);
 	spin_lock(&mm->page_table_lock);
+	
+	pud = pud_alloc(mm, pgd, addr);
+	if (!pud)
+		goto err_unlock;
 
-	pmd = pmd_alloc(mm, pgd, addr);
+	pmd = pmd_alloc(mm, pud, addr);
 	if (!pmd)
 		goto err_unlock;
 
@@ -112,14 +117,19 @@
 {
 	int err = -ENOMEM;
 	pte_t *pte;
-	pgd_t *pgd;
 	pmd_t *pmd;
+	pud_t *pud;
+	pgd_t *pgd;
 	pte_t pte_val;
 
 	pgd = pgd_offset(mm, addr);
 	spin_lock(&mm->page_table_lock);
+	
+	pud = pud_alloc(mm, pgd, addr);
+	if (!pud)
+		goto err_unlock;
 
-	pmd = pmd_alloc(mm, pgd, addr);
+	pmd = pmd_alloc(mm, pud, addr);
 	if (!pmd)
 		goto err_unlock;
 
diff -Nru a/mm/highmem.c b/mm/highmem.c
--- a/mm/highmem.c	2005-03-01 23:39:07 -08:00
+++ b/mm/highmem.c	2005-03-01 23:39:07 -08:00
@@ -53,7 +53,7 @@
 #ifdef CONFIG_HIGHMEM
 static int pkmap_count[LAST_PKMAP];
 static unsigned int last_pkmap_nr;
-static spinlock_t kmap_lock __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
+static  __cacheline_aligned_in_smp DEFINE_SPINLOCK(kmap_lock);
 
 pte_t * pkmap_page_table;
 
@@ -425,7 +425,7 @@
 	 * at least one page was bounced, fill in possible non-highmem
 	 * pages
 	 */
-	bio_for_each_segment(from, *bio_orig, i) {
+	__bio_for_each_segment(from, *bio_orig, i, 0) {
 		to = bio_iovec_idx(bio, i);
 		if (!to->bv_page) {
 			to->bv_page = from->bv_page;
diff -Nru a/mm/hugetlb.c b/mm/hugetlb.c
--- a/mm/hugetlb.c	2005-03-01 23:39:07 -08:00
+++ b/mm/hugetlb.c	2005-03-01 23:39:07 -08:00
@@ -10,6 +10,7 @@
 #include <linux/hugetlb.h>
 #include <linux/sysctl.h>
 #include <linux/highmem.h>
+#include <linux/nodemask.h>
 
 const unsigned long hugetlb_zero = 0, hugetlb_infinity = ~0UL;
 static unsigned long nr_huge_pages, free_huge_pages;
@@ -17,7 +18,7 @@
 static struct list_head hugepage_freelists[MAX_NUMNODES];
 static unsigned int nr_huge_pages_node[MAX_NUMNODES];
 static unsigned int free_huge_pages_node[MAX_NUMNODES];
-static spinlock_t hugetlb_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(hugetlb_lock);
 
 static void enqueue_huge_page(struct page *page)
 {
@@ -54,10 +55,10 @@
 	struct page *page;
 	page = alloc_pages_node(nid, GFP_HIGHUSER|__GFP_COMP|__GFP_NOWARN,
 					HUGETLB_PAGE_ORDER);
-	nid = (nid + 1) % numnodes;
+	nid = (nid + 1) % num_online_nodes();
 	if (page) {
 		nr_huge_pages++;
-		nr_huge_pages_node[page_zone(page)->zone_pgdat->node_id]++;
+		nr_huge_pages_node[page_to_nid(page)]++;
 	}
 	return page;
 }
diff -Nru a/mm/internal.h b/mm/internal.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/mm/internal.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,13 @@
+/* internal.h: mm/ internal definitions
+ *
+ * Copyright (C) 2004 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.
+ */
+
+/* page_alloc.c */
+extern void set_page_refs(struct page *page, int order);
diff -Nru a/mm/madvise.c b/mm/madvise.c
--- a/mm/madvise.c	2005-03-01 23:38:54 -08:00
+++ b/mm/madvise.c	2005-03-01 23:38:54 -08:00
@@ -8,7 +8,7 @@
 #include <linux/mman.h>
 #include <linux/pagemap.h>
 #include <linux/syscalls.h>
-
+#include <linux/hugetlb.h>
 
 /*
  * We can potentially split a vm area into separate
@@ -18,18 +18,18 @@
 			     unsigned long end, int behavior)
 {
 	struct mm_struct * mm = vma->vm_mm;
-	int error;
+	int error = 0;
 
 	if (start != vma->vm_start) {
 		error = split_vma(mm, vma, start, 1);
 		if (error)
-			return -EAGAIN;
+			goto out;
 	}
 
 	if (end != vma->vm_end) {
 		error = split_vma(mm, vma, end, 0);
 		if (error)
-			return -EAGAIN;
+			goto out;
 	}
 
 	/*
@@ -48,7 +48,10 @@
 		break;
 	}
 
-	return 0;
+out:
+	if (error == -ENOMEM)
+		error = -EAGAIN;
+	return error;
 }
 
 /*
@@ -94,7 +97,7 @@
 static long madvise_dontneed(struct vm_area_struct * vma,
 			     unsigned long start, unsigned long end)
 {
-	if (vma->vm_flags & VM_LOCKED)
+	if ((vma->vm_flags & VM_LOCKED) || is_vm_hugetlb_page(vma))
 		return -EINVAL;
 
 	if (unlikely(vma->vm_flags & VM_NONLINEAR)) {
diff -Nru a/mm/memory.c b/mm/memory.c
--- a/mm/memory.c	2005-03-01 23:38:56 -08:00
+++ b/mm/memory.c	2005-03-01 23:38:56 -08:00
@@ -34,6 +34,8 @@
  *
  * 16.07.99  -  Support of BIGMEM added by Gerhard Wichert, Siemens AG
  *		(Gerhard.Wichert@pdb.siemens.de)
+ *
+ * Aug/Sep 2004 Changed to four level page tables (Andi Kleen)
  */
 
 #include <linux/kernel_stat.h>
@@ -44,6 +46,7 @@
 #include <linux/highmem.h>
 #include <linux/pagemap.h>
 #include <linux/rmap.h>
+#include <linux/acct.h>
 #include <linux/module.h>
 #include <linux/init.h>
 
@@ -74,84 +77,120 @@
  * and ZONE_HIGHMEM.
  */
 void * high_memory;
-struct page *highmem_start_page;
 unsigned long vmalloc_earlyreserve;
 
 EXPORT_SYMBOL(num_physpages);
-EXPORT_SYMBOL(highmem_start_page);
 EXPORT_SYMBOL(high_memory);
 EXPORT_SYMBOL(vmalloc_earlyreserve);
 
 /*
- * We special-case the C-O-W ZERO_PAGE, because it's such
- * a common occurrence (no need to read the page to know
- * that it's zero - better for the cache and memory subsystem).
+ * Note: this doesn't free the actual pages themselves. That
+ * has been handled earlier when unmapping all the memory regions.
  */
-static inline void copy_cow_page(struct page * from, struct page * to, unsigned long address)
+static inline void clear_pmd_range(struct mmu_gather *tlb, pmd_t *pmd, unsigned long start, unsigned long end)
 {
-	if (from == ZERO_PAGE(address)) {
-		clear_user_highpage(to, address);
+	struct page *page;
+
+	if (pmd_none(*pmd))
+		return;
+	if (unlikely(pmd_bad(*pmd))) {
+		pmd_ERROR(*pmd);
+		pmd_clear(pmd);
 		return;
 	}
-	copy_user_highpage(to, from, address);
+	if (!((start | end) & ~PMD_MASK)) {
+		/* Only clear full, aligned ranges */
+		page = pmd_page(*pmd);
+		pmd_clear(pmd);
+		dec_page_state(nr_page_table_pages);
+		tlb->mm->nr_ptes--;
+		pte_free_tlb(tlb, page);
+	}
 }
 
-/*
- * Note: this doesn't free the actual pages themselves. That
- * has been handled earlier when unmapping all the memory regions.
- */
-static inline void free_one_pmd(struct mmu_gather *tlb, pmd_t * dir)
+static inline void clear_pud_range(struct mmu_gather *tlb, pud_t *pud, unsigned long start, unsigned long end)
 {
-	struct page *page;
+	unsigned long addr = start, next;
+	pmd_t *pmd, *__pmd;
 
-	if (pmd_none(*dir))
+	if (pud_none(*pud))
 		return;
-	if (unlikely(pmd_bad(*dir))) {
-		pmd_ERROR(*dir);
-		pmd_clear(dir);
+	if (unlikely(pud_bad(*pud))) {
+		pud_ERROR(*pud);
+		pud_clear(pud);
 		return;
 	}
-	page = pmd_page(*dir);
-	pmd_clear(dir);
-	dec_page_state(nr_page_table_pages);
-	tlb->mm->nr_ptes--;
-	pte_free_tlb(tlb, page);
+
+	pmd = __pmd = pmd_offset(pud, start);
+	do {
+		next = (addr + PMD_SIZE) & PMD_MASK;
+		if (next > end || next <= addr)
+			next = end;
+		
+		clear_pmd_range(tlb, pmd, addr, next);
+		pmd++;
+		addr = next;
+	} while (addr && (addr < end));
+
+	if (!((start | end) & ~PUD_MASK)) {
+		/* Only clear full, aligned ranges */
+		pud_clear(pud);
+		pmd_free_tlb(tlb, __pmd);
+	}
 }
 
-static inline void free_one_pgd(struct mmu_gather *tlb, pgd_t * dir)
+
+static inline void clear_pgd_range(struct mmu_gather *tlb, pgd_t *pgd, unsigned long start, unsigned long end)
 {
-	int j;
-	pmd_t * pmd;
+	unsigned long addr = start, next;
+	pud_t *pud, *__pud;
 
-	if (pgd_none(*dir))
+	if (pgd_none(*pgd))
 		return;
-	if (unlikely(pgd_bad(*dir))) {
-		pgd_ERROR(*dir);
-		pgd_clear(dir);
+	if (unlikely(pgd_bad(*pgd))) {
+		pgd_ERROR(*pgd);
+		pgd_clear(pgd);
 		return;
 	}
-	pmd = pmd_offset(dir, 0);
-	pgd_clear(dir);
-	for (j = 0; j < PTRS_PER_PMD ; j++)
-		free_one_pmd(tlb, pmd+j);
-	pmd_free_tlb(tlb, pmd);
+
+	pud = __pud = pud_offset(pgd, start);
+	do {
+		next = (addr + PUD_SIZE) & PUD_MASK;
+		if (next > end || next <= addr)
+			next = end;
+		
+		clear_pud_range(tlb, pud, addr, next);
+		pud++;
+		addr = next;
+	} while (addr && (addr < end));
+
+	if (!((start | end) & ~PGDIR_MASK)) {
+		/* Only clear full, aligned ranges */
+		pgd_clear(pgd);
+		pud_free_tlb(tlb, __pud);
+	}
 }
 
 /*
- * This function clears all user-level page tables of a process - this
- * is needed by execve(), so that old pages aren't in the way.
+ * This function clears user-level page tables of a process.
  *
  * Must be called with pagetable lock held.
  */
-void clear_page_tables(struct mmu_gather *tlb, unsigned long first, int nr)
+void clear_page_range(struct mmu_gather *tlb, unsigned long start, unsigned long end)
 {
-	pgd_t * page_dir = tlb->mm->pgd;
-
-	page_dir += first;
-	do {
-		free_one_pgd(tlb, page_dir);
-		page_dir++;
-	} while (--nr);
+	unsigned long addr = start, next;
+	pgd_t * pgd = pgd_offset(tlb->mm, start);
+	unsigned long i;
+
+	for (i = pgd_index(start); i <= pgd_index(end-1); i++) {
+		next = (addr + PGDIR_SIZE) & PGDIR_MASK;
+		if (next > end || next <= addr)
+			next = end;
+		
+		clear_pgd_range(tlb, pgd, addr, next);
+		pgd++;
+		addr = next;
+	}
 }
 
 pte_t fastcall * pte_alloc_map(struct mm_struct *mm, pmd_t *pmd, unsigned long address)
@@ -204,165 +243,212 @@
 out:
 	return pte_offset_kernel(pmd, address);
 }
-#define PTE_TABLE_MASK	((PTRS_PER_PTE-1) * sizeof(pte_t))
-#define PMD_TABLE_MASK	((PTRS_PER_PMD-1) * sizeof(pmd_t))
 
 /*
  * copy one vm_area from one task to the other. Assumes the page tables
  * already present in the new task to be cleared in the whole range
  * covered by this vma.
  *
- * 08Jan98 Merged into one routine from several inline routines to reduce
- *         variable count and make things faster. -jj
- *
  * dst->page_table_lock is held on entry and exit,
- * but may be dropped within pmd_alloc() and pte_alloc_map().
+ * but may be dropped within p[mg]d_alloc() and pte_alloc_map().
  */
-int copy_page_range(struct mm_struct *dst, struct mm_struct *src,
-			struct vm_area_struct *vma)
+
+static inline void
+copy_swap_pte(struct mm_struct *dst_mm, struct mm_struct *src_mm, pte_t pte)
 {
-	pgd_t * src_pgd, * dst_pgd;
-	unsigned long address = vma->vm_start;
-	unsigned long end = vma->vm_end;
-	unsigned long cow;
+	if (pte_file(pte))
+		return;
+	swap_duplicate(pte_to_swp_entry(pte));
+	if (list_empty(&dst_mm->mmlist)) {
+		spin_lock(&mmlist_lock);
+		list_add(&dst_mm->mmlist, &src_mm->mmlist);
+		spin_unlock(&mmlist_lock);
+	}
+}
 
-	if (is_vm_hugetlb_page(vma))
-		return copy_hugetlb_page_range(dst, src, vma);
+static inline void
+copy_one_pte(struct mm_struct *dst_mm,  struct mm_struct *src_mm,
+		pte_t *dst_pte, pte_t *src_pte, unsigned long vm_flags,
+		unsigned long addr)
+{
+	pte_t pte = *src_pte;
+	struct page *page;
+	unsigned long pfn;
 
-	cow = (vma->vm_flags & (VM_SHARED | VM_MAYWRITE)) == VM_MAYWRITE;
-	src_pgd = pgd_offset(src, address)-1;
-	dst_pgd = pgd_offset(dst, address)-1;
+	/* pte contains position in swap, so copy. */
+	if (!pte_present(pte)) {
+		copy_swap_pte(dst_mm, src_mm, pte);
+		set_pte(dst_pte, pte);
+		return;
+	}
+	pfn = pte_pfn(pte);
+	/* the pte points outside of valid memory, the
+	 * mapping is assumed to be good, meaningful
+	 * and not mapped via rmap - duplicate the
+	 * mapping as is.
+	 */
+	page = NULL;
+	if (pfn_valid(pfn))
+		page = pfn_to_page(pfn);
 
-	for (;;) {
-		pmd_t * src_pmd, * dst_pmd;
+	if (!page || PageReserved(page)) {
+		set_pte(dst_pte, pte);
+		return;
+	}
 
-		src_pgd++; dst_pgd++;
-		
-		/* copy_pmd_range */
-		
-		if (pgd_none(*src_pgd))
-			goto skip_copy_pmd_range;
-		if (unlikely(pgd_bad(*src_pgd))) {
-			pgd_ERROR(*src_pgd);
-			pgd_clear(src_pgd);
-skip_copy_pmd_range:	address = (address + PGDIR_SIZE) & PGDIR_MASK;
-			if (!address || (address >= end))
-				goto out;
+	/*
+	 * If it's a COW mapping, write protect it both
+	 * in the parent and the child
+	 */
+	if ((vm_flags & (VM_SHARED | VM_MAYWRITE)) == VM_MAYWRITE) {
+		ptep_set_wrprotect(src_pte);
+		pte = *src_pte;
+	}
+
+	/*
+	 * If it's a shared mapping, mark it clean in
+	 * the child
+	 */
+	if (vm_flags & VM_SHARED)
+		pte = pte_mkclean(pte);
+	pte = pte_mkold(pte);
+	get_page(page);
+	dst_mm->rss++;
+	if (PageAnon(page))
+		dst_mm->anon_rss++;
+	set_pte(dst_pte, pte);
+	page_dup_rmap(page);
+}
+
+static int copy_pte_range(struct mm_struct *dst_mm,  struct mm_struct *src_mm,
+		pmd_t *dst_pmd, pmd_t *src_pmd, struct vm_area_struct *vma,
+		unsigned long addr, unsigned long end)
+{
+	pte_t *src_pte, *dst_pte;
+	pte_t *s, *d;
+	unsigned long vm_flags = vma->vm_flags;
+
+	d = dst_pte = pte_alloc_map(dst_mm, dst_pmd, addr);
+	if (!dst_pte)
+		return -ENOMEM;
+
+	spin_lock(&src_mm->page_table_lock);
+	s = src_pte = pte_offset_map_nested(src_pmd, addr);
+	for (; addr < end; addr += PAGE_SIZE, s++, d++) {
+		if (pte_none(*s))
+			continue;
+		copy_one_pte(dst_mm, src_mm, d, s, vm_flags, addr);
+	}
+	pte_unmap_nested(src_pte);
+	pte_unmap(dst_pte);
+	spin_unlock(&src_mm->page_table_lock);
+	cond_resched_lock(&dst_mm->page_table_lock);
+	return 0;
+}
+
+static int copy_pmd_range(struct mm_struct *dst_mm,  struct mm_struct *src_mm,
+		pud_t *dst_pud, pud_t *src_pud, struct vm_area_struct *vma,
+		unsigned long addr, unsigned long end)
+{
+	pmd_t *src_pmd, *dst_pmd;
+	int err = 0;
+	unsigned long next;
+
+	src_pmd = pmd_offset(src_pud, addr);
+	dst_pmd = pmd_alloc(dst_mm, dst_pud, addr);
+	if (!dst_pmd)
+		return -ENOMEM;
+
+	for (; addr < end; addr = next, src_pmd++, dst_pmd++) {
+		next = (addr + PMD_SIZE) & PMD_MASK;
+		if (next > end || next <= addr)
+			next = end;
+		if (pmd_none(*src_pmd))
+			continue;
+		if (pmd_bad(*src_pmd)) {
+			pmd_ERROR(*src_pmd);
+			pmd_clear(src_pmd);
 			continue;
 		}
+		err = copy_pte_range(dst_mm, src_mm, dst_pmd, src_pmd,
+							vma, addr, next);
+		if (err)
+			break;
+	}
+	return err;
+}
 
-		src_pmd = pmd_offset(src_pgd, address);
-		dst_pmd = pmd_alloc(dst, dst_pgd, address);
-		if (!dst_pmd)
-			goto nomem;
+static int copy_pud_range(struct mm_struct *dst_mm,  struct mm_struct *src_mm,
+		pgd_t *dst_pgd, pgd_t *src_pgd, struct vm_area_struct *vma,
+		unsigned long addr, unsigned long end)
+{
+	pud_t *src_pud, *dst_pud;
+	int err = 0;
+	unsigned long next;
+
+	src_pud = pud_offset(src_pgd, addr);
+	dst_pud = pud_alloc(dst_mm, dst_pgd, addr);
+	if (!dst_pud)
+		return -ENOMEM;
+
+	for (; addr < end; addr = next, src_pud++, dst_pud++) {
+		next = (addr + PUD_SIZE) & PUD_MASK;
+		if (next > end || next <= addr)
+			next = end;
+		if (pud_none(*src_pud))
+			continue;
+		if (pud_bad(*src_pud)) {
+			pud_ERROR(*src_pud);
+			pud_clear(src_pud);
+			continue;
+		}
+		err = copy_pmd_range(dst_mm, src_mm, dst_pud, src_pud,
+							vma, addr, next);
+		if (err)
+			break;
+	}
+	return err;
+}
 
-		do {
-			pte_t * src_pte, * dst_pte;
-		
-			/* copy_pte_range */
-		
-			if (pmd_none(*src_pmd))
-				goto skip_copy_pte_range;
-			if (unlikely(pmd_bad(*src_pmd))) {
-				pmd_ERROR(*src_pmd);
-				pmd_clear(src_pmd);
-skip_copy_pte_range:
-				address = (address + PMD_SIZE) & PMD_MASK;
-				if (address >= end)
-					goto out;
-				goto cont_copy_pmd_range;
-			}
+int copy_page_range(struct mm_struct *dst, struct mm_struct *src,
+		struct vm_area_struct *vma)
+{
+	pgd_t *src_pgd, *dst_pgd;
+	unsigned long addr, start, end, next;
+	int err = 0;
 
-			dst_pte = pte_alloc_map(dst, dst_pmd, address);
-			if (!dst_pte)
-				goto nomem;
-			spin_lock(&src->page_table_lock);	
-			src_pte = pte_offset_map_nested(src_pmd, address);
-			do {
-				pte_t pte = *src_pte;
-				struct page *page;
-				unsigned long pfn;
-
-				/* copy_one_pte */
-
-				if (pte_none(pte))
-					goto cont_copy_pte_range_noset;
-				/* pte contains position in swap, so copy. */
-				if (!pte_present(pte)) {
-					if (!pte_file(pte)) {
-						swap_duplicate(pte_to_swp_entry(pte));
-						if (list_empty(&dst->mmlist)) {
-							spin_lock(&mmlist_lock);
-							list_add(&dst->mmlist,
-								 &src->mmlist);
-							spin_unlock(&mmlist_lock);
-						}
-					}
-					set_pte(dst_pte, pte);
-					goto cont_copy_pte_range_noset;
-				}
-				pfn = pte_pfn(pte);
-				/* the pte points outside of valid memory, the
-				 * mapping is assumed to be good, meaningful
-				 * and not mapped via rmap - duplicate the
-				 * mapping as is.
-				 */
-				page = NULL;
-				if (pfn_valid(pfn)) 
-					page = pfn_to_page(pfn); 
-
-				if (!page || PageReserved(page)) {
-					set_pte(dst_pte, pte);
-					goto cont_copy_pte_range_noset;
-				}
+	if (is_vm_hugetlb_page(vma))
+		return copy_hugetlb_page_range(dst, src, vma);
 
-				/*
-				 * If it's a COW mapping, write protect it both
-				 * in the parent and the child
-				 */
-				if (cow) {
-					ptep_set_wrprotect(src_pte);
-					pte = *src_pte;
-				}
+	start = vma->vm_start;
+	src_pgd = pgd_offset(src, start);
+	dst_pgd = pgd_offset(dst, start);
+
+	end = vma->vm_end;
+	addr = start;
+	while (addr && (addr < end-1)) {
+		next = (addr + PGDIR_SIZE) & PGDIR_MASK;
+		if (next > end || next <= addr)
+			next = end;
+		if (pgd_none(*src_pgd))
+			goto next_pgd;
+		if (pgd_bad(*src_pgd)) {
+			pgd_ERROR(*src_pgd);
+			pgd_clear(src_pgd);
+			goto next_pgd;
+		}
+		err = copy_pud_range(dst, src, dst_pgd, src_pgd,
+							vma, addr, next);
+		if (err)
+			break;
 
-				/*
-				 * If it's a shared mapping, mark it clean in
-				 * the child
-				 */
-				if (vma->vm_flags & VM_SHARED)
-					pte = pte_mkclean(pte);
-				pte = pte_mkold(pte);
-				get_page(page);
-				dst->rss++;
-				if (PageAnon(page))
-					dst->anon_rss++;
-				set_pte(dst_pte, pte);
-				page_dup_rmap(page);
-cont_copy_pte_range_noset:
-				address += PAGE_SIZE;
-				if (address >= end) {
-					pte_unmap_nested(src_pte);
-					pte_unmap(dst_pte);
-					goto out_unlock;
-				}
-				src_pte++;
-				dst_pte++;
-			} while ((unsigned long)src_pte & PTE_TABLE_MASK);
-			pte_unmap_nested(src_pte-1);
-			pte_unmap(dst_pte-1);
-			spin_unlock(&src->page_table_lock);
-			cond_resched_lock(&dst->page_table_lock);
-cont_copy_pmd_range:
-			src_pmd++;
-			dst_pmd++;
-		} while ((unsigned long)src_pmd & PMD_TABLE_MASK);
+next_pgd:
+		src_pgd++;
+		dst_pgd++;
+		addr = next;
 	}
-out_unlock:
-	spin_unlock(&src->page_table_lock);
-out:
-	return 0;
-nomem:
-	return -ENOMEM;
+
+	return err;
 }
 
 static void zap_pte_range(struct mmu_gather *tlb,
@@ -449,23 +535,23 @@
 }
 
 static void zap_pmd_range(struct mmu_gather *tlb,
-		pgd_t * dir, unsigned long address,
+		pud_t *pud, unsigned long address,
 		unsigned long size, struct zap_details *details)
 {
 	pmd_t * pmd;
 	unsigned long end;
 
-	if (pgd_none(*dir))
+	if (pud_none(*pud))
 		return;
-	if (unlikely(pgd_bad(*dir))) {
-		pgd_ERROR(*dir);
-		pgd_clear(dir);
+	if (unlikely(pud_bad(*pud))) {
+		pud_ERROR(*pud);
+		pud_clear(pud);
 		return;
 	}
-	pmd = pmd_offset(dir, address);
+	pmd = pmd_offset(pud, address);
 	end = address + size;
-	if (end > ((address + PGDIR_SIZE) & PGDIR_MASK))
-		end = ((address + PGDIR_SIZE) & PGDIR_MASK);
+	if (end > ((address + PUD_SIZE) & PUD_MASK))
+		end = ((address + PUD_SIZE) & PUD_MASK);
 	do {
 		zap_pte_range(tlb, pmd, address, end - address, details);
 		address = (address + PMD_SIZE) & PMD_MASK; 
@@ -473,36 +559,54 @@
 	} while (address && (address < end));
 }
 
+static void zap_pud_range(struct mmu_gather *tlb,
+		pgd_t * pgd, unsigned long address,
+		unsigned long end, struct zap_details *details)
+{
+	pud_t * pud;
+
+	if (pgd_none(*pgd))
+		return;
+	if (unlikely(pgd_bad(*pgd))) {
+		pgd_ERROR(*pgd);
+		pgd_clear(pgd);
+		return;
+	}
+	pud = pud_offset(pgd, address);
+	do {
+		zap_pmd_range(tlb, pud, address, end - address, details);
+		address = (address + PUD_SIZE) & PUD_MASK; 
+		pud++;
+	} while (address && (address < end));
+}
+
 static void unmap_page_range(struct mmu_gather *tlb,
 		struct vm_area_struct *vma, unsigned long address,
 		unsigned long end, struct zap_details *details)
 {
-	pgd_t * dir;
+	unsigned long next;
+	pgd_t *pgd;
+	int i;
 
 	BUG_ON(address >= end);
-	dir = pgd_offset(vma->vm_mm, address);
+	pgd = pgd_offset(vma->vm_mm, address);
 	tlb_start_vma(tlb, vma);
-	do {
-		zap_pmd_range(tlb, dir, address, end - address, details);
-		address = (address + PGDIR_SIZE) & PGDIR_MASK;
-		dir++;
-	} while (address && (address < end));
+	for (i = pgd_index(address); i <= pgd_index(end-1); i++) {
+		next = (address + PGDIR_SIZE) & PGDIR_MASK;
+		if (next <= address || next > end)
+			next = end;
+		zap_pud_range(tlb, pgd, address, next, details);
+		address = next;
+		pgd++;
+	}
 	tlb_end_vma(tlb, vma);
 }
 
-/* Dispose of an entire struct mmu_gather per rescheduling point */
-#if defined(CONFIG_SMP) && defined(CONFIG_PREEMPT)
-#define ZAP_BLOCK_SIZE	(FREE_PTE_NR * PAGE_SIZE)
-#endif
-
-/* For UP, 256 pages at a time gives nice low latency */
-#if !defined(CONFIG_SMP) && defined(CONFIG_PREEMPT)
-#define ZAP_BLOCK_SIZE	(256 * PAGE_SIZE)
-#endif
-
+#ifdef CONFIG_PREEMPT
+# define ZAP_BLOCK_SIZE	(8 * PAGE_SIZE)
+#else
 /* No preempt: go for improved straight-line efficiency */
-#if !defined(CONFIG_PREEMPT)
-#define ZAP_BLOCK_SIZE	(1024 * PAGE_SIZE)
+# define ZAP_BLOCK_SIZE	(1024 * PAGE_SIZE)
 #endif
 
 /**
@@ -541,7 +645,8 @@
 	unsigned long tlb_start = 0;	/* For tlb_finish_mmu */
 	int tlb_start_valid = 0;
 	int ret = 0;
-	int atomic = details && details->atomic;
+	spinlock_t *i_mmap_lock = details? details->i_mmap_lock: NULL;
+	int fullmm = tlb_is_full_mm(*tlbp);
 
 	for ( ; vma && vma->vm_start < end_addr; vma = vma->vm_next) {
 		unsigned long start;
@@ -579,16 +684,29 @@
 			zap_bytes -= block;
 			if ((long)zap_bytes > 0)
 				continue;
-			if (!atomic && need_resched()) {
-				int fullmm = tlb_is_full_mm(*tlbp);
-				tlb_finish_mmu(*tlbp, tlb_start, start);
-				cond_resched_lock(&mm->page_table_lock);
-				*tlbp = tlb_gather_mmu(mm, fullmm);
-				tlb_start_valid = 0;
+
+			tlb_finish_mmu(*tlbp, tlb_start, start);
+
+			if (need_resched() ||
+				need_lockbreak(&mm->page_table_lock) ||
+				(i_mmap_lock && need_lockbreak(i_mmap_lock))) {
+				if (i_mmap_lock) {
+					/* must reset count of rss freed */
+					*tlbp = tlb_gather_mmu(mm, fullmm);
+					details->break_addr = start;
+					goto out;
+				}
+				spin_unlock(&mm->page_table_lock);
+				cond_resched();
+				spin_lock(&mm->page_table_lock);
 			}
+
+			*tlbp = tlb_gather_mmu(mm, fullmm);
+			tlb_start_valid = 0;
 			zap_bytes = ZAP_BLOCK_SIZE;
 		}
 	}
+out:
 	return ret;
 }
 
@@ -617,6 +735,7 @@
 	tlb = tlb_gather_mmu(mm, 0);
 	unmap_vmas(&tlb, mm, vma, address, end, &nr_accounted, details);
 	tlb_finish_mmu(tlb, address, end);
+	acct_update_integrals();
 	spin_unlock(&mm->page_table_lock);
 }
 
@@ -624,10 +743,11 @@
  * Do a quick page-table lookup for a single page.
  * mm->page_table_lock must be held.
  */
-struct page *
-follow_page(struct mm_struct *mm, unsigned long address, int write) 
+static struct page *
+__follow_page(struct mm_struct *mm, unsigned long address, int read, int write)
 {
 	pgd_t *pgd;
+	pud_t *pud;
 	pmd_t *pmd;
 	pte_t *ptep, pte;
 	unsigned long pfn;
@@ -641,13 +761,15 @@
 	if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd)))
 		goto out;
 
-	pmd = pmd_offset(pgd, address);
-	if (pmd_none(*pmd))
+	pud = pud_offset(pgd, address);
+	if (pud_none(*pud) || unlikely(pud_bad(*pud)))
+		goto out;
+	
+	pmd = pmd_offset(pud, address);
+	if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd)))
 		goto out;
 	if (pmd_huge(*pmd))
 		return follow_huge_pmd(mm, address, pmd, write);
-	if (unlikely(pmd_bad(*pmd)))
-		goto out;
 
 	ptep = pte_offset_map(pmd, address);
 	if (!ptep)
@@ -658,6 +780,8 @@
 	if (pte_present(pte)) {
 		if (write && !pte_write(pte))
 			goto out;
+		if (read && !pte_read(pte))
+			goto out;
 		pfn = pte_pfn(pte);
 		if (pfn_valid(pfn)) {
 			page = pfn_to_page(pfn);
@@ -672,6 +796,20 @@
 	return NULL;
 }
 
+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;
+}
+
+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
@@ -691,6 +829,7 @@
 			 unsigned long address)
 {
 	pgd_t *pgd;
+	pud_t *pud;
 	pmd_t *pmd;
 
 	/* Check if the vma is for an anonymous mapping. */
@@ -702,8 +841,12 @@
 	if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd)))
 		return 1;
 
+	pud = pud_offset(pgd, address);
+	if (pud_none(*pud) || unlikely(pud_bad(*pud)))
+		return 1;
+
 	/* Check if page middle directory entry exists. */
-	pmd = pmd_offset(pgd, address);
+	pmd = pmd_offset(pud, address);
 	if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd)))
 		return 1;
 
@@ -735,6 +878,7 @@
 			unsigned long pg = start & PAGE_MASK;
 			struct vm_area_struct *gate_vma = get_gate_vma(tsk);
 			pgd_t *pgd;
+			pud_t *pud;
 			pmd_t *pmd;
 			pte_t *pte;
 			if (write) /* user gate pages are read-only */
@@ -744,7 +888,9 @@
 			else
 				pgd = pgd_offset_gate(mm, pg);
 			BUG_ON(pgd_none(*pgd));
-			pmd = pmd_offset(pgd, pg);
+			pud = pud_offset(pgd, pg);
+			BUG_ON(pud_none(*pud));
+			pmd = pmd_offset(pud, pg);
 			BUG_ON(pmd_none(*pmd));
 			pte = pte_offset_map(pmd, pg);
 			BUG_ON(pte_none(*pte));
@@ -774,6 +920,8 @@
 		do {
 			struct page *map;
 			int lookup_write = write;
+
+			cond_resched_lock(&mm->page_table_lock);
 			while (!(map = follow_page(mm, start, lookup_write))) {
 				/*
 				 * Shortcut for anonymous pages. We don't want
@@ -857,16 +1005,16 @@
 	} while (address && (address < end));
 }
 
-static inline int zeromap_pmd_range(struct mm_struct *mm, pmd_t * pmd, unsigned long address,
-                                    unsigned long size, pgprot_t prot)
+static inline int zeromap_pmd_range(struct mm_struct *mm, pmd_t * pmd,
+		unsigned long address, unsigned long size, pgprot_t prot)
 {
 	unsigned long base, end;
 
-	base = address & PGDIR_MASK;
-	address &= ~PGDIR_MASK;
+	base = address & PUD_MASK;
+	address &= ~PUD_MASK;
 	end = address + size;
-	if (end > PGDIR_SIZE)
-		end = PGDIR_SIZE;
+	if (end > PUD_SIZE)
+		end = PUD_SIZE;
 	do {
 		pte_t * pte = pte_alloc_map(mm, pmd, base + address);
 		if (!pte)
@@ -879,31 +1027,65 @@
 	return 0;
 }
 
-int zeromap_page_range(struct vm_area_struct *vma, unsigned long address, unsigned long size, pgprot_t prot)
+static inline int zeromap_pud_range(struct mm_struct *mm, pud_t * pud,
+				    unsigned long address,
+                                    unsigned long size, pgprot_t prot)
+{
+	unsigned long base, end;
+	int error = 0;
+
+	base = address & PGDIR_MASK;
+	address &= ~PGDIR_MASK;
+	end = address + size;
+	if (end > PGDIR_SIZE)
+		end = PGDIR_SIZE;
+	do {
+		pmd_t * pmd = pmd_alloc(mm, pud, base + address);
+		error = -ENOMEM;
+		if (!pmd)
+			break;
+		error = zeromap_pmd_range(mm, pmd, base + address,
+					  end - address, prot);
+		if (error)
+			break;
+		address = (address + PUD_SIZE) & PUD_MASK;
+		pud++;
+	} while (address && (address < end));
+	return 0;
+}
+
+int zeromap_page_range(struct vm_area_struct *vma, unsigned long address,
+					unsigned long size, pgprot_t prot)
 {
+	int i;
 	int error = 0;
-	pgd_t * dir;
+	pgd_t * pgd;
 	unsigned long beg = address;
 	unsigned long end = address + size;
+	unsigned long next;
 	struct mm_struct *mm = vma->vm_mm;
 
-	dir = pgd_offset(mm, address);
+	pgd = pgd_offset(mm, address);
 	flush_cache_range(vma, beg, end);
-	if (address >= end)
-		BUG();
+	BUG_ON(address >= end);
+	BUG_ON(end > vma->vm_end);
 
 	spin_lock(&mm->page_table_lock);
-	do {
-		pmd_t *pmd = pmd_alloc(mm, dir, address);
+	for (i = pgd_index(address); i <= pgd_index(end-1); i++) {
+		pud_t *pud = pud_alloc(mm, pgd, address);
 		error = -ENOMEM;
-		if (!pmd)
+		if (!pud)
 			break;
-		error = zeromap_pmd_range(mm, pmd, address, end - address, prot);
+		next = (address + PGDIR_SIZE) & PGDIR_MASK;
+		if (next <= beg || next > end)
+			next = end;
+		error = zeromap_pud_range(mm, pud, address,
+						next - address, prot);
 		if (error)
 			break;
-		address = (address + PGDIR_SIZE) & PGDIR_MASK;
-		dir++;
-	} while (address && (address < end));
+		address = next;
+		pgd++;
+	}
 	/*
 	 * Why flush? zeromap_pte_range has a BUG_ON for !pte_none()
 	 */
@@ -917,8 +1099,9 @@
  * mappings are removed. any references to nonexistent pages results
  * in null mappings (currently treated as "copy-on-access")
  */
-static inline void remap_pte_range(pte_t * pte, unsigned long address, unsigned long size,
-	unsigned long pfn, pgprot_t prot)
+static inline void
+remap_pte_range(pte_t * pte, unsigned long address, unsigned long size,
+		unsigned long pfn, pgprot_t prot)
 {
 	unsigned long end;
 
@@ -936,22 +1119,24 @@
 	} while (address && (address < end));
 }
 
-static inline int remap_pmd_range(struct mm_struct *mm, pmd_t * pmd, unsigned long address, unsigned long size,
-	unsigned long pfn, pgprot_t prot)
+static inline int
+remap_pmd_range(struct mm_struct *mm, pmd_t * pmd, unsigned long address,
+		unsigned long size, unsigned long pfn, pgprot_t prot)
 {
 	unsigned long base, end;
 
-	base = address & PGDIR_MASK;
-	address &= ~PGDIR_MASK;
+	base = address & PUD_MASK;
+	address &= ~PUD_MASK;
 	end = address + size;
-	if (end > PGDIR_SIZE)
-		end = PGDIR_SIZE;
-	pfn -= address >> PAGE_SHIFT;
+	if (end > PUD_SIZE)
+		end = PUD_SIZE;
+	pfn -= (address >> PAGE_SHIFT);
 	do {
 		pte_t * pte = pte_alloc_map(mm, pmd, base + address);
 		if (!pte)
 			return -ENOMEM;
-		remap_pte_range(pte, base + address, end - address, pfn + (address >> PAGE_SHIFT), prot);
+		remap_pte_range(pte, base + address, end - address,
+				(address >> PAGE_SHIFT) + pfn, prot);
 		pte_unmap(pte);
 		address = (address + PMD_SIZE) & PMD_MASK;
 		pmd++;
@@ -959,20 +1144,50 @@
 	return 0;
 }
 
+static inline int remap_pud_range(struct mm_struct *mm, pud_t * pud,
+				  unsigned long address, unsigned long size,
+				  unsigned long pfn, pgprot_t prot)
+{
+	unsigned long base, end;
+	int error;
+
+	base = address & PGDIR_MASK;
+	address &= ~PGDIR_MASK;
+	end = address + size;
+	if (end > PGDIR_SIZE)
+		end = PGDIR_SIZE;
+	pfn -= address >> PAGE_SHIFT;
+	do {
+		pmd_t *pmd = pmd_alloc(mm, pud, base+address);
+		error = -ENOMEM;
+		if (!pmd)
+			break;
+		error = remap_pmd_range(mm, pmd, base + address, end - address,
+				(address >> PAGE_SHIFT) + pfn, prot);
+		if (error)
+			break;
+		address = (address + PUD_SIZE) & PUD_MASK;
+		pud++;
+	} while (address && (address < end));
+	return error;
+}
+
 /*  Note: this is only safe if the mm semaphore is held when called. */
-int remap_pfn_range(struct vm_area_struct *vma, unsigned long from, unsigned long pfn, unsigned long size, pgprot_t prot)
+int remap_pfn_range(struct vm_area_struct *vma, unsigned long from,
+		    unsigned long pfn, unsigned long size, pgprot_t prot)
 {
 	int error = 0;
-	pgd_t * dir;
+	pgd_t *pgd;
 	unsigned long beg = from;
 	unsigned long end = from + size;
+	unsigned long next;
 	struct mm_struct *mm = vma->vm_mm;
+	int i;
 
 	pfn -= from >> PAGE_SHIFT;
-	dir = pgd_offset(mm, from);
+	pgd = pgd_offset(mm, from);
 	flush_cache_range(vma, beg, end);
-	if (from >= end)
-		BUG();
+	BUG_ON(from >= end);
 
 	/*
 	 * Physically remapped pages are special. Tell the
@@ -983,25 +1198,32 @@
 	 *	this region.
 	 */
 	vma->vm_flags |= VM_IO | VM_RESERVED;
+
 	spin_lock(&mm->page_table_lock);
-	do {
-		pmd_t *pmd = pmd_alloc(mm, dir, from);
+	for (i = pgd_index(beg); i <= pgd_index(end-1); i++) {
+		pud_t *pud = pud_alloc(mm, pgd, from);
 		error = -ENOMEM;
-		if (!pmd)
+		if (!pud)
 			break;
-		error = remap_pmd_range(mm, pmd, from, end - from, pfn + (from >> PAGE_SHIFT), prot);
+		next = (from + PGDIR_SIZE) & PGDIR_MASK;
+		if (next > end || next <= from)
+			next = end;
+		error = remap_pud_range(mm, pud, from, end - from,
+					pfn + (from >> PAGE_SHIFT), prot);
 		if (error)
 			break;
-		from = (from + PGDIR_SIZE) & PGDIR_MASK;
-		dir++;
-	} while (from && (from < end));
+		from = next;
+		pgd++;
+	}
 	/*
 	 * Why flush? remap_pte_range has a BUG_ON for !pte_none()
 	 */
 	flush_tlb_range(vma, beg, end);
 	spin_unlock(&mm->page_table_lock);
+
 	return error;
 }
+
 EXPORT_SYMBOL(remap_pfn_range);
 
 /*
@@ -1098,11 +1320,16 @@
 
 	if (unlikely(anon_vma_prepare(vma)))
 		goto no_new_page;
-	new_page = alloc_page_vma(GFP_HIGHUSER, vma, address);
-	if (!new_page)
-		goto no_new_page;
-	copy_cow_page(old_page,new_page,address);
-
+	if (old_page == ZERO_PAGE(address)) {
+		new_page = alloc_zeroed_user_highpage(vma, address);
+		if (!new_page)
+			goto no_new_page;
+	} else {
+		new_page = alloc_page_vma(GFP_HIGHUSER, vma, address);
+		if (!new_page)
+			goto no_new_page;
+		copy_user_highpage(new_page, old_page, address);
+	}
 	/*
 	 * Re-check the pte - we dropped the lock
 	 */
@@ -1111,9 +1338,11 @@
 	if (likely(pte_same(*page_table, pte))) {
 		if (PageAnon(old_page))
 			mm->anon_rss--;
-		if (PageReserved(old_page))
+		if (PageReserved(old_page)) {
 			++mm->rss;
-		else
+			acct_update_integrals();
+			update_mem_hiwater();
+		} else
 			page_remove_rmap(old_page);
 		break_cow(vma, new_page, address, page_table);
 		lru_cache_add_active(new_page);
@@ -1134,17 +1363,112 @@
 }
 
 /*
- * Helper function for unmap_mapping_range().
+ * Helper functions for unmap_mapping_range().
+ *
+ * __ Notes on dropping i_mmap_lock to reduce latency while unmapping __
+ *
+ * We have to restart searching the prio_tree whenever we drop the lock,
+ * since the iterator is only valid while the lock is held, and anyway
+ * a later vma might be split and reinserted earlier while lock dropped.
+ *
+ * The list of nonlinear vmas could be handled more efficiently, using
+ * a placeholder, but handle it in the same way until a need is shown.
+ * It is important to search the prio_tree before nonlinear list: a vma
+ * may become nonlinear and be shifted from prio_tree to nonlinear list
+ * while the lock is dropped; but never shifted from list to prio_tree.
+ *
+ * In order to make forward progress despite restarting the search,
+ * vm_truncate_count is used to mark a vma as now dealt with, so we can
+ * quickly skip it next time around.  Since the prio_tree search only
+ * shows us those vmas affected by unmapping the range in question, we
+ * can't efficiently keep all vmas in step with mapping->truncate_count:
+ * so instead reset them all whenever it wraps back to 0 (then go to 1).
+ * mapping->truncate_count and vma->vm_truncate_count are protected by
+ * i_mmap_lock.
+ *
+ * In order to make forward progress despite repeatedly restarting some
+ * large vma, note the break_addr set by unmap_vmas when it breaks out:
+ * and restart from that address when we reach that vma again.  It might
+ * have been split or merged, shrunk or extended, but never shifted: so
+ * restart_addr remains valid so long as it remains in the vma's range.
+ * unmap_mapping_range forces truncate_count to leap over page-aligned
+ * values so we can save vma's restart_addr in its truncate_count field.
  */
-static inline void unmap_mapping_range_list(struct prio_tree_root *root,
+#define is_restart_addr(truncate_count) (!((truncate_count) & ~PAGE_MASK))
+
+static void reset_vma_truncate_counts(struct address_space *mapping)
+{
+	struct vm_area_struct *vma;
+	struct prio_tree_iter iter;
+
+	vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, 0, ULONG_MAX)
+		vma->vm_truncate_count = 0;
+	list_for_each_entry(vma, &mapping->i_mmap_nonlinear, shared.vm_set.list)
+		vma->vm_truncate_count = 0;
+}
+
+static int unmap_mapping_range_vma(struct vm_area_struct *vma,
+		unsigned long start_addr, unsigned long end_addr,
+		struct zap_details *details)
+{
+	unsigned long restart_addr;
+	int need_break;
+
+again:
+	restart_addr = vma->vm_truncate_count;
+	if (is_restart_addr(restart_addr) && start_addr < restart_addr) {
+		start_addr = restart_addr;
+		if (start_addr >= end_addr) {
+			/* Top of vma has been split off since last time */
+			vma->vm_truncate_count = details->truncate_count;
+			return 0;
+		}
+	}
+
+	details->break_addr = end_addr;
+	zap_page_range(vma, start_addr, end_addr - start_addr, details);
+
+	/*
+	 * We cannot rely on the break test in unmap_vmas:
+	 * on the one hand, we don't want to restart our loop
+	 * just because that broke out for the page_table_lock;
+	 * on the other hand, it does no test when vma is small.
+	 */
+	need_break = need_resched() ||
+			need_lockbreak(details->i_mmap_lock);
+
+	if (details->break_addr >= end_addr) {
+		/* We have now completed this vma: mark it so */
+		vma->vm_truncate_count = details->truncate_count;
+		if (!need_break)
+			return 0;
+	} else {
+		/* Note restart_addr in vma's truncate_count field */
+		vma->vm_truncate_count = details->break_addr;
+		if (!need_break)
+			goto again;
+	}
+
+	spin_unlock(details->i_mmap_lock);
+	cond_resched();
+	spin_lock(details->i_mmap_lock);
+	return -EINTR;
+}
+
+static inline void unmap_mapping_range_tree(struct prio_tree_root *root,
 					    struct zap_details *details)
 {
 	struct vm_area_struct *vma;
 	struct prio_tree_iter iter;
 	pgoff_t vba, vea, zba, zea;
 
+restart:
 	vma_prio_tree_foreach(vma, &iter, root,
 			details->first_index, details->last_index) {
+		/* Skip quickly over those we have already dealt with */
+		if (vma->vm_truncate_count == details->truncate_count)
+			continue;
+
 		vba = vma->vm_pgoff;
 		vea = vba + ((vma->vm_end - vma->vm_start) >> PAGE_SHIFT) - 1;
 		/* Assume for now that PAGE_CACHE_SHIFT == PAGE_SHIFT */
@@ -1154,9 +1478,35 @@
 		zea = details->last_index;
 		if (zea > vea)
 			zea = vea;
-		zap_page_range(vma,
+
+		if (unmap_mapping_range_vma(vma,
 			((zba - vba) << PAGE_SHIFT) + vma->vm_start,
-			(zea - zba + 1) << PAGE_SHIFT, details);
+			((zea - vba + 1) << PAGE_SHIFT) + vma->vm_start,
+				details) < 0)
+			goto restart;
+	}
+}
+
+static inline void unmap_mapping_range_list(struct list_head *head,
+					    struct zap_details *details)
+{
+	struct vm_area_struct *vma;
+
+	/*
+	 * In nonlinear VMAs there is no correspondence between virtual address
+	 * offset and file offset.  So we must perform an exhaustive search
+	 * across *all* the pages in each nonlinear VMA, not just the pages
+	 * whose virtual address lies outside the file truncation point.
+	 */
+restart:
+	list_for_each_entry(vma, head, shared.vm_set.list) {
+		/* Skip quickly over those we have already dealt with */
+		if (vma->vm_truncate_count == details->truncate_count)
+			continue;
+		details->nonlinear_vma = vma;
+		if (unmap_mapping_range_vma(vma, vma->vm_start,
+					vma->vm_end, details) < 0)
+			goto restart;
 	}
 }
 
@@ -1195,32 +1545,34 @@
 	details.nonlinear_vma = NULL;
 	details.first_index = hba;
 	details.last_index = hba + hlen - 1;
-	details.atomic = 1;	/* A spinlock is held */
 	if (details.last_index < details.first_index)
 		details.last_index = ULONG_MAX;
+	details.i_mmap_lock = &mapping->i_mmap_lock;
 
 	spin_lock(&mapping->i_mmap_lock);
-	/* Protect against page fault */
-	atomic_inc(&mapping->truncate_count);
-
-	if (unlikely(!prio_tree_empty(&mapping->i_mmap)))
-		unmap_mapping_range_list(&mapping->i_mmap, &details);
 
+	/* serialize i_size write against truncate_count write */
+	smp_wmb();
+	/* Protect against page faults, and endless unmapping loops */
+	mapping->truncate_count++;
 	/*
-	 * In nonlinear VMAs there is no correspondence between virtual address
-	 * offset and file offset.  So we must perform an exhaustive search
-	 * across *all* the pages in each nonlinear VMA, not just the pages
-	 * whose virtual address lies outside the file truncation point.
+	 * For archs where spin_lock has inclusive semantics like ia64
+	 * this smp_mb() will prevent to read pagetable contents
+	 * before the truncate_count increment is visible to
+	 * other cpus.
 	 */
-	if (unlikely(!list_empty(&mapping->i_mmap_nonlinear))) {
-		struct vm_area_struct *vma;
-		list_for_each_entry(vma, &mapping->i_mmap_nonlinear,
-						shared.vm_set.list) {
-			details.nonlinear_vma = vma;
-			zap_page_range(vma, vma->vm_start,
-				vma->vm_end - vma->vm_start, &details);
-		}
+	smp_mb();
+	if (unlikely(is_restart_addr(mapping->truncate_count))) {
+		if (mapping->truncate_count == 0)
+			reset_vma_truncate_counts(mapping);
+		mapping->truncate_count++;
 	}
+	details.truncate_count = mapping->truncate_count;
+
+	if (unlikely(!prio_tree_empty(&mapping->i_mmap)))
+		unmap_mapping_range_tree(&mapping->i_mmap, &details);
+	if (unlikely(!list_empty(&mapping->i_mmap_nonlinear)))
+		unmap_mapping_range_list(&mapping->i_mmap_nonlinear, &details);
 	spin_unlock(&mapping->i_mmap_lock);
 }
 EXPORT_SYMBOL(unmap_mapping_range);
@@ -1395,6 +1747,9 @@
 		remove_exclusive_swap_page(page);
 
 	mm->rss++;
+	acct_update_integrals();
+	update_mem_hiwater();
+
 	pte = mk_pte(page, vma->vm_page_prot);
 	if (write_access && can_share_swap_page(page)) {
 		pte = maybe_mkwrite(pte_mkdirty(pte), vma);
@@ -1445,10 +1800,9 @@
 
 		if (unlikely(anon_vma_prepare(vma)))
 			goto no_mem;
-		page = alloc_page_vma(GFP_HIGHUSER, vma, addr);
+		page = alloc_zeroed_user_highpage(vma, addr);
 		if (!page)
 			goto no_mem;
-		clear_user_highpage(page, addr);
 
 		spin_lock(&mm->page_table_lock);
 		page_table = pte_offset_map(pmd, addr);
@@ -1460,11 +1814,13 @@
 			goto out;
 		}
 		mm->rss++;
+		acct_update_integrals();
+		update_mem_hiwater();
 		entry = maybe_mkwrite(pte_mkdirty(mk_pte(page,
 							 vma->vm_page_prot)),
 				      vma);
 		lru_cache_add_active(page);
-		mark_page_accessed(page);
+		SetPageReferenced(page);
 		page_add_anon_rmap(page, vma, addr);
 	}
 
@@ -1499,7 +1855,7 @@
 	struct page * new_page;
 	struct address_space *mapping = NULL;
 	pte_t entry;
-	int sequence = 0;
+	unsigned int sequence = 0;
 	int ret = VM_FAULT_MINOR;
 	int anon = 0;
 
@@ -1511,11 +1867,19 @@
 
 	if (vma->vm_file) {
 		mapping = vma->vm_file->f_mapping;
-		sequence = atomic_read(&mapping->truncate_count);
+		sequence = mapping->truncate_count;
+		smp_rmb(); /* serializes i_size against truncate_count */
 	}
-	smp_rmb();  /* Prevent CPU from reordering lock-free ->nopage() */
 retry:
+	cond_resched();
 	new_page = vma->vm_ops->nopage(vma, address & PAGE_MASK, &ret);
+	/*
+	 * No smp_rmb is needed here as long as there's a full
+	 * spin_lock/unlock sequence inside the ->nopage callback
+	 * (for the pagecache lookup) that acts as an implicit
+	 * smp_mb() and prevents the i_size read to happen
+	 * after the next truncate_count read.
+	 */
 
 	/* no page was available -- either SIGBUS or OOM */
 	if (new_page == NOPAGE_SIGBUS)
@@ -1546,9 +1910,8 @@
 	 * invalidated this page.  If unmap_mapping_range got called,
 	 * retry getting the page.
 	 */
-	if (mapping &&
-	      (unlikely(sequence != atomic_read(&mapping->truncate_count)))) {
-		sequence = atomic_read(&mapping->truncate_count);
+	if (mapping && unlikely(sequence != mapping->truncate_count)) {
+		sequence = mapping->truncate_count;
 		spin_unlock(&mm->page_table_lock);
 		page_cache_release(new_page);
 		goto retry;
@@ -1569,6 +1932,9 @@
 	if (pte_none(*page_table)) {
 		if (!PageReserved(new_page))
 			++mm->rss;
+		acct_update_integrals();
+		update_mem_hiwater();
+
 		flush_icache_page(vma, new_page);
 		entry = mk_pte(new_page, vma->vm_page_prot);
 		if (write_access)
@@ -1693,13 +2059,14 @@
  * 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,
-	unsigned long address, int write_access)
+		unsigned long address, int write_access)
 {
 	pgd_t *pgd;
+	pud_t *pud;
 	pmd_t *pmd;
+	pte_t *pte;
 
 	__set_current_state(TASK_RUNNING);
-	pgd = pgd_offset(mm, address);
 
 	inc_page_state(pgfault);
 
@@ -1710,18 +2077,61 @@
 	 * We need the page table lock to synchronize with kswapd
 	 * and the SMP-safe atomic PTE updates.
 	 */
+	pgd = pgd_offset(mm, address);
 	spin_lock(&mm->page_table_lock);
-	pmd = pmd_alloc(mm, pgd, address);
 
-	if (pmd) {
-		pte_t * pte = pte_alloc_map(mm, pmd, address);
-		if (pte)
-			return handle_pte_fault(mm, vma, address, write_access, pte, pmd);
-	}
+	pud = pud_alloc(mm, pgd, address);
+	if (!pud)
+		goto oom;
+
+	pmd = pmd_alloc(mm, pud, address);
+	if (!pmd)
+		goto oom;
+
+	pte = pte_alloc_map(mm, pmd, address);
+	if (!pte)
+		goto oom;
+	
+	return handle_pte_fault(mm, vma, address, write_access, pte, pmd);
+
+ oom:
 	spin_unlock(&mm->page_table_lock);
 	return VM_FAULT_OOM;
 }
 
+#ifndef __ARCH_HAS_4LEVEL_HACK
+/*
+ * Allocate page upper directory.
+ *
+ * We've already handled the fast-path in-line, and we own the
+ * page table lock.
+ *
+ * On a two-level or three-level page table, this ends up actually being
+ * entirely optimized away.
+ */
+pud_t fastcall *__pud_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address)
+{
+	pud_t *new;
+
+	spin_unlock(&mm->page_table_lock);
+	new = pud_alloc_one(mm, address);
+	spin_lock(&mm->page_table_lock);
+	if (!new)
+		return NULL;
+
+	/*
+	 * Because we dropped the lock, we should re-check the
+	 * entry, as somebody else could have populated it..
+	 */
+	if (pgd_present(*pgd)) {
+		pud_free(new);
+		goto out;
+	}
+	pgd_populate(mm, pgd, new);
+ out:
+	return pud_offset(pgd, address);
+}
+
 /*
  * Allocate page middle directory.
  *
@@ -1731,7 +2141,7 @@
  * On a two-level page table, this ends up actually being entirely
  * optimized away.
  */
-pmd_t fastcall *__pmd_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address)
+pmd_t fastcall *__pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address)
 {
 	pmd_t *new;
 
@@ -1745,14 +2155,38 @@
 	 * Because we dropped the lock, we should re-check the
 	 * entry, as somebody else could have populated it..
 	 */
-	if (pgd_present(*pgd)) {
+	if (pud_present(*pud)) {
 		pmd_free(new);
 		goto out;
 	}
-	pgd_populate(mm, pgd, new);
+	pud_populate(mm, pud, new);
+ out:
+	return pmd_offset(pud, address);
+}
+#else
+pmd_t fastcall *__pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address)
+{
+	pmd_t *new;
+
+	spin_unlock(&mm->page_table_lock);
+	new = pmd_alloc_one(mm, address);
+	spin_lock(&mm->page_table_lock);
+	if (!new)
+		return NULL;
+
+	/*
+	 * Because we dropped the lock, we should re-check the
+	 * entry, as somebody else could have populated it..
+	 */
+	if (pgd_present(*pud)) {
+		pmd_free(new);
+		goto out;
+	}
+	pgd_populate(mm, pud, new);
 out:
-	return pmd_offset(pgd, address);
+	return pmd_offset(pud, address);
 }
+#endif
 
 int make_pages_present(unsigned long addr, unsigned long end)
 {
@@ -1783,17 +2217,21 @@
 	unsigned long addr = (unsigned long) vmalloc_addr;
 	struct page *page = NULL;
 	pgd_t *pgd = pgd_offset_k(addr);
+	pud_t *pud;
 	pmd_t *pmd;
 	pte_t *ptep, pte;
   
 	if (!pgd_none(*pgd)) {
-		pmd = pmd_offset(pgd, addr);
-		if (!pmd_none(*pmd)) {
-			ptep = pte_offset_map(pmd, addr);
-			pte = *ptep;
-			if (pte_present(pte))
-				page = pte_page(pte);
-			pte_unmap(ptep);
+		pud = pud_offset(pgd, addr);
+		if (!pud_none(*pud)) {
+			pmd = pmd_offset(pud, addr);
+			if (!pmd_none(*pmd)) {
+				ptep = pte_offset_map(pmd, addr);
+				pte = *ptep;
+				if (pte_present(pte))
+					page = pte_page(pte);
+				pte_unmap(ptep);
+			}
 		}
 	}
 	return page;
@@ -1811,7 +2249,23 @@
 
 EXPORT_SYMBOL(vmalloc_to_pfn);
 
-#if !defined(CONFIG_ARCH_GATE_AREA)
+/*
+ * update_mem_hiwater
+ *	- update per process rss and vm high water data
+ */
+void update_mem_hiwater(void)
+{
+	struct task_struct *tsk = current;
+
+	if (tsk->mm) {
+		if (tsk->mm->hiwater_rss < tsk->mm->rss)
+			tsk->mm->hiwater_rss = tsk->mm->rss;
+		if (tsk->mm->hiwater_vm < tsk->mm->total_vm)
+			tsk->mm->hiwater_vm = tsk->mm->total_vm;
+	}
+}
+
+#if !defined(__HAVE_ARCH_GATE_AREA)
 
 #if defined(AT_SYSINFO_EHDR)
 struct vm_area_struct gate_vma;
@@ -1837,7 +2291,7 @@
 #endif
 }
 
-int in_gate_area(struct task_struct *task, unsigned long addr)
+int in_gate_area_no_task(unsigned long addr)
 {
 #ifdef AT_SYSINFO_EHDR
 	if ((addr >= FIXADDR_USER_START) && (addr < FIXADDR_USER_END))
@@ -1846,4 +2300,4 @@
 	return 0;
 }
 
-#endif
+#endif	/* __HAVE_ARCH_GATE_AREA */
diff -Nru a/mm/mempolicy.c b/mm/mempolicy.c
--- a/mm/mempolicy.c	2005-03-01 23:39:17 -08:00
+++ b/mm/mempolicy.c	2005-03-01 23:39:17 -08:00
@@ -234,18 +234,29 @@
 
 /* Ensure all existing pages follow the policy. */
 static int
-verify_pages(unsigned long addr, unsigned long end, unsigned long *nodes)
+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;
-		pgd_t *pgd = pgd_offset_k(addr);
+		pud_t *pud;
+		pgd_t *pgd;
+		pgd = pgd_offset(mm, addr);
 		if (pgd_none(*pgd)) {
-			addr = (addr + PGDIR_SIZE) & PGDIR_MASK;
+			unsigned long next = (addr + PGDIR_SIZE) & PGDIR_MASK;
+			if (next > addr)
+				break;
+			addr = next;
+			continue;
+		}
+		pud = pud_offset(pgd, addr);
+		if (pud_none(*pud)) {
+			addr = (addr + PUD_SIZE) & PUD_MASK;
 			continue;
 		}
-		pmd = pmd_offset(pgd, addr);
+		pmd = pmd_offset(pud, addr);
 		if (pmd_none(*pmd)) {
 			addr = (addr + PMD_SIZE) & PMD_MASK;
 			continue;
@@ -283,7 +294,8 @@
 		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_start, vma->vm_end, nodes);
+			err = verify_pages(vma->vm_mm,
+					   vma->vm_start, vma->vm_end, nodes);
 			if (err) {
 				first = ERR_PTR(err);
 				break;
@@ -477,7 +489,7 @@
 
 	if (flags & ~(unsigned long)(MPOL_F_NODE|MPOL_F_ADDR))
 		return -EINVAL;
-	if (nmask != NULL && maxnode < numnodes)
+	if (nmask != NULL && maxnode < MAX_NUMNODES)
 		return -EINVAL;
 	if (flags & MPOL_F_ADDR) {
 		down_read(&mm->mmap_sem);
@@ -512,9 +524,13 @@
 	} else
 		pval = pol->policy;
 
-	err = -EFAULT;
+	if (vma) {
+		up_read(&current->mm->mmap_sem);
+		vma = NULL;
+	}
+
 	if (policy && put_user(pval, policy))
-		goto out;
+		return -EFAULT;
 
 	err = 0;
 	if (nmask) {
@@ -1016,12 +1032,11 @@
 						return -ENOMEM;
 					goto restart;
 				}
-				n->end = end;
+				n->end = start;
 				sp_insert(sp, new2);
 				new2 = NULL;
-			}
-			/* Old crossing beginning, but not end (easy) */
-			if (n->start < start && n->end > start)
+				break;
+			} else
 				n->end = start;
 		}
 		if (!next)
@@ -1074,11 +1089,11 @@
 	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 -Nru a/mm/mincore.c b/mm/mincore.c
--- a/mm/mincore.c	2005-03-01 23:39:17 -08:00
+++ b/mm/mincore.c	2005-03-01 23:39:17 -08:00
@@ -109,39 +109,45 @@
 	unsigned char __user * vec)
 {
 	int index = 0;
-	unsigned long end;
+	unsigned long end, limit;
 	struct vm_area_struct * vma;
+	size_t max;
 	int unmapped_error = 0;
-	long error = -EINVAL;
+	long error;
 
-	down_read(&current->mm->mmap_sem);
+	/* check the arguments */
+ 	if (start & ~PAGE_CACHE_MASK)
+		goto einval;
+
+	if (start < FIRST_USER_PGD_NR * PGDIR_SIZE)
+		goto enomem;
+
+	limit = TASK_SIZE;
+	if (start >= limit)
+		goto enomem;
+
+	max = limit - start;
+	len = PAGE_CACHE_ALIGN(len);
+	if (len > max)
+		goto einval;
 
-	if (start & ~PAGE_CACHE_MASK)
-		goto out;
-	len = (len + ~PAGE_CACHE_MASK) & PAGE_CACHE_MASK;
 	end = start + len;
-	if (end < start)
-		goto out;
 
+	/* check the output buffer whilst holding the lock */
 	error = -EFAULT;
-	if (!access_ok(VERIFY_WRITE, vec, len >> PAGE_SHIFT))
-		goto out;
+	down_read(&current->mm->mmap_sem);
 
-	error = 0;
-	if (end == start)
+	if (!access_ok(VERIFY_WRITE, vec, len >> PAGE_SHIFT))
 		goto out;
 
 	/*
 	 * If the interval [start,end) covers some unmapped address
 	 * ranges, just ignore them, but return -ENOMEM at the end.
 	 */
-	vma = find_vma(current->mm, start);
-	for (;;) {
-		/* Still start < end. */
-		error = -ENOMEM;
-		if (!vma)
-			goto out;
+	error = 0;
 
+	vma = find_vma(current->mm, start);
+	while (vma) {
 		/* Here start < vma->vm_end. */
 		if (start < vma->vm_start) {
 			unmapped_error = -ENOMEM;
@@ -169,7 +175,15 @@
 		vma = vma->vm_next;
 	}
 
+	/* we found a hole in the area queried if we arrive here */
+	error = -ENOMEM;
+
 out:
 	up_read(&current->mm->mmap_sem);
 	return error;
+
+einval:
+	return -EINVAL;
+enomem:
+	return -ENOMEM;
 }
diff -Nru a/mm/mlock.c b/mm/mlock.c
--- a/mm/mlock.c	2005-03-01 23:38:52 -08:00
+++ b/mm/mlock.c	2005-03-01 23:38:52 -08:00
@@ -21,17 +21,15 @@
 		goto out;
 
 	if (start != vma->vm_start) {
-		if (split_vma(mm, vma, start, 1)) {
-			ret = -EAGAIN;
+		ret = split_vma(mm, vma, start, 1);
+		if (ret)
 			goto out;
-		}
 	}
 
 	if (end != vma->vm_end) {
-		if (split_vma(mm, vma, end, 0)) {
-			ret = -EAGAIN;
+		ret = split_vma(mm, vma, end, 0);
+		if (ret)
 			goto out;
-		}
 	}
 
 	/*
@@ -53,6 +51,8 @@
 
 	vma->vm_mm->locked_vm -= pages;
 out:
+	if (ret == -ENOMEM)
+		ret = -EAGAIN;
 	return ret;
 }
 
@@ -204,7 +204,7 @@
  * Objects with different lifetime than processes (SHM_LOCK and SHM_HUGETLB
  * shm segments) get accounted against the user_struct instead.
  */
-static spinlock_t shmlock_user_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(shmlock_user_lock);
 
 int user_shm_lock(size_t size, struct user_struct *user)
 {
diff -Nru a/mm/mmap.c b/mm/mmap.c
--- a/mm/mmap.c	2005-03-01 23:39:07 -08:00
+++ b/mm/mmap.c	2005-03-01 23:39:07 -08:00
@@ -7,6 +7,7 @@
  */
 
 #include <linux/slab.h>
+#include <linux/mm.h>
 #include <linux/shm.h>
 #include <linux/mman.h>
 #include <linux/pagemap.h>
@@ -20,6 +21,7 @@
 #include <linux/hugetlb.h>
 #include <linux/profile.h>
 #include <linux/module.h>
+#include <linux/acct.h>
 #include <linux/mount.h>
 #include <linux/mempolicy.h>
 #include <linux/rmap.h>
@@ -59,10 +61,98 @@
 int sysctl_max_map_count = DEFAULT_MAX_MAP_COUNT;
 atomic_t vm_committed_space = ATOMIC_INIT(0);
 
+/*
+ * Check that a process has enough memory to allocate a new virtual
+ * mapping. 0 means there is enough memory for the allocation to
+ * succeed and -ENOMEM implies there is not.
+ *
+ * We currently support three overcommit policies, which are set via the
+ * vm.overcommit_memory sysctl.  See Documentation/vm/overcommit-accounting
+ *
+ * Strict overcommit modes added 2002 Feb 26 by Alan Cox.
+ * Additional code 2002 Jul 20 by Robert Love.
+ *
+ * cap_sys_admin is 1 if the process has admin privileges, 0 otherwise.
+ *
+ * Note this is a helper function intended to be used by LSMs which
+ * wish to use this logic.
+ */
+int __vm_enough_memory(long pages, int cap_sys_admin)
+{
+	unsigned long free, allowed;
+
+	vm_acct_memory(pages);
+
+	/*
+	 * Sometimes we want to use more memory than we have
+	 */
+	if (sysctl_overcommit_memory == OVERCOMMIT_ALWAYS)
+		return 0;
+
+	if (sysctl_overcommit_memory == OVERCOMMIT_GUESS) {
+		unsigned long n;
+
+		free = get_page_cache_size();
+		free += nr_swap_pages;
+
+		/*
+		 * Any slabs which are created with the
+		 * SLAB_RECLAIM_ACCOUNT flag claim to have contents
+		 * which are reclaimable, under pressure.  The dentry
+		 * cache and most inode caches should fall into this
+		 */
+		free += atomic_read(&slab_reclaim_pages);
+
+		/*
+		 * Leave the last 3% for root
+		 */
+		if (!cap_sys_admin)
+			free -= free / 32;
+
+		if (free > pages)
+			return 0;
+
+		/*
+		 * nr_free_pages() is very expensive on large systems,
+		 * only call if we're about to fail.
+		 */
+		n = nr_free_pages();
+		if (!cap_sys_admin)
+			n -= n / 32;
+		free += n;
+
+		if (free > pages)
+			return 0;
+		vm_unacct_memory(pages);
+		return -ENOMEM;
+	}
+
+	allowed = (totalram_pages - hugetlb_total_pages())
+	       	* sysctl_overcommit_ratio / 100;
+	/*
+	 * Leave the last 3% for root
+	 */
+	if (!cap_sys_admin)
+		allowed -= allowed / 32;
+	allowed += total_swap_pages;
+
+	/* Don't let a single process grow too big:
+	   leave 3% of the size of this process for other processes */
+	allowed -= current->mm->total_vm / 32;
+
+	if (atomic_read(&vm_committed_space) < allowed)
+		return 0;
+
+	vm_unacct_memory(pages);
+
+	return -ENOMEM;
+}
+
 EXPORT_SYMBOL(sysctl_overcommit_memory);
 EXPORT_SYMBOL(sysctl_overcommit_ratio);
 EXPORT_SYMBOL(sysctl_max_map_count);
 EXPORT_SYMBOL(vm_committed_space);
+EXPORT_SYMBOL(__vm_enough_memory);
 
 /*
  * Requires inode->i_mapping->i_mmap_lock
@@ -306,8 +396,10 @@
 	if (vma->vm_file)
 		mapping = vma->vm_file->f_mapping;
 
-	if (mapping)
+	if (mapping) {
 		spin_lock(&mapping->i_mmap_lock);
+		vma->vm_truncate_count = mapping->truncate_count;
+	}
 	anon_vma_lock(vma);
 
 	__vma_link(mm, vma, prev, rb_link, rb_parent);
@@ -378,6 +470,7 @@
 again:			remove_next = 1 + (end > next->vm_end);
 			end = next->vm_end;
 			anon_vma = next->anon_vma;
+			importer = vma;
 		} else if (end > next->vm_start) {
 			/*
 			 * vma expands, overlapping part of the next:
@@ -403,7 +496,16 @@
 		if (!(vma->vm_flags & VM_NONLINEAR))
 			root = &mapping->i_mmap;
 		spin_lock(&mapping->i_mmap_lock);
+		if (importer &&
+		    vma->vm_truncate_count != next->vm_truncate_count) {
+			/*
+			 * unmap_mapping_range might be in progress:
+			 * ensure that the expanding vma is rescanned.
+			 */
+			importer->vm_truncate_count = 0;
+		}
 		if (insert) {
+			insert->vm_truncate_count = vma->vm_truncate_count;
 			/*
 			 * Put into prio_tree now, so instantiated pages
 			 * are visible to arm/parisc __flush_dcache_page
@@ -1019,6 +1121,8 @@
 					pgoff, flags & MAP_NONBLOCK);
 		down_write(&mm->mmap_sem);
 	}
+	acct_update_integrals();
+	update_mem_hiwater();
 	return addr;
 
 unmap_and_free_vma:
@@ -1319,13 +1423,58 @@
 	return prev ? prev->vm_next : vma;
 }
 
+/*
+ * Verify that the stack growth is acceptable and
+ * update accounting. This is shared with both the
+ * grow-up and grow-down cases.
+ */
+static int acct_stack_growth(struct vm_area_struct * vma, unsigned long size, unsigned long grow)
+{
+	struct mm_struct *mm = vma->vm_mm;
+	struct rlimit *rlim = current->signal->rlim;
+
+	/* address space limit tests */
+	if (mm->total_vm + grow > rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT)
+		return -ENOMEM;
+
+	/* Stack limit test */
+	if (size > rlim[RLIMIT_STACK].rlim_cur)
+		return -ENOMEM;
+
+	/* mlock limit tests */
+	if (vma->vm_flags & VM_LOCKED) {
+		unsigned long locked;
+		unsigned long limit;
+		locked = mm->locked_vm + grow;
+		limit = rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT;
+		if (locked > limit && !capable(CAP_IPC_LOCK))
+			return -ENOMEM;
+	}
+
+	/*
+	 * Overcommit..  This must be the final test, as it will
+	 * update security statistics.
+	 */
+	if (security_vm_enough_memory(grow))
+		return -ENOMEM;
+
+	/* Ok, everything looks good - let it rip */
+	mm->total_vm += grow;
+	if (vma->vm_flags & VM_LOCKED)
+		mm->locked_vm += grow;
+	__vm_stat_account(mm, vma->vm_flags, vma->vm_file, grow);
+	acct_update_integrals();
+	update_mem_hiwater();
+	return 0;
+}
+
 #ifdef CONFIG_STACK_GROWSUP
 /*
  * vma is the first one with address > vma->vm_end.  Have to extend vma.
  */
 int expand_stack(struct vm_area_struct * vma, unsigned long address)
 {
-	unsigned long grow;
+	int error;
 
 	if (!(vma->vm_flags & VM_GROWSUP))
 		return -EFAULT;
@@ -1345,28 +1494,21 @@
 	 */
 	address += 4 + PAGE_SIZE - 1;
 	address &= PAGE_MASK;
-	grow = (address - vma->vm_end) >> PAGE_SHIFT;
+	error = 0;
 
-	/* Overcommit.. */
-	if (security_vm_enough_memory(grow)) {
-		anon_vma_unlock(vma);
-		return -ENOMEM;
-	}
-	
-	if (address - vma->vm_start > current->signal->rlim[RLIMIT_STACK].rlim_cur ||
-			((vma->vm_mm->total_vm + grow) << PAGE_SHIFT) >
-			current->signal->rlim[RLIMIT_AS].rlim_cur) {
-		anon_vma_unlock(vma);
-		vm_unacct_memory(grow);
-		return -ENOMEM;
+	/* Somebody else might have raced and expanded it already */
+	if (address > vma->vm_end) {
+		unsigned long size, grow;
+
+		size = address - vma->vm_start;
+		grow = (address - vma->vm_end) >> PAGE_SHIFT;
+
+		error = acct_stack_growth(vma, size, grow);
+		if (!error)
+			vma->vm_end = address;
 	}
-	vma->vm_end = address;
-	vma->vm_mm->total_vm += grow;
-	if (vma->vm_flags & VM_LOCKED)
-		vma->vm_mm->locked_vm += grow;
-	__vm_stat_account(vma->vm_mm, vma->vm_flags, vma->vm_file, grow);
 	anon_vma_unlock(vma);
-	return 0;
+	return error;
 }
 
 struct vm_area_struct *
@@ -1391,7 +1533,7 @@
  */
 int expand_stack(struct vm_area_struct *vma, unsigned long address)
 {
-	unsigned long grow;
+	int error;
 
 	/*
 	 * We must make sure the anon_vma is allocated
@@ -1407,29 +1549,23 @@
 	 * anon_vma lock to serialize against concurrent expand_stacks.
 	 */
 	address &= PAGE_MASK;
-	grow = (vma->vm_start - address) >> PAGE_SHIFT;
+	error = 0;
 
-	/* Overcommit.. */
-	if (security_vm_enough_memory(grow)) {
-		anon_vma_unlock(vma);
-		return -ENOMEM;
-	}
-	
-	if (vma->vm_end - address > current->signal->rlim[RLIMIT_STACK].rlim_cur ||
-			((vma->vm_mm->total_vm + grow) << PAGE_SHIFT) >
-			current->signal->rlim[RLIMIT_AS].rlim_cur) {
-		anon_vma_unlock(vma);
-		vm_unacct_memory(grow);
-		return -ENOMEM;
+	/* Somebody else might have raced and expanded it already */
+	if (address < vma->vm_start) {
+		unsigned long size, grow;
+
+		size = vma->vm_end - address;
+		grow = (vma->vm_start - address) >> PAGE_SHIFT;
+
+		error = acct_stack_growth(vma, size, grow);
+		if (!error) {
+			vma->vm_start = address;
+			vma->vm_pgoff -= grow;
+		}
 	}
-	vma->vm_start = address;
-	vma->vm_pgoff -= grow;
-	vma->vm_mm->total_vm += grow;
-	if (vma->vm_flags & VM_LOCKED)
-		vma->vm_mm->locked_vm += grow;
-	__vm_stat_account(vma->vm_mm, vma->vm_flags, vma->vm_file, grow);
 	anon_vma_unlock(vma);
-	return 0;
+	return error;
 }
 
 struct vm_area_struct *
@@ -1474,9 +1610,11 @@
 {
 	unsigned long first = start & PGDIR_MASK;
 	unsigned long last = end + PGDIR_SIZE - 1;
-	unsigned long start_index, end_index;
 	struct mm_struct *mm = tlb->mm;
 
+	if (last > MM_VM_SIZE(mm) || last < end)
+		last = MM_VM_SIZE(mm);
+
 	if (!prev) {
 		prev = mm->mmap;
 		if (!prev)
@@ -1499,23 +1637,18 @@
 				last = next->vm_start;
 		}
 		if (prev->vm_end > first)
-			first = prev->vm_end + PGDIR_SIZE - 1;
+			first = prev->vm_end;
 		break;
 	}
 no_mmaps:
 	if (last < first)	/* for arches with discontiguous pgd indices */
 		return;
-	/*
-	 * If the PGD bits are not consecutive in the virtual address, the
-	 * old method of shifting the VA >> by PGDIR_SHIFT doesn't work.
-	 */
-	start_index = pgd_index(first);
-	if (start_index < FIRST_USER_PGD_NR)
-		start_index = FIRST_USER_PGD_NR;
-	end_index = pgd_index(last);
-	if (end_index > start_index) {
-		clear_page_tables(tlb, start_index, end_index - start_index);
-		flush_tlb_pgtables(mm, first & PGDIR_MASK, last & PGDIR_MASK);
+	if (first < FIRST_USER_PGD_NR * PGDIR_SIZE)
+		first = FIRST_USER_PGD_NR * PGDIR_SIZE;
+	/* No point trying to free anything if we're in the same pte page */
+	if ((first & PMD_MASK) < (last & PMD_MASK)) {
+		clear_page_range(tlb, first, last);
+		flush_tlb_pgtables(mm, first, last);
 	}
 }
 
@@ -1614,6 +1747,9 @@
 	struct mempolicy *pol;
 	struct vm_area_struct *new;
 
+	if (is_vm_hugetlb_page(vma) && (addr & ~HPAGE_MASK))
+		return -EINVAL;
+
 	if (mm->map_count >= sysctl_max_map_count)
 		return -ENOMEM;
 
@@ -1675,13 +1811,6 @@
 		return 0;
 	/* we have  start < mpnt->vm_end  */
 
-	if (is_vm_hugetlb_page(mpnt)) {
-		int ret = is_aligned_hugepage_range(start, len);
-
-		if (ret)
-			return ret;
-	}
-
 	/* if it doesn't overlap, we have nothing.. */
 	end = start + len;
 	if (mpnt->vm_start >= end)
@@ -1695,16 +1824,18 @@
 	 * places tmp vma above, and higher split_vma places tmp vma below.
 	 */
 	if (start > mpnt->vm_start) {
-		if (split_vma(mm, mpnt, start, 0))
-			return -ENOMEM;
+		int error = split_vma(mm, mpnt, start, 0);
+		if (error)
+			return error;
 		prev = mpnt;
 	}
 
 	/* Does it split the last one? */
 	last = find_vma(mm, end);
 	if (last && end > last->vm_start) {
-		if (split_vma(mm, last, end, 1))
-			return -ENOMEM;
+		int error = split_vma(mm, last, end, 1);
+		if (error)
+			return error;
 	}
 	mpnt = prev? prev->vm_next: mm->mmap;
 
@@ -1737,6 +1868,16 @@
 	return ret;
 }
 
+static inline void verify_mm_writelocked(struct mm_struct *mm)
+{
+#ifdef CONFIG_DEBUG_KERNEL
+	if (unlikely(down_read_trylock(&mm->mmap_sem))) {
+		WARN_ON(1);
+		up_read(&mm->mmap_sem);
+	}
+#endif
+}
+
 /*
  *  this is really a simplified "do_mmap".  it only handles
  *  anonymous maps.  eventually we may be able to do some
@@ -1770,6 +1911,12 @@
 	}
 
 	/*
+	 * mm->mmap_sem is required to protect against another thread
+	 * changing the mappings in case we sleep.
+	 */
+	verify_mm_writelocked(mm);
+
+	/*
 	 * Clear old maps.  this also does some error checking for us
 	 */
  munmap_back:
@@ -1821,6 +1968,8 @@
 		mm->locked_vm += len >> PAGE_SHIFT;
 		make_pages_present(addr, addr + len);
 	}
+	acct_update_integrals();
+	update_mem_hiwater();
 	return addr;
 }
 
@@ -1844,7 +1993,8 @@
 					~0UL, &nr_accounted, NULL);
 	vm_unacct_memory(nr_accounted);
 	BUG_ON(mm->map_count);	/* This is just debugging */
-	clear_page_tables(tlb, FIRST_USER_PGD_NR, USER_PTRS_PER_PGD);
+	clear_page_range(tlb, FIRST_USER_PGD_NR * PGDIR_SIZE, MM_VM_SIZE(mm));
+	
 	tlb_finish_mmu(tlb, 0, MM_VM_SIZE(mm));
 
 	vma = mm->mmap;
diff -Nru a/mm/mprotect.c b/mm/mprotect.c
--- a/mm/mprotect.c	2005-03-01 23:39:18 -08:00
+++ b/mm/mprotect.c	2005-03-01 23:39:18 -08:00
@@ -62,12 +62,38 @@
 }
 
 static inline void
-change_pmd_range(pgd_t *pgd, unsigned long address,
+change_pmd_range(pud_t *pud, unsigned long address,
 		unsigned long size, pgprot_t newprot)
 {
 	pmd_t * pmd;
 	unsigned long end;
 
+	if (pud_none(*pud))
+		return;
+	if (pud_bad(*pud)) {
+		pud_ERROR(*pud);
+		pud_clear(pud);
+		return;
+	}
+	pmd = pmd_offset(pud, address);
+	address &= ~PUD_MASK;
+	end = address + size;
+	if (end > PUD_SIZE)
+		end = PUD_SIZE;
+	do {
+		change_pte_range(pmd, address, end - address, newprot);
+		address = (address + PMD_SIZE) & PMD_MASK;
+		pmd++;
+	} while (address && (address < end));
+}
+
+static inline void
+change_pud_range(pgd_t *pgd, unsigned long address,
+		unsigned long size, pgprot_t newprot)
+{
+	pud_t * pud;
+	unsigned long end;
+
 	if (pgd_none(*pgd))
 		return;
 	if (pgd_bad(*pgd)) {
@@ -75,15 +101,15 @@
 		pgd_clear(pgd);
 		return;
 	}
-	pmd = pmd_offset(pgd, address);
+	pud = pud_offset(pgd, address);
 	address &= ~PGDIR_MASK;
 	end = address + size;
 	if (end > PGDIR_SIZE)
 		end = PGDIR_SIZE;
 	do {
-		change_pte_range(pmd, address, end - address, newprot);
-		address = (address + PMD_SIZE) & PMD_MASK;
-		pmd++;
+		change_pmd_range(pud, address, end - address, newprot);
+		address = (address + PUD_SIZE) & PUD_MASK;
+		pud++;
 	} while (address && (address < end));
 }
 
@@ -91,22 +117,25 @@
 change_protection(struct vm_area_struct *vma, unsigned long start,
 		unsigned long end, pgprot_t newprot)
 {
-	pgd_t *dir;
-	unsigned long beg = start;
+	struct mm_struct *mm = current->mm;
+	pgd_t *pgd;
+	unsigned long beg = start, next;
+	int i;
 
-	dir = pgd_offset(current->mm, start);
+	pgd = pgd_offset(mm, start);
 	flush_cache_range(vma, beg, end);
-	if (start >= end)
-		BUG();
-	spin_lock(&current->mm->page_table_lock);
-	do {
-		change_pmd_range(dir, start, end - start, newprot);
-		start = (start + PGDIR_SIZE) & PGDIR_MASK;
-		dir++;
-	} while (start && (start < end));
+	BUG_ON(start >= end);
+	spin_lock(&mm->page_table_lock);
+	for (i = pgd_index(start); i <= pgd_index(end-1); i++) {
+		next = (start + PGDIR_SIZE) & PGDIR_MASK;
+		if (next <= start || next > end)
+			next = end;
+		change_pud_range(pgd, start, next - start, newprot);
+		start = next;
+		pgd++;
+	}
 	flush_tlb_range(vma, beg, end);
-	spin_unlock(&current->mm->page_table_lock);
-	return;
+	spin_unlock(&mm->page_table_lock);
 }
 
 static int
diff -Nru a/mm/mremap.c b/mm/mremap.c
--- a/mm/mremap.c	2005-03-01 23:38:58 -08:00
+++ b/mm/mremap.c	2005-03-01 23:38:58 -08:00
@@ -16,6 +16,7 @@
 #include <linux/fs.h>
 #include <linux/highmem.h>
 #include <linux/security.h>
+#include <linux/acct.h>
 #include <linux/syscalls.h>
 
 #include <asm/uaccess.h>
@@ -25,19 +26,24 @@
 static pte_t *get_one_pte_map_nested(struct mm_struct *mm, unsigned long addr)
 {
 	pgd_t *pgd;
+	pud_t *pud;
 	pmd_t *pmd;
 	pte_t *pte = NULL;
 
 	pgd = pgd_offset(mm, addr);
 	if (pgd_none(*pgd))
 		goto end;
-	if (pgd_bad(*pgd)) {
-		pgd_ERROR(*pgd);
-		pgd_clear(pgd);
+
+	pud = pud_offset(pgd, addr);
+	if (pud_none(*pud))
+		goto end;
+	if (pud_bad(*pud)) {
+		pud_ERROR(*pud);
+		pud_clear(pud);
 		goto end;
 	}
 
-	pmd = pmd_offset(pgd, addr);
+	pmd = pmd_offset(pud, addr);
 	if (pmd_none(*pmd))
 		goto end;
 	if (pmd_bad(*pmd)) {
@@ -58,12 +64,17 @@
 static pte_t *get_one_pte_map(struct mm_struct *mm, unsigned long addr)
 {
 	pgd_t *pgd;
+	pud_t *pud;
 	pmd_t *pmd;
 
 	pgd = pgd_offset(mm, addr);
 	if (pgd_none(*pgd))
 		return NULL;
-	pmd = pmd_offset(pgd, addr);
+
+	pud = pud_offset(pgd, addr);
+	if (pud_none(*pud))
+		return NULL;
+	pmd = pmd_offset(pud, addr);
 	if (!pmd_present(*pmd))
 		return NULL;
 	return pte_offset_map(pmd, addr);
@@ -71,10 +82,17 @@
 
 static inline pte_t *alloc_one_pte_map(struct mm_struct *mm, unsigned long addr)
 {
+	pgd_t *pgd;
+	pud_t *pud;
 	pmd_t *pmd;
 	pte_t *pte = NULL;
 
-	pmd = pmd_alloc(mm, pgd_offset(mm, addr), addr);
+	pgd = pgd_offset(mm, addr);
+
+	pud = pud_alloc(mm, pgd, addr);
+	if (!pud)
+		return NULL;
+	pmd = pmd_alloc(mm, pud, addr);
 	if (pmd)
 		pte = pte_alloc_map(mm, pmd, addr);
 	return pte;
@@ -82,7 +100,7 @@
 
 static int
 move_one_page(struct vm_area_struct *vma, unsigned long old_addr,
-		unsigned long new_addr)
+		struct vm_area_struct *new_vma, unsigned long new_addr)
 {
 	struct address_space *mapping = NULL;
 	struct mm_struct *mm = vma->vm_mm;
@@ -98,6 +116,9 @@
 		 */
 		mapping = vma->vm_file->f_mapping;
 		spin_lock(&mapping->i_mmap_lock);
+		if (new_vma->vm_truncate_count &&
+		    new_vma->vm_truncate_count != vma->vm_truncate_count)
+			new_vma->vm_truncate_count = 0;
 	}
 	spin_lock(&mm->page_table_lock);
 
@@ -144,8 +165,8 @@
 }
 
 static unsigned long move_page_tables(struct vm_area_struct *vma,
-		unsigned long new_addr, unsigned long old_addr,
-		unsigned long len)
+		unsigned long old_addr, struct vm_area_struct *new_vma,
+		unsigned long new_addr, unsigned long len)
 {
 	unsigned long offset;
 
@@ -157,7 +178,8 @@
 	 * only a few pages.. This also makes error recovery easier.
 	 */
 	for (offset = 0; offset < len; offset += PAGE_SIZE) {
-		if (move_one_page(vma, old_addr+offset, new_addr+offset) < 0)
+		if (move_one_page(vma, old_addr + offset,
+				new_vma, new_addr + offset) < 0)
 			break;
 		cond_resched();
 	}
@@ -188,14 +210,14 @@
 	if (!new_vma)
 		return -ENOMEM;
 
-	moved_len = move_page_tables(vma, new_addr, old_addr, old_len);
+	moved_len = move_page_tables(vma, old_addr, new_vma, new_addr, old_len);
 	if (moved_len < old_len) {
 		/*
 		 * On error, move entries back from new area to old,
 		 * which will succeed since page tables still there,
 		 * and then proceed to unmap new area instead of old.
 		 */
-		move_page_tables(new_vma, old_addr, new_addr, moved_len);
+		move_page_tables(new_vma, new_addr, vma, old_addr, moved_len);
 		vma = new_vma;
 		old_len = new_len;
 		old_addr = new_addr;
@@ -233,6 +255,9 @@
 					   new_addr + new_len);
 	}
 
+	acct_update_integrals();
+	update_mem_hiwater();
+
 	return new_addr;
 }
 
@@ -369,6 +394,8 @@
 				make_pages_present(addr + old_len,
 						   addr + new_len);
 			}
+			acct_update_integrals();
+			update_mem_hiwater();
 			ret = addr;
 			goto out;
 		}
diff -Nru a/mm/msync.c b/mm/msync.c
--- a/mm/msync.c	2005-03-01 23:38:55 -08:00
+++ b/mm/msync.c	2005-03-01 23:38:55 -08:00
@@ -67,13 +67,39 @@
 	return error;
 }
 
-static inline int filemap_sync_pmd_range(pgd_t * pgd,
+static inline int filemap_sync_pmd_range(pud_t * pud,
 	unsigned long address, unsigned long end, 
 	struct vm_area_struct *vma, unsigned int flags)
 {
 	pmd_t * pmd;
 	int error;
 
+	if (pud_none(*pud))
+		return 0;
+	if (pud_bad(*pud)) {
+		pud_ERROR(*pud);
+		pud_clear(pud);
+		return 0;
+	}
+	pmd = pmd_offset(pud, address);
+	if ((address & PUD_MASK) != (end & PUD_MASK))
+		end = (address & PUD_MASK) + PUD_SIZE;
+	error = 0;
+	do {
+		error |= filemap_sync_pte_range(pmd, address, end, vma, flags);
+		address = (address + PMD_SIZE) & PMD_MASK;
+		pmd++;
+	} while (address && (address < end));
+	return error;
+}
+
+static inline int filemap_sync_pud_range(pgd_t *pgd,
+	unsigned long address, unsigned long end,
+	struct vm_area_struct *vma, unsigned int flags)
+{
+	pud_t *pud;
+	int error;
+
 	if (pgd_none(*pgd))
 		return 0;
 	if (pgd_bad(*pgd)) {
@@ -81,23 +107,25 @@
 		pgd_clear(pgd);
 		return 0;
 	}
-	pmd = pmd_offset(pgd, address);
+	pud = pud_offset(pgd, address);
 	if ((address & PGDIR_MASK) != (end & PGDIR_MASK))
 		end = (address & PGDIR_MASK) + PGDIR_SIZE;
 	error = 0;
 	do {
-		error |= filemap_sync_pte_range(pmd, address, end, vma, flags);
-		address = (address + PMD_SIZE) & PMD_MASK;
-		pmd++;
+		error |= filemap_sync_pmd_range(pud, address, end, vma, flags);
+		address = (address + PUD_SIZE) & PUD_MASK;
+		pud++;
 	} while (address && (address < end));
 	return error;
 }
 
-static int filemap_sync(struct vm_area_struct * vma, unsigned long address,
-	size_t size, unsigned int flags)
+static int __filemap_sync(struct vm_area_struct *vma, unsigned long address,
+			size_t size, unsigned int flags)
 {
-	pgd_t * dir;
+	pgd_t *pgd;
 	unsigned long end = address + size;
+	unsigned long next;
+	int i;
 	int error = 0;
 
 	/* Aquire the lock early; it may be possible to avoid dropping
@@ -105,7 +133,7 @@
 	 */
 	spin_lock(&vma->vm_mm->page_table_lock);
 
-	dir = pgd_offset(vma->vm_mm, address);
+	pgd = pgd_offset(vma->vm_mm, address);
 	flush_cache_range(vma, address, end);
 
 	/* For hugepages we can't go walking the page table normally,
@@ -116,11 +144,14 @@
 
 	if (address >= end)
 		BUG();
-	do {
-		error |= filemap_sync_pmd_range(dir, address, end, vma, flags);
-		address = (address + PGDIR_SIZE) & PGDIR_MASK;
-		dir++;
-	} while (address && (address < end));
+	for (i = pgd_index(address); i <= pgd_index(end-1); i++) {
+		next = (address + PGDIR_SIZE) & PGDIR_MASK;
+		if (next <= address || next > end)
+			next = end;
+		error |= filemap_sync_pud_range(pgd, address, next, vma, flags);
+		address = next;
+		pgd++;
+	}
 	/*
 	 * Why flush ? filemap_sync_pte already flushed the tlbs with the
 	 * dirty bits.
@@ -132,6 +163,31 @@
 	return error;
 }
 
+#ifdef CONFIG_PREEMPT
+static int filemap_sync(struct vm_area_struct *vma, unsigned long address,
+			size_t size, unsigned int flags)
+{
+	const size_t chunk = 64 * 1024;	/* bytes */
+	int error = 0;
+
+	while (size) {
+		size_t sz = min(size, chunk);
+
+		error |= __filemap_sync(vma, address, sz, flags);
+		cond_resched();
+		address += sz;
+		size -= sz;
+	}
+	return error;
+}
+#else
+static int filemap_sync(struct vm_area_struct *vma, unsigned long address,
+			size_t size, unsigned int flags)
+{
+	return __filemap_sync(vma, address, size, flags);
+}
+#endif
+
 /*
  * MS_SYNC syncs the entire file - including mappings.
  *
@@ -159,9 +215,12 @@
 			struct address_space *mapping = file->f_mapping;
 			int err;
 
-			down(&mapping->host->i_sem);
 			ret = filemap_fdatawrite(mapping);
 			if (file->f_op && file->f_op->fsync) {
+				/*
+				 * We don't take i_sem here because mmap_sem
+				 * is already held.
+				 */
 				err = file->f_op->fsync(file,file->f_dentry,1);
 				if (err && !ret)
 					ret = err;
@@ -169,7 +228,6 @@
 			err = filemap_fdatawait(mapping);
 			if (!ret)
 				ret = err;
-			up(&mapping->host->i_sem);
 		}
 	}
 	return ret;
@@ -181,6 +239,9 @@
 	struct vm_area_struct * vma;
 	int unmapped_error, error = -EINVAL;
 
+	if (flags & MS_SYNC)
+		current->flags |= PF_SYNCWRITE;
+
 	down_read(&current->mm->mmap_sem);
 	if (flags & ~(MS_ASYNC | MS_INVALIDATE | MS_SYNC))
 		goto out;
@@ -231,5 +292,6 @@
 	}
 out:
 	up_read(&current->mm->mmap_sem);
+	current->flags &= ~PF_SYNCWRITE;
 	return error;
 }
diff -Nru a/mm/nommu.c b/mm/nommu.c
--- a/mm/nommu.c	2005-03-01 23:39:09 -08:00
+++ b/mm/nommu.c	2005-03-01 23:39:09 -08:00
@@ -4,6 +4,9 @@
  *  Replacement code for mm functions to support CPU's that don't
  *  have any form of memory management unit (thus no virtual memory).
  *
+ *  See Documentation/nommu-mmap.txt
+ *
+ *  Copyright (c) 2004-2005 David Howells <dhowells@redhat.com>
  *  Copyright (c) 2000-2003 David McCullough <davidm@snapgear.com>
  *  Copyright (c) 2000-2001 D Jeff Dionne <jeff@uClinux.org>
  *  Copyright (c) 2002      Greg Ungerer <gerg@snapgear.com>
@@ -12,13 +15,17 @@
 #include <linux/mm.h>
 #include <linux/mman.h>
 #include <linux/swap.h>
-#include <linux/smp_lock.h>
+#include <linux/file.h>
 #include <linux/highmem.h>
 #include <linux/pagemap.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
+#include <linux/ptrace.h>
 #include <linux/blkdev.h>
 #include <linux/backing-dev.h>
+#include <linux/mount.h>
+#include <linux/personality.h>
+#include <linux/security.h>
 #include <linux/syscalls.h>
 
 #include <asm/uaccess.h>
@@ -34,9 +41,21 @@
 int sysctl_overcommit_memory = OVERCOMMIT_GUESS; /* heuristic overcommit */
 int sysctl_overcommit_ratio = 50; /* default is 50% */
 int sysctl_max_map_count = DEFAULT_MAX_MAP_COUNT;
+int heap_stack_gap = 0;
 
-EXPORT_SYMBOL(sysctl_max_map_count);
 EXPORT_SYMBOL(mem_map);
+EXPORT_SYMBOL(sysctl_max_map_count);
+EXPORT_SYMBOL(sysctl_overcommit_memory);
+EXPORT_SYMBOL(sysctl_overcommit_ratio);
+EXPORT_SYMBOL(vm_committed_space);
+EXPORT_SYMBOL(__vm_enough_memory);
+
+/* list of shareable VMAs */
+struct rb_root nommu_vma_tree = RB_ROOT;
+DECLARE_RWSEM(nommu_vma_sem);
+
+struct vm_operations_struct generic_file_vm_ops = {
+};
 
 /*
  * Handle all mappings that got truncated by a "truncate()"
@@ -123,7 +142,7 @@
 	return(i);
 }
 
-rwlock_t vmlist_lock = RW_LOCK_UNLOCKED;
+DEFINE_RWLOCK(vmlist_lock);
 struct vm_struct *vmlist;
 
 void vfree(void *addr)
@@ -161,7 +180,7 @@
 	/* Don't allow overflow */
 	if ((unsigned long) addr + count < count)
 		count = -(unsigned long) addr;
-	
+
 	memcpy(addr, buf, count);
 	return(count);
 }
@@ -217,7 +236,7 @@
 {
 	struct mm_struct *mm = current->mm;
 
-	if (brk < mm->end_code || brk < mm->start_brk || brk > mm->context.end_brk)
+	if (brk < mm->start_brk || brk > mm->context.end_brk)
 		return mm->brk;
 
 	if (mm->brk == brk)
@@ -263,49 +282,127 @@
 #ifdef DEBUG
 static void show_process_blocks(void)
 {
-	struct mm_tblock_struct *tblock;
+	struct vm_list_struct *vml;
 
 	printk("Process blocks %d:", current->pid);
 
-	for (tblock = &current->mm->context.tblock; tblock; tblock = tblock->next) {
-		printk(" %p: %p", tblock, tblock->rblock);
-		if (tblock->rblock)
-			printk(" (%d @%p #%d)", kobjsize(tblock->rblock->kblock), tblock->rblock->kblock, tblock->rblock->refcount);
-		printk(tblock->next ? " ->" : ".\n");
+	for (vml = &current->mm->context.vmlist; vml; vml = vml->next) {
+		printk(" %p: %p", vml, vml->vma);
+		if (vml->vma)
+			printk(" (%d @%lx #%d)",
+			       kobjsize((void *) vml->vma->vm_start),
+			       vml->vma->vm_start,
+			       atomic_read(&vml->vma->vm_usage));
+		printk(vml->next ? " ->" : ".\n");
 	}
 }
 #endif /* DEBUG */
 
-unsigned long do_mmap_pgoff(
-	struct file * file,
-	unsigned long addr,
-	unsigned long len,
-	unsigned long prot,
-	unsigned long flags,
-	unsigned long pgoff)
+static inline struct vm_area_struct *find_nommu_vma(unsigned long start)
 {
-	void * result;
-	struct mm_tblock_struct * tblock;
-	unsigned int vm_flags;
+	struct vm_area_struct *vma;
+	struct rb_node *n = nommu_vma_tree.rb_node;
 
-	/*
-	 * Get the !CONFIG_MMU specific checks done first
-	 */
-	if ((flags & MAP_SHARED) && (prot & PROT_WRITE) && (file)) {
-		printk("MAP_SHARED not supported (cannot write mappings to disk)\n");
-		return -EINVAL;
+	while (n) {
+		vma = rb_entry(n, struct vm_area_struct, vm_rb);
+
+		if (start < vma->vm_start)
+			n = n->rb_left;
+		else if (start > vma->vm_start)
+			n = n->rb_right;
+		else
+			return vma;
 	}
-	
-	if ((prot & PROT_WRITE) && (flags & MAP_PRIVATE)) {
-		printk("Private writable mappings not supported\n");
+
+	return NULL;
+}
+
+static void add_nommu_vma(struct vm_area_struct *vma)
+{
+	struct vm_area_struct *pvma;
+	struct address_space *mapping;
+	struct rb_node **p = &nommu_vma_tree.rb_node;
+	struct rb_node *parent = NULL;
+
+	/* add the VMA to the mapping */
+	if (vma->vm_file) {
+		mapping = vma->vm_file->f_mapping;
+
+		flush_dcache_mmap_lock(mapping);
+		vma_prio_tree_insert(vma, &mapping->i_mmap);
+		flush_dcache_mmap_unlock(mapping);
+	}
+
+	/* add the VMA to the master list */
+	while (*p) {
+		parent = *p;
+		pvma = rb_entry(parent, struct vm_area_struct, vm_rb);
+
+		if (vma->vm_start < pvma->vm_start) {
+			p = &(*p)->rb_left;
+		}
+		else if (vma->vm_start > pvma->vm_start) {
+			p = &(*p)->rb_right;
+		}
+		else {
+			/* mappings are at the same address - this can only
+			 * happen for shared-mem chardevs and shared file
+			 * mappings backed by ramfs/tmpfs */
+			BUG_ON(!(pvma->vm_flags & VM_SHARED));
+
+			if (vma < pvma)
+				p = &(*p)->rb_left;
+			else if (vma > pvma)
+				p = &(*p)->rb_right;
+			else
+				BUG();
+		}
+	}
+
+	rb_link_node(&vma->vm_rb, parent, p);
+	rb_insert_color(&vma->vm_rb, &nommu_vma_tree);
+}
+
+static void delete_nommu_vma(struct vm_area_struct *vma)
+{
+	struct address_space *mapping;
+
+	/* remove the VMA from the mapping */
+	if (vma->vm_file) {
+		mapping = vma->vm_file->f_mapping;
+
+		flush_dcache_mmap_lock(mapping);
+		vma_prio_tree_remove(vma, &mapping->i_mmap);
+		flush_dcache_mmap_unlock(mapping);
+	}
+
+	/* remove from the master list */
+	rb_erase(&vma->vm_rb, &nommu_vma_tree);
+}
+
+/*
+ * handle mapping creation for uClinux
+ */
+unsigned long do_mmap_pgoff(struct file *file,
+			    unsigned long addr,
+			    unsigned long len,
+			    unsigned long prot,
+			    unsigned long flags,
+			    unsigned long pgoff)
+{
+	struct vm_list_struct *vml = NULL;
+	struct vm_area_struct *vma = NULL;
+	struct rb_node *rb;
+	unsigned int vm_flags;
+	void *result;
+	int ret, membacked;
+
+	/* do the simple checks first */
+	if (flags & MAP_FIXED || addr) {
+		printk(KERN_DEBUG "%d: Can't do fixed-address/overlay mmap of RAM\n",
+		       current->pid);
 		return -EINVAL;
 	}
-	
-	/*
-	 *	now all the standard checks
-	 */
-	if (file && (!file->f_op || !file->f_op->mmap))
-		return -ENODEV;
 
 	if (PAGE_ALIGN(len) == 0)
 		return addr;
@@ -317,148 +414,379 @@
 	if ((pgoff + (len >> PAGE_SHIFT)) < pgoff)
 		return -EINVAL;
 
-	/* Do simple checking here so the lower-level routines won't have
+	/* validate file mapping requests */
+	membacked = 0;
+	if (file) {
+		/* files must support mmap */
+		if (!file->f_op || !file->f_op->mmap)
+			return -ENODEV;
+
+		if ((prot & PROT_EXEC) &&
+		    (file->f_vfsmnt->mnt_flags & MNT_NOEXEC))
+			return -EPERM;
+
+		/* work out if what we've got could possibly be shared
+		 * - we support chardevs that provide their own "memory"
+		 * - we support files/blockdevs that are memory backed
+		 */
+		if (S_ISCHR(file->f_dentry->d_inode->i_mode)) {
+			membacked = 1;
+		}
+		else {
+			struct address_space *mapping = file->f_mapping;
+			if (!mapping)
+				mapping = file->f_dentry->d_inode->i_mapping;
+			if (mapping && mapping->backing_dev_info)
+				membacked = mapping->backing_dev_info->memory_backed;
+		}
+
+		if (flags & MAP_SHARED) {
+			/* do checks for writing, appending and locking */
+			if ((prot & PROT_WRITE) && !(file->f_mode & FMODE_WRITE))
+				return -EACCES;
+
+			if (IS_APPEND(file->f_dentry->d_inode) &&
+			    (file->f_mode & FMODE_WRITE))
+				return -EACCES;
+
+			if (locks_verify_locked(file->f_dentry->d_inode))
+				return -EAGAIN;
+
+			if (!membacked) {
+				printk("MAP_SHARED not completely supported on !MMU\n");
+				return -EINVAL;
+			}
+
+			/* we require greater support from the driver or
+			 * filesystem - we ask it to tell us what memory to
+			 * use */
+			if (!file->f_op->get_unmapped_area)
+				return -ENODEV;
+		}
+		else {
+			/* we read private files into memory we allocate */
+			if (!file->f_op->read)
+				return -ENODEV;
+		}
+	}
+
+	/* handle PROT_EXEC implication by PROT_READ */
+	if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
+		if (!(file && (file->f_vfsmnt->mnt_flags & MNT_NOEXEC)))
+			prot |= PROT_EXEC;
+
+	/* do simple checking here so the lower-level routines won't have
 	 * to. we assume access permissions have been handled by the open
 	 * of the memory object, so we don't do any here.
 	 */
-	vm_flags = calc_vm_flags(prot,flags) /* | mm->def_flags */ | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
+	vm_flags = calc_vm_flags(prot,flags) /* | mm->def_flags */
+		| VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
 
-	/*
-	 * determine the object being mapped and call the appropriate
-	 * specific mapper. 
+	if (!membacked) {
+		/* share any file segment that's mapped read-only */
+		if (((flags & MAP_PRIVATE) && !(prot & PROT_WRITE) && file) ||
+		    ((flags & MAP_SHARED) && !(prot & PROT_WRITE) && file))
+			vm_flags |= VM_MAYSHARE;
+
+		/* refuse to let anyone share files with this process if it's being traced -
+		 * otherwise breakpoints set in it may interfere with another untraced process
+		 */
+		if (current->ptrace & PT_PTRACED)
+			vm_flags &= ~(VM_SHARED | VM_MAYSHARE);
+	}
+	else {
+		/* permit sharing of character devices and ramfs files at any time for
+		 * anything other than a privately writable mapping
+		 */
+		if (!(flags & MAP_PRIVATE) || !(prot & PROT_WRITE)) {
+			vm_flags |= VM_MAYSHARE;
+			if (flags & MAP_SHARED)
+				vm_flags |= VM_SHARED;
+		}
+	}
+
+	/* allow the security API to have its say */
+	ret = security_file_mmap(file, prot, flags);
+	if (ret)
+		return ret;
+
+	/* we're going to need to record the mapping if it works */
+	vml = kmalloc(sizeof(struct vm_list_struct), GFP_KERNEL);
+	if (!vml)
+		goto error_getting_vml;
+	memset(vml, 0, sizeof(*vml));
+
+	down_write(&nommu_vma_sem);
+
+	/* if we want to share, we need to search for VMAs created by another
+	 * mmap() call that overlap with our proposed mapping
+	 * - we can only share with an exact match on most regular files
+	 * - shared mappings on character devices and memory backed files are
+	 *   permitted to overlap inexactly as far as we are concerned for in
+	 *   these cases, sharing is handled in the driver or filesystem rather
+	 *   than here
 	 */
-	if (file) {
-		struct vm_area_struct vma;
-		int error;
+	if (vm_flags & VM_MAYSHARE) {
+		unsigned long pglen = (len + PAGE_SIZE - 1) >> PAGE_SHIFT;
+		unsigned long vmpglen;
+
+		for (rb = rb_first(&nommu_vma_tree); rb; rb = rb_next(rb)) {
+			vma = rb_entry(rb, struct vm_area_struct, vm_rb);
+
+			if (!(vma->vm_flags & VM_MAYSHARE))
+				continue;
+
+			/* search for overlapping mappings on the same file */
+			if (vma->vm_file->f_dentry->d_inode != file->f_dentry->d_inode)
+				continue;
+
+			if (vma->vm_pgoff >= pgoff + pglen)
+				continue;
+
+			vmpglen = (vma->vm_end - vma->vm_start + PAGE_SIZE - 1) >> PAGE_SHIFT;
+			if (pgoff >= vma->vm_pgoff + vmpglen)
+				continue;
+
+			/* handle inexact matches between mappings */
+			if (vmpglen != pglen || vma->vm_pgoff != pgoff) {
+				if (!membacked)
+					goto sharing_violation;
+				continue;
+			}
 
-		if (!file->f_op)
-			return -ENODEV;
+			/* we've found a VMA we can share */
+			atomic_inc(&vma->vm_usage);
+
+			vml->vma = vma;
+			result = (void *) vma->vm_start;
+			goto shared;
+		}
+	}
+
+	vma = NULL;
+
+	/* obtain the address to map to. we verify (or select) it and ensure
+	 * that it represents a valid section of the address space
+	 * - this is the hook for quasi-memory character devices
+	 */
+	if (file && file->f_op->get_unmapped_area) {
+		addr = file->f_op->get_unmapped_area(file, addr, len, pgoff, flags);
+		if (IS_ERR((void *) addr)) {
+			ret = addr;
+			if (ret == (unsigned long) -ENOSYS)
+				ret = (unsigned long) -ENODEV;
+			goto error;
+		}
+	}
 
-		vma.vm_start = addr;
-		vma.vm_end = addr + len;
-		vma.vm_flags = vm_flags;
-		vma.vm_pgoff = pgoff;
+	/* we're going to need a VMA struct as well */
+	vma = kmalloc(sizeof(struct vm_area_struct), GFP_KERNEL);
+	if (!vma)
+		goto error_getting_vma;
+
+	memset(vma, 0, sizeof(*vma));
+	INIT_LIST_HEAD(&vma->anon_vma_node);
+	atomic_set(&vma->vm_usage, 1);
+	if (file)
+		get_file(file);
+	vma->vm_file	= file;
+	vma->vm_flags	= vm_flags;
+	vma->vm_start	= addr;
+	vma->vm_end	= addr + len;
+	vma->vm_pgoff	= pgoff;
 
+	vml->vma = vma;
+
+	/* determine the object being mapped and call the appropriate specific
+	 * mapper.
+	 */
+	if (file) {
 #ifdef MAGIC_ROM_PTR
 		/* First, try simpler routine designed to give us a ROM pointer. */
-
 		if (file->f_op->romptr && !(prot & PROT_WRITE)) {
-			error = file->f_op->romptr(file, &vma);
+			ret = file->f_op->romptr(file, vma);
 #ifdef DEBUG
-			printk("romptr mmap returned %d, start 0x%.8x\n", error,
-					vma.vm_start);
+			printk("romptr mmap returned %d (st=%lx)\n",
+			       ret, vma->vm_start);
 #endif
-			if (!error)
-				return vma.vm_start;
-			else if (error != -ENOSYS)
-				return error;
+			result = (void *) vma->vm_start;
+			if (!ret)
+				goto done;
+			else if (ret != -ENOSYS)
+				goto error;
 		} else
 #endif /* MAGIC_ROM_PTR */
-		/* Then try full mmap routine, which might return a RAM pointer,
-		   or do something truly complicated. */
-		   
+		/* Then try full mmap routine, which might return a RAM
+		 * pointer, or do something truly complicated
+		 */
 		if (file->f_op->mmap) {
-			error = file->f_op->mmap(file, &vma);
-				   
+			ret = file->f_op->mmap(file, vma);
+
 #ifdef DEBUG
-			printk("f_op->mmap() returned %d/%lx\n", error, vma.vm_start);
+			printk("f_op->mmap() returned %d (st=%lx)\n",
+			       ret, vma->vm_start);
 #endif
-			if (!error)
-				return vma.vm_start;
-			else if (error != -ENOSYS)
-				return error;
-		} else
-			return -ENODEV; /* No mapping operations defined */
-
-		/* An ENOSYS error indicates that mmap isn't possible (as opposed to
-		   tried but failed) so we'll fall through to the copy. */
-	}
-
-	tblock = (struct mm_tblock_struct *)
-                        kmalloc(sizeof(struct mm_tblock_struct), GFP_KERNEL);
-	if (!tblock) {
-		printk("Allocation of tblock for %lu byte allocation from process %d failed\n", len, current->pid);
-		show_free_areas();
-		return -ENOMEM;
-	}
-
-	tblock->rblock = (struct mm_rblock_struct *)
-			kmalloc(sizeof(struct mm_rblock_struct), GFP_KERNEL);
+			result = (void *) vma->vm_start;
+			if (!ret)
+				goto done;
+			else if (ret != -ENOSYS)
+				goto error;
+		} else {
+			ret = -ENODEV; /* No mapping operations defined */
+			goto error;
+		}
 
-	if (!tblock->rblock) {
-		printk("Allocation of rblock for %lu byte allocation from process %d failed\n", len, current->pid);
-		show_free_areas();
-		kfree(tblock);
-		return -ENOMEM;
+		/* An ENOSYS error indicates that mmap isn't possible (as
+		 * opposed to tried but failed) so we'll fall through to the
+		 * copy. */
 	}
 
+	/* allocate some memory to hold the mapping
+	 * - note that this may not return a page-aligned address if the object
+	 *   we're allocating is smaller than a page
+	 */
+	ret = -ENOMEM;
 	result = kmalloc(len, GFP_KERNEL);
 	if (!result) {
-		printk("Allocation of length %lu from process %d failed\n", len,
-				current->pid);
+		printk("Allocation of length %lu from process %d failed\n",
+		       len, current->pid);
 		show_free_areas();
-		kfree(tblock->rblock);
-		kfree(tblock);
-		return -ENOMEM;
+		goto error;
 	}
 
-	tblock->rblock->refcount = 1;
-	tblock->rblock->kblock = result;
-	tblock->rblock->size = len;
-	
-	realalloc += kobjsize(result);
-	askedalloc += len;
-
-#ifdef WARN_ON_SLACK	
-	if ((len+WARN_ON_SLACK) <= kobjsize(result))
-		printk("Allocation of %lu bytes from process %d has %lu bytes of slack\n", len, current->pid, kobjsize(result)-len);
+	vma->vm_start = (unsigned long) result;
+	vma->vm_end = vma->vm_start + len;
+
+#ifdef WARN_ON_SLACK
+	if (len + WARN_ON_SLACK <= kobjsize(result))
+		printk("Allocation of %lu bytes from process %d has %lu bytes of slack\n",
+		       len, current->pid, kobjsize(result) - len);
 #endif
-	
+
 	if (file) {
-		int error;
 		mm_segment_t old_fs = get_fs();
+		loff_t fpos;
+
+		fpos = pgoff;
+		fpos <<= PAGE_SHIFT;
+
 		set_fs(KERNEL_DS);
-		error = file->f_op->read(file, (char *) result, len, &file->f_pos);
+		ret = file->f_op->read(file, (char *) result, len, &fpos);
 		set_fs(old_fs);
-		if (error < 0) {
-			kfree(result);
-			kfree(tblock->rblock);
-			kfree(tblock);
-			return error;
-		}
-		if (error < len)
-			memset(result+error, '\0', len-error);
+
+		if (ret < 0)
+			goto error2;
+		if (ret < len)
+			memset(result + ret, 0, len - ret);
 	} else {
-		memset(result, '\0', len);
+		memset(result, 0, len);
 	}
 
-	realalloc += kobjsize(tblock);
-	askedalloc += sizeof(struct mm_tblock_struct);
+	if (prot & PROT_EXEC)
+		flush_icache_range((unsigned long) result, (unsigned long) result + len);
 
-	realalloc += kobjsize(tblock->rblock);
-	askedalloc += sizeof(struct mm_rblock_struct);
+ done:
+	if (!(vma->vm_flags & VM_SHARED)) {
+		realalloc += kobjsize(result);
+		askedalloc += len;
+	}
+
+	realalloc += kobjsize(vma);
+	askedalloc += sizeof(*vma);
 
-	tblock->next = current->mm->context.tblock.next;
-	current->mm->context.tblock.next = tblock;
 	current->mm->total_vm += len >> PAGE_SHIFT;
 
+	add_nommu_vma(vma);
+ shared:
+	realalloc += kobjsize(vml);
+	askedalloc += sizeof(*vml);
+
+	vml->next = current->mm->context.vmlist;
+	current->mm->context.vmlist = vml;
+
+	up_write(&nommu_vma_sem);
+
 #ifdef DEBUG
 	printk("do_mmap:\n");
 	show_process_blocks();
-#endif	  
+#endif
 
-	return (unsigned long)result;
+	return (unsigned long) result;
+
+ error2:
+	kfree(result);
+ error:
+	up_write(&nommu_vma_sem);
+	kfree(vml);
+	if (vma) {
+		fput(vma->vm_file);
+		kfree(vma);
+	}
+	return ret;
+
+ sharing_violation:
+	up_write(&nommu_vma_sem);
+	printk("Attempt to share mismatched mappings\n");
+	kfree(vml);
+	return -EINVAL;
+
+ error_getting_vma:
+	up_write(&nommu_vma_sem);
+	kfree(vml);
+	printk("Allocation of vml for %lu byte allocation from process %d failed\n",
+	       len, current->pid);
+	show_free_areas();
+	return -ENOMEM;
+
+ error_getting_vml:
+	printk("Allocation of vml for %lu byte allocation from process %d failed\n",
+	       len, current->pid);
+	show_free_areas();
+	return -ENOMEM;
 }
 
-int do_munmap(struct mm_struct * mm, unsigned long addr, size_t len)
+/*
+ * handle mapping disposal for uClinux
+ */
+static void put_vma(struct vm_area_struct *vma)
 {
-	struct mm_tblock_struct * tblock, *tmp;
+	if (vma) {
+		down_write(&nommu_vma_sem);
+
+		if (atomic_dec_and_test(&vma->vm_usage)) {
+			delete_nommu_vma(vma);
+
+			if (vma->vm_ops && vma->vm_ops->close)
+				vma->vm_ops->close(vma);
+
+			/* IO memory and memory shared directly out of the pagecache from
+			 * ramfs/tmpfs mustn't be released here */
+			if (!(vma->vm_flags & (VM_IO | VM_SHARED)) && vma->vm_start) {
+				realalloc -= kobjsize((void *) vma->vm_start);
+				askedalloc -= vma->vm_end - vma->vm_start;
+				kfree((void *) vma->vm_start);
+			}
+
+			realalloc -= kobjsize(vma);
+			askedalloc -= sizeof(*vma);
+
+			if (vma->vm_file)
+				fput(vma->vm_file);
+			kfree(vma);
+		}
+
+		up_write(&nommu_vma_sem);
+	}
+}
+
+int do_munmap(struct mm_struct *mm, unsigned long addr, size_t len)
+{
+	struct vm_list_struct *vml, **parent;
+	unsigned long end = addr + len;
 
 #ifdef MAGIC_ROM_PTR
-	/*
-	 * For efficiency's sake, if the pointer is obviously in ROM,
-	 * don't bother walking the lists to free it.
-	 */
+	/* For efficiency's sake, if the pointer is obviously in ROM,
+	   don't bother walking the lists to free it */
 	if (is_in_rom(addr))
 		return 0;
 #endif
@@ -467,38 +795,29 @@
 	printk("do_munmap:\n");
 #endif
 
-	tmp = &mm->context.tblock; /* dummy head */
-	while ((tblock=tmp->next) && tblock->rblock &&
-			tblock->rblock->kblock != (void*)addr) 
-		tmp = tblock;
-		
-	if (!tblock) {
-		printk("munmap of non-mmaped memory by process %d (%s): %p\n",
-				current->pid, current->comm, (void*)addr);
-		return -EINVAL;
-	}
-	if (tblock->rblock) {
-		if (!--tblock->rblock->refcount) {
-			if (tblock->rblock->kblock) {
-				realalloc -= kobjsize(tblock->rblock->kblock);
-				askedalloc -= tblock->rblock->size;
-				kfree(tblock->rblock->kblock);
-			}
-			
-			realalloc -= kobjsize(tblock->rblock);
-			askedalloc -= sizeof(struct mm_rblock_struct);
-			kfree(tblock->rblock);
-		}
-	}
-	tmp->next = tblock->next;
-	realalloc -= kobjsize(tblock);
-	askedalloc -= sizeof(struct mm_tblock_struct);
-	kfree(tblock);
+	for (parent = &mm->context.vmlist; *parent; parent = &(*parent)->next)
+		if ((*parent)->vma->vm_start == addr &&
+		    (*parent)->vma->vm_end == end)
+			goto found;
+
+	printk("munmap of non-mmaped memory by process %d (%s): %p\n",
+	       current->pid, current->comm, (void *) addr);
+	return -EINVAL;
+
+ found:
+	vml = *parent;
+
+	put_vma(vml->vma);
+
+	*parent = vml->next;
+	realalloc -= kobjsize(vml);
+	askedalloc -= sizeof(*vml);
+	kfree(vml);
 	mm->total_vm -= len >> PAGE_SHIFT;
 
 #ifdef DEBUG
 	show_process_blocks();
-#endif	  
+#endif
 
 	return 0;
 }
@@ -506,39 +825,28 @@
 /* Release all mmaps. */
 void exit_mmap(struct mm_struct * mm)
 {
-	struct mm_tblock_struct *tmp;
-	mm->total_vm = 0;
-
-	if (!mm)
-		return;
+	struct vm_list_struct *tmp;
 
+	if (mm) {
 #ifdef DEBUG
-	printk("Exit_mmap:\n");
+		printk("Exit_mmap:\n");
 #endif
 
-	while((tmp = mm->context.tblock.next)) {
-		if (tmp->rblock) {
-			if (!--tmp->rblock->refcount) {
-				if (tmp->rblock->kblock) {
-					realalloc -= kobjsize(tmp->rblock->kblock);
-					askedalloc -= tmp->rblock->size;
-					kfree(tmp->rblock->kblock);
-				}
-				realalloc -= kobjsize(tmp->rblock);
-				askedalloc -= sizeof(struct mm_rblock_struct);
-				kfree(tmp->rblock);
-			}
-			tmp->rblock = 0;
+		mm->total_vm = 0;
+
+		while ((tmp = mm->context.vmlist)) {
+			mm->context.vmlist = tmp->next;
+			put_vma(tmp->vma);
+
+			realalloc -= kobjsize(tmp);
+			askedalloc -= sizeof(*tmp);
+			kfree(tmp);
 		}
-		mm->context.tblock.next = tmp->next;
-		realalloc -= kobjsize(tmp);
-		askedalloc -= sizeof(struct mm_tblock_struct);
-		kfree(tmp);
-	}
 
 #ifdef DEBUG
-	show_process_blocks();
-#endif	  
+		show_process_blocks();
+#endif
+	}
 }
 
 asmlinkage long sys_munmap(unsigned long addr, size_t len)
@@ -557,11 +865,70 @@
 	return -ENOMEM;
 }
 
-struct vm_area_struct * find_vma(struct mm_struct * mm, unsigned long addr)
+/*
+ * Expand (or shrink) an existing mapping, potentially moving it at the
+ * same time (controlled by the MREMAP_MAYMOVE flag and available VM space)
+ *
+ * MREMAP_FIXED option added 5-Dec-1999 by Benjamin LaHaise
+ * This option implies MREMAP_MAYMOVE.
+ *
+ * on uClinux, we only permit changing a mapping's size, and only as long as it stays within the
+ * hole allocated by the kmalloc() call in do_mmap_pgoff() and the block is not shareable
+ */
+unsigned long do_mremap(unsigned long addr,
+			unsigned long old_len, unsigned long new_len,
+			unsigned long flags, unsigned long new_addr)
 {
+	struct vm_list_struct *vml = NULL;
+
+	/* insanity checks first */
+	if (new_len == 0)
+		return (unsigned long) -EINVAL;
+
+	if (flags & MREMAP_FIXED && new_addr != addr)
+		return (unsigned long) -EINVAL;
+
+	for (vml = current->mm->context.vmlist; vml; vml = vml->next)
+		if (vml->vma->vm_start == addr)
+			goto found;
+
+	return (unsigned long) -EINVAL;
+
+ found:
+	if (vml->vma->vm_end != vml->vma->vm_start + old_len)
+		return (unsigned long) -EFAULT;
+
+	if (vml->vma->vm_flags & VM_MAYSHARE)
+		return (unsigned long) -EPERM;
+
+	if (new_len > kobjsize((void *) addr))
+		return (unsigned long) -ENOMEM;
+
+	/* all checks complete - do it */
+	vml->vma->vm_end = vml->vma->vm_start + new_len;
+
+	askedalloc -= old_len;
+	askedalloc += new_len;
+
+	return vml->vma->vm_start;
+}
+
+/*
+ * Look up the first VMA which satisfies  addr < vm_end,  NULL if none
+ */
+struct vm_area_struct *find_vma(struct mm_struct *mm, unsigned long addr)
+{
+	struct vm_list_struct *vml;
+
+	for (vml = mm->context.vmlist; vml; vml = vml->next)
+		if (addr >= vml->vma->vm_start && addr < vml->vma->vm_end)
+			return vml->vma;
+
 	return NULL;
 }
 
+EXPORT_SYMBOL(find_vma);
+
 struct page * follow_page(struct mm_struct *mm, unsigned long addr, int write)
 {
 	return NULL;
@@ -578,12 +945,6 @@
 	return -EPERM;
 }
 
-unsigned long get_unmapped_area(struct file *file, unsigned long addr,
-	unsigned long len, unsigned long pgoff, unsigned long flags)
-{
-	return -ENOMEM;
-}
-
 void swap_unplug_io_fn(struct backing_dev_info *bdi, struct page *page)
 {
 }
@@ -596,5 +957,109 @@
 
 void arch_unmap_area(struct vm_area_struct *area)
 {
+}
+
+void update_mem_hiwater(void)
+{
+	struct task_struct *tsk = current;
+
+	if (likely(tsk->mm)) {
+		if (tsk->mm->hiwater_rss < tsk->mm->rss)
+			tsk->mm->hiwater_rss = tsk->mm->rss;
+		if (tsk->mm->hiwater_vm < tsk->mm->total_vm)
+			tsk->mm->hiwater_vm = tsk->mm->total_vm;
+	}
+}
+
+void unmap_mapping_range(struct address_space *mapping,
+			 loff_t const holebegin, loff_t const holelen,
+			 int even_cows)
+{
+}
+
+/*
+ * Check that a process has enough memory to allocate a new virtual
+ * mapping. 0 means there is enough memory for the allocation to
+ * succeed and -ENOMEM implies there is not.
+ *
+ * We currently support three overcommit policies, which are set via the
+ * vm.overcommit_memory sysctl.  See Documentation/vm/overcommit-accounting
+ *
+ * Strict overcommit modes added 2002 Feb 26 by Alan Cox.
+ * Additional code 2002 Jul 20 by Robert Love.
+ *
+ * cap_sys_admin is 1 if the process has admin privileges, 0 otherwise.
+ *
+ * Note this is a helper function intended to be used by LSMs which
+ * wish to use this logic.
+ */
+int __vm_enough_memory(long pages, int cap_sys_admin)
+{
+	unsigned long free, allowed;
+
+	vm_acct_memory(pages);
+
+	/*
+	 * Sometimes we want to use more memory than we have
+	 */
+	if (sysctl_overcommit_memory == OVERCOMMIT_ALWAYS)
+		return 0;
+
+	if (sysctl_overcommit_memory == OVERCOMMIT_GUESS) {
+		unsigned long n;
+
+		free = get_page_cache_size();
+		free += nr_swap_pages;
+
+		/*
+		 * Any slabs which are created with the
+		 * SLAB_RECLAIM_ACCOUNT flag claim to have contents
+		 * which are reclaimable, under pressure.  The dentry
+		 * cache and most inode caches should fall into this
+		 */
+		free += atomic_read(&slab_reclaim_pages);
+
+		/*
+		 * Leave the last 3% for root
+		 */
+		if (!cap_sys_admin)
+			free -= free / 32;
+
+		if (free > pages)
+			return 0;
+
+		/*
+		 * nr_free_pages() is very expensive on large systems,
+		 * only call if we're about to fail.
+		 */
+		n = nr_free_pages();
+		if (!cap_sys_admin)
+			n -= n / 32;
+		free += n;
+
+		if (free > pages)
+			return 0;
+		vm_unacct_memory(pages);
+		return -ENOMEM;
+	}
+
+	allowed = totalram_pages * sysctl_overcommit_ratio / 100;
+	/*
+	 * Leave the last 3% for root
+	 */
+	if (!cap_sys_admin)
+		allowed -= allowed / 32;
+	allowed += total_swap_pages;
+
+	/* Don't let a single process grow too big:
+	   leave 3% of the size of this process for other processes */
+	allowed -= current->mm->total_vm / 32;
+
+	if (atomic_read(&vm_committed_space) < allowed)
+		return 0;
+
+	vm_unacct_memory(pages);
+
+	return -ENOMEM;
 }
 
diff -Nru a/mm/oom_kill.c b/mm/oom_kill.c
--- a/mm/oom_kill.c	2005-03-01 23:38:58 -08:00
+++ b/mm/oom_kill.c	2005-03-01 23:38:58 -08:00
@@ -42,26 +42,39 @@
  *    of least surprise ... (be careful when you change it)
  */
 
-static unsigned long badness(struct task_struct *p, unsigned long uptime)
+unsigned long badness(struct task_struct *p, unsigned long uptime)
 {
 	unsigned long points, cpu_time, run_time, s;
+	struct list_head *tsk;
 
 	if (!p->mm)
 		return 0;
 
-	if (p->flags & PF_MEMDIE)
-		return 0;
 	/*
 	 * The memory size of the process is the basis for the badness.
 	 */
 	points = p->mm->total_vm;
 
 	/*
+	 * Processes which fork a lot of child processes are likely
+	 * a good choice. We add the vmsize of the childs if they
+	 * have an own mm. This prevents forking servers to flood the
+	 * machine with an endless amount of childs
+	 */
+	list_for_each(tsk, &p->children) {
+		struct task_struct *chld;
+		chld = list_entry(tsk, struct task_struct, sibling);
+		if (chld->mm != p->mm && chld->mm)
+			points += chld->mm->total_vm;
+	}
+
+	/*
 	 * CPU time is in tens of seconds and run time is in thousands
          * of seconds. There is no particular reason for this other than
          * that it turned out to work very well in practice.
 	 */
-	cpu_time = (p->utime + p->stime) >> (SHIFT_HZ + 3);
+	cpu_time = (cputime_to_jiffies(p->utime) + cputime_to_jiffies(p->stime))
+		>> (SHIFT_HZ + 3);
 
 	if (uptime >= p->start_time.tv_sec)
 		run_time = (uptime - p->start_time.tv_sec) >> 10;
@@ -98,6 +111,17 @@
 	 */
 	if (cap_t(p->cap_effective) & CAP_TO_MASK(CAP_SYS_RAWIO))
 		points /= 4;
+
+	/*
+	 * Adjust the score by oomkilladj.
+	 */
+	if (p->oomkilladj) {
+		if (p->oomkilladj > 0)
+			points <<= p->oomkilladj;
+		else
+			points >>= -(p->oomkilladj);
+	}
+
 #ifdef DEBUG
 	printk(KERN_DEBUG "OOMkill: task %d (%s) got %d points\n",
 	p->pid, p->comm, points);
@@ -120,14 +144,25 @@
 
 	do_posix_clock_monotonic_gettime(&uptime);
 	do_each_thread(g, p)
-		if (p->pid) {
-			unsigned long points = badness(p, uptime.tv_sec);
-			if (points > maxpoints) {
+		/* skip the init task with pid == 1 */
+		if (p->pid > 1) {
+			unsigned long points;
+
+			/*
+			 * This is in the process of releasing memory so wait it
+			 * to finish before killing some other task by mistake.
+			 */
+			if ((unlikely(test_tsk_thread_flag(p, TIF_MEMDIE)) || (p->flags & PF_EXITING)) &&
+			    !(p->flags & PF_DEAD))
+				return ERR_PTR(-1UL);
+			if (p->flags & PF_SWAPOFF)
+				return p;
+
+			points = badness(p, uptime.tv_sec);
+			if (points > maxpoints || !chosen) {
 				chosen = p;
 				maxpoints = points;
 			}
-			if (p->flags & PF_SWAPOFF)
-				return p;
 		}
 	while_each_thread(g, p);
 	return chosen;
@@ -140,6 +175,12 @@
  */
 static void __oom_kill_task(task_t *p)
 {
+	if (p->pid == 1) {
+		WARN_ON(1);
+		printk(KERN_WARNING "tried to kill init!\n");
+		return;
+	}
+
 	task_lock(p);
 	if (!p->mm || p->mm == &init_mm) {
 		WARN_ON(1);
@@ -156,25 +197,53 @@
 	 * exit() and clear out its resources quickly...
 	 */
 	p->time_slice = HZ;
-	p->flags |= PF_MEMALLOC | PF_MEMDIE;
+	set_tsk_thread_flag(p, TIF_MEMDIE);
 
-	/* This process has hardware access, be more careful. */
-	if (cap_t(p->cap_effective) & CAP_TO_MASK(CAP_SYS_RAWIO)) {
-		force_sig(SIGTERM, p);
-	} else {
-		force_sig(SIGKILL, p);
-	}
+	force_sig(SIGKILL, p);
 }
 
 static struct mm_struct *oom_kill_task(task_t *p)
 {
 	struct mm_struct *mm = get_task_mm(p);
-	if (!mm || mm == &init_mm)
+	task_t * g, * q;
+
+	if (!mm)
+		return NULL;
+	if (mm == &init_mm) {
+		mmput(mm);
 		return NULL;
+	}
+
 	__oom_kill_task(p);
+	/*
+	 * kill all processes that share the ->mm (i.e. all threads),
+	 * but are in a different thread group
+	 */
+	do_each_thread(g, q)
+		if (q->mm == mm && q->tgid != p->tgid)
+			__oom_kill_task(q);
+	while_each_thread(g, q);
+
 	return mm;
 }
 
+static struct mm_struct *oom_kill_process(struct task_struct *p)
+{
+ 	struct mm_struct *mm;
+	struct task_struct *c;
+	struct list_head *tsk;
+
+	/* Try to kill a child first */
+	list_for_each(tsk, &p->children) {
+		c = list_entry(tsk, struct task_struct, sibling);
+		if (c->mm == p->mm)
+			continue;
+		mm = oom_kill_task(c);
+		if (mm)
+			return mm;
+	}
+	return oom_kill_task(p);
+}
 
 /**
  * oom_kill - kill the "best" process when we run out of memory
@@ -184,117 +253,40 @@
  * 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.
  */
-static void oom_kill(void)
+void out_of_memory(int gfp_mask)
 {
-	struct mm_struct *mm;
-	struct task_struct *g, *p, *q;
-	
+	struct mm_struct *mm = NULL;
+	task_t * p;
+
 	read_lock(&tasklist_lock);
 retry:
 	p = select_bad_process();
 
+	if (PTR_ERR(p) == -1UL)
+		goto out;
+
 	/* 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");
 	}
 
-	mm = oom_kill_task(p);
+	printk("oom-killer: gfp_mask=0x%x\n", gfp_mask);
+	show_free_areas();
+	mm = oom_kill_process(p);
 	if (!mm)
 		goto retry;
-	/*
-	 * kill all processes that share the ->mm (i.e. all threads),
-	 * but are in a different thread group
-	 */
-	do_each_thread(g, q)
-		if (q->mm == mm && q->tgid != p->tgid)
-			__oom_kill_task(q);
-	while_each_thread(g, q);
-	if (!p->mm)
-		printk(KERN_INFO "Fixed up OOM kill of mm-less task\n");
-	read_unlock(&tasklist_lock);
-	mmput(mm);
-
-	/*
-	 * Make kswapd go out of the way, so "p" has a good chance of
-	 * killing itself before someone else gets the chance to ask
-	 * for more memory.
-	 */
-	yield();
-	return;
-}
-
-/**
- * out_of_memory - is the system out of memory?
- */
-void out_of_memory(int gfp_mask)
-{
-	/*
-	 * oom_lock protects out_of_memory()'s static variables.
-	 * It's a global lock; this is not performance-critical.
-	 */
-	static spinlock_t oom_lock = SPIN_LOCK_UNLOCKED;
-	static unsigned long first, last, count, lastkill;
-	unsigned long now, since;
-
-	spin_lock(&oom_lock);
-	now = jiffies;
-	since = now - last;
-	last = now;
-
-	/*
-	 * If it's been a long time since last failure,
-	 * we're not oom.
-	 */
-	if (since > 5*HZ)
-		goto reset;
-
-	/*
-	 * If we haven't tried for at least one second,
-	 * we're not really oom.
-	 */
-	since = now - first;
-	if (since < HZ)
-		goto out_unlock;
-
-	/*
-	 * If we have gotten only a few failures,
-	 * we're not really oom. 
-	 */
-	if (++count < 10)
-		goto out_unlock;
 
-	/*
-	 * If we just killed a process, wait a while
-	 * to give that task a chance to exit. This
-	 * avoids killing multiple processes needlessly.
-	 */
-	since = now - lastkill;
-	if (since < HZ*5)
-		goto out_unlock;
+ out:
+	read_unlock(&tasklist_lock);
+	if (mm)
+		mmput(mm);
 
 	/*
-	 * Ok, really out of memory. Kill something.
+	 * Give "p" a good chance of killing itself before we
+	 * retry to allocate memory.
 	 */
-	lastkill = now;
-
-	printk("oom-killer: gfp_mask=0x%x\n", gfp_mask);
-	show_free_areas();
-
-	/* oom_kill() sleeps */
-	spin_unlock(&oom_lock);
-	oom_kill();
-	spin_lock(&oom_lock);
-
-reset:
-	/*
-	 * We dropped the lock above, so check to be sure the variable
-	 * first only ever increases to prevent false OOM's.
-	 */
-	if (time_after(now, first))
-		first = now;
-	count = 0;
-
-out_unlock:
-	spin_unlock(&oom_lock);
+	__set_current_state(TASK_INTERRUPTIBLE);
+	schedule_timeout(1);
 }
diff -Nru a/mm/page-writeback.c b/mm/page-writeback.c
--- a/mm/page-writeback.c	2005-03-01 23:39:07 -08:00
+++ b/mm/page-writeback.c	2005-03-01 23:39:07 -08:00
@@ -133,17 +133,29 @@
  * clamping level.
  */
 static void
-get_dirty_limits(struct writeback_state *wbs, long *pbackground, long *pdirty)
+get_dirty_limits(struct writeback_state *wbs, long *pbackground, long *pdirty,
+		struct address_space *mapping)
 {
 	int background_ratio;		/* Percentages */
 	int dirty_ratio;
 	int unmapped_ratio;
 	long background;
 	long dirty;
+	unsigned long available_memory = total_pages;
 	struct task_struct *tsk;
 
 	get_writeback_state(wbs);
 
+#ifdef CONFIG_HIGHMEM
+	/*
+	 * If this mapping can only allocate from low memory,
+	 * we exclude high memory from our count.
+	 */
+	if (mapping && !(mapping_gfp_mask(mapping) & __GFP_HIGHMEM))
+		available_memory -= totalhigh_pages;
+#endif
+
+
 	unmapped_ratio = 100 - (wbs->nr_mapped * 100) / total_pages;
 
 	dirty_ratio = vm_dirty_ratio;
@@ -157,8 +169,8 @@
 	if (background_ratio >= dirty_ratio)
 		background_ratio = dirty_ratio / 2;
 
-	background = (background_ratio * total_pages) / 100;
-	dirty = (dirty_ratio * total_pages) / 100;
+	background = (background_ratio * available_memory) / 100;
+	dirty = (dirty_ratio * available_memory) / 100;
 	tsk = current;
 	if (tsk->flags & PF_LESS_THROTTLE || rt_task(tsk)) {
 		background += background / 4;
@@ -194,7 +206,8 @@
 			.nr_to_write	= write_chunk,
 		};
 
-		get_dirty_limits(&wbs, &background_thresh, &dirty_thresh);
+		get_dirty_limits(&wbs, &background_thresh,
+					&dirty_thresh, mapping);
 		nr_reclaimable = wbs.nr_dirty + wbs.nr_unstable;
 		if (nr_reclaimable + wbs.nr_writeback <= dirty_thresh)
 			break;
@@ -210,7 +223,7 @@
 		if (nr_reclaimable) {
 			writeback_inodes(&wbc);
 			get_dirty_limits(&wbs, &background_thresh,
-					&dirty_thresh);
+					&dirty_thresh, mapping);
 			nr_reclaimable = wbs.nr_dirty + wbs.nr_unstable;
 			if (nr_reclaimable + wbs.nr_writeback <= dirty_thresh)
 				break;
@@ -296,7 +309,7 @@
 		long background_thresh;
 		long dirty_thresh;
 
-		get_dirty_limits(&wbs, &background_thresh, &dirty_thresh);
+		get_dirty_limits(&wbs, &background_thresh, &dirty_thresh, NULL);
 		if (wbs.nr_dirty + wbs.nr_unstable < background_thresh
 				&& min_pages <= 0)
 			break;
diff -Nru a/mm/page_alloc.c b/mm/page_alloc.c
--- a/mm/page_alloc.c	2005-03-01 23:38:52 -08:00
+++ b/mm/page_alloc.c	2005-03-01 23:38:52 -08:00
@@ -32,17 +32,27 @@
 #include <linux/sysctl.h>
 #include <linux/cpu.h>
 #include <linux/nodemask.h>
+#include <linux/vmalloc.h>
 
 #include <asm/tlbflush.h>
+#include "internal.h"
 
-nodemask_t node_online_map = NODE_MASK_NONE;
+/* MCD - HACK: Find somewhere to initialize this EARLY, or make this initializer cleaner */
+nodemask_t node_online_map = { { [0] = 1UL } };
 nodemask_t node_possible_map = NODE_MASK_ALL;
 struct pglist_data *pgdat_list;
 unsigned long totalram_pages;
 unsigned long totalhigh_pages;
 long nr_swap_pages;
-int numnodes = 1;
-int sysctl_lower_zone_protection = 0;
+/*
+ * results with 256, 32 in the lowmem_reserve sysctl:
+ *	1G machine -> (16M dma, 800M-16M normal, 1G-800M high)
+ *	1G machine -> (16M dma, 784M normal, 224M high)
+ *	NORMAL allocation will leave 784M/256 of ram reserved in the ZONE_DMA
+ *	HIGHMEM allocation will leave 224M/32 of ram reserved in ZONE_NORMAL
+ *	HIGHMEM allocation will (224M+784M)/256 of ram reserved in ZONE_DMA
+ */
+int sysctl_lowmem_reserve_ratio[MAX_NR_ZONES-1] = { 256, 32 };
 
 EXPORT_SYMBOL(totalram_pages);
 EXPORT_SYMBOL(nr_swap_pages);
@@ -69,6 +79,10 @@
 		return 1;
 	if (page_to_pfn(page) < zone->zone_start_pfn)
 		return 1;
+#ifdef CONFIG_HOLES_IN_ZONE
+	if (!pfn_valid(page_to_pfn(page)))
+		return 1;
+#endif
 	if (zone != page_zone(page))
 		return 1;
 	return 0;
@@ -157,6 +171,45 @@
 #endif		/* CONFIG_HUGETLB_PAGE */
 
 /*
+ * function for dealing with page's order in buddy system.
+ * zone->lock is already acquired when we use these.
+ * So, we don't need atomic page->flags operations here.
+ */
+static inline unsigned long page_order(struct page *page) {
+	return page->private;
+}
+
+static inline void set_page_order(struct page *page, int order) {
+	page->private = order;
+	__SetPagePrivate(page);
+}
+
+static inline void rmv_page_order(struct page *page)
+{
+	__ClearPagePrivate(page);
+	page->private = 0;
+}
+
+/*
+ * This function checks whether a page is free && is the buddy
+ * we can do coalesce a page and its buddy if
+ * (a) the buddy is free &&
+ * (b) the buddy is on the buddy system &&
+ * (c) a page and its buddy have the same order.
+ * for recording page's order, we use page->private and PG_private.
+ *
+ */
+static inline int page_is_buddy(struct page *page, int order)
+{
+       if (PagePrivate(page)           &&
+           (page_order(page) == order) &&
+           !PageReserved(page)         &&
+            page_count(page) == 0)
+               return 1;
+       return 0;
+}
+
+/*
  * Freeing function for a buddy system allocator.
  *
  * The concept of a buddy system is to maintain direct-mapped table
@@ -168,9 +221,10 @@
  * at the bottom level available, and propagating the changes upward
  * as necessary, plus some accounting needed to play nicely with other
  * parts of the VM system.
- * At each level, we keep one bit for each pair of blocks, which
- * is set to 1 iff only one of the pair is allocated.  So when we
- * are allocating or freeing one, we can derive the state of the
+ * At each level, we keep a list of pages, which are heads of continuous
+ * free pages of length of (1 << order) and marked with PG_Private.Page's
+ * order is recorded in page->private field.
+ * So when we are allocating or freeing one, we can derive the state of the
  * other.  That is, if we allocate a small block, and both were   
  * free, the remainder of the region must be split into blocks.   
  * If a block is freed, and its buddy is also free, then this
@@ -180,42 +234,44 @@
  */
 
 static inline void __free_pages_bulk (struct page *page, struct page *base,
-		struct zone *zone, struct free_area *area, unsigned int order)
+		struct zone *zone, unsigned int order)
 {
-	unsigned long page_idx, index, mask;
+	unsigned long page_idx;
+	struct page *coalesced;
+	int order_size = 1 << order;
 
-	if (order)
+	if (unlikely(order))
 		destroy_compound_page(page, order);
-	mask = (~0UL) << order;
+
 	page_idx = page - base;
-	if (page_idx & ~mask)
-		BUG();
-	index = page_idx >> (1 + order);
 
-	zone->free_pages += 1 << order;
-	while (order < MAX_ORDER-1) {
-		struct page *buddy1, *buddy2;
+	BUG_ON(page_idx & (order_size - 1));
+	BUG_ON(bad_range(zone, page));
 
-		BUG_ON(area >= zone->free_area + MAX_ORDER);
-		if (!__test_and_change_bit(index, area->map))
-			/*
-			 * the buddy page is still allocated.
-			 */
+	zone->free_pages += order_size;
+	while (order < MAX_ORDER-1) {
+		struct free_area *area;
+		struct page *buddy;
+		int buddy_idx;
+
+		buddy_idx = (page_idx ^ (1 << order));
+		buddy = base + buddy_idx;
+		if (bad_range(zone, buddy))
+			break;
+		if (!page_is_buddy(buddy, order))
 			break;
-
 		/* Move the buddy up one level. */
-		buddy1 = base + (page_idx ^ (1 << order));
-		buddy2 = base + page_idx;
-		BUG_ON(bad_range(zone, buddy1));
-		BUG_ON(bad_range(zone, buddy2));
-		list_del(&buddy1->lru);
-		mask <<= 1;
+		list_del(&buddy->lru);
+		area = zone->free_area + order;
+		area->nr_free--;
+		rmv_page_order(buddy);
+		page_idx &= buddy_idx;
 		order++;
-		area++;
-		index >>= 1;
-		page_idx &= mask;
 	}
-	list_add(&(base + page_idx)->lru, &area->free_list);
+	coalesced = base + page_idx;
+	set_page_order(coalesced, order);
+	list_add(&coalesced->lru, &zone->free_area[order].free_list);
+	zone->free_area[order].nr_free++;
 }
 
 static inline void free_pages_check(const char *function, struct page *page)
@@ -253,12 +309,10 @@
 		struct list_head *list, unsigned int order)
 {
 	unsigned long flags;
-	struct free_area *area;
 	struct page *base, *page = NULL;
 	int ret = 0;
 
 	base = zone->zone_mem_map;
-	area = zone->free_area + order;
 	spin_lock_irqsave(&zone->lock, flags);
 	zone->all_unreclaimable = 0;
 	zone->pages_scanned = 0;
@@ -266,7 +320,7 @@
 		page = list_entry(list->prev, struct page, lru);
 		/* have to delete it as __free_pages_bulk list manipulates */
 		list_del(&page->lru);
-		__free_pages_bulk(page, base, zone, area, order);
+		__free_pages_bulk(page, base, zone, order);
 		ret++;
 	}
 	spin_unlock_irqrestore(&zone->lock, flags);
@@ -281,6 +335,13 @@
 	arch_free_page(page, order);
 
 	mod_page_state(pgfree, 1 << order);
+
+#ifndef CONFIG_MMU
+	if (order > 0)
+		for (i = 1 ; i < (1 << order) ; ++i)
+			__put_page(page + i);
+#endif
+
 	for (i = 0 ; i < (1 << order) ; ++i)
 		free_pages_check(__FUNCTION__, page + i);
 	list_add(&page->lru, &list);
@@ -288,8 +349,6 @@
 	free_pages_bulk(page_zone(page), 1, &list, order);
 }
 
-#define MARK_USED(index, order, area) \
-	__change_bit((index) >> (1+(order)), (area)->map)
 
 /*
  * The order of subdivision here is critical for the IO subsystem.
@@ -307,7 +366,7 @@
  */
 static inline struct page *
 expand(struct zone *zone, struct page *page,
-	 unsigned long index, int low, int high, struct free_area *area)
+ 	int low, int high, struct free_area *area)
 {
 	unsigned long size = 1 << high;
 
@@ -317,12 +376,13 @@
 		size >>= 1;
 		BUG_ON(bad_range(zone, &page[size]));
 		list_add(&page[size].lru, &area->free_list);
-		MARK_USED(index + size, high, area);
+		area->nr_free++;
+		set_page_order(&page[size], high);
 	}
 	return page;
 }
 
-static inline void set_page_refs(struct page *page, int order)
+void set_page_refs(struct page *page, int order)
 {
 #ifdef CONFIG_MMU
 	set_page_count(page, 1);
@@ -332,9 +392,10 @@
 	/*
 	 * We need to reference all the pages for this order, otherwise if
 	 * anyone accesses one of the pages with (get/put) it will be freed.
+	 * - eg: access_process_vm()
 	 */
 	for (i = 0; i < (1 << order); i++)
-		set_page_count(page+i, 1);
+		set_page_count(page + i, 1);
 #endif /* CONFIG_MMU */
 }
 
@@ -360,6 +421,7 @@
 			1 << PG_checked | 1 << PG_mappedtodisk);
 	page->private = 0;
 	set_page_refs(page, order);
+	kernel_map_pages(page, 1 << order, 1);
 }
 
 /* 
@@ -371,7 +433,6 @@
 	struct free_area * area;
 	unsigned int current_order;
 	struct page *page;
-	unsigned int index;
 
 	for (current_order = order; current_order < MAX_ORDER; ++current_order) {
 		area = zone->free_area + current_order;
@@ -380,11 +441,10 @@
 
 		page = list_entry(area->free_list.next, struct page, lru);
 		list_del(&page->lru);
-		index = page - zone->zone_mem_map;
-		if (current_order != MAX_ORDER-1)
-			MARK_USED(index, current_order, area);
+		rmv_page_order(page);
+		area->nr_free--;
 		zone->free_pages -= 1UL << order;
-		return expand(zone, page, index, order, current_order, area);
+		return expand(zone, page, order, current_order, area);
 	}
 
 	return NULL;
@@ -437,26 +497,30 @@
 #endif /* CONFIG_PM || CONFIG_HOTPLUG_CPU */
 
 #ifdef CONFIG_PM
-int is_head_of_free_region(struct page *page)
+
+void mark_free_pages(struct zone *zone)
 {
-        struct zone *zone = page_zone(page);
-        unsigned long flags;
+	unsigned long zone_pfn, flags;
 	int order;
 	struct list_head *curr;
 
-	/*
-	 * Should not matter as we need quiescent system for
-	 * suspend anyway, but...
-	 */
+	if (!zone->spanned_pages)
+		return;
+
 	spin_lock_irqsave(&zone->lock, flags);
+	for (zone_pfn = 0; zone_pfn < zone->spanned_pages; ++zone_pfn)
+		ClearPageNosaveFree(pfn_to_page(zone_pfn + zone->zone_start_pfn));
+
 	for (order = MAX_ORDER - 1; order >= 0; --order)
-		list_for_each(curr, &zone->free_area[order].free_list)
-			if (page == list_entry(curr, struct page, lru)) {
-				spin_unlock_irqrestore(&zone->lock, flags);
-				return 1 << order;
-			}
+		list_for_each(curr, &zone->free_area[order].free_list) {
+			unsigned long start_pfn, i;
+
+			start_pfn = page_to_pfn(list_entry(curr, struct page, lru));
+
+			for (i=0; i < (1<<order); i++)
+				SetPageNosaveFree(pfn_to_page(start_pfn+i));
+	}
 	spin_unlock_irqrestore(&zone->lock, flags);
-        return 0;
 }
 
 /*
@@ -535,12 +599,20 @@
 	free_hot_cold_page(page, 1);
 }
 
+static inline void prep_zero_page(struct page *page, int order, int gfp_flags)
+{
+	int i;
+
+	BUG_ON((gfp_flags & (__GFP_WAIT | __GFP_HIGHMEM)) == __GFP_HIGHMEM);
+	for(i = 0; i < (1 << order); i++)
+		clear_highpage(page + i);
+}
+
 /*
  * Really, prep_compound_page() should be called from __rmqueue_bulk().  But
  * we cheat by calling it from here, in the order > 0 path.  Saves a branch
  * or two.
  */
-
 static struct page *
 buffered_rmqueue(struct zone *zone, int order, int gfp_flags)
 {
@@ -575,6 +647,10 @@
 		BUG_ON(bad_range(zone, page));
 		mod_page_state_zone(zone, pgalloc, 1 << order);
 		prep_new_page(page, order);
+
+		if (gfp_flags & __GFP_ZERO)
+			prep_zero_page(page, order, gfp_flags);
+
 		if (order && (gfp_flags & __GFP_COMP))
 			prep_compound_page(page, order);
 	}
@@ -582,35 +658,53 @@
 }
 
 /*
+ * Return 1 if free pages are above 'mark'. This takes into account the order
+ * of the allocation.
+ */
+int zone_watermark_ok(struct zone *z, int order, unsigned long mark,
+		      int classzone_idx, int can_try_harder, int gfp_high)
+{
+	/* free_pages my go negative - that's OK */
+	long min = mark, free_pages = z->free_pages - (1 << order) + 1;
+	int o;
+
+	if (gfp_high)
+		min -= min / 2;
+	if (can_try_harder)
+		min -= min / 4;
+
+	if (free_pages <= min + z->lowmem_reserve[classzone_idx])
+		return 0;
+	for (o = 0; o < order; o++) {
+		/* At the next order, this order's pages become unavailable */
+		free_pages -= z->free_area[o].nr_free << o;
+
+		/* Require fewer higher order pages to be free */
+		min >>= 1;
+
+		if (free_pages <= min)
+			return 0;
+	}
+	return 1;
+}
+
+/*
  * This is the 'heart' of the zoned buddy allocator.
- *
- * Herein lies the mysterious "incremental min".  That's the
- *
- *	local_low = z->pages_low;
- *	min += local_low;
- *
- * thing.  The intent here is to provide additional protection to low zones for
- * allocation requests which _could_ use higher zones.  So a GFP_HIGHMEM
- * request is not allowed to dip as deeply into the normal zone as a GFP_KERNEL
- * request.  This preserves additional space in those lower zones for requests
- * which really do need memory from those zones.  It means that on a decent
- * sized machine, GFP_HIGHMEM and GFP_KERNEL requests basically leave the DMA
- * zone untouched.
  */
 struct page * fastcall
 __alloc_pages(unsigned int gfp_mask, unsigned int order,
 		struct zonelist *zonelist)
 {
 	const int wait = gfp_mask & __GFP_WAIT;
-	unsigned long min;
 	struct zone **zones, *z;
 	struct page *page;
 	struct reclaim_state reclaim_state;
 	struct task_struct *p = current;
 	int i;
-	int alloc_type;
+	int classzone_idx;
 	int do_retry;
 	int can_try_harder;
+	int did_some_progress;
 
 	might_sleep_if(wait);
 
@@ -628,13 +722,14 @@
 		return NULL;
 	}
 
-	alloc_type = zone_idx(zones[0]);
+	classzone_idx = zone_idx(zones[0]);
 
+ restart:
 	/* Go through the zonelist once, looking for a zone with enough free */
 	for (i = 0; (z = zones[i]) != NULL; i++) {
-		min = z->pages_low + (1<<order) + z->protection[alloc_type];
 
-		if (z->free_pages < min)
+		if (!zone_watermark_ok(z, order, z->pages_low,
+				       classzone_idx, 0, 0))
 			continue;
 
 		page = buffered_rmqueue(z, order, gfp_mask);
@@ -643,21 +738,16 @@
 	}
 
 	for (i = 0; (z = zones[i]) != NULL; i++)
-		wakeup_kswapd(z);
+		wakeup_kswapd(z, order);
 
 	/*
 	 * Go through the zonelist again. Let __GFP_HIGH and allocations
 	 * coming from realtime tasks to go deeper into reserves
 	 */
 	for (i = 0; (z = zones[i]) != NULL; i++) {
-		min = z->pages_min;
-		if (gfp_mask & __GFP_HIGH)
-			min /= 2;
-		if (can_try_harder)
-			min -= min / 4;
-		min += (1<<order) + z->protection[alloc_type];
-
-		if (z->free_pages < min)
+		if (!zone_watermark_ok(z, order, z->pages_min,
+				       classzone_idx, can_try_harder,
+				       gfp_mask & __GFP_HIGH))
 			continue;
 
 		page = buffered_rmqueue(z, order, gfp_mask);
@@ -666,7 +756,7 @@
 	}
 
 	/* This allocation should allow future memory freeing. */
-	if ((p->flags & (PF_MEMALLOC | PF_MEMDIE)) && !in_interrupt()) {
+	if (((p->flags & PF_MEMALLOC) || unlikely(test_thread_flag(TIF_MEMDIE))) && !in_interrupt()) {
 		/* go through the zonelist yet again, ignoring mins */
 		for (i = 0; (z = zones[i]) != NULL; i++) {
 			page = buffered_rmqueue(z, order, gfp_mask);
@@ -681,31 +771,56 @@
 		goto nopage;
 
 rebalance:
+	cond_resched();
+
 	/* We now go into synchronous reclaim */
 	p->flags |= PF_MEMALLOC;
 	reclaim_state.reclaimed_slab = 0;
 	p->reclaim_state = &reclaim_state;
 
-	try_to_free_pages(zones, gfp_mask, order);
+	did_some_progress = try_to_free_pages(zones, gfp_mask, order);
 
 	p->reclaim_state = NULL;
 	p->flags &= ~PF_MEMALLOC;
 
-	/* go through the zonelist yet one more time */
-	for (i = 0; (z = zones[i]) != NULL; i++) {
-		min = z->pages_min;
-		if (gfp_mask & __GFP_HIGH)
-			min /= 2;
-		if (can_try_harder)
-			min -= min / 4;
-		min += (1<<order) + z->protection[alloc_type];
+	cond_resched();
 
-		if (z->free_pages < min)
-			continue;
+	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,
+					       gfp_mask & __GFP_HIGH))
+				continue;
 
-		page = buffered_rmqueue(z, order, gfp_mask);
-		if (page)
-			goto got_pg;
+			page = buffered_rmqueue(z, order, gfp_mask);
+			if (page)
+				goto got_pg;
+		}
+	} else if ((gfp_mask & __GFP_FS) && !(gfp_mask & __GFP_NORETRY)) {
+		/*
+		 * 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_high,
+					       classzone_idx, 0, 0))
+				continue;
+
+			page = buffered_rmqueue(z, order, gfp_mask);
+			if (page)
+				goto got_pg;
+		}
+
+		out_of_memory(gfp_mask);
+		goto restart;
 	}
 
 	/*
@@ -737,7 +852,6 @@
 	return NULL;
 got_pg:
 	zone_statistics(zonelist, z);
-	kernel_map_pages(page, 1 << order, 1);
 	return page;
 }
 
@@ -767,12 +881,9 @@
 	 */
 	BUG_ON(gfp_mask & __GFP_HIGHMEM);
 
-	page = alloc_pages(gfp_mask, 0);
-	if (page) {
-		void *address = page_address(page);
-		clear_page(address);
-		return (unsigned long) address;
-	}
+	page = alloc_pages(gfp_mask | __GFP_ZERO, 0);
+	if (page)
+		return (unsigned long) page_address(page);
 	return 0;
 }
 
@@ -900,8 +1011,7 @@
  * The result is unavoidably approximate - it can change
  * during and after execution of this function.
  */
-DEFINE_PER_CPU(struct page_state, page_states) = {0};
-EXPORT_PER_CPU_SYMBOL(page_states);
+static DEFINE_PER_CPU(struct page_state, page_states) = {0};
 
 atomic_t nr_pagecache = ATOMIC_INIT(0);
 EXPORT_SYMBOL(nr_pagecache);
@@ -914,18 +1024,18 @@
 	int cpu = 0;
 
 	memset(ret, 0, sizeof(*ret));
+
+	cpu = first_cpu(cpu_online_map);
 	while (cpu < NR_CPUS) {
 		unsigned long *in, *out, off;
 
-		if (!cpu_possible(cpu)) {
-			cpu++;
-			continue;
-		}
-
 		in = (unsigned long *)&per_cpu(page_states, cpu);
-		cpu++;
-		if (cpu < NR_CPUS && cpu_possible(cpu))
+
+		cpu = next_cpu(cpu, cpu_online_map);
+
+		if (cpu < NR_CPUS)
 			prefetch(&per_cpu(page_states, cpu));
+
 		out = (unsigned long *)ret;
 		for (off = 0; off < nr; off++)
 			*out++ += *in++;
@@ -952,18 +1062,28 @@
 	unsigned long ret = 0;
 	int cpu;
 
-	for (cpu = 0; cpu < NR_CPUS; cpu++) {
+	for_each_online_cpu(cpu) {
 		unsigned long in;
 
-		if (!cpu_possible(cpu))
-			continue;
-
 		in = (unsigned long)&per_cpu(page_states, cpu) + offset;
 		ret += *((unsigned long *)in);
 	}
 	return ret;
 }
 
+void __mod_page_state(unsigned offset, unsigned long delta)
+{
+	unsigned long flags;
+	void* ptr;
+
+	local_irq_save(flags);
+	ptr = &__get_cpu_var(page_states);
+	*(unsigned long*)(ptr + offset) += delta;
+	local_irq_restore(flags);
+}
+
+EXPORT_SYMBOL(__mod_page_state);
+
 void __get_zone_counts(unsigned long *active, unsigned long *inactive,
 			unsigned long *free, struct pglist_data *pgdat)
 {
@@ -1117,14 +1237,13 @@
 			zone->pages_scanned,
 			(zone->all_unreclaimable ? "yes" : "no")
 			);
-		printk("protections[]:");
+		printk("lowmem_reserve[]:");
 		for (i = 0; i < MAX_NR_ZONES; i++)
-			printk(" %lu", zone->protection[i]);
+			printk(" %lu", zone->lowmem_reserve[i]);
 		printk("\n");
 	}
 
 	for_each_zone(zone) {
-		struct list_head *elem;
  		unsigned long nr, flags, order, total = 0;
 
 		show_node(zone);
@@ -1136,9 +1255,7 @@
 
 		spin_lock_irqsave(&zone->lock, flags);
 		for (order = 0; order < MAX_ORDER; order++) {
-			nr = 0;
-			list_for_each(elem, &zone->free_area[order].free_list)
-				++nr;
+			nr = zone->free_area[order].nr_free;
 			total += nr << order;
 			printk("%lu*%lukB ", nr, K(1UL) << order);
 		}
@@ -1180,13 +1297,13 @@
 }
 
 #ifdef CONFIG_NUMA
-#define MAX_NODE_LOAD (numnodes)
+#define MAX_NODE_LOAD (num_online_nodes())
 static int __initdata node_load[MAX_NUMNODES];
 /**
  * find_next_best_node - find the next node that should appear in a given
  *    node's fallback list
  * @node: node whose fallback list we're appending
- * @used_node_mask: pointer to the bitmap of already used nodes
+ * @used_node_mask: nodemask_t of already used nodes
  *
  * We use a number of factors to determine which is the next node that should
  * appear on a given node's fallback list.  The node should not have appeared
@@ -1197,24 +1314,24 @@
  * on them otherwise.
  * It returns -1 if no node is found.
  */
-static int __init find_next_best_node(int node, void *used_node_mask)
+static int __init find_next_best_node(int node, nodemask_t *used_node_mask)
 {
 	int i, n, val;
 	int min_val = INT_MAX;
 	int best_node = -1;
 
-	for (i = 0; i < numnodes; i++) {
+	for_each_online_node(i) {
 		cpumask_t tmp;
 
 		/* Start from local node */
-		n = (node+i)%numnodes;
+		n = (node+i) % num_online_nodes();
 
 		/* Don't want a node to appear more than once */
-		if (test_bit(n, used_node_mask))
+		if (node_isset(n, *used_node_mask))
 			continue;
 
 		/* Use the local node if we haven't already */
-		if (!test_bit(node, used_node_mask)) {
+		if (!node_isset(node, *used_node_mask)) {
 			best_node = node;
 			break;
 		}
@@ -1238,7 +1355,7 @@
 	}
 
 	if (best_node >= 0)
-		set_bit(best_node, used_node_mask);
+		node_set(best_node, *used_node_mask);
 
 	return best_node;
 }
@@ -1248,7 +1365,7 @@
 	int i, j, k, node, local_node;
 	int prev_node, load;
 	struct zonelist *zonelist;
-	DECLARE_BITMAP(used_mask, MAX_NUMNODES);
+	nodemask_t used_mask;
 
 	/* initialize zonelists */
 	for (i = 0; i < GFP_ZONETYPES; i++) {
@@ -1259,10 +1376,10 @@
 
 	/* NUMA-aware ordering of nodes */
 	local_node = pgdat->node_id;
-	load = numnodes;
+	load = num_online_nodes();
 	prev_node = local_node;
-	bitmap_zero(used_mask, MAX_NUMNODES);
-	while ((node = find_next_best_node(local_node, used_mask)) >= 0) {
+	nodes_clear(used_mask);
+	while ((node = find_next_best_node(local_node, &used_mask)) >= 0) {
 		/*
 		 * We don't want to pressure a particular node.
 		 * So adding penalty to the first node in same
@@ -1318,11 +1435,17 @@
  		 * zones coming right after the local ones are those from
  		 * node N+1 (modulo N)
  		 */
- 		for (node = local_node + 1; node < numnodes; node++)
- 			j = build_zonelists_node(NODE_DATA(node), zonelist, j, k);
- 		for (node = 0; node < local_node; node++)
- 			j = build_zonelists_node(NODE_DATA(node), zonelist, j, k);
- 
+		for (node = local_node + 1; node < MAX_NUMNODES; node++) {
+			if (!node_online(node))
+				continue;
+			j = build_zonelists_node(NODE_DATA(node), zonelist, j, k);
+		}
+		for (node = 0; node < local_node; node++) {
+			if (!node_online(node))
+				continue;
+			j = build_zonelists_node(NODE_DATA(node), zonelist, j, k);
+		}
+
 		zonelist->zones[j] = NULL;
 	}
 }
@@ -1333,9 +1456,9 @@
 {
 	int i;
 
-	for(i = 0 ; i < numnodes ; i++)
+	for_each_online_node(i)
 		build_zonelists(NODE_DATA(i));
-	printk("Built %i zonelists\n", numnodes);
+	printk("Built %i zonelists\n", num_online_nodes());
 }
 
 /*
@@ -1427,49 +1550,13 @@
 	}
 }
 
-/*
- * Page buddy system uses "index >> (i+1)", where "index" is
- * at most "size-1".
- *
- * The extra "+3" is to round down to byte size (8 bits per byte
- * assumption). Thus we get "(size-1) >> (i+4)" as the last byte
- * we can access.
- *
- * The "+1" is because we want to round the byte allocation up
- * rather than down. So we should have had a "+7" before we shifted
- * down by three. Also, we have to add one as we actually _use_ the
- * last bit (it's [0,n] inclusive, not [0,n[).
- *
- * So we actually had +7+1 before we shift down by 3. But
- * (n+8) >> 3 == (n >> 3) + 1 (modulo overflows, which we do not have).
- *
- * Finally, we LONG_ALIGN because all bitmap operations are on longs.
- */
-unsigned long pages_to_bitmap_size(unsigned long order, unsigned long nr_pages)
-{
-	unsigned long bitmap_size;
-
-	bitmap_size = (nr_pages-1) >> (order+4);
-	bitmap_size = LONG_ALIGN(bitmap_size+1);
-
-	return bitmap_size;
-}
-
-void zone_init_free_lists(struct pglist_data *pgdat, struct zone *zone, unsigned long size)
+void zone_init_free_lists(struct pglist_data *pgdat, struct zone *zone,
+				unsigned long size)
 {
 	int order;
-	for (order = 0; ; order++) {
-		unsigned long bitmap_size;
-
+	for (order = 0; order < MAX_ORDER ; order++) {
 		INIT_LIST_HEAD(&zone->free_area[order].free_list);
-		if (order == MAX_ORDER-1) {
-			zone->free_area[order].map = NULL;
-			break;
-		}
-
-		bitmap_size = pages_to_bitmap_size(order, size);
-		zone->free_area[order].map =
-		  (unsigned long *) alloc_bootmem_node(pgdat, bitmap_size);
+		zone->free_area[order].nr_free = 0;
 	}
 }
 
@@ -1494,6 +1581,7 @@
 
 	pgdat->nr_zones = 0;
 	init_waitqueue_head(&pgdat->kswapd_wait);
+	pgdat->kswapd_max_order = 0;
 	
 	for (j = 0; j < MAX_NR_ZONES; j++) {
 		struct zone *zone = pgdat->node_zones + j;
@@ -1581,7 +1669,7 @@
 		zone->zone_start_pfn = zone_start_pfn;
 
 		if ((zone_start_pfn) & (zone_required_alignment-1))
-			printk("BUG: wrong zone alignment, it will crash\n");
+			printk(KERN_CRIT "BUG: wrong zone alignment, it will crash\n");
 
 		memmap_init(size, nid, j, zone_start_pfn);
 
@@ -1657,8 +1745,7 @@
 }
 
 /* 
- * This walks the freelist for each zone. Whilst this is slow, I'd rather 
- * be slow here than slow down the fast path by keeping stats - mjbligh
+ * This walks the free areas for each zone.
  */
 static int frag_show(struct seq_file *m, void *arg)
 {
@@ -1674,14 +1761,8 @@
 
 		spin_lock_irqsave(&zone->lock, flags);
 		seq_printf(m, "Node %d, zone %8s ", pgdat->node_id, zone->name);
-		for (order = 0; order < MAX_ORDER; ++order) {
-			unsigned long nr_bufs = 0;
-			struct list_head *elem;
-
-			list_for_each(elem, &(zone->free_area[order].free_list))
-				++nr_bufs;
-			seq_printf(m, "%6lu ", nr_bufs);
-		}
+		for (order = 0; order < MAX_ORDER; ++order)
+			seq_printf(m, "%6lu ", zone->free_area[order].nr_free);
 		spin_unlock_irqrestore(&zone->lock, flags);
 		seq_putc(m, '\n');
 	}
@@ -1797,14 +1878,28 @@
 {
 	int cpu = (unsigned long)hcpu;
 	long *count;
+	unsigned long *src, *dest;
 
 	if (action == CPU_DEAD) {
+		int i;
+
 		/* Drain local pagecache count. */
 		count = &per_cpu(nr_pagecache_local, cpu);
 		atomic_add(*count, &nr_pagecache);
 		*count = 0;
 		local_irq_disable();
 		__drain_pages(cpu);
+
+		/* Add dead cpu's page_states to our own. */
+		dest = (unsigned long *)&__get_cpu_var(page_states);
+		src = (unsigned long *)&per_cpu(page_states, cpu);
+
+		for (i = 0; i < sizeof(struct page_state)/sizeof(unsigned long);
+				i++) {
+			dest[i] += src[i];
+			src[i] = 0;
+		}
+
 		local_irq_enable();
 	}
 	return NOTIFY_OK;
@@ -1816,87 +1911,29 @@
 	hotcpu_notifier(page_alloc_cpu_notify, 0);
 }
 
-static unsigned long higherzone_val(struct zone *z, int max_zone,
-					int alloc_type)
-{
-	int z_idx = zone_idx(z);
-	struct zone *higherzone;
-	unsigned long pages;
-
-	/* there is no higher zone to get a contribution from */
-	if (z_idx == MAX_NR_ZONES-1)
-		return 0;
-
-	higherzone = &z->zone_pgdat->node_zones[z_idx+1];
-
-	/* We always start with the higher zone's protection value */
-	pages = higherzone->protection[alloc_type];
-
-	/*
-	 * We get a lower-zone-protection contribution only if there are
-	 * pages in the higher zone and if we're not the highest zone
-	 * in the current zonelist.  e.g., never happens for GFP_DMA. Happens
-	 * only for ZONE_DMA in a GFP_KERNEL allocation and happens for ZONE_DMA
-	 * and ZONE_NORMAL for a GFP_HIGHMEM allocation.
-	 */
-	if (higherzone->present_pages && z_idx < alloc_type)
-		pages += higherzone->pages_low * sysctl_lower_zone_protection;
-
-	return pages;
-}
-
 /*
- * setup_per_zone_protection - called whenver min_free_kbytes or
- *	sysctl_lower_zone_protection changes.  Ensures that each zone
- *	has a correct pages_protected value, so an adequate number of
+ * setup_per_zone_lowmem_reserve - called whenever
+ *	sysctl_lower_zone_reserve_ratio changes.  Ensures that each zone
+ *	has a correct pages reserved value, so an adequate number of
  *	pages are left in the zone after a successful __alloc_pages().
- *
- *	This algorithm is way confusing.  I tries to keep the same behavior
- *	as we had with the incremental min iterative algorithm.
  */
-static void setup_per_zone_protection(void)
+static void setup_per_zone_lowmem_reserve(void)
 {
 	struct pglist_data *pgdat;
-	struct zone *zones, *zone;
-	int max_zone;
-	int i, j;
+	int j, idx;
 
 	for_each_pgdat(pgdat) {
-		zones = pgdat->node_zones;
+		for (j = 0; j < MAX_NR_ZONES; j++) {
+			struct zone * zone = pgdat->node_zones + j;
+			unsigned long present_pages = zone->present_pages;
 
-		for (i = 0, max_zone = 0; i < MAX_NR_ZONES; i++)
-			if (zones[i].present_pages)
-				max_zone = i;
+			zone->lowmem_reserve[j] = 0;
 
-		/*
-		 * For each of the different allocation types:
-		 * GFP_DMA -> GFP_KERNEL -> GFP_HIGHMEM
-		 */
-		for (i = 0; i < GFP_ZONETYPES; i++) {
-			/*
-			 * For each of the zones:
-			 * ZONE_HIGHMEM -> ZONE_NORMAL -> ZONE_DMA
-			 */
-			for (j = MAX_NR_ZONES-1; j >= 0; j--) {
-				zone = &zones[j];
+			for (idx = j-1; idx >= 0; idx--) {
+				struct zone * lower_zone = pgdat->node_zones + idx;
 
-				/*
-				 * We never protect zones that don't have memory
-				 * in them (j>max_zone) or zones that aren't in
-				 * the zonelists for a certain type of
-				 * allocation (j>=i).  We have to assign these
-				 * to zero because the lower zones take
-				 * contributions from the higher zones.
-				 */
-				if (j > max_zone || j >= i) {
-					zone->protection[i] = 0;
-					continue;
-				}
-				/*
-				 * The contribution of the next higher zone
-				 */
-				zone->protection[i] = higherzone_val(zone,
-								max_zone, i);
+				lower_zone->lowmem_reserve[j] = present_pages / sysctl_lowmem_reserve_ratio[idx];
+				present_pages += lower_zone->present_pages;
 			}
 		}
 	}
@@ -1991,7 +2028,7 @@
 	if (min_free_kbytes > 65536)
 		min_free_kbytes = 65536;
 	setup_per_zone_pages_min();
-	setup_per_zone_protection();
+	setup_per_zone_lowmem_reserve();
 	return 0;
 }
 module_init(init_per_zone_pages_min)
@@ -2006,44 +2043,62 @@
 {
 	proc_dointvec(table, write, file, buffer, length, ppos);
 	setup_per_zone_pages_min();
-	setup_per_zone_protection();
 	return 0;
 }
 
 /*
- * lower_zone_protection_sysctl_handler - just a wrapper around
- *	proc_dointvec() so that we can call setup_per_zone_protection()
- *	whenever sysctl_lower_zone_protection changes.
+ * lowmem_reserve_ratio_sysctl_handler - just a wrapper around
+ *	proc_dointvec() so that we can call setup_per_zone_lowmem_reserve()
+ *	whenever sysctl_lowmem_reserve_ratio changes.
+ *
+ * The reserve ratio obviously has absolutely no relation with the
+ * pages_min watermarks. The lowmem reserve ratio can only make sense
+ * if in function of the boot time zone sizes.
  */
-int lower_zone_protection_sysctl_handler(ctl_table *table, int write,
+int lowmem_reserve_ratio_sysctl_handler(ctl_table *table, int write,
 		 struct file *file, void __user *buffer, size_t *length, loff_t *ppos)
 {
 	proc_dointvec_minmax(table, write, file, buffer, length, ppos);
-	setup_per_zone_protection();
+	setup_per_zone_lowmem_reserve();
 	return 0;
 }
 
+__initdata int hashdist = HASHDIST_DEFAULT;
+
+#ifdef CONFIG_NUMA
+static int __init set_hashdist(char *str)
+{
+	if (!str)
+		return 0;
+	hashdist = simple_strtoul(str, &str, 0);
+	return 1;
+}
+__setup("hashdist=", set_hashdist);
+#endif
+
 /*
  * allocate a large system hash table from bootmem
  * - it is assumed that the hash table must contain an exact power-of-2
  *   quantity of entries
+ * - limit is the number of hash buckets, not the total allocation size
  */
 void *__init alloc_large_system_hash(const char *tablename,
 				     unsigned long bucketsize,
 				     unsigned long numentries,
 				     int scale,
-				     int consider_highmem,
+				     int flags,
 				     unsigned int *_hash_shift,
-				     unsigned int *_hash_mask)
+				     unsigned int *_hash_mask,
+				     unsigned long limit)
 {
-	unsigned long long max;
+	unsigned long long max = limit;
 	unsigned long log2qty, size;
-	void *table;
+	void *table = NULL;
 
 	/* allow the kernel cmdline to have a say */
 	if (!numentries) {
 		/* round applicable memory size up to nearest megabyte */
-		numentries = consider_highmem ? nr_all_pages : nr_kernel_pages;
+		numentries = (flags & HASH_HIGHMEM) ? nr_all_pages : nr_kernel_pages;
 		numentries += (1UL << (20 - PAGE_SHIFT)) - 1;
 		numentries >>= 20 - PAGE_SHIFT;
 		numentries <<= 20 - PAGE_SHIFT;
@@ -2057,9 +2112,11 @@
 	/* rounded up to nearest power of 2 in size */
 	numentries = 1UL << (long_log2(numentries) + 1);
 
-	/* limit allocation size to 1/16 total memory */
-	max = ((unsigned long long)nr_all_pages << PAGE_SHIFT) >> 4;
-	do_div(max, bucketsize);
+	/* limit allocation size to 1/16 total memory by default */
+	if (max == 0) {
+		max = ((unsigned long long)nr_all_pages << PAGE_SHIFT) >> 4;
+		do_div(max, bucketsize);
+	}
 
 	if (numentries > max)
 		numentries = max;
@@ -2068,7 +2125,16 @@
 
 	do {
 		size = bucketsize << log2qty;
-		table = alloc_bootmem(size);
+		if (flags & HASH_EARLY)
+			table = alloc_bootmem(size);
+		else if (hashdist)
+			table = __vmalloc(size, GFP_ATOMIC, PAGE_KERNEL);
+		else {
+			unsigned long order;
+			for (order = 0; ((1UL << order) << PAGE_SHIFT) < size; order++)
+				;
+			table = (void*) __get_free_pages(GFP_ATOMIC, order);
+		}
 	} while (!table && size > PAGE_SIZE && --log2qty);
 
 	if (!table)
diff -Nru a/mm/pdflush.c b/mm/pdflush.c
--- a/mm/pdflush.c	2005-03-01 23:39:18 -08:00
+++ b/mm/pdflush.c	2005-03-01 23:39:18 -08:00
@@ -17,7 +17,6 @@
 #include <linux/gfp.h>
 #include <linux/init.h>
 #include <linux/module.h>
-#include <linux/suspend.h>
 #include <linux/fs.h>		// Needed by writeback.h
 #include <linux/writeback.h>	// Prototypes pdflush_operation()
 #include <linux/kthread.h>
@@ -45,7 +44,7 @@
  * All the pdflush threads.  Protected by pdflush_lock
  */
 static LIST_HEAD(pdflush_list);
-static spinlock_t pdflush_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(pdflush_lock);
 
 /*
  * The count of currently-running pdflush threads.  Protected
@@ -106,8 +105,7 @@
 		spin_unlock_irq(&pdflush_lock);
 
 		schedule();
-		if (current->flags & PF_FREEZE) {
-			refrigerator(PF_FREEZE);
+		if (try_to_freeze(PF_FREEZE)) {
 			spin_lock_irq(&pdflush_lock);
 			continue;
 		}
diff -Nru a/mm/prio_tree.c b/mm/prio_tree.c
--- a/mm/prio_tree.c	2005-03-01 23:39:17 -08:00
+++ b/mm/prio_tree.c	2005-03-01 23:39:17 -08:00
@@ -11,473 +11,24 @@
  * 02Feb2004	Initial version
  */
 
-#include <linux/init.h>
-#include <linux/module.h>
 #include <linux/mm.h>
 #include <linux/prio_tree.h>
 
 /*
- * A clever mix of heap and radix trees forms a radix priority search tree (PST)
- * which is useful for storing intervals, e.g, we can consider a vma as a closed
- * interval of file pages [offset_begin, offset_end], and store all vmas that
- * map a file in a PST. Then, using the PST, we can answer a stabbing query,
- * i.e., selecting a set of stored intervals (vmas) that overlap with (map) a
- * given input interval X (a set of consecutive file pages), in "O(log n + m)"
- * time where 'log n' is the height of the PST, and 'm' is the number of stored
- * intervals (vmas) that overlap (map) with the input interval X (the set of
- * consecutive file pages).
- *
- * In our implementation, we store closed intervals of the form [radix_index,
- * heap_index]. We assume that always radix_index <= heap_index. McCreight's PST
- * is designed for storing intervals with unique radix indices, i.e., each
- * interval have different radix_index. However, this limitation can be easily
- * overcome by using the size, i.e., heap_index - radix_index, as part of the
- * index, so we index the tree using [(radix_index,size), heap_index].
- *
- * When the above-mentioned indexing scheme is used, theoretically, in a 32 bit
- * machine, the maximum height of a PST can be 64. We can use a balanced version
- * of the priority search tree to optimize the tree height, but the balanced
- * tree proposed by McCreight is too complex and memory-hungry for our purpose.
+ * See lib/prio_tree.c for details on the general radix priority search tree
+ * code.
  */
 
 /*
- * The following macros are used for implementing prio_tree for i_mmap
+ * The following #defines are mirrored from lib/prio_tree.c. They're only used
+ * for debugging, and should be removed (along with the debugging code using
+ * them) when switching also VMAs to the regular prio_tree code.
  */
 
 #define RADIX_INDEX(vma)  ((vma)->vm_pgoff)
 #define VMA_SIZE(vma)	  (((vma)->vm_end - (vma)->vm_start) >> PAGE_SHIFT)
 /* avoid overflow */
-#define HEAP_INDEX(vma)	  ((vma)->vm_pgoff + (VMA_SIZE(vma) - 1))
-
-#define GET_INDEX_VMA(vma, radix, heap)		\
-do {						\
-	radix = RADIX_INDEX(vma);		\
-	heap = HEAP_INDEX(vma);			\
-} while (0)
-
-#define GET_INDEX(node, radix, heap)		\
-do { 						\
-	struct vm_area_struct *__tmp = 		\
-	  prio_tree_entry(node, struct vm_area_struct, shared.prio_tree_node);\
-	GET_INDEX_VMA(__tmp, radix, heap); 	\
-} while (0)
-
-static unsigned long index_bits_to_maxindex[BITS_PER_LONG];
-
-void __init prio_tree_init(void)
-{
-	unsigned int i;
-
-	for (i = 0; i < ARRAY_SIZE(index_bits_to_maxindex) - 1; i++)
-		index_bits_to_maxindex[i] = (1UL << (i + 1)) - 1;
-	index_bits_to_maxindex[ARRAY_SIZE(index_bits_to_maxindex) - 1] = ~0UL;
-}
-
-/*
- * Maximum heap_index that can be stored in a PST with index_bits bits
- */
-static inline unsigned long prio_tree_maxindex(unsigned int bits)
-{
-	return index_bits_to_maxindex[bits - 1];
-}
-
-static void prio_tree_remove(struct prio_tree_root *, struct prio_tree_node *);
-
-/*
- * Extend a priority search tree so that it can store a node with heap_index
- * max_heap_index. In the worst case, this algorithm takes O((log n)^2).
- * However, this function is used rarely and the common case performance is
- * not bad.
- */
-static struct prio_tree_node *prio_tree_expand(struct prio_tree_root *root,
-		struct prio_tree_node *node, unsigned long max_heap_index)
-{
-	struct prio_tree_node *first = NULL, *prev, *last = NULL;
-
-	if (max_heap_index > prio_tree_maxindex(root->index_bits))
-		root->index_bits++;
-
-	while (max_heap_index > prio_tree_maxindex(root->index_bits)) {
-		root->index_bits++;
-
-		if (prio_tree_empty(root))
-			continue;
-
-		if (first == NULL) {
-			first = root->prio_tree_node;
-			prio_tree_remove(root, root->prio_tree_node);
-			INIT_PRIO_TREE_NODE(first);
-			last = first;
-		} else {
-			prev = last;
-			last = root->prio_tree_node;
-			prio_tree_remove(root, root->prio_tree_node);
-			INIT_PRIO_TREE_NODE(last);
-			prev->left = last;
-			last->parent = prev;
-		}
-	}
-
-	INIT_PRIO_TREE_NODE(node);
-
-	if (first) {
-		node->left = first;
-		first->parent = node;
-	} else
-		last = node;
-
-	if (!prio_tree_empty(root)) {
-		last->left = root->prio_tree_node;
-		last->left->parent = last;
-	}
-
-	root->prio_tree_node = node;
-	return node;
-}
-
-/*
- * Replace a prio_tree_node with a new node and return the old node
- */
-static struct prio_tree_node *prio_tree_replace(struct prio_tree_root *root,
-		struct prio_tree_node *old, struct prio_tree_node *node)
-{
-	INIT_PRIO_TREE_NODE(node);
-
-	if (prio_tree_root(old)) {
-		BUG_ON(root->prio_tree_node != old);
-		/*
-		 * We can reduce root->index_bits here. However, it is complex
-		 * and does not help much to improve performance (IMO).
-		 */
-		node->parent = node;
-		root->prio_tree_node = node;
-	} else {
-		node->parent = old->parent;
-		if (old->parent->left == old)
-			old->parent->left = node;
-		else
-			old->parent->right = node;
-	}
-
-	if (!prio_tree_left_empty(old)) {
-		node->left = old->left;
-		old->left->parent = node;
-	}
-
-	if (!prio_tree_right_empty(old)) {
-		node->right = old->right;
-		old->right->parent = node;
-	}
-
-	return old;
-}
-
-/*
- * Insert a prio_tree_node @node into a radix priority search tree @root. The
- * algorithm typically takes O(log n) time where 'log n' is the number of bits
- * required to represent the maximum heap_index. In the worst case, the algo
- * can take O((log n)^2) - check prio_tree_expand.
- *
- * If a prior node with same radix_index and heap_index is already found in
- * the tree, then returns the address of the prior node. Otherwise, inserts
- * @node into the tree and returns @node.
- */
-static struct prio_tree_node *prio_tree_insert(struct prio_tree_root *root,
-		struct prio_tree_node *node)
-{
-	struct prio_tree_node *cur, *res = node;
-	unsigned long radix_index, heap_index;
-	unsigned long r_index, h_index, index, mask;
-	int size_flag = 0;
-
-	GET_INDEX(node, radix_index, heap_index);
-
-	if (prio_tree_empty(root) ||
-			heap_index > prio_tree_maxindex(root->index_bits))
-		return prio_tree_expand(root, node, heap_index);
-
-	cur = root->prio_tree_node;
-	mask = 1UL << (root->index_bits - 1);
-
-	while (mask) {
-		GET_INDEX(cur, r_index, h_index);
-
-		if (r_index == radix_index && h_index == heap_index)
-			return cur;
-
-                if (h_index < heap_index ||
-		    (h_index == heap_index && r_index > radix_index)) {
-			struct prio_tree_node *tmp = node;
-			node = prio_tree_replace(root, cur, node);
-			cur = tmp;
-			/* swap indices */
-			index = r_index;
-			r_index = radix_index;
-			radix_index = index;
-			index = h_index;
-			h_index = heap_index;
-			heap_index = index;
-		}
-
-		if (size_flag)
-			index = heap_index - radix_index;
-		else
-			index = radix_index;
-
-		if (index & mask) {
-			if (prio_tree_right_empty(cur)) {
-				INIT_PRIO_TREE_NODE(node);
-				cur->right = node;
-				node->parent = cur;
-				return res;
-			} else
-				cur = cur->right;
-		} else {
-			if (prio_tree_left_empty(cur)) {
-				INIT_PRIO_TREE_NODE(node);
-				cur->left = node;
-				node->parent = cur;
-				return res;
-			} else
-				cur = cur->left;
-		}
-
-		mask >>= 1;
-
-		if (!mask) {
-			mask = 1UL << (BITS_PER_LONG - 1);
-			size_flag = 1;
-		}
-	}
-	/* Should not reach here */
-	BUG();
-	return NULL;
-}
-
-/*
- * Remove a prio_tree_node @node from a radix priority search tree @root. The
- * algorithm takes O(log n) time where 'log n' is the number of bits required
- * to represent the maximum heap_index.
- */
-static void prio_tree_remove(struct prio_tree_root *root,
-		struct prio_tree_node *node)
-{
-	struct prio_tree_node *cur;
-	unsigned long r_index, h_index_right, h_index_left;
-
-	cur = node;
-
-	while (!prio_tree_left_empty(cur) || !prio_tree_right_empty(cur)) {
-		if (!prio_tree_left_empty(cur))
-			GET_INDEX(cur->left, r_index, h_index_left);
-		else {
-			cur = cur->right;
-			continue;
-		}
-
-		if (!prio_tree_right_empty(cur))
-			GET_INDEX(cur->right, r_index, h_index_right);
-		else {
-			cur = cur->left;
-			continue;
-		}
-
-		/* both h_index_left and h_index_right cannot be 0 */
-		if (h_index_left >= h_index_right)
-			cur = cur->left;
-		else
-			cur = cur->right;
-	}
-
-	if (prio_tree_root(cur)) {
-		BUG_ON(root->prio_tree_node != cur);
-		INIT_PRIO_TREE_ROOT(root);
-		return;
-	}
-
-	if (cur->parent->right == cur)
-		cur->parent->right = cur->parent;
-	else
-		cur->parent->left = cur->parent;
-
-	while (cur != node)
-		cur = prio_tree_replace(root, cur->parent, cur);
-}
-
-/*
- * Following functions help to enumerate all prio_tree_nodes in the tree that
- * overlap with the input interval X [radix_index, heap_index]. The enumeration
- * takes O(log n + m) time where 'log n' is the height of the tree (which is
- * proportional to # of bits required to represent the maximum heap_index) and
- * 'm' is the number of prio_tree_nodes that overlap the interval X.
- */
-
-static struct prio_tree_node *prio_tree_left(struct prio_tree_iter *iter,
-		unsigned long *r_index, unsigned long *h_index)
-{
-	if (prio_tree_left_empty(iter->cur))
-		return NULL;
-
-	GET_INDEX(iter->cur->left, *r_index, *h_index);
-
-	if (iter->r_index <= *h_index) {
-		iter->cur = iter->cur->left;
-		iter->mask >>= 1;
-		if (iter->mask) {
-			if (iter->size_level)
-				iter->size_level++;
-		} else {
-			if (iter->size_level) {
-				BUG_ON(!prio_tree_left_empty(iter->cur));
-				BUG_ON(!prio_tree_right_empty(iter->cur));
-				iter->size_level++;
-				iter->mask = ULONG_MAX;
-			} else {
-				iter->size_level = 1;
-				iter->mask = 1UL << (BITS_PER_LONG - 1);
-			}
-		}
-		return iter->cur;
-	}
-
-	return NULL;
-}
-
-static struct prio_tree_node *prio_tree_right(struct prio_tree_iter *iter,
-		unsigned long *r_index, unsigned long *h_index)
-{
-	unsigned long value;
-
-	if (prio_tree_right_empty(iter->cur))
-		return NULL;
-
-	if (iter->size_level)
-		value = iter->value;
-	else
-		value = iter->value | iter->mask;
-
-	if (iter->h_index < value)
-		return NULL;
-
-	GET_INDEX(iter->cur->right, *r_index, *h_index);
-
-	if (iter->r_index <= *h_index) {
-		iter->cur = iter->cur->right;
-		iter->mask >>= 1;
-		iter->value = value;
-		if (iter->mask) {
-			if (iter->size_level)
-				iter->size_level++;
-		} else {
-			if (iter->size_level) {
-				BUG_ON(!prio_tree_left_empty(iter->cur));
-				BUG_ON(!prio_tree_right_empty(iter->cur));
-				iter->size_level++;
-				iter->mask = ULONG_MAX;
-			} else {
-				iter->size_level = 1;
-				iter->mask = 1UL << (BITS_PER_LONG - 1);
-			}
-		}
-		return iter->cur;
-	}
-
-	return NULL;
-}
-
-static struct prio_tree_node *prio_tree_parent(struct prio_tree_iter *iter)
-{
-	iter->cur = iter->cur->parent;
-	if (iter->mask == ULONG_MAX)
-		iter->mask = 1UL;
-	else if (iter->size_level == 1)
-		iter->mask = 1UL;
-	else
-		iter->mask <<= 1;
-	if (iter->size_level)
-		iter->size_level--;
-	if (!iter->size_level && (iter->value & iter->mask))
-		iter->value ^= iter->mask;
-	return iter->cur;
-}
-
-static inline int overlap(struct prio_tree_iter *iter,
-		unsigned long r_index, unsigned long h_index)
-{
-	return iter->h_index >= r_index && iter->r_index <= h_index;
-}
-
-/*
- * prio_tree_first:
- *
- * Get the first prio_tree_node that overlaps with the interval [radix_index,
- * heap_index]. Note that always radix_index <= heap_index. We do a pre-order
- * traversal of the tree.
- */
-static struct prio_tree_node *prio_tree_first(struct prio_tree_iter *iter)
-{
-	struct prio_tree_root *root;
-	unsigned long r_index, h_index;
-
-	INIT_PRIO_TREE_ITER(iter);
-
-	root = iter->root;
-	if (prio_tree_empty(root))
-		return NULL;
-
-	GET_INDEX(root->prio_tree_node, r_index, h_index);
-
-	if (iter->r_index > h_index)
-		return NULL;
-
-	iter->mask = 1UL << (root->index_bits - 1);
-	iter->cur = root->prio_tree_node;
-
-	while (1) {
-		if (overlap(iter, r_index, h_index))
-			return iter->cur;
-
-		if (prio_tree_left(iter, &r_index, &h_index))
-			continue;
-
-		if (prio_tree_right(iter, &r_index, &h_index))
-			continue;
-
-		break;
-	}
-	return NULL;
-}
-
-/*
- * prio_tree_next:
- *
- * Get the next prio_tree_node that overlaps with the input interval in iter
- */
-static struct prio_tree_node *prio_tree_next(struct prio_tree_iter *iter)
-{
-	unsigned long r_index, h_index;
-
-repeat:
-	while (prio_tree_left(iter, &r_index, &h_index))
-		if (overlap(iter, r_index, h_index))
-			return iter->cur;
-
-	while (!prio_tree_right(iter, &r_index, &h_index)) {
-	    	while (!prio_tree_root(iter->cur) &&
-				iter->cur->parent->right == iter->cur)
-			prio_tree_parent(iter);
-
-		if (prio_tree_root(iter->cur))
-			return NULL;
-
-		prio_tree_parent(iter);
-	}
-
-	if (overlap(iter, r_index, h_index))
-		return iter->cur;
-
-	goto repeat;
-}
+#define HEAP_INDEX(vma)   ((vma)->vm_pgoff + (VMA_SIZE(vma) - 1))
 
 /*
  * Radix priority search tree for address_space->i_mmap
@@ -551,8 +102,8 @@
 
 	vma->shared.vm_set.head = NULL;
 
-	ptr = prio_tree_insert(root, &vma->shared.prio_tree_node);
-	if (ptr != &vma->shared.prio_tree_node) {
+	ptr = raw_prio_tree_insert(root, &vma->shared.prio_tree_node);
+	if (ptr != (struct prio_tree_node *) &vma->shared.prio_tree_node) {
 		old = prio_tree_entry(ptr, struct vm_area_struct,
 					shared.prio_tree_node);
 		vma_prio_tree_add(vma, old);
@@ -568,7 +119,7 @@
 		if (!vma->shared.vm_set.parent)
 			list_del_init(&vma->shared.vm_set.list);
 		else
-			prio_tree_remove(root, &vma->shared.prio_tree_node);
+			raw_prio_tree_remove(root, &vma->shared.prio_tree_node);
 	} else {
 		/* Leave this BUG_ON till prio_tree patch stabilizes */
 		BUG_ON(vma->shared.vm_set.head->shared.vm_set.head != vma);
@@ -583,7 +134,7 @@
 			} else
 				new_head = NULL;
 
-			prio_tree_replace(root, &vma->shared.prio_tree_node,
+			raw_prio_tree_replace(root, &vma->shared.prio_tree_node,
 					&head->shared.prio_tree_node);
 			head->shared.vm_set.head = new_head;
 			if (new_head)
@@ -620,7 +171,7 @@
 		/*
 		 * First call is with NULL vma
 		 */
-		ptr = prio_tree_first(iter);
+		ptr = prio_tree_next(iter);
 		if (ptr) {
 			next = prio_tree_entry(ptr, struct vm_area_struct,
 						shared.prio_tree_node);
diff -Nru a/mm/readahead.c b/mm/readahead.c
--- a/mm/readahead.c	2005-03-01 23:38:52 -08:00
+++ b/mm/readahead.c	2005-03-01 23:38:52 -08:00
@@ -35,7 +35,7 @@
 file_ra_state_init(struct file_ra_state *ra, struct address_space *mapping)
 {
 	ra->ra_pages = mapping->backing_dev_info->ra_pages;
-	ra->average = ra->ra_pages / 2;
+	ra->prev_page = -1;
 }
 
 /*
@@ -51,6 +51,56 @@
 	return (VM_MIN_READAHEAD * 1024) / PAGE_CACHE_SIZE;
 }
 
+static inline void ra_off(struct file_ra_state *ra)
+{
+	ra->start = 0;
+	ra->flags = 0;
+	ra->size = -1;
+	ra->ahead_start = 0;
+	ra->ahead_size = 0;
+	return;
+}
+
+/*
+ * Set the initial window size, round to next power of 2 and square
+ * for small size, x 4 for medium, and x 2 for large
+ * for 128k (32 page) max ra
+ * 1-8 page = 32k initial, > 8 page = 128k initial
+ */
+static unsigned long get_init_ra_size(unsigned long size, unsigned long max)
+{
+	unsigned long newsize = roundup_pow_of_two(size);
+
+	if (newsize <= max / 64)
+		newsize = newsize * newsize;
+	else if (newsize <= max / 4)
+		newsize = max / 4;
+	else
+		newsize = max;
+	return newsize;
+}
+
+/*
+ * Set the new window size, this is called only when I/O is to be submitted,
+ * not for each call to readahead.  If a cache miss occured, reduce next I/O
+ * size, else increase depending on how close to max we are.
+ */
+static unsigned long get_next_ra_size(unsigned long cur, unsigned long max,
+				unsigned long min, unsigned long * flags)
+{
+	unsigned long newsize;
+
+	if (*flags & RA_FLAG_MISS) {
+		newsize = max((cur - 2), min);
+		*flags &= ~RA_FLAG_MISS;
+	} else if (cur < max / 16) {
+		newsize = 4 * cur;
+	} else {
+		newsize = 2 * cur;
+	}
+	return min(newsize, max);
+}
+
 #define list_to_page(head) (list_entry((head)->prev, struct page, lru))
 
 /**
@@ -65,7 +115,7 @@
  * Hides the details of the LRU cache etc from the filesystems.
  */
 int read_cache_pages(struct address_space *mapping, struct list_head *pages,
-		 int (*filler)(void *, struct page *), void *data)
+			int (*filler)(void *, struct page *), void *data)
 {
 	struct page *page;
 	struct pagevec lru_pvec;
@@ -151,19 +201,16 @@
  * ahead_size:  Together, these form the "ahead window".
  * ra_pages:	The externally controlled max readahead for this fd.
  *
- * When readahead is in the "maximally shrunk" state (next_size == -1UL),
- * readahead is disabled.  In this state, prev_page and size are used, inside
- * handle_ra_miss(), to detect the resumption of sequential I/O.  Once there
- * has been a decent run of sequential I/O (defined by get_min_readahead),
- * readahead is reenabled.
+ * When readahead is in the off state (size == -1UL), readahead is disabled.
+ * In this state, prev_page is used to detect the resumption of sequential I/O.
  *
  * The readahead code manages two windows - the "current" and the "ahead"
  * windows.  The intent is that while the application is walking the pages
  * in the current window, I/O is underway on the ahead window.  When the
  * current window is fully traversed, it is replaced by the ahead window
  * and the ahead window is invalidated.  When this copying happens, the
- * new current window's pages are probably still locked.  When I/O has
- * completed, we submit a new batch of I/O, creating a new ahead window.
+ * new current window's pages are probably still locked.  So
+ * we submit a new batch of I/O immediately, creating a new ahead window.
  *
  * So:
  *
@@ -175,34 +222,25 @@
  *           ahead window.
  *
  * A `readahead hit' occurs when a read request is made against a page which is
- * inside the current window.  Hits are good, and the window size (next_size)
- * is grown aggressively when hits occur.  Two pages are added to the next
- * window size on each hit, which will end up doubling the next window size by
- * the time I/O is submitted for it.
- *
- * If readahead hits are more sparse (say, the application is only reading
- * every second page) then the window will build more slowly.
- *
- * On a readahead miss (the application seeked away) the readahead window is
- * shrunk by 25%.  We don't want to drop it too aggressively, because it is a
- * good assumption that an application which has built a good readahead window
- * will continue to perform linear reads.  Either at the new file position, or
- * at the old one after another seek.
+ * the next sequential page. Ahead windowe calculations are done only when it
+ * is time to submit a new IO.  The code ramps up the size agressively at first,
+ * but slow down as it approaches max_readhead.
  *
- * After enough misses, readahead is fully disabled. (next_size = -1UL).
+ * Any seek/ramdom IO will result in readahead being turned off.  It will resume
+ * at the first sequential access.
  *
  * There is a special-case: if the first page which the application tries to
  * read happens to be the first page of the file, it is assumed that a linear
- * read is about to happen and the window is immediately set to half of the
- * device maximum.
+ * read is about to happen and the window is immediately set to the initial size
+ * based on I/O request size and the max_readahead.
  * 
  * A page request at (start + size) is not a miss at all - it's just a part of
  * sequential file reading.
  *
- * This function is to be called for every page which is read, rather than when
- * it is time to perform readahead.  This is so the readahead algorithm can
- * centrally work out the access patterns.  This could be costly with many tiny
- * read()s, so we specifically optimise for that case with prev_page.
+ * This function is to be called for every read request, rather than when
+ * it is time to perform readahead.  It is called only oce for the entire I/O
+ * regardless of size unless readahead is unable to start enough I/O to satisfy
+ * the request (I/O request > max_readahead).
  */
 
 /*
@@ -211,9 +249,12 @@
  * behaviour which would occur if page allocations are causing VM writeback.
  * We really don't want to intermingle reads and writes like that.
  *
- * Returns the number of pages which actually had IO started against them.
+ * Returns the number of pages requested, or the maximum amount of I/O allowed.
+ *
+ * do_page_cache_readahead() returns -1 if it encountered request queue
+ * congestion.
  */
-static inline int
+static int
 __do_page_cache_readahead(struct address_space *mapping, struct file *filp,
 			unsigned long offset, unsigned long nr_to_read)
 {
@@ -300,6 +341,28 @@
 }
 
 /*
+ * Check how effective readahead is being.  If the amount of started IO is
+ * less than expected then the file is partly or fully in pagecache and
+ * readahead isn't helping.
+ *
+ */
+int check_ra_success(struct file_ra_state *ra, unsigned long nr_to_read,
+				 unsigned long actual)
+{
+	if (actual == 0) {
+		ra->cache_hit += nr_to_read;
+		if (ra->cache_hit >= VM_MAX_CACHE_HIT) {
+			ra_off(ra);
+			ra->flags |= RA_FLAG_INCACHE;
+			return 0;
+		}
+	} else {
+		ra->cache_hit=0;
+	}
+	return 1;
+}
+
+/*
  * This version skips the IO if the queue is read-congested, and will tell the
  * block layer to abandon the readahead if request allocation would block.
  *
@@ -309,256 +372,196 @@
 int do_page_cache_readahead(struct address_space *mapping, struct file *filp,
 			unsigned long offset, unsigned long nr_to_read)
 {
-	if (!bdi_read_congested(mapping->backing_dev_info))
-		return __do_page_cache_readahead(mapping, filp,
-						offset, nr_to_read);
-	return 0;
+	if (bdi_read_congested(mapping->backing_dev_info))
+		return -1;
+
+	return __do_page_cache_readahead(mapping, filp, offset, nr_to_read);
 }
 
 /*
- * Check how effective readahead is being.  If the amount of started IO is
- * less than expected then the file is partly or fully in pagecache and
- * readahead isn't helping.  Shrink the window.
- *
- * But don't shrink it too much - the application may read the same page
- * occasionally.
+ * Read 'nr_to_read' pages starting at page 'offset'. If the flag 'block'
+ * is set wait till the read completes.  Otherwise attempt to read without
+ * blocking.
+ * Returns 1 meaning 'success' if read is succesfull without switching off
+ * readhaead mode. Otherwise return failure.
  */
-static inline void
-check_ra_success(struct file_ra_state *ra, pgoff_t attempt,
-			pgoff_t actual, pgoff_t orig_next_size)
+static int
+blockable_page_cache_readahead(struct address_space *mapping, struct file *filp,
+			unsigned long offset, unsigned long nr_to_read,
+			struct file_ra_state *ra, int block)
 {
-	if (actual == 0) {
-		if (orig_next_size > 1) {
-			ra->next_size = orig_next_size - 1;
-			if (ra->ahead_size)
-				ra->ahead_size = ra->next_size;
-		} else {
-			ra->next_size = -1UL;
-			ra->size = 0;
-		}
+	int actual;
+
+	if (block) {
+		actual = __do_page_cache_readahead(mapping, filp,
+						offset, nr_to_read);
+	} else {
+		actual = do_page_cache_readahead(mapping, filp,
+						offset, nr_to_read);
+		if (actual == -1)
+			return 0;
 	}
+	return check_ra_success(ra, nr_to_read, actual);
 }
 
 /*
  * page_cache_readahead is the main function.  If performs the adaptive
  * readahead window size management and submits the readahead I/O.
  */
-void
+unsigned long
 page_cache_readahead(struct address_space *mapping, struct file_ra_state *ra,
-			struct file *filp, unsigned long offset)
+		     struct file *filp, unsigned long offset,
+		     unsigned long req_size)
 {
-	unsigned max;
-	unsigned orig_next_size;
-	unsigned actual;
-	int first_access=0;
-	unsigned long average;
+	unsigned long max, min;
+	unsigned long newsize = req_size;
+	unsigned long block;
 
 	/*
 	 * Here we detect the case where the application is performing
 	 * sub-page sized reads.  We avoid doing extra work and bogusly
 	 * perturbing the readahead window expansion logic.
-	 * If next_size is zero, this is the very first read for this
-	 * file handle, or the window is maximally shrunk.
+	 * If size is zero, there is no read ahead window so we need one
 	 */
-	if (offset == ra->prev_page) {
-		if (ra->next_size != 0)
-			goto out;
-	}
-
-	if (ra->next_size == -1UL)
-		goto out;	/* Maximally shrunk */
+	if (offset == ra->prev_page && req_size == 1 && ra->size != 0)
+		goto out;
 
 	max = get_max_readahead(ra);
-	if (max == 0)
-		goto out;	/* No readahead */
-
-	orig_next_size = ra->next_size;
+	min = get_min_readahead(ra);
+	newsize = min(req_size, max);
 
-	if (ra->next_size == 0) {
-		/*
-		 * Special case - first read.
-		 * We'll assume it's a whole-file read, and
-		 * grow the window fast.
-		 */
-		first_access=1;
-		ra->next_size = max / 2;
+	if (newsize == 0 || (ra->flags & RA_FLAG_INCACHE)) {
+		newsize = 1;
 		ra->prev_page = offset;
-		ra->currnt_wnd_hit++;
-		goto do_io;
+		goto out;	/* No readahead or file already in cache */
 	}
+	/*
+	 * Special case - first read.  We'll assume it's a whole-file read if
+	 * at start of file, and grow the window fast.  Or detect first
+	 * sequential access
+	 */
+	if ((ra->size == 0 && offset == 0)	/* first io and start of file */
+	    || (ra->size == -1 && ra->prev_page == offset - 1)) {
+		/* First sequential */
+		ra->prev_page  = offset + newsize - 1;
+		ra->size = get_init_ra_size(newsize, max);
+		ra->start = offset;
+		if (!blockable_page_cache_readahead(mapping, filp, offset,
+							 ra->size, ra, 1))
+			goto out;
 
-	ra->prev_page = offset;
-
-	if (offset >= ra->start && offset <= (ra->start + ra->size)) {
-		/*
-		 * A readahead hit.  Either inside the window, or one
-		 * page beyond the end.  Expand the next readahead size.
-		 */
-		ra->next_size += 2;
-
-		if (ra->currnt_wnd_hit <= (max * 2))
-			ra->currnt_wnd_hit++;
-	} else {
 		/*
-		 * A miss - lseek, pagefault, pread, etc.  Shrink the readahead
-		 * window.
+		 * If the request size is larger than our max readahead, we
+		 * at least want to be sure that we get 2 IOs in flight and
+		 * we know that we will definitly need the new I/O.
+		 * once we do this, subsequent calls should be able to overlap
+		 * IOs,* thus preventing stalls. so issue the ahead window
+		 * immediately.
 		 */
-		ra->next_size -= 2;
-
-		average = ra->average;
-		if (average < ra->currnt_wnd_hit) {
-			average++;
+		if (req_size >= max) {
+			ra->ahead_size = get_next_ra_size(ra->size, max, min,
+							  &ra->flags);
+			ra->ahead_start = ra->start + ra->size;
+			blockable_page_cache_readahead(mapping, filp,
+				 ra->ahead_start, ra->ahead_size, ra, 1);
 		}
-		ra->average = (average + ra->currnt_wnd_hit) / 2;
-		ra->currnt_wnd_hit = 1;
+		goto out;
 	}
 
-	if ((long)ra->next_size > (long)max)
-		ra->next_size = max;
-	if ((long)ra->next_size <= 0L) {
-		ra->next_size = -1UL;
-		ra->size = 0;
-		goto out;		/* Readahead is off */
+	/*
+	 * Now handle the random case:
+	 * partial page reads and first access were handled above,
+	 * so this must be the next page otherwise it is random
+	 */
+	if ((offset != (ra->prev_page+1) || (ra->size == 0))) {
+		ra_off(ra);
+		ra->prev_page  = offset + newsize - 1;
+		blockable_page_cache_readahead(mapping, filp, offset,
+				 newsize, ra, 1);
+		goto out;
 	}
 
 	/*
-	 * Is this request outside the current window?
+	 * If we get here we are doing sequential IO and this was not the first
+	 * occurence (ie we have an existing window)
 	 */
-	if (offset < ra->start || offset >= (ra->start + ra->size)) {
-		/*
-		 * A miss against the current window.  Have we merely
-		 * advanced into the ahead window?
-		 */
-		if (offset == ra->ahead_start) {
-			/*
-			 * Yes, we have.  The ahead window now becomes
-			 * the current window.
+
+	if (ra->ahead_start == 0) {	 /* no ahead window yet */
+		ra->ahead_size = get_next_ra_size(ra->size, max, min,
+						  &ra->flags);
+		ra->ahead_start = ra->start + ra->size;
+		block = ((offset + newsize -1) >= ra->ahead_start);
+		if (!blockable_page_cache_readahead(mapping, filp,
+		    ra->ahead_start, ra->ahead_size, ra, block)) {
+			/* A read failure in blocking mode, implies pages are
+			 * all cached. So we can safely assume we have taken
+			 * care of all the pages requested in this call. A read
+			 * failure in non-blocking mode, implies we are reading
+			 * more pages than requested in this call.  So we safely
+			 * assume we have taken care of all the pages requested
+			 * in this call.
+			 *
+			 * Just reset the ahead window in case we failed due to
+			 * congestion.  The ahead window will any way be closed
+			 * in case we failed due to exessive page cache hits.
 			 */
-			ra->start = ra->ahead_start;
-			ra->size = ra->ahead_size;
-			ra->prev_page = ra->start;
 			ra->ahead_start = 0;
 			ra->ahead_size = 0;
-
-			/*
-			 * Control now returns, probably to sleep until I/O
-			 * completes against the first ahead page.
-			 * When the second page in the old ahead window is
-			 * requested, control will return here and more I/O
-			 * will be submitted to build the new ahead window.
-			 */
 			goto out;
 		}
-do_io:
-		/*
-		 * This is the "unusual" path.  We come here during
-		 * startup or after an lseek.  We invalidate the
-		 * ahead window and get some I/O underway for the new
-		 * current window.
-		 */
-		if (!first_access) {
-			 /* Heuristic: there is a high probability
-			  * that around  ra->average number of
-			  * pages shall be accessed in the next
-			  * current window.
-			  */
-			average = ra->average;
-			if (ra->currnt_wnd_hit > average)
-				average = (ra->currnt_wnd_hit + ra->average + 1) / 2;
-
-			ra->next_size = min(average , (unsigned long)max);
-		}
-		ra->start = offset;
-		ra->size = ra->next_size;
-		ra->ahead_start = 0;		/* Invalidate these */
-		ra->ahead_size = 0;
-		actual = do_page_cache_readahead(mapping, filp, offset,
-						 ra->size);
-		if(!first_access) {
-			/*
-			 * do not adjust the readahead window size the first
-			 * time, the ahead window might get closed if all
-			 * the pages are already in the cache.
-			 */
-			check_ra_success(ra, ra->size, actual, orig_next_size);
-		}
-	} else {
-		/*
-		 * This read request is within the current window.  It may be
-		 * time to submit I/O for the ahead window while the
-		 * application is about to step into the ahead window.
-		 */
-		if (ra->ahead_start == 0) {
-			/*
-			 * If the average io-size is more than maximum
-			 * readahead size of the file the io pattern is
-			 * sequential. Hence  bring in the readahead window
-			 * immediately.
-			 * If the average io-size is less than maximum
-			 * readahead size of the file the io pattern is
-			 * random. Hence don't bother to readahead.
+	}
+	/*
+	 * Already have an ahead window, check if we crossed into it.
+	 * If so, shift windows and issue a new ahead window.
+	 * Only return the #pages that are in the current window, so that
+	 * we get called back on the first page of the ahead window which
+	 * will allow us to submit more IO.
+	 */
+	if ((offset + newsize - 1) >= ra->ahead_start) {
+		ra->start = ra->ahead_start;
+		ra->size = ra->ahead_size;
+		ra->ahead_start = ra->ahead_start + ra->ahead_size;
+		ra->ahead_size = get_next_ra_size(ra->ahead_size,
+						  max, min, &ra->flags);
+		block = ((offset + newsize - 1) >= ra->ahead_start);
+		if (!blockable_page_cache_readahead(mapping, filp,
+			ra->ahead_start, ra->ahead_size, ra, block)) {
+			/* A read failure in blocking mode, implies pages are
+			 * all cached. So we can safely assume we have taken
+			 * care of all the pages requested in this call.
+			 * A read failure in non-blocking mode, implies we are
+			 * reading more pages than requested in this call.  So
+			 * we safely assume we have taken care of all the pages
+			 * requested in this call.
+			 *
+			 * Just reset the ahead window in case we failed due to
+			 * congestion.  The ahead window will any way be closed
+			 * in case we failed due to excessive page cache hits.
 			 */
-			average = ra->average;
-			if (ra->currnt_wnd_hit > average)
-				average = (ra->currnt_wnd_hit + ra->average + 1) / 2;
-
-			if (average > max) {
-				ra->ahead_start = ra->start + ra->size;
-				ra->ahead_size = ra->next_size;
-				actual = do_page_cache_readahead(mapping, filp,
-					ra->ahead_start, ra->ahead_size);
-				check_ra_success(ra, ra->ahead_size,
-						actual, orig_next_size);
-			}
+			ra->ahead_start = 0;
+			ra->ahead_size = 0;
 		}
 	}
+
 out:
-	return;
+	ra->prev_page = offset + newsize - 1;
+	return(newsize);
 }
 
-
 /*
  * handle_ra_miss() is called when it is known that a page which should have
  * been present in the pagecache (we just did some readahead there) was in fact
  * not found.  This will happen if it was evicted by the VM (readahead
- * thrashing) or if the readahead window is maximally shrunk.
+ * thrashing)
  *
- * If the window has been maximally shrunk (next_size == -1UL) then look to see
- * if we are getting misses against sequential file offsets.  If so, and this
- * persists then resume readahead.
- *
- * Otherwise we're thrashing, so shrink the readahead window by three pages.
- * This is because it is grown by two pages on a readahead hit.  Theory being
- * that the readahead window size will stabilise around the maximum level at
- * which there is no thrashing.
+ * Turn on the cache miss flag in the RA struct, this will cause the RA code
+ * to reduce the RA size on the next read.
  */
 void handle_ra_miss(struct address_space *mapping,
 		struct file_ra_state *ra, pgoff_t offset)
 {
-	if (ra->next_size == -1UL) {
-		const unsigned long max = get_max_readahead(ra);
-
-		if (offset != ra->prev_page + 1) {
-			ra->size = ra->size?ra->size-1:0; /* Not sequential */
-		} else {
-			ra->size++;			/* A sequential read */
-			if (ra->size >= max) {		/* Resume readahead */
-				ra->start = offset - max;
-				ra->next_size = max;
-				ra->size = max;
-				ra->ahead_start = 0;
-				ra->ahead_size = 0;
-				ra->average = max / 2;
-			}
-		}
-		ra->prev_page = offset;
-	} else {
-		const unsigned long min = get_min_readahead(ra);
-
-		ra->next_size -= 3;
-		if (ra->next_size < min)
-			ra->next_size = min;
-	}
+	ra->flags |= RA_FLAG_MISS;
+	ra->flags &= ~RA_FLAG_INCACHE;
 }
 
 /*
diff -Nru a/mm/rmap.c b/mm/rmap.c
--- a/mm/rmap.c	2005-03-01 23:39:16 -08:00
+++ b/mm/rmap.c	2005-03-01 23:39:16 -08:00
@@ -51,6 +51,7 @@
 #include <linux/swapops.h>
 #include <linux/slab.h>
 #include <linux/init.h>
+#include <linux/acct.h>
 #include <linux/rmap.h>
 #include <linux/rcupdate.h>
 
@@ -120,14 +121,7 @@
 
 void __anon_vma_merge(struct vm_area_struct *vma, struct vm_area_struct *next)
 {
-	if (!vma->anon_vma) {
-		BUG_ON(!next->anon_vma);
-		vma->anon_vma = next->anon_vma;
-		list_add(&vma->anon_vma_node, &next->anon_vma_node);
-	} else {
-		/* if they're both non-null they must be the same */
-		BUG_ON(vma->anon_vma != next->anon_vma);
-	}
+	BUG_ON(vma->anon_vma != next->anon_vma);
 	list_del(&next->anon_vma_node);
 }
 
@@ -259,6 +253,7 @@
 	struct mm_struct *mm = vma->vm_mm;
 	unsigned long address;
 	pgd_t *pgd;
+	pud_t *pud;
 	pmd_t *pmd;
 	pte_t *pte;
 	int referenced = 0;
@@ -275,7 +270,11 @@
 	if (!pgd_present(*pgd))
 		goto out_unlock;
 
-	pmd = pmd_offset(pgd, address);
+	pud = pud_offset(pgd, address);
+	if (!pud_present(*pud))
+		goto out_unlock;
+
+	pmd = pmd_offset(pud, address);
 	if (!pmd_present(*pmd))
 		goto out_unlock;
 
@@ -505,6 +504,7 @@
 	struct mm_struct *mm = vma->vm_mm;
 	unsigned long address;
 	pgd_t *pgd;
+	pud_t *pud;
 	pmd_t *pmd;
 	pte_t *pte;
 	pte_t pteval;
@@ -526,7 +526,11 @@
 	if (!pgd_present(*pgd))
 		goto out_unlock;
 
-	pmd = pmd_offset(pgd, address);
+	pud = pud_offset(pgd, address);
+	if (!pud_present(*pud))
+		goto out_unlock;
+
+	pmd = pmd_offset(pud, address);
 	if (!pmd_present(*pmd))
 		goto out_unlock;
 
@@ -596,6 +600,7 @@
 	}
 
 	mm->rss--;
+	acct_update_integrals();
 	page_remove_rmap(page);
 	page_cache_release(page);
 
@@ -634,6 +639,7 @@
 {
 	struct mm_struct *mm = vma->vm_mm;
 	pgd_t *pgd;
+	pud_t *pud;
 	pmd_t *pmd;
 	pte_t *pte;
 	pte_t pteval;
@@ -659,7 +665,11 @@
 	if (!pgd_present(*pgd))
 		goto out_unlock;
 
-	pmd = pmd_offset(pgd, address);
+	pud = pud_offset(pgd, address);
+	if (!pud_present(*pud))
+		goto out_unlock;
+
+	pmd = pmd_offset(pud, address);
 	if (!pmd_present(*pmd))
 		goto out_unlock;
 
@@ -695,6 +705,7 @@
 
 		page_remove_rmap(page);
 		page_cache_release(page);
+		acct_update_integrals();
 		mm->rss--;
 		(*mapcount)--;
 	}
diff -Nru a/mm/shmem.c b/mm/shmem.c
--- a/mm/shmem.c	2005-03-01 23:38:56 -08:00
+++ b/mm/shmem.c	2005-03-01 23:38:56 -08:00
@@ -189,7 +189,7 @@
 };
 
 static LIST_HEAD(shmem_swaplist);
-static spinlock_t shmem_swaplist_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(shmem_swaplist_lock);
 
 static void shmem_free_blocks(struct inode *inode, long pages)
 {
@@ -369,9 +369,8 @@
 		}
 
 		spin_unlock(&info->lock);
-		page = shmem_dir_alloc(mapping_gfp_mask(inode->i_mapping));
+		page = shmem_dir_alloc(mapping_gfp_mask(inode->i_mapping) | __GFP_ZERO);
 		if (page) {
-			clear_highpage(page);
 			page->nr_swapped = 0;
 		}
 		spin_lock(&info->lock);
@@ -910,7 +909,7 @@
 	pvma.vm_policy = mpol_shared_policy_lookup(&info->policy, idx);
 	pvma.vm_pgoff = idx;
 	pvma.vm_end = PAGE_SIZE;
-	page = alloc_page_vma(gfp, &pvma, 0);
+	page = alloc_page_vma(gfp | __GFP_ZERO, &pvma, 0);
 	mpol_free(pvma.vm_policy);
 	return page;
 }
@@ -926,7 +925,7 @@
 shmem_alloc_page(unsigned long gfp,struct shmem_inode_info *info,
 				 unsigned long idx)
 {
-	return alloc_page(gfp);
+	return alloc_page(gfp | __GFP_ZERO);
 }
 #endif
 
@@ -1135,7 +1134,6 @@
 
 		info->alloced++;
 		spin_unlock(&info->lock);
-		clear_highpage(filepage);
 		flush_dcache_page(filepage);
 		SetPageUptodate(filepage);
 	}
@@ -1164,6 +1162,8 @@
 	idx = (address - vma->vm_start) >> PAGE_SHIFT;
 	idx += vma->vm_pgoff;
 	idx >>= PAGE_CACHE_SHIFT - PAGE_SHIFT;
+	if (((loff_t) idx << PAGE_CACHE_SHIFT) >= i_size_read(inode))
+		return NOPAGE_SIGBUS;
 
 	error = shmem_getpage(inode, idx, &page, SGP_CACHE, type);
 	if (error)
diff -Nru a/mm/slab.c b/mm/slab.c
--- a/mm/slab.c	2005-03-01 23:39:18 -08:00
+++ b/mm/slab.c	2005-03-01 23:39:18 -08:00
@@ -128,9 +128,28 @@
 #endif
 
 #ifndef ARCH_KMALLOC_MINALIGN
+/*
+ * Enforce a minimum alignment for the kmalloc caches.
+ * Usually, the kmalloc caches are cache_line_size() aligned, except when
+ * DEBUG and FORCED_DEBUG are enabled, then they are BYTES_PER_WORD aligned.
+ * Some archs want to perform DMA into kmalloc caches and need a guaranteed
+ * alignment larger than BYTES_PER_WORD. ARCH_KMALLOC_MINALIGN allows that.
+ * Note that this flag disables some debug features.
+ */
 #define ARCH_KMALLOC_MINALIGN 0
 #endif
 
+#ifndef ARCH_SLAB_MINALIGN
+/*
+ * Enforce a minimum alignment for all caches.
+ * Intended for archs that get misalignment faults even for BYTES_PER_WORD
+ * aligned buffers. Includes ARCH_KMALLOC_MINALIGN.
+ * If possible: Do not enable this flag for CONFIG_DEBUG_SLAB, it disables
+ * some debug features.
+ */
+#define ARCH_SLAB_MINALIGN 0
+#endif
+
 #ifndef ARCH_KMALLOC_FLAGS
 #define ARCH_KMALLOC_FLAGS SLAB_HWCACHE_ALIGN
 #endif
@@ -875,16 +894,13 @@
 
 	flags |= cachep->gfpflags;
 	if (likely(nodeid == -1)) {
-		addr = (void*)__get_free_pages(flags, cachep->gfporder);
-		if (!addr)
-			return NULL;
-		page = virt_to_page(addr);
+		page = alloc_pages(flags, cachep->gfporder);
 	} else {
 		page = alloc_pages_node(nodeid, flags, cachep->gfporder);
-		if (!page)
-			return NULL;
-		addr = page_address(page);
 	}
+	if (!page)
+		return NULL;
+	addr = page_address(page);
 
 	i = (1 << cachep->gfporder);
 	if (cachep->flags & SLAB_RECLAIM_ACCOUNT)
@@ -1172,7 +1188,7 @@
 	unsigned long flags, void (*ctor)(void*, kmem_cache_t *, unsigned long),
 	void (*dtor)(void*, kmem_cache_t *, unsigned long))
 {
-	size_t left_over, slab_size;
+	size_t left_over, slab_size, ralign;
 	kmem_cache_t *cachep = NULL;
 
 	/*
@@ -1222,24 +1238,44 @@
 	if (flags & ~CREATE_MASK)
 		BUG();
 
-	if (align) {
-		/* combinations of forced alignment and advanced debugging is
-		 * not yet implemented.
+	/* Check that size is in terms of words.  This is needed to avoid
+	 * unaligned accesses for some archs when redzoning is used, and makes
+	 * sure any on-slab bufctl's are also correctly aligned.
+	 */
+	if (size & (BYTES_PER_WORD-1)) {
+		size += (BYTES_PER_WORD-1);
+		size &= ~(BYTES_PER_WORD-1);
+	}
+
+	/* calculate out the final buffer alignment: */
+	/* 1) arch recommendation: can be overridden for debug */
+	if (flags & SLAB_HWCACHE_ALIGN) {
+		/* Default alignment: as specified by the arch code.
+		 * Except if an object is really small, then squeeze multiple
+		 * objects into one cacheline.
 		 */
-		flags &= ~(SLAB_RED_ZONE|SLAB_STORE_USER);
+		ralign = cache_line_size();
+		while (size <= ralign/2)
+			ralign /= 2;
 	} else {
-		if (flags & SLAB_HWCACHE_ALIGN) {
-			/* Default alignment: as specified by the arch code.
-			 * Except if an object is really small, then squeeze multiple
-			 * into one cacheline.
-			 */
-			align = cache_line_size();
-			while (size <= align/2)
-				align /= 2;
-		} else {
-			align = BYTES_PER_WORD;
-		}
+		ralign = BYTES_PER_WORD;
+	}
+	/* 2) arch mandated alignment: disables debug if necessary */
+	if (ralign < ARCH_SLAB_MINALIGN) {
+		ralign = ARCH_SLAB_MINALIGN;
+		if (ralign > BYTES_PER_WORD)
+			flags &= ~(SLAB_RED_ZONE|SLAB_STORE_USER);
+	}
+	/* 3) caller mandated alignment: disables debug if necessary */
+	if (ralign < align) {
+		ralign = align;
+		if (ralign > BYTES_PER_WORD)
+			flags &= ~(SLAB_RED_ZONE|SLAB_STORE_USER);
 	}
+	/* 4) Store it. Note that the debug code below can reduce
+	 *    the alignment to BYTES_PER_WORD.
+	 */
+	align = ralign;
 
 	/* Get cache's description obj. */
 	cachep = (kmem_cache_t *) kmem_cache_alloc(&cache_cache, SLAB_KERNEL);
@@ -1247,15 +1283,6 @@
 		goto opps;
 	memset(cachep, 0, sizeof(kmem_cache_t));
 
-	/* Check that size is in terms of words.  This is needed to avoid
-	 * unaligned accesses for some archs when redzoning is used, and makes
-	 * sure any on-slab bufctl's are also correctly aligned.
-	 */
-	if (size & (BYTES_PER_WORD-1)) {
-		size += (BYTES_PER_WORD-1);
-		size &= ~(BYTES_PER_WORD-1);
-	}
-	
 #if DEBUG
 	cachep->reallen = size;
 
@@ -2806,7 +2833,7 @@
 next_unlock:
 		spin_unlock_irq(&searchp->spinlock);
 next:
-		;
+		cond_resched();
 	}
 	check_irq_on();
 	up(&cache_chain_sem);
@@ -2833,7 +2860,7 @@
 		seq_puts(m, "slabinfo - version: 2.1\n");
 #endif
 		seq_puts(m, "# name            <active_objs> <num_objs> <objsize> <objperslab> <pagesperslab>");
-		seq_puts(m, " : tunables <batchcount> <limit> <sharedfactor>");
+		seq_puts(m, " : tunables <limit> <batchcount> <sharedfactor>");
 		seq_puts(m, " : slabdata <active_slabs> <num_slabs> <sharedavail>");
 #if STATS
 		seq_puts(m, " : globalstat <listallocs> <maxobjs> <grown> <reaped>"
diff -Nru a/mm/swap_state.c b/mm/swap_state.c
--- a/mm/swap_state.c	2005-03-01 23:38:56 -08:00
+++ b/mm/swap_state.c	2005-03-01 23:38:56 -08:00
@@ -59,6 +59,8 @@
 		swap_cache_info.add_total, swap_cache_info.del_total,
 		swap_cache_info.find_success, swap_cache_info.find_total,
 		swap_cache_info.noent_race, swap_cache_info.exist_race);
+	printk("Free swap  = %lukB\n", nr_swap_pages << (PAGE_SHIFT - 10));
+	printk("Total swap = %lukB\n", total_swap_pages << (PAGE_SHIFT - 10));
 }
 
 /*
diff -Nru a/mm/swapfile.c b/mm/swapfile.c
--- a/mm/swapfile.c	2005-03-01 23:38:53 -08:00
+++ b/mm/swapfile.c	2005-03-01 23:38:53 -08:00
@@ -24,6 +24,7 @@
 #include <linux/module.h>
 #include <linux/rmap.h>
 #include <linux/security.h>
+#include <linux/acct.h>
 #include <linux/backing-dev.h>
 #include <linux/syscalls.h>
 
@@ -31,7 +32,7 @@
 #include <asm/tlbflush.h>
 #include <linux/swapops.h>
 
-spinlock_t swaplock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(swaplock);
 unsigned int nr_swapfiles;
 long total_swap_pages;
 static int swap_overflow;
@@ -436,15 +437,16 @@
 	set_pte(dir, pte_mkold(mk_pte(page, vma->vm_page_prot)));
 	page_add_anon_rmap(page, vma, address);
 	swap_free(entry);
+	acct_update_integrals();
+	update_mem_hiwater();
 }
 
 /* vma->vm_mm->page_table_lock is held */
-static unsigned long unuse_pmd(struct vm_area_struct * vma, pmd_t *dir,
-	unsigned long address, unsigned long size, unsigned long offset,
+static unsigned long unuse_pmd(struct vm_area_struct *vma, pmd_t *dir,
+	unsigned long address, unsigned long end,
 	swp_entry_t entry, struct page *page)
 {
-	pte_t * pte;
-	unsigned long end;
+	pte_t *pte;
 	pte_t swp_pte = swp_entry_to_pte(entry);
 
 	if (pmd_none(*dir))
@@ -455,18 +457,13 @@
 		return 0;
 	}
 	pte = pte_offset_map(dir, address);
-	offset += address & PMD_MASK;
-	address &= ~PMD_MASK;
-	end = address + size;
-	if (end > PMD_SIZE)
-		end = PMD_SIZE;
 	do {
 		/*
 		 * swapoff spends a _lot_ of time in this loop!
 		 * Test inline before going to call unuse_pte.
 		 */
 		if (unlikely(pte_same(*pte, swp_pte))) {
-			unuse_pte(vma, offset + address, pte, entry, page);
+			unuse_pte(vma, address, pte, entry, page);
 			pte_unmap(pte);
 
 			/*
@@ -476,77 +473,104 @@
 			activate_page(page);
 
 			/* add 1 since address may be 0 */
-			return 1 + offset + address;
+			return 1 + address;
 		}
 		address += PAGE_SIZE;
 		pte++;
-	} while (address && (address < end));
+	} while (address < end);
 	pte_unmap(pte - 1);
 	return 0;
 }
 
 /* vma->vm_mm->page_table_lock is held */
-static unsigned long unuse_pgd(struct vm_area_struct * vma, pgd_t *dir,
-	unsigned long address, unsigned long size,
+static unsigned long unuse_pud(struct vm_area_struct *vma, pud_t *pud,
+        unsigned long address, unsigned long end,
 	swp_entry_t entry, struct page *page)
 {
-	pmd_t * pmd;
-	unsigned long offset, end;
+	pmd_t *pmd;
+	unsigned long next;
 	unsigned long foundaddr;
 
-	if (pgd_none(*dir))
+	if (pud_none(*pud))
 		return 0;
-	if (pgd_bad(*dir)) {
-		pgd_ERROR(*dir);
-		pgd_clear(dir);
+	if (pud_bad(*pud)) {
+		pud_ERROR(*pud);
+		pud_clear(pud);
 		return 0;
 	}
-	pmd = pmd_offset(dir, address);
-	offset = address & PGDIR_MASK;
-	address &= ~PGDIR_MASK;
-	end = address + size;
-	if (end > PGDIR_SIZE)
-		end = PGDIR_SIZE;
-	if (address >= end)
-		BUG();
+	pmd = pmd_offset(pud, address);
 	do {
-		foundaddr = unuse_pmd(vma, pmd, address, end - address,
-						offset, entry, page);
+		next = (address + PMD_SIZE) & PMD_MASK;
+		if (next > end || !next)
+			next = end;
+		foundaddr = unuse_pmd(vma, pmd, address, next, entry, page);
 		if (foundaddr)
 			return foundaddr;
-		address = (address + PMD_SIZE) & PMD_MASK;
+		address = next;
 		pmd++;
-	} while (address && (address < end));
+	} while (address < end);
+	return 0;
+}
+
+/* vma->vm_mm->page_table_lock is held */
+static unsigned long unuse_pgd(struct vm_area_struct *vma, pgd_t *pgd,
+	unsigned long address, unsigned long end,
+	swp_entry_t entry, struct page *page)
+{
+	pud_t *pud;
+	unsigned long next;
+	unsigned long foundaddr;
+
+	if (pgd_none(*pgd))
+		return 0;
+	if (pgd_bad(*pgd)) {
+		pgd_ERROR(*pgd);
+		pgd_clear(pgd);
+		return 0;
+	}
+	pud = pud_offset(pgd, address);
+	do {
+		next = (address + PUD_SIZE) & PUD_MASK;
+		if (next > end || !next)
+			next = end;
+		foundaddr = unuse_pud(vma, pud, address, next, entry, page);
+		if (foundaddr)
+			return foundaddr;
+		address = next;
+		pud++;
+	} while (address < end);
 	return 0;
 }
 
 /* vma->vm_mm->page_table_lock is held */
-static unsigned long unuse_vma(struct vm_area_struct * vma,
+static unsigned long unuse_vma(struct vm_area_struct *vma,
 	swp_entry_t entry, struct page *page)
 {
-	pgd_t *pgdir;
-	unsigned long start, end;
+	pgd_t *pgd;
+	unsigned long address, next, end;
 	unsigned long foundaddr;
 
 	if (page->mapping) {
-		start = page_address_in_vma(page, vma);
-		if (start == -EFAULT)
+		address = page_address_in_vma(page, vma);
+		if (address == -EFAULT)
 			return 0;
 		else
-			end = start + PAGE_SIZE;
+			end = address + PAGE_SIZE;
 	} else {
-		start = vma->vm_start;
+		address = vma->vm_start;
 		end = vma->vm_end;
 	}
-	pgdir = pgd_offset(vma->vm_mm, start);
+	pgd = pgd_offset(vma->vm_mm, address);
 	do {
-		foundaddr = unuse_pgd(vma, pgdir, start, end - start,
-						entry, page);
+		next = (address + PGDIR_SIZE) & PGDIR_MASK;
+		if (next > end || !next)
+			next = end;
+		foundaddr = unuse_pgd(vma, pgd, address, next, entry, page);
 		if (foundaddr)
 			return foundaddr;
-		start = (start + PGDIR_SIZE) & PGDIR_MASK;
-		pgdir++;
-	} while (start && (start < end));
+		address = next;
+		pgd++;
+	} while (address < end);
 	return 0;
 }
 
@@ -1592,8 +1616,7 @@
 		++least_priority;
 	swap_list_unlock();
 	destroy_swap_extents(p);
-	if (swap_map)
-		vfree(swap_map);
+	vfree(swap_map);
 	if (swap_file)
 		filp_close(swap_file, NULL);
 out:
diff -Nru a/mm/thrash.c b/mm/thrash.c
--- a/mm/thrash.c	2005-03-01 23:38:54 -08:00
+++ b/mm/thrash.c	2005-03-01 23:38:54 -08:00
@@ -13,7 +13,7 @@
 #include <linux/sched.h>
 #include <linux/swap.h>
 
-static spinlock_t swap_token_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(swap_token_lock);
 static unsigned long swap_token_timeout;
 unsigned long swap_token_check;
 struct mm_struct * swap_token_mm = &init_mm;
diff -Nru a/mm/truncate.c b/mm/truncate.c
--- a/mm/truncate.c	2005-03-01 23:39:16 -08:00
+++ b/mm/truncate.c	2005-03-01 23:39:16 -08:00
@@ -64,6 +64,8 @@
  * be marked dirty at any time too.  So we re-check the dirtiness inside
  * ->tree_lock.  That provides exclusion against the __set_page_dirty
  * functions.
+ *
+ * Returns non-zero if the page was successfully invalidated.
  */
 static int
 invalidate_complete_page(struct address_space *mapping, struct page *page)
@@ -81,10 +83,6 @@
 	}
 
 	BUG_ON(PagePrivate(page));
-	if (page_count(page) != 2) {
-		spin_unlock_irq(&mapping->tree_lock);
-		return 0;
-	}
 	__remove_from_page_cache(page);
 	spin_unlock_irq(&mapping->tree_lock);
 	ClearPageUptodate(page);
@@ -243,50 +241,67 @@
 EXPORT_SYMBOL(invalidate_inode_pages);
 
 /**
- * invalidate_inode_pages2 - remove all unmapped pages from an address_space
+ * invalidate_inode_pages2 - remove all pages from an address_space
  * @mapping - the address_space
  *
- * invalidate_inode_pages2() is like truncate_inode_pages(), except for the case
- * where the page is seen to be mapped into process pagetables.  In that case,
- * the page is marked clean but is left attached to its address_space.
- *
- * The page is also marked not uptodate so that a subsequent pagefault will
- * perform I/O to bringthe page's contents back into sync with its backing
- * store.
+ * Any pages which are found to be mapped into pagetables are unmapped prior to
+ * invalidation.
  *
- * FIXME: invalidate_inode_pages2() is probably trivially livelockable.
+ * Returns -EIO if any pages could not be invalidated.
  */
-void invalidate_inode_pages2(struct address_space *mapping)
+int invalidate_inode_pages2(struct address_space *mapping)
 {
 	struct pagevec pvec;
 	pgoff_t next = 0;
 	int i;
+	int ret = 0;
+	int did_full_unmap = 0;
 
 	pagevec_init(&pvec, 0);
-	while (pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE)) {
-		for (i = 0; i < pagevec_count(&pvec); i++) {
+	while (!ret && pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE)) {
+		for (i = 0; !ret && i < pagevec_count(&pvec); i++) {
 			struct page *page = pvec.pages[i];
+			int was_dirty;
 
 			lock_page(page);
-			if (page->mapping == mapping) {	/* truncate race? */
-				wait_on_page_writeback(page);
-				next = page->index + 1;
-				if (page_mapped(page)) {
-					clear_page_dirty(page);
-					ClearPageUptodate(page);
+			if (page->mapping != mapping) {	/* truncate race? */
+				unlock_page(page);
+				continue;
+			}
+			wait_on_page_writeback(page);
+			next = page->index + 1;
+			while (page_mapped(page)) {
+				if (!did_full_unmap) {
+					/*
+					 * Zap the rest of the file in one hit.
+					 * FIXME: invalidate_inode_pages2()
+					 * should take start/end offsets.
+					 */
+					unmap_mapping_range(mapping,
+						page->index << PAGE_CACHE_SHIFT,
+					  	-1, 0);
+					did_full_unmap = 1;
 				} else {
-					if (!invalidate_complete_page(mapping,
-								      page)) {
-						clear_page_dirty(page);
-						ClearPageUptodate(page);
-					}
+					/*
+					 * Just zap this page
+					 */
+					unmap_mapping_range(mapping,
+					  page->index << PAGE_CACHE_SHIFT,
+					  (page->index << PAGE_CACHE_SHIFT)+1,
+					  0);
 				}
 			}
+			was_dirty = test_clear_page_dirty(page);
+			if (!invalidate_complete_page(mapping, page)) {
+				if (was_dirty)
+					set_page_dirty(page);
+				ret = -EIO;
+			}
 			unlock_page(page);
 		}
 		pagevec_release(&pvec);
 		cond_resched();
 	}
+	return ret;
 }
-
 EXPORT_SYMBOL_GPL(invalidate_inode_pages2);
diff -Nru a/mm/vmalloc.c b/mm/vmalloc.c
--- a/mm/vmalloc.c	2005-03-01 23:38:58 -08:00
+++ b/mm/vmalloc.c	2005-03-01 23:38:58 -08:00
@@ -20,7 +20,7 @@
 #include <asm/tlbflush.h>
 
 
-rwlock_t vmlist_lock = RW_LOCK_UNLOCKED;
+DEFINE_RWLOCK(vmlist_lock);
 struct vm_struct *vmlist;
 
 static void unmap_area_pte(pmd_t *pmd, unsigned long address,
@@ -56,25 +56,25 @@
 	} while (address < end);
 }
 
-static void unmap_area_pmd(pgd_t *dir, unsigned long address,
+static void unmap_area_pmd(pud_t *pud, unsigned long address,
 				  unsigned long size)
 {
 	unsigned long end;
 	pmd_t *pmd;
 
-	if (pgd_none(*dir))
+	if (pud_none(*pud))
 		return;
-	if (pgd_bad(*dir)) {
-		pgd_ERROR(*dir);
-		pgd_clear(dir);
+	if (pud_bad(*pud)) {
+		pud_ERROR(*pud);
+		pud_clear(pud);
 		return;
 	}
 
-	pmd = pmd_offset(dir, address);
-	address &= ~PGDIR_MASK;
+	pmd = pmd_offset(pud, address);
+	address &= ~PUD_MASK;
 	end = address + size;
-	if (end > PGDIR_SIZE)
-		end = PGDIR_SIZE;
+	if (end > PUD_SIZE)
+		end = PUD_SIZE;
 
 	do {
 		unmap_area_pte(pmd, address, end - address);
@@ -83,6 +83,33 @@
 	} while (address < end);
 }
 
+static void unmap_area_pud(pgd_t *pgd, unsigned long address,
+			   unsigned long size)
+{
+	pud_t *pud;
+	unsigned long end;
+
+	if (pgd_none(*pgd))
+		return;
+	if (pgd_bad(*pgd)) {
+		pgd_ERROR(*pgd);
+		pgd_clear(pgd);
+		return;
+	}
+
+	pud = pud_offset(pgd, address);
+	address &= ~PGDIR_MASK;
+	end = address + size;
+	if (end > PGDIR_SIZE)
+		end = PGDIR_SIZE;
+
+	do {
+		unmap_area_pmd(pud, address, end - address);
+		address = (address + PUD_SIZE) & PUD_MASK;
+		pud++;
+	} while (address && (address < end));
+}
+
 static int map_area_pte(pte_t *pte, unsigned long address,
 			       unsigned long size, pgprot_t prot,
 			       struct page ***pages)
@@ -96,7 +123,6 @@
 
 	do {
 		struct page *page = **pages;
-
 		WARN_ON(!pte_none(*pte));
 		if (!page)
 			return -ENOMEM;
@@ -115,11 +141,11 @@
 {
 	unsigned long base, end;
 
-	base = address & PGDIR_MASK;
-	address &= ~PGDIR_MASK;
+	base = address & PUD_MASK;
+	address &= ~PUD_MASK;
 	end = address + size;
-	if (end > PGDIR_SIZE)
-		end = PGDIR_SIZE;
+	if (end > PUD_SIZE)
+		end = PUD_SIZE;
 
 	do {
 		pte_t * pte = pte_alloc_kernel(&init_mm, pmd, base + address);
@@ -134,19 +160,41 @@
 	return 0;
 }
 
+static int map_area_pud(pud_t *pud, unsigned long address,
+			       unsigned long end, pgprot_t prot,
+			       struct page ***pages)
+{
+	do {
+		pmd_t *pmd = pmd_alloc(&init_mm, pud, address);
+		if (!pmd)
+			return -ENOMEM;
+		if (map_area_pmd(pmd, address, end - address, prot, pages))
+			return -ENOMEM;
+		address = (address + PUD_SIZE) & PUD_MASK;
+		pud++;
+	} while (address && address < end);
+
+	return 0;
+}
+
 void unmap_vm_area(struct vm_struct *area)
 {
 	unsigned long address = (unsigned long) area->addr;
 	unsigned long end = (address + area->size);
-	pgd_t *dir;
+	unsigned long next;
+	pgd_t *pgd;
+	int i;
 
-	dir = pgd_offset_k(address);
+	pgd = pgd_offset_k(address);
 	flush_cache_vunmap(address, end);
-	do {
-		unmap_area_pmd(dir, address, end - address);
-		address = (address + PGDIR_SIZE) & PGDIR_MASK;
-		dir++;
-	} while (address && (address < end));
+	for (i = pgd_index(address); i <= pgd_index(end-1); i++) {
+		next = (address + PGDIR_SIZE) & PGDIR_MASK;
+		if (next <= address || next > end)
+			next = end;
+		unmap_area_pud(pgd, address, next - address);
+		address = next;
+	        pgd++;
+	}
 	flush_tlb_kernel_range((unsigned long) area->addr, end);
 }
 
@@ -154,25 +202,30 @@
 {
 	unsigned long address = (unsigned long) area->addr;
 	unsigned long end = address + (area->size-PAGE_SIZE);
-	pgd_t *dir;
+	unsigned long next;
+	pgd_t *pgd;
 	int err = 0;
+	int i;
 
-	dir = pgd_offset_k(address);
+	pgd = pgd_offset_k(address);
 	spin_lock(&init_mm.page_table_lock);
-	do {
-		pmd_t *pmd = pmd_alloc(&init_mm, dir, address);
-		if (!pmd) {
+	for (i = pgd_index(address); i <= pgd_index(end-1); i++) {
+		pud_t *pud = pud_alloc(&init_mm, pgd, address);
+		if (!pud) {
 			err = -ENOMEM;
 			break;
 		}
-		if (map_area_pmd(pmd, address, end - address, prot, pages)) {
+		next = (address + PGDIR_SIZE) & PGDIR_MASK;
+		if (next < address || next > end)
+			next = end;
+		if (map_area_pud(pud, address, next, prot, pages)) {
 			err = -ENOMEM;
 			break;
 		}
 
-		address = (address + PGDIR_SIZE) & PGDIR_MASK;
-		dir++;
-	} while (address && (address < end));
+		address = next;
+		pgd++;
+	}
 
 	spin_unlock(&init_mm.page_table_lock);
 	flush_cache_vmap((unsigned long) area->addr, end);
@@ -325,7 +378,10 @@
 			__free_page(area->pages[i]);
 		}
 
-		kfree(area->pages);
+		if (area->nr_pages > PAGE_SIZE/sizeof(struct page *))
+			vfree(area->pages);
+		else
+			kfree(area->pages);
 	}
 
 	kfree(area);
@@ -429,7 +485,12 @@
 	array_size = (nr_pages * sizeof(struct page *));
 
 	area->nr_pages = nr_pages;
-	area->pages = pages = kmalloc(array_size, (gfp_mask & ~__GFP_HIGHMEM));
+	/* Please note that the recursion is strictly bounded. */
+	if (array_size > PAGE_SIZE)
+		pages = __vmalloc(array_size, gfp_mask, PAGE_KERNEL);
+	else
+		pages = kmalloc(array_size, (gfp_mask & ~__GFP_HIGHMEM));
+	area->pages = pages;
 	if (!area->pages) {
 		remove_vm_area(area->addr);
 		kfree(area);
diff -Nru a/mm/vmscan.c b/mm/vmscan.c
--- a/mm/vmscan.c	2005-03-01 23:38:52 -08:00
+++ b/mm/vmscan.c	2005-03-01 23:38:52 -08:00
@@ -21,7 +21,6 @@
 #include <linux/highmem.h>
 #include <linux/file.h>
 #include <linux/writeback.h>
-#include <linux/suspend.h>
 #include <linux/blkdev.h>
 #include <linux/buffer_head.h>	/* for try_to_release_page(),
 					buffer_heads_over_limit */
@@ -361,6 +360,8 @@
 		int may_enter_fs;
 		int referenced;
 
+		cond_resched();
+
 		page = lru_to_page(page_list);
 		list_del(&page->lru);
 
@@ -369,14 +370,14 @@
 
 		BUG_ON(PageActive(page));
 
-		if (PageWriteback(page))
-			goto keep_locked;
-
 		sc->nr_scanned++;
 		/* Double the slab pressure for mapped and swapcache pages */
 		if (page_mapped(page) || PageSwapCache(page))
 			sc->nr_scanned++;
 
+		if (PageWriteback(page))
+			goto keep_locked;
+
 		referenced = page_referenced(page, 1, sc->priority <= 0);
 		/* In active use or really unfreeable?  Activate it. */
 		if (referenced && page_mapping_inuse(page))
@@ -574,6 +575,7 @@
 			nr_taken++;
 		}
 		zone->nr_inactive -= nr_taken;
+		zone->pages_scanned += nr_scan;
 		spin_unlock_irq(&zone->lru_lock);
 
 		if (nr_taken == 0)
@@ -710,6 +712,7 @@
 		reclaim_mapped = 1;
 
 	while (!list_empty(&l_hold)) {
+		cond_resched();
 		page = lru_to_page(&l_hold);
 		list_del(&page->lru);
 		if (page_mapped(page)) {
@@ -935,8 +938,6 @@
 		if (sc.nr_scanned && priority < DEF_PRIORITY - 2)
 			blk_congestion_wait(WRITE, HZ/10);
 	}
-	if ((gfp_mask & __GFP_FS) && !(gfp_mask & __GFP_NORETRY))
-		out_of_memory(gfp_mask);
 out:
 	for (i = 0; zones[i] != 0; i++)
 		zones[i]->prev_priority = zones[i]->temp_priority;
@@ -968,7 +969,7 @@
  * the page allocator fallback scheme to ensure that aging of pages is balanced
  * across the zones.
  */
-static int balance_pgdat(pg_data_t *pgdat, int nr_pages)
+static int balance_pgdat(pg_data_t *pgdat, int nr_pages, int order)
 {
 	int to_free = nr_pages;
 	int all_zones_ok;
@@ -1014,7 +1015,8 @@
 						priority != DEF_PRIORITY)
 					continue;
 
-				if (zone->free_pages <= zone->pages_high) {
+				if (!zone_watermark_ok(zone, order,
+						zone->pages_high, 0, 0, 0)) {
 					end_zone = i;
 					goto scan;
 				}
@@ -1049,7 +1051,8 @@
 				continue;
 
 			if (nr_pages == 0) {	/* Not software suspend */
-				if (zone->free_pages <= zone->pages_high)
+				if (!zone_watermark_ok(zone, order,
+						zone->pages_high, end_zone, 0, 0))
 					all_zones_ok = 0;
 			}
 			zone->temp_priority = priority;
@@ -1063,6 +1066,7 @@
 			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 +
@@ -1126,6 +1130,7 @@
  */
 static int kswapd(void *p)
 {
+	unsigned long order;
 	pg_data_t *pgdat = (pg_data_t*)p;
 	struct task_struct *tsk = current;
 	DEFINE_WAIT(wait);
@@ -1154,14 +1159,28 @@
 	 */
 	tsk->flags |= PF_MEMALLOC|PF_KSWAPD;
 
+	order = 0;
 	for ( ; ; ) {
+		unsigned long new_order;
 		if (current->flags & PF_FREEZE)
 			refrigerator(PF_FREEZE);
+
 		prepare_to_wait(&pgdat->kswapd_wait, &wait, TASK_INTERRUPTIBLE);
-		schedule();
+		new_order = pgdat->kswapd_max_order;
+		pgdat->kswapd_max_order = 0;
+		if (order < new_order) {
+			/*
+			 * Don't sleep if someone wants a larger 'order'
+			 * allocation
+			 */
+			order = new_order;
+		} else {
+			schedule();
+			order = pgdat->kswapd_max_order;
+		}
 		finish_wait(&pgdat->kswapd_wait, &wait);
 
-		balance_pgdat(pgdat, 0);
+		balance_pgdat(pgdat, 0, order);
 	}
 	return 0;
 }
@@ -1169,12 +1188,18 @@
 /*
  * A zone is low on free memory, so wake its kswapd task to service it.
  */
-void wakeup_kswapd(struct zone *zone)
+void wakeup_kswapd(struct zone *zone, int order)
 {
+	pg_data_t *pgdat;
+
 	if (zone->present_pages == 0)
 		return;
-	if (zone->free_pages > zone->pages_low)
+
+	pgdat = zone->zone_pgdat;
+	if (zone_watermark_ok(zone, order, zone->pages_low, 0, 0, 0))
 		return;
+	if (pgdat->kswapd_max_order < order)
+		pgdat->kswapd_max_order = order;
 	if (!waitqueue_active(&zone->zone_pgdat->kswapd_wait))
 		return;
 	wake_up_interruptible(&zone->zone_pgdat->kswapd_wait);
@@ -1197,7 +1222,7 @@
 	current->reclaim_state = &reclaim_state;
 	for_each_pgdat(pgdat) {
 		int freed;
-		freed = balance_pgdat(pgdat, nr_to_free);
+		freed = balance_pgdat(pgdat, nr_to_free, 0);
 		ret += freed;
 		nr_to_free -= freed;
 		if (nr_to_free <= 0)
diff -Nru a/net/802/fc.c b/net/802/fc.c
--- a/net/802/fc.c	2005-03-01 23:39:17 -08:00
+++ b/net/802/fc.c	2005-03-01 23:39:17 -08:00
@@ -35,8 +35,9 @@
  *	Put the headers on a Fibre Channel packet. 
  */
  
-int fc_header(struct sk_buff *skb, struct net_device *dev, unsigned short type,
-              void *daddr, void *saddr, unsigned len) 
+static int fc_header(struct sk_buff *skb, struct net_device *dev,
+		     unsigned short type,
+		     void *daddr, void *saddr, unsigned len) 
 {
 	struct fch_hdr *fch;
 	int hdr_len;
@@ -81,7 +82,7 @@
  *	can now send the packet.
  */
  
-int fc_rebuild_header(struct sk_buff *skb) 
+static int fc_rebuild_header(struct sk_buff *skb) 
 {
 	struct fch_hdr *fch=(struct fch_hdr *)skb->data;
 	struct fcllc *fcllc=(struct fcllc *)(skb->data+sizeof(struct fch_hdr));
diff -Nru a/net/802/fddi.c b/net/802/fddi.c
--- a/net/802/fddi.c	2005-03-01 23:39:09 -08:00
+++ b/net/802/fddi.c	2005-03-01 23:39:09 -08:00
@@ -52,8 +52,9 @@
  * daddr=NULL	means leave destination address (eg unresolved arp)
  */
 
-int fddi_header(struct sk_buff	*skb, struct net_device *dev, unsigned short type,
-		void *daddr, void *saddr, unsigned len)
+static int fddi_header(struct sk_buff *skb, struct net_device *dev,
+		       unsigned short type,
+		       void *daddr, void *saddr, unsigned len)
 {
 	int hl = FDDI_K_SNAP_HLEN;
 	struct fddihdr *fddi;
@@ -96,7 +97,7 @@
  * this sk_buff.  We now let ARP fill in the other fields.
  */
  
-int fddi_rebuild_header(struct sk_buff	*skb)
+static int fddi_rebuild_header(struct sk_buff	*skb)
 {
 	struct fddihdr *fddi = (struct fddihdr *)skb->data;
 
diff -Nru a/net/802/hippi.c b/net/802/hippi.c
--- a/net/802/hippi.c	2005-03-01 23:38:57 -08:00
+++ b/net/802/hippi.c	2005-03-01 23:38:57 -08:00
@@ -40,26 +40,15 @@
 #include <asm/system.h>
 
 /*
- * hippi_net_init()
- *
- * Do nothing, this is just to pursuade the stupid linker to behave.
- */
-
-void hippi_net_init(void)
-{
-	return;
-}
-
-/*
  * Create the HIPPI MAC header for an arbitrary protocol layer 
  *
  * saddr=NULL	means use device source address
  * daddr=NULL	means leave destination address (eg unresolved arp)
  */
 
-int hippi_header(struct sk_buff *skb, struct net_device *dev,
-		 unsigned short type, void *daddr, void *saddr,
-		 unsigned len)
+static int hippi_header(struct sk_buff *skb, struct net_device *dev,
+			unsigned short type, void *daddr, void *saddr,
+			unsigned len)
 {
 	struct hippi_hdr *hip = (struct hippi_hdr *)skb_push(skb, HIPPI_HLEN);
 
@@ -107,7 +96,7 @@
  * completed on this sk_buff. We now let ARP fill in the other fields.
  */
 
-int hippi_rebuild_header(struct sk_buff *skb)
+static int hippi_rebuild_header(struct sk_buff *skb)
 {
 	struct hippi_hdr *hip = (struct hippi_hdr *)skb->data;
 
diff -Nru a/net/802/psnap.c b/net/802/psnap.c
--- a/net/802/psnap.c	2005-03-01 23:39:17 -08:00
+++ b/net/802/psnap.c	2005-03-01 23:39:17 -08:00
@@ -22,7 +22,7 @@
 #include <linux/init.h>
 
 static LIST_HEAD(snap_list);
-static spinlock_t snap_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(snap_lock);
 static struct llc_sap *snap_sap;
 
 /*
diff -Nru a/net/802/tr.c b/net/802/tr.c
--- a/net/802/tr.c	2005-03-01 23:38:52 -08:00
+++ b/net/802/tr.c	2005-03-01 23:38:52 -08:00
@@ -66,7 +66,7 @@
  
 static struct rif_cache_s *rif_table[RIF_TABLE_SIZE];
 
-static spinlock_t rif_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(rif_lock);
 
 
 /*
@@ -98,8 +98,9 @@
  *	makes this a little more exciting than on ethernet.
  */
  
-int tr_header(struct sk_buff *skb, struct net_device *dev, unsigned short type,
-              void *daddr, void *saddr, unsigned len) 
+static int tr_header(struct sk_buff *skb, struct net_device *dev,
+		     unsigned short type,
+		     void *daddr, void *saddr, unsigned len) 
 {
 	struct trh_hdr *trh;
 	int hdr_len;
@@ -153,7 +154,7 @@
  *	can now send the packet.
  */
  
-int tr_rebuild_header(struct sk_buff *skb) 
+static int tr_rebuild_header(struct sk_buff *skb) 
 {
 	struct trh_hdr *trh=(struct trh_hdr *)skb->data;
 	struct trllc *trllc=(struct trllc *)(skb->data+sizeof(struct trh_hdr));
diff -Nru a/net/8021q/vlan.c b/net/8021q/vlan.c
--- a/net/8021q/vlan.c	2005-03-01 23:39:09 -08:00
+++ b/net/8021q/vlan.c	2005-03-01 23:39:09 -08:00
@@ -40,7 +40,7 @@
 /* Global VLAN variables */
 
 /* Our listing of VLAN group(s) */
-struct hlist_head vlan_group_hash[VLAN_GRP_HASH_SIZE];
+static struct hlist_head vlan_group_hash[VLAN_GRP_HASH_SIZE];
 #define vlan_grp_hashfn(IDX)	((((IDX) >> VLAN_GRP_HASH_SHIFT) ^ (IDX)) & VLAN_GRP_HASH_MASK)
 
 static char vlan_fullname[] = "802.1Q VLAN Support";
@@ -52,7 +52,7 @@
 static int vlan_ioctl_handler(void __user *);
 static int unregister_vlan_dev(struct net_device *, unsigned short );
 
-struct notifier_block vlan_notifier_block = {
+static struct notifier_block vlan_notifier_block = {
 	.notifier_call = vlan_device_event,
 };
 
@@ -61,9 +61,6 @@
 /* Determines interface naming scheme. */
 unsigned short vlan_name_type = VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD;
 
-/* DO reorder the header by default */
-unsigned short vlan_default_dev_flags = 1;
-
 static struct packet_type vlan_packet_type = {
 	.type = __constant_htons(ETH_P_8021Q),
 	.func = vlan_skb_recv, /* VLAN receive method */
@@ -490,7 +487,7 @@
 	VLAN_DEV_INFO(new_dev)->vlan_id = VLAN_ID; /* 1 through VLAN_VID_MASK */
 	VLAN_DEV_INFO(new_dev)->real_dev = real_dev;
 	VLAN_DEV_INFO(new_dev)->dent = NULL;
-	VLAN_DEV_INFO(new_dev)->flags = vlan_default_dev_flags;
+	VLAN_DEV_INFO(new_dev)->flags = 1;
 
 #ifdef VLAN_DEBUG
 	printk(VLAN_DBG "About to go find the group for idx: %i\n",
diff -Nru a/net/8021q/vlan.h b/net/8021q/vlan.h
--- a/net/8021q/vlan.h	2005-03-01 23:39:07 -08:00
+++ b/net/8021q/vlan.h	2005-03-01 23:39:07 -08:00
@@ -33,7 +33,6 @@
 #define VLAN_GRP_HASH_SHIFT	5
 #define VLAN_GRP_HASH_SIZE	(1 << VLAN_GRP_HASH_SHIFT)
 #define VLAN_GRP_HASH_MASK	(VLAN_GRP_HASH_SIZE - 1)
-extern struct  hlist_head vlan_group_hash[VLAN_GRP_HASH_SIZE];
 
 /*  Find a VLAN device by the MAC address of its Ethernet device, and
  *  it's VLAN ID.  The default configuration is to have VLAN's scope
diff -Nru a/net/8021q/vlanproc.c b/net/8021q/vlanproc.c
--- a/net/8021q/vlanproc.c	2005-03-01 23:38:55 -08:00
+++ b/net/8021q/vlanproc.c	2005-03-01 23:38:55 -08:00
@@ -239,7 +239,7 @@
  */
 
 /* starting at dev, find a VLAN device */
-struct net_device *vlan_skip(struct net_device *dev) 
+static struct net_device *vlan_skip(struct net_device *dev) 
 {
 	while (dev && !(dev->priv_flags & IFF_802_1Q_VLAN)) 
 		dev = dev->next;
diff -Nru a/net/8021q/vlanproc.h b/net/8021q/vlanproc.h
--- a/net/8021q/vlanproc.h	2005-03-01 23:39:17 -08:00
+++ b/net/8021q/vlanproc.h	2005-03-01 23:39:17 -08:00
@@ -11,8 +11,8 @@
 
 #define vlan_proc_init()	(0)
 #define vlan_proc_cleanup()	do {} while(0)
-#define vlan_proc_add_dev(dev)	((void)(dev), 0)
-#define vlan_proc_rem_dev(dev)	((void)(dev), 0)
+#define vlan_proc_add_dev(dev)	({(void)(dev), 0;})
+#define vlan_proc_rem_dev(dev)	({(void)(dev), 0;})
 
 #endif
 
diff -Nru a/net/Kconfig b/net/Kconfig
--- a/net/Kconfig	2005-03-01 23:38:52 -08:00
+++ b/net/Kconfig	2005-03-01 23:38:52 -08:00
@@ -621,7 +621,7 @@
 	  stress testing and performance analysis.  If you don't understand
 	  what was just said, you don't need it: say N.
 
-	  Documentation on how to use the packet generaor can be found
+	  Documentation on how to use the packet generator can be found
 	  at <file:Documentation/networking/pktgen.txt>.
 
 	  To compile this code as a module, choose M here: the
diff -Nru a/net/appletalk/aarp.c b/net/appletalk/aarp.c
--- a/net/appletalk/aarp.c	2005-03-01 23:39:16 -08:00
+++ b/net/appletalk/aarp.c	2005-03-01 23:39:16 -08:00
@@ -77,7 +77,7 @@
 static int unresolved_count;
 
 /* One lock protects it all. */
-static rwlock_t aarp_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(aarp_lock);
 
 /* Used to walk the list and purge/kick entries.  */
 static struct timer_list aarp_timer;
@@ -199,7 +199,7 @@
  *	aarp_proxy_probe_network.
  */
 
-void aarp_send_probe(struct net_device *dev, struct atalk_addr *us)
+static void aarp_send_probe(struct net_device *dev, struct atalk_addr *us)
 {
 	struct elapaarp *eah;
 	int len = dev->hard_header_len + sizeof(*eah) + aarp_dl->header_length;
@@ -429,7 +429,7 @@
  * Probe a Phase 1 device or a device that requires its Net:Node to
  * be set via an ioctl.
  */
-void aarp_send_probe_phase1(struct atalk_iface *iface)
+static void aarp_send_probe_phase1(struct atalk_iface *iface)
 {
 	struct ifreq atreq;
 	struct sockaddr_at *sa = (struct sockaddr_at *)&atreq.ifr_addr;
diff -Nru a/net/appletalk/atalk_proc.c b/net/appletalk/atalk_proc.c
--- a/net/appletalk/atalk_proc.c	2005-03-01 23:39:10 -08:00
+++ b/net/appletalk/atalk_proc.c	2005-03-01 23:39:10 -08:00
@@ -205,21 +205,21 @@
 	return 0;
 }
 
-struct seq_operations atalk_seq_interface_ops = {
+static struct seq_operations atalk_seq_interface_ops = {
 	.start  = atalk_seq_interface_start,
 	.next   = atalk_seq_interface_next,
 	.stop   = atalk_seq_interface_stop,
 	.show   = atalk_seq_interface_show,
 };
 
-struct seq_operations atalk_seq_route_ops = {
+static struct seq_operations atalk_seq_route_ops = {
 	.start  = atalk_seq_route_start,
 	.next   = atalk_seq_route_next,
 	.stop   = atalk_seq_route_stop,
 	.show   = atalk_seq_route_show,
 };
 
-struct seq_operations atalk_seq_socket_ops = {
+static struct seq_operations atalk_seq_socket_ops = {
 	.start  = atalk_seq_socket_start,
 	.next   = atalk_seq_socket_next,
 	.stop   = atalk_seq_socket_stop,
diff -Nru a/net/appletalk/ddp.c b/net/appletalk/ddp.c
--- a/net/appletalk/ddp.c	2005-03-01 23:39:17 -08:00
+++ b/net/appletalk/ddp.c	2005-03-01 23:39:17 -08:00
@@ -9,6 +9,7 @@
  *		Wesley Craig <netatalk@umich.edu>
  *
  *	Fixes:
+ *		Neil Horman		:	Added missing device ioctls
  *		Michael Callahan	:	Made routing work
  *		Wesley Craig		:	Fix probing to listen to a
  *						passed node id.
@@ -71,7 +72,7 @@
 \**************************************************************************/
 
 HLIST_HEAD(atalk_sockets);
-rwlock_t atalk_sockets_lock = RW_LOCK_UNLOCKED;
+DEFINE_RWLOCK(atalk_sockets_lock);
 
 static inline void __atalk_insert_socket(struct sock *sk)
 {
@@ -193,10 +194,10 @@
 
 /* Anti-deadlock ordering is atalk_routes_lock --> iface_lock -DaveM */
 struct atalk_route *atalk_routes;
-rwlock_t atalk_routes_lock = RW_LOCK_UNLOCKED;
+DEFINE_RWLOCK(atalk_routes_lock);
 
 struct atalk_iface *atalk_interfaces;
-rwlock_t atalk_interfaces_lock = RW_LOCK_UNLOCKED;
+DEFINE_RWLOCK(atalk_interfaces_lock);
 
 /* For probing devices or in a routerless network */
 struct atalk_route atrtr_default;
@@ -612,7 +613,7 @@
  * Called when a device is downed. Just throw away any routes
  * via it.
  */
-void atrtr_device_down(struct net_device *dev)
+static void atrtr_device_down(struct net_device *dev)
 {
 	struct atalk_route **r = &atalk_routes;
 	struct atalk_route *tmp;
@@ -1806,6 +1807,8 @@
 		case SIOCSIFHWADDR:
 		case SIOCGIFFLAGS:
 		case SIOCSIFFLAGS:
+		case SIOCGIFTXQLEN:
+		case SIOCSIFTXQLEN:
 		case SIOCGIFMTU:
 		case SIOCGIFCONF:
 		case SIOCADDMULTI:
@@ -1854,12 +1857,12 @@
 	.notifier_call	= ddp_device_event,
 };
 
-struct packet_type ltalk_packet_type = {
+static struct packet_type ltalk_packet_type = {
 	.type		= __constant_htons(ETH_P_LOCALTALK),
 	.func		= ltalk_rcv,
 };
 
-struct packet_type ppptalk_packet_type = {
+static struct packet_type ppptalk_packet_type = {
 	.type		= __constant_htons(ETH_P_PPPTALK),
 	.func		= atalk_rcv,
 };
diff -Nru a/net/atm/addr.c b/net/atm/addr.c
--- a/net/atm/addr.c	2005-03-01 23:38:51 -08:00
+++ b/net/atm/addr.c	2005-03-01 23:38:51 -08:00
@@ -2,7 +2,6 @@
 
 /* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
 
-
 #include <linux/atm.h>
 #include <linux/atmdev.h>
 #include <linux/sched.h>
@@ -11,127 +10,121 @@
 #include "signaling.h"
 #include "addr.h"
 
-
 static int check_addr(struct sockaddr_atmsvc *addr)
 {
 	int i;
 
-	if (addr->sas_family != AF_ATMSVC) return -EAFNOSUPPORT;
+	if (addr->sas_family != AF_ATMSVC)
+		return -EAFNOSUPPORT;
 	if (!*addr->sas_addr.pub)
 		return *addr->sas_addr.prv ? 0 : -EINVAL;
-	for (i = 1; i < ATM_E164_LEN+1; i++) /* make sure it's \0-terminated */
-		if (!addr->sas_addr.pub[i]) return 0;
+	for (i = 1; i < ATM_E164_LEN + 1; i++)	/* make sure it's \0-terminated */
+		if (!addr->sas_addr.pub[i])
+			return 0;
 	return -EINVAL;
 }
 
-
-static int identical(struct sockaddr_atmsvc *a,struct sockaddr_atmsvc *b)
+static int identical(struct sockaddr_atmsvc *a, struct sockaddr_atmsvc *b)
 {
 	if (*a->sas_addr.prv)
-		if (memcmp(a->sas_addr.prv,b->sas_addr.prv,ATM_ESA_LEN))
+		if (memcmp(a->sas_addr.prv, b->sas_addr.prv, ATM_ESA_LEN))
 			return 0;
-	if (!*a->sas_addr.pub) return !*b->sas_addr.pub;
-	if (!*b->sas_addr.pub) return 0;
-	return !strcmp(a->sas_addr.pub,b->sas_addr.pub);
+	if (!*a->sas_addr.pub)
+		return !*b->sas_addr.pub;
+	if (!*b->sas_addr.pub)
+		return 0;
+	return !strcmp(a->sas_addr.pub, b->sas_addr.pub);
 }
 
-
 static void notify_sigd(struct atm_dev *dev)
 {
 	struct sockaddr_atmpvc pvc;
 
 	pvc.sap_addr.itf = dev->number;
-	sigd_enq(NULL,as_itf_notify,NULL,&pvc,NULL);
+	sigd_enq(NULL, as_itf_notify, NULL, &pvc, NULL);
 }
 
-
 void atm_reset_addr(struct atm_dev *dev)
 {
 	unsigned long flags;
-	struct atm_dev_addr *this;
+	struct atm_dev_addr *this, *p;
 
 	spin_lock_irqsave(&dev->lock, flags);
-	while (dev->local) {
-		this = dev->local;
-		dev->local = this->next;
-		kfree(this);
-	}
+	list_for_each_entry_safe(this, p, &dev->local, entry)
+	    kfree(this);
 	spin_unlock_irqrestore(&dev->lock, flags);
 	notify_sigd(dev);
 }
 
-
-int atm_add_addr(struct atm_dev *dev,struct sockaddr_atmsvc *addr)
+int atm_add_addr(struct atm_dev *dev, struct sockaddr_atmsvc *addr)
 {
 	unsigned long flags;
-	struct atm_dev_addr **walk;
+	struct atm_dev_addr *this;
 	int error;
 
 	error = check_addr(addr);
 	if (error)
 		return error;
 	spin_lock_irqsave(&dev->lock, flags);
-	for (walk = &dev->local; *walk; walk = &(*walk)->next)
-		if (identical(&(*walk)->addr,addr)) {
+	list_for_each_entry(this, &dev->local, entry) {
+		if (identical(&this->addr, addr)) {
 			spin_unlock_irqrestore(&dev->lock, flags);
 			return -EEXIST;
 		}
-	*walk = kmalloc(sizeof(struct atm_dev_addr), GFP_ATOMIC);
-	if (!*walk) {
+	}
+	this = kmalloc(sizeof(struct atm_dev_addr), GFP_ATOMIC);
+	if (!this) {
 		spin_unlock_irqrestore(&dev->lock, flags);
 		return -ENOMEM;
 	}
-	(*walk)->addr = *addr;
-	(*walk)->next = NULL;
+	this->addr = *addr;
+	list_add(&this->entry, &dev->local);
 	spin_unlock_irqrestore(&dev->lock, flags);
 	notify_sigd(dev);
 	return 0;
 }
 
-
-int atm_del_addr(struct atm_dev *dev,struct sockaddr_atmsvc *addr)
+int atm_del_addr(struct atm_dev *dev, struct sockaddr_atmsvc *addr)
 {
 	unsigned long flags;
-	struct atm_dev_addr **walk,*this;
+	struct atm_dev_addr *this;
 	int error;
 
 	error = check_addr(addr);
 	if (error)
 		return error;
 	spin_lock_irqsave(&dev->lock, flags);
-	for (walk = &dev->local; *walk; walk = &(*walk)->next)
-		if (identical(&(*walk)->addr,addr)) break;
-	if (!*walk) {
-		spin_unlock_irqrestore(&dev->lock, flags);
-		return -ENOENT;
+	list_for_each_entry(this, &dev->local, entry) {
+		if (identical(&this->addr, addr)) {
+			list_del(&this->entry);
+			spin_unlock_irqrestore(&dev->lock, flags);
+			kfree(this);
+			notify_sigd(dev);
+			return 0;
+		}
 	}
-	this = *walk;
-	*walk = this->next;
-	kfree(this);
 	spin_unlock_irqrestore(&dev->lock, flags);
-	notify_sigd(dev);
-	return 0;
+	return -ENOENT;
 }
 
-
-int atm_get_addr(struct atm_dev *dev,struct sockaddr_atmsvc __user *buf,int size)
+int atm_get_addr(struct atm_dev *dev, struct sockaddr_atmsvc __user * buf,
+		 size_t size)
 {
 	unsigned long flags;
-	struct atm_dev_addr *walk;
+	struct atm_dev_addr *this;
 	int total = 0, error;
 	struct sockaddr_atmsvc *tmp_buf, *tmp_bufp;
 
-
 	spin_lock_irqsave(&dev->lock, flags);
-	for (walk = dev->local; walk; walk = walk->next)
-		total += sizeof(struct sockaddr_atmsvc);
+	list_for_each_entry(this, &dev->local, entry)
+	    total += sizeof(struct sockaddr_atmsvc);
 	tmp_buf = tmp_bufp = kmalloc(total, GFP_ATOMIC);
 	if (!tmp_buf) {
 		spin_unlock_irqrestore(&dev->lock, flags);
 		return -ENOMEM;
 	}
-	for (walk = dev->local; walk; walk = walk->next)
-		memcpy(tmp_bufp++, &walk->addr, sizeof(struct sockaddr_atmsvc));
+	list_for_each_entry(this, &dev->local, entry)
+	    memcpy(tmp_bufp++, &this->addr, sizeof(struct sockaddr_atmsvc));
 	spin_unlock_irqrestore(&dev->lock, flags);
 	error = total > size ? -E2BIG : total;
 	if (copy_to_user(buf, tmp_buf, total < size ? total : size))
diff -Nru a/net/atm/addr.h b/net/atm/addr.h
--- a/net/atm/addr.h	2005-03-01 23:38:56 -08:00
+++ b/net/atm/addr.h	2005-03-01 23:38:56 -08:00
@@ -13,6 +13,6 @@
 void atm_reset_addr(struct atm_dev *dev);
 int atm_add_addr(struct atm_dev *dev,struct sockaddr_atmsvc *addr);
 int atm_del_addr(struct atm_dev *dev,struct sockaddr_atmsvc *addr);
-int atm_get_addr(struct atm_dev *dev,struct sockaddr_atmsvc __user *buf,int size);
+int atm_get_addr(struct atm_dev *dev,struct sockaddr_atmsvc __user *buf,size_t size);
 
 #endif
diff -Nru a/net/atm/br2684.c b/net/atm/br2684.c
--- a/net/atm/br2684.c	2005-03-01 23:39:18 -08:00
+++ b/net/atm/br2684.c	2005-03-01 23:39:18 -08:00
@@ -97,7 +97,7 @@
  * do read-locking under interrupt context, so write locking must block
  * the current CPU's interrupts
  */
-static rwlock_t devs_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(devs_lock);
 
 static LIST_HEAD(br2684_devs);
 
diff -Nru a/net/atm/common.c b/net/atm/common.c
--- a/net/atm/common.c	2005-03-01 23:39:18 -08:00
+++ b/net/atm/common.c	2005-03-01 23:39:18 -08:00
@@ -39,7 +39,7 @@
 #endif
 
 struct hlist_head vcc_hash[VCC_HTABLE_SIZE];
-rwlock_t vcc_sklist_lock = RW_LOCK_UNLOCKED;
+DEFINE_RWLOCK(vcc_sklist_lock);
 
 void __vcc_insert_socket(struct sock *sk)
 {
diff -Nru a/net/atm/lec.c b/net/atm/lec.c
--- a/net/atm/lec.c	2005-03-01 23:39:06 -08:00
+++ b/net/atm/lec.c	2005-03-01 23:39:06 -08:00
@@ -422,6 +422,7 @@
 static int 
 lec_atm_send(struct atm_vcc *vcc, struct sk_buff *skb)
 {
+	unsigned long flags;
         struct net_device *dev = (struct net_device*)vcc->proto_data;
         struct lec_priv *priv = (struct lec_priv*)dev->priv;
         struct atmlec_msg *mesg;
@@ -456,8 +457,10 @@
                 lec_flush_complete(priv, mesg->content.normal.flag);
                 break;
         case l_narp_req: /* LANE2: see 7.1.35 in the lane2 spec */
+		spin_lock_irqsave(&priv->lec_arp_lock, flags);
                 entry = lec_arp_find(priv, mesg->content.normal.mac_addr);
                 lec_arp_remove(priv, entry);
+		spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
 
                 if (mesg->content.normal.no_source_le_narp)
                         break;
@@ -1222,17 +1225,20 @@
 static int lane2_resolve(struct net_device *dev, u8 *dst_mac, int force,
     u8 **tlvs, u32 *sizeoftlvs)
 {
+	unsigned long flags;
         struct lec_priv *priv = (struct lec_priv *)dev->priv;
         struct lec_arp_table *table;
         struct sk_buff *skb;
         int retval;
 
         if (force == 0) {
+		spin_lock_irqsave(&priv->lec_arp_lock, flags);
                 table = lec_arp_find(priv, dst_mac);
+		spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
                 if(table == NULL)
                         return -1;
                 
-                *tlvs = kmalloc(table->sizeoftlvs, GFP_KERNEL);
+                *tlvs = kmalloc(table->sizeoftlvs, GFP_ATOMIC);
                 if (*tlvs == NULL)
                         return -1;
                 
@@ -1377,18 +1383,6 @@
 
 #define HASH(ch) (ch & (LEC_ARP_TABLE_SIZE -1))
 
-static __inline__ void 
-lec_arp_get(struct lec_priv *priv)
-{
-        atomic_inc(&priv->lec_arp_users);
-}
-
-static __inline__ void 
-lec_arp_put(struct lec_priv *priv)
-{
-        atomic_dec(&priv->lec_arp_users);
-}
-
 /*
  * Initialization of arp-cache
  */
@@ -1397,12 +1391,12 @@
 {
         unsigned short i;
 
-        for (i=0;i<LEC_ARP_TABLE_SIZE;i++) {
+        for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
                 priv->lec_arp_tables[i] = NULL;
         }        
 	spin_lock_init(&priv->lec_arp_lock);
         init_timer(&priv->lec_arp_timer);
-        priv->lec_arp_timer.expires = jiffies+LEC_ARP_REFRESH_INTERVAL;
+        priv->lec_arp_timer.expires = jiffies + LEC_ARP_REFRESH_INTERVAL;
         priv->lec_arp_timer.data = (unsigned long)priv;
         priv->lec_arp_timer.function = lec_arp_check_expire;
         add_timer(&priv->lec_arp_timer);
@@ -1439,12 +1433,9 @@
 static inline void 
 lec_arp_add(struct lec_priv *priv, struct lec_arp_table *to_add)
 {
-        unsigned long flags;
         unsigned short place;
         struct lec_arp_table *tmp;
 
-        spin_lock_irqsave(&priv->lec_arp_lock, flags);
-
         place = HASH(to_add->mac_addr[ETH_ALEN-1]);
         tmp = priv->lec_arp_tables[place];
         to_add->next = NULL;
@@ -1457,8 +1448,6 @@
                 tmp->next = to_add;
         }
 
-        spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
-
         DPRINTK("LEC_ARP: Added entry:%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n",
                 0xff&to_add->mac_addr[0], 0xff&to_add->mac_addr[1],
                 0xff&to_add->mac_addr[2], 0xff&to_add->mac_addr[3],
@@ -1472,15 +1461,11 @@
 lec_arp_remove(struct lec_priv *priv,
                struct lec_arp_table *to_remove)
 {
-        unsigned long flags;
         unsigned short place;
         struct lec_arp_table *tmp;
         int remove_vcc=1;
 
-        spin_lock_irqsave(&priv->lec_arp_lock, flags);
-
         if (!to_remove) {
-                spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
                 return -1;
         }
         place = HASH(to_remove->mac_addr[ETH_ALEN-1]);
@@ -1492,7 +1477,6 @@
                         tmp = tmp->next;
                 }
                 if (!tmp) {/* Entry was not found */
-                        spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
                         return -1;
                 }
         }
@@ -1505,7 +1489,7 @@
                 /*
                  * ESI_FLUSH_PENDING, ESI_FORWARD_DIRECT
                  */
-                for(place=0;place<LEC_ARP_TABLE_SIZE;place++) {
+                for(place = 0; place < LEC_ARP_TABLE_SIZE; place++) {
                         for(tmp = priv->lec_arp_tables[place]; tmp != NULL; tmp = tmp->next) {
                                 if (memcmp(tmp->atm_addr, to_remove->atm_addr,
                                            ATM_ESA_LEN)==0) {
@@ -1519,8 +1503,6 @@
         }
         skb_queue_purge(&to_remove->tx_wait); /* FIXME: good place for this? */
 
-        spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
-
         DPRINTK("LEC_ARP: Removed entry:%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n",
                 0xff&to_remove->mac_addr[0], 0xff&to_remove->mac_addr[1],
                 0xff&to_remove->mac_addr[2], 0xff&to_remove->mac_addr[3],
@@ -1704,6 +1686,7 @@
 void
 lec_arp_destroy(struct lec_priv *priv)
 {
+	unsigned long flags;
         struct lec_arp_table *entry, *next;
         int i;
 
@@ -1712,8 +1695,10 @@
         /*
          * Remove all entries
          */
-        for (i=0;i<LEC_ARP_TABLE_SIZE;i++) {
-                for(entry =priv->lec_arp_tables[i];entry != NULL; entry=next) {
+
+	spin_lock_irqsave(&priv->lec_arp_lock, flags);
+        for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
+                for(entry = priv->lec_arp_tables[i]; entry != NULL; entry=next) {
                         next = entry->next;
                         lec_arp_remove(priv, entry);
                         kfree(entry);
@@ -1748,7 +1733,8 @@
         priv->mcast_fwds = NULL;
         priv->mcast_vcc = NULL;
         memset(priv->lec_arp_tables, 0, 
-               sizeof(struct lec_arp_table*)*LEC_ARP_TABLE_SIZE);
+               sizeof(struct lec_arp_table *) * LEC_ARP_TABLE_SIZE);
+	spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
 }
 
 
@@ -1765,18 +1751,15 @@
         DPRINTK("LEC_ARP: lec_arp_find :%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n",
                 mac_addr[0]&0xff, mac_addr[1]&0xff, mac_addr[2]&0xff, 
                 mac_addr[3]&0xff, mac_addr[4]&0xff, mac_addr[5]&0xff);
-        lec_arp_get(priv);
         place = HASH(mac_addr[ETH_ALEN-1]);
   
         to_return = priv->lec_arp_tables[place];
         while(to_return) {
                 if (memcmp(mac_addr, to_return->mac_addr, ETH_ALEN) == 0) {
-                        lec_arp_put(priv);
                         return to_return;
                 }
                 to_return = to_return->next;
         }
-        lec_arp_put(priv);
         return NULL;
 }
 
@@ -1785,17 +1768,17 @@
 {
         struct lec_arp_table *to_return;
 
-        to_return=(struct lec_arp_table *)kmalloc(sizeof(struct lec_arp_table),
-                                                  GFP_ATOMIC);
+        to_return = (struct lec_arp_table *) kmalloc(sizeof(struct lec_arp_table),
+						     GFP_ATOMIC);
         if (!to_return) {
                 printk("LEC: Arp entry kmalloc failed\n");
                 return NULL;
         }
-        memset(to_return,0,sizeof(struct lec_arp_table));
+        memset(to_return, 0, sizeof(struct lec_arp_table));
         memcpy(to_return->mac_addr, mac_addr, ETH_ALEN);
         init_timer(&to_return->timer);
         to_return->timer.function = lec_arp_expire_arp;
-        to_return->timer.data = (unsigned long)to_return;
+        to_return->timer.data = (unsigned long) to_return;
         to_return->last_used = jiffies;
         to_return->priv = priv;
         skb_queue_head_init(&to_return->tx_wait);
@@ -1835,6 +1818,7 @@
 static void
 lec_arp_expire_vcc(unsigned long data)
 {
+	unsigned long flags;
         struct lec_arp_table *to_remove = (struct lec_arp_table*)data;
         struct lec_priv *priv = (struct lec_priv *)to_remove->priv;
         struct lec_arp_table *entry = NULL;
@@ -1846,6 +1830,8 @@
                 to_remove->vcc?to_remove->recv_vcc->vpi:0,
                 to_remove->vcc?to_remove->recv_vcc->vci:0);
         DPRINTK("eo:%p nf:%p\n",priv->lec_arp_empty_ones,priv->lec_no_forward);
+
+	spin_lock_irqsave(&priv->lec_arp_lock, flags);
         if (to_remove == priv->lec_arp_empty_ones)
                 priv->lec_arp_empty_ones = to_remove->next;
         else {
@@ -1866,6 +1852,8 @@
                                 entry->next = to_remove->next;
                 }
 	}
+	spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
+
         lec_arp_clear_vccs(to_remove);
         kfree(to_remove);
 }
@@ -1889,69 +1877,67 @@
 static void
 lec_arp_check_expire(unsigned long data)
 {
+	unsigned long flags;
         struct lec_priv *priv = (struct lec_priv *)data;
         struct lec_arp_table *entry, *next;
         unsigned long now;
         unsigned long time_to_check;
         int i;
 
-        DPRINTK("lec_arp_check_expire %p,%d\n",priv,
-                atomic_read(&priv->lec_arp_users));
+        DPRINTK("lec_arp_check_expire %p\n",priv);
         DPRINTK("expire: eo:%p nf:%p\n",priv->lec_arp_empty_ones,
                 priv->lec_no_forward);
-        if (!atomic_read(&priv->lec_arp_users)) {
-                lec_arp_get(priv);
-                now = jiffies;
-                for(i=0;i<LEC_ARP_TABLE_SIZE;i++) {
-                        for(entry = priv->lec_arp_tables[i]; entry != NULL; ) {
-                                if ((entry->flags) & LEC_REMOTE_FLAG && 
-                                    priv->topology_change)
-                                        time_to_check=priv->forward_delay_time;
-                                else
-                                        time_to_check = priv->aging_time;
-
-                                DPRINTK("About to expire: %lx - %lx > %lx\n",
-                                        now,entry->last_used, time_to_check);
-                                if( time_after(now, entry->last_used+
-                                   time_to_check) && 
-                                    !(entry->flags & LEC_PERMANENT_FLAG) &&
-                                    !(entry->mac_addr[0] & 0x01) ) { /* LANE2: 7.1.20 */
-                                        /* Remove entry */
-                                        DPRINTK("LEC:Entry timed out\n");
-                                        next = entry->next;      
-                                        lec_arp_remove(priv, entry);
-                                        kfree(entry);
-                                        entry = next;
-                                } else {
-                                        /* Something else */
-                                        if ((entry->status == ESI_VC_PENDING ||
-                                             entry->status == ESI_ARP_PENDING) 
-                                            && time_after_eq(now,
-                                            entry->timestamp +
-                                            priv->max_unknown_frame_time)) {
-                                                entry->timestamp = jiffies;
-                                                entry->packets_flooded = 0;
-                                                if (entry->status == ESI_VC_PENDING)
-                                                        send_to_lecd(priv, l_svc_setup, entry->mac_addr, entry->atm_addr, NULL);
-                                        }
-                                        if (entry->status == ESI_FLUSH_PENDING 
-                                           &&
-                                           time_after_eq(now, entry->timestamp+
-                                           priv->path_switching_delay)) {
-			                        struct sk_buff *skb;
-
- 				                while ((skb = skb_dequeue(&entry->tx_wait)) != NULL)
-					                lec_send(entry->vcc, skb, entry->priv);
-                                                entry->last_used = jiffies;
-                                                entry->status = 
-                                                        ESI_FORWARD_DIRECT;
-                                        }
-                                        entry = entry->next;
-                                }
-                        }
-                }
-                lec_arp_put(priv);
-        }
+	now = jiffies;
+	spin_lock_irqsave(&priv->lec_arp_lock, flags);
+	for(i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
+		for(entry = priv->lec_arp_tables[i]; entry != NULL; ) {
+			if ((entry->flags) & LEC_REMOTE_FLAG && 
+			    priv->topology_change)
+				time_to_check = priv->forward_delay_time;
+			else
+				time_to_check = priv->aging_time;
+
+			DPRINTK("About to expire: %lx - %lx > %lx\n",
+				now,entry->last_used, time_to_check);
+			if( time_after(now, entry->last_used+
+			   time_to_check) && 
+			    !(entry->flags & LEC_PERMANENT_FLAG) &&
+			    !(entry->mac_addr[0] & 0x01) ) { /* LANE2: 7.1.20 */
+				/* Remove entry */
+				DPRINTK("LEC:Entry timed out\n");
+				next = entry->next;      
+				lec_arp_remove(priv, entry);
+				kfree(entry);
+				entry = next;
+			} else {
+				/* Something else */
+				if ((entry->status == ESI_VC_PENDING ||
+				     entry->status == ESI_ARP_PENDING) 
+				    && time_after_eq(now,
+				    entry->timestamp +
+				    priv->max_unknown_frame_time)) {
+					entry->timestamp = jiffies;
+					entry->packets_flooded = 0;
+					if (entry->status == ESI_VC_PENDING)
+						send_to_lecd(priv, l_svc_setup, entry->mac_addr, entry->atm_addr, NULL);
+				}
+				if (entry->status == ESI_FLUSH_PENDING 
+				   &&
+				   time_after_eq(now, entry->timestamp+
+				   priv->path_switching_delay)) {
+					struct sk_buff *skb;
+
+					while ((skb = skb_dequeue(&entry->tx_wait)) != NULL)
+						lec_send(entry->vcc, skb, entry->priv);
+					entry->last_used = jiffies;
+					entry->status = 
+						ESI_FORWARD_DIRECT;
+				}
+				entry = entry->next;
+			}
+		}
+	}
+	spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
 
         mod_timer(&priv->lec_arp_timer, jiffies + LEC_ARP_REFRESH_INTERVAL);
 }
@@ -1963,9 +1949,11 @@
 lec_arp_resolve(struct lec_priv *priv, unsigned char *mac_to_find, int is_rdesc,
                 struct lec_arp_table **ret_entry)
 {
+	unsigned long flags;
         struct lec_arp_table *entry;
+	struct atm_vcc *found;
 
-        if (mac_to_find[0]&0x01) {
+        if (mac_to_find[0] & 0x01) {
                 switch (priv->lane_version) {
                 case 1:
                         return priv->mcast_vcc;
@@ -1979,6 +1967,7 @@
                 }
         }
 
+	spin_lock_irqsave(&priv->lec_arp_lock, flags);
         entry = lec_arp_find(priv, mac_to_find);
   
         if (entry) {
@@ -1986,7 +1975,8 @@
                         /* Connection Ok */
                         entry->last_used = jiffies;
                         *ret_entry = entry;
-                        return entry->vcc;
+                        found = entry->vcc;
+			goto out;
                 }
                 /* Data direct VC not yet set up, check to see if the unknown
                    frame count is greater than the limit. If the limit has
@@ -1996,7 +1986,8 @@
                     entry->packets_flooded<priv->maximum_unknown_frame_count) {
                         entry->packets_flooded++;
                         DPRINTK("LEC_ARP: Flooding..\n");
-                        return priv->mcast_vcc;
+                        found = priv->mcast_vcc;
+			goto out;
                 }
 		/* We got here because entry->status == ESI_FLUSH_PENDING
 		 * or BUS flood limit was reached for an entry which is
@@ -2004,13 +1995,14 @@
 		 */
                 *ret_entry = entry;
                 DPRINTK("lec: entry->status %d entry->vcc %p\n", entry->status, entry->vcc);
-                return NULL;
+                found = NULL;
         } else {
                 /* No matching entry was found */
                 entry = make_entry(priv, mac_to_find);
                 DPRINTK("LEC_ARP: Making entry\n");
                 if (!entry) {
-                        return priv->mcast_vcc;
+                        found = priv->mcast_vcc;
+			goto out;
                 }
                 lec_arp_add(priv, entry);
                 /* We want arp-request(s) to be sent */
@@ -2026,33 +2018,38 @@
                 entry->timer.expires = jiffies + (1*HZ);
                 entry->timer.function = lec_arp_expire_arp;
                 add_timer(&entry->timer);
-                return priv->mcast_vcc;
+                found = priv->mcast_vcc;
         }
+
+out:
+	spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
+	return found;
 }
 
 int
 lec_addr_delete(struct lec_priv *priv, unsigned char *atm_addr, 
                 unsigned long permanent)
 {
+	unsigned long flags;
         struct lec_arp_table *entry, *next;
         int i;
 
-        lec_arp_get(priv);
         DPRINTK("lec_addr_delete\n");
-        for(i=0;i<LEC_ARP_TABLE_SIZE;i++) {
-                for(entry=priv->lec_arp_tables[i];entry != NULL; entry=next) {
+	spin_lock_irqsave(&priv->lec_arp_lock, flags);
+        for(i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
+                for(entry = priv->lec_arp_tables[i]; entry != NULL; entry = next) {
                         next = entry->next;
                         if (!memcmp(atm_addr, entry->atm_addr, ATM_ESA_LEN)
                             && (permanent || 
                                 !(entry->flags & LEC_PERMANENT_FLAG))) {
-                                lec_arp_remove(priv, entry);
+				lec_arp_remove(priv, entry);
                                 kfree(entry);
                         }
-                        lec_arp_put(priv);
+			spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
                         return 0;
                 }
         }
-        lec_arp_put(priv);
+	spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
         return -1;
 }
 
@@ -2064,6 +2061,7 @@
                unsigned char *atm_addr, unsigned long remoteflag,
                unsigned int targetless_le_arp)
 {
+	unsigned long flags;
         struct lec_arp_table *entry, *tmp;
         int i;
 
@@ -2072,12 +2070,12 @@
                 mac_addr[0],mac_addr[1],mac_addr[2],mac_addr[3],
                 mac_addr[4],mac_addr[5]);
 
+	spin_lock_irqsave(&priv->lec_arp_lock, flags);
         entry = lec_arp_find(priv, mac_addr);
         if (entry == NULL && targetless_le_arp)
-                return;   /* LANE2: ignore targetless LE_ARPs for which
-                           * we have no entry in the cache. 7.1.30
-                           */
-        lec_arp_get(priv);
+                goto out;   /* LANE2: ignore targetless LE_ARPs for which
+                             * we have no entry in the cache. 7.1.30
+                             */
         if (priv->lec_arp_empty_ones) {
                 entry = priv->lec_arp_empty_ones;
                 if (!memcmp(entry->atm_addr, atm_addr, ATM_ESA_LEN)) {
@@ -2117,27 +2115,24 @@
                                 entry->flags|=LEC_REMOTE_FLAG;
                         else
                                 entry->flags&=~LEC_REMOTE_FLAG;
-                        lec_arp_put(priv);
                         DPRINTK("After update\n");
                         dump_arp_table(priv);
-                        return;
+                        goto out;
                 }
         }
         entry = lec_arp_find(priv, mac_addr);
         if (!entry) {
                 entry = make_entry(priv, mac_addr);
-                if (!entry) {
-                        lec_arp_put(priv);
-                        return;
-                }
+                if (!entry)
+			goto out;
                 entry->status = ESI_UNKNOWN;
                 lec_arp_add(priv, entry);
                 /* Temporary, changes before end of function */
         }
         memcpy(entry->atm_addr, atm_addr, ATM_ESA_LEN);
         del_timer(&entry->timer);
-        for(i=0;i<LEC_ARP_TABLE_SIZE;i++) {
-                for(tmp=priv->lec_arp_tables[i];tmp;tmp=tmp->next) {
+        for(i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
+                for(tmp = priv->lec_arp_tables[i]; tmp; tmp=tmp->next) {
                         if (entry != tmp &&
                             !memcmp(tmp->atm_addr, atm_addr,
                                     ATM_ESA_LEN)) { 
@@ -2166,7 +2161,8 @@
         }
         DPRINTK("After update2\n");
         dump_arp_table(priv);
-        lec_arp_put(priv);
+out:
+	spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
 }
 
 /*
@@ -2177,10 +2173,11 @@
               struct atm_vcc *vcc,
               void (*old_push)(struct atm_vcc *vcc, struct sk_buff *skb))
 {
+	unsigned long flags;
         struct lec_arp_table *entry;
         int i, found_entry=0;
 
-        lec_arp_get(priv);
+	spin_lock_irqsave(&priv->lec_arp_lock, flags);
         if (ioc_data->receive == 2) {
                 /* Vcc for Multicast Forward. No timer, LANEv2 7.1.20 and 2.3.5.3 */
 
@@ -2189,26 +2186,22 @@
                 entry = lec_arp_find(priv, bus_mac);
                 if (!entry) {
                         printk("LEC_ARP: Multicast entry not found!\n");
-                        lec_arp_put(priv);
-                        return;
+			goto out;
                 }
                 memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN);
                 entry->recv_vcc = vcc;
                 entry->old_recv_push = old_push;
 #endif
                 entry = make_entry(priv, bus_mac);
-                if (entry == NULL) {
-                        lec_arp_put(priv);
-                        return;
-                }
+                if (entry == NULL)
+			goto out;
                 del_timer(&entry->timer);
                 memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN);
                 entry->recv_vcc = vcc;
                 entry->old_recv_push = old_push;
                 entry->next = priv->mcast_fwds;
                 priv->mcast_fwds = entry;
-                lec_arp_put(priv);
-                return;
+                goto out;
         } else if (ioc_data->receive == 1) {
                 /* Vcc which we don't want to make default vcc, attach it
                    anyway. */
@@ -2224,10 +2217,8 @@
                         ioc_data->atm_addr[16],ioc_data->atm_addr[17],
                         ioc_data->atm_addr[18],ioc_data->atm_addr[19]);
                 entry = make_entry(priv, bus_mac);
-                if (entry == NULL) {
-                        lec_arp_put(priv);
-                        return;
-                }
+                if (entry == NULL)
+			goto out;
                 memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN);
                 memset(entry->mac_addr, 0, ETH_ALEN);
                 entry->recv_vcc = vcc;
@@ -2238,9 +2229,8 @@
                 add_timer(&entry->timer);
                 entry->next = priv->lec_no_forward;
                 priv->lec_no_forward = entry;
-                lec_arp_put(priv);
 		dump_arp_table(priv);
-                return;
+		goto out;
         }
         DPRINTK("LEC_ARP:Attaching data direct, default:%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x\n",
                 ioc_data->atm_addr[0],ioc_data->atm_addr[1],
@@ -2253,8 +2243,8 @@
                 ioc_data->atm_addr[14],ioc_data->atm_addr[15],
                 ioc_data->atm_addr[16],ioc_data->atm_addr[17],
                 ioc_data->atm_addr[18],ioc_data->atm_addr[19]);
-        for (i=0;i<LEC_ARP_TABLE_SIZE;i++) {
-                for (entry = priv->lec_arp_tables[i];entry;entry=entry->next) {
+        for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
+                for (entry = priv->lec_arp_tables[i]; entry; entry=entry->next) {
                         if (memcmp(ioc_data->atm_addr, entry->atm_addr, 
                                    ATM_ESA_LEN)==0) {
                                 DPRINTK("LEC_ARP: Attaching data direct\n");
@@ -2297,18 +2287,15 @@
                 }
         }
         if (found_entry) {
-                lec_arp_put(priv);
                 DPRINTK("After vcc was added\n");
                 dump_arp_table(priv);
-                return;
+		goto out;
         }
         /* Not found, snatch address from first data packet that arrives from
            this vcc */
         entry = make_entry(priv, bus_mac);
-        if (!entry) {
-                lec_arp_put(priv);
-                return;
-        }
+        if (!entry)
+		goto out;
         entry->vcc = vcc;
         entry->old_push = old_push;
         memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN);
@@ -2319,20 +2306,23 @@
         entry->timer.expires = jiffies + priv->vcc_timeout_period;
         entry->timer.function = lec_arp_expire_vcc;
         add_timer(&entry->timer);
-        lec_arp_put(priv);
         DPRINTK("After vcc was added\n");
 	dump_arp_table(priv);
+out:
+	spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
 }
 
 void
 lec_flush_complete(struct lec_priv *priv, unsigned long tran_id)
 {
+	unsigned long flags;
         struct lec_arp_table *entry;
         int i;
   
         DPRINTK("LEC:lec_flush_complete %lx\n",tran_id);
-        for (i=0;i<LEC_ARP_TABLE_SIZE;i++) {
-                for (entry=priv->lec_arp_tables[i];entry;entry=entry->next) {
+	spin_lock_irqsave(&priv->lec_arp_lock, flags);
+        for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
+                for (entry = priv->lec_arp_tables[i]; entry; entry=entry->next) {
                         if (entry->flush_tran_id == tran_id &&
                             entry->status == ESI_FLUSH_PENDING) {
 			        struct sk_buff *skb;
@@ -2344,6 +2334,7 @@
                         }
                 }
         }
+	spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
         dump_arp_table(priv);
 }
 
@@ -2351,24 +2342,29 @@
 lec_set_flush_tran_id(struct lec_priv *priv,
                       unsigned char *atm_addr, unsigned long tran_id)
 {
+	unsigned long flags;
         struct lec_arp_table *entry;
         int i;
 
-        for (i=0;i<LEC_ARP_TABLE_SIZE;i++)
-                for(entry=priv->lec_arp_tables[i];entry;entry=entry->next)
+	spin_lock_irqsave(&priv->lec_arp_lock, flags);
+        for (i = 0; i < LEC_ARP_TABLE_SIZE; i++)
+                for(entry = priv->lec_arp_tables[i]; entry; entry=entry->next)
                         if (!memcmp(atm_addr, entry->atm_addr, ATM_ESA_LEN)) {
                                 entry->flush_tran_id = tran_id;
                                 DPRINTK("Set flush transaction id to %lx for %p\n",tran_id,entry);
                         }
+	spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
 }
 
 int 
 lec_mcast_make(struct lec_priv *priv, struct atm_vcc *vcc)
 {
+	unsigned long flags;
         unsigned char mac_addr[] = {
                 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
         struct lec_arp_table *to_add;
 	struct lec_vcc_priv *vpriv;
+	int err = 0;
   
 	if (!(vpriv = kmalloc(sizeof(struct lec_vcc_priv), GFP_KERNEL)))
 		return -ENOMEM;
@@ -2376,13 +2372,13 @@
 	vpriv->old_pop = vcc->pop;
 	vcc->user_back = vpriv;
         vcc->pop = lec_pop;
-        lec_arp_get(priv);
+	spin_lock_irqsave(&priv->lec_arp_lock, flags);
         to_add = make_entry(priv, mac_addr);
         if (!to_add) {
-                lec_arp_put(priv);
 		vcc->pop = vpriv->old_pop;
 		kfree(vpriv);
-                return -ENOMEM;
+                err = -ENOMEM;
+		goto out;
         }
         memcpy(to_add->atm_addr, vcc->remote.sas_addr.prv, ATM_ESA_LEN);
         to_add->status = ESI_FORWARD_DIRECT;
@@ -2392,19 +2388,21 @@
         vcc->push = lec_push;
         priv->mcast_vcc = vcc;
         lec_arp_add(priv, to_add);
-        lec_arp_put(priv);
-        return 0;
+out:
+	spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
+        return err;
 }
 
 void
 lec_vcc_close(struct lec_priv *priv, struct atm_vcc *vcc)
 {
+	unsigned long flags;
         struct lec_arp_table *entry, *next;
         int i;
 
         DPRINTK("LEC_ARP: lec_vcc_close vpi:%d vci:%d\n",vcc->vpi,vcc->vci);
         dump_arp_table(priv);
-        lec_arp_get(priv);
+	spin_lock_irqsave(&priv->lec_arp_lock, flags);
         for(i=0;i<LEC_ARP_TABLE_SIZE;i++) {
                 for(entry = priv->lec_arp_tables[i];entry; entry=next) {
                         next = entry->next;
@@ -2466,7 +2464,7 @@
                 entry = next;
         }
 
-        lec_arp_put(priv);
+	spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
 	dump_arp_table(priv);
 }
 
@@ -2486,26 +2484,22 @@
 #endif
         src = hdr->h_source;
 
-        lec_arp_get(priv);
+	spin_lock_irqsave(&priv->lec_arp_lock, flags);
         entry = priv->lec_arp_empty_ones;
         if (vcc == entry->vcc) {
-		spin_lock_irqsave(&priv->lec_arp_lock, flags);
                 del_timer(&entry->timer);
                 memcpy(entry->mac_addr, src, ETH_ALEN);
                 entry->status = ESI_FORWARD_DIRECT;
                 entry->last_used = jiffies;
                 priv->lec_arp_empty_ones = entry->next;
-                spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
                 /* We might have got an entry */
-                if ((prev=lec_arp_find(priv,src))) {
+                if ((prev = lec_arp_find(priv,src))) {
                         lec_arp_remove(priv, prev);
                         kfree(prev);
                 }
                 lec_arp_add(priv, entry);
-                lec_arp_put(priv);
-                return;
+		goto out;
         }
-        spin_lock_irqsave(&priv->lec_arp_lock, flags);
         prev = entry;
         entry = entry->next;
         while (entry && entry->vcc != vcc) {
@@ -2514,21 +2508,19 @@
         }
         if (!entry) {
                 DPRINTK("LEC_ARP: Arp_check_empties: entry not found!\n");
-                lec_arp_put(priv);
-                spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
-                return;
+		goto out;
         }
         del_timer(&entry->timer);
         memcpy(entry->mac_addr, src, ETH_ALEN);
         entry->status = ESI_FORWARD_DIRECT;
         entry->last_used = jiffies;
         prev->next = entry->next;
-        spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
         if ((prev = lec_arp_find(priv, src))) {
                 lec_arp_remove(priv, prev);
                 kfree(prev);
         }
         lec_arp_add(priv, entry);
-        lec_arp_put(priv);  
+out:
+	spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
 }
 MODULE_LICENSE("GPL");
diff -Nru a/net/atm/lec.h b/net/atm/lec.h
--- a/net/atm/lec.h	2005-03-01 23:38:55 -08:00
+++ b/net/atm/lec.h	2005-03-01 23:38:55 -08:00
@@ -95,7 +95,6 @@
            establishes multiple Multicast Forward VCCs to us. This list
            collects all those VCCs. LANEv1 client has only one item in this
            list. These entries are not aged out. */
-        atomic_t lec_arp_users;
         spinlock_t lec_arp_lock;
         struct atm_vcc *mcast_vcc; /* Default Multicast Send VCC */
         struct atm_vcc *lecd;
diff -Nru a/net/atm/resources.c b/net/atm/resources.c
--- a/net/atm/resources.c	2005-03-01 23:39:16 -08:00
+++ b/net/atm/resources.c	2005-03-01 23:39:16 -08:00
@@ -16,6 +16,7 @@
 #include <linux/kernel.h> /* for barrier */
 #include <linux/module.h>
 #include <linux/bitops.h>
+#include <linux/delay.h>
 #include <net/sock.h>	 /* for struct sock */
 
 #include "common.h"
@@ -24,7 +25,7 @@
 
 
 LIST_HEAD(atm_devs);
-spinlock_t atm_dev_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(atm_dev_lock);
 
 static struct atm_dev *__alloc_atm_dev(const char *type)
 {
@@ -38,6 +39,7 @@
 	dev->signal = ATM_PHY_SIG_UNKNOWN;
 	dev->link_rate = ATM_OC3_PCR;
 	spin_lock_init(&dev->lock);
+	INIT_LIST_HEAD(&dev->local);
 
 	return dev;
 }
@@ -137,8 +139,7 @@
 
         warning_time = jiffies;
         while (atomic_read(&dev->refcnt) != 1) {
-                current->state = TASK_INTERRUPTIBLE;
-                schedule_timeout(HZ / 4);
+                msleep(250);
                 if ((jiffies - warning_time) > 10 * HZ) {
                         printk(KERN_EMERG "atm_dev_deregister: waiting for "
                                "dev %d to become free. Usage count = %d\n",
diff -Nru a/net/atm/svc.c b/net/atm/svc.c
--- a/net/atm/svc.c	2005-03-01 23:39:07 -08:00
+++ b/net/atm/svc.c	2005-03-01 23:39:07 -08:00
@@ -67,13 +67,12 @@
 	/* beware - socket is still in use by atmsigd until the last
 	   as_indicate has been answered */
 	while ((skb = skb_dequeue(&vcc->sk->sk_receive_queue)) != NULL) {
+		atm_return(vcc, skb->truesize);
 		DPRINTK("LISTEN REL\n");
 		sigd_enq2(NULL,as_reject,vcc,NULL,NULL,&vcc->qos,0);
 		dev_kfree_skb(skb);
 	}
-	clear_bit(ATM_VF_REGIS,&vcc->flags);
-	clear_bit(ATM_VF_RELEASED,&vcc->flags);
-	clear_bit(ATM_VF_CLOSE,&vcc->flags);
+	clear_bit(ATM_VF_REGIS, &vcc->flags);
 	/* ... may retry later */
 }
 
@@ -90,10 +89,8 @@
 		/* VCC pointer is used as a reference, so we must not free it
 		   (thereby subjecting it to re-use) before all pending connections
 	           are closed */
-		sock_hold(sk);
-		vcc_release(sock);
 		svc_disconnect(vcc);
-		sock_put(sk);
+		vcc_release(sock);
 	}
 	return 0;
 }
@@ -286,7 +283,8 @@
  */
 	if (!(error = vcc_connect(sock, vcc->itf, vcc->vpi, vcc->vci)))
 		sock->state = SS_CONNECTED;
-	else (void) svc_disconnect(vcc);
+	else
+		(void) svc_disconnect(vcc);
 out:
 	release_sock(sk);
 	return error;
diff -Nru a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
--- a/net/ax25/af_ax25.c	2005-03-01 23:39:16 -08:00
+++ b/net/ax25/af_ax25.c	2005-03-01 23:39:16 -08:00
@@ -52,7 +52,7 @@
 
 
 HLIST_HEAD(ax25_list);
-spinlock_t ax25_list_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(ax25_list_lock);
 
 static struct proto_ops ax25_proto_ops;
 
@@ -207,8 +207,16 @@
 			continue;
 		if (s->ax25_dev == NULL)
 			continue;
-		if (ax25cmp(&s->source_addr, src_addr) == 0 &&
-		    ax25cmp(&s->dest_addr, dest_addr) == 0) {
+		if (ax25cmp(&s->source_addr, src_addr) == 0 && ax25cmp(&s->dest_addr, dest_addr) == 0 && s->ax25_dev->dev == dev) {
+			if (digi != NULL && digi->ndigi != 0) {
+				if (s->digipeat == NULL)
+					continue;
+				if (ax25digicmp(s->digipeat, digi) != 0)
+					continue;
+			} else {
+				if (s->digipeat != NULL && s->digipeat->ndigi != 0)
+					continue;
+			}
 			ax25_cb_hold(s);
 			spin_unlock_bh(&ax25_list_lock);
 
@@ -755,7 +763,7 @@
 	return res;
 }
 
-int ax25_create(struct socket *sock, int protocol)
+static int ax25_create(struct socket *sock, int protocol)
 {
 	struct sock *sk;
 	ax25_cb *ax25;
diff -Nru a/net/ax25/ax25_dev.c b/net/ax25/ax25_dev.c
--- a/net/ax25/ax25_dev.c	2005-03-01 23:38:53 -08:00
+++ b/net/ax25/ax25_dev.c	2005-03-01 23:38:53 -08:00
@@ -32,7 +32,7 @@
 #include <linux/init.h>
 
 ax25_dev *ax25_dev_list;
-spinlock_t ax25_dev_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(ax25_dev_lock);
 
 ax25_dev *ax25_addr_ax25dev(ax25_address *addr)
 {
diff -Nru a/net/ax25/ax25_ds_subr.c b/net/ax25/ax25_ds_subr.c
--- a/net/ax25/ax25_ds_subr.c	2005-03-01 23:39:16 -08:00
+++ b/net/ax25/ax25_ds_subr.c	2005-03-01 23:39:16 -08:00
@@ -174,7 +174,7 @@
 	return res;
 }
 
-void ax25_dev_dama_on(ax25_dev *ax25_dev)
+static void ax25_dev_dama_on(ax25_dev *ax25_dev)
 {
 	if (ax25_dev == NULL)
 		return;
diff -Nru a/net/ax25/ax25_iface.c b/net/ax25/ax25_iface.c
--- a/net/ax25/ax25_iface.c	2005-03-01 23:39:17 -08:00
+++ b/net/ax25/ax25_iface.c	2005-03-01 23:39:17 -08:00
@@ -34,20 +34,20 @@
 	unsigned int pid;
 	int (*func)(struct sk_buff *, ax25_cb *);
 } *protocol_list = NULL;
-static rwlock_t protocol_list_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(protocol_list_lock);
 
 static struct linkfail_struct {
 	struct linkfail_struct *next;
 	void (*func)(ax25_cb *, int);
 } *linkfail_list = NULL;
-static spinlock_t linkfail_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(linkfail_lock);
 
 static struct listen_struct {
 	struct listen_struct *next;
 	ax25_address  callsign;
 	struct net_device *dev;
 } *listen_list = NULL;
-static spinlock_t listen_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(listen_lock);
 
 int ax25_protocol_register(unsigned int pid,
 	int (*func)(struct sk_buff *, ax25_cb *))
diff -Nru a/net/ax25/ax25_out.c b/net/ax25/ax25_out.c
--- a/net/ax25/ax25_out.c	2005-03-01 23:39:09 -08:00
+++ b/net/ax25/ax25_out.c	2005-03-01 23:39:09 -08:00
@@ -32,7 +32,7 @@
 #include <linux/mm.h>
 #include <linux/interrupt.h>
 
-static spinlock_t ax25_frag_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(ax25_frag_lock);
 
 ax25_cb *ax25_send_frame(struct sk_buff *skb, int paclen, ax25_address *src, ax25_address *dest, ax25_digi *digi, struct net_device *dev)
 {
diff -Nru a/net/ax25/ax25_route.c b/net/ax25/ax25_route.c
--- a/net/ax25/ax25_route.c	2005-03-01 23:39:07 -08:00
+++ b/net/ax25/ax25_route.c	2005-03-01 23:39:07 -08:00
@@ -37,7 +37,7 @@
 #include <linux/seq_file.h>
 
 static ax25_route *ax25_route_list;
-static rwlock_t ax25_route_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(ax25_route_lock);
 
 static ax25_route *ax25_get_route(ax25_address *, struct net_device *);
 
diff -Nru a/net/ax25/ax25_uid.c b/net/ax25/ax25_uid.c
--- a/net/ax25/ax25_uid.c	2005-03-01 23:38:53 -08:00
+++ b/net/ax25/ax25_uid.c	2005-03-01 23:38:53 -08:00
@@ -42,7 +42,7 @@
  */
 
 static ax25_uid_assoc *ax25_uid_list;
-static rwlock_t ax25_uid_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(ax25_uid_lock);
 
 int ax25_uid_policy = 0;
 
diff -Nru a/net/bluetooth/cmtp/capi.c b/net/bluetooth/cmtp/capi.c
--- a/net/bluetooth/cmtp/capi.c	2005-03-01 23:39:07 -08:00
+++ b/net/bluetooth/cmtp/capi.c	2005-03-01 23:39:07 -08:00
@@ -35,6 +35,7 @@
 #include <linux/socket.h>
 #include <linux/ioctl.h>
 #include <linux/file.h>
+#include <linux/wait.h>
 #include <net/sock.h>
 
 #include <linux/isdn/capilli.h>
@@ -139,6 +140,19 @@
 	return session->msgnum;
 }
 
+static void cmtp_send_capimsg(struct cmtp_session *session, struct sk_buff *skb)
+{
+	struct cmtp_scb *scb = (void *) skb->cb;
+
+	BT_DBG("session %p skb %p len %d", session, skb, skb->len);
+
+	scb->id = -1;
+	scb->data = (CAPIMSG_COMMAND(skb->data) == CAPI_DATA_B3);
+
+	skb_queue_tail(&session->transmit, skb);
+
+	cmtp_schedule(session);
+}
 
 static void cmtp_send_interopmsg(struct cmtp_session *session,
 					__u8 subcmd, __u16 appl, __u16 msgnum,
@@ -337,21 +351,6 @@
 	capi_ctr_handle_message(ctrl, appl, skb);
 }
 
-void cmtp_send_capimsg(struct cmtp_session *session, struct sk_buff *skb)
-{
-	struct cmtp_scb *scb = (void *) skb->cb;
-
-	BT_DBG("session %p skb %p len %d", session, skb, skb->len);
-
-	scb->id = -1;
-	scb->data = (CAPIMSG_COMMAND(skb->data) == CAPI_DATA_B3);
-
-	skb_queue_tail(&session->transmit, skb);
-
-	cmtp_schedule(session);
-}
-
-
 static int cmtp_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
 {
 	BT_DBG("ctrl %p data %p", ctrl, data);
@@ -442,10 +441,8 @@
 
 static void cmtp_release_appl(struct capi_ctr *ctrl, __u16 appl)
 {
-	DECLARE_WAITQUEUE(wait, current);
 	struct cmtp_session *session = ctrl->driverdata;
 	struct cmtp_application *application;
-	unsigned long timeo = CMTP_INTEROP_TIMEOUT;
 
 	BT_DBG("ctrl %p appl %d", ctrl, appl);
 
@@ -460,20 +457,8 @@
 	cmtp_send_interopmsg(session, CAPI_REQ, application->mapping, application->msgnum,
 				CAPI_FUNCTION_RELEASE, NULL, 0);
 
-	add_wait_queue(&session->wait, &wait);
-	while (timeo) {
-		set_current_state(TASK_INTERRUPTIBLE);
-
-		if (application->state == BT_CLOSED)
-			break;
-
-		if (signal_pending(current))
-			break;
-
-		timeo = schedule_timeout(timeo);
-	}
-	set_current_state(TASK_RUNNING);
-	remove_wait_queue(&session->wait, &wait);
+	wait_event_interruptible_timeout(session->wait,
+			(application->state == BT_CLOSED), CMTP_INTEROP_TIMEOUT);
 
 	cmtp_application_del(session, application);
 }
@@ -543,9 +528,8 @@
 
 int cmtp_attach_device(struct cmtp_session *session)
 {
-	DECLARE_WAITQUEUE(wait, current);
-	unsigned long timeo = CMTP_INTEROP_TIMEOUT;
 	unsigned char buf[4];
+	long ret;
 
 	BT_DBG("session %p", session);
 
@@ -554,29 +538,16 @@
 	cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, CMTP_INITIAL_MSGNUM,
 				CAPI_FUNCTION_GET_PROFILE, buf, 4);
 
-	add_wait_queue(&session->wait, &wait);
-	while (timeo) {
-		set_current_state(TASK_INTERRUPTIBLE);
-
-		if (session->ncontroller)
-			break;
-
-		if (signal_pending(current))
-			break;
-
-		timeo = schedule_timeout(timeo);
-	}
-	set_current_state(TASK_RUNNING);
-	remove_wait_queue(&session->wait, &wait);
-
+	ret = wait_event_interruptible_timeout(session->wait,
+			session->ncontroller, CMTP_INTEROP_TIMEOUT);
+	
 	BT_INFO("Found %d CAPI controller(s) on device %s", session->ncontroller, session->name);
 
-	if (!timeo)
+	if (!ret)
 		return -ETIMEDOUT;
 
 	if (!session->ncontroller)
 		return -ENODEV;
-
 
 	if (session->ncontroller > 1)
 		BT_INFO("Setting up only CAPI controller 1");
diff -Nru a/net/bluetooth/cmtp/cmtp.h b/net/bluetooth/cmtp/cmtp.h
--- a/net/bluetooth/cmtp/cmtp.h	2005-03-01 23:39:07 -08:00
+++ b/net/bluetooth/cmtp/cmtp.h	2005-03-01 23:39:07 -08:00
@@ -120,7 +120,6 @@
 void cmtp_detach_device(struct cmtp_session *session);
 
 void cmtp_recv_capimsg(struct cmtp_session *session, struct sk_buff *skb);
-void cmtp_send_capimsg(struct cmtp_session *session, struct sk_buff *skb);
 
 static inline void cmtp_schedule(struct cmtp_session *session)
 {
diff -Nru a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
--- a/net/bluetooth/hci_conn.c	2005-03-01 23:39:17 -08:00
+++ b/net/bluetooth/hci_conn.c	2005-03-01 23:39:17 -08:00
@@ -53,7 +53,7 @@
 #define BT_DBG(D...)
 #endif
 
-void hci_acl_connect(struct hci_conn *conn)
+static void hci_acl_connect(struct hci_conn *conn)
 {
 	struct hci_dev *hdev = conn->hdev;
 	struct inquiry_entry *ie;
@@ -226,7 +226,7 @@
 	list_for_each(p, &hci_dev_list) {
 		struct hci_dev *d = list_entry(p, struct hci_dev, list);
 
-		if (!test_bit(HCI_UP, &d->flags))
+		if (!test_bit(HCI_UP, &d->flags) || test_bit(HCI_RAW, &d->flags))
 			continue;
 
 		/* Simple routing: 
diff -Nru a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
--- a/net/bluetooth/hci_core.c	2005-03-01 23:38:54 -08:00
+++ b/net/bluetooth/hci_core.c	2005-03-01 23:38:54 -08:00
@@ -59,15 +59,15 @@
 static void hci_tx_task(unsigned long arg);
 static void hci_notify(struct hci_dev *hdev, int event);
 
-rwlock_t hci_task_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(hci_task_lock);
 
 /* HCI device list */
 LIST_HEAD(hci_dev_list);
-rwlock_t hci_dev_list_lock = RW_LOCK_UNLOCKED;
+DEFINE_RWLOCK(hci_dev_list_lock);
 
 /* HCI callback list */
 LIST_HEAD(hci_cb_list);
-rwlock_t hci_cb_list_lock = RW_LOCK_UNLOCKED;
+DEFINE_RWLOCK(hci_cb_list_lock);
 
 /* HCI protocols */
 #define HCI_MAX_PROTO	2
@@ -106,7 +106,7 @@
 	}
 }
 
-void hci_req_cancel(struct hci_dev *hdev, int err)
+static void hci_req_cancel(struct hci_dev *hdev, int err)
 {
 	BT_DBG("%s err 0x%2.2x", hdev->name, err);
 
@@ -183,10 +183,22 @@
 
 static void hci_init_req(struct hci_dev *hdev, unsigned long opt)
 {
+	struct sk_buff *skb;
 	__u16 param;
 
 	BT_DBG("%s %ld", hdev->name, opt);
 
+	/* Driver initialization */
+
+	/* Special commands */
+	while ((skb = skb_dequeue(&hdev->driver_init))) {
+		skb->pkt_type = HCI_COMMAND_PKT;
+		skb->dev = (void *) hdev;
+		skb_queue_tail(&hdev->cmd_q, skb);
+		hci_sched_cmd(hdev);
+	}
+	skb_queue_purge(&hdev->driver_init);
+
 	/* Mandatory initialization */
 
 	/* Reset */
@@ -457,6 +469,9 @@
 		goto done;
 	}
 
+	if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
+		set_bit(HCI_RAW, &hdev->flags);
+
 	if (hdev->open(hdev)) {
 		ret = -EIO;
 		goto done;
@@ -532,9 +547,11 @@
 	/* Reset device */
 	skb_queue_purge(&hdev->cmd_q);
 	atomic_set(&hdev->cmd_cnt, 1);
-	set_bit(HCI_INIT, &hdev->flags);
-	__hci_request(hdev, hci_reset_req, 0, HZ/4);
-	clear_bit(HCI_INIT, &hdev->flags);
+	if (!test_bit(HCI_RAW, &hdev->flags)) {
+		set_bit(HCI_INIT, &hdev->flags);
+		__hci_request(hdev, hci_reset_req, 0, HZ/4);
+		clear_bit(HCI_INIT, &hdev->flags);
+	}
 
 	/* Kill cmd task */
 	tasklet_kill(&hdev->cmd_task);
@@ -604,7 +621,8 @@
 	atomic_set(&hdev->cmd_cnt, 1); 
 	hdev->acl_cnt = 0; hdev->sco_cnt = 0;
 
-	ret = __hci_request(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT);
+	if (!test_bit(HCI_RAW, &hdev->flags))
+		ret = __hci_request(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT);
 
 done:
 	tasklet_enable(&hdev->tx_task);
@@ -786,6 +804,8 @@
 
 	memset(hdev, 0, sizeof(struct hci_dev));
 
+	skb_queue_head_init(&hdev->driver_init);
+
 	return hdev;
 }
 EXPORT_SYMBOL(hci_alloc_dev);
@@ -793,6 +813,8 @@
 /* Free HCI device */
 void hci_free_dev(struct hci_dev *hdev)
 {
+	skb_queue_purge(&hdev->driver_init);
+
 	/* will free via class release */
 	class_device_put(&hdev->class_dev);
 }
@@ -1192,10 +1214,12 @@
 
 	BT_DBG("%s", hdev->name);
 
-	/* ACL tx timeout must be longer than maximum
-	 * link supervision timeout (40.9 seconds) */
-	if (!hdev->acl_cnt && (jiffies - hdev->acl_last_tx) > (HZ * 45))
-		hci_acl_tx_to(hdev);
+	if (!test_bit(HCI_RAW, &hdev->flags)) {
+		/* ACL tx timeout must be longer than maximum
+		 * link supervision timeout (40.9 seconds) */
+		if (!hdev->acl_cnt && (jiffies - hdev->acl_last_tx) > (HZ * 45))
+			hci_acl_tx_to(hdev);
+	}
 
 	while (hdev->acl_cnt && (conn = hci_low_sent(hdev, ACL_LINK, &quote))) {
 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
diff -Nru a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
--- a/net/bluetooth/hci_event.c	2005-03-01 23:38:44 -08:00
+++ b/net/bluetooth/hci_event.c	2005-03-01 23:38:44 -08:00
@@ -818,6 +818,30 @@
 {
 }
 
+/* Clock Offset */
+static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	struct hci_ev_clock_offset *ev = (struct hci_ev_clock_offset *) skb->data;
+	struct hci_conn *conn = NULL;
+	__u16 handle = __le16_to_cpu(ev->handle);
+
+	BT_DBG("%s status %d", hdev->name, ev->status);
+
+	hci_dev_lock(hdev);
+
+	conn = hci_conn_hash_lookup_handle(hdev, handle);
+	if (conn && !ev->status) {
+		struct inquiry_entry *ie;
+
+		if ((ie = hci_inquiry_cache_lookup(hdev, &conn->dst))) {
+			ie->data.clock_offset = ev->clock_offset;
+			ie->timestamp = jiffies;
+		}
+	}
+
+	hci_dev_unlock(hdev);
+}
+
 void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
 {
 	struct hci_event_hdr *hdr = (struct hci_event_hdr *) skb->data;
@@ -884,6 +908,10 @@
 
 	case HCI_EV_LINK_KEY_NOTIFY:
 		hci_link_key_notify_evt(hdev, skb);
+		break;
+
+	case HCI_EV_CLOCK_OFFSET:
+		hci_clock_offset_evt(hdev, skb);
 		break;
 
 	case HCI_EV_CMD_STATUS:
diff -Nru a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
--- a/net/bluetooth/hci_sock.c	2005-03-01 23:38:58 -08:00
+++ b/net/bluetooth/hci_sock.c	2005-03-01 23:38:58 -08:00
@@ -179,6 +179,9 @@
 		if (!capable(CAP_NET_ADMIN))
 			return -EACCES;
 
+		if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
+			return -EPERM;
+
 		if (arg)
 			set_bit(HCI_RAW, &hdev->flags);
 		else
@@ -447,7 +450,7 @@
 	goto done;
 }
 
-int hci_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int len)
+static int hci_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int len)
 {
 	struct hci_ufilter uf = { .opcode = 0 };
 	struct sock *sk = sock->sk;
@@ -514,7 +517,7 @@
 	return err;
 }
 
-int hci_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen)
+static int hci_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen)
 {
 	struct hci_ufilter uf;
 	struct sock *sk = sock->sk;
@@ -567,7 +570,7 @@
 	return 0;
 }
 
-struct proto_ops hci_sock_ops = {
+static struct proto_ops hci_sock_ops = {
 	.family		= PF_BLUETOOTH,
 	.owner		= THIS_MODULE,
 	.release	= hci_sock_release,
@@ -647,13 +650,13 @@
 	return NOTIFY_DONE;
 }
 
-struct net_proto_family hci_sock_family_ops = {
+static struct net_proto_family hci_sock_family_ops = {
 	.family	= PF_BLUETOOTH,
 	.owner	= THIS_MODULE,
 	.create	= hci_sock_create,
 };
 
-struct notifier_block hci_sock_nblock = {
+static struct notifier_block hci_sock_nblock = {
 	.notifier_call = hci_sock_dev_event
 };
 
diff -Nru a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c
--- a/net/bluetooth/hidp/core.c	2005-03-01 23:39:09 -08:00
+++ b/net/bluetooth/hidp/core.c	2005-03-01 23:39:09 -08:00
@@ -36,6 +36,7 @@
 #include <linux/ioctl.h>
 #include <linux/file.h>
 #include <linux/init.h>
+#include <linux/wait.h>
 #include <net/sock.h>
 
 #include <linux/input.h>
@@ -50,7 +51,7 @@
 #define BT_DBG(D...)
 #endif
 
-#define VERSION "1.0"
+#define VERSION "1.1"
 
 static DECLARE_RWSEM(hidp_session_sem);
 static LIST_HEAD(hidp_session_list);
@@ -74,6 +75,8 @@
 	150,158,159,128,136,177,178,176,142,152,173,140
 };
 
+static unsigned char hidp_mkeyspat[] = { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 };
+
 static struct hidp_session *__hidp_get_session(bdaddr_t *bdaddr)
 {
 	struct hidp_session *session;
@@ -130,7 +133,7 @@
 	struct sk_buff *skb;
 	unsigned char newleds;
 
-	BT_DBG("session %p hid %p data %p size %d", session, device, data, size);
+	BT_DBG("input %p type %d code %d value %d", dev, type, code, value);
 
 	if (type != EV_LED)
 		return -1;
@@ -151,7 +154,7 @@
 		return -ENOMEM;
 	}
 
-	*skb_put(skb, 1) = 0xa2;
+	*skb_put(skb, 1) = HIDP_TRANS_DATA | HIDP_DATA_RTYPE_OUPUT;
 	*skb_put(skb, 1) = 0x01;
 	*skb_put(skb, 1) = newleds;
 
@@ -175,6 +178,11 @@
 		for (i = 0; i < 8; i++)
 			input_report_key(dev, hidp_keycode[i + 224], (udata[0] >> i) & 1);
 
+		/* If all the key codes have been set to 0x01, it means
+		 * too many keys were pressed at the same time. */
+		if (!memcmp(udata + 2, hidp_mkeyspat, 6))
+			break;
+
 		for (i = 2; i < 8; i++) {
 			if (keys[i] > 3 && memscan(udata + 2, keys[i], 6) == udata + 8) {
 				if (hidp_keycode[keys[i]])
@@ -232,36 +240,171 @@
 		del_timer(&session->timer);
 }
 
-static inline void hidp_send_message(struct hidp_session *session, unsigned char hdr)
+static int __hidp_send_ctrl_message(struct hidp_session *session,
+			unsigned char hdr, unsigned char *data, int size)
 {
 	struct sk_buff *skb;
 
-	BT_DBG("session %p", session);
+	BT_DBG("session %p data %p size %d", session, data, size);
 
-	if (!(skb = alloc_skb(1, GFP_ATOMIC))) {
-		BT_ERR("Can't allocate memory for message");
-		return;
+	if (!(skb = alloc_skb(size + 1, GFP_ATOMIC))) {
+		BT_ERR("Can't allocate memory for new frame");
+		return -ENOMEM;
 	}
 
 	*skb_put(skb, 1) = hdr;
+	if (data && size > 0)
+		memcpy(skb_put(skb, size), data, size);
 
 	skb_queue_tail(&session->ctrl_transmit, skb);
 
+	return 0;
+}
+
+static int inline hidp_send_ctrl_message(struct hidp_session *session,
+			unsigned char hdr, unsigned char *data, int size)
+{
+	int err;
+
+	err = __hidp_send_ctrl_message(session, hdr, data, size);
+
 	hidp_schedule(session);
+
+	return err;
 }
 
-static inline int hidp_recv_frame(struct hidp_session *session, struct sk_buff *skb)
+static inline void hidp_process_handshake(struct hidp_session *session, unsigned char param)
 {
-	__u8 hdr;
+	BT_DBG("session %p param 0x%02x", session, param);
+
+	switch (param) {
+	case HIDP_HSHK_SUCCESSFUL:
+		/* FIXME: Call into SET_ GET_ handlers here */
+		break;
+
+	case HIDP_HSHK_NOT_READY:
+	case HIDP_HSHK_ERR_INVALID_REPORT_ID:
+	case HIDP_HSHK_ERR_UNSUPPORTED_REQUEST:
+	case HIDP_HSHK_ERR_INVALID_PARAMETER:
+		/* FIXME: Call into SET_ GET_ handlers here */
+		break;
+
+	case HIDP_HSHK_ERR_UNKNOWN:
+		break;
+
+	case HIDP_HSHK_ERR_FATAL:
+		/* Device requests a reboot, as this is the only way this error
+ 		 * can be recovered. */
+		__hidp_send_ctrl_message(session,
+			HIDP_TRANS_HID_CONTROL | HIDP_CTRL_SOFT_RESET, NULL, 0);
+		break;
+
+	default:
+		__hidp_send_ctrl_message(session,
+			HIDP_TRANS_HANDSHAKE | HIDP_HSHK_ERR_INVALID_PARAMETER, NULL, 0);
+		break;
+	}
+}
+
+static inline void hidp_process_hid_control(struct hidp_session *session, unsigned char param)
+{
+	BT_DBG("session %p param 0x%02x", session, param);
+
+	switch (param) {
+	case HIDP_CTRL_NOP:
+		break;
+
+	case HIDP_CTRL_VIRTUAL_CABLE_UNPLUG:
+		/* Flush the transmit queues */
+		skb_queue_purge(&session->ctrl_transmit);
+		skb_queue_purge(&session->intr_transmit);
+
+		/* Kill session thread */
+		atomic_inc(&session->terminate);
+		break;
+
+	case HIDP_CTRL_HARD_RESET:
+	case HIDP_CTRL_SOFT_RESET:
+	case HIDP_CTRL_SUSPEND:
+	case HIDP_CTRL_EXIT_SUSPEND:
+		/* FIXME: We have to parse these and return no error */
+		break;
+
+	default:
+		__hidp_send_ctrl_message(session,
+			HIDP_TRANS_HANDSHAKE | HIDP_HSHK_ERR_INVALID_PARAMETER, NULL, 0);
+		break;
+	}
+}
+
+static inline void hidp_process_data(struct hidp_session *session, struct sk_buff *skb, unsigned char param)
+{
+	BT_DBG("session %p skb %p len %d param 0x%02x", session, skb, skb->len, param);
+
+	switch (param) {
+	case HIDP_DATA_RTYPE_INPUT:
+		hidp_set_timer(session);
+
+		if (session->input)
+			hidp_input_report(session, skb);
+		break;
+
+	case HIDP_DATA_RTYPE_OTHER:
+	case HIDP_DATA_RTYPE_OUPUT:
+	case HIDP_DATA_RTYPE_FEATURE:
+		break;
+
+	default:
+		__hidp_send_ctrl_message(session,
+			HIDP_TRANS_HANDSHAKE | HIDP_HSHK_ERR_INVALID_PARAMETER, NULL, 0);
+	}
+}
+
+static inline void hidp_recv_ctrl_frame(struct hidp_session *session, struct sk_buff *skb)
+{
+	unsigned char hdr, type, param;
 
 	BT_DBG("session %p skb %p len %d", session, skb, skb->len);
 
 	hdr = skb->data[0];
 	skb_pull(skb, 1);
 
-	if (hdr == 0xa1) {
-		hidp_set_timer(session);
+	type = hdr & HIDP_HEADER_TRANS_MASK;
+	param = hdr & HIDP_HEADER_PARAM_MASK;
+
+	switch (type) {
+	case HIDP_TRANS_HANDSHAKE:
+		hidp_process_handshake(session, param);
+		break;
+
+	case HIDP_TRANS_HID_CONTROL:
+		hidp_process_hid_control(session, param);
+		break;
+
+	case HIDP_TRANS_DATA:
+		hidp_process_data(session, skb, param);
+		break;
+
+	default:
+		__hidp_send_ctrl_message(session,
+			HIDP_TRANS_HANDSHAKE | HIDP_HSHK_ERR_UNSUPPORTED_REQUEST, NULL, 0);
+		break;
+	}
+
+	kfree_skb(skb);
+}
+
+static inline void hidp_recv_intr_frame(struct hidp_session *session, struct sk_buff *skb)
+{
+	unsigned char hdr;
+
+	BT_DBG("session %p skb %p len %d", session, skb, skb->len);
+
+	hdr = skb->data[0];
+	skb_pull(skb, 1);
 
+	if (hdr == (HIDP_TRANS_DATA | HIDP_DATA_RTYPE_INPUT)) {
+		hidp_set_timer(session);
 		if (session->input)
 			hidp_input_report(session, skb);
 	} else {
@@ -269,7 +412,6 @@
 	}
 
 	kfree_skb(skb);
-	return 0;
 }
 
 static int hidp_send_frame(struct socket *sock, unsigned char *data, int len)
@@ -325,7 +467,6 @@
 	struct sk_buff *skb;
 	int vendor = 0x0000, product = 0x0000;
 	wait_queue_t ctrl_wait, intr_wait;
-	unsigned long timeo = HZ;
 
 	BT_DBG("session %p", session);
 
@@ -350,12 +491,12 @@
 
 		while ((skb = skb_dequeue(&ctrl_sk->sk_receive_queue))) {
 			skb_orphan(skb);
-			hidp_recv_frame(session, skb);
+			hidp_recv_ctrl_frame(session, skb);
 		}
 
 		while ((skb = skb_dequeue(&intr_sk->sk_receive_queue))) {
 			skb_orphan(skb);
-			hidp_recv_frame(session, skb);
+			hidp_recv_intr_frame(session, skb);
 		}
 
 		hidp_process_transmit(session);
@@ -370,28 +511,12 @@
 
 	hidp_del_timer(session);
 
-	if (intr_sk->sk_state != BT_CONNECTED) {
-		init_waitqueue_entry(&ctrl_wait, current);
-		add_wait_queue(ctrl_sk->sk_sleep, &ctrl_wait);
-		while (timeo && ctrl_sk->sk_state != BT_CLOSED) {
-			set_current_state(TASK_INTERRUPTIBLE);
-			timeo = schedule_timeout(timeo);
-		}
-		set_current_state(TASK_RUNNING);
-		remove_wait_queue(ctrl_sk->sk_sleep, &ctrl_wait);
-		timeo = HZ;
-	}
+	if (intr_sk->sk_state != BT_CONNECTED)
+		wait_event_timeout(*(ctrl_sk->sk_sleep), (ctrl_sk->sk_state == BT_CLOSED), HZ);
 
 	fput(session->ctrl_sock->file);
 
-	init_waitqueue_entry(&intr_wait, current);
-	add_wait_queue(intr_sk->sk_sleep, &intr_wait);
-	while (timeo && intr_sk->sk_state != BT_CLOSED) {
-		set_current_state(TASK_INTERRUPTIBLE);
-		timeo = schedule_timeout(timeo);
-	}
-	set_current_state(TASK_RUNNING);
-	remove_wait_queue(intr_sk->sk_sleep, &intr_wait);
+	wait_event_timeout(*(intr_sk->sk_sleep), (intr_sk->sk_state == BT_CLOSED), HZ);
 
 	fput(session->intr_sock->file);
 
@@ -514,7 +639,8 @@
 		goto unlink;
 
 	if (session->input) {
-		hidp_send_message(session, 0x70);
+		hidp_send_ctrl_message(session,
+			HIDP_TRANS_SET_PROTOCOL | HIDP_PROTO_BOOT, NULL, 0);
 		session->flags |= (1 << HIDP_BOOT_PROTOCOL_MODE);
 
 		session->leds = 0xff;
@@ -554,7 +680,8 @@
 	session = __hidp_get_session(&req->bdaddr);
 	if (session) {
 		if (req->flags & (1 << HIDP_VIRTUAL_CABLE_UNPLUG)) {
-			hidp_send_message(session, 0x15);
+			hidp_send_ctrl_message(session,
+				HIDP_TRANS_HID_CONTROL | HIDP_CTRL_VIRTUAL_CABLE_UNPLUG, NULL, 0);
 		} else {
 			/* Flush the transmit queues */
 			skb_queue_purge(&session->ctrl_transmit);
diff -Nru a/net/bluetooth/hidp/hidp.h b/net/bluetooth/hidp/hidp.h
--- a/net/bluetooth/hidp/hidp.h	2005-03-01 23:38:55 -08:00
+++ b/net/bluetooth/hidp/hidp.h	2005-03-01 23:38:55 -08:00
@@ -26,6 +26,51 @@
 #include <linux/types.h>
 #include <net/bluetooth/bluetooth.h>
 
+/* HIDP header masks */
+#define HIDP_HEADER_TRANS_MASK			0xf0
+#define HIDP_HEADER_PARAM_MASK			0x0f
+
+/* HIDP transaction types */
+#define HIDP_TRANS_HANDSHAKE			0x00
+#define HIDP_TRANS_HID_CONTROL			0x10
+#define HIDP_TRANS_GET_REPORT			0x40
+#define HIDP_TRANS_SET_REPORT			0x50
+#define HIDP_TRANS_GET_PROTOCOL			0x60
+#define HIDP_TRANS_SET_PROTOCOL			0x70
+#define HIDP_TRANS_GET_IDLE			0x80
+#define HIDP_TRANS_SET_IDLE			0x90
+#define HIDP_TRANS_DATA				0xa0
+#define HIDP_TRANS_DATC				0xb0
+
+/* HIDP handshake results */
+#define HIDP_HSHK_SUCCESSFUL			0x00
+#define HIDP_HSHK_NOT_READY			0x01
+#define HIDP_HSHK_ERR_INVALID_REPORT_ID		0x02
+#define HIDP_HSHK_ERR_UNSUPPORTED_REQUEST	0x03
+#define HIDP_HSHK_ERR_INVALID_PARAMETER		0x04
+#define HIDP_HSHK_ERR_UNKNOWN			0x0e
+#define HIDP_HSHK_ERR_FATAL			0x0f
+
+/* HIDP control operation parameters */
+#define HIDP_CTRL_NOP				0x00
+#define HIDP_CTRL_HARD_RESET			0x01
+#define HIDP_CTRL_SOFT_RESET			0x02
+#define HIDP_CTRL_SUSPEND			0x03
+#define HIDP_CTRL_EXIT_SUSPEND			0x04
+#define HIDP_CTRL_VIRTUAL_CABLE_UNPLUG		0x05
+
+/* HIDP data transaction headers */
+#define HIDP_DATA_RTYPE_MASK			0x03
+#define HIDP_DATA_RSRVD_MASK			0x0c
+#define HIDP_DATA_RTYPE_OTHER			0x00
+#define HIDP_DATA_RTYPE_INPUT			0x01
+#define HIDP_DATA_RTYPE_OUPUT			0x02
+#define HIDP_DATA_RTYPE_FEATURE			0x03
+
+/* HIDP protocol header parameters */
+#define HIDP_PROTO_BOOT				0x00
+#define HIDP_PROTO_REPORT			0x01
+
 /* HIDP ioctl defines */
 #define HIDPCONNADD	_IOW('H', 200, int)
 #define HIDPCONNDEL	_IOW('H', 201, int)
diff -Nru a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
--- a/net/bluetooth/l2cap.c	2005-03-01 23:39:07 -08:00
+++ b/net/bluetooth/l2cap.c	2005-03-01 23:39:07 -08:00
@@ -57,11 +57,11 @@
 #define BT_DBG(D...)
 #endif
 
-#define VERSION "2.6"
+#define VERSION "2.7"
 
 static struct proto_ops l2cap_sock_ops;
 
-struct bt_sock_list l2cap_sk_list = {
+static struct bt_sock_list l2cap_sk_list = {
 	.lock = RW_LOCK_UNLOCKED
 };
 
@@ -770,7 +770,7 @@
 		return -EOPNOTSUPP;
 
 	/* Check outgoing MTU */
-	if (len > l2cap_pi(sk)->omtu)
+	if (sk->sk_type != SOCK_RAW && len > l2cap_pi(sk)->omtu)
 		return -EINVAL;
 
 	lock_sock(sk);
@@ -798,7 +798,7 @@
 	switch (optname) {
 	case L2CAP_OPTIONS:
 		len = min_t(unsigned int, sizeof(opts), optlen);
-		if (copy_from_user((char *)&opts, optval, len)) {
+		if (copy_from_user((char *) &opts, optval, len)) {
 			err = -EFAULT;
 			break;
 		}
@@ -807,7 +807,7 @@
 		break;
 
 	case L2CAP_LM:
-		if (get_user(opt, (u32 __user *)optval)) {
+		if (get_user(opt, (u32 __user *) optval)) {
 			err = -EFAULT;
 			break;
 		}
@@ -829,7 +829,9 @@
 	struct sock *sk = sock->sk;
 	struct l2cap_options opts;
 	struct l2cap_conninfo cinfo;
-	int len, err = 0; 
+	int len, err = 0;
+
+	BT_DBG("sk %p", sk);
 
 	if (get_user(len, optlen))
 		return -EFAULT;
@@ -841,15 +843,16 @@
 		opts.imtu     = l2cap_pi(sk)->imtu;
 		opts.omtu     = l2cap_pi(sk)->omtu;
 		opts.flush_to = l2cap_pi(sk)->flush_to;
+		opts.mode     = 0x00;
 
 		len = min_t(unsigned int, len, sizeof(opts));
-		if (copy_to_user(optval, (char *)&opts, len))
+		if (copy_to_user(optval, (char *) &opts, len))
 			err = -EFAULT;
 
 		break;
 
 	case L2CAP_LM:
-		if (put_user(l2cap_pi(sk)->link_mode, (u32 __user *)optval))
+		if (put_user(l2cap_pi(sk)->link_mode, (u32 __user *) optval))
 			err = -EFAULT;
 		break;
 
@@ -860,9 +863,10 @@
 		}
 
 		cinfo.hci_handle = l2cap_pi(sk)->conn->hcon->handle;
+		memcpy(cinfo.dev_class, l2cap_pi(sk)->conn->hcon->dev_class, 3);
 
 		len = min_t(unsigned int, len, sizeof(cinfo));
-		if (copy_to_user(optval, (char *)&cinfo, len))
+		if (copy_to_user(optval, (char *) &cinfo, len))
 			err = -EFAULT;
 
 		break;
diff -Nru a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
--- a/net/bluetooth/rfcomm/core.c	2005-03-01 23:38:44 -08:00
+++ b/net/bluetooth/rfcomm/core.c	2005-03-01 23:38:44 -08:00
@@ -47,10 +47,11 @@
 #include <asm/unaligned.h>
 
 #include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
 #include <net/bluetooth/l2cap.h>
 #include <net/bluetooth/rfcomm.h>
 
-#define VERSION "1.3"
+#define VERSION "1.5"
 
 #ifndef CONFIG_BT_RFCOMM_DEBUG
 #undef  BT_DBG
@@ -61,8 +62,12 @@
 struct proc_dir_entry *proc_bt_rfcomm;
 #endif
 
-struct task_struct *rfcomm_thread;
-DECLARE_MUTEX(rfcomm_sem);
+static struct task_struct *rfcomm_thread;
+
+static DECLARE_MUTEX(rfcomm_sem);
+#define rfcomm_lock()	down(&rfcomm_sem);
+#define rfcomm_unlock()	up(&rfcomm_sem);
+
 unsigned long rfcomm_event;
 
 static LIST_HEAD(session_list);
@@ -81,6 +86,10 @@
 
 static void rfcomm_process_connect(struct rfcomm_session *s);
 
+static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, bdaddr_t *dst, int *err);
+static struct rfcomm_session *rfcomm_session_get(bdaddr_t *src, bdaddr_t *dst);
+static void rfcomm_session_del(struct rfcomm_session *s);
+
 /* ---- RFCOMM frame parsing macros ---- */
 #define __get_dlci(b)     ((b & 0xfc) >> 2)
 #define __get_channel(b)  ((b & 0xf8) >> 3)
@@ -111,6 +120,21 @@
 #define __get_rpn_stop_bits(line) (((line) >> 2) & 0x1)
 #define __get_rpn_parity(line)    (((line) >> 3) & 0x3)
 
+static inline void rfcomm_schedule(uint event)
+{
+	if (!rfcomm_thread)
+		return;
+	//set_bit(event, &rfcomm_event);
+	set_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event);
+	wake_up_process(rfcomm_thread);
+}
+
+static inline void rfcomm_session_put(struct rfcomm_session *s)
+{
+	if (atomic_dec_and_test(&s->refcnt))
+		rfcomm_session_del(s);
+}
+
 /* ---- RFCOMM FCS computation ---- */
 
 /* CRC on 2 bytes */
@@ -458,7 +482,7 @@
 }
 
 /* ---- RFCOMM sessions ---- */
-struct rfcomm_session *rfcomm_session_add(struct socket *sock, int state)
+static struct rfcomm_session *rfcomm_session_add(struct socket *sock, int state)
 {
 	struct rfcomm_session *s = kmalloc(sizeof(*s), GFP_KERNEL);
 	if (!s)
@@ -487,7 +511,7 @@
 	return s;
 }
 
-void rfcomm_session_del(struct rfcomm_session *s)
+static void rfcomm_session_del(struct rfcomm_session *s)
 {
 	int state = s->state;
 
@@ -505,7 +529,7 @@
 		module_put(THIS_MODULE);
 }
 
-struct rfcomm_session *rfcomm_session_get(bdaddr_t *src, bdaddr_t *dst)
+static struct rfcomm_session *rfcomm_session_get(bdaddr_t *src, bdaddr_t *dst)
 {
 	struct rfcomm_session *s;
 	struct list_head *p, *n;
@@ -521,7 +545,7 @@
 	return NULL;
 }
 
-void rfcomm_session_close(struct rfcomm_session *s, int err)
+static void rfcomm_session_close(struct rfcomm_session *s, int err)
 {
 	struct rfcomm_dlc *d;
 	struct list_head *p, *n;
@@ -542,7 +566,7 @@
 	rfcomm_session_put(s);
 }
 
-struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, bdaddr_t *dst, int *err)
+static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, bdaddr_t *dst, int *err)
 {
 	struct rfcomm_session *s = NULL;
 	struct sockaddr_l2 addr;
@@ -1071,6 +1095,35 @@
 	return 0;
 }
 
+static inline int rfcomm_check_link_mode(struct rfcomm_dlc *d)
+{
+	struct sock *sk = d->session->sock->sk;
+
+	if (d->link_mode & (RFCOMM_LM_ENCRYPT | RFCOMM_LM_SECURE)) {
+		if (!hci_conn_encrypt(l2cap_pi(sk)->conn->hcon))
+			return 1;
+	} else if (d->link_mode & RFCOMM_LM_AUTH) {
+		if (!hci_conn_auth(l2cap_pi(sk)->conn->hcon))
+			return 1;
+	}
+
+	return 0;
+}
+
+static void rfcomm_dlc_accept(struct rfcomm_dlc *d)
+{
+	BT_DBG("dlc %p", d);
+
+	rfcomm_send_ua(d->session, d->dlci);
+
+	rfcomm_dlc_lock(d);
+	d->state = BT_CONNECTED;
+	d->state_change(d, 0);
+	rfcomm_dlc_unlock(d);
+
+	rfcomm_send_msc(d->session, 1, d->dlci, d->v24_sig);
+}
+
 static int rfcomm_recv_sabm(struct rfcomm_session *s, u8 dlci)
 {
 	struct rfcomm_dlc *d;
@@ -1093,14 +1146,13 @@
 	if (d) {
 		if (d->state == BT_OPEN) {
 			/* DLC was previously opened by PN request */
-			rfcomm_send_ua(s, dlci);
-
-			rfcomm_dlc_lock(d);
-			d->state = BT_CONNECTED;
-			d->state_change(d, 0);
-			rfcomm_dlc_unlock(d);
+			if (rfcomm_check_link_mode(d)) {
+				set_bit(RFCOMM_AUTH_PENDING, &d->flags);
+				rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT);
+				return 0;
+			}
 
-			rfcomm_send_msc(s, 1, dlci, d->v24_sig);
+			rfcomm_dlc_accept(d);
 		}
 		return 0;
 	}
@@ -1112,14 +1164,13 @@
 		d->addr = __addr(s->initiator, dlci);
 		rfcomm_dlc_link(s, d);
 
-		rfcomm_send_ua(s, dlci);
-
-		rfcomm_dlc_lock(d);
-		d->state = BT_CONNECTED;
-		d->state_change(d, 0);
-		rfcomm_dlc_unlock(d);
+		if (rfcomm_check_link_mode(d)) {
+			set_bit(RFCOMM_AUTH_PENDING, &d->flags);
+			rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT);
+			return 0;
+		}
 
-		rfcomm_send_msc(s, 1, dlci, d->v24_sig);
+		rfcomm_dlc_accept(d);
 	} else {
 		rfcomm_send_dm(s, dlci);
 	}
@@ -1457,7 +1508,7 @@
 	/* Trim FCS */
 	skb->len--; skb->tail--;
 	fcs = *(u8 *) skb->tail;
-	
+
 	if (__check_fcs(skb->data, type, fcs)) {
 		BT_ERR("bad checksum in packet");
 		kfree_skb(skb);
@@ -1468,7 +1519,7 @@
 		skb_pull(skb, 3);
 	else
 		skb_pull(skb, 4);
-	
+
 	switch (type) {
 	case RFCOMM_SABM:
 		if (__test_pf(hdr->ctrl))
@@ -1536,7 +1587,7 @@
 	/* Send pending MSC */
 	if (test_and_clear_bit(RFCOMM_MSC_PENDING, &d->flags))
 		rfcomm_send_msc(d->session, 1, d->dlci, d->v24_sig); 
-	
+
 	if (d->cfc) {
 		/* CFC enabled. 
 		 * Give them some credits */
@@ -1582,11 +1633,27 @@
 
 	list_for_each_safe(p, n, &s->dlcs) {
 		d = list_entry(p, struct rfcomm_dlc, list);
+
 		if (test_bit(RFCOMM_TIMED_OUT, &d->flags)) {
 			__rfcomm_dlc_close(d, ETIMEDOUT);
 			continue;
 		}
 
+		if (test_and_clear_bit(RFCOMM_AUTH_ACCEPT, &d->flags)) {
+			rfcomm_dlc_clear_timer(d);
+			rfcomm_dlc_accept(d);
+			if (d->link_mode & RFCOMM_LM_SECURE) {
+				struct sock *sk = s->sock->sk;
+				hci_conn_change_link_key(l2cap_pi(sk)->conn->hcon);
+			}
+			continue;
+		} else if (test_and_clear_bit(RFCOMM_AUTH_REJECT, &d->flags)) {
+			rfcomm_dlc_clear_timer(d);
+			rfcomm_send_dm(s, d->dlci);
+			__rfcomm_dlc_close(d, ECONNREFUSED);
+			continue;
+		}
+
 		if (test_bit(RFCOMM_TX_THROTTLED, &s->flags))
 			continue;
 
@@ -1710,7 +1777,7 @@
 
 		rfcomm_session_put(s);
 	}
-	
+
 	rfcomm_unlock();
 }
 
@@ -1819,6 +1886,77 @@
 	return 0;
 }
 
+static void rfcomm_auth_cfm(struct hci_conn *conn, u8 status)
+{
+	struct rfcomm_session *s;
+	struct rfcomm_dlc *d;
+	struct list_head *p, *n;
+
+	BT_DBG("conn %p status 0x%02x", conn, status);
+
+	s = rfcomm_session_get(&conn->hdev->bdaddr, &conn->dst);
+	if (!s)
+		return;
+
+	rfcomm_session_hold(s);
+
+	list_for_each_safe(p, n, &s->dlcs) {
+		d = list_entry(p, struct rfcomm_dlc, list);
+
+		if (d->link_mode & (RFCOMM_LM_ENCRYPT | RFCOMM_LM_SECURE))
+			continue;
+
+		if (!test_and_clear_bit(RFCOMM_AUTH_PENDING, &d->flags))
+			continue;
+
+		if (!status)
+			set_bit(RFCOMM_AUTH_ACCEPT, &d->flags);
+		else
+			set_bit(RFCOMM_AUTH_REJECT, &d->flags);
+	}
+
+	rfcomm_session_put(s);
+
+	rfcomm_schedule(RFCOMM_SCHED_AUTH);
+}
+
+static void rfcomm_encrypt_cfm(struct hci_conn *conn, u8 status, u8 encrypt)
+{
+	struct rfcomm_session *s;
+	struct rfcomm_dlc *d;
+	struct list_head *p, *n;
+
+	BT_DBG("conn %p status 0x%02x encrypt 0x%02x", conn, status, encrypt);
+
+	s = rfcomm_session_get(&conn->hdev->bdaddr, &conn->dst);
+	if (!s)
+		return;
+
+	rfcomm_session_hold(s);
+
+	list_for_each_safe(p, n, &s->dlcs) {
+		d = list_entry(p, struct rfcomm_dlc, list);
+
+		if (!test_and_clear_bit(RFCOMM_AUTH_PENDING, &d->flags))
+			continue;
+
+		if (!status && encrypt)
+			set_bit(RFCOMM_AUTH_ACCEPT, &d->flags);
+		else
+			set_bit(RFCOMM_AUTH_REJECT, &d->flags);
+	}
+
+	rfcomm_session_put(s);
+
+	rfcomm_schedule(RFCOMM_SCHED_AUTH);
+}
+
+static struct hci_cb rfcomm_cb = {
+	.name		= "RFCOMM",
+	.auth_cfm	= rfcomm_auth_cfm,
+	.encrypt_cfm	= rfcomm_encrypt_cfm
+};
+
 /* ---- Proc fs support ---- */
 #ifdef CONFIG_PROC_FS
 static void *rfcomm_seq_start(struct seq_file *seq, loff_t *pos)
@@ -1936,6 +2074,8 @@
 {
 	l2cap_load();
 
+	hci_register_cb(&rfcomm_cb);
+
 	kernel_thread(rfcomm_run, NULL, CLONE_KERNEL);
 
 	BT_INFO("RFCOMM ver %s", VERSION);
@@ -1953,6 +2093,8 @@
 
 static void __exit rfcomm_exit(void)
 {
+	hci_unregister_cb(&rfcomm_cb);
+
 	/* Terminate working thread.
 	 * ie. Set terminate flag and wake it up */
 	atomic_inc(&terminate);
diff -Nru a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
--- a/net/bluetooth/rfcomm/sock.c	2005-03-01 23:39:07 -08:00
+++ b/net/bluetooth/rfcomm/sock.c	2005-03-01 23:39:07 -08:00
@@ -51,6 +51,8 @@
 #include <asm/uaccess.h>
 
 #include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
+#include <net/bluetooth/l2cap.h>
 #include <net/bluetooth/rfcomm.h>
 
 #ifndef CONFIG_BT_RFCOMM_DEBUG
@@ -115,8 +117,13 @@
 
 	bh_unlock_sock(sk);
 
-	if (parent && sk->sk_zapped)
+	if (parent && sk->sk_zapped) {
+		/* We have to drop DLC lock here, otherwise
+		 * rfcomm_sock_destruct() will dead lock. */
+		rfcomm_dlc_unlock(d);
 		rfcomm_sock_kill(sk);
+		rfcomm_dlc_lock(d);
+	}
 }
 
 /* ---- Socket functions ---- */
@@ -182,7 +189,7 @@
 
 	rfcomm_dlc_lock(d);
 	rfcomm_pi(sk)->dlc = NULL;
-	
+
 	/* Detach DLC if it's owned by this socket */
 	if (d->owner == sk)
 		d->owner = NULL;
@@ -261,10 +268,18 @@
 
 static void rfcomm_sock_init(struct sock *sk, struct sock *parent)
 {
+	struct rfcomm_pinfo *pi = rfcomm_pi(sk);
+
 	BT_DBG("sk %p", sk);
 
-	if (parent) 
+	if (parent) {
 		sk->sk_type = parent->sk_type;
+		pi->link_mode = rfcomm_pi(parent)->link_mode;
+	} else {
+		pi->link_mode = 0;
+	}
+
+	pi->dlc->link_mode = pi->link_mode;
 }
 
 static struct sock *rfcomm_sock_alloc(struct socket *sock, int proto, int prio)
@@ -393,7 +408,7 @@
 	return err;
 }
 
-int rfcomm_sock_listen(struct socket *sock, int backlog)
+static int rfcomm_sock_listen(struct socket *sock, int backlog)
 {
 	struct sock *sk = sock->sk;
 	int err = 0;
@@ -437,7 +452,7 @@
 	return err;
 }
 
-int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int flags)
+static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int flags)
 {
 	DECLARE_WAITQUEUE(wait, current);
 	struct sock *sk = sock->sk, *nsk;
@@ -671,12 +686,22 @@
 {
 	struct sock *sk = sock->sk;
 	int err = 0;
+	u32 opt;
 
 	BT_DBG("sk %p", sk);
 
 	lock_sock(sk);
 
 	switch (optname) {
+	case RFCOMM_LM:
+		if (get_user(opt, (u32 __user *) optval)) {
+			err = -EFAULT;
+			break;
+		}
+
+		rfcomm_pi(sk)->link_mode = opt;
+		break;
+
 	default:
 		err = -ENOPROTOOPT;
 		break;
@@ -689,7 +714,9 @@
 static int rfcomm_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen)
 {
 	struct sock *sk = sock->sk;
-	int len, err = 0; 
+	struct sock *l2cap_sk;
+	struct rfcomm_conninfo cinfo;
+	int len, err = 0;
 
 	BT_DBG("sk %p", sk);
 
@@ -699,10 +726,32 @@
 	lock_sock(sk);
 
 	switch (optname) {
+	case RFCOMM_LM:
+		if (put_user(rfcomm_pi(sk)->link_mode, (u32 __user *) optval))
+			err = -EFAULT;
+		break;
+
+	case RFCOMM_CONNINFO:
+		if (sk->sk_state != BT_CONNECTED) {
+			err = -ENOTCONN;
+			break;
+		}
+
+		l2cap_sk = rfcomm_pi(sk)->dlc->session->sock->sk;
+
+		cinfo.hci_handle = l2cap_pi(l2cap_sk)->conn->hcon->handle;
+		memcpy(cinfo.dev_class, l2cap_pi(l2cap_sk)->conn->hcon->dev_class, 3);
+
+		len = min_t(unsigned int, len, sizeof(cinfo));
+		if (copy_to_user(optval, (char *) &cinfo, len))
+			err = -EFAULT;
+
+		break;
+
 	default:
 		err = -ENOPROTOOPT;
 		break;
-	};
+	}
 
 	release_sock(sk);
 	return err;
diff -Nru a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c
--- a/net/bluetooth/rfcomm/tty.c	2005-03-01 23:38:58 -08:00
+++ b/net/bluetooth/rfcomm/tty.c	2005-03-01 23:38:58 -08:00
@@ -77,7 +77,7 @@
 };
 
 static LIST_HEAD(rfcomm_dev_list);
-static rwlock_t rfcomm_dev_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(rfcomm_dev_lock);
 
 static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc, struct sk_buff *skb);
 static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err);
diff -Nru a/net/bluetooth/sco.c b/net/bluetooth/sco.c
--- a/net/bluetooth/sco.c	2005-03-01 23:38:54 -08:00
+++ b/net/bluetooth/sco.c	2005-03-01 23:38:54 -08:00
@@ -56,7 +56,7 @@
 #define BT_DBG(D...)
 #endif
 
-#define VERSION "0.3"
+#define VERSION "0.4"
 
 static struct proto_ops sco_sock_ops;
 
@@ -705,6 +705,7 @@
 		}
 
 		cinfo.hci_handle = sco_pi(sk)->conn->hcon->handle;
+		memcpy(cinfo.dev_class, sco_pi(sk)->conn->hcon->dev_class, 3);
 
 		len = min_t(unsigned int, len, sizeof(cinfo));
 		if (copy_to_user(optval, (char *)&cinfo, len))
@@ -1045,7 +1046,7 @@
 module_init(sco_init);
 module_exit(sco_exit);
 
-MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
+MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>, Marcel Holtmann <marcel@holtmann.org>");
 MODULE_DESCRIPTION("Bluetooth SCO ver " VERSION);
 MODULE_VERSION(VERSION);
 MODULE_LICENSE("GPL");
diff -Nru a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
--- a/net/bridge/br_netfilter.c	2005-03-01 23:39:17 -08:00
+++ b/net/bridge/br_netfilter.c	2005-03-01 23:39:17 -08:00
@@ -845,19 +845,6 @@
 {
 	struct sk_buff *skb = *pskb;
 
-#ifdef CONFIG_SYSCTL
-	if (!skb->nf_bridge) {
-		struct vlan_ethhdr *hdr = vlan_eth_hdr(skb);
-
-		if (skb->protocol == __constant_htons(ETH_P_IP) ||
-		    IS_VLAN_IP) {
-			if (!brnf_call_iptables)
-				return NF_ACCEPT;
-		} else if (!brnf_call_ip6tables)
-			return NF_ACCEPT;
-	}
-#endif
-
 	if ((out->hard_start_xmit == br_dev_xmit &&
 	    okfn != br_nf_forward_finish &&
 	    okfn != br_nf_local_out_finish &&
@@ -869,8 +856,24 @@
 	    ) {
 		struct nf_bridge_info *nf_bridge;
 
-		if (!skb->nf_bridge && !nf_bridge_alloc(skb))
-			return NF_DROP;
+		if (!skb->nf_bridge) {
+#ifdef CONFIG_SYSCTL
+			/* This code is executed while in the IP(v6) stack,
+			   the version should be 4 or 6. We can't use
+			   skb->protocol because that isn't set on
+			   PF_INET(6)/LOCAL_OUT. */
+			struct iphdr *ip = skb->nh.iph;
+
+			if (ip->version == 4 && !brnf_call_iptables)
+				return NF_ACCEPT;
+			else if (ip->version == 6 && !brnf_call_ip6tables)
+				return NF_ACCEPT;
+#endif
+			if (hook == NF_IP_POST_ROUTING)
+				return NF_ACCEPT;
+			if (!nf_bridge_alloc(skb))
+				return NF_DROP;
+		}
 
 		nf_bridge = skb->nf_bridge;
 
diff -Nru a/net/bridge/netfilter/Kconfig b/net/bridge/netfilter/Kconfig
--- a/net/bridge/netfilter/Kconfig	2005-03-01 23:38:54 -08:00
+++ b/net/bridge/netfilter/Kconfig	2005-03-01 23:38:54 -08:00
@@ -189,8 +189,22 @@
 	tristate "ebt: log support"
 	depends on BRIDGE_NF_EBTABLES
 	help
-	  This option adds the log target, that you can use in any rule in
-	  any ebtables table. It records the frame header to the syslog.
+	  This option adds the log watcher, that you can use in any rule
+	  in any ebtables table. It records info about the frame header
+	  to the syslog.
+
+	  To compile it as a module, choose M here.  If unsure, say N.
+
+config BRIDGE_EBT_ULOG
+	tristate "ebt: ulog support"
+	depends on BRIDGE_NF_EBTABLES
+	help
+	  This option adds the ulog watcher, that you can use in any rule
+	  in any ebtables table. The packet is passed to a userspace
+	  logging daemon using netlink multicast sockets. This differs
+	  from the log watcher in the sense that the complete packet is
+	  sent to userspace instead of a descriptive text and that
+	  netlink multicast sockets are used instead of the syslog.
 
 	  To compile it as a module, choose M here.  If unsure, say N.
 
diff -Nru a/net/bridge/netfilter/Makefile b/net/bridge/netfilter/Makefile
--- a/net/bridge/netfilter/Makefile	2005-03-01 23:39:07 -08:00
+++ b/net/bridge/netfilter/Makefile	2005-03-01 23:39:07 -08:00
@@ -29,3 +29,4 @@
 
 # watchers
 obj-$(CONFIG_BRIDGE_EBT_LOG) += ebt_log.o
+obj-$(CONFIG_BRIDGE_EBT_LOG) += ebt_ulog.o
diff -Nru a/net/bridge/netfilter/ebt_limit.c b/net/bridge/netfilter/ebt_limit.c
--- a/net/bridge/netfilter/ebt_limit.c	2005-03-01 23:38:58 -08:00
+++ b/net/bridge/netfilter/ebt_limit.c	2005-03-01 23:38:58 -08:00
@@ -18,7 +18,7 @@
 #include <linux/netdevice.h>
 #include <linux/spinlock.h>
 
-static spinlock_t limit_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(limit_lock);
 
 #define MAX_CPJ (0xFFFFFFFF / (HZ*60*60*24))
 
diff -Nru a/net/bridge/netfilter/ebt_log.c b/net/bridge/netfilter/ebt_log.c
--- a/net/bridge/netfilter/ebt_log.c	2005-03-01 23:39:07 -08:00
+++ b/net/bridge/netfilter/ebt_log.c	2005-03-01 23:39:07 -08:00
@@ -15,7 +15,7 @@
 #include <linux/if_arp.h>
 #include <linux/spinlock.h>
 
-static spinlock_t ebt_log_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(ebt_log_lock);
 
 static int ebt_log_check(const char *tablename, unsigned int hookmask,
    const struct ebt_entry *e, void *data, unsigned int datalen)
@@ -55,8 +55,9 @@
 }
 
 #define myNIPQUAD(a) a[0], a[1], a[2], a[3]
-static void ebt_log(const struct sk_buff *skb, const struct net_device *in,
-   const struct net_device *out, const void *data, unsigned int datalen)
+static void ebt_log(const struct sk_buff *skb, unsigned int hooknr,
+   const struct net_device *in, const struct net_device *out,
+   const void *data, unsigned int datalen)
 {
 	struct ebt_log_info *info = (struct ebt_log_info *)data;
 	char level_string[4] = "< >";
diff -Nru a/net/bridge/netfilter/ebt_ulog.c b/net/bridge/netfilter/ebt_ulog.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/net/bridge/netfilter/ebt_ulog.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,295 @@
+/*
+ * netfilter module for userspace bridged Ethernet frames logging daemons
+ *
+ *	Authors:
+ *	Bart De Schuymer <bdschuym@pandora.be>
+ *
+ *  November, 2004
+ *
+ * Based on ipt_ULOG.c, which is
+ * (C) 2000-2002 by Harald Welte <laforge@netfilter.org>
+ *
+ * This module accepts two parameters: 
+ * 
+ * nlbufsiz:
+ *   The parameter specifies how big the buffer for each netlink multicast
+ * group is. e.g. If you say nlbufsiz=8192, up to eight kb of packets will
+ * get accumulated in the kernel until they are sent to userspace. It is
+ * NOT possible to allocate more than 128kB, and it is strongly discouraged,
+ * because atomically allocating 128kB inside the network rx softirq is not
+ * reliable. Please also keep in mind that this buffer size is allocated for
+ * each nlgroup you are using, so the total kernel memory usage increases
+ * by that factor.
+ *
+ * flushtimeout:
+ *   Specify, after how many hundredths of a second the queue should be
+ *   flushed even if it is not full yet.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/config.h>
+#include <linux/spinlock.h>
+#include <linux/socket.h>
+#include <linux/skbuff.h>
+#include <linux/kernel.h>
+#include <linux/timer.h>
+#include <linux/netlink.h>
+#include <linux/netdevice.h>
+#include <linux/module.h>
+#include <linux/netfilter_bridge/ebtables.h>
+#include <linux/netfilter_bridge/ebt_ulog.h>
+#include <net/sock.h>
+#include "../br_private.h"
+
+#define PRINTR(format, args...) do { if (net_ratelimit()) \
+                                printk(format , ## args); } while (0)
+
+static unsigned int nlbufsiz = 4096;
+module_param(nlbufsiz, uint, 0600);
+MODULE_PARM_DESC(nlbufsiz, "netlink buffer size (number of bytes) "
+                           "(defaults to 4096)");
+
+static unsigned int flushtimeout = 10;
+module_param(flushtimeout, uint, 0600);
+MODULE_PARM_DESC(flushtimeout, "buffer flush timeout (hundredths ofa second) "
+                               "(defaults to 10)");
+
+typedef struct {
+	unsigned int qlen;		/* number of nlmsgs' in the skb */
+	struct nlmsghdr *lastnlh;	/* netlink header of last msg in skb */
+	struct sk_buff *skb;		/* the pre-allocated skb */
+	struct timer_list timer;	/* the timer function */
+	spinlock_t lock;		/* the per-queue lock */
+} ebt_ulog_buff_t;
+
+static ebt_ulog_buff_t ulog_buffers[EBT_ULOG_MAXNLGROUPS];
+static struct sock *ebtulognl;
+
+/* send one ulog_buff_t to userspace */
+static void ulog_send(unsigned int nlgroup)
+{
+	ebt_ulog_buff_t *ub = &ulog_buffers[nlgroup];
+
+	if (timer_pending(&ub->timer))
+		del_timer(&ub->timer);
+
+	/* last nlmsg needs NLMSG_DONE */
+	if (ub->qlen > 1)
+		ub->lastnlh->nlmsg_type = NLMSG_DONE;
+
+	NETLINK_CB(ub->skb).dst_groups = 1 << nlgroup;
+	netlink_broadcast(ebtulognl, ub->skb, 0, 1 << nlgroup, GFP_ATOMIC);
+
+	ub->qlen = 0;
+	ub->skb = NULL;
+}
+
+/* timer function to flush queue in flushtimeout time */
+static void ulog_timer(unsigned long data)
+{
+	spin_lock_bh(&ulog_buffers[data].lock);
+	if (ulog_buffers[data].skb)
+		ulog_send(data);
+	spin_unlock_bh(&ulog_buffers[data].lock);
+}
+
+static struct sk_buff *ulog_alloc_skb(unsigned int size)
+{
+	struct sk_buff *skb;
+
+	skb = alloc_skb(nlbufsiz, GFP_ATOMIC);
+	if (!skb) {
+		PRINTR(KERN_ERR "ebt_ulog: can't alloc whole buffer "
+		       "of size %ub!\n", nlbufsiz);
+		if (size < nlbufsiz) {
+			/* try to allocate only as much as we need for
+			 * current packet */
+			skb = alloc_skb(size, GFP_ATOMIC);
+			if (!skb)
+				PRINTR(KERN_ERR "ebt_ulog: can't even allocate "
+				       "buffer of size %ub\n", size);
+		}
+	}
+
+	return skb;
+}
+
+static void ebt_ulog(const struct sk_buff *skb, unsigned int hooknr,
+   const struct net_device *in, const struct net_device *out,
+   const void *data, unsigned int datalen)
+{
+	ebt_ulog_packet_msg_t *pm;
+	size_t size, copy_len;
+	struct nlmsghdr *nlh;
+	struct ebt_ulog_info *uloginfo = (struct ebt_ulog_info *)data;
+	unsigned int group = uloginfo->nlgroup;
+	ebt_ulog_buff_t *ub = &ulog_buffers[group];
+	spinlock_t *lock = &ub->lock;
+
+	if ((uloginfo->cprange == 0) ||
+	    (uloginfo->cprange > skb->len + ETH_HLEN))
+		copy_len = skb->len + ETH_HLEN;
+	else
+		copy_len = uloginfo->cprange;
+
+	size = NLMSG_SPACE(sizeof(*pm) + copy_len);
+	if (size > nlbufsiz) {
+		PRINTR("ebt_ulog: Size %Zd needed, but nlbufsiz=%d\n",
+		       size, nlbufsiz);
+		return;
+	}
+
+	spin_lock_bh(lock);
+
+	if (!ub->skb) {
+		if (!(ub->skb = ulog_alloc_skb(size)))
+			goto alloc_failure;
+	} else if (size > skb_tailroom(ub->skb)) {
+		ulog_send(group);
+
+		if (!(ub->skb = ulog_alloc_skb(size)))
+			goto alloc_failure;
+	}
+
+	nlh = NLMSG_PUT(ub->skb, 0, ub->qlen, 0,
+	                size - NLMSG_ALIGN(sizeof(*nlh)));
+	ub->qlen++;
+
+	pm = NLMSG_DATA(nlh);
+
+	/* Fill in the ulog data */
+	pm->version = EBT_ULOG_VERSION;
+	do_gettimeofday(&pm->stamp);
+	if (ub->qlen == 1)
+		ub->skb->stamp = pm->stamp;
+	pm->data_len = copy_len;
+	pm->mark = skb->nfmark;
+	pm->hook = hooknr;
+	if (uloginfo->prefix != NULL)
+		strcpy(pm->prefix, uloginfo->prefix);
+	else
+		*(pm->prefix) = '\0';
+
+	if (in) {
+		strcpy(pm->physindev, in->name);
+		/* If in isn't a bridge, then physindev==indev */
+		if (in->br_port)
+			strcpy(pm->indev, in->br_port->br->dev->name);
+		else
+			strcpy(pm->indev, in->name);
+	} else
+		pm->indev[0] = pm->physindev[0] = '\0';
+
+	if (out) {
+		/* If out exists, then out is a bridge port */
+		strcpy(pm->physoutdev, out->name);
+		strcpy(pm->outdev, out->br_port->br->dev->name);
+	} else
+		pm->outdev[0] = pm->physoutdev[0] = '\0';
+
+	if (skb_copy_bits(skb, -ETH_HLEN, pm->data, copy_len) < 0)
+		BUG();
+
+	if (ub->qlen > 1)
+		ub->lastnlh->nlmsg_flags |= NLM_F_MULTI;
+
+	ub->lastnlh = nlh;
+
+	if (ub->qlen >= uloginfo->qthreshold)
+		ulog_send(group);
+	else if (!timer_pending(&ub->timer)) {
+		ub->timer.expires = jiffies + flushtimeout * HZ / 100;
+		add_timer(&ub->timer);
+	}
+
+unlock:
+	spin_unlock_bh(lock);
+
+	return;
+
+nlmsg_failure:
+	printk(KERN_CRIT "ebt_ulog: error during NLMSG_PUT. This should "
+	       "not happen, please report to author.\n");
+	goto unlock;
+alloc_failure:
+	goto unlock;
+}
+
+static int ebt_ulog_check(const char *tablename, unsigned int hookmask,
+   const struct ebt_entry *e, void *data, unsigned int datalen)
+{
+	struct ebt_ulog_info *uloginfo = (struct ebt_ulog_info *)data;
+
+	if (datalen != EBT_ALIGN(sizeof(struct ebt_ulog_info)) ||
+	    uloginfo->nlgroup > 31)
+		return -EINVAL;
+
+	uloginfo->prefix[EBT_ULOG_PREFIX_LEN - 1] = '\0';
+
+	if (uloginfo->qthreshold > EBT_ULOG_MAX_QLEN)
+		uloginfo->qthreshold = EBT_ULOG_MAX_QLEN;
+
+	return 0;
+}
+
+static struct ebt_watcher ulog = {
+	.name		= EBT_ULOG_WATCHER,
+	.watcher	= ebt_ulog,
+	.check		= ebt_ulog_check,
+	.me		= THIS_MODULE,
+};
+
+static int __init init(void)
+{
+	int i, ret = 0;
+
+	if (nlbufsiz >= 128*1024) {
+		printk(KERN_NOTICE "ebt_ulog: Netlink buffer has to be <= 128kB,"
+		       " please try a smaller nlbufsiz parameter.\n");
+		return -EINVAL;
+	}
+
+	/* initialize ulog_buffers */
+	for (i = 0; i < EBT_ULOG_MAXNLGROUPS; i++) {
+		init_timer(&ulog_buffers[i].timer);
+		ulog_buffers[i].timer.function = ulog_timer;
+		ulog_buffers[i].timer.data = i;
+		spin_lock_init(&ulog_buffers[i].lock);
+	}
+
+	ebtulognl = netlink_kernel_create(NETLINK_NFLOG, NULL);
+	if (!ebtulognl)
+		ret = -ENOMEM;
+	else if ((ret = ebt_register_watcher(&ulog)))
+		sock_release(ebtulognl->sk_socket);
+
+	return ret;
+}
+
+static void __exit fini(void)
+{
+	ebt_ulog_buff_t *ub;
+	int i;
+
+	ebt_unregister_watcher(&ulog);
+	for (i = 0; i < EBT_ULOG_MAXNLGROUPS; i++) {
+		ub = &ulog_buffers[i];
+		if (timer_pending(&ub->timer))
+			del_timer(&ub->timer);
+		spin_lock_bh(&ub->lock);
+		if (ub->skb) {
+			kfree_skb(ub->skb);
+			ub->skb = NULL;
+		}
+		spin_unlock_bh(&ub->lock);
+	}
+	sock_release(ebtulognl->sk_socket);
+}
+
+module_init(init);
+module_exit(fini);
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Bart De Schuymer <bdschuym@pandora.be>");
+MODULE_DESCRIPTION("ebtables userspace logging module for bridged Ethernet"
+                   " frames");
diff -Nru a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
--- a/net/bridge/netfilter/ebtables.c	2005-03-01 23:38:55 -08:00
+++ b/net/bridge/netfilter/ebtables.c	2005-03-01 23:38:55 -08:00
@@ -90,10 +90,10 @@
 { {NULL, NULL}, EBT_STANDARD_TARGET, NULL, NULL, NULL, NULL};
 
 static inline int ebt_do_watcher (struct ebt_entry_watcher *w,
-   const struct sk_buff *skb, const struct net_device *in,
+   const struct sk_buff *skb, unsigned int hooknr, const struct net_device *in,
    const struct net_device *out)
 {
-	w->u.watcher->watcher(skb, in, out, w->data,
+	w->u.watcher->watcher(skb, hooknr, in, out, w->data,
 	   w->watcher_size);
 	/* watchers don't give a verdict */
 	return 0;
@@ -208,7 +208,7 @@
 
 		/* these should only watch: not modify, nor tell us
 		   what to do with the packet */
-		EBT_WATCHER_ITERATE(point, ebt_do_watcher, *pskb, in,
+		EBT_WATCHER_ITERATE(point, ebt_do_watcher, *pskb, hook, in,
 		   out);
 
 		t = (struct ebt_entry_target *)
diff -Nru a/net/compat.c b/net/compat.c
--- a/net/compat.c	2005-03-01 23:38:59 -08:00
+++ b/net/compat.c	2005-03-01 23:38:59 -08:00
@@ -125,7 +125,7 @@
 	 (struct compat_cmsghdr __user *)NULL)
 
 #define CMSG_COMPAT_OK(ucmlen, ucmsg, mhdr) \
-	((ucmlen) >= sizeof(struct cmsghdr) && \
+	((ucmlen) >= sizeof(struct compat_cmsghdr) && \
 	 (ucmlen) <= (unsigned long) \
 	 ((mhdr)->msg_controllen - \
 	  ((char *)(ucmsg) - (char *)(mhdr)->msg_control)))
@@ -507,7 +507,8 @@
 asmlinkage long compat_sys_getsockopt(int fd, int level, int optname,
 				char __user *optval, int __user *optlen)
 {
-	if (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO)
+	if (level == SOL_SOCKET &&
+	    (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO))
 		return do_get_sock_timeout(fd, level, optname, optval, optlen);
 	return sys_getsockopt(fd, level, optname, optval, optlen);
 }
diff -Nru a/net/core/datagram.c b/net/core/datagram.c
--- a/net/core/datagram.c	2005-03-01 23:39:06 -08:00
+++ b/net/core/datagram.c	2005-03-01 23:39:06 -08:00
@@ -199,19 +199,6 @@
 	kfree_skb(skb);
 }
 
-/*
- *	Copy a datagram to a linear buffer.
- */
-int skb_copy_datagram(const struct sk_buff *skb, int offset, char __user *to, int size)
-{
-	struct iovec iov = {
-		.iov_base = to,
-		.iov_len =size,
-	};
-
-	return skb_copy_datagram_iovec(skb, offset, &iov, size);
-}
-
 /**
  *	skb_copy_datagram_iovec - Copy a datagram to an iovec.
  *	@skb - buffer to copy
@@ -296,8 +283,9 @@
 	return -EFAULT;
 }
 
-int skb_copy_and_csum_datagram(const struct sk_buff *skb, int offset,
-			       u8 __user *to, int len, unsigned int *csump)
+static int skb_copy_and_csum_datagram(const struct sk_buff *skb, int offset,
+				      u8 __user *to, int len,
+				      unsigned int *csump)
 {
 	int start = skb_headlen(skb);
 	int pos = 0;
@@ -489,7 +477,6 @@
 
 EXPORT_SYMBOL(datagram_poll);
 EXPORT_SYMBOL(skb_copy_and_csum_datagram_iovec);
-EXPORT_SYMBOL(skb_copy_datagram);
 EXPORT_SYMBOL(skb_copy_datagram_iovec);
 EXPORT_SYMBOL(skb_free_datagram);
 EXPORT_SYMBOL(skb_recv_datagram);
diff -Nru a/net/core/dev.c b/net/core/dev.c
--- a/net/core/dev.c	2005-03-01 23:38:57 -08:00
+++ b/net/core/dev.c	2005-03-01 23:38:57 -08:00
@@ -108,6 +108,7 @@
 #include <linux/kallsyms.h>
 #include <linux/netpoll.h>
 #include <linux/rcupdate.h>
+#include <linux/delay.h>
 #ifdef CONFIG_NET_RADIO
 #include <linux/wireless.h>		/* Note : will define WIRELESS_EXT */
 #include <net/iw_handler.h>
@@ -154,7 +155,7 @@
  *		86DD	IPv6
  */
 
-static spinlock_t ptype_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(ptype_lock);
 static struct list_head ptype_base[16];	/* 16 way hashed list */
 static struct list_head ptype_all;		/* Taps */
 
@@ -183,8 +184,8 @@
  * semaphore held.
  */
 struct net_device *dev_base;
-struct net_device **dev_tail = &dev_base;
-rwlock_t dev_base_lock = RW_LOCK_UNLOCKED;
+static struct net_device **dev_tail = &dev_base;
+DEFINE_RWLOCK(dev_base_lock);
 
 EXPORT_SYMBOL(dev_base);
 EXPORT_SYMBOL(dev_base_lock);
@@ -361,7 +362,7 @@
  *	returns 0 on error and 1 on success.  This is a generic routine to
  *	all netdevices.
  */
-int netdev_boot_setup_add(char *name, struct ifmap *map)
+static int netdev_boot_setup_add(char *name, struct ifmap *map)
 {
 	struct netdev_boot_setup *s;
 	int i;
@@ -644,7 +645,7 @@
  *	Network device names need to be valid file names to
  *	to allow sysfs to work
  */
-int dev_valid_name(const char *name)
+static int dev_valid_name(const char *name)
 {
 	return !(*name == '\0' 
 		 || !strcmp(name, ".")
@@ -1119,7 +1120,7 @@
 		return 0;
 
 	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)
-		if (skb_shinfo(skb)->frags[i].page >= highmem_start_page)
+		if (PageHighMem(skb_shinfo(skb)->frags[i].page))
 			return 1;
 
 	return 0;
@@ -1486,7 +1487,7 @@
 
 	preempt_disable();
 	err = netif_rx(skb);
-	if (softirq_pending(smp_processor_id()))
+	if (local_softirq_pending())
 		do_softirq();
 	preempt_enable();
 
@@ -1590,7 +1591,7 @@
  * the ingress scheduler, you just cant add policies on ingress.
  *
  */
-int ing_filter(struct sk_buff *skb) 
+static int ing_filter(struct sk_buff *skb) 
 {
 	struct Qdisc *q;
 	struct net_device *dev = skb->dev;
@@ -2674,7 +2675,7 @@
 static int dev_boot_phase = 1;
 
 /* Delayed registration/unregisteration */
-static spinlock_t net_todo_list_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(net_todo_list_lock);
 static struct list_head net_todo_list = LIST_HEAD_INIT(net_todo_list);
 
 static inline void net_set_todo(struct net_device *dev)
@@ -2693,8 +2694,7 @@
  *	chain. 0 is returned on success. A negative errno code is returned
  *	on a failure to set up the device, or if the name is a duplicate.
  *
- *	Callers must hold the rtnl semaphore.  See the comment at the
- *	end of Space.c for details about the locking.  You may want
+ *	Callers must hold the rtnl semaphore. You may want
  *	register_netdev() instead of this.
  *
  *	BUGS:
@@ -2815,6 +2815,51 @@
 	goto out;
 }
 
+/**
+ *	register_netdev	- register a network device
+ *	@dev: device to register
+ *
+ *	Take a completed network device structure and add it to the kernel
+ *	interfaces. A %NETDEV_REGISTER message is sent to the netdev notifier
+ *	chain. 0 is returned on success. A negative errno code is returned
+ *	on a failure to set up the device, or if the name is a duplicate.
+ *
+ *	This is a wrapper around register_netdev that takes the rtnl semaphore
+ *	and expands the device name if you passed a format string to
+ *	alloc_netdev.
+ */
+int register_netdev(struct net_device *dev)
+{
+	int err;
+
+	rtnl_lock();
+
+	/*
+	 * If the name is a format string the caller wants us to do a
+	 * name allocation.
+	 */
+	if (strchr(dev->name, '%')) {
+		err = dev_alloc_name(dev, dev->name);
+		if (err < 0)
+			goto out;
+	}
+	
+	/*
+	 * Back compatibility hook. Kill this one in 2.5
+	 */
+	if (dev->name[0] == 0 || dev->name[0] == ' ') {
+		err = dev_alloc_name(dev, "eth%d");
+		if (err < 0)
+			goto out;
+	}
+
+	err = register_netdevice(dev);
+out:
+	rtnl_unlock();
+	return err;
+}
+EXPORT_SYMBOL(register_netdev);
+
 /*
  * netdev_wait_allrefs - wait until all references are gone.
  *
@@ -2855,8 +2900,7 @@
 			rebroadcast_time = jiffies;
 		}
 
-		current->state = TASK_INTERRUPTIBLE;
-		schedule_timeout(HZ / 4);
+		msleep(250);
 
 		if (time_after(jiffies, warning_time + 10 * HZ)) {
 			printk(KERN_EMERG "unregister_netdevice: "
@@ -2958,6 +3002,46 @@
 }
 
 /**
+ *	alloc_netdev - allocate network device
+ *	@sizeof_priv:	size of private data to allocate space for
+ *	@name:		device name format string
+ *	@setup:		callback to initialize device
+ *
+ *	Allocates a struct net_device with private data area for driver use
+ *	and performs basic initialization.
+ */
+struct net_device *alloc_netdev(int sizeof_priv, const char *name,
+		void (*setup)(struct net_device *))
+{
+	void *p;
+	struct net_device *dev;
+	int alloc_size;
+
+	/* ensure 32-byte alignment of both the device and private area */
+	alloc_size = (sizeof(*dev) + NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST;
+	alloc_size += sizeof_priv + NETDEV_ALIGN_CONST;
+
+	p = kmalloc(alloc_size, GFP_KERNEL);
+	if (!p) {
+		printk(KERN_ERR "alloc_dev: Unable to allocate device.\n");
+		return NULL;
+	}
+	memset(p, 0, alloc_size);
+
+	dev = (struct net_device *)
+		(((long)p + NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST);
+	dev->padded = (char *)dev - (char *)p;
+
+	if (sizeof_priv)
+		dev->priv = netdev_priv(dev);
+
+	setup(dev);
+	strcpy(dev->name, name);
+	return dev;
+}
+EXPORT_SYMBOL(alloc_netdev);
+
+/**
  *	free_netdev - free network device
  *	@dev: device
  *
@@ -2999,8 +3083,7 @@
  *	from the kernel tables. On success 0 is returned, on a failure
  *	a negative errno code is returned.
  *
- *	Callers must hold the rtnl semaphore.  See the comment at the
- *	end of Space.c for details about the locking.  You may want
+ *	Callers must hold the rtnl semaphore.  You may want
  *	unregister_netdev() instead of this.
  */
 
@@ -3078,6 +3161,27 @@
 	return 0;
 }
 
+/**
+ *	unregister_netdev - remove device from the kernel
+ *	@dev: device
+ *
+ *	This function shuts down a device interface and removes it
+ *	from the kernel tables. On success 0 is returned, on a failure
+ *	a negative errno code is returned.
+ *
+ *	This is just a wrapper for unregister_netdevice that takes
+ *	the rtnl semaphore.  In general you want to use this and not
+ *	unregister_netdevice.
+ */
+void unregister_netdev(struct net_device *dev)
+{
+	rtnl_lock();
+	unregister_netdevice(dev);
+	rtnl_unlock();
+}
+
+EXPORT_SYMBOL(unregister_netdev);
+
 #ifdef CONFIG_HOTPLUG_CPU
 static int dev_cpu_callback(struct notifier_block *nfb,
 			    unsigned long action,
@@ -3241,10 +3345,5 @@
 #ifdef CONFIG_KMOD
 EXPORT_SYMBOL(dev_load);
 #endif
-
-#ifdef CONFIG_NET_CLS_ACT
-EXPORT_SYMBOL(ing_filter);
-#endif
-
 
 EXPORT_PER_CPU_SYMBOL(softnet_data);
diff -Nru a/net/core/dst.c b/net/core/dst.c
--- a/net/core/dst.c	2005-03-01 23:38:59 -08:00
+++ b/net/core/dst.c	2005-03-01 23:38:59 -08:00
@@ -32,7 +32,7 @@
 #if RT_CACHE_DEBUG >= 2 
 static atomic_t			 dst_total = ATOMIC_INIT(0);
 #endif
-static spinlock_t		 dst_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(dst_lock);
 
 static unsigned long dst_gc_timer_expires;
 static unsigned long dst_gc_timer_inc = DST_GC_MAX;
@@ -169,6 +169,8 @@
 	struct neighbour *neigh;
 	struct hh_cache *hh;
 
+	smp_rmb();
+
 again:
 	neigh = dst->neighbour;
 	hh = dst->hh;
@@ -218,31 +220,28 @@
  *
  * Commented and originally written by Alexey.
  */
-static void dst_ifdown(struct dst_entry *dst, int unregister)
+static inline void dst_ifdown(struct dst_entry *dst, struct net_device *dev,
+			      int unregister)
 {
-	struct net_device *dev = dst->dev;
+	if (dst->ops->ifdown)
+		dst->ops->ifdown(dst, dev, unregister);
+
+	if (dev != dst->dev)
+		return;
 
 	if (!unregister) {
 		dst->input = dst_discard_in;
 		dst->output = dst_discard_out;
-	}
-
-	do {
-		if (unregister) {
-			dst->dev = &loopback_dev;
-			dev_hold(&loopback_dev);
+	} else {
+		dst->dev = &loopback_dev;
+		dev_hold(&loopback_dev);
+		dev_put(dev);
+		if (dst->neighbour && dst->neighbour->dev == dev) {
+			dst->neighbour->dev = &loopback_dev;
 			dev_put(dev);
-			if (dst->neighbour && dst->neighbour->dev == dev) {
-				dst->neighbour->dev = &loopback_dev;
-				dev_put(dev);
-				dev_hold(&loopback_dev);
-			}
+			dev_hold(&loopback_dev);
 		}
-
-		if (dst->ops->ifdown)
-			dst->ops->ifdown(dst, unregister);
-	} while ((dst = dst->child) && dst->flags & DST_NOHASH &&
-		 dst->dev == dev);
+	}
 }
 
 static int dst_dev_event(struct notifier_block *this, unsigned long event, void *ptr)
@@ -255,8 +254,7 @@
 	case NETDEV_DOWN:
 		spin_lock_bh(&dst_lock);
 		for (dst = dst_garbage_list; dst; dst = dst->next) {
-			if (dst->dev == dev)
-				dst_ifdown(dst, event != NETDEV_DOWN);
+			dst_ifdown(dst, dev, event != NETDEV_DOWN);
 		}
 		spin_unlock_bh(&dst_lock);
 		break;
@@ -264,7 +262,7 @@
 	return NOTIFY_DONE;
 }
 
-struct notifier_block dst_dev_notifier = {
+static struct notifier_block dst_dev_notifier = {
 	.notifier_call	= dst_dev_event,
 };
 
diff -Nru a/net/core/dv.c b/net/core/dv.c
--- a/net/core/dv.c	2005-03-01 23:38:56 -08:00
+++ b/net/core/dv.c	2005-03-01 23:38:56 -08:00
@@ -52,26 +52,20 @@
 {
 	int alloc_size = (sizeof(struct divert_blk) + 3) & ~3;
 
+	dev->divert = NULL;
 	if (dev->type == ARPHRD_ETHER) {
-		printk(KERN_DEBUG "divert: allocating divert_blk for %s\n",
-		       dev->name);
-
 		dev->divert = (struct divert_blk *)
 			kmalloc(alloc_size, GFP_KERNEL);
 		if (dev->divert == NULL) {
-			printk(KERN_DEBUG "divert: unable to allocate divert_blk for %s\n",
+			printk(KERN_INFO "divert: unable to allocate divert_blk for %s\n",
 			       dev->name);
 			return -ENOMEM;
-		} else {
-			memset(dev->divert, 0, sizeof(struct divert_blk));
 		}
-		dev_hold(dev);
-	} else {
-		printk(KERN_DEBUG "divert: not allocating divert_blk for non-ethernet device %s\n",
-		       dev->name);
 
-		dev->divert = NULL;
+		memset(dev->divert, 0, sizeof(struct divert_blk));
+		dev_hold(dev);
 	}
+
 	return 0;
 } 
 
@@ -85,11 +79,6 @@
 		kfree(dev->divert);
 		dev->divert=NULL;
 		dev_put(dev);
-		printk(KERN_DEBUG "divert: freeing divert_blk for %s\n",
-		       dev->name);
-	} else {
-		printk(KERN_DEBUG "divert: no divert_blk to free, %s not ethernet\n",
-		       dev->name);
 	}
 }
 
@@ -192,8 +181,12 @@
 /*
  * control function of the diverter
  */
+#if 0
 #define	DVDBG(a)	\
 	printk(KERN_DEBUG "divert_ioctl() line %d %s\n", __LINE__, (a))
+#else
+#define	DVDBG(a)
+#endif
 
 int divert_ioctl(unsigned int cmd, struct divert_cf __user *arg)
 {
diff -Nru a/net/core/gen_estimator.c b/net/core/gen_estimator.c
--- a/net/core/gen_estimator.c	2005-03-01 23:38:59 -08:00
+++ b/net/core/gen_estimator.c	2005-03-01 23:38:59 -08:00
@@ -100,7 +100,7 @@
 static struct gen_estimator_head elist[EST_MAX_INTERVAL+1];
 
 /* Estimator array lock */
-static rwlock_t est_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(est_lock);
 
 static void est_timer(unsigned long arg)
 {
diff -Nru a/net/core/iovec.c b/net/core/iovec.c
--- a/net/core/iovec.c	2005-03-01 23:39:18 -08:00
+++ b/net/core/iovec.c	2005-03-01 23:39:18 -08:00
@@ -99,28 +99,6 @@
 }
 
 /*
- *	In kernel copy to iovec. Returns -EFAULT on error.
- *
- *	Note: this modifies the original iovec.
- */
- 
-void memcpy_tokerneliovec(struct iovec *iov, unsigned char *kdata, int len)
-{
-	while (len > 0) {
-		if (iov->iov_len) {
-			int copy = min_t(unsigned int, iov->iov_len, len);
-			memcpy(iov->iov_base, kdata, copy);
-			kdata += copy;
-			len -= copy;
-			iov->iov_len -= copy;
-			iov->iov_base += copy;
-		}
-		iov++;
-	}
-}
-
-
-/*
  *	Copy iovec to kernel. Returns -EFAULT on error.
  *
  *	Note: this modifies the original iovec.
@@ -259,4 +237,3 @@
 EXPORT_SYMBOL(memcpy_fromiovec);
 EXPORT_SYMBOL(memcpy_fromiovecend);
 EXPORT_SYMBOL(memcpy_toiovec);
-EXPORT_SYMBOL(memcpy_tokerneliovec);
diff -Nru a/net/core/link_watch.c b/net/core/link_watch.c
--- a/net/core/link_watch.c	2005-03-01 23:38:43 -08:00
+++ b/net/core/link_watch.c	2005-03-01 23:38:43 -08:00
@@ -38,7 +38,7 @@
 static DECLARE_WORK(linkwatch_work, linkwatch_event, NULL);
 
 static LIST_HEAD(lweventlist);
-static spinlock_t lweventlist_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(lweventlist_lock);
 
 struct lw_event {
 	struct list_head list;
diff -Nru a/net/core/neighbour.c b/net/core/neighbour.c
--- a/net/core/neighbour.c	2005-03-01 23:38:51 -08:00
+++ b/net/core/neighbour.c	2005-03-01 23:38:51 -08:00
@@ -93,7 +93,7 @@
    list of neighbour tables. This list is used only in process context,
  */
 
-static rwlock_t neigh_tbl_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(neigh_tbl_lock);
 
 static int neigh_blackhole(struct sk_buff *skb)
 {
@@ -109,7 +109,7 @@
 
 unsigned long neigh_rand_reach_time(unsigned long base)
 {
-	return (net_random() % base) + (base >> 1);
+	return (base ? (net_random() % base) + (base >> 1) : 0);
 }
 
 
@@ -1556,6 +1556,7 @@
 					 sizeof(struct ndmsg));
 	struct ndmsg *ndm = NLMSG_DATA(nlh);
 
+	nlh->nlmsg_flags = pid ? NLM_F_MULTI : 0;
 	ndm->ndm_family	 = n->ops->family;
 	ndm->ndm_flags	 = n->flags;
 	ndm->ndm_type	 = n->type;
diff -Nru a/net/core/netfilter.c b/net/core/netfilter.c
--- a/net/core/netfilter.c	2005-03-01 23:38:57 -08:00
+++ b/net/core/netfilter.c	2005-03-01 23:38:57 -08:00
@@ -47,7 +47,7 @@
 
 struct list_head nf_hooks[NPROTO][NF_MAX_HOOKS];
 static LIST_HEAD(nf_sockopts);
-static spinlock_t nf_hook_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(nf_hook_lock);
 
 /* 
  * A queue handler may be registered for each protocol.  Each is protected by
@@ -58,7 +58,7 @@
 	nf_queue_outfn_t outfn;
 	void *data;
 } queue_handler[NPROTO];
-static rwlock_t queue_handler_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(queue_handler_lock);
 
 int nf_register_hook(struct nf_hook_ops *reg)
 {
@@ -173,7 +173,7 @@
 	printk("\n");
 }
 
-void nf_dump_skb(int pf, struct sk_buff *skb)
+static void nf_dump_skb(int pf, struct sk_buff *skb)
 {
 	printk("skb: pf=%i %s dev=%s len=%u\n", 
 	       pf,
@@ -744,7 +744,7 @@
 
 static nf_logfn *nf_logging[NPROTO]; /* = NULL */
 static int reported = 0;
-static spinlock_t nf_log_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(nf_log_lock);
 
 int nf_log_register(int pf, nf_logfn *logfn)
 {
diff -Nru a/net/core/netpoll.c b/net/core/netpoll.c
--- a/net/core/netpoll.c	2005-03-01 23:39:17 -08:00
+++ b/net/core/netpoll.c	2005-03-01 23:39:17 -08:00
@@ -31,15 +31,15 @@
 #define MAX_SKBS 32
 #define MAX_UDP_CHUNK 1460
 
-static spinlock_t skb_list_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(skb_list_lock);
 static int nr_skbs;
 static struct sk_buff *skbs;
 
-static spinlock_t rx_list_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(rx_list_lock);
 static LIST_HEAD(rx_list);
 
 static atomic_t trapped;
-spinlock_t netpoll_poll_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(netpoll_poll_lock);
 
 #define NETPOLL_RX_ENABLED  1
 #define NETPOLL_RX_DROP     2
@@ -65,27 +65,25 @@
 	return csum_fold(skb_checksum(skb, 0, skb->len, skb->csum));
 }
 
-void netpoll_poll(struct netpoll *np)
+/*
+ * Check whether delayed processing was scheduled for our current CPU,
+ * and then manually invoke NAPI polling to pump data off the card.
+ *
+ * In cases where there is bi-directional communications, reading only
+ * one message at a time can lead to packets being dropped by the
+ * network adapter, forcing superfluous retries and possibly timeouts.
+ * Thus, we set our budget to greater than 1.
+ */
+static void poll_napi(struct netpoll *np)
 {
-	/*
-	 * In cases where there is bi-directional communications, reading
-	 * only one message at a time can lead to packets being dropped by
-	 * the network adapter, forcing superfluous retries and possibly
-	 * timeouts.  Thus, we set our budget to a more reasonable value.
-	 */
 	int budget = 16;
 	unsigned long flags;
+	struct softnet_data *queue;
 
-	if(!np->dev || !netif_running(np->dev) || !np->dev->poll_controller)
-		return;
-
-	/* Process pending work on NIC */
-	np->dev->poll_controller(np->dev);
-
-	/* If scheduling is stopped, tickle NAPI bits */
 	spin_lock_irqsave(&netpoll_poll_lock, flags);
-	if (np->dev->poll &&
-	    test_bit(__LINK_STATE_RX_SCHED, &np->dev->state)) {
+	queue = &__get_cpu_var(softnet_data);
+	if (test_bit(__LINK_STATE_RX_SCHED, &np->dev->state) &&
+	    !list_empty(&queue->poll_list)) {
 		np->dev->netpoll_rx |= NETPOLL_RX_DROP;
 		atomic_inc(&trapped);
 
@@ -95,6 +93,17 @@
 		np->dev->netpoll_rx &= ~NETPOLL_RX_DROP;
 	}
 	spin_unlock_irqrestore(&netpoll_poll_lock, flags);
+}
+
+void netpoll_poll(struct netpoll *np)
+{
+	if(!np->dev || !netif_running(np->dev) || !np->dev->poll_controller)
+		return;
+
+	/* Process pending work on NIC */
+	np->dev->poll_controller(np->dev);
+	if (np->dev->poll)
+		poll_napi(np);
 
 	zap_completion_queue();
 }
@@ -178,7 +187,7 @@
 	return skb;
 }
 
-void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb)
+static void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb)
 {
 	int status;
 
@@ -676,6 +685,5 @@
 EXPORT_SYMBOL(netpoll_parse_options);
 EXPORT_SYMBOL(netpoll_setup);
 EXPORT_SYMBOL(netpoll_cleanup);
-EXPORT_SYMBOL(netpoll_send_skb);
 EXPORT_SYMBOL(netpoll_send_udp);
 EXPORT_SYMBOL(netpoll_poll);
diff -Nru a/net/core/pktgen.c b/net/core/pktgen.c
--- a/net/core/pktgen.c	2005-03-01 23:39:07 -08:00
+++ b/net/core/pktgen.c	2005-03-01 23:39:07 -08:00
@@ -1,13 +1,22 @@
-/* -*-linux-c-*-
- * $Id: pktgen.c,v 1.8 2002/07/15 19:30:17 robert Exp $
- * pktgen.c: Packet Generator for performance evaluation.
- *
+/*
+ * Authors:
  * Copyright 2001, 2002 by Robert Olsson <robert.olsson@its.uu.se>
- *				 Uppsala University, Sweden
+ *                             Uppsala University and
+ *                             Swedish University of Agricultural Sciences
+ *
+ * Alexey Kuznetsov  <kuznet@ms2.inr.ac.ru>
+ * Ben Greear <greearb@candelatech.com>
+ * Jens Låås <jens.laas@data.slu.se>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
  *
  * A tool for loading the network with preconfigurated packets.
  * The tool is implemented as a linux module.  Parameters are output 
- * device, IPG (interpacket gap), number of packets, and whether
+ * device, delay (to hard_xmit), number of packets, and whether
  * to use multiple SKBs or just the same one.
  * pktgen uses the installed interface's output routine.
  *
@@ -21,866 +30,702 @@
  * Added multiskb option 020301 --DaveM
  * Scaling of results. 020417--sigurdur@linpro.no
  * Significant re-work of the module:
- *   *  Updated to support generation over multiple interfaces at once
- *       by creating 32 /proc/net/pg* files.  Each file can be manipulated
- *       individually.
+ *   *  Convert to threaded model to more efficiently be able to transmit
+ *       and receive on multiple interfaces at once.
  *   *  Converted many counters to __u64 to allow longer runs.
  *   *  Allow configuration of ranges, like min/max IP address, MACs,
  *       and UDP-ports, for both source and destination, and can
  *       set to use a random distribution or sequentially walk the range.
- *   *  Can now change some values after starting.
+ *   *  Can now change most values after starting.
  *   *  Place 12-byte packet in UDP payload with magic number,
- *       sequence number, and timestamp.  Will write receiver next.
- *   *  The new changes seem to have a performance impact of around 1%,
- *       as far as I can tell.
+ *       sequence number, and timestamp.
+ *   *  Add receiver code that detects dropped pkts, re-ordered pkts, and
+ *       latencies (with micro-second) precision.
+ *   *  Add IOCTL interface to easily get counters & configuration.
  *   --Ben Greear <greearb@candelatech.com>
- * Integrated to 2.5.x 021029 --Lucio Maciel (luciomaciel@zipmail.com.br)
  *
  * Renamed multiskb to clone_skb and cleaned up sending core for two distinct 
  * skb modes. A clone_skb=0 mode for Ben "ranges" work and a clone_skb != 0 
  * as a "fastpath" with a configurable number of clones after alloc's.
- *
  * clone_skb=0 means all packets are allocated this also means ranges time 
  * stamps etc can be used. clone_skb=100 means 1 malloc is followed by 100 
  * clones.
  *
  * Also moved to /proc/net/pktgen/ 
- * --ro 
+ * --ro
+ *
+ * Sept 10:  Fixed threading/locking.  Lots of bone-headed and more clever
+ *    mistakes.  Also merged in DaveM's patch in the -pre6 patch.
+ * --Ben Greear <greearb@candelatech.com>
+ *
+ * Integrated to 2.5.x 021029 --Lucio Maciel (luciomaciel@zipmail.com.br)
+ *
+ * 
+ * 021124 Finished major redesign and rewrite for new functionality.
+ * See Documentation/networking/pktgen.txt for how to use this.
+ *
+ * The new operation:
+ * For each CPU one thread/process is created at start. This process checks 
+ * for running devices in the if_list and sends packets until count is 0 it 
+ * also the thread checks the thread->control which is used for inter-process 
+ * communication. controlling process "posts" operations to the threads this 
+ * way. The if_lock should be possible to remove when add/rem_device is merged
+ * into this too.
+ *
+ * By design there should only be *one* "controlling" process. In practice 
+ * multiple write accesses gives unpredictable result. Understood by "write" 
+ * to /proc gives result code thats should be read be the "writer".
+ * For pratical use this should be no problem.
+ *
+ * Note when adding devices to a specific CPU there good idea to also assign 
+ * /proc/irq/XX/smp_affinity so TX-interrupts gets bound to the same CPU. 
+ * --ro
  *
  * Fix refcount off by one if first packet fails, potential null deref, 
  * memleak 030710- KJP
  *
+ * First "ranges" functionality for ipv6 030726 --ro
+ *
+ * Included flow support. 030802 ANK.
+ *
  * Fixed unaligned access on IA-64 Grant Grundler <grundler@parisc-linux.org>
+ * 
+ * Remove if fix from added Harald Welte <laforge@netfilter.org> 040419
+ * ia64 compilation fix from  Aron Griffis <aron@hp.com> 040604
  *
  * New xmit() return, do_div and misc clean up by Stephen Hemminger 
  * <shemminger@osdl.org> 040923
  *
- * See Documentation/networking/pktgen.txt for how to use this.
+ * Rany Dunlap fixed u64 printk compiler waring 
+ *
+ * Remove FCS from BW calculation.  Lennert Buytenhek <buytenh@wantstofly.org>
+ * New time handling. Lennert Buytenhek <buytenh@wantstofly.org> 041213
+ *
+ * Corrections from Nikolai Malykh (nmalykh@bilim.com) 
+ * Removed unused flags F_SET_SRCMAC & F_SET_SRCIP 041230
+ *
+ * interruptible_sleep_on_timeout() replaced Nishanth Aravamudan <nacc@us.ibm.com> 
+ * 050103
  */
-
+#include <linux/sys.h>
+#include <linux/types.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/kernel.h>
+#include <linux/smp_lock.h>
 #include <linux/sched.h>
-#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/sched.h>
+#include <linux/unistd.h>
 #include <linux/string.h>
 #include <linux/ptrace.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
+#include <linux/timer.h>
 #include <linux/init.h>
-#include <linux/inet.h>
-#include <linux/rcupdate.h>
-#include <linux/bitops.h>
-#include <asm/byteorder.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-#include <asm/uaccess.h>
-
-#include <linux/in.h>
-#include <linux/ip.h>
-#include <linux/udp.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
+#include <linux/inet.h>
 #include <linux/inetdevice.h>
 #include <linux/rtnetlink.h>
-#include <linux/proc_fs.h>
 #include <linux/if_arp.h>
+#include <linux/in.h>
+#include <linux/ip.h>
+#include <linux/ipv6.h>
+#include <linux/udp.h>
+#include <linux/proc_fs.h>
+#include <linux/wait.h>
 #include <net/checksum.h>
+#include <net/ipv6.h>
+#include <net/addrconf.h>
+#include <asm/byteorder.h>
+#include <linux/rcupdate.h>
+#include <asm/bitops.h>
+#include <asm/io.h>
+#include <asm/dma.h>
+#include <asm/uaccess.h>
+#include <asm/div64.h> /* do_div */
 #include <asm/timex.h>
 
-#define cycles()	((u32)get_cycles())
-
-
-#define VERSION "pktgen version 1.32"
-static char version[] __initdata = 
-  "pktgen.c: v1.4: Packet Generator for packet performance testing.\n";
-
-/* Used to help with determining the pkts on receive */
-
-#define PKTGEN_MAGIC 0xbe9be955
 
+#define VERSION  "pktgen v2.58: Packet Generator for packet performance testing.\n"
 
-/* Keep information per interface */
-struct pktgen_info {
-	/* Parameters */
+/* #define PG_DEBUG(a) a */
+#define PG_DEBUG(a) 
 
-	/* If min != max, then we will either do a linear iteration, or
-	 * we will do a random selection from within the range.
-	 */
-	__u32 flags;     
+/* The buckets are exponential in 'width' */
+#define LAT_BUCKETS_MAX 32
+#define IP_NAME_SZ 32
 
+/* Device flag bits */
 #define F_IPSRC_RND   (1<<0)  /* IP-Src Random  */
 #define F_IPDST_RND   (1<<1)  /* IP-Dst Random  */
 #define F_UDPSRC_RND  (1<<2)  /* UDP-Src Random */
 #define F_UDPDST_RND  (1<<3)  /* UDP-Dst Random */
 #define F_MACSRC_RND  (1<<4)  /* MAC-Src Random */
 #define F_MACDST_RND  (1<<5)  /* MAC-Dst Random */
-#define F_SET_SRCMAC  (1<<6)  /* Specify-Src-Mac 
-				 (default is to use Interface's MAC Addr) */
-#define F_SET_SRCIP   (1<<7)  /*  Specify-Src-IP
-				  (default is to use Interface's IP Addr) */ 
+#define F_TXSIZE_RND  (1<<6)  /* Transmit size is random */
+#define F_IPV6        (1<<7)  /* Interface in IPV6 Mode */
 
-	
-	int pkt_size;    /* = ETH_ZLEN; */
-	int nfrags;
-	__u32 ipg;       /* Default Interpacket gap in nsec */
-	__u64 count;     /* Default No packets to send */
-	__u64 sofar;     /* How many pkts we've sent so far */
-	__u64 errors;    /* Errors when trying to transmit, pkts will be re-sent */
-	struct timeval started_at;
-	struct timeval stopped_at;
-	__u64 idle_acc;
-	__u32 seq_num;
-	
-	int clone_skb;   /* Use multiple SKBs during packet gen.  If this number
-			  * is greater than 1, then that many coppies of the same
-			  * packet will be sent before a new packet is allocated.
-			  * For instance, if you want to send 1024 identical packets
-			  * before creating a new packet, set clone_skb to 1024.
-			  */
-	int busy;
-	int do_run_run;   /* if this changes to false, the test will stop */
-	
-	char outdev[32];
-	char dst_min[32];
-	char dst_max[32];
-	char src_min[32];
-	char src_max[32];
+/* Thread control flag bits */
+#define T_TERMINATE   (1<<0)  
+#define T_STOP        (1<<1)  /* Stop run */
+#define T_RUN         (1<<2)  /* Start run */
+#define T_REMDEV      (1<<3)  /* Remove all devs */
+
+/* Locks */
+#define   thread_lock()        spin_lock(&_thread_lock)
+#define   thread_unlock()      spin_unlock(&_thread_lock)
+
+/* If lock -- can be removed after some work */
+#define   if_lock(t)           spin_lock(&(t->if_lock));
+#define   if_unlock(t)           spin_unlock(&(t->if_lock));
+
+/* Used to help with determining the pkts on receive */
+#define PKTGEN_MAGIC 0xbe9be955
+#define PG_PROC_DIR "pktgen"
+
+#define MAX_CFLOWS  65536
+
+struct flow_state
+{
+	__u32		cur_daddr;
+	int		count;
+};
 
-	/* If we're doing ranges, random or incremental, then this
-	 * defines the min/max for those ranges.
+struct pktgen_dev {
+
+	/*
+	 * Try to keep frequent/infrequent used vars. separated.
 	 */
-	__u32 saddr_min; /* inclusive, source IP address */
-	__u32 saddr_max; /* exclusive, source IP address */
-	__u32 daddr_min; /* inclusive, dest IP address */
-	__u32 daddr_max; /* exclusive, dest IP address */
-
-	__u16 udp_src_min; /* inclusive, source UDP port */
-	__u16 udp_src_max; /* exclusive, source UDP port */
-	__u16 udp_dst_min; /* inclusive, dest UDP port */
-	__u16 udp_dst_max; /* exclusive, dest UDP port */
 
-	__u32 src_mac_count; /* How many MACs to iterate through */
-	__u32 dst_mac_count; /* How many MACs to iterate through */
-	
-	unsigned char dst_mac[6];
-	unsigned char src_mac[6];
-	
-	__u32 cur_dst_mac_offset;
-	__u32 cur_src_mac_offset;
-	__u32 cur_saddr;
-	__u32 cur_daddr;
-	__u16 cur_udp_dst;
-	__u16 cur_udp_src;
-	
-	__u8 hh[14];
-	/* = { 
-	   0x00, 0x80, 0xC8, 0x79, 0xB3, 0xCB, 
-	   
-	   We fill in SRC address later
-	   0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	   0x08, 0x00
-	   };
-	*/
-	__u16 pad; /* pad out the hh struct to an even 16 bytes */
-	char result[512];
-
-	/* proc file names */
-	char fname[80];
-	char busy_fname[80];
-	
-	struct proc_dir_entry *proc_ent;
-	struct proc_dir_entry *busy_proc_ent;
+        char ifname[32];
+        struct proc_dir_entry *proc_ent;
+        char result[512];
+        /* proc file names */
+        char fname[80];
+
+        struct pktgen_thread* pg_thread; /* the owner */
+        struct pktgen_dev *next; /* Used for chaining in the thread's run-queue */
+
+        int running;  /* if this changes to false, the test will stop */
+        
+        /* If min != max, then we will either do a linear iteration, or
+         * we will do a random selection from within the range.
+         */
+        __u32 flags;     
+
+        int min_pkt_size;    /* = ETH_ZLEN; */
+        int max_pkt_size;    /* = ETH_ZLEN; */
+        int nfrags;
+        __u32 delay_us;    /* Default delay */
+        __u32 delay_ns;
+        __u64 count;  /* Default No packets to send */
+        __u64 sofar;  /* How many pkts we've sent so far */
+        __u64 tx_bytes; /* How many bytes we've transmitted */
+        __u64 errors;    /* Errors when trying to transmit, pkts will be re-sent */
+
+        /* runtime counters relating to clone_skb */
+        __u64 next_tx_us;          /* timestamp of when to tx next */
+        __u32 next_tx_ns;
+        
+        __u64 allocated_skbs;
+        __u32 clone_count;
+	int last_ok;           /* Was last skb sent? 
+	                        * Or a failed transmit of some sort?  This will keep
+                                * sequence numbers in order, for example.
+				*/
+        __u64 started_at; /* micro-seconds */
+        __u64 stopped_at; /* micro-seconds */
+        __u64 idle_acc; /* micro-seconds */
+        __u32 seq_num;
+        
+        int clone_skb; /* Use multiple SKBs during packet gen.  If this number
+                          * is greater than 1, then that many coppies of the same
+                          * packet will be sent before a new packet is allocated.
+                          * For instance, if you want to send 1024 identical packets
+                          * before creating a new packet, set clone_skb to 1024.
+                          */
+        
+        char dst_min[IP_NAME_SZ]; /* IP, ie 1.2.3.4 */
+        char dst_max[IP_NAME_SZ]; /* IP, ie 1.2.3.4 */
+        char src_min[IP_NAME_SZ]; /* IP, ie 1.2.3.4 */
+        char src_max[IP_NAME_SZ]; /* IP, ie 1.2.3.4 */
+
+	struct in6_addr  in6_saddr;
+	struct in6_addr  in6_daddr;
+	struct in6_addr  cur_in6_daddr;
+	struct in6_addr  cur_in6_saddr;
+	/* For ranges */
+	struct in6_addr  min_in6_daddr;
+	struct in6_addr  max_in6_daddr;
+	struct in6_addr  min_in6_saddr;
+	struct in6_addr  max_in6_saddr;
+
+        /* If we're doing ranges, random or incremental, then this
+         * defines the min/max for those ranges.
+         */
+        __u32 saddr_min; /* inclusive, source IP address */
+        __u32 saddr_max; /* exclusive, source IP address */
+        __u32 daddr_min; /* inclusive, dest IP address */
+        __u32 daddr_max; /* exclusive, dest IP address */
+
+        __u16 udp_src_min; /* inclusive, source UDP port */
+        __u16 udp_src_max; /* exclusive, source UDP port */
+        __u16 udp_dst_min; /* inclusive, dest UDP port */
+        __u16 udp_dst_max; /* exclusive, dest UDP port */
+
+        __u32 src_mac_count; /* How many MACs to iterate through */
+        __u32 dst_mac_count; /* How many MACs to iterate through */
+        
+        unsigned char dst_mac[6];
+        unsigned char src_mac[6];
+        
+        __u32 cur_dst_mac_offset;
+        __u32 cur_src_mac_offset;
+        __u32 cur_saddr;
+        __u32 cur_daddr;
+        __u16 cur_udp_dst;
+        __u16 cur_udp_src;
+        __u32 cur_pkt_size;
+        
+        __u8 hh[14];
+        /* = { 
+           0x00, 0x80, 0xC8, 0x79, 0xB3, 0xCB, 
+           
+           We fill in SRC address later
+           0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+           0x08, 0x00
+           };
+        */
+        __u16 pad; /* pad out the hh struct to an even 16 bytes */
+
+        struct sk_buff* skb; /* skb we are to transmit next, mainly used for when we
+                              * are transmitting the same one multiple times
+                              */
+        struct net_device* odev; /* The out-going device.  Note that the device should
+                                  * have it's pg_info pointer pointing back to this
+                                  * device.  This will be set when the user specifies
+                                  * the out-going device name (not when the inject is
+                                  * started as it used to do.)
+                                  */
+	struct flow_state *flows;
+	unsigned cflows;         /* Concurrent flows (config) */
+	unsigned lflow;          /* Flow length  (config) */
+	unsigned nflows;         /* accumulated flows (stats) */
 };
 
 struct pktgen_hdr {
-	__u32 pgh_magic;
-	__u32 seq_num;
+        __u32 pgh_magic;
+        __u32 seq_num;
 	__u32 tv_sec;
 	__u32 tv_usec;
 };
 
-static int cpu_speed;
-static int debug;
-
-/* Module parameters, defaults. */
-static int count_d = 100000;
-static int ipg_d;
-static int clone_skb_d;
+struct pktgen_thread {
+        spinlock_t if_lock;
+        struct pktgen_dev *if_list;           /* All device here */
+        struct pktgen_thread* next;
+        char name[32];
+        char fname[128]; /* name of proc file */
+        struct proc_dir_entry *proc_ent;
+        char result[512];
+        u32 max_before_softirq; /* We'll call do_softirq to prevent starvation. */
+        
+	/* Field for thread to receive "posted" events terminate, stop ifs etc.*/
+
+        u32 control;
+	int pid;
+	int cpu;
 
+        wait_queue_head_t queue;
+};
 
-#define MAX_PKTGEN 8
-static struct pktgen_info pginfos[MAX_PKTGEN];
+#define REMOVE 1
+#define FIND   0
 
+/*  This code works around the fact that do_div cannot handle two 64-bit
+    numbers, and regular 64-bit division doesn't work on x86 kernels.
+    --Ben
+*/
 
-/** Convert to miliseconds */
-static inline __u64 tv_to_ms(const struct timeval* tv) {
-	__u64 ms = tv->tv_usec / 1000;
-	ms += (__u64)tv->tv_sec * (__u64)1000;
-	return ms;
-}
+#define PG_DIV 0
 
-static inline __u64 getCurMs(void) {
-	struct timeval tv;
-	do_gettimeofday(&tv);
-	return tv_to_ms(&tv);
+/* This was emailed to LMKL by: Chris Caputo <ccaputo@alt.net>
+ * Function copied/adapted/optimized from:
+ *
+ *  nemesis.sourceforge.net/browse/lib/static/intmath/ix86/intmath.c.html
+ *
+ * Copyright 1994, University of Cambridge Computer Laboratory
+ * All Rights Reserved.
+ *
+ */
+inline static s64 divremdi3(s64 x, s64 y, int type) 
+{
+        u64 a = (x < 0) ? -x : x;
+        u64 b = (y < 0) ? -y : y;
+        u64 res = 0, d = 1;
+
+        if (b > 0) {
+                while (b < a) {
+                        b <<= 1;
+                        d <<= 1;
+                }
+        }
+        
+        do {
+                if ( a >= b ) {
+                        a -= b;
+                        res += d;
+                }
+                b >>= 1;
+                d >>= 1;
+        }
+        while (d);
+
+        if (PG_DIV == type) {
+                return (((x ^ y) & (1ll<<63)) == 0) ? res : -(s64)res;
+        }
+        else {
+                return ((x & (1ll<<63)) == 0) ? a : -(s64)a;
+        }
 }
 
-#define PG_PROC_DIR "pktgen"
-static struct proc_dir_entry *proc_dir;
+/* End of hacks to deal with 64-bit math on x86 */
 
-static struct net_device *setup_inject(struct pktgen_info* info)
+/** Convert to miliseconds */
+static inline __u64 tv_to_ms(const struct timeval* tv) 
 {
-	struct net_device *odev;
-
-	odev = dev_get_by_name(info->outdev);
-	if (!odev) {
-		sprintf(info->result, "No such netdevice: \"%s\"", info->outdev);
-		goto out;
-	}
-
-	if (odev->type != ARPHRD_ETHER) {
-		sprintf(info->result, "Not ethernet device: \"%s\"", info->outdev);
-		goto out_put;
-	}
-
-	if (!netif_running(odev)) {
-		sprintf(info->result, "Device is down: \"%s\"", info->outdev);
-		goto out_put;
-	}
-
-	/* Default to the interface's mac if not explicitly set. */
-	if (!(info->flags & F_SET_SRCMAC)) {
-		memcpy(&(info->hh[6]), odev->dev_addr, 6);
-	}
-	else {
-		memcpy(&(info->hh[6]), info->src_mac, 6);
-	}
-
-	/* Set up Dest MAC */
-	memcpy(&(info->hh[0]), info->dst_mac, 6);
-	
-	info->saddr_min = 0;
-	info->saddr_max = 0;
-	if (strlen(info->src_min) == 0) {
-		struct in_device *in_dev;
-
-		rcu_read_lock();
-		in_dev = __in_dev_get(odev);
-		if (in_dev) {
-			if (in_dev->ifa_list) {
-				info->saddr_min = in_dev->ifa_list->ifa_address;
-				info->saddr_max = info->saddr_min;
-			}
-		}
-		rcu_read_unlock();
-	}
-	else {
-		info->saddr_min = in_aton(info->src_min);
-		info->saddr_max = in_aton(info->src_max);
-	}
+        __u64 ms = tv->tv_usec / 1000;
+        ms += (__u64)tv->tv_sec * (__u64)1000;
+        return ms;
+}
 
-	info->daddr_min = in_aton(info->dst_min);
-	info->daddr_max = in_aton(info->dst_max);
 
-	/* Initialize current values. */
-	info->cur_dst_mac_offset = 0;
-	info->cur_src_mac_offset = 0;
-	info->cur_saddr = info->saddr_min;
-	info->cur_daddr = info->daddr_min;
-	info->cur_udp_dst = info->udp_dst_min;
-	info->cur_udp_src = info->udp_src_min;
-	
-	return odev;
+/** Convert to micro-seconds */
+static inline __u64 tv_to_us(const struct timeval* tv) 
+{
+        __u64 us = tv->tv_usec;
+        us += (__u64)tv->tv_sec * (__u64)1000000;
+        return us;
+}
 
-out_put:
-	dev_put(odev);
-out:
-	return NULL;
+static inline __u64 pg_div(__u64 n, __u32 base) {
+        __u64 tmp = n;
+        do_div(tmp, base);
+        /* printk("pktgen: pg_div, n: %llu  base: %d  rv: %llu\n",
+                  n, base, tmp); */
+        return tmp;
 }
 
-static void nanospin(int ipg, struct pktgen_info* info)
+static inline __u64 pg_div64(__u64 n, __u64 base) 
 {
-	u32 idle_start, idle;
-
-	idle_start = cycles();
+        __u64 tmp = n;
+/*
+ * How do we know if the architectrure we are running on
+ * supports division with 64 bit base?
+ * 
+ */
+#if defined(__sparc_v9__) || defined(__powerpc64__) || defined(__alpha__) || defined(__x86_64__) || defined(__ia64__) 
 
-	for (;;) {
-		barrier();
-		idle = cycles() - idle_start;
-		if (idle * 1000 >= ipg * cpu_speed)
-			break;
-	}
-	info->idle_acc += idle;
+		do_div(tmp, base);
+#else
+		tmp = divremdi3(n, base, PG_DIV);
+#endif
+        return tmp;
 }
 
-static int calc_mhz(void)
+static inline u32 pktgen_random(void)
 {
-	struct timeval start, stop;
-	u32 start_s, elapsed;
-
-	do_gettimeofday(&start);
-	start_s = cycles();
-	do {
-		barrier();
-		elapsed = cycles() - start_s;
-		if (elapsed == 0)
-			return 0;
-	} while (elapsed < 1000 * 50000);
-	do_gettimeofday(&stop);
-	return elapsed/(stop.tv_usec-start.tv_usec+1000000*(stop.tv_sec-start.tv_sec));
+#if 0
+	__u32 n;
+	get_random_bytes(&n, 4);
+	return n;
+#else
+	return net_random();
+#endif
 }
 
-static void cycles_calibrate(void)
+static inline __u64 getCurMs(void) 
 {
-	int i;
+        struct timeval tv;
+        do_gettimeofday(&tv);
+        return tv_to_ms(&tv);
+}
 
-	for (i = 0; i < 3; i++) {
-		int res = calc_mhz();
-		if (res > cpu_speed)
-			cpu_speed = res;
-	}
+static inline __u64 getCurUs(void) 
+{
+        struct timeval tv;
+        do_gettimeofday(&tv);
+        return tv_to_us(&tv);
 }
 
+static inline __u64 tv_diff(const struct timeval* a, const struct timeval* b) 
+{
+        return tv_to_us(a) - tv_to_us(b);
+}
 
-/* Increment/randomize headers according to flags and current values
- * for IP src/dest, UDP src/dst port, MAC-Addr src/dst
- */
-static void mod_cur_headers(struct pktgen_info* info) {	
-	__u32 imn;
-	__u32 imx;
-	
-	/*  Deal with source MAC */
-	if (info->src_mac_count > 1) {
-		__u32 mc;
-		__u32 tmp;
-		if (info->flags & F_MACSRC_RND) {
-			mc = net_random() % (info->src_mac_count);
-		}
-		else {
-			mc = info->cur_src_mac_offset++;
-			if (info->cur_src_mac_offset > info->src_mac_count) {
-				info->cur_src_mac_offset = 0;
-			}
-		}
 
-		tmp = info->src_mac[5] + (mc & 0xFF);
-		info->hh[11] = tmp;
-		tmp = (info->src_mac[4] + ((mc >> 8) & 0xFF) + (tmp >> 8));
-		info->hh[10] = tmp;
-		tmp = (info->src_mac[3] + ((mc >> 16) & 0xFF) + (tmp >> 8));
-		info->hh[9] = tmp;
-		tmp = (info->src_mac[2] + ((mc >> 24) & 0xFF) + (tmp >> 8));
-		info->hh[8] = tmp;
-		tmp = (info->src_mac[1] + (tmp >> 8));
-		info->hh[7] = tmp;	
-	}
-
-	/*  Deal with Destination MAC */
-	if (info->dst_mac_count > 1) {
-		__u32 mc;
-		__u32 tmp;
-		if (info->flags & F_MACDST_RND) {
-			mc = net_random() % (info->dst_mac_count);
-		}
-		else {
-			mc = info->cur_dst_mac_offset++;
-			if (info->cur_dst_mac_offset > info->dst_mac_count) {
-				info->cur_dst_mac_offset = 0;
-			}
-		}
+/* old include end */
 
-		tmp = info->dst_mac[5] + (mc & 0xFF);
-		info->hh[5] = tmp;
-		tmp = (info->dst_mac[4] + ((mc >> 8) & 0xFF) + (tmp >> 8));
-		info->hh[4] = tmp;
-		tmp = (info->dst_mac[3] + ((mc >> 16) & 0xFF) + (tmp >> 8));
-		info->hh[3] = tmp;
-		tmp = (info->dst_mac[2] + ((mc >> 24) & 0xFF) + (tmp >> 8));
-		info->hh[2] = tmp;
-		tmp = (info->dst_mac[1] + (tmp >> 8));
-		info->hh[1] = tmp;	
-	}
-
-	if (info->udp_src_min < info->udp_src_max) {
-		if (info->flags & F_UDPSRC_RND) {
-			info->cur_udp_src = ((net_random() % (info->udp_src_max - info->udp_src_min))
-					     + info->udp_src_min);
-		}
-		else {
-		     info->cur_udp_src++;
-		     if (info->cur_udp_src >= info->udp_src_max) {
-			     info->cur_udp_src = info->udp_src_min;
-		     }
-		}
-	}
+static char version[] __initdata = VERSION;
 
-	if (info->udp_dst_min < info->udp_dst_max) {
-		if (info->flags & F_UDPDST_RND) {
-			info->cur_udp_dst = ((net_random() % (info->udp_dst_max - info->udp_dst_min))
-					     + info->udp_dst_min);
-		}
-		else {
-		     info->cur_udp_dst++;
-		     if (info->cur_udp_dst >= info->udp_dst_max) {
-			     info->cur_udp_dst = info->udp_dst_min;
-		     }
-		}
-	}
+static ssize_t proc_pgctrl_read(struct file* file, char __user * buf, size_t count, loff_t *ppos);
+static ssize_t proc_pgctrl_write(struct file* file, const char __user * buf, size_t count, loff_t *ppos);
+static int proc_if_read(char *buf , char **start, off_t offset, int len, int *eof, void *data);
+
+static int proc_thread_read(char *buf , char **start, off_t offset, int len, int *eof, void *data);
+static int proc_if_write(struct file *file, const char __user *user_buffer, unsigned long count, void *data);
+static int proc_thread_write(struct file *file, const char __user *user_buffer, unsigned long count, void *data);
+static int create_proc_dir(void);
+static int remove_proc_dir(void);
+
+static int pktgen_remove_device(struct pktgen_thread* t, struct pktgen_dev *i);
+static int pktgen_add_device(struct pktgen_thread* t, const char* ifname);
+static struct pktgen_thread* pktgen_find_thread(const char* name);
+static struct pktgen_dev *pktgen_find_dev(struct pktgen_thread* t, const char* ifname);
+static int pktgen_device_event(struct notifier_block *, unsigned long, void *);
+static void pktgen_run_all_threads(void);
+static void pktgen_stop_all_threads_ifs(void);
+static int pktgen_stop_device(struct pktgen_dev *pkt_dev);
+static void pktgen_stop(struct pktgen_thread* t);
+static void pktgen_clear_counters(struct pktgen_dev *pkt_dev);
+static struct pktgen_dev *pktgen_NN_threads(const char* dev_name, int remove);
+static unsigned int scan_ip6(const char *s,char ip[16]);
+static unsigned int fmt_ip6(char *s,const char ip[16]);
 
-	if ((imn = ntohl(info->saddr_min)) < (imx = ntohl(info->saddr_max))) {
-		__u32 t;
-		if (info->flags & F_IPSRC_RND) {
-			t = ((net_random() % (imx - imn)) + imn);
-		}
-		else {
-		     t = ntohl(info->cur_saddr);
-		     t++;
-		     if (t >= imx) {
-			     t = imn;
-		     }
-		}
-		info->cur_saddr = htonl(t);
-	}
+/* Module parameters, defaults. */
+static int pg_count_d = 1000; /* 1000 pkts by default */
+static int pg_delay_d = 0;
+static int pg_clone_skb_d = 0;
+static int debug = 0;
 
-	if ((imn = ntohl(info->daddr_min)) < (imx = ntohl(info->daddr_max))) {
-		__u32 t;
-		if (info->flags & F_IPDST_RND) {
-			t = ((net_random() % (imx - imn)) + imn);
-		}
-		else {
-		     t = ntohl(info->cur_daddr);
-		     t++;
-		     if (t >= imx) {
-			     t = imn;
-		     }
-		}
-		info->cur_daddr = htonl(t);
-	}
-}/* mod_cur_headers */
+static spinlock_t _thread_lock = SPIN_LOCK_UNLOCKED;
+static struct pktgen_thread *pktgen_threads = NULL;
 
+static char module_fname[128];
+static struct proc_dir_entry *module_proc_ent = NULL;
 
-static struct sk_buff *fill_packet(struct net_device *odev, struct pktgen_info* info)
-{
-	struct sk_buff *skb = NULL;
-	__u8 *eth;
-	struct udphdr *udph;
-	int datalen, iplen;
-	struct iphdr *iph;
-	struct pktgen_hdr *pgh = NULL;
-	
-	skb = alloc_skb(info->pkt_size + 64 + 16, GFP_ATOMIC);
-	if (!skb) {
-		sprintf(info->result, "No memory");
-		return NULL;
-	}
+static struct notifier_block pktgen_notifier_block = {
+	.notifier_call = pktgen_device_event,
+};
 
-	skb_reserve(skb, 16);
+static struct file_operations pktgen_fops = {
+        .read     = proc_pgctrl_read,
+        .write    = proc_pgctrl_write,
+	/*  .ioctl    = pktgen_ioctl, later maybe */
+};
 
-	/*  Reserve for ethernet and IP header  */
-	eth = (__u8 *) skb_push(skb, 14);
-	iph = (struct iphdr *)skb_put(skb, sizeof(struct iphdr));
-	udph = (struct udphdr *)skb_put(skb, sizeof(struct udphdr));
+/*
+ * /proc handling functions 
+ *
+ */
 
-	/* Update any of the values, used when we're incrementing various
-	 * fields.
-	 */
-	mod_cur_headers(info);
+static struct proc_dir_entry *pg_proc_dir = NULL;
+static int proc_pgctrl_read_eof=0;
 
-	memcpy(eth, info->hh, 14);
-	
-	datalen = info->pkt_size - 14 - 20 - 8; /* Eth + IPh + UDPh */
-	if (datalen < sizeof(struct pktgen_hdr)) {
-		datalen = sizeof(struct pktgen_hdr);
+static ssize_t proc_pgctrl_read(struct file* file, char __user * buf,
+                                 size_t count, loff_t *ppos)
+{ 
+	char data[200];
+	int len = 0;
+
+	if(proc_pgctrl_read_eof) {
+		proc_pgctrl_read_eof=0;
+		len = 0;
+		goto out;
 	}
-	
-	udph->source = htons(info->cur_udp_src);
-	udph->dest = htons(info->cur_udp_dst);
-	udph->len = htons(datalen + 8); /* DATA + udphdr */
-	udph->check = 0;  /* No checksum */
 
-	iph->ihl = 5;
-	iph->version = 4;
-	iph->ttl = 3;
-	iph->tos = 0;
-	iph->protocol = IPPROTO_UDP; /* UDP */
-	iph->saddr = info->cur_saddr;
-	iph->daddr = info->cur_daddr;
-	iph->frag_off = 0;
-	iplen = 20 + 8 + datalen;
-	iph->tot_len = htons(iplen);
-	iph->check = 0;
-	iph->check = ip_fast_csum((void *) iph, iph->ihl);
-	skb->protocol = __constant_htons(ETH_P_IP);
-	skb->mac.raw = ((u8 *)iph) - 14;
-	skb->dev = odev;
-	skb->pkt_type = PACKET_HOST;
+	sprintf(data, "%s", VERSION); 
 
-	if (info->nfrags <= 0) {
-		pgh = (struct pktgen_hdr *)skb_put(skb, datalen);
-	} else {
-		int frags = info->nfrags;
-		int i;
+	len = strlen(data);
 
-		/* TODO: Verify this is OK...it sure is ugly. --Ben */
-		pgh = (struct pktgen_hdr*)(((char*)(udph)) + 8);
-		
-		if (frags > MAX_SKB_FRAGS)
-			frags = MAX_SKB_FRAGS;
-		if (datalen > frags*PAGE_SIZE) {
-			skb_put(skb, datalen-frags*PAGE_SIZE);
-			datalen = frags*PAGE_SIZE;
-		}
-
-		i = 0;
-		while (datalen > 0) {
-			struct page *page = alloc_pages(GFP_KERNEL, 0);
-			skb_shinfo(skb)->frags[i].page = page;
-			skb_shinfo(skb)->frags[i].page_offset = 0;
-			skb_shinfo(skb)->frags[i].size =
-				(datalen < PAGE_SIZE ? datalen : PAGE_SIZE);
-			datalen -= skb_shinfo(skb)->frags[i].size;
-			skb->len += skb_shinfo(skb)->frags[i].size;
-			skb->data_len += skb_shinfo(skb)->frags[i].size;
-			i++;
-			skb_shinfo(skb)->nr_frags = i;
-		}
-
-		while (i < frags) {
-			int rem;
-
-			if (i == 0)
-				break;
-
-			rem = skb_shinfo(skb)->frags[i - 1].size / 2;
-			if (rem == 0)
-				break;
-
-			skb_shinfo(skb)->frags[i - 1].size -= rem;
+	if(len > count) {
+		len =-EFAULT;
+		goto out;
+	}  	
 
-			skb_shinfo(skb)->frags[i] = skb_shinfo(skb)->frags[i - 1];
-			get_page(skb_shinfo(skb)->frags[i].page);
-			skb_shinfo(skb)->frags[i].page = skb_shinfo(skb)->frags[i - 1].page;
-			skb_shinfo(skb)->frags[i].page_offset += skb_shinfo(skb)->frags[i - 1].size;
-			skb_shinfo(skb)->frags[i].size = rem;
-			i++;
-			skb_shinfo(skb)->nr_frags = i;
-		}
-	}
+	if (copy_to_user(buf, data, len)) {
+		len =-EFAULT;
+		goto out;
+	}  
 
-	/* Stamp the time, and sequence number, convert them to network byte order */
-	if (pgh) {
-		struct timeval timestamp;
+	*ppos += len;
+	proc_pgctrl_read_eof=1; /* EOF next call */
 
-		pgh->pgh_magic = htonl(PKTGEN_MAGIC);
-		pgh->seq_num   = htonl(info->seq_num);
-		
-		do_gettimeofday(&timestamp);
-		pgh->tv_sec    = htonl(timestamp.tv_sec);
-		pgh->tv_usec   = htonl(timestamp.tv_usec);
-	}
-	
-	return skb;
+ out:
+	return len;
 }
 
-static void show_results(struct pktgen_info* info, int nr_frags)
+static ssize_t proc_pgctrl_write(struct file* file,const char __user * buf,
+				 size_t count, loff_t *ppos)
 {
-	__u64 total, bps, mbps, pps;
-	unsigned long idle;
-	int size = info->pkt_size + 4; /* incl 32bit ethernet CRC */
-	char *p = info->result;
+	char *data = NULL;
+	int err = 0;
 
-	total = (info->stopped_at.tv_sec - info->started_at.tv_sec) * 1000000ull
-		+ info->stopped_at.tv_usec - info->started_at.tv_usec;
-
-	BUG_ON(cpu_speed == 0);
-
-	idle = info->idle_acc;
-	do_div(idle, cpu_speed);
+        if (!capable(CAP_NET_ADMIN)){
+                err = -EPERM;
+		goto out;
+        }
 
-	p += sprintf(p, "OK: %llu(c%llu+d%lu) usec, %llu (%dbyte,%dfrags)\n",
-		     (unsigned long long) total,
-		     (unsigned long long) (total - idle), idle,
-		     (unsigned long long) info->sofar,
-		     size, nr_frags);
+	data = (void*)vmalloc ((unsigned int)count);
 
-	pps = info->sofar * USEC_PER_SEC;
-	
-	while ((total >> 32) != 0) {
-		pps >>= 1;
-		total >>= 1;
+	if(!data) {
+		err = -ENOMEM;
+		goto out;
 	}
-
-	do_div(pps, total);
-	
-	bps = pps * 8 * size;
-
-	mbps = bps;
-	do_div(mbps, 1000000);
-	p += sprintf(p, "  %llupps %lluMb/sec (%llubps) errors: %llu",
-		     (unsigned long long) pps,
-		     (unsigned long long) mbps,
-		     (unsigned long long) bps,
-		     (unsigned long long) info->errors);
+	if (copy_from_user(data, buf, count)) {
+		err =-EFAULT;
+		goto out_free;
+	}  
+	data[count-1] = 0; /* Make string */
+
+	if (!strcmp(data, "stop")) 
+		pktgen_stop_all_threads_ifs();
+
+        else if (!strcmp(data, "start")) 
+		pktgen_run_all_threads();
+
+	else 
+		printk("pktgen: Unknown command: %s\n", data);
+
+	err = count;
+
+ out_free:
+	vfree (data);
+ out:
+        return err;
 }
 
-static void inject(struct pktgen_info* info)
+static int proc_if_read(char *buf , char **start, off_t offset,
+                           int len, int *eof, void *data)
 {
-	struct net_device *odev;
-	struct sk_buff *skb = NULL;
-	__u64 lcount = 0;
-	int ret;
-	int last_ok = 1;	   /* Was last skb sent? 
-				    * Or a failed transmit of some sort?  This will keep
-				    * sequence numbers in order, for example.
-				    */
-	__u64 fp = 0;
-	__u32 fp_tmp = 0;
-
-	odev = setup_inject(info);
-	if (!odev)
-		return;
-
-	info->do_run_run = 1; /* Cranke yeself! */
-	info->idle_acc = 0;
-	info->sofar = 0;
-	info->errors = 0;
-	lcount = info->count;
-
-
-	/* Build our initial pkt and place it as a re-try pkt. */
-	skb = fill_packet(odev, info);
-	if (skb == NULL) goto out_reldev;
-
-	do_gettimeofday(&(info->started_at));
-
-	while(info->do_run_run) {
-
-		/* Set a time-stamp, so build a new pkt each time */
-
-		if (last_ok) {
-			if (++fp_tmp >= info->clone_skb ) {
-				kfree_skb(skb);
-				skb = fill_packet(odev, info);
-				if (skb == NULL) {
-					goto out_reldev;
-				}
-				fp++;
-				fp_tmp = 0; /* reset counter */
-			}
-		}
-
-		if (!(odev->features & NETIF_F_LLTX))
-			spin_lock_bh(&odev->xmit_lock);
-		if (!netif_queue_stopped(odev)) {
-
-			atomic_inc(&skb->users);
-
-		retry:
-			ret = odev->hard_start_xmit(skb, odev);
-			if (likely(ret == NETDEV_TX_OK)) {
-				last_ok = 1;	
-				info->sofar++;
-				info->seq_num++;
-			} else if (ret == NETDEV_TX_LOCKED 
-				   && (odev->features & NETIF_F_LLTX)) {
-				cpu_relax();
-				goto retry;
-			} else {
-				atomic_dec(&skb->users);
-				if (debug && net_ratelimit()) {
-				   printk(KERN_INFO "Hard xmit error\n");
-				}
-				info->errors++;
-				last_ok = 0;
-			}
-		}
-		else {
-			/* Re-try it next time */
-			last_ok = 0;
-		}
-		
-		if (!(odev->features & NETIF_F_LLTX))
-			spin_unlock_bh(&odev->xmit_lock);
-
-		if (info->ipg) {
-			/* Try not to busy-spin if we have larger sleep times.
-			 * TODO:  Investigate better ways to do this.
-			 */
-			if (info->ipg < 10000) { /* 10 usecs or less */
-				nanospin(info->ipg, info);
-			}
-			else if (info->ipg < 10000000) { /* 10ms or less */
-				udelay(info->ipg / 1000);
-			}
-			else {
-				mdelay(info->ipg / 1000000);
-			}
-		}
-		
-		if (signal_pending(current)) {
-			break;
-		}
-
-		/* If lcount is zero, then run forever */
-		if ((lcount != 0) && (--lcount == 0)) {
-			if (atomic_read(&skb->users) != 1) {
-				u32 idle_start, idle;
-
-				idle_start = cycles();
-				while (atomic_read(&skb->users) != 1) {
-					if (signal_pending(current)) {
-						break;
-					}
-					schedule();
-				}
-				idle = cycles() - idle_start;
-				info->idle_acc += idle;
-			}
-			break;
-		}
-
-		if (netif_queue_stopped(odev) || need_resched()) {
-			u32 idle_start, idle;
-
-			idle_start = cycles();
-			do {
-				if (signal_pending(current)) {
-					info->do_run_run = 0;
-					break;
-				}
-				if (!netif_running(odev)) {
-					info->do_run_run = 0;
-					break;
-				}
-				if (need_resched())
-					schedule();
-				else
-					do_softirq();
-			} while (netif_queue_stopped(odev));
-			idle = cycles() - idle_start;
-			info->idle_acc += idle;
-		}
-	}/* while we should be running */
-
-	do_gettimeofday(&(info->stopped_at));
-
-	show_results(info, skb_shinfo(skb)->nr_frags);
-
-	kfree_skb(skb);
+	char *p;
+	int i;
+        struct pktgen_dev *pkt_dev = (struct pktgen_dev*)(data);
+        __u64 sa;
+        __u64 stopped;
+        __u64 now = getCurUs();
+        
+	p = buf;
+	p += sprintf(p, "Params: count %llu  min_pkt_size: %u  max_pkt_size: %u\n",
+		     (unsigned long long) pkt_dev->count,
+		     pkt_dev->min_pkt_size, pkt_dev->max_pkt_size);
+
+	p += sprintf(p, "     frags: %d  delay: %u  clone_skb: %d  ifname: %s\n",
+                     pkt_dev->nfrags, 1000*pkt_dev->delay_us+pkt_dev->delay_ns, pkt_dev->clone_skb, pkt_dev->ifname);
+
+	p += sprintf(p, "     flows: %u flowlen: %u\n", pkt_dev->cflows, pkt_dev->lflow);
+
+
+	if(pkt_dev->flags & F_IPV6) {
+		char b1[128], b2[128], b3[128];
+		fmt_ip6(b1,  pkt_dev->in6_saddr.s6_addr);
+		fmt_ip6(b2,  pkt_dev->min_in6_saddr.s6_addr);
+		fmt_ip6(b3,  pkt_dev->max_in6_saddr.s6_addr);
+		p += sprintf(p, "     saddr: %s  min_saddr: %s  max_saddr: %s\n", b1, b2, b3);
+
+		fmt_ip6(b1,  pkt_dev->in6_daddr.s6_addr);
+		fmt_ip6(b2,  pkt_dev->min_in6_daddr.s6_addr);
+		fmt_ip6(b3,  pkt_dev->max_in6_daddr.s6_addr);
+		p += sprintf(p, "     daddr: %s  min_daddr: %s  max_daddr: %s\n", b1, b2, b3);
+
+	} 
+	else 
+		p += sprintf(p, "     dst_min: %s  dst_max: %s\n     src_min: %s  src_max: %s\n",
+                     pkt_dev->dst_min, pkt_dev->dst_max, pkt_dev->src_min, pkt_dev->src_max);
+
+        p += sprintf(p, "     src_mac: ");
+
+	if ((pkt_dev->src_mac[0] == 0) && 
+	    (pkt_dev->src_mac[1] == 0) && 
+	    (pkt_dev->src_mac[2] == 0) && 
+	    (pkt_dev->src_mac[3] == 0) && 
+	    (pkt_dev->src_mac[4] == 0) && 
+	    (pkt_dev->src_mac[5] == 0)) 
+
+		for (i = 0; i < 6; i++) 
+			p += sprintf(p, "%02X%s", pkt_dev->odev->dev_addr[i], i == 5 ? "  " : ":");
+
+	else 
+		for (i = 0; i < 6; i++) 
+			p += sprintf(p, "%02X%s", pkt_dev->src_mac[i], i == 5 ? "  " : ":");
+
+        p += sprintf(p, "dst_mac: ");
+	for (i = 0; i < 6; i++) 
+		p += sprintf(p, "%02X%s", pkt_dev->dst_mac[i], i == 5 ? "\n" : ":");
+
+        p += sprintf(p, "     udp_src_min: %d  udp_src_max: %d  udp_dst_min: %d  udp_dst_max: %d\n",
+                     pkt_dev->udp_src_min, pkt_dev->udp_src_max, pkt_dev->udp_dst_min,
+                     pkt_dev->udp_dst_max);
+
+        p += sprintf(p, "     src_mac_count: %d  dst_mac_count: %d \n     Flags: ",
+                     pkt_dev->src_mac_count, pkt_dev->dst_mac_count);
+
+
+        if (pkt_dev->flags &  F_IPV6) 
+                p += sprintf(p, "IPV6  ");
+
+        if (pkt_dev->flags &  F_IPSRC_RND) 
+                p += sprintf(p, "IPSRC_RND  ");
+
+        if (pkt_dev->flags & F_IPDST_RND) 
+                p += sprintf(p, "IPDST_RND  ");
+        
+        if (pkt_dev->flags & F_TXSIZE_RND) 
+                p += sprintf(p, "TXSIZE_RND  ");
+        
+        if (pkt_dev->flags & F_UDPSRC_RND) 
+                p += sprintf(p, "UDPSRC_RND  ");
+        
+        if (pkt_dev->flags & F_UDPDST_RND) 
+                p += sprintf(p, "UDPDST_RND  ");
+        
+        if (pkt_dev->flags & F_MACSRC_RND) 
+                p += sprintf(p, "MACSRC_RND  ");
+        
+        if (pkt_dev->flags & F_MACDST_RND) 
+                p += sprintf(p, "MACDST_RND  ");
+
+        
+        p += sprintf(p, "\n");
+        
+        sa = pkt_dev->started_at;
+        stopped = pkt_dev->stopped_at;
+        if (pkt_dev->running) 
+                stopped = now; /* not really stopped, more like last-running-at */
+        
+        p += sprintf(p, "Current:\n     pkts-sofar: %llu  errors: %llu\n     started: %lluus  stopped: %lluus idle: %lluus\n",
+		     (unsigned long long) pkt_dev->sofar,
+		     (unsigned long long) pkt_dev->errors,
+		     (unsigned long long) sa,
+		     (unsigned long long) stopped, 
+		     (unsigned long long) pkt_dev->idle_acc);
 
-out_reldev:
-	if (odev) {
-		dev_put(odev);
-		odev = NULL;
-	}
+        p += sprintf(p, "     seq_num: %d  cur_dst_mac_offset: %d  cur_src_mac_offset: %d\n",
+                     pkt_dev->seq_num, pkt_dev->cur_dst_mac_offset, pkt_dev->cur_src_mac_offset);
 
-	return;
+	if(pkt_dev->flags & F_IPV6) {
+		char b1[128], b2[128];
+		fmt_ip6(b1,  pkt_dev->cur_in6_daddr.s6_addr);
+		fmt_ip6(b2,  pkt_dev->cur_in6_saddr.s6_addr);
+		p += sprintf(p, "     cur_saddr: %s  cur_daddr: %s\n", b2, b1);
+	} 
+	else 
+		p += sprintf(p, "     cur_saddr: 0x%x  cur_daddr: 0x%x\n",
+                     pkt_dev->cur_saddr, pkt_dev->cur_daddr);
 
-}
 
-/* proc/net/pktgen/pg */
+	p += sprintf(p, "     cur_udp_dst: %d  cur_udp_src: %d\n",
+                     pkt_dev->cur_udp_dst, pkt_dev->cur_udp_src);
 
-static int proc_busy_read(char *buf , char **start, off_t offset,
-			     int len, int *eof, void *data)
-{
-	char *p;
-	int idx = (int)(long)(data);
-	struct pktgen_info* info = NULL;
-	
-	if ((idx < 0) || (idx >= MAX_PKTGEN)) {
-		printk("ERROR: idx: %i is out of range in proc_write\n", idx);
-		return -EINVAL;
-	}
-	info = &(pginfos[idx]);
-  
-	p = buf;
-	p += sprintf(p, "%d\n", info->busy);
-	*eof = 1;
-  
-	return p-buf;
-}
+	p += sprintf(p, "     flows: %u\n", pkt_dev->nflows);
 
-static int proc_read(char *buf , char **start, off_t offset,
-			int len, int *eof, void *data)
-{
-	char *p;
-	int i;
-	int idx = (int)(long)(data);
-	struct pktgen_info* info = NULL;
-	__u64 sa;
-	__u64 stopped;
-	__u64 now = getCurMs();
-	
-	if ((idx < 0) || (idx >= MAX_PKTGEN)) {
-		printk("ERROR: idx: %i is out of range in proc_write\n", idx);
-		return -EINVAL;
-	}
-	info = &(pginfos[idx]);
-  
-	p = buf;
-	p += sprintf(p, "%s\n", VERSION); /* Help with parsing compatibility */
-	p += sprintf(p, "Params: count %llu  pkt_size: %u  frags: %d  ipg: %u  clone_skb: %d odev \"%s\"\n",
-		     (unsigned long long) info->count,
-		     info->pkt_size, info->nfrags, info->ipg,
-		     info->clone_skb, info->outdev);
-	p += sprintf(p, "     dst_min: %s  dst_max: %s  src_min: %s  src_max: %s\n",
-		     info->dst_min, info->dst_max, info->src_min, info->src_max);
-	p += sprintf(p, "     src_mac: ");
-	for (i = 0; i < 6; i++) {
-		p += sprintf(p, "%02X%s", info->src_mac[i], i == 5 ? "  " : ":");
-	}
-	p += sprintf(p, "dst_mac: ");
-	for (i = 0; i < 6; i++) {
-		p += sprintf(p, "%02X%s", info->dst_mac[i], i == 5 ? "\n" : ":");
-	}
-	p += sprintf(p, "     udp_src_min: %d  udp_src_max: %d  udp_dst_min: %d  udp_dst_max: %d\n",
-		     info->udp_src_min, info->udp_src_max, info->udp_dst_min,
-		     info->udp_dst_max);
-	p += sprintf(p, "     src_mac_count: %d  dst_mac_count: %d\n     Flags: ",
-		     info->src_mac_count, info->dst_mac_count);
-	if (info->flags &  F_IPSRC_RND) {
-		p += sprintf(p, "IPSRC_RND  ");
-	}
-	if (info->flags & F_IPDST_RND) {
-		p += sprintf(p, "IPDST_RND  ");
-	}
-	if (info->flags & F_UDPSRC_RND) {
-		p += sprintf(p, "UDPSRC_RND  ");
-	}
-	if (info->flags & F_UDPDST_RND) {
-		p += sprintf(p, "UDPDST_RND  ");
-	}
-	if (info->flags & F_MACSRC_RND) {
-		p += sprintf(p, "MACSRC_RND  ");
-	}
-	if (info->flags & F_MACDST_RND) {
-		p += sprintf(p, "MACDST_RND  ");
-	}
-	p += sprintf(p, "\n");
-	
-	sa = tv_to_ms(&(info->started_at));
-	stopped = tv_to_ms(&(info->stopped_at));
-	if (info->do_run_run) {
-		stopped = now; /* not really stopped, more like last-running-at */
-	}
-	p += sprintf(p, "Current:\n     pkts-sofar: %llu  errors: %llu\n     started: %llums  stopped: %llums  now: %llums  idle: %lluns\n",
-		     (unsigned long long) info->sofar,
-		     (unsigned long long) info->errors,
-		     (unsigned long long) sa,
-		     (unsigned long long) stopped,
-		     (unsigned long long) now,
-		     (unsigned long long) info->idle_acc);
-	p += sprintf(p, "     seq_num: %d  cur_dst_mac_offset: %d  cur_src_mac_offset: %d\n",
-		     info->seq_num, info->cur_dst_mac_offset, info->cur_src_mac_offset);
-	p += sprintf(p, "     cur_saddr: 0x%x  cur_daddr: 0x%x  cur_udp_dst: %d  cur_udp_src: %d\n",
-		     info->cur_saddr, info->cur_daddr, info->cur_udp_dst, info->cur_udp_src);
-	
-	if (info->result[0])
-		p += sprintf(p, "Result: %s\n", info->result);
+	if (pkt_dev->result[0])
+		p += sprintf(p, "Result: %s\n", pkt_dev->result);
 	else
 		p += sprintf(p, "Result: Idle\n");
 	*eof = 1;
@@ -888,16 +733,16 @@
 	return p - buf;
 }
 
+
 static int count_trail_chars(const char __user *user_buffer, unsigned int maxlen)
 {
 	int i;
 
 	for (i = 0; i < maxlen; i++) {
-		char c;
-
-		if (get_user(c, &user_buffer[i]))
-			return -EFAULT;
-		switch (c) {
+                char c;
+                if (get_user(c, &user_buffer[i]))
+                        return -EFAULT;
+                switch (c) {
 		case '\"':
 		case '\n':
 		case '\r':
@@ -913,19 +758,17 @@
 	return i;
 }
 
-static unsigned long num_arg(const char __user *user_buffer, unsigned long maxlen,
+static unsigned long num_arg(const char __user *user_buffer, unsigned long maxlen, 
 			     unsigned long *num)
 {
 	int i = 0;
-
 	*num = 0;
   
 	for(; i < maxlen; i++) {
-		char c;
-
-		if (get_user(c, &user_buffer[i]))
-			return -EFAULT;
-		if ((c >= '0') && (c <= '9')) {
+                char c;
+                if (get_user(c, &user_buffer[i]))
+                        return -EFAULT;
+                if ((c >= '0') && (c <= '9')) {
 			*num *= 10;
 			*num += c -'0';
 		} else
@@ -939,316 +782,469 @@
 	int i = 0;
 
 	for(; i < maxlen; i++) {
-		char c;
-
-		if (get_user(c, &user_buffer[i]))
-			return -EFAULT;
-		switch (c) {
+                char c;
+                if (get_user(c, &user_buffer[i]))
+                        return -EFAULT;
+                switch (c) {
 		case '\"':
 		case '\n':
 		case '\r':
 		case '\t':
 		case ' ':
 			goto done_str;
+			break;
 		default:
 			break;
 		};
 	}
 done_str:
+
 	return i;
 }
 
-static int proc_write(struct file *file, const char __user *user_buffer,
-			 unsigned long count, void *data)
+static int proc_if_write(struct file *file, const char __user *user_buffer,
+                            unsigned long count, void *data)
 {
 	int i = 0, max, len;
 	char name[16], valstr[32];
 	unsigned long value = 0;
-	int idx = (int)(long)(data);
-	struct pktgen_info* info = NULL;
-	char* result = NULL;
-	int tmp;
-	
-	if ((idx < 0) || (idx >= MAX_PKTGEN)) {
-		printk("ERROR: idx: %i is out of range in proc_write\n", idx);
-		return -EINVAL;
-	}
-	info = &(pginfos[idx]);
-	result = &(info->result[0]);
-	
+        struct pktgen_dev *pkt_dev = (struct pktgen_dev*)(data);
+        char* pg_result = NULL;
+        int tmp = 0;
+	char buf[128];
+        
+        pg_result = &(pkt_dev->result[0]);
+        
 	if (count < 1) {
-		sprintf(result, "Wrong command format");
+		printk("pktgen: wrong command format\n");
 		return -EINVAL;
 	}
   
 	max = count - i;
 	tmp = count_trail_chars(&user_buffer[i], max);
-	if (tmp < 0)
-		return tmp;
-	i += tmp;
-  
+        if (tmp < 0) { 
+		printk("pktgen: illegal format\n");
+		return tmp; 
+	}
+        i += tmp;
+        
 	/* Read variable name */
 
 	len = strn_len(&user_buffer[i], sizeof(name) - 1);
-	if (len < 0)
-		return len;
+        if (len < 0) { return len; }
 	memset(name, 0, sizeof(name));
-	if (copy_from_user(name, &user_buffer[i], len))
+	if (copy_from_user(name, &user_buffer[i], len) )
 		return -EFAULT;
 	i += len;
   
 	max = count -i;
 	len = count_trail_chars(&user_buffer[i], max);
-	if (len < 0)
-		return len;
+        if (len < 0) 
+                return len;
+        
 	i += len;
 
-	if (debug)
-		printk("pg: %s,%lu\n", name, count);
+	if (debug) {
+                char tb[count + 1];
+                if (copy_from_user(tb, user_buffer, count))
+			return -EFAULT;
+                tb[count] = 0;
+		printk("pktgen: %s,%lu  buffer -:%s:-\n", name, count, tb);
+        }
 
-	if (!strcmp(name, "stop")) {
-		if (info->do_run_run) {
-			strcpy(result, "Stopping");
-		}
-		else {
-			strcpy(result, "Already stopped...\n");
-		}
-		info->do_run_run = 0;
+	if (!strcmp(name, "min_pkt_size")) {
+		len = num_arg(&user_buffer[i], 10, &value);
+                if (len < 0) { return len; }
+		i += len;
+		if (value < 14+20+8)
+			value = 14+20+8;
+                if (value != pkt_dev->min_pkt_size) {
+                        pkt_dev->min_pkt_size = value;
+                        pkt_dev->cur_pkt_size = value;
+                }
+		sprintf(pg_result, "OK: min_pkt_size=%u", pkt_dev->min_pkt_size);
 		return count;
 	}
 
+        if (!strcmp(name, "max_pkt_size")) {
+		len = num_arg(&user_buffer[i], 10, &value);
+                if (len < 0) { return len; }
+		i += len;
+		if (value < 14+20+8)
+			value = 14+20+8;
+                if (value != pkt_dev->max_pkt_size) {
+                        pkt_dev->max_pkt_size = value;
+                        pkt_dev->cur_pkt_size = value;
+                }
+		sprintf(pg_result, "OK: max_pkt_size=%u", pkt_dev->max_pkt_size);
+		return count;
+	}
+
+        /* Shortcut for min = max */
+
 	if (!strcmp(name, "pkt_size")) {
 		len = num_arg(&user_buffer[i], 10, &value);
-		if (len < 0)
-			return len;
+                if (len < 0) { return len; }
 		i += len;
 		if (value < 14+20+8)
 			value = 14+20+8;
-		info->pkt_size = value;
-		sprintf(result, "OK: pkt_size=%u", info->pkt_size);
+                if (value != pkt_dev->min_pkt_size) {
+                        pkt_dev->min_pkt_size = value;
+                        pkt_dev->max_pkt_size = value;
+                        pkt_dev->cur_pkt_size = value;
+                }
+		sprintf(pg_result, "OK: pkt_size=%u", pkt_dev->min_pkt_size);
 		return count;
 	}
-	if (!strcmp(name, "frags")) {
+
+        if (!strcmp(name, "debug")) {
 		len = num_arg(&user_buffer[i], 10, &value);
-		if (len < 0)
-			return len;
+                if (len < 0) { return len; }
 		i += len;
-		info->nfrags = value;
-		sprintf(result, "OK: frags=%u", info->nfrags);
+                debug = value;
+		sprintf(pg_result, "OK: debug=%u", debug);
 		return count;
 	}
-	if (!strcmp(name, "ipg")) {
+
+        if (!strcmp(name, "frags")) {
 		len = num_arg(&user_buffer[i], 10, &value);
-		if (len < 0)
-			return len;
+                if (len < 0) { return len; }
+		i += len;
+		pkt_dev->nfrags = value;
+		sprintf(pg_result, "OK: frags=%u", pkt_dev->nfrags);
+		return count;
+	}
+	if (!strcmp(name, "delay")) {
+		len = num_arg(&user_buffer[i], 10, &value);
+                if (len < 0) { return len; }
 		i += len;
-		info->ipg = value;
-		sprintf(result, "OK: ipg=%u", info->ipg);
+		if (value == 0x7FFFFFFF) {
+			pkt_dev->delay_us = 0x7FFFFFFF;
+			pkt_dev->delay_ns = 0;
+		} else {
+			pkt_dev->delay_us = value / 1000;
+			pkt_dev->delay_ns = value % 1000;
+		}
+		sprintf(pg_result, "OK: delay=%u", 1000*pkt_dev->delay_us+pkt_dev->delay_ns);
 		return count;
 	}
  	if (!strcmp(name, "udp_src_min")) {
 		len = num_arg(&user_buffer[i], 10, &value);
-		if (len < 0)
-			return len;
+                if (len < 0) { return len; }
 		i += len;
-	 	info->udp_src_min = value;
-		sprintf(result, "OK: udp_src_min=%u", info->udp_src_min);
+                if (value != pkt_dev->udp_src_min) {
+                        pkt_dev->udp_src_min = value;
+                        pkt_dev->cur_udp_src = value;
+                }       
+		sprintf(pg_result, "OK: udp_src_min=%u", pkt_dev->udp_src_min);
 		return count;
 	}
  	if (!strcmp(name, "udp_dst_min")) {
 		len = num_arg(&user_buffer[i], 10, &value);
-		if (len < 0)
-			return len;
+                if (len < 0) { return len; }
 		i += len;
-	 	info->udp_dst_min = value;
-		sprintf(result, "OK: udp_dst_min=%u", info->udp_dst_min);
+                if (value != pkt_dev->udp_dst_min) {
+                        pkt_dev->udp_dst_min = value;
+                        pkt_dev->cur_udp_dst = value;
+                }
+		sprintf(pg_result, "OK: udp_dst_min=%u", pkt_dev->udp_dst_min);
 		return count;
 	}
  	if (!strcmp(name, "udp_src_max")) {
 		len = num_arg(&user_buffer[i], 10, &value);
-		if (len < 0)
-			return len;
+                if (len < 0) { return len; }
 		i += len;
-	 	info->udp_src_max = value;
-		sprintf(result, "OK: udp_src_max=%u", info->udp_src_max);
+                if (value != pkt_dev->udp_src_max) {
+                        pkt_dev->udp_src_max = value;
+                        pkt_dev->cur_udp_src = value;
+                }
+		sprintf(pg_result, "OK: udp_src_max=%u", pkt_dev->udp_src_max);
 		return count;
 	}
  	if (!strcmp(name, "udp_dst_max")) {
 		len = num_arg(&user_buffer[i], 10, &value);
-		if (len < 0)
-			return len;
+                if (len < 0) { return len; }
 		i += len;
-	 	info->udp_dst_max = value;
-		sprintf(result, "OK: udp_dst_max=%u", info->udp_dst_max);
+                if (value != pkt_dev->udp_dst_max) {
+                        pkt_dev->udp_dst_max = value;
+                        pkt_dev->cur_udp_dst = value;
+                }
+		sprintf(pg_result, "OK: udp_dst_max=%u", pkt_dev->udp_dst_max);
 		return count;
 	}
 	if (!strcmp(name, "clone_skb")) {
 		len = num_arg(&user_buffer[i], 10, &value);
-		if (len < 0)
-			return len;
+                if (len < 0) { return len; }
 		i += len;
-		info->clone_skb = value;
+                pkt_dev->clone_skb = value;
 	
-		sprintf(result, "OK: clone_skb=%d", info->clone_skb);
+		sprintf(pg_result, "OK: clone_skb=%d", pkt_dev->clone_skb);
 		return count;
 	}
 	if (!strcmp(name, "count")) {
 		len = num_arg(&user_buffer[i], 10, &value);
-		if (len < 0)
-			return len;
+                if (len < 0) { return len; }
 		i += len;
-		info->count = value;
-		sprintf(result, "OK: count=%llu", (unsigned long long) info->count);
+		pkt_dev->count = value;
+		sprintf(pg_result, "OK: count=%llu",
+			(unsigned long long) pkt_dev->count);
 		return count;
 	}
 	if (!strcmp(name, "src_mac_count")) {
 		len = num_arg(&user_buffer[i], 10, &value);
-		if (len < 0)
-			return len;
+                if (len < 0) { return len; }
 		i += len;
-		info->src_mac_count = value;
-		sprintf(result, "OK: src_mac_count=%d", info->src_mac_count);
+		if (pkt_dev->src_mac_count != value) {
+                        pkt_dev->src_mac_count = value;
+                        pkt_dev->cur_src_mac_offset = 0;
+                }
+		sprintf(pg_result, "OK: src_mac_count=%d", pkt_dev->src_mac_count);
 		return count;
 	}
 	if (!strcmp(name, "dst_mac_count")) {
 		len = num_arg(&user_buffer[i], 10, &value);
-		if (len < 0)
-			return len;
-		i += len;
-		info->dst_mac_count = value;
-		sprintf(result, "OK: dst_mac_count=%d", info->dst_mac_count);
-		return count;
-	}
-	if (!strcmp(name, "odev")) {
-		len = strn_len(&user_buffer[i], sizeof(info->outdev) - 1);
-		if (len < 0)
-			return len;
-		memset(info->outdev, 0, sizeof(info->outdev));
-		if (copy_from_user(info->outdev, &user_buffer[i], len))
-			return -EFAULT;
+                if (len < 0) { return len; }
 		i += len;
-		sprintf(result, "OK: odev=%s", info->outdev);
+		if (pkt_dev->dst_mac_count != value) {
+                        pkt_dev->dst_mac_count = value;
+                        pkt_dev->cur_dst_mac_offset = 0;
+                }
+		sprintf(pg_result, "OK: dst_mac_count=%d", pkt_dev->dst_mac_count);
 		return count;
 	}
 	if (!strcmp(name, "flag")) {
-		char f[32];
+                char f[32];
+                memset(f, 0, 32);
 		len = strn_len(&user_buffer[i], sizeof(f) - 1);
-		if (len < 0)
-			return len;
-		memset(f, 0, 32);
+                if (len < 0) { return len; }
 		if (copy_from_user(f, &user_buffer[i], len))
 			return -EFAULT;
 		i += len;
-		if (strcmp(f, "IPSRC_RND") == 0) {
-			info->flags |= F_IPSRC_RND;
-		}
-		else if (strcmp(f, "!IPSRC_RND") == 0) {
-			info->flags &= ~F_IPSRC_RND;
-		}
-		else if (strcmp(f, "IPDST_RND") == 0) {
-			info->flags |= F_IPDST_RND;
-		}
-		else if (strcmp(f, "!IPDST_RND") == 0) {
-			info->flags &= ~F_IPDST_RND;
-		}
-		else if (strcmp(f, "UDPSRC_RND") == 0) {
-			info->flags |= F_UDPSRC_RND;
-		}
-		else if (strcmp(f, "!UDPSRC_RND") == 0) {
-			info->flags &= ~F_UDPSRC_RND;
-		}
-		else if (strcmp(f, "UDPDST_RND") == 0) {
-			info->flags |= F_UDPDST_RND;
-		}
-		else if (strcmp(f, "!UDPDST_RND") == 0) {
-			info->flags &= ~F_UDPDST_RND;
-		}
-		else if (strcmp(f, "MACSRC_RND") == 0) {
-			info->flags |= F_MACSRC_RND;
-		}
-		else if (strcmp(f, "!MACSRC_RND") == 0) {
-			info->flags &= ~F_MACSRC_RND;
-		}
-		else if (strcmp(f, "MACDST_RND") == 0) {
-			info->flags |= F_MACDST_RND;
-		}
-		else if (strcmp(f, "!MACDST_RND") == 0) {
-			info->flags &= ~F_MACDST_RND;
-		}
-		else {
-			sprintf(result, "Flag -:%s:- unknown\nAvailable flags, (prepend ! to un-set flag):\n%s",
-				f,
-				"IPSRC_RND, IPDST_RND, UDPSRC_RND, UDPDST_RND, MACSRC_RND, MACDST_RND\n");
-			return count;
-		}
-		sprintf(result, "OK: flags=0x%x", info->flags);
+                if (strcmp(f, "IPSRC_RND") == 0) 
+                        pkt_dev->flags |= F_IPSRC_RND;
+                
+                else if (strcmp(f, "!IPSRC_RND") == 0) 
+                        pkt_dev->flags &= ~F_IPSRC_RND;
+                
+                else if (strcmp(f, "TXSIZE_RND") == 0) 
+                        pkt_dev->flags |= F_TXSIZE_RND;
+                
+                else if (strcmp(f, "!TXSIZE_RND") == 0) 
+                        pkt_dev->flags &= ~F_TXSIZE_RND;
+                
+                else if (strcmp(f, "IPDST_RND") == 0) 
+                        pkt_dev->flags |= F_IPDST_RND;
+                
+                else if (strcmp(f, "!IPDST_RND") == 0) 
+                        pkt_dev->flags &= ~F_IPDST_RND;
+                
+                else if (strcmp(f, "UDPSRC_RND") == 0) 
+                        pkt_dev->flags |= F_UDPSRC_RND;
+                
+                else if (strcmp(f, "!UDPSRC_RND") == 0) 
+                        pkt_dev->flags &= ~F_UDPSRC_RND;
+                
+                else if (strcmp(f, "UDPDST_RND") == 0) 
+                        pkt_dev->flags |= F_UDPDST_RND;
+                
+                else if (strcmp(f, "!UDPDST_RND") == 0) 
+                        pkt_dev->flags &= ~F_UDPDST_RND;
+                
+                else if (strcmp(f, "MACSRC_RND") == 0) 
+                        pkt_dev->flags |= F_MACSRC_RND;
+                
+                else if (strcmp(f, "!MACSRC_RND") == 0) 
+                        pkt_dev->flags &= ~F_MACSRC_RND;
+                
+                else if (strcmp(f, "MACDST_RND") == 0) 
+                        pkt_dev->flags |= F_MACDST_RND;
+                
+                else if (strcmp(f, "!MACDST_RND") == 0) 
+                        pkt_dev->flags &= ~F_MACDST_RND;
+                
+                else {
+                        sprintf(pg_result, "Flag -:%s:- unknown\nAvailable flags, (prepend ! to un-set flag):\n%s",
+                                f,
+                                "IPSRC_RND, IPDST_RND, TXSIZE_RND, UDPSRC_RND, UDPDST_RND, MACSRC_RND, MACDST_RND\n");
+                        return count;
+                }
+		sprintf(pg_result, "OK: flags=0x%x", pkt_dev->flags);
 		return count;
 	}
 	if (!strcmp(name, "dst_min") || !strcmp(name, "dst")) {
-		len = strn_len(&user_buffer[i], sizeof(info->dst_min) - 1);
-		if (len < 0)
-			return len;
-		memset(info->dst_min, 0, sizeof(info->dst_min));
-		if (copy_from_user(info->dst_min, &user_buffer[i], len))
+		len = strn_len(&user_buffer[i], sizeof(pkt_dev->dst_min) - 1);
+                if (len < 0) { return len; }
+
+                if (copy_from_user(buf, &user_buffer[i], len))
 			return -EFAULT;
-		if(debug)
-			printk("pg: dst_min set to: %s\n", info->dst_min);
-		i += len;
-		sprintf(result, "OK: dst_min=%s", info->dst_min);
+                buf[len] = 0;
+                if (strcmp(buf, pkt_dev->dst_min) != 0) {
+                        memset(pkt_dev->dst_min, 0, sizeof(pkt_dev->dst_min));
+                        strncpy(pkt_dev->dst_min, buf, len);
+                        pkt_dev->daddr_min = in_aton(pkt_dev->dst_min);
+                        pkt_dev->cur_daddr = pkt_dev->daddr_min;
+                }
+                if(debug)
+                        printk("pktgen: dst_min set to: %s\n", pkt_dev->dst_min);
+                i += len;
+		sprintf(pg_result, "OK: dst_min=%s", pkt_dev->dst_min);
 		return count;
 	}
 	if (!strcmp(name, "dst_max")) {
-		len = strn_len(&user_buffer[i], sizeof(info->dst_max) - 1);
-		if (len < 0)
-			return len;
-		memset(info->dst_max, 0, sizeof(info->dst_max));
-		if (copy_from_user(info->dst_max, &user_buffer[i], len))
+		len = strn_len(&user_buffer[i], sizeof(pkt_dev->dst_max) - 1);
+                if (len < 0) { return len; }
+
+                if (copy_from_user(buf, &user_buffer[i], len))
 			return -EFAULT;
+
+                buf[len] = 0;
+                if (strcmp(buf, pkt_dev->dst_max) != 0) {
+                        memset(pkt_dev->dst_max, 0, sizeof(pkt_dev->dst_max));
+                        strncpy(pkt_dev->dst_max, buf, len);
+                        pkt_dev->daddr_max = in_aton(pkt_dev->dst_max);
+                        pkt_dev->cur_daddr = pkt_dev->daddr_max;
+                }
 		if(debug)
-			printk("pg: dst_max set to: %s\n", info->dst_max);
+			printk("pktgen: dst_max set to: %s\n", pkt_dev->dst_max);
 		i += len;
-		sprintf(result, "OK: dst_max=%s", info->dst_max);
+		sprintf(pg_result, "OK: dst_max=%s", pkt_dev->dst_max);
+		return count;
+	}
+	if (!strcmp(name, "dst6")) {
+		len = strn_len(&user_buffer[i], sizeof(buf) - 1);
+                if (len < 0) return len; 
+
+		pkt_dev->flags |= F_IPV6;
+
+                if (copy_from_user(buf, &user_buffer[i], len))
+			return -EFAULT;
+                buf[len] = 0;
+
+		scan_ip6(buf, pkt_dev->in6_daddr.s6_addr);
+		fmt_ip6(buf,  pkt_dev->in6_daddr.s6_addr);
+
+		ipv6_addr_copy(&pkt_dev->cur_in6_daddr, &pkt_dev->in6_daddr);
+
+                if(debug) 
+			printk("pktgen: dst6 set to: %s\n", buf);
+
+                i += len;
+		sprintf(pg_result, "OK: dst6=%s", buf);
+		return count;
+	}
+	if (!strcmp(name, "dst6_min")) {
+		len = strn_len(&user_buffer[i], sizeof(buf) - 1);
+                if (len < 0) return len; 
+
+		pkt_dev->flags |= F_IPV6;
+
+                if (copy_from_user(buf, &user_buffer[i], len))
+			return -EFAULT;
+                buf[len] = 0;
+
+		scan_ip6(buf, pkt_dev->min_in6_daddr.s6_addr);
+		fmt_ip6(buf,  pkt_dev->min_in6_daddr.s6_addr);
+
+		ipv6_addr_copy(&pkt_dev->cur_in6_daddr, &pkt_dev->min_in6_daddr);
+                if(debug) 
+			printk("pktgen: dst6_min set to: %s\n", buf);
+
+                i += len;
+		sprintf(pg_result, "OK: dst6_min=%s", buf);
+		return count;
+	}
+	if (!strcmp(name, "dst6_max")) {
+		len = strn_len(&user_buffer[i], sizeof(buf) - 1);
+                if (len < 0) return len; 
+
+		pkt_dev->flags |= F_IPV6;
+
+                if (copy_from_user(buf, &user_buffer[i], len))
+			return -EFAULT;
+                buf[len] = 0;
+
+		scan_ip6(buf, pkt_dev->max_in6_daddr.s6_addr);
+		fmt_ip6(buf,  pkt_dev->max_in6_daddr.s6_addr);
+
+                if(debug) 
+			printk("pktgen: dst6_max set to: %s\n", buf);
+
+                i += len;
+		sprintf(pg_result, "OK: dst6_max=%s", buf);
+		return count;
+	}
+	if (!strcmp(name, "src6")) {
+		len = strn_len(&user_buffer[i], sizeof(buf) - 1);
+                if (len < 0) return len; 
+
+		pkt_dev->flags |= F_IPV6;
+
+                if (copy_from_user(buf, &user_buffer[i], len))
+			return -EFAULT;
+                buf[len] = 0;
+
+		scan_ip6(buf, pkt_dev->in6_saddr.s6_addr);
+		fmt_ip6(buf,  pkt_dev->in6_saddr.s6_addr);
+
+		ipv6_addr_copy(&pkt_dev->cur_in6_saddr, &pkt_dev->in6_saddr);
+
+                if(debug) 
+			printk("pktgen: src6 set to: %s\n", buf);
+		
+                i += len;
+		sprintf(pg_result, "OK: src6=%s", buf);
 		return count;
 	}
 	if (!strcmp(name, "src_min")) {
-		len = strn_len(&user_buffer[i], sizeof(info->src_min) - 1);
-		if (len < 0)
-			return len;
-		memset(info->src_min, 0, sizeof(info->src_min));
-		if (copy_from_user(info->src_min, &user_buffer[i], len))
+		len = strn_len(&user_buffer[i], sizeof(pkt_dev->src_min) - 1);
+                if (len < 0) { return len; }
+                if (copy_from_user(buf, &user_buffer[i], len))
 			return -EFAULT;
+                buf[len] = 0;
+                if (strcmp(buf, pkt_dev->src_min) != 0) {
+                        memset(pkt_dev->src_min, 0, sizeof(pkt_dev->src_min));
+                        strncpy(pkt_dev->src_min, buf, len);
+                        pkt_dev->saddr_min = in_aton(pkt_dev->src_min);
+                        pkt_dev->cur_saddr = pkt_dev->saddr_min;
+                }
 		if(debug)
-			printk("pg: src_min set to: %s\n", info->src_min);
+			printk("pktgen: src_min set to: %s\n", pkt_dev->src_min);
 		i += len;
-		sprintf(result, "OK: src_min=%s", info->src_min);
+		sprintf(pg_result, "OK: src_min=%s", pkt_dev->src_min);
 		return count;
 	}
 	if (!strcmp(name, "src_max")) {
-		len = strn_len(&user_buffer[i], sizeof(info->src_max) - 1);
-		if (len < 0)
-			return len;
-		memset(info->src_max, 0, sizeof(info->src_max));
-		if (copy_from_user(info->src_max, &user_buffer[i], len))
+		len = strn_len(&user_buffer[i], sizeof(pkt_dev->src_max) - 1);
+                if (len < 0) { return len; }
+                if (copy_from_user(buf, &user_buffer[i], len))
 			return -EFAULT;
+                buf[len] = 0;
+                if (strcmp(buf, pkt_dev->src_max) != 0) {
+                        memset(pkt_dev->src_max, 0, sizeof(pkt_dev->src_max));
+                        strncpy(pkt_dev->src_max, buf, len);
+                        pkt_dev->saddr_max = in_aton(pkt_dev->src_max);
+                        pkt_dev->cur_saddr = pkt_dev->saddr_max;
+                }
 		if(debug)
-			printk("pg: src_max set to: %s\n", info->src_max);
+			printk("pktgen: src_max set to: %s\n", pkt_dev->src_max);
 		i += len;
-		sprintf(result, "OK: src_max=%s", info->src_max);
+		sprintf(pg_result, "OK: src_max=%s", pkt_dev->src_max);
 		return count;
 	}
-	if (!strcmp(name, "dstmac")) {
+	if (!strcmp(name, "dst_mac")) {
 		char *v = valstr;
-		unsigned char *m = info->dst_mac;
-
+                unsigned char old_dmac[6];
+		unsigned char *m = pkt_dev->dst_mac;
+                memcpy(old_dmac, pkt_dev->dst_mac, 6);
+                
 		len = strn_len(&user_buffer[i], sizeof(valstr) - 1);
-		if (len < 0)
-			return len;
+                if (len < 0) { return len; }
 		memset(valstr, 0, sizeof(valstr));
-		if (copy_from_user(valstr, &user_buffer[i], len))
+		if( copy_from_user(valstr, &user_buffer[i], len))
 			return -EFAULT;
 		i += len;
 
-		for(*m = 0;*v && m < info->dst_mac + 6; v++) {
+		for(*m = 0;*v && m < pkt_dev->dst_mac + 6; v++) {
 			if (*v >= '0' && *v <= '9') {
 				*m *= 16;
 				*m += *v - '0';
@@ -1265,23 +1261,27 @@
 				m++;
 				*m = 0;
 			}
-		}	  
-		sprintf(result, "OK: dstmac");
+		}
+
+		/* Set up Dest MAC */
+                if (memcmp(old_dmac, pkt_dev->dst_mac, 6) != 0) 
+                        memcpy(&(pkt_dev->hh[0]), pkt_dev->dst_mac, 6);
+                
+		sprintf(pg_result, "OK: dstmac");
 		return count;
 	}
-	if (!strcmp(name, "srcmac")) {
+	if (!strcmp(name, "src_mac")) {
 		char *v = valstr;
-		unsigned char *m = info->src_mac;
+		unsigned char *m = pkt_dev->src_mac;
 
 		len = strn_len(&user_buffer[i], sizeof(valstr) - 1);
-		if (len < 0)
-			return len;
+                if (len < 0) { return len; }
 		memset(valstr, 0, sizeof(valstr));
-		if (copy_from_user(valstr, &user_buffer[i], len))
+		if( copy_from_user(valstr, &user_buffer[i], len)) 
 			return -EFAULT;
 		i += len;
 
-		for(*m = 0;*v && m < info->src_mac + 6; v++) {
+		for(*m = 0;*v && m < pkt_dev->src_mac + 6; v++) {
 			if (*v >= '0' && *v <= '9') {
 				*m *= 16;
 				*m += *v - '0';
@@ -1299,135 +1299,1838 @@
 				*m = 0;
 			}
 		}	  
-		sprintf(result, "OK: srcmac");
+
+                sprintf(pg_result, "OK: srcmac");
 		return count;
 	}
 
-	if (!strcmp(name, "inject") || !strcmp(name, "start")) {
-		if (info->busy) {
-			strcpy(info->result, "Already running...\n");
-		}
-		else {
-			info->busy = 1;
-			strcpy(info->result, "Starting");
-			inject(info);
-			info->busy = 0;
-		}
+        if (!strcmp(name, "clear_counters")) {
+                pktgen_clear_counters(pkt_dev);
+                sprintf(pg_result, "OK: Clearing counters.\n");
+                return count;
+        }
+
+	if (!strcmp(name, "flows")) {
+		len = num_arg(&user_buffer[i], 10, &value);
+                if (len < 0) { return len; }
+		i += len;
+		if (value > MAX_CFLOWS)
+			value = MAX_CFLOWS;
+
+		pkt_dev->cflows = value;
+		sprintf(pg_result, "OK: flows=%u", pkt_dev->cflows);
 		return count;
 	}
 
-	sprintf(info->result, "No such parameter \"%s\"", name);
+	if (!strcmp(name, "flowlen")) {
+		len = num_arg(&user_buffer[i], 10, &value);
+                if (len < 0) { return len; }
+		i += len;
+		pkt_dev->lflow = value;
+		sprintf(pg_result, "OK: flowlen=%u", pkt_dev->lflow);
+		return count;
+	}
+        
+	sprintf(pkt_dev->result, "No such parameter \"%s\"", name);
 	return -EINVAL;
 }
 
+static int proc_thread_read(char *buf , char **start, off_t offset,
+                               int len, int *eof, void *data)
+{
+	char *p;
+        struct pktgen_thread *t = (struct pktgen_thread*)(data);
+        struct pktgen_dev *pkt_dev = NULL;
+
+
+        if (!t) {
+                printk("pktgen: ERROR: could not find thread in proc_thread_read\n");
+                return -EINVAL;
+        }
+
+	p = buf;
+	p += sprintf(p, "Name: %s  max_before_softirq: %d\n",
+                     t->name, t->max_before_softirq);
+
+        p += sprintf(p, "Running: ");
+        
+        if_lock(t);
+        for(pkt_dev = t->if_list;pkt_dev; pkt_dev = pkt_dev->next) 
+		if(pkt_dev->running)
+			p += sprintf(p, "%s ", pkt_dev->ifname);
+        
+        p += sprintf(p, "\nStopped: ");
+
+        for(pkt_dev = t->if_list;pkt_dev; pkt_dev = pkt_dev->next) 
+		if(!pkt_dev->running)
+			p += sprintf(p, "%s ", pkt_dev->ifname);
+
+	if (t->result[0])
+		p += sprintf(p, "\nResult: %s\n", t->result);
+	else
+		p += sprintf(p, "\nResult: NA\n");
+
+	*eof = 1;
+
+        if_unlock(t);
+
+	return p - buf;
+}
+
+static int proc_thread_write(struct file *file, const char __user *user_buffer,
+                                unsigned long count, void *data)
+{
+	int i = 0, max, len, ret;
+	char name[40];
+        struct pktgen_thread *t;
+        char *pg_result;
+        unsigned long value = 0;
+        
+	if (count < 1) {
+		//	sprintf(pg_result, "Wrong command format");
+		return -EINVAL;
+	}
+  
+	max = count - i;
+        len = count_trail_chars(&user_buffer[i], max);
+        if (len < 0) 
+		return len; 
+     
+	i += len;
+  
+	/* Read variable name */
+
+	len = strn_len(&user_buffer[i], sizeof(name) - 1);
+        if (len < 0)  
+		return len; 
+	
+	memset(name, 0, sizeof(name));
+	if (copy_from_user(name, &user_buffer[i], len))
+		return -EFAULT;
+	i += len;
+  
+	max = count -i;
+	len = count_trail_chars(&user_buffer[i], max);
+        if (len < 0)  
+		return len; 
+	
+	i += len;
+
+	if (debug) 
+		printk("pktgen: t=%s, count=%lu\n", name, count);
+        
+	thread_lock();
+
+        t = (struct pktgen_thread*)(data);
+	if(!t) {
+		printk("pktgen: ERROR: No thread\n");
+		ret = -EINVAL;
+		goto out;
+	}
+
+	pg_result = &(t->result[0]);
+
+        if (!strcmp(name, "add_device")) {
+                char f[32];
+                memset(f, 0, 32);
+		len = strn_len(&user_buffer[i], sizeof(f) - 1);
+                if (len < 0) { 
+			ret = len; 
+			goto out;
+		}
+		if( copy_from_user(f, &user_buffer[i], len) )
+			return -EFAULT;
+		i += len;
+                pktgen_add_device(t, f);
+                ret = count;
+                sprintf(pg_result, "OK: add_device=%s", f);
+		goto out;
+	}
+
+        if (!strcmp(name, "rem_device_all")) {
+		t->control |= T_REMDEV;
+		current->state = TASK_INTERRUPTIBLE;
+		schedule_timeout(HZ/8);  /* Propagate thread->control  */
+		ret = count;
+                sprintf(pg_result, "OK: rem_device_all");
+		goto out;
+	}
+
+
+        if (!strcmp(name, "max_before_softirq")) {
+                len = num_arg(&user_buffer[i], 10, &value);
+                t->max_before_softirq = value;
+                ret = count;
+                sprintf(pg_result, "OK: max_before_softirq=%lu", value);
+		goto out;
+	}
+
+	ret = -EINVAL;
+ out:
+	thread_unlock();
+
+	return ret;
+}
 
 static int create_proc_dir(void)
 {
-	int     len;
-	/*  does proc_dir already exists */
-	len = strlen(PG_PROC_DIR);
-
-	for (proc_dir = proc_net->subdir; proc_dir;
-	     proc_dir=proc_dir->next) {
-		if ((proc_dir->namelen == len) &&
-		    (! memcmp(proc_dir->name, PG_PROC_DIR, len)))
+        int     len;
+        /*  does proc_dir already exists */
+        len = strlen(PG_PROC_DIR);
+
+        for (pg_proc_dir = proc_net->subdir; pg_proc_dir; pg_proc_dir=pg_proc_dir->next) {
+                if ((pg_proc_dir->namelen == len) &&
+		    (! memcmp(pg_proc_dir->name, PG_PROC_DIR, len))) 
+                        break;
+        }
+        
+        if (!pg_proc_dir) 
+                pg_proc_dir = create_proc_entry(PG_PROC_DIR, S_IFDIR, proc_net);
+        
+        if (!pg_proc_dir) 
+                return -ENODEV;
+        
+        return 0;
+}
+
+static int remove_proc_dir(void)
+{
+        remove_proc_entry(PG_PROC_DIR, proc_net);
+        return 0;
+}
+
+/* Think find or remove for NN */
+static struct pktgen_dev *__pktgen_NN_threads(const char* ifname, int remove) 
+{
+	struct pktgen_thread *t;
+	struct pktgen_dev *pkt_dev = NULL;
+
+        t = pktgen_threads;
+                
+	while (t) {
+		pkt_dev = pktgen_find_dev(t, ifname);
+		if (pkt_dev) {
+		                if(remove) { 
+				        if_lock(t);
+				        pktgen_remove_device(t, pkt_dev);
+				        if_unlock(t);
+				}
 			break;
+		}
+		t = t->next;
 	}
-	if (!proc_dir)
-		proc_dir = create_proc_entry(PG_PROC_DIR, S_IFDIR, proc_net);
-	if (!proc_dir) return -ENODEV;
-	return 1;
+        return pkt_dev;
 }
 
-static int remove_proc_dir(void)
+static struct pktgen_dev *pktgen_NN_threads(const char* ifname, int remove) 
 {
-	remove_proc_entry(PG_PROC_DIR, proc_net);
-	return 1;
+	struct pktgen_dev *pkt_dev = NULL;
+	thread_lock();
+	pkt_dev = __pktgen_NN_threads(ifname, remove);
+        thread_unlock();
+	return pkt_dev;
 }
 
-static int __init init(void)
+static int pktgen_device_event(struct notifier_block *unused, unsigned long event, void *ptr) 
 {
-	int i;
-	printk(version);
-	cycles_calibrate();
-	if (cpu_speed == 0) {
-		printk("pktgen: Error: your machine does not have working cycle counter.\n");
-		return -EINVAL;
+	struct net_device *dev = (struct net_device *)(ptr);
+
+	/* It is OK that we do not hold the group lock right now,
+	 * as we run under the RTNL lock.
+	 */
+
+	switch (event) {
+	case NETDEV_CHANGEADDR:
+	case NETDEV_GOING_DOWN:
+	case NETDEV_DOWN:
+	case NETDEV_UP:
+		/* Ignore for now */
+		break;
+		
+	case NETDEV_UNREGISTER:
+                pktgen_NN_threads(dev->name, REMOVE);
+		break;
+	};
+
+	return NOTIFY_DONE;
+}
+
+/* Associate pktgen_dev with a device. */
+
+static struct net_device* pktgen_setup_dev(struct pktgen_dev *pkt_dev) {
+	struct net_device *odev;
+
+	/* Clean old setups */
+
+	if (pkt_dev->odev) {
+		dev_put(pkt_dev->odev);
+                pkt_dev->odev = NULL;
+        }
+
+	odev = dev_get_by_name(pkt_dev->ifname);
+
+	if (!odev) {
+		printk("pktgen: no such netdevice: \"%s\"\n", pkt_dev->ifname);
+		goto out;
 	}
+	if (odev->type != ARPHRD_ETHER) {
+		printk("pktgen: not an ethernet device: \"%s\"\n", pkt_dev->ifname);
+		goto out_put;
+	}
+	if (!netif_running(odev)) {
+		printk("pktgen: device is down: \"%s\"\n", pkt_dev->ifname);
+		goto out_put;
+	}
+	pkt_dev->odev = odev;
+	
+        return pkt_dev->odev;
 
-	create_proc_dir();
+out_put:
+	dev_put(odev);
+out:
+ 	return NULL;
+
+}
+
+/* Read pkt_dev from the interface and set up internal pktgen_dev
+ * structure to have the right information to create/send packets
+ */
+static void pktgen_setup_inject(struct pktgen_dev *pkt_dev)
+{
+	/* Try once more, just in case it works now. */
+        if (!pkt_dev->odev) 
+                pktgen_setup_dev(pkt_dev);
+        
+        if (!pkt_dev->odev) {
+                printk("pktgen: ERROR: pkt_dev->odev == NULL in setup_inject.\n");
+                sprintf(pkt_dev->result, "ERROR: pkt_dev->odev == NULL in setup_inject.\n");
+                return;
+        }
+        
+        /* Default to the interface's mac if not explicitly set. */
+
+	if ((pkt_dev->src_mac[0] == 0) && 
+	    (pkt_dev->src_mac[1] == 0) && 
+	    (pkt_dev->src_mac[2] == 0) && 
+	    (pkt_dev->src_mac[3] == 0) && 
+	    (pkt_dev->src_mac[4] == 0) && 
+	    (pkt_dev->src_mac[5] == 0)) {
+
+	       memcpy(&(pkt_dev->hh[6]), pkt_dev->odev->dev_addr, 6);
+       }
+        /* Set up Dest MAC */
+        memcpy(&(pkt_dev->hh[0]), pkt_dev->dst_mac, 6);
+
+        /* Set up pkt size */
+        pkt_dev->cur_pkt_size = pkt_dev->min_pkt_size;
+	
+	if(pkt_dev->flags & F_IPV6) {
+		/*
+		 * Skip this automatic address setting until locks or functions 
+		 * gets exported
+		 */
+
+#ifdef NOTNOW
+		int i, set = 0, err=1;
+		struct inet6_dev *idev;
+
+		for(i=0; i< IN6_ADDR_HSIZE; i++)
+			if(pkt_dev->cur_in6_saddr.s6_addr[i]) {
+				set = 1;
+				break;
+			}
+
+		if(!set) {
+			
+			/*
+			 * Use linklevel address if unconfigured.
+			 *
+			 * use ipv6_get_lladdr if/when it's get exported
+			 */
+
+
+			read_lock(&addrconf_lock);
+			if ((idev = __in6_dev_get(pkt_dev->odev)) != NULL) {
+				struct inet6_ifaddr *ifp;
+
+				read_lock_bh(&idev->lock);
+				for (ifp=idev->addr_list; ifp; ifp=ifp->if_next) {
+					if (ifp->scope == IFA_LINK && !(ifp->flags&IFA_F_TENTATIVE)) {
+						ipv6_addr_copy(&pkt_dev->cur_in6_saddr, &ifp->addr);
+						err = 0;
+						break;
+					}
+				}
+				read_unlock_bh(&idev->lock);
+			}
+			read_unlock(&addrconf_lock);
+			if(err)	printk("pktgen: ERROR: IPv6 link address not availble.\n");
+		}
+#endif
+	} 
+	else {
+		pkt_dev->saddr_min = 0;
+		pkt_dev->saddr_max = 0;
+		if (strlen(pkt_dev->src_min) == 0) {
+			
+			struct in_device *in_dev; 
+
+			rcu_read_lock();
+			in_dev = __in_dev_get(pkt_dev->odev);
+			if (in_dev) {
+				if (in_dev->ifa_list) {
+					pkt_dev->saddr_min = in_dev->ifa_list->ifa_address;
+					pkt_dev->saddr_max = pkt_dev->saddr_min;
+				}
+				in_dev_put(in_dev);	
+			}
+			rcu_read_unlock();
+		}
+		else {
+			pkt_dev->saddr_min = in_aton(pkt_dev->src_min);
+			pkt_dev->saddr_max = in_aton(pkt_dev->src_max);
+		}
+
+		pkt_dev->daddr_min = in_aton(pkt_dev->dst_min);
+		pkt_dev->daddr_max = in_aton(pkt_dev->dst_max);
+	}
+        /* Initialize current values. */
+        pkt_dev->cur_dst_mac_offset = 0;
+        pkt_dev->cur_src_mac_offset = 0;
+        pkt_dev->cur_saddr = pkt_dev->saddr_min;
+        pkt_dev->cur_daddr = pkt_dev->daddr_min;
+        pkt_dev->cur_udp_dst = pkt_dev->udp_dst_min;
+        pkt_dev->cur_udp_src = pkt_dev->udp_src_min;
+	pkt_dev->nflows = 0;
+}
+
+static void spin(struct pktgen_dev *pkt_dev, __u64 spin_until_us)
+{
+	__u64 start;
+	__u64 now;
+
+	start = now = getCurUs();
+	printk(KERN_INFO "sleeping for %d\n", (int)(spin_until_us - now));
+	while (now < spin_until_us) {
+		/* TODO: optimise sleeping behavior */
+		if (spin_until_us - now > (1000000/HZ)+1) {
+			current->state = TASK_INTERRUPTIBLE;
+			schedule_timeout(1);
+		} else if (spin_until_us - now > 100) {
+			do_softirq();
+			if (!pkt_dev->running)
+				return;
+			if (need_resched())
+				schedule();
+		}
 
-	for (i = 0; i<MAX_PKTGEN; i++) {
-		memset(&(pginfos[i]), 0, sizeof(pginfos[i]));
-		pginfos[i].pkt_size = ETH_ZLEN;
-		pginfos[i].nfrags = 0;
-		pginfos[i].clone_skb = clone_skb_d;
-		pginfos[i].ipg = ipg_d;
-		pginfos[i].count = count_d;
-		pginfos[i].sofar = 0;
-		pginfos[i].hh[12] = 0x08; /* fill in protocol.  Rest is filled in later. */
-		pginfos[i].hh[13] = 0x00;
-		pginfos[i].udp_src_min = 9; /* sink NULL */
-		pginfos[i].udp_src_max = 9;
-		pginfos[i].udp_dst_min = 9;
-		pginfos[i].udp_dst_max = 9;
+		now = getCurUs();
+	}
+
+	pkt_dev->idle_acc += now - start;
+}
+
+
+/* Increment/randomize headers according to flags and current values
+ * for IP src/dest, UDP src/dst port, MAC-Addr src/dst
+ */
+static void mod_cur_headers(struct pktgen_dev *pkt_dev) {        
+        __u32 imn;
+        __u32 imx;
+	int  flow = 0;
+
+	if(pkt_dev->cflows)  {
+		flow = pktgen_random() % pkt_dev->cflows;
+		
+		if (pkt_dev->flows[flow].count > pkt_dev->lflow)
+			pkt_dev->flows[flow].count = 0;
+	}						
+
+
+	/*  Deal with source MAC */
+        if (pkt_dev->src_mac_count > 1) {
+                __u32 mc;
+                __u32 tmp;
+
+                if (pkt_dev->flags & F_MACSRC_RND) 
+                        mc = pktgen_random() % (pkt_dev->src_mac_count);
+                else {
+                        mc = pkt_dev->cur_src_mac_offset++;
+                        if (pkt_dev->cur_src_mac_offset > pkt_dev->src_mac_count) 
+                                pkt_dev->cur_src_mac_offset = 0;
+                }
+
+                tmp = pkt_dev->src_mac[5] + (mc & 0xFF);
+                pkt_dev->hh[11] = tmp;
+                tmp = (pkt_dev->src_mac[4] + ((mc >> 8) & 0xFF) + (tmp >> 8));
+                pkt_dev->hh[10] = tmp;
+                tmp = (pkt_dev->src_mac[3] + ((mc >> 16) & 0xFF) + (tmp >> 8));
+                pkt_dev->hh[9] = tmp;
+                tmp = (pkt_dev->src_mac[2] + ((mc >> 24) & 0xFF) + (tmp >> 8));
+                pkt_dev->hh[8] = tmp;
+                tmp = (pkt_dev->src_mac[1] + (tmp >> 8));
+                pkt_dev->hh[7] = tmp;        
+        }
+
+        /*  Deal with Destination MAC */
+        if (pkt_dev->dst_mac_count > 1) {
+                __u32 mc;
+                __u32 tmp;
+
+                if (pkt_dev->flags & F_MACDST_RND) 
+                        mc = pktgen_random() % (pkt_dev->dst_mac_count);
+
+                else {
+                        mc = pkt_dev->cur_dst_mac_offset++;
+                        if (pkt_dev->cur_dst_mac_offset > pkt_dev->dst_mac_count) {
+                                pkt_dev->cur_dst_mac_offset = 0;
+                        }
+                }
+
+                tmp = pkt_dev->dst_mac[5] + (mc & 0xFF);
+                pkt_dev->hh[5] = tmp;
+                tmp = (pkt_dev->dst_mac[4] + ((mc >> 8) & 0xFF) + (tmp >> 8));
+                pkt_dev->hh[4] = tmp;
+                tmp = (pkt_dev->dst_mac[3] + ((mc >> 16) & 0xFF) + (tmp >> 8));
+                pkt_dev->hh[3] = tmp;
+                tmp = (pkt_dev->dst_mac[2] + ((mc >> 24) & 0xFF) + (tmp >> 8));
+                pkt_dev->hh[2] = tmp;
+                tmp = (pkt_dev->dst_mac[1] + (tmp >> 8));
+                pkt_dev->hh[1] = tmp;        
+        }
+
+        if (pkt_dev->udp_src_min < pkt_dev->udp_src_max) {
+                if (pkt_dev->flags & F_UDPSRC_RND) 
+                        pkt_dev->cur_udp_src = ((pktgen_random() % (pkt_dev->udp_src_max - pkt_dev->udp_src_min)) + pkt_dev->udp_src_min);
+
+                else {
+			pkt_dev->cur_udp_src++;
+			if (pkt_dev->cur_udp_src >= pkt_dev->udp_src_max)
+				pkt_dev->cur_udp_src = pkt_dev->udp_src_min;
+                }
+        }
+
+        if (pkt_dev->udp_dst_min < pkt_dev->udp_dst_max) {
+                if (pkt_dev->flags & F_UDPDST_RND) {
+                        pkt_dev->cur_udp_dst = ((pktgen_random() % (pkt_dev->udp_dst_max - pkt_dev->udp_dst_min)) + pkt_dev->udp_dst_min);
+                }
+                else {
+			pkt_dev->cur_udp_dst++;
+			if (pkt_dev->cur_udp_dst >= pkt_dev->udp_dst_max) 
+				pkt_dev->cur_udp_dst = pkt_dev->udp_dst_min;
+                }
+        }
+
+	if (!(pkt_dev->flags & F_IPV6)) {
+
+		if ((imn = ntohl(pkt_dev->saddr_min)) < (imx = ntohl(pkt_dev->saddr_max))) {
+			__u32 t;
+			if (pkt_dev->flags & F_IPSRC_RND) 
+				t = ((pktgen_random() % (imx - imn)) + imn);
+			else {
+				t = ntohl(pkt_dev->cur_saddr);
+				t++;
+				if (t > imx) {
+					t = imn;
+				}
+			}
+			pkt_dev->cur_saddr = htonl(t);
+		}
 		
-		sprintf(pginfos[i].fname, "net/%s/pg%i", PG_PROC_DIR, i);
-		pginfos[i].proc_ent = create_proc_entry(pginfos[i].fname, 0600, NULL);
-		if (!pginfos[i].proc_ent) {
-			printk("pktgen: Error: cannot create net/%s/pg procfs entry.\n", PG_PROC_DIR);
-			goto cleanup_mem;
-		}
-		pginfos[i].proc_ent->read_proc = proc_read;
-		pginfos[i].proc_ent->write_proc = proc_write;
-		pginfos[i].proc_ent->data = (void*)(long)(i);
-		pginfos[i].proc_ent->owner = THIS_MODULE;
-
-		sprintf(pginfos[i].busy_fname, "net/%s/pg_busy%i",  PG_PROC_DIR, i);
-		pginfos[i].busy_proc_ent = create_proc_entry(pginfos[i].busy_fname, 0, NULL);
-		if (!pginfos[i].busy_proc_ent) {
-			printk("pktgen: Error: cannot create net/%s/pg_busy procfs entry.\n", PG_PROC_DIR);
-			goto cleanup_mem;
+		if (pkt_dev->cflows && pkt_dev->flows[flow].count != 0) {
+			pkt_dev->cur_daddr = pkt_dev->flows[flow].cur_daddr;
+		} else {
+
+			if ((imn = ntohl(pkt_dev->daddr_min)) < (imx = ntohl(pkt_dev->daddr_max))) {
+				__u32 t;
+				if (pkt_dev->flags & F_IPDST_RND) {
+
+					t = ((pktgen_random() % (imx - imn)) + imn);
+					t = htonl(t);
+
+					while( LOOPBACK(t) || MULTICAST(t) || BADCLASS(t) || ZERONET(t) ||  LOCAL_MCAST(t) ) {
+						t = ((pktgen_random() % (imx - imn)) + imn);
+						t = htonl(t);
+					}
+					pkt_dev->cur_daddr = t;
+				}
+				
+				else {
+					t = ntohl(pkt_dev->cur_daddr);
+					t++;
+					if (t > imx) {
+						t = imn;
+					}
+					pkt_dev->cur_daddr = htonl(t);
+				}
+			}
+			if(pkt_dev->cflows) {	
+				pkt_dev->flows[flow].cur_daddr = pkt_dev->cur_daddr;
+				pkt_dev->nflows++;
+			}
 		}
-		pginfos[i].busy_proc_ent->read_proc = proc_busy_read;
-		pginfos[i].busy_proc_ent->data = (void*)(long)(i);
 	}
-	return 0;
+	else /* IPV6 * */
+	{
+		if(pkt_dev->min_in6_daddr.s6_addr32[0] == 0 &&
+		   pkt_dev->min_in6_daddr.s6_addr32[1] == 0 &&
+		   pkt_dev->min_in6_daddr.s6_addr32[2] == 0 &&
+		   pkt_dev->min_in6_daddr.s6_addr32[3] == 0);
+		else {
+			int i;
+
+			/* Only random destinations yet */
+
+			for(i=0; i < 4; i++) {
+				pkt_dev->cur_in6_daddr.s6_addr32[i] =
+					((pktgen_random() |
+					  pkt_dev->min_in6_daddr.s6_addr32[i]) &
+					 pkt_dev->max_in6_daddr.s6_addr32[i]);
+			}
+ 		}
+	}
+
+        if (pkt_dev->min_pkt_size < pkt_dev->max_pkt_size) {
+                __u32 t;
+                if (pkt_dev->flags & F_TXSIZE_RND) {
+                        t = ((pktgen_random() % (pkt_dev->max_pkt_size - pkt_dev->min_pkt_size))
+                             + pkt_dev->min_pkt_size);
+                }
+                else {
+			t = pkt_dev->cur_pkt_size + 1;
+			if (t > pkt_dev->max_pkt_size) 
+				t = pkt_dev->min_pkt_size;
+                }
+                pkt_dev->cur_pkt_size = t;
+        }
+
+	pkt_dev->flows[flow].count++;
+}
+
+
+static struct sk_buff *fill_packet_ipv4(struct net_device *odev, 
+				   struct pktgen_dev *pkt_dev)
+{
+	struct sk_buff *skb = NULL;
+	__u8 *eth;
+	struct udphdr *udph;
+	int datalen, iplen;
+	struct iphdr *iph;
+        struct pktgen_hdr *pgh = NULL;
+        
+	skb = alloc_skb(pkt_dev->cur_pkt_size + 64 + 16, GFP_ATOMIC);
+	if (!skb) {
+		sprintf(pkt_dev->result, "No memory");
+		return NULL;
+	}
+
+	skb_reserve(skb, 16);
+
+	/*  Reserve for ethernet and IP header  */
+	eth = (__u8 *) skb_push(skb, 14);
+	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);
+
+	datalen = pkt_dev->cur_pkt_size - 14 - 20 - 8; /* Eth + IPh + UDPh */
+	if (datalen < sizeof(struct pktgen_hdr)) 
+		datalen = sizeof(struct pktgen_hdr);
+        
+	udph->source = htons(pkt_dev->cur_udp_src);
+	udph->dest = htons(pkt_dev->cur_udp_dst);
+	udph->len = htons(datalen + 8); /* DATA + udphdr */
+	udph->check = 0;  /* No checksum */
+
+	iph->ihl = 5;
+	iph->version = 4;
+	iph->ttl = 32;
+	iph->tos = 0;
+	iph->protocol = IPPROTO_UDP; /* UDP */
+	iph->saddr = pkt_dev->cur_saddr;
+	iph->daddr = pkt_dev->cur_daddr;
+	iph->frag_off = 0;
+	iplen = 20 + 8 + datalen;
+	iph->tot_len = htons(iplen);
+	iph->check = 0;
+	iph->check = ip_fast_csum((void *) iph, iph->ihl);
+	skb->protocol = __constant_htons(ETH_P_IP);
+	skb->mac.raw = ((u8 *)iph) - 14;
+	skb->dev = odev;
+	skb->pkt_type = PACKET_HOST;
+
+	if (pkt_dev->nfrags <= 0) 
+                pgh = (struct pktgen_hdr *)skb_put(skb, datalen);
+	else {
+		int frags = pkt_dev->nfrags;
+		int i;
+
+                pgh = (struct pktgen_hdr*)(((char*)(udph)) + 8);
+                
+		if (frags > MAX_SKB_FRAGS)
+			frags = MAX_SKB_FRAGS;
+		if (datalen > frags*PAGE_SIZE) {
+			skb_put(skb, datalen-frags*PAGE_SIZE);
+			datalen = frags*PAGE_SIZE;
+		}
+
+		i = 0;
+		while (datalen > 0) {
+			struct page *page = alloc_pages(GFP_KERNEL, 0);
+			skb_shinfo(skb)->frags[i].page = page;
+			skb_shinfo(skb)->frags[i].page_offset = 0;
+			skb_shinfo(skb)->frags[i].size =
+				(datalen < PAGE_SIZE ? datalen : PAGE_SIZE);
+			datalen -= skb_shinfo(skb)->frags[i].size;
+			skb->len += skb_shinfo(skb)->frags[i].size;
+			skb->data_len += skb_shinfo(skb)->frags[i].size;
+			i++;
+			skb_shinfo(skb)->nr_frags = i;
+		}
+
+		while (i < frags) {
+			int rem;
+
+			if (i == 0)
+				break;
+
+			rem = skb_shinfo(skb)->frags[i - 1].size / 2;
+			if (rem == 0)
+				break;
+
+			skb_shinfo(skb)->frags[i - 1].size -= rem;
+
+			skb_shinfo(skb)->frags[i] = skb_shinfo(skb)->frags[i - 1];
+			get_page(skb_shinfo(skb)->frags[i].page);
+			skb_shinfo(skb)->frags[i].page = skb_shinfo(skb)->frags[i - 1].page;
+			skb_shinfo(skb)->frags[i].page_offset += skb_shinfo(skb)->frags[i - 1].size;
+			skb_shinfo(skb)->frags[i].size = rem;
+			i++;
+			skb_shinfo(skb)->nr_frags = i;
+		}
+	}
+
+        /* Stamp the time, and sequence number, convert them to network byte order */
+
+        if (pgh) {
+              struct timeval timestamp;
+	      
+	      pgh->pgh_magic = htonl(PKTGEN_MAGIC);
+	      pgh->seq_num   = htonl(pkt_dev->seq_num);
+	      
+	      do_gettimeofday(&timestamp);
+	      pgh->tv_sec    = htonl(timestamp.tv_sec);
+	      pgh->tv_usec   = htonl(timestamp.tv_usec);
+        }
+        pkt_dev->seq_num++;
+        
+	return skb;
+}
+
+/*
+ * scan_ip6, fmt_ip taken from dietlibc-0.21 
+ * Author Felix von Leitner <felix-dietlibc@fefe.de>
+ *
+ * Slightly modified for kernel. 
+ * Should be candidate for net/ipv4/utils.c
+ * --ro
+ */
+
+static unsigned int scan_ip6(const char *s,char ip[16])
+{
+	unsigned int i;
+	unsigned int len=0;
+	unsigned long u;
+	char suffix[16];
+	unsigned int prefixlen=0;
+	unsigned int suffixlen=0;
+	__u32 tmp;
+
+	for (i=0; i<16; i++) ip[i]=0;
+
+	for (;;) {
+		if (*s == ':') {
+			len++;
+			if (s[1] == ':') {        /* Found "::", skip to part 2 */
+				s+=2;
+				len++;
+				break;
+			}
+			s++;
+		}
+		{
+			char *tmp;
+			u=simple_strtoul(s,&tmp,16);
+			i=tmp-s;
+		}
+
+		if (!i) return 0;
+		if (prefixlen==12 && s[i]=='.') {
+
+			/* the last 4 bytes may be written as IPv4 address */
+
+			tmp = in_aton(s);
+			memcpy((struct in_addr*)(ip+12), &tmp, sizeof(tmp));
+			return i+len;
+		}
+		ip[prefixlen++] = (u >> 8);
+		ip[prefixlen++] = (u & 255);
+		s += i; len += i;
+		if (prefixlen==16)
+			return len;
+	}
+
+/* part 2, after "::" */
+	for (;;) {
+		if (*s == ':') {
+			if (suffixlen==0)
+				break;
+			s++;
+			len++;
+		} else if (suffixlen!=0)
+			break;
+		{
+			char *tmp;
+			u=simple_strtol(s,&tmp,16);
+			i=tmp-s;
+		}
+		if (!i) {
+			if (*s) len--;
+			break;
+		}
+		if (suffixlen+prefixlen<=12 && s[i]=='.') {
+			tmp = in_aton(s);
+			memcpy((struct in_addr*)(suffix+suffixlen), &tmp, sizeof(tmp));
+			suffixlen+=4;
+			len+=strlen(s);
+			break;
+		}
+		suffix[suffixlen++] = (u >> 8);
+		suffix[suffixlen++] = (u & 255);
+		s += i; len += i;
+		if (prefixlen+suffixlen==16)
+			break;
+	}
+	for (i=0; i<suffixlen; i++)
+		ip[16-suffixlen+i] = suffix[i];
+	return len;
+}
+
+static char tohex(char hexdigit) {
+	return hexdigit>9?hexdigit+'a'-10:hexdigit+'0';
+}
+
+static int fmt_xlong(char* s,unsigned int i) {
+	char* bak=s;
+	*s=tohex((i>>12)&0xf); if (s!=bak || *s!='0') ++s;
+	*s=tohex((i>>8)&0xf); if (s!=bak || *s!='0') ++s;
+	*s=tohex((i>>4)&0xf); if (s!=bak || *s!='0') ++s;
+	*s=tohex(i&0xf);
+	return s-bak+1;
+}
+
+static unsigned int fmt_ip6(char *s,const char ip[16]) {
+	unsigned int len;
+	unsigned int i;
+	unsigned int temp;
+	unsigned int compressing;
+	int j;
+
+	len = 0; compressing = 0;
+	for (j=0; j<16; j+=2) {
+
+#ifdef V4MAPPEDPREFIX
+		if (j==12 && !memcmp(ip,V4mappedprefix,12)) {
+			inet_ntoa_r(*(struct in_addr*)(ip+12),s);
+			temp=strlen(s);
+			return len+temp;
+		}
+#endif
+		temp = ((unsigned long) (unsigned char) ip[j] << 8) +
+			(unsigned long) (unsigned char) ip[j+1];
+		if (temp == 0) {
+			if (!compressing) {
+				compressing=1;
+				if (j==0) {
+					*s++=':'; ++len;
+				}
+			}
+		} else {
+			if (compressing) {
+				compressing=0;
+				*s++=':'; ++len;
+			}
+			i = fmt_xlong(s,temp); len += i; s += i;
+			if (j<14) {
+				*s++ = ':';
+				++len;
+			}
+		}
+	}
+	if (compressing) {
+		*s++=':'; ++len;
+	}
+	*s=0;
+	return len;
+}
+
+static struct sk_buff *fill_packet_ipv6(struct net_device *odev, 
+				   struct pktgen_dev *pkt_dev)
+{
+	struct sk_buff *skb = NULL;
+	__u8 *eth;
+	struct udphdr *udph;
+	int datalen;
+	struct ipv6hdr *iph;
+        struct pktgen_hdr *pgh = NULL;
+        
+	skb = alloc_skb(pkt_dev->cur_pkt_size + 64 + 16, GFP_ATOMIC);
+	if (!skb) {
+		sprintf(pkt_dev->result, "No memory");
+		return NULL;
+	}
+
+	skb_reserve(skb, 16);
+
+	/*  Reserve for ethernet and IP header  */
+	eth = (__u8 *) skb_push(skb, 14);
+	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 */
+
+	if (datalen < sizeof(struct pktgen_hdr)) { 
+		datalen = sizeof(struct pktgen_hdr);
+		if (net_ratelimit())
+			printk(KERN_INFO "pktgen: increased datalen to %d\n", datalen);
+	}
+
+	udph->source = htons(pkt_dev->cur_udp_src);
+	udph->dest = htons(pkt_dev->cur_udp_dst);
+	udph->len = htons(datalen + sizeof(struct udphdr)); 
+	udph->check = 0;  /* No checksum */
+
+	 *(u32*)iph = __constant_htonl(0x60000000); /* Version + flow */
+
+	iph->hop_limit = 32;
+
+	iph->payload_len = htons(sizeof(struct udphdr) + datalen);
+	iph->nexthdr = IPPROTO_UDP;
+
+	ipv6_addr_copy(&iph->daddr, &pkt_dev->cur_in6_daddr);
+	ipv6_addr_copy(&iph->saddr, &pkt_dev->cur_in6_saddr);
+
+	skb->mac.raw = ((u8 *)iph) - 14;
+	skb->protocol = __constant_htons(ETH_P_IPV6);
+	skb->dev = odev;
+	skb->pkt_type = PACKET_HOST;
+
+	if (pkt_dev->nfrags <= 0) 
+                pgh = (struct pktgen_hdr *)skb_put(skb, datalen);
+	else {
+		int frags = pkt_dev->nfrags;
+		int i;
+
+                pgh = (struct pktgen_hdr*)(((char*)(udph)) + 8);
+                
+		if (frags > MAX_SKB_FRAGS)
+			frags = MAX_SKB_FRAGS;
+		if (datalen > frags*PAGE_SIZE) {
+			skb_put(skb, datalen-frags*PAGE_SIZE);
+			datalen = frags*PAGE_SIZE;
+		}
+
+		i = 0;
+		while (datalen > 0) {
+			struct page *page = alloc_pages(GFP_KERNEL, 0);
+			skb_shinfo(skb)->frags[i].page = page;
+			skb_shinfo(skb)->frags[i].page_offset = 0;
+			skb_shinfo(skb)->frags[i].size =
+				(datalen < PAGE_SIZE ? datalen : PAGE_SIZE);
+			datalen -= skb_shinfo(skb)->frags[i].size;
+			skb->len += skb_shinfo(skb)->frags[i].size;
+			skb->data_len += skb_shinfo(skb)->frags[i].size;
+			i++;
+			skb_shinfo(skb)->nr_frags = i;
+		}
+
+		while (i < frags) {
+			int rem;
+
+			if (i == 0)
+				break;
+
+			rem = skb_shinfo(skb)->frags[i - 1].size / 2;
+			if (rem == 0)
+				break;
+
+			skb_shinfo(skb)->frags[i - 1].size -= rem;
+
+			skb_shinfo(skb)->frags[i] = skb_shinfo(skb)->frags[i - 1];
+			get_page(skb_shinfo(skb)->frags[i].page);
+			skb_shinfo(skb)->frags[i].page = skb_shinfo(skb)->frags[i - 1].page;
+			skb_shinfo(skb)->frags[i].page_offset += skb_shinfo(skb)->frags[i - 1].size;
+			skb_shinfo(skb)->frags[i].size = rem;
+			i++;
+			skb_shinfo(skb)->nr_frags = i;
+		}
+	}
+
+        /* Stamp the time, and sequence number, convert them to network byte order */
+	/* should we update cloned packets too ? */
+        if (pgh) {
+              struct timeval timestamp;
+	      
+	      pgh->pgh_magic = htonl(PKTGEN_MAGIC);
+	      pgh->seq_num   = htonl(pkt_dev->seq_num);
+	      
+	      do_gettimeofday(&timestamp);
+	      pgh->tv_sec    = htonl(timestamp.tv_sec);
+	      pgh->tv_usec   = htonl(timestamp.tv_usec);
+        }
+        pkt_dev->seq_num++;
+        
+	return skb;
+}
+
+static inline struct sk_buff *fill_packet(struct net_device *odev, 
+				   struct pktgen_dev *pkt_dev)
+{
+	if(pkt_dev->flags & F_IPV6) 
+		return fill_packet_ipv6(odev, pkt_dev);
+	else
+		return fill_packet_ipv4(odev, pkt_dev);
+}
+
+static void pktgen_clear_counters(struct pktgen_dev *pkt_dev) 
+{
+        pkt_dev->seq_num = 1;
+        pkt_dev->idle_acc = 0;
+	pkt_dev->sofar = 0;
+        pkt_dev->tx_bytes = 0;
+        pkt_dev->errors = 0;
+}
+
+/* Set up structure for sending pkts, clear counters */
+
+static void pktgen_run(struct pktgen_thread *t)
+{
+        struct pktgen_dev *pkt_dev = NULL;
+	int started = 0;
+
+	PG_DEBUG(printk("pktgen: entering pktgen_run. %p\n", t));
+
+	if_lock(t);
+        for (pkt_dev = t->if_list; pkt_dev; pkt_dev = pkt_dev->next ) {
+
+		/*
+		 * setup odev and create initial packet.
+		 */
+		pktgen_setup_inject(pkt_dev);
+
+		if(pkt_dev->odev) { 
+			pktgen_clear_counters(pkt_dev);
+			pkt_dev->running = 1; /* Cranke yeself! */
+			pkt_dev->skb = NULL;
+			pkt_dev->started_at = getCurUs();
+			pkt_dev->next_tx_us = getCurUs(); /* Transmit immediately */
+			pkt_dev->next_tx_ns = 0;
+			
+			strcpy(pkt_dev->result, "Starting");
+			started++;
+		}
+		else 
+			strcpy(pkt_dev->result, "Error starting");
+	}
+	if_unlock(t);
+	if(started) t->control &= ~(T_STOP);
+}
+
+static void pktgen_stop_all_threads_ifs(void)
+{
+        struct pktgen_thread *t = pktgen_threads;
+
+	PG_DEBUG(printk("pktgen: entering pktgen_stop_all_threads.\n"));
+
+	thread_lock();
+	while(t) {
+		pktgen_stop(t);
+		t = t->next;
+	}
+       thread_unlock();
+}
+
+static int thread_is_running(struct pktgen_thread *t )
+{
+        struct pktgen_dev *next;
+        int res = 0;
+
+        for(next=t->if_list; next; next=next->next) { 
+		if(next->running) {
+			res = 1;
+			break;
+		}
+        }
+        return res;
+}
+
+static int pktgen_wait_thread_run(struct pktgen_thread *t )
+{
+        if_lock(t);
+
+        while(thread_is_running(t)) {
+
+                if_unlock(t);
+
+		msleep_interruptible(100); 
+
+                if (signal_pending(current)) 
+                        goto signal;
+                if_lock(t);
+        }
+        if_unlock(t);
+        return 1;
+ signal:
+        return 0;
+}
+
+static int pktgen_wait_all_threads_run(void)
+{
+	struct pktgen_thread *t = pktgen_threads;
+	int sig = 1;
 	
-cleanup_mem:
-	for (i = 0; i<MAX_PKTGEN; i++) {
-		if (strlen(pginfos[i].fname)) {
-			remove_proc_entry(pginfos[i].fname, NULL);
+	while (t) {
+		sig = pktgen_wait_thread_run(t);
+		if( sig == 0 ) break;
+		thread_lock();
+		t=t->next;
+		thread_unlock();
+	}
+	if(sig == 0) {
+		thread_lock();
+		while (t) {
+			t->control |= (T_STOP);
+			t=t->next;
 		}
-		if (strlen(pginfos[i].busy_fname)) {
-			remove_proc_entry(pginfos[i].busy_fname, NULL);
+		thread_unlock();
+	}
+	return sig;
+}
+
+static void pktgen_run_all_threads(void)
+{
+        struct pktgen_thread *t = pktgen_threads;
+
+	PG_DEBUG(printk("pktgen: entering pktgen_run_all_threads.\n"));
+
+	thread_lock();
+
+	while(t) {
+		t->control |= (T_RUN);
+		t = t->next;
+	}
+	thread_unlock();
+
+	current->state = TASK_INTERRUPTIBLE;
+	schedule_timeout(HZ/8);  /* Propagate thread->control  */
+			
+	pktgen_wait_all_threads_run();
+}
+
+
+static void show_results(struct pktgen_dev *pkt_dev, int nr_frags)
+{
+       __u64 total_us, bps, mbps, pps, idle;
+       char *p = pkt_dev->result;
+
+       total_us = pkt_dev->stopped_at - pkt_dev->started_at;
+
+       idle = pkt_dev->idle_acc;
+
+       p += sprintf(p, "OK: %llu(c%llu+d%llu) usec, %llu (%dbyte,%dfrags)\n",
+                    (unsigned long long) total_us, 
+		    (unsigned long long)(total_us - idle), 
+		    (unsigned long long) idle,
+                    (unsigned long long) pkt_dev->sofar, 
+		    pkt_dev->cur_pkt_size, nr_frags);
+
+       pps = pkt_dev->sofar * USEC_PER_SEC;
+
+       while ((total_us >> 32) != 0) {
+               pps >>= 1;
+               total_us >>= 1;
+       }
+
+       do_div(pps, total_us);
+       
+       bps = pps * 8 * pkt_dev->cur_pkt_size;
+
+       mbps = bps;
+       do_div(mbps, 1000000);
+       p += sprintf(p, "  %llupps %lluMb/sec (%llubps) errors: %llu",
+                    (unsigned long long) pps, 
+		    (unsigned long long) mbps, 
+		    (unsigned long long) bps, 
+		    (unsigned long long) pkt_dev->errors);
+}
+ 
+
+/* Set stopped-at timer, remove from running list, do counters & statistics */
+
+static int pktgen_stop_device(struct pktgen_dev *pkt_dev) 
+{
+	
+        if (!pkt_dev->running) {
+                printk("pktgen: interface: %s is already stopped\n", pkt_dev->ifname);
+                return -EINVAL;
+        }
+
+        pkt_dev->stopped_at = getCurUs();
+        pkt_dev->running = 0;
+
+	show_results(pkt_dev, skb_shinfo(pkt_dev->skb)->nr_frags);
+
+	if (pkt_dev->skb) 
+		kfree_skb(pkt_dev->skb);
+
+	pkt_dev->skb = NULL;
+	
+        return 0;
+}
+
+static struct pktgen_dev *next_to_run(struct pktgen_thread *t )
+{
+	struct pktgen_dev *next, *best = NULL;
+        
+	if_lock(t);
+
+	for(next=t->if_list; next ; next=next->next) {
+		if(!next->running) continue;
+		if(best == NULL) best=next;
+		else if ( next->next_tx_us < best->next_tx_us) 
+			best =  next;
+	}
+	if_unlock(t);
+        return best;
+}
+
+static void pktgen_stop(struct pktgen_thread *t) {
+        struct pktgen_dev *next = NULL;
+
+	PG_DEBUG(printk("pktgen: entering pktgen_stop.\n"));
+
+        if_lock(t);
+
+        for(next=t->if_list; next; next=next->next)
+                pktgen_stop_device(next);
+
+        if_unlock(t);
+}
+
+static void pktgen_rem_all_ifs(struct pktgen_thread *t) 
+{
+        struct pktgen_dev *cur, *next = NULL;
+        
+        /* Remove all devices, free mem */
+ 
+        if_lock(t);
+
+        for(cur=t->if_list; cur; cur=next) { 
+		next = cur->next;
+		pktgen_remove_device(t, cur);
+	}
+
+        if_unlock(t);
+}
+
+static void pktgen_rem_thread(struct pktgen_thread *t) 
+{
+        /* Remove from the thread list */
+
+	struct pktgen_thread *tmp = pktgen_threads;
+
+        if (strlen(t->fname))
+                remove_proc_entry(t->fname, NULL);
+
+       thread_lock();
+
+	if (tmp == t)
+		pktgen_threads = tmp->next;
+	else {
+		while (tmp) {
+			if (tmp->next == t) {
+				tmp->next = t->next;
+				t->next = NULL;
+				break;
+			}
+			tmp = tmp->next;
 		}
 	}
-	return -ENOMEM;
+        thread_unlock();
 }
 
+__inline__ void pktgen_xmit(struct pktgen_dev *pkt_dev)
+{
+	struct net_device *odev = NULL;
+	__u64 idle_start = 0;
+	int ret;
+
+	odev = pkt_dev->odev;
+	
+	if (pkt_dev->delay_us || pkt_dev->delay_ns) {
+		u64 now;
+
+		now = getCurUs();
+		if (now < pkt_dev->next_tx_us)
+			spin(pkt_dev, pkt_dev->next_tx_us);
 
-static void __exit cleanup(void)
+		/* This is max DELAY, this has special meaning of
+		 * "never transmit"
+		 */
+		if (pkt_dev->delay_us == 0x7FFFFFFF) {
+			pkt_dev->next_tx_us = getCurUs() + pkt_dev->delay_us;
+			pkt_dev->next_tx_ns = pkt_dev->delay_ns;
+			goto out;
+		}
+	}
+	
+	if (netif_queue_stopped(odev) || need_resched()) {
+		idle_start = getCurUs();
+		
+		if (!netif_running(odev)) {
+			pktgen_stop_device(pkt_dev);
+			goto out;
+		}
+		if (need_resched()) 
+			schedule();
+		
+		pkt_dev->idle_acc += getCurUs() - idle_start;
+		
+		if (netif_queue_stopped(odev)) {
+			pkt_dev->next_tx_us = getCurUs(); /* TODO */
+			pkt_dev->next_tx_ns = 0;
+			goto out; /* Try the next interface */
+		}
+	}
+	
+	if (pkt_dev->last_ok || !pkt_dev->skb) {
+		if ((++pkt_dev->clone_count >= pkt_dev->clone_skb ) || (!pkt_dev->skb)) {
+			/* build a new pkt */
+			if (pkt_dev->skb) 
+				kfree_skb(pkt_dev->skb);
+			
+			pkt_dev->skb = fill_packet(odev, pkt_dev);
+			if (pkt_dev->skb == NULL) {
+				printk("pktgen: ERROR: couldn't allocate skb in fill_packet.\n");
+				schedule();
+				pkt_dev->clone_count--; /* back out increment, OOM */
+				goto out;
+			}
+			pkt_dev->allocated_skbs++;
+			pkt_dev->clone_count = 0; /* reset counter */
+		}
+	}
+	
+	spin_lock_bh(&odev->xmit_lock);
+	if (!netif_queue_stopped(odev)) {
+		u64 now;
+
+		atomic_inc(&(pkt_dev->skb->users));
+retry_now:
+		ret = odev->hard_start_xmit(pkt_dev->skb, odev);
+		if (likely(ret == NETDEV_TX_OK)) {
+			pkt_dev->last_ok = 1;    
+			pkt_dev->sofar++;
+			pkt_dev->seq_num++;
+			pkt_dev->tx_bytes += pkt_dev->cur_pkt_size;
+			
+		} else if (ret == NETDEV_TX_LOCKED 
+			   && (odev->features & NETIF_F_LLTX)) {
+			cpu_relax();
+			goto retry_now;
+		} else {  /* Retry it next time */
+			
+			atomic_dec(&(pkt_dev->skb->users));
+			
+			if (debug && net_ratelimit())
+				printk(KERN_INFO "pktgen: Hard xmit error\n");
+			
+			pkt_dev->errors++;
+			pkt_dev->last_ok = 0;
+			pkt_dev->next_tx_us = getCurUs(); /* TODO */
+			pkt_dev->next_tx_ns = 0;
+		}
+
+		pkt_dev->next_tx_us += pkt_dev->delay_us;
+		pkt_dev->next_tx_ns += pkt_dev->delay_ns;
+		if (pkt_dev->next_tx_ns > 1000) {
+			pkt_dev->next_tx_us++;
+			pkt_dev->next_tx_ns -= 1000;
+		}
+
+		now = getCurUs();
+		if (now > pkt_dev->next_tx_us) {
+			/* TODO: this code is slightly wonky.  */
+			pkt_dev->errors++;
+			pkt_dev->next_tx_us = now - pkt_dev->delay_us;
+			pkt_dev->next_tx_ns = 0;
+		}
+	} 
+
+	else {  /* Retry it next time */
+                pkt_dev->last_ok = 0;
+                pkt_dev->next_tx_us = getCurUs(); /* TODO */
+		pkt_dev->next_tx_ns = 0;
+        }
+
+	spin_unlock_bh(&odev->xmit_lock);
+	
+	/* If pkt_dev->count is zero, then run forever */
+	if ((pkt_dev->count != 0) && (pkt_dev->sofar >= pkt_dev->count)) {
+		if (atomic_read(&(pkt_dev->skb->users)) != 1) {
+			idle_start = getCurUs();
+			while (atomic_read(&(pkt_dev->skb->users)) != 1) {
+				if (signal_pending(current)) {
+					break;
+				}
+				schedule();
+			}
+			pkt_dev->idle_acc += getCurUs() - idle_start;
+		}
+                
+		/* Done with this */
+		pktgen_stop_device(pkt_dev);
+	} 
+ out:;
+ }
+
+/* 
+ * Main loop of the thread goes here
+ */
+
+static void pktgen_thread_worker(struct pktgen_thread *t) 
 {
-	int i;
-	for (i = 0; i<MAX_PKTGEN; i++) {
-		if (strlen(pginfos[i].fname)) {
-			remove_proc_entry(pginfos[i].fname, NULL);
+	DEFINE_WAIT(wait);
+        struct pktgen_dev *pkt_dev = NULL;
+	int cpu = t->cpu;
+	sigset_t tmpsig;
+	u32 max_before_softirq;
+        u32 tx_since_softirq = 0;
+
+	daemonize("pktgen/%d", cpu);
+
+        /* Block all signals except SIGKILL, SIGSTOP and SIGTERM */
+
+        spin_lock_irq(&current->sighand->siglock);
+        tmpsig = current->blocked;
+        siginitsetinv(&current->blocked, 
+                      sigmask(SIGKILL) | 
+                      sigmask(SIGSTOP)| 
+                      sigmask(SIGTERM));
+
+        recalc_sigpending();
+        spin_unlock_irq(&current->sighand->siglock);
+
+	/* Migrate to the right CPU */
+	set_cpus_allowed(current, cpumask_of_cpu(cpu));
+        if (smp_processor_id() != cpu)
+                BUG();
+
+	init_waitqueue_head(&t->queue);
+
+	t->control &= ~(T_TERMINATE);
+	t->control &= ~(T_RUN);
+	t->control &= ~(T_STOP);
+	t->control &= ~(T_REMDEV);
+
+        t->pid = current->pid;        
+
+        PG_DEBUG(printk("pktgen: starting pktgen/%d:  pid=%d\n", cpu, current->pid));
+
+	max_before_softirq = t->max_before_softirq;
+        
+        __set_current_state(TASK_INTERRUPTIBLE);
+        mb();
+
+        while (1) {
+		
+		__set_current_state(TASK_RUNNING);
+
+		/*
+		 * Get next dev to xmit -- if any.
+		 */
+
+                pkt_dev = next_to_run(t);
+                
+                if (pkt_dev) {
+
+			pktgen_xmit(pkt_dev);
+
+			/*
+			 * We like to stay RUNNING but must also give
+			 * others fair share.
+			 */
+
+			tx_since_softirq += pkt_dev->last_ok;
+
+			if (tx_since_softirq > max_before_softirq) {
+				if (local_softirq_pending())
+					do_softirq();
+				tx_since_softirq = 0;
+			}
+		} else {
+			prepare_to_wait(&(t->queue), &wait, TASK_INTERRUPTIBLE);
+			schedule_timeout(HZ/10);
+			finish_wait(&(t->queue), &wait);
+		}
+
+                /* 
+		 * Back from sleep, either due to the timeout or signal.
+		 * We check if we have any "posted" work for us.
+		 */
+
+                if (t->control & T_TERMINATE || signal_pending(current)) 
+                        /* we received a request to terminate ourself */
+                        break;
+		
+
+		if(t->control & T_STOP) {
+			pktgen_stop(t);
+			t->control &= ~(T_STOP);
 		}
-		if (strlen(pginfos[i].busy_fname)) {
-			remove_proc_entry(pginfos[i].busy_fname, NULL);
+
+		if(t->control & T_RUN) {
+			pktgen_run(t);
+			t->control &= ~(T_RUN);
 		}
+
+		if(t->control & T_REMDEV) {
+			pktgen_rem_all_ifs(t);
+			t->control &= ~(T_REMDEV);
+		}
+
+		if (need_resched()) 
+			schedule();
+        } 
+
+        PG_DEBUG(printk("pktgen: %s stopping all device\n", t->name));
+        pktgen_stop(t);
+
+        PG_DEBUG(printk("pktgen: %s removing all device\n", t->name));
+        pktgen_rem_all_ifs(t);
+
+        PG_DEBUG(printk("pktgen: %s removing thread.\n", t->name));
+        pktgen_rem_thread(t);
+}
+
+static struct pktgen_dev *pktgen_find_dev(struct pktgen_thread *t, const char* ifname) 
+{
+        struct pktgen_dev *pkt_dev = NULL;
+        if_lock(t);
+
+        for(pkt_dev=t->if_list; pkt_dev; pkt_dev = pkt_dev->next ) {
+                if (strcmp(pkt_dev->ifname, ifname) == 0) {
+                        break;
+                }
+        }
+
+        if_unlock(t);
+	PG_DEBUG(printk("pktgen: find_dev(%s) returning %p\n", ifname,pkt_dev));
+        return pkt_dev;
+}
+
+/* 
+ * Adds a dev at front of if_list. 
+ */
+
+static int add_dev_to_thread(struct pktgen_thread *t, struct pktgen_dev *pkt_dev) 
+{
+	int rv = 0;
+	
+        if_lock(t);
+
+        if (pkt_dev->pg_thread) {
+                printk("pktgen: ERROR:  already assigned to a thread.\n");
+                rv = -EBUSY;
+                goto out;
+        }
+	pkt_dev->next =t->if_list; t->if_list=pkt_dev;
+        pkt_dev->pg_thread = t;
+	pkt_dev->running = 0;
+
+ out:
+        if_unlock(t);        
+        return rv;
+}
+
+/* Called under thread lock */
+
+static int pktgen_add_device(struct pktgen_thread *t, const char* ifname) 
+{
+        struct pktgen_dev *pkt_dev;
+	
+	/* We don't allow a device to be on several threads */
+
+	if( (pkt_dev = __pktgen_NN_threads(ifname, FIND)) == NULL) {
+						   
+		pkt_dev = kmalloc(sizeof(struct pktgen_dev), GFP_KERNEL);
+                if (!pkt_dev) 
+                        return -ENOMEM;
+
+                memset(pkt_dev, 0, sizeof(struct pktgen_dev));
+
+		pkt_dev->flows = vmalloc(MAX_CFLOWS*sizeof(struct flow_state));
+		if (pkt_dev->flows == NULL) {
+			kfree(pkt_dev);
+			return -ENOMEM;
+		}
+		memset(pkt_dev->flows, 0, MAX_CFLOWS*sizeof(struct flow_state));
+
+		pkt_dev->min_pkt_size = ETH_ZLEN;
+                pkt_dev->max_pkt_size = ETH_ZLEN;
+                pkt_dev->nfrags = 0;
+                pkt_dev->clone_skb = pg_clone_skb_d;
+                pkt_dev->delay_us = pg_delay_d / 1000;
+                pkt_dev->delay_ns = pg_delay_d % 1000;
+                pkt_dev->count = pg_count_d;
+                pkt_dev->sofar = 0;
+                pkt_dev->udp_src_min = 9; /* sink port */
+                pkt_dev->udp_src_max = 9;
+                pkt_dev->udp_dst_min = 9;
+                pkt_dev->udp_dst_max = 9;
+
+                strncpy(pkt_dev->ifname, ifname, 31);
+                sprintf(pkt_dev->fname, "net/%s/%s", PG_PROC_DIR, ifname);
+
+                if (! pktgen_setup_dev(pkt_dev)) {
+                        printk("pktgen: ERROR: pktgen_setup_dev failed.\n");
+			if (pkt_dev->flows)
+				vfree(pkt_dev->flows);
+                        kfree(pkt_dev);
+                        return -ENODEV;
+                }
+
+                pkt_dev->proc_ent = create_proc_entry(pkt_dev->fname, 0600, NULL);
+                if (!pkt_dev->proc_ent) {
+                        printk("pktgen: cannot create %s procfs entry.\n", pkt_dev->fname);
+			if (pkt_dev->flows)
+				vfree(pkt_dev->flows);
+                        kfree(pkt_dev);
+                        return -EINVAL;
+                }
+                pkt_dev->proc_ent->read_proc = proc_if_read;
+                pkt_dev->proc_ent->write_proc = proc_if_write;
+                pkt_dev->proc_ent->data = (void*)(pkt_dev);
+		pkt_dev->proc_ent->owner = THIS_MODULE;
+
+                return add_dev_to_thread(t, pkt_dev);
+        }
+        else {
+                printk("pktgen: ERROR: interface already used.\n");
+                return -EBUSY;
+        }
+}
+
+static struct pktgen_thread *pktgen_find_thread(const char* name) 
+{
+        struct pktgen_thread *t = NULL;
+
+       thread_lock();
+
+        t = pktgen_threads;
+        while (t) {
+                if (strcmp(t->name, name) == 0) 
+                        break;
+
+                t = t->next;
+        }
+        thread_unlock();
+        return t;
+}
+
+static int pktgen_create_thread(const char* name, int cpu) 
+{
+        struct pktgen_thread *t = NULL;
+
+        if (strlen(name) > 31) {
+                printk("pktgen: ERROR:  Thread name cannot be more than 31 characters.\n");
+                return -EINVAL;
+        }
+        
+        if (pktgen_find_thread(name)) {
+                printk("pktgen: ERROR: thread: %s already exists\n", name);
+                return -EINVAL;
+        }
+
+        t = (struct pktgen_thread*)(kmalloc(sizeof(struct pktgen_thread), GFP_KERNEL));
+        if (!t) {
+                printk("pktgen: ERROR: out of memory, can't create new thread.\n");
+                return -ENOMEM;
+        }
+
+        memset(t, 0, sizeof(struct pktgen_thread));
+        strcpy(t->name, name);
+        spin_lock_init(&t->if_lock);
+	t->cpu = cpu;
+        
+        sprintf(t->fname, "net/%s/%s", PG_PROC_DIR, t->name);
+        t->proc_ent = create_proc_entry(t->fname, 0600, NULL);
+        if (!t->proc_ent) {
+                printk("pktgen: cannot create %s procfs entry.\n", t->fname);
+                kfree(t);
+                return -EINVAL;
+        }
+        t->proc_ent->read_proc = proc_thread_read;
+        t->proc_ent->write_proc = proc_thread_write;
+        t->proc_ent->data = (void*)(t);
+        t->proc_ent->owner = THIS_MODULE;
+
+        t->next = pktgen_threads;
+        pktgen_threads = t;
+
+	if (kernel_thread((void *) pktgen_thread_worker, (void *) t, 
+			  CLONE_FS | CLONE_FILES | CLONE_SIGHAND) < 0)
+		printk("pktgen: kernel_thread() failed for cpu %d\n", t->cpu);
+
+	return 0;
+}
+
+/* 
+ * Removes a device from the thread if_list. 
+ */
+static void _rem_dev_from_if_list(struct pktgen_thread *t, struct pktgen_dev *pkt_dev) 
+{
+	struct pktgen_dev *i, *prev = NULL;
+
+	i = t->if_list;
+
+	while(i) {
+		if(i == pkt_dev) {
+			if(prev) prev->next = i->next;
+			else t->if_list = NULL;
+			break;
+		}
+		prev = i;
+		i=i->next;
 	}
+}
+
+static int pktgen_remove_device(struct pktgen_thread *t, struct pktgen_dev *pkt_dev) 
+{
+
+	PG_DEBUG(printk("pktgen: remove_device pkt_dev=%p\n", pkt_dev));
+
+        if (pkt_dev->running) { 
+                printk("pktgen:WARNING: trying to remove a running interface, stopping it now.\n");
+                pktgen_stop_device(pkt_dev);
+        }
+        
+        /* Dis-associate from the interface */
+
+	if (pkt_dev->odev) {
+		dev_put(pkt_dev->odev);
+                pkt_dev->odev = NULL;
+        }
+        
+	/* And update the thread if_list */
+
+	_rem_dev_from_if_list(t, pkt_dev);
+
+        /* Clean up proc file system */
+
+        if (strlen(pkt_dev->fname)) 
+                remove_proc_entry(pkt_dev->fname, NULL);
+
+	if (pkt_dev->flows)
+		vfree(pkt_dev->flows);
+	kfree(pkt_dev);
+        return 0;
+}
+
+static int __init pg_init(void) 
+{
+	int cpu;
+	printk(version);
+
+        module_fname[0] = 0;
+
+	create_proc_dir();
+
+        sprintf(module_fname, "net/%s/pgctrl", PG_PROC_DIR);
+        module_proc_ent = create_proc_entry(module_fname, 0600, NULL);
+        if (!module_proc_ent) {
+                printk("pktgen: ERROR: cannot create %s procfs entry.\n", module_fname);
+                return -EINVAL;
+        }
+
+        module_proc_ent->proc_fops =  &pktgen_fops;
+        module_proc_ent->data = NULL;
+
+	/* Register us to receive netdevice events */
+	register_netdevice_notifier(&pktgen_notifier_block);
+        
+	for (cpu = 0; cpu < NR_CPUS ; cpu++) {
+		char buf[30];
+
+		if (!cpu_online(cpu))
+			continue;
+
+                sprintf(buf, "kpktgend_%i", cpu);
+                pktgen_create_thread(buf, cpu);
+        }
+        return 0;        
+}
+
+static void __exit pg_cleanup(void)
+{
+	wait_queue_head_t queue;
+	init_waitqueue_head(&queue);
+
+        /* Stop all interfaces & threads */        
+
+        while (pktgen_threads) {
+                struct pktgen_thread *t = pktgen_threads;
+                pktgen_threads->control |= (T_TERMINATE);
+
+		wait_event_interruptible_timeout(queue, (t != pktgen_threads), HZ);
+        }
+
+        /* Un-register us from receiving netdevice events */
+	unregister_netdevice_notifier(&pktgen_notifier_block);
+
+        /* Clean up proc file system */
+
+        remove_proc_entry(module_fname, NULL);
+        
 	remove_proc_dir();
 }
 
-module_init(init);
-module_exit(cleanup);
+
+module_init(pg_init);
+module_exit(pg_cleanup);
 
 MODULE_AUTHOR("Robert Olsson <robert.olsson@its.uu.se");
 MODULE_DESCRIPTION("Packet Generator tool");
 MODULE_LICENSE("GPL");
-module_param(count_d, int, 0);
-module_param(ipg_d, int, 0);
-module_param(cpu_speed, int, 0);
-module_param(clone_skb_d, int, 0);
+module_param(pg_count_d, int, 0);
+module_param(pg_delay_d, int, 0);
+module_param(pg_clone_skb_d, int, 0);
+module_param(debug, int, 0);
diff -Nru a/net/core/rtnetlink.c b/net/core/rtnetlink.c
--- a/net/core/rtnetlink.c	2005-03-01 23:39:18 -08:00
+++ b/net/core/rtnetlink.c	2005-03-01 23:39:18 -08:00
@@ -57,6 +57,11 @@
 {
 	rtnl_shlock();
 }
+
+int rtnl_lock_interruptible(void)
+{
+	return down_interruptible(&rtnl_sem);
+}
  
 void rtnl_unlock(void)
 {
@@ -119,6 +124,21 @@
 	memcpy(RTA_DATA(rta), data, attrlen);
 }
 
+size_t rtattr_strlcpy(char *dest, const struct rtattr *rta, size_t size)
+{
+	size_t ret = RTA_PAYLOAD(rta);
+	char *src = RTA_DATA(rta);
+
+	if (ret > 0 && src[ret - 1] == '\0')
+		ret--;
+	if (size > 0) {
+		size_t len = (ret >= size) ? size - 1 : ret;
+		memset(dest, 0, size);
+		memcpy(dest, src, len);
+	}
+	return ret;
+}
+
 int rtnetlink_send(struct sk_buff *skb, u32 pid, unsigned group, int echo)
 {
 	int err = 0;
@@ -241,7 +261,7 @@
 	return -1;
 }
 
-int rtnetlink_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
+static int rtnetlink_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
 {
 	int idx;
 	int s_idx = cb->args[0];
@@ -267,7 +287,18 @@
 	struct net_device *dev;
 	int err, send_addr_notify = 0;
 
-	dev = dev_get_by_index(ifm->ifi_index);
+	if (ifm->ifi_index >= 0)
+		dev = dev_get_by_index(ifm->ifi_index);
+	else if (ida[IFLA_IFNAME - 1]) {
+		char ifname[IFNAMSIZ];
+
+		if (rtattr_strlcpy(ifname, ida[IFLA_IFNAME - 1],
+		                   IFNAMSIZ) >= IFNAMSIZ)
+			return -EINVAL;
+		dev = dev_get_by_name(ifname);
+	} else
+		return -EINVAL;
+
 	if (!dev)
 		return -ENODEV;
 
@@ -358,19 +389,13 @@
 		dev->weight = *((u32 *) RTA_DATA(ida[IFLA_WEIGHT - 1]));
 	}
 
-	if (ida[IFLA_IFNAME - 1]) {
+	if (ifm->ifi_index >= 0 && ida[IFLA_IFNAME - 1]) {
 		char ifname[IFNAMSIZ];
 
-		if (ida[IFLA_IFNAME - 1]->rta_len > RTA_LENGTH(sizeof(ifname)))
+		if (rtattr_strlcpy(ifname, ida[IFLA_IFNAME - 1],
+		                   IFNAMSIZ) >= IFNAMSIZ)
 			goto out;
-
-		memset(ifname, 0, sizeof(ifname));
-		memcpy(ifname, RTA_DATA(ida[IFLA_IFNAME - 1]),
-			RTA_PAYLOAD(ida[IFLA_IFNAME - 1]));
-		ifname[IFNAMSIZ - 1] = '\0';
-
 		err = dev_change_name(dev, ifname);
-
 		if (err)
 			goto out;
 	}
@@ -675,11 +700,12 @@
 }
 
 EXPORT_SYMBOL(__rta_fill);
+EXPORT_SYMBOL(rtattr_strlcpy);
 EXPORT_SYMBOL(rtattr_parse);
-EXPORT_SYMBOL(rtnetlink_dump_ifinfo);
 EXPORT_SYMBOL(rtnetlink_links);
 EXPORT_SYMBOL(rtnetlink_put_metrics);
 EXPORT_SYMBOL(rtnl);
 EXPORT_SYMBOL(rtnl_lock);
+EXPORT_SYMBOL(rtnl_lock_interruptible);
 EXPORT_SYMBOL(rtnl_sem);
 EXPORT_SYMBOL(rtnl_unlock);
diff -Nru a/net/core/skbuff.c b/net/core/skbuff.c
--- a/net/core/skbuff.c	2005-03-01 23:39:08 -08:00
+++ b/net/core/skbuff.c	2005-03-01 23:39:08 -08:00
@@ -163,6 +163,59 @@
 	goto out;
 }
 
+/**
+ *	alloc_skb_from_cache	-	allocate a network buffer
+ *	@cp: kmem_cache from which to allocate the data area
+ *           (object size must be big enough for @size bytes + skb overheads)
+ *	@size: size to allocate
+ *	@gfp_mask: allocation mask
+ *
+ *	Allocate a new &sk_buff. The returned buffer has no headroom and
+ *	tail room of size bytes. The object has a reference count of one.
+ *	The return is the buffer. On a failure the return is %NULL.
+ *
+ *	Buffers may only be allocated from interrupts using a @gfp_mask of
+ *	%GFP_ATOMIC.
+ */
+struct sk_buff *alloc_skb_from_cache(kmem_cache_t *cp,
+				     unsigned int size, int gfp_mask)
+{
+	struct sk_buff *skb;
+	u8 *data;
+
+	/* Get the HEAD */
+	skb = kmem_cache_alloc(skbuff_head_cache,
+			       gfp_mask & ~__GFP_DMA);
+	if (!skb)
+		goto out;
+
+	/* Get the DATA. */
+	size = SKB_DATA_ALIGN(size);
+	data = kmem_cache_alloc(cp, gfp_mask);
+	if (!data)
+		goto nodata;
+
+	memset(skb, 0, offsetof(struct sk_buff, truesize));
+	skb->truesize = size + sizeof(struct sk_buff);
+	atomic_set(&skb->users, 1);
+	skb->head = data;
+	skb->data = data;
+	skb->tail = data;
+	skb->end  = data + size;
+
+	atomic_set(&(skb_shinfo(skb)->dataref), 1);
+	skb_shinfo(skb)->nr_frags  = 0;
+	skb_shinfo(skb)->tso_size = 0;
+	skb_shinfo(skb)->tso_segs = 0;
+	skb_shinfo(skb)->frag_list = NULL;
+out:
+	return skb;
+nodata:
+	kmem_cache_free(skbuff_head_cache, skb);
+	skb = NULL;
+	goto out;
+}
+
 
 static void skb_drop_fraglist(struct sk_buff *skb)
 {
diff -Nru a/net/core/sock.c b/net/core/sock.c
--- a/net/core/sock.c	2005-03-01 23:39:08 -08:00
+++ b/net/core/sock.c	2005-03-01 23:39:08 -08:00
@@ -166,7 +166,7 @@
 static void sock_warn_obsolete_bsdism(const char *name)
 {
 	static int warned;
-	static char warncomm[16];
+	static char warncomm[TASK_COMM_LEN];
 	if (strcmp(warncomm, current->comm) && warned < 5) { 
 		strcpy(warncomm,  current->comm); 
 		printk(KERN_WARNING "process `%s' is using obsolete "
@@ -825,8 +825,10 @@
  *	Generic send/receive buffer handlers
  */
 
-struct sk_buff *sock_alloc_send_pskb(struct sock *sk, unsigned long header_len,
-				     unsigned long data_len, int noblock, int *errcode)
+static struct sk_buff *sock_alloc_send_pskb(struct sock *sk,
+					    unsigned long header_len,
+					    unsigned long data_len,
+					    int noblock, int *errcode)
 {
 	struct sk_buff *skb;
 	unsigned int gfp_mask;
@@ -942,6 +944,15 @@
 
 			skb->next = NULL;
 			sk->sk_backlog_rcv(sk, skb);
+
+			/*
+			 * We are in process context here with softirqs
+			 * disabled, use cond_resched_softirq() to preempt.
+			 * This is safe to do because we've taken the backlog
+			 * queue private:
+			 */
+			cond_resched_softirq();
+
 			skb = next;
 		} while (skb != NULL);
 
@@ -1075,7 +1086,7 @@
  *	Default Socket Callbacks
  */
 
-void sock_def_wakeup(struct sock *sk)
+static void sock_def_wakeup(struct sock *sk)
 {
 	read_lock(&sk->sk_callback_lock);
 	if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
@@ -1083,7 +1094,7 @@
 	read_unlock(&sk->sk_callback_lock);
 }
 
-void sock_def_error_report(struct sock *sk)
+static void sock_def_error_report(struct sock *sk)
 {
 	read_lock(&sk->sk_callback_lock);
 	if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
@@ -1092,7 +1103,7 @@
 	read_unlock(&sk->sk_callback_lock);
 }
 
-void sock_def_readable(struct sock *sk, int len)
+static void sock_def_readable(struct sock *sk, int len)
 {
 	read_lock(&sk->sk_callback_lock);
 	if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
@@ -1101,7 +1112,7 @@
 	read_unlock(&sk->sk_callback_lock);
 }
 
-void sock_def_write_space(struct sock *sk)
+static void sock_def_write_space(struct sock *sk)
 {
 	read_lock(&sk->sk_callback_lock);
 
@@ -1120,7 +1131,7 @@
 	read_unlock(&sk->sk_callback_lock);
 }
 
-void sock_def_destruct(struct sock *sk)
+static void sock_def_destruct(struct sock *sk)
 {
 	if (sk->sk_protinfo)
 		kfree(sk->sk_protinfo);
@@ -1359,7 +1370,6 @@
 EXPORT_SYMBOL(sk_alloc);
 EXPORT_SYMBOL(sk_free);
 EXPORT_SYMBOL(sk_send_sigurg);
-EXPORT_SYMBOL(sock_alloc_send_pskb);
 EXPORT_SYMBOL(sock_alloc_send_skb);
 EXPORT_SYMBOL(sock_init_data);
 EXPORT_SYMBOL(sock_kfree_s);
diff -Nru a/net/core/wireless.c b/net/core/wireless.c
--- a/net/core/wireless.c	2005-03-01 23:39:18 -08:00
+++ b/net/core/wireless.c	2005-03-01 23:39:18 -08:00
@@ -304,7 +304,7 @@
 				       sizeof(struct iw_ioctl_description));
 
 /* Size (in bytes) of the various private data types */
-const char iw_priv_type_size[] = {
+static const char iw_priv_type_size[] = {
 	0,				/* IW_PRIV_TYPE_NONE */
 	1,				/* IW_PRIV_TYPE_BYTE */
 	1,				/* IW_PRIV_TYPE_CHAR */
diff -Nru a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c
--- a/net/decnet/af_decnet.c	2005-03-01 23:38:57 -08:00
+++ b/net/decnet/af_decnet.c	2005-03-01 23:38:57 -08:00
@@ -151,7 +151,7 @@
 
 static kmem_cache_t *dn_sk_cachep;
 static struct proto_ops dn_proto_ops;
-static rwlock_t dn_hash_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(dn_hash_lock);
 static struct hlist_head dn_sk_hash[DN_SK_HASH_SIZE];
 static struct hlist_head dn_wild_sk;
 
@@ -246,7 +246,7 @@
 	write_unlock_bh(&dn_hash_lock);
 }
 
-struct hlist_head *listen_hash(struct sockaddr_dn *addr)
+static struct hlist_head *listen_hash(struct sockaddr_dn *addr)
 {
 	int i;
 	unsigned hash = addr->sdn_objnum;
@@ -447,7 +447,7 @@
 	dst_release(xchg(&sk->sk_dst_cache, NULL));
 }
 
-struct sock *dn_alloc_sock(struct socket *sock, int gfp)
+static struct sock *dn_alloc_sock(struct socket *sock, int gfp)
 {
 	struct dn_scp *scp;
 	struct sock *sk = sk_alloc(PF_DECnet, gfp, sizeof(struct dn_sock),
@@ -578,7 +578,6 @@
 	if (sk->sk_socket)
 		return 0;
 
-	dn_stop_fast_timer(sk); /* unlikely, but possible that this is runninng */
 	if ((jiffies - scp->stamp) >= (HZ * decnet_time_wait)) {
 		dn_unhash_sock(sk);
 		sock_put(sk);
@@ -631,7 +630,6 @@
 		default:
 			printk(KERN_DEBUG "DECnet: dn_destroy_sock passed socket in invalid state\n");
 		case DN_O:
-			dn_stop_fast_timer(sk);
 			dn_stop_slow_timer(sk);
 
 			dn_unhash_sock_bh(sk);
diff -Nru a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c
--- a/net/decnet/dn_dev.c	2005-03-01 23:38:55 -08:00
+++ b/net/decnet/dn_dev.c	2005-03-01 23:38:55 -08:00
@@ -65,7 +65,7 @@
  */
 dn_address decnet_address = 0;
 
-static rwlock_t dndev_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(dndev_lock);
 static struct net_device *decnet_default_device;
 static struct notifier_block *dnaddr_chain;
 
@@ -662,7 +662,7 @@
 	for(ifap = &dn_db->ifa_list; (ifa=*ifap) != NULL; ifap = &ifa->ifa_next) {
 		void *tmp = rta[IFA_LOCAL-1];
 		if ((tmp && memcmp(RTA_DATA(tmp), &ifa->ifa_local, 2)) ||
-				(rta[IFA_LABEL-1] && strcmp(RTA_DATA(rta[IFA_LABEL-1]), ifa->ifa_label)))
+		    (rta[IFA_LABEL-1] && rtattr_strcmp(rta[IFA_LABEL-1], ifa->ifa_label)))
 			continue;
 
 		dn_dev_del_ifa(dn_db, ifap, 1);
@@ -705,7 +705,7 @@
 	ifa->ifa_scope = ifm->ifa_scope;
 	ifa->ifa_dev = dn_db;
 	if (rta[IFA_LABEL-1])
-		memcpy(ifa->ifa_label, RTA_DATA(rta[IFA_LABEL-1]), IFNAMSIZ);
+		rtattr_strlcpy(ifa->ifa_label, rta[IFA_LABEL-1], IFNAMSIZ);
 	else
 		memcpy(ifa->ifa_label, dev->name, IFNAMSIZ);
 
diff -Nru a/net/decnet/dn_fib.c b/net/decnet/dn_fib.c
--- a/net/decnet/dn_fib.c	2005-03-01 23:39:18 -08:00
+++ b/net/decnet/dn_fib.c	2005-03-01 23:39:18 -08:00
@@ -57,10 +57,9 @@
 
 extern int dn_cache_dump(struct sk_buff *skb, struct netlink_callback *cb);
 
-static spinlock_t dn_fib_multipath_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(dn_fib_multipath_lock);
 static struct dn_fib_info *dn_fib_info_list;
-static rwlock_t dn_fib_info_lock = RW_LOCK_UNLOCKED;
-int dn_fib_info_cnt;
+static DEFINE_RWLOCK(dn_fib_info_lock);
 
 static struct
 {
@@ -93,7 +92,6 @@
 			dev_put(nh->nh_dev);
 		nh->nh_dev = NULL;
 	} endfor_nexthops(fi);
-	dn_fib_info_cnt--;
 	kfree(fi);
 }
 
@@ -388,7 +386,6 @@
 	if (dn_fib_info_list)
 		dn_fib_info_list->fib_prev = fi;
 	dn_fib_info_list = fi;
-	dn_fib_info_cnt++;
 	write_unlock(&dn_fib_info_lock);
 	return fi;
 
@@ -483,18 +480,6 @@
 	} endfor_nexthops(fi);
 	res->nh_sel = 0;
 	spin_unlock_bh(&dn_fib_multipath_lock);
-}
-
-
-/*
- * Punt to user via netlink for example, but for now
- * we just drop it.
- */
-int dn_fib_rt_message(struct sk_buff *skb)
-{
-	kfree_skb(skb);
-
-	return 0;
 }
 
 
diff -Nru a/net/decnet/dn_neigh.c b/net/decnet/dn_neigh.c
--- a/net/decnet/dn_neigh.c	2005-03-01 23:39:07 -08:00
+++ b/net/decnet/dn_neigh.c	2005-03-01 23:39:07 -08:00
@@ -355,14 +355,6 @@
  * basically does a neigh_lookup(), but without comparing the device
  * field. This is required for the On-Ethernet cache
  */
-/*
- * Any traffic on a pointopoint link causes the timer to be reset
- * for the entry in the neighbour table.
- */
-void dn_neigh_pointopoint_notify(struct sk_buff *skb)
-{
-	return;
-}
 
 /*
  * Pointopoint link receives a hello message
diff -Nru a/net/decnet/dn_route.c b/net/decnet/dn_route.c
--- a/net/decnet/dn_route.c	2005-03-01 23:39:16 -08:00
+++ b/net/decnet/dn_route.c	2005-03-01 23:39:16 -08:00
@@ -99,9 +99,9 @@
 
 static unsigned char dn_hiord_addr[6] = {0xAA,0x00,0x04,0x00,0x00,0x00};
 
-int dn_rt_min_delay = 2 * HZ;
-int dn_rt_max_delay = 10 * HZ;
-int dn_rt_mtu_expires = 10 * 60 * HZ;
+static const int dn_rt_min_delay = 2 * HZ;
+static const int dn_rt_max_delay = 10 * HZ;
+static const int dn_rt_mtu_expires = 10 * 60 * HZ;
 
 static unsigned long dn_rt_deadline;
 
@@ -336,7 +336,7 @@
 	}
 }
 
-static spinlock_t dn_rt_flush_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(dn_rt_flush_lock);
 
 void dn_rt_cache_flush(int delay)
 {
diff -Nru a/net/decnet/dn_rules.c b/net/decnet/dn_rules.c
--- a/net/decnet/dn_rules.c	2005-03-01 23:39:08 -08:00
+++ b/net/decnet/dn_rules.c	2005-03-01 23:39:08 -08:00
@@ -68,7 +68,7 @@
 };
 
 static struct dn_fib_rule *dn_fib_rules = &default_rule;
-static rwlock_t dn_fib_rules_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(dn_fib_rules_lock);
 
 
 int dn_fib_rtm_delrule(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
@@ -88,7 +88,7 @@
 #endif
 			(!rtm->rtm_type || rtm->rtm_type == r->r_action) &&
 			(!rta[RTA_PRIORITY-1] || memcmp(RTA_DATA(rta[RTA_PRIORITY-1]), &r->r_preference, 4) == 0) &&
-			(!rta[RTA_IIF-1] || strcmp(RTA_DATA(rta[RTA_IIF-1]), r->r_ifname) == 0) &&
+			(!rta[RTA_IIF-1] || rtattr_strcmp(rta[RTA_IIF-1], r->r_ifname) == 0) &&
 			(!rtm->rtm_table || (r && rtm->rtm_table == r->r_table))) {
 
 			err = -EPERM;
@@ -170,8 +170,7 @@
 	new_r->r_table = table_id;
 	if (rta[RTA_IIF-1]) {
 		struct net_device *dev;
-		memcpy(new_r->r_ifname, RTA_DATA(rta[RTA_IIF-1]), IFNAMSIZ);
-		new_r->r_ifname[IFNAMSIZ-1] = 0;
+		rtattr_strlcpy(new_r->r_ifname, rta[RTA_IIF-1], IFNAMSIZ);
 		new_r->r_ifindex = -1;
 		dev = dev_get_by_name(new_r->r_ifname);
 		if (dev) {
diff -Nru a/net/decnet/dn_table.c b/net/decnet/dn_table.c
--- a/net/decnet/dn_table.c	2005-03-01 23:38:54 -08:00
+++ b/net/decnet/dn_table.c	2005-03-01 23:38:54 -08:00
@@ -76,7 +76,7 @@
 
 #define RT_TABLE_MIN 1
 
-static rwlock_t dn_fib_tables_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(dn_fib_tables_lock);
 struct dn_fib_table *dn_fib_tables[RT_TABLE_MAX + 1];
 
 static kmem_cache_t *dn_hash_kmem;
diff -Nru a/net/decnet/dn_timer.c b/net/decnet/dn_timer.c
--- a/net/decnet/dn_timer.c	2005-03-01 23:38:58 -08:00
+++ b/net/decnet/dn_timer.c	2005-03-01 23:38:58 -08:00
@@ -27,11 +27,9 @@
 #include <net/dn.h>
 
 /*
- * Fast timer is for delayed acks (200mS max)
  * Slow timer is for everything else (n * 500mS)
  */
 
-#define FAST_INTERVAL (HZ/5)
 #define SLOW_INTERVAL (HZ/2)
 
 static void dn_slow_timer(unsigned long arg);
@@ -109,48 +107,3 @@
 	bh_unlock_sock(sk);
 	sock_put(sk);
 }
-
-static void dn_fast_timer(unsigned long arg)
-{
-	struct sock *sk = (struct sock *)arg;
-	struct dn_scp *scp = DN_SK(sk);
-
-	bh_lock_sock(sk);
-	if (sock_owned_by_user(sk)) {
-		scp->delack_timer.expires = jiffies + HZ / 20;
-		add_timer(&scp->delack_timer);
-		goto out;
-	}
-
-	scp->delack_pending = 0;
-
-	if (scp->delack_fxn)
-		scp->delack_fxn(sk);
-out:
-	bh_unlock_sock(sk);
-}
-
-void dn_start_fast_timer(struct sock *sk)
-{
-	struct dn_scp *scp = DN_SK(sk);
-
-	if (!scp->delack_pending) {
-		scp->delack_pending = 1;
-		init_timer(&scp->delack_timer);
-		scp->delack_timer.expires = jiffies + FAST_INTERVAL;
-		scp->delack_timer.data = (unsigned long)sk;
-		scp->delack_timer.function = dn_fast_timer;
-		add_timer(&scp->delack_timer);
-	}
-}
-
-void dn_stop_fast_timer(struct sock *sk)
-{
-	struct dn_scp *scp = DN_SK(sk);
-
-	if (scp->delack_pending) {
-		scp->delack_pending = 0;
-		del_timer(&scp->delack_timer);
-	}
-}
-
diff -Nru a/net/econet/af_econet.c b/net/econet/af_econet.c
--- a/net/econet/af_econet.c	2005-03-01 23:38:57 -08:00
+++ b/net/econet/af_econet.c	2005-03-01 23:38:57 -08:00
@@ -47,7 +47,7 @@
 
 static struct proto_ops econet_ops;
 static struct hlist_head econet_sklist;
-static rwlock_t econet_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(econet_lock);
 
 /* Since there are only 256 possible network numbers (or fewer, depends
    how you count) it makes sense to use a simple lookup table. */
diff -Nru a/net/ethernet/eth.c b/net/ethernet/eth.c
--- a/net/ethernet/eth.c	2005-03-01 23:38:57 -08:00
+++ b/net/ethernet/eth.c	2005-03-01 23:38:57 -08:00
@@ -208,7 +208,7 @@
 	return htons(ETH_P_802_2);
 }
 
-int eth_header_parse(struct sk_buff *skb, unsigned char *haddr)
+static int eth_header_parse(struct sk_buff *skb, unsigned char *haddr)
 {
 	struct ethhdr *eth = eth_hdr(skb);
 	memcpy(haddr, eth->h_source, ETH_ALEN);
diff -Nru a/net/ipv4/Kconfig b/net/ipv4/Kconfig
--- a/net/ipv4/Kconfig	2005-03-01 23:39:08 -08:00
+++ b/net/ipv4/Kconfig	2005-03-01 23:39:08 -08:00
@@ -355,7 +355,10 @@
 	default y
 	---help---
 	  Support for TCP socket monitoring interface used by native Linux
-	  tools such as ss.
+	  tools such as ss. ss is included in iproute2, currently downloadable
+	  at <http://developer.osdl.org/dev/iproute2>. If you want IPv6 support
+	  and have selected IPv6 as a module, you need to build this as a
+	  module too.
 	  
 	  If unsure, say Y.
 
diff -Nru a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
--- a/net/ipv4/af_inet.c	2005-03-01 23:38:52 -08:00
+++ b/net/ipv4/af_inet.c	2005-03-01 23:38:52 -08:00
@@ -125,13 +125,13 @@
  * build a new socket.
  */
 static struct list_head inetsw[SOCK_MAX];
-static spinlock_t inetsw_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(inetsw_lock);
 
 /* New destruction routine */
 
 void inet_sock_destruct(struct sock *sk)
 {
-	struct inet_opt *inet = inet_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
 
 	__skb_queue_purge(&sk->sk_receive_queue);
 	__skb_queue_purge(&sk->sk_error_queue);
@@ -173,7 +173,7 @@
 
 static int inet_autobind(struct sock *sk)
 {
-	struct inet_opt *inet;
+	struct inet_sock *inet;
 	/* We may need to bind the socket. */
 	lock_sock(sk);
 	inet = inet_sk(sk);
@@ -232,7 +232,7 @@
 	struct sock *sk;
 	struct list_head *p;
 	struct inet_protosw *answer;
-	struct inet_opt *inet;
+	struct inet_sock *inet;
 	struct proto *answer_prot;
 	unsigned char answer_flags;
 	char answer_no_check;
@@ -389,7 +389,7 @@
 {
 	struct sockaddr_in *addr = (struct sockaddr_in *)uaddr;
 	struct sock *sk = sock->sk;
-	struct inet_opt *inet = inet_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
 	unsigned short snum;
 	int chk_addr_ret;
 	int err;
@@ -623,7 +623,7 @@
 			int *uaddr_len, int peer)
 {
 	struct sock *sk		= sock->sk;
-	struct inet_opt *inet	= inet_sk(sk);
+	struct inet_sock *inet	= inet_sk(sk);
 	struct sockaddr_in *sin	= (struct sockaddr_in *)uaddr;
 
 	sin->sin_family = AF_INET;
@@ -659,7 +659,7 @@
 }
 
 
-ssize_t inet_sendpage(struct socket *sock, struct page *page, int offset, size_t size, int flags)
+static ssize_t inet_sendpage(struct socket *sock, struct page *page, int offset, size_t size, int flags)
 {
 	struct sock *sk = sock->sk;
 
@@ -1011,7 +1011,7 @@
 	return 0;
 }
 
-int ipv4_proc_init(void);
+static int ipv4_proc_init(void);
 extern void ipfrag_init(void);
 
 static int __init inet_init(void)
@@ -1136,7 +1136,7 @@
 extern int  udp4_proc_init(void);
 extern void udp4_proc_exit(void);
 
-int __init ipv4_proc_init(void)
+static int __init ipv4_proc_init(void)
 {
 	int rc = 0;
 
@@ -1166,7 +1166,7 @@
 }
 
 #else /* CONFIG_PROC_FS */
-int __init ipv4_proc_init(void)
+static int __init ipv4_proc_init(void)
 {
 	return 0;
 }
diff -Nru a/net/ipv4/ah4.c b/net/ipv4/ah4.c
--- a/net/ipv4/ah4.c	2005-03-01 23:39:09 -08:00
+++ b/net/ipv4/ah4.c	2005-03-01 23:39:09 -08:00
@@ -236,7 +236,7 @@
 	 * we need for AH processing.  This lookup cannot fail here
 	 * after a successful crypto_alloc_tfm().
 	 */
-	aalg_desc = xfrm_aalg_get_byname(x->aalg->alg_name);
+	aalg_desc = xfrm_aalg_get_byname(x->aalg->alg_name, 0);
 	BUG_ON(!aalg_desc);
 
 	if (aalg_desc->uinfo.auth.icv_fullbits/8 !=
diff -Nru a/net/ipv4/arp.c b/net/ipv4/arp.c
--- a/net/ipv4/arp.c	2005-03-01 23:39:09 -08:00
+++ b/net/ipv4/arp.c	2005-03-01 23:39:09 -08:00
@@ -213,6 +213,9 @@
 	case ARPHRD_IEEE802_TR:
 		ip_tr_mc_map(addr, haddr);
 		return 0;
+	case ARPHRD_INFINIBAND:
+		ip_ib_mc_map(addr, haddr);
+		return 0;
 	default:
 		if (dir) {
 			memcpy(haddr, dev->broadcast, dev->addr_len);
@@ -704,7 +707,7 @@
  *	Process an arp request.
  */
 
-int arp_process(struct sk_buff *skb)
+static int arp_process(struct sk_buff *skb)
 {
 	struct net_device *dev = skb->dev;
 	struct in_device *in_dev = in_dev_get(dev);
@@ -961,7 +964,7 @@
  *	Set (create) an ARP cache entry.
  */
 
-int arp_req_set(struct arpreq *r, struct net_device * dev)
+static int arp_req_set(struct arpreq *r, struct net_device * dev)
 {
 	u32 ip = ((struct sockaddr_in *) &r->arp_pa)->sin_addr.s_addr;
 	struct neighbour *neigh;
@@ -1075,7 +1078,7 @@
 	return err;
 }
 
-int arp_req_delete(struct arpreq *r, struct net_device * dev)
+static int arp_req_delete(struct arpreq *r, struct net_device * dev)
 {
 	int err;
 	u32 ip = ((struct sockaddr_in *)&r->arp_pa)->sin_addr.s_addr;
@@ -1207,7 +1210,7 @@
 	return NOTIFY_DONE;
 }
 
-struct notifier_block arp_netdev_notifier = {
+static struct notifier_block arp_netdev_notifier = {
 	.notifier_call = arp_netdev_event,
 };
 
diff -Nru a/net/ipv4/datagram.c b/net/ipv4/datagram.c
--- a/net/ipv4/datagram.c	2005-03-01 23:38:43 -08:00
+++ b/net/ipv4/datagram.c	2005-03-01 23:38:43 -08:00
@@ -22,7 +22,7 @@
 
 int ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
 {
-	struct inet_opt *inet = inet_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
 	struct sockaddr_in *usin = (struct sockaddr_in *) uaddr;
 	struct rtable *rt;
 	u32 saddr;
diff -Nru a/net/ipv4/devinet.c b/net/ipv4/devinet.c
--- a/net/ipv4/devinet.c	2005-03-01 23:38:53 -08:00
+++ b/net/ipv4/devinet.c	2005-03-01 23:38:53 -08:00
@@ -380,7 +380,7 @@
 	return NULL;
 }
 
-int inet_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
+static int inet_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
 {
 	struct rtattr **rta = arg;
 	struct in_device *in_dev;
@@ -399,7 +399,7 @@
 		     memcmp(RTA_DATA(rta[IFA_LOCAL - 1]),
 			    &ifa->ifa_local, 4)) ||
 		    (rta[IFA_LABEL - 1] &&
-		     strcmp(RTA_DATA(rta[IFA_LABEL - 1]), ifa->ifa_label)) ||
+		     rtattr_strcmp(rta[IFA_LABEL - 1], ifa->ifa_label)) ||
 		    (rta[IFA_ADDRESS - 1] &&
 		     (ifm->ifa_prefixlen != ifa->ifa_prefixlen ||
 		      !inet_ifa_match(*(u32*)RTA_DATA(rta[IFA_ADDRESS - 1]),
@@ -412,7 +412,7 @@
 	return -EADDRNOTAVAIL;
 }
 
-int inet_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
+static int inet_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
 {
 	struct rtattr **rta = arg;
 	struct net_device *dev;
@@ -456,7 +456,7 @@
 	in_dev_hold(in_dev);
 	ifa->ifa_dev   = in_dev;
 	if (rta[IFA_LABEL - 1])
-		memcpy(ifa->ifa_label, RTA_DATA(rta[IFA_LABEL - 1]), IFNAMSIZ);
+		rtattr_strlcpy(ifa->ifa_label, rta[IFA_LABEL - 1], IFNAMSIZ);
 	else
 		memcpy(ifa->ifa_label, dev->name, IFNAMSIZ);
 
diff -Nru a/net/ipv4/esp4.c b/net/ipv4/esp4.c
--- a/net/ipv4/esp4.c	2005-03-01 23:38:58 -08:00
+++ b/net/ipv4/esp4.c	2005-03-01 23:38:58 -08:00
@@ -392,7 +392,7 @@
 			goto error;
 		esp->auth.icv = esp_hmac_digest;
 
-		aalg_desc = xfrm_aalg_get_byname(x->aalg->alg_name);
+		aalg_desc = xfrm_aalg_get_byname(x->aalg->alg_name, 0);
 		BUG_ON(!aalg_desc);
 
 		if (aalg_desc->uinfo.auth.icv_fullbits/8 !=
@@ -427,7 +427,8 @@
 			goto error;
 		get_random_bytes(esp->conf.ivec, esp->conf.ivlen);
 	}
-	crypto_cipher_setkey(esp->conf.tfm, esp->conf.key, esp->conf.key_len);
+	if (crypto_cipher_setkey(esp->conf.tfm, esp->conf.key, esp->conf.key_len))
+		goto error;
 	x->props.header_len = sizeof(struct ip_esp_hdr) + esp->conf.ivlen;
 	if (x->props.mode)
 		x->props.header_len += sizeof(struct iphdr);
diff -Nru a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
--- a/net/ipv4/fib_frontend.c	2005-03-01 23:39:17 -08:00
+++ b/net/ipv4/fib_frontend.c	2005-03-01 23:39:17 -08:00
@@ -75,7 +75,7 @@
 #endif /* CONFIG_IP_MULTIPLE_TABLES */
 
 
-void fib_flush(void)
+static void fib_flush(void)
 {
 	int flushed = 0;
 #ifdef CONFIG_IP_MULTIPLE_TABLES
@@ -585,11 +585,11 @@
 	return NOTIFY_DONE;
 }
 
-struct notifier_block fib_inetaddr_notifier = {
+static struct notifier_block fib_inetaddr_notifier = {
 	.notifier_call =fib_inetaddr_event,
 };
 
-struct notifier_block fib_netdev_notifier = {
+static struct notifier_block fib_netdev_notifier = {
 	.notifier_call =fib_netdev_event,
 };
 
diff -Nru a/net/ipv4/fib_hash.c b/net/ipv4/fib_hash.c
--- a/net/ipv4/fib_hash.c	2005-03-01 23:38:57 -08:00
+++ b/net/ipv4/fib_hash.c	2005-03-01 23:38:57 -08:00
@@ -92,7 +92,7 @@
 	return dst & FZ_MASK(fz);
 }
 
-static rwlock_t fib_hash_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(fib_hash_lock);
 
 #define FZ_MAX_DIVISOR ((PAGE_SIZE<<MAX_ORDER) / sizeof(struct hlist_head))
 
@@ -274,29 +274,6 @@
 
 static int fn_hash_last_dflt=-1;
 
-static int fib_detect_death(struct fib_info *fi, int order,
-			    struct fib_info **last_resort, int *last_idx)
-{
-	struct neighbour *n;
-	int state = NUD_NONE;
-
-	n = neigh_lookup(&arp_tbl, &fi->fib_nh[0].nh_gw, fi->fib_dev);
-	if (n) {
-		state = n->nud_state;
-		neigh_release(n);
-	}
-	if (state==NUD_REACHABLE)
-		return 0;
-	if ((state&NUD_VALID) && order != fn_hash_last_dflt)
-		return 0;
-	if ((state&NUD_VALID) ||
-	    (*last_idx<0 && order > fn_hash_last_dflt)) {
-		*last_resort = fi;
-		*last_idx = order;
-	}
-	return 1;
-}
-
 static void
 fn_hash_select_default(struct fib_table *tb, const struct flowi *flp, struct fib_result *res)
 {
@@ -337,7 +314,7 @@
 				if (next_fi != res->fi)
 					break;
 			} else if (!fib_detect_death(fi, order, &last_resort,
-						     &last_idx)) {
+						     &last_idx, &fn_hash_last_dflt)) {
 				if (res->fi)
 					fib_info_put(res->fi);
 				res->fi = fi;
@@ -355,7 +332,7 @@
 		goto out;
 	}
 
-	if (!fib_detect_death(fi, order, &last_resort, &last_idx)) {
+	if (!fib_detect_death(fi, order, &last_resort, &last_idx, &fn_hash_last_dflt)) {
 		if (res->fi)
 			fib_info_put(res->fi);
 		res->fi = fi;
@@ -376,11 +353,6 @@
 	read_unlock(&fib_hash_lock);
 }
 
-static void rtmsg_fib(int, struct fib_node *, struct fib_alias *,
-		      int, int,
-		      struct nlmsghdr *n,
-		      struct netlink_skb_parms *);
-
 /* Insert node F to FZ. */
 static inline void fib_insert_node(struct fn_zone *fz, struct fib_node *f)
 {
@@ -404,26 +376,6 @@
 	return NULL;
 }
 
-/* Return the first fib alias matching TOS with
- * priority less than or equal to PRIO.
- */
-static struct fib_alias *fib_find_alias(struct fib_node *fn, u8 tos, u32 prio)
-{
-	if (fn) {
-		struct list_head *head = &fn->fn_alias;
-		struct fib_alias *fa;
-
-		list_for_each_entry(fa, head, fa_list) {
-			if (fa->fa_tos > tos)
-				continue;
-			if (fa->fa_info->fib_priority >= prio ||
-			    fa->fa_tos < tos)
-				return fa;
-		}
-	}
-	return NULL;
-}
-
 static int
 fn_hash_insert(struct fib_table *tb, struct rtmsg *r, struct kern_rta *rta,
 	       struct nlmsghdr *n, struct netlink_skb_parms *req)
@@ -463,7 +415,11 @@
 		fn_rehash_zone(fz);
 
 	f = fib_find_node(fz, key);
-	fa = fib_find_alias(f, tos, fi->fib_priority);
+
+	if (!f)
+		fa = NULL;
+	else
+		fa = fib_find_alias(&f->fn_alias, 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
@@ -565,7 +521,7 @@
 		fz->fz_nent++;
 	rt_cache_flush(-1);
 
-	rtmsg_fib(RTM_NEWROUTE, f, new_fa, z, tb->tb_id, n, req);
+	rtmsg_fib(RTM_NEWROUTE, key, new_fa, z, tb->tb_id, n, req);
 	return 0;
 
 out_free_new_fa:
@@ -603,7 +559,11 @@
 	}
 
 	f = fib_find_node(fz, key);
-	fa = fib_find_alias(f, tos, 0);
+
+	if (!f)
+		fa = NULL;
+	else
+		fa = fib_find_alias(&f->fn_alias, tos, 0);
 	if (!fa)
 		return -ESRCH;
 
@@ -631,7 +591,7 @@
 		int kill_fn;
 
 		fa = fa_to_delete;
-		rtmsg_fib(RTM_DELROUTE, f, fa, z, tb->tb_id, n, req);
+		rtmsg_fib(RTM_DELROUTE, key, fa, z, tb->tb_id, n, req);
 
 		kill_fn = 0;
 		write_lock_bh(&fib_hash_lock);
@@ -724,7 +684,7 @@
 
 		list_for_each_entry(fa, &f->fn_alias, fa_list) {
 			if (i < s_i)
-				continue;
+				goto next;
 
 			if (fib_dump_info(skb, NETLINK_CB(cb->skb).pid,
 					  cb->nlh->nlmsg_seq,
@@ -739,7 +699,7 @@
 				cb->args[3] = i;
 				return -1;
 			}
-
+		next:
 			i++;
 		}
 	}
@@ -794,33 +754,6 @@
 	read_unlock(&fib_hash_lock);
 	cb->args[1] = m;
 	return skb->len;
-}
-
-static void rtmsg_fib(int event, struct fib_node *f, struct fib_alias *fa,
-		      int z, int tb_id,
-		      struct nlmsghdr *n, struct netlink_skb_parms *req)
-{
-	struct sk_buff *skb;
-	u32 pid = req ? req->pid : 0;
-	int size = NLMSG_SPACE(sizeof(struct rtmsg)+256);
-
-	skb = alloc_skb(size, GFP_KERNEL);
-	if (!skb)
-		return;
-
-	if (fib_dump_info(skb, pid, n->nlmsg_seq, event, tb_id,
-			  fa->fa_type, fa->fa_scope, &f->fn_key, z,
-			  fa->fa_tos,
-			  fa->fa_info) < 0) {
-		kfree_skb(skb);
-		return;
-	}
-	NETLINK_CB(skb).dst_groups = RTMGRP_IPV4_ROUTE;
-	if (n->nlmsg_flags&NLM_F_ECHO)
-		atomic_inc(&skb->users);
-	netlink_broadcast(rtnl, skb, pid, RTMGRP_IPV4_ROUTE, GFP_KERNEL);
-	if (n->nlmsg_flags&NLM_F_ECHO)
-		netlink_unicast(rtnl, skb, pid, MSG_DONTWAIT);
 }
 
 #ifdef CONFIG_IP_MULTIPLE_TABLES
diff -Nru a/net/ipv4/fib_lookup.h b/net/ipv4/fib_lookup.h
--- a/net/ipv4/fib_lookup.h	2005-03-01 23:38:55 -08:00
+++ b/net/ipv4/fib_lookup.h	2005-03-01 23:38:55 -08:00
@@ -30,5 +30,13 @@
 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);
+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);
+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);
 
 #endif /* _FIB_LOOKUP_H */
diff -Nru a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c
--- a/net/ipv4/fib_rules.c	2005-03-01 23:38:58 -08:00
+++ b/net/ipv4/fib_rules.c	2005-03-01 23:38:58 -08:00
@@ -99,7 +99,7 @@
 };
 
 static struct fib_rule *fib_rules = &local_rule;
-static rwlock_t fib_rules_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(fib_rules_lock);
 
 int inet_rtm_delrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
 {
@@ -119,7 +119,7 @@
 #endif
 		    (!rtm->rtm_type || rtm->rtm_type == r->r_action) &&
 		    (!rta[RTA_PRIORITY-1] || memcmp(RTA_DATA(rta[RTA_PRIORITY-1]), &r->r_preference, 4) == 0) &&
-		    (!rta[RTA_IIF-1] || strcmp(RTA_DATA(rta[RTA_IIF-1]), r->r_ifname) == 0) &&
+		    (!rta[RTA_IIF-1] || rtattr_strcmp(rta[RTA_IIF-1], r->r_ifname) == 0) &&
 		    (!rtm->rtm_table || (r && rtm->rtm_table == r->r_table))) {
 			err = -EPERM;
 			if (r == &local_rule)
@@ -209,8 +209,7 @@
 	new_r->r_table = table_id;
 	if (rta[RTA_IIF-1]) {
 		struct net_device *dev;
-		memcpy(new_r->r_ifname, RTA_DATA(rta[RTA_IIF-1]), IFNAMSIZ);
-		new_r->r_ifname[IFNAMSIZ-1] = 0;
+		rtattr_strlcpy(new_r->r_ifname, rta[RTA_IIF-1], IFNAMSIZ);
 		new_r->r_ifindex = -1;
 		dev = __dev_get_by_name(new_r->r_ifname);
 		if (dev)
@@ -245,12 +244,6 @@
 	return 0;
 }
 
-u32 fib_rules_map_destination(u32 daddr, struct fib_result *res)
-{
-	u32 mask = inet_make_mask(res->prefixlen);
-	return (daddr&~mask)|res->fi->fib_nh->nh_gw;
-}
-
 #ifdef CONFIG_NET_CLS_ROUTE
 u32 fib_rules_tclass(struct fib_result *res)
 {
@@ -368,7 +361,7 @@
 }
 
 
-struct notifier_block fib_rules_notifier = {
+static struct notifier_block fib_rules_notifier = {
 	.notifier_call =fib_rules_event,
 };
 
diff -Nru a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
--- a/net/ipv4/fib_semantics.c	2005-03-01 23:38:53 -08:00
+++ b/net/ipv4/fib_semantics.c	2005-03-01 23:38:53 -08:00
@@ -47,7 +47,7 @@
 
 #define FSprintk(a...)
 
-static rwlock_t fib_info_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(fib_info_lock);
 static struct hlist_head *fib_info_hash;
 static struct hlist_head *fib_info_laddrhash;
 static unsigned int fib_hash_size;
@@ -59,7 +59,7 @@
 
 #ifdef CONFIG_IP_ROUTE_MULTIPATH
 
-static spinlock_t fib_multipath_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(fib_multipath_lock);
 
 #define for_nexthops(fi) { int nhsel; const struct fib_nh * nh; \
 for (nhsel=0, nh = (fi)->fib_nh; nhsel < (fi)->fib_nhs; nh++, nhsel++)
@@ -268,6 +268,74 @@
 	read_unlock(&fib_info_lock);
 
 	return -1;
+}
+
+void rtmsg_fib(int event, u32 key, struct fib_alias *fa,
+	       int z, int tb_id,
+	       struct nlmsghdr *n, struct netlink_skb_parms *req)
+{
+	struct sk_buff *skb;
+	u32 pid = req ? req->pid : 0;
+	int size = NLMSG_SPACE(sizeof(struct rtmsg)+256);
+
+	skb = alloc_skb(size, GFP_KERNEL);
+	if (!skb)
+		return;
+
+	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) {
+		kfree_skb(skb);
+		return;
+	}
+	NETLINK_CB(skb).dst_groups = RTMGRP_IPV4_ROUTE;
+	if (n->nlmsg_flags&NLM_F_ECHO)
+		atomic_inc(&skb->users);
+	netlink_broadcast(rtnl, skb, pid, RTMGRP_IPV4_ROUTE, GFP_KERNEL);
+	if (n->nlmsg_flags&NLM_F_ECHO)
+		netlink_unicast(rtnl, skb, pid, MSG_DONTWAIT);
+}
+
+/* Return the first fib alias matching TOS with
+ * priority less than or equal to PRIO.
+ */
+struct fib_alias *fib_find_alias(struct list_head *fah, u8 tos, u32 prio)
+{
+	if (fah) {
+		struct fib_alias *fa;
+		list_for_each_entry(fa, fah, fa_list) {
+			if (fa->fa_tos > tos)
+				continue;
+			if (fa->fa_info->fib_priority >= prio ||
+			    fa->fa_tos < tos)
+				return fa;
+		}
+	}
+	return NULL;
+}
+
+int fib_detect_death(struct fib_info *fi, int order,
+		     struct fib_info **last_resort, int *last_idx, int *dflt)
+{
+	struct neighbour *n;
+	int state = NUD_NONE;
+
+	n = neigh_lookup(&arp_tbl, &fi->fib_nh[0].nh_gw, fi->fib_dev);
+	if (n) {
+		state = n->nud_state;
+		neigh_release(n);
+	}
+	if (state==NUD_REACHABLE)
+		return 0;
+	if ((state&NUD_VALID) && order != *dflt)
+		return 0;
+	if ((state&NUD_VALID) ||
+	    (*last_idx<0 && order > *dflt)) {
+		*last_resort = fi;
+		*last_idx = order;
+	}
+	return 1;
 }
 
 #ifdef CONFIG_IP_ROUTE_MULTIPATH
diff -Nru a/net/ipv4/icmp.c b/net/ipv4/icmp.c
--- a/net/ipv4/icmp.c	2005-03-01 23:39:16 -08:00
+++ b/net/ipv4/icmp.c	2005-03-01 23:39:16 -08:00
@@ -327,8 +327,8 @@
  *	Checksum each fragment, and on the first include the headers and final
  *	checksum.
  */
-int icmp_glue_bits(void *from, char *to, int offset, int len, int odd,
-		   struct sk_buff *skb)
+static int icmp_glue_bits(void *from, char *to, int offset, int len, int odd,
+			  struct sk_buff *skb)
 {
 	struct icmp_bxm *icmp_param = (struct icmp_bxm *)from;
 	unsigned int csum;
@@ -377,7 +377,7 @@
 static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb)
 {
 	struct sock *sk = icmp_socket->sk;
-	struct inet_opt *inet = inet_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
 	struct ipcm_cookie ipc;
 	struct rtable *rt = (struct rtable *)skb->dst;
 	u32 daddr;
@@ -1097,7 +1097,7 @@
 
 void __init icmp_init(struct net_proto_family *ops)
 {
-	struct inet_opt *inet;
+	struct inet_sock *inet;
 	int i;
 
 	for (i = 0; i < NR_CPUS; i++) {
diff -Nru a/net/ipv4/igmp.c b/net/ipv4/igmp.c
--- a/net/ipv4/igmp.c	2005-03-01 23:39:17 -08:00
+++ b/net/ipv4/igmp.c	2005-03-01 23:39:17 -08:00
@@ -143,8 +143,8 @@
 static void sf_markstate(struct ip_mc_list *pmc);
 #endif
 static void ip_mc_clear_src(struct ip_mc_list *pmc);
-int ip_mc_add_src(struct in_device *in_dev, __u32 *pmca, int sfmode,
-	int sfcount, __u32 *psfsrc, int delta);
+static int ip_mc_add_src(struct in_device *in_dev, __u32 *pmca, int sfmode,
+			 int sfcount, __u32 *psfsrc, int delta);
 
 static void ip_ma_put(struct ip_mc_list *im)
 {
@@ -1384,8 +1384,8 @@
 #define igmp_ifc_event(x)	do { } while (0)
 #endif
 
-int ip_mc_del_src(struct in_device *in_dev, __u32 *pmca, int sfmode,
-	int sfcount, __u32 *psfsrc, int delta)
+static int ip_mc_del_src(struct in_device *in_dev, __u32 *pmca, int sfmode,
+			 int sfcount, __u32 *psfsrc, int delta)
 {
 	struct ip_mc_list *pmc;
 	int	changerec = 0;
@@ -1520,8 +1520,8 @@
 /*
  * Add multicast source filter list to the interface list
  */
-int ip_mc_add_src(struct in_device *in_dev, __u32 *pmca, int sfmode,
-	int sfcount, __u32 *psfsrc, int delta)
+static int ip_mc_add_src(struct in_device *in_dev, __u32 *pmca, int sfmode,
+			 int sfcount, __u32 *psfsrc, int delta)
 {
 	struct ip_mc_list *pmc;
 	int	isexclude;
@@ -1617,7 +1617,7 @@
 	u32 addr = imr->imr_multiaddr.s_addr;
 	struct ip_mc_socklist *iml, *i;
 	struct in_device *in_dev;
-	struct inet_opt *inet = inet_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
 	int count = 0;
 
 	if (!MULTICAST(addr))
@@ -1667,8 +1667,8 @@
 	return err;
 }
 
-int ip_mc_leave_src(struct sock *sk, struct ip_mc_socklist *iml,
-	struct in_device *in_dev)
+static int ip_mc_leave_src(struct sock *sk, struct ip_mc_socklist *iml,
+			   struct in_device *in_dev)
 {
 	int err;
 
@@ -1691,7 +1691,7 @@
 
 int ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr)
 {
-	struct inet_opt *inet = inet_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
 	struct ip_mc_socklist *iml, **imlp;
 
 	rtnl_lock();
@@ -1734,7 +1734,7 @@
 	u32 addr = mreqs->imr_multiaddr;
 	struct ip_mc_socklist *pmc;
 	struct in_device *in_dev = NULL;
-	struct inet_opt *inet = inet_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
 	struct ip_sf_socklist *psl;
 	int i, j, rv;
 
@@ -1852,7 +1852,7 @@
 	u32 addr = msf->imsf_multiaddr;
 	struct ip_mc_socklist *pmc;
 	struct in_device *in_dev;
-	struct inet_opt *inet = inet_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
 	struct ip_sf_socklist *newpsl, *psl;
 
 	if (!MULTICAST(addr))
@@ -1922,7 +1922,7 @@
 	u32 addr = msf->imsf_multiaddr;
 	struct ip_mc_socklist *pmc;
 	struct in_device *in_dev;
-	struct inet_opt *inet = inet_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
 	struct ip_sf_socklist *psl;
 
 	if (!MULTICAST(addr))
@@ -1980,7 +1980,7 @@
 	struct sockaddr_in *psin;
 	u32 addr;
 	struct ip_mc_socklist *pmc;
-	struct inet_opt *inet = inet_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
 	struct ip_sf_socklist *psl;
 
 	psin = (struct sockaddr_in *)&gsf->gf_group;
@@ -2033,7 +2033,7 @@
  */
 int ip_mc_sf_allow(struct sock *sk, u32 loc_addr, u32 rmt_addr, int dif)
 {
-	struct inet_opt *inet = inet_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
 	struct ip_mc_socklist *pmc;
 	struct ip_sf_socklist *psl;
 	int i;
@@ -2069,7 +2069,7 @@
 
 void ip_mc_drop_socket(struct sock *sk)
 {
-	struct inet_opt *inet = inet_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
 	struct ip_mc_socklist *iml;
 
 	if (inet->mc_list == NULL)
diff -Nru a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c
--- a/net/ipv4/inetpeer.c	2005-03-01 23:39:16 -08:00
+++ b/net/ipv4/inetpeer.c	2005-03-01 23:39:16 -08:00
@@ -70,7 +70,7 @@
  */
 
 /* Exported for inet_getid inline function.  */
-spinlock_t inet_peer_idlock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(inet_peer_idlock);
 
 static kmem_cache_t *peer_cachep;
 
@@ -82,7 +82,7 @@
 };
 #define peer_avl_empty (&peer_fake_node)
 static struct inet_peer *peer_root = peer_avl_empty;
-static rwlock_t peer_pool_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(peer_pool_lock);
 #define PEER_MAXDEPTH 40 /* sufficient for about 2^27 nodes */
 
 static volatile int peer_total;
@@ -95,7 +95,7 @@
 /* Exported for inet_putpeer inline function.  */
 struct inet_peer *inet_peer_unused_head,
 		**inet_peer_unused_tailp = &inet_peer_unused_head;
-spinlock_t inet_peer_unused_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(inet_peer_unused_lock);
 #define PEER_MAX_CLEANUP_WORK 30
 
 static void peer_check_expire(unsigned long dummy);
diff -Nru a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
--- a/net/ipv4/ip_fragment.c	2005-03-01 23:38:54 -08:00
+++ b/net/ipv4/ip_fragment.c	2005-03-01 23:38:54 -08:00
@@ -73,6 +73,7 @@
 struct ipq {
 	struct ipq	*next;		/* linked list pointers			*/
 	struct list_head lru_list;	/* lru list member 			*/
+	u32		user;
 	u32		saddr;
 	u32		daddr;
 	u16		id;
@@ -99,7 +100,7 @@
 
 /* Per-bucket lock is easy to add now. */
 static struct ipq *ipq_hash[IPQ_HASHSZ];
-static rwlock_t ipfrag_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(ipfrag_lock);
 static u32 ipfrag_hash_rnd;
 static LIST_HEAD(ipq_lru_list);
 int ip_frag_nqueues = 0;
@@ -243,13 +244,13 @@
 /* Memory limiting on fragments.  Evictor trashes the oldest 
  * fragment queue until we are back under the threshold.
  */
-static void __ip_evictor(int threshold)
+static void ip_evictor(void)
 {
 	struct ipq *qp;
 	struct list_head *tmp;
 	int work;
 
-	work = atomic_read(&ip_frag_mem) - threshold;
+	work = atomic_read(&ip_frag_mem) - sysctl_ipfrag_low_thresh;
 	if (work <= 0)
 		return;
 
@@ -274,11 +275,6 @@
 	}
 }
 
-static inline void ip_evictor(void)
-{
-	__ip_evictor(sysctl_ipfrag_low_thresh);
-}
-
 /*
  * Oops, a fragment queue timed out.  Kill it and send an ICMP reply.
  */
@@ -325,7 +321,8 @@
 		if(qp->id == qp_in->id		&&
 		   qp->saddr == qp_in->saddr	&&
 		   qp->daddr == qp_in->daddr	&&
-		   qp->protocol == qp_in->protocol) {
+		   qp->protocol == qp_in->protocol &&
+		   qp->user == qp_in->user) {
 			atomic_inc(&qp->refcnt);
 			write_unlock(&ipfrag_lock);
 			qp_in->last_in |= COMPLETE;
@@ -352,7 +349,7 @@
 }
 
 /* Add an entry to the 'ipq' queue for a newly received IP datagram. */
-static struct ipq *ip_frag_create(unsigned hash, struct iphdr *iph)
+static struct ipq *ip_frag_create(unsigned hash, struct iphdr *iph, u32 user)
 {
 	struct ipq *qp;
 
@@ -364,6 +361,7 @@
 	qp->id = iph->id;
 	qp->saddr = iph->saddr;
 	qp->daddr = iph->daddr;
+	qp->user = user;
 	qp->len = 0;
 	qp->meat = 0;
 	qp->fragments = NULL;
@@ -386,7 +384,7 @@
 /* Find the correct entry in the "incomplete datagrams" queue for
  * this IP datagram, and create new one, if nothing is found.
  */
-static inline struct ipq *ip_find(struct iphdr *iph)
+static inline struct ipq *ip_find(struct iphdr *iph, u32 user)
 {
 	__u16 id = iph->id;
 	__u32 saddr = iph->saddr;
@@ -400,7 +398,8 @@
 		if(qp->id == id		&&
 		   qp->saddr == saddr	&&
 		   qp->daddr == daddr	&&
-		   qp->protocol == protocol) {
+		   qp->protocol == protocol &&
+		   qp->user == user) {
 			atomic_inc(&qp->refcnt);
 			read_unlock(&ipfrag_lock);
 			return qp;
@@ -408,7 +407,7 @@
 	}
 	read_unlock(&ipfrag_lock);
 
-	return ip_frag_create(hash, iph);
+	return ip_frag_create(hash, iph, user);
 }
 
 /* Add new segment to existing queue. */
@@ -642,7 +641,7 @@
 }
 
 /* Process an incoming IP datagram fragment. */
-struct sk_buff *ip_defrag(struct sk_buff *skb)
+struct sk_buff *ip_defrag(struct sk_buff *skb, u32 user)
 {
 	struct iphdr *iph = skb->nh.iph;
 	struct ipq *qp;
@@ -657,7 +656,7 @@
 	dev = skb->dev;
 
 	/* Lookup (or create) queue header */
-	if ((qp = ip_find(iph)) != NULL) {
+	if ((qp = ip_find(iph, user)) != NULL) {
 		struct sk_buff *ret = NULL;
 
 		spin_lock(&qp->lock);
@@ -689,10 +688,4 @@
 	add_timer(&ipfrag_secret_timer);
 }
 
-void ipfrag_flush(void)
-{
-	__ip_evictor(0);
-}
-
 EXPORT_SYMBOL(ip_defrag);
-EXPORT_SYMBOL(ipfrag_flush);
diff -Nru a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
--- a/net/ipv4/ip_gre.c	2005-03-01 23:39:08 -08:00
+++ b/net/ipv4/ip_gre.c	2005-03-01 23:39:08 -08:00
@@ -152,7 +152,7 @@
 #define tunnels_l	(tunnels[1])
 #define tunnels_wc	(tunnels[0])
 
-static rwlock_t ipgre_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(ipgre_lock);
 
 /* Given src, dst and key, find appropriate for input tunnel. */
 
@@ -304,7 +304,7 @@
 }
 
 
-void ipgre_err(struct sk_buff *skb, u32 info)
+static void ipgre_err(struct sk_buff *skb, u32 info)
 {
 #ifndef I_WISH_WORLD_WERE_PERFECT
 
@@ -552,7 +552,7 @@
 	return INET_ECN_encapsulate(tos, inner);
 }
 
-int ipgre_rcv(struct sk_buff *skb)
+static int ipgre_rcv(struct sk_buff *skb)
 {
 	struct iphdr *iph;
 	u8     *h;
@@ -1279,7 +1279,7 @@
 	goto out;
 }
 
-void ipgre_fini(void)
+static void ipgre_fini(void)
 {
 	if (inet_del_protocol(&ipgre_protocol, IPPROTO_GRE) < 0)
 		printk(KERN_INFO "ipgre close: can't remove protocol\n");
diff -Nru a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
--- a/net/ipv4/ip_input.c	2005-03-01 23:38:52 -08:00
+++ b/net/ipv4/ip_input.c	2005-03-01 23:38:52 -08:00
@@ -172,7 +172,7 @@
 		    (!sk->sk_bound_dev_if ||
 		     sk->sk_bound_dev_if == skb->dev->ifindex)) {
 			if (skb->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) {
-				skb = ip_defrag(skb);
+				skb = ip_defrag(skb, IP_DEFRAG_CALL_RA_CHAIN);
 				if (skb == NULL) {
 					read_unlock(&ip_ra_lock);
 					return 1;
@@ -273,7 +273,7 @@
 	 */
 
 	if (skb->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) {
-		skb = ip_defrag(skb);
+		skb = ip_defrag(skb, IP_DEFRAG_LOCAL_DELIVER);
 		if (!skb)
 			return 0;
 	}
diff -Nru a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
--- a/net/ipv4/ip_output.c	2005-03-01 23:39:17 -08:00
+++ b/net/ipv4/ip_output.c	2005-03-01 23:39:17 -08:00
@@ -115,7 +115,7 @@
 	return 0;
 }
 
-static inline int ip_select_ttl(struct inet_opt *inet, struct dst_entry *dst)
+static inline int ip_select_ttl(struct inet_sock *inet, struct dst_entry *dst)
 {
 	int ttl = inet->uc_ttl;
 
@@ -131,7 +131,7 @@
 int ip_build_and_send_pkt(struct sk_buff *skb, struct sock *sk,
 			  u32 saddr, u32 daddr, struct ip_options *opt)
 {
-	struct inet_opt *inet = inet_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
 	struct rtable *rt = (struct rtable *)skb->dst;
 	struct iphdr *iph;
 
@@ -297,7 +297,7 @@
 int ip_queue_xmit(struct sk_buff *skb, int ipfragok)
 {
 	struct sock *sk = skb->sk;
-	struct inet_opt *inet = inet_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
 	struct ip_options *opt = inet->opt;
 	struct rtable *rt;
 	struct iphdr *iph;
@@ -389,6 +389,7 @@
 	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;
 
@@ -504,6 +505,7 @@
 			/* Prepare header of the next frame,
 			 * before previous one went down. */
 			if (frag) {
+				frag->ip_summed = CHECKSUM_NONE;
 				frag->h.raw = frag->data;
 				frag->nh.raw = __skb_push(frag, hlen);
 				memcpy(frag->nh.raw, iph, hlen);
@@ -712,7 +714,7 @@
 		   struct ipcm_cookie *ipc, struct rtable *rt,
 		   unsigned int flags)
 {
-	struct inet_opt *inet = inet_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
 	struct sk_buff *skb;
 
 	struct ip_options *opt = NULL;
@@ -973,7 +975,7 @@
 ssize_t	ip_append_page(struct sock *sk, struct page *page,
 		       int offset, size_t size, int flags)
 {
-	struct inet_opt *inet = inet_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
 	struct sk_buff *skb;
 	struct rtable *rt;
 	struct ip_options *opt = NULL;
@@ -1112,7 +1114,7 @@
 {
 	struct sk_buff *skb, *tmp_skb;
 	struct sk_buff **tail_skb;
-	struct inet_opt *inet = inet_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
 	struct ip_options *opt = NULL;
 	struct rtable *rt = inet->cork.rt;
 	struct iphdr *iph;
@@ -1217,7 +1219,7 @@
  */
 void ip_flush_pending_frames(struct sock *sk)
 {
-	struct inet_opt *inet = inet_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
 	struct sk_buff *skb;
 
 	while ((skb = __skb_dequeue_tail(&sk->sk_write_queue)) != NULL)
@@ -1260,7 +1262,7 @@
 void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *arg,
 		   unsigned int len)
 {
-	struct inet_opt *inet = inet_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
 	struct {
 		struct ip_options	opt;
 		char			data[40];
diff -Nru a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
--- a/net/ipv4/ip_sockglue.c	2005-03-01 23:38:54 -08:00
+++ b/net/ipv4/ip_sockglue.c	2005-03-01 23:38:54 -08:00
@@ -92,7 +92,7 @@
 }
 
 
-void ip_cmsg_recv_retopts(struct msghdr *msg, struct sk_buff *skb)
+static void ip_cmsg_recv_retopts(struct msghdr *msg, struct sk_buff *skb)
 {
 	unsigned char optbuf[sizeof(struct ip_options) + 40];
 	struct ip_options * opt = (struct ip_options*)optbuf;
@@ -112,7 +112,7 @@
 
 void ip_cmsg_recv(struct msghdr *msg, struct sk_buff *skb)
 {
-	struct inet_opt *inet = inet_sk(skb->sk);
+	struct inet_sock *inet = inet_sk(skb->sk);
 	unsigned flags = inet->cmsg_flags;
 
 	/* Ordered by supposed usage frequency */
@@ -186,7 +186,7 @@
    sent to multicast group to reach destination designated router.
  */
 struct ip_ra_chain *ip_ra_chain;
-rwlock_t ip_ra_lock = RW_LOCK_UNLOCKED;
+DEFINE_RWLOCK(ip_ra_lock);
 
 int ip_ra_control(struct sock *sk, unsigned char on, void (*destructor)(struct sock *))
 {
@@ -234,7 +234,7 @@
 void ip_icmp_error(struct sock *sk, struct sk_buff *skb, int err, 
 		   u16 port, u32 info, u8 *payload)
 {
-	struct inet_opt *inet = inet_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
 	struct sock_exterr_skb *serr;
 
 	if (!inet->recverr)
@@ -263,7 +263,7 @@
 
 void ip_local_error(struct sock *sk, int err, u32 daddr, u16 port, u32 info)
 {
-	struct inet_opt *inet = inet_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
 	struct sock_exterr_skb *serr;
 	struct iphdr *iph;
 	struct sk_buff *skb;
@@ -342,7 +342,7 @@
 	sin = &errhdr.offender;
 	sin->sin_family = AF_UNSPEC;
 	if (serr->ee.ee_origin == SO_EE_ORIGIN_ICMP) {
-		struct inet_opt *inet = inet_sk(sk);
+		struct inet_sock *inet = inet_sk(sk);
 
 		sin->sin_family = AF_INET;
 		sin->sin_addr.s_addr = skb->nh.iph->saddr;
@@ -383,7 +383,7 @@
 
 int ip_setsockopt(struct sock *sk, int level, int optname, char __user *optval, int optlen)
 {
-	struct inet_opt *inet = inet_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
 	int val=0,err;
 
 	if (level != SOL_IP)
@@ -429,7 +429,7 @@
 			if (err)
 				break;
 			if (sk->sk_type == SOCK_STREAM) {
-				struct tcp_opt *tp = tcp_sk(sk);
+				struct tcp_sock *tp = tcp_sk(sk);
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 				if (sk->sk_family == PF_INET ||
 				    (!((1 << sk->sk_state) &
@@ -875,7 +875,7 @@
 
 int ip_getsockopt(struct sock *sk, int level, int optname, char __user *optval, int __user *optlen)
 {
-	struct inet_opt *inet = inet_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
 	int val;
 	int len;
 	
diff -Nru a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c
--- a/net/ipv4/ipcomp.c	2005-03-01 23:39:09 -08:00
+++ b/net/ipv4/ipcomp.c	2005-03-01 23:39:09 -08:00
@@ -472,7 +472,7 @@
 			goto error_tunnel;
 	}
 
-	calg_desc = xfrm_calg_get_byname(x->calg->alg_name);
+	calg_desc = xfrm_calg_get_byname(x->calg->alg_name, 0);
 	BUG_ON(!calg_desc);
 	ipcd->threshold = calg_desc->uinfo.comp.threshold;
 	x->data = ipcd;
diff -Nru a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c
--- a/net/ipv4/ipconfig.c	2005-03-01 23:38:51 -08:00
+++ b/net/ipv4/ipconfig.c	2005-03-01 23:38:51 -08:00
@@ -53,6 +53,7 @@
 #include <linux/seq_file.h>
 #include <linux/major.h>
 #include <linux/root_dev.h>
+#include <linux/delay.h>
 #include <net/arp.h>
 #include <net/ip.h>
 #include <net/ipconfig.h>
@@ -84,8 +85,8 @@
 #endif
 
 /* Define the friendly delay before and after opening net devices */
-#define CONF_PRE_OPEN		(HZ/2)	/* Before opening: 1/2 second */
-#define CONF_POST_OPEN		(1*HZ)	/* After opening: 1 second */
+#define CONF_PRE_OPEN		500	/* Before opening: 1/2 second */
+#define CONF_POST_OPEN		1	/* After opening: 1 second */
 
 /* Define the timeout for waiting for a DHCP/BOOTP/RARP reply */
 #define CONF_OPEN_RETRIES 	2	/* (Re)open devices twice */
@@ -109,7 +110,7 @@
  */
 int ic_set_manually __initdata = 0;		/* IPconfig parameters set manually */
 
-int ic_enable __initdata = 0;			/* IP config enabled? */
+static int ic_enable __initdata = 0;		/* IP config enabled? */
 
 /* Protocol choice */
 int ic_proto_enabled __initdata = 0
@@ -124,10 +125,10 @@
 #endif
 			;
 
-int ic_host_name_set __initdata = 0;		/* Host name set by us? */
+static int ic_host_name_set __initdata = 0;	/* Host name set by us? */
 
 u32 ic_myaddr = INADDR_NONE;		/* My IP address */
-u32 ic_netmask = INADDR_NONE;	/* Netmask for local subnet */
+static u32 ic_netmask = INADDR_NONE;	/* Netmask for local subnet */
 u32 ic_gateway = INADDR_NONE;	/* Gateway IP address */
 
 u32 ic_servaddr = INADDR_NONE;	/* Boot server IP address */
@@ -137,9 +138,9 @@
 
 /* Persistent data: */
 
-int ic_proto_used;			/* Protocol used, if any */
-u32 ic_nameservers[CONF_NAMESERVERS_MAX]; /* DNS Server IP addresses */
-u8 ic_domain[64];		/* DNS (not NIS) domain name */
+static int ic_proto_used;			/* Protocol used, if any */
+static u32 ic_nameservers[CONF_NAMESERVERS_MAX]; /* DNS Server IP addresses */
+static u8 ic_domain[64];		/* DNS (not NIS) domain name */
 
 /*
  * Private state.
@@ -152,7 +153,7 @@
 static int ic_proto_have_if __initdata = 0;
 
 #ifdef IPCONFIG_DYNAMIC
-static spinlock_t ic_recv_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(ic_recv_lock);
 static volatile int ic_got_reply __initdata = 0;    /* Proto(s) that replied */
 #endif
 #ifdef IPCONFIG_DHCP
@@ -1232,7 +1233,7 @@
 		if (*cp == ':')
 			*cp++ = '\0';
 		addr = in_aton(name);
-		strcpy(name, cp);
+		memmove(name, cp, strlen(cp) + 1);
 	} else
 		addr = INADDR_NONE;
 
@@ -1259,16 +1260,14 @@
  try_try_again:
 #endif
 	/* Give hardware a chance to settle */
-	set_current_state(TASK_UNINTERRUPTIBLE);
-	schedule_timeout(CONF_PRE_OPEN);
+	msleep(CONF_PRE_OPEN);
 
 	/* Setup all network devices */
 	if (ic_open_devs() < 0)
 		return -1;
 
 	/* Give drivers a chance to settle */
-	set_current_state(TASK_UNINTERRUPTIBLE);
-	schedule_timeout(CONF_POST_OPEN);
+	ssleep(CONF_POST_OPEN);
 
 	/*
 	 * If the config information is insufficient (e.g., our IP address or
diff -Nru a/net/ipv4/ipip.c b/net/ipv4/ipip.c
--- a/net/ipv4/ipip.c	2005-03-01 23:39:19 -08:00
+++ b/net/ipv4/ipip.c	2005-03-01 23:39:19 -08:00
@@ -132,7 +132,7 @@
 static struct ip_tunnel *tunnels_wc[1];
 static struct ip_tunnel **tunnels[4] = { tunnels_wc, tunnels_l, tunnels_r, tunnels_r_l };
 
-static rwlock_t ipip_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(ipip_lock);
 
 static struct ip_tunnel * ipip_tunnel_lookup(u32 remote, u32 local)
 {
diff -Nru a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
--- a/net/ipv4/ipmr.c	2005-03-01 23:38:57 -08:00
+++ b/net/ipv4/ipmr.c	2005-03-01 23:38:57 -08:00
@@ -73,7 +73,7 @@
    Note that the changes are semaphored via rtnl_lock.
  */
 
-static rwlock_t mrt_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(mrt_lock);
 
 /*
  *	Multicast router control variables
@@ -93,7 +93,7 @@
 static atomic_t cache_resolve_queue_len;		/* Size of unresolved	*/
 
 /* Special spinlock for queue of unresolved entries */
-static spinlock_t mfc_unres_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(mfc_unres_lock);
 
 /* We return to original Alan's scheme. Hash table of resolved
    entries is changed only in process context and protected
diff -Nru a/net/ipv4/ipvs/ip_vs_app.c b/net/ipv4/ipvs/ip_vs_app.c
--- a/net/ipv4/ipvs/ip_vs_app.c	2005-03-01 23:38:44 -08:00
+++ b/net/ipv4/ipvs/ip_vs_app.c	2005-03-01 23:38:44 -08:00
@@ -65,7 +65,7 @@
 /*
  *	Allocate/initialize app incarnation and register it in proto apps.
  */
-int
+static int
 ip_vs_app_inc_new(struct ip_vs_app *app, __u16 proto, __u16 port)
 {
 	struct ip_vs_protocol *pp;
diff -Nru a/net/ipv4/ipvs/ip_vs_conn.c b/net/ipv4/ipvs/ip_vs_conn.c
--- a/net/ipv4/ipvs/ip_vs_conn.c	2005-03-01 23:39:16 -08:00
+++ b/net/ipv4/ipvs/ip_vs_conn.c	2005-03-01 23:39:16 -08:00
@@ -64,7 +64,7 @@
 } __attribute__((__aligned__(SMP_CACHE_BYTES)));
 
 /* lock array for conn table */
-struct ip_vs_aligned_lock
+static struct ip_vs_aligned_lock
 __ip_vs_conntbl_lock_array[CT_LOCKARRAY_SIZE] __cacheline_aligned;
 
 static inline void ct_read_lock(unsigned key)
diff -Nru a/net/ipv4/ipvs/ip_vs_core.c b/net/ipv4/ipvs/ip_vs_core.c
--- a/net/ipv4/ipvs/ip_vs_core.c	2005-03-01 23:38:44 -08:00
+++ b/net/ipv4/ipvs/ip_vs_core.c	2005-03-01 23:38:44 -08:00
@@ -57,7 +57,6 @@
 #ifdef CONFIG_IP_VS_DEBUG
 EXPORT_SYMBOL(ip_vs_get_debug_level);
 #endif
-EXPORT_SYMBOL(check_for_ip_vs_out);
 EXPORT_SYMBOL(ip_vs_make_skb_writable);
 
 
@@ -545,9 +544,9 @@
 }
 
 static inline struct sk_buff *
-ip_vs_gather_frags(struct sk_buff *skb)
+ip_vs_gather_frags(struct sk_buff *skb, u_int32_t user)
 {
-	skb = ip_defrag(skb);
+	skb = ip_defrag(skb, user);
 	if (skb)
 		ip_send_check(skb->nh.iph);
 	return skb;
@@ -621,7 +620,7 @@
 
 	/* reassemble IP fragments */
 	if (skb->nh.iph->frag_off & __constant_htons(IP_MF|IP_OFFSET)) {
-		skb = ip_vs_gather_frags(skb);
+		skb = ip_vs_gather_frags(skb, IP_DEFRAG_VS_OUT);
 		if (!skb)
 			return NF_STOLEN;
 		*pskb = skb;
@@ -760,7 +759,7 @@
 	/* reassemble IP fragments */
 	if (unlikely(iph->frag_off & __constant_htons(IP_MF|IP_OFFSET) &&
 		     !pp->dont_defrag)) {
-		skb = ip_vs_gather_frags(skb);
+		skb = ip_vs_gather_frags(skb, IP_DEFRAG_VS_OUT);
 		if (!skb)
 			return NF_STOLEN;
 		iph = skb->nh.iph;
@@ -835,37 +834,13 @@
 
 
 /*
- *      Check if the packet is for VS/NAT connections, then send it
- *      immediately.
- *      Called by ip_fw_compact to detect packets for VS/NAT before
- *      they are changed by ipchains masquerading code.
- */
-unsigned int
-check_for_ip_vs_out(struct sk_buff **pskb, int (*okfn)(struct sk_buff *))
-{
-	unsigned int ret;
-
-	ret = ip_vs_out(NF_IP_FORWARD, pskb, NULL, NULL, NULL);
-	if (ret != NF_ACCEPT) {
-		return ret;
-	} else {
-		/* send the packet immediately if it is already mangled
-		   by ip_vs_out */
-		if ((*pskb)->nfcache & NFC_IPVS_PROPERTY) {
-			(*okfn)(*pskb);
-			return NF_STOLEN;
-		}
-	}
-	return NF_ACCEPT;
-}
-
-/*
  *	Handle ICMP messages in the outside-to-inside direction (incoming).
  *	Find any that might be relevant, check against existing connections,
  *	forward to the right destination host if relevant.
  *	Currently handles error types - unreachable, quench, ttl exceeded.
  */
-static int ip_vs_in_icmp(struct sk_buff **pskb, int *related)
+static int 
+ip_vs_in_icmp(struct sk_buff **pskb, int *related, unsigned int hooknum)
 {
 	struct sk_buff *skb = *pskb;
 	struct iphdr *iph;
@@ -879,7 +854,9 @@
 
 	/* reassemble IP fragments */
 	if (skb->nh.iph->frag_off & __constant_htons(IP_MF|IP_OFFSET)) {
-		skb = ip_vs_gather_frags(skb);
+		skb = ip_vs_gather_frags(skb,
+		                         hooknum == NF_IP_LOCAL_IN ?
+					 IP_DEFRAG_VS_IN : IP_DEFRAG_VS_FWD);
 		if (!skb)
 			return NF_STOLEN;
 		*pskb = skb;
@@ -988,7 +965,7 @@
 
 	iph = skb->nh.iph;
 	if (unlikely(iph->protocol == IPPROTO_ICMP)) {
-		int related, verdict = ip_vs_in_icmp(pskb, &related);
+		int related, verdict = ip_vs_in_icmp(pskb, &related, hooknum);
 
 		if (related)
 			return verdict;
@@ -1083,7 +1060,7 @@
 	if ((*pskb)->nh.iph->protocol != IPPROTO_ICMP)
 		return NF_ACCEPT;
 
-	return ip_vs_in_icmp(pskb, &r);
+	return ip_vs_in_icmp(pskb, &r, hooknum);
 }
 
 
diff -Nru a/net/ipv4/ipvs/ip_vs_ctl.c b/net/ipv4/ipvs/ip_vs_ctl.c
--- a/net/ipv4/ipvs/ip_vs_ctl.c	2005-03-01 23:39:16 -08:00
+++ b/net/ipv4/ipvs/ip_vs_ctl.c	2005-03-01 23:39:16 -08:00
@@ -45,24 +45,24 @@
 static DECLARE_MUTEX(__ip_vs_mutex);
 
 /* lock for service table */
-static rwlock_t __ip_vs_svc_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(__ip_vs_svc_lock);
 
 /* lock for table with the real services */
-static rwlock_t __ip_vs_rs_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(__ip_vs_rs_lock);
 
 /* lock for state and timeout tables */
-static rwlock_t __ip_vs_securetcp_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(__ip_vs_securetcp_lock);
 
 /* lock for drop entry handling */
-static spinlock_t __ip_vs_dropentry_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(__ip_vs_dropentry_lock);
 
 /* lock for drop packet handling */
-static spinlock_t __ip_vs_droppacket_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(__ip_vs_droppacket_lock);
 
 /* 1/rate drop and drop-entry variables */
 int ip_vs_drop_rate = 0;
 int ip_vs_drop_counter = 0;
-atomic_t ip_vs_dropentry = ATOMIC_INIT(0);
+static atomic_t ip_vs_dropentry = ATOMIC_INIT(0);
 
 /* number of virtual services */
 static int ip_vs_num_services = 0;
diff -Nru a/net/ipv4/ipvs/ip_vs_est.c b/net/ipv4/ipvs/ip_vs_est.c
--- a/net/ipv4/ipvs/ip_vs_est.c	2005-03-01 23:38:51 -08:00
+++ b/net/ipv4/ipvs/ip_vs_est.c	2005-03-01 23:38:51 -08:00
@@ -62,7 +62,7 @@
 
 
 static struct ip_vs_estimator *est_list = NULL;
-static rwlock_t est_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(est_lock);
 static struct timer_list est_timer;
 
 static void estimation_timer(unsigned long arg)
diff -Nru a/net/ipv4/ipvs/ip_vs_proto.c b/net/ipv4/ipvs/ip_vs_proto.c
--- a/net/ipv4/ipvs/ip_vs_proto.c	2005-03-01 23:38:56 -08:00
+++ b/net/ipv4/ipvs/ip_vs_proto.c	2005-03-01 23:38:56 -08:00
@@ -45,7 +45,7 @@
 /*
  *	register an ipvs protocol
  */
-int register_ip_vs_protocol(struct ip_vs_protocol *pp)
+static int register_ip_vs_protocol(struct ip_vs_protocol *pp)
 {
 	unsigned hash = IP_VS_PROTO_HASH(pp->protocol);
 
@@ -62,7 +62,7 @@
 /*
  *	unregister an ipvs protocol
  */
-int unregister_ip_vs_protocol(struct ip_vs_protocol *pp)
+static int unregister_ip_vs_protocol(struct ip_vs_protocol *pp)
 {
 	struct ip_vs_protocol **pp_p;
 	unsigned hash = IP_VS_PROTO_HASH(pp->protocol);
diff -Nru a/net/ipv4/ipvs/ip_vs_proto_icmp.c b/net/ipv4/ipvs/ip_vs_proto_icmp.c
--- a/net/ipv4/ipvs/ip_vs_proto_icmp.c	2005-03-01 23:38:51 -08:00
+++ b/net/ipv4/ipvs/ip_vs_proto_icmp.c	2005-03-01 23:38:51 -08:00
@@ -22,7 +22,7 @@
 
 static char * icmp_state_name_table[1] = { "ICMP" };
 
-struct ip_vs_conn *
+static struct ip_vs_conn *
 icmp_conn_in_get(const struct sk_buff *skb,
 		 struct ip_vs_protocol *pp,
 		 const struct iphdr *iph,
@@ -49,7 +49,7 @@
 #endif
 }
 
-struct ip_vs_conn *
+static struct ip_vs_conn *
 icmp_conn_out_get(const struct sk_buff *skb,
 		  struct ip_vs_protocol *pp,
 		  const struct iphdr *iph,
diff -Nru a/net/ipv4/ipvs/ip_vs_proto_tcp.c b/net/ipv4/ipvs/ip_vs_proto_tcp.c
--- a/net/ipv4/ipvs/ip_vs_proto_tcp.c	2005-03-01 23:38:54 -08:00
+++ b/net/ipv4/ipvs/ip_vs_proto_tcp.c	2005-03-01 23:38:54 -08:00
@@ -510,7 +510,7 @@
 #define	TCP_APP_TAB_MASK	(TCP_APP_TAB_SIZE - 1)
 
 static struct list_head tcp_apps[TCP_APP_TAB_SIZE];
-static spinlock_t tcp_app_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(tcp_app_lock);
 
 static inline __u16 tcp_app_hashkey(__u16 port)
 {
diff -Nru a/net/ipv4/ipvs/ip_vs_proto_udp.c b/net/ipv4/ipvs/ip_vs_proto_udp.c
--- a/net/ipv4/ipvs/ip_vs_proto_udp.c	2005-03-01 23:39:18 -08:00
+++ b/net/ipv4/ipvs/ip_vs_proto_udp.c	2005-03-01 23:39:18 -08:00
@@ -277,7 +277,7 @@
 #define	UDP_APP_TAB_MASK	(UDP_APP_TAB_SIZE - 1)
 
 static struct list_head udp_apps[UDP_APP_TAB_SIZE];
-static spinlock_t udp_app_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(udp_app_lock);
 
 static inline __u16 udp_app_hashkey(__u16 port)
 {
diff -Nru a/net/ipv4/ipvs/ip_vs_sched.c b/net/ipv4/ipvs/ip_vs_sched.c
--- a/net/ipv4/ipvs/ip_vs_sched.c	2005-03-01 23:38:51 -08:00
+++ b/net/ipv4/ipvs/ip_vs_sched.c	2005-03-01 23:38:51 -08:00
@@ -33,7 +33,7 @@
 static LIST_HEAD(ip_vs_schedulers);
 
 /* lock for service table */
-static rwlock_t __ip_vs_sched_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(__ip_vs_sched_lock);
 
 
 /*
diff -Nru a/net/ipv4/ipvs/ip_vs_sync.c b/net/ipv4/ipvs/ip_vs_sync.c
--- a/net/ipv4/ipvs/ip_vs_sync.c	2005-03-01 23:39:18 -08:00
+++ b/net/ipv4/ipvs/ip_vs_sync.c	2005-03-01 23:39:18 -08:00
@@ -23,7 +23,7 @@
 #include <linux/slab.h>
 #include <linux/net.h>
 #include <linux/completion.h>
-
+#include <linux/delay.h>
 #include <linux/skbuff.h>
 #include <linux/in.h>
 #include <linux/igmp.h>                 /* for ip_mc_join_group */
@@ -119,11 +119,11 @@
 
 /* the sync_buff list head and the lock */
 static LIST_HEAD(ip_vs_sync_queue);
-static spinlock_t ip_vs_sync_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(ip_vs_sync_lock);
 
 /* current sync_buff for accepting new conn entries */
 static struct ip_vs_sync_buff   *curr_sb = NULL;
-static spinlock_t curr_sb_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(curr_sb_lock);
 
 /* ipvs sync daemon state */
 volatile int ip_vs_sync_state = IP_VS_STATE_NONE;
@@ -343,7 +343,7 @@
  */
 static void set_mcast_loop(struct sock *sk, u_char loop)
 {
-	struct inet_opt *inet = inet_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
 
 	/* setsockopt(sock, SOL_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop)); */
 	lock_sock(sk);
@@ -356,7 +356,7 @@
  */
 static void set_mcast_ttl(struct sock *sk, u_char ttl)
 {
-	struct inet_opt *inet = inet_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
 
 	/* setsockopt(sock, SOL_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)); */
 	lock_sock(sk);
@@ -370,7 +370,7 @@
 static int set_mcast_if(struct sock *sk, char *ifname)
 {
 	struct net_device *dev;
-	struct inet_opt *inet = inet_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
 
 	if ((dev = __dev_get_by_name(ifname)) == NULL)
 		return -ENODEV;
@@ -647,8 +647,7 @@
 		if (stop_master_sync)
 			break;
 
-		__set_current_state(TASK_INTERRUPTIBLE);
-		schedule_timeout(HZ);
+		ssleep(1);
 	}
 
 	/* clean up the sync_buff queue */
@@ -705,8 +704,7 @@
 		if (stop_backup_sync)
 			break;
 
-		__set_current_state(TASK_INTERRUPTIBLE);
-		schedule_timeout(HZ);
+		ssleep(1);
 	}
 
 	/* release the sending multicast socket */
@@ -818,8 +816,7 @@
 	if ((pid = kernel_thread(sync_thread, startup, 0)) < 0) {
 		IP_VS_ERR("could not create sync_thread due to %d... "
 			  "retrying.\n", pid);
-		current->state = TASK_UNINTERRUPTIBLE;
-		schedule_timeout(HZ);
+		ssleep(1);
 		goto repeat;
 	}
 
@@ -853,8 +850,7 @@
 	if ((pid = kernel_thread(fork_sync_thread, &startup, 0)) < 0) {
 		IP_VS_ERR("could not create fork_sync_thread due to %d... "
 			  "retrying.\n", pid);
-		current->state = TASK_UNINTERRUPTIBLE;
-		schedule_timeout(HZ);
+		ssleep(1);
 		goto repeat;
 	}
 
diff -Nru a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
--- a/net/ipv4/netfilter/Kconfig	2005-03-01 23:39:09 -08:00
+++ b/net/ipv4/netfilter/Kconfig	2005-03-01 23:39:09 -08:00
@@ -48,7 +48,7 @@
 	  be able to do state tracking on SCTP connections.
 
 	  If you want to compile it as a module, say M here and read
-	  Documentation/modules.txt.  If unsure, say `N'.
+	  <file:Documentation/modules.txt>.  If unsure, say `N'.
 
 config IP_NF_FTP
 	tristate "FTP protocol support"
@@ -313,7 +313,7 @@
 	  eg. UNICAST, LOCAL, BROADCAST, ...
 	
 	  If you want to compile it as a module, say M here and read
-	  Documentation/modules.txt.  If unsure, say `N'.
+	  <file:Documentation/modules.txt>.  If unsure, say `N'.
 
 config IP_NF_MATCH_REALM
 	tristate  'realm match support'
@@ -321,13 +321,13 @@
 	select NET_CLS_ROUTE
 	help
 	  This option adds a `realm' match, which allows you to use the realm
-	  key from the routing subsytem inside iptables.
+	  key from the routing subsystem inside iptables.
 	
 	  This match pretty much resembles the CONFIG_NET_CLS_ROUTE4 option 
 	  in tc world.
 	
 	  If you want to compile it as a module, say M here and read
-	  Documentation/modules.txt.  If unsure, say `N'.
+	  <file:Documentation/modules.txt>.  If unsure, say `N'.
 
 config IP_NF_MATCH_SCTP
 	tristate  'SCTP protocol match support'
@@ -338,7 +338,7 @@
 	  and SCTP chunk types.
 
 	  If you want to compile it as a module, say M here and read
-	  Documentation/modules.txt.  If unsure, say `N'.
+	  <file:Documentation/modules.txt>.  If unsure, say `N'.
 
 config IP_NF_MATCH_COMMENT
 	tristate  'comment match support'
@@ -348,7 +348,7 @@
 	  comments in your iptables ruleset.
 
 	  If you want to compile it as a module, say M here and read
-	  Documentation/modules.txt.  If unsure, say `N'.
+	  <file:Documentation/modules.txt>.  If unsure, say `N'.
 
 config IP_NF_MATCH_CONNMARK
 	tristate  'Connection mark match support'
@@ -358,7 +358,7 @@
 	  connection mark value previously set for the session by `CONNMARK'. 
 	
 	  If you want to compile it as a module, say M here and read
-	  Documentation/modules.txt.  The module will be called
+	  <file:Documentation/modules.txt>.  The module will be called
 	  ipt_connmark.o.  If unsure, say `N'.
 
 config IP_NF_MATCH_HASHLIMIT
@@ -458,7 +458,7 @@
 
 config IP_NF_NAT_NEEDED
 	bool
-	depends on IP_NF_CONNTRACK!=y && IP_NF_IPTABLES!=y && (IP_NF_COMPAT_IPCHAINS!=y && IP_NF_COMPAT_IPFWADM || IP_NF_COMPAT_IPCHAINS) || IP_NF_IPTABLES && IP_NF_CONNTRACK && IP_NF_NAT
+	depends on IP_NF_NAT != n
 	default y
 
 config IP_NF_TARGET_MASQUERADE
@@ -504,20 +504,6 @@
 
 	  To compile it as a module, choose M here.  If unsure, say N.
 
-config IP_NF_NAT_LOCAL
-	bool "NAT of local connections (READ HELP)"
-	depends on IP_NF_NAT
-	help
-	  This option enables support for NAT of locally originated connections. 
-	  Enable this if you need to use destination NAT on connections
-	  originating from local processes on the nat box itself.
-
-	  Please note that you will need a recent version (>= 1.2.6a)
-	  of the iptables userspace program in order to use this feature.
-	  See <http://www.iptables.org/> for download instructions.
-
-	  If unsure, say 'N'.
-
 config IP_NF_NAT_SNMP_BASIC
 	tristate "Basic SNMP-ALG support (EXPERIMENTAL)"
 	depends on EXPERIMENTAL && IP_NF_NAT
@@ -639,7 +625,7 @@
 	  affects the connection mark value rather than the packet mark value.
 	
 	  If you want to compile it as a module, say M here and read
-	  Documentation/modules.txt.  The module will be called
+	  <file:Documentation/modules.txt>.  The module will be called
 	  ipt_CONNMARK.o.  If unsure, say `N'.
 
 config IP_NF_TARGET_CLUSTERIP
@@ -663,7 +649,6 @@
 	
 	  If you want to compile it as a module, say M here and read
 	  <file:Documentation/modules.txt>.  If unsure, say `N'.
-	  help
 
 config IP_NF_TARGET_NOTRACK
 	tristate  'NOTRACK target support'
@@ -706,31 +691,6 @@
 	help
 	  Allows altering the ARP packet payload: source and destination
 	  hardware and network addresses.
-
-# Backwards compatibility modules: only if you don't build in the others.
-config IP_NF_COMPAT_IPCHAINS
-	tristate "ipchains (2.2-style) support"
-	depends on IP_NF_CONNTRACK!=y && IP_NF_IPTABLES!=y
-	help
-	  This option places ipchains (with masquerading and redirection
-	  support) back into the kernel, using the new netfilter
-	  infrastructure.  It is not recommended for new installations (see
-	  `Packet filtering').  With this enabled, you should be able to use
-	  the ipchains tool exactly as in 2.2 kernels.
-
-	  To compile it as a module, choose M here.  If unsure, say N.
-
-config IP_NF_COMPAT_IPFWADM
-	tristate "ipfwadm (2.0-style) support"
-	depends on IP_NF_CONNTRACK!=y && IP_NF_IPTABLES!=y && IP_NF_COMPAT_IPCHAINS!=y
-	help
-	  This option places ipfwadm (with masquerading and redirection
-	  support) back into the kernel, using the new netfilter
-	  infrastructure.  It is not recommended for new installations (see
-	  `Packet filtering').  With this enabled, you should be able to use
-	  the ipfwadm tool exactly as in 2.0 kernels.
-
-	  To compile it as a module, choose M here.  If unsure, say N.
 
 endmenu
 
diff -Nru a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile
--- a/net/ipv4/netfilter/Makefile	2005-03-01 23:38:53 -08:00
+++ b/net/ipv4/netfilter/Makefile	2005-03-01 23:38:53 -08:00
@@ -2,19 +2,9 @@
 # Makefile for the netfilter modules on top of IPv4.
 #
 
-# objects for the conntrack and NAT core (used by standalone and backw. compat)
-ip_nf_conntrack-objs	:= ip_conntrack_core.o ip_conntrack_proto_generic.o ip_conntrack_proto_tcp.o ip_conntrack_proto_udp.o ip_conntrack_proto_icmp.o
-ip_nf_nat-objs		:= ip_nat_core.o ip_nat_helper.o ip_nat_proto_unknown.o ip_nat_proto_tcp.o ip_nat_proto_udp.o ip_nat_proto_icmp.o
-
 # objects for the standalone - connection tracking / NAT
-ip_conntrack-objs	:= ip_conntrack_standalone.o $(ip_nf_conntrack-objs)
-iptable_nat-objs	:= ip_nat_standalone.o ip_nat_rule.o $(ip_nf_nat-objs)
-
-# objects for backwards compatibility mode
-ip_nf_compat-objs	:= ip_fw_compat.o ip_fw_compat_redir.o ip_fw_compat_masq.o $(ip_nf_conntrack-objs) $(ip_nf_nat-objs)
-
-ipfwadm-objs		:= $(ip_nf_compat-objs) ipfwadm_core.o
-ipchains-objs		:= $(ip_nf_compat-objs) ipchains_core.o
+ip_conntrack-objs	:= ip_conntrack_standalone.o ip_conntrack_core.o ip_conntrack_proto_generic.o ip_conntrack_proto_tcp.o ip_conntrack_proto_udp.o ip_conntrack_proto_icmp.o
+iptable_nat-objs	:= ip_nat_standalone.o ip_nat_rule.o ip_nat_core.o ip_nat_helper.o ip_nat_proto_unknown.o ip_nat_proto_tcp.o ip_nat_proto_udp.o ip_nat_proto_icmp.o
 
 # connection tracking
 obj-$(CONFIG_IP_NF_CONNTRACK) += ip_conntrack.o
@@ -95,9 +85,5 @@
 
 # just filtering instance of ARP tables for now
 obj-$(CONFIG_IP_NF_ARPFILTER) += arptable_filter.o
-
-# backwards compatibility 
-obj-$(CONFIG_IP_NF_COMPAT_IPCHAINS) += ipchains.o
-obj-$(CONFIG_IP_NF_COMPAT_IPFWADM) += ipfwadm.o
 
 obj-$(CONFIG_IP_NF_QUEUE) += ip_queue.o
diff -Nru a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
--- a/net/ipv4/netfilter/arp_tables.c	2005-03-01 23:39:18 -08:00
+++ b/net/ipv4/netfilter/arp_tables.c	2005-03-01 23:39:18 -08:00
@@ -948,12 +948,12 @@
 	/* Decrease module usage counts and free resource */
 	ARPT_ENTRY_ITERATE(oldinfo->entries, oldinfo->size, cleanup_entry,NULL);
 	vfree(oldinfo);
-	/* Silent error: too late now. */
-	copy_to_user(tmp.counters, counters,
-		     sizeof(struct arpt_counters) * tmp.num_counters);
+	if (copy_to_user(tmp.counters, counters,
+			 sizeof(struct arpt_counters) * tmp.num_counters) != 0)
+		ret = -EFAULT;
 	vfree(counters);
 	up(&arpt_mutex);
-	return 0;
+	return ret;
 
  put_module:
 	module_put(t->me);
@@ -1150,7 +1150,8 @@
 	up(&arpt_mutex);
 }
 
-int arpt_register_table(struct arpt_table *table)
+int arpt_register_table(struct arpt_table *table,
+			const struct arpt_replace *repl)
 {
 	int ret;
 	struct arpt_table_info *newinfo;
@@ -1158,18 +1159,18 @@
 		= { 0, 0, 0, { 0 }, { 0 }, { } };
 
 	newinfo = vmalloc(sizeof(struct arpt_table_info)
-			  + SMP_ALIGN(table->table->size) * NR_CPUS);
+			  + SMP_ALIGN(repl->size) * NR_CPUS);
 	if (!newinfo) {
 		ret = -ENOMEM;
 		return ret;
 	}
-	memcpy(newinfo->entries, table->table->entries, table->table->size);
+	memcpy(newinfo->entries, repl->entries, repl->size);
 
 	ret = translate_table(table->name, table->valid_hooks,
-			      newinfo, table->table->size,
-			      table->table->num_entries,
-			      table->table->hook_entry,
-			      table->table->underflow);
+			      newinfo, repl->size,
+			      repl->num_entries,
+			      repl->hook_entry,
+			      repl->underflow);
 	duprintf("arpt_register_table: translate table gives %d\n", ret);
 	if (ret != 0) {
 		vfree(newinfo);
diff -Nru a/net/ipv4/netfilter/arptable_filter.c b/net/ipv4/netfilter/arptable_filter.c
--- a/net/ipv4/netfilter/arptable_filter.c	2005-03-01 23:38:44 -08:00
+++ b/net/ipv4/netfilter/arptable_filter.c	2005-03-01 23:38:44 -08:00
@@ -141,7 +141,6 @@
 
 static struct arpt_table packet_filter = {
 	.name		= "filter",
-	.table		= &initial_table.repl,
 	.valid_hooks	= FILTER_VALID_HOOKS,
 	.lock		= RW_LOCK_UNLOCKED,
 	.private	= NULL,
@@ -184,7 +183,7 @@
 	int ret, i;
 
 	/* Register table */
-	ret = arpt_register_table(&packet_filter);
+	ret = arpt_register_table(&packet_filter, &initial_table.repl);
 	if (ret < 0)
 		return ret;
 
diff -Nru a/net/ipv4/netfilter/ip_conntrack_amanda.c b/net/ipv4/netfilter/ip_conntrack_amanda.c
--- a/net/ipv4/netfilter/ip_conntrack_amanda.c	2005-03-01 23:39:07 -08:00
+++ b/net/ipv4/netfilter/ip_conntrack_amanda.c	2005-03-01 23:39:07 -08:00
@@ -44,14 +44,21 @@
 static char amanda_buffer[65536];
 static DECLARE_LOCK(amanda_buffer_lock);
 
-static int help(struct sk_buff *skb,
+unsigned int (*ip_nat_amanda_hook)(struct sk_buff **pskb,
+				   enum ip_conntrack_info ctinfo,
+				   unsigned int matchoff,
+				   unsigned int matchlen,
+				   struct ip_conntrack_expect *exp);
+EXPORT_SYMBOL_GPL(ip_nat_amanda_hook);
+
+static int help(struct sk_buff **pskb,
                 struct ip_conntrack *ct, enum ip_conntrack_info ctinfo)
 {
 	struct ip_conntrack_expect *exp;
-	struct ip_ct_amanda_expect *exp_amanda_info;
 	char *data, *data_limit, *tmp;
 	unsigned int dataoff, i;
 	u_int16_t port, len;
+	int ret = NF_ACCEPT;
 
 	/* Only look at packets from the Amanda server */
 	if (CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL)
@@ -62,17 +69,17 @@
 	ip_ct_refresh_acct(ct, ctinfo, NULL, master_timeout * HZ);
 
 	/* No data? */
-	dataoff = skb->nh.iph->ihl*4 + sizeof(struct udphdr);
-	if (dataoff >= skb->len) {
+	dataoff = (*pskb)->nh.iph->ihl*4 + sizeof(struct udphdr);
+	if (dataoff >= (*pskb)->len) {
 		if (net_ratelimit())
-			printk("amanda_help: skblen = %u\n", skb->len);
+			printk("amanda_help: skblen = %u\n", (*pskb)->len);
 		return NF_ACCEPT;
 	}
 
 	LOCK_BH(&amanda_buffer_lock);
-	skb_copy_bits(skb, dataoff, amanda_buffer, skb->len - dataoff);
+	skb_copy_bits(*pskb, dataoff, amanda_buffer, (*pskb)->len - dataoff);
 	data = amanda_buffer;
-	data_limit = amanda_buffer + skb->len - dataoff;
+	data_limit = amanda_buffer + (*pskb)->len - dataoff;
 	*data_limit = '\0';
 
 	/* Search for the CONNECT string */
@@ -96,36 +103,44 @@
 			break;
 
 		exp = ip_conntrack_expect_alloc();
-		if (exp == NULL)
+		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;
 		exp->tuple.dst.ip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip;
 		exp->tuple.dst.protonum = IPPROTO_TCP;
+		exp->tuple.dst.u.tcp.port = htons(port);
+
 		exp->mask.src.ip = 0xFFFFFFFF;
+		exp->mask.src.u.tcp.port = 0;
 		exp->mask.dst.ip = 0xFFFFFFFF;
-		exp->mask.dst.protonum = 0xFFFF;
+		exp->mask.dst.protonum = 0xFF;
 		exp->mask.dst.u.tcp.port = 0xFFFF;
 
-		exp_amanda_info = &exp->help.exp_amanda_info;
-		exp_amanda_info->offset = tmp - amanda_buffer;
-		exp_amanda_info->port   = port;
-		exp_amanda_info->len    = len;
-
-		exp->tuple.dst.u.tcp.port = htons(port);
-
-		ip_conntrack_expect_related(exp, ct);
+		if (ip_nat_amanda_hook)
+			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);
+			ret = NF_DROP;
+		}
 	}
 
 out:
 	UNLOCK_BH(&amanda_buffer_lock);
-	return NF_ACCEPT;
+	return ret;
 }
 
 static struct ip_conntrack_helper amanda_helper = {
 	.max_expected = ARRAY_SIZE(conns),
 	.timeout = 180,
-	.flags = IP_CT_HELPER_F_REUSE_EXPECT,
 	.me = THIS_MODULE,
 	.help = help,
 	.name = "amanda",
@@ -134,7 +149,7 @@
 		   .dst = { .protonum = IPPROTO_UDP },
 	},
 	.mask = { .src = { .u = { 0xFFFF } },
-		 .dst = { .protonum = 0xFFFF },
+		 .dst = { .protonum = 0xFF },
 	},
 };
 
@@ -148,6 +163,5 @@
 	return ip_conntrack_helper_register(&amanda_helper);
 }
 
-PROVIDES_CONNTRACK(amanda);
 module_init(init);
 module_exit(fini);
diff -Nru a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c
--- a/net/ipv4/netfilter/ip_conntrack_core.c	2005-03-01 23:38:44 -08:00
+++ b/net/ipv4/netfilter/ip_conntrack_core.c	2005-03-01 23:38:44 -08:00
@@ -58,7 +58,6 @@
 #endif
 
 DECLARE_RWLOCK(ip_conntrack_lock);
-DECLARE_RWLOCK(ip_conntrack_expect_tuple_lock);
 
 /* ip_conntrack_standalone needs this */
 atomic_t ip_conntrack_count = ATOMIC_INIT(0);
@@ -74,10 +73,12 @@
 static kmem_cache_t *ip_conntrack_expect_cachep;
 struct ip_conntrack ip_conntrack_untracked;
 unsigned int ip_ct_log_invalid;
+static LIST_HEAD(unconfirmed);
+static int ip_conntrack_vmalloc;
 
 DEFINE_PER_CPU(struct ip_conntrack_stat, ip_conntrack_stat);
 
-inline void 
+void 
 ip_conntrack_put(struct ip_conntrack *ct)
 {
 	IP_NF_ASSERT(ct);
@@ -116,6 +117,7 @@
 	tuple->src.ip = iph->saddr;
 	tuple->dst.ip = iph->daddr;
 	tuple->dst.protonum = iph->protocol;
+	tuple->dst.dir = IP_CT_DIR_ORIGINAL;
 
 	return protocol->pkt_to_tuple(skb, dataoff, tuple);
 }
@@ -128,135 +130,76 @@
 	inverse->src.ip = orig->dst.ip;
 	inverse->dst.ip = orig->src.ip;
 	inverse->dst.protonum = orig->dst.protonum;
+	inverse->dst.dir = !orig->dst.dir;
 
 	return protocol->invert_tuple(inverse, orig);
 }
 
 
 /* ip_conntrack_expect helper functions */
-
-/* Compare tuple parts depending on mask. */
-static inline int expect_cmp(const struct ip_conntrack_expect *i,
-			     const struct ip_conntrack_tuple *tuple)
-{
-	MUST_BE_READ_LOCKED(&ip_conntrack_expect_tuple_lock);
-	return ip_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask);
-}
-
-static void
-destroy_expect(struct ip_conntrack_expect *exp)
+static void destroy_expect(struct ip_conntrack_expect *exp)
 {
-	DEBUGP("destroy_expect(%p) use=%d\n", exp, atomic_read(&exp->use));
-	IP_NF_ASSERT(atomic_read(&exp->use) == 0);
+	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);
 }
 
-inline void ip_conntrack_expect_put(struct ip_conntrack_expect *exp)
+static void unlink_expect(struct ip_conntrack_expect *exp)
 {
-	IP_NF_ASSERT(exp);
-
-	if (atomic_dec_and_test(&exp->use)) {
-		/* usage count dropped to zero */
-		destroy_expect(exp);
-	}
-}
-
-static inline struct ip_conntrack_expect *
-__ip_ct_expect_find(const struct ip_conntrack_tuple *tuple)
-{
-	MUST_BE_READ_LOCKED(&ip_conntrack_lock);
-	MUST_BE_READ_LOCKED(&ip_conntrack_expect_tuple_lock);
-	return LIST_FIND(&ip_conntrack_expect_list, expect_cmp, 
-			 struct ip_conntrack_expect *, tuple);
+	MUST_BE_WRITE_LOCKED(&ip_conntrack_lock);
+	list_del(&exp->list);
+	/* Logically in destroy_expect, but we hold the lock here. */
+	exp->master->expecting--;
 }
 
-/* Find a expectation corresponding to a tuple. */
-struct ip_conntrack_expect *
-ip_conntrack_expect_find_get(const struct ip_conntrack_tuple *tuple)
+static void expectation_timed_out(unsigned long ul_expect)
 {
-	struct ip_conntrack_expect *exp;
-
-	READ_LOCK(&ip_conntrack_lock);
-	READ_LOCK(&ip_conntrack_expect_tuple_lock);
-	exp = __ip_ct_expect_find(tuple);
-	if (exp)
-		atomic_inc(&exp->use);
-	READ_UNLOCK(&ip_conntrack_expect_tuple_lock);
-	READ_UNLOCK(&ip_conntrack_lock);
+	struct ip_conntrack_expect *exp = (void *)ul_expect;
 
-	return exp;
+	WRITE_LOCK(&ip_conntrack_lock);
+	unlink_expect(exp);
+	WRITE_UNLOCK(&ip_conntrack_lock);
+	destroy_expect(exp);
 }
 
-/* remove one specific expectation from all lists and drop refcount,
- * does _NOT_ delete the timer. */
-static void __unexpect_related(struct ip_conntrack_expect *expect)
+/* If an expectation for this connection is found, it gets delete from
+ * global list then returned. */
+static struct ip_conntrack_expect *
+find_expectation(const struct ip_conntrack_tuple *tuple)
 {
-	DEBUGP("unexpect_related(%p)\n", expect);
-	MUST_BE_WRITE_LOCKED(&ip_conntrack_lock);
-
-	/* we're not allowed to unexpect a confirmed expectation! */
-	IP_NF_ASSERT(!expect->sibling);
-
-	/* delete from global and local lists */
-	list_del(&expect->list);
-	list_del(&expect->expected_list);
-
-	/* decrement expect-count of master conntrack */
-	if (expect->expectant)
-		expect->expectant->expecting--;
-
-	ip_conntrack_expect_put(expect);
-}
-
-/* remove one specific expecatation from all lists, drop refcount
- * and expire timer. 
- * This function can _NOT_ be called for confirmed expects! */
-static void unexpect_related(struct ip_conntrack_expect *expect)
-{
-	IP_NF_ASSERT(expect->expectant);
-	IP_NF_ASSERT(expect->expectant->helper);
-	/* if we are supposed to have a timer, but we can't delete
-	 * it: race condition.  __unexpect_related will
-	 * be calledd by timeout function */
-	if (expect->expectant->helper->timeout
-	    && !del_timer(&expect->timeout))
-		return;
+	struct ip_conntrack_expect *i;
 
-	__unexpect_related(expect);
+	list_for_each_entry(i, &ip_conntrack_expect_list, list) {
+		/* If master is not in hash table yet (ie. packet hasn't left
+		   this machine yet), how can other end know about expected?
+		   Hence these are not the droids you are looking for (if
+		   master ct never got confirmed, we'd hold a reference to it
+		   and weird things would happen to future packets). */
+		if (ip_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask)
+		    && is_confirmed(i->master)
+		    && del_timer(&i->timeout)) {
+			unlink_expect(i);
+			return i;
+		}
+	}
+	return NULL;
 }
 
-/* delete all unconfirmed expectations for this conntrack */
-static void remove_expectations(struct ip_conntrack *ct, int drop_refcount)
+/* delete all expectations for this conntrack */
+static void remove_expectations(struct ip_conntrack *ct)
 {
-	struct list_head *exp_entry, *next;
-	struct ip_conntrack_expect *exp;
+	struct ip_conntrack_expect *i, *tmp;
 
-	DEBUGP("remove_expectations(%p)\n", ct);
+	/* Optimization: most connection never expect any others. */
+	if (ct->expecting == 0)
+		return;
 
-	list_for_each_safe(exp_entry, next, &ct->sibling_list) {
-		exp = list_entry(exp_entry, struct ip_conntrack_expect,
-				 expected_list);
-
-		/* we skip established expectations, as we want to delete
-		 * the un-established ones only */
-		if (exp->sibling) {
-			DEBUGP("remove_expectations: skipping established %p of %p\n", exp->sibling, ct);
-			if (drop_refcount) {
-				/* Indicate that this expectations parent is dead */
-				ip_conntrack_put(exp->expectant);
-				exp->expectant = NULL;
-			}
-			continue;
+	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_NF_ASSERT(list_inlist(&ip_conntrack_expect_list, exp));
-		IP_NF_ASSERT(exp->expectant == ct);
-
-		/* delete expectation from global and private lists */
-		unexpect_related(exp);
 	}
 }
 
@@ -273,14 +216,14 @@
 	LIST_DELETE(&ip_conntrack_hash[ho], &ct->tuplehash[IP_CT_DIR_ORIGINAL]);
 	LIST_DELETE(&ip_conntrack_hash[hr], &ct->tuplehash[IP_CT_DIR_REPLY]);
 
-	/* Destroy all un-established, pending expectations */
-	remove_expectations(ct, 1);
+	/* Destroy all pending expectations */
+	remove_expectations(ct);
 }
 
 static void
 destroy_conntrack(struct nf_conntrack *nfct)
 {
-	struct ip_conntrack *ct = (struct ip_conntrack *)nfct, *master = NULL;
+	struct ip_conntrack *ct = (struct ip_conntrack *)nfct;
 	struct ip_conntrack_protocol *proto;
 
 	DEBUGP("destroy_conntrack(%p)\n", ct);
@@ -298,25 +241,23 @@
 		ip_conntrack_destroyed(ct);
 
 	WRITE_LOCK(&ip_conntrack_lock);
-	/* Make sure don't leave any orphaned expectations lying around */
-	if (ct->expecting)
-		remove_expectations(ct, 1);
-
-	/* Delete our master expectation */
-	if (ct->master) {
-		if (ct->master->expectant) {
-			/* can't call __unexpect_related here,
-			 * since it would screw up expect_list */
-			list_del(&ct->master->expected_list);
-			master = ct->master->expectant;
-		}
-		kmem_cache_free(ip_conntrack_expect_cachep, ct->master);
+	/* 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,
+	 * too. */
+	remove_expectations(ct);
+
+	/* We overload first tuple to link into unconfirmed list. */
+	if (!is_confirmed(ct)) {
+		BUG_ON(list_empty(&ct->tuplehash[IP_CT_DIR_ORIGINAL].list));
+		list_del(&ct->tuplehash[IP_CT_DIR_ORIGINAL].list);
 	}
+
 	CONNTRACK_STAT_INC(delete);
 	WRITE_UNLOCK(&ip_conntrack_lock);
 
-	if (master)
-		ip_conntrack_put(master);
+	if (ct->master)
+		ip_conntrack_put(ct->master);
 
 	DEBUGP("destroy_conntrack: returning ct=%p to slab\n", ct);
 	kmem_cache_free(ip_conntrack_cachep, ct);
@@ -342,7 +283,7 @@
 		    const struct ip_conntrack *ignored_conntrack)
 {
 	MUST_BE_READ_LOCKED(&ip_conntrack_lock);
-	return i->ctrack != ignored_conntrack
+	return tuplehash_to_ctrack(i) != ignored_conntrack
 		&& ip_ct_tuple_equal(tuple, &i->tuple);
 }
 
@@ -375,7 +316,7 @@
 	READ_LOCK(&ip_conntrack_lock);
 	h = __ip_conntrack_find(tuple, ignored_conntrack);
 	if (h)
-		atomic_inc(&h->ctrack->ct_general.use);
+		atomic_inc(&tuplehash_to_ctrack(h)->ct_general.use);
 	READ_UNLOCK(&ip_conntrack_lock);
 
 	return h;
@@ -383,13 +324,13 @@
 
 /* Confirm a connection given skb; places it in hash table */
 int
-__ip_conntrack_confirm(struct sk_buff *skb)
+__ip_conntrack_confirm(struct sk_buff **pskb)
 {
 	unsigned int hash, repl_hash;
 	struct ip_conntrack *ct;
 	enum ip_conntrack_info ctinfo;
 
-	ct = ip_conntrack_get(skb, &ctinfo);
+	ct = ip_conntrack_get(*pskb, &ctinfo);
 
 	/* ipt_REJECT uses ip_conntrack_attach to attach related
 	   ICMP/TCP RST packets in other direction.  Actual packet
@@ -412,6 +353,7 @@
 	DEBUGP("Confirming conntrack %p\n", ct);
 
 	WRITE_LOCK(&ip_conntrack_lock);
+
 	/* See if there's one in the list already, including reverse:
            NAT could have grabbed it without realizing, since we're
            not in the hash.  If there is, we lost race. */
@@ -423,6 +365,9 @@
 			  conntrack_tuple_cmp,
 			  struct ip_conntrack_tuple_hash *,
 			  &ct->tuplehash[IP_CT_DIR_REPLY].tuple, NULL)) {
+		/* Remove from unconfirmed list */
+		list_del(&ct->tuplehash[IP_CT_DIR_ORIGINAL].list);
+
 		list_prepend(&ip_conntrack_hash[hash],
 			     &ct->tuplehash[IP_CT_DIR_ORIGINAL]);
 		list_prepend(&ip_conntrack_hash[repl_hash],
@@ -464,30 +409,33 @@
    connection.  Too bad: we're in trouble anyway. */
 static inline int unreplied(const struct ip_conntrack_tuple_hash *i)
 {
-	return !(test_bit(IPS_ASSURED_BIT, &i->ctrack->status));
+	return !(test_bit(IPS_ASSURED_BIT, &tuplehash_to_ctrack(i)->status));
 }
 
 static int early_drop(struct list_head *chain)
 {
 	/* Traverse backwards: gives us oldest, which is roughly LRU */
 	struct ip_conntrack_tuple_hash *h;
+	struct ip_conntrack *ct = NULL;
 	int dropped = 0;
 
 	READ_LOCK(&ip_conntrack_lock);
 	h = LIST_FIND_B(chain, unreplied, struct ip_conntrack_tuple_hash *);
-	if (h)
-		atomic_inc(&h->ctrack->ct_general.use);
+	if (h) {
+		ct = tuplehash_to_ctrack(h);
+		atomic_inc(&ct->ct_general.use);
+	}
 	READ_UNLOCK(&ip_conntrack_lock);
 
-	if (!h)
+	if (!ct)
 		return dropped;
 
-	if (del_timer(&h->ctrack->timeout)) {
-		death_by_timeout((unsigned long)h->ctrack);
+	if (del_timer(&ct->timeout)) {
+		death_by_timeout((unsigned long)ct);
 		dropped = 1;
 		CONNTRACK_STAT_INC(early_drop);
 	}
-	ip_conntrack_put(h->ctrack);
+	ip_conntrack_put(ct);
 	return dropped;
 }
 
@@ -497,7 +445,7 @@
 	return ip_ct_tuple_mask_cmp(rtuple, &i->tuple, &i->mask);
 }
 
-struct ip_conntrack_helper *ip_ct_find_helper(const struct ip_conntrack_tuple *tuple)
+static struct ip_conntrack_helper *ip_ct_find_helper(const struct ip_conntrack_tuple *tuple)
 {
 	return LIST_FIND(&helpers, helper_cmp,
 			 struct ip_conntrack_helper *,
@@ -514,7 +462,7 @@
 	struct ip_conntrack *conntrack;
 	struct ip_conntrack_tuple repl_tuple;
 	size_t hash;
-	struct ip_conntrack_expect *expected;
+	struct ip_conntrack_expect *exp;
 
 	if (!ip_conntrack_hash_rnd_initted) {
 		get_random_bytes(&ip_conntrack_hash_rnd, 4);
@@ -550,9 +498,7 @@
 	atomic_set(&conntrack->ct_general.use, 1);
 	conntrack->ct_general.destroy = destroy_conntrack;
 	conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple = *tuple;
-	conntrack->tuplehash[IP_CT_DIR_ORIGINAL].ctrack = conntrack;
 	conntrack->tuplehash[IP_CT_DIR_REPLY].tuple = repl_tuple;
-	conntrack->tuplehash[IP_CT_DIR_REPLY].ctrack = conntrack;
 	if (!protocol->new(conntrack, skb)) {
 		kmem_cache_free(ip_conntrack_cachep, conntrack);
 		return NULL;
@@ -562,65 +508,39 @@
 	conntrack->timeout.data = (unsigned long)conntrack;
 	conntrack->timeout.function = death_by_timeout;
 
-	INIT_LIST_HEAD(&conntrack->sibling_list);
-
 	WRITE_LOCK(&ip_conntrack_lock);
-	/* Need finding and deleting of expected ONLY if we win race */
-	READ_LOCK(&ip_conntrack_expect_tuple_lock);
-	expected = LIST_FIND(&ip_conntrack_expect_list, expect_cmp,
-			     struct ip_conntrack_expect *, tuple);
-	READ_UNLOCK(&ip_conntrack_expect_tuple_lock);
-
-	if (expected) {
-		/* If master is not in hash table yet (ie. packet hasn't left
-		   this machine yet), how can other end know about expected?
-		   Hence these are not the droids you are looking for (if
-		   master ct never got confirmed, we'd hold a reference to it
-		   and weird things would happen to future packets). */
-		if (!is_confirmed(expected->expectant)) {
-			conntrack->helper = ip_ct_find_helper(&repl_tuple);
-			goto end;
-		}
-
-		/* Expectation is dying... */
-		if (expected->expectant->helper->timeout
-		    && !del_timer(&expected->timeout))
-			goto end;	
+	exp = find_expectation(tuple);
 
+	if (exp) {
 		DEBUGP("conntrack: expectation arrives ct=%p exp=%p\n",
-			conntrack, expected);
+			conntrack, exp);
 		/* Welcome, Mr. Bond.  We've been expecting you... */
-		IP_NF_ASSERT(expected->expectant);
 		__set_bit(IPS_EXPECTED_BIT, &conntrack->status);
-		conntrack->master = expected;
-		expected->sibling = conntrack;
+		conntrack->master = exp->master;
 #if CONFIG_IP_NF_CONNTRACK_MARK
-		conntrack->mark = expected->expectant->mark;
+		conntrack->mark = exp->master->mark;
 #endif
-		LIST_DELETE(&ip_conntrack_expect_list, expected);
-		expected->expectant->expecting--;
-		nf_conntrack_get(&master_ct(conntrack)->ct_general);
-
-		/* this is a braindead... --pablo */
-		atomic_inc(&ip_conntrack_count);
-		WRITE_UNLOCK(&ip_conntrack_lock);
-
-		if (expected->expectfn)
-			expected->expectfn(conntrack);
-	
+		nf_conntrack_get(&conntrack->master->ct_general);
 		CONNTRACK_STAT_INC(expect_new);
-
-		goto ret;
-	} else  {
+	} else {
 		conntrack->helper = ip_ct_find_helper(&repl_tuple);
 
 		CONNTRACK_STAT_INC(new);
 	}
 
-end:	atomic_inc(&ip_conntrack_count);
+	/* Overload tuple linked list to put us in unconfirmed list. */
+	list_add(&conntrack->tuplehash[IP_CT_DIR_ORIGINAL].list, &unconfirmed);
+
+	atomic_inc(&ip_conntrack_count);
 	WRITE_UNLOCK(&ip_conntrack_lock);
 
-ret:	return &conntrack->tuplehash[IP_CT_DIR_ORIGINAL];
+	if (exp) {
+		if (exp->expectfn)
+			exp->expectfn(conntrack, exp);
+		destroy_expect(exp);
+	}
+
+	return &conntrack->tuplehash[IP_CT_DIR_ORIGINAL];
 }
 
 /* On success, returns conntrack ptr, sets skb->nfct and ctinfo */
@@ -633,6 +553,7 @@
 {
 	struct ip_conntrack_tuple tuple;
 	struct ip_conntrack_tuple_hash *h;
+	struct ip_conntrack *ct;
 
 	IP_NF_ASSERT((skb->nh.iph->frag_off & htons(IP_OFFSET)) == 0);
 
@@ -649,6 +570,7 @@
 		if (IS_ERR(h))
 			return (void *)h;
 	}
+	ct = tuplehash_to_ctrack(h);
 
 	/* It exists; we have (non-exclusive) reference. */
 	if (DIRECTION(h) == IP_CT_DIR_REPLY) {
@@ -657,24 +579,24 @@
 		*set_reply = 1;
 	} else {
 		/* Once we've had two way comms, always ESTABLISHED. */
-		if (test_bit(IPS_SEEN_REPLY_BIT, &h->ctrack->status)) {
+		if (test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) {
 			DEBUGP("ip_conntrack_in: normal packet for %p\n",
-			       h->ctrack);
+			       ct);
 		        *ctinfo = IP_CT_ESTABLISHED;
-		} else if (test_bit(IPS_EXPECTED_BIT, &h->ctrack->status)) {
+		} else if (test_bit(IPS_EXPECTED_BIT, &ct->status)) {
 			DEBUGP("ip_conntrack_in: related packet for %p\n",
-			       h->ctrack);
+			       ct);
 			*ctinfo = IP_CT_RELATED;
 		} else {
 			DEBUGP("ip_conntrack_in: new packet for %p\n",
-			       h->ctrack);
+			       ct);
 			*ctinfo = IP_CT_NEW;
 		}
 		*set_reply = 0;
 	}
-	skb->nfct = &h->ctrack->ct_general;
+	skb->nfct = &ct->ct_general;
 	skb->nfctinfo = *ctinfo;
-	return h->ctrack;
+	return ct;
 }
 
 /* Netfilter hook itself. */
@@ -759,16 +681,6 @@
 		return -ret;
 	}
 
-	if (ret != NF_DROP && ct->helper) {
-		ret = ct->helper->help(*pskb, ct, ctinfo);
-		if (ret == -1) {
-			/* Invalid */
-			CONNTRACK_STAT_INC(invalid);
-			nf_conntrack_put((*pskb)->nfct);
-			(*pskb)->nfct = NULL;
-			return NF_ACCEPT;
-		}
-	}
 	if (set_reply)
 		set_bit(IPS_SEEN_REPLY_BIT, &ct->status);
 
@@ -782,55 +694,49 @@
 				  ip_ct_find_proto(orig->dst.protonum));
 }
 
-static inline int resent_expect(const struct ip_conntrack_expect *i,
-			        const struct ip_conntrack_tuple *tuple,
-			        const struct ip_conntrack_tuple *mask)
-{
-	DEBUGP("resent_expect\n");
-	DEBUGP("   tuple:   "); DUMP_TUPLE(&i->tuple);
-	DEBUGP("ct_tuple:   "); DUMP_TUPLE(&i->ct_tuple);
-	DEBUGP("test tuple: "); DUMP_TUPLE(tuple);
-	return (((i->ct_tuple.dst.protonum == 0 && ip_ct_tuple_equal(&i->tuple, tuple))
-	         || (i->ct_tuple.dst.protonum && ip_ct_tuple_equal(&i->ct_tuple, tuple)))
-		&& ip_ct_tuple_equal(&i->mask, mask));
-}
-
 /* Would two expected things clash? */
-static inline int expect_clash(const struct ip_conntrack_expect *i,
-			       const struct ip_conntrack_tuple *tuple,
-			       const struct ip_conntrack_tuple *mask)
+static inline int expect_clash(const struct ip_conntrack_expect *a,
+			       const struct ip_conntrack_expect *b)
 {
 	/* Part covered by intersection of masks must be unequal,
            otherwise they clash */
 	struct ip_conntrack_tuple intersect_mask
-		= { { i->mask.src.ip & mask->src.ip,
-		      { i->mask.src.u.all & mask->src.u.all } },
-		    { i->mask.dst.ip & mask->dst.ip,
-		      { i->mask.dst.u.all & mask->dst.u.all },
-		      i->mask.dst.protonum & mask->dst.protonum } };
+		= { { a->mask.src.ip & b->mask.src.ip,
+		      { a->mask.src.u.all & b->mask.src.u.all } },
+		    { a->mask.dst.ip & b->mask.dst.ip,
+		      { a->mask.dst.u.all & b->mask.dst.u.all },
+		      a->mask.dst.protonum & b->mask.dst.protonum } };
 
-	return ip_ct_tuple_mask_cmp(&i->tuple, tuple, &intersect_mask);
+	return ip_ct_tuple_mask_cmp(&a->tuple, &b->tuple, &intersect_mask);
 }
 
-inline void ip_conntrack_unexpect_related(struct ip_conntrack_expect *expect)
+static inline int expect_matches(const struct ip_conntrack_expect *a,
+				 const struct ip_conntrack_expect *b)
 {
-	WRITE_LOCK(&ip_conntrack_lock);
-	unexpect_related(expect);
-	WRITE_UNLOCK(&ip_conntrack_lock);
+	return a->master == b->master
+		&& ip_ct_tuple_equal(&a->tuple, &b->tuple)
+		&& ip_ct_tuple_equal(&a->mask, &b->mask);
 }
-	
-static void expectation_timed_out(unsigned long ul_expect)
+
+/* Generally a bad idea to call this: could have matched already. */
+void ip_conntrack_unexpect_related(struct ip_conntrack_expect *exp)
 {
-	struct ip_conntrack_expect *expect = (void *) ul_expect;
+	struct ip_conntrack_expect *i;
 
-	DEBUGP("expectation %p timed out\n", expect);	
 	WRITE_LOCK(&ip_conntrack_lock);
-	__unexpect_related(expect);
+	/* 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);
+			return;
+		}
+	}
 	WRITE_UNLOCK(&ip_conntrack_lock);
 }
 
-struct ip_conntrack_expect *
-ip_conntrack_expect_alloc(void)
+struct ip_conntrack_expect *ip_conntrack_expect_alloc(void)
 {
 	struct ip_conntrack_expect *new;
 
@@ -839,190 +745,103 @@
 		DEBUGP("expect_related: OOM allocating expect\n");
 		return NULL;
 	}
-
-	/* tuple_cmp compares whole union, we have to initialized cleanly */
-	memset(new, 0, sizeof(struct ip_conntrack_expect));
-	atomic_set(&new->use, 1);
-
+	new->master = NULL;
 	return new;
 }
 
-static void
-ip_conntrack_expect_insert(struct ip_conntrack_expect *new,
-			   struct ip_conntrack *related_to)
+void ip_conntrack_expect_free(struct ip_conntrack_expect *expect)
 {
-	DEBUGP("new expectation %p of conntrack %p\n", new, related_to);
-	new->expectant = related_to;
-	new->sibling = NULL;
-
-	/* add to expected list for this connection */
-	list_add_tail(&new->expected_list, &related_to->sibling_list);
-	/* add to global list of expectations */
-	list_prepend(&ip_conntrack_expect_list, &new->list);
-	/* add and start timer if required */
-	if (related_to->helper->timeout) {
-		init_timer(&new->timeout);
-		new->timeout.data = (unsigned long)new;
-		new->timeout.function = expectation_timed_out;
-		new->timeout.expires = jiffies +
-					related_to->helper->timeout * HZ;
-		add_timer(&new->timeout);
-	}
-	related_to->expecting++;
-}
-
-/* Add a related connection. */
-int ip_conntrack_expect_related(struct ip_conntrack_expect *expect,
-				struct ip_conntrack *related_to)
+	kmem_cache_free(ip_conntrack_expect_cachep, expect);
+}
+
+static void ip_conntrack_expect_insert(struct ip_conntrack_expect *exp)
 {
-	struct ip_conntrack_expect *old;
-	int ret = 0;
+	atomic_inc(&exp->master->ct_general.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;
 
-	WRITE_LOCK(&ip_conntrack_lock);
-	/* Because of the write lock, no reader can walk the lists,
-	 * so there is no need to use the tuple lock too */
+	CONNTRACK_STAT_INC(expect_create);
+}
 
-	DEBUGP("ip_conntrack_expect_related %p\n", related_to);
-	DEBUGP("tuple: "); DUMP_TUPLE(&expect->tuple);
-	DEBUGP("mask:  "); DUMP_TUPLE(&expect->mask);
+/* Race with expectations being used means we could have none to find; OK. */
+static void evict_oldest_expect(struct ip_conntrack *master)
+{
+	struct ip_conntrack_expect *i;
 
-	old = LIST_FIND(&ip_conntrack_expect_list, resent_expect,
-		        struct ip_conntrack_expect *, &expect->tuple, 
-			&expect->mask);
-	if (old) {
-		/* Helper private data may contain offsets but no pointers
-		   pointing into the payload - otherwise we should have to copy 
-		   the data filled out by the helper over the old one */
-		DEBUGP("expect_related: resent packet\n");
-		if (related_to->helper->timeout) {
-			if (!del_timer(&old->timeout)) {
-				/* expectation is dying. Fall through */
-				goto out;
-			} else {
-				old->timeout.expires = jiffies + 
-					related_to->helper->timeout * HZ;
-				add_timer(&old->timeout);
+	list_for_each_entry_reverse(i, &ip_conntrack_expect_list, list) {
+		if (i->master == master) {
+			if (del_timer(&i->timeout)) {
+				unlink_expect(i);
+				destroy_expect(i);
 			}
+			break;
 		}
-
-		WRITE_UNLOCK(&ip_conntrack_lock);
-		/* This expectation is not inserted so no need to lock */
-		kmem_cache_free(ip_conntrack_expect_cachep, expect);
-		return -EEXIST;
-
-	} else if (related_to->helper->max_expected && 
-		   related_to->expecting >= related_to->helper->max_expected) {
-		/* old == NULL */
-		if (!(related_to->helper->flags & 
-		      IP_CT_HELPER_F_REUSE_EXPECT)) {
-			WRITE_UNLOCK(&ip_conntrack_lock);
- 		    	if (net_ratelimit())
- 			    	printk(KERN_WARNING
-				       "ip_conntrack: max number of expected "
-				       "connections %i of %s reached for "
-				       "%u.%u.%u.%u->%u.%u.%u.%u\n",
-				       related_to->helper->max_expected,
-				       related_to->helper->name,
- 		    	       	       NIPQUAD(related_to->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip),
- 		    	       	       NIPQUAD(related_to->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip));
-			kmem_cache_free(ip_conntrack_expect_cachep, expect);
-			return -EPERM;
-		}
-		DEBUGP("ip_conntrack: max number of expected "
-		       "connections %i of %s reached for "
-		       "%u.%u.%u.%u->%u.%u.%u.%u, reusing\n",
- 		       related_to->helper->max_expected,
-		       related_to->helper->name,
-		       NIPQUAD(related_to->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip),
-		       NIPQUAD(related_to->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip));
- 
-		/* choose the the oldest expectation to evict */
-		list_for_each_entry(old, &related_to->sibling_list, 
-		                                      expected_list)
-			if (old->sibling == NULL)
-				break;
-
-		/* We cannot fail since related_to->expecting is the number
-		 * of unconfirmed expectations */
-		IP_NF_ASSERT(old && old->sibling == NULL);
-
-		/* newnat14 does not reuse the real allocated memory
-		 * structures but rather unexpects the old and
-		 * allocates a new.  unexpect_related will decrement
-		 * related_to->expecting. 
-		 */
-		unexpect_related(old);
-		ret = -EPERM;
-	} else if (LIST_FIND(&ip_conntrack_expect_list, expect_clash,
-			     struct ip_conntrack_expect *, &expect->tuple, 
-			     &expect->mask)) {
-		WRITE_UNLOCK(&ip_conntrack_lock);
-		DEBUGP("expect_related: busy!\n");
-
-		kmem_cache_free(ip_conntrack_expect_cachep, expect);
-		return -EBUSY;
 	}
+}
 
-out:	ip_conntrack_expect_insert(expect, related_to);
-
-	WRITE_UNLOCK(&ip_conntrack_lock);
-
-	CONNTRACK_STAT_INC(expect_create);
+static inline int refresh_timer(struct ip_conntrack_expect *i)
+{
+	if (!del_timer(&i->timeout))
+		return 0;
 
-	return ret;
+	i->timeout.expires = jiffies + i->master->helper->timeout*HZ;
+	add_timer(&i->timeout);
+	return 1;
 }
 
-/* Change tuple in an existing expectation */
-int ip_conntrack_change_expect(struct ip_conntrack_expect *expect,
-			       struct ip_conntrack_tuple *newtuple)
+int ip_conntrack_expect_related(struct ip_conntrack_expect *expect)
 {
+	struct ip_conntrack_expect *i;
 	int ret;
 
-	MUST_BE_READ_LOCKED(&ip_conntrack_lock);
-	WRITE_LOCK(&ip_conntrack_expect_tuple_lock);
+	DEBUGP("ip_conntrack_expect_related %p\n", related_to);
+	DEBUGP("tuple: "); DUMP_TUPLE(&expect->tuple);
+	DEBUGP("mask:  "); DUMP_TUPLE(&expect->mask);
 
-	DEBUGP("change_expect:\n");
-	DEBUGP("exp tuple: "); DUMP_TUPLE(&expect->tuple);
-	DEBUGP("exp mask:  "); DUMP_TUPLE(&expect->mask);
-	DEBUGP("newtuple:  "); DUMP_TUPLE(newtuple);
-	if (expect->ct_tuple.dst.protonum == 0) {
-		/* Never seen before */
-		DEBUGP("change expect: never seen before\n");
-		if (!ip_ct_tuple_equal(&expect->tuple, newtuple) 
-		    && LIST_FIND(&ip_conntrack_expect_list, expect_clash,
-			         struct ip_conntrack_expect *, newtuple, &expect->mask)) {
-			/* Force NAT to find an unused tuple */
-			ret = -1;
-		} else {
-			memcpy(&expect->ct_tuple, &expect->tuple, sizeof(expect->tuple));
-			memcpy(&expect->tuple, newtuple, sizeof(expect->tuple));
-			ret = 0;
-		}
-	} else {
-		/* Resent packet */
-		DEBUGP("change expect: resent packet\n");
-		if (ip_ct_tuple_equal(&expect->tuple, newtuple)) {
-			ret = 0;
-		} else {
-			/* Force NAT to choose again the same port */
-			ret = -1;
+	WRITE_LOCK(&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)) {
+			ret = -EBUSY;
+			goto out;
 		}
 	}
-	WRITE_UNLOCK(&ip_conntrack_expect_tuple_lock);
-	
-	return ret;
+
+	/* Will be over limit? */
+	if (expect->master->helper->max_expected && 
+	    expect->master->expecting >= expect->master->helper->max_expected)
+		evict_oldest_expect(expect->master);
+
+	ip_conntrack_expect_insert(expect);
+	ret = 0;
+out:
+	WRITE_UNLOCK(&ip_conntrack_lock);
+ 	return ret;
 }
 
-/* Alter reply tuple (maybe alter helper).  If it's already taken,
-   return 0 and don't do alteration. */
-int ip_conntrack_alter_reply(struct ip_conntrack *conntrack,
-			     const struct ip_conntrack_tuple *newreply)
+/* Alter reply tuple (maybe alter helper).  This is for NAT, and is
+   implicitly racy: see __ip_conntrack_confirm */
+void ip_conntrack_alter_reply(struct ip_conntrack *conntrack,
+			      const struct ip_conntrack_tuple *newreply)
 {
 	WRITE_LOCK(&ip_conntrack_lock);
-	if (__ip_conntrack_find(newreply, conntrack)) {
-		WRITE_UNLOCK(&ip_conntrack_lock);
-		return 0;
-	}
 	/* Should be unconfirmed, so not in hash table yet */
 	IP_NF_ASSERT(!is_confirmed(conntrack));
 
@@ -1030,15 +849,14 @@
 	DUMP_TUPLE(newreply);
 
 	conntrack->tuplehash[IP_CT_DIR_REPLY].tuple = *newreply;
-	if (!conntrack->master && list_empty(&conntrack->sibling_list))
+	if (!conntrack->master && conntrack->expecting == 0)
 		conntrack->helper = ip_ct_find_helper(newreply);
 	WRITE_UNLOCK(&ip_conntrack_lock);
-
-	return 1;
 }
 
 int ip_conntrack_helper_register(struct ip_conntrack_helper *me)
 {
+	BUG_ON(me->timeout == 0);
 	WRITE_LOCK(&ip_conntrack_lock);
 	list_prepend(&helpers, me);
 	WRITE_UNLOCK(&ip_conntrack_lock);
@@ -1049,24 +867,29 @@
 static inline int unhelp(struct ip_conntrack_tuple_hash *i,
 			 const struct ip_conntrack_helper *me)
 {
-	if (i->ctrack->helper == me) {
-		/* Get rid of any expected. */
-		remove_expectations(i->ctrack, 0);
-		/* And *then* set helper to NULL */
-		i->ctrack->helper = NULL;
-	}
+	if (tuplehash_to_ctrack(i)->helper == me)
+		tuplehash_to_ctrack(i)->helper = NULL;
 	return 0;
 }
 
 void ip_conntrack_helper_unregister(struct ip_conntrack_helper *me)
 {
 	unsigned int i;
+	struct ip_conntrack_expect *exp, *tmp;
 
 	/* Need write lock here, to delete helper. */
 	WRITE_LOCK(&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);
+		}
+	}
 	/* Get rid of expecteds, set helpers to NULL. */
+	LIST_FIND_W(&unconfirmed, unhelp, struct ip_conntrack_tuple_hash*, me);
 	for (i = 0; i < ip_conntrack_htable_size; i++)
 		LIST_FIND_W(&ip_conntrack_hash[i], unhelp,
 			    struct ip_conntrack_tuple_hash *, me);
@@ -1113,29 +936,22 @@
 	}
 }
 
-int ip_ct_no_defrag;
-
 /* Returns new sk_buff, or NULL */
 struct sk_buff *
-ip_ct_gather_frags(struct sk_buff *skb)
+ip_ct_gather_frags(struct sk_buff *skb, u_int32_t user)
 {
 	struct sock *sk = skb->sk;
 #ifdef CONFIG_NETFILTER_DEBUG
 	unsigned int olddebug = skb->nf_debug;
 #endif
 
-	if (unlikely(ip_ct_no_defrag)) {
-		kfree_skb(skb);
-		return NULL;
-	}
-
 	if (sk) {
 		sock_hold(sk);
 		skb_orphan(skb);
 	}
 
 	local_bh_disable(); 
-	skb = ip_defrag(skb);
+	skb = ip_defrag(skb, user);
 	local_bh_enable();
 
 	if (!skb) {
@@ -1179,46 +995,51 @@
 }
 
 static inline int
-do_kill(const struct ip_conntrack_tuple_hash *i,
-	int (*kill)(const struct ip_conntrack *i, void *data),
+do_iter(const struct ip_conntrack_tuple_hash *i,
+	int (*iter)(struct ip_conntrack *i, void *data),
 	void *data)
 {
-	return kill(i->ctrack, data);
+	return iter(tuplehash_to_ctrack(i), data);
 }
 
 /* Bring out ya dead! */
 static struct ip_conntrack_tuple_hash *
-get_next_corpse(int (*kill)(const struct ip_conntrack *i, void *data),
+get_next_corpse(int (*iter)(struct ip_conntrack *i, void *data),
 		void *data, unsigned int *bucket)
 {
 	struct ip_conntrack_tuple_hash *h = NULL;
 
-	READ_LOCK(&ip_conntrack_lock);
-	for (; !h && *bucket < ip_conntrack_htable_size; (*bucket)++) {
-		h = LIST_FIND(&ip_conntrack_hash[*bucket], do_kill,
-			      struct ip_conntrack_tuple_hash *, kill, data);
+	WRITE_LOCK(&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);
+		if (h)
+			break;
 	}
+	if (!h)
+		h = LIST_FIND_W(&unconfirmed, do_iter,
+				struct ip_conntrack_tuple_hash *, iter, data);
 	if (h)
-		atomic_inc(&h->ctrack->ct_general.use);
-	READ_UNLOCK(&ip_conntrack_lock);
+		atomic_inc(&tuplehash_to_ctrack(h)->ct_general.use);
+	WRITE_UNLOCK(&ip_conntrack_lock);
 
 	return h;
 }
 
 void
-ip_ct_selective_cleanup(int (*kill)(const struct ip_conntrack *i, void *data),
-			void *data)
+ip_ct_iterate_cleanup(int (*iter)(struct ip_conntrack *i, void *), void *data)
 {
 	struct ip_conntrack_tuple_hash *h;
 	unsigned int bucket = 0;
 
-	while ((h = get_next_corpse(kill, data, &bucket)) != NULL) {
+	while ((h = get_next_corpse(iter, data, &bucket)) != NULL) {
+		struct ip_conntrack *ct = tuplehash_to_ctrack(h);
 		/* Time to push up daises... */
-		if (del_timer(&h->ctrack->timeout))
-			death_by_timeout((unsigned long)h->ctrack);
+		if (del_timer(&ct->timeout))
+			death_by_timeout((unsigned long)ct);
 		/* ... else the timer will get him soon. */
 
-		ip_conntrack_put(h->ctrack);
+		ip_conntrack_put(ct);
 	}
 }
 
@@ -1229,7 +1050,7 @@
 static int
 getorigdst(struct sock *sk, int optval, void __user *user, int *len)
 {
-	struct inet_opt *inet = inet_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
 	struct ip_conntrack_tuple_hash *h;
 	struct ip_conntrack_tuple tuple;
 	
@@ -1255,16 +1076,17 @@
 	h = ip_conntrack_find_get(&tuple, NULL);
 	if (h) {
 		struct sockaddr_in sin;
+		struct ip_conntrack *ct = tuplehash_to_ctrack(h);
 
 		sin.sin_family = AF_INET;
-		sin.sin_port = h->ctrack->tuplehash[IP_CT_DIR_ORIGINAL]
+		sin.sin_port = ct->tuplehash[IP_CT_DIR_ORIGINAL]
 			.tuple.dst.u.tcp.port;
-		sin.sin_addr.s_addr = h->ctrack->tuplehash[IP_CT_DIR_ORIGINAL]
+		sin.sin_addr.s_addr = ct->tuplehash[IP_CT_DIR_ORIGINAL]
 			.tuple.dst.ip;
 
 		DEBUGP("SO_ORIGINAL_DST: %u.%u.%u.%u %u\n",
 		       NIPQUAD(sin.sin_addr.s_addr), ntohs(sin.sin_port));
-		ip_conntrack_put(h->ctrack);
+		ip_conntrack_put(ct);
 		if (copy_to_user(user, &sin, sizeof(sin)) != 0)
 			return -EFAULT;
 		else
@@ -1283,11 +1105,21 @@
 	.get		= &getorigdst,
 };
 
-static int kill_all(const struct ip_conntrack *i, void *data)
+static int kill_all(struct ip_conntrack *i, void *data)
 {
 	return 1;
 }
 
+static void free_conntrack_hash(void)
+{
+	if (ip_conntrack_vmalloc)
+		vfree(ip_conntrack_hash);
+	else
+		free_pages((unsigned long)ip_conntrack_hash, 
+			   get_order(sizeof(struct list_head)
+				     * ip_conntrack_htable_size));
+}
+
 /* Mishearing the voices in his head, our hero wonders how he's
    supposed to kill the mall. */
 void ip_conntrack_cleanup(void)
@@ -1299,7 +1131,7 @@
 	synchronize_net();
  
  i_see_dead_people:
-	ip_ct_selective_cleanup(kill_all, NULL);
+	ip_ct_iterate_cleanup(kill_all, NULL);
 	if (atomic_read(&ip_conntrack_count) != 0) {
 		schedule();
 		goto i_see_dead_people;
@@ -1307,7 +1139,7 @@
 
 	kmem_cache_destroy(ip_conntrack_cachep);
 	kmem_cache_destroy(ip_conntrack_expect_cachep);
-	vfree(ip_conntrack_hash);
+	free_conntrack_hash();
 	nf_unregister_sockopt(&so_getorigdst);
 }
 
@@ -1345,8 +1177,20 @@
 		return ret;
 	}
 
-	ip_conntrack_hash = vmalloc(sizeof(struct list_head)
-				    * ip_conntrack_htable_size);
+	/* AK: the hash table is twice as big than needed because it
+	   uses list_head.  it would be much nicer to caches to use a
+	   single pointer list head here. */
+	ip_conntrack_vmalloc = 0; 
+	ip_conntrack_hash 
+		=(void*)__get_free_pages(GFP_KERNEL, 
+					 get_order(sizeof(struct list_head)
+						   *ip_conntrack_htable_size));
+	if (!ip_conntrack_hash) { 
+		ip_conntrack_vmalloc = 1;
+		printk(KERN_WARNING "ip_conntrack: falling back to vmalloc.\n");
+		ip_conntrack_hash = vmalloc(sizeof(struct list_head)
+					    * ip_conntrack_htable_size);
+	}
 	if (!ip_conntrack_hash) {
 		printk(KERN_ERR "Unable to create ip_conntrack_hash\n");
 		goto err_unreg_sockopt;
@@ -1354,7 +1198,7 @@
 
 	ip_conntrack_cachep = kmem_cache_create("ip_conntrack",
 	                                        sizeof(struct ip_conntrack), 0,
-	                                        SLAB_HWCACHE_ALIGN, NULL, NULL);
+	                                        0, NULL, NULL);
 	if (!ip_conntrack_cachep) {
 		printk(KERN_ERR "Unable to create ip_conntrack slab cache\n");
 		goto err_free_hash;
@@ -1362,7 +1206,7 @@
 
 	ip_conntrack_expect_cachep = kmem_cache_create("ip_conntrack_expect",
 					sizeof(struct ip_conntrack_expect),
-					0, SLAB_HWCACHE_ALIGN, NULL, NULL);
+					0, 0, NULL, NULL);
 	if (!ip_conntrack_expect_cachep) {
 		printk(KERN_ERR "Unable to create ip_expect slab cache\n");
 		goto err_free_conntrack_slab;
@@ -1395,7 +1239,7 @@
 err_free_conntrack_slab:
 	kmem_cache_destroy(ip_conntrack_cachep);
 err_free_hash:
-	vfree(ip_conntrack_hash);
+	free_conntrack_hash();
 err_unreg_sockopt:
 	nf_unregister_sockopt(&so_getorigdst);
 
diff -Nru a/net/ipv4/netfilter/ip_conntrack_ftp.c b/net/ipv4/netfilter/ip_conntrack_ftp.c
--- a/net/ipv4/netfilter/ip_conntrack_ftp.c	2005-03-01 23:39:18 -08:00
+++ b/net/ipv4/netfilter/ip_conntrack_ftp.c	2005-03-01 23:39:18 -08:00
@@ -29,7 +29,6 @@
 static char ftp_buffer[65536];
 
 static DECLARE_LOCK(ip_ftp_lock);
-struct module *ip_conntrack_ftp = THIS_MODULE;
 
 #define MAX_PORTS 8
 static int ports[MAX_PORTS];
@@ -39,6 +38,15 @@
 static int loose;
 module_param(loose, int, 0600);
 
+unsigned int (*ip_nat_ftp_hook)(struct sk_buff **pskb,
+				enum ip_conntrack_info ctinfo,
+				enum ip_ct_ftp_type type,
+				unsigned int matchoff,
+				unsigned int matchlen,
+				struct ip_conntrack_expect *exp,
+				u32 *seq);
+EXPORT_SYMBOL_GPL(ip_nat_ftp_hook);
+
 #if 0
 #define DEBUGP printk
 #else
@@ -243,24 +251,53 @@
 	return 1;
 }
 
-static int help(struct sk_buff *skb,
+/* Look up to see if we're just after a \n. */
+static int find_nl_seq(u16 seq, const struct ip_ct_ftp_master *info, int dir)
+{
+	unsigned int i;
+
+	for (i = 0; i < info->seq_aft_nl_num[dir]; i++)
+		if (info->seq_aft_nl[dir][i] == seq)
+			return 1;
+	return 0;
+}
+
+/* We don't update if it's older than what we have. */
+static void update_nl_seq(u16 nl_seq, struct ip_ct_ftp_master *info, int dir)
+{
+	unsigned int i, oldest = NUM_SEQ_TO_REMEMBER;
+
+	/* Look for oldest: if we find exact match, we're done. */
+	for (i = 0; i < info->seq_aft_nl_num[dir]; i++) {
+		if (info->seq_aft_nl[dir][i] == nl_seq)
+			return;
+
+		if (oldest == info->seq_aft_nl_num[dir]
+		    || before(info->seq_aft_nl[dir][i], oldest))
+			oldest = i;
+	}
+
+	if (info->seq_aft_nl_num[dir] < NUM_SEQ_TO_REMEMBER)
+		info->seq_aft_nl[dir][info->seq_aft_nl_num[dir]++] = nl_seq;
+	else if (oldest != NUM_SEQ_TO_REMEMBER)
+		info->seq_aft_nl[dir][oldest] = nl_seq;
+}
+
+static int help(struct sk_buff **pskb,
 		struct ip_conntrack *ct,
 		enum ip_conntrack_info ctinfo)
 {
 	unsigned int dataoff, datalen;
 	struct tcphdr _tcph, *th;
 	char *fb_ptr;
-	u_int32_t old_seq_aft_nl;
-	int old_seq_aft_nl_set, ret;
-	u_int32_t array[6] = { 0 };
+	int ret;
+	u32 seq, array[6] = { 0 };
 	int dir = CTINFO2DIR(ctinfo);
 	unsigned int matchlen, matchoff;
 	struct ip_ct_ftp_master *ct_ftp_info = &ct->help.ct_ftp_info;
 	struct ip_conntrack_expect *exp;
-	struct ip_ct_ftp_expect *exp_ftp_info;
-
 	unsigned int i;
-	int found = 0;
+	int found = 0, ends_in_nl;
 
 	/* Until there's been traffic both ways, don't look in packets. */
 	if (ctinfo != IP_CT_ESTABLISHED
@@ -269,46 +306,35 @@
 		return NF_ACCEPT;
 	}
 
-	th = skb_header_pointer(skb, skb->nh.iph->ihl*4,
+	th = skb_header_pointer(*pskb, (*pskb)->nh.iph->ihl*4,
 				sizeof(_tcph), &_tcph);
 	if (th == NULL)
 		return NF_ACCEPT;
 
-	dataoff = skb->nh.iph->ihl*4 + th->doff*4;
+	dataoff = (*pskb)->nh.iph->ihl*4 + th->doff*4;
 	/* No data? */
-	if (dataoff >= skb->len) {
-		DEBUGP("ftp: skblen = %u\n", skb->len);
+	if (dataoff >= (*pskb)->len) {
+		DEBUGP("ftp: pskblen = %u\n", (*pskb)->len);
 		return NF_ACCEPT;
 	}
-	datalen = skb->len - dataoff;
+	datalen = (*pskb)->len - dataoff;
 
 	LOCK_BH(&ip_ftp_lock);
-	fb_ptr = skb_header_pointer(skb, dataoff,
-				    skb->len - dataoff, ftp_buffer);
+	fb_ptr = skb_header_pointer(*pskb, dataoff,
+				    (*pskb)->len - dataoff, ftp_buffer);
 	BUG_ON(fb_ptr == NULL);
 
-	old_seq_aft_nl_set = ct_ftp_info->seq_aft_nl_set[dir];
-	old_seq_aft_nl = ct_ftp_info->seq_aft_nl[dir];
+	ends_in_nl = (fb_ptr[datalen - 1] == '\n');
+	seq = ntohl(th->seq) + datalen;
 
-	DEBUGP("conntrack_ftp: datalen %u\n", datalen);
-	if (fb_ptr[datalen - 1] == '\n') {
-		DEBUGP("conntrack_ftp: datalen %u ends in \\n\n", datalen);
-		if (!old_seq_aft_nl_set
-		    || after(ntohl(th->seq) + datalen, old_seq_aft_nl)) {
-			DEBUGP("conntrack_ftp: updating nl to %u\n",
-			       ntohl(th->seq) + datalen);
-			ct_ftp_info->seq_aft_nl[dir] = 
-						ntohl(th->seq) + datalen;
-			ct_ftp_info->seq_aft_nl_set[dir] = 1;
-		}
-	}
-
-	if(!old_seq_aft_nl_set ||
-			(ntohl(th->seq) != old_seq_aft_nl)) {
-		DEBUGP("ip_conntrack_ftp_help: wrong seq pos %s(%u)\n",
+	/* Look up to see if we're just after a \n. */
+	if (!find_nl_seq(ntohl(th->seq), ct_ftp_info, dir)) {
+		/* Now if this ends in \n, update ftp info. */
+		DEBUGP("ip_conntrack_ftp_help: wrong seq pos %s(%u) or %s(%u)\n",
+		       ct_ftp_info->seq_aft_nl[0][dir] 
 		       old_seq_aft_nl_set ? "":"(UNSET) ", old_seq_aft_nl);
 		ret = NF_ACCEPT;
-		goto out;
+		goto out_update_nl;
 	}
 
 	/* Initialize IP array to expected address (it's not mentioned
@@ -321,7 +347,7 @@
 	for (i = 0; i < ARRAY_SIZE(search); i++) {
 		if (search[i].dir != dir) continue;
 
-		found = find_pattern(fb_ptr, skb->len - dataoff,
+		found = find_pattern(fb_ptr, (*pskb)->len - dataoff,
 				     search[i].pattern,
 				     search[i].plen,
 				     search[i].skip,
@@ -344,30 +370,26 @@
 		goto out;
 	} else if (found == 0) { /* No match */
 		ret = NF_ACCEPT;
-		goto out;
+		goto out_update_nl;
 	}
 
-	DEBUGP("conntrack_ftp: match `%.*s' (%u bytes at %u)\n",
-	       (int)matchlen, data + matchoff,
-	       matchlen, ntohl(th->seq) + matchoff);
-
+	DEBUGP("conntrack_ftp: match `%s' (%u bytes at %u)\n",
+	       fb_ptr + matchoff, matchlen, ntohl(th->seq) + matchoff);
+			 
 	/* Allocate expectation which will be inserted */
 	exp = ip_conntrack_expect_alloc();
 	if (exp == NULL) {
-		ret = NF_ACCEPT;
+		ret = NF_DROP;
 		goto out;
 	}
 
-	exp_ftp_info = &exp->help.exp_ftp_info;
+	/* We refer to the reverse direction ("!dir") tuples here,
+	 * because we're expecting something in the other direction.
+	 * Doesn't matter unless NAT is happening.  */
+	exp->tuple.dst.ip = ct->tuplehash[!dir].tuple.dst.ip;
 
-	/* Update the ftp info */
 	if (htonl((array[0] << 24) | (array[1] << 16) | (array[2] << 8) | array[3])
-	    == ct->tuplehash[dir].tuple.src.ip) {
-		exp->seq = ntohl(th->seq) + matchoff;
-		exp_ftp_info->len = matchlen;
-		exp_ftp_info->ftptype = search[i].ftptype;
-		exp_ftp_info->port = array[4] << 8 | array[5];
-	} else {
+	    != ct->tuplehash[dir].tuple.src.ip) {
 		/* Enrico Scholz's passive FTP to partially RNAT'd ftp
 		   server: it really wants us to connect to a
 		   different IP address.  Simply don't record it for
@@ -381,28 +403,44 @@
 		   problem (DMZ machines opening holes to internal
 		   networks, or the packet filter itself). */
 		if (!loose) {
-			ip_conntrack_expect_put(exp);
 			ret = NF_ACCEPT;
-			goto out;
+			ip_conntrack_expect_free(exp);
+			goto out_update_nl;
 		}
+		exp->tuple.dst.ip = htonl((array[0] << 24) | (array[1] << 16)
+					 | (array[2] << 8) | array[3]);
 	}
 
-	exp->tuple = ((struct ip_conntrack_tuple)
-		{ { ct->tuplehash[!dir].tuple.src.ip,
-		    { 0 } },
-		  { htonl((array[0] << 24) | (array[1] << 16)
-			  | (array[2] << 8) | array[3]),
-		    { .tcp = { htons(array[4] << 8 | array[5]) } },
-		    IPPROTO_TCP }});
+	exp->tuple.src.ip = ct->tuplehash[!dir].tuple.src.ip;
+	exp->tuple.dst.u.tcp.port = htons(array[4] << 8 | array[5]);
+	exp->tuple.src.u.tcp.port = 0; /* Don't care. */
+	exp->tuple.dst.protonum = IPPROTO_TCP;
 	exp->mask = ((struct ip_conntrack_tuple)
 		{ { 0xFFFFFFFF, { 0 } },
-		  { 0xFFFFFFFF, { .tcp = { 0xFFFF } }, 0xFFFF }});
+		  { 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. */
+	if (ip_nat_ftp_hook)
+		ret = ip_nat_ftp_hook(pskb, ctinfo, search[i].ftptype,
+				      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);
+			ret = NF_DROP;
+		} else
+			ret = NF_ACCEPT;
+	}
 
-	/* Ignore failure; should only happen with NAT */
-	ip_conntrack_expect_related(exp, ct);
-	ret = NF_ACCEPT;
+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);
 	return ret;
@@ -434,11 +472,10 @@
 		ftp[i].tuple.src.u.tcp.port = htons(ports[i]);
 		ftp[i].tuple.dst.protonum = IPPROTO_TCP;
 		ftp[i].mask.src.u.tcp.port = 0xFFFF;
-		ftp[i].mask.dst.protonum = 0xFFFF;
+		ftp[i].mask.dst.protonum = 0xFF;
 		ftp[i].max_expected = 1;
-		ftp[i].timeout = 0;
-		ftp[i].flags = IP_CT_HELPER_F_REUSE_EXPECT;
-		ftp[i].me = ip_conntrack_ftp;
+		ftp[i].timeout = 5 * 60; /* 5 minutes */
+		ftp[i].me = THIS_MODULE;
 		ftp[i].help = help;
 
 		tmpname = &ftp_names[i][0];
@@ -459,8 +496,6 @@
 	}
 	return 0;
 }
-
-PROVIDES_CONNTRACK(ftp);
 
 module_init(init);
 module_exit(fini);
diff -Nru a/net/ipv4/netfilter/ip_conntrack_irc.c b/net/ipv4/netfilter/ip_conntrack_irc.c
--- a/net/ipv4/netfilter/ip_conntrack_irc.c	2005-03-01 23:39:08 -08:00
+++ b/net/ipv4/netfilter/ip_conntrack_irc.c	2005-03-01 23:39:08 -08:00
@@ -43,6 +43,13 @@
 static char irc_buffer[65536];
 static DECLARE_LOCK(irc_buffer_lock);
 
+unsigned int (*ip_nat_irc_hook)(struct sk_buff **pskb,
+				enum ip_conntrack_info ctinfo,
+				unsigned int matchoff,
+				unsigned int matchlen,
+				struct ip_conntrack_expect *exp);
+EXPORT_SYMBOL_GPL(ip_nat_irc_hook);
+
 MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
 MODULE_DESCRIPTION("IRC (DCC) connection tracking helper");
 MODULE_LICENSE("GPL");
@@ -56,8 +63,6 @@
 static char *dccprotos[] = { "SEND ", "CHAT ", "MOVE ", "TSEND ", "SCHAT " };
 #define MINMATCHLEN	5
 
-struct module *ip_conntrack_irc = THIS_MODULE;
-
 #if 0
 #define DEBUGP(format, args...) printk(KERN_DEBUG "%s:%s:" format, \
                                        __FILE__, __FUNCTION__ , ## args)
@@ -98,7 +103,7 @@
 	return 0;
 }
 
-static int help(struct sk_buff *skb,
+static int help(struct sk_buff **pskb,
 		struct ip_conntrack *ct, enum ip_conntrack_info ctinfo)
 {
 	unsigned int dataoff;
@@ -106,11 +111,10 @@
 	char *data, *data_limit, *ib_ptr;
 	int dir = CTINFO2DIR(ctinfo);
 	struct ip_conntrack_expect *exp;
-	struct ip_ct_irc_expect *exp_irc_info = NULL;
-
+	u32 seq;
 	u_int32_t dcc_ip;
 	u_int16_t dcc_port;
-	int i;
+	int i, ret = NF_ACCEPT;
 	char *addr_beg_p, *addr_end_p;
 
 	DEBUGP("entered\n");
@@ -127,23 +131,23 @@
 	}
 
 	/* Not a full tcp header? */
-	th = skb_header_pointer(skb, skb->nh.iph->ihl*4,
+	th = skb_header_pointer(*pskb, (*pskb)->nh.iph->ihl*4,
 				sizeof(_tcph), &_tcph);
 	if (th == NULL)
 		return NF_ACCEPT;
 
 	/* No data? */
-	dataoff = skb->nh.iph->ihl*4 + th->doff*4;
-	if (dataoff >= skb->len)
+	dataoff = (*pskb)->nh.iph->ihl*4 + th->doff*4;
+	if (dataoff >= (*pskb)->len)
 		return NF_ACCEPT;
 
 	LOCK_BH(&irc_buffer_lock);
-	ib_ptr = skb_header_pointer(skb, dataoff,
-				    skb->len - dataoff, irc_buffer);
+	ib_ptr = skb_header_pointer(*pskb, dataoff,
+				    (*pskb)->len - dataoff, irc_buffer);
 	BUG_ON(ib_ptr == NULL);
 
 	data = ib_ptr;
-	data_limit = ib_ptr + skb->len - dataoff;
+	data_limit = ib_ptr + (*pskb)->len - dataoff;
 
 	/* strlen("\1DCC SENT t AAAAAAAA P\1\n")=24
 	 * 5+MINMATCHLEN+strlen("t AAAAAAAA P\1\n")=14 */
@@ -195,45 +199,46 @@
 			}
 
 			exp = ip_conntrack_expect_alloc();
-			if (exp == NULL)
+			if (exp == NULL) {
+				ret = NF_DROP;
 				goto out;
-
-			exp_irc_info = &exp->help.exp_irc_info;
+			}
 
 			/* save position of address in dcc string,
 			 * necessary for NAT */
 			DEBUGP("tcph->seq = %u\n", th->seq);
-			exp->seq = ntohl(th->seq) + (addr_beg_p - ib_ptr);
-			exp_irc_info->len = (addr_end_p - addr_beg_p);
-			exp_irc_info->port = dcc_port;
-			DEBUGP("wrote info seq=%u (ofs=%u), len=%d\n",
-				exp->seq, (addr_end_p - _data), exp_irc_info->len);
+			seq = ntohl(th->seq) + (addr_beg_p - ib_ptr);
 
+			/* We refer to the reverse direction ("!dir")
+			 * tuples here, because we're expecting
+			 * something in the other * direction.
+			 * Doesn't matter unless NAT is happening.  */
 			exp->tuple = ((struct ip_conntrack_tuple)
 				{ { 0, { 0 } },
-				  { ct->tuplehash[dir].tuple.src.ip, { .tcp = { htons(dcc_port) } },
+				  { ct->tuplehash[!dir].tuple.dst.ip,
+				    { .tcp = { htons(dcc_port) } },
 				    IPPROTO_TCP }});
 			exp->mask = ((struct ip_conntrack_tuple)
 				{ { 0, { 0 } },
-				  { 0xFFFFFFFF, { .tcp = { 0xFFFF } }, 0xFFFF }});
-
+				  { 0xFFFFFFFF, { .tcp = { 0xFFFF } }, 0xFF }});
 			exp->expectfn = NULL;
-
-			DEBUGP("expect_related %u.%u.%u.%u:%u-%u.%u.%u.%u:%u\n",
-				NIPQUAD(exp->tuple.src.ip),
-				ntohs(exp->tuple.src.u.tcp.port),
-				NIPQUAD(exp->tuple.dst.ip),
-				ntohs(exp->tuple.dst.u.tcp.port));
-
-			ip_conntrack_expect_related(exp, ct);
-
+			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);
+				ret = NF_DROP;
+			}
 			goto out;
 		} /* for .. NUM_DCCPROTO */
 	} /* while data < ... */
 
  out:
 	UNLOCK_BH(&irc_buffer_lock);
-	return NF_ACCEPT;
+	return ret;
 }
 
 static struct ip_conntrack_helper irc_helpers[MAX_PORTS];
@@ -265,11 +270,10 @@
 		hlpr->tuple.src.u.tcp.port = htons(ports[i]);
 		hlpr->tuple.dst.protonum = IPPROTO_TCP;
 		hlpr->mask.src.u.tcp.port = 0xFFFF;
-		hlpr->mask.dst.protonum = 0xFFFF;
+		hlpr->mask.dst.protonum = 0xFF;
 		hlpr->max_expected = max_dcc_channels;
 		hlpr->timeout = dcc_timeout;
-		hlpr->flags = IP_CT_HELPER_F_REUSE_EXPECT;
-		hlpr->me = ip_conntrack_irc;
+		hlpr->me = THIS_MODULE;
 		hlpr->help = help;
 
 		tmpname = &irc_names[i][0];
@@ -304,8 +308,6 @@
 		ip_conntrack_helper_unregister(&irc_helpers[i]);
 	}
 }
-
-PROVIDES_CONNTRACK(irc);
 
 module_init(init);
 module_exit(fini);
diff -Nru a/net/ipv4/netfilter/ip_conntrack_proto_icmp.c b/net/ipv4/netfilter/ip_conntrack_proto_icmp.c
--- a/net/ipv4/netfilter/ip_conntrack_proto_icmp.c	2005-03-01 23:38:51 -08:00
+++ b/net/ipv4/netfilter/ip_conntrack_proto_icmp.c	2005-03-01 23:38:51 -08:00
@@ -196,7 +196,7 @@
 	}
 
 	/* Update skb to refer to this connection */
-	skb->nfct = &h->ctrack->ct_general;
+	skb->nfct = &tuplehash_to_ctrack(h)->ct_general;
 	skb->nfctinfo = *ctinfo;
 	return -NF_ACCEPT;
 }
diff -Nru 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	2005-03-01 23:39:10 -08:00
+++ b/net/ipv4/netfilter/ip_conntrack_proto_sctp.c	2005-03-01 23:39:10 -08:00
@@ -58,13 +58,13 @@
 #define HOURS * 60 MINS
 #define DAYS  * 24 HOURS
 
-unsigned long ip_ct_sctp_timeout_closed            =  10 SECS;
-unsigned long ip_ct_sctp_timeout_cookie_wait       =   3 SECS;
-unsigned long ip_ct_sctp_timeout_cookie_echoed     =   3 SECS;
-unsigned long ip_ct_sctp_timeout_established       =   5 DAYS;
-unsigned long ip_ct_sctp_timeout_shutdown_sent     = 300 SECS / 1000;
-unsigned long ip_ct_sctp_timeout_shutdown_recd     = 300 SECS / 1000;
-unsigned long ip_ct_sctp_timeout_shutdown_ack_sent =   3 SECS;
+static unsigned long ip_ct_sctp_timeout_closed            =  10 SECS;
+static unsigned long ip_ct_sctp_timeout_cookie_wait       =   3 SECS;
+static unsigned long ip_ct_sctp_timeout_cookie_echoed     =   3 SECS;
+static unsigned long ip_ct_sctp_timeout_established       =   5 DAYS;
+static unsigned long ip_ct_sctp_timeout_shutdown_sent     = 300 SECS / 1000;
+static unsigned long ip_ct_sctp_timeout_shutdown_recd     = 300 SECS / 1000;
+static unsigned long ip_ct_sctp_timeout_shutdown_ack_sent =   3 SECS;
 
 static unsigned long * sctp_timeouts[]
 = { NULL,                                  /* SCTP_CONNTRACK_NONE  */
@@ -494,14 +494,7 @@
 	return 1;
 }
 
-static int sctp_exp_matches_pkt(struct ip_conntrack_expect *exp,
-				const struct sk_buff *skb)
-{
-	/* To be implemented */
-	return 0;
-}
-
-struct ip_conntrack_protocol ip_conntrack_protocol_sctp = { 
+static struct ip_conntrack_protocol ip_conntrack_protocol_sctp = { 
 	.proto 		 = IPPROTO_SCTP, 
 	.name 		 = "sctp",
 	.pkt_to_tuple 	 = sctp_pkt_to_tuple, 
@@ -511,7 +504,6 @@
 	.packet 	 = sctp_packet, 
 	.new 		 = sctp_new, 
 	.destroy 	 = NULL, 
-	.exp_matches_pkt = sctp_exp_matches_pkt, 
 	.me 		 = THIS_MODULE 
 };
 
@@ -609,7 +601,7 @@
 static struct ctl_table_header *ip_ct_sysctl_header;
 #endif
 
-int __init init(void)
+static int __init init(void)
 {
 	int ret;
 
@@ -622,6 +614,7 @@
 #ifdef CONFIG_SYSCTL
 	ip_ct_sysctl_header = register_sysctl_table(ip_ct_net_table, 0);
 	if (ip_ct_sysctl_header == NULL) {
+		ret = -ENOMEM;
 		printk("ip_conntrack_proto_sctp: can't register to sysctl.\n");
 		goto cleanup;
 	}
@@ -639,7 +632,7 @@
 	return ret;
 }
 
-void __exit fini(void)
+static void __exit fini(void)
 {
 	ip_conntrack_protocol_unregister(&ip_conntrack_protocol_sctp);
 #ifdef CONFIG_SYSCTL
diff -Nru 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	2005-03-01 23:39:17 -08:00
+++ b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c	2005-03-01 23:39:17 -08:00
@@ -665,11 +665,13 @@
 		if (*index == TCP_ACK_SET) {
 			if (state->last_dir == dir
 			    && state->last_seq == seq
+			    && state->last_ack == ack
 			    && state->last_end == end)
 				state->retrans++;
 			else {
 				state->last_dir = dir;
 				state->last_seq = seq;
+				state->last_ack = ack;
 				state->last_end = end;
 				state->retrans = 0;
 			}
@@ -707,9 +709,9 @@
 
 #ifdef CONFIG_IP_NF_NAT_NEEDED
 /* Update sender->td_end after NAT successfully mangled the packet */
-int ip_conntrack_tcp_update(struct sk_buff *skb,
-			    struct ip_conntrack *conntrack, 
-			    int dir)
+void ip_conntrack_tcp_update(struct sk_buff *skb,
+			     struct ip_conntrack *conntrack, 
+			     enum ip_conntrack_dir dir)
 {
 	struct iphdr *iph = skb->nh.iph;
 	struct tcphdr *tcph = (void *)skb->nh.iph + skb->nh.iph->ihl*4;
@@ -735,8 +737,6 @@
 		sender->td_scale, 
 		receiver->td_end, receiver->td_maxend, receiver->td_maxwin,
 		receiver->td_scale);
-		
-	return 1;
 }
  
 #endif
@@ -906,7 +906,8 @@
 		if (index == TCP_RST_SET
 		    && ((test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)
 		         && conntrack->proto.tcp.last_index <= TCP_SYNACK_SET)
-		        || conntrack->proto.tcp.last_index == TCP_ACK_SET)
+		        || (!test_bit(IPS_ASSURED_BIT, &conntrack->status)
+			 && conntrack->proto.tcp.last_index == TCP_ACK_SET))
 		    && after(ntohl(th->ack_seq),
 		    	     conntrack->proto.tcp.last_seq)) {
 			/* Ignore RST closing down invalid SYN or ACK
@@ -1060,22 +1061,6 @@
 	return 1;
 }
   
-static int tcp_exp_matches_pkt(struct ip_conntrack_expect *exp,
-			       const struct sk_buff *skb)
-{
-	const struct iphdr *iph = skb->nh.iph;
-	struct tcphdr *th, _tcph;
-	unsigned int datalen;
-
-	th = skb_header_pointer(skb, iph->ihl * 4,
-				sizeof(_tcph), &_tcph);
-	if (th == NULL)
-		return 0;
-	datalen = skb->len - iph->ihl*4 - th->doff*4;
-
-	return between(exp->seq, ntohl(th->seq), ntohl(th->seq) + datalen);
-}
-
 struct ip_conntrack_protocol ip_conntrack_protocol_tcp =
 {
 	.proto 			= IPPROTO_TCP,
@@ -1086,6 +1071,5 @@
 	.print_conntrack 	= tcp_print_conntrack,
 	.packet 		= tcp_packet,
 	.new 			= tcp_new,
-	.exp_matches_pkt	= tcp_exp_matches_pkt,
 	.error			= tcp_error,
 };
diff -Nru a/net/ipv4/netfilter/ip_conntrack_standalone.c b/net/ipv4/netfilter/ip_conntrack_standalone.c
--- a/net/ipv4/netfilter/ip_conntrack_standalone.c	2005-03-01 23:38:56 -08:00
+++ b/net/ipv4/netfilter/ip_conntrack_standalone.c	2005-03-01 23:38:56 -08:00
@@ -48,7 +48,7 @@
 extern atomic_t ip_conntrack_count;
 DECLARE_PER_CPU(struct ip_conntrack_stat, ip_conntrack_stat);
 
-static int kill_proto(const struct ip_conntrack *i, void *data)
+static int kill_proto(struct ip_conntrack *i, void *data)
 {
 	return (i->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum == 
 			*((u_int8_t *) data));
@@ -66,7 +66,8 @@
 
 #ifdef CONFIG_IP_NF_CT_ACCT
 static unsigned int
-seq_print_counters(struct seq_file *s, struct ip_conntrack_counter *counter)
+seq_print_counters(struct seq_file *s,
+		   const struct ip_conntrack_counter *counter)
 {
 	return seq_printf(s, "packets=%llu bytes=%llu ",
 			  (unsigned long long)counter->packets,
@@ -99,7 +100,7 @@
 static int ct_seq_real_show(const struct ip_conntrack_tuple_hash *hash,
 			    struct seq_file *s)
 {
-	struct ip_conntrack *conntrack = hash->ctrack;
+	const struct ip_conntrack *conntrack = tuplehash_to_ctrack(hash);
 	struct ip_conntrack_protocol *proto;
 
 	MUST_BE_READ_LOCKED(&ip_conntrack_lock);
@@ -200,7 +201,6 @@
 	/* 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(&ip_conntrack_expect_tuple_lock);
 
 	if (list_empty(e))
 		return NULL;
@@ -227,7 +227,6 @@
 
 static void exp_seq_stop(struct seq_file *s, void *v)
 {
-	READ_UNLOCK(&ip_conntrack_expect_tuple_lock);
 	READ_UNLOCK(&ip_conntrack_lock);
 }
 
@@ -235,14 +234,13 @@
 {
 	struct ip_conntrack_expect *expect = v;
 
-	if (expect->expectant->helper->timeout)
+	if (expect->timeout.function)
 		seq_printf(s, "%lu ", timer_pending(&expect->timeout)
 			   ? (expect->timeout.expires - jiffies)/HZ : 0);
 	else
 		seq_printf(s, "- ");
 
-	seq_printf(s, "use=%u proto=%u ", atomic_read(&expect->use),
-		   expect->tuple.dst.protonum);
+	seq_printf(s, "proto=%u ", expect->tuple.dst.protonum);
 
 	print_tuple(s, &expect->tuple,
 		    ip_ct_find_proto(expect->tuple.dst.protonum));
@@ -364,8 +362,20 @@
 			       const struct net_device *out,
 			       int (*okfn)(struct sk_buff *))
 {
+	struct ip_conntrack *ct;
+	enum ip_conntrack_info ctinfo;
+
+	/* This is where we call the helper: as the packet goes out. */
+	ct = ip_conntrack_get(*pskb, &ctinfo);
+	if (ct && ct->helper) {
+		unsigned int ret;
+		ret = ct->helper->help(pskb, ct, ctinfo);
+		if (ret != NF_ACCEPT)
+			return ret;
+	}
+
 	/* We've seen it coming out the other side: confirm it */
-	return ip_conntrack_confirm(*pskb);
+	return ip_conntrack_confirm(pskb);
 }
 
 static unsigned int ip_conntrack_defrag(unsigned int hooknum,
@@ -374,14 +384,19 @@
 				        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);
+		*pskb = ip_ct_gather_frags(*pskb,
+		                           hooknum == NF_IP_PRE_ROUTING ? 
+					   IP_DEFRAG_CONNTRACK_IN :
+					   IP_DEFRAG_CONNTRACK_OUT);
 		if (!*pskb)
 			return NF_STOLEN;
 	}
@@ -791,7 +806,8 @@
 	ip_ct_sysctl_header = register_sysctl_table(ip_ct_net_table, 0);
 	if (ip_ct_sysctl_header == NULL) {
 		printk("ip_conntrack: can't register to sysctl.\n");
-		goto cleanup;
+		ret = -ENOMEM;
+		goto cleanup_localinops;
 	}
 #endif
 
@@ -800,6 +816,7 @@
  cleanup:
 #ifdef CONFIG_SYSCTL
  	unregister_sysctl_table(ip_ct_sysctl_header);
+ cleanup_localinops:
 #endif
 	nf_unregister_hook(&ip_conntrack_local_in_ops);
  cleanup_inoutandlocalops:
@@ -811,17 +828,11 @@
  cleanup_defraglocalops:
 	nf_unregister_hook(&ip_conntrack_defrag_local_out_ops);
  cleanup_defragops:
-	/* Frag queues may hold fragments with skb->dst == NULL */
-	ip_ct_no_defrag = 1;
-	synchronize_net();
-	local_bh_disable();
-	ipfrag_flush();
-	local_bh_enable();
 	nf_unregister_hook(&ip_conntrack_defrag_ops);
  cleanup_proc_stat:
 #ifdef CONFIG_PROC_FS
-	proc_net_remove("ip_conntrack_stat");
-cleanup_proc_exp:
+	remove_proc_entry("ip_conntrack", proc_net_stat);
+ cleanup_proc_exp:
 	proc_net_remove("ip_conntrack_expect");
  cleanup_proc:
 	proc_net_remove("ip_conntrack");
@@ -859,7 +870,7 @@
 	synchronize_net();
 
 	/* Remove all contrack entries for this protocol */
-	ip_ct_selective_cleanup(kill_proto, &proto->proto);
+	ip_ct_iterate_cleanup(kill_proto, &proto->proto);
 }
 
 static int __init init(void)
@@ -883,27 +894,24 @@
 
 EXPORT_SYMBOL(ip_conntrack_protocol_register);
 EXPORT_SYMBOL(ip_conntrack_protocol_unregister);
+EXPORT_SYMBOL(ip_ct_get_tuple);
 EXPORT_SYMBOL(invert_tuplepr);
 EXPORT_SYMBOL(ip_conntrack_alter_reply);
 EXPORT_SYMBOL(ip_conntrack_destroyed);
 EXPORT_SYMBOL(need_ip_conntrack);
 EXPORT_SYMBOL(ip_conntrack_helper_register);
 EXPORT_SYMBOL(ip_conntrack_helper_unregister);
-EXPORT_SYMBOL(ip_ct_selective_cleanup);
+EXPORT_SYMBOL(ip_ct_iterate_cleanup);
 EXPORT_SYMBOL(ip_ct_refresh_acct);
 EXPORT_SYMBOL(ip_ct_protos);
 EXPORT_SYMBOL(ip_ct_find_proto);
-EXPORT_SYMBOL(ip_ct_find_helper);
 EXPORT_SYMBOL(ip_conntrack_expect_alloc);
+EXPORT_SYMBOL(ip_conntrack_expect_free);
 EXPORT_SYMBOL(ip_conntrack_expect_related);
-EXPORT_SYMBOL(ip_conntrack_change_expect);
 EXPORT_SYMBOL(ip_conntrack_unexpect_related);
-EXPORT_SYMBOL_GPL(ip_conntrack_expect_find_get);
-EXPORT_SYMBOL_GPL(ip_conntrack_expect_put);
 EXPORT_SYMBOL(ip_conntrack_tuple_taken);
 EXPORT_SYMBOL(ip_ct_gather_frags);
 EXPORT_SYMBOL(ip_conntrack_htable_size);
-EXPORT_SYMBOL(ip_conntrack_expect_list);
 EXPORT_SYMBOL(ip_conntrack_lock);
 EXPORT_SYMBOL(ip_conntrack_hash);
 EXPORT_SYMBOL(ip_conntrack_untracked);
diff -Nru a/net/ipv4/netfilter/ip_conntrack_tftp.c b/net/ipv4/netfilter/ip_conntrack_tftp.c
--- a/net/ipv4/netfilter/ip_conntrack_tftp.c	2005-03-01 23:38:55 -08:00
+++ b/net/ipv4/netfilter/ip_conntrack_tftp.c	2005-03-01 23:38:55 -08:00
@@ -38,15 +38,21 @@
 #define DEBUGP(format, args...)
 #endif
 
-static int tftp_help(struct sk_buff *skb,
+unsigned int (*ip_nat_tftp_hook)(struct sk_buff **pskb,
+				 enum ip_conntrack_info ctinfo,
+				 struct ip_conntrack_expect *exp);
+EXPORT_SYMBOL_GPL(ip_nat_tftp_hook);
+
+static int tftp_help(struct sk_buff **pskb,
 		     struct ip_conntrack *ct,
 		     enum ip_conntrack_info ctinfo)
 {
 	struct tftphdr _tftph, *tfh;
 	struct ip_conntrack_expect *exp;
+	unsigned int ret = NF_ACCEPT;
 
-	tfh = skb_header_pointer(skb,
-				 skb->nh.iph->ihl * 4 + sizeof(struct udphdr),
+	tfh = skb_header_pointer(*pskb,
+				 (*pskb)->nh.iph->ihl*4+sizeof(struct udphdr),
 				 sizeof(_tftph), &_tftph);
 	if (tfh == NULL)
 		return NF_ACCEPT;
@@ -61,19 +67,25 @@
 
 		exp = ip_conntrack_expect_alloc();
 		if (exp == NULL)
-			return NF_ACCEPT;
+			return NF_DROP;
 
 		exp->tuple = ct->tuplehash[IP_CT_DIR_REPLY].tuple;
 		exp->mask.src.ip = 0xffffffff;
 		exp->mask.dst.ip = 0xffffffff;
 		exp->mask.dst.u.udp.port = 0xffff;
-		exp->mask.dst.protonum = 0xffff;
+		exp->mask.dst.protonum = 0xff;
 		exp->expectfn = NULL;
+		exp->master = ct;
 
 		DEBUGP("expect: ");
 		DUMP_TUPLE(&exp->tuple);
 		DUMP_TUPLE(&exp->mask);
-		ip_conntrack_expect_related(exp, ct);
+		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);
+			ret = NF_DROP;
+		}
 		break;
 	case TFTP_OPCODE_DATA:
 	case TFTP_OPCODE_ACK:
@@ -116,11 +128,10 @@
 
 		tftp[i].tuple.dst.protonum = IPPROTO_UDP;
 		tftp[i].tuple.src.u.udp.port = htons(ports[i]);
-		tftp[i].mask.dst.protonum = 0xFFFF;
+		tftp[i].mask.dst.protonum = 0xFF;
 		tftp[i].mask.src.u.udp.port = 0xFFFF;
 		tftp[i].max_expected = 1;
-		tftp[i].timeout = 0;
-		tftp[i].flags = IP_CT_HELPER_F_REUSE_EXPECT;
+		tftp[i].timeout = 5 * 60; /* 5 minutes */
 		tftp[i].me = THIS_MODULE;
 		tftp[i].help = tftp_help;
 
@@ -143,8 +154,6 @@
 	}
 	return(0);
 }
-
-PROVIDES_CONNTRACK(tftp);
 
 module_init(init);
 module_exit(fini);
diff -Nru a/net/ipv4/netfilter/ip_fw_compat.c b/net/ipv4/netfilter/ip_fw_compat.c
--- a/net/ipv4/netfilter/ip_fw_compat.c	2005-03-01 23:38:55 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,303 +0,0 @@
-/* Compatibility framework for ipchains and ipfwadm support; designed
-   to look as much like the 2.2 infrastructure as possible. */
-
-/* (C) 1999-2001 Paul `Rusty' Russell
- * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.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.
- */
-
-struct notifier_block;
-
-#include <linux/netfilter_ipv4.h>
-#include <linux/ip.h>
-#include <net/icmp.h>
-#include <linux/if.h>
-#include <linux/inetdevice.h>
-#include <linux/netdevice.h>
-#include <linux/module.h>
-#include <asm/uaccess.h>
-#include <net/ip.h>
-#include <net/route.h>
-#include <linux/netfilter_ipv4/compat_firewall.h>
-#include <linux/netfilter_ipv4/ip_conntrack.h>
-#include <linux/netfilter_ipv4/ip_conntrack_core.h>
-#include "ip_fw_compat.h"
-
-static struct firewall_ops *fwops;
-
-#ifdef CONFIG_IP_VS
-/* From ip_vs_core.c */
-extern unsigned int
-check_for_ip_vs_out(struct sk_buff **skb_p, int (*okfn)(struct sk_buff *));
-#endif
-
-/* They call these; we do what they want. */
-int register_firewall(int pf, struct firewall_ops *fw)
-{
-	if (pf != PF_INET) {
-		printk("Attempt to register non-IP firewall module.\n");
-		return -EINVAL;
-	}
-	if (fwops) {
-		printk("Attempt to register multiple firewall modules.\n");
-		return -EBUSY;
-	}
-
-	fwops = fw;
-	return 0;
-}
-
-int unregister_firewall(int pf, struct firewall_ops *fw)
-{
-	fwops = NULL;
-	return 0;
-}
-
-static unsigned int
-fw_in(unsigned int hooknum,
-      struct sk_buff **pskb,
-      const struct net_device *in,
-      const struct net_device *out,
-      int (*okfn)(struct sk_buff *))
-{
-	int ret = FW_BLOCK;
-	u_int16_t redirpt;
-
-	/* Assume worse case: any hook could change packet */
-	(*pskb)->nfcache |= NFC_UNKNOWN | NFC_ALTERED;
-	if ((*pskb)->ip_summed == CHECKSUM_HW)
-		if (skb_checksum_help(*pskb, (out == NULL)))
-			return NF_DROP;
-
-	switch (hooknum) {
-	case NF_IP_PRE_ROUTING:
-		if (fwops->fw_acct_in)
-			fwops->fw_acct_in(fwops, PF_INET,
-					  (struct net_device *)in,
-					  &redirpt, pskb);
-
-		if ((*pskb)->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) {
-			*pskb = ip_ct_gather_frags(*pskb);
-
-			if (!*pskb)
-				return NF_STOLEN;
-		}
-
-		ret = fwops->fw_input(fwops, PF_INET, (struct net_device *)in,
-				      &redirpt, pskb);
-		break;
-
-	case NF_IP_FORWARD:
-		/* Connection will only be set if it was
-                   demasqueraded: if so, skip forward chain. */
-		if ((*pskb)->nfct)
-			ret = FW_ACCEPT;
-		else ret = fwops->fw_forward(fwops, PF_INET,
-					     (struct net_device *)out,
-					     &redirpt, pskb);
-		break;
-
-	case NF_IP_POST_ROUTING:
-		ret = fwops->fw_output(fwops, PF_INET,
-				       (struct net_device *)out,
-				       &redirpt, pskb);
-		if (ret == FW_ACCEPT || ret == FW_SKIP) {
-			if (fwops->fw_acct_out)
-				fwops->fw_acct_out(fwops, PF_INET,
-						   (struct net_device *)out,
-						   &redirpt,
-						   pskb);
-
-			/* ip_conntrack_confirm return NF_DROP or NF_ACCEPT */
-			if (ip_conntrack_confirm(*pskb) == NF_DROP)
-				ret = FW_BLOCK;
-		}
-		break;
-	}
-
-	switch (ret) {
-	case FW_REJECT: {
-		/* Alexey says:
-		 *
-		 * Generally, routing is THE FIRST thing to make, when
-		 * packet enters IP stack. Before packet is routed you
-		 * cannot call any service routines from IP stack.  */
-		struct iphdr *iph = (*pskb)->nh.iph;
-
-		if ((*pskb)->dst != NULL
-		    || ip_route_input(*pskb, iph->daddr, iph->saddr, iph->tos,
-				      (struct net_device *)in) == 0)
-			icmp_send(*pskb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH,
-				  0);
-		return NF_DROP;
-	}
-
-	case FW_ACCEPT:
-	case FW_SKIP:
-		if (hooknum == NF_IP_PRE_ROUTING) {
-			check_for_demasq(pskb);
-			check_for_redirect(*pskb);
-		} else if (hooknum == NF_IP_POST_ROUTING) {
-			check_for_unredirect(*pskb);
-			/* Handle ICMP errors from client here */
-			if ((*pskb)->nh.iph->protocol == IPPROTO_ICMP
-			    && (*pskb)->nfct)
-				check_for_masq_error(pskb);
-		}
-		return NF_ACCEPT;
-
-	case FW_MASQUERADE:
-		if (hooknum == NF_IP_FORWARD) {
-#ifdef CONFIG_IP_VS
-			/* check if it is for ip_vs */
-			if (check_for_ip_vs_out(pskb, okfn) == NF_STOLEN)
-				return NF_STOLEN;
-#endif
-			return do_masquerade(pskb, out);
-		}
-		else return NF_ACCEPT;
-
-	case FW_REDIRECT:
-		if (hooknum == NF_IP_PRE_ROUTING)
-			return do_redirect(*pskb, in, redirpt);
-		else return NF_ACCEPT;
-
-	default:
-		/* FW_BLOCK */
-		return NF_DROP;
-	}
-}
-
-static unsigned int fw_confirm(unsigned int hooknum,
-			       struct sk_buff **pskb,
-			       const struct net_device *in,
-			       const struct net_device *out,
-			       int (*okfn)(struct sk_buff *))
-{
-	return ip_conntrack_confirm(*pskb);
-}
-
-extern int ip_fw_ctl(int optval, void *m, unsigned int len);
-
-static int sock_fn(struct sock *sk, int optval, void __user *user, unsigned int len)
-{
-	/* MAX of:
-	   2.2: sizeof(struct ip_fwtest) (~14x4 + 3x4 = 17x4)
-	   2.2: sizeof(struct ip_fwnew) (~1x4 + 15x4 + 3x4 + 3x4 = 22x4)
-	   2.0: sizeof(struct ip_fw) (~25x4)
-
-	   We can't include both 2.0 and 2.2 headers, they conflict.
-	   Hence, 200 is a good number. --RR */
-	char tmp_fw[200];
-	if (!capable(CAP_NET_ADMIN))
-		return -EPERM;
-
-	if (len > sizeof(tmp_fw) || len < 1)
-		return -EINVAL;
-
-	if (copy_from_user(&tmp_fw, user, len))
-		return -EFAULT;
-
-	return -ip_fw_ctl(optval, &tmp_fw, len);
-}
-
-static struct nf_hook_ops preroute_ops = {
-	.hook		= fw_in,
-	.owner		= THIS_MODULE,
-	.pf		= PF_INET,
-	.hooknum	= NF_IP_PRE_ROUTING,
-	.priority	= NF_IP_PRI_FILTER,
-};
-
-static struct nf_hook_ops postroute_ops = {
-	.hook		= fw_in,
-	.owner		= THIS_MODULE,
-	.pf		= PF_INET,
-	.hooknum	= NF_IP_POST_ROUTING,
-	.priority	= NF_IP_PRI_FILTER,
-};
-
-static struct nf_hook_ops forward_ops = {
-	.hook		= fw_in,
-	.owner		= THIS_MODULE,
-	.pf		= PF_INET,
-	.hooknum	= NF_IP_FORWARD,
-	.priority	= NF_IP_PRI_FILTER,
-};
-
-static struct nf_hook_ops local_in_ops = {
-	.hook		= fw_confirm,
-	.owner		= THIS_MODULE,
-	.pf		= PF_INET,
-	.hooknum	= NF_IP_LOCAL_IN,
-	.priority	= NF_IP_PRI_LAST - 1,
-};
-
-static struct nf_sockopt_ops sock_ops = {
-	.pf		= PF_INET,
-	.set_optmin	= 64,
-	.set_optmax	= 64 + 1024 + 1,
-	.set		= &sock_fn,
-};
-
-extern int ipfw_init_or_cleanup(int init);
-
-static int init_or_cleanup(int init)
-{
-	int ret = 0;
-
-	if (!init) goto cleanup;
-
-	ret = nf_register_sockopt(&sock_ops);
-
-	if (ret < 0)
-		goto cleanup_nothing;
-
-	ret = ipfw_init_or_cleanup(1);
-	if (ret < 0)
-		goto cleanup_sockopt;
-
-	ret = masq_init();
-	if (ret < 0)
-		goto cleanup_ipfw;
-
-	nf_register_hook(&preroute_ops);
-	nf_register_hook(&postroute_ops);
-	nf_register_hook(&forward_ops);
-	nf_register_hook(&local_in_ops);
-
-	return ret;
-
- cleanup:
-	nf_unregister_hook(&preroute_ops);
-	nf_unregister_hook(&postroute_ops);
-	nf_unregister_hook(&forward_ops);
-	nf_unregister_hook(&local_in_ops);
-
-	masq_cleanup();
-
- cleanup_ipfw:
-	ipfw_init_or_cleanup(0);
-
- cleanup_sockopt:
-	nf_unregister_sockopt(&sock_ops);
-
- cleanup_nothing:
-	return ret;
-}
-
-static int __init init(void)
-{
-	return init_or_cleanup(1);
-}
-
-static void __exit fini(void)
-{
-	init_or_cleanup(0);
-}
-
-module_init(init);
-module_exit(fini);
diff -Nru a/net/ipv4/netfilter/ip_fw_compat.h b/net/ipv4/netfilter/ip_fw_compat.h
--- a/net/ipv4/netfilter/ip_fw_compat.h	2005-03-01 23:38:56 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,28 +0,0 @@
-#ifndef _LINUX_IP_FW_COMPAT_H
-#define _LINUX_IP_FW_COMPAT_H
-
-/* From ip_fw_compat_redir.c */
-extern unsigned int
-do_redirect(struct sk_buff *skb,
-	    const struct net_device *dev,
-	    u_int16_t redirpt);
-
-extern void
-check_for_redirect(struct sk_buff *skb);
-
-extern void
-check_for_unredirect(struct sk_buff *skb);
-
-/* From ip_fw_compat_masq.c */
-extern unsigned int
-do_masquerade(struct sk_buff **pskb, const struct net_device *dev);
-
-extern void check_for_masq_error(struct sk_buff **pskb);
-
-extern unsigned int
-check_for_demasq(struct sk_buff **pskb);
-
-extern int __init masq_init(void);
-extern void masq_cleanup(void);
-
-#endif /* _LINUX_IP_FW_COMPAT_H */
diff -Nru a/net/ipv4/netfilter/ip_fw_compat_masq.c b/net/ipv4/netfilter/ip_fw_compat_masq.c
--- a/net/ipv4/netfilter/ip_fw_compat_masq.c	2005-03-01 23:39:09 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,342 +0,0 @@
-/* Masquerading compatibility layer.
-
-   Note that there are no restrictions on other programs binding to
-   ports 61000:65095 (in 2.0 and 2.2 they get EADDRINUSE).  Just DON'T
-   DO IT.
- */
-
-/* (C) 1999-2001 Paul `Rusty' Russell
- * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.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/skbuff.h>
-#include <linux/in.h>
-#include <linux/ip.h>
-#include <linux/icmp.h>
-#include <linux/udp.h>
-#include <linux/netfilter_ipv4.h>
-#include <linux/netdevice.h>
-#include <linux/inetdevice.h>
-#include <linux/proc_fs.h>
-#include <linux/module.h>
-#include <net/route.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)
-
-#include <linux/netfilter_ipv4/ip_conntrack.h>
-#include <linux/netfilter_ipv4/ip_conntrack_core.h>
-#include <linux/netfilter_ipv4/ip_conntrack_protocol.h>
-#include <linux/netfilter_ipv4/ip_nat.h>
-#include <linux/netfilter_ipv4/ip_nat_core.h>
-#include <linux/netfilter_ipv4/listhelp.h>
-#include "ip_fw_compat.h"
-
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
-unsigned int
-do_masquerade(struct sk_buff **pskb, const struct net_device *dev)
-{
-	struct ip_nat_info *info;
-	enum ip_conntrack_info ctinfo;
-	struct ip_conntrack *ct;
-	unsigned int ret;
-
-	/* Sorry, only ICMP, TCP and UDP. */
-	if ((*pskb)->nh.iph->protocol != IPPROTO_ICMP
-	    && (*pskb)->nh.iph->protocol != IPPROTO_TCP
-	    && (*pskb)->nh.iph->protocol != IPPROTO_UDP)
-		return NF_DROP;
-
-	/* Feed it to connection tracking; in fact we're in NF_IP_FORWARD,
-           but connection tracking doesn't expect that */
-	ret = ip_conntrack_in(NF_IP_POST_ROUTING, pskb, dev, NULL, NULL);
-	if (ret != NF_ACCEPT) {
-		DEBUGP("ip_conntrack_in returned %u.\n", ret);
-		return ret;
-	}
-
-	ct = ip_conntrack_get(*pskb, &ctinfo);
-
-	if (!ct) {
-		DEBUGP("ip_conntrack_in set to invalid conntrack.\n");
-		return NF_DROP;
-	}
-
-	info = &ct->nat.info;
-
-	WRITE_LOCK(&ip_nat_lock);
-	/* Setup the masquerade, if not already */
-	if (!info->initialized) {
-		u_int32_t newsrc;
-		struct flowi fl = { .nl_u = { .ip4_u = { .daddr = (*pskb)->nh.iph->daddr } } };
-		struct rtable *rt;
-		struct ip_nat_multi_range range;
-
-		/* Pass 0 instead of saddr, since it's going to be changed
-		   anyway. */
-		if (ip_route_output_key(&rt, &fl) != 0) {
-			DEBUGP("ipnat_rule_masquerade: Can't reroute.\n");
-			return NF_DROP;
-		}
-		newsrc = inet_select_addr(rt->u.dst.dev, rt->rt_gateway,
-					  RT_SCOPE_UNIVERSE);
-		ip_rt_put(rt);
-		range = ((struct ip_nat_multi_range)
-			 { 1,
-			   {{IP_NAT_RANGE_MAP_IPS|IP_NAT_RANGE_PROTO_SPECIFIED,
-			     newsrc, newsrc,
-			     { htons(61000) }, { htons(65095) } } } });
-
-		ret = ip_nat_setup_info(ct, &range, NF_IP_POST_ROUTING);
-		if (ret != NF_ACCEPT) {
-			WRITE_UNLOCK(&ip_nat_lock);
-			return ret;
-		}
-	} else
-		DEBUGP("Masquerading already done on this conn.\n");
-	WRITE_UNLOCK(&ip_nat_lock);
-
-	return do_bindings(ct, ctinfo, info, NF_IP_POST_ROUTING, pskb);
-}
-
-void
-check_for_masq_error(struct sk_buff **pskb)
-{
-	enum ip_conntrack_info ctinfo;
-	struct ip_conntrack *ct;
-
-	ct = ip_conntrack_get(*pskb, &ctinfo);
-	/* Wouldn't be here if not tracked already => masq'ed ICMP
-           ping or error related to masq'd connection */
-	IP_NF_ASSERT(ct);
-	if (ctinfo == IP_CT_RELATED) {
-		icmp_reply_translation(pskb, ct, NF_IP_PRE_ROUTING,
-				       CTINFO2DIR(ctinfo));
-		icmp_reply_translation(pskb, ct, NF_IP_POST_ROUTING,
-				       CTINFO2DIR(ctinfo));
-	}
-}
-
-unsigned int
-check_for_demasq(struct sk_buff **pskb)
-{
-	struct ip_conntrack_tuple tuple;
-	struct ip_conntrack_protocol *protocol;
-	struct ip_conntrack_tuple_hash *h;
-	enum ip_conntrack_info ctinfo;
-	struct ip_conntrack *ct;
-	int ret;
-
-	protocol = ip_ct_find_proto((*pskb)->nh.iph->protocol);
-
-	/* We don't feed packets to conntrack system unless we know
-           they're part of an connection already established by an
-           explicit masq command. */
-	switch ((*pskb)->nh.iph->protocol) {
-	case IPPROTO_ICMP:
-		/* ICMP errors. */
-		protocol->error(*pskb, &ctinfo, NF_IP_PRE_ROUTING);
-		ct = (struct ip_conntrack *)(*pskb)->nfct;
-		if (ct) {
-			/* We only do SNAT in the compatibility layer.
-			   So we can manipulate ICMP errors from
-			   server here (== DNAT).  Do SNAT icmp manips
-			   in POST_ROUTING handling. */
-			if (CTINFO2DIR(ctinfo) == IP_CT_DIR_REPLY) {
-				icmp_reply_translation(pskb, ct,
-						       NF_IP_PRE_ROUTING,
-						       CTINFO2DIR(ctinfo));
-				icmp_reply_translation(pskb, ct,
-						       NF_IP_POST_ROUTING,
-						       CTINFO2DIR(ctinfo));
-			}
-			return NF_ACCEPT;
-		}
-		/* Fall thru... */
-	case IPPROTO_TCP:
-	case IPPROTO_UDP:
-		IP_NF_ASSERT(((*pskb)->nh.iph->frag_off & htons(IP_OFFSET)) == 0);
-
-		if (!ip_ct_get_tuple((*pskb)->nh.iph, *pskb,
-				     (*pskb)->nh.iph->ihl*4, &tuple, protocol)) {
-			if (net_ratelimit())
-				printk("ip_fw_compat_masq: Can't get tuple\n");
-			return NF_ACCEPT;
-		}
-		break;
-
-	default:
-		/* Not ours... */
-		return NF_ACCEPT;
-	}
-	h = ip_conntrack_find_get(&tuple, NULL);
-
-	/* MUST be found, and MUST be reply. */
-	if (h && DIRECTION(h) == 1) {
-		ret = ip_conntrack_in(NF_IP_PRE_ROUTING, pskb,
-				      NULL, NULL, NULL);
-
-		/* Put back the reference gained from find_get */
-		nf_conntrack_put(&h->ctrack->ct_general);
-		if (ret == NF_ACCEPT) {
-			struct ip_conntrack *ct;
-			ct = ip_conntrack_get(*pskb, &ctinfo);
-
-			if (ct) {
-				struct ip_nat_info *info = &ct->nat.info;
-
-				do_bindings(ct, ctinfo, info,
-					    NF_IP_PRE_ROUTING,
-					    pskb);
-			} else
-				if (net_ratelimit()) 
-					printk("ip_fw_compat_masq: conntrack"
-					       " didn't like\n");
-		}
-	} else {
-		if (h)
-			/* Put back the reference gained from find_get */
-			nf_conntrack_put(&h->ctrack->ct_general);
-		ret = NF_ACCEPT;
-	}
-
-	return ret;
-}
-
-int ip_fw_masq_timeouts(void *user, int len)
-{
-	printk("Sorry: masquerading timeouts set 5DAYS/2MINS/60SECS\n");
-	return 0;
-}
-
-static const char *masq_proto_name(u_int16_t protonum)
-{
-	switch (protonum) {
-	case IPPROTO_TCP: return "TCP";
-	case IPPROTO_UDP: return "UDP";
-	case IPPROTO_ICMP: return "ICMP";
-	default: return "MORE-CAFFEINE-FOR-RUSTY";
-	}
-}
-
-static unsigned int
-print_masq(char *buffer, const struct ip_conntrack *conntrack)
-{
-	char temp[129];
-
-	/* This is for backwards compatibility, but ick!.
-	   We should never export jiffies to userspace.
-	*/
-	sprintf(temp,"%s %08X:%04X %08X:%04X %04X %08X %6d %6d %7lu",
-		masq_proto_name(conntrack->tuplehash[0].tuple.dst.protonum),
-		ntohl(conntrack->tuplehash[0].tuple.src.ip),
-		ntohs(conntrack->tuplehash[0].tuple.src.u.all),
-		ntohl(conntrack->tuplehash[0].tuple.dst.ip),
-		ntohs(conntrack->tuplehash[0].tuple.dst.u.all),
-		ntohs(conntrack->tuplehash[1].tuple.dst.u.all),
-		/* Sorry, no init_seq, delta or previous_delta (yet). */
-		0, 0, 0,
-		conntrack->timeout.expires - jiffies);
-
-	return sprintf(buffer, "%-127s\n", temp);
-}
-
-/* Returns true when finished. */
-static int
-masq_iterate(const struct ip_conntrack_tuple_hash *hash,
-	     char *buffer, off_t offset, off_t *upto,
-	     unsigned int *len, unsigned int maxlen)
-{
-	unsigned int newlen;
-
-	IP_NF_ASSERT(hash->ctrack);
-
-	/* Only count originals */
-	if (DIRECTION(hash))
-		return 0;
-
-	if ((*upto)++ < offset)
-		return 0;
-
-	newlen = print_masq(buffer + *len, hash->ctrack);
-	if (*len + newlen > maxlen)
-		return 1;
-	else *len += newlen;
-
-	return 0;
-}
-
-/* Everything in the hash is masqueraded. */
-static int
-masq_procinfo(char *buffer, char **start, off_t offset, int length)
-{
-	unsigned int i;
-	int len = 0;
-	off_t upto = 1;
-
-	/* Header: first record */
-	if (offset == 0) {
-		char temp[128];
-
-		sprintf(temp,
-			"Prc FromIP   FPrt ToIP     TPrt Masq Init-seq  Delta PDelta Expires (free=0,0,0)");
-		len = sprintf(buffer, "%-127s\n", temp);
-		offset = 1;
-	}
-
-	READ_LOCK(&ip_conntrack_lock);
-	/* Traverse hash; print originals then reply. */
-	for (i = 0; i < ip_conntrack_htable_size; i++) {
-		if (LIST_FIND(&ip_conntrack_hash[i], masq_iterate,
-			      struct ip_conntrack_tuple_hash *,
-			      buffer, offset, &upto, &len, length))
-			break;
-	}
-	READ_UNLOCK(&ip_conntrack_lock);
-
-	/* `start' hack - see fs/proc/generic.c line ~165 */
-	*start = (char *)((unsigned int)upto - offset);
-	return len;
-}
-
-int __init masq_init(void)
-{
-	int ret;
-	struct proc_dir_entry *proc;
-
-	ret = ip_conntrack_init();
-	if (ret == 0) {
-		ret = ip_nat_init();
-		if (ret == 0) {
-			proc = proc_net_create("ip_masquerade",
-					       0, masq_procinfo);
-			if (proc)
-				proc->owner = THIS_MODULE;
-			else {
-				ip_nat_cleanup();
-				ip_conntrack_cleanup();
-				ret = -ENOMEM;
-			}
-		} else
-			ip_conntrack_cleanup();
-	}
-
-	return ret;
-}
-
-void masq_cleanup(void)
-{
-	ip_nat_cleanup();
-	ip_conntrack_cleanup();
-	proc_net_remove("ip_masquerade");
-}
diff -Nru a/net/ipv4/netfilter/ip_fw_compat_redir.c b/net/ipv4/netfilter/ip_fw_compat_redir.c
--- a/net/ipv4/netfilter/ip_fw_compat_redir.c	2005-03-01 23:39:08 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,318 +0,0 @@
-/* This is a file to handle the "simple" NAT cases (redirect and
-   masquerade) required for the compatibility layer.
-
-   `bind to foreign address' and `getpeername' hacks are not
-   supported.
-
-   FIXME: Timing is overly simplistic.  If anyone complains, make it
-   use conntrack.
-*/
-
-/* (C) 1999-2001 Paul `Rusty' Russell
- * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.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/config.h>
-#include <linux/netfilter.h>
-#include <linux/ip.h>
-#include <linux/udp.h>
-#include <linux/tcp.h>
-#include <net/checksum.h>
-#include <net/ip.h>
-#include <linux/timer.h>
-#include <linux/netdevice.h>
-#include <linux/if.h>
-#include <linux/in.h>
-
-#include <linux/netfilter_ipv4/lockhelp.h>
-
-/* Very simple timeout pushed back by each packet */
-#define REDIR_TIMEOUT (240*HZ)
-
-static DECLARE_LOCK(redir_lock);
-#define ASSERT_READ_LOCK(x) MUST_BE_LOCKED(&redir_lock)
-#define ASSERT_WRITE_LOCK(x) MUST_BE_LOCKED(&redir_lock)
-
-#include <linux/netfilter_ipv4/listhelp.h>
-#include "ip_fw_compat.h"
-
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
-#ifdef CONFIG_NETFILTER_DEBUG
-#define IP_NF_ASSERT(x)							 \
-do {									 \
-	if (!(x))							 \
-		/* Wooah!  I'm tripping my conntrack in a frenzy of	 \
-		   netplay... */					 \
-		printk("ASSERT: %s:%i(%s)\n",				 \
-		       __FILE__, __LINE__, __FUNCTION__);		 \
-} while(0)
-#else
-#define IP_NF_ASSERT(x)
-#endif
-
-static u_int16_t
-cheat_check(u_int32_t oldvalinv, u_int32_t newval, u_int16_t oldcheck)
-{
-	u_int32_t diffs[] = { oldvalinv, newval };
-	return csum_fold(csum_partial((char *)diffs, sizeof(diffs),
-				      oldcheck^0xFFFF));
-}
-
-struct redir_core {
-	u_int32_t orig_srcip, orig_dstip;
-	u_int16_t orig_sport, orig_dport;
-
-	u_int32_t new_dstip;
-	u_int16_t new_dport;
-};
-
-struct redir
-{
-	struct list_head list;
-	struct redir_core core;
-	struct timer_list destroyme;
-};
-
-static LIST_HEAD(redirs);
-
-static int
-redir_cmp(const struct redir *i,
-	  u_int32_t orig_srcip, u_int32_t orig_dstip,
-	  u_int16_t orig_sport, u_int16_t orig_dport)
-{
-	return (i->core.orig_srcip == orig_srcip
-		&& i->core.orig_dstip == orig_dstip
-		&& i->core.orig_sport == orig_sport
-		&& i->core.orig_dport == orig_dport);
-}
-
-/* Search for an existing redirection of the TCP packet. */
-static struct redir *
-find_redir(u_int32_t orig_srcip, u_int32_t orig_dstip,
-	   u_int16_t orig_sport, u_int16_t orig_dport)
-{
-	return LIST_FIND(&redirs, redir_cmp, struct redir *,
-			 orig_srcip, orig_dstip, orig_sport, orig_dport);
-}
-
-static void do_tcp_redir(struct sk_buff *skb, struct redir *redir)
-{
-	struct iphdr *iph = skb->nh.iph;
-	struct tcphdr *tcph = (struct tcphdr *)((u_int32_t *)iph
-						+ iph->ihl);
-
-	tcph->check = cheat_check(~redir->core.orig_dstip,
-				  redir->core.new_dstip,
-				  cheat_check(redir->core.orig_dport ^ 0xFFFF,
-					      redir->core.new_dport,
-					      tcph->check));
-	iph->check = cheat_check(~redir->core.orig_dstip,
-				 redir->core.new_dstip, iph->check);
-	tcph->dest = redir->core.new_dport;
-	iph->daddr = redir->core.new_dstip;
-
-	skb->nfcache |= NFC_ALTERED;
-}
-
-static int
-unredir_cmp(const struct redir *i,
-	    u_int32_t new_dstip, u_int32_t orig_srcip,
-	    u_int16_t new_dport, u_int16_t orig_sport)
-{
-	return (i->core.orig_srcip == orig_srcip
-		&& i->core.new_dstip == new_dstip
-		&& i->core.orig_sport == orig_sport
-		&& i->core.new_dport == new_dport);
-}
-
-/* Match reply packet against redir */
-static struct redir *
-find_unredir(u_int32_t new_dstip, u_int32_t orig_srcip,
-	     u_int16_t new_dport, u_int16_t orig_sport)
-{
-	return LIST_FIND(&redirs, unredir_cmp, struct redir *,
-			 new_dstip, orig_srcip, new_dport, orig_sport);
-}
-
-/* `unredir' a reply packet. */
-static void do_tcp_unredir(struct sk_buff *skb, struct redir *redir)
-{
-	struct iphdr *iph = skb->nh.iph;
-	struct tcphdr *tcph = (struct tcphdr *)((u_int32_t *)iph
-						+ iph->ihl);
-
-	tcph->check = cheat_check(~redir->core.new_dstip,
-				  redir->core.orig_dstip,
-				  cheat_check(redir->core.new_dport ^ 0xFFFF,
-					      redir->core.orig_dport,
-					      tcph->check));
-	iph->check = cheat_check(~redir->core.new_dstip,
-				 redir->core.orig_dstip,
-				 iph->check);
-	tcph->source = redir->core.orig_dport;
-	iph->saddr = redir->core.orig_dstip;
-
-	skb->nfcache |= NFC_ALTERED;
-}
-
-static void destroyme(unsigned long me)
-{
-	LOCK_BH(&redir_lock);
-	LIST_DELETE(&redirs, (struct redir *)me);
-	UNLOCK_BH(&redir_lock);
-	kfree((struct redir *)me);
-}
-
-/* REDIRECT a packet. */
-unsigned int
-do_redirect(struct sk_buff *skb,
-	    const struct net_device *dev,
-	    u_int16_t redirpt)
-{
-	struct iphdr *iph = skb->nh.iph;
-	u_int32_t newdst;
-
-	/* Figure out address: not loopback. */
-	if (!dev)
-		return NF_DROP;
-
-	/* Grab first address on interface. */
-	newdst = ((struct in_device *)dev->ip_ptr)->ifa_list->ifa_local;
-
-	switch (iph->protocol) {
-	case IPPROTO_UDP: {
-		/* Simple mangle. */
-		struct udphdr *udph = (struct udphdr *)((u_int32_t *)iph
-							+ iph->ihl);
-
-		/* Must have whole header */
-		if (skb->len < iph->ihl*4 + sizeof(*udph))
-			return NF_DROP;
-
-		if (udph->check) /* 0 is a special case meaning no checksum */
-			udph->check = cheat_check(~iph->daddr, newdst,
-					  cheat_check(udph->dest ^ 0xFFFF,
-						      redirpt,
-						      udph->check));
-		iph->check = cheat_check(~iph->daddr, newdst, iph->check);
-		udph->dest = redirpt;
-		iph->daddr = newdst;
-
-		skb->nfcache |= NFC_ALTERED;
-		return NF_ACCEPT;
-	}
-	case IPPROTO_TCP: {
-		/* Mangle, maybe record. */
-		struct tcphdr *tcph = (struct tcphdr *)((u_int32_t *)iph
-							+ iph->ihl);
-		struct redir *redir;
-		int ret;
-
-		/* Must have whole header */
-		if (skb->len < iph->ihl*4 + sizeof(*tcph))
-			return NF_DROP;
-
-		DEBUGP("Doing tcp redirect. %08X:%u %08X:%u -> %08X:%u\n",
-		       iph->saddr, tcph->source, iph->daddr, tcph->dest,
-		       newdst, redirpt);
-		LOCK_BH(&redir_lock);
-		redir = find_redir(iph->saddr, iph->daddr,
-				   tcph->source, tcph->dest);
-
-		if (!redir) {
-			redir = kmalloc(sizeof(struct redir), GFP_ATOMIC);
-			if (!redir) {
-				ret = NF_DROP;
-				goto out;
-			}
-			list_prepend(&redirs, redir);
-			init_timer(&redir->destroyme);
-			redir->destroyme.function = destroyme;
-			redir->destroyme.data = (unsigned long)redir;
-			redir->destroyme.expires = jiffies + REDIR_TIMEOUT;
-			add_timer(&redir->destroyme);
-		}
-		/* In case mangling has changed, rewrite this part. */
-		redir->core = ((struct redir_core)
-			       { iph->saddr, iph->daddr,
-				 tcph->source, tcph->dest,
-				 newdst, redirpt });
-		do_tcp_redir(skb, redir);
-		ret = NF_ACCEPT;
-
-	out:
-		UNLOCK_BH(&redir_lock);
-		return ret;
-	}
-
-	default: /* give up if not TCP or UDP. */
-		return NF_DROP;
-	}
-}
-
-/* Incoming packet: is it a reply to a masqueraded connection, or
-   part of an already-redirected TCP connection? */
-void
-check_for_redirect(struct sk_buff *skb)
-{
-	struct iphdr *iph = skb->nh.iph;
-	struct tcphdr *tcph = (struct tcphdr *)((u_int32_t *)iph
-						+ iph->ihl);
-	struct redir *redir;
-
-	if (iph->protocol != IPPROTO_TCP)
-		return;
-
-	/* Must have whole header */
-	if (skb->len < iph->ihl*4 + sizeof(*tcph))
-		return;
-
-	LOCK_BH(&redir_lock);
-	redir = find_redir(iph->saddr, iph->daddr, tcph->source, tcph->dest);
-	if (redir) {
-		DEBUGP("Doing tcp redirect again.\n");
-		do_tcp_redir(skb, redir);
-		if (del_timer(&redir->destroyme)) {
-			redir->destroyme.expires = jiffies + REDIR_TIMEOUT;
-			add_timer(&redir->destroyme);
-		}
-	}
-	UNLOCK_BH(&redir_lock);
-}
-
-void
-check_for_unredirect(struct sk_buff *skb)
-{
-	struct iphdr *iph = skb->nh.iph;
-	struct tcphdr *tcph = (struct tcphdr *)((u_int32_t *)iph
-						+ iph->ihl);
-	struct redir *redir;
-
-	if (iph->protocol != IPPROTO_TCP)
-		return;
-
-	/* Must have whole header */
-	if (skb->len < iph->ihl*4 + sizeof(*tcph))
-		return;
-
-	LOCK_BH(&redir_lock);
-	redir = find_unredir(iph->saddr, iph->daddr, tcph->source, tcph->dest);
-	if (redir) {
-		DEBUGP("Doing tcp unredirect.\n");
-		do_tcp_unredir(skb, redir);
-		if (del_timer(&redir->destroyme)) {
-			redir->destroyme.expires = jiffies + REDIR_TIMEOUT;
-			add_timer(&redir->destroyme);
-		}
-	}
-	UNLOCK_BH(&redir_lock);
-}
diff -Nru a/net/ipv4/netfilter/ip_nat_amanda.c b/net/ipv4/netfilter/ip_nat_amanda.c
--- a/net/ipv4/netfilter/ip_nat_amanda.c	2005-03-01 23:38:53 -08:00
+++ b/net/ipv4/netfilter/ip_nat_amanda.c	2005-03-01 23:38:53 -08:00
@@ -31,119 +31,58 @@
 MODULE_DESCRIPTION("Amanda NAT helper");
 MODULE_LICENSE("GPL");
 
-static unsigned int
-amanda_nat_expected(struct sk_buff **pskb,
-                    unsigned int hooknum,
-                    struct ip_conntrack *ct,
-                    struct ip_nat_info *info)
+static unsigned int help(struct sk_buff **pskb,
+			 enum ip_conntrack_info ctinfo,
+			 unsigned int matchoff,
+			 unsigned int matchlen,
+			 struct ip_conntrack_expect *exp)
 {
-	struct ip_conntrack *master = master_ct(ct);
-	struct ip_ct_amanda_expect *exp_amanda_info;
-	struct ip_nat_multi_range mr;
-	u_int32_t newip;
-
-	IP_NF_ASSERT(info);
-	IP_NF_ASSERT(master);
-	IP_NF_ASSERT(!(info->initialized & (1 << HOOK2MANIP(hooknum))));
-
-	if (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC)
-		newip = master->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip;
-	else
-		newip = master->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip;
-
-	mr.rangesize = 1;
-	/* We don't want to manip the per-protocol, just the IPs. */
-	mr.range[0].flags = IP_NAT_RANGE_MAP_IPS;
-	mr.range[0].min_ip = mr.range[0].max_ip = newip;
-
-	if (HOOK2MANIP(hooknum) == IP_NAT_MANIP_DST) {
-		exp_amanda_info = &ct->master->help.exp_amanda_info;
-		mr.range[0].flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
-		mr.range[0].min = mr.range[0].max
-			= ((union ip_conntrack_manip_proto)
-				{ .udp = { htons(exp_amanda_info->port) } });
-	}
-
-	return ip_nat_setup_info(ct, &mr, hooknum);
-}
-
-static int amanda_data_fixup(struct ip_conntrack *ct,
-                             struct sk_buff **pskb,
-                             enum ip_conntrack_info ctinfo,
-                             struct ip_conntrack_expect *exp)
-{
-	struct ip_ct_amanda_expect *exp_amanda_info;
-	struct ip_conntrack_tuple t = exp->tuple;
 	char buffer[sizeof("65535")];
 	u_int16_t port;
+	unsigned int ret;
 
-	/* Alter conntrack's expectations. */
-	exp_amanda_info = &exp->help.exp_amanda_info;
-	t.dst.ip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip;
-	for (port = exp_amanda_info->port; port != 0; port++) {
-		t.dst.u.tcp.port = htons(port);
-		if (ip_conntrack_change_expect(exp, &t) == 0)
+	/* Connection comes from client. */
+	exp->saved_proto.tcp.port = exp->tuple.dst.u.tcp.port;
+	exp->dir = IP_CT_DIR_ORIGINAL;
+
+	/* When you see the packet, we need to NAT it the same as the
+	 * this one (ie. same IP: it will be TCP and master is UDP). */
+	exp->expectfn = ip_nat_follow_master;
+
+	/* Try to get same port: if not, try to change it. */
+	for (port = ntohs(exp->saved_proto.tcp.port); port != 0; port++) {
+		exp->tuple.dst.u.tcp.port = htons(port);
+		if (ip_conntrack_expect_related(exp) == 0)
 			break;
 	}
-	if (port == 0)
-		return 0;
-
-	sprintf(buffer, "%u", port);
-	return ip_nat_mangle_udp_packet(pskb, ct, ctinfo,
-	                                exp_amanda_info->offset,
-	                                exp_amanda_info->len,
-	                                buffer, strlen(buffer));
-}
 
-static unsigned int help(struct ip_conntrack *ct,
-                         struct ip_conntrack_expect *exp,
-                         struct ip_nat_info *info,
-                         enum ip_conntrack_info ctinfo,
-                         unsigned int hooknum,
-                         struct sk_buff **pskb)
-{
-	int dir = CTINFO2DIR(ctinfo);
-	int ret = NF_ACCEPT;
-
-	/* Only mangle things once: original direction in POST_ROUTING
-	   and reply direction on PRE_ROUTING. */
-	if (!((hooknum == NF_IP_POST_ROUTING && dir == IP_CT_DIR_ORIGINAL)
-	      || (hooknum == NF_IP_PRE_ROUTING && dir == IP_CT_DIR_REPLY)))
-		return NF_ACCEPT;
-
-	/* if this exectation has a "offset" the packet needs to be mangled */
-	if (exp->help.exp_amanda_info.offset != 0)
-		if (!amanda_data_fixup(ct, pskb, ctinfo, exp))
-			ret = NF_DROP;
-	exp->help.exp_amanda_info.offset = 0;
+	if (port == 0) {
+		ip_conntrack_expect_free(exp);
+		return NF_DROP;
+	}
 
+	sprintf(buffer, "%u", port);
+	ret = ip_nat_mangle_udp_packet(pskb, exp->master, ctinfo,
+				       matchoff, matchlen,
+				       buffer, strlen(buffer));
+	if (ret != NF_ACCEPT)
+		ip_conntrack_unexpect_related(exp);
 	return ret;
 }
 
-static struct ip_nat_helper ip_nat_amanda_helper;
-
 static void __exit fini(void)
 {
-	ip_nat_helper_unregister(&ip_nat_amanda_helper);
+	ip_nat_amanda_hook = NULL;
+	/* Make sure noone calls it, meanwhile. */
+	synchronize_net();
 }
 
 static int __init init(void)
 {
-	struct ip_nat_helper *hlpr = &ip_nat_amanda_helper;
-
-	hlpr->tuple.dst.protonum = IPPROTO_UDP;
-	hlpr->tuple.src.u.udp.port = htons(10080);
-	hlpr->mask.src.u.udp.port = 0xFFFF;
-	hlpr->mask.dst.protonum = 0xFFFF;
-	hlpr->help = help;
-	hlpr->flags = 0;
-	hlpr->me = THIS_MODULE;
-	hlpr->expect = amanda_nat_expected;
-	hlpr->name = "amanda";
-
-	return ip_nat_helper_register(hlpr);
+	BUG_ON(ip_nat_amanda_hook);
+	ip_nat_amanda_hook = help;
+	return 0;
 }
 
-NEEDS_CONNTRACK(amanda);
 module_init(init);
 module_exit(fini);
diff -Nru a/net/ipv4/netfilter/ip_nat_core.c b/net/ipv4/netfilter/ip_nat_core.c
--- a/net/ipv4/netfilter/ip_nat_core.c	2005-03-01 23:38:53 -08:00
+++ b/net/ipv4/netfilter/ip_nat_core.c	2005-03-01 23:38:53 -08:00
@@ -20,6 +20,7 @@
 #include <net/tcp.h>  /* For tcp_prot in getorigdst */
 #include <linux/icmp.h>
 #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)
@@ -41,53 +42,31 @@
 #endif
 
 DECLARE_RWLOCK(ip_nat_lock);
-DECLARE_RWLOCK_EXTERN(ip_conntrack_lock);
 
 /* Calculated at init based on memory size */
 static unsigned int ip_nat_htable_size;
 
 static struct list_head *bysource;
-static struct list_head *byipsproto;
 struct ip_nat_protocol *ip_nat_protos[MAX_IP_NAT_PROTO];
 
 
-/* We keep extra hashes for each conntrack, for fast searching. */
-static inline size_t
-hash_by_ipsproto(u_int32_t src, u_int32_t dst, u_int16_t proto)
-{
-	/* Modified src and dst, to ensure we don't create two
-           identical streams. */
-	return (src + dst + proto) % ip_nat_htable_size;
-}
-
-static inline size_t
-hash_by_src(const struct ip_conntrack_manip *manip, u_int16_t proto)
+/* We keep an extra hash for each conntrack, for fast searching. */
+static inline unsigned int
+hash_by_src(const struct ip_conntrack_tuple *tuple)
 {
 	/* Original src, to ensure we map it consistently if poss. */
-	return (manip->ip + manip->u.all + proto) % ip_nat_htable_size;
+	return jhash_3words(tuple->src.ip, tuple->src.u.all,
+			    tuple->dst.protonum, 0) % ip_nat_htable_size;
 }
 
 /* Noone using conntrack by the time this called. */
 static void ip_nat_cleanup_conntrack(struct ip_conntrack *conn)
 {
-	struct ip_nat_info *info = &conn->nat.info;
-	unsigned int hs, hp;
-
-	if (!info->initialized)
+	if (!(conn->status & IPS_NAT_DONE_MASK))
 		return;
 
-	hs = hash_by_src(&conn->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src,
-	                 conn->tuplehash[IP_CT_DIR_ORIGINAL]
-	                 .tuple.dst.protonum);
-
-	hp = hash_by_ipsproto(conn->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip,
-	                      conn->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip,
-	                      conn->tuplehash[IP_CT_DIR_REPLY]
-	                      .tuple.dst.protonum);
-
 	WRITE_LOCK(&ip_nat_lock);
-	list_del(&info->bysource);
-	list_del(&info->byipsproto);
+	list_del(&conn->nat.info.bysource);
 	WRITE_UNLOCK(&ip_nat_lock);
 }
 
@@ -119,29 +98,26 @@
 }
 
 /* If we source map this tuple so reply looks like reply_tuple, will
- * that meet the constraints of mr. */
+ * that meet the constraints of range. */
 static int
 in_range(const struct ip_conntrack_tuple *tuple,
-	 const struct ip_nat_multi_range *mr)
+	 const struct ip_nat_range *range)
 {
 	struct ip_nat_protocol *proto = ip_nat_find_proto(tuple->dst.protonum);
-	unsigned int i;
-
-	for (i = 0; i < mr->rangesize; i++) {
-		/* If we are supposed to map IPs, then we must be in the
-		   range specified. */
-		if (mr->range[i].flags & IP_NAT_RANGE_MAP_IPS) {
-			if (ntohl(tuple->src.ip) < ntohl(mr->range[i].min_ip)
-			    || (ntohl(tuple->src.ip)
-				> ntohl(mr->range[i].max_ip)))
-				continue;
-		}
 
-		if (!(mr->range[i].flags & IP_NAT_RANGE_PROTO_SPECIFIED)
-		    || proto->in_range(tuple, IP_NAT_MANIP_SRC,
-				       &mr->range[i].min, &mr->range[i].max))
-			return 1;
+	/* If we are supposed to map IPs, then we must be in the
+	   range specified, otherwise let this drag us onto a new src IP. */
+	if (range->flags & IP_NAT_RANGE_MAP_IPS) {
+		if (ntohl(tuple->src.ip) < ntohl(range->min_ip)
+		    || ntohl(tuple->src.ip) > ntohl(range->max_ip))
+			return 0;
 	}
+
+	if (!(range->flags & IP_NAT_RANGE_PROTO_SPECIFIED)
+	    || proto->in_range(tuple, IP_NAT_MANIP_SRC,
+			       &range->min, &range->max))
+		return 1;
+
 	return 0;
 }
 
@@ -161,13 +137,12 @@
 static int
 find_appropriate_src(const struct ip_conntrack_tuple *tuple,
 		     struct ip_conntrack_tuple *result,
-		     const struct ip_nat_multi_range *mr)
+		     const struct ip_nat_range *range)
 {
-	unsigned int h = hash_by_src(&tuple->src, tuple->dst.protonum);
+	unsigned int h = hash_by_src(tuple);
 	struct ip_conntrack *ct;
 
-	MUST_BE_READ_LOCKED(&ip_nat_lock);
-
+	READ_LOCK(&ip_nat_lock);
 	list_for_each_entry(ct, &bysource[h], nat.info.bysource) {
 		if (same_src(ct, tuple)) {
 			/* Copy source part from reply tuple. */
@@ -175,218 +150,74 @@
 				       &ct->tuplehash[IP_CT_DIR_REPLY].tuple);
 			result->dst = tuple->dst;
 
-			if (in_range(result, mr))
+			if (in_range(result, range)) {
+				READ_UNLOCK(&ip_nat_lock);
 				return 1;
+			}
 		}
 	}
+	READ_UNLOCK(&ip_nat_lock);
 	return 0;
 }
 
-#ifdef CONFIG_IP_NF_NAT_LOCAL
-/* If it's really a local destination manip, it may need to do a
-   source manip too. */
-static int
-do_extra_mangle(u_int32_t var_ip, u_int32_t *other_ipp)
-{
-	struct flowi fl = { .nl_u = { .ip4_u = { .daddr = var_ip } } };
-	struct rtable *rt;
-
-	/* FIXME: IPTOS_TOS(iph->tos) --RR */
-	if (ip_route_output_key(&rt, &fl) != 0) {
-		DEBUGP("do_extra_mangle: Can't get route to %u.%u.%u.%u\n",
-		       NIPQUAD(var_ip));
-		return 0;
-	}
-
-	*other_ipp = rt->rt_src;
-	ip_rt_put(rt);
-	return 1;
-}
-#endif
-
-/* Simple way to iterate through all. */
-static inline int fake_cmp(const struct ip_conntrack *ct,
-			   u_int32_t src, u_int32_t dst, u_int16_t protonum,
-			   unsigned int *score, const struct ip_conntrack *ct2)
-{
-	/* Compare backwards: we're dealing with OUTGOING tuples, and
-           inside the conntrack is the REPLY tuple.  Don't count this
-           conntrack. */
-	if (ct != ct2
-	    && ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip == dst
-	    && ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip == src
-	    && (ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.protonum == protonum))
-		(*score)++;
-	return 0;
-}
-
-static inline unsigned int
-count_maps(u_int32_t src, u_int32_t dst, u_int16_t protonum,
-	   const struct ip_conntrack *conntrack)
-{
-	struct ip_conntrack *ct;
-	unsigned int score = 0;
-	unsigned int h;
-
-	MUST_BE_READ_LOCKED(&ip_nat_lock);
-	h = hash_by_ipsproto(src, dst, protonum);
-	list_for_each_entry(ct, &byipsproto[h], nat.info.byipsproto)
-		fake_cmp(ct, src, dst, protonum, &score, conntrack);
-
-	return score;
-}
-
 /* For [FUTURE] fragmentation handling, we want the least-used
    src-ip/dst-ip/proto triple.  Fairness doesn't come into it.  Thus
    if the range specifies 1.2.3.4 ports 10000-10005 and 1.2.3.5 ports
    1-65535, we don't do pro-rata allocation based on ports; we choose
    the ip with the lowest src-ip/dst-ip/proto usage.
-
-   If an allocation then fails (eg. all 6 ports used in the 1.2.3.4
-   range), we eliminate that and try again.  This is not the most
-   efficient approach, but if you're worried about that, don't hand us
-   ranges you don't really have.  */
-static struct ip_nat_range *
+*/
+static void
 find_best_ips_proto(struct ip_conntrack_tuple *tuple,
-		    const struct ip_nat_multi_range *mr,
+		    const struct ip_nat_range *range,
 		    const struct ip_conntrack *conntrack,
-		    unsigned int hooknum)
+		    enum ip_nat_manip_type maniptype)
 {
-	unsigned int i;
-	struct {
-		const struct ip_nat_range *range;
-		unsigned int score;
-		struct ip_conntrack_tuple tuple;
-	} best = { NULL,  0xFFFFFFFF };
-	u_int32_t *var_ipp, *other_ipp, saved_ip, orig_dstip;
-	static unsigned int randomness;
+	u_int32_t *var_ipp;
+	/* Host order */
+	u_int32_t minip, maxip, j;
 
-	if (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC) {
+	/* No IP mapping?  Do nothing. */
+	if (!(range->flags & IP_NAT_RANGE_MAP_IPS))
+		return;
+
+	if (maniptype == IP_NAT_MANIP_SRC)
 		var_ipp = &tuple->src.ip;
-		saved_ip = tuple->dst.ip;
-		other_ipp = &tuple->dst.ip;
-	} else {
+	else
 		var_ipp = &tuple->dst.ip;
-		saved_ip = tuple->src.ip;
-		other_ipp = &tuple->src.ip;
-	}
-	/* Don't do do_extra_mangle unless necessary (overrides
-           explicit socket bindings, for example) */
-	orig_dstip = tuple->dst.ip;
-
-	IP_NF_ASSERT(mr->rangesize >= 1);
-	for (i = 0; i < mr->rangesize; i++) {
-		/* Host order */
-		u_int32_t minip, maxip, j;
-
-		/* Don't do ranges which are already eliminated. */
-		if (mr->range[i].flags & IP_NAT_RANGE_FULL) {
-			continue;
-		}
 
-		if (mr->range[i].flags & IP_NAT_RANGE_MAP_IPS) {
-			minip = ntohl(mr->range[i].min_ip);
-			maxip = ntohl(mr->range[i].max_ip);
-		} else
-			minip = maxip = ntohl(*var_ipp);
-
-		randomness++;
-		for (j = 0; j < maxip - minip + 1; j++) {
-			unsigned int score;
-
-			*var_ipp = htonl(minip + (randomness + j) 
-					 % (maxip - minip + 1));
-
-			/* Reset the other ip in case it was mangled by
-			 * do_extra_mangle last time. */
-			*other_ipp = saved_ip;
-
-#ifdef CONFIG_IP_NF_NAT_LOCAL
-			if (hooknum == NF_IP_LOCAL_OUT
-			    && *var_ipp != orig_dstip
-			    && !do_extra_mangle(*var_ipp, other_ipp)) {
-				DEBUGP("Range %u %u.%u.%u.%u rt failed!\n",
-				       i, NIPQUAD(*var_ipp));
-				/* Can't route?  This whole range part is
-				 * probably screwed, but keep trying
-				 * anyway. */
-				continue;
-			}
-#endif
-
-			/* Count how many others map onto this. */
-			score = count_maps(tuple->src.ip, tuple->dst.ip,
-					   tuple->dst.protonum, conntrack);
-			if (score < best.score) {
-				/* Optimization: doesn't get any better than
-				   this. */
-				if (score == 0)
-					return (struct ip_nat_range *)
-						&mr->range[i];
-
-				best.score = score;
-				best.tuple = *tuple;
-				best.range = &mr->range[i];
-			}
-		}
-	}
-	*tuple = best.tuple;
-
-	/* Discard const. */
-	return (struct ip_nat_range *)best.range;
-}
-
-/* Fast version doesn't iterate through hash chains, but only handles
-   common case of single IP address (null NAT, masquerade) */
-static struct ip_nat_range *
-find_best_ips_proto_fast(struct ip_conntrack_tuple *tuple,
-			 const struct ip_nat_multi_range *mr,
-			 const struct ip_conntrack *conntrack,
-			 unsigned int hooknum)
-{
-	if (mr->rangesize != 1
-	    || (mr->range[0].flags & IP_NAT_RANGE_FULL)
-	    || ((mr->range[0].flags & IP_NAT_RANGE_MAP_IPS)
-		&& mr->range[0].min_ip != mr->range[0].max_ip))
-		return find_best_ips_proto(tuple, mr, conntrack, hooknum);
-
-	if (mr->range[0].flags & IP_NAT_RANGE_MAP_IPS) {
-		if (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC)
-			tuple->src.ip = mr->range[0].min_ip;
-		else {
-			/* Only do extra mangle when required (breaks
-                           socket binding) */
-#ifdef CONFIG_IP_NF_NAT_LOCAL
-			if (tuple->dst.ip != mr->range[0].min_ip
-			    && hooknum == NF_IP_LOCAL_OUT
-			    && !do_extra_mangle(mr->range[0].min_ip,
-						&tuple->src.ip))
-				return NULL;
-#endif
-			tuple->dst.ip = mr->range[0].min_ip;
-		}
+	/* Fast path: only one choice. */
+	if (range->min_ip == range->max_ip) {
+		*var_ipp = range->min_ip;
+		return;
 	}
 
-	/* Discard const. */
-	return (struct ip_nat_range *)&mr->range[0];
-}
-
-static int
+	/* Hashing source and destination IPs gives a fairly even
+	 * spread in practice (if there are a small number of IPs
+	 * involved, there usually aren't that many connections
+	 * anyway).  The consistency means that servers see the same
+	 * client coming from the same IP (some Internet Banking sites
+	 * like this), even across reboots. */
+	minip = ntohl(range->min_ip);
+	maxip = ntohl(range->max_ip);
+	j = jhash_2words(tuple->src.ip, tuple->dst.ip, 0);
+	*var_ipp = htonl(minip + j % (maxip - minip + 1));
+}
+
+/* Manipulate the tuple into the range given.  For NF_IP_POST_ROUTING,
+ * we change the source to map into the range.  For NF_IP_PRE_ROUTING
+ * and NF_IP_LOCAL_OUT, we change the destination to map into the
+ * range.  It might not be possible to get a unique tuple, but we try.
+ * At worst (or if we race), we will end up with a final duplicate in
+ * __ip_conntrack_confirm and drop the packet. */
+static void
 get_unique_tuple(struct ip_conntrack_tuple *tuple,
 		 const struct ip_conntrack_tuple *orig_tuple,
-		 const struct ip_nat_multi_range *mrr,
+		 const struct ip_nat_range *range,
 		 struct ip_conntrack *conntrack,
-		 unsigned int hooknum)
+		 enum ip_nat_manip_type maniptype)
 {
 	struct ip_nat_protocol *proto
 		= ip_nat_find_proto(orig_tuple->dst.protonum);
-	struct ip_nat_range *rptr;
-	unsigned int i;
-	int ret;
-
-	/* We temporarily use flags for marking full parts, but we
-	   always clean up afterwards */
-	struct ip_nat_multi_range *mr = (void *)mrr;
 
 	/* 1) If this srcip/proto/src-proto-part is currently mapped,
 	   and that same mapping gives a unique tuple within the given
@@ -395,448 +226,183 @@
 	   This is only required for source (ie. NAT/masq) mappings.
 	   So far, we don't do local source mappings, so multiple
 	   manips not an issue.  */
-	if (hooknum == NF_IP_POST_ROUTING) {
-		if (find_appropriate_src(orig_tuple, tuple, mr)) {
+	if (maniptype == IP_NAT_MANIP_SRC) {
+		if (find_appropriate_src(orig_tuple, tuple, range)) {
 			DEBUGP("get_unique_tuple: Found current src map\n");
 			if (!ip_nat_used_tuple(tuple, conntrack))
-				return 1;
+				return;
 		}
 	}
 
 	/* 2) Select the least-used IP/proto combination in the given
-	   range.
-	*/
+	   range. */
 	*tuple = *orig_tuple;
-	while ((rptr = find_best_ips_proto_fast(tuple, mr, conntrack, hooknum))
-	       != NULL) {
-		DEBUGP("Found best for "); DUMP_TUPLE(tuple);
-		/* 3) The per-protocol part of the manip is made to
-		   map into the range to make a unique tuple. */
-
-		/* Only bother mapping if it's not already in range
-		   and unique */
-		if ((!(rptr->flags & IP_NAT_RANGE_PROTO_SPECIFIED)
-		     || proto->in_range(tuple, HOOK2MANIP(hooknum),
-					&rptr->min, &rptr->max))
-		    && !ip_nat_used_tuple(tuple, conntrack)) {
-			ret = 1;
-			goto clear_fulls;
-		} else {
-			if (proto->unique_tuple(tuple, rptr,
-						HOOK2MANIP(hooknum),
-						conntrack)) {
-				/* Must be unique. */
-				IP_NF_ASSERT(!ip_nat_used_tuple(tuple,
-								conntrack));
-				ret = 1;
-				goto clear_fulls;
-			} else if (HOOK2MANIP(hooknum) == IP_NAT_MANIP_DST) {
-				/* Try implicit source NAT; protocol
-                                   may be able to play with ports to
-                                   make it unique. */
-				struct ip_nat_range r
-					= { IP_NAT_RANGE_MAP_IPS, 
-					    tuple->src.ip, tuple->src.ip,
-					    { 0 }, { 0 } };
-				DEBUGP("Trying implicit mapping\n");
-				if (proto->unique_tuple(tuple, &r,
-							IP_NAT_MANIP_SRC,
-							conntrack)) {
-					/* Must be unique. */
-					IP_NF_ASSERT(!ip_nat_used_tuple
-						     (tuple, conntrack));
-					ret = 1;
-					goto clear_fulls;
-				}
-			}
-			DEBUGP("Protocol can't get unique tuple %u.\n",
-			       hooknum);
-		}
+	find_best_ips_proto(tuple, range, conntrack, maniptype);
 
-		/* Eliminate that from range, and try again. */
-		rptr->flags |= IP_NAT_RANGE_FULL;
-		*tuple = *orig_tuple;
-	}
+	/* 3) The per-protocol part of the manip is made to map into
+	   the range to make a unique tuple. */
 
-	ret = 0;
-
- clear_fulls:
-	/* Clear full flags. */
-	IP_NF_ASSERT(mr->rangesize >= 1);
-	for (i = 0; i < mr->rangesize; i++)
-		mr->range[i].flags &= ~IP_NAT_RANGE_FULL;
+	/* Only bother mapping if it's not already in range and unique */
+	if ((!(range->flags & IP_NAT_RANGE_PROTO_SPECIFIED)
+	     || proto->in_range(tuple, maniptype, &range->min, &range->max))
+	    && !ip_nat_used_tuple(tuple, conntrack))
+		return;
 
-	return ret;
+	/* Last change: get protocol to try to obtain unique tuple. */
+	proto->unique_tuple(tuple, range, maniptype, conntrack);
 }
 
-/* Where to manip the reply packets (will be reverse manip). */
-static unsigned int opposite_hook[NF_IP_NUMHOOKS]
-= { [NF_IP_PRE_ROUTING] = NF_IP_POST_ROUTING,
-    [NF_IP_POST_ROUTING] = NF_IP_PRE_ROUTING,
-#ifdef CONFIG_IP_NF_NAT_LOCAL
-    [NF_IP_LOCAL_OUT] = NF_IP_LOCAL_IN,
-    [NF_IP_LOCAL_IN] = NF_IP_LOCAL_OUT,
-#endif
-};
-
 unsigned int
 ip_nat_setup_info(struct ip_conntrack *conntrack,
-		  const struct ip_nat_multi_range *mr,
+		  const struct ip_nat_range *range,
 		  unsigned int hooknum)
 {
-	struct ip_conntrack_tuple new_tuple, inv_tuple, reply;
-	struct ip_conntrack_tuple orig_tp;
+	struct ip_conntrack_tuple curr_tuple, new_tuple;
 	struct ip_nat_info *info = &conntrack->nat.info;
-	int in_hashes = info->initialized;
+	int have_to_hash = !(conntrack->status & IPS_NAT_DONE_MASK);
+	enum ip_nat_manip_type maniptype = HOOK2MANIP(hooknum);
 
-	MUST_BE_WRITE_LOCKED(&ip_nat_lock);
 	IP_NF_ASSERT(hooknum == NF_IP_PRE_ROUTING
 		     || hooknum == NF_IP_POST_ROUTING
 		     || hooknum == NF_IP_LOCAL_IN
 		     || hooknum == NF_IP_LOCAL_OUT);
-	IP_NF_ASSERT(info->num_manips < IP_NAT_MAX_MANIPS);
-	IP_NF_ASSERT(!(info->initialized & (1 << HOOK2MANIP(hooknum))));
+	BUG_ON(ip_nat_initialized(conntrack, maniptype));
 
 	/* What we've got will look like inverse of reply. Normally
 	   this is what is in the conntrack, except for prior
 	   manipulations (future optimization: if num_manips == 0,
 	   orig_tp =
 	   conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple) */
-	invert_tuplepr(&orig_tp,
+	invert_tuplepr(&curr_tuple,
 		       &conntrack->tuplehash[IP_CT_DIR_REPLY].tuple);
 
-#if 0
-	{
-	unsigned int i;
+	get_unique_tuple(&new_tuple, &curr_tuple, range, conntrack, maniptype);
 
-	DEBUGP("Hook %u (%s), ", hooknum,
-	       HOOK2MANIP(hooknum)==IP_NAT_MANIP_SRC ? "SRC" : "DST");
-	DUMP_TUPLE(&orig_tp);
-	DEBUGP("Range %p: ", mr);
-	for (i = 0; i < mr->rangesize; i++) {
-		DEBUGP("%u:%s%s%s %u.%u.%u.%u - %u.%u.%u.%u %u - %u\n",
-		       i,
-		       (mr->range[i].flags & IP_NAT_RANGE_MAP_IPS)
-		       ? " MAP_IPS" : "",
-		       (mr->range[i].flags
-			& IP_NAT_RANGE_PROTO_SPECIFIED)
-		       ? " PROTO_SPECIFIED" : "",
-		       (mr->range[i].flags & IP_NAT_RANGE_FULL)
-		       ? " FULL" : "",
-		       NIPQUAD(mr->range[i].min_ip),
-		       NIPQUAD(mr->range[i].max_ip),
-		       mr->range[i].min.all,
-		       mr->range[i].max.all);
-	}
-	}
-#endif
+	if (!ip_ct_tuple_equal(&new_tuple, &curr_tuple)) {
+		struct ip_conntrack_tuple reply;
 
-	do {
-		if (!get_unique_tuple(&new_tuple, &orig_tp, mr, conntrack,
-				      hooknum)) {
-			DEBUGP("ip_nat_setup_info: Can't get unique for %p.\n",
-			       conntrack);
-			return NF_DROP;
-		}
-
-#if 0
-		DEBUGP("Hook %u (%s) %p\n", hooknum,
-		       HOOK2MANIP(hooknum)==IP_NAT_MANIP_SRC ? "SRC" : "DST",
-		       conntrack);
-		DEBUGP("Original: ");
-		DUMP_TUPLE(&orig_tp);
-		DEBUGP("New: ");
-		DUMP_TUPLE(&new_tuple);
-#endif
-
-		/* We now have two tuples (SRCIP/SRCPT/DSTIP/DSTPT):
-		   the original (A/B/C/D') and the mangled one (E/F/G/H').
-
-		   We're only allowed to work with the SRC per-proto
-		   part, so we create inverses of both to start, then
-		   derive the other fields we need.  */
-
-		/* Reply connection: simply invert the new tuple
-                   (G/H/E/F') */
+		/* Alter conntrack table so will recognize replies. */
 		invert_tuplepr(&reply, &new_tuple);
+		ip_conntrack_alter_reply(conntrack, &reply);
 
-		/* Alter conntrack table so it recognizes replies.
-                   If fail this race (reply tuple now used), repeat. */
-	} while (!ip_conntrack_alter_reply(conntrack, &reply));
-
-	/* FIXME: We can simply used existing conntrack reply tuple
-           here --RR */
-	/* Create inverse of original: C/D/A/B' */
-	invert_tuplepr(&inv_tuple, &orig_tp);
-
-	/* Has source changed?. */
-	if (!ip_ct_tuple_src_equal(&new_tuple, &orig_tp)) {
-		/* In this direction, a source manip. */
-		info->manips[info->num_manips++] =
-			((struct ip_nat_info_manip)
-			 { IP_CT_DIR_ORIGINAL, hooknum,
-			   IP_NAT_MANIP_SRC, new_tuple.src });
-
-		IP_NF_ASSERT(info->num_manips < IP_NAT_MAX_MANIPS);
-
-		/* In the reverse direction, a destination manip. */
-		info->manips[info->num_manips++] =
-			((struct ip_nat_info_manip)
-			 { IP_CT_DIR_REPLY, opposite_hook[hooknum],
-			   IP_NAT_MANIP_DST, orig_tp.src });
-		IP_NF_ASSERT(info->num_manips <= IP_NAT_MAX_MANIPS);
-	}
-
-	/* Has destination changed? */
-	if (!ip_ct_tuple_dst_equal(&new_tuple, &orig_tp)) {
-		/* In this direction, a destination manip */
-		info->manips[info->num_manips++] =
-			((struct ip_nat_info_manip)
-			 { IP_CT_DIR_ORIGINAL, hooknum,
-			   IP_NAT_MANIP_DST, reply.src });
-
-		IP_NF_ASSERT(info->num_manips < IP_NAT_MAX_MANIPS);
-
-		/* In the reverse direction, a source manip. */
-		info->manips[info->num_manips++] =
-			((struct ip_nat_info_manip)
-			 { IP_CT_DIR_REPLY, opposite_hook[hooknum],
-			   IP_NAT_MANIP_SRC, inv_tuple.src });
-		IP_NF_ASSERT(info->num_manips <= IP_NAT_MAX_MANIPS);
-	}
-
-	/* If there's a helper, assign it; based on new tuple. */
-	if (!conntrack->master)
-		info->helper = __ip_nat_find_helper(&reply);
+		/* Non-atomic: we own this at the moment. */
+		if (maniptype == IP_NAT_MANIP_SRC)
+			conntrack->status |= IPS_SRC_NAT;
+		else
+			conntrack->status |= IPS_DST_NAT;
+	}
+
+	/* Place in source hash if this is the first time. */
+	if (have_to_hash) {
+		unsigned int srchash
+			= hash_by_src(&conntrack->tuplehash[IP_CT_DIR_ORIGINAL]
+				      .tuple);
+		WRITE_LOCK(&ip_nat_lock);
+		list_add(&info->bysource, &bysource[srchash]);
+		WRITE_UNLOCK(&ip_nat_lock);
+	}
 
 	/* It's done. */
-	info->initialized |= (1 << HOOK2MANIP(hooknum));
-
-	if (in_hashes)
-		replace_in_hashes(conntrack, info);
+	if (maniptype == IP_NAT_MANIP_DST)
+		set_bit(IPS_DST_NAT_DONE_BIT, &conntrack->status);
 	else
-		place_in_hashes(conntrack, info);
+		set_bit(IPS_SRC_NAT_DONE_BIT, &conntrack->status);
 
 	return NF_ACCEPT;
 }
 
-void replace_in_hashes(struct ip_conntrack *conntrack,
-		       struct ip_nat_info *info)
-{
-	/* Source has changed, so replace in hashes. */
-	unsigned int srchash
-		= hash_by_src(&conntrack->tuplehash[IP_CT_DIR_ORIGINAL]
-			      .tuple.src,
-			      conntrack->tuplehash[IP_CT_DIR_ORIGINAL]
-			      .tuple.dst.protonum);
-	/* We place packet as seen OUTGOUNG in byips_proto hash
-           (ie. reverse dst and src of reply packet. */
-	unsigned int ipsprotohash
-		= hash_by_ipsproto(conntrack->tuplehash[IP_CT_DIR_REPLY]
-				   .tuple.dst.ip,
-				   conntrack->tuplehash[IP_CT_DIR_REPLY]
-				   .tuple.src.ip,
-				   conntrack->tuplehash[IP_CT_DIR_REPLY]
-				   .tuple.dst.protonum);
-
-	MUST_BE_WRITE_LOCKED(&ip_nat_lock);
-	list_move(&info->bysource, &bysource[srchash]);
-	list_move(&info->byipsproto, &byipsproto[ipsprotohash]);
-}
-
-void place_in_hashes(struct ip_conntrack *conntrack,
-		     struct ip_nat_info *info)
-{
-	unsigned int srchash
-		= hash_by_src(&conntrack->tuplehash[IP_CT_DIR_ORIGINAL]
-			      .tuple.src,
-			      conntrack->tuplehash[IP_CT_DIR_ORIGINAL]
-			      .tuple.dst.protonum);
-	/* We place packet as seen OUTGOUNG in byips_proto hash
-           (ie. reverse dst and src of reply packet. */
-	unsigned int ipsprotohash
-		= hash_by_ipsproto(conntrack->tuplehash[IP_CT_DIR_REPLY]
-				   .tuple.dst.ip,
-				   conntrack->tuplehash[IP_CT_DIR_REPLY]
-				   .tuple.src.ip,
-				   conntrack->tuplehash[IP_CT_DIR_REPLY]
-				   .tuple.dst.protonum);
-
-	MUST_BE_WRITE_LOCKED(&ip_nat_lock);
-	list_add(&info->bysource, &bysource[srchash]);
-	list_add(&info->byipsproto, &byipsproto[ipsprotohash]);
-}
-
 /* Returns true if succeeded. */
 static int
 manip_pkt(u_int16_t proto,
 	  struct sk_buff **pskb,
 	  unsigned int iphdroff,
-	  const struct ip_conntrack_manip *manip,
+	  const struct ip_conntrack_tuple *target,
 	  enum ip_nat_manip_type maniptype)
 {
 	struct iphdr *iph;
 
 	(*pskb)->nfcache |= NFC_ALTERED;
-	if (!skb_ip_make_writable(pskb, iphdroff+sizeof(iph)))
+	if (!skb_ip_make_writable(pskb, iphdroff + sizeof(*iph)))
 		return 0;
 
 	iph = (void *)(*pskb)->data + iphdroff;
 
 	/* Manipulate protcol part. */
 	if (!ip_nat_find_proto(proto)->manip_pkt(pskb, iphdroff,
-	                                         manip, maniptype))
+	                                         target, maniptype))
 		return 0;
 
 	iph = (void *)(*pskb)->data + iphdroff;
 
 	if (maniptype == IP_NAT_MANIP_SRC) {
-		iph->check = ip_nat_cheat_check(~iph->saddr, manip->ip,
+		iph->check = ip_nat_cheat_check(~iph->saddr, target->src.ip,
 						iph->check);
-		iph->saddr = manip->ip;
+		iph->saddr = target->src.ip;
 	} else {
-		iph->check = ip_nat_cheat_check(~iph->daddr, manip->ip,
+		iph->check = ip_nat_cheat_check(~iph->daddr, target->dst.ip,
 						iph->check);
-		iph->daddr = manip->ip;
+		iph->daddr = target->dst.ip;
 	}
 	return 1;
 }
 
-static inline int exp_for_packet(struct ip_conntrack_expect *exp,
-			         struct sk_buff *skb)
+/* Do packet manipulations according to ip_nat_setup_info. */
+unsigned int nat_packet(struct ip_conntrack *ct,
+			enum ip_conntrack_info ctinfo,
+			unsigned int hooknum,
+			struct sk_buff **pskb)
 {
-	struct ip_conntrack_protocol *proto;
-	int ret = 1;
-
-	MUST_BE_READ_LOCKED(&ip_conntrack_lock);
-	proto = ip_ct_find_proto(skb->nh.iph->protocol);
-	if (proto->exp_matches_pkt)
-		ret = proto->exp_matches_pkt(exp, skb);
-
-	return ret;
-}
-
-/* Do packet manipulations according to binding. */
-unsigned int
-do_bindings(struct ip_conntrack *ct,
-	    enum ip_conntrack_info ctinfo,
-	    struct ip_nat_info *info,
-	    unsigned int hooknum,
-	    struct sk_buff **pskb)
-{
-	unsigned int i;
-	struct ip_nat_helper *helper;
 	enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
-	int proto = (*pskb)->nh.iph->protocol;
+	unsigned long statusbit;
+	enum ip_nat_manip_type mtype = HOOK2MANIP(hooknum);
 
-	/* Need nat lock to protect against modification, but neither
-	   conntrack (referenced) and helper (deleted with
-	   synchronize_bh()) can vanish. */
-	READ_LOCK(&ip_nat_lock);
-	for (i = 0; i < info->num_manips; i++) {
-		if (info->manips[i].direction == dir
-		    && info->manips[i].hooknum == hooknum) {
-			DEBUGP("Mangling %p: %s to %u.%u.%u.%u %u\n",
-			       *pskb,
-			       info->manips[i].maniptype == IP_NAT_MANIP_SRC
-			       ? "SRC" : "DST",
-			       NIPQUAD(info->manips[i].manip.ip),
-			       htons(info->manips[i].manip.u.all));
-			if (!manip_pkt(proto, pskb, 0,
-				       &info->manips[i].manip,
-				       info->manips[i].maniptype)) {
-				READ_UNLOCK(&ip_nat_lock);
-				return NF_DROP;
-			}
-		}
+	if (test_bit(IPS_SEQ_ADJUST_BIT, &ct->status)
+	    && (hooknum == NF_IP_POST_ROUTING || hooknum == NF_IP_LOCAL_IN)) {
+		DEBUGP("ip_nat_core: adjusting sequence number\n");
+		/* future: put this in a l4-proto specific function,
+		 * and call this function here. */
+		if (!ip_nat_seq_adjust(pskb, ct, ctinfo))
+			return NF_DROP;
 	}
-	helper = info->helper;
-	READ_UNLOCK(&ip_nat_lock);
 
-	if (helper) {
-		struct ip_conntrack_expect *exp = NULL;
-		struct list_head *cur_item;
-		int ret = NF_ACCEPT;
-		int helper_called = 0;
-
-		DEBUGP("do_bindings: helper existing for (%p)\n", ct);
-
-		/* Always defragged for helpers */
-		IP_NF_ASSERT(!((*pskb)->nh.iph->frag_off
-			       & htons(IP_MF|IP_OFFSET)));
-
-		/* Have to grab read lock before sibling_list traversal */
-		READ_LOCK(&ip_conntrack_lock);
-		list_for_each_prev(cur_item, &ct->sibling_list) { 
-			exp = list_entry(cur_item, struct ip_conntrack_expect, 
-					 expected_list);
-					 
-			/* if this expectation is already established, skip */
-			if (exp->sibling)
-				continue;
-
-			if (exp_for_packet(exp, *pskb)) {
-				/* FIXME: May be true multiple times in the
-				 * case of UDP!! */
-				DEBUGP("calling nat helper (exp=%p) for packet\n", exp);
-				ret = helper->help(ct, exp, info, ctinfo, 
-						   hooknum, pskb);
-				if (ret != NF_ACCEPT) {
-					READ_UNLOCK(&ip_conntrack_lock);
-					return ret;
-				}
-				helper_called = 1;
-			}
-		}
-		/* Helper might want to manip the packet even when there is no
-		 * matching expectation for this packet */
-		if (!helper_called && helper->flags & IP_NAT_HELPER_F_ALWAYS) {
-			DEBUGP("calling nat helper for packet without expectation\n");
-			ret = helper->help(ct, NULL, info, ctinfo, 
-					   hooknum, pskb);
-			if (ret != NF_ACCEPT) {
-				READ_UNLOCK(&ip_conntrack_lock);
-				return ret;
-			}
-		}
-		READ_UNLOCK(&ip_conntrack_lock);
-		
-		/* Adjust sequence number only once per packet 
-		 * (helper is called at all hooks) */
-		if (proto == IPPROTO_TCP
-		    && (hooknum == NF_IP_POST_ROUTING
-			|| hooknum == NF_IP_LOCAL_IN)) {
-			DEBUGP("ip_nat_core: adjusting sequence number\n");
-			/* future: put this in a l4-proto specific function,
-			 * and call this function here. */
-			if (!ip_nat_seq_adjust(pskb, ct, ctinfo))
-				ret = NF_DROP;
-		}
+	if (mtype == IP_NAT_MANIP_SRC)
+		statusbit = IPS_SRC_NAT;
+	else
+		statusbit = IPS_DST_NAT;
+
+	/* Invert if this is reply dir. */
+	if (dir == IP_CT_DIR_REPLY)
+		statusbit ^= IPS_NAT_MASK;
 
-		return ret;
+	/* Non-atomic: these bits don't change. */
+	if (ct->status & statusbit) {
+		struct ip_conntrack_tuple target;
 
-	} else 
-		return NF_ACCEPT;
+		/* We are aiming to look like inverse of other direction. */
+		invert_tuplepr(&target, &ct->tuplehash[!dir].tuple);
 
-	/* not reached */
+		if (!manip_pkt(target.dst.protonum, pskb, 0, &target, mtype))
+			return NF_DROP;
+	}
+	return NF_ACCEPT;
 }
 
-int
-icmp_reply_translation(struct sk_buff **pskb,
-		       struct ip_conntrack *conntrack,
-		       unsigned int hooknum,
-		       int dir)
+/* Dir is direction ICMP is coming from (opposite to packet it contains) */
+int icmp_reply_translation(struct sk_buff **pskb,
+			   struct ip_conntrack *ct,
+			   enum ip_nat_manip_type manip,
+			   enum ip_conntrack_dir dir)
 {
 	struct {
 		struct icmphdr icmp;
 		struct iphdr ip;
 	} *inside;
-	unsigned int i;
-	struct ip_nat_info *info = &conntrack->nat.info;
-	int hdrlen;
+	struct ip_conntrack_tuple inner, target;
+	int hdrlen = (*pskb)->nh.iph->ihl * 4;
 
-	if (!skb_ip_make_writable(pskb,(*pskb)->nh.iph->ihl*4+sizeof(*inside)))
+	if (!skb_ip_make_writable(pskb, hdrlen + sizeof(*inside)))
 		return 0;
+
 	inside = (void *)(*pskb)->data + (*pskb)->nh.iph->ihl*4;
 
 	/* We're actually going to mangle it beyond trivial checksum
@@ -856,82 +422,87 @@
            start talking to each other without our translation, and be
            confused... --RR */
 	if (inside->icmp.type == ICMP_REDIRECT) {
-		/* Don't care about races here. */
-		if (info->initialized
-		    != ((1 << IP_NAT_MANIP_SRC) | (1 << IP_NAT_MANIP_DST))
-		    || info->num_manips != 0)
+		/* If NAT isn't finished, assume it and drop. */
+		if ((ct->status & IPS_NAT_DONE_MASK) != IPS_NAT_DONE_MASK)
+			return 0;
+
+		if (ct->status & IPS_NAT_MASK)
 			return 0;
 	}
 
-	DEBUGP("icmp_reply_translation: translating error %p hook %u dir %s\n",
-	       *pskb, hooknum, dir == IP_CT_DIR_ORIGINAL ? "ORIG" : "REPLY");
-	/* Note: May not be from a NAT'd host, but probably safest to
-	   do translation always as if it came from the host itself
-	   (even though a "host unreachable" coming from the host
-	   itself is a bit weird).
+	DEBUGP("icmp_reply_translation: translating error %p manp %u dir %s\n",
+	       *pskb, manip, dir == IP_CT_DIR_ORIGINAL ? "ORIG" : "REPLY");
 
-	   More explanation: some people use NAT for anonymizing.
-	   Also, CERT recommends dropping all packets from private IP
-	   addresses (although ICMP errors from internal links with
-	   such addresses are not too uncommon, as Alan Cox points
-	   out) */
-
-	READ_LOCK(&ip_nat_lock);
-	for (i = 0; i < info->num_manips; i++) {
-		DEBUGP("icmp_reply: manip %u dir %s hook %u\n",
-		       i, info->manips[i].direction == IP_CT_DIR_ORIGINAL ?
-		       "ORIG" : "REPLY", info->manips[i].hooknum);
-
-		if (info->manips[i].direction != dir)
-			continue;
-
-		/* Mapping the inner packet is just like a normal
-		   packet, except it was never src/dst reversed, so
-		   where we would normally apply a dst manip, we apply
-		   a src, and vice versa. */
-		if (info->manips[i].hooknum == hooknum) {
-			DEBUGP("icmp_reply: inner %s -> %u.%u.%u.%u %u\n",
-			       info->manips[i].maniptype == IP_NAT_MANIP_SRC
-			       ? "DST" : "SRC",
-			       NIPQUAD(info->manips[i].manip.ip),
-			       ntohs(info->manips[i].manip.u.udp.port));
-			if (!manip_pkt(inside->ip.protocol, pskb,
-				       (*pskb)->nh.iph->ihl*4
-				       + sizeof(inside->icmp),
-				       &info->manips[i].manip,
-				       !info->manips[i].maniptype))
-				goto unlock_fail;
-
-			/* Outer packet needs to have IP header NATed like
-	                   it's a reply. */
-
-			/* Use mapping to map outer packet: 0 give no
-                           per-proto mapping */
-			DEBUGP("icmp_reply: outer %s -> %u.%u.%u.%u\n",
-			       info->manips[i].maniptype == IP_NAT_MANIP_SRC
-			       ? "SRC" : "DST",
-			       NIPQUAD(info->manips[i].manip.ip));
-			if (!manip_pkt(0, pskb, 0,
-				       &info->manips[i].manip,
-				       info->manips[i].maniptype))
-				goto unlock_fail;
-		}
-	}
-	READ_UNLOCK(&ip_nat_lock);
+	if (!ip_ct_get_tuple(&inside->ip, *pskb, (*pskb)->nh.iph->ihl*4 +
+	                     sizeof(struct icmphdr) + inside->ip.ihl*4,
+	                     &inner, ip_ct_find_proto(inside->ip.protocol)))
+		return 0;
 
-	hdrlen = (*pskb)->nh.iph->ihl * 4;
+	/* Change inner back to look like incoming packet.  We do the
+	   opposite manip on this hook to normal, because it might not
+	   pass all hooks (locally-generated ICMP).  Consider incoming
+	   packet: PREROUTING (DST manip), routing produces ICMP, goes
+	   through POSTROUTING (which must correct the DST manip). */
+	if (!manip_pkt(inside->ip.protocol, pskb,
+		       (*pskb)->nh.iph->ihl*4
+		       + sizeof(inside->icmp),
+		       &ct->tuplehash[!dir].tuple,
+		       !manip))
+		return 0;
 
+	/* Reloading "inside" here since manip_pkt inner. */
 	inside = (void *)(*pskb)->data + (*pskb)->nh.iph->ihl*4;
-
 	inside->icmp.checksum = 0;
 	inside->icmp.checksum = csum_fold(skb_checksum(*pskb, hdrlen,
 						       (*pskb)->len - hdrlen,
 						       0));
+
+	/* Change outer to look the reply to an incoming packet
+	 * (proto 0 means don't invert per-proto part). */
+
+	/* Obviously, we need to NAT destination IP, but source IP
+	   should be NAT'ed only if it is from a NAT'd host.
+
+	   Explanation: some people use NAT for anonymizing.  Also,
+	   CERT recommends dropping all packets from private IP
+	   addresses (although ICMP errors from internal links with
+	   such addresses are not too uncommon, as Alan Cox points
+	   out) */
+	if (manip != IP_NAT_MANIP_SRC
+	    || ((*pskb)->nh.iph->saddr == ct->tuplehash[dir].tuple.src.ip)) {
+		invert_tuplepr(&target, &ct->tuplehash[!dir].tuple);
+		if (!manip_pkt(0, pskb, 0, &target, manip))
+			return 0;
+	}
+
 	return 1;
+}
 
- unlock_fail:
-	READ_UNLOCK(&ip_nat_lock);
-	return 0;
+/* Protocol registration. */
+int ip_nat_protocol_register(struct ip_nat_protocol *proto)
+{
+	int ret = 0;
+
+	WRITE_LOCK(&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);
+	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);
+	ip_nat_protos[proto->protonum] = &ip_nat_unknown_protocol;
+	WRITE_UNLOCK(&ip_nat_lock);
+
+	/* Someone could be still looking at the proto in a bh. */
+	synchronize_net();
 }
 
 int __init ip_nat_init(void)
@@ -942,11 +513,9 @@
 	ip_nat_htable_size = ip_conntrack_htable_size;
 
 	/* One vmalloc for both hash tables */
-	bysource = vmalloc(sizeof(struct list_head) * ip_nat_htable_size*2);
-	if (!bysource) {
+	bysource = vmalloc(sizeof(struct list_head) * ip_nat_htable_size);
+	if (!bysource)
 		return -ENOMEM;
-	}
-	byipsproto = bysource + ip_nat_htable_size;
 
 	/* Sew in builtin protocols. */
 	WRITE_LOCK(&ip_nat_lock);
@@ -959,31 +528,29 @@
 
 	for (i = 0; i < ip_nat_htable_size; i++) {
 		INIT_LIST_HEAD(&bysource[i]);
-		INIT_LIST_HEAD(&byipsproto[i]);
 	}
 
 	/* FIXME: Man, this is a hack.  <SIGH> */
 	IP_NF_ASSERT(ip_conntrack_destroyed == NULL);
 	ip_conntrack_destroyed = &ip_nat_cleanup_conntrack;
-	
-	/* Initialize fake conntrack so that NAT will skip it */
-	ip_conntrack_untracked.nat.info.initialized |= 
-		(1 << IP_NAT_MANIP_SRC) | (1 << IP_NAT_MANIP_DST);
 
+	/* Initialize fake conntrack so that NAT will skip it */
+	ip_conntrack_untracked.status |= IPS_NAT_DONE_MASK;
 	return 0;
 }
 
 /* Clear NAT section of all conntracks, in case we're loaded again. */
-static int clean_nat(const struct ip_conntrack *i, void *data)
+static int clean_nat(struct ip_conntrack *i, void *data)
 {
-	memset((void *)&i->nat, 0, sizeof(i->nat));
+	memset(&i->nat, 0, sizeof(i->nat));
+	i->status &= ~(IPS_NAT_MASK | IPS_NAT_DONE_MASK | IPS_SEQ_ADJUST);
 	return 0;
 }
 
 /* Not __exit: called from ip_nat_standalone.c:init_or_cleanup() --RR */
 void ip_nat_cleanup(void)
 {
-	ip_ct_selective_cleanup(&clean_nat, NULL);
+	ip_ct_iterate_cleanup(&clean_nat, NULL);
 	ip_conntrack_destroyed = NULL;
 	vfree(bysource);
 }
diff -Nru a/net/ipv4/netfilter/ip_nat_ftp.c b/net/ipv4/netfilter/ip_nat_ftp.c
--- a/net/ipv4/netfilter/ip_nat_ftp.c	2005-03-01 23:39:07 -08:00
+++ b/net/ipv4/netfilter/ip_nat_ftp.c	2005-03-01 23:39:07 -08:00
@@ -30,72 +30,8 @@
 #define DEBUGP(format, args...)
 #endif
 
-#define MAX_PORTS 8
-static int ports[MAX_PORTS];
-static int ports_c;
-
-module_param_array(ports, int, &ports_c, 0400);
-
 /* FIXME: Time out? --RR */
 
-static unsigned int
-ftp_nat_expected(struct sk_buff **pskb,
-		 unsigned int hooknum,
-		 struct ip_conntrack *ct,
-		 struct ip_nat_info *info)
-{
-	struct ip_nat_multi_range mr;
-	u_int32_t newdstip, newsrcip, newip;
-	struct ip_ct_ftp_expect *exp_ftp_info;
-
-	struct ip_conntrack *master = master_ct(ct);
-	
-	IP_NF_ASSERT(info);
-	IP_NF_ASSERT(master);
-
-	IP_NF_ASSERT(!(info->initialized & (1<<HOOK2MANIP(hooknum))));
-
-	DEBUGP("nat_expected: We have a connection!\n");
-	exp_ftp_info = &ct->master->help.exp_ftp_info;
-
-	if (exp_ftp_info->ftptype == IP_CT_FTP_PORT
-	    || exp_ftp_info->ftptype == IP_CT_FTP_EPRT) {
-		/* PORT command: make connection go to the client. */
-		newdstip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip;
-		newsrcip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip;
-		DEBUGP("nat_expected: PORT cmd. %u.%u.%u.%u->%u.%u.%u.%u\n",
-		       NIPQUAD(newsrcip), NIPQUAD(newdstip));
-	} else {
-		/* PASV command: make the connection go to the server */
-		newdstip = master->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip;
-		newsrcip = master->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip;
-		DEBUGP("nat_expected: PASV cmd. %u.%u.%u.%u->%u.%u.%u.%u\n",
-		       NIPQUAD(newsrcip), NIPQUAD(newdstip));
-	}
-
-	if (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC)
-		newip = newsrcip;
-	else
-		newip = newdstip;
-
-	DEBUGP("nat_expected: IP to %u.%u.%u.%u\n", NIPQUAD(newip));
-
-	mr.rangesize = 1;
-	/* We don't want to manip the per-protocol, just the IPs... */
-	mr.range[0].flags = IP_NAT_RANGE_MAP_IPS;
-	mr.range[0].min_ip = mr.range[0].max_ip = newip;
-
-	/* ... unless we're doing a MANIP_DST, in which case, make
-	   sure we map to the correct port */
-	if (HOOK2MANIP(hooknum) == IP_NAT_MANIP_DST) {
-		mr.range[0].flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
-		mr.range[0].min = mr.range[0].max
-			= ((union ip_conntrack_manip_proto)
-				{ .tcp = { htons(exp_ftp_info->port) } });
-	}
-	return ip_nat_setup_info(ct, &mr, hooknum);
-}
-
 static int
 mangle_rfc959_packet(struct sk_buff **pskb,
 		     u_int32_t newip,
@@ -103,7 +39,8 @@
 		     unsigned int matchoff,
 		     unsigned int matchlen,
 		     struct ip_conntrack *ct,
-		     enum ip_conntrack_info ctinfo)
+		     enum ip_conntrack_info ctinfo,
+		     u32 *seq)
 {
 	char buffer[sizeof("nnn,nnn,nnn,nnn,nnn,nnn")];
 
@@ -112,6 +49,7 @@
 
 	DEBUGP("calling ip_nat_mangle_tcp_packet\n");
 
+	*seq += strlen(buffer) - matchlen;
 	return ip_nat_mangle_tcp_packet(pskb, ct, ctinfo, matchoff, 
 					matchlen, buffer, strlen(buffer));
 }
@@ -124,7 +62,8 @@
 		   unsigned int matchoff,
 		   unsigned int matchlen,
 		   struct ip_conntrack *ct,
-		   enum ip_conntrack_info ctinfo)
+		   enum ip_conntrack_info ctinfo,
+		   u32 *seq)
 {
 	char buffer[sizeof("|1|255.255.255.255|65535|")];
 
@@ -132,6 +71,7 @@
 
 	DEBUGP("calling ip_nat_mangle_tcp_packet\n");
 
+	*seq += strlen(buffer) - matchlen;
 	return ip_nat_mangle_tcp_packet(pskb, ct, ctinfo, matchoff, 
 					matchlen, buffer, strlen(buffer));
 }
@@ -144,7 +84,8 @@
 		   unsigned int matchoff,
 		   unsigned int matchlen,
 		   struct ip_conntrack *ct,
-		   enum ip_conntrack_info ctinfo)
+		   enum ip_conntrack_info ctinfo,
+		   u32 *seq)
 {
 	char buffer[sizeof("|||65535|")];
 
@@ -152,6 +93,7 @@
 
 	DEBUGP("calling ip_nat_mangle_tcp_packet\n");
 
+	*seq += strlen(buffer) - matchlen;
 	return ip_nat_mangle_tcp_packet(pskb, ct, ctinfo, matchoff, 
 					matchlen, buffer, strlen(buffer));
 }
@@ -160,178 +102,73 @@
 		     unsigned int,
 		     unsigned int,
 		     struct ip_conntrack *,
-		     enum ip_conntrack_info)
+		     enum ip_conntrack_info,
+		     u32 *seq)
 = { [IP_CT_FTP_PORT] = mangle_rfc959_packet,
     [IP_CT_FTP_PASV] = mangle_rfc959_packet,
     [IP_CT_FTP_EPRT] = mangle_eprt_packet,
     [IP_CT_FTP_EPSV] = mangle_epsv_packet
 };
 
-static int ftp_data_fixup(const struct ip_ct_ftp_expect *exp_ftp_info,
-			  struct ip_conntrack *ct,
-			  struct sk_buff **pskb,
-			  enum ip_conntrack_info ctinfo,
-			  struct ip_conntrack_expect *expect)
+/* So, this packet has hit the connection tracking matching code.
+   Mangle it, and change the expectation to match the new version. */
+static unsigned int ip_nat_ftp(struct sk_buff **pskb,
+			       enum ip_conntrack_info ctinfo,
+			       enum ip_ct_ftp_type type,
+			       unsigned int matchoff,
+			       unsigned int matchlen,
+			       struct ip_conntrack_expect *exp,
+			       u32 *seq)
 {
 	u_int32_t newip;
-	struct iphdr *iph = (*pskb)->nh.iph;
-	struct tcphdr *tcph = (void *)iph + iph->ihl*4;
 	u_int16_t port;
-	struct ip_conntrack_tuple newtuple;
+	int dir = CTINFO2DIR(ctinfo);
+	struct ip_conntrack *ct = exp->master;
 
-	DEBUGP("FTP_NAT: seq %u + %u in %u\n",
-	       expect->seq, exp_ftp_info->len,
-	       ntohl(tcph->seq));
-
-	/* Change address inside packet to match way we're mapping
-	   this connection. */
-	if (exp_ftp_info->ftptype == IP_CT_FTP_PASV
-	    || exp_ftp_info->ftptype == IP_CT_FTP_EPSV) {
-		/* PASV/EPSV response: must be where client thinks server
-		   is */
-		newip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip;
-		/* Expect something from client->server */
-		newtuple.src.ip = 
-			ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip;
-		newtuple.dst.ip = 
-			ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip;
-	} else {
-		/* PORT command: must be where server thinks client is */
-		newip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip;
-		/* Expect something from server->client */
-		newtuple.src.ip = 
-			ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip;
-		newtuple.dst.ip = 
-			ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip;
-	}
-	newtuple.dst.protonum = IPPROTO_TCP;
-	newtuple.src.u.tcp.port = expect->tuple.src.u.tcp.port;
+	DEBUGP("FTP_NAT: type %i, off %u len %u\n", type, matchoff, matchlen);
 
-	/* Try to get same port: if not, try to change it. */
-	for (port = exp_ftp_info->port; port != 0; port++) {
-		newtuple.dst.u.tcp.port = htons(port);
+	/* Connection will come from wherever this packet goes, hence !dir */
+	newip = ct->tuplehash[!dir].tuple.dst.ip;
+	exp->saved_proto.tcp.port = exp->tuple.dst.u.tcp.port;
+	exp->dir = !dir;
+
+	/* When you see the packet, we need to NAT it the same as the
+	 * this one. */
+	exp->expectfn = ip_nat_follow_master;
 
-		if (ip_conntrack_change_expect(expect, &newtuple) == 0)
+	/* Try to get same port: if not, try to change it. */
+	for (port = ntohs(exp->saved_proto.tcp.port); port != 0; port++) {
+		exp->tuple.dst.u.tcp.port = htons(port);
+		if (ip_conntrack_expect_related(exp) == 0)
 			break;
 	}
-	if (port == 0)
-		return 0;
-
-	if (!mangle[exp_ftp_info->ftptype](pskb, newip, port,
-					  expect->seq - ntohl(tcph->seq),
-					  exp_ftp_info->len, ct, ctinfo))
-		return 0;
 
-	return 1;
-}
-
-static unsigned int help(struct ip_conntrack *ct,
-			 struct ip_conntrack_expect *exp,
-			 struct ip_nat_info *info,
-			 enum ip_conntrack_info ctinfo,
-			 unsigned int hooknum,
-			 struct sk_buff **pskb)
-{
-	struct iphdr *iph = (*pskb)->nh.iph;
-	struct tcphdr *tcph = (void *)iph + iph->ihl*4;
-	unsigned int datalen;
-	int dir;
-	struct ip_ct_ftp_expect *exp_ftp_info;
-
-	if (!exp)
-		DEBUGP("ip_nat_ftp: no exp!!");
-
-	exp_ftp_info = &exp->help.exp_ftp_info;
-
-	/* Only mangle things once: original direction in POST_ROUTING
-	   and reply direction on PRE_ROUTING. */
-	dir = CTINFO2DIR(ctinfo);
-	if (!((hooknum == NF_IP_POST_ROUTING && dir == IP_CT_DIR_ORIGINAL)
-	      || (hooknum == NF_IP_PRE_ROUTING && dir == IP_CT_DIR_REPLY))) {
-		DEBUGP("nat_ftp: Not touching dir %s at hook %s\n",
-		       dir == IP_CT_DIR_ORIGINAL ? "ORIG" : "REPLY",
-		       hooknum == NF_IP_POST_ROUTING ? "POSTROUTING"
-		       : hooknum == NF_IP_PRE_ROUTING ? "PREROUTING"
-		       : hooknum == NF_IP_LOCAL_OUT ? "OUTPUT" : "???");
-		return NF_ACCEPT;
+	if (port == 0) {
+		ip_conntrack_expect_free(exp);
+		return NF_DROP;
 	}
 
-	datalen = (*pskb)->len - iph->ihl * 4 - tcph->doff * 4;
-	/* If it's in the right range... */
-	if (between(exp->seq + exp_ftp_info->len,
-		    ntohl(tcph->seq),
-		    ntohl(tcph->seq) + datalen)) {
-		if (!ftp_data_fixup(exp_ftp_info, ct, pskb, ctinfo, exp))
-			return NF_DROP;
-	} else {
-		/* Half a match?  This means a partial retransmisison.
-		   It's a cracker being funky. */
-		if (net_ratelimit()) {
-			printk("FTP_NAT: partial packet %u/%u in %u/%u\n",
-			       exp->seq, exp_ftp_info->len,
-			       ntohl(tcph->seq),
-			       ntohl(tcph->seq) + datalen);
-		}
+	if (!mangle[type](pskb, newip, port, matchoff, matchlen, ct, ctinfo,
+			  seq)) {
+		ip_conntrack_unexpect_related(exp);
 		return NF_DROP;
 	}
 	return NF_ACCEPT;
 }
 
-static struct ip_nat_helper ftp[MAX_PORTS];
-static char ftp_names[MAX_PORTS][10];
-
-/* Not __exit: called from init() */
-static void fini(void)
+static void __exit fini(void)
 {
-	int i;
-
-	for (i = 0; i < ports_c; i++) {
-		DEBUGP("ip_nat_ftp: unregistering port %d\n", ports[i]);
-		ip_nat_helper_unregister(&ftp[i]);
-	}
+	ip_nat_ftp_hook = NULL;
+	/* Make sure noone calls it, meanwhile. */
+	synchronize_net();
 }
 
 static int __init init(void)
 {
-	int i, ret = 0;
-	char *tmpname;
-
-	if (ports_c == 0)
-		ports[ports_c++] = FTP_PORT;
-
-	for (i = 0; i < ports_c; i++) {
-		ftp[i].tuple.dst.protonum = IPPROTO_TCP;
-		ftp[i].tuple.src.u.tcp.port = htons(ports[i]);
-		ftp[i].mask.dst.protonum = 0xFFFF;
-		ftp[i].mask.src.u.tcp.port = 0xFFFF;
-		ftp[i].help = help;
-		ftp[i].me = THIS_MODULE;
-		ftp[i].flags = 0;
-		ftp[i].expect = ftp_nat_expected;
-
-		tmpname = &ftp_names[i][0];
-		if (ports[i] == FTP_PORT)
-			sprintf(tmpname, "ftp");
-		else
-			sprintf(tmpname, "ftp-%d", i);
-		ftp[i].name = tmpname;
-
-		DEBUGP("ip_nat_ftp: Trying to register for port %d\n",
-				ports[i]);
-		ret = ip_nat_helper_register(&ftp[i]);
-
-		if (ret) {
-			printk("ip_nat_ftp: error registering "
-			       "helper for port %d\n", ports[i]);
-			fini();
-			return ret;
-		}
-	}
-
-	return ret;
+	BUG_ON(ip_nat_ftp_hook);
+	ip_nat_ftp_hook = ip_nat_ftp;
+	return 0;
 }
-
-NEEDS_CONNTRACK(ftp);
 
 module_init(init);
 module_exit(fini);
diff -Nru a/net/ipv4/netfilter/ip_nat_helper.c b/net/ipv4/netfilter/ip_nat_helper.c
--- a/net/ipv4/netfilter/ip_nat_helper.c	2005-03-01 23:38:53 -08:00
+++ b/net/ipv4/netfilter/ip_nat_helper.c	2005-03-01 23:38:53 -08:00
@@ -47,8 +47,7 @@
 #define DUMP_OFFSET(x)
 #endif
 
-static LIST_HEAD(helpers);
-DECLARE_LOCK(ip_nat_seqofs_lock);
+static DECLARE_LOCK(ip_nat_seqofs_lock);
 
 /* Setup TCP sequence correction given this change at this sequence */
 static inline void 
@@ -193,9 +192,14 @@
 	tcph->check = tcp_v4_check(tcph, datalen, iph->saddr, iph->daddr,
 				   csum_partial((char *)tcph, datalen, 0));
 
-	adjust_tcp_sequence(ntohl(tcph->seq),
-			    (int)rep_len - (int)match_len,
-			    ct, ctinfo);
+	if (rep_len != match_len) {
+		set_bit(IPS_SEQ_ADJUST_BIT, &ct->status);
+		adjust_tcp_sequence(ntohl(tcph->seq),
+				    (int)rep_len - (int)match_len,
+				    ct, ctinfo);
+		/* Tell TCP window tracking about seq change */
+		ip_conntrack_tcp_update(*pskb, ct, CTINFO2DIR(ctinfo));
+	}
 	return 1;
 }
 			
@@ -362,11 +366,6 @@
 	this_way = &ct->nat.info.seq[dir];
 	other_way = &ct->nat.info.seq[!dir];
 
-	/* No adjustments to make?  Very common case. */
-	if (!this_way->offset_before && !this_way->offset_after
-	    && !other_way->offset_before && !other_way->offset_after)
-		return 1;
-
 	if (!skb_ip_make_writable(pskb, (*pskb)->nh.iph->ihl*4+sizeof(*tcph)))
 		return 0;
 
@@ -404,75 +403,28 @@
 	return 1;
 }
 
-static inline int
-helper_cmp(const struct ip_nat_helper *helper,
-	   const struct ip_conntrack_tuple *tuple)
-{
-	return ip_ct_tuple_mask_cmp(tuple, &helper->tuple, &helper->mask);
-}
-
-int ip_nat_helper_register(struct ip_nat_helper *me)
-{
-	int ret = 0;
-
-	WRITE_LOCK(&ip_nat_lock);
-	if (LIST_FIND(&helpers, helper_cmp, struct ip_nat_helper *,&me->tuple))
-		ret = -EBUSY;
-	else
-		list_prepend(&helpers, me);
-	WRITE_UNLOCK(&ip_nat_lock);
-
-	return ret;
-}
-
-struct ip_nat_helper *
-__ip_nat_find_helper(const struct ip_conntrack_tuple *tuple)
-{
-	return LIST_FIND(&helpers, helper_cmp, struct ip_nat_helper *, tuple);
-}
-
-struct ip_nat_helper *
-ip_nat_find_helper(const struct ip_conntrack_tuple *tuple)
-{
-	struct ip_nat_helper *h;
-
-	READ_LOCK(&ip_nat_lock);
-	h = __ip_nat_find_helper(tuple);
-	READ_UNLOCK(&ip_nat_lock);
-
-	return h;
-}
-
-static int
-kill_helper(const struct ip_conntrack *i, void *helper)
-{
-	int ret;
-
-	READ_LOCK(&ip_nat_lock);
-	ret = (i->nat.info.helper == helper);
-	READ_UNLOCK(&ip_nat_lock);
-
-	return ret;
-}
-
-void ip_nat_helper_unregister(struct ip_nat_helper *me)
-{
-	WRITE_LOCK(&ip_nat_lock);
-	/* Autoloading conntrack helper might have failed */
-	if (LIST_FIND(&helpers, helper_cmp, struct ip_nat_helper *,&me->tuple)) {
-		LIST_DELETE(&helpers, me);
-	}
-	WRITE_UNLOCK(&ip_nat_lock);
-
-	/* Someone could be still looking at the helper in a bh. */
-	synchronize_net();
-
-	/* Find anything using it, and umm, kill them.  We can't turn
-	   them into normal connections: if we've adjusted SYNs, then
-	   they'll ackstorm.  So we just drop it.  We used to just
-	   bump module count when a connection existed, but that
-	   forces admins to gen fake RSTs or bounce box, either of
-	   which is just a long-winded way of making things
-	   worse. --RR */
-	ip_ct_selective_cleanup(kill_helper, me);
+/* Setup NAT on this expected conntrack so it follows master. */
+/* If we fail to get a free NAT slot, we'll get dropped on confirm */
+void ip_nat_follow_master(struct ip_conntrack *ct,
+			  struct ip_conntrack_expect *exp)
+{
+	struct ip_nat_range range;
+
+	/* This must be a fresh one. */
+	BUG_ON(ct->status & IPS_NAT_DONE_MASK);
+
+	/* Change src to where master sends to */
+	range.flags = IP_NAT_RANGE_MAP_IPS;
+	range.min_ip = range.max_ip
+		= ct->master->tuplehash[!exp->dir].tuple.dst.ip;
+	/* hook doesn't matter, but it has to do source manip */
+	ip_nat_setup_info(ct, &range, NF_IP_POST_ROUTING);
+
+	/* For DST manip, map port here to where it's expected. */
+	range.flags = (IP_NAT_RANGE_MAP_IPS | IP_NAT_RANGE_PROTO_SPECIFIED);
+	range.min = range.max = exp->saved_proto;
+	range.min_ip = range.max_ip
+		= ct->master->tuplehash[!exp->dir].tuple.src.ip;
+	/* hook doesn't matter, but it has to do destination manip */
+	ip_nat_setup_info(ct, &range, NF_IP_PRE_ROUTING);
 }
diff -Nru a/net/ipv4/netfilter/ip_nat_irc.c b/net/ipv4/netfilter/ip_nat_irc.c
--- a/net/ipv4/netfilter/ip_nat_irc.c	2005-03-01 23:39:17 -08:00
+++ b/net/ipv4/netfilter/ip_nat_irc.c	2005-03-01 23:39:17 -08:00
@@ -1,5 +1,6 @@
 /* IRC extension for TCP NAT alteration.
  * (C) 2000-2001 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2004 Rusty Russell <rusty@rustcorp.com.au> IBM Corporation
  * based on a copy of RR's ip_nat_ftp.c
  *
  * ip_nat_irc.c,v 1.16 2001/12/06 07:42:10 laforge Exp
@@ -8,12 +9,6 @@
  *      modify it under the terms of the GNU General Public License
  *      as published by the Free Software Foundation; either version
  *      2 of the License, or (at your option) any later version.
- *
- *	Module load syntax:
- * 	insmod ip_nat_irc.o ports=port1,port2,...port<MAX_PORTS>
- *	
- * 	please give the ports of all IRC servers You wish to connect to.
- *	If You don't specify ports, the default will be port 6667
  */
 
 #include <linux/module.h>
@@ -35,67 +30,18 @@
 #define DEBUGP(format, args...)
 #endif
 
-#define MAX_PORTS 8
-static int ports[MAX_PORTS];
-static int ports_c;
-
 MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");
 MODULE_DESCRIPTION("IRC (DCC) NAT helper");
 MODULE_LICENSE("GPL");
-module_param_array(ports, int, &ports_c, 0400);
-MODULE_PARM_DESC(ports, "port numbers of IRC servers");
-
-/* FIXME: Time out? --RR */
-
-static unsigned int
-irc_nat_expected(struct sk_buff **pskb,
-		 unsigned int hooknum,
-		 struct ip_conntrack *ct,
-		 struct ip_nat_info *info)
-{
-	struct ip_nat_multi_range mr;
-	u_int32_t newdstip, newsrcip, newip;
-
-	struct ip_conntrack *master = master_ct(ct);
-
-	IP_NF_ASSERT(info);
-	IP_NF_ASSERT(master);
-
-	IP_NF_ASSERT(!(info->initialized & (1 << HOOK2MANIP(hooknum))));
-
-	DEBUGP("nat_expected: We have a connection!\n");
 
-	newdstip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip;
-	newsrcip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip;
-	DEBUGP("nat_expected: DCC cmd. %u.%u.%u.%u->%u.%u.%u.%u\n",
-	       NIPQUAD(newsrcip), NIPQUAD(newdstip));
-
-	if (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC)
-		newip = newsrcip;
-	else
-		newip = newdstip;
-
-	DEBUGP("nat_expected: IP to %u.%u.%u.%u\n", NIPQUAD(newip));
-
-	mr.rangesize = 1;
-	/* We don't want to manip the per-protocol, just the IPs. */
-	mr.range[0].flags = IP_NAT_RANGE_MAP_IPS;
-	mr.range[0].min_ip = mr.range[0].max_ip = newip;
-
-	return ip_nat_setup_info(ct, &mr, hooknum);
-}
-
-static int irc_data_fixup(const struct ip_ct_irc_expect *exp_irc_info,
-			  struct ip_conntrack *ct,
-			  struct sk_buff **pskb,
-			  enum ip_conntrack_info ctinfo,
-			  struct ip_conntrack_expect *expect)
+static unsigned int help(struct sk_buff **pskb,
+			 enum ip_conntrack_info ctinfo,
+			 unsigned int matchoff,
+			 unsigned int matchlen,
+			 struct ip_conntrack_expect *exp)
 {
-	u_int32_t newip;
-	struct ip_conntrack_tuple t;
-	struct iphdr *iph = (*pskb)->nh.iph;
-	struct tcphdr *tcph = (void *) iph + iph->ihl * 4;
 	u_int16_t port;
+	unsigned int ret;
 
 	/* "4294967296 65635 " */
 	char buffer[18];
@@ -104,21 +50,25 @@
 	       expect->seq, exp_irc_info->len,
 	       ntohl(tcph->seq));
 
-	newip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip;
-
-	/* Alter conntrack's expectations. */
-	t = expect->tuple;
-	t.dst.ip = newip;
-	for (port = exp_irc_info->port; port != 0; port++) {
-		t.dst.u.tcp.port = htons(port);
-		if (ip_conntrack_change_expect(expect, &t) == 0) {
-			DEBUGP("using port %d", port);
+	/* Reply comes from server. */
+	exp->saved_proto.tcp.port = exp->tuple.dst.u.tcp.port;
+	exp->dir = IP_CT_DIR_REPLY;
+
+	/* When you see the packet, we need to NAT it the same as the
+	 * this one. */
+	exp->expectfn = ip_nat_follow_master;
+
+	/* Try to get same port: if not, try to change it. */
+	for (port = ntohs(exp->saved_proto.tcp.port); port != 0; port++) {
+		exp->tuple.dst.u.tcp.port = htons(port);
+		if (ip_conntrack_expect_related(exp) == 0)
 			break;
-		}
+	}
 
+	if (port == 0) {
+		ip_conntrack_expect_free(exp);
+		return NF_DROP;
 	}
-	if (port == 0)
-		return 0;
 
 	/*      strlen("\1DCC CHAT chat AAAAAAAA P\1\n")=27
 	 *      strlen("\1DCC SCHAT chat AAAAAAAA P\1\n")=28
@@ -133,131 +83,34 @@
 	 *              0x01, \n:  terminators
 	 */
 
-	sprintf(buffer, "%u %u", ntohl(newip), port);
+	/* AAA = "us", ie. where server normally talks to. */
+	sprintf(buffer, "%u %u",
+		ntohl(exp->master->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip),
+		port);
 	DEBUGP("ip_nat_irc: Inserting '%s' == %u.%u.%u.%u, port %u\n",
-	       buffer, NIPQUAD(newip), port);
-
-	return ip_nat_mangle_tcp_packet(pskb, ct, ctinfo, 
-					expect->seq - ntohl(tcph->seq),
-					exp_irc_info->len, buffer, 
-					strlen(buffer));
-}
-
-static unsigned int help(struct ip_conntrack *ct,
-			 struct ip_conntrack_expect *exp,
-			 struct ip_nat_info *info,
-			 enum ip_conntrack_info ctinfo,
-			 unsigned int hooknum, 
-			 struct sk_buff **pskb)
-{
-	struct iphdr *iph = (*pskb)->nh.iph;
-	struct tcphdr *tcph = (void *) iph + iph->ihl * 4;
-	unsigned int datalen;
-	int dir;
-	struct ip_ct_irc_expect *exp_irc_info;
-
-	if (!exp)
-		DEBUGP("ip_nat_irc: no exp!!");
-		
-	exp_irc_info = &exp->help.exp_irc_info;
-
-	/* Only mangle things once: original direction in POST_ROUTING
-	   and reply direction on PRE_ROUTING. */
-	dir = CTINFO2DIR(ctinfo);
-	if (!((hooknum == NF_IP_POST_ROUTING && dir == IP_CT_DIR_ORIGINAL)
-	      || (hooknum == NF_IP_PRE_ROUTING && dir == IP_CT_DIR_REPLY))) {
-		DEBUGP("nat_irc: Not touching dir %s at hook %s\n",
-		       dir == IP_CT_DIR_ORIGINAL ? "ORIG" : "REPLY",
-		       hooknum == NF_IP_POST_ROUTING ? "POSTROUTING"
-		       : hooknum == NF_IP_PRE_ROUTING ? "PREROUTING"
-		       : hooknum == NF_IP_LOCAL_OUT ? "OUTPUT" : "???");
-		return NF_ACCEPT;
-	}
-	DEBUGP("got beyond not touching\n");
+	       buffer, NIPQUAD(exp->tuple.src.ip), port);
 
-	datalen = (*pskb)->len - iph->ihl * 4 - tcph->doff * 4;
-	/* Check whether the whole IP/address pattern is carried in the payload */
-	if (between(exp->seq + exp_irc_info->len,
-		    ntohl(tcph->seq),
-		    ntohl(tcph->seq) + datalen)) {
-		if (!irc_data_fixup(exp_irc_info, ct, pskb, ctinfo, exp))
-			return NF_DROP;
-	} else { 
-		/* Half a match?  This means a partial retransmisison.
-		   It's a cracker being funky. */
-		if (net_ratelimit()) {
-			printk
-			    ("IRC_NAT: partial packet %u/%u in %u/%u\n",
-			     exp->seq, exp_irc_info->len,
-			     ntohl(tcph->seq),
-			     ntohl(tcph->seq) + datalen);
-		}
-		return NF_DROP;
-	}
-	return NF_ACCEPT;
+	ret = ip_nat_mangle_tcp_packet(pskb, exp->master, ctinfo, 
+				       matchoff, matchlen, buffer, 
+				       strlen(buffer));
+	if (ret != NF_ACCEPT)
+		ip_conntrack_unexpect_related(exp);
+	return ret;
 }
 
-static struct ip_nat_helper ip_nat_irc_helpers[MAX_PORTS];
-static char irc_names[MAX_PORTS][10];
-
-/* This function is intentionally _NOT_ defined as  __exit, because
- * it is needed by init() */
-static void fini(void)
+static void __exit fini(void)
 {
-	int i;
-
-	for (i = 0; i < ports_c; i++) {
-		DEBUGP("ip_nat_irc: unregistering helper for port %d\n",
-		       ports[i]);
-		ip_nat_helper_unregister(&ip_nat_irc_helpers[i]);
-	} 
+	ip_nat_irc_hook = NULL;
+	/* Make sure noone calls it, meanwhile. */
+	synchronize_net();
 }
 
 static int __init init(void)
 {
-	int ret = 0;
-	int i;
-	struct ip_nat_helper *hlpr;
-	char *tmpname;
-
-	if (ports_c == 0)
-		ports[ports_c++] = IRC_PORT;
-
-	for (i = 0; i < ports_c; i++) {
-		hlpr = &ip_nat_irc_helpers[i];
-		hlpr->tuple.dst.protonum = IPPROTO_TCP;
-		hlpr->tuple.src.u.tcp.port = htons(ports[i]);
-		hlpr->mask.src.u.tcp.port = 0xFFFF;
-		hlpr->mask.dst.protonum = 0xFFFF;
-		hlpr->help = help;
-		hlpr->flags = 0;
-		hlpr->me = THIS_MODULE;
-		hlpr->expect = irc_nat_expected;
-
-		tmpname = &irc_names[i][0];
-		if (ports[i] == IRC_PORT)
-			sprintf(tmpname, "irc");
-		else
-			sprintf(tmpname, "irc-%d", i);
-		hlpr->name = tmpname;
-
-		DEBUGP
-		    ("ip_nat_irc: Trying to register helper for port %d: name %s\n",
-		     ports[i], hlpr->name);
-		ret = ip_nat_helper_register(hlpr);
-
-		if (ret) {
-			printk
-			    ("ip_nat_irc: error registering helper for port %d\n",
-			     ports[i]);
-			fini();
-			return 1;
-		}
-	}
-	return ret;
+	BUG_ON(ip_nat_irc_hook);
+	ip_nat_irc_hook = help;
+	return 0;
 }
-
-NEEDS_CONNTRACK(irc);
 
 module_init(init);
 module_exit(fini);
diff -Nru 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	2005-03-01 23:38:54 -08:00
+++ b/net/ipv4/netfilter/ip_nat_proto_icmp.c	2005-03-01 23:38:54 -08:00
@@ -54,7 +54,7 @@
 static int
 icmp_manip_pkt(struct sk_buff **pskb,
 	       unsigned int iphdroff,
-	       const struct ip_conntrack_manip *manip,
+	       const struct ip_conntrack_tuple *tuple,
 	       enum ip_nat_manip_type maniptype)
 {
 	struct iphdr *iph = (struct iphdr *)((*pskb)->data + iphdroff);
@@ -64,12 +64,12 @@
 	if (!skb_ip_make_writable(pskb, hdroff + sizeof(*hdr)))
 		return 0;
 
-	hdr = (void *)(*pskb)->data + hdroff;
+	hdr = (struct icmphdr *)((*pskb)->data + hdroff);
 
 	hdr->checksum = ip_nat_cheat_check(hdr->un.echo.id ^ 0xFFFF,
-					    manip->u.icmp.id,
+					    tuple->src.u.icmp.id,
 					    hdr->checksum);
-	hdr->un.echo.id = manip->u.icmp.id;
+	hdr->un.echo.id = tuple->src.u.icmp.id;
 	return 1;
 }
 
diff -Nru 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	2005-03-01 23:38:44 -08:00
+++ b/net/ipv4/netfilter/ip_nat_proto_tcp.c	2005-03-01 23:38:44 -08:00
@@ -85,14 +85,14 @@
 static int
 tcp_manip_pkt(struct sk_buff **pskb,
 	      unsigned int iphdroff,
-	      const struct ip_conntrack_manip *manip,
+	      const struct ip_conntrack_tuple *tuple,
 	      enum ip_nat_manip_type maniptype)
 {
 	struct iphdr *iph = (struct iphdr *)((*pskb)->data + iphdroff);
 	struct tcphdr *hdr;
 	unsigned int hdroff = iphdroff + iph->ihl*4;
-	u_int32_t oldip;
-	u_int16_t *portptr, oldport;
+	u32 oldip, newip;
+	u16 *portptr, newport, oldport;
 	int hdrsize = 8; /* TCP connection tracking guarantees this much */
 
 	/* this could be a inner header returned in icmp packet; in such
@@ -104,27 +104,32 @@
 	if (!skb_ip_make_writable(pskb, hdroff + hdrsize))
 		return 0;
 
-	hdr = (void *)(*pskb)->data + hdroff;
+	iph = (struct iphdr *)((*pskb)->data + iphdroff);
+	hdr = (struct tcphdr *)((*pskb)->data + hdroff);
 
 	if (maniptype == IP_NAT_MANIP_SRC) {
 		/* Get rid of src ip and src pt */
 		oldip = iph->saddr;
+		newip = tuple->src.ip;
+		newport = tuple->src.u.tcp.port;
 		portptr = &hdr->source;
 	} else {
 		/* Get rid of dst ip and dst pt */
 		oldip = iph->daddr;
+		newip = tuple->dst.ip;
+		newport = tuple->dst.u.tcp.port;
 		portptr = &hdr->dest;
 	}
 
 	oldport = *portptr;
-	*portptr = manip->u.tcp.port;
+	*portptr = newport;
 
 	if (hdrsize < sizeof(*hdr))
 		return 1;
 
-	hdr->check = ip_nat_cheat_check(~oldip, manip->ip,
+	hdr->check = ip_nat_cheat_check(~oldip, newip,
 					ip_nat_cheat_check(oldport ^ 0xFFFF,
-							   manip->u.tcp.port,
+							   newport,
 							   hdr->check));
 	return 1;
 }
diff -Nru 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	2005-03-01 23:38:53 -08:00
+++ b/net/ipv4/netfilter/ip_nat_proto_udp.c	2005-03-01 23:38:53 -08:00
@@ -84,34 +84,40 @@
 static int
 udp_manip_pkt(struct sk_buff **pskb,
 	      unsigned int iphdroff,
-	      const struct ip_conntrack_manip *manip,
+	      const struct ip_conntrack_tuple *tuple,
 	      enum ip_nat_manip_type maniptype)
 {
 	struct iphdr *iph = (struct iphdr *)((*pskb)->data + iphdroff);
 	struct udphdr *hdr;
 	unsigned int hdroff = iphdroff + iph->ihl*4;
-	u_int32_t oldip;
-	u_int16_t *portptr;
+	u32 oldip, newip;
+	u16 *portptr, newport;
 
-	if (!skb_ip_make_writable(pskb, hdroff + sizeof(hdr)))
+	if (!skb_ip_make_writable(pskb, hdroff + sizeof(*hdr)))
 		return 0;
 
-	hdr = (void *)(*pskb)->data + hdroff;
+	iph = (struct iphdr *)((*pskb)->data + iphdroff);
+	hdr = (struct udphdr *)((*pskb)->data + hdroff);
+
 	if (maniptype == IP_NAT_MANIP_SRC) {
 		/* Get rid of src ip and src pt */
 		oldip = iph->saddr;
+		newip = tuple->src.ip;
+		newport = tuple->src.u.udp.port;
 		portptr = &hdr->source;
 	} else {
 		/* Get rid of dst ip and dst pt */
 		oldip = iph->daddr;
+		newip = tuple->dst.ip;
+		newport = tuple->dst.u.udp.port;
 		portptr = &hdr->dest;
 	}
 	if (hdr->check) /* 0 is a special case meaning no checksum */
-		hdr->check = ip_nat_cheat_check(~oldip, manip->ip,
+		hdr->check = ip_nat_cheat_check(~oldip, newip,
 					ip_nat_cheat_check(*portptr ^ 0xFFFF,
-							   manip->u.udp.port,
+							   newport,
 							   hdr->check));
-	*portptr = manip->u.udp.port;
+	*portptr = newport;
 	return 1;
 }
 
diff -Nru a/net/ipv4/netfilter/ip_nat_proto_unknown.c b/net/ipv4/netfilter/ip_nat_proto_unknown.c
--- a/net/ipv4/netfilter/ip_nat_proto_unknown.c	2005-03-01 23:38:57 -08:00
+++ b/net/ipv4/netfilter/ip_nat_proto_unknown.c	2005-03-01 23:38:57 -08:00
@@ -40,7 +40,7 @@
 static int
 unknown_manip_pkt(struct sk_buff **pskb,
 		  unsigned int iphdroff,
-		  const struct ip_conntrack_manip *manip,
+		  const struct ip_conntrack_tuple *tuple,
 		  enum ip_nat_manip_type maniptype)
 {
 	return 1;
diff -Nru a/net/ipv4/netfilter/ip_nat_rule.c b/net/ipv4/netfilter/ip_nat_rule.c
--- a/net/ipv4/netfilter/ip_nat_rule.c	2005-03-01 23:38:56 -08:00
+++ b/net/ipv4/netfilter/ip_nat_rule.c	2005-03-01 23:38:56 -08:00
@@ -16,6 +16,7 @@
 #include <linux/skbuff.h>
 #include <linux/proc_fs.h>
 #include <net/checksum.h>
+#include <net/route.h>
 #include <linux/bitops.h>
 
 #define ASSERT_READ_LOCK(x) MUST_BE_READ_LOCKED(&ip_nat_lock)
@@ -35,32 +36,13 @@
 
 #define NAT_VALID_HOOKS ((1<<NF_IP_PRE_ROUTING) | (1<<NF_IP_POST_ROUTING) | (1<<NF_IP_LOCAL_OUT))
 
-/* Standard entry. */
-struct ipt_standard
-{
-	struct ipt_entry entry;
-	struct ipt_standard_target target;
-};
-
-struct ipt_error_target
-{
-	struct ipt_entry_target target;
-	char errorname[IPT_FUNCTION_MAXNAMELEN];
-};
-
-struct ipt_error
-{
-	struct ipt_entry entry;
-	struct ipt_error_target target;
-};
-
 static struct
 {
 	struct ipt_replace repl;
 	struct ipt_standard entries[3];
 	struct ipt_error term;
-} nat_initial_table = {
-    { "nat", NAT_VALID_HOOKS, 4,
+} nat_initial_table __initdata
+= { { "nat", NAT_VALID_HOOKS, 4,
       sizeof(struct ipt_standard) * 3 + sizeof(struct ipt_error),
       { [NF_IP_PRE_ROUTING] = 0,
 	[NF_IP_POST_ROUTING] = sizeof(struct ipt_standard),
@@ -110,7 +92,6 @@
 
 static struct ipt_table nat_table = {
 	.name		= "nat",
-	.table		= &nat_initial_table.repl,
 	.valid_hooks	= NAT_VALID_HOOKS,
 	.lock		= RW_LOCK_UNLOCKED,
 	.me		= THIS_MODULE,
@@ -126,6 +107,7 @@
 {
 	struct ip_conntrack *ct;
 	enum ip_conntrack_info ctinfo;
+	const struct ip_nat_multi_range_compat *mr = targinfo;
 
 	IP_NF_ASSERT(hooknum == NF_IP_POST_ROUTING);
 
@@ -136,7 +118,26 @@
 	                    || ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY));
 	IP_NF_ASSERT(out);
 
-	return ip_nat_setup_info(ct, targinfo, hooknum);
+	return ip_nat_setup_info(ct, &mr->range[0], hooknum);
+}
+
+/* Before 2.6.11 we did implicit source NAT if required. Warn about change. */
+static void warn_if_extra_mangle(u32 dstip, u32 srcip)
+{
+	static int warned = 0;
+	struct flowi fl = { .nl_u = { .ip4_u = { .daddr = dstip } } };
+	struct rtable *rt;
+
+	if (ip_route_output_key(&rt, &fl) != 0)
+		return;
+
+	if (rt->rt_src != srcip && !warned) {
+		printk("NAT: no longer support implicit source local NAT\n");
+		printk("NAT: packet src %u.%u.%u.%u -> dst %u.%u.%u.%u\n",
+		       NIPQUAD(srcip), NIPQUAD(dstip));
+		warned = 1;
+	}
+	ip_rt_put(rt);
 }
 
 static unsigned int ipt_dnat_target(struct sk_buff **pskb,
@@ -148,20 +149,22 @@
 {
 	struct ip_conntrack *ct;
 	enum ip_conntrack_info ctinfo;
+	const struct ip_nat_multi_range_compat *mr = targinfo;
 
-#ifdef CONFIG_IP_NF_NAT_LOCAL
 	IP_NF_ASSERT(hooknum == NF_IP_PRE_ROUTING
 		     || hooknum == NF_IP_LOCAL_OUT);
-#else
-	IP_NF_ASSERT(hooknum == NF_IP_PRE_ROUTING);
-#endif
 
 	ct = ip_conntrack_get(*pskb, &ctinfo);
 
 	/* Connection must be valid and new. */
 	IP_NF_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED));
 
-	return ip_nat_setup_info(ct, targinfo, hooknum);
+	if (hooknum == NF_IP_LOCAL_OUT
+	    && mr->range[0].flags & IP_NAT_RANGE_MAP_IPS)
+		warn_if_extra_mangle((*pskb)->nh.iph->daddr,
+				     mr->range[0].min_ip);
+
+	return ip_nat_setup_info(ct, &mr->range[0], hooknum);
 }
 
 static int ipt_snat_checkentry(const char *tablename,
@@ -170,17 +173,15 @@
 			       unsigned int targinfosize,
 			       unsigned int hook_mask)
 {
-	struct ip_nat_multi_range *mr = targinfo;
+	struct ip_nat_multi_range_compat *mr = targinfo;
 
 	/* Must be a valid range */
-	if (targinfosize < sizeof(struct ip_nat_multi_range)) {
-		DEBUGP("SNAT: Target size %u too small\n", targinfosize);
+	if (mr->rangesize != 1) {
+		printk("SNAT: multiple ranges no longer supported\n");
 		return 0;
 	}
 
-	if (targinfosize != IPT_ALIGN((sizeof(struct ip_nat_multi_range)
-				       + (sizeof(struct ip_nat_range)
-					  * (mr->rangesize - 1))))) {
+	if (targinfosize != IPT_ALIGN(sizeof(struct ip_nat_multi_range_compat))) {
 		DEBUGP("SNAT: Target size %u wrong for %u ranges\n",
 		       targinfosize, mr->rangesize);
 		return 0;
@@ -205,17 +206,15 @@
 			       unsigned int targinfosize,
 			       unsigned int hook_mask)
 {
-	struct ip_nat_multi_range *mr = targinfo;
+	struct ip_nat_multi_range_compat *mr = targinfo;
 
 	/* Must be a valid range */
-	if (targinfosize < sizeof(struct ip_nat_multi_range)) {
-		DEBUGP("DNAT: Target size %u too small\n", targinfosize);
+	if (mr->rangesize != 1) {
+		printk("DNAT: multiple ranges no longer supported\n");
 		return 0;
 	}
 
-	if (targinfosize != IPT_ALIGN((sizeof(struct ip_nat_multi_range)
-				       + (sizeof(struct ip_nat_range)
-					  * (mr->rangesize - 1))))) {
+	if (targinfosize != IPT_ALIGN(sizeof(struct ip_nat_multi_range_compat))) {
 		DEBUGP("DNAT: Target size %u wrong for %u ranges\n",
 		       targinfosize, mr->rangesize);
 		return 0;
@@ -232,13 +231,6 @@
 		return 0;
 	}
 	
-#ifndef CONFIG_IP_NF_NAT_LOCAL
-	if (hook_mask & (1 << NF_IP_LOCAL_OUT)) {
-		DEBUGP("DNAT: CONFIG_IP_NF_NAT_LOCAL not enabled\n");
-		return 0;
-	}
-#endif
-
 	return 1;
 }
 
@@ -255,12 +247,12 @@
 		= (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC
 		   ? conntrack->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip
 		   : conntrack->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip);
-	struct ip_nat_multi_range mr
-		= { 1, { { IP_NAT_RANGE_MAP_IPS, ip, ip, { 0 }, { 0 } } } };
+	struct ip_nat_range range
+		= { IP_NAT_RANGE_MAP_IPS, ip, ip, { 0 }, { 0 } };
 
 	DEBUGP("Allocating NULL binding for %p (%u.%u.%u.%u)\n", conntrack,
 	       NIPQUAD(ip));
-	return ip_nat_setup_info(conntrack, &mr, hooknum);
+	return ip_nat_setup_info(conntrack, &range, hooknum);
 }
 
 int ip_nat_rule_find(struct sk_buff **pskb,
@@ -275,7 +267,7 @@
 	ret = ipt_do_table(pskb, hooknum, in, out, &nat_table, NULL);
 
 	if (ret == NF_ACCEPT) {
-		if (!(info->initialized & (1 << HOOK2MANIP(hooknum))))
+		if (!ip_nat_initialized(ct, HOOK2MANIP(hooknum)))
 			/* NUL mapping */
 			ret = alloc_null_binding(ct, info, hooknum);
 	}
@@ -298,7 +290,7 @@
 {
 	int ret;
 
-	ret = ipt_register_table(&nat_table);
+	ret = ipt_register_table(&nat_table, &nat_initial_table.repl);
 	if (ret != 0)
 		return ret;
 	ret = ipt_register_target(&ipt_snat_reg);
diff -Nru a/net/ipv4/netfilter/ip_nat_snmp_basic.c b/net/ipv4/netfilter/ip_nat_snmp_basic.c
--- a/net/ipv4/netfilter/ip_nat_snmp_basic.c	2005-03-01 23:39:09 -08:00
+++ b/net/ipv4/netfilter/ip_nat_snmp_basic.c	2005-03-01 23:39:09 -08:00
@@ -50,6 +50,7 @@
 #include <linux/moduleparam.h>
 #include <linux/netfilter_ipv4.h>
 #include <linux/netfilter_ipv4/ip_nat.h>
+#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
 #include <linux/netfilter_ipv4/ip_nat_helper.h>
 #include <linux/ip.h>
 #include <net/checksum.h>
@@ -65,7 +66,7 @@
 #define NOCT1(n) (u_int8_t )((n) & 0xff)
 
 static int debug;
-static spinlock_t snmp_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(snmp_lock);
 
 /* 
  * Application layer address mapping mimics the NAT mapping, but 
@@ -1203,9 +1204,7 @@
  * SNMP translation routine.
  */
 static int snmp_translate(struct ip_conntrack *ct,
-                          struct ip_nat_info *info,
                           enum ip_conntrack_info ctinfo,
-                          unsigned int hooknum,
                           struct sk_buff **pskb)
 {
 	struct iphdr *iph = (*pskb)->nh.iph;
@@ -1234,101 +1233,86 @@
 	
 	if (!snmp_parse_mangle((unsigned char *)udph + sizeof(struct udphdr),
 	                       paylen, &map, &udph->check)) {
-		printk(KERN_WARNING "bsalg: parser failed\n");
+		if (net_ratelimit())
+			printk(KERN_WARNING "bsalg: parser failed\n");
 		return NF_DROP;
 	}
 	return NF_ACCEPT;
 }
 
-/* 
- * NAT helper function, packets arrive here from NAT code.
- */
-static unsigned int nat_help(struct ip_conntrack *ct,
-			     struct ip_conntrack_expect *exp,
-                             struct ip_nat_info *info,
-                             enum ip_conntrack_info ctinfo,
-                             unsigned int hooknum,
-                             struct sk_buff **pskb)
+/* We don't actually set up expectations, just adjust internal IP
+ * addresses if this is being NATted */
+static int help(struct sk_buff **pskb,
+		struct ip_conntrack *ct,
+		enum ip_conntrack_info ctinfo)
 {
 	int dir = CTINFO2DIR(ctinfo);
+	unsigned int ret;
 	struct iphdr *iph = (*pskb)->nh.iph;
 	struct udphdr *udph = (struct udphdr *)((u_int32_t *)iph + iph->ihl);
-	
-	if (!skb_ip_make_writable(pskb, (*pskb)->len))
-		return NF_DROP;
 
-	spin_lock_bh(&snmp_lock);
-	
-	/*
-	 * Translate snmp replies on pre-routing (DNAT) and snmp traps
-	 * on post routing (SNAT).
-	 */
-	if (!((dir == IP_CT_DIR_REPLY && hooknum == NF_IP_PRE_ROUTING &&
-			udph->source == ntohs(SNMP_PORT)) ||
-	      (dir == IP_CT_DIR_ORIGINAL && hooknum == NF_IP_POST_ROUTING &&
-	      		udph->dest == ntohs(SNMP_TRAP_PORT)))) {
-		spin_unlock_bh(&snmp_lock);
+	/* SNMP replies and originating SNMP traps get mangled */
+	if (udph->source == ntohs(SNMP_PORT) && dir != IP_CT_DIR_REPLY)
+		return NF_ACCEPT;
+	if (udph->dest == ntohs(SNMP_TRAP_PORT) && dir != IP_CT_DIR_ORIGINAL)
+		return NF_ACCEPT;
+
+	/* No NAT? */
+	if (!(ct->status & IPS_NAT_MASK))
 		return NF_ACCEPT;
-	}
 
-	if (debug > 1) {
-		printk(KERN_DEBUG "bsalg: dir=%s hook=%d manip=%s len=%d "
-		       "src=%u.%u.%u.%u:%u dst=%u.%u.%u.%u:%u "
-		       "osrc=%u.%u.%u.%u odst=%u.%u.%u.%u "
-		       "rsrc=%u.%u.%u.%u rdst=%u.%u.%u.%u "
-		       "\n", 
-		       dir == IP_CT_DIR_REPLY ? "reply" : "orig", hooknum, 
-		       HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC ? "snat" :
-		       "dnat", (*pskb)->len,
-		       NIPQUAD(iph->saddr), ntohs(udph->source),
-		       NIPQUAD(iph->daddr), ntohs(udph->dest),
-		       NIPQUAD(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip),
-		       NIPQUAD(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip),
-		       NIPQUAD(ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip),
-		       NIPQUAD(ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip));
-	}
-	
 	/* 
 	 * Make sure the packet length is ok.  So far, we were only guaranteed
 	 * to have a valid length IP header plus 8 bytes, which means we have
 	 * enough room for a UDP header.  Just verify the UDP length field so we
 	 * can mess around with the payload.
 	 */
-	 if (ntohs(udph->len) == (*pskb)->len - (iph->ihl << 2)) {
-	 	int ret = snmp_translate(ct, info, ctinfo, hooknum, pskb);
-	 	spin_unlock_bh(&snmp_lock);
-	 	return ret;
+	if (ntohs(udph->len) != (*pskb)->len - (iph->ihl << 2)) {
+		 if (net_ratelimit())
+			 printk(KERN_WARNING "SNMP: dropping malformed packet "
+				"src=%u.%u.%u.%u dst=%u.%u.%u.%u\n",
+				NIPQUAD(iph->saddr), NIPQUAD(iph->daddr));
+		 return NF_DROP;
 	}
-	
-	if (net_ratelimit())
-		printk(KERN_WARNING "bsalg: dropping malformed packet "
-		       "src=%u.%u.%u.%u dst=%u.%u.%u.%u\n",
-		       NIPQUAD(iph->saddr), NIPQUAD(iph->daddr));
+
+	if (!skb_ip_make_writable(pskb, (*pskb)->len))
+		return NF_DROP;
+
+	spin_lock_bh(&snmp_lock);
+	ret = snmp_translate(ct, ctinfo, pskb);
 	spin_unlock_bh(&snmp_lock);
-	return NF_DROP;
+	return ret;
 }
 
-static struct ip_nat_helper snmp = { 
-	{ NULL, NULL },
-	"snmp",
-	0,
-	THIS_MODULE,
-	{ { 0, { .udp = { __constant_htons(SNMP_PORT) } } },
-	  { 0, { 0 }, IPPROTO_UDP } },
-	{ { 0, { .udp = { 0xFFFF } } },
-	  { 0, { 0 }, 0xFFFF } },
-	nat_help, NULL };
- 
-static struct ip_nat_helper snmp_trap = { 
-	{ NULL, NULL },
-	"snmp_trap",
-	0,
-	THIS_MODULE,
-	{ { 0, { .udp = { __constant_htons(SNMP_TRAP_PORT) } } },
-	  { 0, { 0 }, IPPROTO_UDP } },
-	{ { 0, { .udp = { 0xFFFF } } },
-	  { 0, { 0 }, 0xFFFF } },
-	nat_help, NULL };
+static struct ip_conntrack_helper snmp_helper = {
+	.max_expected = 0,
+	.timeout = 180,
+	.me = THIS_MODULE,
+	.help = help,
+	.name = "snmp",
+
+	.tuple = { .src = { .u = { __constant_htons(SNMP_PORT) } },
+		   .dst = { .protonum = IPPROTO_UDP },
+	},
+	.mask = { .src = { .u = { 0xFFFF } },
+		 .dst = { .protonum = 0xFF },
+	},
+};
+
+static struct ip_conntrack_helper snmp_trap_helper = {
+	.max_expected = 0,
+	.timeout = 180,
+	.me = THIS_MODULE,
+	.help = help,
+	.name = "snmp_trap",
+
+	.tuple = { .src = { .u = { __constant_htons(SNMP_TRAP_PORT) } },
+		   .dst = { .protonum = IPPROTO_UDP },
+	},
+	.mask = { .src = { .u = { 0xFFFF } },
+		 .dst = { .protonum = 0xFF },
+	},
+};
 
 /*****************************************************************************
  *
@@ -1340,12 +1324,12 @@
 {
 	int ret = 0;
 
-	ret = ip_nat_helper_register(&snmp);
+	ret = ip_conntrack_helper_register(&snmp_helper);
 	if (ret < 0)
 		return ret;
-	ret = ip_nat_helper_register(&snmp_trap);
+	ret = ip_conntrack_helper_register(&snmp_trap_helper);
 	if (ret < 0) {
-		ip_nat_helper_unregister(&snmp);
+		ip_conntrack_helper_unregister(&snmp_helper);
 		return ret;
 	}
 	return ret;
@@ -1353,9 +1337,8 @@
 
 static void __exit fini(void)
 {
-	ip_nat_helper_unregister(&snmp);
-	ip_nat_helper_unregister(&snmp_trap);
-	synchronize_net();
+	ip_conntrack_helper_unregister(&snmp_helper);
+	ip_conntrack_helper_unregister(&snmp_trap_helper);
 }
 
 module_init(init);
diff -Nru a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c
--- a/net/ipv4/netfilter/ip_nat_standalone.c	2005-03-01 23:39:09 -08:00
+++ b/net/ipv4/netfilter/ip_nat_standalone.c	2005-03-01 23:39:09 -08:00
@@ -55,15 +55,6 @@
 			         : ((hooknum) == NF_IP_LOCAL_IN ? "LOCAL_IN"  \
 				    : "*ERROR*")))
 
-static inline int call_expect(struct ip_conntrack *master,
-			      struct sk_buff **pskb,
-			      unsigned int hooknum,
-			      struct ip_conntrack *ct,
-			      struct ip_nat_info *info)
-{
-	return master->nat.info.helper->expect(pskb, hooknum, ct, info);
-}
-
 static unsigned int
 ip_nat_fn(unsigned int hooknum,
 	  struct sk_buff **pskb,
@@ -115,7 +106,7 @@
 	case IP_CT_RELATED:
 	case IP_CT_RELATED+IP_CT_IS_REPLY:
 		if ((*pskb)->nh.iph->protocol == IPPROTO_ICMP) {
-			if (!icmp_reply_translation(pskb, ct, hooknum,
+			if (!icmp_reply_translation(pskb, ct, maniptype,
 						    CTINFO2DIR(ctinfo)))
 				return NF_DROP;
 			else
@@ -125,47 +116,26 @@
 	case IP_CT_NEW:
 		info = &ct->nat.info;
 
-		WRITE_LOCK(&ip_nat_lock);
 		/* Seen it before?  This can happen for loopback, retrans,
 		   or local packets.. */
-		if (!(info->initialized & (1 << maniptype))
-#ifndef CONFIG_IP_NF_NAT_LOCAL
-		    /* If this session has already been confirmed we must not
-		     * touch it again even if there is no mapping set up.
-		     * Can only happen on local->local traffic with
-		     * CONFIG_IP_NF_NAT_LOCAL disabled.
-		     */
-		    && !(ct->status & IPS_CONFIRMED)
-#endif
-		    ) {
+		if (!ip_nat_initialized(ct, maniptype)) {
 			unsigned int ret;
 
-			if (ct->master
-			    && master_ct(ct)->nat.info.helper
-			    && master_ct(ct)->nat.info.helper->expect) {
-				ret = call_expect(master_ct(ct), pskb, 
-						  hooknum, ct, info);
-			} else {
-#ifdef CONFIG_IP_NF_NAT_LOCAL
-				/* LOCAL_IN hook doesn't have a chain!  */
-				if (hooknum == NF_IP_LOCAL_IN)
-					ret = alloc_null_binding(ct, info,
-								 hooknum);
-				else
-#endif
-				ret = ip_nat_rule_find(pskb, hooknum, in, out,
-						       ct, info);
-			}
+			/* LOCAL_IN hook doesn't have a chain!  */
+			if (hooknum == NF_IP_LOCAL_IN)
+				ret = alloc_null_binding(ct, info, hooknum);
+			else
+				ret = ip_nat_rule_find(pskb, hooknum,
+						       in, out, ct,
+						       info);
 
 			if (ret != NF_ACCEPT) {
-				WRITE_UNLOCK(&ip_nat_lock);
 				return ret;
 			}
 		} else
 			DEBUGP("Already setup manip %s for ct %p\n",
 			       maniptype == IP_NAT_MANIP_SRC ? "SRC" : "DST",
 			       ct);
-		WRITE_UNLOCK(&ip_nat_lock);
 		break;
 
 	default:
@@ -176,7 +146,30 @@
 	}
 
 	IP_NF_ASSERT(info);
-	return do_bindings(ct, ctinfo, info, hooknum, pskb);
+	return nat_packet(ct, ctinfo, hooknum, pskb);
+}
+
+static unsigned int
+ip_nat_in(unsigned int hooknum,
+          struct sk_buff **pskb,
+          const struct net_device *in,
+          const struct net_device *out,
+          int (*okfn)(struct sk_buff *))
+{
+	u_int32_t saddr, daddr;
+	unsigned int ret;
+
+	saddr = (*pskb)->nh.iph->saddr;
+	daddr = (*pskb)->nh.iph->daddr;
+
+	ret = ip_nat_fn(hooknum, pskb, in, out, okfn);
+	if (ret != NF_DROP && ret != NF_STOLEN
+	    && ((*pskb)->nh.iph->saddr != saddr
+	        || (*pskb)->nh.iph->daddr != daddr)) {
+		dst_release((*pskb)->dst);
+		(*pskb)->dst = NULL;
+	}
+	return ret;
 }
 
 static unsigned int
@@ -202,7 +195,7 @@
 	   I'm starting to have nightmares about fragments.  */
 
 	if ((*pskb)->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) {
-		*pskb = ip_ct_gather_frags(*pskb);
+		*pskb = ip_ct_gather_frags(*pskb, IP_DEFRAG_NAT_OUT);
 
 		if (!*pskb)
 			return NF_STOLEN;
@@ -211,7 +204,6 @@
 	return ip_nat_fn(hooknum, pskb, in, out, okfn);
 }
 
-#ifdef CONFIG_IP_NF_NAT_LOCAL
 static unsigned int
 ip_nat_local_fn(unsigned int hooknum,
 		struct sk_buff **pskb,
@@ -237,13 +229,12 @@
 		return ip_route_me_harder(pskb) == 0 ? ret : NF_DROP;
 	return ret;
 }
-#endif
 
 /* We must be after connection tracking and before packet filtering. */
 
 /* Before packet filtering, change destination */
 static struct nf_hook_ops ip_nat_in_ops = {
-	.hook		= ip_nat_fn,
+	.hook		= ip_nat_in,
 	.owner		= THIS_MODULE,
 	.pf		= PF_INET,
 	.hooknum	= NF_IP_PRE_ROUTING,
@@ -259,7 +250,6 @@
 	.priority	= NF_IP_PRI_NAT_SRC,
 };
 
-#ifdef CONFIG_IP_NF_NAT_LOCAL
 /* Before packet filtering, change destination */
 static struct nf_hook_ops ip_nat_local_out_ops = {
 	.hook		= ip_nat_local_fn,
@@ -277,34 +267,6 @@
 	.hooknum	= NF_IP_LOCAL_IN,
 	.priority	= NF_IP_PRI_NAT_SRC,
 };
-#endif
-
-/* Protocol registration. */
-int ip_nat_protocol_register(struct ip_nat_protocol *proto)
-{
-	int ret = 0;
-
-	WRITE_LOCK(&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);
-	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);
-	ip_nat_protos[proto->protonum] = &ip_nat_unknown_protocol;
-	WRITE_UNLOCK(&ip_nat_lock);
-
-	/* Someone could be still looking at the proto in a bh. */
-	synchronize_net();
-}
 
 static int init_or_cleanup(int init)
 {
@@ -334,7 +296,6 @@
 		printk("ip_nat_init: can't register out hook.\n");
 		goto cleanup_inops;
 	}
-#ifdef CONFIG_IP_NF_NAT_LOCAL
 	ret = nf_register_hook(&ip_nat_local_out_ops);
 	if (ret < 0) {
 		printk("ip_nat_init: can't register local out hook.\n");
@@ -345,16 +306,13 @@
 		printk("ip_nat_init: can't register local in hook.\n");
 		goto cleanup_localoutops;
 	}
-#endif
 	return ret;
 
  cleanup:
-#ifdef CONFIG_IP_NF_NAT_LOCAL
 	nf_unregister_hook(&ip_nat_local_in_ops);
  cleanup_localoutops:
 	nf_unregister_hook(&ip_nat_local_out_ops);
  cleanup_outops:
-#endif
 	nf_unregister_hook(&ip_nat_out_ops);
  cleanup_inops:
 	nf_unregister_hook(&ip_nat_in_ops);
@@ -383,12 +341,9 @@
 EXPORT_SYMBOL(ip_nat_setup_info);
 EXPORT_SYMBOL(ip_nat_protocol_register);
 EXPORT_SYMBOL(ip_nat_protocol_unregister);
-EXPORT_SYMBOL(ip_nat_helper_register);
-EXPORT_SYMBOL(ip_nat_helper_unregister);
 EXPORT_SYMBOL(ip_nat_cheat_check);
 EXPORT_SYMBOL(ip_nat_mangle_tcp_packet);
 EXPORT_SYMBOL(ip_nat_mangle_udp_packet);
 EXPORT_SYMBOL(ip_nat_used_tuple);
-EXPORT_SYMBOL(ip_nat_find_helper);
-EXPORT_SYMBOL(__ip_nat_find_helper);
+EXPORT_SYMBOL(ip_nat_follow_master);
 MODULE_LICENSE("GPL");
diff -Nru a/net/ipv4/netfilter/ip_nat_tftp.c b/net/ipv4/netfilter/ip_nat_tftp.c
--- a/net/ipv4/netfilter/ip_nat_tftp.c	2005-03-01 23:38:54 -08:00
+++ b/net/ipv4/netfilter/ip_nat_tftp.c	2005-03-01 23:38:54 -08:00
@@ -38,170 +38,32 @@
 MODULE_DESCRIPTION("tftp NAT helper");
 MODULE_LICENSE("GPL");
 
-#define MAX_PORTS 8
-
-static int ports[MAX_PORTS];
-static int ports_c = 0;
-module_param_array(ports, int, &ports_c, 0400);
-MODULE_PARM_DESC(ports, "port numbers of tftp servers");
-
-#if 0
-#define DEBUGP(format, args...) printk("%s:%s:" format, \
-                                       __FILE__, __FUNCTION__ , ## args)
-#else
-#define DEBUGP(format, args...)
-#endif
-static unsigned int 
-tftp_nat_help(struct ip_conntrack *ct,
-	      struct ip_conntrack_expect *exp,
-	      struct ip_nat_info *info,
-	      enum ip_conntrack_info ctinfo,
-	      unsigned int hooknum,
-	      struct sk_buff **pskb)
+static unsigned int help(struct sk_buff **pskb,
+			 enum ip_conntrack_info ctinfo,
+			 struct ip_conntrack_expect *exp)
 {
-	int dir = CTINFO2DIR(ctinfo);
-	struct tftphdr _tftph, *tfh;
-	struct ip_conntrack_tuple repl;
-
-	if (!((hooknum == NF_IP_POST_ROUTING && dir == IP_CT_DIR_ORIGINAL)
-	      || (hooknum == NF_IP_PRE_ROUTING && dir == IP_CT_DIR_REPLY))) 
-		return NF_ACCEPT;
-
-	if (!exp) {
-		DEBUGP("no conntrack expectation to modify\n");
-		return NF_ACCEPT;
-	}
-
-	tfh = skb_header_pointer(*pskb,
-				 (*pskb)->nh.iph->ihl*4+sizeof(struct udphdr),
-				 sizeof(_tftph), &_tftph);
-	if (tfh == NULL)
+	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);
 		return NF_DROP;
-
-	switch (ntohs(tfh->opcode)) {
-	/* RRQ and WRQ works the same way */
-	case TFTP_OPCODE_READ:
-	case TFTP_OPCODE_WRITE:
-		repl = ct->tuplehash[IP_CT_DIR_REPLY].tuple;
-		DEBUGP("");
-		DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
-		DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_REPLY].tuple);
-		DEBUGP("expecting: ");
-		DUMP_TUPLE(&repl);
-		DUMP_TUPLE(&exp->mask);
-		ip_conntrack_change_expect(exp, &repl);
-		break;
-	default:
-		DEBUGP("Unknown opcode\n");
-	}               
-
-	return NF_ACCEPT;
-}
-
-static unsigned int 
-tftp_nat_expected(struct sk_buff **pskb,
-		  unsigned int hooknum,
-		  struct ip_conntrack *ct, 
-		  struct ip_nat_info *info) 
-{
-	const struct ip_conntrack *master = ct->master->expectant;
-	const struct ip_conntrack_tuple *orig = 
-			&master->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
-	struct ip_nat_multi_range mr;
-#if 0
-	const struct ip_conntrack_tuple *repl =
-			&master->tuplehash[IP_CT_DIR_REPLY].tuple;
-	struct udphdr _udph, *uh;
-
-	uh = skb_header_pointer(*pskb,
-				(*pskb)->nh.iph->ihl*4,
-				sizeof(_udph), &_udph);
-	if (uh == NULL)
-		return NF_DROP;
-#endif
-
-	IP_NF_ASSERT(info);
-	IP_NF_ASSERT(master);
-	IP_NF_ASSERT(!(info->initialized & (1 << HOOK2MANIP(hooknum))));
-
-	mr.rangesize = 1;
-	mr.range[0].flags = IP_NAT_RANGE_MAP_IPS;
-
-	if (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC) {
-		mr.range[0].min_ip = mr.range[0].max_ip = orig->dst.ip; 
-		DEBUGP("orig: %u.%u.%u.%u:%u <-> %u.%u.%u.%u:%u "
-			"newsrc: %u.%u.%u.%u\n",
-                        NIPQUAD((*pskb)->nh.iph->saddr), ntohs(uh->source),
- 			NIPQUAD((*pskb)->nh.iph->daddr), ntohs(uh->dest),
-			NIPQUAD(orig->dst.ip));
-	} else {
-		mr.range[0].min_ip = mr.range[0].max_ip = orig->src.ip;
-		mr.range[0].min.udp.port = mr.range[0].max.udp.port = 
-							orig->src.u.udp.port;
-		mr.range[0].flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
-
-		DEBUGP("orig: %u.%u.%u.%u:%u <-> %u.%u.%u.%u:%u "
-			"newdst: %u.%u.%u.%u:%u\n",
-                        NIPQUAD((*pskb)->nh.iph->saddr), ntohs(uh->source),
-                        NIPQUAD((*pskb)->nh.iph->daddr), ntohs(uh->dest),
-                        NIPQUAD(orig->src.ip), ntohs(orig->src.u.udp.port));
 	}
-
-	return ip_nat_setup_info(ct,&mr,hooknum);
+	return NF_ACCEPT;
 }
 
-static struct ip_nat_helper tftp[MAX_PORTS];
-static char tftp_names[MAX_PORTS][10];
-
-static void fini(void)
+static void __exit fini(void)
 {
-	int i;
-
-	for (i = 0 ; i < ports_c; i++) {
-		DEBUGP("unregistering helper for port %d\n", ports[i]);
-		ip_nat_helper_unregister(&tftp[i]);
-	}
+	ip_nat_tftp_hook = NULL;
+	/* Make sure noone calls it, meanwhile. */
+	synchronize_net();
 }
 
 static int __init init(void)
 {
-	int i, ret = 0;
-	char *tmpname;
-
-	if (ports_c == 0)
-		ports[ports_c++] = TFTP_PORT;
-
-	for (i = 0; i < ports_c; i++) {
-		memset(&tftp[i], 0, sizeof(struct ip_nat_helper));
-
-		tftp[i].tuple.dst.protonum = IPPROTO_UDP;
-		tftp[i].tuple.src.u.udp.port = htons(ports[i]);
-		tftp[i].mask.dst.protonum = 0xFFFF;
-		tftp[i].mask.src.u.udp.port = 0xFFFF;
-		tftp[i].help = tftp_nat_help;
-		tftp[i].flags = 0;
-		tftp[i].me = THIS_MODULE;
-		tftp[i].expect = tftp_nat_expected;
-
-		tmpname = &tftp_names[i][0];
-		if (ports[i] == TFTP_PORT)
-			sprintf(tmpname, "tftp");
-		else
-			sprintf(tmpname, "tftp-%d", i);
-		tftp[i].name = tmpname;
-		
-		DEBUGP("ip_nat_tftp: registering for port %d: name %s\n",
-			ports[i], tftp[i].name);
-		ret = ip_nat_helper_register(&tftp[i]);
-
-		if (ret) {
-			printk("ip_nat_tftp: unable to register for port %d\n",
-				ports[i]);
-			fini();
-			return ret;
-		}
-	}
-	return ret;
+	BUG_ON(ip_nat_tftp_hook);
+	ip_nat_tftp_hook = help;
+	return 0;
 }
 
 module_init(init);
diff -Nru a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c
--- a/net/ipv4/netfilter/ip_queue.c	2005-03-01 23:39:18 -08:00
+++ b/net/ipv4/netfilter/ip_queue.c	2005-03-01 23:39:18 -08:00
@@ -55,7 +55,7 @@
 
 static unsigned char copy_mode = IPQ_COPY_NONE;
 static unsigned int queue_maxlen = IPQ_QMAX_DEFAULT;
-static rwlock_t queue_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(queue_lock);
 static int peer_pid;
 static unsigned int copy_range;
 static unsigned int queue_total;
diff -Nru a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
--- a/net/ipv4/netfilter/ip_tables.c	2005-03-01 23:38:54 -08:00
+++ b/net/ipv4/netfilter/ip_tables.c	2005-03-01 23:38:54 -08:00
@@ -26,6 +26,7 @@
 #include <asm/uaccess.h>
 #include <asm/semaphore.h>
 #include <linux/proc_fs.h>
+#include <linux/err.h>
 
 #include <linux/netfilter_ipv4/ip_tables.h>
 
@@ -408,87 +409,145 @@
 #endif
 }
 
-/* If it succeeds, returns element and locks mutex */
-static inline void *
-find_inlist_lock_noload(struct list_head *head,
-			const char *name,
-			int *error,
-			struct semaphore *mutex)
-{
-	void *ret;
-
-#if 0 
-	duprintf("find_inlist: searching for `%s' in %s.\n",
-		 name, head == &ipt_target ? "ipt_target"
-		 : head == &ipt_match ? "ipt_match"
-		 : head == &ipt_tables ? "ipt_tables" : "UNKNOWN");
-#endif
+/*
+ * These are weird, but module loading must not be done with mutex
+ * held (since they will register), and we have to have a single
+ * function to use try_then_request_module().
+ */
 
-	*error = down_interruptible(mutex);
-	if (*error != 0)
-		return NULL;
+/* Find table by name, grabs mutex & ref.  Returns ERR_PTR() on error. */
+static inline struct ipt_table *find_table_lock(const char *name)
+{
+	struct ipt_table *t;
 
-	ret = list_named_find(head, name);
-	if (!ret) {
-		*error = -ENOENT;
-		up(mutex);
-	}
-	return ret;
+	if (down_interruptible(&ipt_mutex) != 0)
+		return ERR_PTR(-EINTR);
+
+	list_for_each_entry(t, &ipt_tables, list)
+		if (strcmp(t->name, name) == 0 && try_module_get(t->me))
+			return t;
+	up(&ipt_mutex);
+	return NULL;
 }
 
-#ifndef CONFIG_KMOD
-#define find_inlist_lock(h,n,p,e,m) find_inlist_lock_noload((h),(n),(e),(m))
-#else
-static void *
-find_inlist_lock(struct list_head *head,
-		 const char *name,
-		 const char *prefix,
-		 int *error,
-		 struct semaphore *mutex)
-{
-	void *ret;
-
-	ret = find_inlist_lock_noload(head, name, error, mutex);
-	if (!ret) {
-		duprintf("find_inlist: loading `%s%s'.\n", prefix, name);
-		request_module("%s%s", prefix, name);
-		ret = find_inlist_lock_noload(head, name, error, mutex);
-	}
+/* Find match, grabs ref.  Returns ERR_PTR() on error. */
+static inline struct ipt_match *find_match(const char *name, u8 revision)
+{
+	struct ipt_match *m;
+	int err = 0;
 
-	return ret;
+	if (down_interruptible(&ipt_mutex) != 0)
+		return ERR_PTR(-EINTR);
+
+	list_for_each_entry(m, &ipt_match, list) {
+		if (strcmp(m->name, name) == 0) {
+			if (m->revision == revision) {
+				if (try_module_get(m->me)) {
+					up(&ipt_mutex);
+					return m;
+				}
+			} else
+				err = -EPROTOTYPE; /* Found something. */
+		}
+	}
+	up(&ipt_mutex);
+	return ERR_PTR(err);
 }
-#endif
 
-static inline struct ipt_table *
-ipt_find_table_lock(const char *name, int *error, struct semaphore *mutex)
+/* Find target, grabs ref.  Returns ERR_PTR() on error. */
+static inline struct ipt_target *find_target(const char *name, u8 revision)
 {
-	return find_inlist_lock(&ipt_tables, name, "iptable_", error, mutex);
+	struct ipt_target *t;
+	int err = 0;
+
+	if (down_interruptible(&ipt_mutex) != 0)
+		return ERR_PTR(-EINTR);
+
+	list_for_each_entry(t, &ipt_target, list) {
+		if (strcmp(t->name, name) == 0) {
+			if (t->revision == revision) {
+				if (try_module_get(t->me)) {
+					up(&ipt_mutex);
+					return t;
+				}
+			} else
+				err = -EPROTOTYPE; /* Found something. */
+		}
+	}
+	up(&ipt_mutex);
+	return ERR_PTR(err);
 }
 
-static inline struct ipt_match *
-find_match_lock(const char *name, int *error, struct semaphore *mutex)
+struct ipt_target *ipt_find_target(const char *name, u8 revision)
 {
-	return find_inlist_lock(&ipt_match, name, "ipt_", error, mutex);
+	struct ipt_target *target;
+
+	target = try_then_request_module(find_target(name, revision),
+					 "ipt_%s", name);
+	if (IS_ERR(target) || !target)
+		return NULL;
+	return target;
 }
 
-static struct ipt_target *
-ipt_find_target_lock(const char *name, int *error, struct semaphore *mutex)
+static int match_revfn(const char *name, u8 revision, int *bestp)
 {
-	return find_inlist_lock(&ipt_target, name, "ipt_", error, mutex);
+	struct ipt_match *m;
+	int have_rev = 0;
+
+	list_for_each_entry(m, &ipt_match, list) {
+		if (strcmp(m->name, name) == 0) {
+			if (m->revision > *bestp)
+				*bestp = m->revision;
+			if (m->revision == revision)
+				have_rev = 1;
+		}
+	}
+	return have_rev;
 }
 
-struct ipt_target *
-__ipt_find_target_lock(const char *name, int *error)
+static int target_revfn(const char *name, u8 revision, int *bestp)
 {
-	return ipt_find_target_lock(name,error,&ipt_mutex);
+	struct ipt_target *t;
+	int have_rev = 0;
+
+	list_for_each_entry(t, &ipt_target, list) {
+		if (strcmp(t->name, name) == 0) {
+			if (t->revision > *bestp)
+				*bestp = t->revision;
+			if (t->revision == revision)
+				have_rev = 1;
+		}
+	}
+	return have_rev;
 }
 
-void
-__ipt_mutex_up(void)
+/* Returns true or false (if no such extension at all) */
+static inline int find_revision(const char *name, u8 revision,
+				int (*revfn)(const char *, u8, int *),
+				int *err)
 {
+	int have_rev, best = -1;
+
+	if (down_interruptible(&ipt_mutex) != 0) {
+		*err = -EINTR;
+		return 1;
+	}
+	have_rev = revfn(name, revision, &best);
 	up(&ipt_mutex);
+
+	/* Nothing at all?  Return 0 to try loading module. */
+	if (best == -1) {
+		*err = -ENOENT;
+		return 0;
+	}
+
+	*err = best;
+	if (!have_rev)
+		*err = -EPROTONOSUPPORT;
+	return 1;
 }
 
+
 /* All zeroes == unconditional rule. */
 static inline int
 unconditional(const struct ipt_ip *ip)
@@ -648,20 +707,16 @@
 	    unsigned int hookmask,
 	    unsigned int *i)
 {
-	int ret;
 	struct ipt_match *match;
 
-	match = find_match_lock(m->u.user.name, &ret, &ipt_mutex);
-	if (!match) {
+	match = try_then_request_module(find_match(m->u.user.name,
+						   m->u.user.revision),
+					"ipt_%s", m->u.user.name);
+	if (IS_ERR(match) || !match) {
 		duprintf("check_match: `%s' not found\n", m->u.user.name);
-		return ret;
-	}
-	if (!try_module_get(match->me)) {
-		up(&ipt_mutex);
-		return -ENOENT;
+		return match ? PTR_ERR(match) : -ENOENT;
 	}
 	m->u.kernel.match = match;
-	up(&ipt_mutex);
 
 	if (m->u.kernel.match->checkentry
 	    && !m->u.kernel.match->checkentry(name, ip, m->data,
@@ -699,18 +754,15 @@
 		goto cleanup_matches;
 
 	t = ipt_get_target(e);
-	target = ipt_find_target_lock(t->u.user.name, &ret, &ipt_mutex);
-	if (!target) {
+	target = try_then_request_module(find_target(t->u.user.name,
+						     t->u.user.revision),
+					 "ipt_%s", t->u.user.name);
+	if (IS_ERR(target) || !target) {
 		duprintf("check_entry: `%s' not found\n", t->u.user.name);
-		goto cleanup_matches;
-	}
-	if (!try_module_get(target->me)) {
-		up(&ipt_mutex);
-		ret = -ENOENT;
+		ret = target ? PTR_ERR(target) : -ENOENT;
 		goto cleanup_matches;
 	}
 	t->u.kernel.target = target;
-	up(&ipt_mutex);
 
 	if (t->u.kernel.target == &ipt_standard_target) {
 		if (!standard_check(t, size)) {
@@ -1036,8 +1088,8 @@
 	int ret;
 	struct ipt_table *t;
 
-	t = ipt_find_table_lock(entries->name, &ret, &ipt_mutex);
-	if (t) {
+	t = find_table_lock(entries->name);
+	if (t && !IS_ERR(t)) {
 		duprintf("t->private->number = %u\n",
 			 t->private->number);
 		if (entries->size == t->private->size)
@@ -1049,10 +1101,10 @@
 				 entries->size);
 			ret = -EINVAL;
 		}
+		module_put(t->me);
 		up(&ipt_mutex);
 	} else
-		duprintf("get_entries: Can't find %s!\n",
-			 entries->name);
+		ret = t ? PTR_ERR(t) : -ENOENT;
 
 	return ret;
 }
@@ -1103,25 +1155,21 @@
 
 	duprintf("ip_tables: Translated table\n");
 
-	t = ipt_find_table_lock(tmp.name, &ret, &ipt_mutex);
-	if (!t)
+	t = try_then_request_module(find_table_lock(tmp.name),
+				    "iptable_%s", tmp.name);
+	if (!t || IS_ERR(t)) {
+		ret = t ? PTR_ERR(t) : -ENOENT;
 		goto free_newinfo_counters_untrans;
+	}
 
 	/* You lied! */
 	if (tmp.valid_hooks != t->valid_hooks) {
 		duprintf("Valid hook crap: %08X vs %08X\n",
 			 tmp.valid_hooks, t->valid_hooks);
 		ret = -EINVAL;
-		goto free_newinfo_counters_untrans_unlock;
-	}
-
-	/* Get a reference in advance, we're not allowed fail later */
-	if (!try_module_get(t->me)) {
-		ret = -EBUSY;
-		goto free_newinfo_counters_untrans_unlock;
+		goto put_module;
 	}
 
-
 	oldinfo = replace_table(t, tmp.num_counters, newinfo, &ret);
 	if (!oldinfo)
 		goto put_module;
@@ -1141,16 +1189,15 @@
 	/* Decrease module usage counts and free resource */
 	IPT_ENTRY_ITERATE(oldinfo->entries, oldinfo->size, cleanup_entry,NULL);
 	vfree(oldinfo);
-	/* Silent error: too late now. */
-	copy_to_user(tmp.counters, counters,
-		     sizeof(struct ipt_counters) * tmp.num_counters);
+	if (copy_to_user(tmp.counters, counters,
+			 sizeof(struct ipt_counters) * tmp.num_counters) != 0)
+		ret = -EFAULT;
 	vfree(counters);
 	up(&ipt_mutex);
-	return 0;
+	return ret;
 
  put_module:
 	module_put(t->me);
- free_newinfo_counters_untrans_unlock:
 	up(&ipt_mutex);
  free_newinfo_counters_untrans:
 	IPT_ENTRY_ITERATE(newinfo->entries, newinfo->size, cleanup_entry,NULL);
@@ -1189,7 +1236,7 @@
 	unsigned int i;
 	struct ipt_counters_info tmp, *paddc;
 	struct ipt_table *t;
-	int ret;
+	int ret = 0;
 
 	if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
 		return -EFAULT;
@@ -1206,9 +1253,11 @@
 		goto free;
 	}
 
-	t = ipt_find_table_lock(tmp.name, &ret, &ipt_mutex);
-	if (!t)
+	t = find_table_lock(tmp.name);
+	if (!t || IS_ERR(t)) {
+		ret = t ? PTR_ERR(t) : -ENOENT;
 		goto free;
+	}
 
 	write_lock_bh(&t->lock);
 	if (t->private->number != paddc->num_counters) {
@@ -1225,6 +1274,7 @@
  unlock_up_free:
 	write_unlock_bh(&t->lock);
 	up(&ipt_mutex);
+	module_put(t->me);
  free:
 	vfree(paddc);
 
@@ -1281,8 +1331,10 @@
 			break;
 		}
 		name[IPT_TABLE_MAXNAMELEN-1] = '\0';
-		t = ipt_find_table_lock(name, &ret, &ipt_mutex);
-		if (t) {
+
+		t = try_then_request_module(find_table_lock(name),
+					    "iptable_%s", name);
+		if (t && !IS_ERR(t)) {
 			struct ipt_getinfo info;
 
 			info.valid_hooks = t->valid_hooks;
@@ -1298,9 +1350,10 @@
 				ret = -EFAULT;
 			else
 				ret = 0;
-
 			up(&ipt_mutex);
-		}
+			module_put(t->me);
+		} else
+			ret = t ? PTR_ERR(t) : -ENOENT;
 	}
 	break;
 
@@ -1321,6 +1374,31 @@
 		break;
 	}
 
+	case IPT_SO_GET_REVISION_MATCH:
+	case IPT_SO_GET_REVISION_TARGET: {
+		struct ipt_get_revision rev;
+		int (*revfn)(const char *, u8, int *);
+
+		if (*len != sizeof(rev)) {
+			ret = -EINVAL;
+			break;
+		}
+		if (copy_from_user(&rev, user, sizeof(rev)) != 0) {
+			ret = -EFAULT;
+			break;
+		}
+
+		if (cmd == IPT_SO_GET_REVISION_TARGET)
+			revfn = target_revfn;
+		else
+			revfn = match_revfn;
+
+		try_then_request_module(find_revision(rev.name, rev.revision,
+						      revfn, &ret),
+					"ipt_%s", rev.name);
+		break;
+	}
+
 	default:
 		duprintf("do_ipt_get_ctl: unknown request %i\n", cmd);
 		ret = -EINVAL;
@@ -1338,12 +1416,7 @@
 	ret = down_interruptible(&ipt_mutex);
 	if (ret != 0)
 		return ret;
-
-	if (!list_named_insert(&ipt_target, target)) {
-		duprintf("ipt_register_target: `%s' already in list!\n",
-			 target->name);
-		ret = -EINVAL;
-	}
+	list_add(&target->list, &ipt_target);
 	up(&ipt_mutex);
 	return ret;
 }
@@ -1365,11 +1438,7 @@
 	if (ret != 0)
 		return ret;
 
-	if (!list_named_insert(&ipt_match, match)) {
-		duprintf("ipt_register_match: `%s' already in list!\n",
-			 match->name);
-		ret = -EINVAL;
-	}
+	list_add(&match->list, &ipt_match);
 	up(&ipt_mutex);
 
 	return ret;
@@ -1383,7 +1452,7 @@
 	up(&ipt_mutex);
 }
 
-int ipt_register_table(struct ipt_table *table)
+int ipt_register_table(struct ipt_table *table, const struct ipt_replace *repl)
 {
 	int ret;
 	struct ipt_table_info *newinfo;
@@ -1391,17 +1460,17 @@
 		= { 0, 0, 0, { 0 }, { 0 }, { } };
 
 	newinfo = vmalloc(sizeof(struct ipt_table_info)
-			  + SMP_ALIGN(table->table->size) * NR_CPUS);
+			  + SMP_ALIGN(repl->size) * NR_CPUS);
 	if (!newinfo)
 		return -ENOMEM;
 
-	memcpy(newinfo->entries, table->table->entries, table->table->size);
+	memcpy(newinfo->entries, repl->entries, repl->size);
 
 	ret = translate_table(table->name, table->valid_hooks,
-			      newinfo, table->table->size,
-			      table->table->num_entries,
-			      table->table->hook_entry,
-			      table->table->underflow);
+			      newinfo, repl->size,
+			      repl->num_entries,
+			      repl->hook_entry,
+			      repl->underflow);
 	if (ret != 0) {
 		vfree(newinfo);
 		return ret;
@@ -1889,8 +1958,7 @@
 EXPORT_SYMBOL(ipt_do_table);
 EXPORT_SYMBOL(ipt_register_target);
 EXPORT_SYMBOL(ipt_unregister_target);
-EXPORT_SYMBOL_GPL(__ipt_find_target_lock);
-EXPORT_SYMBOL_GPL(__ipt_mutex_up);
+EXPORT_SYMBOL(ipt_find_target);
 
 module_init(init);
 module_exit(fini);
diff -Nru a/net/ipv4/netfilter/ipchains_core.c b/net/ipv4/netfilter/ipchains_core.c
--- a/net/ipv4/netfilter/ipchains_core.c	2005-03-01 23:39:09 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,1854 +0,0 @@
-#warning ipchains is obsolete, and will be removed soon.
-
-/* Minor modifications to fit on compatibility framework:
-   Rusty.Russell@rustcorp.com.au
-*/
-
-/*
- * This code is heavily based on the code on the old ip_fw.c code; see below for
- * copyrights and attributions of the old code.  This code is basically GPL.
- *
- * 15-Aug-1997: Major changes to allow graphs for firewall rules.
- *              Paul Russell <Paul.Russell@rustcorp.com.au> and
- *		Michael Neuling <Michael.Neuling@rustcorp.com.au>
- * 24-Aug-1997: Generalised protocol handling (not just TCP/UDP/ICMP).
- *              Added explicit RETURN from chains.
- *              Removed TOS mangling (done in ipchains 1.0.1).
- *              Fixed read & reset bug by reworking proc handling.
- *              Paul Russell <Paul.Russell@rustcorp.com.au>
- * 28-Sep-1997: Added packet marking for net sched code.
- *              Removed fw_via comparisons: all done on device name now,
- *              similar to changes in ip_fw.c in DaveM's CVS970924 tree.
- *              Paul Russell <Paul.Russell@rustcorp.com.au>
- * 2-Nov-1997:  Moved types across to __u16, etc.
- *              Added inverse flags.
- *              Fixed fragment bug (in args to port_match).
- *              Changed mark to only one flag (MARKABS).
- * 21-Nov-1997: Added ability to test ICMP code.
- * 19-Jan-1998: Added wildcard interfaces.
- * 6-Feb-1998:  Merged 2.0 and 2.1 versions.
- *              Initialised ip_masq for 2.0.x version.
- *              Added explicit NETLINK option for 2.1.x version.
- *              Added packet and byte counters for policy matches.
- * 26-Feb-1998: Fixed race conditions, added SMP support.
- * 18-Mar-1998: Fix SMP, fix race condition fix.
- * 1-May-1998:  Remove caching of device pointer.
- * 12-May-1998: Allow tiny fragment case for TCP/UDP.
- * 15-May-1998: Treat short packets as fragments, don't just block.
- * 3-Jan-1999:  Fixed serious procfs security hole -- users should never
- *              be allowed to view the chains!
- *              Marc Santoro <ultima@snicker.emoti.com>
- * 29-Jan-1999: Locally generated bogus IPs dealt with, rather than crash
- *              during dump_packet. --RR.
- * 19-May-1999: Star Wars: The Phantom Menace opened.  Rule num
- *		printed in log (modified from Michael Hasenstein's patch).
- *		Added SYN in log message. --RR
- * 23-Jul-1999: Fixed small fragment security exposure opened on 15-May-1998.
- *              John McDonald <jm@dataprotect.com>
- *              Thomas Lopatic <tl@dataprotect.com>
- */
-
-/*
- *
- * The origina Linux port was done Alan Cox, with changes/fixes from
- * Pauline Middlelink, Jos Vos, Thomas Quinot, Wouter Gadeyne, Juan
- * Jose Ciarlante, Bernd Eckenfels, Keith Owens and others.
- *
- * Copyright from the original FreeBSD version follows:
- *
- * Copyright (c) 1993 Daniel Boulet
- * Copyright (c) 1994 Ugen J.S.Antsilevich
- *
- * Redistribution and use in source forms, with and without modification,
- * are permitted provided that this entire comment appears intact.
- *
- * Redistribution in binary form may occur without any restrictions.
- * Obviously, it would be nice if you gave credit where credit is due
- * but requiring it would be too onerous.
- *
- * This software is provided ``AS IS'' without any warranties of any kind.  */
-
-#include <linux/config.h>
-
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <linux/types.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/module.h>
-
-#include <linux/socket.h>
-#include <linux/sockios.h>
-#include <linux/in.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/icmp.h>
-#include <linux/udp.h>
-#include <net/ip.h>
-#include <net/protocol.h>
-#include <net/route.h>
-#include <net/tcp.h>
-#include <net/udp.h>
-#include <net/sock.h>
-#include <net/icmp.h>
-#include <linux/netlink.h>
-#include <linux/netfilter.h>
-#include <linux/netfilter_ipv4/compat_firewall.h>
-#include <linux/netfilter_ipv4/ipchains_core.h>
-#include <linux/netfilter_ipv4/ip_nat_core.h>
-
-#include <net/checksum.h>
-#include <linux/proc_fs.h>
-#include <linux/stat.h>
-
-MODULE_LICENSE("Dual BSD/GPL");
-MODULE_AUTHOR("Rusty Russell <rusty@rustcorp.com.au>");
-MODULE_DESCRIPTION("ipchains backwards compatibility layer");
-
-/* Understanding locking in this code: (thanks to Alan Cox for using
- * little words to explain this to me). -- PR
- *
- * In UP, there can be two packets traversing the chains:
- * 1) A packet from the current userspace context
- * 2) A packet off the bh handlers (timer or net).
- *
- * For SMP (kernel v2.1+), multiply this by # CPUs.
- *
- * [Note that this in not correct for 2.2 - because the socket code always
- *  uses lock_kernel() to serialize, and bottom halves (timers and net_bhs)
- *  only run on one CPU at a time.  This will probably change for 2.3.
- *  It is still good to use spinlocks because that avoids the global cli()
- *  for updating the tables, which is rather costly in SMP kernels -AK]
- *
- * This means counters and backchains can get corrupted if no precautions
- * are taken.
- *
- * To actually alter a chain on UP, we need only do a cli(), as this will
- * stop a bh handler firing, as we are in the current userspace context
- * (coming from a setsockopt()).
- *
- * On SMP, we need a write_lock_irqsave(), which is a simple cli() in
- * UP.
- *
- * For backchains and counters, we use an array, indexed by
- * [smp_processor_id()*2 + !in_interrupt()]; the array is of
- * size [NR_CPUS*2].  For v2.0, NR_CPUS is effectively 1.  So,
- * confident of uniqueness, we modify counters even though we only
- * have a read lock (to read the counters, you need a write lock,
- * though).  */
-
-/* Why I didn't use straight locking... -- PR
- *
- * The backchains can be separated out of the ip_chains structure, and
- * allocated as needed inside ip_fw_check().
- *
- * The counters, however, can't.  Trying to lock these means blocking
- * interrupts every time we want to access them.  This would suck HARD
- * performance-wise.  Not locking them leads to possible corruption,
- * made worse on 32-bit machines (counters are 64-bit).  */
-
-/*#define DEBUG_IP_FIREWALL*/
-/*#define DEBUG_ALLOW_ALL*/ /* Useful for remote debugging */
-/*#define DEBUG_IP_FIREWALL_USER*/
-/*#define DEBUG_IP_FIREWALL_LOCKING*/
-
-#if defined(CONFIG_NETLINK_DEV) || defined(CONFIG_NETLINK_DEV_MODULE)
-static struct sock *ipfwsk;
-#endif
-
-#ifdef CONFIG_SMP
-#define SLOT_NUMBER() (smp_processor_id()*2 + !in_interrupt())
-#else /* !SMP */
-#define SLOT_NUMBER() (!in_interrupt())
-#endif /* CONFIG_SMP */
-#define NUM_SLOTS (NR_CPUS*2)
-
-#define SIZEOF_STRUCT_IP_CHAIN (sizeof(struct ip_chain) \
-				+ NUM_SLOTS*sizeof(struct ip_reent))
-#define SIZEOF_STRUCT_IP_FW_KERNEL (sizeof(struct ip_fwkernel) \
-				    + NUM_SLOTS*sizeof(struct ip_counters))
-
-#ifdef DEBUG_IP_FIREWALL_LOCKING
-static unsigned int fwc_rlocks, fwc_wlocks;
-#define FWC_DEBUG_LOCK(d)			\
-do {						\
-	FWC_DONT_HAVE_LOCK(d);			\
-	d |= (1 << SLOT_NUMBER());		\
-} while (0)
-
-#define FWC_DEBUG_UNLOCK(d)			\
-do {						\
-	FWC_HAVE_LOCK(d);			\
-	d &= ~(1 << SLOT_NUMBER());		\
-} while (0)
-
-#define FWC_DONT_HAVE_LOCK(d)					\
-do {								\
-	if ((d) & (1 << SLOT_NUMBER()))				\
-		printk("%s:%i: Got lock on %i already!\n", 	\
-		       __FILE__, __LINE__, SLOT_NUMBER());	\
-} while(0)
-
-#define FWC_HAVE_LOCK(d)				\
-do {							\
-	if (!((d) & (1 << SLOT_NUMBER())))		\
-	printk("%s:%i:No lock on %i!\n", 		\
-	       __FILE__, __LINE__, SLOT_NUMBER());	\
-} while (0)
-
-#else
-#define FWC_DEBUG_LOCK(d) do { } while(0)
-#define FWC_DEBUG_UNLOCK(d) do { } while(0)
-#define FWC_DONT_HAVE_LOCK(d) do { } while(0)
-#define FWC_HAVE_LOCK(d) do { } while(0)
-#endif /*DEBUG_IP_FIRWALL_LOCKING*/
-
-#define FWC_READ_LOCK(l) do { FWC_DEBUG_LOCK(fwc_rlocks); read_lock(l); } while (0)
-#define FWC_WRITE_LOCK(l) do { FWC_DEBUG_LOCK(fwc_wlocks); write_lock(l); } while (0)
-#define FWC_READ_LOCK_IRQ(l,f) do { FWC_DEBUG_LOCK(fwc_rlocks); read_lock_irqsave(l,f); } while (0)
-#define FWC_WRITE_LOCK_IRQ(l,f) do { FWC_DEBUG_LOCK(fwc_wlocks); write_lock_irqsave(l,f); } while (0)
-#define FWC_READ_UNLOCK(l) do { FWC_DEBUG_UNLOCK(fwc_rlocks); read_unlock(l); } while (0)
-#define FWC_WRITE_UNLOCK(l) do { FWC_DEBUG_UNLOCK(fwc_wlocks); write_unlock(l); } while (0)
-#define FWC_READ_UNLOCK_IRQ(l,f) do { FWC_DEBUG_UNLOCK(fwc_rlocks); read_unlock_irqrestore(l,f); } while (0)
-#define FWC_WRITE_UNLOCK_IRQ(l,f) do { FWC_DEBUG_UNLOCK(fwc_wlocks); write_unlock_irqrestore(l,f); } while (0)
-
-struct ip_chain;
-
-struct ip_counters
-{
-	__u64 pcnt, bcnt;			/* Packet and byte counters */
-};
-
-struct ip_fwkernel
-{
-	struct ip_fw ipfw;
-	struct ip_fwkernel *next;	/* where to go next if current
-					 * rule doesn't match */
-	struct ip_chain *branch;	/* which branch to jump to if
-					 * current rule matches */
-	int simplebranch;		/* Use this if branch == NULL */
-	struct ip_counters counters[0]; /* Actually several of these */
-};
-
-struct ip_reent
-{
-	struct ip_chain *prevchain;	/* Pointer to referencing chain */
-	struct ip_fwkernel *prevrule;	/* Pointer to referencing rule */
-	struct ip_counters counters;
-};
-
-struct ip_chain
-{
-	ip_chainlabel label;	    /* Defines the label for each block */
- 	struct ip_chain *next;	    /* Pointer to next block */
-	struct ip_fwkernel *chain;  /* Pointer to first rule in block */
-	__u32 refcount; 	    /* Number of refernces to block */
-	int policy;		    /* Default rule for chain.  Only *
-				     * used in built in chains */
-	struct ip_reent reent[0];   /* Actually several of these */
-};
-
-/*
- *	Implement IP packet firewall
- */
-
-#ifdef DEBUG_IP_FIREWALL
-#define dprintf(format, args...)  printk(format , ## args)
-#else
-#define dprintf(format, args...)
-#endif
-
-#ifdef DEBUG_IP_FIREWALL_USER
-#define duprintf(format, args...) printk(format , ## args)
-#else
-#define duprintf(format, args...)
-#endif
-
-/* Lock around ip_fw_chains linked list structure */
-rwlock_t ip_fw_lock = RW_LOCK_UNLOCKED;
-
-/* Head of linked list of fw rules */
-static struct ip_chain *ip_fw_chains;
-
-#define IP_FW_INPUT_CHAIN ip_fw_chains
-#define IP_FW_FORWARD_CHAIN (ip_fw_chains->next)
-#define IP_FW_OUTPUT_CHAIN (ip_fw_chains->next->next)
-
-/* Returns 1 if the port is matched by the range, 0 otherwise */
-extern inline int port_match(__u16 min, __u16 max, __u16 port,
-			     int frag, int invert)
-{
-	if (frag) /* Fragments fail ANY port test. */
-		return (min == 0 && max == 0xFFFF);
-	else return (port >= min && port <= max) ^ invert;
-}
-
-/* Returns whether matches rule or not. */
-static int ip_rule_match(struct ip_fwkernel *f,
-			 const char *ifname,
-			 struct sk_buff **pskb,
-			 char tcpsyn,
-			 __u16 src_port, __u16 dst_port,
-			 char isfrag)
-{
-	struct iphdr *ip = (*pskb)->nh.iph;
-
-#define FWINV(bool,invflg) ((bool) ^ !!(f->ipfw.fw_invflg & invflg))
-	/*
-	 *	This is a bit simpler as we don't have to walk
-	 *	an interface chain as you do in BSD - same logic
-	 *	however.
-	 */
-
-	if (FWINV((ip->saddr&f->ipfw.fw_smsk.s_addr) != f->ipfw.fw_src.s_addr,
-		  IP_FW_INV_SRCIP)
-	    || FWINV((ip->daddr&f->ipfw.fw_dmsk.s_addr)!=f->ipfw.fw_dst.s_addr,
-		     IP_FW_INV_DSTIP)) {
-		dprintf("Source or dest mismatch.\n");
-
-		dprintf("SRC: %u. Mask: %u. Target: %u.%s\n", ip->saddr,
-			f->ipfw.fw_smsk.s_addr, f->ipfw.fw_src.s_addr,
-			f->ipfw.fw_invflg & IP_FW_INV_SRCIP ? " (INV)" : "");
-		dprintf("DST: %u. Mask: %u. Target: %u.%s\n", ip->daddr,
-			f->ipfw.fw_dmsk.s_addr, f->ipfw.fw_dst.s_addr,
-			f->ipfw.fw_invflg & IP_FW_INV_DSTIP ? " (INV)" : "");
-		return 0;
-	}
-
-	/*
-	 *	Look for a VIA device match
-	 */
-	if (f->ipfw.fw_flg & IP_FW_F_WILDIF) {
-	    if (FWINV(strncmp(ifname, f->ipfw.fw_vianame,
-			      strlen(f->ipfw.fw_vianame)) != 0,
-		      IP_FW_INV_VIA)) {
-		dprintf("Wildcard interface mismatch.%s\n",
-			f->ipfw.fw_invflg & IP_FW_INV_VIA ? " (INV)" : "");
-		return 0;	/* Mismatch */
-	    }
-	}
-	else if (FWINV(strcmp(ifname, f->ipfw.fw_vianame) != 0,
-		       IP_FW_INV_VIA)) {
-	    dprintf("Interface name does not match.%s\n",
-		    f->ipfw.fw_invflg & IP_FW_INV_VIA
-		    ? " (INV)" : "");
-	    return 0;	/* Mismatch */
-	}
-
-	/*
-	 *	Ok the chain addresses match.
-	 */
-
-	/* If we have a fragment rule but the packet is not a fragment
-	 * the we return zero */
-	if (FWINV((f->ipfw.fw_flg&IP_FW_F_FRAG) && !isfrag, IP_FW_INV_FRAG)) {
-		dprintf("Fragment rule but not fragment.%s\n",
-			f->ipfw.fw_invflg & IP_FW_INV_FRAG ? " (INV)" : "");
-		return 0;
-	}
-
-	/* Fragment NEVER passes a SYN test, even an inverted one. */
-	if (FWINV((f->ipfw.fw_flg&IP_FW_F_TCPSYN) && !tcpsyn, IP_FW_INV_SYN)
-	    || (isfrag && (f->ipfw.fw_flg&IP_FW_F_TCPSYN))) {
-		dprintf("Rule requires SYN and packet has no SYN.%s\n",
-			f->ipfw.fw_invflg & IP_FW_INV_SYN ? " (INV)" : "");
-		return 0;
-	}
-
-	if (f->ipfw.fw_proto) {
-		/*
-		 *	Specific firewall - packet's protocol
-		 *	must match firewall's.
-		 */
-
-		if (FWINV(ip->protocol!=f->ipfw.fw_proto, IP_FW_INV_PROTO)) {
-			dprintf("Packet protocol %hi does not match %hi.%s\n",
-				ip->protocol, f->ipfw.fw_proto,
-				f->ipfw.fw_invflg&IP_FW_INV_PROTO ? " (INV)":"");
-			return 0;
-		}
-
-		/* For non TCP/UDP/ICMP, port range is max anyway. */
-		if (!port_match(f->ipfw.fw_spts[0],
-				f->ipfw.fw_spts[1],
-				src_port, isfrag,
-				!!(f->ipfw.fw_invflg&IP_FW_INV_SRCPT))
-		    || !port_match(f->ipfw.fw_dpts[0],
-				   f->ipfw.fw_dpts[1],
-				   dst_port, isfrag,
-				   !!(f->ipfw.fw_invflg
-				      &IP_FW_INV_DSTPT))) {
-		    dprintf("Port match failed.\n");
-		    return 0;
-		}
-	}
-
-	dprintf("Match succeeded.\n");
-	return 1;
-}
-
-static const char *branchname(struct ip_chain *branch,int simplebranch)
-{
-	if (branch)
-		return branch->label;
-	switch (simplebranch)
-	{
-	case FW_BLOCK: return IP_FW_LABEL_BLOCK;
-	case FW_ACCEPT: return IP_FW_LABEL_ACCEPT;
-	case FW_REJECT: return IP_FW_LABEL_REJECT;
-	case FW_REDIRECT: return IP_FW_LABEL_REDIRECT;
-	case FW_MASQUERADE: return IP_FW_LABEL_MASQUERADE;
-	case FW_SKIP: return "-";
-	case FW_SKIP+1: return IP_FW_LABEL_RETURN;
-	default:
-		return "UNKNOWN";
-	}
-}
-
-/*
- * VERY ugly piece of code which actually
- * makes kernel printf for matching packets...
- */
-static void dump_packet(struct sk_buff **pskb,
-			const char *ifname,
-			struct ip_fwkernel *f,
-			const ip_chainlabel chainlabel,
-			__u16 src_port,
-			__u16 dst_port,
-			unsigned int count,
-			int syn)
-{
-	__u32 *opt = (__u32 *) ((*pskb)->nh.iph + 1);
-	int opti;
-
-	if (f) {
-		printk(KERN_INFO "Packet log: %s ",chainlabel);
-		printk("%s ",branchname(f->branch,f->simplebranch));
-		if (f->simplebranch==FW_REDIRECT)
-			printk("%d ",f->ipfw.fw_redirpt);
-	}
-
-	printk("%s 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",
-	       ifname, (*pskb)->nh.iph->protocol,
-	       NIPQUAD((*pskb)->nh.iph->saddr),
-	       src_port,
-	       NIPQUAD((*pskb)->nh.iph->daddr),
-	       dst_port,
-	       ntohs((*pskb)->nh.iph->tot_len),
-	       (*pskb)->nh.iph->tos,
-	       ntohs((*pskb)->nh.iph->id),
-	       ntohs((*pskb)->nh.iph->frag_off),
-	       (*pskb)->nh.iph->ttl);
-
-	for (opti = 0; opti < ((*pskb)->nh.iph->ihl - sizeof(struct iphdr) / 4); opti++)
-		printk(" O=0x%8.8X", *opt++);
-	printk(" %s(#%d)\n", syn ? "SYN " : /* "PENANCE" */ "", count);
-}
-
-/* function for checking chain labels for user space. */
-static int check_label(ip_chainlabel label)
-{
-	unsigned int i;
-	/* strlen must be < IP_FW_MAX_LABEL_LENGTH. */
-	for (i = 0; i < IP_FW_MAX_LABEL_LENGTH + 1; i++)
-		if (label[i] == '\0') return 1;
-
-	return 0;
-}
-
-/*	This function returns a pointer to the first chain with a label
- *	that matches the one given. */
-static struct ip_chain *find_label(ip_chainlabel label)
-{
-	struct ip_chain *tmp;
-	FWC_HAVE_LOCK(fwc_rlocks | fwc_wlocks);
-	for (tmp = ip_fw_chains; tmp; tmp = tmp->next)
-		if (strcmp(tmp->label,label) == 0)
-			break;
-	return tmp;
-}
-
-/* This function returns a boolean which when true sets answer to one
-   of the FW_*. */
-static int find_special(ip_chainlabel label, int *answer)
-{
-	if (label[0] == '\0') {
-		*answer = FW_SKIP; /* => pass-through rule */
-		return 1;
-	} else if (strcmp(label,IP_FW_LABEL_ACCEPT) == 0) {
-		*answer = FW_ACCEPT;
-		return 1;
-	} else if (strcmp(label,IP_FW_LABEL_BLOCK) == 0) {
-		*answer = FW_BLOCK;
-		return 1;
-	} else if (strcmp(label,IP_FW_LABEL_REJECT) == 0) {
-		*answer = FW_REJECT;
-		return 1;
-	} else if (strcmp(label,IP_FW_LABEL_REDIRECT) == 0) {
-		*answer = FW_REDIRECT;
-		return 1;
-	} else if (strcmp(label,IP_FW_LABEL_MASQUERADE) == 0) {
-		*answer = FW_MASQUERADE;
-		return 1;
-	} else if (strcmp(label, IP_FW_LABEL_RETURN) == 0) {
-		*answer = FW_SKIP+1;
-		return 1;
-	} else {
-		return 0;
-	}
-}
-
-/* This function cleans up the prevchain and prevrule.  If the verbose
- * flag is set then he names of the chains will be printed as it
- * cleans up.  */
-static void cleanup(struct ip_chain *chain,
-		    const int verbose,
-		    unsigned int slot)
-{
-	struct ip_chain *tmpchain = chain->reent[slot].prevchain;
-	if (verbose)
-		printk(KERN_ERR "Chain backtrace: ");
-	while (tmpchain) {
-		if (verbose)
-			printk("%s<-",chain->label);
-		chain->reent[slot].prevchain = NULL;
-		chain = tmpchain;
-		tmpchain = chain->reent[slot].prevchain;
-	}
-	if (verbose)
-		printk("%s\n",chain->label);
-}
-
-static inline int
-ip_fw_domatch(struct ip_fwkernel *f,
-	      const char *rif,
-	      const ip_chainlabel label,
-	      struct sk_buff **pskb,
-	      unsigned int slot,
-	      __u16 src_port, __u16 dst_port,
-	      unsigned int count,
-	      int tcpsyn,
-	      unsigned char *tos)
-{
-	f->counters[slot].bcnt+=ntohs((*pskb)->nh.iph->tot_len);
-	f->counters[slot].pcnt++;
-	if (f->ipfw.fw_flg & IP_FW_F_PRN) {
-		dump_packet(pskb,rif,f,label,src_port,dst_port,count,tcpsyn);
-	}
-
-	*tos = (*tos & f->ipfw.fw_tosand) ^ f->ipfw.fw_tosxor;
-
-/* This functionality is useless in stock 2.0.x series, but we don't
- * discard the mark thing altogether, to avoid breaking ipchains (and,
- * more importantly, the ipfwadm wrapper) --PR */
-	if (f->ipfw.fw_flg & IP_FW_F_MARKABS) {
-		(*pskb)->nfmark = f->ipfw.fw_mark;
-	} else {
-		(*pskb)->nfmark += f->ipfw.fw_mark;
-	}
-	if (f->ipfw.fw_flg & IP_FW_F_NETLINK) {
-#if defined(CONFIG_NETLINK_DEV) || defined(CONFIG_NETLINK_DEV_MODULE)
-		size_t len = min_t(unsigned int, f->ipfw.fw_outputsize, ntohs((*pskb)->nh.iph->tot_len))
-			+ sizeof(__u32) + sizeof((*pskb)->nfmark) + IFNAMSIZ;
-		struct sk_buff *outskb=alloc_skb(len, GFP_ATOMIC);
-
-		duprintf("Sending packet out NETLINK (length = %u).\n",
-			 (unsigned int)len);
-		if (outskb) {
-			/* Prepend length, mark & interface */
-			skb_put(outskb, len);
-			*((__u32 *)outskb->data) = (__u32)len;
-			*((__u32 *)(outskb->data+sizeof(__u32))) =
-				(*pskb)->nfmark;
-			strcpy(outskb->data+sizeof(__u32)*2, rif);
-			skb_copy_bits(*pskb,
-				((char *)(*pskb)->nh.iph - (char *)(*pskb)->data),
-				outskb->data+sizeof(__u32)*2+IFNAMSIZ,
-				len-(sizeof(__u32)*2+IFNAMSIZ));
-			netlink_broadcast(ipfwsk, outskb, 0, ~0, GFP_ATOMIC);
-		}
-		else {
-#endif
-			if (net_ratelimit())
-				printk(KERN_WARNING "ip_fw: packet drop due to "
-				       "netlink failure\n");
-			return 0;
-#if defined(CONFIG_NETLINK_DEV) || defined(CONFIG_NETLINK_DEV_MODULE)
-		}
-#endif
-	}
-	return 1;
-}
-
-/*
- *	Returns one of the generic firewall policies, like FW_ACCEPT.
- *
- *	The testing is either false for normal firewall mode or true for
- *	user checking mode (counters are not updated, TOS & mark not done).
- */
-static int
-ip_fw_check(const char *rif,
-	    __u16 *redirport,
-	    struct ip_chain *chain,
-	    struct sk_buff **pskb,
-	    unsigned int slot,
-	    int testing)
-{
-	__u32			src, dst;
-	__u16			src_port = 0xFFFF, dst_port = 0xFFFF;
-	char			tcpsyn=0;
-	__u16			offset;
-	unsigned char		tos;
-	struct ip_fwkernel	*f;
-	int			ret = FW_SKIP+2;
-	unsigned int		count;
-
-	/* We handle fragments by dealing with the first fragment as
-	 * if it was a normal packet.  All other fragments are treated
-	 * normally, except that they will NEVER match rules that ask
-	 * things we don't know, ie. tcp syn flag or ports).  If the
-	 * rule is also a fragment-specific rule, non-fragments won't
-	 * match it. */
-
-	offset = ntohs((*pskb)->nh.iph->frag_off) & IP_OFFSET;
-
-	/*
-	 *	Don't allow a fragment of TCP 8 bytes in. Nobody
-	 *	normal causes this. Its a cracker trying to break
-	 *	in by doing a flag overwrite to pass the direction
-	 *	checks.
-	 */
-	if (offset == 1 && (*pskb)->nh.iph->protocol == IPPROTO_TCP) {
-		if (!testing && net_ratelimit()) {
-			printk("Suspect TCP fragment.\n");
-			dump_packet(pskb,rif,NULL,NULL,0,0,0,0);
-		}
-		return FW_BLOCK;
-	}
-
-	/* If we can't investigate ports, treat as fragment.  It's
-	 * either a trucated whole packet, or a truncated first
-	 * fragment, or a TCP first fragment of length 8-15, in which
-	 * case the above rule stops reassembly.
-	 */
-	if (offset == 0) {
-		unsigned int size_req;
-		switch ((*pskb)->nh.iph->protocol) {
-		case IPPROTO_TCP:
-			/* Don't care about things past flags word */
-			size_req = 16;
-			break;
-
-		case IPPROTO_UDP:
-		case IPPROTO_ICMP:
-			size_req = 8;
-			break;
-
-		default:
-			size_req = 0;
-		}
-
-		/* If it is a truncated first fragment then it can be
-		 * used to rewrite port information, and thus should
-		 * be blocked.
-		 */
-		if (ntohs((*pskb)->nh.iph->tot_len) <
-		    ((*pskb)->nh.iph->ihl<<2)+size_req) {
-			if (!testing && net_ratelimit()) {
-				printk("Suspect short first fragment.\n");
-				dump_packet(pskb,rif,NULL,NULL,0,0,0,0);
-			}
-			return FW_BLOCK;
-		}
-	}
-
-	src = (*pskb)->nh.iph->saddr;
-	dst = (*pskb)->nh.iph->daddr;
-	tos = (*pskb)->nh.iph->tos;
-
-	/*
-	 *	If we got interface from which packet came
-	 *	we can use the address directly. Linux 2.1 now uses address
-	 *	chains per device too, but unlike BSD we first check if the
-	 *	incoming packet matches a device address and the routing
-	 *	table before calling the firewall.
-	 */
-
-	dprintf("Packet ");
-	switch ((*pskb)->nh.iph->protocol) {
-		case IPPROTO_TCP:
-			dprintf("TCP ");
-			if (!offset) {
-				struct tcphdr _tcph, *th;
-
-				th = skb_header_pointer(*pskb,
-							(*pskb)->nh.iph->ihl*4,
-							sizeof(_tcph), &_tcph);
-				if (th == NULL)
-					return FW_BLOCK;
-
-				src_port = ntohs(th->source);
-				dst_port = ntohs(th->dest);
-
-				/* Connection initilisation can only
-				 * be made when the syn bit is set and
-				 * neither of the ack or reset is
-				 * set. */
-				if (th->syn && !(th->ack || th->rst))
-					tcpsyn = 1;
-			}
-			break;
-		case IPPROTO_UDP:
-			dprintf("UDP ");
-			if (!offset) {
-				struct udphdr _udph, *uh;
-
-				uh = skb_header_pointer(*pskb,
-							(*pskb)->nh.iph->ihl*4,
-							sizeof(_udph), &_udph);
-				if (uh == NULL)
-					return FW_BLOCK;
-
-				src_port = ntohs(uh->source);
-				dst_port = ntohs(uh->dest);
-			}
-			break;
-		case IPPROTO_ICMP:
-			if (!offset) {
-				struct icmphdr _icmph, *ic;
-
-				ic = skb_header_pointer(*pskb,
-							(*pskb)->nh.iph->ihl*4,
-							sizeof(_icmph),
-							&_icmph);
-				if (ic == NULL)
-					return FW_BLOCK;
-
-				src_port = (__u16) ic->type;
-				dst_port = (__u16) ic->code;
-			}
-			dprintf("ICMP ");
-			break;
-		default:
-			dprintf("p=%d ", (*pskb)->nh.iph->protocol);
-			break;
-	}
-#ifdef DEBUG_IP_FIREWALL
-	print_ip((*pskb)->nh.iph->saddr);
-
-	if (offset)
-		dprintf(":fragment (%i) ", ((int)offset)<<2);
-	else if ((*pskb)->nh.iph->protocol == IPPROTO_TCP ||
-		 (*pskb)->nh.iph->protocol == IPPROTO_UDP ||
-		 (*pskb)->nh.iph->protocol == IPPROTO_ICMP)
-		dprintf(":%hu:%hu", src_port, dst_port);
-	dprintf("\n");
-#endif
-
-	if (!testing) FWC_READ_LOCK(&ip_fw_lock);
-	else FWC_HAVE_LOCK(fwc_rlocks);
-
-	f = chain->chain;
-	do {
-		count = 0;
-		for (; f; f = f->next) {
-			count++;
-			if (ip_rule_match(f, rif, pskb,
-					  tcpsyn, src_port, dst_port,
-					  offset)) {
-				if (!testing
-				    && !ip_fw_domatch(f, rif, chain->label,
-						      pskb, slot,
-						      src_port, dst_port,
-						      count, tcpsyn, &tos)) {
-					ret = FW_BLOCK;
-					cleanup(chain, 0, slot);
-					goto out;
-				}
-				break;
-			}
-		}
-		if (f) {
-			if (f->branch) {
-				/* Do sanity check to see if we have
-                                 * already set prevchain and if so we
-                                 * must be in a loop */
-				if (f->branch->reent[slot].prevchain) {
-					if (!testing) {
-						printk(KERN_ERR
-						       "IP firewall: "
-						       "Loop detected "
-						       "at `%s'.\n",
-						       f->branch->label);
-						cleanup(chain, 1, slot);
-						ret = FW_BLOCK;
-					} else {
-						cleanup(chain, 0, slot);
-						ret = FW_SKIP+1;
-					}
-				}
-				else {
-					f->branch->reent[slot].prevchain
-						= chain;
-					f->branch->reent[slot].prevrule
-						= f->next;
-					chain = f->branch;
-					f = chain->chain;
-				}
-			}
-			else if (f->simplebranch == FW_SKIP)
-				f = f->next;
-			else if (f->simplebranch == FW_SKIP+1) {
-				/* Just like falling off the chain */
-				goto fall_off_chain;
-			} else {
-				cleanup(chain, 0, slot);
-				ret = f->simplebranch;
-			}
-		} /* f == NULL */
-		else {
-		fall_off_chain:
-			if (chain->reent[slot].prevchain) {
-				struct ip_chain *tmp = chain;
-				f = chain->reent[slot].prevrule;
-				chain = chain->reent[slot].prevchain;
-				tmp->reent[slot].prevchain = NULL;
-			}
-			else {
-				ret = chain->policy;
-				if (!testing) {
-					chain->reent[slot].counters.pcnt++;
-					chain->reent[slot].counters.bcnt
-						+= ntohs((*pskb)->nh.iph->tot_len);
-				}
-			}
-		}
-	} while (ret == FW_SKIP+2);
-
- out:
-	if (!testing) FWC_READ_UNLOCK(&ip_fw_lock);
-
-	/* Recalculate checksum if not going to reject, and TOS changed. */
-	if ((*pskb)->nh.iph->tos != tos
-	    && ret != FW_REJECT && ret != FW_BLOCK
-	    && !testing) {
-		if (!skb_ip_make_writable(pskb, offsetof(struct iphdr, tos)+1))
-			ret = FW_BLOCK;
-		else {
-			(*pskb)->nh.iph->tos = tos;
-			ip_send_check((*pskb)->nh.iph);
-		}
-	}
-
-	if (ret == FW_REDIRECT && redirport) {
-		if ((*redirport = htons(f->ipfw.fw_redirpt)) == 0) {
-			/* Wildcard redirection.
-			 * Note that redirport will become
-			 * 0xFFFF for non-TCP/UDP packets.
-			 */
-			*redirport = htons(dst_port);
-		}
-	}
-
-#ifdef DEBUG_ALLOW_ALL
-	return (testing ? ret : FW_ACCEPT);
-#else
-	return ret;
-#endif
-}
-
-/* Must have write lock & interrupts off for any of these */
-
-/* This function sets all the byte counters in a chain to zero.  The
- * input is a pointer to the chain required for zeroing */
-static int zero_fw_chain(struct ip_chain *chainptr)
-{
-	struct ip_fwkernel *i;
-
-	FWC_HAVE_LOCK(fwc_wlocks);
-	for (i = chainptr->chain; i; i = i->next)
-		memset(i->counters, 0, sizeof(struct ip_counters)*NUM_SLOTS);
-	return 0;
-}
-
-static int clear_fw_chain(struct ip_chain *chainptr)
-{
-	struct ip_fwkernel *i= chainptr->chain;
-
-	FWC_HAVE_LOCK(fwc_wlocks);
-	chainptr->chain=NULL;
-
-	while (i) {
-		struct ip_fwkernel *tmp = i->next;
-		if (i->branch)
-			i->branch->refcount--;
-		kfree(i);
-		i = tmp;
-		/* We will block in cleanup's unregister sockopt if unloaded,
-		   so this is safe. */
-		module_put(THIS_MODULE);
-	}
-	return 0;
-}
-
-static int replace_in_chain(struct ip_chain *chainptr,
-			    struct ip_fwkernel *frwl,
-			    __u32 position)
-{
-	struct ip_fwkernel *f = chainptr->chain;
-
-	FWC_HAVE_LOCK(fwc_wlocks);
-
-	while (--position && f != NULL) f = f->next;
-	if (f == NULL)
-		return EINVAL;
-
-	if (f->branch) f->branch->refcount--;
-	if (frwl->branch) frwl->branch->refcount++;
-
-	frwl->next = f->next;
-	memcpy(f,frwl,sizeof(struct ip_fwkernel));
-	kfree(frwl);
-	return 0;
-}
-
-static int append_to_chain(struct ip_chain *chainptr, struct ip_fwkernel *rule)
-{
-	struct ip_fwkernel *i;
-
-	FWC_HAVE_LOCK(fwc_wlocks);
-
-	/* Are we unloading now?  We will block on nf_unregister_sockopt */
-	if (!try_module_get(THIS_MODULE))
-		return ENOPROTOOPT;
-
-	/* Special case if no rules already present */
-	if (chainptr->chain == NULL) {
-
-		/* If pointer writes are atomic then turning off
-		 * interrupts is not necessary. */
-		chainptr->chain = rule;
-		if (rule->branch) rule->branch->refcount++;
-		goto append_successful;
-	}
-
-	/* Find the rule before the end of the chain */
-	for (i = chainptr->chain; i->next; i = i->next);
-	i->next = rule;
-	if (rule->branch) rule->branch->refcount++;
-
-append_successful:
-	return 0;
-}
-
-/* This function inserts a rule at the position of position in the
- * chain refenced by chainptr.  If position is 1 then this rule will
- * become the new rule one. */
-static int insert_in_chain(struct ip_chain *chainptr,
-			   struct ip_fwkernel *frwl,
-			   __u32 position)
-{
-	struct ip_fwkernel *f = chainptr->chain;
-
-	FWC_HAVE_LOCK(fwc_wlocks);
-
-	/* Are we unloading now?  We will block on nf_unregister_sockopt */
-	if (!try_module_get(THIS_MODULE))
-		return ENOPROTOOPT;
-
-	/* special case if the position is number 1 */
-	if (position == 1) {
-		frwl->next = chainptr->chain;
-		if (frwl->branch) frwl->branch->refcount++;
-		chainptr->chain = frwl;
-		goto insert_successful;
-	}
-	position--;
-	while (--position && f != NULL) f = f->next;
-	if (f == NULL)
-		return EINVAL;
-	if (frwl->branch) frwl->branch->refcount++;
-	frwl->next = f->next;
-
-	f->next = frwl;
-
-insert_successful:
-	return 0;
-}
-
-/* This function deletes the a rule from a given rulenum and chain.
- * With rulenum = 1 is the first rule is deleted. */
-
-static int del_num_from_chain(struct ip_chain *chainptr, __u32 rulenum)
-{
-	struct ip_fwkernel *i=chainptr->chain,*tmp;
-
-	FWC_HAVE_LOCK(fwc_wlocks);
-
-	if (!chainptr->chain)
-		return ENOENT;
-
-	/* Need a special case for the first rule */
-	if (rulenum == 1) {
-		/* store temp to allow for freeing up of memory */
-		tmp = chainptr->chain;
-	        if (chainptr->chain->branch) chainptr->chain->branch->refcount--;
-		chainptr->chain = chainptr->chain->next;
-		kfree(tmp); /* free memory that is now unused */
-	} else {
-		rulenum--;
-		while (--rulenum && i->next ) i = i->next;
-		if (!i->next)
-			return ENOENT;
-		tmp = i->next;
-		if (i->next->branch)
-			i->next->branch->refcount--;
-		i->next = i->next->next;
-		kfree(tmp);
-	}
-
-	/* We will block in cleanup's unregister sockopt if unloaded,
-	   so this is safe. */
-	module_put(THIS_MODULE);
-	return 0;
-}
-
-
-/* This function deletes the a rule from a given rule and chain.
- * The rule that is deleted is the first occursance of that rule. */
-static int del_rule_from_chain(struct ip_chain *chainptr,
-			       struct ip_fwkernel *frwl)
-{
-	struct ip_fwkernel *ltmp,*ftmp = chainptr->chain ;
-	int was_found;
-
-	FWC_HAVE_LOCK(fwc_wlocks);
-
-	/* Sure, we should compare marks, but since the `ipfwadm'
-	 * script uses it for an unholy hack... well, life is easier
-	 * this way.  We also mask it out of the flags word. --PR */
-	for (ltmp=NULL, was_found=0;
-	     !was_found && ftmp != NULL;
-	     ltmp = ftmp,ftmp = ftmp->next) {
-		if (ftmp->ipfw.fw_src.s_addr!=frwl->ipfw.fw_src.s_addr
-		    || ftmp->ipfw.fw_dst.s_addr!=frwl->ipfw.fw_dst.s_addr
-		    || ftmp->ipfw.fw_smsk.s_addr!=frwl->ipfw.fw_smsk.s_addr
-		    || ftmp->ipfw.fw_dmsk.s_addr!=frwl->ipfw.fw_dmsk.s_addr
-#if 0
-		    || ftmp->ipfw.fw_flg!=frwl->ipfw.fw_flg
-#else
-		    || ((ftmp->ipfw.fw_flg & ~IP_FW_F_MARKABS)
-			!= (frwl->ipfw.fw_flg & ~IP_FW_F_MARKABS))
-#endif
-		    || ftmp->ipfw.fw_invflg!=frwl->ipfw.fw_invflg
-		    || ftmp->ipfw.fw_proto!=frwl->ipfw.fw_proto
-#if 0
-		    || ftmp->ipfw.fw_mark!=frwl->ipfw.fw_mark
-#endif
-		    || ftmp->ipfw.fw_redirpt!=frwl->ipfw.fw_redirpt
-		    || ftmp->ipfw.fw_spts[0]!=frwl->ipfw.fw_spts[0]
-		    || ftmp->ipfw.fw_spts[1]!=frwl->ipfw.fw_spts[1]
-		    || ftmp->ipfw.fw_dpts[0]!=frwl->ipfw.fw_dpts[0]
-		    || ftmp->ipfw.fw_dpts[1]!=frwl->ipfw.fw_dpts[1]
-		    || ftmp->ipfw.fw_outputsize!=frwl->ipfw.fw_outputsize) {
-			duprintf("del_rule_from_chain: mismatch:"
-				 "src:%u/%u dst:%u/%u smsk:%u/%u dmsk:%u/%u "
-				 "flg:%hX/%hX invflg:%hX/%hX proto:%u/%u "
-				 "mark:%u/%u "
-				 "ports:%hu-%hu/%hu-%hu %hu-%hu/%hu-%hu "
-				 "outputsize:%hu-%hu\n",
-				 ftmp->ipfw.fw_src.s_addr,
-				 frwl->ipfw.fw_src.s_addr,
-				 ftmp->ipfw.fw_dst.s_addr,
-				 frwl->ipfw.fw_dst.s_addr,
-				 ftmp->ipfw.fw_smsk.s_addr,
-				 frwl->ipfw.fw_smsk.s_addr,
-				 ftmp->ipfw.fw_dmsk.s_addr,
-				 frwl->ipfw.fw_dmsk.s_addr,
-				 ftmp->ipfw.fw_flg,
-				 frwl->ipfw.fw_flg,
-				 ftmp->ipfw.fw_invflg,
-				 frwl->ipfw.fw_invflg,
-				 ftmp->ipfw.fw_proto,
-				 frwl->ipfw.fw_proto,
-				 ftmp->ipfw.fw_mark,
-				 frwl->ipfw.fw_mark,
-				 ftmp->ipfw.fw_spts[0],
-				 frwl->ipfw.fw_spts[0],
-				 ftmp->ipfw.fw_spts[1],
-				 frwl->ipfw.fw_spts[1],
-				 ftmp->ipfw.fw_dpts[0],
-				 frwl->ipfw.fw_dpts[0],
-				 ftmp->ipfw.fw_dpts[1],
-				 frwl->ipfw.fw_dpts[1],
-				 ftmp->ipfw.fw_outputsize,
-				 frwl->ipfw.fw_outputsize);
-			continue;
-		}
-
-		if (strncmp(ftmp->ipfw.fw_vianame,
-			    frwl->ipfw.fw_vianame,
-			    IFNAMSIZ)) {
-			duprintf("del_rule_from_chain: if mismatch: %s/%s\n",
-				 ftmp->ipfw.fw_vianame,
-				 frwl->ipfw.fw_vianame);
-		        continue;
-		}
-		if (ftmp->branch != frwl->branch) {
-			duprintf("del_rule_from_chain: branch mismatch: "
-				 "%s/%s\n",
-				 ftmp->branch?ftmp->branch->label:"(null)",
-				 frwl->branch?frwl->branch->label:"(null)");
-			continue;
-		}
-		if (ftmp->branch == NULL
-		    && ftmp->simplebranch != frwl->simplebranch) {
-			duprintf("del_rule_from_chain: simplebranch mismatch: "
-				 "%i/%i\n",
-				 ftmp->simplebranch, frwl->simplebranch);
-			continue;
-		}
-		was_found = 1;
-		if (ftmp->branch)
-			ftmp->branch->refcount--;
-		if (ltmp)
-			ltmp->next = ftmp->next;
-		else
-			chainptr->chain = ftmp->next;
-		kfree(ftmp);
-		/* We will block in cleanup's unregister sockopt if unloaded,
-		   so this is safe. */
-		module_put(THIS_MODULE);
-		break;
-	}
-
-	if (was_found)
-		return 0;
-	else {
-		duprintf("del_rule_from_chain: no matching rule found\n");
-		return EINVAL;
-	}
-}
-
-/* This function takes the label of a chain and deletes the first
- * chain with that name.  No special cases required for the built in
- * chains as they have their refcount initilised to 1 so that they are
- * never deleted.  */
-static int del_chain(ip_chainlabel label)
-{
-	struct ip_chain *tmp,*tmp2;
-
-	FWC_HAVE_LOCK(fwc_wlocks);
-	/* Corner case: return EBUSY not ENOENT for first elem ("input") */
-	if (strcmp(label, ip_fw_chains->label) == 0)
-		return EBUSY;
-
-	for (tmp = ip_fw_chains; tmp->next; tmp = tmp->next)
-		if(strcmp(tmp->next->label,label) == 0)
-			break;
-
-	tmp2 = tmp->next;
-	if (!tmp2)
-		return ENOENT;
-
-	if (tmp2->refcount)
-		return EBUSY;
-
-	if (tmp2->chain)
-		return ENOTEMPTY;
-
-	tmp->next = tmp2->next;
-	kfree(tmp2);
-
-	/* We will block in cleanup's unregister sockopt if unloaded,
-	   so this is safe. */
-	module_put(THIS_MODULE);
-	return 0;
-}
-
-/* This is a function to initilise a chain.  Built in rules start with
- * refcount = 1 so that they cannot be deleted.  User defined rules
- * start with refcount = 0 so they can be deleted. */
-static struct ip_chain *ip_init_chain(ip_chainlabel name,
-				      __u32 ref,
-				      int policy)
-{
-	unsigned int i;
-	struct ip_chain *label
-		= kmalloc(SIZEOF_STRUCT_IP_CHAIN, GFP_KERNEL);
-	if (label == NULL)
-		panic("Can't kmalloc for firewall chains.\n");
-	strcpy(label->label,name);
-	label->next = NULL;
-	label->chain = NULL;
-	label->refcount = ref;
-	label->policy = policy;
-	for (i = 0; i < NUM_SLOTS; i++) {
-		label->reent[i].counters.pcnt = label->reent[i].counters.bcnt
-			= 0;
-		label->reent[i].prevchain = NULL;
-		label->reent[i].prevrule = NULL;
-	}
-
-	return label;
-}
-
-/* This is a function for reating a new chain.  The chains is not
- * created if a chain of the same name already exists */
-static int create_chain(ip_chainlabel label)
-{
-	struct ip_chain *tmp;
-
-	if (!check_label(label))
-		return EINVAL;
-
-	FWC_HAVE_LOCK(fwc_wlocks);
-	for (tmp = ip_fw_chains; tmp->next; tmp = tmp->next)
-		if (strcmp(tmp->label,label) == 0)
-			return EEXIST;
-
-	if (strcmp(tmp->label,label) == 0)
-		return EEXIST;
-
-	/* Are we unloading now?  We will block on nf_unregister_sockopt */
-	if (!try_module_get(THIS_MODULE))
-		return ENOPROTOOPT;
-
-	tmp->next = ip_init_chain(label, 0, FW_SKIP); /* refcount is
-					      * zero since this is a
-					      * user defined chain *
-					      * and therefore can be
-					      * deleted */
-	return 0;
-}
-
-/* This function simply changes the policy on one of the built in
- * chains.  checking must be done before this is call to ensure that
- * chainptr is pointing to one of the three possible chains */
-static int change_policy(struct ip_chain *chainptr, int policy)
-{
-	FWC_HAVE_LOCK(fwc_wlocks);
-	chainptr->policy = policy;
-	return 0;
-}
-
-/* This function takes an ip_fwuser and converts it to a ip_fwkernel.  It also
- * performs some checks in the structure. */
-static struct ip_fwkernel *convert_ipfw(struct ip_fwuser *fwuser, int *errno)
-{
-	struct ip_fwkernel *fwkern;
-
-	if ( (fwuser->ipfw.fw_flg & ~IP_FW_F_MASK) != 0 ) {
-		duprintf("convert_ipfw: undefined flag bits set (flags=%x)\n",
-			 fwuser->ipfw.fw_flg);
-		*errno = EINVAL;
-		return NULL;
-	}
-
-#ifdef DEBUG_IP_FIREWALL_USER
-	/* These are sanity checks that don't really matter.
-	 * We can get rid of these once testing is complete.
-	 */
-	if ((fwuser->ipfw.fw_flg & IP_FW_F_TCPSYN)
-	    && ((fwuser->ipfw.fw_invflg & IP_FW_INV_PROTO)
-		|| fwuser->ipfw.fw_proto != IPPROTO_TCP)) {
-		duprintf("convert_ipfw: TCP SYN flag set but proto != TCP!\n");
-		*errno = EINVAL;
-		return NULL;
-	}
-
-	if (strcmp(fwuser->label, IP_FW_LABEL_REDIRECT) != 0
-	    && fwuser->ipfw.fw_redirpt != 0) {
-		duprintf("convert_ipfw: Target not REDIR but redirpt != 0!\n");
-		*errno = EINVAL;
-		return NULL;
-	}
-
-	if ((!(fwuser->ipfw.fw_flg & IP_FW_F_FRAG)
-	     && (fwuser->ipfw.fw_invflg & IP_FW_INV_FRAG))
-	    || (!(fwuser->ipfw.fw_flg & IP_FW_F_TCPSYN)
-		&& (fwuser->ipfw.fw_invflg & IP_FW_INV_SYN))) {
-		duprintf("convert_ipfw: Can't have INV flag if flag unset!\n");
-		*errno = EINVAL;
-		return NULL;
-	}
-
-	if (((fwuser->ipfw.fw_invflg & IP_FW_INV_SRCPT)
-	     && fwuser->ipfw.fw_spts[0] == 0
-	     && fwuser->ipfw.fw_spts[1] == 0xFFFF)
-	    || ((fwuser->ipfw.fw_invflg & IP_FW_INV_DSTPT)
-		&& fwuser->ipfw.fw_dpts[0] == 0
-		&& fwuser->ipfw.fw_dpts[1] == 0xFFFF)
-	    || ((fwuser->ipfw.fw_invflg & IP_FW_INV_VIA)
-		&& (fwuser->ipfw.fw_vianame)[0] == '\0')
-	    || ((fwuser->ipfw.fw_invflg & IP_FW_INV_SRCIP)
-		&& fwuser->ipfw.fw_smsk.s_addr == 0)
-	    || ((fwuser->ipfw.fw_invflg & IP_FW_INV_DSTIP)
-		&& fwuser->ipfw.fw_dmsk.s_addr == 0)) {
-		duprintf("convert_ipfw: INV flag makes rule unmatchable!\n");
-		*errno = EINVAL;
-		return NULL;
-	}
-
-	if ((fwuser->ipfw.fw_flg & IP_FW_F_FRAG)
-	    && !(fwuser->ipfw.fw_invflg & IP_FW_INV_FRAG)
-	    && (fwuser->ipfw.fw_spts[0] != 0
-		|| fwuser->ipfw.fw_spts[1] != 0xFFFF
-		|| fwuser->ipfw.fw_dpts[0] != 0
-		|| fwuser->ipfw.fw_dpts[1] != 0xFFFF
-		|| (fwuser->ipfw.fw_flg & IP_FW_F_TCPSYN))) {
-		duprintf("convert_ipfw: Can't test ports or SYN with frag!\n");
-		*errno = EINVAL;
-		return NULL;
-	}
-#endif
-
-	if ((fwuser->ipfw.fw_spts[0] != 0
-	     || fwuser->ipfw.fw_spts[1] != 0xFFFF
-	     || fwuser->ipfw.fw_dpts[0] != 0
-	     || fwuser->ipfw.fw_dpts[1] != 0xFFFF)
-	    && ((fwuser->ipfw.fw_invflg & IP_FW_INV_PROTO)
-		|| (fwuser->ipfw.fw_proto != IPPROTO_TCP
-		    && fwuser->ipfw.fw_proto != IPPROTO_UDP
-		    && fwuser->ipfw.fw_proto != IPPROTO_ICMP))) {
-		duprintf("convert_ipfw: Can only test ports for TCP/UDP/ICMP!\n");
-		*errno = EINVAL;
-		return NULL;
-	}
-
-	fwkern = kmalloc(SIZEOF_STRUCT_IP_FW_KERNEL, GFP_ATOMIC);
-	if (!fwkern) {
-		duprintf("convert_ipfw: kmalloc failed!\n");
-		*errno = ENOMEM;
-		return NULL;
-	}
-	memcpy(&fwkern->ipfw,&fwuser->ipfw,sizeof(struct ip_fw));
-
-	if (!find_special(fwuser->label, &fwkern->simplebranch)) {
-		fwkern->branch = find_label(fwuser->label);
-		if (!fwkern->branch) {
-			duprintf("convert_ipfw: chain doesn't exist `%s'.\n",
-				 fwuser->label);
-			kfree(fwkern);
-			*errno = ENOENT;
-			return NULL;
-		} else if (fwkern->branch == IP_FW_INPUT_CHAIN
-			   || fwkern->branch == IP_FW_FORWARD_CHAIN
-			   || fwkern->branch == IP_FW_OUTPUT_CHAIN) {
-			duprintf("convert_ipfw: Can't branch to builtin chain `%s'.\n",
-				 fwuser->label);
-			kfree(fwkern);
-			*errno = ENOENT;
-			return NULL;
-		}
-	} else
-		fwkern->branch = NULL;
-	memset(fwkern->counters, 0, sizeof(struct ip_counters)*NUM_SLOTS);
-
-	/* Handle empty vianame by making it a wildcard */
-	if ((fwkern->ipfw.fw_vianame)[0] == '\0')
-	    fwkern->ipfw.fw_flg |= IP_FW_F_WILDIF;
-
-	fwkern->next = NULL;
-	return fwkern;
-}
-
-int ip_fw_ctl(int cmd, void *m, int len)
-{
-	int ret;
-	struct ip_chain *chain;
-	unsigned long flags;
-
-	FWC_WRITE_LOCK_IRQ(&ip_fw_lock, flags);
-
-	switch (cmd) {
-	case IP_FW_FLUSH:
-		if (len != sizeof(ip_chainlabel) || !check_label(m))
-			ret = EINVAL;
-		else if ((chain = find_label(m)) == NULL)
-			ret = ENOENT;
-		else ret = clear_fw_chain(chain);
-		break;
-
-	case IP_FW_ZERO:
-		if (len != sizeof(ip_chainlabel) || !check_label(m))
-			ret = EINVAL;
-		else if ((chain = find_label(m)) == NULL)
-			ret = ENOENT;
-		else ret = zero_fw_chain(chain);
-		break;
-
-	case IP_FW_CHECK: {
-		struct ip_fwtest *new = m;
-		struct iphdr *ip;
-
-		/* Don't need write lock. */
-		FWC_WRITE_UNLOCK_IRQ(&ip_fw_lock, flags);
-
-		if (len != sizeof(struct ip_fwtest) || !check_label(m))
-			return EINVAL;
-
-		/* Need readlock to do find_label */
-		FWC_READ_LOCK(&ip_fw_lock);
-
-		if ((chain = find_label(new->fwt_label)) == NULL)
-			ret = ENOENT;
-		else {
-			struct sk_buff *tmp_skb;
-			int hdrlen;
-
-			hdrlen = sizeof(struct ip_fwpkt) -
-				sizeof(struct in_addr) -
-				IFNAMSIZ;
-
-			ip = &(new->fwt_packet.fwp_iph);
-
-			/* Fix this one up by hand, who knows how many
-			 * tools will break if we start to barf on this.
-			 */
-			if (ntohs(ip->tot_len) > hdrlen)
-				ip->tot_len = htons(hdrlen);
-
-			if (ip->ihl != sizeof(struct iphdr) / sizeof(u32)) {
-				duprintf("ip_fw_ctl: ip->ihl=%d, want %d\n",
-					 ip->ihl,
-					 sizeof(struct iphdr) / sizeof(u32));
-				ret = EINVAL;
-			} else if ((tmp_skb = alloc_skb(hdrlen,
-							GFP_ATOMIC)) == NULL) {
-				duprintf("ip_fw_ctl: tmp_skb alloc failure\n");
-				ret = EFAULT;
-			} else {
-				skb_reserve(tmp_skb, hdrlen);
-				skb_push(tmp_skb, hdrlen);
-				memcpy(tmp_skb->data, ip, hdrlen);
-				tmp_skb->nh.raw =
-					(unsigned char *) tmp_skb->data;
-				ret = ip_fw_check(new->fwt_packet.fwp_vianame,
-						  NULL, chain,
-						  &tmp_skb, SLOT_NUMBER(), 1);
-				kfree_skb(tmp_skb);
-				switch (ret) {
-				case FW_ACCEPT:
-					ret = 0; break;
-				case FW_REDIRECT:
-					ret = ECONNABORTED; break;
-				case FW_MASQUERADE:
-					ret = ECONNRESET; break;
-				case FW_REJECT:
-					ret = ECONNREFUSED; break;
-					/* Hack to help diag; these only get
-					   returned when testing. */
-				case FW_SKIP+1:
-					ret = ELOOP; break;
-				case FW_SKIP:
-					ret = ENFILE; break;
-				default: /* FW_BLOCK */
-					ret = ETIMEDOUT; break;
-				}
-			}
-		}
-		FWC_READ_UNLOCK(&ip_fw_lock);
-		return ret;
-	}
-
-	case IP_FW_MASQ_TIMEOUTS: {
-		ret = ip_fw_masq_timeouts(m, len);
-	}
-	break;
-
-	case IP_FW_REPLACE: {
-		struct ip_fwkernel *ip_fwkern;
-		struct ip_fwnew *new = m;
-
-		if (len != sizeof(struct ip_fwnew)
-		    || !check_label(new->fwn_label))
-			ret = EINVAL;
-		else if ((chain = find_label(new->fwn_label)) == NULL)
-			ret = ENOENT;
-		else if ((ip_fwkern = convert_ipfw(&new->fwn_rule, &ret))
-			 != NULL)
-			ret = replace_in_chain(chain, ip_fwkern,
-					       new->fwn_rulenum);
-	}
-	break;
-
-	case IP_FW_APPEND: {
-		struct ip_fwchange *new = m;
-		struct ip_fwkernel *ip_fwkern;
-
-		if (len != sizeof(struct ip_fwchange)
-		    || !check_label(new->fwc_label))
-			ret = EINVAL;
-		else if ((chain = find_label(new->fwc_label)) == NULL)
-			ret = ENOENT;
-		else if ((ip_fwkern = convert_ipfw(&new->fwc_rule, &ret))
-			 != NULL)
-			ret = append_to_chain(chain, ip_fwkern);
-	}
-	break;
-
-	case IP_FW_INSERT: {
-		struct ip_fwkernel *ip_fwkern;
-		struct ip_fwnew *new = m;
-
-		if (len != sizeof(struct ip_fwnew)
-		    || !check_label(new->fwn_label))
-			ret = EINVAL;
-		else if ((chain = find_label(new->fwn_label)) == NULL)
-			ret = ENOENT;
-		else if ((ip_fwkern = convert_ipfw(&new->fwn_rule, &ret))
-			 != NULL)
-			ret = insert_in_chain(chain, ip_fwkern,
-					      new->fwn_rulenum);
-	}
-	break;
-
-	case IP_FW_DELETE: {
-		struct ip_fwchange *new = m;
-		struct ip_fwkernel *ip_fwkern;
-
-		if (len != sizeof(struct ip_fwchange)
-		    || !check_label(new->fwc_label))
-			ret = EINVAL;
-		else if ((chain = find_label(new->fwc_label)) == NULL)
-			ret = ENOENT;
-		else if ((ip_fwkern = convert_ipfw(&new->fwc_rule, &ret))
-			 != NULL) {
-			ret = del_rule_from_chain(chain, ip_fwkern);
-			kfree(ip_fwkern);
-		}
-	}
-	break;
-
-	case IP_FW_DELETE_NUM: {
-		struct ip_fwdelnum *new = m;
-
-		if (len != sizeof(struct ip_fwdelnum)
-		    || !check_label(new->fwd_label))
-			ret = EINVAL;
-		else if ((chain = find_label(new->fwd_label)) == NULL)
-			ret = ENOENT;
-		else ret = del_num_from_chain(chain, new->fwd_rulenum);
-	}
-	break;
-
-	case IP_FW_CREATECHAIN: {
-		if (len != sizeof(ip_chainlabel)) {
-			duprintf("create_chain: bad size %i\n", len);
-			ret = EINVAL;
-		}
-		else ret = create_chain(m);
-	}
-	break;
-
-	case IP_FW_DELETECHAIN: {
-		if (len != sizeof(ip_chainlabel)) {
-			duprintf("delete_chain: bad size %i\n", len);
-			ret = EINVAL;
-		}
-		else ret = del_chain(m);
-	}
-	break;
-
-	case IP_FW_POLICY: {
-		struct ip_fwpolicy *new = m;
-
-		if (len != sizeof(struct ip_fwpolicy)
-		    || !check_label(new->fwp_label))
-			ret = EINVAL;
-		else if ((chain = find_label(new->fwp_label)) == NULL)
-			ret = ENOENT;
-		else if (chain != IP_FW_INPUT_CHAIN
-			 && chain != IP_FW_FORWARD_CHAIN
-			 && chain != IP_FW_OUTPUT_CHAIN) {
-			duprintf("change_policy: can't change policy on user"
-				 " defined chain.\n");
-			ret = EINVAL;
-		}
-		else {
-		        int pol = FW_SKIP;
-			find_special(new->fwp_policy, &pol);
-
-			switch(pol) {
-			case FW_MASQUERADE:
-				if (chain != IP_FW_FORWARD_CHAIN) {
-					ret = EINVAL;
-					break;
-				}
-				/* Fall thru... */
-			case FW_BLOCK:
-			case FW_ACCEPT:
-			case FW_REJECT:
-				ret = change_policy(chain, pol);
-				break;
-			default:
-			        duprintf("change_policy: bad policy `%s'\n",
-					 new->fwp_policy);
-				ret = EINVAL;
-			}
-		}
-		break;
-	}
-	default:
-		duprintf("ip_fw_ctl:  unknown request %d\n",cmd);
-		ret = ENOPROTOOPT;
-	}
-
-	FWC_WRITE_UNLOCK_IRQ(&ip_fw_lock, flags);
-	return ret;
-}
-
-/* Returns bytes used - doesn't NUL terminate */
-static int dump_rule(char *buffer,
-		     const char *chainlabel,
-		     const struct ip_fwkernel *rule)
-{
-	int len;
-	unsigned int i;
-	__u64 packets = 0, bytes = 0;
-
-	FWC_HAVE_LOCK(fwc_wlocks);
-	for (i = 0; i < NUM_SLOTS; i++) {
-		packets += rule->counters[i].pcnt;
-		bytes += rule->counters[i].bcnt;
-	}
-
-	len=sprintf(buffer,
-		    "%9s "			/* Chain name */
-		    "%08X/%08X->%08X/%08X "	/* Source & Destination IPs */
-		    "%.16s "			/* Interface */
-		    "%X %X "			/* fw_flg and fw_invflg fields */
-		    "%u "			/* Protocol */
-		    "%-9u %-9u %-9u %-9u "	/* Packet & byte counters */
-		    "%u-%u %u-%u "		/* Source & Dest port ranges */
-		    "A%02X X%02X "		/* TOS and and xor masks */
-		    "%08X "			/* Redirection port */
-		    "%u "			/* fw_mark field */
-		    "%u "			/* output size */
-		    "%9s\n",			/* Target */
-		    chainlabel,
-		    ntohl(rule->ipfw.fw_src.s_addr),
-		    ntohl(rule->ipfw.fw_smsk.s_addr),
-		    ntohl(rule->ipfw.fw_dst.s_addr),
-		    ntohl(rule->ipfw.fw_dmsk.s_addr),
-		    (rule->ipfw.fw_vianame)[0] ? rule->ipfw.fw_vianame : "-",
-		    rule->ipfw.fw_flg,
-		    rule->ipfw.fw_invflg,
-		    rule->ipfw.fw_proto,
-		    (__u32)(packets >> 32), (__u32)packets,
-		    (__u32)(bytes >> 32), (__u32)bytes,
-		    rule->ipfw.fw_spts[0], rule->ipfw.fw_spts[1],
-		    rule->ipfw.fw_dpts[0], rule->ipfw.fw_dpts[1],
-		    rule->ipfw.fw_tosand, rule->ipfw.fw_tosxor,
-		    rule->ipfw.fw_redirpt,
-		    rule->ipfw.fw_mark,
-		    rule->ipfw.fw_outputsize,
-		    branchname(rule->branch,rule->simplebranch));
-
-	duprintf("dump_rule: %i bytes done.\n", len);
-	return len;
-}
-
-/* File offset is actually in records, not bytes. */
-static int ip_chain_procinfo(char *buffer, char **start,
-			     off_t offset, int length)
-{
-	struct ip_chain *i;
-	struct ip_fwkernel *j = ip_fw_chains->chain;
-	unsigned long flags;
-	int len = 0;
-	int last_len = 0;
-	off_t upto = 0;
-
-	duprintf("Offset starts at %lu\n", offset);
-	duprintf("ip_fw_chains is 0x%0lX\n", (unsigned long int)ip_fw_chains);
-
-	/* Need a write lock to lock out ``readers'' which update counters. */
-	FWC_WRITE_LOCK_IRQ(&ip_fw_lock, flags);
-
-	for (i = ip_fw_chains; i; i = i->next) {
-	    for (j = i->chain; j; j = j->next) {
-		if (upto == offset) break;
-		duprintf("Skipping rule in chain `%s'\n",
-			 i->label);
-		upto++;
-	    }
-	    if (upto == offset) break;
-	}
-
-	/* Don't init j first time, or once i = NULL */
-	for (; i; (void)((i = i->next) && (j = i->chain))) {
-		duprintf("Dumping chain `%s'\n", i->label);
-		for (; j; j = j->next, upto++, last_len = len)
-		{
-			len += dump_rule(buffer+len, i->label, j);
-			if (len > length) {
-				duprintf("Dumped to %i (past %i).  "
-					 "Moving back to %i.\n",
-					 len, length, last_len);
-				len = last_len;
-				goto outside;
-			}
-		}
-	}
-outside:
-	FWC_WRITE_UNLOCK_IRQ(&ip_fw_lock, flags);
-	buffer[len] = '\0';
-
-	duprintf("ip_chain_procinfo: Length = %i (of %i).  Offset = %li.\n",
-		 len, length, upto);
-	/* `start' hack - see fs/proc/generic.c line ~165 */
-	*start=(char *)((unsigned int)upto-offset);
-	return len;
-}
-
-static int ip_chain_name_procinfo(char *buffer, char **start,
-				  off_t offset, int length)
-{
-	struct ip_chain *i;
-	int len = 0,last_len = 0;
-	off_t pos = 0,begin = 0;
-	unsigned long flags;
-
-	/* Need a write lock to lock out ``readers'' which update counters. */
-	FWC_WRITE_LOCK_IRQ(&ip_fw_lock, flags);
-
-	for (i = ip_fw_chains; i; i = i->next)
-	{
-		unsigned int j;
-		__u32 packetsHi = 0, packetsLo = 0, bytesHi = 0, bytesLo = 0;
-
-		for (j = 0; j < NUM_SLOTS; j++) {
-			packetsLo += i->reent[j].counters.pcnt & 0xFFFFFFFF;
-			packetsHi += ((i->reent[j].counters.pcnt >> 32)
-				      & 0xFFFFFFFF);
-			bytesLo += i->reent[j].counters.bcnt & 0xFFFFFFFF;
-			bytesHi += ((i->reent[j].counters.bcnt >> 32)
-				    & 0xFFFFFFFF);
-		}
-
-		/* print the label and the policy */
-		len+=sprintf(buffer+len,"%s %s %i %u %u %u %u\n",
-			     i->label,branchname(NULL, i->policy),i->refcount,
-			     packetsHi, packetsLo, bytesHi, bytesLo);
-		pos=begin+len;
-		if(pos<offset) {
-			len=0;
-			begin=pos;
-		}
-		else if(pos>offset+length) {
-			len = last_len;
-			break;
-		}
-
-		last_len = len;
-	}
-	FWC_WRITE_UNLOCK_IRQ(&ip_fw_lock, flags);
-
-	*start = buffer+(offset-begin);
-	len-=(offset-begin);
-	if(len>length)
-		len=length;
-	return len;
-}
-
-/*
- *	Interface to the generic firewall chains.
- */
-int ipfw_input_check(struct firewall_ops *this, int pf,
-		     struct net_device *dev, void *arg,
-		     struct sk_buff **pskb)
-{
-	return ip_fw_check(dev->name,
-			   arg, IP_FW_INPUT_CHAIN, pskb, SLOT_NUMBER(), 0);
-}
-
-int ipfw_output_check(struct firewall_ops *this, int pf,
-		      struct net_device *dev, void *arg,
-		      struct sk_buff **pskb)
-{
-	/* Locally generated bogus packets by root. <SIGH>. */
-	if ((*pskb)->len < sizeof(struct iphdr) ||
-	    (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr))
-		return FW_ACCEPT;
-	return ip_fw_check(dev->name,
-			   arg, IP_FW_OUTPUT_CHAIN, pskb, SLOT_NUMBER(), 0);
-}
-
-int ipfw_forward_check(struct firewall_ops *this, int pf,
-		       struct net_device *dev, void *arg,
-		       struct sk_buff **pskb)
-{
-	return ip_fw_check(dev->name,
-			   arg, IP_FW_FORWARD_CHAIN, pskb, SLOT_NUMBER(), 0);
-}
-
-struct firewall_ops ipfw_ops = {
-	.fw_forward	=	ipfw_forward_check,
-	.fw_input	=	ipfw_input_check,
-	.fw_output	=	ipfw_output_check,
-};
-
-int ipfw_init_or_cleanup(int init)
-{
-	struct proc_dir_entry *proc;
-	int ret = 0;
-	unsigned long flags;
-
-	if (!init) goto cleanup;
-
-#ifdef DEBUG_IP_FIREWALL_LOCKING
-	fwc_wlocks = fwc_rlocks = 0;
-#endif
-
-#if defined(CONFIG_NETLINK_DEV) || defined(CONFIG_NETLINK_DEV_MODULE)
-	ipfwsk = netlink_kernel_create(NETLINK_FIREWALL, NULL);
-	if (ipfwsk == NULL)
-		goto cleanup_nothing;
-#endif
-
-	ret = register_firewall(PF_INET, &ipfw_ops);
-	if (ret < 0)
-		goto cleanup_netlink;
-
-	proc = proc_net_create(IP_FW_PROC_CHAINS, S_IFREG | S_IRUSR | S_IWUSR,
-			       ip_chain_procinfo);
-	if (proc) proc->owner = THIS_MODULE;
-	proc = proc_net_create(IP_FW_PROC_CHAIN_NAMES,
-			       S_IFREG | S_IRUSR | S_IWUSR,
-			       ip_chain_name_procinfo);
-	if (proc) proc->owner = THIS_MODULE;
-
-	IP_FW_INPUT_CHAIN = ip_init_chain(IP_FW_LABEL_INPUT, 1, FW_ACCEPT);
-	IP_FW_FORWARD_CHAIN = ip_init_chain(IP_FW_LABEL_FORWARD, 1, FW_ACCEPT);
-	IP_FW_OUTPUT_CHAIN = ip_init_chain(IP_FW_LABEL_OUTPUT, 1, FW_ACCEPT);
-
-	return ret;
-
- cleanup:
-	unregister_firewall(PF_INET, &ipfw_ops);
-
-	FWC_WRITE_LOCK_IRQ(&ip_fw_lock, flags);
-	while (ip_fw_chains) {
-		struct ip_chain *next = ip_fw_chains->next;
-
-		clear_fw_chain(ip_fw_chains);
-		kfree(ip_fw_chains);
-		ip_fw_chains = next;
-	}
-	FWC_WRITE_UNLOCK_IRQ(&ip_fw_lock, flags);
-
-	proc_net_remove(IP_FW_PROC_CHAINS);
-	proc_net_remove(IP_FW_PROC_CHAIN_NAMES);
-
- cleanup_netlink:
-#if defined(CONFIG_NETLINK_DEV) || defined(CONFIG_NETLINK_DEV_MODULE)
-	sock_release(ipfwsk->sk_socket);
-
- cleanup_nothing:
-#endif
-	return ret;
-}
diff -Nru a/net/ipv4/netfilter/ipfwadm_core.c b/net/ipv4/netfilter/ipfwadm_core.c
--- a/net/ipv4/netfilter/ipfwadm_core.c	2005-03-01 23:38:56 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,1464 +0,0 @@
-#warning ipfwadm is obsolete, and will be removed soon.
-
-/* Minor modifications to fit on compatibility framework:
-   Rusty.Russell@rustcorp.com.au
-*/
-
-#include <linux/config.h>
-#define CONFIG_IP_FIREWALL
-#define CONFIG_IP_FIREWALL_VERBOSE
-#define CONFIG_IP_MASQUERADE
-#define CONFIG_IP_ACCT
-#define CONFIG_IP_TRANSPARENT_PROXY
-#if defined(CONFIG_NETLINK_DEV) || defined(CONFIG_NETLINK_DEV_MODULE)
-#define CONFIG_IP_FIREWALL_NETLINK
-#endif
-
-/*
- *	IP firewalling code. This is taken from 4.4BSD. Please note the
- *	copyright message below. As per the GPL it must be maintained
- *	and the licenses thus do not conflict. While this port is subject
- *	to the GPL I also place my modifications under the original
- *	license in recognition of the original copyright.
- *				-- Alan Cox.
- *
- *	$Id: ipfwadm_core.c,v 1.11 2002/01/24 15:50:31 davem Exp $
- *
- *	Ported from BSD to Linux,
- *		Alan Cox 22/Nov/1994.
- *	Zeroing /proc and other additions
- *		Jos Vos 4/Feb/1995.
- *	Merged and included the FreeBSD-Current changes at Ugen's request
- *	(but hey it's a lot cleaner now). Ugen would prefer in some ways
- *	we waited for his final product but since Linux 1.2.0 is about to
- *	appear it's not practical - Read: It works, it's not clean but please
- *	don't consider it to be his standard of finished work.
- *		Alan Cox 12/Feb/1995
- *	Porting bidirectional entries from BSD, fixing accounting issues,
- *	adding struct ip_fwpkt for checking packets with interface address
- *		Jos Vos 5/Mar/1995.
- *	Established connections (ACK check), ACK check on bidirectional rules,
- *	ICMP type check.
- *		Wilfred Mollenvanger 7/7/1995.
- *	TCP attack protection.
- *		Alan Cox 25/8/95, based on information from bugtraq.
- *	ICMP type printk, IP_FW_F_APPEND
- *		Bernd Eckenfels 1996-01-31
- *	Split blocking chain into input and output chains, add new "insert" and
- *	"append" commands to replace semi-intelligent "add" command, let "delete".
- *	only delete the first matching entry, use 0xFFFF (0xFF) as ports (ICMP
- *	types) when counting packets being 2nd and further fragments.
- *		Jos Vos <jos@xos.nl> 8/2/1996.
- *	Add support for matching on device names.
- *		Jos Vos <jos@xos.nl> 15/2/1996.
- *	Transparent proxying support.
- *		Willy Konynenberg <willy@xos.nl> 10/5/96.
- *	Make separate accounting on incoming and outgoing packets possible.
- *		Jos Vos <jos@xos.nl> 18/5/1996.
- *	Added trap out of bad frames.
- *		Alan Cox <alan@cymru.net> 17/11/1996
- *
- *
- * Masquerading functionality
- *
- * Copyright (c) 1994 Pauline Middelink
- *
- * The pieces which added masquerading functionality are totally
- * my responsibility and have nothing to with the original authors
- * copyright or doing.
- *
- * Parts distributed under GPL.
- *
- * Fixes:
- *	Pauline Middelink	:	Added masquerading.
- *	Alan Cox		:	Fixed an error in the merge.
- *	Thomas Quinot		:	Fixed port spoofing.
- *	Alan Cox		:	Cleaned up retransmits in spoofing.
- *	Alan Cox		:	Cleaned up length setting.
- *	Wouter Gadeyne		:	Fixed masquerading support of ftp PORT commands
- *
- *	Juan Jose Ciarlante	:	Masquerading code moved to ip_masq.c
- *	Andi Kleen :		Print frag_offsets and the ip flags properly.
- *
- *	All the real work was done by .....
- *
- */
-
-
-/*
- * Copyright (c) 1993 Daniel Boulet
- * Copyright (c) 1994 Ugen J.S.Antsilevich
- *
- * Redistribution and use in source forms, with and without modification,
- * are permitted provided that this entire comment appears intact.
- *
- * Redistribution in binary form may occur without any restrictions.
- * Obviously, it would be nice if you gave credit where credit is due
- * but requiring it would be too onerous.
- *
- * This software is provided ``AS IS'' without any warranties of any kind.
- */
-
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/module.h>
-
-#include <linux/socket.h>
-#include <linux/sockios.h>
-#include <linux/in.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/icmp.h>
-#include <linux/udp.h>
-#include <net/ip.h>
-#include <net/protocol.h>
-#include <net/route.h>
-#include <net/tcp.h>
-#include <net/udp.h>
-#include <net/sock.h>
-#include <net/icmp.h>
-#include <linux/netlink.h>
-#include <linux/init.h>
-#include <linux/spinlock.h>
-#include <linux/netfilter_ipv4/ipfwadm_core.h>
-#include <linux/netfilter_ipv4/compat_firewall.h>
-#include <linux/netfilter_ipv4/lockhelp.h>
-#include <linux/netfilter_ipv4/ip_nat_core.h>
-
-#include <net/checksum.h>
-#include <linux/proc_fs.h>
-#include <linux/stat.h>
-
-MODULE_LICENSE("Dual BSD/GPL");
-MODULE_DESCRIPTION("ipfwadm backwards compatibility layer");
-
-/*
- *	Implement IP packet firewall
- */
-
-#ifdef DEBUG_IP_FIREWALL
-#define dprintf1(a)		printk(a)
-#define dprintf2(a1,a2)		printk(a1,a2)
-#define dprintf3(a1,a2,a3)	printk(a1,a2,a3)
-#define dprintf4(a1,a2,a3,a4)	printk(a1,a2,a3,a4)
-#else
-#define dprintf1(a)
-#define dprintf2(a1,a2)
-#define dprintf3(a1,a2,a3)
-#define dprintf4(a1,a2,a3,a4)
-#endif
-
-#define print_ip(a)	 printk("%u.%u.%u.%u", NIPQUAD(a));
-
-#ifdef DEBUG_IP_FIREWALL
-#define dprint_ip(a)	print_ip(a)
-#else
-#define dprint_ip(a)
-#endif
-
-static DECLARE_RWLOCK(ip_fw_lock);
-
-#if defined(CONFIG_IP_ACCT) || defined(CONFIG_IP_FIREWALL)
-
-struct ip_fw *ip_fw_fwd_chain;
-struct ip_fw *ip_fw_in_chain;
-struct ip_fw *ip_fw_out_chain;
-struct ip_fw *ip_acct_chain;
-struct ip_fw *ip_masq_chain;
-
-static struct ip_fw **chains[] =
-	{&ip_fw_fwd_chain, &ip_fw_in_chain, &ip_fw_out_chain, &ip_acct_chain,
-	 &ip_masq_chain
-	};
-#endif /* CONFIG_IP_ACCT || CONFIG_IP_FIREWALL */
-
-#ifdef CONFIG_IP_FIREWALL
-int ip_fw_fwd_policy=IP_FW_F_ACCEPT;
-int ip_fw_in_policy=IP_FW_F_ACCEPT;
-int ip_fw_out_policy=IP_FW_F_ACCEPT;
-
-static int *policies[] =
-	{&ip_fw_fwd_policy, &ip_fw_in_policy, &ip_fw_out_policy};
-
-#endif
-
-#ifdef CONFIG_IP_FIREWALL_NETLINK
-struct sock *ipfwsk;
-#endif
-
-/*
- *	Returns 1 if the port is matched by the vector, 0 otherwise
- */
-
-extern inline int port_match(unsigned short *portptr,int nports,unsigned short port,int range_flag)
-{
-	if (!nports)
-		return 1;
-	if ( range_flag )
-	{
-		if ( portptr[0] <= port && port <= portptr[1] )
-		{
-			return( 1 );
-		}
-		nports -= 2;
-		portptr += 2;
-	}
-	while ( nports-- > 0 )
-	{
-		if ( *portptr++ == port )
-		{
-			return( 1 );
-		}
-	}
-	return(0);
-}
-
-#if defined(CONFIG_IP_ACCT) || defined(CONFIG_IP_FIREWALL)
-
-#ifdef CONFIG_IP_FIREWALL_VERBOSE
-
-/*
- *	VERY ugly piece of code which actually makes kernel printf for
- * 	matching packets.
- */
-
-static char *chain_name(struct ip_fw *chain, int mode)
-{
-	switch (mode) {
-	case IP_FW_MODE_ACCT_IN: return "acct in";
-	case IP_FW_MODE_ACCT_OUT: return "acct out";
-	default:
-		if (chain == ip_fw_fwd_chain)
-			return "fw-fwd";
-		else if (chain == ip_fw_in_chain)
-			return "fw-in";
-		else
-			return "fw-out";
-	}
-}
-
-static char *rule_name(struct ip_fw *f, int mode, char *buf)
-{
-	if (mode == IP_FW_MODE_ACCT_IN || mode == IP_FW_MODE_ACCT_OUT)
-		return "";
-
-	if(f->fw_flg&IP_FW_F_ACCEPT) {
-		if(f->fw_flg&IP_FW_F_REDIR) {
-			sprintf(buf, "acc/r%d ", f->fw_pts[f->fw_nsp+f->fw_ndp]);
-			return buf;
-		} else if(f->fw_flg&IP_FW_F_MASQ)
-			return "acc/masq ";
-		else
-			return "acc ";
-	} else if(f->fw_flg&IP_FW_F_ICMPRPL) {
-		return "rej ";
-	} else {
-		return "deny ";
-	}
-}
-
-static void print_packet(struct sk_buff **pskb,
-			 u16 src_port, u16 dst_port, u16 icmp_type,
-			 char *chain, char *rule, char *devname)
-{
-	__u32 *opt = (__u32 *) ((*pskb)->nh.iph + 1);
-	int opti;
-	__u16 foff = ntohs((*pskb)->nh.iph->frag_off);
-	int protocol = (*pskb)->nh.iph->protocol;
-
-	printk(KERN_INFO "IP %s %s%s", chain, rule, devname);
-
-	switch (protocol) {
-	case IPPROTO_TCP:
-		printk(" TCP ");
-		break;
-	case IPPROTO_UDP:
-		printk(" UDP ");
-		break;
-	case IPPROTO_ICMP:
-		printk(" ICMP/%d ", icmp_type);
-		break;
-	default:
-		printk(" PROTO=%d ", protocol);
-		break;
-	};
-
-	print_ip((*pskb)->nh.iph->saddr);
-	if (protocol == IPPROTO_TCP || protocol == IPPROTO_UDP)
-		printk(":%hu", src_port);
-	printk(" ");
-	print_ip((*pskb)->nh.iph->daddr);
-	if (protocol == IPPROTO_TCP || protocol == IPPROTO_UDP)
-		printk(":%hu", dst_port);
-	printk(" L=%hu S=0x%2.2hX I=%hu FO=0x%4.4hX T=%hu",
-	       ntohs((*pskb)->nh.iph->tot_len),
-	       (*pskb)->nh.iph->tos,
-	       ntohs((*pskb)->nh.iph->id),
-	       foff & IP_OFFSET,
-	       (*pskb)->nh.iph->ttl);
-	if (foff & IP_DF)
-		printk(" DF=1");
-	if (foff & IP_MF)
-		printk(" MF=1");
-	for (opti = 0; opti < ((*pskb)->nh.iph->ihl - sizeof(struct iphdr) / 4); opti++)
-		printk(" O=0x%8.8X", *opt++);
-	printk("\n");
-}
-#endif
-
-/*
- *	Returns one of the generic firewall policies, like FW_ACCEPT.
- *	Also does accounting so you can feed it the accounting chain.
- *
- *	The modes is either IP_FW_MODE_FW (normal firewall mode),
- *	IP_FW_MODE_ACCT_IN or IP_FW_MODE_ACCT_OUT (accounting mode,
- *	steps through the entire chain and handles fragments
- *	differently), or IP_FW_MODE_CHK (handles user-level check,
- *	counters are not updated).
- */
-
-
-int ip_fw_chk(struct sk_buff **pskb,
-	      struct net_device *rif, __u16 *redirport,
-	      struct ip_fw *chain, int policy, int mode)
-{
-	struct ip_fw *f;
-	__u32			src, dst;
-	__u16			src_port=0xFFFF, dst_port=0xFFFF, icmp_type=0xFF;
-	unsigned short		f_prt=0, prt;
-	char			notcpsyn=0, notcpack=0, match;
-	unsigned short		offset;
-	int			answer;
-	unsigned char		tosand, tosxor;
-	int			protocol;
-
-	/*
-	 *	If the chain is empty follow policy. The BSD one
-	 *	accepts anything giving you a time window while
-	 *	flushing and rebuilding the tables.
-	 */
-
-	/*
-	 *	This way we handle fragmented packets.
-	 *	we ignore all fragments but the first one
-	 *	so the whole packet can't be reassembled.
-	 *	This way we relay on the full info which
-	 *	stored only in first packet.
-	 *
-	 *	Note that this theoretically allows partial packet
-	 *	spoofing. Not very dangerous but paranoid people may
-	 *	wish to play with this. It also allows the so called
-	 *	"fragment bomb" denial of service attack on some types
-	 *	of system.
-	 */
-
-	offset = ntohs((*pskb)->nh.iph->frag_off) & IP_OFFSET;
-	protocol = (*pskb)->nh.iph->protocol;
-
-	/*
-	 *	Don't allow a fragment of TCP 8 bytes in. Nobody
-	 *	normal causes this. Its a cracker trying to break
-	 *	in by doing a flag overwrite to pass the direction
-	 *	checks.
-	 */
-
-	if (offset == 1 && protocol == IPPROTO_TCP)
-		return FW_BLOCK;
-
-	if (offset!=0 && !(mode & (IP_FW_MODE_ACCT_IN|IP_FW_MODE_ACCT_OUT)) &&
-		(protocol == IPPROTO_TCP ||
-		 protocol == IPPROTO_UDP ||
-		 protocol == IPPROTO_ICMP))
-		return FW_ACCEPT;
-
-	/*
-	 *	 Header fragment for TCP is too small to check the bits.
-	 */
-
-	if (protocol == IPPROTO_TCP &&
-	    ((*pskb)->nh.iph->ihl<<2)+16 > ntohs((*pskb)->nh.iph->tot_len))
-		return FW_BLOCK;
-
-	/*
-	 *	Too short.
-	 *
-	 *	But only too short for a packet with ports...
-	 */
-
-	else if ((ntohs((*pskb)->nh.iph->tot_len) <
-		  8 + ((*pskb)->nh.iph->ihl << 2)) &&
-		 (protocol == IPPROTO_TCP || protocol == IPPROTO_UDP))
-		return FW_BLOCK;
-
-	src = (*pskb)->nh.iph->saddr;
-	dst = (*pskb)->nh.iph->daddr;
-
-	/*
-	 *	If we got interface from which packet came
-	 *	we can use the address directly. This is unlike
-	 *	4.4BSD derived systems that have an address chain
-	 *	per device. We have a device per address with dummy
-	 *	devices instead.
-	 */
-
-	dprintf1("Packet ");
-	switch (protocol) {
-		case IPPROTO_TCP:
-			dprintf1("TCP ");
-			/* ports stay 0xFFFF if it is not the first fragment */
-			if (!offset) {
-				struct tcphdr _tcph, *th;
-
-				th = skb_header_pointer(*pskb,
-							(*pskb)->nh.iph->ihl*4,
-							sizeof(_tcph), &_tcph);
-				if (th == NULL)
-					return FW_BLOCK;
-
-				src_port = ntohs(th->source);
-				dst_port = ntohs(th->dest);
-
-				if(!th->ack && !th->rst)
-					/* We do NOT have ACK, value TRUE */
-					notcpack = 1;
-				if(!th->syn || !notcpack)
-					/* We do NOT have SYN, value TRUE */
-					notcpsyn = 1;
-			}
-			prt = IP_FW_F_TCP;
-			break;
-		case IPPROTO_UDP:
-			dprintf1("UDP ");
-			/* ports stay 0xFFFF if it is not the first fragment */
-			if (!offset) {
-				struct udphdr _udph, *uh;
-
-				uh = skb_header_pointer(*pskb,
-							(*pskb)->nh.iph->ihl*4,
-							sizeof(_udph), &_udph);
-				if (uh == NULL)
-					return FW_BLOCK;
-
-				src_port = ntohs(uh->source);
-				dst_port = ntohs(uh->dest);
-			}
-			prt = IP_FW_F_UDP;
-			break;
-		case IPPROTO_ICMP:
-			/* icmp_type stays 255 if it is not the first fragment */
-			if (!offset) {
-				struct icmphdr _icmph, *ic;
-
-				ic = skb_header_pointer(*pskb,
-							(*pskb)->nh.iph->ihl*4,
-							sizeof(_icmph),
-							&_icmph);
-				if (ic == NULL)
-					return FW_BLOCK;
-
-				icmp_type = (__u16) ic->type;
-			}
-			dprintf2("ICMP:%d ", icmp_type);
-			prt = IP_FW_F_ICMP;
-			break;
-		default:
-			dprintf2("p=%d ", protocol);
-			prt = IP_FW_F_ALL;
-			break;
-	}
-#ifdef DEBUG_IP_FIREWALL
-	dprint_ip(src);
-
-	if (protocol == IPPROTO_TCP || protocol == IPPROTO_UDP)
-		/* This will print 65535 when it is not the first fragment! */
-		dprintf2(":%d ", src_port);
-	dprint_ip(dst);
-	if (protocol == IPPROTO_TCP || protocol == IPPROTO_UDP)
-		/* This will print 65535 when it is not the first fragment! */
-		dprintf2(":%d ", dst_port);
-	dprintf1("\n");
-#endif
-
-	if (mode == IP_FW_MODE_CHK)
-		READ_LOCK(&ip_fw_lock);
-	else
-		WRITE_LOCK(&ip_fw_lock);
-	
-	for (f = chain; f; f = f->fw_next) {
-		/*
-		 *	This is a bit simpler as we don't have to walk
-		 *	an interface chain as you do in BSD - same logic
-		 *	however.
-		 */
-
-		/*
-		 *	Match can become 0x01 (a "normal" match was found),
-		 *	0x02 (a reverse match was found), and 0x03 (the
-		 *	IP addresses match in both directions).
-		 *	Now we know in which direction(s) we should look
-		 *	for a match for the TCP/UDP ports.  Both directions
-		 *	might match (e.g., when both addresses are on the
-		 *	same network for which an address/mask is given), but
-		 *	the ports might only match in one direction.
-		 *	This was obviously wrong in the original BSD code.
-		 */
-		match = 0x00;
-
-		if ((src & f->fw_smsk.s_addr) == f->fw_src.s_addr &&
-		    (dst & f->fw_dmsk.s_addr) == f->fw_dst.s_addr)
-			/* normal direction */
-			match |= 0x01;
-
-		if ((f->fw_flg & IP_FW_F_BIDIR) &&
-		    (dst & f->fw_smsk.s_addr) == f->fw_src.s_addr &&
-		    (src & f->fw_dmsk.s_addr) == f->fw_dst.s_addr)
-			/* reverse direction */
-			match |= 0x02;
-
-		if (!match)
-			continue;
-
-		/*
-		 *	Look for a VIA device match
-		 */
-		if (f->fw_viadev) {
-			if (rif != f->fw_viadev)
-				continue;	/* Mismatch */
-		}
-
-		/* This looks stupid, because we scan almost static
-		   list, searching for static key. However, this way seems
-		   to be only reasonable way of handling fw_via rules
-		   (btw bsd makes the same thing).
-
-		   It will not affect performance if you will follow
-		   the following simple rules:
-
-		   - if interface is aliased, ALWAYS specify fw_viadev,
-		     so that previous check will guarantee, that we will
-		     not waste time when packet arrive on another interface.
-
-		   - avoid using fw_via.s_addr if fw_via.s_addr is owned
-		     by an aliased interface.
-
-		                                                       --ANK
-		 */
-		if (f->fw_via.s_addr && rif) {
-			struct in_ifaddr *ifa;
-
-			if (rif->ip_ptr == NULL)
-				continue;	/* Mismatch */
-
-			for (ifa = ((struct in_device*)(rif->ip_ptr))->ifa_list;
-			     ifa; ifa = ifa->ifa_next) {
-				if (ifa->ifa_local == f->fw_via.s_addr)
-					goto ifa_ok;
-			}
-			continue;	/* Mismatch */
-
-		ifa_ok:;
-		}
-
-		/*
-		 *	Ok the chain addresses match.
-		 */
-
-#ifdef CONFIG_IP_ACCT
-		/*
-		 *	See if we're in accounting mode and only want to
-		 *	count incoming or outgoing packets.
-		 */
-
-		if (mode & (IP_FW_MODE_ACCT_IN|IP_FW_MODE_ACCT_OUT) &&
-		   ((mode == IP_FW_MODE_ACCT_IN && f->fw_flg&IP_FW_F_ACCTOUT) ||
-		    (mode == IP_FW_MODE_ACCT_OUT && f->fw_flg&IP_FW_F_ACCTIN)))
-			continue;
-
-#endif
-		/*
-		 * For all non-TCP packets and/or non-first fragments,
-		 * notcpsyn and notcpack will always be FALSE,
-		 * so the IP_FW_F_TCPSYN and IP_FW_F_TCPACK flags
-		 * are actually ignored for these packets.
-		 */
-
-		if((f->fw_flg&IP_FW_F_TCPSYN) && notcpsyn)
-		 	continue;
-
-		if((f->fw_flg&IP_FW_F_TCPACK) && notcpack)
-		 	continue;
-
-		f_prt=f->fw_flg&IP_FW_F_KIND;
-		if (f_prt != IP_FW_F_ALL) {
-			/*
-			 *	Specific firewall - packet's protocol
-			 *	must match firewall's.
-			 */
-
-			if (prt != f_prt)
-				continue;
-
-			if((prt==IP_FW_F_ICMP &&
-				! port_match(&f->fw_pts[0], f->fw_nsp,
-					icmp_type,f->fw_flg&IP_FW_F_SRNG)) ||
-			    !(prt==IP_FW_F_ICMP || ((match & 0x01) &&
-				port_match(&f->fw_pts[0], f->fw_nsp, src_port,
-					f->fw_flg&IP_FW_F_SRNG) &&
-				port_match(&f->fw_pts[f->fw_nsp], f->fw_ndp, dst_port,
-					f->fw_flg&IP_FW_F_DRNG)) || ((match & 0x02) &&
-				port_match(&f->fw_pts[0], f->fw_nsp, dst_port,
-					f->fw_flg&IP_FW_F_SRNG) &&
-				port_match(&f->fw_pts[f->fw_nsp], f->fw_ndp, src_port,
-					f->fw_flg&IP_FW_F_DRNG))))
-			{
-				continue;
-			}
-		}
-
-#ifdef CONFIG_IP_FIREWALL_VERBOSE
-		if (f->fw_flg & IP_FW_F_PRN)
-		{
-			char buf[16];
-
-			print_packet(pskb, src_port, dst_port, icmp_type,
-				     chain_name(chain, mode),
-				     rule_name(f, mode, buf),
-				     rif ? rif->name : "-");
-		}
-#endif
-		if (mode != IP_FW_MODE_CHK) {
-			f->fw_bcnt += ntohs((*pskb)->nh.iph->tot_len);
-			f->fw_pcnt++;
-		}
-		if (!(mode & (IP_FW_MODE_ACCT_IN|IP_FW_MODE_ACCT_OUT)))
-			break;
-	} /* Loop */
-
-	if (!(mode & (IP_FW_MODE_ACCT_IN|IP_FW_MODE_ACCT_OUT))) {
-
-		/*
-		 * We rely on policy defined in the rejecting entry or, if no match
-		 * was found, we rely on the general policy variable for this type
-		 * of firewall.
-		 */
-
-		if (f != NULL) {
-			policy = f->fw_flg;
-			tosand = f->fw_tosand;
-			tosxor = f->fw_tosxor;
-		} else {
-			tosand = 0xFF;
-			tosxor = 0x00;
-		}
-
-		if (policy & IP_FW_F_ACCEPT) {
-			/* Adjust priority and recompute checksum */
-			__u8 tos = (*pskb)->nh.iph->tos;
-
-			if (((tos & tosand) ^ tosxor) != tos) {
-				if (!skb_ip_make_writable(pskb,
-					  offsetof(struct iphdr, tos)+1))
-					goto drop_it;
-
-				(*pskb)->nh.iph->tos = (tos & tosand) ^ tosxor;
-		 		ip_send_check((*pskb)->nh.iph);
-			}
-
-#ifdef CONFIG_IP_TRANSPARENT_PROXY
-			if (policy & IP_FW_F_REDIR) {
-				if (redirport)
-					if ((*redirport = htons(f->fw_pts[f->fw_nsp+f->fw_ndp])) == 0) {
-						/* Wildcard redirection.
-						 * Note that redirport will become
-						 * 0xFFFF for non-TCP/UDP packets.
-						 */
-						*redirport = htons(dst_port);
-					}
-				answer = FW_REDIRECT;
-			} else
-#endif
-#ifdef CONFIG_IP_MASQUERADE
-			if (policy & IP_FW_F_MASQ)
-				answer = FW_MASQUERADE;
-			else
-#endif
-				answer = FW_ACCEPT;
-
-		} else if (policy & IP_FW_F_ICMPRPL)
-			answer = FW_REJECT;
-		else {
-		drop_it:
-			answer = FW_BLOCK;
-		}
-
-#ifdef CONFIG_IP_FIREWALL_NETLINK
-		if ((policy & IP_FW_F_PRN) && (answer == FW_REJECT || answer == FW_BLOCK))
-		{
-			struct sk_buff *skb = alloc_skb(128,
-					(mode == IP_FW_MODE_CHK) ?
-					GFP_KERNEL : GFP_ATOMIC);
-			if (skb) {
-				int len = min_t(unsigned int,
-					128,
-					ntohs((*pskb)->nh.iph->tot_len));
-
-				skb_put(skb, len);
-				skb_copy_bits(*pskb,
-					((char *)(*pskb)->nh.iph -
-					 (char *)(*pskb)->data),
-					skb->data, len);
-				if (netlink_post(NETLINK_FIREWALL, skb))
-					kfree_skb(skb);
-			}
-		}
-#endif
-	} else
-		/* we're doing accounting, always ok */
-		answer = 0;
-	
-	if (mode == IP_FW_MODE_CHK)
-		READ_UNLOCK(&ip_fw_lock);
-	else
-		WRITE_UNLOCK(&ip_fw_lock);
-
-	return answer;
-}
-
-
-static void zero_fw_chain(struct ip_fw *chainptr)
-{
-	struct ip_fw *ctmp=chainptr;
-	
-	WRITE_LOCK(&ip_fw_lock);
-	while(ctmp)
-	{
-		ctmp->fw_pcnt=0L;
-		ctmp->fw_bcnt=0L;
-		ctmp=ctmp->fw_next;
-	}
-	WRITE_UNLOCK(&ip_fw_lock);
-}
-
-static void free_fw_chain(struct ip_fw *volatile* chainptr)
-{
-	WRITE_LOCK(&ip_fw_lock);
-	while ( *chainptr != NULL )
-	{
-		struct ip_fw *ftmp;
-		ftmp = *chainptr;
-		*chainptr = ftmp->fw_next;
-		if (ftmp->fw_viadev
-		    && ftmp->fw_viadev != (struct net_device *)-1)
-			dev_put(ftmp->fw_viadev);
-		kfree(ftmp);
-		/* We will block in cleanup's unregister sockopt if unloaded,
-		   so this is safe. */
-		module_put(THIS_MODULE);
-	}
-	WRITE_UNLOCK(&ip_fw_lock);
-}
-
-/* Volatiles to keep some of the compiler versions amused */
-
-static int insert_in_chain(struct ip_fw *volatile* chainptr, struct ip_fw *frwl,int len)
-{
-	struct ip_fw *ftmp;
-
-	/* Are we unloading now?  We will block on nf_unregister_sockopt */
-	if (!try_module_get(THIS_MODULE))
-		return ENOPROTOOPT;
-
-	ftmp = kmalloc( sizeof(struct ip_fw), GFP_KERNEL );
-	if ( ftmp == NULL )
-	{
-#ifdef DEBUG_IP_FIREWALL
-		printk("ip_fw_ctl:  malloc said no\n");
-#endif
-		return( ENOMEM );
-	}
-
-	memcpy(ftmp, frwl, len);
-	/*
-	 *	Allow the more recent "minimise cost" flag to be
-	 *	set. [Rob van Nieuwkerk]
-	 */
-	ftmp->fw_tosand |= 0x01;
-	ftmp->fw_tosxor &= 0xFE;
-	ftmp->fw_pcnt=0L;
-	ftmp->fw_bcnt=0L;
-
-	WRITE_LOCK(&ip_fw_lock);
-
-	if ((ftmp->fw_vianame)[0]) {
-		if (!(ftmp->fw_viadev = dev_get_by_name(ftmp->fw_vianame)))
-			ftmp->fw_viadev = (struct net_device *) -1;
-	} else
-		ftmp->fw_viadev = NULL;
-
-	ftmp->fw_next = *chainptr;
-       	*chainptr=ftmp;
-	WRITE_UNLOCK(&ip_fw_lock);
-	return(0);
-}
-
-static int append_to_chain(struct ip_fw *volatile* chainptr, struct ip_fw *frwl,int len)
-{
-	struct ip_fw *ftmp;
-	struct ip_fw *chtmp=NULL;
-	struct ip_fw *volatile chtmp_prev=NULL;
-
-	/* Are we unloading now?  We will block on nf_unregister_sockopt */
-	if (!try_module_get(THIS_MODULE))
-		return ENOPROTOOPT;
-
-	ftmp = kmalloc( sizeof(struct ip_fw), GFP_KERNEL );
-	if ( ftmp == NULL )
-	{
-#ifdef DEBUG_IP_FIREWALL
-		printk("ip_fw_ctl:  malloc said no\n");
-#endif
-		return( ENOMEM );
-	}
-
-	memcpy(ftmp, frwl, len);
-	/*
-	 *	Allow the more recent "minimise cost" flag to be
-	 *	set. [Rob van Nieuwkerk]
-	 */
-	ftmp->fw_tosand |= 0x01;
-	ftmp->fw_tosxor &= 0xFE;
-	ftmp->fw_pcnt=0L;
-	ftmp->fw_bcnt=0L;
-
-	ftmp->fw_next = NULL;
-
-	WRITE_LOCK(&ip_fw_lock);
-
-	if ((ftmp->fw_vianame)[0]) {
-		if (!(ftmp->fw_viadev = dev_get_by_name(ftmp->fw_vianame)))
-			ftmp->fw_viadev = (struct net_device *) -1;
-	} else
-		ftmp->fw_viadev = NULL;
-
-	chtmp_prev=NULL;
-	for (chtmp=*chainptr;chtmp!=NULL;chtmp=chtmp->fw_next)
-		chtmp_prev=chtmp;
-
-	if (chtmp_prev)
-		chtmp_prev->fw_next=ftmp;
-	else
-        	*chainptr=ftmp;
-	WRITE_UNLOCK(&ip_fw_lock);
-	return(0);
-}
-
-static int del_from_chain(struct ip_fw *volatile*chainptr, struct ip_fw *frwl)
-{
-	struct ip_fw 	*ftmp,*ltmp;
-	unsigned short	tport1,tport2,tmpnum;
-	char		matches,was_found;
-
-	WRITE_LOCK(&ip_fw_lock);
-
-	ftmp=*chainptr;
-
-	if ( ftmp == NULL )
-	{
-#ifdef DEBUG_IP_FIREWALL
-		printk("ip_fw_ctl:  chain is empty\n");
-#endif
-		WRITE_UNLOCK(&ip_fw_lock);
-		return( EINVAL );
-	}
-
-	ltmp=NULL;
-	was_found=0;
-
-	while( !was_found && ftmp != NULL )
-	{
-		matches=1;
-		if (ftmp->fw_src.s_addr!=frwl->fw_src.s_addr
-		     ||  ftmp->fw_dst.s_addr!=frwl->fw_dst.s_addr
-		     ||  ftmp->fw_smsk.s_addr!=frwl->fw_smsk.s_addr
-		     ||  ftmp->fw_dmsk.s_addr!=frwl->fw_dmsk.s_addr
-		     ||  ftmp->fw_via.s_addr!=frwl->fw_via.s_addr
-		     ||  ftmp->fw_flg!=frwl->fw_flg)
-        		matches=0;
-
-		tport1=ftmp->fw_nsp+ftmp->fw_ndp;
-		tport2=frwl->fw_nsp+frwl->fw_ndp;
-		if (tport1!=tport2)
-		        matches=0;
-		else if (tport1!=0)
-		{
-			for (tmpnum=0;tmpnum < tport1 && tmpnum < IP_FW_MAX_PORTS;tmpnum++)
-        		if (ftmp->fw_pts[tmpnum]!=frwl->fw_pts[tmpnum])
-				matches=0;
-		}
-		if (strncmp(ftmp->fw_vianame, frwl->fw_vianame, IFNAMSIZ))
-		        matches=0;
-		if(matches)
-		{
-			was_found=1;
-			if (ftmp->fw_viadev
-			    && ftmp->fw_viadev != (struct net_device *)-1)
-				dev_put(ftmp->fw_viadev);
-			if (ltmp)
-			{
-				ltmp->fw_next=ftmp->fw_next;
-				kfree(ftmp);
-				ftmp=ltmp->fw_next;
-        		}
-      			else
-      			{
-      				*chainptr=ftmp->fw_next;
-	 			kfree(ftmp);
-				ftmp=*chainptr;
-			}
-		}
-		else
-		{
-			ltmp = ftmp;
-			ftmp = ftmp->fw_next;
-		 }
-	}
-	WRITE_UNLOCK(&ip_fw_lock);
-	if (was_found) {
-		/* We will block in cleanup's unregister sockopt if unloaded,
-		   so this is safe. */
-		module_put(THIS_MODULE);
-		return 0;
-	} else
-		return(EINVAL);
-}
-
-#endif  /* CONFIG_IP_ACCT || CONFIG_IP_FIREWALL */
-
-struct ip_fw *check_ipfw_struct(struct ip_fw *frwl, int len)
-{
-
-	if ( len != sizeof(struct ip_fw) )
-	{
-#ifdef DEBUG_IP_FIREWALL
-		printk("ip_fw_ctl: len=%d, want %d\n",len, sizeof(struct ip_fw));
-#endif
-		return(NULL);
-	}
-
-	if ( (frwl->fw_flg & ~IP_FW_F_MASK) != 0 )
-	{
-#ifdef DEBUG_IP_FIREWALL
-		printk("ip_fw_ctl: undefined flag bits set (flags=%x)\n",
-			frwl->fw_flg);
-#endif
-		return(NULL);
-	}
-
-#ifndef CONFIG_IP_TRANSPARENT_PROXY
-	if (frwl->fw_flg & IP_FW_F_REDIR) {
-#ifdef DEBUG_IP_FIREWALL
-		printk("ip_fw_ctl: unsupported flag IP_FW_F_REDIR\n");
-#endif
-		return(NULL);
-	}
-#endif
-
-#ifndef CONFIG_IP_MASQUERADE
-	if (frwl->fw_flg & IP_FW_F_MASQ) {
-#ifdef DEBUG_IP_FIREWALL
-		printk("ip_fw_ctl: unsupported flag IP_FW_F_MASQ\n");
-#endif
-		return(NULL);
-	}
-#endif
-
-	if ( (frwl->fw_flg & IP_FW_F_SRNG) && frwl->fw_nsp < 2 )
-	{
-#ifdef DEBUG_IP_FIREWALL
-		printk("ip_fw_ctl: src range set but fw_nsp=%d\n",
-			frwl->fw_nsp);
-#endif
-		return(NULL);
-	}
-
-	if ( (frwl->fw_flg & IP_FW_F_DRNG) && frwl->fw_ndp < 2 )
-	{
-#ifdef DEBUG_IP_FIREWALL
-		printk("ip_fw_ctl: dst range set but fw_ndp=%d\n",
-			frwl->fw_ndp);
-#endif
-		return(NULL);
-	}
-
-	if ( frwl->fw_nsp + frwl->fw_ndp > (frwl->fw_flg & IP_FW_F_REDIR ? IP_FW_MAX_PORTS - 1 : IP_FW_MAX_PORTS) )
-	{
-#ifdef DEBUG_IP_FIREWALL
-		printk("ip_fw_ctl: too many ports (%d+%d)\n",
-			frwl->fw_nsp,frwl->fw_ndp);
-#endif
-		return(NULL);
-	}
-
-	return frwl;
-}
-
-
-
-
-#ifdef CONFIG_IP_ACCT
-
-int ip_acct_ctl(int stage, void *m, int len)
-{
-	if ( stage == IP_ACCT_FLUSH )
-	{
-		free_fw_chain(&ip_acct_chain);
-		return(0);
-	}
-	if ( stage == IP_ACCT_ZERO )
-	{
-		zero_fw_chain(ip_acct_chain);
-		return(0);
-	}
-	if ( stage == IP_ACCT_INSERT || stage == IP_ACCT_APPEND ||
-	  				stage == IP_ACCT_DELETE )
-	{
-		struct ip_fw *frwl;
-
-		if (!(frwl=check_ipfw_struct(m,len)))
-			return (EINVAL);
-
-		switch (stage)
-		{
-			case IP_ACCT_INSERT:
-				return( insert_in_chain(&ip_acct_chain,frwl,len));
-			case IP_ACCT_APPEND:
-				return( append_to_chain(&ip_acct_chain,frwl,len));
-		    	case IP_ACCT_DELETE:
-				return( del_from_chain(&ip_acct_chain,frwl));
-			default:
-				/*
- 				 *	Should be panic but... (Why ??? - AC)
-				 */
-#ifdef DEBUG_IP_FIREWALL
-				printk("ip_acct_ctl:  unknown request %d\n",stage);
-#endif
-				return(EINVAL);
-		}
-	}
-#ifdef DEBUG_IP_FIREWALL
-	printk("ip_acct_ctl:  unknown request %d\n",stage);
-#endif
-	return(EINVAL);
-}
-#endif
-
-#ifdef CONFIG_IP_FIREWALL
-int ip_fw_ctl(int stage, void *m, int len)
-{
-	int cmd, fwtype;
-
-	cmd = stage & IP_FW_COMMAND;
-	fwtype = (stage & IP_FW_TYPE) >> IP_FW_SHIFT;
-
-	if ( cmd == IP_FW_FLUSH )
-	{
-		free_fw_chain(chains[fwtype]);
-		return(0);
-	}
-
-	if ( cmd == IP_FW_ZERO )
-	{
-		zero_fw_chain(*chains[fwtype]);
-		return(0);
-	}
-
-	if ( cmd == IP_FW_POLICY )
-	{
-		int *tmp_policy_ptr;
-		tmp_policy_ptr=(int *)m;
-		*policies[fwtype] = *tmp_policy_ptr;
-		return 0;
-	}
-
-	if ( cmd == IP_FW_CHECK )
-	{
-		struct sk_buff *tmp_skb;
-		struct net_device *viadev;
-		struct ip_fwpkt *ipfwp;
-		struct iphdr *ip;
-		int hdrlen, ret;
-
-		hdrlen = sizeof(struct ip_fwpkt) -
-			sizeof(struct in_addr) -
-			IFNAMSIZ;
-
-		if ( len != sizeof(struct ip_fwpkt) )
-		{
-#ifdef DEBUG_IP_FIREWALL
-			printk("ip_fw_ctl: length=%d, expected %d\n",
-				len, sizeof(struct ip_fwpkt));
-#endif
-			return( EINVAL );
-		}
-
-	 	ipfwp = (struct ip_fwpkt *)m;
-	 	ip = &(ipfwp->fwp_iph);
-
-		if ( !(viadev = dev_get_by_name(ipfwp->fwp_vianame)) ) {
-#ifdef DEBUG_IP_FIREWALL
-			printk("ip_fw_ctl: invalid device \"%s\"\n", ipfwp->fwp_vianame);
-#endif
-			return(EINVAL);
-		} else if ( ip->ihl != sizeof(struct iphdr) / sizeof(int)) {
-#ifdef DEBUG_IP_FIREWALL
-			printk("ip_fw_ctl: ip->ihl=%d, want %d\n",ip->ihl,
-					sizeof(struct iphdr)/sizeof(int));
-#endif
-			dev_put(viadev);
-			return(EINVAL);
-		}
-
-		/* Fix this one up by hand, who knows how many
-		 * tools will break if we start to barf on this.
-		 */
-		if (ntohs(ip->tot_len) > hdrlen)
-			ip->tot_len = htons(hdrlen);
-
-		if ((tmp_skb = alloc_skb(hdrlen, GFP_ATOMIC)) == NULL) {
-#ifdef DEBUG_IP_FIREWALL
-			printk("ip_fw_ctl: tmp_skb alloc failure\n");
-#endif
-			dev_put(viadev);
-			return(EFAULT);
-		}
-		skb_reserve(tmp_skb, hdrlen);
-		skb_push(tmp_skb, hdrlen);
-		memcpy(tmp_skb->data, ip, hdrlen);
-
-		ret = ip_fw_chk(&tmp_skb, viadev, NULL, *chains[fwtype],
-				*policies[fwtype], IP_FW_MODE_CHK);
-
-		kfree_skb(tmp_skb);
-		dev_put(viadev);
-
-		switch (ret) {
-			case FW_ACCEPT:
-				return(0);
-	    		case FW_REDIRECT:
-				return(ECONNABORTED);
-	    		case FW_MASQUERADE:
-				return(ECONNRESET);
-	    		case FW_REJECT:
-				return(ECONNREFUSED);
-			default: /* FW_BLOCK */
-				return(ETIMEDOUT);
-		}
-	}
-
-	if ( cmd == IP_FW_MASQ_TIMEOUTS )
-		return ip_fw_masq_timeouts(m, len);
-
-/*
- *	Here we really working hard-adding new elements
- *	to blocking/forwarding chains or deleting 'em
- */
-
-	if ( cmd == IP_FW_INSERT || cmd == IP_FW_APPEND || cmd == IP_FW_DELETE )
-	{
-		struct ip_fw *frwl;
-		int fwtype;
-
-		frwl=check_ipfw_struct(m,len);
-		if (frwl==NULL)
-			return (EINVAL);
-		fwtype = (stage & IP_FW_TYPE) >> IP_FW_SHIFT;
-
-		switch (cmd)
-		{
-			case IP_FW_INSERT:
-				return(insert_in_chain(chains[fwtype],frwl,len));
-			case IP_FW_APPEND:
-				return(append_to_chain(chains[fwtype],frwl,len));
-			case IP_FW_DELETE:
-				return(del_from_chain(chains[fwtype],frwl));
-			default:
-			/*
-	 		 *	Should be panic but... (Why are BSD people panic obsessed ??)
-			 */
-#ifdef DEBUG_IP_FIREWALL
-				printk("ip_fw_ctl:  unknown request %d\n",stage);
-#endif
-				return(EINVAL);
-		}
-	}
-
-#ifdef DEBUG_IP_FIREWALL
-	printk("ip_fw_ctl:  unknown request %d\n",stage);
-#endif
-	return(ENOPROTOOPT);
-}
-#endif /* CONFIG_IP_FIREWALL */
-
-#if defined(CONFIG_IP_FIREWALL) || defined(CONFIG_IP_ACCT)
-static int ip_chain_procinfo(int stage, char *buffer, char **start,
-			     off_t offset, int length)
-{
-	off_t pos=0, begin=0;
-	struct ip_fw *i;
-	int len, p;
-	int last_len = 0;
-
-
-	switch(stage)
-	{
-#ifdef CONFIG_IP_FIREWALL
-		case IP_FW_IN:
-			i = ip_fw_in_chain;
-			len=sprintf(buffer, "IP firewall input rules, default %d\n",
-				ip_fw_in_policy);
-			break;
-		case IP_FW_OUT:
-			i = ip_fw_out_chain;
-			len=sprintf(buffer, "IP firewall output rules, default %d\n",
-				ip_fw_out_policy);
-			break;
-		case IP_FW_FWD:
-			i = ip_fw_fwd_chain;
-			len=sprintf(buffer, "IP firewall forward rules, default %d\n",
-				ip_fw_fwd_policy);
-			break;
-#endif
-#ifdef CONFIG_IP_ACCT
-		case IP_FW_ACCT:
-			i = ip_acct_chain;
-			len=sprintf(buffer,"IP accounting rules\n");
-			break;
-#endif
-		default:
-			/* this should never be reached, but safety first... */
-			i = NULL;
-			len=0;
-			break;
-	}
-
-	READ_LOCK(&ip_fw_lock);
-
-	while(i!=NULL)
-	{
-		len+=sprintf(buffer+len,"%08X/%08X->%08X/%08X %.16s %08X %X ",
-			ntohl(i->fw_src.s_addr),ntohl(i->fw_smsk.s_addr),
-			ntohl(i->fw_dst.s_addr),ntohl(i->fw_dmsk.s_addr),
-			(i->fw_vianame)[0] ? i->fw_vianame : "-",
-			ntohl(i->fw_via.s_addr), i->fw_flg);
-		/* 10 is enough for a 32 bit box but the counters are 64bit on
-		   the Alpha and Ultrapenguin */
-		len+=sprintf(buffer+len,"%u %u %-20lu %-20lu",
-			i->fw_nsp,i->fw_ndp, i->fw_pcnt,i->fw_bcnt);
-		for (p = 0; p < IP_FW_MAX_PORTS; p++)
-			len+=sprintf(buffer+len, " %u", i->fw_pts[p]);
-		len+=sprintf(buffer+len, " A%02X X%02X", i->fw_tosand, i->fw_tosxor);
-		buffer[len++]='\n';
-		buffer[len]='\0';
-		pos=begin+len;
-		if(pos<offset)
-		{
-			len=0;
-			begin=pos;
-		}
-		else if(pos>offset+length)
-		{
-			len = last_len;
-			break;
-		}
-		last_len = len;
-		i=i->fw_next;
-	}
-	READ_UNLOCK(&ip_fw_lock);
-	*start=buffer+(offset-begin);
-	len-=(offset-begin);
-	if(len>length)
-		len=length;
-	return len;
-}
-#endif
-
-#ifdef CONFIG_IP_ACCT
-static int ip_acct_procinfo(char *buffer, char **start, off_t offset,
-			    int length)
-{
-	return ip_chain_procinfo(IP_FW_ACCT, buffer,start, offset,length);
-}
-#endif
-
-#ifdef CONFIG_IP_FIREWALL
-static int ip_fw_in_procinfo(char *buffer, char **start, off_t offset,
-			      int length)
-{
-	return ip_chain_procinfo(IP_FW_IN, buffer,start,offset,length);
-}
-
-static int ip_fw_out_procinfo(char *buffer, char **start, off_t offset,
-			      int length)
-{
-	return ip_chain_procinfo(IP_FW_OUT, buffer,start,offset,length);
-}
-
-static int ip_fw_fwd_procinfo(char *buffer, char **start, off_t offset,
-			      int length)
-{
-	return ip_chain_procinfo(IP_FW_FWD, buffer,start,offset,length);
-}
-#endif
-
-
-#ifdef CONFIG_IP_FIREWALL
-/*
- *	Interface to the generic firewall chains.
- */
-
-int ipfw_input_check(struct firewall_ops *this, int pf,
-		     struct net_device *dev, void *arg,
-		     struct sk_buff **pskb)
-{
-	return ip_fw_chk(pskb, dev, arg, ip_fw_in_chain, ip_fw_in_policy,
-			 IP_FW_MODE_FW);
-}
-
-int ipfw_output_check(struct firewall_ops *this, int pf,
-		      struct net_device *dev, void *arg,
-		      struct sk_buff **pskb)
-{
-	return ip_fw_chk(pskb, dev, arg, ip_fw_out_chain, ip_fw_out_policy,
-			 IP_FW_MODE_FW);
-}
-
-int ipfw_forward_check(struct firewall_ops *this, int pf,
-		       struct net_device *dev, void *arg,
-		       struct sk_buff **pskb)
-{
-	return ip_fw_chk(pskb, dev, arg, ip_fw_fwd_chain, ip_fw_fwd_policy,
-			 IP_FW_MODE_FW);
-}
-
-#ifdef CONFIG_IP_ACCT
-int ipfw_acct_in(struct firewall_ops *this, int pf, struct net_device *dev,
-		 void *arg, struct sk_buff **pskb)
-{
-	return ip_fw_chk(pskb,dev,NULL,ip_acct_chain,0,IP_FW_MODE_ACCT_IN);
-}
-
-int ipfw_acct_out(struct firewall_ops *this, int pf, struct net_device *dev,
-		  void *arg, struct sk_buff **pskb)
-{
-	return ip_fw_chk(pskb,dev,NULL,ip_acct_chain,0,IP_FW_MODE_ACCT_OUT);
-}
-#endif
-
-struct firewall_ops ipfw_ops = {
-	.fw_forward	=	ipfw_forward_check,
-	.fw_input	=	ipfw_input_check,
-	.fw_output	=	ipfw_output_check,
-#ifdef CONFIG_IP_ACCT
-	.fw_acct_in	=	ipfw_acct_in,
-	.fw_acct_out	=	ipfw_acct_out,
-#endif
-};
-
-#endif
-
-#if defined(CONFIG_IP_ACCT) || defined(CONFIG_IP_FIREWALL)
-
-int ipfw_device_event(struct notifier_block *this, unsigned long event, void *ptr)
-{
-	struct net_device *dev=ptr;
-	char *devname = dev->name;
-	struct ip_fw *fw;
-	int chn;
-
-	WRITE_LOCK(&ip_fw_lock);
-
-	if (event == NETDEV_UP) {
-		for (chn = 0; chn < IP_FW_CHAINS; chn++)
-			for (fw = *chains[chn]; fw; fw = fw->fw_next)
-				if ((fw->fw_vianame)[0] && !strncmp(devname,
-					    fw->fw_vianame, IFNAMSIZ)) {
-					dev_hold(dev);
-					fw->fw_viadev = dev;
-				}
-	} else if (event == NETDEV_DOWN) {
-		for (chn = 0; chn < IP_FW_CHAINS; chn++)
-			for (fw = *chains[chn]; fw; fw = fw->fw_next)
-				/* we could compare just the pointers ... */
-				if ((fw->fw_vianame)[0] && !strncmp(devname,
-						    fw->fw_vianame, IFNAMSIZ)){
-					if (fw->fw_viadev
-					    && fw->fw_viadev != (struct net_device *)-1)
-						dev_put(fw->fw_viadev);
-					fw->fw_viadev = (struct net_device*)-1;
-				}
-	}
-
-	WRITE_UNLOCK(&ip_fw_lock);
-	return NOTIFY_DONE;
-}
-
-static struct notifier_block ipfw_dev_notifier = {
-	.notifier_call	=	ipfw_device_event,
-};
-
-#endif
-
-int ipfw_init_or_cleanup(int init)
-{
-	int ret = 0;
-
-	if (!init)
-		goto cleanup;
-
-	ret = register_firewall(PF_INET, &ipfw_ops);
-	if (ret < 0)
-		goto cleanup_nothing;
-
-#ifdef CONFIG_IP_ACCT
-	proc_net_create("ip_acct", S_IFREG | S_IRUGO | S_IWUSR, ip_acct_procinfo);
-#endif
-	proc_net_create("ip_input", S_IFREG | S_IRUGO | S_IWUSR, ip_fw_in_procinfo);
-	proc_net_create("ip_output", S_IFREG | S_IRUGO | S_IWUSR, ip_fw_out_procinfo);
-	proc_net_create("ip_forward", S_IFREG | S_IRUGO | S_IWUSR, ip_fw_fwd_procinfo);
-
-	/* Register for device up/down reports */
-	register_netdevice_notifier(&ipfw_dev_notifier);
-
-#ifdef CONFIG_IP_FIREWALL_NETLINK
-	ipfwsk = netlink_kernel_create(NETLINK_FIREWALL, NULL);
-#endif
-	return ret;
-
- cleanup:
-#ifdef CONFIG_IP_FIREWALL_NETLINK
-	sock_release(ipfwsk->sk_socket);
-#endif
-	unregister_netdevice_notifier(&ipfw_dev_notifier);
-
-#ifdef CONFIG_IP_ACCT
-	proc_net_remove("ip_acct");
-#endif
-	proc_net_remove("ip_input");
-	proc_net_remove("ip_output");
-	proc_net_remove("ip_forward");
-
-	free_fw_chain(chains[IP_FW_FWD]);
-	free_fw_chain(chains[IP_FW_IN]);
-	free_fw_chain(chains[IP_FW_OUT]);
-	free_fw_chain(chains[IP_FW_ACCT]);
-
-	unregister_firewall(PF_INET, &ipfw_ops);
-
- cleanup_nothing:
-	return ret;
-}
diff -Nru a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c
--- a/net/ipv4/netfilter/ipt_CLUSTERIP.c	2005-03-01 23:38:52 -08:00
+++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c	2005-03-01 23:38:52 -08:00
@@ -29,6 +29,7 @@
 #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"
 
@@ -66,7 +67,7 @@
 
 /* clusterip_lock protects the clusterip_configs list _AND_ the configurable
  * data within all structurses (num_local_nodes, local_nodes[]) */
-DECLARE_RWLOCK(clusterip_lock);
+static DECLARE_RWLOCK(clusterip_lock);
 
 #ifdef CONFIG_PROC_FS
 static struct file_operations clusterip_proc_fops;
diff -Nru a/net/ipv4/netfilter/ipt_ECN.c b/net/ipv4/netfilter/ipt_ECN.c
--- a/net/ipv4/netfilter/ipt_ECN.c	2005-03-01 23:39:17 -08:00
+++ b/net/ipv4/netfilter/ipt_ECN.c	2005-03-01 23:39:17 -08:00
@@ -52,44 +52,41 @@
 static inline int
 set_ect_tcp(struct sk_buff **pskb, const struct ipt_ECN_info *einfo, int inward)
 {
-	struct tcphdr _tcph, *th;
+	struct tcphdr _tcph, *tcph;
 	u_int16_t diffs[2];
 
 	/* Not enought header? */
-	th = skb_header_pointer(*pskb, (*pskb)->nh.iph->ihl*4,
-				sizeof(_tcph), &_tcph);
-	if (th == NULL)
+	tcph = skb_header_pointer(*pskb, (*pskb)->nh.iph->ihl*4,
+				  sizeof(_tcph), &_tcph);
+	if (!tcph)
 		return 0;
 
-	diffs[0] = ((u_int16_t *)th)[6];
-	if (einfo->operation & IPT_ECN_OP_SET_ECE)
-		th->ece = einfo->proto.tcp.ece;
+	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 (einfo->operation & IPT_ECN_OP_SET_CWR)
-		th->cwr = einfo->proto.tcp.cwr;
-	diffs[1] = ((u_int16_t *)&th)[6];
+	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;
 
-	/* Only mangle if it's changed. */
-	if (diffs[0] != diffs[1]) {
-		diffs[0] = diffs[0] ^ 0xFFFF;
-		if (!skb_ip_make_writable(pskb,
-					  (*pskb)->nh.iph->ihl*4+sizeof(_tcph)))
+	diffs[0] = ((u_int16_t *)tcph)[6];
+	if (einfo->operation & IPT_ECN_OP_SET_ECE)
+		tcph->ece = einfo->proto.tcp.ece;
+	if (einfo->operation & IPT_ECN_OP_SET_CWR)
+		tcph->cwr = einfo->proto.tcp.cwr;
+	diffs[1] = ((u_int16_t *)tcph)[6];
+	diffs[0] = diffs[0] ^ 0xFFFF;
+
+	if ((*pskb)->ip_summed != CHECKSUM_HW)
+		tcph->check = csum_fold(csum_partial((char *)diffs,
+						     sizeof(diffs),
+						     tcph->check^0xFFFF));
+	else
+		if (skb_checksum_help(*pskb, inward))
 			return 0;
-
-		if (th != &_tcph)
-			memcpy(&_tcph, th, sizeof(_tcph));
-
-		if ((*pskb)->ip_summed != CHECKSUM_HW)
-			_tcph.check = csum_fold(csum_partial((char *)diffs,
-							     sizeof(diffs),
-							     _tcph.check^0xFFFF));
-		memcpy((*pskb)->data + (*pskb)->nh.iph->ihl*4,
-		       &_tcph, sizeof(_tcph));
-		if ((*pskb)->ip_summed == CHECKSUM_HW)
-			if (skb_checksum_help(*pskb, inward))
-				return 0;
-		(*pskb)->nfcache |= NFC_ALTERED;
-	}
+	(*pskb)->nfcache |= NFC_ALTERED;
 	return 1;
 }
 
@@ -148,7 +145,7 @@
 	}
 
 	if ((einfo->operation & (IPT_ECN_OP_SET_ECE|IPT_ECN_OP_SET_CWR))
-	    && e->ip.proto != IPPROTO_TCP) {
+	    && (e->ip.proto != IPPROTO_TCP || (e->ip.invflags & IPT_INV_PROTO))) {
 		printk(KERN_WARNING "ECN: cannot use TCP operations on a "
 		       "non-tcp rule\n");
 		return 0;
diff -Nru a/net/ipv4/netfilter/ipt_LOG.c b/net/ipv4/netfilter/ipt_LOG.c
--- a/net/ipv4/netfilter/ipt_LOG.c	2005-03-01 23:39:09 -08:00
+++ b/net/ipv4/netfilter/ipt_LOG.c	2005-03-01 23:39:09 -08:00
@@ -38,7 +38,7 @@
 #endif
 
 /* Use lock to serialize, so printks don't overlap */
-static spinlock_t log_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(log_lock);
 
 /* One level of recursion won't kill us */
 static void dump_packet(const struct ipt_log_info *info,
@@ -325,6 +325,14 @@
 	/* Max length: 10 "PROTO 255 " */
 	default:
 		printk("PROTO=%u ", ih->protocol);
+	}
+
+	/* Max length: 15 "UID=4294967295 " */
+ 	if ((info->logflags & IPT_LOG_UID) && !iphoff && skb->sk) {
+		read_lock_bh(&skb->sk->sk_callback_lock);
+		if (skb->sk->sk_socket && skb->sk->sk_socket->file)
+ 			printk("UID=%u ", skb->sk->sk_socket->file->f_uid);
+		read_unlock_bh(&skb->sk->sk_callback_lock);
 	}
 
 	/* Proto    Max log string length */
diff -Nru a/net/ipv4/netfilter/ipt_MARK.c b/net/ipv4/netfilter/ipt_MARK.c
--- a/net/ipv4/netfilter/ipt_MARK.c	2005-03-01 23:38:57 -08:00
+++ b/net/ipv4/netfilter/ipt_MARK.c	2005-03-01 23:38:57 -08:00
@@ -20,12 +20,12 @@
 MODULE_DESCRIPTION("iptables MARK modification module");
 
 static unsigned int
-target(struct sk_buff **pskb,
-       const struct net_device *in,
-       const struct net_device *out,
-       unsigned int hooknum,
-       const void *targinfo,
-       void *userinfo)
+target_v0(struct sk_buff **pskb,
+	  const struct net_device *in,
+	  const struct net_device *out,
+	  unsigned int hooknum,
+	  const void *targinfo,
+	  void *userinfo)
 {
 	const struct ipt_mark_target_info *markinfo = targinfo;
 
@@ -36,12 +36,45 @@
 	return IPT_CONTINUE;
 }
 
+static unsigned int
+target_v1(struct sk_buff **pskb,
+	  const struct net_device *in,
+	  const struct net_device *out,
+	  unsigned int hooknum,
+	  const void *targinfo,
+	  void *userinfo)
+{
+	const struct ipt_mark_target_info_v1 *markinfo = targinfo;
+	int mark = 0;
+
+	switch (markinfo->mode) {
+	case IPT_MARK_SET:
+		mark = markinfo->mark;
+		break;
+		
+	case IPT_MARK_AND:
+		mark = (*pskb)->nfmark & markinfo->mark;
+		break;
+		
+	case IPT_MARK_OR:
+		mark = (*pskb)->nfmark | markinfo->mark;
+		break;
+	}
+
+	if((*pskb)->nfmark != mark) {
+		(*pskb)->nfmark = mark;
+		(*pskb)->nfcache |= NFC_ALTERED;
+	}
+	return IPT_CONTINUE;
+}
+
+
 static int
-checkentry(const char *tablename,
-	   const struct ipt_entry *e,
-           void *targinfo,
-           unsigned int targinfosize,
-           unsigned int hook_mask)
+checkentry_v0(const char *tablename,
+	      const struct ipt_entry *e,
+	      void *targinfo,
+	      unsigned int targinfosize,
+	      unsigned int hook_mask)
 {
 	if (targinfosize != IPT_ALIGN(sizeof(struct ipt_mark_target_info))) {
 		printk(KERN_WARNING "MARK: targinfosize %u != %Zu\n",
@@ -58,21 +91,71 @@
 	return 1;
 }
 
-static struct ipt_target ipt_mark_reg = {
+static int
+checkentry_v1(const char *tablename,
+	      const struct ipt_entry *e,
+	      void *targinfo,
+	      unsigned int targinfosize,
+	      unsigned int hook_mask)
+{
+	struct ipt_mark_target_info_v1 *markinfo = targinfo;
+
+	if (targinfosize != IPT_ALIGN(sizeof(struct ipt_mark_target_info_v1))){
+		printk(KERN_WARNING "MARK: targinfosize %u != %Zu\n",
+		       targinfosize,
+		       IPT_ALIGN(sizeof(struct ipt_mark_target_info_v1)));
+		return 0;
+	}
+
+	if (strcmp(tablename, "mangle") != 0) {
+		printk(KERN_WARNING "MARK: can only be called from \"mangle\" table, not \"%s\"\n", tablename);
+		return 0;
+	}
+
+	if (markinfo->mode != IPT_MARK_SET
+	    && markinfo->mode != IPT_MARK_AND
+	    && markinfo->mode != IPT_MARK_OR) {
+		printk(KERN_WARNING "MARK: unknown mode %u\n",
+		       markinfo->mode);
+		return 0;
+	}
+
+	return 1;
+}
+
+static struct ipt_target ipt_mark_reg_v0 = {
+	.name		= "MARK",
+	.target		= target_v0,
+	.checkentry	= checkentry_v0,
+	.me		= THIS_MODULE,
+	.revision	= 0,
+};
+
+static struct ipt_target ipt_mark_reg_v1 = {
 	.name		= "MARK",
-	.target		= target,
-	.checkentry	= checkentry,
+	.target		= target_v1,
+	.checkentry	= checkentry_v1,
 	.me		= THIS_MODULE,
+	.revision	= 1,
 };
 
 static int __init init(void)
 {
-	return ipt_register_target(&ipt_mark_reg);
+	int err;
+
+	err = ipt_register_target(&ipt_mark_reg_v0);
+	if (!err) {
+		err = ipt_register_target(&ipt_mark_reg_v1);
+		if (err)
+			ipt_unregister_target(&ipt_mark_reg_v0);
+	}
+	return err;
 }
 
 static void __exit fini(void)
 {
-	ipt_unregister_target(&ipt_mark_reg);
+	ipt_unregister_target(&ipt_mark_reg_v0);
+	ipt_unregister_target(&ipt_mark_reg_v1);
 }
 
 module_init(init);
diff -Nru a/net/ipv4/netfilter/ipt_MASQUERADE.c b/net/ipv4/netfilter/ipt_MASQUERADE.c
--- a/net/ipv4/netfilter/ipt_MASQUERADE.c	2005-03-01 23:39:06 -08:00
+++ b/net/ipv4/netfilter/ipt_MASQUERADE.c	2005-03-01 23:39:06 -08:00
@@ -43,7 +43,7 @@
 		 unsigned int targinfosize,
 		 unsigned int hook_mask)
 {
-	const struct ip_nat_multi_range *mr = targinfo;
+	const struct ip_nat_multi_range_compat *mr = targinfo;
 
 	if (strcmp(tablename, "nat") != 0) {
 		DEBUGP("masquerade_check: bad table `%s'.\n", tablename);
@@ -79,8 +79,8 @@
 {
 	struct ip_conntrack *ct;
 	enum ip_conntrack_info ctinfo;
-	const struct ip_nat_multi_range *mr;
-	struct ip_nat_multi_range newrange;
+	const struct ip_nat_multi_range_compat *mr;
+	struct ip_nat_range newrange;
 	struct rtable *rt;
 	u_int32_t newsrc;
 
@@ -108,17 +108,17 @@
 	WRITE_UNLOCK(&masq_lock);
 
 	/* Transfer from original range. */
-	newrange = ((struct ip_nat_multi_range)
-		{ 1, { { mr->range[0].flags | IP_NAT_RANGE_MAP_IPS,
-			 newsrc, newsrc,
-			 mr->range[0].min, mr->range[0].max } } });
+	newrange = ((struct ip_nat_range)
+		{ mr->range[0].flags | IP_NAT_RANGE_MAP_IPS,
+		  newsrc, newsrc,
+		  mr->range[0].min, mr->range[0].max });
 
 	/* Hand modified range to generic setup. */
 	return ip_nat_setup_info(ct, &newrange, hooknum);
 }
 
 static inline int
-device_cmp(const struct ip_conntrack *i, void *ifindex)
+device_cmp(struct ip_conntrack *i, void *ifindex)
 {
 	int ret;
 
@@ -141,7 +141,7 @@
 		   and forget them. */
 		IP_NF_ASSERT(dev->ifindex != 0);
 
-		ip_ct_selective_cleanup(device_cmp, (void *)(long)dev->ifindex);
+		ip_ct_iterate_cleanup(device_cmp, (void *)(long)dev->ifindex);
 	}
 
 	return NOTIFY_DONE;
@@ -159,7 +159,7 @@
 		   and forget them. */
 		IP_NF_ASSERT(dev->ifindex != 0);
 
-		ip_ct_selective_cleanup(device_cmp, (void *)(long)dev->ifindex);
+		ip_ct_iterate_cleanup(device_cmp, (void *)(long)dev->ifindex);
 	}
 
 	return NOTIFY_DONE;
diff -Nru a/net/ipv4/netfilter/ipt_NETMAP.c b/net/ipv4/netfilter/ipt_NETMAP.c
--- a/net/ipv4/netfilter/ipt_NETMAP.c	2005-03-01 23:38:57 -08:00
+++ b/net/ipv4/netfilter/ipt_NETMAP.c	2005-03-01 23:38:57 -08:00
@@ -36,7 +36,7 @@
       unsigned int targinfosize,
       unsigned int hook_mask)
 {
-	const struct ip_nat_multi_range *mr = targinfo;
+	const struct ip_nat_multi_range_compat *mr = targinfo;
 
 	if (strcmp(tablename, "nat") != 0) {
 		DEBUGP(MODULENAME":check: bad table `%s'.\n", tablename);
@@ -72,8 +72,8 @@
 	struct ip_conntrack *ct;
 	enum ip_conntrack_info ctinfo;
 	u_int32_t new_ip, netmask;
-	const struct ip_nat_multi_range *mr = targinfo;
-	struct ip_nat_multi_range newrange;
+	const struct ip_nat_multi_range_compat *mr = targinfo;
+	struct ip_nat_range newrange;
 
 	IP_NF_ASSERT(hooknum == NF_IP_PRE_ROUTING
 		     || hooknum == NF_IP_POST_ROUTING);
@@ -87,10 +87,10 @@
 		new_ip = (*pskb)->nh.iph->saddr & ~netmask;
 	new_ip |= mr->range[0].min_ip & netmask;
 
-	newrange = ((struct ip_nat_multi_range)
-	{ 1, { { mr->range[0].flags | IP_NAT_RANGE_MAP_IPS,
-		 new_ip, new_ip,
-		 mr->range[0].min, mr->range[0].max } } });
+	newrange = ((struct ip_nat_range)
+		{ mr->range[0].flags | IP_NAT_RANGE_MAP_IPS,
+		  new_ip, new_ip,
+		  mr->range[0].min, mr->range[0].max });
 
 	/* Hand modified range to generic setup. */
 	return ip_nat_setup_info(ct, &newrange, hooknum);
diff -Nru a/net/ipv4/netfilter/ipt_REDIRECT.c b/net/ipv4/netfilter/ipt_REDIRECT.c
--- a/net/ipv4/netfilter/ipt_REDIRECT.c	2005-03-01 23:38:55 -08:00
+++ b/net/ipv4/netfilter/ipt_REDIRECT.c	2005-03-01 23:38:55 -08:00
@@ -38,7 +38,7 @@
 	       unsigned int targinfosize,
 	       unsigned int hook_mask)
 {
-	const struct ip_nat_multi_range *mr = targinfo;
+	const struct ip_nat_multi_range_compat *mr = targinfo;
 
 	if (strcmp(tablename, "nat") != 0) {
 		DEBUGP("redirect_check: bad table `%s'.\n", table);
@@ -74,8 +74,8 @@
 	struct ip_conntrack *ct;
 	enum ip_conntrack_info ctinfo;
 	u_int32_t newdst;
-	const struct ip_nat_multi_range *mr = targinfo;
-	struct ip_nat_multi_range newrange;
+	const struct ip_nat_multi_range_compat *mr = targinfo;
+	struct ip_nat_range newrange;
 
 	IP_NF_ASSERT(hooknum == NF_IP_PRE_ROUTING
 		     || hooknum == NF_IP_LOCAL_OUT);
@@ -99,10 +99,10 @@
 	}
 
 	/* Transfer from original range. */
-	newrange = ((struct ip_nat_multi_range)
-		{ 1, { { mr->range[0].flags | IP_NAT_RANGE_MAP_IPS,
-			 newdst, newdst,
-			 mr->range[0].min, mr->range[0].max } } });
+	newrange = ((struct ip_nat_range)
+		{ mr->range[0].flags | IP_NAT_RANGE_MAP_IPS,
+		  newdst, newdst,
+		  mr->range[0].min, mr->range[0].max });
 
 	/* Hand modified range to generic setup. */
 	return ip_nat_setup_info(ct, &newrange, hooknum);
diff -Nru a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c
--- a/net/ipv4/netfilter/ipt_REJECT.c	2005-03-01 23:39:09 -08:00
+++ b/net/ipv4/netfilter/ipt_REJECT.c	2005-03-01 23:39:09 -08:00
@@ -223,7 +223,6 @@
 static void send_unreach(struct sk_buff *skb_in, int code)
 {
 	struct iphdr *iph;
-	struct udphdr *udph;
 	struct icmphdr *icmph;
 	struct sk_buff *nskb;
 	u32 saddr;
@@ -257,26 +256,13 @@
 	if (skb_in->len < skb_in->nh.iph->ihl*4 + 8)
 		return;
 
-	/* if UDP checksum is set, verify it's correct */
-	if (iph->protocol == IPPROTO_UDP
-	    && skb_in->tail-(u8*)iph >= sizeof(struct udphdr)) {
-		int datalen = skb_in->len - (iph->ihl<<2);
-		udph = (struct udphdr *)((char *)iph + (iph->ihl<<2));
-		if (udph->check
-		    && csum_tcpudp_magic(iph->saddr, iph->daddr,
-		                         datalen, IPPROTO_UDP,
-		                         csum_partial((char *)udph, datalen,
-		                                      0)) != 0)
-			return;
-	}
-
 	/* If we send an ICMP error to an ICMP error a mess would result.. */
-	if (iph->protocol == IPPROTO_ICMP
-	    && skb_in->tail-(u8*)iph >= sizeof(struct icmphdr)) {
-		icmph = (struct icmphdr *)((char *)iph + (iph->ihl<<2));
+	if (iph->protocol == IPPROTO_ICMP) {
+		struct icmphdr ihdr;
 
-		if (skb_copy_bits(skb_in, skb_in->nh.iph->ihl*4,
-				  icmph, sizeof(*icmph)) < 0)
+		icmph = skb_header_pointer(skb_in, skb_in->nh.iph->ihl*4,
+					   sizeof(ihdr), &ihdr);
+		if (!icmph)
 			return;
 
 		/* Between echo-reply (0) and timestamp (13),
diff -Nru a/net/ipv4/netfilter/ipt_SAME.c b/net/ipv4/netfilter/ipt_SAME.c
--- a/net/ipv4/netfilter/ipt_SAME.c	2005-03-01 23:39:07 -08:00
+++ b/net/ipv4/netfilter/ipt_SAME.c	2005-03-01 23:39:07 -08:00
@@ -149,8 +149,8 @@
 	struct ip_conntrack *ct;
 	enum ip_conntrack_info ctinfo;
 	u_int32_t tmpip, aindex, new_ip;
-	const struct ipt_same_info *mr = targinfo;
-	struct ip_nat_multi_range newrange;
+	const struct ipt_same_info *same = targinfo;
+	struct ip_nat_range newrange;
 	const struct ip_conntrack_tuple *t;
 
 	IP_NF_ASSERT(hooknum == NF_IP_PRE_ROUTING ||
@@ -161,17 +161,17 @@
 
 	/* Base new source on real src ip and optionally dst ip,
 	   giving some hope for consistency across reboots.
-	   Here we calculate the index in mr->iparray which
+	   Here we calculate the index in same->iparray which
 	   holds the ipaddress we should use */
 	
 	tmpip = ntohl(t->src.ip);
 
-	if (!(mr->info & IPT_SAME_NODST))
+	if (!(same->info & IPT_SAME_NODST))
 		tmpip += ntohl(t->dst.ip);
 	
-	aindex = tmpip % mr->ipnum;
-		
-	new_ip = htonl(mr->iparray[aindex]);
+	aindex = tmpip % same->ipnum;
+
+	new_ip = htonl(same->iparray[aindex]);
 
 	DEBUGP("ipt_SAME: src=%u.%u.%u.%u dst=%u.%u.%u.%u, "
 			"new src=%u.%u.%u.%u\n",
@@ -179,10 +179,10 @@
 			NIPQUAD(new_ip));
 
 	/* Transfer from original range. */
-	newrange = ((struct ip_nat_multi_range)
-		{ 1, { { mr->range[0].flags | IP_NAT_RANGE_MAP_IPS,
-			 new_ip, new_ip,
-			 mr->range[0].min, mr->range[0].max } } });
+	newrange = ((struct ip_nat_range)
+		{ same->range[0].flags, new_ip, new_ip,
+		  /* FIXME: Use ports from correct range! */
+		  same->range[0].min, same->range[0].max });
 
 	/* Hand modified range to generic setup. */
 	return ip_nat_setup_info(ct, &newrange, hooknum);
diff -Nru a/net/ipv4/netfilter/ipt_ULOG.c b/net/ipv4/netfilter/ipt_ULOG.c
--- a/net/ipv4/netfilter/ipt_ULOG.c	2005-03-01 23:38:55 -08:00
+++ b/net/ipv4/netfilter/ipt_ULOG.c	2005-03-01 23:38:55 -08:00
@@ -100,7 +100,7 @@
 static ulog_buff_t ulog_buffers[ULOG_MAXNLGROUPS];	/* array of buffers */
 
 static struct sock *nflognl;	/* our socket */
-DECLARE_LOCK(ulog_lock);	/* spinlock */
+static DECLARE_LOCK(ulog_lock);	/* spinlock */
 
 /* send one ulog_buff_t to userspace */
 static void ulog_send(unsigned int nlgroupnum)
@@ -140,7 +140,7 @@
 	UNLOCK_BH(&ulog_lock);
 }
 
-struct sk_buff *ulog_alloc_skb(unsigned int size)
+static struct sk_buff *ulog_alloc_skb(unsigned int size)
 {
 	struct sk_buff *skb;
 
diff -Nru a/net/ipv4/netfilter/ipt_hashlimit.c b/net/ipv4/netfilter/ipt_hashlimit.c
--- a/net/ipv4/netfilter/ipt_hashlimit.c	2005-03-01 23:38:57 -08:00
+++ b/net/ipv4/netfilter/ipt_hashlimit.c	2005-03-01 23:38:57 -08:00
@@ -97,7 +97,8 @@
 	struct list_head hash[0];	/* hashtable itself */
 };
 
-DECLARE_RWLOCK(hashlimit_lock);		/* protects htables list */
+static DECLARE_RWLOCK(hashlimit_lock);	/* protects htables list */
+static DECLARE_MUTEX(hlimit_mutex);	/* additional checkentry protection */
 static LIST_HEAD(hashlimit_htables);
 static kmem_cache_t *hashlimit_cachep;
 
@@ -531,10 +532,19 @@
 	if (!r->cfg.expire)
 		return 0;
 
+	/* This is the best we've got: We cannot release and re-grab lock,
+	 * since checkentry() is called before ip_tables.c grabs ipt_mutex.  
+	 * We also cannot grab the hashtable spinlock, since htable_create will 
+	 * call vmalloc, and that can sleep.  And we cannot just re-search
+	 * the list of htable's in htable_create(), since then we would
+	 * create duplicate proc files. -HW */
+	down(&hlimit_mutex);
 	r->hinfo = htable_find_get(r->name);
 	if (!r->hinfo && (htable_create(r) != 0)) {
+		up(&hlimit_mutex);
 		return 0;
 	}
+	up(&hlimit_mutex);
 
 	/* Ugly hack: For SMP, we only want to use one set */
 	r->u.master = r;
@@ -570,7 +580,7 @@
 	if (*pos >= htable->cfg.size)
 		return NULL;
 
-	bucket = kmalloc(sizeof(unsigned int), GFP_KERNEL);
+	bucket = kmalloc(sizeof(unsigned int), GFP_ATOMIC);
 	if (!bucket)
 		return ERR_PTR(-ENOMEM);
 
@@ -668,11 +678,9 @@
 		goto cleanup_nothing;
 	}
 
-	/* FIXME: do we really want HWCACHE_ALIGN since our objects are
-	 * quite small ? */
 	hashlimit_cachep = kmem_cache_create("ipt_hashlimit",
 					    sizeof(struct dsthash_ent), 0,
-					    SLAB_HWCACHE_ALIGN, NULL, NULL);
+					    0, NULL, NULL);
 	if (!hashlimit_cachep) {
 		printk(KERN_ERR "Unable to create ipt_hashlimit slab cache\n");
 		ret = -ENOMEM;
diff -Nru a/net/ipv4/netfilter/ipt_helper.c b/net/ipv4/netfilter/ipt_helper.c
--- a/net/ipv4/netfilter/ipt_helper.c	2005-03-01 23:39:18 -08:00
+++ b/net/ipv4/netfilter/ipt_helper.c	2005-03-01 23:39:18 -08:00
@@ -38,7 +38,6 @@
       int *hotdrop)
 {
 	const struct ipt_helper_info *info = matchinfo;
-	struct ip_conntrack_expect *exp;
 	struct ip_conntrack *ct;
 	enum ip_conntrack_info ctinfo;
 	int ret = info->invert;
@@ -54,28 +53,21 @@
 		return ret;
 	}
 
-	exp = ct->master;
 	READ_LOCK(&ip_conntrack_lock);
-	if (!exp->expectant) {
-		DEBUGP("ipt_helper: expectation %p without expectant !?!\n", 
-			exp);
-		goto out_unlock;
-	}
-
-	if (!exp->expectant->helper) {
+	if (!ct->master->helper) {
 		DEBUGP("ipt_helper: master ct %p has no helper\n", 
 			exp->expectant);
 		goto out_unlock;
 	}
 
 	DEBUGP("master's name = %s , info->name = %s\n", 
-		exp->expectant->helper->name, info->name);
+		ct->master->helper->name, info->name);
 
 	if (info->name[0] == '\0')
 		ret ^= 1;
 	else
-		ret ^= !strncmp(exp->expectant->helper->name, info->name, 
-		                strlen(exp->expectant->helper->name));
+		ret ^= !strncmp(ct->master->helper->name, info->name, 
+		                strlen(ct->master->helper->name));
 out_unlock:
 	READ_UNLOCK(&ip_conntrack_lock);
 	return ret;
diff -Nru a/net/ipv4/netfilter/ipt_limit.c b/net/ipv4/netfilter/ipt_limit.c
--- a/net/ipv4/netfilter/ipt_limit.c	2005-03-01 23:38:52 -08:00
+++ b/net/ipv4/netfilter/ipt_limit.c	2005-03-01 23:38:52 -08:00
@@ -29,7 +29,7 @@
  * see net/sched/sch_tbf.c in the linux source tree
  */
 
-static spinlock_t limit_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(limit_lock);
 
 /* Rusty: This is my (non-mathematically-inclined) understanding of
    this algorithm.  The `average rate' in jiffies becomes your initial
diff -Nru a/net/ipv4/netfilter/ipt_multiport.c b/net/ipv4/netfilter/ipt_multiport.c
--- a/net/ipv4/netfilter/ipt_multiport.c	2005-03-01 23:38:53 -08:00
+++ b/net/ipv4/netfilter/ipt_multiport.c	2005-03-01 23:38:53 -08:00
@@ -46,6 +46,51 @@
 	return 0;
 }
 
+/* Returns 1 if the port is matched by the test, 0 otherwise. */
+static inline int
+ports_match_v1(const struct ipt_multiport_v1 *minfo,
+	       u_int16_t src, u_int16_t dst)
+{
+	unsigned int i;
+	u_int16_t s, e;
+
+	for (i=0; i < minfo->count; i++) {
+		s = minfo->ports[i];
+
+		if (minfo->pflags[i]) {
+			/* range port matching */
+			e = minfo->ports[++i];
+			duprintf("src or dst matches with %d-%d?\n", s, e);
+
+			if (minfo->flags == IPT_MULTIPORT_SOURCE
+			    && src >= s && src <= e)
+				return 1 ^ minfo->invert;
+			if (minfo->flags == IPT_MULTIPORT_DESTINATION
+			    && dst >= s && dst <= e)
+				return 1 ^ minfo->invert;
+			if (minfo->flags == IPT_MULTIPORT_EITHER
+			    && ((dst >= s && dst <= e)
+				|| (src >= s && src <= e)))
+				return 1 ^ minfo->invert;
+		} else {
+			/* exact port matching */
+			duprintf("src or dst matches with %d?\n", s);
+
+			if (minfo->flags == IPT_MULTIPORT_SOURCE
+			    && src == s)
+				return 1 ^ minfo->invert;
+			if (minfo->flags == IPT_MULTIPORT_DESTINATION
+			    && dst == s)
+				return 1 ^ minfo->invert;
+			if (minfo->flags == IPT_MULTIPORT_EITHER
+			    && (src == s || dst == s))
+				return 1 ^ minfo->invert;
+		}
+	}
+ 
+ 	return minfo->invert;
+}
+
 static int
 match(const struct sk_buff *skb,
       const struct net_device *in,
@@ -57,14 +102,11 @@
 	u16 _ports[2], *pptr;
 	const struct ipt_multiport *multiinfo = matchinfo;
 
-	/* Must not be a fragment. */
 	if (offset)
 		return 0;
 
-	/* Must be big enough to read ports (both UDP and TCP have
-           them at the start). */
 	pptr = skb_header_pointer(skb, skb->nh.iph->ihl * 4,
-				  sizeof(_ports), &_ports[0]);
+				  sizeof(_ports), _ports);
 	if (pptr == NULL) {
 		/* We've been asked to examine this packet, and we
 		 * can't.  Hence, no choice but to drop.
@@ -80,6 +122,35 @@
 			   ntohs(pptr[0]), ntohs(pptr[1]));
 }
 
+static int
+match_v1(const struct sk_buff *skb,
+	 const struct net_device *in,
+	 const struct net_device *out,
+	 const void *matchinfo,
+	 int offset,
+	 int *hotdrop)
+{
+	u16 _ports[2], *pptr;
+	const struct ipt_multiport_v1 *multiinfo = matchinfo;
+
+	if (offset)
+		return 0;
+
+	pptr = skb_header_pointer(skb, skb->nh.iph->ihl * 4,
+				  sizeof(_ports), _ports);
+	if (pptr == NULL) {
+		/* We've been asked to examine this packet, and we
+		 * can't.  Hence, no choice but to drop.
+		 */
+		duprintf("ipt_multiport:"
+			 " Dropping evil offset=0 tinygram.\n");
+		*hotdrop = 1;
+		return 0;
+	}
+
+	return ports_match_v1(multiinfo, ntohs(pptr[0]), ntohs(pptr[1]));
+}
+
 /* Called when user tries to insert an entry of this type. */
 static int
 checkentry(const char *tablename,
@@ -88,36 +159,53 @@
 	   unsigned int matchsize,
 	   unsigned int hook_mask)
 {
-	const struct ipt_multiport *multiinfo = matchinfo;
-
-	if (matchsize != IPT_ALIGN(sizeof(struct ipt_multiport)))
-		return 0;
+	return (matchsize == IPT_ALIGN(sizeof(struct ipt_multiport)));
+}
 
-	/* Must specify proto == TCP/UDP, no unknown flags or bad count */
-	return (ip->proto == IPPROTO_TCP || ip->proto == IPPROTO_UDP)
-		&& !(ip->invflags & IPT_INV_PROTO)
-		&& matchsize == IPT_ALIGN(sizeof(struct ipt_multiport))
-		&& (multiinfo->flags == IPT_MULTIPORT_SOURCE
-		    || multiinfo->flags == IPT_MULTIPORT_DESTINATION
-		    || multiinfo->flags == IPT_MULTIPORT_EITHER)
-		&& multiinfo->count <= IPT_MULTI_PORTS;
+static int
+checkentry_v1(const char *tablename,
+	      const struct ipt_ip *ip,
+	      void *matchinfo,
+	      unsigned int matchsize,
+	      unsigned int hook_mask)
+{
+	return (matchsize == IPT_ALIGN(sizeof(struct ipt_multiport_v1)));
 }
 
 static struct ipt_match multiport_match = {
 	.name		= "multiport",
+	.revision	= 0,
 	.match		= &match,
 	.checkentry	= &checkentry,
 	.me		= THIS_MODULE,
 };
 
+static struct ipt_match multiport_match_v1 = {
+	.name		= "multiport",
+	.revision	= 1,
+	.match		= &match_v1,
+	.checkentry	= &checkentry_v1,
+	.me		= THIS_MODULE,
+};
+
 static int __init init(void)
 {
-	return ipt_register_match(&multiport_match);
+	int err;
+
+	err = ipt_register_match(&multiport_match);
+	if (!err) {
+		err = ipt_register_match(&multiport_match_v1);
+		if (err)
+			ipt_unregister_match(&multiport_match);
+	}
+
+	return err;
 }
 
 static void __exit fini(void)
 {
 	ipt_unregister_match(&multiport_match);
+	ipt_unregister_match(&multiport_match_v1);
 }
 
 module_init(init);
diff -Nru a/net/ipv4/netfilter/ipt_recent.c b/net/ipv4/netfilter/ipt_recent.c
--- a/net/ipv4/netfilter/ipt_recent.c	2005-03-01 23:38:52 -08:00
+++ b/net/ipv4/netfilter/ipt_recent.c	2005-03-01 23:38:52 -08:00
@@ -90,7 +90,7 @@
 /* We protect r_list with this spinlock so two processors are not modifying
  * the list at the same time. 
  */
-static spinlock_t recent_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(recent_lock);
 
 #ifdef CONFIG_PROC_FS
 /* Our /proc/net/ipt_recent entry */
@@ -107,7 +107,7 @@
       int *hotdrop);
 
 /* Function to hash a given address into the hash table of table_size size */
-int hash_func(unsigned int addr, int table_size)
+static int hash_func(unsigned int addr, int table_size)
 {
 	int result = 0;
 	unsigned int value = addr;
@@ -713,7 +713,7 @@
 #endif
 
 	curr_table = vmalloc(sizeof(struct recent_ip_tables));
-	if(curr_table == NULL) return -ENOMEM;
+	if(curr_table == NULL) return 0;
 
 	spin_lock_init(&curr_table->list_lock);
 	curr_table->next = NULL;
@@ -730,7 +730,7 @@
 #endif
 
 	curr_table->table = vmalloc(sizeof(struct recent_ip_list)*ip_list_tot);
-	if(curr_table->table == NULL) { vfree(curr_table); return -ENOMEM; }
+	if(curr_table->table == NULL) { vfree(curr_table); return 0; }
 	memset(curr_table->table,0,sizeof(struct recent_ip_list)*ip_list_tot);
 #ifdef DEBUG
 	if(debug) printk(KERN_INFO RECENT_NAME ": checkentry: Allocating %d for pkt_list.\n",
@@ -745,7 +745,7 @@
 		printk(KERN_INFO RECENT_NAME ": checkentry: unable to allocate for pkt_list.\n");
 		vfree(curr_table->table); 
 		vfree(curr_table);
-		return -ENOMEM;
+		return 0;
 	}
 	for(c = 0; c < ip_list_tot; c++) {
 		curr_table->table[c].last_pkts = hold + c*ip_pkt_list_tot;
@@ -763,7 +763,7 @@
 		vfree(hold);
 		vfree(curr_table->table); 
 		vfree(curr_table);
-		return -ENOMEM;
+		return 0;
 	}
 
 	for(c = 0; c < ip_list_hash_size; c++) {
@@ -783,7 +783,7 @@
 		vfree(hold);
 		vfree(curr_table->table); 
 		vfree(curr_table);
-		return -ENOMEM;
+		return 0;
 	}
 	for(c = 0; c < ip_list_tot; c++) {
 		curr_table->time_info[c].position = c;
@@ -827,7 +827,7 @@
 			if(debug) printk(KERN_INFO RECENT_NAME ": checkentry() create_proc failed, no tables.\n");
 #endif
 			spin_unlock_bh(&recent_lock);
-			return -ENOMEM;
+			return 0;
 		}
 		while( strncmp(info->name,curr_table->name,IPT_RECENT_NAME_LEN) && (last_table = curr_table) && (curr_table = curr_table->next) );
 		if(!curr_table) {
@@ -835,7 +835,7 @@
 			if(debug) printk(KERN_INFO RECENT_NAME ": checkentry() create_proc failed, table already destroyed.\n");
 #endif
 			spin_unlock_bh(&recent_lock);
-			return -ENOMEM;
+			return 0;
 		}
 		if(last_table) last_table->next = curr_table->next; else r_tables = curr_table->next;
 		spin_unlock_bh(&recent_lock);
@@ -844,7 +844,7 @@
 		vfree(hold);
 		vfree(curr_table->table);
 		vfree(curr_table);
-		return -ENOMEM;
+		return 0;
 	}
 	
 	curr_table->status_proc->owner = THIS_MODULE;
@@ -959,7 +959,7 @@
 /* Kernel module initialization. */
 static int __init init(void)
 {
-	int count;
+	int err, count;
 
 	printk(version);
 #ifdef CONFIG_PROC_FS
@@ -983,7 +983,10 @@
 	if(debug) printk(KERN_INFO RECENT_NAME ": ip_list_hash_size: %d\n",ip_list_hash_size);
 #endif
 
-	return ipt_register_match(&recent_match);
+	err = ipt_register_match(&recent_match);
+	if (err)
+		remove_proc_entry("ipt_recent", proc_net);
+	return err;
 }
 
 /* Kernel module destruction. */
diff -Nru a/net/ipv4/netfilter/iptable_filter.c b/net/ipv4/netfilter/iptable_filter.c
--- a/net/ipv4/netfilter/iptable_filter.c	2005-03-01 23:38:55 -08:00
+++ b/net/ipv4/netfilter/iptable_filter.c	2005-03-01 23:38:55 -08:00
@@ -20,32 +20,13 @@
 
 #define FILTER_VALID_HOOKS ((1 << NF_IP_LOCAL_IN) | (1 << NF_IP_FORWARD) | (1 << NF_IP_LOCAL_OUT))
 
-/* Standard entry. */
-struct ipt_standard
-{
-	struct ipt_entry entry;
-	struct ipt_standard_target target;
-};
-
-struct ipt_error_target
-{
-	struct ipt_entry_target target;
-	char errorname[IPT_FUNCTION_MAXNAMELEN];
-};
-
-struct ipt_error
-{
-	struct ipt_entry entry;
-	struct ipt_error_target target;
-};
-
 static struct
 {
 	struct ipt_replace repl;
 	struct ipt_standard entries[3];
 	struct ipt_error term;
-} initial_table = {
-    { "filter", FILTER_VALID_HOOKS, 4,
+} initial_table __initdata 
+= { { "filter", FILTER_VALID_HOOKS, 4,
       sizeof(struct ipt_standard) * 3 + sizeof(struct ipt_error),
       { [NF_IP_LOCAL_IN] = 0,
 	[NF_IP_FORWARD] = sizeof(struct ipt_standard),
@@ -95,7 +76,6 @@
 
 static struct ipt_table packet_filter = {
 	.name		= "filter",
-	.table		= &initial_table.repl,
 	.valid_hooks	= FILTER_VALID_HOOKS,
 	.lock		= RW_LOCK_UNLOCKED,
 	.me		= THIS_MODULE
@@ -171,7 +151,7 @@
 	initial_table.entries[1].target.verdict = -forward - 1;
 
 	/* Register table */
-	ret = ipt_register_table(&packet_filter);
+	ret = ipt_register_table(&packet_filter, &initial_table.repl);
 	if (ret < 0)
 		return ret;
 
diff -Nru a/net/ipv4/netfilter/iptable_mangle.c b/net/ipv4/netfilter/iptable_mangle.c
--- a/net/ipv4/netfilter/iptable_mangle.c	2005-03-01 23:39:09 -08:00
+++ b/net/ipv4/netfilter/iptable_mangle.c	2005-03-01 23:39:09 -08:00
@@ -29,25 +29,6 @@
 			    (1 << NF_IP_LOCAL_OUT) | \
 			    (1 << NF_IP_POST_ROUTING))
 
-/* Standard entry. */
-struct ipt_standard
-{
-	struct ipt_entry entry;
-	struct ipt_standard_target target;
-};
-
-struct ipt_error_target
-{
-	struct ipt_entry_target target;
-	char errorname[IPT_FUNCTION_MAXNAMELEN];
-};
-
-struct ipt_error
-{
-	struct ipt_entry entry;
-	struct ipt_error_target target;
-};
-
 /* Ouch - five different hooks? Maybe this should be a config option..... -- BC */
 static struct
 {
@@ -125,7 +106,6 @@
 
 static struct ipt_table packet_mangler = {
 	.name		= "mangle",
-	.table		= &initial_table.repl,
 	.valid_hooks	= MANGLE_VALID_HOOKS,
 	.lock		= RW_LOCK_UNLOCKED,
 	.me		= THIS_MODULE,
@@ -225,7 +205,7 @@
 	int ret;
 
 	/* Register table */
-	ret = ipt_register_table(&packet_mangler);
+	ret = ipt_register_table(&packet_mangler, &initial_table.repl);
 	if (ret < 0)
 		return ret;
 
diff -Nru a/net/ipv4/netfilter/iptable_raw.c b/net/ipv4/netfilter/iptable_raw.c
--- a/net/ipv4/netfilter/iptable_raw.c	2005-03-01 23:39:16 -08:00
+++ b/net/ipv4/netfilter/iptable_raw.c	2005-03-01 23:39:16 -08:00
@@ -8,25 +8,6 @@
 
 #define RAW_VALID_HOOKS ((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_OUT))
 
-/* Standard entry. */
-struct ipt_standard
-{
-	struct ipt_entry entry;
-	struct ipt_standard_target target;
-};
-
-struct ipt_error_target
-{
-	struct ipt_entry_target target;
-	char errorname[IPT_FUNCTION_MAXNAMELEN];
-};
-
-struct ipt_error
-{
-	struct ipt_entry entry;
-	struct ipt_error_target target;
-};
-
 static struct
 {
 	struct ipt_replace repl;
@@ -100,7 +81,6 @@
 
 static struct ipt_table packet_raw = { 
 	.name = "raw", 
-	.table = &initial_table.repl,
 	.valid_hooks =  RAW_VALID_HOOKS, 
 	.lock = RW_LOCK_UNLOCKED, 
 	.me = THIS_MODULE
@@ -138,7 +118,7 @@
 	int ret;
 
 	/* Register table */
-	ret = ipt_register_table(&packet_raw);
+	ret = ipt_register_table(&packet_raw, &initial_table.repl);
 	if (ret < 0)
 		return ret;
 
diff -Nru a/net/ipv4/protocol.c b/net/ipv4/protocol.c
--- a/net/ipv4/protocol.c	2005-03-01 23:38:52 -08:00
+++ b/net/ipv4/protocol.c	2005-03-01 23:38:52 -08:00
@@ -49,7 +49,7 @@
 #include <linux/igmp.h>
 
 struct net_protocol *inet_protos[MAX_INET_PROTOS];
-static spinlock_t inet_proto_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(inet_proto_lock);
 
 /*
  *	Add a protocol handler to the hash tables
diff -Nru a/net/ipv4/raw.c b/net/ipv4/raw.c
--- a/net/ipv4/raw.c	2005-03-01 23:38:58 -08:00
+++ b/net/ipv4/raw.c	2005-03-01 23:38:58 -08:00
@@ -81,7 +81,7 @@
 #include <linux/netfilter_ipv4.h>
 
 struct hlist_head raw_v4_htable[RAWV4_HTABLE_SIZE];
-rwlock_t raw_v4_lock = RW_LOCK_UNLOCKED;
+DEFINE_RWLOCK(raw_v4_lock);
 
 static void raw_v4_hash(struct sock *sk)
 {
@@ -109,7 +109,7 @@
 	struct hlist_node *node;
 
 	sk_for_each_from(sk, node) {
-		struct inet_opt *inet = inet_sk(sk);
+		struct inet_sock *inet = inet_sk(sk);
 
 		if (inet->num == num 					&&
 		    !(inet->daddr && inet->daddr != raddr) 		&&
@@ -135,7 +135,7 @@
 
 	type = skb->h.icmph->type;
 	if (type < 32) {
-		__u32 data = raw4_sk(sk)->filter.data;
+		__u32 data = raw_sk(sk)->filter.data;
 
 		return ((1 << type) & data) != 0;
 	}
@@ -181,7 +181,7 @@
 
 void raw_err (struct sock *sk, struct sk_buff *skb, u32 info)
 {
-	struct inet_opt *inet = inet_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
 	int type = skb->h.icmph->type;
 	int code = skb->h.icmph->code;
 	int err = 0;
@@ -263,7 +263,7 @@
 			struct rtable *rt, 
 			unsigned int flags)
 {
-	struct inet_opt *inet = inet_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
 	int hh_len;
 	struct iphdr *iph;
 	struct sk_buff *skb;
@@ -374,7 +374,7 @@
 static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
 		       size_t len)
 {
-	struct inet_opt *inet = inet_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
 	struct ipcm_cookie ipc;
 	struct rtable *rt = NULL;
 	int free = 0;
@@ -537,7 +537,7 @@
 /* This gets rid of all the nasties in af_inet. -DaveM */
 static int raw_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
 {
-	struct inet_opt *inet = inet_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
 	struct sockaddr_in *addr = (struct sockaddr_in *) uaddr;
 	int ret = -EINVAL;
 	int chk_addr_ret;
@@ -562,10 +562,10 @@
  *	we return it, otherwise we block.
  */
 
-int raw_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
-		size_t len, int noblock, int flags, int *addr_len)
+static int raw_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
+		       size_t len, int noblock, int flags, int *addr_len)
 {
-	struct inet_opt *inet = inet_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
 	size_t copied = 0;
 	int err = -EOPNOTSUPP;
 	struct sockaddr_in *sin = (struct sockaddr_in *)msg->msg_name;
@@ -615,9 +615,10 @@
 
 static int raw_init(struct sock *sk)
 {
-	struct raw_opt *tp = raw4_sk(sk);
+	struct raw_sock *rp = raw_sk(sk);
+
 	if (inet_sk(sk)->num == IPPROTO_ICMP)
-		memset(&tp->filter, 0, sizeof(tp->filter));
+		memset(&rp->filter, 0, sizeof(rp->filter));
 	return 0;
 }
 
@@ -625,7 +626,7 @@
 {
 	if (optlen > sizeof(struct icmp_filter))
 		optlen = sizeof(struct icmp_filter);
-	if (copy_from_user(&raw4_sk(sk)->filter, optval, optlen))
+	if (copy_from_user(&raw_sk(sk)->filter, optval, optlen))
 		return -EFAULT;
 	return 0;
 }
@@ -643,7 +644,7 @@
 		len = sizeof(struct icmp_filter);
 	ret = -EFAULT;
 	if (put_user(len, optlen) ||
-	    copy_to_user(optval, &raw4_sk(sk)->filter, len))
+	    copy_to_user(optval, &raw_sk(sk)->filter, len))
 		goto out;
 	ret = 0;
 out:	return ret;
@@ -802,7 +803,7 @@
 
 static __inline__ char *get_raw_sock(struct sock *sp, char *tmpbuf, int i)
 {
-	struct inet_opt *inet = inet_sk(sp);
+	struct inet_sock *inet = inet_sk(sp);
 	unsigned int dest = inet->daddr,
 		     src = inet->rcv_saddr;
 	__u16 destp = 0,
diff -Nru a/net/ipv4/route.c b/net/ipv4/route.c
--- a/net/ipv4/route.c	2005-03-01 23:39:17 -08:00
+++ b/net/ipv4/route.c	2005-03-01 23:39:17 -08:00
@@ -108,22 +108,22 @@
 
 #define RT_GC_TIMEOUT (300*HZ)
 
-int ip_rt_min_delay		= 2 * HZ;
-int ip_rt_max_delay		= 10 * HZ;
-int ip_rt_max_size;
-int ip_rt_gc_timeout		= RT_GC_TIMEOUT;
-int ip_rt_gc_interval		= 60 * HZ;
-int ip_rt_gc_min_interval	= HZ / 2;
-int ip_rt_redirect_number	= 9;
-int ip_rt_redirect_load		= HZ / 50;
-int ip_rt_redirect_silence	= ((HZ / 50) << (9 + 1));
-int ip_rt_error_cost		= HZ;
-int ip_rt_error_burst		= 5 * HZ;
-int ip_rt_gc_elasticity		= 8;
-int ip_rt_mtu_expires		= 10 * 60 * HZ;
-int ip_rt_min_pmtu		= 512 + 20 + 20;
-int ip_rt_min_advmss		= 256;
-int ip_rt_secret_interval	= 10 * 60 * HZ;
+static int ip_rt_min_delay		= 2 * HZ;
+static int ip_rt_max_delay		= 10 * HZ;
+static int ip_rt_max_size;
+static int ip_rt_gc_timeout		= RT_GC_TIMEOUT;
+static int ip_rt_gc_interval		= 60 * HZ;
+static int ip_rt_gc_min_interval	= HZ / 2;
+static int ip_rt_redirect_number	= 9;
+static int ip_rt_redirect_load		= HZ / 50;
+static int ip_rt_redirect_silence	= ((HZ / 50) << (9 + 1));
+static int ip_rt_error_cost		= HZ;
+static int ip_rt_error_burst		= 5 * HZ;
+static int ip_rt_gc_elasticity		= 8;
+static int ip_rt_mtu_expires		= 10 * 60 * HZ;
+static int ip_rt_min_pmtu		= 512 + 20 + 20;
+static int ip_rt_min_advmss		= 256;
+static int ip_rt_secret_interval	= 10 * 60 * HZ;
 static unsigned long rt_deadline;
 
 #define RTprint(a...)	printk(KERN_DEBUG a)
@@ -138,7 +138,8 @@
 
 static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie);
 static void		 ipv4_dst_destroy(struct dst_entry *dst);
-static void		 ipv4_dst_ifdown(struct dst_entry *dst, int how);
+static void		 ipv4_dst_ifdown(struct dst_entry *dst,
+					 struct net_device *dev, int how);
 static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst);
 static void		 ipv4_link_failure(struct sk_buff *skb);
 static void		 ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu);
@@ -582,7 +583,7 @@
 	}
 }
 
-static spinlock_t rt_flush_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(rt_flush_lock);
 
 void rt_cache_flush(int delay)
 {
@@ -901,7 +902,7 @@
 
 void rt_bind_peer(struct rtable *rt, int create)
 {
-	static spinlock_t rt_peer_lock = SPIN_LOCK_UNLOCKED;
+	static DEFINE_SPINLOCK(rt_peer_lock);
 	struct inet_peer *peer;
 
 	peer = inet_getpeer(rt->rt_dst, create);
@@ -925,7 +926,7 @@
  */
 static void ip_select_fb_ident(struct iphdr *iph)
 {
-	static spinlock_t ip_fb_id_lock = SPIN_LOCK_UNLOCKED;
+	static DEFINE_SPINLOCK(ip_fb_id_lock);
 	static u32 ip_fallback_id;
 	u32 salt;
 
@@ -1342,11 +1343,12 @@
 	}
 }
 
-static void ipv4_dst_ifdown(struct dst_entry *dst, int how)
+static void ipv4_dst_ifdown(struct dst_entry *dst, struct net_device *dev,
+			    int how)
 {
 	struct rtable *rt = (struct rtable *) dst;
 	struct in_device *idev = rt->idev;
-	if (idev && idev->dev != &loopback_dev) {
+	if (dev != &loopback_dev && idev && idev->dev == dev) {
 		struct in_device *loopback_idev = in_dev_get(&loopback_dev);
 		if (loopback_idev) {
 			rt->idev = loopback_idev;
@@ -2529,6 +2531,8 @@
 		.proc_handler	= &proc_dointvec,
 	},
 	{
+		/*  Deprecated. Use gc_min_interval_ms */
+ 
 		.ctl_name	= NET_IPV4_ROUTE_GC_MIN_INTERVAL,
 		.procname	= "gc_min_interval",
 		.data		= &ip_rt_gc_min_interval,
@@ -2536,6 +2540,15 @@
 		.mode		= 0644,
 		.proc_handler	= &proc_dointvec_jiffies,
 		.strategy	= &sysctl_jiffies,
+	},
+	{
+		.ctl_name	= NET_IPV4_ROUTE_GC_MIN_INTERVAL_MS,
+		.procname	= "gc_min_interval_ms",
+		.data		= &ip_rt_gc_min_interval,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec_ms_jiffies,
+		.strategy	= &sysctl_ms_jiffies,
 	},
 	{
 		.ctl_name	= NET_IPV4_ROUTE_GC_TIMEOUT,
diff -Nru a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c
--- a/net/ipv4/syncookies.c	2005-03-01 23:39:18 -08:00
+++ b/net/ipv4/syncookies.c	2005-03-01 23:39:18 -08:00
@@ -47,7 +47,7 @@
  */
 __u32 cookie_v4_init_sequence(struct sock *sk, struct sk_buff *skb, __u16 *mssp)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	int mssind;
 	const __u16 mss = *mssp;
 
@@ -98,7 +98,7 @@
 					   struct open_request *req,
 					   struct dst_entry *dst)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	struct sock *child;
 
 	child = tp->af_specific->syn_recv_sock(sk, skb, req, dst);
@@ -114,7 +114,7 @@
 struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
 			     struct ip_options *opt)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	__u32 cookie = ntohl(skb->h.th->ack_seq) - 1; 
 	struct sock *ret = sk;
 	struct open_request *req; 
diff -Nru a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
--- a/net/ipv4/sysctl_net_ipv4.c	2005-03-01 23:39:08 -08:00
+++ b/net/ipv4/sysctl_net_ipv4.c	2005-03-01 23:39:08 -08:00
@@ -682,6 +682,14 @@
 		.mode		= 0644,
 		.proc_handler	= &proc_dointvec,
 	},
+	{
+		.ctl_name	= NET_TCP_BIC_BETA,
+		.procname	= "tcp_bic_beta",
+		.data		= &sysctl_tcp_bic_beta,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec,
+	},
 	{ .ctl_name = 0 }
 };
 
diff -Nru a/net/ipv4/tcp.c b/net/ipv4/tcp.c
--- a/net/ipv4/tcp.c	2005-03-01 23:38:54 -08:00
+++ b/net/ipv4/tcp.c	2005-03-01 23:38:54 -08:00
@@ -256,6 +256,7 @@
 #include <linux/smp_lock.h>
 #include <linux/fs.h>
 #include <linux/random.h>
+#include <linux/bootmem.h>
 
 #include <net/icmp.h>
 #include <net/tcp.h>
@@ -330,7 +331,7 @@
 {
 	unsigned int mask;
 	struct sock *sk = sock->sk;
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 
 	poll_wait(file, sk->sk_sleep, wait);
 	if (sk->sk_state == TCP_LISTEN)
@@ -413,7 +414,7 @@
 
 int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	int answ;
 
 	switch (cmd) {
@@ -460,8 +461,8 @@
 
 int tcp_listen_start(struct sock *sk)
 {
-	struct inet_opt *inet = inet_sk(sk);
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	struct tcp_listen_opt *lopt;
 
 	sk->sk_max_ack_backlog = 0;
@@ -514,7 +515,7 @@
 
 static void tcp_listen_stop (struct sock *sk)
 {
-	struct tcp_opt *tp = tcp_sk(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;
@@ -578,18 +579,18 @@
 	BUG_TRAP(!sk->sk_ack_backlog);
 }
 
-static inline void tcp_mark_push(struct tcp_opt *tp, struct sk_buff *skb)
+static inline void tcp_mark_push(struct tcp_sock *tp, struct sk_buff *skb)
 {
 	TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_PSH;
 	tp->pushed_seq = tp->write_seq;
 }
 
-static inline int forced_push(struct tcp_opt *tp)
+static inline int forced_push(struct tcp_sock *tp)
 {
 	return after(tp->write_seq, tp->pushed_seq + (tp->max_window >> 1));
 }
 
-static inline void skb_entail(struct sock *sk, struct tcp_opt *tp,
+static inline void skb_entail(struct sock *sk, struct tcp_sock *tp,
 			      struct sk_buff *skb)
 {
 	skb->csum = 0;
@@ -605,7 +606,7 @@
 		tp->nonagle &= ~TCP_NAGLE_PUSH; 
 }
 
-static inline void tcp_mark_urg(struct tcp_opt *tp, int flags,
+static inline void tcp_mark_urg(struct tcp_sock *tp, int flags,
 				struct sk_buff *skb)
 {
 	if (flags & MSG_OOB) {
@@ -615,7 +616,7 @@
 	}
 }
 
-static inline void tcp_push(struct sock *sk, struct tcp_opt *tp, int flags,
+static inline void tcp_push(struct sock *sk, struct tcp_sock *tp, int flags,
 			    int mss_now, int nonagle)
 {
 	if (sk->sk_send_head) {
@@ -631,7 +632,7 @@
 static ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffset,
 			 size_t psize, int flags)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	int mss_now;
 	int err;
 	ssize_t copied;
@@ -654,7 +655,7 @@
 	while (psize > 0) {
 		struct sk_buff *skb = sk->sk_write_queue.prev;
 		struct page *page = pages[poffset / PAGE_SIZE];
-		int copy, i;
+		int copy, i, can_coalesce;
 		int offset = poffset % PAGE_SIZE;
 		int size = min_t(size_t, psize, PAGE_SIZE - offset);
 
@@ -663,7 +664,7 @@
 			if (!sk_stream_memory_free(sk))
 				goto wait_for_sndbuf;
 
-			skb = sk_stream_alloc_pskb(sk, 0, tp->mss_cache,
+			skb = sk_stream_alloc_pskb(sk, 0, 0,
 						   sk->sk_allocation);
 			if (!skb)
 				goto wait_for_memory;
@@ -676,18 +677,27 @@
 			copy = size;
 
 		i = skb_shinfo(skb)->nr_frags;
-		if (skb_can_coalesce(skb, i, page, offset)) {
+		can_coalesce = skb_can_coalesce(skb, i, page, offset);
+		if (!can_coalesce && i >= MAX_SKB_FRAGS) {
+			tcp_mark_push(tp, skb);
+			goto new_segment;
+		}
+		if (sk->sk_forward_alloc < copy &&
+		    !sk_stream_mem_schedule(sk, copy, 0))
+			goto wait_for_memory;
+		
+		if (can_coalesce) {
 			skb_shinfo(skb)->frags[i - 1].size += copy;
-		} else if (i < MAX_SKB_FRAGS) {
+		} else {
 			get_page(page);
 			skb_fill_page_desc(skb, i, page, offset, copy);
-		} else {
-			tcp_mark_push(tp, skb);
-			goto new_segment;
 		}
 
 		skb->len += copy;
 		skb->data_len += copy;
+		skb->truesize += copy;
+		sk->sk_wmem_queued += copy;
+		sk->sk_forward_alloc -= copy;
 		skb->ip_summed = CHECKSUM_HW;
 		tp->write_seq += copy;
 		TCP_SKB_CB(skb)->end_seq += copy;
@@ -760,7 +770,7 @@
 #define TCP_PAGE(sk)	(sk->sk_sndmsg_page)
 #define TCP_OFF(sk)	(sk->sk_sndmsg_off)
 
-static inline int select_size(struct sock *sk, struct tcp_opt *tp)
+static inline int select_size(struct sock *sk, struct tcp_sock *tp)
 {
 	int tmp = tp->mss_cache_std;
 
@@ -778,7 +788,7 @@
 		size_t size)
 {
 	struct iovec *iov;
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	struct sk_buff *skb;
 	int iovlen, flags;
 	int mss_now;
@@ -1002,7 +1012,7 @@
 			struct msghdr *msg, int len, int flags,
 			int *addr_len)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 
 	/* No URG data to read. */
 	if (sock_flag(sk, SOCK_URGINLINE) || !tp->urg_data ||
@@ -1052,7 +1062,7 @@
  */
 static void cleanup_rbuf(struct sock *sk, int copied)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	int time_to_ack = 0;
 
 #if TCP_DEBUG
@@ -1107,7 +1117,7 @@
 static void tcp_prequeue_process(struct sock *sk)
 {
 	struct sk_buff *skb;
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 
 	NET_ADD_STATS_USER(LINUX_MIB_TCPPREQUEUED, skb_queue_len(&tp->ucopy.prequeue));
 
@@ -1154,7 +1164,7 @@
 		  sk_read_actor_t recv_actor)
 {
 	struct sk_buff *skb;
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	u32 seq = tp->copied_seq;
 	u32 offset;
 	int copied = 0;
@@ -1213,7 +1223,7 @@
 int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
 		size_t len, int nonblock, int flags, int *addr_len)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	int copied = 0;
 	u32 peek_seq;
 	u32 *seq;
@@ -1719,7 +1729,7 @@
 	 */
 
 	if (sk->sk_state == TCP_FIN_WAIT2) {
-		struct tcp_opt *tp = tcp_sk(sk);
+		struct tcp_sock *tp = tcp_sk(sk);
 		if (tp->linger2 < 0) {
 			tcp_set_state(sk, TCP_CLOSE);
 			tcp_send_active_reset(sk, GFP_ATOMIC);
@@ -1772,8 +1782,8 @@
 
 int tcp_disconnect(struct sock *sk, int flags)
 {
-	struct inet_opt *inet = inet_sk(sk);
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	int err = 0;
 	int old_state = sk->sk_state;
 
@@ -1812,15 +1822,15 @@
 	tp->backoff = 0;
 	tp->snd_cwnd = 2;
 	tp->probes_out = 0;
-	tcp_set_pcount(&tp->packets_out, 0);
+	tp->packets_out = 0;
 	tp->snd_ssthresh = 0x7fffffff;
 	tp->snd_cwnd_cnt = 0;
 	tcp_set_ca_state(tp, TCP_CA_Open);
 	tcp_clear_retrans(tp);
 	tcp_delack_init(tp);
 	sk->sk_send_head = NULL;
-	tp->saw_tstamp = 0;
-	tcp_sack_reset(tp);
+	tp->rx_opt.saw_tstamp = 0;
+	tcp_sack_reset(&tp->rx_opt);
 	__sk_dst_reset(sk);
 
 	BUG_TRAP(!inet->num || tp->bind_hash);
@@ -1835,7 +1845,7 @@
  */
 static int wait_for_connect(struct sock *sk, long timeo)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	DEFINE_WAIT(wait);
 	int err;
 
@@ -1883,7 +1893,7 @@
 
 struct sock *tcp_accept(struct sock *sk, int flags, int *err)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	struct open_request *req;
 	struct sock *newsk;
 	int error;
@@ -1934,7 +1944,7 @@
 int tcp_setsockopt(struct sock *sk, int level, int optname, char __user *optval,
 		   int optlen)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	int val;
 	int err = 0;
 
@@ -1959,7 +1969,7 @@
 			err = -EINVAL;
 			break;
 		}
-		tp->user_mss = val;
+		tp->rx_opt.user_mss = val;
 		break;
 
 	case TCP_NODELAY:
@@ -2098,7 +2108,7 @@
 /* Return information about state of tcp endpoint in API format. */
 void tcp_get_info(struct sock *sk, struct tcp_info *info)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	u32 now = tcp_time_stamp;
 
 	memset(info, 0, sizeof(*info));
@@ -2109,14 +2119,14 @@
 	info->tcpi_probes = tp->probes_out;
 	info->tcpi_backoff = tp->backoff;
 
-	if (tp->tstamp_ok)
+	if (tp->rx_opt.tstamp_ok)
 		info->tcpi_options |= TCPI_OPT_TIMESTAMPS;
-	if (tp->sack_ok)
+	if (tp->rx_opt.sack_ok)
 		info->tcpi_options |= TCPI_OPT_SACK;
-	if (tp->wscale_ok) {
+	if (tp->rx_opt.wscale_ok) {
 		info->tcpi_options |= TCPI_OPT_WSCALE;
-		info->tcpi_snd_wscale = tp->snd_wscale;
-		info->tcpi_rcv_wscale = tp->rcv_wscale;
+		info->tcpi_snd_wscale = tp->rx_opt.snd_wscale;
+		info->tcpi_rcv_wscale = tp->rx_opt.rcv_wscale;
 	} 
 
 	if (tp->ecn_flags&TCP_ECN_OK)
@@ -2127,11 +2137,11 @@
 	info->tcpi_snd_mss = tp->mss_cache_std;
 	info->tcpi_rcv_mss = tp->ack.rcv_mss;
 
-	info->tcpi_unacked = tcp_get_pcount(&tp->packets_out);
-	info->tcpi_sacked = tcp_get_pcount(&tp->sacked_out);
-	info->tcpi_lost = tcp_get_pcount(&tp->lost_out);
-	info->tcpi_retrans = tcp_get_pcount(&tp->retrans_out);
-	info->tcpi_fackets = tcp_get_pcount(&tp->fackets_out);
+	info->tcpi_unacked = tp->packets_out;
+	info->tcpi_sacked = tp->sacked_out;
+	info->tcpi_lost = tp->lost_out;
+	info->tcpi_retrans = tp->retrans_out;
+	info->tcpi_fackets = tp->fackets_out;
 
 	info->tcpi_last_data_sent = jiffies_to_msecs(now - tp->lsndtime);
 	info->tcpi_last_data_recv = jiffies_to_msecs(now - tp->ack.lrcvtime);
@@ -2157,7 +2167,7 @@
 int tcp_getsockopt(struct sock *sk, int level, int optname, char __user *optval,
 		   int __user *optlen)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	int val, len;
 
 	if (level != SOL_TCP)
@@ -2176,7 +2186,7 @@
 	case TCP_MAXSEG:
 		val = tp->mss_cache_std;
 		if (!val && ((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN)))
-			val = tp->user_mss;
+			val = tp->rx_opt.user_mss;
 		break;
 	case TCP_NODELAY:
 		val = !!(tp->nonagle&TCP_NAGLE_OFF);
@@ -2254,7 +2264,6 @@
 void __init tcp_init(void)
 {
 	struct sk_buff *skb = NULL;
-	unsigned long goal;
 	int order, i;
 
 	if (sizeof(struct tcp_skb_cb) > sizeof(skb->cb))
@@ -2287,43 +2296,35 @@
 	 *
 	 * The methodology is similar to that of the buffer cache.
 	 */
-	if (num_physpages >= (128 * 1024))
-		goal = num_physpages >> (21 - PAGE_SHIFT);
-	else
-		goal = num_physpages >> (23 - PAGE_SHIFT);
-
-	if (thash_entries)
-		goal = (thash_entries * sizeof(struct tcp_ehash_bucket)) >> PAGE_SHIFT;
-	for (order = 0; (1UL << order) < goal; order++)
-		;
-	do {
-		tcp_ehash_size = (1UL << order) * PAGE_SIZE /
-			sizeof(struct tcp_ehash_bucket);
-		tcp_ehash_size >>= 1;
-		while (tcp_ehash_size & (tcp_ehash_size - 1))
-			tcp_ehash_size--;
-		tcp_ehash = (struct tcp_ehash_bucket *)
-			__get_free_pages(GFP_ATOMIC, order);
-	} while (!tcp_ehash && --order > 0);
-
-	if (!tcp_ehash)
-		panic("Failed to allocate TCP established hash table\n");
+	tcp_ehash = (struct tcp_ehash_bucket *)
+		alloc_large_system_hash("TCP established",
+					sizeof(struct tcp_ehash_bucket),
+					thash_entries,
+					(num_physpages >= 128 * 1024) ?
+						(25 - PAGE_SHIFT) :
+						(27 - PAGE_SHIFT),
+					HASH_HIGHMEM,
+					&tcp_ehash_size,
+					NULL,
+					0);
+	tcp_ehash_size = (1 << tcp_ehash_size) >> 1;
 	for (i = 0; i < (tcp_ehash_size << 1); i++) {
 		rwlock_init(&tcp_ehash[i].lock);
 		INIT_HLIST_HEAD(&tcp_ehash[i].chain);
 	}
 
-	do {
-		tcp_bhash_size = (1UL << order) * PAGE_SIZE /
-			sizeof(struct tcp_bind_hashbucket);
-		if ((tcp_bhash_size > (64 * 1024)) && order > 0)
-			continue;
-		tcp_bhash = (struct tcp_bind_hashbucket *)
-			__get_free_pages(GFP_ATOMIC, order);
-	} while (!tcp_bhash && --order >= 0);
-
-	if (!tcp_bhash)
-		panic("Failed to allocate TCP bind hash table\n");
+	tcp_bhash = (struct tcp_bind_hashbucket *)
+		alloc_large_system_hash("TCP bind",
+					sizeof(struct tcp_bind_hashbucket),
+					tcp_ehash_size,
+					(num_physpages >= 128 * 1024) ?
+						(25 - PAGE_SHIFT) :
+						(27 - PAGE_SHIFT),
+					HASH_HIGHMEM,
+					&tcp_bhash_size,
+					NULL,
+					64 * 1024);
+	tcp_bhash_size = 1 << tcp_bhash_size;
 	for (i = 0; i < tcp_bhash_size; i++) {
 		spin_lock_init(&tcp_bhash[i].lock);
 		INIT_HLIST_HEAD(&tcp_bhash[i].chain);
@@ -2332,6 +2333,10 @@
 	/* Try to be a bit smarter and adjust defaults depending
 	 * on available memory.
 	 */
+	for (order = 0; ((1 << order) << PAGE_SHIFT) <
+			(tcp_bhash_size * sizeof(struct tcp_bind_hashbucket));
+			order++)
+		;
 	if (order > 4) {
 		sysctl_local_port_range[0] = 32768;
 		sysctl_local_port_range[1] = 61000;
diff -Nru a/net/ipv4/tcp_diag.c b/net/ipv4/tcp_diag.c
--- a/net/ipv4/tcp_diag.c	2005-03-01 23:38:44 -08:00
+++ b/net/ipv4/tcp_diag.c	2005-03-01 23:38:44 -08:00
@@ -55,8 +55,8 @@
 static int tcpdiag_fill(struct sk_buff *skb, struct sock *sk,
 			int ext, u32 pid, u32 seq, u16 nlmsg_flags)
 {
-	struct inet_opt *inet = inet_sk(sk);
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	struct tcpdiagmsg *r;
 	struct nlmsghdr  *nlh;
 	struct tcp_info  *info = NULL;
@@ -427,7 +427,7 @@
 	if (cb->nlh->nlmsg_len > 4 + NLMSG_SPACE(sizeof(*r))) {
 		struct tcpdiag_entry entry;
 		struct rtattr *bc = (struct rtattr *)(r + 1);
-		struct inet_opt *inet = inet_sk(sk);
+		struct inet_sock *inet = inet_sk(sk);
 
 		entry.family = sk->sk_family;
 #ifdef CONFIG_IP_TCPDIAG_IPV6
@@ -458,7 +458,7 @@
 			    struct open_request *req,
 			    u32 pid, u32 seq)
 {
-	struct inet_opt *inet = inet_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
 	unsigned char *b = skb->tail;
 	struct tcpdiagmsg *r;
 	struct nlmsghdr *nlh;
@@ -512,10 +512,10 @@
 {
 	struct tcpdiag_entry entry;
 	struct tcpdiagreq *r = NLMSG_DATA(cb->nlh);
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	struct tcp_listen_opt *lopt;
 	struct rtattr *bc = NULL;
-	struct inet_opt *inet = inet_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
 	int j, s_j;
 	int reqnum, s_reqnum;
 	int err = 0;
@@ -609,7 +609,7 @@
 
 			num = 0;
 			sk_for_each(sk, node, &tcp_listening_hash[i]) {
-				struct inet_opt *inet = inet_sk(sk);
+				struct inet_sock *inet = inet_sk(sk);
 
 				if (num < s_num) {
 					num++;
@@ -670,7 +670,7 @@
 
 		num = 0;
 		sk_for_each(sk, node, &head->chain) {
-			struct inet_opt *inet = inet_sk(sk);
+			struct inet_sock *inet = inet_sk(sk);
 
 			if (num < s_num)
 				goto next_normal;
@@ -692,7 +692,7 @@
 		if (r->tcpdiag_states&TCPF_TIME_WAIT) {
 			sk_for_each(sk, node,
 				    &tcp_ehash[i + tcp_ehash_size].chain) {
-				struct inet_opt *inet = inet_sk(sk);
+				struct inet_sock *inet = inet_sk(sk);
 
 				if (num < s_num)
 					goto next_dying;
diff -Nru a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
--- a/net/ipv4/tcp_input.c	2005-03-01 23:39:08 -08:00
+++ b/net/ipv4/tcp_input.c	2005-03-01 23:39:08 -08:00
@@ -102,6 +102,7 @@
 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.	*/
@@ -118,16 +119,17 @@
 #define FLAG_CA_ALERT		(FLAG_DATA_SACKED|FLAG_ECE)
 #define FLAG_FORWARD_PROGRESS	(FLAG_ACKED|FLAG_DATA_SACKED)
 
-#define IsReno(tp) ((tp)->sack_ok == 0)
-#define IsFack(tp) ((tp)->sack_ok & 2)
-#define IsDSack(tp) ((tp)->sack_ok & 4)
+#define IsReno(tp) ((tp)->rx_opt.sack_ok == 0)
+#define IsFack(tp) ((tp)->rx_opt.sack_ok & 2)
+#define IsDSack(tp) ((tp)->rx_opt.sack_ok & 4)
 
 #define TCP_REMNANT (TCP_FLAG_FIN|TCP_FLAG_URG|TCP_FLAG_SYN|TCP_FLAG_PSH)
 
 /* Adapt the MSS value used to make delayed ack decision to the 
  * real world.
  */ 
-static __inline__ void tcp_measure_rcv_mss(struct tcp_opt *tp, struct sk_buff *skb)
+static inline void tcp_measure_rcv_mss(struct tcp_sock *tp,
+				       struct sk_buff *skb)
 {
 	unsigned int len, lss;
 
@@ -170,7 +172,7 @@
 	}
 }
 
-static void tcp_incr_quickack(struct tcp_opt *tp)
+static void tcp_incr_quickack(struct tcp_sock *tp)
 {
 	unsigned quickacks = tp->rcv_wnd/(2*tp->ack.rcv_mss);
 
@@ -180,7 +182,7 @@
 		tp->ack.quick = min(quickacks, TCP_MAX_QUICKACKS);
 }
 
-void tcp_enter_quickack_mode(struct tcp_opt *tp)
+void tcp_enter_quickack_mode(struct tcp_sock *tp)
 {
 	tcp_incr_quickack(tp);
 	tp->ack.pingpong = 0;
@@ -191,7 +193,7 @@
  * and the session is not interactive.
  */
 
-static __inline__ int tcp_in_quickack_mode(struct tcp_opt *tp)
+static __inline__ int tcp_in_quickack_mode(struct tcp_sock *tp)
 {
 	return (tp->ack.quick && !tp->ack.pingpong);
 }
@@ -203,7 +205,7 @@
 
 static void tcp_fixup_sndbuf(struct sock *sk)
 {
-	int sndmem = tcp_sk(sk)->mss_clamp + MAX_TCP_HEADER + 16 +
+	int sndmem = tcp_sk(sk)->rx_opt.mss_clamp + MAX_TCP_HEADER + 16 +
 		     sizeof(struct sk_buff);
 
 	if (sk->sk_sndbuf < 3 * sndmem)
@@ -236,8 +238,8 @@
  */
 
 /* Slow part of check#2. */
-static int
-__tcp_grow_window(struct sock *sk, struct tcp_opt *tp, struct sk_buff *skb)
+static int __tcp_grow_window(struct sock *sk, struct tcp_sock *tp,
+			     struct sk_buff *skb)
 {
 	/* Optimize this! */
 	int truesize = tcp_win_from_space(skb->truesize)/2;
@@ -253,8 +255,8 @@
 	return 0;
 }
 
-static __inline__ void
-tcp_grow_window(struct sock *sk, struct tcp_opt *tp, struct sk_buff *skb)
+static inline void tcp_grow_window(struct sock *sk, struct tcp_sock *tp,
+				   struct sk_buff *skb)
 {
 	/* Check #1 */
 	if (tp->rcv_ssthresh < tp->window_clamp &&
@@ -281,7 +283,7 @@
 
 static void tcp_fixup_rcvbuf(struct sock *sk)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	int rcvmem = tp->advmss + MAX_TCP_HEADER + 16 + sizeof(struct sk_buff);
 
 	/* Try to select rcvbuf so that 4 mss-sized segments
@@ -299,7 +301,7 @@
  */
 static void tcp_init_buffer_space(struct sock *sk)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	int maxwin;
 
 	if (!(sk->sk_userlocks & SOCK_RCVBUF_LOCK))
@@ -330,7 +332,7 @@
 	tp->snd_cwnd_stamp = tcp_time_stamp;
 }
 
-static void init_bictcp(struct tcp_opt *tp)
+static void init_bictcp(struct tcp_sock *tp)
 {
 	tp->bictcp.cnt = 0;
 
@@ -340,7 +342,7 @@
 }
 
 /* 5. Recalculate window clamp after socket hit its memory bounds. */
-static void tcp_clamp_window(struct sock *sk, struct tcp_opt *tp)
+static void tcp_clamp_window(struct sock *sk, struct tcp_sock *tp)
 {
 	struct sk_buff *skb;
 	unsigned int app_win = tp->rcv_nxt - tp->copied_seq;
@@ -388,7 +390,7 @@
  * though this reference is out of date.  A new paper
  * is pending.
  */
-static void tcp_rcv_rtt_update(struct tcp_opt *tp, u32 sample, int win_dep)
+static void tcp_rcv_rtt_update(struct tcp_sock *tp, u32 sample, int win_dep)
 {
 	u32 new_sample = tp->rcv_rtt_est.rtt;
 	long m = sample;
@@ -421,7 +423,7 @@
 		tp->rcv_rtt_est.rtt = new_sample;
 }
 
-static inline void tcp_rcv_rtt_measure(struct tcp_opt *tp)
+static inline void tcp_rcv_rtt_measure(struct tcp_sock *tp)
 {
 	if (tp->rcv_rtt_est.time == 0)
 		goto new_measure;
@@ -436,12 +438,12 @@
 	tp->rcv_rtt_est.time = tcp_time_stamp;
 }
 
-static inline void tcp_rcv_rtt_measure_ts(struct tcp_opt *tp, struct sk_buff *skb)
+static inline void tcp_rcv_rtt_measure_ts(struct tcp_sock *tp, struct sk_buff *skb)
 {
-	if (tp->rcv_tsecr &&
+	if (tp->rx_opt.rcv_tsecr &&
 	    (TCP_SKB_CB(skb)->end_seq -
 	     TCP_SKB_CB(skb)->seq >= tp->ack.rcv_mss))
-		tcp_rcv_rtt_update(tp, tcp_time_stamp - tp->rcv_tsecr, 0);
+		tcp_rcv_rtt_update(tp, tcp_time_stamp - tp->rx_opt.rcv_tsecr, 0);
 }
 
 /*
@@ -450,7 +452,7 @@
  */
 void tcp_rcv_space_adjust(struct sock *sk)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	int time;
 	int space;
 	
@@ -511,7 +513,7 @@
  * each ACK we send, he increments snd_cwnd and transmits more of his
  * queue.  -DaveM
  */
-static void tcp_event_data_recv(struct sock *sk, struct tcp_opt *tp, struct sk_buff *skb)
+static void tcp_event_data_recv(struct sock *sk, struct tcp_sock *tp, struct sk_buff *skb)
 {
 	u32 now;
 
@@ -558,7 +560,7 @@
 /* When starting a new connection, pin down the current choice of 
  * congestion algorithm.
  */
-void tcp_ca_init(struct tcp_opt *tp)
+void tcp_ca_init(struct tcp_sock *tp)
 {
 	if (sysctl_tcp_westwood) 
 		tp->adv_cong = TCP_WESTWOOD;
@@ -579,7 +581,7 @@
  *   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_opt *tp, __u32 rtt)
+static inline void vegas_rtt_calc(struct tcp_sock *tp, __u32 rtt)
 {
 	__u32 vrtt = rtt + 1; /* Never allow zero rtt or baseRTT */
 
@@ -603,7 +605,7 @@
  * 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_opt *tp, __u32 mrtt)
+static void tcp_rtt_estimator(struct tcp_sock *tp, __u32 mrtt)
 {
 	long m = mrtt; /* RTT */
 
@@ -673,7 +675,7 @@
 /* Calculate rto without backoff.  This is the second half of Van Jacobson's
  * routine referred to above.
  */
-static __inline__ void tcp_set_rto(struct tcp_opt *tp)
+static inline void tcp_set_rto(struct tcp_sock *tp)
 {
 	/* Old crap is replaced with new one. 8)
 	 *
@@ -697,7 +699,7 @@
 /* NOTE: clamping at TCP_RTO_MIN is not required, current algo
  * guarantees that rto is higher.
  */
-static __inline__ void tcp_bound_rto(struct tcp_opt *tp)
+static inline void tcp_bound_rto(struct tcp_sock *tp)
 {
 	if (tp->rto > TCP_RTO_MAX)
 		tp->rto = TCP_RTO_MAX;
@@ -709,7 +711,7 @@
  */
 void tcp_update_metrics(struct sock *sk)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	struct dst_entry *dst = __sk_dst_get(sk);
 
 	if (sysctl_tcp_nometrics_save)
@@ -797,7 +799,7 @@
 }
 
 /* Numbers are taken from RFC2414.  */
-__u32 tcp_init_cwnd(struct tcp_opt *tp, struct dst_entry *dst)
+__u32 tcp_init_cwnd(struct tcp_sock *tp, struct dst_entry *dst)
 {
 	__u32 cwnd = (dst ? dst_metric(dst, RTAX_INITCWND) : 0);
 
@@ -814,7 +816,7 @@
 
 static void tcp_init_metrics(struct sock *sk)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	struct dst_entry *dst = __sk_dst_get(sk);
 
 	if (dst == NULL)
@@ -831,7 +833,7 @@
 	}
 	if (dst_metric(dst, RTAX_REORDERING) &&
 	    tp->reordering != dst_metric(dst, RTAX_REORDERING)) {
-		tp->sack_ok &= ~2;
+		tp->rx_opt.sack_ok &= ~2;
 		tp->reordering = dst_metric(dst, RTAX_REORDERING);
 	}
 
@@ -865,7 +867,7 @@
 	}
 	tcp_set_rto(tp);
 	tcp_bound_rto(tp);
-	if (tp->rto < TCP_TIMEOUT_INIT && !tp->saw_tstamp)
+	if (tp->rto < TCP_TIMEOUT_INIT && !tp->rx_opt.saw_tstamp)
 		goto reset;
 	tp->snd_cwnd = tcp_init_cwnd(tp, dst);
 	tp->snd_cwnd_stamp = tcp_time_stamp;
@@ -876,14 +878,14 @@
 	 * supported, TCP will fail to recalculate correct
 	 * rtt, if initial rto is too small. FORGET ALL AND RESET!
 	 */
-	if (!tp->saw_tstamp && tp->srtt) {
+	if (!tp->rx_opt.saw_tstamp && tp->srtt) {
 		tp->srtt = 0;
 		tp->mdev = tp->mdev_max = tp->rttvar = TCP_TIMEOUT_INIT;
 		tp->rto = TCP_TIMEOUT_INIT;
 	}
 }
 
-static void tcp_update_reordering(struct tcp_opt *tp, int metric, int ts)
+static void tcp_update_reordering(struct tcp_sock *tp, int metric, int ts)
 {
 	if (metric > tp->reordering) {
 		tp->reordering = min(TCP_MAX_REORDERING, metric);
@@ -899,14 +901,14 @@
 			NET_INC_STATS_BH(LINUX_MIB_TCPSACKREORDER);
 #if FASTRETRANS_DEBUG > 1
 		printk(KERN_DEBUG "Disorder%d %d %u f%u s%u rr%d\n",
-		       tp->sack_ok, tp->ca_state,
+		       tp->rx_opt.sack_ok, tp->ca_state,
 		       tp->reordering,
-		       tcp_get_pcount(&tp->fackets_out),
-		       tcp_get_pcount(&tp->sacked_out),
+		       tp->fackets_out,
+		       tp->sacked_out,
 		       tp->undo_marker ? tp->undo_retrans : 0);
 #endif
 		/* Disable FACK yet. */
-		tp->sack_ok &= ~2;
+		tp->rx_opt.sack_ok &= ~2;
 	}
 }
 
@@ -961,11 +963,11 @@
 static int
 tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_una)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	unsigned char *ptr = ack_skb->h.raw + TCP_SKB_CB(ack_skb)->sacked;
 	struct tcp_sack_block *sp = (struct tcp_sack_block *)(ptr+2);
 	int num_sacks = (ptr[1] - TCPOLEN_SACK_BASE)>>3;
-	int reord = tcp_get_pcount(&tp->packets_out);
+	int reord = tp->packets_out;
 	int prior_fackets;
 	u32 lost_retrans = 0;
 	int flag = 0;
@@ -979,9 +981,9 @@
 		tp->mss_cache = tp->mss_cache_std;
 	}
 
-	if (!tcp_get_pcount(&tp->sacked_out))
-		tcp_set_pcount(&tp->fackets_out, 0);
-	prior_fackets = tcp_get_pcount(&tp->fackets_out);
+	if (!tp->sacked_out)
+		tp->fackets_out = 0;
+	prior_fackets = tp->fackets_out;
 
 	for (i=0; i<num_sacks; i++, sp++) {
 		struct sk_buff *skb;
@@ -996,13 +998,13 @@
 
 			if (before(start_seq, ack)) {
 				dup_sack = 1;
-				tp->sack_ok |= 4;
+				tp->rx_opt.sack_ok |= 4;
 				NET_INC_STATS_BH(LINUX_MIB_TCPDSACKRECV);
 			} else if (num_sacks > 1 &&
 				   !after(end_seq, ntohl(sp[1].end_seq)) &&
 				   !before(start_seq, ntohl(sp[1].start_seq))) {
 				dup_sack = 1;
-				tp->sack_ok |= 4;
+				tp->rx_opt.sack_ok |= 4;
 				NET_INC_STATS_BH(LINUX_MIB_TCPDSACKOFORECV);
 			}
 
@@ -1079,8 +1081,8 @@
 					 */
 					if (sacked & TCPCB_LOST) {
 						TCP_SKB_CB(skb)->sacked &= ~(TCPCB_LOST|TCPCB_SACKED_RETRANS);
-						tcp_dec_pcount(&tp->lost_out, skb);
-						tcp_dec_pcount(&tp->retrans_out, skb);
+						tp->lost_out -= tcp_skb_pcount(skb);
+						tp->retrans_out -= tcp_skb_pcount(skb);
 					}
 				} else {
 					/* New sack for not retransmitted frame,
@@ -1092,16 +1094,16 @@
 
 					if (sacked & TCPCB_LOST) {
 						TCP_SKB_CB(skb)->sacked &= ~TCPCB_LOST;
-						tcp_dec_pcount(&tp->lost_out, skb);
+						tp->lost_out -= tcp_skb_pcount(skb);
 					}
 				}
 
 				TCP_SKB_CB(skb)->sacked |= TCPCB_SACKED_ACKED;
 				flag |= FLAG_DATA_SACKED;
-				tcp_inc_pcount(&tp->sacked_out, skb);
+				tp->sacked_out += tcp_skb_pcount(skb);
 
-				if (fack_count > tcp_get_pcount(&tp->fackets_out))
-					tcp_set_pcount(&tp->fackets_out, fack_count);
+				if (fack_count > tp->fackets_out)
+					tp->fackets_out = fack_count;
 			} else {
 				if (dup_sack && (sacked&TCPCB_RETRANS))
 					reord = min(fack_count, reord);
@@ -1115,7 +1117,7 @@
 			if (dup_sack &&
 			    (TCP_SKB_CB(skb)->sacked&TCPCB_SACKED_RETRANS)) {
 				TCP_SKB_CB(skb)->sacked &= ~TCPCB_SACKED_RETRANS;
-				tcp_dec_pcount(&tp->retrans_out, skb);
+				tp->retrans_out -= tcp_skb_pcount(skb);
 			}
 		}
 	}
@@ -1141,10 +1143,10 @@
 				     TCP_SKB_CB(skb)->ack_seq + tp->reordering *
 				     tp->mss_cache_std))) {
 				TCP_SKB_CB(skb)->sacked &= ~TCPCB_SACKED_RETRANS;
-				tcp_dec_pcount(&tp->retrans_out, skb);
+				tp->retrans_out -= tcp_skb_pcount(skb);
 
 				if (!(TCP_SKB_CB(skb)->sacked&(TCPCB_LOST|TCPCB_SACKED_ACKED))) {
-					tcp_inc_pcount(&tp->lost_out, skb);
+					tp->lost_out += tcp_skb_pcount(skb);
 					TCP_SKB_CB(skb)->sacked |= TCPCB_LOST;
 					flag |= FLAG_DATA_SACKED;
 					NET_INC_STATS_BH(LINUX_MIB_TCPLOSTRETRANSMIT);
@@ -1153,20 +1155,15 @@
 		}
 	}
 
-	tcp_set_pcount(&tp->left_out,
-		       (tcp_get_pcount(&tp->sacked_out) +
-			tcp_get_pcount(&tp->lost_out)));
-
-	if ((reord < tcp_get_pcount(&tp->fackets_out)) &&
-	    tp->ca_state != TCP_CA_Loss)
-		tcp_update_reordering(tp,
-				      ((tcp_get_pcount(&tp->fackets_out) + 1) -
-				       reord), 0);
+	tp->left_out = tp->sacked_out + tp->lost_out;
+
+	if ((reord < tp->fackets_out) && tp->ca_state != TCP_CA_Loss)
+		tcp_update_reordering(tp, ((tp->fackets_out + 1) - reord), 0);
 
 #if FASTRETRANS_DEBUG > 0
-	BUG_TRAP((int)tcp_get_pcount(&tp->sacked_out) >= 0);
-	BUG_TRAP((int)tcp_get_pcount(&tp->lost_out) >= 0);
-	BUG_TRAP((int)tcp_get_pcount(&tp->retrans_out) >= 0);
+	BUG_TRAP((int)tp->sacked_out >= 0);
+	BUG_TRAP((int)tp->lost_out >= 0);
+	BUG_TRAP((int)tp->retrans_out >= 0);
 	BUG_TRAP((int)tcp_packets_in_flight(tp) >= 0);
 #endif
 	return flag;
@@ -1178,7 +1175,7 @@
  */
 void tcp_enter_frto(struct sock *sk)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	struct sk_buff *skb;
 
 	tp->frto_counter = 1;
@@ -1196,7 +1193,7 @@
 	 * If something was really lost, it is eventually caught up
 	 * in tcp_enter_frto_loss.
 	 */
-	tcp_set_pcount(&tp->retrans_out, 0);
+	tp->retrans_out = 0;
 	tp->undo_marker = tp->snd_una;
 	tp->undo_retrans = 0;
 
@@ -1215,13 +1212,13 @@
  */
 static void tcp_enter_frto_loss(struct sock *sk)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	struct sk_buff *skb;
 	int cnt = 0;
 
-	tcp_set_pcount(&tp->sacked_out, 0);
-	tcp_set_pcount(&tp->lost_out, 0);
-	tcp_set_pcount(&tp->fackets_out, 0);
+	tp->sacked_out = 0;
+	tp->lost_out = 0;
+	tp->fackets_out = 0;
 
 	sk_stream_for_retrans_queue(skb, sk) {
 		cnt += tcp_skb_pcount(skb);
@@ -1234,11 +1231,11 @@
 			if (!after(TCP_SKB_CB(skb)->end_seq,
 				   tp->frto_highmark)) {
 				TCP_SKB_CB(skb)->sacked |= TCPCB_LOST;
-				tcp_inc_pcount(&tp->lost_out, skb);
+				tp->lost_out += tcp_skb_pcount(skb);
 			}
 		} else {
-			tcp_inc_pcount(&tp->sacked_out, skb);
-			tcp_set_pcount(&tp->fackets_out, cnt);
+			tp->sacked_out += tcp_skb_pcount(skb);
+			tp->fackets_out = cnt;
 		}
 	}
 	tcp_sync_left_out(tp);
@@ -1258,14 +1255,14 @@
 	init_bictcp(tp);
 }
 
-void tcp_clear_retrans(struct tcp_opt *tp)
+void tcp_clear_retrans(struct tcp_sock *tp)
 {
-	tcp_set_pcount(&tp->left_out, 0);
-	tcp_set_pcount(&tp->retrans_out, 0);
+	tp->left_out = 0;
+	tp->retrans_out = 0;
 
-	tcp_set_pcount(&tp->fackets_out, 0);
-	tcp_set_pcount(&tp->sacked_out, 0);
-	tcp_set_pcount(&tp->lost_out, 0);
+	tp->fackets_out = 0;
+	tp->sacked_out = 0;
+	tp->lost_out = 0;
 
 	tp->undo_marker = 0;
 	tp->undo_retrans = 0;
@@ -1277,7 +1274,7 @@
  */
 void tcp_enter_loss(struct sock *sk, int how)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	struct sk_buff *skb;
 	int cnt = 0;
 
@@ -1306,10 +1303,10 @@
 		if (!(TCP_SKB_CB(skb)->sacked&TCPCB_SACKED_ACKED) || how) {
 			TCP_SKB_CB(skb)->sacked &= ~TCPCB_SACKED_ACKED;
 			TCP_SKB_CB(skb)->sacked |= TCPCB_LOST;
-			tcp_inc_pcount(&tp->lost_out, skb);
+			tp->lost_out += tcp_skb_pcount(skb);
 		} else {
-			tcp_inc_pcount(&tp->sacked_out, skb);
-			tcp_set_pcount(&tp->fackets_out, cnt);
+			tp->sacked_out += tcp_skb_pcount(skb);
+			tp->fackets_out = cnt;
 		}
 	}
 	tcp_sync_left_out(tp);
@@ -1321,7 +1318,7 @@
 	TCP_ECN_queue_cwr(tp);
 }
 
-static int tcp_check_sack_reneging(struct sock *sk, struct tcp_opt *tp)
+static int tcp_check_sack_reneging(struct sock *sk, struct tcp_sock *tp)
 {
 	struct sk_buff *skb;
 
@@ -1344,20 +1341,19 @@
 	return 0;
 }
 
-static inline int tcp_fackets_out(struct tcp_opt *tp)
+static inline int tcp_fackets_out(struct tcp_sock *tp)
 {
-	return IsReno(tp) ? tcp_get_pcount(&tp->sacked_out)+1 :
-		tcp_get_pcount(&tp->fackets_out);
+	return IsReno(tp) ? tp->sacked_out+1 : tp->fackets_out;
 }
 
-static inline int tcp_skb_timedout(struct tcp_opt *tp, struct sk_buff *skb)
+static inline int tcp_skb_timedout(struct tcp_sock *tp, struct sk_buff *skb)
 {
 	return (tcp_time_stamp - TCP_SKB_CB(skb)->when > tp->rto);
 }
 
-static inline int tcp_head_timedout(struct sock *sk, struct tcp_opt *tp)
+static inline int tcp_head_timedout(struct sock *sk, struct tcp_sock *tp)
 {
-	return tcp_get_pcount(&tp->packets_out) &&
+	return tp->packets_out &&
 	       tcp_skb_timedout(tp, skb_peek(&sk->sk_write_queue));
 }
 
@@ -1454,13 +1450,12 @@
  * Main question: may we further continue forward transmission
  * with the same cwnd?
  */
-static int
-tcp_time_to_recover(struct sock *sk, struct tcp_opt *tp)
+static int tcp_time_to_recover(struct sock *sk, struct tcp_sock *tp)
 {
 	__u32 packets_out;
 
 	/* Trick#1: The loss is proven. */
-	if (tcp_get_pcount(&tp->lost_out))
+	if (tp->lost_out)
 		return 1;
 
 	/* Not-A-Trick#2 : Classic rule... */
@@ -1476,9 +1471,9 @@
 	/* Trick#4: It is still not OK... But will it be useful to delay
 	 * recovery more?
 	 */
-	packets_out = tcp_get_pcount(&tp->packets_out);
+	packets_out = tp->packets_out;
 	if (packets_out <= tp->reordering &&
-	    tcp_get_pcount(&tp->sacked_out) >= max_t(__u32, packets_out/2, sysctl_tcp_reordering) &&
+	    tp->sacked_out >= max_t(__u32, packets_out/2, sysctl_tcp_reordering) &&
 	    !tcp_may_send_now(sk, tp)) {
 		/* We have nothing to send. This connection is limited
 		 * either by receiver window or by application.
@@ -1493,61 +1488,57 @@
  * in assumption of absent reordering, interpret this as reordering.
  * The only another reason could be bug in receiver TCP.
  */
-static void tcp_check_reno_reordering(struct tcp_opt *tp, int addend)
+static void tcp_check_reno_reordering(struct tcp_sock *tp, int addend)
 {
 	u32 holes;
 
-	holes = max(tcp_get_pcount(&tp->lost_out), 1U);
-	holes = min(holes, tcp_get_pcount(&tp->packets_out));
+	holes = max(tp->lost_out, 1U);
+	holes = min(holes, tp->packets_out);
 
-	if ((tcp_get_pcount(&tp->sacked_out) + holes) >
-	    tcp_get_pcount(&tp->packets_out)) {
-		tcp_set_pcount(&tp->sacked_out,
-			       (tcp_get_pcount(&tp->packets_out) - holes));
-		tcp_update_reordering(tp,
-				      tcp_get_pcount(&tp->packets_out)+addend,
-				      0);
+	if ((tp->sacked_out + holes) > tp->packets_out) {
+		tp->sacked_out = tp->packets_out - holes;
+		tcp_update_reordering(tp, tp->packets_out+addend, 0);
 	}
 }
 
 /* Emulate SACKs for SACKless connection: account for a new dupack. */
 
-static void tcp_add_reno_sack(struct tcp_opt *tp)
+static void tcp_add_reno_sack(struct tcp_sock *tp)
 {
-	tcp_inc_pcount_explicit(&tp->sacked_out, 1);
+	tp->sacked_out++;
 	tcp_check_reno_reordering(tp, 0);
 	tcp_sync_left_out(tp);
 }
 
 /* Account for ACK, ACKing some data in Reno Recovery phase. */
 
-static void tcp_remove_reno_sacks(struct sock *sk, struct tcp_opt *tp, int acked)
+static void tcp_remove_reno_sacks(struct sock *sk, struct tcp_sock *tp, int acked)
 {
 	if (acked > 0) {
 		/* One ACK acked hole. The rest eat duplicate ACKs. */
-		if (acked-1 >= tcp_get_pcount(&tp->sacked_out))
-			tcp_set_pcount(&tp->sacked_out, 0);
+		if (acked-1 >= tp->sacked_out)
+			tp->sacked_out = 0;
 		else
-			tcp_dec_pcount_explicit(&tp->sacked_out, acked-1);
+			tp->sacked_out -= acked-1;
 	}
 	tcp_check_reno_reordering(tp, acked);
 	tcp_sync_left_out(tp);
 }
 
-static inline void tcp_reset_reno_sack(struct tcp_opt *tp)
+static inline void tcp_reset_reno_sack(struct tcp_sock *tp)
 {
-	tcp_set_pcount(&tp->sacked_out, 0);
-	tcp_set_pcount(&tp->left_out, tcp_get_pcount(&tp->lost_out));
+	tp->sacked_out = 0;
+	tp->left_out = tp->lost_out;
 }
 
 /* Mark head of queue up as lost. */
-static void
-tcp_mark_head_lost(struct sock *sk, struct tcp_opt *tp, int packets, u32 high_seq)
+static void tcp_mark_head_lost(struct sock *sk, struct tcp_sock *tp,
+			       int packets, u32 high_seq)
 {
 	struct sk_buff *skb;
 	int cnt = packets;
 
-	BUG_TRAP(cnt <= tcp_get_pcount(&tp->packets_out));
+	BUG_TRAP(cnt <= tp->packets_out);
 
 	sk_stream_for_retrans_queue(skb, sk) {
 		cnt -= tcp_skb_pcount(skb);
@@ -1555,7 +1546,7 @@
 			break;
 		if (!(TCP_SKB_CB(skb)->sacked&TCPCB_TAGBITS)) {
 			TCP_SKB_CB(skb)->sacked |= TCPCB_LOST;
-			tcp_inc_pcount(&tp->lost_out, skb);
+			tp->lost_out += tcp_skb_pcount(skb);
 		}
 	}
 	tcp_sync_left_out(tp);
@@ -1563,10 +1554,10 @@
 
 /* Account newly detected lost packet(s) */
 
-static void tcp_update_scoreboard(struct sock *sk, struct tcp_opt *tp)
+static void tcp_update_scoreboard(struct sock *sk, struct tcp_sock *tp)
 {
 	if (IsFack(tp)) {
-		int lost = tcp_get_pcount(&tp->fackets_out) - tp->reordering;
+		int lost = tp->fackets_out - tp->reordering;
 		if (lost <= 0)
 			lost = 1;
 		tcp_mark_head_lost(sk, tp, lost, tp->high_seq);
@@ -1586,7 +1577,7 @@
 			if (tcp_skb_timedout(tp, skb) &&
 			    !(TCP_SKB_CB(skb)->sacked&TCPCB_TAGBITS)) {
 				TCP_SKB_CB(skb)->sacked |= TCPCB_LOST;
-				tcp_inc_pcount(&tp->lost_out, skb);
+				tp->lost_out += tcp_skb_pcount(skb);
 			}
 		}
 		tcp_sync_left_out(tp);
@@ -1596,7 +1587,7 @@
 /* CWND moderation, preventing bursts due to too big ACKs
  * in dubious situations.
  */
-static __inline__ void tcp_moderate_cwnd(struct tcp_opt *tp)
+static inline void tcp_moderate_cwnd(struct tcp_sock *tp)
 {
 	tp->snd_cwnd = min(tp->snd_cwnd,
 			   tcp_packets_in_flight(tp)+tcp_max_burst(tp));
@@ -1605,7 +1596,7 @@
 
 /* Decrease cwnd each second ack. */
 
-static void tcp_cwnd_down(struct tcp_opt *tp)
+static void tcp_cwnd_down(struct tcp_sock *tp)
 {
 	int decr = tp->snd_cwnd_cnt + 1;
 	__u32 limit;
@@ -1635,31 +1626,31 @@
 /* Nothing was retransmitted or returned timestamp is less
  * than timestamp of the first retransmission.
  */
-static __inline__ int tcp_packet_delayed(struct tcp_opt *tp)
+static inline int tcp_packet_delayed(struct tcp_sock *tp)
 {
 	return !tp->retrans_stamp ||
-		(tp->saw_tstamp && tp->rcv_tsecr &&
-		 (__s32)(tp->rcv_tsecr - tp->retrans_stamp) < 0);
+		(tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr &&
+		 (__s32)(tp->rx_opt.rcv_tsecr - tp->retrans_stamp) < 0);
 }
 
 /* Undo procedures. */
 
 #if FASTRETRANS_DEBUG > 1
-static void DBGUNDO(struct sock *sk, struct tcp_opt *tp, const char *msg)
+static void DBGUNDO(struct sock *sk, struct tcp_sock *tp, const char *msg)
 {
-	struct inet_opt *inet = inet_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
 	printk(KERN_DEBUG "Undo %s %u.%u.%u.%u/%u c%u l%u ss%u/%u p%u\n",
 	       msg,
 	       NIPQUAD(inet->daddr), ntohs(inet->dport),
-	       tp->snd_cwnd, tcp_get_pcount(&tp->left_out),
+	       tp->snd_cwnd, tp->left_out,
 	       tp->snd_ssthresh, tp->prior_ssthresh,
-	       tcp_get_pcount(&tp->packets_out));
+	       tp->packets_out);
 }
 #else
 #define DBGUNDO(x...) do { } while (0)
 #endif
 
-static void tcp_undo_cwr(struct tcp_opt *tp, int undo)
+static void tcp_undo_cwr(struct tcp_sock *tp, int undo)
 {
 	if (tp->prior_ssthresh) {
 		tp->snd_cwnd = max(tp->snd_cwnd, tp->snd_ssthresh<<1);
@@ -1675,14 +1666,14 @@
 	tp->snd_cwnd_stamp = tcp_time_stamp;
 }
 
-static inline int tcp_may_undo(struct tcp_opt *tp)
+static inline int tcp_may_undo(struct tcp_sock *tp)
 {
 	return tp->undo_marker &&
 		(!tp->undo_retrans || tcp_packet_delayed(tp));
 }
 
 /* People celebrate: "We love our President!" */
-static int tcp_try_undo_recovery(struct sock *sk, struct tcp_opt *tp)
+static int tcp_try_undo_recovery(struct sock *sk, struct tcp_sock *tp)
 {
 	if (tcp_may_undo(tp)) {
 		/* Happy end! We did not retransmit anything
@@ -1708,7 +1699,7 @@
 }
 
 /* Try to undo cwnd reduction, because D-SACKs acked all retransmitted data */
-static void tcp_try_undo_dsack(struct sock *sk, struct tcp_opt *tp)
+static void tcp_try_undo_dsack(struct sock *sk, struct tcp_sock *tp)
 {
 	if (tp->undo_marker && !tp->undo_retrans) {
 		DBGUNDO(sk, tp, "D-SACK");
@@ -1720,16 +1711,17 @@
 
 /* Undo during fast recovery after partial ACK. */
 
-static int tcp_try_undo_partial(struct sock *sk, struct tcp_opt *tp, int acked)
+static int tcp_try_undo_partial(struct sock *sk, struct tcp_sock *tp,
+				int acked)
 {
 	/* Partial ACK arrived. Force Hoe's retransmit. */
-	int failed = IsReno(tp) || tcp_get_pcount(&tp->fackets_out)>tp->reordering;
+	int failed = IsReno(tp) || tp->fackets_out>tp->reordering;
 
 	if (tcp_may_undo(tp)) {
 		/* Plain luck! Hole if filled with delayed
 		 * packet, rather than with a retransmit.
 		 */
-		if (tcp_get_pcount(&tp->retrans_out) == 0)
+		if (tp->retrans_out == 0)
 			tp->retrans_stamp = 0;
 
 		tcp_update_reordering(tp, tcp_fackets_out(tp)+acked, 1);
@@ -1748,7 +1740,7 @@
 }
 
 /* Undo during loss recovery after partial ACK. */
-static int tcp_try_undo_loss(struct sock *sk, struct tcp_opt *tp)
+static int tcp_try_undo_loss(struct sock *sk, struct tcp_sock *tp)
 {
 	if (tcp_may_undo(tp)) {
 		struct sk_buff *skb;
@@ -1756,8 +1748,8 @@
 			TCP_SKB_CB(skb)->sacked &= ~TCPCB_LOST;
 		}
 		DBGUNDO(sk, tp, "partial loss");
-		tcp_set_pcount(&tp->lost_out, 0);
-		tcp_set_pcount(&tp->left_out, tcp_get_pcount(&tp->sacked_out));
+		tp->lost_out = 0;
+		tp->left_out = tp->sacked_out;
 		tcp_undo_cwr(tp, 1);
 		NET_INC_STATS_BH(LINUX_MIB_TCPLOSSUNDO);
 		tp->retransmits = 0;
@@ -1769,7 +1761,7 @@
 	return 0;
 }
 
-static __inline__ void tcp_complete_cwr(struct tcp_opt *tp)
+static inline void tcp_complete_cwr(struct tcp_sock *tp)
 {
 	if (tcp_westwood_cwnd(tp)) 
 		tp->snd_ssthresh = tp->snd_cwnd;
@@ -1778,11 +1770,11 @@
 	tp->snd_cwnd_stamp = tcp_time_stamp;
 }
 
-static void tcp_try_to_open(struct sock *sk, struct tcp_opt *tp, int flag)
+static void tcp_try_to_open(struct sock *sk, struct tcp_sock *tp, int flag)
 {
-	tcp_set_pcount(&tp->left_out, tcp_get_pcount(&tp->sacked_out));
+	tp->left_out = tp->sacked_out;
 
-	if (tcp_get_pcount(&tp->retrans_out) == 0)
+	if (tp->retrans_out == 0)
 		tp->retrans_stamp = 0;
 
 	if (flag&FLAG_ECE)
@@ -1791,9 +1783,7 @@
 	if (tp->ca_state != TCP_CA_CWR) {
 		int state = TCP_CA_Open;
 
-		if (tcp_get_pcount(&tp->left_out) ||
-		    tcp_get_pcount(&tp->retrans_out) ||
-		    tp->undo_marker)
+		if (tp->left_out || tp->retrans_out || tp->undo_marker)
 			state = TCP_CA_Disorder;
 
 		if (tp->ca_state != state) {
@@ -1821,16 +1811,16 @@
 tcp_fastretrans_alert(struct sock *sk, u32 prior_snd_una,
 		      int prior_packets, int flag)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	int is_dupack = (tp->snd_una == prior_snd_una && !(flag&FLAG_NOT_DUP));
 
 	/* Some technical things:
 	 * 1. Reno does not count dupacks (sacked_out) automatically. */
-	if (!tcp_get_pcount(&tp->packets_out))
-		tcp_set_pcount(&tp->sacked_out, 0);
+	if (!tp->packets_out)
+		tp->sacked_out = 0;
         /* 2. SACK counts snd_fack in packets inaccurately. */
-	if (tcp_get_pcount(&tp->sacked_out) == 0)
-		tcp_set_pcount(&tp->fackets_out, 0);
+	if (tp->sacked_out == 0)
+		tp->fackets_out = 0;
 
         /* Now state machine starts.
 	 * A. ECE, hence prohibit cwnd undoing, the reduction is required. */
@@ -1838,15 +1828,15 @@
 		tp->prior_ssthresh = 0;
 
 	/* B. In all the states check for reneging SACKs. */
-	if (tcp_get_pcount(&tp->sacked_out) && tcp_check_sack_reneging(sk, tp))
+	if (tp->sacked_out && tcp_check_sack_reneging(sk, tp))
 		return;
 
 	/* C. Process data loss notification, provided it is valid. */
 	if ((flag&FLAG_DATA_LOST) &&
 	    before(tp->snd_una, tp->high_seq) &&
 	    tp->ca_state != TCP_CA_Open &&
-	    tcp_get_pcount(&tp->fackets_out) > tp->reordering) {
-		tcp_mark_head_lost(sk, tp, tcp_get_pcount(&tp->fackets_out)-tp->reordering, tp->high_seq);
+	    tp->fackets_out > tp->reordering) {
+		tcp_mark_head_lost(sk, tp, tp->fackets_out-tp->reordering, tp->high_seq);
 		NET_INC_STATS_BH(LINUX_MIB_TCPLOSS);
 	}
 
@@ -1857,7 +1847,7 @@
 	 *    when high_seq is ACKed. */
 	if (tp->ca_state == TCP_CA_Open) {
 		if (!sysctl_tcp_frto)
-			BUG_TRAP(tcp_get_pcount(&tp->retrans_out) == 0);
+			BUG_TRAP(tp->retrans_out == 0);
 		tp->retrans_stamp = 0;
 	} else if (!before(tp->snd_una, tp->high_seq)) {
 		switch (tp->ca_state) {
@@ -1904,8 +1894,7 @@
 			if (IsReno(tp) && is_dupack)
 				tcp_add_reno_sack(tp);
 		} else {
-			int acked = prior_packets -
-				tcp_get_pcount(&tp->packets_out);
+			int acked = prior_packets - tp->packets_out;
 			if (IsReno(tp))
 				tcp_remove_reno_sacks(sk, tp, acked);
 			is_dupack = tcp_try_undo_partial(sk, tp, acked);
@@ -1948,7 +1937,7 @@
 		tp->high_seq = tp->snd_nxt;
 		tp->prior_ssthresh = 0;
 		tp->undo_marker = tp->snd_una;
-		tp->undo_retrans = tcp_get_pcount(&tp->retrans_out);
+		tp->undo_retrans = tp->retrans_out;
 
 		if (tp->ca_state < TCP_CA_CWR) {
 			if (!(flag&FLAG_ECE))
@@ -1970,7 +1959,7 @@
 /* Read draft-ietf-tcplw-high-performance before mucking
  * with this code. (Superceeds RFC1323)
  */
-static void tcp_ack_saw_tstamp(struct tcp_opt *tp, int flag)
+static void tcp_ack_saw_tstamp(struct tcp_sock *tp, int flag)
 {
 	__u32 seq_rtt;
 
@@ -1989,14 +1978,14 @@
 	 * answer arrives rto becomes 120 seconds! If at least one of segments
 	 * in window is lost... Voila.	 			--ANK (010210)
 	 */
-	seq_rtt = tcp_time_stamp - tp->rcv_tsecr;
+	seq_rtt = tcp_time_stamp - tp->rx_opt.rcv_tsecr;
 	tcp_rtt_estimator(tp, seq_rtt);
 	tcp_set_rto(tp);
 	tp->backoff = 0;
 	tcp_bound_rto(tp);
 }
 
-static void tcp_ack_no_tstamp(struct tcp_opt *tp, u32 seq_rtt, int flag)
+static void tcp_ack_no_tstamp(struct tcp_sock *tp, u32 seq_rtt, int flag)
 {
 	/* We don't have a timestamp. Can only use
 	 * packets that are not retransmitted to determine
@@ -2016,11 +2005,11 @@
 	tcp_bound_rto(tp);
 }
 
-static __inline__ void
-tcp_ack_update_rtt(struct tcp_opt *tp, int flag, s32 seq_rtt)
+static inline void tcp_ack_update_rtt(struct tcp_sock *tp,
+				      int flag, s32 seq_rtt)
 {
 	/* Note that peer MAY send zero echo. In this case it is ignored. (rfc1323) */
-	if (tp->saw_tstamp && tp->rcv_tsecr)
+	if (tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr)
 		tcp_ack_saw_tstamp(tp, flag);
 	else if (seq_rtt >= 0)
 		tcp_ack_no_tstamp(tp, seq_rtt, flag);
@@ -2039,7 +2028,7 @@
  * Unless BIC is enabled and congestion window is large
  * this behaves the same as the original Reno.
  */
-static inline __u32 bictcp_cwnd(struct tcp_opt *tp)
+static inline __u32 bictcp_cwnd(struct tcp_sock *tp)
 {
 	/* orignal Reno behaviour */
 	if (!tcp_is_bic(tp))
@@ -2092,7 +2081,7 @@
 /* This is Jacobson's slow start and congestion avoidance. 
  * SIGCOMM '88, p. 328.
  */
-static __inline__ void reno_cong_avoid(struct tcp_opt *tp)
+static inline void reno_cong_avoid(struct tcp_sock *tp)
 {
         if (tp->snd_cwnd <= tp->snd_ssthresh) {
                 /* In "safe" area, increase. */
@@ -2141,7 +2130,7 @@
  *     a cwnd adjustment decision. The original Vegas implementation
  *     assumed senders never went idle.
  */
-static void vegas_cong_avoid(struct tcp_opt *tp, u32 ack, u32 seq_rtt)
+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.
 	 *
@@ -2334,7 +2323,7 @@
 	tp->snd_cwnd_stamp = tcp_time_stamp;
 }
 
-static inline void tcp_cong_avoid(struct tcp_opt *tp, u32 ack, u32 seq_rtt)
+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);
@@ -2346,9 +2335,9 @@
  * RFC2988 recommends to restart timer to now+rto.
  */
 
-static __inline__ void tcp_ack_packets_out(struct sock *sk, struct tcp_opt *tp)
+static inline void tcp_ack_packets_out(struct sock *sk, struct tcp_sock *tp)
 {
-	if (!tcp_get_pcount(&tp->packets_out)) {
+	if (!tp->packets_out) {
 		tcp_clear_xmit_timer(sk, TCP_TIME_RETRANS);
 	} else {
 		tcp_reset_xmit_timer(sk, TCP_TIME_RETRANS, tp->rto);
@@ -2367,7 +2356,7 @@
 static int tcp_tso_acked(struct sock *sk, struct sk_buff *skb,
 			 __u32 now, __s32 *seq_rtt)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	struct tcp_skb_cb *scb = TCP_SKB_CB(skb); 
 	__u32 seq = tp->snd_una;
 	__u32 packets_acked;
@@ -2390,18 +2379,15 @@
 		if (sacked) {
 			if (sacked & TCPCB_RETRANS) {
 				if (sacked & TCPCB_SACKED_RETRANS)
-					tcp_dec_pcount_explicit(&tp->retrans_out,
-								packets_acked);
+					tp->retrans_out -= packets_acked;
 				acked |= FLAG_RETRANS_DATA_ACKED;
 				*seq_rtt = -1;
 			} else if (*seq_rtt < 0)
 				*seq_rtt = now - scb->when;
 			if (sacked & TCPCB_SACKED_ACKED)
-				tcp_dec_pcount_explicit(&tp->sacked_out,
-							packets_acked);
+				tp->sacked_out -= packets_acked;
 			if (sacked & TCPCB_LOST)
-				tcp_dec_pcount_explicit(&tp->lost_out,
-							packets_acked);
+				tp->lost_out -= packets_acked;
 			if (sacked & TCPCB_URG) {
 				if (tp->urg_mode &&
 				    !before(seq, tp->snd_up))
@@ -2410,12 +2396,11 @@
 		} else if (*seq_rtt < 0)
 			*seq_rtt = now - scb->when;
 
-		if (tcp_get_pcount(&tp->fackets_out)) {
-			__u32 dval = min(tcp_get_pcount(&tp->fackets_out),
-					 packets_acked);
-			tcp_dec_pcount_explicit(&tp->fackets_out, dval);
+		if (tp->fackets_out) {
+			__u32 dval = min(tp->fackets_out, packets_acked);
+			tp->fackets_out -= dval;
 		}
-		tcp_dec_pcount_explicit(&tp->packets_out, packets_acked);
+		tp->packets_out -= packets_acked;
 
 		BUG_ON(tcp_skb_pcount(skb) == 0);
 		BUG_ON(!before(scb->seq, scb->end_seq));
@@ -2428,7 +2413,7 @@
 /* Remove acknowledged frames from the retransmission queue. */
 static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	struct sk_buff *skb;
 	__u32 now = tcp_time_stamp;
 	int acked = 0;
@@ -2467,15 +2452,15 @@
 		if (sacked) {
 			if (sacked & TCPCB_RETRANS) {
 				if(sacked & TCPCB_SACKED_RETRANS)
-					tcp_dec_pcount(&tp->retrans_out, skb);
+					tp->retrans_out -= tcp_skb_pcount(skb);
 				acked |= FLAG_RETRANS_DATA_ACKED;
 				seq_rtt = -1;
 			} else if (seq_rtt < 0)
 				seq_rtt = now - scb->when;
 			if (sacked & TCPCB_SACKED_ACKED)
-				tcp_dec_pcount(&tp->sacked_out, skb);
+				tp->sacked_out -= tcp_skb_pcount(skb);
 			if (sacked & TCPCB_LOST)
-				tcp_dec_pcount(&tp->lost_out, skb);
+				tp->lost_out -= tcp_skb_pcount(skb);
 			if (sacked & TCPCB_URG) {
 				if (tp->urg_mode &&
 				    !before(scb->end_seq, tp->snd_up))
@@ -2495,27 +2480,24 @@
 	}
 
 #if FASTRETRANS_DEBUG > 0
-	BUG_TRAP((int)tcp_get_pcount(&tp->sacked_out) >= 0);
-	BUG_TRAP((int)tcp_get_pcount(&tp->lost_out) >= 0);
-	BUG_TRAP((int)tcp_get_pcount(&tp->retrans_out) >= 0);
-	if (!tcp_get_pcount(&tp->packets_out) && tp->sack_ok) {
-		if (tcp_get_pcount(&tp->lost_out)) {
+	BUG_TRAP((int)tp->sacked_out >= 0);
+	BUG_TRAP((int)tp->lost_out >= 0);
+	BUG_TRAP((int)tp->retrans_out >= 0);
+	if (!tp->packets_out && tp->rx_opt.sack_ok) {
+		if (tp->lost_out) {
 			printk(KERN_DEBUG "Leak l=%u %d\n",
-			       tcp_get_pcount(&tp->lost_out),
-			       tp->ca_state);
-			tcp_set_pcount(&tp->lost_out, 0);
+			       tp->lost_out, tp->ca_state);
+			tp->lost_out = 0;
 		}
-		if (tcp_get_pcount(&tp->sacked_out)) {
+		if (tp->sacked_out) {
 			printk(KERN_DEBUG "Leak s=%u %d\n",
-			       tcp_get_pcount(&tp->sacked_out),
-			       tp->ca_state);
-			tcp_set_pcount(&tp->sacked_out, 0);
+			       tp->sacked_out, tp->ca_state);
+			tp->sacked_out = 0;
 		}
-		if (tcp_get_pcount(&tp->retrans_out)) {
+		if (tp->retrans_out) {
 			printk(KERN_DEBUG "Leak r=%u %d\n",
-			       tcp_get_pcount(&tp->retrans_out),
-			       tp->ca_state);
-			tcp_set_pcount(&tp->retrans_out, 0);
+			       tp->retrans_out, tp->ca_state);
+			tp->retrans_out = 0;
 		}
 	}
 #endif
@@ -2525,7 +2507,7 @@
 
 static void tcp_ack_probe(struct sock *sk)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 
 	/* Was it a usable window open? */
 
@@ -2542,13 +2524,13 @@
 	}
 }
 
-static __inline__ int tcp_ack_is_dubious(struct tcp_opt *tp, int flag)
+static inline int tcp_ack_is_dubious(struct tcp_sock *tp, int flag)
 {
 	return (!(flag & FLAG_NOT_DUP) || (flag & FLAG_CA_ALERT) ||
 		tp->ca_state != TCP_CA_Open);
 }
 
-static __inline__ int tcp_may_raise_cwnd(struct tcp_opt *tp, int flag)
+static inline int tcp_may_raise_cwnd(struct tcp_sock *tp, int flag)
 {
 	return (!(flag & FLAG_ECE) || tp->snd_cwnd < tp->snd_ssthresh) &&
 		!((1<<tp->ca_state)&(TCPF_CA_Recovery|TCPF_CA_CWR));
@@ -2557,8 +2539,8 @@
 /* Check that window update is acceptable.
  * The function assumes that snd_una<=ack<=snd_next.
  */
-static __inline__ int
-tcp_may_update_window(struct tcp_opt *tp, u32 ack, u32 ack_seq, u32 nwin)
+static inline int tcp_may_update_window(struct tcp_sock *tp, u32 ack,
+					u32 ack_seq, u32 nwin)
 {
 	return (after(ack, tp->snd_una) ||
 		after(ack_seq, tp->snd_wl1) ||
@@ -2570,14 +2552,14 @@
  * Window update algorithm, described in RFC793/RFC1122 (used in linux-2.2
  * and in FreeBSD. NetBSD's one is even worse.) is wrong.
  */
-static int tcp_ack_update_window(struct sock *sk, struct tcp_opt *tp,
+static int tcp_ack_update_window(struct sock *sk, struct tcp_sock *tp,
 				 struct sk_buff *skb, u32 ack, u32 ack_seq)
 {
 	int flag = 0;
 	u32 nwin = ntohs(skb->h.th->window);
 
 	if (likely(!skb->h.th->syn))
-		nwin <<= tp->snd_wscale;
+		nwin <<= tp->rx_opt.snd_wscale;
 
 	if (tcp_may_update_window(tp, ack, ack_seq, nwin)) {
 		flag |= FLAG_WIN_UPDATE;
@@ -2605,7 +2587,7 @@
 
 static void tcp_process_frto(struct sock *sk, u32 prior_snd_una)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	
 	tcp_sync_left_out(tp);
 	
@@ -2654,7 +2636,7 @@
 
 static void init_westwood(struct sock *sk)
 {
-        struct tcp_opt *tp = tcp_sk(sk);
+        struct tcp_sock *tp = tcp_sk(sk);
 
         tp->westwood.bw_ns_est = 0;
         tp->westwood.bw_est = 0;
@@ -2678,7 +2660,7 @@
 
 static void westwood_filter(struct sock *sk, __u32 delta)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 
 	tp->westwood.bw_ns_est =
 		westwood_do_filter(tp->westwood.bw_ns_est, 
@@ -2696,7 +2678,7 @@
 
 static inline __u32 westwood_update_rttmin(const struct sock *sk)
 {
-	const struct tcp_opt *tp = tcp_sk(sk);
+	const struct tcp_sock *tp = tcp_sk(sk);
 	__u32 rttmin = tp->westwood.rtt_min;
 
 	if (tp->westwood.rtt != 0 &&
@@ -2713,7 +2695,7 @@
 
 static inline __u32 westwood_acked(const struct sock *sk)
 {
-	const struct tcp_opt *tp = tcp_sk(sk);
+	const struct tcp_sock *tp = tcp_sk(sk);
 
 	return tp->snd_una - tp->westwood.snd_una;
 }
@@ -2729,7 +2711,7 @@
 
 static int westwood_new_window(const struct sock *sk)
 {
-	const struct tcp_opt *tp = tcp_sk(sk);
+	const struct tcp_sock *tp = tcp_sk(sk);
 	__u32 left_bound;
 	__u32 rtt;
 	int ret = 0;
@@ -2760,7 +2742,7 @@
 
 static void __westwood_update_window(struct sock *sk, __u32 now)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	__u32 delta = now - tp->westwood.rtt_win_sx;
 
         if (delta) {
@@ -2786,9 +2768,9 @@
  * straight forward and doesn't need any particular care.
  */
 
-void __tcp_westwood_fast_bw(struct sock *sk, struct sk_buff *skb)
+static void __tcp_westwood_fast_bw(struct sock *sk, struct sk_buff *skb)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 
 	westwood_update_window(sk, tcp_time_stamp);
 
@@ -2797,6 +2779,12 @@
 	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
@@ -2805,24 +2793,24 @@
 
 static void westwood_dupack_update(struct sock *sk)
 {
-	struct tcp_opt *tp = tcp_sk(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_opt *tp)
+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_opt *tp)
+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_opt *tp)
+static inline void westwood_complete_update(struct tcp_sock *tp)
 {
 	tp->westwood.cumul_ack -= tp->westwood.accounted;
 	tp->westwood.accounted = 0;
@@ -2836,7 +2824,7 @@
 
 static inline __u32 westwood_acked_count(struct sock *sk)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 
 	tp->westwood.cumul_ack = westwood_acked(sk);
 
@@ -2867,9 +2855,9 @@
  * dupack. But we need to be careful in such case.
  */
 
-void __tcp_westwood_slow_bw(struct sock *sk, struct sk_buff *skb)
+static void __tcp_westwood_slow_bw(struct sock *sk, struct sk_buff *skb)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 
 	westwood_update_window(sk, tcp_time_stamp);
 
@@ -2877,10 +2865,16 @@
 	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)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	u32 prior_snd_una = tp->snd_una;
 	u32 ack_seq = TCP_SKB_CB(skb)->seq;
 	u32 ack = TCP_SKB_CB(skb)->ack_seq;
@@ -2930,7 +2924,7 @@
 	 */
 	sk->sk_err_soft = 0;
 	tp->rcv_tstamp = tcp_time_stamp;
-	prior_packets = tcp_get_pcount(&tp->packets_out);
+	prior_packets = tp->packets_out;
 	if (!prior_packets)
 		goto no_queue;
 
@@ -2985,14 +2979,14 @@
  * But, this can also be called on packets in the established flow when
  * the fast version below fails.
  */
-void tcp_parse_options(struct sk_buff *skb, struct tcp_opt *tp, int estab)
+void tcp_parse_options(struct sk_buff *skb, struct tcp_options_received *opt_rx, int estab)
 {
 	unsigned char *ptr;
 	struct tcphdr *th = skb->h.th;
 	int length=(th->doff*4)-sizeof(struct tcphdr);
 
 	ptr = (unsigned char *)(th + 1);
-	tp->saw_tstamp = 0;
+	opt_rx->saw_tstamp = 0;
 
 	while(length>0) {
 	  	int opcode=*ptr++;
@@ -3015,41 +3009,41 @@
 					if(opsize==TCPOLEN_MSS && th->syn && !estab) {
 						u16 in_mss = ntohs(*(__u16 *)ptr);
 						if (in_mss) {
-							if (tp->user_mss && tp->user_mss < in_mss)
-								in_mss = tp->user_mss;
-							tp->mss_clamp = in_mss;
+							if (opt_rx->user_mss && opt_rx->user_mss < in_mss)
+								in_mss = opt_rx->user_mss;
+							opt_rx->mss_clamp = in_mss;
 						}
 					}
 					break;
 				case TCPOPT_WINDOW:
 					if(opsize==TCPOLEN_WINDOW && th->syn && !estab)
 						if (sysctl_tcp_window_scaling) {
-							tp->wscale_ok = 1;
-							tp->snd_wscale = *(__u8 *)ptr;
-							if(tp->snd_wscale > 14) {
+							opt_rx->wscale_ok = 1;
+							opt_rx->snd_wscale = *(__u8 *)ptr;
+							if(opt_rx->snd_wscale > 14) {
 								if(net_ratelimit())
 									printk(KERN_INFO "tcp_parse_options: Illegal window "
 									       "scaling value %d >14 received.\n",
-									       tp->snd_wscale);
-								tp->snd_wscale = 14;
+									       opt_rx->snd_wscale);
+								opt_rx->snd_wscale = 14;
 							}
 						}
 					break;
 				case TCPOPT_TIMESTAMP:
 					if(opsize==TCPOLEN_TIMESTAMP) {
-						if ((estab && tp->tstamp_ok) ||
+						if ((estab && opt_rx->tstamp_ok) ||
 						    (!estab && sysctl_tcp_timestamps)) {
-							tp->saw_tstamp = 1;
-							tp->rcv_tsval = ntohl(*(__u32 *)ptr);
-							tp->rcv_tsecr = ntohl(*(__u32 *)(ptr+4));
+							opt_rx->saw_tstamp = 1;
+							opt_rx->rcv_tsval = ntohl(*(__u32 *)ptr);
+							opt_rx->rcv_tsecr = ntohl(*(__u32 *)(ptr+4));
 						}
 					}
 					break;
 				case TCPOPT_SACK_PERM:
 					if(opsize==TCPOLEN_SACK_PERM && th->syn && !estab) {
 						if (sysctl_tcp_sack) {
-							tp->sack_ok = 1;
-							tcp_sack_reset(tp);
+							opt_rx->sack_ok = 1;
+							tcp_sack_reset(opt_rx);
 						}
 					}
 					break;
@@ -3057,7 +3051,7 @@
 				case TCPOPT_SACK:
 					if((opsize >= (TCPOLEN_SACK_BASE + TCPOLEN_SACK_PERBLOCK)) &&
 					   !((opsize - TCPOLEN_SACK_BASE) % TCPOLEN_SACK_PERBLOCK) &&
-					   tp->sack_ok) {
+					   opt_rx->sack_ok) {
 						TCP_SKB_CB(skb)->sacked = (ptr - 2) - (unsigned char *)th;
 					}
 	  			};
@@ -3070,39 +3064,38 @@
 /* Fast parse options. This hopes to only see timestamps.
  * If it is wrong it falls back on tcp_parse_options().
  */
-static __inline__ int tcp_fast_parse_options(struct sk_buff *skb, struct tcphdr *th, struct tcp_opt *tp)
+static inline int tcp_fast_parse_options(struct sk_buff *skb, struct tcphdr *th,
+					 struct tcp_sock *tp)
 {
 	if (th->doff == sizeof(struct tcphdr)>>2) {
-		tp->saw_tstamp = 0;
+		tp->rx_opt.saw_tstamp = 0;
 		return 0;
-	} else if (tp->tstamp_ok &&
+	} else if (tp->rx_opt.tstamp_ok &&
 		   th->doff == (sizeof(struct tcphdr)>>2)+(TCPOLEN_TSTAMP_ALIGNED>>2)) {
 		__u32 *ptr = (__u32 *)(th + 1);
 		if (*ptr == ntohl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16)
 				  | (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP)) {
-			tp->saw_tstamp = 1;
+			tp->rx_opt.saw_tstamp = 1;
 			++ptr;
-			tp->rcv_tsval = ntohl(*ptr);
+			tp->rx_opt.rcv_tsval = ntohl(*ptr);
 			++ptr;
-			tp->rcv_tsecr = ntohl(*ptr);
+			tp->rx_opt.rcv_tsecr = ntohl(*ptr);
 			return 1;
 		}
 	}
-	tcp_parse_options(skb, tp, 1);
+	tcp_parse_options(skb, &tp->rx_opt, 1);
 	return 1;
 }
 
-static __inline__ void
-tcp_store_ts_recent(struct tcp_opt *tp)
+static inline void tcp_store_ts_recent(struct tcp_sock *tp)
 {
-	tp->ts_recent = tp->rcv_tsval;
-	tp->ts_recent_stamp = xtime.tv_sec;
+	tp->rx_opt.ts_recent = tp->rx_opt.rcv_tsval;
+	tp->rx_opt.ts_recent_stamp = xtime.tv_sec;
 }
 
-static __inline__ void
-tcp_replace_ts_recent(struct tcp_opt *tp, u32 seq)
+static inline void tcp_replace_ts_recent(struct tcp_sock *tp, u32 seq)
 {
-	if (tp->saw_tstamp && !after(seq, tp->rcv_wup)) {
+	if (tp->rx_opt.saw_tstamp && !after(seq, tp->rcv_wup)) {
 		/* PAWS bug workaround wrt. ACK frames, the PAWS discard
 		 * extra check below makes sure this can only happen
 		 * for pure ACK frames.  -DaveM
@@ -3110,8 +3103,8 @@
 		 * Not only, also it occurs for expired timestamps.
 		 */
 
-		if((s32)(tp->rcv_tsval - tp->ts_recent) >= 0 ||
-		   xtime.tv_sec >= tp->ts_recent_stamp + TCP_PAWS_24DAYS)
+		if((s32)(tp->rx_opt.rcv_tsval - tp->rx_opt.ts_recent) >= 0 ||
+		   xtime.tv_sec >= tp->rx_opt.ts_recent_stamp + TCP_PAWS_24DAYS)
 			tcp_store_ts_recent(tp);
 	}
 }
@@ -3139,7 +3132,7 @@
  * up to bandwidth of 18Gigabit/sec. 8) ]
  */
 
-static int tcp_disordered_ack(struct tcp_opt *tp, struct sk_buff *skb)
+static int tcp_disordered_ack(struct tcp_sock *tp, struct sk_buff *skb)
 {
 	struct tcphdr *th = skb->h.th;
 	u32 seq = TCP_SKB_CB(skb)->seq;
@@ -3152,16 +3145,16 @@
 		ack == tp->snd_una &&
 
 		/* 3. ... and does not update window. */
-		!tcp_may_update_window(tp, ack, seq, ntohs(th->window)<<tp->snd_wscale) &&
+		!tcp_may_update_window(tp, ack, seq, ntohs(th->window) << tp->rx_opt.snd_wscale) &&
 
 		/* 4. ... and sits in replay window. */
-		(s32)(tp->ts_recent - tp->rcv_tsval) <= (tp->rto*1024)/HZ);
+		(s32)(tp->rx_opt.ts_recent - tp->rx_opt.rcv_tsval) <= (tp->rto*1024)/HZ);
 }
 
-static __inline__ int tcp_paws_discard(struct tcp_opt *tp, struct sk_buff *skb)
+static inline int tcp_paws_discard(struct tcp_sock *tp, struct sk_buff *skb)
 {
-	return ((s32)(tp->ts_recent - tp->rcv_tsval) > TCP_PAWS_WINDOW &&
-		xtime.tv_sec < tp->ts_recent_stamp + TCP_PAWS_24DAYS &&
+	return ((s32)(tp->rx_opt.ts_recent - tp->rx_opt.rcv_tsval) > TCP_PAWS_WINDOW &&
+		xtime.tv_sec < tp->rx_opt.ts_recent_stamp + TCP_PAWS_24DAYS &&
 		!tcp_disordered_ack(tp, skb));
 }
 
@@ -3178,7 +3171,7 @@
  * (borrowed from freebsd)
  */
 
-static inline int tcp_sequence(struct tcp_opt *tp, u32 seq, u32 end_seq)
+static inline int tcp_sequence(struct tcp_sock *tp, u32 seq, u32 end_seq)
 {
 	return	!before(end_seq, tp->rcv_wup) &&
 		!after(seq, tp->rcv_nxt + tcp_receive_window(tp));
@@ -3223,7 +3216,7 @@
  */
 static void tcp_fin(struct sk_buff *skb, struct sock *sk, struct tcphdr *th)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 
 	tcp_schedule_ack(tp);
 
@@ -3274,8 +3267,8 @@
 	 * Probably, we should reset in this case. For now drop them.
 	 */
 	__skb_queue_purge(&tp->out_of_order_queue);
-	if (tp->sack_ok)
-		tcp_sack_reset(tp);
+	if (tp->rx_opt.sack_ok)
+		tcp_sack_reset(&tp->rx_opt);
 	sk_stream_mem_reclaim(sk);
 
 	if (!sock_flag(sk, SOCK_DEAD)) {
@@ -3303,24 +3296,24 @@
 	return 0;
 }
 
-static __inline__ void tcp_dsack_set(struct tcp_opt *tp, u32 seq, u32 end_seq)
+static inline void tcp_dsack_set(struct tcp_sock *tp, u32 seq, u32 end_seq)
 {
-	if (tp->sack_ok && sysctl_tcp_dsack) {
+	if (tp->rx_opt.sack_ok && sysctl_tcp_dsack) {
 		if (before(seq, tp->rcv_nxt))
 			NET_INC_STATS_BH(LINUX_MIB_TCPDSACKOLDSENT);
 		else
 			NET_INC_STATS_BH(LINUX_MIB_TCPDSACKOFOSENT);
 
-		tp->dsack = 1;
+		tp->rx_opt.dsack = 1;
 		tp->duplicate_sack[0].start_seq = seq;
 		tp->duplicate_sack[0].end_seq = end_seq;
-		tp->eff_sacks = min(tp->num_sacks+1, 4-tp->tstamp_ok);
+		tp->rx_opt.eff_sacks = min(tp->rx_opt.num_sacks + 1, 4 - tp->rx_opt.tstamp_ok);
 	}
 }
 
-static __inline__ void tcp_dsack_extend(struct tcp_opt *tp, u32 seq, u32 end_seq)
+static inline void tcp_dsack_extend(struct tcp_sock *tp, u32 seq, u32 end_seq)
 {
-	if (!tp->dsack)
+	if (!tp->rx_opt.dsack)
 		tcp_dsack_set(tp, seq, end_seq);
 	else
 		tcp_sack_extend(tp->duplicate_sack, seq, end_seq);
@@ -3328,14 +3321,14 @@
 
 static void tcp_send_dupack(struct sock *sk, struct sk_buff *skb)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 
 	if (TCP_SKB_CB(skb)->end_seq != TCP_SKB_CB(skb)->seq &&
 	    before(TCP_SKB_CB(skb)->seq, tp->rcv_nxt)) {
 		NET_INC_STATS_BH(LINUX_MIB_DELAYEDACKLOST);
 		tcp_enter_quickack_mode(tp);
 
-		if (tp->sack_ok && sysctl_tcp_dsack) {
+		if (tp->rx_opt.sack_ok && sysctl_tcp_dsack) {
 			u32 end_seq = TCP_SKB_CB(skb)->end_seq;
 
 			if (after(TCP_SKB_CB(skb)->end_seq, tp->rcv_nxt))
@@ -3350,7 +3343,7 @@
 /* These routines update the SACK block as out-of-order packets arrive or
  * in-order packets close up the sequence space.
  */
-static void tcp_sack_maybe_coalesce(struct tcp_opt *tp)
+static void tcp_sack_maybe_coalesce(struct tcp_sock *tp)
 {
 	int this_sack;
 	struct tcp_sack_block *sp = &tp->selective_acks[0];
@@ -3359,16 +3352,16 @@
 	/* See if the recent change to the first SACK eats into
 	 * or hits the sequence space of other SACK blocks, if so coalesce.
 	 */
-	for (this_sack = 1; this_sack < tp->num_sacks; ) {
+	for (this_sack = 1; this_sack < tp->rx_opt.num_sacks; ) {
 		if (tcp_sack_extend(sp, swalk->start_seq, swalk->end_seq)) {
 			int i;
 
 			/* Zap SWALK, by moving every further SACK up by one slot.
 			 * Decrease num_sacks.
 			 */
-			tp->num_sacks--;
-			tp->eff_sacks = min(tp->num_sacks+tp->dsack, 4-tp->tstamp_ok);
-			for(i=this_sack; i < tp->num_sacks; i++)
+			tp->rx_opt.num_sacks--;
+			tp->rx_opt.eff_sacks = min(tp->rx_opt.num_sacks + tp->rx_opt.dsack, 4 - tp->rx_opt.tstamp_ok);
+			for(i=this_sack; i < tp->rx_opt.num_sacks; i++)
 				sp[i] = sp[i+1];
 			continue;
 		}
@@ -3391,9 +3384,9 @@
 
 static void tcp_sack_new_ofo_skb(struct sock *sk, u32 seq, u32 end_seq)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	struct tcp_sack_block *sp = &tp->selective_acks[0];
-	int cur_sacks = tp->num_sacks;
+	int cur_sacks = tp->rx_opt.num_sacks;
 	int this_sack;
 
 	if (!cur_sacks)
@@ -3418,7 +3411,7 @@
 	 */
 	if (this_sack >= 4) {
 		this_sack--;
-		tp->num_sacks--;
+		tp->rx_opt.num_sacks--;
 		sp--;
 	}
 	for(; this_sack > 0; this_sack--, sp--)
@@ -3428,22 +3421,22 @@
 	/* Build the new head SACK, and we're done. */
 	sp->start_seq = seq;
 	sp->end_seq = end_seq;
-	tp->num_sacks++;
-	tp->eff_sacks = min(tp->num_sacks + tp->dsack, 4 - tp->tstamp_ok);
+	tp->rx_opt.num_sacks++;
+	tp->rx_opt.eff_sacks = min(tp->rx_opt.num_sacks + tp->rx_opt.dsack, 4 - tp->rx_opt.tstamp_ok);
 }
 
 /* RCV.NXT advances, some SACKs should be eaten. */
 
-static void tcp_sack_remove(struct tcp_opt *tp)
+static void tcp_sack_remove(struct tcp_sock *tp)
 {
 	struct tcp_sack_block *sp = &tp->selective_acks[0];
-	int num_sacks = tp->num_sacks;
+	int num_sacks = tp->rx_opt.num_sacks;
 	int this_sack;
 
 	/* Empty ofo queue, hence, all the SACKs are eaten. Clear. */
 	if (skb_queue_len(&tp->out_of_order_queue) == 0) {
-		tp->num_sacks = 0;
-		tp->eff_sacks = tp->dsack;
+		tp->rx_opt.num_sacks = 0;
+		tp->rx_opt.eff_sacks = tp->rx_opt.dsack;
 		return;
 	}
 
@@ -3464,9 +3457,9 @@
 		this_sack++;
 		sp++;
 	}
-	if (num_sacks != tp->num_sacks) {
-		tp->num_sacks = num_sacks;
-		tp->eff_sacks = min(tp->num_sacks+tp->dsack, 4-tp->tstamp_ok);
+	if (num_sacks != tp->rx_opt.num_sacks) {
+		tp->rx_opt.num_sacks = num_sacks;
+		tp->rx_opt.eff_sacks = min(tp->rx_opt.num_sacks + tp->rx_opt.dsack, 4 - tp->rx_opt.tstamp_ok);
 	}
 }
 
@@ -3475,7 +3468,7 @@
  */
 static void tcp_ofo_queue(struct sock *sk)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	__u32 dsack_high = tp->rcv_nxt;
 	struct sk_buff *skb;
 
@@ -3513,7 +3506,7 @@
 static void tcp_data_queue(struct sock *sk, struct sk_buff *skb)
 {
 	struct tcphdr *th = skb->h.th;
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	int eaten = -1;
 
 	if (TCP_SKB_CB(skb)->seq == TCP_SKB_CB(skb)->end_seq)
@@ -3524,10 +3517,10 @@
 
 	TCP_ECN_accept_cwr(tp, skb);
 
-	if (tp->dsack) {
-		tp->dsack = 0;
-		tp->eff_sacks = min_t(unsigned int, tp->num_sacks,
-						    4 - tp->tstamp_ok);
+	if (tp->rx_opt.dsack) {
+		tp->rx_opt.dsack = 0;
+		tp->rx_opt.eff_sacks = min_t(unsigned int, tp->rx_opt.num_sacks,
+						    4 - tp->rx_opt.tstamp_ok);
 	}
 
 	/*  Queue data for delivery to the user.
@@ -3585,7 +3578,7 @@
 				tp->ack.pingpong = 0;
 		}
 
-		if (tp->num_sacks)
+		if (tp->rx_opt.num_sacks)
 			tcp_sack_remove(tp);
 
 		tcp_fast_path_check(sk, tp);
@@ -3652,10 +3645,10 @@
 
 	if (!skb_peek(&tp->out_of_order_queue)) {
 		/* Initial out of order segment, build 1 SACK. */
-		if (tp->sack_ok) {
-			tp->num_sacks = 1;
-			tp->dsack     = 0;
-			tp->eff_sacks = 1;
+		if (tp->rx_opt.sack_ok) {
+			tp->rx_opt.num_sacks = 1;
+			tp->rx_opt.dsack     = 0;
+			tp->rx_opt.eff_sacks = 1;
 			tp->selective_acks[0].start_seq = TCP_SKB_CB(skb)->seq;
 			tp->selective_acks[0].end_seq =
 						TCP_SKB_CB(skb)->end_seq;
@@ -3669,7 +3662,7 @@
 		if (seq == TCP_SKB_CB(skb1)->end_seq) {
 			__skb_append(skb1, skb);
 
-			if (!tp->num_sacks ||
+			if (!tp->rx_opt.num_sacks ||
 			    tp->selective_acks[0].end_seq != seq)
 				goto add_sack;
 
@@ -3717,7 +3710,7 @@
 		}
 
 add_sack:
-		if (tp->sack_ok)
+		if (tp->rx_opt.sack_ok)
 			tcp_sack_new_ofo_skb(sk, seq, end_seq);
 	}
 }
@@ -3768,8 +3761,7 @@
 	while (before(start, end)) {
 		struct sk_buff *nskb;
 		int header = skb_headroom(skb);
-		int copy = (PAGE_SIZE - sizeof(struct sk_buff) -
-			    sizeof(struct skb_shared_info) - header - 31)&~15;
+		int copy = SKB_MAX_ORDER(header, 0);
 
 		/* Too big header? This can happen with IPv6. */
 		if (copy < 0)
@@ -3821,7 +3813,7 @@
  */
 static void tcp_collapse_ofo_queue(struct sock *sk)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	struct sk_buff *skb = skb_peek(&tp->out_of_order_queue);
 	struct sk_buff *head;
 	u32 start, end;
@@ -3866,7 +3858,7 @@
  */
 static int tcp_prune_queue(struct sock *sk)
 {
-	struct tcp_opt *tp = tcp_sk(sk); 
+	struct tcp_sock *tp = tcp_sk(sk); 
 
 	SOCK_DEBUG(sk, "prune_queue: c=%x\n", tp->copied_seq);
 
@@ -3900,8 +3892,8 @@
 		 * is in a sad state like this, we care only about integrity
 		 * of the connection not performance.
 		 */
-		if (tp->sack_ok)
-			tcp_sack_reset(tp);
+		if (tp->rx_opt.sack_ok)
+			tcp_sack_reset(&tp->rx_opt);
 		sk_stream_mem_reclaim(sk);
 	}
 
@@ -3926,7 +3918,7 @@
  */
 void tcp_cwnd_application_limited(struct sock *sk)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 
 	if (tp->ca_state == TCP_CA_Open &&
 	    sk->sk_socket && !test_bit(SOCK_NOSPACE, &sk->sk_socket->flags)) {
@@ -3950,13 +3942,13 @@
  */
 static void tcp_new_space(struct sock *sk)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 
-	if (tcp_get_pcount(&tp->packets_out) < tp->snd_cwnd &&
+	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->mss_clamp, tp->mss_cache_std) +
+ 		int sndmem = max_t(u32, tp->rx_opt.mss_clamp, tp->mss_cache_std) +
 			MAX_TCP_HEADER + 16 + sizeof(struct sk_buff),
 		    demanded = max_t(unsigned int, tp->snd_cwnd,
 						   tp->reordering + 1);
@@ -3981,7 +3973,7 @@
 
 static void __tcp_data_snd_check(struct sock *sk, struct sk_buff *skb)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	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 ||
@@ -4003,7 +3995,7 @@
  */
 static void __tcp_ack_snd_check(struct sock *sk, int ofo_possible)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 
 	    /* More than one full frame received... */
 	if (((tp->rcv_nxt - tp->rcv_wup) > tp->ack.rcv_mss
@@ -4026,7 +4018,7 @@
 
 static __inline__ void tcp_ack_snd_check(struct sock *sk)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	if (!tcp_ack_scheduled(tp)) {
 		/* We sent a data segment already. */
 		return;
@@ -4046,7 +4038,7 @@
  
 static void tcp_check_urg(struct sock * sk, struct tcphdr * th)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	u32 ptr = ntohs(th->urg_ptr);
 
 	if (ptr && !sysctl_tcp_stdurg)
@@ -4113,7 +4105,7 @@
 /* This is the 'fast' part of urgent handling. */
 static void tcp_urg(struct sock *sk, struct sk_buff *skb, struct tcphdr *th)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 
 	/* Check if we get a new urgent pointer - normally not. */
 	if (th->urg)
@@ -4138,7 +4130,7 @@
 
 static int tcp_copy_to_iovec(struct sock *sk, struct sk_buff *skb, int hlen)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	int chunk = skb->len - hlen;
 	int err;
 
@@ -4206,7 +4198,7 @@
 int tcp_rcv_established(struct sock *sk, struct sk_buff *skb,
 			struct tcphdr *th, unsigned len)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 
 	/*
 	 *	Header prediction.
@@ -4223,7 +4215,7 @@
 	 *	We do checksum and copy also but from device to kernel.
 	 */
 
-	tp->saw_tstamp = 0;
+	tp->rx_opt.saw_tstamp = 0;
 
 	/*	pred_flags is 0xS?10 << 16 + snd_wnd
 	 *	if header_predition is to be made
@@ -4252,14 +4244,14 @@
 					  | (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP))
 				goto slow_path;
 
-			tp->saw_tstamp = 1;
+			tp->rx_opt.saw_tstamp = 1;
 			++ptr; 
-			tp->rcv_tsval = ntohl(*ptr);
+			tp->rx_opt.rcv_tsval = ntohl(*ptr);
 			++ptr;
-			tp->rcv_tsecr = ntohl(*ptr);
+			tp->rx_opt.rcv_tsecr = ntohl(*ptr);
 
 			/* If PAWS failed, check it more carefully in slow path */
-			if ((s32)(tp->rcv_tsval - tp->ts_recent) < 0)
+			if ((s32)(tp->rx_opt.rcv_tsval - tp->rx_opt.ts_recent) < 0)
 				goto slow_path;
 
 			/* DO NOT update ts_recent here, if checksum fails
@@ -4385,7 +4377,7 @@
 	/*
 	 * RFC1323: H1. Apply PAWS check first.
 	 */
-	if (tcp_fast_parse_options(skb, th, tp) && tp->saw_tstamp &&
+	if (tcp_fast_parse_options(skb, th, tp) && tp->rx_opt.saw_tstamp &&
 	    tcp_paws_discard(tp, skb)) {
 		if (!th->rst) {
 			NET_INC_STATS_BH(LINUX_MIB_PAWSESTABREJECTED);
@@ -4456,10 +4448,10 @@
 static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb,
 					 struct tcphdr *th, unsigned len)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
-	int saved_clamp = tp->mss_clamp;
+	struct tcp_sock *tp = tcp_sk(sk);
+	int saved_clamp = tp->rx_opt.mss_clamp;
 
-	tcp_parse_options(skb, tp, 0);
+	tcp_parse_options(skb, &tp->rx_opt, 0);
 
 	if (th->ack) {
 		/* rfc793:
@@ -4476,8 +4468,8 @@
 		if (TCP_SKB_CB(skb)->ack_seq != tp->snd_nxt)
 			goto reset_and_undo;
 
-		if (tp->saw_tstamp && tp->rcv_tsecr &&
-		    !between(tp->rcv_tsecr, tp->retrans_stamp,
+		if (tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr &&
+		    !between(tp->rx_opt.rcv_tsecr, tp->retrans_stamp,
 			     tcp_time_stamp)) {
 			NET_INC_STATS_BH(LINUX_MIB_PAWSACTIVEREJECTED);
 			goto reset_and_undo;
@@ -4532,13 +4524,13 @@
 		tp->snd_wnd = ntohs(th->window);
 		tcp_init_wl(tp, TCP_SKB_CB(skb)->ack_seq, TCP_SKB_CB(skb)->seq);
 
-		if (!tp->wscale_ok) {
-			tp->snd_wscale = tp->rcv_wscale = 0;
+		if (!tp->rx_opt.wscale_ok) {
+			tp->rx_opt.snd_wscale = tp->rx_opt.rcv_wscale = 0;
 			tp->window_clamp = min(tp->window_clamp, 65535U);
 		}
 
-		if (tp->saw_tstamp) {
-			tp->tstamp_ok	   = 1;
+		if (tp->rx_opt.saw_tstamp) {
+			tp->rx_opt.tstamp_ok	   = 1;
 			tp->tcp_header_len =
 				sizeof(struct tcphdr) + TCPOLEN_TSTAMP_ALIGNED;
 			tp->advmss	    -= TCPOLEN_TSTAMP_ALIGNED;
@@ -4547,8 +4539,8 @@
 			tp->tcp_header_len = sizeof(struct tcphdr);
 		}
 
-		if (tp->sack_ok && sysctl_tcp_fack)
-			tp->sack_ok |= 2;
+		if (tp->rx_opt.sack_ok && sysctl_tcp_fack)
+			tp->rx_opt.sack_ok |= 2;
 
 		tcp_sync_mss(sk, tp->pmtu_cookie);
 		tcp_initialize_rcv_mss(sk);
@@ -4575,7 +4567,7 @@
 		if (sock_flag(sk, SOCK_KEEPOPEN))
 			tcp_reset_keepalive_timer(sk, keepalive_time_when(tp));
 
-		if (!tp->snd_wscale)
+		if (!tp->rx_opt.snd_wscale)
 			__tcp_fast_path_on(tp, tp->snd_wnd);
 		else
 			tp->pred_flags = 0;
@@ -4622,7 +4614,7 @@
 	}
 
 	/* PAWS check. */
-	if (tp->ts_recent_stamp && tp->saw_tstamp && tcp_paws_check(tp, 0))
+	if (tp->rx_opt.ts_recent_stamp && tp->rx_opt.saw_tstamp && tcp_paws_check(&tp->rx_opt, 0))
 		goto discard_and_undo;
 
 	if (th->syn) {
@@ -4632,8 +4624,8 @@
 		 */
 		tcp_set_state(sk, TCP_SYN_RECV);
 
-		if (tp->saw_tstamp) {
-			tp->tstamp_ok = 1;
+		if (tp->rx_opt.saw_tstamp) {
+			tp->rx_opt.tstamp_ok = 1;
 			tcp_store_ts_recent(tp);
 			tp->tcp_header_len =
 				sizeof(struct tcphdr) + TCPOLEN_TSTAMP_ALIGNED;
@@ -4680,13 +4672,13 @@
 	 */
 
 discard_and_undo:
-	tcp_clear_options(tp);
-	tp->mss_clamp = saved_clamp;
+	tcp_clear_options(&tp->rx_opt);
+	tp->rx_opt.mss_clamp = saved_clamp;
 	goto discard;
 
 reset_and_undo:
-	tcp_clear_options(tp);
-	tp->mss_clamp = saved_clamp;
+	tcp_clear_options(&tp->rx_opt);
+	tp->rx_opt.mss_clamp = saved_clamp;
 	return 1;
 }
 
@@ -4701,10 +4693,10 @@
 int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
 			  struct tcphdr *th, unsigned len)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	int queued = 0;
 
-	tp->saw_tstamp = 0;
+	tp->rx_opt.saw_tstamp = 0;
 
 	switch (sk->sk_state) {
 	case TCP_CLOSE:
@@ -4759,7 +4751,7 @@
 		return 0;
 	}
 
-	if (tcp_fast_parse_options(skb, th, tp) && tp->saw_tstamp &&
+	if (tcp_fast_parse_options(skb, th, tp) && tp->rx_opt.saw_tstamp &&
 	    tcp_paws_discard(tp, skb)) {
 		if (!th->rst) {
 			NET_INC_STATS_BH(LINUX_MIB_PAWSESTABREJECTED);
@@ -4819,7 +4811,7 @@
 
 				tp->snd_una = TCP_SKB_CB(skb)->ack_seq;
 				tp->snd_wnd = ntohs(th->window) <<
-					      tp->snd_wscale;
+					      tp->rx_opt.snd_wscale;
 				tcp_init_wl(tp, TCP_SKB_CB(skb)->ack_seq,
 					    TCP_SKB_CB(skb)->seq);
 
@@ -4827,11 +4819,11 @@
 				 * and does not calculate rtt.
 				 * Fix it at least with timestamps.
 				 */
-				if (tp->saw_tstamp && tp->rcv_tsecr &&
+				if (tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr &&
 				    !tp->srtt)
 					tcp_ack_saw_tstamp(tp, 0);
 
-				if (tp->tstamp_ok)
+				if (tp->rx_opt.tstamp_ok)
 					tp->advmss -= TCPOLEN_TSTAMP_ALIGNED;
 
 				/* Make sure socket is routed, for
diff -Nru a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
--- a/net/ipv4/tcp_ipv4.c	2005-03-01 23:38:55 -08:00
+++ b/net/ipv4/tcp_ipv4.c	2005-03-01 23:38:55 -08:00
@@ -115,7 +115,7 @@
 
 static __inline__ int tcp_sk_hashfn(struct sock *sk)
 {
-	struct inet_opt *inet = inet_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
 	__u32 laddr = inet->rcv_saddr;
 	__u16 lport = inet->num;
 	__u32 faddr = inet->daddr;
@@ -300,7 +300,7 @@
  */
 static void __tcp_put_port(struct sock *sk)
 {
-	struct inet_opt *inet = inet_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
 	struct tcp_bind_hashbucket *head = &tcp_bhash[tcp_bhashfn(inet->num)];
 	struct tcp_bind_bucket *tb;
 
@@ -420,7 +420,7 @@
 
 	hiscore=-1;
 	sk_for_each(sk, node, head) {
-		struct inet_opt *inet = inet_sk(sk);
+		struct inet_sock *inet = inet_sk(sk);
 
 		if (inet->num == hnum && !ipv6_only_sock(sk)) {
 			__u32 rcv_saddr = inet->rcv_saddr;
@@ -457,7 +457,7 @@
 	read_lock(&tcp_lhash_lock);
 	head = &tcp_listening_hash[tcp_lhashfn(hnum)];
 	if (!hlist_empty(head)) {
-		struct inet_opt *inet = inet_sk((sk = __sk_head(head)));
+		struct inet_sock *inet = inet_sk((sk = __sk_head(head)));
 
 		if (inet->num == hnum && !sk->sk_node.next &&
 		    (!inet->rcv_saddr || inet->rcv_saddr == daddr) &&
@@ -549,7 +549,7 @@
 static int __tcp_v4_check_established(struct sock *sk, __u16 lport,
 				      struct tcp_tw_bucket **twp)
 {
-	struct inet_opt *inet = inet_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
 	u32 daddr = inet->rcv_saddr;
 	u32 saddr = inet->daddr;
 	int dif = sk->sk_bound_dev_if;
@@ -568,7 +568,7 @@
 		tw = (struct tcp_tw_bucket *)sk2;
 
 		if (TCP_IPV4_TW_MATCH(sk2, acookie, saddr, daddr, ports, dif)) {
-			struct tcp_opt *tp = tcp_sk(sk);
+			struct tcp_sock *tp = tcp_sk(sk);
 
 			/* With PAWS, it is safe from the viewpoint
 			   of data integrity. Even without PAWS it
@@ -591,8 +591,8 @@
 				if ((tp->write_seq =
 						tw->tw_snd_nxt + 65535 + 2) == 0)
 					tp->write_seq = 1;
-				tp->ts_recent	    = tw->tw_ts_recent;
-				tp->ts_recent_stamp = tw->tw_ts_recent_stamp;
+				tp->rx_opt.ts_recent	   = tw->tw_ts_recent;
+				tp->rx_opt.ts_recent_stamp = tw->tw_ts_recent_stamp;
 				sock_hold(sk2);
 				goto unique;
 			} else
@@ -636,10 +636,18 @@
 	return -EADDRNOTAVAIL;
 }
 
+static inline u32 connect_port_offset(const struct sock *sk)
+{
+	const struct inet_sock *inet = inet_sk(sk);
+
+	return secure_tcp_port_ephemeral(inet->rcv_saddr, inet->daddr, 
+					 inet->dport);
+}
+
 /*
  * Bind a port for a connect operation and hash it.
  */
-static int tcp_v4_hash_connect(struct sock *sk)
+static inline int tcp_v4_hash_connect(struct sock *sk)
 {
 	unsigned short snum = inet_sk(sk)->num;
  	struct tcp_bind_hashbucket *head;
@@ -647,36 +655,20 @@
 	int ret;
 
  	if (!snum) {
- 		int rover;
  		int low = sysctl_local_port_range[0];
  		int high = sysctl_local_port_range[1];
- 		int remaining = (high - low) + 1;
+		int range = high - low;
+ 		int i;
+		int port;
+		static u32 hint;
+		u32 offset = hint + connect_port_offset(sk);
 		struct hlist_node *node;
  		struct tcp_tw_bucket *tw = NULL;
 
  		local_bh_disable();
-
- 		/* TODO. Actually it is not so bad idea to remove
- 		 * tcp_portalloc_lock before next submission to Linus.
- 		 * As soon as we touch this place at all it is time to think.
- 		 *
- 		 * Now it protects single _advisory_ variable tcp_port_rover,
- 		 * hence it is mostly useless.
- 		 * Code will work nicely if we just delete it, but
- 		 * I am afraid in contented case it will work not better or
- 		 * even worse: another cpu just will hit the same bucket
- 		 * and spin there.
- 		 * So some cpu salt could remove both contention and
- 		 * memory pingpong. Any ideas how to do this in a nice way?
- 		 */
- 		spin_lock(&tcp_portalloc_lock);
- 		rover = tcp_port_rover;
-
- 		do {
- 			rover++;
- 			if ((rover < low) || (rover > high))
- 				rover = low;
- 			head = &tcp_bhash[tcp_bhashfn(rover)];
+		for (i = 1; i <= range; i++) {
+			port = low + (i + offset) % range;
+ 			head = &tcp_bhash[tcp_bhashfn(port)];
  			spin_lock(&head->lock);
 
  			/* Does not bother with rcv_saddr checks,
@@ -684,19 +676,19 @@
  			 * unique enough.
  			 */
 			tb_for_each(tb, node, &head->chain) {
- 				if (tb->port == rover) {
+ 				if (tb->port == port) {
  					BUG_TRAP(!hlist_empty(&tb->owners));
  					if (tb->fastreuse >= 0)
  						goto next_port;
  					if (!__tcp_v4_check_established(sk,
-									rover,
+									port,
 									&tw))
  						goto ok;
  					goto next_port;
  				}
  			}
 
- 			tb = tcp_bucket_create(head, rover);
+ 			tb = tcp_bucket_create(head, port);
  			if (!tb) {
  				spin_unlock(&head->lock);
  				break;
@@ -706,22 +698,18 @@
 
  		next_port:
  			spin_unlock(&head->lock);
- 		} while (--remaining > 0);
- 		tcp_port_rover = rover;
- 		spin_unlock(&tcp_portalloc_lock);
-
+ 		}
  		local_bh_enable();
 
  		return -EADDRNOTAVAIL;
 
 ok:
- 		/* All locks still held and bhs disabled */
- 		tcp_port_rover = rover;
- 		spin_unlock(&tcp_portalloc_lock);
+		hint += i;
 
- 		tcp_bind_hash(sk, tb, rover);
+ 		/* Head lock still held and bh's disabled */
+ 		tcp_bind_hash(sk, tb, port);
 		if (sk_unhashed(sk)) {
- 			inet_sk(sk)->sport = htons(rover);
+ 			inet_sk(sk)->sport = htons(port);
  			__tcp_v4_hash(sk, 0);
  		}
  		spin_unlock(&head->lock);
@@ -755,8 +743,8 @@
 /* This will initiate an outgoing connection. */
 int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
 {
-	struct inet_opt *inet = inet_sk(sk);
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	struct sockaddr_in *usin = (struct sockaddr_in *)uaddr;
 	struct rtable *rt;
 	u32 daddr, nexthop;
@@ -795,25 +783,25 @@
 		inet->saddr = rt->rt_src;
 	inet->rcv_saddr = inet->saddr;
 
-	if (tp->ts_recent_stamp && inet->daddr != daddr) {
+	if (tp->rx_opt.ts_recent_stamp && inet->daddr != daddr) {
 		/* Reset inherited state */
-		tp->ts_recent	    = 0;
-		tp->ts_recent_stamp = 0;
-		tp->write_seq	    = 0;
+		tp->rx_opt.ts_recent	   = 0;
+		tp->rx_opt.ts_recent_stamp = 0;
+		tp->write_seq		   = 0;
 	}
 
 	if (sysctl_tcp_tw_recycle &&
-	    !tp->ts_recent_stamp && rt->rt_dst == daddr) {
+	    !tp->rx_opt.ts_recent_stamp && rt->rt_dst == daddr) {
 		struct inet_peer *peer = rt_get_peer(rt);
 
 		/* VJ's idea. We save last timestamp seen from
 		 * the destination in peer table, when entering state TIME-WAIT
-		 * and initialize ts_recent from it, when trying new connection.
+		 * and initialize rx_opt.ts_recent from it, when trying new connection.
 		 */
 
 		if (peer && peer->tcp_ts_stamp + TCP_PAWS_MSL >= xtime.tv_sec) {
-			tp->ts_recent_stamp = peer->tcp_ts_stamp;
-			tp->ts_recent = peer->tcp_ts;
+			tp->rx_opt.ts_recent_stamp = peer->tcp_ts_stamp;
+			tp->rx_opt.ts_recent = peer->tcp_ts;
 		}
 	}
 
@@ -824,7 +812,7 @@
 	if (inet->opt)
 		tp->ext_header_len = inet->opt->optlen;
 
-	tp->mss_clamp = 536;
+	tp->rx_opt.mss_clamp = 536;
 
 	/* Socket identity is still unknown (sport may be zero).
 	 * However we set state to SYN-SENT and not releasing socket
@@ -879,7 +867,7 @@
 	return (jhash_2words(raddr, (u32) rport, rnd) & (TCP_SYNQ_HSIZE - 1));
 }
 
-static struct open_request *tcp_v4_search_req(struct tcp_opt *tp,
+static struct open_request *tcp_v4_search_req(struct tcp_sock *tp,
 					      struct open_request ***prevp,
 					      __u16 rport,
 					      __u32 raddr, __u32 laddr)
@@ -905,7 +893,7 @@
 
 static void tcp_v4_synq_add(struct sock *sk, struct open_request *req)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	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);
 
@@ -929,8 +917,8 @@
 				     u32 mtu)
 {
 	struct dst_entry *dst;
-	struct inet_opt *inet = inet_sk(sk);
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 
 	/* We are not interested in TCP_LISTEN and open_requests (SYN-ACKs
 	 * send out by Linux are always <576bytes so they should go through
@@ -991,8 +979,8 @@
 {
 	struct iphdr *iph = (struct iphdr *)skb->data;
 	struct tcphdr *th = (struct tcphdr *)(skb->data + (iph->ihl << 2));
-	struct tcp_opt *tp;
-	struct inet_opt *inet;
+	struct tcp_sock *tp;
+	struct inet_sock *inet;
 	int type = skb->h.icmph->type;
 	int code = skb->h.icmph->code;
 	struct sock *sk;
@@ -1139,7 +1127,7 @@
 void tcp_v4_send_check(struct sock *sk, struct tcphdr *th, int len,
 		       struct sk_buff *skb)
 {
-	struct inet_opt *inet = inet_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
 
 	if (skb->ip_summed == CHECKSUM_HW) {
 		th->check = ~tcp_v4_check(th, len, inet->saddr, inet->daddr, 0);
@@ -1405,7 +1393,7 @@
 
 int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
 {
-	struct tcp_opt tp;
+	struct tcp_options_received tmp_opt;
 	struct open_request *req;
 	__u32 saddr = skb->nh.iph->saddr;
 	__u32 daddr = skb->nh.iph->daddr;
@@ -1447,29 +1435,29 @@
 	if (!req)
 		goto drop;
 
-	tcp_clear_options(&tp);
-	tp.mss_clamp = 536;
-	tp.user_mss  = tcp_sk(sk)->user_mss;
+	tcp_clear_options(&tmp_opt);
+	tmp_opt.mss_clamp = 536;
+	tmp_opt.user_mss  = tcp_sk(sk)->rx_opt.user_mss;
 
-	tcp_parse_options(skb, &tp, 0);
+	tcp_parse_options(skb, &tmp_opt, 0);
 
 	if (want_cookie) {
-		tcp_clear_options(&tp);
-		tp.saw_tstamp = 0;
+		tcp_clear_options(&tmp_opt);
+		tmp_opt.saw_tstamp = 0;
 	}
 
-	if (tp.saw_tstamp && !tp.rcv_tsval) {
+	if (tmp_opt.saw_tstamp && !tmp_opt.rcv_tsval) {
 		/* Some OSes (unknown ones, but I see them on web server, which
 		 * contains information interesting only for windows'
 		 * users) do not send their stamp in SYN. It is easy case.
 		 * We simply do not advertise TS support.
 		 */
-		tp.saw_tstamp = 0;
-		tp.tstamp_ok  = 0;
+		tmp_opt.saw_tstamp = 0;
+		tmp_opt.tstamp_ok  = 0;
 	}
-	tp.tstamp_ok = tp.saw_tstamp;
+	tmp_opt.tstamp_ok = tmp_opt.saw_tstamp;
 
-	tcp_openreq_init(req, &tp, skb);
+	tcp_openreq_init(req, &tmp_opt, skb);
 
 	req->af.v4_req.loc_addr = daddr;
 	req->af.v4_req.rmt_addr = saddr;
@@ -1495,7 +1483,7 @@
 		 * timewait bucket, so that all the necessary checks
 		 * are made in the function processing timewait state.
 		 */
-		if (tp.saw_tstamp &&
+		if (tmp_opt.saw_tstamp &&
 		    sysctl_tcp_tw_recycle &&
 		    (dst = tcp_v4_route_req(sk, req)) != NULL &&
 		    (peer = rt_get_peer((struct rtable *)dst)) != NULL &&
@@ -1561,8 +1549,8 @@
 				  struct open_request *req,
 				  struct dst_entry *dst)
 {
-	struct inet_opt *newinet;
-	struct tcp_opt *newtp;
+	struct inet_sock *newinet;
+	struct tcp_sock *newtp;
 	struct sock *newsk;
 
 	if (sk_acceptq_is_full(sk))
@@ -1614,7 +1602,7 @@
 {
 	struct tcphdr *th = skb->h.th;
 	struct iphdr *iph = skb->nh.iph;
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	struct sock *nsk;
 	struct open_request **prev;
 	/* Find possible connection requests. */
@@ -1868,7 +1856,7 @@
 
 static int tcp_v4_reselect_saddr(struct sock *sk)
 {
-	struct inet_opt *inet = inet_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
 	int err;
 	struct rtable *rt;
 	__u32 old_saddr = inet->saddr;
@@ -1919,7 +1907,7 @@
 
 int tcp_v4_rebuild_header(struct sock *sk)
 {
-	struct inet_opt *inet = inet_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
 	struct rtable *rt = (struct rtable *)__sk_dst_check(sk, 0);
 	u32 daddr;
 	int err;
@@ -1968,7 +1956,7 @@
 static void v4_addr2sockaddr(struct sock *sk, struct sockaddr * uaddr)
 {
 	struct sockaddr_in *sin = (struct sockaddr_in *) uaddr;
-	struct inet_opt *inet = inet_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
 
 	sin->sin_family		= AF_INET;
 	sin->sin_addr.s_addr	= inet->daddr;
@@ -1983,8 +1971,8 @@
 
 int tcp_v4_remember_stamp(struct sock *sk)
 {
-	struct inet_opt *inet = inet_sk(sk);
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	struct rtable *rt = (struct rtable *)__sk_dst_get(sk);
 	struct inet_peer *peer = NULL;
 	int release_it = 0;
@@ -1999,11 +1987,11 @@
 	}
 
 	if (peer) {
-		if ((s32)(peer->tcp_ts - tp->ts_recent) <= 0 ||
+		if ((s32)(peer->tcp_ts - tp->rx_opt.ts_recent) <= 0 ||
 		    (peer->tcp_ts_stamp + TCP_PAWS_MSL < xtime.tv_sec &&
-		     peer->tcp_ts_stamp <= tp->ts_recent_stamp)) {
-			peer->tcp_ts_stamp = tp->ts_recent_stamp;
-			peer->tcp_ts = tp->ts_recent;
+		     peer->tcp_ts_stamp <= tp->rx_opt.ts_recent_stamp)) {
+			peer->tcp_ts_stamp = tp->rx_opt.ts_recent_stamp;
+			peer->tcp_ts = tp->rx_opt.ts_recent;
 		}
 		if (release_it)
 			inet_putpeer(peer);
@@ -2052,7 +2040,7 @@
  */
 static int tcp_v4_init_sock(struct sock *sk)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 
 	skb_queue_head_init(&tp->out_of_order_queue);
 	tcp_init_xmit_timers(sk);
@@ -2094,7 +2082,7 @@
 
 int tcp_v4_destroy_sock(struct sock *sk)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 
 	tcp_clear_xmit_timers(sk);
 
@@ -2143,7 +2131,7 @@
 
 static void *listening_get_next(struct seq_file *seq, void *cur)
 {
-	struct tcp_opt *tp;
+	struct tcp_sock *tp;
 	struct hlist_node *node;
 	struct sock *sk = cur;
 	struct tcp_iter_state* st = seq->private;
@@ -2232,7 +2220,10 @@
 		struct sock *sk;
 		struct hlist_node *node;
 		struct tcp_tw_bucket *tw;
-	       
+
+		/* We can reschedule _before_ having picked the target: */
+		cond_resched_softirq();
+
 		read_lock(&tcp_ehash[st->bucket].lock);
 		sk_for_each(sk, node, &tcp_ehash[st->bucket].chain) {
 			if (sk->sk_family != st->family) {
@@ -2279,6 +2270,10 @@
 		}
 		read_unlock(&tcp_ehash[st->bucket].lock);
 		st->state = TCP_SEQ_STATE_ESTABLISHED;
+
+		/* We can reschedule between buckets: */
+		cond_resched_softirq();
+
 		if (++st->bucket < tcp_ehash_size) {
 			read_lock(&tcp_ehash[st->bucket].lock);
 			sk = sk_head(&tcp_ehash[st->bucket].chain);
@@ -2380,7 +2375,7 @@
 	switch (st->state) {
 	case TCP_SEQ_STATE_OPENREQ:
 		if (v) {
-			struct tcp_opt *tp = tcp_sk(st->syn_wait_sk);
+			struct tcp_sock *tp = tcp_sk(st->syn_wait_sk);
 			read_unlock_bh(&tp->syn_wait_lock);
 		}
 	case TCP_SEQ_STATE_LISTENING:
@@ -2485,8 +2480,8 @@
 {
 	int timer_active;
 	unsigned long timer_expires;
-	struct tcp_opt *tp = tcp_sk(sp);
-	struct inet_opt *inet = inet_sk(sp);
+	struct tcp_sock *tp = tcp_sk(sp);
+	struct inet_sock *inet = inet_sk(sp);
 	unsigned int dest = inet->daddr;
 	unsigned int src = inet->rcv_saddr;
 	__u16 destp = ntohs(inet->dport);
diff -Nru a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
--- a/net/ipv4/tcp_minisocks.c	2005-03-01 23:39:08 -08:00
+++ b/net/ipv4/tcp_minisocks.c	2005-03-01 23:39:08 -08:00
@@ -41,6 +41,8 @@
 int sysctl_tcp_syncookies = SYNC_INIT; 
 int sysctl_tcp_abort_on_overflow;
 
+static void tcp_tw_schedule(struct tcp_tw_bucket *tw, int timeo);
+
 static __inline__ int tcp_in_window(u32 seq, u32 end_seq, u32 s_win, u32 e_win)
 {
 	if (seq == s_win)
@@ -123,17 +125,17 @@
 tcp_timewait_state_process(struct tcp_tw_bucket *tw, struct sk_buff *skb,
 			   struct tcphdr *th, unsigned len)
 {
-	struct tcp_opt tp;
+	struct tcp_options_received tmp_opt;
 	int paws_reject = 0;
 
-	tp.saw_tstamp = 0;
+	tmp_opt.saw_tstamp = 0;
 	if (th->doff > (sizeof(struct tcphdr) >> 2) && tw->tw_ts_recent_stamp) {
-		tcp_parse_options(skb, &tp, 0);
+		tcp_parse_options(skb, &tmp_opt, 0);
 
-		if (tp.saw_tstamp) {
-			tp.ts_recent	   = tw->tw_ts_recent;
-			tp.ts_recent_stamp = tw->tw_ts_recent_stamp;
-			paws_reject = tcp_paws_check(&tp, th->rst);
+		if (tmp_opt.saw_tstamp) {
+			tmp_opt.ts_recent	   = tw->tw_ts_recent;
+			tmp_opt.ts_recent_stamp = tw->tw_ts_recent_stamp;
+			paws_reject = tcp_paws_check(&tmp_opt, th->rst);
 		}
 	}
 
@@ -174,9 +176,9 @@
 		/* FIN arrived, enter true time-wait state. */
 		tw->tw_substate	= TCP_TIME_WAIT;
 		tw->tw_rcv_nxt	= TCP_SKB_CB(skb)->end_seq;
-		if (tp.saw_tstamp) {
+		if (tmp_opt.saw_tstamp) {
 			tw->tw_ts_recent_stamp	= xtime.tv_sec;
-			tw->tw_ts_recent	= tp.rcv_tsval;
+			tw->tw_ts_recent	= tmp_opt.rcv_tsval;
 		}
 
 		/* I am shamed, but failed to make it more elegant.
@@ -229,8 +231,8 @@
 		}
 		tcp_tw_schedule(tw, TCP_TIMEWAIT_LEN);
 
-		if (tp.saw_tstamp) {
-			tw->tw_ts_recent	= tp.rcv_tsval;
+		if (tmp_opt.saw_tstamp) {
+			tw->tw_ts_recent	= tmp_opt.rcv_tsval;
 			tw->tw_ts_recent_stamp	= xtime.tv_sec;
 		}
 
@@ -257,7 +259,7 @@
 
 	if (th->syn && !th->rst && !th->ack && !paws_reject &&
 	    (after(TCP_SKB_CB(skb)->seq, tw->tw_rcv_nxt) ||
-	     (tp.saw_tstamp && (s32)(tw->tw_ts_recent - tp.rcv_tsval) < 0))) {
+	     (tmp_opt.saw_tstamp && (s32)(tw->tw_ts_recent - tmp_opt.rcv_tsval) < 0))) {
 		u32 isn = tw->tw_snd_nxt + 65535 + 2;
 		if (isn == 0)
 			isn++;
@@ -327,17 +329,17 @@
 void tcp_time_wait(struct sock *sk, int state, int timeo)
 {
 	struct tcp_tw_bucket *tw = NULL;
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	int recycle_ok = 0;
 
-	if (sysctl_tcp_tw_recycle && tp->ts_recent_stamp)
+	if (sysctl_tcp_tw_recycle && tp->rx_opt.ts_recent_stamp)
 		recycle_ok = tp->af_specific->remember_stamp(sk);
 
 	if (tcp_tw_count < sysctl_tcp_max_tw_buckets)
 		tw = kmem_cache_alloc(tcp_timewait_cachep, SLAB_ATOMIC);
 
 	if(tw != NULL) {
-		struct inet_opt *inet = inet_sk(sk);
+		struct inet_sock *inet = inet_sk(sk);
 		int rto = (tp->rto<<2) - (tp->rto>>1);
 
 		/* Give us an identity. */
@@ -351,15 +353,15 @@
 		tw->tw_dport		= inet->dport;
 		tw->tw_family		= sk->sk_family;
 		tw->tw_reuse		= sk->sk_reuse;
-		tw->tw_rcv_wscale	= tp->rcv_wscale;
+		tw->tw_rcv_wscale	= tp->rx_opt.rcv_wscale;
 		atomic_set(&tw->tw_refcnt, 1);
 
 		tw->tw_hashent		= sk->sk_hashent;
 		tw->tw_rcv_nxt		= tp->rcv_nxt;
 		tw->tw_snd_nxt		= tp->snd_nxt;
 		tw->tw_rcv_wnd		= tcp_receive_window(tp);
-		tw->tw_ts_recent	= tp->ts_recent;
-		tw->tw_ts_recent_stamp	= tp->ts_recent_stamp;
+		tw->tw_ts_recent	= tp->rx_opt.ts_recent;
+		tw->tw_ts_recent_stamp	= tp->rx_opt.ts_recent_stamp;
 		tw_dead_node_init(tw);
 
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
@@ -417,7 +419,7 @@
 #define TCP_TWKILL_QUOTA	100
 
 static struct hlist_head tcp_tw_death_row[TCP_TWKILL_SLOTS];
-static spinlock_t tw_death_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(tw_death_lock);
 static struct timer_list tcp_tw_timer = TIMER_INITIALIZER(tcp_twkill, 0, 0);
 static void twkill_work(void *);
 static DECLARE_WORK(tcp_twkill_work, twkill_work, NULL);
@@ -551,7 +553,7 @@
 		TIMER_INITIALIZER(tcp_twcal_tick, 0, 0);
 static struct hlist_head tcp_twcal_row[TCP_TW_RECYCLE_SLOTS];
 
-void tcp_tw_schedule(struct tcp_tw_bucket *tw, int timeo)
+static void tcp_tw_schedule(struct tcp_tw_bucket *tw, int timeo)
 {
 	struct hlist_head *list;
 	int slot;
@@ -690,7 +692,7 @@
 	struct sock *newsk = sk_alloc(PF_INET, GFP_ATOMIC, 0, sk->sk_prot->slab);
 
 	if(newsk != NULL) {
-		struct tcp_opt *newtp;
+		struct tcp_sock *newtp;
 		struct sk_filter *filter;
 
 		memcpy(newsk, sk, sizeof(struct tcp_sock));
@@ -734,7 +736,7 @@
 			return NULL;
 		}
 
-		/* Now setup tcp_opt */
+		/* Now setup tcp_sock */
 		newtp = tcp_sk(newsk);
 		newtp->pred_flags = 0;
 		newtp->rcv_nxt = req->rcv_isn + 1;
@@ -752,11 +754,11 @@
 		newtp->mdev = TCP_TIMEOUT_INIT;
 		newtp->rto = TCP_TIMEOUT_INIT;
 
-		tcp_set_pcount(&newtp->packets_out, 0);
-		tcp_set_pcount(&newtp->left_out, 0);
-		tcp_set_pcount(&newtp->retrans_out, 0);
-		tcp_set_pcount(&newtp->sacked_out, 0);
-		tcp_set_pcount(&newtp->fackets_out, 0);
+		newtp->packets_out = 0;
+		newtp->left_out = 0;
+		newtp->retrans_out = 0;
+		newtp->sacked_out = 0;
+		newtp->fackets_out = 0;
 		newtp->snd_ssthresh = 0x7fffffff;
 
 		/* So many TCP implementations out there (incorrectly) count the
@@ -778,13 +780,13 @@
 		newtp->pushed_seq = newtp->write_seq;
 		newtp->copied_seq = req->rcv_isn + 1;
 
-		newtp->saw_tstamp = 0;
+		newtp->rx_opt.saw_tstamp = 0;
 
-		newtp->dsack = 0;
-		newtp->eff_sacks = 0;
+		newtp->rx_opt.dsack = 0;
+		newtp->rx_opt.eff_sacks = 0;
 
 		newtp->probes_out = 0;
-		newtp->num_sacks = 0;
+		newtp->rx_opt.num_sacks = 0;
 		newtp->urg_data = 0;
 		newtp->listen_opt = NULL;
 		newtp->accept_queue = newtp->accept_queue_tail = NULL;
@@ -807,36 +809,36 @@
 		newsk->sk_sleep = NULL;
 		newsk->sk_owner = NULL;
 
-		newtp->tstamp_ok = req->tstamp_ok;
-		if((newtp->sack_ok = req->sack_ok) != 0) {
+		newtp->rx_opt.tstamp_ok = req->tstamp_ok;
+		if((newtp->rx_opt.sack_ok = req->sack_ok) != 0) {
 			if (sysctl_tcp_fack)
-				newtp->sack_ok |= 2;
+				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->wscale_ok = req->wscale_ok;
-		if (newtp->wscale_ok) {
-			newtp->snd_wscale = req->snd_wscale;
-			newtp->rcv_wscale = req->rcv_wscale;
+		newtp->rx_opt.wscale_ok = req->wscale_ok;
+		if (newtp->rx_opt.wscale_ok) {
+			newtp->rx_opt.snd_wscale = req->snd_wscale;
+			newtp->rx_opt.rcv_wscale = req->rcv_wscale;
 		} else {
-			newtp->snd_wscale = newtp->rcv_wscale = 0;
+			newtp->rx_opt.snd_wscale = newtp->rx_opt.rcv_wscale = 0;
 			newtp->window_clamp = min(newtp->window_clamp, 65535U);
 		}
-		newtp->snd_wnd = ntohs(skb->h.th->window) << newtp->snd_wscale;
+		newtp->snd_wnd = ntohs(skb->h.th->window) << newtp->rx_opt.snd_wscale;
 		newtp->max_window = newtp->snd_wnd;
 
-		if (newtp->tstamp_ok) {
-			newtp->ts_recent = req->ts_recent;
-			newtp->ts_recent_stamp = xtime.tv_sec;
+		if (newtp->rx_opt.tstamp_ok) {
+			newtp->rx_opt.ts_recent = req->ts_recent;
+			newtp->rx_opt.ts_recent_stamp = xtime.tv_sec;
 			newtp->tcp_header_len = sizeof(struct tcphdr) + TCPOLEN_TSTAMP_ALIGNED;
 		} else {
-			newtp->ts_recent_stamp = 0;
+			newtp->rx_opt.ts_recent_stamp = 0;
 			newtp->tcp_header_len = sizeof(struct tcphdr);
 		}
 		if (skb->len >= TCP_MIN_RCVMSS+newtp->tcp_header_len)
 			newtp->ack.last_seg_size = skb->len-newtp->tcp_header_len;
-		newtp->mss_clamp = req->mss;
+		newtp->rx_opt.mss_clamp = req->mss;
 		TCP_ECN_openreq_child(newtp, req);
 		if (newtp->ecn_flags&TCP_ECN_OK)
 			newsk->sk_no_largesend = 1;
@@ -858,24 +860,24 @@
 			   struct open_request **prev)
 {
 	struct tcphdr *th = skb->h.th;
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	u32 flg = tcp_flag_word(th) & (TCP_FLAG_RST|TCP_FLAG_SYN|TCP_FLAG_ACK);
 	int paws_reject = 0;
-	struct tcp_opt ttp;
+	struct tcp_options_received tmp_opt;
 	struct sock *child;
 
-	ttp.saw_tstamp = 0;
+	tmp_opt.saw_tstamp = 0;
 	if (th->doff > (sizeof(struct tcphdr)>>2)) {
-		tcp_parse_options(skb, &ttp, 0);
+		tcp_parse_options(skb, &tmp_opt, 0);
 
-		if (ttp.saw_tstamp) {
-			ttp.ts_recent = req->ts_recent;
+		if (tmp_opt.saw_tstamp) {
+			tmp_opt.ts_recent = req->ts_recent;
 			/* We do not store true stamp, but it is not required,
 			 * it can be estimated (approximately)
 			 * from another data.
 			 */
-			ttp.ts_recent_stamp = xtime.tv_sec - ((TCP_TIMEOUT_INIT/HZ)<<req->retrans);
-			paws_reject = tcp_paws_check(&ttp, th->rst);
+			tmp_opt.ts_recent_stamp = xtime.tv_sec - ((TCP_TIMEOUT_INIT/HZ)<<req->retrans);
+			paws_reject = tcp_paws_check(&tmp_opt, th->rst);
 		}
 	}
 
@@ -980,63 +982,63 @@
 
 	/* In sequence, PAWS is OK. */
 
-	if (ttp.saw_tstamp && !after(TCP_SKB_CB(skb)->seq, req->rcv_isn+1))
-		req->ts_recent = ttp.rcv_tsval;
+	if (tmp_opt.saw_tstamp && !after(TCP_SKB_CB(skb)->seq, req->rcv_isn+1))
+			req->ts_recent = tmp_opt.rcv_tsval;
 
-	if (TCP_SKB_CB(skb)->seq == req->rcv_isn) {
-		/* Truncate SYN, it is out of window starting
-		   at req->rcv_isn+1. */
-		flg &= ~TCP_FLAG_SYN;
-	}
+		if (TCP_SKB_CB(skb)->seq == req->rcv_isn) {
+			/* Truncate SYN, it is out of window starting
+			   at req->rcv_isn+1. */
+			flg &= ~TCP_FLAG_SYN;
+		}
 
-	/* RFC793: "second check the RST bit" and
-	 *	   "fourth, check the SYN bit"
-	 */
-	if (flg & (TCP_FLAG_RST|TCP_FLAG_SYN))
-		goto embryonic_reset;
+		/* RFC793: "second check the RST bit" and
+		 *	   "fourth, check the SYN bit"
+		 */
+		if (flg & (TCP_FLAG_RST|TCP_FLAG_SYN))
+			goto embryonic_reset;
 
-	/* ACK sequence verified above, just make sure ACK is
-	 * set.  If ACK not set, just silently drop the packet.
-	 */
-	if (!(flg & TCP_FLAG_ACK))
-		return NULL;
+		/* ACK sequence verified above, just make sure ACK is
+		 * set.  If ACK not set, just silently drop the packet.
+		 */
+		if (!(flg & TCP_FLAG_ACK))
+			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;
-		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;
+			return NULL;
+		}
 
-	/* OK, ACK is valid, create big socket and
-	 * feed this segment to it. It will repeat all
-	 * the tests. THIS SEGMENT MUST MOVE SOCKET TO
-	 * ESTABLISHED STATE. If it will be dropped after
-	 * socket is created, wait for troubles.
-	 */
-	child = tp->af_specific->syn_recv_sock(sk, skb, req, NULL);
-	if (child == NULL)
-		goto listen_overflow;
-
-	sk_set_owner(child, sk->sk_owner);
-	tcp_synq_unlink(tp, req, prev);
-	tcp_synq_removed(sk, req);
-
-	tcp_acceptq_queue(sk, req, child);
-	return child;
-
-listen_overflow:
-	if (!sysctl_tcp_abort_on_overflow) {
-		req->acked = 1;
-		return NULL;
-	}
+		/* OK, ACK is valid, create big socket and
+		 * feed this segment to it. It will repeat all
+		 * the tests. THIS SEGMENT MUST MOVE SOCKET TO
+		 * ESTABLISHED STATE. If it will be dropped after
+		 * socket is created, wait for troubles.
+		 */
+		child = tp->af_specific->syn_recv_sock(sk, skb, req, NULL);
+		if (child == NULL)
+			goto listen_overflow;
+
+		sk_set_owner(child, sk->sk_owner);
+		tcp_synq_unlink(tp, req, prev);
+		tcp_synq_removed(sk, req);
+
+		tcp_acceptq_queue(sk, req, child);
+		return child;
+
+	listen_overflow:
+		if (!sysctl_tcp_abort_on_overflow) {
+			req->acked = 1;
+			return NULL;
+		}
 
-embryonic_reset:
-	NET_INC_STATS_BH(LINUX_MIB_EMBRYONICRSTS);
-	if (!(flg & TCP_FLAG_RST))
-		req->class->send_reset(skb);
+	embryonic_reset:
+		NET_INC_STATS_BH(LINUX_MIB_EMBRYONICRSTS);
+		if (!(flg & TCP_FLAG_RST))
+			req->class->send_reset(skb);
 
-	tcp_synq_drop(sk, req, prev);
-	return NULL;
+		tcp_synq_drop(sk, req, prev);
+		return NULL;
 }
 
 /*
diff -Nru a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
--- a/net/ipv4/tcp_output.c	2005-03-01 23:39:07 -08:00
+++ b/net/ipv4/tcp_output.c	2005-03-01 23:39:07 -08:00
@@ -51,8 +51,8 @@
  */
 int sysctl_tcp_tso_win_divisor = 8;
 
-static __inline__
-void update_send_head(struct sock *sk, struct tcp_opt *tp, struct sk_buff *skb)
+static inline void update_send_head(struct sock *sk, struct tcp_sock *tp,
+				    struct sk_buff *skb)
 {
 	sk->sk_send_head = skb->next;
 	if (sk->sk_send_head == (struct sk_buff *)&sk->sk_write_queue)
@@ -67,7 +67,7 @@
  * Anything in between SND.UNA...SND.UNA+SND.WND also can be already
  * invalid. OK, let's make this for now:
  */
-static __inline__ __u32 tcp_acceptable_seq(struct sock *sk, struct tcp_opt *tp)
+static inline __u32 tcp_acceptable_seq(struct sock *sk, struct tcp_sock *tp)
 {
 	if (!before(tp->snd_una+tp->snd_wnd, tp->snd_nxt))
 		return tp->snd_nxt;
@@ -91,7 +91,7 @@
  */
 static __u16 tcp_advertise_mss(struct sock *sk)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	struct dst_entry *dst = __sk_dst_get(sk);
 	int mss = tp->advmss;
 
@@ -105,7 +105,7 @@
 
 /* RFC2861. Reset CWND after idle period longer RTO to "restart window".
  * This is the first part of cwnd validation mechanism. */
-static void tcp_cwnd_restart(struct tcp_opt *tp, struct dst_entry *dst)
+static void tcp_cwnd_restart(struct tcp_sock *tp, struct dst_entry *dst)
 {
 	s32 delta = tcp_time_stamp - tp->lsndtime;
 	u32 restart_cwnd = tcp_init_cwnd(tp, dst);
@@ -124,12 +124,12 @@
 	tp->snd_cwnd_used = 0;
 }
 
-static __inline__ void tcp_event_data_sent(struct tcp_opt *tp, struct sk_buff *skb, struct sock *sk)
+static inline void tcp_event_data_sent(struct tcp_sock *tp,
+				       struct sk_buff *skb, struct sock *sk)
 {
 	u32 now = tcp_time_stamp;
 
-	if (!tcp_get_pcount(&tp->packets_out) &&
-	    (s32)(now - tp->lsndtime) > tp->rto)
+	if (!tp->packets_out && (s32)(now - tp->lsndtime) > tp->rto)
 		tcp_cwnd_restart(tp, __sk_dst_get(sk));
 
 	tp->lsndtime = now;
@@ -143,7 +143,7 @@
 
 static __inline__ void tcp_event_ack_sent(struct sock *sk)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 
 	tcp_dec_quickack_mode(tp);
 	tcp_clear_xmit_timer(sk, TCP_TIME_DACK);
@@ -208,14 +208,14 @@
 	(*window_clamp) = min(65535U << (*rcv_wscale), *window_clamp);
 }
 
-/* Chose a new window to advertise, update state in tcp_opt for the
+/* Chose a new window to advertise, update state in tcp_sock for the
  * socket, and return result with RFC1323 scaling applied.  The return
  * value can be stuffed directly into th->window for an outgoing
  * frame.
  */
 static __inline__ u16 tcp_select_window(struct sock *sk)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	u32 cur_win = tcp_receive_window(tp);
 	u32 new_win = __tcp_select_window(sk);
 
@@ -236,13 +236,13 @@
 	/* Make sure we do not exceed the maximum possible
 	 * scaled window.
 	 */
-	if (!tp->rcv_wscale)
+	if (!tp->rx_opt.rcv_wscale)
 		new_win = min(new_win, MAX_TCP_WINDOW);
 	else
-		new_win = min(new_win, (65535U << tp->rcv_wscale));
+		new_win = min(new_win, (65535U << tp->rx_opt.rcv_wscale));
 
 	/* RFC1323 scaling applied */
-	new_win >>= tp->rcv_wscale;
+	new_win >>= tp->rx_opt.rcv_wscale;
 
 	/* If we advertise zero window, disable fast path. */
 	if (new_win == 0)
@@ -266,8 +266,8 @@
 static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb)
 {
 	if (skb != NULL) {
-		struct inet_opt *inet = inet_sk(sk);
-		struct tcp_opt *tp = tcp_sk(sk);
+		struct inet_sock *inet = inet_sk(sk);
+		struct tcp_sock *tp = tcp_sk(sk);
 		struct tcp_skb_cb *tcb = TCP_SKB_CB(skb);
 		int tcp_header_size = tp->tcp_header_len;
 		struct tcphdr *th;
@@ -296,12 +296,12 @@
 				if(!(sysctl_flags & SYSCTL_FLAG_TSTAMPS))
 					tcp_header_size += TCPOLEN_SACKPERM_ALIGNED;
 			}
-		} else if (tp->eff_sacks) {
+		} else if (tp->rx_opt.eff_sacks) {
 			/* A SACK is 2 pad bytes, a 2 byte header, plus
 			 * 2 32-bit sequence numbers for each SACK block.
 			 */
 			tcp_header_size += (TCPOLEN_SACK_BASE_ALIGNED +
-					    (tp->eff_sacks * TCPOLEN_SACK_PERBLOCK));
+					    (tp->rx_opt.eff_sacks * TCPOLEN_SACK_PERBLOCK));
 		}
 		
 		/*
@@ -349,9 +349,9 @@
 					      (sysctl_flags & SYSCTL_FLAG_TSTAMPS),
 					      (sysctl_flags & SYSCTL_FLAG_SACK),
 					      (sysctl_flags & SYSCTL_FLAG_WSCALE),
-					      tp->rcv_wscale,
+					      tp->rx_opt.rcv_wscale,
 					      tcb->when,
-		      			      tp->ts_recent);
+		      			      tp->rx_opt.ts_recent);
 		} else {
 			tcp_build_and_update_options((__u32 *)(th + 1),
 						     tp, tcb->when);
@@ -396,7 +396,7 @@
  */
 static void tcp_queue_skb(struct sock *sk, struct sk_buff *skb)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 
 	/* Advance write_seq and place onto the write_queue. */
 	tp->write_seq = TCP_SKB_CB(skb)->end_seq;
@@ -408,17 +408,28 @@
 		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_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	struct sk_buff *skb = sk->sk_send_head;
 
 	if (tcp_snd_test(tp, 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;
@@ -453,7 +464,7 @@
  */
 static int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	struct sk_buff *buff;
 	int nsize;
 	u16 flags;
@@ -508,8 +519,8 @@
 	TCP_SKB_CB(buff)->when = TCP_SKB_CB(skb)->when;
 
 	if (TCP_SKB_CB(skb)->sacked & TCPCB_LOST) {
-		tcp_dec_pcount(&tp->lost_out, skb);
-		tcp_dec_pcount(&tp->left_out, skb);
+		tp->lost_out -= tcp_skb_pcount(skb);
+		tp->left_out -= tcp_skb_pcount(skb);
 	}
 
 	/* Fix up tso_factor for both original and new SKB.  */
@@ -517,13 +528,13 @@
 	tcp_set_skb_tso_segs(buff, tp->mss_cache_std);
 
 	if (TCP_SKB_CB(skb)->sacked & TCPCB_LOST) {
-		tcp_inc_pcount(&tp->lost_out, skb);
-		tcp_inc_pcount(&tp->left_out, skb);
+		tp->lost_out += tcp_skb_pcount(skb);
+		tp->left_out += tcp_skb_pcount(skb);
 	}
 
 	if (TCP_SKB_CB(buff)->sacked&TCPCB_LOST) {
-		tcp_inc_pcount(&tp->lost_out, buff);
-		tcp_inc_pcount(&tp->left_out, buff);
+		tp->lost_out += tcp_skb_pcount(buff);
+		tp->left_out += tcp_skb_pcount(buff);
 	}
 
 	/* Link BUFF into the send queue. */
@@ -596,10 +607,10 @@
 
 /* This function synchronize snd mss to current pmtu/exthdr set.
 
-   tp->user_mss is mss set by user by TCP_MAXSEG. It does NOT counts
+   tp->rx_opt.user_mss is mss set by user by TCP_MAXSEG. It does NOT counts
    for TCP options, but includes only bare TCP header.
 
-   tp->mss_clamp is mss negotiated at connection setup.
+   tp->rx_opt.mss_clamp is mss negotiated at connection setup.
    It is minumum of user_mss and mss received with SYN.
    It also does not include TCP options.
 
@@ -608,7 +619,7 @@
    tp->mss_cache is current effective sending mss, including
    all tcp options except for SACKs. It is evaluated,
    taking into account current pmtu, but never exceeds
-   tp->mss_clamp.
+   tp->rx_opt.mss_clamp.
 
    NOTE1. rfc1122 clearly states that advertised MSS
    DOES NOT include either tcp or ip options.
@@ -619,7 +630,7 @@
 
 unsigned int tcp_sync_mss(struct sock *sk, u32 pmtu)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	struct dst_entry *dst = __sk_dst_get(sk);
 	int mss_now;
 
@@ -632,8 +643,8 @@
 	mss_now = pmtu - tp->af_specific->net_header_len - sizeof(struct tcphdr);
 
 	/* Clamp it (mss_clamp does not include tcp options) */
-	if (mss_now > tp->mss_clamp)
-		mss_now = tp->mss_clamp;
+	if (mss_now > tp->rx_opt.mss_clamp)
+		mss_now = tp->rx_opt.mss_clamp;
 
 	/* Now subtract optional transport overhead */
 	mss_now -= tp->ext_header_len + tp->ext2_header_len;
@@ -666,7 +677,7 @@
 
 unsigned int tcp_current_mss(struct sock *sk, int large)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	struct dst_entry *dst = __sk_dst_get(sk);
 	unsigned int do_large, mss_now;
 
@@ -712,9 +723,9 @@
 		mss_now = tp->mss_cache;
 	}
 
-	if (tp->eff_sacks)
+	if (tp->rx_opt.eff_sacks)
 		mss_now -= (TCPOLEN_SACK_BASE_ALIGNED +
-			    (tp->eff_sacks * TCPOLEN_SACK_PERBLOCK));
+			    (tp->rx_opt.eff_sacks * TCPOLEN_SACK_PERBLOCK));
 	return mss_now;
 }
 
@@ -727,7 +738,7 @@
  */
 int tcp_write_xmit(struct sock *sk, int nonagle)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	unsigned int mss_now;
 
 	/* If we are closed, the bytes will have to remain here.
@@ -755,6 +766,7 @@
 			}
 
 			TCP_SKB_CB(skb)->when = tcp_time_stamp;
+			tcp_tso_set_push(skb);
 			if (tcp_transmit_skb(sk, skb_clone(skb, GFP_ATOMIC)))
 				break;
 
@@ -772,7 +784,7 @@
 			return 0;
 		}
 
-		return !tcp_get_pcount(&tp->packets_out) && sk->sk_send_head;
+		return !tp->packets_out && sk->sk_send_head;
 	}
 	return 0;
 }
@@ -831,7 +843,7 @@
  */
 u32 __tcp_select_window(struct sock *sk)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	/* MSS for the peer's data.  Previous verions used mss_clamp
 	 * here.  I don't know if the value based on our guesses
 	 * of peer's MSS is better for the performance.  It's more correct
@@ -863,16 +875,16 @@
 	 * scaled window will not line up with the MSS boundary anyway.
 	 */
 	window = tp->rcv_wnd;
-	if (tp->rcv_wscale) {
+	if (tp->rx_opt.rcv_wscale) {
 		window = free_space;
 
 		/* Advertise enough space so that it won't get scaled away.
 		 * Import case: prevent zero window announcement if
 		 * 1<<rcv_wscale > mss.
 		 */
-		if (((window >> tp->rcv_wscale) << tp->rcv_wscale) != window)
-			window = (((window >> tp->rcv_wscale) + 1)
-				  << tp->rcv_wscale);
+		if (((window >> tp->rx_opt.rcv_wscale) << tp->rx_opt.rcv_wscale) != window)
+			window = (((window >> tp->rx_opt.rcv_wscale) + 1)
+				  << tp->rx_opt.rcv_wscale);
 	} else {
 		/* Get the largest window that is a nice multiple of mss.
 		 * Window clamp already applied above.
@@ -892,7 +904,7 @@
 /* Attempt to collapse two adjacent SKB's during retransmission. */
 static void tcp_retrans_try_collapse(struct sock *sk, struct sk_buff *skb, int mss_now)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	struct sk_buff *next_skb = skb->next;
 
 	/* The first test we must make is that neither of these two
@@ -944,15 +956,15 @@
 		 */
 		TCP_SKB_CB(skb)->sacked |= TCP_SKB_CB(next_skb)->sacked&(TCPCB_EVER_RETRANS|TCPCB_AT_TAIL);
 		if (TCP_SKB_CB(next_skb)->sacked&TCPCB_SACKED_RETRANS)
-			tcp_dec_pcount(&tp->retrans_out, next_skb);
+			tp->retrans_out -= tcp_skb_pcount(next_skb);
 		if (TCP_SKB_CB(next_skb)->sacked&TCPCB_LOST) {
-			tcp_dec_pcount(&tp->lost_out, next_skb);
-			tcp_dec_pcount(&tp->left_out, next_skb);
+			tp->lost_out -= tcp_skb_pcount(next_skb);
+			tp->left_out -= tcp_skb_pcount(next_skb);
 		}
 		/* Reno case is special. Sigh... */
-		if (!tp->sack_ok && tcp_get_pcount(&tp->sacked_out)) {
+		if (!tp->rx_opt.sack_ok && tp->sacked_out) {
 			tcp_dec_pcount_approx(&tp->sacked_out, next_skb);
-			tcp_dec_pcount(&tp->left_out, next_skb);
+			tp->left_out -= tcp_skb_pcount(next_skb);
 		}
 
 		/* Not quite right: it can be > snd.fack, but
@@ -970,7 +982,7 @@
  */ 
 void tcp_simple_retransmit(struct sock *sk)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	struct sk_buff *skb;
 	unsigned int mss = tcp_current_mss(sk, 0);
 	int lost = 0;
@@ -980,11 +992,11 @@
 		    !(TCP_SKB_CB(skb)->sacked&TCPCB_SACKED_ACKED)) {
 			if (TCP_SKB_CB(skb)->sacked&TCPCB_SACKED_RETRANS) {
 				TCP_SKB_CB(skb)->sacked &= ~TCPCB_SACKED_RETRANS;
-				tcp_dec_pcount(&tp->retrans_out, skb);
+				tp->retrans_out -= tcp_skb_pcount(skb);
 			}
 			if (!(TCP_SKB_CB(skb)->sacked&TCPCB_LOST)) {
 				TCP_SKB_CB(skb)->sacked |= TCPCB_LOST;
-				tcp_inc_pcount(&tp->lost_out, skb);
+				tp->lost_out += tcp_skb_pcount(skb);
 				lost = 1;
 			}
 		}
@@ -1016,7 +1028,7 @@
  */
 int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
  	unsigned int cur_mss = tcp_current_mss(sk, 0);
 	int err;
 
@@ -1059,9 +1071,8 @@
 
 		/* New SKB created, account for it. */
 		new_factor = tcp_skb_pcount(skb);
-		tcp_dec_pcount_explicit(&tp->packets_out,
-					old_factor - new_factor);
-		tcp_inc_pcount(&tp->packets_out, skb->next);
+		tp->packets_out -= old_factor - new_factor;
+		tp->packets_out += tcp_skb_pcount(skb->next);
 	}
 
 	/* Collapse two adjacent packets if worthwhile and we can. */
@@ -1070,6 +1081,7 @@
 	   (skb->next != sk->sk_send_head) &&
 	   (skb->next != (struct sk_buff *)&sk->sk_write_queue) &&
 	   (skb_shinfo(skb)->nr_frags == 0 && skb_shinfo(skb->next)->nr_frags == 0) &&
+	   (tcp_skb_pcount(skb) == 1 && tcp_skb_pcount(skb->next) == 1) &&
 	   (sysctl_tcp_retrans_collapse != 0))
 		tcp_retrans_try_collapse(sk, skb, cur_mss);
 
@@ -1096,6 +1108,7 @@
 	 * 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):
@@ -1114,7 +1127,7 @@
 		}
 #endif
 		TCP_SKB_CB(skb)->sacked |= TCPCB_RETRANS;
-		tcp_inc_pcount(&tp->retrans_out, skb);
+		tp->retrans_out += tcp_skb_pcount(skb);
 
 		/* Save stamp of the first retransmit. */
 		if (!tp->retrans_stamp)
@@ -1140,9 +1153,9 @@
  */
 void tcp_xmit_retransmit_queue(struct sock *sk)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	struct sk_buff *skb;
-	int packet_cnt = tcp_get_pcount(&tp->lost_out);
+	int packet_cnt = tp->lost_out;
 
 	/* First pass: retransmit lost packets. */
 	if (packet_cnt) {
@@ -1187,7 +1200,7 @@
 		return;
 
 	/* No forward retransmissions in Reno are possible. */
-	if (!tp->sack_ok)
+	if (!tp->rx_opt.sack_ok)
 		return;
 
 	/* Yeah, we have to make difficult choice between forward transmission
@@ -1209,7 +1222,7 @@
 		 * real MSS sized packet because tcp_retransmit_skb()
 		 * will fragment it if necessary.
 		 */
-		if (++packet_cnt > tcp_get_pcount(&tp->fackets_out))
+		if (++packet_cnt > tp->fackets_out)
 			break;
 
 		if (tcp_packets_in_flight(tp) >= tp->snd_cwnd)
@@ -1235,7 +1248,7 @@
  */
 void tcp_send_fin(struct sock *sk)
 {
-	struct tcp_opt *tp = tcp_sk(sk);	
+	struct tcp_sock *tp = tcp_sk(sk);	
 	struct sk_buff *skb = skb_peek_tail(&sk->sk_write_queue);
 	int mss_now;
 	
@@ -1281,7 +1294,7 @@
  */
 void tcp_send_active_reset(struct sock *sk, int priority)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	struct sk_buff *skb;
 
 	/* NOTE: No TCP options attached and we never retransmit this. */
@@ -1346,7 +1359,7 @@
 struct sk_buff * tcp_make_synack(struct sock *sk, struct dst_entry *dst,
 				 struct open_request *req)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	struct tcphdr *th;
 	int tcp_header_size;
 	struct sk_buff *skb;
@@ -1417,7 +1430,7 @@
 static inline void tcp_connect_init(struct sock *sk)
 {
 	struct dst_entry *dst = __sk_dst_get(sk);
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 
 	/* We'll fix this up when we get a response from the other end.
 	 * See tcp_input.c:tcp_rcv_state_process case TCP_SYN_SENT.
@@ -1426,8 +1439,8 @@
 		(sysctl_tcp_timestamps ? TCPOLEN_TSTAMP_ALIGNED : 0);
 
 	/* If user gave his TCP_MAXSEG, record it to clamp */
-	if (tp->user_mss)
-		tp->mss_clamp = tp->user_mss;
+	if (tp->rx_opt.user_mss)
+		tp->rx_opt.mss_clamp = tp->rx_opt.user_mss;
 	tp->max_window = 0;
 	tcp_sync_mss(sk, dst_pmtu(dst));
 
@@ -1438,11 +1451,11 @@
 	tcp_ca_init(tp);
 
 	tcp_select_initial_window(tcp_full_space(sk),
-				  tp->advmss - (tp->ts_recent_stamp ? tp->tcp_header_len - sizeof(struct tcphdr) : 0),
+				  tp->advmss - (tp->rx_opt.ts_recent_stamp ? tp->tcp_header_len - sizeof(struct tcphdr) : 0),
 				  &tp->rcv_wnd,
 				  &tp->window_clamp,
 				  sysctl_tcp_window_scaling,
-				  &tp->rcv_wscale);
+				  &tp->rx_opt.rcv_wscale);
 
 	tp->rcv_ssthresh = tp->rcv_wnd;
 
@@ -1466,7 +1479,7 @@
  */ 
 int tcp_connect(struct sock *sk)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	struct sk_buff *buff;
 
 	tcp_connect_init(sk);
@@ -1495,7 +1508,7 @@
 	tp->retrans_stamp = TCP_SKB_CB(buff)->when;
 	__skb_queue_tail(&sk->sk_write_queue, buff);
 	sk_charge_skb(sk, buff);
-	tcp_inc_pcount(&tp->packets_out, buff);
+	tp->packets_out += tcp_skb_pcount(buff);
 	tcp_transmit_skb(sk, skb_clone(buff, GFP_KERNEL));
 	TCP_INC_STATS(TCP_MIB_ACTIVEOPENS);
 
@@ -1510,7 +1523,7 @@
  */
 void tcp_send_delayed_ack(struct sock *sk)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	int ato = tp->ack.ato;
 	unsigned long timeout;
 
@@ -1562,7 +1575,7 @@
 {
 	/* If we have been reset, we may not send again. */
 	if (sk->sk_state != TCP_CLOSE) {
-		struct tcp_opt *tp = tcp_sk(sk);
+		struct tcp_sock *tp = tcp_sk(sk);
 		struct sk_buff *buff;
 
 		/* We are not putting this on the write queue, so
@@ -1605,7 +1618,7 @@
  */
 static int tcp_xmit_probe_skb(struct sock *sk, int urgent)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	struct sk_buff *skb;
 
 	/* We don't queue it, tcp_transmit_skb() sets ownership. */
@@ -1634,7 +1647,7 @@
 int tcp_write_wakeup(struct sock *sk)
 {
 	if (sk->sk_state != TCP_CLOSE) {
-		struct tcp_opt *tp = tcp_sk(sk);
+		struct tcp_sock *tp = tcp_sk(sk);
 		struct sk_buff *skb;
 
 		if ((skb = sk->sk_send_head) != NULL &&
@@ -1668,6 +1681,7 @@
 
 			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);
@@ -1688,12 +1702,12 @@
  */
 void tcp_send_probe0(struct sock *sk)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	int err;
 
 	err = tcp_write_wakeup(sk);
 
-	if (tcp_get_pcount(&tp->packets_out) || !sk->sk_send_head) {
+	if (tp->packets_out || !sk->sk_send_head) {
 		/* Cancel probe timer, if it is not required. */
 		tp->probes_out = 0;
 		tp->backoff = 0;
diff -Nru a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
--- a/net/ipv4/tcp_timer.c	2005-03-01 23:39:16 -08:00
+++ b/net/ipv4/tcp_timer.c	2005-03-01 23:39:16 -08:00
@@ -48,7 +48,7 @@
 
 void tcp_init_xmit_timers(struct sock *sk)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 
 	init_timer(&tp->retransmit_timer);
 	tp->retransmit_timer.function=&tcp_write_timer;
@@ -67,7 +67,7 @@
 
 void tcp_clear_xmit_timers(struct sock *sk)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 
 	tp->pending = 0;
 	sk_stop_timer(sk, &tp->retransmit_timer);
@@ -101,7 +101,7 @@
  */
 static int tcp_out_of_resources(struct sock *sk, int do_reset)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	int orphans = atomic_read(&tcp_orphan_count);
 
 	/* If peer does not open window for long time, or did not transmit 
@@ -123,7 +123,7 @@
 		 *      1. Last segment was sent recently. */
 		if ((s32)(tcp_time_stamp - tp->lsndtime) <= TCP_TIMEWAIT_LEN ||
 		    /*  2. Window is closed. */
-		    (!tp->snd_wnd && !tcp_get_pcount(&tp->packets_out)))
+		    (!tp->snd_wnd && !tp->packets_out))
 			do_reset = 1;
 		if (do_reset)
 			tcp_send_active_reset(sk, GFP_ATOMIC);
@@ -154,7 +154,7 @@
 /* A write timeout has occurred. Process the after effects. */
 static int tcp_write_timeout(struct sock *sk)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	int retry_until;
 
 	if ((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV)) {
@@ -208,7 +208,7 @@
 static void tcp_delack_timer(unsigned long data)
 {
 	struct sock *sk = (struct sock*)data;
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 
 	bh_lock_sock(sk);
 	if (sock_owned_by_user(sk)) {
@@ -268,10 +268,10 @@
 
 static void tcp_probe_timer(struct sock *sk)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	int max_probes;
 
-	if (tcp_get_pcount(&tp->packets_out) || !sk->sk_send_head) {
+	if (tp->packets_out || !sk->sk_send_head) {
 		tp->probes_out = 0;
 		return;
 	}
@@ -316,9 +316,9 @@
 
 static void tcp_retransmit_timer(struct sock *sk)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 
-	if (!tcp_get_pcount(&tp->packets_out))
+	if (!tp->packets_out)
 		goto out;
 
 	BUG_TRAP(!skb_queue_empty(&sk->sk_write_queue));
@@ -332,7 +332,7 @@
 		 */
 #ifdef TCP_DEBUG
 		if (net_ratelimit()) {
-			struct inet_opt *inet = inet_sk(sk);
+			struct inet_sock *inet = inet_sk(sk);
 			printk(KERN_DEBUG "TCP: Treason uncloaked! Peer %u.%u.%u.%u:%u/%u shrinks window %u:%u. Repaired.\n",
 			       NIPQUAD(inet->daddr), htons(inet->dport),
 			       inet->num, tp->snd_una, tp->snd_nxt);
@@ -353,7 +353,7 @@
 
 	if (tp->retransmits == 0) {
 		if (tp->ca_state == TCP_CA_Disorder || tp->ca_state == TCP_CA_Recovery) {
-			if (tp->sack_ok) {
+			if (tp->rx_opt.sack_ok) {
 				if (tp->ca_state == TCP_CA_Recovery)
 					NET_INC_STATS_BH(LINUX_MIB_TCPSACKRECOVERYFAIL);
 				else
@@ -418,7 +418,7 @@
 static void tcp_write_timer(unsigned long data)
 {
 	struct sock *sk = (struct sock*)data;
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	int event;
 
 	bh_lock_sock(sk);
@@ -462,7 +462,7 @@
 
 static void tcp_synack_timer(struct sock *sk)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	struct tcp_listen_opt *lopt = tp->listen_opt;
 	int max_retries = tp->syn_retries ? : sysctl_tcp_synack_retries;
 	int thresh = max_retries;
@@ -573,7 +573,7 @@
 static void tcp_keepalive_timer (unsigned long data)
 {
 	struct sock *sk = (struct sock *) data;
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	__u32 elapsed;
 
 	/* Only process if socket is not in use. */
@@ -608,7 +608,7 @@
 	elapsed = keepalive_time_when(tp);
 
 	/* It is alive without keepalive 8) */
-	if (tcp_get_pcount(&tp->packets_out) || sk->sk_send_head)
+	if (tp->packets_out || sk->sk_send_head)
 		goto resched;
 
 	elapsed = tcp_time_stamp - tp->rcv_tstamp;
@@ -653,6 +653,3 @@
 EXPORT_SYMBOL(tcp_delete_keepalive_timer);
 EXPORT_SYMBOL(tcp_init_xmit_timers);
 EXPORT_SYMBOL(tcp_reset_keepalive_timer);
-#ifdef TCP_DEBUG
-EXPORT_SYMBOL(tcp_timer_bug_msg);
-#endif
diff -Nru a/net/ipv4/udp.c b/net/ipv4/udp.c
--- a/net/ipv4/udp.c	2005-03-01 23:38:53 -08:00
+++ b/net/ipv4/udp.c	2005-03-01 23:38:53 -08:00
@@ -115,7 +115,7 @@
 DEFINE_SNMP_STAT(struct udp_mib, udp_statistics);
 
 struct hlist_head udp_hash[UDP_HTABLE_SIZE];
-rwlock_t udp_hash_lock = RW_LOCK_UNLOCKED;
+DEFINE_RWLOCK(udp_hash_lock);
 
 /* Shared by v4/v6 udp. */
 int udp_port_rover;
@@ -124,7 +124,7 @@
 {
 	struct hlist_node *node;
 	struct sock *sk2;
-	struct inet_opt *inet = inet_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
 
 	write_lock_bh(&udp_hash_lock);
 	if (snum == 0) {
@@ -171,7 +171,7 @@
 	} else {
 		sk_for_each(sk2, node,
 			    &udp_hash[snum & (UDP_HTABLE_SIZE - 1)]) {
-			struct inet_opt *inet2 = inet_sk(sk2);
+			struct inet_sock *inet2 = inet_sk(sk2);
 
 			if (inet2->num == snum &&
 			    sk2 != sk &&
@@ -219,7 +219,8 @@
 /* UDP is nearly always wildcards out the wazoo, it makes no sense to try
  * harder than this. -DaveM
  */
-struct sock *udp_v4_lookup_longway(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif)
+static struct sock *udp_v4_lookup_longway(u32 saddr, u16 sport,
+					  u32 daddr, u16 dport, int dif)
 {
 	struct sock *sk, *result = NULL;
 	struct hlist_node *node;
@@ -227,7 +228,7 @@
 	int badness = -1;
 
 	sk_for_each(sk, node, &udp_hash[hnum & (UDP_HTABLE_SIZE - 1)]) {
-		struct inet_opt *inet = inet_sk(sk);
+		struct inet_sock *inet = inet_sk(sk);
 
 		if (inet->num == hnum && !ipv6_only_sock(sk)) {
 			int score = (sk->sk_family == PF_INET ? 1 : 0);
@@ -263,7 +264,8 @@
 	return result;
 }
 
-__inline__ struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif)
+static __inline__ struct sock *udp_v4_lookup(u32 saddr, u16 sport,
+					     u32 daddr, u16 dport, int dif)
 {
 	struct sock *sk;
 
@@ -285,7 +287,7 @@
 	unsigned short hnum = ntohs(loc_port);
 
 	sk_for_each_from(s, node) {
-		struct inet_opt *inet = inet_sk(s);
+		struct inet_sock *inet = inet_sk(s);
 
 		if (inet->num != hnum					||
 		    (inet->daddr && inet->daddr != rmt_addr)		||
@@ -316,7 +318,7 @@
 
 void udp_err(struct sk_buff *skb, u32 info)
 {
-	struct inet_opt *inet;
+	struct inet_sock *inet;
 	struct iphdr *iph = (struct iphdr*)skb->data;
 	struct udphdr *uh = (struct udphdr*)(skb->data+(iph->ihl<<2));
 	int type = skb->h.icmph->type;
@@ -384,7 +386,7 @@
  */
 static void udp_flush_pending_frames(struct sock *sk)
 {
-	struct udp_opt *up = udp_sk(sk);
+	struct udp_sock *up = udp_sk(sk);
 
 	if (up->pending) {
 		up->len = 0;
@@ -396,9 +398,9 @@
 /*
  * Push out all pending data as one UDP datagram. Socket is locked.
  */
-static int udp_push_pending_frames(struct sock *sk, struct udp_opt *up)
+static int udp_push_pending_frames(struct sock *sk, struct udp_sock *up)
 {
-	struct inet_opt *inet = inet_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
 	struct flowi *fl = &inet->cork.fl;
 	struct sk_buff *skb;
 	struct udphdr *uh;
@@ -480,8 +482,8 @@
 int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
 		size_t len)
 {
-	struct inet_opt *inet = inet_sk(sk);
-	struct udp_opt *up = udp_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
+	struct udp_sock *up = udp_sk(sk);
 	int ulen = len;
 	struct ipcm_cookie ipc;
 	struct rtable *rt = NULL;
@@ -667,9 +669,10 @@
 	goto out;
 }
 
-int udp_sendpage(struct sock *sk, struct page *page, int offset, size_t size, int flags)
+static int udp_sendpage(struct sock *sk, struct page *page, int offset,
+			size_t size, int flags)
 {
-	struct udp_opt *up = udp_sk(sk);
+	struct udp_sock *up = udp_sk(sk);
 	int ret;
 
 	if (!up->pending) {
@@ -770,10 +773,10 @@
  * 	return it, otherwise we block.
  */
 
-int udp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
-		size_t len, int noblock, int flags, int *addr_len)
+static int udp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
+		       size_t len, int noblock, int flags, int *addr_len)
 {
-	struct inet_opt *inet = inet_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
   	struct sockaddr_in *sin = (struct sockaddr_in *)msg->msg_name;
   	struct sk_buff *skb;
   	int copied, err;
@@ -864,7 +867,7 @@
 
 int udp_disconnect(struct sock *sk, int flags)
 {
-	struct inet_opt *inet = inet_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
 	/*
 	 *	1003.1g - break association.
 	 */
@@ -899,7 +902,7 @@
 #ifndef CONFIG_XFRM
 	return 1; 
 #else
-	struct udp_opt *up = udp_sk(sk);
+	struct udp_sock *up = udp_sk(sk);
   	struct udphdr *uh = skb->h.uh;
 	struct iphdr *iph;
 	int iphlen, len;
@@ -985,7 +988,7 @@
  */
 static int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
 {
-	struct udp_opt *up = udp_sk(sk);
+	struct udp_sock *up = udp_sk(sk);
 
 	/*
 	 *	Charge it to the socket, dropping if the queue is full.
@@ -1220,7 +1223,7 @@
 static int udp_setsockopt(struct sock *sk, int level, int optname, 
 			  char __user *optval, int optlen)
 {
-	struct udp_opt *up = udp_sk(sk);
+	struct udp_sock *up = udp_sk(sk);
 	int val;
 	int err = 0;
 
@@ -1269,7 +1272,7 @@
 static int udp_getsockopt(struct sock *sk, int level, int optname, 
 			  char __user *optval, int __user *optlen)
 {
-	struct udp_opt *up = udp_sk(sk);
+	struct udp_sock *up = udp_sk(sk);
 	int val, len;
 
 	if (level != SOL_UDP)
@@ -1503,7 +1506,7 @@
 /* ------------------------------------------------------------------------ */
 static void udp4_format_sock(struct sock *sp, char *tmpbuf, int bucket)
 {
-	struct inet_opt *inet = inet_sk(sp);
+	struct inet_sock *inet = inet_sk(sp);
 	unsigned int dest = inet->daddr;
 	unsigned int src  = inet->rcv_saddr;
 	__u16 destp	  = ntohs(inet->dport);
diff -Nru a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
--- a/net/ipv4/xfrm4_policy.c	2005-03-01 23:39:08 -08:00
+++ b/net/ipv4/xfrm4_policy.c	2005-03-01 23:39:08 -08:00
@@ -279,10 +279,3 @@
 	xfrm4_policy_init();
 }
 
-void __exit xfrm4_fini(void)
-{
-	//xfrm4_input_fini();
-	xfrm4_policy_fini();
-	xfrm4_state_fini();
-}
-
diff -Nru a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
--- a/net/ipv6/addrconf.c	2005-03-01 23:39:16 -08:00
+++ b/net/ipv6/addrconf.c	2005-03-01 23:39:16 -08:00
@@ -48,6 +48,7 @@
 #include <linux/netdevice.h>
 #include <linux/if_arp.h>
 #include <linux/if_arcnet.h>
+#include <linux/if_infiniband.h>
 #include <linux/route.h>
 #include <linux/inetdevice.h>
 #include <linux/init.h>
@@ -98,9 +99,6 @@
 static void addrconf_sysctl_unregister(struct ipv6_devconf *p);
 #endif
 
-int inet6_dev_count;
-int inet6_ifa_count;
-
 #ifdef CONFIG_IPV6_PRIVACY
 static int __ipv6_regen_rndid(struct inet6_dev *idev);
 static int __ipv6_try_regen_rndid(struct inet6_dev *idev, struct in6_addr *tmpaddr); 
@@ -108,7 +106,7 @@
 
 static int desync_factor = MAX_DESYNC_FACTOR * HZ;
 static struct crypto_tfm *md5_tfm;
-static spinlock_t md5_tfm_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(md5_tfm_lock);
 #endif
 
 static int ipv6_count_addresses(struct inet6_dev *idev);
@@ -117,16 +115,16 @@
  *	Configured unicast address hash table
  */
 static struct inet6_ifaddr		*inet6_addr_lst[IN6_ADDR_HSIZE];
-static rwlock_t	addrconf_hash_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(addrconf_hash_lock);
 
 /* Protects inet6 devices */
-rwlock_t addrconf_lock = RW_LOCK_UNLOCKED;
+DEFINE_RWLOCK(addrconf_lock);
 
 static void addrconf_verify(unsigned long);
 
 static struct timer_list addr_chk_timer =
 			TIMER_INITIALIZER(addrconf_verify, 0, 0);
-static spinlock_t addrconf_verify_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(addrconf_verify_lock);
 
 static void addrconf_join_anycast(struct inet6_ifaddr *ifp);
 static void addrconf_leave_anycast(struct inet6_ifaddr *ifp);
@@ -190,7 +188,9 @@
 };
 
 /* IPv6 Wildcard Address and Loopback Address defined by RFC2553 */
+#if 0
 const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
+#endif
 const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
 
 int ipv6_addr_type(const struct in6_addr *addr)
@@ -308,8 +308,7 @@
 		printk("Freeing alive inet6 device %p\n", idev);
 		return;
 	}
-	snmp6_unregister_dev(idev);
-	inet6_dev_count--;
+	snmp6_free_dev(idev);
 	kfree(idev);
 }
 
@@ -337,10 +336,19 @@
 			kfree(ndev);
 			return NULL;
 		}
-		inet6_dev_count++;
 		/* We refer to the device */
 		dev_hold(dev);
 
+		if (snmp6_alloc_dev(ndev) < 0) {
+			ADBG((KERN_WARNING
+				"%s(): cannot allocate memory for statistics; dev=%s.\n",
+				__FUNCTION__, dev->name));
+			neigh_parms_release(&nd_tbl, ndev->nd_parms);
+			ndev->dead = 1;
+			in6_dev_finish_destroy(ndev);
+			return NULL;
+		}
+
 		if (snmp6_register_dev(ndev) < 0) {
 			ADBG((KERN_WARNING
 				"%s(): cannot create /proc/net/dev_snmp6/%s\n",
@@ -474,7 +482,6 @@
 	}
 	dst_release(&ifp->rt->u.dst);
 
-	inet6_ifa_count--;
 	kfree(ifp);
 }
 
@@ -529,7 +536,6 @@
 	ifa->flags = flags | IFA_F_TENTATIVE;
 	ifa->cstamp = ifa->tstamp = jiffies;
 
-	inet6_ifa_count++;
 	ifa->idev = idev;
 	in6_dev_hold(idev);
 	/* For caller */
@@ -1083,10 +1089,29 @@
 		if (dev->addr_len != ETH_ALEN)
 			return -1;
 		memcpy(eui, dev->dev_addr, 3);
-		memcpy(eui + 5, dev->dev_addr+3, 3);
-		eui[3] = 0xFF;
-		eui[4] = 0xFE;
-		eui[0] ^= 2;
+		memcpy(eui + 5, dev->dev_addr + 3, 3);
+
+		/*
+		 * The zSeries OSA network cards can be shared among various
+		 * OS instances, but the OSA cards have only one MAC address.
+		 * This leads to duplicate address conflicts in conjunction
+		 * with IPv6 if more than one instance uses the same card.
+		 * 
+		 * The driver for these cards can deliver a unique 16-bit
+		 * identifier for each instance sharing the same card.  It is
+		 * placed instead of 0xFFFE in the interface identifier.  The
+		 * "u" bit of the interface identifier is not inverted in this
+		 * case.  Hence the resulting interface identifier has local
+		 * scope according to RFC2373.
+		 */
+		if (dev->dev_id) {
+			eui[3] = (dev->dev_id >> 8) & 0xFF;
+			eui[4] = dev->dev_id & 0xFF;
+		} else {
+			eui[3] = 0xFF;
+			eui[4] = 0xFE;
+			eui[0] ^= 2;
+		}
 		return 0;
 	case ARPHRD_ARCNET:
 		/* XXX: inherit EUI-64 from other interface -- yoshfuji */
@@ -1095,6 +1120,12 @@
 		memset(eui, 0, 7);
 		eui[7] = *(u8*)dev->dev_addr;
 		return 0;
+	case ARPHRD_INFINIBAND:
+		if (dev->addr_len != INFINIBAND_ALEN)
+			return -1;
+		memcpy(eui, dev->dev_addr + 12, 8);
+		eui[0] |= 2;
+		return 0;
 	}
 	return -1;
 }
@@ -1794,7 +1825,8 @@
 	if ((dev->type != ARPHRD_ETHER) && 
 	    (dev->type != ARPHRD_FDDI) &&
 	    (dev->type != ARPHRD_IEEE802_TR) &&
-	    (dev->type != ARPHRD_ARCNET)) {
+	    (dev->type != ARPHRD_ARCNET) &&
+	    (dev->type != ARPHRD_INFINIBAND)) {
 		/* Alas, we support only Ethernet autoconfiguration. */
 		return;
 	}
@@ -1991,6 +2023,10 @@
 		dev->ip6_ptr = NULL;
 		idev->dead = 1;
 		write_unlock_bh(&addrconf_lock);
+
+		/* Step 1.5: remove snmp6 entry */
+		snmp6_unregister_dev(idev);
+
 	}
 
 	/* Step 2: clear hash table */
diff -Nru a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
--- a/net/ipv6/af_inet6.c	2005-03-01 23:38:58 -08:00
+++ b/net/ipv6/af_inet6.c	2005-03-01 23:38:58 -08:00
@@ -94,7 +94,7 @@
  * build a new socket.
  */
 static struct list_head inetsw6[SOCK_MAX];
-static spinlock_t inetsw6_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(inetsw6_lock);
 
 static void inet6_sock_destruct(struct sock *sk)
 {
@@ -114,10 +114,9 @@
 
 static int inet6_create(struct socket *sock, int protocol)
 {
-	struct inet_opt *inet;
+	struct inet_sock *inet;
 	struct ipv6_pinfo *np;
 	struct sock *sk;
-	struct tcp6_sock* tcp6sk;
 	struct list_head *p;
 	struct inet_protosw *answer;
 	struct proto *answer_prot;
@@ -196,8 +195,7 @@
 
 	sk->sk_backlog_rcv	= answer->prot->backlog_rcv;
 
-	tcp6sk		= (struct tcp6_sock *)sk;
-	tcp6sk->pinet6 = np = inet6_sk_generic(sk);
+	inet_sk(sk)->pinet6 = np = inet6_sk_generic(sk);
 	np->hop_limit	= -1;
 	np->mcast_hops	= -1;
 	np->mc_loop	= 1;
@@ -252,7 +250,7 @@
 {
 	struct sockaddr_in6 *addr=(struct sockaddr_in6 *)uaddr;
 	struct sock *sk = sock->sk;
-	struct inet_opt *inet = inet_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
 	struct ipv6_pinfo *np = inet6_sk(sk);
 	__u32 v4addr = 0;
 	unsigned short snum;
@@ -410,7 +408,7 @@
 {
 	struct sockaddr_in6 *sin=(struct sockaddr_in6 *)uaddr;
 	struct sock *sk = sock->sk;
-	struct inet_opt *inet = inet_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
 	struct ipv6_pinfo *np = inet6_sk(sk);
   
 	sin->sin6_family = AF_INET6;
@@ -654,8 +652,10 @@
 {
 	if (ptr == NULL)
 		return;
-	free_percpu(ptr[0]);
-	free_percpu(ptr[1]);
+	if (ptr[0])
+		free_percpu(ptr[0]);
+	if (ptr[1])
+		free_percpu(ptr[1]);
 	ptr[0] = ptr[1] = NULL;
 }
 
diff -Nru a/net/ipv6/ah6.c b/net/ipv6/ah6.c
--- a/net/ipv6/ah6.c	2005-03-01 23:39:07 -08:00
+++ b/net/ipv6/ah6.c	2005-03-01 23:39:07 -08:00
@@ -375,7 +375,7 @@
 	 * we need for AH processing.  This lookup cannot fail here
 	 * after a successful crypto_alloc_tfm().
 	 */
-	aalg_desc = xfrm_aalg_get_byname(x->aalg->alg_name);
+	aalg_desc = xfrm_aalg_get_byname(x->aalg->alg_name, 0);
 	BUG_ON(!aalg_desc);
 
 	if (aalg_desc->uinfo.auth.icv_fullbits/8 !=
diff -Nru a/net/ipv6/anycast.c b/net/ipv6/anycast.c
--- a/net/ipv6/anycast.c	2005-03-01 23:39:18 -08:00
+++ b/net/ipv6/anycast.c	2005-03-01 23:39:18 -08:00
@@ -43,8 +43,10 @@
 
 #include <net/checksum.h>
 
+static int ipv6_dev_ac_dec(struct net_device *dev, struct in6_addr *addr);
+
 /* Big ac list lock for all the sockets */
-static rwlock_t ipv6_sk_ac_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(ipv6_sk_ac_lock);
 
 /* XXX ip6_addr_match() and ip6_onlink() really belong in net/core.c */
 
@@ -413,7 +415,7 @@
 	return 0;
 }
 
-int ipv6_dev_ac_dec(struct net_device *dev, struct in6_addr *addr)
+static int ipv6_dev_ac_dec(struct net_device *dev, struct in6_addr *addr)
 {
 	int ret;
 	struct inet6_dev *idev = in6_dev_get(dev);
diff -Nru a/net/ipv6/datagram.c b/net/ipv6/datagram.c
--- a/net/ipv6/datagram.c	2005-03-01 23:38:52 -08:00
+++ b/net/ipv6/datagram.c	2005-03-01 23:38:52 -08:00
@@ -36,7 +36,7 @@
 int ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
 {
 	struct sockaddr_in6	*usin = (struct sockaddr_in6 *) uaddr;
-	struct inet_opt      	*inet = inet_sk(sk);
+	struct inet_sock      	*inet = inet_sk(sk);
 	struct ipv6_pinfo      	*np = inet6_sk(sk);
 	struct in6_addr		*daddr, *final_p = NULL, final;
 	struct dst_entry	*dst;
@@ -335,7 +335,7 @@
 			if (ipv6_addr_type(&sin->sin6_addr) & IPV6_ADDR_LINKLOCAL)
 				sin->sin6_scope_id = IP6CB(skb)->iif;
 		} else {
-			struct inet_opt *inet = inet_sk(sk);
+			struct inet_sock *inet = inet_sk(sk);
 
 			ipv6_addr_set(&sin->sin6_addr, 0, 0,
 				      htonl(0xffff),
diff -Nru a/net/ipv6/esp6.c b/net/ipv6/esp6.c
--- a/net/ipv6/esp6.c	2005-03-01 23:39:07 -08:00
+++ b/net/ipv6/esp6.c	2005-03-01 23:39:07 -08:00
@@ -329,7 +329,7 @@
 			goto error;
 		esp->auth.icv = esp_hmac_digest;
  
-		aalg_desc = xfrm_aalg_get_byname(x->aalg->alg_name);
+		aalg_desc = xfrm_aalg_get_byname(x->aalg->alg_name, 0);
 		BUG_ON(!aalg_desc);
  
 		if (aalg_desc->uinfo.auth.icv_fullbits/8 !=
@@ -364,7 +364,8 @@
 			goto error;
 		get_random_bytes(esp->conf.ivec, esp->conf.ivlen);
 	}
-	crypto_cipher_setkey(esp->conf.tfm, esp->conf.key, esp->conf.key_len);
+	if (crypto_cipher_setkey(esp->conf.tfm, esp->conf.key, esp->conf.key_len))
+		goto error;
 	x->props.header_len = sizeof(struct ipv6_esp_hdr) + esp->conf.ivlen;
 	if (x->props.mode)
 		x->props.header_len += sizeof(struct ipv6hdr);
@@ -372,15 +373,9 @@
 	return 0;
 
 error:
-	if (esp) {
-		if (esp->auth.tfm)
-			crypto_free_tfm(esp->auth.tfm);
-		if (esp->auth.work_icv)
-			kfree(esp->auth.work_icv);
-		if (esp->conf.tfm)
-			crypto_free_tfm(esp->conf.tfm);
-		kfree(esp);
-	}
+	x->data = esp;
+	esp6_destroy(x);
+	x->data = NULL;
 	return -EINVAL;
 }
 
diff -Nru a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
--- a/net/ipv6/exthdrs.c	2005-03-01 23:38:51 -08:00
+++ b/net/ipv6/exthdrs.c	2005-03-01 23:38:51 -08:00
@@ -501,83 +501,6 @@
  *	for headers.
  */
 
-static u8 *ipv6_build_rthdr(struct sk_buff *skb, u8 *prev_hdr,
-		     struct ipv6_rt_hdr *opt, struct in6_addr *addr)
-{
-	struct rt0_hdr *phdr, *ihdr;
-	int hops;
-
-	ihdr = (struct rt0_hdr *) opt;
-	
-	phdr = (struct rt0_hdr *) skb_put(skb, (ihdr->rt_hdr.hdrlen + 1) << 3);
-	memcpy(phdr, ihdr, sizeof(struct rt0_hdr));
-
-	hops = ihdr->rt_hdr.hdrlen >> 1;
-
-	if (hops > 1)
-		memcpy(phdr->addr, ihdr->addr + 1,
-		       (hops - 1) * sizeof(struct in6_addr));
-
-	ipv6_addr_copy(phdr->addr + (hops - 1), addr);
-
-	phdr->rt_hdr.nexthdr = *prev_hdr;
-	*prev_hdr = NEXTHDR_ROUTING;
-	return &phdr->rt_hdr.nexthdr;
-}
-
-static u8 *ipv6_build_exthdr(struct sk_buff *skb, u8 *prev_hdr, u8 type, struct ipv6_opt_hdr *opt)
-{
-	struct ipv6_opt_hdr *h = (struct ipv6_opt_hdr *)skb_put(skb, ipv6_optlen(opt));
-
-	memcpy(h, opt, ipv6_optlen(opt));
-	h->nexthdr = *prev_hdr;
-	*prev_hdr = type;
-	return &h->nexthdr;
-}
-
-u8 *ipv6_build_nfrag_opts(struct sk_buff *skb, u8 *prev_hdr, struct ipv6_txoptions *opt,
-			  struct in6_addr *daddr, u32 jumbolen)
-{
-	struct ipv6_opt_hdr *h = (struct ipv6_opt_hdr *)skb->data;
-
-	if (opt && opt->hopopt)
-		prev_hdr = ipv6_build_exthdr(skb, prev_hdr, NEXTHDR_HOP, opt->hopopt);
-
-	if (jumbolen) {
-		u8 *jumboopt = (u8 *)skb_put(skb, 8);
-
-		if (opt && opt->hopopt) {
-			*jumboopt++ = IPV6_TLV_PADN;
-			*jumboopt++ = 0;
-			h->hdrlen++;
-		} else {
-			h = (struct ipv6_opt_hdr *)jumboopt;
-			h->nexthdr = *prev_hdr;
-			h->hdrlen = 0;
-			jumboopt += 2;
-			*prev_hdr = NEXTHDR_HOP;
-			prev_hdr = &h->nexthdr;
-		}
-		jumboopt[0] = IPV6_TLV_JUMBO;
-		jumboopt[1] = 4;
-		*(u32*)(jumboopt+2) = htonl(jumbolen);
-	}
-	if (opt) {
-		if (opt->dst0opt)
-			prev_hdr = ipv6_build_exthdr(skb, prev_hdr, NEXTHDR_DEST, opt->dst0opt);
-		if (opt->srcrt)
-			prev_hdr = ipv6_build_rthdr(skb, prev_hdr, opt->srcrt, daddr);
-	}
-	return prev_hdr;
-}
-
-u8 *ipv6_build_frag_opts(struct sk_buff *skb, u8 *prev_hdr, struct ipv6_txoptions *opt)
-{
-	if (opt->dst1opt)
-		prev_hdr = ipv6_build_exthdr(skb, prev_hdr, NEXTHDR_DEST, opt->dst1opt);
-	return prev_hdr;
-}
-
 static void ipv6_push_rthdr(struct sk_buff *skb, u8 *proto,
 			    struct ipv6_rt_hdr *opt,
 			    struct in6_addr **addr_p)
diff -Nru a/net/ipv6/icmp.c b/net/ipv6/icmp.c
--- a/net/ipv6/icmp.c	2005-03-01 23:38:54 -08:00
+++ b/net/ipv6/icmp.c	2005-03-01 23:38:54 -08:00
@@ -211,7 +211,7 @@
 	return (*op & 0xC0) == 0x80;
 }
 
-int icmpv6_push_pending_frames(struct sock *sk, struct flowi *fl, struct icmp6hdr *thdr, int len)
+static int icmpv6_push_pending_frames(struct sock *sk, struct flowi *fl, struct icmp6hdr *thdr, int len)
 {
 	struct sk_buff *skb;
 	struct icmp6hdr *icmp6h;
@@ -287,7 +287,7 @@
 	int iif = 0;
 	int addr_type = 0;
 	int len;
-	int hlimit = -1;
+	int hlimit;
 	int err = 0;
 
 	if ((u8*)hdr < skb->head || (u8*)(hdr+1) > skb->tail)
@@ -375,14 +375,12 @@
 	if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0)
 		goto out_dst_release;
 
-	if (hlimit < 0) {
-		if (ipv6_addr_is_multicast(&fl.fl6_dst))
-			hlimit = np->mcast_hops;
-		else
-			hlimit = np->hop_limit;
-		if (hlimit < 0)
-			hlimit = dst_metric(dst, RTAX_HOPLIMIT);
-	}
+	if (ipv6_addr_is_multicast(&fl.fl6_dst))
+		hlimit = np->mcast_hops;
+	else
+		hlimit = np->hop_limit;
+	if (hlimit < 0)
+		hlimit = dst_metric(dst, RTAX_HOPLIMIT);
 
 	msg.skb = skb;
 	msg.offset = skb->nh.raw - skb->data;
@@ -433,7 +431,7 @@
 	struct icmpv6_msg msg;
 	struct dst_entry *dst;
 	int err = 0;
-	int hlimit = -1;
+	int hlimit;
 
 	saddr = &skb->nh.ipv6h->daddr;
 
@@ -463,14 +461,12 @@
 	if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0)
 		goto out_dst_release;
 
-	if (hlimit < 0) {
-		if (ipv6_addr_is_multicast(&fl.fl6_dst))
-			hlimit = np->mcast_hops;
-		else
-			hlimit = np->hop_limit;
-		if (hlimit < 0)
-			hlimit = dst_metric(dst, RTAX_HOPLIMIT);
-	}
+	if (ipv6_addr_is_multicast(&fl.fl6_dst))
+		hlimit = np->mcast_hops;
+	else
+		hlimit = np->hop_limit;
+	if (hlimit < 0)
+		hlimit = dst_metric(dst, RTAX_HOPLIMIT);
 
 	idev = in6_dev_get(skb->dev);
 
diff -Nru a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
--- a/net/ipv6/ip6_fib.c	2005-03-01 23:39:09 -08:00
+++ b/net/ipv6/ip6_fib.c	2005-03-01 23:39:09 -08:00
@@ -69,7 +69,7 @@
 	void *arg;
 };
 
-rwlock_t fib6_walker_lock = RW_LOCK_UNLOCKED;
+DEFINE_RWLOCK(fib6_walker_lock);
 
 
 #ifdef CONFIG_IPV6_SUBTREES
@@ -1205,7 +1205,7 @@
 	return 0;
 }
 
-static spinlock_t fib6_gc_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(fib6_gc_lock);
 
 void fib6_run_gc(unsigned long dummy)
 {
diff -Nru a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c
--- a/net/ipv6/ip6_flowlabel.c	2005-03-01 23:38:53 -08:00
+++ b/net/ipv6/ip6_flowlabel.c	2005-03-01 23:38:53 -08:00
@@ -54,11 +54,11 @@
 
 /* FL hash table lock: it protects only of GC */
 
-static rwlock_t ip6_fl_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(ip6_fl_lock);
 
 /* Big socket sock */
 
-static rwlock_t ip6_sk_fl_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(ip6_sk_fl_lock);
 
 
 static __inline__ struct ip6_flowlabel * __fl_lookup(u32 label)
diff -Nru a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
--- a/net/ipv6/ip6_output.c	2005-03-01 23:38:52 -08:00
+++ b/net/ipv6/ip6_output.c	2005-03-01 23:38:52 -08:00
@@ -61,7 +61,7 @@
 static __inline__ void ipv6_select_ident(struct sk_buff *skb, struct frag_hdr *fhdr)
 {
 	static u32 ipv6_fragmentation_id = 1;
-	static spinlock_t ip6_id_lock = SPIN_LOCK_UNLOCKED;
+	static DEFINE_SPINLOCK(ip6_id_lock);
 
 	spin_lock_bh(&ip6_id_lock);
 	fhdr->identification = htonl(ipv6_fragmentation_id);
@@ -311,7 +311,7 @@
 	return 0;
 }
 
-int ip6_call_ra_chain(struct sk_buff *skb, int sel)
+static int ip6_call_ra_chain(struct sk_buff *skb, int sel)
 {
 	struct ip6_ra_chain *ra;
 	struct sock *last = NULL;
@@ -463,6 +463,7 @@
 	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;
 
@@ -592,6 +593,7 @@
 			/* Prepare header of the next frame,
 			 * before previous one went down. */
 			if (frag) {
+				frag->ip_summed = CHECKSUM_NONE;
 				frag->h.raw = frag->data;
 				fh = (struct frag_hdr*)__skb_push(frag, sizeof(struct frag_hdr));
 				frag->nh.raw = __skb_push(frag, hlen);
@@ -745,7 +747,7 @@
 	if (sk) {
 		struct ipv6_pinfo *np = inet6_sk(sk);
 	
-		*dst = __sk_dst_check(sk, np->dst_cookie);
+		*dst = sk_dst_check(sk, np->dst_cookie);
 		if (*dst) {
 			struct rt6_info *rt = (struct rt6_info*)*dst;
 	
@@ -772,9 +774,9 @@
 			     && (np->daddr_cache == NULL ||
 				 !ipv6_addr_equal(&fl->fl6_dst, np->daddr_cache)))
 			    || (fl->oif && fl->oif != (*dst)->dev->ifindex)) {
+				dst_release(*dst);
 				*dst = NULL;
-			} else
-				dst_hold(*dst);
+			}
 		}
 	}
 
@@ -809,7 +811,7 @@
 		    int hlimit, struct ipv6_txoptions *opt, struct flowi *fl, struct rt6_info *rt,
 		    unsigned int flags)
 {
-	struct inet_opt *inet = inet_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
 	struct ipv6_pinfo *np = inet6_sk(sk);
 	struct sk_buff *skb;
 	unsigned int maxfraglen, fragheaderlen;
@@ -1087,7 +1089,7 @@
 	struct sk_buff *skb, *tmp_skb;
 	struct sk_buff **tail_skb;
 	struct in6_addr final_dst_buf, *final_dst = &final_dst_buf;
-	struct inet_opt *inet = inet_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
 	struct ipv6_pinfo *np = inet6_sk(sk);
 	struct ipv6hdr *hdr;
 	struct ipv6_txoptions *opt = np->cork.opt;
@@ -1165,7 +1167,7 @@
 
 void ip6_flush_pending_frames(struct sock *sk)
 {
-	struct inet_opt *inet = inet_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
 	struct ipv6_pinfo *np = inet6_sk(sk);
 	struct sk_buff *skb;
 
diff -Nru a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
--- a/net/ipv6/ip6_tunnel.c	2005-03-01 23:38:52 -08:00
+++ b/net/ipv6/ip6_tunnel.c	2005-03-01 23:38:52 -08:00
@@ -85,7 +85,7 @@
 static struct ip6_tnl **tnls[2] = { tnls_wc, tnls_r_l };
 
 /* lock for the tunnel lists */
-static rwlock_t ip6ip6_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(ip6ip6_lock);
 
 static inline struct dst_entry *ip6_tnl_dst_check(struct ip6_tnl *t)
 {
@@ -180,10 +180,10 @@
 {
 	struct ip6_tnl **tp = ip6ip6_bucket(&t->parms);
 
-	write_lock_bh(&ip6ip6_lock);
 	t->next = *tp;
-	write_unlock_bh(&ip6ip6_lock);
+	write_lock_bh(&ip6ip6_lock);
 	*tp = t;
+	write_unlock_bh(&ip6ip6_lock);
 }
 
 /**
diff -Nru a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c
--- a/net/ipv6/ipcomp6.c	2005-03-01 23:38:57 -08:00
+++ b/net/ipv6/ipcomp6.c	2005-03-01 23:38:57 -08:00
@@ -468,7 +468,7 @@
 			goto error_tunnel;
 	}
 
-	calg_desc = xfrm_calg_get_byname(x->calg->alg_name);
+	calg_desc = xfrm_calg_get_byname(x->calg->alg_name, 0);
 	BUG_ON(!calg_desc);
 	ipcd->threshold = calg_desc->uinfo.comp.threshold;
 	x->data = ipcd;
diff -Nru a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
--- a/net/ipv6/ipv6_sockglue.c	2005-03-01 23:38:52 -08:00
+++ b/net/ipv6/ipv6_sockglue.c	2005-03-01 23:38:52 -08:00
@@ -63,7 +63,7 @@
 };
 
 struct ip6_ra_chain *ip6_ra_chain;
-rwlock_t ip6_ra_lock = RW_LOCK_UNLOCKED;
+DEFINE_RWLOCK(ip6_ra_lock);
 
 int ip6_ra_control(struct sock *sk, int sel, void (*destructor)(struct sock *))
 {
@@ -164,7 +164,7 @@
 			ipv6_sock_mc_close(sk);
 
 			if (sk->sk_protocol == IPPROTO_TCP) {
-				struct tcp_opt *tp = tcp_sk(sk);
+				struct tcp_sock *tp = tcp_sk(sk);
 
 				local_bh_disable();
 				sock_prot_dec_use(sk->sk_prot);
@@ -281,7 +281,7 @@
 		retv = 0;
 		if (sk->sk_type == SOCK_STREAM) {
 			if (opt) {
-				struct tcp_opt *tp = tcp_sk(sk);
+				struct tcp_sock *tp = tcp_sk(sk);
 				if (!((1 << sk->sk_state) &
 				      (TCPF_LISTEN | TCPF_CLOSE))
 				    && inet_sk(sk)->daddr != LOOPBACK4_IPV6) {
diff -Nru a/net/ipv6/ipv6_syms.c b/net/ipv6/ipv6_syms.c
--- a/net/ipv6/ipv6_syms.c	2005-03-01 23:39:08 -08:00
+++ b/net/ipv6/ipv6_syms.c	2005-03-01 23:39:08 -08:00
@@ -32,8 +32,6 @@
 EXPORT_SYMBOL(inet6_ioctl);
 EXPORT_SYMBOL(ipv6_get_saddr);
 EXPORT_SYMBOL(ipv6_chk_addr);
-EXPORT_SYMBOL(in6addr_any);
-EXPORT_SYMBOL(in6addr_loopback);
 EXPORT_SYMBOL(in6_dev_finish_destroy);
 #ifdef CONFIG_XFRM
 EXPORT_SYMBOL(xfrm6_rcv);
diff -Nru a/net/ipv6/mcast.c b/net/ipv6/mcast.c
--- a/net/ipv6/mcast.c	2005-03-01 23:39:09 -08:00
+++ b/net/ipv6/mcast.c	2005-03-01 23:39:09 -08:00
@@ -121,10 +121,10 @@
 	struct in6_addr srcs[0];
 };
 
-struct in6_addr mld2_all_mcr = MLD2_ALL_MCR_INIT;
+static struct in6_addr mld2_all_mcr = MLD2_ALL_MCR_INIT;
 
 /* Big mc list lock for all the sockets */
-static rwlock_t ipv6_sk_mc_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(ipv6_sk_mc_lock);
 
 static struct socket *igmp6_socket;
 
@@ -143,12 +143,14 @@
 static int sf_setstate(struct ifmcaddr6 *pmc);
 static void sf_markstate(struct ifmcaddr6 *pmc);
 static void ip6_mc_clear_src(struct ifmcaddr6 *pmc);
-int ip6_mc_del_src(struct inet6_dev *idev, struct in6_addr *pmca, int sfmode,
-	int sfcount, struct in6_addr *psfsrc, int delta);
-int ip6_mc_add_src(struct inet6_dev *idev, struct in6_addr *pmca, int sfmode,
-	int sfcount, struct in6_addr *psfsrc, int delta);
-int ip6_mc_leave_src(struct sock *sk, struct ipv6_mc_socklist *iml,
-	struct inet6_dev *idev);
+static int ip6_mc_del_src(struct inet6_dev *idev, struct in6_addr *pmca,
+			  int sfmode, int sfcount, struct in6_addr *psfsrc,
+			  int delta);
+static int ip6_mc_add_src(struct inet6_dev *idev, struct in6_addr *pmca,
+			  int sfmode, int sfcount, struct in6_addr *psfsrc,
+			  int delta);
+static int ip6_mc_leave_src(struct sock *sk, struct ipv6_mc_socklist *iml,
+			    struct inet6_dev *idev);
 
 
 #define IGMP6_UNSOLICITED_IVAL	(10*HZ)
@@ -272,7 +274,7 @@
 	return -ENOENT;
 }
 
-struct inet6_dev *ip6_mc_find_dev(struct in6_addr *group, int ifindex)
+static struct inet6_dev *ip6_mc_find_dev(struct in6_addr *group, int ifindex)
 {
 	struct net_device *dev = NULL;
 	struct inet6_dev *idev = NULL;
@@ -1723,8 +1725,9 @@
 	return rv;
 }
 
-int ip6_mc_del_src(struct inet6_dev *idev, struct in6_addr *pmca, int sfmode,
-	int sfcount, struct in6_addr *psfsrc, int delta)
+static int ip6_mc_del_src(struct inet6_dev *idev, struct in6_addr *pmca,
+			  int sfmode, int sfcount, struct in6_addr *psfsrc,
+			  int delta)
 {
 	struct ifmcaddr6 *pmc;
 	int	changerec = 0;
@@ -1847,8 +1850,9 @@
 /*
  * Add multicast source filter list to the interface list
  */
-int ip6_mc_add_src(struct inet6_dev *idev, struct in6_addr *pmca, int sfmode,
-	int sfcount, struct in6_addr *psfsrc, int delta)
+static int ip6_mc_add_src(struct inet6_dev *idev, struct in6_addr *pmca,
+			  int sfmode, int sfcount, struct in6_addr *psfsrc,
+			  int delta)
 {
 	struct ifmcaddr6 *pmc;
 	int	isexclude;
@@ -1951,8 +1955,8 @@
 	spin_unlock_bh(&ma->mca_lock);
 }
 
-int ip6_mc_leave_src(struct sock *sk, struct ipv6_mc_socklist *iml,
-	struct inet6_dev *idev)
+static int ip6_mc_leave_src(struct sock *sk, struct ipv6_mc_socklist *iml,
+			    struct inet6_dev *idev)
 {
 	int err;
 
diff -Nru a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
--- a/net/ipv6/ndisc.c	2005-03-01 23:38:58 -08:00
+++ b/net/ipv6/ndisc.c	2005-03-01 23:38:58 -08:00
@@ -169,12 +169,33 @@
 
 #define NDISC_OPT_SPACE(len) (((len)+2+7)&~7)
 
-static u8 *ndisc_fill_option(u8 *opt, int type, void *data, int data_len)
+/*
+ * Return the padding between the option length and the start of the
+ * link addr.  Currently only IP-over-InfiniBand needs this, although
+ * if RFC 3831 IPv6-over-Fibre Channel is ever implemented it may
+ * also need a pad of 2.
+ */
+static int ndisc_addr_option_pad(unsigned short type)
+{
+	switch (type) {
+	case ARPHRD_INFINIBAND: return 2;
+	default:                return 0;
+	}
+}
+
+static u8 *ndisc_fill_addr_option(u8 *opt, int type, void *data, int data_len,
+				  unsigned short addr_type)
 {
 	int space = NDISC_OPT_SPACE(data_len);
+	int pad   = ndisc_addr_option_pad(addr_type);
 
 	opt[0] = type;
 	opt[1] = space>>3;
+
+	memset(opt + 2, 0, pad);
+	opt   += pad;
+	space -= pad;
+
 	memcpy(opt+2, data, data_len);
 	data_len += 2;
 	opt += data_len;
@@ -260,6 +281,9 @@
 	case ARPHRD_ARCNET:
 		ipv6_arcnet_mc_map(addr, buf);
 		return 0;
+	case ARPHRD_INFINIBAND:
+		ipv6_ib_mc_map(addr, buf);
+		return 0;
 	default:
 		if (dir) {
 			memcpy(buf, dev->broadcast, dev->addr_len);
@@ -450,7 +474,8 @@
 	ipv6_addr_copy(&msg->target, solicited_addr);
 
 	if (inc_opt)
-		ndisc_fill_option(msg->opt, ND_OPT_TARGET_LL_ADDR, dev->dev_addr, dev->addr_len);
+		ndisc_fill_addr_option(msg->opt, ND_OPT_TARGET_LL_ADDR, dev->dev_addr,
+				       dev->addr_len, dev->type);
 
 	/* checksum */
 	msg->icmph.icmp6_cksum = csum_ipv6_magic(src_addr, daddr, len, 
@@ -533,7 +558,8 @@
 	ipv6_addr_copy(&msg->target, solicit);
 
 	if (send_llinfo)
-		ndisc_fill_option(msg->opt, ND_OPT_SOURCE_LL_ADDR, dev->dev_addr, dev->addr_len);
+		ndisc_fill_addr_option(msg->opt, ND_OPT_SOURCE_LL_ADDR, dev->dev_addr,
+				       dev->addr_len, dev->type);
 
 	/* checksum */
 	msg->icmph.icmp6_cksum = csum_ipv6_magic(&skb->nh.ipv6h->saddr,
@@ -607,7 +633,8 @@
 	opt = (u8*) (hdr + 1);
 
 	if (dev->addr_len)
-		ndisc_fill_option(opt, ND_OPT_SOURCE_LL_ADDR, dev->dev_addr, dev->addr_len);
+		ndisc_fill_addr_option(opt, ND_OPT_SOURCE_LL_ADDR, dev->dev_addr,
+				       dev->addr_len, dev->type);
 
 	/* checksum */
 	hdr->icmp6_cksum = csum_ipv6_magic(&skb->nh.ipv6h->saddr, daddr, len,
@@ -714,7 +741,8 @@
 	}
 
 	if (ndopts.nd_opts_src_lladdr) {
-		lladdr = (u8*)(ndopts.nd_opts_src_lladdr + 1);
+		lladdr = (u8*)(ndopts.nd_opts_src_lladdr + 1) +
+			ndisc_addr_option_pad(dev->type);
 		lladdrlen = ndopts.nd_opts_src_lladdr->nd_opt_len << 3;
 		if (lladdrlen != NDISC_OPT_SPACE(dev->addr_len)) {
 			ND_PRINTK2(KERN_WARNING
@@ -871,7 +899,8 @@
 		return;
 	}
 	if (ndopts.nd_opts_tgt_lladdr) {
-		lladdr = (u8*)(ndopts.nd_opts_tgt_lladdr + 1);
+		lladdr = (u8*)(ndopts.nd_opts_tgt_lladdr + 1) +
+			ndisc_addr_option_pad(dev->type);
 		lladdrlen = ndopts.nd_opts_tgt_lladdr->nd_opt_len << 3;
 		if (lladdrlen != NDISC_OPT_SPACE(dev->addr_len)) {
 			ND_PRINTK2(KERN_WARNING
@@ -900,6 +929,9 @@
 	if (neigh) {
 		u8 old_flags = neigh->flags;
 
+		if (neigh->nud_state & NUD_FAILED)
+			goto out;
+
 		neigh_update(neigh, lladdr,
 			     msg->icmph.icmp6_solicited ? NUD_REACHABLE : NUD_STALE,
 			     NEIGH_UPDATE_F_WEAK_OVERRIDE|
@@ -917,6 +949,7 @@
 				ip6_del_rt(rt, NULL, NULL);
 		}
 
+out:
 		neigh_release(neigh);
 	}
 }
@@ -961,7 +994,8 @@
 	}
 
 	if (ndopts.nd_opts_src_lladdr) {
-		lladdr = (u8 *)(ndopts.nd_opts_src_lladdr + 1);
+		lladdr = (u8 *)(ndopts.nd_opts_src_lladdr + 1) +
+			ndisc_addr_option_pad(skb->dev->type);
 		lladdrlen = ndopts.nd_opts_src_lladdr->nd_opt_len << 3;
 		if (lladdrlen != NDISC_OPT_SPACE(skb->dev->addr_len))
 			goto out;
@@ -982,7 +1016,7 @@
 static void ndisc_router_discovery(struct sk_buff *skb)
 {
         struct ra_msg *ra_msg = (struct ra_msg *) skb->h.raw;
-	struct neighbour *neigh;
+	struct neighbour *neigh = NULL;
 	struct inet6_dev *in6_dev;
 	struct rt6_info *rt;
 	int lifetime;
@@ -1050,7 +1084,11 @@
 
 	rt = rt6_get_dflt_router(&skb->nh.ipv6h->saddr, skb->dev);
 
+	if (rt)
+		neigh = rt->rt6i_nexthop;
+
 	if (rt && lifetime == 0) {
+		neigh_clone(neigh);
 		ip6_del_rt(rt, NULL, NULL);
 		rt = NULL;
 	}
@@ -1123,11 +1161,15 @@
 	 *	Process options.
 	 */
 
-	if (rt && (neigh = rt->rt6i_nexthop) != NULL) {
+	if (!neigh)
+		neigh = __neigh_lookup(&nd_tbl, &skb->nh.ipv6h->saddr,
+				       skb->dev, 1);
+	if (neigh) {
 		u8 *lladdr = NULL;
 		int lladdrlen;
 		if (ndopts.nd_opts_src_lladdr) {
-			lladdr = (u8*)((ndopts.nd_opts_src_lladdr)+1);
+			lladdr = (u8*)((ndopts.nd_opts_src_lladdr)+1) +
+				ndisc_addr_option_pad(skb->dev->type);
 			lladdrlen = ndopts.nd_opts_src_lladdr->nd_opt_len << 3;
 			if (lladdrlen != NDISC_OPT_SPACE(skb->dev->addr_len)) {
 				ND_PRINTK2(KERN_WARNING
@@ -1178,6 +1220,8 @@
 out:
 	if (rt)
 		dst_release(&rt->u.dst);
+	else if (neigh)
+		neigh_release(neigh);
 	in6_dev_put(in6_dev);
 }
 
@@ -1247,7 +1291,8 @@
 		return;
 	}
 	if (ndopts.nd_opts_tgt_lladdr) {
-		lladdr = (u8*)(ndopts.nd_opts_tgt_lladdr + 1);
+		lladdr = (u8*)(ndopts.nd_opts_tgt_lladdr + 1) +
+			ndisc_addr_option_pad(skb->dev->type);
 		lladdrlen = ndopts.nd_opts_tgt_lladdr->nd_opt_len << 3;
 		if (lladdrlen != NDISC_OPT_SPACE(skb->dev->addr_len)) {
 			ND_PRINTK2(KERN_WARNING
@@ -1376,7 +1421,8 @@
 	 */
 
 	if (dev->addr_len)
-		opt = ndisc_fill_option(opt, ND_OPT_TARGET_LL_ADDR, neigh->ha, dev->addr_len);
+		opt = ndisc_fill_addr_option(opt, ND_OPT_TARGET_LL_ADDR, neigh->ha,
+					     dev->addr_len, dev->type);
 
 	/*
 	 *	build redirect option and copy skb over to the new packet.
diff -Nru a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig
--- a/net/ipv6/netfilter/Kconfig	2005-03-01 23:39:09 -08:00
+++ b/net/ipv6/netfilter/Kconfig	2005-03-01 23:39:09 -08:00
@@ -237,7 +237,6 @@
 	
 	  If you want to compile it as a module, say M here and read
 	  <file:Documentation/modules.txt>.  If unsure, say `N'.
-	  help
 
 endmenu
 
diff -Nru a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c
--- a/net/ipv6/netfilter/ip6_queue.c	2005-03-01 23:38:54 -08:00
+++ b/net/ipv6/netfilter/ip6_queue.c	2005-03-01 23:38:54 -08:00
@@ -60,7 +60,7 @@
 
 static unsigned char copy_mode = IPQ_COPY_NONE;
 static unsigned int queue_maxlen = IPQ_QMAX_DEFAULT;
-static rwlock_t queue_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(queue_lock);
 static int peer_pid;
 static unsigned int copy_range;
 static unsigned int queue_total;
diff -Nru a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
--- a/net/ipv6/netfilter/ip6_tables.c	2005-03-01 23:39:10 -08:00
+++ b/net/ipv6/netfilter/ip6_tables.c	2005-03-01 23:39:10 -08:00
@@ -234,7 +234,7 @@
 			 * we will change the return 0 to 1*/
 			if ((currenthdr == IPPROTO_NONE) || 
 				(currenthdr == IPPROTO_ESP))
-				return 0;
+				break;
 
 			hp = skb_header_pointer(skb, ptr, sizeof(_hdr), &_hdr);
 			BUG_ON(hp == NULL);
@@ -366,10 +366,6 @@
 	void *table_base;
 	struct ip6t_entry *e, *back;
 
-	/* FIXME: Push down to extensions --RR */
-	if (skb_is_nonlinear(*pskb) && skb_linearize(*pskb, GFP_ATOMIC) != 0)
-		return NF_DROP;
-
 	/* Initialization */
 	indev = in ? in->name : nulldevname;
 	outdev = out ? out->name : nulldevname;
@@ -1222,11 +1218,12 @@
 	IP6T_ENTRY_ITERATE(oldinfo->entries, oldinfo->size, cleanup_entry,NULL);
 	vfree(oldinfo);
 	/* Silent error: too late now. */
-	copy_to_user(tmp.counters, counters,
-		     sizeof(struct ip6t_counters) * tmp.num_counters);
+	if (copy_to_user(tmp.counters, counters,
+			 sizeof(struct ip6t_counters) * tmp.num_counters) != 0)
+		ret = -EFAULT;
 	vfree(counters);
 	up(&ip6t_mutex);
-	return 0;
+	return ret;
 
  put_module:
 	module_put(t->me);
@@ -1372,7 +1369,7 @@
 			       sizeof(info.underflow));
 			info.num_entries = t->private->number;
 			info.size = t->private->size;
-			strcpy(info.name, name);
+			memcpy(info.name, name, sizeof(info.name));
 
 			if (copy_to_user(user, &info, *len) != 0)
 				ret = -EFAULT;
@@ -1463,7 +1460,8 @@
 	up(&ip6t_mutex);
 }
 
-int ip6t_register_table(struct ip6t_table *table)
+int ip6t_register_table(struct ip6t_table *table,
+			const struct ip6t_replace *repl)
 {
 	int ret;
 	struct ip6t_table_info *newinfo;
@@ -1471,17 +1469,17 @@
 		= { 0, 0, 0, { 0 }, { 0 }, { } };
 
 	newinfo = vmalloc(sizeof(struct ip6t_table_info)
-			  + SMP_ALIGN(table->table->size) * NR_CPUS);
+			  + SMP_ALIGN(repl->size) * NR_CPUS);
 	if (!newinfo)
 		return -ENOMEM;
 
-	memcpy(newinfo->entries, table->table->entries, table->table->size);
+	memcpy(newinfo->entries, repl->entries, repl->size);
 
 	ret = translate_table(table->name, table->valid_hooks,
-			      newinfo, table->table->size,
-			      table->table->num_entries,
-			      table->table->hook_entry,
-			      table->table->underflow);
+			      newinfo, repl->size,
+			      repl->num_entries,
+			      repl->hook_entry,
+			      repl->underflow);
 	if (ret != 0) {
 		vfree(newinfo);
 		return ret;
diff -Nru a/net/ipv6/netfilter/ip6t_LOG.c b/net/ipv6/netfilter/ip6t_LOG.c
--- a/net/ipv6/netfilter/ip6t_LOG.c	2005-03-01 23:38:54 -08:00
+++ b/net/ipv6/netfilter/ip6t_LOG.c	2005-03-01 23:38:54 -08:00
@@ -41,7 +41,7 @@
 #endif
 
 /* Use lock to serialize, so printks don't overlap */
-static spinlock_t log_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(log_lock);
 
 /* One level of recursion won't kill us */
 static void dump_packet(const struct ip6t_log_info *info,
@@ -346,6 +346,14 @@
 	/* Max length: 10 "PROTO=255 " */
 	default:
 		printk("PROTO=%u ", currenthdr);
+	}
+
+	/* Max length: 15 "UID=4294967295 " */
+	if ((info->logflags & IP6T_LOG_UID) && recurse && skb->sk) {
+		read_lock_bh(&skb->sk->sk_callback_lock);
+		if (skb->sk->sk_socket && skb->sk->sk_socket->file)
+			printk("UID=%u ", skb->sk->sk_socket->file->f_uid);
+		read_unlock_bh(&skb->sk->sk_callback_lock);
 	}
 }
 
diff -Nru a/net/ipv6/netfilter/ip6t_limit.c b/net/ipv6/netfilter/ip6t_limit.c
--- a/net/ipv6/netfilter/ip6t_limit.c	2005-03-01 23:38:54 -08:00
+++ b/net/ipv6/netfilter/ip6t_limit.c	2005-03-01 23:38:54 -08:00
@@ -29,7 +29,7 @@
  * see net/sched/sch_tbf.c in the linux source tree
  */
 
-static spinlock_t limit_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(limit_lock);
 
 /* Rusty: This is my (non-mathematically-inclined) understanding of
    this algorithm.  The `average rate' in jiffies becomes your initial
diff -Nru a/net/ipv6/netfilter/ip6table_filter.c b/net/ipv6/netfilter/ip6table_filter.c
--- a/net/ipv6/netfilter/ip6table_filter.c	2005-03-01 23:38:52 -08:00
+++ b/net/ipv6/netfilter/ip6table_filter.c	2005-03-01 23:38:52 -08:00
@@ -94,7 +94,6 @@
 
 static struct ip6t_table packet_filter = {
 	.name		= "filter",
-	.table		= &initial_table.repl,
 	.valid_hooks	= FILTER_VALID_HOOKS,
 	.lock		= RW_LOCK_UNLOCKED,
 	.me		= THIS_MODULE,
@@ -172,7 +171,7 @@
 	initial_table.entries[1].target.verdict = -forward - 1;
 
 	/* Register table */
-	ret = ip6t_register_table(&packet_filter);
+	ret = ip6t_register_table(&packet_filter, &initial_table.repl);
 	if (ret < 0)
 		return ret;
 
diff -Nru a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c
--- a/net/ipv6/netfilter/ip6table_mangle.c	2005-03-01 23:38:55 -08:00
+++ b/net/ipv6/netfilter/ip6table_mangle.c	2005-03-01 23:38:55 -08:00
@@ -124,7 +124,6 @@
 
 static struct ip6t_table packet_mangler = {
 	.name		= "mangle",
-	.table		= &initial_table.repl,
 	.valid_hooks	= MANGLE_VALID_HOOKS,
 	.lock		= RW_LOCK_UNLOCKED,
 	.me		= THIS_MODULE,
@@ -165,10 +164,6 @@
 	}
 #endif
 
-	/* FIXME: Push down to extensions --RR */
-	if (skb_is_nonlinear(*pskb) && skb_linearize(*pskb, GFP_ATOMIC) != 0)
-		return NF_DROP;
-
 	/* save source/dest address, nfmark, hoplimit, flowlabel, priority,  */
 	memcpy(&saddr, &(*pskb)->nh.ipv6h->saddr, sizeof(saddr));
 	memcpy(&daddr, &(*pskb)->nh.ipv6h->daddr, sizeof(daddr));
@@ -237,7 +232,7 @@
 	int ret;
 
 	/* Register table */
-	ret = ip6t_register_table(&packet_mangler);
+	ret = ip6t_register_table(&packet_mangler, &initial_table.repl);
 	if (ret < 0)
 		return ret;
 
diff -Nru a/net/ipv6/netfilter/ip6table_raw.c b/net/ipv6/netfilter/ip6table_raw.c
--- a/net/ipv6/netfilter/ip6table_raw.c	2005-03-01 23:39:08 -08:00
+++ b/net/ipv6/netfilter/ip6table_raw.c	2005-03-01 23:39:08 -08:00
@@ -108,7 +108,6 @@
 
 static struct ip6t_table packet_raw = { 
 	.name = "raw", 
-	.table = &initial_table.repl,
 	.valid_hooks = RAW_VALID_HOOKS, 
 	.lock = RW_LOCK_UNLOCKED, 
 	.me = THIS_MODULE
@@ -145,7 +144,7 @@
 	int ret;
 
 	/* Register table */
-	ret = ip6t_register_table(&packet_raw);
+	ret = ip6t_register_table(&packet_raw, &initial_table.repl);
 	if (ret < 0)
 		return ret;
 
diff -Nru a/net/ipv6/proc.c b/net/ipv6/proc.c
--- a/net/ipv6/proc.c	2005-03-01 23:38:56 -08:00
+++ b/net/ipv6/proc.c	2005-03-01 23:38:56 -08:00
@@ -201,33 +201,23 @@
 
 int snmp6_register_dev(struct inet6_dev *idev)
 {
-	int err = -ENOMEM;
 	struct proc_dir_entry *p;
 
 	if (!idev || !idev->dev)
 		return -EINVAL;
 
-	if (snmp6_mib_init((void **)idev->stats.icmpv6, sizeof(struct icmpv6_mib),
-			   __alignof__(struct icmpv6_mib)) < 0)
-		goto err_icmp;
+	if (!proc_net_devsnmp6)
+		return -ENOENT;
 
-	if (!proc_net_devsnmp6) {
-		err = -ENOENT;
-		goto err_proc;
-	}
 	p = create_proc_entry(idev->dev->name, S_IRUGO, proc_net_devsnmp6);
 	if (!p)
-		goto err_proc;
+		return -ENOMEM;
+
 	p->data = idev;
 	p->proc_fops = &snmp6_seq_fops;
 
 	idev->stats.proc_dir_entry = p;
 	return 0;
-
-err_proc:
-	snmp6_mib_free((void **)idev->stats.icmpv6);
-err_icmp:
-	return err;
 }
 
 int snmp6_unregister_dev(struct inet6_dev *idev)
@@ -238,8 +228,6 @@
 		return -EINVAL;
 	remove_proc_entry(idev->stats.proc_dir_entry->name,
 			  proc_net_devsnmp6);
-	snmp6_mib_free((void **)idev->stats.icmpv6);
-
 	return 0;
 }
 
@@ -280,6 +268,17 @@
 
 int snmp6_register_dev(struct inet6_dev *idev)
 {
+	return 0;
+}
+
+int snmp6_unregister_dev(struct inet6_dev *idev)
+{
+	return 0;
+}
+#endif	/* CONFIG_PROC_FS */
+
+int snmp6_alloc_dev(struct inet6_dev *idev)
+{
 	int err = -ENOMEM;
 
 	if (!idev || !idev->dev)
@@ -295,11 +294,10 @@
 	return err;
 }
 
-int snmp6_unregister_dev(struct inet6_dev *idev)
+int snmp6_free_dev(struct inet6_dev *idev)
 {
 	snmp6_mib_free((void **)idev->stats.icmpv6);
 	return 0;
 }
 
-#endif
 
diff -Nru a/net/ipv6/protocol.c b/net/ipv6/protocol.c
--- a/net/ipv6/protocol.c	2005-03-01 23:38:53 -08:00
+++ b/net/ipv6/protocol.c	2005-03-01 23:38:53 -08:00
@@ -40,7 +40,7 @@
 #include <net/protocol.h>
 
 struct inet6_protocol *inet6_protos[MAX_INET_PROTOS];
-static spinlock_t inet6_proto_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(inet6_proto_lock);
 
 
 int inet6_add_protocol(struct inet6_protocol *prot, unsigned char protocol)
diff -Nru a/net/ipv6/raw.c b/net/ipv6/raw.c
--- a/net/ipv6/raw.c	2005-03-01 23:38:55 -08:00
+++ b/net/ipv6/raw.c	2005-03-01 23:38:55 -08:00
@@ -56,7 +56,7 @@
 #include <linux/seq_file.h>
 
 struct hlist_head raw_v6_htable[RAWV6_HTABLE_SIZE];
-rwlock_t raw_v6_lock = RW_LOCK_UNLOCKED;
+DEFINE_RWLOCK(raw_v6_lock);
 
 static void raw_v6_hash(struct sock *sk)
 {
@@ -115,10 +115,10 @@
 static __inline__ int icmpv6_filter(struct sock *sk, struct sk_buff *skb)
 {
 	struct icmp6hdr *icmph;
-	struct raw6_opt *opt = raw6_sk(sk);
+	struct raw6_sock *rp = raw6_sk(sk);
 
 	if (pskb_may_pull(skb, sizeof(struct icmp6hdr))) {
-		__u32 *data = &opt->filter.data[0];
+		__u32 *data = &rp->filter.data[0];
 		int bit_nr;
 
 		icmph = (struct icmp6hdr *) skb->data;
@@ -178,7 +178,7 @@
 /* This cleans up af_inet6 a bit. -DaveM */
 static int rawv6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
 {
-	struct inet_opt *inet = inet_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
 	struct ipv6_pinfo *np = inet6_sk(sk);
 	struct sockaddr_in6 *addr = (struct sockaddr_in6 *) uaddr;
 	__u32 v4addr = 0;
@@ -253,7 +253,7 @@
 	       struct inet6_skb_parm *opt,
 	       int type, int code, int offset, u32 info)
 {
-	struct inet_opt *inet = inet_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
 	struct ipv6_pinfo *np = inet6_sk(sk);
 	int err;
 	int harderr;
@@ -314,15 +314,15 @@
  */
 int rawv6_rcv(struct sock *sk, struct sk_buff *skb)
 {
-	struct inet_opt *inet = inet_sk(sk);
-	struct raw6_opt *raw_opt = raw6_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
+	struct raw6_sock *rp = raw6_sk(sk);
 
         if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb)) {
                 kfree_skb(skb);
                 return NET_RX_DROP;
         }
 
-	if (!raw_opt->checksum)
+	if (!rp->checksum)
 		skb->ip_summed = CHECKSUM_UNNECESSARY;
 
 	if (skb->ip_summed != CHECKSUM_UNNECESSARY) {
@@ -451,21 +451,22 @@
 	goto out_free;
 }
 
-static int rawv6_push_pending_frames(struct sock *sk, struct flowi *fl, struct raw6_opt *opt, int len)
+static int rawv6_push_pending_frames(struct sock *sk, struct flowi *fl,
+				     struct raw6_sock *rp, int len)
 {
 	struct sk_buff *skb;
 	int err = 0;
 	u16 *csum;
 	u32 tmp_csum;
 
-	if (!opt->checksum)
+	if (!rp->checksum)
 		goto send;
 
 	if ((skb = skb_peek(&sk->sk_write_queue)) == NULL)
 		goto out;
 
-	if (opt->offset + 1 < len)
-		csum = (u16 *)(skb->h.raw + opt->offset);
+	if (rp->offset + 1 < len)
+		csum = (u16 *)(skb->h.raw + rp->offset);
 	else {
 		err = -EINVAL;
 		goto out;
@@ -505,7 +506,7 @@
 			struct flowi *fl, struct rt6_info *rt, 
 			unsigned int flags)
 {
-	struct inet_opt *inet = inet_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
 	struct ipv6hdr *iph;
 	struct sk_buff *skb;
 	unsigned int hh_len;
@@ -607,9 +608,9 @@
 	struct ipv6_txoptions opt_space;
 	struct sockaddr_in6 * sin6 = (struct sockaddr_in6 *) msg->msg_name;
 	struct in6_addr *daddr, *final_p = NULL, final;
-	struct inet_opt *inet = inet_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
 	struct ipv6_pinfo *np = inet6_sk(sk);
-	struct raw6_opt *raw_opt = raw6_sk(sk);
+	struct raw6_sock *rp = raw6_sk(sk);
 	struct ipv6_txoptions *opt = NULL;
 	struct ip6_flowlabel *flowlabel = NULL;
 	struct dst_entry *dst = NULL;
@@ -771,7 +772,7 @@
 		if (err)
 			ip6_flush_pending_frames(sk);
 		else if (!(msg->msg_flags & MSG_MORE))
-			err = rawv6_push_pending_frames(sk, &fl, raw_opt, len);
+			err = rawv6_push_pending_frames(sk, &fl, rp, len);
 	}
 done:
 	ip6_dst_store(sk, dst,
@@ -838,7 +839,7 @@
 static int rawv6_setsockopt(struct sock *sk, int level, int optname, 
 			    char __user *optval, int optlen)
 {
-	struct raw6_opt *opt = raw6_sk(sk);
+	struct raw6_sock *rp = raw6_sk(sk);
 	int val;
 
 	switch(level) {
@@ -868,10 +869,10 @@
 			if (val > 0 && (val&1))
 				return(-EINVAL);
 			if (val < 0) {
-				opt->checksum = 0;
+				rp->checksum = 0;
 			} else {
-				opt->checksum = 1;
-				opt->offset = val;
+				rp->checksum = 1;
+				rp->offset = val;
 			}
 
 			return 0;
@@ -885,7 +886,7 @@
 static int rawv6_getsockopt(struct sock *sk, int level, int optname, 
 			    char __user *optval, int __user *optlen)
 {
-	struct raw6_opt *opt = raw6_sk(sk);
+	struct raw6_sock *rp = raw6_sk(sk);
 	int val, len;
 
 	switch(level) {
@@ -910,10 +911,10 @@
 
 	switch (optname) {
 	case IPV6_CHECKSUM:
-		if (opt->checksum == 0)
+		if (rp->checksum == 0)
 			val = -1;
 		else
-			val = opt->offset;
+			val = rp->offset;
 		break;
 
 	default:
@@ -966,9 +967,9 @@
 static int rawv6_init_sk(struct sock *sk)
 {
 	if (inet_sk(sk)->num == IPPROTO_ICMPV6) {
-		struct raw6_opt *opt = raw6_sk(sk);
-		opt->checksum = 1;
-		opt->offset = 2;
+		struct raw6_sock *rp = raw6_sk(sk);
+		rp->checksum = 1;
+		rp->offset   = 2;
 	}
 	return(0);
 }
diff -Nru a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
--- a/net/ipv6/reassembly.c	2005-03-01 23:38:54 -08:00
+++ b/net/ipv6/reassembly.c	2005-03-01 23:38:54 -08:00
@@ -103,7 +103,7 @@
 #define IP6Q_HASHSZ	64
 
 static struct frag_queue *ip6_frag_hash[IP6Q_HASHSZ];
-static rwlock_t ip6_frag_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(ip6_frag_lock);
 static u32 ip6_frag_hash_rnd;
 static LIST_HEAD(ip6_frag_lru_list);
 int ip6_frag_nqueues = 0;
diff -Nru a/net/ipv6/route.c b/net/ipv6/route.c
--- a/net/ipv6/route.c	2005-03-01 23:39:08 -08:00
+++ b/net/ipv6/route.c	2005-03-01 23:39:08 -08:00
@@ -84,7 +84,8 @@
 static struct dst_entry	*ip6_dst_check(struct dst_entry *dst, u32 cookie);
 static struct dst_entry *ip6_negative_advice(struct dst_entry *);
 static void		ip6_dst_destroy(struct dst_entry *);
-static void		ip6_dst_ifdown(struct dst_entry *, int how);
+static void		ip6_dst_ifdown(struct dst_entry *,
+				       struct net_device *dev, int how);
 static int		 ip6_dst_gc(void);
 
 static int		ip6_pkt_discard(struct sk_buff *skb);
@@ -133,7 +134,7 @@
 
 /* Protects all the ip6 fib */
 
-rwlock_t rt6_lock = RW_LOCK_UNLOCKED;
+DEFINE_RWLOCK(rt6_lock);
 
 
 /* allocate dst with ip6_dst_ops */
@@ -153,12 +154,13 @@
 	}	
 }
 
-static void ip6_dst_ifdown(struct dst_entry *dst, int how)
+static void ip6_dst_ifdown(struct dst_entry *dst, struct net_device *dev,
+			   int how)
 {
 	struct rt6_info *rt = (struct rt6_info *)dst;
 	struct inet6_dev *idev = rt->rt6i_idev;
 
-	if (idev != NULL && idev->dev != &loopback_dev) {
+	if (dev != &loopback_dev && idev != NULL && idev->dev == dev) {
 		struct inet6_dev *loopback_idev = in6_dev_get(&loopback_dev);
 		if (loopback_idev != NULL) {
 			rt->rt6i_idev = loopback_idev;
@@ -167,6 +169,12 @@
 	}
 }
 
+static __inline__ int rt6_check_expired(const struct rt6_info *rt)
+{
+	return (rt->rt6i_flags & RTF_EXPIRES &&
+		time_after(jiffies, rt->rt6i_expires));
+}
+
 /*
  *	Route lookup. Any rt6_lock is implied.
  */
@@ -208,8 +216,8 @@
 /*
  *	pointer to the last default router chosen. BH is disabled locally.
  */
-struct rt6_info *rt6_dflt_pointer;
-spinlock_t rt6_dflt_lock = SPIN_LOCK_UNLOCKED;
+static struct rt6_info *rt6_dflt_pointer;
+static DEFINE_SPINLOCK(rt6_dflt_lock);
 
 void rt6_reset_dflt_pointer(struct rt6_info *rt)
 {
@@ -237,8 +245,7 @@
 		     sprt->rt6i_dev->ifindex == oif))
 			m += 8;
 
-		if ((sprt->rt6i_flags & RTF_EXPIRES) &&
-		    time_after(jiffies, sprt->rt6i_expires))
+		if (rt6_check_expired(sprt))
 			continue;
 
 		if (sprt == rt6_dflt_pointer)
@@ -296,7 +303,8 @@
 			for (sprt = rt6_dflt_pointer->u.next;
 			     sprt; sprt = sprt->u.next) {
 				if (sprt->u.dst.obsolete <= 0 &&
-				    sprt->u.dst.error == 0) {
+				    sprt->u.dst.error == 0 &&
+				    !rt6_check_expired(sprt)) {
 					match = sprt;
 					break;
 				}
@@ -305,7 +313,8 @@
 			     !match && sprt;
 			     sprt = sprt->u.next) {
 				if (sprt->u.dst.obsolete <= 0 &&
-				    sprt->u.dst.error == 0) {
+				    sprt->u.dst.error == 0 &&
+				    !rt6_check_expired(sprt)) {
 					match = sprt;
 					break;
 				}
@@ -331,7 +340,8 @@
 		 */
 		for (sprt = ip6_routing_table.leaf;
 		     sprt; sprt = sprt->u.next) {
-			if ((sprt->rt6i_flags & RTF_DEFAULT) &&
+			if (!rt6_check_expired(sprt) &&
+			    (sprt->rt6i_flags & RTF_DEFAULT) &&
 			    (!oif ||
 			     (sprt->rt6i_dev &&
 			      sprt->rt6i_dev->ifindex == oif))) {
diff -Nru a/net/ipv6/sit.c b/net/ipv6/sit.c
--- a/net/ipv6/sit.c	2005-03-01 23:39:16 -08:00
+++ b/net/ipv6/sit.c	2005-03-01 23:39:16 -08:00
@@ -73,7 +73,7 @@
 static struct ip_tunnel *tunnels_wc[1];
 static struct ip_tunnel **tunnels[4] = { tunnels_wc, tunnels_l, tunnels_r, tunnels_r_l };
 
-static rwlock_t ipip6_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(ipip6_lock);
 
 static struct ip_tunnel * ipip6_tunnel_lookup(u32 remote, u32 local)
 {
@@ -135,10 +135,10 @@
 {
 	struct ip_tunnel **tp = ipip6_bucket(t);
 
-	write_lock_bh(&ipip6_lock);
 	t->next = *tp;
-	write_unlock_bh(&ipip6_lock);
+	write_lock_bh(&ipip6_lock);
 	*tp = t;
+	write_unlock_bh(&ipip6_lock);
 }
 
 static struct ip_tunnel * ipip6_tunnel_locate(struct ip_tunnel_parm *parms, int create)
diff -Nru a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c
--- a/net/ipv6/sysctl_net_ipv6.c	2005-03-01 23:38:52 -08:00
+++ b/net/ipv6/sysctl_net_ipv6.c	2005-03-01 23:38:52 -08:00
@@ -19,7 +19,7 @@
 
 #ifdef CONFIG_SYSCTL
 
-ctl_table ipv6_table[] = {
+static ctl_table ipv6_table[] = {
 	{
 		.ctl_name	= NET_IPV6_ROUTE,
 		.procname	= "route",
diff -Nru a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
--- a/net/ipv6/tcp_ipv6.c	2005-03-01 23:38:58 -08:00
+++ b/net/ipv6/tcp_ipv6.c	2005-03-01 23:38:58 -08:00
@@ -89,7 +89,7 @@
 
 static __inline__ int tcp_v6_sk_hashfn(struct sock *sk)
 {
-	struct inet_opt *inet = inet_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
 	struct ipv6_pinfo *np = inet6_sk(sk);
 	struct in6_addr *laddr = &np->rcv_saddr;
 	struct in6_addr *faddr = &np->daddr;
@@ -235,7 +235,7 @@
 static void tcp_v6_hash(struct sock *sk)
 {
 	if (sk->sk_state != TCP_CLOSE) {
-		struct tcp_opt *tp = tcp_sk(sk);
+		struct tcp_sock *tp = tcp_sk(sk);
 
 		if (tp->af_specific == &ipv6_mapped) {
 			tcp_prot.hash(sk);
@@ -391,7 +391,7 @@
 	return c & (TCP_SYNQ_HSIZE - 1);
 }
 
-static struct open_request *tcp_v6_search_req(struct tcp_opt *tp,
+static struct open_request *tcp_v6_search_req(struct tcp_sock *tp,
 					      struct open_request ***prevp,
 					      __u16 rport,
 					      struct in6_addr *raddr,
@@ -443,7 +443,7 @@
 
 static int tcp_v6_check_established(struct sock *sk)
 {
-	struct inet_opt *inet = inet_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
 	struct ipv6_pinfo *np = inet6_sk(sk);
 	struct in6_addr *daddr = &np->rcv_saddr;
 	struct in6_addr *saddr = &np->daddr;
@@ -466,15 +466,15 @@
 		   ipv6_addr_equal(&tw->tw_v6_daddr, saddr)	&&
 		   ipv6_addr_equal(&tw->tw_v6_rcv_saddr, daddr)	&&
 		   sk2->sk_bound_dev_if == sk->sk_bound_dev_if) {
-			struct tcp_opt *tp = tcp_sk(sk);
+			struct tcp_sock *tp = tcp_sk(sk);
 
 			if (tw->tw_ts_recent_stamp) {
 				/* See comment in tcp_ipv4.c */
 				tp->write_seq = tw->tw_snd_nxt + 65535 + 2;
 				if (!tp->write_seq)
 					tp->write_seq = 1;
-				tp->ts_recent = tw->tw_ts_recent;
-				tp->ts_recent_stamp = tw->tw_ts_recent_stamp;
+				tp->rx_opt.ts_recent = tw->tw_ts_recent;
+				tp->rx_opt.ts_recent_stamp = tw->tw_ts_recent_stamp;
 				sock_hold(sk2);
 				goto unique;
 			} else
@@ -549,9 +549,9 @@
 			  int addr_len)
 {
 	struct sockaddr_in6 *usin = (struct sockaddr_in6 *) uaddr;
-	struct inet_opt *inet = inet_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
 	struct ipv6_pinfo *np = inet6_sk(sk);
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	struct in6_addr *saddr = NULL, *final_p = NULL, final;
 	struct flowi fl;
 	struct dst_entry *dst;
@@ -609,10 +609,10 @@
 			return -EINVAL;
 	}
 
-	if (tp->ts_recent_stamp &&
+	if (tp->rx_opt.ts_recent_stamp &&
 	    !ipv6_addr_equal(&np->daddr, &usin->sin6_addr)) {
-		tp->ts_recent = 0;
-		tp->ts_recent_stamp = 0;
+		tp->rx_opt.ts_recent = 0;
+		tp->rx_opt.ts_recent_stamp = 0;
 		tp->write_seq = 0;
 	}
 
@@ -703,7 +703,7 @@
 		tp->ext_header_len = np->opt->opt_flen + np->opt->opt_nflen;
 	tp->ext2_header_len = dst->header_len;
 
-	tp->mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr);
+	tp->rx_opt.mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr);
 
 	inet->dport = usin->sin6_port;
 
@@ -741,7 +741,7 @@
 	struct ipv6_pinfo *np;
 	struct sock *sk;
 	int err;
-	struct tcp_opt *tp; 
+	struct tcp_sock *tp; 
 	__u32 seq;
 
 	sk = tcp_v6_lookup(&hdr->daddr, th->dest, &hdr->saddr, th->source, skb->dev->ifindex);
@@ -785,7 +785,7 @@
 		dst = __sk_dst_check(sk, np->dst_cookie);
 
 		if (dst == NULL) {
-			struct inet_opt *inet = inet_sk(sk);
+			struct inet_sock *inet = inet_sk(sk);
 			struct flowi fl;
 
 			/* BUGGG_FUTURE: Again, it is not clear how
@@ -1146,7 +1146,7 @@
 {
 	struct open_request *req, **prev;
 	struct tcphdr *th = skb->h.th;
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 	struct sock *nsk;
 
 	/* Find possible connection requests. */
@@ -1179,7 +1179,7 @@
 
 static void tcp_v6_synq_add(struct sock *sk, struct open_request *req)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	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);
 
@@ -1202,7 +1202,8 @@
 static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
 {
 	struct ipv6_pinfo *np = inet6_sk(sk);
-	struct tcp_opt tmptp, *tp = tcp_sk(sk);
+	struct tcp_options_received tmp_opt;
+	struct tcp_sock *tp = tcp_sk(sk);
 	struct open_request *req = NULL;
 	__u32 isn = TCP_SKB_CB(skb)->when;
 
@@ -1228,14 +1229,14 @@
 	if (req == NULL)
 		goto drop;
 
-	tcp_clear_options(&tmptp);
-	tmptp.mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr);
-	tmptp.user_mss = tp->user_mss;
+	tcp_clear_options(&tmp_opt);
+	tmp_opt.mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr);
+	tmp_opt.user_mss = tp->rx_opt.user_mss;
 
-	tcp_parse_options(skb, &tmptp, 0);
+	tcp_parse_options(skb, &tmp_opt, 0);
 
-	tmptp.tstamp_ok = tmptp.saw_tstamp;
-	tcp_openreq_init(req, &tmptp, skb);
+	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);
@@ -1281,8 +1282,8 @@
 {
 	struct ipv6_pinfo *newnp, *np = inet6_sk(sk);
 	struct tcp6_sock *newtcp6sk;
-	struct inet_opt *newinet;
-	struct tcp_opt *newtp;
+	struct inet_sock *newinet;
+	struct tcp_sock *newtp;
 	struct sock *newsk;
 	struct ipv6_txoptions *opt;
 
@@ -1297,7 +1298,7 @@
 			return NULL;
 
 		newtcp6sk = (struct tcp6_sock *)newsk;
-		newtcp6sk->pinet6 = &newtcp6sk->inet6;
+		inet_sk(newsk)->pinet6 = &newtcp6sk->inet6;
 
 		newinet = inet_sk(newsk);
 		newnp = inet6_sk(newsk);
@@ -1390,7 +1391,7 @@
 		~(NETIF_F_IP_CSUM | NETIF_F_TSO);
 
 	newtcp6sk = (struct tcp6_sock *)newsk;
-	newtcp6sk->pinet6 = &newtcp6sk->inet6;
+	inet_sk(newsk)->pinet6 = &newtcp6sk->inet6;
 
 	newtp = tcp_sk(newsk);
 	newinet = inet_sk(newsk);
@@ -1497,7 +1498,7 @@
 static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
 {
 	struct ipv6_pinfo *np = inet6_sk(sk);
-	struct tcp_opt *tp;
+	struct tcp_sock *tp;
 	struct sk_buff *opt_skb = NULL;
 
 	/* Imagine: socket is IPv6. IPv4 packet arrives,
@@ -1754,7 +1755,7 @@
 	dst = __sk_dst_check(sk, np->dst_cookie);
 
 	if (dst == NULL) {
-		struct inet_opt *inet = inet_sk(sk);
+		struct inet_sock *inet = inet_sk(sk);
 		struct in6_addr *final_p = NULL, final;
 		struct flowi fl;
 
@@ -1800,7 +1801,7 @@
 static int tcp_v6_xmit(struct sk_buff *skb, int ipfragok)
 {
 	struct sock *sk = skb->sk;
-	struct inet_opt *inet = inet_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
 	struct ipv6_pinfo *np = inet6_sk(sk);
 	struct flowi fl;
 	struct dst_entry *dst;
@@ -1919,7 +1920,7 @@
  */
 static int tcp_v6_init_sock(struct sock *sk)
 {
-	struct tcp_opt *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 
 	skb_queue_head_init(&tp->out_of_order_queue);
 	tcp_init_xmit_timers(sk);
@@ -2006,8 +2007,8 @@
 	__u16 destp, srcp;
 	int timer_active;
 	unsigned long timer_expires;
-	struct inet_opt *inet = inet_sk(sp);
-	struct tcp_opt *tp = tcp_sk(sp);
+	struct inet_sock *inet = inet_sk(sp);
+	struct tcp_sock *tp = tcp_sk(sp);
 	struct ipv6_pinfo *np = inet6_sk(sp);
 
 	dest  = &np->daddr;
diff -Nru a/net/ipv6/udp.c b/net/ipv6/udp.c
--- a/net/ipv6/udp.c	2005-03-01 23:39:09 -08:00
+++ b/net/ipv6/udp.c	2005-03-01 23:39:09 -08:00
@@ -160,7 +160,7 @@
 
  	read_lock(&udp_hash_lock);
 	sk_for_each(sk, node, &udp_hash[hnum & (UDP_HTABLE_SIZE - 1)]) {
-		struct inet_opt *inet = inet_sk(sk);
+		struct inet_sock *inet = inet_sk(sk);
 
 		if (inet->num == hnum && sk->sk_family == PF_INET6) {
 			struct ipv6_pinfo *np = inet6_sk(sk);
@@ -219,6 +219,7 @@
 		  int noblock, int flags, int *addr_len)
 {
 	struct ipv6_pinfo *np = inet6_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
   	struct sk_buff *skb;
 	size_t copied;
   	int err;
@@ -268,21 +269,22 @@
 		sin6->sin6_flowinfo = 0;
 		sin6->sin6_scope_id = 0;
 
-		if (skb->protocol == htons(ETH_P_IP)) {
-			struct inet_opt *inet = inet_sk(sk);
-
+		if (skb->protocol == htons(ETH_P_IP))
 			ipv6_addr_set(&sin6->sin6_addr, 0, 0,
 				      htonl(0xffff), skb->nh.iph->saddr);
-			if (inet->cmsg_flags)
-				ip_cmsg_recv(msg, skb);
-		} else {
+		else {
 			ipv6_addr_copy(&sin6->sin6_addr, &skb->nh.ipv6h->saddr);
-
-			if (np->rxopt.all)
-				datagram_recv_ctl(sk, msg, skb);
 			if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL)
 				sin6->sin6_scope_id = IP6CB(skb)->iif;
 		}
+
+	}
+	if (skb->protocol == htons(ETH_P_IP)) {
+		if (inet->cmsg_flags)
+			ip_cmsg_recv(msg, skb);
+	} else {
+		if (np->rxopt.all)
+			datagram_recv_ctl(sk, msg, skb);
   	}
 
 	err = copied;
@@ -386,7 +388,7 @@
 	unsigned short num = ntohs(loc_port);
 
 	sk_for_each_from(s, node) {
-		struct inet_opt *inet = inet_sk(s);
+		struct inet_sock *inet = inet_sk(s);
 
 		if (inet->num == num && s->sk_family == PF_INET6) {
 			struct ipv6_pinfo *np = inet6_sk(s);
@@ -549,7 +551,7 @@
  */
 static void udp_v6_flush_pending_frames(struct sock *sk)
 {
-	struct udp_opt *up = udp_sk(sk);
+	struct udp_sock *up = udp_sk(sk);
 
 	if (up->pending) {
 		up->len = 0;
@@ -562,11 +564,11 @@
  *	Sending
  */
 
-static int udp_v6_push_pending_frames(struct sock *sk, struct udp_opt *up)
+static int udp_v6_push_pending_frames(struct sock *sk, struct udp_sock *up)
 {
 	struct sk_buff *skb;
 	struct udphdr *uh;
-	struct inet_opt *inet = inet_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
 	struct flowi *fl = &inet->cork.fl;
 	int err = 0;
 
@@ -623,8 +625,8 @@
 		  struct msghdr *msg, size_t len)
 {
 	struct ipv6_txoptions opt_space;
-	struct udp_opt *up = udp_sk(sk);
-	struct inet_opt *inet = inet_sk(sk);
+	struct udp_sock *up = udp_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
 	struct ipv6_pinfo *np = inet6_sk(sk);
 	struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) msg->msg_name;
 	struct in6_addr *daddr, *final_p = NULL, final;
@@ -878,7 +880,7 @@
 static int udpv6_setsockopt(struct sock *sk, int level, int optname, 
 			  char __user *optval, int optlen)
 {
-	struct udp_opt *up = udp_sk(sk);
+	struct udp_sock *up = udp_sk(sk);
 	int val;
 	int err = 0;
 
@@ -925,7 +927,7 @@
 static int udpv6_getsockopt(struct sock *sk, int level, int optname, 
 			  char __user *optval, int __user *optlen)
 {
-	struct udp_opt *up = udp_sk(sk);
+	struct udp_sock *up = udp_sk(sk);
 	int val, len;
 
 	if (level != SOL_UDP)
@@ -970,7 +972,7 @@
 
 static void udp6_sock_seq_show(struct seq_file *seq, struct sock *sp, int bucket)
 {
-	struct inet_opt *inet = inet_sk(sp);
+	struct inet_sock *inet = inet_sk(sp);
 	struct ipv6_pinfo *np = inet6_sk(sp);
 	struct in6_addr *dest, *src;
 	__u16 destp, srcp;
diff -Nru a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c
--- a/net/ipv6/xfrm6_tunnel.c	2005-03-01 23:39:08 -08:00
+++ b/net/ipv6/xfrm6_tunnel.c	2005-03-01 23:39:08 -08:00
@@ -72,7 +72,7 @@
 # define XFRM6_TUNNEL_SPI_MAGIC 0xdeadbeef
 #endif
 
-static rwlock_t xfrm6_tunnel_spi_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(xfrm6_tunnel_spi_lock);
 
 static u32 xfrm6_tunnel_spi;
 
diff -Nru a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c
--- a/net/ipx/af_ipx.c	2005-03-01 23:38:53 -08:00
+++ b/net/ipx/af_ipx.c	2005-03-01 23:38:53 -08:00
@@ -78,7 +78,9 @@
 static struct proto_ops ipx_dgram_ops;
 
 LIST_HEAD(ipx_interfaces);
-spinlock_t ipx_interfaces_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(ipx_interfaces_lock);
+
+static kmem_cache_t *ipx_sk_slab;
 
 struct ipx_interface *ipx_primary_net;
 struct ipx_interface *ipx_internal_net;
@@ -277,7 +279,7 @@
 	spin_lock_bh(&intrfc->if_sklist_lock);
 
 	sk_for_each(s, node, &intrfc->if_sklist) {
-		struct ipx_opt *ipxs = ipx_sk(s);
+		struct ipx_sock *ipxs = ipx_sk(s);
 
 		if (ipxs->port == port &&
 		    !memcmp(ipx_node, ipxs->node, IPX_NODE_LEN))
@@ -291,7 +293,7 @@
 }
 #endif
 
-void __ipxitf_down(struct ipx_interface *intrfc)
+static void __ipxitf_down(struct ipx_interface *intrfc)
 {
 	struct sock *s;
 	struct hlist_node *node, *t;
@@ -302,7 +304,7 @@
 	spin_lock_bh(&intrfc->if_sklist_lock);
 	/* error sockets */
 	sk_for_each_safe(s, node, t, &intrfc->if_sklist) {
-		struct ipx_opt *ipxs = ipx_sk(s);
+		struct ipx_sock *ipxs = ipx_sk(s);
 
 		s->sk_err = ENOLINK;
 		s->sk_error_report(s);
@@ -335,6 +337,12 @@
 	spin_unlock_bh(&ipx_interfaces_lock);
 }
 
+static __inline__ void __ipxitf_put(struct ipx_interface *intrfc)
+{
+	if (atomic_dec_and_test(&intrfc->refcnt))
+		__ipxitf_down(intrfc);
+}
+
 static int ipxitf_device_event(struct notifier_block *notifier,
 				unsigned long event, void *ptr)
 {
@@ -394,7 +402,7 @@
 	spin_lock_bh(&intrfc->if_sklist_lock);
 
 	sk_for_each(s, node, &intrfc->if_sklist) {
-		struct ipx_opt *ipxs = ipx_sk(s);
+		struct ipx_sock *ipxs = ipx_sk(s);
 
 		if (ipxs->port == ipx->ipx_dest.sock &&
 		    (is_broadcast || !memcmp(ipx->ipx_dest.node,
@@ -1342,32 +1350,21 @@
 static int ipx_create(struct socket *sock, int protocol)
 {
 	int rc = -ESOCKTNOSUPPORT;
-	struct ipx_opt *ipx = NULL;
 	struct sock *sk;
 
-	switch (sock->type) {
-	case SOCK_DGRAM:
-		sk = sk_alloc(PF_IPX, GFP_KERNEL, 1, NULL);
-        	rc = -ENOMEM;
-		if (!sk)
-			goto out;
-		ipx = sk->sk_protinfo = kmalloc(sizeof(*ipx), GFP_KERNEL);
-		if (!ipx)
-			goto outsk;
-		memset(ipx, 0, sizeof(*ipx));
-                sock->ops = &ipx_dgram_ops;
-                break;
-	case SOCK_SEQPACKET:
-		/*
-		 * SPX support is not anymore in the kernel sources. If
-		 * you want to ressurrect it, completing it and making
-		 * it understand shared skbs, be fully multithreaded,
-		 * etc, grab the sources in an early 2.5 kernel tree.
-		 */
-	case SOCK_STREAM:       /* Allow higher levels to piggyback */
-	default:
+	/*
+	 * SPX support is not anymore in the kernel sources. If you want to
+	 * ressurrect it, completing it and making it understand shared skbs,
+	 * be fully multithreaded, etc, grab the sources in an early 2.5 kernel
+	 * tree.
+	 */
+	if (sock->type != SOCK_DGRAM)
+		goto out;
+
+	sk = sk_alloc(PF_IPX, GFP_KERNEL, sizeof(struct ipx_sock), ipx_sk_slab);
+       	rc = -ENOMEM;
+	if (!sk)
 		goto out;
-	}
 #ifdef IPX_REFCNT_DEBUG
         atomic_inc(&ipx_sock_nr);
         printk(KERN_DEBUG "IPX socket %p created, now we have %d alive\n", sk,
@@ -1376,12 +1373,10 @@
 	sock_init_data(sock, sk);
 	sk_set_owner(sk, THIS_MODULE);
 	sk->sk_no_check = 1;		/* Checksum off by default */
+	sock->ops = &ipx_dgram_ops;
 	rc = 0;
 out:
 	return rc;
-outsk:
-	sk_free(sk);
-	goto out;
 }
 
 static int ipx_release(struct socket *sock)
@@ -1427,7 +1422,7 @@
 static int ipx_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
 {
 	struct sock *sk = sock->sk;
-	struct ipx_opt *ipxs = ipx_sk(sk);
+	struct ipx_sock *ipxs = ipx_sk(sk);
 	struct ipx_interface *intrfc;
 	struct sockaddr_ipx *addr = (struct sockaddr_ipx *)uaddr;
 	int rc = -EINVAL;
@@ -1523,7 +1518,7 @@
 	int addr_len, int flags)
 {
 	struct sock *sk = sock->sk;
-	struct ipx_opt *ipxs = ipx_sk(sk);
+	struct ipx_sock *ipxs = ipx_sk(sk);
 	struct sockaddr_ipx *addr;
 	int rc = -EINVAL;
 	struct ipx_route *rt;
@@ -1587,7 +1582,7 @@
 	struct ipx_address *addr;
 	struct sockaddr_ipx sipx;
 	struct sock *sk = sock->sk;
-	struct ipx_opt *ipxs = ipx_sk(sk);
+	struct ipx_sock *ipxs = ipx_sk(sk);
 	int rc;
 
 	*uaddr_len = sizeof(struct sockaddr_ipx);
@@ -1629,7 +1624,7 @@
 	return rc;
 }
 
-int ipx_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt)
+static int ipx_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt)
 {
 	/* NULL here for pt means the packet was looped back */
 	struct ipx_interface *intrfc;
@@ -1687,7 +1682,7 @@
 	struct msghdr *msg, size_t len)
 {
 	struct sock *sk = sock->sk;
-	struct ipx_opt *ipxs = ipx_sk(sk);
+	struct ipx_sock *ipxs = ipx_sk(sk);
 	struct sockaddr_ipx *usipx = (struct sockaddr_ipx *)msg->msg_name;
 	struct sockaddr_ipx local_sipx;
 	int rc = -EINVAL;
@@ -1752,7 +1747,7 @@
 		struct msghdr *msg, size_t size, int flags)
 {
 	struct sock *sk = sock->sk;
-	struct ipx_opt *ipxs = ipx_sk(sk);
+	struct ipx_sock *ipxs = ipx_sk(sk);
 	struct sockaddr_ipx *sipx = (struct sockaddr_ipx *)msg->msg_name;
 	struct ipxhdr *ipx = NULL;
 	struct sk_buff *skb;
@@ -1959,6 +1954,13 @@
 
 static int __init ipx_init(void)
 {
+	ipx_sk_slab = kmem_cache_create("ipx_sock",
+					sizeof(struct ipx_sock), 0,
+					SLAB_HWCACHE_ALIGN, NULL, NULL);
+
+	if (ipx_sk_slab == NULL)
+		return -ENOMEM;
+
 	sock_register(&ipx_family_ops);
 
 	pEII_datalink = make_EII_client();
@@ -2009,6 +2011,11 @@
 	dev_remove_pack(&ipx_dix_packet_type);
 	destroy_EII_client(pEII_datalink);
 	pEII_datalink = NULL;
+
+	if (ipx_sk_slab != NULL) {
+		kmem_cache_destroy(ipx_sk_slab);
+		ipx_sk_slab = NULL;
+	}
 
 	sock_unregister(ipx_family_ops.family);
 }
diff -Nru a/net/ipx/ipx_proc.c b/net/ipx/ipx_proc.c
--- a/net/ipx/ipx_proc.c	2005-03-01 23:38:44 -08:00
+++ b/net/ipx/ipx_proc.c	2005-03-01 23:38:44 -08:00
@@ -202,7 +202,7 @@
 {
 	struct sock* sk, *next;
 	struct ipx_interface *i;
-	struct ipx_opt *ipxs;
+	struct ipx_sock *ipxs;
 
 	++*pos;
 	if (v == SEQ_START_TOKEN) {
@@ -243,7 +243,7 @@
 static int ipx_seq_socket_show(struct seq_file *seq, void *v)
 {
 	struct sock *s;
-	struct ipx_opt *ipxs;
+	struct ipx_sock *ipxs;
 
 	if (v == SEQ_START_TOKEN) {
 #ifdef CONFIG_IPX_INTERN
@@ -287,21 +287,21 @@
 	return 0;
 }
 
-struct seq_operations ipx_seq_interface_ops = {
+static struct seq_operations ipx_seq_interface_ops = {
 	.start  = ipx_seq_interface_start,
 	.next   = ipx_seq_interface_next,
 	.stop   = ipx_seq_interface_stop,
 	.show   = ipx_seq_interface_show,
 };
 
-struct seq_operations ipx_seq_route_ops = {
+static struct seq_operations ipx_seq_route_ops = {
 	.start  = ipx_seq_route_start,
 	.next   = ipx_seq_route_next,
 	.stop   = ipx_seq_route_stop,
 	.show   = ipx_seq_route_show,
 };
 
-struct seq_operations ipx_seq_socket_ops = {
+static struct seq_operations ipx_seq_socket_ops = {
 	.start  = ipx_seq_socket_start,
 	.next   = ipx_seq_socket_next,
 	.stop   = ipx_seq_interface_stop,
diff -Nru a/net/ipx/ipx_route.c b/net/ipx/ipx_route.c
--- a/net/ipx/ipx_route.c	2005-03-01 23:38:57 -08:00
+++ b/net/ipx/ipx_route.c	2005-03-01 23:38:57 -08:00
@@ -16,7 +16,7 @@
 #include <net/sock.h>
 
 LIST_HEAD(ipx_routes);
-rwlock_t ipx_routes_lock = RW_LOCK_UNLOCKED;
+DEFINE_RWLOCK(ipx_routes_lock);
 
 extern struct ipx_interface *ipx_internal_net;
 
@@ -172,7 +172,7 @@
 			struct iovec *iov, size_t len, int noblock)
 {
 	struct sk_buff *skb;
-	struct ipx_opt *ipxs = ipx_sk(sk);
+	struct ipx_sock *ipxs = ipx_sk(sk);
 	struct ipx_interface *intrfc;
 	struct ipxhdr *ipx;
 	size_t size;
diff -Nru a/net/irda/af_irda.c b/net/irda/af_irda.c
--- a/net/irda/af_irda.c	2005-03-01 23:38:54 -08:00
+++ b/net/irda/af_irda.c	2005-03-01 23:38:54 -08:00
@@ -298,7 +298,7 @@
  *    Accept incoming connection
  *
  */
-void irda_connect_response(struct irda_sock *self)
+static void irda_connect_response(struct irda_sock *self)
 {
 	struct sk_buff *skb;
 
@@ -1155,7 +1155,7 @@
  *    Destroy socket
  *
  */
-void irda_destroy_socket(struct irda_sock *self)
+static void irda_destroy_socket(struct irda_sock *self)
 {
 	IRDA_DEBUG(2, "%s(%p)\n", __FUNCTION__, self);
 
diff -Nru a/net/irda/discovery.c b/net/irda/discovery.c
--- a/net/irda/discovery.c	2005-03-01 23:38:54 -08:00
+++ b/net/irda/discovery.c	2005-03-01 23:38:54 -08:00
@@ -315,41 +315,6 @@
 	return(buffer);
 }
 
-/*
- * Function irlmp_find_device (name, saddr)
- *
- *    Look through the discovery log at each of the links and try to find 
- *    the device with the given name. Return daddr and saddr. If saddr is
- *    specified, that look at that particular link only (not impl).
- */
-__u32 irlmp_find_device(hashbin_t *cachelog, char *name, __u32 *saddr)
-{
-	unsigned long flags;
-	discovery_t *d;
-
-	spin_lock_irqsave(&cachelog->hb_spinlock, flags);
-
-	/* Look at all discoveries for that link */
-	d = (discovery_t *) hashbin_get_first(cachelog);
-	while (d != NULL) {
-		IRDA_DEBUG(1, "Discovery:\n");
-		IRDA_DEBUG(1, "  daddr=%08x\n", d->data.daddr);
-		IRDA_DEBUG(1, "  nickname=%s\n", d->data.info);
-
-		if (strcmp(name, d->data.info) == 0) {
-			*saddr = d->data.saddr;
-			
-			spin_unlock_irqrestore(&cachelog->hb_spinlock, flags);
-			return d->data.daddr;
-		}
-		d = (discovery_t *) hashbin_get_next(cachelog);
-	}
-
-	spin_unlock_irqrestore(&cachelog->hb_spinlock, flags);
-
-	return 0;
-}
-
 #ifdef CONFIG_PROC_FS
 static inline discovery_t *discovery_seq_idx(loff_t pos)
 
diff -Nru a/net/irda/ircomm/ircomm_core.c b/net/irda/ircomm/ircomm_core.c
--- a/net/irda/ircomm/ircomm_core.c	2005-03-01 23:39:18 -08:00
+++ b/net/irda/ircomm/ircomm_core.c	2005-03-01 23:39:18 -08:00
@@ -68,7 +68,7 @@
 
 hashbin_t *ircomm = NULL;
 
-int __init ircomm_init(void)
+static int __init ircomm_init(void)
 {
 	ircomm = hashbin_new(HB_LOCK); 
 	if (ircomm == NULL) {
@@ -89,7 +89,7 @@
 	return 0;
 }
 
-void __exit ircomm_cleanup(void)
+static void __exit ircomm_cleanup(void)
 {
 	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
 
diff -Nru a/net/irda/ircomm/ircomm_event.c b/net/irda/ircomm/ircomm_event.c
--- a/net/irda/ircomm/ircomm_event.c	2005-03-01 23:38:55 -08:00
+++ b/net/irda/ircomm/ircomm_event.c	2005-03-01 23:38:55 -08:00
@@ -57,7 +57,8 @@
 	"IRCOMM_CONN",
 };
 
-char *ircomm_event[] = {
+#ifdef CONFIG_IRDA_DEBUG
+static char *ircomm_event[] = {
 	"IRCOMM_CONNECT_REQUEST",
         "IRCOMM_CONNECT_RESPONSE",
         "IRCOMM_TTP_CONNECT_INDICATION",
@@ -75,6 +76,7 @@
         "IRCOMM_CONTROL_REQUEST",
         "IRCOMM_CONTROL_INDICATION",
 };
+#endif /* CONFIG_IRDA_DEBUG */
 
 static int (*state[])(struct ircomm_cb *self, IRCOMM_EVENT event,
 		      struct sk_buff *skb, struct ircomm_info *info) = 
diff -Nru a/net/irda/ircomm/ircomm_lmp.c b/net/irda/ircomm/ircomm_lmp.c
--- a/net/irda/ircomm/ircomm_lmp.c	2005-03-01 23:38:51 -08:00
+++ b/net/irda/ircomm/ircomm_lmp.c	2005-03-01 23:38:51 -08:00
@@ -41,44 +41,6 @@
 #include <net/irda/ircomm_event.h>
 #include <net/irda/ircomm_lmp.h>
 
-/*
- * Function ircomm_open_lsap (self)
- *
- *    Open LSAP. This function will only be used when using "raw" services
- *
- */
-int ircomm_open_lsap(struct ircomm_cb *self)
-{
-	notify_t notify;
-	
-	IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
-	
-        /* Register callbacks */
-        irda_notify_init(&notify);
-	notify.data_indication       = ircomm_lmp_data_indication;
-	notify.connect_confirm       = ircomm_lmp_connect_confirm;
-        notify.connect_indication    = ircomm_lmp_connect_indication;
-	notify.disconnect_indication = ircomm_lmp_disconnect_indication;
-	notify.instance = self;
-	strlcpy(notify.name, "IrCOMM", sizeof(notify.name));
-
-	self->lsap = irlmp_open_lsap(LSAP_ANY, &notify, 0);
-	if (!self->lsap) {
-		IRDA_DEBUG(0,"%sfailed to allocate tsap\n", __FUNCTION__ );
-		return -1;
-	}
-	self->slsap_sel = self->lsap->slsap_sel;
-
-	/*
-	 *  Initialize the call-table for issuing commands
-	 */
-	self->issue.data_request       = ircomm_lmp_data_request;
-	self->issue.connect_request    = ircomm_lmp_connect_request;
-	self->issue.connect_response   = ircomm_lmp_connect_response;
-	self->issue.disconnect_request = ircomm_lmp_disconnect_request;
-
-	return 0;
-}
 
 /*
  * Function ircomm_lmp_connect_request (self, userdata)
@@ -86,9 +48,9 @@
  *    
  *
  */
-int ircomm_lmp_connect_request(struct ircomm_cb *self, 
-			       struct sk_buff *userdata, 
-			       struct ircomm_info *info)
+static int ircomm_lmp_connect_request(struct ircomm_cb *self, 
+				      struct sk_buff *userdata, 
+				      struct ircomm_info *info)
 {
 	int ret = 0;
 
@@ -109,7 +71,8 @@
  *    
  *
  */
-int ircomm_lmp_connect_response(struct ircomm_cb *self, struct sk_buff *userdata)
+static int ircomm_lmp_connect_response(struct ircomm_cb *self,
+				       struct sk_buff *userdata)
 {
 	struct sk_buff *tx_skb;
 	int ret;
@@ -141,9 +104,9 @@
 	return 0;
 }
 
-int ircomm_lmp_disconnect_request(struct ircomm_cb *self, 
-				  struct sk_buff *userdata, 
-				  struct ircomm_info *info)
+static int ircomm_lmp_disconnect_request(struct ircomm_cb *self, 
+					 struct sk_buff *userdata, 
+					 struct ircomm_info *info)
 {
         struct sk_buff *tx_skb;
 	int ret;
@@ -175,7 +138,7 @@
  *    been deallocated. We do this to make sure we don't flood IrLAP with 
  *    frames, since we are not using the IrTTP flow control mechanism
  */
-void ircomm_lmp_flow_control(struct sk_buff *skb)
+static void ircomm_lmp_flow_control(struct sk_buff *skb)
 {
 	struct irda_skb_cb *cb;
 	struct ircomm_cb *self;
@@ -215,8 +178,9 @@
  *    Send data frame to peer device
  *
  */
-int ircomm_lmp_data_request(struct ircomm_cb *self, struct sk_buff *skb, 
-			    int not_used)
+static int ircomm_lmp_data_request(struct ircomm_cb *self,
+				   struct sk_buff *skb, 
+				   int not_used)
 {
 	struct irda_skb_cb *cb;
 	int ret;
@@ -256,8 +220,8 @@
  *    Incoming data which we must deliver to the state machine, to check
  *    we are still connected.
  */
-int ircomm_lmp_data_indication(void *instance, void *sap,
-			       struct sk_buff *skb)
+static int ircomm_lmp_data_indication(void *instance, void *sap,
+				      struct sk_buff *skb)
 {
 	struct ircomm_cb *self = (struct ircomm_cb *) instance;
 
@@ -282,11 +246,11 @@
  *    Connection has been confirmed by peer device
  *
  */
-void ircomm_lmp_connect_confirm(void *instance, void *sap,
-				struct qos_info *qos, 
-				__u32 max_seg_size, 
-				__u8 max_header_size,
-				struct sk_buff *skb)
+static void ircomm_lmp_connect_confirm(void *instance, void *sap,
+				       struct qos_info *qos, 
+				       __u32 max_seg_size, 
+				       __u8 max_header_size,
+				       struct sk_buff *skb)
 {
 	struct ircomm_cb *self = (struct ircomm_cb *) instance;
 	struct ircomm_info info;
@@ -315,11 +279,11 @@
  *    Peer device wants to make a connection with us
  *
  */
-void ircomm_lmp_connect_indication(void *instance, void *sap,
-				   struct qos_info *qos,
-				   __u32 max_seg_size,
-				   __u8 max_header_size,
-				   struct sk_buff *skb)
+static void ircomm_lmp_connect_indication(void *instance, void *sap,
+					  struct qos_info *qos,
+					  __u32 max_seg_size,
+					  __u8 max_header_size,
+					  struct sk_buff *skb)
 {
 	struct ircomm_cb *self = (struct ircomm_cb *)instance;
 	struct ircomm_info info;
@@ -347,9 +311,9 @@
  *    Peer device has closed the connection, or the link went down for some
  *    other reason
  */
-void ircomm_lmp_disconnect_indication(void *instance, void *sap, 
-				      LM_REASON reason,
-				      struct sk_buff *skb)
+static void ircomm_lmp_disconnect_indication(void *instance, void *sap, 
+					     LM_REASON reason,
+					     struct sk_buff *skb)
 {
 	struct ircomm_cb *self = (struct ircomm_cb *) instance;
 	struct ircomm_info info;
@@ -366,4 +330,42 @@
 	/* Drop reference count - see ircomm_tty_disconnect_indication(). */
 	if(skb)
 		dev_kfree_skb(skb);
+}
+/*
+ * Function ircomm_open_lsap (self)
+ *
+ *    Open LSAP. This function will only be used when using "raw" services
+ *
+ */
+int ircomm_open_lsap(struct ircomm_cb *self)
+{
+	notify_t notify;
+
+	IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
+
+	/* Register callbacks */
+	irda_notify_init(&notify);
+	notify.data_indication       = ircomm_lmp_data_indication;
+	notify.connect_confirm       = ircomm_lmp_connect_confirm;
+	notify.connect_indication    = ircomm_lmp_connect_indication;
+	notify.disconnect_indication = ircomm_lmp_disconnect_indication;
+	notify.instance = self;
+	strlcpy(notify.name, "IrCOMM", sizeof(notify.name));
+
+	self->lsap = irlmp_open_lsap(LSAP_ANY, &notify, 0);
+	if (!self->lsap) {
+		IRDA_DEBUG(0,"%sfailed to allocate tsap\n", __FUNCTION__ );
+		return -1;
+	}
+	self->slsap_sel = self->lsap->slsap_sel;
+
+	/*
+	 *  Initialize the call-table for issuing commands
+	 */
+	self->issue.data_request       = ircomm_lmp_data_request;
+	self->issue.connect_request    = ircomm_lmp_connect_request;
+	self->issue.connect_response   = ircomm_lmp_connect_response;
+	self->issue.disconnect_request = ircomm_lmp_disconnect_request;
+
+	return 0;
 }
diff -Nru a/net/irda/ircomm/ircomm_param.c b/net/irda/ircomm/ircomm_param.c
--- a/net/irda/ircomm/ircomm_param.c	2005-03-01 23:38:57 -08:00
+++ b/net/irda/ircomm/ircomm_param.c	2005-03-01 23:38:57 -08:00
@@ -92,23 +92,6 @@
 pi_param_info_t ircomm_param_info = { pi_major_call_table, 3, 0x0f, 4 };
 
 /*
- * Function ircomm_param_flush (self)
- *
- *    Flush (send) out all queued parameters
- *
- */
-int ircomm_param_flush(struct ircomm_tty_cb *self)
-{
-	/* we should lock here, but I guess this function is unused...
-	 * Jean II */
-	if (self->ctrl_skb) {
-		ircomm_control_request(self->ircomm, self->ctrl_skb);
-		self->ctrl_skb = NULL;	
-	}
-	return 0;
-}
-
-/*
  * Function ircomm_param_request (self, pi, flush)
  *
  *    Queue a parameter for the control channel
diff -Nru a/net/irda/ircomm/ircomm_ttp.c b/net/irda/ircomm/ircomm_ttp.c
--- a/net/irda/ircomm/ircomm_ttp.c	2005-03-01 23:39:16 -08:00
+++ b/net/irda/ircomm/ircomm_ttp.c	2005-03-01 23:39:16 -08:00
@@ -40,6 +40,35 @@
 #include <net/irda/ircomm_event.h>
 #include <net/irda/ircomm_ttp.h>
 
+static int ircomm_ttp_data_indication(void *instance, void *sap,
+				      struct sk_buff *skb);
+static void ircomm_ttp_connect_confirm(void *instance, void *sap,
+				       struct qos_info *qos, 
+				       __u32 max_sdu_size, 
+				       __u8 max_header_size,
+				       struct sk_buff *skb);
+static void ircomm_ttp_connect_indication(void *instance, void *sap,
+					  struct qos_info *qos,
+					  __u32 max_sdu_size,
+					  __u8 max_header_size,
+					  struct sk_buff *skb);
+static void ircomm_ttp_flow_indication(void *instance, void *sap,
+				       LOCAL_FLOW cmd);
+static void ircomm_ttp_disconnect_indication(void *instance, void *sap, 
+					     LM_REASON reason,
+					     struct sk_buff *skb);
+static int ircomm_ttp_data_request(struct ircomm_cb *self,
+				   struct sk_buff *skb, 
+				   int clen);
+static int ircomm_ttp_connect_request(struct ircomm_cb *self, 
+				      struct sk_buff *userdata, 
+				      struct ircomm_info *info);
+static int ircomm_ttp_connect_response(struct ircomm_cb *self,
+				       struct sk_buff *userdata);
+static int ircomm_ttp_disconnect_request(struct ircomm_cb *self, 
+					 struct sk_buff *userdata, 
+					 struct ircomm_info *info);
+
 /*
  * Function ircomm_open_tsap (self)
  *
@@ -87,9 +116,9 @@
  *    
  *
  */
-int ircomm_ttp_connect_request(struct ircomm_cb *self, 
-			       struct sk_buff *userdata, 
-			       struct ircomm_info *info)
+static int ircomm_ttp_connect_request(struct ircomm_cb *self, 
+				      struct sk_buff *userdata, 
+				      struct ircomm_info *info)
 {
 	int ret = 0;
 
@@ -112,8 +141,8 @@
  *    
  *
  */
-int ircomm_ttp_connect_response(struct ircomm_cb *self,
-				struct sk_buff *userdata)
+static int ircomm_ttp_connect_response(struct ircomm_cb *self,
+				       struct sk_buff *userdata)
 {
 	int ret;
 
@@ -137,9 +166,9 @@
  *    some of them are sent after connection establishment, so this can 
  *    increase the latency a bit.
  */
-int ircomm_ttp_data_request(struct ircomm_cb *self,
-			    struct sk_buff *skb, 
-			    int clen)
+static int ircomm_ttp_data_request(struct ircomm_cb *self,
+				   struct sk_buff *skb, 
+				   int clen)
 {
 	int ret;
 
@@ -175,8 +204,8 @@
  *    Incoming data
  *
  */
-int ircomm_ttp_data_indication(void *instance, void *sap,
-			       struct sk_buff *skb)
+static int ircomm_ttp_data_indication(void *instance, void *sap,
+				      struct sk_buff *skb)
 {
 	struct ircomm_cb *self = (struct ircomm_cb *) instance;
 
@@ -194,11 +223,11 @@
 	return 0;
 }
 
-void ircomm_ttp_connect_confirm(void *instance, void *sap,
-				struct qos_info *qos, 
-				__u32 max_sdu_size, 
-				__u8 max_header_size,
-				struct sk_buff *skb)
+static void ircomm_ttp_connect_confirm(void *instance, void *sap,
+				       struct qos_info *qos, 
+				       __u32 max_sdu_size, 
+				       __u8 max_header_size,
+				       struct sk_buff *skb)
 {
 	struct ircomm_cb *self = (struct ircomm_cb *) instance;
 	struct ircomm_info info;
@@ -234,11 +263,11 @@
  *    
  *
  */
-void ircomm_ttp_connect_indication(void *instance, void *sap,
-				   struct qos_info *qos,
-				   __u32 max_sdu_size,
-				   __u8 max_header_size,
-				   struct sk_buff *skb)
+static void ircomm_ttp_connect_indication(void *instance, void *sap,
+					  struct qos_info *qos,
+					  __u32 max_sdu_size,
+					  __u8 max_header_size,
+					  struct sk_buff *skb)
 {
 	struct ircomm_cb *self = (struct ircomm_cb *)instance;
 	struct ircomm_info info;
@@ -273,9 +302,9 @@
  *    
  *
  */
-int ircomm_ttp_disconnect_request(struct ircomm_cb *self, 
-				  struct sk_buff *userdata, 
-				  struct ircomm_info *info)
+static int ircomm_ttp_disconnect_request(struct ircomm_cb *self, 
+					 struct sk_buff *userdata, 
+					 struct ircomm_info *info)
 {
 	int ret;
 
@@ -294,9 +323,9 @@
  *    
  *
  */
-void ircomm_ttp_disconnect_indication(void *instance, void *sap, 
-				      LM_REASON reason,
-				      struct sk_buff *skb)
+static void ircomm_ttp_disconnect_indication(void *instance, void *sap, 
+					     LM_REASON reason,
+					     struct sk_buff *skb)
 {
 	struct ircomm_cb *self = (struct ircomm_cb *) instance;
 	struct ircomm_info info;
@@ -321,7 +350,8 @@
  *    Layer below is telling us to start or stop the flow of data
  *
  */
-void ircomm_ttp_flow_indication(void *instance, void *sap, LOCAL_FLOW cmd)
+static void ircomm_ttp_flow_indication(void *instance, void *sap,
+				       LOCAL_FLOW cmd)
 {
 	struct ircomm_cb *self = (struct ircomm_cb *) instance;
 
diff -Nru a/net/irda/ircomm/ircomm_tty.c b/net/irda/ircomm/ircomm_tty.c
--- a/net/irda/ircomm/ircomm_tty.c	2005-03-01 23:38:54 -08:00
+++ b/net/irda/ircomm/ircomm_tty.c	2005-03-01 23:38:54 -08:00
@@ -64,6 +64,7 @@
 static void ircomm_tty_hangup(struct tty_struct *tty);
 static void ircomm_tty_do_softint(void *private_);
 static void ircomm_tty_shutdown(struct ircomm_tty_cb *self);
+static void ircomm_tty_stop(struct tty_struct *tty);
 
 static int ircomm_tty_data_indication(void *instance, void *sap,
 				      struct sk_buff *skb);
@@ -108,7 +109,7 @@
  *    Init IrCOMM TTY layer/driver
  *
  */
-int __init ircomm_tty_init(void)
+static int __init ircomm_tty_init(void)
 {
 	driver = alloc_tty_driver(IRCOMM_TTY_PORTS);
 	if (!driver)
@@ -159,7 +160,7 @@
  *    Remove IrCOMM TTY layer/driver
  *
  */
-void __exit ircomm_tty_cleanup(void)
+static void __exit ircomm_tty_cleanup(void)
 {
 	int ret;
 
@@ -1064,7 +1065,7 @@
  *     This routine notifies the tty driver that it should stop outputting
  *     characters to the tty device. 
  */
-void ircomm_tty_stop(struct tty_struct *tty) 
+static void ircomm_tty_stop(struct tty_struct *tty) 
 {
 	struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;
 
diff -Nru a/net/irda/ircomm/ircomm_tty_attach.c b/net/irda/ircomm/ircomm_tty_attach.c
--- a/net/irda/ircomm/ircomm_tty_attach.c	2005-03-01 23:39:16 -08:00
+++ b/net/irda/ircomm/ircomm_tty_attach.c	2005-03-01 23:39:16 -08:00
@@ -52,8 +52,9 @@
 					    void *priv);
 static void ircomm_tty_getvalue_confirm(int result, __u16 obj_id, 
 					struct ias_value *value, void *priv);
-void ircomm_tty_start_watchdog_timer(struct ircomm_tty_cb *self, int timeout);
-void ircomm_tty_watchdog_timer_expired(void *data);
+static void ircomm_tty_start_watchdog_timer(struct ircomm_tty_cb *self,
+					    int timeout);
+static void ircomm_tty_watchdog_timer_expired(void *data);
 
 static int ircomm_tty_state_idle(struct ircomm_tty_cb *self, 
 				 IRCOMM_TTY_EVENT event, 
@@ -90,7 +91,8 @@
 	"*** ERROR *** ",
 };
 
-char *ircomm_tty_event[] = {
+#ifdef CONFIG_IRDA_DEBUG
+static char *ircomm_tty_event[] = {
 	"IRCOMM_TTY_ATTACH_CABLE",
 	"IRCOMM_TTY_DETACH_CABLE",
 	"IRCOMM_TTY_DATA_REQUEST",
@@ -106,6 +108,7 @@
 	"IRCOMM_TTY_GOT_LSAPSEL",
 	"*** ERROR ****",
 };
+#endif /* CONFIG_IRDA_DEBUG */
 
 static int (*state[])(struct ircomm_tty_cb *self, IRCOMM_TTY_EVENT event,
 		      struct sk_buff *skb, struct ircomm_tty_info *info) = 
@@ -594,7 +597,8 @@
  *    connection attempt is successful, and if not, we will retry after 
  *    the timeout
  */
-void ircomm_tty_start_watchdog_timer(struct ircomm_tty_cb *self, int timeout)
+static void ircomm_tty_start_watchdog_timer(struct ircomm_tty_cb *self,
+					    int timeout)
 {
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
@@ -609,7 +613,7 @@
  *    Called when the connect procedure have taken to much time.
  *
  */
-void ircomm_tty_watchdog_timer_expired(void *data)
+static void ircomm_tty_watchdog_timer_expired(void *data)
 {
 	struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) data;
 	
diff -Nru a/net/irda/ircomm/ircomm_tty_ioctl.c b/net/irda/ircomm/ircomm_tty_ioctl.c
--- a/net/irda/ircomm/ircomm_tty_ioctl.c	2005-03-01 23:38:44 -08:00
+++ b/net/irda/ircomm/ircomm_tty_ioctl.c	2005-03-01 23:38:44 -08:00
@@ -53,7 +53,7 @@
  *    Change speed of the driver. If the remote device is a DCE, then this
  *    should make it change the speed of its serial port
  */
-void ircomm_tty_change_speed(struct ircomm_tty_cb *self)
+static void ircomm_tty_change_speed(struct ircomm_tty_cb *self)
 {
 	unsigned cflag, cval;
 	int baud;
diff -Nru a/net/irda/irda_device.c b/net/irda/irda_device.c
--- a/net/irda/irda_device.c	2005-03-01 23:38:57 -08:00
+++ b/net/irda/irda_device.c	2005-03-01 23:38:57 -08:00
@@ -143,47 +143,6 @@
 EXPORT_SYMBOL(irda_device_set_media_busy);
 
 
-int irda_device_set_dtr_rts(struct net_device *dev, int dtr, int rts)
-{
-	struct if_irda_req req;
-	int ret;
-
-	IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
-
-	if (!dev->do_ioctl) {
-		ERROR("%s: do_ioctl not impl. by device driver\n",
-				__FUNCTION__);
-		return -1;
-	}
-
-	req.ifr_dtr = dtr;
-	req.ifr_rts = rts;
-
-	ret = dev->do_ioctl(dev, (struct ifreq *) &req, SIOCSDTRRTS);
-
-	return ret;
-}
-
-int irda_device_change_speed(struct net_device *dev, __u32 speed)
-{
-	struct if_irda_req req;
-	int ret;
-
-	IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
-
-	if (!dev->do_ioctl) {
-		ERROR("%s: do_ioctl not impl. by device driver\n",
-				__FUNCTION__);
-		return -1;
-	}
-
-	req.ifr_baudrate = speed;
-
-	ret = dev->do_ioctl(dev, (struct ifreq *) &req, SIOCSBANDWIDTH);
-
-	return ret;
-}
-
 /*
  * Function irda_device_is_receiving (dev)
  *
@@ -372,7 +331,7 @@
  *    This function should be used by low level device drivers in a similar way
  *    as ether_setup() is used by normal network device drivers
  */
-void irda_device_setup(struct net_device *dev)
+static void irda_device_setup(struct net_device *dev)
 {
         dev->hard_header_len = 0;
         dev->addr_len        = 0;
@@ -501,33 +460,6 @@
 	spin_unlock(&dongles->hb_spinlock);
 }
 EXPORT_SYMBOL(irda_device_unregister_dongle);
-
-/*
- * Function irda_device_set_mode (self, mode)
- *
- *    Set the Infrared device driver into mode where it sends and receives
- *    data without using IrLAP framing. Check out the particular device
- *    driver to find out which modes it support.
- */
-int irda_device_set_mode(struct net_device* dev, int mode)
-{
-	struct if_irda_req req;
-	int ret;
-
-	IRDA_DEBUG(0, "%s()\n", __FUNCTION__);
-
-	if (!dev->do_ioctl) {
-		ERROR("%s: set_raw_mode not impl. by device driver\n",
-				__FUNCTION__);
-		return -1;
-	}
-
-	req.ifr_mode = mode;
-
-	ret = dev->do_ioctl(dev, (struct ifreq *) &req, SIOCSMODE);
-
-	return ret;
-}
 
 #ifdef CONFIG_ISA
 /*
diff -Nru a/net/irda/iriap.c b/net/irda/iriap.c
--- a/net/irda/iriap.c	2005-03-01 23:38:54 -08:00
+++ b/net/irda/iriap.c	2005-03-01 23:38:54 -08:00
@@ -77,6 +77,15 @@
 static int iriap_data_indication(void *instance, void *sap,
 				 struct sk_buff *skb);
 
+static void iriap_watchdog_timer_expired(void *data);
+
+static inline void iriap_start_watchdog_timer(struct iriap_cb *self, 
+					      int timeout) 
+{
+	irda_start_timer(&self->watchdog_timer, timeout, self, 
+			 iriap_watchdog_timer_expired);
+}
+
 /*
  * Function iriap_init (void)
  *
@@ -328,7 +337,7 @@
 /*
  * Function iriap_disconnect_request (handle)
  */
-void iriap_disconnect_request(struct iriap_cb *self)
+static void iriap_disconnect_request(struct iriap_cb *self)
 {
 	struct sk_buff *tx_skb;
 
@@ -352,31 +361,6 @@
 	irlmp_disconnect_request(self->lsap, tx_skb);
 }
 
-void iriap_getinfobasedetails_request(void)
-{
-	IRDA_DEBUG(0, "%s(), Not implemented!\n", __FUNCTION__);
-}
-
-void iriap_getinfobasedetails_confirm(void)
-{
-	IRDA_DEBUG(0, "%s(), Not implemented!\n", __FUNCTION__);
-}
-
-void iriap_getobjects_request(void)
-{
-	IRDA_DEBUG(0, "%s(), Not implemented!\n", __FUNCTION__);
-}
-
-void iriap_getobjects_confirm(void)
-{
-	IRDA_DEBUG(0, "%s(), Not implemented!\n", __FUNCTION__);
-}
-
-void iriap_getvalue(void)
-{
-	IRDA_DEBUG(0, "%s(), Not implemented!\n", __FUNCTION__);
-}
-
 /*
  * Function iriap_getvaluebyclass (addr, name, attr)
  *
@@ -445,7 +429,8 @@
  *    to service user.
  *
  */
-void iriap_getvaluebyclass_confirm(struct iriap_cb *self, struct sk_buff *skb)
+static void iriap_getvaluebyclass_confirm(struct iriap_cb *self,
+					  struct sk_buff *skb)
 {
 	struct ias_value *value;
 	int charset;
@@ -552,8 +537,10 @@
  *    Send answer back to remote LM-IAS
  *
  */
-void iriap_getvaluebyclass_response(struct iriap_cb *self, __u16 obj_id,
-				    __u8 ret_code, struct ias_value *value)
+static void iriap_getvaluebyclass_response(struct iriap_cb *self,
+					   __u16 obj_id,
+					   __u8 ret_code,
+					   struct ias_value *value)
 {
 	struct sk_buff *tx_skb;
 	int n;
@@ -641,8 +628,8 @@
  *    getvaluebyclass is requested from peer LM-IAS
  *
  */
-void iriap_getvaluebyclass_indication(struct iriap_cb *self,
-				      struct sk_buff *skb)
+static void iriap_getvaluebyclass_indication(struct iriap_cb *self,
+					     struct sk_buff *skb)
 {
 	struct ias_object *obj;
 	struct ias_attrib *attrib;
@@ -962,7 +949,7 @@
  *    Query has taken too long time, so abort
  *
  */
-void iriap_watchdog_timer_expired(void *data)
+static void iriap_watchdog_timer_expired(void *data)
 {
 	struct iriap_cb *self = (struct iriap_cb *) data;
 
diff -Nru a/net/irda/irias_object.c b/net/irda/irias_object.c
--- a/net/irda/irias_object.c	2005-03-01 23:39:07 -08:00
+++ b/net/irda/irias_object.c	2005-03-01 23:39:07 -08:00
@@ -116,7 +116,7 @@
  *    Delete given attribute and deallocate all its memory
  *
  */
-void __irias_delete_attrib(struct ias_attrib *attrib)
+static void __irias_delete_attrib(struct ias_attrib *attrib)
 {
 	ASSERT(attrib != NULL, return;);
 	ASSERT(attrib->magic == IAS_ATTRIB_MAGIC, return;);
@@ -267,8 +267,8 @@
  *    Add attribute to object
  *
  */
-void irias_add_attrib( struct ias_object *obj, struct ias_attrib *attrib,
-		       int owner)
+static void irias_add_attrib(struct ias_object *obj, struct ias_attrib *attrib,
+			     int owner)
 {
 	ASSERT(obj != NULL, return;);
 	ASSERT(obj->magic == IAS_OBJECT_MAGIC, return;);
diff -Nru a/net/irda/irlan/irlan_client.c b/net/irda/irlan/irlan_client.c
--- a/net/irda/irlan/irlan_client.c	2005-03-01 23:38:58 -08:00
+++ b/net/irda/irlan/irlan_client.c	2005-03-01 23:38:58 -08:00
@@ -66,6 +66,7 @@
 					      struct sk_buff *);
 static void irlan_check_response_param(struct irlan_cb *self, char *param, 
 				       char *value, int val_len);
+static void irlan_client_open_ctrl_tsap(struct irlan_cb *self);
 
 static void irlan_client_kick_timer_expired(void *data)
 {
@@ -88,7 +89,7 @@
 	}
 }
 
-void irlan_client_start_kick_timer(struct irlan_cb *self, int timeout)
+static void irlan_client_start_kick_timer(struct irlan_cb *self, int timeout)
 {
 	IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
 	
@@ -248,7 +249,7 @@
  *    Initialize callbacks and open IrTTP TSAPs
  *
  */
-void irlan_client_open_ctrl_tsap(struct irlan_cb *self)
+static void irlan_client_open_ctrl_tsap(struct irlan_cb *self)
 {
 	struct tsap_cb *tsap;
 	notify_t notify;
@@ -307,42 +308,6 @@
 
 	irlan_do_client_event(self, IRLAN_CONNECT_COMPLETE, NULL);
 }
-
-/*
- * Function irlan_client_reconnect_data_channel (self)
- *
- *    Try to reconnect data channel (currently not used)
- *
- */
-void irlan_client_reconnect_data_channel(struct irlan_cb *self) 
-{
-	struct sk_buff *skb;
-	__u8 *frame;
-		
-	IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
-
-	ASSERT(self != NULL, return;);
-	ASSERT(self->magic == IRLAN_MAGIC, return;);
-	
-	skb = dev_alloc_skb(128);
-	if (!skb)
-		return;
-
-	/* Reserve space for TTP, LMP, and LAP header */
-	skb_reserve(skb, self->max_header_size);
-	skb_put(skb, 2);
-	
-	frame = skb->data;
-	
- 	frame[0] = CMD_RECONNECT_DATA_CHAN;
-	frame[1] = 0x01;
- 	irlan_insert_array_param(skb, "RECONNECT_KEY", 
-				 self->client.reconnect_key,
-				 self->client.key_len);
-	
-	irttp_data_request(self->client.tsap_ctrl, skb);	
-}
-
 
 /*
  * Function print_ret_code (code)
diff -Nru a/net/irda/irlan/irlan_common.c b/net/irda/irlan/irlan_common.c
--- a/net/irda/irlan/irlan_common.c	2005-03-01 23:38:58 -08:00
+++ b/net/irda/irlan/irlan_common.c	2005-03-01 23:38:58 -08:00
@@ -105,10 +105,13 @@
 extern struct proc_dir_entry *proc_irda;
 #endif /* CONFIG_PROC_FS */
 
+static struct irlan_cb *irlan_open(__u32 saddr, __u32 daddr);
 static void __irlan_close(struct irlan_cb *self);
 static int __irlan_insert_param(struct sk_buff *skb, char *param, int type, 
 				__u8 value_byte, __u16 value_short, 
 				__u8 *value_array, __u16 value_len);
+static void irlan_open_unicast_addr(struct irlan_cb *self);
+static void irlan_get_unicast_addr(struct irlan_cb *self);
 void irlan_close_tsaps(struct irlan_cb *self);
 
 /*
@@ -185,7 +188,7 @@
  *    Open new instance of a client/provider, we should only register the 
  *    network device if this instance is ment for a particular client/provider
  */
-struct irlan_cb *irlan_open(__u32 saddr, __u32 daddr)
+static struct irlan_cb *irlan_open(__u32 saddr, __u32 daddr)
 {
 	struct net_device *dev;
 	struct irlan_cb *self;
@@ -294,9 +297,11 @@
  *    Here we receive the connect indication for the data channel
  *
  */
-void irlan_connect_indication(void *instance, void *sap, struct qos_info *qos,
-			      __u32 max_sdu_size, __u8 max_header_size, 
-			      struct sk_buff *skb)
+static void irlan_connect_indication(void *instance, void *sap,
+				     struct qos_info *qos,
+				     __u32 max_sdu_size,
+				     __u8 max_header_size, 
+				     struct sk_buff *skb)
 {
 	struct irlan_cb *self;
 	struct tsap_cb *tsap;
@@ -339,9 +344,11 @@
 	netif_start_queue(self->dev); /* Clear reason */
 }
 
-void irlan_connect_confirm(void *instance, void *sap, struct qos_info *qos, 
-			   __u32 max_sdu_size, __u8 max_header_size, 
-			   struct sk_buff *skb) 
+static void irlan_connect_confirm(void *instance, void *sap,
+				  struct qos_info *qos, 
+				  __u32 max_sdu_size,
+				  __u8 max_header_size, 
+				  struct sk_buff *skb) 
 {
 	struct irlan_cb *self;
 
@@ -384,8 +391,9 @@
  *    Callback function for the IrTTP layer. Indicates a disconnection of
  *    the specified connection (handle)
  */
-void irlan_disconnect_indication(void *instance, void *sap, LM_REASON reason, 
-				 struct sk_buff *userdata) 
+static void irlan_disconnect_indication(void *instance,
+					void *sap, LM_REASON reason, 
+					struct sk_buff *userdata) 
 {
 	struct irlan_cb *self;
 	struct tsap_cb *tsap;
@@ -602,7 +610,7 @@
  *    This function makes sure that commands on the control channel is being
  *    sent in a command/response fashion
  */
-void irlan_ctrl_data_request(struct irlan_cb *self, struct sk_buff *skb)
+static void irlan_ctrl_data_request(struct irlan_cb *self, struct sk_buff *skb)
 {
 	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
 
@@ -722,7 +730,7 @@
  *    address.
  *
  */
-void irlan_open_unicast_addr(struct irlan_cb *self) 
+static void irlan_open_unicast_addr(struct irlan_cb *self)
 {
 	struct sk_buff *skb;
 	__u8 *frame;
@@ -839,7 +847,7 @@
  *    can construct its packets.
  *
  */
-void irlan_get_unicast_addr(struct irlan_cb *self) 
+static void irlan_get_unicast_addr(struct irlan_cb *self)
 {
 	struct sk_buff *skb;
 	__u8 *frame;
diff -Nru a/net/irda/irlan/irlan_provider.c b/net/irda/irlan/irlan_provider.c
--- a/net/irda/irlan/irlan_provider.c	2005-03-01 23:38:55 -08:00
+++ b/net/irda/irlan/irlan_provider.c	2005-03-01 23:38:55 -08:00
@@ -175,9 +175,9 @@
 	irttp_connect_response(tsap, IRLAN_MTU, NULL);
 }
 
-void irlan_provider_disconnect_indication(void *instance, void *sap, 
-					  LM_REASON reason, 
-					  struct sk_buff *userdata) 
+static void irlan_provider_disconnect_indication(void *instance, void *sap, 
+						 LM_REASON reason, 
+						 struct sk_buff *userdata) 
 {
 	struct irlan_cb *self;
 	struct tsap_cb *tsap;
diff -Nru a/net/irda/irlap.c b/net/irda/irlap.c
--- a/net/irda/irlap.c	2005-03-01 23:39:16 -08:00
+++ b/net/irda/irlap.c	2005-03-01 23:39:16 -08:00
@@ -60,6 +60,8 @@
 
 extern void irlap_queue_xmit(struct irlap_cb *self, struct sk_buff *skb);
 static void __irlap_close(struct irlap_cb *self);
+static void irlap_init_qos_capabilities(struct irlap_cb *self,
+					struct qos_info *qos_user);
 
 #ifdef CONFIG_IRDA_DEBUG
 static char *lap_reasons[] = {
@@ -867,7 +869,7 @@
  *    Change the speed of the IrDA port
  *
  */
-void irlap_change_speed(struct irlap_cb *self, __u32 speed, int now)
+static void irlap_change_speed(struct irlap_cb *self, __u32 speed, int now)
 {
 	struct sk_buff *skb;
 
@@ -894,8 +896,8 @@
  *    IrLAP itself. Normally, IrLAP will not specify any values, but it can
  *    be used to restrict certain values.
  */
-void irlap_init_qos_capabilities(struct irlap_cb *self,
-				 struct qos_info *qos_user)
+static void irlap_init_qos_capabilities(struct irlap_cb *self,
+					struct qos_info *qos_user)
 {
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == LAP_MAGIC, return;);
diff -Nru a/net/irda/irlap_event.c b/net/irda/irlap_event.c
--- a/net/irda/irlap_event.c	2005-03-01 23:38:59 -08:00
+++ b/net/irda/irlap_event.c	2005-03-01 23:38:59 -08:00
@@ -181,7 +181,7 @@
  * Make sure that state is XMIT_P/XMIT_S when calling this function
  * (and that nobody messed up with the state). - Jean II
  */
-void irlap_start_poll_timer(struct irlap_cb *self, int timeout)
+static void irlap_start_poll_timer(struct irlap_cb *self, int timeout)
 {
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == LAP_MAGIC, return;);
diff -Nru a/net/irda/irlap_frame.c b/net/irda/irlap_frame.c
--- a/net/irda/irlap_frame.c	2005-03-01 23:38:54 -08:00
+++ b/net/irda/irlap_frame.c	2005-03-01 23:38:54 -08:00
@@ -43,6 +43,9 @@
 #include <net/irda/irlap_frame.h>
 #include <net/irda/qos.h>
 
+static void irlap_send_i_frame(struct irlap_cb *self, struct sk_buff *skb,
+			       int command);
+
 /*
  * Function irlap_insert_info (self, skb)
  *
@@ -629,34 +632,6 @@
 		irlap_do_event(self, RECV_RR_RSP, skb, info);
 }
 
-void irlap_send_frmr_frame( struct irlap_cb *self, int command)
-{
-	struct sk_buff *tx_skb = NULL;
-	__u8 *frame;
-
-	ASSERT( self != NULL, return;);
-	ASSERT( self->magic == LAP_MAGIC, return;);
-
-	tx_skb = dev_alloc_skb( 32);
-	if (!tx_skb)
-		return;
-
-	frame = skb_put(tx_skb, 2);
-
-	frame[0] = self->caddr;
-	frame[0] |= (command) ? CMD_FRAME : 0;
-
-	frame[1]  = (self->vs << 1);
-	frame[1] |= PF_BIT;
-	frame[1] |= (self->vr << 5);
-
-	frame[2] = 0;
-
-	IRDA_DEBUG(4, "%s(), vr=%d, %ld\n", __FUNCTION__, self->vr, jiffies);
-
-	irlap_queue_xmit(self, tx_skb);
-}
-
 /*
  * Function irlap_recv_rnr_frame (self, skb, info)
  *
@@ -1129,8 +1104,8 @@
  *
  *    Contruct and transmit Information (I) frame
  */
-void irlap_send_i_frame(struct irlap_cb *self, struct sk_buff *skb,
-			int command)
+static void irlap_send_i_frame(struct irlap_cb *self, struct sk_buff *skb,
+			       int command)
 {
 	/* Insert connection address */
 	skb->data[0] = self->caddr;
diff -Nru a/net/irda/irlmp.c b/net/irda/irlmp.c
--- a/net/irda/irlmp.c	2005-03-01 23:39:16 -08:00
+++ b/net/irda/irlmp.c	2005-03-01 23:39:16 -08:00
@@ -44,6 +44,9 @@
 #include <net/irda/irlmp.h>
 #include <net/irda/irlmp_frame.h>
 
+static __u8 irlmp_find_free_slsap(void);
+static int irlmp_slsap_inuse(__u8 slsap_sel);
+
 /* Master structure */
 struct irlmp_cb *irlmp = NULL;
 
@@ -1278,11 +1281,6 @@
 }
 #endif /* CONFIG_IRDA_ULTRA */
 
-void irlmp_status_request(void)
-{
-	IRDA_DEBUG(0, "%s(), Not implemented\n", __FUNCTION__);
-}
-
 /*
  * Propagate status indication from LAP to LSAPs (via LMP)
  * This don't trigger any change of state in lap_cb, lmp_cb or lsap_cb,
@@ -1656,7 +1654,7 @@
  * of the allocated LSAP, but I'm not sure the complexity is worth it.
  * Jean II
  */
-int irlmp_slsap_inuse(__u8 slsap_sel)
+static int irlmp_slsap_inuse(__u8 slsap_sel)
 {
 	struct lsap_cb *self;
 	struct lap_cb *lap;
@@ -1756,7 +1754,7 @@
  *    Find a free source LSAP to use. This function is called if the service
  *    user has requested a source LSAP equal to LM_ANY
  */
-__u8 irlmp_find_free_slsap(void)
+static __u8 irlmp_find_free_slsap(void)
 {
 	__u8 lsap_sel;
 	int wrapped = 0;
diff -Nru a/net/irda/irmod.c b/net/irda/irmod.c
--- a/net/irda/irmod.c	2005-03-01 23:39:09 -08:00
+++ b/net/irda/irmod.c	2005-03-01 23:39:09 -08:00
@@ -100,7 +100,7 @@
  *  Protocol stack initialisation entry point.
  *  Initialise the various components of the IrDA stack
  */
-int __init irda_init(void)
+static int __init irda_init(void)
 {
 	IRDA_DEBUG(0, "%s()\n", __FUNCTION__);
 
@@ -136,7 +136,7 @@
  *  Protocol stack cleanup/removal entry point.
  *  Cleanup the various components of the IrDA stack
  */
-void __exit irda_cleanup(void)
+static void __exit irda_cleanup(void)
 {
 	/* Remove External APIs */
 #ifdef CONFIG_SYSCTL
diff -Nru a/net/irda/irnet/Kconfig b/net/irda/irnet/Kconfig
--- a/net/irda/irnet/Kconfig	2005-03-01 23:39:07 -08:00
+++ b/net/irda/irnet/Kconfig	2005-03-01 23:39:07 -08:00
@@ -7,7 +7,7 @@
 	  called irnet.  IrNET is a PPP driver, so you will also need a
 	  working PPP subsystem (driver, daemon and config)...
 
-	  IrNET is an alternate way to tranfer TCP/IP traffic over IrDA.  It
+	  IrNET is an alternate way to transfer TCP/IP traffic over IrDA.  It
 	  uses synchronous PPP over a set of point to point IrDA sockets.  You
 	  can use it between Linux machine or with W2k.
 
diff -Nru a/net/irda/irnet/irnet.h b/net/irda/irnet/irnet.h
--- a/net/irda/irnet/irnet.h	2005-03-01 23:39:07 -08:00
+++ b/net/irda/irnet/irnet.h	2005-03-01 23:39:07 -08:00
@@ -363,13 +363,13 @@
 /* Exit a function with debug */
 #define DRETURN(ret, dbg, args...) \
 	{DEXIT(dbg, ": " args);\
-	return(ret); }
+	return ret; }
 
 /* Exit a function on failed condition */
 #define DABORT(cond, ret, dbg, args...) \
 	{if(cond) {\
 		DERROR(dbg, args);\
-		return(ret); }}
+		return ret; }}
 
 /* Invalid assertion, print out an error and exit... */
 #define DASSERT(cond, ret, dbg, args...) \
@@ -520,8 +520,6 @@
 /* ---------------------------- MODULE ---------------------------- */
 extern int
 	irnet_init(void);		/* Initialise IrNET module */
-extern void
-	irnet_cleanup(void);		/* Teardown IrNET module */
 
 /**************************** VARIABLES ****************************/
 
diff -Nru a/net/irda/irnet/irnet_ppp.c b/net/irda/irnet/irnet_ppp.c
--- a/net/irda/irnet/irnet_ppp.c	2005-03-01 23:39:08 -08:00
+++ b/net/irda/irnet/irnet_ppp.c	2005-03-01 23:39:08 -08:00
@@ -16,6 +16,12 @@
 #include "irnet_ppp.h"		/* Private header */
 /* Please put other headers in irnet.h - Thanks */
 
+/* Generic PPP callbacks (to call us) */
+static struct ppp_channel_ops irnet_ppp_ops = {
+	.start_xmit = ppp_irnet_send,
+	.ioctl = ppp_irnet_ioctl
+};
+
 /************************* CONTROL CHANNEL *************************/
 /*
  * When a pppd instance is not active on /dev/irnet, it acts as a control
@@ -1095,7 +1101,7 @@
 /*
  * Module exit
  */
-void __exit
+static void __exit
 irnet_cleanup(void)
 {
   irda_irnet_cleanup();
diff -Nru a/net/irda/irnet/irnet_ppp.h b/net/irda/irnet/irnet_ppp.h
--- a/net/irda/irnet/irnet_ppp.h	2005-03-01 23:39:08 -08:00
+++ b/net/irda/irnet/irnet_ppp.h	2005-03-01 23:39:08 -08:00
@@ -116,11 +116,4 @@
 	&irnet_device_fops
 };
 
-/* Generic PPP callbacks (to call us) */
-struct ppp_channel_ops irnet_ppp_ops =
-{
-  ppp_irnet_send,
-  ppp_irnet_ioctl
-};
-
 #endif /* IRNET_PPP_H */
diff -Nru a/net/irda/irsysctl.c b/net/irda/irsysctl.c
--- a/net/irda/irsysctl.c	2005-03-01 23:38:55 -08:00
+++ b/net/irda/irsysctl.c	2005-03-01 23:38:55 -08:00
@@ -43,7 +43,6 @@
 extern int  sysctl_discovery_timeout;
 extern int  sysctl_slot_timeout;
 extern int  sysctl_fast_poll_increase;
-int         sysctl_compression = 0;
 extern char sysctl_devname[];
 extern int  sysctl_max_baud_rate;
 extern int  sysctl_min_tx_turn_time;
diff -Nru a/net/irda/irttp.c b/net/irda/irttp.c
--- a/net/irda/irttp.c	2005-03-01 23:38:59 -08:00
+++ b/net/irda/irttp.c	2005-03-01 23:38:59 -08:00
@@ -64,6 +64,10 @@
 static int irttp_param_max_sdu_size(void *instance, irda_param_t *param, 
 				    int get);
 
+static void irttp_flow_indication(void *instance, void *sap, LOCAL_FLOW flow);
+static void irttp_status_indication(void *instance,
+				    LINK_STATUS link, LOCK_STATUS lock);
+
 /* Information for parsing parameters in IrTTP */
 static pi_minor_info_t pi_minor_call_table[] = {
 	{ NULL, 0 },                                             /* 0x00 */
@@ -961,8 +965,8 @@
  *    Status_indication, just pass to the higher layer...
  *
  */
-void irttp_status_indication(void *instance,
-			     LINK_STATUS link, LOCK_STATUS lock)
+static void irttp_status_indication(void *instance,
+				    LINK_STATUS link, LOCK_STATUS lock)
 {
 	struct tsap_cb *self;
 
@@ -993,7 +997,7 @@
  *    Flow_indication : IrLAP tells us to send more data.
  *
  */
-void irttp_flow_indication(void *instance, void *sap, LOCAL_FLOW flow)
+static void irttp_flow_indication(void *instance, void *sap, LOCAL_FLOW flow)
 {
 	struct tsap_cb *self;
 
@@ -1613,7 +1617,7 @@
  *    for some reason should fail. We mark rx sdu as busy to apply back
  *    pressure is necessary.
  */
-void irttp_do_data_indication(struct tsap_cb *self, struct sk_buff *skb)
+static void irttp_do_data_indication(struct tsap_cb *self, struct sk_buff *skb)
 {
 	int err;
 
diff -Nru a/net/irda/parameters.c b/net/irda/parameters.c
--- a/net/irda/parameters.c	2005-03-01 23:39:07 -08:00
+++ b/net/irda/parameters.c	2005-03-01 23:39:07 -08:00
@@ -51,6 +51,8 @@
 static int irda_insert_no_value(void *self, __u8 *buf, int len, __u8 pi,
 				PV_TYPE type, PI_HANDLER func);
 
+static int irda_param_unpack(__u8 *buf, char *fmt, ...);
+
 /* Parameter value call table. Must match PV_TYPE */
 static PV_HANDLER pv_extract_table[] = {
 	irda_extract_integer, /* Handler for any length integers */
@@ -400,7 +402,7 @@
 /*
  * Function irda_param_unpack (skb, fmt, ...)
  */
-int irda_param_unpack(__u8 *buf, char *fmt, ...)
+static int irda_param_unpack(__u8 *buf, char *fmt, ...)
 {
 	irda_pv_t arg;
 	va_list args;
@@ -440,7 +442,6 @@
 
 	return 0;
 }
-EXPORT_SYMBOL(irda_param_unpack);
 
 /*
  * Function irda_param_insert (self, pi, buf, len, info)
@@ -496,13 +497,14 @@
 EXPORT_SYMBOL(irda_param_insert);
 
 /*
- * Function irda_param_extract_all (self, buf, len, info)
+ * Function irda_param_extract (self, buf, len, info)
  *
  *    Parse all parameters. If len is correct, then everything should be
  *    safe. Returns the number of bytes that was parsed
  *
  */
-int irda_param_extract(void *self, __u8 *buf, int len, pi_param_info_t *info)
+static int irda_param_extract(void *self, __u8 *buf, int len,
+			      pi_param_info_t *info)
 {
 	pi_minor_info_t *pi_minor_info;
 	__u8 pi_minor;
@@ -549,7 +551,6 @@
 						  type, pi_minor_info->func);
 	return ret;
 }
-EXPORT_SYMBOL(irda_param_extract);
 
 /*
  * Function irda_param_extract_all (self, buf, len, info)
diff -Nru a/net/irda/qos.c b/net/irda/qos.c
--- a/net/irda/qos.c	2005-03-01 23:39:09 -08:00
+++ b/net/irda/qos.c	2005-03-01 23:39:09 -08:00
@@ -96,6 +96,10 @@
 static int irlap_param_min_turn_time(void *instance, irda_param_t *param, 
 				     int get);
 
+#ifndef CONFIG_IRDA_DYNAMIC_WINDOW
+static __u32 irlap_requested_line_capacity(struct qos_info *qos);
+#endif
+
 static __u32 min_turn_times[]  = { 10000, 5000, 1000, 500, 100, 50, 10, 0 }; /* us */
 static __u32 baud_rates[]      = { 2400, 9600, 19200, 38400, 57600, 115200, 576000, 
 				   1152000, 4000000, 16000000 };           /* bps */
@@ -333,7 +337,7 @@
  *     Adjust QoS settings in case some values are not possible to use because
  *     of other settings
  */
-void irlap_adjust_qos_settings(struct qos_info *qos)
+static void irlap_adjust_qos_settings(struct qos_info *qos)
 {
 	__u32 line_capacity;
 	int index;
@@ -723,19 +727,22 @@
 	return line_capacity;
 }
 
-__u32 irlap_requested_line_capacity(struct qos_info *qos)
-{	__u32 line_capacity;
-	
-	line_capacity = qos->window_size.value * 
+#ifndef CONFIG_IRDA_DYNAMIC_WINDOW
+static __u32 irlap_requested_line_capacity(struct qos_info *qos)
+{
+	__u32 line_capacity;
+
+	line_capacity = qos->window_size.value *
 		(qos->data_size.value + 6 + qos->additional_bofs.value) +
-		irlap_min_turn_time_in_bytes(qos->baud_rate.value, 
+		irlap_min_turn_time_in_bytes(qos->baud_rate.value,
 					     qos->min_turn_time.value);
-	
+
 	IRDA_DEBUG(2, "%s(), requested line capacity=%d\n",
 		   __FUNCTION__, line_capacity);
-	
-	return line_capacity;			       		  
+
+	return line_capacity;
 }
+#endif
 
 void irda_qos_bits_to_value(struct qos_info *qos)
 {
diff -Nru a/net/key/af_key.c b/net/key/af_key.c
--- a/net/key/af_key.c	2005-03-01 23:39:18 -08:00
+++ b/net/key/af_key.c	2005-03-01 23:39:18 -08:00
@@ -35,9 +35,9 @@
 
 
 /* List of all pfkey sockets. */
-HLIST_HEAD(pfkey_table);
+static HLIST_HEAD(pfkey_table);
 static DECLARE_WAIT_QUEUE_HEAD(pfkey_table_wait);
-static rwlock_t pfkey_table_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(pfkey_table_lock);
 static atomic_t pfkey_table_users = ATOMIC_INIT(0);
 
 static atomic_t pfkey_socks_nr = ATOMIC_INIT(0);
@@ -665,18 +665,18 @@
 		sa->sadb_sa_state = SADB_SASTATE_DEAD;
 	sa->sadb_sa_auth = 0;
 	if (x->aalg) {
-		struct xfrm_algo_desc *a = xfrm_aalg_get_byname(x->aalg->alg_name);
+		struct xfrm_algo_desc *a = xfrm_aalg_get_byname(x->aalg->alg_name, 0);
 		sa->sadb_sa_auth = a ? a->desc.sadb_alg_id : 0;
 	}
 	sa->sadb_sa_encrypt = 0;
 	BUG_ON(x->ealg && x->calg);
 	if (x->ealg) {
-		struct xfrm_algo_desc *a = xfrm_ealg_get_byname(x->ealg->alg_name);
+		struct xfrm_algo_desc *a = xfrm_ealg_get_byname(x->ealg->alg_name, 0);
 		sa->sadb_sa_encrypt = a ? a->desc.sadb_alg_id : 0;
 	}
 	/* KAME compatible: sadb_sa_encrypt is overloaded with calg id */
 	if (x->calg) {
-		struct xfrm_algo_desc *a = xfrm_calg_get_byname(x->calg->alg_name);
+		struct xfrm_algo_desc *a = xfrm_calg_get_byname(x->calg->alg_name, 0);
 		sa->sadb_sa_encrypt = a ? a->desc.sadb_alg_id : 0;
 	}
 
@@ -2344,7 +2344,7 @@
 {
 	u32 res;
 	static u32 acqseq;
-	static spinlock_t acqseq_lock = SPIN_LOCK_UNLOCKED;
+	static DEFINE_SPINLOCK(acqseq_lock);
 
 	spin_lock_bh(&acqseq_lock);
 	res = (++acqseq ? : ++acqseq);
diff -Nru a/net/lapb/lapb_iface.c b/net/lapb/lapb_iface.c
--- a/net/lapb/lapb_iface.c	2005-03-01 23:38:56 -08:00
+++ b/net/lapb/lapb_iface.c	2005-03-01 23:38:56 -08:00
@@ -40,7 +40,7 @@
 #include <net/lapb.h>
 
 static struct list_head lapb_list = LIST_HEAD_INIT(lapb_list);
-static rwlock_t lapb_list_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(lapb_list_lock);
 
 /*
  *	Free an allocated lapb control block. 
diff -Nru a/net/llc/llc_c_ac.c b/net/llc/llc_c_ac.c
--- a/net/llc/llc_c_ac.c	2005-03-01 23:39:17 -08:00
+++ b/net/llc/llc_c_ac.c	2005-03-01 23:39:17 -08:00
@@ -33,6 +33,13 @@
 static void llc_process_tmr_ev(struct sock *sk, struct sk_buff *skb);
 static int llc_conn_ac_data_confirm(struct sock *sk, struct sk_buff *ev);
 
+static int llc_conn_ac_inc_npta_value(struct sock *sk, struct sk_buff *skb);
+
+static int llc_conn_ac_send_rr_rsp_f_set_ackpf(struct sock *sk,
+					       struct sk_buff *skb);
+
+static int llc_conn_ac_set_p_flag_1(struct sock *sk, struct sk_buff *skb);
+
 #define INCORRECT 0
 
 int llc_conn_ac_clear_remote_busy(struct sock *sk, struct sk_buff *skb)
@@ -185,11 +192,6 @@
 	return 0;
 }
 
-int llc_conn_ac_report_status(struct sock *sk, struct sk_buff *skb)
-{
-	return 0;
-}
-
 int llc_conn_ac_clear_remote_busy_if_f_eq_1(struct sock *sk,
 					    struct sk_buff *skb)
 {
@@ -291,32 +293,6 @@
 	goto out;
 }
 
-int llc_conn_ac_send_dm_rsp_f_set_f_flag(struct sock *sk, struct sk_buff *skb)
-{
-	int rc = -ENOBUFS;
-	struct sk_buff *nskb = llc_alloc_frame();
-
-	if (nskb) {
-		struct llc_opt *llc = llc_sk(sk);
-		struct llc_sap *sap = llc->sap;
-		u8 f_bit = llc->f_flag;
-
-		nskb->dev = llc->dev;
-		llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
-				    llc->daddr.lsap, LLC_PDU_RSP);
-		llc_pdu_init_as_dm_rsp(nskb, f_bit);
-		rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
-		if (rc)
-			goto free;
-		llc_conn_send_pdu(sk, nskb);
-	}
-out:
-	return rc;
-free:
-	kfree_skb(nskb);
-	goto out;
-}
-
 int llc_conn_ac_send_frmr_rsp_f_set_x(struct sock *sk, struct sk_buff *skb)
 {
 	u8 f_bit;
@@ -426,7 +402,7 @@
 	return rc;
 }
 
-int llc_conn_ac_send_i_cmd_p_set_0(struct sock *sk, struct sk_buff *skb)
+static int llc_conn_ac_send_i_cmd_p_set_0(struct sock *sk, struct sk_buff *skb)
 {
 	int rc;
 	struct llc_opt *llc = llc_sk(sk);
@@ -443,27 +419,6 @@
 	return rc;
 }
 
-int llc_conn_ac_resend_i_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
-{
-	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
-	u8 nr = LLC_I_GET_NR(pdu);
-
-	llc_conn_resend_i_pdu_as_cmd(sk, nr, 1);
-	return 0;
-}
-
-int llc_conn_ac_resend_i_cmd_p_set_1_or_send_rr(struct sock *sk,
-						struct sk_buff *skb)
-{
-	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
-	u8 nr = LLC_I_GET_NR(pdu);
-	int rc = llc_conn_ac_send_rr_cmd_p_set_1(sk, skb);
-
-	if (!rc)
-		llc_conn_resend_i_pdu_as_cmd(sk, nr, 0);
-	return rc;
-}
-
 int llc_conn_ac_send_i_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
 {
 	int rc;
@@ -745,31 +700,6 @@
 	goto out;
 }
 
-int llc_conn_ac_send_ack_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
-{
-	int rc = -ENOBUFS;
-	struct sk_buff *nskb = llc_alloc_frame();
-
-	if (nskb) {
-		struct llc_opt *llc = llc_sk(sk);
-		struct llc_sap *sap = llc->sap;
-
-		nskb->dev = llc->dev;
-		llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
-				    llc->daddr.lsap, LLC_PDU_CMD);
-		llc_pdu_init_as_rr_cmd(nskb, 1, llc->vR);
-		rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
-		if (rc)
-			goto free;
-		llc_conn_send_pdu(sk, nskb);
-	}
-out:
-	return rc;
-free:
-	kfree_skb(nskb);
-	goto out;
-}
-
 int llc_conn_ac_send_rr_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
 {
 	int rc = -ENOBUFS;
@@ -911,31 +841,6 @@
 	goto out;
 }
 
-int llc_conn_ac_send_ua_rsp_f_set_f_flag(struct sock *sk, struct sk_buff *skb)
-{
-	int rc = -ENOBUFS;
-	struct sk_buff *nskb = llc_alloc_frame();
-
-	if (nskb) {
-		struct llc_opt *llc = llc_sk(sk);
-		struct llc_sap *sap = llc->sap;
-
-		nskb->dev = llc->dev;
-		llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
-				    llc->daddr.lsap, LLC_PDU_RSP);
-		llc_pdu_init_as_ua_rsp(nskb, llc->f_flag);
-		rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
-		if (rc)
-			goto free;
-		llc_conn_send_pdu(sk, nskb);
-	}
-out:
-	return rc;
-free:
-	kfree_skb(nskb);
-	goto out;
-}
-
 int llc_conn_ac_send_ua_rsp_f_set_p(struct sock *sk, struct sk_buff *skb)
 {
 	u8 f_bit;
@@ -1041,7 +946,8 @@
  *	set to one if one PDU with p-bit set to one is received.  Returns 0 for
  *	success, 1 otherwise.
  */
-int llc_conn_ac_send_i_rsp_f_set_ackpf(struct sock *sk, struct sk_buff *skb)
+static int llc_conn_ac_send_i_rsp_f_set_ackpf(struct sock *sk,
+					      struct sk_buff *skb)
 {
 	int rc;
 	struct llc_opt *llc = llc_sk(sk);
@@ -1091,7 +997,8 @@
  *	if there is any. ack_pf flag indicates if a PDU has been received with
  *	p-bit set to one. Returns 0 for success, 1 otherwise.
  */
-int llc_conn_ac_send_rr_rsp_f_set_ackpf(struct sock *sk, struct sk_buff *skb)
+static int llc_conn_ac_send_rr_rsp_f_set_ackpf(struct sock *sk,
+					       struct sk_buff *skb)
 {
 	int rc = -ENOBUFS;
 	struct sk_buff *nskb = llc_alloc_frame();
@@ -1126,7 +1033,7 @@
  *	acknowledgements decreases by increasing of "npta". Returns 0 for
  *	success, 1 otherwise.
  */
-int llc_conn_ac_inc_npta_value(struct sock *sk, struct sk_buff *skb)
+static int llc_conn_ac_inc_npta_value(struct sock *sk, struct sk_buff *skb)
 {
 	struct llc_opt *llc = llc_sk(sk);
 
@@ -1387,7 +1294,7 @@
 	return 0;
 }
 
-int llc_conn_ac_set_p_flag_1(struct sock *sk, struct sk_buff *skb)
+static int llc_conn_ac_set_p_flag_1(struct sock *sk, struct sk_buff *skb)
 {
 	llc_conn_set_p_flag(sk, 1);
 	return 0;
@@ -1450,12 +1357,6 @@
 int llc_conn_ac_inc_vs_by_1(struct sock *sk, struct sk_buff *skb)
 {
 	llc_sk(sk)->vS = (llc_sk(sk)->vS + 1) % 128;
-	return 0;
-}
-
-int llc_conn_ac_set_f_flag_p(struct sock *sk, struct sk_buff *skb)
-{
-	llc_pdu_decode_pf_bit(skb, &llc_sk(sk)->f_flag);
 	return 0;
 }
 
diff -Nru a/net/llc/llc_c_ev.c b/net/llc/llc_c_ev.c
--- a/net/llc/llc_c_ev.c	2005-03-01 23:38:52 -08:00
+++ b/net/llc/llc_c_ev.c	2005-03-01 23:38:52 -08:00
@@ -105,14 +105,6 @@
 	       ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
 }
 
-int llc_conn_ev_conn_resp(struct sock *sk, struct sk_buff *skb)
-{
-	struct llc_conn_state_ev *ev = llc_conn_ev(skb);
-
-	return ev->prim == LLC_CONN_PRIM &&
-	       ev->prim_type == LLC_PRIM_TYPE_RESP ? 0 : 1;
-}
-
 int llc_conn_ev_data_req(struct sock *sk, struct sk_buff *skb)
 {
 	struct llc_conn_state_ev *ev = llc_conn_ev(skb);
@@ -137,14 +129,6 @@
 	       ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
 }
 
-int llc_conn_ev_rst_resp(struct sock *sk, struct sk_buff *skb)
-{
-	struct llc_conn_state_ev *ev = llc_conn_ev(skb);
-
-	return ev->prim == LLC_RESET_PRIM &&
-	       ev->prim_type == LLC_PRIM_TYPE_RESP ? 0 : 1;
-}
-
 int llc_conn_ev_local_busy_detected(struct sock *sk, struct sk_buff *skb)
 {
 	struct llc_conn_state_ev *ev = llc_conn_ev(skb);
@@ -474,27 +458,6 @@
 	return rc;
 }
 
-int llc_conn_ev_rx_xxx_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb)
-{
-	u16 rc = 1;
-	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
-
-	if (LLC_PDU_IS_CMD(pdu)) {
-		if (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu)) {
-			if (LLC_I_PF_IS_0(pdu))
-				rc = 0;
-		} else if (LLC_PDU_TYPE_IS_U(pdu))
-			switch (LLC_U_PDU_CMD(pdu)) {
-			case LLC_2_PDU_CMD_SABME:
-			case LLC_2_PDU_CMD_DISC:
-				if (LLC_U_PF_IS_0(pdu))
-					rc = 0;
-				break;
-			}
-	}
-	return rc;
-}
-
 int llc_conn_ev_rx_xxx_cmd_pbit_set_x(struct sock *sk, struct sk_buff *skb)
 {
 	u16 rc = 1;
@@ -557,26 +520,6 @@
 	return rc;
 }
 
-int llc_conn_ev_rx_xxx_yyy(struct sock *sk, struct sk_buff *skb)
-{
-	u16 rc = 1;
-	struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
-
-	if (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu))
-		rc = 0;
-	else if (LLC_PDU_TYPE_IS_U(pdu))
-		switch (LLC_U_PDU_CMD(pdu)) {
-		case LLC_2_PDU_CMD_SABME:
-		case LLC_2_PDU_CMD_DISC:
-		case LLC_2_PDU_RSP_UA:
-		case LLC_2_PDU_RSP_DM:
-		case LLC_2_PDU_RSP_FRMR:
-			rc = 0;
-			break;
-		}
-	return rc;
-}
-
 int llc_conn_ev_rx_zzz_cmd_pbit_set_x_inval_nr(struct sock *sk,
 					       struct sk_buff *skb)
 {
@@ -646,16 +589,6 @@
 	return ev->type != LLC_CONN_EV_TYPE_BUSY_TMR;
 }
 
-int llc_conn_ev_any_tmr_exp(struct sock *sk, struct sk_buff *skb)
-{
-	struct llc_conn_state_ev *ev = llc_conn_ev(skb);
-
-	return ev->type == LLC_CONN_EV_TYPE_P_TMR ||
-	       ev->type == LLC_CONN_EV_TYPE_ACK_TMR ||
-	       ev->type == LLC_CONN_EV_TYPE_REJ_TMR ||
-	       ev->type == LLC_CONN_EV_TYPE_BUSY_TMR ? 0 : 1;
-}
-
 int llc_conn_ev_init_p_f_cycle(struct sock *sk, struct sk_buff *skb)
 {
 	return 1;
@@ -778,11 +711,6 @@
 	return llc_sk(sk)->cause_flag;
 }
 
-int llc_conn_ev_qlfy_init_p_f_cycle(struct sock *sk, struct sk_buff *skb)
-{
-	return 0;
-}
-
 int llc_conn_ev_qlfy_set_status_conn(struct sock *sk, struct sk_buff *skb)
 {
 	struct llc_conn_state_ev *ev = llc_conn_ev(skb);
@@ -799,14 +727,6 @@
 	return 0;
 }
 
-int llc_conn_ev_qlfy_set_status_impossible(struct sock *sk, struct sk_buff *skb)
-{
-	struct llc_conn_state_ev *ev = llc_conn_ev(skb);
-
-	ev->status = LLC_STATUS_IMPOSSIBLE;
-	return 0;
-}
-
 int llc_conn_ev_qlfy_set_status_failed(struct sock *sk, struct sk_buff *skb)
 {
 	struct llc_conn_state_ev *ev = llc_conn_ev(skb);
@@ -821,14 +741,6 @@
 	struct llc_conn_state_ev *ev = llc_conn_ev(skb);
 
 	ev->status = LLC_STATUS_REMOTE_BUSY;
-	return 0;
-}
-
-int llc_conn_ev_qlfy_set_status_received(struct sock *sk, struct sk_buff *skb)
-{
-	struct llc_conn_state_ev *ev = llc_conn_ev(skb);
-
-	ev->status = LLC_STATUS_RECEIVED;
 	return 0;
 }
 
diff -Nru a/net/llc/llc_conn.c b/net/llc/llc_conn.c
--- a/net/llc/llc_conn.c	2005-03-01 23:38:52 -08:00
+++ b/net/llc/llc_conn.c	2005-03-01 23:38:52 -08:00
@@ -503,7 +503,8 @@
  *	local mac, and local sap. Returns pointer for parent socket found,
  *	%NULL otherwise.
  */
-struct sock *llc_lookup_listener(struct llc_sap *sap, struct llc_addr *laddr)
+static struct sock *llc_lookup_listener(struct llc_sap *sap,
+					struct llc_addr *laddr)
 {
 	struct sock *rc;
 	struct hlist_node *node;
@@ -546,7 +547,7 @@
  *	Finds offset of next category of transitions in transition table.
  *	Returns the start index of next category.
  */
-u16 find_next_offset(struct llc_conn_state *state, u16 offset)
+static u16 find_next_offset(struct llc_conn_state *state, u16 offset)
 {
 	u16 cnt = 0;
 	struct llc_conn_state_trans **next_trans;
@@ -785,7 +786,7 @@
  *
  *     Initializes a socket with default llc values.
  */
-int llc_sk_init(struct sock* sk)
+static int llc_sk_init(struct sock* sk)
 {
 	struct llc_opt *llc = kmalloc(sizeof(*llc), GFP_ATOMIC);
 	int rc = -ENOMEM;
diff -Nru a/net/llc/llc_core.c b/net/llc/llc_core.c
--- a/net/llc/llc_core.c	2005-03-01 23:38:44 -08:00
+++ b/net/llc/llc_core.c	2005-03-01 23:38:44 -08:00
@@ -22,7 +22,7 @@
 #include <net/llc.h>
 
 LIST_HEAD(llc_sap_list);
-rwlock_t llc_sap_list_lock = RW_LOCK_UNLOCKED;
+DEFINE_RWLOCK(llc_sap_list_lock);
 
 unsigned char llc_station_mac_sa[ETH_ALEN];
 
@@ -31,7 +31,7 @@
  *
  *	Allocates and initializes sap.
  */
-struct llc_sap *llc_sap_alloc(void)
+static struct llc_sap *llc_sap_alloc(void)
 {
 	struct llc_sap *sap = kmalloc(sizeof(*sap), GFP_ATOMIC);
 
@@ -50,7 +50,7 @@
  *
  *	Adds a sap to the LLC's station sap list.
  */
-void llc_add_sap(struct llc_sap *sap)
+static void llc_add_sap(struct llc_sap *sap)
 {
 	write_lock_bh(&llc_sap_list_lock);
 	list_add_tail(&sap->node, &llc_sap_list);
@@ -63,7 +63,7 @@
  *
  *	Removes a sap to the LLC's station sap list.
  */
-void llc_del_sap(struct llc_sap *sap)
+static void llc_del_sap(struct llc_sap *sap)
 {
 	write_lock_bh(&llc_sap_list_lock);
 	list_del(&sap->node);
diff -Nru a/net/llc/llc_if.c b/net/llc/llc_if.c
--- a/net/llc/llc_if.c	2005-03-01 23:38:57 -08:00
+++ b/net/llc/llc_if.c	2005-03-01 23:38:57 -08:00
@@ -155,27 +155,3 @@
 	return rc;
 }
 
-/**
- *	llc_build_and_send_reset_pkt - Resets an established LLC connection
- *	@prim: pointer to structure that contains service parameters.
- *
- *	Called when upper layer wants to reset an established LLC connection
- *	with a remote machine. This function packages a proper event and sends
- *	it to connection component state machine. Returns 0 for success, 1
- *	otherwise.
- */
-int llc_build_and_send_reset_pkt(struct sock *sk)
-{
-	int rc = 1;
-	struct sk_buff *skb = alloc_skb(0, GFP_ATOMIC);
-
-	if (skb) {
-		struct llc_conn_state_ev *ev = llc_conn_ev(skb);
-
-		ev->type      = LLC_CONN_EV_TYPE_PRIM;
-		ev->prim      = LLC_RESET_PRIM;
-		ev->prim_type = LLC_PRIM_TYPE_REQ;
-		rc = llc_conn_state_process(sk, skb);
-	}
-	return rc;
-}
diff -Nru a/net/llc/llc_pdu.c b/net/llc/llc_pdu.c
--- a/net/llc/llc_pdu.c	2005-03-01 23:38:53 -08:00
+++ b/net/llc/llc_pdu.c	2005-03-01 23:38:53 -08:00
@@ -80,19 +80,6 @@
 }
 
 /**
- *	llc_pdu_decode_cr_bit - extracts command response bit from LLC header
- *	@skb: input skb that c/r bit must be extracted from it.
- *	@cr_bit: command/response bit (0 or 1).
- *
- *	This function extracts command/response bit from LLC header. this bit
- *	is right bit of source SAP.
- */
-void llc_pdu_decode_cr_bit(struct sk_buff *skb, u8 *cr_bit)
-{
-	*cr_bit = llc_pdu_un_hdr(skb)->ssap & LLC_PDU_CMD_RSP_MASK;
-}
-
-/**
  *	llc_pdu_init_as_disc_cmd - Builds DISC PDU
  *	@skb: Address of the skb to build
  *	@p_bit: The P bit to set in the PDU
diff -Nru a/net/llc/llc_proc.c b/net/llc/llc_proc.c
--- a/net/llc/llc_proc.c	2005-03-01 23:38:52 -08:00
+++ b/net/llc/llc_proc.c	2005-03-01 23:38:52 -08:00
@@ -185,14 +185,14 @@
 	return 0;
 }
 
-struct seq_operations llc_seq_socket_ops = {
+static struct seq_operations llc_seq_socket_ops = {
 	.start  = llc_seq_start,
 	.next   = llc_seq_next,
 	.stop   = llc_seq_stop,
 	.show   = llc_seq_socket_show,
 };
 
-struct seq_operations llc_seq_core_ops = {
+static struct seq_operations llc_seq_core_ops = {
 	.start  = llc_seq_start,
 	.next   = llc_seq_next,
 	.stop   = llc_seq_stop,
diff -Nru a/net/llc/llc_sap.c b/net/llc/llc_sap.c
--- a/net/llc/llc_sap.c	2005-03-01 23:39:08 -08:00
+++ b/net/llc/llc_sap.c	2005-03-01 23:39:08 -08:00
@@ -173,7 +173,7 @@
  *	if needed(on receiving an UI frame). sk can be null for the
  *	datalink_proto case.
  */
-void llc_sap_state_process(struct llc_sap *sap, struct sk_buff *skb)
+static void llc_sap_state_process(struct llc_sap *sap, struct sk_buff *skb)
 {
 	struct llc_sap_state_ev *ev = llc_sap_ev(skb);
 
@@ -275,7 +275,8 @@
  *	Search socket list of the SAP and finds connection using the local
  *	mac, and local sap. Returns pointer for socket found, %NULL otherwise.
  */
-struct sock *llc_lookup_dgram(struct llc_sap *sap, struct llc_addr *laddr)
+static struct sock *llc_lookup_dgram(struct llc_sap *sap,
+				     struct llc_addr *laddr)
 {
 	struct sock *rc;
 	struct hlist_node *node;
diff -Nru a/net/llc/llc_station.c b/net/llc/llc_station.c
--- a/net/llc/llc_station.c	2005-03-01 23:38:55 -08:00
+++ b/net/llc/llc_station.c	2005-03-01 23:38:55 -08:00
@@ -642,7 +642,7 @@
  *	Queues an event (on the station event queue) for handling by the
  *	station state machine and attempts to process any queued-up events.
  */
-void llc_station_state_process(struct sk_buff *skb)
+static void llc_station_state_process(struct sk_buff *skb)
 {
 	spin_lock_bh(&llc_main_station.ev_q.lock);
 	skb_queue_tail(&llc_main_station.ev_q.list, skb);
diff -Nru a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
--- a/net/netlink/af_netlink.c	2005-03-01 23:38:57 -08:00
+++ b/net/netlink/af_netlink.c	2005-03-01 23:38:57 -08:00
@@ -91,21 +91,17 @@
 struct netlink_table {
 	struct nl_pid_hash hash;
 	struct hlist_head mc_list;
+	unsigned int nl_nonroot;
 };
 
 static struct netlink_table *nl_table;
 
 static DECLARE_WAIT_QUEUE_HEAD(nl_table_wait);
-static unsigned int nl_nonroot[MAX_LINKS];
-
-#ifdef NL_EMULATE_DEV
-static struct socket *netlink_kernel[MAX_LINKS];
-#endif
 
 static int netlink_dump(struct sock *sk);
 static void netlink_destroy_callback(struct netlink_callback *cb);
 
-static rwlock_t nl_table_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(nl_table_lock);
 static atomic_t nl_table_users = ATOMIC_INIT(0);
 
 static struct notifier_block *netlink_chain;
@@ -442,7 +438,7 @@
 
 static inline int netlink_capable(struct socket *sock, unsigned int flag) 
 { 
-	return (nl_nonroot[sock->sk->sk_protocol] & flag) ||
+	return (nl_table[sock->sk->sk_protocol].nl_nonroot & flag) ||
 	       capable(CAP_NET_ADMIN);
 } 
 
@@ -546,7 +542,7 @@
 	}
 }
 
-struct sock *netlink_getsockbypid(struct sock *ssk, u32 pid)
+static struct sock *netlink_getsockbypid(struct sock *ssk, u32 pid)
 {
 	int protocol = ssk->sk_protocol;
 	struct sock *sock;
@@ -633,7 +629,6 @@
 		}
 		return 1;
 	}
-	skb_orphan(skb);
 	skb_set_owner_r(skb, sk);
 	return 0;
 }
@@ -665,21 +660,28 @@
 	sock_put(sk);
 }
 
-static inline void netlink_trim(struct sk_buff *skb, int allocation)
+static inline struct sk_buff *netlink_trim(struct sk_buff *skb, int allocation)
 {
-	int delta = skb->end - skb->tail;
+	int delta;
 
-	/* If the packet is charged to a socket, the modification
-	 * of truesize below is illegal and will corrupt socket
-	 * buffer accounting state.
-	 */
-	BUG_ON(skb->list != NULL);
+	skb_orphan(skb);
 
+	delta = skb->end - skb->tail;
 	if (delta * 2 < skb->truesize)
-		return;
-	if (pskb_expand_head(skb, 0, -delta, allocation))
-		return;
-	skb->truesize -= delta;
+		return skb;
+
+	if (skb_shared(skb)) {
+		struct sk_buff *nskb = skb_clone(skb, allocation);
+		if (!nskb)
+			return skb;
+		kfree_skb(skb);
+		skb = nskb;
+	}
+
+	if (!pskb_expand_head(skb, 0, -delta, allocation))
+		skb->truesize -= delta;
+
+	return skb;
 }
 
 int netlink_unicast(struct sock *ssk, struct sk_buff *skb, u32 pid, int nonblock)
@@ -688,7 +690,7 @@
 	int err;
 	long timeo;
 
-	netlink_trim(skb, gfp_any());
+	skb = netlink_trim(skb, gfp_any());
 
 	timeo = sock_sndtimeo(ssk, nonblock);
 retry:
@@ -711,14 +713,12 @@
 	struct netlink_opt *nlk = nlk_sk(sk);
 #ifdef NL_EMULATE_DEV
 	if (nlk->handler) {
-		skb_orphan(skb);
 		nlk->handler(sk->sk_protocol, skb);
 		return 0;
 	} else
 #endif
 	if (atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf &&
 	    !test_bit(0, &nlk->state)) {
-                skb_orphan(skb);
 		skb_set_owner_r(skb, sk);
 		skb_queue_tail(&sk->sk_receive_queue, skb);
 		sk->sk_data_ready(sk, skb->len);
@@ -788,6 +788,8 @@
 	struct hlist_node *node;
 	struct sock *sk;
 
+	skb = netlink_trim(skb, allocation);
+
 	info.exclude_sk = ssk;
 	info.pid = pid;
 	info.group = group;
@@ -798,8 +800,6 @@
 	info.skb = skb;
 	info.skb2 = NULL;
 
-	netlink_trim(skb, allocation);
-
 	/* While we sleep in clone, do not allow to change socket list */
 
 	netlink_lock_table();
@@ -1066,7 +1066,7 @@
 void netlink_set_nonroot(int protocol, unsigned int flags)
 { 
 	if ((unsigned int)protocol < MAX_LINKS) 
-		nl_nonroot[protocol] = flags;
+		nl_table[protocol].nl_nonroot = flags;
 } 
 
 static void netlink_destroy_callback(struct netlink_callback *cb)
@@ -1202,61 +1202,6 @@
 }
 
 
-#ifdef NL_EMULATE_DEV
-
-static rwlock_t nl_emu_lock = RW_LOCK_UNLOCKED;
-
-/*
- *	Backward compatibility.
- */	
- 
-int netlink_attach(int unit, int (*function)(int, struct sk_buff *skb))
-{
-	struct sock *sk = netlink_kernel_create(unit, NULL);
-	if (sk == NULL)
-		return -ENOBUFS;
-	nlk_sk(sk)->handler = function;
-	write_lock_bh(&nl_emu_lock);
-	netlink_kernel[unit] = sk->sk_socket;
-	write_unlock_bh(&nl_emu_lock);
-	return 0;
-}
-
-void netlink_detach(int unit)
-{
-	struct socket *sock;
-
-	write_lock_bh(&nl_emu_lock);
-	sock = netlink_kernel[unit];
-	netlink_kernel[unit] = NULL;
-	write_unlock_bh(&nl_emu_lock);
-
-	sock_release(sock);
-}
-
-int netlink_post(int unit, struct sk_buff *skb)
-{
-	struct socket *sock;
-
-	read_lock(&nl_emu_lock);
-	sock = netlink_kernel[unit];
-	if (sock) {
-		struct sock *sk = sock->sk;
-		memset(skb->cb, 0, sizeof(skb->cb));
-		sock_hold(sk);
-		read_unlock(&nl_emu_lock);
-
-		netlink_broadcast(sk, skb, 0, ~0, GFP_ATOMIC);
-
-		sock_put(sk);
-		return 0;
-	}
-	read_unlock(&nl_emu_lock);
-	return -EUNATCH;
-}
-
-#endif
-
 #ifdef CONFIG_PROC_FS
 struct nl_seq_iter {
 	int link;
@@ -1521,8 +1466,3 @@
 EXPORT_SYMBOL(netlink_unicast);
 EXPORT_SYMBOL(netlink_unregister_notifier);
 
-#if defined(CONFIG_NETLINK_DEV) || defined(CONFIG_NETLINK_DEV_MODULE)
-EXPORT_SYMBOL(netlink_attach);
-EXPORT_SYMBOL(netlink_detach);
-EXPORT_SYMBOL(netlink_post);
-#endif
diff -Nru a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c
--- a/net/netrom/af_netrom.c	2005-03-01 23:38:57 -08:00
+++ b/net/netrom/af_netrom.c	2005-03-01 23:38:57 -08:00
@@ -43,7 +43,7 @@
 #include <net/arp.h>
 #include <linux/init.h>
 
-int nr_ndevs = 4;
+static int nr_ndevs = 4;
 
 int sysctl_netrom_default_path_quality            = NR_DEFAULT_QUAL;
 int sysctl_netrom_obsolescence_count_initialiser  = NR_DEFAULT_OBS;
@@ -60,7 +60,7 @@
 static unsigned short circuit = 0x101;
 
 static HLIST_HEAD(nr_list);
-static spinlock_t nr_list_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(nr_list_lock);
 
 static struct proto_ops nr_proto_ops;
 void nr_init_timers(struct sock *sk);
diff -Nru a/net/netrom/nr_dev.c b/net/netrom/nr_dev.c
--- a/net/netrom/nr_dev.c	2005-03-01 23:39:16 -08:00
+++ b/net/netrom/nr_dev.c	2005-03-01 23:39:16 -08:00
@@ -46,7 +46,7 @@
 
 int nr_rx_ip(struct sk_buff *skb, struct net_device *dev)
 {
-	struct net_device_stats *stats = (struct net_device_stats *)dev->priv;
+	struct net_device_stats *stats = netdev_priv(dev);
 
 	if (!netif_running(dev)) {
 		stats->rx_errors++;
@@ -73,7 +73,7 @@
 static int nr_rebuild_header(struct sk_buff *skb)
 {
 	struct net_device *dev = skb->dev;
-	struct net_device_stats *stats = (struct net_device_stats *)dev->priv;
+	struct net_device_stats *stats = netdev_priv(dev);
 	struct sk_buff *skbn;
 	unsigned char *bp = skb->data;
 	int len;
@@ -186,7 +186,7 @@
 
 static int nr_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-	struct net_device_stats *stats = (struct net_device_stats *)dev->priv;
+	struct net_device_stats *stats = netdev_priv(dev);
 	dev_kfree_skb(skb);
 	stats->tx_errors++;
 	return 0;
@@ -194,7 +194,7 @@
 
 static struct net_device_stats *nr_get_stats(struct net_device *dev)
 {
-	return (struct net_device_stats *)dev->priv;
+	return netdev_priv(dev);
 }
 
 void nr_setup(struct net_device *dev)
diff -Nru a/net/netrom/nr_route.c b/net/netrom/nr_route.c
--- a/net/netrom/nr_route.c	2005-03-01 23:39:17 -08:00
+++ b/net/netrom/nr_route.c	2005-03-01 23:39:17 -08:00
@@ -41,11 +41,11 @@
 static unsigned int nr_neigh_no = 1;
 
 static HLIST_HEAD(nr_node_list);
-static spinlock_t nr_node_list_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(nr_node_list_lock);
 static HLIST_HEAD(nr_neigh_list);
-static spinlock_t nr_neigh_list_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(nr_neigh_list_lock);
 
-struct nr_node *nr_node_get(ax25_address *callsign)
+static struct nr_node *nr_node_get(ax25_address *callsign)
 {
 	struct nr_node *found = NULL;
 	struct nr_node *nr_node;
@@ -62,7 +62,8 @@
 	return found;
 }
 
-struct nr_neigh *nr_neigh_get_dev(ax25_address *callsign, struct net_device *dev)
+static struct nr_neigh *nr_neigh_get_dev(ax25_address *callsign,
+					 struct net_device *dev)
 {
 	struct nr_neigh *found = NULL;
 	struct nr_neigh *nr_neigh;
diff -Nru a/net/packet/af_packet.c b/net/packet/af_packet.c
--- a/net/packet/af_packet.c	2005-03-01 23:39:07 -08:00
+++ b/net/packet/af_packet.c	2005-03-01 23:39:07 -08:00
@@ -145,10 +145,10 @@
  */
 
 /* List of all packet sockets. */
-HLIST_HEAD(packet_sklist);
-static rwlock_t packet_sklist_lock = RW_LOCK_UNLOCKED;
+static HLIST_HEAD(packet_sklist);
+static DEFINE_RWLOCK(packet_sklist_lock);
 
-atomic_t packet_socks_nr;
+static atomic_t packet_socks_nr;
 
 
 /* Private packet socket structures. */
@@ -215,7 +215,7 @@
 
 #define pkt_sk(__sk) ((struct packet_opt *)(__sk)->sk_protinfo)
 
-void packet_sock_destruct(struct sock *sk)
+static void packet_sock_destruct(struct sock *sk)
 {
 	BUG_TRAP(!atomic_read(&sk->sk_rmem_alloc));
 	BUG_TRAP(!atomic_read(&sk->sk_wmem_alloc));
@@ -234,10 +234,10 @@
 }
 
 
-extern struct proto_ops packet_ops;
+static struct proto_ops packet_ops;
 
 #ifdef CONFIG_SOCK_PACKET
-extern struct proto_ops packet_ops_spkt;
+static struct proto_ops packet_ops_spkt;
 
 static int packet_rcv_spkt(struct sk_buff *skb, struct net_device *dev,  struct packet_type *pt)
 {
@@ -1350,8 +1350,8 @@
 	}
 }
 
-int packet_getsockopt(struct socket *sock, int level, int optname,
-		      char __user *optval, int __user *optlen)
+static int packet_getsockopt(struct socket *sock, int level, int optname,
+			     char __user *optval, int __user *optlen)
 {
 	int len;
 	struct sock *sk = sock->sk;
@@ -1500,7 +1500,8 @@
 #define packet_poll datagram_poll
 #else
 
-unsigned int packet_poll(struct file * file, struct socket *sock, poll_table *wait)
+static unsigned int packet_poll(struct file * file, struct socket *sock,
+				poll_table *wait)
 {
 	struct sock *sk = sock->sk;
 	struct packet_opt *po = pkt_sk(sk);
@@ -1747,7 +1748,7 @@
 
 
 #ifdef CONFIG_SOCK_PACKET
-struct proto_ops packet_ops_spkt = {
+static struct proto_ops packet_ops_spkt = {
 	.family =	PF_PACKET,
 	.owner =	THIS_MODULE,
 	.release =	packet_release,
@@ -1769,7 +1770,7 @@
 };
 #endif
 
-struct proto_ops packet_ops = {
+static struct proto_ops packet_ops = {
 	.family =	PF_PACKET,
 	.owner =	THIS_MODULE,
 	.release =	packet_release,
diff -Nru a/net/rose/af_rose.c b/net/rose/af_rose.c
--- a/net/rose/af_rose.c	2005-03-01 23:38:57 -08:00
+++ b/net/rose/af_rose.c	2005-03-01 23:38:57 -08:00
@@ -59,7 +59,7 @@
 int sysctl_rose_window_size             = ROSE_DEFAULT_WINDOW_SIZE;
 
 static HLIST_HEAD(rose_list);
-spinlock_t rose_list_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(rose_list_lock);
 
 static struct proto_ops rose_proto_ops;
 
diff -Nru a/net/rose/rose_dev.c b/net/rose/rose_dev.c
--- a/net/rose/rose_dev.c	2005-03-01 23:38:53 -08:00
+++ b/net/rose/rose_dev.c	2005-03-01 23:38:53 -08:00
@@ -37,38 +37,6 @@
 #include <net/ax25.h>
 #include <net/rose.h>
 
-/*
- *	Only allow IP over ROSE frames through if the netrom device is up.
- */
-
-int rose_rx_ip(struct sk_buff *skb, struct net_device *dev)
-{
-	struct net_device_stats *stats = (struct net_device_stats *)dev->priv;
-
-#ifdef CONFIG_INET
-	if (!netif_running(dev)) {
-		stats->rx_errors++;
-		return 0;
-	}
-
-	stats->rx_packets++;
-	stats->rx_bytes += skb->len;
-
-	skb->protocol = htons(ETH_P_IP);
-
-	/* Spoof incoming device */
-	skb->dev      = dev;
-	skb->h.raw    = skb->data;
-	skb->nh.raw   = skb->data;
-	skb->pkt_type = PACKET_HOST;
-
-	ip_rcv(skb, skb->dev, NULL);
-#else
-	kfree_skb(skb);
-#endif
-	return 1;
-}
-
 static int rose_header(struct sk_buff *skb, struct net_device *dev, unsigned short type,
 	void *daddr, void *saddr, unsigned len)
 {
@@ -89,7 +57,7 @@
 static int rose_rebuild_header(struct sk_buff *skb)
 {
 	struct net_device *dev = skb->dev;
-	struct net_device_stats *stats = (struct net_device_stats *)dev->priv;
+	struct net_device_stats *stats = netdev_priv(dev);
 	unsigned char *bp = (unsigned char *)skb->data;
 	struct sk_buff *skbn;
 
@@ -149,7 +117,7 @@
 
 static int rose_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-	struct net_device_stats *stats = (struct net_device_stats *)dev->priv;
+	struct net_device_stats *stats = netdev_priv(dev);
 
 	if (!netif_running(dev)) {
 		printk(KERN_ERR "ROSE: rose_xmit - called when iface is down\n");
@@ -162,7 +130,7 @@
 
 static struct net_device_stats *rose_get_stats(struct net_device *dev)
 {
-	return (struct net_device_stats *)dev->priv;
+	return netdev_priv(dev);
 }
 
 void rose_setup(struct net_device *dev)
diff -Nru a/net/rose/rose_link.c b/net/rose/rose_link.c
--- a/net/rose/rose_link.c	2005-03-01 23:38:58 -08:00
+++ b/net/rose/rose_link.c	2005-03-01 23:38:58 -08:00
@@ -31,6 +31,9 @@
 static void rose_ftimer_expiry(unsigned long);
 static void rose_t0timer_expiry(unsigned long);
 
+static void rose_transmit_restart_confirmation(struct rose_neigh *neigh);
+static void rose_transmit_restart_request(struct rose_neigh *neigh);
+
 void rose_start_ftimer(struct rose_neigh *neigh)
 {
 	del_timer(&neigh->ftimer);
@@ -42,7 +45,7 @@
 	add_timer(&neigh->ftimer);
 }
 
-void rose_start_t0timer(struct rose_neigh *neigh)
+static void rose_start_t0timer(struct rose_neigh *neigh)
 {
 	del_timer(&neigh->t0timer);
 
@@ -68,7 +71,7 @@
 	return timer_pending(&neigh->ftimer);
 }
 
-int rose_t0timer_running(struct rose_neigh *neigh)
+static int rose_t0timer_running(struct rose_neigh *neigh)
 {
 	return timer_pending(&neigh->t0timer);
 }
@@ -165,7 +168,7 @@
 /*
  *	This routine is called when a Restart Request is needed
  */
-void rose_transmit_restart_request(struct rose_neigh *neigh)
+static void rose_transmit_restart_request(struct rose_neigh *neigh)
 {
 	struct sk_buff *skb;
 	unsigned char *dptr;
@@ -194,7 +197,7 @@
 /*
  * This routine is called when a Restart Confirmation is needed
  */
-void rose_transmit_restart_confirmation(struct rose_neigh *neigh)
+static void rose_transmit_restart_confirmation(struct rose_neigh *neigh)
 {
 	struct sk_buff *skb;
 	unsigned char *dptr;
@@ -213,34 +216,6 @@
 	*dptr++ = ROSE_GFI;
 	*dptr++ = 0x00;
 	*dptr++ = ROSE_RESTART_CONFIRMATION;
-
-	if (!rose_send_frame(skb, neigh))
-		kfree_skb(skb);
-}
-
-/*
- * This routine is called when a Diagnostic is required.
- */
-void rose_transmit_diagnostic(struct rose_neigh *neigh, unsigned char diag)
-{
-	struct sk_buff *skb;
-	unsigned char *dptr;
-	int len;
-
-	len = AX25_BPQ_HEADER_LEN + AX25_MAX_HEADER_LEN + ROSE_MIN_LEN + 2;
-
-	if ((skb = alloc_skb(len, GFP_ATOMIC)) == NULL)
-		return;
-
-	skb_reserve(skb, AX25_BPQ_HEADER_LEN + AX25_MAX_HEADER_LEN);
-
-	dptr = skb_put(skb, ROSE_MIN_LEN + 2);
-
-	*dptr++ = AX25_P_ROSE;
-	*dptr++ = ROSE_GFI;
-	*dptr++ = 0x00;
-	*dptr++ = ROSE_DIAGNOSTIC;
-	*dptr++ = diag;
 
 	if (!rose_send_frame(skb, neigh))
 		kfree_skb(skb);
diff -Nru a/net/rose/rose_route.c b/net/rose/rose_route.c
--- a/net/rose/rose_route.c	2005-03-01 23:39:17 -08:00
+++ b/net/rose/rose_route.c	2005-03-01 23:39:17 -08:00
@@ -40,11 +40,11 @@
 static unsigned int rose_neigh_no = 1;
 
 static struct rose_node  *rose_node_list;
-static spinlock_t rose_node_list_lock = SPIN_LOCK_UNLOCKED;
-struct rose_neigh *rose_neigh_list;
-static spinlock_t rose_neigh_list_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(rose_node_list_lock);
+static struct rose_neigh *rose_neigh_list;
+static DEFINE_SPINLOCK(rose_neigh_list_lock);
 static struct rose_route *rose_route_list;
-static spinlock_t rose_route_list_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(rose_route_list_lock);
 
 struct rose_neigh *rose_loopback_neigh;
 
@@ -587,7 +587,7 @@
 /*
  *	Check that the device given is a valid AX.25 interface that is "up".
  */
-struct net_device *rose_ax25_dev_get(char *devname)
+static struct net_device *rose_ax25_dev_get(char *devname)
 {
 	struct net_device *dev;
 
diff -Nru a/net/rose/rose_subr.c b/net/rose/rose_subr.c
--- a/net/rose/rose_subr.c	2005-03-01 23:39:17 -08:00
+++ b/net/rose/rose_subr.c	2005-03-01 23:39:17 -08:00
@@ -28,6 +28,8 @@
 #include <linux/interrupt.h>
 #include <net/rose.h>
 
+static int rose_create_facilities(unsigned char *buffer, rose_cb *rose);
+
 /*
  *	This routine purges all of the queues of frames.
  */
@@ -394,7 +396,7 @@
 	return 1;
 }
 
-int rose_create_facilities(unsigned char *buffer, rose_cb *rose)
+static int rose_create_facilities(unsigned char *buffer, rose_cb *rose)
 {
 	unsigned char *p = buffer + 1;
 	char *callsign;
diff -Nru a/net/rxrpc/call.c b/net/rxrpc/call.c
--- a/net/rxrpc/call.c	2005-03-01 23:39:09 -08:00
+++ b/net/rxrpc/call.c	2005-03-01 23:39:09 -08:00
@@ -26,10 +26,10 @@
 LIST_HEAD(rxrpc_calls);
 DECLARE_RWSEM(rxrpc_calls_sem);
 
-unsigned rxrpc_call_rcv_timeout		= HZ/3;
-unsigned rxrpc_call_acks_timeout	= HZ/3;
-unsigned rxrpc_call_dfr_ack_timeout	= HZ/20;
-unsigned short rxrpc_call_max_resend	= HZ/10;
+unsigned rxrpc_call_rcv_timeout			= HZ/3;
+static unsigned rxrpc_call_acks_timeout		= HZ/3;
+static unsigned rxrpc_call_dfr_ack_timeout	= HZ/20;
+static unsigned short rxrpc_call_max_resend	= HZ/10;
 
 const char *rxrpc_call_states[] = {
 	"COMPLETE",
@@ -58,7 +58,7 @@
 	"?09", "?10", "?11", "?12", "?13", "?14", "?15"
 };
 
-const char *rxrpc_acks[] = {
+static const char *rxrpc_acks[] = {
 	"---", "REQ", "DUP", "SEQ", "WIN", "MEM", "PNG", "PNR", "DLY", "IDL",
 	"-?-"
 };
@@ -79,6 +79,9 @@
 				 struct rxrpc_message *msg,
 				 rxrpc_seq_t seq,
 				 size_t count);
+
+static int rxrpc_call_flush(struct rxrpc_call *call);
+
 #define _state(call) \
 	_debug("[[[ state %s ]]]", rxrpc_call_states[call->app_call_state]);
 
@@ -2079,7 +2082,7 @@
 /*
  * flush outstanding packets to the network
  */
-int rxrpc_call_flush(struct rxrpc_call *call)
+static int rxrpc_call_flush(struct rxrpc_call *call)
 {
 	struct rxrpc_message *msg;
 	int ret = 0;
diff -Nru a/net/rxrpc/connection.c b/net/rxrpc/connection.c
--- a/net/rxrpc/connection.c	2005-03-01 23:38:58 -08:00
+++ b/net/rxrpc/connection.c	2005-03-01 23:38:58 -08:00
@@ -30,6 +30,8 @@
 DECLARE_RWSEM(rxrpc_conns_sem);
 unsigned long rxrpc_conn_timeout = 60 * 60;
 
+static void rxrpc_conn_do_timeout(struct rxrpc_connection *conn);
+
 static void __rxrpc_conn_timeout(rxrpc_timer_t *timer)
 {
 	struct rxrpc_connection *conn =
@@ -415,7 +417,7 @@
 /*
  * free a connection record
  */
-void rxrpc_conn_do_timeout(struct rxrpc_connection *conn)
+static void rxrpc_conn_do_timeout(struct rxrpc_connection *conn)
 {
 	struct rxrpc_peer *peer;
 
diff -Nru a/net/rxrpc/internal.h b/net/rxrpc/internal.h
--- a/net/rxrpc/internal.h	2005-03-01 23:38:54 -08:00
+++ b/net/rxrpc/internal.h	2005-03-01 23:38:54 -08:00
@@ -73,7 +73,6 @@
 extern struct rw_semaphore rxrpc_conns_sem;
 extern unsigned long rxrpc_conn_timeout;
 
-extern void rxrpc_conn_do_timeout(struct rxrpc_connection *conn);
 extern void rxrpc_conn_clearall(struct rxrpc_peer *peer);
 
 /*
@@ -88,8 +87,6 @@
 				     struct rxrpc_message *resp);
 
 extern void rxrpc_peer_clearall(struct rxrpc_transport *trans);
-
-extern void rxrpc_peer_do_timeout(struct rxrpc_peer *peer);
 
 
 /*
diff -Nru a/net/rxrpc/krxiod.c b/net/rxrpc/krxiod.c
--- a/net/rxrpc/krxiod.c	2005-03-01 23:38:51 -08:00
+++ b/net/rxrpc/krxiod.c	2005-03-01 23:38:51 -08:00
@@ -25,10 +25,10 @@
 static atomic_t rxrpc_krxiod_qcount = ATOMIC_INIT(0);
 
 static LIST_HEAD(rxrpc_krxiod_transportq);
-static spinlock_t rxrpc_krxiod_transportq_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(rxrpc_krxiod_transportq_lock);
 
 static LIST_HEAD(rxrpc_krxiod_callq);
-static spinlock_t rxrpc_krxiod_callq_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(rxrpc_krxiod_callq_lock);
 
 static volatile int rxrpc_krxiod_die;
 
diff -Nru a/net/rxrpc/krxsecd.c b/net/rxrpc/krxsecd.c
--- a/net/rxrpc/krxsecd.c	2005-03-01 23:38:53 -08:00
+++ b/net/rxrpc/krxsecd.c	2005-03-01 23:38:53 -08:00
@@ -39,7 +39,7 @@
 /* queue of unprocessed inbound messages with seqno #1 and
  * RXRPC_CLIENT_INITIATED flag set */
 static LIST_HEAD(rxrpc_krxsecd_initmsgq);
-static spinlock_t rxrpc_krxsecd_initmsgq_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(rxrpc_krxsecd_initmsgq_lock);
 
 static void rxrpc_krxsecd_process_incoming_call(struct rxrpc_message *msg);
 
diff -Nru a/net/rxrpc/krxtimod.c b/net/rxrpc/krxtimod.c
--- a/net/rxrpc/krxtimod.c	2005-03-01 23:38:52 -08:00
+++ b/net/rxrpc/krxtimod.c	2005-03-01 23:38:52 -08:00
@@ -24,7 +24,7 @@
 static int krxtimod_die;
 
 static LIST_HEAD(krxtimod_list);
-static spinlock_t krxtimod_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(krxtimod_lock);
 
 static int krxtimod(void *arg);
 
diff -Nru a/net/rxrpc/peer.c b/net/rxrpc/peer.c
--- a/net/rxrpc/peer.c	2005-03-01 23:38:56 -08:00
+++ b/net/rxrpc/peer.c	2005-03-01 23:38:56 -08:00
@@ -30,6 +30,8 @@
 DECLARE_RWSEM(rxrpc_peers_sem);
 unsigned long rxrpc_peer_timeout = 12 * 60 * 60;
 
+static void rxrpc_peer_do_timeout(struct rxrpc_peer *peer);
+
 static void __rxrpc_peer_timeout(rxrpc_timer_t *timer)
 {
 	struct rxrpc_peer *peer =
@@ -259,7 +261,7 @@
  * handle a peer timing out in the graveyard
  * - called from krxtimod
  */
-void rxrpc_peer_do_timeout(struct rxrpc_peer *peer)
+static void rxrpc_peer_do_timeout(struct rxrpc_peer *peer)
 {
 	struct rxrpc_transport *trans = peer->trans;
 
diff -Nru a/net/rxrpc/rxrpc_syms.c b/net/rxrpc/rxrpc_syms.c
--- a/net/rxrpc/rxrpc_syms.c	2005-03-01 23:38:55 -08:00
+++ b/net/rxrpc/rxrpc_syms.c	2005-03-01 23:38:55 -08:00
@@ -23,7 +23,6 @@
 EXPORT_SYMBOL(rxrpc_call_abort);
 EXPORT_SYMBOL(rxrpc_call_read_data);
 EXPORT_SYMBOL(rxrpc_call_write_data);
-EXPORT_SYMBOL(rxrpc_call_flush);
 
 /* connection.c */
 EXPORT_SYMBOL(rxrpc_create_connection);
diff -Nru a/net/rxrpc/transport.c b/net/rxrpc/transport.c
--- a/net/rxrpc/transport.c	2005-03-01 23:39:08 -08:00
+++ b/net/rxrpc/transport.c	2005-03-01 23:39:08 -08:00
@@ -39,7 +39,7 @@
 	struct sockaddr_in		icmp_src;	/* ICMP packet source address */
 };
 
-static spinlock_t rxrpc_transports_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(rxrpc_transports_lock);
 static struct list_head rxrpc_transports = LIST_HEAD_INIT(rxrpc_transports);
 
 __RXACCT_DECL(atomic_t rxrpc_transport_count);
@@ -147,16 +147,6 @@
 	_leave(" = %d", ret);
 	return ret;
 } /* end rxrpc_create_transport() */
-
-/*****************************************************************************/
-/*
- * clear the connections on a transport endpoint
- */
-void rxrpc_clear_transport(struct rxrpc_transport *trans)
-{
-	//struct rxrpc_connection *conn;
-
-} /* end rxrpc_clear_transport() */
 
 /*****************************************************************************/
 /*
diff -Nru a/net/sched/Kconfig b/net/sched/Kconfig
--- a/net/sched/Kconfig	2005-03-01 23:39:09 -08:00
+++ b/net/sched/Kconfig	2005-03-01 23:39:09 -08:00
@@ -334,6 +334,18 @@
 	  Requires a new iproute2
 	  You MUST NOT turn this on if you dont have an update iproute2.
 
+config CLS_U32_MARK
+	bool "Use nfmark as a key in U32 classifier"
+	depends on NET_CLS_U32 && NETFILTER
+	help
+	  This allows you to match mark in a u32 filter.
+	  Example:
+	  tc filter add dev eth0 protocol ip parent 1:0 prio 5 u32 \
+		match mark 0x0090 0xffff \
+		match ip dst 4.4.4.4 \
+		flowid 1:90
+	  You must use a new iproute2 to use this feature.
+
 config NET_CLS_RSVP
 	tristate "Special RSVP classifier"
 	depends on NET_CLS && NET_QOS
@@ -369,7 +381,6 @@
 	---help---
 	This option requires you have a new iproute2. It enables
 	tc extensions which can be used with tc classifiers.
-	Only the u32 and fw classifiers are supported at the moment.
 	  You MUST NOT turn this on if you dont have an update iproute2.
 
 config NET_ACT_POLICE
@@ -380,13 +391,6 @@
 	below to select a policer.
 	  You MUST NOT turn this on if you dont have an update iproute2.
 
-config NET_CLS_POLICE
-	bool "Traffic policing (needed for in/egress)"
-	depends on NET_CLS && NET_QOS && NET_ACT_POLICE!=y && NET_ACT_POLICE!=m
-	help
-	  Say Y to support traffic policing (bandwidth limits).  Needed for
-	  ingress and egress rate limiting.
-
 config NET_ACT_GACT
         tristate "generic Actions"
         depends on NET_CLS_ACT
@@ -420,3 +424,11 @@
         ---help---
         requires new iproute2
         This allows for packets to be generically edited
+
+config NET_CLS_POLICE
+	bool "Traffic policing (needed for in/egress)"
+	depends on NET_CLS && NET_QOS && NET_CLS_ACT!=y
+	help
+	  Say Y to support traffic policing (bandwidth limits).  Needed for
+	  ingress and egress rate limiting.
+
diff -Nru a/net/sched/act_api.c b/net/sched/act_api.c
--- a/net/sched/act_api.c	2005-03-01 23:39:18 -08:00
+++ b/net/sched/act_api.c	2005-03-01 23:39:18 -08:00
@@ -35,36 +35,33 @@
 #include <net/act_api.h>
 
 #if 1 /* control */
-#define DPRINTK(format,args...) printk(KERN_DEBUG format,##args)
+#define DPRINTK(format, args...) printk(KERN_DEBUG format, ##args)
 #else
-#define DPRINTK(format,args...)
+#define DPRINTK(format, args...)
 #endif
 #if 0 /* data */
-#define D2PRINTK(format,args...) printk(KERN_DEBUG format,##args)
+#define D2PRINTK(format, args...) printk(KERN_DEBUG format, ##args)
 #else
-#define D2PRINTK(format,args...)
+#define D2PRINTK(format, args...)
 #endif
 
 static struct tc_action_ops *act_base = NULL;
-static rwlock_t act_mod_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(act_mod_lock);
 
 int tcf_register_action(struct tc_action_ops *act)
 {
 	struct tc_action_ops *a, **ap;
 
 	write_lock(&act_mod_lock);
-	for (ap = &act_base; (a=*ap)!=NULL; ap = &a->next) {
+	for (ap = &act_base; (a = *ap) != NULL; ap = &a->next) {
 		if (act->type == a->type || (strcmp(act->kind, a->kind) == 0)) {
 			write_unlock(&act_mod_lock);
 			return -EEXIST;
 		}
 	}
-
-        act->next = NULL;
+	act->next = NULL;
 	*ap = act;
-
 	write_unlock(&act_mod_lock);
-
 	return 0;
 }
 
@@ -74,10 +71,9 @@
 	int err = -ENOENT;
 
 	write_lock(&act_mod_lock);
-	for (ap = &act_base; (a=*ap)!=NULL; ap = &a->next) 
-		if(a == act)
+	for (ap = &act_base; (a = *ap) != NULL; ap = &a->next)
+		if (a == act)
 			break;
-
 	if (a) {
 		*ap = a->next;
 		a->next = NULL;
@@ -90,47 +86,42 @@
 /* lookup by name */
 static struct tc_action_ops *tc_lookup_action_n(char *kind)
 {
-
 	struct tc_action_ops *a = NULL;
 
 	if (kind) {
 		read_lock(&act_mod_lock);
 		for (a = act_base; a; a = a->next) {
-			if (strcmp(kind,a->kind) == 0) {
+			if (strcmp(kind, a->kind) == 0) {
 				if (!try_module_get(a->owner)) {
 					read_unlock(&act_mod_lock);
 					return NULL;
-				} 
+				}
 				break;
 			}
 		}
 		read_unlock(&act_mod_lock);
 	}
-
 	return a;
 }
 
 /* lookup by rtattr */
 static struct tc_action_ops *tc_lookup_action(struct rtattr *kind)
 {
-
 	struct tc_action_ops *a = NULL;
 
 	if (kind) {
 		read_lock(&act_mod_lock);
 		for (a = act_base; a; a = a->next) {
-
-			if (strcmp((char*)RTA_DATA(kind),a->kind) == 0){
+			if (rtattr_strcmp(kind, a->kind) == 0) {
 				if (!try_module_get(a->owner)) {
 					read_unlock(&act_mod_lock);
 					return NULL;
-				} 
+				}
 				break;
 			}
 		}
 		read_unlock(&act_mod_lock);
 	}
-
 	return a;
 }
 
@@ -147,55 +138,52 @@
 				if (!try_module_get(a->owner)) {
 					read_unlock(&act_mod_lock);
 					return NULL;
-				} 
+				}
 				break;
 			}
 		}
 		read_unlock(&act_mod_lock);
 	}
-
 	return a;
 }
 #endif
 
-int tcf_action_exec(struct sk_buff *skb,struct tc_action *act, struct tcf_result *res)
+int tcf_action_exec(struct sk_buff *skb, struct tc_action *act,
+                    struct tcf_result *res)
 {
-
 	struct tc_action *a;
-	int ret = -1; 
+	int ret = -1;
 
 	if (skb->tc_verd & TC_NCLS) {
 		skb->tc_verd = CLR_TC_NCLS(skb->tc_verd);
-		D2PRINTK("(%p)tcf_action_exec: cleared TC_NCLS in %s out %s\n",skb,skb->input_dev?skb->input_dev->name:"xxx",skb->dev->name);
+		D2PRINTK("(%p)tcf_action_exec: cleared TC_NCLS in %s out %s\n",
+		         skb, skb->input_dev ? skb->input_dev->name : "xxx",
+		         skb->dev->name);
 		ret = TC_ACT_OK;
 		goto exec_done;
 	}
 	while ((a = act) != NULL) {
 repeat:
 		if (a->ops && a->ops->act) {
-			ret = a->ops->act(&skb,a);
-				if (TC_MUNGED & skb->tc_verd) {
-					/* copied already, allow trampling */
-					skb->tc_verd = SET_TC_OK2MUNGE(skb->tc_verd);
-					skb->tc_verd = CLR_TC_MUNGED(skb->tc_verd);
-				}
-
+			ret = a->ops->act(&skb, a);
+			if (TC_MUNGED & skb->tc_verd) {
+				/* copied already, allow trampling */
+				skb->tc_verd = SET_TC_OK2MUNGE(skb->tc_verd);
+				skb->tc_verd = CLR_TC_MUNGED(skb->tc_verd);
+			}
 			if (ret != TC_ACT_PIPE)
 				goto exec_done;
 			if (ret == TC_ACT_REPEAT)
 				goto repeat;	/* we need a ttl - JHS */
-
 		}
 		act = a->next;
 	}
-
 exec_done:
 	if (skb->tc_classid > 0) {
 		res->classid = skb->tc_classid;
 		res->class = 0;
 		skb->tc_classid = 0;
 	}
-
 	return ret;
 }
 
@@ -203,56 +191,44 @@
 {
 	struct tc_action *a;
 
-	for (a = act; act; a = act) {
-		if (a && a->ops && a->ops->cleanup) {
-			DPRINTK("tcf_action_destroy destroying %p next %p\n", a,a->next?a->next:NULL);
-			act = act->next;
-			if (ACT_P_DELETED == a->ops->cleanup(a, bind)) {
+	for (a = act; a; a = act) {
+		if (a->ops && a->ops->cleanup) {
+			DPRINTK("tcf_action_destroy destroying %p next %p\n",
+			        a, a->next);
+			if (a->ops->cleanup(a, bind) == ACT_P_DELETED)
 				module_put(a->ops->owner);
-			}
-			
-			a->ops = NULL;  
+			act = act->next;
 			kfree(a);
 		} else { /*FIXME: Remove later - catch insertion bugs*/
-			printk("tcf_action_destroy: BUG? destroying NULL ops \n");
-			if (a) {
-				act = act->next;
-				kfree(a);
-			} else {
-				printk("tcf_action_destroy: BUG? destroying NULL action! \n");
-				break;
-			}
+			printk("tcf_action_destroy: BUG? destroying NULL ops\n");
+			act = act->next;
+			kfree(a);
 		}
 	}
 }
 
-int tcf_action_dump_old(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
+int
+tcf_action_dump_old(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
 {
 	int err = -EINVAL;
 
-
-	if ( (NULL == a) || (NULL == a->ops)
-	   || (NULL == a->ops->dump) )
+	if (a->ops == NULL || a->ops->dump == NULL)
 		return err;
 	return a->ops->dump(skb, a, bind, ref);
-
 }
 
-
-int tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
+int
+tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
 {
 	int err = -EINVAL;
-	unsigned char    *b = skb->tail;
+	unsigned char *b = skb->tail;
 	struct rtattr *r;
 
-
-	if ( (NULL == a) || (NULL == a->ops)
-	   || (NULL == a->ops->dump) || (NULL == a->ops->kind))
+	if (a->ops == NULL || a->ops->dump == NULL)
 		return err;
 
-
 	RTA_PUT(skb, TCA_KIND, IFNAMSIZ, a->ops->kind);
-	if (tcf_action_copy_stats(skb,a))
+	if (tcf_action_copy_stats(skb, a))
 		goto rtattr_failure;
 	r = (struct rtattr*) skb->tail;
 	RTA_PUT(skb, TCA_OPTIONS, 0, NULL);
@@ -261,18 +237,17 @@
 		return err;
 	}
 
-
 rtattr_failure:
 	skb_trim(skb, b - skb->data);
 	return -1;
-
 }
 
-int tcf_action_dump(struct sk_buff *skb, struct tc_action *act, int bind, int ref)
+int
+tcf_action_dump(struct sk_buff *skb, struct tc_action *act, int bind, int ref)
 {
 	struct tc_action *a;
 	int err = -EINVAL;
-	unsigned char    *b = skb->tail;
+	unsigned char *b = skb->tail;
 	struct rtattr *r ;
 
 	while ((a = act) != NULL) {
@@ -280,9 +255,8 @@
 		act = a->next;
 		RTA_PUT(skb, a->order, 0, NULL);
 		err = tcf_action_dump_1(skb, a, bind, ref);
-		if (0 > err) 
+		if (err < 0)
 			goto rtattr_failure;
-
 		r->rta_len = skb->tail - (u8*)r;
 	}
 
@@ -291,142 +265,128 @@
 rtattr_failure:
 	skb_trim(skb, b - skb->data);
 	return -err;
-	
 }
 
-int tcf_action_init_1(struct rtattr *rta, struct rtattr *est, struct tc_action *a, char *name, int ovr, int bind )
+struct tc_action *tcf_action_init_1(struct rtattr *rta, struct rtattr *est,
+                                    char *name, int ovr, int bind, int *err)
 {
+	struct tc_action *a;
 	struct tc_action_ops *a_o;
-	char act_name[4 + IFNAMSIZ + 1];
+	char act_name[IFNAMSIZ];
 	struct rtattr *tb[TCA_ACT_MAX+1];
-	struct rtattr *kind = NULL;
+	struct rtattr *kind;
 
-	int err = -EINVAL;
+	*err = -EINVAL;
 
-	if (NULL == name) {
-		if (rtattr_parse(tb, TCA_ACT_MAX, RTA_DATA(rta), RTA_PAYLOAD(rta))<0)
+	if (name == NULL) {
+		if (rtattr_parse_nested(tb, TCA_ACT_MAX, rta) < 0)
 			goto err_out;
 		kind = tb[TCA_ACT_KIND-1];
-		if (NULL != kind) {
-			sprintf(act_name, "%s", (char*)RTA_DATA(kind));
-			if (RTA_PAYLOAD(kind) >= IFNAMSIZ) {
-				printk(" Action %s bad\n", (char*)RTA_DATA(kind));
-				goto err_out;
-			}
-
-		} else {
-			printk("Action bad kind\n");
+		if (kind == NULL)
+			goto err_out;
+		if (rtattr_strlcpy(act_name, kind, IFNAMSIZ) >= IFNAMSIZ)
 			goto err_out;
-		}
-		a_o = tc_lookup_action(kind);
 	} else {
-		sprintf(act_name, "%s", name);
-		DPRINTK("tcf_action_init_1: finding  %s\n",act_name);
-		a_o = tc_lookup_action_n(name);
+		if (strlcpy(act_name, name, IFNAMSIZ) >= IFNAMSIZ)
+			goto err_out;
 	}
+
+	a_o = tc_lookup_action_n(act_name);
+	if (a_o == NULL) {
 #ifdef CONFIG_KMOD
-	if (NULL == a_o) {
-		DPRINTK("tcf_action_init_1: trying to load module %s\n",act_name);
-		request_module (act_name);
+		rtnl_unlock();
+		request_module(act_name);
+		rtnl_lock();
+
 		a_o = tc_lookup_action_n(act_name);
-	}
 
+		/* We dropped the RTNL semaphore in order to
+		 * perform the module load.  So, even if we
+		 * succeeded in loading the module we have to
+		 * tell the caller to replay the request.  We
+		 * indicate this using -EAGAIN.
+		 */
+		if (a_o != NULL) {
+			*err = -EAGAIN;
+			goto err_mod;
+		}
 #endif
-	if (NULL == a_o) {
-		printk("failed to find %s\n",act_name);
 		goto err_out;
 	}
 
-	if (NULL == a) {
+	*err = -ENOMEM;
+	a = kmalloc(sizeof(*a), GFP_KERNEL);
+	if (a == NULL)
 		goto err_mod;
-	}
+	memset(a, 0, sizeof(*a));
 
 	/* backward compatibility for policer */
-	if (NULL == name) {
-		err = a_o->init(tb[TCA_ACT_OPTIONS-1], est, a, ovr, bind);
-		if (0 > err ) {
-			err = -EINVAL;
-			goto err_mod;
-		}
-	} else {
-		err = a_o->init(rta, est, a, ovr, bind);
-		if (0 > err ) {
-			err = -EINVAL;
-			goto err_mod;
-		}
-	}
+	if (name == NULL)
+		*err = a_o->init(tb[TCA_ACT_OPTIONS-1], est, a, ovr, bind);
+	else
+		*err = a_o->init(rta, est, a, ovr, bind);
+	if (*err < 0)
+		goto err_free;
 
 	/* module count goes up only when brand new policy is created
 	   if it exists and is only bound to in a_o->init() then
-           ACT_P_CREATED is not returned (a zero is).
-        */
-	if (ACT_P_CREATED != err) {
+	   ACT_P_CREATED is not returned (a zero is).
+	*/
+	if (*err != ACT_P_CREATED)
 		module_put(a_o->owner);
-	} 
 	a->ops = a_o;
-	DPRINTK("tcf_action_init_1: successfull %s \n",act_name);
+	DPRINTK("tcf_action_init_1: successfull %s\n", act_name);
 
-	return 0;
+	*err = 0;
+	return a;
+
+err_free:
+	kfree(a);
 err_mod:
 	module_put(a_o->owner);
 err_out:
-	return err;
+	return NULL;
 }
 
-int tcf_action_init(struct rtattr *rta, struct rtattr *est, struct tc_action *a, char *name, int ovr , int bind)
+struct tc_action *tcf_action_init(struct rtattr *rta, struct rtattr *est,
+                                  char *name, int ovr, int bind, int *err)
 {
 	struct rtattr *tb[TCA_ACT_MAX_PRIO+1];
+	struct tc_action *head = NULL, *act, *act_prev = NULL;
 	int i;
-	struct tc_action *act = a, *a_s = a;
-
-	int err = -EINVAL;
-
-	if (rtattr_parse(tb, TCA_ACT_MAX_PRIO, RTA_DATA(rta), RTA_PAYLOAD(rta))<0)
-		return err;
 
-	for (i=0; i < TCA_ACT_MAX_PRIO ; i++) {
-		if (tb[i]) {
-			if (NULL == act) {
-				act = kmalloc(sizeof(*act),GFP_KERNEL);
-				if (NULL == act) {
-					err = -ENOMEM;
-					goto bad_ret;
-				}
-				memset(act, 0,sizeof(*act));
-			}
-			act->next = NULL;
-			if (0 > tcf_action_init_1(tb[i],est,act,name,ovr,bind)) {
-				printk("Error processing action order %d\n",i);
-				return err;
-			}
+	if (rtattr_parse_nested(tb, TCA_ACT_MAX_PRIO, rta) < 0) {
+		*err = -EINVAL;
+		return head;
+	}
 
-			act->order = i+1;
-			if (a_s != act) {
-				a_s->next = act;
-				a_s = act;
-			}
-			act = NULL;
-		}
+	for (i=0; i < TCA_ACT_MAX_PRIO && tb[i]; i++) {
+		act = tcf_action_init_1(tb[i], est, name, ovr, bind, err);
+		if (act == NULL)
+			goto err;
+		act->order = i+1;
 
+		if (head == NULL)
+			head = act;
+		else
+			act_prev->next = act;
+		act_prev = act;
 	}
+	return head;
 
-	return 0;
-bad_ret:
-	tcf_action_destroy(a, bind);
-	return err;
+err:
+	if (head != NULL)
+		tcf_action_destroy(head, bind);
+	return NULL;
 }
 
-int tcf_action_copy_stats (struct sk_buff *skb,struct tc_action *a)
+int tcf_action_copy_stats(struct sk_buff *skb, struct tc_action *a)
 {
 	int err;
 	struct gnet_dump d;
 	struct tcf_act_hdr *h = a->priv;
 	
-#ifdef CONFIG_KMOD
-	/* place holder */
-#endif
-
-	if (NULL == h)
+	if (h == NULL)
 		goto errout;
 
 	if (a->type == TCA_OLD_COMPAT)
@@ -439,7 +399,7 @@
 	if (err < 0)
 		goto errout;
 
-	if (NULL != a->ops && NULL != a->ops->get_stats)
+	if (a->ops != NULL && a->ops->get_stats != NULL)
 		if (a->ops->get_stats(skb, a) < 0)
 			goto errout;
 
@@ -459,14 +419,13 @@
 	return -1;
 }
 
-
 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)
+tca_get_fill(struct sk_buff *skb, struct tc_action *a, u32 pid, u32 seq,
+             unsigned flags, int event, int bind, int ref)
 {
 	struct tcamsg *t;
-	struct nlmsghdr  *nlh;
-	unsigned char	 *b = skb->tail;
+	struct nlmsghdr *nlh;
+	unsigned char *b = skb->tail;
 	struct rtattr *x;
 
 	nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*t));
@@ -477,9 +436,8 @@
 	x = (struct rtattr*) skb->tail;
 	RTA_PUT(skb, TCA_ACT_TAB, 0, NULL);
 
-	if (0 > tcf_action_dump(skb, a, bind, ref)) {
+	if (tcf_action_dump(skb, a, bind, ref) < 0)
 		goto rtattr_failure;
-	}
 
 	x->rta_len = skb->tail - (u8*)x;
 	
@@ -492,160 +450,88 @@
 	return -1;
 }
 
-static int act_get_notify(u32 pid, struct nlmsghdr *n,
-			   struct tc_action *a, int event)
+static int
+act_get_notify(u32 pid, struct nlmsghdr *n, struct tc_action *a, int event)
 {
 	struct sk_buff *skb;
-
 	int err = 0;
 
 	skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
 	if (!skb)
 		return -ENOBUFS;
-
-	if (tca_get_fill(skb, a,  pid, n->nlmsg_seq, 0, event, 0, 0) <= 0) {
+	if (tca_get_fill(skb, a, pid, n->nlmsg_seq, 0, event, 0, 0) <= 0) {
 		kfree_skb(skb);
 		return -EINVAL;
 	}
-
-	err =  netlink_unicast(rtnl,skb, pid, MSG_DONTWAIT);
+	err = netlink_unicast(rtnl, skb, pid, MSG_DONTWAIT);
 	if (err > 0)
 		err = 0;
 	return err;
 }
 
-static int tcf_action_get_1(struct rtattr *rta, struct tc_action *a, struct nlmsghdr *n, u32 pid)
+static struct tc_action *
+tcf_action_get_1(struct rtattr *rta, struct nlmsghdr *n, u32 pid, int *err)
 {
-	struct tc_action_ops *a_o;
-	char act_name[4 + IFNAMSIZ + 1];
 	struct rtattr *tb[TCA_ACT_MAX+1];
-	struct rtattr *kind = NULL;
+	struct tc_action *a;
 	int index;
 
-	int err = -EINVAL;
-
-	if (rtattr_parse(tb, TCA_ACT_MAX, RTA_DATA(rta), RTA_PAYLOAD(rta))<0)
-		goto err_out;
-
-
-	kind = tb[TCA_ACT_KIND-1];
-	if (NULL != kind) {
-		sprintf(act_name, "%s", (char*)RTA_DATA(kind));
-		if (RTA_PAYLOAD(kind) >= IFNAMSIZ) {
-			printk("tcf_action_get_1: action %s bad\n", (char*)RTA_DATA(kind));
-			goto err_out;
-		}
-
-	} else {
-		printk("tcf_action_get_1: action bad kind\n");
-		goto err_out;
-	}
-
-	if (tb[TCA_ACT_INDEX - 1]) {
-		index = *(int *)RTA_DATA(tb[TCA_ACT_INDEX - 1]);
-	} else {
-		printk("tcf_action_get_1: index not received\n");
-		goto err_out;
-	}
+	*err = -EINVAL;
+	if (rtattr_parse_nested(tb, TCA_ACT_MAX, rta) < 0)
+		return NULL;
 
-	a_o = tc_lookup_action(kind);
-#ifdef CONFIG_KMOD
-	if (NULL == a_o) {
-		request_module (act_name);
-		a_o = tc_lookup_action_n(act_name);
-	}
+	if (tb[TCA_ACT_INDEX - 1] == NULL ||
+	    RTA_PAYLOAD(tb[TCA_ACT_INDEX - 1]) < sizeof(index))
+		return NULL;
+	index = *(int *)RTA_DATA(tb[TCA_ACT_INDEX - 1]);
 
-#endif
-	if (NULL == a_o) {
-		printk("failed to find %s\n",act_name);
-		goto err_out;
-	}
+	*err = -ENOMEM;
+	a = kmalloc(sizeof(struct tc_action), GFP_KERNEL);
+	if (a == NULL)
+		return NULL;
+	memset(a, 0, sizeof(struct tc_action));
 
-	if (NULL == a) {
+	*err = -EINVAL;
+	a->ops = tc_lookup_action(tb[TCA_ACT_KIND - 1]);
+	if (a->ops == NULL)
+		goto err_free;
+	if (a->ops->lookup == NULL)
 		goto err_mod;
-	}
-
-	a->ops = a_o;
-
-	if (NULL == a_o->lookup || 0 == a_o->lookup(a, index)) {
-		a->ops = NULL;
-		err = -EINVAL;
+	*err = -ENOENT;
+	if (a->ops->lookup(a, index) == 0)
 		goto err_mod;
-	}
 
-	module_put(a_o->owner);
-	return 0;
+	module_put(a->ops->owner);
+	*err = 0;
+	return a;
 err_mod:
-	module_put(a_o->owner);
-err_out:
-	return err;
+	module_put(a->ops->owner);
+err_free:
+	kfree(a);
+	return NULL;
 }
 
-static void cleanup_a (struct tc_action *act) 
+static void cleanup_a(struct tc_action *act)
 {
 	struct tc_action *a;
 
-	for (a = act; act; a = act) {
-		if (a) {
-			act = act->next;
-			a->ops = NULL;
-			a->priv = NULL;
-			kfree(a);
-		} else {
-			printk("cleanup_a: BUG? empty action\n");
-		}
-	}
-}
-
-static struct tc_action_ops *get_ao(struct rtattr *kind, struct tc_action *a)
-{
-	char act_name[4 + IFNAMSIZ + 1];
-	struct tc_action_ops *a_o = NULL;
-
-	if (NULL != kind) {
-		sprintf(act_name, "%s", (char*)RTA_DATA(kind));
-		if (RTA_PAYLOAD(kind) >= IFNAMSIZ) {
-			printk("get_ao: action %s bad\n", (char*)RTA_DATA(kind));
-			return NULL;
-		}
-
-	} else {
-		printk("get_ao: action bad kind\n");
-		return NULL;
-	}
-
-	a_o = tc_lookup_action(kind);
-#ifdef CONFIG_KMOD
-	if (NULL == a_o) {
-		DPRINTK("get_ao: trying to load module %s\n",act_name);
-		request_module (act_name);
-		a_o = tc_lookup_action_n(act_name);
-	}
-#endif
-
-	if (NULL == a_o) {
-		printk("get_ao: failed to find %s\n",act_name);
-		return NULL;
+	for (a = act; a; a = act) {
+		act = a->next;
+		kfree(a);
 	}
-
-	a->ops = a_o;
-	return a_o;
 }
 
 static struct tc_action *create_a(int i)
 {
-	struct tc_action *act = NULL;
+	struct tc_action *act;
 
-	act = kmalloc(sizeof(*act),GFP_KERNEL);
-	if (NULL == act) { /* grrr .. */
-		printk("create_a: failed to alloc! \n");
+	act = kmalloc(sizeof(*act), GFP_KERNEL);
+	if (act == NULL) {
+		printk("create_a: failed to alloc!\n");
 		return NULL;
 	}
-
-	memset(act, 0,sizeof(*act));
-
+	memset(act, 0, sizeof(*act));
 	act->order = i;
-
 	return act;
 }
 
@@ -658,11 +544,11 @@
 	struct netlink_callback dcb;
 	struct rtattr *x;
 	struct rtattr *tb[TCA_ACT_MAX+1];
-	struct rtattr *kind = NULL;
+	struct rtattr *kind;
 	struct tc_action *a = create_a(0);
 	int err = -EINVAL;
 
-	if (NULL == a) {
+	if (a == NULL) {
 		printk("tca_action_flush: couldnt create tc_action\n");
 		return err;
 	}
@@ -676,16 +562,15 @@
 
 	b = (unsigned char *)skb->tail;
 
-	if (rtattr_parse(tb, TCA_ACT_MAX, RTA_DATA(rta), RTA_PAYLOAD(rta))<0) {
+	if (rtattr_parse_nested(tb, TCA_ACT_MAX, rta) < 0)
 		goto err_out;
-	}
 
 	kind = tb[TCA_ACT_KIND-1];
-	if (NULL == get_ao(kind, a)) {
+	a->ops = tc_lookup_action(kind);
+	if (a->ops == NULL)
 		goto err_out;
-	}
 
-	nlh = NLMSG_PUT(skb, pid,  n->nlmsg_seq, RTM_DELACTION, sizeof (*t));
+	nlh = NLMSG_PUT(skb, pid, n->nlmsg_seq, RTM_DELACTION, sizeof(*t));
 	t = NLMSG_DATA(nlh);
 	t->tca_family = AF_UNSPEC;
 
@@ -693,9 +578,8 @@
 	RTA_PUT(skb, TCA_ACT_TAB, 0, NULL);
 
 	err = a->ops->walk(skb, &dcb, RTM_DELACTION, a);
-	if (0 > err ) {
+	if (err < 0)
 		goto rtattr_failure;
-	}
 
 	x->rta_len = skb->tail - (u8 *) x;
 
@@ -709,7 +593,6 @@
 
 	return err;
 
-
 rtattr_failure:
 	module_put(a->ops->owner);
 nlmsg_failure:
@@ -719,99 +602,73 @@
 	return err;
 }
 
-static int tca_action_gd(struct rtattr *rta, struct nlmsghdr *n, u32 pid, int event )
+static int
+tca_action_gd(struct rtattr *rta, struct nlmsghdr *n, u32 pid, int event)
 {
-
-	int s = 0;
 	int i, ret = 0;
-	struct tc_action *act = NULL;
 	struct rtattr *tb[TCA_ACT_MAX_PRIO+1];
-	struct tc_action *a = NULL, *a_s = NULL;
-
-	if (event != RTM_GETACTION  && event != RTM_DELACTION)
-		ret = -EINVAL;
+	struct tc_action *head = NULL, *act, *act_prev = NULL;
 
-	if (rtattr_parse(tb, TCA_ACT_MAX_PRIO, RTA_DATA(rta), RTA_PAYLOAD(rta))<0) {
-		ret = -EINVAL;
-		goto nlmsg_failure;
-	}
+	if (rtattr_parse_nested(tb, TCA_ACT_MAX_PRIO, rta) < 0)
+		return -EINVAL;
 
 	if (event == RTM_DELACTION && n->nlmsg_flags&NLM_F_ROOT) {
-		if (NULL != tb[0]  && NULL == tb[1]) {
-			return tca_action_flush(tb[0],n,pid);
-		}
+		if (tb[0] != NULL && tb[1] == NULL)
+			return tca_action_flush(tb[0], n, pid);
 	}
 
-	for (i=0; i < TCA_ACT_MAX_PRIO ; i++) {
-
-		if (NULL == tb[i])
-			break;
-
-		act = create_a(i+1);
-		if (NULL != a && a != act) {
-			a->next = act;
-			a = act;
-		} else {
-			a = act;
-		}
-
-		if (!s) {
-			s = 1;
-			a_s = a;
-		}
-
-		ret = tcf_action_get_1(tb[i],act,n,pid);
-		if (ret < 0) {
-			printk("tcf_action_get: failed to get! \n");
-			ret = -EINVAL;
-			goto rtattr_failure;
-		}
-
-	}
-
-
-	if (RTM_GETACTION == event) {
-		ret = act_get_notify(pid, n, a_s, event);
-	} else { /* delete */
-
+	for (i=0; i < TCA_ACT_MAX_PRIO && tb[i]; i++) {
+		act = tcf_action_get_1(tb[i], n, pid, &ret);
+		if (act == NULL)
+			goto err;
+		act->order = i+1;
+
+		if (head == NULL)
+			head = act;
+		else
+			act_prev->next = act;
+		act_prev = act;
+	}
+
+	if (event == RTM_GETACTION)
+		ret = act_get_notify(pid, n, head, event);
+	else { /* delete */
 		struct sk_buff *skb;
 
 		skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
 		if (!skb) {
 			ret = -ENOBUFS;
-			goto nlmsg_failure;
+			goto err;
 		}
 
-		if (tca_get_fill(skb, a_s,  pid, n->nlmsg_seq, 0, event, 0 , 1) <= 0) {
+		if (tca_get_fill(skb, head, pid, n->nlmsg_seq, 0, event,
+		                 0, 1) <= 0) {
 			kfree_skb(skb);
 			ret = -EINVAL;
-			goto nlmsg_failure;
+			goto err;
 		}
 
 		/* now do the delete */
-		tcf_action_destroy(a_s, 0);
-
-		ret = rtnetlink_send(skb, pid, RTMGRP_TC, n->nlmsg_flags&NLM_F_ECHO);
+		tcf_action_destroy(head, 0);
+		ret = rtnetlink_send(skb, pid, RTMGRP_TC,
+		                     n->nlmsg_flags&NLM_F_ECHO);
 		if (ret > 0)
 			return 0;
 		return ret;
 	}
-rtattr_failure:
-nlmsg_failure:
-	cleanup_a(a_s);
+err:
+	cleanup_a(head);
 	return ret;
 }
 
-
-static int tcf_add_notify(struct tc_action *a, u32 pid, u32 seq, int event, unsigned flags) 
+static int tcf_add_notify(struct tc_action *a, u32 pid, u32 seq, int event,
+                          unsigned flags)
 {
 	struct tcamsg *t;
-	struct nlmsghdr  *nlh;
+	struct nlmsghdr *nlh;
 	struct sk_buff *skb;
 	struct rtattr *x;
 	unsigned char *b;
-
-
 	int err = 0;
 
 	skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
@@ -828,9 +685,8 @@
 	x = (struct rtattr*) skb->tail;
 	RTA_PUT(skb, TCA_ACT_TAB, 0, NULL);
 
-	if (0 > tcf_action_dump(skb, a, 0, 0)) {
+	if (tcf_action_dump(skb, a, 0, 0) < 0)
 		goto rtattr_failure;
-	}
 
 	x->rta_len = skb->tail - (u8*)x;
 	
@@ -840,7 +696,6 @@
 	err = rtnetlink_send(skb, pid, RTMGRP_TC, flags&NLM_F_ECHO);
 	if (err > 0)
 		err = 0;
-
 	return err;
 
 rtattr_failure:
@@ -850,45 +705,27 @@
 }
 
 	
-static int tcf_action_add(struct rtattr *rta, struct nlmsghdr *n, u32 pid, int ovr ) 
+static int
+tcf_action_add(struct rtattr *rta, struct nlmsghdr *n, u32 pid, int ovr)
 {
 	int ret = 0;
-	struct tc_action *act = NULL;
-	struct tc_action *a = NULL;
+	struct tc_action *act;
+	struct tc_action *a;
 	u32 seq = n->nlmsg_seq;
 
-	act = kmalloc(sizeof(*act),GFP_KERNEL);
-	if (NULL == act)
-		return -ENOMEM;
-
-	memset(act, 0, sizeof(*act));
-
-	ret = tcf_action_init(rta, NULL,act,NULL,ovr,0);
-	/* NOTE: We have an all-or-none model
-	 * This means that of any of the actions fail
-	 * to update then all are undone.
-	 * */
-	if (0 > ret) {
-		tcf_action_destroy(act, 0);
+	act = tcf_action_init(rta, NULL, NULL, ovr, 0, &ret);
+	if (act == NULL)
 		goto done;
-	}
 
 	/* dump then free all the actions after update; inserted policy
 	 * stays intact
 	 * */
-	ret = tcf_add_notify(act, pid, seq, RTM_NEWACTION, n->nlmsg_flags); 
-	for (a = act; act; a = act) {
-		if (a) {
-			act = act->next;
-			a->ops = NULL;
-			a->priv = NULL;
-			kfree(a);
-		} else {
-			printk("tcf_action_add: BUG? empty action\n");
-		}
+	ret = tcf_add_notify(act, pid, seq, RTM_NEWACTION, n->nlmsg_flags);
+	for (a = act; a; a = act) {
+		act = a->next;
+		kfree(a);
 	}
 done:
-
 	return ret;
 }
 
@@ -896,38 +733,38 @@
 {
 	struct rtattr **tca = arg;
 	u32 pid = skb ? NETLINK_CB(skb).pid : 0;
-
 	int ret = 0, ovr = 0;
 
-	if (NULL == tca[TCA_ACT_TAB-1]) {
-			printk("tc_ctl_action: received NO action attribs\n");
-			return -EINVAL;
+	if (tca[TCA_ACT_TAB-1] == NULL) {
+		printk("tc_ctl_action: received NO action attribs\n");
+		return -EINVAL;
 	}
 
 	/* n->nlmsg_flags&NLM_F_CREATE
 	 * */
 	switch (n->nlmsg_type) {
-	case RTM_NEWACTION:    
+	case RTM_NEWACTION:
 		/* we are going to assume all other flags
 		 * imply create only if it doesnt exist
 		 * Note that CREATE | EXCL implies that
 		 * but since we want avoid ambiguity (eg when flags
 		 * is zero) then just set this
 		 */
-		if (n->nlmsg_flags&NLM_F_REPLACE) {
+		if (n->nlmsg_flags&NLM_F_REPLACE)
 			ovr = 1;
-		}
-		ret =  tcf_action_add(tca[TCA_ACT_TAB-1], n, pid, ovr);
+replay:
+		ret = tcf_action_add(tca[TCA_ACT_TAB-1], n, pid, ovr);
+		if (ret == -EAGAIN)
+			goto replay;
 		break;
 	case RTM_DELACTION:
-		ret = tca_action_gd(tca[TCA_ACT_TAB-1], n, pid,RTM_DELACTION);
+		ret = tca_action_gd(tca[TCA_ACT_TAB-1], n, pid, RTM_DELACTION);
 		break;
 	case RTM_GETACTION:
-		ret = tca_action_gd(tca[TCA_ACT_TAB-1], n, pid,RTM_GETACTION);
+		ret = tca_action_gd(tca[TCA_ACT_TAB-1], n, pid, RTM_GETACTION);
 		break;
 	default:
-		printk(" Unknown cmd was detected\n");
-		break;
+		BUG();
 	}
 
 	return ret;
@@ -939,25 +776,25 @@
 	struct rtattr *tb1, *tb2[TCA_ACT_MAX+1];
 	struct rtattr *tb[TCA_ACT_MAX_PRIO + 1];
 	struct rtattr *rta[TCAA_MAX + 1];
-	struct rtattr *kind = NULL;
-	int min_len = NLMSG_LENGTH(sizeof (struct tcamsg));
-
+	struct rtattr *kind;
+	int min_len = NLMSG_LENGTH(sizeof(struct tcamsg));
 	int attrlen = n->nlmsg_len - NLMSG_ALIGN(min_len);
 	struct rtattr *attr = (void *) n + NLMSG_ALIGN(min_len);
 
 	if (rtattr_parse(rta, TCAA_MAX, attr, attrlen) < 0)
 		return NULL;
 	tb1 = rta[TCA_ACT_TAB - 1];
-	if (NULL == tb1) {
+	if (tb1 == NULL)
 		return NULL;
-	}
 
-	if (rtattr_parse(tb, TCA_ACT_MAX_PRIO, RTA_DATA(tb1), NLMSG_ALIGN(RTA_PAYLOAD(tb1))) < 0)
+	if (rtattr_parse(tb, TCA_ACT_MAX_PRIO, RTA_DATA(tb1),
+	                 NLMSG_ALIGN(RTA_PAYLOAD(tb1))) < 0)
 		return NULL;
-	if (NULL == tb[0]) 
+	if (tb[0] == NULL)
 		return NULL;
 
-	if (rtattr_parse(tb2, TCA_ACT_MAX, RTA_DATA(tb[0]), RTA_PAYLOAD(tb[0]))<0)
+	if (rtattr_parse(tb2, TCA_ACT_MAX, RTA_DATA(tb[0]),
+	                 RTA_PAYLOAD(tb[0])) < 0)
 		return NULL;
 	kind = tb2[TCA_ACT_KIND-1];
 
@@ -973,30 +810,30 @@
 	struct tc_action_ops *a_o;
 	struct tc_action a;
 	int ret = 0;
-
 	struct tcamsg *t = (struct tcamsg *) NLMSG_DATA(cb->nlh);
 	char *kind = find_dump_kind(cb->nlh);
-	if (NULL == kind) {
+
+	if (kind == NULL) {
 		printk("tc_dump_action: action bad kind\n");
 		return 0;
 	}
 
 	a_o = tc_lookup_action_n(kind);
-
-	if (NULL == a_o) {
+	if (a_o == NULL) {
 		printk("failed to find %s\n", kind);
 		return 0;
 	}
 
-	memset(&a,0,sizeof(struct tc_action));
+	memset(&a, 0, sizeof(struct tc_action));
 	a.ops = a_o;
 
-	if (NULL == a_o->walk) {
-		printk("tc_dump_action: %s !capable of dumping table\n",kind);
+	if (a_o->walk == NULL) {
+		printk("tc_dump_action: %s !capable of dumping table\n", kind);
 		goto rtattr_failure;
 	}
 
-	nlh = NLMSG_PUT(skb, NETLINK_CB(cb->skb).pid,  cb->nlh->nlmsg_seq, cb->nlh->nlmsg_type, sizeof (*t));
+	nlh = NLMSG_PUT(skb, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq,
+	                cb->nlh->nlmsg_type, sizeof(*t));
 	t = NLMSG_DATA(nlh);
 	t->tca_family = AF_UNSPEC;
 
@@ -1004,19 +841,17 @@
 	RTA_PUT(skb, TCA_ACT_TAB, 0, NULL);
 
 	ret = a_o->walk(skb, cb, RTM_GETACTION, &a);
-	if (0 > ret ) {
+	if (ret < 0)
 		goto rtattr_failure;
-	}
 
 	if (ret > 0) {
 		x->rta_len = skb->tail - (u8 *) x;
 		ret = skb->len;
-	} else {
+	} else
 		skb_trim(skb, (u8*)x - skb->data);
-	}
 
 	nlh->nlmsg_len = skb->tail - b;
-	if (NETLINK_CB(cb->skb).pid && ret) 
+	if (NETLINK_CB(cb->skb).pid && ret)
 		nlh->nlmsg_flags |= NLM_F_MULTI;
 	module_put(a_o->owner);
 	return skb->len;
@@ -1039,7 +874,8 @@
 		link_p[RTM_GETACTION-RTM_BASE].dumpit = tc_dump_action;
 	}
 
-	printk("TC classifier action (bugs to netdev@oss.sgi.com cc hadi@cyberus.ca)\n");
+	printk("TC classifier action (bugs to netdev@oss.sgi.com cc "
+	       "hadi@cyberus.ca)\n");
 	return 0;
 }
 
@@ -1047,11 +883,5 @@
 
 EXPORT_SYMBOL(tcf_register_action);
 EXPORT_SYMBOL(tcf_unregister_action);
-EXPORT_SYMBOL(tcf_action_init_1);
-EXPORT_SYMBOL(tcf_action_init);
-EXPORT_SYMBOL(tcf_action_destroy);
 EXPORT_SYMBOL(tcf_action_exec);
-EXPORT_SYMBOL(tcf_action_copy_stats);
-EXPORT_SYMBOL(tcf_action_dump);
 EXPORT_SYMBOL(tcf_action_dump_1);
-EXPORT_SYMBOL(tcf_action_dump_old);
diff -Nru a/net/sched/cls_api.c b/net/sched/cls_api.c
--- a/net/sched/cls_api.c	2005-03-01 23:38:53 -08:00
+++ b/net/sched/cls_api.c	2005-03-01 23:38:53 -08:00
@@ -49,7 +49,7 @@
 static struct tcf_proto_ops *tcf_proto_base;
 
 /* Protects list of registered TC modules. It is pure SMP lock. */
-static rwlock_t cls_mod_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(cls_mod_lock);
 
 /* Find classifier type by string name */
 
@@ -130,22 +130,31 @@
 
 static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
 {
-	struct rtattr **tca = arg;
-	struct tcmsg *t = NLMSG_DATA(n);
-	u32 protocol = TC_H_MIN(t->tcm_info);
-	u32 prio = TC_H_MAJ(t->tcm_info);
-	u32 nprio = prio;
-	u32 parent = t->tcm_parent;
+	struct rtattr **tca;
+	struct tcmsg *t;
+	u32 protocol;
+	u32 prio;
+	u32 nprio;
+	u32 parent;
 	struct net_device *dev;
 	struct Qdisc  *q;
 	struct tcf_proto **back, **chain;
-	struct tcf_proto *tp = NULL;
+	struct tcf_proto *tp;
 	struct tcf_proto_ops *tp_ops;
 	struct Qdisc_class_ops *cops;
-	unsigned long cl = 0;
+	unsigned long cl;
 	unsigned long fh;
 	int err;
 
+replay:
+	tca = arg;
+	t = NLMSG_DATA(n);
+	protocol = TC_H_MIN(t->tcm_info);
+	prio = TC_H_MAJ(t->tcm_info);
+	nprio = prio;
+	parent = t->tcm_parent;
+	cl = 0;
+
 	if (prio == 0) {
 		/* If no priority is given, user wants we allocated it. */
 		if (n->nlmsg_type != RTM_NEWTFILTER || !(n->nlmsg_flags&NLM_F_CREATE))
@@ -211,19 +220,31 @@
 		err = -ENOBUFS;
 		if ((tp = kmalloc(sizeof(*tp), GFP_KERNEL)) == NULL)
 			goto errout;
+		err = -EINVAL;
 		tp_ops = tcf_proto_lookup_ops(tca[TCA_KIND-1]);
+		if (tp_ops == NULL) {
 #ifdef CONFIG_KMOD
-		if (tp_ops==NULL && tca[TCA_KIND-1] != NULL) {
 			struct rtattr *kind = tca[TCA_KIND-1];
+			char name[IFNAMSIZ];
 
-			if (RTA_PAYLOAD(kind) <= IFNAMSIZ) {
-				request_module("cls_%s", (char*)RTA_DATA(kind));
+			if (kind != NULL &&
+			    rtattr_strlcpy(name, kind, IFNAMSIZ) < IFNAMSIZ) {
+				rtnl_unlock();
+				request_module("cls_%s", name);
+				rtnl_lock();
 				tp_ops = tcf_proto_lookup_ops(kind);
+				/* We dropped the RTNL semaphore in order to
+				 * perform the module load.  So, even if we
+				 * succeeded in loading the module we have to
+				 * replay the request.  We indicate this using
+				 * -EAGAIN.
+				 */
+				if (tp_ops != NULL) {
+					module_put(tp_ops->owner);
+					err = -EAGAIN;
+				}
 			}
-		}
 #endif
-		if (tp_ops == NULL) {
-			err = -EINVAL;
 			kfree(tp);
 			goto errout;
 		}
@@ -293,6 +314,9 @@
 errout:
 	if (cl)
 		cops->put(q, cl);
+	if (err == -EAGAIN)
+		/* Replay the request. */
+		goto replay;
 	return err;
 }
 
@@ -439,6 +463,156 @@
 	return skb->len;
 }
 
+void
+tcf_exts_destroy(struct tcf_proto *tp, struct tcf_exts *exts)
+{
+#ifdef CONFIG_NET_CLS_ACT
+	if (exts->action) {
+		tcf_action_destroy(exts->action, TCA_ACT_UNBIND);
+		exts->action = NULL;
+	}
+#elif defined CONFIG_NET_CLS_POLICE
+	if (exts->police) {
+		tcf_police_release(exts->police, TCA_ACT_UNBIND);
+		exts->police = NULL;
+	}
+#endif
+}
+
+
+int
+tcf_exts_validate(struct tcf_proto *tp, struct rtattr **tb,
+	          struct rtattr *rate_tlv, struct tcf_exts *exts,
+	          struct tcf_ext_map *map)
+{
+	memset(exts, 0, sizeof(*exts));
+	
+#ifdef CONFIG_NET_CLS_ACT
+	{
+		int err;
+		struct tc_action *act;
+
+		if (map->police && tb[map->police-1]) {
+			act = tcf_action_init_1(tb[map->police-1], rate_tlv, "police",
+				TCA_ACT_NOREPLACE, TCA_ACT_BIND, &err);
+			if (act == NULL)
+				return err;
+
+			act->type = TCA_OLD_COMPAT;
+			exts->action = act;
+		} else if (map->action && tb[map->action-1]) {
+			act = tcf_action_init(tb[map->action-1], rate_tlv, NULL,
+				TCA_ACT_NOREPLACE, TCA_ACT_BIND, &err);
+			if (act == NULL)
+				return err;
+
+			exts->action = act;
+		}
+	}
+#elif defined CONFIG_NET_CLS_POLICE
+	if (map->police && tb[map->police-1]) {
+		struct tcf_police *p;
+		
+		p = tcf_police_locate(tb[map->police-1], rate_tlv);
+		if (p == NULL)
+			return -EINVAL;
+
+		exts->police = p;
+	} else if (map->action && tb[map->action-1])
+		return -EOPNOTSUPP;
+#else
+	if ((map->action && tb[map->action-1]) ||
+	    (map->police && tb[map->police-1]))
+		return -EOPNOTSUPP;
+#endif
+
+	return 0;
+}
+
+void
+tcf_exts_change(struct tcf_proto *tp, struct tcf_exts *dst,
+	        struct tcf_exts *src)
+{
+#ifdef CONFIG_NET_CLS_ACT
+	if (src->action) {
+		struct tc_action *act;
+		tcf_tree_lock(tp);
+		act = xchg(&dst->action, src->action);
+		tcf_tree_unlock(tp);
+		if (act)
+			tcf_action_destroy(act, TCA_ACT_UNBIND);
+	}
+#elif defined CONFIG_NET_CLS_POLICE
+	if (src->police) {
+		struct tcf_police *p;
+		tcf_tree_lock(tp);
+		p = xchg(&dst->police, src->police);
+		tcf_tree_unlock(tp);
+		if (p)
+			tcf_police_release(p, TCA_ACT_UNBIND);
+	}
+#endif
+}
+
+int
+tcf_exts_dump(struct sk_buff *skb, struct tcf_exts *exts,
+	      struct tcf_ext_map *map)
+{
+#ifdef CONFIG_NET_CLS_ACT
+	if (map->action && exts->action) {
+		/*
+		 * again for backward compatible mode - we want
+		 * to work with both old and new modes of entering
+		 * tc data even if iproute2  was newer - jhs
+		 */
+		struct rtattr * p_rta = (struct rtattr*) skb->tail;
+
+		if (exts->action->type != TCA_OLD_COMPAT) {
+			RTA_PUT(skb, map->action, 0, NULL);
+			if (tcf_action_dump(skb, exts->action, 0, 0) < 0)
+				goto rtattr_failure;
+			p_rta->rta_len = skb->tail - (u8*)p_rta;
+		} else if (map->police) {
+			RTA_PUT(skb, map->police, 0, NULL);
+			if (tcf_action_dump_old(skb, exts->action, 0, 0) < 0)
+				goto rtattr_failure;
+			p_rta->rta_len = skb->tail - (u8*)p_rta;
+		}
+	}
+#elif defined CONFIG_NET_CLS_POLICE
+	if (map->police && exts->police) {
+		struct rtattr * p_rta = (struct rtattr*) skb->tail;
+
+		RTA_PUT(skb, map->police, 0, NULL);
+
+		if (tcf_police_dump(skb, exts->police) < 0)
+			goto rtattr_failure;
+
+		p_rta->rta_len = skb->tail - (u8*)p_rta;
+	}
+#endif
+	return 0;
+rtattr_failure: __attribute__ ((unused))
+	return -1;
+}
+
+int
+tcf_exts_dump_stats(struct sk_buff *skb, struct tcf_exts *exts,
+	            struct tcf_ext_map *map)
+{
+#ifdef CONFIG_NET_CLS_ACT
+	if (exts->action)
+		if (tcf_action_copy_stats(skb, exts->action) < 0)
+			goto rtattr_failure;
+#elif defined CONFIG_NET_CLS_POLICE
+	if (exts->police)
+		if (tcf_police_dump_stats(skb, exts->police) < 0)
+			goto rtattr_failure;
+#endif
+	return 0;
+rtattr_failure: __attribute__ ((unused))
+	return -1;
+}
 
 static int __init tc_filter_init(void)
 {
@@ -461,3 +635,8 @@
 
 EXPORT_SYMBOL(register_tcf_proto_ops);
 EXPORT_SYMBOL(unregister_tcf_proto_ops);
+EXPORT_SYMBOL(tcf_exts_validate);
+EXPORT_SYMBOL(tcf_exts_destroy);
+EXPORT_SYMBOL(tcf_exts_change);
+EXPORT_SYMBOL(tcf_exts_dump);
+EXPORT_SYMBOL(tcf_exts_dump_stats);
diff -Nru a/net/sched/cls_fw.c b/net/sched/cls_fw.c
--- a/net/sched/cls_fw.c	2005-03-01 23:38:55 -08:00
+++ b/net/sched/cls_fw.c	2005-03-01 23:38:55 -08:00
@@ -59,13 +59,12 @@
 #ifdef CONFIG_NET_CLS_IND
 	char			indev[IFNAMSIZ];
 #endif /* CONFIG_NET_CLS_IND */
-#ifdef CONFIG_NET_CLS_ACT
-	struct tc_action        *action;
-#else /* CONFIG_NET_CLS_ACT */
-#ifdef CONFIG_NET_CLS_POLICE
-	struct tcf_police	*police;
-#endif /* CONFIG_NET_CLS_POLICE */
-#endif /* CONFIG_NET_CLS_ACT */
+	struct tcf_exts		exts;
+};
+
+static struct tcf_ext_map fw_ext_map = {
+	.action = TCA_FW_ACT,
+	.police = TCA_FW_POLICE
 };
 
 static __inline__ int fw_hash(u32 handle)
@@ -78,6 +77,7 @@
 {
 	struct fw_head *head = (struct fw_head*)tp->root;
 	struct fw_filter *f;
+	int r;
 #ifdef CONFIG_NETFILTER
 	u32 id = skb->nfmark;
 #else
@@ -92,20 +92,11 @@
 				if (!tcf_match_indev(skb, f->indev))
 					continue;
 #endif /* CONFIG_NET_CLS_IND */
-#ifdef CONFIG_NET_CLS_ACT
-				if (f->action) {
-					int act_res = tcf_action_exec(skb, f->action, res);
-					if (act_res >= 0)
-						return act_res;
+				r = tcf_exts_exec(skb, &f->exts, res);
+				if (r < 0)
 					continue;
-				}
-#else /* CONFIG_NET_CLS_ACT */
-#ifdef CONFIG_NET_CLS_POLICE
-				if (f->police)
-					return tcf_police(skb, f->police);
-#endif /* CONFIG_NET_CLS_POLICE */
-#endif /* CONFIG_NET_CLS_ACT */
-				return 0;
+
+				return r;
 			}
 		}
 	} else {
@@ -144,6 +135,14 @@
 	return 0;
 }
 
+static inline void
+fw_delete_filter(struct tcf_proto *tp, struct fw_filter *f)
+{
+	tcf_unbind_filter(tp, &f->res);
+	tcf_exts_destroy(tp, &f->exts);
+	kfree(f);
+}
+
 static void fw_destroy(struct tcf_proto *tp)
 {
 	struct fw_head *head = (struct fw_head*)xchg(&tp->root, NULL);
@@ -156,18 +155,7 @@
 	for (h=0; h<256; h++) {
 		while ((f=head->ht[h]) != NULL) {
 			head->ht[h] = f->next;
-			tcf_unbind_filter(tp, &f->res);
-#ifdef CONFIG_NET_CLS_ACT
-			if (f->action)
-				tcf_action_destroy(f->action, TCA_ACT_UNBIND);
-#else /* CONFIG_NET_CLS_ACT */
-#ifdef CONFIG_NET_CLS_POLICE
-			if (f->police)
-				tcf_police_release(f->police, TCA_ACT_UNBIND);
-#endif /* CONFIG_NET_CLS_POLICE */
-#endif /* CONFIG_NET_CLS_ACT */
-
-			kfree(f);
+			fw_delete_filter(tp, f);
 		}
 	}
 	kfree(head);
@@ -187,16 +175,7 @@
 			tcf_tree_lock(tp);
 			*fp = f->next;
 			tcf_tree_unlock(tp);
-			tcf_unbind_filter(tp, &f->res);
-#ifdef CONFIG_NET_CLS_ACT
-			if (f->action)
-				tcf_action_destroy(f->action,TCA_ACT_UNBIND);
-#else /* CONFIG_NET_CLS_ACT */
-#ifdef CONFIG_NET_CLS_POLICE
-			tcf_police_release(f->police,TCA_ACT_UNBIND);
-#endif /* CONFIG_NET_CLS_POLICE */
-#endif /* CONFIG_NET_CLS_ACT */
-			kfree(f);
+			fw_delete_filter(tp, f);
 			return 0;
 		}
 	}
@@ -208,8 +187,14 @@
 fw_change_attrs(struct tcf_proto *tp, struct fw_filter *f,
 	struct rtattr **tb, struct rtattr **tca, unsigned long base)
 {
-	int err = -EINVAL;
+	struct tcf_exts e;
+	int err;
 
+	err = tcf_exts_validate(tp, tb, tca[TCA_RATE-1], &e, &fw_ext_map);
+	if (err < 0)
+		return err;
+
+	err = -EINVAL;
 	if (tb[TCA_FW_CLASSID-1]) {
 		if (RTA_PAYLOAD(tb[TCA_FW_CLASSID-1]) != sizeof(u32))
 			goto errout;
@@ -225,33 +210,11 @@
 	}
 #endif /* CONFIG_NET_CLS_IND */
 
-#ifdef CONFIG_NET_CLS_ACT
-	if (tb[TCA_FW_POLICE-1]) {
-		err = tcf_change_act_police(tp, &f->action, tb[TCA_FW_POLICE-1],
-			tca[TCA_RATE-1]);
-		if (err < 0)
-			goto errout;
-	}
-
-	if (tb[TCA_FW_ACT-1]) {
-		err = tcf_change_act(tp, &f->action, tb[TCA_FW_ACT-1],
-			tca[TCA_RATE-1]);
-		if (err < 0)
-			goto errout;
-	}
-#else /* CONFIG_NET_CLS_ACT */
-#ifdef CONFIG_NET_CLS_POLICE
-	if (tb[TCA_FW_POLICE-1]) {
-		err = tcf_change_police(tp, &f->police, tb[TCA_FW_POLICE-1],
-			tca[TCA_RATE-1]);
-		if (err < 0)
-			goto errout;
-	}
-#endif /* CONFIG_NET_CLS_POLICE */
-#endif /* CONFIG_NET_CLS_ACT */
+	tcf_exts_change(tp, &f->exts, &e);
 
-	err = 0;
+	return 0;
 errout:
+	tcf_exts_destroy(tp, &e);
 	return err;
 }
 
@@ -269,7 +232,7 @@
 	if (!opt)
 		return handle ? -EINVAL : 0;
 
-	if (rtattr_parse(tb, TCA_FW_MAX, RTA_DATA(opt), RTA_PAYLOAD(opt)) < 0)
+	if (rtattr_parse_nested(tb, TCA_FW_MAX, opt) < 0)
 		return -EINVAL;
 
 	if (f != NULL) {
@@ -357,15 +320,7 @@
 
 	t->tcm_handle = f->id;
 
-	if (!f->res.classid
-#ifdef CONFIG_NET_CLS_ACT
-		&& !f->action
-#else
-#ifdef CONFIG_NET_CLS_POLICE
-		&& !f->police
-#endif
-#endif
-		)
+	if (!f->res.classid && !tcf_exts_is_available(&f->exts))
 		return skb->len;
 
 	rta = (struct rtattr*)b;
@@ -377,29 +332,15 @@
 	if (strlen(f->indev))
 		RTA_PUT(skb, TCA_FW_INDEV, IFNAMSIZ, f->indev);
 #endif /* CONFIG_NET_CLS_IND */
-#ifdef CONFIG_NET_CLS_ACT
-	if (tcf_dump_act(skb, f->action, TCA_FW_ACT, TCA_FW_POLICE) < 0)
-		goto rtattr_failure;
-#else /* CONFIG_NET_CLS_ACT */
-#ifdef CONFIG_NET_CLS_POLICE
-	if (tcf_dump_police(skb, f->police, TCA_FW_POLICE) < 0)
+
+	if (tcf_exts_dump(skb, &f->exts, &fw_ext_map) < 0)
 		goto rtattr_failure;
-#endif /* CONFIG_NET_CLS_POLICE */
-#endif /* CONFIG_NET_CLS_ACT */
 
 	rta->rta_len = skb->tail - b;
-#ifdef CONFIG_NET_CLS_ACT
-	if (f->action && f->action->type == TCA_OLD_COMPAT) {
-		if (tcf_action_copy_stats(skb,f->action))
-			goto rtattr_failure;
-	}
-#else /* CONFIG_NET_CLS_ACT */
-#ifdef CONFIG_NET_CLS_POLICE
-	if (f->police)
-		if (tcf_police_dump_stats(skb, f->police) < 0)
-			goto rtattr_failure;
-#endif /* CONFIG_NET_CLS_POLICE */
-#endif /* CONFIG_NET_CLS_ACT */
+
+	if (tcf_exts_dump_stats(skb, &f->exts, &fw_ext_map) < 0)
+		goto rtattr_failure;
+
 	return skb->len;
 
 rtattr_failure:
diff -Nru a/net/sched/cls_route.c b/net/sched/cls_route.c
--- a/net/sched/cls_route.c	2005-03-01 23:38:54 -08:00
+++ b/net/sched/cls_route.c	2005-03-01 23:38:54 -08:00
@@ -59,6 +59,7 @@
 
 struct route4_bucket
 {
+	/* 16 FROM buckets + 16 IIF buckets + 1 wildcard bucket */
 	struct route4_filter	*ht[16+16+1];
 };
 
@@ -69,22 +70,25 @@
 	int			iif;
 
 	struct tcf_result	res;
-#ifdef CONFIG_NET_CLS_POLICE
-	struct tcf_police	*police;
-#endif
-
+	struct tcf_exts		exts;
 	u32			handle;
 	struct route4_bucket	*bkt;
 };
 
 #define ROUTE4_FAILURE ((struct route4_filter*)(-1L))
 
+static struct tcf_ext_map route_ext_map = {
+	.police = TCA_ROUTE4_POLICE,
+	.action = TCA_ROUTE4_ACT
+};
+
 static __inline__ int route4_fastmap_hash(u32 id, int iif)
 {
 	return id&0xF;
 }
 
-static void route4_reset_fastmap(struct net_device *dev, struct route4_head *head, u32 id)
+static inline
+void route4_reset_fastmap(struct net_device *dev, struct route4_head *head, u32 id)
 {
 	spin_lock_bh(&dev->queue_lock);
 	memset(head->fastmap, 0, sizeof(head->fastmap));
@@ -121,19 +125,20 @@
 	return 32;
 }
 
-#ifdef CONFIG_NET_CLS_POLICE
-#define IF_ROUTE_POLICE \
-if (f->police) { \
-	int pol_res = tcf_police(skb, f->police); \
-	if (pol_res >= 0) return pol_res; \
-	dont_cache = 1; \
-	continue; \
-} \
-if (!dont_cache)
-#else
-#define IF_ROUTE_POLICE
-#endif
-
+#define ROUTE4_APPLY_RESULT()					\
+{								\
+	*res = f->res;						\
+	if (tcf_exts_is_available(&f->exts)) {			\
+		int r = tcf_exts_exec(skb, &f->exts, res);	\
+		if (r < 0) {					\
+			dont_cache = 1;				\
+			continue;				\
+		}						\
+		return r;					\
+	} else if (!dont_cache)					\
+		route4_set_fastmap(head, id, iif, f);		\
+	return 0;						\
+}
 
 static int route4_classify(struct sk_buff *skb, struct tcf_proto *tp,
 			   struct tcf_result *res)
@@ -142,11 +147,8 @@
 	struct dst_entry *dst;
 	struct route4_bucket *b;
 	struct route4_filter *f;
-#ifdef CONFIG_NET_CLS_POLICE
-	int dont_cache = 0;
-#endif
 	u32 id, h;
-	int iif;
+	int iif, dont_cache = 0;
 
 	if ((dst = skb->dst) == NULL)
 		goto failure;
@@ -172,29 +174,16 @@
 
 restart:
 	if ((b = head->table[h]) != NULL) {
-		f = b->ht[route4_hash_from(id)];
-
-		for ( ; f; f = f->next) {
-			if (f->id == id) {
-				*res = f->res;
-				IF_ROUTE_POLICE route4_set_fastmap(head, id, iif, f);
-				return 0;
-			}
-		}
+		for (f = b->ht[route4_hash_from(id)]; f; f = f->next)
+			if (f->id == id)
+				ROUTE4_APPLY_RESULT();
+
+		for (f = b->ht[route4_hash_iif(iif)]; f; f = f->next)
+			if (f->iif == iif)
+				ROUTE4_APPLY_RESULT();
 
-		for (f = b->ht[route4_hash_iif(iif)]; f; f = f->next) {
-			if (f->iif == iif) {
-				*res = f->res;
-				IF_ROUTE_POLICE route4_set_fastmap(head, id, iif, f);
-				return 0;
-			}
-		}
-
-		for (f = b->ht[route4_hash_wild()]; f; f = f->next) {
-			*res = f->res;
-			IF_ROUTE_POLICE route4_set_fastmap(head, id, iif, f);
-			return 0;
-		}
+		for (f = b->ht[route4_hash_wild()]; f; f = f->next)
+			ROUTE4_APPLY_RESULT();
 
 	}
 	if (h < 256) {
@@ -203,9 +192,7 @@
 		goto restart;
 	}
 
-#ifdef CONFIG_NET_CLS_POLICE
 	if (!dont_cache)
-#endif
 		route4_set_fastmap(head, id, iif, ROUTE4_FAILURE);
 failure:
 	return -1;
@@ -220,7 +207,7 @@
 	return -1;
 }
 
-static u32 to_hash(u32 id)
+static inline u32 to_hash(u32 id)
 {
 	u32 h = id&0xFF;
 	if (id&0x8000)
@@ -228,7 +215,7 @@
 	return h;
 }
 
-static u32 from_hash(u32 id)
+static inline u32 from_hash(u32 id)
 {
 	id &= 0xFFFF;
 	if (id == 0xFFFF)
@@ -276,6 +263,14 @@
 	return 0;
 }
 
+static inline void
+route4_delete_filter(struct tcf_proto *tp, struct route4_filter *f)
+{
+	tcf_unbind_filter(tp, &f->res);
+	tcf_exts_destroy(tp, &f->exts);
+	kfree(f);
+}
+
 static void route4_destroy(struct tcf_proto *tp)
 {
 	struct route4_head *head = xchg(&tp->root, NULL);
@@ -293,11 +288,7 @@
 
 				while ((f = b->ht[h2]) != NULL) {
 					b->ht[h2] = f->next;
-					tcf_unbind_filter(tp, &f->res);
-#ifdef CONFIG_NET_CLS_POLICE
-					tcf_police_release(f->police,TCA_ACT_UNBIND);
-#endif
-					kfree(f);
+					route4_delete_filter(tp, f);
 				}
 			}
 			kfree(b);
@@ -327,11 +318,7 @@
 			tcf_tree_unlock(tp);
 
 			route4_reset_fastmap(tp->q->dev, head, f->id);
-			tcf_unbind_filter(tp, &f->res);
-#ifdef CONFIG_NET_CLS_POLICE
-			tcf_police_release(f->police,TCA_ACT_UNBIND);
-#endif
-			kfree(f);
+			route4_delete_filter(tp, f);
 
 			/* Strip tree */
 
@@ -351,108 +338,63 @@
 	return 0;
 }
 
-static int route4_change(struct tcf_proto *tp, unsigned long base,
-		       u32 handle,
-		       struct rtattr **tca,
-		       unsigned long *arg)
+static int route4_set_parms(struct tcf_proto *tp, unsigned long base,
+	struct route4_filter *f, u32 handle, struct route4_head *head,
+	struct rtattr **tb, struct rtattr *est, int new)
 {
-	struct route4_head *head = tp->root;
-	struct route4_filter *f, *f1, **ins_f;
-	struct route4_bucket *b;
-	struct rtattr *opt = tca[TCA_OPTIONS-1];
-	struct rtattr *tb[TCA_ROUTE4_MAX];
-	unsigned h1, h2;
 	int err;
+	u32 id = 0, to = 0, nhandle = 0x8000;
+	struct route4_filter *fp;
+	unsigned int h1;
+	struct route4_bucket *b;
+	struct tcf_exts e;
 
-	if (opt == NULL)
-		return handle ? -EINVAL : 0;
-
-	if (rtattr_parse(tb, TCA_ROUTE4_MAX, RTA_DATA(opt), RTA_PAYLOAD(opt)) < 0)
-		return -EINVAL;
-
-	if ((f = (struct route4_filter*)*arg) != NULL) {
-		if (f->handle != handle && handle)
-			return -EINVAL;
-		if (tb[TCA_ROUTE4_CLASSID-1]) {
-			f->res.classid = *(u32*)RTA_DATA(tb[TCA_ROUTE4_CLASSID-1]);
-			tcf_bind_filter(tp, &f->res, base);
-		}
-#ifdef CONFIG_NET_CLS_POLICE
-		if (tb[TCA_ROUTE4_POLICE-1]) {
-			err = tcf_change_police(tp, &f->police,
-				tb[TCA_ROUTE4_POLICE-1], tca[TCA_RATE-1]);
-			if (err < 0)
-				return err;
-		}
-#endif
-		return 0;
-	}
-
-	/* Now more serious part... */
-
-	if (head == NULL) {
-		head = kmalloc(sizeof(struct route4_head), GFP_KERNEL);
-		if (head == NULL)
-			return -ENOBUFS;
-		memset(head, 0, sizeof(struct route4_head));
-
-		tcf_tree_lock(tp);
-		tp->root = head;
-		tcf_tree_unlock(tp);
-	}
-
-	f = kmalloc(sizeof(struct route4_filter), GFP_KERNEL);
-	if (f == NULL)
-		return -ENOBUFS;
-
-	memset(f, 0, sizeof(*f));
+	err = tcf_exts_validate(tp, tb, est, &e, &route_ext_map);
+	if (err < 0)
+		return err;
 
 	err = -EINVAL;
-	f->handle = 0x8000;
+	if (tb[TCA_ROUTE4_CLASSID-1])
+		if (RTA_PAYLOAD(tb[TCA_ROUTE4_CLASSID-1]) < sizeof(u32))
+			goto errout;
+
 	if (tb[TCA_ROUTE4_TO-1]) {
-		if (handle&0x8000)
+		if (new && handle & 0x8000)
 			goto errout;
-		if (RTA_PAYLOAD(tb[TCA_ROUTE4_TO-1]) < 4)
+		if (RTA_PAYLOAD(tb[TCA_ROUTE4_TO-1]) < sizeof(u32))
 			goto errout;
-		f->id = *(u32*)RTA_DATA(tb[TCA_ROUTE4_TO-1]);
-		if (f->id > 0xFF)
+		to = *(u32*)RTA_DATA(tb[TCA_ROUTE4_TO-1]);
+		if (to > 0xFF)
 			goto errout;
-		f->handle = f->id;
+		nhandle = to;
 	}
+
 	if (tb[TCA_ROUTE4_FROM-1]) {
-		u32 sid;
 		if (tb[TCA_ROUTE4_IIF-1])
 			goto errout;
-		if (RTA_PAYLOAD(tb[TCA_ROUTE4_FROM-1]) < 4)
+		if (RTA_PAYLOAD(tb[TCA_ROUTE4_FROM-1]) < sizeof(u32))
 			goto errout;
-		sid = (*(u32*)RTA_DATA(tb[TCA_ROUTE4_FROM-1]));
-		if (sid > 0xFF)
+		id = *(u32*)RTA_DATA(tb[TCA_ROUTE4_FROM-1]);
+		if (id > 0xFF)
 			goto errout;
-		f->handle |= sid<<16;
-		f->id |= sid<<16;
+		nhandle |= id << 16;
 	} else if (tb[TCA_ROUTE4_IIF-1]) {
-		if (RTA_PAYLOAD(tb[TCA_ROUTE4_IIF-1]) < 4)
+		if (RTA_PAYLOAD(tb[TCA_ROUTE4_IIF-1]) < sizeof(u32))
 			goto errout;
-		f->iif = *(u32*)RTA_DATA(tb[TCA_ROUTE4_IIF-1]);
-		if (f->iif > 0x7FFF)
+		id = *(u32*)RTA_DATA(tb[TCA_ROUTE4_IIF-1]);
+		if (id > 0x7FFF)
 			goto errout;
-		f->handle |= (f->iif|0x8000)<<16;
+		nhandle |= (id | 0x8000) << 16;
 	} else
-		f->handle |= 0xFFFF<<16;
-
-	if (handle) {
-		f->handle |= handle&0x7F00;
-		if (f->handle != handle)
-			goto errout;
-	}
+		nhandle |= 0xFFFF << 16;
 
-	if (tb[TCA_ROUTE4_CLASSID-1]) {
-		if (RTA_PAYLOAD(tb[TCA_ROUTE4_CLASSID-1]) < 4)
+	if (handle && new) {
+		nhandle |= handle & 0x7F00;
+		if (nhandle != handle)
 			goto errout;
-		f->res.classid = *(u32*)RTA_DATA(tb[TCA_ROUTE4_CLASSID-1]);
 	}
 
-	h1 = to_hash(f->handle);
+	h1 = to_hash(nhandle);
 	if ((b = head->table[h1]) == NULL) {
 		err = -ENOBUFS;
 		b = kmalloc(sizeof(struct route4_bucket), GFP_KERNEL);
@@ -463,27 +405,119 @@
 		tcf_tree_lock(tp);
 		head->table[h1] = b;
 		tcf_tree_unlock(tp);
+	} else {
+		unsigned int h2 = from_hash(nhandle >> 16);
+		err = -EEXIST;
+		for (fp = b->ht[h2]; fp; fp = fp->next)
+			if (fp->handle == f->handle)
+				goto errout;
 	}
+
+	tcf_tree_lock(tp);
+	if (tb[TCA_ROUTE4_TO-1])
+		f->id = to;
+
+	if (tb[TCA_ROUTE4_FROM-1])
+		f->id = to | id<<16;
+	else if (tb[TCA_ROUTE4_IIF-1])
+		f->iif = id;
+
+	f->handle = nhandle;
 	f->bkt = b;
+	tcf_tree_unlock(tp);
 
-	err = -EEXIST;
-	h2 = from_hash(f->handle>>16);
-	for (ins_f = &b->ht[h2]; (f1=*ins_f) != NULL; ins_f = &f1->next) {
-		if (f->handle < f1->handle)
-			break;
-		if (f1->handle == f->handle)
+	if (tb[TCA_ROUTE4_CLASSID-1]) {
+		f->res.classid = *(u32*)RTA_DATA(tb[TCA_ROUTE4_CLASSID-1]);
+		tcf_bind_filter(tp, &f->res, base);
+	}
+
+	tcf_exts_change(tp, &f->exts, &e);
+
+	return 0;
+errout:
+	tcf_exts_destroy(tp, &e);
+	return err;
+}
+
+static int route4_change(struct tcf_proto *tp, unsigned long base,
+		       u32 handle,
+		       struct rtattr **tca,
+		       unsigned long *arg)
+{
+	struct route4_head *head = tp->root;
+	struct route4_filter *f, *f1, **fp;
+	struct route4_bucket *b;
+	struct rtattr *opt = tca[TCA_OPTIONS-1];
+	struct rtattr *tb[TCA_ROUTE4_MAX];
+	unsigned int h, th;
+	u32 old_handle = 0;
+	int err;
+
+	if (opt == NULL)
+		return handle ? -EINVAL : 0;
+
+	if (rtattr_parse_nested(tb, TCA_ROUTE4_MAX, opt) < 0)
+		return -EINVAL;
+
+	if ((f = (struct route4_filter*)*arg) != NULL) {
+		if (f->handle != handle && handle)
+			return -EINVAL;
+
+		if (f->bkt)
+			old_handle = f->handle;
+
+		err = route4_set_parms(tp, base, f, handle, head, tb,
+			tca[TCA_RATE-1], 0);
+		if (err < 0)
+			return err;
+
+		goto reinsert;
+	}
+
+	err = -ENOBUFS;
+	if (head == NULL) {
+		head = kmalloc(sizeof(struct route4_head), GFP_KERNEL);
+		if (head == NULL)
 			goto errout;
+		memset(head, 0, sizeof(struct route4_head));
+
+		tcf_tree_lock(tp);
+		tp->root = head;
+		tcf_tree_unlock(tp);
 	}
 
-	tcf_bind_filter(tp, &f->res, base);
-#ifdef CONFIG_NET_CLS_POLICE
-	if (tb[TCA_ROUTE4_POLICE-1])
-		tcf_change_police(tp, &f->police, tb[TCA_ROUTE4_POLICE-1], tca[TCA_RATE-1]);
-#endif
+	f = kmalloc(sizeof(struct route4_filter), GFP_KERNEL);
+	if (f == NULL)
+		goto errout;
+	memset(f, 0, sizeof(*f));
+
+	err = route4_set_parms(tp, base, f, handle, head, tb,
+		tca[TCA_RATE-1], 1);
+	if (err < 0)
+		goto errout;
+
+reinsert:
+	h = from_hash(f->handle >> 16);
+	for (fp = &f->bkt->ht[h]; (f1=*fp) != NULL; fp = &f1->next)
+		if (f->handle < f1->handle)
+			break;
 
 	f->next = f1;
 	tcf_tree_lock(tp);
-	*ins_f = f;
+	*fp = f;
+
+	if (old_handle && f->handle != old_handle) {
+		th = to_hash(old_handle);
+		h = from_hash(old_handle >> 16);
+		if ((b = head->table[th]) != NULL) {
+			for (fp = &b->ht[h]; *fp; fp = &(*fp)->next) {
+				if (*fp == f) {
+					*fp = f->next;
+					break;
+				}
+			}
+		}
+	}
 	tcf_tree_unlock(tp);
 
 	route4_reset_fastmap(tp->q->dev, head, f->id);
@@ -559,17 +593,15 @@
 	}
 	if (f->res.classid)
 		RTA_PUT(skb, TCA_ROUTE4_CLASSID, 4, &f->res.classid);
-#ifdef CONFIG_NET_CLS_POLICE
-	if (tcf_dump_police(skb, f->police, TCA_ROUTE4_POLICE) < 0)
+
+	if (tcf_exts_dump(skb, &f->exts, &route_ext_map) < 0)
 		goto rtattr_failure;
-#endif
 
 	rta->rta_len = skb->tail - b;
-#ifdef CONFIG_NET_CLS_POLICE
-	if (f->police)
-		if (tcf_police_dump_stats(skb, f->police) < 0)
-			goto rtattr_failure;
-#endif
+
+	if (tcf_exts_dump_stats(skb, &f->exts, &route_ext_map) < 0)
+		goto rtattr_failure;
+
 	return skb->len;
 
 rtattr_failure:
diff -Nru a/net/sched/cls_rsvp.h b/net/sched/cls_rsvp.h
--- a/net/sched/cls_rsvp.h	2005-03-01 23:38:52 -08:00
+++ b/net/sched/cls_rsvp.h	2005-03-01 23:38:52 -08:00
@@ -95,9 +95,7 @@
 	u8			tunnelhdr;
 
 	struct tcf_result	res;
-#ifdef CONFIG_NET_CLS_POLICE
-	struct tcf_police	*police;
-#endif
+	struct tcf_exts		exts;
 
 	u32			handle;
 	struct rsvp_session	*sess;
@@ -120,18 +118,20 @@
 	return h & 0xF;
 }
 
-#ifdef CONFIG_NET_CLS_POLICE
-#define RSVP_POLICE() \
-if (f->police) { \
-	int pol_res = tcf_police(skb, f->police); \
-	if (pol_res < 0) continue; \
-	if (pol_res) return pol_res; \
-}
-#else
-#define RSVP_POLICE()
-#endif
-
+static struct tcf_ext_map rsvp_ext_map = {
+	.police = TCA_RSVP_POLICE,
+	.action = TCA_RSVP_ACT
+};
 
+#define RSVP_APPLY_RESULT()				\
+{							\
+	int r = tcf_exts_exec(skb, &f->exts, res);	\
+	if (r < 0)					\
+		continue;				\
+	else if (r > 0)					\
+		return r;				\
+}
+	
 static int rsvp_classify(struct sk_buff *skb, struct tcf_proto *tp,
 			 struct tcf_result *res)
 {
@@ -189,8 +189,7 @@
 #endif
 				    ) {
 					*res = f->res;
-
-					RSVP_POLICE();
+					RSVP_APPLY_RESULT();
 
 matched:
 					if (f->tunnelhdr == 0)
@@ -205,7 +204,7 @@
 			/* And wildcard bucket... */
 			for (f = s->ht[16]; f; f = f->next) {
 				*res = f->res;
-				RSVP_POLICE();
+				RSVP_APPLY_RESULT();
 				goto matched;
 			}
 			return -1;
@@ -251,6 +250,14 @@
 	return -ENOBUFS;
 }
 
+static inline void
+rsvp_delete_filter(struct tcf_proto *tp, struct rsvp_filter *f)
+{
+	tcf_unbind_filter(tp, &f->res);
+	tcf_exts_destroy(tp, &f->exts);
+	kfree(f);
+}
+
 static void rsvp_destroy(struct tcf_proto *tp)
 {
 	struct rsvp_head *data = xchg(&tp->root, NULL);
@@ -273,11 +280,7 @@
 
 				while ((f = s->ht[h2]) != NULL) {
 					s->ht[h2] = f->next;
-					tcf_unbind_filter(tp, &f->res);
-#ifdef CONFIG_NET_CLS_POLICE
-					tcf_police_release(f->police,TCA_ACT_UNBIND);
-#endif
-					kfree(f);
+					rsvp_delete_filter(tp, f);
 				}
 			}
 			kfree(s);
@@ -299,12 +302,7 @@
 			tcf_tree_lock(tp);
 			*fp = f->next;
 			tcf_tree_unlock(tp);
-			tcf_unbind_filter(tp, &f->res);
-#ifdef CONFIG_NET_CLS_POLICE
-			tcf_police_release(f->police,TCA_ACT_UNBIND);
-#endif
-
-			kfree(f);
+			rsvp_delete_filter(tp, f);
 
 			/* Strip tree */
 
@@ -412,6 +410,7 @@
 	struct tc_rsvp_pinfo *pinfo = NULL;
 	struct rtattr *opt = tca[TCA_OPTIONS-1];
 	struct rtattr *tb[TCA_RSVP_MAX];
+	struct tcf_exts e;
 	unsigned h1, h2;
 	u32 *dst;
 	int err;
@@ -419,38 +418,38 @@
 	if (opt == NULL)
 		return handle ? -EINVAL : 0;
 
-	if (rtattr_parse(tb, TCA_RSVP_MAX, RTA_DATA(opt), RTA_PAYLOAD(opt)) < 0)
+	if (rtattr_parse_nested(tb, TCA_RSVP_MAX, opt) < 0)
 		return -EINVAL;
 
+	err = tcf_exts_validate(tp, tb, tca[TCA_RATE-1], &e, &rsvp_ext_map);
+	if (err < 0)
+		return err;
+
 	if ((f = (struct rsvp_filter*)*arg) != NULL) {
 		/* Node exists: adjust only classid */
 
 		if (f->handle != handle && handle)
-			return -EINVAL;
+			goto errout2;
 		if (tb[TCA_RSVP_CLASSID-1]) {
 			f->res.classid = *(u32*)RTA_DATA(tb[TCA_RSVP_CLASSID-1]);
 			tcf_bind_filter(tp, &f->res, base);
 		}
-#ifdef CONFIG_NET_CLS_POLICE
-		if (tb[TCA_RSVP_POLICE-1]) {
-			err = tcf_change_police(tp, &f->police,
-				tb[TCA_RSVP_POLICE-1], tca[TCA_RATE-1]);
-			if (err < 0)
-				return err;
-		}
-#endif
+
+		tcf_exts_change(tp, &f->exts, &e);
 		return 0;
 	}
 
 	/* Now more serious part... */
+	err = -EINVAL;
 	if (handle)
-		return -EINVAL;
+		goto errout2;
 	if (tb[TCA_RSVP_DST-1] == NULL)
-		return -EINVAL;
+		goto errout2;
 
+	err = -ENOBUFS;
 	f = kmalloc(sizeof(struct rsvp_filter), GFP_KERNEL);
 	if (f == NULL)
-		return -ENOBUFS;
+		goto errout2;
 
 	memset(f, 0, sizeof(*f));
 	h2 = 16;
@@ -516,10 +515,8 @@
 			f->sess = s;
 			if (f->tunnelhdr == 0)
 				tcf_bind_filter(tp, &f->res, base);
-#ifdef CONFIG_NET_CLS_POLICE
-			if (tb[TCA_RSVP_POLICE-1])
-				tcf_change_police(tp, &f->police, tb[TCA_RSVP_POLICE-1], tca[TCA_RATE-1]);
-#endif
+
+			tcf_exts_change(tp, &f->exts, &e);
 
 			for (fp = &s->ht[h2]; *fp; fp = &(*fp)->next)
 				if (((*fp)->spi.mask&f->spi.mask) != f->spi.mask)
@@ -560,6 +557,8 @@
 errout:
 	if (f)
 		kfree(f);
+errout2:
+	tcf_exts_destroy(tp, &e);
 	return err;
 }
 
@@ -624,17 +623,14 @@
 		RTA_PUT(skb, TCA_RSVP_CLASSID, 4, &f->res.classid);
 	if (((f->handle>>8)&0xFF) != 16)
 		RTA_PUT(skb, TCA_RSVP_SRC, sizeof(f->src), f->src);
-#ifdef CONFIG_NET_CLS_POLICE
-	if (tcf_dump_police(skb, f->police, TCA_RSVP_POLICE) < 0)
+
+	if (tcf_exts_dump(skb, &f->exts, &rsvp_ext_map) < 0)
 		goto rtattr_failure;
-#endif
 
 	rta->rta_len = skb->tail - b;
-#ifdef CONFIG_NET_CLS_POLICE
-	if (f->police)
-		if (tcf_police_dump_stats(skb, f->police) < 0)
-			goto rtattr_failure;
-#endif
+
+	if (tcf_exts_dump_stats(skb, &f->exts, &rsvp_ext_map) < 0)
+		goto rtattr_failure;
 	return skb->len;
 
 rtattr_failure:
diff -Nru a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c
--- a/net/sched/cls_tcindex.c	2005-03-01 23:38:56 -08:00
+++ b/net/sched/cls_tcindex.c	2005-03-01 23:38:56 -08:00
@@ -49,12 +49,12 @@
 
 
 struct tcindex_filter_result {
-	struct tcf_police *police;
-	struct tcf_result res;
+	struct tcf_exts		exts;
+	struct tcf_result	res;
 };
 
 struct tcindex_filter {
-	__u16 key;
+	u16 key;
 	struct tcindex_filter_result result;
 	struct tcindex_filter *next;
 };
@@ -64,60 +64,64 @@
 	struct tcindex_filter_result *perfect; /* perfect hash; NULL if none */
 	struct tcindex_filter **h; /* imperfect hash; only used if !perfect;
 				      NULL if unused */
-	__u16 mask;		/* AND key with mask */
+	u16 mask;		/* AND key with mask */
 	int shift;		/* shift ANDed key to the right */
 	int hash;		/* hash table size; 0 if undefined */
 	int alloc_hash;		/* allocated size */
 	int fall_through;	/* 0: only classify if explicit match */
 };
 
+static struct tcf_ext_map tcindex_ext_map = {
+	.police = TCA_TCINDEX_POLICE,
+	.action = TCA_TCINDEX_ACT
+};
+
+static inline int
+tcindex_filter_is_set(struct tcindex_filter_result *r)
+{
+	return tcf_exts_is_predicative(&r->exts) || r->res.classid;
+}
 
-static struct tcindex_filter_result *lookup(struct tcindex_data *p,__u16 key)
+static struct tcindex_filter_result *
+tcindex_lookup(struct tcindex_data *p, u16 key)
 {
 	struct tcindex_filter *f;
 
 	if (p->perfect)
-		return p->perfect[key].res.class ? p->perfect+key : NULL;
-	if (!p->h)
-		return NULL;
-	for (f = p->h[key % p->hash]; f; f = f->next) {
-		if (f->key == key)
-			return &f->result;
+		return tcindex_filter_is_set(p->perfect + key) ?
+			p->perfect + key : NULL;
+	else if (p->h) {
+		for (f = p->h[key % p->hash]; f; f = f->next)
+			if (f->key == key)
+				return &f->result;
 	}
+
 	return NULL;
 }
 
 
 static int tcindex_classify(struct sk_buff *skb, struct tcf_proto *tp,
-			  struct tcf_result *res)
+			    struct tcf_result *res)
 {
 	struct tcindex_data *p = PRIV(tp);
 	struct tcindex_filter_result *f;
+	int key = (skb->tc_index & p->mask) >> p->shift;
 
 	D2PRINTK("tcindex_classify(skb %p,tp %p,res %p),p %p\n",skb,tp,res,p);
 
-	f = lookup(p,(skb->tc_index & p->mask) >> p->shift);
+	f = tcindex_lookup(p, key);
 	if (!f) {
 		if (!p->fall_through)
 			return -1;
-		res->classid = TC_H_MAKE(TC_H_MAJ(tp->q->handle),
-		    (skb->tc_index& p->mask) >> p->shift);
+		res->classid = TC_H_MAKE(TC_H_MAJ(tp->q->handle), key);
 		res->class = 0;
 		D2PRINTK("alg 0x%x\n",res->classid);
 		return 0;
 	}
 	*res = f->res;
 	D2PRINTK("map 0x%x\n",res->classid);
-#ifdef CONFIG_NET_CLS_POLICE
-	if (f->police) {
-		int result;
-
-		result = tcf_police(skb,f->police);
-		D2PRINTK("police %d\n",res);
-		return result;
-	}
-#endif
-	return 0;
+
+	return tcf_exts_exec(skb, &f->exts, res);
 }
 
 
@@ -129,8 +133,8 @@
 	DPRINTK("tcindex_get(tp %p,handle 0x%08x)\n",tp,handle);
 	if (p->perfect && handle >= p->alloc_hash)
 		return 0;
-	r = lookup(PRIV(tp),handle);
-	return r && r->res.class ? (unsigned long) r : 0;
+	r = tcindex_lookup(p, handle);
+	return r && tcindex_filter_is_set(r) ? (unsigned long) r : 0UL;
 }
 
 
@@ -149,13 +153,12 @@
 	if (!p)
 		return -ENOMEM;
 
-	tp->root = p;
-	p->perfect = NULL;
-	p->h = NULL;
-	p->hash = 0;
+	memset(p, 0, sizeof(*p));
 	p->mask = 0xffff;
-	p->shift = 0;
+	p->hash = DEFAULT_HASH_SIZE;
 	p->fall_through = 1;
+
+	tp->root = p;
 	return 0;
 }
 
@@ -190,9 +193,7 @@
 			tcf_tree_unlock(tp);
 	}
 	tcf_unbind_filter(tp, &r->res);
-#ifdef CONFIG_NET_CLS_POLICE
-	tcf_police_release(r->police, TCA_ACT_UNBIND);
-#endif
+	tcf_exts_destroy(tp, &r->exts);
 	if (f)
 		kfree(f);
 	return 0;
@@ -203,148 +204,184 @@
 	return __tcindex_delete(tp, arg, 1);
 }
 
-/*
- * There are no parameters for tcindex_init, so we overload tcindex_change
- */
+static inline int
+valid_perfect_hash(struct tcindex_data *p)
+{
+	return  p->hash > (p->mask >> p->shift);
+}
+
+static int
+tcindex_set_parms(struct tcf_proto *tp, unsigned long base, u32 handle,
+		  struct tcindex_data *p, struct tcindex_filter_result *r,
+		  struct rtattr **tb, struct rtattr *est)
+{
+	int err, balloc = 0;
+	struct tcindex_filter_result new_filter_result, *old_r = r;
+	struct tcindex_filter_result cr;
+	struct tcindex_data cp;
+	struct tcindex_filter *f = NULL; /* make gcc behave */
+	struct tcf_exts e;
+
+	err = tcf_exts_validate(tp, tb, est, &e, &tcindex_ext_map);
+	if (err < 0)
+		return err;
+	
+	memcpy(&cp, p, sizeof(cp));
+	memset(&new_filter_result, 0, sizeof(new_filter_result));
+
+	if (old_r)
+		memcpy(&cr, r, sizeof(cr));
+	else
+		memset(&cr, 0, sizeof(cr));
+
+	err = -EINVAL;
+	if (tb[TCA_TCINDEX_HASH-1]) {
+		if (RTA_PAYLOAD(tb[TCA_TCINDEX_HASH-1]) < sizeof(u32))
+			goto errout;
+		cp.hash = *(u32 *) RTA_DATA(tb[TCA_TCINDEX_HASH-1]);
+	}
+
+	if (tb[TCA_TCINDEX_MASK-1]) {
+		if (RTA_PAYLOAD(tb[TCA_TCINDEX_MASK-1]) < sizeof(u16))
+			goto errout;
+		cp.mask = *(u16 *) RTA_DATA(tb[TCA_TCINDEX_MASK-1]);
+	}
+
+	if (tb[TCA_TCINDEX_SHIFT-1]) {
+		if (RTA_PAYLOAD(tb[TCA_TCINDEX_SHIFT-1]) < sizeof(u16))
+			goto errout;
+		cp.shift = *(u16 *) RTA_DATA(tb[TCA_TCINDEX_SHIFT-1]);
+	}
+
+	err = -EBUSY;
+	/* Hash already allocated, make sure that we still meet the
+	 * requirements for the allocated hash.
+	 */
+	if (cp.perfect) {
+		if (!valid_perfect_hash(&cp) ||
+		    cp.hash > cp.alloc_hash)
+			goto errout;
+	} else if (cp.h && cp.hash != cp.alloc_hash)
+		goto errout;
+
+	err = -EINVAL;
+	if (tb[TCA_TCINDEX_FALL_THROUGH-1]) {
+		if (RTA_PAYLOAD(tb[TCA_TCINDEX_FALL_THROUGH-1]) < sizeof(u32))
+			goto errout;
+		cp.fall_through =
+			*(u32 *) RTA_DATA(tb[TCA_TCINDEX_FALL_THROUGH-1]);
+	}
+
+	if (!cp.hash) {
+		/* Hash not specified, use perfect hash if the upper limit
+		 * of the hashing index is below the threshold.
+		 */
+		if ((cp.mask >> cp.shift) < PERFECT_HASH_THRESHOLD)
+			cp.hash = (cp.mask >> cp.shift)+1;
+		else
+			cp.hash = DEFAULT_HASH_SIZE;
+	}
+
+	if (!cp.perfect && !cp.h)
+		cp.alloc_hash = cp.hash;
+
+	/* Note: this could be as restrictive as if (handle & ~(mask >> shift))
+	 * but then, we'd fail handles that may become valid after some future
+	 * mask change. While this is extremely unlikely to ever matter,
+	 * the check below is safer (and also more backwards-compatible).
+	 */
+	if (cp.perfect || valid_perfect_hash(&cp))
+		if (handle >= cp.alloc_hash)
+			goto errout;
+
+
+	err = -ENOMEM;
+	if (!cp.perfect && !cp.h) {
+		if (valid_perfect_hash(&cp)) {
+			cp.perfect = kmalloc(cp.hash * sizeof(*r), GFP_KERNEL);
+			if (!cp.perfect)
+				goto errout;
+			memset(cp.perfect, 0, cp.hash * sizeof(*r));
+			balloc = 1;
+		} else {
+			cp.h = kmalloc(cp.hash * sizeof(f), GFP_KERNEL);
+			if (!cp.h)
+				goto errout;
+			memset(cp.h, 0, cp.hash * sizeof(f));
+			balloc = 2;
+		}
+	}
+
+	if (cp.perfect)
+		r = cp.perfect + handle;
+	else
+		r = tcindex_lookup(&cp, handle) ? : &new_filter_result;
+
+	if (r == &new_filter_result) {
+		f = kmalloc(sizeof(*f), GFP_KERNEL);
+		if (!f)
+			goto errout_alloc;
+		memset(f, 0, sizeof(*f));
+ 	}
+
+	if (tb[TCA_TCINDEX_CLASSID-1]) {
+		cr.res.classid = *(u32 *) RTA_DATA(tb[TCA_TCINDEX_CLASSID-1]);
+		tcf_bind_filter(tp, &cr.res, base);
+ 	}
+
+	tcf_exts_change(tp, &cr.exts, &e);
+
+	tcf_tree_lock(tp);
+	if (old_r && old_r != r)
+		memset(old_r, 0, sizeof(*old_r));
+
+	memcpy(p, &cp, sizeof(cp));
+	memcpy(r, &cr, sizeof(cr));
+
+	if (r == &new_filter_result) {
+		struct tcindex_filter **fp;
+
+		f->key = handle;
+		f->result = new_filter_result;
+		f->next = NULL;
+		for (fp = p->h+(handle % p->hash); *fp; fp = &(*fp)->next)
+			/* nothing */;
+		*fp = f;
+ 	}
+	tcf_tree_unlock(tp);
+
+	return 0;
 
+errout_alloc:
+	if (balloc == 1)
+		kfree(cp.perfect);
+	else if (balloc == 2)
+		kfree(cp.h);
+errout:
+	tcf_exts_destroy(tp, &e);
+	return err;
+}
 
-static int tcindex_change(struct tcf_proto *tp,unsigned long base,u32 handle,
-    struct rtattr **tca,unsigned long *arg)
-{
-	struct tcindex_filter_result new_filter_result = {
-		NULL,		/* no policing */
-		{ 0,0 },	/* no classification */
-	};
+static int
+tcindex_change(struct tcf_proto *tp, unsigned long base, u32 handle,
+	       struct rtattr **tca, unsigned long *arg)
+{
 	struct rtattr *opt = tca[TCA_OPTIONS-1];
 	struct rtattr *tb[TCA_TCINDEX_MAX];
 	struct tcindex_data *p = PRIV(tp);
-	struct tcindex_filter *f;
 	struct tcindex_filter_result *r = (struct tcindex_filter_result *) *arg;
-	struct tcindex_filter **walk;
-	int hash,shift;
-	__u16 mask;
 
 	DPRINTK("tcindex_change(tp %p,handle 0x%08x,tca %p,arg %p),opt %p,"
-	    "p %p,r %p\n",tp,handle,tca,arg,opt,p,r);
-	if (arg)
-		DPRINTK("*arg = 0x%lx\n",*arg);
+	    "p %p,r %p,*arg 0x%lx\n",
+	    tp, handle, tca, arg, opt, p, r, arg ? *arg : 0L);
+
 	if (!opt)
 		return 0;
-	if (rtattr_parse(tb,TCA_TCINDEX_MAX,RTA_DATA(opt),RTA_PAYLOAD(opt)) < 0)
-		return -EINVAL;
-	if (!tb[TCA_TCINDEX_HASH-1]) {
-		hash = p->hash;
-	} else {
-		if (RTA_PAYLOAD(tb[TCA_TCINDEX_HASH-1]) < sizeof(int))
-			return -EINVAL;
-		hash = *(int *) RTA_DATA(tb[TCA_TCINDEX_HASH-1]);
-	}
-	if (!tb[TCA_TCINDEX_MASK-1]) {
-		mask = p->mask;
-	} else {
-		if (RTA_PAYLOAD(tb[TCA_TCINDEX_MASK-1]) < sizeof(__u16))
-			return -EINVAL;
-		mask = *(__u16 *) RTA_DATA(tb[TCA_TCINDEX_MASK-1]);
-	}
-	if (!tb[TCA_TCINDEX_SHIFT-1])
-		shift = p->shift;
-	else {
-		if (RTA_PAYLOAD(tb[TCA_TCINDEX_SHIFT-1]) < sizeof(__u16))
-			return -EINVAL;
-		shift = *(int *) RTA_DATA(tb[TCA_TCINDEX_SHIFT-1]);
-	}
-	if (p->perfect && hash <= (mask >> shift))
-		return -EBUSY;
-	if (p->perfect && hash > p->alloc_hash)
-		return -EBUSY;
-	if (p->h && hash != p->alloc_hash)
-		return -EBUSY;
-	p->hash = hash;
-	p->mask = mask;
-	p->shift = shift;
-	if (tb[TCA_TCINDEX_FALL_THROUGH-1]) {
-		if (RTA_PAYLOAD(tb[TCA_TCINDEX_FALL_THROUGH-1]) < sizeof(int))
-			return -EINVAL;
-		p->fall_through =
-		    *(int *) RTA_DATA(tb[TCA_TCINDEX_FALL_THROUGH-1]);
-	}
-	DPRINTK("classid/police %p/%p\n",tb[TCA_TCINDEX_CLASSID-1],
-	    tb[TCA_TCINDEX_POLICE-1]);
-	if (!tb[TCA_TCINDEX_CLASSID-1] && !tb[TCA_TCINDEX_POLICE-1])
-		return 0;
-	if (!hash) {
-		if ((mask >> shift) < PERFECT_HASH_THRESHOLD) {
-			p->hash = (mask >> shift)+1;
-		} else {
-			p->hash = DEFAULT_HASH_SIZE;
-		}
-	}
-	if (!p->perfect && !p->h) {
-		p->alloc_hash = p->hash;
-		DPRINTK("hash %d mask %d\n",p->hash,p->mask);
-		if (p->hash > (mask >> shift)) {
-			p->perfect = kmalloc(p->hash*
-			    sizeof(struct tcindex_filter_result),GFP_KERNEL);
-			if (!p->perfect)
-				return -ENOMEM;
-			memset(p->perfect, 0,
-			       p->hash * sizeof(struct tcindex_filter_result));
-		} else {
-			p->h = kmalloc(p->hash*sizeof(struct tcindex_filter *),
-			    GFP_KERNEL);
-			if (!p->h)
-				return -ENOMEM;
-			memset(p->h, 0, p->hash*sizeof(struct tcindex_filter *));
-		}
-	}
-	/*
-	 * Note: this could be as restrictive as
-	 * if (handle & ~(mask >> shift))
-	 * but then, we'd fail handles that may become valid after some
-	 * future mask change. While this is extremely unlikely to ever
-	 * matter, the check below is safer (and also more
-	 * backwards-compatible).
-	 */
-	if (p->perfect && handle >= p->alloc_hash)
+
+	if (rtattr_parse_nested(tb, TCA_TCINDEX_MAX, opt) < 0)
 		return -EINVAL;
-	if (p->perfect) {
-		r = p->perfect+handle;
-	} else {
-		r = lookup(p,handle);
-		DPRINTK("r=%p\n",r);
-		if (!r)
-			r = &new_filter_result;
-	}
-	DPRINTK("r=%p\n",r);
-	if (tb[TCA_TCINDEX_CLASSID-1]) {
-		r->res.classid = *(__u32 *) RTA_DATA(tb[TCA_TCINDEX_CLASSID-1]);
-		tcf_bind_filter(tp, &r->res, base);
 
-		if (!r->res.class) {
-			r->res.classid = 0;
-			return -ENOENT;
-		}
-	}
-#ifdef CONFIG_NET_CLS_POLICE
-	if (tb[TCA_TCINDEX_POLICE-1]) {
-		int err = tcf_change_police(tp, &r->police, tb[TCA_TCINDEX_POLICE-1], NULL);
-		if (err < 0)
-			return err;
-	}
-#endif
-	if (r != &new_filter_result)
-		return 0;
-	f = kmalloc(sizeof(struct tcindex_filter),GFP_KERNEL);
-	if (!f)
-		return -ENOMEM;
-	f->key = handle;
-	f->result = new_filter_result;
-	f->next = NULL;
-	for (walk = p->h+(handle % p->hash); *walk; walk = &(*walk)->next)
-		/* nothing */;
-	wmb();
-	*walk = f;
-	return 0;
+	return tcindex_set_parms(tp, base, handle, p, r, tb, tca[TCA_RATE-1]);
 }
 
 
@@ -434,6 +471,7 @@
 		RTA_PUT(skb,TCA_TCINDEX_SHIFT,sizeof(p->shift),&p->shift);
 		RTA_PUT(skb,TCA_TCINDEX_FALL_THROUGH,sizeof(p->fall_through),
 		    &p->fall_through);
+		rta->rta_len = skb->tail-b;
 	} else {
 		if (p->perfect) {
 			t->tcm_handle = r-p->perfect;
@@ -453,12 +491,15 @@
 		DPRINTK("handle = %d\n",t->tcm_handle);
 		if (r->res.class)
 			RTA_PUT(skb, TCA_TCINDEX_CLASSID, 4, &r->res.classid);
-#ifdef CONFIG_NET_CLS_POLICE
-		if (tcf_dump_police(skb, r->police, TCA_TCINDEX_POLICE) < 0)
+
+		if (tcf_exts_dump(skb, &r->exts, &tcindex_ext_map) < 0)
+			goto rtattr_failure;
+		rta->rta_len = skb->tail-b;
+
+		if (tcf_exts_dump_stats(skb, &r->exts, &tcindex_ext_map) < 0)
 			goto rtattr_failure;
-#endif
 	}
-	rta->rta_len = skb->tail-b;
+	
 	return skb->len;
 
 rtattr_failure:
diff -Nru a/net/sched/cls_u32.c b/net/sched/cls_u32.c
--- a/net/sched/cls_u32.c	2005-03-01 23:38:54 -08:00
+++ b/net/sched/cls_u32.c	2005-03-01 23:38:54 -08:00
@@ -27,6 +27,7 @@
  *	JHS: We should remove the CONFIG_NET_CLS_IND from here
  *	eventually when the meta match extension is made available
  *
+ *	nfmark match added by Catalin(ux aka Dino) BOIE <catab at umbrella.ro>
  */
 
 #include <asm/uaccess.h>
@@ -58,18 +59,19 @@
 #include <net/pkt_cls.h>
 
 
+struct tc_u32_mark
+{
+	u32		val;
+	u32		mask;
+	u32		success;
+};
+
 struct tc_u_knode
 {
 	struct tc_u_knode	*next;
 	u32			handle;
 	struct tc_u_hnode	*ht_up;
-#ifdef CONFIG_NET_CLS_ACT
-	struct tc_action	*action;
-#else
-#ifdef CONFIG_NET_CLS_POLICE
-	struct tcf_police	*police;
-#endif
-#endif
+	struct tcf_exts		exts;
 #ifdef CONFIG_NET_CLS_IND
 	char                     indev[IFNAMSIZ];
 #endif
@@ -79,6 +81,9 @@
 #ifdef CONFIG_CLS_U32_PERF
 	struct tc_u32_pcnt	*pf;
 #endif
+#ifdef CONFIG_CLS_U32_MARK
+	struct tc_u32_mark	mark;
+#endif
 	struct tc_u32_sel	sel;
 };
 
@@ -86,6 +91,7 @@
 {
 	struct tc_u_hnode	*next;
 	u32			handle;
+	u32			prio;
 	struct tc_u_common	*tp_c;
 	int			refcnt;
 	unsigned		divisor;
@@ -101,6 +107,11 @@
 	u32			hgenerator;
 };
 
+static struct tcf_ext_map u32_ext_map = {
+	.action = TCA_U32_ACT,
+	.police = TCA_U32_POLICE
+};
+
 static struct tc_u_common *u32_list;
 
 static __inline__ unsigned u32_hash_fold(u32 key, struct tc_u32_sel *sel, u8 fshift)
@@ -126,7 +137,7 @@
 #ifdef CONFIG_CLS_U32_PERF
 	int j;
 #endif
-	int i;
+	int i, r;
 
 next_ht:
 	n = ht->ht[sel];
@@ -139,6 +150,16 @@
 		n->pf->rcnt +=1;
 		j = 0;
 #endif
+
+#ifdef CONFIG_CLS_U32_MARK
+		if ((skb->nfmark & n->mark.mask) != n->mark.val) {
+			n = n->next;
+			goto next_knode;
+		} else {
+			n->mark.success++;
+		}
+#endif
+
 		for (i = n->sel.nkeys; i>0; i--, key++) {
 
 			if ((*(u32*)(ptr+key->off+(off2&key->offmask))^key->val)&key->mask) {
@@ -164,22 +185,13 @@
 #ifdef CONFIG_CLS_U32_PERF
 				n->pf->rhit +=1;
 #endif
-#ifdef CONFIG_NET_CLS_ACT
-				if (n->action) {
-					int pol_res = tcf_action_exec(skb, n->action, res);
-					if (pol_res >= 0)
-						return pol_res;
-				} else
-#else
-#ifdef CONFIG_NET_CLS_POLICE
-				if (n->police) {
-					int pol_res = tcf_police(skb, n->police);
-					if (pol_res >= 0)
-						return pol_res;
-				} else
-#endif
-#endif
-					return 0;
+				r = tcf_exts_exec(skb, &n->exts, res);
+				if (r < 0) {
+					n = n->next;
+					goto next_knode;
+				}
+
+				return r;
 			}
 			n = n->next;
 			goto next_knode;
@@ -312,6 +324,7 @@
 	root_ht->divisor = 0;
 	root_ht->refcnt++;
 	root_ht->handle = tp_c ? gen_new_htid(tp_c) : 0x80000000;
+	root_ht->prio = tp->prio;
 
 	if (tp_c == NULL) {
 		tp_c = kmalloc(sizeof(*tp_c), GFP_KERNEL);
@@ -338,15 +351,7 @@
 static int u32_destroy_key(struct tcf_proto *tp, struct tc_u_knode *n)
 {
 	tcf_unbind_filter(tp, &n->res);
-#ifdef CONFIG_NET_CLS_ACT
-	if (n->action) {
-		tcf_action_destroy(n->action, TCA_ACT_UNBIND);
-	}
-#else
-#ifdef CONFIG_NET_CLS_POLICE
-	tcf_police_release(n->police, TCA_ACT_UNBIND);
-#endif
-#endif
+	tcf_exts_destroy(tp, &n->exts);
 	if (n->ht_down)
 		n->ht_down->refcnt--;
 #ifdef CONFIG_CLS_U32_PERF
@@ -488,18 +493,26 @@
 			 struct tc_u_knode *n, struct rtattr **tb,
 			 struct rtattr *est)
 {
+	int err;
+	struct tcf_exts e;
+
+	err = tcf_exts_validate(tp, tb, est, &e, &u32_ext_map);
+	if (err < 0)
+		return err;
+
+	err = -EINVAL;
 	if (tb[TCA_U32_LINK-1]) {
 		u32 handle = *(u32*)RTA_DATA(tb[TCA_U32_LINK-1]);
 		struct tc_u_hnode *ht_down = NULL;
 
 		if (TC_U32_KEY(handle))
-			return -EINVAL;
+			goto errout;
 
 		if (handle) {
 			ht_down = u32_lookup_ht(ht->tp_c, handle);
 
 			if (ht_down == NULL)
-				return -EINVAL;
+				goto errout;
 			ht_down->refcnt++;
 		}
 
@@ -514,36 +527,20 @@
 		n->res.classid = *(u32*)RTA_DATA(tb[TCA_U32_CLASSID-1]);
 		tcf_bind_filter(tp, &n->res, base);
 	}
-#ifdef CONFIG_NET_CLS_ACT
-	if (tb[TCA_U32_POLICE-1]) {
-		int err = tcf_change_act_police(tp, &n->action, tb[TCA_U32_POLICE-1], est);
-		if (err < 0)
-			return err;
-	}
 
-	if (tb[TCA_U32_ACT-1]) {
-		int err = tcf_change_act(tp, &n->action, tb[TCA_U32_ACT-1], est);
-		if (err < 0)
-			return err;
-	}
-#else
-#ifdef CONFIG_NET_CLS_POLICE
-	if (tb[TCA_U32_POLICE-1]) {
-		int err = tcf_change_police(tp, &n->police, tb[TCA_U32_POLICE-1], est);
-		if (err < 0)
-			return err;
-	}
-#endif
-#endif
 #ifdef CONFIG_NET_CLS_IND
 	if (tb[TCA_U32_INDEV-1]) {
 		int err = tcf_change_indev(tp, n->indev, tb[TCA_U32_INDEV-1]);
 		if (err < 0)
-			return err;
+			goto errout;
 	}
 #endif
+	tcf_exts_change(tp, &n->exts, &e);
 
 	return 0;
+errout:
+	tcf_exts_destroy(tp, &e);
+	return err;
 }
 
 static int u32_change(struct tcf_proto *tp, unsigned long base, u32 handle,
@@ -562,7 +559,7 @@
 	if (opt == NULL)
 		return handle ? -EINVAL : 0;
 
-	if (rtattr_parse(tb, TCA_U32_MAX, RTA_DATA(opt), RTA_PAYLOAD(opt)) < 0)
+	if (rtattr_parse_nested(tb, TCA_U32_MAX, opt) < 0)
 		return -EINVAL;
 
 	if ((n = (struct tc_u_knode*)*arg) != NULL) {
@@ -592,6 +589,7 @@
 		ht->refcnt = 0;
 		ht->divisor = divisor;
 		ht->handle = handle;
+		ht->prio = tp->prio;
 		ht->next = tp_c->hlist;
 		tp_c->hlist = ht;
 		*arg = (unsigned long)ht;
@@ -635,12 +633,12 @@
 
 	memset(n, 0, sizeof(*n) + s->nkeys*sizeof(struct tc_u32_key));
 #ifdef CONFIG_CLS_U32_PERF
-	n->pf = kmalloc(sizeof(struct tc_u32_pcnt) + s->nkeys*sizeof(__u64), GFP_KERNEL);
+	n->pf = kmalloc(sizeof(struct tc_u32_pcnt) + s->nkeys*sizeof(u64), GFP_KERNEL);
 	if (n->pf == NULL) {
 		kfree(n);
 		return -ENOBUFS;
 	}
-	memset(n->pf, 0, sizeof(struct tc_u32_pcnt) + s->nkeys*sizeof(__u64));
+	memset(n->pf, 0, sizeof(struct tc_u32_pcnt) + s->nkeys*sizeof(u64));
 #endif
 
 	memcpy(&n->sel, s, sizeof(*s) + s->nkeys*sizeof(struct tc_u32_key));
@@ -657,6 +655,24 @@
 	}
 	n->fshift = i;
 }
+
+#ifdef CONFIG_CLS_U32_MARK
+	if (tb[TCA_U32_MARK-1]) {
+		struct tc_u32_mark *mark;
+
+		if (RTA_PAYLOAD(tb[TCA_U32_MARK-1]) < sizeof(struct tc_u32_mark)) {
+#ifdef CONFIG_CLS_U32_PERF
+			kfree(n->pf);
+#endif
+			kfree(n);
+			return -EINVAL;
+		}
+		mark = RTA_DATA(tb[TCA_U32_MARK-1]);
+		memcpy(&n->mark, mark, sizeof(struct tc_u32_mark));
+		n->mark.success = 0;
+	}
+#endif
+
 	err = u32_set_parms(tp, base, ht, n, tb, tca[TCA_RATE-1]);
 	if (err == 0) {
 		struct tc_u_knode **ins;
@@ -690,6 +706,8 @@
 		return;
 
 	for (ht = tp_c->hlist; ht; ht = ht->next) {
+		if (ht->prio != tp->prio)
+			continue;
 		if (arg->count >= arg->skip) {
 			if (arg->fn(tp, (unsigned long)ht, arg) < 0) {
 				arg->stop = 1;
@@ -744,42 +762,30 @@
 			RTA_PUT(skb, TCA_U32_CLASSID, 4, &n->res.classid);
 		if (n->ht_down)
 			RTA_PUT(skb, TCA_U32_LINK, 4, &n->ht_down->handle);
-#ifdef CONFIG_NET_CLS_ACT
-		if (tcf_dump_act(skb, n->action, TCA_U32_ACT, TCA_U32_POLICE) < 0)
-			goto rtattr_failure;
-#else
-#ifdef CONFIG_NET_CLS_POLICE
-		if (tcf_dump_police(skb, n->police, TCA_U32_POLICE) < 0)
-			goto rtattr_failure;
-#endif
+
+#ifdef CONFIG_CLS_U32_MARK
+		if (n->mark.val || n->mark.mask)
+			RTA_PUT(skb, TCA_U32_MARK, sizeof(n->mark), &n->mark);
 #endif
 
+		if (tcf_exts_dump(skb, &n->exts, &u32_ext_map) < 0)
+			goto rtattr_failure;
+
 #ifdef CONFIG_NET_CLS_IND
 		if(strlen(n->indev))
 			RTA_PUT(skb, TCA_U32_INDEV, IFNAMSIZ, n->indev);
 #endif
 #ifdef CONFIG_CLS_U32_PERF
 		RTA_PUT(skb, TCA_U32_PCNT, 
-		sizeof(struct tc_u32_pcnt) + n->sel.nkeys*sizeof(__u64),
+		sizeof(struct tc_u32_pcnt) + n->sel.nkeys*sizeof(u64),
 			n->pf);
 #endif
 	}
 
 	rta->rta_len = skb->tail - b;
-#ifdef CONFIG_NET_CLS_ACT
-	if (TC_U32_KEY(n->handle) != 0) {
-		if (TC_U32_KEY(n->handle) && n->action && n->action->type == TCA_OLD_COMPAT) {
-			if (tcf_action_copy_stats(skb,n->action))
-				goto rtattr_failure;
-		}
-	}
-#else
-#ifdef CONFIG_NET_CLS_POLICE
-	if (TC_U32_KEY(n->handle) && n->police)
-		if (tcf_police_dump_stats(skb, n->police) < 0)
+	if (TC_U32_KEY(n->handle))
+		if (tcf_exts_dump_stats(skb, &n->exts, &u32_ext_map) < 0)
 			goto rtattr_failure;
-#endif
-#endif
 	return skb->len;
 
 rtattr_failure:
diff -Nru a/net/sched/estimator.c b/net/sched/estimator.c
--- a/net/sched/estimator.c	2005-03-01 23:38:52 -08:00
+++ b/net/sched/estimator.c	2005-03-01 23:38:52 -08:00
@@ -95,7 +95,7 @@
 static struct qdisc_estimator_head elist[EST_MAX_INTERVAL+1];
 
 /* Estimator array lock */
-static rwlock_t est_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(est_lock);
 
 static void est_timer(unsigned long arg)
 {
diff -Nru a/net/sched/gact.c b/net/sched/gact.c
--- a/net/sched/gact.c	2005-03-01 23:38:58 -08:00
+++ b/net/sched/gact.c	2005-03-01 23:38:58 -08:00
@@ -38,103 +38,98 @@
 /* use generic hash table */
 #define MY_TAB_SIZE	16
 #define MY_TAB_MASK	15
+
 static u32 idx_gen;
 static struct tcf_gact *tcf_gact_ht[MY_TAB_SIZE];
-static rwlock_t gact_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(gact_lock);
 
 /* ovewrride the defaults */
-#define tcf_st  tcf_gact
-#define tc_st  tc_gact
-#define tcf_t_lock   gact_lock
-#define tcf_ht tcf_gact_ht
+#define tcf_st		tcf_gact
+#define tc_st		tc_gact
+#define tcf_t_lock	gact_lock
+#define tcf_ht		tcf_gact_ht
 
 #define CONFIG_NET_ACT_INIT 1
 #include <net/pkt_act.h>
 
 #ifdef CONFIG_GACT_PROB
-typedef int (*g_rand)(struct tcf_gact *p);
-static int
-gact_net_rand(struct tcf_gact *p) {
+static int gact_net_rand(struct tcf_gact *p)
+{
 	if (net_random()%p->pval)
 		return p->action;
 	return p->paction;
 }
 
-static int
-gact_determ(struct tcf_gact *p) {
+static int gact_determ(struct tcf_gact *p)
+{
 	if (p->bstats.packets%p->pval)
 		return p->action;
 	return p->paction;
 }
 
-
-g_rand gact_rand[MAX_RAND]= { NULL,gact_net_rand, gact_determ};
-
+typedef int (*g_rand)(struct tcf_gact *p);
+static g_rand gact_rand[MAX_RAND]= { NULL, gact_net_rand, gact_determ };
 #endif
-static int
-tcf_gact_init(struct rtattr *rta, struct rtattr *est, struct tc_action *a,int ovr,int bind)
+
+static int tcf_gact_init(struct rtattr *rta, struct rtattr *est,
+                         struct tc_action *a, int ovr, int bind)
 {
 	struct rtattr *tb[TCA_GACT_MAX];
-	struct tc_gact *parm = NULL;
-#ifdef CONFIG_GACT_PROB
-	struct tc_gact_p *p_parm = NULL;
-#endif
-	struct tcf_gact *p = NULL;
+	struct tc_gact *parm;
+	struct tcf_gact *p;
 	int ret = 0;
-	int size = sizeof (*p);
 
-	if (rtattr_parse(tb, TCA_GACT_MAX, RTA_DATA(rta), RTA_PAYLOAD(rta)) < 0)
-		return -1;
-
-	if (NULL == a || NULL == tb[TCA_GACT_PARMS - 1]) {
-		printk("BUG: tcf_gact_init called with NULL params\n");
-		return -1;
-	}
+	if (rta == NULL || rtattr_parse_nested(tb, TCA_GACT_MAX, rta) < 0)
+		return -EINVAL;
 
+	if (tb[TCA_GACT_PARMS - 1] == NULL ||
+	    RTA_PAYLOAD(tb[TCA_GACT_PARMS - 1]) < sizeof(*parm))
+		return -EINVAL;
 	parm = RTA_DATA(tb[TCA_GACT_PARMS - 1]);
+
+	if (tb[TCA_GACT_PROB-1] != NULL)
 #ifdef CONFIG_GACT_PROB
-	if (NULL != tb[TCA_GACT_PROB - 1]) {
-		p_parm = RTA_DATA(tb[TCA_GACT_PROB - 1]);
-	}
+		if (RTA_PAYLOAD(tb[TCA_GACT_PROB-1]) < sizeof(struct tc_gact_p))
+			return -EINVAL;
+#else
+		return -EOPNOTSUPP;
 #endif
 
-	p = tcf_hash_check(parm, a, ovr, bind);
-
-	if (NULL == p) {
-		p = tcf_hash_create(parm,est,a,size,ovr, bind);
-
-		if (NULL == p) {
-			return -1;
-		} else {
-			p->refcnt = 1;
-			ret = 1;
-			goto override;
+	p = tcf_hash_check(parm->index, a, ovr, bind);
+	if (p == NULL) {
+		p = tcf_hash_create(parm->index, est, a, sizeof(*p), ovr, bind);
+		if (p == NULL)
+			return -ENOMEM;
+		ret = ACT_P_CREATED;
+	} else {
+		if (!ovr) {
+			tcf_hash_release(p, bind);
+			return -EEXIST;
 		}
 	}
 
-	if (ovr) {
-override:
-		p->action = parm->action;
+	spin_lock_bh(&p->lock);
+	p->action = parm->action;
 #ifdef CONFIG_GACT_PROB
-		if (NULL != p_parm) {
-			p->paction = p_parm->paction;
-			p->pval = p_parm->pval;
-			p->ptype = p_parm->ptype;
-		} else {
-			p->paction = p->pval = p->ptype = 0;
-		}
-#endif
+	if (tb[TCA_GACT_PROB-1] != NULL) {
+		struct tc_gact_p *p_parm = RTA_DATA(tb[TCA_GACT_PROB-1]);
+		p->paction = p_parm->paction;
+		p->pval    = p_parm->pval;
+		p->ptype   = p_parm->ptype;
 	}
-
+#endif
+	spin_unlock_bh(&p->lock);
+	if (ret == ACT_P_CREATED)
+		tcf_hash_insert(p);
 	return ret;
 }
 
 static int
 tcf_gact_cleanup(struct tc_action *a, int bind)
 {
-	struct tcf_gact *p;
-	p = PRIV(a,gact);
-	if (NULL != p)
+	struct tcf_gact *p = PRIV(a, gact);
+
+	if (p != NULL)
 		return tcf_hash_release(p, bind);
 	return 0;
 }
@@ -142,21 +137,13 @@
 static int
 tcf_gact(struct sk_buff **pskb, struct tc_action *a)
 {
-	struct tcf_gact *p;
+	struct tcf_gact *p = PRIV(a, gact);
 	struct sk_buff *skb = *pskb;
 	int action = TC_ACT_SHOT;
 
-	p = PRIV(a,gact);
-
-	if (NULL == p) {
-		if (net_ratelimit())
-			printk("BUG: tcf_gact called with NULL params\n");
-		return -1;
-	}
-
 	spin_lock(&p->lock);
 #ifdef CONFIG_GACT_PROB
-	if (p->ptype && NULL != gact_rand[p->ptype])
+	if (p->ptype && gact_rand[p->ptype] != NULL)
 		action = gact_rand[p->ptype](p);
 	else
 		action = p->action;
@@ -165,7 +152,7 @@
 #endif
 	p->bstats.bytes += skb->len;
 	p->bstats.packets++;
-	if (TC_ACT_SHOT == action)
+	if (action == TC_ACT_SHOT)
 		p->qstats.drops++;
 	p->tm.lastuse = jiffies;
 	spin_unlock(&p->lock);
@@ -178,35 +165,27 @@
 {
 	unsigned char *b = skb->tail;
 	struct tc_gact opt;
-#ifdef CONFIG_GACT_PROB
-	struct tc_gact_p p_opt;
-#endif
-	struct tcf_gact *p;
+	struct tcf_gact *p = PRIV(a, gact);
 	struct tcf_t t;
 
-	p = PRIV(a,gact);
-	if (NULL == p) {
-		printk("BUG: tcf_gact_dump called with NULL params\n");
-		goto rtattr_failure;
-	}
-
 	opt.index = p->index;
 	opt.refcnt = p->refcnt - ref;
 	opt.bindcnt = p->bindcnt - bind;
 	opt.action = p->action;
-	RTA_PUT(skb, TCA_GACT_PARMS, sizeof (opt), &opt);
+	RTA_PUT(skb, TCA_GACT_PARMS, sizeof(opt), &opt);
 #ifdef CONFIG_GACT_PROB
 	if (p->ptype) {
+		struct tc_gact_p p_opt;
 		p_opt.paction = p->paction;
 		p_opt.pval = p->pval;
 		p_opt.ptype = p->ptype;
-		RTA_PUT(skb, TCA_GACT_PROB, sizeof (p_opt), &p_opt);
-	} 
+		RTA_PUT(skb, TCA_GACT_PROB, sizeof(p_opt), &p_opt);
+	}
 #endif
 	t.install = jiffies_to_clock_t(jiffies - p->tm.install);
 	t.lastuse = jiffies_to_clock_t(jiffies - p->tm.lastuse);
 	t.expires = jiffies_to_clock_t(p->tm.expires);
-	RTA_PUT(skb, TCA_GACT_TM, sizeof (t), &t);
+	RTA_PUT(skb, TCA_GACT_TM, sizeof(t), &t);
 	return skb->len;
 
       rtattr_failure:
@@ -215,7 +194,6 @@
 }
 
 static struct tc_action_ops act_gact_ops = {
-	.next		=	NULL,
 	.kind		=	"gact",
 	.type		=	TCA_ACT_GACT,
 	.capab		=	TCA_CAP_NONE,
diff -Nru a/net/sched/ipt.c b/net/sched/ipt.c
--- a/net/sched/ipt.c	2005-03-01 23:38:44 -08:00
+++ b/net/sched/ipt.c	2005-03-01 23:38:44 -08:00
@@ -31,6 +31,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/proc_fs.h>
+#include <linux/kmod.h>
 #include <net/sock.h>
 #include <net/pkt_sched.h>
 #include <linux/tc_act/tc_ipt.h>
@@ -45,212 +46,170 @@
 static u32 idx_gen;
 static struct tcf_ipt *tcf_ipt_ht[MY_TAB_SIZE];
 /* ipt hash table lock */
-static rwlock_t ipt_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(ipt_lock);
 
 /* ovewrride the defaults */
-#define tcf_st  tcf_ipt
-#define tcf_t_lock   ipt_lock
-#define tcf_ht tcf_ipt_ht
+#define tcf_st		tcf_ipt
+#define tcf_t_lock	ipt_lock
+#define tcf_ht		tcf_ipt_ht
 
+#define CONFIG_NET_ACT_INIT
 #include <net/pkt_act.h>
 
-static inline int
-init_targ(struct tcf_ipt *p)
+static int
+ipt_init_target(struct ipt_entry_target *t, char *table, unsigned int hook)
 {
 	struct ipt_target *target;
 	int ret = 0;
-	struct ipt_entry_target *t = p->t;
-	target = __ipt_find_target_lock(t->u.user.name, &ret);
 
-	if (!target) {
-		printk("init_targ: Failed to find %s\n", t->u.user.name);
-		return -1;
-	}
+	target = ipt_find_target(t->u.user.name, t->u.user.revision);
+	if (!target)
+		return -ENOENT;
 
-	DPRINTK("init_targ: found %s\n", target->name);
-	/* we really need proper ref counting
-	 seems to be only needed for modules?? Talk to laforge */
-/*      if (target->me)
-              __MOD_INC_USE_COUNT(target->me);
-*/
+	DPRINTK("ipt_init_target: found %s\n", target->name);
 	t->u.kernel.target = target;
 
-	__ipt_mutex_up();
-
 	if (t->u.kernel.target->checkentry
-	    && !t->u.kernel.target->checkentry(p->tname, NULL, t->data,
-					       t->u.target_size
-					       - sizeof (*t), p->hook)) {
-/*              if (t->u.kernel.target->me)
-	      __MOD_DEC_USE_COUNT(t->u.kernel.target->me);
-*/
-		DPRINTK("ip_tables: check failed for `%s'.\n",
+	    && !t->u.kernel.target->checkentry(table, NULL, t->data,
+					       t->u.target_size - sizeof(*t),
+					       hook)) {
+		DPRINTK("ipt_init_target: check failed for `%s'.\n",
 			t->u.kernel.target->name);
+		module_put(t->u.kernel.target->me);
 		ret = -EINVAL;
 	}
 
 	return ret;
 }
 
+static void
+ipt_destroy_target(struct ipt_entry_target *t)
+{
+	if (t->u.kernel.target->destroy)
+		t->u.kernel.target->destroy(t->data,
+		                            t->u.target_size - sizeof(*t));
+        module_put(t->u.kernel.target->me);
+}
+
 static int
-tcf_ipt_init(struct rtattr *rta, struct rtattr *est, struct tc_action *a, int ovr, int bind)
+tcf_ipt_release(struct tcf_ipt *p, int bind)
 {
-	struct ipt_entry_target *t;
-	unsigned h;
-	struct rtattr *tb[TCA_IPT_MAX];
-	struct tcf_ipt *p;
 	int ret = 0;
-	u32 index = 0;
-	u32 hook = 0;
-
-	if (NULL == a || NULL == rta ||
-	    (rtattr_parse(tb, TCA_IPT_MAX, RTA_DATA(rta), RTA_PAYLOAD(rta)) <
-	     0)) {
-		return -1;
-	}
-
-
-	if (tb[TCA_IPT_INDEX - 1]) {
-		index = *(u32 *) RTA_DATA(tb[TCA_IPT_INDEX - 1]);
-		DPRINTK("ipt index %d\n", index);
-	}
-
-	if (index && (p = tcf_hash_lookup(index)) != NULL) {
-		a->priv = (void *) p;
-		spin_lock(&p->lock);
-		if (bind) {
-			p->bindcnt += 1;
-			p->refcnt += 1;
-		}
-		if (ovr) {
-			goto override;
+	if (p) {
+		if (bind)
+			p->bindcnt--;
+		p->refcnt--;
+		if (p->bindcnt <= 0 && p->refcnt <= 0) {
+			ipt_destroy_target(p->t);
+			kfree(p->tname);
+			kfree(p->t);
+			tcf_hash_destroy(p);
+			ret = ACT_P_DELETED;
 		}
-		spin_unlock(&p->lock);
-		return ret;
 	}
+	return ret;
+}
 
-	if (NULL == tb[TCA_IPT_TARG - 1] || NULL == tb[TCA_IPT_HOOK - 1]) {
-		return -1;
-	}
+static int
+tcf_ipt_init(struct rtattr *rta, struct rtattr *est, struct tc_action *a,
+             int ovr, int bind)
+{
+	struct rtattr *tb[TCA_IPT_MAX];
+	struct tcf_ipt *p;
+	struct ipt_entry_target *td, *t;
+	char *tname;
+	int ret = 0, err;
+	u32 hook = 0;
+	u32 index = 0;
 
-	p = kmalloc(sizeof (*p), GFP_KERNEL);
-	if (p == NULL)
-		return -1;
-
-	memset(p, 0, sizeof (*p));
-	p->refcnt = 1;
-	ret = 1;
-	spin_lock_init(&p->lock);
-	p->stats_lock = &p->lock;
-	if (bind)
-		p->bindcnt = 1;
-
-override:
-	hook = *(u32 *) RTA_DATA(tb[TCA_IPT_HOOK - 1]);
-
-	t = (struct ipt_entry_target *) RTA_DATA(tb[TCA_IPT_TARG - 1]);
-
-	p->t = kmalloc(t->u.target_size, GFP_KERNEL);
-	if (p->t == NULL) {
-		if (ovr) {
-			printk("ipt policy messed up \n");
-			spin_unlock(&p->lock);
-			return -1;
-		}
-		kfree(p);
-		return -1;
-	}
+	if (rta == NULL || rtattr_parse_nested(tb, TCA_IPT_MAX, rta) < 0)
+		return -EINVAL;
 
-	memcpy(p->t, RTA_DATA(tb[TCA_IPT_TARG - 1]), t->u.target_size);
-	DPRINTK(" target NAME %s size %d data[0] %x data[1] %x\n",
-		t->u.user.name, t->u.target_size, t->data[0], t->data[1]);
-
-	p->tname = kmalloc(IFNAMSIZ, GFP_KERNEL);
-
-	if (p->tname == NULL) {
-		if (ovr) {
-			printk("ipt policy messed up 2 \n");
-			spin_unlock(&p->lock);
-			return -1;
-		}
-		kfree(p->t);
-		kfree(p);
-		return -1;
+	if (tb[TCA_IPT_HOOK-1] == NULL ||
+	    RTA_PAYLOAD(tb[TCA_IPT_HOOK-1]) < sizeof(u32))
+		return -EINVAL;
+	if (tb[TCA_IPT_TARG-1] == NULL ||
+	    RTA_PAYLOAD(tb[TCA_IPT_TARG-1]) < sizeof(*t))
+		return -EINVAL;
+	td = (struct ipt_entry_target *)RTA_DATA(tb[TCA_IPT_TARG-1]);
+	if (RTA_PAYLOAD(tb[TCA_IPT_TARG-1]) < td->u.target_size)
+		return -EINVAL;
+
+	if (tb[TCA_IPT_INDEX-1] != NULL &&
+	    RTA_PAYLOAD(tb[TCA_IPT_INDEX-1]) >= sizeof(u32))
+		index = *(u32 *)RTA_DATA(tb[TCA_IPT_INDEX-1]);
+
+	p = tcf_hash_check(index, a, ovr, bind);
+	if (p == NULL) {
+		p = tcf_hash_create(index, est, a, sizeof(*p), ovr, bind);
+		if (p == NULL)
+			return -ENOMEM;
+		ret = ACT_P_CREATED;
 	} else {
-		int csize = IFNAMSIZ - 1;
-
-		memset(p->tname, 0, IFNAMSIZ);
-		if (tb[TCA_IPT_TABLE - 1]) {
-			if (strlen((char *) RTA_DATA(tb[TCA_IPT_TABLE - 1])) <
-			    csize)
-				csize = strlen(RTA_DATA(tb[TCA_IPT_TABLE - 1]));
-			strncpy(p->tname, RTA_DATA(tb[TCA_IPT_TABLE - 1]),
-				csize);
-			DPRINTK("table name %s\n", p->tname);
-		} else {
-			strncpy(p->tname, "mangle", 1 + strlen("mangle"));
+		if (!ovr) {
+			tcf_ipt_release(p, bind);
+			return -EEXIST;
 		}
 	}
 
-	if (0 > init_targ(p)) {
-		if (ovr) {
-			printk("ipt policy messed up 2 \n");
-			spin_unlock(&p->lock);
-			return -1;
-		}
+	hook = *(u32 *)RTA_DATA(tb[TCA_IPT_HOOK-1]);
+
+	err = -ENOMEM;
+	tname = kmalloc(IFNAMSIZ, GFP_KERNEL);
+	if (tname == NULL)
+		goto err1;
+	if (tb[TCA_IPT_TABLE - 1] == NULL ||
+	    rtattr_strlcpy(tname, tb[TCA_IPT_TABLE-1], IFNAMSIZ) >= IFNAMSIZ)
+		strcpy(tname, "mangle");
+
+	t = kmalloc(td->u.target_size, GFP_KERNEL);
+	if (t == NULL)
+		goto err2;
+	memcpy(t, td, td->u.target_size);
+
+	if ((err = ipt_init_target(t, tname, hook)) < 0)
+		goto err3;
+
+	spin_lock_bh(&p->lock);
+	if (ret != ACT_P_CREATED) {
+		ipt_destroy_target(p->t);
 		kfree(p->tname);
 		kfree(p->t);
-		kfree(p);
-		return -1;
-	}
-
-	if (ovr) {
-		spin_unlock(&p->lock);
-		return -1;
 	}
-
-	p->index = index ? : tcf_hash_new_index();
-
-	p->tm.lastuse = jiffies;
-	/*
-	p->tm.expires = jiffies;
-	*/
-	p->tm.install = jiffies;
-#ifdef CONFIG_NET_ESTIMATOR
-	if (est)
-		gen_new_estimator(&p->bstats, &p->rate_est, p->stats_lock, est);
-#endif
-	h = tcf_hash(p->index);
-	write_lock_bh(&ipt_lock);
-	p->next = tcf_ipt_ht[h];
-	tcf_ipt_ht[h] = p;
-	write_unlock_bh(&ipt_lock);
-	a->priv = (void *) p;
+	p->tname = tname;
+	p->t     = t;
+	p->hook  = hook;
+	spin_unlock_bh(&p->lock);
+	if (ret == ACT_P_CREATED)
+		tcf_hash_insert(p);
 	return ret;
 
+err3:
+	kfree(t);
+err2:
+	kfree(tname);
+err1:
+	kfree(p);
+	return err;
 }
 
 static int
 tcf_ipt_cleanup(struct tc_action *a, int bind)
 {
-	struct tcf_ipt *p;
-	p = PRIV(a,ipt);
-	if (NULL != p)
-		return tcf_hash_release(p, bind);
-	return 0;
+	struct tcf_ipt *p = PRIV(a, ipt);
+	return tcf_ipt_release(p, bind);
 }
 
 static int
 tcf_ipt(struct sk_buff **pskb, struct tc_action *a)
 {
 	int ret = 0, result = 0;
-	struct tcf_ipt *p;
+	struct tcf_ipt *p = PRIV(a, ipt);
 	struct sk_buff *skb = *pskb;
 
-	p = PRIV(a,ipt);
-
-	if (NULL == p || NULL == skb) {
-		return -1;
+	if (skb_cloned(skb)) {
+		if (pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
+			return TC_ACT_UNSPEC;
 	}
 
 	spin_lock(&p->lock);
@@ -259,17 +218,12 @@
 	p->bstats.bytes += skb->len;
 	p->bstats.packets++;
 
-	if (skb_cloned(skb) ) {
-		if (pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) {
-			return -1;
-		}
-	}
 	/* yes, we have to worry about both in and out dev
 	 worry later - danger - this API seems to have changed
 	 from earlier kernels */
 
 	ret = p->t->u.kernel.target->target(&skb, skb->dev, NULL,
-					    p->hook, p->t->data, (void *)NULL);
+					    p->hook, p->t->data, NULL);
 	switch (ret) {
 	case NF_ACCEPT:
 		result = TC_ACT_OK;
@@ -299,22 +253,15 @@
 	struct tcf_t tm;
 	struct tc_cnt c;
 	unsigned char *b = skb->tail;
+	struct tcf_ipt *p = PRIV(a, ipt);
 
-	struct tcf_ipt *p;
-
-	p = PRIV(a,ipt);
-	if (NULL == p) {
-		printk("BUG: tcf_ipt_dump called with NULL params\n");
-		goto rtattr_failure;
-	}
 	/* for simple targets kernel size == user size
 	** user name = target name
 	** for foolproof you need to not assume this
 	*/
 
 	t = kmalloc(p->t->u.user.target_size, GFP_ATOMIC);
-
-	if (NULL == t)
+	if (t == NULL)
 		goto rtattr_failure;
 
 	c.bindcnt = p->bindcnt - bind;
@@ -324,10 +271,10 @@
 
 	DPRINTK("\ttcf_ipt_dump tablename %s length %d\n", p->tname,
 		strlen(p->tname));
-	DPRINTK
-	    ("\tdump target name %s size %d size user %d data[0] %x data[1] %x\n",
-	     p->t->u.kernel.target->name, p->t->u.target_size, p->t->u.user.target_size,
-	     p->t->data[0], p->t->data[1]);
+	DPRINTK("\tdump target name %s size %d size user %d "
+	        "data[0] %x data[1] %x\n", p->t->u.kernel.target->name,
+	        p->t->u.target_size, p->t->u.user.target_size,
+	        p->t->data[0], p->t->data[1]);
 	RTA_PUT(skb, TCA_IPT_TARG, p->t->u.user.target_size, t);
 	RTA_PUT(skb, TCA_IPT_INDEX, 4, &p->index);
 	RTA_PUT(skb, TCA_IPT_HOOK, 4, &p->hook);
@@ -345,7 +292,6 @@
 }
 
 static struct tc_action_ops act_ipt_ops = {
-	.next		=	NULL,
 	.kind		=	"ipt",
 	.type		=	TCA_ACT_IPT,
 	.capab		=	TCA_CAP_NONE,
diff -Nru a/net/sched/mirred.c b/net/sched/mirred.c
--- a/net/sched/mirred.c	2005-03-01 23:38:54 -08:00
+++ b/net/sched/mirred.c	2005-03-01 23:38:54 -08:00
@@ -46,13 +46,13 @@
 #define MY_TAB_MASK     (MY_TAB_SIZE - 1)
 static u32 idx_gen;
 static struct tcf_mirred *tcf_mirred_ht[MY_TAB_SIZE];
-static rwlock_t mirred_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(mirred_lock);
 
 /* ovewrride the defaults */
-#define tcf_st  tcf_mirred
-#define tc_st  tc_mirred
-#define tcf_t_lock   mirred_lock
-#define tcf_ht tcf_mirred_ht
+#define tcf_st		tcf_mirred
+#define tc_st		tc_mirred
+#define tcf_t_lock	mirred_lock
+#define tcf_ht		tcf_mirred_ht
 
 #define CONFIG_NET_ACT_INIT 1
 #include <net/pkt_act.h>
@@ -61,10 +61,8 @@
 tcf_mirred_release(struct tcf_mirred *p, int bind)
 {
 	if (p) {
-		if (bind) {
+		if (bind)
 			p->bindcnt--;
-		}
-
 		p->refcnt--;
 		if(!p->bindcnt && p->refcnt <= 0) {
 			dev_put(p->dev);
@@ -72,46 +70,32 @@
 			return 1;
 		}
 	}
-
 	return 0;
 }
 
 static int
-tcf_mirred_init(struct rtattr *rta, struct rtattr *est, struct tc_action *a,int ovr, int bind)
+tcf_mirred_init(struct rtattr *rta, struct rtattr *est, struct tc_action *a,
+                int ovr, int bind)
 {
 	struct rtattr *tb[TCA_MIRRED_MAX];
 	struct tc_mirred *parm;
 	struct tcf_mirred *p;
 	struct net_device *dev = NULL;
-	int size = sizeof (*p), new = 0;
+	int ret = 0;
+	int ok_push = 0;
 
+	if (rta == NULL || rtattr_parse_nested(tb, TCA_MIRRED_MAX, rta) < 0)
+		return -EINVAL;
 
-	if (rtattr_parse(tb, TCA_MIRRED_MAX, RTA_DATA(rta), RTA_PAYLOAD(rta)) < 0) {
-		DPRINTK("tcf_mirred_init BUG in user space couldnt parse properly\n");
-		return -1;
-	}
-
-	if (NULL == a || NULL == tb[TCA_MIRRED_PARMS - 1]) {
-		DPRINTK("BUG: tcf_mirred_init called with NULL params\n");
-		return -1;
-	}
-
-	parm = RTA_DATA(tb[TCA_MIRRED_PARMS - 1]);
-
-	p = tcf_hash_check(parm, a, ovr, bind);
-	if (NULL == p) { /* new */
-		p = tcf_hash_create(parm,est,a,size,ovr,bind);
-		new = 1;
-		if (NULL == p)
-			return -1;
-	}
+	if (tb[TCA_MIRRED_PARMS-1] == NULL ||
+	    RTA_PAYLOAD(tb[TCA_MIRRED_PARMS-1]) < sizeof(*parm))
+		return -EINVAL;
+	parm = RTA_DATA(tb[TCA_MIRRED_PARMS-1]);
 
 	if (parm->ifindex) {
-		dev = dev_get_by_index(parm->ifindex);
-		if (NULL == dev) {
-			printk("BUG: tcf_mirred_init called with bad device\n");
-			return -1;
-		}
+		dev = __dev_get_by_index(parm->ifindex);
+		if (dev == NULL)
+			return -ENODEV;
 		switch (dev->type) {
 			case ARPHRD_TUNNEL:
 			case ARPHRD_TUNNEL6:
@@ -119,44 +103,56 @@
 			case ARPHRD_IPGRE:
 			case ARPHRD_VOID:
 			case ARPHRD_NONE:
-				p->ok_push = 0;
+				ok_push = 0;
 				break;
 			default:
-				p->ok_push = 1;
+				ok_push = 1;
 				break;
 		}
-	} else {
-		if (new) {
-			kfree(p);
-			return -1;
-		}	
 	}
 
-	if (new || ovr) {
-		spin_lock(&p->lock);
-		p->action = parm->action;
-		p->eaction = parm->eaction;
-		if (parm->ifindex) {
-			p->ifindex = parm->ifindex;
-			if (ovr)
-				dev_put(p->dev);
-			p->dev = dev;
+	p = tcf_hash_check(parm->index, a, ovr, bind);
+	if (p == NULL) {
+		if (!parm->ifindex)
+			return -EINVAL;
+		p = tcf_hash_create(parm->index, est, a, sizeof(*p), ovr, bind);
+		if (p == NULL)
+			return -ENOMEM;
+		ret = ACT_P_CREATED;
+	} else {
+		if (!ovr) {
+			tcf_mirred_release(p, bind);
+			return -EEXIST;
 		}
-		spin_unlock(&p->lock);
 	}
 
-
-	DPRINTK(" tcf_mirred_init index %d action %d eaction %d device %s ifndex %d\n",parm->index,parm->action,parm->eaction,dev->name,parm->ifindex);
-	return new;
-
+	spin_lock_bh(&p->lock);
+	p->action = parm->action;
+	p->eaction = parm->eaction;
+	if (parm->ifindex) {
+		p->ifindex = parm->ifindex;
+		if (ret != ACT_P_CREATED)
+			dev_put(p->dev);
+		p->dev = dev;
+		dev_hold(dev);
+		p->ok_push = ok_push;
+	}
+	spin_unlock_bh(&p->lock);
+	if (ret == ACT_P_CREATED)
+		tcf_hash_insert(p);
+
+	DPRINTK("tcf_mirred_init index %d action %d eaction %d device %s "
+	        "ifindex %d\n", parm->index, parm->action, parm->eaction,
+	        dev->name, parm->ifindex);
+	return ret;
 }
 
 static int
 tcf_mirred_cleanup(struct tc_action *a, int bind)
 {
-	struct tcf_mirred *p;
-	p = PRIV(a,mirred);
-	if (NULL != p)
+	struct tcf_mirred *p = PRIV(a, mirred);
+
+	if (p != NULL)
 		return tcf_mirred_release(p, bind);
 	return 0;
 }
@@ -164,70 +160,52 @@
 static int
 tcf_mirred(struct sk_buff **pskb, struct tc_action *a)
 {
-	struct tcf_mirred *p;
+	struct tcf_mirred *p = PRIV(a, mirred);
 	struct net_device *dev;
 	struct sk_buff *skb2 = NULL;
 	struct sk_buff *skb = *pskb;
-	__u32 at = G_TC_AT(skb->tc_verd);
-
-	if (NULL == a) {
-		if (net_ratelimit())
-			printk("BUG: tcf_mirred called with NULL action!\n");
-		return -1;
-	}
-
-	p = PRIV(a,mirred);
-
-	if (NULL == p) {
-		if (net_ratelimit())
-			printk("BUG: tcf_mirred called with NULL params\n");
-		return -1;
-	}
+	u32 at = G_TC_AT(skb->tc_verd);
 
 	spin_lock(&p->lock);
 
-       	dev = p->dev;
+	dev = p->dev;
 	p->tm.lastuse = jiffies;
 
-	if (NULL == dev || !(dev->flags&IFF_UP) ) {
+	if (!(dev->flags&IFF_UP) ) {
 		if (net_ratelimit())
 			printk("mirred to Houston: device %s is gone!\n",
-					dev?dev->name:"");
+			       dev->name);
 bad_mirred:
-		if (NULL != skb2)
+		if (skb2 != NULL)
 			kfree_skb(skb2);
 		p->qstats.overlimits++;
 		p->bstats.bytes += skb->len;
 		p->bstats.packets++;
 		spin_unlock(&p->lock);
 		/* should we be asking for packet to be dropped?
-		 * may make sense for redirect case only 
+		 * may make sense for redirect case only
 		*/
 		return TC_ACT_SHOT;
-	} 
+	}
 
 	skb2 = skb_clone(skb, GFP_ATOMIC);
-	if (skb2 == NULL) {
+	if (skb2 == NULL)
 		goto bad_mirred;
-	}
-	if (TCA_EGRESS_MIRROR != p->eaction &&
-		TCA_EGRESS_REDIR != p->eaction) {
+	if (p->eaction != TCA_EGRESS_MIRROR && p->eaction != TCA_EGRESS_REDIR) {
 		if (net_ratelimit())
-			printk("tcf_mirred unknown action %d\n",p->eaction);
+			printk("tcf_mirred unknown action %d\n", p->eaction);
 		goto bad_mirred;
 	}
 
 	p->bstats.bytes += skb2->len;
 	p->bstats.packets++;
-	if ( !(at & AT_EGRESS)) {
-		if (p->ok_push) {
+	if (!(at & AT_EGRESS))
+		if (p->ok_push)
 			skb_push(skb2, skb2->dev->hard_header_len);
-		}
-	}
 
 	/* mirror is always swallowed */
-	if (TCA_EGRESS_MIRROR != p->eaction)
-		skb2->tc_verd = SET_TC_FROM(skb2->tc_verd,at);
+	if (p->eaction != TCA_EGRESS_MIRROR)
+		skb2->tc_verd = SET_TC_FROM(skb2->tc_verd, at);
 
 	skb2->dev = dev;
 	skb2->input_dev = skb->dev;
@@ -237,31 +215,26 @@
 }
 
 static int
-tcf_mirred_dump(struct sk_buff *skb, struct tc_action *a,int bind, int ref)
+tcf_mirred_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
 {
 	unsigned char *b = skb->tail;
 	struct tc_mirred opt;
-	struct tcf_mirred *p;
+	struct tcf_mirred *p = PRIV(a, mirred);
 	struct tcf_t t;
 
-	p = PRIV(a,mirred);
-	if (NULL == p) {
-		printk("BUG: tcf_mirred_dump called with NULL params\n");
-		goto rtattr_failure;
-	}
-
 	opt.index = p->index;
 	opt.action = p->action;
 	opt.refcnt = p->refcnt - ref;
 	opt.bindcnt = p->bindcnt - bind;
 	opt.eaction = p->eaction;
 	opt.ifindex = p->ifindex;
-	DPRINTK(" tcf_mirred_dump index %d action %d eaction %d ifndex %d\n",p->index,p->action,p->eaction,p->ifindex);
-	RTA_PUT(skb, TCA_MIRRED_PARMS, sizeof (opt), &opt);
+	DPRINTK("tcf_mirred_dump index %d action %d eaction %d ifindex %d\n",
+	         p->index, p->action, p->eaction, p->ifindex);
+	RTA_PUT(skb, TCA_MIRRED_PARMS, sizeof(opt), &opt);
 	t.install = jiffies_to_clock_t(jiffies - p->tm.install);
 	t.lastuse = jiffies_to_clock_t(jiffies - p->tm.lastuse);
 	t.expires = jiffies_to_clock_t(p->tm.expires);
-	RTA_PUT(skb, TCA_MIRRED_TM, sizeof (t), &t);
+	RTA_PUT(skb, TCA_MIRRED_TM, sizeof(t), &t);
 	return skb->len;
 
       rtattr_failure:
@@ -270,7 +243,6 @@
 }
 
 static struct tc_action_ops act_mirred_ops = {
-	.next		=	NULL,
 	.kind		=	"mirred",
 	.type		=	TCA_ACT_MIRRED,
 	.capab		=	TCA_CAP_NONE,
@@ -287,7 +259,6 @@
 MODULE_DESCRIPTION("Device Mirror/redirect actions");
 MODULE_LICENSE("GPL");
 
-
 static int __init
 mirred_init_module(void)
 {
@@ -303,4 +274,3 @@
 
 module_init(mirred_init_module);
 module_exit(mirred_cleanup_module);
-
diff -Nru a/net/sched/pedit.c b/net/sched/pedit.c
--- a/net/sched/pedit.c	2005-03-01 23:39:08 -08:00
+++ b/net/sched/pedit.c	2005-03-01 23:39:08 -08:00
@@ -42,92 +42,101 @@
 #define MY_TAB_MASK     15
 static u32 idx_gen;
 static struct tcf_pedit *tcf_pedit_ht[MY_TAB_SIZE];
-static rwlock_t pedit_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(pedit_lock);
 
-#define tcf_st  tcf_pedit
-#define tc_st  tc_pedit
-#define tcf_t_lock   pedit_lock
-#define tcf_ht tcf_pedit_ht
+#define tcf_st		tcf_pedit
+#define tc_st		tc_pedit
+#define tcf_t_lock	pedit_lock
+#define tcf_ht		tcf_pedit_ht
 
 #define CONFIG_NET_ACT_INIT 1
 #include <net/pkt_act.h>
 
-
 static int
-tcf_pedit_init(struct rtattr *rta, struct rtattr *est, struct tc_action *a,int ovr, int bind)
+tcf_pedit_init(struct rtattr *rta, struct rtattr *est, struct tc_action *a,
+               int ovr, int bind)
 {
 	struct rtattr *tb[TCA_PEDIT_MAX];
 	struct tc_pedit *parm;
-	int size = 0;
 	int ret = 0;
-	struct tcf_pedit *p = NULL;
-
-	if (rtattr_parse(tb, TCA_PEDIT_MAX, RTA_DATA(rta), RTA_PAYLOAD(rta)) < 0)
-		return -1;
-
-	if (NULL == a || NULL == tb[TCA_PEDIT_PARMS - 1]) {
-		printk("BUG: tcf_pedit_init called with NULL params\n");
-		return -1;
-	}
-
-	parm = RTA_DATA(tb[TCA_PEDIT_PARMS - 1]);
+	struct tcf_pedit *p;
+	struct tc_pedit_key *keys = NULL;
+	int ksize;
 
-	p = tcf_hash_check(parm, a, ovr, bind);
+	if (rta == NULL || rtattr_parse_nested(tb, TCA_PEDIT_MAX, rta) < 0)
+		return -EINVAL;
 
-	if (NULL == p) { /* new */
+	if (tb[TCA_PEDIT_PARMS - 1] == NULL ||
+	    RTA_PAYLOAD(tb[TCA_PEDIT_PARMS-1]) < sizeof(*parm))
+		return -EINVAL;
+	parm = RTA_DATA(tb[TCA_PEDIT_PARMS-1]);
+	ksize = parm->nkeys * sizeof(struct tc_pedit_key);
+	if (RTA_PAYLOAD(tb[TCA_PEDIT_PARMS-1]) < sizeof(*parm) + ksize)
+		return -EINVAL;
 
+	p = tcf_hash_check(parm->index, a, ovr, bind);
+	if (p == NULL) {
 		if (!parm->nkeys)
-			return -1;
-
-		size = sizeof (*p)+ (parm->nkeys*sizeof(struct tc_pedit_key));
-
-		p = tcf_hash_create(parm,est,a,size,ovr,bind);
-
-		if (NULL == p)
-			return -1;
-		ret = 1;
-		goto override;
-	} 
+			return -EINVAL;
+		p = tcf_hash_create(parm->index, est, a, sizeof(*p), ovr, bind);
+		if (p == NULL)
+			return -ENOMEM;
+		keys = kmalloc(ksize, GFP_KERNEL);
+		if (keys == NULL) {
+			kfree(p);
+			return -ENOMEM;
+		}
+		ret = ACT_P_CREATED;
+	} else {
+		if (!ovr) {
+			tcf_hash_release(p, bind);
+			return -EEXIST;
+		}
+		if (p->nkeys && p->nkeys != parm->nkeys) {
+			keys = kmalloc(ksize, GFP_KERNEL);
+			if (keys == NULL)
+				return -ENOMEM;
+		}
+	}
 
-	if (ovr) {
-override:
-		p->flags = parm->flags;
+	spin_lock_bh(&p->lock);
+	p->flags = parm->flags;
+	p->action = parm->action;
+	if (keys) {
+		kfree(p->keys);
+		p->keys = keys;
 		p->nkeys = parm->nkeys;
-		p->action = parm->action;
-		memcpy(p->keys,parm->keys,parm->nkeys*(sizeof(struct tc_pedit_key)));
 	}
-
+	memcpy(p->keys, parm->keys, ksize);
+	spin_unlock_bh(&p->lock);
+	if (ret == ACT_P_CREATED)
+		tcf_hash_insert(p);
 	return ret;
 }
 
 static int
 tcf_pedit_cleanup(struct tc_action *a, int bind)
 {
-	struct tcf_pedit *p;
-	p = PRIV(a,pedit);
-	if (NULL != p)
-		return	tcf_hash_release(p, bind);
+	struct tcf_pedit *p = PRIV(a, pedit);
+
+	if (p != NULL) {
+		struct tc_pedit_key *keys = p->keys;
+		if (tcf_hash_release(p, bind)) {
+			kfree(keys);
+			return 1;
+		}
+	}
 	return 0;
 }
 
-/*
-**
-*/
 static int
 tcf_pedit(struct sk_buff **pskb, struct tc_action *a)
 {
-	struct tcf_pedit *p;
+	struct tcf_pedit *p = PRIV(a, pedit);
 	struct sk_buff *skb = *pskb;
 	int i, munged = 0;
 	u8 *pptr;
 
-	p = PRIV(a,pedit);
-
-	if (NULL == p) {
-		printk("BUG: tcf_pedit called with NULL params\n");
-		return -1; /* change to something symbolic */
-	}
-
 	if (!(skb->tc_verd & TC_OK2MUNGE)) {
 		/* should we set skb->cloned? */
 		if (pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) {
@@ -141,17 +150,18 @@
 
 	p->tm.lastuse = jiffies;
 
-	if (0 < p->nkeys) {
+	if (p->nkeys > 0) {
 		struct tc_pedit_key *tkey = p->keys;
 
 		for (i = p->nkeys; i > 0; i--, tkey++) {
-			u32 *ptr ;
-
+			u32 *ptr;
 			int offset = tkey->off;
+
 			if (tkey->offmask) {
 				if (skb->len > tkey->at) {
-					 char *j = pptr+tkey->at;
-					 offset +=((*j&tkey->offmask)>>tkey->shift);
+					 char *j = pptr + tkey->at;
+					 offset += ((*j & tkey->offmask) >> 
+					           tkey->shift);
 				} else {
 					goto bad;
 				}
@@ -161,14 +171,12 @@
 				printk("offset must be on 32 bit boundaries\n");
 				goto bad;
 			}
-
 			if (skb->len < 0 || (offset > 0 && offset > skb->len)) {
 				printk("offset %d cant exceed pkt length %d\n",
-						offset, skb->len);
+				       offset, skb->len);
 				goto bad;
 			}
 
-
 			ptr = (u32 *)(pptr+offset);
 			/* just do it, baby */
 			*ptr = ((*ptr & tkey->mask) ^ tkey->val);
@@ -196,29 +204,19 @@
 {
 	unsigned char *b = skb->tail;
 	struct tc_pedit *opt;
-	struct tcf_pedit *p;
+	struct tcf_pedit *p = PRIV(a, pedit);
 	struct tcf_t t;
 	int s; 
 		
+	s = sizeof(*opt) + p->nkeys * sizeof(struct tc_pedit_key);
 
-	p = PRIV(a,pedit);
-
-	if (NULL == p) {
-		printk("BUG: tcf_pedit_dump called with NULL params\n");
-		goto rtattr_failure;
-	}
-
-	s = sizeof (*opt)+(p->nkeys*sizeof(struct tc_pedit_key));
-
-	/* netlink spinlocks held above us - must use ATOMIC
-	 * */
+	/* netlink spinlocks held above us - must use ATOMIC */
 	opt = kmalloc(s, GFP_ATOMIC);
 	if (opt == NULL)
 		return -ENOBUFS;
-
 	memset(opt, 0, s);
 
-	memcpy(opt->keys,p->keys,p->nkeys*(sizeof(struct tc_pedit_key)));
+	memcpy(opt->keys, p->keys, p->nkeys * sizeof(struct tc_pedit_key));
 	opt->index = p->index;
 	opt->nkeys = p->nkeys;
 	opt->flags = p->flags;
@@ -239,15 +237,15 @@
 			(unsigned int)key->off,
 			(unsigned int)key->val,
 			(unsigned int)key->mask);
-												}
-											}
+		}
+	}
 #endif
 
 	RTA_PUT(skb, TCA_PEDIT_PARMS, s, opt);
 	t.install = jiffies_to_clock_t(jiffies - p->tm.install);
 	t.lastuse = jiffies_to_clock_t(jiffies - p->tm.lastuse);
 	t.expires = jiffies_to_clock_t(p->tm.expires);
-	RTA_PUT(skb, TCA_PEDIT_TM, sizeof (t), &t);
+	RTA_PUT(skb, TCA_PEDIT_TM, sizeof(t), &t);
 	return skb->len;
 
 rtattr_failure:
diff -Nru a/net/sched/police.c b/net/sched/police.c
--- a/net/sched/police.c	2005-03-01 23:39:16 -08:00
+++ b/net/sched/police.c	2005-03-01 23:39:16 -08:00
@@ -43,7 +43,7 @@
 static u32 idx_gen;
 static struct tcf_police *tcf_police_ht[MY_TAB_SIZE];
 /* Policer hash table lock */
-static rwlock_t police_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(police_lock);
 
 /* Each policer is serialized by its individual spinlock */
 
@@ -66,11 +66,12 @@
 }
 
 #ifdef CONFIG_NET_CLS_ACT
-static __inline__ int tcf_generic_walker(struct sk_buff *skb, struct netlink_callback *cb, int type, struct tc_action *a)
+static int tcf_generic_walker(struct sk_buff *skb, struct netlink_callback *cb,
+                              int type, struct tc_action *a)
 {
 	struct tcf_police *p;
-	int err =0, index =  -1,i= 0, s_i = 0, n_i = 0;
-	struct rtattr *r ;
+	int err = 0, index = -1, i = 0, s_i = 0, n_i = 0;
+	struct rtattr *r;
 
 	read_lock(&police_lock);
 
@@ -91,7 +92,7 @@
 				err = tcf_action_dump_1(skb, a, 0, 1);
 			else
 				err = tcf_action_dump_1(skb, a, 0, 0);
-			if (0 > err) {
+			if (err < 0) {
 				index--;
 				skb_trim(skb, (u8*)r - skb->data);
 				goto done;
@@ -123,11 +124,9 @@
 		return 0;
 	}
 }
-
-
 #endif
 
-static __inline__ u32 tcf_police_new_index(void)
+static inline u32 tcf_police_new_index(void)
 {
 	do {
 		if (++idx_gen == 0)
@@ -137,7 +136,6 @@
 	return idx_gen;
 }
 
-
 void tcf_police_destroy(struct tcf_police *p)
 {
 	unsigned h = tcf_police_hash(p->index);
@@ -163,48 +161,48 @@
 }
 
 #ifdef CONFIG_NET_CLS_ACT
-int tcf_act_police_locate(struct rtattr *rta, struct rtattr *est,struct tc_action *a, int ovr, int bind)
+static int tcf_act_police_locate(struct rtattr *rta, struct rtattr *est,
+                                 struct tc_action *a, int ovr, int bind)
 {
 	unsigned h;
-	int ret = 0;
+	int ret = 0, err;
 	struct rtattr *tb[TCA_POLICE_MAX];
 	struct tc_police *parm;
 	struct tcf_police *p;
+	struct qdisc_rate_table *R_tab = NULL, *P_tab = NULL;
 
-	if (NULL == a) {
-		if (net_ratelimit())
-			printk("BUG: tcf_police_locate called with NULL params\n");
-		return -1;  
-	}
-
-	if (rtattr_parse(tb, TCA_POLICE_MAX, RTA_DATA(rta), RTA_PAYLOAD(rta)) < 0)
-		return -1;
-
-	if (tb[TCA_POLICE_TBF-1] == NULL)
-		return -1;
+	if (rta == NULL || rtattr_parse_nested(tb, TCA_POLICE_MAX, rta) < 0)
+		return -EINVAL;
 
+	if (tb[TCA_POLICE_TBF-1] == NULL ||
+	    RTA_PAYLOAD(tb[TCA_POLICE_TBF-1]) != sizeof(*parm))
+		return -EINVAL;
 	parm = RTA_DATA(tb[TCA_POLICE_TBF-1]);
 
+	if (tb[TCA_POLICE_RESULT-1] != NULL &&
+	    RTA_PAYLOAD(tb[TCA_POLICE_RESULT-1]) != sizeof(u32))
+		return -EINVAL;
+	if (tb[TCA_POLICE_RESULT-1] != NULL &&
+	    RTA_PAYLOAD(tb[TCA_POLICE_RESULT-1]) != sizeof(u32))
+		return -EINVAL;
+
 	if (parm->index && (p = tcf_police_lookup(parm->index)) != NULL) {
-		a->priv = (void *)p;
-		spin_lock(&p->lock);
+		a->priv = p;
 		if (bind) {
 			p->bindcnt += 1;
 			p->refcnt += 1;
 		}
-		if (ovr) {
+		if (ovr)
 			goto override;
-		}
-		spin_unlock(&p->lock);
-		return ret; 
+		return ret;
 	}
 
 	p = kmalloc(sizeof(*p), GFP_KERNEL);
 	if (p == NULL)
-		return -1;
-
+		return -ENOMEM;
 	memset(p, 0, sizeof(*p));
-	ret = 1;
+
+	ret = ACT_P_CREATED;
 	p->refcnt = 1;
 	spin_lock_init(&p->lock);
 	p->stats_lock = &p->lock;
@@ -212,20 +210,32 @@
 		p->bindcnt = 1;
 override:
 	if (parm->rate.rate) {
-		if ((p->R_tab = qdisc_get_rtab(&parm->rate, tb[TCA_POLICE_RATE-1])) == NULL) {
-			goto failure;
-		}
-		if (parm->peakrate.rate &&
-		    (p->P_tab = qdisc_get_rtab(&parm->peakrate, tb[TCA_POLICE_PEAKRATE-1])) == NULL) {
+		err = -ENOMEM;
+		R_tab = qdisc_get_rtab(&parm->rate, tb[TCA_POLICE_RATE-1]);
+		if (R_tab == NULL)
 			goto failure;
+		if (parm->peakrate.rate) {
+			P_tab = qdisc_get_rtab(&parm->peakrate,
+					       tb[TCA_POLICE_PEAKRATE-1]);
+			if (p->P_tab == NULL) {
+				qdisc_put_rtab(R_tab);
+				goto failure;
+			}
 		}
 	}
+	/* No failure allowed after this point */
+	spin_lock_bh(&p->lock);
+	if (R_tab != NULL) {
+		qdisc_put_rtab(p->R_tab);
+		p->R_tab = R_tab;
+	}
+	if (P_tab != NULL) {
+		qdisc_put_rtab(p->P_tab);
+		p->P_tab = P_tab;
+	}
+
 	if (tb[TCA_POLICE_RESULT-1])
-		p->result = *(int*)RTA_DATA(tb[TCA_POLICE_RESULT-1]);
-#ifdef CONFIG_NET_ESTIMATOR
-	if (tb[TCA_POLICE_AVRATE-1])
-		p->ewma_rate = *(u32*)RTA_DATA(tb[TCA_POLICE_AVRATE-1]);
-#endif
+		p->result = *(u32*)RTA_DATA(tb[TCA_POLICE_RESULT-1]);
 	p->toks = p->burst = parm->burst;
 	p->mtu = parm->mtu;
 	if (p->mtu == 0) {
@@ -237,59 +247,51 @@
 		p->ptoks = L2T_P(p, p->mtu);
 	p->action = parm->action;
 
-	if (ovr) {
-		spin_unlock(&p->lock);
-		return ret;
-	}
-	PSCHED_GET_TIME(p->t_c);
-	p->index = parm->index ? : tcf_police_new_index();
 #ifdef CONFIG_NET_ESTIMATOR
+	if (tb[TCA_POLICE_AVRATE-1])
+		p->ewma_rate = *(u32*)RTA_DATA(tb[TCA_POLICE_AVRATE-1]);
 	if (est)
-		gen_new_estimator(&p->bstats, &p->rate_est, p->stats_lock, est);
+		gen_replace_estimator(&p->bstats, &p->rate_est, p->stats_lock, est);
 #endif
+
+	spin_unlock_bh(&p->lock);
+	if (ret != ACT_P_CREATED)
+		return ret;
+
+	PSCHED_GET_TIME(p->t_c);
+	p->index = parm->index ? : tcf_police_new_index();
 	h = tcf_police_hash(p->index);
 	write_lock_bh(&police_lock);
 	p->next = tcf_police_ht[h];
 	tcf_police_ht[h] = p;
 	write_unlock_bh(&police_lock);
 
-	a->priv = (void *)p;
-	return ret;  
+	a->priv = p;
+	return ret;
 
 failure:
-	if (p->R_tab)
-		qdisc_put_rtab(p->R_tab);
-	if (ovr)
-		spin_unlock(&p->lock);
-	kfree(p);
-	return -1;
+	if (ret == ACT_P_CREATED)
+		kfree(p);
+	return err;
 }
 
-int tcf_act_police_cleanup(struct tc_action *a, int bind)
+static int tcf_act_police_cleanup(struct tc_action *a, int bind)
 {
-	struct tcf_police *p;
-	p = PRIV(a);
-	if (NULL != p) 
-		return tcf_police_release(p, bind);
+	struct tcf_police *p = PRIV(a);
 
+	if (p != NULL)
+		return tcf_police_release(p, bind);
 	return 0;
 }
 
-int tcf_act_police(struct sk_buff **pskb, struct tc_action *a)
+static int tcf_act_police(struct sk_buff **pskb, struct tc_action *a)
 {
 	psched_time_t now;
 	struct sk_buff *skb = *pskb;
-	struct tcf_police *p;
+	struct tcf_police *p = PRIV(a);
 	long toks;
 	long ptoks = 0;
 
-	p = PRIV(a);
-
-	if (NULL == p) {
-		printk("BUG: tcf_police called with NULL params\n");
-		return -1;  
-	}
-
 	spin_lock(&p->lock);
 
 	p->bstats.bytes += skb->len;
@@ -338,17 +340,12 @@
 	return p->action;
 }
 
-int tcf_act_police_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
+static int
+tcf_act_police_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
 {
 	unsigned char	 *b = skb->tail;
 	struct tc_police opt;
-	struct tcf_police *p;
-
-	p = PRIV(a);
-	if (NULL == p) {
-		printk("BUG: tcf_police_dump called with NULL params\n");
-		goto rtattr_failure;
-	}
+	struct tcf_police *p = PRIV(a);
 
 	opt.index = p->index;
 	opt.action = p->action;
@@ -382,12 +379,10 @@
 MODULE_DESCRIPTION("Policing actions");
 MODULE_LICENSE("GPL");
 
-
 static struct tc_action_ops act_police_ops = {
-	.next		=	NULL,
 	.kind		=	"police",
-	.type		=	TCA_ID_POLICE, 
-	.capab		=	TCA_CAP_NONE, 
+	.type		=	TCA_ID_POLICE,
+	.capab		=	TCA_CAP_NONE,
 	.owner		=	THIS_MODULE,
 	.act		=	tcf_act_police,
 	.dump		=	tcf_act_police_dump,
@@ -421,10 +416,11 @@
 	struct rtattr *tb[TCA_POLICE_MAX];
 	struct tc_police *parm;
 
-	if (rtattr_parse(tb, TCA_POLICE_MAX, RTA_DATA(rta), RTA_PAYLOAD(rta)) < 0)
+	if (rtattr_parse_nested(tb, TCA_POLICE_MAX, rta) < 0)
 		return NULL;
 
-	if (tb[TCA_POLICE_TBF-1] == NULL)
+	if (tb[TCA_POLICE_TBF-1] == NULL ||
+	    RTA_PAYLOAD(tb[TCA_POLICE_TBF-1]) != sizeof(*parm))
 		return NULL;
 
 	parm = RTA_DATA(tb[TCA_POLICE_TBF-1]);
@@ -443,17 +439,27 @@
 	spin_lock_init(&p->lock);
 	p->stats_lock = &p->lock;
 	if (parm->rate.rate) {
-		if ((p->R_tab = qdisc_get_rtab(&parm->rate, tb[TCA_POLICE_RATE-1])) == NULL)
+		p->R_tab = qdisc_get_rtab(&parm->rate, tb[TCA_POLICE_RATE-1]);
+		if (p->R_tab == NULL)
 			goto failure;
-		if (parm->peakrate.rate &&
-		    (p->P_tab = qdisc_get_rtab(&parm->peakrate, tb[TCA_POLICE_PEAKRATE-1])) == NULL)
+		if (parm->peakrate.rate) {
+			p->P_tab = qdisc_get_rtab(&parm->peakrate,
+			                          tb[TCA_POLICE_PEAKRATE-1]);
+			if (p->P_tab == NULL)
+				goto failure;
+		}
+	}
+	if (tb[TCA_POLICE_RESULT-1]) {
+		if (RTA_PAYLOAD(tb[TCA_POLICE_RESULT-1]) != sizeof(u32))
 			goto failure;
+		p->result = *(u32*)RTA_DATA(tb[TCA_POLICE_RESULT-1]);
 	}
-	if (tb[TCA_POLICE_RESULT-1])
-		p->result = *(int*)RTA_DATA(tb[TCA_POLICE_RESULT-1]);
 #ifdef CONFIG_NET_ESTIMATOR
-	if (tb[TCA_POLICE_AVRATE-1])
+	if (tb[TCA_POLICE_AVRATE-1]) {
+		if (RTA_PAYLOAD(tb[TCA_POLICE_AVRATE-1]) != sizeof(u32))
+			goto failure;
 		p->ewma_rate = *(u32*)RTA_DATA(tb[TCA_POLICE_AVRATE-1]);
+	}
 #endif
 	p->toks = p->burst = parm->burst;
 	p->mtu = parm->mtu;
diff -Nru a/net/sched/sch_api.c b/net/sched/sch_api.c
--- a/net/sched/sch_api.c	2005-03-01 23:38:56 -08:00
+++ b/net/sched/sch_api.c	2005-03-01 23:38:56 -08:00
@@ -131,7 +131,7 @@
  */
 
 /* Protects list of registered TC modules. It is pure SMP lock. */
-static rwlock_t qdisc_mod_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(qdisc_mod_lock);
 
 
 /************************************************
@@ -207,7 +207,7 @@
 	return NULL;
 }
 
-struct Qdisc *qdisc_leaf(struct Qdisc *p, u32 classid)
+static struct Qdisc *qdisc_leaf(struct Qdisc *p, u32 classid)
 {
 	unsigned long cl;
 	struct Qdisc *leaf;
@@ -226,7 +226,7 @@
 
 /* Find queueing discipline by name */
 
-struct Qdisc_ops *qdisc_lookup_ops(struct rtattr *kind)
+static struct Qdisc_ops *qdisc_lookup_ops(struct rtattr *kind)
 {
 	struct Qdisc_ops *q = NULL;
 
@@ -290,7 +290,7 @@
 
 /* Allocate an unique handle from space managed by kernel */
 
-u32 qdisc_alloc_handle(struct net_device *dev)
+static u32 qdisc_alloc_handle(struct net_device *dev)
 {
 	int i = 0x10000;
 	static u32 autohandle = TC_H_MAKE(0x80000000U, 0);
@@ -356,8 +356,9 @@
    Old qdisc is not destroyed but returned in *old.
  */
 
-int qdisc_graft(struct net_device *dev, struct Qdisc *parent, u32 classid,
-		struct Qdisc *new, struct Qdisc **old)
+static int qdisc_graft(struct net_device *dev, struct Qdisc *parent,
+		       u32 classid,
+		       struct Qdisc *new, struct Qdisc **old)
 {
 	int err = 0;
 	struct Qdisc *q = *old;
@@ -406,8 +407,9 @@
 	ops = qdisc_lookup_ops(kind);
 #ifdef CONFIG_KMOD
 	if (ops==NULL && tca[TCA_KIND-1] != NULL) {
-		if (RTA_PAYLOAD(kind) <= IFNAMSIZ) {
-			request_module("sch_%s", (char*)RTA_DATA(kind));
+		char name[IFNAMSIZ];
+		if (rtattr_strlcpy(name, kind, IFNAMSIZ) < IFNAMSIZ) {
+			request_module("sch_%s", name);
 			ops = qdisc_lookup_ops(kind);
 		}
 	}
diff -Nru a/net/sched/sch_atm.c b/net/sched/sch_atm.c
--- a/net/sched/sch_atm.c	2005-03-01 23:38:56 -08:00
+++ b/net/sched/sch_atm.c	2005-03-01 23:38:56 -08:00
@@ -255,8 +255,8 @@
 	 * later.)
 	 */
 	if (flow) return -EBUSY;
-	if (opt == NULL || rtattr_parse(tb,TCA_ATM_MAX,RTA_DATA(opt),
-	    RTA_PAYLOAD(opt))) return -EINVAL;
+	if (opt == NULL || rtattr_parse_nested(tb, TCA_ATM_MAX, opt))
+		return -EINVAL;
 	if (!tb[TCA_ATM_FD-1] || RTA_PAYLOAD(tb[TCA_ATM_FD-1]) < sizeof(fd))
 		return -EINVAL;
 	fd = *(int *) RTA_DATA(tb[TCA_ATM_FD-1]);
diff -Nru a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c
--- a/net/sched/sch_cbq.c	2005-03-01 23:38:52 -08:00
+++ b/net/sched/sch_cbq.c	2005-03-01 23:38:52 -08:00
@@ -241,7 +241,7 @@
  */
 
 static struct cbq_class *
-cbq_classify(struct sk_buff *skb, struct Qdisc *sch, int *qres)
+cbq_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)
 {
 	struct cbq_sched_data *q = qdisc_priv(sch);
 	struct cbq_class *head = &q->link;
@@ -255,13 +255,11 @@
 	 */
 	if (TC_H_MAJ(prio^sch->handle) == 0 &&
 	    (cl = cbq_class_lookup(q, prio)) != NULL)
-			return cl;
+		return cl;
 
+	*qerr = NET_XMIT_DROP;
 	for (;;) {
 		int result = 0;
-#ifdef CONFIG_NET_CLS_ACT
-		int terminal = 0;
-#endif
 		defmap = head->defaults;
 
 		/*
@@ -282,27 +280,13 @@
 
 #ifdef CONFIG_NET_CLS_ACT
 		switch (result) {
-		case TC_ACT_SHOT: /* Stop and kfree */
-			*qres = NET_XMIT_DROP;
-			terminal = 1;
-			break;
 		case TC_ACT_QUEUED:
 		case TC_ACT_STOLEN: 
-			terminal = 1;
-			break;
-		case TC_ACT_RECLASSIFY:  /* Things look good */
-		case TC_ACT_OK: 
-		case TC_ACT_UNSPEC:
-		default:
-			break;
-		}
-
-		if (terminal) {
-			kfree_skb(skb);
+			*qerr = NET_XMIT_SUCCESS;
+		case TC_ACT_SHOT:
 			return NULL;
 		}
-#else
-#ifdef CONFIG_NET_CLS_POLICE
+#elif defined(CONFIG_NET_CLS_POLICE)
 		switch (result) {
 		case TC_POLICE_RECLASSIFY:
 			return cbq_reclassify(skb, cl);
@@ -312,7 +296,6 @@
 			break;
 		}
 #endif
-#endif
 		if (cl->level == 0)
 			return cl;
 
@@ -423,45 +406,35 @@
 {
 	struct cbq_sched_data *q = qdisc_priv(sch);
 	int len = skb->len;
-	int ret = NET_XMIT_SUCCESS;
-	struct cbq_class *cl = cbq_classify(skb, sch,&ret);
+	int ret;
+	struct cbq_class *cl = cbq_classify(skb, sch, &ret);
 
 #ifdef CONFIG_NET_CLS_POLICE
 	q->rx_class = cl;
 #endif
-	if (cl) {
-#ifdef CONFIG_NET_CLS_POLICE
-		cl->q->__parent = sch;
-#endif
-		if ((ret = cl->q->enqueue(skb, cl->q)) == NET_XMIT_SUCCESS) {
-			sch->q.qlen++;
-			sch->bstats.packets++;
-			sch->bstats.bytes+=len;
-			cbq_mark_toplevel(q, cl);
-			if (!cl->next_alive)
-				cbq_activate_class(cl);
-			return ret;
-		}
-	}
-
-#ifndef CONFIG_NET_CLS_ACT
-	sch->qstats.drops++;
-	if (cl == NULL)
+	if (cl == NULL) {
+		if (ret == NET_XMIT_DROP)
+			sch->qstats.drops++;
 		kfree_skb(skb);
-	else {
-		cbq_mark_toplevel(q, cl);
-		cl->qstats.drops++;
-	}
-#else
-	if ( NET_XMIT_DROP == ret) {
-		sch->qstats.drops++;
+		return ret;
 	}
 
-	if (cl != NULL) {
+#ifdef CONFIG_NET_CLS_POLICE
+	cl->q->__parent = sch;
+#endif
+	if ((ret = cl->q->enqueue(skb, cl->q)) == NET_XMIT_SUCCESS) {
+		sch->q.qlen++;
+		sch->bstats.packets++;
+		sch->bstats.bytes+=len;
 		cbq_mark_toplevel(q, cl);
-		cl->qstats.drops++;
+		if (!cl->next_alive)
+			cbq_activate_class(cl);
+		return ret;
 	}
-#endif
+
+	sch->qstats.drops++;
+	cbq_mark_toplevel(q, cl);
+	cl->qstats.drops++;
 	return ret;
 }
 
@@ -1439,7 +1412,7 @@
 	struct rtattr *tb[TCA_CBQ_MAX];
 	struct tc_ratespec *r;
 
-	if (rtattr_parse(tb, TCA_CBQ_MAX, RTA_DATA(opt), RTA_PAYLOAD(opt)) < 0 ||
+	if (rtattr_parse_nested(tb, TCA_CBQ_MAX, opt) < 0 ||
 	    tb[TCA_CBQ_RTAB-1] == NULL || tb[TCA_CBQ_RATE-1] == NULL ||
 	    RTA_PAYLOAD(tb[TCA_CBQ_RATE-1]) < sizeof(struct tc_ratespec))
 		return -EINVAL;
@@ -1824,8 +1797,7 @@
 	struct cbq_class *parent;
 	struct qdisc_rate_table *rtab = NULL;
 
-	if (opt==NULL ||
-	    rtattr_parse(tb, TCA_CBQ_MAX, RTA_DATA(opt), RTA_PAYLOAD(opt)))
+	if (opt==NULL || rtattr_parse_nested(tb, TCA_CBQ_MAX, opt))
 		return -EINVAL;
 
 	if (tb[TCA_CBQ_OVL_STRATEGY-1] &&
diff -Nru a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c
--- a/net/sched/sch_dsmark.c	2005-03-01 23:38:53 -08:00
+++ b/net/sched/sch_dsmark.c	2005-03-01 23:38:53 -08:00
@@ -14,6 +14,7 @@
 #include <linux/rtnetlink.h>
 #include <net/pkt_sched.h>
 #include <net/dsfield.h>
+#include <net/inet_ecn.h>
 #include <asm/byteorder.h>
 
 
@@ -124,8 +125,7 @@
 	    "arg 0x%lx\n",sch,p,classid,parent,*arg);
 	if (*arg > p->indices)
 		return -ENOENT;
-	if (!opt || rtattr_parse(tb, TCA_DSMARK_MAX, RTA_DATA(opt),
-				 RTA_PAYLOAD(opt)))
+	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]))
@@ -198,10 +198,12 @@
 		/* FIXME: Safe with non-linear skbs? --RR */
 		switch (skb->protocol) {
 			case __constant_htons(ETH_P_IP):
-				skb->tc_index = ipv4_get_dsfield(skb->nh.iph);
+				skb->tc_index = ipv4_get_dsfield(skb->nh.iph)
+					& ~INET_ECN_MASK;
 				break;
 			case __constant_htons(ETH_P_IPV6):
-				skb->tc_index = ipv6_get_dsfield(skb->nh.ipv6h);
+				skb->tc_index = ipv6_get_dsfield(skb->nh.ipv6h)
+					& ~INET_ECN_MASK;
 				break;
 			default:
 				skb->tc_index = 0;
@@ -320,7 +322,7 @@
 }
 
 
-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];
diff -Nru a/net/sched/sch_generic.c b/net/sched/sch_generic.c
--- a/net/sched/sch_generic.c	2005-03-01 23:38:51 -08:00
+++ b/net/sched/sch_generic.c	2005-03-01 23:38:51 -08:00
@@ -54,7 +54,7 @@
 
    qdisc_tree_lock must be grabbed BEFORE dev->queue_lock!
  */
-rwlock_t qdisc_tree_lock = RW_LOCK_UNLOCKED;
+DEFINE_RWLOCK(qdisc_tree_lock);
 
 void qdisc_lock_tree(struct net_device *dev)
 {
@@ -283,7 +283,7 @@
 	.list		=	LIST_HEAD_INIT(noop_qdisc.list),
 };
 
-struct Qdisc_ops noqueue_qdisc_ops = {
+static struct Qdisc_ops noqueue_qdisc_ops = {
 	.next		=	NULL,
 	.cl_ops		=	NULL,
 	.id		=	"noqueue",
@@ -294,7 +294,7 @@
 	.owner		=	THIS_MODULE,
 };
 
-struct Qdisc noqueue_qdisc = {
+static struct Qdisc noqueue_qdisc = {
 	.enqueue	=	NULL,
 	.dequeue	=	noop_dequeue,
 	.flags		=	TCQ_F_BUILTIN,
diff -Nru a/net/sched/sch_gred.c b/net/sched/sch_gred.c
--- a/net/sched/sch_gred.c	2005-03-01 23:39:09 -08:00
+++ b/net/sched/sch_gred.c	2005-03-01 23:39:09 -08:00
@@ -332,13 +332,11 @@
 	struct rtattr *tb2[TCA_GRED_DPS];
 	int i;
 
-	if (opt == NULL ||
-		rtattr_parse(tb, TCA_GRED_STAB, RTA_DATA(opt), RTA_PAYLOAD(opt)) )
-			return -EINVAL;
+	if (opt == NULL || rtattr_parse_nested(tb, TCA_GRED_STAB, opt))
+		return -EINVAL;
 
 	if (tb[TCA_GRED_PARMS-1] == 0 && tb[TCA_GRED_STAB-1] == 0) {
-		rtattr_parse(tb2, TCA_GRED_DPS, RTA_DATA(opt),
-		    RTA_PAYLOAD(opt));
+		rtattr_parse_nested(tb2, TCA_GRED_DPS, opt);
 
 	    if (tb2[TCA_GRED_DPS-1] == 0) 
 			return -EINVAL;
@@ -475,12 +473,11 @@
 	struct rtattr *tb[TCA_GRED_STAB];
 	struct rtattr *tb2[TCA_GRED_DPS];
 
-	if (opt == NULL ||
-		rtattr_parse(tb, TCA_GRED_STAB, RTA_DATA(opt), RTA_PAYLOAD(opt)) )
-			return -EINVAL;
+	if (opt == NULL || rtattr_parse_nested(tb, TCA_GRED_STAB, opt))
+		return -EINVAL;
 
 	if (tb[TCA_GRED_PARMS-1] == 0 && tb[TCA_GRED_STAB-1] == 0) {
-		rtattr_parse(tb2, TCA_GRED_DPS, RTA_DATA(opt),RTA_PAYLOAD(opt));
+		rtattr_parse_nested(tb2, TCA_GRED_DPS, opt);
 
 	    if (tb2[TCA_GRED_DPS-1] == 0) 
 			return -EINVAL;
diff -Nru a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c
--- a/net/sched/sch_hfsc.c	2005-03-01 23:38:52 -08:00
+++ b/net/sched/sch_hfsc.c	2005-03-01 23:38:52 -08:00
@@ -1046,8 +1046,7 @@
 	struct tc_service_curve *rsc = NULL, *fsc = NULL, *usc = NULL;
 	u64 cur_time;
 
-	if (opt == NULL ||
-	    rtattr_parse(tb, TCA_HFSC_MAX, RTA_DATA(opt), RTA_PAYLOAD(opt)))
+	if (opt == NULL || rtattr_parse_nested(tb, TCA_HFSC_MAX, opt))
 		return -EINVAL;
 
 	if (tb[TCA_HFSC_RSC-1]) {
@@ -1215,7 +1214,7 @@
 }
 
 static struct hfsc_class *
-hfsc_classify(struct sk_buff *skb, struct Qdisc *sch, int *qres)
+hfsc_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)
 {
 	struct hfsc_sched *q = qdisc_priv(sch);
 	struct hfsc_class *cl;
@@ -1228,36 +1227,21 @@
 		if (cl->level == 0)
 			return cl;
 
+	*qerr = NET_XMIT_DROP;
 	tcf = q->root.filter_list;
 	while (tcf && (result = tc_classify(skb, tcf, &res)) >= 0) {
 #ifdef CONFIG_NET_CLS_ACT
-		int terminal = 0;
 		switch (result) {
-		case TC_ACT_SHOT: 
-			*qres = NET_XMIT_DROP;
-			terminal = 1;
-			break;
 		case TC_ACT_QUEUED:
 		case TC_ACT_STOLEN: 
-			terminal = 1;
-			break;
-		case TC_ACT_RECLASSIFY: 
-		case TC_ACT_OK:
-		case TC_ACT_UNSPEC:
-		default:
-		break;
-		}
-
-		if (terminal) {
-			kfree_skb(skb);
+			*qerr = NET_XMIT_SUCCESS;
+		case TC_ACT_SHOT: 
 			return NULL;
 		}
-#else
-#ifdef CONFIG_NET_CLS_POLICE
+#elif defined(CONFIG_NET_CLS_POLICE)
 		if (result == TC_POLICE_SHOT)
 			return NULL;
 #endif
-#endif
 		if ((cl = (struct hfsc_class *)res.class) == NULL) {
 			if ((cl = hfsc_find_class(res.classid, sch)) == NULL)
 				break; /* filter selected invalid classid */
@@ -1653,27 +1637,19 @@
 static int
 hfsc_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 {
-	int ret = NET_XMIT_SUCCESS;
-	struct hfsc_class *cl = hfsc_classify(skb, sch, &ret);
-	unsigned int len = skb->len;
+	struct hfsc_class *cl;
+	unsigned int len;
 	int err;
 
-
-#ifdef CONFIG_NET_CLS_ACT
+	cl = hfsc_classify(skb, sch, &err);
 	if (cl == NULL) {
-		if (NET_XMIT_DROP == ret) {
+		if (err == NET_XMIT_DROP)
 			sch->qstats.drops++;
-		}
-		return ret;
-	}
-#else
-	if (cl == NULL) {
 		kfree_skb(skb);
-		sch->qstats.drops++;
-		return NET_XMIT_DROP;
+		return err;
 	}
-#endif
 
+	len = skb->len;
 	err = cl->qdisc->enqueue(skb, cl->qdisc);
 	if (unlikely(err != NET_XMIT_SUCCESS)) {
 		cl->qstats.drops++;
diff -Nru a/net/sched/sch_htb.c b/net/sched/sch_htb.c
--- a/net/sched/sch_htb.c	2005-03-01 23:39:07 -08:00
+++ b/net/sched/sch_htb.c	2005-03-01 23:39:07 -08:00
@@ -71,7 +71,7 @@
 
 #define HTB_HSIZE 16	/* classid hash size */
 #define HTB_EWMAC 2	/* rate average over HTB_EWMAC*HTB_HSIZE sec */
-#define HTB_DEBUG 1	/* compile debugging support (activated by tc tool) */
+#undef HTB_DEBUG	/* compile debugging support (activated by tc tool) */
 #define HTB_RATECM 1    /* whether to use rate computer */
 #define HTB_HYSTERESIS 1/* whether to use mode hysteresis for speedup */
 #define HTB_QLOCK(S) spin_lock_bh(&(S)->dev->queue_lock)
@@ -305,7 +305,7 @@
 	return (cl && cl != HTB_DIRECT) ? cl->classid : TC_H_UNSPEC;
 }
 
-static struct htb_class *htb_classify(struct sk_buff *skb, struct Qdisc *sch, int *qres)
+static struct htb_class *htb_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)
 {
 	struct htb_sched *q = qdisc_priv(sch);
 	struct htb_class *cl;
@@ -321,35 +321,20 @@
 	if ((cl = htb_find(skb->priority,sch)) != NULL && cl->level == 0) 
 		return cl;
 
+	*qerr = NET_XMIT_DROP;
 	tcf = q->filter_list;
 	while (tcf && (result = tc_classify(skb, tcf, &res)) >= 0) {
 #ifdef CONFIG_NET_CLS_ACT
-		int terminal = 0;
 		switch (result) {
-		case TC_ACT_SHOT: /* Stop and kfree */
-			*qres = NET_XMIT_DROP;
-			terminal = 1;
-			break;
 		case TC_ACT_QUEUED:
 		case TC_ACT_STOLEN: 
-			terminal = 1;
-			break;
-		case TC_ACT_RECLASSIFY:  /* Things look good */
-		case TC_ACT_OK:
-		case TC_ACT_UNSPEC:
-		default:
-		break;
-		}
-
-		if (terminal) {
-			kfree_skb(skb);
+			*qerr = NET_XMIT_SUCCESS;
+		case TC_ACT_SHOT:
 			return NULL;
 		}
-#else
-#ifdef CONFIG_NET_CLS_POLICE
+#elif defined(CONFIG_NET_CLS_POLICE)
 		if (result == TC_POLICE_SHOT)
-			return NULL;
-#endif
+			return HTB_DIRECT;
 #endif
 		if ((cl = (void*)res.class) == NULL) {
 			if (res.classid == sch->handle)
@@ -723,37 +708,24 @@
 
 static int htb_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 {
-    int ret = NET_XMIT_SUCCESS;
+    int ret;
     struct htb_sched *q = qdisc_priv(sch);
     struct htb_class *cl = htb_classify(skb,sch,&ret);
 
-
-#ifdef CONFIG_NET_CLS_ACT
-    if (cl == HTB_DIRECT ) {
-	if (q->direct_queue.qlen < q->direct_qlen ) {
-	    __skb_queue_tail(&q->direct_queue, skb);
-	    q->direct_pkts++;
-	}
-    } else if (!cl) {
-	    if (NET_XMIT_DROP == ret) {
-		    sch->qstats.drops++;
-	    }
-	    return ret;
-    }
-#else
-    if (cl == HTB_DIRECT || !cl) {
+    if (cl == HTB_DIRECT) {
 	/* enqueue to helper queue */
-	if (q->direct_queue.qlen < q->direct_qlen && cl) {
+	if (q->direct_queue.qlen < q->direct_qlen) {
 	    __skb_queue_tail(&q->direct_queue, skb);
 	    q->direct_pkts++;
-	} else {
-	    kfree_skb (skb);
-	    sch->qstats.drops++;
-	    return NET_XMIT_DROP;
 	}
-    }
+#ifdef CONFIG_NET_CLS_ACT
+    } else if (!cl) {
+	if (ret == NET_XMIT_DROP)
+		sch->qstats.drops++;
+	kfree_skb (skb);
+	return ret;
 #endif
-    else if (cl->un.leaf.q->enqueue(skb, cl->un.leaf.q) != NET_XMIT_SUCCESS) {
+    } else if (cl->un.leaf.q->enqueue(skb, cl->un.leaf.q) != NET_XMIT_SUCCESS) {
 	sch->qstats.drops++;
 	cl->qstats.drops++;
 	return NET_XMIT_DROP;
@@ -1267,7 +1239,7 @@
 	printk(KERN_INFO "HTB init, kernel part version %d.%d\n",
 			  HTB_VER >> 16,HTB_VER & 0xffff);
 #endif
-	if (!opt || rtattr_parse(tb, TCA_HTB_INIT, RTA_DATA(opt), RTA_PAYLOAD(opt)) ||
+	if (!opt || rtattr_parse_nested(tb, TCA_HTB_INIT, opt) ||
 			tb[TCA_HTB_INIT-1] == NULL ||
 			RTA_PAYLOAD(tb[TCA_HTB_INIT-1]) < sizeof(*gopt)) {
 		printk(KERN_ERR "HTB: hey probably you have bad tc tool ?\n");
@@ -1559,7 +1531,7 @@
 	struct tc_htb_opt *hopt;
 
 	/* extract all subattrs from opt attr */
-	if (!opt || rtattr_parse(tb, TCA_HTB_RTAB, RTA_DATA(opt), RTA_PAYLOAD(opt)) ||
+	if (!opt || rtattr_parse_nested(tb, TCA_HTB_RTAB, opt) ||
 			tb[TCA_HTB_PARMS-1] == NULL ||
 			RTA_PAYLOAD(tb[TCA_HTB_PARMS-1]) < sizeof(*hopt))
 		goto failure;
diff -Nru a/net/sched/sch_ingress.c b/net/sched/sch_ingress.c
--- a/net/sched/sch_ingress.c	2005-03-01 23:39:18 -08:00
+++ b/net/sched/sch_ingress.c	2005-03-01 23:39:18 -08:00
@@ -14,6 +14,7 @@
 #include <linux/netdevice.h>
 #include <linux/rtnetlink.h>
 #include <linux/netfilter_ipv4.h>
+#include <linux/netfilter_ipv6.h>
 #include <linux/netfilter.h>
 #include <linux/smp.h>
 #include <net/pkt_sched.h>
@@ -271,10 +272,18 @@
 	.priority       = NF_IP_PRI_FILTER + 1,
 };
 
+static struct nf_hook_ops ing6_ops = {
+	.hook           = ing_hook,
+	.owner		= THIS_MODULE,
+	.pf             = PF_INET6,
+	.hooknum        = NF_IP6_PRE_ROUTING,
+	.priority       = NF_IP6_PRI_FILTER + 1,
+};
+
 #endif
 #endif
 
-int ingress_init(struct Qdisc *sch,struct rtattr *opt)
+static int ingress_init(struct Qdisc *sch,struct rtattr *opt)
 {
 	struct ingress_qdisc_data *p = PRIV(sch);
 
@@ -297,6 +306,12 @@
 			return -EINVAL;
 		}
 		nf_registered++;
+
+		if (nf_register_hook(&ing6_ops) < 0) {
+			printk("IPv6 ingress qdisc registration error, " \
+			    "disabling IPv6 support.\n");
+		} else
+			nf_registered++;
 	}
 #endif
 #endif
@@ -408,8 +423,11 @@
 	unregister_qdisc(&ingress_qdisc_ops);
 #ifndef CONFIG_NET_CLS_ACT
 #ifdef CONFIG_NETFILTER
-	if (nf_registered)
+	if (nf_registered) {
 		nf_unregister_hook(&ing_ops);
+		if (nf_registered > 1)
+			nf_unregister_hook(&ing6_ops);
+	}
 #endif
 #endif
 }
diff -Nru a/net/sched/sch_netem.c b/net/sched/sch_netem.c
--- a/net/sched/sch_netem.c	2005-03-01 23:39:17 -08:00
+++ b/net/sched/sch_netem.c	2005-03-01 23:39:17 -08:00
@@ -177,6 +177,7 @@
 	if (q->loss && q->loss >= get_crandom(&q->loss_cor)) {
 		pr_debug("netem_enqueue: random loss\n");
 		sch->qstats.drops++;
+		kfree_skb(skb);
 		return 0;	/* lie about loss so TCP doesn't know */
 	}
 
diff -Nru a/net/sched/sch_prio.c b/net/sched/sch_prio.c
--- a/net/sched/sch_prio.c	2005-03-01 23:38:56 -08:00
+++ b/net/sched/sch_prio.c	2005-03-01 23:38:56 -08:00
@@ -47,36 +47,23 @@
 };
 
 
-struct Qdisc *prio_classify(struct sk_buff *skb, struct Qdisc *sch,int *r)
+static struct Qdisc *
+prio_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)
 {
 	struct prio_sched_data *q = qdisc_priv(sch);
 	u32 band = skb->priority;
 	struct tcf_result res;
 
+	*qerr = NET_XMIT_DROP;
 	if (TC_H_MAJ(skb->priority) != sch->handle) {
 #ifdef CONFIG_NET_CLS_ACT
-		int result = 0, terminal = 0;
-		result = tc_classify(skb, q->filter_list, &res);
-
-		switch (result) {
-			case TC_ACT_SHOT:
-				*r = NET_XMIT_DROP;
-				terminal = 1;
-				break;
-			case TC_ACT_STOLEN:
-			case TC_ACT_QUEUED:
-				terminal = 1;
-				break;
-			case TC_ACT_RECLASSIFY:
-			case TC_ACT_OK:
-			case TC_ACT_UNSPEC:
-			default:
-			break;
-		};
-		if (terminal) {
-			kfree_skb(skb);
+		switch (tc_classify(skb, q->filter_list, &res)) {
+		case TC_ACT_STOLEN:
+		case TC_ACT_QUEUED:
+			*qerr = NET_XMIT_SUCCESS;
+		case TC_ACT_SHOT:
 			return NULL;
-		} 
+		};
 
 		if (!q->filter_list ) {
 #else
@@ -96,15 +83,20 @@
 }
 
 static int
-prio_enqueue(struct sk_buff *skb, struct Qdisc* sch)
+prio_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 {
 	struct Qdisc *qdisc;
-	int ret = NET_XMIT_SUCCESS;
+	int ret;
 
 	qdisc = prio_classify(skb, sch, &ret);
-
-	if (NULL == qdisc)
-		goto dropped;
+#ifdef CONFIG_NET_CLS_ACT
+	if (qdisc == NULL) {
+		if (ret == NET_XMIT_DROP)
+			sch->qstats.drops++;
+		kfree_skb(skb);
+		return ret;
+	}
+#endif
 
 	if ((ret = qdisc->enqueue(skb, qdisc)) == NET_XMIT_SUCCESS) {
 		sch->bstats.bytes += skb->len;
@@ -112,17 +104,7 @@
 		sch->q.qlen++;
 		return NET_XMIT_SUCCESS;
 	}
-
-dropped:
-#ifdef CONFIG_NET_CLS_ACT
-	if (NET_XMIT_DROP == ret) {
-#endif
-		sch->qstats.drops++;
-#ifdef CONFIG_NET_CLS_ACT
-	} else {
-		sch->qstats.overlimits++; /* abuse, but noone uses it */
-	}
-#endif
+	sch->qstats.drops++;
 	return ret; 
 }
 
@@ -131,18 +113,23 @@
 prio_requeue(struct sk_buff *skb, struct Qdisc* sch)
 {
 	struct Qdisc *qdisc;
-	int ret = NET_XMIT_DROP;
+	int ret;
 
 	qdisc = prio_classify(skb, sch, &ret);
-	if (qdisc == NULL)
-		goto dropped;
+#ifdef CONFIG_NET_CLS_ACT
+	if (qdisc == NULL) {
+		if (ret == NET_XMIT_DROP)
+			sch->qstats.drops++;
+		kfree_skb(skb);
+		return ret;
+	}
+#endif
 
-	if ((ret = qdisc->ops->requeue(skb, qdisc)) == 0) {
+	if ((ret = qdisc->ops->requeue(skb, qdisc)) == NET_XMIT_SUCCESS) {
 		sch->q.qlen++;
 		sch->qstats.requeues++;
 		return 0;
 	}
-dropped:
 	sch->qstats.drops++;
 	return NET_XMIT_DROP;
 }
diff -Nru a/net/sched/sch_red.c b/net/sched/sch_red.c
--- a/net/sched/sch_red.c	2005-03-01 23:39:17 -08:00
+++ b/net/sched/sch_red.c	2005-03-01 23:39:17 -08:00
@@ -364,7 +364,7 @@
 	struct tc_red_qopt *ctl;
 
 	if (opt == NULL ||
-	    rtattr_parse(tb, TCA_RED_STAB, RTA_DATA(opt), RTA_PAYLOAD(opt)) ||
+	    rtattr_parse_nested(tb, TCA_RED_STAB, opt) ||
 	    tb[TCA_RED_PARMS-1] == 0 || tb[TCA_RED_STAB-1] == 0 ||
 	    RTA_PAYLOAD(tb[TCA_RED_PARMS-1]) < sizeof(*ctl) ||
 	    RTA_PAYLOAD(tb[TCA_RED_STAB-1]) < 256)
diff -Nru a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c
--- a/net/sched/sch_tbf.c	2005-03-01 23:38:52 -08:00
+++ b/net/sched/sch_tbf.c	2005-03-01 23:38:52 -08:00
@@ -310,7 +310,7 @@
 	struct Qdisc *child = NULL;
 	int max_size,n;
 
-	if (rtattr_parse(tb, TCA_TBF_PTAB, RTA_DATA(opt), RTA_PAYLOAD(opt)) ||
+	if (rtattr_parse_nested(tb, TCA_TBF_PTAB, opt) ||
 	    tb[TCA_TBF_PARMS-1] == NULL ||
 	    RTA_PAYLOAD(tb[TCA_TBF_PARMS-1]) < sizeof(*qopt))
 		goto done;
diff -Nru a/net/sctp/associola.c b/net/sctp/associola.c
--- a/net/sctp/associola.c	2005-03-01 23:38:51 -08:00
+++ b/net/sctp/associola.c	2005-03-01 23:38:51 -08:00
@@ -66,39 +66,14 @@
 
 /* 1st Level Abstractions. */
 
-/* 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)
-{
-	struct sctp_association *asoc;
-
-	asoc = t_new(struct sctp_association, gfp);
-	if (!asoc)
-		goto fail;
-
-	if (!sctp_association_init(asoc, ep, sk, scope, gfp))
-		goto fail_init;
-
-	asoc->base.malloced = 1;
-	SCTP_DBG_OBJCNT_INC(assoc);
-
-	return asoc;
-
-fail_init:
-	kfree(asoc);
-fail:
-	return NULL;
-}
-
 /* Initialize a new association from provided memory. */
-struct sctp_association *sctp_association_init(struct sctp_association *asoc,
+static struct sctp_association *sctp_association_init(struct sctp_association *asoc,
 					  const struct sctp_endpoint *ep,
 					  const struct sock *sk,
 					  sctp_scope_t scope,
 					  int gfp)
 {
-	struct sctp_opt *sp;
+	struct sctp_sock *sp;
 	int i;
 
 	/* Retrieve the SCTP per socket area.  */
@@ -204,6 +179,7 @@
 	asoc->c.peer_vtag = 0;
 	asoc->c.my_ttag   = 0;
 	asoc->c.peer_ttag = 0;
+	asoc->c.my_port = ep->base.bind_addr.port;
 
 	asoc->c.initial_tsn = sctp_generate_tsn(ep);
 
@@ -296,6 +272,31 @@
 	return NULL;
 }
 
+/* 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)
+{
+	struct sctp_association *asoc;
+
+	asoc = t_new(struct sctp_association, gfp);
+	if (!asoc)
+		goto fail;
+
+	if (!sctp_association_init(asoc, ep, sk, scope, gfp))
+		goto fail_init;
+
+	asoc->base.malloced = 1;
+	SCTP_DBG_OBJCNT_INC(assoc);
+
+	return asoc;
+
+fail_init:
+	kfree(asoc);
+fail:
+	return NULL;
+}
+
 /* Free this association if possible.  There may still be users, so
  * the actual deallocation may be delayed.
  */
@@ -433,7 +434,7 @@
 					   int gfp)
 {
 	struct sctp_transport *peer;
-	struct sctp_opt *sp;
+	struct sctp_sock *sp;
 	unsigned short port;
 
 	sp = sctp_sk(asoc->base.sk);
@@ -500,7 +501,6 @@
 
 	peer->partial_bytes_acked = 0;
 	peer->flight_size = 0;
-	peer->error_threshold = peer->max_retrans;
 
 	/* By default, enable heartbeat for peer address. */
 	peer->hb_allowed = 1;
@@ -511,7 +511,7 @@
 	peer->hb_interval = msecs_to_jiffies(sp->paddrparam.spp_hbinterval);
 
 	/* Set the path max_retrans.  */
-	peer->max_retrans = asoc->max_retrans;
+	peer->max_retrans = sp->paddrparam.spp_pathmaxrxt;
 
 	/* Set the transport's RTO.initial value */
 	peer->rto = asoc->rto_initial;
@@ -714,18 +714,6 @@
 	return retval;
 }
 
-/* Allocate 'num' TSNs by incrementing the association's TSN by num. */
-__u32 sctp_association_get_tsn_block(struct sctp_association *asoc, int num)
-{
-	__u32 retval = asoc->next_tsn;
-
-	asoc->next_tsn += num;
-	asoc->unack_data += num;
-
-	return retval;
-}
-
-
 /* Compare two addresses to see if they match.  Wildcard addresses
  * only match themselves.
  */
@@ -760,14 +748,6 @@
 	return chunk;
 }
 
-/* Use this function for the packet prepend callback when no ECNE
- * packet is desired (e.g. some packets don't like to be bundled).
- */
-struct sctp_chunk *sctp_get_no_prepend(struct sctp_association *asoc)
-{
-	return NULL;
-}
-
 /*
  * Find which transport this TSN was sent on.
  */
@@ -861,7 +841,8 @@
 	struct sctp_chunk *chunk;
 	struct sock *sk;
 	struct sctp_inq *inqueue;
-	int state, subtype;
+	int state;
+	sctp_subtype_t subtype;
 	int error = 0;
 
 	/* The association should be held so we should be safe. */
@@ -872,7 +853,7 @@
 	sctp_association_hold(asoc);
 	while (NULL != (chunk = sctp_inq_pop(inqueue))) {
 		state = asoc->state;
-		subtype = chunk->chunk_hdr->type;
+		subtype = SCTP_ST_CHUNK(chunk->chunk_hdr->type);
 
 		/* Remember where the last DATA chunk came from so we
 		 * know where to send the SACK.
@@ -886,7 +867,7 @@
 			chunk->transport->last_time_heard = jiffies;
 
 		/* Run through the state machine. */
-		error = sctp_do_sm(SCTP_EVENT_T_CHUNK, SCTP_ST_CHUNK(subtype),
+		error = sctp_do_sm(SCTP_EVENT_T_CHUNK, subtype,
 				   state, ep, asoc, chunk, GFP_ATOMIC);
 
 		/* Check to see if the association is freed in response to
@@ -905,7 +886,7 @@
 /* This routine moves an association from its old sk to a new sk.  */
 void sctp_assoc_migrate(struct sctp_association *assoc, struct sock *newsk)
 {
-	struct sctp_opt *newsp = sctp_sk(newsk);
+	struct sctp_sock *newsp = sctp_sk(newsk);
 	struct sock *oldsk = assoc->base.sk;
 
 	/* Delete the association from the old endpoint's list of
@@ -1078,7 +1059,7 @@
 	}
 
 	if (pmtu) {
-		struct sctp_opt *sp = sctp_sk(asoc->base.sk);
+		struct sctp_sock *sp = sctp_sk(asoc->base.sk);
 		asoc->pmtu = pmtu;
 		asoc->frag_point = sctp_frag_point(sp, pmtu);
 	}
diff -Nru a/net/sctp/bind_addr.c b/net/sctp/bind_addr.c
--- a/net/sctp/bind_addr.c	2005-03-01 23:39:09 -08:00
+++ b/net/sctp/bind_addr.c	2005-03-01 23:39:09 -08:00
@@ -104,23 +104,6 @@
 	return error;
 }
 
-/* Create a new SCTP_bind_addr from nothing.  */
-struct sctp_bind_addr *sctp_bind_addr_new(int gfp)
-{
-	struct sctp_bind_addr *retval;
-
-	retval = t_new(struct sctp_bind_addr, gfp);
-	if (!retval)
-		goto nomem;
-
-	sctp_bind_addr_init(retval, 0);
-	retval->malloced = 1;
-	SCTP_DBG_OBJCNT_INC(bind_addr);
-
-nomem:
-	return retval;
-}
-
 /* Initialize the SCTP_bind_addr structure for either an endpoint or
  * an association.
  */
@@ -310,7 +293,7 @@
 /* Does this contain a specified address?  Allow wildcarding. */
 int sctp_bind_addr_match(struct sctp_bind_addr *bp, 
 			 const union sctp_addr *addr,
-			 struct sctp_opt *opt)
+			 struct sctp_sock *opt)
 {
 	struct sctp_sockaddr_entry *laddr;
 	struct list_head *pos;
@@ -330,7 +313,7 @@
 union sctp_addr *sctp_find_unmatch_addr(struct sctp_bind_addr	*bp,
 					const union sctp_addr	*addrs,
 					int			addrcnt,
-					struct sctp_opt		*opt)
+					struct sctp_sock	*opt)
 {
 	struct sctp_sockaddr_entry	*laddr;
 	union sctp_addr			*addr;
diff -Nru a/net/sctp/chunk.c b/net/sctp/chunk.c
--- a/net/sctp/chunk.c	2005-03-01 23:39:08 -08:00
+++ b/net/sctp/chunk.c	2005-03-01 23:39:08 -08:00
@@ -51,7 +51,7 @@
  */
 
 /* Initialize datamsg from memory. */
-void sctp_datamsg_init(struct sctp_datamsg *msg)
+static void sctp_datamsg_init(struct sctp_datamsg *msg)
 {
 	atomic_set(&msg->refcnt, 1);
 	msg->send_failed = 0;
@@ -62,7 +62,7 @@
 }
 
 /* Allocate and initialize datamsg. */
-struct sctp_datamsg *sctp_datamsg_new(int gfp)
+SCTP_STATIC struct sctp_datamsg *sctp_datamsg_new(int gfp)
 {
 	struct sctp_datamsg *msg;
 	msg = kmalloc(sizeof(struct sctp_datamsg), gfp);
@@ -77,7 +77,7 @@
 {
 	struct list_head *pos, *temp;
 	struct sctp_chunk *chunk;
-	struct sctp_opt *sp;
+	struct sctp_sock *sp;
 	struct sctp_ulpevent *ev;
 	struct sctp_association *asoc = NULL;
 	int error = 0, notify;
@@ -124,7 +124,7 @@
 }
 
 /* Hold a reference. */
-void sctp_datamsg_hold(struct sctp_datamsg *msg)
+static void sctp_datamsg_hold(struct sctp_datamsg *msg)
 {
 	atomic_inc(&msg->refcnt);
 }
@@ -151,7 +151,7 @@
 }
 
 /* Assign a chunk to this datamsg. */
-void sctp_datamsg_assign(struct sctp_datamsg *msg, struct sctp_chunk *chunk)
+static void sctp_datamsg_assign(struct sctp_datamsg *msg, struct sctp_chunk *chunk)
 {
 	sctp_datamsg_hold(msg);
 	chunk->msg = msg;
diff -Nru a/net/sctp/command.c b/net/sctp/command.c
--- a/net/sctp/command.c	2005-03-01 23:39:07 -08:00
+++ b/net/sctp/command.c	2005-03-01 23:39:07 -08:00
@@ -42,17 +42,6 @@
 #include <net/sctp/sctp.h>
 #include <net/sctp/sm.h>
 
-/* Create a new sctp_command_sequence.  */
-sctp_cmd_seq_t *sctp_new_cmd_seq(int gfp)
-{
-	sctp_cmd_seq_t *retval = t_new(sctp_cmd_seq_t, gfp);
-
-	if (retval)
-		sctp_init_cmd_seq(retval);
-
-	return retval;
-}
-
 /* Initialize a block of memory as a command sequence. */
 int sctp_init_cmd_seq(sctp_cmd_seq_t *seq)
 {
@@ -77,13 +66,6 @@
 	return 0;
 }
 
-/* Rewind an sctp_cmd_seq_t to iterate from the start.  */
-int sctp_rewind_sequence(sctp_cmd_seq_t *seq)
-{
-	seq->next_cmd = 0;
-	return 1;		/* We always succeed. */
-}
-
 /* Return the next command structure in a sctp_cmd_seq.
  * Returns NULL at the end of the sequence.
  */
@@ -97,8 +79,3 @@
 	return retval;
 }
 
-/* Dispose of a command sequence.  */
-void sctp_free_cmd_seq(sctp_cmd_seq_t *seq)
-{
-	kfree(seq);
-}
diff -Nru a/net/sctp/debug.c b/net/sctp/debug.c
--- a/net/sctp/debug.c	2005-03-01 23:38:55 -08:00
+++ b/net/sctp/debug.c	2005-03-01 23:38:55 -08:00
@@ -98,23 +98,6 @@
 	return "unknown chunk";
 }
 
-/* These are printable form of variable-length parameters. */
-const char *sctp_param_tbl[SCTP_PARAM_ECN_CAPABLE + 1] = {
-	"",
-	"PARAM_HEARTBEAT_INFO",
-	"",
-	"",
-	"",
-	"PARAM_IPV4_ADDRESS",
-	"PARAM_IPV6_ADDRESS",
-	"PARAM_STATE_COOKIE",
-	"PARAM_UNRECOGNIZED_PARAMETERS",
-	"PARAM_COOKIE_PRESERVATIVE",
-	"",
-	"PARAM_HOST_NAME_ADDRESS",
-	"PARAM_SUPPORTED_ADDRESS_TYPES",
-};
-
 /* These are printable forms of the states.  */
 const char *sctp_state_tbl[SCTP_STATE_NUM_STATES] = {
 	"STATE_EMPTY",
@@ -171,6 +154,7 @@
 
 static const char *sctp_other_tbl[] = {
 	"NO_PENDING_TSN",
+        "ICMP_PROTO_UNREACH",
 };
 
 /* Lookup "other" debug name. */
@@ -178,7 +162,7 @@
 {
 	if (id.other < 0)
 		return "illegal 'other' event";
-	if (id.other < SCTP_EVENT_OTHER_MAX)
+	if (id.other <= SCTP_EVENT_OTHER_MAX)
 		return sctp_other_tbl[id.other];
 	return "unknown 'other' event";
 }
diff -Nru a/net/sctp/endpointola.c b/net/sctp/endpointola.c
--- a/net/sctp/endpointola.c	2005-03-01 23:38:52 -08:00
+++ b/net/sctp/endpointola.c	2005-03-01 23:38:52 -08:00
@@ -63,36 +63,13 @@
 /* Forward declarations for internal helpers. */
 static void sctp_endpoint_bh_rcv(struct sctp_endpoint *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 *ep;
-
-	/* Build a local endpoint. */
-	ep = t_new(struct sctp_endpoint, gfp);
-	if (!ep)
-		goto fail;
-	if (!sctp_endpoint_init(ep, sk, gfp))
-		goto fail_init;
-	ep->base.malloced = 1;
-	SCTP_DBG_OBJCNT_INC(ep);
-	return ep;
-
-fail_init:
-	kfree(ep);
-fail:
-	return NULL;
-}
-
 /*
  * Initialize the base fields of the endpoint structure.
  */
-struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep,
-					 struct sock *sk, int gfp)
+static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep,
+						struct sock *sk, int gfp)
 {
-	struct sctp_opt *sp = sctp_sk(sk);
+	struct sctp_sock *sp = sctp_sk(sk);
 	memset(ep, 0, sizeof(struct sctp_endpoint));
 
 	/* Initialize the base structure. */
@@ -160,6 +137,29 @@
 	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 *ep;
+
+	/* Build a local endpoint. */
+	ep = t_new(struct sctp_endpoint, gfp);
+	if (!ep)
+		goto fail;
+	if (!sctp_endpoint_init(ep, sk, gfp))
+		goto fail_init;
+	ep->base.malloced = 1;
+	SCTP_DBG_OBJCNT_INC(ep);
+	return ep;
+
+fail_init:
+	kfree(ep);
+fail:
+	return NULL;
+}
+
 /* Add an association to an endpoint.  */
 void sctp_endpoint_add_asoc(struct sctp_endpoint *ep,
 			    struct sctp_association *asoc)
@@ -184,7 +184,7 @@
 }
 
 /* Final destructor for endpoint.  */
-void sctp_endpoint_destroy(struct sctp_endpoint *ep)
+static void sctp_endpoint_destroy(struct sctp_endpoint *ep)
 {
 	SCTP_ASSERT(ep->base.dead, "Endpoint is not dead", return);
 
@@ -257,7 +257,7 @@
  * We do a linear search of the associations for this endpoint.
  * We return the matching transport address too.
  */
-struct sctp_association *__sctp_endpoint_lookup_assoc(
+static struct sctp_association *__sctp_endpoint_lookup_assoc(
 	const struct sctp_endpoint *ep,
 	const union sctp_addr *paddr,
 	struct sctp_transport **transport)
@@ -345,7 +345,7 @@
 	sk = ep->base.sk;
 
 	while (NULL != (chunk = sctp_inq_pop(inqueue))) {
-		subtype.chunk = chunk->chunk_hdr->type;
+		subtype = SCTP_ST_CHUNK(chunk->chunk_hdr->type);
 
 		/* We might have grown an association since last we
 		 * looked, so try again.
diff -Nru a/net/sctp/input.c b/net/sctp/input.c
--- a/net/sctp/input.c	2005-03-01 23:38:52 -08:00
+++ b/net/sctp/input.c	2005-03-01 23:38:52 -08:00
@@ -63,11 +63,15 @@
 
 /* Forward declarations for internal helpers. */
 static int sctp_rcv_ootb(struct sk_buff *);
-struct sctp_association *__sctp_rcv_lookup(struct sk_buff *skb,
+static struct sctp_association *__sctp_rcv_lookup(struct sk_buff *skb,
 				      const union sctp_addr *laddr,
 				      const union sctp_addr *paddr,
 				      struct sctp_transport **transportp);
-struct sctp_endpoint *__sctp_rcv_lookup_endpoint(const union sctp_addr *laddr);
+static struct sctp_endpoint *__sctp_rcv_lookup_endpoint(const union sctp_addr *laddr);
+static struct sctp_association *__sctp_lookup_association(
+					const union sctp_addr *local,
+					const union sctp_addr *peer,
+					struct sctp_transport **pt);
 
 
 /* Calculate the SCTP checksum of an SCTP packet.  */
@@ -130,6 +134,10 @@
 
 	skb_pull(skb, sizeof(struct sctphdr));
 
+	/* Make sure we at least have chunk headers worth of data left. */
+	if (skb->len < sizeof(struct sctp_chunkhdr))
+		goto discard_it;
+
 	family = ipver2af(skb->nh.iph->version);
 	af = sctp_get_af_specific(family);
 	if (unlikely(!af))
@@ -284,6 +292,31 @@
 	}
 }
 
+/*
+ * SCTP Implementer's Guide, 2.37 ICMP handling procedures
+ *
+ * ICMP8) If the ICMP code is a "Unrecognized next header type encountered"
+ *        or a "Protocol Unreachable" treat this message as an abort
+ *        with the T bit set.
+ *
+ * This function sends an event to the state machine, which will abort the
+ * association.
+ *
+ */
+void sctp_icmp_proto_unreachable(struct sock *sk,
+                           struct sctp_endpoint *ep,
+                           struct sctp_association *asoc,
+                           struct sctp_transport *t)
+{
+	SCTP_DEBUG_PRINTK("%s\n",  __FUNCTION__);
+
+	sctp_do_sm(SCTP_EVENT_T_OTHER,
+		   SCTP_ST_OTHER(SCTP_EVENT_ICMP_PROTO_UNREACH),
+		   asoc->state, asoc->ep, asoc, NULL,
+		   GFP_ATOMIC);
+
+}
+
 /* Common lookup code for icmp/icmpv6 error handler. */
 struct sock *sctp_err_lookup(int family, struct sk_buff *skb,
 			     struct sctphdr *sctphdr,
@@ -326,11 +359,12 @@
 	}
 
 	if (asoc) {
+		sk = asoc->base.sk;
+
 		if (ntohl(sctphdr->vtag) != asoc->c.peer_vtag) {
 			ICMP_INC_STATS_BH(ICMP_MIB_INERRORS);
 			goto out;
 		}
-		sk = asoc->base.sk;
 	} else
 		sk = ep->base.sk;
 
@@ -393,7 +427,7 @@
 	struct sctp_endpoint *ep;
 	struct sctp_association *asoc;
 	struct sctp_transport *transport;
-	struct inet_opt *inet;
+	struct inet_sock *inet;
 	char *saveip, *savesctp;
 	int err;
 
@@ -432,7 +466,13 @@
 			sctp_icmp_frag_needed(sk, asoc, transport, info);
 			goto out_unlock;
 		}
-
+		else {
+			if (ICMP_PROT_UNREACH == code) {
+				sctp_icmp_proto_unreachable(sk, ep, asoc,
+							    transport);
+				goto out_unlock;
+			}
+		}
 		err = icmp_err_convert[code].errno;
 		break;
 	case ICMP_TIME_EXCEEDED:
@@ -479,10 +519,10 @@
 	sctp_errhdr_t *err;
 
 	ch = (sctp_chunkhdr_t *) skb->data;
+	ch_end = ((__u8 *) ch) + WORD_ROUND(ntohs(ch->length));
 
 	/* Scan through all the chunks in the packet.  */
-	do {
-		ch_end = ((__u8 *) ch) + WORD_ROUND(ntohs(ch->length));
+	while (ch_end > (__u8 *)ch && ch_end < skb->tail) {
 
 		/* RFC 8.4, 2) If the OOTB packet contains an ABORT chunk, the
 		 * receiver MUST silently discard the OOTB packet and take no
@@ -513,7 +553,8 @@
 		}
 
 		ch = (sctp_chunkhdr_t *) ch_end;
-	} while (ch_end < skb->tail);
+	        ch_end = ((__u8 *) ch) + WORD_ROUND(ntohs(ch->length));
+	}
 
 	return 0;
 
@@ -522,7 +563,7 @@
 }
 
 /* Insert endpoint into the hash table.  */
-void __sctp_hash_endpoint(struct sctp_endpoint *ep)
+static void __sctp_hash_endpoint(struct sctp_endpoint *ep)
 {
 	struct sctp_ep_common **epp;
 	struct sctp_ep_common *epb;
@@ -552,7 +593,7 @@
 }
 
 /* Remove endpoint from the hash table.  */
-void __sctp_unhash_endpoint(struct sctp_endpoint *ep)
+static void __sctp_unhash_endpoint(struct sctp_endpoint *ep)
 {
 	struct sctp_hashbucket *head;
 	struct sctp_ep_common *epb;
@@ -584,7 +625,7 @@
 }
 
 /* Look up an endpoint. */
-struct sctp_endpoint *__sctp_rcv_lookup_endpoint(const union sctp_addr *laddr)
+static struct sctp_endpoint *__sctp_rcv_lookup_endpoint(const union sctp_addr *laddr)
 {
 	struct sctp_hashbucket *head;
 	struct sctp_ep_common *epb;
@@ -610,16 +651,8 @@
 	return ep;
 }
 
-/* Add an association to the hash. Local BH-safe. */
-void sctp_hash_established(struct sctp_association *asoc)
-{
-	sctp_local_bh_disable();
-	__sctp_hash_established(asoc);
-	sctp_local_bh_enable();
-}
-
 /* Insert association into the hash table.  */
-void __sctp_hash_established(struct sctp_association *asoc)
+static void __sctp_hash_established(struct sctp_association *asoc)
 {
 	struct sctp_ep_common **epp;
 	struct sctp_ep_common *epb;
@@ -642,16 +675,16 @@
 	sctp_write_unlock(&head->lock);
 }
 
-/* Remove association from the hash table.  Local BH-safe. */
-void sctp_unhash_established(struct sctp_association *asoc)
+/* Add an association to the hash. Local BH-safe. */
+void sctp_hash_established(struct sctp_association *asoc)
 {
 	sctp_local_bh_disable();
-	__sctp_unhash_established(asoc);
+	__sctp_hash_established(asoc);
 	sctp_local_bh_enable();
 }
 
 /* Remove association from the hash table.  */
-void __sctp_unhash_established(struct sctp_association *asoc)
+static void __sctp_unhash_established(struct sctp_association *asoc)
 {
 	struct sctp_hashbucket *head;
 	struct sctp_ep_common *epb;
@@ -675,8 +708,16 @@
 	sctp_write_unlock(&head->lock);
 }
 
+/* Remove association from the hash table.  Local BH-safe. */
+void sctp_unhash_established(struct sctp_association *asoc)
+{
+	sctp_local_bh_disable();
+	__sctp_unhash_established(asoc);
+	sctp_local_bh_enable();
+}
+
 /* Look up an association. */
-struct sctp_association *__sctp_lookup_association(
+static struct sctp_association *__sctp_lookup_association(
 					const union sctp_addr *local,
 					const union sctp_addr *peer,
 					struct sctp_transport **pt)
@@ -713,8 +754,9 @@
 }
 
 /* Look up an association. BH-safe. */
+SCTP_STATIC
 struct sctp_association *sctp_lookup_association(const union sctp_addr *laddr,
-					    const union sctp_addr *paddr,
+						 const union sctp_addr *paddr,
 					    struct sctp_transport **transportp)
 {
 	struct sctp_association *asoc;
@@ -784,6 +826,14 @@
 		return NULL;
 	}
 
+	/* The code below will attempt to walk the chunk and extract
+	 * parameter information.  Before we do that, we need to verify
+	 * that the chunk length doesn't cause overflow.  Otherwise, we'll
+	 * walk off the end.
+	 */
+	if (WORD_ROUND(ntohs(ch->length)) > skb->len)
+		return NULL;
+
 	/*
 	 * This code will NOT touch anything inside the chunk--it is
 	 * strictly READ-ONLY.
@@ -821,7 +871,7 @@
 }
 
 /* Lookup an association for an inbound skb. */
-struct sctp_association *__sctp_rcv_lookup(struct sk_buff *skb,
+static struct sctp_association *__sctp_rcv_lookup(struct sk_buff *skb,
 				      const union sctp_addr *paddr,
 				      const union sctp_addr *laddr,
 				      struct sctp_transport **transportp)
diff -Nru a/net/sctp/inqueue.c b/net/sctp/inqueue.c
--- a/net/sctp/inqueue.c	2005-03-01 23:39:07 -08:00
+++ b/net/sctp/inqueue.c	2005-03-01 23:39:07 -08:00
@@ -59,19 +59,6 @@
 	queue->malloced = 0;
 }
 
-/* Create an initialized sctp_inq.  */
-struct sctp_inq *sctp_inq_new(void)
-{
-	struct sctp_inq *retval;
-
-	retval = t_new(struct sctp_inq, GFP_ATOMIC);
-	if (retval) {
-		sctp_inq_init(retval);
-		retval->malloced = 1;
-	}
-        return retval;
-}
-
 /* Release the memory associated with an SCTP inqueue.  */
 void sctp_inq_free(struct sctp_inq *queue)
 {
@@ -157,14 +144,36 @@
 	}
 
         chunk->chunk_hdr = ch;
-        chunk->chunk_end = ((__u8 *) ch)
-		+ WORD_ROUND(ntohs(ch->length));
+        chunk->chunk_end = ((__u8 *)ch) + WORD_ROUND(ntohs(ch->length));
+	/* In the unlikely case of an IP reassembly, the skb could be
+	 * non-linear. If so, update chunk_end so that it doesn't go past
+	 * the skb->tail.
+	 */
+	if (unlikely(skb_is_nonlinear(chunk->skb))) {
+		if (chunk->chunk_end > chunk->skb->tail)
+			chunk->chunk_end = chunk->skb->tail;
+	}
 	skb_pull(chunk->skb, sizeof(sctp_chunkhdr_t));
 	chunk->subh.v = NULL; /* Subheader is no longer valid.  */
 
 	if (chunk->chunk_end < chunk->skb->tail) {
 		/* This is not a singleton */
 		chunk->singleton = 0;
+	} else if (chunk->chunk_end > chunk->skb->tail) {
+                /* RFC 2960, Section 6.10  Bundling
+		 *
+		 * Partial chunks MUST NOT be placed in an SCTP packet.
+		 * If the receiver detects a partial chunk, it MUST drop
+		 * the chunk.  
+		 *
+		 * Since the end of the chunk is past the end of our buffer
+		 * (which contains the whole packet, we can freely discard
+		 * the whole packet.
+		 */
+		sctp_chunk_free(chunk);
+		chunk = queue->in_progress = NULL;
+
+		return NULL;
 	} else {
 		/* We are at the end of the packet, so mark the chunk
 		 * in case we need to send a SACK.
diff -Nru a/net/sctp/ipv6.c b/net/sctp/ipv6.c
--- a/net/sctp/ipv6.c	2005-03-01 23:38:59 -08:00
+++ b/net/sctp/ipv6.c	2005-03-01 23:38:59 -08:00
@@ -84,8 +84,8 @@
 };
 
 /* ICMP error handler. */
-void sctp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
-		 int type, int code, int offset, __u32 info)
+SCTP_STATIC void sctp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
+			     int type, int code, int offset, __u32 info)
 {
 	struct inet6_dev *idev;
 	struct ipv6hdr *iph = (struct ipv6hdr *)skb->data;
@@ -122,6 +122,12 @@
 	case ICMPV6_PKT_TOOBIG:
 		sctp_icmp_frag_needed(sk, asoc, transport, ntohl(info));
 		goto out_unlock;
+	case ICMPV6_PARAMPROB:
+		if (ICMPV6_UNK_NEXTHDR == code) {
+			sctp_icmp_proto_unreachable(sk, ep, asoc, transport);
+			goto out_unlock;
+		}
+		break;
 	default:
 		break;
 	}
@@ -188,9 +194,9 @@
 /* Returns the dst cache entry for the given source and destination ip
  * addresses.
  */
-struct dst_entry *sctp_v6_get_dst(struct sctp_association *asoc,
-				  union sctp_addr *daddr,
-				  union sctp_addr *saddr)
+static struct dst_entry *sctp_v6_get_dst(struct sctp_association *asoc,
+					 union sctp_addr *daddr,
+					 union sctp_addr *saddr)
 {
 	struct dst_entry *dst;
 	struct flowi fl;
@@ -251,8 +257,10 @@
 /* Fills in the source address(saddr) based on the destination address(daddr)
  * and asoc's bind address list.
  */
-void sctp_v6_get_saddr(struct sctp_association *asoc, struct dst_entry *dst,
-		       union sctp_addr *daddr, union sctp_addr *saddr)
+static void sctp_v6_get_saddr(struct sctp_association *asoc,
+			      struct dst_entry *dst,
+			      union sctp_addr *daddr,
+			      union sctp_addr *saddr)
 {
 	struct sctp_bind_addr *bp;
 	rwlock_t *addr_lock;
@@ -494,7 +502,7 @@
 }
 
 /* Should this be available for binding?   */
-static int sctp_v6_available(union sctp_addr *addr, struct sctp_opt *sp)
+static int sctp_v6_available(union sctp_addr *addr, struct sctp_sock *sp)
 {
 	int type;
 	struct in6_addr *in6 = (struct in6_addr *)&addr->v6.sin6_addr;
@@ -523,14 +531,14 @@
  * Return 0 - If the address is a non-unicast or an illegal address.
  * Return 1 - If the address is a unicast.
  */
-static int sctp_v6_addr_valid(union sctp_addr *addr, struct sctp_opt *sp)
+static int sctp_v6_addr_valid(union sctp_addr *addr, struct sctp_sock *sp)
 {
 	int ret = ipv6_addr_type(&addr->v6.sin6_addr);
 
 	/* Support v4-mapped-v6 address. */
 	if (ret == IPV6_ADDR_MAPPED) {
 		/* Note: This routine is used in input, so v4-mapped-v6
-		 * are disallowed here when there is no sctp_opt.
+		 * are disallowed here when there is no sctp_sock.
 		 */
 		if (!sp || !sp->v4mapped)
 			return 0;
@@ -577,12 +585,12 @@
 }
 
 /* Create and initialize a new sk for the socket to be returned by accept(). */
-struct sock *sctp_v6_create_accept_sk(struct sock *sk,
-				      struct sctp_association *asoc)
+static struct sock *sctp_v6_create_accept_sk(struct sock *sk,
+					     struct sctp_association *asoc)
 {
-	struct inet_opt *inet = inet_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
 	struct sock *newsk;
-	struct inet_opt *newinet;
+	struct inet_sock *newinet;
 	struct ipv6_pinfo *newnp, *np = inet6_sk(sk);
 	struct sctp6_sock *newsctp6sk;
 
@@ -608,7 +616,7 @@
 	newsk->sk_shutdown = sk->sk_shutdown;
 
 	newsctp6sk = (struct sctp6_sock *)newsk;
-	newsctp6sk->pinet6 = &newsctp6sk->inet6;
+	inet_sk(newsk)->pinet6 = &newsctp6sk->inet6;
 
 	newinet = inet_sk(newsk);
 	newnp = inet6_sk(newsk);
@@ -653,7 +661,7 @@
 }
 
 /* Map v4 address to mapped v6 address */
-static void sctp_v6_addr_v4map(struct sctp_opt *sp, union sctp_addr *addr)
+static void sctp_v6_addr_v4map(struct sctp_sock *sp, union sctp_addr *addr)
 {
 	if (sp->v4mapped && AF_INET == addr->sa.sa_family)
 		sctp_v4_map_v6(addr);
@@ -758,7 +766,7 @@
 }
 
 /* Do we support this AF? */
-static int sctp_inet6_af_supported(sa_family_t family, struct sctp_opt *sp)
+static int sctp_inet6_af_supported(sa_family_t family, struct sctp_sock *sp)
 {
 	switch (family) {
 	case AF_INET6:
@@ -778,7 +786,7 @@
  */
 static int sctp_inet6_cmp_addr(const union sctp_addr *addr1,
 			       const union sctp_addr *addr2,
-			       struct sctp_opt *opt)
+			       struct sctp_sock *opt)
 {
 	struct sctp_af *af1, *af2;
 
@@ -800,7 +808,7 @@
 /* Verify that the provided sockaddr looks bindable.   Common verification,
  * has already been taken care of.
  */
-static int sctp_inet6_bind_verify(struct sctp_opt *opt, union sctp_addr *addr)
+static int sctp_inet6_bind_verify(struct sctp_sock *opt, union sctp_addr *addr)
 {
 	struct sctp_af *af;
 
@@ -830,7 +838,7 @@
 /* Verify that the provided sockaddr looks bindable.   Common verification,
  * has already been taken care of.
  */
-static int sctp_inet6_send_verify(struct sctp_opt *opt, union sctp_addr *addr)
+static int sctp_inet6_send_verify(struct sctp_sock *opt, union sctp_addr *addr)
 {
 	struct sctp_af *af = NULL;
 
@@ -864,7 +872,7 @@
  * addresses.
  * Returns number of addresses supported.
  */
-static int sctp_inet6_supported_addrs(const struct sctp_opt *opt,
+static int sctp_inet6_supported_addrs(const struct sctp_sock *opt,
 				      __u16 *types)
 {
 	types[0] = SCTP_PARAM_IPV4_ADDRESS;
diff -Nru a/net/sctp/objcnt.c b/net/sctp/objcnt.c
--- a/net/sctp/objcnt.c	2005-03-01 23:38:52 -08:00
+++ b/net/sctp/objcnt.c	2005-03-01 23:38:52 -08:00
@@ -62,7 +62,7 @@
 /* An array to make it easy to pretty print the debug information
  * to the proc fs.
  */
-sctp_dbg_objcnt_entry_t sctp_dbg_objcnt[] = {
+static sctp_dbg_objcnt_entry_t sctp_dbg_objcnt[] = {
 	SCTP_DBG_OBJCNT_ENTRY(sock),
 	SCTP_DBG_OBJCNT_ENTRY(ep),
 	SCTP_DBG_OBJCNT_ENTRY(assoc),
diff -Nru a/net/sctp/output.c b/net/sctp/output.c
--- a/net/sctp/output.c	2005-03-01 23:38:53 -08:00
+++ b/net/sctp/output.c	2005-03-01 23:38:53 -08:00
@@ -110,7 +110,7 @@
 	packet->destination_port = dport;
 	skb_queue_head_init(&packet->chunks);
 	if (asoc) {
-		struct sctp_opt *sp = sctp_sk(asoc->base.sk);	
+		struct sctp_sock *sp = sctp_sk(asoc->base.sk);	
 		overhead = sp->pf->af->net_header_len; 
 	} else {
 		overhead = sizeof(struct ipv6hdr);
@@ -534,7 +534,7 @@
 	struct sctp_transport *transport = packet->transport;
 	__u32 max_burst_bytes;
 	struct sctp_association *asoc = transport->asoc;
-	struct sctp_opt *sp = sctp_sk(asoc->base.sk);
+	struct sctp_sock *sp = sctp_sk(asoc->base.sk);
 	struct sctp_outq *q = &asoc->outqueue;
 
 	/* RFC 2960 6.1  Transmission of DATA Chunks
diff -Nru a/net/sctp/outqueue.c b/net/sctp/outqueue.c
--- a/net/sctp/outqueue.c	2005-03-01 23:38:55 -08:00
+++ b/net/sctp/outqueue.c	2005-03-01 23:38:55 -08:00
@@ -190,19 +190,6 @@
 	return 0;
 }
 
-/* Generate a new outqueue.  */
-struct sctp_outq *sctp_outq_new(struct sctp_association *asoc)
-{
-	struct sctp_outq *q;
-
-	q = t_new(struct sctp_outq, GFP_KERNEL);
-	if (q) {
-		sctp_outq_init(asoc, q);
-		q->malloced = 1;
-	}
-	return q;
-}
-
 /* Initialize an existing sctp_outq.  This does the boring stuff.
  * You still need to define handlers if you really want to DO
  * something with this structure...
@@ -362,7 +349,7 @@
 /* Insert a chunk into the sorted list based on the TSNs.  The retransmit list
  * and the abandoned list are in ascending order.
  */
-void sctp_insert_list(struct list_head *head, struct list_head *new)
+static void sctp_insert_list(struct list_head *head, struct list_head *new)
 {
 	struct list_head *pos;
 	struct sctp_chunk *nchunk, *lchunk;
diff -Nru a/net/sctp/proc.c b/net/sctp/proc.c
--- a/net/sctp/proc.c	2005-03-01 23:39:18 -08:00
+++ b/net/sctp/proc.c	2005-03-01 23:39:18 -08:00
@@ -39,7 +39,7 @@
 #include <linux/init.h>
 #include <net/sctp/sctp.h>
 
-struct snmp_mib sctp_snmp_list[] = {
+static struct snmp_mib sctp_snmp_list[] = {
 	SNMP_MIB_ITEM("SctpCurrEstab", SCTP_MIB_CURRESTAB),
 	SNMP_MIB_ITEM("SctpActiveEstabs", SCTP_MIB_ACTIVEESTABS),
 	SNMP_MIB_ITEM("SctpPassiveEstabs", SCTP_MIB_PASSIVEESTABS),
diff -Nru a/net/sctp/protocol.c b/net/sctp/protocol.c
--- a/net/sctp/protocol.c	2005-03-01 23:38:59 -08:00
+++ b/net/sctp/protocol.c	2005-03-01 23:38:59 -08:00
@@ -65,7 +65,7 @@
 DEFINE_SNMP_STAT(struct sctp_mib, sctp_statistics);
 
 struct idr sctp_assocs_id;
-spinlock_t sctp_assocs_id_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(sctp_assocs_id_lock);
 
 /* This is the global socket data structure used for responding to
  * the Out-of-the-blue (OOTB) packets.  A control sock will be created
@@ -95,7 +95,7 @@
 }
 
 /* Set up the proc fs entry for the SCTP protocol. */
-__init int sctp_proc_init(void)
+static __init int sctp_proc_init(void)
 {
 	if (!proc_net_sctp) {
 		struct proc_dir_entry *ent;
@@ -124,7 +124,7 @@
  * Note: Do not make this __exit as it is used in the init error
  * path.
  */
-void sctp_proc_exit(void)
+static void sctp_proc_exit(void)
 {
 	sctp_snmp_proc_exit();
 	sctp_eps_proc_exit();
@@ -364,7 +364,7 @@
  * Return 0 - If the address is a non-unicast or an illegal address.
  * Return 1 - If the address is a unicast.
  */
-static int sctp_v4_addr_valid(union sctp_addr *addr, struct sctp_opt *sp)
+static int sctp_v4_addr_valid(union sctp_addr *addr, struct sctp_sock *sp)
 {
 	/* Is this a non-unicast address or a unusable SCTP address? */
 	if (IS_IPV4_UNUSABLE_ADDRESS(&addr->v4.sin_addr.s_addr))
@@ -374,7 +374,7 @@
 }
 
 /* Should this be available for binding?   */
-static int sctp_v4_available(union sctp_addr *addr, struct sctp_opt *sp)
+static int sctp_v4_available(union sctp_addr *addr, struct sctp_sock *sp)
 {
 	int ret = inet_addr_type(addr->v4.sin_addr.s_addr);
 
@@ -428,9 +428,9 @@
  * addresses. If an association is passed, trys to get a dst entry with a
  * source address that matches an address in the bind address list.
  */
-struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc,
-				  union sctp_addr *daddr,
-				  union sctp_addr *saddr)
+static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc,
+					 union sctp_addr *daddr,
+					 union sctp_addr *saddr)
 {
 	struct rtable *rt;
 	struct flowi fl;
@@ -520,10 +520,10 @@
 /* For v4, the source address is cached in the route entry(dst). So no need
  * to cache it separately and hence this is an empty routine.
  */
-void sctp_v4_get_saddr(struct sctp_association *asoc,
-		       struct dst_entry *dst,
-		       union sctp_addr *daddr,
-		       union sctp_addr *saddr)
+static void sctp_v4_get_saddr(struct sctp_association *asoc,
+			      struct dst_entry *dst,
+			      union sctp_addr *daddr,
+			      union sctp_addr *saddr)
 {
 	struct rtable *rt = (struct rtable *)dst;
 
@@ -547,12 +547,12 @@
 }
 
 /* Create and initialize a new sk for the socket returned by accept(). */
-struct sock *sctp_v4_create_accept_sk(struct sock *sk,
-				      struct sctp_association *asoc)
+static struct sock *sctp_v4_create_accept_sk(struct sock *sk,
+					     struct sctp_association *asoc)
 {
 	struct sock *newsk;
-	struct inet_opt *inet = inet_sk(sk);
-	struct inet_opt *newinet;
+	struct inet_sock *inet = inet_sk(sk);
+	struct inet_sock *newinet;
 
 	newsk = sk_alloc(PF_INET, GFP_KERNEL, sk->sk_prot->slab_obj_size,
 			 sk->sk_prot->slab);
@@ -608,7 +608,7 @@
 }
 
 /* Map address, empty for v4 family */
-static void sctp_v4_addr_v4map(struct sctp_opt *sp, union sctp_addr *addr)
+static void sctp_v4_addr_v4map(struct sctp_sock *sp, union sctp_addr *addr)
 {
 	/* Empty */
 }
@@ -639,7 +639,7 @@
  * Initialize the control inode/socket with a control endpoint data
  * structure.  This endpoint is reserved exclusively for the OOTB processing.
  */
-int sctp_ctl_sock_init(void)
+static int sctp_ctl_sock_init(void)
 {
 	int err;
 	sa_family_t family;
@@ -745,7 +745,7 @@
 }
 
 /* Do we support this AF? */
-static int sctp_inet_af_supported(sa_family_t family, struct sctp_opt *sp)
+static int sctp_inet_af_supported(sa_family_t family, struct sctp_sock *sp)
 {
 	/* PF_INET only supports AF_INET addresses. */
 	return (AF_INET == family);
@@ -754,7 +754,7 @@
 /* Address matching with wildcards allowed. */
 static int sctp_inet_cmp_addr(const union sctp_addr *addr1,
 			      const union sctp_addr *addr2,
-			      struct sctp_opt *opt)
+			      struct sctp_sock *opt)
 {
 	/* PF_INET only supports AF_INET addresses. */
 	if (addr1->sa.sa_family != addr2->sa.sa_family)
@@ -771,7 +771,7 @@
 /* Verify that provided sockaddr looks bindable.  Common verification has
  * already been taken care of.
  */
-static int sctp_inet_bind_verify(struct sctp_opt *opt, union sctp_addr *addr)
+static int sctp_inet_bind_verify(struct sctp_sock *opt, union sctp_addr *addr)
 {
 	return sctp_v4_available(addr, opt);
 }
@@ -779,7 +779,7 @@
 /* Verify that sockaddr looks sendable.  Common verification has already
  * been taken care of.
  */
-static int sctp_inet_send_verify(struct sctp_opt *opt, union sctp_addr *addr)
+static int sctp_inet_send_verify(struct sctp_sock *opt, union sctp_addr *addr)
 {
 	return 1;
 }
@@ -787,7 +787,7 @@
 /* Fill in Supported Address Type information for INIT and INIT-ACK
  * chunks.  Returns number of addresses supported.
  */
-static int sctp_inet_supported_addrs(const struct sctp_opt *opt,
+static int sctp_inet_supported_addrs(const struct sctp_sock *opt,
 				     __u16 *types)
 {
 	types[0] = SCTP_PARAM_IPV4_ADDRESS;
@@ -808,7 +808,7 @@
 	return ip_queue_xmit(skb, ipfragok);
 }
 
-struct sctp_af sctp_ipv4_specific;
+static struct sctp_af sctp_ipv4_specific;
 
 static struct sctp_pf sctp_pf_inet = {
 	.event_msgname = sctp_inet_event_msgname,
@@ -829,7 +829,7 @@
 };
 
 /* Socket operations.  */
-struct proto_ops inet_seqpacket_ops = {
+static struct proto_ops inet_seqpacket_ops = {
 	.family      = PF_INET,
 	.owner       = THIS_MODULE,
 	.release     = inet_release,       /* Needs to be wrapped... */
@@ -878,7 +878,7 @@
 };
 
 /* IPv4 address related functions.  */
-struct sctp_af sctp_ipv4_specific = {
+static struct sctp_af sctp_ipv4_specific = {
 	.sctp_xmit      = sctp_v4_xmit,
 	.setsockopt     = ip_setsockopt,
 	.getsockopt     = ip_getsockopt,
@@ -959,7 +959,7 @@
 }
 
 /* Initialize the universe into something sensible.  */
-__init int sctp_init(void)
+SCTP_STATIC __init int sctp_init(void)
 {
 	int i;
 	int status = -EINVAL;
@@ -1196,7 +1196,7 @@
 }
 
 /* Exit handler for the SCTP protocol.  */
-__exit void sctp_exit(void)
+SCTP_STATIC __exit void sctp_exit(void)
 {
 	/* BUG.  This should probably do something useful like clean
 	 * up all the remaining associations and all that memory.
diff -Nru a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
--- a/net/sctp/sm_make_chunk.c	2005-03-01 23:38:52 -08:00
+++ b/net/sctp/sm_make_chunk.c	2005-03-01 23:38:52 -08:00
@@ -67,6 +67,19 @@
 
 extern kmem_cache_t *sctp_chunk_cachep;
 
+SCTP_STATIC
+struct sctp_chunk *sctp_make_chunk(const struct sctp_association *asoc,
+				   __u8 type, __u8 flags, int paylen);
+static sctp_cookie_param_t *sctp_pack_cookie(const struct sctp_endpoint *ep,
+					const struct sctp_association *asoc,
+					const struct sctp_chunk *init_chunk,
+					int *cookie_len,
+					const __u8 *raw_addrs, int addrs_len);
+static int sctp_process_param(struct sctp_association *asoc,
+			      union sctp_params param,
+			      const union sctp_addr *peer_addr,
+			      int gfp);
+
 /* What was the inbound interface for this chunk? */
 int sctp_chunk_iif(const struct sctp_chunk *chunk)
 {
@@ -168,7 +181,7 @@
 	size_t chunksize;
 	struct sctp_chunk *retval = NULL;
 	int num_types, addrs_len = 0;
-	struct sctp_opt *sp;
+	struct sctp_sock *sp;
 	sctp_supported_addrs_param_t sat;
 	__u16 types[2];
 	sctp_adaption_ind_param_t aiparam;
@@ -559,52 +572,6 @@
 	return retval;
 }
 
-/* Make a DATA chunk for the given association.  Populate the data
- * payload.
- */
-struct sctp_chunk *sctp_make_datafrag(struct sctp_association *asoc,
-				 const struct sctp_sndrcvinfo *sinfo,
-				 int data_len, const __u8 *data,
-				 __u8 flags, __u16 ssn)
-{
-	struct sctp_chunk *retval;
-
-	retval = sctp_make_datafrag_empty(asoc, sinfo, data_len, flags, ssn);
-	if (retval)
-		sctp_addto_chunk(retval, data_len, data);
-
-	return retval;
-}
-
-/* Make a DATA chunk for the given association to ride on stream id
- * 'stream', with a payload id of 'payload', and a body of 'data'.
- */
-struct sctp_chunk *sctp_make_data(struct sctp_association *asoc,
-			     const struct sctp_sndrcvinfo *sinfo,
-			     int data_len, const __u8 *data)
-{
-	struct sctp_chunk *retval = NULL;
-
-	retval = sctp_make_data_empty(asoc, sinfo, data_len);
-	if (retval)
-		sctp_addto_chunk(retval, data_len, data);
-        return retval;
-}
-
-/* Make a DATA chunk for the given association to ride on stream id
- * 'stream', with a payload id of 'payload', and a body big enough to
- * hold 'data_len' octets of data.  We use this version when we need
- * to build the message AFTER allocating memory.
- */
-struct sctp_chunk *sctp_make_data_empty(struct sctp_association *asoc,
-				   const struct sctp_sndrcvinfo *sinfo,
-				   int data_len)
-{
-	__u8 flags = SCTP_DATA_NOT_FRAG;
-
-	return sctp_make_datafrag_empty(asoc, sinfo, data_len, flags, 0);
-}
-
 /* Create a selective ackowledgement (SACK) for the given
  * association.  This reports on which TSN's we've seen to date,
  * including duplicates and gaps.
@@ -881,6 +848,31 @@
 	return retval;
 }
 
+/* Make an ABORT chunk with a PROTOCOL VIOLATION cause code. */ 
+struct sctp_chunk *sctp_make_abort_violation(
+	const struct sctp_association *asoc,
+	const struct sctp_chunk *chunk,
+	const __u8   *payload,
+	const size_t paylen)
+{
+	struct sctp_chunk  *retval;
+	struct sctp_paramhdr phdr;
+
+	retval = sctp_make_abort(asoc, chunk, sizeof(sctp_errhdr_t) + paylen
+					+ sizeof(sctp_chunkhdr_t));
+	if (!retval)
+		goto end;
+
+	sctp_init_cause(retval, SCTP_ERROR_PROTO_VIOLATION, payload, paylen);
+
+	phdr.type = htons(chunk->chunk_hdr->type);
+	phdr.length = chunk->chunk_hdr->length;
+	sctp_addto_chunk(retval, sizeof(sctp_paramhdr_t), &phdr);
+
+end:
+	return retval;
+}
+
 /* Make a HEARTBEAT chunk.  */
 struct sctp_chunk *sctp_make_heartbeat(const struct sctp_association *asoc,
 				  const struct sctp_transport *transport,
@@ -933,7 +925,7 @@
 /* Create an Operation Error chunk with the specified space reserved.
  * This routine can be used for containing multiple causes in the chunk.
  */
-struct sctp_chunk *sctp_make_op_error_space(
+static struct sctp_chunk *sctp_make_op_error_space(
 	const struct sctp_association *asoc,
 	const struct sctp_chunk *chunk,
 	size_t size)
@@ -1034,7 +1026,6 @@
 	SCTP_DBG_OBJCNT_INC(chunk);
 	atomic_set(&retval->refcnt, 1);
 
-
 nodata:
 	return retval;
 }
@@ -1062,6 +1053,7 @@
 /* Create a new chunk, setting the type and flags headers from the
  * arguments, reserving enough space for a 'paylen' byte payload.
  */
+SCTP_STATIC
 struct sctp_chunk *sctp_make_chunk(const struct sctp_association *asoc,
 				   __u8 type, __u8 flags, int paylen)
 {
@@ -1261,7 +1253,7 @@
 /* Build a cookie representing asoc.
  * This INCLUDES the param header needed to put the cookie in the INIT ACK.
  */
-sctp_cookie_param_t *sctp_pack_cookie(const struct sctp_endpoint *ep,
+static sctp_cookie_param_t *sctp_pack_cookie(const struct sctp_endpoint *ep,
 				      const struct sctp_association *asoc,
 				      const struct sctp_chunk *init_chunk,
 				      int *cookie_len,
@@ -1409,6 +1401,24 @@
 	}
 
 no_hmac:
+	/* IG Section 2.35.2:
+	 *  3) Compare the port numbers and the verification tag contained
+	 *     within the COOKIE ECHO chunk to the actual port numbers and the
+	 *     verification tag within the SCTP common header of the received
+	 *     packet. If these values do not match the packet MUST be silently
+	 *     discarded,
+	 */
+	if (ntohl(chunk->sctp_hdr->vtag) != bear_cookie->my_vtag) {
+		*error = -SCTP_IERROR_BAD_TAG;
+		goto fail;
+	}
+
+	if (ntohs(chunk->sctp_hdr->source) != bear_cookie->peer_addr.v4.sin_port ||
+	    ntohs(chunk->sctp_hdr->dest) != bear_cookie->my_port) {
+		*error = -SCTP_IERROR_BAD_PORTS;
+		goto fail;
+	}
+
 	/* Check to see if the cookie is stale.  If there is already
 	 * an association, there is no need to check cookie's expiration
 	 * for init collision case of lost COOKIE ACK.
@@ -1547,6 +1557,30 @@
 	return 0;
 }
 
+static int sctp_process_inv_paramlength(const struct sctp_association *asoc,
+					struct sctp_paramhdr *param,
+					const struct sctp_chunk *chunk,
+					struct sctp_chunk **errp)
+{
+	char		error[] = "The following parameter had invalid length:";
+	size_t		payload_len = WORD_ROUND(sizeof(error)) + 
+						sizeof(sctp_paramhdr_t);
+
+
+	/* Create an error chunk and fill it in with our payload. */
+	if (!*errp)
+		*errp = sctp_make_op_error_space(asoc, chunk, payload_len);
+
+	if (*errp) {
+		sctp_init_cause(*errp, SCTP_ERROR_PROTO_VIOLATION, error,
+				sizeof(error));
+		sctp_addto_chunk(*errp, sizeof(sctp_paramhdr_t), param);
+	}
+
+	return 0;
+}
+
+
 /* Do not attempt to handle the HOST_NAME parm.  However, do
  * send back an indicator to the peer.
  */
@@ -1725,6 +1759,18 @@
 
 	} /* for (loop through all parameters) */
 
+	/* There is a possibility that a parameter length was bad and
+	 * in that case we would have stoped walking the parameters.
+	 * The current param.p would point at the bad one.
+	 * Current consensus on the mailing list is to generate a PROTOCOL
+	 * VIOLATION error.  We build the ERROR chunk here and let the normal
+	 * error handling code build and send the packet.
+	 */
+	if (param.v < (void*)chunk->chunk_end - sizeof(sctp_paramhdr_t)) {
+		sctp_process_inv_paramlength(asoc, param.p, chunk, errp);
+		return 0;
+	}
+
 	/* The only missing mandatory param possible today is
 	 * the state cookie for an INIT-ACK chunk.
 	 */
@@ -1912,8 +1958,10 @@
  * work we do.  In particular, we should not build transport
  * structures for the addresses.
  */
-int sctp_process_param(struct sctp_association *asoc, union sctp_params param,
-		       const union sctp_addr *peer_addr, int gfp)
+static int sctp_process_param(struct sctp_association *asoc,
+			      union sctp_params param,
+			      const union sctp_addr *peer_addr,
+			      int gfp)
 {
 	union sctp_addr addr;
 	int i;
@@ -2078,8 +2126,9 @@
  *
  * Address Parameter and other parameter will not be wrapped in this function 
  */
-struct sctp_chunk *sctp_make_asconf(struct sctp_association *asoc,
-				    union sctp_addr *addr, int vparam_len)
+static struct sctp_chunk *sctp_make_asconf(struct sctp_association *asoc,
+					   union sctp_addr *addr,
+					   int vparam_len)
 {
 	sctp_addiphdr_t asconf;
 	struct sctp_chunk *retval;
@@ -2248,8 +2297,8 @@
  *
  * Create an ASCONF_ACK chunk with enough space for the parameter responses. 
  */
-struct sctp_chunk *sctp_make_asconf_ack(const struct sctp_association *asoc,
-					__u32 serial, int vparam_len)
+static struct sctp_chunk *sctp_make_asconf_ack(const struct sctp_association *asoc,
+					       __u32 serial, int vparam_len)
 {
 	sctp_addiphdr_t		asconf;
 	struct sctp_chunk	*retval;
diff -Nru a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
--- a/net/sctp/sm_sideeffect.c	2005-03-01 23:39:07 -08:00
+++ b/net/sctp/sm_sideeffect.c	2005-03-01 23:39:07 -08:00
@@ -55,6 +55,24 @@
 #include <net/sctp/sctp.h>
 #include <net/sctp/sm.h>
 
+static int sctp_cmd_interpreter(sctp_event_t event_type,
+				sctp_subtype_t subtype,
+				sctp_state_t state,
+				struct sctp_endpoint *ep,
+				struct sctp_association *asoc,
+				void *event_arg,
+			 	sctp_disposition_t status,
+				sctp_cmd_seq_t *commands,
+				int gfp);
+static int sctp_side_effects(sctp_event_t event_type, sctp_subtype_t subtype,
+			     sctp_state_t state,
+			     struct sctp_endpoint *ep,
+			     struct sctp_association *asoc,
+			     void *event_arg,
+			     sctp_disposition_t status,
+			     sctp_cmd_seq_t *commands,
+			     int gfp);
+
 /********************************************************************
  * Helper functions
  ********************************************************************/
@@ -134,8 +152,8 @@
 }
 
 /* Generate SACK if necessary.  We call this at the end of a packet.  */
-int sctp_gen_sack(struct sctp_association *asoc, int force,
-		  sctp_cmd_seq_t *commands)
+static int sctp_gen_sack(struct sctp_association *asoc, int force,
+			 sctp_cmd_seq_t *commands)
 {
 	__u32 ctsn, max_tsn_seen;
 	struct sctp_chunk *sack;
@@ -276,31 +294,31 @@
 	sctp_association_put(asoc);
 }
 
-void sctp_generate_t1_cookie_event(unsigned long data)
+static void sctp_generate_t1_cookie_event(unsigned long data)
 {
 	struct sctp_association *asoc = (struct sctp_association *) data;
 	sctp_generate_timeout_event(asoc, SCTP_EVENT_TIMEOUT_T1_COOKIE);
 }
 
-void sctp_generate_t1_init_event(unsigned long data)
+static void sctp_generate_t1_init_event(unsigned long data)
 {
 	struct sctp_association *asoc = (struct sctp_association *) data;
 	sctp_generate_timeout_event(asoc, SCTP_EVENT_TIMEOUT_T1_INIT);
 }
 
-void sctp_generate_t2_shutdown_event(unsigned long data)
+static void sctp_generate_t2_shutdown_event(unsigned long data)
 {
 	struct sctp_association *asoc = (struct sctp_association *) data;
 	sctp_generate_timeout_event(asoc, SCTP_EVENT_TIMEOUT_T2_SHUTDOWN);
 }
 
-void sctp_generate_t4_rto_event(unsigned long data)
+static void sctp_generate_t4_rto_event(unsigned long data)
 {
 	struct sctp_association *asoc = (struct sctp_association *) data;
 	sctp_generate_timeout_event(asoc, SCTP_EVENT_TIMEOUT_T4_RTO);
 }
 
-void sctp_generate_t5_shutdown_guard_event(unsigned long data)
+static void sctp_generate_t5_shutdown_guard_event(unsigned long data)
 {
         struct sctp_association *asoc = (struct sctp_association *)data;
         sctp_generate_timeout_event(asoc,
@@ -308,7 +326,7 @@
 
 } /* sctp_generate_t5_shutdown_guard_event() */
 
-void sctp_generate_autoclose_event(unsigned long data)
+static void sctp_generate_autoclose_event(unsigned long data)
 {
 	struct sctp_association *asoc = (struct sctp_association *) data;
 	sctp_generate_timeout_event(asoc, SCTP_EVENT_TIMEOUT_AUTOCLOSE);
@@ -353,7 +371,7 @@
 }
 
 /* Inject a SACK Timeout event into the state machine.  */
-void sctp_generate_sack_event(unsigned long data)
+static void sctp_generate_sack_event(unsigned long data)
 {
 	struct sctp_association *asoc = (struct sctp_association *) data;
 	sctp_generate_timeout_event(asoc, SCTP_EVENT_TIMEOUT_SACK);
@@ -397,7 +415,7 @@
 	asoc->overall_error_count++;
 
 	if (transport->active &&
-	    (transport->error_count++ >= transport->error_threshold)) {
+	    (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));
@@ -857,14 +875,14 @@
 /*****************************************************************
  * This the master state function side effect processing function.
  *****************************************************************/
-int sctp_side_effects(sctp_event_t event_type, sctp_subtype_t subtype,
-		      sctp_state_t state,
-		      struct sctp_endpoint *ep,
-		      struct sctp_association *asoc,
-		      void *event_arg,
-		      sctp_disposition_t status,
-		      sctp_cmd_seq_t *commands,
-		      int gfp)
+static int sctp_side_effects(sctp_event_t event_type, sctp_subtype_t subtype,
+			     sctp_state_t state,
+			     struct sctp_endpoint *ep,
+			     struct sctp_association *asoc,
+			     void *event_arg,
+			     sctp_disposition_t status,
+			     sctp_cmd_seq_t *commands,
+			     int gfp)
 {
 	int error;
 
@@ -944,11 +962,15 @@
  ********************************************************************/
 
 /* This is the side-effect interpreter.  */
-int sctp_cmd_interpreter(sctp_event_t event_type, sctp_subtype_t subtype,
-			 sctp_state_t state, struct sctp_endpoint *ep,
-			 struct sctp_association *asoc, void *event_arg,
-			 sctp_disposition_t status, sctp_cmd_seq_t *commands,
-			 int gfp)
+static int sctp_cmd_interpreter(sctp_event_t event_type,
+				sctp_subtype_t subtype,
+				sctp_state_t state,
+				struct sctp_endpoint *ep,
+				struct sctp_association *asoc,
+				void *event_arg,
+			 	sctp_disposition_t status,
+				sctp_cmd_seq_t *commands,
+				int gfp)
 {
 	int error = 0;
 	int force;
diff -Nru a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
--- a/net/sctp/sm_statefuns.c	2005-03-01 23:38:52 -08:00
+++ b/net/sctp/sm_statefuns.c	2005-03-01 23:38:52 -08:00
@@ -65,6 +65,53 @@
 #include <net/sctp/sm.h>
 #include <net/sctp/structs.h>
 
+static struct sctp_packet *sctp_abort_pkt_new(const struct sctp_endpoint *ep,
+				  const struct sctp_association *asoc,
+				  struct sctp_chunk *chunk,
+				  const void *payload,
+				  size_t paylen);
+static int sctp_eat_data(const struct sctp_association *asoc,
+			 struct sctp_chunk *chunk,
+			 sctp_cmd_seq_t *commands);
+static struct sctp_packet *sctp_ootb_pkt_new(const struct sctp_association *asoc,
+					     const struct sctp_chunk *chunk);
+static void sctp_send_stale_cookie_err(const struct sctp_endpoint *ep,
+				       const struct sctp_association *asoc,
+				       const struct sctp_chunk *chunk,
+				       sctp_cmd_seq_t *commands,
+				       struct sctp_chunk *err_chunk);
+static sctp_disposition_t sctp_sf_do_5_2_6_stale(const struct sctp_endpoint *ep,
+						 const struct sctp_association *asoc,
+						 const sctp_subtype_t type,
+						 void *arg,
+						 sctp_cmd_seq_t *commands);
+static sctp_disposition_t sctp_sf_shut_8_4_5(const struct sctp_endpoint *ep,
+					     const struct sctp_association *asoc,
+					     const sctp_subtype_t type,
+					     void *arg,
+					     sctp_cmd_seq_t *commands);
+static struct sctp_sackhdr *sctp_sm_pull_sack(struct sctp_chunk *chunk);
+
+
+/* Small helper function that checks if the chunk length
+ * is of the appropriate length.  The 'required_length' argument
+ * is set to be the size of a specific chunk we are testing.
+ * Return Values:  1 = Valid length
+ * 		   0 = Invalid length
+ *
+ */
+static inline int
+sctp_chunk_length_valid(struct sctp_chunk *chunk,
+			   __u16 required_length)
+{
+	__u16 chunk_length = ntohs(chunk->chunk_hdr->length);
+
+	if (unlikely(chunk_length < required_length))
+		return 0;
+
+	return 1;
+}
+
 /**********************************************************
  * These are the state functions for handling chunk events.
  **********************************************************/
@@ -199,9 +246,14 @@
 	/* 6.10 Bundling
 	 * An endpoint MUST NOT bundle INIT, INIT ACK or
 	 * SHUTDOWN COMPLETE with any other chunks.
+	 * 
+	 * IG Section 2.11.2
+	 * Furthermore, we require that the receiver of an INIT chunk MUST
+	 * enforce these rules by silently discarding an arriving packet
+	 * with an INIT chunk that is bundled with other chunks.
 	 */
 	if (!chunk->singleton)
-		return SCTP_DISPOSITION_VIOLATION;
+		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 
 	/* If the packet is an OOTB packet which is temporarily on the
 	 * control endpoint, respond with an ABORT.
@@ -225,6 +277,14 @@
 	if (chunk->sctp_hdr->vtag != 0)
 		return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
 
+	/* Make sure that the INIT chunk has a valid length.
+	 * Normally, this would cause an ABORT with a Protocol Violation
+	 * error, but since we don't have an association, we'll
+	 * just discard the packet.
+	 */
+	if (!sctp_chunk_length_valid(chunk, sizeof(sctp_init_chunk_t)))
+		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+
 	/* Verify the INIT chunk before processing it. */
 	err_chunk = NULL;
 	if (!sctp_verify_init(asoc, chunk->chunk_hdr->type,
@@ -376,6 +436,13 @@
 	struct sctp_packet *packet;
 	sctp_disposition_t ret;
 
+	if (!sctp_vtag_verify(chunk, asoc))
+		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+
+	/* Make sure that the INIT-ACK chunk has a valid length */
+	if (!sctp_chunk_length_valid(chunk, sizeof(sctp_initack_chunk_t)))
+		return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+						  commands);
 	/* 6.10 Bundling
 	 * An endpoint MUST NOT bundle INIT, INIT ACK or
 	 * SHUTDOWN COMPLETE with any other chunks.
@@ -383,9 +450,6 @@
 	if (!chunk->singleton)
 		return SCTP_DISPOSITION_VIOLATION;
 
-	if (!sctp_vtag_verify(chunk, asoc))
-		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
-
 	/* Grab the INIT header.  */
 	chunk->subh.init_hdr = (sctp_inithdr_t *) chunk->skb->data;
 
@@ -542,6 +606,14 @@
 	if (ep == sctp_sk((sctp_get_ctl_sock()))->ep)
 		return sctp_sf_ootb(ep, asoc, type, arg, commands);
 
+	/* Make sure that the COOKIE_ECHO chunk has a valid length.
+	 * In this case, we check that we have enough for at least a
+	 * chunk header.  More detailed verification is done
+	 * in sctp_unpack_cookie().
+	 */
+	if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t)))
+		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+
 	/* "Decode" the chunk.  We have no optional parameters so we
 	 * are in good shape.
 	 */
@@ -687,6 +759,13 @@
 	if (!sctp_vtag_verify(chunk, asoc))
 		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 
+	/* Verify that the chunk length for the COOKIE-ACK is OK.
+	 * If we don't do this, any bundled chunks may be junked.
+	 */
+	if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t)))
+		return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+						  commands);
+
 	/* Reset init error count upon receipt of COOKIE-ACK,
 	 * to avoid problems with the managemement of this
 	 * counter in stale cookie situations when a transition back
@@ -748,11 +827,11 @@
 }
 
 /* Generate and sendout a heartbeat packet.  */
-sctp_disposition_t sctp_sf_heartbeat(const struct sctp_endpoint *ep,
-				     const struct sctp_association *asoc,
-				     const sctp_subtype_t type,
-				     void *arg,
-				     sctp_cmd_seq_t *commands)
+static sctp_disposition_t sctp_sf_heartbeat(const struct sctp_endpoint *ep,
+					    const struct sctp_association *asoc,
+					    const sctp_subtype_t type,
+					    void *arg,
+					    sctp_cmd_seq_t *commands)
 {
 	struct sctp_transport *transport = (struct sctp_transport *) arg;
 	struct sctp_chunk *reply;
@@ -859,6 +938,11 @@
 	if (!sctp_vtag_verify(chunk, asoc))
 		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 
+	/* Make sure that the HEARTBEAT chunk has a valid length. */
+	if (!sctp_chunk_length_valid(chunk, sizeof(sctp_heartbeat_chunk_t)))
+		return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+						  commands);
+
 	/* 8.3 The receiver of the HEARTBEAT should immediately
 	 * respond with a HEARTBEAT ACK that contains the Heartbeat
 	 * Information field copied from the received HEARTBEAT chunk.
@@ -922,6 +1006,11 @@
 	if (!sctp_vtag_verify(chunk, asoc))
 		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 
+	/* Make sure that the HEARTBEAT-ACK chunk has a valid length.  */
+	if (!sctp_chunk_length_valid(chunk, sizeof(sctp_heartbeat_chunk_t)))
+		return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+						  commands);
+
 	hbinfo = (sctp_sender_hb_info_t *) chunk->skb->data;
 	from_addr = hbinfo->daddr;
 	link = sctp_assoc_lookup_paddr(asoc, &from_addr);
@@ -1165,9 +1254,14 @@
 	/* 6.10 Bundling
 	 * An endpoint MUST NOT bundle INIT, INIT ACK or
 	 * SHUTDOWN COMPLETE with any other chunks.
+	 *
+	 * IG Section 2.11.2
+	 * Furthermore, we require that the receiver of an INIT chunk MUST
+	 * enforce these rules by silently discarding an arriving packet
+	 * with an INIT chunk that is bundled with other chunks.
 	 */
 	if (!chunk->singleton)
-		return SCTP_DISPOSITION_VIOLATION;
+		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 
 	/* 3.1 A packet containing an INIT chunk MUST have a zero Verification
 	 * Tag. 
@@ -1175,6 +1269,13 @@
 	if (chunk->sctp_hdr->vtag != 0)
 		return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
 
+	/* Make sure that the INIT chunk has a valid length.
+	 * In this case, we generate a protocol violation since we have
+	 * an association established.
+	 */
+	if (!sctp_chunk_length_valid(chunk, sizeof(sctp_init_chunk_t)))
+		return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+						  commands);
 	/* Grab the INIT header.  */
 	chunk->subh.init_hdr = (sctp_inithdr_t *) chunk->skb->data;
 
@@ -1718,6 +1819,15 @@
 	char action;
 	struct sctp_chunk *err_chk_p;
 
+	/* Make sure that the chunk has a valid length from the protocol
+	 * perspective.  In this case check to make sure we have at least
+	 * enough for the chunk header.  Cookie length verification is
+	 * done later.
+	 */
+	if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t)))
+		return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+						  commands);
+
 	/* "Decode" the chunk.  We have no optional parameters so we
 	 * are in good shape.
 	 */
@@ -1815,6 +1925,19 @@
 	if (!sctp_vtag_verify_either(chunk, asoc))
 		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 
+	/* Make sure that the ABORT chunk has a valid length.
+	 * Since this is an ABORT chunk, we have to discard it
+	 * because of the following text:
+	 * RFC 2960, Section 3.3.7
+	 *    If an endpoint receives an ABORT with a format error or for an
+	 *    association that doesn't exist, it MUST silently discard it.
+	 * Becasue the length is "invalid", we can't really discard just
+	 * as we do not know its true length.  So, to be safe, discard the
+	 * packet.
+	 */
+	if (!sctp_chunk_length_valid(chunk, sizeof(sctp_abort_chunk_t)))
+		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+
 	/* Stop the T5-shutdown guard timer.  */
 	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
 			SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
@@ -1838,6 +1961,19 @@
 	if (!sctp_vtag_verify_either(chunk, asoc))
 		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 
+	/* Make sure that the ABORT chunk has a valid length.
+	 * Since this is an ABORT chunk, we have to discard it
+	 * because of the following text:
+	 * RFC 2960, Section 3.3.7
+	 *    If an endpoint receives an ABORT with a format error or for an
+	 *    association that doesn't exist, it MUST silently discard it.
+	 * Becasue the length is "invalid", we can't really discard just
+	 * as we do not know its true length.  So, to be safe, discard the
+	 * packet.
+	 */
+	if (!sctp_chunk_length_valid(chunk, sizeof(sctp_abort_chunk_t)))
+		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+
 	/* Stop the T2-shutdown timer. */
 	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
 			SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN));
@@ -1890,6 +2026,16 @@
 	struct sctp_chunk *chunk = arg;
 	sctp_errhdr_t *err;
 
+	if (!sctp_vtag_verify(chunk, asoc))
+		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+
+	/* Make sure that the ERROR chunk has a valid length.
+	 * The parameter walking depends on this as well.
+	 */
+	if (!sctp_chunk_length_valid(chunk, sizeof(sctp_operr_chunk_t)))
+		return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+						  commands);
+
 	/* Process the error here */
 	/* FUTURE FIXME:  When PR-SCTP related and other optional
 	 * parms are emitted, this will have to change to handle multiple
@@ -1900,6 +2046,12 @@
 			return sctp_sf_do_5_2_6_stale(ep, asoc, type, 
 							arg, commands);
 	}
+
+	/* It is possible to have malformed error causes, and that
+	 * will cause us to end the walk early.  However, since
+	 * we are discarding the packet, there should be no adverse
+	 * affects.
+	 */
 	return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 }
 
@@ -1928,11 +2080,11 @@
  *
  * The return value is the disposition of the chunk.
  */
-sctp_disposition_t sctp_sf_do_5_2_6_stale(const struct sctp_endpoint *ep,
-					  const struct sctp_association *asoc,
-					  const sctp_subtype_t type,
-					  void *arg,
-					  sctp_cmd_seq_t *commands)
+static sctp_disposition_t sctp_sf_do_5_2_6_stale(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 *chunk = arg;
 	time_t stale;
@@ -2064,12 +2216,24 @@
 	if (!sctp_vtag_verify_either(chunk, asoc))
 		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 
-	/* Check that chunk header looks valid.  */
+	/* Make sure that the ABORT chunk has a valid length.
+	 * Since this is an ABORT chunk, we have to discard it
+	 * because of the following text:
+	 * RFC 2960, Section 3.3.7
+	 *    If an endpoint receives an ABORT with a format error or for an
+	 *    association that doesn't exist, it MUST silently discard it.
+	 * Becasue the length is "invalid", we can't really discard just
+	 * as we do not know its true length.  So, to be safe, discard the
+	 * packet.
+	 */
+	if (!sctp_chunk_length_valid(chunk, sizeof(sctp_abort_chunk_t)))
+		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+
+	/* See if we have an error cause code in the chunk.  */
 	len = ntohs(chunk->chunk_hdr->length);
 	if (len >= sizeof(struct sctp_chunkhdr) + sizeof(struct sctp_errhdr))
 		error = ((sctp_errhdr_t *)chunk->skb->data)->cause;
 
-
  	/* ASSOC_FAILED will DELETE_TCB. */
 	sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, SCTP_U32(error));
 	SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
@@ -2096,27 +2260,43 @@
 	if (!sctp_vtag_verify_either(chunk, asoc))
 		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 
-	sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
-			SCTP_STATE(SCTP_STATE_CLOSED));
-	SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
-	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
-			SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT));
+	/* Make sure that the ABORT chunk has a valid length.
+	 * Since this is an ABORT chunk, we have to discard it
+	 * because of the following text:
+	 * RFC 2960, Section 3.3.7
+	 *    If an endpoint receives an ABORT with a format error or for an
+	 *    association that doesn't exist, it MUST silently discard it.
+	 * Becasue the length is "invalid", we can't really discard just
+	 * as we do not know its true length.  So, to be safe, discard the
+	 * packet.
+	 */
+	if (!sctp_chunk_length_valid(chunk, sizeof(sctp_abort_chunk_t)))
+		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 
-	/* Check that chunk header looks valid.  */
+	/* See if we have an error cause code in the chunk.  */
 	len = ntohs(chunk->chunk_hdr->length);
 	if (len >= sizeof(struct sctp_chunkhdr) + sizeof(struct sctp_errhdr))
 		error = ((sctp_errhdr_t *)chunk->skb->data)->cause;
 
-	/* CMD_INIT_FAILED will DELETE_TCB. */
-	sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED, SCTP_U32(error));
-
+ 	sctp_stop_t1_and_abort(commands, error);
 	return SCTP_DISPOSITION_ABORT;
 }
 
 /*
+ * Process an incoming ICMP as an ABORT.  (COOKIE-WAIT state)
+ */
+sctp_disposition_t sctp_sf_cookie_wait_icmp_abort(const struct sctp_endpoint *ep,
+					const struct sctp_association *asoc,
+					const sctp_subtype_t type,
+					void *arg,
+					sctp_cmd_seq_t *commands)
+{
+	sctp_stop_t1_and_abort(commands, SCTP_ERROR_NO_ERROR);
+ 	return SCTP_DISPOSITION_ABORT;
+}
+
+/*
  * Process an ABORT.  (COOKIE-ECHOED state)
- *
- * See sctp_sf_do_9_1_abort() above.
  */
 sctp_disposition_t sctp_sf_cookie_echoed_abort(const struct sctp_endpoint *ep,
 					       const struct sctp_association *asoc,
@@ -2131,6 +2311,23 @@
 }
 
 /*
+ * Stop T1 timer and abort association with "INIT failed".
+ *
+ * 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)
+{
+	sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
+			SCTP_STATE(SCTP_STATE_CLOSED));
+	SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
+	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
+			SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT));
+	/* CMD_INIT_FAILED will DELETE_TCB. */
+	sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED,
+			SCTP_U32(error));
+}
+
+/*
  * sctp_sf_do_9_2_shut
  *
  * Section: 9.2
@@ -2174,14 +2371,20 @@
 	sctp_disposition_t disposition;
 	struct sctp_ulpevent *ev;
 
+	if (!sctp_vtag_verify(chunk, asoc))
+		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+
+	/* Make sure that the SHUTDOWN chunk has a valid length. */
+	if (!sctp_chunk_length_valid(chunk,
+				      sizeof(struct sctp_shutdown_chunk_t)))
+		return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+						  commands);
+
 	/* Convert the elaborate header.  */
 	sdh = (sctp_shutdownhdr_t *)chunk->skb->data;
 	skb_pull(chunk->skb, sizeof(sctp_shutdownhdr_t));
 	chunk->subh.shutdown_hdr = sdh;
 
-	if (!sctp_vtag_verify(chunk, asoc))
-		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
-
 	/* Upon the reception of the SHUTDOWN, the peer endpoint shall
 	 *  - enter the SHUTDOWN-RECEIVED state,
 	 *  - stop accepting new data from its SCTP user
@@ -2238,6 +2441,10 @@
 	struct sctp_chunk *chunk = (struct sctp_chunk *) arg;
 	struct sctp_chunk *reply;
 
+	/* Since we are not going to really process this INIT, there
+	 * is no point in verifying chunk boundries.  Just generate
+	 * the SHUTDOWN ACK.
+	 */
 	reply = sctp_make_shutdown_ack(asoc, chunk);
 	if (NULL == reply)
 		goto nomem;
@@ -2295,6 +2502,10 @@
 	if (!sctp_vtag_verify(chunk, asoc))
 		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 
+	if (!sctp_chunk_length_valid(chunk, sizeof(sctp_ecne_chunk_t)))
+		return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+						  commands);
+		
 	cwr = (sctp_cwrhdr_t *) chunk->skb->data;
 	skb_pull(chunk->skb, sizeof(sctp_cwrhdr_t));
 
@@ -2345,6 +2556,10 @@
 	if (!sctp_vtag_verify(chunk, asoc))
 		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 
+	if (!sctp_chunk_length_valid(chunk, sizeof(sctp_ecne_chunk_t)))
+		return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+						  commands);
+
 	ecne = (sctp_ecnehdr_t *) chunk->skb->data;
 	skb_pull(chunk->skb, sizeof(sctp_ecnehdr_t));
 
@@ -2400,6 +2615,10 @@
 		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
         }
 
+	if (!sctp_chunk_length_valid(chunk, sizeof(sctp_data_chunk_t)))
+		return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+						  commands);
+
 	error = sctp_eat_data(asoc, chunk, commands );
 	switch (error) {
 	case SCTP_IERROR_NO_ERROR:
@@ -2517,6 +2736,10 @@
 		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 	}
 
+	if (!sctp_chunk_length_valid(chunk, sizeof(sctp_data_chunk_t)))
+		return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+						  commands);
+
 	error = sctp_eat_data(asoc, chunk, commands );
 	switch (error) {
 	case SCTP_IERROR_NO_ERROR:
@@ -2598,6 +2821,11 @@
 	if (!sctp_vtag_verify(chunk, asoc))
 		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 
+	/* Make sure that the SACK chunk has a valid length. */
+	if (!sctp_chunk_length_valid(chunk, sizeof(sctp_sack_chunk_t)))
+		return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+						  commands);
+
 	/* Pull the SACK chunk from the data buffer */
 	sackh = sctp_sm_pull_sack(chunk);
 	/* Was this a bogus SACK? */
@@ -2700,6 +2928,14 @@
 	struct sctp_chunk *chunk = arg;
 	struct sctp_ulpevent *ev;
 
+	if (!sctp_vtag_verify(chunk, asoc))
+		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+
+	/* Make sure that the ERROR chunk has a valid length. */
+	if (!sctp_chunk_length_valid(chunk, sizeof(sctp_operr_chunk_t)))
+		return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+						  commands);
+
 	while (chunk->chunk_end > chunk->skb->data) {
 		ev = sctp_ulpevent_make_remote_error(asoc, chunk, 0,
 						     GFP_ATOMIC);
@@ -2744,6 +2980,11 @@
 	if (!sctp_vtag_verify(chunk, asoc))
 		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 
+	/* Make sure that the SHUTDOWN_ACK chunk has a valid length. */
+	if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t)))
+		return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+						  commands);
+
 	/* 10.2 H) SHUTDOWN COMPLETE notification
 	 *
 	 * When SCTP completes the shutdown procedures (section 9.2) this
@@ -2818,11 +3059,23 @@
 
 	ch = (sctp_chunkhdr_t *) chunk->chunk_hdr;
 	do {
+		/* Break out if chunk length is less then minimal. */
+		if (ntohs(ch->length) < sizeof(sctp_chunkhdr_t))
+			break;
+
 		ch_end = ((__u8 *)ch) + WORD_ROUND(ntohs(ch->length));
 
 		if (SCTP_CID_SHUTDOWN_ACK == ch->type)
 			ootb_shut_ack = 1;
 
+		/* RFC 2960, Section 3.3.7
+		 *   Moreover, under any circumstances, an endpoint that
+		 *   receives an ABORT  MUST NOT respond to that ABORT by
+		 *   sending an ABORT of its own.
+		 */
+		if (SCTP_CID_ABORT == ch->type)
+			return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+			
 		ch = (sctp_chunkhdr_t *) ch_end;
 	} while (ch_end < skb->tail);
 
@@ -2853,11 +3106,11 @@
  *
  * The return value is the disposition of the chunk.
  */
-sctp_disposition_t sctp_sf_shut_8_4_5(const struct sctp_endpoint *ep,
-				      const struct sctp_association *asoc,
-				      const sctp_subtype_t type,
-				      void *arg,
-				      sctp_cmd_seq_t *commands)
+static sctp_disposition_t sctp_sf_shut_8_4_5(const struct sctp_endpoint *ep,
+					     const struct sctp_association *asoc,
+					     const sctp_subtype_t type,
+					     void *arg,
+					     sctp_cmd_seq_t *commands)
 {
 	struct sctp_packet *packet = NULL;
 	struct sctp_chunk *chunk = arg;
@@ -2885,6 +3138,12 @@
 
 		SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS);
 
+		/* If the chunk length is invalid, we don't want to process
+		 * the reset of the packet.
+		 */
+		if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t)))
+			return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+
 		return SCTP_DISPOSITION_CONSUME;
 	}
 
@@ -2927,6 +3186,17 @@
 	sctp_addiphdr_t		*hdr;
 	__u32			serial;
 
+	if (!sctp_vtag_verify(chunk, asoc)) {
+		sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG,
+				SCTP_NULL());
+		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+	}
+
+	/* Make sure that the ASCONF ADDIP chunk has a valid length.  */
+	if (!sctp_chunk_length_valid(chunk, sizeof(sctp_addip_chunk_t)))
+		return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+						  commands);
+
 	hdr = (sctp_addiphdr_t *)chunk->skb->data;
 	serial = ntohl(hdr->serial);
 
@@ -2947,7 +3217,8 @@
 		/* ADDIP 4.2 C3) If the value found in the serial number is
 		 * equal to the value stored in the 'Peer-Serial-Number'
 		 * IMPLEMENTATION NOTE: As an optimization a receiver may wish
-		 * to save the last ASCONF-ACK for some predetermined period of 		 * time and instead of re-processing the ASCONF (with the same
+		 * to save the last ASCONF-ACK for some predetermined period of
+		 * time and instead of re-processing the ASCONF (with the same
 		 * serial number) it may just re-transmit the ASCONF-ACK.
 		 */
 		if (asoc->addip_last_asconf_ack)
@@ -2986,6 +3257,17 @@
 	sctp_addiphdr_t		*addip_hdr;
 	__u32			sent_serial, rcvd_serial;
 
+	if (!sctp_vtag_verify(asconf_ack, asoc)) {
+		sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG,
+				SCTP_NULL());
+		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+	}
+
+	/* Make sure that the ADDIP chunk has a valid length.  */
+	if (!sctp_chunk_length_valid(asconf_ack, sizeof(sctp_addip_chunk_t)))
+		return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+						  commands);
+
 	addip_hdr = (sctp_addiphdr_t *)asconf_ack->skb->data;
 	rcvd_serial = ntohl(addip_hdr->serial);
 
@@ -3084,6 +3366,11 @@
 		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 	}
 
+	/* Make sure that the FORWARD_TSN chunk has valid length.  */
+	if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_fwdtsn_chunk)))
+		return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+						  commands);
+
 	fwdtsn_hdr = (struct sctp_fwdtsn_hdr *)chunk->skb->data;
 	chunk->subh.fwdtsn_hdr = fwdtsn_hdr;
 	len = ntohs(chunk->chunk_hdr->length);
@@ -3142,6 +3429,11 @@
 		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 	}
 
+	/* Make sure that the FORWARD_TSN chunk has a valid length.  */
+	if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_fwdtsn_chunk)))
+		return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+						  commands);
+
 	fwdtsn_hdr = (struct sctp_fwdtsn_hdr *)chunk->skb->data;
 	chunk->subh.fwdtsn_hdr = fwdtsn_hdr;
 	len = ntohs(chunk->chunk_hdr->length);
@@ -3216,6 +3508,14 @@
 	if (!sctp_vtag_verify(unk_chunk, asoc))
 		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 
+	/* Make sure that the chunk has a valid length.
+	 * Since we don't know the chunk type, we use a general
+	 * chunkhdr structure to make a comparison.
+	 */
+	if (!sctp_chunk_length_valid(unk_chunk, sizeof(sctp_chunkhdr_t)))
+		return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+						  commands);
+
 	switch (type.chunk & SCTP_CID_ACTION_MASK) {
 	case SCTP_CID_ACTION_DISCARD:
 		/* Discard the packet.  */
@@ -3338,6 +3638,66 @@
 	return SCTP_DISPOSITION_VIOLATION;
 }
 
+
+/*
+ * Handle a protocol violation when the chunk length is invalid.
+ * "Invalid" length is identified as smaller then the minimal length a
+ * given chunk can be.  For example, a SACK chunk has invalid length
+ * if it's length is set to be smaller then the size of sctp_sack_chunk_t.
+ *
+ * We inform the other end by sending an ABORT with a Protocol Violation
+ * error code. 
+ *
+ * Section: Not specified
+ * Verification Tag:  Nothing to do
+ * Inputs
+ * (endpoint, asoc, chunk)
+ *
+ * Outputs
+ * (reply_msg, msg_up, counters)
+ *
+ * Generate an  ABORT chunk and terminate the association.
+ */
+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)
+{
+	struct sctp_chunk *chunk =  arg;
+	struct sctp_chunk *abort = NULL;
+	char 		   err_str[]="The following chunk had invalid length:";
+
+	/* Make the abort chunk. */
+	abort = sctp_make_abort_violation(asoc, chunk, err_str,
+					  sizeof(err_str));
+	if (!abort)
+		goto nomem;
+
+	sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort));
+	SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS);
+
+	if (asoc->state <= SCTP_STATE_COOKIE_ECHOED) {
+		sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
+				SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT));
+		sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED,
+				SCTP_U32(SCTP_ERROR_PROTO_VIOLATION));
+	} else {
+		sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
+				SCTP_U32(SCTP_ERROR_PROTO_VIOLATION));
+		SCTP_DEC_STATS(SCTP_MIB_CURRESTAB);
+	}
+
+	sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET, SCTP_NULL());
+
+	SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
+	
+	return SCTP_DISPOSITION_ABORT;
+
+nomem:
+	return SCTP_DISPOSITION_NOMEM;
+}
+
 /***************************************************************************
  * These are the state functions for handling primitive (Section 10) events.
  ***************************************************************************/
@@ -4050,6 +4410,23 @@
 	struct sctp_chunk *chunk = (struct sctp_chunk *) arg;
 	struct sctp_chunk *reply;
 
+	/* There are 2 ways of getting here:
+	 *    1) called in response to a SHUTDOWN chunk
+	 *    2) called when SCTP_EVENT_NO_PENDING_TSN event is issued.
+	 *
+	 * For the case (2), the arg parameter is set to NULL.  We need
+	 * to check that we have a chunk before accessing it's fields.
+	 */
+	if (chunk) {
+		if (!sctp_vtag_verify(chunk, asoc))
+			return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+
+		/* Make sure that the SHUTDOWN chunk has a valid length. */
+		if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_shutdown_chunk_t)))
+			return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+							  commands);
+	}
+
 	/* If it has no more outstanding DATA chunks, the SHUTDOWN receiver
 	 * shall send a SHUTDOWN ACK ...
 	 */
@@ -4537,7 +4914,7 @@
  ********************************************************************/
 
 /* Pull the SACK chunk based on the SACK header. */
-struct sctp_sackhdr *sctp_sm_pull_sack(struct sctp_chunk *chunk)
+static struct sctp_sackhdr *sctp_sm_pull_sack(struct sctp_chunk *chunk)
 {
 	struct sctp_sackhdr *sack;
 	unsigned int len;
@@ -4564,7 +4941,7 @@
 /* Create an ABORT packet to be sent as a response, with the specified
  * error causes.
  */
-struct sctp_packet *sctp_abort_pkt_new(const struct sctp_endpoint *ep,
+static struct sctp_packet *sctp_abort_pkt_new(const struct sctp_endpoint *ep,
 				  const struct sctp_association *asoc,
 				  struct sctp_chunk *chunk,
 				  const void *payload,
@@ -4600,8 +4977,8 @@
 }
 
 /* Allocate a packet for responding in the OOTB conditions.  */
-struct sctp_packet *sctp_ootb_pkt_new(const struct sctp_association *asoc,
-				 const struct sctp_chunk *chunk)
+static struct sctp_packet *sctp_ootb_pkt_new(const struct sctp_association *asoc,
+					     const struct sctp_chunk *chunk)
 {
 	struct sctp_packet *packet;
 	struct sctp_transport *transport;
@@ -4664,11 +5041,11 @@
 }
 
 /* Send a stale cookie error when a invalid COOKIE ECHO chunk is found  */
-void sctp_send_stale_cookie_err(const struct sctp_endpoint *ep,
-				const struct sctp_association *asoc,
-				const struct sctp_chunk *chunk,
-				sctp_cmd_seq_t *commands,
-				struct sctp_chunk *err_chunk)
+static void sctp_send_stale_cookie_err(const struct sctp_endpoint *ep,
+				       const struct sctp_association *asoc,
+				       const struct sctp_chunk *chunk,
+				       sctp_cmd_seq_t *commands,
+				       struct sctp_chunk *err_chunk)
 {
 	struct sctp_packet *packet;
 
@@ -4694,9 +5071,9 @@
 
 
 /* Process a data chunk */
-int sctp_eat_data(const struct sctp_association *asoc,
-		  struct sctp_chunk *chunk,
-		  sctp_cmd_seq_t *commands)
+static int sctp_eat_data(const struct sctp_association *asoc,
+			 struct sctp_chunk *chunk,
+			 sctp_cmd_seq_t *commands)
 {
 	sctp_datahdr_t *data_hdr;
 	struct sctp_chunk *err;
diff -Nru a/net/sctp/sm_statetable.c b/net/sctp/sm_statetable.c
--- a/net/sctp/sm_statetable.c	2005-03-01 23:39:17 -08:00
+++ b/net/sctp/sm_statetable.c	2005-03-01 23:39:17 -08:00
@@ -50,6 +50,17 @@
 #include <net/sctp/sctp.h>
 #include <net/sctp/sm.h>
 
+static const sctp_sm_table_entry_t
+primitive_event_table[SCTP_NUM_PRIMITIVE_TYPES][SCTP_STATE_NUM_STATES];
+static const sctp_sm_table_entry_t
+other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_STATE_NUM_STATES];
+static const sctp_sm_table_entry_t
+timeout_event_table[SCTP_NUM_TIMEOUT_TYPES][SCTP_STATE_NUM_STATES];
+
+static const sctp_sm_table_entry_t *sctp_chunk_event_lookup(sctp_cid_t cid,
+							    sctp_state_t state);
+
+
 static const sctp_sm_table_entry_t bug = {
 	.fn = sctp_sf_bug,
 	.name = "sctp_sf_bug"
@@ -419,7 +430,7 @@
  *
  * For base protocol (RFC 2960).
  */
-const sctp_sm_table_entry_t chunk_event_table[SCTP_NUM_BASE_CHUNK_TYPES][SCTP_STATE_NUM_STATES] = {
+static const sctp_sm_table_entry_t chunk_event_table[SCTP_NUM_BASE_CHUNK_TYPES][SCTP_STATE_NUM_STATES] = {
 	TYPE_SCTP_DATA,
 	TYPE_SCTP_INIT,
 	TYPE_SCTP_INIT_ACK,
@@ -482,7 +493,7 @@
 /* The primary index for this table is the chunk type.
  * The secondary index for this table is the state.
  */
-const sctp_sm_table_entry_t addip_chunk_event_table[SCTP_NUM_ADDIP_CHUNK_TYPES][SCTP_STATE_NUM_STATES] = {
+static const sctp_sm_table_entry_t addip_chunk_event_table[SCTP_NUM_ADDIP_CHUNK_TYPES][SCTP_STATE_NUM_STATES] = {
 	TYPE_SCTP_ASCONF,
 	TYPE_SCTP_ASCONF_ACK,
 }; /*state_fn_t addip_chunk_event_table[][] */
@@ -511,7 +522,7 @@
 /* The primary index for this table is the chunk type.
  * The secondary index for this table is the state.
  */
-const sctp_sm_table_entry_t prsctp_chunk_event_table[SCTP_NUM_PRSCTP_CHUNK_TYPES][SCTP_STATE_NUM_STATES] = {
+static const sctp_sm_table_entry_t prsctp_chunk_event_table[SCTP_NUM_PRSCTP_CHUNK_TYPES][SCTP_STATE_NUM_STATES] = {
 	TYPE_SCTP_FWD_TSN,
 }; /*state_fn_t prsctp_chunk_event_table[][] */
 
@@ -684,7 +695,7 @@
 /* The primary index for this table is the primitive type.
  * The secondary index for this table is the state.
  */
-const sctp_sm_table_entry_t primitive_event_table[SCTP_NUM_PRIMITIVE_TYPES][SCTP_STATE_NUM_STATES] = {
+static const sctp_sm_table_entry_t primitive_event_table[SCTP_NUM_PRIMITIVE_TYPES][SCTP_STATE_NUM_STATES] = {
 	TYPE_SCTP_PRIMITIVE_ASSOCIATE,
 	TYPE_SCTP_PRIMITIVE_SHUTDOWN,
 	TYPE_SCTP_PRIMITIVE_ABORT,
@@ -716,8 +727,31 @@
 	{.fn = sctp_sf_ignore_other, .name = "sctp_sf_ignore_other"}, \
 }
 
-const sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_STATE_NUM_STATES] = {
+#define TYPE_SCTP_OTHER_ICMP_PROTO_UNREACH  { \
+	/* SCTP_STATE_EMPTY */ \
+	{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
+	/* SCTP_STATE_CLOSED */ \
+	{.fn = sctp_sf_ignore_other, .name = "sctp_sf_ignore_other"}, \
+	/* SCTP_STATE_COOKIE_WAIT */ \
+	{.fn = sctp_sf_cookie_wait_icmp_abort, \
+	 .name = "sctp_sf_cookie_wait_icmp_abort"}, \
+	/* SCTP_STATE_COOKIE_ECHOED */ \
+	{.fn = sctp_sf_ignore_other, .name = "sctp_sf_ignore_other"}, \
+	/* SCTP_STATE_ESTABLISHED */ \
+	{.fn = sctp_sf_ignore_other, .name = "sctp_sf_ignore_other"}, \
+	/* SCTP_STATE_SHUTDOWN_PENDING */ \
+	{.fn = sctp_sf_ignore_other, .name = "sctp_sf_ignore_other"}, \
+	/* SCTP_STATE_SHUTDOWN_SENT */ \
+	{.fn = sctp_sf_ignore_other, .name = "sctp_sf_ignore_other"}, \
+	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
+	{.fn = sctp_sf_ignore_other, .name = "sctp_sf_ignore_other"}, \
+	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
+	{.fn = sctp_sf_ignore_other, .name = "sctp_sf_ignore_other"}, \
+}
+
+static const sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_STATE_NUM_STATES] = {
 	TYPE_SCTP_OTHER_NO_PENDING_TSN,
+	TYPE_SCTP_OTHER_ICMP_PROTO_UNREACH,
 };
 
 #define TYPE_SCTP_EVENT_TIMEOUT_NONE { \
@@ -931,7 +965,7 @@
 	{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
 }
 
-const sctp_sm_table_entry_t timeout_event_table[SCTP_NUM_TIMEOUT_TYPES][SCTP_STATE_NUM_STATES] = {
+static const sctp_sm_table_entry_t timeout_event_table[SCTP_NUM_TIMEOUT_TYPES][SCTP_STATE_NUM_STATES] = {
 	TYPE_SCTP_EVENT_TIMEOUT_NONE,
 	TYPE_SCTP_EVENT_TIMEOUT_T1_COOKIE,
 	TYPE_SCTP_EVENT_TIMEOUT_T1_INIT,
@@ -944,8 +978,8 @@
 	TYPE_SCTP_EVENT_TIMEOUT_AUTOCLOSE,
 };
 
-const sctp_sm_table_entry_t *sctp_chunk_event_lookup(sctp_cid_t cid, 
-						     sctp_state_t state)
+static const sctp_sm_table_entry_t *sctp_chunk_event_lookup(sctp_cid_t cid, 
+							    sctp_state_t state)
 {
 	if (state > SCTP_STATE_MAX)
 		return &bug;
diff -Nru a/net/sctp/socket.c b/net/sctp/socket.c
--- a/net/sctp/socket.c	2005-03-01 23:39:18 -08:00
+++ b/net/sctp/socket.c	2005-03-01 23:39:18 -08:00
@@ -93,7 +93,7 @@
 static int sctp_wait_for_connect(struct sctp_association *, long *timeo_p);
 static int sctp_wait_for_accept(struct sock *sk, long timeo);
 static void sctp_wait_for_close(struct sock *sk, long timeo);
-static struct sctp_af *sctp_sockaddr_af(struct sctp_opt *opt,
+static struct sctp_af *sctp_sockaddr_af(struct sctp_sock *opt,
 					union sctp_addr *addr, int len);
 static int sctp_bindx_add(struct sock *, struct sockaddr *, int);
 static int sctp_bindx_rem(struct sock *, struct sockaddr *, int);
@@ -208,7 +208,7 @@
  * id are specified, the associations matching the address and the id should be
  * the same.
  */
-struct sctp_transport *sctp_addr_id2transport(struct sock *sk,
+static struct sctp_transport *sctp_addr_id2transport(struct sock *sk,
 					      struct sockaddr_storage *addr,
 					      sctp_assoc_t id)
 {
@@ -245,7 +245,7 @@
  *             sockaddr_in6 [RFC 2553]),
  *   addr_len - the size of the address structure.
  */
-int sctp_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
+SCTP_STATIC int sctp_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
 {
 	int retval = 0;
 
@@ -269,7 +269,7 @@
 static long sctp_get_port_local(struct sock *, union sctp_addr *);
 
 /* Verify this is a valid sockaddr. */
-static struct sctp_af *sctp_sockaddr_af(struct sctp_opt *opt,
+static struct sctp_af *sctp_sockaddr_af(struct sctp_sock *opt,
 					union sctp_addr *addr, int len)
 {
 	struct sctp_af *af;
@@ -294,7 +294,7 @@
 /* Bind a local address either to an endpoint or to an association.  */
 SCTP_STATIC int sctp_do_bind(struct sock *sk, union sctp_addr *addr, int len)
 {
-	struct sctp_opt *sp = sctp_sk(sk);
+	struct sctp_sock *sp = sctp_sk(sk);
 	struct sctp_endpoint *ep = sp->ep;
 	struct sctp_bind_addr *bp = &ep->base.bind_addr;
 	struct sctp_af *af;
@@ -343,8 +343,8 @@
 	}
 
 	/* Refresh ephemeral port.  */
-	if (!snum)
-		snum = inet_sk(sk)->num;
+	if (!bp->port)
+		bp->port = inet_sk(sk)->num;
 
 	/* Add the address to the bind address list.  */
 	sctp_local_bh_disable();
@@ -354,8 +354,6 @@
 	addr->v4.sin_port = ntohs(addr->v4.sin_port);
 	ret = sctp_add_bind_addr(bp, addr, GFP_ATOMIC);
 	addr->v4.sin_port = htons(addr->v4.sin_port);
-	if (!ret && !bp->port)
-		bp->port = snum;
 	sctp_write_unlock(&ep->base.addr_lock);
 	sctp_local_bh_enable();
 
@@ -469,7 +467,7 @@
 				   struct sockaddr	*addrs,
 				   int 			addrcnt)
 {
-	struct sctp_opt			*sp;
+	struct sctp_sock		*sp;
 	struct sctp_endpoint		*ep;
 	struct sctp_association		*asoc;
 	struct sctp_bind_addr		*bp;
@@ -574,7 +572,7 @@
  */
 int sctp_bindx_rem(struct sock *sk, struct sockaddr *addrs, int addrcnt)
 {
-	struct sctp_opt *sp = sctp_sk(sk);
+	struct sctp_sock *sp = sctp_sk(sk);
 	struct sctp_endpoint *ep = sp->ep;
 	int cnt;
 	struct sctp_bind_addr *bp = &ep->base.bind_addr;
@@ -658,7 +656,7 @@
 				   struct sockaddr	*addrs,
 				   int			addrcnt)
 {
-	struct sctp_opt		*sp;
+	struct sctp_sock	*sp;
 	struct sctp_endpoint	*ep;
 	struct sctp_association	*asoc;
 	struct sctp_bind_addr	*bp;
@@ -1053,7 +1051,7 @@
 SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
 			     struct msghdr *msg, size_t msg_len)
 {
-	struct sctp_opt *sp;
+	struct sctp_sock *sp;
 	struct sctp_endpoint *ep;
 	struct sctp_association *new_asoc=NULL, *asoc=NULL;
 	struct sctp_transport *transport, *chunk_tp;
@@ -1494,7 +1492,7 @@
 			     int flags, int *addr_len)
 {
 	struct sctp_ulpevent *event = NULL;
-	struct sctp_opt *sp = sctp_sk(sk);
+	struct sctp_sock *sp = sctp_sk(sk);
 	struct sk_buff *skb;
 	int copied;
 	int err = 0;
@@ -1639,7 +1637,7 @@
 static int sctp_setsockopt_autoclose(struct sock *sk, char __user *optval,
 					    int optlen)
 {
-	struct sctp_opt *sp = sctp_sk(sk);
+	struct sctp_sock *sp = sctp_sk(sk);
 
 	/* Applicable to UDP-style socket only */
 	if (sctp_style(sk, TCP))
@@ -1713,10 +1711,13 @@
 	/* update default value for endpoint (all future associations) */
 	if (!params.spp_assoc_id && 
 	    sctp_is_any(( union sctp_addr *)&params.spp_address)) {
-		if (params.spp_hbinterval)
+		/* Manual heartbeat on an endpoint is invalid. */
+		if (0xffffffff == params.spp_hbinterval)
+			return -EINVAL;
+		else if (params.spp_hbinterval)
 			sctp_sk(sk)->paddrparam.spp_hbinterval =
 						params.spp_hbinterval;
-		if (sctp_max_retrans_path)
+		if (params.spp_pathmaxrxt)
 			sctp_sk(sk)->paddrparam.spp_pathmaxrxt =
 						params.spp_pathmaxrxt;
 		return 0;
@@ -1758,7 +1759,8 @@
 	/* spp_pathmaxrxt contains the maximum number of retransmissions
 	 * before this address shall be considered unreachable.
 	 */
-	trans->error_threshold = params.spp_pathmaxrxt;
+	if (params.spp_pathmaxrxt)
+		trans->max_retrans = params.spp_pathmaxrxt;
 
 	return 0;
 }
@@ -1777,7 +1779,7 @@
 static int sctp_setsockopt_initmsg(struct sock *sk, char __user *optval, int optlen)
 {
 	struct sctp_initmsg sinit;
-	struct sctp_opt *sp = sctp_sk(sk);
+	struct sctp_sock *sp = sctp_sk(sk);
 
 	if (optlen != sizeof(struct sctp_initmsg))
 		return -EINVAL;
@@ -1815,7 +1817,7 @@
 {
 	struct sctp_sndrcvinfo info;
 	struct sctp_association *asoc;
-	struct sctp_opt *sp = sctp_sk(sk);
+	struct sctp_sock *sp = sctp_sk(sk);
 
 	if (optlen != sizeof(struct sctp_sndrcvinfo))
 		return -EINVAL;
@@ -1932,7 +1934,7 @@
 		/* If there is no association or the association-id = 0
 		 * set the values to the endpoint.
 		 */
-		struct sctp_opt *sp = sctp_sk(sk);
+		struct sctp_sock *sp = sctp_sk(sk);
 
 		if (rtoinfo.srto_initial != 0)
 			sp->rtoinfo.srto_initial = rtoinfo.srto_initial;
@@ -1985,7 +1987,7 @@
 		}
 	} else {
 		/* Set the values to the endpoint */
-		struct sctp_opt *sp = sctp_sk(sk);
+		struct sctp_sock *sp = sctp_sk(sk);
 
 		if (assocparams.sasoc_asocmaxrxt != 0)
 			sp->assocparams.sasoc_asocmaxrxt =
@@ -2010,7 +2012,7 @@
 static int sctp_setsockopt_mappedv4(struct sock *sk, char __user *optval, int optlen)
 {
 	int val;
-	struct sctp_opt *sp = sctp_sk(sk);
+	struct sctp_sock *sp = sctp_sk(sk);
 
 	if (optlen < sizeof(int))
 		return -EINVAL;
@@ -2038,7 +2040,7 @@
 {
 	struct sctp_association *asoc;
 	struct list_head *pos;
-	struct sctp_opt *sp = sctp_sk(sk);
+	struct sctp_sock *sp = sctp_sk(sk);
 	int val;
 
 	if (optlen < sizeof(int))
@@ -2072,7 +2074,7 @@
 static int sctp_setsockopt_peer_primary_addr(struct sock *sk, char __user *optval,
 					     int optlen)
 {
-	struct sctp_opt		*sp;
+	struct sctp_sock	*sp;
 	struct sctp_endpoint	*ep;
 	struct sctp_association	*asoc = NULL;
 	struct sctp_setpeerprim	prim;
@@ -2267,7 +2269,7 @@
 SCTP_STATIC int sctp_connect(struct sock *sk, struct sockaddr *uaddr,
 			     int addr_len)
 {
-	struct sctp_opt *sp;
+	struct sctp_sock *sp;
 	struct sctp_endpoint *ep;
 	struct sctp_association *asoc;
 	struct sctp_transport *transport;
@@ -2388,7 +2390,7 @@
  */
 SCTP_STATIC struct sock *sctp_accept(struct sock *sk, int flags, int *err)
 {
-	struct sctp_opt *sp;
+	struct sctp_sock *sp;
 	struct sctp_endpoint *ep;
 	struct sock *newsk = NULL;
 	struct sctp_association *asoc;
@@ -2451,7 +2453,7 @@
 SCTP_STATIC int sctp_init_sock(struct sock *sk)
 {
 	struct sctp_endpoint *ep;
-	struct sctp_opt *sp;
+	struct sctp_sock *sp;
 
 	SCTP_DEBUG_PRINTK("sctp_init_sock(sk: %p)\n", sk);
 
@@ -2937,7 +2939,7 @@
 	/* spp_pathmaxrxt contains the maximum number of retransmissions
 	 * before this address shall be considered unreachable.
 	 */
-	params.spp_pathmaxrxt = trans->error_threshold;
+	params.spp_pathmaxrxt = trans->max_retrans;
 
 done:
 	if (copy_to_user(optval, &params, len))
@@ -3005,7 +3007,7 @@
 	struct sctp_transport *from;
 	void __user *to;
 	union sctp_addr temp;
-	struct sctp_opt *sp = sctp_sk(sk);
+	struct sctp_sock *sp = sctp_sk(sk);
 	int addrlen;
 
 	if (len != sizeof(struct sctp_getaddrs))
@@ -3049,6 +3051,9 @@
 	struct sctp_bind_addr *bp;
 	struct sctp_association *asoc;
 	struct list_head *pos;
+	struct sctp_sockaddr_entry *addr;
+	rwlock_t *addr_lock;
+	unsigned long flags;
 	int cnt = 0;
 
 	if (len != sizeof(sctp_assoc_t))
@@ -3065,33 +3070,104 @@
 	 */
 	if (0 == id) {
 		bp = &sctp_sk(sk)->ep->base.bind_addr;
+		addr_lock = &sctp_sk(sk)->ep->base.addr_lock;
 	} else {
 		asoc = sctp_id2assoc(sk, id);
 		if (!asoc)
 			return -EINVAL;
 		bp = &asoc->base.bind_addr;
+		addr_lock = &asoc->base.addr_lock;
+	}
+
+	sctp_read_lock(addr_lock);
+
+	/* If the endpoint is bound to 0.0.0.0 or ::0, count the valid
+	 * addresses from the global local address list.
+	 */
+	if (sctp_list_single_entry(&bp->address_list)) {
+		addr = list_entry(bp->address_list.next,
+				  struct sctp_sockaddr_entry, list);
+		if (sctp_is_any(&addr->a)) {
+			sctp_spin_lock_irqsave(&sctp_local_addr_lock, flags);
+			list_for_each(pos, &sctp_local_addr_list) {
+				addr = list_entry(pos,
+						  struct sctp_sockaddr_entry,
+						  list);
+				if ((PF_INET == sk->sk_family) && 
+				    (AF_INET6 == addr->a.sa.sa_family))	
+					continue;
+				cnt++;
+			}
+			sctp_spin_unlock_irqrestore(&sctp_local_addr_lock,
+						    flags);
+		} else {
+			cnt = 1;
+		}
+		goto done;
 	}
 
 	list_for_each(pos, &bp->address_list) {
 		cnt ++;
 	}
 
+done:
+	sctp_read_unlock(addr_lock);
+	return cnt;
+}
+
+/* Helper function that copies local addresses to user and returns the number
+ * of addresses copied.
+ */
+static int sctp_copy_laddrs_to_user(struct sock *sk, __u16 port, int max_addrs,
+				    void __user *to)
+{
+	struct list_head *pos;
+	struct sctp_sockaddr_entry *addr;
+	unsigned long flags;
+	union sctp_addr temp;
+	int cnt = 0;
+	int addrlen;
+
+	sctp_spin_lock_irqsave(&sctp_local_addr_lock, flags);
+	list_for_each(pos, &sctp_local_addr_list) {
+		addr = list_entry(pos, struct sctp_sockaddr_entry, list);
+		if ((PF_INET == sk->sk_family) && 
+		    (AF_INET6 == addr->a.sa.sa_family))
+			continue;
+		memcpy(&temp, &addr->a, sizeof(temp));
+		sctp_get_pf_specific(sk->sk_family)->addr_v4map(sctp_sk(sk),
+								&temp);
+		addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len;
+		temp.v4.sin_port = htons(port);
+		if (copy_to_user(to, &temp, addrlen)) {
+			sctp_spin_unlock_irqrestore(&sctp_local_addr_lock,
+						    flags);
+			return -EFAULT;
+		}
+		to += addrlen;
+		cnt ++;
+		if (cnt >= max_addrs) break;
+	}
+	sctp_spin_unlock_irqrestore(&sctp_local_addr_lock, flags);
+
 	return cnt;
 }
 
 static int sctp_getsockopt_local_addrs(struct sock *sk, int len,
-					char __user *optval, int __user *optlen)
+				       char __user *optval, int __user *optlen)
 {
 	struct sctp_bind_addr *bp;
 	struct sctp_association *asoc;
 	struct list_head *pos;
 	int cnt = 0;
 	struct sctp_getaddrs getaddrs;
-	struct sctp_sockaddr_entry *from;
+	struct sctp_sockaddr_entry *addr;
 	void __user *to;
 	union sctp_addr temp;
-	struct sctp_opt *sp = sctp_sk(sk);
+	struct sctp_sock *sp = sctp_sk(sk);
 	int addrlen;
+	rwlock_t *addr_lock;
+	int err = 0;
 
 	if (len != sizeof(struct sctp_getaddrs))
 		return -EINVAL;
@@ -3108,33 +3184,59 @@
 	 */
 	if (0 == getaddrs.assoc_id) {
 		bp = &sctp_sk(sk)->ep->base.bind_addr;
+		addr_lock = &sctp_sk(sk)->ep->base.addr_lock;
 	} else {
 		asoc = sctp_id2assoc(sk, getaddrs.assoc_id);
 		if (!asoc)
 			return -EINVAL;
 		bp = &asoc->base.bind_addr;
+		addr_lock = &asoc->base.addr_lock;
 	}
 
 	to = getaddrs.addrs;
+
+	sctp_read_lock(addr_lock);
+
+	/* If the endpoint is bound to 0.0.0.0 or ::0, get the valid
+	 * addresses from the global local address list.
+	 */
+	if (sctp_list_single_entry(&bp->address_list)) {
+		addr = list_entry(bp->address_list.next,
+				  struct sctp_sockaddr_entry, list);
+		if (sctp_is_any(&addr->a)) {
+			cnt = sctp_copy_laddrs_to_user(sk, bp->port,
+						       getaddrs.addr_num, to);
+			if (cnt < 0) {
+				err = cnt;
+				goto unlock;
+			}
+			goto copy_getaddrs;		
+		}
+	}
+
 	list_for_each(pos, &bp->address_list) {
-		from = list_entry(pos,
-				struct sctp_sockaddr_entry,
-				list);
-		memcpy(&temp, &from->a, sizeof(temp));
+		addr = list_entry(pos, struct sctp_sockaddr_entry, list);
+		memcpy(&temp, &addr->a, sizeof(temp));
 		sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, &temp);
 		addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len;
 		temp.v4.sin_port = htons(temp.v4.sin_port);
-		if (copy_to_user(to, &temp, addrlen))
-			return -EFAULT;
+		if (copy_to_user(to, &temp, addrlen)) {
+			err = -EFAULT;
+			goto unlock;
+		}
 		to += addrlen;
 		cnt ++;
 		if (cnt >= getaddrs.addr_num) break;
 	}
+
+copy_getaddrs:
 	getaddrs.addr_num = cnt;
 	if (copy_to_user(optval, &getaddrs, sizeof(struct sctp_getaddrs)))
-		return -EFAULT;
+		err = -EFAULT;
 
-	return 0;
+unlock:
+	sctp_read_unlock(addr_lock);
+	return err;
 }
 
 /* 7.1.10 Set Primary Address (SCTP_PRIMARY_ADDR)
@@ -3148,7 +3250,7 @@
 {
 	struct sctp_prim prim;
 	struct sctp_association *asoc;
-	struct sctp_opt *sp = sctp_sk(sk);
+	struct sctp_sock *sp = sctp_sk(sk);
 
 	if (len != sizeof(struct sctp_prim))
 		return -EINVAL;
@@ -3227,7 +3329,7 @@
 {
 	struct sctp_sndrcvinfo info;
 	struct sctp_association *asoc;
-	struct sctp_opt *sp = sctp_sk(sk);
+	struct sctp_sock *sp = sctp_sk(sk);
 
 	if (len != sizeof(struct sctp_sndrcvinfo))
 		return -EINVAL;
@@ -3321,7 +3423,7 @@
 		rtoinfo.srto_min = jiffies_to_msecs(asoc->rto_min);
 	} else {
 		/* Values corresponding to the endpoint. */
-		struct sctp_opt *sp = sctp_sk(sk);
+		struct sctp_sock *sp = sctp_sk(sk);
 
 		rtoinfo.srto_initial = sp->rtoinfo.srto_initial;
 		rtoinfo.srto_max = sp->rtoinfo.srto_max;
@@ -3387,7 +3489,7 @@
 		assocparams.sasoc_number_peer_destinations = cnt;
 	} else {
 		/* Values corresponding to the endpoint */
-		struct sctp_opt *sp = sctp_sk(sk);
+		struct sctp_sock *sp = sctp_sk(sk);
 
 		assocparams.sasoc_asocmaxrxt = sp->assocparams.sasoc_asocmaxrxt;
 		assocparams.sasoc_peer_rwnd = sp->assocparams.sasoc_peer_rwnd;
@@ -3422,7 +3524,7 @@
 				    char __user *optval, int __user *optlen)
 {
 	int val;
-	struct sctp_opt *sp = sctp_sk(sk);
+	struct sctp_sock *sp = sctp_sk(sk);
 
 	if (len < sizeof(int))
 		return -EINVAL;
@@ -3774,7 +3876,7 @@
  */
 SCTP_STATIC int sctp_seqpacket_listen(struct sock *sk, int backlog)
 {
-	struct sctp_opt *sp = sctp_sk(sk);
+	struct sctp_sock *sp = sctp_sk(sk);
 	struct sctp_endpoint *ep = sp->ep;
 
 	/* Only UDP style sockets that are not peeled off are allowed to
@@ -3823,7 +3925,7 @@
  */
 SCTP_STATIC int sctp_stream_listen(struct sock *sk, int backlog)
 {
-	struct sctp_opt *sp = sctp_sk(sk);
+	struct sctp_sock *sp = sctp_sk(sk);
 	struct sctp_endpoint *ep = sp->ep;
 
 	/* If backlog is zero, disable listening. */
@@ -3924,7 +4026,7 @@
 unsigned int sctp_poll(struct file *file, struct socket *sock, poll_table *wait)
 {
 	struct sock *sk = sock->sk;
-	struct sctp_opt *sp = sctp_sk(sk);
+	struct sctp_sock *sp = sctp_sk(sk);
 	unsigned int mask;
 
 	poll_wait(file, sk->sk_sleep, wait);
@@ -4552,8 +4654,8 @@
 			      struct sctp_association *assoc,
 			      sctp_socket_type_t type)
 {
-	struct sctp_opt *oldsp = sctp_sk(oldsk);
-	struct sctp_opt *newsp = sctp_sk(newsk);
+	struct sctp_sock *oldsp = sctp_sk(oldsk);
+	struct sctp_sock *newsp = sctp_sk(newsk);
 	struct sctp_bind_bucket *pp; /* hash list port iterator */
 	struct sctp_endpoint *newep = newsp->ep;
 	struct sk_buff *skb, *tmp;
@@ -4565,7 +4667,7 @@
 	newsk->sk_sndbuf = oldsk->sk_sndbuf;
 	newsk->sk_rcvbuf = oldsk->sk_rcvbuf;
 	/* Brute force copy old sctp opt. */
-	memcpy(newsp, oldsp, sizeof(struct sctp_opt));
+	inet_sk_copy_descendant(newsk, oldsk);
 
 	/* Restore the ep value that was overwritten with the above structure
 	 * copy.
diff -Nru a/net/sctp/ssnmap.c b/net/sctp/ssnmap.c
--- a/net/sctp/ssnmap.c	2005-03-01 23:39:09 -08:00
+++ b/net/sctp/ssnmap.c	2005-03-01 23:39:09 -08:00
@@ -42,6 +42,9 @@
 
 #define MAX_KMALLOC_SIZE	131072
 
+static struct sctp_ssnmap *sctp_ssnmap_init(struct sctp_ssnmap *map, __u16 in,
+					    __u16 out);
+
 /* Storage size needed for map includes 2 headers and then the
  * specific needs of in or out streams.
  */
@@ -87,8 +90,8 @@
 
 
 /* Initialize a block of memory as a ssnmap.  */
-struct sctp_ssnmap *sctp_ssnmap_init(struct sctp_ssnmap *map, __u16 in,
-				     __u16 out)
+static struct sctp_ssnmap *sctp_ssnmap_init(struct sctp_ssnmap *map, __u16 in,
+					    __u16 out)
 {
 	memset(map, 0x00, sctp_ssnmap_size(in, out));
 
diff -Nru a/net/sctp/transport.c b/net/sctp/transport.c
--- a/net/sctp/transport.c	2005-03-01 23:39:18 -08:00
+++ b/net/sctp/transport.c	2005-03-01 23:39:18 -08:00
@@ -54,34 +54,10 @@
 
 /* 1st Level Abstractions.  */
 
-/* Allocate and initialize a new transport.  */
-struct sctp_transport *sctp_transport_new(const union sctp_addr *addr, int gfp)
-{
-        struct sctp_transport *transport;
-
-        transport = t_new(struct sctp_transport, gfp);
-	if (!transport)
-		goto fail;
-
-	if (!sctp_transport_init(transport, addr, gfp))
-		goto fail_init;
-
-	transport->malloced = 1;
-	SCTP_DBG_OBJCNT_INC(transport);
-
-	return transport;
-
-fail_init:
-	kfree(transport);
-
-fail:
-	return NULL;
-}
-
 /* Initialize a new transport from provided memory.  */
-struct sctp_transport *sctp_transport_init(struct sctp_transport *peer,
-					   const union sctp_addr *addr,
-					   int gfp)
+static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer,
+						  const union sctp_addr *addr,
+						  int gfp)
 {
 	/* Copy in the address.  */
 	peer->ipaddr = *addr;
@@ -112,7 +88,6 @@
 
 	/* Initialize the default path max_retrans.  */
 	peer->max_retrans = sctp_max_retrans_path;
-	peer->error_threshold = 0;
 	peer->error_count = 0;
 
 	INIT_LIST_HEAD(&peer->transmitted);
@@ -144,6 +119,30 @@
 	return peer;
 }
 
+/* Allocate and initialize a new transport.  */
+struct sctp_transport *sctp_transport_new(const union sctp_addr *addr, int gfp)
+{
+        struct sctp_transport *transport;
+
+        transport = t_new(struct sctp_transport, gfp);
+	if (!transport)
+		goto fail;
+
+	if (!sctp_transport_init(transport, addr, gfp))
+		goto fail_init;
+
+	transport->malloced = 1;
+	SCTP_DBG_OBJCNT_INC(transport);
+
+	return transport;
+
+fail_init:
+	kfree(transport);
+
+fail:
+	return NULL;
+}
+
 /* This transport is no longer needed.  Free up if possible, or
  * delay until it last reference count.
  */
@@ -155,13 +154,23 @@
 	if (del_timer(&transport->hb_timer))
 		sctp_transport_put(transport);
 
+	/* Delete the T3_rtx timer if it's active.
+	 * There is no point in not doing this now and letting
+	 * structure hang around in memory since we know
+	 * the tranport is going away.
+	 */
+	if (timer_pending(&transport->T3_rtx_timer) &&
+	    del_timer(&transport->T3_rtx_timer))
+		sctp_transport_put(transport);
+
+
 	sctp_transport_put(transport);
 }
 
 /* Destroy the transport data structure.
  * Assumes there are no more users of this structure.
  */
-void sctp_transport_destroy(struct sctp_transport *transport)
+static void sctp_transport_destroy(struct sctp_transport *transport)
 {
 	SCTP_ASSERT(transport->dead, "Transport is not dead", return);
 
@@ -228,7 +237,7 @@
  * address.
  */
 void sctp_transport_route(struct sctp_transport *transport,
-			  union sctp_addr *saddr, struct sctp_opt *opt)
+			  union sctp_addr *saddr, struct sctp_sock *opt)
 {
 	struct sctp_association *asoc = transport->asoc;
 	struct sctp_af *af = transport->af_specific;
diff -Nru a/net/sctp/tsnmap.c b/net/sctp/tsnmap.c
--- a/net/sctp/tsnmap.c	2005-03-01 23:39:17 -08:00
+++ b/net/sctp/tsnmap.c	2005-03-01 23:39:17 -08:00
@@ -52,29 +52,6 @@
 				     int *started, __u16 *start,
 				     int *ended, __u16 *end);
 
-/* Create a new sctp_tsnmap.
- * Allocate room to store at least 'len' contiguous TSNs.
- */
-struct sctp_tsnmap *sctp_tsnmap_new(__u16 len, __u32 initial_tsn, int gfp)
-{
-	struct sctp_tsnmap *retval;
-
-	retval = kmalloc(sizeof(struct sctp_tsnmap) +
-			 sctp_tsnmap_storage_size(len), gfp);
-	if (!retval)
-		goto fail;
-
-	if (!sctp_tsnmap_init(retval, len, initial_tsn))
-		goto fail_map;
-	retval->malloced = 1;
-	return retval;
-
-fail_map:
-	kfree(retval);
-fail:
-	return NULL;
-}
-
 /* Initialize a block of memory as a tsnmap.  */
 struct sctp_tsnmap *sctp_tsnmap_init(struct sctp_tsnmap *map, __u16 len,
 				     __u32 initial_tsn)
@@ -168,16 +145,9 @@
 }
 
 
-/* Dispose of a tsnmap.  */
-void sctp_tsnmap_free(struct sctp_tsnmap *map)
-{
-	if (map->malloced)
-		kfree(map);
-}
-
 /* Initialize a Gap Ack Block iterator from memory being provided.  */
-void sctp_tsnmap_iter_init(const struct sctp_tsnmap *map,
-			   struct sctp_tsnmap_iter *iter)
+SCTP_STATIC void sctp_tsnmap_iter_init(const struct sctp_tsnmap *map,
+				       struct sctp_tsnmap_iter *iter)
 {
 	/* Only start looking one past the Cumulative TSN Ack Point.  */
 	iter->start = map->cumulative_tsn_ack_point + 1;
@@ -186,8 +156,9 @@
 /* Get the next Gap Ack Blocks. Returns 0 if there was not another block
  * to get.
  */
-int sctp_tsnmap_next_gap_ack(const struct sctp_tsnmap *map,
-	struct sctp_tsnmap_iter *iter, __u16 *start, __u16 *end)
+SCTP_STATIC int sctp_tsnmap_next_gap_ack(const struct sctp_tsnmap *map,
+					 struct sctp_tsnmap_iter *iter,
+					 __u16 *start, __u16 *end)
 {
 	int started, ended;
 	__u16 _start, _end, offset;
diff -Nru a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c
--- a/net/sctp/ulpevent.c	2005-03-01 23:38:53 -08:00
+++ b/net/sctp/ulpevent.c	2005-03-01 23:38:53 -08:00
@@ -65,8 +65,16 @@
  */
 }
 
+/* Initialize an ULP event from an given skb.  */
+SCTP_STATIC void sctp_ulpevent_init(struct sctp_ulpevent *event, int msg_flags)
+{
+	memset(event, 0, sizeof(struct sctp_ulpevent));
+	event->msg_flags = msg_flags;
+}
+
 /* Create a new sctp_ulpevent.  */
-struct sctp_ulpevent *sctp_ulpevent_new(int size, int msg_flags, int gfp)
+SCTP_STATIC struct sctp_ulpevent *sctp_ulpevent_new(int size, int msg_flags,
+						    int gfp)
 {
 	struct sctp_ulpevent *event;
 	struct sk_buff *skb;
@@ -82,13 +90,6 @@
 
 fail:
 	return NULL;
-}
-
-/* Initialize an ULP event from an given skb.  */
-void sctp_ulpevent_init(struct sctp_ulpevent *event, int msg_flags)
-{
-	memset(event, 0, sizeof(struct sctp_ulpevent));
-	event->msg_flags = msg_flags;
 }
 
 /* Is this a MSG_NOTIFICATION?  */
diff -Nru a/net/sctp/ulpqueue.c b/net/sctp/ulpqueue.c
--- a/net/sctp/ulpqueue.c	2005-03-01 23:39:16 -08:00
+++ b/net/sctp/ulpqueue.c	2005-03-01 23:39:16 -08:00
@@ -56,25 +56,6 @@
 
 /* 1st Level Abstractions */
 
-/* Create a new ULP queue.  */
-struct sctp_ulpq *sctp_ulpq_new(struct sctp_association *asoc, int gfp)
-{
-	struct sctp_ulpq *ulpq;
-
-	ulpq = kmalloc(sizeof(struct sctp_ulpq), gfp);
-	if (!ulpq)
-		goto fail;
-	if (!sctp_ulpq_init(ulpq, asoc))
-		goto fail_init;
-	ulpq->malloced = 1;
-	return ulpq;
-
-fail_init:
-	kfree(ulpq);
-fail:
-	return NULL;
-}
-
 /* Initialize a ULP queue from a block of memory.  */
 struct sctp_ulpq *sctp_ulpq_init(struct sctp_ulpq *ulpq,
 				 struct sctp_association *asoc)
@@ -92,7 +73,7 @@
 
 
 /* Flush the reassembly and ordering queues.  */
-void sctp_ulpq_flush(struct sctp_ulpq *ulpq)
+static void sctp_ulpq_flush(struct sctp_ulpq *ulpq)
 {
 	struct sk_buff *skb;
 	struct sctp_ulpevent *event;
@@ -157,8 +138,7 @@
  */
 int sctp_clear_pd(struct sock *sk)
 {
-	struct sctp_opt *sp;
-	sp = sctp_sk(sk);
+	struct sctp_sock *sp = sctp_sk(sk);
 
 	sp->pd_mode = 0;
 	if (!skb_queue_empty(&sp->pd_lobby)) {
diff -Nru a/net/socket.c b/net/socket.c
--- a/net/socket.c	2005-03-01 23:38:55 -08:00
+++ b/net/socket.c	2005-03-01 23:38:55 -08:00
@@ -104,7 +104,7 @@
 static int sock_close(struct inode *inode, struct file *file);
 static unsigned int sock_poll(struct file *file,
 			      struct poll_table_struct *wait);
-static int sock_ioctl(struct inode *inode, struct file *file,
+static long sock_ioctl(struct file *file,
 		      unsigned int cmd, unsigned long arg);
 static int sock_fasync(int fd, struct file *filp, int on);
 static ssize_t sock_readv(struct file *file, const struct iovec *vector,
@@ -126,7 +126,7 @@
 	.aio_read =	sock_aio_read,
 	.aio_write =	sock_aio_write,
 	.poll =		sock_poll,
-	.ioctl =	sock_ioctl,
+	.unlocked_ioctl = sock_ioctl,
 	.mmap =		sock_mmap,
 	.open =		sock_no_open,	/* special open code to disallow open via /proc */
 	.release =	sock_close,
@@ -144,7 +144,7 @@
 
 #if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT)
 static atomic_t net_family_lockct = ATOMIC_INIT(0);
-static spinlock_t net_family_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(net_family_lock);
 
 /* The strategy is: modifications net_family vector are short, do not
    sleep and veeery rare, but read access should be free of any exclusive
@@ -736,8 +736,9 @@
 	return sock->ops->sendpage(sock, page, offset, size, flags);
 }
 
-int sock_readv_writev(int type, struct inode * inode, struct file * file,
-		      const struct iovec * iov, long count, size_t size)
+static int sock_readv_writev(int type, struct inode * inode,
+			     struct file * file, const struct iovec * iov,
+			     long count, size_t size)
 {
 	struct msghdr msg;
 	struct socket *sock;
@@ -828,15 +829,13 @@
  *	what to do with it - that's up to the protocol still.
  */
 
-static int sock_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
-		      unsigned long arg)
+static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)
 {
 	struct socket *sock;
 	void __user *argp = (void __user *)arg;
 	int pid, err;
 
-	unlock_kernel();
-	sock = SOCKET_I(inode);
+	sock = SOCKET_I(file->f_dentry->d_inode);
 	if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) {
 		err = dev_ioctl(cmd, argp);
 	} else
@@ -902,8 +901,6 @@
 			err = sock->ops->ioctl(sock, cmd, arg);
 			break;
 	}
-	lock_kernel();
-
 	return err;
 }
 
@@ -1073,7 +1070,6 @@
 
 static int __sock_create(int family, int type, int protocol, struct socket **res, int kern)
 {
-	int i;
 	int err;
 	struct socket *sock;
 
@@ -1118,7 +1114,7 @@
 
 	net_family_read_lock();
 	if (net_families[family] == NULL) {
-		i = -EAFNOSUPPORT;
+		err = -EAFNOSUPPORT;
 		goto out;
 	}
 
@@ -1128,10 +1124,9 @@
  *	default.
  */
 
-	if (!(sock = sock_alloc())) 
-	{
+	if (!(sock = sock_alloc())) {
 		printk(KERN_WARNING "socket: no more sockets\n");
-		i = -ENFILE;		/* Not exactly a match, but its the
+		err = -ENFILE;		/* Not exactly a match, but its the
 					   closest posix thing */
 		goto out;
 	}
@@ -1142,11 +1137,11 @@
 	 * We will call the ->create function, that possibly is in a loadable
 	 * module, so we have to bump that loadable module refcnt first.
 	 */
-	i = -EAFNOSUPPORT;
+	err = -EAFNOSUPPORT;
 	if (!try_module_get(net_families[family]->owner))
 		goto out_release;
 
-	if ((i = net_families[family]->create(sock, protocol)) < 0)
+	if ((err = net_families[family]->create(sock, protocol)) < 0)
 		goto out_module_put;
 	/*
 	 * Now to bump the refcnt of the [loadable] module that owns this
@@ -1166,7 +1161,7 @@
 
 out:
 	net_family_read_unlock();
-	return i;
+	return err;
 out_module_put:
 	module_put(net_families[family]->owner);
 out_release:
@@ -2031,15 +2026,6 @@
 
 void __init sock_init(void)
 {
-	int i;
-
-	/*
-	 *	Initialize all address (protocol) families. 
-	 */
-	 
-	for (i = 0; i < NPROTO; i++) 
-		net_families[i] = NULL;
-
 	/*
 	 *	Initialize sock SLAB cache.
 	 */
diff -Nru a/net/sunrpc/auth.c b/net/sunrpc/auth.c
--- a/net/sunrpc/auth.c	2005-03-01 23:38:57 -08:00
+++ b/net/sunrpc/auth.c	2005-03-01 23:38:57 -08:00
@@ -25,7 +25,7 @@
 	NULL,			/* others can be loadable modules */
 };
 
-u32
+static u32
 pseudoflavor_to_flavor(u32 flavor) {
 	if (flavor >= RPC_AUTH_MAXFLAVOR)
 		return RPC_AUTH_GSS;
@@ -89,7 +89,7 @@
 	kfree(auth);
 }
 
-static spinlock_t rpc_credcache_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(rpc_credcache_lock);
 
 /*
  * Initialize RPC credential cache
@@ -214,8 +214,6 @@
 	list_for_each_safe(pos, next, &auth->au_credcache[nr]) {
 		struct rpc_cred *entry;
 	       	entry = list_entry(pos, struct rpc_cred, cr_hash);
-		if (entry->cr_flags & RPCAUTH_CRED_DEAD)
-			continue;
 		if (rpcauth_prune_expired(entry, &free))
 			continue;
 		if (entry->cr_ops->crmatch(acred, entry, taskflags)) {
@@ -307,9 +305,6 @@
 	if (!atomic_dec_and_lock(&cred->cr_count, &rpc_credcache_lock))
 		return;
 
-	if ((cred->cr_flags & RPCAUTH_CRED_DEAD) && !list_empty(&cred->cr_hash))
-		list_del_init(&cred->cr_hash);
-
 	if (list_empty(&cred->cr_hash)) {
 		spin_unlock(&rpc_credcache_lock);
 		rpcauth_crdestroy(cred);
@@ -412,11 +407,4 @@
 {
 	return !(task->tk_msg.rpc_cred) ||
 		(task->tk_msg.rpc_cred->cr_flags & RPCAUTH_CRED_UPTODATE);
-}
-
-int
-rpcauth_deadcred(struct rpc_task *task)
-{
-	return !(task->tk_msg.rpc_cred) ||
-		(task->tk_msg.rpc_cred->cr_flags & RPCAUTH_CRED_DEAD);
 }
diff -Nru a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
--- a/net/sunrpc/auth_gss/auth_gss.c	2005-03-01 23:38:56 -08:00
+++ b/net/sunrpc/auth_gss/auth_gss.c	2005-03-01 23:38:56 -08:00
@@ -80,7 +80,7 @@
 /* dump the buffer in `emacs-hexl' style */
 #define isprint(c)      ((c > 0x1f) && (c < 0x7f))
 
-static rwlock_t gss_ctx_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(gss_ctx_lock);
 
 struct gss_auth {
 	struct rpc_auth rpc_auth;
@@ -480,12 +480,14 @@
 	if (!cred)
 		goto err;
 	if (gss_err)
-		cred->cr_flags |= RPCAUTH_CRED_DEAD;
+		cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE;
 	else
 		gss_cred_set_ctx(cred, ctx);
 	spin_lock(&gss_auth->lock);
 	gss_msg = __gss_find_upcall(gss_auth, acred.uid);
 	if (gss_msg) {
+		if (gss_err)
+			gss_msg->msg.errno = -EACCES;
 		__gss_unhash_msg(gss_msg);
 		spin_unlock(&gss_auth->lock);
 		gss_release_msg(gss_msg);
@@ -532,7 +534,7 @@
 	spin_unlock(&gss_auth->lock);
 }
 
-void
+static void
 gss_pipe_destroy_msg(struct rpc_pipe_msg *msg)
 {
 	struct gss_upcall_msg *gss_msg = container_of(msg, struct gss_upcall_msg, msg);
@@ -591,9 +593,11 @@
 			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))
-		goto err_free;
+		goto err_put_mech;
 
 	return auth;
+err_put_mech:
+	gss_mech_put(gss_auth->mech);
 err_free:
 	kfree(gss_auth);
 out_dec:
@@ -610,6 +614,7 @@
 
 	gss_auth = container_of(auth, struct gss_auth, rpc_auth);
 	rpc_unlink(gss_auth->path);
+	gss_mech_put(gss_auth->mech);
 
 	rpcauth_free_credcache(auth);
 }
@@ -740,7 +745,9 @@
 	maj_stat = gss_get_mic(ctx->gc_gss_ctx,
 			       GSS_C_QOP_DEFAULT, 
 			       &verf_buf, &mic);
-	if(maj_stat != 0){
+	if (maj_stat == GSS_S_CONTEXT_EXPIRED) {
+		cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE;
+	} else if (maj_stat != 0) {
 		printk("gss_marshal: gss_get_mic FAILED (%d)\n", maj_stat);
 		goto out_put_ctx;
 	}
@@ -779,6 +786,7 @@
 	struct xdr_netobj mic;
 	u32		flav,len;
 	u32		service;
+	u32		maj_stat;
 
 	dprintk("RPC: %4u gss_validate\n", task->tk_pid);
 
@@ -794,8 +802,11 @@
 	mic.data = (u8 *)p;
 	mic.len = len;
 
-	if (gss_verify_mic(ctx->gc_gss_ctx, &verf_buf, &mic, &qop_state))
-               goto out_bad;
+	maj_stat = gss_verify_mic(ctx->gc_gss_ctx, &verf_buf, &mic, &qop_state);
+	if (maj_stat == GSS_S_CONTEXT_EXPIRED)
+		cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE;
+	if (maj_stat)
+		goto out_bad;
        service = gss_pseudoflavor_to_service(ctx->gc_gss_ctx->mech_type,
 					gss_cred->gc_flavor);
        switch (service) {
@@ -821,11 +832,10 @@
 }
 
 static inline int
-gss_wrap_req_integ(struct gss_cl_ctx *ctx,
-			kxdrproc_t encode, void *rqstp, u32 *p, void *obj)
+gss_wrap_req_integ(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
+		kxdrproc_t encode, struct rpc_rqst *rqstp, u32 *p, void *obj)
 {
-	struct rpc_rqst	*req = (struct rpc_rqst *)rqstp;
-	struct xdr_buf	*snd_buf = &req->rq_snd_buf;
+	struct xdr_buf	*snd_buf = &rqstp->rq_snd_buf;
 	struct xdr_buf	integ_buf;
 	u32             *integ_len = NULL;
 	struct xdr_netobj mic;
@@ -836,7 +846,7 @@
 
 	integ_len = p++;
 	offset = (u8 *)p - (u8 *)snd_buf->head[0].iov_base;
-	*p++ = htonl(req->rq_seqno);
+	*p++ = htonl(rqstp->rq_seqno);
 
 	status = encode(rqstp, p, obj);
 	if (status)
@@ -858,7 +868,9 @@
 	maj_stat = gss_get_mic(ctx->gc_gss_ctx,
 			GSS_C_QOP_DEFAULT, &integ_buf, &mic);
 	status = -EIO; /* XXX? */
-	if (maj_stat)
+	if (maj_stat == GSS_S_CONTEXT_EXPIRED)
+		cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE;
+	else if (maj_stat)
 		return status;
 	q = xdr_encode_opaque(p, NULL, mic.len);
 
@@ -894,7 +906,8 @@
 			status = encode(rqstp, p, obj);
 			goto out;
 		case RPC_GSS_SVC_INTEGRITY:
-			status = gss_wrap_req_integ(ctx, encode, rqstp, p, obj);
+			status = gss_wrap_req_integ(cred, ctx, encode,
+								rqstp, p, obj);
 			goto out;
 		case RPC_GSS_SVC_PRIVACY:
 		default:
@@ -907,11 +920,10 @@
 }
 
 static inline int
-gss_unwrap_resp_integ(struct gss_cl_ctx *ctx,
-		kxdrproc_t decode, void *rqstp, u32 **p, void *obj)
+gss_unwrap_resp_integ(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
+		struct rpc_rqst *rqstp, u32 **p)
 {
-	struct rpc_rqst *req = (struct rpc_rqst *)rqstp;
-	struct xdr_buf	*rcv_buf = &req->rq_rcv_buf;
+	struct xdr_buf	*rcv_buf = &rqstp->rq_rcv_buf;
 	struct xdr_buf integ_buf;
 	struct xdr_netobj mic;
 	u32 data_offset, mic_offset;
@@ -926,7 +938,7 @@
 	mic_offset = integ_len + data_offset;
 	if (mic_offset > rcv_buf->len)
 		return status;
-	if (ntohl(*(*p)++) != req->rq_seqno)
+	if (ntohl(*(*p)++) != rqstp->rq_seqno)
 		return status;
 
 	if (xdr_buf_subsegment(rcv_buf, &integ_buf, data_offset,
@@ -938,6 +950,8 @@
 
 	maj_stat = gss_verify_mic(ctx->gc_gss_ctx, &integ_buf,
 			&mic, NULL);
+	if (maj_stat == GSS_S_CONTEXT_EXPIRED)
+		cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE;
 	if (maj_stat != GSS_S_COMPLETE)
 		return status;
 	return 0;
@@ -962,8 +976,7 @@
 		case RPC_GSS_SVC_NONE:
 			goto out_decode;
 		case RPC_GSS_SVC_INTEGRITY:
-			status = gss_unwrap_resp_integ(ctx, decode, 
-							rqstp, &p, obj);
+			status = gss_unwrap_resp_integ(cred, ctx, rqstp, &p);
 			if (status)
 				goto out;
 			break;
diff -Nru a/net/sunrpc/auth_gss/gss_generic_token.c b/net/sunrpc/auth_gss/gss_generic_token.c
--- a/net/sunrpc/auth_gss/gss_generic_token.c	2005-03-01 23:38:55 -08:00
+++ b/net/sunrpc/auth_gss/gss_generic_token.c	2005-03-01 23:38:55 -08:00
@@ -233,38 +233,3 @@
 
 EXPORT_SYMBOL(g_verify_token_header);
 
-/* Given a buffer containing a token, returns a copy of the mech oid in
- * the parameter mech. */
-u32
-g_get_mech_oid(struct xdr_netobj *mech, struct xdr_netobj * in_buf)
-{
-	unsigned char *buf = in_buf->data;
-	int len = in_buf->len;
-	int ret=0;
-	int seqsize;
-
-	if ((len-=1) < 0)
-		return(G_BAD_TOK_HEADER);
-	if (*buf++ != 0x60)
-		return(G_BAD_TOK_HEADER);
-
-	if ((seqsize = der_read_length(&buf, &len)) < 0)
-		return(G_BAD_TOK_HEADER);
-
-	if ((len-=1) < 0)
-		return(G_BAD_TOK_HEADER);
-	if (*buf++ != 0x06)
-		return(G_BAD_TOK_HEADER);
-
-	if ((len-=1) < 0)
-		return(G_BAD_TOK_HEADER);
-	mech->len = *buf++;
-
-	if ((len-=mech->len) < 0)
-		return(G_BAD_TOK_HEADER);
-	if (!(mech->data = kmalloc(mech->len, GFP_KERNEL))) 
-		return(G_BUFFER_ALLOC);
-	memcpy(mech->data, buf, mech->len);
-
-	return ret;
-}
diff -Nru 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	2005-03-01 23:38:51 -08:00
+++ b/net/sunrpc/auth_gss/gss_krb5_crypto.c	2005-03-01 23:38:51 -08:00
@@ -132,7 +132,7 @@
 
 EXPORT_SYMBOL(krb5_decrypt);
 
-void
+static void
 buf_to_sg(struct scatterlist *sg, char *ptr, int len) {
 	sg->page = virt_to_page(ptr);
 	sg->offset = offset_in_page(ptr);
diff -Nru a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c
--- a/net/sunrpc/auth_gss/gss_krb5_mech.c	2005-03-01 23:39:08 -08:00
+++ b/net/sunrpc/auth_gss/gss_krb5_mech.c	2005-03-01 23:39:08 -08:00
@@ -48,9 +48,6 @@
 # define RPCDBG_FACILITY	RPCDBG_AUTH
 #endif
 
-struct xdr_netobj gss_mech_krb5_oid =
-   {9, "\052\206\110\206\367\022\001\002\002"};
-
 static inline int
 get_bytes(char **ptr, const char *end, void *res, int len)
 {
diff -Nru a/net/sunrpc/auth_gss/gss_mech_switch.c b/net/sunrpc/auth_gss/gss_mech_switch.c
--- a/net/sunrpc/auth_gss/gss_mech_switch.c	2005-03-01 23:39:07 -08:00
+++ b/net/sunrpc/auth_gss/gss_mech_switch.c	2005-03-01 23:39:07 -08:00
@@ -51,7 +51,7 @@
 #endif
 
 static LIST_HEAD(registered_mechs);
-static spinlock_t registered_mechs_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(registered_mechs_lock);
 
 static void
 gss_mech_free(struct gss_api_mech *gm)
@@ -150,9 +150,8 @@
 	spin_lock(&registered_mechs_lock);
 	list_for_each_entry(pos, &registered_mechs, gm_list) {
 		if (0 == strcmp(name, pos->gm_name)) {
-			if (!try_module_get(pos->gm_owner))
-				continue;
-			gm = pos;
+			if (try_module_get(pos->gm_owner))
+				gm = pos;
 			break;
 		}
 	}
@@ -182,13 +181,12 @@
 
 	spin_lock(&registered_mechs_lock);
 	list_for_each_entry(pos, &registered_mechs, gm_list) {
-		if (!try_module_get(pos->gm_owner))
-			continue;
 		if (!mech_supports_pseudoflavor(pos, pseudoflavor)) {
 			module_put(pos->gm_owner);
 			continue;
 		}
-		gm = pos;
+		if (try_module_get(pos->gm_owner))
+			gm = pos;
 		break;
 	}
 	spin_unlock(&registered_mechs_lock);
diff -Nru a/net/sunrpc/auth_gss/gss_pseudoflavors.c b/net/sunrpc/auth_gss/gss_pseudoflavors.c
--- a/net/sunrpc/auth_gss/gss_pseudoflavors.c	2005-03-01 23:38:57 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,237 +0,0 @@
-/*
- *  linux/net/sunrpc/gss_union.c
- *
- *  Adapted from MIT Kerberos 5-1.2.1 lib/gssapi/generic code
- *
- *  Copyright (c) 2001 The Regents of the University of Michigan.
- *  All rights reserved.
- *
- *  Andy Adamson   <andros@umich.edu>
- *
- */
-
-/*
- * Copyright 1993 by OpenVision Technologies, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software
- * and its documentation for any purpose is hereby granted without fee,
- * provided that the above copyright notice appears in all copies and
- * that both that copyright notice and this permission notice appear in
- * supporting documentation, and that the name of OpenVision not be used
- * in advertising or publicity pertaining to distribution of the software
- * without specific, written prior permission. OpenVision makes no
- * representations about the suitability of this software for any
- * purpose.  It is provided "as is" without express or implied warranty.
- *
- * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
- * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
- * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */ 
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/socket.h>
-#include <linux/sunrpc/gss_asn1.h>
-#include <linux/sunrpc/auth_gss.h>
-
-#ifdef RPC_DEBUG
-# define RPCDBG_FACILITY        RPCDBG_AUTH
-#endif
-
-static LIST_HEAD(registered_triples);
-static spinlock_t registered_triples_lock = SPIN_LOCK_UNLOCKED;
-
-/* The following must be called with spinlock held: */
-static struct sup_sec_triple *
-do_lookup_triple_by_pseudoflavor(u32 pseudoflavor)
-{
-	struct sup_sec_triple *pos, *triple = NULL;
-
-	list_for_each_entry(pos, &registered_triples, triples) {
-		if (pos->pseudoflavor == pseudoflavor) {
-			triple = pos;
-			break;
-		}
-	}
-	return triple;
-}
-
-/* XXX Need to think about reference counting of triples and of mechs.
- * Currently we do no reference counting of triples, and I think that's
- * probably OK given the reference counting on mechs, but there's probably
- * a better way to do all this. */
-
-int
-gss_register_triple(u32 pseudoflavor, struct gss_api_mech *mech,
-			  u32 qop, u32 service)
-{
-	struct sup_sec_triple *triple;
-
-	if (!(triple = kmalloc(sizeof(*triple), GFP_KERNEL))) {
-		printk("Alloc failed in gss_register_triple");
-		goto err;
-	}
-	triple->pseudoflavor = pseudoflavor;
-	triple->mech = gss_mech_get_by_OID(&mech->gm_oid);
-	triple->qop = qop;
-	triple->service = service;
-
-	spin_lock(&registered_triples_lock);
-	if (do_lookup_triple_by_pseudoflavor(pseudoflavor)) {
-		printk(KERN_WARNING "RPC: Registered pseudoflavor %d again\n",
-				pseudoflavor);
-		goto err_unlock;
-	}
-	list_add(&triple->triples, &registered_triples);
-	spin_unlock(&registered_triples_lock);
-	dprintk("RPC:      registered pseudoflavor %d\n", pseudoflavor);
-
-	return 0;
-
-err_unlock:
-	kfree(triple);
-	spin_unlock(&registered_triples_lock);
-err:
-	return -1;
-}
-
-int
-gss_unregister_triple(u32 pseudoflavor)
-{
-	struct sup_sec_triple *triple;
-
-	spin_lock(&registered_triples_lock);
-	if (!(triple = do_lookup_triple_by_pseudoflavor(pseudoflavor))) {
-		spin_unlock(&registered_triples_lock);
-		printk("Can't unregister unregistered pseudoflavor %d\n",
-		       pseudoflavor);
-		return -1;
-	}
-	list_del(&triple->triples);
-	spin_unlock(&registered_triples_lock);
-	gss_mech_put(triple->mech);
-	kfree(triple);
-	return 0;
-
-}
-
-void
-print_sec_triple(struct xdr_netobj *oid,u32 qop,u32 service)
-{
-	dprintk("RPC: print_sec_triple:\n");
-	dprintk("                     oid_len %d\n  oid :\n",oid->len);
-	print_hexl((u32 *)oid->data,oid->len,0);
-	dprintk("                     qop %d\n",qop);
-	dprintk("                     service %d\n",service);
-}
-
-/* Function: gss_get_cmp_triples
- *
- * Description: search sec_triples for a matching security triple
- * return pseudoflavor if match, else 0
- * (Note that 0 is a valid pseudoflavor, but not for any gss pseudoflavor
- * (0 means auth_null), so this shouldn't cause confusion.)
- */
-u32
-gss_cmp_triples(u32 oid_len, char *oid_data, u32 qop, u32 service)
-{
-	struct sup_sec_triple *triple;
-	u32 pseudoflavor = 0;
-	struct xdr_netobj oid;
-
-	oid.len = oid_len;
-	oid.data = oid_data;
-
-	dprintk("RPC:      gss_cmp_triples\n");
-	print_sec_triple(&oid,qop,service);
-
-	spin_lock(&registered_triples_lock);
-	list_for_each_entry(triple, &registered_triples, triples) {
-		if((g_OID_equal(&oid, &triple->mech->gm_oid))
-		    && (qop == triple->qop)
-		    && (service == triple->service)) {
-			pseudoflavor = triple->pseudoflavor;
-			break;
-		}
-	}
-	spin_unlock(&registered_triples_lock);
-	dprintk("RPC:      gss_cmp_triples return %d\n", pseudoflavor);
-	return pseudoflavor;
-}
-
-u32
-gss_get_pseudoflavor(struct gss_ctx *ctx, u32 qop, u32 service)
-{
-	return gss_cmp_triples(ctx->mech_type->gm_oid.len,
-			       ctx->mech_type->gm_oid.data,
-			       qop, service);
-}
-
-/* Returns nonzero iff the given pseudoflavor is in the supported list.
- * (Note that without incrementing a reference count or anything, this
- * doesn't give any guarantees.) */
-int
-gss_pseudoflavor_supported(u32 pseudoflavor)
-{
-	struct sup_sec_triple *triple;
-
-	spin_lock(&registered_triples_lock);
-	triple = do_lookup_triple_by_pseudoflavor(pseudoflavor);
-	spin_unlock(&registered_triples_lock);
-	return (triple ? 1 : 0);
-}
-
-u32
-gss_pseudoflavor_to_service(u32 pseudoflavor)
-{
-	struct sup_sec_triple *triple;
-
-	spin_lock(&registered_triples_lock);
-	triple = do_lookup_triple_by_pseudoflavor(pseudoflavor);
-	spin_unlock(&registered_triples_lock);
-	if (!triple) {
-		dprintk("RPC:      gss_pseudoflavor_to_service called with unsupported pseudoflavor %d\n",
-				pseudoflavor);
-		return 0;
-	}
-	return triple->service;
-}
-
-struct gss_api_mech *
-gss_pseudoflavor_to_mech(u32 pseudoflavor) {
-	struct sup_sec_triple *triple;
-	struct gss_api_mech *mech = NULL;
-
-	spin_lock(&registered_triples_lock);
-	triple = do_lookup_triple_by_pseudoflavor(pseudoflavor);
-	spin_unlock(&registered_triples_lock);
-	if (triple)
-		mech = gss_mech_get(triple->mech);
-	else
-		dprintk("RPC:      gss_pseudoflavor_to_mech called with unsupported pseudoflavor %d\n",
-				pseudoflavor);
-	return mech;
-}
-
-int
-gss_pseudoflavor_to_mechOID(u32 pseudoflavor, struct xdr_netobj * oid)
-{
-	struct gss_api_mech *mech;
-
-	mech = gss_pseudoflavor_to_mech(pseudoflavor);
-	if (!mech)  {
-		dprintk("RPC:      gss_pseudoflavor_to_mechOID called with unsupported pseudoflavor %d\n",
-				pseudoflavor);
-		        return -1;
-	}
-	oid->len = mech->gm_oid.len;
-	if (!(oid->data = kmalloc(oid->len, GFP_KERNEL)))
-		return -1;
-	memcpy(oid->data, mech->gm_oid.data, oid->len);
-	gss_mech_put(mech);
-	return 0;
-}
diff -Nru a/net/sunrpc/auth_gss/gss_spkm3_mech.c b/net/sunrpc/auth_gss/gss_spkm3_mech.c
--- a/net/sunrpc/auth_gss/gss_spkm3_mech.c	2005-03-01 23:39:09 -08:00
+++ b/net/sunrpc/auth_gss/gss_spkm3_mech.c	2005-03-01 23:39:09 -08:00
@@ -49,9 +49,6 @@
 # define RPCDBG_FACILITY	RPCDBG_AUTH
 #endif
 
-struct xdr_netobj gss_mech_spkm3_oid =
-   {7, "\053\006\001\005\005\001\003"};
-
 static inline int
 get_bytes(char **ptr, const char *end, void *res, int len)
 {
@@ -206,7 +203,7 @@
 	return GSS_S_FAILURE;
 }
 
-void
+static void
 gss_delete_sec_context_spkm3(void *internal_ctx) {
 	struct spkm3_ctx *sctx = internal_ctx;
 
@@ -221,7 +218,7 @@
 	kfree(sctx);
 }
 
-u32
+static u32
 gss_verify_mic_spkm3(struct gss_ctx		*ctx,
 			struct xdr_buf		*signbuf,
 			struct xdr_netobj	*checksum,
@@ -241,7 +238,7 @@
 	return maj_stat;
 }
 
-u32
+static u32
 gss_get_mic_spkm3(struct gss_ctx	*ctx,
 		     u32		qop,
 		     struct xdr_buf	*message_buffer,
diff -Nru a/net/sunrpc/auth_gss/sunrpcgss_syms.c b/net/sunrpc/auth_gss/sunrpcgss_syms.c
--- a/net/sunrpc/auth_gss/sunrpcgss_syms.c	2005-03-01 23:39:08 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,37 +0,0 @@
-#include <linux/config.h>
-#include <linux/module.h>
-
-#include <linux/types.h>
-#include <linux/socket.h>
-#include <linux/sched.h>
-#include <linux/uio.h>
-#include <linux/unistd.h>
-
-#include <linux/sunrpc/auth_gss.h>
-#include <linux/sunrpc/svcauth_gss.h>
-#include <linux/sunrpc/gss_asn1.h>
-#include <linux/sunrpc/gss_krb5.h>
-
-/* svcauth_gss.c: */
-EXPORT_SYMBOL(svcauth_gss_register_pseudoflavor);
-
-/* registering gss mechanisms to the mech switching code: */
-EXPORT_SYMBOL(gss_mech_register);
-EXPORT_SYMBOL(gss_mech_unregister);
-EXPORT_SYMBOL(gss_mech_get);
-EXPORT_SYMBOL(gss_mech_get_by_pseudoflavor);
-EXPORT_SYMBOL(gss_mech_get_by_name);
-EXPORT_SYMBOL(gss_mech_put);
-EXPORT_SYMBOL(gss_pseudoflavor_to_service);
-EXPORT_SYMBOL(gss_service_to_auth_domain_name);
-
-/* generic functionality in gss code: */
-EXPORT_SYMBOL(g_make_token_header);
-EXPORT_SYMBOL(g_verify_token_header);
-EXPORT_SYMBOL(g_token_size);
-EXPORT_SYMBOL(make_checksum);
-EXPORT_SYMBOL(krb5_encrypt);
-EXPORT_SYMBOL(krb5_decrypt);
-
-/* debug */
-EXPORT_SYMBOL(print_hexl);
diff -Nru a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
--- a/net/sunrpc/auth_gss/svcauth_gss.c	2005-03-01 23:38:57 -08:00
+++ b/net/sunrpc/auth_gss/svcauth_gss.c	2005-03-01 23:38:57 -08:00
@@ -448,7 +448,7 @@
 
 static DefineSimpleCacheLookup(rsc, 0);
 
-struct rsc *
+static struct rsc *
 gss_svc_searchbyctx(struct xdr_netobj *handle)
 {
 	struct rsc rsci;
@@ -958,7 +958,7 @@
 	if (gc->gc_proc != RPC_GSS_PROC_DATA)
 		goto out;
 	/* Release can be called twice, but we only wrap once. */
-	if (gsd->body_start == 0)
+	if (gsd->body_start == NULL)
 		goto out;
 	/* normally not set till svc_send, but we need it here: */
 	resbuf->len = resbuf->head[0].iov_len
@@ -1045,7 +1045,7 @@
 	kfree(gd);
 }
 
-struct auth_ops svcauthops_gss = {
+static struct auth_ops svcauthops_gss = {
 	.name		= "rpcsec_gss",
 	.owner		= THIS_MODULE,
 	.flavour	= RPC_AUTH_GSS,
diff -Nru a/net/sunrpc/auth_null.c b/net/sunrpc/auth_null.c
--- a/net/sunrpc/auth_null.c	2005-03-01 23:39:18 -08:00
+++ b/net/sunrpc/auth_null.c	2005-03-01 23:39:18 -08:00
@@ -100,7 +100,8 @@
 static int
 nul_refresh(struct rpc_task *task)
 {
-	return task->tk_status = -EACCES;
+	task->tk_msg.rpc_cred->cr_flags |= RPCAUTH_CRED_UPTODATE;
+	return 0;
 }
 
 static u32 *
diff -Nru a/net/sunrpc/auth_unix.c b/net/sunrpc/auth_unix.c
--- a/net/sunrpc/auth_unix.c	2005-03-01 23:38:58 -08:00
+++ b/net/sunrpc/auth_unix.c	2005-03-01 23:38:58 -08:00
@@ -187,7 +187,7 @@
 unx_refresh(struct rpc_task *task)
 {
 	task->tk_msg.rpc_cred->cr_flags |= RPCAUTH_CRED_UPTODATE;
-	return task->tk_status = -EACCES;
+	return 0;
 }
 
 static u32 *
diff -Nru a/net/sunrpc/cache.c b/net/sunrpc/cache.c
--- a/net/sunrpc/cache.c	2005-03-01 23:38:58 -08:00
+++ b/net/sunrpc/cache.c	2005-03-01 23:38:58 -08:00
@@ -33,6 +33,9 @@
 
 #define	 RPCDBG_FACILITY RPCDBG_CACHE
 
+static void cache_defer_req(struct cache_req *req, struct cache_head *item);
+static void cache_revisit_request(struct cache_head *item);
+
 void cache_init(struct cache_head *h)
 {
 	time_t now = get_seconds();
@@ -158,7 +161,7 @@
  */
 
 static LIST_HEAD(cache_list);
-static spinlock_t cache_list_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(cache_list_lock);
 static struct cache_detail *current_detail;
 static int current_index;
 
@@ -256,39 +259,13 @@
 	return 0;
 }
 
-struct cache_detail *cache_find(char *name)
-{
-	struct list_head *l;
-
-	spin_lock(&cache_list_lock);
-	list_for_each(l, &cache_list) {
-		struct cache_detail *cd = list_entry(l, struct cache_detail, others);
-		
-		if (strcmp(cd->name, name)==0) {
-			atomic_inc(&cd->inuse);
-			spin_unlock(&cache_list_lock);
-			return cd;
-		}
-	}
-	spin_unlock(&cache_list_lock);
-	return NULL;
-}
-
-/* cache_drop must be called on any cache returned by
- * cache_find, after it has been used
- */
-void cache_drop(struct cache_detail *detail)
-{
-	atomic_dec(&detail->inuse);
-}
-
 /* clean cache tries to find something to clean
  * and cleans it.
  * It returns 1 if it cleaned something,
  *            0 if it didn't find anything this time
  *           -1 if it fell off the end of the list.
  */
-int cache_clean(void)
+static int cache_clean(void)
 {
 	int rv = 0;
 	struct list_head *next;
@@ -428,12 +405,12 @@
 
 #define	DFR_MAX	300	/* ??? */
 
-spinlock_t cache_defer_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(cache_defer_lock);
 static LIST_HEAD(cache_defer_list);
 static struct list_head cache_defer_hash[DFR_HASHSIZE];
 static int cache_defer_cnt;
 
-void cache_defer_req(struct cache_req *req, struct cache_head *item)
+static void cache_defer_req(struct cache_req *req, struct cache_head *item)
 {
 	struct cache_deferred_req *dreq;
 	int hash = DFR_HASH(item);
@@ -483,7 +460,7 @@
 	}
 }
 
-void cache_revisit_request(struct cache_head *item)
+static void cache_revisit_request(struct cache_head *item)
 {
 	struct cache_deferred_req *dreq;
 	struct list_head pending;
@@ -556,7 +533,7 @@
  *
  */
 
-static spinlock_t queue_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(queue_lock);
 static DECLARE_MUTEX(queue_io_sem);
 
 struct cache_queue {
@@ -902,7 +879,7 @@
 	*lp = len;
 }
 
-void warn_no_listener(struct cache_detail *detail)
+static void warn_no_listener(struct cache_detail *detail)
 {
 	if (detail->last_warn != detail->last_close) {
 		detail->last_warn = detail->last_close;
@@ -1119,7 +1096,7 @@
 	return cd->cache_show(m, cd, cp);
 }
 
-struct seq_operations cache_content_op = {
+static struct seq_operations cache_content_op = {
 	.start	= c_start,
 	.next	= c_next,
 	.stop	= c_stop,
diff -Nru a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
--- a/net/sunrpc/clnt.c	2005-03-01 23:38:55 -08:00
+++ b/net/sunrpc/clnt.c	2005-03-01 23:38:55 -08:00
@@ -928,7 +928,7 @@
 	task->tk_action = call_reserve;
 	if (status >= 0 && rpcauth_uptodatecred(task))
 		return;
-	if (rpcauth_deadcred(task)) {
+	if (status == -EACCES) {
 		rpc_exit(task, -EACCES);
 		return;
 	}
@@ -970,23 +970,31 @@
 	struct kvec *iov = &task->tk_rqstp->rq_rcv_buf.head[0];
 	int len = task->tk_rqstp->rq_rcv_buf.len >> 2;
 	u32	*p = iov->iov_base, n;
+	int error = -EACCES;
 
 	if ((len -= 3) < 0)
-		goto garbage;
+		goto out_overflow;
 	p += 1;	/* skip XID */
 
 	if ((n = ntohl(*p++)) != RPC_REPLY) {
 		printk(KERN_WARNING "call_verify: not an RPC reply: %x\n", n);
-		goto garbage;
+		goto out_retry;
 	}
 	if ((n = ntohl(*p++)) != RPC_MSG_ACCEPTED) {
-		int	error = -EACCES;
-
 		if (--len < 0)
-			goto garbage;
-		if ((n = ntohl(*p++)) != RPC_AUTH_ERROR) {
-			printk(KERN_WARNING "call_verify: RPC call rejected: %x\n", n);
-		} else if (--len < 0)
+			goto out_overflow;
+		switch ((n = ntohl(*p++))) {
+			case RPC_AUTH_ERROR:
+				break;
+			case RPC_MISMATCH:
+				printk(KERN_WARNING "%s: RPC call version mismatch!\n", __FUNCTION__);
+				goto out_eio;
+			default:
+				printk(KERN_WARNING "%s: RPC call rejected, unknown error: %x\n", __FUNCTION__, n);
+				goto out_eio;
+		}
+		if (--len < 0)
+			goto out_overflow;
 		switch ((n = ntohl(*p++))) {
 		case RPC_AUTH_REJECTEDCRED:
 		case RPC_AUTH_REJECTEDVERF:
@@ -1017,20 +1025,18 @@
 		default:
 			printk(KERN_WARNING "call_verify: unknown auth error: %x\n", n);
 			error = -EIO;
-		} else
-			goto garbage;
+		}
 		dprintk("RPC: %4d call_verify: call rejected %d\n",
 						task->tk_pid, n);
-		rpc_exit(task, error);
-		return NULL;
+		goto out_err;
 	}
 	if (!(p = rpcauth_checkverf(task, p))) {
 		printk(KERN_WARNING "call_verify: auth check failed\n");
-		goto garbage;		/* bad verifier, retry */
+		goto out_retry;		/* bad verifier, retry */
 	}
 	len = p - (u32 *)iov->iov_base - 1;
 	if (len < 0)
-		goto garbage;
+		goto out_overflow;
 	switch ((n = ntohl(*p++))) {
 	case RPC_SUCCESS:
 		return p;
@@ -1053,23 +1059,28 @@
 				task->tk_client->cl_server);
 		goto out_eio;
 	case RPC_GARBAGE_ARGS:
+		dprintk("RPC: %4d %s: server saw garbage\n", task->tk_pid, __FUNCTION__);
 		break;			/* retry */
 	default:
 		printk(KERN_WARNING "call_verify: server accept status: %x\n", n);
 		/* Also retry */
 	}
 
-garbage:
-	dprintk("RPC: %4d call_verify: server saw garbage\n", task->tk_pid);
+out_retry:
 	task->tk_client->cl_stats->rpcgarbage++;
 	if (task->tk_garb_retry) {
 		task->tk_garb_retry--;
-		dprintk(KERN_WARNING "RPC: garbage, retrying %4d\n", task->tk_pid);
+		dprintk(KERN_WARNING "RPC %s: retrying %4d\n", __FUNCTION__, task->tk_pid);
 		task->tk_action = call_bind;
 		return NULL;
 	}
-	printk(KERN_WARNING "RPC: garbage, exit EIO\n");
+	printk(KERN_WARNING "RPC %s: retry failed, exit EIO\n", __FUNCTION__);
 out_eio:
-	rpc_exit(task, -EIO);
+	error = -EIO;
+out_err:
+	rpc_exit(task, error);
 	return NULL;
+out_overflow:
+	printk(KERN_WARNING "RPC %s: server reply was truncated.\n", __FUNCTION__);
+	goto out_retry;
 }
diff -Nru a/net/sunrpc/pmap_clnt.c b/net/sunrpc/pmap_clnt.c
--- a/net/sunrpc/pmap_clnt.c	2005-03-01 23:38:57 -08:00
+++ b/net/sunrpc/pmap_clnt.c	2005-03-01 23:38:57 -08:00
@@ -31,8 +31,8 @@
 static struct rpc_procinfo	pmap_procedures[];
 static struct rpc_clnt *	pmap_create(char *, struct sockaddr_in *, int);
 static void			pmap_getport_done(struct rpc_task *);
-extern struct rpc_program	pmap_program;
-static spinlock_t		pmap_lock = SPIN_LOCK_UNLOCKED;
+static struct rpc_program	pmap_program;
+static DEFINE_SPINLOCK(pmap_lock);
 
 /*
  * Obtain the port for a given RPC service on a given host. This one can
@@ -292,7 +292,7 @@
 
 static struct rpc_stat		pmap_stats;
 
-struct rpc_program	pmap_program = {
+static struct rpc_program	pmap_program = {
 	.name		= "portmap",
 	.number		= RPC_PMAP_PROGRAM,
 	.nrvers		= ARRAY_SIZE(pmap_version),
diff -Nru a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
--- a/net/sunrpc/rpc_pipe.c	2005-03-01 23:38:54 -08:00
+++ b/net/sunrpc/rpc_pipe.c	2005-03-01 23:38:54 -08:00
@@ -276,12 +276,7 @@
 	}
 }
 
-struct inode_operations rpc_pipe_iops = {
-	.lookup		= simple_lookup,
-};
-
-
-struct file_operations rpc_pipe_fops = {
+static struct file_operations rpc_pipe_fops = {
 	.owner		= THIS_MODULE,
 	.llseek		= no_llseek,
 	.read		= rpc_pipe_read,
@@ -595,7 +590,7 @@
 	return 0;
 }
 
-struct dentry *
+static struct dentry *
 rpc_lookup_negative(char *path, struct nameidata *nd)
 {
 	struct dentry *dentry;
@@ -769,6 +764,7 @@
 	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
 	sb->s_magic = RPCAUTH_GSSMAGIC;
 	sb->s_op = &s_ops;
+	sb->s_time_gran = 1;
 
 	inode = rpc_get_inode(sb, S_IFDIR | 0755);
 	if (!inode)
diff -Nru a/net/sunrpc/sched.c b/net/sunrpc/sched.c
--- a/net/sunrpc/sched.c	2005-03-01 23:38:58 -08:00
+++ b/net/sunrpc/sched.c	2005-03-01 23:38:58 -08:00
@@ -18,13 +18,13 @@
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
 #include <linux/spinlock.h>
-#include <linux/suspend.h>
 
 #include <linux/sunrpc/clnt.h>
 #include <linux/sunrpc/xprt.h>
 
 #ifdef RPC_DEBUG
 #define RPCDBG_FACILITY		RPCDBG_SCHED
+#define RPC_TASK_MAGIC_ID	0xf00baa
 static int			rpc_task_id;
 #endif
 
@@ -41,13 +41,9 @@
 
 static void			__rpc_default_timer(struct rpc_task *task);
 static void			rpciod_killall(void);
+static void			rpc_free(struct rpc_task *task);
 
-/*
- * When an asynchronous RPC task is activated within a bottom half
- * handler, or while executing another RPC task, it is put on
- * schedq, and rpciod is woken up.
- */
-static RPC_WAITQ(schedq, "schedq");
+static void			rpc_async_schedule(void *);
 
 /*
  * RPC tasks that create another task (e.g. for contacting the portmapper)
@@ -68,26 +64,18 @@
 /*
  * rpciod-related stuff
  */
-static DECLARE_WAIT_QUEUE_HEAD(rpciod_idle);
-static DECLARE_COMPLETION(rpciod_killer);
 static DECLARE_MUTEX(rpciod_sema);
 static unsigned int		rpciod_users;
-static pid_t			rpciod_pid;
-static int			rpc_inhibit;
+static struct workqueue_struct *rpciod_workqueue;
 
 /*
- * Spinlock for wait queues. Access to the latter also has to be
- * interrupt-safe in order to allow timers to wake up sleeping tasks.
- */
-static spinlock_t rpc_queue_lock = SPIN_LOCK_UNLOCKED;
-/*
  * Spinlock for other critical sections of code.
  */
-static spinlock_t rpc_sched_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(rpc_sched_lock);
 
 /*
  * Disable the timer for a given RPC task. Should be called with
- * rpc_queue_lock and bh_disabled in order to avoid races within
+ * queue->lock and bh_disabled in order to avoid races within
  * rpc_run_timer().
  */
 static inline void
@@ -105,19 +93,19 @@
  * without calling del_timer_sync(). The latter could cause a
  * deadlock if called while we're holding spinlocks...
  */
-static void
-rpc_run_timer(struct rpc_task *task)
+static void rpc_run_timer(struct rpc_task *task)
 {
 	void (*callback)(struct rpc_task *);
 
-	spin_lock_bh(&rpc_queue_lock);
 	callback = task->tk_timeout_fn;
 	task->tk_timeout_fn = NULL;
-	spin_unlock_bh(&rpc_queue_lock);
-	if (callback) {
+	if (callback && RPC_IS_QUEUED(task)) {
 		dprintk("RPC: %4d running timer\n", task->tk_pid);
 		callback(task);
 	}
+	smp_mb__before_clear_bit();
+	clear_bit(RPC_TASK_HAS_TIMER, &task->tk_runstate);
+	smp_mb__after_clear_bit();
 }
 
 /*
@@ -136,29 +124,21 @@
 		task->tk_timeout_fn = timer;
 	else
 		task->tk_timeout_fn = __rpc_default_timer;
+	set_bit(RPC_TASK_HAS_TIMER, &task->tk_runstate);
 	mod_timer(&task->tk_timer, jiffies + task->tk_timeout);
 }
 
 /*
- * Set up a timer for an already sleeping task.
- */
-void rpc_add_timer(struct rpc_task *task, rpc_action timer)
-{
-	spin_lock_bh(&rpc_queue_lock);
-	if (!RPC_IS_RUNNING(task))
-		__rpc_add_timer(task, timer);
-	spin_unlock_bh(&rpc_queue_lock);
-}
-
-/*
  * Delete any timer for the current task. Because we use del_timer_sync(),
- * this function should never be called while holding rpc_queue_lock.
+ * this function should never be called while holding queue->lock.
  */
 static inline void
 rpc_delete_timer(struct rpc_task *task)
 {
-	if (del_timer_sync(&task->tk_timer))
+	if (test_and_clear_bit(RPC_TASK_HAS_TIMER, &task->tk_runstate)) {
+		del_singleshot_timer_sync(&task->tk_timer);
 		dprintk("RPC: %4d deleting timer\n", task->tk_pid);
+	}
 }
 
 /*
@@ -169,16 +149,17 @@
 	struct list_head *q;
 	struct rpc_task *t;
 
+	INIT_LIST_HEAD(&task->u.tk_wait.links);
 	q = &queue->tasks[task->tk_priority];
 	if (unlikely(task->tk_priority > queue->maxpriority))
 		q = &queue->tasks[queue->maxpriority];
-	list_for_each_entry(t, q, tk_list) {
+	list_for_each_entry(t, q, u.tk_wait.list) {
 		if (t->tk_cookie == task->tk_cookie) {
-			list_add_tail(&task->tk_list, &t->tk_links);
+			list_add_tail(&task->u.tk_wait.list, &t->u.tk_wait.links);
 			return;
 		}
 	}
-	list_add_tail(&task->tk_list, q);
+	list_add_tail(&task->u.tk_wait.list, q);
 }
 
 /*
@@ -189,37 +170,21 @@
  * improve overall performance.
  * Everyone else gets appended to the queue to ensure proper FIFO behavior.
  */
-static int __rpc_add_wait_queue(struct rpc_wait_queue *queue, struct rpc_task *task)
+static void __rpc_add_wait_queue(struct rpc_wait_queue *queue, struct rpc_task *task)
 {
-	if (task->tk_rpcwait == queue)
-		return 0;
+	BUG_ON (RPC_IS_QUEUED(task));
 
-	if (task->tk_rpcwait) {
-		printk(KERN_WARNING "RPC: doubly enqueued task!\n");
-		return -EWOULDBLOCK;
-	}
 	if (RPC_IS_PRIORITY(queue))
 		__rpc_add_wait_queue_priority(queue, task);
 	else if (RPC_IS_SWAPPER(task))
-		list_add(&task->tk_list, &queue->tasks[0]);
+		list_add(&task->u.tk_wait.list, &queue->tasks[0]);
 	else
-		list_add_tail(&task->tk_list, &queue->tasks[0]);
-	task->tk_rpcwait = queue;
+		list_add_tail(&task->u.tk_wait.list, &queue->tasks[0]);
+	task->u.tk_wait.rpc_waitq = queue;
+	rpc_set_queued(task);
 
 	dprintk("RPC: %4d added to queue %p \"%s\"\n",
 				task->tk_pid, queue, rpc_qname(queue));
-
-	return 0;
-}
-
-int rpc_add_wait_queue(struct rpc_wait_queue *q, struct rpc_task *task)
-{
-	int		result;
-
-	spin_lock_bh(&rpc_queue_lock);
-	result = __rpc_add_wait_queue(q, task);
-	spin_unlock_bh(&rpc_queue_lock);
-	return result;
 }
 
 /*
@@ -229,12 +194,12 @@
 {
 	struct rpc_task *t;
 
-	if (!list_empty(&task->tk_links)) {
-		t = list_entry(task->tk_links.next, struct rpc_task, tk_list);
-		list_move(&t->tk_list, &task->tk_list);
-		list_splice_init(&task->tk_links, &t->tk_links);
+	if (!list_empty(&task->u.tk_wait.links)) {
+		t = list_entry(task->u.tk_wait.links.next, struct rpc_task, u.tk_wait.list);
+		list_move(&t->u.tk_wait.list, &task->u.tk_wait.list);
+		list_splice_init(&task->u.tk_wait.links, &t->u.tk_wait.links);
 	}
-	list_del(&task->tk_list);
+	list_del(&task->u.tk_wait.list);
 }
 
 /*
@@ -243,31 +208,17 @@
  */
 static void __rpc_remove_wait_queue(struct rpc_task *task)
 {
-	struct rpc_wait_queue *queue = task->tk_rpcwait;
-
-	if (!queue)
-		return;
+	struct rpc_wait_queue *queue;
+	queue = task->u.tk_wait.rpc_waitq;
 
 	if (RPC_IS_PRIORITY(queue))
 		__rpc_remove_wait_queue_priority(task);
 	else
-		list_del(&task->tk_list);
-	task->tk_rpcwait = NULL;
-
+		list_del(&task->u.tk_wait.list);
 	dprintk("RPC: %4d removed from queue %p \"%s\"\n",
 				task->tk_pid, queue, rpc_qname(queue));
 }
 
-void
-rpc_remove_wait_queue(struct rpc_task *task)
-{
-	if (!task->tk_rpcwait)
-		return;
-	spin_lock_bh(&rpc_queue_lock);
-	__rpc_remove_wait_queue(task);
-	spin_unlock_bh(&rpc_queue_lock);
-}
-
 static inline void rpc_set_waitqueue_priority(struct rpc_wait_queue *queue, int priority)
 {
 	queue->priority = priority;
@@ -290,6 +241,7 @@
 {
 	int i;
 
+	spin_lock_init(&queue->lock);
 	for (i = 0; i < ARRAY_SIZE(queue->tasks); i++)
 		INIT_LIST_HEAD(&queue->tasks[i]);
 	queue->maxpriority = maxprio;
@@ -316,34 +268,31 @@
  * Note: If the task is ASYNC, this must be called with 
  * the spinlock held to protect the wait queue operation.
  */
-static inline void
-rpc_make_runnable(struct rpc_task *task)
+static void rpc_make_runnable(struct rpc_task *task)
 {
-	if (task->tk_timeout_fn) {
-		printk(KERN_ERR "RPC: task w/ running timer in rpc_make_runnable!!\n");
+	int do_ret;
+
+	BUG_ON(task->tk_timeout_fn);
+	do_ret = rpc_test_and_set_running(task);
+	rpc_clear_queued(task);
+	if (do_ret)
 		return;
-	}
-	rpc_set_running(task);
 	if (RPC_IS_ASYNC(task)) {
-		if (RPC_IS_SLEEPING(task)) {
-			int status;
-			status = __rpc_add_wait_queue(&schedq, task);
-			if (status < 0) {
-				printk(KERN_WARNING "RPC: failed to add task to queue: error: %d!\n", status);
-				task->tk_status = status;
-				return;
-			}
-			rpc_clear_sleeping(task);
-			wake_up(&rpciod_idle);
+		int status;
+
+		INIT_WORK(&task->u.tk_work, rpc_async_schedule, (void *)task);
+		status = queue_work(task->tk_workqueue, &task->u.tk_work);
+		if (status < 0) {
+			printk(KERN_WARNING "RPC: failed to add task to queue: error: %d!\n", status);
+			task->tk_status = status;
+			return;
 		}
-	} else {
-		rpc_clear_sleeping(task);
-		wake_up(&task->tk_wait);
-	}
+	} else
+		wake_up(&task->u.tk_wait.waitq);
 }
 
 /*
- * Place a newly initialized task on the schedq.
+ * Place a newly initialized task on the workqueue.
  */
 static inline void
 rpc_schedule_run(struct rpc_task *task)
@@ -352,33 +301,18 @@
 	if (RPC_IS_ACTIVATED(task))
 		return;
 	task->tk_active = 1;
-	rpc_set_sleeping(task);
 	rpc_make_runnable(task);
 }
 
 /*
- *	For other people who may need to wake the I/O daemon
- *	but should (for now) know nothing about its innards
- */
-void rpciod_wake_up(void)
-{
-	if(rpciod_pid==0)
-		printk(KERN_ERR "rpciod: wot no daemon?\n");
-	wake_up(&rpciod_idle);
-}
-
-/*
  * Prepare for sleeping on a wait queue.
  * By always appending tasks to the list we ensure FIFO behavior.
  * NB: An RPC task will only receive interrupt-driven events as long
  * as it's on a wait queue.
  */
-static void
-__rpc_sleep_on(struct rpc_wait_queue *q, struct rpc_task *task,
+static void __rpc_sleep_on(struct rpc_wait_queue *q, struct rpc_task *task,
 			rpc_action action, rpc_action timer)
 {
-	int status;
-
 	dprintk("RPC: %4d sleep_on(queue \"%s\" time %ld)\n", task->tk_pid,
 				rpc_qname(q), jiffies);
 
@@ -388,69 +322,48 @@
 	}
 
 	/* Mark the task as being activated if so needed */
-	if (!RPC_IS_ACTIVATED(task)) {
+	if (!RPC_IS_ACTIVATED(task))
 		task->tk_active = 1;
-		rpc_set_sleeping(task);
-	}
 
-	status = __rpc_add_wait_queue(q, task);
-	if (status) {
-		printk(KERN_WARNING "RPC: failed to add task to queue: error: %d!\n", status);
-		task->tk_status = status;
-	} else {
-		rpc_clear_running(task);
-		if (task->tk_callback) {
-			dprintk(KERN_ERR "RPC: %4d overwrites an active callback\n", task->tk_pid);
-			BUG();
-		}
-		task->tk_callback = action;
-		__rpc_add_timer(task, timer);
-	}
+	__rpc_add_wait_queue(q, task);
+
+	BUG_ON(task->tk_callback != NULL);
+	task->tk_callback = action;
+	__rpc_add_timer(task, timer);
 }
 
-void
-rpc_sleep_on(struct rpc_wait_queue *q, struct rpc_task *task,
+void rpc_sleep_on(struct rpc_wait_queue *q, struct rpc_task *task,
 				rpc_action action, rpc_action timer)
 {
 	/*
 	 * Protect the queue operations.
 	 */
-	spin_lock_bh(&rpc_queue_lock);
+	spin_lock_bh(&q->lock);
 	__rpc_sleep_on(q, task, action, timer);
-	spin_unlock_bh(&rpc_queue_lock);
+	spin_unlock_bh(&q->lock);
 }
 
 /**
- * __rpc_wake_up_task - wake up a single rpc_task
+ * __rpc_do_wake_up_task - wake up a single rpc_task
  * @task: task to be woken up
  *
- * Caller must hold rpc_queue_lock
+ * Caller must hold queue->lock, and have cleared the task queued flag.
  */
-static void
-__rpc_wake_up_task(struct rpc_task *task)
+static void __rpc_do_wake_up_task(struct rpc_task *task)
 {
-	dprintk("RPC: %4d __rpc_wake_up_task (now %ld inh %d)\n",
-					task->tk_pid, jiffies, rpc_inhibit);
+	dprintk("RPC: %4d __rpc_wake_up_task (now %ld)\n", task->tk_pid, jiffies);
 
 #ifdef RPC_DEBUG
-	if (task->tk_magic != 0xf00baa) {
-		printk(KERN_ERR "RPC: attempt to wake up non-existing task!\n");
-		rpc_debug = ~0;
-		rpc_show_tasks();
-		return;
-	}
+	BUG_ON(task->tk_magic != RPC_TASK_MAGIC_ID);
 #endif
 	/* Has the task been executed yet? If not, we cannot wake it up! */
 	if (!RPC_IS_ACTIVATED(task)) {
 		printk(KERN_ERR "RPC: Inactive task (%p) being woken up!\n", task);
 		return;
 	}
-	if (RPC_IS_RUNNING(task))
-		return;
 
 	__rpc_disable_timer(task);
-	if (task->tk_rpcwait != &schedq)
-		__rpc_remove_wait_queue(task);
+	__rpc_remove_wait_queue(task);
 
 	rpc_make_runnable(task);
 
@@ -458,6 +371,18 @@
 }
 
 /*
+ * Wake up the specified task
+ */
+static void __rpc_wake_up_task(struct rpc_task *task)
+{
+	if (rpc_start_wakeup(task)) {
+		if (RPC_IS_QUEUED(task))
+			__rpc_do_wake_up_task(task);
+		rpc_finish_wakeup(task);
+	}
+}
+
+/*
  * Default timeout handler if none specified by user
  */
 static void
@@ -471,14 +396,18 @@
 /*
  * Wake up the specified task
  */
-void
-rpc_wake_up_task(struct rpc_task *task)
+void rpc_wake_up_task(struct rpc_task *task)
 {
-	if (RPC_IS_RUNNING(task))
-		return;
-	spin_lock_bh(&rpc_queue_lock);
-	__rpc_wake_up_task(task);
-	spin_unlock_bh(&rpc_queue_lock);
+	if (rpc_start_wakeup(task)) {
+		if (RPC_IS_QUEUED(task)) {
+			struct rpc_wait_queue *queue = task->u.tk_wait.rpc_waitq;
+
+			spin_lock_bh(&queue->lock);
+			__rpc_do_wake_up_task(task);
+			spin_unlock_bh(&queue->lock);
+		}
+		rpc_finish_wakeup(task);
+	}
 }
 
 /*
@@ -494,11 +423,11 @@
 	 */
 	q = &queue->tasks[queue->priority];
 	if (!list_empty(q)) {
-		task = list_entry(q->next, struct rpc_task, tk_list);
+		task = list_entry(q->next, struct rpc_task, u.tk_wait.list);
 		if (queue->cookie == task->tk_cookie) {
 			if (--queue->nr)
 				goto out;
-			list_move_tail(&task->tk_list, q);
+			list_move_tail(&task->u.tk_wait.list, q);
 		}
 		/*
 		 * Check if we need to switch queues.
@@ -516,7 +445,7 @@
 		else
 			q = q - 1;
 		if (!list_empty(q)) {
-			task = list_entry(q->next, struct rpc_task, tk_list);
+			task = list_entry(q->next, struct rpc_task, u.tk_wait.list);
 			goto new_queue;
 		}
 	} while (q != &queue->tasks[queue->priority]);
@@ -541,14 +470,14 @@
 	struct rpc_task	*task = NULL;
 
 	dprintk("RPC:      wake_up_next(%p \"%s\")\n", queue, rpc_qname(queue));
-	spin_lock_bh(&rpc_queue_lock);
+	spin_lock_bh(&queue->lock);
 	if (RPC_IS_PRIORITY(queue))
 		task = __rpc_wake_up_next_priority(queue);
 	else {
 		task_for_first(task, &queue->tasks[0])
 			__rpc_wake_up_task(task);
 	}
-	spin_unlock_bh(&rpc_queue_lock);
+	spin_unlock_bh(&queue->lock);
 
 	return task;
 }
@@ -557,25 +486,25 @@
  * rpc_wake_up - wake up all rpc_tasks
  * @queue: rpc_wait_queue on which the tasks are sleeping
  *
- * Grabs rpc_queue_lock
+ * Grabs queue->lock
  */
 void rpc_wake_up(struct rpc_wait_queue *queue)
 {
 	struct rpc_task *task;
 
 	struct list_head *head;
-	spin_lock_bh(&rpc_queue_lock);
+	spin_lock_bh(&queue->lock);
 	head = &queue->tasks[queue->maxpriority];
 	for (;;) {
 		while (!list_empty(head)) {
-			task = list_entry(head->next, struct rpc_task, tk_list);
+			task = list_entry(head->next, struct rpc_task, u.tk_wait.list);
 			__rpc_wake_up_task(task);
 		}
 		if (head == &queue->tasks[0])
 			break;
 		head--;
 	}
-	spin_unlock_bh(&rpc_queue_lock);
+	spin_unlock_bh(&queue->lock);
 }
 
 /**
@@ -583,18 +512,18 @@
  * @queue: rpc_wait_queue on which the tasks are sleeping
  * @status: status value to set
  *
- * Grabs rpc_queue_lock
+ * Grabs queue->lock
  */
 void rpc_wake_up_status(struct rpc_wait_queue *queue, int status)
 {
 	struct list_head *head;
 	struct rpc_task *task;
 
-	spin_lock_bh(&rpc_queue_lock);
+	spin_lock_bh(&queue->lock);
 	head = &queue->tasks[queue->maxpriority];
 	for (;;) {
 		while (!list_empty(head)) {
-			task = list_entry(head->next, struct rpc_task, tk_list);
+			task = list_entry(head->next, struct rpc_task, u.tk_wait.list);
 			task->tk_status = status;
 			__rpc_wake_up_task(task);
 		}
@@ -602,7 +531,7 @@
 			break;
 		head--;
 	}
-	spin_unlock_bh(&rpc_queue_lock);
+	spin_unlock_bh(&queue->lock);
 }
 
 /*
@@ -626,22 +555,23 @@
 /*
  * This is the RPC `scheduler' (or rather, the finite state machine).
  */
-static int
-__rpc_execute(struct rpc_task *task)
+static int __rpc_execute(struct rpc_task *task)
 {
 	int		status = 0;
 
 	dprintk("RPC: %4d rpc_execute flgs %x\n",
 				task->tk_pid, task->tk_flags);
 
-	if (!RPC_IS_RUNNING(task)) {
-		printk(KERN_WARNING "RPC: rpc_execute called for sleeping task!!\n");
-		return 0;
-	}
+	BUG_ON(RPC_IS_QUEUED(task));
 
  restarted:
 	while (1) {
 		/*
+		 * Garbage collection of pending timers...
+		 */
+		rpc_delete_timer(task);
+
+		/*
 		 * Execute any pending callback.
 		 */
 		if (RPC_DO_CALLBACK(task)) {
@@ -657,7 +587,9 @@
 			 */
 			save_callback=task->tk_callback;
 			task->tk_callback=NULL;
+			lock_kernel();
 			save_callback(task);
+			unlock_kernel();
 		}
 
 		/*
@@ -665,43 +597,35 @@
 		 * tk_action may be NULL when the task has been killed
 		 * by someone else.
 		 */
-		if (RPC_IS_RUNNING(task)) {
-			/*
-			 * Garbage collection of pending timers...
-			 */
-			rpc_delete_timer(task);
+		if (!RPC_IS_QUEUED(task)) {
 			if (!task->tk_action)
 				break;
+			lock_kernel();
 			task->tk_action(task);
-			/* micro-optimization to avoid spinlock */
-			if (RPC_IS_RUNNING(task))
-				continue;
+			unlock_kernel();
 		}
 
 		/*
-		 * Check whether task is sleeping.
+		 * Lockless check for whether task is sleeping or not.
 		 */
-		spin_lock_bh(&rpc_queue_lock);
-		if (!RPC_IS_RUNNING(task)) {
-			rpc_set_sleeping(task);
-			if (RPC_IS_ASYNC(task)) {
-				spin_unlock_bh(&rpc_queue_lock);
+		if (!RPC_IS_QUEUED(task))
+			continue;
+		rpc_clear_running(task);
+		if (RPC_IS_ASYNC(task)) {
+			/* Careful! we may have raced... */
+			if (RPC_IS_QUEUED(task))
 				return 0;
-			}
+			if (rpc_test_and_set_running(task))
+				return 0;
+			continue;
 		}
-		spin_unlock_bh(&rpc_queue_lock);
 
-		if (!RPC_IS_SLEEPING(task))
-			continue;
 		/* sync task: sleep here */
 		dprintk("RPC: %4d sync task going to sleep\n", task->tk_pid);
-		if (current->pid == rpciod_pid)
-			printk(KERN_ERR "RPC: rpciod waiting on sync task!\n");
-
 		if (RPC_TASK_UNINTERRUPTIBLE(task)) {
-			__wait_event(task->tk_wait, !RPC_IS_SLEEPING(task));
+			__wait_event(task->u.tk_wait.waitq, !RPC_IS_QUEUED(task));
 		} else {
-			__wait_event_interruptible(task->tk_wait, !RPC_IS_SLEEPING(task), status);
+			__wait_event_interruptible(task->u.tk_wait.waitq, !RPC_IS_QUEUED(task), status);
 			/*
 			 * When a sync task receives a signal, it exits with
 			 * -ERESTARTSYS. In order to catch any callbacks that
@@ -715,11 +639,14 @@
 				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)) {
@@ -738,7 +665,6 @@
 
 	/* Release all resources associated with the task */
 	rpc_release_task(task);
-
 	return status;
 }
 
@@ -754,57 +680,16 @@
 int
 rpc_execute(struct rpc_task *task)
 {
-	int status = -EIO;
-	if (rpc_inhibit) {
-		printk(KERN_INFO "RPC: execution inhibited!\n");
-		goto out_release;
-	}
-
-	status = -EWOULDBLOCK;
-	if (task->tk_active) {
-		printk(KERN_ERR "RPC: active task was run twice!\n");
-		goto out_err;
-	}
+	BUG_ON(task->tk_active);
 
 	task->tk_active = 1;
 	rpc_set_running(task);
 	return __rpc_execute(task);
- out_release:
-	rpc_release_task(task);
- out_err:
-	return status;
 }
 
-/*
- * This is our own little scheduler for async RPC tasks.
- */
-static void
-__rpc_schedule(void)
+static void rpc_async_schedule(void *arg)
 {
-	struct rpc_task	*task;
-	int		count = 0;
-
-	dprintk("RPC:      rpc_schedule enter\n");
-	while (1) {
-
-		task_for_first(task, &schedq.tasks[0]) {
-			__rpc_remove_wait_queue(task);
-			spin_unlock_bh(&rpc_queue_lock);
-
-			__rpc_execute(task);
-			spin_lock_bh(&rpc_queue_lock);
-		} else {
-			break;
-		}
-
-		if (++count >= 200 || need_resched()) {
-			count = 0;
-			spin_unlock_bh(&rpc_queue_lock);
-			schedule();
-			spin_lock_bh(&rpc_queue_lock);
-		}
-	}
-	dprintk("RPC:      rpc_schedule leave\n");
+	__rpc_execute((struct rpc_task *)arg);
 }
 
 /*
@@ -837,7 +722,7 @@
 	return task->tk_buffer;
 }
 
-void
+static void
 rpc_free(struct rpc_task *task)
 {
 	if (task->tk_buffer) {
@@ -862,7 +747,6 @@
 	task->tk_client = clnt;
 	task->tk_flags  = flags;
 	task->tk_exit   = callback;
-	init_waitqueue_head(&task->tk_wait);
 	if (current->uid != current->fsuid || current->gid != current->fsgid)
 		task->tk_flags |= RPC_TASK_SETUID;
 
@@ -873,12 +757,11 @@
 
 	task->tk_priority = RPC_PRIORITY_NORMAL;
 	task->tk_cookie = (unsigned long)current;
-	INIT_LIST_HEAD(&task->tk_links);
 
-	/* Add to global list of all tasks */
-	spin_lock(&rpc_sched_lock);
-	list_add(&task->tk_task, &all_tasks);
-	spin_unlock(&rpc_sched_lock);
+	/* 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);
@@ -889,9 +772,14 @@
 	}
 
 #ifdef RPC_DEBUG
-	task->tk_magic = 0xf00baa;
+	task->tk_magic = RPC_TASK_MAGIC_ID;
 	task->tk_pid = rpc_task_id++;
 #endif
+	/* Add to global list of all tasks */
+	spin_lock(&rpc_sched_lock);
+	list_add_tail(&task->tk_task, &all_tasks);
+	spin_unlock(&rpc_sched_lock);
+
 	dprintk("RPC: %4d new task procpid %d\n", task->tk_pid,
 				current->pid);
 }
@@ -944,18 +832,12 @@
 	goto out;
 }
 
-void
-rpc_release_task(struct rpc_task *task)
+void rpc_release_task(struct rpc_task *task)
 {
 	dprintk("RPC: %4d release task\n", task->tk_pid);
 
 #ifdef RPC_DEBUG
-	if (task->tk_magic != 0xf00baa) {
-		printk(KERN_ERR "RPC: attempt to release a non-existing task!\n");
-		rpc_debug = ~0;
-		rpc_show_tasks();
-		return;
-	}
+	BUG_ON(task->tk_magic != RPC_TASK_MAGIC_ID);
 #endif
 
 	/* Remove from global task list */
@@ -963,19 +845,9 @@
 	list_del(&task->tk_task);
 	spin_unlock(&rpc_sched_lock);
 
-	/* Protect the execution below. */
-	spin_lock_bh(&rpc_queue_lock);
-
-	/* Disable timer to prevent zombie wakeup */
-	__rpc_disable_timer(task);
-
-	/* Remove from any wait queue we're still on */
-	__rpc_remove_wait_queue(task);
-
+	BUG_ON (RPC_IS_QUEUED(task));
 	task->tk_active = 0;
 
-	spin_unlock_bh(&rpc_queue_lock);
-
 	/* Synchronously delete any running timer */
 	rpc_delete_timer(task);
 
@@ -1005,10 +877,9 @@
  * queue 'childq'. If so returns a pointer to the parent.
  * Upon failure returns NULL.
  *
- * Caller must hold rpc_queue_lock
+ * Caller must hold childq.lock
  */
-static inline struct rpc_task *
-rpc_find_parent(struct rpc_task *child)
+static inline struct rpc_task *rpc_find_parent(struct rpc_task *child)
 {
 	struct rpc_task	*task, *parent;
 	struct list_head *le;
@@ -1021,17 +892,16 @@
 	return NULL;
 }
 
-static void
-rpc_child_exit(struct rpc_task *child)
+static void rpc_child_exit(struct rpc_task *child)
 {
 	struct rpc_task	*parent;
 
-	spin_lock_bh(&rpc_queue_lock);
+	spin_lock_bh(&childq.lock);
 	if ((parent = rpc_find_parent(child)) != NULL) {
 		parent->tk_status = child->tk_status;
 		__rpc_wake_up_task(parent);
 	}
-	spin_unlock_bh(&rpc_queue_lock);
+	spin_unlock_bh(&childq.lock);
 }
 
 /*
@@ -1054,22 +924,20 @@
 	return NULL;
 }
 
-void
-rpc_run_child(struct rpc_task *task, struct rpc_task *child, rpc_action func)
+void rpc_run_child(struct rpc_task *task, struct rpc_task *child, rpc_action func)
 {
-	spin_lock_bh(&rpc_queue_lock);
+	spin_lock_bh(&childq.lock);
 	/* N.B. Is it possible for the child to have already finished? */
 	__rpc_sleep_on(&childq, task, func, NULL);
 	rpc_schedule_run(child);
-	spin_unlock_bh(&rpc_queue_lock);
+	spin_unlock_bh(&childq.lock);
 }
 
 /*
  * Kill all tasks for the given client.
  * XXX: kill their descendants as well?
  */
-void
-rpc_killall_tasks(struct rpc_clnt *clnt)
+void rpc_killall_tasks(struct rpc_clnt *clnt)
 {
 	struct rpc_task	*rovr;
 	struct list_head *le;
@@ -1080,104 +948,28 @@
 	 * Spin lock all_tasks to prevent changes...
 	 */
 	spin_lock(&rpc_sched_lock);
-	alltask_for_each(rovr, le, &all_tasks)
+	alltask_for_each(rovr, le, &all_tasks) {
+		if (! RPC_IS_ACTIVATED(rovr))
+			continue;
 		if (!clnt || rovr->tk_client == clnt) {
 			rovr->tk_flags |= RPC_TASK_KILLED;
 			rpc_exit(rovr, -EIO);
 			rpc_wake_up_task(rovr);
 		}
+	}
 	spin_unlock(&rpc_sched_lock);
 }
 
 static DECLARE_MUTEX_LOCKED(rpciod_running);
 
-static inline int
-rpciod_task_pending(void)
-{
-	return !list_empty(&schedq.tasks[0]);
-}
-
-
-/*
- * This is the rpciod kernel thread
- */
-static int
-rpciod(void *ptr)
-{
-	int		rounds = 0;
-
-	lock_kernel();
-	/*
-	 * Let our maker know we're running ...
-	 */
-	rpciod_pid = current->pid;
-	up(&rpciod_running);
-
-	daemonize("rpciod");
-	allow_signal(SIGKILL);
-
-	dprintk("RPC: rpciod starting (pid %d)\n", rpciod_pid);
-	spin_lock_bh(&rpc_queue_lock);
-	while (rpciod_users) {
-		DEFINE_WAIT(wait);
-		if (signalled()) {
-			spin_unlock_bh(&rpc_queue_lock);
-			rpciod_killall();
-			flush_signals(current);
-			spin_lock_bh(&rpc_queue_lock);
-		}
-		__rpc_schedule();
-		if (current->flags & PF_FREEZE) {
-			spin_unlock_bh(&rpc_queue_lock);
-			refrigerator(PF_FREEZE);
-			spin_lock_bh(&rpc_queue_lock);
-		}
-
-		if (++rounds >= 64) {	/* safeguard */
-			spin_unlock_bh(&rpc_queue_lock);
-			schedule();
-			rounds = 0;
-			spin_lock_bh(&rpc_queue_lock);
-		}
-
-		dprintk("RPC: rpciod back to sleep\n");
-		prepare_to_wait(&rpciod_idle, &wait, TASK_INTERRUPTIBLE);
-		if (!rpciod_task_pending() && !signalled()) {
-			spin_unlock_bh(&rpc_queue_lock);
-			schedule();
-			rounds = 0;
-			spin_lock_bh(&rpc_queue_lock);
-		}
-		finish_wait(&rpciod_idle, &wait);
-		dprintk("RPC: switch to rpciod\n");
-	}
-	spin_unlock_bh(&rpc_queue_lock);
-
-	dprintk("RPC: rpciod shutdown commences\n");
-	if (!list_empty(&all_tasks)) {
-		printk(KERN_ERR "rpciod: active tasks at shutdown?!\n");
-		rpciod_killall();
-	}
-
-	dprintk("RPC: rpciod exiting\n");
-	unlock_kernel();
-
-	rpciod_pid = 0;
-	complete_and_exit(&rpciod_killer, 0);
-	return 0;
-}
-
-static void
-rpciod_killall(void)
+static void rpciod_killall(void)
 {
 	unsigned long flags;
 
 	while (!list_empty(&all_tasks)) {
 		clear_thread_flag(TIF_SIGPENDING);
 		rpc_killall_tasks(NULL);
-		spin_lock_bh(&rpc_queue_lock);
-		__rpc_schedule();
-		spin_unlock_bh(&rpc_queue_lock);
+		flush_workqueue(rpciod_workqueue);
 		if (!list_empty(&all_tasks)) {
 			dprintk("rpciod_killall: waiting for tasks to exit\n");
 			yield();
@@ -1195,28 +987,30 @@
 int
 rpciod_up(void)
 {
+	struct workqueue_struct *wq;
 	int error = 0;
 
 	down(&rpciod_sema);
-	dprintk("rpciod_up: pid %d, users %d\n", rpciod_pid, rpciod_users);
+	dprintk("rpciod_up: users %d\n", rpciod_users);
 	rpciod_users++;
-	if (rpciod_pid)
+	if (rpciod_workqueue)
 		goto out;
 	/*
 	 * If there's no pid, we should be the first user.
 	 */
 	if (rpciod_users > 1)
-		printk(KERN_WARNING "rpciod_up: no pid, %d users??\n", rpciod_users);
+		printk(KERN_WARNING "rpciod_up: no workqueue, %d users??\n", rpciod_users);
 	/*
 	 * Create the rpciod thread and wait for it to start.
 	 */
-	error = kernel_thread(rpciod, NULL, 0);
-	if (error < 0) {
-		printk(KERN_WARNING "rpciod_up: create thread failed, error=%d\n", error);
+	error = -ENOMEM;
+	wq = create_workqueue("rpciod");
+	if (wq == NULL) {
+		printk(KERN_WARNING "rpciod_up: create workqueue failed, error=%d\n", error);
 		rpciod_users--;
 		goto out;
 	}
-	down(&rpciod_running);
+	rpciod_workqueue = wq;
 	error = 0;
 out:
 	up(&rpciod_sema);
@@ -1227,20 +1021,21 @@
 rpciod_down(void)
 {
 	down(&rpciod_sema);
-	dprintk("rpciod_down pid %d sema %d\n", rpciod_pid, rpciod_users);
+	dprintk("rpciod_down sema %d\n", rpciod_users);
 	if (rpciod_users) {
 		if (--rpciod_users)
 			goto out;
 	} else
-		printk(KERN_WARNING "rpciod_down: pid=%d, no users??\n", rpciod_pid);
+		printk(KERN_WARNING "rpciod_down: no users??\n");
 
-	if (!rpciod_pid) {
+	if (!rpciod_workqueue) {
 		dprintk("rpciod_down: Nothing to do!\n");
 		goto out;
 	}
+	rpciod_killall();
 
-	kill_proc(rpciod_pid, SIGKILL, 1);
-	wait_for_completion(&rpciod_killer);
+	destroy_workqueue(rpciod_workqueue);
+	rpciod_workqueue = NULL;
  out:
 	up(&rpciod_sema);
 }
@@ -1258,7 +1053,12 @@
 	}
 	printk("-pid- proc flgs status -client- -prog- --rqstp- -timeout "
 		"-rpcwait -action- --exit--\n");
-	alltask_for_each(t, le, &all_tasks)
+	alltask_for_each(t, le, &all_tasks) {
+		const char *rpc_waitq = "none";
+
+		if (RPC_IS_QUEUED(t))
+			rpc_waitq = rpc_qname(t->u.tk_wait.rpc_waitq);
+
 		printk("%05d %04d %04x %06d %8p %6d %8p %08ld %8s %8p %8p\n",
 			t->tk_pid,
 			(t->tk_msg.rpc_proc ? t->tk_msg.rpc_proc->p_proc : -1),
@@ -1266,8 +1066,9 @@
 			t->tk_client,
 			(t->tk_client ? t->tk_client->cl_prog : 0),
 			t->tk_rqstp, t->tk_timeout,
-			rpc_qname(t->tk_rpcwait),
+			rpc_waitq,
 			t->tk_action, t->tk_exit);
+	}
 	spin_unlock(&rpc_sched_lock);
 }
 #endif
diff -Nru a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c
--- a/net/sunrpc/sunrpc_syms.c	2005-03-01 23:39:09 -08:00
+++ b/net/sunrpc/sunrpc_syms.c	2005-03-01 23:39:09 -08:00
@@ -107,7 +107,6 @@
 EXPORT_SYMBOL(auth_unix_forget_old);
 EXPORT_SYMBOL(auth_unix_lookup);
 EXPORT_SYMBOL(cache_check);
-EXPORT_SYMBOL(cache_clean);
 EXPORT_SYMBOL(cache_flush);
 EXPORT_SYMBOL(cache_purge);
 EXPORT_SYMBOL(cache_fresh);
diff -Nru a/net/sunrpc/svcauth.c b/net/sunrpc/svcauth.c
--- a/net/sunrpc/svcauth.c	2005-03-01 23:39:08 -08:00
+++ b/net/sunrpc/svcauth.c	2005-03-01 23:39:08 -08:00
@@ -28,7 +28,7 @@
 extern struct auth_ops svcauth_null;
 extern struct auth_ops svcauth_unix;
 
-static spinlock_t authtab_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(authtab_lock);
 static struct auth_ops	*authtab[RPC_AUTH_MAXFLAVOR] = {
 	[0] = &svcauth_null,
 	[1] = &svcauth_unix,
@@ -128,7 +128,8 @@
 #define	DN_HASHMASK	(DN_HASHMAX-1)
 
 static struct cache_head	*auth_domain_table[DN_HASHMAX];
-void auth_domain_drop(struct cache_head *item, struct cache_detail *cd)
+
+static void auth_domain_drop(struct cache_head *item, struct cache_detail *cd)
 {
 	struct auth_domain *dom = container_of(item, struct auth_domain, h);
 	if (cache_put(item,cd))
diff -Nru a/net/sunrpc/svcauth_des.c b/net/sunrpc/svcauth_des.c
--- a/net/sunrpc/svcauth_des.c	2005-03-01 23:39:07 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,215 +0,0 @@
-/*
- * linux/net/sunrpc/svcauth_des.c
- *
- * Server-side AUTH_DES handling.
- * 
- * Copyright (C) 1996, 1997 Olaf Kirch <okir@monad.swb.de>
- */
-
-#include <linux/types.h>
-#include <linux/sched.h>
-#include <linux/sunrpc/types.h>
-#include <linux/sunrpc/xdr.h>
-#include <linux/sunrpc/svcauth.h>
-#include <linux/sunrpc/svcsock.h>
-
-#define RPCDBG_FACILITY	RPCDBG_AUTH
-
-/*
- * DES cedential cache.
- * The cache is indexed by fullname/key to allow for multiple sessions
- * by the same user from different hosts.
- * It would be tempting to use the client's IP address rather than the
- * conversation key as an index, but that could become problematic for
- * multi-homed hosts that distribute traffic across their interfaces.
- */
-struct des_cred {
-	struct des_cred *	dc_next;
-	char *			dc_fullname;
-	u32			dc_nickname;
-	des_cblock		dc_key;		/* conversation key */
-	des_cblock		dc_xkey;	/* encrypted conv. key */
-	des_key_schedule	dc_keysched;
-};
-
-#define ADN_FULLNAME		0
-#define ADN_NICKNAME		1
-
-/*
- * The default slack allowed when checking for replayed credentials
- * (in milliseconds).
- */
-#define DES_REPLAY_SLACK	2000
-
-/*
- * Make sure we don't place more than one call to the key server at
- * a time.
- */
-static int			in_keycall;
-
-#define FAIL(err) \
-	{ if (data) put_cred(data);			\
-	  *authp = rpc_autherr_##err;			\
-	  return;					\
-	}
-
-void
-svcauth_des(struct svc_rqst *rqstp, u32 *statp, u32 *authp)
-{
-	struct svc_buf	*argp = &rqstp->rq_argbuf;
-	struct svc_buf	*resp = &rqstp->rq_resbuf;
-	struct svc_cred	*cred = &rqstp->rq_cred;
-	struct des_cred	*data = NULL;
-	u32		cryptkey[2];
-	u32		cryptbuf[4];
-	u32		*p = argp->buf;
-	int		len   = argp->len, slen, i;
-
-	*authp = rpc_auth_ok;
-
-	if ((argp->len -= 3) < 0) {
-		*statp = rpc_garbage_args;
-		return;
-	}
-
-	p++;					/* skip length field */
-	namekind = ntohl(*p++);			/* fullname/nickname */
-
-	/* Get the credentials */
-	if (namekind == ADN_NICKNAME) {
-		/* If we can't find the cached session key, initiate a
-		 * new session. */
-		if (!(data = get_cred_bynick(*p++)))
-			FAIL(rejectedcred);
-	} else if (namekind == ADN_FULLNAME) {
-		p = xdr_decode_string(p, &fullname, &len, RPC_MAXNETNAMELEN);
-		if (p == NULL)
-			FAIL(badcred);
-		cryptkey[0] = *p++;		/* get the encrypted key */
-		cryptkey[1] = *p++;
-		cryptbuf[2] = *p++;		/* get the encrypted window */
-	} else {
-		FAIL(badcred);
-	}
-
-	/* If we're just updating the key, silently discard the request. */
-	if (data && data->dc_locked) {
-		*authp = rpc_autherr_dropit;
-		_put_cred(data);	/* release but don't unlock */
-		return;
-	}
-
-	/* Get the verifier flavor and length */
-	if (ntohl(*p++) != RPC_AUTH_DES && ntohl(*p++) != 12)
-		FAIL(badverf);
-
-	cryptbuf[0] = *p++;			/* encrypted time stamp */
-	cryptbuf[1] = *p++;
-	cryptbuf[3] = *p++;			/* 0 or window - 1 */
-
-	if (namekind == ADN_NICKNAME) {
-		status = des_ecb_encrypt((des_block *) cryptbuf,
-					 (des_block *) cryptbuf,
-					 data->dc_keysched, DES_DECRYPT);
-	} else {
-		/* We first have to decrypt the new session key and
-		 * fill in the UNIX creds. */
-		if (!(data = get_cred_byname(rqstp, authp, fullname, cryptkey)))
-			return;
-		status = des_cbc_encrypt((des_cblock *) cryptbuf,
-					 (des_cblock *) cryptbuf, 16,
-					 data->dc_keysched,
-					 (des_cblock *) &ivec,
-					 DES_DECRYPT);
-	}
-	if (status) {
-		printk("svcauth_des: DES decryption failed (status %d)\n",
-				status);
-		FAIL(badverf);
-	}
-
-	/* Now check the whole lot */
-	if (namekind == ADN_FULLNAME) {
-		unsigned long	winverf;
-
-		data->dc_window = ntohl(cryptbuf[2]);
-		winverf = ntohl(cryptbuf[2]);
-		if (window != winverf - 1) {
-			printk("svcauth_des: bad window verifier!\n");
-			FAIL(badverf);
-		}
-	}
-
-	/* XDR the decrypted timestamp */
-	cryptbuf[0] = ntohl(cryptbuf[0]);
-	cryptbuf[1] = ntohl(cryptbuf[1]);
-	if (cryptbuf[1] > 1000000) {
-		dprintk("svcauth_des: bad usec value %u\n", cryptbuf[1]);
-		if (namekind == ADN_NICKNAME)
-			FAIL(rejectedverf);
-		FAIL(badverf);
-	}
-	
-	/*
-	 * Check for replayed credentials. We must allow for reordering
-	 * of requests by the network, and the OS scheduler, hence we
-	 * cannot expect timestamps to be increasing monotonically.
-	 * This opens a small security hole, therefore the replay_slack
-	 * value shouldn't be too large.
-	 */
-	if ((delta = cryptbuf[0] - data->dc_timestamp[0]) <= 0) {
-		switch (delta) {
-		case -1:	
-			delta = -1000000;
-		case 0:
-			delta += cryptbuf[1] - data->dc_timestamp[1];
-			break;
-		default:
-			delta = -1000000;
-		}
-		if (delta < DES_REPLAY_SLACK)
-			FAIL(rejectedverf);
-#ifdef STRICT_REPLAY_CHECKS
-		/* TODO: compare time stamp to last five timestamps cached
-		 * and reject (drop?) request if a match is found. */
-#endif
-	}
-
-	now = xtime;
-	now.tv_secs -= data->dc_window;
-	if (now.tv_secs < cryptbuf[0] ||
-	    (now.tv_secs == cryptbuf[0] && now.tv_usec < cryptbuf[1]))
-		FAIL(rejectedverf);
-
-	/* Okay, we're done. Update the lot */
-	if (namekind == ADN_FULLNAME)
-		data->dc_valid = 1;
-	data->dc_timestamp[0] = cryptbuf[0];
-	data->dc_timestamp[1] = cryptbuf[1];
-
-	put_cred(data);
-	return;
-garbage:
-	*statp = rpc_garbage_args;
-	return;
-}
-
-/*
- * Call the keyserver to obtain the decrypted conversation key and
- * UNIX creds. We use a Linux-specific keycall extension that does
- * both things in one go.
- */
-static struct des_cred *
-get_cred_byname(struct svc_rqst *rqstp, u32 *authp, char *fullname, u32 *cryptkey)
-{
-	static int	in_keycall;
-	struct des_cred	*cred;
-
-	if (in_keycall) {
-		*authp = rpc_autherr_dropit;
-		return NULL;
-	}
-	in_keycall = 1;
-	in_keycall = 0;
-	return cred;
-}
diff -Nru a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c
--- a/net/sunrpc/svcauth_unix.c	2005-03-01 23:39:07 -08:00
+++ b/net/sunrpc/svcauth_unix.c	2005-03-01 23:39:07 -08:00
@@ -97,7 +97,7 @@
 };
 static struct cache_head	*ip_table[IP_HASHMAX];
 
-void ip_map_put(struct cache_head *item, struct cache_detail *cd)
+static void ip_map_put(struct cache_head *item, struct cache_detail *cd)
 {
 	struct ip_map *im = container_of(item, struct ip_map,h);
 	if (cache_put(item, cd)) {
@@ -329,14 +329,49 @@
 	cache_purge(&auth_domain_cache);
 }
 
+static int
+svcauth_unix_set_client(struct svc_rqst *rqstp)
+{
+	struct ip_map key, *ipm;
+
+	rqstp->rq_client = NULL;
+	if (rqstp->rq_proc == 0)
+		return SVC_OK;
+
+	strcpy(key.m_class, rqstp->rq_server->sv_program->pg_class);
+	key.m_addr = rqstp->rq_addr.sin_addr;
+
+	ipm = ip_map_lookup(&key, 0);
+
+	if (ipm == NULL)
+		return SVC_DENIED;
+
+	switch (cache_check(&ip_map_cache, &ipm->h, &rqstp->rq_chandle)) {
+		default:
+			BUG();
+		case -EAGAIN:
+			return SVC_DROP;
+		case -ENOENT:
+			return SVC_DENIED;
+		case 0:
+			rqstp->rq_client = &ipm->m_client->h;
+			cache_get(&rqstp->rq_client->h);
+			ip_map_put(&ipm->h, &ip_map_cache);
+			break;
+	}
+	return SVC_OK;
+}
 
 static int
 svcauth_null_accept(struct svc_rqst *rqstp, u32 *authp)
 {
 	struct kvec	*argv = &rqstp->rq_arg.head[0];
 	struct kvec	*resv = &rqstp->rq_res.head[0];
+	struct svc_cred	*cred = &rqstp->rq_cred;
 	int		rv=0;
-	struct ip_map key, *ipm;
+
+	cred->cr_group_info = NULL;
+	rqstp->rq_client = NULL;
 
 	if (argv->iov_len < 3*4)
 		return SVC_GARBAGE;
@@ -353,45 +388,25 @@
 	}
 
 	/* Signal that mapping to nobody uid/gid is required */
-	rqstp->rq_cred.cr_uid = (uid_t) -1;
-	rqstp->rq_cred.cr_gid = (gid_t) -1;
-	rqstp->rq_cred.cr_group_info = groups_alloc(0);
-	if (rqstp->rq_cred.cr_group_info == NULL)
+	cred->cr_uid = (uid_t) -1;
+	cred->cr_gid = (gid_t) -1;
+	cred->cr_group_info = groups_alloc(0);
+	if (cred->cr_group_info == NULL)
 		return SVC_DROP; /* kmalloc failure - client must retry */
 
+	rv = svcauth_unix_set_client(rqstp);
+	if (rv == SVC_DENIED)
+		goto badcred;
+
 	/* Put NULL verifier */
 	svc_putu32(resv, RPC_AUTH_NULL);
 	svc_putu32(resv, 0);
 
-	strcpy(key.m_class, rqstp->rq_server->sv_program->pg_class);
-	key.m_addr = rqstp->rq_addr.sin_addr;
-
-	ipm = ip_map_lookup(&key, 0);
-
-	rqstp->rq_client = NULL;
-
-	if (ipm)
-		switch (cache_check(&ip_map_cache, &ipm->h, &rqstp->rq_chandle)) {
-		case -EAGAIN:
-			rv = SVC_DROP;
-			break;
-		case -ENOENT:
-			rv = SVC_OK; /* rq_client is NULL */
-			break;
-		case 0:
-			rqstp->rq_client = &ipm->m_client->h;
-			cache_get(&rqstp->rq_client->h);
-			ip_map_put(&ipm->h, &ip_map_cache);
-			rv = SVC_OK;
-			break;
-		default: BUG();
-		}
-	else rv = SVC_DROP;
-
-	if (rqstp->rq_client == NULL && rqstp->rq_proc != 0)
-		*authp = rpc_autherr_badcred;
-
 	return rv;
+
+badcred:
+	*authp = rpc_autherr_badcred;
+	return SVC_DENIED;
 }
 
 static int
@@ -417,7 +432,7 @@
 };
 
 
-int
+static int
 svcauth_unix_accept(struct svc_rqst *rqstp, u32 *authp)
 {
 	struct kvec	*argv = &rqstp->rq_arg.head[0];
@@ -426,7 +441,6 @@
 	u32		slen, i;
 	int		len   = argv->iov_len;
 	int		rv=0;
-	struct ip_map key, *ipm;
 
 	cred->cr_group_info = NULL;
 	rqstp->rq_client = NULL;
@@ -458,32 +472,8 @@
 		return SVC_DENIED;
 	}
 
-
-	strcpy(key.m_class, rqstp->rq_server->sv_program->pg_class);
-	key.m_addr = rqstp->rq_addr.sin_addr;
-
-
-	ipm = ip_map_lookup(&key, 0);
-
-	if (ipm)
-		switch (cache_check(&ip_map_cache, &ipm->h, &rqstp->rq_chandle)) {
-		case -EAGAIN:
-			rv = SVC_DROP;
-			break;
-		case -ENOENT:
-			rv = SVC_OK; /* rq_client is NULL */
-			break;
-		case 0:
-			rqstp->rq_client = &ipm->m_client->h;
-			cache_get(&rqstp->rq_client->h);
-			ip_map_put(&ipm->h, &ip_map_cache);
-			rv = SVC_OK;
-			break;
-		default: BUG();
-		}
-	else rv = SVC_DROP;
-
-	if (rv  == SVC_OK && rqstp->rq_client == NULL && rqstp->rq_proc != 0)
+	rv = svcauth_unix_set_client(rqstp);
+	if (rv == SVC_DENIED)
 		goto badcred;
 
 	/* Put NULL verifier */
@@ -497,7 +487,7 @@
 	return SVC_DENIED;
 }
 
-int
+static int
 svcauth_unix_release(struct svc_rqst *rqstp)
 {
 	/* Verifier (such as it is) is already in place.
diff -Nru a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
--- a/net/sunrpc/svcsock.c	2005-03-01 23:38:52 -08:00
+++ b/net/sunrpc/svcsock.c	2005-03-01 23:38:52 -08:00
@@ -31,7 +31,6 @@
 #include <linux/slab.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
-#include <linux/suspend.h>
 #include <net/sock.h>
 #include <net/checksum.h>
 #include <net/ip.h>
@@ -1077,7 +1076,7 @@
 svc_tcp_init(struct svc_sock *svsk)
 {
 	struct sock	*sk = svsk->sk_sk;
-	struct tcp_opt  *tp = tcp_sk(sk);
+	struct tcp_sock *tp = tcp_sk(sk);
 
 	svsk->sk_recvfrom = svc_tcp_recvfrom;
 	svsk->sk_sendto = svc_tcp_sendto;
@@ -1227,8 +1226,7 @@
 
 		schedule_timeout(timeout);
 
-		if (current->flags & PF_FREEZE)
-			refrigerator(PF_FREEZE);
+		try_to_freeze(PF_FREEZE);
 
 		spin_lock_bh(&serv->sv_lock);
 		remove_wait_queue(&rqstp->rq_wait, &wait);
diff -Nru a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c
--- a/net/sunrpc/xdr.c	2005-03-01 23:39:08 -08:00
+++ b/net/sunrpc/xdr.c	2005-03-01 23:39:08 -08:00
@@ -33,15 +33,6 @@
 }
 
 u32 *
-xdr_decode_netobj_fixed(u32 *p, void *obj, unsigned int len)
-{
-	if (ntohl(*p++) != len)
-		return NULL;
-	memcpy(obj, p, len);
-	return p + XDR_QUADLEN(len);
-}
-
-u32 *
 xdr_decode_netobj(u32 *p, struct xdr_netobj *obj)
 {
 	unsigned int	len;
@@ -185,124 +176,6 @@
 	xdr->buflen += len;
 }
 
-/*
- * Realign the kvec if the server missed out some reply elements
- * (such as post-op attributes,...)
- * Note: This is a simple implementation that assumes that
- *            len <= iov->iov_len !!!
- *       The RPC header (assumed to be the 1st element in the iov array)
- *            is not shifted.
- */
-void xdr_shift_iovec(struct kvec *iov, int nr, size_t len)
-{
-	struct kvec *pvec;
-
-	for (pvec = iov + nr - 1; nr > 1; nr--, pvec--) {
-		struct kvec *svec = pvec - 1;
-
-		if (len > pvec->iov_len) {
-			printk(KERN_DEBUG "RPC: Urk! Large shift of short iovec.\n");
-			return;
-		}
-		memmove((char *)pvec->iov_base + len, pvec->iov_base,
-			pvec->iov_len - len);
-
-		if (len > svec->iov_len) {
-			printk(KERN_DEBUG "RPC: Urk! Large shift of short iovec.\n");
-			return;
-		}
-		memcpy(pvec->iov_base,
-		       (char *)svec->iov_base + svec->iov_len - len, len);
-	}
-}
-
-/*
- * Map a struct xdr_buf into an kvec array.
- */
-int xdr_kmap(struct kvec *iov_base, struct xdr_buf *xdr, size_t base)
-{
-	struct kvec	*iov = iov_base;
-	struct page	**ppage = xdr->pages;
-	unsigned int	len, pglen = xdr->page_len;
-
-	len = xdr->head[0].iov_len;
-	if (base < len) {
-		iov->iov_len = len - base;
-		iov->iov_base = (char *)xdr->head[0].iov_base + base;
-		iov++;
-		base = 0;
-	} else
-		base -= len;
-
-	if (pglen == 0)
-		goto map_tail;
-	if (base >= pglen) {
-		base -= pglen;
-		goto map_tail;
-	}
-	if (base || xdr->page_base) {
-		pglen -= base;
-		base  += xdr->page_base;
-		ppage += base >> PAGE_CACHE_SHIFT;
-		base &= ~PAGE_CACHE_MASK;
-	}
-	do {
-		len = PAGE_CACHE_SIZE;
-		iov->iov_base = kmap(*ppage);
-		if (base) {
-			iov->iov_base += base;
-			len -= base;
-			base = 0;
-		}
-		if (pglen < len)
-			len = pglen;
-		iov->iov_len = len;
-		iov++;
-		ppage++;
-	} while ((pglen -= len) != 0);
-map_tail:
-	if (xdr->tail[0].iov_len) {
-		iov->iov_len = xdr->tail[0].iov_len - base;
-		iov->iov_base = (char *)xdr->tail[0].iov_base + base;
-		iov++;
-	}
-	return (iov - iov_base);
-}
-
-void xdr_kunmap(struct xdr_buf *xdr, size_t base)
-{
-	struct page	**ppage = xdr->pages;
-	unsigned int	pglen = xdr->page_len;
-
-	if (!pglen)
-		return;
-	if (base > xdr->head[0].iov_len)
-		base -= xdr->head[0].iov_len;
-	else
-		base = 0;
-
-	if (base >= pglen)
-		return;
-	if (base || xdr->page_base) {
-		pglen -= base;
-		base  += xdr->page_base;
-		ppage += base >> PAGE_CACHE_SHIFT;
-		/* Note: The offset means that the length of the first
-		 * page is really (PAGE_CACHE_SIZE - (base & ~PAGE_CACHE_MASK)).
-		 * In order to avoid an extra test inside the loop,
-		 * we bump pglen here, and just subtract PAGE_CACHE_SIZE... */
-		pglen += base & ~PAGE_CACHE_MASK;
-	}
-	for (;;) {
-		flush_dcache_page(*ppage);
-		kunmap(*ppage);
-		if (pglen <= PAGE_CACHE_SIZE)
-			break;
-		pglen -= PAGE_CACHE_SIZE;
-		ppage++;
-	}
-}
-
 void
 xdr_partial_copy_from_skb(struct xdr_buf *xdr, unsigned int base,
 			  skb_reader_t *desc,
@@ -498,6 +371,7 @@
 	do {
 		/* Are any pointers crossing a page boundary? */
 		if (pgto_base == 0) {
+			flush_dcache_page(*pgto);
 			pgto_base = PAGE_CACHE_SIZE;
 			pgto--;
 		}
@@ -521,6 +395,7 @@
 		kunmap_atomic(vto, KM_USER0);
 
 	} while ((len -= copy) != 0);
+	flush_dcache_page(*pgto);
 }
 
 /*
@@ -554,12 +429,14 @@
 
 		pgbase += copy;
 		if (pgbase == PAGE_CACHE_SIZE) {
+			flush_dcache_page(*pgto);
 			pgbase = 0;
 			pgto++;
 		}
 		p += copy;
 
 	} while ((len -= copy) != 0);
+	flush_dcache_page(*pgto);
 }
 
 /*
@@ -572,7 +449,7 @@
  * Copies data into an arbitrary memory location from an array of pages
  * The copy is assumed to be non-overlapping.
  */
-void
+static void
 _copy_from_pages(char *p, struct page **pages, size_t pgbase, size_t len)
 {
 	struct page **pgfrom;
@@ -610,7 +487,7 @@
  * 'len' bytes. The extra data is not lost, but is instead
  * moved into the inlined pages and/or the tail.
  */
-void
+static void
 xdr_shrink_bufhead(struct xdr_buf *buf, size_t len)
 {
 	struct kvec *head, *tail;
@@ -683,7 +560,7 @@
  * 'len' bytes. The extra data is not lost, but is instead
  * moved into the tail.
  */
-void
+static void
 xdr_shrink_pagelen(struct xdr_buf *buf, size_t len)
 {
 	struct kvec *tail;
diff -Nru a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
--- a/net/sunrpc/xprt.c	2005-03-01 23:39:07 -08:00
+++ b/net/sunrpc/xprt.c	2005-03-01 23:39:07 -08:00
@@ -90,6 +90,8 @@
 static void	xprt_bind_socket(struct rpc_xprt *, struct socket *);
 static int      __xprt_get_cong(struct rpc_xprt *, struct rpc_task *);
 
+static int	xprt_clear_backlog(struct rpc_xprt *xprt);
+
 #ifdef RPC_DEBUG_DATA
 /*
  * Print the buffer contents (first 128 bytes only--just enough for
@@ -891,7 +893,8 @@
 	xprt->tcp_flags &= ~XPRT_COPY_XID;
 	xprt->tcp_flags |= XPRT_COPY_DATA;
 	xprt->tcp_copied = 4;
-	dprintk("RPC:      reading reply for XID %08x\n", xprt->tcp_xid);
+	dprintk("RPC:      reading reply for XID %08x\n",
+						ntohl(xprt->tcp_xid));
 	tcp_check_recm(xprt);
 }
 
@@ -911,7 +914,7 @@
 	if (!req) {
 		xprt->tcp_flags &= ~XPRT_COPY_DATA;
 		dprintk("RPC:      XID %08x request not found!\n",
-				xprt->tcp_xid);
+				ntohl(xprt->tcp_xid));
 		spin_unlock(&xprt->sock_lock);
 		return;
 	}
@@ -1101,7 +1104,7 @@
 		goto out;
 
 	spin_lock_bh(&xprt->sock_lock);
-	if (xprt->snd_task && xprt->snd_task->tk_rpcwait == &xprt->pending)
+	if (xprt->snd_task)
 		rpc_wake_up_task(xprt->snd_task);
 	spin_unlock_bh(&xprt->sock_lock);
 out:
@@ -1360,7 +1363,7 @@
 	req->rq_xprt    = xprt;
 	req->rq_xid     = xprt_alloc_xid(xprt);
 	dprintk("RPC: %4d reserved req %p xid %08x\n", task->tk_pid,
-			req, req->rq_xid);
+			req, ntohl(req->rq_xid));
 }
 
 /*
@@ -1397,7 +1400,7 @@
 /*
  * Set default timeout parameters
  */
-void
+static void
 xprt_default_timeout(struct rpc_timeout *to, int proto)
 {
 	if (proto == IPPROTO_UDP)
@@ -1545,8 +1548,7 @@
 		sk->sk_no_check = UDP_CSUM_NORCV;
 		xprt_set_connected(xprt);
 	} else {
-		struct tcp_opt *tp = tcp_sk(sk);
-		tp->nonagle = 1;	/* disable Nagle's algorithm */
+		tcp_sk(sk)->nonagle = 1;	/* disable Nagle's algorithm */
 		sk->sk_data_ready = tcp_data_ready;
 		sk->sk_state_change = tcp_state_change;
 		xprt_clear_connected(xprt);
@@ -1633,7 +1635,7 @@
 /*
  * Prepare for transport shutdown.
  */
-void
+static void
 xprt_shutdown(struct rpc_xprt *xprt)
 {
 	xprt->shutdown = 1;
@@ -1648,7 +1650,7 @@
 /*
  * Clear the xprt backlog queue
  */
-int
+static int
 xprt_clear_backlog(struct rpc_xprt *xprt) {
 	rpc_wake_up_next(&xprt->backlog);
 	wake_up(&xprt->cong_wait);
diff -Nru a/net/unix/af_unix.c b/net/unix/af_unix.c
--- a/net/unix/af_unix.c	2005-03-01 23:39:07 -08:00
+++ b/net/unix/af_unix.c	2005-03-01 23:39:07 -08:00
@@ -121,10 +121,10 @@
 
 int sysctl_unix_max_dgram_qlen = 10;
 
-kmem_cache_t *unix_sk_cachep;
+static kmem_cache_t *unix_sk_cachep;
 
 struct hlist_head unix_socket_table[UNIX_HASH_SIZE + 1];
-rwlock_t unix_table_lock = RW_LOCK_UNLOCKED;
+DEFINE_RWLOCK(unix_table_lock);
 static atomic_t unix_nr_socks = ATOMIC_INIT(0);
 
 #define unix_sockets_unbound	(&unix_socket_table[UNIX_HASH_SIZE])
@@ -1850,15 +1850,22 @@
 		case SIOCINQ:
 		{
 			struct sk_buff *skb;
+
 			if (sk->sk_state == TCP_LISTEN) {
 				err = -EINVAL;
 				break;
 			}
 
 			spin_lock(&sk->sk_receive_queue.lock);
-			skb = skb_peek(&sk->sk_receive_queue);
-			if (skb)
-				amount=skb->len;
+			if (sk->sk_type == SOCK_STREAM ||
+			    sk->sk_type == SOCK_SEQPACKET) {
+				skb_queue_walk(&sk->sk_receive_queue, skb)
+					amount += skb->len;
+			} else {
+				skb = skb_peek(&sk->sk_receive_queue);
+				if (skb)
+					amount=skb->len;
+			}
 			spin_unlock(&sk->sk_receive_queue.lock);
 			err = put_user(amount, (int __user *)arg);
 			break;
diff -Nru a/net/unix/sysctl_net_unix.c b/net/unix/sysctl_net_unix.c
--- a/net/unix/sysctl_net_unix.c	2005-03-01 23:38:55 -08:00
+++ b/net/unix/sysctl_net_unix.c	2005-03-01 23:38:55 -08:00
@@ -14,7 +14,7 @@
 
 extern int sysctl_unix_max_dgram_qlen;
 
-ctl_table unix_table[] = {
+static ctl_table unix_table[] = {
 	{
 		.ctl_name	= NET_UNIX_MAX_DGRAM_QLEN,
 		.procname	= "max_dgram_qlen",
diff -Nru a/net/wanrouter/af_wanpipe.c b/net/wanrouter/af_wanpipe.c
--- a/net/wanrouter/af_wanpipe.c	2005-03-01 23:39:17 -08:00
+++ b/net/wanrouter/af_wanpipe.c	2005-03-01 23:39:17 -08:00
@@ -158,7 +158,7 @@
 
 /* List of all wanpipe sockets. */
 HLIST_HEAD(wanpipe_sklist);
-static rwlock_t wanpipe_sklist_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(wanpipe_sklist_lock);
 
 atomic_t wanpipe_socks_nr;
 static unsigned long wanpipe_tx_critical;
diff -Nru a/net/x25/af_x25.c b/net/x25/af_x25.c
--- a/net/x25/af_x25.c	2005-03-01 23:39:16 -08:00
+++ b/net/x25/af_x25.c	2005-03-01 23:39:16 -08:00
@@ -34,28 +34,19 @@
 #include <linux/config.h>
 #include <linux/module.h>
 #include <linux/errno.h>
-#include <linux/types.h>
-#include <linux/socket.h>
-#include <linux/in.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/timer.h>
 #include <linux/string.h>
-#include <linux/sockios.h>
 #include <linux/net.h>
-#include <linux/stat.h>
-#include <linux/inet.h>
 #include <linux/netdevice.h>
 #include <linux/if_arp.h>
 #include <linux/skbuff.h>
 #include <net/sock.h>
 #include <net/tcp.h>
-#include <asm/system.h>
 #include <asm/uaccess.h>
 #include <linux/fcntl.h>
 #include <linux/termios.h>	/* For TIOCINQ/OUTQ */
-#include <linux/mm.h>
-#include <linux/interrupt.h>
 #include <linux/notifier.h>
 #include <linux/init.h>
 #include <net/x25.h>
@@ -67,7 +58,7 @@
 int sysctl_x25_ack_holdback_timeout    = X25_DEFAULT_T2;
 
 HLIST_HEAD(x25_list);
-rwlock_t x25_list_lock = RW_LOCK_UNLOCKED;
+DEFINE_RWLOCK(x25_list_lock);
 
 static struct proto_ops x25_proto_ops;
 
@@ -223,14 +214,19 @@
 
 /*
  *	Find a socket that wants to accept the Call Request we just
- *	received.
+ *	received. Check the full list for an address/cud match.
+ *	If no cuds match return the next_best thing, an address match.
+ *	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)
+static struct sock *x25_find_listener(struct x25_address *addr, struct x25_calluserdata *calluserdata)
 {
 	struct sock *s;
+	struct sock *next_best;
 	struct hlist_node *node;
 
 	read_lock_bh(&x25_list_lock);
+	next_best = NULL;
 
 	sk_for_each(s, node, &x25_list)
 		if ((!strcmp(addr->x25_addr,
@@ -238,9 +234,24 @@
 		     !strcmp(addr->x25_addr,
 			     null_x25_address.x25_addr)) &&
 		     s->sk_state == TCP_LISTEN) {
-			sock_hold(s);
-			goto found;
+
+			/*
+			 * 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) {
+				next_best = s;
+			}
 		}
+	if (next_best) {
+		s = next_best;
+		sock_hold(s);
+		goto found;
+	}
 	s = NULL;
 found:
 	read_unlock_bh(&x25_list_lock);
@@ -250,7 +261,7 @@
 /*
  *	Find a connected X.25 socket given my LCI and neighbour.
  */
-struct sock *__x25_find_socket(unsigned int lci, struct x25_neigh *nb)
+static struct sock *__x25_find_socket(unsigned int lci, struct x25_neigh *nb)
 {
 	struct sock *s;
 	struct hlist_node *node;
@@ -278,7 +289,7 @@
 /*
  *	Find a unique LCI for a given device.
  */
-unsigned int x25_new_lci(struct x25_neigh *nb)
+static unsigned int x25_new_lci(struct x25_neigh *nb)
 {
 	unsigned int lci = 1;
 	struct sock *sk;
@@ -814,6 +825,7 @@
 	struct x25_opt *makex25;
 	struct x25_address source_addr, dest_addr;
 	struct x25_facilities facilities;
+	struct x25_calluserdata calluserdata;
 	int len, rc;
 
 	/*
@@ -828,9 +840,27 @@
 	skb_pull(skb, x25_addr_ntoa(skb->data, &source_addr, &dest_addr));
 
 	/*
-	 *	Find a listener for the particular address.
+	 *	Get the length of the facilities, skip past them for the moment
+	 *	get the call user data because this is needed to determine
+	 *	the correct listener
+	 */
+	len = skb->data[0] + 1;
+	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);
+	sk = x25_find_listener(&source_addr,&calluserdata);
 
 	/*
 	 *	We can't accept the Call Request.
@@ -859,7 +889,7 @@
 		goto out_sock_put;
 
 	/*
-	 *	Remove the facilities, leaving any Call User Data.
+	 *	Remove the facilities
 	 */
 	skb_pull(skb, len);
 
@@ -873,17 +903,10 @@
 	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);
 
-	/*
-	 *	Incoming Call User Data.
-	 */
-	if (skb->len >= 0) {
-		memcpy(makex25->calluserdata.cuddata, skb->data, skb->len);
-		makex25->calluserdata.cudlength = skb->len;
-	}
-
 	makex25->state = X25_STATE_3;
 
 	sk->sk_ack_backlog++;
@@ -1313,7 +1336,7 @@
 	return rc;
 }
 
-struct net_proto_family x25_family_ops = {
+static struct net_proto_family x25_family_ops = {
 	.family =	AF_X25,
 	.create =	x25_create,
 	.owner	=	THIS_MODULE,
@@ -1348,7 +1371,7 @@
 	.func =	x25_lapb_receive_frame,
 };
 
-struct notifier_block x25_dev_notifier = {
+static struct notifier_block x25_dev_notifier = {
 	.notifier_call = x25_device_event,
 };
 
diff -Nru a/net/x25/sysctl_net_x25.c b/net/x25/sysctl_net_x25.c
--- a/net/x25/sysctl_net_x25.c	2005-03-01 23:38:57 -08:00
+++ b/net/x25/sysctl_net_x25.c	2005-03-01 23:38:57 -08:00
@@ -5,7 +5,6 @@
  * Added /proc/sys/net/x25 directory entry (empty =) ). [MS]
  */
 
-#include <linux/mm.h>
 #include <linux/sysctl.h>
 #include <linux/skbuff.h>
 #include <linux/socket.h>
diff -Nru a/net/x25/x25_dev.c b/net/x25/x25_dev.c
--- a/net/x25/x25_dev.c	2005-03-01 23:38:56 -08:00
+++ b/net/x25/x25_dev.c	2005-03-01 23:38:56 -08:00
@@ -18,29 +18,10 @@
  */
 
 #include <linux/config.h>
-#include <linux/errno.h>
-#include <linux/types.h>
-#include <linux/socket.h>
-#include <linux/in.h>
 #include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/timer.h>
-#include <linux/string.h>
-#include <linux/sockios.h>
-#include <linux/net.h>
-#include <linux/stat.h>
-#include <linux/inet.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <net/sock.h>
-#include <asm/system.h>
-#include <asm/uaccess.h>
-#include <linux/fcntl.h>
-#include <linux/termios.h>	/* For TIOCINQ/OUTQ */
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <linux/notifier.h>
-#include <linux/proc_fs.h>
 #include <linux/if_arp.h>
 #include <net/x25.h>
 
@@ -140,29 +121,6 @@
 	kfree_skb(skb);
 out:
 	return 0;
-}
-
-int x25_llc_receive_frame(struct sk_buff *skb, struct net_device *dev,
-			  struct packet_type *ptype)
-{
-	struct x25_neigh *nb;
-	int rc = 0;
-
-	skb->sk = NULL;
-
-	/*
-	 * Packet received from unrecognised device, throw it away.
-	 */
-	nb = x25_get_neigh(dev);
-	if (!nb) {
-		printk(KERN_DEBUG "X.25: unknown_neighbour - %s\n", dev->name);
-		kfree_skb(skb);
-	} else {
-		rc = x25_receive_data(skb, nb);
-		x25_neigh_put(nb);
-	}
-
-	return rc;
 }
 
 void x25_establish_link(struct x25_neigh *nb)
diff -Nru a/net/x25/x25_facilities.c b/net/x25/x25_facilities.c
--- a/net/x25/x25_facilities.c	2005-03-01 23:38:58 -08:00
+++ b/net/x25/x25_facilities.c	2005-03-01 23:38:58 -08:00
@@ -19,24 +19,10 @@
  *					  negotiation.
  */
 
-#include <linux/errno.h>
-#include <linux/types.h>
-#include <linux/socket.h>
-#include <linux/in.h>
 #include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/timer.h>
 #include <linux/string.h>
-#include <linux/sockios.h>
-#include <linux/net.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <net/sock.h>
-#include <asm/system.h>
-#include <linux/fcntl.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
 #include <net/x25.h>
 
 /*
diff -Nru a/net/x25/x25_in.c b/net/x25/x25_in.c
--- a/net/x25/x25_in.c	2005-03-01 23:39:17 -08:00
+++ b/net/x25/x25_in.c	2005-03-01 23:39:17 -08:00
@@ -24,25 +24,11 @@
  */
 
 #include <linux/errno.h>
-#include <linux/types.h>
-#include <linux/socket.h>
-#include <linux/in.h>
 #include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/timer.h>
 #include <linux/string.h>
-#include <linux/sockios.h>
-#include <linux/net.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <net/sock.h>
-#include <net/ip.h>			/* For ip_rcv */
 #include <net/tcp.h>
-#include <asm/system.h>
-#include <linux/fcntl.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
 #include <net/x25.h>
 
 static int x25_queue_rx_frame(struct sock *sk, struct sk_buff *skb, int more)
diff -Nru a/net/x25/x25_link.c b/net/x25/x25_link.c
--- a/net/x25/x25_link.c	2005-03-01 23:38:52 -08:00
+++ b/net/x25/x25_link.c	2005-03-01 23:38:52 -08:00
@@ -21,33 +21,23 @@
  *	2000-09-04	Henner Eisen	  dev_hold() / dev_put() for x25_neigh.
  */
 
-#include <linux/errno.h>
-#include <linux/types.h>
-#include <linux/socket.h>
-#include <linux/in.h>
 #include <linux/kernel.h>
 #include <linux/jiffies.h>
 #include <linux/timer.h>
-#include <linux/string.h>
-#include <linux/sockios.h>
-#include <linux/net.h>
-#include <linux/inet.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
-#include <net/sock.h>
-#include <asm/system.h>
 #include <asm/uaccess.h>
-#include <linux/fcntl.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
 #include <linux/init.h>
 #include <net/x25.h>
 
 static struct list_head x25_neigh_list = LIST_HEAD_INIT(x25_neigh_list);
-static rwlock_t x25_neigh_list_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(x25_neigh_list_lock);
 
 static void x25_t20timer_expiry(unsigned long);
 
+static void x25_transmit_restart_confirmation(struct x25_neigh *nb);
+static void x25_transmit_restart_request(struct x25_neigh *nb);
+
 /*
  *	Linux set/reset timer routines
  */
@@ -119,7 +109,7 @@
 /*
  *	This routine is called when a Restart Request is needed
  */
-void x25_transmit_restart_request(struct x25_neigh *nb)
+static void x25_transmit_restart_request(struct x25_neigh *nb)
 {
 	unsigned char *dptr;
 	int len = X25_MAX_L2_LEN + X25_STD_MIN_LEN + 2;
@@ -146,7 +136,7 @@
 /*
  * This routine is called when a Restart Confirmation is needed
  */
-void x25_transmit_restart_confirmation(struct x25_neigh *nb)
+static void x25_transmit_restart_confirmation(struct x25_neigh *nb)
 {
 	unsigned char *dptr;
 	int len = X25_MAX_L2_LEN + X25_STD_MIN_LEN;
@@ -162,32 +152,6 @@
 	*dptr++ = nb->extended ? X25_GFI_EXTSEQ : X25_GFI_STDSEQ;
 	*dptr++ = 0x00;
 	*dptr++ = X25_RESTART_CONFIRMATION;
-
-	skb->sk = NULL;
-
-	x25_send_frame(skb, nb);
-}
-
-/*
- * This routine is called when a Diagnostic is required.
- */
-void x25_transmit_diagnostic(struct x25_neigh *nb, unsigned char diag)
-{
-	unsigned char *dptr;
-	int len = X25_MAX_L2_LEN + X25_STD_MIN_LEN + 1;
-	struct sk_buff *skb = alloc_skb(len, GFP_ATOMIC);
-
-	if (!skb)
-		return;
-
-	skb_reserve(skb, X25_MAX_L2_LEN);
-
-	dptr = skb_put(skb, X25_STD_MIN_LEN + 1);
-
-	*dptr++ = nb->extended ? X25_GFI_EXTSEQ : X25_GFI_STDSEQ;
-	*dptr++ = 0x00;
-	*dptr++ = X25_DIAGNOSTIC;
-	*dptr++ = diag;
 
 	skb->sk = NULL;
 
diff -Nru a/net/x25/x25_out.c b/net/x25/x25_out.c
--- a/net/x25/x25_out.c	2005-03-01 23:38:52 -08:00
+++ b/net/x25/x25_out.c	2005-03-01 23:38:52 -08:00
@@ -22,24 +22,11 @@
  *					needed cleaned seq-number fields.
  */
 
-#include <linux/errno.h>
-#include <linux/types.h>
 #include <linux/socket.h>
-#include <linux/in.h>
 #include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/timer.h>
 #include <linux/string.h>
-#include <linux/sockios.h>
-#include <linux/net.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <net/sock.h>
-#include <asm/system.h>
-#include <linux/fcntl.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
 #include <net/x25.h>
 
 static int x25_pacsize_to_bytes(unsigned int pacsize)
diff -Nru a/net/x25/x25_proc.c b/net/x25/x25_proc.c
--- a/net/x25/x25_proc.c	2005-03-01 23:38:53 -08:00
+++ b/net/x25/x25_proc.c	2005-03-01 23:38:53 -08:00
@@ -166,14 +166,14 @@
 	return 0;
 } 
 
-struct seq_operations x25_seq_route_ops = {
+static struct seq_operations x25_seq_route_ops = {
 	.start  = x25_seq_route_start,
 	.next   = x25_seq_route_next,
 	.stop   = x25_seq_route_stop,
 	.show   = x25_seq_route_show,
 };
 
-struct seq_operations x25_seq_socket_ops = {
+static struct seq_operations x25_seq_socket_ops = {
 	.start  = x25_seq_socket_start,
 	.next   = x25_seq_socket_next,
 	.stop   = x25_seq_socket_stop,
diff -Nru a/net/x25/x25_route.c b/net/x25/x25_route.c
--- a/net/x25/x25_route.c	2005-03-01 23:39:08 -08:00
+++ b/net/x25/x25_route.c	2005-03-01 23:39:08 -08:00
@@ -23,7 +23,7 @@
 #include <net/x25.h>
 
 struct list_head x25_route_list = LIST_HEAD_INIT(x25_route_list);
-rwlock_t x25_route_list_lock = RW_LOCK_UNLOCKED;
+DEFINE_RWLOCK(x25_route_list_lock);
 
 /*
  *	Add a new route.
diff -Nru a/net/x25/x25_subr.c b/net/x25/x25_subr.c
--- a/net/x25/x25_subr.c	2005-03-01 23:38:54 -08:00
+++ b/net/x25/x25_subr.c	2005-03-01 23:38:54 -08:00
@@ -21,25 +21,11 @@
  *	jun/24/01	Arnaldo C. Melo	  use skb_queue_purge, cleanups
  */
 
-#include <linux/errno.h>
-#include <linux/types.h>
-#include <linux/socket.h>
-#include <linux/in.h>
 #include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/timer.h>
 #include <linux/string.h>
-#include <linux/sockios.h>
-#include <linux/net.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <net/sock.h>
 #include <net/tcp.h>
-#include <asm/system.h>
-#include <linux/fcntl.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
 #include <net/x25.h>
 
 /*
@@ -367,3 +353,22 @@
 		x25_stop_timer(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 -Nru a/net/x25/x25_timer.c b/net/x25/x25_timer.c
--- a/net/x25/x25_timer.c	2005-03-01 23:38:52 -08:00
+++ b/net/x25/x25_timer.c	2005-03-01 23:38:52 -08:00
@@ -20,24 +20,10 @@
  */
 
 #include <linux/errno.h>
-#include <linux/types.h>
-#include <linux/socket.h>
-#include <linux/in.h>
-#include <linux/kernel.h>
 #include <linux/jiffies.h>
 #include <linux/timer.h>
-#include <linux/string.h>
-#include <linux/sockios.h>
-#include <linux/net.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/skbuff.h>
 #include <net/sock.h>
 #include <net/tcp.h>
-#include <asm/system.h>
-#include <linux/fcntl.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
 #include <net/x25.h>
 
 static void x25_heartbeat_expiry(unsigned long);
diff -Nru a/net/xfrm/Makefile b/net/xfrm/Makefile
--- a/net/xfrm/Makefile	2005-03-01 23:39:18 -08:00
+++ b/net/xfrm/Makefile	2005-03-01 23:39:18 -08:00
@@ -2,7 +2,6 @@
 # Makefile for the XFRM subsystem.
 #
 
-obj-$(CONFIG_XFRM) := xfrm_policy.o xfrm_state.o xfrm_input.o xfrm_algo.o \
-	xfrm_export.o
+obj-$(CONFIG_XFRM) := xfrm_policy.o xfrm_state.o xfrm_input.o xfrm_algo.o
 obj-$(CONFIG_XFRM_USER) += xfrm_user.o
 
diff -Nru a/net/xfrm/xfrm_algo.c b/net/xfrm/xfrm_algo.c
--- a/net/xfrm/xfrm_algo.c	2005-03-01 23:39:18 -08:00
+++ b/net/xfrm/xfrm_algo.c	2005-03-01 23:39:18 -08:00
@@ -13,6 +13,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/pfkeyv2.h>
+#include <linux/crypto.h>
 #include <net/xfrm.h>
 #if defined(CONFIG_INET_AH) || defined(CONFIG_INET_AH_MODULE) || defined(CONFIG_INET6_AH) || defined(CONFIG_INET6_AH_MODULE)
 #include <net/ah.h>
@@ -315,6 +316,7 @@
 	}
 	return NULL;
 }
+EXPORT_SYMBOL_GPL(xfrm_aalg_get_byid);
 
 struct xfrm_algo_desc *xfrm_ealg_get_byid(int alg_id)
 {
@@ -330,6 +332,7 @@
 	}
 	return NULL;
 }
+EXPORT_SYMBOL_GPL(xfrm_ealg_get_byid);
 
 struct xfrm_algo_desc *xfrm_calg_get_byid(int alg_id)
 {
@@ -345,60 +348,54 @@
 	}
 	return NULL;
 }
+EXPORT_SYMBOL_GPL(xfrm_calg_get_byid);
 
-struct xfrm_algo_desc *xfrm_aalg_get_byname(char *name)
+static struct xfrm_algo_desc *xfrm_get_byname(struct xfrm_algo_desc *list,
+					      int entries, char *name,
+					      int probe)
 {
-	int i;
+	int i, status;
 
 	if (!name)
 		return NULL;
 
-	for (i=0; i < aalg_entries(); i++) {
-		if (strcmp(name, aalg_list[i].name) == 0) {
-			if (aalg_list[i].available)
-				return &aalg_list[i];
-			else
-				break;
-		}
+	for (i = 0; i < entries; i++) {
+		if (strcmp(name, list[i].name))
+			continue;
+
+		if (list[i].available)
+			return &list[i];
+
+		if (!probe)
+			break;
+
+		status = crypto_alg_available(name, 0);
+		if (!status)
+			break;
+
+		list[i].available = status;
+		return &list[i];
 	}
 	return NULL;
 }
 
-struct xfrm_algo_desc *xfrm_ealg_get_byname(char *name)
+struct xfrm_algo_desc *xfrm_aalg_get_byname(char *name, int probe)
 {
-	int i;
-
-	if (!name)
-		return NULL;
-
-	for (i=0; i < ealg_entries(); i++) {
-		if (strcmp(name, ealg_list[i].name) == 0) {
-			if (ealg_list[i].available)
-				return &ealg_list[i];
-			else
-				break;
-		}
-	}
-	return NULL;
+	return xfrm_get_byname(aalg_list, aalg_entries(), name, probe);
 }
+EXPORT_SYMBOL_GPL(xfrm_aalg_get_byname);
 
-struct xfrm_algo_desc *xfrm_calg_get_byname(char *name)
+struct xfrm_algo_desc *xfrm_ealg_get_byname(char *name, int probe)
 {
-	int i;
-
-	if (!name)
-		return NULL;
+	return xfrm_get_byname(ealg_list, ealg_entries(), name, probe);
+}
+EXPORT_SYMBOL_GPL(xfrm_ealg_get_byname);
 
-	for (i=0; i < calg_entries(); i++) {
-		if (strcmp(name, calg_list[i].name) == 0) {
-			if (calg_list[i].available)
-				return &calg_list[i];
-			else
-				break;
-		}
-	}
-	return NULL;
+struct xfrm_algo_desc *xfrm_calg_get_byname(char *name, int probe)
+{
+	return xfrm_get_byname(calg_list, calg_entries(), name, probe);
 }
+EXPORT_SYMBOL_GPL(xfrm_calg_get_byname);
 
 struct xfrm_algo_desc *xfrm_aalg_get_byidx(unsigned int idx)
 {
@@ -407,6 +404,7 @@
 
 	return &aalg_list[idx];
 }
+EXPORT_SYMBOL_GPL(xfrm_aalg_get_byidx);
 
 struct xfrm_algo_desc *xfrm_ealg_get_byidx(unsigned int idx)
 {
@@ -415,14 +413,7 @@
 
 	return &ealg_list[idx];
 }
-
-struct xfrm_algo_desc *xfrm_calg_get_byidx(unsigned int idx)
-{
-	if (idx >= calg_entries())
-		return NULL;
-
-	return &calg_list[idx];
-}
+EXPORT_SYMBOL_GPL(xfrm_ealg_get_byidx);
 
 /*
  * Probe for the availability of crypto algorithms, and set the available
@@ -455,6 +446,7 @@
 	}
 #endif
 }
+EXPORT_SYMBOL_GPL(xfrm_probe_algs);
 
 int xfrm_count_auth_supported(void)
 {
@@ -465,6 +457,7 @@
 			n++;
 	return n;
 }
+EXPORT_SYMBOL_GPL(xfrm_count_auth_supported);
 
 int xfrm_count_enc_supported(void)
 {
@@ -475,6 +468,7 @@
 			n++;
 	return n;
 }
+EXPORT_SYMBOL_GPL(xfrm_count_enc_supported);
 
 /* Move to common area: it is shared with AH. */
 
@@ -549,6 +543,7 @@
 	if (len)
 		BUG();
 }
+EXPORT_SYMBOL_GPL(skb_icv_walk);
 
 #if defined(CONFIG_INET_ESP) || defined(CONFIG_INET_ESP_MODULE) || defined(CONFIG_INET6_ESP) || defined(CONFIG_INET6_ESP_MODULE)
 
diff -Nru a/net/xfrm/xfrm_export.c b/net/xfrm/xfrm_export.c
--- a/net/xfrm/xfrm_export.c	2005-03-01 23:38:57 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,63 +0,0 @@
-#include <linux/module.h>
-#include <net/xfrm.h>
-
-EXPORT_SYMBOL(xfrm_user_policy);
-EXPORT_SYMBOL(km_waitq);
-EXPORT_SYMBOL(km_new_mapping);
-EXPORT_SYMBOL(xfrm_cfg_sem);
-EXPORT_SYMBOL(xfrm_policy_alloc);
-EXPORT_SYMBOL(__xfrm_policy_destroy);
-EXPORT_SYMBOL(xfrm_lookup);
-EXPORT_SYMBOL(__xfrm_policy_check);
-EXPORT_SYMBOL(__xfrm_route_forward);
-EXPORT_SYMBOL(xfrm_state_alloc);
-EXPORT_SYMBOL(__xfrm_state_destroy);
-EXPORT_SYMBOL(xfrm_state_insert);
-EXPORT_SYMBOL(xfrm_state_add);
-EXPORT_SYMBOL(xfrm_state_update);
-EXPORT_SYMBOL(xfrm_state_check_expire);
-EXPORT_SYMBOL(xfrm_state_check);
-EXPORT_SYMBOL(xfrm_state_lookup);
-EXPORT_SYMBOL(xfrm_state_register_afinfo);
-EXPORT_SYMBOL(xfrm_state_unregister_afinfo);
-EXPORT_SYMBOL(xfrm_state_delete_tunnel);
-EXPORT_SYMBOL(xfrm_replay_check);
-EXPORT_SYMBOL(xfrm_replay_advance);
-EXPORT_SYMBOL(__secpath_destroy);
-EXPORT_SYMBOL(secpath_dup);
-EXPORT_SYMBOL(xfrm_get_acqseq);
-EXPORT_SYMBOL(xfrm_parse_spi);
-EXPORT_SYMBOL(xfrm_register_type);
-EXPORT_SYMBOL(xfrm_unregister_type);
-EXPORT_SYMBOL(xfrm_get_type);
-EXPORT_SYMBOL(xfrm_register_km);
-EXPORT_SYMBOL(xfrm_unregister_km);
-EXPORT_SYMBOL(xfrm_state_delete);
-EXPORT_SYMBOL(xfrm_state_walk);
-EXPORT_SYMBOL(xfrm_find_acq_byseq);
-EXPORT_SYMBOL(xfrm_find_acq);
-EXPORT_SYMBOL(xfrm_alloc_spi);
-EXPORT_SYMBOL(xfrm_state_flush);
-EXPORT_SYMBOL(xfrm_policy_bysel);
-EXPORT_SYMBOL(xfrm_policy_insert);
-EXPORT_SYMBOL(xfrm_policy_walk);
-EXPORT_SYMBOL(xfrm_policy_flush);
-EXPORT_SYMBOL(xfrm_policy_byid);
-EXPORT_SYMBOL(xfrm_policy_list);
-EXPORT_SYMBOL(xfrm_dst_lookup);
-EXPORT_SYMBOL(xfrm_policy_register_afinfo);
-EXPORT_SYMBOL(xfrm_policy_unregister_afinfo);
-
-EXPORT_SYMBOL_GPL(xfrm_probe_algs);
-EXPORT_SYMBOL_GPL(xfrm_count_auth_supported);
-EXPORT_SYMBOL_GPL(xfrm_count_enc_supported);
-EXPORT_SYMBOL_GPL(xfrm_aalg_get_byidx);
-EXPORT_SYMBOL_GPL(xfrm_ealg_get_byidx);
-EXPORT_SYMBOL_GPL(xfrm_calg_get_byidx);
-EXPORT_SYMBOL_GPL(xfrm_aalg_get_byid);
-EXPORT_SYMBOL_GPL(xfrm_ealg_get_byid);
-EXPORT_SYMBOL_GPL(xfrm_calg_get_byid);
-EXPORT_SYMBOL_GPL(xfrm_aalg_get_byname);
-EXPORT_SYMBOL_GPL(xfrm_ealg_get_byname);
-EXPORT_SYMBOL_GPL(xfrm_calg_get_byname);
-EXPORT_SYMBOL_GPL(skb_icv_walk);
diff -Nru a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c
--- a/net/xfrm/xfrm_input.c	2005-03-01 23:39:18 -08:00
+++ b/net/xfrm/xfrm_input.c	2005-03-01 23:39:18 -08:00
@@ -8,6 +8,7 @@
  */
 
 #include <linux/slab.h>
+#include <linux/module.h>
 #include <net/ip.h>
 #include <net/xfrm.h>
 
@@ -20,6 +21,7 @@
 		xfrm_state_put(sp->x[i].xvec);
 	kmem_cache_free(secpath_cachep, sp);
 }
+EXPORT_SYMBOL(__secpath_destroy);
 
 struct sec_path *secpath_dup(struct sec_path *src)
 {
@@ -40,6 +42,7 @@
 	atomic_set(&sp->refcnt, 1);
 	return sp;
 }
+EXPORT_SYMBOL(secpath_dup);
 
 /* Fetch spi and seq from ipsec header */
 
@@ -73,6 +76,7 @@
 	*seq = *(u32*)(skb->h.raw + offset_seq);
 	return 0;
 }
+EXPORT_SYMBOL(xfrm_parse_spi);
 
 void __init xfrm_input_init(void)
 {
diff -Nru a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
--- a/net/xfrm/xfrm_policy.c	2005-03-01 23:38:57 -08:00
+++ b/net/xfrm/xfrm_policy.c	2005-03-01 23:38:57 -08:00
@@ -21,24 +21,27 @@
 #include <linux/workqueue.h>
 #include <linux/notifier.h>
 #include <linux/netdevice.h>
+#include <linux/module.h>
 #include <net/xfrm.h>
 #include <net/ip.h>
 
 DECLARE_MUTEX(xfrm_cfg_sem);
+EXPORT_SYMBOL(xfrm_cfg_sem);
 
-static rwlock_t xfrm_policy_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(xfrm_policy_lock);
 
 struct xfrm_policy *xfrm_policy_list[XFRM_POLICY_MAX*2];
+EXPORT_SYMBOL(xfrm_policy_list);
 
-static rwlock_t xfrm_policy_afinfo_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(xfrm_policy_afinfo_lock);
 static struct xfrm_policy_afinfo *xfrm_policy_afinfo[NPROTO];
 
-kmem_cache_t *xfrm_dst_cache;
+static kmem_cache_t *xfrm_dst_cache;
 
 static struct work_struct xfrm_policy_gc_work;
 static struct list_head xfrm_policy_gc_list =
 	LIST_HEAD_INIT(xfrm_policy_gc_list);
-static spinlock_t xfrm_policy_gc_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(xfrm_policy_gc_lock);
 
 static struct xfrm_policy_afinfo *xfrm_policy_get_afinfo(unsigned short family);
 static void xfrm_policy_put_afinfo(struct xfrm_policy_afinfo *afinfo);
@@ -62,6 +65,7 @@
 	xfrm_policy_put_afinfo(afinfo);
 	return err;
 }
+EXPORT_SYMBOL(xfrm_register_type);
 
 int xfrm_unregister_type(struct xfrm_type *type, unsigned short family)
 {
@@ -82,6 +86,7 @@
 	xfrm_policy_put_afinfo(afinfo);
 	return err;
 }
+EXPORT_SYMBOL(xfrm_unregister_type);
 
 struct xfrm_type *xfrm_get_type(u8 proto, unsigned short family)
 {
@@ -112,6 +117,7 @@
 	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)
@@ -129,6 +135,7 @@
 	xfrm_policy_put_afinfo(afinfo);
 	return err;
 }
+EXPORT_SYMBOL(xfrm_dst_lookup);
 
 void xfrm_put_type(struct xfrm_type *type)
 {
@@ -234,6 +241,7 @@
 	}
 	return policy;
 }
+EXPORT_SYMBOL(xfrm_policy_alloc);
 
 /* Destroy xfrm_policy: descendant resources must be released to this moment. */
 
@@ -250,6 +258,7 @@
 
 	kfree(policy);
 }
+EXPORT_SYMBOL(__xfrm_policy_destroy);
 
 static void xfrm_policy_gc_kill(struct xfrm_policy *policy)
 {
@@ -373,6 +382,7 @@
 	}
 	return 0;
 }
+EXPORT_SYMBOL(xfrm_policy_insert);
 
 struct xfrm_policy *xfrm_policy_bysel(int dir, struct xfrm_selector *sel,
 				      int delete)
@@ -396,6 +406,7 @@
 	}
 	return pol;
 }
+EXPORT_SYMBOL(xfrm_policy_bysel);
 
 struct xfrm_policy *xfrm_policy_byid(int dir, u32 id, int delete)
 {
@@ -418,6 +429,7 @@
 	}
 	return pol;
 }
+EXPORT_SYMBOL(xfrm_policy_byid);
 
 void xfrm_policy_flush(void)
 {
@@ -438,6 +450,7 @@
 	atomic_inc(&flow_cache_genid);
 	write_unlock_bh(&xfrm_policy_lock);
 }
+EXPORT_SYMBOL(xfrm_policy_flush);
 
 int xfrm_policy_walk(int (*func)(struct xfrm_policy *, int, int, void*),
 		     void *data)
@@ -470,7 +483,7 @@
 	read_unlock_bh(&xfrm_policy_lock);
 	return error;
 }
-
+EXPORT_SYMBOL(xfrm_policy_walk);
 
 /* Find policy to apply to this flow. */
 
@@ -498,7 +511,7 @@
 		*obj_refp = &pol->refcnt;
 }
 
-struct xfrm_policy *xfrm_sk_policy_lookup(struct sock *sk, int dir, struct flowi *fl)
+static struct xfrm_policy *xfrm_sk_policy_lookup(struct sock *sk, int dir, struct flowi *fl)
 {
 	struct xfrm_policy *pol;
 
@@ -845,6 +858,7 @@
 	*dst_p = NULL;
 	return err;
 }
+EXPORT_SYMBOL(xfrm_lookup);
 
 /* When skb is transformed back to its "native" form, we have to
  * check policy restrictions. At the moment we make this in maximally
@@ -981,6 +995,7 @@
 	xfrm_pol_put(pol);
 	return 0;
 }
+EXPORT_SYMBOL(__xfrm_policy_check);
 
 int __xfrm_route_forward(struct sk_buff *skb, unsigned short family)
 {
@@ -991,6 +1006,7 @@
 
 	return xfrm_lookup(&skb->dst, &fl, NULL, 0) == 0;
 }
+EXPORT_SYMBOL(__xfrm_route_forward);
 
 /* Optimize later using cookies and generation ids. */
 
@@ -1027,6 +1043,19 @@
 	dst->xfrm = NULL;
 }
 
+static void xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev,
+			    int unregister)
+{
+	if (!unregister)
+		return;
+
+	while ((dst = dst->child) && dst->xfrm && dst->dev == dev) {
+		dst->dev = &loopback_dev;
+		dev_hold(&loopback_dev);
+		dev_put(dev);
+	}
+}
+
 static void xfrm_link_failure(struct sk_buff *skb)
 {
 	/* Impossible. Such dst must be popped before reaches point of failure. */
@@ -1150,6 +1179,8 @@
 			dst_ops->check = xfrm_dst_check;
 		if (likely(dst_ops->destroy == NULL))
 			dst_ops->destroy = xfrm_dst_destroy;
+		if (likely(dst_ops->ifdown == NULL))
+			dst_ops->ifdown = xfrm_dst_ifdown;
 		if (likely(dst_ops->negative_advice == NULL))
 			dst_ops->negative_advice = xfrm_negative_advice;
 		if (likely(dst_ops->link_failure == NULL))
@@ -1163,6 +1194,7 @@
 	write_unlock(&xfrm_policy_afinfo_lock);
 	return err;
 }
+EXPORT_SYMBOL(xfrm_policy_register_afinfo);
 
 int xfrm_policy_unregister_afinfo(struct xfrm_policy_afinfo *afinfo)
 {
@@ -1181,6 +1213,7 @@
 			dst_ops->kmem_cachep = NULL;
 			dst_ops->check = NULL;
 			dst_ops->destroy = NULL;
+			dst_ops->ifdown = NULL;
 			dst_ops->negative_advice = NULL;
 			dst_ops->link_failure = NULL;
 			dst_ops->get_mss = NULL;
@@ -1190,6 +1223,7 @@
 	write_unlock(&xfrm_policy_afinfo_lock);
 	return err;
 }
+EXPORT_SYMBOL(xfrm_policy_unregister_afinfo);
 
 static struct xfrm_policy_afinfo *xfrm_policy_get_afinfo(unsigned short family)
 {
@@ -1220,13 +1254,13 @@
 	return NOTIFY_DONE;
 }
 
-struct notifier_block xfrm_dev_notifier = {
+static struct notifier_block xfrm_dev_notifier = {
 	xfrm_dev_event,
 	NULL,
 	0
 };
 
-void __init xfrm_policy_init(void)
+static void __init xfrm_policy_init(void)
 {
 	xfrm_dst_cache = kmem_cache_create("xfrm_dst_cache",
 					   sizeof(struct xfrm_dst),
diff -Nru a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
--- a/net/xfrm/xfrm_state.c	2005-03-01 23:39:08 -08:00
+++ b/net/xfrm/xfrm_state.c	2005-03-01 23:39:08 -08:00
@@ -17,6 +17,7 @@
 #include <net/xfrm.h>
 #include <linux/pfkeyv2.h>
 #include <linux/ipsec.h>
+#include <linux/module.h>
 #include <asm/uaccess.h>
 
 /* Each xfrm_state may be linked to two tables:
@@ -26,7 +27,7 @@
       destination/tunnel endpoint. (output)
  */
 
-static spinlock_t xfrm_state_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(xfrm_state_lock);
 
 /* Hash table to find appropriate SA towards given target (endpoint
  * of tunnel or destination of transport mode) allowed by selector.
@@ -38,19 +39,23 @@
 static struct list_head xfrm_state_byspi[XFRM_DST_HSIZE];
 
 DECLARE_WAIT_QUEUE_HEAD(km_waitq);
+EXPORT_SYMBOL(km_waitq);
 
-static rwlock_t xfrm_state_afinfo_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(xfrm_state_afinfo_lock);
 static struct xfrm_state_afinfo *xfrm_state_afinfo[NPROTO];
 
 static struct work_struct xfrm_state_gc_work;
 static struct list_head xfrm_state_gc_list = LIST_HEAD_INIT(xfrm_state_gc_list);
-static spinlock_t xfrm_state_gc_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(xfrm_state_gc_lock);
 
 static void __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);
 
+static int km_query(struct xfrm_state *x, struct xfrm_tmpl *t, struct xfrm_policy *pol);
+static void km_state_expired(struct xfrm_state *x, int hard);
+
 static void xfrm_state_gc_destroy(struct xfrm_state *x)
 {
 	if (del_timer(&x->timer))
@@ -190,6 +195,7 @@
 	}
 	return x;
 }
+EXPORT_SYMBOL(xfrm_state_alloc);
 
 void __xfrm_state_destroy(struct xfrm_state *x)
 {
@@ -200,6 +206,7 @@
 	spin_unlock_bh(&xfrm_state_gc_lock);
 	schedule_work(&xfrm_state_gc_work);
 }
+EXPORT_SYMBOL(__xfrm_state_destroy);
 
 static void __xfrm_state_delete(struct xfrm_state *x)
 {
@@ -238,6 +245,7 @@
 	__xfrm_state_delete(x);
 	spin_unlock_bh(&x->lock);
 }
+EXPORT_SYMBOL(xfrm_state_delete);
 
 void xfrm_state_flush(u8 proto)
 {
@@ -264,6 +272,7 @@
 	spin_unlock_bh(&xfrm_state_lock);
 	wake_up(&km_waitq);
 }
+EXPORT_SYMBOL(xfrm_state_flush);
 
 static int
 xfrm_init_tempsel(struct xfrm_state *x, struct flowi *fl,
@@ -389,6 +398,7 @@
 	__xfrm_state_insert(x);
 	spin_unlock_bh(&xfrm_state_lock);
 }
+EXPORT_SYMBOL(xfrm_state_insert);
 
 static struct xfrm_state *__xfrm_find_acq_byseq(u32 seq);
 
@@ -441,6 +451,7 @@
 
 	return err;
 }
+EXPORT_SYMBOL(xfrm_state_add);
 
 int xfrm_state_update(struct xfrm_state *x)
 {
@@ -505,6 +516,7 @@
 
 	return err;
 }
+EXPORT_SYMBOL(xfrm_state_update);
 
 int xfrm_state_check_expire(struct xfrm_state *x)
 {
@@ -528,6 +540,7 @@
 		km_state_expired(x, 0);
 	return 0;
 }
+EXPORT_SYMBOL(xfrm_state_check_expire);
 
 static int xfrm_state_check_space(struct xfrm_state *x, struct sk_buff *skb)
 {
@@ -550,6 +563,7 @@
 err:
 	return err;
 }
+EXPORT_SYMBOL(xfrm_state_check);
 
 struct xfrm_state *
 xfrm_state_lookup(xfrm_address_t *daddr, u32 spi, u8 proto,
@@ -566,6 +580,7 @@
 	xfrm_state_put_afinfo(afinfo);
 	return x;
 }
+EXPORT_SYMBOL(xfrm_state_lookup);
 
 struct xfrm_state *
 xfrm_find_acq(u8 mode, u32 reqid, u8 proto, 
@@ -583,6 +598,7 @@
 	xfrm_state_put_afinfo(afinfo);
 	return x;
 }
+EXPORT_SYMBOL(xfrm_find_acq);
 
 /* Silly enough, but I'm lazy to build resolution list */
 
@@ -611,18 +627,20 @@
 	spin_unlock_bh(&xfrm_state_lock);
 	return x;
 }
- 
+EXPORT_SYMBOL(xfrm_find_acq_byseq);
+
 u32 xfrm_get_acqseq(void)
 {
 	u32 res;
 	static u32 acqseq;
-	static spinlock_t acqseq_lock = SPIN_LOCK_UNLOCKED;
+	static DEFINE_SPINLOCK(acqseq_lock);
 
 	spin_lock_bh(&acqseq_lock);
 	res = (++acqseq ? : ++acqseq);
 	spin_unlock_bh(&acqseq_lock);
 	return res;
 }
+EXPORT_SYMBOL(xfrm_get_acqseq);
 
 void
 xfrm_alloc_spi(struct xfrm_state *x, u32 minspi, u32 maxspi)
@@ -663,6 +681,7 @@
 		wake_up(&km_waitq);
 	}
 }
+EXPORT_SYMBOL(xfrm_alloc_spi);
 
 int xfrm_state_walk(u8 proto, int (*func)(struct xfrm_state *, int, void*),
 		    void *data)
@@ -697,7 +716,7 @@
 	spin_unlock_bh(&xfrm_state_lock);
 	return err;
 }
-
+EXPORT_SYMBOL(xfrm_state_walk);
 
 int xfrm_replay_check(struct xfrm_state *x, u32 seq)
 {
@@ -723,6 +742,7 @@
 	}
 	return 0;
 }
+EXPORT_SYMBOL(xfrm_replay_check);
 
 void xfrm_replay_advance(struct xfrm_state *x, u32 seq)
 {
@@ -742,11 +762,12 @@
 		x->replay.bitmap |= (1U << diff);
 	}
 }
+EXPORT_SYMBOL(xfrm_replay_advance);
 
 static struct list_head xfrm_km_list = LIST_HEAD_INIT(xfrm_km_list);
-static rwlock_t		xfrm_km_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(xfrm_km_lock);
 
-void km_state_expired(struct xfrm_state *x, int hard)
+static void km_state_expired(struct xfrm_state *x, int hard)
 {
 	struct xfrm_mgr *km;
 
@@ -764,7 +785,7 @@
 		wake_up(&km_waitq);
 }
 
-int km_query(struct xfrm_state *x, struct xfrm_tmpl *t, struct xfrm_policy *pol)
+static int km_query(struct xfrm_state *x, struct xfrm_tmpl *t, struct xfrm_policy *pol)
 {
 	int err = -EINVAL;
 	struct xfrm_mgr *km;
@@ -794,6 +815,7 @@
 	read_unlock(&xfrm_km_lock);
 	return err;
 }
+EXPORT_SYMBOL(km_new_mapping);
 
 void km_policy_expired(struct xfrm_policy *pol, int dir, int hard)
 {
@@ -847,6 +869,7 @@
 	kfree(data);
 	return err;
 }
+EXPORT_SYMBOL(xfrm_user_policy);
 
 int xfrm_register_km(struct xfrm_mgr *km)
 {
@@ -855,6 +878,7 @@
 	write_unlock_bh(&xfrm_km_lock);
 	return 0;
 }
+EXPORT_SYMBOL(xfrm_register_km);
 
 int xfrm_unregister_km(struct xfrm_mgr *km)
 {
@@ -863,6 +887,7 @@
 	write_unlock_bh(&xfrm_km_lock);
 	return 0;
 }
+EXPORT_SYMBOL(xfrm_unregister_km);
 
 int xfrm_state_register_afinfo(struct xfrm_state_afinfo *afinfo)
 {
@@ -882,6 +907,7 @@
 	write_unlock(&xfrm_state_afinfo_lock);
 	return err;
 }
+EXPORT_SYMBOL(xfrm_state_register_afinfo);
 
 int xfrm_state_unregister_afinfo(struct xfrm_state_afinfo *afinfo)
 {
@@ -903,6 +929,7 @@
 	write_unlock(&xfrm_state_afinfo_lock);
 	return err;
 }
+EXPORT_SYMBOL(xfrm_state_unregister_afinfo);
 
 static struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned short family)
 {
@@ -937,6 +964,7 @@
 		x->tunnel = NULL;
 	}
 }
+EXPORT_SYMBOL(xfrm_state_delete_tunnel);
 
 void __init xfrm_state_init(void)
 {
diff -Nru a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
--- a/net/xfrm/xfrm_user.c	2005-03-01 23:38:58 -08:00
+++ b/net/xfrm/xfrm_user.c	2005-03-01 23:38:58 -08:00
@@ -156,7 +156,7 @@
 }
 
 static int attach_one_algo(struct xfrm_algo **algpp, u8 *props,
-			   struct xfrm_algo_desc *(*get_byname)(char *),
+			   struct xfrm_algo_desc *(*get_byname)(char *, int),
 			   struct rtattr *u_arg)
 {
 	struct rtattr *rta = u_arg;
@@ -168,7 +168,7 @@
 
 	ualg = RTA_DATA(rta);
 
-	algo = get_byname(ualg->alg_name);
+	algo = get_byname(ualg->alg_name, 1);
 	if (!algo)
 		return -ENOSYS;
 	*props = algo->desc.sadb_alg_id;
@@ -273,8 +273,6 @@
 	if (err)
 		return err;
 
-	xfrm_probe_algs();
-
 	x = xfrm_state_construct(p, (struct rtattr **) xfrma, &err);
 	if (!x)
 		return err;
@@ -1128,8 +1126,8 @@
 /* User gives us xfrm_user_policy_info followed by an array of 0
  * or more templates.
  */
-struct xfrm_policy *xfrm_compile_policy(u16 family, int opt,
-                                        u8 *data, int len, int *dir)
+static struct xfrm_policy *xfrm_compile_policy(u16 family, int opt,
+					       u8 *data, int len, int *dir)
 {
 	struct xfrm_userpolicy_info *p = (struct xfrm_userpolicy_info *)data;
 	struct xfrm_user_tmpl *ut = (struct xfrm_user_tmpl *) (p + 1);
diff -Nru a/scripts/Makefile.build b/scripts/Makefile.build
--- a/scripts/Makefile.build	2005-03-01 23:39:09 -08:00
+++ b/scripts/Makefile.build	2005-03-01 23:39:09 -08:00
@@ -83,7 +83,6 @@
 
 # Linus' kernel sanity checking tool
 ifneq ($(KBUILD_CHECKSRC),0)
-  CHECKFLAGS += -I$(shell $(CC) -print-file-name=include)
   ifeq ($(KBUILD_CHECKSRC),2)
     quiet_cmd_force_checksrc = CHECK   $<
           cmd_force_checksrc = $(CHECK) $(CHECKFLAGS) $(c_flags) $< ;
diff -Nru a/scripts/README.Menuconfig b/scripts/README.Menuconfig
--- a/scripts/README.Menuconfig	2005-03-01 23:38:56 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,201 +0,0 @@
-Menuconfig gives the Linux kernel configuration a long needed face
-lift.  Featuring text based color menus and dialogs, it does not
-require X Windows (however, you need ncurses in order to use it).
-With this utility you can easily select a kernel option to modify
-without sifting through 100 other options.
-
-Overview
---------
-Some kernel features may be built directly into the kernel.
-Some may be made into loadable runtime modules.  Some features
-may be completely removed altogether.  There are also certain
-kernel parameters which are not really features, but must be 
-entered in as decimal or hexadecimal numbers or possibly text.
-
-Menu items beginning with [*], <M> or [ ] represent features 
-configured to be built in, modularized or removed respectively.
-Pointed brackets <> represent module capable features.
-                                                             more...
-
-To change any of these features, highlight it with the cursor 
-keys and press <Y> to build it in, <M> to make it a module or
-<N> to removed it.  You may also press the <Space Bar> to cycle
-through the available options (ie. Y->N->M->Y). 
-
-Items beginning with numbers or other text within parenthesis can 
-be changed by highlighting the item and pressing <Enter>.  Then
-enter the new parameter into the dialog box that pops up.
-
-
-Some additional keyboard hints:
-
-Menus
-----------
-o  Use the Up/Down arrow keys (cursor keys) to highlight the item 
-   you wish to change or submenu wish to select and press <Enter>.
-   Submenus are designated by "--->".
-
-   Shortcut: Press the option's highlighted letter (hotkey).
-             Pressing a hotkey more than once will sequence
-             through all visible items which use that hotkey.
-
-   You may also use the <PAGE UP> and <PAGE DOWN> keys to scroll
-   unseen options into view.
-
-o  To exit a menu use the cursor keys to highlight the <Exit> button
-   and press <ENTER>.  
-
-   Shortcut: Press <ESC><ESC> or <E> or <X> if there is no hotkey
-             using those letters.  You may press a single <ESC>, but
-             there is a delayed response which you may find annoying.
-
-   Also, the <TAB> and cursor keys will cycle between <Select>,
-   <Exit> and <Help>
-
-o  To get help with an item, use the cursor keys to highlight <Help>
-   and Press <ENTER>.
-
-   Shortcut: Press <H> or <?>.
-
-
-Radiolists  (Choice lists)
------------
-o  Use the cursor keys to select the option you wish to set and press
-   <S> or the <SPACE BAR>.
-
-   Shortcut: Press the first letter of the option you wish to set then
-             press <S> or <SPACE BAR>.
-
-o  To see available help for the item, use the cursor keys to highlight
-   <Help> and Press <ENTER>.
-
-   Shortcut: Press <H> or <?>.
-
-   Also, the <TAB> and cursor keys will cycle between <Select> and
-   <Help>
-
-
-Data Entry
------------
-o  Enter the requested information and press <ENTER>
-   If you are entering hexadecimal values, it is not necessary to
-   add the '0x' prefix to the entry.
-
-o  For help, use the <TAB> or cursor keys to highlight the help option
-   and press <ENTER>.  You can try <TAB><H> as well.
-
-
-Text Box    (Help Window)
---------
-o  Use the cursor keys to scroll up/down/left/right.  The VI editor
-   keys h,j,k,l function here as do <SPACE BAR> and <B> for those
-   who are familiar with less and lynx.
-
-o  Press <E>, <X>, <Enter> or <Esc><Esc> to exit.
-
-
-Final Acceptance
-----------------
-With the exception of the old style sound configuration,
-YOUR CHANGES ARE NOT FINAL.  You will be given a last chance to
-confirm them prior to exiting Menuconfig.
-
-If Menuconfig quits with an error while saving your configuration,
-you may look in the file /usr/src/linux/.menuconfig.log for
-information which may help you determine the cause.
-
-Alternate Configuration Files
------------------------------
-Menuconfig supports the use of alternate configuration files for
-those who, for various reasons, find it necessary to switch 
-between different kernel configurations.
-
-At the end of the main menu you will find two options.  One is
-for saving the current configuration to a file of your choosing.
-The other option is for loading a previously saved alternate
-configuration.
-
-Even if you don't use alternate configuration files, but you 
-find during a Menuconfig session that you have completely messed
-up your settings, you may use the "Load Alternate..." option to
-restore your previously saved settings from ".config" without 
-restarting Menuconfig.
-
-Other information
------------------
-The windowing utility, lxdialog, will only be rebuilt if your kernel
-source tree is fresh, or changes are patched into it via a kernel
-patch or you do 'make mrproper'.  If changes to lxdialog are patched
-in, most likely the rebuild time will be short.  You may force a
-complete rebuild of lxdialog by changing to its directory and doing
-'make clean all'
-
-If you use Menuconfig in an XTERM window make sure you have your 
-$TERM variable set to point to a xterm definition which supports color.
-Otherwise, Menuconfig will look rather bad.  Menuconfig will not 
-display correctly in a RXVT window because rxvt displays only one
-intensity of color, bright.
-
-Menuconfig will display larger menus on screens or xterms which are
-set to display more than the standard 25 row by 80 column geometry.
-In order for this to work, the "stty size" command must be able to 
-display the screen's current row and column geometry.  I STRONGLY
-RECOMMEND that you make sure you do NOT have the shell variables
-LINES and COLUMNS exported into your environment.  Some distributions
-export those variables via /etc/profile.  Some ncurses programs can
-become confused when those variables (LINES & COLUMNS) don't reflect
-the true screen size.
-
-
-NOTICE:  lxdialog requires the ncurses libraries to compile.  If you
-         don't already have ncurses you really should get it.
-
-         The makefile for lxdialog attempts to find your ncurses
-         header file.  Although it should find the header for older
-         versions of ncurses, it is probably a good idea to get the
-         latest ncurses anyway. 
-
-         If you have upgraded your ncurses libraries, MAKE SURE you
-         remove the old ncurses header files.  If you don't you
-         will most certainly get a segmentation fault.
-
-WARNING: It is not recommended that you change any defines in
-         lxdialog's header files.  If you have a grayscale display and
-         are brave, you may tinker with color.h to tune the colors to
-         your preference.
-
-COMPATIBILITY ISSUE:
-         There have been some compatibility problems reported with
-         older versions of bash and sed.  I am trying to work these
-         out but it is preferable that you upgrade those utilities.
-
-
-******** IMPORTANT, OPTIONAL ALTERNATE PERSONALITY AVAILABLE ********
-********                                                     ********
-If you prefer to have all of the kernel options listed in a single
-menu, rather than the default multimenu hierarchy, run the menuconfig
-with MENUCONFIG_MODE environment variable set to single_menu. Example:
-
-make menuconfig MENUCONFIG_MODE=single_menu
-
-<Enter> will then unroll the appropriate category, or enfold it if it
-is already unrolled.
-
-Note that this mode can eventually be a little more CPU expensive
-(especially with a larger number of unrolled categories) than the
-default mode.
-*********************************************************************
-
-
-Propaganda
-----------
-The windowing support utility (lxdialog) is a VERY modified version of
-the dialog utility by Savio Lam <lam836@cs.cuhk.hk>.  Although lxdialog
-is significantly different from dialog, I have left Savio's copyrights
-intact.  Please DO NOT contact Savio with questions about lxdialog.
-He will not be able to assist.
-
-William Roadcap was the original author of Menuconfig.
-Michael Elizabeth Chastain <mec@shout.net> is the current maintainer.
-
-<END OF FILE>
diff -Nru a/scripts/gen_initramfs_list.sh b/scripts/gen_initramfs_list.sh
--- a/scripts/gen_initramfs_list.sh	2005-03-01 23:39:07 -08:00
+++ b/scripts/gen_initramfs_list.sh	2005-03-01 23:39:07 -08:00
@@ -2,19 +2,17 @@
 # Copyright (C) Martin Schlemmer <azarah@nosferatu.za.org>
 # Released under the terms of the GNU GPL
 #
-# Generate a newline separated list of entries from the file/directory pointed
-# out by the environment variable: CONFIG_INITRAMFS_SOURCE
+# Generate a newline separated list of entries from the file/directory
+# supplied as an argument.
 #
-# If CONFIG_INITRAMFS_SOURCE is non-existing then generate a small dummy file.
+# If a file/directory is not supplied then generate a small dummy file.
 #
-# The output is suitable for gen_init_cpio as found in usr/Makefile.
+# The output is suitable for gen_init_cpio built from usr/gen_init_cpio.c.
 #
-# TODO:  Add support for symlinks, sockets and pipes when gen_init_cpio
-#        supports them.
 
-simple_initramfs() {
+default_initramfs() {
 	cat <<-EOF
-		# This is a very simple initramfs
+		# This is a very simple, default initramfs
 
 		dir /dev 0755 0 0
 		nod /dev/console 0600 0 0 c 5 1
@@ -25,12 +23,19 @@
 filetype() {
 	local argv1="$1"
 
-	if [ -f "${argv1}" ]; then
+	# symlink test must come before file test
+	if [ -L "${argv1}" ]; then
+		echo "slink"
+	elif [ -f "${argv1}" ]; then
 		echo "file"
 	elif [ -d "${argv1}" ]; then
 		echo "dir"
 	elif [ -b "${argv1}" -o -c "${argv1}" ]; then
 		echo "nod"
+	elif [ -p "${argv1}" ]; then
+		echo "pipe"
+	elif [ -S "${argv1}" ]; then
+		echo "sock"
 	else
 		echo "invalid"
 	fi
@@ -52,10 +57,15 @@
 parse() {
 	local location="$1"
 	local name="${location/${srcdir}//}"
+	# change '//' into '/'
+	name="${name//\/\///}"
 	local mode="$2"
 	local uid="$3"
 	local gid="$4"
 	local ftype=$(filetype "${location}")
+	# remap uid/gid to 0 if necessary
+	[ "$uid" -eq "$root_uid" ] && uid=0
+	[ "$gid" -eq "$root_gid" ] && gid=0
 	local str="${mode} ${uid} ${gid}"
 
 	[ "${ftype}" == "invalid" ] && return 0
@@ -79,6 +89,11 @@
 			fi
 			str="${ftype} ${name} ${str} ${dev_type} ${maj} ${min}"
 			;;
+		"slink")
+			local target=$(LC_ALL=C ls -l "${location}" | \
+					gawk '{print $11}')
+			str="${ftype} ${name} ${target} ${str}"
+			;;
 		*)
 			str="${ftype} ${name} ${str}"
 			;;
@@ -89,30 +104,100 @@
 	return 0
 }
 
-if [ -z "$1" ]; then
-	simple_initramfs
-elif [ -f "$1" ]; then
-	print_mtime "$1"
-	cat "$1"
-elif [ -d "$1" ]; then
-	srcdir=$(echo "$1" | sed -e 's://*:/:g')
-	dirlist=$(find "${srcdir}" -printf "%p %m %U %G\n" 2>/dev/null)
-
-	# If $dirlist is only one line, then the directory is empty
-	if [  "$(echo "${dirlist}" | wc -l)" -gt 1 ]; then
-		print_mtime "$1"
+usage() {
+	printf    "Usage:\n"
+	printf    "$0 [ [-u <root_uid>] [-g <root_gid>] [-d | <cpio_source>] ] . . .\n"
+	printf    "\n"
+	printf -- "-u <root_uid>  User ID to map to user ID 0 (root).\n"
+	printf    "               <root_uid> is only meaningful if <cpio_source>\n"
+	printf    "               is a directory.\n"
+	printf -- "-g <root_gid>  Group ID to map to group ID 0 (root).\n"
+	printf    "               <root_gid> is only meaningful if <cpio_source>\n"
+	printf    "               is a directory.\n"
+	printf    "<cpio_source>  File list or directory for cpio archive.\n"
+	printf    "               If <cpio_source> is not provided then a\n"
+	printf    "               a default list will be output.\n"
+	printf -- "-d             Output the default cpio list.  If no <cpio_source>\n"
+	printf    "               is given then the default cpio list will be output.\n"
+	printf    "\n"
+	printf    "All options may be repeated and are interpreted sequentially\n"
+	printf    "and immediately.  -u and -g states are preserved across\n"
+	printf    "<cpio_source> options so an explicit \"-u 0 -g 0\" is required\n"
+	printf    "to reset the root/group mapping.\n"
+}
+
+build_list() {
+	printf "\n#####################\n# $cpio_source\n"
+
+	if [ -f "$cpio_source" ]; then
+		print_mtime "$cpio_source"
+		cat "$cpio_source"
+	elif [ -d "$cpio_source" ]; then
+		srcdir=$(echo "$cpio_source" | sed -e 's://*:/:g')
+		dirlist=$(find "${srcdir}" -printf "%p %m %U %G\n" 2>/dev/null)
+
+		# If $dirlist is only one line, then the directory is empty
+		if [  "$(echo "${dirlist}" | wc -l)" -gt 1 ]; then
+			print_mtime "$cpio_source"
 		
-		echo "${dirlist}" | \
-		while read x; do
-			parse ${x}
-		done
+			echo "${dirlist}" | \
+			while read x; do
+				parse ${x}
+			done
+		else
+			# Failsafe in case directory is empty
+			default_initramfs
+		fi
 	else
-		# Failsafe in case directory is empty
-		simple_initramfs
+		echo "  $0: Cannot open '$cpio_source'" >&2
+		exit 1
 	fi
-else
-	echo "  $0: Cannot open '$1' (CONFIG_INITRAMFS_SOURCE)" >&2
-	exit 1
-fi
+}
+
+
+root_uid=0
+root_gid=0
+
+while [ $# -gt 0 ]; do
+	arg="$1"
+	shift
+	case "$arg" in
+		"-u")
+			root_uid="$1"
+			shift
+			;;
+		"-g")
+			root_gid="$1"
+			shift
+			;;
+		"-d")
+			default_list="$arg"
+			default_initramfs
+			;;
+		"-h")
+			usage
+			exit 0
+			;;
+		*)
+			case "$arg" in
+				"-"*)
+					printf "ERROR: unknown option \"$arg\"\n" >&2
+					printf "If the filename validly begins with '-', then it must be prefixed\n" >&2
+					printf "by './' so that it won't be interpreted as an option." >&2
+					printf "\n" >&2
+					usage >&2
+					exit 1
+					;;
+				*)
+					cpio_source="$arg"
+					build_list
+					;;
+			esac
+			;;
+	esac
+done
+
+# spit out the default cpio list if a source hasn't been specified
+[ -z "$cpio_source" -a -z "$default_list" ] && default_initramfs
 
 exit 0
diff -Nru a/scripts/kallsyms.c b/scripts/kallsyms.c
--- a/scripts/kallsyms.c	2005-03-01 23:39:17 -08:00
+++ b/scripts/kallsyms.c	2005-03-01 23:39:17 -08:00
@@ -184,6 +184,15 @@
 		if ((s->addr < _stext || s->addr > _etext)
 		    && (s->addr < _sinittext || s->addr > _einittext))
 			return 0;
+		/* Corner case.  Discard any symbols with the same value as
+		 * _etext or _einittext, they can move between pass 1 and 2
+		 * when the kallsyms data is added.  If these symbols move then
+		 * they may get dropped in pass 2, which breaks the kallsyms
+		 * rules.
+		 */
+		if ((s->addr == _etext && strcmp(s->sym + 1, "_etext")) ||
+		    (s->addr == _einittext && strcmp(s->sym + 1, "_einittext")))
+			return 0;
 	}
 
 	/* Exclude symbols which vary between passes. */
diff -Nru a/scripts/kconfig/expr.c b/scripts/kconfig/expr.c
--- a/scripts/kconfig/expr.c	2005-03-01 23:38:55 -08:00
+++ b/scripts/kconfig/expr.c	2005-03-01 23:38:55 -08:00
@@ -1087,3 +1087,13 @@
 {
 	expr_print(e, expr_print_file_helper, out, E_NONE);
 }
+
+static void expr_print_gstr_helper(void *data, const char *str)
+{
+	str_append((struct gstr*)data, str);
+}
+
+void expr_gstr_print(struct expr *e, struct gstr *gs)
+{
+	expr_print(e, expr_print_gstr_helper, gs, E_NONE);
+}
diff -Nru a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h
--- a/scripts/kconfig/expr.h	2005-03-01 23:39:07 -08:00
+++ b/scripts/kconfig/expr.h	2005-03-01 23:39:07 -08:00
@@ -174,6 +174,8 @@
 struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym);
 
 void expr_fprint(struct expr *e, FILE *out);
+struct gstr; /* forward */
+void expr_gstr_print(struct expr *e, struct gstr *gs);
 
 static inline int expr_is_yes(struct expr *e)
 {
diff -Nru a/scripts/kconfig/gconf.c b/scripts/kconfig/gconf.c
--- a/scripts/kconfig/gconf.c	2005-03-01 23:39:16 -08:00
+++ b/scripts/kconfig/gconf.c	2005-03-01 23:39:16 -08:00
@@ -187,8 +187,6 @@
 	GtkWidget *widget;
 	GtkTextBuffer *txtbuf;
 	char title[256];
-	GdkPixmap *pixmap;
-	GdkBitmap *mask;
 	GtkStyle *style;
 
 	xml = glade_xml_new(glade_file, "window1", NULL);
@@ -220,36 +218,6 @@
 
 	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);
 
 	switch (view_mode) {
 	case SINGLE_VIEW:
diff -Nru a/scripts/kconfig/gconf.glade b/scripts/kconfig/gconf.glade
--- a/scripts/kconfig/gconf.glade	2005-03-01 23:38:57 -08:00
+++ b/scripts/kconfig/gconf.glade	2005-03-01 23:38:57 -08:00
@@ -310,13 +310,13 @@
 	      <property name="tooltips">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>
+		  <signal name="clicked" handler="on_back_pressed"/>
 		</widget>
 	      </child>
 
@@ -327,24 +327,24 @@
 	      </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>
+		  <signal name="clicked" handler="on_load_pressed"/>
 		</widget>
 	      </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>
+		  <signal name="clicked" handler="on_save_pressed"/>
 		</widget>
 	      </child>
 
@@ -355,34 +355,34 @@
 	      </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-indent</property>
 		  <signal name="clicked" handler="on_single_clicked" last_modification_time="Sun, 12 Jan 2003 14:28:39 GMT"/>
 		</widget>
 	      </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-copy</property>
 		  <signal name="clicked" handler="on_split_clicked" last_modification_time="Sun, 12 Jan 2003 14:28:45 GMT"/>
 		</widget>
 	      </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-justify-left</property>
 		  <signal name="clicked" handler="on_full_clicked" last_modification_time="Sun, 12 Jan 2003 14:28:50 GMT"/>
 		</widget>
 	      </child>
@@ -394,22 +394,24 @@
 	      </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-zoom-out</property>
+		  <signal name="clicked" handler="on_collapse_pressed"/>
 		</widget>
 	      </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-zoom-in</property>
+		  <signal name="clicked" handler="on_expand_pressed"/>
 		</widget>
 	      </child>
 	    </widget>
diff -Nru a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h
--- a/scripts/kconfig/lkc.h	2005-03-01 23:38:51 -08:00
+++ b/scripts/kconfig/lkc.h	2005-03-01 23:38:51 -08:00
@@ -56,8 +56,21 @@
 void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep);
 void menu_finalize(struct menu *parent);
 void menu_set_type(int type);
+
+/* util.c */
 struct file *file_lookup(const char *name);
 int file_write_dep(const char *name);
+
+struct gstr {
+	size_t len;
+	char  *s;
+};
+struct gstr str_new(void);
+struct gstr str_assign(const char *s);
+void str_free(struct gstr *gs);
+void str_append(struct gstr *gs, const char *s);
+void str_printf(struct gstr *gs, const char *fmt, ...);
+const char *str_get(struct gstr *gs);
 
 /* symbol.c */
 void sym_init(void);
diff -Nru a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h
--- a/scripts/kconfig/lkc_proto.h	2005-03-01 23:38:55 -08:00
+++ b/scripts/kconfig/lkc_proto.h	2005-03-01 23:38:55 -08:00
@@ -18,6 +18,7 @@
 
 P(sym_lookup,struct symbol *,(const char *name, int isconst));
 P(sym_find,struct symbol *,(const char *name));
+P(sym_re_search,struct symbol **,(const char *pattern));
 P(sym_type_name,const char *,(enum symbol_type type));
 P(sym_calc_value,void,(struct symbol *sym));
 P(sym_get_type,enum symbol_type,(struct symbol *sym));
diff -Nru a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c
--- a/scripts/kconfig/mconf.c	2005-03-01 23:38:53 -08:00
+++ b/scripts/kconfig/mconf.c	2005-03-01 23:38:53 -08:00
@@ -18,13 +18,146 @@
 #include <string.h>
 #include <termios.h>
 #include <unistd.h>
-#include <regex.h>
 
 #define LKC_DIRECT_LINK
 #include "lkc.h"
 
 static char menu_backtitle[128];
-static const char menu_instructions[] =
+static const char mconf_readme[] =
+"Overview\n"
+"--------\n"
+"Some kernel features may be built directly into the kernel.\n"
+"Some may be made into loadable runtime modules.  Some features\n"
+"may be completely removed altogether.  There are also certain\n"
+"kernel parameters which are not really features, but must be\n"
+"entered in as decimal or hexadecimal numbers or possibly text.\n"
+"\n"
+"Menu items beginning with [*], <M> or [ ] represent features\n"
+"configured to be built in, modularized or removed respectively.\n"
+"Pointed brackets <> represent module capable features.\n"
+"\n"
+"To change any of these features, highlight it with the cursor\n"
+"keys and press <Y> to build it in, <M> to make it a module or\n"
+"<N> to removed it.  You may also press the <Space Bar> to cycle\n"
+"through the available options (ie. Y->N->M->Y).\n"
+"\n"
+"Some additional keyboard hints:\n"
+"\n"
+"Menus\n"
+"----------\n"
+"o  Use the Up/Down arrow keys (cursor keys) to highlight the item\n"
+"   you wish to change or submenu wish to select and press <Enter>.\n"
+"   Submenus are designated by \"--->\".\n"
+"\n"
+"   Shortcut: Press the option's highlighted letter (hotkey).\n"
+"             Pressing a hotkey more than once will sequence\n"
+"             through all visible items which use that hotkey.\n"
+"\n"
+"   You may also use the <PAGE UP> and <PAGE DOWN> keys to scroll\n"
+"   unseen options into view.\n"
+"\n"
+"o  To exit a menu use the cursor keys to highlight the <Exit> button\n"
+"   and press <ENTER>.\n"
+"\n"
+"   Shortcut: Press <ESC><ESC> or <E> or <X> if there is no hotkey\n"
+"             using those letters.  You may press a single <ESC>, but\n"
+"             there is a delayed response which you may find annoying.\n"
+"\n"
+"   Also, the <TAB> and cursor keys will cycle between <Select>,\n"
+"   <Exit> and <Help>\n"
+"\n"
+"o  To get help with an item, use the cursor keys to highlight <Help>\n"
+"   and Press <ENTER>.\n"
+"\n"
+"   Shortcut: Press <H> or <?>.\n"
+"\n"
+"\n"
+"Radiolists  (Choice lists)\n"
+"-----------\n"
+"o  Use the cursor keys to select the option you wish to set and press\n"
+"   <S> or the <SPACE BAR>.\n"
+"\n"
+"   Shortcut: Press the first letter of the option you wish to set then\n"
+"             press <S> or <SPACE BAR>.\n"
+"\n"
+"o  To see available help for the item, use the cursor keys to highlight\n"
+"   <Help> and Press <ENTER>.\n"
+"\n"
+"   Shortcut: Press <H> or <?>.\n"
+"\n"
+"   Also, the <TAB> and cursor keys will cycle between <Select> and\n"
+"   <Help>\n"
+"\n"
+"\n"
+"Data Entry\n"
+"-----------\n"
+"o  Enter the requested information and press <ENTER>\n"
+"   If you are entering hexadecimal values, it is not necessary to\n"
+"   add the '0x' prefix to the entry.\n"
+"\n"
+"o  For help, use the <TAB> or cursor keys to highlight the help option\n"
+"   and press <ENTER>.  You can try <TAB><H> as well.\n"
+"\n"
+"\n"
+"Text Box    (Help Window)\n"
+"--------\n"
+"o  Use the cursor keys to scroll up/down/left/right.  The VI editor\n"
+"   keys h,j,k,l function here as do <SPACE BAR> and <B> for those\n"
+"   who are familiar with less and lynx.\n"
+"\n"
+"o  Press <E>, <X>, <Enter> or <Esc><Esc> to exit.\n"
+"\n"
+"\n"
+"Alternate Configuration Files\n"
+"-----------------------------\n"
+"Menuconfig supports the use of alternate configuration files for\n"
+"those who, for various reasons, find it necessary to switch\n"
+"between different kernel configurations.\n"
+"\n"
+"At the end of the main menu you will find two options.  One is\n"
+"for saving the current configuration to a file of your choosing.\n"
+"The other option is for loading a previously saved alternate\n"
+"configuration.\n"
+"\n"
+"Even if you don't use alternate configuration files, but you\n"
+"find during a Menuconfig session that you have completely messed\n"
+"up your settings, you may use the \"Load Alternate...\" option to\n"
+"restore your previously saved settings from \".config\" without\n"
+"restarting Menuconfig.\n"
+"\n"
+"Other information\n"
+"-----------------\n"
+"If you use Menuconfig in an XTERM window make sure you have your\n"
+"$TERM variable set to point to a xterm definition which supports color.\n"
+"Otherwise, Menuconfig will look rather bad.  Menuconfig will not\n"
+"display correctly in a RXVT window because rxvt displays only one\n"
+"intensity of color, bright.\n"
+"\n"
+"Menuconfig will display larger menus on screens or xterms which are\n"
+"set to display more than the standard 25 row by 80 column geometry.\n"
+"In order for this to work, the \"stty size\" command must be able to\n"
+"display the screen's current row and column geometry.  I STRONGLY\n"
+"RECOMMEND that you make sure you do NOT have the shell variables\n"
+"LINES and COLUMNS exported into your environment.  Some distributions\n"
+"export those variables via /etc/profile.  Some ncurses programs can\n"
+"become confused when those variables (LINES & COLUMNS) don't reflect\n"
+"the true screen size.\n"
+"\n"
+"Optional personality available\n"
+"------------------------------\n"
+"If you prefer to have all of the kernel options listed in a single\n"
+"menu, rather than the default multimenu hierarchy, run the menuconfig\n"
+"with MENUCONFIG_MODE environment variable set to single_menu. Example:\n"
+"\n"
+"make MENUCONFIG_MODE=single_menu menuconfig\n"
+"\n"
+"<Enter> will then unroll the appropriate category, or enfold it if it\n"
+"is already unrolled.\n"
+"\n"
+"Note that this mode can eventually be a little more CPU expensive\n"
+"(especially with a larger number of unrolled categories) than the\n"
+"default mode.\n",
+menu_instructions[] =
 	"Arrow keys navigate the menu.  "
 	"<Enter> selects submenus --->.  "
 	"Highlighted letters are hotkeys.  "
@@ -79,8 +212,45 @@
 	"configuration options you have selected at that time.\n"
 	"\n"
 	"If you are uncertain what all this means then you should probably\n"
-	"leave this blank.\n"
-;
+	"leave this blank.\n",
+search_help[] =
+	"\n"
+	"Search for CONFIG_ symbols and display their relations.\n"
+	"Example: search for \"^FOO\"\n"
+	"Result:\n"
+	"-----------------------------------------------------------------\n"
+	"Symbol: FOO [=m]\n"
+	"Prompt: Foo bus is used to drive the bar HW\n"
+	"Defined at drivers/pci/Kconfig:47\n"
+	"Depends on: X86_LOCAL_APIC && X86_IO_APIC || IA64\n"
+	"Location:\n"
+	"  -> Bus options (PCI, PCMCIA, EISA, MCA, ISA)\n"
+	"    -> PCI support (PCI [=y])\n"
+	"      -> PCI access mode (<choice> [=y])\n"
+	"Selects: LIBCRC32\n"
+	"Selected by: BAR\n"
+	"-----------------------------------------------------------------\n"
+	"o The line 'Prompt:' shows the text used in the menu structure for\n"
+	"  this CONFIG_ symbol\n"
+	"o The 'Defined at' line tell at what file / line number the symbol\n"
+	"  is defined\n"
+	"o The 'Depends on:' line tell what symbols needs to be defined for\n"
+	"  this symbol to be visible in the menu (selectable)\n"
+	"o The 'Location:' lines tell where in the menu structure this symbol\n"
+	"  is located\n"
+	"    A location followed by a [=y] indicate that this is a selectable\n"
+	"    menu item - and current value is displayed inside brackets.\n"
+	"o The 'Selects:' line tell what symbol will be automatically\n"
+	"  selected if this symbol is selected (y or m)\n"
+	"o The 'Selected by' line tell what symbol has selected this symbol\n"
+	"\n"
+	"Only relevant lines are shown.\n"
+	"\n\n"
+	"Search examples:\n"
+	"Examples: USB	=> find all CONFIG_ symbols containing USB\n"
+	"          ^USB => find all CONFIG_ symbols starting with USB\n"
+	"          USB$ => find all CONFIG_ symbols ending with USB\n"
+	"\n";
 
 static signed char buf[4096], *bufptr = buf;
 static signed char input_buf[4096];
@@ -102,11 +272,7 @@
 static void show_textbox(const char *title, const char *text, int r, int c);
 static void show_helptext(const char *title, const char *text);
 static void show_help(struct menu *menu);
-static void show_readme(void);
 static void show_file(const char *filename, const char *title, int r, int c);
-static void show_expr(struct menu *menu, FILE *fp);
-static void search_conf(char *pattern);
-static int regex_match(const char *string, regex_t *re);
 
 static void cprint_init(void);
 static int cprint1(const char *fmt, ...);
@@ -196,6 +362,78 @@
 	return res;
 }
 
+static void get_prompt_str(struct gstr *r, struct property *prop)
+{
+	int i, j;
+	struct menu *submenu[8], *menu;
+
+	str_printf(r, "Prompt: %s\n", prop->text);
+	str_printf(r, "  Defined at %s:%d\n", prop->menu->file->name,
+		prop->menu->lineno);
+	if (!expr_is_yes(prop->visible.expr)) {
+		str_append(r, "  Depends on: ");
+		expr_gstr_print(prop->visible.expr, r);
+		str_append(r, "\n");
+	}
+	menu = prop->menu->parent;
+	for (i = 0; menu != &rootmenu && i < 8; menu = menu->parent)
+		submenu[i++] = menu;
+	if (i > 0) {
+		str_printf(r, "  Location:\n");
+		for (j = 4; --i >= 0; j += 2) {
+			menu = submenu[i];
+			str_printf(r, "%*c-> %s", j, ' ', menu_get_prompt(menu));
+			if (menu->sym) {
+				str_printf(r, " (%s [=%s])", menu->sym->name ?
+					menu->sym->name : "<choice>",
+					sym_get_string_value(menu->sym));
+			}
+			str_append(r, "\n");
+		}
+	}
+}
+
+static void get_symbol_str(struct gstr *r, struct symbol *sym)
+{
+	bool hit;
+	struct property *prop;
+
+	str_printf(r, "Symbol: %s [=%s]\n", sym->name,
+	                               sym_get_string_value(sym));
+	for_all_prompts(sym, prop)
+		get_prompt_str(r, prop);
+	hit = false;
+	for_all_properties(sym, prop, P_SELECT) {
+		if (!hit) {
+			str_append(r, "  Selects: ");
+			hit = true;
+		} else
+			str_printf(r, " && ");
+		expr_gstr_print(prop->expr, r);
+	}
+	if (hit)
+		str_append(r, "\n");
+	if (sym->rev_dep.expr) {
+		str_append(r, "  Selected by: ");
+		expr_gstr_print(sym->rev_dep.expr, r);
+		str_append(r, "\n");
+	}
+	str_append(r, "\n\n");
+}
+
+static struct gstr get_relations_str(struct symbol **sym_arr)
+{
+	struct symbol *sym;
+	struct gstr res = str_new();
+	int i;
+
+	for (i = 0; sym_arr && (sym = sym_arr[i]); i++)
+		get_symbol_str(&res, sym);
+	if (!i)
+		str_append(&res, "No matches found.\n");
+	return res;
+}
+
 pid_t pid;
 
 static void winch_handler(int sig)
@@ -279,112 +517,39 @@
 	return WEXITSTATUS(stat);
 }
 
-static int regex_match(const char *string, regex_t *re)
+static void search_conf(void)
 {
-	int rc;
-
-	rc = regexec(re, string, (size_t) 0, NULL, 0);
-	if (rc)
-		return 0;
-	return 1;
-}
-
-static void show_expr(struct menu *menu, FILE *fp)
-{
-	bool hit = false;
-	fprintf(fp, "Depends:\n ");
-	if (menu->prompt->visible.expr) {
-		if (!hit)
-			hit = true;
-		expr_fprint(menu->prompt->visible.expr, fp);
-	}
-	if (!hit)
-		fprintf(fp, "None");
-	if (menu->sym) {
-		struct property *prop;
-		hit = false;
-		fprintf(fp, "\nSelects:\n ");
-		for_all_properties(menu->sym, prop, P_SELECT) {
-			if (!hit)
-				hit = true;
-			expr_fprint(prop->expr, fp);
-		}
-		if (!hit)
-			fprintf(fp, "None");
-		hit = false;
-		fprintf(fp, "\nSelected by:\n ");
-		if (menu->sym->rev_dep.expr) {
-			hit = true;
-			expr_fprint(menu->sym->rev_dep.expr, fp);
-		}
-		if (!hit)
-			fprintf(fp, "None");
-	}
-}
-
-static void search_conf(char *pattern)
-{
-	struct symbol *sym = NULL;
-	struct menu *menu[32] = { 0 };
-	struct property *prop = NULL;
-	FILE *fp = NULL;
-	bool hit = false;
-	int i, j, k, l;
-	regex_t re;
-
-	if (regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB))
+	struct symbol **sym_arr;
+	int stat;
+	struct gstr res;
+
+again:
+	cprint_init();
+	cprint("--title");
+	cprint("Search Configuration Parameter");
+	cprint("--inputbox");
+	cprint("Enter Keyword");
+	cprint("10");
+	cprint("75");
+	cprint("");
+	stat = exec_conf();
+	if (stat < 0)
+		goto again;
+	switch (stat) {
+	case 0:
+		break;
+	case 1:
+		show_helptext("Search Configuration", search_help);
+		goto again;
+	default:
 		return;
-
-	fp = fopen(".search.tmp", "w");
-	if (fp == NULL) {
-		perror("fopen");
-		return;
-	}
-	for_all_symbols(i, sym) {
-		if (!sym->name)
-			continue;
-		if (!regex_match(sym->name, &re))
-			continue;
-		for_all_prompts(sym, prop) {
-			struct menu *submenu = prop->menu;
-			if (!submenu)
-				continue;
-			j = 0;
-			hit = false;
-			while (submenu) {
-				menu[j++] = submenu;
-				submenu = submenu->parent;
-			}
-			if (j > 0) {
-				if (!hit)
-					hit = true;
-				fprintf(fp, "%s (%s)\n", prop->text, sym->name);
-				fprintf(fp, "Location:\n");
-			}
-			for (k = j-2, l=1; k > 0; k--, l++) {
-				const char *prompt = menu_get_prompt(menu[k]);
-				if (menu[k]->sym)
-					fprintf(fp, "%*c-> %s (%s)\n",
-								l, ' ',
-								prompt,
-								menu[k]->sym->name);
-				else
-					fprintf(fp, "%*c-> %s\n",
-								l, ' ',
-								prompt);
-			}
-			if (hit) {
-				show_expr(menu[0], fp);
-				fprintf(fp, "\n\n\n");
-			}
-		}
 	}
-	if (!hit)
-		fprintf(fp, "No matches found.");
-	regfree(&re);
-	fclose(fp);
-	show_file(".search.tmp", "Search Results", rows, cols);
-	unlink(".search.tmp");
+
+	sym_arr = sym_re_search(input_buf);
+	res = get_relations_str(sym_arr);
+	free(sym_arr);
+	show_textbox("Search Results", str_get(&res), 0, 0);
+	str_free(&res);
 }
 
 static void build_conf(struct menu *menu)
@@ -576,23 +741,6 @@
 			cprint("    Save Configuration to an Alternate File");
 		}
 		stat = exec_conf();
-		if (stat == 26) {
-			char *pattern;
-
-			if (!strlen(input_buf))
-				continue;
-			pattern = malloc(sizeof(char)*sizeof(input_buf));
-			if (pattern == NULL) {
-				perror("malloc");
-				continue;
-			}
-			for (i = 0; input_buf[i]; i++)
-				pattern[i] = toupper(input_buf[i]);
-			pattern[i] = '\0';
-			search_conf(pattern);
-			free(pattern);
-			continue;
-		}
 		if (stat < 0)
 			continue;
 
@@ -645,7 +793,7 @@
 			if (sym)
 				show_help(submenu);
 			else
-				show_readme();
+				show_helptext("README", mconf_readme);
 			break;
 		case 3:
 			if (type == 't') {
@@ -669,6 +817,9 @@
 			else if (type == 'm')
 				conf(submenu);
 			break;
+		case 7:
+			search_conf();
+			break;
 		}
 	}
 }
@@ -686,30 +837,27 @@
 
 static void show_helptext(const char *title, const char *text)
 {
-	show_textbox(title, text, rows, cols);
+	show_textbox(title, text, 0, 0);
 }
 
 static void show_help(struct menu *menu)
 {
-	const char *help;
-	char *helptext;
+	struct gstr help = str_new();
 	struct symbol *sym = menu->sym;
 
-	help = sym->help;
-	if (!help)
-		help = nohelp_text;
-	if (sym->name) {
-		helptext = malloc(strlen(sym->name) + strlen(help) + 16);
-		sprintf(helptext, "CONFIG_%s:\n\n%s", sym->name, help);
-		show_helptext(menu_get_prompt(menu), helptext);
-		free(helptext);
-	} else
-		show_helptext(menu_get_prompt(menu), help);
-}
-
-static void show_readme(void)
-{
-	show_file("scripts/README.Menuconfig", NULL, rows, cols);
+	if (sym->help)
+	{
+		if (sym->name) {
+			str_printf(&help, "CONFIG_%s:\n\n", sym->name);
+			str_append(&help, sym->help);
+			str_append(&help, "\n");
+		}
+	} else {
+		str_append(&help, nohelp_text);
+	}
+	get_symbol_str(&help, sym);
+	show_helptext(menu_get_prompt(menu), str_get(&help));
+	str_free(&help);
 }
 
 static void show_file(const char *filename, const char *title, int r, int c)
@@ -722,8 +870,8 @@
 		}
 		cprint("--textbox");
 		cprint("%s", filename);
-		cprint("%d", r);
-		cprint("%d", c);
+		cprint("%d", r ? r : rows);
+		cprint("%d", c ? c : cols);
 	} while (exec_conf() < 0);
 }
 
diff -Nru a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c
--- a/scripts/kconfig/menu.c	2005-03-01 23:39:16 -08:00
+++ b/scripts/kconfig/menu.c	2005-03-01 23:39:16 -08:00
@@ -388,43 +388,3 @@
 	return menu;
 }
 
-struct file *file_lookup(const char *name)
-{
-	struct file *file;
-
-	for (file = file_list; file; file = file->next) {
-		if (!strcmp(name, file->name))
-			return file;
-	}
-
-	file = malloc(sizeof(*file));
-	memset(file, 0, sizeof(*file));
-	file->name = strdup(name);
-	file->next = file_list;
-	file_list = file;
-	return file;
-}
-
-int file_write_dep(const char *name)
-{
-	struct file *file;
-	FILE *out;
-
-	if (!name)
-		name = ".config.cmd";
-	out = fopen("..config.tmp", "w");
-	if (!out)
-		return 1;
-	fprintf(out, "deps_config := \\\n");
-	for (file = file_list; file; file = file->next) {
-		if (file->next)
-			fprintf(out, "\t%s \\\n", file->name);
-		else
-			fprintf(out, "\t%s\n", file->name);
-	}
-	fprintf(out, "\n.config include/linux/autoconf.h: $(deps_config)\n\n$(deps_config):\n");
-	fclose(out);
-	rename("..config.tmp", name);
-	return 0;
-}
-
diff -Nru a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c
--- a/scripts/kconfig/symbol.c	2005-03-01 23:38:54 -08:00
+++ b/scripts/kconfig/symbol.c	2005-03-01 23:38:54 -08:00
@@ -6,6 +6,7 @@
 #include <ctype.h>
 #include <stdlib.h>
 #include <string.h>
+#include <regex.h>
 #include <sys/utsname.h>
 
 #define LKC_DIRECT_LINK
@@ -655,6 +656,43 @@
 
 	return symbol;
 }
+
+struct symbol **sym_re_search(const char *pattern)
+{
+	struct symbol *sym, **sym_arr = NULL;
+	int i, cnt, size;
+	regex_t re;
+
+	cnt = size = 0;
+	/* Skip if empty */
+	if (strlen(pattern) == 0)
+		return NULL;
+	if (regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB|REG_ICASE))
+		return NULL;
+
+	for_all_symbols(i, sym) {
+		if (sym->flags & SYMBOL_CONST || !sym->name)
+			continue;
+		if (regexec(&re, sym->name, 0, NULL, 0))
+			continue;
+		if (cnt + 1 >= size) {
+			void *tmp = sym_arr;
+			size += 16;
+			sym_arr = realloc(sym_arr, size * sizeof(struct symbol *));
+			if (!sym_arr) {
+				free(tmp);
+				return NULL;
+			}
+		}
+		sym_arr[cnt++] = sym;
+	}
+	if (sym_arr)
+		sym_arr[cnt] = NULL;
+	regfree(&re);
+
+	return sym_arr;
+}
+
 
 struct symbol *sym_check_deps(struct symbol *sym);
 
diff -Nru a/scripts/kconfig/util.c b/scripts/kconfig/util.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/scripts/kconfig/util.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2002-2005 Roman Zippel <zippel@linux-m68k.org>
+ * Copyright (C) 2002-2005 Sam Ravnborg <sam@ravnborg.org>
+ *
+ * Released under the terms of the GNU GPL v2.0.
+ */
+
+#include <string.h>
+#include "lkc.h"
+
+/* file already present in list? If not add it */
+struct file *file_lookup(const char *name)
+{
+	struct file *file;
+
+	for (file = file_list; file; file = file->next) {
+		if (!strcmp(name, file->name))
+			return file;
+	}
+
+	file = malloc(sizeof(*file));
+	memset(file, 0, sizeof(*file));
+	file->name = strdup(name);
+	file->next = file_list;
+	file_list = file;
+	return file;
+}
+
+/* write a dependency file as used by kbuild to track dependencies */
+int file_write_dep(const char *name)
+{
+	struct file *file;
+	FILE *out;
+
+	if (!name)
+		name = ".config.cmd";
+	out = fopen("..config.tmp", "w");
+	if (!out)
+		return 1;
+	fprintf(out, "deps_config := \\\n");
+	for (file = file_list; file; file = file->next) {
+		if (file->next)
+			fprintf(out, "\t%s \\\n", file->name);
+		else
+			fprintf(out, "\t%s\n", file->name);
+	}
+	fprintf(out, "\n.config include/linux/autoconf.h: $(deps_config)\n\n$(deps_config):\n");
+	fclose(out);
+	rename("..config.tmp", name);
+	return 0;
+}
+
+
+/* Allocate initial growable sting */
+struct gstr str_new(void)
+{
+	struct gstr gs;
+	gs.s = malloc(sizeof(char) * 64);
+	gs.len = 16;
+	strcpy(gs.s, "\0");
+	return gs;
+}
+
+/* Allocate and assign growable string */
+struct gstr str_assign(const char *s)
+{
+	struct gstr gs;
+	gs.s = strdup(s);
+	gs.len = strlen(s) + 1;
+	return gs;
+}
+
+/* Free storage for growable string */
+void str_free(struct gstr *gs)
+{
+	if (gs->s)
+		free(gs->s);
+	gs->s = NULL;
+	gs->len = 0;
+}
+
+/* Append to growable string */
+void str_append(struct gstr *gs, const char *s)
+{
+	size_t l = strlen(gs->s) + strlen(s) + 1;
+	if (l > gs->len) {
+		gs->s   = realloc(gs->s, l);
+		gs->len = l;
+	}
+	strcat(gs->s, s);
+}
+
+/* Append printf formatted string to growable string */
+void str_printf(struct gstr *gs, const char *fmt, ...)
+{
+	va_list ap;
+	char s[10000]; /* big enough... */
+	va_start(ap, fmt);
+	vsnprintf(s, sizeof(s), fmt, ap);
+	str_append(gs, s);
+	va_end(ap);
+}
+
+/* Retreive value of growable string */
+const char *str_get(struct gstr *gs)
+{
+	return gs->s;
+}
+
diff -Nru a/scripts/kconfig/zconf.tab.c_shipped b/scripts/kconfig/zconf.tab.c_shipped
--- a/scripts/kconfig/zconf.tab.c_shipped	2005-03-01 23:39:09 -08:00
+++ b/scripts/kconfig/zconf.tab.c_shipped	2005-03-01 23:39:09 -08:00
@@ -2121,6 +2121,7 @@
 }
 
 #include "lex.zconf.c"
+#include "util.c"
 #include "confdata.c"
 #include "expr.c"
 #include "symbol.c"
diff -Nru a/scripts/kconfig/zconf.y b/scripts/kconfig/zconf.y
--- a/scripts/kconfig/zconf.y	2005-03-01 23:39:16 -08:00
+++ b/scripts/kconfig/zconf.y	2005-03-01 23:39:16 -08:00
@@ -683,6 +683,7 @@
 }
 
 #include "lex.zconf.c"
+#include "util.c"
 #include "confdata.c"
 #include "expr.c"
 #include "symbol.c"
diff -Nru a/scripts/lxdialog/menubox.c b/scripts/lxdialog/menubox.c
--- a/scripts/lxdialog/menubox.c	2005-03-01 23:39:16 -08:00
+++ b/scripts/lxdialog/menubox.c	2005-03-01 23:39:16 -08:00
@@ -276,15 +276,6 @@
 
     while (key != ESC) {
 	key = wgetch(menu);
-	if ( key == '/' ) {
-		int ret = dialog_inputbox("Search Configuration Parameter",
-					"Enter Keyword", height, width,
-					(char *) NULL);
-		if (ret == 0) {
-			fprintf(stderr, "%s", dialog_input_result);
-			return 26;
-		}
-	}
 
 	if (key < 256 && isalpha(key)) key = tolower(key);
 
@@ -408,6 +399,7 @@
 	case 'y':
 	case 'n':
 	case 'm':
+	case '/':
 	    /* save scroll info */
 	    if ( (f=fopen("lxdialog.scrltmp","w")) != NULL ) {
 		fprintf(f,"%d\n",scroll);
@@ -421,6 +413,7 @@
             case 'n': return 4;
             case 'm': return 5;
             case ' ': return 6;
+            case '/': return 7;
             }
 	    return 0;
 	case 'h':
diff -Nru a/scripts/reference_discarded.pl b/scripts/reference_discarded.pl
--- a/scripts/reference_discarded.pl	2005-03-01 23:38:56 -08:00
+++ b/scripts/reference_discarded.pl	2005-03-01 23:38:56 -08:00
@@ -62,7 +62,7 @@
 		$l = read(OBJECT, $comment, $size);
 		die "read $size bytes from $object .comment failed" if ($l != $size);
 		close(OBJECT);
-		if ($comment =~ /GCC\:.*GCC\:/m) {
+		if ($comment =~ /GCC\:.*GCC\:/m || $object =~ /built-in\.o/) {
 			++$ignore;
 			delete($object{$object});
 		}
@@ -90,6 +90,7 @@
 		     $from !~ /\.data\.exit$/ &&
 		     $from !~ /\.exit\.data$/ &&
 		     $from !~ /\.altinstructions$/ &&
+		     $from !~ /\.pdr$/ &&
 		     $from !~ /\.debug_info$/ &&
 		     $from !~ /\.debug_aranges$/ &&
 		     $from !~ /\.debug_ranges$/ &&
diff -Nru a/scripts/reference_init.pl b/scripts/reference_init.pl
--- a/scripts/reference_init.pl	2005-03-01 23:39:08 -08:00
+++ b/scripts/reference_init.pl	2005-03-01 23:39:08 -08:00
@@ -70,7 +70,7 @@
 		$l = read(OBJECT, $comment, $size);
 		die "read $size bytes from $object .comment failed" if ($l != $size);
 		close(OBJECT);
-		if ($comment =~ /GCC\:.*GCC\:/m) {
+		if ($comment =~ /GCC\:.*GCC\:/m || $object =~ /built-in\.o/) {
 			++$ignore;
 			delete($object{$object});
 		}
@@ -95,7 +95,9 @@
 		     $from !~ /\.text\.lock$/ &&
 		     $from !~ /\.pci_fixup_header$/ &&
 		     $from !~ /\.pci_fixup_final$/ &&
+		     $from !~ /\.pdr$/ &&
 		     $from !~ /\__param$/ &&
+		     $from !~ /\.altinstructions/ &&
 		     $from !~ /\.debug_/)) {
 			printf("Error: %s %s refers to %s\n", $object, $from, $line);
 		}
diff -Nru a/scripts/ver_linux b/scripts/ver_linux
--- a/scripts/ver_linux	2005-03-01 23:39:07 -08:00
+++ b/scripts/ver_linux	2005-03-01 23:39:07 -08:00
@@ -87,6 +87,8 @@
 
 expr --v 2>&1 | awk 'NR==1{print "Sh-utils              ", $NF}'
 
+udevinfo -V | awk '{print "udev                  ", $3}'
+
 if [ -e /proc/modules ]; then
     X=`cat /proc/modules | sed -e "s/ .*$//"`
     echo "Modules Loaded         "$X
diff -Nru a/security/Kconfig b/security/Kconfig
--- a/security/Kconfig	2005-03-01 23:39:07 -08:00
+++ b/security/Kconfig	2005-03-01 23:39:07 -08:00
@@ -76,10 +76,11 @@
 config SECURITY_SECLVL
 	tristate "BSD Secure Levels"
 	depends on SECURITY
+	select CRYPTO
 	select CRYPTO_SHA1
 	help
 	  Implements BSD Secure Levels as an LSM.  See
-	  Documentation/seclvl.txt for instructions on how to use this
+	  <file:Documentation/seclvl.txt> for instructions on how to use this
 	  module.
 
 	  If you are unsure how to answer this question, answer N.
diff -Nru a/security/commoncap.c b/security/commoncap.c
--- a/security/commoncap.c	2005-03-01 23:38:55 -08:00
+++ b/security/commoncap.c	2005-03-01 23:38:55 -08:00
@@ -316,82 +316,13 @@
 	return 0;
 }
 
-/*
- * Check that a process has enough memory to allocate a new virtual
- * mapping. 0 means there is enough memory for the allocation to
- * succeed and -ENOMEM implies there is not.
- *
- * We currently support three overcommit policies, which are set via the
- * vm.overcommit_memory sysctl.  See Documentation/vm/overcommit-accounting
- *
- * Strict overcommit modes added 2002 Feb 26 by Alan Cox.
- * Additional code 2002 Jul 20 by Robert Love.
- */
 int cap_vm_enough_memory(long pages)
 {
-	unsigned long free, allowed;
+	int cap_sys_admin = 0;
 
-	vm_acct_memory(pages);
-
-	/*
-	 * Sometimes we want to use more memory than we have
-	 */
-	if (sysctl_overcommit_memory == OVERCOMMIT_ALWAYS)
-		return 0;
-
-	if (sysctl_overcommit_memory == OVERCOMMIT_GUESS) {
-		unsigned long n;
-
-		free = get_page_cache_size();
-		free += nr_swap_pages;
-
-		/*
-		 * Any slabs which are created with the
-		 * SLAB_RECLAIM_ACCOUNT flag claim to have contents
-		 * which are reclaimable, under pressure.  The dentry
-		 * cache and most inode caches should fall into this
-		 */
-		free += atomic_read(&slab_reclaim_pages);
-
-		/*
-		 * Leave the last 3% for root
-		 */
-		if (!capable(CAP_SYS_ADMIN))
-			free -= free / 32;
-
-		if (free > pages)
-			return 0;
-
-		/*
-		 * nr_free_pages() is very expensive on large systems,
-		 * only call if we're about to fail.
-		 */
-		n = nr_free_pages();
-		if (!capable(CAP_SYS_ADMIN))
-			n -= n / 32;
-		free += n;
-
-		if (free > pages)
-			return 0;
-		vm_unacct_memory(pages);
-		return -ENOMEM;
-	}
-
-	allowed = (totalram_pages - hugetlb_total_pages())
-	       	* sysctl_overcommit_ratio / 100;
-	/*
-	 * Leave the last 3% for root
-	 */
-	if (!capable(CAP_SYS_ADMIN))
-		allowed -= allowed / 32;
-	allowed += total_swap_pages;
-
-	if (atomic_read(&vm_committed_space) < allowed)
-		return 0;
-
-	vm_unacct_memory(pages);
-
-	return -ENOMEM;
+	if (cap_capable(current, CAP_SYS_ADMIN) == 0)
+		cap_sys_admin = 1;
+	return __vm_enough_memory(pages, cap_sys_admin);
 }
 
 EXPORT_SYMBOL(cap_capable);
diff -Nru a/security/dummy.c b/security/dummy.c
--- a/security/dummy.c	2005-03-01 23:38:53 -08:00
+++ b/security/dummy.c	2005-03-01 23:38:53 -08:00
@@ -74,11 +74,8 @@
 
 static int dummy_capable (struct task_struct *tsk, int cap)
 {
-	if (cap_is_fs_cap (cap) ? tsk->fsuid == 0 : tsk->euid == 0)
-		/* capability granted */
+	if (cap_raised (tsk->cap_effective, cap))
 		return 0;
-
-	/* capability denied */
 	return -EPERM;
 }
 
@@ -92,7 +89,7 @@
 	return 0;
 }
 
-static int dummy_quota_on (struct file *f)
+static int dummy_quota_on (struct dentry *dentry)
 {
 	return 0;
 }
@@ -111,61 +108,13 @@
 	return 0;
 }
 
-/*
- * Check that a process has enough memory to allocate a new virtual
- * mapping. 0 means there is enough memory for the allocation to
- * succeed and -ENOMEM implies there is not.
- *
- * We currently support three overcommit policies, which are set via the
- * vm.overcommit_memory sysctl.  See Documentation/vm/overcommit-accounting
- */
 static int dummy_vm_enough_memory(long pages)
 {
-	unsigned long free, allowed;
-
-	vm_acct_memory(pages);
-
-	/*
-	 * Sometimes we want to use more memory than we have
-	 */
-	if (sysctl_overcommit_memory == OVERCOMMIT_ALWAYS)
-		return 0;
+	int cap_sys_admin = 0;
 
-	if (sysctl_overcommit_memory == OVERCOMMIT_GUESS) {
-		free = get_page_cache_size();
-		free += nr_free_pages();
-		free += nr_swap_pages;
-
-		/*
-		 * Any slabs which are created with the
-		 * SLAB_RECLAIM_ACCOUNT flag claim to have contents
-		 * which are reclaimable, under pressure.  The dentry
-		 * cache and most inode caches should fall into this
-		 */
-		free += atomic_read(&slab_reclaim_pages);
-
-		/*
-		 * Leave the last 3% for root
-		 */
-		if (current->euid)
-			free -= free / 32;
-
-		if (free > pages)
-			return 0;
-		vm_unacct_memory(pages);
-		return -ENOMEM;
-	}
-
-	allowed = (totalram_pages - hugetlb_total_pages())
-		* sysctl_overcommit_ratio / 100;
-	allowed += total_swap_pages;
-
-	if (atomic_read(&vm_committed_space) < allowed)
-		return 0;
-
-	vm_unacct_memory(pages);
-
-	return -ENOMEM;
+	if (dummy_capable(current, CAP_SYS_ADMIN) == 0)
+		cap_sys_admin = 1;
+	return __vm_enough_memory(pages, cap_sys_admin);
 }
 
 static int dummy_bprm_alloc_security (struct linux_binprm *bprm)
@@ -191,6 +140,13 @@
 
 	current->suid = current->euid = current->fsuid = bprm->e_uid;
 	current->sgid = current->egid = current->fsgid = bprm->e_gid;
+
+	dummy_capget(current, &current->cap_effective, &current->cap_inheritable, &current->cap_permitted);
+}
+
+static void dummy_bprm_post_apply_creds (struct linux_binprm *bprm)
+{
+	return;
 }
 
 static int dummy_bprm_set_security (struct linux_binprm *bprm)
@@ -550,6 +506,7 @@
 
 static int dummy_task_post_setuid (uid_t id0, uid_t id1, uid_t id2, int flags)
 {
+	dummy_capget(current, &current->cap_effective, &current->cap_inheritable, &current->cap_permitted);
 	return 0;
 }
 
@@ -728,10 +685,7 @@
 
 static int dummy_netlink_send (struct sock *sk, struct sk_buff *skb)
 {
-	if (current->euid == 0)
-		cap_raise (NETLINK_CB (skb).eff_cap, CAP_NET_ADMIN);
-	else
-		NETLINK_CB (skb).eff_cap = 0;
+	NETLINK_CB(skb).eff_cap = current->cap_effective;
 	return 0;
 }
 
@@ -908,6 +862,7 @@
 	set_to_dummy_if_null(ops, bprm_alloc_security);
 	set_to_dummy_if_null(ops, bprm_free_security);
 	set_to_dummy_if_null(ops, bprm_apply_creds);
+	set_to_dummy_if_null(ops, bprm_post_apply_creds);
 	set_to_dummy_if_null(ops, bprm_set_security);
 	set_to_dummy_if_null(ops, bprm_check_security);
 	set_to_dummy_if_null(ops, bprm_secureexec);
diff -Nru a/security/keys/compat.c b/security/keys/compat.c
--- a/security/keys/compat.c	2005-03-01 23:38:52 -08:00
+++ b/security/keys/compat.c	2005-03-01 23:38:52 -08:00
@@ -31,7 +31,7 @@
 		return keyctl_get_keyring_ID(arg2, arg3);
 
 	case KEYCTL_JOIN_SESSION_KEYRING:
-		return keyctl_join_session_keyring(compat_ptr(arg3));
+		return keyctl_join_session_keyring(compat_ptr(arg2));
 
 	case KEYCTL_UPDATE:
 		return keyctl_update_key(arg2, compat_ptr(arg3), arg4);
diff -Nru a/security/keys/key.c b/security/keys/key.c
--- a/security/keys/key.c	2005-03-01 23:39:09 -08:00
+++ b/security/keys/key.c	2005-03-01 23:39:09 -08:00
@@ -20,10 +20,10 @@
 static kmem_cache_t	*key_jar;
 static key_serial_t	key_serial_next = 3;
 struct rb_root		key_serial_tree; /* tree of keys indexed by serial */
-spinlock_t		key_serial_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(key_serial_lock);
 
 struct rb_root	key_user_tree; /* tree of quota records indexed by UID */
-spinlock_t	key_user_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(key_user_lock);
 
 static LIST_HEAD(key_types_list);
 static DECLARE_RWSEM(key_types_sem);
diff -Nru a/security/keys/keyctl.c b/security/keys/keyctl.c
--- a/security/keys/keyctl.c	2005-03-01 23:38:54 -08:00
+++ b/security/keys/keyctl.c	2005-03-01 23:38:54 -08:00
@@ -923,7 +923,7 @@
 					     (int) arg3);
 
 	case KEYCTL_JOIN_SESSION_KEYRING:
-		return keyctl_join_session_keyring((const char __user *) arg3);
+		return keyctl_join_session_keyring((const char __user *) arg2);
 
 	case KEYCTL_UPDATE:
 		return keyctl_update_key((key_serial_t) arg2,
diff -Nru a/security/keys/keyring.c b/security/keys/keyring.c
--- a/security/keys/keyring.c	2005-03-01 23:39:18 -08:00
+++ b/security/keys/keyring.c	2005-03-01 23:39:18 -08:00
@@ -30,7 +30,7 @@
 #define KEYRING_NAME_HASH_SIZE	(1 << 5)
 
 static struct list_head	keyring_name_hash[KEYRING_NAME_HASH_SIZE];
-static rwlock_t		keyring_name_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(keyring_name_lock);
 
 static inline unsigned keyring_hash(const char *desc)
 {
diff -Nru a/security/security.c b/security/security.c
--- a/security/security.c	2005-03-01 23:38:44 -08:00
+++ b/security/security.c	2005-03-01 23:38:44 -08:00
@@ -38,8 +38,8 @@
 static void __init do_security_initcalls(void)
 {
 	initcall_t *call;
-	call = &__security_initcall_start;
-	while (call < &__security_initcall_end) {
+	call = __security_initcall_start;
+	while (call < __security_initcall_end) {
 		(*call) ();
 		call++;
 	}
diff -Nru a/security/selinux/Kconfig b/security/selinux/Kconfig
--- a/security/selinux/Kconfig	2005-03-01 23:38:52 -08:00
+++ b/security/selinux/Kconfig	2005-03-01 23:38:52 -08:00
@@ -34,7 +34,7 @@
 	  'selinux', which allows SELinux to be disabled at boot.  If this
 	  option is set to 0 (zero), the SELinux kernel parameter will
 	  default to 0, disabling SELinux at bootup.  If this option is
-	  set to 1 (one), the SELinux kernel paramater will default to 1,
+	  set to 1 (one), the SELinux kernel parameter will default to 1,
 	  enabling SELinux at bootup.
 
 	  If you are unsure how to answer this question, answer 1.
@@ -66,6 +66,15 @@
 	  unless you specify enforcing=1 on the kernel command line.  You
 	  can interactively toggle the kernel between enforcing mode and
 	  permissive mode (if permitted by the policy) via /selinux/enforce.
+
+config SECURITY_SELINUX_AVC_STATS
+	bool "NSA SELinux AVC Statistics"
+	depends on SECURITY_SELINUX
+	default y
+	help
+	  This option collects access vector cache statistics to
+	  /selinux/avc/cache_stats, which may be monitored via
+	  tools such as avcstat.
 
 config SECURITY_SELINUX_MLS
 	bool "NSA SELinux MLS policy (EXPERIMENTAL)"
diff -Nru a/security/selinux/avc.c b/security/selinux/avc.c
--- a/security/selinux/avc.c	2005-03-01 23:39:08 -08:00
+++ b/security/selinux/avc.c	2005-03-01 23:39:08 -08:00
@@ -4,6 +4,9 @@
  * Authors:  Stephen Smalley, <sds@epoch.ncsc.mil>
  *           James Morris <jmorris@redhat.com>
  *
+ * Update:   KaiGai, Kohei <kaigai@ak.jp.nec.com>
+ *     Replaced the avc_lock spinlock by RCU.
+ *
  * Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com>
  *
  *	This program is free software; you can redistribute it and/or modify
@@ -18,6 +21,7 @@
 #include <linux/dcache.h>
 #include <linux/init.h>
 #include <linux/skbuff.h>
+#include <linux/percpu.h>
 #include <net/sock.h>
 #include <linux/un.h>
 #include <net/af_unix.h>
@@ -27,35 +31,79 @@
 #include <net/ipv6.h>
 #include "avc.h"
 #include "avc_ss.h"
+
+static const struct av_perm_to_string
+{
+  u16 tclass;
+  u32 value;
+  const char *name;
+} av_perm_to_string[] = {
+#define S_(c, v, s) { c, v, s },
+#include "av_perm_to_string.h"
+#undef S_
+};
+
 #ifdef CONFIG_AUDIT
+static const char *class_to_string[] = {
+#define S_(s) s,
 #include "class_to_string.h"
+#undef S_
+};
 #endif
+
+#define TB_(s) static const char * s [] = {
+#define TE_(s) };
+#define S_(s) s,
 #include "common_perm_to_string.h"
+#undef TB_
+#undef TE_
+#undef S_
+
+static const struct av_inherit
+{
+    u16 tclass;
+    const char **common_pts;
+    u32 common_base;
+} av_inherit[] = {
+#define S_(c, i, b) { c, common_##i##_perm_to_string, b },
 #include "av_inherit.h"
-#include "av_perm_to_string.h"
-#include "objsec.h"
+#undef S_
+};
 
-#define AVC_CACHE_SLOTS		512
-#define AVC_CACHE_MAXNODES	410
+#define AVC_CACHE_SLOTS			512
+#define AVC_DEF_CACHE_THRESHOLD		512
+#define AVC_CACHE_RECLAIM		16
+
+#ifdef CONFIG_SECURITY_SELINUX_AVC_STATS
+#define avc_cache_stats_incr(field) 				\
+do {								\
+	per_cpu(avc_cache_stats, get_cpu()).field++;		\
+	put_cpu();						\
+} while (0)
+#else
+#define avc_cache_stats_incr(field)	do {} while (0)
+#endif
 
 struct avc_entry {
 	u32			ssid;
 	u32			tsid;
 	u16			tclass;
 	struct av_decision	avd;
-	int			used;	/* used recently */
+	atomic_t		used;	/* used recently */
 };
 
 struct avc_node {
 	struct avc_entry	ae;
-	struct avc_node		*next;
+	struct list_head	list;
+	struct rcu_head         rhead;
 };
 
 struct avc_cache {
-	struct avc_node	*slots[AVC_CACHE_SLOTS];
-	u32		lru_hint;	/* LRU hint for reclaim scan */
-	u32		active_nodes;
-	u32		latest_notif;	/* latest revocation notification */
+	struct list_head	slots[AVC_CACHE_SLOTS];
+	spinlock_t		slots_lock[AVC_CACHE_SLOTS]; /* lock for writes */
+	atomic_t		lru_hint;	/* LRU hint for reclaim scan */
+	atomic_t		active_nodes;
+	u32			latest_notif;	/* latest revocation notification */
 };
 
 struct avc_callback_node {
@@ -70,35 +118,22 @@
 	struct avc_callback_node *next;
 };
 
-static spinlock_t avc_lock = SPIN_LOCK_UNLOCKED;
-static struct avc_node *avc_node_freelist;
+/* Exported via selinufs */
+unsigned int avc_cache_threshold = AVC_DEF_CACHE_THRESHOLD;
+
+#ifdef CONFIG_SECURITY_SELINUX_AVC_STATS
+DEFINE_PER_CPU(struct avc_cache_stats, avc_cache_stats) = { 0 };
+#endif
+
 static struct avc_cache avc_cache;
-static unsigned avc_cache_stats[AVC_NSTATS];
 static struct avc_callback_node *avc_callbacks;
+static kmem_cache_t *avc_node_cachep;
 
 static inline int avc_hash(u32 ssid, u32 tsid, u16 tclass)
 {
 	return (ssid ^ (tsid<<2) ^ (tclass<<4)) & (AVC_CACHE_SLOTS - 1);
 }
 
-#ifdef AVC_CACHE_STATS
-static inline void avc_cache_stats_incr(int type)
-{
-	avc_cache_stats[type]++;
-}
-
-static inline void avc_cache_stats_add(int type, unsigned val)
-{
-	avc_cache_stats[type] += val;
-}
-#else
-static inline void avc_cache_stats_incr(int type)
-{ }
-
-static inline void avc_cache_stats_add(int type, unsigned val)
-{ }
-#endif
-
 /**
  * avc_dump_av - Display an access vector in human-readable form.
  * @tclass: target security class
@@ -106,7 +141,7 @@
  */
 void avc_dump_av(struct audit_buffer *ab, u16 tclass, u32 av)
 {
-	char **common_pts = NULL;
+	const char **common_pts = NULL;
 	u32 common_base = 0;
 	int i, i2, perm;
 
@@ -127,8 +162,10 @@
 	i = 0;
 	perm = 1;
 	while (perm < common_base) {
-		if (perm & av)
+		if (perm & av) {
 			audit_log_format(ab, " %s", common_pts[i]);
+			av &= ~perm;
+		}
 		i++;
 		perm <<= 1;
 	}
@@ -140,14 +177,19 @@
 				    (av_perm_to_string[i2].value == perm))
 					break;
 			}
-			if (i2 < ARRAY_SIZE(av_perm_to_string))
+			if (i2 < ARRAY_SIZE(av_perm_to_string)) {
 				audit_log_format(ab, " %s",
 						 av_perm_to_string[i2].name);
+				av &= ~perm;
+			}
 		}
 		i++;
 		perm <<= 1;
 	}
 
+	if (av)
+		audit_log_format(ab, " 0x%x", av);
+
 	audit_log_format(ab, " }");
 }
 
@@ -188,155 +230,161 @@
  */
 void __init avc_init(void)
 {
-	struct avc_node	*new;
 	int i;
 
-	for (i = 0; i < AVC_CACHE_MAXNODES; i++) {
-		new = kmalloc(sizeof(*new), GFP_ATOMIC);
-		if (!new) {
-			printk(KERN_WARNING "avc:  only able to allocate "
-			       "%d entries\n", i);
-			break;
-		}
-		memset(new, 0, sizeof(*new));
-		new->next = avc_node_freelist;
-		avc_node_freelist = new;
+	for (i = 0; i < AVC_CACHE_SLOTS; i++) {
+		INIT_LIST_HEAD(&avc_cache.slots[i]);
+		spin_lock_init(&avc_cache.slots_lock[i]);
 	}
+	atomic_set(&avc_cache.active_nodes, 0);
+	atomic_set(&avc_cache.lru_hint, 0);
+
+	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");
 }
 
-#if 0
-static void avc_hash_eval(char *tag)
+int avc_get_hash_stats(char *page)
 {
 	int i, chain_len, max_chain_len, slots_used;
 	struct avc_node *node;
-	unsigned long flags;
 
-	spin_lock_irqsave(&avc_lock,flags);
+	rcu_read_lock();
 
 	slots_used = 0;
 	max_chain_len = 0;
 	for (i = 0; i < AVC_CACHE_SLOTS; i++) {
-		node = avc_cache.slots[i];
-		if (node) {
+		if (!list_empty(&avc_cache.slots[i])) {
 			slots_used++;
 			chain_len = 0;
-			while (node) {
+			list_for_each_entry_rcu(node, &avc_cache.slots[i], list)
 				chain_len++;
-				node = node->next;
-			}
 			if (chain_len > max_chain_len)
 				max_chain_len = chain_len;
 		}
 	}
 
-	spin_unlock_irqrestore(&avc_lock,flags);
+	rcu_read_unlock();
 
-	printk(KERN_INFO "\n");
-	printk(KERN_INFO "%s avc:  %d entries and %d/%d buckets used, longest "
-	       "chain length %d\n", tag, avc_cache.active_nodes, slots_used,
-	       AVC_CACHE_SLOTS, max_chain_len);
+	return scnprintf(page, PAGE_SIZE, "entries: %d\nbuckets used: %d/%d\n"
+			 "longest chain: %d\n",
+			 atomic_read(&avc_cache.active_nodes),
+			 slots_used, AVC_CACHE_SLOTS, max_chain_len);
 }
-#else
-static inline void avc_hash_eval(char *tag)
-{ }
-#endif
 
-static inline struct avc_node *avc_reclaim_node(void)
+static void avc_node_free(struct rcu_head *rhead)
 {
-	struct avc_node *prev, *cur;
-	int hvalue, try;
+	struct avc_node *node = container_of(rhead, struct avc_node, rhead);
+	kmem_cache_free(avc_node_cachep, node);
+	avc_cache_stats_incr(frees);
+}
 
-	hvalue = avc_cache.lru_hint;
-	for (try = 0; try < 2; try++) {
-		do {
-			prev = NULL;
-			cur = avc_cache.slots[hvalue];
-			while (cur) {
-				if (!cur->ae.used)
-					goto found;
+static void avc_node_delete(struct avc_node *node)
+{
+	list_del_rcu(&node->list);
+	call_rcu(&node->rhead, avc_node_free);
+	atomic_dec(&avc_cache.active_nodes);
+}
 
-				cur->ae.used = 0;
+static void avc_node_kill(struct avc_node *node)
+{
+	kmem_cache_free(avc_node_cachep, node);
+	avc_cache_stats_incr(frees);
+	atomic_dec(&avc_cache.active_nodes);
+}
 
-				prev = cur;
-				cur = cur->next;
-			}
-			hvalue = (hvalue + 1) & (AVC_CACHE_SLOTS - 1);
-		} while (hvalue != avc_cache.lru_hint);
-	}
+static void avc_node_replace(struct avc_node *new, struct avc_node *old)
+{
+	list_replace_rcu(&old->list, &new->list);
+	call_rcu(&old->rhead, avc_node_free);
+	atomic_dec(&avc_cache.active_nodes);
+}
 
-	panic("avc_reclaim_node");
+static inline int avc_reclaim_node(void)
+{
+	struct avc_node *node;
+	int hvalue, try, ecx;
+	unsigned long flags;
 
-found:
-	avc_cache.lru_hint = hvalue;
+	for (try = 0, ecx = 0; try < AVC_CACHE_SLOTS; try++ ) {
+		hvalue = atomic_inc_return(&avc_cache.lru_hint) & (AVC_CACHE_SLOTS - 1);
 
-	if (prev == NULL)
-		avc_cache.slots[hvalue] = cur->next;
-	else
-		prev->next = cur->next;
+		if (!spin_trylock_irqsave(&avc_cache.slots_lock[hvalue], flags))
+			continue;
 
-	return cur;
+		list_for_each_entry(node, &avc_cache.slots[hvalue], list) {
+			if (atomic_dec_and_test(&node->ae.used)) {
+				/* Recently Unused */
+				avc_node_delete(node);
+				avc_cache_stats_incr(reclaims);
+				ecx++;
+				if (ecx >= AVC_CACHE_RECLAIM) {
+					spin_unlock_irqrestore(&avc_cache.slots_lock[hvalue], flags);
+					goto out;
+				}
+			}
+		}
+		spin_unlock_irqrestore(&avc_cache.slots_lock[hvalue], flags);
+	}
+out:
+	return ecx;
 }
 
-static inline struct avc_node *avc_claim_node(u32 ssid,
-                                              u32 tsid, u16 tclass)
+static struct avc_node *avc_alloc_node(void)
 {
-	struct avc_node *new;
-	int hvalue;
+	struct avc_node *node;
 
-	hvalue = avc_hash(ssid, tsid, tclass);
-	if (avc_node_freelist) {
-		new = avc_node_freelist;
-		avc_node_freelist = avc_node_freelist->next;
-		avc_cache.active_nodes++;
-	} else {
-		new = avc_reclaim_node();
-		if (!new)
-			goto out;
-	}
+	node = kmem_cache_alloc(avc_node_cachep, SLAB_ATOMIC);
+	if (!node)
+		goto out;
+
+	memset(node, 0, sizeof(*node));
+	INIT_RCU_HEAD(&node->rhead);
+	INIT_LIST_HEAD(&node->list);
+	atomic_set(&node->ae.used, 1);
+	avc_cache_stats_incr(allocations);
 
-	new->ae.used = 1;
-	new->ae.ssid = ssid;
-	new->ae.tsid = tsid;
-	new->ae.tclass = tclass;
-	new->next = avc_cache.slots[hvalue];
-	avc_cache.slots[hvalue] = new;
+	if (atomic_inc_return(&avc_cache.active_nodes) > avc_cache_threshold)
+		avc_reclaim_node();
 
 out:
-	return new;
+	return node;
 }
 
-static inline struct avc_node *avc_search_node(u32 ssid, u32 tsid,
-                                               u16 tclass, int *probes)
+static void avc_node_populate(struct avc_node *node, u32 ssid, u32 tsid, u16 tclass, struct avc_entry *ae)
 {
-	struct avc_node *cur;
+	node->ae.ssid = ssid;
+	node->ae.tsid = tsid;
+	node->ae.tclass = tclass;
+	memcpy(&node->ae.avd, &ae->avd, sizeof(node->ae.avd));
+}
+
+static inline struct avc_node *avc_search_node(u32 ssid, u32 tsid, u16 tclass)
+{
+	struct avc_node *node, *ret = NULL;
 	int hvalue;
-	int tprobes = 1;
 
 	hvalue = avc_hash(ssid, tsid, tclass);
-	cur = avc_cache.slots[hvalue];
-	while (cur != NULL &&
-	       (ssid != cur->ae.ssid ||
-		tclass != cur->ae.tclass ||
-		tsid != cur->ae.tsid)) {
-		tprobes++;
-		cur = cur->next;
+	list_for_each_entry_rcu(node, &avc_cache.slots[hvalue], list) {
+		if (ssid == node->ae.ssid &&
+		    tclass == node->ae.tclass &&
+		    tsid == node->ae.tsid) {
+			ret = node;
+			break;
+		}
 	}
 
-	if (cur == NULL) {
+	if (ret == NULL) {
 		/* cache miss */
 		goto out;
 	}
 
 	/* cache hit */
-	if (probes)
-		*probes = tprobes;
-
-	cur->ae.used = 1;
-
+	if (atomic_read(&ret->ae.used) != 1)
+		atomic_set(&ret->ae.used, 1);
 out:
-	return cur;
+	return ret;
 }
 
 /**
@@ -345,36 +393,52 @@
  * @tsid: target security identifier
  * @tclass: target security class
  * @requested: requested permissions, interpreted based on @tclass
- * @aeref:  AVC entry reference
  *
  * Look up an AVC entry that is valid for the
  * @requested permissions between the SID pair
  * (@ssid, @tsid), interpreting the permissions
  * based on @tclass.  If a valid AVC entry exists,
- * then this function updates @aeref to refer to the
- * entry and returns %0. Otherwise, this function
- * returns -%ENOENT.
+ * then this function return the avc_node.
+ * Otherwise, this function returns NULL.
  */
-int avc_lookup(u32 ssid, u32 tsid, u16 tclass,
-               u32 requested, struct avc_entry_ref *aeref)
+static struct avc_node *avc_lookup(u32 ssid, u32 tsid, u16 tclass, u32 requested)
 {
 	struct avc_node *node;
-	int probes, rc = 0;
 
-	avc_cache_stats_incr(AVC_CAV_LOOKUPS);
-	node = avc_search_node(ssid, tsid, tclass,&probes);
+	avc_cache_stats_incr(lookups);
+	node = avc_search_node(ssid, tsid, tclass);
 
 	if (node && ((node->ae.avd.decided & requested) == requested)) {
-		avc_cache_stats_incr(AVC_CAV_HITS);
-		avc_cache_stats_add(AVC_CAV_PROBES,probes);
-		aeref->ae = &node->ae;
+		avc_cache_stats_incr(hits);
 		goto out;
 	}
 
-	avc_cache_stats_incr(AVC_CAV_MISSES);
-	rc = -ENOENT;
+	node = NULL;
+	avc_cache_stats_incr(misses);
 out:
-	return rc;
+	return node;
+}
+
+static int avc_latest_notif_update(int seqno, int is_insert)
+{
+	int ret = 0;
+	static DEFINE_SPINLOCK(notif_lock);
+	unsigned long flag;
+
+	spin_lock_irqsave(&notif_lock, flag);
+	if (is_insert) {
+		if (seqno < avc_cache.latest_notif) {
+			printk(KERN_WARNING "avc:  seqno %d < latest_notif %d\n",
+			       seqno, avc_cache.latest_notif);
+			ret = -EAGAIN;
+		}
+	} else {
+		if (seqno > avc_cache.latest_notif)
+			avc_cache.latest_notif = seqno;
+	}
+	spin_unlock_irqrestore(&notif_lock, flag);
+
+	return ret;
 }
 
 /**
@@ -383,7 +447,6 @@
  * @tsid: target security identifier
  * @tclass: target security class
  * @ae: AVC entry
- * @aeref:  AVC entry reference
  *
  * Insert an AVC entry for the SID pair
  * (@ssid, @tsid) and class @tclass.
@@ -392,37 +455,38 @@
  * response to a security_compute_av() call.  If the
  * sequence number @ae->avd.seqno is not less than the latest
  * revocation notification, then the function copies
- * the access vectors into a cache entry, updates
- * @aeref to refer to the entry, and returns %0.
- * Otherwise, this function returns -%EAGAIN.
+ * the access vectors into a cache entry, returns
+ * avc_node inserted. Otherwise, this function returns NULL.
  */
-int avc_insert(u32 ssid, u32 tsid, u16 tclass,
-               struct avc_entry *ae, struct avc_entry_ref *aeref)
+static struct avc_node *avc_insert(u32 ssid, u32 tsid, u16 tclass, struct avc_entry *ae)
 {
-	struct avc_node *node;
-	int rc = 0;
+	struct avc_node *pos, *node = NULL;
+	int hvalue;
+	unsigned long flag;
 
-	if (ae->avd.seqno < avc_cache.latest_notif) {
-		printk(KERN_WARNING "avc:  seqno %d < latest_notif %d\n",
-		       ae->avd.seqno, avc_cache.latest_notif);
-		rc = -EAGAIN;
+	if (avc_latest_notif_update(ae->avd.seqno, 1))
 		goto out;
-	}
 
-	node = avc_claim_node(ssid, tsid, tclass);
-	if (!node) {
-		rc = -ENOMEM;
-		goto out;
+	node = avc_alloc_node();
+	if (node) {
+		hvalue = avc_hash(ssid, tsid, tclass);
+		avc_node_populate(node, ssid, tsid, tclass, ae);
+
+		spin_lock_irqsave(&avc_cache.slots_lock[hvalue], flag);
+		list_for_each_entry(pos, &avc_cache.slots[hvalue], list) {
+			if (pos->ae.ssid == ssid &&
+			    pos->ae.tsid == tsid &&
+			    pos->ae.tclass == tclass) {
+			    	avc_node_replace(node, pos);
+				goto found;
+			}
+		}
+		list_add_rcu(&node->list, &avc_cache.slots[hvalue]);
+found:
+		spin_unlock_irqrestore(&avc_cache.slots_lock[hvalue], flag);
 	}
-
-	node->ae.avd.allowed = ae->avd.allowed;
-	node->ae.avd.decided = ae->avd.decided;
-	node->ae.avd.auditallow = ae->avd.auditallow;
-	node->ae.avd.auditdeny = ae->avd.auditdeny;
-	node->ae.avd.seqno = ae->avd.seqno;
-	aeref->ae = &node->ae;
 out:
-	return rc;
+	return node;
 }
 
 static inline void avc_print_ipv6_addr(struct audit_buffer *ab,
@@ -516,6 +580,8 @@
 					vma = vma->vm_next;
 				}
 				up_read(&mm->mmap_sem);
+			} else {
+				audit_log_format(ab, " comm=%s", tsk->comm);
 			}
 			if (tsk != current)
 				mmput(mm);
@@ -566,7 +632,7 @@
 
 				switch (sk->sk_family) {
 				case AF_INET: {
-					struct inet_opt *inet = inet_sk(sk);
+					struct inet_sock *inet = inet_sk(sk);
 
 					avc_print_ipv4_addr(ab, inet->rcv_saddr,
 							    inet->sport,
@@ -577,7 +643,7 @@
 					break;
 				}
 				case AF_INET6: {
-					struct inet_opt *inet = inet_sk(sk);
+					struct inet_sock *inet = inet_sk(sk);
 					struct ipv6_pinfo *inet6 = inet6_sk(sk);
 
 					avc_print_ipv6_addr(ab, &inet6->rcv_saddr,
@@ -686,8 +752,54 @@
 	return (x == y || x == SECSID_WILD || y == SECSID_WILD);
 }
 
-static inline void avc_update_node(u32 event, struct avc_node *node, u32 perms)
+/**
+ * avc_update_node Update an AVC entry
+ * @event : Updating event
+ * @perms : Permission mask bits
+ * @ssid,@tsid,@tclass : identifier of an AVC entry
+ *
+ * if a valid AVC entry doesn't exist,this function returns -ENOENT.
+ * if kmalloc() called internal returns NULL, this function returns -ENOMEM.
+ * otherwise, this function update the AVC entry. The original AVC-entry object
+ * will release later by RCU.
+ */
+static int avc_update_node(u32 event, u32 perms, u32 ssid, u32 tsid, u16 tclass)
 {
+	int hvalue, rc = 0;
+	unsigned long flag;
+	struct avc_node *pos, *node, *orig = NULL;
+
+	node = avc_alloc_node();
+	if (!node) {
+		rc = -ENOMEM;
+		goto out;
+	}
+
+	/* Lock the target slot */
+	hvalue = avc_hash(ssid, tsid, tclass);
+	spin_lock_irqsave(&avc_cache.slots_lock[hvalue], flag);
+
+	list_for_each_entry(pos, &avc_cache.slots[hvalue], list){
+		if ( ssid==pos->ae.ssid &&
+		     tsid==pos->ae.tsid &&
+		     tclass==pos->ae.tclass ){
+			orig = pos;
+			break;
+		}
+	}
+
+	if (!orig) {
+		rc = -ENOENT;
+		avc_node_kill(node);
+		goto out_unlock;
+	}
+
+	/*
+	 * Copy and replace original node.
+	 */
+
+	avc_node_populate(node, ssid, tsid, tclass, &orig->ae);
+
 	switch (event) {
 	case AVC_CALLBACK_GRANT:
 		node->ae.avd.allowed |= perms;
@@ -709,6 +821,11 @@
 		node->ae.avd.auditdeny &= ~perms;
 		break;
 	}
+	avc_node_replace(node, orig);
+out_unlock:
+	spin_unlock_irqrestore(&avc_cache.slots_lock[hvalue], flag);
+out:
+	return rc;
 }
 
 static int avc_update_cache(u32 event, u32 ssid, u32 tsid,
@@ -716,31 +833,27 @@
 {
 	struct avc_node *node;
 	int i;
-	unsigned long flags;
 
-	spin_lock_irqsave(&avc_lock,flags);
+	rcu_read_lock();
 
 	if (ssid == SECSID_WILD || tsid == SECSID_WILD) {
 		/* apply to all matching nodes */
 		for (i = 0; i < AVC_CACHE_SLOTS; i++) {
-			for (node = avc_cache.slots[i]; node;
-			     node = node->next) {
+			list_for_each_entry_rcu(node, &avc_cache.slots[i], list) {
 				if (avc_sidcmp(ssid, node->ae.ssid) &&
 				    avc_sidcmp(tsid, node->ae.tsid) &&
-				    tclass == node->ae.tclass) {
-					avc_update_node(event,node,perms);
+				    tclass == node->ae.tclass ) {
+					avc_update_node(event, perms, node->ae.ssid,
+							node->ae.tsid, node->ae.tclass);
 				}
 			}
 		}
 	} else {
 		/* apply to one node */
-		node = avc_search_node(ssid, tsid, tclass, NULL);
-		if (node) {
-			avc_update_node(event,node,perms);
-		}
+		avc_update_node(event, perms, ssid, tsid, tclass);
 	}
 
-	spin_unlock_irqrestore(&avc_lock,flags);
+	rcu_read_unlock();
 
 	return 0;
 }
@@ -752,7 +865,6 @@
 	struct avc_callback_node *c;
 	u32 tretained = 0, cretained = 0;
 	int rc = 0;
-	unsigned long flags;
 
 	/*
 	 * try_revoke only removes permissions from the cache
@@ -787,10 +899,7 @@
 		*out_retained = tretained;
 	}
 
-	spin_lock_irqsave(&avc_lock,flags);
-	if (seqno > avc_cache.latest_notif)
-		avc_cache.latest_notif = seqno;
-	spin_unlock_irqrestore(&avc_lock,flags);
+	avc_latest_notif_update(seqno, 0);
 
 out:
 	return rc;
@@ -857,35 +966,15 @@
 {
 	struct avc_callback_node *c;
 	int i, rc = 0;
-	struct avc_node *node, *tmp;
-	unsigned long flags;
-
-	avc_hash_eval("reset");
-
-	spin_lock_irqsave(&avc_lock,flags);
+	unsigned long flag;
+	struct avc_node *node;
 
 	for (i = 0; i < AVC_CACHE_SLOTS; i++) {
-		node = avc_cache.slots[i];
-		while (node) {
-			tmp = node;
-			node = node->next;
-			tmp->ae.ssid = tmp->ae.tsid = SECSID_NULL;
-			tmp->ae.tclass = SECCLASS_NULL;
-			tmp->ae.avd.allowed = tmp->ae.avd.decided = 0;
-			tmp->ae.avd.auditallow = tmp->ae.avd.auditdeny = 0;
-			tmp->ae.used = 0;
-			tmp->next = avc_node_freelist;
-			avc_node_freelist = tmp;
-			avc_cache.active_nodes--;
-		}
-		avc_cache.slots[i] = NULL;
+		spin_lock_irqsave(&avc_cache.slots_lock[i], flag);
+		list_for_each_entry(node, &avc_cache.slots[i], list)
+			avc_node_delete(node);
+		spin_unlock_irqrestore(&avc_cache.slots_lock[i], flag);
 	}
-	avc_cache.lru_hint = 0;
-
-	spin_unlock_irqrestore(&avc_lock,flags);
-
-	for (i = 0; i < AVC_NSTATS; i++)
-		avc_cache_stats[i] = 0;
 
 	for (c = avc_callbacks; c; c = c->next) {
 		if (c->events & AVC_CALLBACK_RESET) {
@@ -896,10 +985,7 @@
 		}
 	}
 
-	spin_lock_irqsave(&avc_lock,flags);
-	if (seqno > avc_cache.latest_notif)
-		avc_cache.latest_notif = seqno;
-	spin_unlock_irqrestore(&avc_lock,flags);
+	avc_latest_notif_update(seqno, 0);
 out:
 	return rc;
 }
@@ -950,14 +1036,12 @@
  * @tsid: target security identifier
  * @tclass: target security class
  * @requested: requested permissions, interpreted based on @tclass
- * @aeref:  AVC entry reference
  * @avd: access vector decisions
  *
  * Check the AVC to determine whether the @requested permissions are granted
  * for the SID pair (@ssid, @tsid), interpreting the permissions
  * based on @tclass, and call the security server on a cache miss to obtain
- * a new decision and add it to the cache.  Update @aeref to refer to an AVC
- * entry with the resulting decisions, and return a copy of the decisions
+ * a new decision and add it to the cache.  Return a copy of the decisions
  * in @avd.  Return %0 if all @requested permissions are granted,
  * -%EACCES if any permissions are denied, or another -errno upon
  * other errors.  This function is typically called by avc_has_perm(),
@@ -967,72 +1051,42 @@
  */
 int avc_has_perm_noaudit(u32 ssid, u32 tsid,
                          u16 tclass, u32 requested,
-                         struct avc_entry_ref *aeref, struct av_decision *avd)
+                         struct av_decision *avd)
 {
-	struct avc_entry *ae;
+	struct avc_node *node;
+	struct avc_entry entry, *p_ae;
 	int rc = 0;
-	unsigned long flags;
-	struct avc_entry entry;
 	u32 denied;
-	struct avc_entry_ref ref;
 
-	if (!aeref) {
-		avc_entry_ref_init(&ref);
-		aeref = &ref;
-	}
-
-	spin_lock_irqsave(&avc_lock, flags);
-	avc_cache_stats_incr(AVC_ENTRY_LOOKUPS);
-	ae = aeref->ae;
-	if (ae) {
-		if (ae->ssid == ssid &&
-		    ae->tsid == tsid &&
-		    ae->tclass == tclass &&
-		    ((ae->avd.decided & requested) == requested)) {
-			avc_cache_stats_incr(AVC_ENTRY_HITS);
-			ae->used = 1;
-		} else {
-			avc_cache_stats_incr(AVC_ENTRY_DISCARDS);
-			ae = NULL;
-		}
-	}
+	rcu_read_lock();
 
-	if (!ae) {
-		avc_cache_stats_incr(AVC_ENTRY_MISSES);
-		rc = avc_lookup(ssid, tsid, tclass, requested, aeref);
-		if (rc) {
-			spin_unlock_irqrestore(&avc_lock,flags);
-			rc = security_compute_av(ssid,tsid,tclass,requested,&entry.avd);
-			if (rc)
-				goto out;
-			spin_lock_irqsave(&avc_lock, flags);
-			rc = avc_insert(ssid,tsid,tclass,&entry,aeref);
-			if (rc) {
-				spin_unlock_irqrestore(&avc_lock,flags);
-				goto out;
-			}
-		}
-		ae = aeref->ae;
+	node = avc_lookup(ssid, tsid, tclass, requested);
+	if (!node) {
+		rcu_read_unlock();
+		rc = security_compute_av(ssid,tsid,tclass,requested,&entry.avd);
+		if (rc)
+			goto out;
+		rcu_read_lock();
+		node = avc_insert(ssid,tsid,tclass,&entry);
 	}
 
+	p_ae = node ? &node->ae : &entry;
+
 	if (avd)
-		memcpy(avd, &ae->avd, sizeof(*avd));
+		memcpy(avd, &p_ae->avd, sizeof(*avd));
 
-	denied = requested & ~(ae->avd.allowed);
+	denied = requested & ~(p_ae->avd.allowed);
 
 	if (!requested || denied) {
-		if (selinux_enforcing) {
-			spin_unlock_irqrestore(&avc_lock,flags);
+		if (selinux_enforcing)
 			rc = -EACCES;
-			goto out;
-		} else {
-			ae->avd.allowed |= requested;
-			spin_unlock_irqrestore(&avc_lock,flags);
-			goto out;
-		}
+		else
+			if (node)
+				avc_update_node(AVC_CALLBACK_GRANT,requested,
+						ssid,tsid,tclass);
 	}
 
-	spin_unlock_irqrestore(&avc_lock,flags);
+	rcu_read_unlock();
 out:
 	return rc;
 }
@@ -1043,26 +1097,23 @@
  * @tsid: target security identifier
  * @tclass: target security class
  * @requested: requested permissions, interpreted based on @tclass
- * @aeref:  AVC entry reference
  * @auditdata: auxiliary audit data
  *
  * Check the AVC to determine whether the @requested permissions are granted
  * for the SID pair (@ssid, @tsid), interpreting the permissions
  * based on @tclass, and call the security server on a cache miss to obtain
- * a new decision and add it to the cache.  Update @aeref to refer to an AVC
- * entry with the resulting decisions.  Audit the granting or denial of
+ * a new decision and add it to the cache.  Audit the granting or denial of
  * permissions in accordance with the policy.  Return %0 if all @requested
  * permissions are granted, -%EACCES if any permissions are denied, or
  * another -errno upon other errors.
  */
 int avc_has_perm(u32 ssid, u32 tsid, u16 tclass,
-                 u32 requested, struct avc_entry_ref *aeref,
-                 struct avc_audit_data *auditdata)
+                 u32 requested, struct avc_audit_data *auditdata)
 {
 	struct av_decision avd;
 	int rc;
 
-	rc = avc_has_perm_noaudit(ssid, tsid, tclass, requested, aeref, &avd);
+	rc = avc_has_perm_noaudit(ssid, tsid, tclass, requested, &avd);
 	avc_audit(ssid, tsid, tclass, requested, &avd, rc, auditdata);
 	return rc;
 }
diff -Nru a/security/selinux/hooks.c b/security/selinux/hooks.c
--- a/security/selinux/hooks.c	2005-03-01 23:39:16 -08:00
+++ b/security/selinux/hooks.c	2005-03-01 23:39:16 -08:00
@@ -73,7 +73,7 @@
 #define XATTR_SELINUX_SUFFIX "selinux"
 #define XATTR_NAME_SELINUX XATTR_SECURITY_PREFIX XATTR_SELINUX_SUFFIX
 
-extern int policydb_loaded_version;
+extern unsigned int policydb_loaded_version;
 extern int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm);
 
 #ifdef CONFIG_SECURITY_SELINUX_DEVELOP
@@ -110,7 +110,7 @@
 /* Lists of inode and superblock security structures initialized
    before the policy was loaded. */
 static LIST_HEAD(superblock_security_head);
-static spinlock_t sb_security_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(sb_security_lock);
 
 /* Allocate and free functions for each kind of security blob. */
 
@@ -448,12 +448,12 @@
 		}
 
 		rc = avc_has_perm(tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM,
-		                  FILESYSTEM__RELABELFROM, NULL, NULL);
+		                  FILESYSTEM__RELABELFROM, NULL);
 		if (rc)
 			goto out_free;
 
 		rc = avc_has_perm(tsec->sid, sid, SECCLASS_FILESYSTEM,
-		                  FILESYSTEM__RELABELTO, NULL, NULL);
+		                  FILESYSTEM__RELABELTO, NULL);
 		if (rc)
 			goto out_free;
 
@@ -476,12 +476,12 @@
 			goto out_free;
 
 		rc = avc_has_perm(tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM,
-				  FILESYSTEM__RELABELFROM, NULL, NULL);
+				  FILESYSTEM__RELABELFROM, NULL);
 		if (rc)
 			goto out_free;
 
 		rc = avc_has_perm(sid, sbsec->sid, SECCLASS_FILESYSTEM,
-				  FILESYSTEM__ASSOCIATE, NULL, NULL);
+				  FILESYSTEM__ASSOCIATE, NULL);
 		if (rc)
 			goto out_free;
 
@@ -927,7 +927,7 @@
 	tsec1 = tsk1->security;
 	tsec2 = tsk2->security;
 	return avc_has_perm(tsec1->sid, tsec2->sid,
-			    SECCLASS_PROCESS, perms, &tsec2->avcr, NULL);
+			    SECCLASS_PROCESS, perms, NULL);
 }
 
 /* Check whether a task is allowed to use a capability. */
@@ -944,7 +944,7 @@
 	ad.u.cap = cap;
 
 	return avc_has_perm(tsec->sid, tsec->sid,
-			    SECCLASS_CAPABILITY, CAP_TO_MASK(cap), NULL, &ad);
+			    SECCLASS_CAPABILITY, CAP_TO_MASK(cap), &ad);
 }
 
 /* Check whether a task is allowed to use a system operation. */
@@ -956,18 +956,15 @@
 	tsec = tsk->security;
 
 	return avc_has_perm(tsec->sid, SECINITSID_KERNEL,
-			    SECCLASS_SYSTEM, perms, NULL, NULL);
+			    SECCLASS_SYSTEM, perms, NULL);
 }
 
 /* Check whether a task has a particular permission to an inode.
-   The 'aeref' parameter is optional and allows other AVC
-   entry references to be passed (e.g. the one in the struct file).
    The 'adp' parameter is optional and allows other audit
    data to be passed (e.g. the dentry). */
 int inode_has_perm(struct task_struct *tsk,
 		   struct inode *inode,
 		   u32 perms,
-		   struct avc_entry_ref *aeref,
 		   struct avc_audit_data *adp)
 {
 	struct task_security_struct *tsec;
@@ -983,8 +980,7 @@
 		ad.u.fs.inode = inode;
 	}
 
-	return avc_has_perm(tsec->sid, isec->sid, isec->sclass,
-			    perms, aeref ? aeref : &isec->avcr, adp);
+	return avc_has_perm(tsec->sid, isec->sid, isec->sclass, perms, adp);
 }
 
 /* Same as inode_has_perm, but pass explicit audit data containing
@@ -1000,7 +996,7 @@
 	AVC_AUDIT_DATA_INIT(&ad,FS);
 	ad.u.fs.mnt = mnt;
 	ad.u.fs.dentry = dentry;
-	return inode_has_perm(tsk, inode, av, NULL, &ad);
+	return inode_has_perm(tsk, inode, av, &ad);
 }
 
 /* Check whether a task can use an open file descriptor to
@@ -1031,14 +1027,14 @@
 		rc = avc_has_perm(tsec->sid, fsec->sid,
 				  SECCLASS_FD,
 				  FD__USE,
-				  &fsec->avcr, &ad);
+				  &ad);
 		if (rc)
 			return rc;
 	}
 
 	/* av is zero if only checking access to the descriptor. */
 	if (av)
-		return inode_has_perm(tsk, inode, av, &fsec->inode_avcr, &ad);
+		return inode_has_perm(tsk, inode, av, &ad);
 
 	return 0;
 }
@@ -1064,7 +1060,7 @@
 
 	rc = avc_has_perm(tsec->sid, dsec->sid, SECCLASS_DIR,
 			  DIR__ADD_NAME | DIR__SEARCH,
-			  &dsec->avcr, &ad);
+			  &ad);
 	if (rc)
 		return rc;
 
@@ -1077,13 +1073,13 @@
 			return rc;
 	}
 
-	rc = avc_has_perm(tsec->sid, newsid, tclass, FILE__CREATE, NULL, &ad);
+	rc = avc_has_perm(tsec->sid, newsid, tclass, FILE__CREATE, &ad);
 	if (rc)
 		return rc;
 
 	return avc_has_perm(newsid, sbsec->sid,
 			    SECCLASS_FILESYSTEM,
-			    FILESYSTEM__ASSOCIATE, NULL, &ad);
+			    FILESYSTEM__ASSOCIATE, &ad);
 }
 
 #define MAY_LINK   0
@@ -1111,8 +1107,7 @@
 
 	av = DIR__SEARCH;
 	av |= (kind ? DIR__REMOVE_NAME : DIR__ADD_NAME);
-	rc = avc_has_perm(tsec->sid, dsec->sid, SECCLASS_DIR,
-			  av, &dsec->avcr, &ad);
+	rc = avc_has_perm(tsec->sid, dsec->sid, SECCLASS_DIR, av, &ad);
 	if (rc)
 		return rc;
 
@@ -1131,8 +1126,7 @@
 		return 0;
 	}
 
-	rc = avc_has_perm(tsec->sid, isec->sid, isec->sclass,
-			  av, &isec->avcr, &ad);
+	rc = avc_has_perm(tsec->sid, isec->sid, isec->sclass, av, &ad);
 	return rc;
 }
 
@@ -1158,21 +1152,16 @@
 
 	ad.u.fs.dentry = old_dentry;
 	rc = avc_has_perm(tsec->sid, old_dsec->sid, SECCLASS_DIR,
-			  DIR__REMOVE_NAME | DIR__SEARCH,
-			  &old_dsec->avcr, &ad);
+			  DIR__REMOVE_NAME | DIR__SEARCH, &ad);
 	if (rc)
 		return rc;
 	rc = avc_has_perm(tsec->sid, old_isec->sid,
-			  old_isec->sclass,
-			  FILE__RENAME,
-			  &old_isec->avcr, &ad);
+			  old_isec->sclass, FILE__RENAME, &ad);
 	if (rc)
 		return rc;
 	if (old_is_dir && new_dir != old_dir) {
 		rc = avc_has_perm(tsec->sid, old_isec->sid,
-				  old_isec->sclass,
-				  DIR__REPARENT,
-				  &old_isec->avcr, &ad);
+				  old_isec->sclass, DIR__REPARENT, &ad);
 		if (rc)
 			return rc;
 	}
@@ -1181,8 +1170,7 @@
 	av = DIR__ADD_NAME | DIR__SEARCH;
 	if (new_dentry->d_inode)
 		av |= DIR__REMOVE_NAME;
-	rc = avc_has_perm(tsec->sid, new_dsec->sid, SECCLASS_DIR,
-			  av,&new_dsec->avcr, &ad);
+	rc = avc_has_perm(tsec->sid, new_dsec->sid, SECCLASS_DIR, av, &ad);
 	if (rc)
 		return rc;
 	if (new_dentry->d_inode) {
@@ -1190,8 +1178,7 @@
 		new_is_dir = S_ISDIR(new_dentry->d_inode->i_mode);
 		rc = avc_has_perm(tsec->sid, new_isec->sid,
 				  new_isec->sclass,
-				  (new_is_dir ? DIR__RMDIR : FILE__UNLINK),
-				  &new_isec->avcr, &ad);
+				  (new_is_dir ? DIR__RMDIR : FILE__UNLINK), &ad);
 		if (rc)
 			return rc;
 	}
@@ -1211,7 +1198,7 @@
 	tsec = tsk->security;
 	sbsec = sb->s_security;
 	return avc_has_perm(tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM,
-			    perms, NULL, ad);
+			    perms, ad);
 }
 
 /* Convert a Linux mode and permission mask to an access vector. */
@@ -1403,12 +1390,6 @@
 static void selinux_capset_set(struct task_struct *target, kernel_cap_t *effective,
                                kernel_cap_t *inheritable, kernel_cap_t *permitted)
 {
-	int error;
-
-	error = task_has_perm(current, target, PROCESS__SETCAP);
-	if (error)
-		return;
-
 	secondary_ops->capset_set(target, effective, inheritable, permitted);
 }
 
@@ -1448,7 +1429,7 @@
 	 * a bad coupling between this module and sysctl.c */
 	if(op == 001) {
 		error = avc_has_perm(tsec->sid, tsid,
-				     SECCLASS_DIR, DIR__SEARCH, NULL, NULL);
+				     SECCLASS_DIR, DIR__SEARCH, NULL);
 	} else {
 		av = 0;
 		if (op & 004)
@@ -1457,7 +1438,7 @@
 			av |= FILE__WRITE;
 		if (av)
 			error = avc_has_perm(tsec->sid, tsid,
-					     SECCLASS_FILE, av, NULL, NULL);
+					     SECCLASS_FILE, av, NULL);
         }
 
 	return error;
@@ -1494,9 +1475,9 @@
 	return rc;
 }
 
-static int selinux_quota_on(struct file *f)
+static int selinux_quota_on(struct dentry *dentry)
 {
-	return file_has_perm(current, f, FILE__QUOTAON);
+	return dentry_has_perm(current, NULL, dentry, FILE__QUOTAON);
 }
 
 static int selinux_syslog(int type)
@@ -1534,70 +1515,29 @@
  * mapping. 0 means there is enough memory for the allocation to
  * succeed and -ENOMEM implies there is not.
  *
- * We currently support three overcommit policies, which are set via the
- * vm.overcommit_memory sysctl.  See Documentation/vm/overcommit-accounting
+ * Note that secondary_ops->capable and task_has_perm_noaudit return 0
+ * if the capability is granted, but __vm_enough_memory requires 1 if
+ * the capability is granted.
  *
- * Strict overcommit modes added 2002 Feb 26 by Alan Cox.
- * Additional code 2002 Jul 20 by Robert Love.
+ * Do not audit the selinux permission check, as this is applied to all
+ * processes that allocate mappings.
  */
 static int selinux_vm_enough_memory(long pages)
 {
-	unsigned long free, allowed;
-	int rc;
+	int rc, cap_sys_admin = 0;
 	struct task_security_struct *tsec = current->security;
 
-	vm_acct_memory(pages);
-
-        /*
-	 * Sometimes we want to use more memory than we have
-	 */
-	if (sysctl_overcommit_memory == OVERCOMMIT_ALWAYS)
-		return 0;
-
-	if (sysctl_overcommit_memory == OVERCOMMIT_GUESS) {
-		free = get_page_cache_size();
-		free += nr_free_pages();
-		free += nr_swap_pages;
-
-		/*
-		 * Any slabs which are created with the
-		 * SLAB_RECLAIM_ACCOUNT flag claim to have contents
-		 * which are reclaimable, under pressure.  The dentry
-		 * cache and most inode caches should fall into this
-		 */
-		free += atomic_read(&slab_reclaim_pages);
-
-		/*
-		 * Leave the last 3% for privileged processes.
-		 * Don't audit the check, as it is applied to all processes
-		 * that allocate mappings.
-		 */
-		rc = secondary_ops->capable(current, CAP_SYS_ADMIN);
-		if (!rc) {
-			rc = avc_has_perm_noaudit(tsec->sid, tsec->sid,
-						  SECCLASS_CAPABILITY,
-						  CAP_TO_MASK(CAP_SYS_ADMIN),
-						  NULL, NULL);
-		}
-		if (rc)
-			free -= free / 32;
-
-		if (free > pages)
-			return 0;
-		vm_unacct_memory(pages);
-		return -ENOMEM;
-	}
-
-	allowed = (totalram_pages - hugetlb_total_pages())
-		* sysctl_overcommit_ratio / 100;
-	allowed += total_swap_pages;
-
-	if (atomic_read(&vm_committed_space) < allowed)
-		return 0;
+	rc = secondary_ops->capable(current, CAP_SYS_ADMIN);
+	if (rc == 0)
+		rc = avc_has_perm_noaudit(tsec->sid, tsec->sid,
+					SECCLASS_CAPABILITY,
+					CAP_TO_MASK(CAP_SYS_ADMIN),
+					NULL);
 
-	vm_unacct_memory(pages);
+	if (rc == 0)
+		cap_sys_admin = 1;
 
-	return -ENOMEM;
+	return __vm_enough_memory(pages, cap_sys_admin);
 }
 
 /* binprm security operations */
@@ -1669,22 +1609,18 @@
 
         if (tsec->sid == newsid) {
 		rc = avc_has_perm(tsec->sid, isec->sid,
-				  SECCLASS_FILE, FILE__EXECUTE_NO_TRANS,
-				  &isec->avcr, &ad);
+				  SECCLASS_FILE, FILE__EXECUTE_NO_TRANS, &ad);
 		if (rc)
 			return rc;
 	} else {
 		/* Check permissions for the transition. */
 		rc = avc_has_perm(tsec->sid, newsid,
-				  SECCLASS_PROCESS, PROCESS__TRANSITION,
-				  NULL,
-				  &ad);
+				  SECCLASS_PROCESS, PROCESS__TRANSITION, &ad);
 		if (rc)
 			return rc;
 
 		rc = avc_has_perm(newsid, isec->sid,
-				  SECCLASS_FILE, FILE__ENTRYPOINT,
-				  &isec->avcr, &ad);
+				  SECCLASS_FILE, FILE__ENTRYPOINT, &ad);
 		if (rc)
 			return rc;
 
@@ -1716,7 +1652,7 @@
 		   the two SIDs, i.e. ahp returns 0. */
 		atsecure = avc_has_perm(tsec->osid, tsec->sid,
 					 SECCLASS_PROCESS,
-					 PROCESS__NOATSECURE, NULL, NULL);
+					 PROCESS__NOATSECURE, NULL);
 	}
 
 	return (atsecure || secondary_ops->bprm_secureexec(bprm));
@@ -1751,8 +1687,7 @@
 			   interested in the inode-based check here. */
 			struct inode *inode = file->f_dentry->d_inode;
 			if (inode_has_perm(current, inode,
-					   FILE__READ | FILE__WRITE,
-					   NULL, NULL)) {
+					   FILE__READ | FILE__WRITE, NULL)) {
 				/* Reset controlling tty. */
 				current->signal->tty = NULL;
 				current->signal->tty_old_pgrp = 0;
@@ -1820,10 +1755,7 @@
 	struct task_security_struct *tsec;
 	struct bprm_security_struct *bsec;
 	u32 sid;
-	struct av_decision avd;
-	struct itimerval itimer;
-	struct rlimit *rlim, *initrlim;
-	int rc, i;
+	int rc;
 
 	secondary_ops->bprm_apply_creds(bprm, unsafe);
 
@@ -1833,93 +1765,101 @@
 	sid = bsec->sid;
 
 	tsec->osid = tsec->sid;
+	bsec->unsafe = 0;
 	if (tsec->sid != sid) {
 		/* Check for shared state.  If not ok, leave SID
 		   unchanged and kill. */
 		if (unsafe & LSM_UNSAFE_SHARE) {
-			rc = avc_has_perm_noaudit(tsec->sid, sid,
-					  SECCLASS_PROCESS, PROCESS__SHARE,
-					  NULL, &avd);
+			rc = avc_has_perm(tsec->sid, sid, SECCLASS_PROCESS,
+					PROCESS__SHARE, NULL);
 			if (rc) {
-				task_unlock(current);
-				avc_audit(tsec->sid, sid, SECCLASS_PROCESS,
-				    PROCESS__SHARE, &avd, rc, NULL);
-				force_sig_specific(SIGKILL, current);
-				goto lock_out;
+				bsec->unsafe = 1;
+				return;
 			}
 		}
 
 		/* Check for ptracing, and update the task SID if ok.
 		   Otherwise, leave SID unchanged and kill. */
 		if (unsafe & (LSM_UNSAFE_PTRACE | LSM_UNSAFE_PTRACE_CAP)) {
-			rc = avc_has_perm_noaudit(tsec->ptrace_sid, sid,
+			rc = avc_has_perm(tsec->ptrace_sid, sid,
 					  SECCLASS_PROCESS, PROCESS__PTRACE,
-					  NULL, &avd);
-			if (!rc)
-				tsec->sid = sid;
-			task_unlock(current);
-			avc_audit(tsec->ptrace_sid, sid, SECCLASS_PROCESS,
-				  PROCESS__PTRACE, &avd, rc, NULL);
+					  NULL);
 			if (rc) {
-				force_sig_specific(SIGKILL, current);
-				goto lock_out;
+				bsec->unsafe = 1;
+				return;
 			}
-		} else {
-			tsec->sid = sid;
-			task_unlock(current);
 		}
+		tsec->sid = sid;
+	}
+}
 
-		/* Close files for which the new task SID is not authorized. */
-		flush_unauthorized_files(current->files);
+/*
+ * called after apply_creds without the task lock held
+ */
+static void selinux_bprm_post_apply_creds(struct linux_binprm *bprm)
+{
+	struct task_security_struct *tsec;
+	struct rlimit *rlim, *initrlim;
+	struct itimerval itimer;
+	struct bprm_security_struct *bsec;
+	int rc, i;
 
-		/* Check whether the new SID can inherit signal state
-		   from the old SID.  If not, clear itimers to avoid
-		   subsequent signal generation and flush and unblock
-		   signals. This must occur _after_ the task SID has
-                  been updated so that any kill done after the flush
-                  will be checked against the new SID. */
-		rc = avc_has_perm(tsec->osid, tsec->sid, SECCLASS_PROCESS,
-				  PROCESS__SIGINH, NULL, NULL);
-		if (rc) {
-			memset(&itimer, 0, sizeof itimer);
-			for (i = 0; i < 3; i++)
-				do_setitimer(i, &itimer, NULL);
-			flush_signals(current);
-			spin_lock_irq(&current->sighand->siglock);
-			flush_signal_handlers(current, 1);
-			sigemptyset(&current->blocked);
-			recalc_sigpending();
-			spin_unlock_irq(&current->sighand->siglock);
-		}
+	tsec = current->security;
+	bsec = bprm->security;
 
-		/* Check whether the new SID can inherit resource limits
-		   from the old SID.  If not, reset all soft limits to
-		   the lower of the current task's hard limit and the init
-		   task's soft limit.  Note that the setting of hard limits 
-		   (even to lower them) can be controlled by the setrlimit 
-		   check. The inclusion of the init task's soft limit into
-	           the computation is to avoid resetting soft limits higher
-		   than the default soft limit for cases where the default
-		   is lower than the hard limit, e.g. RLIMIT_CORE or 
-		   RLIMIT_STACK.*/
-		rc = avc_has_perm(tsec->osid, tsec->sid, SECCLASS_PROCESS,
-				  PROCESS__RLIMITINH, NULL, NULL);
-		if (rc) {
-			for (i = 0; i < RLIM_NLIMITS; i++) {
-				rlim = current->signal->rlim + i;
-				initrlim = init_task.signal->rlim+i;
-				rlim->rlim_cur = min(rlim->rlim_max,initrlim->rlim_cur);
-			}
-		}
+	if (bsec->unsafe) {
+		force_sig_specific(SIGKILL, current);
+		return;
+	}
+	if (tsec->osid == tsec->sid)
+		return;
 
-		/* Wake up the parent if it is waiting so that it can
-		   recheck wait permission to the new task SID. */
-		wake_up_interruptible(&current->parent->wait_chldexit);
+	/* Close files for which the new task SID is not authorized. */
+	flush_unauthorized_files(current->files);
 
-lock_out:
-		task_lock(current);
-		return;
+	/* Check whether the new SID can inherit signal state
+	   from the old SID.  If not, clear itimers to avoid
+	   subsequent signal generation and flush and unblock
+	   signals. This must occur _after_ the task SID has
+	  been updated so that any kill done after the flush
+	  will be checked against the new SID. */
+	rc = avc_has_perm(tsec->osid, tsec->sid, SECCLASS_PROCESS,
+			  PROCESS__SIGINH, NULL);
+	if (rc) {
+		memset(&itimer, 0, sizeof itimer);
+		for (i = 0; i < 3; i++)
+			do_setitimer(i, &itimer, NULL);
+		flush_signals(current);
+		spin_lock_irq(&current->sighand->siglock);
+		flush_signal_handlers(current, 1);
+		sigemptyset(&current->blocked);
+		recalc_sigpending();
+		spin_unlock_irq(&current->sighand->siglock);
+	}
+
+	/* Check whether the new SID can inherit resource limits
+	   from the old SID.  If not, reset all soft limits to
+	   the lower of the current task's hard limit and the init
+	   task's soft limit.  Note that the setting of hard limits
+	   (even to lower them) can be controlled by the setrlimit
+	   check. The inclusion of the init task's soft limit into
+	   the computation is to avoid resetting soft limits higher
+	   than the default soft limit for cases where the default
+	   is lower than the hard limit, e.g. RLIMIT_CORE or
+	   RLIMIT_STACK.*/
+	rc = avc_has_perm(tsec->osid, tsec->sid, SECCLASS_PROCESS,
+			  PROCESS__RLIMITINH, NULL);
+	if (rc) {
+		for (i = 0; i < RLIM_NLIMITS; i++) {
+			rlim = current->signal->rlim + i;
+			initrlim = init_task.signal->rlim+i;
+			rlim->rlim_cur = min(rlim->rlim_max,initrlim->rlim_cur);
+		}
 	}
+
+	/* Wake up the parent if it is waiting so that it can
+	   recheck wait permission to the new task SID. */
+	wake_up_interruptible(&current->parent->signal->wait_chldexit);
 }
 
 /* superblock security operations */
@@ -2189,7 +2129,7 @@
 	}
 
 	return inode_has_perm(current, inode,
-			       file_mask_to_av(inode->i_mode, mask), NULL, NULL);
+			       file_mask_to_av(inode->i_mode, mask), NULL);
 }
 
 static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr)
@@ -2200,6 +2140,9 @@
 	if (rc)
 		return rc;
 
+	if (iattr->ia_valid & ATTR_FORCE)
+		return 0;
+
 	if (iattr->ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID |
 			       ATTR_ATIME_SET | ATTR_MTIME_SET))
 		return dentry_has_perm(current, NULL, dentry, FILE__SETATTR);
@@ -2247,8 +2190,7 @@
 	ad.u.fs.dentry = dentry;
 
 	rc = avc_has_perm(tsec->sid, isec->sid, isec->sclass,
-			  FILE__RELABELFROM,
-			  &isec->avcr, &ad);
+			  FILE__RELABELFROM, &ad);
 	if (rc)
 		return rc;
 
@@ -2257,7 +2199,7 @@
 		return rc;
 
 	rc = avc_has_perm(tsec->sid, newsid, isec->sclass,
-			  FILE__RELABELTO, NULL, &ad);
+			  FILE__RELABELTO, &ad);
 	if (rc)
 		return rc;
 
@@ -2265,7 +2207,6 @@
 			    sbsec->sid,
 			    SECCLASS_FILESYSTEM,
 			    FILESYSTEM__ASSOCIATE,
-			    NULL,
 			    &ad);
 }
 
@@ -2466,6 +2407,17 @@
 
 static int file_map_prot_check(struct file *file, unsigned long prot, int shared)
 {
+	if ((prot & PROT_EXEC) && (!file || (!shared && (prot & PROT_WRITE)))) {
+		/*
+		 * We are making executable an anonymous mapping or a
+		 * private file mapping that will also be writable.
+		 * This has an additional check.
+		 */
+		int rc = task_has_perm(current, current, PROCESS__EXECMEM);
+		if (rc)
+			return rc;
+	}
+
 	if (file) {
 		/* read access is always possible with a mapping */
 		u32 av = FILE__READ;
@@ -2503,6 +2455,18 @@
 	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
+		 * had some COW done. Since pages might have been written,
+		 * check ability to execute the possibly modified content.
+		 * This typically should only occur for text relocations.
+		 */
+		int rc = file_has_perm(current, vma->vm_file, FILE__EXECMOD);
+		if (rc)
+			return rc;
+	}
+
 	return file_map_prot_check(vma->vm_file, prot, vma->vm_flags&VM_SHARED);
 }
 
@@ -2587,7 +2551,7 @@
 		perm = signal_to_av(signum);
 
 	return avc_has_perm(fsec->fown_sid, tsec->sid,
-			    SECCLASS_PROCESS, perm, NULL, NULL);
+			    SECCLASS_PROCESS, perm, NULL);
 }
 
 static int selinux_file_receive(struct file *file)
@@ -2715,17 +2679,7 @@
 
 static int selinux_task_setscheduler(struct task_struct *p, int policy, struct sched_param *lp)
 {
-	struct task_security_struct *tsec1, *tsec2;
-
-	tsec1 = current->security;
-	tsec2 = p->security;
-
-	/* No auditing from the setscheduler hook, since the runqueue lock
-	   is held and the system will deadlock if we try to log an audit
-	   message. */
-	return avc_has_perm_noaudit(tsec1->sid, tsec2->sid,
-				    SECCLASS_PROCESS, PROCESS__SETSCHED,
-				    &tsec2->avcr, NULL);
+	return task_has_perm(current, p, PROCESS__SETSCHED);
 }
 
 static int selinux_task_getscheduler(struct task_struct *p)
@@ -2968,8 +2922,7 @@
 
 	AVC_AUDIT_DATA_INIT(&ad,NET);
 	ad.u.net.sk = sock->sk;
-	err = avc_has_perm(tsec->sid, isec->sid, isec->sclass,
-			   perms, &isec->avcr, &ad);
+	err = avc_has_perm(tsec->sid, isec->sid, isec->sclass, perms, &ad);
 
 out:
 	return err;
@@ -2987,7 +2940,7 @@
 	tsec = current->security;
 	err = avc_has_perm(tsec->sid, tsec->sid,
 			   socket_type_to_security_class(family, type,
-			   protocol), SOCKET__CREATE, NULL, NULL);
+			   protocol), SOCKET__CREATE, NULL);
 
 out:
 	return err;
@@ -3068,7 +3021,7 @@
 			ad.u.net.family = family;
 			err = avc_has_perm(isec->sid, sid,
 					   isec->sclass,
-					   SOCKET__NAME_BIND, NULL, &ad);
+					   SOCKET__NAME_BIND, &ad);
 			if (err)
 				goto out;
 		}
@@ -3101,7 +3054,7 @@
 			ipv6_addr_copy(&ad.u.net.v6info.saddr, &addr6->sin6_addr);
 
 		err = avc_has_perm(isec->sid, sid,
-		                   isec->sclass, node_perm, NULL, &ad);
+		                   isec->sclass, node_perm, &ad);
 		if (err)
 			goto out;
 	}
@@ -3201,8 +3154,7 @@
 
 	err = avc_has_perm(isec->sid, other_isec->sid,
 			   isec->sclass,
-			   UNIX_STREAM_SOCKET__CONNECTTO,
-			   &other_isec->avcr, &ad);
+			   UNIX_STREAM_SOCKET__CONNECTTO, &ad);
 	if (err)
 		return err;
 
@@ -3232,9 +3184,7 @@
 	ad.u.net.sk = other->sk;
 
 	err = avc_has_perm(isec->sid, other_isec->sid,
-			   isec->sclass,
-			   SOCKET__SENDTO,
-			   &other_isec->avcr, &ad);
+			   isec->sclass, SOCKET__SENDTO, &ad);
 	if (err)
 		return err;
 
@@ -3312,8 +3262,7 @@
 	if (err)
 		goto out;
 
-	err = avc_has_perm(sock_sid, if_sid, SECCLASS_NETIF,
-	                   netif_perm, NULL, &ad);
+	err = avc_has_perm(sock_sid, if_sid, SECCLASS_NETIF, netif_perm, &ad);
 	if (err)
 		goto out;
 	
@@ -3322,7 +3271,7 @@
 	if (err)
 		goto out;
 	
-	err = avc_has_perm(sock_sid, node_sid, SECCLASS_NODE, node_perm, NULL, &ad);
+	err = avc_has_perm(sock_sid, node_sid, SECCLASS_NODE, node_perm, &ad);
 	if (err)
 		goto out;
 
@@ -3336,8 +3285,8 @@
 		if (err)
 			goto out;
 
-		err = avc_has_perm(sock_sid, port_sid, sock_class,
-		                   recv_perm, NULL, &ad);
+		err = avc_has_perm(sock_sid, port_sid,
+				   sock_class, recv_perm, &ad);
 	}
 out:	
 	return err;
@@ -3486,7 +3435,7 @@
 		goto out;
 
 	err = avc_has_perm(isec->sid, if_sid, SECCLASS_NETIF,
-	                   netif_perm, NULL, &ad) ? NF_DROP : NF_ACCEPT;
+	                   netif_perm, &ad) ? NF_DROP : NF_ACCEPT;
 	if (err != NF_ACCEPT)
 		goto out;
 		
@@ -3497,7 +3446,7 @@
 		goto out;
 	
 	err = avc_has_perm(isec->sid, node_sid, SECCLASS_NODE,
-	                   node_perm, NULL, &ad) ? NF_DROP : NF_ACCEPT;
+	                   node_perm, &ad) ? NF_DROP : NF_ACCEPT;
 	if (err != NF_ACCEPT)
 		goto out;
 
@@ -3514,7 +3463,7 @@
 			goto out;
 
 		err = avc_has_perm(isec->sid, port_sid, isec->sclass,
-		                   send_perm, NULL, &ad) ? NF_DROP : NF_ACCEPT;
+		                   send_perm, &ad) ? NF_DROP : NF_ACCEPT;
 	}
 
 out:
@@ -3556,12 +3505,20 @@
 
 static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb)
 {
-	int err = 0;
+	struct task_security_struct *tsec;
+	struct av_decision avd;
+	int err;
 
-	if (capable(CAP_NET_ADMIN))
-		cap_raise (NETLINK_CB (skb).eff_cap, CAP_NET_ADMIN);
-	else
-		NETLINK_CB(skb).eff_cap = 0;
+	err = secondary_ops->netlink_send(sk, skb);
+	if (err)
+		return err;
+
+	tsec = current->security;
+
+	avd.allowed = 0;
+	avc_has_perm_noaudit(tsec->sid, tsec->sid,
+				SECCLASS_CAPABILITY, ~0, &avd);
+	cap_mask(NETLINK_CB(skb).eff_cap, avd.allowed);
 
 	if (policydb_loaded_version >= POLICYDB_VERSION_NLCLASS)
 		err = selinux_nlmsg_perm(sk, skb);
@@ -3651,8 +3608,7 @@
 	AVC_AUDIT_DATA_INIT(&ad, IPC);
 	ad.u.ipc_id = ipc_perms->key;
 
-	return avc_has_perm(tsec->sid, isec->sid, sclass,
-			    perms, &isec->avcr, &ad);
+	return avc_has_perm(tsec->sid, isec->sid, sclass, perms, &ad);
 }
 
 static int selinux_msg_msg_alloc_security(struct msg_msg *msg)
@@ -3684,7 +3640,7 @@
  	ad.u.ipc_id = msq->q_perm.key;
 
 	rc = avc_has_perm(tsec->sid, isec->sid, SECCLASS_MSGQ,
-			  MSGQ__CREATE, &isec->avcr, &ad);
+			  MSGQ__CREATE, &ad);
 	if (rc) {
 		ipc_free_security(&msq->q_perm);
 		return rc;
@@ -3710,7 +3666,7 @@
 	ad.u.ipc_id = msq->q_perm.key;
 
 	return avc_has_perm(tsec->sid, isec->sid, SECCLASS_MSGQ,
-			    MSGQ__ASSOCIATE, &isec->avcr, &ad);
+			    MSGQ__ASSOCIATE, &ad);
 }
 
 static int selinux_msg_queue_msgctl(struct msg_queue *msq, int cmd)
@@ -3774,17 +3730,15 @@
 
 	/* Can this process write to the queue? */
 	rc = avc_has_perm(tsec->sid, isec->sid, SECCLASS_MSGQ,
-			  MSGQ__WRITE, &isec->avcr, &ad);
+			  MSGQ__WRITE, &ad);
 	if (!rc)
 		/* Can this process send the message */
 		rc = avc_has_perm(tsec->sid, msec->sid,
-				  SECCLASS_MSG, MSG__SEND,
-				  &msec->avcr, &ad);
+				  SECCLASS_MSG, MSG__SEND, &ad);
 	if (!rc)
 		/* Can the message be put in the queue? */
 		rc = avc_has_perm(msec->sid, isec->sid,
-				  SECCLASS_MSGQ, MSGQ__ENQUEUE,
-				  &isec->avcr, &ad);
+				  SECCLASS_MSGQ, MSGQ__ENQUEUE, &ad);
 
 	return rc;
 }
@@ -3807,12 +3761,10 @@
  	ad.u.ipc_id = msq->q_perm.key;
 
 	rc = avc_has_perm(tsec->sid, isec->sid,
-			  SECCLASS_MSGQ, MSGQ__READ,
-			  &isec->avcr, &ad);
+			  SECCLASS_MSGQ, MSGQ__READ, &ad);
 	if (!rc)
 		rc = avc_has_perm(tsec->sid, msec->sid,
-				  SECCLASS_MSG, MSG__RECEIVE,
-				  &msec->avcr, &ad);
+				  SECCLASS_MSG, MSG__RECEIVE, &ad);
 	return rc;
 }
 
@@ -3835,7 +3787,7 @@
  	ad.u.ipc_id = shp->shm_perm.key;
 
 	rc = avc_has_perm(tsec->sid, isec->sid, SECCLASS_SHM,
-			  SHM__CREATE, &isec->avcr, &ad);
+			  SHM__CREATE, &ad);
 	if (rc) {
 		ipc_free_security(&shp->shm_perm);
 		return rc;
@@ -3861,7 +3813,7 @@
 	ad.u.ipc_id = shp->shm_perm.key;
 
 	return avc_has_perm(tsec->sid, isec->sid, SECCLASS_SHM,
-			    SHM__ASSOCIATE, &isec->avcr, &ad);
+			    SHM__ASSOCIATE, &ad);
 }
 
 /* Note, at this point, shp is locked down */
@@ -3934,7 +3886,7 @@
  	ad.u.ipc_id = sma->sem_perm.key;
 
 	rc = avc_has_perm(tsec->sid, isec->sid, SECCLASS_SEM,
-			  SEM__CREATE, &isec->avcr, &ad);
+			  SEM__CREATE, &ad);
 	if (rc) {
 		ipc_free_security(&sma->sem_perm);
 		return rc;
@@ -3960,7 +3912,7 @@
 	ad.u.ipc_id = sma->sem_perm.key;
 
 	return avc_has_perm(tsec->sid, isec->sid, SECCLASS_SEM,
-			    SEM__ASSOCIATE, &isec->avcr, &ad);
+			    SEM__ASSOCIATE, &ad);
 }
 
 /* Note, at this point, sma is locked down */
@@ -4128,10 +4080,9 @@
 	u32 sid = 0;
 	int error;
 
-	if (current != p || !strcmp(name, "current")) {
+	if (current != p) {
 		/* SELinux only allows a process to change its own
-		   security attributes, and it only allows the process
-		   current SID to change via exec. */
+		   security attributes. */
 		return -EACCES;
 	}
 
@@ -4144,6 +4095,8 @@
 		error = task_has_perm(current, p, PROCESS__SETEXEC);
 	else if (!strcmp(name, "fscreate"))
 		error = task_has_perm(current, p, PROCESS__SETFSCREATE);
+	else if (!strcmp(name, "current"))
+		error = task_has_perm(current, p, PROCESS__SETCURRENT);
 	else
 		error = -EINVAL;
 	if (error)
@@ -4168,6 +4121,51 @@
 		tsec->exec_sid = sid;
 	else if (!strcmp(name, "fscreate"))
 		tsec->create_sid = sid;
+	else if (!strcmp(name, "current")) {
+		struct av_decision avd;
+
+		if (sid == 0)
+			return -EINVAL;
+
+		/* Only allow single threaded processes to change context */
+		if (atomic_read(&p->mm->mm_users) != 1) {
+			struct task_struct *g, *t;
+			struct mm_struct *mm = p->mm;
+			read_lock(&tasklist_lock);
+			do_each_thread(g, t)
+				if (t->mm == mm && t != p) {
+					read_unlock(&tasklist_lock);
+					return -EPERM;
+				}
+			while_each_thread(g, t);
+			read_unlock(&tasklist_lock);
+                }
+
+		/* Check permissions for the transition. */
+		error = avc_has_perm(tsec->sid, sid, SECCLASS_PROCESS,
+		                     PROCESS__DYNTRANSITION, NULL);
+		if (error)
+			return error;
+
+		/* Check for ptracing, and update the task SID if ok.
+		   Otherwise, leave SID unchanged and fail. */
+		task_lock(p);
+		if (p->ptrace & PT_PTRACED) {
+			error = avc_has_perm_noaudit(tsec->ptrace_sid, sid,
+						     SECCLASS_PROCESS,
+						     PROCESS__PTRACE, &avd);
+			if (!error)
+				tsec->sid = sid;
+			task_unlock(p);
+			avc_audit(tsec->ptrace_sid, sid, SECCLASS_PROCESS,
+				  PROCESS__PTRACE, &avd, error, NULL);
+			if (error)
+				return error;
+		} else {
+			tsec->sid = sid;
+			task_unlock(p);
+		}
+	}
 	else
 		return -EINVAL;
 
@@ -4192,6 +4190,7 @@
 	.bprm_alloc_security =		selinux_bprm_alloc_security,
 	.bprm_free_security =		selinux_bprm_free_security,
 	.bprm_apply_creds =		selinux_bprm_apply_creds,
+	.bprm_post_apply_creds =	selinux_bprm_post_apply_creds,
 	.bprm_set_security =		selinux_bprm_set_security,
 	.bprm_check_security =		selinux_bprm_check_security,
 	.bprm_secureexec =		selinux_bprm_secureexec,
diff -Nru a/security/selinux/include/av_inherit.h b/security/selinux/include/av_inherit.h
--- a/security/selinux/include/av_inherit.h	2005-03-01 23:38:58 -08:00
+++ b/security/selinux/include/av_inherit.h	2005-03-01 23:38:58 -08:00
@@ -1,44 +1,30 @@
 /* This file is automatically generated.  Do not edit. */
-/* FLASK */
-
-struct av_inherit
-{
-    u16 tclass;
-    char **common_pts;
-    u32 common_base;
-};
-
-static struct av_inherit av_inherit[] = {
-   { SECCLASS_DIR, common_file_perm_to_string, 0x00020000UL },
-   { SECCLASS_FILE, common_file_perm_to_string, 0x00020000UL },
-   { SECCLASS_LNK_FILE, common_file_perm_to_string, 0x00020000UL },
-   { SECCLASS_CHR_FILE, common_file_perm_to_string, 0x00020000UL },
-   { SECCLASS_BLK_FILE, common_file_perm_to_string, 0x00020000UL },
-   { SECCLASS_SOCK_FILE, common_file_perm_to_string, 0x00020000UL },
-   { SECCLASS_FIFO_FILE, common_file_perm_to_string, 0x00020000UL },
-   { SECCLASS_SOCKET, common_socket_perm_to_string, 0x00400000UL },
-   { SECCLASS_TCP_SOCKET, common_socket_perm_to_string, 0x00400000UL },
-   { SECCLASS_UDP_SOCKET, common_socket_perm_to_string, 0x00400000UL },
-   { SECCLASS_RAWIP_SOCKET, common_socket_perm_to_string, 0x00400000UL },
-   { SECCLASS_NETLINK_SOCKET, common_socket_perm_to_string, 0x00400000UL },
-   { SECCLASS_PACKET_SOCKET, common_socket_perm_to_string, 0x00400000UL },
-   { SECCLASS_KEY_SOCKET, common_socket_perm_to_string, 0x00400000UL },
-   { SECCLASS_UNIX_STREAM_SOCKET, common_socket_perm_to_string, 0x00400000UL },
-   { SECCLASS_UNIX_DGRAM_SOCKET, common_socket_perm_to_string, 0x00400000UL },
-   { SECCLASS_IPC, common_ipc_perm_to_string, 0x00000200UL },
-   { SECCLASS_SEM, common_ipc_perm_to_string, 0x00000200UL },
-   { SECCLASS_MSGQ, common_ipc_perm_to_string, 0x00000200UL },
-   { SECCLASS_SHM, common_ipc_perm_to_string, 0x00000200UL },
-   { SECCLASS_NETLINK_ROUTE_SOCKET, common_socket_perm_to_string, 0x00400000UL },
-   { SECCLASS_NETLINK_FIREWALL_SOCKET, common_socket_perm_to_string, 0x00400000UL },
-   { SECCLASS_NETLINK_TCPDIAG_SOCKET, common_socket_perm_to_string, 0x00400000UL },
-   { SECCLASS_NETLINK_NFLOG_SOCKET, common_socket_perm_to_string, 0x00400000UL },
-   { SECCLASS_NETLINK_XFRM_SOCKET, common_socket_perm_to_string, 0x00400000UL },
-   { SECCLASS_NETLINK_SELINUX_SOCKET, common_socket_perm_to_string, 0x00400000UL },
-   { SECCLASS_NETLINK_AUDIT_SOCKET, common_socket_perm_to_string, 0x00400000UL },
-   { SECCLASS_NETLINK_IP6FW_SOCKET, common_socket_perm_to_string, 0x00400000UL },
-   { SECCLASS_NETLINK_DNRT_SOCKET, common_socket_perm_to_string, 0x00400000UL },
-};
-
-
-/* FLASK */
+   S_(SECCLASS_DIR, file, 0x00020000UL)
+   S_(SECCLASS_FILE, file, 0x00020000UL)
+   S_(SECCLASS_LNK_FILE, file, 0x00020000UL)
+   S_(SECCLASS_CHR_FILE, file, 0x00020000UL)
+   S_(SECCLASS_BLK_FILE, file, 0x00020000UL)
+   S_(SECCLASS_SOCK_FILE, file, 0x00020000UL)
+   S_(SECCLASS_FIFO_FILE, file, 0x00020000UL)
+   S_(SECCLASS_SOCKET, socket, 0x00400000UL)
+   S_(SECCLASS_TCP_SOCKET, socket, 0x00400000UL)
+   S_(SECCLASS_UDP_SOCKET, socket, 0x00400000UL)
+   S_(SECCLASS_RAWIP_SOCKET, socket, 0x00400000UL)
+   S_(SECCLASS_NETLINK_SOCKET, socket, 0x00400000UL)
+   S_(SECCLASS_PACKET_SOCKET, socket, 0x00400000UL)
+   S_(SECCLASS_KEY_SOCKET, socket, 0x00400000UL)
+   S_(SECCLASS_UNIX_STREAM_SOCKET, socket, 0x00400000UL)
+   S_(SECCLASS_UNIX_DGRAM_SOCKET, socket, 0x00400000UL)
+   S_(SECCLASS_IPC, ipc, 0x00000200UL)
+   S_(SECCLASS_SEM, ipc, 0x00000200UL)
+   S_(SECCLASS_MSGQ, ipc, 0x00000200UL)
+   S_(SECCLASS_SHM, ipc, 0x00000200UL)
+   S_(SECCLASS_NETLINK_ROUTE_SOCKET, socket, 0x00400000UL)
+   S_(SECCLASS_NETLINK_FIREWALL_SOCKET, socket, 0x00400000UL)
+   S_(SECCLASS_NETLINK_TCPDIAG_SOCKET, socket, 0x00400000UL)
+   S_(SECCLASS_NETLINK_NFLOG_SOCKET, socket, 0x00400000UL)
+   S_(SECCLASS_NETLINK_XFRM_SOCKET, socket, 0x00400000UL)
+   S_(SECCLASS_NETLINK_SELINUX_SOCKET, socket, 0x00400000UL)
+   S_(SECCLASS_NETLINK_AUDIT_SOCKET, socket, 0x00400000UL)
+   S_(SECCLASS_NETLINK_IP6FW_SOCKET, socket, 0x00400000UL)
+   S_(SECCLASS_NETLINK_DNRT_SOCKET, socket, 0x00400000UL)
diff -Nru 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	2005-03-01 23:39:09 -08:00
+++ b/security/selinux/include/av_perm_to_string.h	2005-03-01 23:39:09 -08:00
@@ -1,225 +1,230 @@
 /* This file is automatically generated.  Do not edit. */
-/* FLASK */
-
-struct av_perm_to_string
-{
-    u16 tclass;
-    u32 value;
-    char *name;
-};
-
-static struct av_perm_to_string av_perm_to_string[] = {
-   { SECCLASS_FILESYSTEM, FILESYSTEM__MOUNT, "mount" },
-   { SECCLASS_FILESYSTEM, FILESYSTEM__REMOUNT, "remount" },
-   { SECCLASS_FILESYSTEM, FILESYSTEM__UNMOUNT, "unmount" },
-   { SECCLASS_FILESYSTEM, FILESYSTEM__GETATTR, "getattr" },
-   { SECCLASS_FILESYSTEM, FILESYSTEM__RELABELFROM, "relabelfrom" },
-   { SECCLASS_FILESYSTEM, FILESYSTEM__RELABELTO, "relabelto" },
-   { SECCLASS_FILESYSTEM, FILESYSTEM__TRANSITION, "transition" },
-   { SECCLASS_FILESYSTEM, FILESYSTEM__ASSOCIATE, "associate" },
-   { SECCLASS_FILESYSTEM, FILESYSTEM__QUOTAMOD, "quotamod" },
-   { SECCLASS_FILESYSTEM, FILESYSTEM__QUOTAGET, "quotaget" },
-   { SECCLASS_DIR, DIR__ADD_NAME, "add_name" },
-   { SECCLASS_DIR, DIR__REMOVE_NAME, "remove_name" },
-   { SECCLASS_DIR, DIR__REPARENT, "reparent" },
-   { SECCLASS_DIR, DIR__SEARCH, "search" },
-   { SECCLASS_DIR, DIR__RMDIR, "rmdir" },
-   { SECCLASS_FILE, FILE__EXECUTE_NO_TRANS, "execute_no_trans" },
-   { SECCLASS_FILE, FILE__ENTRYPOINT, "entrypoint" },
-   { SECCLASS_FD, FD__USE, "use" },
-   { SECCLASS_TCP_SOCKET, TCP_SOCKET__CONNECTTO, "connectto" },
-   { SECCLASS_TCP_SOCKET, TCP_SOCKET__NEWCONN, "newconn" },
-   { SECCLASS_TCP_SOCKET, TCP_SOCKET__ACCEPTFROM, "acceptfrom" },
-   { SECCLASS_TCP_SOCKET, TCP_SOCKET__NODE_BIND, "node_bind" },
-   { SECCLASS_UDP_SOCKET, UDP_SOCKET__NODE_BIND, "node_bind" },
-   { SECCLASS_RAWIP_SOCKET, RAWIP_SOCKET__NODE_BIND, "node_bind" },
-   { SECCLASS_NODE, NODE__TCP_RECV, "tcp_recv" },
-   { SECCLASS_NODE, NODE__TCP_SEND, "tcp_send" },
-   { SECCLASS_NODE, NODE__UDP_RECV, "udp_recv" },
-   { SECCLASS_NODE, NODE__UDP_SEND, "udp_send" },
-   { SECCLASS_NODE, NODE__RAWIP_RECV, "rawip_recv" },
-   { SECCLASS_NODE, NODE__RAWIP_SEND, "rawip_send" },
-   { SECCLASS_NODE, NODE__ENFORCE_DEST, "enforce_dest" },
-   { SECCLASS_NETIF, NETIF__TCP_RECV, "tcp_recv" },
-   { SECCLASS_NETIF, NETIF__TCP_SEND, "tcp_send" },
-   { SECCLASS_NETIF, NETIF__UDP_RECV, "udp_recv" },
-   { SECCLASS_NETIF, NETIF__UDP_SEND, "udp_send" },
-   { SECCLASS_NETIF, NETIF__RAWIP_RECV, "rawip_recv" },
-   { SECCLASS_NETIF, NETIF__RAWIP_SEND, "rawip_send" },
-   { SECCLASS_UNIX_STREAM_SOCKET, UNIX_STREAM_SOCKET__CONNECTTO, "connectto" },
-   { SECCLASS_UNIX_STREAM_SOCKET, UNIX_STREAM_SOCKET__NEWCONN, "newconn" },
-   { SECCLASS_UNIX_STREAM_SOCKET, UNIX_STREAM_SOCKET__ACCEPTFROM, "acceptfrom" },
-   { SECCLASS_PROCESS, PROCESS__FORK, "fork" },
-   { SECCLASS_PROCESS, PROCESS__TRANSITION, "transition" },
-   { SECCLASS_PROCESS, PROCESS__SIGCHLD, "sigchld" },
-   { SECCLASS_PROCESS, PROCESS__SIGKILL, "sigkill" },
-   { SECCLASS_PROCESS, PROCESS__SIGSTOP, "sigstop" },
-   { SECCLASS_PROCESS, PROCESS__SIGNULL, "signull" },
-   { SECCLASS_PROCESS, PROCESS__SIGNAL, "signal" },
-   { SECCLASS_PROCESS, PROCESS__PTRACE, "ptrace" },
-   { SECCLASS_PROCESS, PROCESS__GETSCHED, "getsched" },
-   { SECCLASS_PROCESS, PROCESS__SETSCHED, "setsched" },
-   { SECCLASS_PROCESS, PROCESS__GETSESSION, "getsession" },
-   { SECCLASS_PROCESS, PROCESS__GETPGID, "getpgid" },
-   { SECCLASS_PROCESS, PROCESS__SETPGID, "setpgid" },
-   { SECCLASS_PROCESS, PROCESS__GETCAP, "getcap" },
-   { SECCLASS_PROCESS, PROCESS__SETCAP, "setcap" },
-   { SECCLASS_PROCESS, PROCESS__SHARE, "share" },
-   { SECCLASS_PROCESS, PROCESS__GETATTR, "getattr" },
-   { SECCLASS_PROCESS, PROCESS__SETEXEC, "setexec" },
-   { SECCLASS_PROCESS, PROCESS__SETFSCREATE, "setfscreate" },
-   { SECCLASS_PROCESS, PROCESS__NOATSECURE, "noatsecure" },
-   { SECCLASS_PROCESS, PROCESS__SIGINH, "siginh" },
-   { SECCLASS_PROCESS, PROCESS__SETRLIMIT, "setrlimit" },
-   { SECCLASS_PROCESS, PROCESS__RLIMITINH, "rlimitinh" },
-   { SECCLASS_MSGQ, MSGQ__ENQUEUE, "enqueue" },
-   { SECCLASS_MSG, MSG__SEND, "send" },
-   { SECCLASS_MSG, MSG__RECEIVE, "receive" },
-   { SECCLASS_SHM, SHM__LOCK, "lock" },
-   { SECCLASS_SECURITY, SECURITY__COMPUTE_AV, "compute_av" },
-   { SECCLASS_SECURITY, SECURITY__COMPUTE_CREATE, "compute_create" },
-   { SECCLASS_SECURITY, SECURITY__COMPUTE_MEMBER, "compute_member" },
-   { SECCLASS_SECURITY, SECURITY__CHECK_CONTEXT, "check_context" },
-   { SECCLASS_SECURITY, SECURITY__LOAD_POLICY, "load_policy" },
-   { SECCLASS_SECURITY, SECURITY__COMPUTE_RELABEL, "compute_relabel" },
-   { SECCLASS_SECURITY, SECURITY__COMPUTE_USER, "compute_user" },
-   { SECCLASS_SECURITY, SECURITY__SETENFORCE, "setenforce" },
-   { SECCLASS_SECURITY, SECURITY__SETBOOL, "setbool" },
-   { SECCLASS_SYSTEM, SYSTEM__IPC_INFO, "ipc_info" },
-   { SECCLASS_SYSTEM, SYSTEM__SYSLOG_READ, "syslog_read" },
-   { SECCLASS_SYSTEM, SYSTEM__SYSLOG_MOD, "syslog_mod" },
-   { SECCLASS_SYSTEM, SYSTEM__SYSLOG_CONSOLE, "syslog_console" },
-   { SECCLASS_CAPABILITY, CAPABILITY__CHOWN, "chown" },
-   { SECCLASS_CAPABILITY, CAPABILITY__DAC_OVERRIDE, "dac_override" },
-   { SECCLASS_CAPABILITY, CAPABILITY__DAC_READ_SEARCH, "dac_read_search" },
-   { SECCLASS_CAPABILITY, CAPABILITY__FOWNER, "fowner" },
-   { SECCLASS_CAPABILITY, CAPABILITY__FSETID, "fsetid" },
-   { SECCLASS_CAPABILITY, CAPABILITY__KILL, "kill" },
-   { SECCLASS_CAPABILITY, CAPABILITY__SETGID, "setgid" },
-   { SECCLASS_CAPABILITY, CAPABILITY__SETUID, "setuid" },
-   { SECCLASS_CAPABILITY, CAPABILITY__SETPCAP, "setpcap" },
-   { SECCLASS_CAPABILITY, CAPABILITY__LINUX_IMMUTABLE, "linux_immutable" },
-   { SECCLASS_CAPABILITY, CAPABILITY__NET_BIND_SERVICE, "net_bind_service" },
-   { SECCLASS_CAPABILITY, CAPABILITY__NET_BROADCAST, "net_broadcast" },
-   { SECCLASS_CAPABILITY, CAPABILITY__NET_ADMIN, "net_admin" },
-   { SECCLASS_CAPABILITY, CAPABILITY__NET_RAW, "net_raw" },
-   { SECCLASS_CAPABILITY, CAPABILITY__IPC_LOCK, "ipc_lock" },
-   { SECCLASS_CAPABILITY, CAPABILITY__IPC_OWNER, "ipc_owner" },
-   { SECCLASS_CAPABILITY, CAPABILITY__SYS_MODULE, "sys_module" },
-   { SECCLASS_CAPABILITY, CAPABILITY__SYS_RAWIO, "sys_rawio" },
-   { SECCLASS_CAPABILITY, CAPABILITY__SYS_CHROOT, "sys_chroot" },
-   { SECCLASS_CAPABILITY, CAPABILITY__SYS_PTRACE, "sys_ptrace" },
-   { SECCLASS_CAPABILITY, CAPABILITY__SYS_PACCT, "sys_pacct" },
-   { SECCLASS_CAPABILITY, CAPABILITY__SYS_ADMIN, "sys_admin" },
-   { SECCLASS_CAPABILITY, CAPABILITY__SYS_BOOT, "sys_boot" },
-   { SECCLASS_CAPABILITY, CAPABILITY__SYS_NICE, "sys_nice" },
-   { SECCLASS_CAPABILITY, CAPABILITY__SYS_RESOURCE, "sys_resource" },
-   { SECCLASS_CAPABILITY, CAPABILITY__SYS_TIME, "sys_time" },
-   { SECCLASS_CAPABILITY, CAPABILITY__SYS_TTY_CONFIG, "sys_tty_config" },
-   { SECCLASS_CAPABILITY, CAPABILITY__MKNOD, "mknod" },
-   { SECCLASS_CAPABILITY, CAPABILITY__LEASE, "lease" },
-   { SECCLASS_PASSWD, PASSWD__PASSWD, "passwd" },
-   { SECCLASS_PASSWD, PASSWD__CHFN, "chfn" },
-   { SECCLASS_PASSWD, PASSWD__CHSH, "chsh" },
-   { SECCLASS_PASSWD, PASSWD__ROOTOK, "rootok" },
-   { SECCLASS_DRAWABLE, DRAWABLE__CREATE, "create" },
-   { SECCLASS_DRAWABLE, DRAWABLE__DESTROY, "destroy" },
-   { SECCLASS_DRAWABLE, DRAWABLE__DRAW, "draw" },
-   { SECCLASS_DRAWABLE, DRAWABLE__COPY, "copy" },
-   { SECCLASS_DRAWABLE, DRAWABLE__GETATTR, "getattr" },
-   { SECCLASS_GC, GC__CREATE, "create" },
-   { SECCLASS_GC, GC__FREE, "free" },
-   { SECCLASS_GC, GC__GETATTR, "getattr" },
-   { SECCLASS_GC, GC__SETATTR, "setattr" },
-   { SECCLASS_WINDOW, WINDOW__ADDCHILD, "addchild" },
-   { SECCLASS_WINDOW, WINDOW__CREATE, "create" },
-   { SECCLASS_WINDOW, WINDOW__DESTROY, "destroy" },
-   { SECCLASS_WINDOW, WINDOW__MAP, "map" },
-   { SECCLASS_WINDOW, WINDOW__UNMAP, "unmap" },
-   { SECCLASS_WINDOW, WINDOW__CHSTACK, "chstack" },
-   { SECCLASS_WINDOW, WINDOW__CHPROPLIST, "chproplist" },
-   { SECCLASS_WINDOW, WINDOW__CHPROP, "chprop" },
-   { SECCLASS_WINDOW, WINDOW__LISTPROP, "listprop" },
-   { SECCLASS_WINDOW, WINDOW__GETATTR, "getattr" },
-   { SECCLASS_WINDOW, WINDOW__SETATTR, "setattr" },
-   { SECCLASS_WINDOW, WINDOW__SETFOCUS, "setfocus" },
-   { SECCLASS_WINDOW, WINDOW__MOVE, "move" },
-   { SECCLASS_WINDOW, WINDOW__CHSELECTION, "chselection" },
-   { SECCLASS_WINDOW, WINDOW__CHPARENT, "chparent" },
-   { SECCLASS_WINDOW, WINDOW__CTRLLIFE, "ctrllife" },
-   { SECCLASS_WINDOW, WINDOW__ENUMERATE, "enumerate" },
-   { SECCLASS_WINDOW, WINDOW__TRANSPARENT, "transparent" },
-   { SECCLASS_WINDOW, WINDOW__MOUSEMOTION, "mousemotion" },
-   { SECCLASS_WINDOW, WINDOW__CLIENTCOMEVENT, "clientcomevent" },
-   { SECCLASS_WINDOW, WINDOW__INPUTEVENT, "inputevent" },
-   { SECCLASS_WINDOW, WINDOW__DRAWEVENT, "drawevent" },
-   { SECCLASS_WINDOW, WINDOW__WINDOWCHANGEEVENT, "windowchangeevent" },
-   { SECCLASS_WINDOW, WINDOW__WINDOWCHANGEREQUEST, "windowchangerequest" },
-   { SECCLASS_WINDOW, WINDOW__SERVERCHANGEEVENT, "serverchangeevent" },
-   { SECCLASS_WINDOW, WINDOW__EXTENSIONEVENT, "extensionevent" },
-   { SECCLASS_FONT, FONT__LOAD, "load" },
-   { SECCLASS_FONT, FONT__FREE, "free" },
-   { SECCLASS_FONT, FONT__GETATTR, "getattr" },
-   { SECCLASS_FONT, FONT__USE, "use" },
-   { SECCLASS_COLORMAP, COLORMAP__CREATE, "create" },
-   { SECCLASS_COLORMAP, COLORMAP__FREE, "free" },
-   { SECCLASS_COLORMAP, COLORMAP__INSTALL, "install" },
-   { SECCLASS_COLORMAP, COLORMAP__UNINSTALL, "uninstall" },
-   { SECCLASS_COLORMAP, COLORMAP__LIST, "list" },
-   { SECCLASS_COLORMAP, COLORMAP__READ, "read" },
-   { SECCLASS_COLORMAP, COLORMAP__STORE, "store" },
-   { SECCLASS_COLORMAP, COLORMAP__GETATTR, "getattr" },
-   { SECCLASS_COLORMAP, COLORMAP__SETATTR, "setattr" },
-   { SECCLASS_PROPERTY, PROPERTY__CREATE, "create" },
-   { SECCLASS_PROPERTY, PROPERTY__FREE, "free" },
-   { SECCLASS_PROPERTY, PROPERTY__READ, "read" },
-   { SECCLASS_PROPERTY, PROPERTY__WRITE, "write" },
-   { SECCLASS_CURSOR, CURSOR__CREATE, "create" },
-   { SECCLASS_CURSOR, CURSOR__CREATEGLYPH, "createglyph" },
-   { SECCLASS_CURSOR, CURSOR__FREE, "free" },
-   { SECCLASS_CURSOR, CURSOR__ASSIGN, "assign" },
-   { SECCLASS_CURSOR, CURSOR__SETATTR, "setattr" },
-   { SECCLASS_XCLIENT, XCLIENT__KILL, "kill" },
-   { SECCLASS_XINPUT, XINPUT__LOOKUP, "lookup" },
-   { SECCLASS_XINPUT, XINPUT__GETATTR, "getattr" },
-   { SECCLASS_XINPUT, XINPUT__SETATTR, "setattr" },
-   { SECCLASS_XINPUT, XINPUT__SETFOCUS, "setfocus" },
-   { SECCLASS_XINPUT, XINPUT__WARPPOINTER, "warppointer" },
-   { SECCLASS_XINPUT, XINPUT__ACTIVEGRAB, "activegrab" },
-   { SECCLASS_XINPUT, XINPUT__PASSIVEGRAB, "passivegrab" },
-   { SECCLASS_XINPUT, XINPUT__UNGRAB, "ungrab" },
-   { SECCLASS_XINPUT, XINPUT__BELL, "bell" },
-   { SECCLASS_XINPUT, XINPUT__MOUSEMOTION, "mousemotion" },
-   { SECCLASS_XINPUT, XINPUT__RELABELINPUT, "relabelinput" },
-   { SECCLASS_XSERVER, XSERVER__SCREENSAVER, "screensaver" },
-   { SECCLASS_XSERVER, XSERVER__GETHOSTLIST, "gethostlist" },
-   { SECCLASS_XSERVER, XSERVER__SETHOSTLIST, "sethostlist" },
-   { SECCLASS_XSERVER, XSERVER__GETFONTPATH, "getfontpath" },
-   { SECCLASS_XSERVER, XSERVER__SETFONTPATH, "setfontpath" },
-   { SECCLASS_XSERVER, XSERVER__GETATTR, "getattr" },
-   { SECCLASS_XSERVER, XSERVER__GRAB, "grab" },
-   { SECCLASS_XSERVER, XSERVER__UNGRAB, "ungrab" },
-   { SECCLASS_XEXTENSION, XEXTENSION__QUERY, "query" },
-   { SECCLASS_XEXTENSION, XEXTENSION__USE, "use" },
-   { SECCLASS_PAX, PAX__PAGEEXEC, "pageexec" },
-   { SECCLASS_PAX, PAX__EMUTRAMP, "emutramp" },
-   { SECCLASS_PAX, PAX__MPROTECT, "mprotect" },
-   { SECCLASS_PAX, PAX__RANDMMAP, "randmmap" },
-   { SECCLASS_PAX, PAX__RANDEXEC, "randexec" },
-   { SECCLASS_PAX, PAX__SEGMEXEC, "segmexec" },
-   { SECCLASS_NETLINK_ROUTE_SOCKET, NETLINK_ROUTE_SOCKET__NLMSG_READ, "nlmsg_read" },
-   { SECCLASS_NETLINK_ROUTE_SOCKET, NETLINK_ROUTE_SOCKET__NLMSG_WRITE, "nlmsg_write" },
-   { SECCLASS_NETLINK_FIREWALL_SOCKET, NETLINK_FIREWALL_SOCKET__NLMSG_READ, "nlmsg_read" },
-   { SECCLASS_NETLINK_FIREWALL_SOCKET, NETLINK_FIREWALL_SOCKET__NLMSG_WRITE, "nlmsg_write" },
-   { SECCLASS_NETLINK_TCPDIAG_SOCKET, NETLINK_TCPDIAG_SOCKET__NLMSG_READ, "nlmsg_read" },
-   { SECCLASS_NETLINK_TCPDIAG_SOCKET, NETLINK_TCPDIAG_SOCKET__NLMSG_WRITE, "nlmsg_write" },
-   { SECCLASS_NETLINK_XFRM_SOCKET, NETLINK_XFRM_SOCKET__NLMSG_READ, "nlmsg_read" },
-   { SECCLASS_NETLINK_XFRM_SOCKET, NETLINK_XFRM_SOCKET__NLMSG_WRITE, "nlmsg_write" },
-   { SECCLASS_NETLINK_AUDIT_SOCKET, NETLINK_AUDIT_SOCKET__NLMSG_READ, "nlmsg_read" },
-   { SECCLASS_NETLINK_AUDIT_SOCKET, NETLINK_AUDIT_SOCKET__NLMSG_WRITE, "nlmsg_write" },
-   { SECCLASS_NETLINK_IP6FW_SOCKET, NETLINK_IP6FW_SOCKET__NLMSG_READ, "nlmsg_read" },
-   { SECCLASS_NETLINK_IP6FW_SOCKET, NETLINK_IP6FW_SOCKET__NLMSG_WRITE, "nlmsg_write" },
-};
-
-
-/* FLASK */
+   S_(SECCLASS_FILESYSTEM, FILESYSTEM__MOUNT, "mount")
+   S_(SECCLASS_FILESYSTEM, FILESYSTEM__REMOUNT, "remount")
+   S_(SECCLASS_FILESYSTEM, FILESYSTEM__UNMOUNT, "unmount")
+   S_(SECCLASS_FILESYSTEM, FILESYSTEM__GETATTR, "getattr")
+   S_(SECCLASS_FILESYSTEM, FILESYSTEM__RELABELFROM, "relabelfrom")
+   S_(SECCLASS_FILESYSTEM, FILESYSTEM__RELABELTO, "relabelto")
+   S_(SECCLASS_FILESYSTEM, FILESYSTEM__TRANSITION, "transition")
+   S_(SECCLASS_FILESYSTEM, FILESYSTEM__ASSOCIATE, "associate")
+   S_(SECCLASS_FILESYSTEM, FILESYSTEM__QUOTAMOD, "quotamod")
+   S_(SECCLASS_FILESYSTEM, FILESYSTEM__QUOTAGET, "quotaget")
+   S_(SECCLASS_DIR, DIR__ADD_NAME, "add_name")
+   S_(SECCLASS_DIR, DIR__REMOVE_NAME, "remove_name")
+   S_(SECCLASS_DIR, DIR__REPARENT, "reparent")
+   S_(SECCLASS_DIR, DIR__SEARCH, "search")
+   S_(SECCLASS_DIR, DIR__RMDIR, "rmdir")
+   S_(SECCLASS_FILE, FILE__EXECUTE_NO_TRANS, "execute_no_trans")
+   S_(SECCLASS_FILE, FILE__ENTRYPOINT, "entrypoint")
+   S_(SECCLASS_FILE, FILE__EXECMOD, "execmod")
+   S_(SECCLASS_CHR_FILE, CHR_FILE__EXECUTE_NO_TRANS, "execute_no_trans")
+   S_(SECCLASS_CHR_FILE, CHR_FILE__ENTRYPOINT, "entrypoint")
+   S_(SECCLASS_CHR_FILE, CHR_FILE__EXECMOD, "execmod")
+   S_(SECCLASS_FD, FD__USE, "use")
+   S_(SECCLASS_TCP_SOCKET, TCP_SOCKET__CONNECTTO, "connectto")
+   S_(SECCLASS_TCP_SOCKET, TCP_SOCKET__NEWCONN, "newconn")
+   S_(SECCLASS_TCP_SOCKET, TCP_SOCKET__ACCEPTFROM, "acceptfrom")
+   S_(SECCLASS_TCP_SOCKET, TCP_SOCKET__NODE_BIND, "node_bind")
+   S_(SECCLASS_UDP_SOCKET, UDP_SOCKET__NODE_BIND, "node_bind")
+   S_(SECCLASS_RAWIP_SOCKET, RAWIP_SOCKET__NODE_BIND, "node_bind")
+   S_(SECCLASS_NODE, NODE__TCP_RECV, "tcp_recv")
+   S_(SECCLASS_NODE, NODE__TCP_SEND, "tcp_send")
+   S_(SECCLASS_NODE, NODE__UDP_RECV, "udp_recv")
+   S_(SECCLASS_NODE, NODE__UDP_SEND, "udp_send")
+   S_(SECCLASS_NODE, NODE__RAWIP_RECV, "rawip_recv")
+   S_(SECCLASS_NODE, NODE__RAWIP_SEND, "rawip_send")
+   S_(SECCLASS_NODE, NODE__ENFORCE_DEST, "enforce_dest")
+   S_(SECCLASS_NETIF, NETIF__TCP_RECV, "tcp_recv")
+   S_(SECCLASS_NETIF, NETIF__TCP_SEND, "tcp_send")
+   S_(SECCLASS_NETIF, NETIF__UDP_RECV, "udp_recv")
+   S_(SECCLASS_NETIF, NETIF__UDP_SEND, "udp_send")
+   S_(SECCLASS_NETIF, NETIF__RAWIP_RECV, "rawip_recv")
+   S_(SECCLASS_NETIF, NETIF__RAWIP_SEND, "rawip_send")
+   S_(SECCLASS_UNIX_STREAM_SOCKET, UNIX_STREAM_SOCKET__CONNECTTO, "connectto")
+   S_(SECCLASS_UNIX_STREAM_SOCKET, UNIX_STREAM_SOCKET__NEWCONN, "newconn")
+   S_(SECCLASS_UNIX_STREAM_SOCKET, UNIX_STREAM_SOCKET__ACCEPTFROM, "acceptfrom")
+   S_(SECCLASS_PROCESS, PROCESS__FORK, "fork")
+   S_(SECCLASS_PROCESS, PROCESS__TRANSITION, "transition")
+   S_(SECCLASS_PROCESS, PROCESS__SIGCHLD, "sigchld")
+   S_(SECCLASS_PROCESS, PROCESS__SIGKILL, "sigkill")
+   S_(SECCLASS_PROCESS, PROCESS__SIGSTOP, "sigstop")
+   S_(SECCLASS_PROCESS, PROCESS__SIGNULL, "signull")
+   S_(SECCLASS_PROCESS, PROCESS__SIGNAL, "signal")
+   S_(SECCLASS_PROCESS, PROCESS__PTRACE, "ptrace")
+   S_(SECCLASS_PROCESS, PROCESS__GETSCHED, "getsched")
+   S_(SECCLASS_PROCESS, PROCESS__SETSCHED, "setsched")
+   S_(SECCLASS_PROCESS, PROCESS__GETSESSION, "getsession")
+   S_(SECCLASS_PROCESS, PROCESS__GETPGID, "getpgid")
+   S_(SECCLASS_PROCESS, PROCESS__SETPGID, "setpgid")
+   S_(SECCLASS_PROCESS, PROCESS__GETCAP, "getcap")
+   S_(SECCLASS_PROCESS, PROCESS__SETCAP, "setcap")
+   S_(SECCLASS_PROCESS, PROCESS__SHARE, "share")
+   S_(SECCLASS_PROCESS, PROCESS__GETATTR, "getattr")
+   S_(SECCLASS_PROCESS, PROCESS__SETEXEC, "setexec")
+   S_(SECCLASS_PROCESS, PROCESS__SETFSCREATE, "setfscreate")
+   S_(SECCLASS_PROCESS, PROCESS__NOATSECURE, "noatsecure")
+   S_(SECCLASS_PROCESS, PROCESS__SIGINH, "siginh")
+   S_(SECCLASS_PROCESS, PROCESS__SETRLIMIT, "setrlimit")
+   S_(SECCLASS_PROCESS, PROCESS__RLIMITINH, "rlimitinh")
+   S_(SECCLASS_PROCESS, PROCESS__DYNTRANSITION, "dyntransition")
+   S_(SECCLASS_PROCESS, PROCESS__SETCURRENT, "setcurrent")
+   S_(SECCLASS_PROCESS, PROCESS__EXECMEM, "execmem")
+   S_(SECCLASS_MSGQ, MSGQ__ENQUEUE, "enqueue")
+   S_(SECCLASS_MSG, MSG__SEND, "send")
+   S_(SECCLASS_MSG, MSG__RECEIVE, "receive")
+   S_(SECCLASS_SHM, SHM__LOCK, "lock")
+   S_(SECCLASS_SECURITY, SECURITY__COMPUTE_AV, "compute_av")
+   S_(SECCLASS_SECURITY, SECURITY__COMPUTE_CREATE, "compute_create")
+   S_(SECCLASS_SECURITY, SECURITY__COMPUTE_MEMBER, "compute_member")
+   S_(SECCLASS_SECURITY, SECURITY__CHECK_CONTEXT, "check_context")
+   S_(SECCLASS_SECURITY, SECURITY__LOAD_POLICY, "load_policy")
+   S_(SECCLASS_SECURITY, SECURITY__COMPUTE_RELABEL, "compute_relabel")
+   S_(SECCLASS_SECURITY, SECURITY__COMPUTE_USER, "compute_user")
+   S_(SECCLASS_SECURITY, SECURITY__SETENFORCE, "setenforce")
+   S_(SECCLASS_SECURITY, SECURITY__SETBOOL, "setbool")
+   S_(SECCLASS_SECURITY, SECURITY__SETSECPARAM, "setsecparam")
+   S_(SECCLASS_SYSTEM, SYSTEM__IPC_INFO, "ipc_info")
+   S_(SECCLASS_SYSTEM, SYSTEM__SYSLOG_READ, "syslog_read")
+   S_(SECCLASS_SYSTEM, SYSTEM__SYSLOG_MOD, "syslog_mod")
+   S_(SECCLASS_SYSTEM, SYSTEM__SYSLOG_CONSOLE, "syslog_console")
+   S_(SECCLASS_CAPABILITY, CAPABILITY__CHOWN, "chown")
+   S_(SECCLASS_CAPABILITY, CAPABILITY__DAC_OVERRIDE, "dac_override")
+   S_(SECCLASS_CAPABILITY, CAPABILITY__DAC_READ_SEARCH, "dac_read_search")
+   S_(SECCLASS_CAPABILITY, CAPABILITY__FOWNER, "fowner")
+   S_(SECCLASS_CAPABILITY, CAPABILITY__FSETID, "fsetid")
+   S_(SECCLASS_CAPABILITY, CAPABILITY__KILL, "kill")
+   S_(SECCLASS_CAPABILITY, CAPABILITY__SETGID, "setgid")
+   S_(SECCLASS_CAPABILITY, CAPABILITY__SETUID, "setuid")
+   S_(SECCLASS_CAPABILITY, CAPABILITY__SETPCAP, "setpcap")
+   S_(SECCLASS_CAPABILITY, CAPABILITY__LINUX_IMMUTABLE, "linux_immutable")
+   S_(SECCLASS_CAPABILITY, CAPABILITY__NET_BIND_SERVICE, "net_bind_service")
+   S_(SECCLASS_CAPABILITY, CAPABILITY__NET_BROADCAST, "net_broadcast")
+   S_(SECCLASS_CAPABILITY, CAPABILITY__NET_ADMIN, "net_admin")
+   S_(SECCLASS_CAPABILITY, CAPABILITY__NET_RAW, "net_raw")
+   S_(SECCLASS_CAPABILITY, CAPABILITY__IPC_LOCK, "ipc_lock")
+   S_(SECCLASS_CAPABILITY, CAPABILITY__IPC_OWNER, "ipc_owner")
+   S_(SECCLASS_CAPABILITY, CAPABILITY__SYS_MODULE, "sys_module")
+   S_(SECCLASS_CAPABILITY, CAPABILITY__SYS_RAWIO, "sys_rawio")
+   S_(SECCLASS_CAPABILITY, CAPABILITY__SYS_CHROOT, "sys_chroot")
+   S_(SECCLASS_CAPABILITY, CAPABILITY__SYS_PTRACE, "sys_ptrace")
+   S_(SECCLASS_CAPABILITY, CAPABILITY__SYS_PACCT, "sys_pacct")
+   S_(SECCLASS_CAPABILITY, CAPABILITY__SYS_ADMIN, "sys_admin")
+   S_(SECCLASS_CAPABILITY, CAPABILITY__SYS_BOOT, "sys_boot")
+   S_(SECCLASS_CAPABILITY, CAPABILITY__SYS_NICE, "sys_nice")
+   S_(SECCLASS_CAPABILITY, CAPABILITY__SYS_RESOURCE, "sys_resource")
+   S_(SECCLASS_CAPABILITY, CAPABILITY__SYS_TIME, "sys_time")
+   S_(SECCLASS_CAPABILITY, CAPABILITY__SYS_TTY_CONFIG, "sys_tty_config")
+   S_(SECCLASS_CAPABILITY, CAPABILITY__MKNOD, "mknod")
+   S_(SECCLASS_CAPABILITY, CAPABILITY__LEASE, "lease")
+   S_(SECCLASS_PASSWD, PASSWD__PASSWD, "passwd")
+   S_(SECCLASS_PASSWD, PASSWD__CHFN, "chfn")
+   S_(SECCLASS_PASSWD, PASSWD__CHSH, "chsh")
+   S_(SECCLASS_PASSWD, PASSWD__ROOTOK, "rootok")
+   S_(SECCLASS_PASSWD, PASSWD__CRONTAB, "crontab")
+   S_(SECCLASS_DRAWABLE, DRAWABLE__CREATE, "create")
+   S_(SECCLASS_DRAWABLE, DRAWABLE__DESTROY, "destroy")
+   S_(SECCLASS_DRAWABLE, DRAWABLE__DRAW, "draw")
+   S_(SECCLASS_DRAWABLE, DRAWABLE__COPY, "copy")
+   S_(SECCLASS_DRAWABLE, DRAWABLE__GETATTR, "getattr")
+   S_(SECCLASS_GC, GC__CREATE, "create")
+   S_(SECCLASS_GC, GC__FREE, "free")
+   S_(SECCLASS_GC, GC__GETATTR, "getattr")
+   S_(SECCLASS_GC, GC__SETATTR, "setattr")
+   S_(SECCLASS_WINDOW, WINDOW__ADDCHILD, "addchild")
+   S_(SECCLASS_WINDOW, WINDOW__CREATE, "create")
+   S_(SECCLASS_WINDOW, WINDOW__DESTROY, "destroy")
+   S_(SECCLASS_WINDOW, WINDOW__MAP, "map")
+   S_(SECCLASS_WINDOW, WINDOW__UNMAP, "unmap")
+   S_(SECCLASS_WINDOW, WINDOW__CHSTACK, "chstack")
+   S_(SECCLASS_WINDOW, WINDOW__CHPROPLIST, "chproplist")
+   S_(SECCLASS_WINDOW, WINDOW__CHPROP, "chprop")
+   S_(SECCLASS_WINDOW, WINDOW__LISTPROP, "listprop")
+   S_(SECCLASS_WINDOW, WINDOW__GETATTR, "getattr")
+   S_(SECCLASS_WINDOW, WINDOW__SETATTR, "setattr")
+   S_(SECCLASS_WINDOW, WINDOW__SETFOCUS, "setfocus")
+   S_(SECCLASS_WINDOW, WINDOW__MOVE, "move")
+   S_(SECCLASS_WINDOW, WINDOW__CHSELECTION, "chselection")
+   S_(SECCLASS_WINDOW, WINDOW__CHPARENT, "chparent")
+   S_(SECCLASS_WINDOW, WINDOW__CTRLLIFE, "ctrllife")
+   S_(SECCLASS_WINDOW, WINDOW__ENUMERATE, "enumerate")
+   S_(SECCLASS_WINDOW, WINDOW__TRANSPARENT, "transparent")
+   S_(SECCLASS_WINDOW, WINDOW__MOUSEMOTION, "mousemotion")
+   S_(SECCLASS_WINDOW, WINDOW__CLIENTCOMEVENT, "clientcomevent")
+   S_(SECCLASS_WINDOW, WINDOW__INPUTEVENT, "inputevent")
+   S_(SECCLASS_WINDOW, WINDOW__DRAWEVENT, "drawevent")
+   S_(SECCLASS_WINDOW, WINDOW__WINDOWCHANGEEVENT, "windowchangeevent")
+   S_(SECCLASS_WINDOW, WINDOW__WINDOWCHANGEREQUEST, "windowchangerequest")
+   S_(SECCLASS_WINDOW, WINDOW__SERVERCHANGEEVENT, "serverchangeevent")
+   S_(SECCLASS_WINDOW, WINDOW__EXTENSIONEVENT, "extensionevent")
+   S_(SECCLASS_FONT, FONT__LOAD, "load")
+   S_(SECCLASS_FONT, FONT__FREE, "free")
+   S_(SECCLASS_FONT, FONT__GETATTR, "getattr")
+   S_(SECCLASS_FONT, FONT__USE, "use")
+   S_(SECCLASS_COLORMAP, COLORMAP__CREATE, "create")
+   S_(SECCLASS_COLORMAP, COLORMAP__FREE, "free")
+   S_(SECCLASS_COLORMAP, COLORMAP__INSTALL, "install")
+   S_(SECCLASS_COLORMAP, COLORMAP__UNINSTALL, "uninstall")
+   S_(SECCLASS_COLORMAP, COLORMAP__LIST, "list")
+   S_(SECCLASS_COLORMAP, COLORMAP__READ, "read")
+   S_(SECCLASS_COLORMAP, COLORMAP__STORE, "store")
+   S_(SECCLASS_COLORMAP, COLORMAP__GETATTR, "getattr")
+   S_(SECCLASS_COLORMAP, COLORMAP__SETATTR, "setattr")
+   S_(SECCLASS_PROPERTY, PROPERTY__CREATE, "create")
+   S_(SECCLASS_PROPERTY, PROPERTY__FREE, "free")
+   S_(SECCLASS_PROPERTY, PROPERTY__READ, "read")
+   S_(SECCLASS_PROPERTY, PROPERTY__WRITE, "write")
+   S_(SECCLASS_CURSOR, CURSOR__CREATE, "create")
+   S_(SECCLASS_CURSOR, CURSOR__CREATEGLYPH, "createglyph")
+   S_(SECCLASS_CURSOR, CURSOR__FREE, "free")
+   S_(SECCLASS_CURSOR, CURSOR__ASSIGN, "assign")
+   S_(SECCLASS_CURSOR, CURSOR__SETATTR, "setattr")
+   S_(SECCLASS_XCLIENT, XCLIENT__KILL, "kill")
+   S_(SECCLASS_XINPUT, XINPUT__LOOKUP, "lookup")
+   S_(SECCLASS_XINPUT, XINPUT__GETATTR, "getattr")
+   S_(SECCLASS_XINPUT, XINPUT__SETATTR, "setattr")
+   S_(SECCLASS_XINPUT, XINPUT__SETFOCUS, "setfocus")
+   S_(SECCLASS_XINPUT, XINPUT__WARPPOINTER, "warppointer")
+   S_(SECCLASS_XINPUT, XINPUT__ACTIVEGRAB, "activegrab")
+   S_(SECCLASS_XINPUT, XINPUT__PASSIVEGRAB, "passivegrab")
+   S_(SECCLASS_XINPUT, XINPUT__UNGRAB, "ungrab")
+   S_(SECCLASS_XINPUT, XINPUT__BELL, "bell")
+   S_(SECCLASS_XINPUT, XINPUT__MOUSEMOTION, "mousemotion")
+   S_(SECCLASS_XINPUT, XINPUT__RELABELINPUT, "relabelinput")
+   S_(SECCLASS_XSERVER, XSERVER__SCREENSAVER, "screensaver")
+   S_(SECCLASS_XSERVER, XSERVER__GETHOSTLIST, "gethostlist")
+   S_(SECCLASS_XSERVER, XSERVER__SETHOSTLIST, "sethostlist")
+   S_(SECCLASS_XSERVER, XSERVER__GETFONTPATH, "getfontpath")
+   S_(SECCLASS_XSERVER, XSERVER__SETFONTPATH, "setfontpath")
+   S_(SECCLASS_XSERVER, XSERVER__GETATTR, "getattr")
+   S_(SECCLASS_XSERVER, XSERVER__GRAB, "grab")
+   S_(SECCLASS_XSERVER, XSERVER__UNGRAB, "ungrab")
+   S_(SECCLASS_XEXTENSION, XEXTENSION__QUERY, "query")
+   S_(SECCLASS_XEXTENSION, XEXTENSION__USE, "use")
+   S_(SECCLASS_PAX, PAX__PAGEEXEC, "pageexec")
+   S_(SECCLASS_PAX, PAX__EMUTRAMP, "emutramp")
+   S_(SECCLASS_PAX, PAX__MPROTECT, "mprotect")
+   S_(SECCLASS_PAX, PAX__RANDMMAP, "randmmap")
+   S_(SECCLASS_PAX, PAX__RANDEXEC, "randexec")
+   S_(SECCLASS_PAX, PAX__SEGMEXEC, "segmexec")
+   S_(SECCLASS_NETLINK_ROUTE_SOCKET, NETLINK_ROUTE_SOCKET__NLMSG_READ, "nlmsg_read")
+   S_(SECCLASS_NETLINK_ROUTE_SOCKET, NETLINK_ROUTE_SOCKET__NLMSG_WRITE, "nlmsg_write")
+   S_(SECCLASS_NETLINK_FIREWALL_SOCKET, NETLINK_FIREWALL_SOCKET__NLMSG_READ, "nlmsg_read")
+   S_(SECCLASS_NETLINK_FIREWALL_SOCKET, NETLINK_FIREWALL_SOCKET__NLMSG_WRITE, "nlmsg_write")
+   S_(SECCLASS_NETLINK_TCPDIAG_SOCKET, NETLINK_TCPDIAG_SOCKET__NLMSG_READ, "nlmsg_read")
+   S_(SECCLASS_NETLINK_TCPDIAG_SOCKET, NETLINK_TCPDIAG_SOCKET__NLMSG_WRITE, "nlmsg_write")
+   S_(SECCLASS_NETLINK_XFRM_SOCKET, NETLINK_XFRM_SOCKET__NLMSG_READ, "nlmsg_read")
+   S_(SECCLASS_NETLINK_XFRM_SOCKET, NETLINK_XFRM_SOCKET__NLMSG_WRITE, "nlmsg_write")
+   S_(SECCLASS_NETLINK_AUDIT_SOCKET, NETLINK_AUDIT_SOCKET__NLMSG_READ, "nlmsg_read")
+   S_(SECCLASS_NETLINK_AUDIT_SOCKET, NETLINK_AUDIT_SOCKET__NLMSG_WRITE, "nlmsg_write")
+   S_(SECCLASS_NETLINK_IP6FW_SOCKET, NETLINK_IP6FW_SOCKET__NLMSG_READ, "nlmsg_read")
+   S_(SECCLASS_NETLINK_IP6FW_SOCKET, NETLINK_IP6FW_SOCKET__NLMSG_WRITE, "nlmsg_write")
+   S_(SECCLASS_DBUS, DBUS__ACQUIRE_SVC, "acquire_svc")
+   S_(SECCLASS_DBUS, DBUS__SEND_MSG, "send_msg")
+   S_(SECCLASS_NSCD, NSCD__GETPWD, "getpwd")
+   S_(SECCLASS_NSCD, NSCD__GETGRP, "getgrp")
+   S_(SECCLASS_NSCD, NSCD__GETHOST, "gethost")
+   S_(SECCLASS_NSCD, NSCD__GETSTAT, "getstat")
+   S_(SECCLASS_NSCD, NSCD__ADMIN, "admin")
+   S_(SECCLASS_NSCD, NSCD__SHMEMPWD, "shmempwd")
+   S_(SECCLASS_NSCD, NSCD__SHMEMGRP, "shmemgrp")
+   S_(SECCLASS_NSCD, NSCD__SHMEMHOST, "shmemhost")
diff -Nru a/security/selinux/include/av_permissions.h b/security/selinux/include/av_permissions.h
--- a/security/selinux/include/av_permissions.h	2005-03-01 23:39:18 -08:00
+++ b/security/selinux/include/av_permissions.h	2005-03-01 23:39:18 -08:00
@@ -1,6 +1,4 @@
 /* This file is automatically generated.  Do not edit. */
-/* FLASK */
-
 #define COMMON_FILE__IOCTL                               0x00000001UL
 #define COMMON_FILE__READ                                0x00000002UL
 #define COMMON_FILE__WRITE                               0x00000004UL
@@ -107,6 +105,7 @@
 
 #define FILE__EXECUTE_NO_TRANS                    0x00020000UL
 #define FILE__ENTRYPOINT                          0x00040000UL
+#define FILE__EXECMOD                             0x00080000UL
 
 #define LNK_FILE__IOCTL                           0x00000001UL
 #define LNK_FILE__READ                            0x00000002UL
@@ -144,6 +143,10 @@
 #define CHR_FILE__QUOTAON                         0x00008000UL
 #define CHR_FILE__MOUNTON                         0x00010000UL
 
+#define CHR_FILE__EXECUTE_NO_TRANS                0x00020000UL
+#define CHR_FILE__ENTRYPOINT                      0x00040000UL
+#define CHR_FILE__EXECMOD                         0x00080000UL
+
 #define BLK_FILE__IOCTL                           0x00000001UL
 #define BLK_FILE__READ                            0x00000002UL
 #define BLK_FILE__WRITE                           0x00000004UL
@@ -458,6 +461,9 @@
 #define PROCESS__SIGINH                           0x00100000UL
 #define PROCESS__SETRLIMIT                        0x00200000UL
 #define PROCESS__RLIMITINH                        0x00400000UL
+#define PROCESS__DYNTRANSITION                    0x00800000UL
+#define PROCESS__SETCURRENT                       0x01000000UL
+#define PROCESS__EXECMEM                          0x02000000UL
 
 #define IPC__CREATE                               0x00000001UL
 #define IPC__DESTROY                              0x00000002UL
@@ -515,6 +521,7 @@
 #define SECURITY__COMPUTE_USER                    0x00000040UL
 #define SECURITY__SETENFORCE                      0x00000080UL
 #define SECURITY__SETBOOL                         0x00000100UL
+#define SECURITY__SETSECPARAM                     0x00000200UL
 
 #define SYSTEM__IPC_INFO                          0x00000001UL
 #define SYSTEM__SYSLOG_READ                       0x00000002UL
@@ -555,6 +562,7 @@
 #define PASSWD__CHFN                              0x00000002UL
 #define PASSWD__CHSH                              0x00000004UL
 #define PASSWD__ROOTOK                            0x00000008UL
+#define PASSWD__CRONTAB                           0x00000010UL
 
 #define DRAWABLE__CREATE                          0x00000001UL
 #define DRAWABLE__DESTROY                         0x00000002UL
@@ -876,5 +884,17 @@
 #define NETLINK_DNRT_SOCKET__SENDTO               0x00040000UL
 #define NETLINK_DNRT_SOCKET__RECV_MSG             0x00080000UL
 #define NETLINK_DNRT_SOCKET__SEND_MSG             0x00100000UL
+#define NETLINK_DNRT_SOCKET__NAME_BIND            0x00200000UL
+
+#define DBUS__ACQUIRE_SVC                         0x00000001UL
+#define DBUS__SEND_MSG                            0x00000002UL
+
+#define NSCD__GETPWD                              0x00000001UL
+#define NSCD__GETGRP                              0x00000002UL
+#define NSCD__GETHOST                             0x00000004UL
+#define NSCD__GETSTAT                             0x00000008UL
+#define NSCD__ADMIN                               0x00000010UL
+#define NSCD__SHMEMPWD                            0x00000020UL
+#define NSCD__SHMEMGRP                            0x00000040UL
+#define NSCD__SHMEMHOST                           0x00000080UL
 
-/* FLASK */
diff -Nru a/security/selinux/include/avc.h b/security/selinux/include/avc.h
--- a/security/selinux/include/avc.h	2005-03-01 23:38:53 -08:00
+++ b/security/selinux/include/avc.h	2005-03-01 23:38:53 -08:00
@@ -29,19 +29,6 @@
  */
 struct avc_entry;
 
-/*
- * A reference to an AVC entry.
- */
-struct avc_entry_ref {
-	struct avc_entry *ae;
-};
-
-/* Initialize an AVC entry reference before first use. */
-static inline void avc_entry_ref_init(struct avc_entry_ref *h)
-{
-	h->ae = NULL;
-}
-
 struct task_struct;
 struct vfsmount;
 struct dentry;
@@ -95,15 +82,15 @@
 /*
  * AVC statistics
  */
-#define AVC_ENTRY_LOOKUPS        0
-#define AVC_ENTRY_HITS	         1
-#define AVC_ENTRY_MISSES         2
-#define AVC_ENTRY_DISCARDS       3
-#define AVC_CAV_LOOKUPS          4
-#define AVC_CAV_HITS             5
-#define AVC_CAV_PROBES           6
-#define AVC_CAV_MISSES           7
-#define AVC_NSTATS               8
+struct avc_cache_stats
+{
+	unsigned int lookups;
+	unsigned int hits;
+	unsigned int misses;
+	unsigned int allocations;
+	unsigned int reclaims;
+	unsigned int frees;
+};
 
 /*
  * AVC display support
@@ -118,23 +105,17 @@
 
 void __init avc_init(void);
 
-int avc_lookup(u32 ssid, u32 tsid, u16 tclass,
-               u32 requested, struct avc_entry_ref *aeref);
-
-int avc_insert(u32 ssid, u32 tsid, u16 tclass,
-               struct avc_entry *ae, struct avc_entry_ref *out_aeref);
-
 void avc_audit(u32 ssid, u32 tsid,
                u16 tclass, u32 requested,
                struct av_decision *avd, int result, struct avc_audit_data *auditdata);
 
 int avc_has_perm_noaudit(u32 ssid, u32 tsid,
                          u16 tclass, u32 requested,
-                         struct avc_entry_ref *aeref, struct av_decision *avd);
+                         struct av_decision *avd);
 
 int avc_has_perm(u32 ssid, u32 tsid,
                  u16 tclass, u32 requested,
-                 struct avc_entry_ref *aeref, struct avc_audit_data *auditdata);
+                 struct avc_audit_data *auditdata);
 
 #define AVC_CALLBACK_GRANT		1
 #define AVC_CALLBACK_TRY_REVOKE		2
@@ -150,6 +131,14 @@
 				     u32 *out_retained),
 		     u32 events, u32 ssid, u32 tsid,
 		     u16 tclass, u32 perms);
+
+/* Exported to selinuxfs */
+int avc_get_hash_stats(char *page);
+extern unsigned int avc_cache_threshold;
+
+#ifdef CONFIG_SECURITY_SELINUX_AVC_STATS
+DECLARE_PER_CPU(struct avc_cache_stats, avc_cache_stats);
+#endif
 
 #endif /* _SELINUX_AVC_H_ */
 
diff -Nru a/security/selinux/include/class_to_string.h b/security/selinux/include/class_to_string.h
--- a/security/selinux/include/class_to_string.h	2005-03-01 23:39:18 -08:00
+++ b/security/selinux/include/class_to_string.h	2005-03-01 23:39:18 -08:00
@@ -2,59 +2,57 @@
 /*
  * Security object class definitions
  */
-static char *class_to_string[] =
-{
-    "null",
-    "security",
-    "process",
-    "system",
-    "capability",
-    "filesystem",
-    "file",
-    "dir",
-    "fd",
-    "lnk_file",
-    "chr_file",
-    "blk_file",
-    "sock_file",
-    "fifo_file",
-    "socket",
-    "tcp_socket",
-    "udp_socket",
-    "rawip_socket",
-    "node",
-    "netif",
-    "netlink_socket",
-    "packet_socket",
-    "key_socket",
-    "unix_stream_socket",
-    "unix_dgram_socket",
-    "sem",
-    "msg",
-    "msgq",
-    "shm",
-    "ipc",
-    "passwd",
-    "drawable",
-    "window",
-    "gc",
-    "font",
-    "colormap",
-    "property",
-    "cursor",
-    "xclient",
-    "xinput",
-    "xserver",
-    "xextension",
-    "pax",
-    "netlink_route_socket",
-    "netlink_firewall_socket",
-    "netlink_tcpdiag_socket",
-    "netlink_nflog_socket",
-    "netlink_xfrm_socket",
-    "netlink_selinux_socket",
-    "netlink_audit_socket",
-    "netlink_ip6fw_socket",
-    "netlink_dnrt_socket",
-};
-
+    S_("null")
+    S_("security")
+    S_("process")
+    S_("system")
+    S_("capability")
+    S_("filesystem")
+    S_("file")
+    S_("dir")
+    S_("fd")
+    S_("lnk_file")
+    S_("chr_file")
+    S_("blk_file")
+    S_("sock_file")
+    S_("fifo_file")
+    S_("socket")
+    S_("tcp_socket")
+    S_("udp_socket")
+    S_("rawip_socket")
+    S_("node")
+    S_("netif")
+    S_("netlink_socket")
+    S_("packet_socket")
+    S_("key_socket")
+    S_("unix_stream_socket")
+    S_("unix_dgram_socket")
+    S_("sem")
+    S_("msg")
+    S_("msgq")
+    S_("shm")
+    S_("ipc")
+    S_("passwd")
+    S_("drawable")
+    S_("window")
+    S_("gc")
+    S_("font")
+    S_("colormap")
+    S_("property")
+    S_("cursor")
+    S_("xclient")
+    S_("xinput")
+    S_("xserver")
+    S_("xextension")
+    S_("pax")
+    S_("netlink_route_socket")
+    S_("netlink_firewall_socket")
+    S_("netlink_tcpdiag_socket")
+    S_("netlink_nflog_socket")
+    S_("netlink_xfrm_socket")
+    S_("netlink_selinux_socket")
+    S_("netlink_audit_socket")
+    S_("netlink_ip6fw_socket")
+    S_("netlink_dnrt_socket")
+    S_("dbus")
+    S_("nscd")
diff -Nru a/security/selinux/include/common_perm_to_string.h b/security/selinux/include/common_perm_to_string.h
--- a/security/selinux/include/common_perm_to_string.h	2005-03-01 23:38:55 -08:00
+++ b/security/selinux/include/common_perm_to_string.h	2005-03-01 23:38:55 -08:00
@@ -1,65 +1,58 @@
 /* This file is automatically generated.  Do not edit. */
-/* FLASK */
+TB_(common_file_perm_to_string)
+    S_("ioctl")
+    S_("read")
+    S_("write")
+    S_("create")
+    S_("getattr")
+    S_("setattr")
+    S_("lock")
+    S_("relabelfrom")
+    S_("relabelto")
+    S_("append")
+    S_("unlink")
+    S_("link")
+    S_("rename")
+    S_("execute")
+    S_("swapon")
+    S_("quotaon")
+    S_("mounton")
+TE_(common_file_perm_to_string)
 
-static char *common_file_perm_to_string[] =
-{
-    "ioctl",
-    "read",
-    "write",
-    "create",
-    "getattr",
-    "setattr",
-    "lock",
-    "relabelfrom",
-    "relabelto",
-    "append",
-    "unlink",
-    "link",
-    "rename",
-    "execute",
-    "swapon",
-    "quotaon",
-    "mounton",
-};
+TB_(common_socket_perm_to_string)
+    S_("ioctl")
+    S_("read")
+    S_("write")
+    S_("create")
+    S_("getattr")
+    S_("setattr")
+    S_("lock")
+    S_("relabelfrom")
+    S_("relabelto")
+    S_("append")
+    S_("bind")
+    S_("connect")
+    S_("listen")
+    S_("accept")
+    S_("getopt")
+    S_("setopt")
+    S_("shutdown")
+    S_("recvfrom")
+    S_("sendto")
+    S_("recv_msg")
+    S_("send_msg")
+    S_("name_bind")
+TE_(common_socket_perm_to_string)
 
-static char *common_socket_perm_to_string[] =
-{
-    "ioctl",
-    "read",
-    "write",
-    "create",
-    "getattr",
-    "setattr",
-    "lock",
-    "relabelfrom",
-    "relabelto",
-    "append",
-    "bind",
-    "connect",
-    "listen",
-    "accept",
-    "getopt",
-    "setopt",
-    "shutdown",
-    "recvfrom",
-    "sendto",
-    "recv_msg",
-    "send_msg",
-    "name_bind",
-};
+TB_(common_ipc_perm_to_string)
+    S_("create")
+    S_("destroy")
+    S_("getattr")
+    S_("setattr")
+    S_("read")
+    S_("write")
+    S_("associate")
+    S_("unix_read")
+    S_("unix_write")
+TE_(common_ipc_perm_to_string)
 
-static char *common_ipc_perm_to_string[] =
-{
-    "create",
-    "destroy",
-    "getattr",
-    "setattr",
-    "read",
-    "write",
-    "associate",
-    "unix_read",
-    "unix_write",
-};
-
-
-/* FLASK */
diff -Nru a/security/selinux/include/flask.h b/security/selinux/include/flask.h
--- a/security/selinux/include/flask.h	2005-03-01 23:39:07 -08:00
+++ b/security/selinux/include/flask.h	2005-03-01 23:39:07 -08:00
@@ -56,6 +56,8 @@
 #define SECCLASS_NETLINK_AUDIT_SOCKET                    49
 #define SECCLASS_NETLINK_IP6FW_SOCKET                    50
 #define SECCLASS_NETLINK_DNRT_SOCKET                     51
+#define SECCLASS_DBUS                                    52
+#define SECCLASS_NSCD                                    53
 
 /*
  * Security identifier indices for initial entities
diff -Nru a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h
--- a/security/selinux/include/objsec.h	2005-03-01 23:38:56 -08:00
+++ b/security/selinux/include/objsec.h	2005-03-01 23:38:56 -08:00
@@ -33,7 +33,6 @@
 	u32 sid;             /* current SID */
 	u32 exec_sid;        /* exec SID */
 	u32 create_sid;      /* fscreate SID */
-        struct avc_entry_ref avcr;     /* reference to process permissions */
 	u32 ptrace_sid;      /* SID of ptrace parent */
 };
 
@@ -44,7 +43,6 @@
 	u32 task_sid;        /* SID of creating task */
 	u32 sid;             /* SID of this object */
 	u16 sclass;       /* security class of this object */
-	struct avc_entry_ref avcr;     /* reference to object permissions */
 	unsigned char initialized;     /* initialization flag */
 	struct semaphore sem;
 	unsigned char inherit;         /* inherit SID from parent entry */
@@ -55,8 +53,6 @@
 	struct file *file;              /* back pointer to file object */
 	u32 sid;              /* SID of open file description */
 	u32 fown_sid;         /* SID of file owner (for SIGIO) */
-	struct avc_entry_ref avcr;	/* reference to fd permissions */
-	struct avc_entry_ref inode_avcr;     /* reference to object permissions */
 };
 
 struct superblock_security_struct {
@@ -77,7 +73,6 @@
         unsigned long magic;		/* magic number for this module */
 	struct msg_msg *msg;		/* back pointer */
 	u32 sid;              /* SID of message */
-        struct avc_entry_ref avcr;	/* reference to permissions */
 };
 
 struct ipc_security_struct {
@@ -85,7 +80,6 @@
 	struct kern_ipc_perm *ipc_perm; /* back pointer */
 	u16 sclass;	/* security class of this object */
 	u32 sid;              /* SID of IPC resource */
-        struct avc_entry_ref avcr;	/* reference to permissions */
 };
 
 struct bprm_security_struct {
@@ -93,6 +87,12 @@
 	struct linux_binprm *bprm;     /* back pointer to bprm object */
 	u32 sid;                       /* SID for transformed process */
 	unsigned char set;
+
+	/*
+	 * unsafe is used to share failure information from bprm_apply_creds()
+	 * to bprm_post_apply_creds().
+	 */
+	char unsafe;
 };
 
 struct netif_security_struct {
diff -Nru a/security/selinux/netif.c b/security/selinux/netif.c
--- a/security/selinux/netif.c	2005-03-01 23:38:57 -08:00
+++ b/security/selinux/netif.c	2005-03-01 23:38:57 -08:00
@@ -45,7 +45,7 @@
 
 static u32 sel_netif_total;
 static LIST_HEAD(sel_netif_list);
-static spinlock_t sel_netif_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(sel_netif_lock);
 static struct list_head sel_netif_hash[SEL_NETIF_HASH_SIZE];
 
 static inline u32 sel_netif_hasfn(struct net_device *dev)
diff -Nru a/security/selinux/nlmsgtab.c b/security/selinux/nlmsgtab.c
--- a/security/selinux/nlmsgtab.c	2005-03-01 23:39:09 -08:00
+++ b/security/selinux/nlmsgtab.c	2005-03-01 23:39:09 -08:00
@@ -56,6 +56,9 @@
 	{ RTM_NEWTFILTER,	NETLINK_ROUTE_SOCKET__NLMSG_WRITE },
 	{ RTM_DELTFILTER,	NETLINK_ROUTE_SOCKET__NLMSG_WRITE },
 	{ RTM_GETTFILTER,	NETLINK_ROUTE_SOCKET__NLMSG_READ  },
+	{ RTM_NEWACTION,	NETLINK_ROUTE_SOCKET__NLMSG_WRITE },
+	{ RTM_DELACTION,	NETLINK_ROUTE_SOCKET__NLMSG_WRITE },
+	{ RTM_GETACTION,	NETLINK_ROUTE_SOCKET__NLMSG_READ  },
 	{ RTM_NEWPREFIX,	NETLINK_ROUTE_SOCKET__NLMSG_WRITE },
 	{ RTM_GETPREFIX,	NETLINK_ROUTE_SOCKET__NLMSG_READ  },
 	{ RTM_GETMULTICAST,	NETLINK_ROUTE_SOCKET__NLMSG_READ  },
diff -Nru a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
--- a/security/selinux/selinuxfs.c	2005-03-01 23:39:18 -08:00
+++ b/security/selinux/selinuxfs.c	2005-03-01 23:39:18 -08:00
@@ -3,6 +3,7 @@
  * 	Added conditional policy language extensions
  *
  * Copyright (C) 2003 - 2004 Tresys Technology, LLC
+ * Copyright (C) 2004 Red Hat, Inc., James Morris <jmorris@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, version 2.
@@ -18,6 +19,8 @@
 #include <linux/string.h>
 #include <linux/security.h>
 #include <linux/major.h>
+#include <linux/seq_file.h>
+#include <linux/percpu.h>
 #include <asm/uaccess.h>
 #include <asm/semaphore.h>
 
@@ -51,7 +54,7 @@
 		return -EACCES;
 
 	return avc_has_perm(tsec->sid, SECINITSID_SECURITY,
-			    SECCLASS_SECURITY, perms, NULL, NULL);
+			    SECCLASS_SECURITY, perms, NULL);
 }
 
 enum sel_inos {
@@ -66,7 +69,9 @@
 	SEL_POLICYVERS,	/* return policy version for this kernel */
 	SEL_COMMIT_BOOLS, /* commit new boolean values */
 	SEL_MLS,	/* return if MLS policy is enabled */
-	SEL_DISABLE	/* disable SELinux until next reboot */
+	SEL_DISABLE,	/* disable SELinux until next reboot */
+	SEL_AVC,	/* AVC management directory */
+	SEL_MEMBER,	/* compute polyinstantiation membership decision */
 };
 
 #define TMPBUFLEN	12
@@ -303,12 +308,14 @@
 static ssize_t sel_write_create(struct file * file, char *buf, size_t size);
 static ssize_t sel_write_relabel(struct file * file, char *buf, size_t size);
 static ssize_t sel_write_user(struct file * file, char *buf, size_t size);
+static ssize_t sel_write_member(struct file * file, char *buf, size_t size);
 
 static ssize_t (*write_op[])(struct file *, char *, size_t) = {
 	[SEL_ACCESS] = sel_write_access,
 	[SEL_CREATE] = sel_write_create,
 	[SEL_RELABEL] = sel_write_relabel,
 	[SEL_USER] = sel_write_user,
+	[SEL_MEMBER] = sel_write_member,
 };
 
 static ssize_t selinux_transaction_write(struct file *file, const char __user *buf, size_t size, loff_t *pos)
@@ -578,6 +585,67 @@
 	return length;
 }
 
+static ssize_t sel_write_member(struct file * file, char *buf, size_t size)
+{
+	char *scon, *tcon;
+	u32 ssid, tsid, newsid;
+	u16 tclass;
+	ssize_t length;
+	char *newcon;
+	u32 len;
+
+	length = task_has_security(current, SECURITY__COMPUTE_MEMBER);
+	if (length)
+		return length;
+
+	length = -ENOMEM;
+	scon = kmalloc(size+1, GFP_KERNEL);
+	if (!scon)
+		return length;
+	memset(scon, 0, size+1);
+
+	tcon = kmalloc(size+1, GFP_KERNEL);
+	if (!tcon)
+		goto out;
+	memset(tcon, 0, size+1);
+
+	length = -EINVAL;
+	if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
+		goto out2;
+
+	length = security_context_to_sid(scon, strlen(scon)+1, &ssid);
+	if (length < 0)
+		goto out2;
+	length = security_context_to_sid(tcon, strlen(tcon)+1, &tsid);
+	if (length < 0)
+		goto out2;
+
+	length = security_member_sid(ssid, tsid, tclass, &newsid);
+	if (length < 0)
+		goto out2;
+
+	length = security_sid_to_context(newsid, &newcon, &len);
+	if (length < 0)
+		goto out2;
+
+	if (len > SIMPLE_TRANSACTION_LIMIT) {
+		printk(KERN_ERR "%s:  context size (%u) exceeds payload "
+		       "max\n", __FUNCTION__, len);
+		length = -ERANGE;
+		goto out3;
+	}
+
+	memcpy(buf, newcon, len);
+	length = len;
+out3:
+	kfree(newcon);
+out2:
+	kfree(tcon);
+out:
+	kfree(scon);
+	return length;
+}
+
 static struct inode *sel_make_inode(struct super_block *sb, int mode)
 {
 	struct inode *ret = new_inode(sb);
@@ -887,6 +955,213 @@
 
 struct dentry *selinux_null = NULL;
 
+static ssize_t sel_read_avc_cache_threshold(struct file *filp, char __user *buf,
+					    size_t count, loff_t *ppos)
+{
+	char tmpbuf[TMPBUFLEN];
+	ssize_t length;
+
+	length = scnprintf(tmpbuf, TMPBUFLEN, "%u", avc_cache_threshold);
+	return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
+}
+
+static ssize_t sel_write_avc_cache_threshold(struct file * file,
+					     const char __user * buf,
+					     size_t count, loff_t *ppos)
+
+{
+	char *page;
+	ssize_t ret;
+	int new_value;
+
+	if (count < 0 || count >= PAGE_SIZE) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	if (*ppos != 0) {
+		/* No partial writes. */
+		ret = -EINVAL;
+		goto out;
+	}
+
+	page = (char*)get_zeroed_page(GFP_KERNEL);
+	if (!page) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	if (copy_from_user(page, buf, count)) {
+		ret = -EFAULT;
+		goto out_free;
+	}
+
+	if (sscanf(page, "%u", &new_value) != 1) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if (new_value != avc_cache_threshold) {
+		ret = task_has_security(current, SECURITY__SETSECPARAM);
+		if (ret)
+			goto out_free;
+		avc_cache_threshold = new_value;
+	}
+	ret = count;
+out_free:
+	free_page((unsigned long)page);
+out:
+	return ret;
+}
+
+static ssize_t sel_read_avc_hash_stats(struct file *filp, char __user *buf,
+				       size_t count, loff_t *ppos)
+{
+	char *page;
+	ssize_t ret = 0;
+
+	page = (char *)__get_free_page(GFP_KERNEL);
+	if (!page) {
+		ret = -ENOMEM;
+		goto out;
+	}
+	ret = avc_get_hash_stats(page);
+	if (ret >= 0)
+		ret = simple_read_from_buffer(buf, count, ppos, page, ret);
+	free_page((unsigned long)page);
+out:
+	return ret;
+}
+
+static struct file_operations sel_avc_cache_threshold_ops = {
+	.read		= sel_read_avc_cache_threshold,
+	.write		= sel_write_avc_cache_threshold,
+};
+
+static struct file_operations sel_avc_hash_stats_ops = {
+	.read		= sel_read_avc_hash_stats,
+};
+
+#ifdef CONFIG_SECURITY_SELINUX_AVC_STATS
+static struct avc_cache_stats *sel_avc_get_stat_idx(loff_t *idx)
+{
+	int cpu;
+
+	for (cpu = *idx; cpu < NR_CPUS; ++cpu) {
+		if (!cpu_possible(cpu))
+			continue;
+		*idx = cpu + 1;
+		return &per_cpu(avc_cache_stats, cpu);
+	}
+	return NULL;
+}
+
+static void *sel_avc_stats_seq_start(struct seq_file *seq, loff_t *pos)
+{
+	loff_t n = *pos - 1;
+
+	if (*pos == 0)
+		return SEQ_START_TOKEN;
+
+	return sel_avc_get_stat_idx(&n);
+}
+
+static void *sel_avc_stats_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+	return sel_avc_get_stat_idx(pos);
+}
+
+static int sel_avc_stats_seq_show(struct seq_file *seq, void *v)
+{
+	struct avc_cache_stats *st = v;
+
+	if (v == SEQ_START_TOKEN)
+		seq_printf(seq, "lookups hits misses allocations reclaims "
+			   "frees\n");
+	else
+		seq_printf(seq, "%u %u %u %u %u %u\n", st->lookups,
+			   st->hits, st->misses, st->allocations,
+			   st->reclaims, st->frees);
+	return 0;
+}
+
+static void sel_avc_stats_seq_stop(struct seq_file *seq, void *v)
+{ }
+
+static struct seq_operations sel_avc_cache_stats_seq_ops = {
+	.start		= sel_avc_stats_seq_start,
+	.next		= sel_avc_stats_seq_next,
+	.show		= sel_avc_stats_seq_show,
+	.stop		= sel_avc_stats_seq_stop,
+};
+
+static int sel_open_avc_cache_stats(struct inode *inode, struct file *file)
+{
+	return seq_open(file, &sel_avc_cache_stats_seq_ops);
+}
+
+static struct file_operations sel_avc_cache_stats_ops = {
+	.open		= sel_open_avc_cache_stats,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= seq_release,
+};
+#endif
+
+static int sel_make_avc_files(struct dentry *dir)
+{
+	int i, ret = 0;
+	static struct tree_descr files[] = {
+		{ "cache_threshold",
+		  &sel_avc_cache_threshold_ops, S_IRUGO|S_IWUSR },
+		{ "hash_stats", &sel_avc_hash_stats_ops, S_IRUGO },
+#ifdef CONFIG_SECURITY_SELINUX_AVC_STATS
+		{ "cache_stats", &sel_avc_cache_stats_ops, S_IRUGO },
+#endif
+	};
+
+	for (i = 0; i < sizeof (files) / sizeof (files[0]); i++) {
+		struct inode *inode;
+		struct dentry *dentry;
+
+		dentry = d_alloc_name(dir, files[i].name);
+		if (!dentry) {
+			ret = -ENOMEM;
+			goto err;
+		}
+
+		inode = sel_make_inode(dir->d_sb, S_IFREG|files[i].mode);
+		if (!inode) {
+			ret = -ENOMEM;
+			goto err;
+		}
+		inode->i_fop = files[i].ops;
+		d_add(dentry, inode);
+	}
+out:
+	return ret;
+err:
+	d_genocide(dir);
+	goto out;
+}
+
+static int sel_make_dir(struct super_block *sb, struct dentry *dentry)
+{
+	int ret = 0;
+	struct inode *inode;
+
+	inode = sel_make_inode(sb, S_IFDIR | S_IRUGO | S_IXUGO);
+	if (!inode) {
+		ret = -ENOMEM;
+		goto out;
+	}
+	inode->i_op = &simple_dir_inode_operations;
+	inode->i_fop = &simple_dir_operations;
+	d_add(dentry, inode);
+out:
+	return ret;
+}
+
 static int sel_fill_super(struct super_block * sb, void * data, int silent)
 {
 	int ret;
@@ -906,6 +1181,7 @@
 		[SEL_COMMIT_BOOLS] = {"commit_pending_bools", &sel_commit_bools_ops, S_IWUSR},
 		[SEL_MLS] = {"mls", &sel_mls_ops, S_IRUGO},
 		[SEL_DISABLE] = {"disable", &sel_disable_ops, S_IWUSR},
+		[SEL_MEMBER] = {"member", &transaction_ops, S_IRUGO|S_IWUGO},
 		/* last one */ {""}
 	};
 	ret = simple_fill_super(sb, SELINUX_MAGIC, selinux_files);
@@ -942,6 +1218,18 @@
 	init_special_inode(inode, S_IFCHR | S_IRUGO | S_IWUGO, MKDEV(MEM_MAJOR, 3));
 	d_add(dentry, inode);
 	selinux_null = dentry;
+
+	dentry = d_alloc_name(sb->s_root, "avc");
+	if (!dentry)
+		return -ENOMEM;
+
+	ret = sel_make_dir(sb, dentry);
+	if (ret)
+		goto out;
+
+	ret = sel_make_avc_files(dentry);
+	if (ret)
+		goto out;
 
 	return 0;
 out:
diff -Nru a/security/selinux/ss/avtab.c b/security/selinux/ss/avtab.c
--- a/security/selinux/ss/avtab.c	2005-03-01 23:39:08 -08:00
+++ b/security/selinux/ss/avtab.c	2005-03-01 23:39:08 -08:00
@@ -303,20 +303,25 @@
 
 int avtab_read_item(void *fp, struct avtab_datum *avdatum, struct avtab_key *avkey)
 {
-	__u32 *buf;
-	__u32 items, items2;
+	u32 buf[7];
+	u32 items, items2;
+	int rc;
 
 	memset(avkey, 0, sizeof(struct avtab_key));
 	memset(avdatum, 0, sizeof(struct avtab_datum));
 
-	buf = next_entry(fp, sizeof(__u32));
-	if (!buf) {
+	rc = next_entry(buf, fp, sizeof(u32));
+	if (rc < 0) {
 		printk(KERN_ERR "security: avtab: truncated entry\n");
 		goto bad;
 	}
 	items2 = le32_to_cpu(buf[0]);
-	buf = next_entry(fp, sizeof(__u32)*items2);
-	if (!buf) {
+	if (items2 > ARRAY_SIZE(buf)) {
+		printk(KERN_ERR "security: avtab: entry overflow\n");
+		goto bad;
+	}
+	rc = next_entry(buf, fp, sizeof(u32)*items2);
+	if (rc < 0) {
 		printk(KERN_ERR "security: avtab: truncated entry\n");
 		goto bad;
 	}
@@ -362,26 +367,29 @@
 
 int avtab_read(struct avtab *a, void *fp, u32 config)
 {
-	int i, rc = -EINVAL;
+	int rc;
 	struct avtab_key avkey;
 	struct avtab_datum avdatum;
-	u32 *buf;
-	u32 nel;
+	u32 buf[1];
+	u32 nel, i;
 
 
-	buf = next_entry(fp, sizeof(u32));
-	if (!buf) {
+	rc = next_entry(buf, fp, sizeof(u32));
+	if (rc < 0) {
 		printk(KERN_ERR "security: avtab: truncated table\n");
 		goto bad;
 	}
 	nel = le32_to_cpu(buf[0]);
 	if (!nel) {
 		printk(KERN_ERR "security: avtab: table is empty\n");
+		rc = -EINVAL;
 		goto bad;
 	}
 	for (i = 0; i < nel; i++) {
-		if (avtab_read_item(fp, &avdatum, &avkey))
+		if (avtab_read_item(fp, &avdatum, &avkey)) {
+			rc = -EINVAL;
 			goto bad;
+		}
 		rc = avtab_insert(a, &avkey, &avdatum);
 		if (rc) {
 			if (rc == -ENOMEM)
diff -Nru a/security/selinux/ss/conditional.c b/security/selinux/ss/conditional.c
--- a/security/selinux/ss/conditional.c	2005-03-01 23:38:53 -08:00
+++ b/security/selinux/ss/conditional.c	2005-03-01 23:38:53 -08:00
@@ -219,15 +219,16 @@
 {
 	char *key = NULL;
 	struct cond_bool_datum *booldatum;
-	__u32 *buf, len;
+	u32 buf[3], len;
+	int rc;
 
 	booldatum = kmalloc(sizeof(struct cond_bool_datum), GFP_KERNEL);
 	if (!booldatum)
 		return -1;
 	memset(booldatum, 0, sizeof(struct cond_bool_datum));
 
-	buf = next_entry(fp, sizeof(__u32) * 3);
-	if (!buf)
+	rc = next_entry(buf, fp, sizeof buf);
+	if (rc < 0)
 		goto err;
 
 	booldatum->value = le32_to_cpu(buf[0]);
@@ -238,13 +239,12 @@
 
 	len = le32_to_cpu(buf[2]);
 
-	buf = next_entry(fp, len);
-	if (!buf)
-		goto err;
 	key = kmalloc(len + 1, GFP_KERNEL);
 	if (!key)
 		goto err;
-	memcpy(key, buf, len);
+	rc = next_entry(key, fp, len);
+	if (rc < 0)
+		goto err;
 	key[len] = 0;
 	if (hashtab_insert(h, key, booldatum))
 		goto err;
@@ -262,15 +262,15 @@
 	struct avtab_key key;
 	struct avtab_datum datum;
 	struct avtab_node *node_ptr;
-	int len, i;
-	__u32 *buf;
-	__u8 found;
+	int rc;
+	u32 buf[1], i, len;
+	u8 found;
 
 	*ret_list = NULL;
 
 	len = 0;
-	buf = next_entry(fp, sizeof(__u32));
-	if (!buf)
+	rc = next_entry(buf, fp, sizeof buf);
+	if (rc < 0)
 		return -1;
 
 	len = le32_to_cpu(buf[0]);
@@ -369,27 +369,27 @@
 
 static int cond_read_node(struct policydb *p, struct cond_node *node, void *fp)
 {
-	__u32 *buf;
-	int len, i;
+	u32 buf[2], len, i;
+	int rc;
 	struct cond_expr *expr = NULL, *last = NULL;
 
-	buf = next_entry(fp, sizeof(__u32));
-	if (!buf)
+	rc = next_entry(buf, fp, sizeof(u32));
+	if (rc < 0)
 		return -1;
 
 	node->cur_state = le32_to_cpu(buf[0]);
 
 	len = 0;
-	buf = next_entry(fp, sizeof(__u32));
-	if (!buf)
+	rc = next_entry(buf, fp, sizeof(u32));
+	if (rc < 0)
 		return -1;
 
 	/* expr */
 	len = le32_to_cpu(buf[0]);
 
 	for (i = 0; i < len; i++ ) {
-		buf = next_entry(fp, sizeof(__u32) * 2);
-		if (!buf)
+		rc = next_entry(buf, fp, sizeof(u32) * 2);
+		if (rc < 0)
 			goto err;
 
 		expr = kmalloc(sizeof(struct cond_expr), GFP_KERNEL);
@@ -401,8 +401,10 @@
 		expr->expr_type = le32_to_cpu(buf[0]);
 		expr->bool = le32_to_cpu(buf[1]);
 
-		if (!expr_isvalid(p, expr))
+		if (!expr_isvalid(p, expr)) {
+			kfree(expr);
 			goto err;
+		}
 
 		if (i == 0) {
 			node->expr = expr;
@@ -425,11 +427,11 @@
 int cond_read_list(struct policydb *p, void *fp)
 {
 	struct cond_node *node, *last = NULL;
-	__u32 *buf;
-	int i, len;
+	u32 buf[1], i, len;
+	int rc;
 
-	buf = next_entry(fp, sizeof(__u32));
-	if (!buf)
+	rc = next_entry(buf, fp, sizeof buf);
+	if (rc < 0)
 		return -1;
 
 	len = le32_to_cpu(buf[0]);
diff -Nru a/security/selinux/ss/ebitmap.c b/security/selinux/ss/ebitmap.c
--- a/security/selinux/ss/ebitmap.c	2005-03-01 23:39:07 -08:00
+++ b/security/selinux/ss/ebitmap.c	2005-03-01 23:39:07 -08:00
@@ -237,15 +237,15 @@
 
 int ebitmap_read(struct ebitmap *e, void *fp)
 {
-	int rc = -EINVAL;
+	int rc;
 	struct ebitmap_node *n, *l;
-	u32 *buf, mapsize, count, i;
+	u32 buf[3], mapsize, count, i;
 	u64 map;
 
 	ebitmap_init(e);
 
-	buf = next_entry(fp, sizeof(u32)*3);
-	if (!buf)
+	rc = next_entry(buf, fp, sizeof buf);
+	if (rc < 0)
 		goto out;
 
 	mapsize = le32_to_cpu(buf[0]);
@@ -256,7 +256,7 @@
 		printk(KERN_ERR "security: ebitmap: map size %u does not "
 		       "match my size %Zd (high bit was %d)\n", mapsize,
 		       MAPSIZE, e->highbit);
-		goto out;
+		goto bad;
 	}
 	if (!e->highbit) {
 		e->node = NULL;
@@ -269,8 +269,8 @@
 	}
 	l = NULL;
 	for (i = 0; i < count; i++) {
-		buf = next_entry(fp, sizeof(u32));
-		if (!buf) {
+		rc = next_entry(buf, fp, sizeof(u32));
+		if (rc < 0) {
 			printk(KERN_ERR "security: ebitmap: truncated map\n");
 			goto bad;
 		}
@@ -296,12 +296,11 @@
 			       n->startbit, (e->highbit - MAPSIZE));
 			goto bad_free;
 		}
-		buf = next_entry(fp, sizeof(u64));
-		if (!buf) {
+		rc = next_entry(&map, fp, sizeof(u64));
+		if (rc < 0) {
 			printk(KERN_ERR "security: ebitmap: truncated map\n");
 			goto bad_free;
 		}
-		memcpy(&map, buf, sizeof(u64));
 		n->map = le64_to_cpu(map);
 
 		if (!n->map) {
@@ -330,6 +329,8 @@
 bad_free:
 	kfree(n);
 bad:
+	if (!rc)
+		rc = -EINVAL;
 	ebitmap_destroy(e);
 	goto out;
 }
diff -Nru a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c
--- a/security/selinux/ss/mls.c	2005-03-01 23:39:18 -08:00
+++ b/security/selinux/ss/mls.c	2005-03-01 23:39:18 -08:00
@@ -402,10 +402,11 @@
 
 int mls_read_perm(struct perm_datum *perdatum, void *fp)
 {
-	u32 *buf;
+	u32 buf[1];
+	int rc;
 
-	buf = next_entry(fp, sizeof(u32));
-	if (!buf)
+	rc = next_entry(buf, fp, sizeof buf);
+	if (rc < 0)
 		return -EINVAL;
 	perdatum->base_perms = le32_to_cpu(buf[0]);
 	return 0;
@@ -418,7 +419,8 @@
 struct mls_level *mls_read_level(void *fp)
 {
 	struct mls_level *l;
-	u32 *buf;
+	u32 buf[1];
+	int rc;
 
 	l = kmalloc(sizeof(*l), GFP_ATOMIC);
 	if (!l) {
@@ -427,8 +429,8 @@
 	}
 	memset(l, 0, sizeof(*l));
 
-	buf = next_entry(fp, sizeof(u32));
-	if (!buf) {
+	rc = next_entry(buf, fp, sizeof buf);
+	if (rc < 0) {
 		printk(KERN_ERR "security: mls: truncated level\n");
 		goto bad;
 	}
@@ -453,16 +455,21 @@
  */
 static int mls_read_range_helper(struct mls_range *r, void *fp)
 {
-	u32 *buf;
-	int items, rc = -EINVAL;
+	u32 buf[2], items;
+	int rc;
 
-	buf = next_entry(fp, sizeof(u32));
-	if (!buf)
+	rc = next_entry(buf, fp, sizeof(u32));
+	if (rc < 0)
 		goto out;
 
 	items = le32_to_cpu(buf[0]);
-	buf = next_entry(fp, sizeof(u32) * items);
-	if (!buf) {
+	if (items > ARRAY_SIZE(buf)) {
+		printk(KERN_ERR "security: mls:  range overflow\n");
+		rc = -EINVAL;
+		goto out;
+	}
+	rc = next_entry(buf, fp, sizeof(u32) * items);
+	if (rc < 0) {
 		printk(KERN_ERR "security: mls:  truncated range\n");
 		goto out;
 	}
@@ -515,10 +522,11 @@
 int mls_read_class(struct class_datum *cladatum, void *fp)
 {
 	struct mls_perms *p = &cladatum->mlsperms;
-	u32 *buf;
+	u32 buf[4];
+	int rc;
 
-	buf = next_entry(fp, sizeof(u32)*4);
-	if (!buf) {
+	rc = next_entry(buf, fp, sizeof buf);
+	if (rc < 0) {
 		printk(KERN_ERR "security: mls:  truncated mls permissions\n");
 		return -EINVAL;
 	}
@@ -532,15 +540,13 @@
 int mls_read_user(struct user_datum *usrdatum, void *fp)
 {
 	struct mls_range_list *r, *l;
-	int rc = 0;
+	int rc;
 	u32 nel, i;
-	u32 *buf;
+	u32 buf[1];
 
-	buf = next_entry(fp, sizeof(u32));
-	if (!buf) {
-		rc = -EINVAL;
+	rc = next_entry(buf, fp, sizeof buf);
+	if (rc < 0)
 		goto out;
-	}
 	nel = le32_to_cpu(buf[0]);
 	l = NULL;
 	for (i = 0; i < nel; i++) {
@@ -569,10 +575,11 @@
 
 int mls_read_nlevels(struct policydb *p, void *fp)
 {
-	u32 *buf;
+	u32 buf[1];
+	int rc;
 
-	buf = next_entry(fp, sizeof(u32));
-	if (!buf)
+	rc = next_entry(buf, fp, sizeof buf);
+	if (rc < 0)
 		return -EINVAL;
 	p->nlevels = le32_to_cpu(buf[0]);
 	return 0;
@@ -657,7 +664,7 @@
 	char *key = NULL;
 	struct level_datum *levdatum;
 	int rc;
-	u32 *buf, len;
+	u32 buf[2], len;
 
 	levdatum = kmalloc(sizeof(*levdatum), GFP_ATOMIC);
 	if (!levdatum) {
@@ -666,26 +673,21 @@
 	}
 	memset(levdatum, 0, sizeof(*levdatum));
 
-	buf = next_entry(fp, sizeof(u32)*2);
-	if (!buf) {
-		rc = -EINVAL;
+	rc = next_entry(buf, fp, sizeof buf);
+	if (rc < 0)
 		goto bad;
-	}
 
 	len = le32_to_cpu(buf[0]);
 	levdatum->isalias = le32_to_cpu(buf[1]);
 
-	buf = next_entry(fp, len);
-	if (!buf) {
-		rc = -EINVAL;
-		goto bad;
-	}
 	key = kmalloc(len + 1,GFP_ATOMIC);
 	if (!key) {
 		rc = -ENOMEM;
 		goto bad;
 	}
-	memcpy(key, buf, len);
+	rc = next_entry(key, fp, len);
+	if (rc < 0)
+		goto bad;
 	key[len] = 0;
 
 	levdatum->level = mls_read_level(fp);
@@ -710,7 +712,7 @@
 	char *key = NULL;
 	struct cat_datum *catdatum;
 	int rc;
-	u32 *buf, len;
+	u32 buf[3], len;
 
 	catdatum = kmalloc(sizeof(*catdatum), GFP_ATOMIC);
 	if (!catdatum) {
@@ -719,27 +721,22 @@
 	}
 	memset(catdatum, 0, sizeof(*catdatum));
 
-	buf = next_entry(fp, sizeof(u32)*3);
-	if (!buf) {
-		rc = -EINVAL;
+	rc = next_entry(buf, fp, sizeof buf);
+	if (rc < 0)
 		goto bad;
-	}
 
 	len = le32_to_cpu(buf[0]);
 	catdatum->value = le32_to_cpu(buf[1]);
 	catdatum->isalias = le32_to_cpu(buf[2]);
 
-	buf = next_entry(fp, len);
-	if (!buf) {
-		rc = -EINVAL;
-		goto bad;
-	}
 	key = kmalloc(len + 1,GFP_ATOMIC);
 	if (!key) {
 		rc = -ENOMEM;
 		goto bad;
 	}
-	memcpy(key, buf, len);
+	rc = next_entry(key, fp, len);
+	if (rc < 0)
+		goto bad;
 	key[len] = 0;
 
 	rc = hashtab_insert(h, key, catdatum);
diff -Nru a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
--- a/security/selinux/ss/policydb.c	2005-03-01 23:38:56 -08:00
+++ b/security/selinux/ss/policydb.c	2005-03-01 23:38:56 -08:00
@@ -38,8 +38,6 @@
 };
 #endif
 
-int policydb_loaded_version;
-
 static unsigned int symtab_sizes[SYM_NUM] = {
 	2,
 	32,
@@ -633,13 +631,12 @@
 				     struct policydb *p,
 				     void *fp)
 {
-	u32 *buf;
-	int rc = 0;
+	u32 buf[3];
+	int rc;
 
-	buf = next_entry(fp, sizeof(u32)*3);
-	if (!buf) {
+	rc = next_entry(buf, fp, sizeof buf);
+	if (rc < 0) {
 		printk(KERN_ERR "security: context truncated\n");
-		rc = -EINVAL;
 		goto out;
 	}
 	c->user = le32_to_cpu(buf[0]);
@@ -672,7 +669,7 @@
 	char *key = NULL;
 	struct perm_datum *perdatum;
 	int rc;
-	u32 *buf, len;
+	u32 buf[2], len;
 
 	perdatum = kmalloc(sizeof(*perdatum), GFP_KERNEL);
 	if (!perdatum) {
@@ -681,11 +678,9 @@
 	}
 	memset(perdatum, 0, sizeof(*perdatum));
 
-	buf = next_entry(fp, sizeof(u32)*2);
-	if (!buf) {
-		rc = -EINVAL;
+	rc = next_entry(buf, fp, sizeof buf);
+	if (rc < 0)
 		goto bad;
-	}
 
 	len = le32_to_cpu(buf[0]);
 	perdatum->value = le32_to_cpu(buf[1]);
@@ -693,17 +688,14 @@
 	if (rc)
 		goto bad;
 
-	buf = next_entry(fp, len);
-	if (!buf) {
-		rc = -EINVAL;
-		goto bad;
-	}
 	key = kmalloc(len + 1,GFP_KERNEL);
 	if (!key) {
 		rc = -ENOMEM;
 		goto bad;
 	}
-	memcpy(key, buf, len);
+	rc = next_entry(key, fp, len);
+	if (rc < 0)
+		goto bad;
 	key[len] = 0;
 
 	rc = hashtab_insert(h, key, perdatum);
@@ -720,7 +712,7 @@
 {
 	char *key = NULL;
 	struct common_datum *comdatum;
-	u32 *buf, len, nel;
+	u32 buf[4], len, nel;
 	int i, rc;
 
 	comdatum = kmalloc(sizeof(*comdatum), GFP_KERNEL);
@@ -730,11 +722,9 @@
 	}
 	memset(comdatum, 0, sizeof(*comdatum));
 
-	buf = next_entry(fp, sizeof(u32)*4);
-	if (!buf) {
-		rc = -EINVAL;
+	rc = next_entry(buf, fp, sizeof buf);
+	if (rc < 0)
 		goto bad;
-	}
 
 	len = le32_to_cpu(buf[0]);
 	comdatum->value = le32_to_cpu(buf[1]);
@@ -745,17 +735,14 @@
 	comdatum->permissions.nprim = le32_to_cpu(buf[2]);
 	nel = le32_to_cpu(buf[3]);
 
-	buf = next_entry(fp, len);
-	if (!buf) {
-		rc = -EINVAL;
-		goto bad;
-	}
 	key = kmalloc(len + 1,GFP_KERNEL);
 	if (!key) {
 		rc = -ENOMEM;
 		goto bad;
 	}
-	memcpy(key, buf, len);
+	rc = next_entry(key, fp, len);
+	if (rc < 0)
+		goto bad;
 	key[len] = 0;
 
 	for (i = 0; i < nel; i++) {
@@ -780,21 +767,19 @@
 	struct class_datum *cladatum;
 	struct constraint_node *c, *lc;
 	struct constraint_expr *e, *le;
-	u32 *buf, len, len2, ncons, nexpr, nel;
+	u32 buf[6], len, len2, ncons, nexpr, nel;
 	int i, j, depth, rc;
 
 	cladatum = kmalloc(sizeof(*cladatum), GFP_KERNEL);
 	if (!cladatum) {
 		rc = -ENOMEM;
-		goto bad;
+		goto out;
 	}
 	memset(cladatum, 0, sizeof(*cladatum));
 
-	buf = next_entry(fp, sizeof(u32)*6);
-	if (!buf) {
-		rc = -EINVAL;
+	rc = next_entry(buf, fp, sizeof(u32)*6);
+	if (rc < 0)
 		goto bad;
-	}
 
 	len = le32_to_cpu(buf[0]);
 	len2 = le32_to_cpu(buf[1]);
@@ -808,17 +793,14 @@
 
 	ncons = le32_to_cpu(buf[5]);
 
-	buf = next_entry(fp, len);
-	if (!buf) {
-		rc = -EINVAL;
-		goto bad;
-	}
 	key = kmalloc(len + 1,GFP_KERNEL);
 	if (!key) {
 		rc = -ENOMEM;
 		goto bad;
 	}
-	memcpy(key, buf, len);
+	rc = next_entry(key, fp, len);
+	if (rc < 0)
+		goto bad;
 	key[len] = 0;
 
 	if (len2) {
@@ -827,12 +809,9 @@
 			rc = -ENOMEM;
 			goto bad;
 		}
-		buf = next_entry(fp, len2);
-		if (!buf) {
-			rc = -EINVAL;
+		rc = next_entry(cladatum->comkey, fp, len2);
+		if (rc < 0)
 			goto bad;
-		}
-		memcpy(cladatum->comkey, buf, len2);
 		cladatum->comkey[len2] = 0;
 
 		cladatum->comdatum = hashtab_search(p->p_commons.table,
@@ -851,7 +830,6 @@
 	}
 
 	lc = NULL;
-	rc = -EINVAL;
 	for (i = 0; i < ncons; i++) {
 		c = kmalloc(sizeof(*c), GFP_KERNEL);
 		if (!c) {
@@ -866,8 +844,8 @@
 			cladatum->constraints = c;
 		}
 
-		buf = next_entry(fp, sizeof(u32)*2);
-		if (!buf)
+		rc = next_entry(buf, fp, sizeof(u32)*2);
+		if (rc < 0)
 			goto bad;
 		c->permissions = le32_to_cpu(buf[0]);
 		nexpr = le32_to_cpu(buf[1]);
@@ -887,13 +865,14 @@
 				c->expr = e;
 			}
 
-			buf = next_entry(fp, sizeof(u32)*3);
-			if (!buf)
+			rc = next_entry(buf, fp, sizeof(u32)*3);
+			if (rc < 0)
 				goto bad;
 			e->expr_type = le32_to_cpu(buf[0]);
 			e->attr = le32_to_cpu(buf[1]);
 			e->op = le32_to_cpu(buf[2]);
 
+			rc = -EINVAL;
 			switch (e->expr_type) {
 			case CEXPR_NOT:
 				if (depth < 0)
@@ -934,6 +913,8 @@
 	rc = hashtab_insert(h, key, cladatum);
 	if (rc)
 		goto bad;
+
+	rc = 0;
 out:
 	return rc;
 bad:
@@ -946,7 +927,7 @@
 	char *key = NULL;
 	struct role_datum *role;
 	int rc;
-	u32 *buf, len;
+	u32 buf[2], len;
 
 	role = kmalloc(sizeof(*role), GFP_KERNEL);
 	if (!role) {
@@ -955,26 +936,21 @@
 	}
 	memset(role, 0, sizeof(*role));
 
-	buf = next_entry(fp, sizeof(u32)*2);
-	if (!buf) {
-		rc = -EINVAL;
+	rc = next_entry(buf, fp, sizeof buf);
+	if (rc < 0)
 		goto bad;
-	}
 
 	len = le32_to_cpu(buf[0]);
 	role->value = le32_to_cpu(buf[1]);
 
-	buf = next_entry(fp, len);
-	if (!buf) {
-		rc = -EINVAL;
-		goto bad;
-	}
 	key = kmalloc(len + 1,GFP_KERNEL);
 	if (!key) {
 		rc = -ENOMEM;
 		goto bad;
 	}
-	memcpy(key, buf, len);
+	rc = next_entry(key, fp, len);
+	if (rc < 0)
+		goto bad;
 	key[len] = 0;
 
 	rc = ebitmap_read(&role->dominates, fp);
@@ -1011,7 +987,7 @@
 	char *key = NULL;
 	struct type_datum *typdatum;
 	int rc;
-	u32 *buf, len;
+	u32 buf[3], len;
 
 	typdatum = kmalloc(sizeof(*typdatum),GFP_KERNEL);
 	if (!typdatum) {
@@ -1020,27 +996,22 @@
 	}
 	memset(typdatum, 0, sizeof(*typdatum));
 
-	buf = next_entry(fp, sizeof(u32)*3);
-	if (!buf) {
-		rc = -EINVAL;
+	rc = next_entry(buf, fp, sizeof buf);
+	if (rc < 0)
 		goto bad;
-	}
 
 	len = le32_to_cpu(buf[0]);
 	typdatum->value = le32_to_cpu(buf[1]);
 	typdatum->primary = le32_to_cpu(buf[2]);
 
-	buf = next_entry(fp, len);
-	if (!buf) {
-		rc = -EINVAL;
-		goto bad;
-	}
 	key = kmalloc(len + 1,GFP_KERNEL);
 	if (!key) {
 		rc = -ENOMEM;
 		goto bad;
 	}
-	memcpy(key, buf, len);
+	rc = next_entry(key, fp, len);
+	if (rc < 0)
+		goto bad;
 	key[len] = 0;
 
 	rc = hashtab_insert(h, key, typdatum);
@@ -1058,7 +1029,7 @@
 	char *key = NULL;
 	struct user_datum *usrdatum;
 	int rc;
-	u32 *buf, len;
+	u32 buf[2], len;
 
 
 	usrdatum = kmalloc(sizeof(*usrdatum), GFP_KERNEL);
@@ -1068,26 +1039,21 @@
 	}
 	memset(usrdatum, 0, sizeof(*usrdatum));
 
-	buf = next_entry(fp, sizeof(u32)*2);
-	if (!buf) {
-		rc = -EINVAL;
+	rc = next_entry(buf, fp, sizeof buf);
+	if (rc < 0)
 		goto bad;
-	}
 
 	len = le32_to_cpu(buf[0]);
 	usrdatum->value = le32_to_cpu(buf[1]);
 
-	buf = next_entry(fp, len);
-	if (!buf) {
-		rc = -EINVAL;
-		goto bad;
-	}
 	key = kmalloc(len + 1,GFP_KERNEL);
 	if (!key) {
 		rc = -ENOMEM;
 		goto bad;
 	}
-	memcpy(key, buf, len);
+	rc = next_entry(key, fp, len);
+	if (rc < 0)
+		goto bad;
 	key[len] = 0;
 
 	rc = ebitmap_read(&usrdatum->roles, fp);
@@ -1132,8 +1098,8 @@
 	struct role_trans *tr, *ltr;
 	struct ocontext *l, *c, *newc;
 	struct genfs *genfs_p, *genfs, *newgenfs;
-	int i, j, rc, r_policyvers = 0;
-	u32 *buf, len, len2, config, nprim, nel, nel2;
+	int i, j, rc;
+	u32 buf[8], len, len2, config, nprim, nel, nel2;
 	char *policydb_str;
 	struct policydb_compat_info *info;
 
@@ -1144,10 +1110,9 @@
 	if (rc)
 		goto out;
 
-	rc = -EINVAL;
 	/* Read the magic number and string length. */
-	buf = next_entry(fp, sizeof(u32)* 2);
-	if (!buf)
+	rc = next_entry(buf, fp, sizeof(u32)* 2);
+	if (rc < 0)
 		goto bad;
 
 	for (i = 0; i < 2; i++)
@@ -1167,11 +1132,6 @@
 		       len, strlen(POLICYDB_STRING));
 		goto bad;
 	}
-	buf = next_entry(fp, len);
-	if (!buf) {
-		printk(KERN_ERR "security:  truncated policydb string identifier\n");
-		goto bad;
-	}
 	policydb_str = kmalloc(len + 1,GFP_KERNEL);
 	if (!policydb_str) {
 		printk(KERN_ERR "security:  unable to allocate memory for policydb "
@@ -1179,7 +1139,12 @@
 		rc = -ENOMEM;
 		goto bad;
 	}
-	memcpy(policydb_str, buf, len);
+	rc = next_entry(policydb_str, fp, len);
+	if (rc < 0) {
+		printk(KERN_ERR "security:  truncated policydb string identifier\n");
+		kfree(policydb_str);
+		goto bad;
+	}
 	policydb_str[len] = 0;
 	if (strcmp(policydb_str, POLICYDB_STRING)) {
 		printk(KERN_ERR "security:  policydb string %s does not match "
@@ -1192,15 +1157,15 @@
 	policydb_str = NULL;
 
 	/* Read the version, config, and table sizes. */
-	buf = next_entry(fp, sizeof(u32)*4);
-	if (!buf)
+	rc = next_entry(buf, fp, sizeof(u32)*4);
+	if (rc < 0)
 		goto bad;
 	for (i = 0; i < 4; i++)
 		buf[i] = le32_to_cpu(buf[i]);
 
-	r_policyvers = buf[0];
-	if (r_policyvers < POLICYDB_VERSION_MIN ||
-	    r_policyvers > POLICYDB_VERSION_MAX) {
+	p->policyvers = buf[0];
+	if (p->policyvers < POLICYDB_VERSION_MIN ||
+	    p->policyvers > POLICYDB_VERSION_MAX) {
 	    	printk(KERN_ERR "security:  policydb version %d does not match "
 	    	       "my version range %d-%d\n",
 	    	       buf[0], POLICYDB_VERSION_MIN, POLICYDB_VERSION_MAX);
@@ -1216,10 +1181,10 @@
 	}
 
 
-	info = policydb_lookup_compat(r_policyvers);
+	info = policydb_lookup_compat(p->policyvers);
 	if (!info) {
 		printk(KERN_ERR "security:  unable to find policy compat info "
-		       "for version %d\n", r_policyvers);
+		       "for version %d\n", p->policyvers);
 		goto bad;
 	}
 
@@ -1235,11 +1200,9 @@
 		goto bad;
 
 	for (i = 0; i < info->sym_num; i++) {
-		buf = next_entry(fp, sizeof(u32)*2);
-		if (!buf) {
-			rc = -EINVAL;
+		rc = next_entry(buf, fp, sizeof(u32)*2);
+		if (rc < 0)
 			goto bad;
-		}
 		nprim = le32_to_cpu(buf[0]);
 		nel = le32_to_cpu(buf[1]);
 		for (j = 0; j < nel; j++) {
@@ -1255,17 +1218,15 @@
 	if (rc)
 		goto bad;
 
-	if (r_policyvers >= POLICYDB_VERSION_BOOL) {
+	if (p->policyvers >= POLICYDB_VERSION_BOOL) {
 		rc = cond_read_list(p, fp);
 		if (rc)
 			goto bad;
 	}
 
-	buf = next_entry(fp, sizeof(u32));
-	if (!buf) {
-		rc = -EINVAL;
+	rc = next_entry(buf, fp, sizeof(u32));
+	if (rc < 0)
 		goto bad;
-	}
 	nel = le32_to_cpu(buf[0]);
 	ltr = NULL;
 	for (i = 0; i < nel; i++) {
@@ -1280,22 +1241,18 @@
 		} else {
 			p->role_tr = tr;
 		}
-		buf = next_entry(fp, sizeof(u32)*3);
-		if (!buf) {
-			rc = -EINVAL;
+		rc = next_entry(buf, fp, sizeof(u32)*3);
+		if (rc < 0)
 			goto bad;
-		}
 		tr->role = le32_to_cpu(buf[0]);
 		tr->type = le32_to_cpu(buf[1]);
 		tr->new_role = le32_to_cpu(buf[2]);
 		ltr = tr;
 	}
 
-	buf = next_entry(fp, sizeof(u32));
-	if (!buf) {
-		rc = -EINVAL;
+	rc = next_entry(buf, fp, sizeof(u32));
+	if (rc < 0)
 		goto bad;
-	}
 	nel = le32_to_cpu(buf[0]);
 	lra = NULL;
 	for (i = 0; i < nel; i++) {
@@ -1310,11 +1267,9 @@
 		} else {
 			p->role_allow = ra;
 		}
-		buf = next_entry(fp, sizeof(u32)*2);
-		if (!buf) {
-			rc = -EINVAL;
+		rc = next_entry(buf, fp, sizeof(u32)*2);
+		if (rc < 0)
 			goto bad;
-		}
 		ra->role = le32_to_cpu(buf[0]);
 		ra->new_role = le32_to_cpu(buf[1]);
 		lra = ra;
@@ -1329,11 +1284,9 @@
 		goto bad;
 
 	for (i = 0; i < info->ocon_num; i++) {
-		buf = next_entry(fp, sizeof(u32));
-		if (!buf) {
-			rc = -EINVAL;
+		rc = next_entry(buf, fp, sizeof(u32));
+		if (rc < 0)
 			goto bad;
-		}
 		nel = le32_to_cpu(buf[0]);
 		l = NULL;
 		for (j = 0; j < nel; j++) {
@@ -1352,8 +1305,8 @@
 			rc = -EINVAL;
 			switch (i) {
 			case OCON_ISID:
-				buf = next_entry(fp, sizeof(u32));
-				if (!buf)
+				rc = next_entry(buf, fp, sizeof(u32));
+				if (rc < 0)
 					goto bad;
 				c->sid[0] = le32_to_cpu(buf[0]);
 				rc = context_read_and_validate(&c->context[0], p, fp);
@@ -1362,19 +1315,18 @@
 				break;
 			case OCON_FS:
 			case OCON_NETIF:
-				buf = next_entry(fp, sizeof(u32));
-				if (!buf)
+				rc = next_entry(buf, fp, sizeof(u32));
+				if (rc < 0)
 					goto bad;
 				len = le32_to_cpu(buf[0]);
-				buf = next_entry(fp, len);
-				if (!buf)
-					goto bad;
 				c->u.name = kmalloc(len + 1,GFP_KERNEL);
 				if (!c->u.name) {
 					rc = -ENOMEM;
 					goto bad;
 				}
-				memcpy(c->u.name, buf, len);
+				rc = next_entry(c->u.name, fp, len);
+				if (rc < 0)
+					goto bad;
 				c->u.name[len] = 0;
 				rc = context_read_and_validate(&c->context[0], p, fp);
 				if (rc)
@@ -1384,8 +1336,8 @@
 					goto bad;
 				break;
 			case OCON_PORT:
-				buf = next_entry(fp, sizeof(u32)*3);
-				if (!buf)
+				rc = next_entry(buf, fp, sizeof(u32)*3);
+				if (rc < 0)
 					goto bad;
 				c->u.port.protocol = le32_to_cpu(buf[0]);
 				c->u.port.low_port = le32_to_cpu(buf[1]);
@@ -1395,8 +1347,8 @@
 					goto bad;
 				break;
 			case OCON_NODE:
-				buf = next_entry(fp, sizeof(u32)* 2);
-				if (!buf)
+				rc = next_entry(buf, fp, sizeof(u32)* 2);
+				if (rc < 0)
 					goto bad;
 				c->u.node.addr = le32_to_cpu(buf[0]);
 				c->u.node.mask = le32_to_cpu(buf[1]);
@@ -1405,22 +1357,21 @@
 					goto bad;
 				break;
 			case OCON_FSUSE:
-				buf = next_entry(fp, sizeof(u32)*2);
-				if (!buf)
+				rc = next_entry(buf, fp, sizeof(u32)*2);
+				if (rc < 0)
 					goto bad;
 				c->v.behavior = le32_to_cpu(buf[0]);
 				if (c->v.behavior > SECURITY_FS_USE_NONE)
 					goto bad;
 				len = le32_to_cpu(buf[1]);
-				buf = next_entry(fp, len);
-				if (!buf)
-					goto bad;
 				c->u.name = kmalloc(len + 1,GFP_KERNEL);
 				if (!c->u.name) {
 					rc = -ENOMEM;
 					goto bad;
 				}
-				memcpy(c->u.name, buf, len);
+				rc = next_entry(c->u.name, fp, len);
+				if (rc < 0)
+					goto bad;
 				c->u.name[len] = 0;
 				rc = context_read_and_validate(&c->context[0], p, fp);
 				if (rc)
@@ -1429,8 +1380,8 @@
 			case OCON_NODE6: {
 				int k;
 
-				buf = next_entry(fp, sizeof(u32) * 8);
-				if (!buf)
+				rc = next_entry(buf, fp, sizeof(u32) * 8);
+				if (rc < 0)
 					goto bad;
 				for (k = 0; k < 4; k++)
 					c->u.node6.addr[k] = le32_to_cpu(buf[k]);
@@ -1444,22 +1395,17 @@
 		}
 	}
 
-	buf = next_entry(fp, sizeof(u32));
-	if (!buf) {
-		rc = -EINVAL;
+	rc = next_entry(buf, fp, sizeof(u32));
+	if (rc < 0)
 		goto bad;
-	}
 	nel = le32_to_cpu(buf[0]);
 	genfs_p = NULL;
 	rc = -EINVAL;
 	for (i = 0; i < nel; i++) {
-		buf = next_entry(fp, sizeof(u32));
-		if (!buf)
+		rc = next_entry(buf, fp, sizeof(u32));
+		if (rc < 0)
 			goto bad;
 		len = le32_to_cpu(buf[0]);
-		buf = next_entry(fp, len);
-		if (!buf)
-			goto bad;
 		newgenfs = kmalloc(sizeof(*newgenfs), GFP_KERNEL);
 		if (!newgenfs) {
 			rc = -ENOMEM;
@@ -1473,7 +1419,12 @@
 			kfree(newgenfs);
 			goto bad;
 		}
-		memcpy(newgenfs->fstype, buf, len);
+		rc = next_entry(newgenfs->fstype, fp, len);
+		if (rc < 0) {
+			kfree(newgenfs->fstype);
+			kfree(newgenfs);
+			goto bad;
+		}
 		newgenfs->fstype[len] = 0;
 		for (genfs_p = NULL, genfs = p->genfs; genfs;
 		     genfs_p = genfs, genfs = genfs->next) {
@@ -1492,18 +1443,15 @@
 			genfs_p->next = newgenfs;
 		else
 			p->genfs = newgenfs;
-		buf = next_entry(fp, sizeof(u32));
-		if (!buf)
+		rc = next_entry(buf, fp, sizeof(u32));
+		if (rc < 0)
 			goto bad;
 		nel2 = le32_to_cpu(buf[0]);
 		for (j = 0; j < nel2; j++) {
-			buf = next_entry(fp, sizeof(u32));
-			if (!buf)
+			rc = next_entry(buf, fp, sizeof(u32));
+			if (rc < 0)
 				goto bad;
 			len = le32_to_cpu(buf[0]);
-			buf = next_entry(fp, len);
-			if (!buf)
-				goto bad;
 
 			newc = kmalloc(sizeof(*newc), GFP_KERNEL);
 			if (!newc) {
@@ -1517,10 +1465,12 @@
 				rc = -ENOMEM;
 				goto bad_newc;
 			}
-			memcpy(newc->u.name, buf, len);
+			rc = next_entry(newc->u.name, fp, len);
+			if (rc < 0)
+				goto bad_newc;
 			newc->u.name[len] = 0;
-			buf = next_entry(fp, sizeof(u32));
-			if (!buf)
+			rc = next_entry(buf, fp, sizeof(u32));
+			if (rc < 0)
 				goto bad_newc;
 			newc->v.sclass = le32_to_cpu(buf[0]);
 			if (context_read_and_validate(&newc->context[0], p, fp))
@@ -1552,12 +1502,15 @@
 	rc = mls_read_trusted(p, fp);
 	if (rc)
 		goto bad;
+
+	rc = 0;
 out:
-	policydb_loaded_version = r_policyvers;
 	return rc;
 bad_newc:
 	ocontext_destroy(newc,OCON_FSUSE);
 bad:
+	if (!rc)
+		rc = -EINVAL;
 	policydb_destroy(p);
 	goto out;
 }
diff -Nru a/security/selinux/ss/policydb.h b/security/selinux/ss/policydb.h
--- a/security/selinux/ss/policydb.h	2005-03-01 23:39:08 -08:00
+++ b/security/selinux/ss/policydb.h	2005-03-01 23:39:08 -08:00
@@ -246,6 +246,8 @@
 	struct ebitmap trustedwriters;
 	struct ebitmap trustedobjects;
 #endif
+
+	unsigned int policyvers;
 };
 
 extern int policydb_init(struct policydb *p);
@@ -271,17 +273,15 @@
 	size_t len;
 };
 
-static inline void *next_entry(struct policy_file *fp, size_t bytes)
+static inline int next_entry(void *buf, struct policy_file *fp, size_t bytes)
 {
-	void *buf;
-
 	if (bytes > fp->len)
-		return NULL;
+		return -EINVAL;
 
-	buf = fp->data;
+	memcpy(buf, fp->data, bytes);
 	fp->data += bytes;
 	fp->len -= bytes;
-	return buf;
+	return 0;
 }
 
 #endif	/* _SS_POLICYDB_H_ */
diff -Nru a/security/selinux/ss/services.c b/security/selinux/ss/services.c
--- a/security/selinux/ss/services.c	2005-03-01 23:39:16 -08:00
+++ b/security/selinux/ss/services.c	2005-03-01 23:39:16 -08:00
@@ -40,9 +40,9 @@
 #include "mls.h"
 
 extern void selnl_notify_policyload(u32 seqno);
-extern int policydb_loaded_version;
+unsigned int policydb_loaded_version;
 
-static rwlock_t policy_rwlock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(policy_rwlock);
 #define POLICY_RDLOCK read_lock(&policy_rwlock)
 #define POLICY_WRLOCK write_lock_irq(&policy_rwlock)
 #define POLICY_RDUNLOCK read_unlock(&policy_rwlock)
@@ -275,7 +275,7 @@
 	 * pair.
 	 */
 	if (tclass == SECCLASS_PROCESS &&
-	    (avd->allowed & PROCESS__TRANSITION) &&
+	    (avd->allowed & (PROCESS__TRANSITION | PROCESS__DYNTRANSITION)) &&
 	    scontext->role != tcontext->role) {
 		for (ra = policydb.role_allow; ra; ra = ra->next) {
 			if (scontext->role == ra->role &&
@@ -283,7 +283,8 @@
 				break;
 		}
 		if (!ra)
-			avd->allowed = (avd->allowed) & ~(PROCESS__TRANSITION);
+			avd->allowed = (avd->allowed) & ~(PROCESS__TRANSITION |
+			                                PROCESS__DYNTRANSITION);
 	}
 
 	return 0;
@@ -1046,6 +1047,7 @@
 			avtab_cache_destroy();
 			return -EINVAL;
 		}
+		policydb_loaded_version = policydb.policyvers;
 		ss_initialized = 1;
 
 		LOAD_UNLOCK;
@@ -1094,7 +1096,7 @@
 	memcpy(&policydb, &newpolicydb, sizeof policydb);
 	sidtab_set(&sidtab, &newsidtab);
 	seqno = ++latest_granting;
-
+	policydb_loaded_version = policydb.policyvers;
 	POLICY_WRUNLOCK;
 	LOAD_UNLOCK;
 
diff -Nru a/sound/Kconfig b/sound/Kconfig
--- a/sound/Kconfig	2005-03-01 23:39:16 -08:00
+++ b/sound/Kconfig	2005-03-01 23:39:16 -08:00
@@ -55,6 +55,8 @@
 
 source "sound/arm/Kconfig"
 
+source "sound/mips/Kconfig"
+
 # the following will depenend on the order of config.
 # here assuming USB is defined before ALSA
 source "sound/usb/Kconfig"
@@ -70,7 +72,7 @@
 endmenu
 
 menu "Open Sound System"
-	depends on SOUND!=n && (BROKEN || !(SPARC32 || SPARC64))
+	depends on SOUND!=n && (BROKEN || (!SPARC32 && !SPARC64))
 
 config SOUND_PRIME
 	tristate "Open Sound System (DEPRECATED)"
diff -Nru a/sound/Makefile b/sound/Makefile
--- a/sound/Makefile	2005-03-01 23:38:54 -08:00
+++ b/sound/Makefile	2005-03-01 23:38:54 -08:00
@@ -4,7 +4,7 @@
 obj-$(CONFIG_SOUND) += soundcore.o
 obj-$(CONFIG_SOUND_PRIME) += oss/
 obj-$(CONFIG_DMASOUND) += oss/
-obj-$(CONFIG_SND) += core/ i2c/ drivers/ isa/ pci/ ppc/ arm/ synth/ usb/ sparc/ parisc/ pcmcia/
+obj-$(CONFIG_SND) += core/ i2c/ drivers/ isa/ pci/ ppc/ arm/ synth/ usb/ sparc/ parisc/ pcmcia/ mips/
 
 ifeq ($(CONFIG_SND),y)
   obj-y += last.o
diff -Nru a/sound/arm/sa11xx-uda1341.c b/sound/arm/sa11xx-uda1341.c
--- a/sound/arm/sa11xx-uda1341.c	2005-03-01 23:38:52 -08:00
+++ b/sound/arm/sa11xx-uda1341.c	2005-03-01 23:38:52 -08:00
@@ -21,7 +21,7 @@
  *                              merged HAL layer (patches from Brian)
  */
 
-/* $Id: sa11xx-uda1341.c,v 1.18 2004/07/20 15:54:09 cladisch Exp $ */
+/* $Id: sa11xx-uda1341.c,v 1.19 2004/12/15 15:26:10 tiwai Exp $ */
 
 /***************************************************************************************************
 *
@@ -875,7 +875,6 @@
 #endif
 	l3_command(chip->uda1341, CMD_SUSPEND, NULL);
 	sa11xx_uda1341_audio_shutdown(chip);
-	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
 	return 0;
 }
 
@@ -891,7 +890,6 @@
 #else
 	//FIXME
 #endif
-	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
 	return 0;
 }
 #endif /* COMFIG_PM */
diff -Nru a/sound/core/Kconfig b/sound/core/Kconfig
--- a/sound/core/Kconfig	2005-03-01 23:39:08 -08:00
+++ b/sound/core/Kconfig	2005-03-01 23:39:08 -08:00
@@ -83,7 +83,7 @@
 
 config SND_BIT32_EMUL
 	tristate "Emulation for 32-bit applications"
-	depends on SND && (MIPS64 || SPARC64 || PPC64 || X86_64 && IA32_EMULATION)
+	depends on SND && COMPAT
 	select SND_PCM
 	select SND_RAWMIDI
 	select SND_TIMER
diff -Nru a/sound/core/control.c b/sound/core/control.c
--- a/sound/core/control.c	2005-03-01 23:38:53 -08:00
+++ b/sound/core/control.c	2005-03-01 23:38:53 -08:00
@@ -31,6 +31,9 @@
 #include <sound/info.h>
 #include <sound/control.h>
 
+/* max number of user-defined controls */
+#define MAX_USER_CONTROLS	32
+
 typedef struct _snd_kctl_ioctl {
 	struct list_head list;		/* list of all ioctls */
 	snd_kctl_ioctl_func_t fioctl;
@@ -635,19 +638,13 @@
 	return result;
 }
 
-static int snd_ctl_elem_read(snd_card_t *card, snd_ctl_elem_value_t __user *_control)
+int snd_ctl_elem_read(snd_card_t *card, snd_ctl_elem_value_t *control)
 {
-	snd_ctl_elem_value_t *control;
 	snd_kcontrol_t *kctl;
 	snd_kcontrol_volatile_t *vd;
 	unsigned int index_offset;
 	int result, indirect;
-	
-	control = kmalloc(sizeof(*control), GFP_KERNEL);
-	if (control == NULL)
-		return -ENOMEM;	
-	if (copy_from_user(control, _control, sizeof(*control)))
-		return -EFAULT;
+
 	down_read(&card->controls_rwsem);
 	kctl = snd_ctl_find_id(card, &control->id);
 	if (kctl == NULL) {
@@ -668,27 +665,36 @@
 		}
 	}
 	up_read(&card->controls_rwsem);
+	return result;
+}
+
+static int snd_ctl_elem_read_user(snd_card_t *card, snd_ctl_elem_value_t __user *_control)
+{
+	snd_ctl_elem_value_t *control;
+	int result;
+	
+	control = kmalloc(sizeof(*control), GFP_KERNEL);
+	if (control == NULL)
+		return -ENOMEM;	
+	if (copy_from_user(control, _control, sizeof(*control))) {
+		kfree(control);
+		return -EFAULT;
+	}
+	result = snd_ctl_elem_read(card, control);
 	if (result >= 0)
 		if (copy_to_user(_control, control, sizeof(*control)))
-			return -EFAULT;
+			result = -EFAULT;
 	kfree(control);
 	return result;
 }
 
-static int snd_ctl_elem_write(snd_ctl_file_t *file, snd_ctl_elem_value_t __user *_control)
+int snd_ctl_elem_write(snd_card_t *card, snd_ctl_file_t *file, snd_ctl_elem_value_t *control)
 {
-	snd_card_t *card = file->card;
-	snd_ctl_elem_value_t *control;
 	snd_kcontrol_t *kctl;
 	snd_kcontrol_volatile_t *vd;
 	unsigned int index_offset;
 	int result, indirect;
 
-	control = kmalloc(sizeof(*control), GFP_KERNEL);
-	if (control == NULL)
-		return -ENOMEM;	
-	if (copy_from_user(control, _control, sizeof(*control)))
-		return -EFAULT;
 	down_read(&card->controls_rwsem);
 	kctl = snd_ctl_find_id(card, &control->id);
 	if (kctl == NULL) {
@@ -702,7 +708,7 @@
 		} else {
 			if (!(vd->access & SNDRV_CTL_ELEM_ACCESS_WRITE) ||
 			    kctl->put == NULL ||
-			    (vd->owner != NULL && vd->owner != file)) {
+			    (file && vd->owner != NULL && vd->owner != file)) {
 				result = -EPERM;
 			} else {
 				snd_ctl_build_ioff(&control->id, kctl, index_offset);
@@ -711,16 +717,30 @@
 			if (result > 0) {
 				up_read(&card->controls_rwsem);
 				snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &control->id);
-				result = 0;
-				goto __unlocked;
+				return 0;
 			}
 		}
 	}
 	up_read(&card->controls_rwsem);
-      __unlocked:
+	return result;
+}
+
+static int snd_ctl_elem_write_user(snd_ctl_file_t *file, snd_ctl_elem_value_t __user *_control)
+{
+	snd_ctl_elem_value_t *control;
+	int result;
+
+	control = kmalloc(sizeof(*control), GFP_KERNEL);
+	if (control == NULL)
+		return -ENOMEM;	
+	if (copy_from_user(control, _control, sizeof(*control))) {
+		kfree(control);
+		return -EFAULT;
+	}
+	result = snd_ctl_elem_write(file->card, file, control);
 	if (result >= 0)
 		if (copy_to_user(_control, control, sizeof(*control)))
-			return -EFAULT;
+			result = -EFAULT;
 	kfree(control);
 	return result;
 }
@@ -784,30 +804,21 @@
 }
 
 struct user_element {
-	enum sndrv_ctl_elem_type type;	/* element type */
-	unsigned int elem_count;	/* count of elements */
-	union {
-		struct {
-			unsigned int items;
-		} enumerated;
-	} u;
+	snd_ctl_elem_info_t info;
 	void *elem_data;		/* element data */
 	unsigned long elem_data_size;	/* size of element data in bytes */
 	void *priv_data;		/* private data (like strings for enumerated type) */
 	unsigned long priv_data_size;	/* size of private data in bytes */
-	unsigned short dimen_count;	/* count of dimensions */
-	unsigned short dimen[0];	/* array of dimensions */
 };
 
 static int snd_ctl_elem_user_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
 {
 	struct user_element *ue = kcontrol->private_data;
 
-	uinfo->type = ue->type;
-	uinfo->count = ue->elem_count;
-	if (ue->type == SNDRV_CTL_ELEM_TYPE_ENUMERATED) {
-		uinfo->value.enumerated.items = ue->u.enumerated.items;
-		if (uinfo->value.enumerated.item >= ue->u.enumerated.items)
+	*uinfo = ue->info;
+	if (ue->info.type == SNDRV_CTL_ELEM_TYPE_ENUMERATED) {
+		uinfo->value.enumerated.items = ue->info.value.enumerated.items;
+		if (uinfo->value.enumerated.item >= ue->info.value.enumerated.items)
 			uinfo->value.enumerated.item = 0;
 		strlcpy(uinfo->value.enumerated.name,
 			(char *)ue->priv_data + uinfo->value.enumerated.item * 64,
@@ -829,9 +840,10 @@
 	int change;
 	struct user_element *ue = kcontrol->private_data;
 	
-	change = memcmp(&ucontrol->value, ue->elem_data, ue->elem_data_size);
-	memcpy(ue->elem_data, &ucontrol->value, ue->elem_data_size);
-	return !!change;
+	change = memcmp(&ucontrol->value, ue->elem_data, ue->elem_data_size) != 0;
+	if (change)
+		memcpy(ue->elem_data, &ucontrol->value, ue->elem_data_size);
+	return change;
 }
 
 static void snd_ctl_elem_user_free(snd_kcontrol_t * kcontrol)
@@ -845,34 +857,35 @@
 	snd_ctl_elem_info_t info;
 	snd_kcontrol_t kctl, *_kctl;
 	unsigned int access;
-	long private_size, dimen_size, extra_size;
+	long private_size, extra_size;
 	struct user_element *ue;
 	int idx, err;
 	
+	if (card->user_ctl_count >= MAX_USER_CONTROLS)
+		return -ENOMEM;
 	if (copy_from_user(&info, _info, sizeof(info)))
 		return -EFAULT;
 	if (info.count > 1024)
 		return -EINVAL;
 	access = info.access == 0 ? SNDRV_CTL_ELEM_ACCESS_READWRITE :
-		 (info.access & (SNDRV_CTL_ELEM_ACCESS_READWRITE|SNDRV_CTL_ELEM_ACCESS_INACTIVE|
-		 		 SNDRV_CTL_ELEM_ACCESS_DINDIRECT|SNDRV_CTL_ELEM_ACCESS_INDIRECT));
-	if (access & (SNDRV_CTL_ELEM_ACCESS_DINDIRECT | SNDRV_CTL_ELEM_ACCESS_INDIRECT))
-		return -EINVAL;
+		(info.access & (SNDRV_CTL_ELEM_ACCESS_READWRITE|SNDRV_CTL_ELEM_ACCESS_INACTIVE));
 	info.id.numid = 0;
 	memset(&kctl, 0, sizeof(kctl));
 	down_write(&card->controls_rwsem);
-	if (!!((_kctl = snd_ctl_find_id(card, &info.id)) != NULL) ^ replace) {
-		up_write(&card->controls_rwsem);
-		return !replace ? -EBUSY : -ENOENT;
-	}
-	if (replace) {
-		err = snd_ctl_remove(card, _kctl);
-		if (err < 0) {
-			up_write(&card->controls_rwsem);
-			return err;
-		}
+	_kctl = snd_ctl_find_id(card, &info.id);
+	err = 0;
+	if (_kctl) {
+		if (replace)
+			err = snd_ctl_remove(card, _kctl);
+		else
+			err = -EBUSY;
+	} else {
+		if (replace)
+			err = -ENOENT;
 	}
 	up_write(&card->controls_rwsem);
+	if (err < 0)
+		return err;
 	memcpy(&kctl.id, &info.id, sizeof(info.id));
 	kctl.count = info.owner ? info.owner : 1;
 	access |= SNDRV_CTL_ELEM_ACCESS_USER;
@@ -902,7 +915,7 @@
 		private_size = sizeof(unsigned int);
 		if (info.count > 128)
 			return -EINVAL;
-		if (info.value.enumerated.items > 1024)
+		if (info.value.enumerated.items > 128)
 			return -EINVAL;
 		extra_size = info.value.enumerated.items * 64;
 		break;
@@ -920,31 +933,18 @@
 		return -EINVAL;
 	}
 	private_size *= info.count;
-	if (private_size > 1024 * 1024)
-		return -EINVAL;
-	dimen_size = 0;
-	if (!(info.access & SNDRV_CTL_ELEM_ACCESS_DINDIRECT))
-		for (idx = 0; idx < 4 && info.dimen.d[idx]; idx++)
-			dimen_size += sizeof(unsigned short);
-	ue = kcalloc(1, sizeof(struct user_element) + dimen_size + private_size + extra_size, GFP_KERNEL);
+	ue = kcalloc(1, sizeof(struct user_element) + private_size + extra_size, GFP_KERNEL);
 	if (ue == NULL)
 		return -ENOMEM;
-	ue->type = info.type;
-	ue->elem_count = info.count;
-	if (!(info.access & SNDRV_CTL_ELEM_ACCESS_DINDIRECT)) {
-		for (idx = 0; idx < 4 && info.dimen.d[idx]; idx++)
-			ue->dimen[idx] = info.dimen.d[idx];
-		ue->dimen_count = dimen_size / sizeof(unsigned short);
-	}
-	ue->elem_data = (char *)ue + sizeof(ue) + dimen_size;
+	ue->info = info;
+	ue->elem_data = (char *)ue + sizeof(ue);
 	ue->elem_data_size = private_size;
 	if (extra_size) {
-		ue->priv_data = (char *)ue + sizeof(ue) + dimen_size + private_size;
+		ue->priv_data = (char *)ue + sizeof(ue) + private_size;
 		ue->priv_data_size = extra_size;
-		if (ue->type == SNDRV_CTL_ELEM_TYPE_ENUMERATED) {
-			if (copy_from_user(ue->priv_data, *(char **)info.value.enumerated.name, extra_size))
+		if (ue->info.type == SNDRV_CTL_ELEM_TYPE_ENUMERATED) {
+			if (copy_from_user(ue->priv_data, *(char __user **)info.value.enumerated.name, extra_size))
 				return -EFAULT;
-			ue->u.enumerated.items = info.value.enumerated.items;
 		}
 	}
 	kctl.private_free = snd_ctl_elem_user_free;
@@ -961,16 +961,29 @@
 		snd_ctl_free_one(_kctl);
 		return err;
 	}
+
+	down_write(&card->controls_rwsem);
+	card->user_ctl_count++;
+	up_write(&card->controls_rwsem);
+
 	return 0;
 }
 
 static int snd_ctl_elem_remove(snd_ctl_file_t *file, snd_ctl_elem_id_t __user *_id)
 {
 	snd_ctl_elem_id_t id;
+	int err;
 
 	if (copy_from_user(&id, _id, sizeof(id)))
 		return -EFAULT;
-	return snd_ctl_remove_unlocked_id(file, &id);
+	err = snd_ctl_remove_unlocked_id(file, &id);
+	if (! err) {
+		snd_card_t *card = file->card;
+		down_write(&card->controls_rwsem);
+		card->user_ctl_count--;
+		up_write(&card->controls_rwsem);
+	}
+	return err;
 }
 
 static int snd_ctl_subscribe_events(snd_ctl_file_t *file, int __user *ptr)
@@ -1002,18 +1015,23 @@
 {
 	switch (power_state) {
 	case SNDRV_CTL_POWER_D0:
-	case SNDRV_CTL_POWER_D1:
-	case SNDRV_CTL_POWER_D2:
-		if (card->power_state != power_state)
+		if (card->power_state != power_state) {
 			/* FIXME: pass the correct state value */
 			card->pm_resume(card, 0);
+			snd_power_change_state(card, power_state);
+		}
 		break;
 	case SNDRV_CTL_POWER_D3hot:
-	case SNDRV_CTL_POWER_D3cold:
-		if (card->power_state != power_state)
+		if (card->power_state != power_state) {
 			/* FIXME: pass the correct state value */
 			card->pm_suspend(card, 0);
+			snd_power_change_state(card, power_state);
+		}
 		break;
+	case SNDRV_CTL_POWER_D1:
+	case SNDRV_CTL_POWER_D2:
+	case SNDRV_CTL_POWER_D3cold:
+		/* not supported yet */
 	default:
 		return -EINVAL;
 	}
@@ -1045,9 +1063,9 @@
 	case SNDRV_CTL_IOCTL_ELEM_INFO:
 		return snd_ctl_elem_info(ctl, argp);
 	case SNDRV_CTL_IOCTL_ELEM_READ:
-		return snd_ctl_elem_read(ctl->card, argp);
+		return snd_ctl_elem_read_user(ctl->card, argp);
 	case SNDRV_CTL_IOCTL_ELEM_WRITE:
-		return snd_ctl_elem_write(ctl, argp);
+		return snd_ctl_elem_write_user(ctl, argp);
 	case SNDRV_CTL_IOCTL_ELEM_LOCK:
 		return snd_ctl_elem_lock(ctl, argp);
 	case SNDRV_CTL_IOCTL_ELEM_UNLOCK:
@@ -1252,11 +1270,11 @@
 };
 
 /*
- * registration of the control device:
- * called from init.c
+ * registration of the control device
  */
-int snd_ctl_register(snd_card_t *card)
+static int snd_ctl_dev_register(snd_device_t *device)
 {
+	snd_card_t *card = device->device_data;
 	int err, cardnum;
 	char name[16];
 
@@ -1271,11 +1289,11 @@
 }
 
 /*
- * disconnection of the control device:
- * called from init.c
+ * disconnection of the control device
  */
-int snd_ctl_disconnect(snd_card_t *card)
+static int snd_ctl_dev_disconnect(snd_device_t *device)
 {
+	snd_card_t *card = device->device_data;
 	struct list_head *flist;
 	snd_ctl_file_t *ctl;
 
@@ -1290,19 +1308,13 @@
 }
 
 /*
- * de-registration of the control device:
- * called from init.c
+ * free all controls
  */
-int snd_ctl_unregister(snd_card_t *card)
+static int snd_ctl_dev_free(snd_device_t *device)
 {
-	int err, cardnum;
+	snd_card_t *card = device->device_data;
 	snd_kcontrol_t *control;
 
-	snd_assert(card != NULL, return -ENXIO);
-	cardnum = card->number;
-	snd_assert(cardnum >= 0 && cardnum < SNDRV_CARDS, return -ENXIO);
-	if ((err = snd_unregister_device(SNDRV_DEVICE_TYPE_CONTROL, card, 0)) < 0)
-		return err;
 	down_write(&card->controls_rwsem);
 	while (!list_empty(&card->controls)) {
 		control = snd_kcontrol(card->controls.next);
@@ -1310,4 +1322,37 @@
 	}
 	up_write(&card->controls_rwsem);
 	return 0;
+}
+
+/*
+ * de-registration of the control device
+ */
+static int snd_ctl_dev_unregister(snd_device_t *device)
+{
+	snd_card_t *card = device->device_data;
+	int err, cardnum;
+
+	snd_assert(card != NULL, return -ENXIO);
+	cardnum = card->number;
+	snd_assert(cardnum >= 0 && cardnum < SNDRV_CARDS, return -ENXIO);
+	if ((err = snd_unregister_device(SNDRV_DEVICE_TYPE_CONTROL, card, 0)) < 0)
+		return err;
+	return snd_ctl_dev_free(device);
+}
+
+/*
+ * create control core:
+ * called from init.c
+ */
+int snd_ctl_create(snd_card_t *card)
+{
+	static snd_device_ops_t ops = {
+		.dev_free = snd_ctl_dev_free,
+		.dev_register =	snd_ctl_dev_register,
+		.dev_disconnect = snd_ctl_dev_disconnect,
+		.dev_unregister = snd_ctl_dev_unregister
+	};
+
+	snd_assert(card != NULL, return -ENXIO);
+	return snd_device_new(card, SNDRV_DEV_CONTROL, card, &ops);
 }
diff -Nru a/sound/core/hwdep.c b/sound/core/hwdep.c
--- a/sound/core/hwdep.c	2005-03-01 23:38:52 -08:00
+++ b/sound/core/hwdep.c	2005-03-01 23:38:52 -08:00
@@ -35,7 +35,7 @@
 MODULE_DESCRIPTION("Hardware dependent layer");
 MODULE_LICENSE("GPL");
 
-snd_hwdep_t *snd_hwdep_devices[SNDRV_CARDS * SNDRV_MINOR_HWDEPS];
+static snd_hwdep_t *snd_hwdep_devices[SNDRV_CARDS * SNDRV_MINOR_HWDEPS];
 
 static DECLARE_MUTEX(register_mutex);
 
diff -Nru a/sound/core/info.c b/sound/core/info.c
--- a/sound/core/info.c	2005-03-01 23:39:16 -08:00
+++ b/sound/core/info.c	2005-03-01 23:39:16 -08:00
@@ -20,18 +20,14 @@
  */
 
 #include <sound/driver.h>
-#include <linux/version.h>
 #include <linux/init.h>
 #include <linux/vmalloc.h>
 #include <linux/time.h>
 #include <linux/smp_lock.h>
-#include <linux/utsname.h>
-#include <linux/config.h>
-
 #include <sound/core.h>
-#include <sound/version.h>
 #include <sound/minors.h>
 #include <sound/info.h>
+#include <sound/version.h>
 #include <linux/proc_fs.h>
 #include <linux/devfs_fs_kernel.h>
 #include <stdarg.h>
@@ -129,8 +125,8 @@
 	de->owner = THIS_MODULE;
 }
 
-void snd_remove_proc_entry(struct proc_dir_entry *parent,
-			   struct proc_dir_entry *de)
+static void snd_remove_proc_entry(struct proc_dir_entry *parent,
+				  struct proc_dir_entry *de)
 {
 	if (de)
 		remove_proc_entry(de->name, parent);
@@ -525,8 +521,8 @@
  *
  * Returns the pointer of new instance or NULL on failure.
  */
-struct proc_dir_entry *snd_create_proc_entry(const char *name, mode_t mode,
-					     struct proc_dir_entry *parent)
+static struct proc_dir_entry *snd_create_proc_entry(const char *name, mode_t mode,
+						    struct proc_dir_entry *parent)
 {
 	struct proc_dir_entry *p;
 	p = create_proc_entry(name, mode, parent);
@@ -895,8 +891,7 @@
 {
 	if (entry == NULL)
 		return;
-	if (entry->name)
-		kfree((char *)entry->name);
+	kfree(entry->name);
 	if (entry->private_free)
 		entry->private_free(entry);
 	kfree(entry);
@@ -962,18 +957,10 @@
 
 static void snd_info_version_read(snd_info_entry_t *entry, snd_info_buffer_t * buffer)
 {
-	static char *kernel_version = system_utsname.release;
-
 	snd_iprintf(buffer,
-		    "Advanced Linux Sound Architecture Driver Version " CONFIG_SND_VERSION CONFIG_SND_DATE ".\n"
-		    "Compiled on " __DATE__ " for kernel %s"
-#ifdef CONFIG_SMP
-		    " (SMP)"
-#endif
-#ifdef MODVERSIONS
-		    " with versioned symbols"
-#endif
-		    ".\n", kernel_version);
+		    "Advanced Linux Sound Architecture Driver Version "
+		    CONFIG_SND_VERSION CONFIG_SND_DATE ".\n"
+		   );
 }
 
 static int __init snd_info_version_init(void)
diff -Nru a/sound/core/init.c b/sound/core/init.c
--- a/sound/core/init.c	2005-03-01 23:38:53 -08:00
+++ b/sound/core/init.c	2005-03-01 23:38:53 -08:00
@@ -37,7 +37,6 @@
 	struct snd_shutdown_f_ops *next;
 };
 
-int snd_cards_count = 0;
 unsigned int snd_cards_lock = 0;	/* locked for registering/using */
 snd_card_t *snd_cards[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = NULL};
 rwlock_t snd_card_rwlock = RW_LOCK_UNLOCKED;
@@ -125,7 +124,7 @@
 #endif
 	/* the control interface cannot be accessed from the user space until */
 	/* snd_cards_bitmask and snd_cards are set with snd_card_register */
-	if ((err = snd_ctl_register(card)) < 0) {
+	if ((err = snd_ctl_create(card)) < 0) {
 		snd_printd("unable to register control minors\n");
 		goto __error;
 	}
@@ -138,7 +137,7 @@
 	return card;
 
       __error_ctl:
-	snd_ctl_unregister(card);
+	snd_device_free_all(card, SNDRV_DEV_CMD_PRE);
       __error:
 	kfree(card);
       	return NULL;
@@ -217,8 +216,6 @@
 	/* phase 3: notify all connected devices about disconnection */
 	/* at this point, they cannot respond to any calls except release() */
 
-	snd_ctl_disconnect(card);
-
 #if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
 	if (snd_mixer_oss_notify_callback)
 		snd_mixer_oss_notify_callback(card, SND_MIXER_OSS_NOTIFY_DISCONNECT);
@@ -251,7 +248,6 @@
 		return -EINVAL;
 	write_lock(&snd_card_rwlock);
 	snd_cards[card->number] = NULL;
-	snd_cards_count--;
 	write_unlock(&snd_card_rwlock);
 
 #ifdef CONFIG_PM
@@ -279,10 +275,6 @@
 		snd_printk(KERN_ERR "unable to free all devices (normal)\n");
 		/* Fatal, but this situation should never occur */
 	}
-	if (snd_ctl_unregister(card) < 0) {
-		snd_printk(KERN_ERR "unable to unregister control minors\n");
-		/* Not fatal error */
-	}
 	if (snd_device_free_all(card, SNDRV_DEV_CMD_POST) < 0) {
 		snd_printk(KERN_ERR "unable to free all devices (post)\n");
 		/* Fatal, but this situation should never occur */
@@ -441,7 +433,6 @@
 	if (card->id[0] == '\0')
 		choose_default_id(card);
 	snd_cards[card->number] = card;
-	snd_cards_count++;
 	write_unlock(&snd_card_rwlock);
 	if ((err = snd_info_card_register(card)) < 0) {
 		snd_printd("unable to create card info\n");
@@ -665,12 +656,11 @@
 	spin_unlock(&card->files_lock);
 	if (card->files == NULL)
 		wake_up(&card->shutdown_sleep);
-	if (mfile) {
-		kfree(mfile);
-	} else {
+	if (!mfile) {
 		snd_printk(KERN_ERR "ALSA card file remove problem (%p)\n", file);
 		return -ENOENT;
 	}
+	kfree(mfile);
 	return 0;
 }
 
@@ -745,12 +735,18 @@
 
 	switch (rqst) {
 	case PM_SUSPEND:
+		if (card->power_state == SNDRV_CTL_POWER_D3hot)
+			break;
 		/* FIXME: the correct state value? */
 		card->pm_suspend(card, 0);
+		snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
 		break;
 	case PM_RESUME:
+		if (card->power_state == SNDRV_CTL_POWER_D0)
+			break;
 		/* FIXME: the correct state value? */
 		card->pm_resume(card, 0);
+		snd_power_change_state(card, SNDRV_CTL_POWER_D0);
 		break;
 	}
 	return 0;
@@ -793,6 +789,7 @@
 	/* FIXME: correct state value? */
 	err = card->pm_suspend(card, 0);
 	pci_save_state(dev);
+	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
 	return err;
 }
 
@@ -806,7 +803,9 @@
 	/* restore the PCI config space */
 	pci_restore_state(dev);
 	/* FIXME: correct state value? */
-	return card->pm_resume(card, 0);
+	card->pm_resume(card, 0);
+	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
+	return 0;
 }
 #endif
 
diff -Nru a/sound/core/ioctl32/hwdep32.c b/sound/core/ioctl32/hwdep32.c
--- a/sound/core/ioctl32/hwdep32.c	2005-03-01 23:39:16 -08:00
+++ b/sound/core/ioctl32/hwdep32.c	2005-03-01 23:39:16 -08:00
@@ -36,24 +36,24 @@
 
 static inline int _snd_ioctl32_hwdep_dsp_image(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file, unsigned int native_ctl)
 {
-	struct sndrv_hwdep_dsp_image data;
-	struct sndrv_hwdep_dsp_image32 data32;
-	mm_segment_t oldseg;
-	int err;
+	struct sndrv_hwdep_dsp_image __user *data, *dst;
+	struct sndrv_hwdep_dsp_image32 __user *data32, *src;
+	compat_caddr_t ptr;
 
-	if (copy_from_user(&data32, (void __user *)arg, sizeof(data32)))
+	data32 = compat_ptr(arg);
+	data = compat_alloc_user_space(sizeof(*data));
+
+	/* index and name */
+	if (copy_in_user(data, data32, 4 + 64))
+		return -EFAULT;
+	if (__get_user(ptr, &data32->image) ||
+	    __put_user(compat_ptr(ptr), &data->image))
 		return -EFAULT;
-	memset(&data, 0, sizeof(data));
-	data.index = data32.index;
-	memcpy(data.name, data32.name, sizeof(data.name));
-	data.image = compat_ptr(data32.image);
-	data.length = data32.length;
-	data.driver_data = data32.driver_data;
-	oldseg = get_fs();
-	set_fs(KERNEL_DS);
-	err = file->f_op->ioctl(file->f_dentry->d_inode, file, native_ctl, (unsigned long)&data);
-	set_fs(oldseg);
-	return err;
+	src = data32;
+	dst = data;
+	COPY_CVT(length);
+	COPY_CVT(driver_data);
+	return file->f_op->ioctl(file->f_dentry->d_inode, file, native_ctl, (unsigned long)data);
 }
 
 DEFINE_ALSA_IOCTL_ENTRY(hwdep_dsp_image, hwdep_dsp_image, SNDRV_HWDEP_IOCTL_DSP_LOAD);
diff -Nru a/sound/core/ioctl32/ioctl32.c b/sound/core/ioctl32/ioctl32.c
--- a/sound/core/ioctl32/ioctl32.c	2005-03-01 23:38:52 -08:00
+++ b/sound/core/ioctl32/ioctl32.c	2005-03-01 23:38:52 -08:00
@@ -27,9 +27,11 @@
 #include <linux/fs.h>
 #include <sound/core.h>
 #include <sound/control.h>
+#include <sound/minors.h>
 #include <asm/uaccess.h>
 #include "ioctl32.h"
 
+
 /*
  * register/unregister mappers
  * exported for other modules
@@ -93,43 +95,28 @@
 	unsigned char reserved[50];
 } /* don't set packed attribute here */;
 
-#define CVT_sndrv_ctl_elem_list()\
-{\
-	COPY(offset);\
-	COPY(space);\
-	COPY(used);\
-	COPY(count);\
-	CPTR(pids);\
-}
-
 static inline int _snd_ioctl32_ctl_elem_list(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file, unsigned int native_ctl)
 {
-	struct sndrv_ctl_elem_list32 data32;
-	struct sndrv_ctl_elem_list data;
-	mm_segment_t oldseg;
+	struct sndrv_ctl_elem_list32 __user *data32;
+	struct sndrv_ctl_elem_list __user *data;
+	compat_caddr_t ptr;
 	int err;
 
-	if (copy_from_user(&data32, (void __user *)arg, sizeof(data32)))
+	data32 = compat_ptr(arg);
+	data = compat_alloc_user_space(sizeof(*data));
+
+	/* offset, space, used, count */
+	if (copy_in_user(data, data32, 4 * sizeof(u32)))
+		return -EFAULT;
+	/* pids */
+	if (__get_user(ptr, &data32->pids) ||
+	    __put_user(compat_ptr(ptr), &data->pids))
 		return -EFAULT;
-	memset(&data, 0, sizeof(data));
-	data.offset = data32.offset;
-	data.space = data32.space;
-	data.used = data32.used;
-	data.count = data32.count;
-	data.pids = compat_ptr(data32.pids);
-	oldseg = get_fs();
-	set_fs(KERNEL_DS);
-	err = file->f_op->ioctl(file->f_dentry->d_inode, file, native_ctl, (unsigned long)&data);
-	set_fs(oldseg);
+	err = file->f_op->ioctl(file->f_dentry->d_inode, file, native_ctl, (unsigned long)data);
 	if (err < 0)
 		return err;
 	/* copy the result */
-	data32.offset = data.offset;
-	data32.space = data.space;
-	data32.used = data.used;
-	data32.count = data.count;
-	//data.pids = data.pids;
-	if (copy_to_user((void __user *)arg, &data32, sizeof(data32)))
+	if (copy_in_user(data32, data, 4 * sizeof(u32)))
 		return -EFAULT;
 	return 0;
 }
@@ -170,54 +157,59 @@
 
 static inline int _snd_ioctl32_ctl_elem_info(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file, unsigned int native_ctl)
 {
-	struct sndrv_ctl_elem_info data;
-	struct sndrv_ctl_elem_info32 data32;
+	struct sndrv_ctl_elem_info __user *data, *src;
+	struct sndrv_ctl_elem_info32 __user *data32, *dst;
+	unsigned int type;
 	int err;
-	mm_segment_t oldseg;
 
-	if (copy_from_user(&data32, (void __user *)arg, sizeof(data32)))
+	data32 = compat_ptr(arg);
+	data = compat_alloc_user_space(sizeof(*data));
+
+	/* copy id */
+	if (copy_in_user(&data->id, &data32->id, sizeof(data->id)))
 		return -EFAULT;
-	memset(&data, 0, sizeof(data));
-	data.id = data32.id;
 	/* we need to copy the item index.
 	 * hope this doesn't break anything..
 	 */
-	data.value.enumerated.item = data32.value.enumerated.item;
-	oldseg = get_fs();
-	set_fs(KERNEL_DS);
-	err = file->f_op->ioctl(file->f_dentry->d_inode, file, native_ctl, (unsigned long)&data);
-	set_fs(oldseg);
+	if (copy_in_user(&data->value.enumerated.item,
+			 &data32->value.enumerated.item,
+			 sizeof(data->value.enumerated.item)))
+		return -EFAULT;
+	err = file->f_op->ioctl(file->f_dentry->d_inode, file, native_ctl, (unsigned long)data);
 	if (err < 0)
 		return err;
 	/* restore info to 32bit */
-	data32.id = data.id;
-	data32.type = data.type;
-	data32.access = data.access;
-	data32.count = data.count;
-	data32.owner = data.owner;
-	switch (data.type) {
+	/* for COPY_CVT macro */
+	src = data;
+	dst = data32;
+	/* id, type, access, count */
+	if (copy_in_user(&data32->id, &data->id, sizeof(data->id)) ||
+	    copy_in_user(&data32->type, &data->type, 3 * sizeof(u32)))
+		return -EFAULT;
+	COPY_CVT(owner);
+	__get_user(type, &data->type);
+	switch (type) {
 	case SNDRV_CTL_ELEM_TYPE_BOOLEAN:
 	case SNDRV_CTL_ELEM_TYPE_INTEGER:
-		data32.value.integer.min = data.value.integer.min;
-		data32.value.integer.max = data.value.integer.max;
-		data32.value.integer.step = data.value.integer.step;
+		COPY_CVT(value.integer.min);
+		COPY_CVT(value.integer.max);
+		COPY_CVT(value.integer.step);
 		break;
 	case SNDRV_CTL_ELEM_TYPE_INTEGER64:
-		data32.value.integer64.min = data.value.integer64.min;
-		data32.value.integer64.max = data.value.integer64.max;
-		data32.value.integer64.step = data.value.integer64.step;
+		if (copy_in_user(&data32->value.integer64,
+				 &data->value.integer64,
+				 sizeof(data->value.integer64)))
+			return -EFAULT;
 		break;
 	case SNDRV_CTL_ELEM_TYPE_ENUMERATED:
-		data32.value.enumerated.items = data.value.enumerated.items;
-		data32.value.enumerated.item = data.value.enumerated.item;
-		memcpy(data32.value.enumerated.name, data.value.enumerated.name,
-		       sizeof(data.value.enumerated.name));
+		if (copy_in_user(&data32->value.enumerated,
+				 &data->value.enumerated,
+				 sizeof(data->value.enumerated)))
+			return -EFAULT;
 		break;
 	default:
 		break;
 	}
-	if (copy_to_user((void __user *)arg, &data32, sizeof(data32)))
-		return -EFAULT;
 	return 0;
 }
 
@@ -227,153 +219,140 @@
 	struct sndrv_ctl_elem_id id;
 	unsigned int indirect;	/* bit-field causes misalignment */
         union {
-		union {
-			s32 value[128];
-			u32 value_ptr;
-		} integer;
-		union {
-			s64 value[64];
-			u32 value_ptr;
-		} integer64;
-		union {
-			u32 item[128];
-			u32 item_ptr;
-		} enumerated;
-		union {
-			unsigned char data[512];
-			u32 data_ptr;
-		} bytes;
-		struct sndrv_aes_iec958 iec958;
+		s32 integer[128];	/* integer and boolean need conversion */
+#ifndef CONFIG_X86_64
+		s64 integer64[64];	/* for alignment */
+#endif
+		unsigned char data[512];	/* others should be compatible */
         } value;
-        unsigned char reserved[128];
+        unsigned char reserved[128];	/* not used */
 };
 
 
 /* hmm, it's so hard to retrieve the value type from the control id.. */
-static int get_ctl_type(struct file *file, snd_ctl_elem_id_t *id)
+static int get_ctl_type(snd_card_t *card, snd_ctl_elem_id_t *id)
 {
-	snd_ctl_file_t *ctl;
 	snd_kcontrol_t *kctl;
 	snd_ctl_elem_info_t info;
 	int err;
 
-	ctl = file->private_data;
-
-	down_read(&ctl->card->controls_rwsem);
-	kctl = snd_ctl_find_id(ctl->card, id);
+	down_read(&card->controls_rwsem);
+	kctl = snd_ctl_find_id(card, id);
 	if (! kctl) {
-		up_read(&ctl->card->controls_rwsem);
+		up_read(&card->controls_rwsem);
 		return -ENXIO;
 	}
 	info.id = *id;
 	err = kctl->info(kctl, &info);
-	up_read(&ctl->card->controls_rwsem);
+	up_read(&card->controls_rwsem);
 	if (err >= 0)
 		err = info.type;
 	return err;
 }
 
+extern int snd_major;
 
 static inline int _snd_ioctl32_ctl_elem_value(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file, unsigned int native_ctl)
 {
 	struct sndrv_ctl_elem_value *data;
-	struct sndrv_ctl_elem_value32 *data32;
-	int err, i;
+	struct sndrv_ctl_elem_value32 __user *data32;
+	snd_ctl_file_t *ctl;
+	int err, i, indirect;
 	int type;
-	mm_segment_t oldseg;
 
-	/* FIXME: check the sane ioctl.. */
+	/* sanity check */
+	if (imajor(file->f_dentry->d_inode) != snd_major ||
+	    SNDRV_MINOR_DEVICE(iminor(file->f_dentry->d_inode)) != SNDRV_MINOR_CONTROL)
+		return -ENOTTY;
+
+	if ((ctl = file->private_data) == NULL)
+		return -ENOTTY;
 
-	data = kmalloc(sizeof(*data), GFP_KERNEL);
-	data32 = kmalloc(sizeof(*data32), GFP_KERNEL);
-	if (data == NULL || data32 == NULL) {
-		err = -ENOMEM;
+	data32 = compat_ptr(arg);
+	data = kcalloc(1, sizeof(*data), GFP_KERNEL);
+	if (data == NULL)
+		return -ENOMEM;
+
+	if (copy_from_user(&data->id, &data32->id, sizeof(data->id))) {
+		err = -EFAULT;
 		goto __end;
 	}
-
-	if (copy_from_user(data32, (void __user *)arg, sizeof(*data32))) {
+	if (__get_user(indirect, &data32->indirect)) {
 		err = -EFAULT;
 		goto __end;
 	}
-	memset(data, 0, sizeof(*data));
-	data->id = data32->id;
-	data->indirect = data32->indirect;
-	if (data->indirect) /* FIXME: this is not correct for long arrays */
-		data->value.integer.value_ptr = compat_ptr(data32->value.integer.value_ptr);
-	type = get_ctl_type(file, &data->id);
+	/* FIXME: indirect access is not supported */
+	if (indirect) {
+		err = -EINVAL;
+		goto __end;
+	}
+	type = get_ctl_type(ctl->card, &data->id);
 	if (type < 0) {
 		err = type;
 		goto __end;
 	}
-	if (! data->indirect) {
-		switch (type) {
-		case SNDRV_CTL_ELEM_TYPE_BOOLEAN:
-		case SNDRV_CTL_ELEM_TYPE_INTEGER:
-			for (i = 0; i < 128; i++)
-				data->value.integer.value[i] = data32->value.integer.value[i];
-			break;
-		case SNDRV_CTL_ELEM_TYPE_INTEGER64:
-			for (i = 0; i < 64; i++)
-				data->value.integer64.value[i] = data32->value.integer64.value[i];
-			break;
-		case SNDRV_CTL_ELEM_TYPE_ENUMERATED:
-			for (i = 0; i < 128; i++)
-				data->value.enumerated.item[i] = data32->value.enumerated.item[i];
-			break;
-		case SNDRV_CTL_ELEM_TYPE_BYTES:
-			memcpy(data->value.bytes.data, data32->value.bytes.data,
-			       sizeof(data->value.bytes.data));
-			break;
-		case SNDRV_CTL_ELEM_TYPE_IEC958:
-			data->value.iec958 = data32->value.iec958;
-			break;
-		default:
-			printk("unknown type %d\n", type);
-			break;
+
+	switch (type) {
+	case SNDRV_CTL_ELEM_TYPE_BOOLEAN:
+	case SNDRV_CTL_ELEM_TYPE_INTEGER:
+		for (i = 0; i < 128; i++) {
+			int val;
+			if (__get_user(val, &data32->value.integer[i])) {
+				err = -EFAULT;
+				goto __end;
+			}
+			data->value.integer.value[i] = val;
 		}
+		break;
+	case SNDRV_CTL_ELEM_TYPE_INTEGER64:
+	case SNDRV_CTL_ELEM_TYPE_ENUMERATED:
+	case SNDRV_CTL_ELEM_TYPE_BYTES:
+	case SNDRV_CTL_ELEM_TYPE_IEC958:
+		if (__copy_from_user(data->value.bytes.data,
+				     data32->value.data,
+				     sizeof(data32->value.data))) {
+			err = -EFAULT;
+			goto __end;
+		}
+		break;
+	default:
+		printk(KERN_ERR "snd_ioctl32_ctl_elem_value: unknown type %d\n", type);
+		err = -EINVAL;
+		goto __end;
 	}
 
-	oldseg = get_fs();
-	set_fs(KERNEL_DS);
-	err = file->f_op->ioctl(file->f_dentry->d_inode, file, native_ctl, (unsigned long)data);
-	set_fs(oldseg);
+	if (native_ctl == SNDRV_CTL_IOCTL_ELEM_READ)
+		err = snd_ctl_elem_read(ctl->card, data);
+	else
+		err = snd_ctl_elem_write(ctl->card, ctl, data);
 	if (err < 0)
 		goto __end;
 	/* restore info to 32bit */
-	if (! data->indirect) {
-		switch (type) {
-		case SNDRV_CTL_ELEM_TYPE_BOOLEAN:
-		case SNDRV_CTL_ELEM_TYPE_INTEGER:
-			for (i = 0; i < 128; i++)
-				data32->value.integer.value[i] = data->value.integer.value[i];
-			break;
-		case SNDRV_CTL_ELEM_TYPE_INTEGER64:
-			for (i = 0; i < 64; i++)
-				data32->value.integer64.value[i] = data->value.integer64.value[i];
-			break;
-		case SNDRV_CTL_ELEM_TYPE_ENUMERATED:
-			for (i = 0; i < 128; i++)
-				data32->value.enumerated.item[i] = data->value.enumerated.item[i];
-			break;
-		case SNDRV_CTL_ELEM_TYPE_BYTES:
-			memcpy(data32->value.bytes.data, data->value.bytes.data,
-			       sizeof(data->value.bytes.data));
-			break;
-		case SNDRV_CTL_ELEM_TYPE_IEC958:
-			data32->value.iec958 = data->value.iec958;
-			break;
-		default:
-			break;
+	switch (type) {
+	case SNDRV_CTL_ELEM_TYPE_BOOLEAN:
+	case SNDRV_CTL_ELEM_TYPE_INTEGER:
+		for (i = 0; i < 128; i++) {
+			int val;
+			val = data->value.integer.value[i];
+			if (__put_user(val, &data32->value.integer[i])) {
+				err = -EFAULT;
+				goto __end;
+			}
 		}
+		break;
+	default:
+		if (__copy_to_user(data32->value.data,
+				   data->value.bytes.data,
+				   sizeof(data32->value.data))) {
+			err = -EFAULT;
+			goto __end;
+		}
+		break;
+		break;
 	}
 	err = 0;
-	if (copy_to_user((void __user *)arg, data32, sizeof(*data32)))
-		err = -EFAULT;
       __end:
-      	if (data32)
-      		kfree(data32);
-	if (data)
-		kfree(data);
+	kfree(data);
 	return err;
 }
 
diff -Nru a/sound/core/ioctl32/ioctl32.h b/sound/core/ioctl32/ioctl32.h
--- a/sound/core/ioctl32/ioctl32.h	2005-03-01 23:38:56 -08:00
+++ b/sound/core/ioctl32/ioctl32.h	2005-03-01 23:38:56 -08:00
@@ -28,20 +28,37 @@
 
 #include <linux/compat.h>
 
-#define COPY(x)  (dst->x = src->x)
-#define CPTR(x)	 (dst->x = compat_ptr(src->x))
+#define COPY(x) \
+	do { \
+		if (copy_in_user(&dst->x, &src->x, sizeof(dst->x))) \
+			return -EFAULT; \
+	} while (0)
+
+#define COPY_ARRAY(x) \
+	do { \
+		if (copy_in_user(dst->x, src->x, sizeof(dst->x))) \
+			return -EFAULT; \
+	} while (0)
+
+#define COPY_CVT(x) \
+	do { \
+		__typeof__(src->x) __val_tmp; \
+		if (get_user(__val_tmp, &src->x) || \
+		    put_user(__val_tmp, &dst->x))\
+			return -EFAULT; \
+	} while (0)
 
 #define convert_from_32(type, dstp, srcp)\
 {\
-	struct sndrv_##type *dst = dstp;\
-	struct sndrv_##type##32 *src = srcp;\
+	struct sndrv_##type __user *dst = dstp;\
+	struct sndrv_##type##32 __user *src = srcp;\
 	CVT_##sndrv_##type();\
 }
 
 #define convert_to_32(type, dstp, srcp)\
 {\
-	struct sndrv_##type *src = srcp;\
-	struct sndrv_##type##32 *dst = dstp;\
+	struct sndrv_##type __user *src = srcp;\
+	struct sndrv_##type##32 __user *dst = dstp;\
 	CVT_##sndrv_##type();\
 }
 
@@ -49,65 +66,19 @@
 #define DEFINE_ALSA_IOCTL(type) \
 static inline int _snd_ioctl32_##type(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file, unsigned int native_ctl)\
 {\
-	struct sndrv_##type##32 data32;\
-	struct sndrv_##type data;\
-	mm_segment_t oldseg;\
-	int err;\
-	if (copy_from_user(&data32, (void __user *)arg, sizeof(data32)))\
-		return -EFAULT;\
-	memset(&data, 0, sizeof(data));\
-	convert_from_32(type, &data, &data32);\
-	oldseg = get_fs();\
-	set_fs(KERNEL_DS);\
-	err = file->f_op->ioctl(file->f_dentry->d_inode, file, native_ctl, (unsigned long)&data);\
-	set_fs(oldseg);\
-	if (err < 0) \
-		return err;\
-	if (native_ctl & (_IOC_READ << _IOC_DIRSHIFT)) {\
-		convert_to_32(type, &data32, &data);\
-		if (copy_to_user((void __user *)arg, &data32, sizeof(data32)))\
-			return -EFAULT;\
-	}\
-	return 0;\
-}
-
-#define DEFINE_ALSA_IOCTL_BIG(type) \
-static inline int _snd_ioctl32_##type(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file, unsigned int native_ctl)\
-{\
-	struct sndrv_##type##32 *data32;\
-	struct sndrv_##type *data;\
-	mm_segment_t oldseg;\
+	struct sndrv_##type##32 __user *data32;\
+	struct sndrv_##type __user *data;\
 	int err;\
-	data32 = kmalloc(sizeof(*data32), GFP_KERNEL); \
-	data = kmalloc(sizeof(*data), GFP_KERNEL); \
-	if (data32 == NULL || data == NULL) { \
-		err = -ENOMEM; \
-		goto __end; \
-	}\
-	if (copy_from_user(data32, (void __user *)arg, sizeof(*data32))) { \
-		err = -EFAULT; \
-		goto __end; \
-	}\
-	memset(data, 0, sizeof(*data));\
+	data32 = compat_ptr(arg);\
+	data = compat_alloc_user_space(sizeof(*data));\
 	convert_from_32(type, data, data32);\
-	oldseg = get_fs();\
-	set_fs(KERNEL_DS);\
 	err = file->f_op->ioctl(file->f_dentry->d_inode, file, native_ctl, (unsigned long)data);\
-	set_fs(oldseg);\
 	if (err < 0) \
-		goto __end;\
-	err = 0;\
+		return err;\
 	if (native_ctl & (_IOC_READ << _IOC_DIRSHIFT)) {\
 		convert_to_32(type, data32, data);\
-		if (copy_to_user((void __user *)arg, data32, sizeof(*data32)))\
-			err = -EFAULT;\
 	}\
-      __end:\
-      	if (data)\
-      		kfree(data);\
-      	if (data32)\
-      		kfree(data32);\
-	return err;\
+	return 0;\
 }
 
 #define DEFINE_ALSA_IOCTL_ENTRY(name,type,native_ctl) \
diff -Nru a/sound/core/ioctl32/pcm32.c b/sound/core/ioctl32/pcm32.c
--- a/sound/core/ioctl32/pcm32.c	2005-03-01 23:38:59 -08:00
+++ b/sound/core/ioctl32/pcm32.c	2005-03-01 23:38:59 -08:00
@@ -24,6 +24,7 @@
 #include <linux/compat.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
+#include <sound/minors.h>
 #include "ioctl32.h"
 
 
@@ -41,23 +42,15 @@
 	u32 val;
 };
 
-#define CVT_sndrv_pcm_sframes_str() { COPY(val); }
-#define CVT_sndrv_pcm_uframes_str() { COPY(val); }
+#define CVT_sndrv_pcm_sframes_str() { COPY_CVT(val); }
+#define CVT_sndrv_pcm_uframes_str() { COPY_CVT(val); }
 
 
-struct sndrv_interval32 {
-	u32 min, max;
-	unsigned int openmin:1,
-		     openmax:1,
-		     integer:1,
-		     empty:1;
-};
-
 struct sndrv_pcm_hw_params32 {
 	u32 flags;
 	struct sndrv_mask masks[SNDRV_PCM_HW_PARAM_LAST_MASK - SNDRV_PCM_HW_PARAM_FIRST_MASK + 1]; /* this must be identical */
 	struct sndrv_mask mres[5];	/* reserved masks */
-	struct sndrv_interval32 intervals[SNDRV_PCM_HW_PARAM_LAST_INTERVAL - SNDRV_PCM_HW_PARAM_FIRST_INTERVAL + 1];
+	struct sndrv_interval intervals[SNDRV_PCM_HW_PARAM_LAST_INTERVAL - SNDRV_PCM_HW_PARAM_FIRST_INTERVAL + 1];
 	struct sndrv_interval ires[9];	/* reserved intervals */
 	u32 rmask;
 	u32 cmask;
@@ -69,31 +62,6 @@
 	unsigned char reserved[64];
 } __attribute__((packed));
 
-#define numberof(array) ARRAY_SIZE(array)
-
-#define CVT_sndrv_pcm_hw_params()\
-{\
-	unsigned int i;\
-	COPY(flags);\
-	for (i = 0; i < numberof(dst->masks); i++)\
-		COPY(masks[i]);\
-	for (i = 0; i < numberof(dst->intervals); i++) {\
-		COPY(intervals[i].min);\
-		COPY(intervals[i].max);\
-		COPY(intervals[i].openmin);\
-		COPY(intervals[i].openmax);\
-		COPY(intervals[i].integer);\
-		COPY(intervals[i].empty);\
-	}\
-	COPY(rmask);\
-	COPY(cmask);\
-	COPY(info);\
-	COPY(msbits);\
-	COPY(rate_num);\
-	COPY(rate_den);\
-	COPY(fifo_size);\
-}
-
 struct sndrv_pcm_sw_params32 {
 	s32 tstamp_mode;
 	u32 period_step;
@@ -113,13 +81,13 @@
 	COPY(tstamp_mode);\
 	COPY(period_step);\
 	COPY(sleep_min);\
-	COPY(avail_min);\
-	COPY(xfer_align);\
-	COPY(start_threshold);\
-	COPY(stop_threshold);\
-	COPY(silence_threshold);\
-	COPY(silence_size);\
-	COPY(boundary);\
+	COPY_CVT(avail_min);\
+	COPY_CVT(xfer_align);\
+	COPY_CVT(start_threshold);\
+	COPY_CVT(stop_threshold);\
+	COPY_CVT(silence_threshold);\
+	COPY_CVT(silence_size);\
+	COPY_CVT(boundary);\
 }
 
 struct sndrv_pcm_channel_info32 {
@@ -132,7 +100,7 @@
 #define CVT_sndrv_pcm_channel_info()\
 {\
 	COPY(channel);\
-	COPY(offset);\
+	COPY_CVT(offset);\
 	COPY(first);\
 	COPY(step);\
 }
@@ -154,16 +122,16 @@
 #define CVT_sndrv_pcm_status()\
 {\
 	COPY(state);\
-	COPY(trigger_tstamp.tv_sec);\
-	COPY(trigger_tstamp.tv_nsec);\
-	COPY(tstamp.tv_sec);\
-	COPY(tstamp.tv_nsec);\
-	COPY(appl_ptr);\
-	COPY(hw_ptr);\
-	COPY(delay);\
-	COPY(avail);\
-	COPY(avail_max);\
-	COPY(overrange);\
+	COPY_CVT(trigger_tstamp.tv_sec);\
+	COPY_CVT(trigger_tstamp.tv_nsec);\
+	COPY_CVT(tstamp.tv_sec);\
+	COPY_CVT(tstamp.tv_nsec);\
+	COPY_CVT(appl_ptr);\
+	COPY_CVT(hw_ptr);\
+	COPY_CVT(delay);\
+	COPY_CVT(avail);\
+	COPY_CVT(avail_max);\
+	COPY_CVT(overrange);\
 	COPY(suspended_state);\
 }
 
@@ -173,61 +141,73 @@
 DEFINE_ALSA_IOCTL(pcm_channel_info);
 DEFINE_ALSA_IOCTL(pcm_status);
 
-/* recalcuate the boundary within 32bit */
-static void recalculate_boundary(struct file *file)
+/* sanity device check */
+extern int snd_major;
+static int sanity_check_pcm(struct file *file)
 {
-	snd_pcm_file_t *pcm_file;
-	snd_pcm_substream_t *substream;
-	snd_pcm_runtime_t *runtime;
+	unsigned short minor;
+	if (imajor(file->f_dentry->d_inode) != snd_major)
+		return -ENOTTY;
+	minor = iminor(file->f_dentry->d_inode);
+	if (minor >= 256 || 
+	    minor % SNDRV_MINOR_DEVICES < SNDRV_MINOR_PCM_PLAYBACK)
+		return -ENOTTY;
+	return 0;
+}
 
-	/* FIXME: need to check whether fop->ioctl is sane */
-	if (! (pcm_file = file->private_data))
-		return;
-	if (! (substream = pcm_file->substream))
-		return;
-	if (! (runtime = substream->runtime))
+/* recalcuate the boundary within 32bit */
+static void recalculate_boundary(snd_pcm_runtime_t *runtime)
+{
+	if (! runtime->buffer_size)
 		return;
 	runtime->boundary = runtime->buffer_size;
 	while (runtime->boundary * 2 <= 0x7fffffffUL - runtime->buffer_size)
 		runtime->boundary *= 2;
 }
 
-static inline int _snd_ioctl32_pcm_hw_params(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file, unsigned int native_ctl)
+/* both for HW_PARAMS and HW_REFINE */
+static int _snd_ioctl32_pcm_hw_params(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file, unsigned int native_ctl)
 {
-	struct sndrv_pcm_hw_params32 *data32;
+	struct sndrv_pcm_hw_params32 __user *data32;
 	struct sndrv_pcm_hw_params *data;
-	mm_segment_t oldseg;
+	snd_pcm_file_t *pcm_file;
+	snd_pcm_substream_t *substream;
+	snd_pcm_runtime_t *runtime;
 	int err;
 
-	data32 = kmalloc(sizeof(*data32), GFP_KERNEL);
+	if (sanity_check_pcm(file))
+		return -ENOTTY;
+	if (! (pcm_file = file->private_data))
+		return -ENOTTY;
+	if (! (substream = pcm_file->substream))
+		return -ENOTTY;
+	if (! (runtime = substream->runtime))
+		return -ENOTTY;
+
+	data32 = compat_ptr(arg);
 	data = kmalloc(sizeof(*data), GFP_KERNEL);
-	if (data32 == NULL || data == NULL) {
-		err = -ENOMEM;
-		goto __end;
-	}
-	if (copy_from_user(data32, (void __user *)arg, sizeof(*data32))) {
+	if (data == NULL)
+		return -ENOMEM;
+	if (copy_from_user(data, data32, sizeof(*data32))) {
 		err = -EFAULT;
-		goto __end;
+		goto error;
 	}
-	memset(data, 0, sizeof(*data));
-	convert_from_32(pcm_hw_params, data, data32);
-	oldseg = get_fs();
-	set_fs(KERNEL_DS);
-	err = file->f_op->ioctl(file->f_dentry->d_inode, file, native_ctl, (unsigned long)data);
-	set_fs(oldseg);
+	if (native_ctl == SNDRV_PCM_IOCTL_HW_REFINE)
+		err = snd_pcm_hw_refine(substream, data);
+	else
+		err = snd_pcm_hw_params(substream, data);
 	if (err < 0)
-		goto __end;
-	err = 0;
-	convert_to_32(pcm_hw_params, data32, data);
-	if (copy_to_user((void __user *)arg, data32, sizeof(*data32)))
+		goto error;
+	if (copy_to_user(data32, data, sizeof(*data32)) ||
+	    __put_user((u32)data->fifo_size, &data32->fifo_size)) {
 		err = -EFAULT;
-	else
-		recalculate_boundary(file);
-      __end:
-      	if (data)
-      		kfree(data);
-      	if (data32)
-      		kfree(data32);
+		goto error;
+	}
+
+	if (native_ctl == SNDRV_PCM_IOCTL_HW_PARAMS)
+		recalculate_boundary(runtime);
+ error:
+	kfree(data);
 	return err;
 }
 
@@ -240,27 +220,27 @@
 	u32 frames;
 } __attribute__((packed));
 
-static inline int _snd_ioctl32_xferi(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file, unsigned int native_ctl)
+static int _snd_ioctl32_xferi(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file, unsigned int native_ctl)
 {
 	struct sndrv_xferi32 data32;
-	struct sndrv_xferi data;
-	mm_segment_t oldseg;
+	struct sndrv_xferi __user *data;
+	snd_pcm_sframes_t result;
 	int err;
 
 	if (copy_from_user(&data32, (void __user *)arg, sizeof(data32)))
 		return -EFAULT;
-	memset(&data, 0, sizeof(data));
-	data.result = data32.result;
-	data.buf = compat_ptr(data32.buf);
-	data.frames = data32.frames;
-	oldseg = get_fs();
-	set_fs(KERNEL_DS);
-	err = file->f_op->ioctl(file->f_dentry->d_inode, file, native_ctl, (unsigned long)&data);
-	set_fs(oldseg);
+	data = compat_alloc_user_space(sizeof(*data));
+	if (put_user((snd_pcm_sframes_t)data32.result, &data->result) ||
+	    __put_user(compat_ptr(data32.buf), &data->buf) ||
+	    __put_user((snd_pcm_uframes_t)data32.frames, &data->frames))
+		return -EFAULT;
+	err = file->f_op->ioctl(file->f_dentry->d_inode, file, native_ctl, (unsigned long)data);
 	if (err < 0)
 		return err;
 	/* copy the result */
-	data32.result = data.result;
+	if (__get_user(result, &data->result))
+		return -EFAULT;
+	data32.result = result;
 	if (copy_to_user((void __user *)arg, &data32, sizeof(data32)))
 		return -EFAULT;
 	return 0;
@@ -280,22 +260,24 @@
  * handler there expands again the same 128 pointers on stack, so it is better
  * to handle the function (calling pcm_readv/writev) directly in this handler.
  */
-static inline int _snd_ioctl32_xfern(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file, unsigned int native_ctl)
+static int _snd_ioctl32_xfern(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file, unsigned int native_ctl)
 {
 	snd_pcm_file_t *pcm_file;
 	snd_pcm_substream_t *substream;
+	struct sndrv_xfern32 __user *srcptr = compat_ptr(arg);
 	struct sndrv_xfern32 data32;
-	struct sndrv_xfern32 __user *srcptr = (void __user *)arg;
-	void __user **bufs = NULL;
+	void __user **bufs;
 	int err = 0, ch, i;
 	u32 __user *bufptr;
-	mm_segment_t oldseg;
-
-	/* FIXME: need to check whether fop->ioctl is sane */
 
-	pcm_file = file->private_data;
-	substream = pcm_file->substream;
-	snd_assert(substream != NULL && substream->runtime, return -ENXIO);
+	if (sanity_check_pcm(file))
+		return -ENOTTY;
+	if (! (pcm_file = file->private_data))
+		return -ENOTTY;
+	if (! (substream = pcm_file->substream))
+		return -ENOTTY;
+	if (! substream->runtime)
+		return -ENOTTY;
 
 	/* check validty of the command */
 	switch (native_ctl) {
@@ -312,22 +294,21 @@
 	}
 	if ((ch = substream->runtime->channels) > 128)
 		return -EINVAL;
-	if (get_user(data32.frames, &srcptr->frames))
+	if (copy_from_user(&data32, (void __user *)arg, sizeof(data32)))
 		return -EFAULT;
-	__get_user(data32.bufs, &srcptr->bufs);
 	bufptr = compat_ptr(data32.bufs);
-	bufs = kmalloc(sizeof(void *) * 128, GFP_KERNEL);
+	bufs = kmalloc(sizeof(void __user *) * ch, GFP_KERNEL);
 	if (bufs == NULL)
 		return -ENOMEM;
 	for (i = 0; i < ch; i++) {
 		u32 ptr;
-		if (get_user(ptr, bufptr))
+		if (get_user(ptr, bufptr)) {
+			kfree(bufs);
 			return -EFAULT;
+		}
 		bufs[ch] = compat_ptr(ptr);
 		bufptr++;
 	}
-	oldseg = get_fs();
-	set_fs(KERNEL_DS);
 	switch (native_ctl) {
 	case SNDRV_PCM_IOCTL_WRITEN_FRAMES:
 		err = snd_pcm_lib_writev(substream, bufs, data32.frames);
@@ -336,109 +317,15 @@
 		err = snd_pcm_lib_readv(substream, bufs, data32.frames);
 		break;
 	}
-	set_fs(oldseg);
 	if (err >= 0) {
 		if (put_user(err, &srcptr->result))
 			err = -EFAULT;
 	}
 	kfree(bufs);
-	return 0;
-}
-
-
-struct sndrv_pcm_hw_params_old32 {
-	u32 flags;
-	u32 masks[SNDRV_PCM_HW_PARAM_SUBFORMAT -
-			   SNDRV_PCM_HW_PARAM_ACCESS + 1];
-	struct sndrv_interval32 intervals[SNDRV_PCM_HW_PARAM_TICK_TIME -
-					SNDRV_PCM_HW_PARAM_SAMPLE_BITS + 1];
-	u32 rmask;
-	u32 cmask;
-	u32 info;
-	u32 msbits;
-	u32 rate_num;
-	u32 rate_den;
-	u32 fifo_size;
-	unsigned char reserved[64];
-} __attribute__((packed));
-
-#define __OLD_TO_NEW_MASK(x) ((x&7)|((x&0x07fffff8)<<5))
-#define __NEW_TO_OLD_MASK(x) ((x&7)|((x&0xffffff00)>>5))
-
-static void snd_pcm_hw_convert_from_old_params(snd_pcm_hw_params_t *params, struct sndrv_pcm_hw_params_old32 *oparams)
-{
-	unsigned int i;
-
-	memset(params, 0, sizeof(*params));
-	params->flags = oparams->flags;
-	for (i = 0; i < ARRAY_SIZE(oparams->masks); i++)
-		params->masks[i].bits[0] = oparams->masks[i];
-	memcpy(params->intervals, oparams->intervals, sizeof(oparams->intervals));
-	params->rmask = __OLD_TO_NEW_MASK(oparams->rmask);
-	params->cmask = __OLD_TO_NEW_MASK(oparams->cmask);
-	params->info = oparams->info;
-	params->msbits = oparams->msbits;
-	params->rate_num = oparams->rate_num;
-	params->rate_den = oparams->rate_den;
-	params->fifo_size = oparams->fifo_size;
-}
-
-static void snd_pcm_hw_convert_to_old_params(struct sndrv_pcm_hw_params_old32 *oparams, snd_pcm_hw_params_t *params)
-{
-	unsigned int i;
-
-	memset(oparams, 0, sizeof(*oparams));
-	oparams->flags = params->flags;
-	for (i = 0; i < ARRAY_SIZE(oparams->masks); i++)
-		oparams->masks[i] = params->masks[i].bits[0];
-	memcpy(oparams->intervals, params->intervals, sizeof(oparams->intervals));
-	oparams->rmask = __NEW_TO_OLD_MASK(params->rmask);
-	oparams->cmask = __NEW_TO_OLD_MASK(params->cmask);
-	oparams->info = params->info;
-	oparams->msbits = params->msbits;
-	oparams->rate_num = params->rate_num;
-	oparams->rate_den = params->rate_den;
-	oparams->fifo_size = params->fifo_size;
-}
-
-static inline int _snd_ioctl32_pcm_hw_params_old(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file, unsigned int native_ctl)
-{
-	struct sndrv_pcm_hw_params_old32 *data32;
-	struct sndrv_pcm_hw_params *data;
-	mm_segment_t oldseg;
-	int err;
-
-	data32 = kcalloc(1, sizeof(*data32), GFP_KERNEL);
-	data = kcalloc(1, sizeof(*data), GFP_KERNEL);
-	if (data32 == NULL || data == NULL) {
-		err = -ENOMEM;
-		goto __end;
-	}
-	if (copy_from_user(data32, (void __user *)arg, sizeof(*data32))) {
-		err = -EFAULT;
-		goto __end;
-	}
-	snd_pcm_hw_convert_from_old_params(data, data32);
-	oldseg = get_fs();
-	set_fs(KERNEL_DS);
-	err = file->f_op->ioctl(file->f_dentry->d_inode, file, native_ctl, (unsigned long)data);
-	set_fs(oldseg);
-	if (err < 0)
-		goto __end;
-	snd_pcm_hw_convert_to_old_params(data32, data);
-	err = 0;
-	if (copy_to_user((void __user *)arg, data32, sizeof(*data32)))
-		err = -EFAULT;
-	else
-		recalculate_boundary(file);
-      __end:
-      	if (data)
-      		kfree(data);
-      	if (data32)
-      		kfree(data32);
 	return err;
 }
 
+
 struct sndrv_pcm_mmap_status32 {
 	s32 state;
 	s32 pad1;
@@ -469,15 +356,15 @@
 	COPY(flags);\
 	COPY(s.status.state);\
 	COPY(s.status.pad1);\
-	COPY(s.status.hw_ptr);\
-	COPY(s.status.tstamp.tv_sec);\
-	COPY(s.status.tstamp.tv_nsec);\
+	COPY_CVT(s.status.hw_ptr);\
+	COPY_CVT(s.status.tstamp.tv_sec);\
+	COPY_CVT(s.status.tstamp.tv_nsec);\
 	COPY(s.status.suspended_state);\
-	COPY(c.control.appl_ptr);\
-	COPY(c.control.avail_min);\
+	COPY_CVT(c.control.appl_ptr);\
+	COPY_CVT(c.control.avail_min);\
 }
 
-DEFINE_ALSA_IOCTL_BIG(pcm_sync_ptr);
+DEFINE_ALSA_IOCTL(pcm_sync_ptr);
 
 /*
  */
@@ -485,12 +372,11 @@
 DEFINE_ALSA_IOCTL_ENTRY(pcm_hw_refine, pcm_hw_params, SNDRV_PCM_IOCTL_HW_REFINE);
 DEFINE_ALSA_IOCTL_ENTRY(pcm_hw_params, pcm_hw_params, SNDRV_PCM_IOCTL_HW_PARAMS);
 DEFINE_ALSA_IOCTL_ENTRY(pcm_sw_params, pcm_sw_params, SNDRV_PCM_IOCTL_SW_PARAMS);
-DEFINE_ALSA_IOCTL_ENTRY(pcm_hw_refine_old, pcm_hw_params_old, SNDRV_PCM_IOCTL_HW_REFINE);
-DEFINE_ALSA_IOCTL_ENTRY(pcm_hw_params_old, pcm_hw_params_old, SNDRV_PCM_IOCTL_HW_PARAMS);
 DEFINE_ALSA_IOCTL_ENTRY(pcm_status, pcm_status, SNDRV_PCM_IOCTL_STATUS);
 DEFINE_ALSA_IOCTL_ENTRY(pcm_delay, pcm_sframes_str, SNDRV_PCM_IOCTL_DELAY);
 DEFINE_ALSA_IOCTL_ENTRY(pcm_channel_info, pcm_channel_info, SNDRV_PCM_IOCTL_CHANNEL_INFO);
 DEFINE_ALSA_IOCTL_ENTRY(pcm_rewind, pcm_uframes_str, SNDRV_PCM_IOCTL_REWIND);
+DEFINE_ALSA_IOCTL_ENTRY(pcm_forward, pcm_uframes_str, SNDRV_PCM_IOCTL_FORWARD);
 DEFINE_ALSA_IOCTL_ENTRY(pcm_readi, xferi, SNDRV_PCM_IOCTL_READI_FRAMES);
 DEFINE_ALSA_IOCTL_ENTRY(pcm_writei, xferi, SNDRV_PCM_IOCTL_WRITEI_FRAMES);
 DEFINE_ALSA_IOCTL_ENTRY(pcm_readn, xfern, SNDRV_PCM_IOCTL_READN_FRAMES);
@@ -534,12 +420,11 @@
 	SNDRV_PCM_IOCTL_DELAY32 = _IOR('A', 0x21, s32),
 	SNDRV_PCM_IOCTL_CHANNEL_INFO32 = _IOR('A', 0x32, struct sndrv_pcm_channel_info32),
 	SNDRV_PCM_IOCTL_REWIND32 = _IOW('A', 0x46, u32),
+	SNDRV_PCM_IOCTL_FORWARD32 = _IOW('A', 0x49, u32),
 	SNDRV_PCM_IOCTL_WRITEI_FRAMES32 = _IOW('A', 0x50, struct sndrv_xferi32),
 	SNDRV_PCM_IOCTL_READI_FRAMES32 = _IOR('A', 0x51, struct sndrv_xferi32),
 	SNDRV_PCM_IOCTL_WRITEN_FRAMES32 = _IOW('A', 0x52, struct sndrv_xfern32),
 	SNDRV_PCM_IOCTL_READN_FRAMES32 = _IOR('A', 0x53, struct sndrv_xfern32),
-	SNDRV_PCM_IOCTL_HW_REFINE_OLD32 = _IOWR('A', 0x10, struct sndrv_pcm_hw_params_old32),
-	SNDRV_PCM_IOCTL_HW_PARAMS_OLD32 = _IOWR('A', 0x11, struct sndrv_pcm_hw_params_old32),
 	SNDRV_PCM_IOCTL_SYNC_PTR32 = _IOWR('A', 0x23, struct sndrv_pcm_sync_ptr32),
 
 };
@@ -551,8 +436,6 @@
 	MAP_COMPAT(SNDRV_PCM_IOCTL_TSTAMP),
 	{ SNDRV_PCM_IOCTL_HW_REFINE32, AP(pcm_hw_refine) },
 	{ SNDRV_PCM_IOCTL_HW_PARAMS32, AP(pcm_hw_params) },
-	{ SNDRV_PCM_IOCTL_HW_REFINE_OLD32, AP(pcm_hw_refine_old) },
-	{ SNDRV_PCM_IOCTL_HW_PARAMS_OLD32, AP(pcm_hw_params_old) },
 	MAP_COMPAT(SNDRV_PCM_IOCTL_HW_FREE),
 	{ SNDRV_PCM_IOCTL_SW_PARAMS32, AP(pcm_sw_params) },
 	{ SNDRV_PCM_IOCTL_STATUS32, AP(pcm_status) },
@@ -569,6 +452,7 @@
 	{ SNDRV_PCM_IOCTL_REWIND32, AP(pcm_rewind) },
 	MAP_COMPAT(SNDRV_PCM_IOCTL_RESUME),
 	MAP_COMPAT(SNDRV_PCM_IOCTL_XRUN),
+	{ SNDRV_PCM_IOCTL_FORWARD32, AP(pcm_forward) },
 	{ SNDRV_PCM_IOCTL_WRITEI_FRAMES32, AP(pcm_writei) },
 	{ SNDRV_PCM_IOCTL_READI_FRAMES32, AP(pcm_readi) },
 	{ SNDRV_PCM_IOCTL_WRITEN_FRAMES32, AP(pcm_writen) },
diff -Nru a/sound/core/ioctl32/rawmidi32.c b/sound/core/ioctl32/rawmidi32.c
--- a/sound/core/ioctl32/rawmidi32.c	2005-03-01 23:38:57 -08:00
+++ b/sound/core/ioctl32/rawmidi32.c	2005-03-01 23:38:57 -08:00
@@ -38,9 +38,11 @@
 #define CVT_sndrv_rawmidi_params()\
 {\
 	COPY(stream);\
-	COPY(buffer_size);\
-	COPY(avail_min);\
-	COPY(no_active_sensing);\
+	COPY_CVT(buffer_size);\
+	COPY_CVT(avail_min);\
+	if (copy_in_user(((size_t __user *)&dst->avail_min + 1),\
+			 ((size_t __user *)&src->avail_min + 1), 4)) \
+		return -EFAULT;\
 }
 
 struct sndrv_rawmidi_status32 {
@@ -54,10 +56,10 @@
 #define CVT_sndrv_rawmidi_status()\
 {\
 	COPY(stream);\
-	COPY(tstamp.tv_sec);\
-	COPY(tstamp.tv_nsec);\
-	COPY(avail);\
-	COPY(xruns);\
+	COPY_CVT(tstamp.tv_sec);\
+	COPY_CVT(tstamp.tv_nsec);\
+	COPY_CVT(avail);\
+	COPY_CVT(xruns);\
 }
 
 DEFINE_ALSA_IOCTL(rawmidi_params);
diff -Nru a/sound/core/ioctl32/seq32.c b/sound/core/ioctl32/seq32.c
--- a/sound/core/ioctl32/seq32.c	2005-03-01 23:39:17 -08:00
+++ b/sound/core/ioctl32/seq32.c	2005-03-01 23:39:17 -08:00
@@ -42,13 +42,14 @@
 
 	u32 kernel;			/* reserved for kernel use (must be NULL) */
 	u32 flags;		/* misc. conditioning */
-	char reserved[60];		/* for future use */
+	unsigned char time_queue;	/* queue # for timestamping */
+	char reserved[59];		/* for future use */
 };
 
 #define CVT_sndrv_seq_port_info()\
 {\
 	COPY(addr);\
-	memcpy(dst->name, src->name, sizeof(dst->name));\
+	COPY_ARRAY(name);\
 	COPY(capability);\
 	COPY(type);\
 	COPY(midi_channels);\
@@ -57,6 +58,7 @@
 	COPY(read_use);\
 	COPY(write_use);\
 	COPY(flags);\
+	COPY(time_queue);\
 }
 
 DEFINE_ALSA_IOCTL(seq_port_info);
diff -Nru a/sound/core/ioctl32/timer32.c b/sound/core/ioctl32/timer32.c
--- a/sound/core/ioctl32/timer32.c	2005-03-01 23:38:58 -08:00
+++ b/sound/core/ioctl32/timer32.c	2005-03-01 23:38:58 -08:00
@@ -41,9 +41,9 @@
 {\
 	COPY(flags);\
 	COPY(card);\
-	memcpy(dst->id, src->id, sizeof(src->id));\
-	memcpy(dst->name, src->name, sizeof(src->name));\
-	COPY(resolution);\
+	COPY_ARRAY(id);\
+	COPY_ARRAY(name);\
+	COPY_CVT(resolution);\
 }
 
 struct sndrv_timer_status32 {
@@ -57,8 +57,8 @@
 
 #define CVT_sndrv_timer_status()\
 {\
-	COPY(tstamp.tv_sec);\
-	COPY(tstamp.tv_nsec);\
+	COPY_CVT(tstamp.tv_sec);\
+	COPY_CVT(tstamp.tv_nsec);\
 	COPY(resolution);\
 	COPY(lost);\
 	COPY(overrun);\
diff -Nru a/sound/core/memory.c b/sound/core/memory.c
--- a/sound/core/memory.c	2005-03-01 23:38:52 -08:00
+++ b/sound/core/memory.c	2005-03-01 23:38:52 -08:00
@@ -89,7 +89,7 @@
 	}
 }
 
-void *__snd_kmalloc(size_t size, int flags, void *caller)
+static void *__snd_kmalloc(size_t size, int flags, void *caller)
 {
 	unsigned long cpu_flags;
 	struct snd_alloc_track *t;
@@ -131,10 +131,8 @@
 {
 	unsigned long flags;
 	struct snd_alloc_track *t;
-	if (obj == NULL) {
-		snd_printk(KERN_WARNING "null kfree (called from %p)\n", __builtin_return_address(0));
+	if (obj == NULL)
 		return;
-	}
 	t = snd_alloc_track_entry(obj);
 	if (t->magic != KMALLOC_MAGIC) {
 		snd_printk(KERN_WARNING "bad kfree (called from %p)\n", __builtin_return_address(0));
@@ -170,10 +168,8 @@
 void snd_hidden_vfree(void *obj)
 {
 	struct snd_alloc_track *t;
-	if (obj == NULL) {
-		snd_printk(KERN_WARNING "null vfree (called from %p)\n", __builtin_return_address(0));
+	if (obj == NULL)
 		return;
-	}
 	t = snd_alloc_track_entry(obj);
 	if (t->magic != VMALLOC_MAGIC) {
 		snd_printk(KERN_ERR "bad vfree (called from %p)\n", __builtin_return_address(0));
@@ -257,7 +253,7 @@
  *
  * Returns zero if successful, or non-zero on failure.
  */
-int copy_to_user_fromio(void __user *dst, const void __iomem *src, size_t count)
+int copy_to_user_fromio(void __user *dst, const volatile void __iomem *src, size_t count)
 {
 #if defined(__i386__) || defined(CONFIG_SPARC32)
 	return copy_to_user(dst, (const void*)src, count) ? -EFAULT : 0;
@@ -267,7 +263,7 @@
 		size_t c = count;
 		if (c > sizeof(buf))
 			c = sizeof(buf);
-		memcpy_fromio(buf, src, c);
+		memcpy_fromio(buf, (void __iomem *)src, c);
 		if (copy_to_user(dst, buf, c))
 			return -EFAULT;
 		count -= c;
@@ -288,7 +284,7 @@
  *
  * Returns zero if successful, or non-zero on failure.
  */
-int copy_from_user_toio(void __iomem *dst, const void __user *src, size_t count)
+int copy_from_user_toio(volatile void __iomem *dst, const void __user *src, size_t count)
 {
 #if defined(__i386__) || defined(CONFIG_SPARC32)
 	return copy_from_user((void*)dst, src, count) ? -EFAULT : 0;
diff -Nru a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c
--- a/sound/core/oss/mixer_oss.c	2005-03-01 23:39:07 -08:00
+++ b/sound/core/oss/mixer_oss.c	2005-03-01 23:39:07 -08:00
@@ -360,8 +360,8 @@
 }
 
 /* FIXME: need to unlock BKL to allow preemption */
-int snd_mixer_oss_ioctl(struct inode *inode, struct file *file,
-			unsigned int cmd, unsigned long arg)
+static int snd_mixer_oss_ioctl(struct inode *inode, struct file *file,
+			       unsigned int cmd, unsigned long arg)
 {
 	int err;
 	/* FIXME: need to unlock BKL to allow preemption */
@@ -527,10 +527,8 @@
 		*right = snd_mixer_oss_conv1(uctl->value.integer.value[1], uinfo->value.integer.min, uinfo->value.integer.max, &pslot->volume[1]);
       __unalloc:
 	up_read(&card->controls_rwsem);
-      	if (uctl)
-      		kfree(uctl);
-      	if (uinfo)
-      		kfree(uinfo);
+      	kfree(uctl);
+      	kfree(uinfo);
 }
 
 static void snd_mixer_oss_get_volume1_sw(snd_mixer_oss_file_t *fmixer,
@@ -566,10 +564,8 @@
 		*right = 0;
       __unalloc:
 	up_read(&card->controls_rwsem);
-      	if (uctl)
-      		kfree(uctl);
-      	if (uinfo)
-		kfree(uinfo);
+      	kfree(uctl);
+	kfree(uinfo);
 }
 
 static int snd_mixer_oss_get_volume1(snd_mixer_oss_file_t *fmixer,
@@ -628,10 +624,8 @@
 		snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id);
       __unalloc:
 	up_read(&card->controls_rwsem);
-      	if (uctl)
-      		kfree(uctl);
-      	if (uinfo)
-		kfree(uinfo);
+      	kfree(uctl);
+	kfree(uinfo);
 }
 
 static void snd_mixer_oss_put_volume1_sw(snd_mixer_oss_file_t *fmixer,
@@ -673,10 +667,8 @@
 		snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id);
       __unalloc:
 	up_read(&card->controls_rwsem);
-      	if (uctl)
-      		kfree(uctl);
-      	if (uinfo)
-		kfree(uinfo);
+      	kfree(uctl);
+	kfree(uinfo);
 }
 
 static int snd_mixer_oss_put_volume1(snd_mixer_oss_file_t *fmixer,
@@ -802,10 +794,8 @@
 	err = 0;
       __unlock:
      	up_read(&card->controls_rwsem);
-      	if (uctl)
-      		kfree(uctl);
-      	if (uinfo)
-      		kfree(uinfo);
+      	kfree(uctl);
+      	kfree(uinfo);
       	return err;
 }
 
@@ -853,10 +843,8 @@
 	err = 0;
       __unlock:
 	up_read(&card->controls_rwsem);
-	if (uctl)
-		kfree(uctl);
-	if (uinfo)
-		kfree(uinfo);
+	kfree(uctl);
+	kfree(uinfo);
 	return err;
 }
 
diff -Nru a/sound/core/oss/mulaw.c b/sound/core/oss/mulaw.c
--- a/sound/core/oss/mulaw.c	2005-03-01 23:39:18 -08:00
+++ b/sound/core/oss/mulaw.c	2005-03-01 23:39:18 -08:00
@@ -301,6 +301,7 @@
 	data = (mulaw_t*)plugin->extra_data;
 	data->func = func;
 	data->conv = getput_index(format->format);
+	snd_assert(data->conv >= 0 && data->conv < 4*2*2, return -EINVAL);
 	plugin->transfer = mulaw_transfer;
 	*r_plugin = plugin;
 	return 0;
diff -Nru a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
--- a/sound/core/oss/pcm_oss.c	2005-03-01 23:39:09 -08:00
+++ b/sound/core/oss/pcm_oss.c	2005-03-01 23:39:09 -08:00
@@ -46,7 +46,7 @@
 
 static int dsp_map[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 0};
 static int adsp_map[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 1};
-static int nonblock_open;
+static int nonblock_open = 1;
 
 MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>, Abramo Bagnara <abramo@alsa-project.org>");
 MODULE_DESCRIPTION("PCM OSS emulation for ALSA.");
@@ -77,7 +77,7 @@
 	set_fs(fs);
 }
 
-int snd_pcm_oss_plugin_clear(snd_pcm_substream_t *substream)
+static int snd_pcm_oss_plugin_clear(snd_pcm_substream_t *substream)
 {
 	snd_pcm_runtime_t *runtime = substream->runtime;
 	snd_pcm_plugin_t *plugin, *next;
@@ -92,7 +92,7 @@
 	return 0;
 }
 
-int snd_pcm_plugin_insert(snd_pcm_plugin_t *plugin)
+static int snd_pcm_plugin_insert(snd_pcm_plugin_t *plugin)
 {
 	snd_pcm_runtime_t *runtime = plugin->plug->runtime;
 	plugin->next = runtime->oss.plugin_first;
@@ -513,8 +513,7 @@
 
 	runtime->oss.params = 0;
 	runtime->oss.prepare = 1;
-	if (runtime->oss.buffer != NULL)
-		vfree(runtime->oss.buffer);
+	vfree(runtime->oss.buffer);
 	runtime->oss.buffer = vmalloc(runtime->oss.period_bytes);
 	runtime->oss.buffer_used = 0;
 	if (runtime->dma_area)
@@ -524,12 +523,9 @@
 
 	err = 0;
 failure:
-	if (sw_params)
-		kfree(sw_params);
-	if (params)
-		kfree(params);
-	if (sparams)
-		kfree(sparams);
+	kfree(sw_params);
+	kfree(params);
+	kfree(sparams);
 	return err;
 }
 
@@ -1671,8 +1667,7 @@
 {
 	snd_pcm_runtime_t *runtime;
 	runtime = substream->runtime;
-	if (runtime->oss.buffer)
-		vfree(runtime->oss.buffer);
+	vfree(runtime->oss.buffer);
 	snd_pcm_oss_plugin_clear(substream);
 	substream->oss.file = NULL;
 	substream->oss.oss = 0;
diff -Nru a/sound/core/oss/pcm_plugin.c b/sound/core/oss/pcm_plugin.c
--- a/sound/core/oss/pcm_plugin.c	2005-03-01 23:38:54 -08:00
+++ b/sound/core/oss/pcm_plugin.c	2005-03-01 23:38:54 -08:00
@@ -86,8 +86,7 @@
 	snd_assert((size % 8) == 0, return -ENXIO);
 	size /= 8;
 	if (plugin->buf_frames < frames) {
-		if (plugin->buf)
-			vfree(plugin->buf);
+		vfree(plugin->buf);
 		plugin->buf = vmalloc(size);
 		plugin->buf_frames = frames;
 	}
@@ -217,14 +216,10 @@
 		return 0;
 	if (plugin->private_free)
 		plugin->private_free(plugin);
-	if (plugin->buf_channels)
-		kfree(plugin->buf_channels);
-	if (plugin->buf)
-		vfree(plugin->buf);
-	if (plugin->src_vmask)
-		kfree(plugin->src_vmask);
-	if (plugin->dst_vmask)
-		kfree(plugin->dst_vmask);
+	kfree(plugin->buf_channels);
+	vfree(plugin->buf);
+	kfree(plugin->src_vmask);
+	kfree(plugin->dst_vmask);
 	kfree(plugin);
 	return 0;
 }
@@ -390,7 +385,7 @@
 	snd_pcm_plugin_format_t srcformat;
 	int src_access, dst_access;
 	snd_pcm_plugin_t *plugin = NULL;
-	int err, first;
+	int err;
 	int stream = snd_pcm_plug_stream(plug);
 	int slave_interleaved = (params_channels(slave_params) == 1 ||
 				 params_access(slave_params) == SNDRV_PCM_ACCESS_RW_INTERLEAVED);
@@ -442,7 +437,6 @@
 			tmpformat.format = dstformat.format;
 		else
 			tmpformat.format = SNDRV_PCM_FORMAT_S16;
-		first = plugin == NULL;
 		switch (srcformat.format) {
 		case SNDRV_PCM_FORMAT_MU_LAW:
 			err = snd_pcm_plugin_build_mulaw(plug,
@@ -656,8 +650,8 @@
 	return count;
 }
 
-int snd_pcm_plug_playback_channels_mask(snd_pcm_plug_t *plug,
-					bitset_t *client_vmask)
+static int snd_pcm_plug_playback_channels_mask(snd_pcm_plug_t *plug,
+					       bitset_t *client_vmask)
 {
 	snd_pcm_plugin_t *plugin = snd_pcm_plug_last(plug);
 	if (plugin == NULL) {
@@ -683,33 +677,6 @@
 			plugin = plugin->prev;
 		}
 		bitset_and(client_vmask, dstmask, plugin->src_format.channels);
-		return 0;
-	}
-}
-
-int snd_pcm_plug_capture_channels_mask(snd_pcm_plug_t *plug,
-				       bitset_t *client_vmask)
-{
-	snd_pcm_plugin_t *plugin = snd_pcm_plug_first(plug);
-	if (plugin == NULL) {
-		return 0;
-	} else {
-		int schannels = plugin->src_format.channels;
-		bitset_t bs[bitset_size(schannels)];
-		bitset_t *srcmask = bs;
-		bitset_t *dstmask;
-		int err;
-		bitset_one(srcmask, schannels);
-		while (1) {
-			err = plugin->dst_channels_mask(plugin, srcmask, &dstmask);
-			if (err < 0)
-				return err;
-			srcmask = dstmask;
-			if (plugin->next == NULL)
-				break;
-			plugin = plugin->next;
-		}
-		bitset_and(client_vmask, srcmask, plugin->dst_format.channels);
 		return 0;
 	}
 }
diff -Nru a/sound/core/oss/pcm_plugin.h b/sound/core/oss/pcm_plugin.h
--- a/sound/core/oss/pcm_plugin.h	2005-03-01 23:39:08 -08:00
+++ b/sound/core/oss/pcm_plugin.h	2005-03-01 23:39:08 -08:00
@@ -168,7 +168,6 @@
 snd_pcm_sframes_t snd_pcm_plug_client_size(snd_pcm_plug_t *handle, snd_pcm_uframes_t drv_size);
 snd_pcm_sframes_t snd_pcm_plug_slave_size(snd_pcm_plug_t *handle, snd_pcm_uframes_t clt_size);
 
-#define ROUTE_PLUGIN_USE_FLOAT 0
 #define FULL ROUTE_PLUGIN_RESOLUTION
 #define HALF ROUTE_PLUGIN_RESOLUTION / 2
 typedef int route_ttable_entry_t;
diff -Nru a/sound/core/oss/rate.c b/sound/core/oss/rate.c
--- a/sound/core/oss/rate.c	2005-03-01 23:38:57 -08:00
+++ b/sound/core/oss/rate.c	2005-03-01 23:38:57 -08:00
@@ -355,7 +355,9 @@
 		return err;
 	data = (rate_t *)plugin->extra_data;
 	data->get = getput_index(src_format->format);
+	snd_assert(data->get >= 0 && data->get < 4*2*2, return -EINVAL);
 	data->put = getput_index(dst_format->format);
+	snd_assert(data->put >= 0 && data->put < 4*2*2, return -EINVAL);
 
 	if (src_format->rate < dst_format->rate) {
 		data->pitch = ((src_format->rate << SHIFT) + (dst_format->rate >> 1)) / dst_format->rate;
diff -Nru a/sound/core/oss/route.c b/sound/core/oss/route.c
--- a/sound/core/oss/route.c	2005-03-01 23:39:16 -08:00
+++ b/sound/core/oss/route.c	2005-03-01 23:39:16 -08:00
@@ -46,9 +46,6 @@
 typedef struct {
 	int channel;
 	int as_int;
-#if ROUTE_PLUGIN_USE_FLOAT
-	float as_float;
-#endif
 } ttable_src_t;
 
 struct ttable_dst {
@@ -59,7 +56,7 @@
 };
 
 struct route_private_data {
-	enum {R_UINT32=0, R_UINT64=1, R_FLOAT=2} sum_type;
+	enum {R_UINT32=0, R_UINT64=1} sum_type;
 	int get, put;
 	int conv;
 	int src_sample_size;
@@ -69,9 +66,6 @@
 typedef union {
 	u_int32_t as_uint32;
 	u_int64_t as_uint64;
-#if ROUTE_PLUGIN_USE_FLOAT
-	float as_float;
-#endif
 } sum_t;
 
 
@@ -136,20 +130,13 @@
 #include "plugin_ops.h"
 #undef GET_U_LABELS
 #undef PUT_U32_LABELS
-	static void *zero_labels[3] = { &&zero_int32, &&zero_int64,
-#if ROUTE_PLUGIN_USE_FLOAT
-				 &&zero_float
-#endif
-	};
+	static void *zero_labels[2] = { &&zero_int32, &&zero_int64 };
 	/* sum_type att */
-	static void *add_labels[3 * 2] = { &&add_int32_noatt, &&add_int32_att,
+	static void *add_labels[2 * 2] = { &&add_int32_noatt, &&add_int32_att,
 				    &&add_int64_noatt, &&add_int64_att,
-#if ROUTE_PLUGIN_USE_FLOAT
-				    &&add_float_noatt, &&add_float_att
-#endif
 	};
 	/* sum_type att shift */
-	static void *norm_labels[3 * 2 * 4] = { NULL,
+	static void *norm_labels[2 * 2 * 4] = { NULL,
 					 &&norm_int32_8_noatt,
 					 &&norm_int32_16_noatt,
 					 &&norm_int32_24_noatt,
@@ -165,16 +152,6 @@
 					 &&norm_int64_8_att,
 					 &&norm_int64_16_att,
 					 &&norm_int64_24_att,
-#if ROUTE_PLUGIN_USE_FLOAT
-					 &&norm_float_0,
-					 &&norm_float_8,
-					 &&norm_float_16,
-					 &&norm_float_24,
-					 &&norm_float_0,
-					 &&norm_float_8,
-					 &&norm_float_16,
-					 &&norm_float_24,
-#endif
 	};
 	route_t *data = (route_t *)plugin->extra_data;
 	void *zero, *get, *add, *norm, *put_u32;
@@ -225,11 +202,6 @@
 	zero_int64: 
 		sum.as_uint64 = 0;
 		goto zero_end;
-#if ROUTE_PLUGIN_USE_FLOAT
-	zero_float:
-		sum.as_float = 0.0;
-		goto zero_end;
-#endif
 	zero_end:
 		for (srcidx = 0; srcidx < nsrcs; ++srcidx) {
 			char *src = srcs[srcidx];
@@ -257,15 +229,6 @@
 			if (ttp->as_int)
 				sum.as_uint64 += sample;
 			goto after_sum;
-#if ROUTE_PLUGIN_USE_FLOAT
-		add_float_att:
-			sum.as_float += sample * ttp->as_float;
-			goto after_sum;
-		add_float_noatt:
-			if (ttp->as_int)
-				sum.as_float += sample;
-			goto after_sum;
-#endif
 		after_sum:
 			srcs[srcidx] += src_steps[srcidx];
 			ttp++;
@@ -321,25 +284,6 @@
 			sample = sum.as_uint64;
 		goto after_norm;
 
-#if ROUTE_PLUGIN_USE_FLOAT
-	norm_float_8:
-		sum.as_float *= 1 << 8;
-		goto norm_float;
-	norm_float_16:
-		sum.as_float *= 1 << 16;
-		goto norm_float;
-	norm_float_24:
-		sum.as_float *= 1 << 24;
-		goto norm_float;
-	norm_float_0:
-	norm_float:
-		sum.as_float = floor(sum.as_float + 0.5);
-		if (sum.as_float > (u_int32_t)0xffffffff)
-			sample = (u_int32_t)0xffffffff;
-		else
-			sample = sum.as_float;
-		goto after_norm;
-#endif
 	after_norm:
 		
 		/* Put sample */
@@ -353,9 +297,9 @@
 	}
 }
 
-int route_src_channels_mask(snd_pcm_plugin_t *plugin,
-			  bitset_t *dst_vmask,
-			  bitset_t **src_vmask)
+static int route_src_channels_mask(snd_pcm_plugin_t *plugin,
+				   bitset_t *dst_vmask,
+				   bitset_t **src_vmask)
 {
 	route_t *data = (route_t *)plugin->extra_data;
 	int schannels = plugin->src_format.channels;
@@ -377,9 +321,9 @@
 	return 0;
 }
 
-int route_dst_channels_mask(snd_pcm_plugin_t *plugin,
-			  bitset_t *src_vmask,
-			  bitset_t **dst_vmask)
+static int route_dst_channels_mask(snd_pcm_plugin_t *plugin,
+				   bitset_t *src_vmask,
+				   bitset_t **dst_vmask)
 {
 	route_t *data = (route_t *)plugin->extra_data;
 	int dchannels = plugin->dst_format.channels;
@@ -407,8 +351,7 @@
 	route_t *data = (route_t *)plugin->extra_data;
 	unsigned int dst_channel;
 	for (dst_channel = 0; dst_channel < plugin->dst_format.channels; ++dst_channel) {
-		if (data->ttable[dst_channel].srcs != NULL)
-			kfree(data->ttable[dst_channel].srcs);
+		kfree(data->ttable[dst_channel].srcs);
 	}
 }
 
@@ -434,13 +377,7 @@
 			snd_assert(*sptr >= 0 || *sptr <= FULL, return -ENXIO);
 			if (*sptr != 0) {
 				srcs[nsrcs].channel = src_channel;
-#if ROUTE_PLUGIN_USE_FLOAT
-				/* Also in user space for non attenuated */
-				srcs[nsrcs].as_int = (*sptr == FULL ? ROUTE_PLUGIN_RESOLUTION : 0);
-				srcs[nsrcs].as_float = *sptr;
-#else
 				srcs[nsrcs].as_int = *sptr;
-#endif
 				if (*sptr != FULL)
 					att = 1;
 				t += *sptr;
@@ -559,17 +496,15 @@
 	data = (route_t *) plugin->extra_data;
 
 	data->get = getput_index(src_format->format);
+	snd_assert(data->get >= 0 && data->get < 4*2*2, return -EINVAL);
 	data->put = getput_index(dst_format->format);
+	snd_assert(data->get >= 0 && data->get < 4*2*2, return -EINVAL);
 	data->conv = conv_index(src_format->format, dst_format->format);
 
-#if ROUTE_PLUGIN_USE_FLOAT
-	data->sum_type = R_FLOAT;
-#else
 	if (snd_pcm_format_width(src_format->format) == 32)
 		data->sum_type = R_UINT64;
 	else
 		data->sum_type = R_UINT32;
-#endif
 	data->src_sample_size = snd_pcm_format_width(src_format->format) / 8;
 
 	if ((err = route_load_ttable(plugin, ttable)) < 0) {
diff -Nru a/sound/core/pcm.c b/sound/core/pcm.c
--- a/sound/core/pcm.c	2005-03-01 23:39:17 -08:00
+++ b/sound/core/pcm.c	2005-03-01 23:39:17 -08:00
@@ -126,12 +126,12 @@
 #define FORMAT(v) [SNDRV_PCM_FORMAT_##v] = #v
 #define SUBFORMAT(v) [SNDRV_PCM_SUBFORMAT_##v] = #v 
 
-char *snd_pcm_stream_names[] = {
+static char *snd_pcm_stream_names[] = {
 	STREAM(PLAYBACK),
 	STREAM(CAPTURE),
 };
 
-char *snd_pcm_state_names[] = {
+static char *snd_pcm_state_names[] = {
 	STATE(OPEN),
 	STATE(SETUP),
 	STATE(PREPARED),
@@ -142,7 +142,7 @@
 	STATE(SUSPENDED),
 };
 
-char *snd_pcm_access_names[] = {
+static char *snd_pcm_access_names[] = {
 	ACCESS(MMAP_INTERLEAVED), 
 	ACCESS(MMAP_NONINTERLEAVED),
 	ACCESS(MMAP_COMPLEX),
@@ -150,7 +150,7 @@
 	ACCESS(RW_NONINTERLEAVED),
 };
 
-char *snd_pcm_format_names[] = {
+static char *snd_pcm_format_names[] = {
 	FORMAT(S8),
 	FORMAT(U8),
 	FORMAT(S16_LE),
@@ -191,22 +191,22 @@
 	FORMAT(U18_3BE),
 };
 
-char *snd_pcm_subformat_names[] = {
+static char *snd_pcm_subformat_names[] = {
 	SUBFORMAT(STD), 
 };
 
-char *snd_pcm_tstamp_mode_names[] = {
+static char *snd_pcm_tstamp_mode_names[] = {
 	TSTAMP(NONE),
 	TSTAMP(MMAP),
 };
 
-const char *snd_pcm_stream_name(snd_pcm_stream_t stream)
+static const char *snd_pcm_stream_name(snd_pcm_stream_t stream)
 {
 	snd_assert(stream <= SNDRV_PCM_STREAM_LAST, return NULL);
 	return snd_pcm_stream_names[stream];
 }
 
-const char *snd_pcm_access_name(snd_pcm_access_t access)
+static const char *snd_pcm_access_name(snd_pcm_access_t access)
 {
 	snd_assert(access <= SNDRV_PCM_ACCESS_LAST, return NULL);
 	return snd_pcm_access_names[access];
@@ -218,19 +218,19 @@
 	return snd_pcm_format_names[format];
 }
 
-const char *snd_pcm_subformat_name(snd_pcm_subformat_t subformat)
+static const char *snd_pcm_subformat_name(snd_pcm_subformat_t subformat)
 {
 	snd_assert(subformat <= SNDRV_PCM_SUBFORMAT_LAST, return NULL);
 	return snd_pcm_subformat_names[subformat];
 }
 
-const char *snd_pcm_tstamp_mode_name(snd_pcm_tstamp_t mode)
+static const char *snd_pcm_tstamp_mode_name(snd_pcm_tstamp_t mode)
 {
 	snd_assert(mode <= SNDRV_PCM_TSTAMP_LAST, return NULL);
 	return snd_pcm_tstamp_mode_names[mode];
 }
 
-const char *snd_pcm_state_name(snd_pcm_state_t state)
+static const char *snd_pcm_state_name(snd_pcm_state_t state)
 {
 	snd_assert(state <= SNDRV_PCM_STATE_LAST, return NULL);
 	return snd_pcm_state_names[state];
@@ -238,7 +238,7 @@
 
 #if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
 #include <linux/soundcard.h>
-const char *snd_pcm_oss_format_name(int format)
+static const char *snd_pcm_oss_format_name(int format)
 {
 	switch (format) {
 	case AFMT_MU_LAW:
@@ -830,8 +830,7 @@
 		runtime->private_free(runtime);
 	snd_free_pages((void*)runtime->status, PAGE_ALIGN(sizeof(snd_pcm_mmap_status_t)));
 	snd_free_pages((void*)runtime->control, PAGE_ALIGN(sizeof(snd_pcm_mmap_control_t)));
-	if (runtime->hw_constraints.rules)
-		kfree(runtime->hw_constraints.rules);
+	kfree(runtime->hw_constraints.rules);
 	kfree(runtime);
 	substream->runtime = NULL;
 	substream->pstr->substream_opened--;
@@ -1035,7 +1034,6 @@
 EXPORT_SYMBOL(snd_pcm_open_substream);
 EXPORT_SYMBOL(snd_pcm_release_substream);
 EXPORT_SYMBOL(snd_pcm_format_name);
-EXPORT_SYMBOL(snd_pcm_subformat_name);
   /* pcm_native.c */
 EXPORT_SYMBOL(snd_pcm_link_rwlock);
 EXPORT_SYMBOL(snd_pcm_start);
@@ -1046,10 +1044,6 @@
 EXPORT_SYMBOL(snd_pcm_kernel_playback_ioctl);
 EXPORT_SYMBOL(snd_pcm_kernel_capture_ioctl);
 EXPORT_SYMBOL(snd_pcm_kernel_ioctl);
-EXPORT_SYMBOL(snd_pcm_open);
-EXPORT_SYMBOL(snd_pcm_release);
-EXPORT_SYMBOL(snd_pcm_playback_poll);
-EXPORT_SYMBOL(snd_pcm_capture_poll);
 EXPORT_SYMBOL(snd_pcm_mmap_data);
 #if SNDRV_PCM_INFO_MMAP_IOMEM
 EXPORT_SYMBOL(snd_pcm_lib_mmap_iomem);
@@ -1062,7 +1056,6 @@
 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 -Nru a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
--- a/sound/core/pcm_lib.c	2005-03-01 23:38:56 -08:00
+++ b/sound/core/pcm_lib.c	2005-03-01 23:38:56 -08:00
@@ -371,7 +371,7 @@
 	return n;
 }
 
-int snd_interval_refine_min(snd_interval_t *i, unsigned int min, int openmin)
+static int snd_interval_refine_min(snd_interval_t *i, unsigned int min, int openmin)
 {
 	int changed = 0;
 	assert(!snd_interval_empty(i));
@@ -396,7 +396,7 @@
 	return changed;
 }
 
-int snd_interval_refine_max(snd_interval_t *i, unsigned int max, int openmax)
+static int snd_interval_refine_max(snd_interval_t *i, unsigned int max, int openmax)
 {
 	int changed = 0;
 	assert(!snd_interval_empty(i));
@@ -474,7 +474,7 @@
 	return changed;
 }
 
-int snd_interval_refine_first(snd_interval_t *i)
+static int snd_interval_refine_first(snd_interval_t *i)
 {
 	assert(!snd_interval_empty(i));
 	if (snd_interval_single(i))
@@ -486,7 +486,7 @@
 	return 1;
 }
 
-int snd_interval_refine_last(snd_interval_t *i)
+static int snd_interval_refine_last(snd_interval_t *i)
 {
 	assert(!snd_interval_empty(i));
 	if (snd_interval_single(i))
@@ -498,7 +498,7 @@
 	return 1;
 }
 
-int snd_interval_refine_set(snd_interval_t *i, unsigned int val)
+static int snd_interval_refine_set(snd_interval_t *i, unsigned int val)
 {
 	snd_interval_t t;
 	t.empty = 0;
@@ -718,9 +718,9 @@
  *
  * Returns non-zero if the value is changed, zero if not changed.
  */
-int snd_interval_ratden(snd_interval_t *i,
-		    unsigned int rats_count, ratden_t *rats,
-		    unsigned int *nump, unsigned int *denp)
+static int snd_interval_ratden(snd_interval_t *i,
+			       unsigned int rats_count, ratden_t *rats,
+			       unsigned int *nump, unsigned int *denp)
 {
 	unsigned int best_num, best_diff, best_den;
 	unsigned int k;
@@ -858,7 +858,7 @@
         return changed;
 }
 
-int snd_interval_step(snd_interval_t *i, unsigned int min, unsigned int step)
+static int snd_interval_step(snd_interval_t *i, unsigned int min, unsigned int step)
 {
 	unsigned int n;
 	int changed = 0;
@@ -1856,80 +1856,6 @@
  *  Conditions
  */
 
-/**
- * snd_pcm_playback_ready - check whether the playback buffer is available
- * @substream: the pcm substream instance
- *
- * Checks whether enough free space is available on the playback buffer.
- *
- * Returns non-zero if available, or zero if not.
- */
-int snd_pcm_playback_ready(snd_pcm_substream_t *substream)
-{
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	return snd_pcm_playback_avail(runtime) >= runtime->control->avail_min;
-}
-
-/**
- * snd_pcm_capture_ready - check whether the capture buffer is available
- * @substream: the pcm substream instance
- *
- * Checks whether enough capture data is available on the capture buffer.
- *
- * Returns non-zero if available, or zero if not.
- */
-int snd_pcm_capture_ready(snd_pcm_substream_t *substream)
-{
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	return snd_pcm_capture_avail(runtime) >= runtime->control->avail_min;
-}
-
-/**
- * snd_pcm_playback_data - check whether any data exists on the playback buffer
- * @substream: the pcm substream instance
- *
- * Checks whether any data exists on the playback buffer. If stop_threshold
- * is bigger or equal to boundary, then this function returns always non-zero.
- *
- * Returns non-zero if exists, or zero if not.
- */
-int snd_pcm_playback_data(snd_pcm_substream_t *substream)
-{
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	
-	if (runtime->stop_threshold >= runtime->boundary)
-		return 1;
-	return snd_pcm_playback_avail(runtime) < runtime->buffer_size;
-}
-
-/**
- * snd_pcm_playback_empty - check whether the playback buffer is empty
- * @substream: the pcm substream instance
- *
- * Checks whether the playback buffer is empty.
- *
- * Returns non-zero if empty, or zero if not.
- */
-int snd_pcm_playback_empty(snd_pcm_substream_t *substream)
-{
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	return snd_pcm_playback_avail(runtime) >= runtime->buffer_size;
-}
-
-/**
- * snd_pcm_capture_empty - check whether the capture buffer is empty
- * @substream: the pcm substream instance
- *
- * Checks whether the capture buffer is empty.
- *
- * Returns non-zero if empty, or zero if not.
- */
-int snd_pcm_capture_empty(snd_pcm_substream_t *substream)
-{
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	return snd_pcm_capture_avail(runtime) == 0;
-}
-
 static void snd_pcm_system_tick_set(snd_pcm_substream_t *substream, 
 				    unsigned long ticks)
 {
@@ -2643,7 +2569,6 @@
 EXPORT_SYMBOL(snd_interval_refine);
 EXPORT_SYMBOL(snd_interval_list);
 EXPORT_SYMBOL(snd_interval_ratnum);
-EXPORT_SYMBOL(snd_interval_ratden);
 EXPORT_SYMBOL(snd_interval_muldivk);
 EXPORT_SYMBOL(snd_interval_mulkdiv);
 EXPORT_SYMBOL(snd_interval_div);
@@ -2660,6 +2585,7 @@
 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);
@@ -2674,10 +2600,6 @@
 EXPORT_SYMBOL(snd_pcm_set_ops);
 EXPORT_SYMBOL(snd_pcm_set_sync);
 EXPORT_SYMBOL(snd_pcm_lib_ioctl);
-EXPORT_SYMBOL(snd_pcm_playback_ready);
-EXPORT_SYMBOL(snd_pcm_capture_ready);
-EXPORT_SYMBOL(snd_pcm_playback_data);
-EXPORT_SYMBOL(snd_pcm_capture_empty);
 EXPORT_SYMBOL(snd_pcm_stop);
 EXPORT_SYMBOL(snd_pcm_period_elapsed);
 EXPORT_SYMBOL(snd_pcm_lib_write);
@@ -2687,7 +2609,6 @@
 EXPORT_SYMBOL(snd_pcm_lib_buffer_bytes);
 EXPORT_SYMBOL(snd_pcm_lib_period_bytes);
 /* pcm_memory.c */
-EXPORT_SYMBOL(snd_pcm_lib_preallocate_free);
 EXPORT_SYMBOL(snd_pcm_lib_preallocate_free_for_all);
 EXPORT_SYMBOL(snd_pcm_lib_preallocate_pages);
 EXPORT_SYMBOL(snd_pcm_lib_preallocate_pages_for_all);
diff -Nru a/sound/core/pcm_memory.c b/sound/core/pcm_memory.c
--- a/sound/core/pcm_memory.c	2005-03-01 23:39:07 -08:00
+++ b/sound/core/pcm_memory.c	2005-03-01 23:39:07 -08:00
@@ -37,7 +37,7 @@
 module_param(maximum_substreams, int, 0444);
 MODULE_PARM_DESC(maximum_substreams, "Maximum substreams with preallocated DMA memory.");
 
-const static size_t snd_minimum_buffer = 16384;
+static const size_t snd_minimum_buffer = 16384;
 
 
 /*
diff -Nru a/sound/core/pcm_native.c b/sound/core/pcm_native.c
--- a/sound/core/pcm_native.c	2005-03-01 23:38:55 -08:00
+++ b/sound/core/pcm_native.c	2005-03-01 23:38:55 -08:00
@@ -329,8 +329,8 @@
 	return err;
 }
 
-static int snd_pcm_hw_params(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)
 {
 	snd_pcm_runtime_t *runtime;
 	int err;
@@ -1445,7 +1445,7 @@
 
  _end:
 	snd_pcm_stream_unlock_irq(substream);
-	if (drec && drec != &drec_tmp)
+	if (drec != &drec_tmp)
 		kfree(drec);
  _unlock:
 	snd_power_unlock(card);
@@ -2020,7 +2020,7 @@
 	return 0;
 }
 
-int snd_pcm_open(struct inode *inode, struct file *file)
+static int snd_pcm_open(struct inode *inode, struct file *file)
 {
 	int cardnum = SNDRV_MINOR_CARD(iminor(inode));
 	int device = SNDRV_MINOR_DEVICE(iminor(inode));
@@ -2079,7 +2079,7 @@
       	return err;
 }
 
-int snd_pcm_release(struct inode *inode, struct file *file)
+static int snd_pcm_release(struct inode *inode, struct file *file)
 {
 	snd_pcm_t *pcm;
 	snd_pcm_substream_t *substream;
@@ -2101,7 +2101,7 @@
 	return 0;
 }
 
-snd_pcm_sframes_t snd_pcm_playback_rewind(snd_pcm_substream_t *substream, snd_pcm_uframes_t frames)
+static snd_pcm_sframes_t snd_pcm_playback_rewind(snd_pcm_substream_t *substream, snd_pcm_uframes_t frames)
 {
 	snd_pcm_runtime_t *runtime = substream->runtime;
 	snd_pcm_sframes_t appl_ptr;
@@ -2150,7 +2150,7 @@
 	return ret;
 }
 
-snd_pcm_sframes_t snd_pcm_capture_rewind(snd_pcm_substream_t *substream, snd_pcm_uframes_t frames)
+static snd_pcm_sframes_t snd_pcm_capture_rewind(snd_pcm_substream_t *substream, snd_pcm_uframes_t frames)
 {
 	snd_pcm_runtime_t *runtime = substream->runtime;
 	snd_pcm_sframes_t appl_ptr;
@@ -2199,7 +2199,7 @@
 	return ret;
 }
 
-snd_pcm_sframes_t snd_pcm_playback_forward(snd_pcm_substream_t *substream, snd_pcm_uframes_t frames)
+static snd_pcm_sframes_t snd_pcm_playback_forward(snd_pcm_substream_t *substream, snd_pcm_uframes_t frames)
 {
 	snd_pcm_runtime_t *runtime = substream->runtime;
 	snd_pcm_sframes_t appl_ptr;
@@ -2249,7 +2249,7 @@
 	return ret;
 }
 
-snd_pcm_sframes_t snd_pcm_capture_forward(snd_pcm_substream_t *substream, snd_pcm_uframes_t frames)
+static snd_pcm_sframes_t snd_pcm_capture_forward(snd_pcm_substream_t *substream, snd_pcm_uframes_t frames)
 {
 	snd_pcm_runtime_t *runtime = substream->runtime;
 	snd_pcm_sframes_t appl_ptr;
@@ -2835,7 +2835,7 @@
 	return result;
 }
 
-unsigned int snd_pcm_playback_poll(struct file *file, poll_table * wait)
+static unsigned int snd_pcm_playback_poll(struct file *file, poll_table * wait)
 {
 	snd_pcm_file_t *pcm_file;
 	snd_pcm_substream_t *substream;
@@ -2873,7 +2873,7 @@
 	return mask;
 }
 
-unsigned int snd_pcm_capture_poll(struct file *file, poll_table * wait)
+static unsigned int snd_pcm_capture_poll(struct file *file, poll_table * wait)
 {
 	snd_pcm_file_t *pcm_file;
 	snd_pcm_substream_t *substream;
diff -Nru a/sound/core/rawmidi.c b/sound/core/rawmidi.c
--- a/sound/core/rawmidi.c	2005-03-01 23:38:53 -08:00
+++ b/sound/core/rawmidi.c	2005-03-01 23:38:53 -08:00
@@ -54,7 +54,7 @@
 static int snd_rawmidi_dev_disconnect(snd_device_t *device);
 static int snd_rawmidi_dev_unregister(snd_device_t *device);
 
-snd_rawmidi_t *snd_rawmidi_devices[SNDRV_CARDS * SNDRV_RAWMIDI_DEVICES];
+static snd_rawmidi_t *snd_rawmidi_devices[SNDRV_CARDS * SNDRV_RAWMIDI_DEVICES];
 
 static DECLARE_MUTEX(register_mutex);
 
@@ -747,7 +747,7 @@
 	case SNDRV_RAWMIDI_IOCTL_DROP:
 	{
 		int val;
-		if (get_user(val, (long __user *) argp))
+		if (get_user(val, (int __user *) argp))
 			return -EFAULT;
 		switch (val) {
 		case SNDRV_RAWMIDI_STREAM_OUTPUT:
@@ -761,7 +761,7 @@
 	case SNDRV_RAWMIDI_IOCTL_DRAIN:
 	{
 		int val;
-		if (get_user(val, (long __user *) argp))
+		if (get_user(val, (int __user *) argp))
 			return -EFAULT;
 		switch (val) {
 		case SNDRV_RAWMIDI_STREAM_OUTPUT:
@@ -795,8 +795,10 @@
 	return err;
 }
 
-int snd_rawmidi_control_ioctl(snd_card_t * card, snd_ctl_file_t * control,
-			      unsigned int cmd, unsigned long arg)
+static int snd_rawmidi_control_ioctl(snd_card_t * card,
+				     snd_ctl_file_t * control,
+				     unsigned int cmd,
+				     unsigned long arg)
 {
 	void __user *argp = (void __user *)arg;
 	unsigned int tmp;
diff -Nru a/sound/core/seq/Makefile b/sound/core/seq/Makefile
--- a/sound/core/seq/Makefile	2005-03-01 23:39:16 -08:00
+++ b/sound/core/seq/Makefile	2005-03-01 23:39:16 -08:00
@@ -37,6 +37,8 @@
 obj-$(CONFIG_SND_VIRMIDI) += snd-seq-virmidi.o snd-seq-midi-event.o
 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_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 -Nru a/sound/core/seq/instr/ainstr_fm.c b/sound/core/seq/instr/ainstr_fm.c
--- a/sound/core/seq/instr/ainstr_fm.c	2005-03-01 23:38:56 -08:00
+++ b/sound/core/seq/instr/ainstr_fm.c	2005-03-01 23:38:56 -08:00
@@ -30,8 +30,6 @@
 MODULE_DESCRIPTION("Advanced Linux Sound Architecture FM Instrument support.");
 MODULE_LICENSE("GPL");
 
-char *snd_seq_fm_id = SNDRV_SEQ_INSTR_ID_OPL2_3;
-
 static int snd_seq_fm_put(void *private_data, snd_seq_kinstr_t *instr,
 			  char __user *instr_data, long len, int atomic, int cmd)
 {
@@ -129,7 +127,7 @@
 	memset(ops, 0, sizeof(*ops));
 	// ops->private_data = private_data;
 	ops->add_len = sizeof(fm_instrument_t);
-	ops->instr_type = snd_seq_fm_id;
+	ops->instr_type = SNDRV_SEQ_INSTR_ID_OPL2_3;
 	ops->put = snd_seq_fm_put;
 	ops->get = snd_seq_fm_get;
 	ops->get_size = snd_seq_fm_get_size;
@@ -155,5 +153,4 @@
 module_init(alsa_ainstr_fm_init)
 module_exit(alsa_ainstr_fm_exit)
 
-EXPORT_SYMBOL(snd_seq_fm_id);
 EXPORT_SYMBOL(snd_seq_fm_init);
diff -Nru a/sound/core/seq/instr/ainstr_gf1.c b/sound/core/seq/instr/ainstr_gf1.c
--- a/sound/core/seq/instr/ainstr_gf1.c	2005-03-01 23:39:08 -08:00
+++ b/sound/core/seq/instr/ainstr_gf1.c	2005-03-01 23:39:08 -08:00
@@ -31,8 +31,6 @@
 MODULE_DESCRIPTION("Advanced Linux Sound Architecture GF1 (GUS) Patch support.");
 MODULE_LICENSE("GPL");
 
-char *snd_seq_gf1_id = SNDRV_SEQ_INSTR_ID_GUS_PATCH;
-
 static unsigned int snd_seq_gf1_size(unsigned int size, unsigned int format)
 {
 	unsigned int result = size;
@@ -331,7 +329,7 @@
 	ops->private_data = private_data;
 	ops->kops.private_data = ops;
 	ops->kops.add_len = sizeof(gf1_instrument_t);
-	ops->kops.instr_type = snd_seq_gf1_id;
+	ops->kops.instr_type = SNDRV_SEQ_INSTR_ID_GUS_PATCH;
 	ops->kops.put = snd_seq_gf1_put;
 	ops->kops.get = snd_seq_gf1_get;
 	ops->kops.get_size = snd_seq_gf1_get_size;
@@ -357,5 +355,4 @@
 module_init(alsa_ainstr_gf1_init)
 module_exit(alsa_ainstr_gf1_exit)
 
-EXPORT_SYMBOL(snd_seq_gf1_id);
 EXPORT_SYMBOL(snd_seq_gf1_init);
diff -Nru a/sound/core/seq/instr/ainstr_iw.c b/sound/core/seq/instr/ainstr_iw.c
--- a/sound/core/seq/instr/ainstr_iw.c	2005-03-01 23:38:57 -08:00
+++ b/sound/core/seq/instr/ainstr_iw.c	2005-03-01 23:38:57 -08:00
@@ -31,8 +31,6 @@
 MODULE_DESCRIPTION("Advanced Linux Sound Architecture IWFFFF support.");
 MODULE_LICENSE("GPL");
 
-char *snd_seq_iwffff_id = SNDRV_SEQ_INSTR_ID_INTERWAVE;
-
 static unsigned int snd_seq_iwffff_size(unsigned int size, unsigned int format)
 {
 	unsigned int result = size;
@@ -595,7 +593,7 @@
 	ops->private_data = private_data;
 	ops->kops.private_data = ops;
 	ops->kops.add_len = sizeof(iwffff_instrument_t);
-	ops->kops.instr_type = snd_seq_iwffff_id;
+	ops->kops.instr_type = SNDRV_SEQ_INSTR_ID_INTERWAVE;
 	ops->kops.put = snd_seq_iwffff_put;
 	ops->kops.get = snd_seq_iwffff_get;
 	ops->kops.get_size = snd_seq_iwffff_get_size;
@@ -621,5 +619,4 @@
 module_init(alsa_ainstr_iw_init)
 module_exit(alsa_ainstr_iw_exit)
 
-EXPORT_SYMBOL(snd_seq_iwffff_id);
 EXPORT_SYMBOL(snd_seq_iwffff_init);
diff -Nru a/sound/core/seq/instr/ainstr_simple.c b/sound/core/seq/instr/ainstr_simple.c
--- a/sound/core/seq/instr/ainstr_simple.c	2005-03-01 23:39:08 -08:00
+++ b/sound/core/seq/instr/ainstr_simple.c	2005-03-01 23:39:08 -08:00
@@ -31,8 +31,6 @@
 MODULE_DESCRIPTION("Advanced Linux Sound Architecture Simple Instrument support.");
 MODULE_LICENSE("GPL");
 
-char *snd_seq_simple_id = SNDRV_SEQ_INSTR_ID_SIMPLE;
-
 static unsigned int snd_seq_simple_size(unsigned int size, unsigned int format)
 {
 	unsigned int result = size;
@@ -188,7 +186,7 @@
 	ops->private_data = private_data;
 	ops->kops.private_data = ops;
 	ops->kops.add_len = sizeof(simple_instrument_t);
-	ops->kops.instr_type = snd_seq_simple_id;
+	ops->kops.instr_type = SNDRV_SEQ_INSTR_ID_SIMPLE;
 	ops->kops.put = snd_seq_simple_put;
 	ops->kops.get = snd_seq_simple_get;
 	ops->kops.get_size = snd_seq_simple_get_size;
@@ -214,5 +212,4 @@
 module_init(alsa_ainstr_simple_init)
 module_exit(alsa_ainstr_simple_exit)
 
-EXPORT_SYMBOL(snd_seq_simple_id);
 EXPORT_SYMBOL(snd_seq_simple_init);
diff -Nru 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	2005-03-01 23:38:57 -08:00
+++ b/sound/core/seq/oss/seq_oss_device.h	2005-03-01 23:38:57 -08:00
@@ -185,7 +185,6 @@
 
 /* misc. functions for proc interface */
 char *enabled_str(int bool);
-char *filemode_str(int fmode);
 
 
 /* for debug */
diff -Nru a/sound/core/seq/oss/seq_oss_init.c b/sound/core/seq/oss/seq_oss_init.c
--- a/sound/core/seq/oss/seq_oss_init.c	2005-03-01 23:38:52 -08:00
+++ b/sound/core/seq/oss/seq_oss_init.c	2005-03-01 23:38:52 -08:00
@@ -491,6 +491,26 @@
 	snd_seq_oss_timer_stop(dp->timer);
 }
 
+
+/*
+ * misc. functions for proc interface
+ */
+char *
+enabled_str(int bool)
+{
+	return bool ? "enabled" : "disabled";
+}
+
+static char *
+filemode_str(int val)
+{
+	static char *str[] = {
+		"none", "read", "write", "read/write",
+	};
+	return str[val & SNDRV_SEQ_OSS_FILE_ACMODE];
+}
+
+
 /*
  * proc interface
  */
@@ -522,23 +542,4 @@
 			snd_seq_oss_readq_info_read(dp->readq, buf);
 	}
 }
-
-/*
- * misc. functions for proc interface
- */
-char *
-enabled_str(int bool)
-{
-	return bool ? "enabled" : "disabled";
-}
-
-char *
-filemode_str(int val)
-{
-	static char *str[] = {
-		"none", "read", "write", "read/write",
-	};
-	return str[val & SNDRV_SEQ_OSS_FILE_ACMODE];
-}
-
 
diff -Nru a/sound/core/seq/oss/seq_oss_misc.c b/sound/core/seq/oss/seq_oss_misc.c
--- a/sound/core/seq/oss/seq_oss_misc.c	2005-03-01 23:38:52 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,110 +0,0 @@
-/*----------------------------------------------------------------
- * miscellaneous functions
- *----------------------------------------------------------------*/
-
-unsigned short snd_seq_oss_semitone_tuning[24] = 
-{
-/*   0 */ 10000, 10595, 11225, 11892, 12599, 13348, 14142, 14983, 
-/*   8 */ 15874, 16818, 17818, 18877, 20000, 21189, 22449, 23784, 
-/*  16 */ 25198, 26697, 28284, 29966, 31748, 33636, 35636, 37755
-};
-
-unsigned short snd_seq_oss_cent_tuning[100] =
-{
-/*   0 */ 10000, 10006, 10012, 10017, 10023, 10029, 10035, 10041, 
-/*   8 */ 10046, 10052, 10058, 10064, 10070, 10075, 10081, 10087, 
-/*  16 */ 10093, 10099, 10105, 10110, 10116, 10122, 10128, 10134, 
-/*  24 */ 10140, 10145, 10151, 10157, 10163, 10169, 10175, 10181, 
-/*  32 */ 10187, 10192, 10198, 10204, 10210, 10216, 10222, 10228, 
-/*  40 */ 10234, 10240, 10246, 10251, 10257, 10263, 10269, 10275, 
-/*  48 */ 10281, 10287, 10293, 10299, 10305, 10311, 10317, 10323, 
-/*  56 */ 10329, 10335, 10341, 10347, 10353, 10359, 10365, 10371, 
-/*  64 */ 10377, 10383, 10389, 10395, 10401, 10407, 10413, 10419, 
-/*  72 */ 10425, 10431, 10437, 10443, 10449, 10455, 10461, 10467, 
-/*  80 */ 10473, 10479, 10485, 10491, 10497, 10503, 10509, 10515, 
-/*  88 */ 10521, 10528, 10534, 10540, 10546, 10552, 10558, 10564, 
-/*  96 */ 10570, 10576, 10582, 10589
-};
-
-/* convert from MIDI note to frequency */
-int
-snd_seq_oss_note_to_freq(int note_num)
-{
-
-	/*
-	 * This routine converts a midi note to a frequency (multiplied by 1000)
-	 */
-
-	int note, octave, note_freq;
-	static int notes[] = {
-		261632, 277189, 293671, 311132, 329632, 349232,
-		369998, 391998, 415306, 440000, 466162, 493880
-	};
-
-#define BASE_OCTAVE	5
-
-	octave = note_num / 12;
-	note = note_num % 12;
-
-	note_freq = notes[note];
-
-	if (octave < BASE_OCTAVE)
-		note_freq >>= (BASE_OCTAVE - octave);
-	else if (octave > BASE_OCTAVE)
-		note_freq <<= (octave - BASE_OCTAVE);
-
-	/*
-	 * note_freq >>= 1;
-	 */
-
-	return note_freq;
-}
-
-unsigned long
-snd_seq_oss_compute_finetune(unsigned long base_freq, int bend, int range, int vibrato_cents)
-{
-	unsigned long amount;
-	int negative, semitones, cents, multiplier = 1;
-
-	if (!bend || !range || !base_freq)
-		return base_freq;
-
-	if (range >= 8192)
-		range = 8192;
-
-	bend = bend * range / 8192;	/* Convert to cents */
-	bend += vibrato_cents;
-
-	if (!bend)
-		return base_freq;
-
-	negative = bend < 0 ? 1 : 0;
-
-	if (bend < 0)
-		bend *= -1;
-	if (bend > range)
-		bend = range;
-
-	/*
-	   if (bend > 2399)
-	   bend = 2399;
-	 */
-	while (bend > 2399) {
-		multiplier *= 4;
-		bend -= 2400;
-	}
-
-	semitones = bend / 100;
-	if (semitones > 99)
-		semitones = 99;
-	cents = bend % 100;
-
-	amount = (int) (snd_seq_oss_semitone_tuning[semitones] * multiplier *
-			snd_seq_oss_cent_tuning[cents]) / 10000;
-
-	if (negative)
-		return (base_freq * 10000) / amount;	/* Bend down */
-	else
-		return (base_freq * amount) / 10000;	/* Bend up */
-}
-
diff -Nru a/sound/core/seq/oss/seq_oss_readq.c b/sound/core/seq/oss/seq_oss_readq.c
--- a/sound/core/seq/oss/seq_oss_readq.c	2005-03-01 23:38:54 -08:00
+++ b/sound/core/seq/oss/seq_oss_readq.c	2005-03-01 23:38:54 -08:00
@@ -74,8 +74,7 @@
 snd_seq_oss_readq_delete(seq_oss_readq_t *q)
 {
 	if (q) {
-		if (q->q)
-			kfree(q->q);
+		kfree(q->q);
 		kfree(q);
 	}
 }
diff -Nru a/sound/core/seq/oss/seq_oss_timer.c b/sound/core/seq/oss/seq_oss_timer.c
--- a/sound/core/seq/oss/seq_oss_timer.c	2005-03-01 23:38:54 -08:00
+++ b/sound/core/seq/oss/seq_oss_timer.c	2005-03-01 23:38:54 -08:00
@@ -149,7 +149,7 @@
 	ev.queue = dp->queue;
 	ev.data.queue.queue = dp->queue;
 	ev.data.queue.param.value = value;
-	return snd_seq_kernel_client_dispatch(dp->cseq, &ev, 0, 0);
+	return snd_seq_kernel_client_dispatch(dp->cseq, &ev, 1, 0);
 }
 
 /*
diff -Nru a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c
--- a/sound/core/seq/seq_clientmgr.c	2005-03-01 23:38:52 -08:00
+++ b/sound/core/seq/seq_clientmgr.c	2005-03-01 23:38:52 -08:00
@@ -751,8 +751,8 @@
  *               n == 0 : the event was not passed to any client.
  *               n < 0  : error - event was not processed.
  */
-int snd_seq_deliver_event(client_t *client, snd_seq_event_t *event,
-			  int atomic, int hop)
+static int snd_seq_deliver_event(client_t *client, snd_seq_event_t *event,
+				 int atomic, int hop)
 {
 	int result;
 
@@ -904,7 +904,7 @@
 		return -ENXIO; /* queue is not allocated */
 
 	/* allocate an event cell */
-	err = snd_seq_event_dup(client->pool, event, &cell, !blocking && !atomic, file);
+	err = snd_seq_event_dup(client->pool, event, &cell, !blocking || atomic, file);
 	if (err < 0)
 		return err;
 
diff -Nru a/sound/core/seq/seq_clientmgr.h b/sound/core/seq/seq_clientmgr.h
--- a/sound/core/seq/seq_clientmgr.h	2005-03-01 23:39:09 -08:00
+++ b/sound/core/seq/seq_clientmgr.h	2005-03-01 23:39:09 -08:00
@@ -100,6 +100,5 @@
 int snd_seq_kernel_client_enqueue_blocking(int client, snd_seq_event_t * ev, struct file *file, int atomic, int hop);
 int snd_seq_kernel_client_write_poll(int clientid, struct file *file, poll_table *wait);
 int snd_seq_client_notify_subscription(int client, int port, snd_seq_port_subscribe_t *info, int evtype);
-int snd_seq_deliver_event(client_t *client, snd_seq_event_t *event, int atomic, int hop);
 
 #endif
diff -Nru a/sound/core/seq/seq_instr.c b/sound/core/seq/seq_instr.c
--- a/sound/core/seq/seq_instr.c	2005-03-01 23:38:55 -08:00
+++ b/sound/core/seq/seq_instr.c	2005-03-01 23:38:55 -08:00
@@ -49,19 +49,7 @@
 	}
 }
 
-snd_seq_kcluster_t *snd_seq_cluster_new(int atomic)
-{
-	return kcalloc(1, sizeof(snd_seq_kcluster_t), atomic ? GFP_ATOMIC : GFP_KERNEL);
-}
-
-void snd_seq_cluster_free(snd_seq_kcluster_t *cluster, int atomic)
-{
-	if (cluster == NULL)
-		return;
-	kfree(cluster);
-}
-
-snd_seq_kinstr_t *snd_seq_instr_new(int add_len, int atomic)
+static snd_seq_kinstr_t *snd_seq_instr_new(int add_len, int atomic)
 {
 	snd_seq_kinstr_t *instr;
 	
@@ -72,7 +60,7 @@
 	return instr;
 }
 
-int snd_seq_instr_free(snd_seq_kinstr_t *instr, int atomic)
+static int snd_seq_instr_free(snd_seq_kinstr_t *instr, int atomic)
 {
 	int result = 0;
 
@@ -132,7 +120,7 @@
 		while ((cluster = list->chash[idx]) != NULL) {
 			list->chash[idx] = cluster->next;
 			list->ccount--;
-			snd_seq_cluster_free(cluster, 0);
+			kfree(cluster);
 		}
 	}
 	kfree(list);
diff -Nru a/sound/core/seq/seq_memory.c b/sound/core/seq/seq_memory.c
--- a/sound/core/seq/seq_memory.c	2005-03-01 23:38:52 -08:00
+++ b/sound/core/seq/seq_memory.c	2005-03-01 23:38:52 -08:00
@@ -215,7 +215,7 @@
 /*
  * allocate an event cell.
  */
-int snd_seq_cell_alloc(pool_t *pool, snd_seq_event_cell_t **cellp, int nonblock, struct file *file)
+static int snd_seq_cell_alloc(pool_t *pool, snd_seq_event_cell_t **cellp, int nonblock, struct file *file)
 {
 	snd_seq_event_cell_t *cell;
 	unsigned long flags;
@@ -436,8 +436,7 @@
 	pool->total_elements = 0;
 	spin_unlock_irqrestore(&pool->lock, flags);
 
-	if (ptr)
-		vfree(ptr);
+	vfree(ptr);
 
 	spin_lock_irqsave(&pool->lock, flags);
 	pool->closing = 0;
diff -Nru a/sound/core/seq/seq_memory.h b/sound/core/seq/seq_memory.h
--- a/sound/core/seq/seq_memory.h	2005-03-01 23:39:08 -08:00
+++ b/sound/core/seq/seq_memory.h	2005-03-01 23:39:08 -08:00
@@ -64,7 +64,6 @@
 };
 
 extern void snd_seq_cell_free(snd_seq_event_cell_t* cell);
-int snd_seq_cell_alloc(pool_t *pool, snd_seq_event_cell_t **cellp, int nonblock, struct file *file);
 
 int snd_seq_event_dup(pool_t *pool, snd_seq_event_t *event, snd_seq_event_cell_t **cellp, int nonblock, struct file *file);
 
diff -Nru a/sound/core/seq/seq_midi.c b/sound/core/seq/seq_midi.c
--- a/sound/core/seq/seq_midi.c	2005-03-01 23:39:19 -08:00
+++ b/sound/core/seq/seq_midi.c	2005-03-01 23:39:19 -08:00
@@ -43,10 +43,10 @@
 MODULE_AUTHOR("Frank van de Pol <fvdpol@coil.demon.nl>, Jaroslav Kysela <perex@suse.cz>");
 MODULE_DESCRIPTION("Advanced Linux Sound Architecture sequencer MIDI synth.");
 MODULE_LICENSE("GPL");
-int output_buffer_size = PAGE_SIZE;
+static int output_buffer_size = PAGE_SIZE;
 module_param(output_buffer_size, int, 0644);
 MODULE_PARM_DESC(output_buffer_size, "Output buffer size in bytes.");
-int input_buffer_size = PAGE_SIZE;
+static int input_buffer_size = PAGE_SIZE;
 module_param(input_buffer_size, int, 0644);
 MODULE_PARM_DESC(input_buffer_size, "Input buffer size in bytes.");
 
@@ -284,7 +284,7 @@
 }
 
 /* register new midi synth port */
-int
+static int
 snd_seq_midisynth_register_port(snd_seq_device_t *dev)
 {
 	seq_midisynth_client_t *client;
@@ -423,7 +423,7 @@
 }
 
 /* release midi synth port */
-int
+static int
 snd_seq_midisynth_unregister_port(snd_seq_device_t *dev)
 {
 	seq_midisynth_client_t *client;
diff -Nru a/sound/core/seq/seq_midi_emul.c b/sound/core/seq/seq_midi_emul.c
--- a/sound/core/seq/seq_midi_emul.c	2005-03-01 23:39:16 -08:00
+++ b/sound/core/seq/seq_midi_emul.c	2005-03-01 23:39:16 -08:00
@@ -53,7 +53,7 @@
 static void sysex(snd_midi_op_t *ops, void *private, unsigned char *sysex, int len, snd_midi_channel_set_t *chset);
 static void all_sounds_off(snd_midi_op_t *ops, void *private, snd_midi_channel_t *chan);
 static void all_notes_off(snd_midi_op_t *ops, void *private, snd_midi_channel_t *chan);
-void snd_midi_reset_controllers(snd_midi_channel_t *chan);
+static void snd_midi_reset_controllers(snd_midi_channel_t *chan);
 static void reset_all_channels(snd_midi_channel_set_t *chset);
 
 
@@ -549,12 +549,12 @@
 
 		} else if (buf[5] == 0x01 && buf[6] == 0x30) {
 			/* reverb mode */
-			parsed = SNDRV_MIDI_SYSEX_GS_CHORUS_MODE;
+			parsed = SNDRV_MIDI_SYSEX_GS_REVERB_MODE;
 			chset->gs_reverb_mode = buf[7];
 
 		} else if (buf[5] == 0x01 && buf[6] == 0x38) {
 			/* chorus mode */
-			parsed = SNDRV_MIDI_SYSEX_GS_REVERB_MODE;
+			parsed = SNDRV_MIDI_SYSEX_GS_CHORUS_MODE;
 			chset->gs_chorus_mode = buf[7];
 
 		} else if (buf[5] == 0x00 && buf[6] == 0x04) {
@@ -621,7 +621,7 @@
 /*
  * Initialise a single midi channel control block.
  */
-void snd_midi_channel_init(snd_midi_channel_t *p, int n)
+static void snd_midi_channel_init(snd_midi_channel_t *p, int n)
 {
 	if (p == NULL)
 		return;
@@ -642,7 +642,7 @@
 /*
  * Allocate and initialise a set of midi channel control blocks.
  */
-snd_midi_channel_t *snd_midi_channel_init_set(int n)
+static snd_midi_channel_t *snd_midi_channel_init_set(int n)
 {
 	snd_midi_channel_t *chan;
 	int  i;
@@ -697,7 +697,7 @@
 /*
  * Reset the midi controllers on a particular channel to default values.
  */
-void snd_midi_reset_controllers(snd_midi_channel_t *chan)
+static void snd_midi_reset_controllers(snd_midi_channel_t *chan)
 {
 	memset(chan->control, 0, sizeof(chan->control));
 	chan->gm_volume = 127;
@@ -713,8 +713,7 @@
 {
 	if (chset == NULL)
 		return;
-	if (chset->channels != NULL)
-		kfree(chset->channels);
+	kfree(chset->channels);
 	kfree(chset);
 }
 
@@ -732,7 +731,5 @@
 
 EXPORT_SYMBOL(snd_midi_process_event);
 EXPORT_SYMBOL(snd_midi_channel_set_clear);
-EXPORT_SYMBOL(snd_midi_channel_init);
-EXPORT_SYMBOL(snd_midi_channel_init_set);
 EXPORT_SYMBOL(snd_midi_channel_alloc_set);
 EXPORT_SYMBOL(snd_midi_channel_free_set);
diff -Nru a/sound/core/seq/seq_midi_event.c b/sound/core/seq/seq_midi_event.c
--- a/sound/core/seq/seq_midi_event.c	2005-03-01 23:38:44 -08:00
+++ b/sound/core/seq/seq_midi_event.c	2005-03-01 23:38:44 -08:00
@@ -138,8 +138,7 @@
 void snd_midi_event_free(snd_midi_event_t *dev)
 {
 	if (dev != NULL) {
-		if (dev->buf)
-			kfree(dev->buf);
+		kfree(dev->buf);
 		kfree(dev);
 	}
 }
@@ -202,8 +201,7 @@
 	dev->bufsize = bufsize;
 	reset_encode(dev);
 	spin_unlock_irqrestore(&dev->lock, flags);
-	if (old_buf)
-		kfree(old_buf);
+	kfree(old_buf);
 	return 0;
 }
 
diff -Nru a/sound/core/sgbuf.c b/sound/core/sgbuf.c
--- a/sound/core/sgbuf.c	2005-03-01 23:39:07 -08:00
+++ b/sound/core/sgbuf.c	2005-03-01 23:39:07 -08:00
@@ -51,10 +51,8 @@
 		vunmap(dmab->area);
 	dmab->area = NULL;
 
-	if (sgbuf->table)
-		kfree(sgbuf->table);
-	if (sgbuf->page_table)
-		kfree(sgbuf->page_table);
+	kfree(sgbuf->table);
+	kfree(sgbuf->page_table);
 	kfree(sgbuf);
 	dmab->private_data = NULL;
 	
diff -Nru a/sound/core/sound.c b/sound/core/sound.c
--- a/sound/core/sound.c	2005-03-01 23:39:07 -08:00
+++ b/sound/core/sound.c	2005-03-01 23:39:07 -08:00
@@ -159,7 +159,7 @@
 	return err;
 }
 
-struct file_operations snd_fops =
+static struct file_operations snd_fops =
 {
 	.owner =	THIS_MODULE,
 	.open =		snd_open
@@ -228,12 +228,11 @@
 		return -EBUSY;
 	}
 	list_add_tail(&preg->list, &snd_minors_hash[SNDRV_MINOR_CARD(minor)]);
-	if (strncmp(name, "controlC", 8) || card->number >= cards_limit) {
+	if (strncmp(name, "controlC", 8) || card->number >= cards_limit)
 		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);
-	}
+	if (card)
+		device = card->dev;
+	class_simple_device_add(sound_class, MKDEV(major, minor), device, name);
 
 	up(&sound_mutex);
 	return 0;
@@ -263,10 +262,9 @@
 		return -EINVAL;
 	}
 
-	if (strncmp(mptr->name, "controlC", 8) || card->number >= cards_limit) { /* created in sound.c */
+	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_simple_device_remove(MKDEV(major, minor));
 
 	list_del(&mptr->list);
 	up(&sound_mutex);
@@ -357,10 +355,8 @@
 		return -ENOMEM;
 	}
 	snd_info_minor_register();
-	for (controlnum = 0; controlnum < cards_limit; controlnum++) {
+	for (controlnum = 0; controlnum < cards_limit; controlnum++)
 		devfs_mk_cdev(MKDEV(major, controlnum<<5), S_IFCHR | device_mode, "snd/controlC%d", controlnum);
-		class_simple_device_add(sound_class, MKDEV(major, controlnum<<5), NULL, "controlC%d", controlnum);
-	}
 #ifndef MODULE
 	printk(KERN_INFO "Advanced Linux Sound Architecture Driver Version " CONFIG_SND_VERSION CONFIG_SND_DATE ".\n");
 #endif
@@ -371,10 +367,8 @@
 {
 	short controlnum;
 
-	for (controlnum = 0; controlnum < cards_limit; controlnum++) {
+	for (controlnum = 0; controlnum < cards_limit; controlnum++)
 		devfs_remove("snd/controlC%d", controlnum);
-		class_simple_device_remove(MKDEV(major, controlnum<<5));
-	}
 
 	snd_info_minor_unregister();
 	snd_info_done();
@@ -411,7 +405,6 @@
 EXPORT_SYMBOL(copy_to_user_fromio);
 EXPORT_SYMBOL(copy_from_user_toio);
   /* init.c */
-EXPORT_SYMBOL(snd_cards_count);
 EXPORT_SYMBOL(snd_cards);
 #if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
 EXPORT_SYMBOL(snd_mixer_oss_notify_callback);
@@ -447,8 +440,6 @@
   /* info.c */
 #ifdef CONFIG_PROC_FS
 EXPORT_SYMBOL(snd_seq_root);
-EXPORT_SYMBOL(snd_create_proc_entry);
-EXPORT_SYMBOL(snd_remove_proc_entry);
 EXPORT_SYMBOL(snd_iprintf);
 EXPORT_SYMBOL(snd_info_get_line);
 EXPORT_SYMBOL(snd_info_get_str);
@@ -476,6 +467,8 @@
 EXPORT_SYMBOL(snd_ctl_notify);
 EXPORT_SYMBOL(snd_ctl_register_ioctl);
 EXPORT_SYMBOL(snd_ctl_unregister_ioctl);
+EXPORT_SYMBOL(snd_ctl_elem_read);
+EXPORT_SYMBOL(snd_ctl_elem_write);
   /* misc.c */
 EXPORT_SYMBOL(snd_task_name);
 #ifdef CONFIG_SND_VERBOSE_PRINTK
diff -Nru a/sound/core/timer.c b/sound/core/timer.c
--- a/sound/core/timer.c	2005-03-01 23:39:07 -08:00
+++ b/sound/core/timer.c	2005-03-01 23:39:07 -08:00
@@ -351,8 +351,7 @@
 	}
 	if (timeri->private_free)
 		timeri->private_free(timeri);
-	if (timeri->owner)
-		kfree(timeri->owner);
+	kfree(timeri->owner);
 	kfree(timeri);
 	if (timer && timer->card)
 		module_put(timer->card->module);
@@ -1004,8 +1003,7 @@
 
 static void snd_timer_free_system(snd_timer_t *timer)
 {
-	if (timer->private_data)
-		kfree(timer->private_data);
+	kfree(timer->private_data);
 }
 
 static int snd_timer_register_system(void)
@@ -1226,10 +1224,8 @@
 		fasync_helper(-1, file, 0, &tu->fasync);
 		if (tu->timeri)
 			snd_timer_close(tu->timeri);
-		if (tu->queue)
-			kfree(tu->queue);
-		if (tu->tqueue)
-			kfree(tu->tqueue);
+		kfree(tu->queue);
+		kfree(tu->tqueue);
 		kfree(tu);
 	}
 	return 0;
diff -Nru a/sound/drivers/opl3/Makefile b/sound/drivers/opl3/Makefile
--- a/sound/drivers/opl3/Makefile	2005-03-01 23:38:44 -08:00
+++ b/sound/drivers/opl3/Makefile	2005-03-01 23:38:44 -08:00
@@ -18,4 +18,5 @@
 sequencer = $(if $(subst y,,$(CONFIG_SND_SEQUENCER)),$(if $(1),m),$(if $(CONFIG_SND_SEQUENCER),$(1)))
 
 obj-$(CONFIG_SND_OPL3_LIB) += snd-opl3-lib.o
+obj-$(CONFIG_SND_OPL4_LIB) += snd-opl3-lib.o
 obj-$(call sequencer,$(CONFIG_SND_OPL3_LIB)) += snd-opl3-synth.o
diff -Nru a/sound/drivers/opl3/opl3_drums.c b/sound/drivers/opl3/opl3_drums.c
--- a/sound/drivers/opl3/opl3_drums.c	2005-03-01 23:39:18 -08:00
+++ b/sound/drivers/opl3/opl3_drums.c	2005-03-01 23:39:18 -08:00
@@ -80,7 +80,7 @@
 /*
  * set drum voice characteristics
  */
-void snd_opl3_drum_voice_set(opl3_t *opl3, snd_opl3_drum_voice_t *data)
+static void snd_opl3_drum_voice_set(opl3_t *opl3, snd_opl3_drum_voice_t *data)
 {
 	unsigned char op_offset = snd_opl3_regmap[data->voice][data->op];
 	unsigned char voice_offset = data->voice;
@@ -114,7 +114,7 @@
 /*
  * Set drum voice pitch
  */
-void snd_opl3_drum_note_set(opl3_t *opl3, snd_opl3_drum_note_t *data)
+static void snd_opl3_drum_note_set(opl3_t *opl3, snd_opl3_drum_note_t *data)
 {
 	unsigned char voice_offset = data->voice;
 	unsigned short opl3_reg;
@@ -131,8 +131,8 @@
 /*
  * Set drum voice volume and position
  */
-void snd_opl3_drum_vol_set(opl3_t *opl3, snd_opl3_drum_voice_t *data, int vel,
-			   snd_midi_channel_t *chan)
+static void snd_opl3_drum_vol_set(opl3_t *opl3, snd_opl3_drum_voice_t *data,
+				  int vel, snd_midi_channel_t *chan)
 {
 	unsigned char op_offset = snd_opl3_regmap[data->voice][data->op];
 	unsigned char voice_offset = data->voice;
diff -Nru a/sound/drivers/opl3/opl3_lib.c b/sound/drivers/opl3/opl3_lib.c
--- a/sound/drivers/opl3/opl3_lib.c	2005-03-01 23:38:53 -08:00
+++ b/sound/drivers/opl3/opl3_lib.c	2005-03-01 23:38:53 -08:00
@@ -37,7 +37,7 @@
 
 extern char snd_opl3_regmap[MAX_OPL2_VOICES][4];
 
-void snd_opl2_command(opl3_t * opl3, unsigned short cmd, unsigned char val)
+static void snd_opl2_command(opl3_t * opl3, unsigned short cmd, unsigned char val)
 {
 	unsigned long flags;
 	unsigned long port;
@@ -60,7 +60,7 @@
 	spin_unlock_irqrestore(&opl3->reg_lock, flags);
 }
 
-void snd_opl3_command(opl3_t * opl3, unsigned short cmd, unsigned char val)
+static void snd_opl3_command(opl3_t * opl3, unsigned short cmd, unsigned char val)
 {
 	unsigned long flags;
 	unsigned long port;
@@ -364,7 +364,7 @@
 	spin_lock_init(&opl3->timer_lock);
 	init_MUTEX(&opl3->access_mutex);
 
-	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, opl3, &ops)) < 0) {
+	if ((err = snd_device_new(card, SNDRV_DEV_CODEC, opl3, &ops)) < 0) {
 		snd_opl3_free(opl3);
 		return err;
 	}
diff -Nru a/sound/drivers/opl3/opl3_midi.c b/sound/drivers/opl3/opl3_midi.c
--- a/sound/drivers/opl3/opl3_midi.c	2005-03-01 23:38:58 -08:00
+++ b/sound/drivers/opl3/opl3_midi.c	2005-03-01 23:38:58 -08:00
@@ -263,7 +263,7 @@
 /*
  * Start system timer
  */
-void snd_opl3_start_timer(opl3_t *opl3)
+static void snd_opl3_start_timer(opl3_t *opl3)
 {
 	unsigned long flags;
 	spin_lock_irqsave(&opl3->sys_timer_lock, flags);
diff -Nru a/sound/drivers/opl3/opl3_seq.c b/sound/drivers/opl3/opl3_seq.c
--- a/sound/drivers/opl3/opl3_seq.c	2005-03-01 23:39:07 -08:00
+++ b/sound/drivers/opl3/opl3_seq.c	2005-03-01 23:39:07 -08:00
@@ -96,7 +96,7 @@
 	up(&opl3->access_mutex);
 }
 
-int snd_opl3_synth_use(void *private_data, snd_seq_port_subscribe_t * info)
+static int snd_opl3_synth_use(void *private_data, snd_seq_port_subscribe_t * info)
 {
 	opl3_t *opl3 = private_data;
 	int err;
@@ -123,7 +123,7 @@
 	return 0;
 }
 
-int snd_opl3_synth_unuse(void *private_data, snd_seq_port_subscribe_t * info)
+static int snd_opl3_synth_unuse(void *private_data, snd_seq_port_subscribe_t * info)
 {
 	opl3_t *opl3 = private_data;
 
diff -Nru a/sound/drivers/opl4/opl4_lib.c b/sound/drivers/opl4/opl4_lib.c
--- a/sound/drivers/opl4/opl4_lib.c	2005-03-01 23:39:16 -08:00
+++ b/sound/drivers/opl4/opl4_lib.c	2005-03-01 23:39:16 -08:00
@@ -229,21 +229,20 @@
 		return err;
 	}
 
-	err = snd_opl3_create(card, fm_port, fm_port + 2, opl4->hardware, 1, &opl3);
+	err = snd_device_new(card, SNDRV_DEV_CODEC, opl4, &ops);
 	if (err < 0) {
 		snd_opl4_free(opl4);
 		return err;
 	}
 
-	/* opl3 initialization disabled opl4, so reenable */
-	snd_opl4_enable_opl4(opl4);
-
-	err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, opl4, &ops);
+	err = snd_opl3_create(card, fm_port, fm_port + 2, opl4->hardware, 1, &opl3);
 	if (err < 0) {
-		snd_device_free(card, opl3);
-		snd_opl4_free(opl4);
+		snd_device_free(card, opl4);
 		return err;
 	}
+
+	/* opl3 initialization disabled opl4, so reenable */
+	snd_opl4_enable_opl4(opl4);
 
 	snd_opl4_create_mixer(opl4);
 #ifdef CONFIG_PROC_FS
diff -Nru a/sound/drivers/vx/vx_cmd.c b/sound/drivers/vx/vx_cmd.c
--- a/sound/drivers/vx/vx_cmd.c	2005-03-01 23:39:08 -08:00
+++ b/sound/drivers/vx/vx_cmd.c	2005-03-01 23:39:08 -08:00
@@ -29,7 +29,7 @@
 /*
  * Array of DSP commands
  */
-struct vx_cmd_info vx_dsp_cmds[] = {
+static struct vx_cmd_info vx_dsp_cmds[] = {
 [CMD_VERSION] =			{ 0x010000, 2, RMH_SSIZE_FIXED, 1 },
 [CMD_SUPPORTED] =		{ 0x020000, 1, RMH_SSIZE_FIXED, 2 },
 [CMD_TEST_IT] =			{ 0x040000, 1, RMH_SSIZE_FIXED, 1 },
diff -Nru a/sound/drivers/vx/vx_cmd.h b/sound/drivers/vx/vx_cmd.h
--- a/sound/drivers/vx/vx_cmd.h	2005-03-01 23:38:55 -08:00
+++ b/sound/drivers/vx/vx_cmd.h	2005-03-01 23:38:55 -08:00
@@ -209,8 +209,6 @@
 /*
  *
  */
-extern struct vx_cmd_info vx_dsp_cmds[];
-
 void vx_init_rmh(struct vx_rmh *rmh, unsigned int cmd);
 
 /**
diff -Nru a/sound/drivers/vx/vx_core.c b/sound/drivers/vx/vx_core.c
--- a/sound/drivers/vx/vx_core.c	2005-03-01 23:39:16 -08:00
+++ b/sound/drivers/vx/vx_core.c	2005-03-01 23:39:16 -08:00
@@ -25,6 +25,7 @@
 #include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
+#include <linux/firmware.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/asoundef.h>
@@ -430,20 +431,19 @@
  * snd_vx_boot_xilinx - boot up the xilinx interface
  * @boot: the boot record to load
  */
-int snd_vx_load_boot_image(vx_core_t *chip, const snd_hwdep_dsp_image_t *boot)
+int snd_vx_load_boot_image(vx_core_t *chip, const struct firmware *boot)
 {
 	unsigned int i;
 	int no_fillup = vx_has_new_dsp(chip);
 
 	/* check the length of boot image */
-	snd_assert(boot->length > 0, return -EINVAL);
-	snd_assert(boot->length % 3 == 0, return -EINVAL);
-	snd_assert(boot->image, return -EINVAL);
+	snd_assert(boot->size > 0, return -EINVAL);
+	snd_assert(boot->size % 3 == 0, return -EINVAL);
 #if 0
 	{
 		/* more strict check */
-		unsigned int c = ((u32)boot->image[0] << 16) | ((u32)boot->image[1] << 8) | boot->image[2];
-		snd_assert(boot->length == (c + 2) * 3, return -EINVAL);
+		unsigned int c = ((u32)boot->data[0] << 16) | ((u32)boot->data[1] << 8) | boot->data[2];
+		snd_assert(boot->size == (c + 2) * 3, return -EINVAL);
 	}
 #endif
 
@@ -454,7 +454,7 @@
 
 	/* download boot strap */
 	for (i = 0; i < 0x600; i += 3) {
-		if (i >= boot->length) {
+		if (i >= boot->size) {
 			if (no_fillup)
 				break;
 			if (vx_wait_isr_bit(chip, ISR_TX_EMPTY) < 0) {
@@ -465,9 +465,7 @@
 			vx_outb(chip, TXM, 0);
 			vx_outb(chip, TXL, 0);
 		} else {
-			unsigned char image[3];
-			if (copy_from_user(image, boot->image + i, 3))
-				return -EFAULT;
+			unsigned char *image = boot->data + i;
 			if (vx_wait_isr_bit(chip, ISR_TX_EMPTY) < 0) {
 				snd_printk(KERN_ERR "dsp boot failed at %d\n", i);
 				return -EIO;
@@ -653,7 +651,7 @@
 /**
  * snd_vx_dsp_boot - load the DSP boot
  */
-int snd_vx_dsp_boot(vx_core_t *chip, const snd_hwdep_dsp_image_t *boot)
+int snd_vx_dsp_boot(vx_core_t *chip, const struct firmware *boot)
 {
 	int err;
 	int cold_reset = !(chip->chip_status & VX_STAT_DEVICE_INIT);
@@ -671,21 +669,20 @@
 /**
  * snd_vx_dsp_load - load the DSP image
  */
-int snd_vx_dsp_load(vx_core_t *chip, const snd_hwdep_dsp_image_t *dsp)
+int snd_vx_dsp_load(vx_core_t *chip, const struct firmware *dsp)
 {
 	unsigned int i;
 	int err;
 	unsigned int csum = 0;
-	unsigned char image[3], *cptr;
+	unsigned char *image, *cptr;
 
-	snd_assert(dsp->length % 3 == 0, return -EINVAL);
+	snd_assert(dsp->size % 3 == 0, return -EINVAL);
 
 	vx_toggle_dac_mute(chip, 1);
 
 	/* Transfert data buffer from PC to DSP */
-	for (i = 0; i < dsp->length; i += 3) {
-		if (copy_from_user(image, dsp->image + i, 3))
-			return -EFAULT;
+	for (i = 0; i < dsp->size; i += 3) {
+		image = dsp->data + i;
 		/* Wait DSP ready for a new read */
 		if ((err = vx_wait_isr_bit(chip, ISR_TX_EMPTY)) < 0) {
 			printk("dsp loading error at position %d\n", i);
@@ -717,6 +714,54 @@
 	return 0;
 }
 
+#ifdef CONFIG_PM
+/*
+ * suspend
+ */
+static int snd_vx_suspend(snd_card_t *card, unsigned int state)
+{
+	vx_core_t *chip = card->pm_private_data;
+	unsigned int i;
+
+	snd_assert(chip, return -EINVAL);
+
+	chip->chip_status |= VX_STAT_IN_SUSPEND;
+	for (i = 0; i < chip->hw->num_codecs; i++)
+		snd_pcm_suspend_all(chip->pcm[i]);
+
+	return 0;
+}
+
+/*
+ * resume
+ */
+static int snd_vx_resume(snd_card_t *card, unsigned int state)
+{
+	vx_core_t *chip = card->pm_private_data;
+	int i, err;
+
+	snd_assert(chip, return -EINVAL);
+
+	chip->chip_status &= ~VX_STAT_CHIP_INIT;
+
+	for (i = 0; i < 4; i++) {
+		if (! chip->firmware[i])
+			continue;
+		err = chip->ops->load_dsp(chip, i, chip->firmware[i]);
+		if (err < 0) {
+			snd_printk(KERN_ERR "vx: firmware resume error at DSP %d\n", i);
+			return -EIO;
+		}
+	}
+
+	chip->chip_status |= VX_STAT_CHIP_INIT;
+	chip->chip_status &= ~VX_STAT_IN_SUSPEND;
+
+	return 0;
+}
+
+#endif
+
 /**
  * snd_vx_create - constructor for vx_core_t
  * @hw: hardware specific record
@@ -734,7 +779,7 @@
 
 	snd_assert(card && hw && ops, return NULL);
 
-	chip = kcalloc(1, sizeof(chip) + extra_size, GFP_KERNEL);
+	chip = kcalloc(1, sizeof(*chip) + extra_size, GFP_KERNEL);
 	if (! chip) {
 		snd_printk(KERN_ERR "vx_core: no memory\n");
 		return NULL;
@@ -753,37 +798,13 @@
 	strcpy(card->driver, hw->name);
 	sprintf(card->shortname, "Digigram %s", hw->name);
 
+	snd_card_set_pm_callback(card, snd_vx_suspend, snd_vx_resume, chip);
+
 	vx_proc_init(chip);
 
 	return chip;
 }
 
-#ifdef CONFIG_PM
-/*
- * suspend
- */
-void snd_vx_suspend(vx_core_t *chip)
-{
-	unsigned int i;
-
-	chip->chip_status |= VX_STAT_IN_SUSPEND;
-	for (i = 0; i < chip->hw->num_codecs; i++)
-		snd_pcm_suspend_all(chip->pcm[i]);
-	if (chip->hwdep)
-		chip->hwdep->dsp_loaded = 0;
-}
-
-/*
- * resume
- */
-void snd_vx_resume(vx_core_t *chip)
-{
-	/* clear all stuff... */
-	chip->chip_status &= ~(VX_STAT_IN_SUSPEND|VX_STAT_CHIP_INIT);
-}
-
-#endif
-
 /*
  * module entries
  */
@@ -804,13 +825,10 @@
  */
 EXPORT_SYMBOL(snd_vx_check_reg_bit);
 EXPORT_SYMBOL(snd_vx_create);
-EXPORT_SYMBOL(snd_vx_hwdep_new);
+EXPORT_SYMBOL(snd_vx_setup_firmware);
+EXPORT_SYMBOL(snd_vx_free_firmware);
 EXPORT_SYMBOL(snd_vx_irq_handler);
 EXPORT_SYMBOL(snd_vx_delay);
 EXPORT_SYMBOL(snd_vx_dsp_boot);
 EXPORT_SYMBOL(snd_vx_dsp_load);
 EXPORT_SYMBOL(snd_vx_load_boot_image);
-#ifdef CONFIG_PM
-EXPORT_SYMBOL(snd_vx_suspend);
-EXPORT_SYMBOL(snd_vx_resume);
-#endif
diff -Nru a/sound/drivers/vx/vx_hwdep.c b/sound/drivers/vx/vx_hwdep.c
--- a/sound/drivers/vx/vx_hwdep.c	2005-03-01 23:38:55 -08:00
+++ b/sound/drivers/vx/vx_hwdep.c	2005-03-01 23:38:55 -08:00
@@ -1,7 +1,7 @@
 /*
  * Driver for Digigram VX soundcards
  *
- * hwdep device manager
+ * DSP firmware management
  *
  * Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
  *
@@ -21,10 +21,89 @@
  */
 
 #include <sound/driver.h>
+#include <linux/firmware.h>
 #include <sound/core.h>
 #include <sound/hwdep.h>
 #include <sound/vx_core.h>
 
+#ifdef SND_VX_FW_LOADER
+
+int snd_vx_setup_firmware(vx_core_t *chip)
+{
+	static char *fw_files[VX_TYPE_NUMS][4] = {
+		[VX_TYPE_BOARD] = {
+			NULL, "x1_1_vx2.xlx", "bd56002.boot", "l_1_vx2.d56",
+		},
+		[VX_TYPE_V2] = {
+			NULL, "x1_2_v22.xlx", "bd563v2.boot", "l_1_v22.d56",
+		},
+		[VX_TYPE_MIC] = {
+			NULL, "x1_2_v22.xlx", "bd563v2.boot", "l_1_v22.d56",
+		},
+		[VX_TYPE_VXPOCKET] = {
+			"bx_1_vxp.b56", "x1_1_vxp.xlx", "bd563s3.boot", "l_1_vxp.d56"
+		},
+		[VX_TYPE_VXP440] = {
+			"bx_1_vp4.b56", "x1_1_vp4.xlx", "bd563s3.boot", "l_1_vp4.d56"
+		},
+	};
+
+	int i, err;
+
+	for (i = 0; i < 4; i++) {
+		char path[32];
+		const struct firmware *fw;
+		if (! fw_files[chip->type][i])
+			continue;
+		sprintf(path, "vx/%s", fw_files[chip->type][i]);
+		if (request_firmware(&fw, path, chip->dev)) {
+			snd_printk(KERN_ERR "vx: can't load firmware %s\n", path);
+			return -ENOENT;
+		}
+		err = chip->ops->load_dsp(chip, i, fw);
+		if (err < 0) {
+			release_firmware(fw);
+			return err;
+		}
+		if (i == 1)
+			chip->chip_status |= VX_STAT_XILINX_LOADED;
+#ifdef CONFIG_PM
+		chip->firmware[i] = fw;
+#else
+		release_firmware(fw);
+#endif
+	}
+
+	/* ok, we reached to the last one */
+	/* create the devices if not built yet */
+	if ((err = snd_vx_pcm_new(chip)) < 0)
+		return err;
+
+	if ((err = snd_vx_mixer_new(chip)) < 0)
+		return err;
+
+	if (chip->ops->add_controls)
+		if ((err = chip->ops->add_controls(chip)) < 0)
+			return err;
+
+	chip->chip_status |= VX_STAT_DEVICE_INIT;
+	chip->chip_status |= VX_STAT_CHIP_INIT;
+
+	return snd_card_register(chip->card);
+}
+
+/* exported */
+void snd_vx_free_firmware(vx_core_t *chip)
+{
+#ifdef CONFIG_PM
+	int i;
+	for (i = 0; i < 4; i++)
+		release_firmware(chip->firmware[i]);
+#endif
+}
+
+#else /* old style firmware loading */
+
 static int vx_hwdep_open(snd_hwdep_t *hw, struct file *file)
 {
 	return 0;
@@ -58,19 +137,54 @@
 	return 0;
 }
 
+static void free_fw(const struct firmware *fw)
+{
+	if (fw) {
+		vfree(fw->data);
+		kfree(fw);
+	}
+}
+
 static int vx_hwdep_dsp_load(snd_hwdep_t *hw, snd_hwdep_dsp_image_t *dsp)
 {
 	vx_core_t *vx = hw->private_data;
 	int index, err;
+	struct firmware *fw;
 
 	snd_assert(vx->ops->load_dsp, return -ENXIO);
-	err = vx->ops->load_dsp(vx, dsp);
-	if (err < 0)
-		return err;
+
+	fw = kmalloc(sizeof(*fw), GFP_KERNEL);
+	if (! fw) {
+		snd_printk(KERN_ERR "cannot allocate firmware\n");
+		return -ENOMEM;
+	}
+	fw->size = dsp->length;
+	fw->data = vmalloc(fw->size);
+	if (! fw->data) {
+		snd_printk(KERN_ERR "cannot allocate firmware image (length=%d)\n",
+			   (int)fw->size);
+		kfree(fw);
+		return -ENOMEM;
+	}
+	if (copy_from_user(fw->data, dsp->image, dsp->length)) {
+		free_fw(fw);
+		return -EFAULT;
+	}
 
 	index = dsp->index;
 	if (! vx_is_pcmcia(vx))
 		index++;
+	err = vx->ops->load_dsp(vx, index, fw);
+	if (err < 0) {
+		free_fw(fw);
+		return err;
+	}
+#ifdef CONFIG_PM
+	vx->firmware[index] = fw;
+#else
+	free_fw(fw);
+#endif
+
 	if (index == 1)
 		vx->chip_status |= VX_STAT_XILINX_LOADED;
 	if (index < 3)
@@ -100,7 +214,7 @@
 
 
 /* exported */
-int snd_vx_hwdep_new(vx_core_t *chip)
+int snd_vx_setup_firmware(vx_core_t *chip)
 {
 	int err;
 	snd_hwdep_t *hw;
@@ -118,5 +232,17 @@
 	sprintf(hw->name, "VX Loader (%s)", chip->card->driver);
 	chip->hwdep = hw;
 
-	return 0;
+	return snd_card_register(chip->card);
 }
+
+/* exported */
+void snd_vx_free_firmware(vx_core_t *chip)
+{
+#ifdef CONFIG_PM
+	int i;
+	for (i = 0; i < 4; i++)
+		free_fw(chip->firmware[i]);
+#endif
+}
+
+#endif /* SND_VX_FW_LOADER */
diff -Nru a/sound/drivers/vx/vx_pcm.c b/sound/drivers/vx/vx_pcm.c
--- a/sound/drivers/vx/vx_pcm.c	2005-03-01 23:38:52 -08:00
+++ b/sound/drivers/vx/vx_pcm.c	2005-03-01 23:38:52 -08:00
@@ -549,7 +549,8 @@
 
 static snd_pcm_hardware_t vx_pcm_playback_hw = {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
-				 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_MMAP_VALID),
+				 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_MMAP_VALID |
+				 SNDRV_PCM_INFO_RESUME),
 	.formats =		/*SNDRV_PCM_FMTBIT_U8 |*/ SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_3LE,
 	.rates =		SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
 	.rate_min =		5000,
@@ -802,6 +803,7 @@
 		
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
+	case SNDRV_PCM_TRIGGER_RESUME:
 		if (! pipe->is_capture)
 			vx_pcm_playback_transfer(chip, subs, pipe, 2);
 		/* FIXME:
@@ -813,6 +815,7 @@
 		pipe->running = 1;
 		break;
 	case SNDRV_PCM_TRIGGER_STOP:
+	case SNDRV_PCM_TRIGGER_SUSPEND:
 		vx_toggle_pipe(chip, pipe, 0);
 		vx_stop_pipe(chip, pipe);
 		vx_stop_stream(chip, pipe);
@@ -946,7 +949,8 @@
 
 static snd_pcm_hardware_t vx_pcm_capture_hw = {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
-				 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_MMAP_VALID),
+				 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_MMAP_VALID |
+				 SNDRV_PCM_INFO_RESUME),
 	.formats =		/*SNDRV_PCM_FMTBIT_U8 |*/ SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_3LE,
 	.rates =		SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
 	.rate_min =		5000,
diff -Nru a/sound/drivers/vx/vx_uer.c b/sound/drivers/vx/vx_uer.c
--- a/sound/drivers/vx/vx_uer.c	2005-03-01 23:38:54 -08:00
+++ b/sound/drivers/vx/vx_uer.c	2005-03-01 23:38:54 -08:00
@@ -197,7 +197,7 @@
  * vx_change_clock_source - change the clock source
  * @source: the new source
  */
-void vx_change_clock_source(vx_core_t *chip, int source)
+static void vx_change_clock_source(vx_core_t *chip, int source)
 {
 	unsigned long flags;
 
diff -Nru a/sound/i2c/cs8427.c b/sound/i2c/cs8427.c
--- a/sound/i2c/cs8427.c	2005-03-01 23:38:44 -08:00
+++ b/sound/i2c/cs8427.c	2005-03-01 23:38:44 -08:00
@@ -30,6 +30,8 @@
 #include <sound/cs8427.h>
 #include <sound/asoundef.h>
 
+static void snd_cs8427_reset(snd_i2c_device_t *cs8427);
+
 MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
 MODULE_DESCRIPTION("IEC958 (S/PDIF) receiver & transmitter by Cirrus Logic");
 MODULE_LICENSE("GPL");
@@ -65,16 +67,6 @@
 	return res;
 }
 
-int snd_cs8427_detect(snd_i2c_bus_t *bus, unsigned char addr)
-{
-	int res;
-
-	snd_i2c_lock(bus);
-	res = snd_i2c_probeaddr(bus, CS8427_ADDR | (addr & 7));
-	snd_i2c_unlock(bus);
-	return res;
-}
-
 int snd_cs8427_reg_write(snd_i2c_device_t *device, unsigned char reg, unsigned char val)
 {
 	int err;
@@ -89,7 +81,7 @@
 	return 0;
 }
 
-int snd_cs8427_reg_read(snd_i2c_device_t *device, unsigned char reg)
+static int snd_cs8427_reg_read(snd_i2c_device_t *device, unsigned char reg)
 {
 	int err;
 	unsigned char buf;
@@ -156,8 +148,7 @@
 
 static void snd_cs8427_free(snd_i2c_device_t *device)
 {
-	if (device->private_data)
-		kfree(device->private_data);
+	kfree(device->private_data);
 }
 
 int snd_cs8427_create(snd_i2c_bus_t *bus,
@@ -288,7 +279,7 @@
  * put back AES3INPUT. This workaround is described in latest
  * CS8427 datasheet, otherwise TXDSERIAL will not work.
  */
-void snd_cs8427_reset(snd_i2c_device_t *cs8427)
+static void snd_cs8427_reset(snd_i2c_device_t *cs8427)
 {
 	cs8427_t *chip;
 	unsigned long end_time;
@@ -573,11 +564,9 @@
 module_init(alsa_cs8427_module_init)
 module_exit(alsa_cs8427_module_exit)
 
-EXPORT_SYMBOL(snd_cs8427_detect);
 EXPORT_SYMBOL(snd_cs8427_create);
 EXPORT_SYMBOL(snd_cs8427_reset);
 EXPORT_SYMBOL(snd_cs8427_reg_write);
-EXPORT_SYMBOL(snd_cs8427_reg_read);
 EXPORT_SYMBOL(snd_cs8427_iec958_build);
 EXPORT_SYMBOL(snd_cs8427_iec958_active);
 EXPORT_SYMBOL(snd_cs8427_iec958_pcm);
diff -Nru a/sound/i2c/i2c.c b/sound/i2c/i2c.c
--- a/sound/i2c/i2c.c	2005-03-01 23:38:56 -08:00
+++ b/sound/i2c/i2c.c	2005-03-01 23:38:56 -08:00
@@ -94,7 +94,7 @@
 		bus->master = master;
 	}
 	strlcpy(bus->name, name, sizeof(bus->name));
-	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, bus, &ops)) < 0) {
+	if ((err = snd_device_new(card, SNDRV_DEV_BUS, bus, &ops)) < 0) {
 		snd_i2c_bus_free(bus);
 		return err;
 	}
diff -Nru a/sound/i2c/l3/uda1341.c b/sound/i2c/l3/uda1341.c
--- a/sound/i2c/l3/uda1341.c	2005-03-01 23:38:57 -08:00
+++ b/sound/i2c/l3/uda1341.c	2005-03-01 23:38:57 -08:00
@@ -17,7 +17,7 @@
  * 2002-05-12   Tomas Kasparek  another code cleanup
  */
 
-/* $Id: uda1341.c,v 1.13 2004/07/20 15:54:13 cladisch Exp $ */
+/* $Id: uda1341.c,v 1.15 2005/01/03 12:05:20 tiwai Exp $ */
 
 #include <sound/driver.h>
 #include <linux/module.h>
@@ -679,7 +679,7 @@
 		return err;
 	}
 
-	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, uda1341, &ops)) < 0) {
+	if ((err = snd_device_new(card, SNDRV_DEV_CODEC, uda1341, &ops)) < 0) {
 		l3_detach_client(uda1341);
 		kfree(uda1341);
 		return err;
@@ -730,8 +730,7 @@
 
 static void uda1341_detach(struct l3_client *clnt)
 {
-	if (clnt->driver_data)
-		kfree(clnt->driver_data);
+	kfree(clnt->driver_data);
 }
 
 static int
diff -Nru a/sound/i2c/other/ak4117.c b/sound/i2c/other/ak4117.c
--- a/sound/i2c/other/ak4117.c	2005-03-01 23:38:58 -08:00
+++ b/sound/i2c/other/ak4117.c	2005-03-01 23:38:58 -08:00
@@ -103,7 +103,7 @@
 	chip->rcs1 = reg_read(chip, AK4117_REG_RCS1);
 	chip->rcs2 = reg_read(chip, AK4117_REG_RCS2);
 
-	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0)
+	if ((err = snd_device_new(card, SNDRV_DEV_CODEC, chip, &ops)) < 0)
 		goto __fail;
 
 	if (r_ak4117)
diff -Nru a/sound/isa/ad1816a/ad1816a_lib.c b/sound/isa/ad1816a/ad1816a_lib.c
--- a/sound/isa/ad1816a/ad1816a_lib.c	2005-03-01 23:39:07 -08:00
+++ b/sound/isa/ad1816a/ad1816a_lib.c	2005-03-01 23:39:07 -08:00
@@ -46,20 +46,20 @@
 	return -EBUSY;
 }
 
-inline unsigned char snd_ad1816a_in(ad1816a_t *chip, unsigned char reg)
+static inline unsigned char snd_ad1816a_in(ad1816a_t *chip, unsigned char reg)
 {
 	snd_ad1816a_busy_wait(chip);
 	return inb(AD1816A_REG(reg));
 }
 
-inline void snd_ad1816a_out(ad1816a_t *chip, unsigned char reg,
+static inline void snd_ad1816a_out(ad1816a_t *chip, unsigned char reg,
 			    unsigned char value)
 {
 	snd_ad1816a_busy_wait(chip);
 	outb(value, AD1816A_REG(reg));
 }
 
-inline void snd_ad1816a_out_mask(ad1816a_t *chip, unsigned char reg,
+static inline void snd_ad1816a_out_mask(ad1816a_t *chip, unsigned char reg,
 				 unsigned char mask, unsigned char value)
 {
 	snd_ad1816a_out(chip, reg,
@@ -372,6 +372,7 @@
 	.fifo_size =		0,
 };
 
+#if 0 /* not used now */
 static int snd_ad1816a_timer_close(snd_timer_t *timer)
 {
 	ad1816a_t *chip = snd_timer_chip(timer);
@@ -435,6 +436,7 @@
 	.start =	snd_ad1816a_timer_start,
 	.stop =		snd_ad1816a_timer_stop,
 };
+#endif /* not used now */
 
 
 static int snd_ad1816a_playback_open(snd_pcm_substream_t *substream)
@@ -692,6 +694,7 @@
 	return 0;
 }
 
+#if 0 /* not used now */
 static void snd_ad1816a_timer_free(snd_timer_t *timer)
 {
 	ad1816a_t *chip = timer->private_data;
@@ -720,6 +723,7 @@
 		*rtimer = timer;
 	return 0;
 }
+#endif /* not used now */
 
 /*
  *
diff -Nru a/sound/isa/ad1848/ad1848_lib.c b/sound/isa/ad1848/ad1848_lib.c
--- a/sound/isa/ad1848/ad1848_lib.c	2005-03-01 23:39:17 -08:00
+++ b/sound/isa/ad1848/ad1848_lib.c	2005-03-01 23:39:17 -08:00
@@ -119,9 +119,8 @@
 #endif
 }
 
-void snd_ad1848_dout(ad1848_t *chip,
-		     unsigned char reg,
-		     unsigned char value)
+static void snd_ad1848_dout(ad1848_t *chip,
+			    unsigned char reg, unsigned char value)
 {
 	int timeout;
 
@@ -132,7 +131,7 @@
 	mb();
 }
 
-unsigned char snd_ad1848_in(ad1848_t *chip, unsigned char reg)
+static unsigned char snd_ad1848_in(ad1848_t *chip, unsigned char reg)
 {
 	int timeout;
 
@@ -147,9 +146,9 @@
 	return inb(AD1848P(chip, REG));
 }
 
-#ifdef CONFIG_SND_DEBUG
+#if 0
 
-void snd_ad1848_debug(ad1848_t *chip)
+static void snd_ad1848_debug(ad1848_t *chip)
 {
 	printk("AD1848 REGS:      INDEX = 0x%02x  ", inb(AD1848P(chip, REGSEL)));
 	printk("                 STATUS = 0x%02x\n", inb(AD1848P(chip, STATUS)));
@@ -177,7 +176,7 @@
  *  AD1848 detection / MCE routines
  */
 
-void snd_ad1848_mce_up(ad1848_t *chip)
+static void snd_ad1848_mce_up(ad1848_t *chip)
 {
 	unsigned long flags;
 	int timeout;
@@ -198,7 +197,7 @@
 	spin_unlock_irqrestore(&chip->reg_lock, flags);
 }
 
-void snd_ad1848_mce_down(ad1848_t *chip)
+static void snd_ad1848_mce_down(ad1848_t *chip)
 {
 	unsigned long flags;
 	int timeout;
@@ -584,7 +583,7 @@
 	return 0;
 }
 
-irqreturn_t snd_ad1848_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t snd_ad1848_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	ad1848_t *chip = dev_id;
 
@@ -649,16 +648,12 @@
 {
 	ad1848_t *chip = card->pm_private_data;
 
-	if (card->power_state == SNDRV_CTL_POWER_D3hot)
-		return 0;
-
 	snd_pcm_suspend_all(chip->pcm);
 	/* FIXME: save registers? */
 
 	if (chip->thinkpad_flag)
 		snd_ad1848_thinkpad_twiddle(chip, 0);
 
-	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
 	return 0;
 }
 
@@ -666,15 +661,11 @@
 {
 	ad1848_t *chip = card->pm_private_data;
 
-	if (card->power_state == SNDRV_CTL_POWER_D0)
-		return 0;
-
 	if (chip->thinkpad_flag)
 		snd_ad1848_thinkpad_twiddle(chip, 1);
 
 	/* FIXME: restore registers? */
 
-	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
 	return 0;
 }
 #endif /* CONFIG_PM */
@@ -1264,12 +1255,7 @@
 	return 0;
 }
 
-EXPORT_SYMBOL(snd_ad1848_in);
 EXPORT_SYMBOL(snd_ad1848_out);
-EXPORT_SYMBOL(snd_ad1848_dout);
-EXPORT_SYMBOL(snd_ad1848_mce_up);
-EXPORT_SYMBOL(snd_ad1848_mce_down);
-EXPORT_SYMBOL(snd_ad1848_interrupt);
 EXPORT_SYMBOL(snd_ad1848_create);
 EXPORT_SYMBOL(snd_ad1848_pcm);
 EXPORT_SYMBOL(snd_ad1848_get_pcm_ops);
diff -Nru a/sound/isa/als100.c b/sound/isa/als100.c
--- a/sound/isa/als100.c	2005-03-01 23:38:52 -08:00
+++ b/sound/isa/als100.c	2005-03-01 23:38:52 -08:00
@@ -94,6 +94,8 @@
 	{ .id = "ALS0120", .devs = { { "@@@2001" }, { "@X@2001" }, { "@H@2001" } } },
 	/* ALS200 */
 	{ .id = "ALS0200", .devs = { { "@@@0020" }, { "@X@0020" }, { "@H@0001" } } },
+	/* ALS200 OEM */
+	{ .id = "ALS0200", .devs = { { "@@@0020" }, { "@X@0020" }, { "@H@0020" } } },
 	/* RTL3000 */
 	{ .id = "RTL3000", .devs = { { "@@@2001" }, { "@X@2001" }, { "@H@2001" } } },
 	{ .id = "", } /* end */
diff -Nru a/sound/isa/cs423x/cs4231_lib.c b/sound/isa/cs423x/cs4231_lib.c
--- a/sound/isa/cs423x/cs4231_lib.c	2005-03-01 23:38:53 -08:00
+++ b/sound/isa/cs423x/cs4231_lib.c	2005-03-01 23:38:53 -08:00
@@ -166,8 +166,8 @@
 #endif
 }
 
-void snd_cs4231_outm(cs4231_t *chip, unsigned char reg,
-		     unsigned char mask, unsigned char value)
+static void snd_cs4231_outm(cs4231_t *chip, unsigned char reg,
+			    unsigned char mask, unsigned char value)
 {
 	int timeout;
 	unsigned char tmp;
@@ -271,9 +271,9 @@
 #endif
 }
 
-#ifdef CONFIG_SND_DEBUG
+#if 0
 
-void snd_cs4231_debug(cs4231_t *chip)
+static void snd_cs4231_debug(cs4231_t *chip)
 {
 	printk("CS4231 REGS:      INDEX = 0x%02x  ", cs4231_inb(chip, CS4231P(REGSEL)));
 	printk("                 STATUS = 0x%02x\n", cs4231_inb(chip, CS4231P(STATUS)));
@@ -356,7 +356,6 @@
 {
 	unsigned long flags;
 	int timeout;
-	signed long time;
 
 	snd_cs4231_busy_wait(chip);
 #if 0
@@ -390,34 +389,26 @@
 #if 0
 	printk("(2) timeout = %i, jiffies = %li\n", timeout, jiffies);
 #endif
-	timeout = HZ / 4 / 2;
-	time = 2;
+	/* in 10 ms increments, check condition, up to 250 ms */
+	timeout = 25;
 	while (snd_cs4231_in(chip, CS4231_TEST_INIT) & CS4231_CALIB_IN_PROGRESS) {
-		set_current_state(TASK_INTERRUPTIBLE);
-		time = schedule_timeout(time);
-		if (time > 0)
-			continue;
-		time = 2;
 		if (--timeout < 0) {
 			snd_printk("mce_down - auto calibration time out (2)\n");
 			return;
 		}
+		msleep(10);
 	}
 #if 0
 	printk("(3) jiffies = %li\n", jiffies);
 #endif
-	timeout = HZ / 10 / 2;
-	time = 2;
+	/* in 10 ms increments, check condition, up to 100 ms */
+	timeout = 10;
 	while (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) {
-		set_current_state(TASK_INTERRUPTIBLE);		
-		time = schedule_timeout(time);
-		if (time > 0)
-			continue;
-		time = 2;
 		if (--timeout < 0) {
 			snd_printk(KERN_ERR "mce_down - auto calibration time out (3)\n");
 			return;
 		}
+		msleep(10);
 	}
 #if 0
 	printk("(4) jiffies = %li\n", jiffies);
@@ -694,7 +685,7 @@
 
 	snd_cs4231_mce_down(chip);
 
-#ifdef SNDRV_DEBUGq_MCE
+#ifdef SNDRV_DEBUG_MCE
 	snd_printk("init: (1)\n");
 #endif
 	snd_cs4231_mce_up(chip);
@@ -1035,7 +1026,7 @@
 
  */
 
-int snd_cs4231_probe(cs4231_t *chip)
+static int snd_cs4231_probe(cs4231_t *chip)
 {
 	unsigned long flags;
 	int i, id, rev;
@@ -1406,20 +1397,16 @@
 static int snd_cs4231_pm_suspend(snd_card_t *card, unsigned int state)
 {
 	cs4231_t *chip = card->pm_private_data;
-	if (chip->suspend) {
+	if (chip->suspend)
 		chip->suspend(chip);
-		snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
-	}
 	return 0;
 }
 
 static int snd_cs4231_pm_resume(snd_card_t *card, unsigned int state)
 {
 	cs4231_t *chip = card->pm_private_data;
-	if (chip->resume) {
+	if (chip->resume)
 		chip->resume(chip);
-		snd_power_change_state(card, SNDRV_CTL_POWER_D0);
-	}
 	return 0;
 }
 #endif /* CONFIG_PM */
@@ -1943,7 +1930,6 @@
 
 EXPORT_SYMBOL(snd_cs4231_out);
 EXPORT_SYMBOL(snd_cs4231_in);
-EXPORT_SYMBOL(snd_cs4231_outm);
 EXPORT_SYMBOL(snd_cs4236_ext_out);
 EXPORT_SYMBOL(snd_cs4236_ext_in);
 EXPORT_SYMBOL(snd_cs4231_mce_up);
diff -Nru a/sound/isa/cs423x/cs4236.c b/sound/isa/cs423x/cs4236.c
--- a/sound/isa/cs423x/cs4236.c	2005-03-01 23:38:52 -08:00
+++ b/sound/isa/cs423x/cs4236.c	2005-03-01 23:38:52 -08:00
@@ -242,6 +242,8 @@
 	{ .id = "CSCd937", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } },
 	/* CS4235 without MPU401 */
 	{ .id = "CSCe825", .devs = { { "CSC0100" }, { "CSC0110" } } },
+	/* Unknown SiS530 - CS4235 */
+	{ .id = "CSC4825", .devs = { { "CSC0100" }, { "CSC0110" } } },
 	/* IBM IntelliStation M Pro 6898 11U - CS4236B */
 	{ .id = "CSCe835", .devs = { { "CSC0000" }, { "CSC0010" } } },
 	/* IBM PC 300PL Onboard - CS4236B */
diff -Nru a/sound/isa/es1688/es1688_lib.c b/sound/isa/es1688/es1688_lib.c
--- a/sound/isa/es1688/es1688_lib.c	2005-03-01 23:38:59 -08:00
+++ b/sound/isa/es1688/es1688_lib.c	2005-03-01 23:38:59 -08:00
@@ -70,7 +70,7 @@
 	return snd_es1688_dsp_command(chip, data);
 }
 
-int snd_es1688_read(es1688_t *chip, unsigned char reg)
+static int snd_es1688_read(es1688_t *chip, unsigned char reg)
 {
 	/* Read a byte from an extended mode register of ES1688 */
 	if (!snd_es1688_dsp_command(chip, 0xc0))
@@ -89,7 +89,7 @@
 	udelay(10);
 }
 
-unsigned char snd_es1688_mixer_read(es1688_t *chip, unsigned char reg)
+static unsigned char snd_es1688_mixer_read(es1688_t *chip, unsigned char reg)
 {
 	unsigned char result;
 
@@ -479,7 +479,7 @@
 	return snd_es1688_trigger(chip, cmd, 0x0f);
 }
 
-irqreturn_t snd_es1688_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t snd_es1688_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	es1688_t *chip = dev_id;
 
@@ -1041,8 +1041,6 @@
 }
 
 EXPORT_SYMBOL(snd_es1688_mixer_write);
-EXPORT_SYMBOL(snd_es1688_mixer_read);
-EXPORT_SYMBOL(snd_es1688_interrupt);
 EXPORT_SYMBOL(snd_es1688_create);
 EXPORT_SYMBOL(snd_es1688_pcm);
 EXPORT_SYMBOL(snd_es1688_mixer);
diff -Nru a/sound/isa/es18xx.c b/sound/isa/es18xx.c
--- a/sound/isa/es18xx.c	2005-03-01 23:38:56 -08:00
+++ b/sound/isa/es18xx.c	2005-03-01 23:38:56 -08:00
@@ -268,7 +268,7 @@
 	return ret;
 }
 
-inline void snd_es18xx_mixer_write(es18xx_t *chip,
+static inline void snd_es18xx_mixer_write(es18xx_t *chip,
 			    unsigned char reg, unsigned char data)
 {
 	unsigned long flags;
@@ -281,7 +281,7 @@
 #endif
 }
 
-inline int snd_es18xx_mixer_read(es18xx_t *chip, unsigned char reg)
+static inline int snd_es18xx_mixer_read(es18xx_t *chip, unsigned char reg)
 {
 	unsigned long flags;
 	int data;
@@ -1569,7 +1569,7 @@
 	snd_pcm_lib_preallocate_free_for_all(pcm);
 }
 
-int __devinit snd_es18xx_pcm(es18xx_t *chip, int device, snd_pcm_t ** rpcm)
+static int __devinit snd_es18xx_pcm(es18xx_t *chip, int device, snd_pcm_t ** rpcm)
 {
         snd_pcm_t *pcm;
 	char str[16];
@@ -1624,7 +1624,6 @@
 	snd_es18xx_write(chip, ES18XX_PM, chip->pm_reg);
 	snd_es18xx_write(chip, ES18XX_PM, chip->pm_reg ^= ES18XX_PM_SUS);
 
-	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
 	return 0;
 }
 
@@ -1635,7 +1634,6 @@
 	/* restore PM register, we won't wake till (not 0x07) i/o activity though */
 	snd_es18xx_write(chip, ES18XX_PM, chip->pm_reg ^= ES18XX_PM_FM);
 
-	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
 	return 0;
 }
 #endif /* CONFIG_PM */
@@ -1849,7 +1847,7 @@
 static int isapnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
 #endif
 static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;	/* 0x220,0x240,0x260,0x280 */
-#ifndef CONFIG_PNP_
+#ifndef CONFIG_PNP
 static long mpu_port[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -1};
 #else
 static long mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
@@ -1988,7 +1986,7 @@
 	kfree(cfg);
 	return 0;
 }
-#endif /* CONFIG_PNP_ */
+#endif /* CONFIG_PNP */
 
 static int __devinit snd_audiodrive_probe(int dev, struct pnp_card_link *pcard,
 					  const struct pnp_card_device_id *pid)
diff -Nru a/sound/isa/gus/gus_dma.c b/sound/isa/gus/gus_dma.c
--- a/sound/isa/gus/gus_dma.c	2005-03-01 23:38:51 -08:00
+++ b/sound/isa/gus/gus_dma.c	2005-03-01 23:38:51 -08:00
@@ -25,7 +25,7 @@
 #include <sound/core.h>
 #include <sound/gus.h>
 
-void snd_gf1_dma_ack(snd_gus_card_t * gus)
+static void snd_gf1_dma_ack(snd_gus_card_t * gus)
 {
 	unsigned long flags;
 
@@ -35,11 +35,11 @@
 	spin_unlock_irqrestore(&gus->reg_lock, flags);
 }
 
-void snd_gf1_dma_program(snd_gus_card_t * gus,
-			 unsigned int addr,
-			 unsigned long buf_addr,
-			 unsigned int count,
-			 unsigned int cmd)
+static void snd_gf1_dma_program(snd_gus_card_t * gus,
+				unsigned int addr,
+				unsigned long buf_addr,
+				unsigned int count,
+				unsigned int cmd)
 {
 	unsigned long flags;
 	unsigned int address;
diff -Nru a/sound/isa/gus/gus_mem.c b/sound/isa/gus/gus_mem.c
--- a/sound/isa/gus/gus_mem.c	2005-03-01 23:38:56 -08:00
+++ b/sound/isa/gus/gus_mem.c	2005-03-01 23:38:56 -08:00
@@ -100,8 +100,7 @@
 		if (block->prev)
 			block->prev->next = block->next;
 	}
-	if (block->name)
-		kfree(block->name);
+	kfree(block->name);
 	kfree(block);
 	return 0;
 }
diff -Nru a/sound/isa/gus/gus_sample.c b/sound/isa/gus/gus_sample.c
--- a/sound/isa/gus/gus_sample.c	2005-03-01 23:38:57 -08:00
+++ b/sound/isa/gus/gus_sample.c	2005-03-01 23:38:57 -08:00
@@ -42,7 +42,7 @@
 	instr = snd_seq_instr_find(gus->gf1.ilist, &v->instr, 0, 1);
 	if (instr != NULL) {
 		if (instr->ops) {
-			if (instr->ops->instr_type == snd_seq_simple_id)
+			if (!strcmp(instr->ops->instr_type, SNDRV_SEQ_INSTR_ID_SIMPLE))
 				snd_gf1_simple_init(v);
 		}
 		snd_seq_instr_free_use(gus->gf1.ilist, instr);
diff -Nru a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c
--- a/sound/isa/opl3sa2.c	2005-03-01 23:39:17 -08:00
+++ b/sound/isa/opl3sa2.c	2005-03-01 23:39:17 -08:00
@@ -341,7 +341,7 @@
 	return 0;
 }
 
-int snd_opl3sa2_get_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_opl3sa2_get_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
 	opl3sa2_t *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
@@ -358,7 +358,7 @@
 	return 0;
 }
 
-int snd_opl3sa2_put_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_opl3sa2_put_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
 	opl3sa2_t *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
@@ -388,7 +388,7 @@
   .get = snd_opl3sa2_get_double, .put = snd_opl3sa2_put_double, \
   .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22) }
 
-int snd_opl3sa2_info_double(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_opl3sa2_info_double(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
 {
 	int mask = (kcontrol->private_value >> 24) & 0xff;
 
@@ -399,7 +399,7 @@
 	return 0;
 }
 
-int snd_opl3sa2_get_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_opl3sa2_get_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
 	opl3sa2_t *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
@@ -421,7 +421,7 @@
 	return 0;
 }
 
-int snd_opl3sa2_put_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_opl3sa2_put_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
 	opl3sa2_t *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
@@ -539,7 +539,6 @@
 	/* power down */
 	snd_opl3sa2_write(chip, OPL3SA2_PM_CTRL, OPL3SA2_PM_D3);
 
-	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
 	return 0;
 }
 
@@ -563,7 +562,6 @@
 	/* restore cs4231 */
 	chip->cs4231_resume(chip->cs4231);
 
-	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
 	return 0;
 }
 #endif /* CONFIG_PM */
@@ -713,7 +711,7 @@
 		chip->single_dma = 1;
 	if ((err = snd_opl3sa2_detect(chip)) < 0)
 		goto __error;
-	if (request_irq(xirq, snd_opl3sa2_interrupt, SA_INTERRUPT, "OPL3-SA2/3", (void *)chip)) {
+	if (request_irq(xirq, snd_opl3sa2_interrupt, SA_INTERRUPT, "OPL3-SA2", (void *)chip)) {
 		snd_printk(KERN_ERR "opl3sa2: can't grab IRQ %d\n", xirq);
 		err = -ENODEV;
 		goto __error;
diff -Nru a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c
--- a/sound/isa/opti9xx/opti92x-ad1848.c	2005-03-01 23:38:53 -08:00
+++ b/sound/isa/opti9xx/opti92x-ad1848.c	2005-03-01 23:38:53 -08:00
@@ -1095,7 +1095,7 @@
 	spin_unlock_irqrestore(&chip->lock, flags);
 }
 
-irqreturn_t snd_opti93x_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t snd_opti93x_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	opti93x_t *codec = dev_id;
 	unsigned char status;
@@ -1263,9 +1263,9 @@
 	}
 }
 
-int snd_opti93x_create(snd_card_t *card, opti9xx_t *chip,
-		       int dma1, int dma2,
-		       opti93x_t **rcodec)
+static int snd_opti93x_create(snd_card_t *card, opti9xx_t *chip,
+			      int dma1, int dma2,
+			      opti93x_t **rcodec)
 {
 	static snd_device_ops_t ops = {
 		.dev_free =	snd_opti93x_dev_free,
@@ -1359,7 +1359,7 @@
 	snd_pcm_lib_preallocate_free_for_all(pcm);
 }
 
-int snd_opti93x_pcm(opti93x_t *codec, int device, snd_pcm_t **rpcm)
+static int snd_opti93x_pcm(opti93x_t *codec, int device, snd_pcm_t **rpcm)
 {
 	int error;
 	snd_pcm_t *pcm;
@@ -1603,7 +1603,7 @@
 }
 };
                                         
-int snd_opti93x_mixer(opti93x_t *chip)
+static int snd_opti93x_mixer(opti93x_t *chip)
 {
 	snd_card_t *card;
 	snd_kcontrol_new_t knew;
diff -Nru a/sound/isa/sb/emu8000.c b/sound/isa/sb/emu8000.c
--- a/sound/isa/sb/emu8000.c	2005-03-01 23:38:55 -08:00
+++ b/sound/isa/sb/emu8000.c	2005-03-01 23:38:55 -08:00
@@ -1133,7 +1133,7 @@
 		return err;
 	}
 	
-	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, hw, &ops)) < 0) {
+	if ((err = snd_device_new(card, SNDRV_DEV_CODEC, hw, &ops)) < 0) {
 		snd_emu8000_free(hw);
 		return err;
 	}
diff -Nru a/sound/isa/sb/emu8000_callback.c b/sound/isa/sb/emu8000_callback.c
--- a/sound/isa/sb/emu8000_callback.c	2005-03-01 23:38:55 -08:00
+++ b/sound/isa/sb/emu8000_callback.c	2005-03-01 23:38:55 -08:00
@@ -528,6 +528,10 @@
 	emu8000_t *hw;
 	hw = emu->hw;
 
+	/* skip header */
+	buf += 16;
+	len -= 16;
+
 	switch (type) {
 	case SNDRV_EMU8000_LOAD_CHORUS_FX:
 		return snd_emu8000_load_chorus_fx(hw, mode, buf, len);
diff -Nru a/sound/isa/sb/emu8000_pcm.c b/sound/isa/sb/emu8000_pcm.c
--- a/sound/isa/sb/emu8000_pcm.c	2005-03-01 23:39:17 -08:00
+++ b/sound/isa/sb/emu8000_pcm.c	2005-03-01 23:39:17 -08:00
@@ -260,8 +260,7 @@
 static int emu8k_pcm_close(snd_pcm_substream_t *subs)
 {
 	emu8k_pcm_t *rec = subs->runtime->private_data;
-	if (rec)
-		kfree(rec);
+	kfree(rec);
 	subs->runtime->private_data = NULL;
 	return 0;
 }
diff -Nru a/sound/isa/sb/sb16_main.c b/sound/isa/sb/sb16_main.c
--- a/sound/isa/sb/sb16_main.c	2005-03-01 23:38:57 -08:00
+++ b/sound/isa/sb/sb16_main.c	2005-03-01 23:38:57 -08:00
@@ -509,7 +509,7 @@
  *  open/close
  */
 
-int snd_sb16_playback_open(snd_pcm_substream_t * substream)
+static int snd_sb16_playback_open(snd_pcm_substream_t * substream)
 {
 	unsigned long flags;
 	sb_t *chip = snd_pcm_substream_chip(substream);
@@ -566,7 +566,7 @@
 	return 0;
 }
 
-int snd_sb16_playback_close(snd_pcm_substream_t * substream)
+static int snd_sb16_playback_close(snd_pcm_substream_t * substream)
 {
 	unsigned long flags;
 	sb_t *chip = snd_pcm_substream_chip(substream);
@@ -579,7 +579,7 @@
 	return 0;
 }
 
-int snd_sb16_capture_open(snd_pcm_substream_t * substream)
+static int snd_sb16_capture_open(snd_pcm_substream_t * substream)
 {
 	unsigned long flags;
 	sb_t *chip = snd_pcm_substream_chip(substream);
@@ -636,7 +636,7 @@
 	return 0;
 }
 
-int snd_sb16_capture_close(snd_pcm_substream_t * substream)
+static int snd_sb16_capture_close(snd_pcm_substream_t * substream)
 {
 	unsigned long flags;
 	sb_t *chip = snd_pcm_substream_chip(substream);
@@ -728,7 +728,7 @@
 	return change;
 }
 
-snd_kcontrol_new_t snd_sb16_dma_control = {
+static snd_kcontrol_new_t snd_sb16_dma_control = {
 	.iface = SNDRV_CTL_ELEM_IFACE_PCM,
 	.name = "16-bit DMA Allocation",
 	.info = snd_sb16_dma_control_info,
diff -Nru a/sound/isa/sb/sb8_main.c b/sound/isa/sb/sb8_main.c
--- a/sound/isa/sb/sb8_main.c	2005-03-01 23:38:56 -08:00
+++ b/sound/isa/sb/sb8_main.c	2005-03-01 23:38:56 -08:00
@@ -425,7 +425,7 @@
  *
  */
  
-int snd_sb8_open(snd_pcm_substream_t *substream)
+static int snd_sb8_open(snd_pcm_substream_t *substream)
 {
 	sb_t *chip = snd_pcm_substream_chip(substream);
 	snd_pcm_runtime_t *runtime = substream->runtime;
@@ -471,7 +471,7 @@
 	return 0;	
 }
 
-int snd_sb8_close(snd_pcm_substream_t *substream)
+static int snd_sb8_close(snd_pcm_substream_t *substream)
 {
 	unsigned long flags;
 	sb_t *chip = snd_pcm_substream_chip(substream);
diff -Nru a/sound/isa/sb/sb_common.c b/sound/isa/sb/sb_common.c
--- a/sound/isa/sb/sb_common.c	2005-03-01 23:39:17 -08:00
+++ b/sound/isa/sb/sb_common.c	2005-03-01 23:39:17 -08:00
@@ -92,7 +92,7 @@
 	return -ENODEV;
 }
 
-int snd_sbdsp_version(sb_t * chip)
+static int snd_sbdsp_version(sb_t * chip)
 {
 	unsigned int result = -ENODEV;
 
diff -Nru a/sound/isa/sscape.c b/sound/isa/sscape.c
--- a/sound/isa/sscape.c	2005-03-01 23:38:52 -08:00
+++ b/sound/isa/sscape.c	2005-03-01 23:38:52 -08:00
@@ -487,7 +487,7 @@
 		 * the userspace pointer ...
 		 */
 		len = min(size, dma.bytes);
-		__copy_from_user(dma.area, data, len);
+		len -= __copy_from_user(dma.area, data, len);
 		data += len;
 		size -= len;
 
@@ -571,8 +571,9 @@
 		if (data < 0) {
 			snd_printk(KERN_ERR "sscape: timeout reading firmware version\n");
 			ret = -EAGAIN;
-		} else {
-			__copy_to_user(&bb->version, &data, sizeof(bb->version));
+		}
+		else if (__copy_to_user(&bb->version, &data, sizeof(bb->version))) {
+			ret = -EFAULT;
 		}
 	}
 
@@ -591,7 +592,7 @@
 {
 	unsigned long flags;
 	char __user *code;
-	int err, ret;
+	int err;
 
 	/*
 	 * We are going to have to copy this data into a special
@@ -601,12 +602,11 @@
 	 * NOTE: This buffer is 64K long! That's WAY too big to
 	 *       copy into a stack-temporary anyway.
 	 */
-	if (get_user(code, &mc->code))
+	if ( get_user(code, &mc->code) ||
+	     !access_ok(VERIFY_READ, code, SSCAPE_MICROCODE_SIZE) )
 		return -EFAULT;
-	if ((err = verify_area(VERIFY_READ, code, SSCAPE_MICROCODE_SIZE)) != 0)
-		return err;
 
-	if ((ret = upload_dma_data(sscape, code, SSCAPE_MICROCODE_SIZE)) == 0) {
+	if ((err = upload_dma_data(sscape, code, SSCAPE_MICROCODE_SIZE)) == 0) {
 		snd_printk(KERN_INFO "sscape: MIDI firmware loaded\n");
 	}
 
@@ -616,7 +616,7 @@
 
 	initialise_mpu401(sscape->mpu);
 
-	return ret;
+	return err;
 }
 
 /*
@@ -673,14 +673,14 @@
 			 * DMA-able buffer before we can upload it. We shall therefore
 			 * just check that the data pointer is valid for now ...
 			 */
-			if ((err = verify_area(VERIFY_READ, bb->code, sizeof(bb->code))) != 0)
-				return err;
+			if ( !access_ok(VERIFY_READ, bb->code, sizeof(bb->code)) )
+				return -EFAULT;
 
 			/*
 			 * Now check that we can write the firmware version number too...
 			 */
-			if ((err = verify_area(VERIFY_WRITE, &bb->version, sizeof(bb->version))) != 0)
-				return err;
+			if ( !access_ok(VERIFY_WRITE, &bb->version, sizeof(bb->version)) )
+				return -EFAULT;
 
 			err = sscape_upload_bootblock(sscape, bb);
 		}
diff -Nru a/sound/isa/wavefront/wavefront.c b/sound/isa/wavefront/wavefront.c
--- a/sound/isa/wavefront/wavefront.c	2005-03-01 23:39:08 -08:00
+++ b/sound/isa/wavefront/wavefront.c	2005-03-01 23:39:08 -08:00
@@ -279,7 +279,7 @@
 	return IRQ_HANDLED;
 }
 
-snd_hwdep_t * __devinit
+static snd_hwdep_t * __devinit
 snd_wavefront_new_synth (snd_card_t *card,
 			 int hw_dev,
 			 snd_wavefront_card_t *acard)
@@ -305,7 +305,7 @@
 	return wavefront_synth;
 }
 
-snd_hwdep_t * __devinit
+static snd_hwdep_t * __devinit
 snd_wavefront_new_fx (snd_card_t *card,
 		      int hw_dev,
 		      snd_wavefront_card_t *acard,
@@ -332,7 +332,7 @@
 static snd_wavefront_mpu_id internal_id = internal_mpu;
 static snd_wavefront_mpu_id external_id = external_mpu;
 
-snd_rawmidi_t * __devinit
+static snd_rawmidi_t * __devinit
 snd_wavefront_new_midi (snd_card_t *card,
 			int midi_dev,
 			snd_wavefront_card_t *acard,
diff -Nru a/sound/isa/wavefront/wavefront_fx.c b/sound/isa/wavefront/wavefront_fx.c
--- a/sound/isa/wavefront/wavefront_fx.c	2005-03-01 23:39:07 -08:00
+++ b/sound/isa/wavefront/wavefront_fx.c	2005-03-01 23:39:07 -08:00
@@ -537,8 +537,7 @@
 			     r.data[1], /* addr */
 			     r.data[2], /* cnt */
 			     pd);
-		if (page_data)
-			kfree(page_data);
+		kfree(page_data);
 		break;
 
 	default:
diff -Nru a/sound/isa/wavefront/wavefront_synth.c b/sound/isa/wavefront/wavefront_synth.c
--- a/sound/isa/wavefront/wavefront_synth.c	2005-03-01 23:38:55 -08:00
+++ b/sound/isa/wavefront/wavefront_synth.c	2005-03-01 23:38:55 -08:00
@@ -32,58 +32,58 @@
 #include <sound/snd_wavefront.h>
 #include <sound/initval.h>
 
-int wf_raw = 0; /* we normally check for "raw state" to firmware
-		   loading. if non-zero, 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 = 0; /* we normally check for "raw state" to firmware
+			  loading. if non-zero, then during driver loading, the
+			  state of the board is ignored, and we reset the
+			  board and load the firmware anyway.
+		       */
 		   
-int fx_raw = 1; /* if this is zero, we'll leave the FX processor in
-		   whatever state it is when the driver is loaded.
-		   The default is to download the microprogram and
-		   associated coefficients to set it up for "default"
-		   operation, whatever that means.
-		*/
-
-int debug_default = 0;  /* you can set this to control debugging
-			      during driver loading. it takes any combination
-			      of the WF_DEBUG_* flags defined in
-			      wavefront.h
-			   */
+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.
+			  The default is to download the microprogram and
+			  associated coefficients to set it up for "default"
+			  operation, whatever that means.
+		       */
+
+static int debug_default = 0;  /* you can set this to control debugging
+				  during driver loading. it takes any combination
+				  of the WF_DEBUG_* flags defined in
+				  wavefront.h
+			       */
 
 /* XXX this needs to be made firmware and hardware version dependent */
 
-char *ospath = "/etc/sound/wavefront.os"; /* where to find a processed
-					     version of the WaveFront OS
-					  */
-
-int wait_usecs = 150; /* This magic number seems to give pretty optimal
-			 throughput based on my limited experimentation.
-			 If you want to play around with it and find a better
-			 value, be my guest. Remember, the idea is to
-			 get a number that causes us to just busy wait
-			 for as many WaveFront commands as possible, without
-			 coming up with a number so large that we hog the
-			 whole CPU.
-
-			 Specifically, with this number, out of about 134,000
-			 status waits, only about 250 result in a sleep.
-		      */
-
-int sleep_interval = 100;   /* HZ/sleep_interval seconds per sleep */
-int sleep_tries = 50;       /* number of times we'll try to sleep */
-
-int reset_time = 2;        /* hundreths of a second we wait after a HW
-			      reset for the expected interrupt.
-			   */
-
-int ramcheck_time = 20;    /* time in seconds to wait while ROM code
-			      checks on-board RAM.
-			   */
-
-int osrun_time = 10;       /* time in seconds we wait for the OS to
-			      start running.
-			   */
+static char *ospath = "/etc/sound/wavefront.os"; /* where to find a processed
+						    version of the WaveFront OS
+						 */
+
+static int wait_usecs = 150; /* This magic number seems to give pretty optimal
+				throughput based on my limited experimentation.
+				If you want to play around with it and find a better
+				value, be my guest. Remember, the idea is to
+				get a number that causes us to just busy wait
+				for as many WaveFront commands as possible, without
+				coming up with a number so large that we hog the
+				whole CPU.
+
+				Specifically, with this number, out of about 134,000
+				status waits, only about 250 result in a sleep.
+			    */
+
+static int sleep_interval = 100;   /* HZ/sleep_interval seconds per sleep */
+static int sleep_tries = 50;       /* number of times we'll try to sleep */
+
+static int reset_time = 2;        /* hundreths of a second we wait after a HW
+				     reset for the expected interrupt.
+				  */
+
+static int ramcheck_time = 20;    /* time in seconds to wait while ROM code
+				     checks on-board RAM.
+				  */
+
+static int osrun_time = 10;       /* time in seconds we wait for the OS to
+				     start running.
+				  */
 module_param(wf_raw, int, 0444);
 MODULE_PARM_DESC(wf_raw, "if non-zero, assume that we need to boot the OS");
 module_param(fx_raw, int, 0444);
@@ -1709,7 +1709,7 @@
 7 Unused
 */
 
-int __init
+static int __init
 snd_wavefront_interrupt_bits (int irq)
 
 {
@@ -1922,7 +1922,7 @@
 
 {
 	unsigned char section[WF_SECTION_MAX];
-	char section_length; /* yes, just a char; max value is WF_SECTION_MAX */
+	signed char section_length; /* yes, just a char; max value is WF_SECTION_MAX */
 	int section_cnt_downloaded = 0;
 	int fd;
 	int c;
diff -Nru a/sound/mips/Kconfig b/sound/mips/Kconfig
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/sound/mips/Kconfig	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,15 @@
+# ALSA MIPS drivers
+
+menu "ALSA MIPS devices"
+	depends on SND!=n && MIPS
+
+config SND_AU1X00
+	tristate "Au1x00 AC97 Port Driver"
+	depends on (SOC_AU1000 || SOC_AU1100 || SOC_AU1500) && SND
+	select SND_PCM
+	select SND_AC97_CODEC
+	help
+	  ALSA Sound driver for the Au1x00's AC97 port.
+
+endmenu
+
diff -Nru a/sound/mips/Makefile b/sound/mips/Makefile
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/sound/mips/Makefile	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,8 @@
+#
+# Makefile for ALSA
+#
+
+snd-au1x00-objs := au1x00.o
+
+# Toplevel Module Dependency
+obj-$(CONFIG_SND_AU1X00) += snd-au1x00.o
diff -Nru a/sound/mips/au1x00.c b/sound/mips/au1x00.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/sound/mips/au1x00.c	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,686 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ *  Driver for AMD Au1000 MIPS Processor, AC'97 Sound Port
+ *
+ * Copyright 2004 Cooper Street Innovations Inc.
+ * Author: Charles Eidsness	<charles@cooper-street.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.
+ *
+ * History:
+ *
+ * 2004-09-09 Charles Eidsness	-- Original verion -- based on
+ * 				  sa11xx-uda1341.c ALSA driver and the
+ *				  au1000.c OSS driver.
+ * 2004-09-09 Matt Porter	-- Added support for ALSA 1.0.6
+ *
+ */
+
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <sound/driver.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/version.h>
+#include <sound/core.h>
+#include <sound/initval.h>
+#include <sound/pcm.h>
+#include <sound/ac97_codec.h>
+#include <asm/mach-au1x00/au1000.h>
+#include <asm/mach-au1x00/au1000_dma.h>
+
+MODULE_AUTHOR("Charles Eidsness <charles@cooper-street.com>");
+MODULE_DESCRIPTION("Au1000 AC'97 ALSA Driver");
+MODULE_LICENSE("GPL");
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8)
+MODULE_SUPPORTED_DEVICE("{{AMD,Au1000 AC'97}}");
+#else
+MODULE_CLASSES("{sound}");
+MODULE_DEVICES("{{AMD,Au1000 AC'97}}");
+#endif
+
+#define chip_t au1000_t
+
+#define PLAYBACK 0
+#define CAPTURE 1
+#define AC97_SLOT_3 0x01
+#define AC97_SLOT_4 0x02
+#define AC97_SLOT_6 0x08
+#define AC97_CMD_IRQ 31
+#define READ 0
+#define WRITE 1
+#define READ_WAIT 2
+#define RW_DONE 3
+
+DECLARE_WAIT_QUEUE_HEAD(ac97_command_wq);
+
+typedef struct au1000_period au1000_period_t;
+struct au1000_period
+{
+	u32 start;
+	u32 relative_end;	/*realtive to start of buffer*/
+	au1000_period_t * next;
+};
+
+/*Au1000 AC97 Port Control Reisters*/
+typedef struct au1000_ac97_reg au1000_ac97_reg_t;
+struct au1000_ac97_reg {
+	u32 volatile config;
+	u32 volatile status;
+	u32 volatile data;
+	u32 volatile cmd;
+	u32 volatile cntrl;
+};
+
+typedef struct audio_stream audio_stream_t;
+struct audio_stream {
+	snd_pcm_substream_t * substream;
+	int dma;
+	spinlock_t dma_lock;
+	au1000_period_t * buffer;
+	unsigned long period_size;
+};
+
+typedef struct snd_card_au1000 {
+	snd_card_t *card;
+	au1000_ac97_reg_t volatile *ac97_ioport;
+
+	struct resource *ac97_res_port;
+	spinlock_t ac97_lock;
+	ac97_t *ac97;
+
+	snd_pcm_t *pcm;
+	audio_stream_t *stream[2];	/* playback & capture */
+} au1000_t;
+
+static au1000_t *au1000 = NULL;
+
+/*--------------------------- Local Functions --------------------------------*/
+static void
+au1000_set_ac97_xmit_slots(long xmit_slots)
+{
+	u32 volatile ac97_config;
+
+	spin_lock(&au1000->ac97_lock);
+	ac97_config = au1000->ac97_ioport->config;
+	ac97_config = ac97_config & ~AC97C_XMIT_SLOTS_MASK;
+	ac97_config |= (xmit_slots << AC97C_XMIT_SLOTS_BIT);
+	au1000->ac97_ioport->config = ac97_config;
+	spin_unlock(&au1000->ac97_lock);
+}
+
+static void
+au1000_set_ac97_recv_slots(long recv_slots)
+{
+	u32 volatile ac97_config;
+
+	spin_lock(&au1000->ac97_lock);
+	ac97_config = au1000->ac97_ioport->config;
+	ac97_config = ac97_config & ~AC97C_RECV_SLOTS_MASK;
+	ac97_config |= (recv_slots << AC97C_RECV_SLOTS_BIT);
+	au1000->ac97_ioport->config = ac97_config;
+	spin_unlock(&au1000->ac97_lock);
+}
+
+
+static void
+au1000_dma_stop(audio_stream_t *stream)
+{
+	unsigned long   flags;
+	au1000_period_t * pointer;
+	au1000_period_t * pointer_next;
+
+	if (stream->buffer != NULL) {
+		spin_lock_irqsave(&stream->dma_lock, flags);
+		disable_dma(stream->dma);
+		spin_unlock_irqrestore(&stream->dma_lock, flags);
+
+		pointer = stream->buffer;
+		pointer_next = stream->buffer->next;
+
+		do {
+			kfree(pointer);
+			pointer = pointer_next;
+			pointer_next = pointer->next;
+		} while (pointer != stream->buffer);
+
+		stream->buffer = NULL;
+	}
+}
+
+static void
+au1000_dma_start(audio_stream_t *stream)
+{
+	snd_pcm_substream_t *substream = stream->substream;
+	snd_pcm_runtime_t *runtime = substream->runtime;
+
+	unsigned long flags, dma_start;
+	int i;
+	au1000_period_t * pointer;
+
+	if (stream->buffer == NULL) {
+		dma_start = virt_to_phys(runtime->dma_area);
+
+		stream->period_size = frames_to_bytes(runtime,
+			runtime->period_size);
+		stream->buffer = kmalloc(sizeof(au1000_period_t), GFP_KERNEL);
+		pointer = stream->buffer;
+		for (i = 0 ; i < runtime->periods ; i++) {
+			pointer->start = (u32)(dma_start +
+				(i * stream->period_size));
+			pointer->relative_end = (u32)
+				(((i+1) * stream->period_size) - 0x1);
+			if ( i < runtime->periods - 1) {
+				pointer->next = kmalloc(sizeof(au1000_period_t)
+					, GFP_KERNEL);
+				pointer = pointer->next;
+			}
+		}
+		pointer->next = stream->buffer;
+
+		spin_lock_irqsave(&stream->dma_lock, flags);
+		init_dma(stream->dma);
+		if (get_dma_active_buffer(stream->dma) == 0) {
+			clear_dma_done0(stream->dma);
+			set_dma_addr0(stream->dma, stream->buffer->start);
+			set_dma_count0(stream->dma, stream->period_size >> 1);
+			set_dma_addr1(stream->dma, stream->buffer->next->start);
+			set_dma_count1(stream->dma, stream->period_size >> 1);
+		} else {
+			clear_dma_done1(stream->dma);
+			set_dma_addr1(stream->dma, stream->buffer->start);
+			set_dma_count1(stream->dma, stream->period_size >> 1);
+			set_dma_addr0(stream->dma, stream->buffer->next->start);
+			set_dma_count0(stream->dma, stream->period_size >> 1);
+		}
+		enable_dma_buffers(stream->dma);
+		start_dma(stream->dma);
+		spin_unlock_irqrestore(&stream->dma_lock, flags);
+	}
+}
+
+static irqreturn_t
+au1000_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	audio_stream_t *stream = (audio_stream_t *) dev_id;
+	snd_pcm_substream_t *substream = stream->substream;
+
+	spin_lock(&stream->dma_lock);
+	switch (get_dma_buffer_done(stream->dma)) {
+	case DMA_D0:
+		stream->buffer = stream->buffer->next;
+		clear_dma_done0(stream->dma);
+		set_dma_addr0(stream->dma, stream->buffer->next->start);
+		set_dma_count0(stream->dma, stream->period_size >> 1);
+		enable_dma_buffer0(stream->dma);
+		break;
+	case DMA_D1:
+		stream->buffer = stream->buffer->next;
+		clear_dma_done1(stream->dma);
+		set_dma_addr1(stream->dma, stream->buffer->next->start);
+		set_dma_count1(stream->dma, stream->period_size >> 1);
+		enable_dma_buffer1(stream->dma);
+		break;
+	case (DMA_D0 | DMA_D1):
+		spin_unlock(&stream->dma_lock);
+		printk(KERN_ERR "DMA %d missed interrupt.\n",stream->dma);
+		au1000_dma_stop(stream);
+		au1000_dma_start(stream);
+		spin_lock(&stream->dma_lock);
+		break;
+	case (~DMA_D0 & ~DMA_D1):
+		printk(KERN_ERR "DMA %d empty irq.\n",stream->dma);
+	}
+	spin_unlock(&stream->dma_lock);
+	snd_pcm_period_elapsed(substream);
+	return IRQ_HANDLED;
+}
+
+/*-------------------------- PCM Audio Streams -------------------------------*/
+
+static unsigned int rates[] = {8000, 11025, 16000, 22050};
+static snd_pcm_hw_constraint_list_t hw_constraints_rates = {
+	.count	=  sizeof(rates) / sizeof(rates[0]),
+	.list	= rates,
+	.mask	= 0,
+};
+
+static snd_pcm_hardware_t snd_au1000 =
+{
+	.info			= (SNDRV_PCM_INFO_INTERLEAVED | \
+				SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID),
+	.formats		= SNDRV_PCM_FMTBIT_S16_LE,
+	.rates			= (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
+				SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050),
+	.rate_min		= 8000,
+	.rate_max		= 22050,
+	.channels_min		= 1,
+	.channels_max		= 2,
+	.buffer_bytes_max	= 128*1024,
+	.period_bytes_min	= 32,
+	.period_bytes_max	= 16*1024,
+	.periods_min		= 8,
+	.periods_max		= 255,
+	.fifo_size		= 16,
+};
+
+static int
+snd_au1000_playback_open(snd_pcm_substream_t * substream)
+{
+	au1000->stream[PLAYBACK]->substream = substream;
+	au1000->stream[PLAYBACK]->buffer = NULL;
+	substream->private_data = au1000->stream[PLAYBACK];
+	substream->runtime->hw = snd_au1000;
+	return (snd_pcm_hw_constraint_list(substream->runtime, 0,
+		SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates) < 0);
+}
+
+static int
+snd_au1000_capture_open(snd_pcm_substream_t * substream)
+{
+	au1000->stream[CAPTURE]->substream = substream;
+	au1000->stream[CAPTURE]->buffer = NULL;
+	substream->private_data = au1000->stream[CAPTURE];
+	substream->runtime->hw = snd_au1000;
+	return (snd_pcm_hw_constraint_list(substream->runtime, 0,
+		SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates) < 0);
+
+}
+
+static int
+snd_au1000_playback_close(snd_pcm_substream_t * substream)
+{
+	au1000->stream[PLAYBACK]->substream = NULL;
+	return 0;
+}
+
+static int
+snd_au1000_capture_close(snd_pcm_substream_t * substream)
+{
+	au1000->stream[CAPTURE]->substream = NULL;
+	return 0;
+}
+
+static int
+snd_au1000_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_au1000_hw_free(snd_pcm_substream_t * substream)
+{
+	return snd_pcm_lib_free_pages(substream);
+}
+
+static int
+snd_au1000_playback_prepare(snd_pcm_substream_t * substream)
+{
+	snd_pcm_runtime_t *runtime = substream->runtime;
+
+	if (runtime->channels == 1 )
+		au1000_set_ac97_xmit_slots(AC97_SLOT_4);
+	else
+		au1000_set_ac97_xmit_slots(AC97_SLOT_3 | AC97_SLOT_4);
+	snd_ac97_set_rate(au1000->ac97, AC97_PCM_FRONT_DAC_RATE, runtime->rate);
+	return 0;
+}
+
+static int
+snd_au1000_capture_prepare(snd_pcm_substream_t * substream)
+{
+	snd_pcm_runtime_t *runtime = substream->runtime;
+
+	if (runtime->channels == 1 )
+		au1000_set_ac97_recv_slots(AC97_SLOT_4);
+	else
+		au1000_set_ac97_recv_slots(AC97_SLOT_3 | AC97_SLOT_4);
+	snd_ac97_set_rate(au1000->ac97, AC97_PCM_LR_ADC_RATE, runtime->rate);
+	return 0;
+}
+
+static int
+snd_au1000_trigger(snd_pcm_substream_t * substream, int cmd)
+{
+	audio_stream_t *stream = substream->private_data;
+	int err = 0;
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+		au1000_dma_start(stream);
+		break;
+	case SNDRV_PCM_TRIGGER_STOP:
+		au1000_dma_stop(stream);
+		break;
+	default:
+		err = -EINVAL;
+		break;
+	}
+	return err;
+}
+
+static snd_pcm_uframes_t
+snd_au1000_pointer(snd_pcm_substream_t * substream)
+{
+	audio_stream_t *stream = substream->private_data;
+	snd_pcm_runtime_t *runtime = substream->runtime;
+	unsigned long flags;
+	long location;
+
+	spin_lock_irqsave(&stream->dma_lock, flags);
+	location = get_dma_residue(stream->dma);
+	spin_unlock_irqrestore(&stream->dma_lock, flags);
+	location = stream->buffer->relative_end - location;
+	if (location == -1)
+		location = 0;
+	return bytes_to_frames(runtime,location);
+}
+
+static snd_pcm_ops_t snd_card_au1000_playback_ops = {
+	.open			= snd_au1000_playback_open,
+	.close			= snd_au1000_playback_close,
+	.ioctl			= snd_pcm_lib_ioctl,
+	.hw_params	        = snd_au1000_hw_params,
+	.hw_free	        = snd_au1000_hw_free,
+	.prepare		= snd_au1000_playback_prepare,
+	.trigger		= snd_au1000_trigger,
+	.pointer		= snd_au1000_pointer,
+};
+
+static snd_pcm_ops_t snd_card_au1000_capture_ops = {
+	.open			= snd_au1000_capture_open,
+	.close			= snd_au1000_capture_close,
+	.ioctl			= snd_pcm_lib_ioctl,
+	.hw_params	        = snd_au1000_hw_params,
+	.hw_free	        = snd_au1000_hw_free,
+	.prepare		= snd_au1000_capture_prepare,
+	.trigger		= snd_au1000_trigger,
+	.pointer		= snd_au1000_pointer,
+};
+
+static int __devinit
+snd_au1000_pcm_new(void)
+{
+	snd_pcm_t *pcm;
+	int err;
+	unsigned long flags;
+
+	if ((err = snd_pcm_new(au1000->card, "AU1000 AC97 PCM", 0, 1, 1, &pcm)) < 0)
+		return err;
+
+	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
+		snd_dma_continuous_data(GFP_KERNEL), 128*1024, 128*1024);
+
+	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
+		&snd_card_au1000_playback_ops);
+	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
+		&snd_card_au1000_capture_ops);
+
+	pcm->private_data = au1000;
+	pcm->info_flags = 0;
+	strcpy(pcm->name, "Au1000 AC97 PCM");
+
+	flags = claim_dma_lock();
+	if ((au1000->stream[PLAYBACK]->dma = request_au1000_dma(DMA_ID_AC97C_TX,
+			"AC97 TX", au1000_dma_interrupt, SA_INTERRUPT,
+			au1000->stream[PLAYBACK])) < 0) {
+		release_dma_lock(flags);
+		return -EBUSY;
+	}
+	if ((au1000->stream[CAPTURE]->dma = request_au1000_dma(DMA_ID_AC97C_RX,
+			"AC97 RX", au1000_dma_interrupt, SA_INTERRUPT,
+			au1000->stream[CAPTURE])) < 0){
+		release_dma_lock(flags);
+		return -EBUSY;
+	}
+	/* enable DMA coherency in read/write DMA channels */
+	set_dma_mode(au1000->stream[PLAYBACK]->dma,
+		     get_dma_mode(au1000->stream[PLAYBACK]->dma) & ~DMA_NC);
+	set_dma_mode(au1000->stream[CAPTURE]->dma,
+		     get_dma_mode(au1000->stream[CAPTURE]->dma) & ~DMA_NC);
+	release_dma_lock(flags);
+	spin_lock_init(&au1000->stream[PLAYBACK]->dma_lock);
+	spin_lock_init(&au1000->stream[CAPTURE]->dma_lock);
+	au1000->pcm = pcm;
+	return 0;
+}
+
+
+/*-------------------------- AC97 CODEC Control ------------------------------*/
+
+static unsigned short
+snd_au1000_ac97_read(ac97_t *ac97, unsigned short reg)
+{
+	u32 volatile cmd;
+	u16 volatile data;
+	int             i;
+	spin_lock(au1000->ac97_lock);
+/* would rather use the interupt than this polling but it works and I can't
+get the interupt driven case to work efficiently */
+	for (i = 0; i < 0x5000; i++)
+		if (!(au1000->ac97_ioport->status & AC97C_CP))
+			break;
+	if (i == 0x5000)
+		printk(KERN_ERR "au1000 AC97: AC97 command read timeout\n");
+
+	cmd = (u32) reg & AC97C_INDEX_MASK;
+	cmd |= AC97C_READ;
+	au1000->ac97_ioport->cmd = cmd;
+
+	/* now wait for the data */
+	for (i = 0; i < 0x5000; i++)
+		if (!(au1000->ac97_ioport->status & AC97C_CP))
+			break;
+	if (i == 0x5000) {
+		printk(KERN_ERR "au1000 AC97: AC97 command read timeout\n");
+		return 0;
+	}
+
+	data = au1000->ac97_ioport->cmd & 0xffff;
+	spin_unlock(au1000->ac97_lock);
+
+	return data;
+
+}
+
+
+static void
+snd_au1000_ac97_write(ac97_t *ac97, unsigned short reg, unsigned short val)
+{
+	u32 cmd;
+	int i;
+	spin_lock(au1000->ac97_lock);
+/* would rather use the interupt than this polling but it works and I can't
+get the interupt driven case to work efficiently */
+	for (i = 0; i < 0x5000; i++)
+		if (!(au1000->ac97_ioport->status & AC97C_CP))
+			break;
+	if (i == 0x5000)
+		printk(KERN_ERR "au1000 AC97: AC97 command write timeout\n");
+
+	cmd = (u32) reg & AC97C_INDEX_MASK;
+	cmd &= ~AC97C_READ;
+	cmd |= ((u32) val << AC97C_WD_BIT);
+	au1000->ac97_ioport->cmd = cmd;
+	spin_unlock(au1000->ac97_lock);
+}
+static void
+snd_au1000_ac97_free(ac97_t *ac97)
+{
+	au1000->ac97 = NULL;
+}
+
+static int __devinit
+snd_au1000_ac97_new(void)
+{
+	int err;
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8)
+	ac97_bus_t *pbus;
+	ac97_template_t ac97;
+ 	static ac97_bus_ops_t ops = {
+		.write = snd_au1000_ac97_write,
+		.read = snd_au1000_ac97_read,
+	};
+#else
+	ac97_bus_t bus, *pbus;
+	ac97_t ac97;
+#endif
+
+	if ((au1000->ac97_res_port = request_region(AC97C_CONFIG,
+	       		sizeof(au1000_ac97_reg_t), "Au1x00 AC97")) == NULL) {
+		snd_printk(KERN_ERR "ALSA AC97: can't grap AC97 port\n");
+		return -EBUSY;
+	}
+	au1000->ac97_ioport = (au1000_ac97_reg_t *) au1000->ac97_res_port->start;
+
+	spin_lock_init(&au1000->ac97_lock);
+
+	spin_lock(&au1000->ac97_lock);
+
+	/* configure pins for AC'97
+	TODO: move to board_setup.c */
+	au_writel(au_readl(SYS_PINFUNC) & ~0x02, SYS_PINFUNC);
+
+	/* Initialise Au1000's AC'97 Control Block */
+	au1000->ac97_ioport->cntrl = AC97C_RS | AC97C_CE;
+	udelay(10);
+	au1000->ac97_ioport->cntrl = AC97C_CE;
+	udelay(10);
+
+	/* Initialise External CODEC -- cold reset */
+	au1000->ac97_ioport->config = AC97C_RESET;
+	udelay(10);
+	au1000->ac97_ioport->config = 0x0;
+	mdelay(5);
+
+	spin_unlock(&au1000->ac97_lock);
+
+	/* Initialise AC97 middle-layer */
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8)
+	if ((err = snd_ac97_bus(au1000->card, 0, &ops, au1000, &pbus)) < 0)
+ 		return err;
+#else
+	memset(&bus, 0, sizeof(bus));
+	bus.write = snd_au1000_ac97_write;
+	bus.read = snd_au1000_ac97_read;
+	if ((err = snd_ac97_bus(au1000->card, &bus, &pbus)) < 0)
+		return err;
+#endif
+	memset(&ac97, 0, sizeof(ac97));
+	ac97.private_data = au1000;
+	ac97.private_free = snd_au1000_ac97_free;
+	if ((err = snd_ac97_mixer(pbus, &ac97, &au1000->ac97)) < 0)
+		return err;
+	return 0;
+
+}
+
+/*------------------------------ Setup / Destroy ----------------------------*/
+
+void
+snd_au1000_free(snd_card_t *card)
+{
+
+	if (au1000->ac97_res_port) {
+		/* put internal AC97 block into reset */
+		au1000->ac97_ioport->cntrl = AC97C_RS;
+		au1000->ac97_ioport = NULL;
+		release_resource(au1000->ac97_res_port);
+		kfree_nocheck(au1000->ac97_res_port);
+	}
+
+	if (au1000->stream[PLAYBACK]->dma >= 0)
+		free_au1000_dma(au1000->stream[PLAYBACK]->dma);
+
+	if (au1000->stream[CAPTURE]->dma >= 0)
+		free_au1000_dma(au1000->stream[CAPTURE]->dma);
+
+	kfree(au1000->stream[PLAYBACK]);
+	au1000->stream[PLAYBACK] = NULL;
+	kfree(au1000->stream[CAPTURE]);
+	au1000->stream[CAPTURE] = NULL;
+	kfree(au1000);
+	au1000 = NULL;
+
+}
+
+static int __init
+au1000_init(void)
+{
+	int err;
+
+	au1000 = kmalloc(sizeof(au1000_t), GFP_KERNEL);
+	if (au1000 == NULL)
+		return -ENOMEM;
+	au1000->stream[PLAYBACK] = kmalloc(sizeof(audio_stream_t), GFP_KERNEL);
+	if (au1000->stream[PLAYBACK] == NULL)
+		return -ENOMEM;
+	au1000->stream[CAPTURE] = kmalloc(sizeof(audio_stream_t), GFP_KERNEL);
+	if (au1000->stream[CAPTURE] == NULL)
+		return -ENOMEM;
+	/* so that snd_au1000_free will work as intended */
+	au1000->stream[PLAYBACK]->dma = -1;
+	au1000->stream[CAPTURE]->dma = -1;
+ 	au1000->ac97_res_port = NULL;
+
+	au1000->card = snd_card_new(-1, "AC97", THIS_MODULE, sizeof(au1000_t));
+	if (au1000->card == NULL) {
+		snd_au1000_free(au1000->card);
+		return -ENOMEM;
+	}
+
+	au1000->card->private_data = (au1000_t *)au1000;
+	au1000->card->private_free = snd_au1000_free;
+
+	if ((err = snd_au1000_ac97_new()) < 0 ) {
+		snd_card_free(au1000->card);
+		return err;
+	}
+
+	if ((err = snd_au1000_pcm_new()) < 0) {
+		snd_card_free(au1000->card);
+		return err;
+	}
+
+	strcpy(au1000->card->driver, "AMD-Au1000-AC97");
+	strcpy(au1000->card->shortname, "Au1000-AC97");
+	sprintf(au1000->card->longname, "AMD Au1000--AC97 ALSA Driver");
+
+	if ((err = snd_card_register(au1000->card)) < 0) {
+		snd_card_free(au1000->card);
+		return err;
+	}
+
+	printk( KERN_INFO "ALSA AC97: Driver Initialized\n" );
+	return 0;
+}
+
+static void __exit au1000_exit(void)
+{
+	snd_card_free(au1000->card);
+}
+
+module_init(au1000_init);
+module_exit(au1000_exit);
+
diff -Nru a/sound/oss/Kconfig b/sound/oss/Kconfig
--- a/sound/oss/Kconfig	2005-03-01 23:39:09 -08:00
+++ b/sound/oss/Kconfig	2005-03-01 23:39:09 -08:00
@@ -100,6 +100,16 @@
 	  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
+	help
+	  The BCM91250A has a Crystal CS4297a on synchronous serial
+	  port B (in addition to the DB-9 serial port).  Say Y or M
+	  here to enable the sound chip instead of the UART.  Also
+	  note that CONFIG_KGDB should not be enabled at the same
+	  time, since it also attempts to use this UART port.
+
 config SOUND_ES1370
 	tristate "Ensoniq AudioPCI (ES1370)"
 	depends on SOUND_PRIME!=n && SOUND && PCI && SOUND_GAMEPORT
@@ -194,6 +204,10 @@
 	  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
+
 config SOUND_VRC5477
 	tristate "NEC Vrc5477 AC97 sound"
 	depends on SOUND_PRIME!=n && DDB5477 && SOUND
@@ -202,6 +216,14 @@
 	  integrated, multi-function controller chip for MIPS CPUs.  Works
 	  with the AC97 codec.
 
+config SOUND_AU1000
+	tristate "Au1000 Sound"
+	depends on SOUND_PRIME!=n && (SOC_AU1000 || SOC_AU1100 || SOC_AU1500) && SOUND
+
+config SOUND_AU1550_AC97
+	tristate "Au1550 AC97 Sound"
+	depends on SOUND_PRIME!=n && SOC_AU1550 && SOUND
+
 config SOUND_TRIDENT
 	tristate "Trident 4DWave DX/NX, SiS 7018 or ALi 5451 PCI Audio Core"
 	depends on SOUND_PRIME!=n && SOUND && SOUND_GAMEPORT
@@ -423,7 +445,7 @@
 	depends on MSNDPIN_NONPNP
 	default "0"
 	help
-	  Iinterrupt request number for the Kurzweil daughterboard
+	  Interrupt request number for the Kurzweil daughterboard
 	  synthesizer on MultiSound Pinnacle and Fiji sound cards.
 
 config MSNDPIN_IDE_IO0
@@ -1081,8 +1103,8 @@
 	depends on SOUND_PRIME!=n && PCI
 	help
 	  Say Y or M if you have a Hammerfall or Hammerfall light
-	  multichannel card from RME. If you want to acess advanced
-	  features of the card, read Documentation/sound/oss/rme96xx.
+	  multichannel card from RME. If you want to access advanced
+	  features of the card, read <file:Documentation/sound/oss/rme96xx>.
 
 config SOUND_AD1980
 	tristate "AD1980 front/back switch plugin"
diff -Nru a/sound/oss/Makefile b/sound/oss/Makefile
--- a/sound/oss/Makefile	2005-03-01 23:38:54 -08:00
+++ b/sound/oss/Makefile	2005-03-01 23:38:54 -08:00
@@ -64,6 +64,8 @@
 obj-$(CONFIG_SOUND_ES1370)	+= es1370.o
 obj-$(CONFIG_SOUND_ES1371)	+= es1371.o ac97_codec.o
 obj-$(CONFIG_SOUND_VRC5477)	+= nec_vrc5477.o ac97_codec.o
+obj-$(CONFIG_SOUND_AU1000)	+= au1000.o ac97_codec.o
+obj-$(CONFIG_SOUND_AU1550_AC97)	+= au1550_ac97.o ac97_codec.o
 obj-$(CONFIG_SOUND_ESSSOLO1)	+= esssolo1.o
 obj-$(CONFIG_SOUND_FUSION)	+= cs46xx.o ac97_codec.o
 obj-$(CONFIG_SOUND_MAESTRO)	+= maestro.o
@@ -71,6 +73,7 @@
 obj-$(CONFIG_SOUND_TRIDENT)	+= trident.o ac97_codec.o
 obj-$(CONFIG_SOUND_HARMONY)	+= harmony.o
 obj-$(CONFIG_SOUND_EMU10K1)	+= ac97_codec.o
+obj-$(CONFIG_SOUND_BCM_CS4297A)	+= swarm_cs4297a.o
 obj-$(CONFIG_SOUND_RME96XX)     += rme96xx.o
 obj-$(CONFIG_SOUND_BT878)	+= btaudio.o
 obj-$(CONFIG_SOUND_ALI5455)	+= ali5455.o ac97_codec.o
diff -Nru a/sound/oss/ac97.c b/sound/oss/ac97.c
--- a/sound/oss/ac97.c	2005-03-01 23:39:07 -08:00
+++ b/sound/oss/ac97.c	2005-03-01 23:39:07 -08:00
@@ -133,7 +133,7 @@
 
 /* Return the contents of register REG; use the cache if the value in it
    is valid.  Returns a negative error code on failure. */
-int
+static int
 ac97_get_register (struct ac97_hwint *dev, u8 reg) 
 {
     if (reg > 127 || (reg & 1))
@@ -226,7 +226,7 @@
     }
 }
 
-int
+static int
 ac97_set_mixer (struct ac97_hwint *dev, int oss_channel, u16 oss_value)
 {
     int scaled_value;
@@ -262,7 +262,7 @@
     return result;
 }
 
-int
+static int
 ac97_get_mixer_scaled (struct ac97_hwint *dev, int oss_channel)
 {
     struct ac97_chn_desc *channel = ac97_find_chndesc (dev, oss_channel);
@@ -292,7 +292,7 @@
 				  channel->is_inverted);
 }
 
-int
+static int
 ac97_get_recmask (struct ac97_hwint *dev)
 {
     int recReg = ac97_get_register (dev, AC97_RECORD_SELECT);
@@ -309,7 +309,7 @@
     }
 }
 
-int
+static int
 ac97_set_recmask (struct ac97_hwint *dev, int oss_recmask)
 {
     int x;
@@ -439,10 +439,7 @@
 
 EXPORT_SYMBOL(ac97_init);
 EXPORT_SYMBOL(ac97_set_values);
-EXPORT_SYMBOL(ac97_set_mixer);
-EXPORT_SYMBOL(ac97_get_register);
 EXPORT_SYMBOL(ac97_put_register);
-EXPORT_SYMBOL(ac97_get_mixer_scaled);
 EXPORT_SYMBOL(ac97_mixer_ioctl);
 EXPORT_SYMBOL(ac97_reset);
 MODULE_LICENSE("GPL");
diff -Nru a/sound/oss/ac97.h b/sound/oss/ac97.h
--- a/sound/oss/ac97.h	2005-03-01 23:39:07 -08:00
+++ b/sound/oss/ac97.h	2005-03-01 23:39:07 -08:00
@@ -184,25 +184,9 @@
 extern int ac97_set_values (struct ac97_hwint *dev,
 			    struct ac97_mixer_value_list *value_list);
 
-/* Sets one mixer channel OSS_CHANNEL to the scaled value OSS_VALUE.
-   Returns the resulting (rescaled) value, or a negative value
-   representing an error code.
-
-   Stereo channels have two values in OSS_VALUE (the left value is in the
-   lower 8 bits, the right value is in the upper 8 bits). */
-extern int ac97_set_mixer (struct ac97_hwint *dev, int oss_channel,
-			   u16 oss_value);
-
-/* Return the contents of the specified AC97 register REG; it uses the
-   last-written value if it is available.  */
-extern int ac97_get_register (struct ac97_hwint *dev, u8 reg);
-
 /* Writes the specified VALUE to the AC97 register REG in the mixer.
    Takes care of setting the last-written cache as well.  */
 extern int ac97_put_register (struct ac97_hwint *dev, u8 reg, u16 value);
-
-/* Returns the last OSS value written to the OSS_CHANNEL mixer channel.  */
-extern int ac97_get_mixer_scaled (struct ac97_hwint *dev, int oss_channel);
 
 /* Default ioctl. */
 extern int ac97_mixer_ioctl (struct ac97_hwint *dev, unsigned int cmd,
diff -Nru a/sound/oss/ac97_codec.c b/sound/oss/ac97_codec.c
--- a/sound/oss/ac97_codec.c	2005-03-01 23:38:52 -08:00
+++ b/sound/oss/ac97_codec.c	2005-03-01 23:38:52 -08:00
@@ -52,6 +52,7 @@
 #include <linux/errno.h>
 #include <linux/bitops.h>
 #include <linux/delay.h>
+#include <linux/pci.h>
 #include <linux/ac97_codec.h>
 #include <asm/uaccess.h>
 
@@ -128,6 +129,9 @@
 	{0x41445348, "Analog Devices AD1881A",	&null_ops},
 	{0x41445360, "Analog Devices AD1885",	&default_ops},
 	{0x41445361, "Analog Devices AD1886",	&ad1886_ops},
+	{0x41445370, "Analog Devices AD1981",	&null_ops},
+	{0x41445372, "Analog Devices AD1981A",	&null_ops},
+	{0x41445374, "Analog Devices AD1981B",	&null_ops},
 	{0x41445460, "Analog Devices AD1885",	&default_ops},
 	{0x41445461, "Analog Devices AD1886",	&ad1886_ops},
 	{0x414B4D00, "Asahi Kasei AK4540",	&null_ops},
@@ -173,6 +177,7 @@
 	{0x83847608, "SigmaTel STAC9708",	&sigmatel_9708_ops},
 	{0x83847609, "SigmaTel STAC9721/23",	&sigmatel_9721_ops},
 	{0x83847644, "SigmaTel STAC9744/45",	&sigmatel_9744_ops},
+	{0x83847652, "SigmaTel STAC9752/53",	&default_ops},
 	{0x83847656, "SigmaTel STAC9756/57",	&sigmatel_9744_ops},
 	{0x83847666, "SigmaTel STAC9750T",	&sigmatel_9744_ops},
 	{0x83847684, "SigmaTel STAC9783/84?",	&null_ops},
@@ -1453,5 +1458,92 @@
 }
 
 EXPORT_SYMBOL_GPL(ac97_unregister_driver);
+
+static int swap_headphone(int remove_master)
+{
+	struct list_head *l;
+	struct ac97_codec *c;
 	
+	if (remove_master) {
+		down(&codec_sem);
+		list_for_each(l, &codecs)
+		{
+			c = list_entry(l, struct ac97_codec, list);
+			if (supported_mixer(c, SOUND_MIXER_PHONEOUT))
+				c->supported_mixers &= ~SOUND_MASK_PHONEOUT;
+		}
+		up(&codec_sem);
+	} else
+		ac97_hw[SOUND_MIXER_PHONEOUT].offset = AC97_MASTER_VOL_STEREO;
+
+	/* Scale values already match */
+	ac97_hw[SOUND_MIXER_VOLUME].offset = AC97_MASTER_VOL_MONO;
+	return 0;
+}
+
+static int apply_quirk(int quirk)
+{
+	switch (quirk) {
+	case AC97_TUNE_NONE:
+		return 0;
+	case AC97_TUNE_HP_ONLY:
+		return swap_headphone(1);
+	case AC97_TUNE_SWAP_HP:
+		return swap_headphone(0);
+	case AC97_TUNE_SWAP_SURROUND:
+		return -ENOSYS; /* not yet implemented */
+	case AC97_TUNE_AD_SHARING:
+		return -ENOSYS; /* not yet implemented */
+	case AC97_TUNE_ALC_JACK:
+		return -ENOSYS; /* not yet implemented */
+	}
+	return -EINVAL;
+}
+
+/**
+ *	ac97_tune_hardware - tune up the hardware
+ *	@pdev: pci_dev pointer
+ *	@quirk: quirk list
+ *	@override: explicit quirk value (overrides if not AC97_TUNE_DEFAULT)
+ *
+ *	Do some workaround for each pci device, such as renaming of the
+ *	headphone (true line-out) control as "Master".
+ *	The quirk-list must be terminated with a zero-filled entry.
+ *
+ *	Returns zero if successful, or a negative error code on failure.
+ */
+
+int ac97_tune_hardware(struct pci_dev *pdev, struct ac97_quirk *quirk, int override)
+{
+	int result;
+
+	if (!quirk)
+		return -EINVAL;
+
+	if (override != AC97_TUNE_DEFAULT) {
+		result = apply_quirk(override);
+		if (result < 0)
+			printk(KERN_ERR "applying quirk type %d failed (%d)\n", override, result);
+		return result;
+	}
+
+	for (; quirk->vendor; quirk++) {
+		if (quirk->vendor != pdev->subsystem_vendor)
+			continue;
+		if ((! quirk->mask && quirk->device == pdev->subsystem_device) ||
+		    quirk->device == (quirk->mask & pdev->subsystem_device)) {
+#ifdef DEBUG
+			printk("ac97 quirk for %s (%04x:%04x)\n", quirk->name, ac97->subsystem_vendor, pdev->subsystem_device);
+#endif
+			result = apply_quirk(quirk->type);
+			if (result < 0)
+				printk(KERN_ERR "applying quirk type %d for %s failed (%d)\n", quirk->type, quirk->name, result);
+			return result;
+		}
+	}
+	return 0;
+}
+
+EXPORT_SYMBOL_GPL(ac97_tune_hardware);
+
 MODULE_LICENSE("GPL");
diff -Nru a/sound/oss/aci.c b/sound/oss/aci.c
--- a/sound/oss/aci.c	2005-03-01 23:38:57 -08:00
+++ b/sound/oss/aci.c	2005-03-01 23:38:57 -08:00
@@ -83,18 +83,18 @@
 
 #ifdef MODULE
 static int reset;
-MODULE_PARM(reset,"i");
+module_param(reset, bool, 0);
 MODULE_PARM_DESC(reset,"When set to 1, reset aci mixer.");
 #else
 static int reset = 1;
 #endif
 
 static int ide=-1;
-MODULE_PARM(ide,"i");
+module_param(ide, int, 0);
 MODULE_PARM_DESC(ide,"1 enable, 0 disable ide-port - untested"
 		 " default: do nothing");
 static int wss=-1;
-MODULE_PARM(wss,"i");
+module_param(wss, int, 0);
 MODULE_PARM_DESC(wss,"change between ACI/WSS-mixer; use 0 and 1 - untested"
 		 " default: do nothing; for PCM1-pro only");
 
diff -Nru a/sound/oss/ad1816.c b/sound/oss/ad1816.c
--- a/sound/oss/ad1816.c	2005-03-01 23:39:16 -08:00
+++ b/sound/oss/ad1816.c	2005-03-01 23:39:16 -08:00
@@ -1215,16 +1215,16 @@
 /* use isapnp for configuration */
 static int isapnp	= 1;
 static int isapnpjump;
-MODULE_PARM(isapnp, "i");
-MODULE_PARM(isapnpjump, "i");
+module_param(isapnp, bool, 0);
+module_param(isapnpjump, int, 0);
 #endif
 
-MODULE_PARM(io,"i");
-MODULE_PARM(irq,"i");
-MODULE_PARM(dma,"i");
-MODULE_PARM(dma2,"i");
-MODULE_PARM(ad1816_clockfreq,"i");
-MODULE_PARM(options,"i");
+module_param(io, int, 0);
+module_param(irq, int, 0);
+module_param(dma, int, 0);
+module_param(dma2, int, 0);
+module_param(ad1816_clockfreq, int, 0);
+module_param(options, int, 0);
 
 #ifdef __ISAPNP__
 static struct {
@@ -1245,8 +1245,9 @@
 MODULE_DEVICE_TABLE(isapnp, isapnp_ad1816_list);
 
 
-void __init ad1816_config_pnp_card(struct pnp_card *card, unsigned short vendor,
-	unsigned short function)
+static void __init ad1816_config_pnp_card(struct pnp_card *card,
+					  unsigned short vendor,
+					  unsigned short function)
 {
 	struct address_info cfg;
   	struct pnp_dev *card_dev = pnp_find_dev(card, vendor, function, NULL);
@@ -1270,7 +1271,7 @@
 	}
 }
 
-void __init ad1816_config_pnp_cards(void)
+static void __init ad1816_config_pnp_cards(void)
 {
 	int nr_pnp_cfg;
 	int i;
diff -Nru a/sound/oss/ad1848.c b/sound/oss/ad1848.c
--- a/sound/oss/ad1848.c	2005-03-01 23:39:06 -08:00
+++ b/sound/oss/ad1848.c	2005-03-01 23:39:06 -08:00
@@ -123,9 +123,9 @@
 static struct address_info cfg;
 static int nr_ad1848_devs;
 
-int deskpro_xl;
-int deskpro_m;
-int soundpro;
+static int deskpro_xl;
+static int deskpro_m;
+static int soundpro;
 
 static volatile signed char irq2dev[17] = {
 	-1, -1, -1, -1, -1, -1, -1, -1,
@@ -2905,24 +2905,24 @@
 static int __initdata dma2 = -1;
 static int __initdata type = 0;
 
-MODULE_PARM(io, "i");                   /* I/O for a raw AD1848 card */
-MODULE_PARM(irq, "i");                  /* IRQ to use */
-MODULE_PARM(dma, "i");                  /* First DMA channel */
-MODULE_PARM(dma2, "i");                 /* Second DMA channel */
-MODULE_PARM(type, "i");                 /* Card type */
-MODULE_PARM(deskpro_xl, "i");           /* Special magic for Deskpro XL boxen */
-MODULE_PARM(deskpro_m, "i");            /* Special magic for Deskpro M box */
-MODULE_PARM(soundpro, "i");             /* More special magic for SoundPro chips */
+module_param(io, int, 0);		/* I/O for a raw AD1848 card */
+module_param(irq, int, 0);		/* IRQ to use */
+module_param(dma, int, 0);		/* First DMA channel */
+module_param(dma2, int, 0);		/* Second DMA channel */
+module_param(type, int, 0);		/* Card type */
+module_param(deskpro_xl, bool, 0);	/* Special magic for Deskpro XL boxen */
+module_param(deskpro_m, bool, 0);	/* Special magic for Deskpro M box */
+module_param(soundpro, bool, 0);	/* More special magic for SoundPro chips */
 
 #ifdef CONFIG_PNP
-MODULE_PARM(isapnp,	"i");
-MODULE_PARM(isapnpjump,	"i");
-MODULE_PARM(reverse,	"i");
+module_param(isapnp, int, 0);
+module_param(isapnpjump, int, 0);
+module_param(reverse, bool, 0);
 MODULE_PARM_DESC(isapnp,	"When set to 0, Plug & Play support will be disabled");
 MODULE_PARM_DESC(isapnpjump,	"Jumps to a specific slot in the driver's PnP table. Use the source, Luke.");
 MODULE_PARM_DESC(reverse,	"When set to 1, will reverse ISAPnP search order");
 
-struct pnp_dev	*ad1848_dev  = NULL;
+static struct pnp_dev	*ad1848_dev  = NULL;
 
 /* Please add new entries at the end of the table */
 static struct {
diff -Nru a/sound/oss/ad1889.c b/sound/oss/ad1889.c
--- a/sound/oss/ad1889.c	2005-03-01 23:38:55 -08:00
+++ b/sound/oss/ad1889.c	2005-03-01 23:38:55 -08:00
@@ -82,20 +82,6 @@
 	ac97_codec->codec_write(dev->ac97_codec, AC97_POWER_CONTROL, 0);
 }
 
-static inline void ad1889_set_adc_rate(ad1889_dev_t *dev, int rate)
-{
-	struct ac97_codec *ac97_codec = dev->ac97_codec;
-
-	DBG("Setting ADC rate to %d\n", rate);
-	dev->state[AD_ADC_STATE].dmabuf.rate = rate;
-	AD1889_WRITEW(dev, AD_DSRES, rate);
-
-	/* Cycle the ADC to enable the new rate */
-	ac97_codec->codec_write(dev->ac97_codec, AC97_POWER_CONTROL, 0x0100);
-	WAIT_10MS();
-	ac97_codec->codec_write(dev->ac97_codec, AC97_POWER_CONTROL, 0);
-}
-
 static inline void ad1889_set_wav_fmt(ad1889_dev_t *dev, int fmt)
 {
 	u16 tmp;
@@ -308,8 +294,8 @@
 	ad1889_start_wav(&dev->state[AD_WAV_STATE]);
 }
 
-int ad1889_read_proc (char *page, char **start, off_t off,
-		      int count, int *eof, void *data)
+static int ad1889_read_proc (char *page, char **start, off_t off,
+			     int count, int *eof, void *data)
 {
 	char *out = page;
 	int len, i;
diff -Nru a/sound/oss/adlib_card.c b/sound/oss/adlib_card.c
--- a/sound/oss/adlib_card.c	2005-03-01 23:38:53 -08:00
+++ b/sound/oss/adlib_card.c	2005-03-01 23:38:53 -08:00
@@ -31,7 +31,7 @@
 
 static int __initdata io = -1;
 
-MODULE_PARM(io, "i");
+module_param(io, int, 0);
 
 static int __init init_adlib(void)
 {
diff -Nru a/sound/oss/aedsp16.c b/sound/oss/aedsp16.c
--- a/sound/oss/aedsp16.c	2005-03-01 23:38:57 -08:00
+++ b/sound/oss/aedsp16.c	2005-03-01 23:38:57 -08:00
@@ -438,7 +438,7 @@
 	int cdrombase;
 };
 
-struct d_hcfg decoded_hcfg __initdata = {0, };
+static struct d_hcfg decoded_hcfg __initdata = {0, };
 
 #endif /* CONFIG_SC6600 */
 
@@ -489,7 +489,7 @@
 	{0x00, 0x00}
 };
 
-static struct aedsp16_info ae_config __initdata = {
+static struct aedsp16_info ae_config = {
 	DEF_AEDSP16_IOB,
 	DEF_AEDSP16_IRQ,
 	DEF_AEDSP16_MRQ,
@@ -610,7 +610,7 @@
 }
 #endif
 
-void __init aedsp16_hard_decode(void) {
+static void __init aedsp16_hard_decode(void) {
 
 	DBG((" aedsp16_hard_decode: 0x%x, 0x%x\n", hard_cfg[0], hard_cfg[1]));
 
@@ -654,7 +654,7 @@
 	DBG(("success.\n"));
 }
 
-void __init aedsp16_hard_encode(void) {
+static void __init aedsp16_hard_encode(void) {
 
 	DBG((" aedsp16_hard_encode: 0x%x, 0x%x\n", hard_cfg[0], hard_cfg[1]));
 
@@ -1155,7 +1155,7 @@
 	return TRUE;
 }
 
-static void __init uninit_aedsp16_sb(void)
+static void uninit_aedsp16_sb(void)
 {
 	DBG(("uninit_aedsp16_sb: "));
 
@@ -1196,7 +1196,7 @@
 	return TRUE;
 }
 
-static void __init uninit_aedsp16_mss(void)
+static void uninit_aedsp16_mss(void)
 {
 	DBG(("uninit_aedsp16_mss: "));
 
@@ -1237,7 +1237,7 @@
 	return TRUE;
 }
 
-static void __init uninit_aedsp16_mpu(void)
+static void uninit_aedsp16_mpu(void)
 {
 	DBG(("uninit_aedsp16_mpu: "));
 
@@ -1252,7 +1252,7 @@
 	DBG(("done.\n"));
 }
 
-int __init init_aedsp16(void)
+static int __init init_aedsp16(void)
 {
 	int initialized = FALSE;
 
@@ -1294,7 +1294,7 @@
 	return initialized;
 }
 
-void __init uninit_aedsp16(void)
+static void __exit uninit_aedsp16(void)
 {
 	if (ae_config.mss_base != -1)
 		uninit_aedsp16_mss();
@@ -1311,17 +1311,17 @@
 static int __initdata mss_base = -1;
 static int __initdata mpu_base = -1;
 
-MODULE_PARM(io, "i");
+module_param(io, int, 0);
 MODULE_PARM_DESC(io, "I/O base address (0x220 0x240)");
-MODULE_PARM(irq, "i");
+module_param(irq, int, 0);
 MODULE_PARM_DESC(irq, "IRQ line (5 7 9 10 11)");
-MODULE_PARM(dma, "i");
+module_param(dma, int, 0);
 MODULE_PARM_DESC(dma, "dma line (0 1 3)");
-MODULE_PARM(mpu_irq, "i");
+module_param(mpu_irq, int, 0);
 MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ line (5 7 9 10 0)");
-MODULE_PARM(mss_base, "i");
+module_param(mss_base, int, 0);
 MODULE_PARM_DESC(mss_base, "MSS emulation I/O base address (0x530 0xE80)");
-MODULE_PARM(mpu_base, "i");
+module_param(mpu_base, int, 0);
 MODULE_PARM_DESC(mpu_base,"MPU-401 I/O base address (0x300 0x310 0x320 0x330)");
 MODULE_AUTHOR("Riccardo Facchetti <fizban@tin.it>");
 MODULE_DESCRIPTION("Audio Excel DSP 16 Driver Version " VERSION);
diff -Nru a/sound/oss/ali5455.c b/sound/oss/ali5455.c
--- a/sound/oss/ali5455.c	2005-03-01 23:39:09 -08:00
+++ b/sound/oss/ali5455.c	2005-03-01 23:39:09 -08:00
@@ -3651,12 +3651,13 @@
 MODULE_AUTHOR("");
 MODULE_DESCRIPTION("ALI 5455 audio support");
 MODULE_LICENSE("GPL");
-MODULE_PARM(clocking, "i");
-MODULE_PARM(strict_clocking, "i");
-MODULE_PARM(codec_pcmout_share_spdif_locked, "i");
-MODULE_PARM(codec_independent_spdif_locked, "i");
-MODULE_PARM(controller_pcmout_share_spdif_locked, "i");
-MODULE_PARM(controller_independent_spdif_locked, "i");
+module_param(clocking, int, 0);
+/* FIXME: bool? */
+module_param(strict_clocking, uint, 0);
+module_param(codec_pcmout_share_spdif_locked, uint, 0);
+module_param(codec_independent_spdif_locked, uint, 0);
+module_param(controller_pcmout_share_spdif_locked, uint, 0);
+module_param(controller_independent_spdif_locked, uint, 0);
 #define ALI5455_MODULE_NAME "ali5455"
 static struct pci_driver ali_pci_driver = {
 	.name		= ALI5455_MODULE_NAME,
diff -Nru a/sound/oss/au1000.c b/sound/oss/au1000.c
--- a/sound/oss/au1000.c	2005-03-01 23:39:07 -08:00
+++ b/sound/oss/au1000.c	2005-03-01 23:39:07 -08:00
@@ -59,6 +59,7 @@
 #include <linux/slab.h>
 #include <linux/soundcard.h>
 #include <linux/init.h>
+#include <linux/page-flags.h>
 #include <linux/poll.h>
 #include <linux/pci.h>
 #include <linux/bitops.h>
@@ -66,21 +67,18 @@
 #include <linux/spinlock.h>
 #include <linux/smp_lock.h>
 #include <linux/ac97_codec.h>
-#include <linux/wrapper.h>
 #include <linux/interrupt.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
-#include <asm/au1000.h>
-#include <asm/au1000_dma.h>
+#include <asm/mach-au1x00/au1000.h>
+#include <asm/mach-au1x00/au1000_dma.h>
 
 /* --------------------------------------------------------------------- */
 
 #undef OSS_DOCUMENTED_MIXER_SEMANTICS
-#define AU1000_DEBUG
+#undef AU1000_DEBUG
 #undef AU1000_VERBOSE_DEBUG
 
-#define USE_COHERENT_DMA
-
 #define AU1000_MODULE_NAME "Au1000 audio"
 #define PFX AU1000_MODULE_NAME
 
@@ -116,7 +114,7 @@
 	struct proc_dir_entry *ac97_ps;
 #endif				/* AU1000_DEBUG */
 
-	struct ac97_codec *codec;
+	struct ac97_codec codec;
 	unsigned        codec_base_caps;// AC'97 reg 00h, "Reset Register"
 	unsigned        codec_ext_caps;	// AC'97 reg 28h, "Extended Audio ID"
 	int             no_vra;	// do not use VRA
@@ -191,35 +189,6 @@
 	return r;
 }
 
-
-#ifdef USE_COHERENT_DMA
-static inline void * dma_alloc(size_t size, dma_addr_t * dma_handle)
-{
-	void* ret = (void *)__get_free_pages(GFP_ATOMIC | GFP_DMA,
-					     get_order(size));
-	if (ret != NULL) {
-		memset(ret, 0, size);
-		*dma_handle = virt_to_phys(ret);
-	}
-	return ret;
-}
-
-static inline void dma_free(size_t size, void* va, dma_addr_t dma_handle)
-{
-	free_pages((unsigned long)va, get_order(size));
-}
-#else
-static inline void * dma_alloc(size_t size, dma_addr_t * dma_handle)
-{
-	return pci_alloc_consistent(NULL, size, dma_handle);
-}
-
-static inline void dma_free(size_t size, void* va, dma_addr_t dma_handle)
-{
-	pci_free_consistent(NULL, size, va, dma_handle);
-}
-#endif
-
 /* --------------------------------------------------------------------- */
 
 static void au1000_delay(int msec)
@@ -356,17 +325,17 @@
 
 	adc->src_factor = 1;
 
-	ac97_extstat = rdcodec(s->codec, AC97_EXTENDED_STATUS);
+	ac97_extstat = rdcodec(&s->codec, AC97_EXTENDED_STATUS);
 
 	rate = rate > 48000 ? 48000 : rate;
 
 	// enable VRA
-	wrcodec(s->codec, AC97_EXTENDED_STATUS,
+	wrcodec(&s->codec, AC97_EXTENDED_STATUS,
 		ac97_extstat | AC97_EXTSTAT_VRA);
 	// now write the sample rate
-	wrcodec(s->codec, AC97_PCM_LR_ADC_RATE, (u16) rate);
+	wrcodec(&s->codec, AC97_PCM_LR_ADC_RATE, (u16) rate);
 	// read it back for actual supported rate
-	adc_rate = rdcodec(s->codec, AC97_PCM_LR_ADC_RATE);
+	adc_rate = rdcodec(&s->codec, AC97_PCM_LR_ADC_RATE);
 
 #ifdef AU1000_VERBOSE_DEBUG
 	dbg("%s: set to %d Hz", __FUNCTION__, adc_rate);
@@ -374,11 +343,11 @@
 
 	// some codec's don't allow unequal DAC and ADC rates, in which case
 	// writing one rate reg actually changes both.
-	dac_rate = rdcodec(s->codec, AC97_PCM_FRONT_DAC_RATE);
+	dac_rate = rdcodec(&s->codec, AC97_PCM_FRONT_DAC_RATE);
 	if (dac->num_channels > 2)
-		wrcodec(s->codec, AC97_PCM_SURR_DAC_RATE, dac_rate);
+		wrcodec(&s->codec, AC97_PCM_SURR_DAC_RATE, dac_rate);
 	if (dac->num_channels > 4)
-		wrcodec(s->codec, AC97_PCM_LFE_DAC_RATE, dac_rate);
+		wrcodec(&s->codec, AC97_PCM_LFE_DAC_RATE, dac_rate);
 
 	adc->sample_rate = adc_rate;
 	dac->sample_rate = dac_rate;
@@ -401,23 +370,23 @@
 
 	dac->src_factor = 1;
 
-	ac97_extstat = rdcodec(s->codec, AC97_EXTENDED_STATUS);
+	ac97_extstat = rdcodec(&s->codec, AC97_EXTENDED_STATUS);
 
 	rate = rate > 48000 ? 48000 : rate;
 
 	// enable VRA
-	wrcodec(s->codec, AC97_EXTENDED_STATUS,
+	wrcodec(&s->codec, AC97_EXTENDED_STATUS,
 		ac97_extstat | AC97_EXTSTAT_VRA);
 	// now write the sample rate
-	wrcodec(s->codec, AC97_PCM_FRONT_DAC_RATE, (u16) rate);
+	wrcodec(&s->codec, AC97_PCM_FRONT_DAC_RATE, (u16) rate);
 	// I don't support different sample rates for multichannel,
 	// so make these channels the same.
 	if (dac->num_channels > 2)
-		wrcodec(s->codec, AC97_PCM_SURR_DAC_RATE, (u16) rate);
+		wrcodec(&s->codec, AC97_PCM_SURR_DAC_RATE, (u16) rate);
 	if (dac->num_channels > 4)
-		wrcodec(s->codec, AC97_PCM_LFE_DAC_RATE, (u16) rate);
+		wrcodec(&s->codec, AC97_PCM_LFE_DAC_RATE, (u16) rate);
 	// read it back for actual supported rate
-	dac_rate = rdcodec(s->codec, AC97_PCM_FRONT_DAC_RATE);
+	dac_rate = rdcodec(&s->codec, AC97_PCM_FRONT_DAC_RATE);
 
 #ifdef AU1000_VERBOSE_DEBUG
 	dbg("%s: set to %d Hz", __FUNCTION__, dac_rate);
@@ -425,7 +394,7 @@
 
 	// some codec's don't allow unequal DAC and ADC rates, in which case
 	// writing one rate reg actually changes both.
-	adc_rate = rdcodec(s->codec, AC97_PCM_LR_ADC_RATE);
+	adc_rate = rdcodec(&s->codec, AC97_PCM_LR_ADC_RATE);
 
 	dac->sample_rate = dac_rate;
 	adc->sample_rate = adc_rate;
@@ -603,8 +572,11 @@
 		pend = virt_to_page(db->rawbuf +
 				    (PAGE_SIZE << db->buforder) - 1);
 		for (page = virt_to_page(db->rawbuf); page <= pend; page++)
-			mem_map_unreserve(page);
-		dma_free(PAGE_SIZE << db->buforder, db->rawbuf, db->dmaaddr);
+			ClearPageReserved(page);
+		dma_free_noncoherent(NULL,
+				PAGE_SIZE << db->buforder,
+				db->rawbuf,
+				db->dmaaddr);
 	}
 	db->rawbuf = db->nextIn = db->nextOut = NULL;
 	db->mapped = db->ready = 0;
@@ -622,8 +594,10 @@
 		db->ready = db->mapped = 0;
 		for (order = DMABUF_DEFAULTORDER;
 		     order >= DMABUF_MINORDER; order--)
-			if ((db->rawbuf = dma_alloc(PAGE_SIZE << order,
-						  &db->dmaaddr)))
+			if ((db->rawbuf = dma_alloc_noncoherent(NULL,
+						PAGE_SIZE << order,
+						&db->dmaaddr,
+						0)))
 				break;
 		if (!db->rawbuf)
 			return -ENOMEM;
@@ -633,7 +607,7 @@
 		pend = virt_to_page(db->rawbuf +
 				    (PAGE_SIZE << db->buforder) - 1);
 		for (page = virt_to_page(db->rawbuf); page <= pend; page++)
-			mem_map_reserve(page);
+			SetPageReserved(page);
 	}
 
 	db->cnt_factor = 1;
@@ -708,7 +682,7 @@
 
 
 /* hold spinlock for the following */
-static void dac_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t dac_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	struct au1000_state *s = (struct au1000_state *) dev_id;
 	struct dmabuf  *dac = &s->dma_dac;
@@ -723,7 +697,7 @@
 
 	if ((buff_done = get_dma_buffer_done(dac->dmanr)) == 0) {
 		/* fastpath out, to ease interrupt sharing */
-		return;
+		return IRQ_HANDLED;
 	}
 
 	spin_lock(&s->lock);
@@ -786,10 +760,12 @@
 		wake_up(&dac->wait);
 
 	spin_unlock(&s->lock);
+
+	return IRQ_HANDLED;
 }
 
 
-static void adc_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t adc_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	struct au1000_state *s = (struct au1000_state *) dev_id;
 	struct dmabuf  *adc = &s->dma_adc;
@@ -804,7 +780,7 @@
 
 	if ((buff_done = get_dma_buffer_done(adc->dmanr)) == 0) {
 		/* fastpath out, to ease interrupt sharing */
-		return;
+		return IRQ_HANDLED;
 	}
 
 	spin_lock(&s->lock);
@@ -816,7 +792,7 @@
 			stop_adc(s);
 			adc->error++;
 			err("adc overrun");
-			return;
+			return IRQ_NONE;
 		}
 
 		adc->nextIn += adc->dma_fragsize;
@@ -853,7 +829,7 @@
 			adc->error++;
 			err("adc overrun");
 			spin_unlock(&s->lock);
-			return;
+			return IRQ_NONE;
 		}
 
 		adc->nextIn += 2*adc->dma_fragsize;
@@ -873,6 +849,8 @@
 		wake_up(&adc->wait);
 
 	spin_unlock(&s->lock);
+
+	return IRQ_HANDLED;
 }
 
 /* --------------------------------------------------------------------- */
@@ -904,7 +882,7 @@
 			       unsigned int cmd, unsigned long arg)
 {
 	struct au1000_state *s = (struct au1000_state *)file->private_data;
-	struct ac97_codec *codec = s->codec;
+	struct ac97_codec *codec = &s->codec;
 
 	return mixdev_ioctl(codec, cmd, arg);
 }
@@ -1338,8 +1316,7 @@
 		ret = -EINVAL;
 		goto out;
 	}
-	if (remap_pfn_range(vma->vm_start,
-			     virt_to_phys(db->rawbuf) >> PAGE_SHIFT,
+	if (remap_pfn_range(vma, vma->vm_start, virt_to_phys(db->rawbuf),
 			     size, vma->vm_page_prot)) {
 		ret = -EAGAIN;
 		goto out;
@@ -1500,9 +1477,9 @@
 			s->dma_dac.num_channels = val ? 2 : 1;
 			if (s->codec_ext_caps & AC97_EXT_DACS) {
 				// disable surround and center/lfe in AC'97
-				u16 ext_stat = rdcodec(s->codec,
+				u16 ext_stat = rdcodec(&s->codec,
 						       AC97_EXTENDED_STATUS);
-				wrcodec(s->codec, AC97_EXTENDED_STATUS,
+				wrcodec(&s->codec, AC97_EXTENDED_STATUS,
 					ext_stat | (AC97_EXTSTAT_PRI |
 						    AC97_EXTSTAT_PRJ |
 						    AC97_EXTSTAT_PRK));
@@ -1552,9 +1529,9 @@
 					// disable surround and center/lfe
 					// channels in AC'97
 					u16             ext_stat =
-						rdcodec(s->codec,
+						rdcodec(&s->codec,
 							AC97_EXTENDED_STATUS);
-					wrcodec(s->codec,
+					wrcodec(&s->codec,
 						AC97_EXTENDED_STATUS,
 						ext_stat | (AC97_EXTSTAT_PRI |
 							    AC97_EXTSTAT_PRJ |
@@ -1563,14 +1540,14 @@
 					// enable surround, center/lfe
 					// channels in AC'97
 					u16             ext_stat =
-						rdcodec(s->codec,
+						rdcodec(&s->codec,
 							AC97_EXTENDED_STATUS);
 					ext_stat &= ~AC97_EXTSTAT_PRJ;
 					if (val == 6)
 						ext_stat &=
 							~(AC97_EXTSTAT_PRI |
 							  AC97_EXTSTAT_PRK);
-					wrcodec(s->codec,
+					wrcodec(&s->codec,
 						AC97_EXTENDED_STATUS,
 						ext_stat);
 				}
@@ -1832,7 +1809,7 @@
 		return -EINVAL;
 	}
 
-	return mixdev_ioctl(s->codec, cmd, arg);
+	return mixdev_ioctl(&s->codec, cmd, arg);
 }
 
 
@@ -1983,7 +1960,7 @@
 	len += sprintf(buf + len, "----------------------\n");
 	for (cnt = 0; cnt <= 0x7e; cnt += 2)
 		len += sprintf(buf + len, "reg %02x = %04x\n",
-			       cnt, rdcodec(s->codec, cnt));
+			       cnt, rdcodec(&s->codec, cnt));
 
 	if (fpos >= len) {
 		*start = buf;
@@ -2010,7 +1987,9 @@
 {
 	struct au1000_state *s = &au1000_state;
 	int             val;
+#ifdef AU1000_DEBUG
 	char            proc_str[80];
+#endif
 
 	memset(s, 0, sizeof(struct au1000_state));
 
@@ -2019,23 +1998,16 @@
 	init_waitqueue_head(&s->open_wait);
 	init_MUTEX(&s->open_sem);
 	spin_lock_init(&s->lock);
-	
-	s->codec = ac97_alloc_codec();
-	if(s->codec == NULL)
-	{
-		error("Out of memory");
-		return -1;
-	}
-	s->codec->private_data = s;
-	s->codec->id = 0;
-	s->codec->codec_read = rdcodec;
-	s->codec->codec_write = wrcodec;
-	s->codec->codec_wait = waitcodec;
+	s->codec.private_data = s;
+	s->codec.id = 0;
+	s->codec.codec_read = rdcodec;
+	s->codec.codec_write = wrcodec;
+	s->codec.codec_wait = waitcodec;
 
-	if (!request_region(virt_to_phys((void *) AC97C_CONFIG),
+	if (!request_mem_region(CPHYSADDR(AC97C_CONFIG),
 			    0x14, AU1000_MODULE_NAME)) {
 		err("AC'97 ports in use");
-		goto err_codec;
+		return -1;
 	}
 	// Allocate the DMA Channels
 	if ((s->dma_dac.dmanr = request_au1000_dma(DMA_ID_AC97C_TX,
@@ -2057,25 +2029,17 @@
 	     s->dma_dac.dmanr, get_dma_done_irq(s->dma_dac.dmanr),
 	     s->dma_adc.dmanr, get_dma_done_irq(s->dma_adc.dmanr));
 
-#ifdef USE_COHERENT_DMA
 	// enable DMA coherency in read/write DMA channels
 	set_dma_mode(s->dma_dac.dmanr,
 		     get_dma_mode(s->dma_dac.dmanr) & ~DMA_NC);
 	set_dma_mode(s->dma_adc.dmanr,
 		     get_dma_mode(s->dma_adc.dmanr) & ~DMA_NC);
-#else
-	// disable DMA coherency in read/write DMA channels
-	set_dma_mode(s->dma_dac.dmanr,
-		     get_dma_mode(s->dma_dac.dmanr) | DMA_NC);
-	set_dma_mode(s->dma_adc.dmanr,
-		     get_dma_mode(s->dma_adc.dmanr) | DMA_NC);
-#endif
 
 	/* register devices */
 
 	if ((s->dev_audio = register_sound_dsp(&au1000_audio_fops, -1)) < 0)
 		goto err_dev1;
-	if ((s->codec->dev_mixer =
+	if ((s->codec.dev_mixer =
 	     register_sound_mixer(&au1000_mixer_fops, -1)) < 0)
 		goto err_dev2;
 
@@ -2108,11 +2072,11 @@
 	au_writel(0, AC97C_CONFIG);
 
 	/* codec init */
-	if (!ac97_probe_codec(s->codec))
+	if (!ac97_probe_codec(&s->codec))
 		goto err_dev3;
 
-	s->codec_base_caps = rdcodec(s->codec, AC97_RESET);
-	s->codec_ext_caps = rdcodec(s->codec, AC97_EXTENDED_ID);
+	s->codec_base_caps = rdcodec(&s->codec, AC97_RESET);
+	s->codec_ext_caps = rdcodec(&s->codec, AC97_EXTENDED_ID);
 	info("AC'97 Base/Extended ID = %04x/%04x",
 	     s->codec_base_caps, s->codec_ext_caps);
 
@@ -2124,12 +2088,12 @@
 	 * ALTPCM). ac97_codec.c does not handle detection
 	 * of this channel correctly.
 	 */
-	s->codec->supported_mixers |= SOUND_MASK_ALTPCM;
+	s->codec.supported_mixers |= SOUND_MASK_ALTPCM;
 	/*
 	 * Now set AUX_OUT's default volume.
 	 */
 	val = 0x4343;
-	mixdev_ioctl(s->codec, SOUND_MIXER_WRITE_ALTPCM,
+	mixdev_ioctl(&s->codec, SOUND_MIXER_WRITE_ALTPCM,
 		     (unsigned long) &val);
 	
 	if (!(s->codec_ext_caps & AC97_EXTID_VRA)) {
@@ -2137,8 +2101,8 @@
 		s->no_vra = 1;
 	} else if (!vra) {
 		// Boot option says disable VRA
-		u16 ac97_extstat = rdcodec(s->codec, AC97_EXTENDED_STATUS);
-		wrcodec(s->codec, AC97_EXTENDED_STATUS,
+		u16 ac97_extstat = rdcodec(&s->codec, AC97_EXTENDED_STATUS);
+		wrcodec(&s->codec, AC97_EXTENDED_STATUS,
 			ac97_extstat & ~AC97_EXTSTAT_VRA);
 		s->no_vra = 1;
 	}
@@ -2147,20 +2111,38 @@
 
 	/* set mic to be the recording source */
 	val = SOUND_MASK_MIC;
-	mixdev_ioctl(s->codec, SOUND_MIXER_WRITE_RECSRC,
+	mixdev_ioctl(&s->codec, SOUND_MIXER_WRITE_RECSRC,
 		     (unsigned long) &val);
 
 #ifdef AU1000_DEBUG
 	sprintf(proc_str, "driver/%s/%d/ac97", AU1000_MODULE_NAME,
-		s->codec->id);
+		s->codec.id);
 	s->ac97_ps = create_proc_read_entry (proc_str, 0, NULL,
-					     ac97_read_proc, s->codec);
+					     ac97_read_proc, &s->codec);
+#endif
+
+#ifdef CONFIG_MIPS_XXS1500
+	/* deassert eapd */
+	wrcodec(&s->codec, AC97_POWER_CONTROL,
+			rdcodec(&s->codec, AC97_POWER_CONTROL) & ~0x8000);
+	/* mute a number of signals which seem to be causing problems
+	 * if not muted.
+	 */
+	wrcodec(&s->codec, AC97_PCBEEP_VOL, 0x8000);
+	wrcodec(&s->codec, AC97_PHONE_VOL, 0x8008);
+	wrcodec(&s->codec, AC97_MIC_VOL, 0x8008);
+	wrcodec(&s->codec, AC97_LINEIN_VOL, 0x8808);
+	wrcodec(&s->codec, AC97_CD_VOL, 0x8808);
+	wrcodec(&s->codec, AC97_VIDEO_VOL, 0x8808);
+	wrcodec(&s->codec, AC97_AUX_VOL, 0x8808);
+	wrcodec(&s->codec, AC97_PCMOUT_VOL, 0x0808);
+	wrcodec(&s->codec, AC97_GENERAL_PURPOSE, 0x2000);
 #endif
 
 	return 0;
 
  err_dev3:
-	unregister_sound_mixer(s->codec->dev_mixer);
+	unregister_sound_mixer(s->codec.dev_mixer);
  err_dev2:
 	unregister_sound_dsp(s->dev_audio);
  err_dev1:
@@ -2168,9 +2150,7 @@
  err_dma2:
 	free_au1000_dma(s->dma_dac.dmanr);
  err_dma1:
-	release_region(virt_to_phys((void *) AC97C_CONFIG), 0x14);
- err_codec:
- 	ac97_release_codec(s->codec);
+	release_mem_region(CPHYSADDR(AC97C_CONFIG), 0x14);
 	return -1;
 }
 
@@ -2187,10 +2167,9 @@
 	synchronize_irq();
 	free_au1000_dma(s->dma_adc.dmanr);
 	free_au1000_dma(s->dma_dac.dmanr);
-	release_region(virt_to_phys((void *) AC97C_CONFIG), 0x14);
+	release_mem_region(CPHYSADDR(AC97C_CONFIG), 0x14);
 	unregister_sound_dsp(s->dev_audio);
-	unregister_sound_mixer(s->codec->dev_mixer);
-	ac97_release_codec(s->codec);
+	unregister_sound_mixer(s->codec.dev_mixer);
 }
 
 static int __init init_au1000(void)
@@ -2219,7 +2198,7 @@
 	if (!options || !*options)
 		return 0;
 
-	while (this_opt = strsep(&options, ",")) {
+	while ((this_opt = strsep(&options, ","))) {
 		if (!*this_opt)
 			continue;
 		if (!strncmp(this_opt, "vra", 3)) {
diff -Nru a/sound/oss/au1550_ac97.c b/sound/oss/au1550_ac97.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/sound/oss/au1550_ac97.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,2119 @@
+/*
+ * au1550_ac97.c  --  Sound driver for Alchemy Au1550 MIPS Internet Edge
+ *                    Processor.
+ *
+ * Copyright 2004 Embedded Edge, LLC
+ *	dan@embeddededge.com
+ *
+ * Mostly copied from the au1000.c driver and some from the
+ * PowerMac dbdma driver.
+ * We assume the processor can do memory coherent DMA.
+ *
+ * Ported to 2.6 by Matt Porter <mporter@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.
+ *
+ *  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.
+ *
+ */
+
+#undef DEBUG
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/sound.h>
+#include <linux/slab.h>
+#include <linux/soundcard.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/poll.h>
+#include <linux/pci.h>
+#include <linux/bitops.h>
+#include <linux/spinlock.h>
+#include <linux/smp_lock.h>
+#include <linux/ac97_codec.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/hardirq.h>
+#include <asm/mach-au1x00/au1000.h>
+#include <asm/mach-au1x00/au1xxx_psc.h>
+#include <asm/mach-au1x00/au1xxx_dbdma.h>
+
+#undef OSS_DOCUMENTED_MIXER_SEMANTICS
+
+/* misc stuff */
+#define POLL_COUNT   0x50000
+#define AC97_EXT_DACS (AC97_EXTID_SDAC | AC97_EXTID_CDAC | AC97_EXTID_LDAC)
+
+/* The number of DBDMA ring descriptors to allocate.  No sense making
+ * this too large....if you can't keep up with a few you aren't likely
+ * to be able to with lots of them, either.
+ */
+#define NUM_DBDMA_DESCRIPTORS 4
+
+#define err(format, arg...) printk(KERN_ERR format "\n" , ## arg)
+
+/* Boot options
+ * 0 = no VRA, 1 = use VRA if codec supports it
+ */
+static int      vra = 1;
+MODULE_PARM(vra, "i");
+MODULE_PARM_DESC(vra, "if 1 use VRA if codec supports it");
+
+static struct au1550_state {
+	/* soundcore stuff */
+	int             dev_audio;
+
+	struct ac97_codec *codec;
+	unsigned        codec_base_caps; /* AC'97 reg 00h, "Reset Register" */
+	unsigned        codec_ext_caps;  /* AC'97 reg 28h, "Extended Audio ID" */
+	int             no_vra;		/* do not use VRA */
+
+	spinlock_t      lock;
+	struct semaphore open_sem;
+	struct semaphore sem;
+	mode_t          open_mode;
+	wait_queue_head_t open_wait;
+
+	struct dmabuf {
+		u32		dmanr;
+		unsigned        sample_rate;
+		unsigned	src_factor;
+		unsigned        sample_size;
+		int             num_channels;
+		int		dma_bytes_per_sample;
+		int		user_bytes_per_sample;
+		int		cnt_factor;
+
+		void		*rawbuf;
+		unsigned        buforder;
+		unsigned	numfrag;
+		unsigned        fragshift;
+		void		*nextIn;
+		void		*nextOut;
+		int		count;
+		unsigned        total_bytes;
+		unsigned        error;
+		wait_queue_head_t wait;
+
+		/* redundant, but makes calculations easier */
+		unsigned	fragsize;
+		unsigned	dma_fragsize;
+		unsigned	dmasize;
+		unsigned	dma_qcount;
+
+		/* OSS stuff */
+		unsigned        mapped:1;
+		unsigned        ready:1;
+		unsigned        stopped:1;
+		unsigned        ossfragshift;
+		int             ossmaxfrags;
+		unsigned        subdivision;
+	} dma_dac, dma_adc;
+} au1550_state;
+
+static unsigned
+ld2(unsigned int x)
+{
+	unsigned        r = 0;
+
+	if (x >= 0x10000) {
+		x >>= 16;
+		r += 16;
+	}
+	if (x >= 0x100) {
+		x >>= 8;
+		r += 8;
+	}
+	if (x >= 0x10) {
+		x >>= 4;
+		r += 4;
+	}
+	if (x >= 4) {
+		x >>= 2;
+		r += 2;
+	}
+	if (x >= 2)
+		r++;
+	return r;
+}
+
+static void
+au1550_delay(int msec)
+{
+	unsigned long   tmo;
+	signed long     tmo2;
+
+	if (in_interrupt())
+		return;
+
+	tmo = jiffies + (msec * HZ) / 1000;
+	for (;;) {
+		tmo2 = tmo - jiffies;
+		if (tmo2 <= 0)
+			break;
+		schedule_timeout(tmo2);
+	}
+}
+
+static u16
+rdcodec(struct ac97_codec *codec, u8 addr)
+{
+	struct au1550_state *s = (struct au1550_state *)codec->private_data;
+	unsigned long   flags;
+	u32             cmd, val;
+	u16             data;
+	int             i;
+
+	spin_lock_irqsave(&s->lock, flags);
+
+	for (i = 0; i < POLL_COUNT; i++) {
+		val = au_readl(PSC_AC97STAT);
+		au_sync();
+		if (!(val & PSC_AC97STAT_CP))
+			break;
+	}
+	if (i == POLL_COUNT)
+		err("rdcodec: codec cmd pending expired!");
+
+	cmd = (u32)PSC_AC97CDC_INDX(addr);
+	cmd |= PSC_AC97CDC_RD;	/* read command */
+	au_writel(cmd, PSC_AC97CDC);
+	au_sync();
+
+	/* now wait for the data
+	*/
+	for (i = 0; i < POLL_COUNT; i++) {
+		val = au_readl(PSC_AC97STAT);
+		au_sync();
+		if (!(val & PSC_AC97STAT_CP))
+			break;
+	}
+	if (i == POLL_COUNT) {
+		err("rdcodec: read poll expired!");
+		return 0;
+	}
+
+	/* wait for command done?
+	*/
+	for (i = 0; i < POLL_COUNT; i++) {
+		val = au_readl(PSC_AC97EVNT);
+		au_sync();
+		if (val & PSC_AC97EVNT_CD)
+			break;
+	}
+	if (i == POLL_COUNT) {
+		err("rdcodec: read cmdwait expired!");
+		return 0;
+	}
+
+	data = au_readl(PSC_AC97CDC) & 0xffff;
+	au_sync();
+
+	/* Clear command done event.
+	*/
+	au_writel(PSC_AC97EVNT_CD, PSC_AC97EVNT);
+	au_sync();
+
+	spin_unlock_irqrestore(&s->lock, flags);
+
+	return data;
+}
+
+
+static void
+wrcodec(struct ac97_codec *codec, u8 addr, u16 data)
+{
+	struct au1550_state *s = (struct au1550_state *)codec->private_data;
+	unsigned long   flags;
+	u32             cmd, val;
+	int             i;
+
+	spin_lock_irqsave(&s->lock, flags);
+
+	for (i = 0; i < POLL_COUNT; i++) {
+		val = au_readl(PSC_AC97STAT);
+		au_sync();
+		if (!(val & PSC_AC97STAT_CP))
+			break;
+	}
+	if (i == POLL_COUNT)
+		err("wrcodec: codec cmd pending expired!");
+
+	cmd = (u32)PSC_AC97CDC_INDX(addr);
+	cmd |= (u32)data;
+	au_writel(cmd, PSC_AC97CDC);
+	au_sync();
+
+	for (i = 0; i < POLL_COUNT; i++) {
+		val = au_readl(PSC_AC97STAT);
+		au_sync();
+		if (!(val & PSC_AC97STAT_CP))
+			break;
+	}
+	if (i == POLL_COUNT)
+		err("wrcodec: codec cmd pending expired!");
+
+	for (i = 0; i < POLL_COUNT; i++) {
+		val = au_readl(PSC_AC97EVNT);
+		au_sync();
+		if (val & PSC_AC97EVNT_CD)
+			break;
+	}
+	if (i == POLL_COUNT)
+		err("wrcodec: read cmdwait expired!");
+
+	/* Clear command done event.
+	*/
+	au_writel(PSC_AC97EVNT_CD, PSC_AC97EVNT);
+	au_sync();
+
+	spin_unlock_irqrestore(&s->lock, flags);
+}
+
+static void
+waitcodec(struct ac97_codec *codec)
+{
+	u16	temp;
+	u32	val;
+	int	i;
+
+	/* codec_wait is used to wait for a ready state after
+	 * an AC97C_RESET.
+	 */
+	au1550_delay(10);
+
+	/* first poll the CODEC_READY tag bit
+	*/
+	for (i = 0; i < POLL_COUNT; i++) {
+		val = au_readl(PSC_AC97STAT);
+		au_sync();
+		if (val & PSC_AC97STAT_CR)
+			break;
+	}
+	if (i == POLL_COUNT) {
+		err("waitcodec: CODEC_READY poll expired!");
+		return;
+	}
+
+	/* get AC'97 powerdown control/status register
+	*/
+	temp = rdcodec(codec, AC97_POWER_CONTROL);
+
+	/* If anything is powered down, power'em up
+	*/
+	if (temp & 0x7f00) {
+		/* Power on
+		*/
+		wrcodec(codec, AC97_POWER_CONTROL, 0);
+		au1550_delay(100);
+
+		/* Reread
+		*/
+		temp = rdcodec(codec, AC97_POWER_CONTROL);
+	}
+
+	/* Check if Codec REF,ANL,DAC,ADC ready
+	*/
+	if ((temp & 0x7f0f) != 0x000f)
+		err("codec reg 26 status (0x%x) not ready!!", temp);
+}
+
+/* stop the ADC before calling */
+static void
+set_adc_rate(struct au1550_state *s, unsigned rate)
+{
+	struct dmabuf  *adc = &s->dma_adc;
+	struct dmabuf  *dac = &s->dma_dac;
+	unsigned        adc_rate, dac_rate;
+	u16             ac97_extstat;
+
+	if (s->no_vra) {
+		/* calc SRC factor
+		*/
+		adc->src_factor = ((96000 / rate) + 1) >> 1;
+		adc->sample_rate = 48000 / adc->src_factor;
+		return;
+	}
+
+	adc->src_factor = 1;
+
+	ac97_extstat = rdcodec(s->codec, AC97_EXTENDED_STATUS);
+
+	rate = rate > 48000 ? 48000 : rate;
+
+	/* enable VRA
+	*/
+	wrcodec(s->codec, AC97_EXTENDED_STATUS,
+		ac97_extstat | AC97_EXTSTAT_VRA);
+
+	/* now write the sample rate
+	*/
+	wrcodec(s->codec, AC97_PCM_LR_ADC_RATE, (u16) rate);
+
+	/* read it back for actual supported rate
+	*/
+	adc_rate = rdcodec(s->codec, AC97_PCM_LR_ADC_RATE);
+
+	pr_debug("set_adc_rate: set to %d Hz\n", adc_rate);
+
+	/* some codec's don't allow unequal DAC and ADC rates, in which case
+	 * writing one rate reg actually changes both.
+	 */
+	dac_rate = rdcodec(s->codec, AC97_PCM_FRONT_DAC_RATE);
+	if (dac->num_channels > 2)
+		wrcodec(s->codec, AC97_PCM_SURR_DAC_RATE, dac_rate);
+	if (dac->num_channels > 4)
+		wrcodec(s->codec, AC97_PCM_LFE_DAC_RATE, dac_rate);
+
+	adc->sample_rate = adc_rate;
+	dac->sample_rate = dac_rate;
+}
+
+/* stop the DAC before calling */
+static void
+set_dac_rate(struct au1550_state *s, unsigned rate)
+{
+	struct dmabuf  *dac = &s->dma_dac;
+	struct dmabuf  *adc = &s->dma_adc;
+	unsigned        adc_rate, dac_rate;
+	u16             ac97_extstat;
+
+	if (s->no_vra) {
+		/* calc SRC factor
+		*/
+		dac->src_factor = ((96000 / rate) + 1) >> 1;
+		dac->sample_rate = 48000 / dac->src_factor;
+		return;
+	}
+
+	dac->src_factor = 1;
+
+	ac97_extstat = rdcodec(s->codec, AC97_EXTENDED_STATUS);
+
+	rate = rate > 48000 ? 48000 : rate;
+
+	/* enable VRA
+	*/
+	wrcodec(s->codec, AC97_EXTENDED_STATUS,
+		ac97_extstat | AC97_EXTSTAT_VRA);
+
+	/* now write the sample rate
+	*/
+	wrcodec(s->codec, AC97_PCM_FRONT_DAC_RATE, (u16) rate);
+
+	/* I don't support different sample rates for multichannel,
+	 * so make these channels the same.
+	 */
+	if (dac->num_channels > 2)
+		wrcodec(s->codec, AC97_PCM_SURR_DAC_RATE, (u16) rate);
+	if (dac->num_channels > 4)
+		wrcodec(s->codec, AC97_PCM_LFE_DAC_RATE, (u16) rate);
+	/* read it back for actual supported rate
+	*/
+	dac_rate = rdcodec(s->codec, AC97_PCM_FRONT_DAC_RATE);
+
+	pr_debug("set_dac_rate: set to %d Hz\n", dac_rate);
+
+	/* some codec's don't allow unequal DAC and ADC rates, in which case
+	 * writing one rate reg actually changes both.
+	 */
+	adc_rate = rdcodec(s->codec, AC97_PCM_LR_ADC_RATE);
+
+	dac->sample_rate = dac_rate;
+	adc->sample_rate = adc_rate;
+}
+
+static void
+stop_dac(struct au1550_state *s)
+{
+	struct dmabuf  *db = &s->dma_dac;
+	u32		stat;
+	unsigned long   flags;
+
+	if (db->stopped)
+		return;
+
+	spin_lock_irqsave(&s->lock, flags);
+
+	au_writel(PSC_AC97PCR_TP, PSC_AC97PCR);
+	au_sync();
+
+	/* Wait for Transmit Busy to show disabled.
+	*/
+	do {
+		stat = readl((void *)PSC_AC97STAT);
+		au_sync();
+	} while ((stat & PSC_AC97STAT_TB) != 0);
+
+	au1xxx_dbdma_reset(db->dmanr);
+
+	db->stopped = 1;
+
+	spin_unlock_irqrestore(&s->lock, flags);
+}
+
+static void
+stop_adc(struct au1550_state *s)
+{
+	struct dmabuf  *db = &s->dma_adc;
+	unsigned long   flags;
+	u32		stat;
+
+	if (db->stopped)
+		return;
+
+	spin_lock_irqsave(&s->lock, flags);
+
+	au_writel(PSC_AC97PCR_RP, PSC_AC97PCR);
+	au_sync();
+
+	/* Wait for Receive Busy to show disabled.
+	*/
+	do {
+		stat = readl((void *)PSC_AC97STAT);
+		au_sync();
+	} while ((stat & PSC_AC97STAT_RB) != 0);
+
+	au1xxx_dbdma_reset(db->dmanr);
+
+	db->stopped = 1;
+
+	spin_unlock_irqrestore(&s->lock, flags);
+}
+
+
+static void
+set_xmit_slots(int num_channels)
+{
+	u32	ac97_config, stat;
+
+	ac97_config = au_readl(PSC_AC97CFG);
+	au_sync();
+	ac97_config &= ~(PSC_AC97CFG_TXSLOT_MASK | PSC_AC97CFG_DE_ENABLE);
+	au_writel(ac97_config, PSC_AC97CFG);
+	au_sync();
+
+	switch (num_channels) {
+	case 6:		/* stereo with surround and center/LFE,
+			 * slots 3,4,6,7,8,9
+			 */
+		ac97_config |= PSC_AC97CFG_TXSLOT_ENA(6);
+		ac97_config |= PSC_AC97CFG_TXSLOT_ENA(9);
+
+	case 4:		/* stereo with surround, slots 3,4,7,8 */
+		ac97_config |= PSC_AC97CFG_TXSLOT_ENA(7);
+		ac97_config |= PSC_AC97CFG_TXSLOT_ENA(8);
+
+	case 2:		/* stereo, slots 3,4 */
+	case 1:		/* mono */
+		ac97_config |= PSC_AC97CFG_TXSLOT_ENA(3);
+		ac97_config |= PSC_AC97CFG_TXSLOT_ENA(4);
+	}
+
+	au_writel(ac97_config, PSC_AC97CFG);
+	au_sync();
+
+	ac97_config |= PSC_AC97CFG_DE_ENABLE;
+	au_writel(ac97_config, PSC_AC97CFG);
+	au_sync();
+
+	/* Wait for Device ready.
+	*/
+	do {
+		stat = readl((void *)PSC_AC97STAT);
+		au_sync();
+	} while ((stat & PSC_AC97STAT_DR) == 0);
+}
+
+static void
+set_recv_slots(int num_channels)
+{
+	u32	ac97_config, stat;
+
+	ac97_config = au_readl(PSC_AC97CFG);
+	au_sync();
+	ac97_config &= ~(PSC_AC97CFG_RXSLOT_MASK | PSC_AC97CFG_DE_ENABLE);
+	au_writel(ac97_config, PSC_AC97CFG);
+	au_sync();
+
+	/* Always enable slots 3 and 4 (stereo). Slot 6 is
+	 * optional Mic ADC, which we don't support yet.
+	 */
+	ac97_config |= PSC_AC97CFG_RXSLOT_ENA(3);
+	ac97_config |= PSC_AC97CFG_RXSLOT_ENA(4);
+
+	au_writel(ac97_config, PSC_AC97CFG);
+	au_sync();
+
+	ac97_config |= PSC_AC97CFG_DE_ENABLE;
+	au_writel(ac97_config, PSC_AC97CFG);
+	au_sync();
+
+	/* Wait for Device ready.
+	*/
+	do {
+		stat = readl((void *)PSC_AC97STAT);
+		au_sync();
+	} while ((stat & PSC_AC97STAT_DR) == 0);
+}
+
+static void
+start_dac(struct au1550_state *s)
+{
+	struct dmabuf  *db = &s->dma_dac;
+	unsigned long   flags;
+
+	if (!db->stopped)
+		return;
+
+	spin_lock_irqsave(&s->lock, flags);
+
+	set_xmit_slots(db->num_channels);
+	au_writel(PSC_AC97PCR_TC, PSC_AC97PCR);
+	au_sync();
+	au_writel(PSC_AC97PCR_TS, PSC_AC97PCR);
+	au_sync();
+
+	au1xxx_dbdma_start(db->dmanr);
+
+	db->stopped = 0;
+
+	spin_unlock_irqrestore(&s->lock, flags);
+}
+
+static void
+start_adc(struct au1550_state *s)
+{
+	struct dmabuf  *db = &s->dma_adc;
+	int	i;
+
+	if (!db->stopped)
+		return;
+
+	/* Put two buffers on the ring to get things started.
+	*/
+	for (i=0; i<2; i++) {
+		au1xxx_dbdma_put_dest(db->dmanr, db->nextIn, db->dma_fragsize);
+
+		db->nextIn += db->dma_fragsize;
+		if (db->nextIn >= db->rawbuf + db->dmasize)
+			db->nextIn -= db->dmasize;
+	}
+
+	set_recv_slots(db->num_channels);
+	au1xxx_dbdma_start(db->dmanr);
+	au_writel(PSC_AC97PCR_RC, PSC_AC97PCR);
+	au_sync();
+	au_writel(PSC_AC97PCR_RS, PSC_AC97PCR);
+	au_sync();
+
+	db->stopped = 0;
+}
+
+static int
+prog_dmabuf(struct au1550_state *s, struct dmabuf *db)
+{
+	unsigned user_bytes_per_sec;
+	unsigned        bufs;
+	unsigned        rate = db->sample_rate;
+
+	if (!db->rawbuf) {
+		db->ready = db->mapped = 0;
+		db->buforder = 5;	/* 32 * PAGE_SIZE */
+		db->rawbuf = kmalloc((PAGE_SIZE << db->buforder), GFP_KERNEL);
+		if (!db->rawbuf)
+			return -ENOMEM;
+	}
+
+	db->cnt_factor = 1;
+	if (db->sample_size == 8)
+		db->cnt_factor *= 2;
+	if (db->num_channels == 1)
+		db->cnt_factor *= 2;
+	db->cnt_factor *= db->src_factor;
+
+	db->count = 0;
+	db->dma_qcount = 0;
+	db->nextIn = db->nextOut = db->rawbuf;
+
+	db->user_bytes_per_sample = (db->sample_size>>3) * db->num_channels;
+	db->dma_bytes_per_sample = 2 * ((db->num_channels == 1) ?
+					2 : db->num_channels);
+
+	user_bytes_per_sec = rate * db->user_bytes_per_sample;
+	bufs = PAGE_SIZE << db->buforder;
+	if (db->ossfragshift) {
+		if ((1000 << db->ossfragshift) < user_bytes_per_sec)
+			db->fragshift = ld2(user_bytes_per_sec/1000);
+		else
+			db->fragshift = db->ossfragshift;
+	} else {
+		db->fragshift = ld2(user_bytes_per_sec / 100 /
+				    (db->subdivision ? db->subdivision : 1));
+		if (db->fragshift < 3)
+			db->fragshift = 3;
+	}
+
+	db->fragsize = 1 << db->fragshift;
+	db->dma_fragsize = db->fragsize * db->cnt_factor;
+	db->numfrag = bufs / db->dma_fragsize;
+
+	while (db->numfrag < 4 && db->fragshift > 3) {
+		db->fragshift--;
+		db->fragsize = 1 << db->fragshift;
+		db->dma_fragsize = db->fragsize * db->cnt_factor;
+		db->numfrag = bufs / db->dma_fragsize;
+	}
+
+	if (db->ossmaxfrags >= 4 && db->ossmaxfrags < db->numfrag)
+		db->numfrag = db->ossmaxfrags;
+
+	db->dmasize = db->dma_fragsize * db->numfrag;
+	memset(db->rawbuf, 0, bufs);
+
+	pr_debug("prog_dmabuf: rate=%d, samplesize=%d, channels=%d\n",
+	    rate, db->sample_size, db->num_channels);
+	pr_debug("prog_dmabuf: fragsize=%d, cnt_factor=%d, dma_fragsize=%d\n",
+	    db->fragsize, db->cnt_factor, db->dma_fragsize);
+	pr_debug("prog_dmabuf: numfrag=%d, dmasize=%d\n", db->numfrag, db->dmasize);
+
+	db->ready = 1;
+	return 0;
+}
+
+static int
+prog_dmabuf_adc(struct au1550_state *s)
+{
+	stop_adc(s);
+	return prog_dmabuf(s, &s->dma_adc);
+
+}
+
+static int
+prog_dmabuf_dac(struct au1550_state *s)
+{
+	stop_dac(s);
+	return prog_dmabuf(s, &s->dma_dac);
+}
+
+
+/* hold spinlock for the following */
+static void
+dac_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct au1550_state *s = (struct au1550_state *) dev_id;
+	struct dmabuf  *db = &s->dma_dac;
+	u32	ac97c_stat;
+
+	ac97c_stat = au_readl(PSC_AC97STAT);
+	if (ac97c_stat & (AC97C_XU | AC97C_XO | AC97C_TE))
+		pr_debug("AC97C status = 0x%08x\n", ac97c_stat);
+	db->dma_qcount--;
+
+	if (db->count >= db->fragsize) {
+		if (au1xxx_dbdma_put_source(db->dmanr, db->nextOut,
+							db->fragsize) == 0) {
+			err("qcount < 2 and no ring room!");
+		}
+		db->nextOut += db->fragsize;
+		if (db->nextOut >= db->rawbuf + db->dmasize)
+			db->nextOut -= db->dmasize;
+		db->count -= db->fragsize;
+		db->total_bytes += db->dma_fragsize;
+		db->dma_qcount++;
+	}
+
+	/* wake up anybody listening */
+	if (waitqueue_active(&db->wait))
+		wake_up(&db->wait);
+}
+
+
+static void
+adc_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct	au1550_state *s = (struct au1550_state *)dev_id;
+	struct	dmabuf  *dp = &s->dma_adc;
+	u32	obytes;
+	char	*obuf;
+
+	/* Pull the buffer from the dma queue.
+	*/
+	au1xxx_dbdma_get_dest(dp->dmanr, (void *)(&obuf), &obytes);
+
+	if ((dp->count + obytes) > dp->dmasize) {
+		/* Overrun. Stop ADC and log the error
+		*/
+		stop_adc(s);
+		dp->error++;
+		err("adc overrun");
+		return;
+	}
+
+	/* Put a new empty buffer on the destination DMA.
+	*/
+	au1xxx_dbdma_put_dest(dp->dmanr, dp->nextIn, dp->dma_fragsize);
+
+	dp->nextIn += dp->dma_fragsize;
+	if (dp->nextIn >= dp->rawbuf + dp->dmasize)
+		dp->nextIn -= dp->dmasize;
+
+	dp->count += obytes;
+	dp->total_bytes += obytes;
+
+	/* wake up anybody listening
+	*/
+	if (waitqueue_active(&dp->wait))
+		wake_up(&dp->wait);
+
+}
+
+static loff_t
+au1550_llseek(struct file *file, loff_t offset, int origin)
+{
+	return -ESPIPE;
+}
+
+
+static int
+au1550_open_mixdev(struct inode *inode, struct file *file)
+{
+	file->private_data = &au1550_state;
+	return 0;
+}
+
+static int
+au1550_release_mixdev(struct inode *inode, struct file *file)
+{
+	return 0;
+}
+
+static int
+mixdev_ioctl(struct ac97_codec *codec, unsigned int cmd,
+                        unsigned long arg)
+{
+	return codec->mixer_ioctl(codec, cmd, arg);
+}
+
+static int
+au1550_ioctl_mixdev(struct inode *inode, struct file *file,
+			       unsigned int cmd, unsigned long arg)
+{
+	struct au1550_state *s = (struct au1550_state *)file->private_data;
+	struct ac97_codec *codec = s->codec;
+
+	return mixdev_ioctl(codec, cmd, arg);
+}
+
+static /*const */ struct file_operations au1550_mixer_fops = {
+	owner:THIS_MODULE,
+	llseek:au1550_llseek,
+	ioctl:au1550_ioctl_mixdev,
+	open:au1550_open_mixdev,
+	release:au1550_release_mixdev,
+};
+
+static int
+drain_dac(struct au1550_state *s, int nonblock)
+{
+	unsigned long   flags;
+	int             count, tmo;
+
+	if (s->dma_dac.mapped || !s->dma_dac.ready || s->dma_dac.stopped)
+		return 0;
+
+	for (;;) {
+		spin_lock_irqsave(&s->lock, flags);
+		count = s->dma_dac.count;
+		spin_unlock_irqrestore(&s->lock, flags);
+		if (count <= s->dma_dac.fragsize)
+			break;
+		if (signal_pending(current))
+			break;
+		if (nonblock)
+			return -EBUSY;
+		tmo = 1000 * count / (s->no_vra ?
+				      48000 : s->dma_dac.sample_rate);
+		tmo /= s->dma_dac.dma_bytes_per_sample;
+		au1550_delay(tmo);
+	}
+	if (signal_pending(current))
+		return -ERESTARTSYS;
+	return 0;
+}
+
+static inline u8 S16_TO_U8(s16 ch)
+{
+	return (u8) (ch >> 8) + 0x80;
+}
+static inline s16 U8_TO_S16(u8 ch)
+{
+	return (s16) (ch - 0x80) << 8;
+}
+
+/*
+ * Translates user samples to dma buffer suitable for AC'97 DAC data:
+ *     If mono, copy left channel to right channel in dma buffer.
+ *     If 8 bit samples, cvt to 16-bit before writing to dma buffer.
+ *     If interpolating (no VRA), duplicate every audio frame src_factor times.
+ */
+static int
+translate_from_user(struct dmabuf *db, char* dmabuf, char* userbuf,
+							       int dmacount)
+{
+	int             sample, i;
+	int             interp_bytes_per_sample;
+	int             num_samples;
+	int             mono = (db->num_channels == 1);
+	char            usersample[12];
+	s16             ch, dmasample[6];
+
+	if (db->sample_size == 16 && !mono && db->src_factor == 1) {
+		/* no translation necessary, just copy
+		*/
+		if (copy_from_user(dmabuf, userbuf, dmacount))
+			return -EFAULT;
+		return dmacount;
+	}
+
+	interp_bytes_per_sample = db->dma_bytes_per_sample * db->src_factor;
+	num_samples = dmacount / interp_bytes_per_sample;
+
+	for (sample = 0; sample < num_samples; sample++) {
+		if (copy_from_user(usersample, userbuf,
+				   db->user_bytes_per_sample)) {
+			return -EFAULT;
+		}
+
+		for (i = 0; i < db->num_channels; i++) {
+			if (db->sample_size == 8)
+				ch = U8_TO_S16(usersample[i]);
+			else
+				ch = *((s16 *) (&usersample[i * 2]));
+			dmasample[i] = ch;
+			if (mono)
+				dmasample[i + 1] = ch;	/* right channel */
+		}
+
+		/* duplicate every audio frame src_factor times
+		*/
+		for (i = 0; i < db->src_factor; i++)
+			memcpy(dmabuf, dmasample, db->dma_bytes_per_sample);
+
+		userbuf += db->user_bytes_per_sample;
+		dmabuf += interp_bytes_per_sample;
+	}
+
+	return num_samples * interp_bytes_per_sample;
+}
+
+/*
+ * Translates AC'97 ADC samples to user buffer:
+ *     If mono, send only left channel to user buffer.
+ *     If 8 bit samples, cvt from 16 to 8 bit before writing to user buffer.
+ *     If decimating (no VRA), skip over src_factor audio frames.
+ */
+static int
+translate_to_user(struct dmabuf *db, char* userbuf, char* dmabuf,
+							     int dmacount)
+{
+	int             sample, i;
+	int             interp_bytes_per_sample;
+	int             num_samples;
+	int             mono = (db->num_channels == 1);
+	char            usersample[12];
+
+	if (db->sample_size == 16 && !mono && db->src_factor == 1) {
+		/* no translation necessary, just copy
+		*/
+		if (copy_to_user(userbuf, dmabuf, dmacount))
+			return -EFAULT;
+		return dmacount;
+	}
+
+	interp_bytes_per_sample = db->dma_bytes_per_sample * db->src_factor;
+	num_samples = dmacount / interp_bytes_per_sample;
+
+	for (sample = 0; sample < num_samples; sample++) {
+		for (i = 0; i < db->num_channels; i++) {
+			if (db->sample_size == 8)
+				usersample[i] =
+					S16_TO_U8(*((s16 *) (&dmabuf[i * 2])));
+			else
+				*((s16 *) (&usersample[i * 2])) =
+					*((s16 *) (&dmabuf[i * 2]));
+		}
+
+		if (copy_to_user(userbuf, usersample,
+				 db->user_bytes_per_sample)) {
+			return -EFAULT;
+		}
+
+		userbuf += db->user_bytes_per_sample;
+		dmabuf += interp_bytes_per_sample;
+	}
+
+	return num_samples * interp_bytes_per_sample;
+}
+
+/*
+ * Copy audio data to/from user buffer from/to dma buffer, taking care
+ * that we wrap when reading/writing the dma buffer. Returns actual byte
+ * count written to or read from the dma buffer.
+ */
+static int
+copy_dmabuf_user(struct dmabuf *db, char* userbuf, int count, int to_user)
+{
+	char           *bufptr = to_user ? db->nextOut : db->nextIn;
+	char           *bufend = db->rawbuf + db->dmasize;
+	int             cnt, ret;
+
+	if (bufptr + count > bufend) {
+		int             partial = (int) (bufend - bufptr);
+		if (to_user) {
+			if ((cnt = translate_to_user(db, userbuf,
+						     bufptr, partial)) < 0)
+				return cnt;
+			ret = cnt;
+			if ((cnt = translate_to_user(db, userbuf + partial,
+						     db->rawbuf,
+						     count - partial)) < 0)
+				return cnt;
+			ret += cnt;
+		} else {
+			if ((cnt = translate_from_user(db, bufptr, userbuf,
+						       partial)) < 0)
+				return cnt;
+			ret = cnt;
+			if ((cnt = translate_from_user(db, db->rawbuf,
+						       userbuf + partial,
+						       count - partial)) < 0)
+				return cnt;
+			ret += cnt;
+		}
+	} else {
+		if (to_user)
+			ret = translate_to_user(db, userbuf, bufptr, count);
+		else
+			ret = translate_from_user(db, bufptr, userbuf, count);
+	}
+
+	return ret;
+}
+
+
+static ssize_t
+au1550_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
+{
+	struct au1550_state *s = (struct au1550_state *)file->private_data;
+	struct dmabuf  *db = &s->dma_adc;
+	DECLARE_WAITQUEUE(wait, current);
+	ssize_t         ret;
+	unsigned long   flags;
+	int             cnt, usercnt, avail;
+
+	if (db->mapped)
+		return -ENXIO;
+	if (!access_ok(VERIFY_WRITE, buffer, count))
+		return -EFAULT;
+	ret = 0;
+
+	count *= db->cnt_factor;
+
+	down(&s->sem);
+	add_wait_queue(&db->wait, &wait);
+
+	while (count > 0) {
+		/* wait for samples in ADC dma buffer
+		*/
+		do {
+			if (db->stopped)
+				start_adc(s);
+			spin_lock_irqsave(&s->lock, flags);
+			avail = db->count;
+			if (avail <= 0)
+				__set_current_state(TASK_INTERRUPTIBLE);
+			spin_unlock_irqrestore(&s->lock, flags);
+			if (avail <= 0) {
+				if (file->f_flags & O_NONBLOCK) {
+					if (!ret)
+						ret = -EAGAIN;
+					goto out;
+				}
+				up(&s->sem);
+				schedule();
+				if (signal_pending(current)) {
+					if (!ret)
+						ret = -ERESTARTSYS;
+					goto out2;
+				}
+				down(&s->sem);
+			}
+		} while (avail <= 0);
+
+		/* copy from nextOut to user
+		*/
+		if ((cnt = copy_dmabuf_user(db, buffer,
+					    count > avail ?
+					    avail : count, 1)) < 0) {
+			if (!ret)
+				ret = -EFAULT;
+			goto out;
+		}
+
+		spin_lock_irqsave(&s->lock, flags);
+		db->count -= cnt;
+		db->nextOut += cnt;
+		if (db->nextOut >= db->rawbuf + db->dmasize)
+			db->nextOut -= db->dmasize;
+		spin_unlock_irqrestore(&s->lock, flags);
+
+		count -= cnt;
+		usercnt = cnt / db->cnt_factor;
+		buffer += usercnt;
+		ret += usercnt;
+	}			/* while (count > 0) */
+
+out:
+	up(&s->sem);
+out2:
+	remove_wait_queue(&db->wait, &wait);
+	set_current_state(TASK_RUNNING);
+	return ret;
+}
+
+static ssize_t
+au1550_write(struct file *file, const char *buffer, size_t count, loff_t * ppos)
+{
+	struct au1550_state *s = (struct au1550_state *)file->private_data;
+	struct dmabuf  *db = &s->dma_dac;
+	DECLARE_WAITQUEUE(wait, current);
+	ssize_t         ret = 0;
+	unsigned long   flags;
+	int             cnt, usercnt, avail;
+
+	pr_debug("write: count=%d\n", count);
+
+	if (db->mapped)
+		return -ENXIO;
+	if (!access_ok(VERIFY_READ, buffer, count))
+		return -EFAULT;
+
+	count *= db->cnt_factor;
+
+	down(&s->sem);
+	add_wait_queue(&db->wait, &wait);
+
+	while (count > 0) {
+		/* wait for space in playback buffer
+		*/
+		do {
+			spin_lock_irqsave(&s->lock, flags);
+			avail = (int) db->dmasize - db->count;
+			if (avail <= 0)
+				__set_current_state(TASK_INTERRUPTIBLE);
+			spin_unlock_irqrestore(&s->lock, flags);
+			if (avail <= 0) {
+				if (file->f_flags & O_NONBLOCK) {
+					if (!ret)
+						ret = -EAGAIN;
+					goto out;
+				}
+				up(&s->sem);
+				schedule();
+				if (signal_pending(current)) {
+					if (!ret)
+						ret = -ERESTARTSYS;
+					goto out2;
+				}
+				down(&s->sem);
+			}
+		} while (avail <= 0);
+
+		/* copy from user to nextIn
+		*/
+		if ((cnt = copy_dmabuf_user(db, (char *) buffer,
+					    count > avail ?
+					    avail : count, 0)) < 0) {
+			if (!ret)
+				ret = -EFAULT;
+			goto out;
+		}
+
+		spin_lock_irqsave(&s->lock, flags);
+		db->count += cnt;
+		db->nextIn += cnt;
+		if (db->nextIn >= db->rawbuf + db->dmasize)
+			db->nextIn -= db->dmasize;
+
+		/* If the data is available, we want to keep two buffers
+		 * on the dma queue.  If the queue count reaches zero,
+		 * we know the dma has stopped.
+		 */
+		while ((db->dma_qcount < 2) && (db->count >= db->fragsize)) {
+			if (au1xxx_dbdma_put_source(db->dmanr, db->nextOut,
+							db->fragsize) == 0) {
+				err("qcount < 2 and no ring room!");
+			}
+			db->nextOut += db->fragsize;
+			if (db->nextOut >= db->rawbuf + db->dmasize)
+				db->nextOut -= db->dmasize;
+			db->total_bytes += db->dma_fragsize;
+			if (db->dma_qcount == 0)
+				start_dac(s);
+			db->dma_qcount++;
+		}
+		spin_unlock_irqrestore(&s->lock, flags);
+
+		count -= cnt;
+		usercnt = cnt / db->cnt_factor;
+		buffer += usercnt;
+		ret += usercnt;
+	}			/* while (count > 0) */
+
+out:
+	up(&s->sem);
+out2:
+	remove_wait_queue(&db->wait, &wait);
+	set_current_state(TASK_RUNNING);
+	return ret;
+}
+
+
+/* No kernel lock - we have our own spinlock */
+static unsigned int
+au1550_poll(struct file *file, struct poll_table_struct *wait)
+{
+	struct au1550_state *s = (struct au1550_state *)file->private_data;
+	unsigned long   flags;
+	unsigned int    mask = 0;
+
+	if (file->f_mode & FMODE_WRITE) {
+		if (!s->dma_dac.ready)
+			return 0;
+		poll_wait(file, &s->dma_dac.wait, wait);
+	}
+	if (file->f_mode & FMODE_READ) {
+		if (!s->dma_adc.ready)
+			return 0;
+		poll_wait(file, &s->dma_adc.wait, wait);
+	}
+
+	spin_lock_irqsave(&s->lock, flags);
+
+	if (file->f_mode & FMODE_READ) {
+		if (s->dma_adc.count >= (signed)s->dma_adc.dma_fragsize)
+			mask |= POLLIN | POLLRDNORM;
+	}
+	if (file->f_mode & FMODE_WRITE) {
+		if (s->dma_dac.mapped) {
+			if (s->dma_dac.count >=
+			    (signed)s->dma_dac.dma_fragsize)
+				mask |= POLLOUT | POLLWRNORM;
+		} else {
+			if ((signed) s->dma_dac.dmasize >=
+			    s->dma_dac.count + (signed)s->dma_dac.dma_fragsize)
+				mask |= POLLOUT | POLLWRNORM;
+		}
+	}
+	spin_unlock_irqrestore(&s->lock, flags);
+	return mask;
+}
+
+static int
+au1550_mmap(struct file *file, struct vm_area_struct *vma)
+{
+	struct au1550_state *s = (struct au1550_state *)file->private_data;
+	struct dmabuf  *db;
+	unsigned long   size;
+	int ret = 0;
+
+	lock_kernel();
+	down(&s->sem);
+	if (vma->vm_flags & VM_WRITE)
+		db = &s->dma_dac;
+	else if (vma->vm_flags & VM_READ)
+		db = &s->dma_adc;
+	else {
+		ret = -EINVAL;
+		goto out;
+	}
+	if (vma->vm_pgoff != 0) {
+		ret = -EINVAL;
+		goto out;
+	}
+	size = vma->vm_end - vma->vm_start;
+	if (size > (PAGE_SIZE << db->buforder)) {
+		ret = -EINVAL;
+		goto out;
+	}
+	if (remap_pfn_range(vma, vma->vm_start, page_to_pfn(virt_to_page(db->rawbuf)),
+			     size, vma->vm_page_prot)) {
+		ret = -EAGAIN;
+		goto out;
+	}
+	vma->vm_flags &= ~VM_IO;
+	db->mapped = 1;
+out:
+	up(&s->sem);
+	unlock_kernel();
+	return ret;
+}
+
+#ifdef DEBUG
+static struct ioctl_str_t {
+	unsigned int    cmd;
+	const char     *str;
+} ioctl_str[] = {
+	{SNDCTL_DSP_RESET, "SNDCTL_DSP_RESET"},
+	{SNDCTL_DSP_SYNC, "SNDCTL_DSP_SYNC"},
+	{SNDCTL_DSP_SPEED, "SNDCTL_DSP_SPEED"},
+	{SNDCTL_DSP_STEREO, "SNDCTL_DSP_STEREO"},
+	{SNDCTL_DSP_GETBLKSIZE, "SNDCTL_DSP_GETBLKSIZE"},
+	{SNDCTL_DSP_SAMPLESIZE, "SNDCTL_DSP_SAMPLESIZE"},
+	{SNDCTL_DSP_CHANNELS, "SNDCTL_DSP_CHANNELS"},
+	{SOUND_PCM_WRITE_CHANNELS, "SOUND_PCM_WRITE_CHANNELS"},
+	{SOUND_PCM_WRITE_FILTER, "SOUND_PCM_WRITE_FILTER"},
+	{SNDCTL_DSP_POST, "SNDCTL_DSP_POST"},
+	{SNDCTL_DSP_SUBDIVIDE, "SNDCTL_DSP_SUBDIVIDE"},
+	{SNDCTL_DSP_SETFRAGMENT, "SNDCTL_DSP_SETFRAGMENT"},
+	{SNDCTL_DSP_GETFMTS, "SNDCTL_DSP_GETFMTS"},
+	{SNDCTL_DSP_SETFMT, "SNDCTL_DSP_SETFMT"},
+	{SNDCTL_DSP_GETOSPACE, "SNDCTL_DSP_GETOSPACE"},
+	{SNDCTL_DSP_GETISPACE, "SNDCTL_DSP_GETISPACE"},
+	{SNDCTL_DSP_NONBLOCK, "SNDCTL_DSP_NONBLOCK"},
+	{SNDCTL_DSP_GETCAPS, "SNDCTL_DSP_GETCAPS"},
+	{SNDCTL_DSP_GETTRIGGER, "SNDCTL_DSP_GETTRIGGER"},
+	{SNDCTL_DSP_SETTRIGGER, "SNDCTL_DSP_SETTRIGGER"},
+	{SNDCTL_DSP_GETIPTR, "SNDCTL_DSP_GETIPTR"},
+	{SNDCTL_DSP_GETOPTR, "SNDCTL_DSP_GETOPTR"},
+	{SNDCTL_DSP_MAPINBUF, "SNDCTL_DSP_MAPINBUF"},
+	{SNDCTL_DSP_MAPOUTBUF, "SNDCTL_DSP_MAPOUTBUF"},
+	{SNDCTL_DSP_SETSYNCRO, "SNDCTL_DSP_SETSYNCRO"},
+	{SNDCTL_DSP_SETDUPLEX, "SNDCTL_DSP_SETDUPLEX"},
+	{SNDCTL_DSP_GETODELAY, "SNDCTL_DSP_GETODELAY"},
+	{SNDCTL_DSP_GETCHANNELMASK, "SNDCTL_DSP_GETCHANNELMASK"},
+	{SNDCTL_DSP_BIND_CHANNEL, "SNDCTL_DSP_BIND_CHANNEL"},
+	{OSS_GETVERSION, "OSS_GETVERSION"},
+	{SOUND_PCM_READ_RATE, "SOUND_PCM_READ_RATE"},
+	{SOUND_PCM_READ_CHANNELS, "SOUND_PCM_READ_CHANNELS"},
+	{SOUND_PCM_READ_BITS, "SOUND_PCM_READ_BITS"},
+	{SOUND_PCM_READ_FILTER, "SOUND_PCM_READ_FILTER"}
+};
+#endif
+
+static int
+dma_count_done(struct dmabuf *db)
+{
+	if (db->stopped)
+		return 0;
+
+	return db->dma_fragsize - au1xxx_get_dma_residue(db->dmanr);
+}
+
+
+static int
+au1550_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+							unsigned long arg)
+{
+	struct au1550_state *s = (struct au1550_state *)file->private_data;
+	unsigned long   flags;
+	audio_buf_info  abinfo;
+	count_info      cinfo;
+	int             count;
+	int             val, mapped, ret, diff;
+
+	mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac.mapped) ||
+		((file->f_mode & FMODE_READ) && s->dma_adc.mapped);
+
+#ifdef DEBUG
+	for (count=0; count<sizeof(ioctl_str)/sizeof(ioctl_str[0]); count++) {
+		if (ioctl_str[count].cmd == cmd)
+			break;
+	}
+	if (count < sizeof(ioctl_str) / sizeof(ioctl_str[0]))
+		pr_debug("ioctl %s, arg=0x%lxn", ioctl_str[count].str, arg);
+	else
+		pr_debug("ioctl 0x%x unknown, arg=0x%lx\n", cmd, arg);
+#endif
+
+	switch (cmd) {
+	case OSS_GETVERSION:
+		return put_user(SOUND_VERSION, (int *) arg);
+
+	case SNDCTL_DSP_SYNC:
+		if (file->f_mode & FMODE_WRITE)
+			return drain_dac(s, file->f_flags & O_NONBLOCK);
+		return 0;
+
+	case SNDCTL_DSP_SETDUPLEX:
+		return 0;
+
+	case SNDCTL_DSP_GETCAPS:
+		return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME |
+				DSP_CAP_TRIGGER | DSP_CAP_MMAP, (int *)arg);
+
+	case SNDCTL_DSP_RESET:
+		if (file->f_mode & FMODE_WRITE) {
+			stop_dac(s);
+			synchronize_irq();
+			s->dma_dac.count = s->dma_dac.total_bytes = 0;
+			s->dma_dac.nextIn = s->dma_dac.nextOut =
+				s->dma_dac.rawbuf;
+		}
+		if (file->f_mode & FMODE_READ) {
+			stop_adc(s);
+			synchronize_irq();
+			s->dma_adc.count = s->dma_adc.total_bytes = 0;
+			s->dma_adc.nextIn = s->dma_adc.nextOut =
+				s->dma_adc.rawbuf;
+		}
+		return 0;
+
+	case SNDCTL_DSP_SPEED:
+		if (get_user(val, (int *) arg))
+			return -EFAULT;
+		if (val >= 0) {
+			if (file->f_mode & FMODE_READ) {
+				stop_adc(s);
+				set_adc_rate(s, val);
+			}
+			if (file->f_mode & FMODE_WRITE) {
+				stop_dac(s);
+				set_dac_rate(s, val);
+			}
+			if (s->open_mode & FMODE_READ)
+				if ((ret = prog_dmabuf_adc(s)))
+					return ret;
+			if (s->open_mode & FMODE_WRITE)
+				if ((ret = prog_dmabuf_dac(s)))
+					return ret;
+		}
+		return put_user((file->f_mode & FMODE_READ) ?
+				s->dma_adc.sample_rate :
+				s->dma_dac.sample_rate,
+				(int *)arg);
+
+	case SNDCTL_DSP_STEREO:
+		if (get_user(val, (int *) arg))
+			return -EFAULT;
+		if (file->f_mode & FMODE_READ) {
+			stop_adc(s);
+			s->dma_adc.num_channels = val ? 2 : 1;
+			if ((ret = prog_dmabuf_adc(s)))
+				return ret;
+		}
+		if (file->f_mode & FMODE_WRITE) {
+			stop_dac(s);
+			s->dma_dac.num_channels = val ? 2 : 1;
+			if (s->codec_ext_caps & AC97_EXT_DACS) {
+				/* disable surround and center/lfe in AC'97
+				*/
+				u16 ext_stat = rdcodec(s->codec,
+						       AC97_EXTENDED_STATUS);
+				wrcodec(s->codec, AC97_EXTENDED_STATUS,
+					ext_stat | (AC97_EXTSTAT_PRI |
+						    AC97_EXTSTAT_PRJ |
+						    AC97_EXTSTAT_PRK));
+			}
+			if ((ret = prog_dmabuf_dac(s)))
+				return ret;
+		}
+		return 0;
+
+	case SNDCTL_DSP_CHANNELS:
+		if (get_user(val, (int *) arg))
+			return -EFAULT;
+		if (val != 0) {
+			if (file->f_mode & FMODE_READ) {
+				if (val < 0 || val > 2)
+					return -EINVAL;
+				stop_adc(s);
+				s->dma_adc.num_channels = val;
+				if ((ret = prog_dmabuf_adc(s)))
+					return ret;
+			}
+			if (file->f_mode & FMODE_WRITE) {
+				switch (val) {
+				case 1:
+				case 2:
+					break;
+				case 3:
+				case 5:
+					return -EINVAL;
+				case 4:
+					if (!(s->codec_ext_caps &
+					      AC97_EXTID_SDAC))
+						return -EINVAL;
+					break;
+				case 6:
+					if ((s->codec_ext_caps &
+					     AC97_EXT_DACS) != AC97_EXT_DACS)
+						return -EINVAL;
+					break;
+				default:
+					return -EINVAL;
+				}
+
+				stop_dac(s);
+				if (val <= 2 &&
+				    (s->codec_ext_caps & AC97_EXT_DACS)) {
+					/* disable surround and center/lfe
+					 * channels in AC'97
+					 */
+					u16             ext_stat =
+						rdcodec(s->codec,
+							AC97_EXTENDED_STATUS);
+					wrcodec(s->codec,
+						AC97_EXTENDED_STATUS,
+						ext_stat | (AC97_EXTSTAT_PRI |
+							    AC97_EXTSTAT_PRJ |
+							    AC97_EXTSTAT_PRK));
+				} else if (val >= 4) {
+					/* enable surround, center/lfe
+					 * channels in AC'97
+					 */
+					u16             ext_stat =
+						rdcodec(s->codec,
+							AC97_EXTENDED_STATUS);
+					ext_stat &= ~AC97_EXTSTAT_PRJ;
+					if (val == 6)
+						ext_stat &=
+							~(AC97_EXTSTAT_PRI |
+							  AC97_EXTSTAT_PRK);
+					wrcodec(s->codec,
+						AC97_EXTENDED_STATUS,
+						ext_stat);
+				}
+
+				s->dma_dac.num_channels = val;
+				if ((ret = prog_dmabuf_dac(s)))
+					return ret;
+			}
+		}
+		return put_user(val, (int *) arg);
+
+	case SNDCTL_DSP_GETFMTS:	/* Returns a mask */
+		return put_user(AFMT_S16_LE | AFMT_U8, (int *) arg);
+
+	case SNDCTL_DSP_SETFMT:	/* Selects ONE fmt */
+		if (get_user(val, (int *) arg))
+			return -EFAULT;
+		if (val != AFMT_QUERY) {
+			if (file->f_mode & FMODE_READ) {
+				stop_adc(s);
+				if (val == AFMT_S16_LE)
+					s->dma_adc.sample_size = 16;
+				else {
+					val = AFMT_U8;
+					s->dma_adc.sample_size = 8;
+				}
+				if ((ret = prog_dmabuf_adc(s)))
+					return ret;
+			}
+			if (file->f_mode & FMODE_WRITE) {
+				stop_dac(s);
+				if (val == AFMT_S16_LE)
+					s->dma_dac.sample_size = 16;
+				else {
+					val = AFMT_U8;
+					s->dma_dac.sample_size = 8;
+				}
+				if ((ret = prog_dmabuf_dac(s)))
+					return ret;
+			}
+		} else {
+			if (file->f_mode & FMODE_READ)
+				val = (s->dma_adc.sample_size == 16) ?
+					AFMT_S16_LE : AFMT_U8;
+			else
+				val = (s->dma_dac.sample_size == 16) ?
+					AFMT_S16_LE : AFMT_U8;
+		}
+		return put_user(val, (int *) arg);
+
+	case SNDCTL_DSP_POST:
+		return 0;
+
+	case SNDCTL_DSP_GETTRIGGER:
+		val = 0;
+		spin_lock_irqsave(&s->lock, flags);
+		if (file->f_mode & FMODE_READ && !s->dma_adc.stopped)
+			val |= PCM_ENABLE_INPUT;
+		if (file->f_mode & FMODE_WRITE && !s->dma_dac.stopped)
+			val |= PCM_ENABLE_OUTPUT;
+		spin_unlock_irqrestore(&s->lock, flags);
+		return put_user(val, (int *) arg);
+
+	case SNDCTL_DSP_SETTRIGGER:
+		if (get_user(val, (int *) arg))
+			return -EFAULT;
+		if (file->f_mode & FMODE_READ) {
+			if (val & PCM_ENABLE_INPUT)
+				start_adc(s);
+			else
+				stop_adc(s);
+		}
+		if (file->f_mode & FMODE_WRITE) {
+			if (val & PCM_ENABLE_OUTPUT)
+				start_dac(s);
+			else
+				stop_dac(s);
+		}
+		return 0;
+
+	case SNDCTL_DSP_GETOSPACE:
+		if (!(file->f_mode & FMODE_WRITE))
+			return -EINVAL;
+		abinfo.fragsize = s->dma_dac.fragsize;
+		spin_lock_irqsave(&s->lock, flags);
+		count = s->dma_dac.count;
+		count -= dma_count_done(&s->dma_dac);
+		spin_unlock_irqrestore(&s->lock, flags);
+		if (count < 0)
+			count = 0;
+		abinfo.bytes = (s->dma_dac.dmasize - count) /
+			s->dma_dac.cnt_factor;
+		abinfo.fragstotal = s->dma_dac.numfrag;
+		abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift;
+		pr_debug("ioctl SNDCTL_DSP_GETOSPACE: bytes=%d, fragments=%d\n", abinfo.bytes, abinfo.fragments);
+		return copy_to_user((void *) arg, &abinfo,
+				    sizeof(abinfo)) ? -EFAULT : 0;
+
+	case SNDCTL_DSP_GETISPACE:
+		if (!(file->f_mode & FMODE_READ))
+			return -EINVAL;
+		abinfo.fragsize = s->dma_adc.fragsize;
+		spin_lock_irqsave(&s->lock, flags);
+		count = s->dma_adc.count;
+		count += dma_count_done(&s->dma_adc);
+		spin_unlock_irqrestore(&s->lock, flags);
+		if (count < 0)
+			count = 0;
+		abinfo.bytes = count / s->dma_adc.cnt_factor;
+		abinfo.fragstotal = s->dma_adc.numfrag;
+		abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift;
+		return copy_to_user((void *) arg, &abinfo,
+				    sizeof(abinfo)) ? -EFAULT : 0;
+
+	case SNDCTL_DSP_NONBLOCK:
+		file->f_flags |= O_NONBLOCK;
+		return 0;
+
+	case SNDCTL_DSP_GETODELAY:
+		if (!(file->f_mode & FMODE_WRITE))
+			return -EINVAL;
+		spin_lock_irqsave(&s->lock, flags);
+		count = s->dma_dac.count;
+		count -= dma_count_done(&s->dma_dac);
+		spin_unlock_irqrestore(&s->lock, flags);
+		if (count < 0)
+			count = 0;
+		count /= s->dma_dac.cnt_factor;
+		return put_user(count, (int *) arg);
+
+	case SNDCTL_DSP_GETIPTR:
+		if (!(file->f_mode & FMODE_READ))
+			return -EINVAL;
+		spin_lock_irqsave(&s->lock, flags);
+		cinfo.bytes = s->dma_adc.total_bytes;
+		count = s->dma_adc.count;
+		if (!s->dma_adc.stopped) {
+			diff = dma_count_done(&s->dma_adc);
+			count += diff;
+			cinfo.bytes += diff;
+			cinfo.ptr =  virt_to_phys(s->dma_adc.nextIn) + diff -
+				virt_to_phys(s->dma_adc.rawbuf);
+		} else
+			cinfo.ptr = virt_to_phys(s->dma_adc.nextIn) -
+				virt_to_phys(s->dma_adc.rawbuf);
+		if (s->dma_adc.mapped)
+			s->dma_adc.count &= (s->dma_adc.dma_fragsize-1);
+		spin_unlock_irqrestore(&s->lock, flags);
+		if (count < 0)
+			count = 0;
+		cinfo.blocks = count >> s->dma_adc.fragshift;
+		return copy_to_user((void *) arg, &cinfo, sizeof(cinfo));
+
+	case SNDCTL_DSP_GETOPTR:
+		if (!(file->f_mode & FMODE_READ))
+			return -EINVAL;
+		spin_lock_irqsave(&s->lock, flags);
+		cinfo.bytes = s->dma_dac.total_bytes;
+		count = s->dma_dac.count;
+		if (!s->dma_dac.stopped) {
+			diff = dma_count_done(&s->dma_dac);
+			count -= diff;
+			cinfo.bytes += diff;
+			cinfo.ptr = virt_to_phys(s->dma_dac.nextOut) + diff -
+				virt_to_phys(s->dma_dac.rawbuf);
+		} else
+			cinfo.ptr = virt_to_phys(s->dma_dac.nextOut) -
+				virt_to_phys(s->dma_dac.rawbuf);
+		if (s->dma_dac.mapped)
+			s->dma_dac.count &= (s->dma_dac.dma_fragsize-1);
+		spin_unlock_irqrestore(&s->lock, flags);
+		if (count < 0)
+			count = 0;
+		cinfo.blocks = count >> s->dma_dac.fragshift;
+		return copy_to_user((void *) arg, &cinfo, sizeof(cinfo));
+
+	case SNDCTL_DSP_GETBLKSIZE:
+		if (file->f_mode & FMODE_WRITE)
+			return put_user(s->dma_dac.fragsize, (int *) arg);
+		else
+			return put_user(s->dma_adc.fragsize, (int *) arg);
+
+	case SNDCTL_DSP_SETFRAGMENT:
+		if (get_user(val, (int *) arg))
+			return -EFAULT;
+		if (file->f_mode & FMODE_READ) {
+			stop_adc(s);
+			s->dma_adc.ossfragshift = val & 0xffff;
+			s->dma_adc.ossmaxfrags = (val >> 16) & 0xffff;
+			if (s->dma_adc.ossfragshift < 4)
+				s->dma_adc.ossfragshift = 4;
+			if (s->dma_adc.ossfragshift > 15)
+				s->dma_adc.ossfragshift = 15;
+			if (s->dma_adc.ossmaxfrags < 4)
+				s->dma_adc.ossmaxfrags = 4;
+			if ((ret = prog_dmabuf_adc(s)))
+				return ret;
+		}
+		if (file->f_mode & FMODE_WRITE) {
+			stop_dac(s);
+			s->dma_dac.ossfragshift = val & 0xffff;
+			s->dma_dac.ossmaxfrags = (val >> 16) & 0xffff;
+			if (s->dma_dac.ossfragshift < 4)
+				s->dma_dac.ossfragshift = 4;
+			if (s->dma_dac.ossfragshift > 15)
+				s->dma_dac.ossfragshift = 15;
+			if (s->dma_dac.ossmaxfrags < 4)
+				s->dma_dac.ossmaxfrags = 4;
+			if ((ret = prog_dmabuf_dac(s)))
+				return ret;
+		}
+		return 0;
+
+	case SNDCTL_DSP_SUBDIVIDE:
+		if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) ||
+		    (file->f_mode & FMODE_WRITE && s->dma_dac.subdivision))
+			return -EINVAL;
+		if (get_user(val, (int *) arg))
+			return -EFAULT;
+		if (val != 1 && val != 2 && val != 4)
+			return -EINVAL;
+		if (file->f_mode & FMODE_READ) {
+			stop_adc(s);
+			s->dma_adc.subdivision = val;
+			if ((ret = prog_dmabuf_adc(s)))
+				return ret;
+		}
+		if (file->f_mode & FMODE_WRITE) {
+			stop_dac(s);
+			s->dma_dac.subdivision = val;
+			if ((ret = prog_dmabuf_dac(s)))
+				return ret;
+		}
+		return 0;
+
+	case SOUND_PCM_READ_RATE:
+		return put_user((file->f_mode & FMODE_READ) ?
+				s->dma_adc.sample_rate :
+				s->dma_dac.sample_rate,
+				(int *)arg);
+
+	case SOUND_PCM_READ_CHANNELS:
+		if (file->f_mode & FMODE_READ)
+			return put_user(s->dma_adc.num_channels, (int *)arg);
+		else
+			return put_user(s->dma_dac.num_channels, (int *)arg);
+
+	case SOUND_PCM_READ_BITS:
+		if (file->f_mode & FMODE_READ)
+			return put_user(s->dma_adc.sample_size, (int *)arg);
+		else
+			return put_user(s->dma_dac.sample_size, (int *)arg);
+
+	case SOUND_PCM_WRITE_FILTER:
+	case SNDCTL_DSP_SETSYNCRO:
+	case SOUND_PCM_READ_FILTER:
+		return -EINVAL;
+	}
+
+	return mixdev_ioctl(s->codec, cmd, arg);
+}
+
+
+static int
+au1550_open(struct inode *inode, struct file *file)
+{
+	int             minor = MINOR(inode->i_rdev);
+	DECLARE_WAITQUEUE(wait, current);
+	struct au1550_state *s = &au1550_state;
+	int             ret;
+
+#ifdef DEBUG
+	if (file->f_flags & O_NONBLOCK)
+		pr_debug("open: non-blocking\n");
+	else
+		pr_debug("open: blocking\n");
+#endif
+
+	file->private_data = s;
+	/* wait for device to become free */
+	down(&s->open_sem);
+	while (s->open_mode & file->f_mode) {
+		if (file->f_flags & O_NONBLOCK) {
+			up(&s->open_sem);
+			return -EBUSY;
+		}
+		add_wait_queue(&s->open_wait, &wait);
+		__set_current_state(TASK_INTERRUPTIBLE);
+		up(&s->open_sem);
+		schedule();
+		remove_wait_queue(&s->open_wait, &wait);
+		set_current_state(TASK_RUNNING);
+		if (signal_pending(current))
+			return -ERESTARTSYS;
+		down(&s->open_sem);
+	}
+
+	stop_dac(s);
+	stop_adc(s);
+
+	if (file->f_mode & FMODE_READ) {
+		s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags =
+			s->dma_adc.subdivision = s->dma_adc.total_bytes = 0;
+		s->dma_adc.num_channels = 1;
+		s->dma_adc.sample_size = 8;
+		set_adc_rate(s, 8000);
+		if ((minor & 0xf) == SND_DEV_DSP16)
+			s->dma_adc.sample_size = 16;
+	}
+
+	if (file->f_mode & FMODE_WRITE) {
+		s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags =
+			s->dma_dac.subdivision = s->dma_dac.total_bytes = 0;
+		s->dma_dac.num_channels = 1;
+		s->dma_dac.sample_size = 8;
+		set_dac_rate(s, 8000);
+		if ((minor & 0xf) == SND_DEV_DSP16)
+			s->dma_dac.sample_size = 16;
+	}
+
+	if (file->f_mode & FMODE_READ) {
+		if ((ret = prog_dmabuf_adc(s)))
+			return ret;
+	}
+	if (file->f_mode & FMODE_WRITE) {
+		if ((ret = prog_dmabuf_dac(s)))
+			return ret;
+	}
+
+	s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
+	up(&s->open_sem);
+	init_MUTEX(&s->sem);
+	return 0;
+}
+
+static int
+au1550_release(struct inode *inode, struct file *file)
+{
+	struct au1550_state *s = (struct au1550_state *)file->private_data;
+
+	lock_kernel();
+
+	if (file->f_mode & FMODE_WRITE) {
+		unlock_kernel();
+		drain_dac(s, file->f_flags & O_NONBLOCK);
+		lock_kernel();
+	}
+
+	down(&s->open_sem);
+	if (file->f_mode & FMODE_WRITE) {
+		stop_dac(s);
+		kfree(s->dma_dac.rawbuf);
+		s->dma_dac.rawbuf = NULL;
+	}
+	if (file->f_mode & FMODE_READ) {
+		stop_adc(s);
+		kfree(s->dma_adc.rawbuf);
+		s->dma_adc.rawbuf = NULL;
+	}
+	s->open_mode &= ((~file->f_mode) & (FMODE_READ|FMODE_WRITE));
+	up(&s->open_sem);
+	wake_up(&s->open_wait);
+	unlock_kernel();
+	return 0;
+}
+
+static /*const */ struct file_operations au1550_audio_fops = {
+	owner:		THIS_MODULE,
+	llseek:		au1550_llseek,
+	read:		au1550_read,
+	write:		au1550_write,
+	poll:		au1550_poll,
+	ioctl:		au1550_ioctl,
+	mmap:		au1550_mmap,
+	open:		au1550_open,
+	release:	au1550_release,
+};
+
+MODULE_AUTHOR("Advanced Micro Devices (AMD), dan@embeddededge.com");
+MODULE_DESCRIPTION("Au1550 AC97 Audio Driver");
+
+static int __devinit
+au1550_probe(void)
+{
+	struct au1550_state *s = &au1550_state;
+	int             val;
+
+	memset(s, 0, sizeof(struct au1550_state));
+
+	init_waitqueue_head(&s->dma_adc.wait);
+	init_waitqueue_head(&s->dma_dac.wait);
+	init_waitqueue_head(&s->open_wait);
+	init_MUTEX(&s->open_sem);
+	spin_lock_init(&s->lock);
+
+	s->codec = ac97_alloc_codec();
+	if(s->codec == NULL) {
+		err("Out of memory");
+		return -1;
+	}
+	s->codec->private_data = s;
+	s->codec->id = 0;
+	s->codec->codec_read = rdcodec;
+	s->codec->codec_write = wrcodec;
+	s->codec->codec_wait = waitcodec;
+
+	if (!request_mem_region(CPHYSADDR(AC97_PSC_SEL),
+			    0x30, "Au1550 AC97")) {
+		err("AC'97 ports in use");
+	}
+
+	/* Allocate the DMA Channels
+	*/
+	if ((s->dma_dac.dmanr = au1xxx_dbdma_chan_alloc(DBDMA_MEM_CHAN,
+	    DBDMA_AC97_TX_CHAN, dac_dma_interrupt, (void *)s)) == 0) {
+		err("Can't get DAC DMA");
+		goto err_dma1;
+	}
+	au1xxx_dbdma_set_devwidth(s->dma_dac.dmanr, 16);
+	if (au1xxx_dbdma_ring_alloc(s->dma_dac.dmanr,
+					NUM_DBDMA_DESCRIPTORS) == 0) {
+		err("Can't get DAC DMA descriptors");
+		goto err_dma1;
+	}
+
+	if ((s->dma_adc.dmanr = au1xxx_dbdma_chan_alloc(DBDMA_AC97_RX_CHAN,
+	    DBDMA_MEM_CHAN, adc_dma_interrupt, (void *)s)) == 0) {
+		err("Can't get ADC DMA");
+		goto err_dma2;
+	}
+	au1xxx_dbdma_set_devwidth(s->dma_adc.dmanr, 16);
+	if (au1xxx_dbdma_ring_alloc(s->dma_adc.dmanr,
+					NUM_DBDMA_DESCRIPTORS) == 0) {
+		err("Can't get ADC DMA descriptors");
+		goto err_dma2;
+	}
+
+	pr_info("DAC: DMA%d, ADC: DMA%d", DBDMA_AC97_TX_CHAN, DBDMA_AC97_RX_CHAN);
+
+	/* register devices */
+
+	if ((s->dev_audio = register_sound_dsp(&au1550_audio_fops, -1)) < 0)
+		goto err_dev1;
+	if ((s->codec->dev_mixer =
+	     register_sound_mixer(&au1550_mixer_fops, -1)) < 0)
+		goto err_dev2;
+
+	/* The GPIO for the appropriate PSC was configured by the
+	 * board specific start up.
+	 *
+	 * configure PSC for AC'97
+	 */
+	au_writel(0, AC97_PSC_CTRL);	/* Disable PSC */
+	au_sync();
+	au_writel((PSC_SEL_CLK_SERCLK | PSC_SEL_PS_AC97MODE), AC97_PSC_SEL);
+	au_sync();
+
+	/* cold reset the AC'97
+	*/
+	au_writel(PSC_AC97RST_RST, PSC_AC97RST);
+	au_sync();
+	au1550_delay(10);
+	au_writel(0, PSC_AC97RST);
+	au_sync();
+
+	/* need to delay around 500msec(bleech) to give
+	   some CODECs enough time to wakeup */
+	au1550_delay(500);
+
+	/* warm reset the AC'97 to start the bitclk
+	*/
+	au_writel(PSC_AC97RST_SNC, PSC_AC97RST);
+	au_sync();
+	udelay(100);
+	au_writel(0, PSC_AC97RST);
+	au_sync();
+
+	/* Enable PSC
+	*/
+	au_writel(PSC_CTRL_ENABLE, AC97_PSC_CTRL);
+	au_sync();
+
+	/* Wait for PSC ready.
+	*/
+	do {
+		val = readl((void *)PSC_AC97STAT);
+		au_sync();
+	} while ((val & PSC_AC97STAT_SR) == 0);
+
+	/* Configure AC97 controller.
+	 * Deep FIFO, 16-bit sample, DMA, make sure DMA matches fifo size.
+	 */
+	val = PSC_AC97CFG_SET_LEN(16);
+	val |= PSC_AC97CFG_RT_FIFO8 | PSC_AC97CFG_TT_FIFO8;
+
+	/* Enable device so we can at least
+	 * talk over the AC-link.
+	 */
+	au_writel(val, PSC_AC97CFG);
+	au_writel(PSC_AC97MSK_ALLMASK, PSC_AC97MSK);
+	au_sync();
+	val |= PSC_AC97CFG_DE_ENABLE;
+	au_writel(val, PSC_AC97CFG);
+	au_sync();
+
+	/* Wait for Device ready.
+	*/
+	do {
+		val = readl((void *)PSC_AC97STAT);
+		au_sync();
+	} while ((val & PSC_AC97STAT_DR) == 0);
+
+	/* codec init */
+	if (!ac97_probe_codec(s->codec))
+		goto err_dev3;
+
+	s->codec_base_caps = rdcodec(s->codec, AC97_RESET);
+	s->codec_ext_caps = rdcodec(s->codec, AC97_EXTENDED_ID);
+	pr_info("AC'97 Base/Extended ID = %04x/%04x",
+	     s->codec_base_caps, s->codec_ext_caps);
+
+	if (!(s->codec_ext_caps & AC97_EXTID_VRA)) {
+		/* codec does not support VRA
+		*/
+		s->no_vra = 1;
+	} else if (!vra) {
+		/* Boot option says disable VRA
+		*/
+		u16 ac97_extstat = rdcodec(s->codec, AC97_EXTENDED_STATUS);
+		wrcodec(s->codec, AC97_EXTENDED_STATUS,
+			ac97_extstat & ~AC97_EXTSTAT_VRA);
+		s->no_vra = 1;
+	}
+	if (s->no_vra)
+		pr_info("no VRA, interpolating and decimating");
+
+	/* set mic to be the recording source */
+	val = SOUND_MASK_MIC;
+	mixdev_ioctl(s->codec, SOUND_MIXER_WRITE_RECSRC,
+		     (unsigned long) &val);
+
+	return 0;
+
+ err_dev3:
+	unregister_sound_mixer(s->codec->dev_mixer);
+ err_dev2:
+	unregister_sound_dsp(s->dev_audio);
+ err_dev1:
+	au1xxx_dbdma_chan_free(s->dma_adc.dmanr);
+ err_dma2:
+	au1xxx_dbdma_chan_free(s->dma_dac.dmanr);
+ err_dma1:
+	release_mem_region(CPHYSADDR(AC97_PSC_SEL), 0x30);
+
+	ac97_release_codec(s->codec);
+	return -1;
+}
+
+static void __devinit
+au1550_remove(void)
+{
+	struct au1550_state *s = &au1550_state;
+
+	if (!s)
+		return;
+	synchronize_irq();
+	au1xxx_dbdma_chan_free(s->dma_adc.dmanr);
+	au1xxx_dbdma_chan_free(s->dma_dac.dmanr);
+	release_mem_region(CPHYSADDR(AC97_PSC_SEL), 0x30);
+	unregister_sound_dsp(s->dev_audio);
+	unregister_sound_mixer(s->codec->dev_mixer);
+	ac97_release_codec(s->codec);
+}
+
+static int __init
+init_au1550(void)
+{
+	return au1550_probe();
+}
+
+static void __exit
+cleanup_au1550(void)
+{
+	au1550_remove();
+}
+
+module_init(init_au1550);
+module_exit(cleanup_au1550);
+
+#ifndef MODULE
+
+static int __init
+au1550_setup(char *options)
+{
+	char           *this_opt;
+
+	if (!options || !*options)
+		return 0;
+
+	while ((this_opt = strsep(&options, ","))) {
+		if (!*this_opt)
+			continue;
+		if (!strncmp(this_opt, "vra", 3)) {
+			vra = 1;
+		}
+	}
+
+	return 1;
+}
+
+__setup("au1550_audio=", au1550_setup);
+
+#endif /* MODULE */
diff -Nru a/sound/oss/awe_wave.c b/sound/oss/awe_wave.c
--- a/sound/oss/awe_wave.c	2005-03-01 23:38:56 -08:00
+++ b/sound/oss/awe_wave.c	2005-03-01 23:38:56 -08:00
@@ -207,8 +207,8 @@
 #define AWE_DEFAULT_MEM_SIZE	-1	/* autodetect */
 #endif
 
-int io = AWE_DEFAULT_BASE_ADDR; /* Emu8000 base address */
-int memsize = AWE_DEFAULT_MEM_SIZE; /* memory size in Kbytes */
+static int io = AWE_DEFAULT_BASE_ADDR; /* Emu8000 base address */
+static int memsize = AWE_DEFAULT_MEM_SIZE; /* memory size in Kbytes */
 #ifdef CONFIG_PNP
 static int isapnp = -1;
 #else
@@ -219,11 +219,11 @@
 MODULE_DESCRIPTION("SB AWE32/64 WaveTable driver");
 MODULE_LICENSE("GPL");
 
-MODULE_PARM(io, "i");
+module_param(io, int, 0);
 MODULE_PARM_DESC(io, "base i/o port of Emu8000");
-MODULE_PARM(memsize, "i");
+module_param(memsize, int, 0);
 MODULE_PARM_DESC(memsize, "onboard DRAM size in Kbytes");
-MODULE_PARM(isapnp, "i");
+module_param(isapnp, bool, 0);
 MODULE_PARM_DESC(isapnp, "use ISAPnP detection");
 
 /* DRAM start offset */
@@ -6113,12 +6113,12 @@
 	return 0;
 }
 
-int __init attach_awe(void)
+static int __init attach_awe(void)
 {
 	return awe_detect() ? 0 : -ENODEV;
 }
 
-void __exit unload_awe(void)
+static void __exit unload_awe(void)
 {
 	pnp_unregister_driver(&awe_pnp_driver);
 	awe_dettach_device();
diff -Nru a/sound/oss/btaudio.c b/sound/oss/btaudio.c
--- a/sound/oss/btaudio.c	2005-03-01 23:38:53 -08:00
+++ b/sound/oss/btaudio.c	2005-03-01 23:38:53 -08:00
@@ -1113,15 +1113,15 @@
 module_init(btaudio_init_module);
 module_exit(btaudio_cleanup_module);
 
-MODULE_PARM(dsp1,"i");
-MODULE_PARM(dsp2,"i");
-MODULE_PARM(mixer,"i");
-MODULE_PARM(debug,"i");
-MODULE_PARM(irq_debug,"i");
-MODULE_PARM(digital,"i");
-MODULE_PARM(analog,"i");
-MODULE_PARM(rate,"i");
-MODULE_PARM(latency,"i");
+module_param(dsp1, int, S_IRUGO);
+module_param(dsp2, int, S_IRUGO);
+module_param(mixer, int, S_IRUGO);
+module_param(debug, int, S_IRUGO | S_IWUSR);
+module_param(irq_debug, int, S_IRUGO | S_IWUSR);
+module_param(digital, int, S_IRUGO);
+module_param(analog, int, S_IRUGO);
+module_param(rate, int, S_IRUGO);
+module_param(latency, int, S_IRUGO);
 MODULE_PARM_DESC(latency,"pci latency timer");
 
 MODULE_DEVICE_TABLE(pci, btaudio_pci_tbl);
diff -Nru a/sound/oss/cmpci.c b/sound/oss/cmpci.c
--- a/sound/oss/cmpci.c	2005-03-01 23:38:58 -08:00
+++ b/sound/oss/cmpci.c	2005-03-01 23:38:58 -08:00
@@ -479,17 +479,17 @@
 static	int	use_mic_as_bass = 0;
 static	int	mic_boost = 0;
 static	int	hw_copy = 0;
-MODULE_PARM(mpuio, "i");
-MODULE_PARM(fmio, "i");
-MODULE_PARM(joystick, "i");
-MODULE_PARM(spdif_inverse, "i");
-MODULE_PARM(spdif_loop, "i");
-MODULE_PARM(spdif_out, "i");
-MODULE_PARM(use_line_as_rear, "i");
-MODULE_PARM(use_line_as_bass, "i");
-MODULE_PARM(use_mic_as_bass, "i");
-MODULE_PARM(mic_boost, "i");
-MODULE_PARM(hw_copy, "i");
+module_param(mpuio, int, 0);
+module_param(fmio, int, 0);
+module_param(joystick, bool, 0);
+module_param(spdif_inverse, bool, 0);
+module_param(spdif_loop, bool, 0);
+module_param(spdif_out, bool, 0);
+module_param(use_line_as_rear, bool, 0);
+module_param(use_line_as_bass, bool, 0);
+module_param(use_mic_as_bass, bool, 0);
+module_param(mic_boost, bool, 0);
+module_param(hw_copy, bool, 0);
 MODULE_PARM_DESC(mpuio, "(0x330, 0x320, 0x310, 0x300) Base of MPU-401, 0 to disable");
 MODULE_PARM_DESC(fmio, "(0x388, 0x3C8, 0x3E0) Base of OPL3, 0 to disable");
 MODULE_PARM_DESC(joystick, "(1/0) Enable joystick interface, still need joystick driver");
@@ -1160,15 +1160,6 @@
 
 	if (s->status & DO_DUAL_DAC)
 		enable_adc(s);
-}
-
-static inline void enable_dac(struct cm_state *s)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&s->lock, flags);
-	enable_dac_unlocked(s);
-	spin_unlock_irqrestore(&s->lock, flags);
 }
 
 static inline void stop_adc_unlocked(struct cm_state *s)
diff -Nru a/sound/oss/cs4232.c b/sound/oss/cs4232.c
--- a/sound/oss/cs4232.c	2005-03-01 23:38:58 -08:00
+++ b/sound/oss/cs4232.c	2005-03-01 23:38:58 -08:00
@@ -54,7 +54,6 @@
 
 #include "sound_config.h"
 
-#include "cs4232.h"
 #include "ad1848.h"
 #include "mpu401.h"
 
@@ -78,7 +77,7 @@
 static int synth_base, synth_irq;
 static int mpu_detected;
 
-int probe_cs4232_mpu(struct address_info *hw_config)
+static int probe_cs4232_mpu(struct address_info *hw_config)
 {
 	/*
 	 *	Just write down the config values.
@@ -363,25 +362,25 @@
 MODULE_AUTHOR("Hannu Savolainen, Paul Barton-Davis"); 
 MODULE_LICENSE("GPL");
 
-MODULE_PARM(io,"i");
+module_param(io, int, 0);
 MODULE_PARM_DESC(io,"base I/O port for AD1848");
-MODULE_PARM(irq,"i");
+module_param(irq, int, 0);
 MODULE_PARM_DESC(irq,"IRQ for AD1848 chip");
-MODULE_PARM(dma,"i");
+module_param(dma, int, 0);
 MODULE_PARM_DESC(dma,"8 bit DMA for AD1848 chip");
-MODULE_PARM(dma2,"i");
+module_param(dma2, int, 0);
 MODULE_PARM_DESC(dma2,"16 bit DMA for AD1848 chip");
-MODULE_PARM(mpuio,"i");
+module_param(mpuio, int, 0);
 MODULE_PARM_DESC(mpuio,"MPU 401 base address");
-MODULE_PARM(mpuirq,"i");
+module_param(mpuirq, int, 0);
 MODULE_PARM_DESC(mpuirq,"MPU 401 IRQ");
-MODULE_PARM(synthio,"i");
+module_param(synthio, int, 0);
 MODULE_PARM_DESC(synthio,"Maui WaveTable base I/O port");
-MODULE_PARM(synthirq,"i");
+module_param(synthirq, int, 0);
 MODULE_PARM_DESC(synthirq,"Maui WaveTable IRQ");
-MODULE_PARM(isapnp,"i");
+module_param(isapnp, bool, 0);
 MODULE_PARM_DESC(isapnp,"Enable ISAPnP probing (default 1)");
-MODULE_PARM(bss,"i");
+module_param(bss, bool, 0);
 MODULE_PARM_DESC(bss,"Enable Bose Sound System Support (default 0)");
 
 /*
diff -Nru a/sound/oss/cs4232.h b/sound/oss/cs4232.h
--- a/sound/oss/cs4232.h	2005-03-01 23:39:18 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,3 +0,0 @@
-
-int probe_cs4232_mpu (struct address_info *hw_config);
-void attach_cs4232_mpu (struct address_info *hw_config);
diff -Nru a/sound/oss/cs4281/cs4281_wrapper-24.c b/sound/oss/cs4281/cs4281_wrapper-24.c
--- a/sound/oss/cs4281/cs4281_wrapper-24.c	2005-03-01 23:38:55 -08:00
+++ b/sound/oss/cs4281/cs4281_wrapper-24.c	2005-03-01 23:38:55 -08:00
@@ -26,8 +26,8 @@
 
 #include <linux/spinlock.h>
 
-int cs4281_resume_null(struct pci_dev *pcidev) { return 0; }
-int cs4281_suspend_null(struct pci_dev *pcidev, u32 state) { return 0; }
+static int cs4281_resume_null(struct pci_dev *pcidev) { return 0; }
+static int cs4281_suspend_null(struct pci_dev *pcidev, u32 state) { return 0; }
 
 #define free_dmabuf(state, dmabuf) \
 	pci_free_consistent(state->pcidev, \
diff -Nru a/sound/oss/cs4281/cs4281m.c b/sound/oss/cs4281/cs4281m.c
--- a/sound/oss/cs4281/cs4281m.c	2005-03-01 23:39:17 -08:00
+++ b/sound/oss/cs4281/cs4281m.c	2005-03-01 23:39:17 -08:00
@@ -111,7 +111,7 @@
 // rather than 64k as some of the games work more responsively.
 // log base 2( buff sz = 32k).
 static unsigned long defaultorder = 3;
-MODULE_PARM(defaultorder, "i");
+module_param(defaultorder, ulong, 0);
 
 //
 // Turn on/off debugging compilation by commenting out "#define CSDEBUG"
@@ -159,8 +159,8 @@
 #if CSDEBUG
 static unsigned long cs_debuglevel = 1;	// levels range from 1-9
 static unsigned long cs_debugmask = CS_INIT | CS_ERROR;	// use CS_DBGOUT with various mask values
-MODULE_PARM(cs_debuglevel, "i");
-MODULE_PARM(cs_debugmask, "i");
+module_param(cs_debuglevel, ulong, 0);
+module_param(cs_debugmask, ulong, 0);
 #endif
 #define CS_TRUE 	1
 #define CS_FALSE 	0
@@ -197,7 +197,7 @@
 })
 
 //LIST_HEAD(cs4281_devs);
-struct list_head cs4281_devs = { &cs4281_devs, &cs4281_devs };
+static struct list_head cs4281_devs = { &cs4281_devs, &cs4281_devs };
 
 struct cs4281_state; 
 
@@ -1019,7 +1019,7 @@
 *  Suspend - save the ac97 regs, mute the outputs and power down the part.  
 *
 ****************************************************************************/
-void cs4281_ac97_suspend(struct cs4281_state *s)
+static void cs4281_ac97_suspend(struct cs4281_state *s)
 {
 	int Count,i;
 
@@ -1070,7 +1070,7 @@
 *  Resume - power up the part and restore its registers..  
 *
 ****************************************************************************/
-void cs4281_ac97_resume(struct cs4281_state *s)
+static void cs4281_ac97_resume(struct cs4281_state *s)
 {
 	int Count,i;
 
@@ -1143,7 +1143,7 @@
 } // SavePowerState
 */
 
-void cs4281_SuspendFIFO(struct cs4281_state *s, struct cs4281_pipeline *pl)
+static void cs4281_SuspendFIFO(struct cs4281_state *s, struct cs4281_pipeline *pl)
 {
  /*
  * We need to save the contents of the BASIC FIFO Registers.
@@ -1151,7 +1151,7 @@
 	pl->u32FCRn_Save = readl(s->pBA0 + pl->u32FCRnAddress);
 	pl->u32FSICn_Save = readl(s->pBA0 + pl->u32FSICnAddress);
 }
-void cs4281_ResumeFIFO(struct cs4281_state *s, struct cs4281_pipeline *pl)
+static void cs4281_ResumeFIFO(struct cs4281_state *s, struct cs4281_pipeline *pl)
 {
  /*
  * We need to restore the contents of the BASIC FIFO Registers.
@@ -1159,7 +1159,7 @@
 	writel(pl->u32FCRn_Save,s->pBA0 + pl->u32FCRnAddress);
 	writel(pl->u32FSICn_Save,s->pBA0 + pl->u32FSICnAddress);
 }
-void cs4281_SuspendDMAengine(struct cs4281_state *s, struct cs4281_pipeline *pl)
+static void cs4281_SuspendDMAengine(struct cs4281_state *s, struct cs4281_pipeline *pl)
 {
 	//
 	// We need to save the contents of the BASIC DMA Registers.
@@ -1171,7 +1171,7 @@
 	pl->u32DCCn_Save = readl(s->pBA0 + pl->u32DCCnAddress);
 	pl->u32DCAn_Save = readl(s->pBA0 + pl->u32DCAnAddress);
 }
-void cs4281_ResumeDMAengine(struct cs4281_state *s, struct cs4281_pipeline *pl)
+static void cs4281_ResumeDMAengine(struct cs4281_state *s, struct cs4281_pipeline *pl)
 {
 	//
 	// We need to save the contents of the BASIC DMA Registers.
@@ -1184,7 +1184,7 @@
 	writel( pl->u32DCAn_Save, s->pBA0 + pl->u32DCAnAddress);
 }
 
-int cs4281_suspend(struct cs4281_state *s)
+static int cs4281_suspend(struct cs4281_state *s)
 {
 	int i;
 	u32 u32CLKCR1;
@@ -1340,7 +1340,7 @@
 	return 0;
 }
 
-int cs4281_resume(struct cs4281_state *s)
+static int cs4281_resume(struct cs4281_state *s)
 {
 	int i;
 	unsigned temp1;
@@ -1695,7 +1695,7 @@
 #define DMABUF_MINORDER 1	// ==> min buffer size = 8K.
 
 
-void dealloc_dmabuf(struct cs4281_state *s, struct dmabuf *db)
+static void dealloc_dmabuf(struct cs4281_state *s, struct dmabuf *db)
 {
 	struct page *map, *mapend;
 
@@ -4112,7 +4112,7 @@
 
 
 #ifndef NOT_CS4281_PM
-void __devinit cs4281_BuildFIFO(
+static void __devinit cs4281_BuildFIFO(
 	struct cs4281_pipeline *p, 
 	struct cs4281_state *s)
 {
@@ -4159,7 +4159,7 @@
 
 }
 
-void __devinit cs4281_BuildDMAengine(
+static void __devinit cs4281_BuildDMAengine(
 	struct cs4281_pipeline *p, 
 	struct cs4281_state *s)
 {
@@ -4229,7 +4229,7 @@
 
 }
 
-void __devinit cs4281_InitPM(struct cs4281_state *s)
+static void __devinit cs4281_InitPM(struct cs4281_state *s)
 {
 	int i;
 	struct cs4281_pipeline *p;
@@ -4459,7 +4459,7 @@
 
 MODULE_DEVICE_TABLE(pci, cs4281_pci_tbl);
 
-struct pci_driver cs4281_pci_driver = {
+static struct pci_driver cs4281_pci_driver = {
 	.name	  = "cs4281",
 	.id_table = cs4281_pci_tbl,
 	.probe	  = cs4281_probe,
@@ -4468,7 +4468,7 @@
 	.resume	  = CS4281_RESUME_TBL,
 };
 
-int __init cs4281_init_module(void)
+static int __init cs4281_init_module(void)
 {
 	int rtn = 0;
 	CS_DBGOUT(CS_INIT | CS_FUNCTION, 2, printk(KERN_INFO 
@@ -4483,7 +4483,7 @@
 	return rtn;
 }
 
-void __exit cs4281_cleanup_module(void)
+static void __exit cs4281_cleanup_module(void)
 {
 	pci_unregister_driver(&cs4281_pci_driver);
 #ifndef NOT_CS4281_PM
@@ -4503,9 +4503,3 @@
 module_init(cs4281_init_module);
 module_exit(cs4281_cleanup_module);
 
-#ifndef MODULE
-int __init init_cs4281(void)
-{
-	return cs4281_init_module();
-}
-#endif
diff -Nru a/sound/oss/cs4281/cs4281pm-24.c b/sound/oss/cs4281/cs4281pm-24.c
--- a/sound/oss/cs4281/cs4281pm-24.c	2005-03-01 23:39:07 -08:00
+++ b/sound/oss/cs4281/cs4281pm-24.c	2005-03-01 23:39:07 -08:00
@@ -30,8 +30,8 @@
 #define cs_pm_register(a, b, c) pm_register((a), (b), (c));
 #define cs_pm_unregister_all(a) pm_unregister_all((a));
 
-int cs4281_suspend(struct cs4281_state *s);
-int cs4281_resume(struct cs4281_state *s);
+static int cs4281_suspend(struct cs4281_state *s);
+static int cs4281_resume(struct cs4281_state *s);
 /* 
 * for now (12/22/00) only enable the pm_register PM support.
 * allow these table entries to be null.
@@ -41,7 +41,7 @@
 #define CS4281_SUSPEND_TBL cs4281_suspend_null
 #define CS4281_RESUME_TBL cs4281_resume_null
 
-int cs4281_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *data)
+static int cs4281_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *data)
 {
 	struct cs4281_state *state;
 
diff -Nru a/sound/oss/cs46xx.c b/sound/oss/cs46xx.c
--- a/sound/oss/cs46xx.c	2005-03-01 23:39:18 -08:00
+++ b/sound/oss/cs46xx.c	2005-03-01 23:39:18 -08:00
@@ -175,24 +175,24 @@
 
 #if CSDEBUG
 static unsigned long cs_debuglevel=1;			/* levels range from 1-9 */
-MODULE_PARM(cs_debuglevel, "i");
+module_param(cs_debuglevel, ulong, 0644);
 static unsigned long cs_debugmask=CS_INIT | CS_ERROR;	/* use CS_DBGOUT with various mask values */
-MODULE_PARM(cs_debugmask, "i");
+module_param(cs_debugmask, ulong, 0644);
 #endif
 static unsigned long hercules_egpio_disable;  /* if non-zero set all EGPIO to 0 */
-MODULE_PARM(hercules_egpio_disable, "i");
+module_param(hercules_egpio_disable, ulong, 0);
 static unsigned long initdelay=700;  /* PM delay in millisecs */
-MODULE_PARM(initdelay, "i");
+module_param(initdelay, ulong, 0);
 static unsigned long powerdown=-1;  /* turn on/off powerdown processing in driver */
-MODULE_PARM(powerdown, "i");
+module_param(powerdown, ulong, 0);
 #define DMABUF_DEFAULTORDER 3
 static unsigned long defaultorder=DMABUF_DEFAULTORDER;
-MODULE_PARM(defaultorder, "i");
+module_param(defaultorder, ulong, 0);
 
 static int external_amp;
-MODULE_PARM(external_amp, "i");
+module_param(external_amp, bool, 0);
 static int thinkpad;
-MODULE_PARM(thinkpad, "i");
+module_param(thinkpad, bool, 0);
 
 /*
 * set the powerdown module parm to 0 to disable all 
@@ -219,7 +219,7 @@
 #define CS46XX_ARCH	     	"32"	//architecture key
 #endif
 
-struct list_head cs46xx_devs = { &cs46xx_devs, &cs46xx_devs };
+static struct list_head cs46xx_devs = { &cs46xx_devs, &cs46xx_devs };
 
 /* magic numbers to protect our data structures */
 #define CS_CARD_MAGIC		0x43525553 /* "CRUS" */
@@ -391,30 +391,9 @@
 static int cs46xx_suspend_tbl(struct pci_dev *pcidev, u32 state);
 static int cs46xx_resume_tbl(struct pci_dev *pcidev);
 
-static inline unsigned ld2(unsigned int x)
-{
-	unsigned r = 0;
-	
-	if (x >= 0x10000) {
-		x >>= 16;
-		r += 16;
-	}
-	if (x >= 0x100) {
-		x >>= 8;
-		r += 8;
-	}
-	if (x >= 0x10) {
-		x >>= 4;
-		r += 4;
-	}
-	if (x >= 4) {
-		x >>= 2;
-		r += 2;
-	}
-	if (x >= 2)
-		r++;
-	return r;
-}
+#ifndef CS46XX_ACPI_SUPPORT
+static int cs46xx_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *data);
+#endif
 
 #if CSDEBUG
 
@@ -426,7 +405,7 @@
 #define SOUND_MIXER_CS_SETDBGMASK 	_SIOWR('M',123, int)
 #define SOUND_MIXER_CS_APM	 	_SIOWR('M',124, int)
 
-void printioctl(unsigned int x)
+static void printioctl(unsigned int x)
 {
     unsigned int i;
     unsigned char vidx;
@@ -964,7 +943,7 @@
  * "SetCaptureSPValues()" -- Initialize record task values before each
  * 	capture startup.  
  */
-void SetCaptureSPValues(struct cs_card *card)
+static void SetCaptureSPValues(struct cs_card *card)
 {
 	unsigned i, offset;
 	CS_DBGOUT(CS_FUNCTION, 8, printk("cs46xx: SetCaptureSPValues()+\n") );
@@ -3490,7 +3469,7 @@
 *  Suspend - save the ac97 regs, mute the outputs and power down the part.  
 *
 ****************************************************************************/
-void cs46xx_ac97_suspend(struct cs_card *card)
+static void cs46xx_ac97_suspend(struct cs_card *card)
 {
 	int Count,i;
 	struct ac97_codec *dev=card->ac97_codec[0];
@@ -3561,7 +3540,7 @@
 *  Resume - power up the part and restore its registers..  
 *
 ****************************************************************************/
-void cs46xx_ac97_resume(struct cs_card *card)
+static void cs46xx_ac97_resume(struct cs_card *card)
 {
 	int Count,i;
 	struct ac97_codec *dev=card->ac97_codec[0];
@@ -4149,7 +4128,6 @@
 	return 0;
 }
 
-void __exit cs46xx_cleanup_module(void);
 static int cs_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int cmd,
 				unsigned long arg)
 {
@@ -5719,7 +5697,7 @@
 
 MODULE_DEVICE_TABLE(pci, cs46xx_pci_tbl);
 
-struct pci_driver cs46xx_pci_driver = {
+static struct pci_driver cs46xx_pci_driver = {
 	.name	  = "cs46xx",
 	.id_table = cs46xx_pci_tbl,
 	.probe	  = cs46xx_probe,
@@ -5728,7 +5706,7 @@
 	.resume	  = CS46XX_RESUME_TBL,
 };
 
-int __init cs46xx_init_module(void)
+static int __init cs46xx_init_module(void)
 {
 	int rtn = 0;
 	CS_DBGOUT(CS_INIT | CS_FUNCTION, 2, printk(KERN_INFO 
@@ -5746,7 +5724,7 @@
 	return rtn;
 }
 
-void __exit cs46xx_cleanup_module(void)
+static void __exit cs46xx_cleanup_module(void)
 {
 	pci_unregister_driver(&cs46xx_pci_driver);
 	cs_pm_unregister_all(cs46xx_pm_callback);
@@ -5757,7 +5735,8 @@
 module_init(cs46xx_init_module);
 module_exit(cs46xx_cleanup_module);
 
-int cs46xx_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *data)
+#ifndef CS46XX_ACPI_SUPPORT
+static int cs46xx_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *data)
 {
 	struct cs_card *card;
 
@@ -5792,6 +5771,7 @@
 
 	return 0;
 }
+#endif
 
 #if CS46XX_ACPI_SUPPORT
 static int cs46xx_suspend_tbl(struct pci_dev *pcidev, u32 state)
diff -Nru a/sound/oss/cs46xx_wrapper-24.h b/sound/oss/cs46xx_wrapper-24.h
--- a/sound/oss/cs46xx_wrapper-24.h	2005-03-01 23:39:07 -08:00
+++ b/sound/oss/cs46xx_wrapper-24.h	2005-03-01 23:39:07 -08:00
@@ -30,7 +30,7 @@
 
 #define CS_OWNER .owner =
 #define CS_THIS_MODULE THIS_MODULE,
-void cs46xx_null(struct pci_dev *pcidev) { return; }
+static inline void cs46xx_null(struct pci_dev *pcidev) { return; }
 #define cs4x_mem_map_reserve(page) SetPageReserved(page)
 #define cs4x_mem_map_unreserve(page) ClearPageReserved(page)
 
diff -Nru a/sound/oss/cs46xxpm-24.h b/sound/oss/cs46xxpm-24.h
--- a/sound/oss/cs46xxpm-24.h	2005-03-01 23:39:16 -08:00
+++ b/sound/oss/cs46xxpm-24.h	2005-03-01 23:39:16 -08:00
@@ -48,6 +48,5 @@
 #define CS46XX_SUSPEND_TBL cs46xx_null
 #define CS46XX_RESUME_TBL cs46xx_null
 #endif
-int cs46xx_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *data);
 
 #endif
diff -Nru a/sound/oss/emu10k1/audio.c b/sound/oss/emu10k1/audio.c
--- a/sound/oss/emu10k1/audio.c	2005-03-01 23:38:52 -08:00
+++ b/sound/oss/emu10k1/audio.c	2005-03-01 23:38:52 -08:00
@@ -49,6 +49,9 @@
 static void calculate_ofrag(struct woinst *);
 static void calculate_ifrag(struct wiinst *);
 
+static void emu10k1_waveout_bh(unsigned long refdata);
+static void emu10k1_wavein_bh(unsigned long refdata);
+
 /* Audio file operations */
 static ssize_t emu10k1_audio_read(struct file *file, char __user *buffer, size_t count, loff_t * ppos)
 {
@@ -1032,7 +1035,7 @@
 	return dmapage;
 }
 
-struct vm_operations_struct emu10k1_mm_ops = {
+static struct vm_operations_struct emu10k1_mm_ops = {
 	.nopage         = emu10k1_mm_nopage,
 };
 
@@ -1191,7 +1194,7 @@
 		wiinst->mmapped = 0;
 		wiinst->total_recorded = 0;
 		wiinst->blocks = 0;
-		wiinst->lock = SPIN_LOCK_UNLOCKED;
+		spin_lock_init(&wiinst->lock);
 		tasklet_init(&wiinst->timer.tasklet, emu10k1_wavein_bh, (unsigned long) wave_dev);
 		wave_dev->wiinst = wiinst;
 		emu10k1_wavein_setformat(wave_dev, &wiinst->format);
@@ -1235,7 +1238,7 @@
 		woinst->total_copied = 0;
 		woinst->total_played = 0;
 		woinst->blocks = 0;
-		woinst->lock = SPIN_LOCK_UNLOCKED;
+		spin_lock_init(&woinst->lock);
 		tasklet_init(&woinst->timer.tasklet, emu10k1_waveout_bh, (unsigned long) wave_dev);
 		wave_dev->woinst = woinst;
 		emu10k1_waveout_setformat(wave_dev, &woinst->format);
@@ -1506,7 +1509,7 @@
 	return;
 }
 
-void emu10k1_wavein_bh(unsigned long refdata)
+static void emu10k1_wavein_bh(unsigned long refdata)
 {
 	struct emu10k1_wavedevice *wave_dev = (struct emu10k1_wavedevice *) refdata;
 	struct wiinst *wiinst = wave_dev->wiinst;
@@ -1537,7 +1540,7 @@
 	return;
 }
 
-void emu10k1_waveout_bh(unsigned long refdata)
+static void emu10k1_waveout_bh(unsigned long refdata)
 {
 	struct emu10k1_wavedevice *wave_dev = (struct emu10k1_wavedevice *) refdata;
 	struct woinst *woinst = wave_dev->woinst;
diff -Nru a/sound/oss/emu10k1/audio.h b/sound/oss/emu10k1/audio.h
--- a/sound/oss/emu10k1/audio.h	2005-03-01 23:39:17 -08:00
+++ b/sound/oss/emu10k1/audio.h	2005-03-01 23:39:17 -08:00
@@ -41,7 +41,4 @@
         u16 enablebits;
 };
 
-void emu10k1_waveout_bh(unsigned long);
-void emu10k1_wavein_bh(unsigned long);
-
 #endif /* _AUDIO_H */
diff -Nru a/sound/oss/emu10k1/cardmi.c b/sound/oss/emu10k1/cardmi.c
--- a/sound/oss/emu10k1/cardmi.c	2005-03-01 23:38:58 -08:00
+++ b/sound/oss/emu10k1/cardmi.c	2005-03-01 23:38:58 -08:00
@@ -38,6 +38,26 @@
 #include "cardmi.h"
 #include "irqmgr.h"
 
+
+static int emu10k1_mpuin_callback(struct emu10k1_mpuin *card_mpuin, u32 msg, unsigned long data, u32 bytesvalid);
+
+static int sblive_miStateInit(struct emu10k1_mpuin *);
+static int sblive_miStateEntry(struct emu10k1_mpuin *, u8);
+static int sblive_miStateParse(struct emu10k1_mpuin *, u8);
+static int sblive_miState3Byte(struct emu10k1_mpuin *, u8);
+static int sblive_miState3ByteKey(struct emu10k1_mpuin *, u8);
+static int sblive_miState3ByteVel(struct emu10k1_mpuin *, u8);
+static int sblive_miState2Byte(struct emu10k1_mpuin *, u8);
+static int sblive_miState2ByteKey(struct emu10k1_mpuin *, u8);
+static int sblive_miStateSysCommon2(struct emu10k1_mpuin *, u8);
+static int sblive_miStateSysCommon2Key(struct emu10k1_mpuin *, u8);
+static int sblive_miStateSysCommon3(struct emu10k1_mpuin *, u8);
+static int sblive_miStateSysCommon3Key(struct emu10k1_mpuin *, u8);
+static int sblive_miStateSysCommon3Vel(struct emu10k1_mpuin *, u8);
+static int sblive_miStateSysExNorm(struct emu10k1_mpuin *, u8);
+static int sblive_miStateSysReal(struct emu10k1_mpuin *, u8);
+
+
 static struct {
 	int (*Fn) (struct emu10k1_mpuin *, u8);
 } midistatefn[] = {
@@ -69,6 +89,7 @@
 	sblive_miStateSysReal}	/* 0xF4 - 0xF6 ,0xF8 - 0xFF     */
 };
 
+
 /* Installs the IRQ handler for the MPU in port                 */
 
 /* and initialize parameters                                    */
@@ -269,7 +290,7 @@
 /* Passes the message with the data back to the client          */
 
 /* via IRQ & DPC callbacks to Ring 3                            */
-int emu10k1_mpuin_callback(struct emu10k1_mpuin *card_mpuin, u32 msg, unsigned long data, u32 bytesvalid)
+static int emu10k1_mpuin_callback(struct emu10k1_mpuin *card_mpuin, u32 msg, unsigned long data, u32 bytesvalid)
 {
 	unsigned long timein;
 	struct midi_queue *midiq;
@@ -374,7 +395,7 @@
 /*****************************************************************************/
 
 /* FIXME: This should be a macro */
-int sblive_miStateInit(struct emu10k1_mpuin *card_mpuin)
+static int sblive_miStateInit(struct emu10k1_mpuin *card_mpuin)
 {
 	card_mpuin->status = 0;	/* For MIDI running status */
 	card_mpuin->fstatus = 0;	/* For 0xFn status only */
@@ -388,12 +409,12 @@
 }
 
 /* FIXME: This should be a macro */
-int sblive_miStateEntry(struct emu10k1_mpuin *card_mpuin, u8 data)
+static int sblive_miStateEntry(struct emu10k1_mpuin *card_mpuin, u8 data)
 {
 	return midistatefn[card_mpuin->curstate].Fn(card_mpuin, data);
 }
 
-int sblive_miStateParse(struct emu10k1_mpuin *card_mpuin, u8 data)
+static int sblive_miStateParse(struct emu10k1_mpuin *card_mpuin, u8 data)
 {
 	switch (data & 0xf0) {
 	case 0x80:
@@ -457,7 +478,7 @@
 	return midistatefn[card_mpuin->curstate].Fn(card_mpuin, data);
 }
 
-int sblive_miState3Byte(struct emu10k1_mpuin *card_mpuin, u8 data)
+static int sblive_miState3Byte(struct emu10k1_mpuin *card_mpuin, u8 data)
 {
 	u8 temp = data & 0xf0;
 
@@ -473,8 +494,7 @@
 	return midistatefn[STIN_PARSE].Fn(card_mpuin, data);
 }
 
-int sblive_miState3ByteKey(struct emu10k1_mpuin *card_mpuin, u8 data)
-
+static int sblive_miState3ByteKey(struct emu10k1_mpuin *card_mpuin, u8 data)
 /* byte 1 */
 {
 	unsigned long tmp;
@@ -502,8 +522,7 @@
 	return CTSTATUS_NEXT_BYTE;
 }
 
-int sblive_miState3ByteVel(struct emu10k1_mpuin *card_mpuin, u8 data)
-
+static int sblive_miState3ByteVel(struct emu10k1_mpuin *card_mpuin, u8 data)
 /* byte 2 */
 {
 	unsigned long tmp;
@@ -539,7 +558,7 @@
 	return 0;
 }
 
-int sblive_miState2Byte(struct emu10k1_mpuin *card_mpuin, u8 data)
+static int sblive_miState2Byte(struct emu10k1_mpuin *card_mpuin, u8 data)
 {
 	u8 temp = data & 0xf0;
 
@@ -556,8 +575,7 @@
 	return midistatefn[STIN_PARSE].Fn(card_mpuin, data);
 }
 
-int sblive_miState2ByteKey(struct emu10k1_mpuin *card_mpuin, u8 data)
-
+static int sblive_miState2ByteKey(struct emu10k1_mpuin *card_mpuin, u8 data)
 /* byte 1 */
 {
 	unsigned long tmp;
@@ -590,7 +608,7 @@
 	return 0;
 }
 
-int sblive_miStateSysCommon2(struct emu10k1_mpuin *card_mpuin, u8 data)
+static int sblive_miStateSysCommon2(struct emu10k1_mpuin *card_mpuin, u8 data)
 {
 	card_mpuin->fstatus = data;
 	card_mpuin->curstate = STIN_SYS_COMMON_2_KEY;
@@ -598,8 +616,7 @@
 	return CTSTATUS_NEXT_BYTE;
 }
 
-int sblive_miStateSysCommon2Key(struct emu10k1_mpuin *card_mpuin, u8 data)
-
+static int sblive_miStateSysCommon2Key(struct emu10k1_mpuin *card_mpuin, u8 data)
 /* byte 1 */
 {
 	unsigned long tmp;
@@ -632,7 +649,7 @@
 	return 0;
 }
 
-int sblive_miStateSysCommon3(struct emu10k1_mpuin *card_mpuin, u8 data)
+static int sblive_miStateSysCommon3(struct emu10k1_mpuin *card_mpuin, u8 data)
 {
 	card_mpuin->fstatus = data;
 	card_mpuin->curstate = STIN_SYS_COMMON_3_KEY;
@@ -640,8 +657,7 @@
 	return CTSTATUS_NEXT_BYTE;
 }
 
-int sblive_miStateSysCommon3Key(struct emu10k1_mpuin *card_mpuin, u8 data)
-
+static int sblive_miStateSysCommon3Key(struct emu10k1_mpuin *card_mpuin, u8 data)
 /* byte 1 */
 {
 	unsigned long tmp;
@@ -670,8 +686,7 @@
 	return CTSTATUS_NEXT_BYTE;
 }
 
-int sblive_miStateSysCommon3Vel(struct emu10k1_mpuin *card_mpuin, u8 data)
-
+static int sblive_miStateSysCommon3Vel(struct emu10k1_mpuin *card_mpuin, u8 data)
 /* byte 2 */
 {
 	unsigned long tmp;
@@ -708,7 +723,7 @@
 	return 0;
 }
 
-int sblive_miStateSysExNorm(struct emu10k1_mpuin *card_mpuin, u8 data)
+static int sblive_miStateSysExNorm(struct emu10k1_mpuin *card_mpuin, u8 data)
 {
 	unsigned long flags;
 
@@ -809,7 +824,7 @@
 	return CTSTATUS_NEXT_BYTE;
 }
 
-int sblive_miStateSysReal(struct emu10k1_mpuin *card_mpuin, u8 data)
+static int sblive_miStateSysReal(struct emu10k1_mpuin *card_mpuin, u8 data)
 {
 	emu10k1_mpuin_callback(card_mpuin, ICARDMIDI_INDATA, data, 1);
 
diff -Nru a/sound/oss/emu10k1/cardmi.h b/sound/oss/emu10k1/cardmi.h
--- a/sound/oss/emu10k1/cardmi.h	2005-03-01 23:39:10 -08:00
+++ b/sound/oss/emu10k1/cardmi.h	2005-03-01 23:39:10 -08:00
@@ -91,24 +91,7 @@
 int emu10k1_mpuin_stop(struct emu10k1_card *);
 int emu10k1_mpuin_reset(struct emu10k1_card *);
 
-int sblive_miStateInit(struct emu10k1_mpuin *);
-int sblive_miStateEntry(struct emu10k1_mpuin *, u8);
-int sblive_miStateParse(struct emu10k1_mpuin *, u8);
-int sblive_miState3Byte(struct emu10k1_mpuin *, u8);
-int sblive_miState3ByteKey(struct emu10k1_mpuin *, u8);
-int sblive_miState3ByteVel(struct emu10k1_mpuin *, u8);
-int sblive_miState2Byte(struct emu10k1_mpuin *, u8);
-int sblive_miState2ByteKey(struct emu10k1_mpuin *, u8);
-int sblive_miStateSysCommon2(struct emu10k1_mpuin *, u8);
-int sblive_miStateSysCommon2Key(struct emu10k1_mpuin *, u8);
-int sblive_miStateSysCommon3(struct emu10k1_mpuin *, u8);
-int sblive_miStateSysCommon3Key(struct emu10k1_mpuin *, u8);
-int sblive_miStateSysCommon3Vel(struct emu10k1_mpuin *, u8);
-int sblive_miStateSysExNorm(struct emu10k1_mpuin *, u8);
-int sblive_miStateSysReal(struct emu10k1_mpuin *, u8);
-
 int emu10k1_mpuin_irqhandler(struct emu10k1_card *);
 void emu10k1_mpuin_bh(unsigned long);
-int emu10k1_mpuin_callback(struct emu10k1_mpuin *card_mpuin, u32 msg, unsigned long data, u32 bytesvalid);
 
 #endif  /* _CARDMI_H */
diff -Nru a/sound/oss/emu10k1/cardwi.c b/sound/oss/emu10k1/cardwi.c
--- a/sound/oss/emu10k1/cardwi.c	2005-03-01 23:39:07 -08:00
+++ b/sound/oss/emu10k1/cardwi.c	2005-03-01 23:39:07 -08:00
@@ -42,7 +42,7 @@
  * This function will return a valid sound format as close
  * to the requested one as possible. 
  */
-void query_format(int recsrc, struct wave_format *wave_fmt)
+static void query_format(int recsrc, struct wave_format *wave_fmt)
 {
 
 	switch (recsrc) {
diff -Nru a/sound/oss/emu10k1/efxmgr.c b/sound/oss/emu10k1/efxmgr.c
--- a/sound/oss/emu10k1/efxmgr.c	2005-03-01 23:38:52 -08:00
+++ b/sound/oss/emu10k1/efxmgr.c	2005-03-01 23:38:52 -08:00
@@ -101,8 +101,8 @@
 #define VOLCTRL_STEP_SIZE        5
 
 //An internal function for setting OSS mixer controls.
-void emu10k1_set_oss_vol(struct emu10k1_card *card, int oss_mixer,
-			 unsigned int left, unsigned int right)
+static void emu10k1_set_oss_vol(struct emu10k1_card *card, int oss_mixer,
+				unsigned int left, unsigned int right)
 {
 	extern char volume_params[SOUND_MIXER_NRDEVICES];
 
diff -Nru a/sound/oss/emu10k1/hwaccess.c b/sound/oss/emu10k1/hwaccess.c
--- a/sound/oss/emu10k1/hwaccess.c	2005-03-01 23:38:54 -08:00
+++ b/sound/oss/emu10k1/hwaccess.c	2005-03-01 23:38:54 -08:00
@@ -105,31 +105,6 @@
 	return 0;		/* Should never reach this point */
 }
 
-/* Returns an attenuation based upon a cumulative volume value */
-
-/* Algorithm calculates 0x200 - 0x10 log2 (input) */
-u8 sumVolumeToAttenuation(u32 value)
-{
-	u16 count = 16;
-	s16 ans;
-
-	if (value == 0)
-		return 0xFF;
-
-	/* Find first SET bit. This is the integer part of the value */
-	while ((value & 0x10000) == 0) {
-		value <<= 1;
-		count--;
-	}
-
-	/* The REST of the data is the fractional part. */
-	ans = (s16) (0x110 - ((count << 4) + ((value & 0x0FFFFL) >> 12)));
-	if (ans > 0xFF)
-		ans = 0xFF;
-
-	return (u8) ans;
-}
-
 /*******************************************
 * write/read PCI function 0 registers      *
 ********************************************/
@@ -160,6 +135,7 @@
 	return;
 }
 
+#ifdef DBGEMU
 void emu10k1_writefn0_2(struct emu10k1_card *card, u32 reg, u32 data, int size)
 {
 	unsigned long flags;
@@ -177,6 +153,7 @@
 
 	return;
 }
+#endif  /*  DBGEMU  */
 
 u32 emu10k1_readfn0(struct emu10k1_card * card, u32 reg)
 {
@@ -338,17 +315,6 @@
         outl(val, card->iobase + INTE);
         spin_unlock_irqrestore(&card->lock, flags);
         return;
-}
-
-void emu10k1_set_stop_on_loop(struct emu10k1_card *card, u32 voicenum)
-{
-	/* Voice interrupt */
-	if (voicenum >= 32)
-		sblive_writeptr(card, SOLEH | ((0x0100 | (voicenum - 32)) << 16), 0, 1);
-	else
-		sblive_writeptr(card, SOLEL | ((0x0100 | voicenum) << 16), 0, 1);
-
-	return;
 }
 
 void emu10k1_clear_stop_on_loop(struct emu10k1_card *card, u32 voicenum)
diff -Nru a/sound/oss/emu10k1/hwaccess.h b/sound/oss/emu10k1/hwaccess.h
--- a/sound/oss/emu10k1/hwaccess.h	2005-03-01 23:39:18 -08:00
+++ b/sound/oss/emu10k1/hwaccess.h	2005-03-01 23:39:18 -08:00
@@ -212,7 +212,6 @@
 #define TIMEOUT 		    16384
 
 u32 srToPitch(u32);
-u8 sumVolumeToAttenuation(u32);
 
 extern struct list_head emu10k1_devs;
 
@@ -232,7 +231,6 @@
 
 void emu10k1_irq_enable(struct emu10k1_card *, u32);
 void emu10k1_irq_disable(struct emu10k1_card *, u32);
-void emu10k1_set_stop_on_loop(struct emu10k1_card *, u32);
 void emu10k1_clear_stop_on_loop(struct emu10k1_card *, u32);
 
 /* AC97 Codec register access function */
diff -Nru a/sound/oss/emu10k1/main.c b/sound/oss/emu10k1/main.c
--- a/sound/oss/emu10k1/main.c	2005-03-01 23:39:17 -08:00
+++ b/sound/oss/emu10k1/main.c	2005-03-01 23:39:17 -08:00
@@ -309,8 +309,8 @@
 	unregister_sound_dsp(card->audio_dev);
 }
 
-int emu10k1_info_proc (char *page, char **start, off_t off,
-		    int count, int *eof, void *data)
+static int emu10k1_info_proc (char *page, char **start, off_t off,
+			      int count, int *eof, void *data)
 {
 	struct emu10k1_card *card = data;
 	int len = 0;
@@ -524,7 +524,7 @@
 {
 	INIT_LIST_HEAD(&card->timers);
 	card->timer_delay = TIMER_STOPPED;
-	card->timer_lock = SPIN_LOCK_UNLOCKED;
+	spin_lock_init(&card->timer_lock);
 }
 
 static void __devinit addxmgr_init(struct emu10k1_card *card)
@@ -873,7 +873,7 @@
 		sblive_writeptr(card, DBG, 0, 0);
 	}
 
-	mgr->lock = SPIN_LOCK_UNLOCKED;
+	spin_lock_init(&mgr->lock);
 
 	// Set up Volume controls, try to keep this the same for both Audigy and Live
 
diff -Nru a/sound/oss/emu10k1/midi.c b/sound/oss/emu10k1/midi.c
--- a/sound/oss/emu10k1/midi.c	2005-03-01 23:39:17 -08:00
+++ b/sound/oss/emu10k1/midi.c	2005-03-01 23:39:17 -08:00
@@ -45,7 +45,7 @@
 #include "../sound_config.h"
 #endif
 
-static spinlock_t midi_spinlock __attribute((unused)) = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(midi_spinlock __attribute((unused)));
 
 static void init_midi_hdr(struct midi_hdr *midihdr)
 {
diff -Nru a/sound/oss/emu10k1/voicemgr.c b/sound/oss/emu10k1/voicemgr.c
--- a/sound/oss/emu10k1/voicemgr.c	2005-03-01 23:39:18 -08:00
+++ b/sound/oss/emu10k1/voicemgr.c	2005-03-01 23:39:18 -08:00
@@ -39,7 +39,8 @@
 #define PITCH_67882 0x00005a82
 #define PITCH_57081 0x00004c1c
 
-u32 emu10k1_select_interprom(struct emu10k1_card *card, struct emu_voice *voice)
+static u32 emu10k1_select_interprom(struct emu10k1_card *card,
+				    struct emu_voice *voice)
 {
 	if(voice->pitch_target==PITCH_48000)
 		return CCCA_INTERPROM_0;
diff -Nru a/sound/oss/es1370.c b/sound/oss/es1370.c
--- a/sound/oss/es1370.c	2005-03-01 23:39:17 -08:00
+++ b/sound/oss/es1370.c	2005-03-01 23:39:17 -08:00
@@ -2525,9 +2525,9 @@
 
 static unsigned int devindex;
 
-MODULE_PARM(lineout, "1-" __MODULE_STRING(NR_DEVICE) "i");
+module_param_array(lineout, bool, NULL, 0);
 MODULE_PARM_DESC(lineout, "if 1 the LINE input is converted to LINE out");
-MODULE_PARM(micbias, "1-" __MODULE_STRING(NR_DEVICE) "i");
+module_param_array(micbias, bool, NULL, 0);
 MODULE_PARM_DESC(micbias, "sets the +5V bias for an electret microphone");
 
 MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu");
diff -Nru a/sound/oss/es1371.c b/sound/oss/es1371.c
--- a/sound/oss/es1371.c	2005-03-01 23:39:08 -08:00
+++ b/sound/oss/es1371.c	2005-03-01 23:39:08 -08:00
@@ -2741,11 +2741,11 @@
 
 static unsigned int devindex;
 
-MODULE_PARM(spdif, "1-" __MODULE_STRING(NR_DEVICE) "i");
+module_param_array(spdif, bool, NULL, 0);
 MODULE_PARM_DESC(spdif, "if 1 the output is in S/PDIF digital mode");
-MODULE_PARM(nomix, "1-" __MODULE_STRING(NR_DEVICE) "i");
+module_param_array(nomix, bool, NULL, 0);
 MODULE_PARM_DESC(nomix, "if 1 no analog audio is mixed to the digital output");
-MODULE_PARM(amplifier, "1-" __MODULE_STRING(NR_DEVICE) "i");
+module_param_array(amplifier, bool, NULL, 0);
 MODULE_PARM_DESC(amplifier, "Set to 1 if the machine needs the amp control enabling (many laptops)");
 
 MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu");
diff -Nru a/sound/oss/forte.c b/sound/oss/forte.c
--- a/sound/oss/forte.c	2005-03-01 23:38:55 -08:00
+++ b/sound/oss/forte.c	2005-03-01 23:38:55 -08:00
@@ -238,7 +238,7 @@
  * @reg:	register to read
  */
 
-u16
+static u16
 forte_ac97_read (struct ac97_codec *codec, u8 reg)
 {
 	u16 ret = 0;
@@ -283,7 +283,7 @@
  * @val:	value to write
  */
 
-void
+static void
 forte_ac97_write (struct ac97_codec *codec, u8 reg, u16 val)
 {
 	struct forte_chip *chip = codec->private_data;
diff -Nru a/sound/oss/gus_card.c b/sound/oss/gus_card.c
--- a/sound/oss/gus_card.c	2005-03-01 23:38:43 -08:00
+++ b/sound/oss/gus_card.c	2005-03-01 23:38:43 -08:00
@@ -218,17 +218,17 @@
 static int __initdata dma16 = -1;	/* Set this for modules that need it */
 static int __initdata type = 0;		/* 1 for PnP */
 
-MODULE_PARM(io, "i");
-MODULE_PARM(irq, "i");
-MODULE_PARM(dma, "i");
-MODULE_PARM(dma16, "i");
-MODULE_PARM(type, "i");
+module_param(io, int, 0);
+module_param(irq, int, 0);
+module_param(dma, int, 0);
+module_param(dma16, int, 0);
+module_param(type, int, 0);
 #ifdef CONFIG_SOUND_GUSMAX
-MODULE_PARM(no_wave_dma, "i");
+module_param(no_wave_dma, int, 0);
 #endif
 #ifdef CONFIG_SOUND_GUS16
-MODULE_PARM(db16, "i");
-MODULE_PARM(gus16, "i");
+module_param(db16, int, 0);
+module_param(gus16, int, 0);
 #endif
 MODULE_LICENSE("GPL");
 
diff -Nru a/sound/oss/gus_wave.c b/sound/oss/gus_wave.c
--- a/sound/oss/gus_wave.c	2005-03-01 23:39:18 -08:00
+++ b/sound/oss/gus_wave.c	2005-03-01 23:39:18 -08:00
@@ -94,7 +94,7 @@
 static int      only_read_access;
 static int      only_8_bits;
 
-int             iw_mode = 0;
+static int      iw_mode = 0;
 int             gus_wave_volume = 60;
 int             gus_pcm_volume = 80;
 int             have_gus_max = 0;
@@ -139,7 +139,7 @@
 static unsigned long pcm_current_buf;
 static int      pcm_current_count;
 static int      pcm_current_intrflag;
-spinlock_t gus_lock=SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(gus_lock);
 
 extern int     *gus_osp;
 
diff -Nru a/sound/oss/i810_audio.c b/sound/oss/i810_audio.c
--- a/sound/oss/i810_audio.c	2005-03-01 23:39:08 -08:00
+++ b/sound/oss/i810_audio.c	2005-03-01 23:39:08 -08:00
@@ -111,6 +111,7 @@
 static int strict_clocking;
 static unsigned int clocking;
 static int spdif_locked;
+static int ac97_quirk = AC97_TUNE_DEFAULT;
 
 //#define DEBUG
 //#define DEBUG2
@@ -481,6 +482,124 @@
 #define CIV_TO_LVI(card, port, off) \
 	I810_IOWRITEB(MODULOP2(GET_CIV((card), (port)) + (off), SG_LEN), (card), (port) + OFF_LVI)
 
+static struct ac97_quirk ac97_quirks[] __devinitdata = {
+	{
+		.vendor = 0x0e11,
+		.device = 0x00b8,
+		.name = "Compaq Evo D510C",
+		.type = AC97_TUNE_HP_ONLY
+	},
+	{
+		.vendor = 0x1028,
+		.device = 0x00d8,
+		.name = "Dell Precision 530",   /* AD1885 */
+		.type = AC97_TUNE_HP_ONLY
+	},
+	{
+		.vendor = 0x1028,
+		.device = 0x0126,
+		.name = "Dell Optiplex GX260",  /* AD1981A */
+		.type = AC97_TUNE_HP_ONLY
+	},
+	{
+		.vendor = 0x1028,
+		.device = 0x012d,
+		.name = "Dell Precision 450",   /* AD1981B*/
+		.type = AC97_TUNE_HP_ONLY
+	},
+	{       /* FIXME: which codec? */
+		.vendor = 0x103c,
+		.device = 0x00c3,
+		.name = "Hewlett-Packard onboard",
+		.type = AC97_TUNE_HP_ONLY
+	},
+	{
+		.vendor = 0x103c,
+		.device = 0x12f1,
+		.name = "HP xw8200",    /* AD1981B*/
+		.type = AC97_TUNE_HP_ONLY
+	},
+	{
+		.vendor = 0x103c,
+		.device = 0x3008,
+		.name = "HP xw4200",    /* AD1981B*/
+		.type = AC97_TUNE_HP_ONLY
+	},
+	{
+		.vendor = 0x10f1,
+		.device = 0x2665,
+		.name = "Fujitsu-Siemens Celsius",      /* AD1981? */
+		.type = AC97_TUNE_HP_ONLY
+	},
+	{
+		.vendor = 0x10f1,
+		.device = 0x2885,
+		.name = "AMD64 Mobo",   /* ALC650 */
+		.type = AC97_TUNE_HP_ONLY
+	},
+	{
+		.vendor = 0x110a,
+		.device = 0x0056,
+		.name = "Fujitsu-Siemens Scenic",       /* AD1981? */
+		.type = AC97_TUNE_HP_ONLY
+	},
+	{
+		.vendor = 0x11d4,
+		.device = 0x5375,
+		.name = "ADI AD1985 (discrete)",
+		.type = AC97_TUNE_HP_ONLY
+	},
+	{
+		.vendor = 0x1462,
+		.device = 0x5470,
+		.name = "MSI P4 ATX 645 Ultra",
+		.type = AC97_TUNE_HP_ONLY
+	},
+	{
+		.vendor = 0x1734,
+		.device = 0x0088,
+		.name = "Fujitsu-Siemens D1522",	/* AD1981 */
+		.type = AC97_TUNE_HP_ONLY
+	},
+	{
+		.vendor = 0x8086,
+		.device = 0x4856,
+		.name = "Intel D845WN (82801BA)",
+		.type = AC97_TUNE_SWAP_HP
+	},
+	{
+		.vendor = 0x8086,
+		.device = 0x4d44,
+		.name = "Intel D850EMV2",       /* AD1885 */
+		.type = AC97_TUNE_HP_ONLY
+	},
+	{
+		.vendor = 0x8086,
+		.device = 0x4d56,
+		.name = "Intel ICH/AD1885",
+		.type = AC97_TUNE_HP_ONLY
+	},
+	{
+		.vendor = 0x1028,
+		.device = 0x012d,
+		.name = "Dell Precision 450",   /* AD1981B*/
+		.type = AC97_TUNE_HP_ONLY
+	},
+	{
+		.vendor = 0x103c,
+		.device = 0x3008,
+		.name = "HP xw4200",    /* AD1981B*/
+		.type = AC97_TUNE_HP_ONLY
+	},
+	{
+		.vendor = 0x103c,
+		.device = 0x12f1,
+		.name = "HP xw8200",    /* AD1981B*/
+		.type = AC97_TUNE_HP_ONLY
+	},
+	{ } /* terminator */
+};
+
 static struct i810_card *devs = NULL;
 
 static int i810_open_mixdev(struct inode *inode, struct file *file);
@@ -1077,10 +1196,23 @@
 	if (count < fragsize)
 		return;
 
+	/* if we are currently stopped, then our CIV is actually set to our
+	 * *last* sg segment and we are ready to wrap to the next.  However,
+	 * if we set our LVI to the last sg segment, then it won't wrap to
+	 * the next sg segment, it won't even get a start.  So, instead, when
+	 * we are stopped, we set both the LVI value and also we increment
+	 * the CIV value to the next sg segment to be played so that when
+	 * we call start, things will operate properly.  Since the CIV can't
+	 * be written to directly for this purpose, we set the LVI to CIV + 1
+	 * temporarily.  Once the engine has started we set the LVI to its
+	 * final value.
+	 */
 	if (!dmabuf->enable && dmabuf->ready) {
 		if (!(dmabuf->trigger & trigger))
 			return;
 
+		CIV_TO_LVI(state->card, port, 1);
+
 		start(state);
 		while (!(I810_IOREADB(state->card, port + OFF_CR) & ((1<<4) | (1<<2))))
 			;
@@ -3043,6 +3175,9 @@
 		card->ac97_codec[num_ac97] = codec;
 	}
 
+	/* tune up the primary codec */
+	ac97_tune_hardware(card->pci_dev, ac97_quirks, ac97_quirk);
+
 	/* pick the minimum of channels supported by ICHx or codec(s) */
 	card->channels = (card->channels > total_channels)?total_channels:card->channels;
 
@@ -3460,15 +3595,15 @@
 }	
 #endif /* CONFIG_PM */
 
-MODULE_AUTHOR("");
+MODULE_AUTHOR("The Linux kernel team");
 MODULE_DESCRIPTION("Intel 810 audio support");
 MODULE_LICENSE("GPL");
-MODULE_PARM(ftsodell, "i");
-MODULE_PARM(clocking, "i");
-MODULE_PARM(strict_clocking, "i");
-MODULE_PARM(spdif_locked, "i");
+module_param(ftsodell, int, 0444);
+module_param(clocking, uint, 0444);
+module_param(strict_clocking, int, 0444);
+module_param(spdif_locked, int, 0444);
 
-#define I810_MODULE_NAME "intel810_audio"
+#define I810_MODULE_NAME "i810_audio"
 
 static struct pci_driver i810_pci_driver = {
 	.name		= I810_MODULE_NAME,
diff -Nru a/sound/oss/ite8172.c b/sound/oss/ite8172.c
--- a/sound/oss/ite8172.c	2005-03-01 23:38:53 -08:00
+++ b/sound/oss/ite8172.c	2005-03-01 23:38:53 -08:00
@@ -96,6 +96,19 @@
 #define warn(format, arg...) printk(KERN_WARNING PFX ": " format "\n" , ## arg)
 
 
+#define IT8172_MODULE_NAME "IT8172 audio"
+#define PFX IT8172_MODULE_NAME
+
+#ifdef IT8172_DEBUG
+#define dbg(format, arg...) printk(KERN_DEBUG PFX ": " format "\n" , ## arg)
+#else
+#define dbg(format, arg...) do {} while (0)
+#endif
+#define err(format, arg...) printk(KERN_ERR PFX ": " format "\n" , ## arg)
+#define info(format, arg...) printk(KERN_INFO PFX ": " format "\n" , ## arg)
+#define warn(format, arg...) printk(KERN_WARNING PFX ": " format "\n" , ## arg)
+
+
 static const unsigned sample_shift[] = { 0, 1, 1, 2 };
 
 
@@ -285,7 +298,7 @@
 	struct proc_dir_entry *ac97_ps;
 #endif /* IT8172_DEBUG */
 
-	struct ac97_codec *codec;
+	struct ac97_codec codec;
 
 	unsigned short pcc, capcc;
 	unsigned dacrate, adcrate;
@@ -664,7 +677,7 @@
 		pend = virt_to_page(db->rawbuf +
 				    (PAGE_SIZE << db->buforder) - 1);
 		for (page = virt_to_page(db->rawbuf); page <= pend; page++)
-			mem_map_unreserve(page);
+			ClearPageReserved(page);
 		pci_free_consistent(s->dev, PAGE_SIZE << db->buforder,
 				    db->rawbuf, db->dmaaddr);
 	}
@@ -697,7 +710,7 @@
 		pend = virt_to_page(db->rawbuf +
 				    (PAGE_SIZE << db->buforder) - 1);
 		for (page = virt_to_page(db->rawbuf); page <= pend; page++)
-			mem_map_reserve(page);
+			SetPageReserved(page);
 	}
 
 	db->count = 0;
@@ -858,12 +871,6 @@
 
 /* --------------------------------------------------------------------- */
 
-static loff_t it8172_llseek(struct file *file, loff_t offset, int origin)
-{
-	return -ESPIPE;
-}
-
-
 static int it8172_open_mixdev(struct inode *inode, struct file *file)
 {
 	int minor = iminor(inode);
@@ -874,7 +881,7 @@
 		if (list == &devs)
 			return -ENODEV;
 		s = list_entry(list, struct it8172_state, devs);
-		if (s->codec->dev_mixer == minor)
+		if (s->codec.dev_mixer == minor)
 			break;
 	}
 	file->private_data = s;
@@ -998,14 +1005,14 @@
 			       unsigned int cmd, unsigned long arg)
 {
 	struct it8172_state *s = (struct it8172_state *)file->private_data;
-	struct ac97_codec *codec = s->codec;
+	struct ac97_codec *codec = &s->codec;
 
 	return mixdev_ioctl(codec, cmd, arg);
 }
 
 static /*const*/ struct file_operations it8172_mixer_fops = {
 	.owner		= THIS_MODULE,
-	.llseek		= it8172_llseek,
+	.llseek		= no_llseek,
 	.ioctl		= it8172_ioctl_mixdev,
 	.open		= it8172_open_mixdev,
 	.release	= it8172_release_mixdev,
@@ -1409,14 +1416,14 @@
 	case SNDCTL_DSP_RESET:
 		if (file->f_mode & FMODE_WRITE) {
 			stop_dac(s);
-			synchronize_irq();
+			synchronize_irq(s->irq);
 			s->dma_dac.count = s->dma_dac.total_bytes = 0;
 			s->dma_dac.nextIn = s->dma_dac.nextOut =
 				s->dma_dac.rawbuf;
 		}
 		if (file->f_mode & FMODE_READ) {
 			stop_adc(s);
-			synchronize_irq();
+			synchronize_irq(s->irq);
 			s->dma_adc.count = s->dma_adc.total_bytes = 0;
 			s->dma_adc.nextIn = s->dma_adc.nextOut =
 				s->dma_adc.rawbuf;
@@ -1651,7 +1658,9 @@
 		if (count < 0)
 			count = 0;
 		cinfo.blocks = count >> s->dma_adc.fragshift;
-		return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
+		if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
+			return -EFAULT;
+		return 0;
 
 	case SNDCTL_DSP_GETOPTR:
 		if (!(file->f_mode & FMODE_READ))
@@ -1674,7 +1683,9 @@
 		if (count < 0)
 			count = 0;
 		cinfo.blocks = count >> s->dma_dac.fragshift;
-		return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
+		if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
+			return -EFAULT;
+		return 0;
 
 	case SNDCTL_DSP_GETBLKSIZE:
 		if (file->f_mode & FMODE_WRITE)
@@ -1761,7 +1772,7 @@
 		return -EINVAL;
 	}
 
-	return mixdev_ioctl(s->codec, cmd, arg);
+	return mixdev_ioctl(&s->codec, cmd, arg);
 }
 
 
@@ -1871,7 +1882,7 @@
 
 static /*const*/ struct file_operations it8172_audio_fops = {
 	.owner		= THIS_MODULE,
-	.llseek		= it8172_llseek,
+	.llseek		= no_llseek,
 	.read		= it8172_read,
 	.write		= it8172_write,
 	.poll		= it8172_poll,
@@ -1929,7 +1940,7 @@
 	len += sprintf (buf + len, "----------------------\n");
 	for (cnt=0; cnt <= 0x7e; cnt = cnt +2)
 		len+= sprintf (buf + len, "reg %02x = %04x\n",
-			       cnt, rdcodec(s->codec, cnt));
+			       cnt, rdcodec(&s->codec, cnt));
 
 	if (fpos >=len){
 		*start = buf;
@@ -1994,16 +2005,11 @@
 	s->vendor = pcidev->vendor;
 	s->device = pcidev->device;
 	pci_read_config_byte(pcidev, PCI_REVISION_ID, &s->rev);
-	
-	s->codec = ac97_alloc_codec();
-	if(s->codec == NULL)
-		goto err_codec;
-		
-	s->codec->private_data = s;
-	s->codec->id = 0;
-	s->codec->codec_read = rdcodec;
-	s->codec->codec_write = wrcodec;
-	s->codec->codec_wait = waitcodec;
+	s->codec.private_data = s;
+	s->codec.id = 0;
+	s->codec.codec_read = rdcodec;
+	s->codec.codec_write = wrcodec;
+	s->codec.codec_wait = waitcodec;
 
 	if (!request_region(s->io, pci_resource_len(pcidev,0),
 			    IT8172_MODULE_NAME)) {
@@ -2022,12 +2028,12 @@
 	/* register devices */
 	if ((s->dev_audio = register_sound_dsp(&it8172_audio_fops, -1)) < 0)
 		goto err_dev1;
-	if ((s->codec->dev_mixer =
+	if ((s->codec.dev_mixer =
 	     register_sound_mixer(&it8172_mixer_fops, -1)) < 0)
 		goto err_dev2;
 
 #ifdef IT8172_DEBUG
-	/* intialize the debug proc device */
+	/* initialize the debug proc device */
 	s->ps = create_proc_read_entry(IT8172_MODULE_NAME, 0, NULL,
 				       proc_it8172_dump, NULL);
 #endif /* IT8172_DEBUG */
@@ -2093,11 +2099,11 @@
 	outw(0, s->io+IT_AC_CODECC);
     
 	/* codec init */
-	if (!ac97_probe_codec(s->codec))
+	if (!ac97_probe_codec(&s->codec))
 		goto err_dev3;
 
 	/* add I2S as allowable recording source */
-	s->codec->record_sources |= SOUND_MASK_I2S;
+	s->codec.record_sources |= SOUND_MASK_I2S;
 	
 	/* Enable Volume button interrupts */
 	imc = inb(s->io+IT_AC_IMC);
@@ -2117,23 +2123,23 @@
 
 	/* set mic to be the recording source */
 	val = SOUND_MASK_MIC;
-	mixdev_ioctl(s->codec, SOUND_MIXER_WRITE_RECSRC,
+	mixdev_ioctl(&s->codec, SOUND_MIXER_WRITE_RECSRC,
 		     (unsigned long)&val);
 
 	/* mute AC'97 master and PCM when in S/PDIF mode */
 	if (s->spdif_volume != -1) {
 		val = 0x0000;
-		s->codec->mixer_ioctl(s->codec, SOUND_MIXER_WRITE_VOLUME,
+		s->codec.mixer_ioctl(&s->codec, SOUND_MIXER_WRITE_VOLUME,
 				     (unsigned long)&val);
-		s->codec->mixer_ioctl(s->codec, SOUND_MIXER_WRITE_PCM,
+		s->codec.mixer_ioctl(&s->codec, SOUND_MIXER_WRITE_PCM,
 				     (unsigned long)&val);
 	}
     
 #ifdef IT8172_DEBUG
 	sprintf(proc_str, "driver/%s/%d/ac97", IT8172_MODULE_NAME,
-		s->codec->id);
+		s->codec.id);
 	s->ac97_ps = create_proc_read_entry (proc_str, 0, NULL,
-					     ac97_read_proc, s->codec);
+					     ac97_read_proc, &s->codec);
 #endif
     
 	/* store it in the driver field */
@@ -2147,7 +2153,7 @@
 	return 0;
 
  err_dev3:
-	unregister_sound_mixer(s->codec->dev_mixer);
+	unregister_sound_mixer(s->codec.dev_mixer);
  err_dev2:
 	unregister_sound_dsp(s->dev_audio);
  err_dev1:
@@ -2156,8 +2162,6 @@
  err_irq:
 	release_region(s->io, pci_resource_len(pcidev,0));
  err_region:
- 	ac97_release_codec(s->codec);
- err_codec:
 	kfree(s);
 	return -1;
 }
@@ -2173,12 +2177,11 @@
 	if (s->ps)
 		remove_proc_entry(IT8172_MODULE_NAME, NULL);
 #endif /* IT8172_DEBUG */
-	synchronize_irq();
+	synchronize_irq(s->irq);
 	free_irq(s->irq, s);
 	release_region(s->io, pci_resource_len(dev,0));
 	unregister_sound_dsp(s->dev_audio);
-	unregister_sound_mixer(s->codec->dev_mixer);
-	ac97_codec_release(s->codec);
+	unregister_sound_mixer(s->codec.dev_mixer);
 	kfree(s);
 	pci_set_drvdata(dev, NULL);
 }
@@ -2202,8 +2205,6 @@
 
 static int __init init_it8172(void)
 {
-	if (!pci_present())   /* No PCI bus in this machine! */
-		return -ENODEV;
 	info("version v0.5 time " __TIME__ " " __DATE__);
 	return pci_module_init(&it8172_driver);
 }
diff -Nru a/sound/oss/mad16.c b/sound/oss/mad16.c
--- a/sound/oss/mad16.c	2005-03-01 23:39:08 -08:00
+++ b/sound/oss/mad16.c	2005-03-01 23:39:08 -08:00
@@ -53,7 +53,7 @@
 static int      mad16_conf;
 static int      mad16_cdsel;
 static struct gameport gameport;
-static spinlock_t lock=SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(lock);
 
 #define C928	1
 #define MOZART	2
@@ -874,19 +874,19 @@
 static int __initdata opl4 = 0;
 static int __initdata joystick = 0;
 
-MODULE_PARM(mpu_io, "i");
-MODULE_PARM(mpu_irq, "i");
-MODULE_PARM(io,"i");
-MODULE_PARM(dma,"i");
-MODULE_PARM(dma16,"i");
-MODULE_PARM(irq,"i");
-MODULE_PARM(cdtype,"i");
-MODULE_PARM(cdirq,"i");
-MODULE_PARM(cdport,"i");
-MODULE_PARM(cddma,"i");
-MODULE_PARM(opl4,"i");
-MODULE_PARM(joystick,"i");
-MODULE_PARM(debug,"i");
+module_param(mpu_io, int, 0);
+module_param(mpu_irq, int, 0);
+module_param(io, int, 0);
+module_param(dma, int, 0);
+module_param(dma16, int, 0);
+module_param(irq, int, 0);
+module_param(cdtype, int, 0);
+module_param(cdirq, int, 0);
+module_param(cdport, int, 0);
+module_param(cddma, int, 0);
+module_param(opl4, int, 0);
+module_param(joystick, bool, 0);
+module_param(debug, bool, 0644);
 
 static int __initdata dma_map[2][8] =
 {
diff -Nru a/sound/oss/maestro.c b/sound/oss/maestro.c
--- a/sound/oss/maestro.c	2005-03-01 23:39:09 -08:00
+++ b/sound/oss/maestro.c	2005-03-01 23:39:09 -08:00
@@ -262,11 +262,11 @@
 MODULE_LICENSE("GPL");
 
 #ifdef M_DEBUG
-MODULE_PARM(debug,"i");
+module_param(debug, bool, 0644);
 #endif
-MODULE_PARM(dsps_order,"i");
-MODULE_PARM(use_pm,"i");
-MODULE_PARM(clocking, "i");
+module_param(dsps_order, int, 0);
+module_param(use_pm, int, 0);
+module_param(clocking, int, 0);
 
 /* --------------------------------------------------------------------- */
 #define DRIVER_VERSION "0.15"
@@ -344,7 +344,7 @@
 
 /* these masks indicate which units we care about at
 	which states */
-u16 acpi_state_mask[] = {
+static u16 acpi_state_mask[] = {
 	[ACPI_D0] = ACPI_ALL,
 	[ACPI_D1] = ACPI_SLEEP,
 	[ACPI_D2] = ACPI_SLEEP,
@@ -610,7 +610,7 @@
 	be sure to fill it in if you add oss mixers
 	to anyone's supported mixer defines */
 
- unsigned int mixer_defaults[SOUND_MIXER_NRDEVICES] = {
+static unsigned int mixer_defaults[SOUND_MIXER_NRDEVICES] = {
 	[SOUND_MIXER_VOLUME] =          0x3232,
 	[SOUND_MIXER_BASS] =            0x3232,
 	[SOUND_MIXER_TREBLE] =          0x3232,
@@ -3363,7 +3363,7 @@
 /* this guy tries to find the pci power management
  * register bank.  this should really be in core
  * code somewhere.  1 on success. */
-int
+static int
 parse_power(struct ess_card *card, struct pci_dev *pcidev)
 {
 	u32 n;
@@ -3629,7 +3629,7 @@
 	.remove	  = maestro_remove,
 };
 
-int __init init_maestro(void)
+static int __init init_maestro(void)
 {
 	int rc;
 
@@ -3666,7 +3666,7 @@
 /* --------------------------------------------------------------------- */
 
 
-void cleanup_maestro(void) {
+static void cleanup_maestro(void) {
 	M_printk("maestro: unloading\n");
 	pci_unregister_driver(&maestro_pci_driver);
 	pm_unregister_all(maestro_pm_callback);
diff -Nru a/sound/oss/maestro3.c b/sound/oss/maestro3.c
--- a/sound/oss/maestro3.c	2005-03-01 23:39:10 -08:00
+++ b/sound/oss/maestro3.c	2005-03-01 23:39:10 -08:00
@@ -378,7 +378,7 @@
 static int m3_suspend(struct pci_dev *pci_dev, u32 state);
 static void check_suspend(struct m3_card *card);
 
-struct notifier_block m3_reboot_nb = {
+static struct notifier_block m3_reboot_nb = {
 	.notifier_call = m3_notifier,
 };
 
@@ -1024,8 +1024,8 @@
     DPRINTK(DPINT,"set_dmac??\n");
 }
 
-u32 get_dma_pos(struct m3_card *card,
-        int instance_addr)
+static u32 get_dma_pos(struct m3_card *card,
+		       int instance_addr)
 {
     u16 hi = 0, lo = 0;
     int retry = 10;
@@ -1047,7 +1047,7 @@
     return lo | (hi<<16);
 }
 
-u32 get_dmaa(struct m3_state *s)
+static u32 get_dmaa(struct m3_state *s)
 {
     u32 offset;
 
@@ -1059,7 +1059,7 @@
     return offset;
 }
 
-u32 get_dmac(struct m3_state *s)
+static u32 get_dmac(struct m3_state *s)
 {
     u32 offset;
 
@@ -2102,7 +2102,7 @@
     return i == 0;
 }
 
-u16 m3_ac97_read(struct ac97_codec *codec, u8 reg)
+static u16 m3_ac97_read(struct ac97_codec *codec, u8 reg)
 {
     u16 ret = 0;
     struct m3_card *card = codec->private_data;
@@ -2129,7 +2129,7 @@
     return ret;
 }
 
-void m3_ac97_write(struct ac97_codec *codec, u8 reg, u16 val)
+static void m3_ac97_write(struct ac97_codec *codec, u8 reg, u16 val)
 {
     struct m3_card *card = codec->private_data;
 
@@ -2187,7 +2187,7 @@
 	.release = m3_release_mixdev,
 };
 
-void remote_codec_config(int io, int isremote)
+static void remote_codec_config(int io, int isremote)
 {
     isremote = isremote ? 1 : 0;
 
@@ -2571,7 +2571,7 @@
 };
 
 #ifdef CONFIG_PM
-int alloc_dsp_suspendmem(struct m3_card *card)
+static int alloc_dsp_suspendmem(struct m3_card *card)
 {
     int len = sizeof(u16) * (REV_B_CODE_MEMORY_LENGTH + REV_B_DATA_MEMORY_LENGTH);
 
@@ -2580,7 +2580,7 @@
 
     return 0;
 }
-void free_dsp_suspendmem(struct m3_card *card)
+static void free_dsp_suspendmem(struct m3_card *card)
 {
    if(card->suspend_mem)
        vfree(card->suspend_mem);
@@ -2919,10 +2919,10 @@
 MODULE_LICENSE("GPL");
 
 #ifdef M_DEBUG
-MODULE_PARM(debug,"i");
+module_param(debug, int, 0);
 #endif
-MODULE_PARM(external_amp,"i");
-MODULE_PARM(gpio_pin, "i");
+module_param(external_amp, int, 0);
+module_param(gpio_pin, int, 0);
 
 static struct pci_driver m3_pci_driver = {
 	.name	  = "ess_m3_audio",
diff -Nru a/sound/oss/maestro3.h b/sound/oss/maestro3.h
--- a/sound/oss/maestro3.h	2005-03-01 23:38:55 -08:00
+++ b/sound/oss/maestro3.h	2005-03-01 23:38:55 -08:00
@@ -695,7 +695,7 @@
  * DSP Code images
  */
 
-u16 assp_kernel_image[] = {
+static u16 assp_kernel_image[] = {
     0x7980, 0x0030, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x00FB, 0x7980, 0x00DD, 0x7980, 0x03B4, 
     0x7980, 0x0332, 0x7980, 0x0287, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x03B4, 
     0x7980, 0x031A, 0x7980, 0x03B4, 0x7980, 0x022F, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x03B4, 
@@ -782,7 +782,7 @@
  * Mini sample rate converter code image
  * that is to be loaded at 0x400 on the DSP.
  */
-u16 assp_minisrc_image[] = {
+static u16 assp_minisrc_image[] = {
 
     0xBF80, 0x101E, 0x906E, 0x006E, 0x8B88, 0x6980, 0xEF88, 0x906F, 0x0D6F, 0x6900, 0xEB08, 0x0412, 
     0xBC20, 0x696E, 0xB801, 0x906E, 0x7980, 0x0403, 0xB90E, 0x8807, 0xBE43, 0xBF01, 0xBE47, 0xBE41, 
diff -Nru a/sound/oss/maui.c b/sound/oss/maui.c
--- a/sound/oss/maui.c	2005-03-01 23:39:08 -08:00
+++ b/sound/oss/maui.c	2005-03-01 23:39:08 -08:00
@@ -420,8 +420,8 @@
 static int __initdata io = -1;
 static int __initdata irq = -1;
 
-MODULE_PARM(io,"i");
-MODULE_PARM(irq,"i");
+module_param(io, int, 0);
+module_param(irq, int, 0);
 
 /*
  *	Install a Maui card. Needs mpu401 loaded already.
diff -Nru a/sound/oss/midibuf.c b/sound/oss/midibuf.c
--- a/sound/oss/midibuf.c	2005-03-01 23:38:56 -08:00
+++ b/sound/oss/midibuf.c	2005-03-01 23:38:56 -08:00
@@ -53,7 +53,7 @@
 static struct timer_list poll_timer = TIMER_INITIALIZER(midi_poll, 0, 0);
 
 static volatile int open_devs;
-static spinlock_t lock=SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(lock);
 
 #define DATA_AVAIL(q) (q->len)
 #define SPACE_AVAIL(q) (MAX_QUEUE_SIZE - q->len)
diff -Nru a/sound/oss/mpu401.c b/sound/oss/mpu401.c
--- a/sound/oss/mpu401.c	2005-03-01 23:39:16 -08:00
+++ b/sound/oss/mpu401.c	2005-03-01 23:39:16 -08:00
@@ -1770,8 +1770,8 @@
 static int io = -1;
 static int irq = -1;
 
-MODULE_PARM(irq, "i");
-MODULE_PARM(io, "i");
+module_param(irq, int, 0);
+module_param(io, int, 0);
 
 static int __init init_mpu401(void)
 {
diff -Nru a/sound/oss/msnd_pinnacle.c b/sound/oss/msnd_pinnacle.c
--- a/sound/oss/msnd_pinnacle.c	2005-03-01 23:39:06 -08:00
+++ b/sound/oss/msnd_pinnacle.c	2005-03-01 23:39:06 -08:00
@@ -1603,24 +1603,6 @@
 MODULE_DESCRIPTION			("Turtle Beach " LONGNAME " Linux Driver");
 MODULE_LICENSE("GPL");
 
-MODULE_PARM				(io, "i");
-MODULE_PARM				(irq, "i");
-MODULE_PARM				(mem, "i");
-MODULE_PARM				(write_ndelay, "i");
-MODULE_PARM				(fifosize, "i");
-MODULE_PARM				(calibrate_signal, "i");
-#ifndef MSND_CLASSIC
-MODULE_PARM				(digital, "i");
-MODULE_PARM				(cfg, "i");
-MODULE_PARM				(reset, "i");
-MODULE_PARM				(mpu_io, "i");
-MODULE_PARM				(mpu_irq, "i");
-MODULE_PARM				(ide_io0, "i");
-MODULE_PARM				(ide_io1, "i");
-MODULE_PARM				(ide_irq, "i");
-MODULE_PARM				(joystick_io, "i");
-#endif
-
 static int io __initdata =		-1;
 static int irq __initdata =		-1;
 static int mem __initdata =		-1;
@@ -1726,6 +1708,23 @@
 calibrate_signal __initdata =		CONFIG_MSND_CALSIGNAL;
 #endif /* MODULE */
 
+module_param				(io, int, 0);
+module_param				(irq, int, 0);
+module_param				(mem, int, 0);
+module_param				(write_ndelay, int, 0);
+module_param				(fifosize, int, 0);
+module_param				(calibrate_signal, int, 0);
+#ifndef MSND_CLASSIC
+module_param				(digital, bool, 0);
+module_param				(cfg, int, 0);
+module_param				(reset, int, 0);
+module_param				(mpu_io, int, 0);
+module_param				(mpu_irq, int, 0);
+module_param				(ide_io0, int, 0);
+module_param				(ide_io1, int, 0);
+module_param				(ide_irq, int, 0);
+module_param				(joystick_io, int, 0);
+#endif
 
 static int __init msnd_init(void)
 {
diff -Nru a/sound/oss/nec_vrc5477.c b/sound/oss/nec_vrc5477.c
--- a/sound/oss/nec_vrc5477.c	2005-03-01 23:39:08 -08:00
+++ b/sound/oss/nec_vrc5477.c	2005-03-01 23:39:08 -08:00
@@ -78,7 +78,6 @@
 #include <linux/spinlock.h>
 #include <linux/smp_lock.h>
 #include <linux/ac97_codec.h>
-#include <linux/interrupt.h>
 #include <asm/io.h>
 #include <asm/dma.h>
 #include <asm/uaccess.h>
@@ -396,10 +395,47 @@
 	}
 }
 
+static int ac97_codec_not_present(struct ac97_codec *codec)
+{
+	struct vrc5477_ac97_state *s =
+		(struct vrc5477_ac97_state *)codec->private_data;
+	unsigned long flags;
+	unsigned short count  = 0xffff;
+
+	spin_lock_irqsave(&s->lock, flags);
+
+	/* wait until we can access codec registers */
+	do {
+	       if (!(inl(s->io + VRC5477_CODEC_WR) & 0x80000000))
+		       break;
+	} while (--count);
+
+	if (count == 0) {
+		spin_unlock_irqrestore(&s->lock, flags);
+		return -1;
+	}
+
+	/* write 0 to reset */
+	outl((AC97_RESET << 16) | 0, s->io + VRC5477_CODEC_WR);
+
+	/* test whether we get a response from ac97 chip */
+	count  = 0xffff;
+	do {
+	       if (!(inl(s->io + VRC5477_CODEC_WR) & 0x80000000))
+		       break;
+	} while (--count);
+
+	if (count == 0) {
+		spin_unlock_irqrestore(&s->lock, flags);
+		return -1;
+	}
+	spin_unlock_irqrestore(&s->lock, flags);
+	return 0;
+}
 
 /* --------------------------------------------------------------------- */
 
-static inline void 
+extern inline void
 stop_dac(struct vrc5477_ac97_state *s)
 {
 	struct dmabuf* db = &s->dma_dac;
@@ -517,7 +553,7 @@
 	spin_unlock_irqrestore(&s->lock, flags);
 }	
 
-static inline void stop_adc(struct vrc5477_ac97_state *s)
+extern inline void stop_adc(struct vrc5477_ac97_state *s)
 {
 	struct dmabuf* db = &s->dma_adc;
 	unsigned long flags;
@@ -616,7 +652,7 @@
 #define DMABUF_DEFAULTORDER (16-PAGE_SHIFT)
 #define DMABUF_MINORDER 1
 
-static inline void dealloc_dmabuf(struct vrc5477_ac97_state *s, 
+extern inline void dealloc_dmabuf(struct vrc5477_ac97_state *s,
 				  struct dmabuf *db)
 {
 	if (db->lbuf) {
@@ -1858,6 +1894,13 @@
 
         }
 
+	/* test if get response from ac97, if not return */
+        if (ac97_codec_not_present(&(s->codec))) {
+		printk(KERN_ERR PFX "no ac97 codec\n");
+		goto err_region;
+
+        }
+
 	if (!request_region(s->io, pci_resource_len(pcidev,0),
 			    VRC5477_AC97_MODULE_NAME)) {
 		printk(KERN_ERR PFX "io ports %#lx->%#lx in use\n",
@@ -1973,7 +2016,7 @@
 		remove_proc_entry(VRC5477_AC97_MODULE_NAME, NULL);
 #endif /* VRC5477_AC97_DEBUG */
 
-	synchronize_irq(s->irq);
+	synchronize_irq();
 	free_irq(s->irq, s);
 	release_region(s->io, pci_resource_len(dev,0));
 	unregister_sound_dsp(s->dev_audio);
@@ -1996,7 +2039,7 @@
 	.name		= VRC5477_AC97_MODULE_NAME,
 	.id_table	= id_table,
 	.probe		= vrc5477_ac97_probe,
-	.remove		= __devexit_p(vrc5477_ac97_remove),
+	.remove		= __devexit_p(vrc5477_ac97_remove)
 };
 
 static int __init init_vrc5477_ac97(void)
diff -Nru a/sound/oss/nm256_audio.c b/sound/oss/nm256_audio.c
--- a/sound/oss/nm256_audio.c	2005-03-01 23:38:56 -08:00
+++ b/sound/oss/nm256_audio.c	2005-03-01 23:38:56 -08:00
@@ -157,7 +157,7 @@
  * attempted.
  */
 
-int
+static int
 nm256_setInfo (int dev, struct nm256_info *card)
 {
     int x;
@@ -1673,17 +1673,17 @@
 MODULE_LICENSE("GPL");
 
 
-struct pci_driver nm256_pci_driver = {
+static struct pci_driver nm256_pci_driver = {
 	.name		= "nm256_audio",
 	.id_table	= nm256_pci_tbl,
 	.probe		= nm256_probe,
 	.remove		= nm256_remove,
 };
 
-MODULE_PARM (usecache, "i");
-MODULE_PARM (buffertop, "i");
-MODULE_PARM (nm256_debug, "i");
-MODULE_PARM (force_load, "i");
+module_param(usecache, bool, 0);
+module_param(buffertop, int, 0);
+module_param(nm256_debug, bool, 0644);
+module_param(force_load, bool, 0);
 
 static int __init do_init_nm256(void)
 {
diff -Nru a/sound/oss/opl3.c b/sound/oss/opl3.c
--- a/sound/oss/opl3.c	2005-03-01 23:38:58 -08:00
+++ b/sound/oss/opl3.c	2005-03-01 23:38:58 -08:00
@@ -1202,7 +1202,7 @@
 
 static int io = -1;
 
-MODULE_PARM(io, "i");
+module_param(io, int, 0);
 
 static int __init init_opl3 (void)
 {
diff -Nru a/sound/oss/opl3sa.c b/sound/oss/opl3sa.c
--- a/sound/oss/opl3sa.c	2005-03-01 23:39:18 -08:00
+++ b/sound/oss/opl3sa.c	2005-03-01 23:39:18 -08:00
@@ -36,7 +36,7 @@
 static int sb_initialized;
 #endif
 
-static spinlock_t lock=SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(lock);
 
 static unsigned char opl3sa_read(int addr)
 {
@@ -245,12 +245,12 @@
 static int __initdata mpu_io	= -1;
 static int __initdata mpu_irq	= -1;
 
-MODULE_PARM(io,"i");
-MODULE_PARM(irq,"i");
-MODULE_PARM(dma,"i");
-MODULE_PARM(dma2,"i");
-MODULE_PARM(mpu_io,"i");
-MODULE_PARM(mpu_irq,"i");
+module_param(io, int, 0);
+module_param(irq, int, 0);
+module_param(dma, int, 0);
+module_param(dma2, int, 0);
+module_param(mpu_io, int, 0);
+module_param(mpu_irq, int, 0);
 
 static int __init init_opl3sa(void)
 {
diff -Nru a/sound/oss/opl3sa2.c b/sound/oss/opl3sa2.c
--- a/sound/oss/opl3sa2.c	2005-03-01 23:38:44 -08:00
+++ b/sound/oss/opl3sa2.c	2005-03-01 23:38:44 -08:00
@@ -177,9 +177,6 @@
 static int __initdata isapnp = 1;
 static int __initdata multiple = 1;
 
-/* PnP devices */
-struct pnp_dev* opl3sa2_dev[OPL3SA2_CARDS_MAX];
-
 /* Whether said devices have been activated */
 static int opl3sa2_activated[OPL3SA2_CARDS_MAX];
 #else
@@ -192,35 +189,35 @@
 MODULE_LICENSE("GPL");
 
 
-MODULE_PARM(io, "i");
+module_param(io, int, 0);
 MODULE_PARM_DESC(io, "Set I/O base of OPL3-SA2 or SA3 card (usually 0x370.  Address must be even and must be from 0x100 to 0xFFE)");
 
-MODULE_PARM(mss_io, "i");
+module_param(mss_io, int, 0);
 MODULE_PARM_DESC(mss_io, "Set MSS (audio) I/O base (0x530, 0xE80, or other. Address must end in 0 or 4 and must be from 0x530 to 0xF48)");
 
-MODULE_PARM(mpu_io, "i");
+module_param(mpu_io, int, 0);
 MODULE_PARM_DESC(mpu_io, "Set MIDI I/O base (0x330 or other. Address must be even and must be from 0x300 to 0x334)");
 
-MODULE_PARM(irq, "i");
+module_param(irq, int, 0);
 MODULE_PARM_DESC(mss_irq, "Set MSS (audio) IRQ (5, 7, 9, 10, 11, 12)");
 
-MODULE_PARM(dma, "i");
+module_param(dma, int, 0);
 MODULE_PARM_DESC(dma, "Set MSS (audio) first DMA channel (0, 1, 3)");
 
-MODULE_PARM(dma2, "i");
+module_param(dma2, int, 0);
 MODULE_PARM_DESC(dma2, "Set MSS (audio) second DMA channel (0, 1, 3)");
 
-MODULE_PARM(ymode, "i");
+module_param(ymode, int, 0);
 MODULE_PARM_DESC(ymode, "Set Yamaha 3D enhancement mode (0 = Desktop/Normal, 1 = Notebook PC (1), 2 = Notebook PC (2), 3 = Hi-Fi)");
 
-MODULE_PARM(loopback, "i");
+module_param(loopback, int, 0);
 MODULE_PARM_DESC(loopback, "Set A/D input source. Useful for echo cancellation (0 = Mic Rch (default), 1 = Mono output loopback)");
 
 #ifdef CONFIG_PNP
-MODULE_PARM(isapnp, "i");
+module_param(isapnp, bool, 0);
 MODULE_PARM_DESC(isapnp, "When set to 0, ISA PnP support will be disabled");
 
-MODULE_PARM(multiple, "i");
+module_param(multiple, bool, 0);
 MODULE_PARM_DESC(multiple, "When set to 0, will not search for multiple cards");
 #endif
 
@@ -714,7 +711,7 @@
 }
 
 
-static void __init opl3sa2_clear_slots(struct address_info* hw_config)
+static void opl3sa2_clear_slots(struct address_info* hw_config)
 {
 	int i;
 
@@ -775,7 +772,7 @@
 }
 
 #ifdef CONFIG_PNP
-struct pnp_device_id pnp_opl3sa2_list[] = {
+static struct pnp_device_id pnp_opl3sa2_list[] = {
 	{.id = "YMH0021", .driver_data = 0},
 	{.id = ""}
 };
@@ -835,7 +832,7 @@
 /* End of component functions */
 
 #ifdef CONFIG_PM
-static spinlock_t opl3sa2_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(opl3sa2_lock);
 
 /* Power Management support functions */
 static int opl3sa2_suspend(struct pm_dev *pdev, unsigned int pm_mode)
diff -Nru a/sound/oss/pas2_card.c b/sound/oss/pas2_card.c
--- a/sound/oss/pas2_card.c	2005-03-01 23:39:08 -08:00
+++ b/sound/oss/pas2_card.c	2005-03-01 23:39:08 -08:00
@@ -40,7 +40,7 @@
 static int      pas_intr_mask;
 static int      pas_irq;
 static int      pas_sb_base;
-spinlock_t	pas_lock=SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(pas_lock);
 #ifndef CONFIG_PAS_JOYSTICK
 static int	joystick;
 #else
@@ -240,8 +240,6 @@
 	mix_write(0x80 | 5, 0x078B);
 	mix_write(5, 0x078B);
 
-#if !defined(DISABLE_SB_EMULATION)
-
 	{
 		struct address_info *sb_config;
 
@@ -279,9 +277,6 @@
 		else
 			pas_write(0x00, 0xF788);
 	}
-#else
-	pas_write(0x00, 0xF788);
-#endif
 
 	if (!ok)
 		printk(KERN_WARNING "PAS16: Driver not enabled\n");
@@ -349,11 +344,6 @@
 		if (config_pas_hw(hw_config))
 		{
 			pas_pcm_init(hw_config);
-
-#if !defined(MODULE) && !defined(DISABLE_SB_EMULATION)
-			sb_dsp_disable_midi(pas_sb_base);	/* No MIDI capability */
-#endif
-
 			pas_midi_init();
 			pas_init_mixer();
 		}
@@ -393,19 +383,19 @@
 static int __initdata sb_dma	= -1;
 static int __initdata sb_dma16	= -1;
 
-MODULE_PARM(io,"i");
-MODULE_PARM(irq,"i");
-MODULE_PARM(dma,"i");
-MODULE_PARM(dma16,"i");
-
-MODULE_PARM(sb_io,"i");
-MODULE_PARM(sb_irq,"i");
-MODULE_PARM(sb_dma,"i");
-MODULE_PARM(sb_dma16,"i");
-
-MODULE_PARM(joystick,"i");
-MODULE_PARM(symphony,"i");
-MODULE_PARM(broken_bus_clock,"i");
+module_param(io, int, 0);
+module_param(irq, int, 0);
+module_param(dma, int, 0);
+module_param(dma16, int, 0);
+
+module_param(sb_io, int, 0);
+module_param(sb_irq, int, 0);
+module_param(sb_dma, int, 0);
+module_param(sb_dma16, int, 0);
+
+module_param(joystick, bool, 0);
+module_param(symphony, bool, 0);
+module_param(broken_bus_clock, bool, 0);
 
 MODULE_LICENSE("GPL");
 
diff -Nru a/sound/oss/pss.c b/sound/oss/pss.c
--- a/sound/oss/pss.c	2005-03-01 23:39:18 -08:00
+++ b/sound/oss/pss.c	2005-03-01 23:39:18 -08:00
@@ -118,9 +118,9 @@
 
 /* If compiled into kernel, it enable or disable pss mixer */
 #ifdef CONFIG_PSS_MIXER
-static unsigned char pss_mixer = 1;
+static int pss_mixer = 1;
 #else
-static unsigned char pss_mixer;
+static int pss_mixer;
 #endif
 
 
@@ -143,7 +143,7 @@
   
 static pss_confdata pss_data;
 static pss_confdata *devc = &pss_data;
-static spinlock_t lock=SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(lock);
 
 static int      pss_initialized;
 static int      nonstandard_microcode;
@@ -649,7 +649,7 @@
 	.ioctl	= pss_mixer_ioctl
 };
 
-void disable_all_emulations(void)
+static void disable_all_emulations(void)
 {
 	outw(0x0000, REG(CONF_PSS));	/* 0x0400 enables joystick */
 	outw(0x0000, REG(CONF_WSS));
@@ -658,7 +658,7 @@
 	outw(0x0000, REG(CONF_CDROM));
 }
 
-void configure_nonsound_components(void)
+static void configure_nonsound_components(void)
 {
 	/* Configure Joystick port */
 
@@ -1153,29 +1153,29 @@
 static int pss_keep_settings  = 1;	/* Keep hardware settings at module exit */
 static char *pss_firmware = "/etc/sound/pss_synth";
 
-MODULE_PARM(pss_io, "i");
+module_param(pss_io, int, 0);
 MODULE_PARM_DESC(pss_io, "Set i/o base of PSS card (probably 0x220 or 0x240)");
-MODULE_PARM(mss_io, "i");
+module_param(mss_io, int, 0);
 MODULE_PARM_DESC(mss_io, "Set WSS (audio) i/o base (0x530, 0x604, 0xE80, 0xF40, or other. Address must end in 0 or 4 and must be from 0x100 to 0xFF4)");
-MODULE_PARM(mss_irq, "i");
+module_param(mss_irq, int, 0);
 MODULE_PARM_DESC(mss_irq, "Set WSS (audio) IRQ (3, 5, 7, 9, 10, 11, 12)");
-MODULE_PARM(mss_dma, "i");
+module_param(mss_dma, int, 0);
 MODULE_PARM_DESC(mss_dma, "Set WSS (audio) DMA (0, 1, 3)");
-MODULE_PARM(mpu_io, "i");
+module_param(mpu_io, int, 0);
 MODULE_PARM_DESC(mpu_io, "Set MIDI i/o base (0x330 or other. Address must be on 4 location boundaries and must be from 0x100 to 0xFFC)");
-MODULE_PARM(mpu_irq, "i");
+module_param(mpu_irq, int, 0);
 MODULE_PARM_DESC(mpu_irq, "Set MIDI IRQ (3, 5, 7, 9, 10, 11, 12)");
-MODULE_PARM(pss_cdrom_port, "i");
+module_param(pss_cdrom_port, int, 0);
 MODULE_PARM_DESC(pss_cdrom_port, "Set the PSS CDROM port i/o base (0x340 or other)");
-MODULE_PARM(pss_enable_joystick, "i");
+module_param(pss_enable_joystick, bool, 0);
 MODULE_PARM_DESC(pss_enable_joystick, "Enables the PSS joystick port (1 to enable, 0 to disable)");
-MODULE_PARM(pss_no_sound, "i");
+module_param(pss_no_sound, bool, 0);
 MODULE_PARM_DESC(pss_no_sound, "Configure sound compoents (0 - no, 1 - yes)");
-MODULE_PARM(pss_keep_settings, "i");
+module_param(pss_keep_settings, bool, 0);
 MODULE_PARM_DESC(pss_keep_settings, "Keep hardware setting at driver unloading (0 - no, 1 - yes)");
-MODULE_PARM(pss_firmware, "s");
+module_param(pss_firmware, charp, 0);
 MODULE_PARM_DESC(pss_firmware, "Location of the firmware file (default - /etc/sound/pss_synth)");
-MODULE_PARM(pss_mixer, "b");
+module_param(pss_mixer, bool, 0);
 MODULE_PARM_DESC(pss_mixer, "Enable (1) or disable (0) PSS mixer (controlling of output volume, bass, treble, synth volume). The mixer is not available on all PSS cards.");
 MODULE_AUTHOR("Hannu Savolainen, Vladimir Michl");
 MODULE_DESCRIPTION("Module for PSS sound cards (based on AD1848, ADSP-2115 and ESC614). This module includes control of output amplifier and synth volume of the Beethoven ADSP-16 card (this may work with other PSS cards).");
diff -Nru a/sound/oss/rme96xx.c b/sound/oss/rme96xx.c
--- a/sound/oss/rme96xx.c	2005-03-01 23:38:55 -08:00
+++ b/sound/oss/rme96xx.c	2005-03-01 23:38:55 -08:00
@@ -68,7 +68,7 @@
 #define NR_DEVICE 2
 
 static int devices = 1;
-MODULE_PARM(devices, "1-" __MODULE_STRING(NR_DEVICE) "i");
+module_param(devices, int, 0);
 MODULE_PARM_DESC(devices, "number of dsp devices allocated by the driver");
 
 
@@ -339,7 +339,7 @@
 
 /* fiddling with the card (first level hardware control) */
 
-inline void rme96xx_set_ctrl(rme96xx_info* s,int mask)
+static inline void rme96xx_set_ctrl(rme96xx_info* s,int mask)
 {
 
 	s->control_register|=mask;
@@ -347,7 +347,7 @@
 
 }
 
-inline void rme96xx_unset_ctrl(rme96xx_info* s,int mask)
+static inline void rme96xx_unset_ctrl(rme96xx_info* s,int mask)
 {
 
 	s->control_register&=(~mask);
@@ -355,7 +355,7 @@
 
 }
 
-inline int rme96xx_get_sample_rate_status(rme96xx_info* s)
+static inline int rme96xx_get_sample_rate_status(rme96xx_info* s)
 {
 	int val;
 	u32 status;
@@ -366,7 +366,7 @@
 	return val;
 }
 
-inline int rme96xx_get_sample_rate_ctrl(rme96xx_info* s)
+static inline int rme96xx_get_sample_rate_ctrl(rme96xx_info* s)
 {
 	int val;
 	val = (s->control_register & RME96xx_freq) ? 48000 : 44100;
@@ -539,7 +539,7 @@
 /* the function returns the hardware pointer in bytes */
 #define RME96xx_BURSTBYTES -64  /* bytes by which hwptr could be off */
 
-inline int rme96xx_gethwptr(rme96xx_info* s,int exact)
+static inline int rme96xx_gethwptr(rme96xx_info* s,int exact)
 {
 	unsigned long flags;
 	if (exact) {
@@ -557,7 +557,7 @@
 	return (s->hwbufid ? s->fragsize : 0);
 }
 
-inline void rme96xx_setlatency(rme96xx_info* s,int l)
+static inline void rme96xx_setlatency(rme96xx_info* s,int l)
 {
 	s->latency = l;
 	s->fragsize = 1<<(8+l);
@@ -626,7 +626,7 @@
 }
 
 
-inline int rme96xx_getospace(struct dmabuf * dma, unsigned int hwp)
+static inline int rme96xx_getospace(struct dmabuf * dma, unsigned int hwp)
 {
 	int cnt;
 	int  swptr;
@@ -643,7 +643,7 @@
 	return cnt;
 }
 
-inline int rme96xx_getispace(struct dmabuf * dma, unsigned int hwp)
+static inline int rme96xx_getispace(struct dmabuf * dma, unsigned int hwp)
 {
 	int cnt;
 	int  swptr;
@@ -661,7 +661,7 @@
 }
 
 
-inline int rme96xx_copyfromuser(struct dmabuf* dma,const char __user * buffer,int count,int hop)
+static inline int rme96xx_copyfromuser(struct dmabuf* dma,const char __user * buffer,int count,int hop)
 {
 	int swptr = dma->writeptr;
 	switch (dma->format) {
@@ -710,7 +710,7 @@
 }
 
 /* The count argument is the number of bytes */
-inline int rme96xx_copytouser(struct dmabuf* dma,const char __user* buffer,int count,int hop)
+static inline int rme96xx_copytouser(struct dmabuf* dma,const char __user* buffer,int count,int hop)
 {
 	int swptr = dma->readptr;
 	switch (dma->format) {
@@ -793,7 +793,7 @@
  PCI detection and module initialization stuff 
  ----------------------------------------------------------------------------*/
 
-void* busmaster_malloc(int size) {
+static void* busmaster_malloc(int size) {
      int pg; /* 2 s exponent of memory size */
         char *buf;
 
@@ -819,7 +819,7 @@
 	return NULL;
 }
 
-void busmaster_free(void* ptr,int size) {
+static void busmaster_free(void* ptr,int size) {
         int pg;
 	struct page* page, *last_page;
 
@@ -866,7 +866,7 @@
 }
 
 
-int rme96xx_init(rme96xx_info* s)
+static int rme96xx_init(rme96xx_info* s)
 {
 	int i;
 	int status;
diff -Nru a/sound/oss/sb.h b/sound/oss/sb.h
--- a/sound/oss/sb.h	2005-03-01 23:38:43 -08:00
+++ b/sound/oss/sb.h	2005-03-01 23:38:43 -08:00
@@ -176,11 +176,8 @@
 int sb_audio_open(int dev, int mode);
 void sb_audio_close(int dev);
 
-extern sb_devc *last_sb;
-
 /*	From sb_common.c */
 void sb_dsp_disable_midi(int port);
-void sb_dsp_disable_recording(int port);
 int probe_sbmpu (struct address_info *hw_config, struct module *owner);
 void unload_sbmpu (struct address_info *hw_config);
 
diff -Nru a/sound/oss/sb_card.c b/sound/oss/sb_card.c
--- a/sound/oss/sb_card.c	2005-03-01 23:39:07 -08:00
+++ b/sound/oss/sb_card.c	2005-03-01 23:39:07 -08:00
@@ -52,7 +52,7 @@
 static int __initdata acer 	= 0; /* Do acer notebook init? */
 static int __initdata sm_games 	= 0; /* Logitech soundman games? */
 
-struct sb_card_config *legacy = NULL;
+static struct sb_card_config *legacy = NULL;
 
 #ifdef CONFIG_PNP
 static int __initdata pnp       = 1;
diff -Nru a/sound/oss/sb_common.c b/sound/oss/sb_common.c
--- a/sound/oss/sb_common.c	2005-03-01 23:38:51 -08:00
+++ b/sound/oss/sb_common.c	2005-03-01 23:38:51 -08:00
@@ -67,7 +67,7 @@
 
 static int jazz16_base;			/* Not detected */
 static unsigned char jazz16_bits;	/* I/O relocation bits */
-static spinlock_t jazz16_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(jazz16_lock);
 
 /*
  * Logitech Soundman Wave specific initialization code
@@ -81,7 +81,7 @@
 
 #endif
 
-sb_devc *last_sb;		/* Last sb loaded */
+static sb_devc *last_sb;		/* Last sb loaded */
 
 int sb_dsp_command(sb_devc * devc, unsigned char val)
 {
@@ -521,7 +521,7 @@
 	
 	DDB(printk("sb_dsp_detect(%x) entered\n", hw_config->io_base));
 
-	devc->lock = SPIN_LOCK_UNLOCKED;
+	spin_lock_init(&devc->lock);
 	devc->type = hw_config->card_subtype;
 
 	devc->base = hw_config->io_base;
@@ -876,14 +876,6 @@
 	return 1;
 }
 
-void sb_dsp_disable_midi(int io_base)
-{
-}
-
-void sb_dsp_disable_recording(int io_base)
-{
-}
-
 /* if (sbmpu) below we allow mpu401 to manage the midi devs
    otherwise we have to unload them. (Andrzej Krzysztofowicz) */
    
@@ -1292,7 +1284,6 @@
 EXPORT_SYMBOL(sb_dsp_init);
 EXPORT_SYMBOL(sb_dsp_detect);
 EXPORT_SYMBOL(sb_dsp_unload);
-EXPORT_SYMBOL(sb_dsp_disable_midi);
 EXPORT_SYMBOL(sb_be_quiet);
 EXPORT_SYMBOL(probe_sbmpu);
 EXPORT_SYMBOL(unload_sbmpu);
diff -Nru a/sound/oss/sb_ess.c b/sound/oss/sb_ess.c
--- a/sound/oss/sb_ess.c	2005-03-01 23:38:55 -08:00
+++ b/sound/oss/sb_ess.c	2005-03-01 23:38:55 -08:00
@@ -1696,7 +1696,7 @@
 	sb_common_mixer_set(devc, dev, left, right);
 }
 
-int es_rec_set_recmask(sb_devc * devc, int mask)
+static int es_rec_set_recmask(sb_devc * devc, int mask)
 {
 	int i, i_mask, cur_mask, diff_mask;
 	int value, left, right;
diff -Nru a/sound/oss/sequencer.c b/sound/oss/sequencer.c
--- a/sound/oss/sequencer.c	2005-03-01 23:38:57 -08:00
+++ b/sound/oss/sequencer.c	2005-03-01 23:38:57 -08:00
@@ -28,7 +28,7 @@
 extern unsigned long seq_time;
 
 static int      obsolete_api_used;
-static spinlock_t lock=SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(lock);
 
 /*
  * Local counts for number of synth and MIDI devices. These are initialized
@@ -1091,7 +1091,7 @@
 	return 0;
 }
 
-void seq_drain_midi_queues(void)
+static void seq_drain_midi_queues(void)
 {
 	int i, n;
 
diff -Nru a/sound/oss/sgalaxy.c b/sound/oss/sgalaxy.c
--- a/sound/oss/sgalaxy.c	2005-03-01 23:39:07 -08:00
+++ b/sound/oss/sgalaxy.c	2005-03-01 23:39:07 -08:00
@@ -153,11 +153,11 @@
 static int __initdata dma2	= -1;
 static int __initdata sgbase	= -1;
 
-MODULE_PARM(io,"i");
-MODULE_PARM(irq,"i");
-MODULE_PARM(dma,"i");
-MODULE_PARM(dma2,"i");
-MODULE_PARM(sgbase,"i");
+module_param(io, int, 0);
+module_param(irq, int, 0);
+module_param(dma, int, 0);
+module_param(dma2, int, 0);
+module_param(sgbase, int, 0);
 
 static int __init init_sgalaxy(void)
 {
diff -Nru a/sound/oss/sonicvibes.c b/sound/oss/sonicvibes.c
--- a/sound/oss/sonicvibes.c	2005-03-01 23:38:56 -08:00
+++ b/sound/oss/sonicvibes.c	2005-03-01 23:38:56 -08:00
@@ -2453,7 +2453,7 @@
 
 static unsigned int devindex;
 
-MODULE_PARM(reverb, "1-" __MODULE_STRING(NR_DEVICE) "i");
+module_param_array(reverb, bool, NULL, 0);
 MODULE_PARM_DESC(reverb, "if 1 enables the reverb circuitry. NOTE: your card must have the reverb RAM");
 #if 0
 MODULE_PARM(wavetable, "1-" __MODULE_STRING(NR_DEVICE) "i");
@@ -2470,7 +2470,7 @@
 static struct initvol {
 	int mixch;
 	int vol;
-} initvol[] __initdata = {
+} initvol[] __devinitdata = {
 	{ SOUND_MIXER_WRITE_RECLEV, 0x4040 },
 	{ SOUND_MIXER_WRITE_LINE1, 0x4040 },
 	{ SOUND_MIXER_WRITE_CD, 0x4040 },
@@ -2487,7 +2487,7 @@
 
 static int __devinit sv_probe(struct pci_dev *pcidev, const struct pci_device_id *pciid)
 {
-	static char __initdata sv_ddma_name[] = "S3 Inc. SonicVibes DDMA Controller";
+	static char __devinitdata sv_ddma_name[] = "S3 Inc. SonicVibes DDMA Controller";
        	struct sv_state *s;
 	mm_segment_t fs;
 	int i, val, ret;
diff -Nru a/sound/oss/soundcard.c b/sound/oss/soundcard.c
--- a/sound/oss/soundcard.c	2005-03-01 23:38:57 -08:00
+++ b/sound/oss/soundcard.c	2005-03-01 23:38:57 -08:00
@@ -535,8 +535,8 @@
 static int dmabuf;
 static int dmabug;
 
-MODULE_PARM(dmabuf, "i");
-MODULE_PARM(dmabug, "i");
+module_param(dmabuf, int, 0444);
+module_param(dmabug, int, 0444);
 
 static int __init oss_init(void)
 {
diff -Nru a/sound/oss/sscape.c b/sound/oss/sscape.c
--- a/sound/oss/sscape.c	2005-03-01 23:39:07 -08:00
+++ b/sound/oss/sscape.c	2005-03-01 23:39:07 -08:00
@@ -1400,13 +1400,13 @@
 static int __initdata mpu_irq = -1;
 static int __initdata mpu_io = -1;
 
-MODULE_PARM(dma, "i");
-MODULE_PARM(irq, "i");
-MODULE_PARM(io, "i");
-MODULE_PARM(spea, "i");		/* spea=0/1 set the old_hardware */
-MODULE_PARM(mpu_irq, "i");
-MODULE_PARM(mpu_io, "i");
-MODULE_PARM(mss, "i");
+module_param(dma, int, 0);
+module_param(irq, int, 0);
+module_param(io, int, 0);
+module_param(spea, int, 0);		/* spea=0/1 set the old_hardware */
+module_param(mpu_irq, int, 0);
+module_param(mpu_io, int, 0);
+module_param(mss, int, 0);
 
 static int __init init_sscape(void)
 {
diff -Nru a/sound/oss/swarm_cs4297a.c b/sound/oss/swarm_cs4297a.c
--- a/sound/oss/swarm_cs4297a.c	2005-03-01 23:38:58 -08:00
+++ b/sound/oss/swarm_cs4297a.c	2005-03-01 23:38:58 -08:00
@@ -10,7 +10,9 @@
 *               (audio@crystal.cirrus.com).
 *            -- adapted from cs4281 PCI driver for cs4297a on
 *               BCM1250 Synchronous Serial interface
-*               (kwalker@broadcom.com)
+*               (Kip Walker, Broadcom Corp.)
+*      Copyright (C) 2004  Maciej W. Rozycki
+*      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
@@ -71,12 +73,13 @@
 #include <linux/pci.h>
 #include <linux/bitops.h>
 #include <linux/interrupt.h>
-#include <asm/io.h>
-#include <asm/dma.h>
 #include <linux/init.h>
 #include <linux/poll.h>
 #include <linux/smp_lock.h>
-#include <linux/wrapper.h>
+
+#include <asm/byteorder.h>
+#include <asm/dma.h>
+#include <asm/io.h>
 #include <asm/uaccess.h>
 
 #include <asm/sibyte/sb1250_regs.h>
@@ -86,7 +89,6 @@
 #include <asm/sibyte/sb1250_syncser.h>
 #include <asm/sibyte/sb1250_mac.h>
 #include <asm/sibyte/sb1250.h>
-#include <asm/sibyte/64bit.h>
 
 struct cs4297a_state;
 
@@ -561,44 +563,44 @@
         CS_DBGOUT(CS_INIT, 2, 
                   printk(KERN_INFO "cs4297a: Setting up serial parameters\n"));
 
-        out64(M_SYNCSER_CMD_RX_RESET | M_SYNCSER_CMD_TX_RESET, SS_CSR(R_SER_CMD));
+        __raw_writeq(M_SYNCSER_CMD_RX_RESET | M_SYNCSER_CMD_TX_RESET, SS_CSR(R_SER_CMD));
 
-        out64(M_SYNCSER_MSB_FIRST, SS_CSR(R_SER_MODE));
-        out64(32, SS_CSR(R_SER_MINFRM_SZ));
-        out64(32, SS_CSR(R_SER_MAXFRM_SZ));
-
-        out64(1, SS_CSR(R_SER_TX_RD_THRSH));
-        out64(4, SS_CSR(R_SER_TX_WR_THRSH));
-        out64(8, SS_CSR(R_SER_RX_RD_THRSH));
+        __raw_writeq(M_SYNCSER_MSB_FIRST, SS_CSR(R_SER_MODE));
+        __raw_writeq(32, SS_CSR(R_SER_MINFRM_SZ));
+        __raw_writeq(32, SS_CSR(R_SER_MAXFRM_SZ));
+
+        __raw_writeq(1, SS_CSR(R_SER_TX_RD_THRSH));
+        __raw_writeq(4, SS_CSR(R_SER_TX_WR_THRSH));
+        __raw_writeq(8, SS_CSR(R_SER_RX_RD_THRSH));
 
         /* This looks good from experimentation */
-        out64((M_SYNCSER_TXSYNC_INT | V_SYNCSER_TXSYNC_DLY(0) | M_SYNCSER_TXCLK_EXT |
+        __raw_writeq((M_SYNCSER_TXSYNC_INT | V_SYNCSER_TXSYNC_DLY(0) | M_SYNCSER_TXCLK_EXT |
                M_SYNCSER_RXSYNC_INT | V_SYNCSER_RXSYNC_DLY(1) | M_SYNCSER_RXCLK_EXT | M_SYNCSER_RXSYNC_EDGE),
               SS_CSR(R_SER_LINE_MODE));
 
         /* This looks good from experimentation */
-        out64(V_SYNCSER_SEQ_COUNT(14) | M_SYNCSER_SEQ_ENABLE | M_SYNCSER_SEQ_STROBE,
+        __raw_writeq(V_SYNCSER_SEQ_COUNT(14) | M_SYNCSER_SEQ_ENABLE | M_SYNCSER_SEQ_STROBE,
               SS_TXTBL(0));
-        out64(V_SYNCSER_SEQ_COUNT(15) | M_SYNCSER_SEQ_ENABLE | M_SYNCSER_SEQ_BYTE,
+        __raw_writeq(V_SYNCSER_SEQ_COUNT(15) | M_SYNCSER_SEQ_ENABLE | M_SYNCSER_SEQ_BYTE,
               SS_TXTBL(1));
-        out64(V_SYNCSER_SEQ_COUNT(13) | M_SYNCSER_SEQ_ENABLE | M_SYNCSER_SEQ_BYTE,
+        __raw_writeq(V_SYNCSER_SEQ_COUNT(13) | M_SYNCSER_SEQ_ENABLE | M_SYNCSER_SEQ_BYTE,
               SS_TXTBL(2));
-        out64(V_SYNCSER_SEQ_COUNT( 0) | M_SYNCSER_SEQ_ENABLE |
+        __raw_writeq(V_SYNCSER_SEQ_COUNT( 0) | M_SYNCSER_SEQ_ENABLE |
               M_SYNCSER_SEQ_STROBE | M_SYNCSER_SEQ_LAST, SS_TXTBL(3));
 
-        out64(V_SYNCSER_SEQ_COUNT(14) | M_SYNCSER_SEQ_ENABLE | M_SYNCSER_SEQ_STROBE,
+        __raw_writeq(V_SYNCSER_SEQ_COUNT(14) | M_SYNCSER_SEQ_ENABLE | M_SYNCSER_SEQ_STROBE,
               SS_RXTBL(0));
-        out64(V_SYNCSER_SEQ_COUNT(15) | M_SYNCSER_SEQ_ENABLE | M_SYNCSER_SEQ_BYTE,
+        __raw_writeq(V_SYNCSER_SEQ_COUNT(15) | M_SYNCSER_SEQ_ENABLE | M_SYNCSER_SEQ_BYTE,
               SS_RXTBL(1));
-        out64(V_SYNCSER_SEQ_COUNT(13) | M_SYNCSER_SEQ_ENABLE | M_SYNCSER_SEQ_BYTE,
+        __raw_writeq(V_SYNCSER_SEQ_COUNT(13) | M_SYNCSER_SEQ_ENABLE | M_SYNCSER_SEQ_BYTE,
               SS_RXTBL(2));
-        out64(V_SYNCSER_SEQ_COUNT( 0) | M_SYNCSER_SEQ_ENABLE | M_SYNCSER_SEQ_STROBE |
+        __raw_writeq(V_SYNCSER_SEQ_COUNT( 0) | M_SYNCSER_SEQ_ENABLE | M_SYNCSER_SEQ_STROBE |
               M_SYNCSER_SEQ_LAST, SS_RXTBL(3));
 
         for (i=4; i<16; i++) {
                 /* Just in case... */
-                out64(M_SYNCSER_SEQ_LAST, SS_TXTBL(i));
-                out64(M_SYNCSER_SEQ_LAST, SS_RXTBL(i));
+                __raw_writeq(M_SYNCSER_SEQ_LAST, SS_TXTBL(i));
+                __raw_writeq(M_SYNCSER_SEQ_LAST, SS_RXTBL(i));
         }
 
         return 0;
@@ -620,7 +622,7 @@
         memset(dma->descrtab, 0, dma->ringsz * sizeof(serdma_descr_t));
         dma->descrtab_end = dma->descrtab + dma->ringsz;
 	/* XXX bloddy mess, use proper DMA API here ...  */
-	dma->descrtab_phys = PHYSADDR((int)dma->descrtab);
+	dma->descrtab_phys = CPHYSADDR((long)dma->descrtab);
         dma->descr_add = dma->descr_rem = dma->descrtab;
 
         /* Frame buffer area */
@@ -631,7 +633,7 @@
                 return -1;
         }
         memset(dma->dma_buf, 0, DMA_BUF_SIZE);
-        dma->dma_buf_phys = PHYSADDR((int)dma->dma_buf);
+        dma->dma_buf_phys = CPHYSADDR((long)dma->dma_buf);
 
         /* Samples buffer area */
         dma->sbufsz = SAMPLE_BUF_SIZE;
@@ -665,8 +667,8 @@
             init_serdma(&s->dma_dac))
                 return -1;
 
-        if (in64(SS_CSR(R_SER_DMA_DSCR_COUNT_RX))||
-            in64(SS_CSR(R_SER_DMA_DSCR_COUNT_TX))) {
+        if (__raw_readq(SS_CSR(R_SER_DMA_DSCR_COUNT_RX))||
+            __raw_readq(SS_CSR(R_SER_DMA_DSCR_COUNT_TX))) {
                 panic("DMA state corrupted?!");
         }
 
@@ -681,38 +683,38 @@
                 s->dma_adc.descrtab[i].descr_b = 0;
         }
 
-        out64((M_DMA_EOP_INT_EN | V_DMA_INT_PKTCNT(DMA_INT_CNT) |
+        __raw_writeq((M_DMA_EOP_INT_EN | V_DMA_INT_PKTCNT(DMA_INT_CNT) |
                V_DMA_RINGSZ(DMA_DESCR) | M_DMA_TDX_EN),
               SS_CSR(R_SER_DMA_CONFIG0_RX));
-        out64(M_DMA_L2CA, SS_CSR(R_SER_DMA_CONFIG1_RX));
-        out64(s->dma_adc.descrtab_phys, SS_CSR(R_SER_DMA_DSCR_BASE_RX));
+        __raw_writeq(M_DMA_L2CA, SS_CSR(R_SER_DMA_CONFIG1_RX));
+        __raw_writeq(s->dma_adc.descrtab_phys, SS_CSR(R_SER_DMA_DSCR_BASE_RX));
 
-        out64(V_DMA_RINGSZ(DMA_DESCR), SS_CSR(R_SER_DMA_CONFIG0_TX));
-        out64(M_DMA_L2CA | M_DMA_NO_DSCR_UPDT, SS_CSR(R_SER_DMA_CONFIG1_TX));
-        out64(s->dma_dac.descrtab_phys, SS_CSR(R_SER_DMA_DSCR_BASE_TX));
+        __raw_writeq(V_DMA_RINGSZ(DMA_DESCR), SS_CSR(R_SER_DMA_CONFIG0_TX));
+        __raw_writeq(M_DMA_L2CA | M_DMA_NO_DSCR_UPDT, SS_CSR(R_SER_DMA_CONFIG1_TX));
+        __raw_writeq(s->dma_dac.descrtab_phys, SS_CSR(R_SER_DMA_DSCR_BASE_TX));
 
         /* Prep the receive DMA descriptor ring */
-        out64(DMA_DESCR, SS_CSR(R_SER_DMA_DSCR_COUNT_RX));
+        __raw_writeq(DMA_DESCR, SS_CSR(R_SER_DMA_DSCR_COUNT_RX));
 
-        out64(M_SYNCSER_DMA_RX_EN | M_SYNCSER_DMA_TX_EN, SS_CSR(R_SER_DMA_ENABLE));
+        __raw_writeq(M_SYNCSER_DMA_RX_EN | M_SYNCSER_DMA_TX_EN, SS_CSR(R_SER_DMA_ENABLE));
 
-        out64((M_SYNCSER_RX_SYNC_ERR | M_SYNCSER_RX_OVERRUN | M_SYNCSER_RX_EOP_COUNT),
+        __raw_writeq((M_SYNCSER_RX_SYNC_ERR | M_SYNCSER_RX_OVERRUN | M_SYNCSER_RX_EOP_COUNT),
               SS_CSR(R_SER_INT_MASK));
 
         /* Enable the rx/tx; let the codec warm up to the sync and
            start sending good frames before the receive FIFO is
            enabled */
-        out64(M_SYNCSER_CMD_TX_EN, SS_CSR(R_SER_CMD));
+        __raw_writeq(M_SYNCSER_CMD_TX_EN, SS_CSR(R_SER_CMD));
         udelay(1000);
-        out64(M_SYNCSER_CMD_RX_EN | M_SYNCSER_CMD_TX_EN, SS_CSR(R_SER_CMD));
+        __raw_writeq(M_SYNCSER_CMD_RX_EN | M_SYNCSER_CMD_TX_EN, SS_CSR(R_SER_CMD));
 
         /* XXXKW is this magic? (the "1" part) */
-        while ((in64(SS_CSR(R_SER_STATUS)) & 0xf1) != 1)
+        while ((__raw_readq(SS_CSR(R_SER_STATUS)) & 0xf1) != 1)
                 ;
 
         CS_DBGOUT(CS_INIT, 4, 
                   printk(KERN_INFO "cs4297a: status: %08x\n",
-                         (unsigned int)(in64(SS_CSR(R_SER_STATUS)) & 0xffffffff)));
+                         (unsigned int)(__raw_readq(SS_CSR(R_SER_STATUS)) & 0xffffffff)));
 
         return 0;
 }
@@ -752,8 +754,8 @@
 
                 descr = &d->descrtab[swptr];
                 data_p = &d->dma_buf[swptr * 4];
-                *data_p = data;
-                out64(1, SS_CSR(R_SER_DMA_DSCR_COUNT_TX));
+		*data_p = cpu_to_be64(data);
+                __raw_writeq(1, SS_CSR(R_SER_DMA_DSCR_COUNT_TX));
                 CS_DBGOUT(CS_DESCR, 4,
                           printk(KERN_INFO "cs4297a: add_tx  %p (%x -> %x)\n",
                                  data_p, swptr, d->hwptr));
@@ -807,7 +809,7 @@
         /* XXXKW what do I really want here?  My theory for now is
            that I just flip the "ena" bit, and the interrupt handler
            will stop processing the xmit channel */
-        out64((s->ena & FMODE_READ) ? M_SYNCSER_DMA_RX_EN : 0,
+        __raw_writeq((s->ena & FMODE_READ) ? M_SYNCSER_DMA_RX_EN : 0,
               SS_CSR(R_SER_DMA_ENABLE));
 #endif
 
@@ -926,11 +928,11 @@
         serdma_descr_t *descr;
 
 	// update ADC pointer 
-        status = intflag ? in64(SS_CSR(R_SER_STATUS)) : 0;
+        status = intflag ? __raw_readq(SS_CSR(R_SER_STATUS)) : 0;
 
 	if ((s->ena & FMODE_READ) || (status & (M_SYNCSER_RX_EOP_COUNT))) {
                 d = &s->dma_adc;
-                hwptr = (unsigned) (((in64(SS_CSR(R_SER_DMA_CUR_DSCR_ADDR_RX)) & M_DMA_CURDSCR_ADDR) -
+                hwptr = (unsigned) (((__raw_readq(SS_CSR(R_SER_DMA_CUR_DSCR_ADDR_RX)) & M_DMA_CURDSCR_ADDR) -
                                      d->descrtab_phys) / sizeof(serdma_descr_t));
 
                 if (s->ena & FMODE_READ) {
@@ -944,12 +946,12 @@
                         s_ptr = (u32 *)&(d->dma_buf[d->swptr*4]);
                         descr = &d->descrtab[d->swptr];
                         while (diff2--) {
-                                u64 data = *(u64 *)s_ptr;
+				u64 data = be64_to_cpu(*(u64 *)s_ptr);
                                 u64 descr_a;
                                 u16 left, right;
                                 descr_a = descr->descr_a;
                                 descr->descr_a &= ~M_DMA_SERRX_SOP;
-                                if ((descr_a & M_DMA_DSCRA_A_ADDR) != PHYSADDR((int)s_ptr)) {
+                                if ((descr_a & M_DMA_DSCRA_A_ADDR) != CPHYSADDR((long)s_ptr)) {
                                         printk(KERN_ERR "cs4297a: RX Bad address (read)\n");
                                 }
                                 if (((data & 0x9800000000000000) != 0x9800000000000000) ||
@@ -971,10 +973,11 @@
                                         continue;
                                 }
                                 good_diff++;
-                                left = ((s_ptr[1] & 0xff) << 8) | ((s_ptr[2] >> 24) & 0xff);
-                                right = (s_ptr[2] >> 4) & 0xffff;
-                                *d->sb_hwptr++ = left;
-                                *d->sb_hwptr++ = right;
+				left = ((be32_to_cpu(s_ptr[1]) & 0xff) << 8) |
+				       ((be32_to_cpu(s_ptr[2]) >> 24) & 0xff);
+				right = (be32_to_cpu(s_ptr[2]) >> 4) & 0xffff;
+				*d->sb_hwptr++ = cpu_to_be16(left);
+				*d->sb_hwptr++ = cpu_to_be16(right);
                                 if (d->sb_hwptr == d->sb_end)
                                         d->sb_hwptr = d->sample_buf;
                                 descr++;
@@ -991,7 +994,7 @@
                                 printk(KERN_ERR "cs4297a: bogus receive overflow!!\n");
                         }
                         d->swptr = (d->swptr + diff) % d->ringsz;
-                        out64(diff, SS_CSR(R_SER_DMA_DSCR_COUNT_RX));
+                        __raw_writeq(diff, SS_CSR(R_SER_DMA_DSCR_COUNT_RX));
                         if (d->mapped) {
                                 if (d->count >= (signed) d->fragsize)
                                         wake_up(&d->wait);
@@ -1019,11 +1022,11 @@
                            here because of an interrupt, so there must
                            be a buffer to process. */
                         do {
-                                data = *data_p;
-                                if ((descr->descr_a & M_DMA_DSCRA_A_ADDR) != PHYSADDR((int)data_p)) {
-                                        printk(KERN_ERR "cs4297a: RX Bad address %d (%x %x)\n", d->swptr,
-                                               (int)(descr->descr_a & M_DMA_DSCRA_A_ADDR),
-                                               (int)PHYSADDR((int)data_p));
+				data = be64_to_cpu(*data_p);
+                                if ((descr->descr_a & M_DMA_DSCRA_A_ADDR) != CPHYSADDR((long)data_p)) {
+                                        printk(KERN_ERR "cs4297a: RX Bad address %d (%llx %lx)\n", d->swptr,
+                                               (long long)(descr->descr_a & M_DMA_DSCRA_A_ADDR),
+                                               (long)CPHYSADDR((long)data_p));
                                 }
                                 if (!(data & (1LL << 63)) ||
                                     !(descr->descr_a & M_DMA_SERRX_SOP) ||
@@ -1047,7 +1050,7 @@
                                         d->swptr = 0;
                                         data_p = d->dma_buf;
                                 }
-                                out64(1, SS_CSR(R_SER_DMA_DSCR_COUNT_RX));
+                                __raw_writeq(1, SS_CSR(R_SER_DMA_DSCR_COUNT_RX));
                         } while (--diff);
                         d->hwptr = hwptr;
 
@@ -1072,7 +1075,7 @@
 	//
 	if (s->ena & FMODE_WRITE) {
                 serdma_t *d = &s->dma_dac;
-                hwptr = (unsigned) (((in64(SS_CSR(R_SER_DMA_CUR_DSCR_ADDR_TX)) & M_DMA_CURDSCR_ADDR) -
+                hwptr = (unsigned) (((__raw_readq(SS_CSR(R_SER_DMA_CUR_DSCR_ADDR_TX)) & M_DMA_CURDSCR_ADDR) -
                                      d->descrtab_phys) / sizeof(serdma_descr_t));
                 diff = (d->ringsz + hwptr - d->hwptr) % d->ringsz;
                 CS_DBGOUT(CS_WAVE_WRITE, 4, printk(KERN_INFO
@@ -1611,7 +1614,7 @@
         if (nonblock)
                 return -EBUSY;
 	add_wait_queue(&s->dma_dac.wait, &wait);
-        while ((count = in64(SS_CSR(R_SER_DMA_DSCR_COUNT_TX))) ||
+        while ((count = __raw_readq(SS_CSR(R_SER_DMA_DSCR_COUNT_TX))) ||
                (s->dma_dac.count > 0)) {
                 if (!signal_pending(current)) {
                         set_current_state(TASK_INTERRUPTIBLE);
@@ -1624,7 +1627,7 @@
         }
         spin_lock_irqsave(&s->lock, flags);
         /* Reset the bookkeeping */
-        hwptr = (int)(((in64(SS_CSR(R_SER_DMA_CUR_DSCR_ADDR_TX)) & M_DMA_CURDSCR_ADDR) -
+        hwptr = (int)(((__raw_readq(SS_CSR(R_SER_DMA_CUR_DSCR_ADDR_TX)) & M_DMA_CURDSCR_ADDR) -
                        s->dma_dac.descrtab_phys) / sizeof(serdma_descr_t));
         s->dma_dac.hwptr = s->dma_dac.swptr = hwptr;
         spin_unlock_irqrestore(&s->lock, flags);
@@ -1787,7 +1790,6 @@
                 u32 *s_tmpl;
                 u32 *t_tmpl;
                 u32 left, right;
-                /* XXXKW check system endian here ... */
                 int swap = (s->prop_dac.fmt == AFMT_S16_LE) || (s->prop_dac.fmt == AFMT_U16_LE);
                 
                 /* XXXXXX this is broken for BLOAT_FACTOR */
@@ -1798,7 +1800,7 @@
 		}
 		if (d->underrun) {
 			d->underrun = 0;
-                        hwptr = (unsigned) (((in64(SS_CSR(R_SER_DMA_CUR_DSCR_ADDR_TX)) & M_DMA_CURDSCR_ADDR) -
+                        hwptr = (unsigned) (((__raw_readq(SS_CSR(R_SER_DMA_CUR_DSCR_ADDR_TX)) & M_DMA_CURDSCR_ADDR) -
                                              d->descrtab_phys) / sizeof(serdma_descr_t));
 			d->swptr = d->hwptr = hwptr;
 		}
@@ -1828,21 +1830,21 @@
 
                 /* XXXKW assuming 16-bit stereo! */
                 do {
-                        t_tmpl[0] = 0x98000000;
-                        left = s_tmpl[0] >> 16;
-                        if (left & 0x8000)
-                                left |= 0xf0000;
-                        right = s_tmpl[0] & 0xffff;
-                        if (right & 0x8000)
-                                right |= 0xf0000;
-                        if (swap) {
-                          t_tmpl[1] = left & 0xff;
-                          t_tmpl[2] = ((left & 0xff00) << 16) | ((right & 0xff) << 12) |
-                              ((right & 0xff00) >> 4);
-                        } else {
-                          t_tmpl[1] = left >> 8;
-                          t_tmpl[2] = ((left & 0xff) << 24) | (right << 4);
-                        }
+			u32 tmp;
+
+			t_tmpl[0] = cpu_to_be32(0x98000000);
+
+			tmp = be32_to_cpu(s_tmpl[0]);
+			left = tmp & 0xffff;
+			right = tmp >> 16;
+			if (swap) {
+				left = swab16(left);
+				right = swab16(right);
+			}
+			t_tmpl[1] = cpu_to_be32(left >> 8);
+			t_tmpl[2] = cpu_to_be32(((left & 0xff) << 24) |
+						(right << 4));
+
                         s_tmpl++;
                         t_tmpl += 8;
                         copy_cnt -= 4;
@@ -1850,7 +1852,8 @@
 
                 /* Mux in any pending read/write accesses */
                 if (s->reg_request) {
-                        *(u64 *)(d->dma_buf + (swptr * 4)) |= s->reg_request;
+			*(u64 *)(d->dma_buf + (swptr * 4)) |=
+				cpu_to_be64(s->reg_request);
                         s->reg_request = 0;
                         wake_up(&s->dma_dac.reg_wait);
                 }
@@ -1860,7 +1863,7 @@
                                  "cs4297a: copy in %d to swptr %x\n", cnt, swptr));
 
 		swptr = (swptr + (cnt/FRAME_SAMPLE_BYTES)) % d->ringsz;
-                out64(cnt/FRAME_SAMPLE_BYTES, SS_CSR(R_SER_DMA_DSCR_COUNT_TX));
+                __raw_writeq(cnt/FRAME_SAMPLE_BYTES, SS_CSR(R_SER_DMA_DSCR_COUNT_TX));
 		spin_lock_irqsave(&s->lock, flags);
 		d->swptr = swptr;
 		d->count += cnt;
@@ -1993,20 +1996,20 @@
 			 "cs4297a: cs4297a_ioctl(): DSP_RESET\n"));
 		if (file->f_mode & FMODE_WRITE) {
 			stop_dac(s);
-			synchronize_irq();
+			synchronize_irq(s->irq);
                         s->dma_dac.count = s->dma_dac.total_bytes =
                                 s->dma_dac.blocks = s->dma_dac.wakeup = 0;
 			s->dma_dac.swptr = s->dma_dac.hwptr =
-                                (int)(((in64(SS_CSR(R_SER_DMA_CUR_DSCR_ADDR_TX)) & M_DMA_CURDSCR_ADDR) -
+                                (int)(((__raw_readq(SS_CSR(R_SER_DMA_CUR_DSCR_ADDR_TX)) & M_DMA_CURDSCR_ADDR) -
                                        s->dma_dac.descrtab_phys) / sizeof(serdma_descr_t));
 		}
 		if (file->f_mode & FMODE_READ) {
 			stop_adc(s);
-			synchronize_irq();
+			synchronize_irq(s->irq);
                         s->dma_adc.count = s->dma_adc.total_bytes =
                                 s->dma_adc.blocks = s->dma_dac.wakeup = 0;
 			s->dma_adc.swptr = s->dma_adc.hwptr =
-                                (int)(((in64(SS_CSR(R_SER_DMA_CUR_DSCR_ADDR_RX)) & M_DMA_CURDSCR_ADDR) -
+                                (int)(((__raw_readq(SS_CSR(R_SER_DMA_CUR_DSCR_ADDR_RX)) & M_DMA_CURDSCR_ADDR) -
                                        s->dma_adc.descrtab_phys) / sizeof(serdma_descr_t));
 		}
 		return 0;
@@ -2378,7 +2381,7 @@
 		"cs4297a: cs4297a_open(): inode=0x%.8x file=0x%.8x f_mode=0x%x\n",
 			(unsigned) inode, (unsigned) file, file->f_mode));
 	CS_DBGOUT(CS_FUNCTION | CS_OPEN, 2, printk(KERN_INFO
-                "cs4297a: status = %08x\n", (int)in64(SS_CSR(R_SER_STATUS_DEBUG))));
+                "cs4297a: status = %08x\n", (int)__raw_readq(SS_CSR(R_SER_STATUS_DEBUG))));
 
 	list_for_each(entry, &cs4297a_devs)
 	{
@@ -2404,9 +2407,9 @@
 		return -ENODEV;
 	}
 	if (file->f_mode & FMODE_WRITE) {
-                if (in64(SS_CSR(R_SER_DMA_DSCR_COUNT_TX)) != 0) {
+                if (__raw_readq(SS_CSR(R_SER_DMA_DSCR_COUNT_TX)) != 0) {
                         printk(KERN_ERR "cs4297a: TX pipe needs to drain\n");
-                        while (in64(SS_CSR(R_SER_DMA_DSCR_COUNT_TX)))
+                        while (__raw_readq(SS_CSR(R_SER_DMA_DSCR_COUNT_TX)))
                                 ;
                 }
           
@@ -2501,12 +2504,12 @@
 	.release	= cs4297a_release,
 };
 
-static irqreturn_t cs4297a_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static void cs4297a_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	struct cs4297a_state *s = (struct cs4297a_state *) dev_id;
         u32 status;
 
-        status = in64(SS_CSR(R_SER_STATUS_DEBUG));
+        status = __raw_readq(SS_CSR(R_SER_STATUS_DEBUG));
 
         CS_DBGOUT(CS_INTERRUPT, 6, printk(KERN_INFO
                  "cs4297a: cs4297a_interrupt() HISR=0x%.8x\n", status));
@@ -2514,16 +2517,16 @@
 #if 0
         /* XXXKW what check *should* be done here? */
         if (!(status & (M_SYNCSER_RX_EOP_COUNT | M_SYNCSER_RX_OVERRUN | M_SYNCSER_RX_SYNC_ERR))) {
-                status = in64(SS_CSR(R_SER_STATUS));
+                status = __raw_readq(SS_CSR(R_SER_STATUS));
                 printk(KERN_ERR "cs4297a: unexpected interrupt (status %08x)\n", status);
-                return IRQ_HANDLED;
+                return;
         }
 #endif
 
         if (status & M_SYNCSER_RX_SYNC_ERR) {
-                status = in64(SS_CSR(R_SER_STATUS));
+                status = __raw_readq(SS_CSR(R_SER_STATUS));
                 printk(KERN_ERR "cs4297a: rx sync error (status %08x)\n", status);
-                return IRQ_HANDLED;
+                return;
         }
 
         if (status & M_SYNCSER_RX_OVERRUN) {
@@ -2533,9 +2536,9 @@
 
                 /* Fix things up: get the receive descriptor pool
                    clean and give them back to the hardware */
-                while (in64(SS_CSR(R_SER_DMA_DSCR_COUNT_RX)))
+                while (__raw_readq(SS_CSR(R_SER_DMA_DSCR_COUNT_RX)))
                         ;
-                newptr = (unsigned) (((in64(SS_CSR(R_SER_DMA_CUR_DSCR_ADDR_RX)) & M_DMA_CURDSCR_ADDR) -
+                newptr = (unsigned) (((__raw_readq(SS_CSR(R_SER_DMA_CUR_DSCR_ADDR_RX)) & M_DMA_CURDSCR_ADDR) -
                                      s->dma_adc.descrtab_phys) / sizeof(serdma_descr_t));
                 for (i=0; i<DMA_DESCR; i++) {
                         s->dma_adc.descrtab[i].descr_a &= ~M_DMA_SERRX_SOP;
@@ -2543,7 +2546,7 @@
                 s->dma_adc.swptr = s->dma_adc.hwptr = newptr;
                 s->dma_adc.count = 0;
                 s->dma_adc.sb_swptr = s->dma_adc.sb_hwptr = s->dma_adc.sample_buf;
-                out64(DMA_DESCR, SS_CSR(R_SER_DMA_DSCR_COUNT_RX));
+                __raw_writeq(DMA_DESCR, SS_CSR(R_SER_DMA_DSCR_COUNT_RX));
         }
 
 	spin_lock(&s->lock);
@@ -2552,9 +2555,9 @@
 
 	CS_DBGOUT(CS_INTERRUPT, 6, printk(KERN_INFO
 		  "cs4297a: cs4297a_interrupt()-\n"));
-	return IRQ_HANDLED;
 }
 
+#if 0
 static struct initvol {
 	int mixch;
 	int vol;
@@ -2570,26 +2573,31 @@
 	{SOUND_MIXER_WRITE_SPEAKER, 0x4040},
 	{SOUND_MIXER_WRITE_MIC, 0x0000}
 };
+#endif
 
 static int __init cs4297a_init(void)
 {
 	struct cs4297a_state *s;
-        u64 cfg;
-        u32 pwr, id;
+	u32 pwr, id;
 	mm_segment_t fs;
-        int rval, mdio_val;
+	int rval;
+#ifndef CONFIG_BCM_CS4297A_CSWARM
+	u64 cfg;
+	int mdio_val;
+#endif
 
 	CS_DBGOUT(CS_INIT | CS_FUNCTION, 2, printk(KERN_INFO 
 		"cs4297a: cs4297a_init_module()+ \n"));
 
-        mdio_val = in64(KSEG1 + A_MAC_REGISTER(2, R_MAC_MDIO)) &
+#ifndef CONFIG_BCM_CS4297A_CSWARM
+        mdio_val = __raw_readq(KSEG1 + A_MAC_REGISTER(2, R_MAC_MDIO)) &
                 (M_MAC_MDIO_DIR|M_MAC_MDIO_OUT);
 
         /* Check syscfg for synchronous serial on port 1 */
-        cfg = in64(KSEG1 + A_SCD_SYSTEM_CFG);
+        cfg = __raw_readq(KSEG1 + A_SCD_SYSTEM_CFG);
         if (!(cfg & M_SYS_SER1_ENABLE)) {
-                out64(cfg | M_SYS_SER1_ENABLE, KSEG1+A_SCD_SYSTEM_CFG);
-                cfg = in64(KSEG1 + A_SCD_SYSTEM_CFG);
+                __raw_writeq(cfg | M_SYS_SER1_ENABLE, KSEG1+A_SCD_SYSTEM_CFG);
+                cfg = __raw_readq(KSEG1 + A_SCD_SYSTEM_CFG);
                 if (!(cfg & M_SYS_SER1_ENABLE)) {
                   printk(KERN_INFO "cs4297a: serial port 1 not configured for synchronous operation\n");
                   return -1;
@@ -2599,14 +2607,15 @@
                 
                 /* Force the codec (on SWARM) to reset by clearing
                    GENO, preserving MDIO (no effect on CSWARM) */
-                out64(mdio_val, KSEG1+A_MAC_REGISTER(2, R_MAC_MDIO));
+                __raw_writeq(mdio_val, KSEG1+A_MAC_REGISTER(2, R_MAC_MDIO));
                 udelay(10);
         }
 
         /* Now set GENO */
-        out64(mdio_val | M_MAC_GENC, KSEG1+A_MAC_REGISTER(2, R_MAC_MDIO));
+        __raw_writeq(mdio_val | M_MAC_GENC, KSEG1+A_MAC_REGISTER(2, R_MAC_MDIO));
         /* Give the codec some time to finish resetting (start the bit clock) */
         udelay(100);
+#endif
 
 	if (!(s = kmalloc(sizeof(struct cs4297a_state), GFP_KERNEL))) {
 		CS_DBGOUT(CS_ERROR, 1, printk(KERN_ERR
@@ -2659,6 +2668,8 @@
         } while (!rval && (pwr != 0xf));
 
         if (!rval) {
+		char *sb1250_duart_present;
+
                 fs = get_fs();
                 set_fs(KERNEL_DS);
 #if 0
@@ -2679,7 +2690,11 @@
                 list_add(&s->list, &cs4297a_devs);
 
                 cs4297a_read_ac97(s, AC97_VENDOR_ID1, &id);
-                
+
+		sb1250_duart_present = symbol_get(sb1250_duart_present);
+		if (sb1250_duart_present)
+			sb1250_duart_present[1] = 0;
+
                 printk(KERN_INFO "cs4297a: initialized (vendor id = %x)\n", id);
 
                 CS_DBGOUT(CS_INIT | CS_FUNCTION, 2,
@@ -2718,9 +2733,7 @@
 
 // --------------------------------------------------------------------- 
 
-EXPORT_NO_SYMBOLS;
-
-MODULE_AUTHOR("Kip Walker, kwalker@broadcom.com");
+MODULE_AUTHOR("Kip Walker, Broadcom Corp.");
 MODULE_DESCRIPTION("Cirrus Logic CS4297a Driver for Broadcom SWARM board");
 
 // --------------------------------------------------------------------- 
diff -Nru a/sound/oss/sys_timer.c b/sound/oss/sys_timer.c
--- a/sound/oss/sys_timer.c	2005-03-01 23:38:57 -08:00
+++ b/sound/oss/sys_timer.c	2005-03-01 23:38:57 -08:00
@@ -27,7 +27,7 @@
 static unsigned long prev_event_time;
 
 static void     poll_def_tmr(unsigned long dummy);
-static spinlock_t lock=SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(lock);
 
 static struct timer_list def_tmr = TIMER_INITIALIZER(poll_def_tmr, 0, 0);
 
diff -Nru a/sound/oss/trident.c b/sound/oss/trident.c
--- a/sound/oss/trident.c	2005-03-01 23:39:08 -08:00
+++ b/sound/oss/trident.c	2005-03-01 23:39:08 -08:00
@@ -4014,7 +4014,8 @@
 	}
 }
 
-struct proc_dir_entry *res;
+static struct proc_dir_entry *res;
+
 static int
 ali_write_proc(struct file *file, const char __user *buffer, unsigned long count, void *data)
 {
diff -Nru a/sound/oss/trix.c b/sound/oss/trix.c
--- a/sound/oss/trix.c	2005-03-01 23:38:51 -08:00
+++ b/sound/oss/trix.c	2005-03-01 23:38:51 -08:00
@@ -413,16 +413,16 @@
 static int __initdata mpu_io	= -1;
 static int __initdata mpu_irq	= -1;
 
-MODULE_PARM(io,"i");
-MODULE_PARM(irq,"i");
-MODULE_PARM(dma,"i");
-MODULE_PARM(dma2,"i");
-MODULE_PARM(sb_io,"i");
-MODULE_PARM(sb_dma,"i");
-MODULE_PARM(sb_irq,"i");
-MODULE_PARM(mpu_io,"i");
-MODULE_PARM(mpu_irq,"i");
-MODULE_PARM(joystick, "i");
+module_param(io, int, 0);
+module_param(irq, int, 0);
+module_param(dma, int, 0);
+module_param(dma2, int, 0);
+module_param(sb_io, int, 0);
+module_param(sb_dma, int, 0);
+module_param(sb_irq, int, 0);
+module_param(mpu_io, int, 0);
+module_param(mpu_irq, int, 0);
+module_param(joystick, bool, 0);
 
 static int __init init_trix(void)
 {
diff -Nru a/sound/oss/uart401.c b/sound/oss/uart401.c
--- a/sound/oss/uart401.c	2005-03-01 23:39:09 -08:00
+++ b/sound/oss/uart401.c	2005-03-01 23:39:09 -08:00
@@ -430,11 +430,11 @@
 
 static struct address_info cfg_mpu;
 
-static int __initdata io = -1;
-static int __initdata irq = -1;
+static int io = -1;
+static int irq = -1;
 
-MODULE_PARM(io, "i");
-MODULE_PARM(irq, "i");
+module_param(io, int, 0444);
+module_param(irq, int, 0444);
 
 
 static int __init init_uart401(void)
diff -Nru a/sound/oss/uart6850.c b/sound/oss/uart6850.c
--- a/sound/oss/uart6850.c	2005-03-01 23:39:07 -08:00
+++ b/sound/oss/uart6850.c	2005-03-01 23:39:07 -08:00
@@ -72,7 +72,7 @@
 static int uart6850_irq;
 static int uart6850_detected;
 static int my_dev;
-static spinlock_t lock=SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(lock);
 
 static void (*midi_input_intr) (int dev, unsigned char data);
 static void poll_uart6850(unsigned long dummy);
@@ -316,8 +316,8 @@
 static int __initdata io = -1;
 static int __initdata irq = -1;
 
-MODULE_PARM(io,"i");
-MODULE_PARM(irq,"i");
+module_param(io, int, 0);
+module_param(irq, int, 0);
 
 static int __init init_uart6850(void)
 {
diff -Nru a/sound/oss/via82cxxx_audio.c b/sound/oss/via82cxxx_audio.c
--- a/sound/oss/via82cxxx_audio.c	2005-03-01 23:38:54 -08:00
+++ b/sound/oss/via82cxxx_audio.c	2005-03-01 23:38:54 -08:00
@@ -62,11 +62,6 @@
         }
 #endif
 
-#if defined(CONFIG_PROC_FS) && \
-    defined(CONFIG_SOUND_VIA82CXXX_PROCFS)
-#define VIA_PROC_FS 1
-#endif
-
 #define VIA_SUPPORT_MMAP 1 /* buggy, for now... */
 
 #define MAX_CARDS	1
@@ -366,18 +361,6 @@
 static void via_chan_pcm_fmt (struct via_channel *chan, int reset);
 static void via_chan_buffer_free (struct via_info *card, struct via_channel *chan);
 
-#ifdef VIA_PROC_FS
-static int via_init_proc (void);
-static void via_cleanup_proc (void);
-static int via_card_init_proc (struct via_info *card);
-static void via_card_cleanup_proc (struct via_info *card);
-#else
-static inline int via_init_proc (void) { return 0; }
-static inline void via_cleanup_proc (void) {}
-static inline int via_card_init_proc (struct via_info *card) { return 0; }
-static inline void via_card_cleanup_proc (struct via_info *card) {}
-#endif
-
 
 /****************************************************************
  *
@@ -2179,7 +2162,7 @@
 #endif /* VM_RESERVED */
 
 
-struct vm_operations_struct via_mm_ops = {
+static struct vm_operations_struct via_mm_ops = {
 	.nopage		= via_mm_nopage,
 
 #ifndef VM_RESERVED
@@ -3484,21 +3467,12 @@
 	}
 
 	/*
-	 * per-card /proc info
-	 */
-	rc = via_card_init_proc (card);
-	if (rc) {
-		printk (KERN_ERR PFX "card-specific /proc init failed, aborting\n");
-		goto err_out_have_dsp;
-	}
-
-	/*
 	 * init and turn on interrupts, as the last thing we do
 	 */
 	rc = via_interrupt_init (card);
 	if (rc) {
 		printk (KERN_ERR PFX "interrupt init failed, aborting\n");
-		goto err_out_have_proc;
+		goto err_out_have_dsp;
 	}
 
 	printk (KERN_INFO PFX "board #%d at 0x%04lX, IRQ %d\n",
@@ -3538,9 +3512,6 @@
 	DPRINTK ("EXIT, returning 0\n");
 	return 0;
 
-err_out_have_proc:
-	via_card_cleanup_proc (card);
-
 err_out_have_dsp:
 	via_dsp_cleanup (card);
 
@@ -3582,7 +3553,6 @@
 #endif
 
 	free_irq (card->pdev->irq, card);
-	via_card_cleanup_proc (card);
 	via_dsp_cleanup (card);
 	via_ac97_cleanup (card);
 
@@ -3615,15 +3585,8 @@
 
 	DPRINTK ("ENTER\n");
 
-	rc = via_init_proc ();
-	if (rc) {
-		DPRINTK ("EXIT, returning %d\n", rc);
-		return rc;
-	}
-
 	rc = pci_register_driver (&via_driver);
 	if (rc) {
-		via_cleanup_proc ();
 		DPRINTK ("EXIT, returning %d\n", rc);
 		return rc;
 	}
@@ -3638,7 +3601,6 @@
 	DPRINTK ("ENTER\n");
 
 	pci_unregister_driver (&via_driver);
-	via_cleanup_proc ();
 
 	DPRINTK ("EXIT\n");
 }
@@ -3651,181 +3613,3 @@
 MODULE_DESCRIPTION("DSP audio and mixer driver for Via 82Cxxx audio devices");
 MODULE_LICENSE("GPL");
 
-
-#ifdef VIA_PROC_FS
-
-/****************************************************************
- *
- * /proc/driver/via/info
- *
- *
- */
-
-static int via_info_read_proc (char *page, char **start, off_t off,
-			       int count, int *eof, void *data)
-{
-#define YN(val,bit) (((val) & (bit)) ? "yes" : "no")
-#define ED(val,bit) (((val) & (bit)) ? "enable" : "disable")
-
-	int len = 0;
-	u8 r40, r41, r42, r44;
-	struct via_info *card = data;
-
-	DPRINTK ("ENTER\n");
-
-	assert (card != NULL);
-
-	len += sprintf (page+len, VIA_CARD_NAME "\n\n");
-
-	pci_read_config_byte (card->pdev, 0x40, &r40);
-	pci_read_config_byte (card->pdev, 0x41, &r41);
-	pci_read_config_byte (card->pdev, 0x42, &r42);
-	pci_read_config_byte (card->pdev, 0x44, &r44);
-
-	len += sprintf (page+len,
-		"Via 82Cxxx PCI registers:\n"
-		"\n"
-		"40  Codec Ready: %s\n"
-		"    Codec Low-power: %s\n"
-		"    Secondary Codec Ready: %s\n"
-		"\n"
-		"41  Interface Enable: %s\n"
-		"    De-Assert Reset: %s\n"
-		"    Force SYNC high: %s\n"
-		"    Force SDO high: %s\n"
-		"    Variable Sample Rate On-Demand Mode: %s\n"
-		"    SGD Read Channel PCM Data Out: %s\n"
-		"    FM Channel PCM Data Out: %s\n"
-		"    SB PCM Data Out: %s\n"
-		"\n"
-		"42  Game port enabled: %s\n"
-		"    SoundBlaster enabled: %s\n"
-		"    FM enabled: %s\n"
-		"    MIDI enabled: %s\n"
-		"\n"
-		"44  AC-Link Interface Access: %s\n"
-		"    Secondary Codec Support: %s\n"
-
-		"\n",
-
-		YN (r40, VIA_CR40_AC97_READY),
-		YN (r40, VIA_CR40_AC97_LOW_POWER),
-		YN (r40, VIA_CR40_SECONDARY_READY),
-
-		ED (r41, VIA_CR41_AC97_ENABLE),
-		YN (r41, (1 << 6)),
-		YN (r41, (1 << 5)),
-		YN (r41, (1 << 4)),
-		ED (r41, (1 << 3)),
-		ED (r41, (1 << 2)),
-		ED (r41, (1 << 1)),
-		ED (r41, (1 << 0)),
-
-		YN (r42, VIA_CR42_GAME_ENABLE),
-		YN (r42, VIA_CR42_SB_ENABLE),
-		YN (r42, VIA_CR42_FM_ENABLE),
-		YN (r42, VIA_CR42_MIDI_ENABLE),
-
-		YN (r44, VIA_CR44_AC_LINK_ACCESS),
-		YN (r44, VIA_CR44_SECOND_CODEC_SUPPORT)
-
-		);
-
-	DPRINTK ("EXIT, returning %d\n", len);
-	return len;
-
-#undef YN
-#undef ED
-}
-
-
-/****************************************************************
- *
- * /proc/driver/via/... setup and cleanup
- *
- *
- */
-
-static int __init via_init_proc (void)
-{
-	DPRINTK ("ENTER\n");
-
-	if (!proc_mkdir ("driver/via", 0))
-		return -EIO;
-
-	DPRINTK ("EXIT, returning 0\n");
-	return 0;
-}
-
-
-static void via_cleanup_proc (void)
-{
-	DPRINTK ("ENTER\n");
-
-	remove_proc_entry ("driver/via", NULL);
-
-	DPRINTK ("EXIT\n");
-}
-
-
-static int __devinit via_card_init_proc (struct via_info *card)
-{
-	char s[32];
-	int rc;
-
-	DPRINTK ("ENTER\n");
-
-	sprintf (s, "driver/via/%d", card->card_num);
-	if (!proc_mkdir (s, 0)) {
-		rc = -EIO;
-		goto err_out_none;
-	}
-
-	sprintf (s, "driver/via/%d/info", card->card_num);
-	if (!create_proc_read_entry (s, 0, 0, via_info_read_proc, card)) {
-		rc = -EIO;
-		goto err_out_dir;
-	}
-
-	sprintf (s, "driver/via/%d/ac97", card->card_num);
-	if (!create_proc_read_entry (s, 0, 0, ac97_read_proc, card->ac97)) {
-		rc = -EIO;
-		goto err_out_info;
-	}
-
-	DPRINTK ("EXIT, returning 0\n");
-	return 0;
-
-err_out_info:
-	sprintf (s, "driver/via/%d/info", card->card_num);
-	remove_proc_entry (s, NULL);
-
-err_out_dir:
-	sprintf (s, "driver/via/%d", card->card_num);
-	remove_proc_entry (s, NULL);
-
-err_out_none:
-	DPRINTK ("EXIT, returning %d\n", rc);
-	return rc;
-}
-
-
-static void via_card_cleanup_proc (struct via_info *card)
-{
-	char s[32];
-
-	DPRINTK ("ENTER\n");
-
-	sprintf (s, "driver/via/%d/ac97", card->card_num);
-	remove_proc_entry (s, NULL);
-
-	sprintf (s, "driver/via/%d/info", card->card_num);
-	remove_proc_entry (s, NULL);
-
-	sprintf (s, "driver/via/%d", card->card_num);
-	remove_proc_entry (s, NULL);
-
-	DPRINTK ("EXIT\n");
-}
-
-#endif /* VIA_PROC_FS */
diff -Nru a/sound/oss/vwsnd.c b/sound/oss/vwsnd.c
--- a/sound/oss/vwsnd.c	2005-03-01 23:38:58 -08:00
+++ b/sound/oss/vwsnd.c	2005-03-01 23:38:58 -08:00
@@ -256,7 +256,7 @@
 {
 	static void li_destroy(lithium_t *);
 
-	lith->lock = SPIN_LOCK_UNLOCKED;
+	spin_lock_init(&lith->lock);
 	lith->page0 = ioremap_nocache(baseaddr + LI_PAGE0_OFFSET, PAGE_SIZE);
 	lith->page1 = ioremap_nocache(baseaddr + LI_PAGE1_OFFSET, PAGE_SIZE);
 	lith->page2 = ioremap_nocache(baseaddr + LI_PAGE2_OFFSET, PAGE_SIZE);
@@ -3380,13 +3380,13 @@
 	init_MUTEX(&devc->io_sema);
 	init_MUTEX(&devc->mix_sema);
 	devc->open_mode = 0;
-	devc->rport.lock = SPIN_LOCK_UNLOCKED;
+	spin_lock_init(&devc->rport.lock);
 	init_waitqueue_head(&devc->rport.queue);
 	devc->rport.swstate = SW_OFF;
 	devc->rport.hwstate = HW_STOPPED;
 	devc->rport.flags = 0;
 	devc->rport.swbuf = NULL;
-	devc->wport.lock = SPIN_LOCK_UNLOCKED;
+	spin_lock_init(&devc->wport.lock);
 	init_waitqueue_head(&devc->wport.queue);
 	devc->wport.swstate = SW_OFF;
 	devc->wport.hwstate = HW_STOPPED;
diff -Nru a/sound/oss/waveartist.c b/sound/oss/waveartist.c
--- a/sound/oss/waveartist.c	2005-03-01 23:39:18 -08:00
+++ b/sound/oss/waveartist.c	2005-03-01 23:39:18 -08:00
@@ -146,7 +146,7 @@
 
 static int		nr_waveartist_devs;
 static wavnc_info	adev_info[MAX_AUDIO_DEV];
-static spinlock_t	waveartist_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(waveartist_lock);
 
 #ifndef CONFIG_ARCH_NETWINDER
 #define machine_is_netwinder() 0
diff -Nru a/sound/oss/wavfront.c b/sound/oss/wavfront.c
--- a/sound/oss/wavfront.c	2005-03-01 23:38:58 -08:00
+++ b/sound/oss/wavfront.c	2005-03-01 23:38:58 -08:00
@@ -157,14 +157,14 @@
 		   board and load the firmware anyway.
 		*/
 		   
-int fx_raw = 1; /* if this is zero, we'll leave the FX processor in
-		   whatever state it is when the driver is loaded.
-		   The default is to download the microprogram and
-		   associated coefficients to set it up for "default"
-		   operation, whatever that means.
-		*/
+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.
+		          The default is to download the microprogram and
+		          associated coefficients to set it up for "default"
+		          operation, whatever that means.
+		       */
 
-int debug_default;      /* you can set this to control debugging
+static int debug_default;  /* you can set this to control debugging
 			      during driver loading. it takes any combination
 			      of the WF_DEBUG_* flags defined in
 			      wavefront.h
@@ -172,44 +172,46 @@
 
 /* XXX this needs to be made firmware and hardware version dependent */
 
-char *ospath = "/etc/sound/wavefront.os"; /* where to find a processed
-					     version of the WaveFront OS
-					  */
-
-int wait_polls = 2000;	/* This is a number of tries we poll the status register
-			   before resorting to sleeping. WaveFront being an ISA
-			   card each poll takes about 1.2us. So before going to
-			   sleep we wait up to 2.4ms in a loop.
-			*/
+static char *ospath = "/etc/sound/wavefront.os"; /* where to find a processed
+					            version of the WaveFront OS
+					          */
+
+static int wait_polls = 2000; /* This is a number of tries we poll the
+				 status register before resorting to sleeping.
+				 WaveFront being an ISA card each poll takes
+				 about 1.2us. So before going to
+			         sleep we wait up to 2.4ms in a loop.
+			     */
+
+static int sleep_length = HZ/100; /* This says how long we're going to
+				     sleep between polls.
+			             10ms sounds reasonable for fast response.
+			          */
 
-int sleep_length = HZ/100; /* This says how long we're going to sleep between polls.
-			      10ms sounds reasonable for fast response.
-			   */
+static int sleep_tries = 50;       /* Wait for status 0.5 seconds total. */
 
-int sleep_tries = 50;       /* Wait for status 0.5 seconds total. */
-
-int reset_time = 2;        /* hundreths of a second we wait after a HW reset for
+static int reset_time = 2; /* hundreths of a second we wait after a HW reset for
 			      the expected interrupt.
 			   */
 
-int ramcheck_time = 20;    /* time in seconds to wait while ROM code
-			      checks on-board RAM.
-			   */
-
-int osrun_time = 10;       /* time in seconds we wait for the OS to
-			      start running.
-			   */
-
-MODULE_PARM(wf_raw,"i");
-MODULE_PARM(fx_raw,"i");
-MODULE_PARM(debug_default,"i");
-MODULE_PARM(wait_polls,"i");
-MODULE_PARM(sleep_length,"i");
-MODULE_PARM(sleep_tries,"i");
-MODULE_PARM(ospath,"s");
-MODULE_PARM(reset_time,"i");
-MODULE_PARM(ramcheck_time,"i");
-MODULE_PARM(osrun_time,"i");
+static int ramcheck_time = 20;    /* time in seconds to wait while ROM code
+			             checks on-board RAM.
+			          */
+
+static int osrun_time = 10;  /* time in seconds we wait for the OS to
+			        start running.
+			     */
+
+module_param(wf_raw, int, 0);
+module_param(fx_raw, int, 0);
+module_param(debug_default, int, 0);
+module_param(wait_polls, int, 0);
+module_param(sleep_length, int, 0);
+module_param(sleep_tries, int, 0);
+module_param(ospath, charp, 0);
+module_param(reset_time, int, 0);
+module_param(ramcheck_time, int, 0);
+module_param(osrun_time, int, 0);
 
 /***************************************************************************/
 
@@ -275,7 +277,7 @@
 	wait_queue_head_t interrupt_sleeper; 
 } dev;
 
-static spinlock_t lock=SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(lock);
 static int  detect_wffx(void);
 static int  wffx_ioctl (wavefront_fx_info *);
 static int  wffx_init (void);
@@ -2036,7 +2038,7 @@
 	}
 }
 
-int
+static int
 wavefront_oss_load_patch (int devno, int format, const char __user *addr,
 			  int offs, int count, int pmgr_flag)
 {
@@ -2165,7 +2167,7 @@
 7 Unused
 */
 
-int
+static int
 wavefront_interrupt_bits (int irq)
 
 {
@@ -2193,7 +2195,7 @@
 	return bits;
 }
 
-void
+static void
 wavefront_should_cause_interrupt (int val, int port, int timeout)
 
 {
@@ -2895,16 +2897,6 @@
 	return 0;
 }	
 
-int __init attach_wffx (void)
-{
-	if ((dev.fx_mididev = sound_alloc_mididev ()) < 0) {
-		printk (KERN_WARNING LOGNAME "cannot install FX Midi driver\n");
-		return -1;
-	}
-
-	return 0;
-}
-
 void
 wffx_mute (int onoff)
     
@@ -3490,8 +3482,8 @@
 MODULE_AUTHOR      ("Paul Barton-Davis <pbd@op.net>");
 MODULE_DESCRIPTION ("Turtle Beach WaveFront Linux Driver");
 MODULE_LICENSE("GPL");
-MODULE_PARM        (io,"i");
-MODULE_PARM        (irq,"i");
+module_param       (io, int, 0);
+module_param       (irq, int, 0);
 
 static int __init init_wavfront (void)
 {
diff -Nru a/sound/oss/wf_midi.c b/sound/oss/wf_midi.c
--- a/sound/oss/wf_midi.c	2005-03-01 23:38:52 -08:00
+++ b/sound/oss/wf_midi.c	2005-03-01 23:38:52 -08:00
@@ -81,7 +81,7 @@
 static struct wf_mpu_config *virt_dev = &devs[1];
 
 static void start_uart_mode (void);
-static spinlock_t lock=SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(lock);
 
 #define	OUTPUT_READY	0x40
 #define	INPUT_AVAIL	0x80
diff -Nru a/sound/oss/ymfpci.c b/sound/oss/ymfpci.c
--- a/sound/oss/ymfpci.c	2005-03-01 23:39:07 -08:00
+++ b/sound/oss/ymfpci.c	2005-03-01 23:39:07 -08:00
@@ -99,7 +99,7 @@
 static void ymfpci_download_image(ymfpci_t *codec);
 static void ymf_memload(ymfpci_t *unit);
 
-static spinlock_t ymf_devs_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(ymf_devs_lock);
 static LIST_HEAD(ymf_devs);
 
 /*
@@ -124,11 +124,6 @@
  *  common I/O routines
  */
 
-static inline u8 ymfpci_readb(ymfpci_t *codec, u32 offset)
-{
-	return readb(codec->reg_area_virt + offset);
-}
-
 static inline void ymfpci_writeb(ymfpci_t *codec, u32 offset, u8 val)
 {
 	writeb(val, codec->reg_area_virt + offset);
@@ -2504,8 +2499,8 @@
 # ifdef MODULE
 static int mpu_io;
 static int synth_io;
-MODULE_PARM(mpu_io, "i");
-MODULE_PARM(synth_io, "i");
+module_param(mpu_io, int, 0);
+module_param(synth_io, int, 0);
 # else
 static int mpu_io     = 0x330;
 static int synth_io   = 0x388;
diff -Nru a/sound/pci/Kconfig b/sound/pci/Kconfig
--- a/sound/pci/Kconfig	2005-03-01 23:38:55 -08:00
+++ b/sound/pci/Kconfig	2005-03-01 23:38:55 -08:00
@@ -54,7 +54,7 @@
 
 	  Supported features: Hardware Mixer, SRC, EQ and SPDIF output.
           3D support code is in place, but not yet useable. For more info, 
-          email the ALSA developer list, or mjander@users.sourceforge.net.
+          email the ALSA developer list, or <mjander@users.sourceforge.net>.
 
 	  To compile this driver as a module, choose M here: the module
 	  will be called snd-au8810.
@@ -68,7 +68,7 @@
 	  Say Y here to include support for Aureal Vortex soundcards.
 
           Supported features: Hardware Mixer and SRC. For more info, email 
-          the ALSA developer list, or mjander@users.sourceforge.net.
+          the ALSA developer list, or <mjander@users.sourceforge.net>.
 
 	  To compile this driver as a module, choose M here: the module
 	  will be called snd-au8820.
@@ -83,7 +83,7 @@
 
           Supported features: Hardware Mixer, SRC, EQ and SPDIF output.
           3D support code is in place, but not yet useable. For more info, 
-          email the ALSA developer list, or mjander@users.sourceforge.net.
+          email the ALSA developer list, or <mjander@users.sourceforge.net>.
 
 	  To compile this driver as a module, choose M here: the module
 	  will be called snd-au8830.
@@ -106,8 +106,9 @@
         depends on SND
 	select SND_PCM
         help
-	  Say Y here to include support for recording audio from TV
-	  cards based on Brooktree Bt878/Bt879 chips.
+	  If you want to record audio from TV cards based on
+	  Brooktree Bt878/Bt879 chips, say Y here and read
+	  <file:Documentation/sound/alsa/Bt87x.txt>.
 
 	  To compile this driver as a module, choose M here: the module
 	  will be called snd-bt87x.
@@ -171,6 +172,29 @@
 	  To compile this driver as a module, choose M here: the module
 	  will be called snd-emu10k1.
 
+config SND_EMU10K1X
+	tristate "Emu10k1X (Dell OEM Version)"
+	depends on SND
+	select SND_AC97_CODEC
+	select SND_RAWMIDI
+	help
+	  Say Y here to include support for the Dell OEM version of the
+	  Sound Blaster Live!.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-emu10k1x.
+
+config SND_CA0106
+	tristate "SB Audigy LS / Live 24bit"
+	depends on SND
+	select SND_AC97_CODEC
+	help
+	  Say Y here to include support for the Sound Blaster Audigy LS
+	  and Live 24bit.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-ca0106.
+
 config SND_KORG1212
 	tristate "Korg 1212 IO"
 	depends on SND
@@ -468,6 +492,17 @@
 
 	  To compile this driver as a module, choose M here: the module
 	  will be called snd-via82xx.
+
+config SND_VIA82XX_MODEM
+	tristate "VIA 82C686A/B, 8233 based Modems"
+	depends on SND
+	select SND_AC97_CODEC
+	help
+	  Say Y here to include support for the integrated MC97 modem on
+	  motherboards with VIA chipsets.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-via82xx-modem.
 
 config SND_VX222
 	tristate "Digigram VX222"
diff -Nru a/sound/pci/Makefile b/sound/pci/Makefile
--- a/sound/pci/Makefile	2005-03-01 23:38:44 -08:00
+++ b/sound/pci/Makefile	2005-03-01 23:38:44 -08:00
@@ -22,6 +22,7 @@
 snd-rme96-objs := rme96.o
 snd-sonicvibes-objs := sonicvibes.o
 snd-via82xx-objs := via82xx.o
+snd-via82xx-modem-objs := via82xx_modem.o
 
 # Toplevel Module Dependency
 obj-$(CONFIG_SND_ALS4000) += snd-als4000.o
@@ -43,11 +44,13 @@
 obj-$(CONFIG_SND_RME96) += snd-rme96.o
 obj-$(CONFIG_SND_SONICVIBES) += snd-sonicvibes.o
 obj-$(CONFIG_SND_VIA82XX) += snd-via82xx.o
+obj-$(CONFIG_SND_VIA82XX_MODEM) += snd-via82xx-modem.o
 
 obj-$(CONFIG_SND) += \
 	ac97/ \
 	ali5451/ \
 	au88x0/ \
+	ca0106/ \
 	cs46xx/ \
 	emu10k1/ \
 	ice1712/ \
diff -Nru a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c
--- a/sound/pci/ac97/ac97_codec.c	2005-03-01 23:39:18 -08:00
+++ b/sound/pci/ac97/ac97_codec.c	2005-03-01 23:39:18 -08:00
@@ -332,11 +332,11 @@
 {
 	if (!snd_ac97_valid_reg(ac97, reg))
 		return;
-	spin_lock(&ac97->reg_lock);
+	down(&ac97->reg_mutex);
 	ac97->regs[reg] = value;
-	spin_unlock(&ac97->reg_lock);
 	ac97->bus->ops->write(ac97, reg, value);
 	set_bit(reg, ac97->reg_accessed);
+	up(&ac97->reg_mutex);
 }
 
 /**
@@ -357,14 +357,13 @@
 
 	if (!snd_ac97_valid_reg(ac97, reg))
 		return -EINVAL;
-	spin_lock(&ac97->reg_lock);
+	down(&ac97->reg_mutex);
 	change = ac97->regs[reg] != value;
 	if (change) {
 		ac97->regs[reg] = value;
-		spin_unlock(&ac97->reg_lock);
 		ac97->bus->ops->write(ac97, reg, value);
-	} else
-		spin_unlock(&ac97->reg_lock);
+	}
+	up(&ac97->reg_mutex);
 	return change;
 }
 
@@ -384,20 +383,29 @@
 int snd_ac97_update_bits(ac97_t *ac97, unsigned short reg, unsigned short mask, unsigned short value)
 {
 	int change;
-	unsigned short old, new;
 
 	if (!snd_ac97_valid_reg(ac97, reg))
 		return -EINVAL;
-	spin_lock(&ac97->reg_lock);
+	down(&ac97->reg_mutex);
+	change = snd_ac97_update_bits_nolock(ac97, reg, mask, value);
+	up(&ac97->reg_mutex);
+	return change;
+}
+
+/* no lock version - see snd_ac97_updat_bits() */
+int snd_ac97_update_bits_nolock(ac97_t *ac97, unsigned short reg,
+				unsigned short mask, unsigned short value)
+{
+	int change;
+	unsigned short old, new;
+
 	old = snd_ac97_read_cache(ac97, reg);
 	new = (old & ~mask) | value;
 	change = old != new;
 	if (change) {
 		ac97->regs[reg] = new;
-		spin_unlock(&ac97->reg_lock);
 		ac97->bus->ops->write(ac97, reg, new);
-	} else
-		spin_unlock(&ac97->reg_lock);
+	}
 	return change;
 }
 
@@ -406,15 +414,14 @@
 	int change;
 	unsigned short old, new, cfg;
 
-	down(&ac97->mutex);
-	spin_lock(&ac97->reg_lock);
+	down(&ac97->page_mutex);
 	old = ac97->spec.ad18xx.pcmreg[codec];
 	new = (old & ~mask) | value;
-	cfg = snd_ac97_read_cache(ac97, AC97_AD_SERIAL_CFG);
 	change = old != new;
 	if (change) {
+		down(&ac97->reg_mutex);
+		cfg = snd_ac97_read_cache(ac97, AC97_AD_SERIAL_CFG);
 		ac97->spec.ad18xx.pcmreg[codec] = new;
-		spin_unlock(&ac97->reg_lock);
 		/* select single codec */
 		ac97->bus->ops->write(ac97, AC97_AD_SERIAL_CFG,
 				 (cfg & ~0x7000) |
@@ -424,9 +431,9 @@
 		/* select all codecs */
 		ac97->bus->ops->write(ac97, AC97_AD_SERIAL_CFG,
 				 cfg | 0x7000);
-	} else
-		spin_unlock(&ac97->reg_lock);
-	up(&ac97->mutex);
+		up(&ac97->reg_mutex);
+	}
+	up(&ac97->page_mutex);
 	return change;
 }
 
@@ -536,104 +543,70 @@
 	return snd_ac97_update_bits(ac97, reg, 1 << shift, val << shift);
 }
 
-int snd_ac97_info_single(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+int snd_ac97_info_volsw(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
 {
 	int mask = (kcontrol->private_value >> 16) & 0xff;
+	int shift = (kcontrol->private_value >> 8) & 0x0f;
+	int rshift = (kcontrol->private_value >> 12) & 0x0f;
 
 	uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
-	uinfo->count = 1;
+	uinfo->count = shift == rshift ? 1 : 2;
 	uinfo->value.integer.min = 0;
 	uinfo->value.integer.max = mask;
 	return 0;
 }
 
-int snd_ac97_get_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+int snd_ac97_get_volsw(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
 	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
 	int reg = kcontrol->private_value & 0xff;
-	int shift = (kcontrol->private_value >> 8) & 0xff;
+	int shift = (kcontrol->private_value >> 8) & 0x0f;
+	int rshift = (kcontrol->private_value >> 12) & 0x0f;
 	int mask = (kcontrol->private_value >> 16) & 0xff;
 	int invert = (kcontrol->private_value >> 24) & 0x01;
 	
 	ucontrol->value.integer.value[0] = (snd_ac97_read_cache(ac97, reg) >> shift) & mask;
-	if (invert)
+	if (shift != rshift)
+		ucontrol->value.integer.value[1] = (snd_ac97_read_cache(ac97, reg) >> rshift) & mask;
+	if (invert) {
 		ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
+		if (shift != rshift)
+			ucontrol->value.integer.value[1] = mask - ucontrol->value.integer.value[1];
+	}
 	return 0;
 }
 
-int snd_ac97_put_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+int snd_ac97_put_volsw(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
 	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
 	int reg = kcontrol->private_value & 0xff;
-	int shift = (kcontrol->private_value >> 8) & 0xff;
+	int shift = (kcontrol->private_value >> 8) & 0x0f;
+	int rshift = (kcontrol->private_value >> 12) & 0x0f;
 	int mask = (kcontrol->private_value >> 16) & 0xff;
 	int invert = (kcontrol->private_value >> 24) & 0x01;
-	unsigned short val;
+	unsigned short val, val2, val_mask;
 	
 	val = (ucontrol->value.integer.value[0] & mask);
 	if (invert)
 		val = mask - val;
-	return snd_ac97_update_bits(ac97, reg, mask << shift, val << shift);
+	val_mask = mask << shift;
+	val = val << shift;
+	if (shift != rshift) {
+		val2 = (ucontrol->value.integer.value[1] & mask);
+		if (invert)
+			val2 = mask - val2;
+		val_mask |= mask << rshift;
+		val |= val2 << rshift;
+	}
+	return snd_ac97_update_bits(ac97, reg, val_mask, val);
 }
 
 #define AC97_DOUBLE(xname, reg, shift_left, shift_right, mask, invert) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), .info = snd_ac97_info_double, \
-  .get = snd_ac97_get_double, .put = snd_ac97_put_double, \
+{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), .info = snd_ac97_info_volsw, \
+  .get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \
   .private_value = (reg) | ((shift_left) << 8) | ((shift_right) << 12) | ((mask) << 16) | ((invert) << 24) }
 
-static int snd_ac97_info_double(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 = 2;
-	uinfo->value.integer.min = 0;
-	uinfo->value.integer.max = mask;
-	return 0;
-}
-
-static int snd_ac97_get_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
-{
-	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
-	int reg = kcontrol->private_value & 0xff;
-	int shift_left = (kcontrol->private_value >> 8) & 0x0f;
-	int shift_right = (kcontrol->private_value >> 12) & 0x0f;
-	int mask = (kcontrol->private_value >> 16) & 0xff;
-	int invert = (kcontrol->private_value >> 24) & 0xff;
-	
-	spin_lock(&ac97->reg_lock);
-	ucontrol->value.integer.value[0] = (snd_ac97_read_cache(ac97, reg) >> shift_left) & mask;
-	ucontrol->value.integer.value[1] = (snd_ac97_read_cache(ac97, reg) >> shift_right) & mask;
-	spin_unlock(&ac97->reg_lock);
-	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;
-}
-
-static int snd_ac97_put_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
-{
-	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
-	int reg = kcontrol->private_value & 0xff;
-	int shift_left = (kcontrol->private_value >> 8) & 0x0f;
-	int shift_right = (kcontrol->private_value >> 12) & 0x0f;
-	int mask = (kcontrol->private_value >> 16) & 0xff;
-	int invert = (kcontrol->private_value >> 24) & 0xff;
-	unsigned short val1, val2;
-	
-	val1 = ucontrol->value.integer.value[0] & mask;
-	val2 = ucontrol->value.integer.value[1] & mask;
-	if (invert) {
-		val1 = mask - val1;
-		val2 = mask - val2;
-	}
-	return snd_ac97_update_bits(ac97, reg, 
-				    (mask << shift_left) | (mask << shift_right),
-				    (val1 << shift_left) | (val2 << shift_right));
-}
-
-int snd_ac97_getput_page(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol,
+static int snd_ac97_getput_page(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol,
 			 int (*func)(snd_kcontrol_t *, snd_ctl_elem_value_t *))
 {
 	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
@@ -644,27 +617,27 @@
 	    (reg >= 0x60 && reg < 0x70)) {
 		unsigned short page_save;
 		unsigned short page = (kcontrol->private_value >> 25) & 0x0f;
-		down(&ac97->mutex); /* lock paging */
+		down(&ac97->page_mutex); /* lock paging */
 		page_save = snd_ac97_read(ac97, AC97_INT_PAGING) & AC97_PAGE_MASK;
 		snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, page);
 		err = func(kcontrol, ucontrol);
 		snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, page_save);
-		up(&ac97->mutex); /* unlock paging */
+		up(&ac97->page_mutex); /* unlock paging */
 	} else
 		err = func(kcontrol, ucontrol);
 	return err;
 }
 
 /* for rev2.3 paging */
-int snd_ac97_page_get_single(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+int snd_ac97_page_get_volsw(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
 {
-	return snd_ac97_getput_page(kcontrol, ucontrol, snd_ac97_get_single);
+	return snd_ac97_getput_page(kcontrol, ucontrol, snd_ac97_get_volsw);
 }
 
 /* for rev2.3 paging */
-int snd_ac97_page_put_single(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+int snd_ac97_page_put_volsw(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
 {
-	return snd_ac97_getput_page(kcontrol, ucontrol, snd_ac97_put_single);
+	return snd_ac97_getput_page(kcontrol, ucontrol, snd_ac97_put_volsw);
 }
 
 static const snd_kcontrol_new_t snd_ac97_controls_master_mono[2] = {
@@ -682,16 +655,9 @@
 AC97_SINGLE("PC Speaker Playback Volume", AC97_PC_BEEP, 1, 15, 1)
 };
 
-static const snd_kcontrol_new_t snd_ac97_controls_phone[2] = {
-AC97_SINGLE("Phone Playback Switch", AC97_PHONE, 15, 1, 1),
-AC97_SINGLE("Phone Playback Volume", AC97_PHONE, 0, 15, 1)
-};
+static const snd_kcontrol_new_t snd_ac97_controls_mic_boost =
+	AC97_SINGLE("Mic Boost (+20dB)", AC97_MIC, 6, 1, 0);
 
-static const snd_kcontrol_new_t snd_ac97_controls_mic[3] = {
-AC97_SINGLE("Mic Playback Switch", AC97_MIC, 15, 1, 1),
-AC97_SINGLE("Mic Playback Volume", AC97_MIC, 0, 15, 1),
-AC97_SINGLE("Mic Boost (+20dB)", AC97_MIC, 6, 1, 0)
-};
 
 static const snd_kcontrol_new_t snd_ac97_control_capture_src = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -793,12 +759,12 @@
 {
 	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
 
-	spin_lock(&ac97->reg_lock);
+	down(&ac97->reg_mutex);
 	ucontrol->value.iec958.status[0] = ac97->spdif_status & 0xff;
 	ucontrol->value.iec958.status[1] = (ac97->spdif_status >> 8) & 0xff;
 	ucontrol->value.iec958.status[2] = (ac97->spdif_status >> 16) & 0xff;
 	ucontrol->value.iec958.status[3] = (ac97->spdif_status >> 24) & 0xff;
-	spin_unlock(&ac97->reg_lock);
+	up(&ac97->reg_mutex);
 	return 0;
 }
                         
@@ -809,7 +775,6 @@
 	unsigned short val = 0;
 	int change;
 
-	spin_lock(&ac97->reg_lock);
 	new = val = ucontrol->value.iec958.status[0] & (IEC958_AES0_PROFESSIONAL|IEC958_AES0_NONAUDIO);
 	if (ucontrol->value.iec958.status[0] & IEC958_AES0_PROFESSIONAL) {
 		new |= ucontrol->value.iec958.status[0] & (IEC958_AES0_PRO_FS|IEC958_AES0_PRO_EMPHASIS_5015);
@@ -838,9 +803,9 @@
 		}
 	}
 
+	down(&ac97->reg_mutex);
 	change = ac97->spdif_status != new;
 	ac97->spdif_status = new;
-	spin_unlock(&ac97->reg_lock);
 
 	if (ac97->flags & AC97_CS_SPDIF) {
 		int x = (val >> 12) & 0x03;
@@ -849,23 +814,24 @@
 		case 2: x = 0; break;  // 48.0
 		default: x = 0; break; // illegal.
 		}
-		change |= snd_ac97_update_bits(ac97, AC97_CSR_SPDIF, 0x3fff, ((val & 0xcfff) | (x << 12)));
+		change |= snd_ac97_update_bits_nolock(ac97, AC97_CSR_SPDIF, 0x3fff, ((val & 0xcfff) | (x << 12)));
 	} else if (ac97->flags & AC97_CX_SPDIF) {
 		int v;
 		v = new & (IEC958_AES0_CON_EMPHASIS_5015|IEC958_AES0_CON_NOT_COPYRIGHT) ? 0 : AC97_CXR_COPYRGT;
 		v |= new & IEC958_AES0_NONAUDIO ? AC97_CXR_SPDIF_AC3 : AC97_CXR_SPDIF_PCM;
-		change |= snd_ac97_update_bits(ac97, AC97_CXR_AUDIO_MISC, 
-					       AC97_CXR_SPDIF_MASK | AC97_CXR_COPYRGT,
-					       v);
+		change |= snd_ac97_update_bits_nolock(ac97, AC97_CXR_AUDIO_MISC, 
+						      AC97_CXR_SPDIF_MASK | AC97_CXR_COPYRGT,
+						      v);
 	} else {
 		unsigned short extst = snd_ac97_read_cache(ac97, AC97_EXTENDED_STATUS);
-		snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, 0); /* turn off */
+		snd_ac97_update_bits_nolock(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, 0); /* turn off */
 
-		change |= snd_ac97_update_bits(ac97, AC97_SPDIF, 0x3fff, val);
+		change |= snd_ac97_update_bits_nolock(ac97, AC97_SPDIF, 0x3fff, val);
 		if (extst & AC97_EA_SPDIF) {
-			snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, AC97_EA_SPDIF); /* turn on again */
+			snd_ac97_update_bits_nolock(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, AC97_EA_SPDIF); /* turn on again */
                 }
 	}
+	up(&ac97->reg_mutex);
 
 	return change;
 }
@@ -878,26 +844,26 @@
 	int mask = (kcontrol->private_value >> 16) & 0xff;
 	// int invert = (kcontrol->private_value >> 24) & 0xff;
 	unsigned short value, old, new;
+	int change;
 
 	value = (ucontrol->value.integer.value[0] & mask);
 
+	down(&ac97->reg_mutex);
 	mask <<= shift;
 	value <<= shift;
-	spin_lock(&ac97->reg_lock);
 	old = snd_ac97_read_cache(ac97, reg);
 	new = (old & ~mask) | value;
-	spin_unlock(&ac97->reg_lock);
+	change = old != new;
 
-	if (old != new) {
-		int change;
+	if (change) {
 		unsigned short extst = snd_ac97_read_cache(ac97, AC97_EXTENDED_STATUS);
-		snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, 0); /* turn off */
-		change = snd_ac97_update_bits(ac97, reg, mask, value);
+		snd_ac97_update_bits_nolock(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, 0); /* turn off */
+		change = snd_ac97_update_bits_nolock(ac97, reg, mask, value);
 		if (extst & AC97_EA_SPDIF)
-			snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, AC97_EA_SPDIF); /* turn on again */
-		return change;
+			snd_ac97_update_bits_nolock(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, AC97_EA_SPDIF); /* turn on again */
 	}
-	return 0;
+	up(&ac97->reg_mutex);
+	return change;
 }
 
 const snd_kcontrol_new_t snd_ac97_controls_spdif[5] = {
@@ -927,8 +893,8 @@
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "AC97-SPSA",
-		.info = snd_ac97_info_single,
-		.get = snd_ac97_get_single,
+		.info = snd_ac97_info_volsw,
+		.get = snd_ac97_get_volsw,
 		.put = snd_ac97_put_spsa,
 		.private_value = AC97_SINGLE_VALUE(AC97_EXTENDED_STATUS, 4, 3, 0)
 	},
@@ -1007,10 +973,10 @@
 	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
 	int codec = kcontrol->private_value & 3;
 	
-	spin_lock(&ac97->reg_lock);
+	down(&ac97->page_mutex);
 	ucontrol->value.integer.value[0] = 31 - ((ac97->spec.ad18xx.pcmreg[codec] >> 0) & 31);
 	ucontrol->value.integer.value[1] = 31 - ((ac97->spec.ad18xx.pcmreg[codec] >> 8) & 31);
-	spin_unlock(&ac97->reg_lock);
+	up(&ac97->page_mutex);
 	return 0;
 }
 
@@ -1055,8 +1021,7 @@
 {
 	if (bus) {
 		snd_ac97_bus_proc_done(bus);
-		if (bus->pcms)
-			kfree(bus->pcms);
+		kfree(bus->pcms);
 		if (bus->private_free)
 			bus->private_free(bus);
 		kfree(bus);
@@ -1148,6 +1113,26 @@
 	return 1;		/* success, useable */
 }
 
+static void check_volume_resolution(ac97_t *ac97, int reg, unsigned char *lo_max, unsigned char *hi_max)
+{
+	unsigned short cbit[3] = { 0x20, 0x10, 0x01 };
+	unsigned char max[3] = { 63, 31, 15 };
+	int i;
+
+	*lo_max = *hi_max = 0;
+	for (i = 0 ; i < ARRAY_SIZE(cbit); i++) {
+		unsigned short val;
+		snd_ac97_write(ac97, reg, 0x8080 | cbit[i] | (cbit[i] << 8));
+		val = snd_ac97_read(ac97, reg);
+		if (! *lo_max && (val & cbit[i]))
+			*lo_max = max[i];
+		if (! *hi_max && (val & (cbit[i] << 8)))
+			*hi_max = max[i];
+		if (*lo_max && *hi_max)
+			break;
+	}
+}
+
 int snd_ac97_try_bit(ac97_t * ac97, int reg, int bit)
 {
 	unsigned short mask, val, orig, res;
@@ -1161,21 +1146,6 @@
 	return res == val;
 }
 
-static void snd_ac97_change_volume_params1(ac97_t * ac97, int reg, unsigned char *max)
-{
-	unsigned short val, val1;
-
-	*max = 63;
-	val = 0x8000 | 0x0020;
-	snd_ac97_write(ac97, reg, val);
-	val1 = snd_ac97_read(ac97, reg);
-	if (val != val1) {
-		*max = 31;
-	}
-	/* reset volume to zero */
-	snd_ac97_write_cache(ac97, reg, 0x8000);
-}
-
 /* check the volume resolution of center/lfe */
 static void snd_ac97_change_volume_params2(ac97_t * ac97, int reg, int shift, unsigned char *max)
 {
@@ -1192,34 +1162,6 @@
 	snd_ac97_write_cache(ac97, reg, 0x8080);
 }
 
-/* check whether the volume resolution is 4 or 5 bits */
-static void snd_ac97_change_volume_params3(ac97_t * ac97, int reg, unsigned char *max)
-{
-	unsigned short val, val1;
-
-	*max = 31;
-	val = 0x8000 | 0x0010;
-	snd_ac97_write(ac97, reg, val);
-	val1 = snd_ac97_read(ac97, reg);
-	if (val != val1) {
-		*max = 15;
-	}
-	/* reset volume to zero */
-	snd_ac97_write_cache(ac97, reg, 0x8000);
-}
-
-/* check whether the volume is mono or stereo */
-static int snd_ac97_is_stereo_vol(ac97_t *ac97, int reg)
-{
-	unsigned short val, val1, val2;
-	val = snd_ac97_read(ac97, reg);
-	val1 = val | 0x8000 | (0x01 << 8);
-	snd_ac97_write(ac97, reg, val1);
-	val2 = snd_ac97_read(ac97, reg);
-	snd_ac97_write(ac97, reg, val); /* restore */
-	return val1 == val2;
-}
-
 static inline int printable(unsigned int x)
 {
 	x &= 0xff;
@@ -1246,22 +1188,22 @@
 static int snd_ac97_cmute_new(snd_card_t *card, char *name, int reg, ac97_t *ac97)
 {
 	snd_kcontrol_t *kctl;
-	int stereo = 0;
+	int err;
+	unsigned short val, val1, mute_mask;
 
 	if (! snd_ac97_valid_reg(ac97, reg))
 		return 0;
 
+	mute_mask = 0x8000;
+	val = snd_ac97_read(ac97, reg);
 	if (ac97->flags & AC97_STEREO_MUTES) {
 		/* check whether both mute bits work */
-		unsigned short val, val1;
-		val = snd_ac97_read(ac97, reg);
 		val1 = val | 0x8080;
 		snd_ac97_write(ac97, reg, val1);
 		if (val1 == snd_ac97_read(ac97, reg))
-			stereo = 1;
-		snd_ac97_write(ac97, reg, val);
+			mute_mask = 0x8080;
 	}
-	if (stereo) {
+	if (mute_mask == 0x8080) {
 		snd_kcontrol_new_t tmp = AC97_DOUBLE(name, reg, 15, 7, 1, 1);
 		tmp.index = ac97->num;
 		kctl = snd_ctl_new1(&tmp, ac97);
@@ -1270,50 +1212,68 @@
 		tmp.index = ac97->num;
 		kctl = snd_ctl_new1(&tmp, ac97);
 	}
-	return snd_ctl_add(card, kctl);
+	err = snd_ctl_add(card, kctl);
+	if (err < 0)
+		return err;
+	/* mute as default */
+	snd_ac97_write_cache(ac97, reg, val | mute_mask);
+	return 0;
 }
 
 /*
- * create volumes for normal stereo controls
+ * create a volume for normal stereo/mono controls
  */
-static int snd_ac97_cvol_new(snd_card_t *card, char *name, int reg, unsigned int max, ac97_t *ac97)
+static int snd_ac97_cvol_new(snd_card_t *card, char *name, int reg, unsigned int lo_max,
+			     unsigned int hi_max, ac97_t *ac97)
 {
 	int err;
-	snd_kcontrol_new_t tmp = AC97_DOUBLE(name, reg, 8, 0, (unsigned int)max, 1);
-	tmp.index = ac97->num;
+	snd_kcontrol_t *kctl;
 
 	if (! snd_ac97_valid_reg(ac97, reg))
 		return 0;
-	if ((err = snd_ctl_add(card, snd_ctl_new1(&tmp, ac97))) < 0)
+	if (hi_max) {
+		/* invert */
+		snd_kcontrol_new_t tmp = AC97_DOUBLE(name, reg, 8, 0, lo_max, 1);
+		tmp.index = ac97->num;
+		kctl = snd_ctl_new1(&tmp, ac97);
+	} else {
+		/* invert */
+		snd_kcontrol_new_t tmp = AC97_SINGLE(name, reg, 0, lo_max, 1);
+		tmp.index = ac97->num;
+		kctl = snd_ctl_new1(&tmp, ac97);
+	}
+	err = snd_ctl_add(card, kctl);
+	if (err < 0)
 		return err;
 	snd_ac97_write_cache(ac97, reg,
-			     ((ac97->flags & AC97_STEREO_MUTES) ? 0x8080 : 0x8000) |
-			     (unsigned short)max | ((unsigned short)max << 8));
+			     (snd_ac97_read(ac97, reg) & 0x8080) |
+			     lo_max | (hi_max << 8));
 	return 0;
 }
 
 /*
- * create mute-switch and volumes for normal stereo controls
+ * create a mute-switch and a volume for normal stereo/mono controls
  */
-static int snd_ac97_cmix_new(snd_card_t *card, const char *pfx, int reg, int check_res, ac97_t *ac97)
+static int snd_ac97_cmix_new(snd_card_t *card, const char *pfx, int reg, ac97_t *ac97)
 {
 	int err;
 	char name[44];
-	unsigned char max;
+	unsigned char lo_max, hi_max;
 
 	if (! snd_ac97_valid_reg(ac97, reg))
 		return 0;
 
-	sprintf(name, "%s Switch", pfx);
-	if ((err = snd_ac97_cmute_new(card, name, reg, ac97)) < 0)
-		return err;
-	sprintf(name, "%s Volume", pfx);
-	if (check_res)
-		snd_ac97_change_volume_params1(ac97, reg, &max);
-	else
-		max = 31; /* 5bit */
-	if ((err = snd_ac97_cvol_new(card, name, reg, max, ac97)) < 0)
-		return err;
+	if (snd_ac97_try_bit(ac97, reg, 15)) {
+		sprintf(name, "%s Switch", pfx);
+		if ((err = snd_ac97_cmute_new(card, name, reg, ac97)) < 0)
+			return err;
+	}
+	check_volume_resolution(ac97, reg, &lo_max, &hi_max);
+	if (lo_max) {
+		sprintf(name, "%s Volume", pfx);
+		if ((err = snd_ac97_cvol_new(card, name, reg, lo_max, hi_max, ac97)) < 0)
+			return err;
+	}
 	return 0;
 }
 
@@ -1331,7 +1291,11 @@
 	/* build master controls */
 	/* AD claims to remove this control from AD1887, although spec v2.2 does not allow this */
 	if (snd_ac97_try_volume_mix(ac97, AC97_MASTER)) {
-		if ((err = snd_ac97_cmix_new(card, "Master Playback", AC97_MASTER, 1, ac97)) < 0)
+		if (ac97->flags & AC97_HAS_NO_MASTER_VOL)
+			err = snd_ac97_cmute_new(card, "Master Playback Switch", AC97_MASTER, ac97);
+		else
+			err = snd_ac97_cmix_new(card, "Master Playback", AC97_MASTER, ac97);
+		if (err < 0)
 			return err;
 	}
 
@@ -1363,32 +1327,20 @@
 
 	/* build surround controls */
 	if (snd_ac97_try_volume_mix(ac97, AC97_SURROUND_MASTER)) {
-		if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_surround[0], ac97))) < 0)
+		if ((err = snd_ac97_cmix_new(card, "Surround Playback", AC97_SURROUND_MASTER, ac97)) < 0)
 			return err;
-		if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_surround[1], ac97))) < 0)
-			return err;
-		snd_ac97_change_volume_params2(ac97, AC97_SURROUND_MASTER, 0, &max);
-		kctl->private_value &= ~(0xff << 16);
-		kctl->private_value |= (int)max << 16;
-		snd_ac97_write_cache(ac97, AC97_SURROUND_MASTER, 0x8080 | max | (max << 8));
 	}
 
 	/* build headphone controls */
 	if (snd_ac97_try_volume_mix(ac97, AC97_HEADPHONE)) {
-		if ((err = snd_ac97_cmix_new(card, "Headphone Playback", AC97_HEADPHONE, 1, ac97)) < 0)
+		if ((err = snd_ac97_cmix_new(card, "Headphone Playback", AC97_HEADPHONE, ac97)) < 0)
 			return err;
 	}
 	
 	/* build master mono controls */
 	if (snd_ac97_try_volume_mix(ac97, AC97_MASTER_MONO)) {
-		if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_master_mono[0], ac97))) < 0)
+		if ((err = snd_ac97_cmix_new(card, "Master Mono Playback", AC97_MASTER_MONO, ac97)) < 0)
 			return err;
-		if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_master_mono[1], ac97))) < 0)
-			return err;
-		snd_ac97_change_volume_params1(ac97, AC97_MASTER_MONO, &max);
-		kctl->private_value &= ~(0xff << 16);
-		kctl->private_value |= (int)max << 16;
-		snd_ac97_write_cache(ac97, AC97_MASTER_MONO, 0x8000 | max);
 	}
 	
 	/* build master tone controls */
@@ -1416,56 +1368,39 @@
 	
 	/* build Phone controls */
 	if (snd_ac97_try_volume_mix(ac97, AC97_PHONE)) {
-		if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_phone[0], ac97))) < 0)
-			return err;
-		if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_phone[1], ac97))) < 0)
+		if ((err = snd_ac97_cmix_new(card, "Phone Playback", AC97_PHONE, ac97)) < 0)
 			return err;
-		snd_ac97_change_volume_params3(ac97, AC97_PHONE, &max);
-		kctl->private_value &= ~(0xff << 16);
-		kctl->private_value |= (int)max << 16;
-		snd_ac97_write_cache(ac97, AC97_PHONE, 0x8000 | max);
 	}
 	
 	/* build MIC controls */
-	snd_ac97_change_volume_params3(ac97, AC97_MIC, &max);
-	if (snd_ac97_is_stereo_vol(ac97, AC97_MIC)) {
-		/* build stereo mic */
-		if ((err = snd_ac97_cmute_new(card, "Mic Playback Switch", AC97_MIC, ac97)) < 0)
+	if (snd_ac97_try_volume_mix(ac97, AC97_MIC)) {
+		if ((err = snd_ac97_cmix_new(card, "Mic Playback", AC97_MIC, ac97)) < 0)
 			return err;
-		if ((err = snd_ac97_cvol_new(card, "Mic Playback Volume", AC97_MIC, max, ac97)) < 0)
+		if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_mic_boost, ac97))) < 0)
 			return err;
-		if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_mic[2], ac97))) < 0)
-			return err;
-	} else {
-		/* build mono mic */
-		for (idx = 0; idx < 3; idx++) {
-			if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_mic[idx], ac97))) < 0)
-				return err;
-			if (idx == 1) {		// volume
-				kctl->private_value &= ~(0xff << 16);
-				kctl->private_value |= (int)max << 16;
-			}
-		}
-		snd_ac97_write_cache(ac97, AC97_MIC, 0x8000 | max);
 	}
 
 	/* build Line controls */
-	if ((err = snd_ac97_cmix_new(card, "Line Playback", AC97_LINE, 0, ac97)) < 0)
-		return err;
+	if (snd_ac97_try_volume_mix(ac97, AC97_LINE)) {
+		if ((err = snd_ac97_cmix_new(card, "Line Playback", AC97_LINE, ac97)) < 0)
+			return err;
+	}
 	
 	/* build CD controls */
-	if ((err = snd_ac97_cmix_new(card, "CD Playback", AC97_CD, 0, ac97)) < 0)
-		return err;
+	if (snd_ac97_try_volume_mix(ac97, AC97_CD)) {
+		if ((err = snd_ac97_cmix_new(card, "CD Playback", AC97_CD, ac97)) < 0)
+			return err;
+	}
 	
 	/* build Video controls */
 	if (snd_ac97_try_volume_mix(ac97, AC97_VIDEO)) {
-		if ((err = snd_ac97_cmix_new(card, "Video Playback", AC97_VIDEO, 0, ac97)) < 0)
+		if ((err = snd_ac97_cmix_new(card, "Video Playback", AC97_VIDEO, ac97)) < 0)
 			return err;
 	}
 
 	/* build Aux controls */
 	if (snd_ac97_try_volume_mix(ac97, AC97_AUX)) {
-		if ((err = snd_ac97_cmix_new(card, "Aux Playback", AC97_AUX, 0, ac97)) < 0)
+		if ((err = snd_ac97_cmix_new(card, "Aux Playback", AC97_AUX, ac97)) < 0)
 			return err;
 	}
 
@@ -1497,15 +1432,12 @@
 		}
 		snd_ac97_write_cache(ac97, AC97_PCM, init_val);
 	} else {
-		if ((err = snd_ac97_cmute_new(card, "PCM Playback Switch", AC97_PCM, ac97)) < 0)
+		if (ac97->flags & AC97_HAS_NO_PCM_VOL)
+			err = snd_ac97_cmute_new(card, "PCM Playback Switch", AC97_PCM, ac97);
+		else
+			err = snd_ac97_cmix_new(card, "PCM Playback", AC97_PCM, ac97);
+		if (err < 0)
 			return err;
-		/* FIXME: C-Media chips have no PCM volume!! */
-		if (ac97->id == AC97_ID_CM9739)
-			snd_ac97_write_cache(ac97, AC97_PCM, 0x9f1f);
-		else {
-			if ((err = snd_ac97_cvol_new(card, "PCM Playback Volume", AC97_PCM, 31, ac97)) < 0)
-				return err;
-		}
 	}
 
 	/* build Capture controls */
@@ -1573,7 +1505,7 @@
 	snd_ac97_update_bits(ac97, AC97_GENERAL_PURPOSE, ~AC97_GP_DRSS_MASK, 0x0000);
 
 	/* build 3D controls */
-	if (ac97->build_ops && ac97->build_ops->build_3d) {
+	if (ac97->build_ops->build_3d) {
 		ac97->build_ops->build_3d(ac97);
 	} else {
 		if (snd_ac97_try_volume_mix(ac97, AC97_3D_CONTROL)) {
@@ -1596,14 +1528,14 @@
 
 	/* build S/PDIF controls */
 	if (ac97->ext_id & AC97_EI_SPDIF) {
-		if (ac97->build_ops && ac97->build_ops->build_spdif) {
+		if (ac97->build_ops->build_spdif) {
 			if ((err = ac97->build_ops->build_spdif(ac97)) < 0)
 				return err;
 		} else {
 			for (idx = 0; idx < 5; idx++)
 				if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_spdif[idx], ac97))) < 0)
 					return err;
-			if (ac97->build_ops && ac97->build_ops->build_post_spdif) {
+			if (ac97->build_ops->build_post_spdif) {
 				if ((err = ac97->build_ops->build_post_spdif(ac97)) < 0)
 					return err;
 			}
@@ -1616,7 +1548,7 @@
 	}
 	
 	/* build chip specific controls */
-	if (ac97->build_ops && ac97->build_ops->build_specific)
+	if (ac97->build_ops->build_specific)
 		if ((err = ac97->build_ops->build_specific(ac97)) < 0)
 			return err;
 
@@ -1662,6 +1594,14 @@
 {
 	unsigned int result = 0;
 
+	if (ac97->bus->no_vra) {
+		*r_result = SNDRV_PCM_RATE_48000;
+		if ((ac97->flags & AC97_DOUBLE_RATE) &&
+		    reg == AC97_PCM_FRONT_DAC_RATE)
+			*r_result |= SNDRV_PCM_RATE_96000;
+		return;
+	}
+
 	if ((ac97->ext_id & AC97_EI_DRA) && reg == AC97_PCM_FRONT_DAC_RATE)
 		snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS,
 				     AC97_EA_DRA, 0);
@@ -1863,7 +1803,7 @@
 	bus->clock = 48000;
 	spin_lock_init(&bus->bus_lock);
 	snd_ac97_bus_proc_init(bus);
-	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, bus, &dev_ops)) < 0) {
+	if ((err = snd_device_new(card, SNDRV_DEV_BUS, bus, &dev_ops)) < 0) {
 		snd_ac97_bus_free(bus);
 		return err;
 	}
@@ -1871,6 +1811,9 @@
 	return 0;
 }
 
+/* build_ops to do nothing */
+static struct snd_ac97_build_ops null_build_ops;
+
 /**
  * snd_ac97_mixer - create an Codec97 component
  * @bus: the AC97 bus which codec is attached to
@@ -1936,8 +1879,8 @@
 	ac97->limited_regs = template->limited_regs;
 	memcpy(ac97->reg_accessed, template->reg_accessed, sizeof(ac97->reg_accessed));
 	bus->codec[ac97->num] = ac97;
-	spin_lock_init(&ac97->reg_lock);
-	init_MUTEX(&ac97->mutex);
+	init_MUTEX(&ac97->reg_mutex);
+	init_MUTEX(&ac97->page_mutex);
 
 	if (ac97->pci) {
 		pci_read_config_word(ac97->pci, PCI_SUBSYSTEM_VENDOR_ID, &ac97->subsystem_vendor);
@@ -1968,7 +1911,8 @@
       __access_ok:
 	ac97->id = snd_ac97_read(ac97, AC97_VENDOR_ID1) << 16;
 	ac97->id |= snd_ac97_read(ac97, AC97_VENDOR_ID2);
-	if (ac97->id == 0x00000000 || ac97->id == 0xffffffff) {
+	if (! (ac97->scaps & AC97_SCAP_DETECT_BY_VENDOR) &&
+	    (ac97->id == 0x00000000 || ac97->id == 0xffffffff)) {
 		snd_printk(KERN_ERR "AC'97 %d access is not valid [0x%x], removing mixer.\n", ac97->num, ac97->id);
 		snd_ac97_free(ac97);
 		return -EIO;
@@ -2064,9 +2008,11 @@
 		ac97->addr = (ac97->ext_id & AC97_EI_ADDR_MASK) >> AC97_EI_ADDR_SHIFT;
 	else
 		ac97->addr = (ac97->ext_mid & AC97_MEI_ADDR_MASK) >> AC97_MEI_ADDR_SHIFT;
-	if (ac97->ext_id & 0x0189) {	/* L/R, MIC, SDAC, LDAC VRA support */
+	if (ac97->ext_id & 0x01c9) {	/* L/R, MIC, SDAC, LDAC VRA support */
 		reg = snd_ac97_read(ac97, AC97_EXTENDED_STATUS);
-		reg |= ac97->ext_id & 0x0189;
+		reg |= ac97->ext_id & 0x01c0; /* LDAC/SDAC/CDAC */
+		if (! bus->no_vra)
+			reg |= ac97->ext_id & 0x0009; /* VRA/VRM */
 		snd_ac97_write_cache(ac97, AC97_EXTENDED_STATUS, reg);
 	}
 	if ((ac97->ext_id & AC97_EI_DRA) && bus->dra) {
@@ -2107,7 +2053,11 @@
 		bus->ops->init(ac97);
 	snd_ac97_get_name(ac97, ac97->id, name, !ac97_is_audio(ac97));
 	snd_ac97_get_name(NULL, ac97->id, name, !ac97_is_audio(ac97));  // ac97->id might be changed in the special setup code
+	if (! ac97->build_ops)
+		ac97->build_ops = &null_build_ops;
+
 	if (ac97_is_audio(ac97)) {
+		char comp[16];
 		if (card->mixername[0] == '\0') {
 			strcpy(card->mixername, name);
 		} else {
@@ -2116,7 +2066,8 @@
 				strcat(card->mixername, name);
 			}
 		}
-		if ((err = snd_component_add(card, "AC97a")) < 0) {
+		sprintf(comp, "AC97a:%08x", ac97->id);
+		if ((err = snd_component_add(card, comp)) < 0) {
 			snd_ac97_free(ac97);
 			return err;
 		}
@@ -2126,6 +2077,7 @@
 		}
 	}
 	if (ac97_is_modem(ac97)) {
+		char comp[16];
 		if (card->mixername[0] == '\0') {
 			strcpy(card->mixername, name);
 		} else {
@@ -2134,7 +2086,8 @@
 				strcat(card->mixername, name);
 			}
 		}
-		if ((err = snd_component_add(card, "AC97m")) < 0) {
+		sprintf(comp, "AC97m:%08x", ac97->id);
+		if ((err = snd_component_add(card, comp)) < 0) {
 			snd_ac97_free(ac97);
 			return err;
 		}
@@ -2153,7 +2106,7 @@
 		snd_ac97_write_cache(ac97, AC97_EXTENDED_STATUS, reg);
 	}
 	snd_ac97_proc_init(ac97);
-	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, ac97, &ops)) < 0) {
+	if ((err = snd_device_new(card, SNDRV_DEV_CODEC, ac97, &ops)) < 0) {
 		snd_ac97_free(ac97);
 		return err;
 	}
@@ -2210,9 +2163,51 @@
  */
 void snd_ac97_suspend(ac97_t *ac97)
 {
+	if (ac97->build_ops->suspend)
+		ac97->build_ops->suspend(ac97);
 	snd_ac97_powerdown(ac97);
 }
 
+/*
+ * restore ac97 status
+ */
+void snd_ac97_restore_status(ac97_t *ac97)
+{
+	int i;
+
+	for (i = 2; i < 0x7c ; i += 2) {
+		if (i == AC97_POWERDOWN || i == AC97_EXTENDED_ID)
+			continue;
+		/* restore only accessible registers
+		 * some chip (e.g. nm256) may hang up when unsupported registers
+		 * are accessed..!
+		 */
+		if (test_bit(i, ac97->reg_accessed)) {
+			snd_ac97_write(ac97, i, ac97->regs[i]);
+			snd_ac97_read(ac97, i);
+		}
+	}
+}
+
+/*
+ * restore IEC958 status
+ */
+void snd_ac97_restore_iec958(ac97_t *ac97)
+{
+	if (ac97->ext_id & AC97_EI_SPDIF) {
+		if (ac97->regs[AC97_EXTENDED_STATUS] & AC97_EA_SPDIF) {
+			/* reset spdif status */
+			snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, 0);
+			snd_ac97_write(ac97, AC97_EXTENDED_STATUS, ac97->regs[AC97_EXTENDED_STATUS]);
+			if (ac97->flags & AC97_CS_SPDIF)
+				snd_ac97_write(ac97, AC97_CSR_SPDIF, ac97->regs[AC97_CSR_SPDIF]);
+			else
+				snd_ac97_write(ac97, AC97_SPDIF, ac97->regs[AC97_SPDIF]);
+			snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, AC97_EA_SPDIF); /* turn on again */
+		}
+	}
+}
+
 /**
  * snd_ac97_resume - General resume function for AC97 codec
  * @ac97: the ac97 instance
@@ -2222,7 +2217,7 @@
  */
 void snd_ac97_resume(ac97_t *ac97)
 {
-	int i, is_ad18xx, codec;
+	int i;
 
 	if (ac97->bus->ops->reset) {
 		ac97->bus->ops->reset(ac97);
@@ -2264,72 +2259,18 @@
 	if (ac97->bus->ops->init)
 		ac97->bus->ops->init(ac97);
 
-	is_ad18xx = (ac97->flags & AC97_AD_MULTI);
-	if (is_ad18xx) {
-		/* restore the AD18xx codec configurations */
-		for (codec = 0; codec < 3; codec++) {
-			if (! ac97->spec.ad18xx.id[codec])
-				continue;
-			/* select single codec */
-			snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000,
-					     ac97->spec.ad18xx.unchained[codec] | ac97->spec.ad18xx.chained[codec]);
-			ac97->bus->ops->write(ac97, AC97_AD_CODEC_CFG, ac97->spec.ad18xx.codec_cfg[codec]);
-		}
-		/* select all codecs */
-		snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000, 0x7000);
-	}
-
-	/* restore ac97 status */
-	for (i = 2; i < 0x7c ; i += 2) {
-		if (i == AC97_POWERDOWN || i == AC97_EXTENDED_ID)
-			continue;
-		/* restore only accessible registers
-		 * some chip (e.g. nm256) may hang up when unsupported registers
-		 * are accessed..!
-		 */
-		if (test_bit(i, ac97->reg_accessed)) {
-			if (is_ad18xx) {
-				/* handle multi codecs for AD18xx */
-				if (i == AC97_PCM) {
-					for (codec = 0; codec < 3; codec++) {
-						if (! ac97->spec.ad18xx.id[codec])
-							continue;
-						/* select single codec */
-						snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000,
-								     ac97->spec.ad18xx.unchained[codec] | ac97->spec.ad18xx.chained[codec]);
-						/* update PCM bits */
-						ac97->bus->ops->write(ac97, AC97_PCM, ac97->spec.ad18xx.pcmreg[codec]);
-					}
-					/* select all codecs */
-					snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000, 0x7000);
-					continue;
-				} else if (i == AC97_AD_TEST ||
-					   i == AC97_AD_CODEC_CFG ||
-					   i == AC97_AD_SERIAL_CFG)
-					continue; /* ignore */
-			}
-			snd_ac97_write(ac97, i, ac97->regs[i]);
-			snd_ac97_read(ac97, i);
-		}
-	}
-
-	if (ac97->ext_id & AC97_EI_SPDIF) {
-		if (ac97->regs[AC97_EXTENDED_STATUS] & AC97_EA_SPDIF) {
-			/* reset spdif status */
-			snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, 0);
-			snd_ac97_write(ac97, AC97_EXTENDED_STATUS, ac97->regs[AC97_EXTENDED_STATUS]);
-			if (ac97->flags & AC97_CS_SPDIF)
-				snd_ac97_write(ac97, AC97_CSR_SPDIF, ac97->regs[AC97_CSR_SPDIF]);
-			else
-				snd_ac97_write(ac97, AC97_SPDIF, ac97->regs[AC97_SPDIF]);
-			snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, AC97_EA_SPDIF); /* turn on again */
-		}
+	if (ac97->build_ops->resume)
+		ac97->build_ops->resume(ac97);
+	else {
+		snd_ac97_restore_status(ac97);
+		snd_ac97_restore_iec958(ac97);
 	}
 }
 #endif
 
 
 /*
+ * Hardware tuning
  */
 static void set_ctl_name(char *dst, const char *src, const char *suffix)
 {
@@ -2339,6 +2280,7 @@
 		strcpy(dst, src);
 }	
 
+/* remove the control with the given name and optional suffix */
 int snd_ac97_remove_ctl(ac97_t *ac97, const char *name, const char *suffix)
 {
 	snd_ctl_elem_id_t id;
@@ -2357,6 +2299,7 @@
 	return snd_ctl_find_id(ac97->bus->card, &sid);
 }
 
+/* rename the control with the given name and optional suffix */
 int snd_ac97_rename_ctl(ac97_t *ac97, const char *src, const char *dst, const char *suffix)
 {
 	snd_kcontrol_t *kctl = ctl_find(ac97, src, suffix);
@@ -2374,6 +2317,7 @@
 	snd_ac97_rename_ctl(ac97, src, dst, "Volume");
 }
 
+/* swap controls */
 int snd_ac97_swap_ctl(ac97_t *ac97, const char *s1, const char *s2, const char *suffix)
 {
 	snd_kcontrol_t *kctl1, *kctl2;
@@ -2387,20 +2331,29 @@
 	return -ENOENT;
 }
 
-static int swap_headphone(ac97_t *ac97, int remove_master)
+/* ac97 tune: use Headphone control as master */
+static int tune_hp_only(ac97_t *ac97)
 {
 	if (ctl_find(ac97, "Headphone Playback Switch", NULL) == NULL)
 		return -ENOENT;
-	if (remove_master) {
-		snd_ac97_remove_ctl(ac97, "Master Playback", "Switch");
-		snd_ac97_remove_ctl(ac97, "Master Playback", "Volume");
-	} else
-		snd_ac97_rename_vol_ctl(ac97, "Master Playback", "Line-Out Playback");
+	snd_ac97_remove_ctl(ac97, "Master Playback", "Switch");
+	snd_ac97_remove_ctl(ac97, "Master Playback", "Volume");
+	snd_ac97_rename_vol_ctl(ac97, "Headphone Playback", "Master Playback");
+	return 0;
+}
+
+/* ac97 tune: swap Headphone and Master controls */
+static int tune_swap_hp(ac97_t *ac97)
+{
+	if (ctl_find(ac97, "Headphone Playback Switch", NULL) == NULL)
+		return -ENOENT;
+	snd_ac97_rename_vol_ctl(ac97, "Master Playback", "Line-Out Playback");
 	snd_ac97_rename_vol_ctl(ac97, "Headphone Playback", "Master Playback");
 	return 0;
 }
 
-static int swap_surround(ac97_t *ac97)
+/* ac97 tune: swap Surround and Master controls */
+static int tune_swap_surround(ac97_t *ac97)
 {
 	if (snd_ac97_swap_ctl(ac97, "Master Playback", "Surround Playback", "Switch") ||
 	    snd_ac97_swap_ctl(ac97, "Master Playback", "Surround Playback", "Volume"))
@@ -2408,6 +2361,7 @@
 	return 0;
 }
 
+/* ac97 tune: set up mic sharing for AD codecs */
 static int tune_ad_sharing(ac97_t *ac97)
 {
 	unsigned short scfg;
@@ -2424,6 +2378,7 @@
 static const snd_kcontrol_new_t snd_ac97_alc_jack_detect = 
 AC97_SINGLE("Jack Detect", AC97_ALC650_CLOCK, 5, 1, 0);
 
+/* ac97 tune: set up ALC jack-select */
 static int tune_alc_jack(ac97_t *ac97)
 {
 	if ((ac97->id & 0xffffff00) != 0x414c4700) {
@@ -2435,6 +2390,7 @@
 	return snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&snd_ac97_alc_jack_detect, ac97));
 }
 
+/* ac97 tune: inversed EAPD bit */
 static int tune_inv_eapd(ac97_t *ac97)
 {
 	snd_kcontrol_t *kctl = ctl_find(ac97, "External Amplifier", NULL);
@@ -2444,24 +2400,79 @@
 	return 0;
 }
 
-static int apply_quirk(ac97_t *ac97, int quirk)
+static int master_mute_sw_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
 {
-	switch (quirk) {
-	case AC97_TUNE_NONE:
-		return 0;
-	case AC97_TUNE_HP_ONLY:
-		return swap_headphone(ac97, 1);
-	case AC97_TUNE_SWAP_HP:
-		return swap_headphone(ac97, 0);
-	case AC97_TUNE_SWAP_SURROUND:
-		return swap_surround(ac97);
-	case AC97_TUNE_AD_SHARING:
-		return tune_ad_sharing(ac97);
-	case AC97_TUNE_ALC_JACK:
-		return tune_alc_jack(ac97);
-	case AC97_TUNE_INV_EAPD:
-		return tune_inv_eapd(ac97);
+	int err = snd_ac97_put_volsw(kcontrol, ucontrol);
+	if (err > 0) {
+		ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
+		int shift = (kcontrol->private_value >> 8) & 0x0f;
+		int rshift = (kcontrol->private_value >> 12) & 0x0f;
+		unsigned short mask;
+		if (shift != rshift)
+			mask = 0x8080;
+		else
+			mask = 0x8000;
+		snd_ac97_update_bits(ac97, AC97_POWERDOWN, 0x8000,
+				     (ac97->regs[AC97_MASTER] & mask) == mask ?
+				     0x8000 : 0);
 	}
+	return err;
+}
+
+/* ac97 tune: EAPD controls mute LED bound with the master mute */
+static int tune_mute_led(ac97_t *ac97)
+{
+	snd_kcontrol_t *msw = ctl_find(ac97, "Master Playback Switch", NULL);
+	if (! msw)
+		return -ENOENT;
+	msw->put = master_mute_sw_put;
+	snd_ac97_remove_ctl(ac97, "External Amplifier", NULL);
+	snd_ac97_update_bits(ac97, AC97_POWERDOWN, 0x8000, 0x8000); /* mute LED on */
+	return 0;
+}
+
+struct quirk_table {
+	const char *name;
+	int (*func)(ac97_t *);
+};
+
+static struct quirk_table applicable_quirks[] = {
+	{ "none", NULL },
+	{ "hp_only", tune_hp_only },
+	{ "swap_hp", tune_swap_hp },
+	{ "swap_surround", tune_swap_surround },
+	{ "ad_sharing", tune_ad_sharing },
+	{ "alc_jack", tune_alc_jack },
+	{ "inv_eapd", tune_inv_eapd },
+	{ "mute_led", tune_mute_led },
+};
+
+/* apply the quirk with the given type */
+static int apply_quirk(ac97_t *ac97, int type)
+{
+	if (type <= 0)
+		return 0;
+	else if (type >= ARRAY_SIZE(applicable_quirks))
+		return -EINVAL;
+	if (applicable_quirks[type].func)
+		return applicable_quirks[type].func(ac97);
+	return 0;
+}
+
+/* apply the quirk with the given name */
+static int apply_quirk_str(ac97_t *ac97, const char *typestr)
+{
+	int i;
+	struct quirk_table *q;
+
+	for (i = 0; i < ARRAY_SIZE(applicable_quirks); i++) {
+		q = &applicable_quirks[i];
+		if (q->name && ! strcmp(typestr, q->name))
+			return apply_quirk(ac97, i);
+	}
+	/* for compatibility, accept the numbers, too */
+	if (*typestr >= '0' && *typestr <= '9')
+		return apply_quirk(ac97, (int)simple_strtol(typestr, NULL, 10));
 	return -EINVAL;
 }
 
@@ -2469,7 +2480,7 @@
  * snd_ac97_tune_hardware - tune up the hardware
  * @ac97: the ac97 instance
  * @quirk: quirk list
- * @override: explicit quirk value (overrides the list if not AC97_TUNE_DEFAULT)
+ * @override: explicit quirk value (overrides the list if non-NULL)
  *
  * Do some workaround for each pci device, such as renaming of the
  * headphone (true line-out) control as "Master".
@@ -2478,16 +2489,17 @@
  * Returns zero if successful, or a negative error code on failure.
  */
 
-int snd_ac97_tune_hardware(ac97_t *ac97, struct ac97_quirk *quirk, int override)
+int snd_ac97_tune_hardware(ac97_t *ac97, struct ac97_quirk *quirk, const char *override)
 {
 	int result;
 
 	snd_assert(quirk, return -EINVAL);
 
-	if (override != AC97_TUNE_DEFAULT) {
-		result = apply_quirk(ac97, override);
+	/* quirk overriden? */
+	if (override && strcmp(override, "-1") && strcmp(override, "default")) {
+		result = apply_quirk_str(ac97, override);
 		if (result < 0)
-			snd_printk(KERN_ERR "applying quirk type %d failed (%d)\n", override, result);
+			snd_printk(KERN_ERR "applying quirk type %s failed (%d)\n", override, result);
 		return result;
 	}
 
diff -Nru a/sound/pci/ac97/ac97_local.h b/sound/pci/ac97/ac97_local.h
--- a/sound/pci/ac97/ac97_local.h	2005-03-01 23:38:55 -08:00
+++ b/sound/pci/ac97/ac97_local.h	2005-03-01 23:38:55 -08:00
@@ -22,15 +22,15 @@
  *
  */
 
-#define AC97_SINGLE_VALUE(reg,shift,mask,invert) ((reg) | ((shift) << 8) | ((mask) << 16) | ((invert) << 24))
-#define AC97_PAGE_SINGLE_VALUE(reg,shift,mask,invert,page) ((reg) | ((shift) << 8) | ((mask) << 16) | ((invert) << 24) | ((page) << 25))
+#define AC97_SINGLE_VALUE(reg,shift,mask,invert) ((reg) | ((shift) << 8) | ((shift) << 12) | ((mask) << 16) | ((invert) << 24))
+#define AC97_PAGE_SINGLE_VALUE(reg,shift,mask,invert,page) (AC97_SINGLE_VALUE(reg,shift,mask,invert) | ((page) << 25))
 #define AC97_SINGLE(xname, reg, shift, mask, invert) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_ac97_info_single, \
-  .get = snd_ac97_get_single, .put = snd_ac97_put_single, \
+{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_ac97_info_volsw, \
+  .get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \
   .private_value =  AC97_SINGLE_VALUE(reg, shift, mask, invert) }
 #define AC97_PAGE_SINGLE(xname, reg, shift, mask, invert, page)		\
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_ac97_info_single, \
-  .get = snd_ac97_page_get_single, .put = snd_ac97_page_put_single, \
+{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_ac97_info_volsw, \
+  .get = snd_ac97_page_get_volsw, .put = snd_ac97_page_put_volsw, \
   .private_value =  AC97_PAGE_SINGLE_VALUE(reg, shift, mask, invert, page) }
 
 /* ac97_codec.c */
@@ -39,16 +39,21 @@
 extern const snd_kcontrol_new_t snd_ac97_controls_spdif[];
 snd_kcontrol_t *snd_ac97_cnew(const snd_kcontrol_new_t *_template, ac97_t * ac97);
 void snd_ac97_get_name(ac97_t *ac97, unsigned int id, char *name, int modem);
-int snd_ac97_info_single(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo);
-int snd_ac97_get_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol);
-int snd_ac97_put_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol);
-int snd_ac97_page_get_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol);
-int snd_ac97_page_put_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol);
+int snd_ac97_info_volsw(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo);
+int snd_ac97_get_volsw(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol);
+int snd_ac97_put_volsw(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol);
+int snd_ac97_page_get_volsw(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol);
+int snd_ac97_page_put_volsw(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol);
 int snd_ac97_try_bit(ac97_t * ac97, int reg, int bit);
 int snd_ac97_remove_ctl(ac97_t *ac97, const char *name, const char *suffix);
 int snd_ac97_rename_ctl(ac97_t *ac97, const char *src, const char *dst, const char *suffix);
 int snd_ac97_swap_ctl(ac97_t *ac97, const char *s1, const char *s2, const char *suffix);
 void snd_ac97_rename_vol_ctl(ac97_t *ac97, const char *src, const char *dst);
+void snd_ac97_restore_status(ac97_t *ac97);
+void snd_ac97_restore_iec958(ac97_t *ac97);
+
+int snd_ac97_update_bits_nolock(ac97_t *ac97, unsigned short reg,
+				unsigned short mask, unsigned short value);
 
 /* ac97_proc.c */
 #ifdef CONFIG_PROC_FS
diff -Nru a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c
--- a/sound/pci/ac97/ac97_patch.c	2005-03-01 23:39:16 -08:00
+++ b/sound/pci/ac97/ac97_patch.c	2005-03-01 23:39:16 -08:00
@@ -55,12 +55,12 @@
 	unsigned short page_save;
 	int ret;
 
-	down(&ac97->mutex);
+	down(&ac97->page_mutex);
 	page_save = snd_ac97_read(ac97, AC97_INT_PAGING) & AC97_PAGE_MASK;
 	snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, page);
 	ret = snd_ac97_update_bits(ac97, reg, mask, value);
 	snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, page_save);
-	up(&ac97->mutex); /* unlock paging */
+	up(&ac97->page_mutex); /* unlock paging */
 	return ret;
 }
 
@@ -775,6 +775,71 @@
 /*
  * Analog Device AD18xx, AD19xx codecs
  */
+#ifdef CONFIG_PM
+static void ad18xx_resume(ac97_t *ac97)
+{
+	static unsigned short setup_regs[] = {
+		AC97_AD_MISC, AC97_AD_SERIAL_CFG, AC97_AD_JACK_SPDIF,
+	};
+	int i, codec;
+
+	for (i = 0; i < (int)ARRAY_SIZE(setup_regs); i++) {
+		unsigned short reg = setup_regs[i];
+		if (test_bit(reg, ac97->reg_accessed)) {
+			snd_ac97_write(ac97, reg, ac97->regs[reg]);
+			snd_ac97_read(ac97, reg);
+		}
+	}
+
+	if (! (ac97->flags & AC97_AD_MULTI))
+		/* normal restore */
+		snd_ac97_restore_status(ac97);
+	else {
+		/* restore the AD18xx codec configurations */
+		for (codec = 0; codec < 3; codec++) {
+			if (! ac97->spec.ad18xx.id[codec])
+				continue;
+			/* select single codec */
+			snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000,
+					     ac97->spec.ad18xx.unchained[codec] | ac97->spec.ad18xx.chained[codec]);
+			ac97->bus->ops->write(ac97, AC97_AD_CODEC_CFG, ac97->spec.ad18xx.codec_cfg[codec]);
+		}
+		/* select all codecs */
+		snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000, 0x7000);
+
+		/* restore status */
+		for (i = 2; i < 0x7c ; i += 2) {
+			if (i == AC97_POWERDOWN || i == AC97_EXTENDED_ID)
+				continue;
+			if (test_bit(i, ac97->reg_accessed)) {
+				/* handle multi codecs for AD18xx */
+				if (i == AC97_PCM) {
+					for (codec = 0; codec < 3; codec++) {
+						if (! ac97->spec.ad18xx.id[codec])
+							continue;
+						/* select single codec */
+						snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000,
+								     ac97->spec.ad18xx.unchained[codec] | ac97->spec.ad18xx.chained[codec]);
+						/* update PCM bits */
+						ac97->bus->ops->write(ac97, AC97_PCM, ac97->spec.ad18xx.pcmreg[codec]);
+					}
+					/* select all codecs */
+					snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000, 0x7000);
+					continue;
+				} else if (i == AC97_AD_TEST ||
+					   i == AC97_AD_CODEC_CFG ||
+					   i == AC97_AD_SERIAL_CFG)
+					continue; /* ignore */
+			}
+			snd_ac97_write(ac97, i, ac97->regs[i]);
+			snd_ac97_read(ac97, i);
+		}
+	}
+
+	snd_ac97_restore_iec958(ac97);
+}
+#endif
+
 int patch_ad1819(ac97_t * ac97)
 {
 	unsigned short scfg;
@@ -843,6 +908,12 @@
 	}
 }
 
+static struct snd_ac97_build_ops patch_ad1881_build_ops = {
+#ifdef CONFIG_PM
+	.resume = ad18xx_resume
+#endif
+};
+
 int patch_ad1881(ac97_t * ac97)
 {
 	static const char cfg_idxs[3][2] = {
@@ -897,6 +968,7 @@
 		ac97->id &= 0xffff0000;
 		ac97->id |= ac97->spec.ad18xx.id[0];
 	}
+	ac97->build_ops = &patch_ad1881_build_ops;
 	return 0;
 }
 
@@ -919,7 +991,10 @@
 }
 
 static struct snd_ac97_build_ops patch_ad1885_build_ops = {
-	.build_specific = &patch_ad1885_specific
+	.build_specific = &patch_ad1885_specific,
+#ifdef CONFIG_PM
+	.resume = ad18xx_resume
+#endif
 };
 
 int patch_ad1885(ac97_t * ac97)
@@ -1013,16 +1088,45 @@
  	return patch_build_controls(ac97, &snd_ac97_ad198x_spdif_source, 1);
 }
 
+static const snd_kcontrol_new_t snd_ac97_ad1981x_jack_sense[] = {
+	AC97_SINGLE("Headphone Jack Sense", AC97_AD_JACK_SPDIF, 11, 1, 0),
+	AC97_SINGLE("Line Jack Sense", AC97_AD_JACK_SPDIF, 12, 1, 0),
+};
+
+static int patch_ad1981a_specific(ac97_t * ac97)
+{
+	return patch_build_controls(ac97, snd_ac97_ad1981x_jack_sense,
+				    ARRAY_SIZE(snd_ac97_ad1981x_jack_sense));
+}
+
 static struct snd_ac97_build_ops patch_ad1981a_build_ops = {
-	.build_post_spdif = patch_ad198x_post_spdif
+	.build_post_spdif = patch_ad198x_post_spdif,
+	.build_specific = patch_ad1981a_specific,
+#ifdef CONFIG_PM
+	.resume = ad18xx_resume
+#endif
 };
 
+static void check_ad1981_hp_jack_sense(ac97_t *ac97)
+{
+	u32 subid = ((u32)ac97->subsystem_vendor << 16) | ac97->subsystem_device;
+	switch (subid) {
+	case 0x103c0890: /* HP nc6000 */
+	case 0x103c006d: /* HP nx9105 */
+	case 0x17340088: /* FSC Scenic-W */
+		/* enable headphone jack sense */
+		snd_ac97_update_bits(ac97, AC97_AD_JACK_SPDIF, 1<<11, 1<<11);
+		break;
+	}
+}
+
 int patch_ad1981a(ac97_t *ac97)
 {
 	patch_ad1881(ac97);
 	ac97->build_ops = &patch_ad1981a_build_ops;
 	snd_ac97_update_bits(ac97, AC97_AD_MISC, AC97_AD198X_MSPLT, AC97_AD198X_MSPLT);
 	ac97->flags |= AC97_STEREO_MUTES;
+	check_ad1981_hp_jack_sense(ac97);
 	return 0;
 }
 
@@ -1031,12 +1135,20 @@
 
 static int patch_ad1981b_specific(ac97_t *ac97)
 {
-	return patch_build_controls(ac97, &snd_ac97_ad198x_2cmic, 1);
+	int err;
+
+	if ((err = patch_build_controls(ac97, &snd_ac97_ad198x_2cmic, 1)) < 0)
+		return err;
+	return patch_build_controls(ac97, snd_ac97_ad1981x_jack_sense,
+				    ARRAY_SIZE(snd_ac97_ad1981x_jack_sense));
 }
 
 static struct snd_ac97_build_ops patch_ad1981b_build_ops = {
 	.build_post_spdif = patch_ad198x_post_spdif,
-	.build_specific = patch_ad1981b_specific
+	.build_specific = patch_ad1981b_specific,
+#ifdef CONFIG_PM
+	.resume = ad18xx_resume
+#endif
 };
 
 int patch_ad1981b(ac97_t *ac97)
@@ -1045,6 +1157,7 @@
 	ac97->build_ops = &patch_ad1981b_build_ops;
 	snd_ac97_update_bits(ac97, AC97_AD_MISC, AC97_AD198X_MSPLT, AC97_AD198X_MSPLT);
 	ac97->flags |= AC97_STEREO_MUTES;
+	check_ad1981_hp_jack_sense(ac97);
 	return 0;
 }
 
@@ -1150,7 +1263,10 @@
 
 static struct snd_ac97_build_ops patch_ad1888_build_ops = {
 	.build_post_spdif = patch_ad198x_post_spdif,
-	.build_specific = patch_ad1888_specific
+	.build_specific = patch_ad1888_specific,
+#ifdef CONFIG_PM
+	.resume = ad18xx_resume
+#endif
 };
 
 int patch_ad1888(ac97_t * ac97)
@@ -1184,7 +1300,10 @@
 
 static struct snd_ac97_build_ops patch_ad1980_build_ops = {
 	.build_post_spdif = patch_ad198x_post_spdif,
-	.build_specific = patch_ad1980_specific
+	.build_specific = patch_ad1980_specific,
+#ifdef CONFIG_PM
+	.resume = ad18xx_resume
+#endif
 };
 
 int patch_ad1980(ac97_t * ac97)
@@ -1210,7 +1329,10 @@
 
 static struct snd_ac97_build_ops patch_ad1985_build_ops = {
 	.build_post_spdif = patch_ad198x_post_spdif,
-	.build_specific = patch_ad1985_specific
+	.build_specific = patch_ad1985_specific,
+#ifdef CONFIG_PM
+	.resume = ad18xx_resume
+#endif
 };
 
 int patch_ad1985(ac97_t * ac97)
@@ -1294,7 +1416,7 @@
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "Mic As Center/LFE",
-		.info = snd_ac97_info_single,
+		.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 */
@@ -1304,7 +1426,8 @@
 static const snd_kcontrol_new_t snd_ac97_spdif_controls_alc650[] = {
         AC97_SINGLE("IEC958 Capture Switch", AC97_ALC650_MULTICH, 11, 1, 0),
         AC97_SINGLE("Analog to IEC958 Output", AC97_ALC650_MULTICH, 12, 1, 0),
-        AC97_SINGLE("IEC958 Input Monitor", AC97_ALC650_MULTICH, 13, 1, 0),
+	/* disable this controls since it doesn't work as expected */
+	/* AC97_SINGLE("IEC958 Input Monitor", AC97_ALC650_MULTICH, 13, 1, 0), */
 };
 
 static int patch_alc650_specific(ac97_t * ac97)
@@ -1405,7 +1528,7 @@
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "Mic As Center/LFE",
-		.info = snd_ac97_info_single,
+		.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 */
@@ -1454,7 +1577,8 @@
 
 static const snd_kcontrol_new_t snd_ac97_spdif_controls_alc655[] = {
         AC97_PAGE_SINGLE("IEC958 Capture Switch", AC97_ALC650_MULTICH, 11, 1, 0, 0),
-        AC97_PAGE_SINGLE("IEC958 Input Monitor", AC97_ALC650_MULTICH, 14, 1, 0, 0),
+	/* disable this controls since it doesn't work as expected */
+        /* AC97_PAGE_SINGLE("IEC958 Input Monitor", AC97_ALC650_MULTICH, 14, 1, 0, 0), */
 	{
 		.iface  = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name   = "IEC958 Playback Route",
@@ -1494,7 +1618,10 @@
 
 	/* adjust default values */
 	val = snd_ac97_read(ac97, 0x7a); /* misc control */
-	val |= (1 << 1); /* spdif input pin */
+	if (ac97->id == 0x414c4780) /* ALC658 */
+		val &= ~(1 << 1); /* Pin 47 is spdif input pin */
+	else /* ALC655 */
+		val |= (1 << 1); /* Pin 47 is spdif input pin */
 	val &= ~(1 << 12); /* vref enable */
 	snd_ac97_write_cache(ac97, 0x7a, val);
 	/* set default: spdif-in enabled,
@@ -1557,7 +1684,7 @@
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "Line-In As Surround",
-		.info = snd_ac97_info_single,
+		.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 */
@@ -1565,7 +1692,7 @@
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "Mic As Center/LFE",
-		.info = snd_ac97_info_single,
+		.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 */
@@ -1644,6 +1771,11 @@
 int patch_cm9738(ac97_t * ac97)
 {
 	ac97->build_ops = &patch_cm9738_ops;
+	/* FIXME: can anyone confirm below? */
+	/* CM9738 has no PCM volume although the register reacts */
+	ac97->flags |= AC97_HAS_NO_PCM_VOL;
+	snd_ac97_write_cache(ac97, AC97_PCM, 0x8000);
+
 	return 0;
 }
 
@@ -1720,7 +1852,7 @@
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "Mic As Center/LFE",
-		.info = snd_ac97_info_single,
+		.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 */
@@ -1748,6 +1880,11 @@
 
 	ac97->build_ops = &patch_cm9739_ops;
 
+	/* CM9739/A has no Master and PCM volume although the register reacts */
+	ac97->flags |= AC97_HAS_NO_MASTER_VOL | AC97_HAS_NO_PCM_VOL;
+	snd_ac97_write_cache(ac97, AC97_MASTER, 0x8000);
+	snd_ac97_write_cache(ac97, AC97_PCM, 0x8000);
+
 	/* check spdif */
 	val = snd_ac97_read(ac97, AC97_EXTENDED_STATUS);
 	if (val & AC97_EA_SPCV) {
@@ -1766,8 +1903,12 @@
 	/* bit 12: disable center/lfe (swithable) */
 	/* bit 10: disable surround/line (switchable) */
 	/* bit 9: mix 2 surround off */
+	/* bit 4: undocumented; 0 mutes the CM9739A, which defaults to 1 */
+	/* bit 3: undocumented; surround? */
 	/* bit 0: dB */
-	val = (1 << 13);
+	val = snd_ac97_read(ac97, AC97_CM9739_MULTI_CHAN) & (1 << 4);
+	val |= (1 << 3);
+	val |= (1 << 13);
 	if (! (ac97->ext_id & AC97_EI_SPDIF))
 		val |= (1 << 14);
 	snd_ac97_write_cache(ac97, AC97_CM9739_MULTI_CHAN, val);
@@ -1775,6 +1916,15 @@
 	/* FIXME: set up GPIO */
 	snd_ac97_write_cache(ac97, 0x70, 0x0100);
 	snd_ac97_write_cache(ac97, 0x72, 0x0020);
+	/* Special exception for ASUS W1000/CMI9739. It does not have an SPDIF in. */
+	if (ac97->pci &&
+	     ac97->subsystem_vendor == 0x1043 &&
+	     ac97->subsystem_device == 0x1843) {
+		snd_ac97_write_cache(ac97, AC97_CM9739_SPDIF_CTRL,
+			snd_ac97_read(ac97, AC97_CM9739_SPDIF_CTRL) & ~0x01);
+		snd_ac97_write_cache(ac97, AC97_CM9739_MULTI_CHAN,
+			snd_ac97_read(ac97, AC97_CM9739_MULTI_CHAN) | (1 << 14));
+	}
 
 	return 0;
 }
@@ -1830,7 +1980,7 @@
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "Line-In As Surround",
-		.info = snd_ac97_info_single,
+		.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 */
@@ -1838,7 +1988,7 @@
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "Mic As Center/LFE",
-		.info = snd_ac97_info_single,
+		.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 */
@@ -1858,6 +2008,11 @@
 int patch_cm9761(ac97_t *ac97)
 {
 	unsigned short val;
+
+	/* CM9761 has no Master and PCM volume although the register reacts */
+	ac97->flags |= AC97_HAS_NO_MASTER_VOL | AC97_HAS_NO_PCM_VOL;
+	snd_ac97_write_cache(ac97, AC97_MASTER, 0x8000);
+	snd_ac97_write_cache(ac97, AC97_PCM, 0x8000);
 
 	ac97->spec.dev_flags = 0; /* 1 = model 82 revision B */
 	if (ac97->id == AC97_ID_CM9761_82) {
diff -Nru a/sound/pci/ac97/ac97_pcm.c b/sound/pci/ac97/ac97_pcm.c
--- a/sound/pci/ac97/ac97_pcm.c	2005-03-01 23:38:52 -08:00
+++ b/sound/pci/ac97/ac97_pcm.c	2005-03-01 23:38:52 -08:00
@@ -206,14 +206,12 @@
 		mask = AC97_SC_SPSR_MASK;
 	}
 
-	spin_lock(&ac97->reg_lock);
+	down(&ac97->reg_mutex);
 	old = snd_ac97_read(ac97, reg) & mask;
-	spin_unlock(&ac97->reg_lock);
 	if (old != bits) {
-		snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, 0);
-		snd_ac97_update_bits(ac97, reg, mask, bits);
+		snd_ac97_update_bits_nolock(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, 0);
+		snd_ac97_update_bits_nolock(ac97, reg, mask, bits);
 		/* update the internal spdif bits */
-		spin_lock(&ac97->reg_lock);
 		sbits = ac97->spdif_status;
 		if (sbits & IEC958_AES0_PROFESSIONAL) {
 			sbits &= ~IEC958_AES0_PRO_FS;
@@ -231,9 +229,9 @@
 			}
 		}
 		ac97->spdif_status = sbits;
-		spin_unlock(&ac97->reg_lock);
 	}
-	snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, AC97_EA_SPDIF);
+	snd_ac97_update_bits_nolock(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, AC97_EA_SPDIF);
+	up(&ac97->reg_mutex);
 	return 0;
 }
 
diff -Nru a/sound/pci/ac97/ac97_proc.c b/sound/pci/ac97/ac97_proc.c
--- a/sound/pci/ac97/ac97_proc.c	2005-03-01 23:39:17 -08:00
+++ b/sound/pci/ac97/ac97_proc.c	2005-03-01 23:39:17 -08:00
@@ -296,7 +296,7 @@
 {
 	ac97_t *ac97 = entry->private_data;
 	
-	down(&ac97->mutex);
+	down(&ac97->page_mutex);
 	if ((ac97->id & 0xffffff40) == AC97_ID_AD1881) {	// Analog Devices AD1881/85/86
 		int idx;
 		for (idx = 0; idx < 3; idx++)
@@ -322,7 +322,7 @@
 	} else {
 		snd_ac97_proc_read_main(ac97, buffer, 0);
 	}
-	up(&ac97->mutex);
+	up(&ac97->page_mutex);
 }
 
 #ifdef CONFIG_SND_DEBUG
@@ -332,7 +332,7 @@
 	ac97_t *ac97 = entry->private_data;
 	char line[64];
 	unsigned int reg, val;
-	down(&ac97->mutex);
+	down(&ac97->page_mutex);
 	while (!snd_info_get_line(buffer, line, sizeof(line))) {
 		if (sscanf(line, "%x %x", &reg, &val) != 2)
 			continue;
@@ -340,7 +340,7 @@
 		if (reg < 0x80 && (reg & 1) == 0 && val <= 0xffff)
 			snd_ac97_write_cache(ac97, reg, val);
 	}
-	up(&ac97->mutex);
+	up(&ac97->page_mutex);
 }
 #endif
 
@@ -359,7 +359,7 @@
 {
 	ac97_t *ac97 = entry->private_data;
 
-	down(&ac97->mutex);
+	down(&ac97->page_mutex);
 	if ((ac97->id & 0xffffff40) == AC97_ID_AD1881) {	// Analog Devices AD1881/85/86
 
 		int idx;
@@ -375,7 +375,7 @@
 	} else {
 		snd_ac97_proc_regs_read_main(ac97, buffer, 0);
 	}	
-	up(&ac97->mutex);
+	up(&ac97->page_mutex);
 }
 
 void snd_ac97_proc_init(ac97_t * ac97)
diff -Nru a/sound/pci/ac97/ak4531_codec.c b/sound/pci/ac97/ak4531_codec.c
--- a/sound/pci/ac97/ak4531_codec.c	2005-03-01 23:38:52 -08:00
+++ b/sound/pci/ac97/ak4531_codec.c	2005-03-01 23:38:52 -08:00
@@ -72,16 +72,15 @@
 static int snd_ak4531_get_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
 	ak4531_t *ak4531 = snd_kcontrol_chip(kcontrol);
-	unsigned long flags;
 	int reg = kcontrol->private_value & 0xff;
 	int shift = (kcontrol->private_value >> 16) & 0x07;
 	int mask = (kcontrol->private_value >> 24) & 0xff;
 	int invert = (kcontrol->private_value >> 22) & 1;
 	int val;
 
-	spin_lock_irqsave(&ak4531->reg_lock, flags);
+	down(&ak4531->reg_mutex);
 	val = (ak4531->regs[reg] >> shift) & mask;
-	spin_unlock_irqrestore(&ak4531->reg_lock, flags);
+	up(&ak4531->reg_mutex);
 	if (invert) {
 		val = mask - val;
 	}
@@ -92,7 +91,6 @@
 static int snd_ak4531_put_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
 	ak4531_t *ak4531 = snd_kcontrol_chip(kcontrol);
-	unsigned long flags;
 	int reg = kcontrol->private_value & 0xff;
 	int shift = (kcontrol->private_value >> 16) & 0x07;
 	int mask = (kcontrol->private_value >> 24) & 0xff;
@@ -105,11 +103,11 @@
 		val = mask - val;
 	}
 	val <<= shift;
-	spin_lock_irqsave(&ak4531->reg_lock, flags);
+	down(&ak4531->reg_mutex);
 	val = (ak4531->regs[reg] & ~(mask << shift)) | val;
 	change = val != ak4531->regs[reg];
 	ak4531->write(ak4531, reg, ak4531->regs[reg] = val);
-	spin_unlock_irqrestore(&ak4531->reg_lock, flags);
+	up(&ak4531->reg_mutex);
 	return change;
 }
 
@@ -133,7 +131,6 @@
 static int snd_ak4531_get_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
 	ak4531_t *ak4531 = snd_kcontrol_chip(kcontrol);
-	unsigned long flags;
 	int left_reg = kcontrol->private_value & 0xff;
 	int right_reg = (kcontrol->private_value >> 8) & 0xff;
 	int left_shift = (kcontrol->private_value >> 16) & 0x07;
@@ -142,10 +139,10 @@
 	int invert = (kcontrol->private_value >> 22) & 1;
 	int left, right;
 
-	spin_lock_irqsave(&ak4531->reg_lock, flags);
+	down(&ak4531->reg_mutex);
 	left = (ak4531->regs[left_reg] >> left_shift) & mask;
 	right = (ak4531->regs[right_reg] >> right_shift) & mask;
-	spin_unlock_irqrestore(&ak4531->reg_lock, flags);
+	up(&ak4531->reg_mutex);
 	if (invert) {
 		left = mask - left;
 		right = mask - right;
@@ -158,7 +155,6 @@
 static int snd_ak4531_put_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
 	ak4531_t *ak4531 = snd_kcontrol_chip(kcontrol);
-	unsigned long flags;
 	int left_reg = kcontrol->private_value & 0xff;
 	int right_reg = (kcontrol->private_value >> 8) & 0xff;
 	int left_shift = (kcontrol->private_value >> 16) & 0x07;
@@ -176,7 +172,7 @@
 	}
 	left <<= left_shift;
 	right <<= right_shift;
-	spin_lock_irqsave(&ak4531->reg_lock, flags);
+	down(&ak4531->reg_mutex);
 	if (left_reg == right_reg) {
 		left = (ak4531->regs[left_reg] & ~((mask << left_shift) | (mask << right_shift))) | left | right;
 		change = left != ak4531->regs[left_reg];
@@ -188,7 +184,7 @@
 		ak4531->write(ak4531, left_reg, ak4531->regs[left_reg] = left);
 		ak4531->write(ak4531, right_reg, ak4531->regs[right_reg] = right);
 	}
-	spin_unlock_irqrestore(&ak4531->reg_lock, flags);
+	up(&ak4531->reg_mutex);
 	return change;
 }
 
@@ -210,25 +206,23 @@
 static int snd_ak4531_get_input_sw(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
 	ak4531_t *ak4531 = snd_kcontrol_chip(kcontrol);
-	unsigned long flags;
 	int reg1 = kcontrol->private_value & 0xff;
 	int reg2 = (kcontrol->private_value >> 8) & 0xff;
 	int left_shift = (kcontrol->private_value >> 16) & 0x0f;
 	int right_shift = (kcontrol->private_value >> 24) & 0x0f;
 
-	spin_lock_irqsave(&ak4531->reg_lock, flags);
+	down(&ak4531->reg_mutex);
 	ucontrol->value.integer.value[0] = (ak4531->regs[reg1] >> left_shift) & 1;
 	ucontrol->value.integer.value[1] = (ak4531->regs[reg2] >> left_shift) & 1;
 	ucontrol->value.integer.value[2] = (ak4531->regs[reg1] >> right_shift) & 1;
 	ucontrol->value.integer.value[3] = (ak4531->regs[reg2] >> right_shift) & 1;
-	spin_unlock_irqrestore(&ak4531->reg_lock, flags);
+	up(&ak4531->reg_mutex);
 	return 0;
 }
 
 static int snd_ak4531_put_input_sw(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
 	ak4531_t *ak4531 = snd_kcontrol_chip(kcontrol);
-	unsigned long flags;
 	int reg1 = kcontrol->private_value & 0xff;
 	int reg2 = (kcontrol->private_value >> 8) & 0xff;
 	int left_shift = (kcontrol->private_value >> 16) & 0x0f;
@@ -236,7 +230,7 @@
 	int change;
 	int val1, val2;
 
-	spin_lock_irqsave(&ak4531->reg_lock, flags);
+	down(&ak4531->reg_mutex);
 	val1 = ak4531->regs[reg1] & ~((1 << left_shift) | (1 << right_shift));
 	val2 = ak4531->regs[reg2] & ~((1 << left_shift) | (1 << right_shift));
 	val1 |= (ucontrol->value.integer.value[0] & 1) << left_shift;
@@ -246,7 +240,7 @@
 	change = val1 != ak4531->regs[reg1] || val2 != ak4531->regs[reg2];
 	ak4531->write(ak4531, reg1, ak4531->regs[reg1] = val1);
 	ak4531->write(ak4531, reg2, ak4531->regs[reg2] = val2);
-	spin_unlock_irqrestore(&ak4531->reg_lock, flags);
+	up(&ak4531->reg_mutex);
 	return change;
 }
 
@@ -367,7 +361,7 @@
 	if (ak4531 == NULL)
 		return -ENOMEM;
 	*ak4531 = *_ak4531;
-	spin_lock_init(&ak4531->reg_lock);
+	init_MUTEX(&ak4531->reg_mutex);
 	if ((err = snd_component_add(card, "AK4531")) < 0) {
 		snd_ak4531_free(ak4531);
 		return err;
@@ -388,7 +382,7 @@
 		}
 	}
 	snd_ak4531_proc_init(card, ak4531);
-	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, ak4531, &ops)) < 0) {
+	if ((err = snd_device_new(card, SNDRV_DEV_CODEC, ak4531, &ops)) < 0) {
 		snd_ak4531_free(ak4531);
 		return err;
 	}
diff -Nru a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c
--- a/sound/pci/ali5451/ali5451.c	2005-03-01 23:39:16 -08:00
+++ b/sound/pci/ali5451/ali5451.c	2005-03-01 23:39:16 -08:00
@@ -1933,7 +1933,6 @@
 
 	spin_unlock_irq(&chip->reg_lock);
 	pci_disable_device(chip->pci);
-	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
 	return 0;
 }
 
@@ -1971,7 +1970,6 @@
 	spin_unlock_irq(&chip->reg_lock);
 
 	snd_ac97_resume(chip->ac97);
-	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
 	
 	return 0;
 }
@@ -1989,8 +1987,7 @@
 		pci_release_regions(codec->pci);
 	pci_disable_device(codec->pci);
 #ifdef CONFIG_PM
-	if (codec->image)
-		kfree(codec->image);
+	kfree(codec->image);
 #endif
 	kfree(codec);
 	return 0;
diff -Nru a/sound/pci/atiixp.c b/sound/pci/atiixp.c
--- a/sound/pci/atiixp.c	2005-03-01 23:38:58 -08:00
+++ b/sound/pci/atiixp.c	2005-03-01 23:38:58 -08:00
@@ -43,6 +43,7 @@
 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
 static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;	/* Enable this card */
 static int ac97_clock[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 48000};
+static char *ac97_quirk[SNDRV_CARDS];
 static int spdif_aclink[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
 
 module_param_array(index, int, NULL, 0444);
@@ -53,6 +54,8 @@
 MODULE_PARM_DESC(enable, "Enable audio part of ATI IXP controller.");
 module_param_array(ac97_clock, int, NULL, 0444);
 MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (default 48000Hz).");
+module_param_array(ac97_quirk, charp, NULL, 0444);
+MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware.");
 module_param_array(spdif_aclink, bool, NULL, 0444);
 MODULE_PARM_DESC(spdif_aclink, "S/PDIF over AC-link.");
 
@@ -264,7 +267,6 @@
 	ac97_t *ac97[NUM_ATI_CODECS];
 
 	spinlock_t reg_lock;
-	spinlock_t ac97_lock;
 
 	atiixp_dma_t dmas[NUM_ATI_DMAS];
 	struct ac97_pcm *pcms[NUM_ATI_PCMS];
@@ -476,20 +478,14 @@
 static unsigned short snd_atiixp_ac97_read(ac97_t *ac97, unsigned short reg)
 {
 	atiixp_t *chip = ac97->private_data;
-	unsigned short data;
-	spin_lock(&chip->ac97_lock);
-	data = snd_atiixp_codec_read(chip, ac97->num, reg);
-	spin_unlock(&chip->ac97_lock);
-	return data;
+	return snd_atiixp_codec_read(chip, ac97->num, reg);
     
 }
 
 static void snd_atiixp_ac97_write(ac97_t *ac97, unsigned short reg, unsigned short val)
 {
 	atiixp_t *chip = ac97->private_data;
-	spin_lock(&chip->ac97_lock);
 	snd_atiixp_codec_write(chip, ac97->num, reg, val);
-	spin_unlock(&chip->ac97_lock);
 }
 
 /*
@@ -637,21 +633,20 @@
 	snd_pcm_runtime_t *runtime = substream->runtime;
 	atiixp_dma_t *dma = (atiixp_dma_t *)runtime->private_data;
 	unsigned int curptr;
+	int timeout = 1000;
 
-	spin_lock(&chip->reg_lock);
-	curptr = readl(chip->remap_addr + dma->ops->dt_cur);
-	if (curptr < dma->buf_addr) {
-		snd_printdd("curptr = %x, base = %x\n", curptr, dma->buf_addr);
-		curptr = 0;
-	} else {
+	while (timeout--) {
+		curptr = readl(chip->remap_addr + dma->ops->dt_cur);
+		if (curptr < dma->buf_addr)
+			continue;
 		curptr -= dma->buf_addr;
-		if (curptr >= dma->buf_bytes) {
-			snd_printdd("curptr = %x, size = %x\n", curptr, dma->buf_bytes);
-			curptr = 0;
-		}
+		if (curptr >= dma->buf_bytes)
+			continue;
+		return bytes_to_frames(runtime, curptr);
 	}
-	spin_unlock(&chip->reg_lock);
-	return bytes_to_frames(runtime, curptr);
+	snd_printd("atiixp: invalid DMA pointer read 0x%x (buf=%x)\n",
+		   readl(chip->remap_addr + dma->ops->dt_cur), dma->buf_addr);
+	return 0;
 }
 
 /*
@@ -1336,7 +1331,17 @@
  * ac97 mixer section
  */
 
-static int __devinit snd_atiixp_mixer_new(atiixp_t *chip, int clock)
+static struct ac97_quirk ac97_quirks[] __devinitdata = {
+	{
+		.vendor = 0x103c,
+		.device = 0x006b,
+		.name = "HP Pavilion ZV5030US",
+		.type = AC97_TUNE_MUTE_LED
+	},
+	{ } /* terminator */
+};
+
+static int __devinit snd_atiixp_mixer_new(atiixp_t *chip, int clock, const char *quirk_override)
 {
 	ac97_bus_t *pbus;
 	ac97_template_t ac97;
@@ -1383,7 +1388,7 @@
 		return -ENODEV;
 	}
 
-	/* snd_ac97_tune_hardware(chip->ac97, ac97_quirks); */
+	snd_ac97_tune_hardware(chip->ac97[0], ac97_quirks, quirk_override);
 
 	return 0;
 }
@@ -1409,7 +1414,6 @@
 
 	pci_set_power_state(chip->pci, 3);
 	pci_disable_device(chip->pci);
-	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
 	return 0;
 }
 
@@ -1429,7 +1433,6 @@
 		if (chip->ac97[i])
 			snd_ac97_resume(chip->ac97[i]);
 
-	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
 	return 0;
 }
 #endif /* CONFIG_PM */
@@ -1508,7 +1511,6 @@
 	}
 
 	spin_lock_init(&chip->reg_lock);
-	spin_lock_init(&chip->ac97_lock);
 	init_MUTEX(&chip->open_mutex);
 	chip->card = card;
 	chip->pci = pci;
@@ -1579,7 +1581,7 @@
 
 	chip->spdif_over_aclink = spdif_aclink[dev];
 
-	if ((err = snd_atiixp_mixer_new(chip, ac97_clock[dev])) < 0)
+	if ((err = snd_atiixp_mixer_new(chip, ac97_clock[dev], ac97_quirk[dev])) < 0)
 		goto __error;
 
 	if ((err = snd_atiixp_pcm_new(chip)) < 0)
diff -Nru a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c
--- a/sound/pci/atiixp_modem.c	2005-03-01 23:39:17 -08:00
+++ b/sound/pci/atiixp_modem.c	2005-03-01 23:39:17 -08:00
@@ -247,7 +247,6 @@
 	ac97_t *ac97[NUM_ATI_CODECS];
 
 	spinlock_t reg_lock;
-	spinlock_t ac97_lock;
 
 	atiixp_dma_t dmas[NUM_ATI_DMAS];
 	struct ac97_pcm *pcms[NUM_ATI_PCMS];
@@ -457,20 +456,14 @@
 static unsigned short snd_atiixp_ac97_read(ac97_t *ac97, unsigned short reg)
 {
 	atiixp_t *chip = ac97->private_data;
-	unsigned short data;
-	spin_lock(&chip->ac97_lock);
-	data = snd_atiixp_codec_read(chip, ac97->num, reg);
-	spin_unlock(&chip->ac97_lock);
-	return data;
+	return snd_atiixp_codec_read(chip, ac97->num, reg);
     
 }
 
 static void snd_atiixp_ac97_write(ac97_t *ac97, unsigned short reg, unsigned short val)
 {
 	atiixp_t *chip = ac97->private_data;
-	spin_lock(&chip->ac97_lock);
 	snd_atiixp_codec_write(chip, ac97->num, reg, val);
-	spin_unlock(&chip->ac97_lock);
 }
 
 /*
@@ -1131,7 +1124,6 @@
 
 	pci_set_power_state(chip->pci, 3);
 	pci_disable_device(chip->pci);
-	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
 	return 0;
 }
 
@@ -1151,7 +1143,6 @@
 		if (chip->ac97[i])
 			snd_ac97_resume(chip->ac97[i]);
 
-	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
 	return 0;
 }
 #endif /* CONFIG_PM */
@@ -1230,7 +1221,6 @@
 	}
 
 	spin_lock_init(&chip->reg_lock);
-	spin_lock_init(&chip->ac97_lock);
 	init_MUTEX(&chip->open_mutex);
 	chip->card = card;
 	chip->pci = pci;
diff -Nru a/sound/pci/au88x0/au88x0.c b/sound/pci/au88x0/au88x0.c
--- a/sound/pci/au88x0/au88x0.c	2005-03-01 23:38:57 -08:00
+++ b/sound/pci/au88x0/au88x0.c	2005-03-01 23:38:57 -08:00
@@ -4,7 +4,7 @@
  *
  *   This driver is the result of the OpenVortex Project from Savannah
  * (savannah.nongnu.org/projects/openvortex). I would like to thank
- * the developers of OpenVortex, Jeff Muizelar and Kester Maddock, from
+ * the developers of OpenVortex, Jeff Muizelaar and Kester Maddock, from
  * whom i got plenty of help, and their codebase was invaluable.
  *   Thanks to the ALSA developers, they helped a lot working out
  * the ALSA part.
@@ -170,9 +170,8 @@
 	if ((err = pci_request_regions(pci, CARD_NAME_SHORT)) != 0)
 		goto regions_out;
 
-	chip->mmio =
-	    ioremap_nocache(pci_resource_start(pci, 0),
-			    pci_resource_len(pci, 0));
+	chip->mmio = ioremap_nocache(pci_resource_start(pci, 0),
+	                             pci_resource_len(pci, 0));
 	if (!chip->mmio) {
 		printk(KERN_ERR "MMIO area remap failed.\n");
 		err = -ENOMEM;
@@ -187,10 +186,9 @@
 		goto core_out;
 	}
 
-	if ((err =
-	     request_irq(pci->irq, vortex_interrupt,
-			 SA_INTERRUPT | SA_SHIRQ, CARD_NAME_SHORT,
-			 (void *)chip)) != 0) {
+	if ((err = request_irq(pci->irq, vortex_interrupt,
+	                       SA_INTERRUPT | SA_SHIRQ, CARD_NAME_SHORT,
+	                       chip)) != 0) {
 		printk(KERN_ERR "cannot grab irq\n");
 		goto irq_out;
 	}
@@ -214,7 +212,6 @@
       irq_out:
 	vortex_core_shutdown(chip);
       core_out:
-	//FIXME: the type of chip->mmio might need to be changed??
 	iounmap(chip->mmio);
       ioremap_out:
 	pci_release_regions(chip->pci_dev);
diff -Nru a/sound/pci/au88x0/au88x0.h b/sound/pci/au88x0/au88x0.h
--- a/sound/pci/au88x0/au88x0.h	2005-03-01 23:38:58 -08:00
+++ b/sound/pci/au88x0/au88x0.h	2005-03-01 23:38:58 -08:00
@@ -80,7 +80,8 @@
 #define VORTEX_RESOURCE_LAST	0x00000005
 
 /* Check for SDAC bit in "Extended audio ID" AC97 register */
-#define VORTEX_IS_QUAD(x) ((x->codec == NULL) ?  0 : (x->codec->ext_id&0x80))
+//#define VORTEX_IS_QUAD(x) (((x)->codec == NULL) ?  0 : ((x)->codec->ext_id&0x80))
+#define VORTEX_IS_QUAD(x) ((x)->isquad)
 /* Check if chip has bug. */
 #define IS_BAD_CHIP(x) (\
 	(x->rev == 0xfe && x->device == PCI_DEVICE_ID_AUREAL_VORTEX_2) || \
@@ -164,6 +165,8 @@
 	int xt_mode;		/* 1: speakers, 0:headphones. */
 #endif
 
+	int isquad;		/* cache of extended ID codec flag. */
+
 	/* Gameport stuff. */
 	struct gameport *gameport;
 
@@ -208,6 +211,7 @@
 static void vortex_adbdma_pausefifo(vortex_t * vortex, int adbdma);
 static void vortex_adbdma_resumefifo(vortex_t * vortex, int adbdma);
 static int inline vortex_adbdma_getlinearpos(vortex_t * vortex, int adbdma);
+static void vortex_adbdma_resetup(vortex_t *vortex, int adbdma);
 
 #ifndef CHIP_AU8810
 static void vortex_wtdma_startfifo(vortex_t * vortex, int wtdma);
diff -Nru a/sound/pci/au88x0/au88x0_core.c b/sound/pci/au88x0/au88x0_core.c
--- a/sound/pci/au88x0/au88x0_core.c	2005-03-01 23:39:16 -08:00
+++ b/sound/pci/au88x0/au88x0_core.c	2005-03-01 23:39:16 -08:00
@@ -21,7 +21,7 @@
  These functions are mainly the result of translations made
  from the original disassembly of the au88x0 binary drivers,
  written by Aureal before they went down.
- Many thanks to the Jeff Muizelar, Kester Maddock, and whoever
+ Many thanks to the Jeff Muizelaar, Kester Maddock, and whoever
  contributed to the OpenVortex project.
  The author of this file, put the few available pieces together
  and translated the rest of the riddle (Mix, Src and connection stuff).
@@ -1223,6 +1223,33 @@
 	return delta;
 }
 
+
+static void vortex_adbdma_resetup(vortex_t *vortex, int adbdma) {
+	stream_t *dma = &vortex->dma_adb[adbdma];
+	int p, pp, i;
+
+	/* refresh hw page table */
+	for (i=0 ; i < 4 && i < dma->nr_periods; i++) {
+		/* p: audio buffer page index */
+		p = dma->period_virt + i;
+		if (p >= dma->nr_periods)
+			p -= dma->nr_periods;
+		/* pp: hardware DMA page index. */
+		pp = dma->period_real + i;
+		if (dma->nr_periods < 4) {
+			if (pp >= dma->nr_periods)
+				pp -= dma->nr_periods;
+		}
+		else {
+			if (pp >= 4)
+				pp -= 4;
+		}
+		hwwrite(vortex->mmio, VORTEX_ADBDMA_BUFBASE+(((adbdma << 2)+pp) << 2), snd_sgbuf_get_addr(dma->sgbuf, dma->period_bytes * p));
+		/* Force write thru cache. */
+		hwread(vortex->mmio, VORTEX_ADBDMA_BUFBASE + (((adbdma << 2)+pp) << 2));
+	}
+}
+
 static int inline vortex_adbdma_getlinearpos(vortex_t * vortex, int adbdma)
 {
 	stream_t *dma = &vortex->dma_adb[adbdma];
@@ -2081,7 +2108,6 @@
 	    || ((dir == SNDRV_PCM_STREAM_CAPTURE) && (nr_ch > 2)))
 		return -EBUSY;
 
-	spin_lock(&vortex->lock);
 	if (dma >= 0) {
 		en = 0;
 		vortex_adb_checkinout(vortex,
@@ -2277,7 +2303,6 @@
 		}
 	}
 	vortex->dma_adb[dma].nr_ch = nr_ch;
-	spin_unlock(&vortex->lock);
 
 #if 0
 	/* AC97 Codec channel setup. FIXME: this has no effect on some cards !! */
@@ -2406,22 +2431,28 @@
 	}
 	if (source & IRQ_PCMOUT) {
 		/* ALSA period acknowledge. */
+		spin_lock(&vortex->lock);
 		for (i = 0; i < NR_ADB; i++) {
 			if (vortex->dma_adb[i].fifo_status == FIFO_START) {
 				if (vortex_adbdma_bufshift(vortex, i)) ;
+				spin_unlock(&vortex->lock);
 				snd_pcm_period_elapsed(vortex->dma_adb[i].
 						       substream);
+				spin_lock(&vortex->lock);
 			}
 		}
 #ifndef CHIP_AU8810
 		for (i = 0; i < NR_WT; i++) {
 			if (vortex->dma_wt[i].fifo_status == FIFO_START) {
 				if (vortex_wtdma_bufshift(vortex, i)) ;
+				spin_unlock(&vortex->lock);
 				snd_pcm_period_elapsed(vortex->dma_wt[i].
 						       substream);
+				spin_lock(&vortex->lock);
 			}
 		}
 #endif
+		spin_unlock(&vortex->lock);
 		handled = 1;
 	}
 	//Acknowledge the Timer interrupt
@@ -2450,32 +2481,32 @@
 
 	for (i = 0; i < 32; i++) {
 		hwwrite(vortex->mmio, (VORTEX_CODEC_CHN + (i << 2)), 0);
-		udelay(2000);
+		msleep(2);
 	}
 	if (0) {
 		hwwrite(vortex->mmio, VORTEX_CODEC_CTRL, 0x8068);
-		udelay(1000);
+		msleep(1);
 		hwwrite(vortex->mmio, VORTEX_CODEC_CTRL, 0x00e8);
-		udelay(1000);
+		msleep(1);
 	} else {
 		hwwrite(vortex->mmio, VORTEX_CODEC_CTRL, 0x00a8);
-		udelay(2000);
+		msleep(2);
 		hwwrite(vortex->mmio, VORTEX_CODEC_CTRL, 0x80a8);
-		udelay(2000);
+		msleep(2);
 		hwwrite(vortex->mmio, VORTEX_CODEC_CTRL, 0x80e8);
-		udelay(2000);
+		msleep(2);
 		hwwrite(vortex->mmio, VORTEX_CODEC_CTRL, 0x80a8);
-		udelay(2000);
+		msleep(2);
 		hwwrite(vortex->mmio, VORTEX_CODEC_CTRL, 0x00a8);
-		udelay(2000);
+		msleep(2);
 		hwwrite(vortex->mmio, VORTEX_CODEC_CTRL, 0x00e8);
 	}
 	for (i = 0; i < 32; i++) {
 		hwwrite(vortex->mmio, (VORTEX_CODEC_CHN + (i << 2)), 0);
-		udelay(5000);
+		msleep(5);
 	}
 	hwwrite(vortex->mmio, VORTEX_CODEC_CTRL, 0xe8);
-	udelay(1000);
+	msleep(1);
 	/* Enable codec channels 0 and 1. */
 	hwwrite(vortex->mmio, VORTEX_CODEC_EN,
 		hwread(vortex->mmio, VORTEX_CODEC_EN) | EN_CODEC);
@@ -2486,16 +2517,13 @@
 {
 
 	vortex_t *card = (vortex_t *) codec->private_data;
-	unsigned long flags;
 	unsigned int lifeboat = 0;
-	spin_lock_irqsave(&card->lock, flags);
 
 	/* wait for transactions to clear */
 	while (!(hwread(card->mmio, VORTEX_CODEC_CTRL) & 0x100)) {
 		udelay(100);
 		if (lifeboat++ > POLL_COUNT) {
 			printk(KERN_ERR "vortex: ac97 codec stuck busy\n");
-			spin_unlock_irqrestore(&card->lock, flags);
 			return;
 		}
 	}
@@ -2507,8 +2535,6 @@
 
 	/* Flush Caches. */
 	hwread(card->mmio, VORTEX_CODEC_IO);
-
-	spin_unlock_irqrestore(&card->lock, flags);
 }
 
 static unsigned short vortex_codec_read(ac97_t * codec, unsigned short addr)
@@ -2516,17 +2542,13 @@
 
 	vortex_t *card = (vortex_t *) codec->private_data;
 	u32 read_addr, data;
-	unsigned long flags;
 	unsigned lifeboat = 0;
 
-	spin_lock_irqsave(&card->lock, flags);
-
 	/* wait for transactions to clear */
 	while (!(hwread(card->mmio, VORTEX_CODEC_CTRL) & 0x100)) {
 		udelay(100);
 		if (lifeboat++ > POLL_COUNT) {
 			printk(KERN_ERR "vortex: ac97 codec stuck busy\n");
-			spin_unlock_irqrestore(&card->lock, flags);
 			return 0xffff;
 		}
 	}
@@ -2535,20 +2557,15 @@
 	hwwrite(card->mmio, VORTEX_CODEC_IO, read_addr);
 
 	/* wait for address */
-	{
+	do {
 		udelay(100);
 		data = hwread(card->mmio, VORTEX_CODEC_IO);
 		if (lifeboat++ > POLL_COUNT) {
 			printk(KERN_ERR "vortex: ac97 address never arrived\n");
-			spin_unlock_irqrestore(&card->lock, flags);
 			return 0xffff;
 		}
-	}
-	while ((data & VORTEX_CODEC_ADDMASK) !=
-	       (addr << VORTEX_CODEC_ADDSHIFT)) ;
-
-	/* Unlock. */
-	spin_unlock_irqrestore(&card->lock, flags);
+	} while ((data & VORTEX_CODEC_ADDMASK) !=
+		 (addr << VORTEX_CODEC_ADDSHIFT));
 
 	/* return data. */
 	return (u16) (data & VORTEX_CODEC_DATMASK);
@@ -2644,10 +2661,10 @@
 	printk(KERN_INFO "Vortex: init.... ");
 	/* Hardware Init. */
 	hwwrite(vortex->mmio, VORTEX_CTRL, 0xffffffff);
-	udelay(5000);
+	msleep(5);
 	hwwrite(vortex->mmio, VORTEX_CTRL,
 		hwread(vortex->mmio, VORTEX_CTRL) & 0xffdfffff);
-	udelay(5000);
+	msleep(5);
 	/* Reset IRQ flags */
 	hwwrite(vortex->mmio, VORTEX_IRQ_SOURCE, 0xffffffff);
 	hwread(vortex->mmio, VORTEX_IRQ_STAT);
@@ -2714,7 +2731,7 @@
 
 	hwwrite(vortex->mmio, VORTEX_IRQ_CTRL, 0);
 	hwwrite(vortex->mmio, VORTEX_CTRL, 0);
-	udelay(5000);
+	msleep(5);
 	hwwrite(vortex->mmio, VORTEX_IRQ_SOURCE, 0xffff);
 
 	printk(KERN_INFO "done.\n");
diff -Nru a/sound/pci/au88x0/au88x0_eq.c b/sound/pci/au88x0/au88x0_eq.c
--- a/sound/pci/au88x0/au88x0_eq.c	2005-03-01 23:39:10 -08:00
+++ b/sound/pci/au88x0/au88x0_eq.c	2005-03-01 23:39:10 -08:00
@@ -45,6 +45,8 @@
 #define VORTEX_EQ_SOURCE (VORTEX_EQ_BASE + 0x430)
 #define VORTEX_EQ_CTRL   (VORTEX_EQ_BASE + 0x440)
 
+#define VORTEX_BAND_COEFF_SIZE 0x30
+
 /* CEqHw.s */
 static void vortex_EqHw_SetTimeConsts(vortex_t * vortex, u16 gain, u16 level)
 {
@@ -52,10 +54,10 @@
 	hwwrite(vortex->mmio, 0x2b3c8, level);
 }
 
-static inline short sign_invert(short a)
+static inline u16 sign_invert(u16 a)
 {
 	/* -(-32768) -> -32768 so we do -(-32768) -> 32767 to make the result positive */
-	if (a == -32768)
+	if (a == (u16)-32768)
 		return 32767;
 	else
 		return -a;
@@ -71,13 +73,13 @@
 		hwwrite(vortex->mmio, 0x2b004 + n * 0x30, coefs[i + 1]);
 
 		if (eqhw->this08 == 0) {
-			hwwrite(vortex->mmio, 0x2b008 + n * 0x30, coefs[i + 2] & 0xffff);
-			hwwrite(vortex->mmio, 0x2b00c + n * 0x30, coefs[i + 3] & 0xffff);
-			hwwrite(vortex->mmio, 0x2b010 + n * 0x30, coefs[i + 4] & 0xffff);
+			hwwrite(vortex->mmio, 0x2b008 + n * 0x30, coefs[i + 2]);
+			hwwrite(vortex->mmio, 0x2b00c + n * 0x30, coefs[i + 3]);
+			hwwrite(vortex->mmio, 0x2b010 + n * 0x30, coefs[i + 4]);
 		} else {
-			hwwrite(vortex->mmio, 0x2b008 + n * 0x30, sign_invert(coefs[2 + i]) & 0xffff);
-			hwwrite(vortex->mmio, 0x2b00c + n * 0x30, sign_invert(coefs[3 + i]) & 0xffff);
-		        hwwrite(vortex->mmio, 0x2b010 + n * 0x30, sign_invert(coefs[4 + i]) & 0xffff);
+			hwwrite(vortex->mmio, 0x2b008 + n * 0x30, sign_invert(coefs[2 + i]));
+			hwwrite(vortex->mmio, 0x2b00c + n * 0x30, sign_invert(coefs[3 + i]));
+		        hwwrite(vortex->mmio, 0x2b010 + n * 0x30, sign_invert(coefs[4 + i]));
 		}
 		i += 5;
 	}
@@ -93,13 +95,13 @@
 		hwwrite(vortex->mmio, 0x2b1e4 + n * 0x30, coefs[1 + i]);
 
 		if (eqhw->this08 == 0) {
-			hwwrite(vortex->mmio, 0x2b1e8 + n * 0x30, coefs[2 + i] & 0xffff);
-			hwwrite(vortex->mmio, 0x2b1ec + n * 0x30, coefs[3 + i] & 0xffff);
-			hwwrite(vortex->mmio, 0x2b1f0 + n * 0x30, coefs[4 + i] & 0xffff);
+			hwwrite(vortex->mmio, 0x2b1e8 + n * 0x30, coefs[2 + i]);
+			hwwrite(vortex->mmio, 0x2b1ec + n * 0x30, coefs[3 + i]);
+			hwwrite(vortex->mmio, 0x2b1f0 + n * 0x30, coefs[4 + i]);
 		} else {
-			hwwrite(vortex->mmio, 0x2b1e8 + n * 0x30, sign_invert(coefs[2 + i]) & 0xffff);
-			hwwrite(vortex->mmio, 0x2b1ec + n * 0x30, sign_invert(coefs[3 + i]) & 0xffff);
-			hwwrite(vortex->mmio, 0x2b1f0 + n * 0x30, sign_invert(coefs[4 + i]) & 0xffff);
+			hwwrite(vortex->mmio, 0x2b1e8 + n * 0x30, sign_invert(coefs[2 + i]));
+			hwwrite(vortex->mmio, 0x2b1ec + n * 0x30, sign_invert(coefs[3 + i]));
+			hwwrite(vortex->mmio, 0x2b1f0 + n * 0x30, sign_invert(coefs[4 + i]));
 		}
 		i += 5;
 	}
@@ -176,8 +178,8 @@
 		hwwrite(vortex->mmio, 0x2b3d4, a);
 		hwwrite(vortex->mmio, 0x2b3ec, b);
 	} else {
-		hwwrite(vortex->mmio, 0x2b3d4, sign_invert(a) & 0xffff);
-		hwwrite(vortex->mmio, 0x2b3ec, sign_invert(b) & 0xffff);
+		hwwrite(vortex->mmio, 0x2b3d4, sign_invert(a));
+		hwwrite(vortex->mmio, 0x2b3ec, sign_invert(b));
 	}
 }
 
@@ -319,25 +321,27 @@
 
 #endif
 /* EQ band levels settings */
-static void vortex_EqHw_SetLevels(vortex_t * vortex, u16 a[])
+static void vortex_EqHw_SetLevels(vortex_t * vortex, u16 peaks[])
 {
 	eqhw_t *eqhw = &(vortex->eq.this04);
-	int ebx;
+	int i;
 
-	for (ebx = 0; ebx < eqhw->this04; ebx++) {
-		hwwrite(vortex->mmio, 0x2b024 + ebx * 0x30, a[ebx]);
+	/* set left peaks */
+	for (i = 0; i < eqhw->this04; i++) {
+		hwwrite(vortex->mmio, 0x2b024 + i * VORTEX_BAND_COEFF_SIZE, peaks[i]);
 	}
 
-	hwwrite(vortex->mmio, 0x2b3cc, a[eqhw->this04]);
-	hwwrite(vortex->mmio, 0x2b3d8, a[eqhw->this04 + 1]);
+	hwwrite(vortex->mmio, 0x2b3cc, peaks[eqhw->this04]);
+	hwwrite(vortex->mmio, 0x2b3d8, peaks[eqhw->this04 + 1]);
 
-	for (ebx = 0; ebx < eqhw->this04; ebx++) {
-		hwwrite(vortex->mmio, 0x2b204 + ebx * 0x30,
-			a[ebx + (eqhw->this04 + 2)]);
+	/* set right peaks */
+	for (i = 0; i < eqhw->this04; i++) {
+		hwwrite(vortex->mmio, 0x2b204 + i * VORTEX_BAND_COEFF_SIZE,
+			peaks[i + (eqhw->this04 + 2)]);
 	}
 
-	hwwrite(vortex->mmio, 0x2b3e4, a[2 + (eqhw->this04 * 2)]);
-	hwwrite(vortex->mmio, 0x2b3f0, a[3 + (eqhw->this04 * 2)]);
+	hwwrite(vortex->mmio, 0x2b3e4, peaks[2 + (eqhw->this04 * 2)]);
+	hwwrite(vortex->mmio, 0x2b3f0, peaks[3 + (eqhw->this04 * 2)]);
 }
 
 #if 0
diff -Nru a/sound/pci/au88x0/au88x0_mixer.c b/sound/pci/au88x0/au88x0_mixer.c
--- a/sound/pci/au88x0/au88x0_mixer.c	2005-03-01 23:38:53 -08:00
+++ b/sound/pci/au88x0/au88x0_mixer.c	2005-03-01 23:38:53 -08:00
@@ -26,5 +26,7 @@
 	memset(&ac97, 0, sizeof(ac97));
 	// Intialize AC97 codec stuff.
 	ac97.private_data = vortex;
-	return snd_ac97_mixer(pbus, &ac97, &vortex->codec);
+	err = snd_ac97_mixer(pbus, &ac97, &vortex->codec);
+	vortex->isquad = ((vortex->codec == NULL) ?  0 : (vortex->codec->ext_id&0x80));
+	return err;
 }
diff -Nru a/sound/pci/au88x0/au88x0_pcm.c b/sound/pci/au88x0/au88x0_pcm.c
--- a/sound/pci/au88x0/au88x0_pcm.c	2005-03-01 23:38:57 -08:00
+++ b/sound/pci/au88x0/au88x0_pcm.c	2005-03-01 23:38:57 -08:00
@@ -206,6 +206,7 @@
 	   printk(KERN_INFO "Vortex: periods %d, period_bytes %d, channels = %d\n", params_periods(hw_params),
 	   params_period_bytes(hw_params), params_channels(hw_params));
 	 */
+	spin_lock_irq(&chip->lock);
 	// Make audio routes and config buffer DMA.
 	if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) {
 		int dma, type = VORTEX_PCM_TYPE(substream->pcm);
@@ -243,6 +244,7 @@
 					params_periods(hw_params));
 	}
 #endif
+	spin_unlock_irq(&chip->lock);
 	return 0;
 }
 
@@ -252,6 +254,7 @@
 	vortex_t *chip = snd_pcm_substream_chip(substream);
 	stream_t *stream = (stream_t *) (substream->runtime->private_data);
 
+	spin_lock_irq(&chip->lock);
 	// Delete audio routes.
 	if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) {
 		if (stream != NULL)
@@ -266,6 +269,7 @@
 	}
 #endif
 	substream->runtime->private_data = NULL;
+	spin_unlock_irq(&chip->lock);
 
 	return snd_pcm_lib_free_pages(substream);
 }
@@ -284,6 +288,7 @@
 	else
 		dir = 0;
 	fmt = vortex_alsafmt_aspfmt(runtime->format);
+	spin_lock_irq(&chip->lock);
 	if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) {
 		vortex_adbdma_setmode(chip, dma, 1, dir, fmt, 0 /*? */ ,
 				      0);
@@ -298,6 +303,7 @@
 		vortex_wtdma_setstartbuffer(chip, dma, 0);
 	}
 #endif
+	spin_unlock_irq(&chip->lock);
 	return 0;
 }
 
@@ -308,13 +314,16 @@
 	stream_t *stream = (stream_t *) substream->runtime->private_data;
 	int dma = stream->dma;
 
+	spin_lock(&chip->lock);
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
 		// do something to start the PCM engine
 		//printk(KERN_INFO "vortex: start %d\n", dma);
 		stream->fifo_enabled = 1;
-		if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT)
+		if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) {
+			vortex_adbdma_resetup(chip, dma);
 			vortex_adbdma_startfifo(chip, dma);
+		}
 #ifndef CHIP_AU8810
 		else {
 			printk(KERN_INFO "vortex: wt start %d\n", dma);
@@ -355,8 +364,10 @@
 #endif
 		break;
 	default:
+		spin_unlock(&chip->lock);
 		return -EINVAL;
 	}
+	spin_unlock(&chip->lock);
 	return 0;
 }
 
diff -Nru a/sound/pci/azt3328.c b/sound/pci/azt3328.c
--- a/sound/pci/azt3328.c	2005-03-01 23:38:58 -08:00
+++ b/sound/pci/azt3328.c	2005-03-01 23:38:58 -08:00
@@ -214,17 +214,17 @@
 
 MODULE_DEVICE_TABLE(pci, snd_azf3328_ids);
 
-void snd_azf3328_io2_write(azf3328_t *chip, int reg, unsigned char value)
+static inline void snd_azf3328_io2_write(azf3328_t *chip, int reg, unsigned char value)
 {
 	outb(value, chip->io2_port + reg);
 }
 
-unsigned char snd_azf3328_io2_read(azf3328_t *chip, int reg)
+static inline unsigned char snd_azf3328_io2_read(azf3328_t *chip, int reg)
 {
 	return inb(chip->io2_port + reg);
 }
 
-void snd_azf3328_mixer_write(azf3328_t *chip, int reg, unsigned long value, int type)
+static void snd_azf3328_mixer_write(azf3328_t *chip, int reg, unsigned long value, int type)
 {
 	switch(type) {
 	case WORD_VALUE:
@@ -239,26 +239,7 @@
 	}
 }
 
-unsigned long snd_azf3328_mixer_read(azf3328_t *chip, int reg, int type)
-{
-	unsigned long res = 0;
-
-	switch(type) {
-	case WORD_VALUE:
-		res = (unsigned long)inw(chip->mixer_port + reg);
-		break;
-	case DWORD_VALUE:
-		res = (unsigned long)inl(chip->mixer_port + reg);
-		break;
-	case BYTE_VALUE:
-		res = (unsigned long)inb(chip->mixer_port + reg);
-		break;
-	}
-
-	return res;
-}
-
-void snd_azf3328_mixer_set_mute(azf3328_t *chip, int reg, int do_mute)
+static void snd_azf3328_mixer_set_mute(azf3328_t *chip, int reg, int do_mute)
 {
 	unsigned char oldval;
 
@@ -272,7 +253,7 @@
 	outb(oldval, chip->mixer_port + reg + 1);
 }
 
-void snd_azf3328_mixer_write_volume_gradually(azf3328_t *chip, int reg, unsigned char dst_vol_left, unsigned char dst_vol_right, int chan_sel, int delay)
+static void snd_azf3328_mixer_write_volume_gradually(azf3328_t *chip, int reg, unsigned char dst_vol_left, unsigned char dst_vol_right, int chan_sel, int delay)
 {
 	unsigned char curr_vol_left = 0, curr_vol_right = 0;
 	int left_done = 0, right_done = 0;
@@ -1363,14 +1344,14 @@
 	for (tmp=0; tmp <= 0x01; tmp += 1)
 		snd_azf3328_dbgmisc("0x%02x: opl 0x%04x, mpu300 0x%04x, mpu310 0x%04x, mpu320 0x%04x, mpu330 0x%04x\n", tmp, inb(0x388 + tmp), inb(0x300 + tmp), inb(0x310 + tmp), inb(0x320 + tmp), inb(0x330 + tmp));
 
-	/* create mixer interface & switches */
-	if ((err = snd_azf3328_mixer_new(chip)) < 0)
-		return err;
-
 	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
 		snd_azf3328_free(chip);
 		return err;
 	}
+
+	/* create mixer interface & switches */
+	if ((err = snd_azf3328_mixer_new(chip)) < 0)
+		return err;
 
 #if 0
 	/* set very low bitrate to reduce noise and power consumption? */
diff -Nru a/sound/pci/bt87x.c b/sound/pci/bt87x.c
--- a/sound/pci/bt87x.c	2005-03-01 23:38:58 -08:00
+++ b/sound/pci/bt87x.c	2005-03-01 23:38:58 -08:00
@@ -45,6 +45,7 @@
 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
 static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;	/* Enable this card */
 static int digital_rate[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = 0 }; /* digital input rate */
+static int load_all;	/* allow to load the non-whitelisted cards */
 
 module_param_array(index, int, NULL, 0444);
 MODULE_PARM_DESC(index, "Index value for Bt87x soundcard");
@@ -54,6 +55,8 @@
 MODULE_PARM_DESC(enable, "Enable Bt87x soundcard");
 module_param_array(digital_rate, int, NULL, 0444);
 MODULE_PARM_DESC(digital_rate, "Digital input rate for Bt87x soundcard");
+module_param(load_all, bool, 0444);
+MODULE_PARM_DESC(load_all, "Allow to load the non-whitelisted cards");
 
 
 #ifndef PCI_VENDOR_ID_BROOKTREE
@@ -159,7 +162,7 @@
 	snd_card_t *card;
 	struct pci_dev *pci;
 
-	void *mmio;
+	void __iomem *mmio;
 	int irq;
 
 	int dig_rate;
@@ -173,7 +176,11 @@
 	unsigned int lines;
 
 	u32 reg_control;
+	u32 interrupt_mask;
+
 	int current_line;
+
+	int pci_parity_errors;
 };
 
 enum { DEVICE_DIGITAL, DEVICE_ANALOG };
@@ -246,33 +253,53 @@
 	}
 }
 
+static void snd_bt87x_pci_error(bt87x_t *chip, unsigned int status)
+{
+	u16 pci_status;
+
+	pci_read_config_word(chip->pci, PCI_STATUS, &pci_status);
+	pci_status &= PCI_STATUS_PARITY | PCI_STATUS_SIG_TARGET_ABORT |
+		PCI_STATUS_REC_TARGET_ABORT | PCI_STATUS_REC_MASTER_ABORT |
+		PCI_STATUS_SIG_SYSTEM_ERROR | PCI_STATUS_DETECTED_PARITY;
+	pci_write_config_word(chip->pci, PCI_STATUS, pci_status);
+	if (pci_status != PCI_STATUS_DETECTED_PARITY)
+		snd_printk(KERN_ERR "Aieee - PCI error! status %#08x, PCI status %#04x\n",
+			   status & ERROR_INTERRUPTS, pci_status);
+	else {
+		snd_printk(KERN_ERR "Aieee - PCI parity error detected!\n");
+		/* error 'handling' similar to aic7xxx_pci.c: */
+		chip->pci_parity_errors++;
+		if (chip->pci_parity_errors > 20) {
+			snd_printk(KERN_ERR "Too many PCI parity errors observed.\n");
+			snd_printk(KERN_ERR "Some device on this bus is generating bad parity.\n");
+			snd_printk(KERN_ERR "This is an error *observed by*, not *generated by*, this card.\n");
+			snd_printk(KERN_ERR "PCI parity error checking has been disabled.\n");
+			chip->interrupt_mask &= ~(INT_PPERR | INT_RIPERR);
+			snd_bt87x_writel(chip, REG_INT_MASK, chip->interrupt_mask);
+		}
+	}
+}
+
 static irqreturn_t snd_bt87x_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	bt87x_t *chip = dev_id;
-	unsigned int status;
+	unsigned int status, irq_status;
 
 	status = snd_bt87x_readl(chip, REG_INT_STAT);
-	if (!(status & MY_INTERRUPTS))
+	irq_status = status & chip->interrupt_mask;
+	if (!irq_status)
 		return IRQ_NONE;
-	snd_bt87x_writel(chip, REG_INT_STAT, status & MY_INTERRUPTS);
+	snd_bt87x_writel(chip, REG_INT_STAT, irq_status);
 
-	if (status & ERROR_INTERRUPTS) {
-		if (status & (INT_FBUS | INT_FTRGT))
+	if (irq_status & ERROR_INTERRUPTS) {
+		if (irq_status & (INT_FBUS | INT_FTRGT))
 			snd_printk(KERN_WARNING "FIFO overrun, status %#08x\n", status);
-		if (status & INT_OCERR)
+		if (irq_status & INT_OCERR)
 			snd_printk(KERN_ERR "internal RISC error, status %#08x\n", status);
-		if (status & (INT_PPERR | INT_RIPERR | INT_PABORT)) {
-			u16 pci_status;
-			pci_read_config_word(chip->pci, PCI_STATUS, &pci_status);
-			pci_write_config_word(chip->pci, PCI_STATUS, pci_status &
-					      (PCI_STATUS_PARITY | PCI_STATUS_SIG_TARGET_ABORT |
-					       PCI_STATUS_REC_TARGET_ABORT | PCI_STATUS_REC_MASTER_ABORT |
-					       PCI_STATUS_SIG_SYSTEM_ERROR | PCI_STATUS_DETECTED_PARITY));
-			snd_printk(KERN_ERR "Aieee - PCI error! status %#08x, PCI status %#04x\n",
-				   status, pci_status);
-		}
+		if (irq_status & (INT_PPERR | INT_RIPERR | INT_PABORT))
+			snd_bt87x_pci_error(chip, irq_status);
 	}
-	if ((status & INT_RISCI) && (chip->reg_control & CTL_ACAP_EN)) {
+	if ((irq_status & INT_RISCI) && (chip->reg_control & CTL_ACAP_EN)) {
 		int current_block, irq_block;
 
 		/* assume that exactly one line has been recorded */
@@ -458,7 +485,7 @@
 	snd_bt87x_writel(chip, REG_RISC_STRT_ADD, chip->dma_risc.addr);
 	snd_bt87x_writel(chip, REG_PACKET_LEN,
 			 chip->line_bytes | (chip->lines << 16));
-	snd_bt87x_writel(chip, REG_INT_MASK, MY_INTERRUPTS);
+	snd_bt87x_writel(chip, REG_INT_MASK, chip->interrupt_mask);
 	snd_bt87x_writel(chip, REG_GPIO_DMA_CTL, chip->reg_control);
 	spin_unlock(&chip->reg_lock);
 	return 0;
@@ -717,6 +744,7 @@
 	}
 
 	chip->reg_control = CTL_DA_ES2 | CTL_PKTP_16 | (15 << CTL_DA_SDR_SHIFT);
+	chip->interrupt_mask = MY_INTERRUPTS;
 	snd_bt87x_writel(chip, REG_GPIO_DMA_CTL, chip->reg_control);
 	snd_bt87x_writel(chip, REG_INT_MASK, 0);
 	snd_bt87x_writel(chip, REG_INT_STAT, MY_INTERRUPTS);
@@ -741,13 +769,73 @@
 	return 0;
 }
 
+#define BT_DEVICE(chip, subvend, subdev, rate) \
+	{ .vendor = PCI_VENDOR_ID_BROOKTREE, \
+	  .device = PCI_DEVICE_ID_BROOKTREE_##chip, \
+	  .subvendor = subvend, .subdevice = subdev, \
+	  .driver_data = rate }
+
+/* driver_data is the default digital_rate value for that device */
+static struct pci_device_id snd_bt87x_ids[] = {
+	BT_DEVICE(878, 0x0070, 0x13eb, 32000), /* Hauppauge WinTV series */
+	BT_DEVICE(879, 0x0070, 0x13eb, 32000), /* Hauppauge WinTV series */
+	BT_DEVICE(878, 0x0070, 0xff01, 44100), /* Viewcast Osprey 200 */
+	{ }
+};
+MODULE_DEVICE_TABLE(pci, snd_bt87x_ids);
+
+/* cards known not to have audio
+ * (DVB cards use the audio function to transfer MPEG data) */
+static struct {
+	unsigned short subvendor, subdevice;
+} blacklist[] __devinitdata = {
+	{0x0071, 0x0101}, /* Nebula Electronics DigiTV */
+	{0x11bd, 0x0026}, /* Pinnacle PCTV SAT CI */
+	{0x1461, 0x0761}, /* AVermedia AverTV DVB-T */
+	{0x1461, 0x0771}, /* AVermedia DVB-T 771 */
+	{0x1822, 0x0001}, /* Twinhan VisionPlus DVB-T */
+	{0x18ac, 0xdb10}, /* DVICO FusionHDTV DVB-T Lite */
+	{0x270f, 0xfc00}, /* Chaintech Digitop DST-1000 DVB-S */
+};
+
+/* 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);
+	if (supported)
+		return supported->driver_data;
+
+	for (i = 0; i < ARRAY_SIZE(blacklist); ++i)
+		if (blacklist[i].subvendor == pci->subsystem_vendor &&
+		    blacklist[i].subdevice == pci->subsystem_device) {
+			snd_printdd(KERN_INFO "card %#04x:%#04x has no audio\n",
+				    pci->subsystem_vendor, pci->subsystem_device);
+			return -EBUSY;
+		}
+
+	snd_printk(KERN_INFO "unknown card %#04x:%#04x, using default rate 32000\n",
+		   pci->subsystem_vendor, pci->subsystem_device);
+	snd_printk(KERN_DEBUG "please mail id, board name, and, "
+		   "if it works, the correct digital_rate option to "
+		   "<alsa-devel@lists.sf.net>\n");
+	return 32000; /* default rate */
+}
+
 static int __devinit snd_bt87x_probe(struct pci_dev *pci,
 				     const struct pci_device_id *pci_id)
 {
 	static int dev;
 	snd_card_t *card;
 	bt87x_t *chip;
-	int err;
+	int err, rate;
+
+	rate = pci_id->driver_data;
+	if (! rate)
+		if ((rate = snd_bt87x_detect_card(pci)) <= 0)
+			return -ENODEV;
 
 	if (dev >= SNDRV_CARDS)
 		return -ENODEV;
@@ -767,7 +855,7 @@
 	if (digital_rate[dev] > 0)
 		chip->dig_rate = digital_rate[dev];
 	else
-		chip->dig_rate = (int)pci_id->driver_data;
+		chip->dig_rate = rate;
 
 	err = snd_bt87x_pcm(chip, DEVICE_DIGITAL, "Bt87x Digital");
 	if (err < 0)
@@ -811,22 +899,13 @@
 	pci_set_drvdata(pci, NULL);
 }
 
-#define BT_DEVICE(chip, subvend, subdev, rate) \
-	{ .vendor = PCI_VENDOR_ID_BROOKTREE, \
-	  .device = PCI_DEVICE_ID_BROOKTREE_##chip, \
-	  .subvendor = subvend, .subdevice = subdev, \
-	  .driver_data = rate }
-
-/* driver_data is the default digital_rate value for that device */
-static struct pci_device_id snd_bt87x_ids[] = {
-	BT_DEVICE(878, 0x0070, 0xff01, 44100), /* Osprey 200 */
-
-	/* default entries for 32kHz and generic Bt87x cards */
-	BT_DEVICE(878, PCI_ANY_ID, PCI_ANY_ID, 32000),
-	BT_DEVICE(879, PCI_ANY_ID, PCI_ANY_ID, 32000),
+/* default entries for all Bt87x cards - it's not exported */
+/* driver_data is set to 0 to call detection */
+static struct pci_device_id snd_bt87x_default_ids[] = {
+	BT_DEVICE(878, PCI_ANY_ID, PCI_ANY_ID, 0),
+	BT_DEVICE(879, PCI_ANY_ID, PCI_ANY_ID, 0),
 	{ }
 };
-MODULE_DEVICE_TABLE(pci, snd_bt87x_ids);
 
 static struct pci_driver driver = {
 	.name = "Bt87x",
@@ -837,6 +916,8 @@
 
 static int __init alsa_card_bt87x_init(void)
 {
+	if (load_all)
+		driver.id_table = snd_bt87x_default_ids;
 	return pci_module_init(&driver);
 }
 
diff -Nru a/sound/pci/ca0106/Makefile b/sound/pci/ca0106/Makefile
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/sound/pci/ca0106/Makefile	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,3 @@
+snd-ca0106-objs := ca0106_main.o ca0106_proc.o ca0106_mixer.o
+
+obj-$(CONFIG_SND_CA0106) += snd-ca0106.o
diff -Nru a/sound/pci/ca0106/ca0106.h b/sound/pci/ca0106/ca0106.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/sound/pci/ca0106/ca0106.h	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,549 @@
+/*
+ *  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
+ *
+ *  FEATURES currently supported:
+ *    See ca0106_main.c for features.
+ * 
+ *  Changelog:
+ *    Support interrupts per period.
+ *    Removed noise from Center/LFE channel when in Analog mode.
+ *    Rename and remove mixer controls.
+ *  0.0.6
+ *    Use separate card based DMA buffer for periods table list.
+ *  0.0.7
+ *    Change remove and rename ctrls into lists.
+ *  0.0.8
+ *    Try to fix capture sources.
+ *  0.0.9
+ *    Fix AC3 output.
+ *    Enable S32_LE format support.
+ *  0.0.10
+ *    Enable playback 48000 and 96000 rates. (Rates other that these do not work, even with "plug:front".)
+ *  0.0.11
+ *    Add Model name recognition.
+ *  0.0.12
+ *    Correct interrupt timing. interrupt at end of period, instead of in the middle of a playback period.
+ *    Remove redundent "voice" handling.
+ *  0.0.13
+ *    Single trigger call for multi channels.
+ *  0.0.14
+ *    Set limits based on what the sound card hardware can do.
+ *    playback periods_min=2, periods_max=8
+ *    capture hw constraints require period_size = n * 64 bytes.
+ *    playback hw constraints require period_size = n * 64 bytes.
+ *  0.0.15
+ *    Separated ca0106.c into separate functional .c files.
+ *  0.0.16
+ *    Implement 192000 sample rate.
+ *  0.0.17
+ *    Add support for SB0410 and SB0413.
+ *  0.0.18
+ *    Modified Copyright message.
+ *  0.0.19
+ *    Added I2C and SPI registers. Filled in interrupt enable.
+ *  0.0.20
+ *    Added GPIO info for 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>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You 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
+ *
+ */
+
+/************************************************************************************************/
+/* PCI function 0 registers, address = <val> + PCIBASE0						*/
+/************************************************************************************************/
+
+#define PTR			0x00		/* Indexed register set pointer register	*/
+						/* NOTE: The CHANNELNUM and ADDRESS words can	*/
+						/* be modified independently of each other.	*/
+						/* CNL[1:0], ADDR[27:16]                        */
+
+#define DATA			0x04		/* Indexed register set data register		*/
+						/* DATA[31:0]					*/
+
+#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_MIDI_RX_B		0x00020000	/* MIDI UART-B Receive buffer non-empty		*/
+#define IPR_MIDI_TX_B		0x00010000	/* MIDI UART-B Transmit buffer empty		*/
+#define IPR_SPDIF_IN_USER	0x00004000      /* SPDIF input user data has 16 more bits	*/
+#define IPR_SPDIF_OUT_USER	0x00002000      /* SPDIF output user data needs 16 more bits	*/
+#define IPR_SPDIF_OUT_FRAME	0x00001000      /* SPDIF frame about to start			*/
+#define IPR_SPI			0x00000800      /* SPI transaction completed			*/
+#define IPR_I2C_EEPROM		0x00000400      /* I2C EEPROM transaction completed		*/
+#define IPR_I2C_DAC		0x00000200      /* I2C DAC transaction completed		*/
+#define IPR_AI			0x00000100      /* Audio pending register changed. See PTR reg 0x76	*/
+#define IPR_GPI			0x00000080      /* General Purpose input changed		*/
+#define IPR_SRC_LOCKED          0x00000040      /* SRC lock status changed			*/
+#define IPR_SPDIF_STATUS        0x00000020      /* SPDIF status changed				*/
+#define IPR_TIMER2              0x00000010      /* 192000Hz Timer				*/
+#define IPR_TIMER1              0x00000008      /* 44100Hz Timer				*/
+#define IPR_MIDI_RX_A		0x00000004	/* MIDI UART-A Receive buffer non-empty		*/
+#define IPR_MIDI_TX_A		0x00000002	/* MIDI UART-A Transmit buffer empty		*/
+#define IPR_PCI			0x00000001	/* PCI Bus error				*/
+
+#define INTE			0x0c		/* Interrupt enable register			*/
+
+#define INTE_MIDI_RX_B		0x00020000	/* MIDI UART-B Receive buffer non-empty		*/
+#define INTE_MIDI_TX_B		0x00010000	/* MIDI UART-B Transmit buffer empty		*/
+#define INTE_SPDIF_IN_USER	0x00004000      /* SPDIF input user data has 16 more bits	*/
+#define INTE_SPDIF_OUT_USER	0x00002000      /* SPDIF output user data needs 16 more bits	*/
+#define INTE_SPDIF_OUT_FRAME	0x00001000      /* SPDIF frame about to start			*/
+#define INTE_SPI		0x00000800      /* SPI transaction completed			*/
+#define INTE_I2C_EEPROM		0x00000400      /* I2C EEPROM transaction completed		*/
+#define INTE_I2C_DAC		0x00000200      /* I2C DAC transaction completed		*/
+#define INTE_AI			0x00000100      /* Audio pending register changed. See PTR reg 0x75 */
+#define INTE_GPI		0x00000080      /* General Purpose input changed		*/
+#define INTE_SRC_LOCKED         0x00000040      /* SRC lock status changed			*/
+#define INTE_SPDIF_STATUS       0x00000020      /* SPDIF status changed				*/
+#define INTE_TIMER2             0x00000010      /* 192000Hz Timer				*/
+#define INTE_TIMER1             0x00000008      /* 44100Hz Timer				*/
+#define INTE_MIDI_RX_A		0x00000004	/* MIDI UART-A Receive buffer non-empty		*/
+#define INTE_MIDI_TX_A		0x00000002	/* MIDI UART-A Transmit buffer empty		*/
+#define INTE_PCI		0x00000001	/* PCI Bus error				*/
+
+#define UNKNOWN10		0x10		/* Unknown ??. Defaults to 0 */
+#define HCFG			0x14		/* Hardware config register			*/
+						/* 0x1000 causes AC3 to fails. It adds a dither bit. */
+
+#define HCFG_STAC		0x10000000	/* Special mode for STAC9460 Codec. */
+#define HCFG_CAPTURE_I2S_BYPASS	0x08000000	/* 1 = bypass I2S input async SRC. */
+#define HCFG_CAPTURE_SPDIF_BYPASS 0x04000000	/* 1 = bypass SPDIF input async SRC. */
+#define HCFG_PLAYBACK_I2S_BYPASS 0x02000000	/* 0 = I2S IN mixer output, 1 = I2S IN1. */
+#define HCFG_FORCE_LOCK		0x01000000	/* For test only. Force input SRC tracker to lock. */
+#define HCFG_PLAYBACK_ATTENUATION 0x00006000	/* Playback attenuation mask. 0 = 0dB, 1 = 6dB, 2 = 12dB, 3 = Mute. */
+#define HCFG_PLAYBACK_DITHER	0x00001000	/* 1 = Add dither bit to all playback channels. */
+#define HCFG_PLAYBACK_S32_LE	0x00000800	/* 1 = S32_LE, 0 = S16_LE                       */
+#define HCFG_CAPTURE_S32_LE	0x00000400	/* 1 = S32_LE, 0 = S16_LE (S32_LE current not working)	*/
+#define HCFG_8_CHANNEL_PLAY	0x00000200	/* 1 = 8 channels, 0 = 2 channels per substream.*/
+#define HCFG_8_CHANNEL_CAPTURE	0x00000100	/* 1 = 8 channels, 0 = 2 channels per substream.*/
+#define HCFG_MONO		0x00000080	/* 1 = I2S Input mono                           */
+#define HCFG_I2S_OUTPUT		0x00000010	/* 1 = I2S Output disabled                      */
+#define HCFG_AC97		0x00000008	/* 0 = AC97 1.0, 1 = AC97 2.0                   */
+#define HCFG_LOCK_PLAYBACK_CACHE 0x00000004	/* 1 = Cancel bustmaster accesses to soundcache */
+						/* NOTE: This should generally never be used.  	*/
+#define HCFG_LOCK_CAPTURE_CACHE	0x00000002	/* 1 = Cancel bustmaster accesses to soundcache */
+						/* NOTE: This should generally never be used.  	*/
+#define HCFG_AUDIOENABLE	0x00000001	/* 0 = CODECs transmit zero-valued samples	*/
+						/* Should be set to 1 when the EMU10K1 is	*/
+						/* completely initialized.			*/
+#define GPIO			0x18		/* Defaults: 005f03a3-Analog, 005f02a2-SPDIF.   */
+						/* Here pins 0,1,2,3,4,,6 are output. 5,7 are input */
+						/* For the Audigy LS, pin 0 (or bit 8) controls the SPDIF/Analog jack. */
+						/* SB Live 24bit:
+						 * bit 8 0 = SPDIF in and out / 1 = Analog (Mic or Line)-in.
+						 * bit 9 0 = Mute / 1 = Analog out.
+						 * bit 10 0 = Line-in / 1 = Mic-in.
+						 * bit 11 0 = ? / 1 = ?
+						 * bit 12 0 = ? / 1 = ?
+						 * bit 13 0 = ? / 1 = ?
+						 * bit 14 0 = Mute / 1 = Analog out
+						 * bit 15 0 = ? / 1 = ?
+						 * Both bit 9 and bit 14 have to be set for analog sound to work on the SB Live 24bit.
+						 */
+						/* 8 general purpose programmable In/Out pins.
+						 * GPI [8:0] Read only. Default 0.
+						 * GPO [15:8] Default 0x9. (Default to SPDIF jack enabled for SPDIF)
+						 * GPO Enable [23:16] Default 0x0f. Setting a bit to 1, causes the pin to be an output pin.
+						 */
+#define AC97DATA		0x1c		/* AC97 register set data register (16 bit)	*/
+
+#define AC97ADDRESS		0x1e		/* AC97 register set address register (8 bit)	*/
+
+/********************************************************************************************************/
+/* CA0106 pointer-offset register set, accessed through the PTR and DATA registers                     */
+/********************************************************************************************************/
+                                                                                                                           
+/* Initally all registers from 0x00 to 0x3f have zero contents. */
+#define PLAYBACK_LIST_ADDR	0x00		/* Base DMA address of a list of pointers to each period/size */
+						/* One list entry: 4 bytes for DMA address, 
+						 * 4 bytes for period_size << 16.
+						 * One list entry is 8 bytes long.
+						 * One list entry for each period in the buffer.
+						 */
+						/* ADDR[31:0], Default: 0x0 */
+#define PLAYBACK_LIST_SIZE	0x01		/* Size of list in bytes << 16. E.g. 8 periods -> 0x00380000  */
+						/* SIZE[21:16], Default: 0x8 */
+#define PLAYBACK_LIST_PTR	0x02		/* Pointer to the current period being played */
+						/* PTR[5:0], Default: 0x0 */
+#define PLAYBACK_UNKNOWN3	0x03		/* Not used ?? */
+#define PLAYBACK_DMA_ADDR	0x04		/* Playback DMA addresss */
+						/* DMA[31:0], Default: 0x0 */
+#define PLAYBACK_PERIOD_SIZE	0x05		/* Playback period size. win2000 uses 0x04000000 */
+						/* SIZE[31:16], Default: 0x0 */
+#define PLAYBACK_POINTER	0x06		/* Playback period pointer. Used with PLAYBACK_LIST_PTR to determine buffer position currently in DAC */
+						/* POINTER[15:0], Default: 0x0 */
+#define PLAYBACK_PERIOD_END_ADDR 0x07		/* Playback fifo end address */
+						/* END_ADDR[15:0], FLAG[16] 0 = don't stop, 1 = stop */
+#define PLAYBACK_FIFO_OFFSET_ADDRESS	0x08	/* Current fifo offset address [21:16] */
+						/* Cache size valid [5:0] */
+#define PLAYBACK_UNKNOWN9	0x09		/* 0x9 to 0xf Unused */
+#define CAPTURE_DMA_ADDR	0x10		/* Capture DMA address */
+						/* DMA[31:0], Default: 0x0 */
+#define CAPTURE_BUFFER_SIZE	0x11		/* Capture buffer size */
+						/* SIZE[31:16], Default: 0x0 */
+#define CAPTURE_POINTER		0x12		/* Capture buffer pointer. Sample currently in ADC */
+						/* POINTER[15:0], Default: 0x0 */
+#define CAPTURE_FIFO_OFFSET_ADDRESS	0x13	/* Current fifo offset address [21:16] */
+						/* Cache size valid [5:0] */
+#define PLAYBACK_LAST_SAMPLE    0x20		/* The sample currently being played */
+/* 0x21 - 0x3f unused */
+#define BASIC_INTERRUPT         0x40		/* Used by both playback and capture interrupt handler */
+						/* Playback (0x1<<channel_id) */
+						/* Capture  (0x100<<channel_id) */
+						/* Playback sample rate 96000 = 0x20000 */
+						/* Start Playback [3:0] (one bit per channel)
+						 * Start Capture [11:8] (one bit per channel)
+						 * Playback rate [23:16] (2 bits per channel) (0=48kHz, 1=44.1kHz, 2=96kHz, 3=192Khz)
+						 * Playback mixer in enable [27:24] (one bit per channel)
+						 * Playback mixer out enable [31:28] (one bit per channel)
+						 */
+/* The Digital out jack is shared with the Center/LFE Analogue output. 
+ * The jack has 4 poles. I will call 1 - Tip, 2 - Next to 1, 3 - Next to 2, 4 - Next to 3
+ * For Analogue: 1 -> Center Speaker, 2 -> Sub Woofer, 3 -> Ground, 4 -> Ground
+ * For Digital: 1 -> Front SPDIF, 2 -> Rear SPDIF, 3 -> Center/Subwoofer SPDIF, 4 -> Ground.
+ * Standard 4 pole Video A/V cable with RCA outputs: 1 -> White, 2 -> Yellow, 3 -> Sheild on all three, 4 -> Red.
+ * So, from this you can see that you cannot use a Standard 4 pole Video A/V cable with the SB Audigy LS card.
+ */
+/* The Front SPDIF PCM gets mixed with samples from the AC97 codec, so can only work for Stereo PCM and not AC3/DTS
+ * The Rear SPDIF can be used for Stereo PCM and also AC3/DTS
+ * The Center/LFE SPDIF cannot be used for AC3/DTS, but can be used for Stereo PCM.
+ * Summary: For ALSA we use the Rear channel for SPDIF Digital AC3/DTS output
+ */
+/* A standard 2 pole mono mini-jack to RCA plug can be used for SPDIF Stereo PCM output from the Front channel.
+ * A standard 3 pole stereo mini-jack to 2 RCA plugs can be used for SPDIF AC3/DTS and Stereo PCM output utilising the Rear channel and just one of the RCA plugs. 
+ */
+#define SPCS0			0x41		/* SPDIF output Channel Status 0 register. For Rear. default=0x02108004, non-audio=0x02108006	*/
+#define SPCS1			0x42		/* SPDIF output Channel Status 1 register. For Front */
+#define SPCS2			0x43		/* SPDIF output Channel Status 2 register. For Center/LFE */
+#define SPCS3			0x44		/* SPDIF output Channel Status 3 register. Unknown */
+						/* When Channel set to 0: */
+#define SPCS_CLKACCYMASK	0x30000000	/* Clock accuracy				*/
+#define SPCS_CLKACCY_1000PPM	0x00000000	/* 1000 parts per million			*/
+#define SPCS_CLKACCY_50PPM	0x10000000	/* 50 parts per million				*/
+#define SPCS_CLKACCY_VARIABLE	0x20000000	/* Variable accuracy				*/
+#define SPCS_SAMPLERATEMASK	0x0f000000	/* Sample rate					*/
+#define SPCS_SAMPLERATE_44	0x00000000	/* 44.1kHz sample rate				*/
+#define SPCS_SAMPLERATE_48	0x02000000	/* 48kHz sample rate				*/
+#define SPCS_SAMPLERATE_32	0x03000000	/* 32kHz sample rate				*/
+#define SPCS_CHANNELNUMMASK	0x00f00000	/* Channel number				*/
+#define SPCS_CHANNELNUM_UNSPEC	0x00000000	/* Unspecified channel number			*/
+#define SPCS_CHANNELNUM_LEFT	0x00100000	/* Left channel					*/
+#define SPCS_CHANNELNUM_RIGHT	0x00200000	/* Right channel				*/
+#define SPCS_SOURCENUMMASK	0x000f0000	/* Source number				*/
+#define SPCS_SOURCENUM_UNSPEC	0x00000000	/* Unspecified source number			*/
+#define SPCS_GENERATIONSTATUS	0x00008000	/* Originality flag (see IEC-958 spec)		*/
+#define SPCS_CATEGORYCODEMASK	0x00007f00	/* Category code (see IEC-958 spec)		*/
+#define SPCS_MODEMASK		0x000000c0	/* Mode (see IEC-958 spec)			*/
+#define SPCS_EMPHASISMASK	0x00000038	/* Emphasis					*/
+#define SPCS_EMPHASIS_NONE	0x00000000	/* No emphasis					*/
+#define SPCS_EMPHASIS_50_15	0x00000008	/* 50/15 usec 2 channel				*/
+#define SPCS_COPYRIGHT		0x00000004	/* Copyright asserted flag -- do not modify	*/
+#define SPCS_NOTAUDIODATA	0x00000002	/* 0 = Digital audio, 1 = not audio		*/
+#define SPCS_PROFESSIONAL	0x00000001	/* 0 = Consumer (IEC-958), 1 = pro (AES3-1992)	*/
+
+						/* When Channel set to 1: */
+#define SPCS_WORD_LENGTH_MASK	0x0000000f	/* Word Length Mask				*/
+#define SPCS_WORD_LENGTH_16	0x00000008	/* Word Length 16 bit				*/
+#define SPCS_WORD_LENGTH_17	0x00000006	/* Word Length 17 bit				*/
+#define SPCS_WORD_LENGTH_18	0x00000004	/* Word Length 18 bit				*/
+#define SPCS_WORD_LENGTH_19	0x00000002	/* Word Length 19 bit				*/
+#define SPCS_WORD_LENGTH_20A	0x0000000a	/* Word Length 20 bit				*/
+#define SPCS_WORD_LENGTH_20	0x00000009	/* Word Length 20 bit (both 0xa and 0x9 are 20 bit) */
+#define SPCS_WORD_LENGTH_21	0x00000007	/* Word Length 21 bit				*/
+#define SPCS_WORD_LENGTH_21	0x00000007	/* Word Length 21 bit				*/
+#define SPCS_WORD_LENGTH_22	0x00000005	/* Word Length 22 bit				*/
+#define SPCS_WORD_LENGTH_23	0x00000003	/* Word Length 23 bit				*/
+#define SPCS_WORD_LENGTH_24	0x0000000b	/* Word Length 24 bit				*/
+#define SPCS_ORIGINAL_SAMPLE_RATE_MASK	0x000000f0 /* Original Sample rate			*/
+#define SPCS_ORIGINAL_SAMPLE_RATE_NONE	0x00000000 /* Original Sample rate not indicated	*/
+#define SPCS_ORIGINAL_SAMPLE_RATE_16000	0x00000010 /* Original Sample rate	*/
+#define SPCS_ORIGINAL_SAMPLE_RATE_RES1	0x00000020 /* Original Sample rate	*/
+#define SPCS_ORIGINAL_SAMPLE_RATE_32000	0x00000030 /* Original Sample rate	*/
+#define SPCS_ORIGINAL_SAMPLE_RATE_12000	0x00000040 /* Original Sample rate	*/
+#define SPCS_ORIGINAL_SAMPLE_RATE_11025	0x00000050 /* Original Sample rate	*/
+#define SPCS_ORIGINAL_SAMPLE_RATE_8000	0x00000060 /* Original Sample rate	*/
+#define SPCS_ORIGINAL_SAMPLE_RATE_RES2	0x00000070 /* Original Sample rate	*/
+#define SPCS_ORIGINAL_SAMPLE_RATE_192000 0x00000080 /* Original Sample rate	*/
+#define SPCS_ORIGINAL_SAMPLE_RATE_24000	0x00000090 /* Original Sample rate	*/
+#define SPCS_ORIGINAL_SAMPLE_RATE_96000	0x000000a0 /* Original Sample rate	*/
+#define SPCS_ORIGINAL_SAMPLE_RATE_48000	0x000000b0 /* Original Sample rate	*/
+#define SPCS_ORIGINAL_SAMPLE_RATE_176400 0x000000c0 /* Original Sample rate	*/
+#define SPCS_ORIGINAL_SAMPLE_RATE_22050	0x000000d0 /* Original Sample rate	*/
+#define SPCS_ORIGINAL_SAMPLE_RATE_88200	0x000000e0 /* Original Sample rate	*/
+#define SPCS_ORIGINAL_SAMPLE_RATE_44100	0x000000f0 /* Original Sample rate	*/
+
+#define SPDIF_SELECT1		0x45		/* Enables SPDIF or Analogue outputs 0-SPDIF, 0xf00-Analogue */
+						/* 0x100 - Front, 0x800 - Rear, 0x200 - Center/LFE.
+						 * But as the jack is shared, use 0xf00.
+						 * The Windows2000 driver uses 0x0000000f for both digital and analog.
+						 * 0xf00 introduces interesting noises onto the Center/LFE.
+						 * If you turn the volume up, you hear computer noise,
+						 * e.g. mouse moving, changing between app windows etc.
+						 * So, I am going to set this to 0x0000000f all the time now,
+						 * same as the windows driver does.
+						 * Use register SPDIF_SELECT2(0x72) to switch between SPDIF and Analog.
+						 */
+						/* When Channel = 0:
+						 * Wide SPDIF format [3:0] (one bit for each channel) (0=20bit, 1=24bit)
+						 * Tristate SPDIF Output [11:8] (one bit for each channel) (0=Not tristate, 1=Tristate)
+						 * SPDIF Bypass enable [19:16] (one bit for each channel) (0=Not bypass, 1=Bypass)
+						 */
+						/* When Channel = 1:
+						 * SPDIF 0 User data [7:0]
+						 * SPDIF 1 User data [15:8]
+						 * SPDIF 0 User data [23:16]
+						 * SPDIF 0 User data [31:24]
+						 * User data can be sent by using the SPDIF output frame pending and SPDIF output user bit interrupts.
+						 */
+#define WATERMARK		0x46		/* Test bit to indicate cache usage level */
+#define SPDIF_INPUT_STATUS	0x49		/* SPDIF Input status register. Bits the same as SPCS.
+						 * When Channel = 0: Bits the same as SPCS channel 0.
+						 * When Channel = 1: Bits the same as SPCS channel 1.
+						 * When Channel = 2:
+						 * SPDIF Input User data [16:0]
+						 * SPDIF Input Frame count [21:16]
+						 */
+#define CAPTURE_CACHE_DATA	0x50		/* 0x50-0x5f Recorded samples. */
+#define CAPTURE_SOURCE          0x60            /* Capture Source 0 = MIC */
+#define CAPTURE_SOURCE_CHANNEL0 0xf0000000	/* Mask for selecting the Capture sources */
+#define CAPTURE_SOURCE_CHANNEL1 0x0f000000	/* 0 - SPDIF mixer output. */
+#define CAPTURE_SOURCE_CHANNEL2 0x00f00000      /* 1 - What you hear or . 2 - ?? */
+#define CAPTURE_SOURCE_CHANNEL3 0x000f0000	/* 3 - Mic in, Line in, TAD in, Aux in. */
+#define CAPTURE_SOURCE_RECORD_MAP 0x0000ffff	/* Default 0x00e4 */
+						/* Record Map [7:0] (2 bits per channel) 0=mapped to channel 0, 1=mapped to channel 1, 2=mapped to channel2, 3=mapped to channel3 
+						 * Record source select for channel 0 [18:16]
+						 * Record source select for channel 1 [22:20]
+						 * Record source select for channel 2 [26:24]
+						 * Record source select for channel 3 [30:28]
+						 * 0 - SPDIF mixer output.
+						 * 1 - i2s mixer output.
+						 * 2 - SPDIF input.
+						 * 3 - i2s input.
+						 * 4 - AC97 capture.
+						 * 5 - SRC output.
+						 */
+#define CAPTURE_VOLUME1         0x61            /* Capture  volume per channel 0-3 */
+#define CAPTURE_VOLUME2         0x62            /* Capture  volume per channel 4-7 */
+
+#define PLAYBACK_ROUTING1       0x63            /* Playback routing of channels 0-7. Effects AC3 output. Default 0x32765410 */
+#define ROUTING1_REAR           0x77000000      /* Channel_id 0 sends to 10, Channel_id 1 sends to 32 */
+#define ROUTING1_NULL           0x00770000      /* Channel_id 2 sends to 54, Channel_id 3 sends to 76 */
+#define ROUTING1_CENTER_LFE     0x00007700      /* 0x32765410 means, send Channel_id 0 to FRONT, Channel_id 1 to REAR */
+#define ROUTING1_FRONT          0x00000077	/* Channel_id 2 to CENTER_LFE, Channel_id 3 to NULL. */
+						/* Channel_id's handle stereo channels. Channel X is a single mono channel */
+						/* Host is input from the PCI bus. */
+						/* Host channel 0 [2:0] -> SPDIF Mixer/Router channel 0-7.
+						 * Host channel 1 [6:4] -> SPDIF Mixer/Router channel 0-7.
+						 * Host channel 2 [10:8] -> SPDIF Mixer/Router channel 0-7.
+						 * Host channel 3 [14:12] -> SPDIF Mixer/Router channel 0-7.
+						 * Host channel 4 [18:16] -> SPDIF Mixer/Router channel 0-7.
+						 * Host channel 5 [22:20] -> SPDIF Mixer/Router channel 0-7.
+						 * Host channel 6 [26:24] -> SPDIF Mixer/Router channel 0-7.
+						 * Host channel 7 [30:28] -> SPDIF Mixer/Router channel 0-7.
+						 */
+
+#define PLAYBACK_ROUTING2       0x64            /* Playback Routing . Feeding Capture channels back into Playback. Effects AC3 output. Default 0x76767676 */
+						/* SRC is input from the capture inputs. */
+						/* SRC channel 0 [2:0] -> SPDIF Mixer/Router channel 0-7.
+						 * SRC channel 1 [6:4] -> SPDIF Mixer/Router channel 0-7.
+						 * SRC channel 2 [10:8] -> SPDIF Mixer/Router channel 0-7.
+						 * SRC channel 3 [14:12] -> SPDIF Mixer/Router channel 0-7.
+						 * SRC channel 4 [18:16] -> SPDIF Mixer/Router channel 0-7.
+						 * SRC channel 5 [22:20] -> SPDIF Mixer/Router channel 0-7.
+						 * SRC channel 6 [26:24] -> SPDIF Mixer/Router channel 0-7.
+						 * SRC channel 7 [30:28] -> SPDIF Mixer/Router channel 0-7.
+						 */
+
+#define PLAYBACK_MUTE           0x65            /* Unknown. While playing 0x0, while silent 0x00fc0000 */
+						/* SPDIF Mixer input control:
+						 * Invert SRC to SPDIF Mixer [7-0] (One bit per channel)
+						 * Invert Host to SPDIF Mixer [15:8] (One bit per channel)
+						 * SRC to SPDIF Mixer disable [23:16] (One bit per channel)
+						 * Host to SPDIF Mixer disable [31:24] (One bit per channel)
+						 */
+#define PLAYBACK_VOLUME1        0x66            /* Playback SPDIF volume per channel. Set to the same PLAYBACK_VOLUME(0x6a) */
+						/* PLAYBACK_VOLUME1 must be set to 30303030 for SPDIF AC3 Playback */
+						/* SPDIF mixer input volume. 0=12dB, 0x30=0dB, 0xFE=-51.5dB, 0xff=Mute */
+						/* One register for each of the 4 stereo streams. */
+						/* SRC Right volume [7:0]
+						 * SRC Left  volume [15:8]
+						 * Host Right volume [23:16]
+						 * Host Left  volume [31:24]
+						 */
+#define CAPTURE_ROUTING1        0x67            /* Capture Routing. Default 0x32765410 */
+						/* Similar to register 0x63, except that the destination is the I2S mixer instead of the SPDIF mixer. I.E. Outputs to the Analog outputs instead of SPDIF. */
+#define CAPTURE_ROUTING2        0x68            /* Unknown Routing. Default 0x76767676 */
+						/* Similar to register 0x64, except that the destination is the I2S mixer instead of the SPDIF mixer. I.E. Outputs to the Analog outputs instead of SPDIF. */
+#define CAPTURE_MUTE            0x69            /* Unknown. While capturing 0x0, while silent 0x00fc0000 */
+						/* Similar to register 0x65, except that the destination is the I2S mixer instead of the SPDIF mixer. I.E. Outputs to the Analog outputs instead of SPDIF. */
+#define PLAYBACK_VOLUME2        0x6a            /* Playback Analog volume per channel. Does not effect AC3 output */
+						/* Similar to register 0x66, except that the destination is the I2S mixer instead of the SPDIF mixer. I.E. Outputs to the Analog outputs instead of SPDIF. */
+#define UNKNOWN6b               0x6b            /* Unknown. Readonly. Default 00400000 00400000 00400000 00400000 */
+#define UART_A_DATA		0x6c            /* Uart, used in setting sample rates, bits per sample etc. */
+#define UART_A_CMD		0x6d            /* Uart, used in setting sample rates, bits per sample etc. */
+#define UART_B_DATA		0x6e            /* Uart, Unknown. */
+#define UART_B_CMD		0x6f            /* Uart, Unknown. */
+#define SAMPLE_RATE_TRACKER_STATUS 0x70         /* Readonly. Default 00108000 00108000 00500000 00500000 */
+						/* Estimated sample rate [19:0] Relative to 48kHz. 0x8000 =  1.0
+						 * Rate Locked [20]
+						 * SPDIF Locked [21] For SPDIF channel only.
+						 * Valid Audio [22] For SPDIF channel only.
+						 */
+#define CAPTURE_CONTROL         0x71            /* Some sort of routing. default = 40c81000 30303030 30300000 00700000 */
+						/* Channel_id 0: 0x40c81000 must be changed to 0x40c80000 for SPDIF AC3 input or output. */
+						/* Channel_id 1: 0xffffffff(mute) 0x30303030(max) controls CAPTURE feedback into PLAYBACK. */
+						/* Sample rate output control register Channel=0
+						 * Sample output rate [1:0] (0=48kHz, 1=44.1kHz, 2=96kHz, 3=192Khz)
+						 * Sample input rate [3:2] (0=48kHz, 1=Not available, 2=96kHz, 3=192Khz)
+						 * SRC input source select [4] 0=Audio from digital mixer, 1=Audio from analog source.
+						 * Record rate [9:8] (0=48kHz, 1=Not available, 2=96kHz, 3=192Khz)
+						 * Record mixer output enable [12:10] 
+						 * I2S input rate master mode [15:14] (0=48kHz, 1=44.1kHz, 2=96kHz, 3=192Khz)
+						 * I2S output rate [17:16] (0=48kHz, 1=44.1kHz, 2=96kHz, 3=192Khz)
+						 * I2S output source select [18] (0=Audio from host, 1=Audio from SRC)
+						 * Record mixer I2S enable [20:19] (enable/disable i2sin1 and i2sin0)
+						 * I2S output master clock select [21] (0=256*I2S output rate, 1=512*I2S output rate.)
+						 * I2S input master clock select [22] (0=256*I2S input rate, 1=512*I2S input rate.)
+						 * I2S input mode [23] (0=Slave, 1=Master)
+						 * SPDIF output rate [25:24] (0=48kHz, 1=44.1kHz, 2=96kHz, 3=192Khz)
+						 * SPDIF output source select [26] (0=host, 1=SRC)
+						 * Not used [27]
+						 * Record Source 0 input [29:28] (0=SPDIF in, 1=I2S in, 2=AC97 Mic, 3=AC97 PCM)
+						 * Record Source 1 input [31:30] (0=SPDIF in, 1=I2S in, 2=AC97 Mic, 3=AC97 PCM)
+						 */ 
+						/* Sample rate output control register Channel=1
+						 * I2S Input 0 volume Right [7:0]
+						 * I2S Input 0 volume Left [15:8]
+						 * I2S Input 1 volume Right [23:16]
+						 * I2S Input 1 volume Left [31:24]
+						 */
+						/* Sample rate output control register Channel=2
+						 * SPDIF Input volume Right [23:16]
+						 * SPDIF Input volume Left [31:24]
+						 */
+						/* Sample rate output control register Channel=3
+						 * No used
+						 */
+#define SPDIF_SELECT2           0x72            /* Some sort of routing. Channel_id 0 only. default = 0x0f0f003f. Analog 0x000b0000, Digital 0x0b000000 */
+#define ROUTING2_FRONT_MASK     0x00010000      /* Enable for Front speakers. */
+#define ROUTING2_CENTER_LFE_MASK 0x00020000     /* Enable for Center/LFE speakers. */
+#define ROUTING2_REAR_MASK      0x00080000      /* Enable for Rear speakers. */
+						/* Audio output control
+						 * AC97 output enable [5:0]
+						 * I2S output enable [19:16]
+						 * SPDIF output enable [27:24]
+						 */ 
+#define UNKNOWN73               0x73            /* Unknown. Readonly. Default 0x0 */
+#define CHIP_VERSION            0x74            /* P17 Chip version. Channel_id 0 only. Default 00000071 */
+#define EXTENDED_INT_MASK       0x75            /* Used by both playback and capture interrupt handler */
+						/* Sets which Interrupts are enabled. */
+						/* 0x00000001 = Half period. Playback.
+						 * 0x00000010 = Full period. Playback.
+						 * 0x00000100 = Half buffer. Playback.
+						 * 0x00001000 = Full buffer. Playback.
+						 * 0x00010000 = Half buffer. Capture.
+						 * 0x00100000 = Full buffer. Capture.
+						 * Capture can only do 2 periods.
+						 * 0x01000000 = End audio. Playback.
+						 * 0x40000000 = Half buffer Playback,Caputre xrun.
+						 * 0x80000000 = Full buffer Playback,Caputre xrun.
+						 */
+#define EXTENDED_INT            0x76            /* Used by both playback and capture interrupt handler */
+						/* Shows which interrupts are active at the moment. */
+						/* Same bit layout as EXTENDED_INT_MASK */
+#define COUNTER77               0x77		/* Counter range 0 to 0x3fffff, 192000 counts per second. */
+#define COUNTER78               0x78		/* Counter range 0 to 0x3fffff, 44100 counts per second. */
+#define EXTENDED_INT_TIMER      0x79            /* Channel_id 0 only. Used by both playback and capture interrupt handler */
+						/* 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 SET_CHANNEL 0  /* Testing channel outputs 0=Front, 1=Center/LFE, 2=Unknown, 3=Rear */
+#define PCM_FRONT_CHANNEL 0
+#define PCM_REAR_CHANNEL 1
+#define PCM_CENTER_LFE_CHANNEL 2
+#define PCM_UNKNOWN_CHANNEL 3
+#define CONTROL_FRONT_CHANNEL 0
+#define CONTROL_REAR_CHANNEL 3
+#define CONTROL_CENTER_LFE_CHANNEL 1
+#define CONTROL_UNKNOWN_CHANNEL 2
+
+typedef struct snd_ca0106_channel ca0106_channel_t;
+typedef struct snd_ca0106 ca0106_t;
+typedef struct snd_ca0106_pcm ca0106_pcm_t;
+
+struct snd_ca0106_channel {
+	ca0106_t *emu;
+	int number;
+	int use;
+	void (*interrupt)(ca0106_t *emu, ca0106_channel_t *channel);
+	ca0106_pcm_t *epcm;
+};
+
+struct snd_ca0106_pcm {
+	ca0106_t *emu;
+	snd_pcm_substream_t *substream;
+        int channel_id;
+	unsigned short running;
+};
+
+// definition of the chip-specific record
+struct snd_ca0106 {
+	snd_card_t *card;
+	struct pci_dev *pci;
+
+	unsigned long port;
+	struct resource *res_port;
+	int irq;
+
+	unsigned int revision;		/* chip revision */
+	unsigned int serial;            /* serial number */
+	unsigned short model;		/* subsystem id */
+
+	spinlock_t emu_lock;
+
+	ac97_t *ac97;
+	snd_pcm_t *pcm;
+
+	ca0106_channel_t playback_channels[4];
+	ca0106_channel_t capture_channels[4];
+	u32 spdif_bits[4];             /* s/pdif out setup */
+	int spdif_enable;
+	int capture_source;
+
+	struct snd_dma_buffer buffer;
+};
+
+int __devinit snd_ca0106_mixer(ca0106_t *emu);
+int __devinit snd_ca0106_proc_init(ca0106_t * emu);
+
+unsigned int snd_ca0106_ptr_read(ca0106_t * emu, 
+					  unsigned int reg, 
+					  unsigned int chn);
+
+void snd_ca0106_ptr_write(ca0106_t *emu, 
+				   unsigned int reg, 
+				   unsigned int chn, 
+				   unsigned int data);
+
diff -Nru a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/sound/pci/ca0106/ca0106_main.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,1274 @@
+/*
+ *  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.21
+ *
+ *  FEATURES currently supported:
+ *    Front, Rear and Center/LFE.
+ *    Surround40 and Surround51.
+ *    Capture from MIC an LINE IN input.
+ *    SPDIF digital playback of PCM stereo and AC3/DTS works.
+ *    (One can use a standard mono mini-jack to one RCA plugs cable.
+ *     or one can use a standard stereo mini-jack to two RCA plugs cable.
+ *     Plug one of the RCA plugs into the Coax input of the external decoder/receiver.)
+ *    ( In theory one could output 3 different AC3 streams at once, to 3 different SPDIF outputs. )
+ *    Notes on how to capture sound:
+ *      The AC97 is used in the PLAYBACK direction.
+ *      The output from the AC97 chip, instead of reaching the speakers, is fed into the Philips 1361T ADC.
+ *      So, to record from the MIC, set the MIC Playback volume to max,
+ *      unmute the MIC and turn up the MASTER Playback volume.
+ *      So, to prevent feedback when capturing, minimise the "Capture feedback into Playback" volume.
+ *   
+ *    The only playback controls that currently do anything are: -
+ *    Analog Front
+ *    Analog Rear
+ *    Analog Center/LFE
+ *    SPDIF Front
+ *    SPDIF Rear
+ *    SPDIF Center/LFE
+ *   
+ *    For capture from Mic in or Line in.
+ *    Digital/Analog ( switch must be in Analog mode for CAPTURE. )
+ * 
+ *    CAPTURE feedback into PLAYBACK
+ * 
+ *  Changelog:
+ *    Support interrupts per period.
+ *    Removed noise from Center/LFE channel when in Analog mode.
+ *    Rename and remove mixer controls.
+ *  0.0.6
+ *    Use separate card based DMA buffer for periods table list.
+ *  0.0.7
+ *    Change remove and rename ctrls into lists.
+ *  0.0.8
+ *    Try to fix capture sources.
+ *  0.0.9
+ *    Fix AC3 output.
+ *    Enable S32_LE format support.
+ *  0.0.10
+ *    Enable playback 48000 and 96000 rates. (Rates other that these do not work, even with "plug:front".)
+ *  0.0.11
+ *    Add Model name recognition.
+ *  0.0.12
+ *    Correct interrupt timing. interrupt at end of period, instead of in the middle of a playback period.
+ *    Remove redundent "voice" handling.
+ *  0.0.13
+ *    Single trigger call for multi channels.
+ *  0.0.14
+ *    Set limits based on what the sound card hardware can do.
+ *    playback periods_min=2, periods_max=8
+ *    capture hw constraints require period_size = n * 64 bytes.
+ *    playback hw constraints require period_size = n * 64 bytes.
+ *  0.0.15
+ *    Minor updates.
+ *  0.0.16
+ *    Implement 192000 sample rate.
+ *  0.0.17
+ *    Add support for SB0410 and SB0413.
+ *  0.0.18
+ *    Modified Copyright message.
+ *  0.0.19
+ *    Finally fix support for SB Live 24 bit. SB0410 and SB0413.
+ *    The output codec needs resetting, otherwise all output is muted.
+ *  0.0.20
+ *    Merge "pci_disable_device(pci);" fixes.
+ *  0.0.21
+ *    Add 4 capture channels. (SPDIF only comes in on channel 0. )
+ *    Add SPDIF capture using optional digital I/O module for SB Live 24bit. (Analog capture does not yet work.)
+ *
+ *  BUGS:
+ *    Some stability problems when unloading the snd-ca0106 kernel module.
+ *    --
+ *
+ *  TODO:
+ *    4 Capture channels, only one implemented so far.
+ *    Other capture rates apart from 48khz not implemented.
+ *    MIDI
+ *    --
+ *  GENERAL INFO:
+ *    Model: SB0310
+ *    P17 Chip: CA0106-DAT
+ *    AC97 Codec: STAC 9721
+ *    ADC: Philips 1361T (Stereo 24bit)
+ *    DAC: WM8746EDS (6-channel, 24bit, 192Khz)
+ *
+ *  GENERAL INFO:
+ *    Model: SB0410
+ *    P17 Chip: CA0106-DAT
+ *    AC97 Codec: None
+ *    ADC: WM8775EDS (4 Channel)
+ *    DAC: CS4382 (114 dB, 24-Bit, 192 kHz, 8-Channel D/A Converter with DSD Support)
+ *    SPDIF Out control switches between Mic in and SPDIF out.
+ *    No sound out or mic input working yet.
+ * 
+ *  GENERAL INFO:
+ *    Model: SB0413
+ *    P17 Chip: CA0106-DAT
+ *    AC97 Codec: None.
+ *    ADC: Unknown
+ *    DAC: Unknown
+ *    Trying to handle it like the SB0410.
+ *
+ *  This code was initally based on code from ALSA's emu10k1x.c which is:
+ *  Copyright (c) by Francisco Moraes <fmoraes@nc.rr.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 <sound/driver.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/moduleparam.h>
+#include <sound/core.h>
+#include <sound/initval.h>
+#include <sound/pcm.h>
+#include <sound/ac97_codec.h>
+#include <sound/info.h>
+
+MODULE_AUTHOR("James Courtier-Dutton <James@superbug.demon.co.uk>");
+MODULE_DESCRIPTION("CA0106");
+MODULE_LICENSE("GPL");
+MODULE_SUPPORTED_DEVICE("{{Creative,SB CA0106 chip}}");
+
+// module parameters (see "Module Parameters")
+static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
+static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
+static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
+
+module_param_array(index, int, NULL, 0444);
+MODULE_PARM_DESC(index, "Index value for the CA0106 soundcard.");
+module_param_array(id, charp, NULL, 0444);
+MODULE_PARM_DESC(id, "ID string for the CA0106 soundcard.");
+module_param_array(enable, bool, NULL, 0444);
+MODULE_PARM_DESC(enable, "Enable the CA0106 soundcard.");
+
+#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.  */
+	 { 0, "AudigyLS [Unknown]" }
+};
+
+/* hardware definition */
+static snd_pcm_hardware_t snd_ca0106_playback_hw = {
+	.info =			(SNDRV_PCM_INFO_MMAP | 
+				 SNDRV_PCM_INFO_INTERLEAVED |
+				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
+				 SNDRV_PCM_INFO_MMAP_VALID),
+	.formats =		SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
+	.rates =		SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000,
+	.rate_min =		48000,
+	.rate_max =		192000,
+	.channels_min =		2,  //1,
+	.channels_max =		2,  //6,
+	.buffer_bytes_max =	(32*1024),
+	.period_bytes_min =	64,
+	.period_bytes_max =	(16*1024),
+	.periods_min =		2,
+	.periods_max =		8,
+	.fifo_size =		0,
+};
+
+static snd_pcm_hardware_t snd_ca0106_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_S16_LE,
+	.rates =		SNDRV_PCM_RATE_48000,
+	.rate_min =		48000,
+	.rate_max =		48000,
+	.channels_min =		2,
+	.channels_max =		2,
+	.buffer_bytes_max =	(32*1024),
+	.period_bytes_min =	64,
+	.period_bytes_max =	(16*1024),
+	.periods_min =		2,
+	.periods_max =		2,
+	.fifo_size =		0,
+};
+
+unsigned int snd_ca0106_ptr_read(ca0106_t * emu, 
+					  unsigned int reg, 
+					  unsigned int chn)
+{
+	unsigned long flags;
+	unsigned int regptr, val;
+  
+	regptr = (reg << 16) | chn;
+
+	spin_lock_irqsave(&emu->emu_lock, flags);
+	outl(regptr, emu->port + PTR);
+	val = inl(emu->port + DATA);
+	spin_unlock_irqrestore(&emu->emu_lock, flags);
+	return val;
+}
+
+void snd_ca0106_ptr_write(ca0106_t *emu, 
+				   unsigned int reg, 
+				   unsigned int chn, 
+				   unsigned int data)
+{
+	unsigned int regptr;
+	unsigned long flags;
+
+	regptr = (reg << 16) | chn;
+
+	spin_lock_irqsave(&emu->emu_lock, flags);
+	outl(regptr, emu->port + PTR);
+	outl(data, emu->port + DATA);
+	spin_unlock_irqrestore(&emu->emu_lock, flags);
+}
+
+static void snd_ca0106_intr_enable(ca0106_t *emu, unsigned int intrenb)
+{
+	unsigned long flags;
+	unsigned int enable;
+  
+	spin_lock_irqsave(&emu->emu_lock, flags);
+	enable = inl(emu->port + INTE) | intrenb;
+	outl(enable, emu->port + INTE);
+	spin_unlock_irqrestore(&emu->emu_lock, flags);
+}
+
+static void snd_ca0106_pcm_free_substream(snd_pcm_runtime_t *runtime)
+{
+	ca0106_pcm_t *epcm = runtime->private_data;
+  
+	if (epcm) {
+		kfree(epcm);
+	}
+}
+
+/* open_playback callback */
+static int snd_ca0106_pcm_open_playback_channel(snd_pcm_substream_t *substream, int channel_id)
+{
+	ca0106_t *chip = snd_pcm_substream_chip(substream);
+        ca0106_channel_t *channel = &(chip->playback_channels[channel_id]);
+	ca0106_pcm_t *epcm;
+	snd_pcm_runtime_t *runtime = substream->runtime;
+	int err;
+
+	epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL);
+
+	if (epcm == NULL)
+		return -ENOMEM;
+	epcm->emu = chip;
+	epcm->substream = substream;
+        epcm->channel_id=channel_id;
+  
+	runtime->private_data = epcm;
+	runtime->private_free = snd_ca0106_pcm_free_substream;
+  
+	runtime->hw = snd_ca0106_playback_hw;
+
+        channel->emu = chip;
+        channel->number = channel_id;
+
+        channel->use=1;
+        //printk("open:channel_id=%d, chip=%p, channel=%p\n",channel_id, chip, channel);
+        //channel->interrupt = snd_ca0106_pcm_channel_interrupt;
+        channel->epcm=epcm;
+	if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
+                return err;
+	if ((err = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 64)) < 0)
+                return err;
+	return 0;
+}
+
+/* close callback */
+static int snd_ca0106_pcm_close_playback(snd_pcm_substream_t *substream)
+{
+	ca0106_t *chip = snd_pcm_substream_chip(substream);
+	snd_pcm_runtime_t *runtime = substream->runtime;
+        ca0106_pcm_t *epcm = runtime->private_data;
+        chip->playback_channels[epcm->channel_id].use=0;
+/* FIXME: maybe zero others */
+	return 0;
+}
+
+static int snd_ca0106_pcm_open_playback_front(snd_pcm_substream_t *substream)
+{
+	return snd_ca0106_pcm_open_playback_channel(substream, PCM_FRONT_CHANNEL);
+}
+
+static int snd_ca0106_pcm_open_playback_center_lfe(snd_pcm_substream_t *substream)
+{
+	return snd_ca0106_pcm_open_playback_channel(substream, PCM_CENTER_LFE_CHANNEL);
+}
+
+static int snd_ca0106_pcm_open_playback_unknown(snd_pcm_substream_t *substream)
+{
+	return snd_ca0106_pcm_open_playback_channel(substream, PCM_UNKNOWN_CHANNEL);
+}
+
+static int snd_ca0106_pcm_open_playback_rear(snd_pcm_substream_t *substream)
+{
+	return snd_ca0106_pcm_open_playback_channel(substream, PCM_REAR_CHANNEL);
+}
+
+/* open_capture callback */
+static int snd_ca0106_pcm_open_capture_channel(snd_pcm_substream_t *substream, int channel_id)
+{
+	ca0106_t *chip = snd_pcm_substream_chip(substream);
+        ca0106_channel_t *channel = &(chip->capture_channels[channel_id]);
+	ca0106_pcm_t *epcm;
+	snd_pcm_runtime_t *runtime = substream->runtime;
+	int err;
+
+	epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL);
+	if (epcm == NULL) {
+                snd_printk("open_capture_channel: failed epcm alloc\n");
+		return -ENOMEM;
+        }
+	epcm->emu = chip;
+	epcm->substream = substream;
+        epcm->channel_id=channel_id;
+  
+	runtime->private_data = epcm;
+	runtime->private_free = snd_ca0106_pcm_free_substream;
+  
+	runtime->hw = snd_ca0106_capture_hw;
+
+        channel->emu = chip;
+        channel->number = channel_id;
+
+        channel->use=1;
+        //printk("open:channel_id=%d, chip=%p, channel=%p\n",channel_id, chip, channel);
+        //channel->interrupt = snd_ca0106_pcm_channel_interrupt;
+        channel->epcm=epcm;
+	if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
+                return err;
+	//snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, &hw_constraints_capture_period_sizes);
+	if ((err = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 64)) < 0)
+                return err;
+	return 0;
+}
+
+/* close callback */
+static int snd_ca0106_pcm_close_capture(snd_pcm_substream_t *substream)
+{
+	ca0106_t *chip = snd_pcm_substream_chip(substream);
+	snd_pcm_runtime_t *runtime = substream->runtime;
+        ca0106_pcm_t *epcm = runtime->private_data;
+        chip->capture_channels[epcm->channel_id].use=0;
+/* FIXME: maybe zero others */
+	return 0;
+}
+
+static int snd_ca0106_pcm_open_0_capture(snd_pcm_substream_t *substream)
+{
+	return snd_ca0106_pcm_open_capture_channel(substream, 0);
+}
+
+static int snd_ca0106_pcm_open_1_capture(snd_pcm_substream_t *substream)
+{
+	return snd_ca0106_pcm_open_capture_channel(substream, 1);
+}
+
+static int snd_ca0106_pcm_open_2_capture(snd_pcm_substream_t *substream)
+{
+	return snd_ca0106_pcm_open_capture_channel(substream, 2);
+}
+
+static int snd_ca0106_pcm_open_3_capture(snd_pcm_substream_t *substream)
+{
+	return snd_ca0106_pcm_open_capture_channel(substream, 3);
+}
+
+/* hw_params callback */
+static int snd_ca0106_pcm_hw_params_playback(snd_pcm_substream_t *substream,
+				      snd_pcm_hw_params_t * hw_params)
+{
+	return snd_pcm_lib_malloc_pages(substream,
+					params_buffer_bytes(hw_params));
+}
+
+/* hw_free callback */
+static int snd_ca0106_pcm_hw_free_playback(snd_pcm_substream_t *substream)
+{
+	return snd_pcm_lib_free_pages(substream);
+}
+
+/* hw_params callback */
+static int snd_ca0106_pcm_hw_params_capture(snd_pcm_substream_t *substream,
+				      snd_pcm_hw_params_t * hw_params)
+{
+	return snd_pcm_lib_malloc_pages(substream,
+					params_buffer_bytes(hw_params));
+}
+
+/* hw_free callback */
+static int snd_ca0106_pcm_hw_free_capture(snd_pcm_substream_t *substream)
+{
+	return snd_pcm_lib_free_pages(substream);
+}
+
+/* prepare playback callback */
+static int snd_ca0106_pcm_prepare_playback(snd_pcm_substream_t *substream)
+{
+	ca0106_t *emu = snd_pcm_substream_chip(substream);
+	snd_pcm_runtime_t *runtime = substream->runtime;
+	ca0106_pcm_t *epcm = runtime->private_data;
+	int channel = epcm->channel_id;
+	u32 *table_base = (u32 *)(emu->buffer.area+(8*16*channel));
+	u32 period_size_bytes = frames_to_bytes(runtime, runtime->period_size);
+	u32 hcfg_mask = HCFG_PLAYBACK_S32_LE;
+	u32 hcfg_set = 0x00000000;
+	u32 hcfg;
+	u32 reg40_mask = 0x30000 << (channel<<1);
+	u32 reg40_set = 0;
+	u32 reg40;
+	/* FIXME: Depending on mixer selection of SPDIF out or not, select the spdif rate or the DAC rate. */
+	u32 reg71_mask = 0x03030000 ; /* Global. Set SPDIF rate. We only support 44100 to spdif, not to DAC. */
+	u32 reg71_set = 0;
+	u32 reg71;
+	int i;
+	
+        //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);
+	/* Rate can be set per channel. */
+	/* reg40 control host to fifo */
+	/* reg71 controls DAC rate. */
+	switch (runtime->rate) {
+	case 44100:
+		reg40_set = 0x10000 << (channel<<1);
+		reg71_set = 0x01010000; 
+		break;
+        case 48000:
+		reg40_set = 0;
+		reg71_set = 0; 
+		break;
+	case 96000:
+		reg40_set = 0x20000 << (channel<<1);
+		reg71_set = 0x02020000; 
+		break;
+	case 192000:
+		reg40_set = 0x30000 << (channel<<1);
+		reg71_set = 0x03030000; 
+		break;
+	default:
+		reg40_set = 0;
+		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_PLAYBACK_S32_LE;
+		break;
+	default:
+		hcfg_set = 0;
+		break;
+	}
+	hcfg = inl(emu->port + HCFG) ;
+	hcfg = (hcfg & ~hcfg_mask) | hcfg_set;
+	outl(hcfg, emu->port + HCFG);
+	reg40 = snd_ca0106_ptr_read(emu, 0x40, 0);
+	reg40 = (reg40 & ~reg40_mask) | reg40_set;
+	snd_ca0106_ptr_write(emu, 0x40, 0, reg40);
+	reg71 = snd_ca0106_ptr_read(emu, 0x71, 0);
+	reg71 = (reg71 & ~reg71_mask) | reg71_set;
+	snd_ca0106_ptr_write(emu, 0x71, 0, reg71);
+
+	/* FIXME: Check emu->buffer.size before actually writing to it. */
+        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;
+	}
+ 
+	snd_ca0106_ptr_write(emu, PLAYBACK_LIST_ADDR, channel, emu->buffer.addr+(8*16*channel));
+	snd_ca0106_ptr_write(emu, PLAYBACK_LIST_SIZE, channel, (runtime->periods - 1) << 19);
+	snd_ca0106_ptr_write(emu, PLAYBACK_LIST_PTR, channel, 0);
+	snd_ca0106_ptr_write(emu, PLAYBACK_DMA_ADDR, channel, runtime->dma_addr);
+	snd_ca0106_ptr_write(emu, PLAYBACK_PERIOD_SIZE, channel, frames_to_bytes(runtime, runtime->period_size)<<16); // buffer size in bytes
+	snd_ca0106_ptr_write(emu, PLAYBACK_POINTER, channel, 0);
+	snd_ca0106_ptr_write(emu, 0x07, channel, 0x0);
+	snd_ca0106_ptr_write(emu, 0x08, channel, 0);
+        snd_ca0106_ptr_write(emu, PLAYBACK_MUTE, 0x0, 0x0); /* Unmute output */
+#if 0
+	snd_ca0106_ptr_write(emu, SPCS0, 0,
+			       SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
+			       SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
+			       SPCS_GENERATIONSTATUS | 0x00001200 |
+			       0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT );
+	}
+#endif
+
+	return 0;
+}
+
+/* prepare capture callback */
+static int snd_ca0106_pcm_prepare_capture(snd_pcm_substream_t *substream)
+{
+	ca0106_t *emu = snd_pcm_substream_chip(substream);
+	snd_pcm_runtime_t *runtime = substream->runtime;
+	ca0106_pcm_t *epcm = runtime->private_data;
+	int channel = epcm->channel_id;
+        //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);
+	snd_ca0106_ptr_write(emu, CAPTURE_BUFFER_SIZE, channel, frames_to_bytes(runtime, runtime->buffer_size)<<16); // buffer size in bytes
+	snd_ca0106_ptr_write(emu, CAPTURE_POINTER, channel, 0);
+
+	return 0;
+}
+
+/* trigger_playback callback */
+static int snd_ca0106_pcm_trigger_playback(snd_pcm_substream_t *substream,
+				    int cmd)
+{
+	ca0106_t *emu = snd_pcm_substream_chip(substream);
+	snd_pcm_runtime_t *runtime;
+	ca0106_pcm_t *epcm;
+	int channel;
+	int result = 0;
+	struct list_head *pos;
+        snd_pcm_substream_t *s;
+	u32 basic = 0;
+	u32 extended = 0;
+	int running=0;
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+		running=1;
+		break;
+	case SNDRV_PCM_TRIGGER_STOP:
+	default:
+		running=0;
+		break;
+	}
+        snd_pcm_group_for_each(pos, substream) {
+                s = snd_pcm_group_substream_entry(pos);
+		runtime = s->runtime;
+		epcm = runtime->private_data;
+		channel = epcm->channel_id;
+		//snd_printk("channel=%d\n",channel);
+		epcm->running = running;
+		basic |= (0x1<<channel);
+		extended |= (0x10<<channel);
+                snd_pcm_trigger_done(s, substream);
+        }
+	//snd_printk("basic=0x%x, extended=0x%x\n",basic, extended);
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+		snd_ca0106_ptr_write(emu, EXTENDED_INT_MASK, 0, snd_ca0106_ptr_read(emu, EXTENDED_INT_MASK, 0) | (extended));
+		snd_ca0106_ptr_write(emu, BASIC_INTERRUPT, 0, snd_ca0106_ptr_read(emu, BASIC_INTERRUPT, 0)|(basic));
+		break;
+	case SNDRV_PCM_TRIGGER_STOP:
+		snd_ca0106_ptr_write(emu, BASIC_INTERRUPT, 0, snd_ca0106_ptr_read(emu, BASIC_INTERRUPT, 0) & ~(basic));
+		snd_ca0106_ptr_write(emu, EXTENDED_INT_MASK, 0, snd_ca0106_ptr_read(emu, EXTENDED_INT_MASK, 0) & ~(extended));
+		break;
+	default:
+		result = -EINVAL;
+		break;
+	}
+	return result;
+}
+
+/* trigger_capture callback */
+static int snd_ca0106_pcm_trigger_capture(snd_pcm_substream_t *substream,
+				    int cmd)
+{
+	ca0106_t *emu = snd_pcm_substream_chip(substream);
+	snd_pcm_runtime_t *runtime = substream->runtime;
+	ca0106_pcm_t *epcm = runtime->private_data;
+	int channel = epcm->channel_id;
+	int result = 0;
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+		snd_ca0106_ptr_write(emu, EXTENDED_INT_MASK, 0, snd_ca0106_ptr_read(emu, EXTENDED_INT_MASK, 0) | (0x110000<<channel));
+		snd_ca0106_ptr_write(emu, BASIC_INTERRUPT, 0, snd_ca0106_ptr_read(emu, BASIC_INTERRUPT, 0)|(0x100<<channel));
+		epcm->running = 1;
+		break;
+	case SNDRV_PCM_TRIGGER_STOP:
+		snd_ca0106_ptr_write(emu, BASIC_INTERRUPT, 0, snd_ca0106_ptr_read(emu, BASIC_INTERRUPT, 0) & ~(0x100<<channel));
+		snd_ca0106_ptr_write(emu, EXTENDED_INT_MASK, 0, snd_ca0106_ptr_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_ca0106_pcm_pointer_playback(snd_pcm_substream_t *substream)
+{
+	ca0106_t *emu = snd_pcm_substream_chip(substream);
+	snd_pcm_runtime_t *runtime = substream->runtime;
+	ca0106_pcm_t *epcm = runtime->private_data;
+	snd_pcm_uframes_t ptr, ptr1, ptr2,ptr3,ptr4 = 0;
+	int channel = epcm->channel_id;
+
+	if (!epcm->running)
+		return 0;
+
+	ptr3 = snd_ca0106_ptr_read(emu, PLAYBACK_LIST_PTR, channel);
+	ptr1 = snd_ca0106_ptr_read(emu, PLAYBACK_POINTER, channel);
+	ptr4 = snd_ca0106_ptr_read(emu, PLAYBACK_LIST_PTR, channel);
+	if (ptr3 != ptr4) ptr1 = snd_ca0106_ptr_read(emu, PLAYBACK_POINTER, channel);
+	ptr2 = bytes_to_frames(runtime, ptr1);
+	ptr2+= (ptr4 >> 3) * runtime->period_size;
+	ptr=ptr2;
+        if (ptr >= runtime->buffer_size)
+		ptr -= runtime->buffer_size;
+	//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;
+}
+
+/* pointer_capture callback */
+static snd_pcm_uframes_t
+snd_ca0106_pcm_pointer_capture(snd_pcm_substream_t *substream)
+{
+	ca0106_t *emu = snd_pcm_substream_chip(substream);
+	snd_pcm_runtime_t *runtime = substream->runtime;
+	ca0106_pcm_t *epcm = runtime->private_data;
+	snd_pcm_uframes_t ptr, ptr1, ptr2 = 0;
+	int channel = channel=epcm->channel_id;
+
+	if (!epcm->running)
+		return 0;
+
+	ptr1 = snd_ca0106_ptr_read(emu, CAPTURE_POINTER, channel);
+	ptr2 = bytes_to_frames(runtime, ptr1);
+	ptr=ptr2;
+        if (ptr >= runtime->buffer_size)
+		ptr -= runtime->buffer_size;
+	//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_ca0106_playback_front_ops = {
+	.open =        snd_ca0106_pcm_open_playback_front,
+	.close =       snd_ca0106_pcm_close_playback,
+	.ioctl =       snd_pcm_lib_ioctl,
+	.hw_params =   snd_ca0106_pcm_hw_params_playback,
+	.hw_free =     snd_ca0106_pcm_hw_free_playback,
+	.prepare =     snd_ca0106_pcm_prepare_playback,
+	.trigger =     snd_ca0106_pcm_trigger_playback,
+	.pointer =     snd_ca0106_pcm_pointer_playback,
+};
+
+static snd_pcm_ops_t snd_ca0106_capture_0_ops = {
+	.open =        snd_ca0106_pcm_open_0_capture,
+	.close =       snd_ca0106_pcm_close_capture,
+	.ioctl =       snd_pcm_lib_ioctl,
+	.hw_params =   snd_ca0106_pcm_hw_params_capture,
+	.hw_free =     snd_ca0106_pcm_hw_free_capture,
+	.prepare =     snd_ca0106_pcm_prepare_capture,
+	.trigger =     snd_ca0106_pcm_trigger_capture,
+	.pointer =     snd_ca0106_pcm_pointer_capture,
+};
+
+static snd_pcm_ops_t snd_ca0106_capture_1_ops = {
+	.open =        snd_ca0106_pcm_open_1_capture,
+	.close =       snd_ca0106_pcm_close_capture,
+	.ioctl =       snd_pcm_lib_ioctl,
+	.hw_params =   snd_ca0106_pcm_hw_params_capture,
+	.hw_free =     snd_ca0106_pcm_hw_free_capture,
+	.prepare =     snd_ca0106_pcm_prepare_capture,
+	.trigger =     snd_ca0106_pcm_trigger_capture,
+	.pointer =     snd_ca0106_pcm_pointer_capture,
+};
+
+static snd_pcm_ops_t snd_ca0106_capture_2_ops = {
+	.open =        snd_ca0106_pcm_open_2_capture,
+	.close =       snd_ca0106_pcm_close_capture,
+	.ioctl =       snd_pcm_lib_ioctl,
+	.hw_params =   snd_ca0106_pcm_hw_params_capture,
+	.hw_free =     snd_ca0106_pcm_hw_free_capture,
+	.prepare =     snd_ca0106_pcm_prepare_capture,
+	.trigger =     snd_ca0106_pcm_trigger_capture,
+	.pointer =     snd_ca0106_pcm_pointer_capture,
+};
+
+static snd_pcm_ops_t snd_ca0106_capture_3_ops = {
+	.open =        snd_ca0106_pcm_open_3_capture,
+	.close =       snd_ca0106_pcm_close_capture,
+	.ioctl =       snd_pcm_lib_ioctl,
+	.hw_params =   snd_ca0106_pcm_hw_params_capture,
+	.hw_free =     snd_ca0106_pcm_hw_free_capture,
+	.prepare =     snd_ca0106_pcm_prepare_capture,
+	.trigger =     snd_ca0106_pcm_trigger_capture,
+	.pointer =     snd_ca0106_pcm_pointer_capture,
+};
+
+static snd_pcm_ops_t snd_ca0106_playback_center_lfe_ops = {
+        .open =         snd_ca0106_pcm_open_playback_center_lfe,
+        .close =        snd_ca0106_pcm_close_playback,
+        .ioctl =        snd_pcm_lib_ioctl,
+        .hw_params =    snd_ca0106_pcm_hw_params_playback,
+        .hw_free =      snd_ca0106_pcm_hw_free_playback,
+        .prepare =      snd_ca0106_pcm_prepare_playback,     
+        .trigger =      snd_ca0106_pcm_trigger_playback,  
+        .pointer =      snd_ca0106_pcm_pointer_playback, 
+};
+
+static snd_pcm_ops_t snd_ca0106_playback_unknown_ops = {
+        .open =         snd_ca0106_pcm_open_playback_unknown,
+        .close =        snd_ca0106_pcm_close_playback,
+        .ioctl =        snd_pcm_lib_ioctl,
+        .hw_params =    snd_ca0106_pcm_hw_params_playback,
+        .hw_free =      snd_ca0106_pcm_hw_free_playback,
+        .prepare =      snd_ca0106_pcm_prepare_playback,     
+        .trigger =      snd_ca0106_pcm_trigger_playback,  
+        .pointer =      snd_ca0106_pcm_pointer_playback, 
+};
+
+static snd_pcm_ops_t snd_ca0106_playback_rear_ops = {
+        .open =         snd_ca0106_pcm_open_playback_rear,
+        .close =        snd_ca0106_pcm_close_playback,
+        .ioctl =        snd_pcm_lib_ioctl,
+        .hw_params =    snd_ca0106_pcm_hw_params_playback,
+		.hw_free =      snd_ca0106_pcm_hw_free_playback,
+        .prepare =      snd_ca0106_pcm_prepare_playback,     
+        .trigger =      snd_ca0106_pcm_trigger_playback,  
+        .pointer =      snd_ca0106_pcm_pointer_playback, 
+};
+
+
+static unsigned short snd_ca0106_ac97_read(ac97_t *ac97,
+					     unsigned short reg)
+{
+	ca0106_t *emu = ac97->private_data;
+	unsigned long flags;
+	unsigned short val;
+
+	spin_lock_irqsave(&emu->emu_lock, flags);
+	outb(reg, emu->port + AC97ADDRESS);
+	val = inw(emu->port + AC97DATA);
+	spin_unlock_irqrestore(&emu->emu_lock, flags);
+	return val;
+}
+
+static void snd_ca0106_ac97_write(ac97_t *ac97,
+				    unsigned short reg, unsigned short val)
+{
+	ca0106_t *emu = ac97->private_data;
+	unsigned long flags;
+  
+	spin_lock_irqsave(&emu->emu_lock, flags);
+	outb(reg, emu->port + AC97ADDRESS);
+	outw(val, emu->port + AC97DATA);
+	spin_unlock_irqrestore(&emu->emu_lock, flags);
+}
+
+static int snd_ca0106_ac97(ca0106_t *chip)
+{
+	ac97_bus_t *pbus;
+	ac97_template_t ac97;
+	int err;
+	static ac97_bus_ops_t ops = {
+		.write = snd_ca0106_ac97_write,
+		.read = snd_ca0106_ac97_read,
+	};
+  
+	if ((err = snd_ac97_bus(chip->card, 0, &ops, NULL, &pbus)) < 0)
+		return err;
+	pbus->no_vra = 1; /* we don't need VRA */
+
+	memset(&ac97, 0, sizeof(ac97));
+	ac97.private_data = chip;
+	return snd_ac97_mixer(pbus, &ac97, &chip->ac97);
+}
+
+static int snd_ca0106_free(ca0106_t *chip)
+{
+	if (chip->res_port != NULL) {    /* avoid access to already used hardware */
+		// disable interrupts
+		snd_ca0106_ptr_write(chip, BASIC_INTERRUPT, 0, 0);
+		outl(0, chip->port + INTE);
+		snd_ca0106_ptr_write(chip, EXTENDED_INT_MASK, 0, 0);
+		udelay(1000);
+		// disable audio
+		//outl(HCFG_LOCKSOUNDCACHE, chip->port + HCFG);
+		outl(0, chip->port + HCFG);
+		/* FIXME: We need to stop and DMA transfers here.
+		 *        But as I am not sure how yet, we cannot from the dma pages.
+		 * So we can fix: snd-malloc: Memory leak?  pages not freed = 8
+		 */
+	}
+	// release the data
+#if 1
+	if (chip->buffer.area)
+		snd_dma_free_pages(&chip->buffer);
+#endif
+
+	// release the i/o port
+	if (chip->res_port) {
+		release_resource(chip->res_port);
+		kfree_nocheck(chip->res_port);
+	}
+	// release the irq
+	if (chip->irq >= 0)
+		free_irq(chip->irq, (void *)chip);
+	pci_disable_device(chip->pci);
+	kfree(chip);
+	return 0;
+}
+
+static int snd_ca0106_dev_free(snd_device_t *device)
+{
+	ca0106_t *chip = device->device_data;
+	return snd_ca0106_free(chip);
+}
+
+static irqreturn_t snd_ca0106_interrupt(int irq, void *dev_id,
+					  struct pt_regs *regs)
+{
+	unsigned int status;
+
+	ca0106_t *chip = dev_id;
+	int i;
+	int mask;
+        unsigned int stat76;
+	ca0106_channel_t *pchannel;
+
+	spin_lock(&chip->emu_lock);
+
+	status = inl(chip->port + IPR);
+
+	// call updater, unlock before it
+	spin_unlock(&chip->emu_lock);
+  
+	if (! status)
+		return IRQ_NONE;
+
+        stat76 = snd_ca0106_ptr_read(chip, EXTENDED_INT, 0);
+	//snd_printk("interrupt status = 0x%08x, stat76=0x%08x\n", status, stat76);
+	//snd_printk("ptr=0x%08x\n",snd_ca0106_ptr_read(chip, PLAYBACK_POINTER, 0));
+        mask = 0x11; /* 0x1 for one half, 0x10 for the other half period. */
+	for(i = 0; i < 4; i++) {
+		pchannel = &(chip->playback_channels[i]);
+		if(stat76 & mask) {
+/* FIXME: Select the correct substream for period elapsed */
+			if(pchannel->use) {
+                          snd_pcm_period_elapsed(pchannel->epcm->substream);
+	                //printk(KERN_INFO "interrupt [%d] used\n", i);
+                        }
+		}
+	        //printk(KERN_INFO "channel=%p\n",pchannel);
+	        //printk(KERN_INFO "interrupt stat76[%d] = %08x, use=%d, channel=%d\n", i, stat76, pchannel->use, pchannel->number);
+		mask <<= 1;
+	}
+        mask = 0x110000; /* 0x1 for one half, 0x10 for the other half period. */
+	for(i = 0; i < 4; i++) {
+		pchannel = &(chip->capture_channels[i]);
+		if(stat76 & mask) {
+/* FIXME: Select the correct substream for period elapsed */
+			if(pchannel->use) {
+                          snd_pcm_period_elapsed(pchannel->epcm->substream);
+	                //printk(KERN_INFO "interrupt [%d] used\n", i);
+                        }
+		}
+	        //printk(KERN_INFO "channel=%p\n",pchannel);
+	        //printk(KERN_INFO "interrupt stat76[%d] = %08x, use=%d, channel=%d\n", i, stat76, pchannel->use, pchannel->number);
+		mask <<= 1;
+	}
+
+        snd_ca0106_ptr_write(chip, EXTENDED_INT, 0, stat76);
+	spin_lock(&chip->emu_lock);
+	// acknowledge the interrupt if necessary
+	outl(status, chip->port+IPR);
+
+	spin_unlock(&chip->emu_lock);
+
+	return IRQ_HANDLED;
+}
+
+static void snd_ca0106_pcm_free(snd_pcm_t *pcm)
+{
+	ca0106_t *emu = pcm->private_data;
+	emu->pcm = NULL;
+	snd_pcm_lib_preallocate_free_for_all(pcm);
+}
+
+static int __devinit snd_ca0106_pcm(ca0106_t *emu, int device, snd_pcm_t **rpcm)
+{
+	snd_pcm_t *pcm;
+	snd_pcm_substream_t *substream;
+	int err;
+  
+	if (rpcm)
+		*rpcm = NULL;
+	if ((err = snd_pcm_new(emu->card, "ca0106", device, 1, 1, &pcm)) < 0)
+		return err;
+  
+	pcm->private_data = emu;
+	pcm->private_free = snd_ca0106_pcm_free;
+
+	switch (device) {
+	case 0:
+	  snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ca0106_playback_front_ops);
+	  snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ca0106_capture_0_ops);
+          break;
+	case 1:
+	  snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ca0106_playback_rear_ops);
+	  snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ca0106_capture_1_ops);
+          break;
+	case 2:
+	  snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ca0106_playback_center_lfe_ops);
+	  snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ca0106_capture_2_ops);
+          break;
+	case 3:
+	  snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ca0106_playback_unknown_ops);
+	  snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ca0106_capture_3_ops);
+          break;
+        }
+
+	pcm->info_flags = 0;
+	pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;
+	strcpy(pcm->name, "CA0106");
+	emu->pcm = pcm;
+
+	for(substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; 
+	    substream; 
+	    substream = substream->next) {
+		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. */
+			return err;
+	}
+
+	for (substream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream; 
+	      substream; 
+	      substream = substream->next) {
+ 		if ((err = snd_pcm_lib_preallocate_pages(substream, 
+	                                           SNDRV_DMA_TYPE_DEV, 
+	                                           snd_dma_pci_data(emu->pci), 
+	                                           64*1024, 64*1024)) < 0)
+			return err;
+	}
+  
+	if (rpcm)
+		*rpcm = pcm;
+  
+	return 0;
+}
+
+static int __devinit snd_ca0106_create(snd_card_t *card,
+					 struct pci_dev *pci,
+					 ca0106_t **rchip)
+{
+	ca0106_t *chip;
+	int err;
+	int ch;
+	static snd_device_ops_t ops = {
+		.dev_free = snd_ca0106_dev_free,
+	};
+  
+	*rchip = NULL;
+  
+	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) {
+		printk(KERN_ERR "error to set 32bit mask DMA\n");
+		pci_disable_device(pci);
+		return -ENXIO;
+	}
+  
+	chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+	if (chip == NULL) {
+		pci_disable_device(pci);
+		return -ENOMEM;
+	}
+  
+	chip->card = card;
+	chip->pci = pci;
+	chip->irq = -1;
+
+	spin_lock_init(&chip->emu_lock);
+  
+	chip->port = pci_resource_start(pci, 0);
+	if ((chip->res_port = request_region(chip->port, 0x20,
+					     "snd_ca0106")) == NULL) { 
+		snd_ca0106_free(chip);
+		printk(KERN_ERR "cannot allocate the port\n");
+		return -EBUSY;
+	}
+
+	if (request_irq(pci->irq, snd_ca0106_interrupt,
+			SA_INTERRUPT|SA_SHIRQ, "snd_ca0106",
+			(void *)chip)) {
+		snd_ca0106_free(chip);
+		printk(KERN_ERR "cannot grab irq\n");
+		return -EBUSY;
+	}
+	chip->irq = pci->irq;
+  
+ 	/* This stores the periods table. */ 
+	if(snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci), 1024, &chip->buffer) < 0) {
+		snd_ca0106_free(chip);
+		return -ENOMEM;
+	}
+
+	pci_set_master(pci);
+	/* read revision & serial */
+	pci_read_config_byte(pci, PCI_REVISION_ID, (char *)&chip->revision);
+	pci_read_config_dword(pci, PCI_SUBSYSTEM_VENDOR_ID, &chip->serial);
+	pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &chip->model);
+#if 1
+	printk(KERN_INFO "Model %04x Rev %08x Serial %08x\n", chip->model,
+	       chip->revision, chip->serial);
+#endif
+
+	outl(0, chip->port + INTE);
+
+	/*
+	 *  Init to 0x02109204 :
+	 *  Clock accuracy    = 0     (1000ppm)
+	 *  Sample Rate       = 2     (48kHz)
+	 *  Audio Channel     = 1     (Left of 2)
+	 *  Source Number     = 0     (Unspecified)
+	 *  Generation Status = 1     (Original for Cat Code 12)
+	 *  Cat Code          = 12    (Digital Signal Mixer)
+	 *  Mode              = 0     (Mode 0)
+	 *  Emphasis          = 0     (None)
+	 *  CP                = 1     (Copyright unasserted)
+	 *  AN                = 0     (Audio data)
+	 *  P                 = 0     (Consumer)
+	 */
+	snd_ca0106_ptr_write(chip, SPCS0, 0,
+				chip->spdif_bits[0] =
+				SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
+				SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
+				SPCS_GENERATIONSTATUS | 0x00001200 |
+				0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT);
+	/* Only SPCS1 has been tested */
+	snd_ca0106_ptr_write(chip, SPCS1, 0,
+				chip->spdif_bits[1] =
+				SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
+				SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
+				SPCS_GENERATIONSTATUS | 0x00001200 |
+				0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT);
+	snd_ca0106_ptr_write(chip, SPCS2, 0,
+				chip->spdif_bits[2] =
+				SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
+				SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
+				SPCS_GENERATIONSTATUS | 0x00001200 |
+				0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT);
+	snd_ca0106_ptr_write(chip, SPCS3, 0,
+				chip->spdif_bits[3] =
+				SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
+				SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
+				SPCS_GENERATIONSTATUS | 0x00001200 |
+				0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT);
+
+        snd_ca0106_ptr_write(chip, PLAYBACK_MUTE, 0, 0x00fc0000);
+        snd_ca0106_ptr_write(chip, CAPTURE_MUTE, 0, 0x00fc0000);
+
+        /* Write 0x8000 to AC97_REC_GAIN to mute it. */
+        outb(AC97_REC_GAIN, chip->port + AC97ADDRESS);
+        outw(0x8000, chip->port + AC97DATA);
+#if 0
+	snd_ca0106_ptr_write(chip, SPCS0, 0, 0x2108006);
+	snd_ca0106_ptr_write(chip, 0x42, 0, 0x2108006);
+	snd_ca0106_ptr_write(chip, 0x43, 0, 0x2108006);
+	snd_ca0106_ptr_write(chip, 0x44, 0, 0x2108006);
+#endif
+
+	//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 */
+	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 */
+	//snd_ca0106_ptr_write(chip, 0x45, 0, 0xf00); /* Digital out */
+
+	snd_ca0106_ptr_write(chip, CAPTURE_CONTROL, 0, 0x40c81000); /* goes to 0x40c80000 when doing SPDIF IN/OUT */
+	snd_ca0106_ptr_write(chip, CAPTURE_CONTROL, 1, 0xffffffff); /* (Mute) CAPTURE feedback into PLAYBACK volume. Only lower 16 bits matter. */
+	snd_ca0106_ptr_write(chip, CAPTURE_CONTROL, 2, 0x30300000); /* SPDIF IN Volume */
+	snd_ca0106_ptr_write(chip, CAPTURE_CONTROL, 3, 0x00700000); /* SPDIF IN Volume, 0x70 = (vol & 0x3f) | 0x40 */
+	snd_ca0106_ptr_write(chip, PLAYBACK_ROUTING1, 0, 0x32765410);
+	snd_ca0106_ptr_write(chip, PLAYBACK_ROUTING2, 0, 0x76767676);
+	snd_ca0106_ptr_write(chip, CAPTURE_ROUTING1, 0, 0x32765410);
+	snd_ca0106_ptr_write(chip, CAPTURE_ROUTING2, 0, 0x76767676);
+	for(ch = 0; ch < 4; ch++) {
+		snd_ca0106_ptr_write(chip, CAPTURE_VOLUME1, ch, 0x30303030); /* Only high 16 bits matter */
+		snd_ca0106_ptr_write(chip, CAPTURE_VOLUME2, ch, 0x30303030);
+		//snd_ca0106_ptr_write(chip, PLAYBACK_VOLUME1, ch, 0x40404040); /* Mute */
+		//snd_ca0106_ptr_write(chip, PLAYBACK_VOLUME2, ch, 0x40404040); /* Mute */
+		snd_ca0106_ptr_write(chip, PLAYBACK_VOLUME1, ch, 0xffffffff); /* Mute */
+		snd_ca0106_ptr_write(chip, PLAYBACK_VOLUME2, ch, 0xffffffff); /* Mute */
+	}
+        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) ) { /* 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 */
+	} else {
+		outl(0x0, chip->port+GPIO);
+		outl(0x005f03a3, chip->port+GPIO); /* Analog */
+		//outl(0x005f02a2, chip->port+GPIO);   /* SPDIF */
+	}
+	snd_ca0106_intr_enable(chip, 0x105); /* Win2000 uses 0x1e0 */
+
+	//outl(HCFG_LOCKSOUNDCACHE|HCFG_AUDIOENABLE, chip->port+HCFG);
+	//outl(0x00001409, chip->port+HCFG); /* 0x1000 causes AC3 to fails. Maybe it effects 24 bit output. */
+	//outl(0x00000009, chip->port+HCFG);
+	outl(HCFG_AC97 | HCFG_AUDIOENABLE, chip->port+HCFG); /* AC97 2.0, Enable outputs. */
+
+	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL,
+				  chip, &ops)) < 0) {
+		snd_ca0106_free(chip);
+		return err;
+	}
+	*rchip = chip;
+	return 0;
+}
+
+static int __devinit snd_ca0106_probe(struct pci_dev *pci,
+					const struct pci_device_id *pci_id)
+{
+	static int dev;
+	snd_card_t *card;
+	ca0106_t *chip;
+	ca0106_names_t *c;
+	int err;
+
+	if (dev >= SNDRV_CARDS)
+		return -ENODEV;
+	if (!enable[dev]) {
+		dev++;
+		return -ENOENT;
+	}
+
+	card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
+	if (card == NULL)
+		return -ENOMEM;
+
+	if ((err = snd_ca0106_create(card, pci, &chip)) < 0) {
+		snd_card_free(card);
+		return err;
+	}
+
+	if ((err = snd_ca0106_pcm(chip, 0, NULL)) < 0) {
+		snd_card_free(card);
+		return err;
+	}
+	if ((err = snd_ca0106_pcm(chip, 1, NULL)) < 0) {
+		snd_card_free(card);
+		return err;
+	}
+	if ((err = snd_ca0106_pcm(chip, 2, NULL)) < 0) {
+		snd_card_free(card);
+		return err;
+	}
+	if ((err = snd_ca0106_pcm(chip, 3, NULL)) < 0) {
+		snd_card_free(card);
+		return err;
+	}
+        if ((chip->serial != 0x10061102) && (chip->serial != 0x10071102) ) { /* The SB0410 and SB0413 do not have an ac97 chip. */
+		if ((err = snd_ca0106_ac97(chip)) < 0) {
+			snd_card_free(card);
+			return err;
+		}
+	}
+	if ((err = snd_ca0106_mixer(chip)) < 0) {
+		snd_card_free(card);
+		return err;
+	}
+
+	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;
+	}
+
+	pci_set_drvdata(pci, card);
+	dev++;
+	return 0;
+}
+
+static void __devexit snd_ca0106_remove(struct pci_dev *pci)
+{
+	snd_card_free(pci_get_drvdata(pci));
+	pci_set_drvdata(pci, NULL);
+}
+
+// PCI IDs
+static struct pci_device_id snd_ca0106_ids[] = {
+	{ 0x1102, 0x0007, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },	/* Audigy LS or Live 24bit */
+	{ 0, }
+};
+MODULE_DEVICE_TABLE(pci, snd_ca0106_ids);
+
+// pci_driver definition
+static struct pci_driver driver = {
+	.name = "CA0106",
+	.id_table = snd_ca0106_ids,
+	.probe = snd_ca0106_probe,
+	.remove = __devexit_p(snd_ca0106_remove),
+};
+
+// initialization of the module
+static int __init alsa_card_ca0106_init(void)
+{
+	int err;
+
+	if ((err = pci_module_init(&driver)) > 0)
+		return err;
+
+	return 0;
+}
+
+// clean up the module
+static void __exit alsa_card_ca0106_exit(void)
+{
+	pci_unregister_driver(&driver);
+}
+
+module_init(alsa_card_ca0106_init)
+module_exit(alsa_card_ca0106_exit)
diff -Nru a/sound/pci/ca0106/ca0106_mixer.c b/sound/pci/ca0106/ca0106_mixer.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/sound/pci/ca0106/ca0106_mixer.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,634 @@
+/*
+ *  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
+ *
+ *  FEATURES currently supported:
+ *    See ca0106_main.c for features.
+ * 
+ *  Changelog:
+ *    Support interrupts per period.
+ *    Removed noise from Center/LFE channel when in Analog mode.
+ *    Rename and remove mixer controls.
+ *  0.0.6
+ *    Use separate card based DMA buffer for periods table list.
+ *  0.0.7
+ *    Change remove and rename ctrls into lists.
+ *  0.0.8
+ *    Try to fix capture sources.
+ *  0.0.9
+ *    Fix AC3 output.
+ *    Enable S32_LE format support.
+ *  0.0.10
+ *    Enable playback 48000 and 96000 rates. (Rates other that these do not work, even with "plug:front".)
+ *  0.0.11
+ *    Add Model name recognition.
+ *  0.0.12
+ *    Correct interrupt timing. interrupt at end of period, instead of in the middle of a playback period.
+ *    Remove redundent "voice" handling.
+ *  0.0.13
+ *    Single trigger call for multi channels.
+ *  0.0.14
+ *    Set limits based on what the sound card hardware can do.
+ *    playback periods_min=2, periods_max=8
+ *    capture hw constraints require period_size = n * 64 bytes.
+ *    playback hw constraints require period_size = n * 64 bytes.
+ *  0.0.15
+ *    Separated ca0106.c into separate functional .c files.
+ *  0.0.16
+ *    Modified Copyright message.
+ *
+ *  This code was initally based on code from ALSA's emu10k1x.c which is:
+ *  Copyright (c) by Francisco Moraes <fmoraes@nc.rr.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 <sound/driver.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/moduleparam.h>
+#include <sound/core.h>
+#include <sound/initval.h>
+#include <sound/pcm.h>
+#include <sound/ac97_codec.h>
+#include <sound/info.h>
+
+#include "ca0106.h"
+
+static int snd_ca0106_shared_spdif_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_ca0106_shared_spdif_get(snd_kcontrol_t * kcontrol,
+					snd_ctl_elem_value_t * ucontrol)
+{
+	ca0106_t *emu = snd_kcontrol_chip(kcontrol);
+
+	ucontrol->value.enumerated.item[0] = emu->spdif_enable;
+	return 0;
+}
+
+static int snd_ca0106_shared_spdif_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 mask;
+
+	val = ucontrol->value.enumerated.item[0] ;
+	change = (emu->spdif_enable != val);
+	if (change) {
+		emu->spdif_enable = val;
+		if (val == 1) {
+			/* Digital */
+			snd_ca0106_ptr_write(emu, SPDIF_SELECT1, 0, 0xf);
+			snd_ca0106_ptr_write(emu, SPDIF_SELECT2, 0, 0x0b000000);
+			snd_ca0106_ptr_write(emu, CAPTURE_CONTROL, 0,
+				snd_ca0106_ptr_read(emu, CAPTURE_CONTROL, 0) & ~0x1000);
+			mask = inl(emu->port + GPIO) & ~0x101;
+			outl(mask, emu->port + GPIO);
+
+		} 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, CAPTURE_CONTROL, 0,
+				snd_ca0106_ptr_read(emu, CAPTURE_CONTROL, 0) | 0x1000);
+			mask = inl(emu->port + GPIO) | 0x101;
+			outl(mask, emu->port + GPIO);
+		}
+	}
+        return change;
+}
+
+static snd_kcontrol_new_t snd_ca0106_shared_spdif __devinitdata =
+{
+	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name =		"SPDIF Out",
+	.info =		snd_ca0106_shared_spdif_info,
+	.get =		snd_ca0106_shared_spdif_get,
+	.put =		snd_ca0106_shared_spdif_put
+};
+
+static int snd_ca0106_capture_source_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+{
+	static char *texts[6] = { "SPDIF out", "i2s mixer out", "SPDIF in", "i2s in", "AC97 in", "SRC out" };
+
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+	uinfo->count = 1;
+	uinfo->value.enumerated.items = 6;
+	if (uinfo->value.enumerated.item > 5)
+                uinfo->value.enumerated.item = 5;
+	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
+	return 0;
+}
+
+static int snd_ca0106_capture_source_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_source;
+	return 0;
+}
+
+static int snd_ca0106_capture_source_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 mask;
+	u32 source;
+
+	val = ucontrol->value.enumerated.item[0] ;
+	change = (emu->capture_source != val);
+	if (change) {
+		emu->capture_source = val;
+		source = (val << 28) | (val << 24) | (val << 20) | (val << 16);
+		mask = snd_ca0106_ptr_read(emu, CAPTURE_SOURCE, 0) & 0xffff;
+		snd_ca0106_ptr_write(emu, CAPTURE_SOURCE, 0, source | mask);
+	}
+        return change;
+}
+
+static snd_kcontrol_new_t snd_ca0106_capture_source __devinitdata =
+{
+	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name =		"Capture Source",
+	.info =		snd_ca0106_capture_source_info,
+	.get =		snd_ca0106_capture_source_get,
+	.put =		snd_ca0106_capture_source_put
+};
+
+static int snd_ca0106_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
+	uinfo->count = 1;
+	return 0;
+}
+
+static int snd_ca0106_spdif_get(snd_kcontrol_t * kcontrol,
+                                 snd_ctl_elem_value_t * ucontrol)
+{
+	ca0106_t *emu = snd_kcontrol_chip(kcontrol);
+	unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
+
+	ucontrol->value.iec958.status[0] = (emu->spdif_bits[idx] >> 0) & 0xff;
+	ucontrol->value.iec958.status[1] = (emu->spdif_bits[idx] >> 8) & 0xff;
+	ucontrol->value.iec958.status[2] = (emu->spdif_bits[idx] >> 16) & 0xff;
+	ucontrol->value.iec958.status[3] = (emu->spdif_bits[idx] >> 24) & 0xff;
+        return 0;
+}
+
+static int snd_ca0106_spdif_get_mask(snd_kcontrol_t * kcontrol,
+				      snd_ctl_elem_value_t * ucontrol)
+{
+	ucontrol->value.iec958.status[0] = 0xff;
+	ucontrol->value.iec958.status[1] = 0xff;
+	ucontrol->value.iec958.status[2] = 0xff;
+	ucontrol->value.iec958.status[3] = 0xff;
+        return 0;
+}
+
+static int snd_ca0106_spdif_put(snd_kcontrol_t * kcontrol,
+                                 snd_ctl_elem_value_t * ucontrol)
+{
+	ca0106_t *emu = snd_kcontrol_chip(kcontrol);
+	unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
+	int change;
+	unsigned int val;
+
+	val = (ucontrol->value.iec958.status[0] << 0) |
+	      (ucontrol->value.iec958.status[1] << 8) |
+	      (ucontrol->value.iec958.status[2] << 16) |
+	      (ucontrol->value.iec958.status[3] << 24);
+	change = val != emu->spdif_bits[idx];
+	if (change) {
+		snd_ca0106_ptr_write(emu, SPCS0 + idx, 0, val);
+		emu->spdif_bits[idx] = val;
+	}
+        return change;
+}
+
+static snd_kcontrol_new_t snd_ca0106_spdif_mask_control =
+{
+	.access =	SNDRV_CTL_ELEM_ACCESS_READ,
+        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
+        .name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
+	.count =	4,
+        .info =         snd_ca0106_spdif_info,
+        .get =          snd_ca0106_spdif_get_mask
+};
+
+static snd_kcontrol_new_t snd_ca0106_spdif_control =
+{
+        .iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
+        .name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
+	.count =	4,
+        .info =         snd_ca0106_spdif_info,
+        .get =          snd_ca0106_spdif_get,
+        .put =          snd_ca0106_spdif_put
+};
+
+static int snd_ca0106_volume_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 = 255;
+        return 0;
+}
+
+static int snd_ca0106_volume_get(snd_kcontrol_t * kcontrol,
+                                       snd_ctl_elem_value_t * ucontrol, int reg, int channel_id)
+{
+        ca0106_t *emu = snd_kcontrol_chip(kcontrol);
+        unsigned int value;
+
+        value = snd_ca0106_ptr_read(emu, reg, channel_id);
+        ucontrol->value.integer.value[0] = 0xff - ((value >> 24) & 0xff); /* Left */
+        ucontrol->value.integer.value[1] = 0xff - ((value >> 16) & 0xff); /* Right */
+        return 0;
+}
+
+static int snd_ca0106_volume_get_spdif_front(snd_kcontrol_t * kcontrol,
+                                       snd_ctl_elem_value_t * ucontrol)
+{
+	int channel_id = CONTROL_FRONT_CHANNEL;
+	int reg = PLAYBACK_VOLUME1;
+        return snd_ca0106_volume_get(kcontrol, ucontrol, reg, channel_id);
+}
+
+static int snd_ca0106_volume_get_spdif_center_lfe(snd_kcontrol_t * kcontrol,
+                                       snd_ctl_elem_value_t * ucontrol)
+{
+	int channel_id = CONTROL_CENTER_LFE_CHANNEL;
+	int reg = PLAYBACK_VOLUME1;
+        return snd_ca0106_volume_get(kcontrol, ucontrol, reg, channel_id);
+}
+static int snd_ca0106_volume_get_spdif_unknown(snd_kcontrol_t * kcontrol,
+                                       snd_ctl_elem_value_t * ucontrol)
+{
+	int channel_id = CONTROL_UNKNOWN_CHANNEL;
+	int reg = PLAYBACK_VOLUME1;
+        return snd_ca0106_volume_get(kcontrol, ucontrol, reg, channel_id);
+}
+static int snd_ca0106_volume_get_spdif_rear(snd_kcontrol_t * kcontrol,
+                                       snd_ctl_elem_value_t * ucontrol)
+{
+	int channel_id = CONTROL_REAR_CHANNEL;
+	int reg = PLAYBACK_VOLUME1;
+        return snd_ca0106_volume_get(kcontrol, ucontrol, reg, channel_id);
+}
+static int snd_ca0106_volume_get_analog_front(snd_kcontrol_t * kcontrol,
+                                       snd_ctl_elem_value_t * ucontrol)
+{
+	int channel_id = CONTROL_FRONT_CHANNEL;
+	int reg = PLAYBACK_VOLUME2;
+        return snd_ca0106_volume_get(kcontrol, ucontrol, reg, channel_id);
+}
+
+static int snd_ca0106_volume_get_analog_center_lfe(snd_kcontrol_t * kcontrol,
+                                       snd_ctl_elem_value_t * ucontrol)
+{
+	int channel_id = CONTROL_CENTER_LFE_CHANNEL;
+	int reg = PLAYBACK_VOLUME2;
+        return snd_ca0106_volume_get(kcontrol, ucontrol, reg, channel_id);
+}
+static int snd_ca0106_volume_get_analog_unknown(snd_kcontrol_t * kcontrol,
+                                       snd_ctl_elem_value_t * ucontrol)
+{
+	int channel_id = CONTROL_UNKNOWN_CHANNEL;
+	int reg = PLAYBACK_VOLUME2;
+        return snd_ca0106_volume_get(kcontrol, ucontrol, reg, channel_id);
+}
+static int snd_ca0106_volume_get_analog_rear(snd_kcontrol_t * kcontrol,
+                                       snd_ctl_elem_value_t * ucontrol)
+{
+	int channel_id = CONTROL_REAR_CHANNEL;
+	int reg = PLAYBACK_VOLUME2;
+        return snd_ca0106_volume_get(kcontrol, ucontrol, reg, channel_id);
+}
+
+static int snd_ca0106_volume_get_feedback(snd_kcontrol_t * kcontrol,
+                                       snd_ctl_elem_value_t * ucontrol)
+{
+	int channel_id = 1;
+	int reg = CAPTURE_CONTROL;
+        return snd_ca0106_volume_get(kcontrol, ucontrol, reg, channel_id);
+}
+                                                                                                                           
+static int snd_ca0106_volume_put(snd_kcontrol_t * kcontrol,
+                                       snd_ctl_elem_value_t * ucontrol, int reg, int channel_id)
+{
+        ca0106_t *emu = snd_kcontrol_chip(kcontrol);
+        unsigned int value;
+        //value = snd_ca0106_ptr_read(emu, reg, channel_id);
+        //value = value & 0xffff;
+        value = ((0xff - ucontrol->value.integer.value[0]) << 24) | ((0xff - ucontrol->value.integer.value[1]) << 16);
+        value = value | ((0xff - ucontrol->value.integer.value[0]) << 8) | ((0xff - ucontrol->value.integer.value[1]) );
+        snd_ca0106_ptr_write(emu, reg, channel_id, value);
+        return 1;
+}
+static int snd_ca0106_volume_put_spdif_front(snd_kcontrol_t * kcontrol,
+                                       snd_ctl_elem_value_t * ucontrol)
+{
+	int channel_id = CONTROL_FRONT_CHANNEL;
+	int reg = PLAYBACK_VOLUME1;
+        return snd_ca0106_volume_put(kcontrol, ucontrol, reg, channel_id);
+}
+static int snd_ca0106_volume_put_spdif_center_lfe(snd_kcontrol_t * kcontrol,
+                                       snd_ctl_elem_value_t * ucontrol)
+{
+	int channel_id = CONTROL_CENTER_LFE_CHANNEL;
+	int reg = PLAYBACK_VOLUME1;
+        return snd_ca0106_volume_put(kcontrol, ucontrol, reg, channel_id);
+}
+static int snd_ca0106_volume_put_spdif_unknown(snd_kcontrol_t * kcontrol,
+                                       snd_ctl_elem_value_t * ucontrol)
+{
+	int channel_id = CONTROL_UNKNOWN_CHANNEL;
+	int reg = PLAYBACK_VOLUME1;
+        return snd_ca0106_volume_put(kcontrol, ucontrol, reg, channel_id);
+}
+static int snd_ca0106_volume_put_spdif_rear(snd_kcontrol_t * kcontrol,
+                                       snd_ctl_elem_value_t * ucontrol)
+{
+	int channel_id = CONTROL_REAR_CHANNEL;
+	int reg = PLAYBACK_VOLUME1;
+        return snd_ca0106_volume_put(kcontrol, ucontrol, reg, channel_id);
+}
+static int snd_ca0106_volume_put_analog_front(snd_kcontrol_t * kcontrol,
+                                       snd_ctl_elem_value_t * ucontrol)
+{
+	int channel_id = CONTROL_FRONT_CHANNEL;
+	int reg = PLAYBACK_VOLUME2;
+        return snd_ca0106_volume_put(kcontrol, ucontrol, reg, channel_id);
+}
+static int snd_ca0106_volume_put_analog_center_lfe(snd_kcontrol_t * kcontrol,
+                                       snd_ctl_elem_value_t * ucontrol)
+{
+	int channel_id = CONTROL_CENTER_LFE_CHANNEL;
+	int reg = PLAYBACK_VOLUME2;
+        return snd_ca0106_volume_put(kcontrol, ucontrol, reg, channel_id);
+}
+static int snd_ca0106_volume_put_analog_unknown(snd_kcontrol_t * kcontrol,
+                                       snd_ctl_elem_value_t * ucontrol)
+{
+	int channel_id = CONTROL_UNKNOWN_CHANNEL;
+	int reg = PLAYBACK_VOLUME2;
+        return snd_ca0106_volume_put(kcontrol, ucontrol, reg, channel_id);
+}
+static int snd_ca0106_volume_put_analog_rear(snd_kcontrol_t * kcontrol,
+                                       snd_ctl_elem_value_t * ucontrol)
+{
+	int channel_id = CONTROL_REAR_CHANNEL;
+	int reg = PLAYBACK_VOLUME2;
+        return snd_ca0106_volume_put(kcontrol, ucontrol, reg, channel_id);
+}
+
+static int snd_ca0106_volume_put_feedback(snd_kcontrol_t * kcontrol,
+                                       snd_ctl_elem_value_t * ucontrol)
+{
+	int channel_id = 1;
+	int reg = CAPTURE_CONTROL;
+        return snd_ca0106_volume_put(kcontrol, ucontrol, reg, channel_id);
+}
+
+static snd_kcontrol_new_t snd_ca0106_volume_control_analog_front =
+{
+        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
+        .name =         "Analog Front Volume",
+        .info =         snd_ca0106_volume_info,
+        .get =          snd_ca0106_volume_get_analog_front,
+        .put =          snd_ca0106_volume_put_analog_front
+};
+static snd_kcontrol_new_t snd_ca0106_volume_control_analog_center_lfe =
+{
+        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
+        .name =         "Analog Center/LFE Volume",
+        .info =         snd_ca0106_volume_info,
+        .get =          snd_ca0106_volume_get_analog_center_lfe,
+        .put =          snd_ca0106_volume_put_analog_center_lfe
+};
+static snd_kcontrol_new_t snd_ca0106_volume_control_analog_unknown =
+{
+        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
+        .name =         "Analog Unknown Volume",
+        .info =         snd_ca0106_volume_info,
+        .get =          snd_ca0106_volume_get_analog_unknown,
+        .put =          snd_ca0106_volume_put_analog_unknown
+};
+static snd_kcontrol_new_t snd_ca0106_volume_control_analog_rear =
+{
+        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
+        .name =         "Analog Rear Volume",
+        .info =         snd_ca0106_volume_info,
+        .get =          snd_ca0106_volume_get_analog_rear,
+        .put =          snd_ca0106_volume_put_analog_rear
+};
+static snd_kcontrol_new_t snd_ca0106_volume_control_spdif_front =
+{
+        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
+        .name =         "SPDIF Front Volume",
+        .info =         snd_ca0106_volume_info,
+        .get =          snd_ca0106_volume_get_spdif_front,
+        .put =          snd_ca0106_volume_put_spdif_front
+};
+static snd_kcontrol_new_t snd_ca0106_volume_control_spdif_center_lfe =
+{
+        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
+        .name =         "SPDIF Center/LFE Volume",
+        .info =         snd_ca0106_volume_info,
+        .get =          snd_ca0106_volume_get_spdif_center_lfe,
+        .put =          snd_ca0106_volume_put_spdif_center_lfe
+};
+static snd_kcontrol_new_t snd_ca0106_volume_control_spdif_unknown =
+{
+        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
+        .name =         "SPDIF Unknown Volume",
+        .info =         snd_ca0106_volume_info,
+        .get =          snd_ca0106_volume_get_spdif_unknown,
+        .put =          snd_ca0106_volume_put_spdif_unknown
+};
+static snd_kcontrol_new_t snd_ca0106_volume_control_spdif_rear =
+{
+        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
+        .name =         "SPDIF Rear Volume",
+        .info =         snd_ca0106_volume_info,
+        .get =          snd_ca0106_volume_get_spdif_rear,
+        .put =          snd_ca0106_volume_put_spdif_rear
+};
+
+static snd_kcontrol_new_t snd_ca0106_volume_control_feedback =
+{
+        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
+        .name =         "CAPTURE feedback into PLAYBACK",
+        .info =         snd_ca0106_volume_info,
+        .get =          snd_ca0106_volume_get_feedback,
+        .put =          snd_ca0106_volume_put_feedback
+};
+
+
+static int remove_ctl(snd_card_t *card, const char *name)
+{
+	snd_ctl_elem_id_t id;
+	memset(&id, 0, sizeof(id));
+	strcpy(id.name, name);
+	id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
+	return snd_ctl_remove_id(card, &id);
+}
+
+static snd_kcontrol_t *ctl_find(snd_card_t *card, const char *name)
+{
+	snd_ctl_elem_id_t sid;
+	memset(&sid, 0, sizeof(sid));
+	/* FIXME: strcpy is bad. */
+	strcpy(sid.name, name);
+	sid.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
+	return snd_ctl_find_id(card, &sid);
+}
+
+static int rename_ctl(snd_card_t *card, const char *src, const char *dst)
+{
+	snd_kcontrol_t *kctl = ctl_find(card, src);
+	if (kctl) {
+		strcpy(kctl->id.name, dst);
+		return 0;
+	}
+	return -ENOENT;
+}
+
+int __devinit snd_ca0106_mixer(ca0106_t *emu)
+{
+        int err;
+        snd_kcontrol_t *kctl;
+        snd_card_t *card = emu->card;
+	char **c;
+	static char *ca0106_remove_ctls[] = {
+		"Master Mono Playback Switch",
+		"Master Mono Playback Volume",
+		"3D Control - Switch",
+		"3D Control Sigmatel - Depth",
+		"PCM Playback Switch",
+		"PCM Playback Volume",
+		"CD Playback Switch",
+		"CD Playback Volume",
+		"Phone Playback Switch",
+		"Phone Playback Volume",
+		"Video Playback Switch",
+		"Video Playback Volume",
+		"PC Speaker Playback Switch",
+		"PC Speaker Playback Volume",
+		"Mono Output Select",
+		"Capture Source",
+		"Capture Switch",
+		"Capture Volume",
+		"External Amplifier",
+		"Sigmatel 4-Speaker Stereo Playback Switch",
+		"Sigmatel Surround Phase Inversion Playback ",
+		NULL
+	};
+	static char *ca0106_rename_ctls[] = {
+		"Master Playback Switch", "Capture Switch",
+		"Master Playback Volume", "Capture Volume",
+		"Line Playback Switch", "AC97 Line Capture Switch",
+		"Line Playback Volume", "AC97 Line Capture Volume",
+		"Aux Playback Switch", "AC97 Aux Capture Switch",
+		"Aux Playback Volume", "AC97 Aux Capture Volume",
+		"Mic Playback Switch", "AC97 Mic Capture Switch",
+		"Mic Playback Volume", "AC97 Mic Capture Volume",
+		"Mic Select", "AC97 Mic Select",
+		"Mic Boost (+20dB)", "AC97 Mic Boost (+20dB)",
+		NULL
+	};
+#if 1
+	for (c=ca0106_remove_ctls; *c; c++)
+		remove_ctl(card, *c);
+	for (c=ca0106_rename_ctls; *c; c += 2)
+		rename_ctl(card, c[0], c[1]);
+#endif
+
+        if ((kctl = snd_ctl_new1(&snd_ca0106_volume_control_analog_front, emu)) == NULL)
+                return -ENOMEM;
+        if ((err = snd_ctl_add(card, kctl)))
+                return err;
+        if ((kctl = snd_ctl_new1(&snd_ca0106_volume_control_analog_rear, emu)) == NULL)
+                return -ENOMEM;
+        if ((err = snd_ctl_add(card, kctl)))
+                return err;
+        if ((kctl = snd_ctl_new1(&snd_ca0106_volume_control_analog_center_lfe, emu)) == NULL)
+                return -ENOMEM;
+        if ((err = snd_ctl_add(card, kctl)))
+                return err;
+        if ((kctl = snd_ctl_new1(&snd_ca0106_volume_control_analog_unknown, emu)) == NULL)
+                return -ENOMEM;
+        if ((err = snd_ctl_add(card, kctl)))
+                return err;
+        if ((kctl = snd_ctl_new1(&snd_ca0106_volume_control_spdif_front, emu)) == NULL)
+                return -ENOMEM;
+        if ((err = snd_ctl_add(card, kctl)))
+                return err;
+        if ((kctl = snd_ctl_new1(&snd_ca0106_volume_control_spdif_rear, emu)) == NULL)
+                return -ENOMEM;
+        if ((err = snd_ctl_add(card, kctl)))
+                return err;
+        if ((kctl = snd_ctl_new1(&snd_ca0106_volume_control_spdif_center_lfe, emu)) == NULL)
+                return -ENOMEM;
+        if ((err = snd_ctl_add(card, kctl)))
+                return err;
+        if ((kctl = snd_ctl_new1(&snd_ca0106_volume_control_spdif_unknown, emu)) == NULL)
+                return -ENOMEM;
+        if ((err = snd_ctl_add(card, kctl)))
+                return err;
+        if ((kctl = snd_ctl_new1(&snd_ca0106_volume_control_feedback, emu)) == NULL)
+                return -ENOMEM;
+        if ((err = snd_ctl_add(card, kctl)))
+                return err;
+	if ((kctl = snd_ctl_new1(&snd_ca0106_spdif_mask_control, emu)) == NULL)
+		return -ENOMEM;
+	if ((err = snd_ctl_add(card, kctl)))
+		return err;
+	if ((kctl = snd_ctl_new1(&snd_ca0106_shared_spdif, emu)) == NULL)
+		return -ENOMEM;
+	if ((err = snd_ctl_add(card, kctl)))
+		return err;
+	if ((kctl = snd_ctl_new1(&snd_ca0106_capture_source, emu)) == NULL)
+		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 ((kctl = snd_ctl_new1(&snd_ca0106_spdif_control, emu)) == NULL)
+		return -ENOMEM;
+	if ((err = snd_ctl_add(card, kctl)))
+		return err;
+        return 0;
+}
+
diff -Nru a/sound/pci/ca0106/ca0106_proc.c b/sound/pci/ca0106/ca0106_proc.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/sound/pci/ca0106/ca0106_proc.c	2005-03-01 23:39:26 -08:00
@@ -0,0 +1,436 @@
+/*
+ *  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
+ *
+ *  FEATURES currently supported:
+ *    See ca0106_main.c for features.
+ * 
+ *  Changelog:
+ *    Support interrupts per period.
+ *    Removed noise from Center/LFE channel when in Analog mode.
+ *    Rename and remove mixer controls.
+ *  0.0.6
+ *    Use separate card based DMA buffer for periods table list.
+ *  0.0.7
+ *    Change remove and rename ctrls into lists.
+ *  0.0.8
+ *    Try to fix capture sources.
+ *  0.0.9
+ *    Fix AC3 output.
+ *    Enable S32_LE format support.
+ *  0.0.10
+ *    Enable playback 48000 and 96000 rates. (Rates other that these do not work, even with "plug:front".)
+ *  0.0.11
+ *    Add Model name recognition.
+ *  0.0.12
+ *    Correct interrupt timing. interrupt at end of period, instead of in the middle of a playback period.
+ *    Remove redundent "voice" handling.
+ *  0.0.13
+ *    Single trigger call for multi channels.
+ *  0.0.14
+ *    Set limits based on what the sound card hardware can do.
+ *    playback periods_min=2, periods_max=8
+ *    capture hw constraints require period_size = n * 64 bytes.
+ *    playback hw constraints require period_size = n * 64 bytes.
+ *  0.0.15
+ *    Separate ca0106.c into separate functional .c files.
+ *  0.0.16
+ *    Modified Copyright message.
+ *  0.0.17
+ *    Add iec958 file in proc file system to show status of SPDIF in.
+ *    
+ *  This code was initally based on code from ALSA's emu10k1x.c which is:
+ *  Copyright (c) by Francisco Moraes <fmoraes@nc.rr.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 <sound/driver.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/moduleparam.h>
+#include <sound/core.h>
+#include <sound/initval.h>
+#include <sound/pcm.h>
+#include <sound/ac97_codec.h>
+#include <sound/info.h>
+#include <sound/asoundef.h>
+
+#include "ca0106.h"
+
+
+struct snd_ca0106_category_str {
+	int val;
+	const char *name;
+};
+
+static struct snd_ca0106_category_str snd_ca0106_con_category[] = {
+	{ IEC958_AES1_CON_DAT, "DAT" },
+	{ IEC958_AES1_CON_VCR, "VCR" },
+	{ IEC958_AES1_CON_MICROPHONE, "microphone" },
+	{ IEC958_AES1_CON_SYNTHESIZER, "synthesizer" },
+	{ IEC958_AES1_CON_RATE_CONVERTER, "rate converter" },
+	{ IEC958_AES1_CON_MIXER, "mixer" },
+	{ IEC958_AES1_CON_SAMPLER, "sampler" },
+	{ IEC958_AES1_CON_PCM_CODER, "PCM coder" },
+	{ IEC958_AES1_CON_IEC908_CD, "CD" },
+	{ IEC958_AES1_CON_NON_IEC908_CD, "non-IEC908 CD" },
+	{ IEC958_AES1_CON_GENERAL, "general" },
+};
+
+
+void snd_ca0106_proc_dump_iec958( snd_info_buffer_t *buffer, u32 value)
+{
+	int i;
+	u32 status[4];
+	status[0] = value & 0xff;
+	status[1] = (value >> 8) & 0xff;
+	status[2] = (value >> 16)  & 0xff;
+	status[3] = (value >> 24)  & 0xff;
+	
+	if (! (status[0] & IEC958_AES0_PROFESSIONAL)) {
+		/* consumer */
+		snd_iprintf(buffer, "Mode: consumer\n");
+		snd_iprintf(buffer, "Data: ");
+		if (!(status[0] & IEC958_AES0_NONAUDIO)) {
+			snd_iprintf(buffer, "audio\n");
+		} else {
+			snd_iprintf(buffer, "non-audio\n");
+		}
+		snd_iprintf(buffer, "Rate: ");
+		switch (status[3] & IEC958_AES3_CON_FS) {
+		case IEC958_AES3_CON_FS_44100:
+			snd_iprintf(buffer, "44100 Hz\n");
+			break;
+		case IEC958_AES3_CON_FS_48000:
+			snd_iprintf(buffer, "48000 Hz\n");
+			break;
+		case IEC958_AES3_CON_FS_32000:
+			snd_iprintf(buffer, "32000 Hz\n");
+			break;
+		default:
+			snd_iprintf(buffer, "unknown\n");
+			break;
+		}
+		snd_iprintf(buffer, "Copyright: ");
+		if (status[0] & IEC958_AES0_CON_NOT_COPYRIGHT) {
+			snd_iprintf(buffer, "permitted\n");
+		} else {
+			snd_iprintf(buffer, "protected\n");
+		}
+		snd_iprintf(buffer, "Emphasis: ");
+		if ((status[0] & IEC958_AES0_CON_EMPHASIS) != IEC958_AES0_CON_EMPHASIS_5015) {
+			snd_iprintf(buffer, "none\n");
+		} else {
+			snd_iprintf(buffer, "50/15us\n");
+		}
+		snd_iprintf(buffer, "Category: ");
+		for (i = 0; i < ARRAY_SIZE(snd_ca0106_con_category); i++) {
+			if ((status[1] & IEC958_AES1_CON_CATEGORY) == snd_ca0106_con_category[i].val) {
+				snd_iprintf(buffer, "%s\n", snd_ca0106_con_category[i].name);
+				break;
+			}
+		}
+		if (i >= ARRAY_SIZE(snd_ca0106_con_category)) {
+			snd_iprintf(buffer, "unknown 0x%x\n", status[1] & IEC958_AES1_CON_CATEGORY);
+		}
+		snd_iprintf(buffer, "Original: ");
+		if (status[1] & IEC958_AES1_CON_ORIGINAL) {
+			snd_iprintf(buffer, "original\n");
+		} else {
+			snd_iprintf(buffer, "1st generation\n");
+		}
+		snd_iprintf(buffer, "Clock: ");
+		switch (status[3] & IEC958_AES3_CON_CLOCK) {
+		case IEC958_AES3_CON_CLOCK_1000PPM:
+			snd_iprintf(buffer, "1000 ppm\n");
+			break;
+		case IEC958_AES3_CON_CLOCK_50PPM:
+			snd_iprintf(buffer, "50 ppm\n");
+			break;
+		case IEC958_AES3_CON_CLOCK_VARIABLE:
+			snd_iprintf(buffer, "variable pitch\n");
+			break;
+		default:
+			snd_iprintf(buffer, "unknown\n");
+			break;
+		}
+	} else {
+		snd_iprintf(buffer, "Mode: professional\n");
+		snd_iprintf(buffer, "Data: ");
+		if (!(status[0] & IEC958_AES0_NONAUDIO)) {
+			snd_iprintf(buffer, "audio\n");
+		} else {
+			snd_iprintf(buffer, "non-audio\n");
+		}
+		snd_iprintf(buffer, "Rate: ");
+		switch (status[0] & IEC958_AES0_PRO_FS) {
+		case IEC958_AES0_PRO_FS_44100:
+			snd_iprintf(buffer, "44100 Hz\n");
+			break;
+		case IEC958_AES0_PRO_FS_48000:
+			snd_iprintf(buffer, "48000 Hz\n");
+			break;
+		case IEC958_AES0_PRO_FS_32000:
+			snd_iprintf(buffer, "32000 Hz\n");
+			break;
+		default:
+			snd_iprintf(buffer, "unknown\n");
+			break;
+		}
+		snd_iprintf(buffer, "Rate Locked: ");
+		if (status[0] & IEC958_AES0_PRO_FREQ_UNLOCKED)
+			snd_iprintf(buffer, "no\n");
+		else
+			snd_iprintf(buffer, "yes\n");
+		snd_iprintf(buffer, "Emphasis: ");
+		switch (status[0] & IEC958_AES0_PRO_EMPHASIS) {
+		case IEC958_AES0_PRO_EMPHASIS_CCITT:
+			snd_iprintf(buffer, "CCITT J.17\n");
+			break;
+		case IEC958_AES0_PRO_EMPHASIS_NONE:
+			snd_iprintf(buffer, "none\n");
+			break;
+		case IEC958_AES0_PRO_EMPHASIS_5015:
+			snd_iprintf(buffer, "50/15us\n");
+			break;
+		case IEC958_AES0_PRO_EMPHASIS_NOTID:
+		default:
+			snd_iprintf(buffer, "unknown\n");
+			break;
+		}
+		snd_iprintf(buffer, "Stereophonic: ");
+		if ((status[1] & IEC958_AES1_PRO_MODE) == IEC958_AES1_PRO_MODE_STEREOPHONIC) {
+			snd_iprintf(buffer, "stereo\n");
+		} else {
+			snd_iprintf(buffer, "not indicated\n");
+		}
+		snd_iprintf(buffer, "Userbits: ");
+		switch (status[1] & IEC958_AES1_PRO_USERBITS) {
+		case IEC958_AES1_PRO_USERBITS_192:
+			snd_iprintf(buffer, "192bit\n");
+			break;
+		case IEC958_AES1_PRO_USERBITS_UDEF:
+			snd_iprintf(buffer, "user-defined\n");
+			break;
+		default:
+			snd_iprintf(buffer, "unkown\n");
+			break;
+		}
+		snd_iprintf(buffer, "Sample Bits: ");
+		switch (status[2] & IEC958_AES2_PRO_SBITS) {
+		case IEC958_AES2_PRO_SBITS_20:
+			snd_iprintf(buffer, "20 bit\n");
+			break;
+		case IEC958_AES2_PRO_SBITS_24:
+			snd_iprintf(buffer, "24 bit\n");
+			break;
+		case IEC958_AES2_PRO_SBITS_UDEF:
+			snd_iprintf(buffer, "user defined\n");
+			break;
+		default:
+			snd_iprintf(buffer, "unknown\n");
+			break;
+		}
+		snd_iprintf(buffer, "Word Length: ");
+		switch (status[2] & IEC958_AES2_PRO_WORDLEN) {
+		case IEC958_AES2_PRO_WORDLEN_22_18:
+			snd_iprintf(buffer, "22 bit or 18 bit\n");
+			break;
+		case IEC958_AES2_PRO_WORDLEN_23_19:
+			snd_iprintf(buffer, "23 bit or 19 bit\n");
+			break;
+		case IEC958_AES2_PRO_WORDLEN_24_20:
+			snd_iprintf(buffer, "24 bit or 20 bit\n");
+			break;
+		case IEC958_AES2_PRO_WORDLEN_20_16:
+			snd_iprintf(buffer, "20 bit or 16 bit\n");
+			break;
+		default:
+			snd_iprintf(buffer, "unknown\n");
+			break;
+		}
+	}
+}
+
+static void snd_ca0106_proc_iec958(snd_info_entry_t *entry, 
+				       snd_info_buffer_t * buffer)
+{
+	ca0106_t *emu = entry->private_data;
+	u32 value;
+
+        value = snd_ca0106_ptr_read(emu, SAMPLE_RATE_TRACKER_STATUS, 0);
+	snd_iprintf(buffer, "Status: %s, %s, %s\n",
+		  (value & 0x100000) ? "Rate Locked" : "Not Rate Locked",
+		  (value & 0x200000) ? "SPDIF Locked" : "No SPDIF Lock",
+		  (value & 0x400000) ? "Audio Valid" : "No valid audio" );
+	snd_iprintf(buffer, "Estimated sample rate: %u\n", 
+		  ((value & 0xfffff) * 48000) / 0x8000 );
+	if (value & 0x200000) {
+		snd_iprintf(buffer, "IEC958/SPDIF input status:\n");
+        	value = snd_ca0106_ptr_read(emu, SPDIF_INPUT_STATUS, 0);
+		snd_ca0106_proc_dump_iec958(buffer, value);
+	}
+
+	snd_iprintf(buffer, "\n");
+}
+
+static void snd_ca0106_proc_reg_write32(snd_info_entry_t *entry, 
+				       snd_info_buffer_t * buffer)
+{
+	ca0106_t *emu = entry->private_data;
+	unsigned long flags;
+        char line[64];
+        u32 reg, val;
+        while (!snd_info_get_line(buffer, line, sizeof(line))) {
+                if (sscanf(line, "%x %x", &reg, &val) != 2)
+                        continue;
+                if ((reg < 0x40) && (reg >=0) && (val <= 0xffffffff) ) {
+			spin_lock_irqsave(&emu->emu_lock, flags);
+			outl(val, emu->port + (reg & 0xfffffffc));
+			spin_unlock_irqrestore(&emu->emu_lock, flags);
+		}
+        }
+}
+
+static void snd_ca0106_proc_reg_read32(snd_info_entry_t *entry, 
+				       snd_info_buffer_t * buffer)
+{
+	ca0106_t *emu = entry->private_data;
+	unsigned long value;
+	unsigned long flags;
+	int i;
+	snd_iprintf(buffer, "Registers:\n\n");
+	for(i = 0; i < 0x20; i+=4) {
+		spin_lock_irqsave(&emu->emu_lock, flags);
+		value = inl(emu->port + i);
+		spin_unlock_irqrestore(&emu->emu_lock, flags);
+		snd_iprintf(buffer, "Register %02X: %08lX\n", i, value);
+	}
+}
+
+static void snd_ca0106_proc_reg_read16(snd_info_entry_t *entry, 
+				       snd_info_buffer_t * buffer)
+{
+	ca0106_t *emu = entry->private_data;
+        unsigned int value;
+	unsigned long flags;
+	int i;
+	snd_iprintf(buffer, "Registers:\n\n");
+	for(i = 0; i < 0x20; i+=2) {
+		spin_lock_irqsave(&emu->emu_lock, flags);
+		value = inw(emu->port + i);
+		spin_unlock_irqrestore(&emu->emu_lock, flags);
+		snd_iprintf(buffer, "Register %02X: %04X\n", i, value);
+	}
+}
+
+static void snd_ca0106_proc_reg_read8(snd_info_entry_t *entry, 
+				       snd_info_buffer_t * buffer)
+{
+	ca0106_t *emu = entry->private_data;
+	unsigned int value;
+	unsigned long flags;
+	int i;
+	snd_iprintf(buffer, "Registers:\n\n");
+	for(i = 0; i < 0x20; i+=1) {
+		spin_lock_irqsave(&emu->emu_lock, flags);
+		value = inb(emu->port + i);
+		spin_unlock_irqrestore(&emu->emu_lock, flags);
+		snd_iprintf(buffer, "Register %02X: %02X\n", i, value);
+	}
+}
+
+static void snd_ca0106_proc_reg_read1(snd_info_entry_t *entry, 
+				       snd_info_buffer_t * buffer)
+{
+	ca0106_t *emu = entry->private_data;
+	unsigned long value;
+	int i,j;
+
+	snd_iprintf(buffer, "Registers\n");
+	for(i = 0; i < 0x40; i++) {
+		snd_iprintf(buffer, "%02X: ",i);
+		for (j = 0; j < 4; j++) {
+                  value = snd_ca0106_ptr_read(emu, i, j);
+		  snd_iprintf(buffer, "%08lX ", value);
+                }
+	        snd_iprintf(buffer, "\n");
+	}
+}
+
+static void snd_ca0106_proc_reg_read2(snd_info_entry_t *entry, 
+				       snd_info_buffer_t * buffer)
+{
+	ca0106_t *emu = entry->private_data;
+	unsigned long value;
+	int i,j;
+
+	snd_iprintf(buffer, "Registers\n");
+	for(i = 0x40; i < 0x80; i++) {
+		snd_iprintf(buffer, "%02X: ",i);
+		for (j = 0; j < 4; j++) {
+                  value = snd_ca0106_ptr_read(emu, i, j);
+		  snd_iprintf(buffer, "%08lX ", value);
+                }
+	        snd_iprintf(buffer, "\n");
+	}
+}
+
+static void snd_ca0106_proc_reg_write(snd_info_entry_t *entry, 
+				       snd_info_buffer_t * buffer)
+{
+	ca0106_t *emu = entry->private_data;
+        char line[64];
+        unsigned int reg, channel_id , val;
+        while (!snd_info_get_line(buffer, line, sizeof(line))) {
+                if (sscanf(line, "%x %x %x", &reg, &channel_id, &val) != 3)
+                        continue;
+                if ((reg < 0x80) && (reg >=0) && (val <= 0xffffffff) && (channel_id >=0) && (channel_id <= 3) )
+                        snd_ca0106_ptr_write(emu, reg, channel_id, val);
+        }
+}
+
+
+int __devinit snd_ca0106_proc_init(ca0106_t * emu)
+{
+	snd_info_entry_t *entry;
+	
+	if(! snd_card_proc_new(emu->card, "iec958", &entry))
+		snd_info_set_text_ops(entry, emu, 1024, snd_ca0106_proc_iec958);
+	if(! snd_card_proc_new(emu->card, "ca0106_reg32", &entry)) {
+		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;
+	}
+	if(! snd_card_proc_new(emu->card, "ca0106_reg16", &entry))
+		snd_info_set_text_ops(entry, emu, 1024, snd_ca0106_proc_reg_read16);
+	if(! snd_card_proc_new(emu->card, "ca0106_reg8", &entry))
+		snd_info_set_text_ops(entry, emu, 1024, snd_ca0106_proc_reg_read8);
+	if(! snd_card_proc_new(emu->card, "ca0106_regs1", &entry)) {
+		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->private_data = emu;
+	}
+	if(! snd_card_proc_new(emu->card, "ca0106_regs2", &entry)) 
+		snd_info_set_text_ops(entry, emu, 1024, snd_ca0106_proc_reg_read2);
+	return 0;
+}
+
diff -Nru a/sound/pci/cmipci.c b/sound/pci/cmipci.c
--- a/sound/pci/cmipci.c	2005-03-01 23:39:07 -08:00
+++ b/sound/pci/cmipci.c	2005-03-01 23:39:07 -08:00
@@ -2608,8 +2608,8 @@
 
 	if (request_irq(pci->irq, snd_cmipci_interrupt, SA_INTERRUPT|SA_SHIRQ, card->driver, (void *)cm)) {
 		snd_printk("unable to grab IRQ %d\n", pci->irq);
-		err = -EBUSY;
-		goto __error;
+		snd_cmipci_free(cm);
+		return -EBUSY;
 	}
 	cm->irq = pci->irq;
 
@@ -2662,6 +2662,11 @@
 		break;
 	}
 
+	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, cm, &ops)) < 0) {
+		snd_cmipci_free(cm);
+		return err;
+	}
+
 	/* set MPU address */
 	switch (iomidi) {
 	case 0x320: val = CM_VMPU_320; break;
@@ -2717,22 +2722,22 @@
 	/* create pcm devices */
 	pcm_index = pcm_spdif_index = 0;
 	if ((err = snd_cmipci_pcm_new(cm, pcm_index)) < 0)
-		goto __error;
+		return err;
 	pcm_index++;
 	if (cm->has_dual_dac) {
 		if ((err = snd_cmipci_pcm2_new(cm, pcm_index)) < 0)
-			goto __error;
+			return err;
 		pcm_index++;
 	}
 	if (cm->can_ac3_hw || cm->can_ac3_sw) {
 		pcm_spdif_index = pcm_index;
 		if ((err = snd_cmipci_pcm_spdif_new(cm, pcm_index)) < 0)
-			goto __error;
+			return err;
 	}
 
 	/* create mixer interface & switches */
 	if ((err = snd_cmipci_mixer_new(cm, pcm_spdif_index)) < 0)
-		goto __error;
+		return err;
 
 	if (iomidi > 0) {
 		if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_CMIPCI,
@@ -2742,10 +2747,6 @@
 		}
 	}
 
-	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, cm, &ops)) < 0) {
-		snd_cmipci_free(cm);
-		return err;
-	}
 #ifdef USE_VAR48KRATE
 	for (val = 0; val < ARRAY_SIZE(rates); val++)
 		snd_cmipci_set_pll(cm, rates[val], val);
@@ -2785,10 +2786,6 @@
 
 	*rcmipci = cm;
 	return 0;
-
- __error:
-	snd_cmipci_free(cm);
-	return err;
 }
 
 /*
diff -Nru a/sound/pci/cs4281.c b/sound/pci/cs4281.c
--- a/sound/pci/cs4281.c	2005-03-01 23:39:16 -08:00
+++ b/sound/pci/cs4281.c	2005-03-01 23:39:16 -08:00
@@ -1439,15 +1439,15 @@
 		return tmp;
 	}
 
-	snd_cs4281_proc_init(chip);
-
-	snd_card_set_pm_callback(card, cs4281_suspend, cs4281_resume, chip);
-
 	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
 		snd_cs4281_free(chip);
 		return err;
 	}
 
+	snd_cs4281_proc_init(chip);
+
+	snd_card_set_pm_callback(card, cs4281_suspend, cs4281_resume, chip);
+
 	snd_card_set_dev(card, &pci->dev);
 
 	*rchip = chip;
@@ -2079,7 +2079,6 @@
 	snd_cs4281_pokeBA0(chip, BA0_CLKCR1, ulCLK);
 
 	pci_disable_device(chip->pci);
-	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
 	return 0;
 }
 
@@ -2112,7 +2111,6 @@
 	ulCLK &= ~CLKCR1_CKRA;
 	snd_cs4281_pokeBA0(chip, BA0_CLKCR1, ulCLK);
 
-	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
 	return 0;
 }
 #endif /* CONFIG_PM */
diff -Nru a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c
--- a/sound/pci/cs46xx/cs46xx_lib.c	2005-03-01 23:38:52 -08:00
+++ b/sound/pci/cs46xx/cs46xx_lib.c	2005-03-01 23:38:52 -08:00
@@ -68,6 +68,20 @@
 
 static void amp_voyetra(cs46xx_t *chip, int change);
 
+#ifdef CONFIG_SND_CS46XX_NEW_DSP
+static snd_pcm_ops_t snd_cs46xx_playback_rear_ops;
+static snd_pcm_ops_t snd_cs46xx_playback_indirect_rear_ops;
+static snd_pcm_ops_t snd_cs46xx_playback_clfe_ops;
+static snd_pcm_ops_t snd_cs46xx_playback_indirect_clfe_ops;
+static snd_pcm_ops_t snd_cs46xx_playback_iec958_ops;
+static snd_pcm_ops_t snd_cs46xx_playback_indirect_iec958_ops;
+#endif
+
+static snd_pcm_ops_t snd_cs46xx_playback_ops;
+static snd_pcm_ops_t snd_cs46xx_playback_indirect_ops;
+static snd_pcm_ops_t snd_cs46xx_capture_ops;
+static snd_pcm_ops_t snd_cs46xx_capture_indirect_ops;
+
 static unsigned short snd_cs46xx_codec_read(cs46xx_t *chip,
 					    unsigned short reg,
 					    int codec_index)
@@ -99,7 +113,7 @@
 	if ((tmp & ACCTL_VFRM) == 0) {
 		snd_printk(KERN_WARNING  "cs46xx: ACCTL_VFRM not set 0x%x\n",tmp);
 		snd_cs46xx_pokeBA0(chip, BA0_ACCTL, (tmp & (~ACCTL_ESYN)) | ACCTL_VFRM );
-		mdelay(50);
+		msleep(50);
 		tmp = snd_cs46xx_peekBA0(chip, BA0_ACCTL + offset);
 		snd_cs46xx_pokeBA0(chip, BA0_ACCTL, tmp | ACCTL_ESYN | ACCTL_VFRM );
 
@@ -1446,7 +1460,7 @@
 }
 
 #ifdef CONFIG_SND_CS46XX_NEW_DSP
-snd_pcm_ops_t snd_cs46xx_playback_rear_ops = {
+static snd_pcm_ops_t snd_cs46xx_playback_rear_ops = {
 	.open =			snd_cs46xx_playback_open_rear,
 	.close =		snd_cs46xx_playback_close,
 	.ioctl =		snd_pcm_lib_ioctl,
@@ -1457,7 +1471,7 @@
 	.pointer =		snd_cs46xx_playback_direct_pointer,
 };
 
-snd_pcm_ops_t snd_cs46xx_playback_indirect_rear_ops = {
+static snd_pcm_ops_t snd_cs46xx_playback_indirect_rear_ops = {
 	.open =			snd_cs46xx_playback_open_rear,
 	.close =		snd_cs46xx_playback_close,
 	.ioctl =		snd_pcm_lib_ioctl,
@@ -1469,7 +1483,7 @@
 	.ack =			snd_cs46xx_playback_transfer,
 };
 
-snd_pcm_ops_t snd_cs46xx_playback_clfe_ops = {
+static snd_pcm_ops_t snd_cs46xx_playback_clfe_ops = {
 	.open =			snd_cs46xx_playback_open_clfe,
 	.close =		snd_cs46xx_playback_close,
 	.ioctl =		snd_pcm_lib_ioctl,
@@ -1480,7 +1494,7 @@
 	.pointer =		snd_cs46xx_playback_direct_pointer,
 };
 
-snd_pcm_ops_t snd_cs46xx_playback_indirect_clfe_ops = {
+static snd_pcm_ops_t snd_cs46xx_playback_indirect_clfe_ops = {
 	.open =			snd_cs46xx_playback_open_clfe,
 	.close =		snd_cs46xx_playback_close,
 	.ioctl =		snd_pcm_lib_ioctl,
@@ -1492,7 +1506,7 @@
 	.ack =			snd_cs46xx_playback_transfer,
 };
 
-snd_pcm_ops_t snd_cs46xx_playback_iec958_ops = {
+static snd_pcm_ops_t snd_cs46xx_playback_iec958_ops = {
 	.open =			snd_cs46xx_playback_open_iec958,
 	.close =		snd_cs46xx_playback_close_iec958,
 	.ioctl =		snd_pcm_lib_ioctl,
@@ -1503,7 +1517,7 @@
 	.pointer =		snd_cs46xx_playback_direct_pointer,
 };
 
-snd_pcm_ops_t snd_cs46xx_playback_indirect_iec958_ops = {
+static snd_pcm_ops_t snd_cs46xx_playback_indirect_iec958_ops = {
 	.open =			snd_cs46xx_playback_open_iec958,
 	.close =		snd_cs46xx_playback_close_iec958,
 	.ioctl =		snd_pcm_lib_ioctl,
@@ -1517,7 +1531,7 @@
 
 #endif
 
-snd_pcm_ops_t snd_cs46xx_playback_ops = {
+static snd_pcm_ops_t snd_cs46xx_playback_ops = {
 	.open =			snd_cs46xx_playback_open,
 	.close =		snd_cs46xx_playback_close,
 	.ioctl =		snd_pcm_lib_ioctl,
@@ -1528,7 +1542,7 @@
 	.pointer =		snd_cs46xx_playback_direct_pointer,
 };
 
-snd_pcm_ops_t snd_cs46xx_playback_indirect_ops = {
+static snd_pcm_ops_t snd_cs46xx_playback_indirect_ops = {
 	.open =			snd_cs46xx_playback_open,
 	.close =		snd_cs46xx_playback_close,
 	.ioctl =		snd_pcm_lib_ioctl,
@@ -1540,7 +1554,7 @@
 	.ack =			snd_cs46xx_playback_transfer,
 };
 
-snd_pcm_ops_t snd_cs46xx_capture_ops = {
+static snd_pcm_ops_t snd_cs46xx_capture_ops = {
 	.open =			snd_cs46xx_capture_open,
 	.close =		snd_cs46xx_capture_close,
 	.ioctl =		snd_pcm_lib_ioctl,
@@ -1551,7 +1565,7 @@
 	.pointer =		snd_cs46xx_capture_direct_pointer,
 };
 
-snd_pcm_ops_t snd_cs46xx_capture_indirect_ops = {
+static snd_pcm_ops_t snd_cs46xx_capture_indirect_ops = {
 	.open =			snd_cs46xx_capture_open,
 	.close =		snd_cs46xx_capture_close,
 	.ioctl =		snd_pcm_lib_ioctl,
@@ -2305,6 +2319,36 @@
 };
 
 #ifdef CONFIG_SND_CS46XX_NEW_DSP
+/* set primary cs4294 codec into Extended Audio Mode */
+static int snd_cs46xx_front_dup_get(snd_kcontrol_t *kcontrol, 
+				    snd_ctl_elem_value_t *ucontrol)
+{
+	cs46xx_t *chip = snd_kcontrol_chip(kcontrol);
+	unsigned short val;
+	val = snd_ac97_read(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX], AC97_CSR_ACMODE);
+	ucontrol->value.integer.value[0] = (val & 0x200) ? 0 : 1;
+	return 0;
+}
+
+static int snd_cs46xx_front_dup_put(snd_kcontrol_t *kcontrol, 
+				    snd_ctl_elem_value_t *ucontrol)
+{
+	cs46xx_t *chip = snd_kcontrol_chip(kcontrol);
+	return snd_ac97_update_bits(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX],
+				    AC97_CSR_ACMODE, 0x200,
+				    ucontrol->value.integer.value[0] ? 0 : 0x200);
+}
+
+static snd_kcontrol_new_t snd_cs46xx_front_dup_ctl = {
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name = "Duplicate Front",
+	.info = snd_mixer_boolean_info,
+	.get = snd_cs46xx_front_dup_get,
+	.put = snd_cs46xx_front_dup_put,
+};
+#endif
+
+#ifdef CONFIG_SND_CS46XX_NEW_DSP
 /* Only available on the Hercules Game Theater XP soundcard */
 static snd_kcontrol_new_t snd_hercules_controls[] __devinitdata = {
 {
@@ -2451,10 +2495,11 @@
 	if (chip->nr_ac97_codecs == 1) {
 		unsigned int id2 = chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]->id & 0xffff;
 		if (id2 == 0x592b || id2 == 0x592d) {
-			/* set primary cs4294 codec into Extended Audio Mode */
-			snd_printdd("setting EAM bit on cs4294 CODEC\n");
-			snd_cs46xx_codec_write(chip, AC97_CSR_ACMODE, 0x200,
-					       CS46XX_PRIMARY_CODEC_INDEX);
+			err = snd_ctl_add(card, snd_ctl_new1(&snd_cs46xx_front_dup_ctl, chip));
+			if (err < 0)
+				return err;
+			snd_ac97_write_cache(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX],
+					     AC97_CSR_ACMODE, 0x200);
 		}
 	}
 	/* do soundcard specific mixer setup */
@@ -3680,7 +3725,6 @@
 	chip->active_ctrl(chip, -chip->amplifier);
 	chip->amplifier = amp_saved; /* restore the status */
 	pci_disable_device(chip->pci);
-	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
 	return 0;
 }
 
@@ -3717,7 +3761,6 @@
 	else
 		chip->active_ctrl(chip, -1); /* disable CLKRUN */
 	chip->amplifier = amp_saved;
-	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
 	return 0;
 }
 #endif /* CONFIG_PM */
@@ -3866,15 +3909,15 @@
 		return err;
 	}
 
-	snd_cs46xx_proc_init(card, chip);
-
-	snd_card_set_pm_callback(card, snd_cs46xx_suspend, snd_cs46xx_resume, chip);
-
 	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
 		snd_cs46xx_free(chip);
 		return err;
 	}
 	
+	snd_cs46xx_proc_init(card, chip);
+
+	snd_card_set_pm_callback(card, snd_cs46xx_suspend, snd_cs46xx_resume, chip);
+
 	chip->active_ctrl(chip, -1); /* disable CLKRUN */
 
 	snd_card_set_dev(card, &pci->dev);
diff -Nru a/sound/pci/cs46xx/cs46xx_lib.h b/sound/pci/cs46xx/cs46xx_lib.h
--- a/sound/pci/cs46xx/cs46xx_lib.h	2005-03-01 23:38:53 -08:00
+++ b/sound/pci/cs46xx/cs46xx_lib.h	2005-03-01 23:38:53 -08:00
@@ -53,18 +53,6 @@
 #define BA1_DWORD_SIZE		(13 * 1024 + 512)
 #define BA1_MEMORY_COUNT	3
 
-extern snd_pcm_ops_t snd_cs46xx_playback_ops;
-extern snd_pcm_ops_t snd_cs46xx_playback_indirect_ops;
-extern snd_pcm_ops_t snd_cs46xx_capture_ops;
-extern snd_pcm_ops_t snd_cs46xx_capture_indirect_ops;
-extern snd_pcm_ops_t snd_cs46xx_playback_rear_ops;
-extern snd_pcm_ops_t snd_cs46xx_playback_indirect_rear_ops;
-extern snd_pcm_ops_t snd_cs46xx_playback_iec958_ops;
-extern snd_pcm_ops_t snd_cs46xx_playback_indirect_iec958_ops;
-extern snd_pcm_ops_t snd_cs46xx_playback_clfe_ops;
-extern snd_pcm_ops_t snd_cs46xx_playback_indirect_clfe_ops;
-
-
 /*
  *  common I/O routines
  */
@@ -99,11 +87,9 @@
 void                   cs46xx_dsp_spos_destroy (cs46xx_t * chip);
 int                    cs46xx_dsp_load_module (cs46xx_t * chip,dsp_module_desc_t * module);
 symbol_entry_t *       cs46xx_dsp_lookup_symbol (cs46xx_t * chip,char * symbol_name,int symbol_type);
-symbol_entry_t *       cs46xx_dsp_lookup_symbol_addr (cs46xx_t * chip,u32 address,int symbol_type);
 int                    cs46xx_dsp_proc_init (snd_card_t * card, cs46xx_t *chip);
 int                    cs46xx_dsp_proc_done (cs46xx_t *chip);
 int                    cs46xx_dsp_scb_and_task_init (cs46xx_t *chip);
-int                    cs46xx_dsp_async_init (cs46xx_t *chip,dsp_scb_descriptor_t * fg_entry);
 int                    snd_cs46xx_download (cs46xx_t *chip,u32 *src,unsigned long offset,
                                             unsigned long len);
 int                    snd_cs46xx_clear_BA1(cs46xx_t *chip,unsigned long offset,unsigned long len);
@@ -120,8 +106,6 @@
 dsp_scb_descriptor_t * cs46xx_dsp_create_scb (cs46xx_t *chip,char * name, u32 * scb_data,u32 dest);
 void                   cs46xx_dsp_proc_free_scb_desc (dsp_scb_descriptor_t * scb);
 void                   cs46xx_dsp_proc_register_scb_desc (cs46xx_t *chip,dsp_scb_descriptor_t * scb);
-dsp_task_descriptor_t * cs46xx_dsp_create_task_tree (cs46xx_t *chip,char * name, 
-                                                     u32 * task_data,u32 dest,int size);
 dsp_scb_descriptor_t * cs46xx_dsp_create_timing_master_scb (cs46xx_t *chip);
 dsp_scb_descriptor_t * cs46xx_dsp_create_codec_out_scb(cs46xx_t * chip,char * codec_name,
                                                        u16 channel_disp,u16 fifo_addr,
@@ -136,21 +120,11 @@
                                                       dsp_scb_descriptor_t * parent_scb,
                                                       int scb_child_type);
 void                   cs46xx_dsp_remove_scb (cs46xx_t *chip,dsp_scb_descriptor_t * scb);
-dsp_scb_descriptor_t * cs46xx_dsp_create_generic_scb (cs46xx_t *chip,char * name, 
-                                                      u32 * scb_data,u32 dest,
-                                                      char * task_entry_name,
-                                                      dsp_scb_descriptor_t * parent_scb,
-                                                      int scb_child_type);
 dsp_scb_descriptor_t *  cs46xx_dsp_create_codec_in_scb(cs46xx_t * chip,char * codec_name,
                                                        u16 channel_disp,u16 fifo_addr,
                                                        u16 sample_buffer_addr,
                                                        u32 dest,dsp_scb_descriptor_t * parent_scb,
                                                        int scb_child_type);
-dsp_scb_descriptor_t * cs46xx_dsp_create_pcm_reader_scb(cs46xx_t * chip,char * scb_name,
-                                                        u16 sample_buffer_addr,u32 dest,
-                                                        int virtual_channel,u32 playback_hw_addr,
-                                                        dsp_scb_descriptor_t * parent_scb,
-                                                        int scb_child_type);
 dsp_scb_descriptor_t *  cs46xx_dsp_create_src_task_scb(cs46xx_t * chip,char * scb_name,
 						       int sample_rate,
                                                        u16 src_buffer_addr,
@@ -169,15 +143,6 @@
                                                             u32 dest,
                                                             dsp_scb_descriptor_t * parent_scb,
                                                             int scb_child_type);
-dsp_scb_descriptor_t *  cs46xx_dsp_create_pcm_serial_input_scb(cs46xx_t * chip,char * scb_name,u32 dest,
-                                                               dsp_scb_descriptor_t * input_scb,
-                                                               dsp_scb_descriptor_t * parent_scb,
-                                                               int scb_child_type);
-dsp_scb_descriptor_t * cs46xx_dsp_create_asynch_fg_tx_scb(cs46xx_t * chip,char * scb_name,u32 dest,
-                                                          u16 hfg_scb_address,
-                                                          u16 asynch_buffer_address,
-                                                          dsp_scb_descriptor_t * parent_scb,
-                                                          int scb_child_type);
 dsp_scb_descriptor_t * cs46xx_dsp_create_asynch_fg_rx_scb(cs46xx_t * chip,char * scb_name,u32 dest,
                                                           u16 hfg_scb_address,
                                                           u16 asynch_buffer_address,
@@ -190,11 +155,6 @@
                                                              u16 mix_buffer_addr,u16 writeback_spb,u32 dest,
                                                              dsp_scb_descriptor_t * parent_scb,
                                                              int scb_child_type);
-dsp_scb_descriptor_t *  cs46xx_dsp_create_output_snoop_scb(cs46xx_t * chip,char * scb_name,u32 dest,
-                                                           u16 snoop_buffer_address,
-                                                           dsp_scb_descriptor_t * snoop_scb,
-                                                           dsp_scb_descriptor_t * parent_scb,
-                                                           int scb_child_type);
 dsp_scb_descriptor_t *  cs46xx_dsp_create_magic_snoop_scb(cs46xx_t * chip,char * scb_name,u32 dest,
                                                           u16 snoop_buffer_address,
                                                           dsp_scb_descriptor_t * snoop_scb,
diff -Nru a/sound/pci/cs46xx/dsp_spos.c b/sound/pci/cs46xx/dsp_spos.c
--- a/sound/pci/cs46xx/dsp_spos.c	2005-03-01 23:39:19 -08:00
+++ b/sound/pci/cs46xx/dsp_spos.c	2005-03-01 23:39:19 -08:00
@@ -37,6 +37,8 @@
 #include "cs46xx_lib.h"
 #include "dsp_spos.h"
 
+static int cs46xx_dsp_async_init (cs46xx_t *chip, dsp_scb_descriptor_t * fg_entry);
+
 static wide_opcode_t wide_opcodes[] = { 
 	WIDE_FOR_BEGIN_LOOP,
 	WIDE_FOR_BEGIN_LOOP2,
@@ -289,15 +291,9 @@
 		cs46xx_dsp_proc_free_scb_desc ( (ins->scbs + i) );
 	}
 
-	if (ins->code.data)
-		kfree(ins->code.data);
-
-	if (ins->symbol_table.symbols)
-		vfree(ins->symbol_table.symbols);
-
-	if (ins->modules)
-		kfree(ins->modules);
-	
+	kfree(ins->code.data);
+	vfree(ins->symbol_table.symbols);
+	kfree(ins->modules);
 	kfree(ins);
 	up(&chip->spos_mutex);
 }
@@ -439,7 +435,7 @@
 }
 
 
-symbol_entry_t * cs46xx_dsp_lookup_symbol_addr (cs46xx_t * chip, u32 address, int symbol_type)
+static symbol_entry_t * cs46xx_dsp_lookup_symbol_addr (cs46xx_t * chip, u32 address, int symbol_type)
 {
 	int i;
 	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
@@ -914,7 +910,7 @@
 	int i;
 
 	for (i = 0; i < size; ++i) {
-		if (debug_tree) printk ("addr %p, val %08x\n", spdst,task_data[i]);
+		if (debug_tree) printk ("addr %p, val %08x\n",spdst,task_data[i]);
 		writel(task_data[i],spdst);
 		spdst += sizeof(u32);
 	}
@@ -928,7 +924,7 @@
 	int i;
 
 	for (i = 0; i < 0x10; ++i) {
-		if (debug_scb) printk ("addr %p, val %08x\n", spdst,scb_data[i]);
+		if (debug_scb) printk ("addr %p, val %08x\n",spdst,scb_data[i]);
 		writel(scb_data[i],spdst);
 		spdst += sizeof(u32);
 	}
@@ -1019,7 +1015,7 @@
 }
 
 
-dsp_task_descriptor_t *  cs46xx_dsp_create_task_tree (cs46xx_t *chip,char * name, u32 * task_data,u32 dest,int size)
+static dsp_task_descriptor_t *  cs46xx_dsp_create_task_tree (cs46xx_t *chip,char * name, u32 * task_data,u32 dest,int size)
 {
 	dsp_task_descriptor_t * desc;
 
@@ -1452,7 +1448,7 @@
 	return -EINVAL;
 }
 
-int cs46xx_dsp_async_init (cs46xx_t *chip, dsp_scb_descriptor_t * fg_entry)
+static int cs46xx_dsp_async_init (cs46xx_t *chip, dsp_scb_descriptor_t * fg_entry)
 {
 	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
 	symbol_entry_t * s16_async_codec_input_task;
diff -Nru a/sound/pci/cs46xx/dsp_spos_scb_lib.c b/sound/pci/cs46xx/dsp_spos_scb_lib.c
--- a/sound/pci/cs46xx/dsp_spos_scb_lib.c	2005-03-01 23:39:16 -08:00
+++ b/sound/pci/cs46xx/dsp_spos_scb_lib.c	2005-03-01 23:39:16 -08:00
@@ -342,7 +342,7 @@
 	return scb;
 }
 
-dsp_scb_descriptor_t * 
+static dsp_scb_descriptor_t * 
 cs46xx_dsp_create_generic_scb (cs46xx_t *chip,char * name, u32 * scb_data,u32 dest,
                                char * task_entry_name,
                                dsp_scb_descriptor_t * parent_scb,
@@ -481,7 +481,7 @@
 }
 
 
-dsp_scb_descriptor_t * 
+static dsp_scb_descriptor_t * 
 cs46xx_dsp_create_pcm_reader_scb(cs46xx_t * chip,char * scb_name,
                                  u16 sample_buffer_addr,u32 dest,
                                  int virtual_channel, u32 playback_hw_addr,
@@ -687,6 +687,7 @@
 	return scb;
 }
 
+#if 0 /* not used */
 dsp_scb_descriptor_t * 
 cs46xx_dsp_create_filter_scb(cs46xx_t * chip,char * scb_name,
 			     u16 buffer_addr,u32 dest,
@@ -735,6 +736,7 @@
 
  	return scb;
 }
+#endif /* not used */
 
 dsp_scb_descriptor_t * 
 cs46xx_dsp_create_mix_only_scb(cs46xx_t * chip,char * scb_name,
@@ -874,7 +876,7 @@
 }
 
 
-dsp_scb_descriptor_t * 
+static dsp_scb_descriptor_t * 
 cs46xx_dsp_create_pcm_serial_input_scb(cs46xx_t * chip,char * scb_name,u32 dest,
                                        dsp_scb_descriptor_t * input_scb,
                                        dsp_scb_descriptor_t * parent_scb,
@@ -917,7 +919,7 @@
 }
 
 
-dsp_scb_descriptor_t * 
+static dsp_scb_descriptor_t * 
 cs46xx_dsp_create_asynch_fg_tx_scb(cs46xx_t * chip,char * scb_name,u32 dest,
                                    u16 hfg_scb_address,
                                    u16 asynch_buffer_address,
@@ -1013,6 +1015,7 @@
 }
 
 
+#if 0 /* not used */
 dsp_scb_descriptor_t * 
 cs46xx_dsp_create_output_snoop_scb(cs46xx_t * chip,char * scb_name,u32 dest,
                                    u16 snoop_buffer_address,
@@ -1052,6 +1055,7 @@
 					    scb_child_type);
 	return scb;
 }
+#endif /* not used */
 
 
 dsp_scb_descriptor_t * 
diff -Nru a/sound/pci/cs46xx/imgs/cwcdma.h b/sound/pci/cs46xx/imgs/cwcdma.h
--- a/sound/pci/cs46xx/imgs/cwcdma.h	2005-03-01 23:38:55 -08:00
+++ b/sound/pci/cs46xx/imgs/cwcdma.h	2005-03-01 23:38:55 -08:00
@@ -3,7 +3,7 @@
 #ifndef __HEADER_cwcdma_H__
 #define __HEADER_cwcdma_H__
 
-symbol_entry_t cwcdma_symbols[] = {
+static symbol_entry_t cwcdma_symbols[] = {
   { 0x8000, "EXECCHILD",0x03 },
   { 0x8001, "EXECCHILD_98",0x03 },
   { 0x8003, "EXECCHILD_PUSH1IND",0x03 },
@@ -33,7 +33,7 @@
   { 0x0018, "#CODE_END",0x00 },
 }; /* cwcdma symbols */
 
-u32 cwcdma_code[] = {
+static u32 cwcdma_code[] = {
 /* OVERLAYBEGINADDRESS */
 /* 0000 */ 0x00002731,0x00001400,0x0004c108,0x000e5044,
 /* 0002 */ 0x0005f608,0x00000000,0x000007ae,0x000be300,
@@ -51,11 +51,11 @@
 
 /* #CODE_END */
 
-segment_desc_t cwcdma_segments[] = {
+static segment_desc_t cwcdma_segments[] = {
   { SEGTYPE_SP_PROGRAM, 0x00000000, 0x00000030, cwcdma_code },
 };
 
-dsp_module_desc_t cwcdma_module = {
+static dsp_module_desc_t cwcdma_module = {
   "cwcdma",
   {
     27,
diff -Nru a/sound/pci/emu10k1/Makefile b/sound/pci/emu10k1/Makefile
--- a/sound/pci/emu10k1/Makefile	2005-03-01 23:38:56 -08:00
+++ b/sound/pci/emu10k1/Makefile	2005-03-01 23:38:56 -08:00
@@ -5,8 +5,9 @@
 
 snd-emu10k1-objs := emu10k1.o emu10k1_main.o \
 		    irq.o memory.o voice.o emumpu401.o emupcm.o io.o \
-		    emuproc.o emumixer.o emufx.o
+		    emuproc.o emumixer.o emufx.o timer.o
 snd-emu10k1-synth-objs := emu10k1_synth.o emu10k1_callback.o emu10k1_patch.o
+snd-emu10k1x-objs := emu10k1x.o
 
 #
 # this function returns:
@@ -19,3 +20,4 @@
 # Toplevel Module Dependency
 obj-$(CONFIG_SND_EMU10K1) += snd-emu10k1.o
 obj-$(call sequencer,$(CONFIG_SND_EMU10K1)) += snd-emu10k1-synth.o
+obj-$(CONFIG_SND_EMU10K1X) += snd-emu10k1x.o
diff -Nru a/sound/pci/emu10k1/emu10k1.c b/sound/pci/emu10k1/emu10k1.c
--- a/sound/pci/emu10k1/emu10k1.c	2005-03-01 23:38:44 -08:00
+++ b/sound/pci/emu10k1/emu10k1.c	2005-03-01 23:38:44 -08:00
@@ -2,6 +2,9 @@
  *  The driver for the EMU10K1 (SB Live!) based soundcards
  *  Copyright (c) by Jaroslav Kysela <perex@suse.cz>
  *
+ *  Copyright (c) by James Courtier-Dutton <James@superbug.demon.co.uk>
+ *      Added support for Audigy 2 Value.
+ *
  *
  *   This program is free software; you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License as published by
@@ -17,6 +20,7 @@
  *   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>
@@ -68,12 +72,27 @@
 module_param_array(enable_ir, bool, NULL, 0444);
 MODULE_PARM_DESC(enable_ir, "Enable IR.");
 
+/*
+ * Class 0401: 1102:0008 (rev 00) Subsystem: 1102:1001 -> Audigy2 Value  Model:SB0400
+ */
 static struct pci_device_id snd_emu10k1_ids[] = {
 	{ 0x1102, 0x0002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },	/* EMU10K1 */
 	{ 0x1102, 0x0004, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 },	/* Audigy */
+	{ 0x1102, 0x0008, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 },	/* Audigy 2 Value SB0400 */
 	{ 0, }
 };
 
+/*
+ * Audigy 2 Value notes:
+ * A_IOCFG Input (GPIO)
+ * 0x400  = Front analog jack plugged in. (Green socket)
+ * 0x1000 = Read analog jack plugged in. (Black socket)
+ * 0x2000 = Center/LFE analog jack plugged in. (Orange socket)
+ * A_IOCFG Output (GPIO)
+ * 0x60 = Sound out of front Left.
+ * Win sets it to 0xXX61
+ */
+
 MODULE_DEVICE_TABLE(pci, snd_emu10k1_ids);
 
 static int __devinit snd_card_emu10k1_probe(struct pci_dev *pci,
@@ -124,6 +143,12 @@
 		snd_card_free(card);
 		return err;
 	}
+	
+	if ((err = snd_emu10k1_timer(emu, 0)) < 0) {
+		snd_card_free(card);
+		return err;
+	}
+
 	if (emu->audigy) {
 		if ((err = snd_emu10k1_audigy_midi(emu)) < 0) {
 			snd_card_free(card);
@@ -155,7 +180,10 @@
 	}
 #endif
  
-	if (emu->audigy && (emu->revision == 4) ) {
+	if (emu->audigy && (emu->serial == 0x10011102) ) {
+		strcpy(card->driver, "Audigy2");
+		strcpy(card->shortname, "Sound Blaster Audigy2_Value");
+	} else if (emu->audigy && (emu->revision == 4) ) {
 		strcpy(card->driver, "Audigy2");
 		strcpy(card->shortname, "Sound Blaster Audigy2");
 	} else if (emu->audigy) {
@@ -168,7 +196,7 @@
 		strcpy(card->driver, "EMU10K1");
 		strcpy(card->shortname, "Sound Blaster Live!");
 	}
-	sprintf(card->longname, "%s (rev.%d) at 0x%lx, irq %i", card->shortname, emu->revision, emu->port, emu->irq);
+	sprintf(card->longname, "%s (rev.%d, serial:0x%x) at 0x%lx, irq %i", card->shortname, emu->revision, emu->serial, emu->port, emu->irq);
 
 	if ((err = snd_card_register(card)) < 0) {
 		snd_card_free(card);
diff -Nru a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c
--- a/sound/pci/emu10k1/emu10k1_main.c	2005-03-01 23:39:17 -08:00
+++ b/sound/pci/emu10k1/emu10k1_main.c	2005-03-01 23:39:17 -08:00
@@ -3,6 +3,10 @@
  *                   Creative Labs, Inc.
  *  Routines for control of EMU10K1 chips
  *
+ *  Copyright (c) by James Courtier-Dutton <James@superbug.demon.co.uk>
+ *      Added support for Audigy 2 Value.
+ *
+ *
  *  BUGS:
  *    --
  *
@@ -183,6 +187,26 @@
 		outl(0x6E0000, emu->port + 0x20);
 		outl(0xFF00FF00, emu->port + 0x24);
 	}
+	if (emu->audigy && (emu->serial == 0x10011102) ) { /* audigy2 Value */
+		/* Hacks for Alice3 to work independent of haP16V driver */
+		u32 tmp;
+
+		snd_printk(KERN_ERR "Audigy2 value:Special config.\n");
+		//Setup SRCMulti_I2S SamplingRate
+		tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0);
+		tmp &= 0xfffff1ff;
+		tmp |= (0x2<<9);
+		snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, 0, tmp);
+
+		/* Setup SRCSel (Enable Spdif,I2S SRCMulti) */
+		outl(0x600000, emu->port + 0x20);
+		outl(0x14, emu->port + 0x24);
+
+		/* Setup SRCMulti Input Audio Enable */
+		outl(0x7b0000, emu->port + 0x20);
+		outl(0xFF000000, emu->port + 0x24);
+	}
+
 
 	/*
 	 *  Clear page with silence & setup all pointers to this page
@@ -267,6 +291,9 @@
 			 * 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 */
+			/* Unmute Analog now. */
+			outl(inl(emu->port + A_IOCFG) | 0x0060, emu->port + A_IOCFG);
 		} else {
 			/* Disable routing from AC97 line out to Front speakers */
 			outl(inl(emu->port + A_IOCFG) | 0x0080, emu->port + A_IOCFG);
@@ -553,10 +580,8 @@
 		snd_dma_free_pages(&emu->silent_page);
 	if (emu->ptb_pages.area)
 		snd_dma_free_pages(&emu->ptb_pages);
-	if (emu->page_ptr_table)
-		vfree(emu->page_ptr_table);
-	if (emu->page_addr_table)
-		vfree(emu->page_addr_table);
+	vfree(emu->page_ptr_table);
+	vfree(emu->page_addr_table);
 	if (emu->irq >= 0)
 		free_irq(emu->irq, (void *)emu);
 	if (emu->port)
@@ -590,7 +615,7 @@
 	*remu = NULL;
 
 	// is_audigy = (int)pci->driver_data;
-	is_audigy = (pci->device == 0x0004);
+	is_audigy = (pci->device == 0x0004) || ( (pci->device == 0x0008) );
 
 	/* enable PCI device */
 	if ((err = pci_enable_device(pci)) < 0)
@@ -689,7 +714,7 @@
 		emu->no_ac97 = 1;	
 	}
 	
-	if (emu->revision == 4 && emu->model == 0x2002) {
+	if (emu->revision == 4 && (emu->model == 0x2001 || emu->model == 0x2002)) {
 		/* Audigy 2 ZS */
 		snd_printdd(KERN_INFO "Audigy2 ZS is detected. setting 7.1 mode.\n");
 		emu->spk71 = 1;
diff -Nru a/sound/pci/emu10k1/emu10k1_synth.c b/sound/pci/emu10k1/emu10k1_synth.c
--- a/sound/pci/emu10k1/emu10k1_synth.c	2005-03-01 23:38:53 -08:00
+++ b/sound/pci/emu10k1/emu10k1_synth.c	2005-03-01 23:38:53 -08:00
@@ -28,7 +28,7 @@
 /*
  * create a new hardware dependent device for Emu10k1
  */
-int snd_emu10k1_synth_new_device(snd_seq_device_t *dev)
+static int snd_emu10k1_synth_new_device(snd_seq_device_t *dev)
 {
 	snd_emux_t *emu;
 	emu10k1_t *hw;
@@ -76,7 +76,7 @@
 	return 0;
 }
 
-int snd_emu10k1_synth_delete_device(snd_seq_device_t *dev)
+static int snd_emu10k1_synth_delete_device(snd_seq_device_t *dev)
 {
 	snd_emux_t *emu;
 	emu10k1_t *hw;
diff -Nru a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/sound/pci/emu10k1/emu10k1x.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,1644 @@
+/*
+ *  Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com>
+ *  Driver EMU10K1X chips
+ *
+ *  Parts of this code were adapted from audigyls.c driver which is
+ *  Copyright (c) by James Courtier-Dutton <James@superbug.demon.co.uk>
+ *
+ *  BUGS:
+ *    --
+ *
+ *  TODO:
+ *
+ *  Chips (SB0200 model):
+ *    - EMU10K1X-DBQ
+ *    - STAC 9708T
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You 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/interrupt.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/moduleparam.h>
+#include <sound/core.h>
+#include <sound/initval.h>
+#include <sound/pcm.h>
+#include <sound/ac97_codec.h>
+#include <sound/info.h>
+#include <sound/rawmidi.h>
+
+MODULE_AUTHOR("Francisco Moraes <fmoraes@nc.rr.com>");
+MODULE_DESCRIPTION("EMU10K1X");
+MODULE_LICENSE("GPL");
+MODULE_SUPPORTED_DEVICE("{{Dell Creative Labs,SB Live!}");
+
+// module parameters (see "Module Parameters")
+static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
+static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
+static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
+
+module_param_array(index, int, NULL, 0444);
+MODULE_PARM_DESC(index, "Index value for the EMU10K1X soundcard.");
+module_param_array(id, charp, NULL, 0444);
+MODULE_PARM_DESC(id, "ID string for the EMU10K1X soundcard.");
+module_param_array(enable, bool, NULL, 0444);
+MODULE_PARM_DESC(enable, "Enable the EMU10K1X soundcard.");
+
+
+// some definitions were borrowed from emu10k1 driver as they seem to be the same
+/************************************************************************************************/
+/* PCI function 0 registers, address = <val> + PCIBASE0						*/
+/************************************************************************************************/
+
+#define PTR			0x00		/* Indexed register set pointer register	*/
+						/* NOTE: The CHANNELNUM and ADDRESS words can	*/
+						/* be modified independently of each other.	*/
+
+#define DATA			0x04		/* Indexed register set data register		*/
+
+#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_MIDITRANSBUFEMPTY   0x00000001	/* MIDI UART transmit buffer empty		*/
+#define IPR_MIDIRECVBUFEMPTY    0x00000002	/* MIDI UART receive buffer empty		*/
+#define IPR_CH_0_LOOP           0x00000800      /* Channel 0 loop                               */
+#define IPR_CH_0_HALF_LOOP      0x00000100      /* Channel 0 half loop                          */
+#define IPR_CAP_0_LOOP          0x00080000      /* Channel capture loop                         */
+#define IPR_CAP_0_HALF_LOOP     0x00010000      /* Channel capture half loop                    */
+
+#define INTE			0x0c		/* Interrupt enable register			*/
+#define INTE_MIDITXENABLE       0x00000001	/* Enable MIDI transmit-buffer-empty interrupts	*/
+#define INTE_MIDIRXENABLE       0x00000002	/* Enable MIDI receive-buffer-empty interrupts	*/
+#define INTE_CH_0_LOOP          0x00000800      /* Channel 0 loop                               */
+#define INTE_CH_0_HALF_LOOP     0x00000100      /* Channel 0 half loop                          */
+#define INTE_CAP_0_LOOP         0x00080000      /* Channel capture loop                         */
+#define INTE_CAP_0_HALF_LOOP    0x00010000      /* Channel capture half loop                    */
+
+#define HCFG			0x14		/* Hardware config register			*/
+
+#define HCFG_LOCKSOUNDCACHE	0x00000008	/* 1 = Cancel bustmaster accesses to soundcache */
+						/* NOTE: This should generally never be used.  	*/
+#define HCFG_AUDIOENABLE	0x00000001	/* 0 = CODECs transmit zero-valued samples	*/
+						/* Should be set to 1 when the EMU10K1 is	*/
+						/* completely initialized.			*/
+#define GPIO			0x18		/* Defaults: 00001080-Analog, 00001000-SPDIF.   */
+
+
+#define AC97DATA		0x1c		/* AC97 register set data register (16 bit)	*/
+
+#define AC97ADDRESS		0x1e		/* AC97 register set address register (8 bit)	*/
+
+/********************************************************************************************************/
+/* Emu10k1x pointer-offset register set, accessed through the PTR and DATA registers			*/
+/********************************************************************************************************/
+#define PLAYBACK_LIST_ADDR	0x00		/* Base DMA address of a list of pointers to each period/size */
+						/* One list entry: 4 bytes for DMA address, 
+						 * 4 bytes for period_size << 16.
+						 * One list entry is 8 bytes long.
+						 * One list entry for each period in the buffer.
+						 */
+#define PLAYBACK_LIST_SIZE	0x01		/* Size of list in bytes << 16. E.g. 8 periods -> 0x00380000  */
+#define PLAYBACK_LIST_PTR	0x02		/* Pointer to the current period being played */
+#define PLAYBACK_DMA_ADDR	0x04		/* Playback DMA addresss */
+#define PLAYBACK_PERIOD_SIZE	0x05		/* Playback period size */
+#define PLAYBACK_POINTER	0x06		/* Playback period pointer. Sample currently in DAC */
+#define PLAYBACK_UNKNOWN1       0x07
+#define PLAYBACK_UNKNOWN2       0x08
+
+/* Only one capture channel supported */
+#define CAPTURE_DMA_ADDR	0x10		/* Capture DMA address */
+#define CAPTURE_BUFFER_SIZE	0x11		/* Capture buffer size */
+#define CAPTURE_POINTER		0x12		/* Capture buffer pointer. Sample currently in ADC */
+#define CAPTURE_UNKNOWN         0x13
+
+/* From 0x20 - 0x3f, last samples played on each channel */
+
+#define TRIGGER_CHANNEL         0x40            /* Trigger channel playback                     */
+#define TRIGGER_CHANNEL_0       0x00000001      /* Trigger channel 0                            */
+#define TRIGGER_CHANNEL_1       0x00000002      /* Trigger channel 1                            */
+#define TRIGGER_CHANNEL_2       0x00000004      /* Trigger channel 2                            */
+#define TRIGGER_CAPTURE         0x00000100      /* Trigger capture channel                      */
+
+#define ROUTING                 0x41            /* Setup sound routing ?                        */
+#define ROUTING_FRONT_LEFT      0x00000001
+#define ROUTING_FRONT_RIGHT     0x00000002
+#define ROUTING_REAR_LEFT       0x00000004
+#define ROUTING_REAR_RIGHT      0x00000008
+#define ROUTING_CENTER_LFE      0x00010000
+
+#define SPCS0			0x42		/* SPDIF output Channel Status 0 register	*/
+
+#define SPCS1			0x43		/* SPDIF output Channel Status 1 register	*/
+
+#define SPCS2			0x44		/* SPDIF output Channel Status 2 register	*/
+
+#define SPCS_CLKACCYMASK	0x30000000	/* Clock accuracy				*/
+#define SPCS_CLKACCY_1000PPM	0x00000000	/* 1000 parts per million			*/
+#define SPCS_CLKACCY_50PPM	0x10000000	/* 50 parts per million				*/
+#define SPCS_CLKACCY_VARIABLE	0x20000000	/* Variable accuracy				*/
+#define SPCS_SAMPLERATEMASK	0x0f000000	/* Sample rate					*/
+#define SPCS_SAMPLERATE_44	0x00000000	/* 44.1kHz sample rate				*/
+#define SPCS_SAMPLERATE_48	0x02000000	/* 48kHz sample rate				*/
+#define SPCS_SAMPLERATE_32	0x03000000	/* 32kHz sample rate				*/
+#define SPCS_CHANNELNUMMASK	0x00f00000	/* Channel number				*/
+#define SPCS_CHANNELNUM_UNSPEC	0x00000000	/* Unspecified channel number			*/
+#define SPCS_CHANNELNUM_LEFT	0x00100000	/* Left channel					*/
+#define SPCS_CHANNELNUM_RIGHT	0x00200000	/* Right channel				*/
+#define SPCS_SOURCENUMMASK	0x000f0000	/* Source number				*/
+#define SPCS_SOURCENUM_UNSPEC	0x00000000	/* Unspecified source number			*/
+#define SPCS_GENERATIONSTATUS	0x00008000	/* Originality flag (see IEC-958 spec)		*/
+#define SPCS_CATEGORYCODEMASK	0x00007f00	/* Category code (see IEC-958 spec)		*/
+#define SPCS_MODEMASK		0x000000c0	/* Mode (see IEC-958 spec)			*/
+#define SPCS_EMPHASISMASK	0x00000038	/* Emphasis					*/
+#define SPCS_EMPHASIS_NONE	0x00000000	/* No emphasis					*/
+#define SPCS_EMPHASIS_50_15	0x00000008	/* 50/15 usec 2 channel				*/
+#define SPCS_COPYRIGHT		0x00000004	/* Copyright asserted flag -- do not modify	*/
+#define SPCS_NOTAUDIODATA	0x00000002	/* 0 = Digital audio, 1 = not audio		*/
+#define SPCS_PROFESSIONAL	0x00000001	/* 0 = Consumer (IEC-958), 1 = pro (AES3-1992)	*/
+
+#define SPDIF_SELECT		0x45		/* Enables SPDIF or Analogue outputs 0-Analogue, 0x700-SPDIF */
+
+/* This is the MPU port on the card                      					*/
+#define MUDATA		0x47
+#define MUCMD		0x48
+#define MUSTAT		MUCMD
+
+/* From 0x50 - 0x5f, last samples captured */
+
+/**
+ * The hardware has 3 channels for playback and 1 for capture.
+ *  - channel 0 is the front channel
+ *  - channel 1 is the rear channel
+ *  - channel 2 is the center/lfe chanel
+ * Volume is controlled by the AC97 for the front and rear channels by
+ * the PCM Playback Volume, Sigmatel Surround Playback Volume and 
+ * Surround Playback Volume. The Sigmatel 4-Speaker Stereo switch affects
+ * the front/rear channel mixing in the REAR OUT jack. When using the
+ * 4-Speaker Stereo, both front and rear channels will be mixed in the
+ * REAR OUT.
+ * The center/lfe channel has no volume control and cannot be muted during
+ * playback.
+ */
+
+typedef struct snd_emu10k1x_voice emu10k1x_voice_t;
+typedef struct snd_emu10k1x emu10k1x_t;
+typedef struct snd_emu10k1x_pcm emu10k1x_pcm_t;
+
+struct snd_emu10k1x_voice {
+	emu10k1x_t *emu;
+	int number;
+	int use;
+  
+	emu10k1x_pcm_t *epcm;
+};
+
+struct snd_emu10k1x_pcm {
+	emu10k1x_t *emu;
+	snd_pcm_substream_t *substream;
+	emu10k1x_voice_t *voice;
+	unsigned short running;
+};
+
+typedef struct {
+	struct snd_emu10k1x *emu;
+	snd_rawmidi_t *rmidi;
+	snd_rawmidi_substream_t *substream_input;
+	snd_rawmidi_substream_t *substream_output;
+	unsigned int midi_mode;
+	spinlock_t input_lock;
+	spinlock_t output_lock;
+	spinlock_t open_lock;
+	int tx_enable, rx_enable;
+	int port;
+	int ipr_tx, ipr_rx;
+	void (*interrupt)(emu10k1x_t *emu, unsigned int status);
+} emu10k1x_midi_t;
+
+// definition of the chip-specific record
+struct snd_emu10k1x {
+	snd_card_t *card;
+	struct pci_dev *pci;
+
+	unsigned long port;
+	struct resource *res_port;
+	int irq;
+
+	unsigned int revision;		/* chip revision */
+	unsigned int serial;            /* serial number */
+	unsigned short model;		/* subsystem id */
+
+	spinlock_t emu_lock;
+	spinlock_t voice_lock;
+
+	ac97_t *ac97;
+	snd_pcm_t *pcm;
+
+	emu10k1x_voice_t voices[3];
+	emu10k1x_voice_t capture_voice;
+	u32 spdif_bits[3]; // SPDIF out setup
+
+	struct snd_dma_buffer dma_buffer;
+
+	emu10k1x_midi_t midi;
+};
+
+/* hardware definition */
+static snd_pcm_hardware_t snd_emu10k1x_playback_hw = {
+	.info =			(SNDRV_PCM_INFO_MMAP | 
+				 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,
+	.channels_min =		2,
+	.channels_max =		2,
+	.buffer_bytes_max =	(32*1024),
+	.period_bytes_min =	64,
+	.period_bytes_max =	(16*1024),
+	.periods_min =		2,
+	.periods_max =		8,
+	.fifo_size =		0,
+};
+
+static snd_pcm_hardware_t snd_emu10k1x_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_S16_LE,
+	.rates =		SNDRV_PCM_RATE_48000,
+	.rate_min =		48000,
+	.rate_max =		48000,
+	.channels_min =		2,
+	.channels_max =		2,
+	.buffer_bytes_max =	(32*1024),
+	.period_bytes_min =	64,
+	.period_bytes_max =	(16*1024),
+	.periods_min =		2,
+	.periods_max =		2,
+	.fifo_size =		0,
+};
+
+static unsigned int snd_emu10k1x_ptr_read(emu10k1x_t * emu, 
+					  unsigned int reg, 
+					  unsigned int chn)
+{
+	unsigned long flags;
+	unsigned int regptr, val;
+  
+	regptr = (reg << 16) | chn;
+
+	spin_lock_irqsave(&emu->emu_lock, flags);
+	outl(regptr, emu->port + PTR);
+	val = inl(emu->port + DATA);
+	spin_unlock_irqrestore(&emu->emu_lock, flags);
+	return val;
+}
+
+static void snd_emu10k1x_ptr_write(emu10k1x_t *emu, 
+				   unsigned int reg, 
+				   unsigned int chn, 
+				   unsigned int data)
+{
+	unsigned int regptr;
+	unsigned long flags;
+
+	regptr = (reg << 16) | chn;
+
+	spin_lock_irqsave(&emu->emu_lock, flags);
+	outl(regptr, emu->port + PTR);
+	outl(data, emu->port + DATA);
+	spin_unlock_irqrestore(&emu->emu_lock, flags);
+}
+
+static void snd_emu10k1x_intr_enable(emu10k1x_t *emu, unsigned int intrenb)
+{
+	unsigned long flags;
+	unsigned int enable;
+  
+	spin_lock_irqsave(&emu->emu_lock, flags);
+	enable = inl(emu->port + INTE) | intrenb;
+	outl(enable, emu->port + INTE);
+	spin_unlock_irqrestore(&emu->emu_lock, flags);
+}
+
+static void snd_emu10k1x_intr_disable(emu10k1x_t *emu, unsigned int intrenb)
+{
+	unsigned long flags;
+	unsigned int enable;
+  
+	spin_lock_irqsave(&emu->emu_lock, flags);
+	enable = inl(emu->port + INTE) & ~intrenb;
+	outl(enable, emu->port + INTE);
+	spin_unlock_irqrestore(&emu->emu_lock, flags);
+}
+
+static void snd_emu10k1x_gpio_write(emu10k1x_t *emu, unsigned int value)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&emu->emu_lock, flags);
+	outl(value, emu->port + GPIO);
+	spin_unlock_irqrestore(&emu->emu_lock, flags);
+}
+
+static void snd_emu10k1x_pcm_free_substream(snd_pcm_runtime_t *runtime)
+{
+	emu10k1x_pcm_t *epcm = runtime->private_data;
+  
+	if (epcm)
+		kfree(epcm);
+}
+
+static void snd_emu10k1x_pcm_interrupt(emu10k1x_t *emu, emu10k1x_voice_t *voice)
+{
+	emu10k1x_pcm_t *epcm;
+
+	if ((epcm = voice->epcm) == NULL)
+		return;
+	if (epcm->substream == NULL)
+		return;
+#if 0
+	snd_printk(KERN_INFO "IRQ: position = 0x%x, period = 0x%x, size = 0x%x\n",
+		   epcm->substream->ops->pointer(epcm->substream),
+		   snd_pcm_lib_period_bytes(epcm->substream),
+		   snd_pcm_lib_buffer_bytes(epcm->substream));
+#endif
+	snd_pcm_period_elapsed(epcm->substream);
+}
+
+/* open callback */
+static int snd_emu10k1x_playback_open(snd_pcm_substream_t *substream)
+{
+	emu10k1x_t *chip = snd_pcm_substream_chip(substream);
+	emu10k1x_pcm_t *epcm;
+	snd_pcm_runtime_t *runtime = substream->runtime;
+	int err;
+
+	if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0) {
+		return err;
+	}
+	if ((err = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 64)) < 0)
+                return err;
+
+	epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL);
+	if (epcm == NULL)
+		return -ENOMEM;
+	epcm->emu = chip;
+	epcm->substream = substream;
+  
+	runtime->private_data = epcm;
+	runtime->private_free = snd_emu10k1x_pcm_free_substream;
+  
+	runtime->hw = snd_emu10k1x_playback_hw;
+
+	return 0;
+}
+
+/* close callback */
+static int snd_emu10k1x_playback_close(snd_pcm_substream_t *substream)
+{
+	return 0;
+}
+
+/* hw_params callback */
+static int snd_emu10k1x_pcm_hw_params(snd_pcm_substream_t *substream,
+				      snd_pcm_hw_params_t * hw_params)
+{
+	snd_pcm_runtime_t *runtime = substream->runtime;
+	emu10k1x_pcm_t *epcm = runtime->private_data;
+
+	if (! epcm->voice) {
+		epcm->voice = &epcm->emu->voices[substream->pcm->device];
+		epcm->voice->use = 1;
+		epcm->voice->epcm = epcm;
+	}
+
+	return snd_pcm_lib_malloc_pages(substream,
+					params_buffer_bytes(hw_params));
+}
+
+/* hw_free callback */
+static int snd_emu10k1x_pcm_hw_free(snd_pcm_substream_t *substream)
+{
+	snd_pcm_runtime_t *runtime = substream->runtime;
+	emu10k1x_pcm_t *epcm;
+
+	if (runtime->private_data == NULL)
+		return 0;
+	
+	epcm = runtime->private_data;
+
+	if (epcm->voice) {
+		epcm->voice->use = 0;
+		epcm->voice->epcm = NULL;
+		epcm->voice = NULL;
+	}
+
+	return snd_pcm_lib_free_pages(substream);
+}
+
+/* prepare callback */
+static int snd_emu10k1x_pcm_prepare(snd_pcm_substream_t *substream)
+{
+	emu10k1x_t *emu = snd_pcm_substream_chip(substream);
+	snd_pcm_runtime_t *runtime = substream->runtime;
+	emu10k1x_pcm_t *epcm = runtime->private_data;
+	int voice = epcm->voice->number;
+	u32 *table_base = (u32 *)(emu->dma_buffer.area+1024*voice);
+	u32 period_size_bytes = frames_to_bytes(runtime, runtime->period_size);
+	int i;
+	
+	for(i=0; i < runtime->periods; i++) {
+		*table_base++=runtime->dma_addr+(i*period_size_bytes);
+		*table_base++=period_size_bytes<<16;
+	}
+
+	snd_emu10k1x_ptr_write(emu, PLAYBACK_LIST_ADDR, voice, emu->dma_buffer.addr+1024*voice);
+	snd_emu10k1x_ptr_write(emu, PLAYBACK_LIST_SIZE, voice, (runtime->periods - 1) << 19);
+	snd_emu10k1x_ptr_write(emu, PLAYBACK_LIST_PTR, voice, 0);
+	snd_emu10k1x_ptr_write(emu, PLAYBACK_POINTER, voice, 0);
+	snd_emu10k1x_ptr_write(emu, PLAYBACK_UNKNOWN1, voice, 0);
+	snd_emu10k1x_ptr_write(emu, PLAYBACK_UNKNOWN2, voice, 0);
+	snd_emu10k1x_ptr_write(emu, PLAYBACK_DMA_ADDR, voice, runtime->dma_addr);
+
+	snd_emu10k1x_ptr_write(emu, PLAYBACK_PERIOD_SIZE, voice, frames_to_bytes(runtime, runtime->period_size)<<16);
+
+	return 0;
+}
+
+/* trigger callback */
+static int snd_emu10k1x_pcm_trigger(snd_pcm_substream_t *substream,
+				    int cmd)
+{
+	emu10k1x_t *emu = snd_pcm_substream_chip(substream);
+	snd_pcm_runtime_t *runtime = substream->runtime;
+	emu10k1x_pcm_t *epcm = runtime->private_data;
+	int channel = epcm->voice->number;
+	int result = 0;
+
+//	snd_printk(KERN_INFO "trigger - emu10k1x = 0x%x, cmd = %i, pointer = %d\n", (int)emu, cmd, (int)substream->ops->pointer(substream));
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+		if(runtime->periods == 2)
+			snd_emu10k1x_intr_enable(emu, (INTE_CH_0_LOOP | INTE_CH_0_HALF_LOOP) << channel);
+		else
+			snd_emu10k1x_intr_enable(emu, INTE_CH_0_LOOP << channel);
+		epcm->running = 1;
+		snd_emu10k1x_ptr_write(emu, TRIGGER_CHANNEL, 0, snd_emu10k1x_ptr_read(emu, TRIGGER_CHANNEL, 0)|(TRIGGER_CHANNEL_0<<channel));
+		break;
+	case SNDRV_PCM_TRIGGER_STOP:
+		epcm->running = 0;
+		snd_emu10k1x_intr_disable(emu, (INTE_CH_0_LOOP | INTE_CH_0_HALF_LOOP) << channel);
+		snd_emu10k1x_ptr_write(emu, TRIGGER_CHANNEL, 0, snd_emu10k1x_ptr_read(emu, TRIGGER_CHANNEL, 0) & ~(TRIGGER_CHANNEL_0<<channel));
+		break;
+	default:
+		result = -EINVAL;
+		break;
+	}
+	return result;
+}
+
+/* pointer callback */
+static snd_pcm_uframes_t
+snd_emu10k1x_pcm_pointer(snd_pcm_substream_t *substream)
+{
+	emu10k1x_t *emu = snd_pcm_substream_chip(substream);
+	snd_pcm_runtime_t *runtime = substream->runtime;
+	emu10k1x_pcm_t *epcm = runtime->private_data;
+	int channel = epcm->voice->number;
+	snd_pcm_uframes_t ptr = 0, ptr1 = 0, ptr2= 0,ptr3 = 0,ptr4 = 0;
+
+	if (!epcm->running)
+		return 0;
+
+	ptr3 = snd_emu10k1x_ptr_read(emu, PLAYBACK_LIST_PTR, channel);
+	ptr1 = snd_emu10k1x_ptr_read(emu, PLAYBACK_POINTER, channel);
+	ptr4 = snd_emu10k1x_ptr_read(emu, PLAYBACK_LIST_PTR, channel);
+
+	if(ptr4 == 0 && ptr1 == frames_to_bytes(runtime, runtime->buffer_size))
+		return 0;
+	
+	if (ptr3 != ptr4) 
+		ptr1 = snd_emu10k1x_ptr_read(emu, PLAYBACK_POINTER, channel);
+	ptr2 = bytes_to_frames(runtime, ptr1);
+	ptr2 += (ptr4 >> 3) * runtime->period_size;
+	ptr = ptr2;
+
+	if (ptr >= runtime->buffer_size)
+		ptr -= runtime->buffer_size;
+
+	return ptr;
+}
+
+/* operators */
+static snd_pcm_ops_t snd_emu10k1x_playback_ops = {
+	.open =        snd_emu10k1x_playback_open,
+	.close =       snd_emu10k1x_playback_close,
+	.ioctl =       snd_pcm_lib_ioctl,
+	.hw_params =   snd_emu10k1x_pcm_hw_params,
+	.hw_free =     snd_emu10k1x_pcm_hw_free,
+	.prepare =     snd_emu10k1x_pcm_prepare,
+	.trigger =     snd_emu10k1x_pcm_trigger,
+	.pointer =     snd_emu10k1x_pcm_pointer,
+};
+
+/* open_capture callback */
+static int snd_emu10k1x_pcm_open_capture(snd_pcm_substream_t *substream)
+{
+	emu10k1x_t *chip = snd_pcm_substream_chip(substream);
+	emu10k1x_pcm_t *epcm;
+	snd_pcm_runtime_t *runtime = substream->runtime;
+	int err;
+
+	if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
+                return err;
+	if ((err = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 64)) < 0)
+                return err;
+
+	epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL);
+	if (epcm == NULL)
+		return -ENOMEM;
+
+	epcm->emu = chip;
+	epcm->substream = substream;
+
+	runtime->private_data = epcm;
+	runtime->private_free = snd_emu10k1x_pcm_free_substream;
+
+	runtime->hw = snd_emu10k1x_capture_hw;
+
+	return 0;
+}
+
+/* close callback */
+static int snd_emu10k1x_pcm_close_capture(snd_pcm_substream_t *substream)
+{
+	return 0;
+}
+
+/* hw_params callback */
+static int snd_emu10k1x_pcm_hw_params_capture(snd_pcm_substream_t *substream,
+					      snd_pcm_hw_params_t * hw_params)
+{
+	snd_pcm_runtime_t *runtime = substream->runtime;
+	emu10k1x_pcm_t *epcm = runtime->private_data;
+
+	if (! epcm->voice) {
+		if (epcm->emu->capture_voice.use)
+			return -EBUSY;
+		epcm->voice = &epcm->emu->capture_voice;
+		epcm->voice->epcm = epcm;
+		epcm->voice->use = 1;
+	}
+
+	return snd_pcm_lib_malloc_pages(substream,
+					params_buffer_bytes(hw_params));
+}
+
+/* hw_free callback */
+static int snd_emu10k1x_pcm_hw_free_capture(snd_pcm_substream_t *substream)
+{
+	snd_pcm_runtime_t *runtime = substream->runtime;
+
+	emu10k1x_pcm_t *epcm;
+
+	if (runtime->private_data == NULL)
+		return 0;
+	epcm = runtime->private_data;
+
+	if (epcm->voice) {
+		epcm->voice->use = 0;
+		epcm->voice->epcm = NULL;
+		epcm->voice = NULL;
+	}
+
+	return snd_pcm_lib_free_pages(substream);
+}
+
+/* prepare capture callback */
+static int snd_emu10k1x_pcm_prepare_capture(snd_pcm_substream_t *substream)
+{
+	emu10k1x_t *emu = snd_pcm_substream_chip(substream);
+	snd_pcm_runtime_t *runtime = substream->runtime;
+
+	snd_emu10k1x_ptr_write(emu, CAPTURE_DMA_ADDR, 0, runtime->dma_addr);
+	snd_emu10k1x_ptr_write(emu, CAPTURE_BUFFER_SIZE, 0, frames_to_bytes(runtime, runtime->buffer_size)<<16); // buffer size in bytes
+	snd_emu10k1x_ptr_write(emu, CAPTURE_POINTER, 0, 0);
+	snd_emu10k1x_ptr_write(emu, CAPTURE_UNKNOWN, 0, 0);
+
+	return 0;
+}
+
+/* trigger_capture callback */
+static int snd_emu10k1x_pcm_trigger_capture(snd_pcm_substream_t *substream,
+					    int cmd)
+{
+	emu10k1x_t *emu = snd_pcm_substream_chip(substream);
+	snd_pcm_runtime_t *runtime = substream->runtime;
+	emu10k1x_pcm_t *epcm = runtime->private_data;
+	int result = 0;
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+		snd_emu10k1x_intr_enable(emu, INTE_CAP_0_LOOP | 
+					 INTE_CAP_0_HALF_LOOP);
+		snd_emu10k1x_ptr_write(emu, TRIGGER_CHANNEL, 0, snd_emu10k1x_ptr_read(emu, TRIGGER_CHANNEL, 0)|TRIGGER_CAPTURE);
+		epcm->running = 1;
+		break;
+	case SNDRV_PCM_TRIGGER_STOP:
+		epcm->running = 0;
+		snd_emu10k1x_intr_disable(emu, INTE_CAP_0_LOOP | 
+					  INTE_CAP_0_HALF_LOOP);
+		snd_emu10k1x_ptr_write(emu, TRIGGER_CHANNEL, 0, snd_emu10k1x_ptr_read(emu, TRIGGER_CHANNEL, 0) & ~(TRIGGER_CAPTURE));
+		break;
+	default:
+		result = -EINVAL;
+		break;
+	}
+	return result;
+}
+
+/* pointer_capture callback */
+static snd_pcm_uframes_t
+snd_emu10k1x_pcm_pointer_capture(snd_pcm_substream_t *substream)
+{
+	emu10k1x_t *emu = snd_pcm_substream_chip(substream);
+	snd_pcm_runtime_t *runtime = substream->runtime;
+	emu10k1x_pcm_t *epcm = runtime->private_data;
+	snd_pcm_uframes_t ptr;
+
+	if (!epcm->running)
+		return 0;
+
+	ptr = bytes_to_frames(runtime, snd_emu10k1x_ptr_read(emu, CAPTURE_POINTER, 0));
+	if (ptr >= runtime->buffer_size)
+		ptr -= runtime->buffer_size;
+
+	return ptr;
+}
+
+static snd_pcm_ops_t snd_emu10k1x_capture_ops = {
+	.open =        snd_emu10k1x_pcm_open_capture,
+	.close =       snd_emu10k1x_pcm_close_capture,
+	.ioctl =       snd_pcm_lib_ioctl,
+	.hw_params =   snd_emu10k1x_pcm_hw_params_capture,
+	.hw_free =     snd_emu10k1x_pcm_hw_free_capture,
+	.prepare =     snd_emu10k1x_pcm_prepare_capture,
+	.trigger =     snd_emu10k1x_pcm_trigger_capture,
+	.pointer =     snd_emu10k1x_pcm_pointer_capture,
+};
+
+static unsigned short snd_emu10k1x_ac97_read(ac97_t *ac97,
+					     unsigned short reg)
+{
+	emu10k1x_t *emu = ac97->private_data;
+	unsigned long flags;
+	unsigned short val;
+  
+	spin_lock_irqsave(&emu->emu_lock, flags);
+	outb(reg, emu->port + AC97ADDRESS);
+	val = inw(emu->port + AC97DATA);
+	spin_unlock_irqrestore(&emu->emu_lock, flags);
+	return val;
+}
+
+static void snd_emu10k1x_ac97_write(ac97_t *ac97,
+				    unsigned short reg, unsigned short val)
+{
+	emu10k1x_t *emu = ac97->private_data;
+	unsigned long flags;
+  
+	spin_lock_irqsave(&emu->emu_lock, flags);
+	outb(reg, emu->port + AC97ADDRESS);
+	outw(val, emu->port + AC97DATA);
+	spin_unlock_irqrestore(&emu->emu_lock, flags);
+}
+
+static int snd_emu10k1x_ac97(emu10k1x_t *chip)
+{
+	ac97_bus_t *pbus;
+	ac97_template_t ac97;
+	int err;
+	static ac97_bus_ops_t ops = {
+		.write = snd_emu10k1x_ac97_write,
+		.read = snd_emu10k1x_ac97_read,
+	};
+  
+	if ((err = snd_ac97_bus(chip->card, 0, &ops, NULL, &pbus)) < 0)
+		return err;
+	pbus->no_vra = 1; /* we don't need VRA */
+
+	memset(&ac97, 0, sizeof(ac97));
+	ac97.private_data = chip;
+	return snd_ac97_mixer(pbus, &ac97, &chip->ac97);
+}
+
+static int snd_emu10k1x_free(emu10k1x_t *chip)
+{
+	snd_emu10k1x_ptr_write(chip, TRIGGER_CHANNEL, 0, 0);
+	// disable interrupts
+	outl(0, chip->port + INTE);
+	// disable audio
+	outl(HCFG_LOCKSOUNDCACHE, chip->port + HCFG);
+
+	// release the i/o port
+	if (chip->res_port) {
+		release_resource(chip->res_port);
+		kfree_nocheck(chip->res_port);
+	}
+	// release the irq
+	if (chip->irq >= 0)
+		free_irq(chip->irq, (void *)chip);
+
+	// release the DMA
+	if (chip->dma_buffer.area) {
+		snd_dma_free_pages(&chip->dma_buffer);
+	}
+
+	pci_disable_device(chip->pci);
+
+	// release the data
+	kfree(chip);
+	return 0;
+}
+
+static int snd_emu10k1x_dev_free(snd_device_t *device)
+{
+	emu10k1x_t *chip = device->device_data;
+	return snd_emu10k1x_free(chip);
+}
+
+static irqreturn_t snd_emu10k1x_interrupt(int irq, void *dev_id,
+					  struct pt_regs *regs)
+{
+	unsigned int status;
+
+	emu10k1x_t *chip = dev_id;
+	emu10k1x_voice_t *pvoice = chip->voices;
+	int i;
+	int mask;
+
+	status = inl(chip->port + IPR);
+
+	if(status) {
+		// capture interrupt
+		if(status & (IPR_CAP_0_LOOP | IPR_CAP_0_HALF_LOOP)) {
+			emu10k1x_voice_t *pvoice = &chip->capture_voice;
+			if(pvoice->use)
+				snd_emu10k1x_pcm_interrupt(chip, pvoice);
+			else
+				snd_emu10k1x_intr_disable(chip, 
+							  INTE_CAP_0_LOOP |
+							  INTE_CAP_0_HALF_LOOP);
+		}
+		
+		mask = IPR_CH_0_LOOP|IPR_CH_0_HALF_LOOP;
+		for(i = 0; i < 3; i++) {
+			if(status & mask) {
+				if(pvoice->use)
+					snd_emu10k1x_pcm_interrupt(chip, pvoice);
+				else 
+					snd_emu10k1x_intr_disable(chip, mask);
+			}
+			pvoice++;
+			mask <<= 1;
+		}
+		
+		if (status & (IPR_MIDITRANSBUFEMPTY|IPR_MIDIRECVBUFEMPTY)) {
+			if (chip->midi.interrupt)
+				chip->midi.interrupt(chip, status);
+			else
+				snd_emu10k1x_intr_disable(chip, INTE_MIDITXENABLE|INTE_MIDIRXENABLE);
+		}
+		
+		// acknowledge the interrupt if necessary
+		if(status)
+			outl(status, chip->port+IPR);
+
+//		snd_printk(KERN_INFO "interrupt %08x\n", status);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static void snd_emu10k1x_pcm_free(snd_pcm_t *pcm)
+{
+	emu10k1x_t *emu = pcm->private_data;
+	emu->pcm = NULL;
+	snd_pcm_lib_preallocate_free_for_all(pcm);
+}
+
+static int __devinit snd_emu10k1x_pcm(emu10k1x_t *emu, int device, snd_pcm_t **rpcm)
+{
+	snd_pcm_t *pcm;
+	int err;
+	int capture = 0;
+  
+	if (rpcm)
+		*rpcm = NULL;
+	if (device == 0)
+		capture = 1;
+	
+	if ((err = snd_pcm_new(emu->card, "emu10k1x", device, 1, capture, &pcm)) < 0)
+		return err;
+  
+	pcm->private_data = emu;
+	pcm->private_free = snd_emu10k1x_pcm_free;
+	
+	switch(device) {
+	case 0:
+		snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_emu10k1x_playback_ops);
+		snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_emu10k1x_capture_ops);
+		break;
+	case 1:
+	case 2:
+		snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_emu10k1x_playback_ops);
+		break;
+	}
+
+	pcm->info_flags = 0;
+	pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;
+	switch(device) {
+	case 0:
+		strcpy(pcm->name, "EMU10K1X Front");
+		break;
+	case 1:
+		strcpy(pcm->name, "EMU10K1X Rear");
+		break;
+	case 2:
+		strcpy(pcm->name, "EMU10K1X Center/LFE");
+		break;
+	}
+	emu->pcm = pcm;
+
+	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
+					      snd_dma_pci_data(emu->pci), 
+					      32*1024, 32*1024);
+  
+	if (rpcm)
+		*rpcm = pcm;
+  
+	return 0;
+}
+
+static int __devinit snd_emu10k1x_create(snd_card_t *card,
+					 struct pci_dev *pci,
+					 emu10k1x_t **rchip)
+{
+	emu10k1x_t *chip;
+	int err;
+	int ch;
+	static snd_device_ops_t ops = {
+		.dev_free = snd_emu10k1x_dev_free,
+	};
+  
+	*rchip = NULL;
+  
+	if ((err = pci_enable_device(pci)) < 0)
+		return err;
+	if (pci_set_dma_mask(pci, 0x0fffffff) < 0 ||
+	    pci_set_consistent_dma_mask(pci, 0x0fffffff) < 0) {
+		snd_printk(KERN_ERR "error to set 28bit mask DMA\n");
+		pci_disable_device(pci);
+		return -ENXIO;
+	}
+  
+	chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+	if (chip == NULL) {
+		pci_disable_device(pci);
+		return -ENOMEM;
+	}
+  
+	chip->card = card;
+	chip->pci = pci;
+	chip->irq = -1;
+
+	spin_lock_init(&chip->emu_lock);
+	spin_lock_init(&chip->voice_lock);
+  
+	chip->port = pci_resource_start(pci, 0);
+	if ((chip->res_port = request_region(chip->port, 8,
+					     "EMU10K1X")) == NULL) { 
+		snd_printk(KERN_ERR "emu10k1x: cannot allocate the port 0x%lx\n", chip->port);
+		snd_emu10k1x_free(chip);
+		return -EBUSY;
+	}
+
+	if (request_irq(pci->irq, snd_emu10k1x_interrupt,
+			SA_INTERRUPT|SA_SHIRQ, "EMU10K1X",
+			(void *)chip)) {
+		snd_printk(KERN_ERR "emu10k1x: cannot grab irq %d\n", pci->irq);
+		snd_emu10k1x_free(chip);
+		return -EBUSY;
+	}
+	chip->irq = pci->irq;
+  
+	if(snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
+			       4 * 1024, &chip->dma_buffer) < 0) {
+		snd_emu10k1x_free(chip);
+		return -ENOMEM;
+	}
+
+	pci_set_master(pci);
+	/* read revision & serial */
+	pci_read_config_byte(pci, PCI_REVISION_ID, (char *)&chip->revision);
+	pci_read_config_dword(pci, PCI_SUBSYSTEM_VENDOR_ID, &chip->serial);
+	pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &chip->model);
+	snd_printk(KERN_INFO "Model %04x Rev %08x Serial %08x\n", chip->model,
+		   chip->revision, chip->serial);
+
+	outl(0, chip->port + INTE);	
+
+	for(ch = 0; ch < 3; ch++) {
+		chip->voices[ch].emu = chip;
+		chip->voices[ch].number = ch;
+	}
+
+	/*
+	 *  Init to 0x02109204 :
+	 *  Clock accuracy    = 0     (1000ppm)
+	 *  Sample Rate       = 2     (48kHz)
+	 *  Audio Channel     = 1     (Left of 2)
+	 *  Source Number     = 0     (Unspecified)
+	 *  Generation Status = 1     (Original for Cat Code 12)
+	 *  Cat Code          = 12    (Digital Signal Mixer)
+	 *  Mode              = 0     (Mode 0)
+	 *  Emphasis          = 0     (None)
+	 *  CP                = 1     (Copyright unasserted)
+	 *  AN                = 0     (Audio data)
+	 *  P                 = 0     (Consumer)
+	 */
+	snd_emu10k1x_ptr_write(chip, SPCS0, 0,
+			       chip->spdif_bits[0] = 
+			       SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
+			       SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
+			       SPCS_GENERATIONSTATUS | 0x00001200 |
+			       0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT);
+	snd_emu10k1x_ptr_write(chip, SPCS1, 0,
+			       chip->spdif_bits[1] = 
+			       SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
+			       SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
+			       SPCS_GENERATIONSTATUS | 0x00001200 |
+			       0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT);
+	snd_emu10k1x_ptr_write(chip, SPCS2, 0,
+			       chip->spdif_bits[2] = 
+			       SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
+			       SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
+			       SPCS_GENERATIONSTATUS | 0x00001200 |
+			       0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT);
+
+	snd_emu10k1x_ptr_write(chip, SPDIF_SELECT, 0, 0x700); // disable SPDIF
+	snd_emu10k1x_ptr_write(chip, ROUTING, 0, 0x1003F); // routing
+	snd_emu10k1x_gpio_write(chip, 0x1080); // analog mode
+
+	outl(HCFG_LOCKSOUNDCACHE|HCFG_AUDIOENABLE, chip->port+HCFG);
+
+	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL,
+				  chip, &ops)) < 0) {
+		snd_emu10k1x_free(chip);
+		return err;
+	}
+	*rchip = chip;
+	return 0;
+}
+
+static void snd_emu10k1x_proc_reg_read(snd_info_entry_t *entry, 
+				       snd_info_buffer_t * buffer)
+{
+	emu10k1x_t *emu = entry->private_data;
+	unsigned long value,value1,value2;
+	unsigned long flags;
+	int i;
+
+	snd_iprintf(buffer, "Registers:\n\n");
+	for(i = 0; i < 0x20; i+=4) {
+		spin_lock_irqsave(&emu->emu_lock, flags);
+		value = inl(emu->port + i);
+		spin_unlock_irqrestore(&emu->emu_lock, flags);
+		snd_iprintf(buffer, "Register %02X: %08lX\n", i, value);
+	}
+	snd_iprintf(buffer, "\nRegisters\n\n");
+	for(i = 0; i <= 0x48; i++) {
+		value = snd_emu10k1x_ptr_read(emu, i, 0);
+		if(i < 0x10 || (i >= 0x20 && i < 0x40)) {
+			value1 = snd_emu10k1x_ptr_read(emu, i, 1);
+			value2 = snd_emu10k1x_ptr_read(emu, i, 2);
+			snd_iprintf(buffer, "%02X: %08lX %08lX %08lX\n", i, value, value1, value2);
+		} else {
+			snd_iprintf(buffer, "%02X: %08lX\n", i, value);
+		}
+	}
+}
+
+static void snd_emu10k1x_proc_reg_write(snd_info_entry_t *entry, 
+					snd_info_buffer_t *buffer)
+{
+	emu10k1x_t *emu = entry->private_data;
+	char line[64];
+	unsigned int reg, channel_id , val;
+
+	while (!snd_info_get_line(buffer, line, sizeof(line))) {
+		if (sscanf(line, "%x %x %x", &reg, &channel_id, &val) != 3)
+			continue;
+
+		if ((reg < 0x49) && (reg >=0) && (val <= 0xffffffff) 
+		    && (channel_id >=0) && (channel_id <= 2) )
+			snd_emu10k1x_ptr_write(emu, reg, channel_id, val);
+	}
+}
+
+static int __devinit snd_emu10k1x_proc_init(emu10k1x_t * emu)
+{
+	snd_info_entry_t *entry;
+	
+	if(! snd_card_proc_new(emu->card, "emu10k1x_regs", &entry)) {
+		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->private_data = emu;
+	}
+	
+	return 0;
+}
+
+static int snd_emu10k1x_shared_spdif_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_emu10k1x_shared_spdif_get(snd_kcontrol_t * kcontrol,
+					 snd_ctl_elem_value_t * ucontrol)
+{
+	emu10k1x_t *emu = snd_kcontrol_chip(kcontrol);
+
+	ucontrol->value.integer.value[0] = (snd_emu10k1x_ptr_read(emu, SPDIF_SELECT, 0) == 0x700) ? 0 : 1;
+
+	return 0;
+}
+
+static int snd_emu10k1x_shared_spdif_put(snd_kcontrol_t * kcontrol,
+					 snd_ctl_elem_value_t * ucontrol)
+{
+	emu10k1x_t *emu = snd_kcontrol_chip(kcontrol);
+	unsigned int val;
+	int change = 0;
+
+	val = ucontrol->value.integer.value[0] ;
+
+	if (val) {
+		// enable spdif output
+		snd_emu10k1x_ptr_write(emu, SPDIF_SELECT, 0, 0x000);
+		snd_emu10k1x_ptr_write(emu, ROUTING, 0, 0x700);
+		snd_emu10k1x_gpio_write(emu, 0x1000);
+	} else {
+		// disable spdif output
+		snd_emu10k1x_ptr_write(emu, SPDIF_SELECT, 0, 0x700);
+		snd_emu10k1x_ptr_write(emu, ROUTING, 0, 0x1003F);
+		snd_emu10k1x_gpio_write(emu, 0x1080);
+	}
+	return change;
+}
+
+static snd_kcontrol_new_t snd_emu10k1x_shared_spdif __devinitdata =
+{
+	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name =		"Analog/Digital Output Jack",
+	.info =		snd_emu10k1x_shared_spdif_info,
+	.get =		snd_emu10k1x_shared_spdif_get,
+	.put =		snd_emu10k1x_shared_spdif_put
+};
+
+static int snd_emu10k1x_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
+	uinfo->count = 1;
+	return 0;
+}
+
+static int snd_emu10k1x_spdif_get(snd_kcontrol_t * kcontrol,
+				  snd_ctl_elem_value_t * ucontrol)
+{
+	emu10k1x_t *emu = snd_kcontrol_chip(kcontrol);
+	unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
+
+	ucontrol->value.iec958.status[0] = (emu->spdif_bits[idx] >> 0) & 0xff;
+	ucontrol->value.iec958.status[1] = (emu->spdif_bits[idx] >> 8) & 0xff;
+	ucontrol->value.iec958.status[2] = (emu->spdif_bits[idx] >> 16) & 0xff;
+	ucontrol->value.iec958.status[3] = (emu->spdif_bits[idx] >> 24) & 0xff;
+	return 0;
+}
+
+static int snd_emu10k1x_spdif_get_mask(snd_kcontrol_t * kcontrol,
+				       snd_ctl_elem_value_t * ucontrol)
+{
+	ucontrol->value.iec958.status[0] = 0xff;
+	ucontrol->value.iec958.status[1] = 0xff;
+	ucontrol->value.iec958.status[2] = 0xff;
+	ucontrol->value.iec958.status[3] = 0xff;
+	return 0;
+}
+
+static int snd_emu10k1x_spdif_put(snd_kcontrol_t * kcontrol,
+				  snd_ctl_elem_value_t * ucontrol)
+{
+	emu10k1x_t *emu = snd_kcontrol_chip(kcontrol);
+	unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
+	int change;
+	unsigned int val;
+
+	val = (ucontrol->value.iec958.status[0] << 0) |
+		(ucontrol->value.iec958.status[1] << 8) |
+		(ucontrol->value.iec958.status[2] << 16) |
+		(ucontrol->value.iec958.status[3] << 24);
+	change = val != emu->spdif_bits[idx];
+	if (change) {
+		snd_emu10k1x_ptr_write(emu, SPCS0 + idx, 0, val);
+		emu->spdif_bits[idx] = val;
+	}
+	return change;
+}
+
+static snd_kcontrol_new_t snd_emu10k1x_spdif_mask_control =
+{
+	.access =	SNDRV_CTL_ELEM_ACCESS_READ,
+	.iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
+	.count =	3,
+	.info =         snd_emu10k1x_spdif_info,
+	.get =          snd_emu10k1x_spdif_get_mask
+};
+
+static snd_kcontrol_new_t snd_emu10k1x_spdif_control =
+{
+	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
+	.count =	3,
+	.info =         snd_emu10k1x_spdif_info,
+	.get =          snd_emu10k1x_spdif_get,
+	.put =          snd_emu10k1x_spdif_put
+};
+
+static int __devinit snd_emu10k1x_mixer(emu10k1x_t *emu)
+{
+	int err;
+	snd_kcontrol_t *kctl;
+	snd_card_t *card = emu->card;
+
+	if ((kctl = snd_ctl_new1(&snd_emu10k1x_spdif_mask_control, emu)) == NULL)
+		return -ENOMEM;
+	if ((err = snd_ctl_add(card, kctl)))
+		return err;
+	if ((kctl = snd_ctl_new1(&snd_emu10k1x_shared_spdif, emu)) == NULL)
+		return -ENOMEM;
+	if ((err = snd_ctl_add(card, kctl)))
+		return err;
+	if ((kctl = snd_ctl_new1(&snd_emu10k1x_spdif_control, emu)) == NULL)
+		return -ENOMEM;
+	if ((err = snd_ctl_add(card, kctl)))
+		return err;
+
+	return 0;
+}
+
+#define EMU10K1X_MIDI_MODE_INPUT	(1<<0)
+#define EMU10K1X_MIDI_MODE_OUTPUT	(1<<1)
+
+static inline unsigned char mpu401_read(emu10k1x_t *emu, emu10k1x_midi_t *mpu, int idx)
+{
+	return (unsigned char)snd_emu10k1x_ptr_read(emu, mpu->port + idx, 0);
+}
+
+static inline void mpu401_write(emu10k1x_t *emu, emu10k1x_midi_t *mpu, int data, int idx)
+{
+	snd_emu10k1x_ptr_write(emu, mpu->port + idx, 0, data);
+}
+
+#define mpu401_write_data(emu, mpu, data)	mpu401_write(emu, mpu, data, 0)
+#define mpu401_write_cmd(emu, mpu, data)	mpu401_write(emu, mpu, data, 1)
+#define mpu401_read_data(emu, mpu)		mpu401_read(emu, mpu, 0)
+#define mpu401_read_stat(emu, mpu)		mpu401_read(emu, mpu, 1)
+
+#define mpu401_input_avail(emu,mpu)	(!(mpu401_read_stat(emu,mpu) & 0x80))
+#define mpu401_output_ready(emu,mpu)	(!(mpu401_read_stat(emu,mpu) & 0x40))
+
+#define MPU401_RESET		0xff
+#define MPU401_ENTER_UART	0x3f
+#define MPU401_ACK		0xfe
+
+static void mpu401_clear_rx(emu10k1x_t *emu, emu10k1x_midi_t *mpu)
+{
+	int timeout = 100000;
+	for (; timeout > 0 && mpu401_input_avail(emu, mpu); timeout--)
+		mpu401_read_data(emu, mpu);
+#ifdef CONFIG_SND_DEBUG
+	if (timeout <= 0)
+		snd_printk(KERN_ERR "cmd: clear rx timeout (status = 0x%x)\n", mpu401_read_stat(emu, mpu));
+#endif
+}
+
+/*
+
+ */
+
+static void do_emu10k1x_midi_interrupt(emu10k1x_t *emu, emu10k1x_midi_t *midi, unsigned int status)
+{
+	unsigned char byte;
+
+	if (midi->rmidi == NULL) {
+		snd_emu10k1x_intr_disable(emu, midi->tx_enable | midi->rx_enable);
+		return;
+	}
+
+	spin_lock(&midi->input_lock);
+	if ((status & midi->ipr_rx) && mpu401_input_avail(emu, midi)) {
+		if (!(midi->midi_mode & EMU10K1X_MIDI_MODE_INPUT)) {
+			mpu401_clear_rx(emu, midi);
+		} else {
+			byte = mpu401_read_data(emu, midi);
+			spin_unlock(&midi->input_lock);
+			if (midi->substream_input)
+				snd_rawmidi_receive(midi->substream_input, &byte, 1);
+			spin_lock(&midi->input_lock);
+		}
+	}
+	spin_unlock(&midi->input_lock);
+
+	spin_lock(&midi->output_lock);
+	if ((status & midi->ipr_tx) && mpu401_output_ready(emu, midi)) {
+		if (midi->substream_output &&
+		    snd_rawmidi_transmit(midi->substream_output, &byte, 1) == 1) {
+			mpu401_write_data(emu, midi, byte);
+		} else {
+			snd_emu10k1x_intr_disable(emu, midi->tx_enable);
+		}
+	}
+	spin_unlock(&midi->output_lock);
+}
+
+static void snd_emu10k1x_midi_interrupt(emu10k1x_t *emu, unsigned int status)
+{
+	do_emu10k1x_midi_interrupt(emu, &emu->midi, status);
+}
+
+static void snd_emu10k1x_midi_cmd(emu10k1x_t * emu, emu10k1x_midi_t *midi, unsigned char cmd, int ack)
+{
+	unsigned long flags;
+	int timeout, ok;
+
+	spin_lock_irqsave(&midi->input_lock, flags);
+	mpu401_write_data(emu, midi, 0x00);
+	/* mpu401_clear_rx(emu, midi); */
+
+	mpu401_write_cmd(emu, midi, cmd);
+	if (ack) {
+		ok = 0;
+		timeout = 10000;
+		while (!ok && timeout-- > 0) {
+			if (mpu401_input_avail(emu, midi)) {
+				if (mpu401_read_data(emu, midi) == MPU401_ACK)
+					ok = 1;
+			}
+		}
+		if (!ok && mpu401_read_data(emu, midi) == MPU401_ACK)
+			ok = 1;
+	} else {
+		ok = 1;
+	}
+	spin_unlock_irqrestore(&midi->input_lock, flags);
+	if (!ok)
+		snd_printk(KERN_ERR "midi_cmd: 0x%x failed at 0x%lx (status = 0x%x, data = 0x%x)!!!\n",
+			   cmd, emu->port,
+			   mpu401_read_stat(emu, midi),
+			   mpu401_read_data(emu, midi));
+}
+
+static int snd_emu10k1x_midi_input_open(snd_rawmidi_substream_t * substream)
+{
+	emu10k1x_t *emu;
+	emu10k1x_midi_t *midi = (emu10k1x_midi_t *)substream->rmidi->private_data;
+	unsigned long flags;
+	
+	emu = midi->emu;
+	snd_assert(emu, return -ENXIO);
+	spin_lock_irqsave(&midi->open_lock, flags);
+	midi->midi_mode |= EMU10K1X_MIDI_MODE_INPUT;
+	midi->substream_input = substream;
+	if (!(midi->midi_mode & EMU10K1X_MIDI_MODE_OUTPUT)) {
+		spin_unlock_irqrestore(&midi->open_lock, flags);
+		snd_emu10k1x_midi_cmd(emu, midi, MPU401_RESET, 1);
+		snd_emu10k1x_midi_cmd(emu, midi, MPU401_ENTER_UART, 1);
+	} else {
+		spin_unlock_irqrestore(&midi->open_lock, flags);
+	}
+	return 0;
+}
+
+static int snd_emu10k1x_midi_output_open(snd_rawmidi_substream_t * substream)
+{
+	emu10k1x_t *emu;
+	emu10k1x_midi_t *midi = (emu10k1x_midi_t *)substream->rmidi->private_data;
+	unsigned long flags;
+
+	emu = midi->emu;
+	snd_assert(emu, return -ENXIO);
+	spin_lock_irqsave(&midi->open_lock, flags);
+	midi->midi_mode |= EMU10K1X_MIDI_MODE_OUTPUT;
+	midi->substream_output = substream;
+	if (!(midi->midi_mode & EMU10K1X_MIDI_MODE_INPUT)) {
+		spin_unlock_irqrestore(&midi->open_lock, flags);
+		snd_emu10k1x_midi_cmd(emu, midi, MPU401_RESET, 1);
+		snd_emu10k1x_midi_cmd(emu, midi, MPU401_ENTER_UART, 1);
+	} else {
+		spin_unlock_irqrestore(&midi->open_lock, flags);
+	}
+	return 0;
+}
+
+static int snd_emu10k1x_midi_input_close(snd_rawmidi_substream_t * substream)
+{
+	emu10k1x_t *emu;
+	emu10k1x_midi_t *midi = (emu10k1x_midi_t *)substream->rmidi->private_data;
+	unsigned long flags;
+
+	emu = midi->emu;
+	snd_assert(emu, return -ENXIO);
+	spin_lock_irqsave(&midi->open_lock, flags);
+	snd_emu10k1x_intr_disable(emu, midi->rx_enable);
+	midi->midi_mode &= ~EMU10K1X_MIDI_MODE_INPUT;
+	midi->substream_input = NULL;
+	if (!(midi->midi_mode & EMU10K1X_MIDI_MODE_OUTPUT)) {
+		spin_unlock_irqrestore(&midi->open_lock, flags);
+		snd_emu10k1x_midi_cmd(emu, midi, MPU401_RESET, 0);
+	} else {
+		spin_unlock_irqrestore(&midi->open_lock, flags);
+	}
+	return 0;
+}
+
+static int snd_emu10k1x_midi_output_close(snd_rawmidi_substream_t * substream)
+{
+	emu10k1x_t *emu;
+	emu10k1x_midi_t *midi = (emu10k1x_midi_t *)substream->rmidi->private_data;
+	unsigned long flags;
+
+	emu = midi->emu;
+	snd_assert(emu, return -ENXIO);
+	spin_lock_irqsave(&midi->open_lock, flags);
+	snd_emu10k1x_intr_disable(emu, midi->tx_enable);
+	midi->midi_mode &= ~EMU10K1X_MIDI_MODE_OUTPUT;
+	midi->substream_output = NULL;
+	if (!(midi->midi_mode & EMU10K1X_MIDI_MODE_INPUT)) {
+		spin_unlock_irqrestore(&midi->open_lock, flags);
+		snd_emu10k1x_midi_cmd(emu, midi, MPU401_RESET, 0);
+	} else {
+		spin_unlock_irqrestore(&midi->open_lock, flags);
+	}
+	return 0;
+}
+
+static void snd_emu10k1x_midi_input_trigger(snd_rawmidi_substream_t * substream, int up)
+{
+	emu10k1x_t *emu;
+	emu10k1x_midi_t *midi = (emu10k1x_midi_t *)substream->rmidi->private_data;
+	emu = midi->emu;
+	snd_assert(emu, return);
+
+	if (up)
+		snd_emu10k1x_intr_enable(emu, midi->rx_enable);
+	else
+		snd_emu10k1x_intr_disable(emu, midi->rx_enable);
+}
+
+static void snd_emu10k1x_midi_output_trigger(snd_rawmidi_substream_t * substream, int up)
+{
+	emu10k1x_t *emu;
+	emu10k1x_midi_t *midi = (emu10k1x_midi_t *)substream->rmidi->private_data;
+	unsigned long flags;
+
+	emu = midi->emu;
+	snd_assert(emu, return);
+
+	if (up) {
+		int max = 4;
+		unsigned char byte;
+	
+		/* try to send some amount of bytes here before interrupts */
+		spin_lock_irqsave(&midi->output_lock, flags);
+		while (max > 0) {
+			if (mpu401_output_ready(emu, midi)) {
+				if (!(midi->midi_mode & EMU10K1X_MIDI_MODE_OUTPUT) ||
+				    snd_rawmidi_transmit(substream, &byte, 1) != 1) {
+					/* no more data */
+					spin_unlock_irqrestore(&midi->output_lock, flags);
+					return;
+				}
+				mpu401_write_data(emu, midi, byte);
+				max--;
+			} else {
+				break;
+			}
+		}
+		spin_unlock_irqrestore(&midi->output_lock, flags);
+		snd_emu10k1x_intr_enable(emu, midi->tx_enable);
+	} else {
+		snd_emu10k1x_intr_disable(emu, midi->tx_enable);
+	}
+}
+
+/*
+
+ */
+
+static snd_rawmidi_ops_t snd_emu10k1x_midi_output =
+{
+	.open =		snd_emu10k1x_midi_output_open,
+	.close =	snd_emu10k1x_midi_output_close,
+	.trigger =	snd_emu10k1x_midi_output_trigger,
+};
+
+static snd_rawmidi_ops_t snd_emu10k1x_midi_input =
+{
+	.open =		snd_emu10k1x_midi_input_open,
+	.close =	snd_emu10k1x_midi_input_close,
+	.trigger =	snd_emu10k1x_midi_input_trigger,
+};
+
+static void snd_emu10k1x_midi_free(snd_rawmidi_t *rmidi)
+{
+	emu10k1x_midi_t *midi = (emu10k1x_midi_t *)rmidi->private_data;
+	midi->interrupt = NULL;
+	midi->rmidi = NULL;
+}
+
+static int __devinit emu10k1x_midi_init(emu10k1x_t *emu, emu10k1x_midi_t *midi, int device, char *name)
+{
+	snd_rawmidi_t *rmidi;
+	int err;
+
+	if ((err = snd_rawmidi_new(emu->card, name, device, 1, 1, &rmidi)) < 0)
+		return err;
+	midi->emu = emu;
+	spin_lock_init(&midi->open_lock);
+	spin_lock_init(&midi->input_lock);
+	spin_lock_init(&midi->output_lock);
+	strcpy(rmidi->name, name);
+	snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_emu10k1x_midi_output);
+	snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_emu10k1x_midi_input);
+	rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT |
+	                     SNDRV_RAWMIDI_INFO_INPUT |
+	                     SNDRV_RAWMIDI_INFO_DUPLEX;
+	rmidi->private_data = midi;
+	rmidi->private_free = snd_emu10k1x_midi_free;
+	midi->rmidi = rmidi;
+	return 0;
+}
+
+static int __devinit snd_emu10k1x_midi(emu10k1x_t *emu)
+{
+	emu10k1x_midi_t *midi = &emu->midi;
+	int err;
+
+	if ((err = emu10k1x_midi_init(emu, midi, 0, "EMU10K1X MPU-401 (UART)")) < 0)
+		return err;
+
+	midi->tx_enable = INTE_MIDITXENABLE;
+	midi->rx_enable = INTE_MIDIRXENABLE;
+	midi->port = MUDATA;
+	midi->ipr_tx = IPR_MIDITRANSBUFEMPTY;
+	midi->ipr_rx = IPR_MIDIRECVBUFEMPTY;
+	midi->interrupt = snd_emu10k1x_midi_interrupt;
+	return 0;
+}
+
+static int __devinit snd_emu10k1x_probe(struct pci_dev *pci,
+					const struct pci_device_id *pci_id)
+{
+	static int dev;
+	snd_card_t *card;
+	emu10k1x_t *chip;
+	int err;
+
+	if (dev >= SNDRV_CARDS)
+		return -ENODEV;
+	if (!enable[dev]) {
+		dev++;
+		return -ENOENT;
+	}
+
+	card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
+	if (card == NULL)
+		return -ENOMEM;
+
+	if ((err = snd_emu10k1x_create(card, pci, &chip)) < 0) {
+		snd_card_free(card);
+		return err;
+	}
+
+	if ((err = snd_emu10k1x_pcm(chip, 0, NULL)) < 0) {
+		snd_card_free(card);
+		return err;
+	}
+	if ((err = snd_emu10k1x_pcm(chip, 1, NULL)) < 0) {
+		snd_card_free(card);
+		return err;
+	}
+	if ((err = snd_emu10k1x_pcm(chip, 2, NULL)) < 0) {
+		snd_card_free(card);
+		return err;
+	}
+
+	if ((err = snd_emu10k1x_ac97(chip)) < 0) {
+		snd_card_free(card);
+		return err;
+	}
+
+	if ((err = snd_emu10k1x_mixer(chip)) < 0) {
+		snd_card_free(card);
+		return err;
+	}
+	
+	if ((err = snd_emu10k1x_midi(chip)) < 0) {
+		snd_card_free(card);
+		return err;
+	}
+
+	snd_emu10k1x_proc_init(chip);
+
+	strcpy(card->driver, "EMU10K1X");
+	strcpy(card->shortname, "Dell Sound Blaster Live!");
+	sprintf(card->longname, "%s at 0x%lx irq %i",
+		card->shortname, chip->port, chip->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_emu10k1x_remove(struct pci_dev *pci)
+{
+	snd_card_free(pci_get_drvdata(pci));
+	pci_set_drvdata(pci, NULL);
+}
+
+// PCI IDs
+static struct pci_device_id snd_emu10k1x_ids[] = {
+	{ 0x1102, 0x0006, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },	/* Dell OEM version (EMU10K1) */
+	{ 0, }
+};
+MODULE_DEVICE_TABLE(pci, snd_emu10k1x_ids);
+
+// pci_driver definition
+static struct pci_driver driver = {
+	.name = "EMU10K1X",
+	.id_table = snd_emu10k1x_ids,
+	.probe = snd_emu10k1x_probe,
+	.remove = __devexit_p(snd_emu10k1x_remove),
+};
+
+// initialization of the module
+static int __init alsa_card_emu10k1x_init(void)
+{
+	int err;
+
+	if ((err = pci_module_init(&driver)) > 0)
+		return err;
+
+	return 0;
+}
+
+// clean up the module
+static void __exit alsa_card_emu10k1x_exit(void)
+{
+	pci_unregister_driver(&driver);
+}
+
+module_init(alsa_card_emu10k1x_init)
+module_exit(alsa_card_emu10k1x_exit)
diff -Nru a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c
--- a/sound/pci/emu10k1/emufx.c	2005-03-01 23:38:57 -08:00
+++ b/sound/pci/emu10k1/emufx.c	2005-03-01 23:38:57 -08:00
@@ -437,7 +437,7 @@
 }
 
 int snd_emu10k1_fx8010_unregister_irq_handler(emu10k1_t *emu,
-						     snd_emu10k1_fx8010_irq_t *irq)
+					      snd_emu10k1_fx8010_irq_t *irq)
 {
 	snd_emu10k1_fx8010_irq_t *tmp;
 	unsigned long flags;
@@ -470,8 +470,8 @@
 {
 	snd_assert(*ptr < 512, return);
 	set_bit(*ptr, icode->code_valid);
-	icode->code[*ptr    ][0] = ((x & 0x3ff) << 10) | (y & 0x3ff);
-	icode->code[(*ptr)++][1] = ((op & 0x0f) << 20) | ((r & 0x3ff) << 10) | (a & 0x3ff);
+	icode->code[(*ptr)   * 2 + 0] = ((x & 0x3ff) << 10) | (y & 0x3ff);
+	icode->code[(*ptr)++ * 2 + 1] = ((op & 0x0f) << 20) | ((r & 0x3ff) << 10) | (a & 0x3ff);
 }
 
 #define OP(icode, ptr, op, r, a, x, y) \
@@ -482,14 +482,14 @@
 {
 	snd_assert(*ptr < 1024, return);
 	set_bit(*ptr, icode->code_valid);
-	icode->code[*ptr    ][0] = ((x & 0x7ff) << 12) | (y & 0x7ff);
-	icode->code[(*ptr)++][1] = ((op & 0x0f) << 24) | ((r & 0x7ff) << 12) | (a & 0x7ff);
+	icode->code[(*ptr)   * 2 + 0] = ((x & 0x7ff) << 12) | (y & 0x7ff);
+	icode->code[(*ptr)++ * 2 + 1] = ((op & 0x0f) << 24) | ((r & 0x7ff) << 12) | (a & 0x7ff);
 }
 
 #define A_OP(icode, ptr, op, r, a, x, y) \
 	snd_emu10k1_audigy_write_op(icode, ptr, op, r, a, x, y)
 
-void snd_emu10k1_efx_write(emu10k1_t *emu, unsigned int pc, unsigned int data)
+static void snd_emu10k1_efx_write(emu10k1_t *emu, unsigned int pc, unsigned int data)
 {
 	pc += emu->audigy ? A_MICROCODEBASE : MICROCODEBASE;
 	snd_emu10k1_ptr_write(emu, pc, 0, data);
@@ -501,83 +501,108 @@
 	return snd_emu10k1_ptr_read(emu, pc, 0);
 }
 
-static void snd_emu10k1_gpr_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
+static int snd_emu10k1_gpr_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
 {
 	int gpr;
+	u32 val;
 
 	for (gpr = 0; gpr < (emu->audigy ? 0x200 : 0x100); gpr++) {
 		if (!test_bit(gpr, icode->gpr_valid))
 			continue;
-		snd_emu10k1_ptr_write(emu, emu->gpr_base + gpr, 0, icode->gpr_map[gpr]);
+		if (get_user(val, &icode->gpr_map[gpr]))
+			return -EFAULT;
+		snd_emu10k1_ptr_write(emu, emu->gpr_base + gpr, 0, val);
 	}
+	return 0;
 }
 
-static void snd_emu10k1_gpr_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
+static int snd_emu10k1_gpr_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
 {
 	int gpr;
+	u32 val;
 
 	for (gpr = 0; gpr < (emu->audigy ? 0x200 : 0x100); gpr++) {
 		set_bit(gpr, icode->gpr_valid);
-		icode->gpr_map[gpr] = snd_emu10k1_ptr_read(emu, emu->gpr_base + gpr, 0);
+		val = snd_emu10k1_ptr_read(emu, emu->gpr_base + gpr, 0);
+		if (put_user(val, &icode->gpr_map[gpr]))
+			return -EFAULT;
 	}
+	return 0;
 }
 
-static void snd_emu10k1_tram_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
+static int snd_emu10k1_tram_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
 {
 	int tram;
+	u32 addr, val;
 
 	for (tram = 0; tram < (emu->audigy ? 0x100 : 0xa0); tram++) {
 		if (!test_bit(tram, icode->tram_valid))
 			continue;
-		snd_emu10k1_ptr_write(emu, TANKMEMDATAREGBASE + tram, 0, icode->tram_data_map[tram]);
-		if (!emu->audigy)
-			snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + tram, 0, icode->tram_addr_map[tram]);
-		else {
-			snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + tram, 0, icode->tram_addr_map[tram] << 12);
-			snd_emu10k1_ptr_write(emu, A_TANKMEMCTLREGBASE + tram, 0, icode->tram_addr_map[tram] >> 20);
+		if (get_user(val, &icode->tram_data_map[tram]) ||
+		    get_user(addr, &icode->tram_addr_map[tram]))
+			return -EFAULT;
+		snd_emu10k1_ptr_write(emu, TANKMEMDATAREGBASE + tram, 0, val);
+		if (!emu->audigy) {
+			snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + tram, 0, addr);
+		} else {
+			snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + tram, 0, addr << 12);
+			snd_emu10k1_ptr_write(emu, A_TANKMEMCTLREGBASE + tram, 0, addr >> 20);
 		}
 	}
+	return 0;
 }
 
-static void snd_emu10k1_tram_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
+static int snd_emu10k1_tram_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
 {
 	int tram;
+	u32 val, addr;
 
 	memset(icode->tram_valid, 0, sizeof(icode->tram_valid));
 	for (tram = 0; tram < (emu->audigy ? 0x100 : 0xa0); tram++) {
 		set_bit(tram, icode->tram_valid);
-		icode->tram_data_map[tram] = snd_emu10k1_ptr_read(emu, TANKMEMDATAREGBASE + tram, 0);
-		if (!emu->audigy)
-			icode->tram_addr_map[tram] = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + tram, 0);
-		else {
-			icode->tram_addr_map[tram] = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + tram, 0) >> 12;
-			icode->tram_addr_map[tram] |= snd_emu10k1_ptr_read(emu, A_TANKMEMCTLREGBASE + tram, 0) << 20;
+		val = snd_emu10k1_ptr_read(emu, TANKMEMDATAREGBASE + tram, 0);
+		if (!emu->audigy) {
+			addr = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + tram, 0);
+		} else {
+			addr = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + tram, 0) >> 12;
+			addr |= snd_emu10k1_ptr_read(emu, A_TANKMEMCTLREGBASE + tram, 0) << 20;
 		}
+		if (put_user(val, &icode->tram_data_map[tram]) ||
+		    put_user(addr, &icode->tram_addr_map[tram]))
+			return -EFAULT;
 	}
+	return 0;
 }
 
-static void snd_emu10k1_code_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
+static int snd_emu10k1_code_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
 {
-	u32 pc;
+	u32 pc, lo, hi;
 
-	for (pc = 0; pc < (emu->audigy ? 1024 : 512); pc++) {
-		if (!test_bit(pc, icode->code_valid))
+	for (pc = 0; pc < (emu->audigy ? 2*1024 : 2*512); pc += 2) {
+		if (!test_bit(pc / 2, icode->code_valid))
 			continue;
-		snd_emu10k1_efx_write(emu, pc * 2, icode->code[pc][0]);
-		snd_emu10k1_efx_write(emu, pc * 2 + 1, icode->code[pc][1]);
+		if (get_user(lo, &icode->code[pc + 0]) ||
+		    get_user(hi, &icode->code[pc + 1]))
+			return -EFAULT;
+		snd_emu10k1_efx_write(emu, pc + 0, lo);
+		snd_emu10k1_efx_write(emu, pc + 1, hi);
 	}
+	return 0;
 }
 
-static void snd_emu10k1_code_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
+static int snd_emu10k1_code_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
 {
 	u32 pc;
 
 	memset(icode->code_valid, 0, sizeof(icode->code_valid));
-	for (pc = 0; pc < (emu->audigy ? 1024 : 512); pc++) {
-		set_bit(pc, icode->code_valid);
-		icode->code[pc][0] = snd_emu10k1_efx_read(emu, pc * 2);
-		icode->code[pc][1] = snd_emu10k1_efx_read(emu, pc * 2 + 1);
+	for (pc = 0; pc < (emu->audigy ? 2*1024 : 2*512); pc += 2) {
+		set_bit(pc / 2, icode->code_valid);
+		if (put_user(snd_emu10k1_efx_read(emu, pc + 0), &icode->code[pc + 0]))
+			return -EFAULT;
+		if (put_user(snd_emu10k1_efx_read(emu, pc + 1), &icode->code[pc + 1]))
+			return -EFAULT;
 	}
+	return 0;
 }
 
 static snd_emu10k1_fx8010_ctl_t *snd_emu10k1_look_for_ctl(emu10k1_t *emu, snd_ctl_elem_id_t *id)
@@ -647,7 +672,7 @@
 	kfree(ctl);
 }
 
-static void snd_emu10k1_add_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
+static int snd_emu10k1_add_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
 {
 	unsigned int i, j;
 	emu10k1_fx8010_control_gpr_t __user *_gctl;
@@ -656,17 +681,20 @@
 	snd_kcontrol_new_t knew;
 	snd_kcontrol_t *kctl;
 	snd_ctl_elem_value_t *val;
+	int err = 0;
 
 	val = (snd_ctl_elem_value_t *)kmalloc(sizeof(*val), GFP_KERNEL);
 	if (!val)
-		return;
+		return -ENOMEM;
 	for (i = 0, _gctl = icode->gpr_add_controls;
 	     i < icode->gpr_add_control_count; i++, _gctl++) {
-		if (copy_from_user(&gctl, _gctl, sizeof(gctl)))
-			break;
+		if (copy_from_user(&gctl, _gctl, sizeof(gctl))) {
+			err = -EFAULT;
+			goto __error;
+		}
 		snd_runtime_check(gctl.id.iface == SNDRV_CTL_ELEM_IFACE_MIXER ||
-		                  gctl.id.iface == SNDRV_CTL_ELEM_IFACE_PCM, continue);
-		snd_runtime_check(gctl.id.name[0] != '\0', continue);
+		                  gctl.id.iface == SNDRV_CTL_ELEM_IFACE_PCM, err = -EINVAL; goto __error);
+		snd_runtime_check(gctl.id.name[0] != '\0', err = -EINVAL; goto __error);
 		ctl = snd_emu10k1_look_for_ctl(emu, &gctl.id);
 		memset(&knew, 0, sizeof(knew));
 		knew.iface = gctl.id.iface;
@@ -694,9 +722,9 @@
 				continue;
 			knew.private_value = (unsigned long)ctl;
 			memcpy(ctl, &nctl, sizeof(nctl));
-			if (snd_ctl_add(emu->card, kctl = snd_ctl_new1(&knew, emu)) < 0) {
+			if ((err = snd_ctl_add(emu->card, kctl = snd_ctl_new1(&knew, emu))) < 0) {
 				kfree(ctl);
-				continue;
+				goto __error;
 			}
 			kctl->private_free = snd_emu10k1_ctl_private_free;
 			ctl->kcontrol = kctl;
@@ -711,10 +739,12 @@
 		}
 		snd_emu10k1_gpr_ctl_put(ctl->kcontrol, val);
 	}
+      __error:
 	kfree(val);
+	return err;
 }
 
-static void snd_emu10k1_del_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
+static int snd_emu10k1_del_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
 {
 	unsigned int i;
 	snd_ctl_elem_id_t id;
@@ -724,13 +754,14 @@
 	
 	for (i = 0, _id = icode->gpr_del_controls;
 	     i < icode->gpr_del_control_count; i++, _id++) {
-	     	snd_runtime_check(copy_from_user(&id, _id, sizeof(id)) == 0, continue);
+	     	snd_runtime_check(copy_from_user(&id, _id, sizeof(id)) == 0, return -EFAULT);
 		down_write(&card->controls_rwsem);
 		ctl = snd_emu10k1_look_for_ctl(emu, &id);
 		if (ctl)
 			snd_ctl_remove(card, ctl->kcontrol);
 		up_write(&card->controls_rwsem);
 	}
+	return 0;
 }
 
 static int snd_emu10k1_list_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
@@ -789,11 +820,12 @@
 	else
 		snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_SINGLE_STEP);
 	/* ok, do the main job */
-	snd_emu10k1_del_controls(emu, icode);
-	snd_emu10k1_gpr_poke(emu, icode);
-	snd_emu10k1_tram_poke(emu, icode);
-	snd_emu10k1_code_poke(emu, icode);
-	snd_emu10k1_add_controls(emu, icode);
+	if ((err = snd_emu10k1_del_controls(emu, icode)) < 0 ||
+	    (err = snd_emu10k1_gpr_poke(emu, icode)) < 0 ||
+	    (err = snd_emu10k1_tram_poke(emu, icode)) < 0 ||
+	    (err = snd_emu10k1_code_poke(emu, icode)) < 0 ||
+	    (err = snd_emu10k1_add_controls(emu, icode)) < 0)
+		goto __error;
 	/* start FX processor when the DSP code is updated */
 	if (emu->audigy)
 		snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg);
@@ -811,10 +843,13 @@
 	down(&emu->fx8010.lock);
 	strlcpy(icode->name, emu->fx8010.name, sizeof(icode->name));
 	/* ok, do the main job */
-	snd_emu10k1_gpr_peek(emu, icode);
-	snd_emu10k1_tram_peek(emu, icode);
-	snd_emu10k1_code_peek(emu, icode);
-	err = snd_emu10k1_list_controls(emu, icode);
+	err = snd_emu10k1_gpr_peek(emu, icode);
+	if (err >= 0)
+		err = snd_emu10k1_tram_peek(emu, icode);
+	if (err >= 0)
+		err = snd_emu10k1_code_peek(emu, icode);
+	if (err >= 0)
+		err = snd_emu10k1_list_controls(emu, icode);
 	up(&emu->fx8010.lock);
 	return err;
 }
@@ -957,20 +992,24 @@
 	const int stereo_mix = capture + 2;
 	const int tmp = 0x88;
 	u32 ptr;
-	emu10k1_fx8010_code_t *icode;
-	emu10k1_fx8010_control_gpr_t *controls, *ctl;
+	emu10k1_fx8010_code_t *icode = NULL;
+	emu10k1_fx8010_control_gpr_t *controls = NULL, *ctl;
 	mm_segment_t seg;
 
 	spin_lock_init(&emu->fx8010.irq_lock);
 	INIT_LIST_HEAD(&emu->fx8010.gpr_ctl);
 
-	if ((icode = kcalloc(1, sizeof(*icode), GFP_KERNEL)) == NULL)
-		return -ENOMEM;
-	if ((controls = kcalloc(SND_EMU10K1_GPR_CONTROLS, sizeof(*controls), GFP_KERNEL)) == NULL) {
-		kfree(icode);
-		return -ENOMEM;
+	if ((icode = kcalloc(1, sizeof(*icode), GFP_KERNEL)) == NULL ||
+	    (icode->gpr_map = kcalloc(512 + 256 + 256 + 2 * 1024, sizeof(u_int32_t), GFP_KERNEL)) == NULL ||
+	    (controls = kcalloc(SND_EMU10K1_GPR_CONTROLS, sizeof(*controls), GFP_KERNEL)) == NULL) {
+		err = -ENOMEM;
+		goto __err;
 	}
 
+	icode->tram_data_map = icode->gpr_map + 512;
+	icode->tram_addr_map = icode->tram_data_map + 256;
+	icode->code = icode->tram_addr_map + 256;
+
 	/* clear free GPRs */
 	for (i = 0; i < 512; i++)
 		set_bit(i, icode->gpr_valid);
@@ -1312,8 +1351,12 @@
 	A_PUT_OUTPUT(A_EXTOUT_LFE, playback+5 + SND_EMU10K1_PLAYBACK_CHANNELS);
 
 	/* ADC buffer */
+#ifdef EMU10K1_CAPTURE_DIGITAL_OUT
+	A_PUT_STEREO_OUTPUT(A_EXTOUT_ADC_CAP_L, A_EXTOUT_ADC_CAP_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
+#else
 	A_PUT_OUTPUT(A_EXTOUT_ADC_CAP_L, capture);
 	A_PUT_OUTPUT(A_EXTOUT_ADC_CAP_R, capture+1);
+#endif
 
 	/*
 	 * ok, set up done..
@@ -1335,8 +1378,13 @@
 	snd_leave_user(seg);
 
  __err:
-	kfree(controls);
-	kfree(icode);
+ 	if (controls != NULL)
+		kfree(controls);
+	if (icode != NULL) {
+		if (icode->gpr_map != NULL)
+			kfree(icode->gpr_map);
+		kfree(icode);
+	}
 	return err;
 }
 
@@ -1398,8 +1446,8 @@
 	int err, i, z, gpr, tmp, playback, capture;
 	u32 ptr;
 	emu10k1_fx8010_code_t *icode;
-	emu10k1_fx8010_pcm_t *ipcm;
-	emu10k1_fx8010_control_gpr_t *controls, *ctl;
+	emu10k1_fx8010_pcm_t *ipcm = NULL;
+	emu10k1_fx8010_control_gpr_t *controls = NULL, *ctl;
 	mm_segment_t seg;
 
 	spin_lock_init(&emu->fx8010.irq_lock);
@@ -1407,15 +1455,16 @@
 
 	if ((icode = kcalloc(1, sizeof(*icode), GFP_KERNEL)) == NULL)
 		return -ENOMEM;
-	if ((controls = kcalloc(SND_EMU10K1_GPR_CONTROLS, sizeof(emu10k1_fx8010_control_gpr_t), GFP_KERNEL)) == NULL) {
-		kfree(icode);
-		return -ENOMEM;
-	}
-	if ((ipcm = kcalloc(1, sizeof(*ipcm), GFP_KERNEL)) == NULL) {
-		kfree(controls);
-		kfree(icode);
-		return -ENOMEM;
+	if ((icode->gpr_map = kcalloc(256 + 160 + 160 + 2 * 512, sizeof(u_int32_t), GFP_KERNEL)) == NULL ||
+            (controls = kcalloc(SND_EMU10K1_GPR_CONTROLS, sizeof(emu10k1_fx8010_control_gpr_t), GFP_KERNEL)) == NULL ||
+	    (ipcm = kcalloc(1, sizeof(*ipcm), GFP_KERNEL)) == NULL) {
+		err = -ENOMEM;
+		goto __err;
 	}
+
+	icode->tram_data_map = icode->gpr_map + 256;
+	icode->tram_addr_map = icode->tram_data_map + 160;
+	icode->code = icode->tram_addr_map + 160;
 	
 	/* clear free GPRs */
 	for (i = 0; i < 256; i++)
@@ -1906,9 +1955,15 @@
 	if (err >= 0)
 		err = snd_emu10k1_ipcm_poke(emu, ipcm);
       __err:
-	kfree(ipcm);
-	kfree(controls);
-	kfree(icode);
+      	if (ipcm != NULL)
+		kfree(ipcm);
+	if (controls != NULL)
+		kfree(controls);
+	if (icode != NULL) {
+		if (icode->gpr_map != NULL)
+			kfree(icode->gpr_map);
+		kfree(icode);
+	}
 	return err;
 }
 
@@ -1959,7 +2014,7 @@
 		}
 		size = 0x2000 << size_reg;
 	}
-	if (emu->fx8010.etram_pages.bytes == size)
+	if ((emu->fx8010.etram_pages.bytes / 2) == size)
 		return 0;
 	spin_lock_irq(&emu->emu_lock);
 	outl(HCFG_LOCKTANKCACHE_MASK | inl(emu->port + HCFG), emu->port + HCFG);
diff -Nru a/sound/pci/emu10k1/emumixer.c b/sound/pci/emu10k1/emumixer.c
--- a/sound/pci/emu10k1/emumixer.c	2005-03-01 23:39:09 -08:00
+++ b/sound/pci/emu10k1/emumixer.c	2005-03-01 23:39:09 -08:00
@@ -54,7 +54,7 @@
 	ucontrol->value.iec958.status[2] = (emu->spdif_bits[idx] >> 16) & 0xff;
 	ucontrol->value.iec958.status[3] = (emu->spdif_bits[idx] >> 24) & 0xff;
 	spin_unlock_irqrestore(&emu->reg_lock, flags);
-        return 0;
+	return 0;
 }
 
 static int snd_emu10k1_spdif_get_mask(snd_kcontrol_t * kcontrol,
@@ -64,7 +64,7 @@
 	ucontrol->value.iec958.status[1] = 0xff;
 	ucontrol->value.iec958.status[2] = 0xff;
 	ucontrol->value.iec958.status[3] = 0xff;
-        return 0;
+	return 0;
 }
 
 static int snd_emu10k1_spdif_put(snd_kcontrol_t * kcontrol,
@@ -87,27 +87,27 @@
 		emu->spdif_bits[idx] = val;
 	}
 	spin_unlock_irqrestore(&emu->reg_lock, flags);
-        return change;
+	return change;
 }
 
 static snd_kcontrol_new_t snd_emu10k1_spdif_mask_control =
 {
 	.access =	SNDRV_CTL_ELEM_ACCESS_READ,
-        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
-        .name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
+	.iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
 	.count =	4,
-        .info =         snd_emu10k1_spdif_info,
-        .get =          snd_emu10k1_spdif_get_mask
+	.info =         snd_emu10k1_spdif_info,
+	.get =          snd_emu10k1_spdif_get_mask
 };
 
 static snd_kcontrol_new_t snd_emu10k1_spdif_control =
 {
-        .iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
-        .name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
+	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
 	.count =	4,
-        .info =         snd_emu10k1_spdif_info,
-        .get =          snd_emu10k1_spdif_get,
-        .put =          snd_emu10k1_spdif_put
+	.info =         snd_emu10k1_spdif_info,
+	.get =          snd_emu10k1_spdif_get,
+	.put =          snd_emu10k1_spdif_put
 };
 
 
@@ -165,7 +165,7 @@
 			ucontrol->value.integer.value[(voice * num_efx) + idx] = 
 				mix->send_routing[voice][idx] & mask;
 	spin_unlock_irqrestore(&emu->reg_lock, flags);
-        return 0;
+	return 0;
 }
 
 static int snd_emu10k1_send_routing_put(snd_kcontrol_t * kcontrol,
@@ -199,18 +199,18 @@
 		}
 	}
 	spin_unlock_irqrestore(&emu->reg_lock, flags);
-        return change;
+	return change;
 }
 
 static snd_kcontrol_new_t snd_emu10k1_send_routing_control =
 {
 	.access =	SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
-        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
-        .name =         "EMU10K1 PCM Send Routing",
+	.iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name =         "EMU10K1 PCM Send Routing",
 	.count =	32,
-        .info =         snd_emu10k1_send_routing_info,
-        .get =          snd_emu10k1_send_routing_get,
-        .put =          snd_emu10k1_send_routing_put
+	.info =         snd_emu10k1_send_routing_info,
+	.get =          snd_emu10k1_send_routing_get,
+	.put =          snd_emu10k1_send_routing_put
 };
 
 static int snd_emu10k1_send_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
@@ -236,7 +236,7 @@
 	for (idx = 0; idx < 3*num_efx; idx++)
 		ucontrol->value.integer.value[idx] = mix->send_volume[idx/num_efx][idx%num_efx];
 	spin_unlock_irqrestore(&emu->reg_lock, flags);
-        return 0;
+	return 0;
 }
 
 static int snd_emu10k1_send_volume_put(snd_kcontrol_t * kcontrol,
@@ -268,18 +268,18 @@
 		}
 	}
 	spin_unlock_irqrestore(&emu->reg_lock, flags);
-        return change;
+	return change;
 }
 
 static snd_kcontrol_new_t snd_emu10k1_send_volume_control =
 {
 	.access =	SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
-        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
-        .name =         "EMU10K1 PCM Send Volume",
+	.iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name =         "EMU10K1 PCM Send Volume",
 	.count =	32,
-        .info =         snd_emu10k1_send_volume_info,
-        .get =          snd_emu10k1_send_volume_get,
-        .put =          snd_emu10k1_send_volume_put
+	.info =         snd_emu10k1_send_volume_info,
+	.get =          snd_emu10k1_send_volume_get,
+	.put =          snd_emu10k1_send_volume_put
 };
 
 static int snd_emu10k1_attn_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
@@ -303,7 +303,7 @@
 	for (idx = 0; idx < 3; idx++)
 		ucontrol->value.integer.value[idx] = mix->attn[idx];
 	spin_unlock_irqrestore(&emu->reg_lock, flags);
-        return 0;
+	return 0;
 }
 
 static int snd_emu10k1_attn_put(snd_kcontrol_t * kcontrol,
@@ -331,18 +331,18 @@
 		}
 	}
 	spin_unlock_irqrestore(&emu->reg_lock, flags);
-        return change;
+	return change;
 }
 
 static snd_kcontrol_new_t snd_emu10k1_attn_control =
 {
 	.access =	SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
-        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
-        .name =         "EMU10K1 PCM Volume",
+	.iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name =         "EMU10K1 PCM Volume",
 	.count =	32,
-        .info =         snd_emu10k1_attn_info,
-        .get =          snd_emu10k1_attn_get,
-        .put =          snd_emu10k1_attn_put
+	.info =         snd_emu10k1_attn_info,
+	.get =          snd_emu10k1_attn_get,
+	.put =          snd_emu10k1_attn_put
 };
 
 static int snd_emu10k1_shared_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
@@ -363,7 +363,7 @@
 		ucontrol->value.integer.value[0] = inl(emu->port + A_IOCFG) & A_IOCFG_GPOUT0 ? 1 : 0;
 	else
 		ucontrol->value.integer.value[0] = inl(emu->port + HCFG) & HCFG_GPOUT0 ? 1 : 0;
-        return 0;
+	return 0;
 }
 
 static int snd_emu10k1_shared_spdif_put(snd_kcontrol_t * kcontrol,
@@ -394,7 +394,7 @@
 		outl(reg | val, emu->port + HCFG);
 	}
 	spin_unlock_irqrestore(&emu->reg_lock, flags);
-        return change;
+	return change;
 }
 
 static snd_kcontrol_new_t snd_emu10k1_shared_spdif __devinitdata =
@@ -519,6 +519,7 @@
 
 		if ((err = snd_ac97_bus(emu->card, 0, &ops, NULL, &pbus)) < 0)
 			return err;
+		pbus->no_vra = 1; /* we don't need VRA */
 		
 		memset(&ac97, 0, sizeof(ac97));
 		ac97.private_data = emu;
diff -Nru a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c
--- a/sound/pci/emu10k1/emupcm.c	2005-03-01 23:38:44 -08:00
+++ b/sound/pci/emu10k1/emupcm.c	2005-03-01 23:38:44 -08:00
@@ -267,6 +267,7 @@
 		send_routing[3] = 3;
 		memset(send_amount, 0, sizeof(send_amount));
 	} else {
+		/* mono, left, right (master voice = left) */
 		tmp = stereo ? (master ? 1 : 2) : 0;
 		memcpy(send_routing, &mix->send_routing[tmp][0], 8);
 		memcpy(send_amount, &mix->send_volume[tmp][0], 8);
@@ -292,15 +293,9 @@
 	// setup routing
 	if (emu->audigy) {
 		snd_emu10k1_ptr_write(emu, A_FXRT1, voice,
-				      ((unsigned int)send_routing[3] << 24) |
-				      ((unsigned int)send_routing[2] << 16) |
-				      ((unsigned int)send_routing[1] << 8) |
-				      (unsigned int)send_routing[0]);
+				      snd_emu10k1_compose_audigy_fxrt1(send_routing));
 		snd_emu10k1_ptr_write(emu, A_FXRT2, voice,
-				      ((unsigned int)send_routing[7] << 24) |
-				      ((unsigned int)send_routing[6] << 16) |
-				      ((unsigned int)send_routing[5] << 8) |
-				      (unsigned int)send_routing[4]);
+				      snd_emu10k1_compose_audigy_fxrt2(send_routing));
 		snd_emu10k1_ptr_write(emu, A_SENDAMOUNTS, voice,
 				      ((unsigned int)send_amount[4] << 24) |
 				      ((unsigned int)send_amount[5] << 16) |
@@ -777,8 +772,7 @@
 {
 	emu10k1_pcm_t *epcm = runtime->private_data;
 
-	if (epcm)
-		kfree(epcm);
+	kfree(epcm);
 }
 
 static int snd_emu10k1_playback_open(snd_pcm_substream_t * substream)
diff -Nru a/sound/pci/emu10k1/emuproc.c b/sound/pci/emu10k1/emuproc.c
--- a/sound/pci/emu10k1/emuproc.c	2005-03-01 23:38:55 -08:00
+++ b/sound/pci/emu10k1/emuproc.c	2005-03-01 23:38:55 -08:00
@@ -175,32 +175,45 @@
 	};
 
 	emu10k1_t *emu = entry->private_data;
-	unsigned int val;
+	unsigned int val, val1;
 	int nefx = emu->audigy ? 64 : 32;
 	char **outputs = emu->audigy ? audigy_outs : creative_outs;
 	int idx;
 	
 	snd_iprintf(buffer, "EMU10K1\n\n");
-	val = emu->audigy ?
-		snd_emu10k1_ptr_read(emu, A_FXRT1, 0) :
-		snd_emu10k1_ptr_read(emu, FXRT, 0);
 	snd_iprintf(buffer, "Card                  : %s\n",
 		    emu->audigy ? "Audigy" : (emu->APS ? "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);
 	snd_iprintf(buffer, "\n");
-	if (emu->audigy) {
-		snd_iprintf(buffer, "Effect Send Routing   : A=%i, B=%i, C=%i, D=%i\n",
-			    val & 0x3f,
-			    (val >> 8) & 0x3f,
-			    (val >> 16) & 0x3f,
-			    (val >> 24) & 0x3f);
-	} else {
-		snd_iprintf(buffer, "Effect Send Routing   : A=%i, B=%i, C=%i, D=%i\n",
-			    (val >> 16) & 0x0f,
-			    (val >> 20) & 0x0f,
-			    (val >> 24) & 0x0f,
-			    (val >> 28) & 0x0f);
+	snd_iprintf(buffer, "Effect Send Routing   :\n");
+	for (idx = 0; idx < NUM_G; idx++) {
+		val = emu->audigy ?
+			snd_emu10k1_ptr_read(emu, A_FXRT1, idx) :
+			snd_emu10k1_ptr_read(emu, FXRT, idx);
+		val1 = emu->audigy ?
+			snd_emu10k1_ptr_read(emu, A_FXRT2, idx) :
+			0;
+		if (emu->audigy) {
+			snd_iprintf(buffer, "Ch%i: A=%i, B=%i, C=%i, D=%i, ",
+				idx,
+				val & 0x3f,
+				(val >> 8) & 0x3f,
+				(val >> 16) & 0x3f,
+				(val >> 24) & 0x3f);
+			snd_iprintf(buffer, "E=%i, F=%i, G=%i, H=%i\n",
+				val1 & 0x3f,
+				(val1 >> 8) & 0x3f,
+				(val1 >> 16) & 0x3f,
+				(val1 >> 24) & 0x3f);
+		} else {
+			snd_iprintf(buffer, "Ch%i: A=%i, B=%i, C=%i, D=%i\n",
+				idx,
+				(val >> 16) & 0x0f,
+				(val >> 20) & 0x0f,
+				(val >> 24) & 0x0f,
+				(val >> 28) & 0x0f);
+		}
 	}
 	snd_iprintf(buffer, "\nCaptured FX Outputs   :\n");
 	for (idx = 0; idx < nefx; idx++) {
@@ -309,6 +322,152 @@
 	return 0;
 }
 
+#ifdef CONFIG_SND_DEBUG
+static void snd_emu_proc_io_reg_read(snd_info_entry_t *entry,
+				     snd_info_buffer_t * buffer)
+{
+	emu10k1_t *emu = entry->private_data;
+	unsigned long value;
+	unsigned long flags;
+	int i;
+	snd_iprintf(buffer, "IO Registers:\n\n");
+	for(i = 0; i < 0x40; i+=4) {
+		spin_lock_irqsave(&emu->emu_lock, flags);
+		value = inl(emu->port + i);
+		spin_unlock_irqrestore(&emu->emu_lock, flags);
+		snd_iprintf(buffer, "%02X: %08lX\n", i, value);
+	}
+}
+
+static void snd_emu_proc_io_reg_write(snd_info_entry_t *entry,
+                                      snd_info_buffer_t * buffer)
+{
+	emu10k1_t *emu = entry->private_data;
+	unsigned long flags;
+	char line[64];
+	u32 reg, val;
+	while (!snd_info_get_line(buffer, line, sizeof(line))) {
+		if (sscanf(line, "%x %x", &reg, &val) != 2)
+			continue;
+		if ((reg < 0x40) && (reg >=0) && (val <= 0xffffffff) ) {
+			spin_lock_irqsave(&emu->emu_lock, flags);
+			outl(val, emu->port + (reg & 0xfffffffc));
+			spin_unlock_irqrestore(&emu->emu_lock, flags);
+		}
+	}
+}
+
+static unsigned int snd_ptr_read(emu10k1_t * emu,
+				 unsigned int iobase,
+				 unsigned int reg,
+				 unsigned int chn)
+{
+	unsigned long flags;
+	unsigned int regptr, val;
+
+	regptr = (reg << 16) | chn;
+
+	spin_lock_irqsave(&emu->emu_lock, flags);
+	outl(regptr, emu->port + iobase + PTR);
+	val = inl(emu->port + iobase + DATA);
+	spin_unlock_irqrestore(&emu->emu_lock, flags);
+	return val;
+}
+
+static void snd_ptr_write(emu10k1_t *emu,
+			  unsigned int iobase,
+			  unsigned int reg,
+			  unsigned int chn,
+			  unsigned int data)
+{
+	unsigned int regptr;
+	unsigned long flags;
+
+	regptr = (reg << 16) | chn;
+
+	spin_lock_irqsave(&emu->emu_lock, flags);
+	outl(regptr, emu->port + iobase + PTR);
+	outl(data, emu->port + iobase + DATA);
+	spin_unlock_irqrestore(&emu->emu_lock, flags);
+}
+
+
+static void snd_emu_proc_ptr_reg_read(snd_info_entry_t *entry,
+				      snd_info_buffer_t * buffer, int iobase, int offset, int length)
+{
+	emu10k1_t *emu = entry->private_data;
+	unsigned long value;
+	int i,j;
+	if (offset+length > 0x80) {
+		snd_iprintf(buffer, "Input values out of range\n");
+		return;
+	}
+	snd_iprintf(buffer, "Registers 0x%x\n", iobase);
+	for(i = offset; i < offset+length; i++) {
+		snd_iprintf(buffer, "%02X: ",i);
+		for (j = 0; j < 4; j++) {
+			if(iobase == 0)
+                		value = snd_ptr_read(emu, 0, i, j);
+			else
+                		value = snd_ptr_read(emu, 0x20, i, j);
+			snd_iprintf(buffer, "%08lX ", value);
+		}
+		snd_iprintf(buffer, "\n");
+	}
+}
+
+static void snd_emu_proc_ptr_reg_write(snd_info_entry_t *entry,
+				       snd_info_buffer_t * buffer, int iobase)
+{
+	emu10k1_t *emu = entry->private_data;
+	char line[64];
+	unsigned int reg, channel_id , val;
+	while (!snd_info_get_line(buffer, line, sizeof(line))) {
+		if (sscanf(line, "%x %x %x", &reg, &channel_id, &val) != 3)
+			continue;
+		if ((reg < 0x80) && (reg >=0) && (val <= 0xffffffff) && (channel_id >=0) && (channel_id <= 3) )
+			snd_ptr_write(emu, iobase, reg, channel_id, val);
+	}
+}
+
+static void snd_emu_proc_ptr_reg_write00(snd_info_entry_t *entry,
+					 snd_info_buffer_t * buffer)
+{
+	snd_emu_proc_ptr_reg_write(entry, buffer, 0);
+}
+
+static void snd_emu_proc_ptr_reg_write20(snd_info_entry_t *entry,
+					 snd_info_buffer_t * buffer)
+{
+	snd_emu_proc_ptr_reg_write(entry, buffer, 0x20);
+}
+	
+
+static void snd_emu_proc_ptr_reg_read00a(snd_info_entry_t *entry,
+					 snd_info_buffer_t * buffer)
+{
+	snd_emu_proc_ptr_reg_read(entry, buffer, 0, 0, 0x40);
+}
+
+static void snd_emu_proc_ptr_reg_read00b(snd_info_entry_t *entry,
+					 snd_info_buffer_t * buffer)
+{
+	snd_emu_proc_ptr_reg_read(entry, buffer, 0, 0x40, 0x40);
+}
+
+static void snd_emu_proc_ptr_reg_read20a(snd_info_entry_t *entry,
+					 snd_info_buffer_t * buffer)
+{
+	snd_emu_proc_ptr_reg_read(entry, buffer, 0x20, 0, 0x40);
+}
+
+static void snd_emu_proc_ptr_reg_read20b(snd_info_entry_t *entry,
+					 snd_info_buffer_t * buffer)
+{
+	snd_emu_proc_ptr_reg_read(entry, buffer, 0x20, 0x40, 0x40);
+}
+#endif
+
 static struct snd_info_entry_ops snd_emu10k1_proc_ops_fx8010 = {
 	.read = snd_emu10k1_fx8010_read,
 };
@@ -316,9 +475,36 @@
 int __devinit snd_emu10k1_proc_init(emu10k1_t * emu)
 {
 	snd_info_entry_t *entry;
+#ifdef CONFIG_SND_DEBUG
+	if (! snd_card_proc_new(emu->card, "io_regs", &entry)) {
+		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;
+	}
+	if (! snd_card_proc_new(emu->card, "ptr_regs00a", &entry)) {
+		snd_info_set_text_ops(entry, emu, 1024, snd_emu_proc_ptr_reg_read00a);
+		entry->c.text.write_size = 64;
+		entry->c.text.write = snd_emu_proc_ptr_reg_write00;
+	}
+	if (! snd_card_proc_new(emu->card, "ptr_regs00b", &entry)) {
+		snd_info_set_text_ops(entry, emu, 1024, snd_emu_proc_ptr_reg_read00b);
+		entry->c.text.write_size = 64;
+		entry->c.text.write = snd_emu_proc_ptr_reg_write00;
+	}
+	if (! snd_card_proc_new(emu->card, "ptr_regs20a", &entry)) {
+		snd_info_set_text_ops(entry, emu, 1024, snd_emu_proc_ptr_reg_read20a);
+		entry->c.text.write_size = 64;
+		entry->c.text.write = snd_emu_proc_ptr_reg_write20;
+	}
+	if (! snd_card_proc_new(emu->card, "ptr_regs20b", &entry)) {
+		snd_info_set_text_ops(entry, emu, 1024, snd_emu_proc_ptr_reg_read20b);
+		entry->c.text.write_size = 64;
+		entry->c.text.write = snd_emu_proc_ptr_reg_write20;
+	}
+#endif
 	
 	if (! snd_card_proc_new(emu->card, "emu10k1", &entry))
-		snd_info_set_text_ops(entry, emu, 1024, snd_emu10k1_proc_read);
+		snd_info_set_text_ops(entry, emu, 2048, snd_emu10k1_proc_read);
 
 	if (! snd_card_proc_new(emu->card, "fx8010_gpr", &entry)) {
 		entry->content = SNDRV_INFO_CONTENT_DATA;
diff -Nru a/sound/pci/emu10k1/io.c b/sound/pci/emu10k1/io.c
--- a/sound/pci/emu10k1/io.c	2005-03-01 23:38:54 -08:00
+++ b/sound/pci/emu10k1/io.c	2005-03-01 23:38:54 -08:00
@@ -313,28 +313,3 @@
 	return 0;		/* Should never reach this point */
 }
 
-/*
- *  Returns an attenuation based upon a cumulative volume value
- *  Algorithm calculates 0x200 - 0x10 log2 (input)
- */
- 
-unsigned char snd_emu10k1_sum_vol_attn(unsigned int value)
-{
-	unsigned short count = 16, ans;
-
-	if (value == 0)
-		return 0xFF;
-
-	/* Find first SET bit. This is the integer part of the value */
-	while ((value & 0x10000) == 0) {
-		value <<= 1;
-		count--;
-	}
-
-	/* The REST of the data is the fractional part. */
-	ans = (unsigned short) (0x110 - ((count << 4) + ((value & 0x0FFFFL) >> 12)));
-	if (ans > 0xFF)
-		ans = 0xFF;
-
-	return (unsigned char) ans;
-}
diff -Nru a/sound/pci/emu10k1/irq.c b/sound/pci/emu10k1/irq.c
--- a/sound/pci/emu10k1/irq.c	2005-03-01 23:39:08 -08:00
+++ b/sound/pci/emu10k1/irq.c	2005-03-01 23:39:08 -08:00
@@ -112,8 +112,8 @@
 			status &= ~(IPR_A_MIDITRANSBUFEMPTY2|IPR_A_MIDIRECVBUFEMPTY2);
 		}
 		if (status & IPR_INTERVALTIMER) {
-			if (emu->timer_interrupt)
-				emu->timer_interrupt(emu);
+			if (emu->timer)
+				snd_timer_interrupt(emu->timer, emu->timer->sticks);
 			else
 				snd_emu10k1_intr_disable(emu, INTE_INTERVALTIMERENB);
 			status &= ~IPR_INTERVALTIMER;
diff -Nru a/sound/pci/emu10k1/timer.c b/sound/pci/emu10k1/timer.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/sound/pci/emu10k1/timer.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,99 @@
+/*
+ *  Copyright (c) by Lee Revell <rlrevell@joe-job.com>
+ *  
+ *  Routines for control of EMU10K1 chips
+ *
+ *  Copied from similar code by Clemens Ladisch in the ymfpci driver
+ * 
+ *  BUGS:
+ *    --
+ *
+ *  TODO:
+ *    --
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You 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/time.h>
+#include <sound/core.h>
+#include <sound/emu10k1.h>
+
+static int snd_emu10k1_timer_start(snd_timer_t *timer)
+{
+	emu10k1_t *emu;
+	unsigned long flags;
+	unsigned int delay;
+
+	emu = snd_timer_chip(timer);
+	delay = timer->sticks - 1;
+	if (delay < 5 ) /* minimum time is 5 ticks */
+		delay = 5;
+	spin_lock_irqsave(&emu->reg_lock, flags);
+	snd_emu10k1_intr_enable(emu, INTE_INTERVALTIMERENB);
+	outw(delay & TIMER_RATE_MASK, emu->port + TIMER);
+	spin_unlock_irqrestore(&emu->reg_lock, flags);
+	return 0;
+}
+
+static int snd_emu10k1_timer_stop(snd_timer_t *timer)
+{
+	emu10k1_t *emu;
+	unsigned long flags;
+
+	emu = snd_timer_chip(timer);
+	spin_lock_irqsave(&emu->reg_lock, flags);
+	snd_emu10k1_intr_disable(emu, INTE_INTERVALTIMERENB);
+	spin_unlock_irqrestore(&emu->reg_lock, flags);
+	return 0;
+}
+
+static int snd_emu10k1_timer_precise_resolution(snd_timer_t *timer,
+					       unsigned long *num, unsigned long *den)
+{
+	*num = 1;
+	*den = 48000;
+	return 0;
+}
+
+static struct _snd_timer_hardware snd_emu10k1_timer_hw = {
+	.flags = SNDRV_TIMER_HW_AUTO,
+	.resolution = 20833, /* 1 sample @ 48KHZ = 20.833...us */
+	.ticks = 1024,
+	.start = snd_emu10k1_timer_start,
+	.stop = snd_emu10k1_timer_stop,
+	.precise_resolution = snd_emu10k1_timer_precise_resolution,
+};
+
+int __devinit snd_emu10k1_timer(emu10k1_t *emu, int device)
+{
+	snd_timer_t *timer = NULL;
+	snd_timer_id_t tid;
+	int err;
+
+	tid.dev_class = SNDRV_TIMER_CLASS_CARD;
+	tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
+	tid.card = emu->card->number;
+	tid.device = device;
+	tid.subdevice = 0;
+	if ((err = snd_timer_new(emu->card, "EMU10K1", &tid, &timer)) >= 0) {
+		strcpy(timer->name, "EMU10K1 timer");
+		timer->private_data = emu;
+		timer->hw = snd_emu10k1_timer_hw;
+	}
+	emu->timer = timer;
+	return err;
+}
diff -Nru a/sound/pci/ens1370.c b/sound/pci/ens1370.c
--- a/sound/pci/ens1370.c	2005-03-01 23:39:09 -08:00
+++ b/sound/pci/ens1370.c	2005-03-01 23:39:09 -08:00
@@ -573,24 +573,18 @@
 				   unsigned short reg, unsigned short val)
 {
 	ensoniq_t *ensoniq = ak4531->private_data;
-	unsigned long flags;
 	unsigned long end_time = jiffies + HZ / 10;
 
 #if 0
 	printk("CODEC WRITE: reg = 0x%x, val = 0x%x (0x%x), creg = 0x%x\n", reg, val, ES_1370_CODEC_WRITE(reg, val), ES_REG(ensoniq, 1370_CODEC));
 #endif
 	do {
-		spin_lock_irqsave(&ensoniq->reg_lock, flags);
 		if (!(inl(ES_REG(ensoniq, STATUS)) & ES_1370_CSTAT)) {
 			outw(ES_1370_CODEC_WRITE(reg, val), ES_REG(ensoniq, 1370_CODEC));
-			spin_unlock_irqrestore(&ensoniq->reg_lock, flags);
 			return;
 		}
-		spin_unlock_irqrestore(&ensoniq->reg_lock, flags);
-#if 0
 		set_current_state(TASK_UNINTERRUPTIBLE);
 		schedule_timeout(1);
-#endif
 	} while (time_after(end_time, jiffies));
 	snd_printk("codec write timeout, status = 0x%x\n", inl(ES_REG(ensoniq, STATUS)));
 }
@@ -603,11 +597,10 @@
 				   unsigned short reg, unsigned short val)
 {
 	ensoniq_t *ensoniq = ac97->private_data;
-	unsigned long flags;
 	unsigned int t, x;
 
+	down(&ensoniq->src_mutex);
 	for (t = 0; t < POLL_COUNT; t++) {
-		spin_lock_irqsave(&ensoniq->reg_lock, flags);
 		if (!(inl(ES_REG(ensoniq, 1371_CODEC)) & ES_1371_CODEC_WIP)) {
 			/* save the current state for latter */
 			x = snd_es1371_wait_src_ready(ensoniq);
@@ -629,11 +622,11 @@
 			/* restore SRC reg */
 			snd_es1371_wait_src_ready(ensoniq);
 			outl(x, ES_REG(ensoniq, 1371_SMPRATE));
-			spin_unlock_irqrestore(&ensoniq->reg_lock, flags);
+			up(&ensoniq->src_mutex);
 			return;
 		}
-		spin_unlock_irqrestore(&ensoniq->reg_lock, flags);
 	}
+	up(&ensoniq->src_mutex);
 	snd_printk("codec write timeout at 0x%lx [0x%x]\n", ES_REG(ensoniq, 1371_CODEC), inl(ES_REG(ensoniq, 1371_CODEC)));
 }
 
@@ -641,12 +634,11 @@
 					    unsigned short reg)
 {
 	ensoniq_t *ensoniq = ac97->private_data;
-	unsigned long flags;
 	unsigned int t, x, fail = 0;
 
       __again:
+	down(&ensoniq->src_mutex);
 	for (t = 0; t < POLL_COUNT; t++) {
-		spin_lock_irqsave(&ensoniq->reg_lock, flags);
 		if (!(inl(ES_REG(ensoniq, 1371_CODEC)) & ES_1371_CODEC_WIP)) {
 			/* save the current state for latter */
 			x = snd_es1371_wait_src_ready(ensoniq);
@@ -676,19 +668,19 @@
 			/* now wait for the stinkin' data (RDY) */
 			for (t = 0; t < POLL_COUNT; t++) {
 				if ((x = inl(ES_REG(ensoniq, 1371_CODEC))) & ES_1371_CODEC_RDY) {
-					spin_unlock_irqrestore(&ensoniq->reg_lock, flags);
+					up(&ensoniq->src_mutex);
 					return ES_1371_CODEC_READ(x);
 				}
 			}
-			spin_unlock_irqrestore(&ensoniq->reg_lock, flags);
+			up(&ensoniq->src_mutex);
 			if (++fail > 10) {
 				snd_printk("codec read timeout (final) at 0x%lx, reg = 0x%x [0x%x]\n", ES_REG(ensoniq, 1371_CODEC), reg, inl(ES_REG(ensoniq, 1371_CODEC)));
 				return 0;
 			}
 			goto __again;
 		}
-		spin_unlock_irqrestore(&ensoniq->reg_lock, flags);
 	}
+	up(&ensoniq->src_mutex);
 	snd_printk("es1371: codec read timeout at 0x%lx [0x%x]\n", ES_REG(ensoniq, 1371_CODEC), inl(ES_REG(ensoniq, 1371_CODEC)));
 	return 0;
 }
@@ -1635,8 +1627,10 @@
 		if (err < 0)
 			return err;
 	}
-	if ((ensoniq->subsystem_vendor_id == 0x1274) &&
-	    (ensoniq->subsystem_device_id == 0x2000)) { /* GA-7DXR */
+	if (((ensoniq->subsystem_vendor_id == 0x1274) &&
+	    (ensoniq->subsystem_device_id == 0x2000)) || /* GA-7DXR */
+	    ((ensoniq->subsystem_vendor_id == 0x1458) &&
+	    (ensoniq->subsystem_device_id == 0xa000))) { /* GA-8IEXP */
 		 err = snd_ctl_add(card, snd_ctl_new1(&snd_ens1373_line, ensoniq));
 		 if (err < 0)
 			 return err;
@@ -1930,7 +1924,6 @@
 	ensoniq->subsystem_vendor_id = cmdw;
 	pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &cmdw);
 	ensoniq->subsystem_device_id = cmdw;
-	snd_ensoniq_proc_init(ensoniq);
 #ifdef CHIP1370
 #if 0
 	ensoniq->ctrl = ES_1370_CDC_EN | ES_1370_SERR_DISABLE | ES_1370_PCLKDIVO(ES_1370_SRTODIV(8000));
@@ -2022,6 +2015,8 @@
 		snd_ensoniq_free(ensoniq);
 		return err;
 	}
+
+	snd_ensoniq_proc_init(ensoniq);
 
 	snd_card_set_dev(card, &pci->dev);
 
diff -Nru a/sound/pci/es1938.c b/sound/pci/es1938.c
--- a/sound/pci/es1938.c	2005-03-01 23:39:07 -08:00
+++ b/sound/pci/es1938.c	2005-03-01 23:39:07 -08:00
@@ -1395,7 +1395,6 @@
 	outb(0x00, SLIO_REG(chip, IRQCONTROL)); /* disable irqs */
 
 	pci_disable_device(chip->pci);
-	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
 	return 0;
 }
 
@@ -1415,7 +1414,6 @@
 			snd_es1938_write(chip, *s, *d);
 	}
 
-	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
 	return 0;
 }
 #endif /* CONFIG_PM */
@@ -1424,8 +1422,9 @@
 {
 	/* disable irqs */
 	outb(0x00, SLIO_REG(chip, IRQCONTROL));
-	/*if (chip->rmidi)
-	  snd_es1938_mixer_bits(chip, ESSSB_IREG_MPU401CONTROL, 0x40, 0);*/
+	if (chip->rmidi)
+		snd_es1938_mixer_bits(chip, ESSSB_IREG_MPU401CONTROL, 0x40, 0);
+
 #if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
 	if (chip->gameport.io)
 		gameport_unregister_port(&chip->gameport);
@@ -1576,6 +1575,9 @@
 
 	/* MPU401 */
 	if (status & 0x80) {
+		// the following line is evil! It switches off MIDI interrupt handling after the first interrupt received.
+		// replacing the last 0 by 0x40 works for ESS-Solo1, but just doing nothing works as well!
+		// andreas@flying-snail.de
 		// snd_es1938_mixer_bits(chip, ESSSB_IREG_MPU401CONTROL, 0x40, 0); /* ack? */
 		if (chip->rmidi) {
 			handled = 1;
@@ -1690,8 +1692,11 @@
 	if (snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
 				chip->mpu_port, 1, chip->irq, 0, &chip->rmidi) < 0) {
 		printk(KERN_ERR "es1938: unable to initialize MPU-401\n");
-	} /*else
-	    snd_es1938_mixer_bits(chip, ESSSB_IREG_MPU401CONTROL, 0x40, 0x40);*/
+	} else {
+		// this line is vital for MIDI interrupt handling on ess-solo1
+		// andreas@flying-snail.de
+		snd_es1938_mixer_bits(chip, ESSSB_IREG_MPU401CONTROL, 0x40, 0x40);
+	}
 
 #if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
 	chip->gameport.io = chip->game_port;
diff -Nru a/sound/pci/es1968.c b/sound/pci/es1968.c
--- a/sound/pci/es1968.c	2005-03-01 23:39:08 -08:00
+++ b/sound/pci/es1968.c	2005-03-01 23:39:08 -08:00
@@ -584,7 +584,7 @@
 	snd_rawmidi_t *rmidi;
 
 	spinlock_t reg_lock;
-	struct semaphore ac97_mutex;	/* ac97 lock */
+	spinlock_t ac97_lock;
 	struct tasklet_struct hwvol_tq;
 
 	/* Maestro Stuff */
@@ -686,35 +686,36 @@
 static void snd_es1968_ac97_write(ac97_t *ac97, unsigned short reg, unsigned short val)
 {
 	es1968_t *chip = ac97->private_data;
+	unsigned long flags;
 
-	down(&chip->ac97_mutex);
 	snd_es1968_ac97_wait(chip);
 
 	/* Write the bus */
+	spin_lock_irqsave(&chip->ac97_lock, flags);
 	outw(val, chip->io_port + ESM_AC97_DATA);
-	msleep(1);
+	/*msleep(1);*/
 	outb(reg, chip->io_port + ESM_AC97_INDEX);
-	msleep(1);
-
-	up(&chip->ac97_mutex);
+	/*msleep(1);*/
+	spin_unlock_irqrestore(&chip->ac97_lock, flags);
 }
 
 static unsigned short snd_es1968_ac97_read(ac97_t *ac97, unsigned short reg)
 {
 	u16 data = 0;
 	es1968_t *chip = ac97->private_data;
+	unsigned long flags;
 
-	down(&chip->ac97_mutex);
 	snd_es1968_ac97_wait(chip);
 
+	spin_lock_irqsave(&chip->ac97_lock, flags);
 	outb(reg | 0x80, chip->io_port + ESM_AC97_INDEX);
-	msleep(1);
+	/*msleep(1);*/
 
 	if (! snd_es1968_ac97_wait(chip)) {
 		data = inw(chip->io_port + ESM_AC97_DATA);
-		msleep(1);
+		/*msleep(1);*/
 	}
-	up(&chip->ac97_mutex);
+	spin_unlock_irqrestore(&chip->ac97_lock, flags);
 
 	return data;
 }
@@ -837,23 +838,19 @@
 static void snd_es1968_bob_stop(es1968_t *chip)
 {
 	u16 reg;
-	unsigned long flags;
 
-	spin_lock_irqsave(&chip->reg_lock, flags);
 	reg = __maestro_read(chip, 0x11);
 	reg &= ~ESM_BOB_ENABLE;
 	__maestro_write(chip, 0x11, reg);
 	reg = __maestro_read(chip, 0x17);
 	reg &= ~ESM_BOB_START;
 	__maestro_write(chip, 0x17, reg);
-	spin_unlock_irqrestore(&chip->reg_lock, flags);
 }
 
 static void snd_es1968_bob_start(es1968_t *chip)
 {
 	int prescale;
 	int divide;
-	unsigned long flags;
 
 	/* compute ideal interrupt frequency for buffer size & play rate */
 	/* first, find best prescaler value to match freq */
@@ -882,13 +879,11 @@
 	} else if (divide > 1)
 		divide--;
 
-	spin_lock_irqsave(&chip->reg_lock, flags);
 	__maestro_write(chip, 6, 0x9000 | (prescale << 5) | divide);	/* set reg */
 
 	/* Now set IDR 11/17 */
 	__maestro_write(chip, 0x11, __maestro_read(chip, 0x11) | 1);
 	__maestro_write(chip, 0x17, __maestro_read(chip, 0x17) | 1);
-	spin_unlock_irqrestore(&chip->reg_lock, flags);
 }
 
 /* call with substream spinlock */
@@ -1931,6 +1926,7 @@
 {
 	es1968_t *chip = (es1968_t *) private_data;
 	int x, val;
+	unsigned long flags;
 
 	/* Figure out which volume control button was pushed,
 	   based on differences from the default register
@@ -1945,11 +1941,15 @@
 	if (! chip->master_switch || ! chip->master_volume)
 		return;
 
-	/* FIXME: more clean up is needed.. */
+	/* 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];
 	if (x & 1) {
 		/* mute */
-		snd_ac97_write_cache(chip->ac97, AC97_MASTER, val ^ 0x8000);
+		val ^= 0x8000;
+		chip->ac97->regs[AC97_MASTER] = val;
+		outw(val, chip->io_port + ESM_AC97_DATA);
+		outb(AC97_MASTER, chip->io_port + ESM_AC97_INDEX);
 		snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
 			       &chip->master_switch->id);
 	} else {
@@ -1967,10 +1967,13 @@
 			if ((val & 0xff00) < 0x1f00)
 				val += 0x0100;
 		}
-		snd_ac97_write_cache(chip->ac97, AC97_MASTER, val);
+		chip->ac97->regs[AC97_MASTER] = val;
+		outw(val, chip->io_port + ESM_AC97_DATA);
+		outb(AC97_MASTER, chip->io_port + ESM_AC97_INDEX);
 		snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
 			       &chip->master_volume->id);
 	}
+	spin_unlock_irqrestore(&chip->ac97_lock, flags);
 }
 
 /*
@@ -2034,6 +2037,7 @@
 
 	if ((err = snd_ac97_bus(chip->card, 0, &ops, NULL, &pbus)) < 0)
 		return err;
+	pbus->no_vra = 1; /* ES1968 doesn't need VRA */
 
 	memset(&ac97, 0, sizeof(ac97));
 	ac97.private_data = chip;
@@ -2412,7 +2416,6 @@
 	snd_es1968_bob_stop(chip);
 	snd_es1968_set_acpi(chip, ACPI_D3);
 	pci_disable_device(chip->pci);
-	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
 	return 0;
 }
 
@@ -2443,7 +2446,6 @@
 	if (chip->bobclient)
 		snd_es1968_bob_start(chip);
 
-	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
 	return 0;
 }
 #endif /* CONFIG_PM */
@@ -2537,7 +2539,7 @@
 	spin_lock_init(&chip->substream_lock);
 	INIT_LIST_HEAD(&chip->buf_list);
 	INIT_LIST_HEAD(&chip->substream_list);
-	init_MUTEX(&chip->ac97_mutex);
+	spin_lock_init(&chip->ac97_lock);
 	init_MUTEX(&chip->memory_mutex);
 	tasklet_init(&chip->hwvol_tq, es1968_update_hw_volume, (unsigned long)chip);
 	chip->card = card;
diff -Nru a/sound/pci/fm801.c b/sound/pci/fm801.c
--- a/sound/pci/fm801.c	2005-03-01 23:39:09 -08:00
+++ b/sound/pci/fm801.c	2005-03-01 23:39:09 -08:00
@@ -208,15 +208,16 @@
 				 unsigned short mask, unsigned short value)
 {
 	int change;
+	unsigned long flags;
 	unsigned short old, new;
 
-	spin_lock(&chip->reg_lock);
+	spin_lock_irqsave(&chip->reg_lock, flags);
 	old = inw(chip->port + reg);
 	new = (old & ~mask) | value;
 	change = old != new;
 	if (change)
 		outw(new, chip->port + reg);
-	spin_unlock(&chip->reg_lock);
+	spin_unlock_irqrestore(&chip->reg_lock, flags);
 	return change;
 }
 
@@ -415,13 +416,12 @@
 
 static int snd_fm801_playback_prepare(snd_pcm_substream_t * substream)
 {
-	unsigned long flags;
 	fm801_t *chip = snd_pcm_substream_chip(substream);
 	snd_pcm_runtime_t *runtime = substream->runtime;
 
 	chip->ply_size = snd_pcm_lib_buffer_bytes(substream);
 	chip->ply_count = snd_pcm_lib_period_bytes(substream);
-	spin_lock_irqsave(&chip->reg_lock, flags);
+	spin_lock_irq(&chip->reg_lock);
 	chip->ply_ctrl &= ~(FM801_START | FM801_16BIT |
 			     FM801_STEREO | FM801_RATE_MASK |
 			     FM801_CHANNELS_MASK);
@@ -442,19 +442,18 @@
 	chip->ply_pos = 0;
 	outl(chip->ply_buffer, FM801_REG(chip, PLY_BUF1));
 	outl(chip->ply_buffer + (chip->ply_count % chip->ply_size), FM801_REG(chip, PLY_BUF2));
-	spin_unlock_irqrestore(&chip->reg_lock, flags);
+	spin_unlock_irq(&chip->reg_lock);
 	return 0;
 }
 
 static int snd_fm801_capture_prepare(snd_pcm_substream_t * substream)
 {
-	unsigned long flags;
 	fm801_t *chip = snd_pcm_substream_chip(substream);
 	snd_pcm_runtime_t *runtime = substream->runtime;
 
 	chip->cap_size = snd_pcm_lib_buffer_bytes(substream);
 	chip->cap_count = snd_pcm_lib_period_bytes(substream);
-	spin_lock_irqsave(&chip->reg_lock, flags);
+	spin_lock_irq(&chip->reg_lock);
 	chip->cap_ctrl &= ~(FM801_START | FM801_16BIT |
 			     FM801_STEREO | FM801_RATE_MASK);
 	if (snd_pcm_format_width(runtime->format) == 16)
@@ -469,7 +468,7 @@
 	chip->cap_pos = 0;
 	outl(chip->cap_buffer, FM801_REG(chip, CAP_BUF1));
 	outl(chip->cap_buffer + (chip->cap_count % chip->cap_size), FM801_REG(chip, CAP_BUF2));
-	spin_unlock_irqrestore(&chip->reg_lock, flags);
+	spin_unlock_irq(&chip->reg_lock);
 	return 0;
 }
 
diff -Nru a/sound/pci/ice1712/ak4xxx.c b/sound/pci/ice1712/ak4xxx.c
--- a/sound/pci/ice1712/ak4xxx.c	2005-03-01 23:38:44 -08:00
+++ b/sound/pci/ice1712/ak4xxx.c	2005-03-01 23:38:44 -08:00
@@ -151,8 +151,7 @@
 		return;
 	for (akidx = 0; akidx < ice->akm_codecs; akidx++) {
 		akm4xxx_t *ak = &ice->akm[akidx];
-		if (ak->private_value[0])
-			kfree((void *)ak->private_value[0]);
+		kfree((void*)ak->private_value[0]);
 	}
 	kfree(ice->akm);
 }
diff -Nru a/sound/pci/ice1712/aureon.c b/sound/pci/ice1712/aureon.c
--- a/sound/pci/ice1712/aureon.c	2005-03-01 23:39:18 -08:00
+++ b/sound/pci/ice1712/aureon.c	2005-03-01 23:39:18 -08:00
@@ -27,18 +27,10 @@
  *   both controls in the future, once if wm codecs are reused in
  *   many boards.
  *
- * - writing over SPI is implemented but reading is not yet.
- *   the SPDIF-in channel status, etc. can be read from CS chip.
- *
  * - DAC digital volumes are not implemented in the mixer.
  *   if they show better response than DAC analog volumes, we can use them
  *   instead.
  *
- * - Aureon boards are equipped with AC97 codec, too.  it's used to do
- *   the analog mixing but not easily controllable (it's not connected
- *   directly from envy24ht chip).  so let's leave it as it is.
- *
- *
  *   Lowlevel functions for AudioTrak Prodigy 7.1 (and possibly 192) cards
  *      Copyright (c) 2003 Dimitromanolakis Apostolos <apostol@cs.utoronto.ca>
  *
@@ -53,10 +45,6 @@
  *                    we have no digital output, no capture, pretty bad clicks and poops
  *                    on mixer switch and other coll stuff.
  *
- * - Prodigy boards are equipped with AC97 STAC9744 chip , too.  it's used to do
- *   the analog mixing but not easily controllable (it's not connected
- *   directly from envy24ht chip).  so let's leave it as it is.
- *
  */      
 
 #include <sound/driver.h>
@@ -89,6 +77,14 @@
 #define WM_OUT_MUX2		0x1e	/* output MUX */
 #define WM_RESET		0x1f	/* software reset */
 
+/* CS8415A registers */
+#define CS8415_CTRL1	0x01
+#define CS8415_CTRL2	0x02
+#define CS8415_QSUB		0x14
+#define CS8415_RATIO	0x1E
+#define CS8415_C_BUFFER	0x20
+#define CS8415_ID		0x7F
+
 static void aureon_ac97_write(ice1712_t *ice, unsigned short reg, unsigned short val) {
 	unsigned int tmp;
 
@@ -325,47 +321,109 @@
 static void aureon_spi_write(ice1712_t *ice, unsigned int cs, unsigned int data, int bits)
 {
 	unsigned int tmp;
-	unsigned int cscs;
 	int i;
 
 	tmp = snd_ice1712_gpio_read(ice);
 
-	if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71)
-		cscs = PRODIGY_CS8415_CS;
-	else
-		cscs = AUREON_CS8415_CS;
-
-	snd_ice1712_gpio_set_mask(ice, ~(AUREON_WM_RW|AUREON_WM_DATA|AUREON_WM_CLK|
-					 AUREON_WM_CS|cscs));
+	snd_ice1712_gpio_set_mask(ice, ~(AUREON_WM_RW|AUREON_SPI_MOSI|AUREON_SPI_CLK|
+					 AUREON_WM_CS|AUREON_CS8415_CS));
 	tmp |= AUREON_WM_RW;
 	tmp &= ~cs;
 	snd_ice1712_gpio_write(ice, tmp);
 	udelay(1);
 
 	for (i = bits - 1; i >= 0; i--) {
-		tmp &= ~AUREON_WM_CLK;
+		tmp &= ~AUREON_SPI_CLK;
 		snd_ice1712_gpio_write(ice, tmp);
 		udelay(1);
 		if (data & (1 << i))
-			tmp |= AUREON_WM_DATA;
+			tmp |= AUREON_SPI_MOSI;
 		else
-			tmp &= ~AUREON_WM_DATA;
+			tmp &= ~AUREON_SPI_MOSI;
 		snd_ice1712_gpio_write(ice, tmp);
 		udelay(1);
-		tmp |= AUREON_WM_CLK;
+		tmp |= AUREON_SPI_CLK;
 		snd_ice1712_gpio_write(ice, tmp);
 		udelay(1);
 	}
 
-	tmp &= ~AUREON_WM_CLK;
+	tmp &= ~AUREON_SPI_CLK;
 	tmp |= cs;
 	snd_ice1712_gpio_write(ice, tmp);
 	udelay(1);
-	tmp |= AUREON_WM_CLK;
+	tmp |= AUREON_SPI_CLK;
+	snd_ice1712_gpio_write(ice, tmp);
+	udelay(1);
+}
+
+/*
+ * Read data in SPI mode
+ */
+static void aureon_spi_read(ice1712_t *ice, unsigned int cs, unsigned int data, int bits, unsigned char *buffer, int size) {
+	int i, j;
+	unsigned int tmp;
+
+	tmp = (snd_ice1712_gpio_read(ice) & ~AUREON_SPI_CLK) | AUREON_CS8415_CS|AUREON_WM_CS;
+	snd_ice1712_gpio_write(ice, tmp);
+	tmp &= ~cs;
 	snd_ice1712_gpio_write(ice, tmp);
 	udelay(1);
+
+	for (i=bits-1; i>=0; i--) {
+		if (data & (1 << i))
+			tmp |= AUREON_SPI_MOSI;
+		else
+			tmp &= ~AUREON_SPI_MOSI;
+		snd_ice1712_gpio_write(ice, tmp);
+		udelay(1);
+
+		tmp |= AUREON_SPI_CLK;
+		snd_ice1712_gpio_write(ice, tmp);
+		udelay(1);
+
+		tmp &= ~AUREON_SPI_CLK;
+		snd_ice1712_gpio_write(ice, tmp);
+		udelay(1);
+	}
+
+	for (j=0; j<size; j++) {
+		unsigned char outdata = 0;
+		for (i=7; i>=0; i--) {
+			tmp = snd_ice1712_gpio_read(ice);
+			outdata <<= 1;
+			outdata |= (tmp & AUREON_SPI_MISO) ? 1 : 0;
+			udelay(1);
+
+			tmp |= AUREON_SPI_CLK;
+			snd_ice1712_gpio_write(ice, tmp);
+			udelay(1);
+
+			tmp &= ~AUREON_SPI_CLK;
+			snd_ice1712_gpio_write(ice, tmp);
+			udelay(1);
+		}
+		buffer[j] = outdata;
+	}
+
+	tmp |= cs;
+	snd_ice1712_gpio_write(ice, tmp);
+}
+
+static unsigned char aureon_cs8415_get(ice1712_t *ice, int reg) {
+	unsigned char val;
+	aureon_spi_write(ice, AUREON_CS8415_CS, 0x2000 | reg, 16);
+	aureon_spi_read(ice, AUREON_CS8415_CS, 0x21, 8, &val, 1);
+	return val;
+}
+
+static void aureon_cs8415_read(ice1712_t *ice, int reg, unsigned char *buffer, int size) {
+	aureon_spi_write(ice, AUREON_CS8415_CS, 0x2000 | reg, 16);
+	aureon_spi_read(ice, AUREON_CS8415_CS, 0x21, 8, buffer, size);
+}
+
+static void aureon_cs8415_put(ice1712_t *ice, int reg, unsigned char val) {
+	aureon_spi_write(ice, AUREON_CS8415_CS, 0x200000 | (reg << 8) | val, 24);
 }
-     
 
 /*
  * get the current register value of WM codec
@@ -845,12 +903,32 @@
 		"Mic",		//AIN4
 		"AC97"		//AIN5
 	};
+	static char *universe_texts[] = {
+		"Aux1",		//AIN1
+		"CD",		//AIN2
+		"Phono",	//AIN3
+		"Line",		//AIN4
+		"Aux2",		//AIN5
+		"Mic",		//AIN6
+		"Aux3",		//AIN7
+		"AC97"		//AIN8
+	};
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
 	uinfo->count = 2;
-	uinfo->value.enumerated.items = 5;
-	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]);
+	if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON71_UNIVERSE) {
+		uinfo->value.enumerated.items = 8;
+		if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
+			uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
+		strcpy(uinfo->value.enumerated.name, universe_texts[uinfo->value.enumerated.item]);
+	}
+	else {
+		uinfo->value.enumerated.items = 5;
+		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;
 }
 
@@ -886,6 +964,154 @@
 }
 
 /*
+ * CS8415 Input mux
+ */
+static int aureon_cs8415_mux_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	static char *aureon_texts[] = {
+		"CD",		//RXP0
+		"Optical"	//RXP1
+	};
+	static char *prodigy_texts[] = {
+		"CD",
+		"Coax"
+	};
+	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;
+	if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71)
+		strcpy(uinfo->value.enumerated.name, prodigy_texts[uinfo->value.enumerated.item]);
+	else
+		strcpy(uinfo->value.enumerated.name, aureon_texts[uinfo->value.enumerated.item]);
+	return 0;
+}
+
+static int aureon_cs8415_mux_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+
+	//snd_ice1712_save_gpio_status(ice);
+	//val = aureon_cs8415_get(ice, CS8415_CTRL2);
+	ucontrol->value.integer.value[0] = ice->spec.aureon.cs8415_mux;
+	//snd_ice1712_restore_gpio_status(ice);
+	return 0;
+}
+
+static int aureon_cs8415_mux_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	unsigned short oval, nval;
+	int change;
+
+	snd_ice1712_save_gpio_status(ice);
+	oval = aureon_cs8415_get(ice, CS8415_CTRL2);
+	nval = oval & ~0x07;
+	nval |= ucontrol->value.integer.value[0] & 7;
+	change = (oval != nval);
+	if (change)
+		aureon_cs8415_put(ice, CS8415_CTRL2, nval);
+	snd_ice1712_restore_gpio_status(ice);
+	ice->spec.aureon.cs8415_mux = ucontrol->value.integer.value[0];
+	return change;
+}
+
+static int aureon_cs8415_rate_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;
+	uinfo->value.integer.max = 192000;
+	return 0;
+}
+
+static int aureon_cs8415_rate_get (snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	unsigned char ratio;
+	ratio = aureon_cs8415_get(ice, CS8415_RATIO);
+	ucontrol->value.integer.value[0] = (int)((unsigned int)ratio * 750);
+	return 0;
+}
+
+/*
+ * CS8415A Mute
+ */
+static int aureon_cs8415_mute_info (snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+	uinfo->count = 1;
+	return 0;
+}
+
+static int aureon_cs8415_mute_get (snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	snd_ice1712_save_gpio_status(ice);
+	ucontrol->value.integer.value[0] = (aureon_cs8415_get(ice, CS8415_CTRL1) & 0x20) ? 0 : 1;
+	snd_ice1712_restore_gpio_status(ice);
+	return 0;
+}
+
+static int aureon_cs8415_mute_put (snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	unsigned char oval, nval;
+	int change;
+	snd_ice1712_save_gpio_status(ice);
+	oval = aureon_cs8415_get(ice, CS8415_CTRL1);
+	if (ucontrol->value.integer.value[0])
+		nval = oval & ~0x20;
+	else
+		nval = oval | 0x20;
+	if ((change = (oval != nval)))
+		aureon_cs8415_put(ice, CS8415_CTRL1, nval);
+	snd_ice1712_restore_gpio_status(ice);
+	return change;
+}
+
+/*
+ * CS8415A Q-Sub info
+ */
+static int aureon_cs8415_qsub_info (snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) {
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
+	uinfo->count = 10;
+	return 0;
+}
+
+static int aureon_cs8415_qsub_get (snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) {
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	
+	snd_ice1712_save_gpio_status(ice);
+	aureon_cs8415_read(ice, CS8415_QSUB, ucontrol->value.bytes.data, 10);
+	snd_ice1712_restore_gpio_status(ice);
+
+	return 0;
+}
+
+static int aureon_cs8415_spdif_info (snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) {
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
+	uinfo->count = 1;
+	return 0;
+}
+
+static int aureon_cs8415_mask_get (snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) {
+	memset(ucontrol->value.iec958.status, 0xFF, 24);
+	return 0;
+}
+
+static int aureon_cs8415_spdif_get (snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) {
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+
+	snd_ice1712_save_gpio_status(ice);
+	aureon_cs8415_read(ice, CS8415_C_BUFFER, ucontrol->value.iec958.status, 24);
+	snd_ice1712_restore_gpio_status(ice);
+	return 0;
+}
+
+/*
  * Headphone Amplifier
  */
 static int aureon_set_headphone_amp(ice1712_t *ice, int enable)
@@ -1142,7 +1368,7 @@
 	},
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-		.name = "Headphone Amplifier Switch",
+		.name = "External Amplifier",
 		.info = aureon_hpamp_info,
 		.get = aureon_hpamp_get,
 		.put = aureon_hpamp_put
@@ -1160,7 +1386,7 @@
 		.info = aureon_oversampling_info,
 		.get = aureon_oversampling_get,
 		.put = aureon_oversampling_put
-	},
+	}
 };
 
 static snd_kcontrol_new_t ac97_controls[] __devinitdata = {
@@ -1246,12 +1472,165 @@
  	},
  	{
  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- 		.name = "Mic Boost",
+ 		.name = "Mic Boost (+20dB)",
+ 		.info = aureon_ac97_micboost_info,
+ 		.get = aureon_ac97_micboost_get,
+ 		.put = aureon_ac97_micboost_put
+ 	}
+};
+
+static snd_kcontrol_new_t universe_ac97_controls[] __devinitdata = {
+ 	{
+ 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "AC97 Playback Switch",
+		.info = aureon_ac97_mmute_info,
+		.get = aureon_ac97_mmute_get,
+		.put = aureon_ac97_mmute_put,
+		.private_value = AC97_MASTER
+ 	},
+ 	{
+ 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ 		.name = "AC97 Playback Volume",
+ 		.info = aureon_ac97_vol_info,
+ 		.get = aureon_ac97_vol_get,
+ 		.put = aureon_ac97_vol_put,
+ 		.private_value = AC97_MASTER|AUREON_AC97_STEREO
+ 	},
+ 	{
+ 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ 		.name = "CD Playback Switch",
+ 		.info = aureon_ac97_mute_info,
+ 		.get = aureon_ac97_mute_get,
+ 		.put = aureon_ac97_mute_put,
+ 		.private_value = AC97_AUX
+ 	},
+ 	{
+ 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ 		.name = "CD Playback Volume",
+ 		.info = aureon_ac97_vol_info,
+ 		.get = aureon_ac97_vol_get,
+ 		.put = aureon_ac97_vol_put,
+ 		.private_value = AC97_AUX|AUREON_AC97_STEREO
+ 	},
+ 	{
+ 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ 		.name = "Phono Playback Switch",
+ 		.info = aureon_ac97_mute_info,
+ 		.get = aureon_ac97_mute_get,
+ 		.put = aureon_ac97_mute_put,
+ 		.private_value = AC97_CD,
+ 	},
+ 	{
+ 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ 		.name = "Phono Playback Volume",
+ 		.info = aureon_ac97_vol_info,
+ 		.get = aureon_ac97_vol_get,
+ 		.put = aureon_ac97_vol_put,
+ 		.private_value = AC97_CD|AUREON_AC97_STEREO
+ 	},
+ 	{
+ 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ 		.name = "Line Playback Switch",
+ 		.info = aureon_ac97_mute_info,
+ 		.get = aureon_ac97_mute_get,
+ 		.put = aureon_ac97_mute_put,
+ 		.private_value = AC97_LINE
+ 	},
+ 	{
+ 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ 		.name = "Line Playback Volume",
+ 		.info = aureon_ac97_vol_info,
+ 		.get = aureon_ac97_vol_get,
+ 		.put = aureon_ac97_vol_put,
+ 		.private_value = AC97_LINE|AUREON_AC97_STEREO
+ 	},
+ 	{
+ 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ 		.name = "Mic Playback Switch",
+ 		.info = aureon_ac97_mute_info,
+ 		.get = aureon_ac97_mute_get,
+ 		.put = aureon_ac97_mute_put,
+ 		.private_value = AC97_MIC
+ 	},
+ 	{
+ 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ 		.name = "Mic Playback Volume",
+ 		.info = aureon_ac97_vol_info,
+ 		.get = aureon_ac97_vol_get,
+ 		.put = aureon_ac97_vol_put,
+ 		.private_value = AC97_MIC
+ 	},
+ 	{
+ 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ 		.name = "Mic Boost (+20dB)",
  		.info = aureon_ac97_micboost_info,
  		.get = aureon_ac97_micboost_get,
  		.put = aureon_ac97_micboost_put
+ 	},
+ 	{
+ 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ 		.name = "Aux Playback Switch",
+ 		.info = aureon_ac97_mute_info,
+ 		.get = aureon_ac97_mute_get,
+ 		.put = aureon_ac97_mute_put,
+ 		.private_value = AC97_VIDEO,
+ 	},
+ 	{
+ 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ 		.name = "Aux Playback Volume",
+ 		.info = aureon_ac97_vol_info,
+ 		.get = aureon_ac97_vol_get,
+ 		.put = aureon_ac97_vol_put,
+ 		.private_value = AC97_VIDEO|AUREON_AC97_STEREO
  	}
 };
+
+	
+static snd_kcontrol_new_t cs8415_controls[] __devinitdata = {
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH),
+		.info = aureon_cs8415_mute_info,
+		.get = aureon_cs8415_mute_get,
+		.put = aureon_cs8415_mute_put
+	},
+ 	{
+ 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = SNDRV_CTL_NAME_IEC958("",CAPTURE,NONE) "Source",
+		.info = aureon_cs8415_mux_info,
+		.get = aureon_cs8415_mux_get,
+		.put = aureon_cs8415_mux_put,
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_PCM,
+		.name = SNDRV_CTL_NAME_IEC958("Q-subcode ",CAPTURE,DEFAULT),
+		.access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
+		.info = aureon_cs8415_qsub_info,
+		.get = aureon_cs8415_qsub_get,
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_PCM,
+		.name = SNDRV_CTL_NAME_IEC958("",CAPTURE,MASK),
+		.access = SNDRV_CTL_ELEM_ACCESS_READ,
+		.info = aureon_cs8415_spdif_info,
+		.get = aureon_cs8415_mask_get
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_PCM,
+		.name = SNDRV_CTL_NAME_IEC958("",CAPTURE,DEFAULT),
+		.access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
+		.info = aureon_cs8415_spdif_info,
+		.get = aureon_cs8415_spdif_get
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_PCM,
+		.name = SNDRV_CTL_NAME_IEC958("",CAPTURE,NONE) "Rate",
+		.access =SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
+		.info = aureon_cs8415_rate_info,
+		.get = aureon_cs8415_rate_get
+	}
+};
+
  
 static int __devinit aureon_add_controls(ice1712_t *ice)
 {
@@ -1273,10 +1652,40 @@
 			return err;
 	}
 	
-	for (i = 0; i < ARRAY_SIZE(ac97_controls); i++) {
-		err = snd_ctl_add(ice->card, snd_ctl_new1(&ac97_controls[i], ice));
-		if (err < 0)
-			return err;
+	if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON71_UNIVERSE) {
+		for (i = 0; i < ARRAY_SIZE(universe_ac97_controls); i++) {
+			err = snd_ctl_add(ice->card, snd_ctl_new1(&universe_ac97_controls[i], ice));
+			if (err < 0)
+				return err;
+		}
+	}
+	else {
+		for (i = 0; i < ARRAY_SIZE(ac97_controls); i++) {
+			err = snd_ctl_add(ice->card, snd_ctl_new1(&ac97_controls[i], ice));
+			if (err < 0)
+				return err;
+		}
+	}
+
+	{
+		unsigned char id;
+		snd_ice1712_save_gpio_status(ice);
+		id = aureon_cs8415_get(ice, CS8415_ID);
+		if (id != 0x41)
+			snd_printk("No CS8415 chip. Skipping CS8415 controls.\n");
+		else if ((id & 0x0F) != 0x01)
+			snd_printk("Detected unsupported CS8415 rev. (%c)\n", (char)((id & 0x0F) + 'A' - 1));
+		else {
+			for (i = 0; i< ARRAY_SIZE(cs8415_controls); i++) {
+				snd_kcontrol_t *kctl;
+				err = snd_ctl_add(ice->card, (kctl = snd_ctl_new1(&cs8415_controls[i], ice)));
+				if (err < 0)
+					return err;
+				if (i > 1)
+					kctl->id.device = ice->pcm->device;
+			}
+		}
+		snd_ice1712_restore_gpio_status(ice);
 	}
 	
 	return 0;
@@ -1290,9 +1699,9 @@
 {
 	static unsigned short wm_inits_aureon[] = {
 		/* These come first to reduce init pop noise */
-		0x1b, 0x005,		/* ADC Mux (AC'97 source) */
-		0x1c, 0x00B,		/* Out Mux1 (VOUT1 = ADC+AUX, VOUT2 = ADC) */
-		0x1d, 0x009,		/* Out Mux2 (VOUT2 = ADC, VOUT3 = ADC) */
+		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 */
 
@@ -1375,7 +1784,6 @@
 	};
 	unsigned int tmp;
 	unsigned short *p;
-	unsigned int cscs;
 	int err, i;
 
 	if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON51_SKY) {
@@ -1396,23 +1804,17 @@
 	if ((err = aureon_ac97_init(ice)) != 0)
 		return err;
 
-	if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71)
-		cscs = PRODIGY_CS8415_CS;
-	else
-		cscs = AUREON_CS8415_CS;
-
 	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, ~(AUREON_WM_RESET|AUREON_WM_CS|
-					 cscs|AUREON_HP_SEL));
+	snd_ice1712_gpio_set_mask(ice, ~(AUREON_WM_RESET|AUREON_WM_CS|AUREON_CS8415_CS|AUREON_HP_SEL));
 
 	tmp = snd_ice1712_gpio_read(ice);
 	tmp &= ~AUREON_WM_RESET;
 	snd_ice1712_gpio_write(ice, tmp);
 	udelay(1);
-	tmp |= AUREON_WM_CS | cscs;
+	tmp |= AUREON_WM_CS | AUREON_CS8415_CS;
 	snd_ice1712_gpio_write(ice, tmp);
 	udelay(1);
 	tmp |= AUREON_WM_RESET;
@@ -1429,8 +1831,8 @@
 
 	/* initialize CS8415A codec */
 	for (p = cs_inits; *p != (unsigned short)-1; p++)
-		aureon_spi_write(ice, cscs,
-				 *p | 0x200000, 24);
+		aureon_spi_write(ice, AUREON_CS8415_CS, *p | 0x200000, 24);
+	ice->spec.aureon.cs8415_mux = 1;
 
 	aureon_set_headphone_amp(ice, 1);
 
@@ -1525,12 +1927,12 @@
  	{
  		.subvendor = VT1724_SUBDEVICE_AUREON71_UNIVERSE,
  		.name = "Terratec Aureon 7.1-Universe",
-		/* model not needed - identical with 7.1-Space */
+		.model = "universe",
  		.chip_init = aureon_init,
  		.build_controls = aureon_add_controls,
  		.eeprom_size = sizeof(aureon71_eeprom),
  		.eeprom_data = aureon71_eeprom,
-		.driver = "Aureon71",
+		.driver = "Aureon71Universe",
 	},
 	{
 		.subvendor = VT1724_SUBDEVICE_PRODIGY71,
diff -Nru a/sound/pci/ice1712/aureon.h b/sound/pci/ice1712/aureon.h
--- a/sound/pci/ice1712/aureon.h	2005-03-01 23:39:17 -08:00
+++ b/sound/pci/ice1712/aureon.h	2005-03-01 23:39:17 -08:00
@@ -38,10 +38,10 @@
 
 /* GPIO bits */
 #define AUREON_CS8415_CS	(1 << 22)
-#define AUREON_CS8415_CDTO	(1 << 21)
+#define AUREON_SPI_MISO		(1 << 21)
 #define AUREON_WM_RESET		(1 << 20)
-#define AUREON_WM_CLK		(1 << 19)
-#define AUREON_WM_DATA		(1 << 18)
+#define AUREON_SPI_CLK		(1 << 19)
+#define AUREON_SPI_MOSI		(1 << 18)
 #define AUREON_WM_RW		(1 << 17)
 #define AUREON_AC97_RESET	(1 << 16)
 #define AUREON_DIGITAL_SEL1	(1 << 15)
@@ -52,9 +52,5 @@
 #define AUREON_AC97_DATA_LOW	(1 << 9)
 #define AUREON_AC97_DATA_HIGH	(1 << 8)
 #define AUREON_AC97_DATA_MASK	0xFF
-
-/* Prodigy has different pin assignment for chip select */
-#define PRODIGY_CS8415_CS	(1 << 23)
-#define PRODIGY_CS8415_CDTO	(1 << 22)
 
 #endif /* __SOUND_AUREON_H */
diff -Nru a/sound/pci/ice1712/delta.c b/sound/pci/ice1712/delta.c
--- a/sound/pci/ice1712/delta.c	2005-03-01 23:38:52 -08:00
+++ b/sound/pci/ice1712/delta.c	2005-03-01 23:38:52 -08:00
@@ -530,6 +530,9 @@
 		ice->num_total_dacs = 8;
 		ice->num_total_adcs = 8;
 		break;
+	case ICE1712_SUBDEVICE_DELTADIO2496:
+		ice->num_total_dacs = 4;	/* two AK4324 codecs */
+		break;
 	case ICE1712_SUBDEVICE_VX442:
 		ice->num_total_dacs = 4;
 		ice->num_total_adcs = 4;
diff -Nru a/sound/pci/ice1712/ice1712.h b/sound/pci/ice1712/ice1712.h
--- a/sound/pci/ice1712/ice1712.h	2005-03-01 23:38:51 -08:00
+++ b/sound/pci/ice1712/ice1712.h	2005-03-01 23:38:51 -08:00
@@ -365,6 +365,7 @@
 		/* AC97 register cache for Aureon */
 		struct aureon_spec {
 			unsigned short stac9744[64];
+			unsigned int cs8415_mux;
 			unsigned short master[2];
 			unsigned short vol[8];
 		} aureon;
diff -Nru a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c
--- a/sound/pci/ice1712/ice1724.c	2005-03-01 23:38:56 -08:00
+++ b/sound/pci/ice1712/ice1724.c	2005-03-01 23:38:56 -08:00
@@ -1814,7 +1814,7 @@
 
 static snd_kcontrol_new_t snd_vt1724_mixer_pro_spdif_route __devinitdata = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-	.name = "IEC958 Playback Route",
+	.name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Route",
 	.info = snd_vt1724_pro_route_info,
 	.get = snd_vt1724_pro_route_spdif_get,
 	.put = snd_vt1724_pro_route_spdif_put,
diff -Nru a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
--- a/sound/pci/intel8x0.c	2005-03-01 23:38:59 -08:00
+++ b/sound/pci/intel8x0.c	2005-03-01 23:38:59 -08:00
@@ -53,6 +53,7 @@
 		"{Intel,82801DB-ICH4},"
 		"{Intel,ICH5},"
 		"{Intel,ICH6},"
+		"{Intel,ICH7},"
 		"{Intel,6300ESB},"
 		"{Intel,MX440},"
 		"{SiS,SI7012},"
@@ -66,7 +67,7 @@
 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
 static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;	/* Enable this card */
 static int ac97_clock[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0};
-static int ac97_quirk[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = AC97_TUNE_DEFAULT};
+static char *ac97_quirk[SNDRV_CARDS];
 static int buggy_irq[SNDRV_CARDS];
 static int xbox[SNDRV_CARDS];
 
@@ -82,7 +83,7 @@
 MODULE_PARM_DESC(enable, "Enable Intel i8x0 soundcard.");
 module_param_array(ac97_clock, int, NULL, 0444);
 MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (0 = auto-detect).");
-module_param_array(ac97_quirk, int, NULL, 0444);
+module_param_array(ac97_quirk, charp, NULL, 0444);
 MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware.");
 module_param_array(buggy_irq, bool, NULL, 0444);
 MODULE_PARM_DESC(buggy_irq, "Enable workaround for buggy interrupts on some motherboards.");
@@ -120,6 +121,9 @@
 #ifndef PCI_DEVICE_ID_INTEL_ICH6_3
 #define PCI_DEVICE_ID_INTEL_ICH6_3	0x266e
 #endif
+#ifndef PCI_DEVICE_ID_INTEL_ICH7_20
+#define PCI_DEVICE_ID_INTEL_ICH7_20	0x27de
+#endif
 #ifndef PCI_DEVICE_ID_SI_7012
 #define PCI_DEVICE_ID_SI_7012		0x7012
 #endif
@@ -380,6 +384,7 @@
 	unsigned int ali_slot;			/* ALI DMA slot */
 	struct ac97_pcm *pcm;
 	int pcm_open_flag;
+	unsigned int page_attr_changed: 1;
 } ichdev_t;
 
 typedef struct _snd_intel8x0 intel8x0_t;
@@ -421,7 +426,6 @@
 	unsigned int ac97_sdin[3];
 
 	spinlock_t reg_lock;
-	spinlock_t ac97_lock;
 	
 	u32 bdbars_count;
 	struct snd_dma_buffer bdbars;
@@ -438,6 +442,7 @@
 	{ 0x8086, 0x24d5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL_ICH4 }, /* ICH5 */
 	{ 0x8086, 0x25a6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL_ICH4 }, /* ESB */
 	{ 0x8086, 0x266e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL_ICH4 }, /* ICH6 */
+	{ 0x8086, 0x27de, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL_ICH4 }, /* ICH7 */
 	{ 0x8086, 0x7195, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL },	/* 440MX */
 	{ 0x1039, 0x7012, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_SIS },	/* SI7012 */
 	{ 0x10de, 0x01b1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_NFORCE },	/* NFORCE */
@@ -589,13 +594,11 @@
 {
 	intel8x0_t *chip = ac97->private_data;
 	
-	spin_lock(&chip->ac97_lock);
 	if (snd_intel8x0_codec_semaphore(chip, ac97->num) < 0) {
 		if (! chip->in_ac97_init)
 			snd_printk("codec_write %d: semaphore is not ready for register 0x%x\n", ac97->num, reg);
 	}
 	iaputword(chip, reg + ac97->num * 0x80, val);
-	spin_unlock(&chip->ac97_lock);
 }
 
 static unsigned short snd_intel8x0_codec_read(ac97_t *ac97,
@@ -605,7 +608,6 @@
 	unsigned short res;
 	unsigned int tmp;
 
-	spin_lock(&chip->ac97_lock);
 	if (snd_intel8x0_codec_semaphore(chip, ac97->num) < 0) {
 		if (! chip->in_ac97_init)
 			snd_printk("codec_read %d: semaphore is not ready for register 0x%x\n", ac97->num, reg);
@@ -620,7 +622,6 @@
 			res = 0xffff;
 		}
 	}
-	spin_unlock(&chip->ac97_lock);
 	return res;
 }
 
@@ -628,7 +629,6 @@
 {
 	unsigned int tmp;
 
-	spin_lock(&chip->ac97_lock);
 	if (snd_intel8x0_codec_semaphore(chip, codec) >= 0) {
 		iagetword(chip, codec * 0x80);
 		if ((tmp = igetdword(chip, ICHREG(GLOB_STA))) & ICH_RCS) {
@@ -636,7 +636,6 @@
 			iputdword(chip, ICHREG(GLOB_STA), tmp & ~(ICH_SRI|ICH_PRI|ICH_TRI|ICH_GSCI));
 		}
 	}
-	spin_unlock(&chip->ac97_lock);
 }
 
 /*
@@ -669,7 +668,6 @@
 	intel8x0_t *chip = ac97->private_data;
 	unsigned short data = 0xffff;
 
-	spin_lock(&chip->ac97_lock);
 	if (snd_intel8x0_ali_codec_semaphore(chip))
 		goto __err;
 	reg |= ALI_CPR_ADDR_READ;
@@ -680,7 +678,6 @@
 		goto __err;
 	data = igetword(chip, ICHREG(ALI_SPR));
  __err:
-	spin_unlock(&chip->ac97_lock);
 	return data;
 }
 
@@ -688,17 +685,13 @@
 {
 	intel8x0_t *chip = ac97->private_data;
 
-	spin_lock(&chip->ac97_lock);
-	if (snd_intel8x0_ali_codec_semaphore(chip)) {
-		spin_unlock(&chip->ac97_lock);
+	if (snd_intel8x0_ali_codec_semaphore(chip))
 		return;
-	}
 	iputword(chip, ICHREG(ALI_CPR), val);
 	if (ac97->num)
 		reg |= ALI_CPR_ADDR_SECONDARY;
 	iputword(chip, ICHREG(ALI_CPR_ADDR), reg);
 	snd_intel8x0_ali_codec_ready(chip, ALI_CSPSR_WRITE_OK);
-	spin_unlock(&chip->ac97_lock);
 }
 
 
@@ -942,17 +935,22 @@
 	intel8x0_t *chip = snd_pcm_substream_chip(substream);
 	ichdev_t *ichdev = get_ichdev(substream);
 	snd_pcm_runtime_t *runtime = substream->runtime;
-	size_t size = params_buffer_bytes(hw_params);
 	int dbl = params_rate(hw_params) > 48000;
 	int err;
 
-	if (chip->fix_nocache && runtime->dma_area && runtime->dma_bytes < size)
+	if (chip->fix_nocache && ichdev->page_attr_changed) {
 		fill_nocache(runtime->dma_area, runtime->dma_bytes, 0); /* clear */
+		ichdev->page_attr_changed = 0;
+	}
 	err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
 	if (err < 0)
 		return err;
-	if (chip->fix_nocache && err > 0)
-		fill_nocache(runtime->dma_area, runtime->dma_bytes, 1);
+	if (chip->fix_nocache) {
+		if (runtime->dma_area && ! ichdev->page_attr_changed) {
+			fill_nocache(runtime->dma_area, runtime->dma_bytes, 1);
+			ichdev->page_attr_changed = 1;
+		}
+	}
 	if (ichdev->pcm_open_flag) {
 		snd_ac97_pcm_close(ichdev->pcm);
 		ichdev->pcm_open_flag = 0;
@@ -978,8 +976,10 @@
 		snd_ac97_pcm_close(ichdev->pcm);
 		ichdev->pcm_open_flag = 0;
 	}
-	if (chip->fix_nocache && substream->runtime->dma_area)
+	if (chip->fix_nocache && ichdev->page_attr_changed) {
 		fill_nocache(substream->runtime->dma_area, substream->runtime->dma_bytes, 0);
+		ichdev->page_attr_changed = 0;
+	}
 	return snd_pcm_lib_free_pages(substream);
 }
 
@@ -1729,6 +1729,12 @@
 		.name = "Compaq Evo D510C",
 		.type = AC97_TUNE_HP_ONLY
 	},
+        {
+		.vendor = 0x0e11,
+		.device = 0x0860,
+		.name = "HP/Compaq nx7010",
+		.type = AC97_TUNE_MUTE_LED
+        },
 	{
 		.vendor = 0x1014,
 		.device = 0x1f00,
@@ -1743,6 +1749,12 @@
 	},
 	{
 		.vendor = 0x1028,
+		.device = 0x010d,
+		.name = "Dell",	/* which model?  AD1885 */
+		.type = AC97_TUNE_HP_ONLY
+	},
+	{
+		.vendor = 0x1028,
 		.device = 0x0126,
 		.name = "Dell Optiplex GX260",	/* AD1981A */
 		.type = AC97_TUNE_HP_ONLY
@@ -1753,10 +1765,40 @@
 		.name = "Dell Precision 450",	/* AD1981B*/
 		.type = AC97_TUNE_HP_ONLY
 	},
+	{
+		.vendor = 0x1028,
+		.device = 0x0147,
+		.name = "Dell",	/* which model?  AD1981B*/
+		.type = AC97_TUNE_HP_ONLY
+	},
+	{
+		.vendor = 0x103c,
+		.device = 0x006d,
+		.name = "HP zv5000",
+		.type = AC97_TUNE_MUTE_LED	/*AD1981B*/
+	},
 	{	/* FIXME: which codec? */
 		.vendor = 0x103c,
 		.device = 0x00c3,
-		.name = "Hewlett-Packard onboard",
+		.name = "HP xw6000",
+		.type = AC97_TUNE_HP_ONLY
+	},
+	{
+		.vendor = 0x103c,
+		.device = 0x088c,
+		.name = "HP nc8000",
+		.type = AC97_TUNE_MUTE_LED
+	},
+	{
+		.vendor = 0x103c,
+		.device = 0x0890,
+		.name = "HP nc6000",
+		.type = AC97_TUNE_MUTE_LED
+	},
+	{
+		.vendor = 0x103c,
+		.device = 0x129d,
+		.name = "HP xw8000",
 		.type = AC97_TUNE_HP_ONLY
 	},
 	{
@@ -1767,6 +1809,12 @@
 	},
 	{
 		.vendor = 0x103c,
+		.device = 0x12f2,
+		.name = "HP xw6200",
+		.type = AC97_TUNE_HP_ONLY
+	},
+	{
+		.vendor = 0x103c,
 		.device = 0x3008,
 		.name = "HP xw4200",	/* AD1981B*/
 		.type = AC97_TUNE_HP_ONLY
@@ -1883,7 +1931,7 @@
 	{ } /* terminator */
 };
 
-static int __devinit snd_intel8x0_mixer(intel8x0_t *chip, int ac97_clock, int ac97_quirk)
+static int __devinit snd_intel8x0_mixer(intel8x0_t *chip, int ac97_clock, const char *quirk_override)
 {
 	ac97_bus_t *pbus;
 	ac97_template_t ac97;
@@ -1979,7 +2027,7 @@
 		}
 	}
 	/* tune up the primary codec */
-	snd_ac97_tune_hardware(chip->ac97[0], ac97_quirks, ac97_quirk);
+	snd_ac97_tune_hardware(chip->ac97[0], ac97_quirks, quirk_override);
 	/* enable separate SDINs for ICH4 */
 	if (chip->device_type == DEVICE_INTEL_ICH4)
 		pbus->isdin = 1;
@@ -2279,11 +2327,21 @@
 
 	for (i = 0; i < chip->pcm_devs; i++)
 		snd_pcm_suspend_all(chip->pcm[i]);
+	/* clear nocache */
+	if (chip->fix_nocache) {
+		for (i = 0; i < chip->bdbars_count; i++) {
+			ichdev_t *ichdev = &chip->ichd[i];
+			if (ichdev->substream && ichdev->page_attr_changed) {
+				snd_pcm_runtime_t *runtime = ichdev->substream->runtime;
+				if (runtime->dma_area)
+					fill_nocache(runtime->dma_area, runtime->dma_bytes, 0);
+			}
+		}
+	}
 	for (i = 0; i < 3; i++)
 		if (chip->ac97[i])
 			snd_ac97_suspend(chip->ac97[i]);
 	pci_disable_device(chip->pci);
-	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
 	return 0;
 }
 
@@ -2308,7 +2366,7 @@
 	if (chip->fix_nocache) {
 		for (i = 0; i < chip->bdbars_count; i++) {
 			ichdev_t *ichdev = &chip->ichd[i];
-			if (ichdev->substream) {
+			if (ichdev->substream && ichdev->page_attr_changed) {
 				snd_pcm_runtime_t *runtime = ichdev->substream->runtime;
 				if (runtime->dma_area)
 					fill_nocache(runtime->dma_area, runtime->dma_bytes, 1);
@@ -2316,7 +2374,6 @@
 		}
 	}
 
-	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
 	return 0;
 }
 #endif /* CONFIG_PM */
@@ -2505,7 +2562,6 @@
 		return -ENOMEM;
 	}
 	spin_lock_init(&chip->reg_lock);
-	spin_lock_init(&chip->ac97_lock);
 	chip->device_type = device_type;
 	chip->card = card;
 	chip->pci = pci;
@@ -2658,6 +2714,7 @@
 	{ PCI_DEVICE_ID_INTEL_ICH5, "Intel ICH5" },
 	{ PCI_DEVICE_ID_INTEL_ESB_5, "Intel 6300ESB" },
 	{ PCI_DEVICE_ID_INTEL_ICH6_3, "Intel ICH6" },
+	{ PCI_DEVICE_ID_INTEL_ICH7_20, "Intel ICH7" },
 	{ PCI_DEVICE_ID_SI_7012, "SiS SI7012" },
 	{ PCI_DEVICE_ID_NVIDIA_MCP_AUDIO, "NVidia nForce" },
 	{ PCI_DEVICE_ID_NVIDIA_MCP2_AUDIO, "NVidia nForce2" },
@@ -2765,11 +2822,7 @@
 
 static int __init alsa_card_intel8x0_init(void)
 {
-	int err;
-
-        if ((err = pci_module_init(&driver)) < 0)
-                return err;
-        return 0;
+	return pci_module_init(&driver);
 }
 
 static void __exit alsa_card_intel8x0_exit(void)
diff -Nru a/sound/pci/intel8x0m.c b/sound/pci/intel8x0m.c
--- a/sound/pci/intel8x0m.c	2005-03-01 23:38:58 -08:00
+++ b/sound/pci/intel8x0m.c	2005-03-01 23:38:58 -08:00
@@ -253,7 +253,6 @@
 	ac97_t *ac97;
 
 	spinlock_t reg_lock;
-	spinlock_t ac97_lock;
 	
 	struct snd_dma_buffer bdbars;
 	u32 bdbars_count;
@@ -411,13 +410,11 @@
 {
 	intel8x0_t *chip = ac97->private_data;
 	
-	spin_lock(&chip->ac97_lock);
 	if (snd_intel8x0m_codec_semaphore(chip, ac97->num) < 0) {
 		if (! chip->in_ac97_init)
 			snd_printk("codec_write %d: semaphore is not ready for register 0x%x\n", ac97->num, reg);
 	}
 	iaputword(chip, reg + ac97->num * 0x80, val);
-	spin_unlock(&chip->ac97_lock);
 }
 
 static unsigned short snd_intel8x0_codec_read(ac97_t *ac97,
@@ -427,7 +424,6 @@
 	unsigned short res;
 	unsigned int tmp;
 
-	spin_lock(&chip->ac97_lock);
 	if (snd_intel8x0m_codec_semaphore(chip, ac97->num) < 0) {
 		if (! chip->in_ac97_init)
 			snd_printk("codec_read %d: semaphore is not ready for register 0x%x\n", ac97->num, reg);
@@ -442,7 +438,6 @@
 			res = 0xffff;
 		}
 	}
-	spin_unlock(&chip->ac97_lock);
 	return res;
 }
 
@@ -1093,7 +1088,6 @@
 	if (chip->ac97)
 		snd_ac97_suspend(chip->ac97);
 	pci_disable_device(chip->pci);
-	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
 	return 0;
 }
 
@@ -1106,7 +1100,6 @@
 	if (chip->ac97)
 		snd_ac97_resume(chip->ac97);
 
-	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
 	return 0;
 }
 #endif /* CONFIG_PM */
@@ -1179,7 +1172,6 @@
 		return -ENOMEM;
 	}
 	spin_lock_init(&chip->reg_lock);
-	spin_lock_init(&chip->ac97_lock);
 	chip->device_type = device_type;
 	chip->card = card;
 	chip->pci = pci;
diff -Nru a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c
--- a/sound/pci/korg1212/korg1212.c	2005-03-01 23:38:44 -08:00
+++ b/sound/pci/korg1212/korg1212.c	2005-03-01 23:38:44 -08:00
@@ -472,7 +472,8 @@
                         "SPDIF-R",
 };
 
-u16 ClockSourceSelector[] = {0x8000,   // selects source as ADAT at 44.1 kHz
+static u16 ClockSourceSelector[] =
+                            {0x8000,   // selects source as ADAT at 44.1 kHz
                              0x0000,   // selects source as ADAT at 48 kHz
                              0x8001,   // selects source as S/PDIF at 44.1 kHz
                              0x0001,   // selects source as S/PDIF at 48 kHz
@@ -2411,14 +2412,17 @@
 	if (rc) K1212_DEBUG_PRINTK("K1212_DEBUG: Reboot Card - RC = %d [%s]\n", rc, stateName[korg1212->cardState]);
 #endif
 
+        if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, korg1212, &ops)) < 0) {
+                snd_korg1212_free(korg1212);
+                return err;
+        }
+        
 	snd_korg1212_EnableCardInterrupts(korg1212);
 
 	mdelay(CARD_BOOT_DELAY_IN_MS);
 
-        if (snd_korg1212_downloadDSPCode(korg1212)) {
-                snd_korg1212_free(korg1212);
+        if (snd_korg1212_downloadDSPCode(korg1212))
         	return -EBUSY;
-	}
 
 	printk(KERN_INFO "dspMemPhy       = %08x U[%08x]\n"
                "PlayDataPhy     = %08x L[%08x]\n"
@@ -2433,10 +2437,8 @@
                korg1212->RoutingTablePhy, LowerWordSwap(korg1212->RoutingTablePhy),
                korg1212->AdatTimeCodePhy, LowerWordSwap(korg1212->AdatTimeCodePhy));
 
-        if ((err = snd_pcm_new(korg1212->card, "korg1212", 0, 1, 1, &korg1212->pcm)) < 0) {
-                snd_korg1212_free(korg1212);
+        if ((err = snd_pcm_new(korg1212->card, "korg1212", 0, 1, 1, &korg1212->pcm)) < 0)
                 return err;
-	}
 
 	korg1212->pcm->private_data = korg1212;
         korg1212->pcm->private_free = snd_korg1212_free_pcm;
@@ -2453,18 +2455,11 @@
 
         for (i = 0; i < ARRAY_SIZE(snd_korg1212_controls); i++) {
                 err = snd_ctl_add(korg1212->card, snd_ctl_new1(&snd_korg1212_controls[i], korg1212));
-                if (err < 0) {
-			snd_korg1212_free(korg1212);
+                if (err < 0)
                         return err;
-		}
         }
 
         snd_korg1212_proc_init(korg1212);
-        
-        if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, korg1212, &ops)) < 0) {
-                snd_korg1212_free(korg1212);
-                return err;
-        }
         
 	snd_card_set_dev(card, &pci->dev);
 
diff -Nru a/sound/pci/maestro3.c b/sound/pci/maestro3.c
--- a/sound/pci/maestro3.c	2005-03-01 23:38:58 -08:00
+++ b/sound/pci/maestro3.c	2005-03-01 23:38:58 -08:00
@@ -1835,34 +1835,24 @@
 snd_m3_ac97_read(ac97_t *ac97, unsigned short reg)
 {
 	m3_t *chip = ac97->private_data;
-	unsigned short ret = 0;
-	unsigned long flags;
 
-	spin_lock_irqsave(&chip->reg_lock, flags);
 	if (snd_m3_ac97_wait(chip))
-		goto __error;
-	snd_m3_outb(chip, 0x80 | (reg & 0x7f), 0x30);
+		return 0xffff;
+	snd_m3_outb(chip, 0x80 | (reg & 0x7f), CODEC_COMMAND);
 	if (snd_m3_ac97_wait(chip))
-		goto __error;
-	ret = snd_m3_inw(chip, 0x32);
-__error:
-	spin_unlock_irqrestore(&chip->reg_lock, flags);
-	return ret;
+		return 0xffff;
+	return snd_m3_inw(chip, CODEC_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;
 
-	spin_lock_irqsave(&chip->reg_lock, flags);
 	if (snd_m3_ac97_wait(chip))
-		goto __error;
-	snd_m3_outw(chip, val, 0x32);
-	snd_m3_outb(chip, reg & 0x7f, 0x30);
-__error:
-	spin_unlock_irqrestore(&chip->reg_lock, flags);
+		return;
+	snd_m3_outw(chip, val, CODEC_DATA);
+	snd_m3_outb(chip, reg & 0x7f, CODEC_COMMAND);
 }
 
 
@@ -2374,8 +2364,7 @@
 	}
 
 #ifdef CONFIG_PM
-	if (chip->suspend_mem)
-		vfree(chip->suspend_mem);
+	vfree(chip->suspend_mem);
 #endif
 
 	if (chip->irq >= 0) {
@@ -2425,7 +2414,6 @@
 	snd_m3_outw(chip, 0xffff, 0x56);
 
 	pci_disable_device(chip->pci);
-	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
 	return 0;
 }
 
@@ -2468,7 +2456,6 @@
 	snd_m3_enable_ints(chip);
 	snd_m3_amp_enable(chip, 1);
 
-	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
 	return 0;
 }
 #endif /* CONFIG_PM */
@@ -2577,26 +2564,7 @@
 
 	snd_m3_assp_init(chip);
 	snd_m3_amp_enable(chip, 1);
-    
-	if ((err = snd_m3_mixer(chip)) < 0) {
-		snd_m3_free(chip);
-		return err;
-	}
 
-	for (i = 0; i < chip->num_substreams; i++) {
-		m3_dma_t *s = &chip->substreams[i];
-		s->chip = chip;
-		if ((err = snd_m3_assp_client_init(chip, s, i)) < 0) {
-			snd_m3_free(chip);
-			return err;
-		}
-	}
-    
-	if ((err = snd_m3_pcm(chip, 0)) < 0) {
-		snd_m3_free(chip);
-		return err;
-	}
-    
 	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);
@@ -2618,6 +2586,19 @@
 		return err;
 	}
 
+	if ((err = snd_m3_mixer(chip)) < 0)
+		return err;
+
+	for (i = 0; i < chip->num_substreams; i++) {
+		m3_dma_t *s = &chip->substreams[i];
+		s->chip = chip;
+		if ((err = snd_m3_assp_client_init(chip, s, i)) < 0)
+			return err;
+	}
+
+	if ((err = snd_m3_pcm(chip, 0)) < 0)
+		return err;
+    
 	snd_m3_enable_ints(chip);
 	snd_m3_assp_continue(chip);
 
diff -Nru a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c
--- a/sound/pci/mixart/mixart.c	2005-03-01 23:39:07 -08:00
+++ b/sound/pci/mixart/mixart.c	2005-03-01 23:39:07 -08:00
@@ -526,11 +526,11 @@
 		stream_param.sample_type = ST_INTEGER_24BE;
 		stream_param.sample_size = 24;
 		break;
-	case SNDRV_PCM_FMTBIT_FLOAT_LE:
+	case SNDRV_PCM_FORMAT_FLOAT_LE:
 		stream_param.sample_type = ST_FLOATING_POINT_32LE;
 		stream_param.sample_size = 32;
 		break;
-	case  SNDRV_PCM_FMTBIT_FLOAT_BE:
+	case  SNDRV_PCM_FORMAT_FLOAT_BE:
 		stream_param.sample_type = ST_FLOATING_POINT_32BE;
 		stream_param.sample_size = 32;
 		break;
@@ -1019,13 +1019,6 @@
 		return err;
 	}
 
-	if (idx == 0) {
-		/* create a DSP loader only on first cardX*/
-		err = snd_mixart_hwdep_new(mgr);
-		if (err < 0)
-			return err;
-	}
-
 	snd_card_set_dev(card, &mgr->pci->dev);
 
 	return 0;
@@ -1359,7 +1352,7 @@
 			idx = index[dev];
 		else
 			idx = index[dev] + i;
-		snprintf(tmpid, sizeof(tmpid), "%s-%d", id[dev], i);
+		snprintf(tmpid, sizeof(tmpid), "%s-%d", id[dev] ? id[dev] : "MIXART", i);
 		card = snd_card_new(idx, tmpid, THIS_MODULE, 0);
 
 		if (! card) {
@@ -1410,6 +1403,13 @@
 	}
 	/* init bufferinfo_array */
 	memset(mgr->bufferinfo.area, 0, size);
+
+	/* set up firmware */
+	err = snd_mixart_setup_firmware(mgr);
+	if (err < 0) {
+		snd_mixart_free(mgr);
+		return err;
+	}
 
 	pci_set_drvdata(pci, mgr);
 	dev++;
diff -Nru a/sound/pci/mixart/mixart_core.c b/sound/pci/mixart/mixart_core.c
--- a/sound/pci/mixart/mixart_core.c	2005-03-01 23:39:17 -08:00
+++ b/sound/pci/mixart/mixart_core.c	2005-03-01 23:39:17 -08:00
@@ -72,9 +72,12 @@
 static int get_msg(mixart_mgr_t *mgr, mixart_msg_t *resp, u32 msg_frame_address )
 {
 	unsigned long flags;
-	u32  headptr, i;
+	u32  headptr;
 	u32  size;
 	int  err;
+#ifndef __BIG_ENDIAN
+	unsigned int i;
+#endif
 
 	spin_lock_irqsave(&mgr->msg_lock, flags);
 	err = 0;
@@ -92,7 +95,7 @@
 	}
 	size -= MSG_DESCRIPTOR_SIZE;
 
-	memcpy_fromio(resp->data, (void *)MIXART_MEM(mgr, msg_frame_address + MSG_HEADER_SIZE ), size);
+	memcpy_fromio(resp->data, MIXART_MEM(mgr, msg_frame_address + MSG_HEADER_SIZE ), size);
 	resp->size = size;
 
 	/* swap if necessary */
diff -Nru a/sound/pci/mixart/mixart_hwdep.c b/sound/pci/mixart/mixart_hwdep.c
--- a/sound/pci/mixart/mixart_hwdep.c	2005-03-01 23:39:18 -08:00
+++ b/sound/pci/mixart/mixart_hwdep.c	2005-03-01 23:39:18 -08:00
@@ -1,7 +1,7 @@
 /*
  * Driver for Digigram miXart soundcards
  *
- * hwdep device manager
+ * DSP firmware management
  *
  * Copyright (c) 2003 by Digigram <alsa@digigram.com>
  *
@@ -22,6 +22,8 @@
 
 #include <sound/driver.h>
 #include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/firmware.h>
 #include <asm/io.h>
 #include <sound/core.h>
 #include "mixart.h"
@@ -30,19 +32,6 @@
 #include "mixart_hwdep.h"
 
 
-/* miXart hwdep interface id string */
-#define SND_MIXART_HWDEP_ID       "miXart Loader"
-
-static int mixart_hwdep_open(snd_hwdep_t *hw, struct file *file)
-{
-	return 0;
-}
-
-static int mixart_hwdep_release(snd_hwdep_t *hw, struct file *file)
-{
-	return 0;
-}
-
 /**
  * wait for a value on a peudo register, exit with a timeout
  *
@@ -109,34 +98,30 @@
 	u32     p_align;
 };
 
-static int mixart_load_elf(mixart_mgr_t *mgr, snd_hwdep_dsp_image_t *dsp )
+static int mixart_load_elf(mixart_mgr_t *mgr, const struct firmware *dsp )
 {
 	char                    elf32_magic_number[4] = {0x7f,'E','L','F'};
-	snd_mixart_elf32_ehdr_t elf_header;
+	snd_mixart_elf32_ehdr_t *elf_header;
 	int                     i;
 
-	if ( copy_from_user(&elf_header, dsp->image , sizeof(snd_mixart_elf32_ehdr_t)) )
-		return -EFAULT;
-
+	elf_header = (snd_mixart_elf32_ehdr_t *)dsp->data;
 	for( i=0; i<4; i++ )
-		if ( elf32_magic_number[i] != elf_header.e_ident[i] )
+		if ( elf32_magic_number[i] != elf_header->e_ident[i] )
 			return -EINVAL;
 
-	if( elf_header.e_phoff != 0 ) {
+	if( elf_header->e_phoff != 0 ) {
 		snd_mixart_elf32_phdr_t     elf_programheader;
 
-		for( i=0; i < be16_to_cpu(elf_header.e_phnum); i++ ) {
-			u32 pos = be32_to_cpu(elf_header.e_phoff) + (u32)(i * be16_to_cpu(elf_header.e_phentsize));
+		for( i=0; i < be16_to_cpu(elf_header->e_phnum); i++ ) {
+			u32 pos = be32_to_cpu(elf_header->e_phoff) + (u32)(i * be16_to_cpu(elf_header->e_phentsize));
 
-			if( copy_from_user( &elf_programheader, dsp->image + pos, sizeof(elf_programheader) ) )
-				return -EFAULT;
+			memcpy( &elf_programheader, dsp->data + pos, sizeof(elf_programheader) );
 
 			if(elf_programheader.p_type != 0) {
 				if( elf_programheader.p_filesz != 0 ) {
-					if(copy_from_user_toio( MIXART_MEM( mgr, be32_to_cpu(elf_programheader.p_vaddr)),
-								dsp->image + be32_to_cpu( elf_programheader.p_offset ),
-								be32_to_cpu( elf_programheader.p_filesz )))
-						return -EFAULT;
+					memcpy_toio( MIXART_MEM( mgr, be32_to_cpu(elf_programheader.p_vaddr)),
+						     dsp->data + be32_to_cpu( elf_programheader.p_offset ),
+						     be32_to_cpu( elf_programheader.p_filesz ));
 				}
 			}
 		}
@@ -144,20 +129,6 @@
 	return 0;
 }
 
-static int mixart_hwdep_dsp_status(snd_hwdep_t *hw, snd_hwdep_dsp_status_t *info)
-{
-	mixart_mgr_t *mgr = hw->private_data;
-
-	strcpy(info->id, "miXart");
-        info->num_dsps = MIXART_HARDW_FILES_MAX_INDEX;
-
-	if (mgr->hwdep->dsp_loaded & (1 <<  MIXART_MOTHERBOARD_ELF_INDEX))
-		info->chip_ready = 1;
-
-	info->version = MIXART_DRIVER_VERSION;
-	return 0;
-}
-
 /*
  * get basic information and init miXart
  */
@@ -344,9 +315,8 @@
 /* firmware base addresses (when hard coded) */
 #define MIXART_MOTHERBOARD_XLX_BASE_ADDRESS   0x00600000
 
-static int mixart_hwdep_dsp_load(snd_hwdep_t *hw, snd_hwdep_dsp_image_t *dsp)
+static int mixart_dsp_load(mixart_mgr_t* mgr, int index, const struct firmware *dsp)
 {
-	mixart_mgr_t* mgr = hw->private_data;
 	int           err, card_index;
 	u32           status_xilinx, status_elf, status_daught;
 	u32           val;
@@ -364,7 +334,7 @@
 		return -EAGAIN; /* try again later */
 	}
 
-	switch (dsp->index)   {
+	switch (index)   {
 	case MIXART_MOTHERBOARD_XLX_INDEX:
 
 		/* xilinx already loaded ? */ 
@@ -379,8 +349,8 @@
 		}
 
 		/* check xilinx validity */
-		snd_assert(((u32*)(dsp->image))[0]==0xFFFFFFFF, return -EINVAL);
-		snd_assert(dsp->length % 4 == 0, return -EINVAL);
+		snd_assert(((u32*)(dsp->data))[0]==0xFFFFFFFF, return -EINVAL);
+		snd_assert(dsp->size % 4 == 0, return -EINVAL);
 
 		/* set xilinx status to copying */
 		writel_be( 1, MIXART_MEM( mgr, MIXART_PSEUDOREG_MXLX_STATUS_OFFSET ));
@@ -388,11 +358,10 @@
 		/* setup xilinx base address */
 		writel_be( MIXART_MOTHERBOARD_XLX_BASE_ADDRESS, MIXART_MEM( mgr,MIXART_PSEUDOREG_MXLX_BASE_ADDR_OFFSET ));
 		/* setup code size for xilinx file */
-		writel_be( dsp->length, MIXART_MEM( mgr, MIXART_PSEUDOREG_MXLX_SIZE_OFFSET ));
+		writel_be( dsp->size, MIXART_MEM( mgr, MIXART_PSEUDOREG_MXLX_SIZE_OFFSET ));
 
 		/* copy xilinx code */
-		if (copy_from_user_toio(  MIXART_MEM( mgr, MIXART_MOTHERBOARD_XLX_BASE_ADDRESS),  dsp->image,  dsp->length))
-			return -EFAULT;
+		memcpy_toio(  MIXART_MEM( mgr, MIXART_MOTHERBOARD_XLX_BASE_ADDRESS),  dsp->data,  dsp->size);
     
 		/* set xilinx status to copy finished */
 		writel_be( 2, MIXART_MEM( mgr, MIXART_PSEUDOREG_MXLX_STATUS_OFFSET ));
@@ -428,7 +397,7 @@
 		writel_be( 1, MIXART_MEM( mgr, MIXART_PSEUDOREG_ELF_STATUS_OFFSET ));
 
 		/* process the copying of the elf packets */
-		err = mixart_load_elf( mgr, dsp);
+		err = mixart_load_elf( mgr, dsp );
 		if (err < 0) return err;
 
 		/* set elf status to copy finished */
@@ -479,11 +448,11 @@
 		}
  
 		/* check daughterboard xilinx validity */
-		snd_assert(((u32*)(dsp->image))[0]==0xFFFFFFFF, return -EINVAL);
-		snd_assert(dsp->length % 4 == 0, return -EINVAL);
+		snd_assert(((u32*)(dsp->data))[0]==0xFFFFFFFF, return -EINVAL);
+		snd_assert(dsp->size % 4 == 0, return -EINVAL);
 
 		/* inform mixart about the size of the file */
-		writel_be( dsp->length, MIXART_MEM( mgr, MIXART_PSEUDOREG_DXLX_SIZE_OFFSET ));
+		writel_be( dsp->size, MIXART_MEM( mgr, MIXART_PSEUDOREG_DXLX_SIZE_OFFSET ));
 
 		/* set daughterboard status to 1 */
 		writel_be( 1, MIXART_MEM( mgr, MIXART_PSEUDOREG_DXLX_STATUS_OFFSET ));
@@ -500,8 +469,7 @@
 		snd_assert(val != 0, return -EINVAL);
 
 		/* copy daughterboard xilinx code */
-		if (copy_from_user_toio(  MIXART_MEM( mgr, val),  dsp->image,  dsp->length))
-			return -EFAULT;
+		memcpy_toio(  MIXART_MEM( mgr, val),  dsp->data,  dsp->size);
 
 		/* set daughterboard status to 4 */
 		writel_be( 4, MIXART_MEM( mgr, MIXART_PSEUDOREG_DXLX_STATUS_OFFSET ));
@@ -549,7 +517,92 @@
 }
 
 
-int snd_mixart_hwdep_new(mixart_mgr_t *mgr)
+#if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE)
+#if !defined(CONFIG_USE_MIXARTLOADER) && !defined(CONFIG_SND_MIXART) /* built-in kernel */
+#define SND_MIXART_FW_LOADER	/* use the standard firmware loader */
+#endif
+#endif
+
+#ifdef SND_MIXART_FW_LOADER
+
+int snd_mixart_setup_firmware(mixart_mgr_t *mgr)
+{
+	static char *fw_files[3] = {
+		"miXart8.xlx", "miXart8.elf", "miXart8AES.xlx"
+	};
+	char path[32];
+
+	const struct firmware *fw_entry;
+	int i, err;
+
+	for (i = 0; i < 3; i++) {
+		sprintf(path, "mixart/%s", fw_files[i]);
+		if (request_firmware(&fw_entry, path, &mgr->pci->dev)) {
+			snd_printk(KERN_ERR "miXart: can't load firmware %s\n", path);
+			return -ENOENT;
+		}
+		/* fake hwdep dsp record */
+		err = mixart_dsp_load(mgr, i, fw_entry);
+		release_firmware(fw_entry);
+		if (err < 0)
+			return err;
+	}
+	return 0;
+}
+
+
+#else /* old style firmware loading */
+
+/* miXart hwdep interface id string */
+#define SND_MIXART_HWDEP_ID       "miXart Loader"
+
+static int mixart_hwdep_open(snd_hwdep_t *hw, struct file *file)
+{
+	return 0;
+}
+
+static int mixart_hwdep_release(snd_hwdep_t *hw, struct file *file)
+{
+	return 0;
+}
+
+static int mixart_hwdep_dsp_status(snd_hwdep_t *hw, snd_hwdep_dsp_status_t *info)
+{
+	mixart_mgr_t *mgr = hw->private_data;
+
+	strcpy(info->id, "miXart");
+        info->num_dsps = MIXART_HARDW_FILES_MAX_INDEX;
+
+	if (mgr->hwdep->dsp_loaded & (1 <<  MIXART_MOTHERBOARD_ELF_INDEX))
+		info->chip_ready = 1;
+
+	info->version = MIXART_DRIVER_VERSION;
+	return 0;
+}
+
+static int mixart_hwdep_dsp_load(snd_hwdep_t *hw, snd_hwdep_dsp_image_t *dsp)
+{
+	mixart_mgr_t* mgr = hw->private_data;
+	struct firmware fw;
+	int err;
+
+	fw.size = dsp->length;
+	fw.data = vmalloc(dsp->length);
+	if (! fw.data) {
+		snd_printk(KERN_ERR "miXart: cannot allocate image size %d\n",
+			   (int)dsp->length);
+		return -ENOMEM;
+	}
+	if (copy_from_user(fw.data, dsp->image, dsp->length)) {
+		vfree(fw.data);
+		return -EFAULT;
+	}
+	err = mixart_dsp_load(mgr, dsp->index, &fw);
+	vfree(fw.data);
+	return err;
+}
+
+int snd_mixart_setup_firmware(mixart_mgr_t *mgr)
 {
 	int err;
 	snd_hwdep_t *hw;
@@ -568,5 +621,8 @@
 	sprintf(hw->name,  SND_MIXART_HWDEP_ID);
 	mgr->hwdep = hw;
 	mgr->hwdep->dsp_loaded = 0;
-	return 0;
+
+	return snd_card_register(mgr->chip[0]->card);
 }
+
+#endif /* SND_MIXART_FW_LOADER */
diff -Nru a/sound/pci/mixart/mixart_hwdep.h b/sound/pci/mixart/mixart_hwdep.h
--- a/sound/pci/mixart/mixart_hwdep.h	2005-03-01 23:39:16 -08:00
+++ b/sound/pci/mixart/mixart_hwdep.h	2005-03-01 23:39:16 -08:00
@@ -140,7 +140,6 @@
 #define MIXART_OIDI                             0x008   /* 0000 0000 1000 */
 
 
-/* exported */
-int snd_mixart_hwdep_new(mixart_mgr_t *mgr);
+int snd_mixart_setup_firmware(mixart_mgr_t *mgr);
 
 #endif /* __SOUND_MIXART_HWDEP_H */
diff -Nru a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c
--- a/sound/pci/nm256/nm256.c	2005-03-01 23:39:09 -08:00
+++ b/sound/pci/nm256/nm256.c	2005-03-01 23:39:09 -08:00
@@ -1130,7 +1130,7 @@
 		return 0;
 	res = snd_nm256_readw(chip, chip->mixer_base + reg);
 	/* Magic delay.  Bleah yucky.  */
-	udelay(1000);
+	msleep(1);
 	return res;
 }
 
@@ -1151,7 +1151,7 @@
 	/* Wait for the write to take, too. */
 	while (tries-- > 0) {
 		snd_nm256_writew(chip, base + reg, val);
-		udelay(1000);  /* a little delay here seems better.. */
+		msleep(1);  /* a little delay here seems better.. */
 		if (snd_nm256_ac97_ready(chip))
 			return;
 	}
@@ -1275,7 +1275,6 @@
 	snd_ac97_suspend(chip->ac97);
 	chip->coeffs_current = 0;
 	pci_disable_device(chip->pci);
-	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
 	return 0;
 }
 
@@ -1290,7 +1289,6 @@
 	/* restore ac97 */
 	snd_ac97_resume(chip->ac97);
 
-	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
 	return 0;
 }
 #endif /* CONFIG_PM */
@@ -1488,12 +1486,6 @@
 
 	snd_nm256_init_chip(chip);
 
-	if ((err = snd_nm256_pcm(chip, 0)) < 0)
-		goto __error;
-	
-	if ((err = snd_nm256_mixer(chip)) < 0)
-		goto __error;
-
 	// pci_set_master(pci); /* needed? */
 	
 	snd_card_set_pm_callback(card, nm256_suspend, nm256_resume, chip);
@@ -1612,6 +1604,12 @@
 	if (reset_workaround[dev]) {
 		snd_printdd(KERN_INFO "nm256: reset_workaround activated\n");
 		chip->reset_workaround = 1;
+	}
+
+	if ((err = snd_nm256_pcm(chip, 0)) < 0 ||
+	    (err = snd_nm256_mixer(chip)) < 0) {
+		snd_card_free(card);
+		return err;
 	}
 
 	sprintf(card->shortname, "NeoMagic %s", card->driver);
diff -Nru a/sound/pci/rme32.c b/sound/pci/rme32.c
--- a/sound/pci/rme32.c	2005-03-01 23:39:17 -08:00
+++ b/sound/pci/rme32.c	2005-03-01 23:39:17 -08:00
@@ -1916,21 +1916,21 @@
 		.private_value = IEC958_AES0_PROFESSIONAL | IEC958_AES0_PRO_EMPHASIS
 	},
 	{
-		.iface = SNDRV_CTL_ELEM_IFACE_PCM,
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name =	"Input Connector",
 		.info =	snd_rme32_info_inputtype_control,
 		.get =	snd_rme32_get_inputtype_control,
 		.put =	snd_rme32_put_inputtype_control
 	},
 	{
-		.iface = SNDRV_CTL_ELEM_IFACE_PCM,
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name =	"Loopback Input",
 		.info =	snd_rme32_info_loopback_control,
 		.get =	snd_rme32_get_loopback_control,
 		.put =	snd_rme32_put_loopback_control
 	},
 	{
-		.iface = SNDRV_CTL_ELEM_IFACE_PCM,
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name =	"Sample Clock Source",
 		.info =	snd_rme32_info_clockmode_control,
 		.get =	snd_rme32_get_clockmode_control,
diff -Nru a/sound/pci/rme96.c b/sound/pci/rme96.c
--- a/sound/pci/rme96.c	2005-03-01 23:38:55 -08:00
+++ b/sound/pci/rme96.c	2005-03-01 23:38:55 -08:00
@@ -2285,35 +2285,35 @@
 			IEC958_AES0_PRO_EMPHASIS
 },
 {
-        .iface =        SNDRV_CTL_ELEM_IFACE_PCM,
+        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name =         "Input Connector",
 	.info =         snd_rme96_info_inputtype_control, 
 	.get =          snd_rme96_get_inputtype_control,
 	.put =          snd_rme96_put_inputtype_control 
 },
 {
-        .iface =        SNDRV_CTL_ELEM_IFACE_PCM,
+        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name =         "Loopback Input",
 	.info =         snd_rme96_info_loopback_control,
 	.get =          snd_rme96_get_loopback_control,
 	.put =          snd_rme96_put_loopback_control
 },
 {
-        .iface =        SNDRV_CTL_ELEM_IFACE_PCM,
+        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name =         "Sample Clock Source",
 	.info =         snd_rme96_info_clockmode_control, 
 	.get =          snd_rme96_get_clockmode_control,
 	.put =          snd_rme96_put_clockmode_control
 },
 {
-        .iface =        SNDRV_CTL_ELEM_IFACE_PCM,
+        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name =         "Monitor Tracks",
 	.info =         snd_rme96_info_montracks_control, 
 	.get =          snd_rme96_get_montracks_control,
 	.put =          snd_rme96_put_montracks_control
 },
 {
-        .iface =        SNDRV_CTL_ELEM_IFACE_PCM,
+        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name =         "Attenuation",
 	.info =         snd_rme96_info_attenuation_control, 
 	.get =          snd_rme96_get_attenuation_control,
diff -Nru a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
--- a/sound/pci/rme9652/hdsp.c	2005-03-01 23:38:55 -08:00
+++ b/sound/pci/rme9652/hdsp.c	2005-03-01 23:38:55 -08:00
@@ -27,6 +27,7 @@
 #include <linux/interrupt.h>
 #include <linux/slab.h>
 #include <linux/pci.h>
+#include <linux/firmware.h>
 #include <linux/moduleparam.h>
 
 #include <sound/core.h>
@@ -399,6 +400,13 @@
 #define HDSP_DMA_AREA_BYTES ((HDSP_MAX_CHANNELS+1) * HDSP_CHANNEL_BUFFER_BYTES)
 #define HDSP_DMA_AREA_KILOBYTES (HDSP_DMA_AREA_BYTES/1024)
 
+/* use hotplug firmeare loader? */
+#if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE)
+#ifndef HDSP_USE_HWDEP_LOADER
+#define HDSP_FW_LOADER
+#endif
+#endif
+
 typedef struct _hdsp             hdsp_t;
 typedef struct _hdsp_midi        hdsp_midi_t;
 typedef struct _hdsp_9632_meters hdsp_9632_meters_t;
@@ -585,8 +593,8 @@
 MODULE_DEVICE_TABLE(pci, snd_hdsp_ids);
 
 /* prototypes */
-static int __devinit snd_hdsp_create_alsa_devices(snd_card_t *card, hdsp_t *hdsp);
-static int __devinit snd_hdsp_create_pcm(snd_card_t *card, hdsp_t *hdsp);
+static int snd_hdsp_create_alsa_devices(snd_card_t *card, hdsp_t *hdsp);
+static int snd_hdsp_create_pcm(snd_card_t *card, hdsp_t *hdsp);
 static int snd_hdsp_enable_io (hdsp_t *hdsp);
 static void snd_hdsp_initialize_midi_flush (hdsp_t *hdsp);
 static void snd_hdsp_initialize_channels (hdsp_t *hdsp);
@@ -934,6 +942,7 @@
 	}
 
 	position &= HDSP_BufferPositionMask;
+	position /= 4;
 	position &= (hdsp->period_bytes/2) - 1;
 	return position;
 }
@@ -1443,14 +1452,14 @@
 	return 0;
 }
 
-snd_rawmidi_ops_t snd_hdsp_midi_output =
+static snd_rawmidi_ops_t snd_hdsp_midi_output =
 {
 	.open =		snd_hdsp_midi_output_open,
 	.close =	snd_hdsp_midi_output_close,
 	.trigger =	snd_hdsp_midi_output_trigger,
 };
 
-snd_rawmidi_ops_t snd_hdsp_midi_input =
+static snd_rawmidi_ops_t snd_hdsp_midi_input =
 {
 	.open =		snd_hdsp_midi_input_open,
 	.close =	snd_hdsp_midi_input_close,
@@ -2728,7 +2737,7 @@
 {
 	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
 	
-	ucontrol->value.enumerated.item[0] = hdsp_pref_sync_ref(hdsp);
+	ucontrol->value.enumerated.item[0] = hdsp_autosync_ref(hdsp);
 	return 0;
 }
 
@@ -3137,7 +3146,7 @@
 static snd_kcontrol_new_t snd_hdsp_96xx_aeb = HDSP_AEB("Analog Extension Board", 0);
 static snd_kcontrol_new_t snd_hdsp_adat_sync_check = HDSP_ADAT_SYNC_CHECK;
 
-int snd_hdsp_create_controls(snd_card_t *card, hdsp_t *hdsp)
+static int snd_hdsp_create_controls(snd_card_t *card, hdsp_t *hdsp)
 {
 	unsigned int idx;
 	int err;
@@ -3651,7 +3660,7 @@
 	return 0;
 }
 
-void hdsp_midi_tasklet(unsigned long arg)
+static void hdsp_midi_tasklet(unsigned long arg)
 {
 	hdsp_t *hdsp = (hdsp_t *)arg;
 	
@@ -4652,6 +4661,7 @@
 		}
 		break;
 	}
+#ifndef HDSP_FW_LOADER
 	case SNDRV_HDSP_IOCTL_UPLOAD_FIRMWARE: {
 		hdsp_firmware_t __user *firmware;
 		u32 __user *firmware_data;
@@ -4661,6 +4671,9 @@
 		/* SNDRV_HDSP_IOCTL_GET_VERSION must have been called */
 		if (hdsp->io_type == Undefined) return -EINVAL;
 
+		if (hdsp->state & (HDSP_FirmwareCached | HDSP_FirmwareLoaded))
+			return -EBUSY;
+
 		snd_printk("initializing firmware upload\n");
 		firmware = (hdsp_firmware_t __user *)argp;
 
@@ -4694,6 +4707,7 @@
 		}
 		break;
 	}
+#endif
 	case SNDRV_HDSP_IOCTL_GET_MIXER: {
 		hdsp_mixer_t __user *mixer = (hdsp_mixer_t __user *)argp;
 		if (copy_to_user(mixer->matrix, hdsp->mixer_matrix, sizeof(unsigned short)*HDSP_MATRIX_MIXER_SIZE))
@@ -4749,8 +4763,7 @@
 	return 0;
 }
 
-static int __devinit snd_hdsp_create_pcm(snd_card_t *card,
-					 hdsp_t *hdsp)
+static int snd_hdsp_create_pcm(snd_card_t *card, hdsp_t *hdsp)
 {
 	snd_pcm_t *pcm;
 	int err;
@@ -4841,7 +4854,7 @@
 	snd_hdsp_flush_midi_input (hdsp, 1);
 }
 
-static int __devinit snd_hdsp_create_alsa_devices(snd_card_t *card, hdsp_t *hdsp)
+static int snd_hdsp_create_alsa_devices(snd_card_t *card, hdsp_t *hdsp)
 {
 	int err;
 	
@@ -4894,6 +4907,86 @@
 	return 0;
 }
 
+#ifdef HDSP_FW_LOADER
+/* load firmware via hotplug fw loader */
+static int __devinit hdsp_request_fw_loader(hdsp_t *hdsp)
+{
+	const char *fwfile;
+	const struct firmware *fw;
+	int err;
+		
+	if (hdsp->io_type == H9652 || hdsp->io_type == H9632)
+		return 0;
+	if (hdsp->io_type == Undefined) {
+		if ((err = hdsp_get_iobox_version(hdsp)) < 0)
+			return err;
+		if (hdsp->io_type == H9652 || hdsp->io_type == H9632)
+			return 0;
+	}
+	if (hdsp_check_for_iobox (hdsp))
+		return -EIO;
+
+	/* caution: max length of firmware filename is 30! */
+	switch (hdsp->io_type) {
+	case Multiface:
+		if (hdsp->firmware_rev == 0xa)
+			fwfile = "multiface_firmware.bin";
+		else
+			fwfile = "multiface_firmware_rev11.bin";
+		break;
+	case Digiface:
+		if (hdsp->firmware_rev == 0xa)
+			fwfile = "digiface_firmware.bin";
+		else
+			fwfile = "digiface_firmware_rev11.bin";
+		break;
+	default:
+		snd_printk(KERN_ERR "hdsp: invalid io_type %d\n", hdsp->io_type);
+		return -EINVAL;
+	}
+
+	if (request_firmware(&fw, fwfile, &hdsp->pci->dev)) {
+		snd_printk(KERN_ERR "hdsp: cannot load firmware %s\n", fwfile);
+		return -ENOENT;
+	}
+	if (fw->size < sizeof(hdsp->firmware_cache)) {
+		snd_printk(KERN_ERR "hdsp: too short firmware size %d (expected %d)\n",
+			   (int)fw->size, (int)sizeof(hdsp->firmware_cache));
+		release_firmware(fw);
+		return -EINVAL;
+	}
+#ifdef SNDRV_BIG_ENDIAN
+	{
+		int i;
+		u32 *src = (void *)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;
+
+	if ((err = snd_hdsp_load_firmware_from_cache(hdsp)) < 0)
+		return err;
+		
+	if (!(hdsp->state & HDSP_InitializationComplete)) {
+		snd_hdsp_initialize_channels(hdsp);
+		snd_hdsp_initialize_midi_flush(hdsp);
+		if ((err = snd_hdsp_create_alsa_devices(hdsp->card, hdsp)) < 0) {
+			snd_printk("error creating alsa devices\n");
+			return err;
+		}
+	}
+	return 0;
+}
+#endif
+
 static int __devinit snd_hdsp_create(snd_card_t *card,
 				     hdsp_t *hdsp,
 				     int precise_ptr)
@@ -5002,11 +5095,16 @@
 	}
 	
 	if ((hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DllError) != 0) {
+#ifdef HDSP_FW_LOADER
+		if ((err = hdsp_request_fw_loader(hdsp)) < 0)
+			return err;
+#else
 		snd_printk("card initialization pending : waiting for firmware\n");
 		if ((err = snd_hdsp_create_hwdep(card, hdsp)) < 0) {
 			return err;
 		}
 		return 0;
+#endif
 	} 
 	
 	snd_printk("Firmware already loaded, initializing card.\n");
diff -Nru a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c
--- a/sound/pci/rme9652/rme9652.c	2005-03-01 23:38:56 -08:00
+++ b/sound/pci/rme9652/rme9652.c	2005-03-01 23:38:56 -08:00
@@ -1584,7 +1584,7 @@
 static snd_kcontrol_new_t snd_rme9652_adat1_input =
 RME9652_ADAT1_IN("ADAT1 Input Source", 0);
 
-int snd_rme9652_create_controls(snd_card_t *card, rme9652_t *rme9652)
+static int snd_rme9652_create_controls(snd_card_t *card, rme9652_t *rme9652)
 {
 	unsigned int idx;
 	int err;
diff -Nru a/sound/pci/sonicvibes.c b/sound/pci/sonicvibes.c
--- a/sound/pci/sonicvibes.c	2005-03-01 23:39:08 -08:00
+++ b/sound/pci/sonicvibes.c	2005-03-01 23:39:08 -08:00
@@ -357,8 +357,8 @@
 	return value;
 }
 
-#ifdef CONFIG_SND_DEBUG
-void snd_sonicvibes_debug(sonicvibes_t * sonic)
+#if 0
+static void snd_sonicvibes_debug(sonicvibes_t * sonic)
 {
 	printk("SV REGS:          INDEX = 0x%02x  ", inb(SV_REG(sonic, INDEX)));
 	printk("                 STATUS = 0x%02x\n", inb(SV_REG(sonic, STATUS)));
@@ -1333,12 +1333,13 @@
 #endif
 	sonic->revision = snd_sonicvibes_in(sonic, SV_IREG_REVISION);
 	snd_ctl_add(card, snd_ctl_new1(&snd_sonicvibes_game_control, sonic));
-	snd_sonicvibes_proc_init(sonic);
 
 	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, sonic, &ops)) < 0) {
 		snd_sonicvibes_free(sonic);
 		return err;
 	}
+
+	snd_sonicvibes_proc_init(sonic);
 
 	snd_card_set_dev(card, &pci->dev);
 
diff -Nru a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c
--- a/sound/pci/trident/trident_main.c	2005-03-01 23:39:07 -08:00
+++ b/sound/pci/trident/trident_main.c	2005-03-01 23:39:07 -08:00
@@ -53,6 +53,9 @@
 #endif
 static int snd_trident_sis_reset(trident_t *trident);
 
+static void snd_trident_clear_voices(trident_t * trident, unsigned short v_min, unsigned short v_max);
+static int snd_trident_free(trident_t *trident);
+
 /*
  *  common I/O routines
  */
@@ -632,7 +635,7 @@
    Returns:     Delta value.
   
   ---------------------------------------------------------------------------*/
-unsigned int snd_trident_convert_rate(unsigned int rate)
+static unsigned int snd_trident_convert_rate(unsigned int rate)
 {
 	unsigned int delta;
 
@@ -692,7 +695,7 @@
    Returns:     Delta value.
   
   ---------------------------------------------------------------------------*/
-unsigned int snd_trident_spurious_threshold(unsigned int rate, unsigned int period_size)
+static unsigned int snd_trident_spurious_threshold(unsigned int rate, unsigned int period_size)
 {
 	unsigned int res = (rate * period_size) / 48000;
 	if (res < 64)
@@ -713,7 +716,7 @@
    Returns:     Control value.
   
   ---------------------------------------------------------------------------*/
-unsigned int snd_trident_control_mode(snd_pcm_substream_t *substream)
+static unsigned int snd_trident_control_mode(snd_pcm_substream_t *substream)
 {
 	unsigned int CTRL;
 	snd_pcm_runtime_t *runtime = substream->runtime;
@@ -770,8 +773,8 @@
   
   ---------------------------------------------------------------------------*/
 
-int snd_trident_allocate_pcm_mem(snd_pcm_substream_t * substream,
-				 snd_pcm_hw_params_t * hw_params)
+static int snd_trident_allocate_pcm_mem(snd_pcm_substream_t * substream,
+					snd_pcm_hw_params_t * hw_params)
 {
 	trident_t *trident = snd_pcm_substream_chip(substream);
 	snd_pcm_runtime_t *runtime = substream->runtime;
@@ -804,8 +807,8 @@
   
   ---------------------------------------------------------------------------*/
 
-int snd_trident_allocate_evoice(snd_pcm_substream_t * substream,
-				snd_pcm_hw_params_t * hw_params)
+static int snd_trident_allocate_evoice(snd_pcm_substream_t * substream,
+				       snd_pcm_hw_params_t * hw_params)
 {
 	trident_t *trident = snd_pcm_substream_chip(substream);
 	snd_pcm_runtime_t *runtime = substream->runtime;
@@ -3611,10 +3614,13 @@
 		return err;
 	}
 
-	if ((err = snd_trident_mixer(trident, pcm_spdif_device)) < 0) {
+	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, trident, &ops)) < 0) {
 		snd_trident_free(trident);
 		return err;
 	}
+
+	if ((err = snd_trident_mixer(trident, pcm_spdif_device)) < 0)
+		return err;
 	
 	/* initialise synth voices */
 	for (i = 0; i < 64; i++) {
@@ -3635,12 +3641,7 @@
 
 	
 	snd_card_set_pm_callback(card, snd_trident_suspend, snd_trident_resume, trident);
-
 	snd_trident_proc_init(trident);
-	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, trident, &ops)) < 0) {
-		snd_trident_free(trident);
-		return err;
-	}
 	snd_card_set_dev(card, &pci->dev);
 	*rtrident = trident;
 	return 0;
@@ -3650,7 +3651,7 @@
    snd_trident_free
   
    Description: This routine will free the device specific class for
-            q    the 4DWave card. 
+                the 4DWave card. 
                 
    Paramters:   trident  - device specific private data for 4DWave card
 
@@ -3658,7 +3659,7 @@
   
   ---------------------------------------------------------------------------*/
 
-int snd_trident_free(trident_t *trident)
+static int snd_trident_free(trident_t *trident)
 {
 #if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
 	if (trident->gameport) {
@@ -3679,8 +3680,7 @@
 			snd_util_memhdr_free(trident->tlb.memhdr);
 		if (trident->tlb.silent_page.area)
 			snd_dma_free_pages(&trident->tlb.silent_page);
-		if (trident->tlb.shadow_entries)
-			vfree(trident->tlb.shadow_entries);
+		vfree(trident->tlb.shadow_entries);
 		snd_dma_free_pages(&trident->tlb.buffer);
 	}
 	if (trident->irq >= 0)
@@ -3807,9 +3807,9 @@
 }
 
 /*---------------------------------------------------------------------------
-   snd_trident_attach_synthesizer, snd_trident_detach_synthesizer
+   snd_trident_attach_synthesizer
   
-   Description: Attach/detach synthesizer hooks
+   Description: Attach synthesizer hooks
                 
    Paramters:   trident  - device specific private data for 4DWave card
 
@@ -3828,17 +3828,6 @@
 	return 0;
 }
 
-int snd_trident_detach_synthesizer(trident_t *trident)
-{
-#if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE))
-	if (trident->seq_dev) {
-		snd_device_free(trident->card, trident->seq_dev);
-		trident->seq_dev = NULL;
-	}
-#endif
-	return 0;
-}
-
 snd_trident_voice_t *snd_trident_alloc_voice(trident_t * trident, int type, int client, int port)
 {
 	snd_trident_voice_t *pvoice;
@@ -3911,7 +3900,7 @@
 		private_free(voice);
 }
 
-void snd_trident_clear_voices(trident_t * trident, unsigned short v_min, unsigned short v_max)
+static void snd_trident_clear_voices(trident_t * trident, unsigned short v_min, unsigned short v_max)
 {
 	unsigned int i, val, mask[2] = { 0, 0 };
 
@@ -3955,7 +3944,6 @@
 		break;
 	}
 	pci_disable_device(trident->pci);
-	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
 	return 0;
 }
 
@@ -3990,7 +3978,6 @@
 
 	snd_trident_enable_eso(trident);
 
-	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
 	trident->in_suspend = 0;
 	return 0;
 }
@@ -4001,9 +3988,7 @@
 EXPORT_SYMBOL(snd_trident_start_voice);
 EXPORT_SYMBOL(snd_trident_stop_voice);
 EXPORT_SYMBOL(snd_trident_write_voice_regs);
-EXPORT_SYMBOL(snd_trident_clear_voices);
 /* trident_memory.c symbols */
 EXPORT_SYMBOL(snd_trident_synth_alloc);
 EXPORT_SYMBOL(snd_trident_synth_free);
-EXPORT_SYMBOL(snd_trident_synth_bzero);
 EXPORT_SYMBOL(snd_trident_synth_copy_from_user);
diff -Nru a/sound/pci/trident/trident_memory.c b/sound/pci/trident/trident_memory.c
--- a/sound/pci/trident/trident_memory.c	2005-03-01 23:39:07 -08:00
+++ b/sound/pci/trident/trident_memory.c	2005-03-01 23:39:07 -08:00
@@ -450,29 +450,6 @@
 }
 
 /*
- * bzero(blk + offset, size)
- */
-int snd_trident_synth_bzero(trident_t *trident, snd_util_memblk_t *blk, int offset, int size)
-{
-	int page, nextofs, end_offset, temp, temp1;
-
-	offset += blk->offset;
-	end_offset = offset + size;
-	page = get_aligned_page(offset) + 1;
-	do {
-		nextofs = aligned_page_offset(page);
-		temp = nextofs - offset;
-		temp1 = end_offset - offset;
-		if (temp1 < temp)
-			temp = temp1;
-		memset(offset_ptr(trident, offset), 0, temp);
-		offset = nextofs;
-		page++;
-	} while (offset < end_offset);
-	return 0;
-}
-
-/*
  * copy_from_user(blk + offset, data, size)
  */
 int snd_trident_synth_copy_from_user(trident_t *trident, snd_util_memblk_t *blk, int offset, const char __user *data, int size)
diff -Nru a/sound/pci/trident/trident_synth.c b/sound/pci/trident/trident_synth.c
--- a/sound/pci/trident/trident_synth.c	2005-03-01 23:38:56 -08:00
+++ b/sound/pci/trident/trident_synth.c	2005-03-01 23:38:56 -08:00
@@ -618,7 +618,7 @@
 	instr = snd_seq_instr_find(trident->synth.ilist, &v->instr, 0, 1);
 	if (instr != NULL) {
 		if (instr->ops) {
-			if (instr->ops->instr_type == snd_seq_simple_id)
+			if (!strcmp(instr->ops->instr_type, SNDRV_SEQ_INSTR_ID_SIMPLE))
 				snd_trident_simple_init(v);
 		}
 		snd_seq_instr_free_use(trident->synth.ilist, instr);
@@ -811,7 +811,7 @@
 	snd_seq_instr_list_free_cond(p->trident->synth.ilist, &ifree, client, 0);
 }
 
-int snd_trident_synth_event_input(snd_seq_event_t * ev, int direct, void *private_data, int atomic, int hop)
+static int snd_trident_synth_event_input(snd_seq_event_t * ev, int direct, void *private_data, int atomic, int hop)
 {
 	snd_trident_port_t *p = (snd_trident_port_t *) private_data;
 
diff -Nru a/sound/pci/via82xx.c b/sound/pci/via82xx.c
--- a/sound/pci/via82xx.c	2005-03-01 23:39:09 -08:00
+++ b/sound/pci/via82xx.c	2005-03-01 23:39:09 -08:00
@@ -81,7 +81,7 @@
 static int joystick[SNDRV_CARDS];
 #endif
 static int ac97_clock[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 48000};
-static int ac97_quirk[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = AC97_TUNE_DEFAULT};
+static char *ac97_quirk[SNDRV_CARDS];
 static int dxs_support[SNDRV_CARDS];
 
 module_param_array(index, int, NULL, 0444);
@@ -98,7 +98,7 @@
 #endif
 module_param_array(ac97_clock, int, NULL, 0444);
 MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (default 48000Hz).");
-module_param_array(ac97_quirk, int, NULL, 0444);
+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)");
@@ -332,6 +332,7 @@
 	struct snd_via_sg_table *idx_table;
 	/* for recovery from the unexpected pointer */
 	unsigned int lastpos;
+	unsigned int fragsize;
 	unsigned int bufsize;
 	unsigned int bufsize2;
 };
@@ -390,7 +391,6 @@
 	unsigned int ac97_secondary;	/* secondary AC'97 codec is present */
 
 	spinlock_t reg_lock;
-	spinlock_t ac97_lock;
 	snd_info_entry_t *proc_entry;
 
 #ifdef SUPPORT_JOYSTICK
@@ -478,6 +478,7 @@
 	dev->tbl_entries = idx;
 	dev->bufsize = periods * fragsize;
 	dev->bufsize2 = dev->bufsize / 2;
+	dev->fragsize = fragsize;
 	return 0;
 }
 
@@ -562,10 +563,8 @@
 	xval <<= VIA_REG_AC97_CODEC_ID_SHIFT;
 	xval |= reg << VIA_REG_AC97_CMD_SHIFT;
 	xval |= val << VIA_REG_AC97_DATA_SHIFT;
-	spin_lock(&chip->ac97_lock);
 	snd_via82xx_codec_xwrite(chip, xval);
 	snd_via82xx_codec_ready(chip, ac97->num);
-	spin_unlock(&chip->ac97_lock);
 }
 
 static unsigned short snd_via82xx_codec_read(ac97_t *ac97, unsigned short reg)
@@ -578,10 +577,8 @@
 	xval |= ac97->num ? VIA_REG_AC97_SECONDARY_VALID : VIA_REG_AC97_PRIMARY_VALID;
 	xval |= VIA_REG_AC97_READ;
 	xval |= (reg & 0x7f) << VIA_REG_AC97_CMD_SHIFT;
-	spin_lock(&chip->ac97_lock);
       	while (1) {
       		if (again++ > 3) {
-		        spin_unlock(&chip->ac97_lock);
 			snd_printk(KERN_ERR "codec_read: codec %i is not valid [0x%x]\n", ac97->num, snd_via82xx_codec_xread(chip));
 		      	return 0xffff;
 		}
@@ -593,7 +590,6 @@
 			break;
 		}
 	}
-	spin_unlock(&chip->ac97_lock);
 	return val & 0xffff;
 }
 
@@ -706,29 +702,34 @@
 
 static inline unsigned int calc_linear_pos(viadev_t *viadev, unsigned int idx, unsigned int count)
 {
-	unsigned int size, res;
+	unsigned int size, base, res;
 
 	size = viadev->idx_table[idx].size;
-	res = viadev->idx_table[idx].offset + size - count;
+	base = viadev->idx_table[idx].offset;
+	res = base + size - count;
 
 	/* check the validity of the calculated position */
 	if (size < count) {
 		snd_printd(KERN_ERR "invalid via82xx_cur_ptr (size = %d, count = %d)\n", (int)size, (int)count);
 		res = viadev->lastpos;
-	} else if (check_invalid_pos(viadev, res)) {
+	} else {
+		if (! count) {
+			/* Some mobos report count = 0 on the DMA boundary,
+			 * i.e. count = size indeed.
+			 * Let's check whether this step is above the expected size.
+			 */
+			int delta = res - viadev->lastpos;
+			if (delta < 0)
+				delta += viadev->bufsize;
+			if ((unsigned int)delta > viadev->fragsize)
+				res = base;
+		}
+		if (check_invalid_pos(viadev, res)) {
 #ifdef POINTER_DEBUG
-		printk("fail: idx = %i/%i, lastpos = 0x%x, bufsize2 = 0x%x, offsize = 0x%x, size = 0x%x, count = 0x%x\n", idx, viadev->tbl_entries, viadev->lastpos, viadev->bufsize2, viadev->idx_table[idx].offset, viadev->idx_table[idx].size, count);
+			printk(KERN_DEBUG "fail: idx = %i/%i, lastpos = 0x%x, bufsize2 = 0x%x, offsize = 0x%x, size = 0x%x, count = 0x%x\n", idx, viadev->tbl_entries, viadev->lastpos, viadev->bufsize2, viadev->idx_table[idx].offset, viadev->idx_table[idx].size, count);
 #endif
-		if (count && size < count) {
-			snd_printd(KERN_ERR "invalid via82xx_cur_ptr, using last valid pointer\n");
-			res = viadev->lastpos;
-		} else {
-			if (! count)
-				/* bogus count 0 on the DMA boundary? */
-				res = viadev->idx_table[idx].offset;
-			else
-				/* count register returns full size when end of buffer is reached */
-				res = viadev->idx_table[idx].offset + size;
+			/* count register returns full size when end of buffer is reached */
+			res = base + size;
 			if (check_invalid_pos(viadev, res)) {
 				snd_printd(KERN_ERR "invalid via82xx_cur_ptr (2), using last valid pointer\n");
 				res = viadev->lastpos;
@@ -778,12 +779,20 @@
 	via82xx_t *chip = snd_pcm_substream_chip(substream);
 	viadev_t *viadev = (viadev_t *)substream->runtime->private_data;
 	unsigned int idx, count, res;
+	int timeout = 5000;
 	
 	snd_assert(viadev->tbl_entries, return 0);
 	if (!(inb(VIADEV_REG(viadev, OFFSET_STATUS)) & VIA_REG_STAT_ACTIVE))
 		return 0;
 	spin_lock(&chip->reg_lock);
-	count = inl(VIADEV_REG(viadev, OFFSET_CURR_COUNT));
+	do {
+		count = inl(VIADEV_REG(viadev, OFFSET_CURR_COUNT));
+		/* some mobos read 0 count */
+		if ((count & 0xffffff) || ! viadev->running)
+			break;
+	} while (--timeout);
+	if (! timeout)
+		snd_printd(KERN_ERR "zero position is read\n");
 	idx = count >> 24;
 	if (idx >= viadev->tbl_entries) {
 #ifdef POINTER_DEBUG
@@ -1593,7 +1602,7 @@
 	{ } /* terminator */
 };
 
-static int __devinit snd_via82xx_mixer_new(via82xx_t *chip, int ac97_quirk)
+static int __devinit snd_via82xx_mixer_new(via82xx_t *chip, const char *quirk_override)
 {
 	ac97_template_t ac97;
 	int err;
@@ -1616,7 +1625,7 @@
 	if ((err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97)) < 0)
 		return err;
 
-	snd_ac97_tune_hardware(chip->ac97, ac97_quirks, ac97_quirk);
+	snd_ac97_tune_hardware(chip->ac97, ac97_quirks, quirk_override);
 
 	if (chip->chip_type != TYPE_VIA686) {
 		/* use slot 10/11 */
@@ -1635,8 +1644,6 @@
 	int i, err, caps;
 	unsigned char val;
 
-	pci_write_config_byte(chip->pci, VIA_FUNC_ENABLE,
-			      chip->old_legacy & ~(VIA_FUNC_ENABLE_SB|VIA_FUNC_ENABLE_FM));
 	caps = chip->chip_type == TYPE_VIA8233A ? 1 : 2;
 	for (i = 0; i < caps; i++) {
 		snd_via8233_capture_source.index = i;
@@ -1673,7 +1680,6 @@
 	legacy_cfg = chip->old_legacy_cfg;
 	legacy |= VIA_FUNC_MIDI_IRQMASK;	/* FIXME: correct? (disable MIDI) */
 	legacy &= ~VIA_FUNC_ENABLE_GAME;	/* disable joystick */
-	legacy &= ~(VIA_FUNC_ENABLE_SB|VIA_FUNC_ENABLE_FM);	/* diable SB & FM */
 	if (chip->revision >= VIA_REV_686_H) {
 		rev_h = 1;
 		if (mpu_port[dev] >= 0x200) {	/* force MIDI */
@@ -1911,7 +1917,6 @@
 
 	pci_set_power_state(chip->pci, 3);
 	pci_disable_device(chip->pci);
-	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
 	return 0;
 }
 
@@ -1946,7 +1951,6 @@
 	for (i = 0; i < chip->num_devs; i++)
 		snd_via82xx_channel_reset(chip, &chip->devs[i]);
 
-	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
 	return 0;
 }
 #endif /* CONFIG_PM */
@@ -2016,7 +2020,6 @@
 	chip->revision = revision;
 
 	spin_lock_init(&chip->reg_lock);
-	spin_lock_init(&chip->ac97_lock);
 	spin_lock_init(&chip->rates[0].lock);
 	spin_lock_init(&chip->rates[1].lock);
 	chip->card = card;
@@ -2025,6 +2028,8 @@
 
 	pci_read_config_byte(pci, VIA_FUNC_ENABLE, &chip->old_legacy);
 	pci_read_config_byte(pci, VIA_PNP_CONTROL, &chip->old_legacy_cfg);
+	pci_write_config_byte(chip->pci, VIA_FUNC_ENABLE,
+			      chip->old_legacy & ~(VIA_FUNC_ENABLE_SB|VIA_FUNC_ENABLE_FM));
 
 	if ((err = pci_request_regions(pci, card->driver)) < 0) {
 		kfree(chip);
@@ -2107,11 +2112,14 @@
 		{ .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 = 0x147b, .device = 0x1401, .action = VIA_DXS_ENABLE }, /* ABIT KD7(-RAID) */
-		{ .vendor = 0x14ff, .device = 0x0403, .action = VIA_DXS_ENABLE }, /* Twinhead mobo */
 		{ .vendor = 0x1462, .device = 0x3800, .action = VIA_DXS_ENABLE }, /* MSI KT266 */
-		{ .vendor = 0x1462, .device = 0x7120, .action = VIA_DXS_ENABLE }, /* MSI KT4V */
 		{ .vendor = 0x1462, .device = 0x5901, .action = VIA_DXS_NO_VRA }, /* MSI KT6 Delta-SR */
+		{ .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 */
diff -Nru a/sound/pci/via82xx_modem.c b/sound/pci/via82xx_modem.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/sound/pci/via82xx_modem.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,1256 @@
+/*
+ *   ALSA modem driver for VIA VT82xx (South Bridge)
+ *
+ *   VT82C686A/B/C, VT8233A/C, VT8235
+ *
+ *	Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
+ *	                   Tjeerd.Mulder <Tjeerd.Mulder@fujitsu-siemens.com>
+ *                    2002 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
+ *
+ */
+
+/*
+ * Changes:
+ *
+ * Sep. 2,  2004  Sasha Khapyorsky <sashak@smlink.com>
+ *      Modified from original audio driver 'via82xx.c' to support AC97
+ *      modems.
+ */
+
+#include <sound/driver.h>
+#include <asm/io.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/moduleparam.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/info.h>
+#include <sound/ac97_codec.h>
+#include <sound/initval.h>
+
+#if 0
+#define POINTER_DEBUG
+#endif
+
+MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
+MODULE_DESCRIPTION("VIA VT82xx modem");
+MODULE_LICENSE("GPL");
+MODULE_SUPPORTED_DEVICE("{{VIA,VT82C686A/B/C modem,pci}}");
+
+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 */
+static int ac97_clock[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 48000};
+
+module_param_array(index, int, NULL, 0444);
+MODULE_PARM_DESC(index, "Index value for VIA 82xx bridge.");
+module_param_array(id, charp, NULL, 0444);
+MODULE_PARM_DESC(id, "ID string for VIA 82xx bridge.");
+module_param_array(enable, bool, NULL, 0444);
+MODULE_PARM_DESC(enable, "Enable modem part of VIA 82xx bridge.");
+module_param_array(ac97_clock, int, NULL, 0444);
+MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (default 48000Hz).");
+
+
+/*
+ *  Direct registers
+ */
+
+#define VIAREG(via, x) ((via)->port + VIA_REG_##x)
+#define VIADEV_REG(viadev, x) ((viadev)->port + VIA_REG_##x)
+
+/* common offsets */
+#define VIA_REG_OFFSET_STATUS		0x00	/* byte - channel status */
+#define   VIA_REG_STAT_ACTIVE		0x80	/* RO */
+#define   VIA_REG_STAT_PAUSED		0x40	/* RO */
+#define   VIA_REG_STAT_TRIGGER_QUEUED	0x08	/* RO */
+#define   VIA_REG_STAT_STOPPED		0x04	/* RWC */
+#define   VIA_REG_STAT_EOL		0x02	/* RWC */
+#define   VIA_REG_STAT_FLAG		0x01	/* RWC */
+#define VIA_REG_OFFSET_CONTROL		0x01	/* byte - channel control */
+#define   VIA_REG_CTRL_START		0x80	/* WO */
+#define   VIA_REG_CTRL_TERMINATE	0x40	/* WO */
+#define   VIA_REG_CTRL_AUTOSTART	0x20
+#define   VIA_REG_CTRL_PAUSE		0x08	/* RW */
+#define   VIA_REG_CTRL_INT_STOP		0x04		
+#define   VIA_REG_CTRL_INT_EOL		0x02
+#define   VIA_REG_CTRL_INT_FLAG		0x01
+#define   VIA_REG_CTRL_RESET		0x01	/* RW - probably reset? undocumented */
+#define   VIA_REG_CTRL_INT (VIA_REG_CTRL_INT_FLAG | VIA_REG_CTRL_INT_EOL | VIA_REG_CTRL_AUTOSTART)
+#define VIA_REG_OFFSET_TYPE		0x02	/* byte - channel type (686 only) */
+#define   VIA_REG_TYPE_AUTOSTART	0x80	/* RW - autostart at EOL */
+#define   VIA_REG_TYPE_16BIT		0x20	/* RW */
+#define   VIA_REG_TYPE_STEREO		0x10	/* RW */
+#define   VIA_REG_TYPE_INT_LLINE	0x00
+#define   VIA_REG_TYPE_INT_LSAMPLE	0x04
+#define   VIA_REG_TYPE_INT_LESSONE	0x08
+#define   VIA_REG_TYPE_INT_MASK		0x0c
+#define   VIA_REG_TYPE_INT_EOL		0x02
+#define   VIA_REG_TYPE_INT_FLAG		0x01
+#define VIA_REG_OFFSET_TABLE_PTR	0x04	/* dword - channel table pointer */
+#define VIA_REG_OFFSET_CURR_PTR		0x04	/* dword - channel current pointer */
+#define VIA_REG_OFFSET_STOP_IDX		0x08	/* dword - stop index, channel type, sample rate */
+#define VIA_REG_OFFSET_CURR_COUNT	0x0c	/* dword - channel current count (24 bit) */
+#define VIA_REG_OFFSET_CURR_INDEX	0x0f	/* byte - channel current index (for via8233 only) */
+
+#define DEFINE_VIA_REGSET(name,val) \
+enum {\
+	VIA_REG_##name##_STATUS		= (val),\
+	VIA_REG_##name##_CONTROL	= (val) + 0x01,\
+	VIA_REG_##name##_TYPE		= (val) + 0x02,\
+	VIA_REG_##name##_TABLE_PTR	= (val) + 0x04,\
+	VIA_REG_##name##_CURR_PTR	= (val) + 0x04,\
+	VIA_REG_##name##_STOP_IDX	= (val) + 0x08,\
+	VIA_REG_##name##_CURR_COUNT	= (val) + 0x0c,\
+}
+
+/* modem block */
+DEFINE_VIA_REGSET(MO, 0x40);
+DEFINE_VIA_REGSET(MI, 0x50);
+
+/* AC'97 */
+#define VIA_REG_AC97			0x80	/* dword */
+#define   VIA_REG_AC97_CODEC_ID_MASK	(3<<30)
+#define   VIA_REG_AC97_CODEC_ID_SHIFT	30
+#define   VIA_REG_AC97_CODEC_ID_PRIMARY	0x00
+#define   VIA_REG_AC97_CODEC_ID_SECONDARY 0x01
+#define   VIA_REG_AC97_SECONDARY_VALID	(1<<27)
+#define   VIA_REG_AC97_PRIMARY_VALID	(1<<25)
+#define   VIA_REG_AC97_BUSY		(1<<24)
+#define   VIA_REG_AC97_READ		(1<<23)
+#define   VIA_REG_AC97_CMD_SHIFT	16
+#define   VIA_REG_AC97_CMD_MASK		0x7e
+#define   VIA_REG_AC97_DATA_SHIFT	0
+#define   VIA_REG_AC97_DATA_MASK	0xffff
+
+#define VIA_REG_SGD_SHADOW		0x84	/* dword */
+#define   VIA_REG_SGD_STAT_PB_FLAG	(1<<0)
+#define   VIA_REG_SGD_STAT_CP_FLAG	(1<<1)
+#define   VIA_REG_SGD_STAT_FM_FLAG	(1<<2)
+#define   VIA_REG_SGD_STAT_PB_EOL	(1<<4)
+#define   VIA_REG_SGD_STAT_CP_EOL	(1<<5)
+#define   VIA_REG_SGD_STAT_FM_EOL	(1<<6)
+#define   VIA_REG_SGD_STAT_PB_STOP	(1<<8)
+#define   VIA_REG_SGD_STAT_CP_STOP	(1<<9)
+#define   VIA_REG_SGD_STAT_FM_STOP	(1<<10)
+#define   VIA_REG_SGD_STAT_PB_ACTIVE	(1<<12)
+#define   VIA_REG_SGD_STAT_CP_ACTIVE	(1<<13)
+#define   VIA_REG_SGD_STAT_FM_ACTIVE	(1<<14)
+#define   VIA_REG_SGD_STAT_MR_FLAG      (1<<16)
+#define   VIA_REG_SGD_STAT_MW_FLAG      (1<<17)
+#define   VIA_REG_SGD_STAT_MR_EOL       (1<<20)
+#define   VIA_REG_SGD_STAT_MW_EOL       (1<<21)
+#define   VIA_REG_SGD_STAT_MR_STOP      (1<<24)
+#define   VIA_REG_SGD_STAT_MW_STOP      (1<<25)
+#define   VIA_REG_SGD_STAT_MR_ACTIVE    (1<<28)
+#define   VIA_REG_SGD_STAT_MW_ACTIVE    (1<<29)
+
+#define VIA_REG_GPI_STATUS		0x88
+#define VIA_REG_GPI_INTR		0x8c
+
+#define VIA_TBL_BIT_FLAG	0x40000000
+#define VIA_TBL_BIT_EOL		0x80000000
+
+/* pci space */
+#define VIA_ACLINK_STAT		0x40
+#define  VIA_ACLINK_C11_READY	0x20
+#define  VIA_ACLINK_C10_READY	0x10
+#define  VIA_ACLINK_C01_READY	0x04 /* secondary codec ready */
+#define  VIA_ACLINK_LOWPOWER	0x02 /* low-power state */
+#define  VIA_ACLINK_C00_READY	0x01 /* primary codec ready */
+#define VIA_ACLINK_CTRL		0x41
+#define  VIA_ACLINK_CTRL_ENABLE	0x80 /* 0: disable, 1: enable */
+#define  VIA_ACLINK_CTRL_RESET	0x40 /* 0: assert, 1: de-assert */
+#define  VIA_ACLINK_CTRL_SYNC	0x20 /* 0: release SYNC, 1: force SYNC hi */
+#define  VIA_ACLINK_CTRL_SDO	0x10 /* 0: release SDO, 1: force SDO hi */
+#define  VIA_ACLINK_CTRL_VRA	0x08 /* 0: disable VRA, 1: enable VRA */
+#define  VIA_ACLINK_CTRL_PCM	0x04 /* 0: disable PCM, 1: enable PCM */
+#define  VIA_ACLINK_CTRL_FM	0x02 /* via686 only */
+#define  VIA_ACLINK_CTRL_SB	0x01 /* via686 only */
+#define  VIA_ACLINK_CTRL_INIT	(VIA_ACLINK_CTRL_ENABLE|\
+				 VIA_ACLINK_CTRL_RESET|\
+				 VIA_ACLINK_CTRL_PCM)
+#define VIA_FUNC_ENABLE		0x42
+#define  VIA_FUNC_MIDI_PNP	0x80 /* FIXME: it's 0x40 in the datasheet! */
+#define  VIA_FUNC_MIDI_IRQMASK	0x40 /* FIXME: not documented! */
+#define  VIA_FUNC_RX2C_WRITE	0x20
+#define  VIA_FUNC_SB_FIFO_EMPTY	0x10
+#define  VIA_FUNC_ENABLE_GAME	0x08
+#define  VIA_FUNC_ENABLE_FM	0x04
+#define  VIA_FUNC_ENABLE_MIDI	0x02
+#define  VIA_FUNC_ENABLE_SB	0x01
+#define VIA_PNP_CONTROL		0x43
+#define VIA_MC97_CTRL		0x44
+#define  VIA_MC97_CTRL_ENABLE   0x80
+#define  VIA_MC97_CTRL_SECONDARY 0x40
+#define  VIA_MC97_CTRL_INIT     (VIA_MC97_CTRL_ENABLE|\
+                                 VIA_MC97_CTRL_SECONDARY)
+
+
+typedef struct _snd_via82xx_modem via82xx_t;
+typedef struct via_dev viadev_t;
+
+/*
+ * pcm stream
+ */
+
+struct snd_via_sg_table {
+	unsigned int offset;
+	unsigned int size;
+} ;
+
+#define VIA_TABLE_SIZE	255
+
+struct via_dev {
+	unsigned int reg_offset;
+	unsigned long port;
+	int direction;	/* playback = 0, capture = 1 */
+        snd_pcm_substream_t *substream;
+	int running;
+	unsigned int tbl_entries; /* # descriptors */
+	struct snd_dma_buffer table;
+	struct snd_via_sg_table *idx_table;
+	/* for recovery from the unexpected pointer */
+	unsigned int lastpos;
+	unsigned int bufsize;
+	unsigned int bufsize2;
+};
+
+enum { TYPE_CARD_VIA82XX_MODEM = 1 };
+
+#define VIA_MAX_MODEM_DEVS	2
+
+struct _snd_via82xx_modem {
+	int irq;
+
+	unsigned long port;
+
+	unsigned int intr_mask; /* SGD_SHADOW mask to check interrupts */
+
+	struct pci_dev *pci;
+	snd_card_t *card;
+
+	unsigned int num_devs;
+	unsigned int playback_devno, capture_devno;
+	viadev_t devs[VIA_MAX_MODEM_DEVS];
+
+	snd_pcm_t *pcms[2];
+
+	ac97_bus_t *ac97_bus;
+	ac97_t *ac97;
+	unsigned int ac97_clock;
+	unsigned int ac97_secondary;	/* secondary AC'97 codec is present */
+
+	spinlock_t reg_lock;
+	snd_info_entry_t *proc_entry;
+};
+
+static struct pci_device_id snd_via82xx_modem_ids[] = {
+	{ 0x1106, 0x3068, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_CARD_VIA82XX_MODEM, },
+	{ 0, }
+};
+
+MODULE_DEVICE_TABLE(pci, snd_via82xx_modem_ids);
+
+/*
+ */
+
+/*
+ * allocate and initialize the descriptor buffers
+ * periods = number of periods
+ * fragsize = period size in bytes
+ */
+static int build_via_table(viadev_t *dev, snd_pcm_substream_t *substream,
+			   struct pci_dev *pci,
+			   unsigned int periods, unsigned int fragsize)
+{
+	unsigned int i, idx, ofs, rest;
+	via82xx_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_sg_buf *sgbuf = snd_pcm_substream_sgbuf(substream);
+
+	if (dev->table.area == NULL) {
+		/* the start of each lists must be aligned to 8 bytes,
+		 * but the kernel pages are much bigger, so we don't care
+		 */
+		if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci),
+					PAGE_ALIGN(VIA_TABLE_SIZE * 2 * 8),
+					&dev->table) < 0)
+			return -ENOMEM;
+	}
+	if (! dev->idx_table) {
+		dev->idx_table = kmalloc(sizeof(*dev->idx_table) * VIA_TABLE_SIZE, GFP_KERNEL);
+		if (! dev->idx_table)
+			return -ENOMEM;
+	}
+
+	/* fill the entries */
+	idx = 0;
+	ofs = 0;
+	for (i = 0; i < periods; i++) {
+		rest = fragsize;
+		/* fill descriptors for a period.
+		 * a period can be split to several descriptors if it's
+		 * over page boundary.
+		 */
+		do {
+			unsigned int r;
+			unsigned int flag;
+
+			if (idx >= VIA_TABLE_SIZE) {
+				snd_printk(KERN_ERR "via82xx: too much table size!\n");
+				return -EINVAL;
+			}
+			((u32 *)dev->table.area)[idx << 1] = cpu_to_le32((u32)snd_pcm_sgbuf_get_addr(sgbuf, ofs));
+			r = PAGE_SIZE - (ofs % PAGE_SIZE);
+			if (rest < r)
+				r = rest;
+			rest -= r;
+			if (! rest) {
+				if (i == periods - 1)
+					flag = VIA_TBL_BIT_EOL; /* buffer boundary */
+				else
+					flag = VIA_TBL_BIT_FLAG; /* period boundary */
+			} else
+				flag = 0; /* period continues to the next */
+			// printk("via: tbl %d: at %d  size %d (rest %d)\n", idx, ofs, r, rest);
+			((u32 *)dev->table.area)[(idx<<1) + 1] = cpu_to_le32(r | flag);
+			dev->idx_table[idx].offset = ofs;
+			dev->idx_table[idx].size = r;
+			ofs += r;
+			idx++;
+		} while (rest > 0);
+	}
+	dev->tbl_entries = idx;
+	dev->bufsize = periods * fragsize;
+	dev->bufsize2 = dev->bufsize / 2;
+	return 0;
+}
+
+
+static int clean_via_table(viadev_t *dev, snd_pcm_substream_t *substream,
+			   struct pci_dev *pci)
+{
+	if (dev->table.area) {
+		snd_dma_free_pages(&dev->table);
+		dev->table.area = NULL;
+	}
+	if (dev->idx_table) {
+		kfree(dev->idx_table);
+		dev->idx_table = NULL;
+	}
+	return 0;
+}
+
+/*
+ *  Basic I/O
+ */
+
+static inline unsigned int snd_via82xx_codec_xread(via82xx_t *chip)
+{
+	return inl(VIAREG(chip, AC97));
+}
+ 
+static inline void snd_via82xx_codec_xwrite(via82xx_t *chip, unsigned int val)
+{
+	outl(val, VIAREG(chip, AC97));
+}
+ 
+static int snd_via82xx_codec_ready(via82xx_t *chip, int secondary)
+{
+	unsigned int timeout = 1000;	/* 1ms */
+	unsigned int val;
+	
+	while (timeout-- > 0) {
+		udelay(1);
+		if (!((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_BUSY))
+			return val & 0xffff;
+	}
+	snd_printk(KERN_ERR "codec_ready: codec %i is not ready [0x%x]\n", secondary, snd_via82xx_codec_xread(chip));
+	return -EIO;
+}
+ 
+static int snd_via82xx_codec_valid(via82xx_t *chip, int secondary)
+{
+	unsigned int timeout = 1000;	/* 1ms */
+	unsigned int val, val1;
+	unsigned int stat = !secondary ? VIA_REG_AC97_PRIMARY_VALID :
+					 VIA_REG_AC97_SECONDARY_VALID;
+	
+	while (timeout-- > 0) {
+		val = snd_via82xx_codec_xread(chip);
+		val1 = val & (VIA_REG_AC97_BUSY | stat);
+		if (val1 == stat)
+			return val & 0xffff;
+		udelay(1);
+	}
+	return -EIO;
+}
+ 
+static void snd_via82xx_codec_wait(ac97_t *ac97)
+{
+	via82xx_t *chip = ac97->private_data;
+	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);
+}
+
+static void snd_via82xx_codec_write(ac97_t *ac97,
+				    unsigned short reg,
+				    unsigned short val)
+{
+	via82xx_t *chip = ac97->private_data;
+	unsigned int xval;
+	
+	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;
+	xval |= val << VIA_REG_AC97_DATA_SHIFT;
+	snd_via82xx_codec_xwrite(chip, xval);
+	snd_via82xx_codec_ready(chip, ac97->num);
+}
+
+static unsigned short snd_via82xx_codec_read(ac97_t *ac97, unsigned short reg)
+{
+	via82xx_t *chip = ac97->private_data;
+	unsigned int xval, val = 0xffff;
+	int again = 0;
+
+	xval = ac97->num << VIA_REG_AC97_CODEC_ID_SHIFT;
+	xval |= ac97->num ? VIA_REG_AC97_SECONDARY_VALID : VIA_REG_AC97_PRIMARY_VALID;
+	xval |= VIA_REG_AC97_READ;
+	xval |= (reg & 0x7f) << VIA_REG_AC97_CMD_SHIFT;
+      	while (1) {
+      		if (again++ > 3) {
+			snd_printk(KERN_ERR "codec_read: codec %i is not valid [0x%x]\n", ac97->num, snd_via82xx_codec_xread(chip));
+		      	return 0xffff;
+		}
+		snd_via82xx_codec_xwrite(chip, xval);
+		udelay (20);
+		if (snd_via82xx_codec_valid(chip, ac97->num) >= 0) {
+			udelay(25);
+			val = snd_via82xx_codec_xread(chip);
+			break;
+		}
+	}
+	return val & 0xffff;
+}
+
+static void snd_via82xx_channel_reset(via82xx_t *chip, viadev_t *viadev)
+{
+	outb(VIA_REG_CTRL_PAUSE | VIA_REG_CTRL_TERMINATE | VIA_REG_CTRL_RESET,
+	     VIADEV_REG(viadev, OFFSET_CONTROL));
+	inb(VIADEV_REG(viadev, OFFSET_CONTROL));
+	udelay(50);
+	/* disable interrupts */
+	outb(0x00, VIADEV_REG(viadev, OFFSET_CONTROL));
+	/* clear interrupts */
+	outb(0x03, VIADEV_REG(viadev, OFFSET_STATUS));
+	outb(0x00, VIADEV_REG(viadev, OFFSET_TYPE)); /* for via686 */
+	// outl(0, VIADEV_REG(viadev, OFFSET_CURR_PTR));
+	viadev->lastpos = 0;
+}
+
+
+/*
+ *  Interrupt handler
+ */
+
+static irqreturn_t snd_via82xx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	via82xx_t *chip = dev_id;
+	unsigned int status;
+	unsigned int i;
+
+	status = inl(VIAREG(chip, SGD_SHADOW));
+	if (! (status & chip->intr_mask)) {
+		return IRQ_NONE;
+	}
+// _skip_sgd:
+
+	/* check status for each stream */
+	spin_lock(&chip->reg_lock);
+	for (i = 0; i < chip->num_devs; i++) {
+		viadev_t *viadev = &chip->devs[i];
+		unsigned char c_status = inb(VIADEV_REG(viadev, OFFSET_STATUS));
+		c_status &= (VIA_REG_STAT_EOL|VIA_REG_STAT_FLAG|VIA_REG_STAT_STOPPED);
+		if (! c_status)
+			continue;
+		if (viadev->substream && viadev->running) {
+			spin_unlock(&chip->reg_lock);
+			snd_pcm_period_elapsed(viadev->substream);
+			spin_lock(&chip->reg_lock);
+		}
+		outb(c_status, VIADEV_REG(viadev, OFFSET_STATUS)); /* ack */
+	}
+	spin_unlock(&chip->reg_lock);
+	return IRQ_HANDLED;
+}
+
+/*
+ *  PCM callbacks
+ */
+
+/*
+ * trigger callback
+ */
+static int snd_via82xx_pcm_trigger(snd_pcm_substream_t * substream, int cmd)
+{
+	via82xx_t *chip = snd_pcm_substream_chip(substream);
+	viadev_t *viadev = (viadev_t *)substream->runtime->private_data;
+	unsigned char val = 0;
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+		val |= VIA_REG_CTRL_START;
+		viadev->running = 1;
+		break;
+	case SNDRV_PCM_TRIGGER_STOP:
+		val = VIA_REG_CTRL_TERMINATE;
+		viadev->running = 0;
+		break;
+	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+		val |= VIA_REG_CTRL_PAUSE;
+		viadev->running = 0;
+		break;
+	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+		viadev->running = 1;
+		break;
+	default:
+		return -EINVAL;
+	}
+	outb(val, VIADEV_REG(viadev, OFFSET_CONTROL));
+	if (cmd == SNDRV_PCM_TRIGGER_STOP)
+		snd_via82xx_channel_reset(chip, viadev);
+	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
+ */
+
+/*
+ * calculate the linear position at the given sg-buffer index and the rest count
+ */
+
+#define check_invalid_pos(viadev,pos) \
+	((pos) < viadev->lastpos && ((pos) >= viadev->bufsize2 || viadev->lastpos < viadev->bufsize2))
+
+static inline unsigned int calc_linear_pos(viadev_t *viadev, unsigned int idx, unsigned int count)
+{
+	unsigned int size, res;
+
+	size = viadev->idx_table[idx].size;
+	res = viadev->idx_table[idx].offset + size - count;
+
+	/* check the validity of the calculated position */
+	if (size < count) {
+		snd_printd(KERN_ERR "invalid via82xx_cur_ptr (size = %d, count = %d)\n", (int)size, (int)count);
+		res = viadev->lastpos;
+	} else if (check_invalid_pos(viadev, res)) {
+#ifdef POINTER_DEBUG
+		printk("fail: idx = %i/%i, lastpos = 0x%x, bufsize2 = 0x%x, offsize = 0x%x, size = 0x%x, count = 0x%x\n", idx, viadev->tbl_entries, viadev->lastpos, viadev->bufsize2, viadev->idx_table[idx].offset, viadev->idx_table[idx].size, count);
+#endif
+		if (count && size < count) {
+			snd_printd(KERN_ERR "invalid via82xx_cur_ptr, using last valid pointer\n");
+			res = viadev->lastpos;
+		} else {
+			if (! count)
+				/* bogus count 0 on the DMA boundary? */
+				res = viadev->idx_table[idx].offset;
+			else
+				/* count register returns full size when end of buffer is reached */
+				res = viadev->idx_table[idx].offset + size;
+			if (check_invalid_pos(viadev, res)) {
+				snd_printd(KERN_ERR "invalid via82xx_cur_ptr (2), using last valid pointer\n");
+				res = viadev->lastpos;
+			}
+		}
+	}
+	viadev->lastpos = res; /* remember the last position */
+	if (res >= viadev->bufsize)
+		res -= viadev->bufsize;
+	return res;
+}
+
+/*
+ * get the current pointer on via686
+ */
+static snd_pcm_uframes_t snd_via686_pcm_pointer(snd_pcm_substream_t *substream)
+{
+	via82xx_t *chip = snd_pcm_substream_chip(substream);
+	viadev_t *viadev = (viadev_t *)substream->runtime->private_data;
+	unsigned int idx, ptr, count, res;
+
+	snd_assert(viadev->tbl_entries, return 0);
+	if (!(inb(VIADEV_REG(viadev, OFFSET_STATUS)) & VIA_REG_STAT_ACTIVE))
+		return 0;
+
+	spin_lock(&chip->reg_lock);
+	count = inl(VIADEV_REG(viadev, OFFSET_CURR_COUNT)) & 0xffffff;
+	/* The via686a does not have the current index register,
+	 * so we need to calculate the index from CURR_PTR.
+	 */
+	ptr = inl(VIADEV_REG(viadev, OFFSET_CURR_PTR));
+	if (ptr <= (unsigned int)viadev->table.addr)
+		idx = 0;
+	else /* CURR_PTR holds the address + 8 */
+		idx = ((ptr - (unsigned int)viadev->table.addr) / 8 - 1) % viadev->tbl_entries;
+	res = calc_linear_pos(viadev, idx, count);
+	spin_unlock(&chip->reg_lock);
+
+	return bytes_to_frames(substream->runtime, res);
+}
+
+/*
+ * hw_params callback:
+ * allocate the buffer and build up the buffer description table
+ */
+static int snd_via82xx_hw_params(snd_pcm_substream_t * substream,
+				 snd_pcm_hw_params_t * hw_params)
+{
+	via82xx_t *chip = snd_pcm_substream_chip(substream);
+	viadev_t *viadev = (viadev_t *)substream->runtime->private_data;
+	int err;
+
+	err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
+	if (err < 0)
+		return err;
+	err = build_via_table(viadev, substream, chip->pci,
+			      params_periods(hw_params),
+			      params_period_bytes(hw_params));
+	if (err < 0)
+		return err;
+
+	snd_ac97_write(chip->ac97, AC97_LINE1_RATE, params_rate(hw_params));
+	snd_ac97_write(chip->ac97, AC97_LINE1_LEVEL, 0);
+
+	return 0;
+}
+
+/*
+ * hw_free callback:
+ * clean up the buffer description table and release the buffer
+ */
+static int snd_via82xx_hw_free(snd_pcm_substream_t * substream)
+{
+	via82xx_t *chip = snd_pcm_substream_chip(substream);
+	viadev_t *viadev = (viadev_t *)substream->runtime->private_data;
+
+	clean_via_table(viadev, substream, chip->pci);
+	snd_pcm_lib_free_pages(substream);
+	return 0;
+}
+
+
+/*
+ * set up the table pointer
+ */
+static void snd_via82xx_set_table_ptr(via82xx_t *chip, viadev_t *viadev)
+{
+	snd_via82xx_codec_ready(chip, chip->ac97_secondary);
+	outl((u32)viadev->table.addr, VIADEV_REG(viadev, OFFSET_TABLE_PTR));
+	udelay(20);
+	snd_via82xx_codec_ready(chip, chip->ac97_secondary);
+}
+
+/*
+ * prepare callback for playback and capture
+ */
+static int snd_via82xx_pcm_prepare(snd_pcm_substream_t *substream)
+{
+	via82xx_t *chip = snd_pcm_substream_chip(substream);
+	viadev_t *viadev = (viadev_t *)substream->runtime->private_data;
+
+	snd_via82xx_channel_reset(chip, viadev);
+	/* this must be set after channel_reset */
+	snd_via82xx_set_table_ptr(chip, viadev);
+	outb(VIA_REG_TYPE_AUTOSTART|VIA_REG_TYPE_INT_EOL|VIA_REG_TYPE_INT_FLAG,
+	     VIADEV_REG(viadev, OFFSET_TYPE));
+	return 0;
+}
+
+/*
+ * pcm hardware definition, identical for both playback and capture
+ */
+static snd_pcm_hardware_t snd_via82xx_hw =
+{
+	.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_PAUSE),
+	.formats =		SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
+	.rates =		SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_KNOT,
+	.rate_min =		8000,
+	.rate_max =		16000,
+	.channels_min =		1,
+	.channels_max =		1,
+	.buffer_bytes_max =	128 * 1024,
+	.period_bytes_min =	32,
+	.period_bytes_max =	128 * 1024,
+	.periods_min =		2,
+	.periods_max =		VIA_TABLE_SIZE / 2,
+	.fifo_size =		0,
+};
+
+
+/*
+ * open callback skeleton
+ */
+static int snd_via82xx_modem_pcm_open(via82xx_t *chip, viadev_t *viadev, snd_pcm_substream_t * substream)
+{
+	snd_pcm_runtime_t *runtime = substream->runtime;
+	int err;
+        static unsigned int rates[] = { 8000,  9600, 12000, 16000 };
+        static snd_pcm_hw_constraint_list_t hw_constraints_rates = {
+                .count = ARRAY_SIZE(rates),
+                .list = rates,
+                .mask = 0,
+        };
+
+	runtime->hw = snd_via82xx_hw;
+	
+        if ((err = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates)) < 0)
+                return err;
+
+	/* we may remove following constaint when we modify table entries
+	   in interrupt */
+	if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
+		return err;
+
+	runtime->private_data = viadev;
+	viadev->substream = substream;
+
+	return 0;
+}
+
+
+/*
+ * open callback for playback
+ */
+static int snd_via82xx_playback_open(snd_pcm_substream_t * substream)
+{
+	via82xx_t *chip = snd_pcm_substream_chip(substream);
+	viadev_t *viadev = &chip->devs[chip->playback_devno + substream->number];
+
+	return snd_via82xx_modem_pcm_open(chip, viadev, substream);
+}
+
+/*
+ * open callback for capture
+ */
+static int snd_via82xx_capture_open(snd_pcm_substream_t * substream)
+{
+	via82xx_t *chip = snd_pcm_substream_chip(substream);
+	viadev_t *viadev = &chip->devs[chip->capture_devno + substream->pcm->device];
+
+	return snd_via82xx_modem_pcm_open(chip, viadev, substream);
+}
+
+/*
+ * close callback
+ */
+static int snd_via82xx_pcm_close(snd_pcm_substream_t * substream)
+{
+	viadev_t *viadev = (viadev_t *)substream->runtime->private_data;
+
+	viadev->substream = NULL;
+	return 0;
+}
+
+
+/* via686 playback callbacks */
+static snd_pcm_ops_t snd_via686_playback_ops = {
+	.open =		snd_via82xx_playback_open,
+	.close =	snd_via82xx_pcm_close,
+	.ioctl =	snd_pcm_lib_ioctl,
+	.hw_params =	snd_via82xx_hw_params,
+	.hw_free =	snd_via82xx_hw_free,
+	.prepare =	snd_via82xx_pcm_prepare,
+	.trigger =	snd_via82xx_modem_pcm_trigger,
+	.pointer =	snd_via686_pcm_pointer,
+	.page =		snd_pcm_sgbuf_ops_page,
+};
+
+/* via686 capture callbacks */
+static snd_pcm_ops_t snd_via686_capture_ops = {
+	.open =		snd_via82xx_capture_open,
+	.close =	snd_via82xx_pcm_close,
+	.ioctl =	snd_pcm_lib_ioctl,
+	.hw_params =	snd_via82xx_hw_params,
+	.hw_free =	snd_via82xx_hw_free,
+	.prepare =	snd_via82xx_pcm_prepare,
+	.trigger =	snd_via82xx_modem_pcm_trigger,
+	.pointer =	snd_via686_pcm_pointer,
+	.page =		snd_pcm_sgbuf_ops_page,
+};
+
+
+static void init_viadev(via82xx_t *chip, int idx, unsigned int reg_offset, int direction)
+{
+	chip->devs[idx].reg_offset = reg_offset;
+	chip->devs[idx].direction = direction;
+	chip->devs[idx].port = chip->port + reg_offset;
+}
+
+/*
+ * create a pcm instance for via686a/b
+ */
+static int __devinit snd_via686_pcm_new(via82xx_t *chip)
+{
+	snd_pcm_t *pcm;
+	int err;
+
+	chip->playback_devno = 0;
+	chip->capture_devno = 1;
+	chip->num_devs = 2;
+	chip->intr_mask = 0x330000; /* FLAGS | EOL for MR, MW */
+
+	err = snd_pcm_new(chip->card, chip->card->shortname, 0, 1, 1, &pcm);
+	if (err < 0)
+		return err;
+	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_via686_playback_ops);
+	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_via686_capture_ops);
+	pcm->private_data = chip;
+	strcpy(pcm->name, chip->card->shortname);
+	chip->pcms[0] = pcm;
+	init_viadev(chip, 0, VIA_REG_MO_STATUS, 0);
+	init_viadev(chip, 1, VIA_REG_MI_STATUS, 1);
+
+	if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
+							 snd_dma_pci_data(chip->pci), 64*1024, 128*1024)) < 0)
+		return err;
+
+	return 0;
+}
+
+
+/*
+ *  Mixer part
+ */
+
+
+static void snd_via82xx_mixer_free_ac97_bus(ac97_bus_t *bus)
+{
+	via82xx_t *chip = bus->private_data;
+	chip->ac97_bus = NULL;
+}
+
+static void snd_via82xx_mixer_free_ac97(ac97_t *ac97)
+{
+	via82xx_t *chip = ac97->private_data;
+	chip->ac97 = NULL;
+}
+
+
+static int __devinit snd_via82xx_mixer_new(via82xx_t *chip)
+{
+	ac97_template_t ac97;
+	int err;
+	static ac97_bus_ops_t ops = {
+		.write = snd_via82xx_codec_write,
+		.read = snd_via82xx_codec_read,
+		.wait = snd_via82xx_codec_wait,
+	};
+
+	if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &chip->ac97_bus)) < 0)
+		return err;
+	chip->ac97_bus->private_free = snd_via82xx_mixer_free_ac97_bus;
+	chip->ac97_bus->clock = chip->ac97_clock;
+	chip->ac97_bus->shared_type = AC97_SHARED_TYPE_VIA;
+
+	memset(&ac97, 0, sizeof(ac97));
+	ac97.private_data = chip;
+	ac97.private_free = snd_via82xx_mixer_free_ac97;
+	ac97.pci = chip->pci;
+	ac97.scaps = AC97_SCAP_SKIP_AUDIO;
+	ac97.num = chip->ac97_secondary;
+
+	if ((err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97)) < 0)
+		return err;
+
+	return 0;
+}
+
+
+/*
+ * proc interface
+ */
+static void snd_via82xx_proc_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
+{
+	via82xx_t *chip = entry->private_data;
+	int i;
+	
+	snd_iprintf(buffer, "%s\n\n", chip->card->longname);
+	for (i = 0; i < 0xa0; i += 4) {
+		snd_iprintf(buffer, "%02x: %08x\n", i, inl(chip->port + i));
+	}
+}
+
+static void __devinit snd_via82xx_proc_init(via82xx_t *chip)
+{
+	snd_info_entry_t *entry;
+
+	if (! snd_card_proc_new(chip->card, "via82xx", &entry))
+		snd_info_set_text_ops(entry, chip, 1024, snd_via82xx_proc_read);
+}
+
+/*
+ *
+ */
+
+static int __devinit snd_via82xx_chip_init(via82xx_t *chip)
+{
+	ac97_t ac97;
+	unsigned int val;
+	int max_count;
+	unsigned char pval;
+
+	memset(&ac97, 0, sizeof(ac97));
+	ac97.private_data = chip;
+
+	pci_read_config_byte(chip->pci, VIA_MC97_CTRL, &pval);
+	if((pval & VIA_MC97_CTRL_INIT) != VIA_MC97_CTRL_INIT) {
+		pci_write_config_byte(chip->pci, 0x44, pval|VIA_MC97_CTRL_INIT);
+		udelay(100);
+	}
+
+	pci_read_config_byte(chip->pci, VIA_ACLINK_STAT, &pval);
+	if (! (pval & VIA_ACLINK_C00_READY)) { /* codec not ready? */
+		/* deassert ACLink reset, force SYNC */
+		pci_write_config_byte(chip->pci, VIA_ACLINK_CTRL,
+				      VIA_ACLINK_CTRL_ENABLE |
+				      VIA_ACLINK_CTRL_RESET |
+				      VIA_ACLINK_CTRL_SYNC);
+		udelay(100);
+#if 1 /* FIXME: should we do full reset here for all chip models? */
+		pci_write_config_byte(chip->pci, VIA_ACLINK_CTRL, 0x00);
+		udelay(100);
+#else
+		/* deassert ACLink reset, force SYNC (warm AC'97 reset) */
+		pci_write_config_byte(chip->pci, VIA_ACLINK_CTRL,
+				      VIA_ACLINK_CTRL_RESET|VIA_ACLINK_CTRL_SYNC);
+		udelay(2);
+#endif
+		/* ACLink on, deassert ACLink reset, VSR, SGD data out */
+		pci_write_config_byte(chip->pci, VIA_ACLINK_CTRL, VIA_ACLINK_CTRL_INIT);
+		udelay(100);
+	}
+	
+	pci_read_config_byte(chip->pci, VIA_ACLINK_CTRL, &pval);
+	if ((pval & VIA_ACLINK_CTRL_INIT) != VIA_ACLINK_CTRL_INIT) {
+		/* ACLink on, deassert ACLink reset, VSR, SGD data out */
+		pci_write_config_byte(chip->pci, VIA_ACLINK_CTRL, VIA_ACLINK_CTRL_INIT);
+		udelay(100);
+	}
+
+	/* wait until codec ready */
+	max_count = ((3 * HZ) / 4) + 1;
+	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);
+
+	if ((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_BUSY)
+		snd_printk("AC'97 codec is not ready [0x%x]\n", val);
+
+	/* and then reset codec.. */
+#if 0 /* do we need it? when? */
+	snd_via82xx_codec_ready(chip, 0);
+	snd_via82xx_codec_write(&ac97, AC97_RESET, 0x0000);
+	snd_via82xx_codec_read(&ac97, 0);
+#endif
+
+	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;
+	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));
+	do {
+		if ((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_SECONDARY_VALID) {
+			chip->ac97_secondary = 1;
+			goto __ac97_ok2;
+		}
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout(1);
+	} while (--max_count > 0);
+	/* This is ok, the most of motherboards have only one codec */
+
+      __ac97_ok2:
+
+	/* route FM trap to IRQ, disable FM trap */
+	// pci_write_config_byte(chip->pci, VIA_FM_NMI_CTRL, 0);
+	/* disable all GPI interrupts */
+	outl(0, VIAREG(chip, GPI_INTR));
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+/*
+ * power management
+ */
+static int snd_via82xx_suspend(snd_card_t *card, unsigned int state)
+{
+	via82xx_t *chip = card->pm_private_data;
+	int i;
+
+	for (i = 0; i < 2; i++)
+		if (chip->pcms[i])
+			snd_pcm_suspend_all(chip->pcms[i]);
+	for (i = 0; i < chip->num_devs; i++)
+		snd_via82xx_channel_reset(chip, &chip->devs[i]);
+	synchronize_irq(chip->irq);
+	snd_ac97_suspend(chip->ac97);
+	pci_set_power_state(chip->pci, 3);
+	pci_disable_device(chip->pci);
+	return 0;
+}
+
+static int snd_via82xx_resume(snd_card_t *card, unsigned int state)
+{
+	via82xx_t *chip = card->pm_private_data;
+	int i;
+
+	pci_enable_device(chip->pci);
+	pci_set_power_state(chip->pci, 0);
+	pci_set_master(chip->pci);
+
+	snd_via82xx_chip_init(chip);
+
+	snd_ac97_resume(chip->ac97);
+
+	for (i = 0; i < chip->num_devs; i++)
+		snd_via82xx_channel_reset(chip, &chip->devs[i]);
+
+	return 0;
+}
+#endif /* CONFIG_PM */
+
+static int snd_via82xx_free(via82xx_t *chip)
+{
+	unsigned int i;
+
+	if (chip->irq < 0)
+		goto __end_hw;
+	/* disable interrupts */
+	for (i = 0; i < chip->num_devs; i++)
+		snd_via82xx_channel_reset(chip, &chip->devs[i]);
+	synchronize_irq(chip->irq);
+      __end_hw:
+	if (chip->irq >= 0)
+		free_irq(chip->irq, (void *)chip);
+	pci_release_regions(chip->pci);
+	pci_disable_device(chip->pci);
+	kfree(chip);
+	return 0;
+}
+
+static int snd_via82xx_dev_free(snd_device_t *device)
+{
+	via82xx_t *chip = device->device_data;
+	return snd_via82xx_free(chip);
+}
+
+static int __devinit snd_via82xx_create(snd_card_t * card,
+					struct pci_dev *pci,
+					int chip_type,
+					int revision,
+					unsigned int ac97_clock,
+					via82xx_t ** r_via)
+{
+	via82xx_t *chip;
+	int err;
+        static snd_device_ops_t ops = {
+		.dev_free =	snd_via82xx_dev_free,
+        };
+
+	if ((err = pci_enable_device(pci)) < 0)
+		return err;
+
+	if ((chip = kcalloc(1, sizeof(*chip), GFP_KERNEL)) == NULL) {
+		pci_disable_device(pci);
+		return -ENOMEM;
+	}
+
+	spin_lock_init(&chip->reg_lock);
+	chip->card = card;
+	chip->pci = pci;
+	chip->irq = -1;
+
+	if ((err = pci_request_regions(pci, card->driver)) < 0) {
+		kfree(chip);
+		pci_disable_device(pci);
+		return err;
+	}
+	chip->port = pci_resource_start(pci, 0);
+	if (request_irq(pci->irq, snd_via82xx_interrupt, SA_INTERRUPT|SA_SHIRQ,
+			card->driver, (void *)chip)) {
+		snd_printk("unable to grab IRQ %d\n", pci->irq);
+		snd_via82xx_free(chip);
+		return -EBUSY;
+	}
+	chip->irq = pci->irq;
+	if (ac97_clock >= 8000 && ac97_clock <= 48000)
+		chip->ac97_clock = ac97_clock;
+	synchronize_irq(chip->irq);
+
+	if ((err = snd_via82xx_chip_init(chip)) < 0) {
+		snd_via82xx_free(chip);
+		return err;
+	}
+
+	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
+		snd_via82xx_free(chip);
+		return err;
+	}
+
+	/* The 8233 ac97 controller does not implement the master bit
+	 * in the pci command register. IMHO this is a violation of the PCI spec.
+	 * We call pci_set_master here because it does not hurt. */
+	pci_set_master(pci);
+
+	snd_card_set_dev(card, &pci->dev);
+
+	*r_via = chip;
+	return 0;
+}
+
+
+static int __devinit snd_via82xx_probe(struct pci_dev *pci,
+				       const struct pci_device_id *pci_id)
+{
+	static int dev;
+	snd_card_t *card;
+	via82xx_t *chip;
+	unsigned char revision;
+	int chip_type = 0, card_type;
+	unsigned int i;
+	int err;
+
+	if (dev >= SNDRV_CARDS)
+		return -ENODEV;
+	if (!enable[dev]) {
+		dev++;
+		return -ENOENT;
+	}
+
+	card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
+	if (card == NULL)
+		return -ENOMEM;
+
+	card_type = pci_id->driver_data;
+	pci_read_config_byte(pci, PCI_REVISION_ID, &revision);
+	switch (card_type) {
+	case TYPE_CARD_VIA82XX_MODEM:
+		strcpy(card->driver, "VIA82XX-MODEM");
+		sprintf(card->shortname, "VIA 82XX modem");
+		break;
+	default:
+		snd_printk(KERN_ERR "invalid card type %d\n", card_type);
+		err = -EINVAL;
+		goto __error;
+	}
+		
+	if ((err = snd_via82xx_create(card, pci, chip_type, revision, ac97_clock[dev], &chip)) < 0)
+		goto __error;
+	if ((err = snd_via82xx_mixer_new(chip)) < 0)
+		goto __error;
+
+	if ((err = snd_via686_pcm_new(chip)) < 0 )
+		goto __error;
+
+	snd_card_set_pm_callback(card, snd_via82xx_suspend, snd_via82xx_resume, chip);
+
+	/* disable interrupts */
+	for (i = 0; i < chip->num_devs; i++)
+		snd_via82xx_channel_reset(chip, &chip->devs[i]);
+
+	sprintf(card->longname, "%s at 0x%lx, irq %d",
+		card->shortname, chip->port, chip->irq);
+
+	snd_via82xx_proc_init(chip);
+
+	if ((err = snd_card_register(card)) < 0) {
+		snd_card_free(card);
+		return err;
+	}
+	pci_set_drvdata(pci, card);
+	dev++;
+	return 0;
+
+ __error:
+	snd_card_free(card);
+	return err;
+}
+
+static void __devexit snd_via82xx_remove(struct pci_dev *pci)
+{
+	snd_card_free(pci_get_drvdata(pci));
+	pci_set_drvdata(pci, NULL);
+}
+
+static struct pci_driver driver = {
+	.name = "VIA 82xx Modem",
+	.id_table = snd_via82xx_modem_ids,
+	.probe = snd_via82xx_probe,
+	.remove = __devexit_p(snd_via82xx_remove),
+	SND_PCI_PM_CALLBACKS
+};
+
+static int __init alsa_card_via82xx_init(void)
+{
+	return pci_module_init(&driver);
+}
+
+static void __exit alsa_card_via82xx_exit(void)
+{
+	pci_unregister_driver(&driver);
+}
+
+module_init(alsa_card_via82xx_init)
+module_exit(alsa_card_via82xx_exit)
diff -Nru a/sound/pci/vx222/vx222.c b/sound/pci/vx222/vx222.c
--- a/sound/pci/vx222/vx222.c	2005-03-01 23:38:57 -08:00
+++ b/sound/pci/vx222/vx222.c	2005-03-01 23:38:57 -08:00
@@ -61,8 +61,8 @@
 };
 
 static struct pci_device_id snd_vx222_ids[] = {
-	{ 0x10b5, 0x9050, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VX_PCI_VX222_OLD, },   /* PLX */
-	{ 0x10b5, 0x9030, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VX_PCI_VX222_NEW, },   /* PLX */
+	{ 0x10b5, 0x9050, 0x1369, PCI_ANY_ID, 0, 0, VX_PCI_VX222_OLD, },   /* PLX */
+	{ 0x10b5, 0x9030, 0x1369, PCI_ANY_ID, 0, 0, VX_PCI_VX222_NEW, },   /* PLX */
 	{ 0, }
 };
 
@@ -225,7 +225,11 @@
 	snd_printdd("%s at 0x%lx & 0x%lx, irq %i\n",
 		    card->shortname, vx->port[0], vx->port[1], vx->core.irq);
 
-	if ((err = snd_vx_hwdep_new(&vx->core)) < 0) {
+#ifdef SND_VX_FW_LOADER
+	vx->core.dev = &pci->dev;
+#endif
+
+	if ((err = snd_vx_setup_firmware(&vx->core)) < 0) {
 		snd_card_free(card);
 		return err;
 	}
@@ -251,6 +255,7 @@
 	.id_table = snd_vx222_ids,
 	.probe = snd_vx222_probe,
 	.remove = __devexit_p(snd_vx222_remove),
+	SND_PCI_PM_CALLBACKS
 };
 
 static int __init alsa_card_vx222_init(void)
diff -Nru a/sound/pci/vx222/vx222_ops.c b/sound/pci/vx222/vx222_ops.c
--- a/sound/pci/vx222/vx222_ops.c	2005-03-01 23:38:44 -08:00
+++ b/sound/pci/vx222/vx222_ops.c	2005-03-01 23:38:44 -08:00
@@ -22,6 +22,7 @@
 
 #include <sound/driver.h>
 #include <linux/delay.h>
+#include <linux/firmware.h>
 #include <sound/core.h>
 #include <sound/control.h>
 #include <asm/io.h>
@@ -351,12 +352,11 @@
 /*
  * load the xilinx image
  */
-static int vx2_load_xilinx_binary(vx_core_t *chip, const snd_hwdep_dsp_image_t *xilinx)
+static int vx2_load_xilinx_binary(vx_core_t *chip, const struct firmware *xilinx)
 {
 	unsigned int i;
 	unsigned int port;
-	unsigned char data;
-	unsigned char __user *image;
+	unsigned char *image;
 
 	/* XILINX reset (wait at least 1 milisecond between reset on and off). */
 	vx_outl(chip, CNTRL, VX_CNTRL_REGISTER_VALUE | VX_XILINX_RESET_MASK);
@@ -371,10 +371,9 @@
 	else
 		port = VX_GPIOC; /* VX222 V2 and VX222_MIC_BOARD with new PLX9030 use this register */
 
-	image = xilinx->image;
-	for (i = 0; i < xilinx->length; i++, image++) {
-		__get_user(data, image);
-		if (put_xilinx_data(chip, port, 8, data) < 0)
+	image = xilinx->data;
+	for (i = 0; i < xilinx->size; i++, image++) {
+		if (put_xilinx_data(chip, port, 8, *image) < 0)
 			return -EINVAL;
 		/* don't take too much time in this loop... */
 		cond_resched();
@@ -400,25 +399,22 @@
 /*
  * load the boot/dsp images
  */
-static int vx2_load_dsp(vx_core_t *vx, const snd_hwdep_dsp_image_t *dsp)
+static int vx2_load_dsp(vx_core_t *vx, int index, const struct firmware *dsp)
 {
 	int err;
 
-	if (*dsp->name)
-		snd_printdd("loading dsp [%d] %s, size = %Zd\n",
-			dsp->index, dsp->name, dsp->length);
-	switch (dsp->index) {
-	case 0:
+	switch (index) {
+	case 1:
 		/* xilinx image */
 		if ((err = vx2_load_xilinx_binary(vx, dsp)) < 0)
 			return err;
 		if ((err = vx2_test_xilinx(vx)) < 0)
 			return err;
 		return 0;
-	case 1:
+	case 2:
 		/* DSP boot */
 		return snd_vx_dsp_boot(vx, dsp);
-	case 2:
+	case 3:
 		/* DSP image */
 		return snd_vx_dsp_load(vx, dsp);
 	default:
diff -Nru a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c
--- a/sound/pci/ymfpci/ymfpci_main.c	2005-03-01 23:39:09 -08:00
+++ b/sound/pci/ymfpci/ymfpci_main.c	2005-03-01 23:39:09 -08:00
@@ -258,7 +258,7 @@
 	return -ENOMEM;
 }
 
-int snd_ymfpci_voice_alloc(ymfpci_t *chip, ymfpci_voice_type_t type, int pair, ymfpci_voice_t **rvoice)
+static int snd_ymfpci_voice_alloc(ymfpci_t *chip, ymfpci_voice_type_t type, int pair, ymfpci_voice_t **rvoice)
 {
 	unsigned long flags;
 	int result;
@@ -278,7 +278,7 @@
 	return result;		
 }
 
-int snd_ymfpci_voice_free(ymfpci_t *chip, ymfpci_voice_t *pvoice)
+static int snd_ymfpci_voice_free(ymfpci_t *chip, ymfpci_voice_t *pvoice)
 {
 	unsigned long flags;
 	
@@ -831,8 +831,7 @@
 {
 	ymfpci_pcm_t *ypcm = runtime->private_data;
 	
-	if (ypcm)
-		kfree(ypcm);
+	kfree(ypcm);
 }
 
 static int snd_ymfpci_playback_open_1(snd_pcm_substream_t * substream)
@@ -1714,6 +1713,7 @@
 	if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &chip->ac97_bus)) < 0)
 		return err;
 	chip->ac97_bus->private_free = snd_ymfpci_mixer_free_ac97_bus;
+	chip->ac97_bus->no_vra = 1; /* YMFPCI doesn't need VRA */
 
 	memset(&ac97, 0, sizeof(ac97));
 	ac97.private_data = chip;
@@ -1721,6 +1721,10 @@
 	if ((err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97)) < 0)
 		return err;
 
+	/* to be sure */
+	snd_ac97_update_bits(chip->ac97, AC97_EXTENDED_STATUS,
+			     AC97_EA_VRA|AC97_EA_VRM, 0);
+
 	for (idx = 0; idx < ARRAY_SIZE(snd_ymfpci_controls); idx++) {
 		if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_ymfpci_controls[idx], chip))) < 0)
 			return err;
@@ -2065,8 +2069,7 @@
 #endif
 
 #ifdef CONFIG_PM
-	if (chip->saved_regs)
-		vfree(chip->saved_regs);
+	vfree(chip->saved_regs);
 #endif
 	if (chip->mpu_res) {
 		release_resource(chip->mpu_res);
@@ -2155,7 +2158,6 @@
 	snd_ymfpci_writel(chip, YDSXGR_NATIVEDACOUTVOL, 0);
 	snd_ymfpci_disable_dsp(chip);
 	pci_disable_device(chip->pci);
-	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
 	return 0;
 }
 
@@ -2183,7 +2185,6 @@
 		chip->active_bank = snd_ymfpci_readl(chip, YDSXGR_CTRLSELECT);
 		spin_unlock_irq(&chip->reg_lock);
 	}
-	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
 	return 0;
 }
 #endif /* CONFIG_PM */
@@ -2265,12 +2266,12 @@
 	snd_card_set_pm_callback(card, snd_ymfpci_suspend, snd_ymfpci_resume, chip);
 #endif
 
-	snd_ymfpci_proc_init(card, chip);
-
 	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
 		snd_ymfpci_free(chip);
 		return err;
 	}
+
+	snd_ymfpci_proc_init(card, chip);
 
 	snd_card_set_dev(card, &pci->dev);
 
diff -Nru a/sound/pcmcia/pdaudiocf/pdaudiocf.c b/sound/pcmcia/pdaudiocf/pdaudiocf.c
--- a/sound/pcmcia/pdaudiocf/pdaudiocf.c	2005-03-01 23:38:54 -08:00
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf.c	2005-03-01 23:38:54 -08:00
@@ -42,8 +42,6 @@
 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 switches */
-static unsigned int irq_mask = 0xffff;
-static int irq_list[4] = { -1 };
 
 module_param_array(index, int, NULL, 0444);
 MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard.");
@@ -51,11 +49,6 @@
 MODULE_PARM_DESC(id, "ID string for " CARD_NAME " soundcard.");
 module_param_array(enable, bool, NULL, 0444);
 MODULE_PARM_DESC(enable, "Enable " CARD_NAME " soundcard.");
-module_param(irq_mask, int, 0444);
-MODULE_PARM_DESC(irq_mask, "IRQ bitmask for " CARD_NAME " soundcard.");
-module_param_array(irq_list, int, NULL, 0444);
-MODULE_PARM_DESC(irq_list, "List of Available interrupts for " CARD_NAME " soundcard.");
- 
 
 /*
  */
@@ -164,12 +157,7 @@
 	link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT | IRQ_FORCED_PULSE;
 	// link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
 
-	link->irq.IRQInfo1 = IRQ_INFO2_VALID /* | IRQ_LEVEL_ID */;
-	if (irq_list[0] == -1)
-		link->irq.IRQInfo2 = irq_mask;
-	else
-		for (i = 0; i < 4; i++)
-			link->irq.IRQInfo2 |= 1 << irq_list[i];
+	link->irq.IRQInfo1 = 0 /* | IRQ_LEVEL_ID */;
 	link->irq.Handler = pdacf_interrupt;
 	link->irq.Instance = pdacf;
 	link->conf.Attributes = CONF_ENABLE_IRQ;
@@ -183,7 +171,6 @@
 
 	/* Register with Card Services */
 	client_reg.dev_info = &dev_info;
-	client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
 	client_reg.EventMask = 
 		CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL
 #ifdef CONFIG_PM
@@ -274,15 +261,6 @@
 }
 
 /*
- * snd_pdacf_detach_all - detach all instances linked to the hw
- */
-static void snd_pdacf_detach_all(void)
-{
-	while (dev_list != NULL)
-		snd_pdacf_detach(dev_list);
-}
-
-/*
  * configuration callback
  */
 
@@ -413,7 +391,7 @@
 static void __exit exit_pdacf(void)
 {
 	pcmcia_unregister_driver(&pdacf_cs_driver);
-	snd_pdacf_detach_all();
+	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_pdacf);
diff -Nru a/sound/pcmcia/pdaudiocf/pdaudiocf.h b/sound/pcmcia/pdaudiocf/pdaudiocf.h
--- a/sound/pcmcia/pdaudiocf/pdaudiocf.h	2005-03-01 23:38:44 -08:00
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf.h	2005-03-01 23:38:44 -08:00
@@ -130,8 +130,6 @@
 	return inw(chip->port + reg);
 }
 
-unsigned char pdacf_ak4117_read(void *private_data, unsigned char reg);
-void pdacf_ak4117_write(void *private_data, unsigned char reg, unsigned char val);
 pdacf_t *snd_pdacf_create(snd_card_t *card);
 int snd_pdacf_ak4117_create(pdacf_t *pdacf);
 void snd_pdacf_powerdown(pdacf_t *chip);
diff -Nru a/sound/pcmcia/pdaudiocf/pdaudiocf_core.c b/sound/pcmcia/pdaudiocf/pdaudiocf_core.c
--- a/sound/pcmcia/pdaudiocf/pdaudiocf_core.c	2005-03-01 23:38:54 -08:00
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf_core.c	2005-03-01 23:38:54 -08:00
@@ -28,7 +28,7 @@
 /*
  *
  */
-unsigned char pdacf_ak4117_read(void *private_data, unsigned char reg)
+static unsigned char pdacf_ak4117_read(void *private_data, unsigned char reg)
 {
 	pdacf_t *chip = private_data;
 	unsigned long timeout;
@@ -60,7 +60,7 @@
 	return res;
 }
 
-void pdacf_ak4117_write(void *private_data, unsigned char reg, unsigned char val)
+static void pdacf_ak4117_write(void *private_data, unsigned char reg, unsigned char val)
 {
 	pdacf_t *chip = private_data;
 	unsigned long timeout;
@@ -267,7 +267,6 @@
 	outw(val, chip->port + PDAUDIOCF_REG_IER);
 	chip->chip_status |= PDAUDIOCF_STAT_IS_SUSPENDED;	/* ignore interrupts from now */
 	snd_pdacf_powerdown(chip);
-	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
 	return 0;
 }
 
@@ -287,7 +286,6 @@
 	       (snd_ak4117_external_rate(chip->ak4117) <= 0 || !check_signal(chip)))
 		mdelay(1);
 	chip->chip_status &= ~PDAUDIOCF_STAT_IS_SUSPENDED;
-	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
 	return 0;
 }
 #endif
diff -Nru a/sound/pcmcia/vx/vx_entry.c b/sound/pcmcia/vx/vx_entry.c
--- a/sound/pcmcia/vx/vx_entry.c	2005-03-01 23:38:51 -08:00
+++ b/sound/pcmcia/vx/vx_entry.c	2005-03-01 23:38:51 -08:00
@@ -68,7 +68,10 @@
 	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;
 }
@@ -120,6 +123,19 @@
 	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);
@@ -141,12 +157,7 @@
 	link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
 	// link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
 
-	link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
-	if (hw->irq_list[0] == -1)
-		link->irq.IRQInfo2 = *hw->irq_mask_p;
-	else
-		for (i = 0; i < 4; i++)
-			link->irq.IRQInfo2 |= 1 << hw->irq_list[i];
+	link->irq.IRQInfo1 = IRQ_LEVEL_ID;
 	link->irq.Handler = &snd_vx_irq_handler;
 	link->irq.Instance = chip;
 
@@ -156,13 +167,9 @@
 	link->conf.ConfigIndex = 1;
 	link->conf.Present = PRESENT_OPTION;
 
-	/* Chain drivers */
-	link->next = hw->dev_list;
-	hw->dev_list = link;
-
 	/* Register with Card Services */
+	memset(&client_reg, 0, sizeof(client_reg));
 	client_reg.dev_info = hw->dev_info;
-	client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
 	client_reg.EventMask = 
 		CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL
 #ifdef CONFIG_PM
@@ -177,10 +184,16 @@
 	ret = pcmcia_register_client(&link->handle, &client_reg);
 	if (ret != CS_SUCCESS) {
 		cs_error(link->handle, RegisterClient, ret);
-		snd_vxpocket_detach(hw, link);
+		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;
 }
 
@@ -208,12 +221,9 @@
 	sprintf(card->longname, "%s at 0x%x, irq %i",
 		card->shortname, port, irq);
 
-	if ((err = snd_vx_hwdep_new(chip)) < 0)
-		return err;
-
 	chip->irq = irq;
 
-	if ((err = snd_card_register(chip->card)) < 0)
+	if ((err = snd_vx_setup_firmware(chip)) < 0)
 		return err;
 
 	return 0;
@@ -226,7 +236,12 @@
  */
 void snd_vxpocket_detach(struct snd_vxp_entry *hw, dev_link_t *link)
 {
-	vx_core_t *chip = link->priv;
+	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 */
@@ -234,10 +249,10 @@
 		dev_link_t **linkp;
 		/* Locate device structure */
 		for (linkp = &hw->dev_list; *linkp; linkp = &(*linkp)->next)
-			if (*linkp == link)
+			if (*linkp == link) {
+				*linkp = link->next;
 				break;
-		if (*linkp)
-			*linkp = link->next;
+			}
 	}
 	chip->chip_status |= VX_STAT_IS_STALE; /* to be sure */
 	snd_card_disconnect(chip->card);
@@ -245,15 +260,6 @@
 }
 
 /*
- * snd_vxpocket_detach_all - detach all instances linked to the hw
- */
-void snd_vxpocket_detach_all(struct snd_vxp_entry *hw)
-{
-	while (hw->dev_list != NULL)
-		snd_vxpocket_detach(hw, hw->dev_list);
-}
-
-/*
  * configuration callback
  */
 
@@ -266,13 +272,16 @@
 	vx_core_t *chip = link->priv;
 	struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip;
 	tuple_t tuple;
-	cisparse_t parse;
-	config_info_t conf;
+	cisparse_t *parse = NULL;
 	u_short buf[32];
 	int last_fn, last_ret;
 
 	snd_printdd(KERN_DEBUG "vxpocket_config called\n");
-	tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+	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);
@@ -280,12 +289,9 @@
 	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.ConfigIndex = 1;
-
-	CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &conf));
-	link->conf.Vcc = conf.Vcc;
+	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;
@@ -299,6 +305,7 @@
 
 	link->dev = &vxp->node;
 	link->state &= ~DEV_CONFIG_PENDING;
+	kfree(parse);
 	return;
 
 cs_failed:
@@ -307,6 +314,8 @@
 	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);
 }
 
 
@@ -328,16 +337,16 @@
 		break;
 	case CS_EVENT_CARD_INSERTION:
 		snd_printdd(KERN_DEBUG "CARD_INSERTION..\n");
-		link->state |= DEV_PRESENT;
+		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) {
+		if (chip && chip->card->pm_suspend) {
 			snd_printdd(KERN_DEBUG "snd_vx_suspend calling\n");
-			snd_vx_suspend(chip);
+			chip->card->pm_suspend(chip->card, 0);
 		}
 		/* Fall through... */
 	case CS_EVENT_RESET_PHYSICAL:
@@ -355,9 +364,9 @@
 			//struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip;
 			snd_printdd(KERN_DEBUG "requestconfig...\n");
 			pcmcia_request_configuration(link->handle, &link->conf);
-			if (chip) {
+			if (chip && chip->card->pm_resume) {
 				snd_printdd(KERN_DEBUG "calling snd_vx_resume\n");
-				snd_vx_resume(chip);
+				chip->card->pm_resume(chip->card, 0);
 			}
 		}
 		snd_printdd(KERN_DEBUG "resume done!\n");
@@ -373,4 +382,3 @@
 EXPORT_SYMBOL(snd_vxpocket_ops);
 EXPORT_SYMBOL(snd_vxpocket_attach);
 EXPORT_SYMBOL(snd_vxpocket_detach);
-EXPORT_SYMBOL(snd_vxpocket_detach_all);
diff -Nru a/sound/pcmcia/vx/vxp_ops.c b/sound/pcmcia/vx/vxp_ops.c
--- a/sound/pcmcia/vx/vxp_ops.c	2005-03-01 23:38:53 -08:00
+++ b/sound/pcmcia/vx/vxp_ops.c	2005-03-01 23:38:53 -08:00
@@ -22,6 +22,7 @@
 
 #include <sound/driver.h>
 #include <linux/delay.h>
+#include <linux/firmware.h>
 #include <sound/core.h>
 #include <asm/io.h>
 #include "vxpocket.h"
@@ -144,13 +145,13 @@
  * vx_load_xilinx_binary - load the xilinx binary image
  * the binary image is the binary array converted from the bitstream file.
  */
-static int vxp_load_xilinx_binary(vx_core_t *_chip, const snd_hwdep_dsp_image_t *xilinx)
+static int vxp_load_xilinx_binary(vx_core_t *_chip, const struct firmware *fw)
 {
 	struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip;
 	unsigned int i;
 	int c;
 	int regCSUER, regRUER;
-	unsigned char __user *image;
+	unsigned char *image;
 	unsigned char data;
 
 	/* Switch to programmation mode */
@@ -171,9 +172,9 @@
 
 	/* set HF1 for loading xilinx binary */
 	vx_outb(chip, ICR, ICR_HF1);
-	image = xilinx->image;
-	for (i = 0; i < xilinx->length; i++, image++) {
-		__get_user(data, image);
+	image = fw->data;
+	for (i = 0; i < fw->size; i++, image++) {
+		data = *image;
 		if (vx_wait_isr_bit(_chip, ISR_TX_EMPTY) < 0)
 			goto _error;
 		vx_outb(chip, TXL, data);
@@ -200,7 +201,7 @@
 	c |= (int)vx_inb(chip, RXM) << 8;
 	c |= vx_inb(chip, RXL);
 
-	snd_printdd(KERN_DEBUG "xilinx: dsp size received 0x%x, orig 0x%x\n", c, xilinx->length);
+	snd_printdd(KERN_DEBUG "xilinx: dsp size received 0x%x, orig 0x%x\n", c, fw->size);
 
 	vx_outb(chip, ICR, ICR_HF0);
 
@@ -242,30 +243,27 @@
 /*
  * vxp_load_dsp - load_dsp callback
  */
-static int vxp_load_dsp(vx_core_t *vx, const snd_hwdep_dsp_image_t *dsp)
+static int vxp_load_dsp(vx_core_t *vx, int index, const struct firmware *fw)
 {
 	int err;
 
-	if (*dsp->name)
-		snd_printdd("loading dsp [%d] %s, size = %d\n", dsp->index, dsp->name, dsp->length);
-
-	switch (dsp->index) {
+	switch (index) {
 	case 0:
 		/* xilinx boot */
 		if ((err = vx_check_magic(vx)) < 0)
 			return err;
-		if ((err = snd_vx_load_boot_image(vx, dsp)) < 0)
+		if ((err = snd_vx_load_boot_image(vx, fw)) < 0)
 			return err;
 		return 0;
 	case 1:
 		/* xilinx image */
-		return vxp_load_xilinx_binary(vx, dsp);
+		return vxp_load_xilinx_binary(vx, fw);
 	case 2:
 		/* DSP boot */
-		return snd_vx_dsp_boot(vx, dsp);
+		return snd_vx_dsp_boot(vx, fw);
 	case 3:
 		/* DSP image */
-		return snd_vx_dsp_load(vx, dsp);
+		return snd_vx_dsp_load(vx, fw);
 	default:
 		snd_BUG();
 		return -EINVAL;
diff -Nru a/sound/pcmcia/vx/vxpocket.c b/sound/pcmcia/vx/vxpocket.c
--- a/sound/pcmcia/vx/vxpocket.c	2005-03-01 23:38:53 -08:00
+++ b/sound/pcmcia/vx/vxpocket.c	2005-03-01 23:38:53 -08:00
@@ -55,8 +55,6 @@
 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 switches */
-static unsigned int irq_mask = 0xffff;
-static int irq_list[4] = { -1 };
 static int ibl[SNDRV_CARDS];
 
 module_param_array(index, int, NULL, 0444);
@@ -65,10 +63,6 @@
 MODULE_PARM_DESC(id, "ID string for " CARD_NAME " soundcard.");
 module_param_array(enable, bool, NULL, 0444);
 MODULE_PARM_DESC(enable, "Enable " CARD_NAME " soundcard.");
-module_param(irq_mask, int, 0444);
-MODULE_PARM_DESC(irq_mask, "IRQ bitmask for " CARD_NAME " soundcard.");
-module_param_array(irq_list, int, NULL, 0444);
-MODULE_PARM_DESC(irq_list, "List of Available interrupts for " CARD_NAME " soundcard.");
 module_param_array(ibl, int, NULL, 0444);
 MODULE_PARM_DESC(ibl, "Capture IBL size for " CARD_NAME " soundcard.");
  
@@ -123,8 +117,6 @@
 	.index_table = index,
 	.id_table = id,
 	.enable_table = enable,
-	.irq_mask_p = &irq_mask,
-	.irq_list = irq_list,
 	.ibl = ibl,
 
 	/* h/w config */
@@ -165,7 +157,7 @@
 static void __exit exit_vxpocket(void)
 {
 	pcmcia_unregister_driver(&vxp_cs_driver);
-	snd_vxpocket_detach_all(&hw_entry);
+	BUG_ON(hw_entry.dev_list != NULL);
 }
 
 module_init(init_vxpocket);
diff -Nru a/sound/pcmcia/vx/vxpocket.h b/sound/pcmcia/vx/vxpocket.h
--- a/sound/pcmcia/vx/vxpocket.h	2005-03-01 23:38:54 -08:00
+++ b/sound/pcmcia/vx/vxpocket.h	2005-03-01 23:38:54 -08:00
@@ -35,8 +35,6 @@
 	int *index_table;
 	char **id_table;
 	int *enable_table;
-	unsigned int *irq_mask_p;
-	int *irq_list;
 	int *ibl;
 
 	/* h/w config */
@@ -77,7 +75,6 @@
  */
 dev_link_t *snd_vxpocket_attach(struct snd_vxp_entry *hw);
 void snd_vxpocket_detach(struct snd_vxp_entry *hw, dev_link_t *link);
-void snd_vxpocket_detach_all(struct snd_vxp_entry *hw);
 
 int vxp_add_mic_controls(vx_core_t *chip);
 
diff -Nru a/sound/ppc/pmac.c b/sound/ppc/pmac.c
--- a/sound/ppc/pmac.c	2005-03-01 23:39:18 -08:00
+++ b/sound/ppc/pmac.c	2005-03-01 23:39:18 -08:00
@@ -71,7 +71,7 @@
 
 static void snd_pmac_dbdma_free(pmac_dbdma_t *rec)
 {
-	if (rec && rec->space)
+	if (rec)
 		kfree(rec->space);
 }
 
@@ -318,7 +318,8 @@
 	stat = ld_le16(&cp->xfer_status);
 	if (stat & (ACTIVE|DEAD)) {
 		count = in_le16(&cp->res_count);
-		count = rec->period_size - count;
+		if (count)
+			count = rec->period_size - count;
 	}
 #endif
 	count += rec->cur_period * rec->period_size;
@@ -425,10 +426,10 @@
 	.rate_max =		44100,
 	.channels_min =		2,
 	.channels_max =		2,
-	.buffer_bytes_max =	32768,
+	.buffer_bytes_max =	131072,
 	.period_bytes_min =	256,
 	.period_bytes_max =	16384,
-	.periods_min =		1,
+	.periods_min =		3,
 	.periods_max =		PMAC_MAX_FRAGS,
 };
 
@@ -444,10 +445,10 @@
 	.rate_max =		44100,
 	.channels_min =		2,
 	.channels_max =		2,
-	.buffer_bytes_max =	32768,
+	.buffer_bytes_max =	131072,
 	.period_bytes_min =	256,
 	.period_bytes_max =	16384,
-	.periods_min =		1,
+	.periods_min =		3,
 	.periods_max =		PMAC_MAX_FRAGS,
 };
 
@@ -550,6 +551,8 @@
 	if (chip->can_duplex)
 		snd_pcm_set_sync(subs);
 
+	/* constraints to fix choppy sound */
+	snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
 	return 0;
 }
 
@@ -1248,7 +1251,6 @@
 	if (chip->rx_irq >= 0)
 		disable_irq(chip->rx_irq);
 	snd_pmac_sound_feature(chip, 0);
-	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
 	return 0;
 }
 
@@ -1275,7 +1277,6 @@
 	if (chip->rx_irq >= 0)
 		enable_irq(chip->rx_irq);
 
-	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
 	return 0;
 }
 
diff -Nru a/sound/sound_core.c b/sound/sound_core.c
--- a/sound/sound_core.c	2005-03-01 23:39:17 -08:00
+++ b/sound/sound_core.c	2005-03-01 23:39:17 -08:00
@@ -146,7 +146,7 @@
  *	This lock guards the sound loader list.
  */
 
-static spinlock_t sound_loader_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(sound_loader_lock);
 
 /*
  *	Allocate the controlling structure and add it to the sound driver
diff -Nru a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c
--- a/sound/sparc/cs4231.c	2005-03-01 23:38:51 -08:00
+++ b/sound/sparc/cs4231.c	2005-03-01 23:38:51 -08:00
@@ -390,7 +390,7 @@
  *  Basic I/O functions
  */
 
-void snd_cs4231_outm(cs4231_t *chip, unsigned char reg,
+static void snd_cs4231_outm(cs4231_t *chip, unsigned char reg,
 		     unsigned char mask, unsigned char value)
 {
 	int timeout;
@@ -473,9 +473,9 @@
 	return ret;
 }
 
-#ifdef CONFIG_SND_DEBUG
+#if 0
 
-void snd_cs4231_debug(cs4231_t *chip)
+static void snd_cs4231_debug(cs4231_t *chip)
 {
 	printk("CS4231 REGS:      INDEX = 0x%02x  ",
 	       __cs4231_readb(chip, CS4231P(chip, REGSEL)));
@@ -560,7 +560,6 @@
 {
 	unsigned long flags;
 	int timeout;
-	signed long time;
 
 	spin_lock_irqsave(&chip->lock, flags);
 	snd_cs4231_busy_wait(chip);
@@ -594,29 +593,29 @@
 #if 0
 	printk("(2) timeout = %i, jiffies = %li\n", timeout, jiffies);
 #endif
-	time = HZ / 4;
+	/* in 10ms increments, check condition, up to 250ms */
+	timeout = 25;
 	while (snd_cs4231_in(chip, CS4231_TEST_INIT) & CS4231_CALIB_IN_PROGRESS) {
 		spin_unlock_irqrestore(&chip->lock, flags);
-		if (time <= 0) {
+		if (--timeout < 0) {
 			snd_printk("mce_down - auto calibration time out (2)\n");
 			return;
 		}
-		set_current_state(TASK_INTERRUPTIBLE);
-		time = schedule_timeout(time);
+		msleep(10);
 		spin_lock_irqsave(&chip->lock, flags);
 	}
 #if 0
 	printk("(3) jiffies = %li\n", jiffies);
 #endif
-	time = HZ / 10;
+	/* in 10ms increments, check condition, up to 100ms */
+	timeout = 10;
 	while (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT) {
 		spin_unlock_irqrestore(&chip->lock, flags);
-		if (time <= 0) {
+		if (--timeout < 0) {
 			snd_printk("mce_down - auto calibration time out (3)\n");
 			return;
 		}
-		set_current_state(TASK_INTERRUPTIBLE);		
-		time = schedule_timeout(time);
+		msleep(10);
 		spin_lock_irqsave(&chip->lock, flags);
 	}
 	spin_unlock_irqrestore(&chip->lock, flags);
diff -Nru a/sound/synth/emux/emux.c b/sound/synth/emux/emux.c
--- a/sound/synth/emux/emux.c	2005-03-01 23:38:57 -08:00
+++ b/sound/synth/emux/emux.c	2005-03-01 23:38:57 -08:00
@@ -137,12 +137,8 @@
 	if (emu->sflist)
 		snd_sf_free(emu->sflist);
 
-	if (emu->voices)
-		kfree(emu->voices);
-
-	if (emu->name)
-		kfree(emu->name);
-
+	kfree(emu->voices);
+	kfree(emu->name);
 	kfree(emu);
 	return 0;
 }
diff -Nru a/sound/synth/emux/emux_seq.c b/sound/synth/emux/emux_seq.c
--- a/sound/synth/emux/emux_seq.c	2005-03-01 23:39:18 -08:00
+++ b/sound/synth/emux/emux_seq.c	2005-03-01 23:39:18 -08:00
@@ -197,8 +197,7 @@
 #ifdef SNDRV_EMUX_USE_RAW_EFFECT
 		snd_emux_delete_effect(p);
 #endif
-		if (p->chset.channels)
-			kfree(p->chset.channels);
+		kfree(p->chset.channels);
 		kfree(p);
 	}
 }
diff -Nru a/sound/synth/emux/emux_synth.c b/sound/synth/emux/emux_synth.c
--- a/sound/synth/emux/emux_synth.c	2005-03-01 23:38:56 -08:00
+++ b/sound/synth/emux/emux_synth.c	2005-03-01 23:38:56 -08:00
@@ -363,16 +363,6 @@
 
 
 /*
- * for Emu10k1 - release at least 1 voice currently using
- */
-int
-snd_emux_release_voice(snd_emux_t *emu)
-{
-	return 0;
-}
-
-
-/*
  * terminate note - if free flag is true, free the terminated voice
  */
 static void
diff -Nru a/sound/synth/emux/soundfont.c b/sound/synth/emux/soundfont.c
--- a/sound/synth/emux/soundfont.c	2005-03-01 23:39:08 -08:00
+++ b/sound/synth/emux/soundfont.c	2005-03-01 23:39:08 -08:00
@@ -1460,11 +1460,3 @@
 	return 0;
 }
 
-/*
- * Return the used memory size (in words)
- */
-int
-snd_soundfont_mem_used(snd_sf_list_t *sflist)
-{
-	return sflist->mem_used;
-}
diff -Nru a/sound/usb/Kconfig b/sound/usb/Kconfig
--- a/sound/usb/Kconfig	2005-03-01 23:39:08 -08:00
+++ b/sound/usb/Kconfig	2005-03-01 23:39:08 -08:00
@@ -17,7 +17,7 @@
 
 config SND_USB_USX2Y
 	tristate "Tascam US-122, US-224 and US-428 USB driver"
-	depends on SND && USB
+	depends on SND && USB && (X86 || PPC || ALPHA)
 	select SND_HWDEP
 	select SND_RAWMIDI
 	select SND_PCM
diff -Nru a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
--- a/sound/usb/usbaudio.c	2005-03-01 23:39:08 -08:00
+++ b/sound/usb/usbaudio.c	2005-03-01 23:39:08 -08:00
@@ -725,7 +725,7 @@
 	subs->running = 0;
 
 	if (!force && subs->stream->chip->shutdown) /* to be sure... */
-		return 0;
+		return -EBADFD;
 
 	async = !can_sleep && async_unlink;
 
@@ -770,6 +770,9 @@
 	unsigned int i;
 	int err;
 
+	if (subs->stream->chip->shutdown)
+		return -EBADFD;
+
 	for (i = 0; i < subs->nurbs; i++) {
 		snd_assert(subs->dataurb[i].urb, return -EINVAL);
 		if (subs->ops.prepare(subs, runtime, subs->dataurb[i].urb) < 0) {
@@ -2063,8 +2066,7 @@
 		return; /* not initialized */
 	list_for_each_safe(p, n, &subs->fmt_list) {
 		struct audioformat *fp = list_entry(p, struct audioformat, list);
-		if (fp->rate_table)
-			kfree(fp->rate_table);
+		kfree(fp->rate_table);
 		kfree(fp);
 	}
 }
@@ -2176,13 +2178,13 @@
 static int is_big_endian_format(struct usb_device *dev, struct audioformat *fp)
 {
 	/* M-Audio */
-	if (dev->descriptor.idVendor == 0x0763) {
+	if (le16_to_cpu(dev->descriptor.idVendor) == 0x0763) {
 		/* Quattro: captured data only */
-		if (dev->descriptor.idProduct == 0x2001 &&
+		if (le16_to_cpu(dev->descriptor.idProduct) == 0x2001 &&
 		    fp->endpoint & USB_DIR_IN)
 			return 1;
 		/* Audiophile USB */
-		if (dev->descriptor.idProduct == 0x2003)
+		if (le16_to_cpu(dev->descriptor.idProduct) == 0x2003)
 			return 1;
 	}
 	return 0;
@@ -2246,7 +2248,8 @@
 		break;
 	case USB_AUDIO_FORMAT_PCM8:
 		/* Dallas DS4201 workaround */
-		if (dev->descriptor.idVendor == 0x04fa && dev->descriptor.idProduct == 0x4201)
+		if (le16_to_cpu(dev->descriptor.idVendor) == 0x04fa &&
+		    le16_to_cpu(dev->descriptor.idProduct) == 0x4201)
 			pcm_format = SNDRV_PCM_FORMAT_S8;
 		else
 			pcm_format = SNDRV_PCM_FORMAT_U8;
@@ -2414,7 +2417,8 @@
 	/* extigy apparently supports sample rates other than 48k
 	 * but not in ordinary way.  so we enable only 48k atm.
 	 */
-	if (dev->descriptor.idVendor == 0x041e && dev->descriptor.idProduct == 0x3000) {
+	if (le16_to_cpu(dev->descriptor.idVendor) == 0x041e && 
+	    le16_to_cpu(dev->descriptor.idProduct) == 0x3000) {
 		if (fmt[3] == USB_FORMAT_TYPE_I &&
 		    stream == SNDRV_PCM_STREAM_PLAYBACK &&
 		    fp->rates != SNDRV_PCM_RATE_48000)
@@ -2448,7 +2452,7 @@
 		    (altsd->bInterfaceSubClass != USB_SUBCLASS_AUDIO_STREAMING &&
 		     altsd->bInterfaceSubClass != USB_SUBCLASS_VENDOR_SPEC) ||
 		    altsd->bNumEndpoints < 1 ||
-		    get_endpoint(alts, 0)->wMaxPacketSize == 0)
+		    le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize) == 0)
 			continue;
 		/* must be isochronous */
 		if ((get_endpoint(alts, 0)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) !=
@@ -2511,14 +2515,14 @@
 		fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress;
 		fp->ep_attr = get_endpoint(alts, 0)->bmAttributes;
 		/* FIXME: decode wMaxPacketSize of high bandwith endpoints */
-		fp->maxpacksize = get_endpoint(alts, 0)->wMaxPacketSize;
+		fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
 		fp->attributes = csep[3];
 
 		/* some quirks for attributes here */
 
 		/* workaround for AudioTrak Optoplay */
-		if (dev->descriptor.idVendor == 0x0a92 &&
-		    dev->descriptor.idProduct == 0x0053) {
+		if (le16_to_cpu(dev->descriptor.idVendor) == 0x0a92 &&
+		    le16_to_cpu(dev->descriptor.idProduct) == 0x0053) {
 			/* Optoplay sets the sample rate attribute although
 			 * it seems not supporting it in fact.
 			 */
@@ -2526,8 +2530,8 @@
 		}
 
 		/* workaround for M-Audio Audiophile USB */
-		if (dev->descriptor.idVendor == 0x0763 &&
-		    dev->descriptor.idProduct == 0x2003) {
+		if (le16_to_cpu(dev->descriptor.idVendor) == 0x0763 &&
+		    le16_to_cpu(dev->descriptor.idProduct) == 0x2003) {
 			/* doesn't set the sample rate attribute, but supports it */
 			fp->attributes |= EP_CS_ATTR_SAMPLE_RATE;
 		}
@@ -2536,11 +2540,11 @@
 		 * plantronics headset and Griffin iMic have set adaptive-in
 		 * although it's really not...
 		 */
-		if ((dev->descriptor.idVendor == 0x047f &&
-		     dev->descriptor.idProduct == 0x0ca1) ||
+		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) */
-		    (dev->descriptor.idVendor == 0x077d &&
-		     dev->descriptor.idProduct == 0x07af)) {
+		    (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;
@@ -2550,8 +2554,7 @@
 
 		/* ok, let's parse further... */
 		if (parse_audio_format(dev, fp, format, fmt, stream) < 0) {
-			if (fp->rate_table)
-				kfree(fp->rate_table);
+			kfree(fp->rate_table);
 			kfree(fp);
 			continue;
 		}
@@ -2559,8 +2562,7 @@
 		snd_printdd(KERN_INFO "%d:%u:%d: add audio endpoint 0x%x\n", dev->devnum, iface_no, i, fp->endpoint);
 		err = add_audio_endpoint(chip, stream, fp);
 		if (err < 0) {
-			if (fp->rate_table)
-				kfree(fp->rate_table);
+			kfree(fp->rate_table);
 			kfree(fp);
 			return err;
 		}
@@ -2693,15 +2695,13 @@
 	err = add_audio_endpoint(chip, stream, fp);
 	if (err < 0) {
 		kfree(fp);
-		if (rate_table)
-			kfree(rate_table);
+		kfree(rate_table);
 		return err;
 	}
 	if (fp->iface != get_iface_desc(&iface->altsetting[0])->bInterfaceNumber ||
 	    fp->altset_idx >= iface->num_altsetting) {
 		kfree(fp);
-		if (rate_table)
-			kfree(rate_table);
+		kfree(rate_table);
 		return -EINVAL;
 	}
 	alts = &iface->altsetting[fp->altset_idx];
@@ -2788,7 +2788,7 @@
 			.type = QUIRK_MIDI_FIXED_ENDPOINT,
 			.data = &ua25_ep
 		};
-		if (chip->dev->descriptor.idProduct == 0x002b)
+		if (le16_to_cpu(chip->dev->descriptor.idProduct) == 0x002b)
 			return snd_usb_create_midi_interface(chip, iface,
 							     &ua700_quirk);
 		else
@@ -2807,7 +2807,7 @@
 	fp->iface = altsd->bInterfaceNumber;
 	fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress;
 	fp->ep_attr = get_endpoint(alts, 0)->bmAttributes;
-	fp->maxpacksize = get_endpoint(alts, 0)->wMaxPacketSize;
+	fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
 
 	switch (fp->maxpacksize) {
 	case 0x120:
@@ -2873,7 +2873,7 @@
 	fp->iface = altsd->bInterfaceNumber;
 	fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress;
 	fp->ep_attr = get_endpoint(alts, 0)->bmAttributes;
-	fp->maxpacksize = get_endpoint(alts, 0)->wMaxPacketSize;
+	fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
 	fp->rate_max = fp->rate_min = combine_triple(&alts->extra[8]);
 
 	stream = (fp->endpoint & USB_DIR_IN)
@@ -2931,8 +2931,8 @@
 	struct usb_host_config *config = dev->actconfig;
 	int err;
 
-	if (get_cfg_desc(config)->wTotalLength == EXTIGY_FIRMWARE_SIZE_OLD ||
-	    get_cfg_desc(config)->wTotalLength == EXTIGY_FIRMWARE_SIZE_NEW) {
+	if (le16_to_cpu(get_cfg_desc(config)->wTotalLength) == EXTIGY_FIRMWARE_SIZE_OLD ||
+	    le16_to_cpu(get_cfg_desc(config)->wTotalLength) == EXTIGY_FIRMWARE_SIZE_NEW) {
 		snd_printdd("sending Extigy boot sequence...\n");
 		/* Send message to force it to reconnect with full interface. */
 		err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev,0),
@@ -2944,7 +2944,8 @@
 		if (err < 0) snd_printdd("error usb_get_descriptor: %d\n", err);
 		err = usb_reset_configuration(dev);
 		if (err < 0) snd_printdd("error usb_reset_configuration: %d\n", err);
-		snd_printdd("extigy_boot: new boot length = %d\n", get_cfg_desc(config)->wTotalLength);
+		snd_printdd("extigy_boot: new boot length = %d\n",
+			    le16_to_cpu(get_cfg_desc(config)->wTotalLength));
 		return -ENODEV; /* quit this anyway */
 	}
 	return 0;
@@ -3000,7 +3001,9 @@
 {
 	snd_usb_audio_t *chip = entry->private_data;
 	if (! chip->shutdown)
-		snd_iprintf(buffer, "%04x:%04x\n", chip->dev->descriptor.idVendor, chip->dev->descriptor.idProduct);
+		snd_iprintf(buffer, "%04x:%04x\n", 
+			    le16_to_cpu(chip->dev->descriptor.idVendor),
+			    le16_to_cpu(chip->dev->descriptor.idProduct));
 }
 
 static void snd_usb_audio_create_proc(snd_usb_audio_t *chip)
@@ -3081,7 +3084,8 @@
 
 	strcpy(card->driver, "USB-Audio");
 	sprintf(component, "USB%04x:%04x",
-		dev->descriptor.idVendor, dev->descriptor.idProduct);
+		le16_to_cpu(dev->descriptor.idVendor),
+		le16_to_cpu(dev->descriptor.idProduct));
 	snd_component_add(card, component);
 
 	/* retrieve the device string as shortname */
@@ -3093,7 +3097,8 @@
       			       card->shortname, sizeof(card->shortname)) <= 0) {
 			/* no name available from anywhere, so use ID */
 			sprintf(card->shortname, "USB Device %#04x:%#04x",
-				dev->descriptor.idVendor, dev->descriptor.idProduct);
+				le16_to_cpu(dev->descriptor.idVendor),
+				le16_to_cpu(dev->descriptor.idProduct));
 		}
 	}
 
@@ -3160,7 +3165,8 @@
 
 	/* SB Extigy needs special boot-up sequence */
 	/* if more models come, this will go to the quirk list. */
-	if (dev->descriptor.idVendor == 0x041e && dev->descriptor.idProduct == 0x3000) {
+	if (le16_to_cpu(dev->descriptor.idVendor) == 0x041e && 
+	    le16_to_cpu(dev->descriptor.idProduct) == 0x3000) {
 		if (snd_usb_extigy_boot_quirk(dev, intf) < 0)
 			goto __err_val;
 		config = dev->actconfig;
@@ -3194,8 +3200,8 @@
 		}
 		for (i = 0; i < SNDRV_CARDS; i++)
 			if (enable[i] && ! usb_chip[i] &&
-			    (vid[i] == -1 || vid[i] == dev->descriptor.idVendor) &&
-			    (pid[i] == -1 || pid[i] == dev->descriptor.idProduct)) {
+			    (vid[i] == -1 || vid[i] == le16_to_cpu(dev->descriptor.idVendor)) &&
+			    (pid[i] == -1 || pid[i] == le16_to_cpu(dev->descriptor.idProduct))) {
 				if (snd_usb_audio_create(dev, i, quirk, &chip) < 0) {
 					goto __error;
 				}
diff -Nru a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c
--- a/sound/usb/usbmidi.c	2005-03-01 23:39:10 -08:00
+++ b/sound/usb/usbmidi.c	2005-03-01 23:39:10 -08:00
@@ -59,7 +59,7 @@
 	__u8  bDescriptorType;
 	__u8  bDescriptorSubtype;
 	__u8  bcdMSC[2];
-	__u16 wTotalLength;
+	__le16 wTotalLength;
 } __attribute__ ((packed));
 
 struct usb_ms_endpoint_descriptor {
@@ -504,8 +504,7 @@
 static void snd_usbmidi_in_endpoint_delete(snd_usb_midi_in_endpoint_t* ep)
 {
 	if (ep->urb) {
-		if (ep->urb->transfer_buffer)
-			kfree(ep->urb->transfer_buffer);
+		kfree(ep->urb->transfer_buffer);
 		usb_free_urb(ep->urb);
 	}
 	kfree(ep);
@@ -521,7 +520,7 @@
 	struct usb_host_interface *hostif;
 	struct usb_interface_descriptor* intfd;
 
-	if (umidi->chip->dev->descriptor.idVendor != 0x0582)
+	if (le16_to_cpu(umidi->chip->dev->descriptor.idVendor) != 0x0582)
 		return NULL;
 	intf = umidi->iface;
 	if (!intf || intf->num_altsetting != 2)
@@ -632,8 +631,7 @@
 	if (ep->tasklet.func)
 		tasklet_kill(&ep->tasklet);
 	if (ep->urb) {
-		if (ep->urb->transfer_buffer)
-			kfree(ep->urb->transfer_buffer);
+		kfree(ep->urb->transfer_buffer);
 		usb_free_urb(ep->urb);
 	}
 	kfree(ep);
@@ -839,8 +837,8 @@
 
 	/* TODO: read port name from jack descriptor */
 	name_format = "%s MIDI %d";
-	vendor = umidi->chip->dev->descriptor.idVendor;
-	product = umidi->chip->dev->descriptor.idProduct;
+	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 &&
diff -Nru a/sound/usb/usbmixer.c b/sound/usb/usbmixer.c
--- a/sound/usb/usbmixer.c	2005-03-01 23:38:54 -08:00
+++ b/sound/usb/usbmixer.c	2005-03-01 23:38:54 -08:00
@@ -374,7 +374,7 @@
 static int check_matrix_bitmap(unsigned char *bmap, int ich, int och, int num_outs)
 {
 	int idx = ich * num_outs + och;
-	return bmap[-(idx >> 3)] & (0x80 >> (idx & 7));
+	return bmap[idx >> 3] & (0x80 >> (idx & 7));
 }
 
 
@@ -573,7 +573,7 @@
 static void usb_mixer_elem_free(snd_kcontrol_t *kctl)
 {
 	if (kctl->private_data) {
-		kfree((void *)kctl->private_data);
+		kfree(kctl->private_data);
 		kctl->private_data = NULL;
 	}
 }
@@ -931,14 +931,14 @@
  */
 
 static void build_mixer_unit_ctl(mixer_build_t *state, unsigned char *desc,
-				 int in_ch, int unitid)
+				 int in_pin, int in_ch, int unitid,
+				 usb_audio_term_t *iterm)
 {
 	usb_mixer_elem_info_t *cval;
-	unsigned int num_ins = desc[4];
-	unsigned int num_outs = desc[5 + num_ins];
+	unsigned int input_pins = desc[4];
+	unsigned int num_outs = desc[5 + input_pins];
 	unsigned int i, len;
 	snd_kcontrol_t *kctl;
-	usb_audio_term_t iterm;
 
 	if (check_ignored_ctl(state, unitid, 0))
 		return;
@@ -947,16 +947,13 @@
 	if (! cval)
 		return;
 
-	if (check_input_term(state, desc[5 + in_ch], &iterm) < 0)
-		return;
-
 	cval->chip = state->chip;
 	cval->ctrlif = state->ctrlif;
 	cval->id = unitid;
 	cval->control = in_ch + 1; /* based on 1 */
 	cval->val_type = USB_MIXER_S16;
 	for (i = 0; i < num_outs; i++) {
-		if (check_matrix_bitmap(desc + 9 + num_ins, in_ch, i, num_outs)) {
+		if (check_matrix_bitmap(desc + 9 + input_pins, in_ch, i, num_outs)) {
 			cval->cmask |= (1 << i);
 			cval->channels++;
 		}
@@ -975,9 +972,9 @@
 
 	len = check_mapped_name(state, unitid, 0, kctl->id.name, sizeof(kctl->id.name));
 	if (! len)
-		len = get_term_name(state, &iterm, kctl->id.name, sizeof(kctl->id.name), 0);
+		len = get_term_name(state, iterm, kctl->id.name, sizeof(kctl->id.name), 0);
 	if (! len)
-		len = sprintf(kctl->id.name, "Mixer Source %d", in_ch);
+		len = sprintf(kctl->id.name, "Mixer Source %d", in_ch + 1);
 	strlcat(kctl->id.name + len, " Volume", sizeof(kctl->id.name));
 
 	snd_printdd(KERN_INFO "[%d] MU [%s] ch = %d, val = %d/%d\n",
@@ -991,17 +988,44 @@
  */
 static int parse_audio_mixer_unit(mixer_build_t *state, int unitid, unsigned char *desc)
 {
-	int num_ins, num_outs;
-	int i, err;
-	if (desc[0] < 12 || ! (num_ins = desc[4]) || ! (num_outs = desc[5 + num_ins]))
+	usb_audio_term_t iterm;
+	int input_pins, num_ins, num_outs;
+	int pin, ich, err;
+
+	if (desc[0] < 11 || ! (input_pins = desc[4]) || ! (num_outs = desc[5 + input_pins])) {
+		snd_printk(KERN_ERR "invalid MIXER UNIT descriptor %d\n", unitid);
 		return -EINVAL;
+	}
+	/* no bmControls field (e.g. Maya44) -> ignore */
+	if (desc[0] <= 10 + input_pins) {
+		snd_printdd(KERN_INFO "MU %d has no bmControls field\n", unitid);
+		return 0;
+	}
 
-	for (i = 0; i < num_ins; i++) {
-		err = parse_audio_unit(state, desc[5 + i]);
+	num_ins = 0;
+	ich = 0;
+	for (pin = 0; pin < input_pins; pin++) {
+		err = parse_audio_unit(state, desc[5 + pin]);
+		if (err < 0)
+			return err;
+		err = check_input_term(state, desc[5 + pin], &iterm);
 		if (err < 0)
 			return err;
-		if (check_matrix_bitmap(desc + 9 + num_ins, i, 0, num_outs))
-			build_mixer_unit_ctl(state, desc, i, unitid);
+		num_ins += iterm.channels;
+		for (; ich < num_ins; ++ich) {
+			int och, ich_has_controls = 0;
+
+			for (och = 0; och < num_outs; ++och) {
+				if (check_matrix_bitmap(desc + 9 + input_pins,
+							ich, och, num_outs)) {
+					ich_has_controls = 1;
+					break;
+				}
+			}
+			if (ich_has_controls)
+				build_mixer_unit_ctl(state, desc, pin, ich,
+						     unitid, &iterm);
+		}
 	}
 	return 0;
 }
@@ -1490,12 +1514,12 @@
 	state.buffer = hostif->extra;
 	state.buflen = hostif->extralen;
 	state.ctrlif = ctrlif;
-	state.vendor = dev->idVendor;
-	state.product = dev->idProduct;
+	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 == dev->idVendor && map->product == dev->idProduct) {
+		if (map->vendor == le16_to_cpu(dev->idVendor) && map->product == le16_to_cpu(dev->idProduct)) {
 			state.map = map->map;
 			chip->ignore_ctl_error = map->ignore_ctl_error;
 			break;
diff -Nru a/sound/usb/usx2y/Makefile b/sound/usb/usx2y/Makefile
--- a/sound/usb/usx2y/Makefile	2005-03-01 23:38:57 -08:00
+++ b/sound/usb/usx2y/Makefile	2005-03-01 23:38:57 -08:00
@@ -1,3 +1,3 @@
-snd-usb-usx2y-objs := usbusx2y.o usbusx2yaudio.o usX2Yhwdep.o
+snd-usb-usx2y-objs := usbusx2y.o usX2Yhwdep.o usx2yhwdeppcm.o
 
 obj-$(CONFIG_SND_USB_USX2Y) += snd-usb-usx2y.o
diff -Nru a/sound/usb/usx2y/usX2Yhwdep.c b/sound/usb/usx2y/usX2Yhwdep.c
--- a/sound/usb/usx2y/usX2Yhwdep.c	2005-03-01 23:38:51 -08:00
+++ b/sound/usb/usx2y/usX2Yhwdep.c	2005-03-01 23:38:51 -08:00
@@ -31,6 +31,8 @@
 #include "usbusx2y.h"
 #include "usX2Yhwdep.h"
 
+int usX2Y_hwdep_pcm_new(snd_card_t* card);
+
 
 static struct page * snd_us428ctls_vm_nopage(struct vm_area_struct *area, unsigned long address, int *type)
 {
@@ -95,20 +97,14 @@
 {
 	unsigned int	mask = 0;
 	usX2Ydev_t	*us428 = (usX2Ydev_t*)hw->private_data;
-	static unsigned	LastN;
-
+	us428ctls_sharedmem_t *shm = us428->us428ctls_sharedmem;
 	if (us428->chip_status & USX2Y_STAT_CHIP_HUP)
 		return POLLHUP;
 
 	poll_wait(file, &us428->us428ctls_wait_queue_head, wait);
 
-	down(&us428->open_mutex);
-	if (us428->us428ctls_sharedmem
-	    && us428->us428ctls_sharedmem->CtlSnapShotLast != LastN) {
+	if (shm != NULL && shm->CtlSnapShotLast != shm->CtlSnapShotRed)
 		mask |= POLLIN;
-		LastN = us428->us428ctls_sharedmem->CtlSnapShotLast;
-	}
-	up(&us428->open_mutex);
 
 	return mask;
 }
@@ -133,7 +129,7 @@
 	};
 	int id = -1;
 
-	switch (((usX2Ydev_t*)hw->private_data)->chip.dev->descriptor.idProduct) {
+	switch (le16_to_cpu(((usX2Ydev_t*)hw->private_data)->chip.dev->descriptor.idProduct)) {
 	case USB_ID_US122:
 		id = USX2Y_TYPE_122;
 		break;
@@ -185,7 +181,7 @@
 	};
 	struct usb_device *dev = usX2Y(card)->chip.dev;
 	struct usb_interface *iface = usb_ifnum_to_if(dev, 0);
-	snd_usb_audio_quirk_t *quirk = dev->descriptor.idProduct == USB_ID_US428 ? &quirk_2 : &quirk_1;
+	snd_usb_audio_quirk_t *quirk = le16_to_cpu(dev->descriptor.idProduct) == USB_ID_US428 ? &quirk_2 : &quirk_1;
 
 	snd_printdd("usX2Y_create_usbmidi \n");
 	return snd_usb_create_midi_interface(&usX2Y(card)->chip, iface, quirk);
@@ -201,6 +197,8 @@
 			break;
 		}
 		if ((err = usX2Y_audio_create(card)) < 0) 
+			break;
+		if ((err = usX2Y_hwdep_pcm_new(card)) < 0)
 			break;
 		if ((err = snd_card_register(card)) < 0)
 			break;
diff -Nru a/sound/usb/usx2y/usbusx2y.c b/sound/usb/usx2y/usbusx2y.c
--- a/sound/usb/usx2y/usbusx2y.c	2005-03-01 23:38:52 -08:00
+++ b/sound/usb/usx2y/usbusx2y.c	2005-03-01 23:38:52 -08:00
@@ -1,6 +1,30 @@
 /*
- * usbus428.c - ALSA USB US-428 Driver
+ * usbusy2y.c - ALSA USB US-428 Driver
  *
+2004-12-14 Karsten Wiese
+	Version 0.8.7.1:
+	snd_pcm_open for rawusb pcm-devices now returns -EBUSY if called without rawusb's hwdep device being open.
+
+2004-12-02 Karsten Wiese
+	Version 0.8.7:
+	Use macro usb_maxpacket() for portability.
+
+2004-10-26 Karsten Wiese
+	Version 0.8.6:
+	wake_up() process waiting in usX2Y_urbs_start() on error.
+
+2004-10-21 Karsten Wiese
+	Version 0.8.5:
+	nrpacks is runtime or compiletime configurable now with tested values from 1 to 4.
+
+2004-10-03 Karsten Wiese
+	Version 0.8.2:
+	Avoid any possible racing while in prepare callback.
+
+2004-09-30 Karsten Wiese
+	Version 0.8.0:
+	Simplified things and made ohci work again.
+
 2004-09-20 Karsten Wiese
 	Version 0.7.3:
 	Use usb_kill_urb() instead of deprecated (kernel 2.6.9) usb_unlink_urb().
@@ -84,7 +108,7 @@
 	Version 0.0.2: midi works with snd-usb-midi, audio (only fullduplex now) with i.e. bristol.
 	The firmware has been sniffed from win2k us-428 driver 3.09.
 
- *   Copyright (c) 2002 Karsten Wiese
+ *   Copyright (c) 2002 - 2004 Karsten Wiese
  *
  *   This program is free software; you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License as published by
@@ -119,7 +143,7 @@
 
 
 MODULE_AUTHOR("Karsten Wiese <annabellesgarden@yahoo.de>");
-MODULE_DESCRIPTION("TASCAM "NAME_ALLCAPS" Version 0.7.3");
+MODULE_DESCRIPTION("TASCAM "NAME_ALLCAPS" Version 0.8.7.1");
 MODULE_LICENSE("GPL");
 MODULE_SUPPORTED_DEVICE("{{TASCAM(0x1604), "NAME_ALLCAPS"(0x8001)(0x8005)(0x8007) }}");
 
@@ -285,8 +309,7 @@
 			S->urb[i] = NULL;
 		}
 	}
-	if (S->buffer)
-		kfree(S->buffer);
+	kfree(S->buffer);
 }
 
 
@@ -325,13 +348,15 @@
 	card->private_free = snd_usX2Y_card_private_free;
 	usX2Y(card)->chip.dev = device;
 	usX2Y(card)->chip.card = card;
-	init_MUTEX (&usX2Y(card)->open_mutex);
+	init_waitqueue_head(&usX2Y(card)->prepare_wait_queue);
+	init_MUTEX (&usX2Y(card)->prepare_mutex);
 	INIT_LIST_HEAD(&usX2Y(card)->chip.midi_list);
 	strcpy(card->driver, "USB "NAME_ALLCAPS"");
 	sprintf(card->shortname, "TASCAM "NAME_ALLCAPS"");
 	sprintf(card->longname, "%s (%x:%x if %d at %03d/%03d)",
 		card->shortname, 
-		device->descriptor.idVendor, device->descriptor.idProduct,
+		le16_to_cpu(device->descriptor.idVendor),
+		le16_to_cpu(device->descriptor.idProduct),
 		0,//us428(card)->usbmidi.ifnum,
 		usX2Y(card)->chip.dev->bus->busnum, usX2Y(card)->chip.dev->devnum
 		);
@@ -344,10 +369,10 @@
 {
 	int		err;
 	snd_card_t*	card;
-	if (device->descriptor.idVendor != 0x1604 ||
-	    (device->descriptor.idProduct != USB_ID_US122 &&
-	     device->descriptor.idProduct != USB_ID_US224 &&
-	     device->descriptor.idProduct != USB_ID_US428) ||
+	if (le16_to_cpu(device->descriptor.idVendor) != 0x1604 ||
+	    (le16_to_cpu(device->descriptor.idProduct) != USB_ID_US122 &&
+	     le16_to_cpu(device->descriptor.idProduct) != USB_ID_US224 &&
+	     le16_to_cpu(device->descriptor.idProduct) != USB_ID_US428) ||
 	    !(card = usX2Y_create_card(device)))
 		return NULL;
 	if ((err = usX2Y_hwdep_new(card, device)) < 0  ||
@@ -389,8 +414,7 @@
 
 static void snd_usX2Y_card_private_free(snd_card_t *card)
 {
-	if (usX2Y(card)->In04Buf)
-		kfree(usX2Y(card)->In04Buf);
+	kfree(usX2Y(card)->In04Buf);
 	usb_free_urb(usX2Y(card)->In04urb);
 	if (usX2Y(card)->us428ctls_sharedmem)
 		snd_free_pages(usX2Y(card)->us428ctls_sharedmem, sizeof(*usX2Y(card)->us428ctls_sharedmem));
diff -Nru a/sound/usb/usx2y/usbusx2y.h b/sound/usb/usx2y/usbusx2y.h
--- a/sound/usb/usx2y/usbusx2y.h	2005-03-01 23:39:08 -08:00
+++ b/sound/usb/usx2y/usbusx2y.h	2005-03-01 23:39:08 -08:00
@@ -3,15 +3,8 @@
 #include "../usbaudio.h"
 #include "usbus428ctldefs.h" 
 
-#define NRURBS	        2	/* */
-#define NRPACKS		1	/* FIXME: Currently only 1 works.
-				   usb-frames/ms per urb: 1 and 2 are supported.
-				   setting to 2 will PERHAPS make it easier for slow machines.
-				   Jitter will be higher though.
-				   On my PIII 500Mhz Laptop setting to 1 is the only way to go 
-				   for PLAYING synths. i.e. Jack & Aeolus sound quit nicely 
-				   at 4 periods 64 frames. 
-				*/
+#define NRURBS	        2	
+
 
 #define URBS_AsyncSeq 10
 #define URB_DataLen_AsyncSeq 32
@@ -27,6 +20,7 @@
 } snd_usX2Y_urbSeq_t;
 
 typedef struct snd_usX2Y_substream snd_usX2Y_substream_t;
+#include "usx2yhwdeppcm.h"
 
 typedef struct {
 	snd_usb_audio_t 	chip;
@@ -40,13 +34,42 @@
 	snd_usX2Y_AsyncSeq_t	AS04;
 	unsigned int		rate,
 				format;
-	int			refframes;
 	int			chip_status;
-	struct semaphore	open_mutex;
+	struct semaphore	prepare_mutex;
 	us428ctls_sharedmem_t	*us428ctls_sharedmem;
+	int			wait_iso_frame;
 	wait_queue_head_t	us428ctls_wait_queue_head;
-	snd_usX2Y_substream_t	*substream[4];
+	snd_usX2Y_hwdep_pcm_shm_t	*hwdep_pcm_shm;
+	snd_usX2Y_substream_t	*subs[4];
+	snd_usX2Y_substream_t	* volatile  prepare_subs;
+	wait_queue_head_t	prepare_wait_queue;
 } usX2Ydev_t;
+
+
+struct snd_usX2Y_substream {
+	usX2Ydev_t	*usX2Y;
+	snd_pcm_substream_t *pcm_substream;
+
+	int			endpoint;		
+	unsigned int		maxpacksize;		/* max packet size in bytes */
+
+	atomic_t		state;
+#define state_STOPPED	0
+#define state_STARTING1 1
+#define state_STARTING2 2
+#define state_STARTING3 3
+#define state_PREPARED	4
+#define state_PRERUNNING  6
+#define state_RUNNING	8
+
+	int			hwptr;			/* free frame position in the buffer (only for playback) */
+	int			hwptr_done;		/* processed frame position in the buffer */
+	int			transfer_done;		/* processed frames since last period update */
+
+	struct urb		*urb[NRURBS];	/* data urb table */
+	struct urb		*completed_urb;
+	char			*tmpbuf;			/* temporary buffer for playback */
+};
 
 
 #define usX2Y(c) ((usX2Ydev_t*)(c)->private_data)
diff -Nru a/sound/usb/usx2y/usbusx2yaudio.c b/sound/usb/usx2y/usbusx2yaudio.c
--- a/sound/usb/usx2y/usbusx2yaudio.c	2005-03-01 23:38:57 -08:00
+++ b/sound/usb/usx2y/usbusx2yaudio.c	2005-03-01 23:38:57 -08:00
@@ -1,10 +1,9 @@
 /*
- *   US-428 AUDIO
-
- *   Copyright (c) 2002-2003 by Karsten Wiese
- 
+ *   US-X2Y AUDIO
+ *   Copyright (c) 2002-2004 by Karsten Wiese
+ *
  *   based on
-
+ *
  *   (Tentative) USB Audio Driver for ALSA
  *
  *   Main and PCM part
@@ -42,34 +41,30 @@
 #include "usx2y.h"
 #include "usbusx2y.h"
 
-
-struct snd_usX2Y_substream {
-	usX2Ydev_t	*usX2Y;
-	snd_pcm_substream_t *pcm_substream;
-
-	unsigned char		endpoint;		
-	unsigned int		datapipe;  		/* the data i/o pipe */
-	unsigned int		maxpacksize;		/* max packet size in bytes */
-
-	char			prepared,
-				running,
-				stalled;
-
-	int			hwptr;			/* free frame position in the buffer (only for playback) */
-	int			hwptr_done;		/* processed frame position in the buffer */
-	int			transfer_done;		/* processed frames since last period update */
-
-	struct urb		*urb[NRURBS];	/* data urb table */
-	int			next_urb_complete;
-	struct urb		*completed_urb;
-	char			*tmpbuf;			/* temporary buffer for playback */
-	volatile int		submitted_urbs;
-	wait_queue_head_t	wait_queue;
-};
-
-
-
-
+#define USX2Y_NRPACKS 4			/* Default value used for nr of packs per urb.
+					  1 to 4 have been tested ok on uhci.
+					  To use 3 on ohci, you'd need a patch:
+					  look for "0000425-linux-2.6.9-rc4-mm1_ohci-hcd.patch.gz" on
+					  "https://bugtrack.alsa-project.org/alsa-bug/bug_view_page.php?bug_id=0000425"
+					  .
+					  1, 2 and 4 work out of the box on ohci, if I recall correctly.
+					  Bigger is safer operation,
+					  smaller gives lower latencies.
+					*/
+#define USX2Y_NRPACKS_VARIABLE y	/* If your system works ok with this module's parameter
+					   nrpacks set to 1, you might as well comment 
+					   this #define out, and thereby produce smaller, faster code.
+					   You'd also set USX2Y_NRPACKS to 1 then.
+					*/
+
+#ifdef USX2Y_NRPACKS_VARIABLE
+ static int nrpacks = USX2Y_NRPACKS; /* number of packets per urb */
+ #define  nr_of_packs() nrpacks
+ module_param(nrpacks, int, 0444);
+ MODULE_PARM_DESC(nrpacks, "Number of packets per URB.");
+#else
+ #define nr_of_packs() USX2Y_NRPACKS
+#endif
 
 
 static int usX2Y_urb_capt_retire(snd_usX2Y_substream_t *subs)
@@ -80,15 +75,15 @@
 	int 		i, len, lens = 0, hwptr_done = subs->hwptr_done;
 	usX2Ydev_t	*usX2Y = subs->usX2Y;
 
-	for (i = 0; i < NRPACKS; i++) {
+	for (i = 0; i < nr_of_packs(); i++) {
 		cp = (unsigned char*)urb->transfer_buffer + urb->iso_frame_desc[i].offset;
 		if (urb->iso_frame_desc[i].status) { /* active? hmm, skip this */
-			snd_printdd("activ frame status %i\n", urb->iso_frame_desc[i].status);
+			snd_printk("activ frame status %i. Most propably some hardware problem.\n", urb->iso_frame_desc[i].status);
 			return urb->iso_frame_desc[i].status;
 		}
 		len = urb->iso_frame_desc[i].actual_length / usX2Y->stride;
 		if (! len) {
-			snd_printk("0 == len ERROR!\n");
+			snd_printd("0 == len ERROR!\n");
 			continue;
 		}
 
@@ -134,7 +129,7 @@
 	snd_pcm_runtime_t *runtime = subs->pcm_substream->runtime;
 
 	count = 0;
-	for (pack = 0; pack < NRPACKS; pack++) {
+	for (pack = 0; pack <  nr_of_packs(); pack++) {
 		/* calculate the size of a packet */
 		counts = cap_urb->iso_frame_desc[pack].actual_length / usX2Y->stride;
 		count += counts;
@@ -142,28 +137,32 @@
 			snd_printk("should not be here with counts=%i\n", counts);
 			return -EPIPE;
 		}
-
 		/* set up descriptor */
-		urb->iso_frame_desc[pack].offset = pack ? urb->iso_frame_desc[pack - 1].offset + urb->iso_frame_desc[pack - 1].length : 0;
-		urb->iso_frame_desc[pack].length = counts * usX2Y->stride;
-	}
-	if (subs->hwptr + count > runtime->buffer_size) {
-		/* err, the transferred area goes over buffer boundary.
-		 * copy the data to the temp buffer.
-		 */
-		int len;
-		len = runtime->buffer_size - subs->hwptr;
-		urb->transfer_buffer = subs->tmpbuf;
-		memcpy(subs->tmpbuf, runtime->dma_area + subs->hwptr * usX2Y->stride, len * usX2Y->stride);
-		memcpy(subs->tmpbuf + len * usX2Y->stride, runtime->dma_area, (count - len) * usX2Y->stride);
-		subs->hwptr += count;
-		subs->hwptr -= runtime->buffer_size;
-	} else {
-		/* set the buffer pointer */
-		urb->transfer_buffer = runtime->dma_area + subs->hwptr * usX2Y->stride;
-		if ((subs->hwptr += count) >= runtime->buffer_size)
+		urb->iso_frame_desc[pack].offset = pack ?
+			urb->iso_frame_desc[pack - 1].offset + urb->iso_frame_desc[pack - 1].length :
+			0;
+		urb->iso_frame_desc[pack].length = cap_urb->iso_frame_desc[pack].actual_length;
+	}
+	if (atomic_read(&subs->state) >= state_PRERUNNING)
+		if (subs->hwptr + count > runtime->buffer_size) {
+			/* err, the transferred area goes over buffer boundary.
+			 * copy the data to the temp buffer.
+			 */
+			int len;
+			len = runtime->buffer_size - subs->hwptr;
+			urb->transfer_buffer = subs->tmpbuf;
+			memcpy(subs->tmpbuf, runtime->dma_area + subs->hwptr * usX2Y->stride, len * usX2Y->stride);
+			memcpy(subs->tmpbuf + len * usX2Y->stride, runtime->dma_area, (count - len) * usX2Y->stride);
+			subs->hwptr += count;
+			subs->hwptr -= runtime->buffer_size;
+		} else {
+			/* set the buffer pointer */
+			urb->transfer_buffer = runtime->dma_area + subs->hwptr * usX2Y->stride;
+			if ((subs->hwptr += count) >= runtime->buffer_size)
 			subs->hwptr -= runtime->buffer_size;			
-	}
+		}
+	else
+		urb->transfer_buffer = subs->tmpbuf;
 	urb->transfer_buffer_length = count * usX2Y->stride;
 	return 0;
 }
@@ -173,14 +172,10 @@
  *
  * update the current position and call callback if a period is processed.
  */
-inline static int usX2Y_urb_play_retire(snd_usX2Y_substream_t *subs, struct urb *urb)
+static void usX2Y_urb_play_retire(snd_usX2Y_substream_t *subs, struct urb *urb)
 {
 	snd_pcm_runtime_t *runtime = subs->pcm_substream->runtime;
-	int		len = (urb->iso_frame_desc[0].actual_length
-#if NRPACKS > 1
-			       + urb->iso_frame_desc[1].actual_length
-#endif
-		               ) / subs->usX2Y->stride;
+	int		len = urb->actual_length / subs->usX2Y->stride;
 
 	subs->transfer_done += len;
 	subs->hwptr_done +=  len;
@@ -190,224 +185,206 @@
 		subs->transfer_done -= runtime->period_size;
 		snd_pcm_period_elapsed(subs->pcm_substream);
 	}
-	return 0;
 }
 
-inline static int usX2Y_urb_submit(snd_usX2Y_substream_t *subs, struct urb *urb, int frame)
+static int usX2Y_urb_submit(snd_usX2Y_substream_t *subs, struct urb *urb, int frame)
 {
 	int err;
 	if (!urb)
 		return -ENODEV;
-	urb->start_frame = (frame + NRURBS*NRPACKS) & (1024 - 1);
+	urb->start_frame = (frame + NRURBS * nr_of_packs());  // let hcd do rollover sanity checks
 	urb->hcpriv = NULL;
 	urb->dev = subs->usX2Y->chip.dev; /* we need to set this at each time */
 	if ((err = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
-		snd_printk("%i\n", err);
+		snd_printk("usb_submit_urb() returned %i\n", err);
 		return err;
-	} else {
-		subs->submitted_urbs++;
-		if (subs->next_urb_complete < 0) 
-			subs->next_urb_complete = 0;
 	}
 	return 0;
 }
 
-
-static inline int frame_distance(int from, int to)
+static inline int usX2Y_usbframe_complete(snd_usX2Y_substream_t *capsubs, snd_usX2Y_substream_t *playbacksubs, int frame)
 {
-	int distance = to - from;
-	if (distance < -512)
-		distance += 1024;
-	else
-		if (distance > 511)
-			distance -= 1024;
-	return distance;
-}
+	int err, state;
+	{
+		struct urb *urb = playbacksubs->completed_urb;
 
+		state = atomic_read(&playbacksubs->state);
+		if (NULL != urb) {
+			if (state == state_RUNNING)
+				usX2Y_urb_play_retire(playbacksubs, urb);
+			else
+				if (state >= state_PRERUNNING) {
+					atomic_inc(&playbacksubs->state);
+				}
+		} else {
+			switch (state) {
+			case state_STARTING1:
+				urb = playbacksubs->urb[0];
+				atomic_inc(&playbacksubs->state);
+				break;
+			case state_STARTING2:
+				urb = playbacksubs->urb[1];
+				atomic_inc(&playbacksubs->state);
+				break;
+			}
+		}
+		if (urb) {
+			if ((err = usX2Y_urb_play_prepare(playbacksubs, capsubs->completed_urb, urb)) ||
+			    (err = usX2Y_urb_submit(playbacksubs, urb, frame))) {
+				return err;
+			}
+		}
 
-static void usX2Y_subs_set_next_urb_complete(snd_usX2Y_substream_t *subs)
-{
-	int next_urb_complete = subs->next_urb_complete + 1;
-	int distance;
-	if (next_urb_complete >= NRURBS)
-		next_urb_complete = 0;
-	distance = frame_distance(subs->completed_urb->start_frame,
-				  subs->urb[next_urb_complete]->start_frame);
-	if (1 == distance) {
-		subs->next_urb_complete = next_urb_complete;
-	} else {
-		snd_printdd("distance %i not set_nuc %i %i %i \n", distance, subs->endpoint, next_urb_complete, subs->urb[next_urb_complete]->status);
-		subs->next_urb_complete = -1;
+		playbacksubs->completed_urb = NULL;
 	}
+	state = atomic_read(&capsubs->state);
+	if (state >= state_PREPARED) {
+		if (state == state_RUNNING) {
+			if ((err = usX2Y_urb_capt_retire(capsubs)))
+				return err;
+		} else
+			if (state >= state_PRERUNNING) {
+				atomic_inc(&capsubs->state);
+			}
+		if ((err = usX2Y_urb_submit(capsubs, capsubs->completed_urb, frame)))
+			return err;
+	}
+	capsubs->completed_urb = NULL;
+	return 0;
 }
 
 
-static inline void usX2Y_usbframe_complete(snd_usX2Y_substream_t *capsubs, snd_usX2Y_substream_t *playbacksubs, int frame)
+static void usX2Y_clients_stop(usX2Ydev_t *usX2Y)
 {
-	{
-		struct urb *urb;
-		if ((urb = playbacksubs->completed_urb)) {
-			if (playbacksubs->prepared)
-				usX2Y_urb_play_retire(playbacksubs, urb);
-			usX2Y_subs_set_next_urb_complete(playbacksubs);
+	int s, u;
+	for (s = 0; s < 4; s++) {
+		snd_usX2Y_substream_t *subs = usX2Y->subs[s];
+		if (subs) {
+			snd_printdd("%i %p state=%i\n", s, subs, atomic_read(&subs->state));
+			atomic_set(&subs->state, state_STOPPED);
 		}
-		if (playbacksubs->running) {
-			if (NULL == urb)
-				urb = playbacksubs->urb[playbacksubs->next_urb_complete + 1];
-			if (urb && 0 == usX2Y_urb_play_prepare(playbacksubs,
-							       capsubs->completed_urb,
-							       urb)) {
-				if (usX2Y_urb_submit(playbacksubs, urb, frame) < 0)
-					return;
-			} else
-				snd_pcm_stop(playbacksubs->pcm_substream, SNDRV_PCM_STATE_XRUN);
+	}
+	for (s = 0; s < 4; s++) {
+		snd_usX2Y_substream_t *subs = usX2Y->subs[s];
+		if (subs) {
+			if (atomic_read(&subs->state) >= state_PRERUNNING) {
+				snd_pcm_stop(subs->pcm_substream, SNDRV_PCM_STATE_XRUN);
+			}
+			for (u = 0; u < NRURBS; u++) {
+				struct urb *urb = subs->urb[u];
+				if (NULL != urb)
+					snd_printdd("%i status=%i start_frame=%i\n", u, urb->status, urb->start_frame);
+			}
 		}
-		playbacksubs->completed_urb = NULL;
 	}
-	if (capsubs->running)
-		usX2Y_urb_capt_retire(capsubs);
-	usX2Y_subs_set_next_urb_complete(capsubs);
-	if (capsubs->prepared)
-		usX2Y_urb_submit(capsubs, capsubs->completed_urb, frame);
-	capsubs->completed_urb = NULL;
+	usX2Y->prepare_subs = NULL;
+	wake_up(&usX2Y->prepare_wait_queue);
 }
 
-
-static void usX2Y_clients_stop(snd_usX2Y_substream_t *subs)
+static void usX2Y_error_urb_status(usX2Ydev_t *usX2Y, snd_usX2Y_substream_t *subs, struct urb *urb)
 {
-	usX2Ydev_t *usX2Y = subs->usX2Y;
-	int i;
-	for (i = 0; i < 4; i++) {
-		snd_usX2Y_substream_t *substream = usX2Y->substream[i];
-		if (substream && substream->running)
-			snd_pcm_stop(substream->pcm_substream, SNDRV_PCM_STATE_XRUN);
-	}
+	snd_printk("ep=%i stalled with status=%i\n", subs->endpoint, urb->status);
+	urb->status = 0;
+	usX2Y_clients_stop(usX2Y);
 }
 
+static void usX2Y_error_sequence(usX2Ydev_t *usX2Y, snd_usX2Y_substream_t *subs, struct urb *urb)
+{
+	snd_printk("Sequence Error!(hcd_frame=%i ep=%i%s;wait=%i,frame=%i).\n"
+		   "Most propably some urb of usb-frame %i is still missing.\n"
+		   "Cause could be too long delays in usb-hcd interrupt handling.\n",
+		   usb_get_current_frame_number(usX2Y->chip.dev),
+		   subs->endpoint, usb_pipein(urb->pipe) ? "in" : "out", usX2Y->wait_iso_frame, urb->start_frame, usX2Y->wait_iso_frame);
+	usX2Y_clients_stop(usX2Y);
+}
 
 static void i_usX2Y_urb_complete(struct urb *urb, struct pt_regs *regs)
 {
 	snd_usX2Y_substream_t *subs = (snd_usX2Y_substream_t*)urb->context;
+	usX2Ydev_t *usX2Y = subs->usX2Y;
 
-	subs->submitted_urbs--;
-	if (urb->status) {
-		snd_printk("ep=%i stalled with status=%i\n", subs->endpoint, urb->status);
-		subs->stalled = 1;
-		usX2Y_clients_stop(subs);
-		urb->status = 0;
+	if (unlikely(atomic_read(&subs->state) < state_PREPARED)) {
+		snd_printdd("hcd_frame=%i ep=%i%s status=%i start_frame=%i\n", usb_get_current_frame_number(usX2Y->chip.dev), subs->endpoint, usb_pipein(urb->pipe) ? "in" : "out", urb->status, urb->start_frame);
+		return;
+	}
+	if (unlikely(urb->status)) {
+		usX2Y_error_urb_status(usX2Y, subs, urb);
 		return;
 	}
-	if (urb == subs->urb[subs->next_urb_complete]) {
+	if (likely((0xFFFF & urb->start_frame) == usX2Y->wait_iso_frame))
 		subs->completed_urb = urb;
-	} else {
-		snd_printk("Sequence Error!(ep=%i;nuc=%i,frame=%i)\n",
-			   subs->endpoint, subs->next_urb_complete, urb->start_frame);
-		subs->stalled = 1;
-		usX2Y_clients_stop(subs);
+	else {
+		usX2Y_error_sequence(usX2Y, subs, urb);
 		return;
 	}
-	if (waitqueue_active(&subs->wait_queue))
-		wake_up(&subs->wait_queue);
 	{
-		snd_usX2Y_substream_t *capsubs = subs->usX2Y->substream[SNDRV_PCM_STREAM_CAPTURE],
-			*playbacksubs = subs->usX2Y->substream[SNDRV_PCM_STREAM_PLAYBACK];
-		if (capsubs->completed_urb &&
-		    (playbacksubs->completed_urb ||
-		     !playbacksubs->prepared ||
-		     (playbacksubs->prepared && (playbacksubs->next_urb_complete < 0 ||	// not started yet
-						 frame_distance(capsubs->completed_urb->start_frame,
-								playbacksubs->urb[playbacksubs->next_urb_complete]->start_frame)
-						 > 0 ||					// other expected later
-						 playbacksubs->stalled))))
-			usX2Y_usbframe_complete(capsubs, playbacksubs, urb->start_frame);
+		snd_usX2Y_substream_t *capsubs = usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE],
+			*playbacksubs = usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK];
+		if (capsubs->completed_urb && atomic_read(&capsubs->state) >= state_PREPARED &&
+		    (playbacksubs->completed_urb || atomic_read(&playbacksubs->state) < state_PREPARED)) {
+			if (!usX2Y_usbframe_complete(capsubs, playbacksubs, urb->start_frame)) {
+				if (nr_of_packs() <= urb->start_frame &&
+				    urb->start_frame <= (2 * nr_of_packs() - 1))	// uhci and ohci
+					usX2Y->wait_iso_frame = urb->start_frame - nr_of_packs();
+				else
+					usX2Y->wait_iso_frame +=  nr_of_packs();
+			} else {
+				snd_printdd("\n");
+				usX2Y_clients_stop(usX2Y);
+			}
+		}
 	}
 }
 
-
-static int usX2Y_urbs_capt_start(snd_usX2Y_substream_t *subs)
+static void usX2Y_urbs_set_complete(usX2Ydev_t * usX2Y, void (*complete)(struct urb *, struct pt_regs *))
 {
-	int i, err;
-
-	for (i = 0; i < NRURBS; i++) {
-		unsigned long pack;
-		struct urb *urb = subs->urb[i];
-		urb->dev = subs->usX2Y->chip.dev;
-		urb->transfer_flags = URB_ISO_ASAP;
-		for (pack = 0; pack < NRPACKS; pack++) {
-			urb->iso_frame_desc[pack].offset = subs->maxpacksize * pack;
-			urb->iso_frame_desc[pack].length = subs->maxpacksize;
-		}
-		urb->transfer_buffer_length = subs->maxpacksize * NRPACKS; 
-		if ((err = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
-			snd_printk (KERN_ERR "cannot submit datapipe for urb %d, err = %d\n", i, err);
-			return -EPIPE;
-		} else {
-			subs->submitted_urbs++;
-		}
-		urb->transfer_flags = 0;
+	int s, u;
+	for (s = 0; s < 4; s++) {
+		snd_usX2Y_substream_t *subs = usX2Y->subs[s];
+		if (NULL != subs)
+			for (u = 0; u < NRURBS; u++) {
+				struct urb * urb = subs->urb[u];
+				if (NULL != urb)
+					urb->complete = complete;
+			}
 	}
-	subs->stalled = 0;
-	subs->next_urb_complete = 0;
-	subs->prepared = 1;
-	return 0;
 }
 
-/* 
- *  wait until all urbs are processed.
- */
-static int usX2Y_urbs_wait_clear(snd_usX2Y_substream_t *subs)
+static void usX2Y_subs_startup_finish(usX2Ydev_t * usX2Y)
 {
-	int timeout = HZ;
-
-	do {
-		if (0 == subs->submitted_urbs)
-			break;
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		snd_printdd("snd_usX2Y_urbs_wait_clear waiting\n");
-		schedule_timeout(1);
-	} while (--timeout > 0);
-	if (subs->submitted_urbs)
-		snd_printk(KERN_ERR "timeout: still %d active urbs..\n", subs->submitted_urbs);
-	return 0;
+	usX2Y_urbs_set_complete(usX2Y, i_usX2Y_urb_complete);
+	usX2Y->prepare_subs = NULL;
 }
-/*
- * return the current pcm pointer.  just return the hwptr_done value.
- */
-static snd_pcm_uframes_t snd_usX2Y_pcm_pointer(snd_pcm_substream_t *substream)
-{
-	snd_usX2Y_substream_t *subs = (snd_usX2Y_substream_t *)substream->runtime->private_data;
-	return subs->hwptr_done;
-}
-/*
- * start/stop substream
- */
-static int snd_usX2Y_pcm_trigger(snd_pcm_substream_t *substream, int cmd)
+
+static void i_usX2Y_subs_startup(struct urb *urb, struct pt_regs *regs)
 {
-	snd_usX2Y_substream_t *subs = (snd_usX2Y_substream_t *)substream->runtime->private_data;
+	snd_usX2Y_substream_t *subs = (snd_usX2Y_substream_t*)urb->context;
+	usX2Ydev_t *usX2Y = subs->usX2Y;
+	snd_usX2Y_substream_t *prepare_subs = usX2Y->prepare_subs;
+	if (NULL != prepare_subs)
+		if (urb->start_frame == prepare_subs->urb[0]->start_frame) {
+			usX2Y_subs_startup_finish(usX2Y);
+			atomic_inc(&prepare_subs->state);
+			wake_up(&usX2Y->prepare_wait_queue);
+		}
 
-	switch (cmd) {
-	case SNDRV_PCM_TRIGGER_START:
-		snd_printdd("snd_usX2Y_pcm_trigger(START)\n");
-		if (subs->usX2Y->substream[SNDRV_PCM_STREAM_CAPTURE]->stalled)
-			return -EPIPE;
-		else
-			subs->running = 1;
-		break;
-	case SNDRV_PCM_TRIGGER_STOP:
-		snd_printdd("snd_usX2Y_pcm_trigger(STOP)\n");
-		subs->running = 0;
-		break;
-	default:
-		return -EINVAL;
-	}
-	return 0;
+	i_usX2Y_urb_complete(urb, regs);
 }
 
+static void usX2Y_subs_prepare(snd_usX2Y_substream_t *subs)
+{
+	snd_printdd("usX2Y_substream_prepare(%p) ep=%i urb0=%p urb1=%p\n", subs, subs->endpoint, subs->urb[0], subs->urb[1]);
+	/* reset the pointer */
+	subs->hwptr = 0;
+	subs->hwptr_done = 0;
+	subs->transfer_done = 0;
+}
 
 
 static void usX2Y_urb_release(struct urb** urb, int free_tb)
 {
 	if (*urb) {
+		usb_kill_urb(*urb);
 		if (free_tb)
 			kfree((*urb)->transfer_buffer);
 		usb_free_urb(*urb);
@@ -415,98 +392,181 @@
 	}
 }
 /*
- * release a substream
+ * release a substreams urbs
  */
 static void usX2Y_urbs_release(snd_usX2Y_substream_t *subs)
 {
 	int i;
-	snd_printdd("snd_usX2Y_urbs_release() %i\n", subs->endpoint);
-	usX2Y_urbs_wait_clear(subs);
+	snd_printdd("usX2Y_urbs_release() %i\n", subs->endpoint);
 	for (i = 0; i < NRURBS; i++)
-		usX2Y_urb_release(subs->urb + i, subs != subs->usX2Y->substream[SNDRV_PCM_STREAM_PLAYBACK]);
+		usX2Y_urb_release(subs->urb + i, subs != subs->usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK]);
 
 	if (subs->tmpbuf) {
 		kfree(subs->tmpbuf);
 		subs->tmpbuf = NULL;
 	}
 }
-
-static void usX2Y_substream_prepare(snd_usX2Y_substream_t *subs)
-{
-	snd_printdd("usX2Y_substream_prepare() ep=%i urb0=%p urb1=%p\n", subs->endpoint, subs->urb[0], subs->urb[1]);
-	/* reset the pointer */
-	subs->hwptr = 0;
-	subs->hwptr_done = 0;
-	subs->transfer_done = 0;
-}
-
-
 /*
  * initialize a substream's urbs
  */
 static int usX2Y_urbs_allocate(snd_usX2Y_substream_t *subs)
 {
 	int i;
-	int is_playback = subs == subs->usX2Y->substream[SNDRV_PCM_STREAM_PLAYBACK];
+	unsigned int pipe;
+	int is_playback = subs == subs->usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK];
 	struct usb_device *dev = subs->usX2Y->chip.dev;
+	struct usb_host_endpoint *ep;
 
-	snd_assert(!subs->prepared, return 0);
+	pipe = is_playback ? usb_sndisocpipe(dev, subs->endpoint) :
+			usb_rcvisocpipe(dev, subs->endpoint);
+	subs->maxpacksize = usb_maxpacket(dev, pipe, is_playback);
+	if (!subs->maxpacksize)
+		return -EINVAL;
 
-	if (is_playback) {	/* allocate a temporary buffer for playback */
-		subs->datapipe = usb_sndisocpipe(dev, subs->endpoint);
-		subs->maxpacksize = dev->epmaxpacketout[subs->endpoint];
+	if (is_playback && NULL == subs->tmpbuf) {	/* allocate a temporary buffer for playback */
+		subs->tmpbuf = kcalloc(nr_of_packs(), subs->maxpacksize, GFP_KERNEL);
 		if (NULL == subs->tmpbuf) {
-			subs->tmpbuf = kcalloc(NRPACKS, subs->maxpacksize, GFP_KERNEL);
-			if (NULL == subs->tmpbuf) {
-				snd_printk(KERN_ERR "cannot malloc tmpbuf\n");
-				return -ENOMEM;
-			}
+			snd_printk(KERN_ERR "cannot malloc tmpbuf\n");
+			return -ENOMEM;
 		}
-	} else {
-		subs->datapipe = usb_rcvisocpipe(dev, subs->endpoint);
-		subs->maxpacksize = dev->epmaxpacketin[subs->endpoint];
 	}
-
 	/* allocate and initialize data urbs */
 	for (i = 0; i < NRURBS; i++) {
 		struct urb** purb = subs->urb + i;
-		if (*purb)
+		if (*purb) {
+			usb_kill_urb(*purb);
 			continue;
-		*purb = usb_alloc_urb(NRPACKS, GFP_KERNEL);
+		}
+		*purb = usb_alloc_urb(nr_of_packs(), GFP_KERNEL);
 		if (NULL == *purb) {
 			usX2Y_urbs_release(subs);
 			return -ENOMEM;
 		}
 		if (!is_playback && !(*purb)->transfer_buffer) {
 			/* allocate a capture buffer per urb */
-			(*purb)->transfer_buffer = kmalloc(subs->maxpacksize*NRPACKS, GFP_KERNEL);
+			(*purb)->transfer_buffer = kmalloc(subs->maxpacksize * nr_of_packs(), GFP_KERNEL);
 			if (NULL == (*purb)->transfer_buffer) {
 				usX2Y_urbs_release(subs);
 				return -ENOMEM;
 			}
 		}
 		(*purb)->dev = dev;
-		(*purb)->pipe = subs->datapipe;
-		(*purb)->number_of_packets = NRPACKS;
+		(*purb)->pipe = pipe;
+		(*purb)->number_of_packets = nr_of_packs();
 		(*purb)->context = subs;
 		(*purb)->interval = 1;
-		(*purb)->complete = snd_usb_complete_callback(i_usX2Y_urb_complete);
+		(*purb)->complete = i_usX2Y_subs_startup;
 	}
 	return 0;
 }
 
-static void i_usX2Y_04Int(struct urb* urb, struct pt_regs *regs)
+static void usX2Y_subs_startup(snd_usX2Y_substream_t *subs)
 {
-	usX2Ydev_t*	usX2Y = urb->context;
-	
-	if (urb->status) {
-		snd_printk("snd_usX2Y_04Int() urb->status=%i\n", urb->status);
-		return;
+	usX2Ydev_t *usX2Y = subs->usX2Y;
+	usX2Y->prepare_subs = subs;
+	subs->urb[0]->start_frame = -1;
+	wmb();
+	usX2Y_urbs_set_complete(usX2Y, i_usX2Y_subs_startup);
+}
+
+static int usX2Y_urbs_start(snd_usX2Y_substream_t *subs)
+{
+	int i, err;
+	usX2Ydev_t *usX2Y = subs->usX2Y;
+
+	if ((err = usX2Y_urbs_allocate(subs)) < 0)
+		return err;
+	subs->completed_urb = NULL;
+	for (i = 0; i < 4; i++) {
+		snd_usX2Y_substream_t *subs = usX2Y->subs[i];
+		if (subs != NULL && atomic_read(&subs->state) >= state_PREPARED)
+			goto start;
 	}
-	if (0 == --usX2Y->US04->len)
-		wake_up(&usX2Y->In04WaitQueue);
+	usX2Y->wait_iso_frame = -1;
+ start:
+	{
+		usX2Y_subs_startup(subs);
+		for (i = 0; i < NRURBS; i++) {
+			struct urb *urb = subs->urb[i];
+			if (usb_pipein(urb->pipe)) {
+				unsigned long pack;
+				if (0 == i)
+					atomic_set(&subs->state, state_STARTING3);
+				urb->dev = usX2Y->chip.dev;
+				urb->transfer_flags = URB_ISO_ASAP;
+				for (pack = 0; pack < nr_of_packs(); pack++) {
+					urb->iso_frame_desc[pack].offset = subs->maxpacksize * pack;
+					urb->iso_frame_desc[pack].length = subs->maxpacksize;
+				}
+				urb->transfer_buffer_length = subs->maxpacksize * nr_of_packs(); 
+				if ((err = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
+					snd_printk (KERN_ERR "cannot submit datapipe for urb %d, err = %d\n", i, err);
+					err = -EPIPE;
+					goto cleanup;
+				} else {
+					if (0 > usX2Y->wait_iso_frame)
+						usX2Y->wait_iso_frame = urb->start_frame;
+				}
+				urb->transfer_flags = 0;
+			} else {
+				atomic_set(&subs->state, state_STARTING1);
+				break;
+			}
+		}
+		err = 0;
+		wait_event(usX2Y->prepare_wait_queue, NULL == usX2Y->prepare_subs);
+		if (atomic_read(&subs->state) != state_PREPARED) {
+			err = -EPIPE;
+		}
+
+	cleanup:
+		if (err) {
+			usX2Y_subs_startup_finish(usX2Y);
+			usX2Y_clients_stop(usX2Y);		// something is completely wroong > stop evrything
+		}
+	}
+	return err;
+}
+
+/*
+ * return the current pcm pointer.  just return the hwptr_done value.
+ */
+static snd_pcm_uframes_t snd_usX2Y_pcm_pointer(snd_pcm_substream_t *substream)
+{
+	snd_usX2Y_substream_t *subs = (snd_usX2Y_substream_t *)substream->runtime->private_data;
+	return subs->hwptr_done;
 }
 /*
+ * start/stop substream
+ */
+static int snd_usX2Y_pcm_trigger(snd_pcm_substream_t *substream, int cmd)
+{
+	snd_usX2Y_substream_t *subs = (snd_usX2Y_substream_t *)substream->runtime->private_data;
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+		snd_printdd("snd_usX2Y_pcm_trigger(START)\n");
+		if (atomic_read(&subs->state) == state_PREPARED &&
+		    atomic_read(&subs->usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE]->state) >= state_PREPARED) {
+			atomic_set(&subs->state, state_PRERUNNING);
+		} else {
+			snd_printdd("\n");
+			return -EPIPE;
+		}
+		break;
+	case SNDRV_PCM_TRIGGER_STOP:
+		snd_printdd("snd_usX2Y_pcm_trigger(STOP)\n");
+		if (atomic_read(&subs->state) >= state_PRERUNNING)
+			atomic_set(&subs->state, state_PREPARED);
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+
+/*
  * allocate a buffer, setup samplerate
  *
  * so far we use a physically linear buffer although packetize transfer
@@ -592,76 +652,74 @@
 };
 #define NOOF_SETRATE_URBS ARRAY_SIZE(SetRate48000)
 
+static void i_usX2Y_04Int(struct urb* urb, struct pt_regs *regs)
+{
+	usX2Ydev_t*	usX2Y = urb->context;
+	
+	if (urb->status) {
+		snd_printk("snd_usX2Y_04Int() urb->status=%i\n", urb->status);
+	}
+	if (0 == --usX2Y->US04->len)
+		wake_up(&usX2Y->In04WaitQueue);
+}
+
 static int usX2Y_rate_set(usX2Ydev_t *usX2Y, int rate)
 {
 	int			err = 0, i;
 	snd_usX2Y_urbSeq_t	*us = NULL;
 	int			*usbdata = NULL;
-	DECLARE_WAITQUEUE(wait, current);
 	struct s_c2		*ra = rate == 48000 ? SetRate48000 : SetRate44100;
 
 	if (usX2Y->rate != rate) {
-		do {
-			us = kmalloc(sizeof(*us) + sizeof(struct urb*) * NOOF_SETRATE_URBS, GFP_KERNEL);
-			if (NULL == us) {
-				err = -ENOMEM;
-				break;
-			}
-			memset(us, 0, sizeof(*us) + sizeof(struct urb*) * NOOF_SETRATE_URBS); 
-			usbdata = kmalloc(sizeof(int)*NOOF_SETRATE_URBS, GFP_KERNEL);
-			if (NULL == usbdata) {
+		us = kmalloc(sizeof(*us) + sizeof(struct urb*) * NOOF_SETRATE_URBS, GFP_KERNEL);
+		if (NULL == us) {
+			err = -ENOMEM;
+			goto cleanup;
+		}
+		memset(us, 0, sizeof(*us) + sizeof(struct urb*) * NOOF_SETRATE_URBS); 
+		usbdata = kmalloc(sizeof(int)*NOOF_SETRATE_URBS, GFP_KERNEL);
+		if (NULL == usbdata) {
+			err = -ENOMEM;
+			goto cleanup;
+		}
+		for (i = 0; i < NOOF_SETRATE_URBS; ++i) {
+			if (NULL == (us->urb[i] = usb_alloc_urb(0, GFP_KERNEL))) {
 				err = -ENOMEM;
-				break;
+				goto cleanup;
 			}
-			for (i = 0; i < NOOF_SETRATE_URBS; ++i) {
-				if (NULL == (us->urb[i] = usb_alloc_urb(0, GFP_KERNEL))) {
-					err = -ENOMEM;
-					break;
-				}
-				((char*)(usbdata + i))[0] = ra[i].c1;
-				((char*)(usbdata + i))[1] = ra[i].c2;
-				usb_fill_bulk_urb(us->urb[i], usX2Y->chip.dev, usb_sndbulkpipe(usX2Y->chip.dev, 4),
-						  usbdata + i, 2, i_usX2Y_04Int, usX2Y);
+			((char*)(usbdata + i))[0] = ra[i].c1;
+			((char*)(usbdata + i))[1] = ra[i].c2;
+			usb_fill_bulk_urb(us->urb[i], usX2Y->chip.dev, usb_sndbulkpipe(usX2Y->chip.dev, 4),
+					  usbdata + i, 2, i_usX2Y_04Int, usX2Y);
 #ifdef OLD_USB
-				us->urb[i]->transfer_flags = USB_QUEUE_BULK;
+			us->urb[i]->transfer_flags = USB_QUEUE_BULK;
 #endif
-			}
-			if (err)
-				break;
-
-			add_wait_queue(&usX2Y->In04WaitQueue, &wait);
-			set_current_state(TASK_INTERRUPTIBLE);
-			us->submitted =	0;
-			us->len =	NOOF_SETRATE_URBS;
-			usX2Y->US04 =	us;
-		
-			do {
-				signed long	timeout = schedule_timeout(HZ/2);
-                	
-				if (signal_pending(current)) {
-					err = -ERESTARTSYS;
-					break;
-				}
-				if (0 == timeout) {
-					err = -ENODEV;
-					break;
-				}
-				usX2Y->rate = rate;
-				usX2Y->refframes = rate == 48000 ? 47 : 44;
-			} while (0);
-		
-			remove_wait_queue(&usX2Y->In04WaitQueue, &wait);
-		} while (0);
-
+		}
+		us->submitted =	0;
+		us->len =	NOOF_SETRATE_URBS;
+		usX2Y->US04 =	us;
+		wait_event_timeout(usX2Y->In04WaitQueue, 0 == us->len, HZ);
+		usX2Y->US04 =	NULL;
+		if (us->len)
+			err = -ENODEV;
+	cleanup:
 		if (us) {
 			us->submitted =	2*NOOF_SETRATE_URBS;
 			for (i = 0; i < NOOF_SETRATE_URBS; ++i) {
-				usb_kill_urb(us->urb[i]);
-				usb_free_urb(us->urb[i]);
+				struct urb *urb = us->urb[i];
+				if (urb->status) {
+					if (!err)
+						err = -ENODEV;
+					usb_kill_urb(urb);
+				}
+				usb_free_urb(urb);
 			}
 			usX2Y->US04 = NULL;
 			kfree(usbdata);
 			kfree(us);
+			if (!err) {
+				usX2Y->rate = rate;
+			}
 		}
 	}
 
@@ -745,27 +803,28 @@
 {
 	snd_pcm_runtime_t *runtime = substream->runtime;
 	snd_usX2Y_substream_t *subs = (snd_usX2Y_substream_t *)runtime->private_data;
+	down(&subs->usX2Y->prepare_mutex);
 	snd_printdd("snd_usX2Y_hw_free(%p)\n", substream);
 
 	if (SNDRV_PCM_STREAM_PLAYBACK == substream->stream) {
-		snd_usX2Y_substream_t *cap_subs = subs->usX2Y->substream[SNDRV_PCM_STREAM_CAPTURE];
-		subs->prepared = 0;
+		snd_usX2Y_substream_t *cap_subs = subs->usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE];
+		atomic_set(&subs->state, state_STOPPED);
 		usX2Y_urbs_release(subs);
 		if (!cap_subs->pcm_substream ||
 		    !cap_subs->pcm_substream->runtime ||
 		    !cap_subs->pcm_substream->runtime->status ||
 		    cap_subs->pcm_substream->runtime->status->state < SNDRV_PCM_STATE_PREPARED) {
-			cap_subs->prepared = 0;
+			atomic_set(&cap_subs->state, state_STOPPED);
 			usX2Y_urbs_release(cap_subs);
 		}
 	} else {
-		snd_usX2Y_substream_t *playback_subs = subs->usX2Y->substream[SNDRV_PCM_STREAM_PLAYBACK];
-		if (!playback_subs->prepared) {
-			subs->prepared = 0;
+		snd_usX2Y_substream_t *playback_subs = subs->usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK];
+		if (atomic_read(&playback_subs->state) < state_PREPARED) {
+			atomic_set(&subs->state, state_STOPPED);
 			usX2Y_urbs_release(subs);
 		}
 	}
-
+	up(&subs->usX2Y->prepare_mutex);
 	return snd_pcm_lib_free_pages(substream);
 }
 /*
@@ -777,71 +836,32 @@
 {
 	snd_pcm_runtime_t *runtime = substream->runtime;
 	snd_usX2Y_substream_t *subs = (snd_usX2Y_substream_t *)runtime->private_data;
-	snd_usX2Y_substream_t *capsubs = subs->usX2Y->substream[SNDRV_PCM_STREAM_CAPTURE];
+	usX2Ydev_t *usX2Y = subs->usX2Y;
+	snd_usX2Y_substream_t *capsubs = subs->usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE];
 	int err = 0;
 	snd_printdd("snd_usX2Y_pcm_prepare(%p)\n", substream);
 
+	down(&usX2Y->prepare_mutex);
+	usX2Y_subs_prepare(subs);
 // Start hardware streams
 // SyncStream first....
-	if (! capsubs->prepared) {
-		if (subs->usX2Y->format != runtime->format)
-			if ((err = usX2Y_format_set(subs->usX2Y, runtime->format)) < 0)
-				return err;
-		if (subs->usX2Y->rate != runtime->rate)
-			if ((err = usX2Y_rate_set(subs->usX2Y, runtime->rate)) < 0)
-				return err;
-		snd_printdd("starting capture pipe for playpipe\n");
-		usX2Y_urbs_allocate(capsubs);
-		capsubs->completed_urb = NULL;
-		{
-			DECLARE_WAITQUEUE(wait, current);
-			add_wait_queue(&capsubs->wait_queue, &wait);
-			if (0 <= (err = usX2Y_urbs_capt_start(capsubs))) {
-				signed long timeout;
-				set_current_state(TASK_INTERRUPTIBLE);
-				timeout = schedule_timeout(HZ/4);
-				if (signal_pending(current))
-					err = -ERESTARTSYS;
-				else {
-					snd_printdd("%li\n", HZ/4 - timeout);
-					if (0 == timeout)
-						err = -EPIPE;
-				}
-			}
-			remove_wait_queue(&capsubs->wait_queue, &wait);
-			if (0 > err)
-				return err;
-		}
+	if (atomic_read(&capsubs->state) < state_PREPARED) {
+		if (usX2Y->format != runtime->format)
+			if ((err = usX2Y_format_set(usX2Y, runtime->format)) < 0)
+				goto up_prepare_mutex;
+		if (usX2Y->rate != runtime->rate)
+			if ((err = usX2Y_rate_set(usX2Y, runtime->rate)) < 0)
+				goto up_prepare_mutex;
+		snd_printdd("starting capture pipe for %s\n", subs == capsubs ? "self" : "playpipe");
+		if (0 > (err = usX2Y_urbs_start(capsubs)))
+			goto up_prepare_mutex;
 	}
 
-	if (subs != capsubs) {
-		int u;
-		if (!subs->prepared) {
-			if ((err = usX2Y_urbs_allocate(subs)) < 0)
-				return err;
-			subs->prepared = 1;
-		}
-		while (subs->submitted_urbs)
-			for (u = 0; u < NRURBS; u++) {
-				snd_printdd("%i\n", subs->urb[u]->status);
-				while(subs->urb[u]->status  ||  NULL != subs->urb[u]->hcpriv) {
-					signed long timeout;
-					snd_printdd("ep=%i waiting for urb=%p status=%i hcpriv=%p\n",
-						    subs->endpoint, subs->urb[u],
-						    subs->urb[u]->status, subs->urb[u]->hcpriv);
-					set_current_state(TASK_INTERRUPTIBLE);
-					timeout = schedule_timeout(HZ/10);
-					if (signal_pending(current)) {
-						return -ERESTARTSYS;
-					}
-				}
-			}
-		subs->completed_urb = NULL;
-		subs->next_urb_complete = -1;
-		subs->stalled = 0;
-	}
+	if (subs != capsubs && atomic_read(&subs->state) < state_PREPARED)
+		err = usX2Y_urbs_start(subs);
 
-	usX2Y_substream_prepare(subs);
+ up_prepare_mutex:
+	up(&usX2Y->prepare_mutex);
 	return err;
 }
 
@@ -872,6 +892,9 @@
 					 snd_pcm_substream_chip(substream))[substream->stream];
 	snd_pcm_runtime_t	*runtime = substream->runtime;
 
+	if (subs->usX2Y->chip_status & USX2Y_STAT_CHIP_MMAP_PCM_URBS)
+		return -EBUSY;
+
 	runtime->hw = snd_usX2Y_2c;
 	runtime->private_data = subs;
 	subs->pcm_substream = substream;
@@ -933,7 +956,7 @@
 	snd_pcm_t *pcm;
 	int err, i;
 	snd_usX2Y_substream_t **usX2Y_substream =
-		usX2Y(card)->substream + 2 * usX2Y(card)->chip.pcm_devs;
+		usX2Y(card)->subs + 2 * usX2Y(card)->chip.pcm_devs;
 
 	for (i = playback_endpoint ? SNDRV_PCM_STREAM_PLAYBACK : SNDRV_PCM_STREAM_CAPTURE;
 	     i <= SNDRV_PCM_STREAM_CAPTURE; ++i) {
@@ -942,7 +965,6 @@
 			snd_printk(KERN_ERR "cannot malloc\n");
 			return -ENOMEM;
 		}
-		init_waitqueue_head(&usX2Y_substream[i]->wait_queue);
 		usX2Y_substream[i]->usX2Y = usX2Y(card);
 	}
 
@@ -986,40 +1008,20 @@
 }
 
 /*
- * free the chip instance
- *
- * here we have to do not much, since pcm and controls are already freed
- *
- */
-static int snd_usX2Y_device_dev_free(snd_device_t *device)
-{
-	return 0;
-}
-
-
-/*
  * create a chip instance and set its names.
  */
 int usX2Y_audio_create(snd_card_t* card)
 {
 	int err = 0;
-	static snd_device_ops_t ops = {
-		.dev_free = snd_usX2Y_device_dev_free,
-	};
 	
 	INIT_LIST_HEAD(&usX2Y(card)->chip.pcm_list);
 
-	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, usX2Y(card), &ops)) < 0) {
-//		snd_usX2Y_audio_free(usX2Y(card));
-		return err;
-	}
-
 	if (0 > (err = usX2Y_audio_stream_new(card, 0xA, 0x8)))
 		return err;
-	if (usX2Y(card)->chip.dev->descriptor.idProduct == USB_ID_US428)
+	if (le16_to_cpu(usX2Y(card)->chip.dev->descriptor.idProduct) == USB_ID_US428)
 	     if (0 > (err = usX2Y_audio_stream_new(card, 0, 0xA)))
 		     return err;
-	if (usX2Y(card)->chip.dev->descriptor.idProduct != USB_ID_US122)
+	if (le16_to_cpu(usX2Y(card)->chip.dev->descriptor.idProduct) != USB_ID_US122)
 		err = usX2Y_rate_set(usX2Y(card), 44100);	// Lets us428 recognize output-volume settings, disturbs us122.
 	return err;
 }
diff -Nru a/sound/usb/usx2y/usx2y.h b/sound/usb/usx2y/usx2y.h
--- a/sound/usb/usx2y/usx2y.h	2005-03-01 23:39:16 -08:00
+++ b/sound/usb/usx2y/usx2y.h	2005-03-01 23:39:16 -08:00
@@ -27,6 +27,7 @@
 
 /* hwdep id string */
 #define SND_USX2Y_LOADER_ID		"USX2Y Loader"
+#define SND_USX2Y_USBPCM_ID		"USX2Y USBPCM"
 
 /* hardware type */
 enum {
@@ -42,8 +43,9 @@
 
 /* chip status */
 enum {
-	USX2Y_STAT_CHIP_INIT	= (1 << 0),	/* all operational */
-	USX2Y_STAT_CHIP_HUP	= (1 << 31),	/* all operational */
+	USX2Y_STAT_CHIP_INIT	=	(1 << 0),	/* all operational */
+	USX2Y_STAT_CHIP_MMAP_PCM_URBS = (1 << 1),	/* pcm transport over mmaped urbs */
+	USX2Y_STAT_CHIP_HUP	=	(1 << 31),	/* all operational */
 };
 
 #endif /* __SOUND_USX2Y_COMMON_H */
diff -Nru a/sound/usb/usx2y/usx2yhwdeppcm.c b/sound/usb/usx2y/usx2yhwdeppcm.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/sound/usb/usx2y/usx2yhwdeppcm.c	2005-03-01 23:39:27 -08:00
@@ -0,0 +1,807 @@
+/*
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You 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
+ */
+
+/* USX2Y "rawusb" aka hwdep_pcm implementation
+
+ Its usb's unableness to atomically handle power of 2 period sized data chuncs
+ at standard samplerates,
+ what led to this part of the usx2y module: 
+ It provides the alsa kernel half of the usx2y-alsa-jack driver pair.
+ The pair uses a hardware dependant alsa-device for mmaped pcm transport.
+ Advantage achieved:
+         The usb_hc moves pcm data from/into memory via DMA.
+         That memory is mmaped by jack's usx2y driver.
+         Jack's usx2y driver is the first/last to read/write pcm data.
+         Read/write is a combination of power of 2 period shaping and
+         float/int conversation.
+         Compared to mainline alsa/jack we leave out power of 2 period shaping inside
+         snd-usb-usx2y which needs memcpy() and additional buffers.
+         As a side effect possible unwanted pcm-data coruption resulting of
+         standard alsa's snd-usb-usx2y period shaping scheme falls away.
+         Result is sane jack operation at buffering schemes down to 128frames,
+         2 periods.
+         plain usx2y alsa mode is able to achieve 64frames, 4periods, but only at the
+         cost of easier triggered i.e. aeolus xruns (128 or 256frames,
+         2periods works but is useless cause of crackling).
+ 
+ This is a first "proof of concept" implementation.
+ Later, funcionalities should migrate to more apropriate places:
+ Userland:
+ - The jackd could mmap its float-pcm buffers directly from alsa-lib.
+ - alsa-lib could provide power of 2 period sized shaping combined with int/float
+   conversation.
+   Currently the usx2y jack driver provides above 2 services.
+ Kernel:
+ - rawusb dma pcm buffer transport should go to snd-usb-lib, so also snd-usb-audio
+   devices can use it.
+   Currently rawusb dma pcm buffer transport (this file) is only available to snd-usb-usx2y. 
+*/
+
+#include "usbusx2yaudio.c"
+
+#if defined(USX2Y_NRPACKS_VARIABLE) || (!defined(USX2Y_NRPACKS_VARIABLE) &&  USX2Y_NRPACKS == 1)
+
+#include <sound/hwdep.h>
+
+
+static int usX2Y_usbpcm_urb_capt_retire(snd_usX2Y_substream_t *subs)
+{
+	struct urb	*urb = subs->completed_urb;
+	snd_pcm_runtime_t *runtime = subs->pcm_substream->runtime;
+	int 		i, lens = 0, hwptr_done = subs->hwptr_done;
+	usX2Ydev_t	*usX2Y = subs->usX2Y;
+	if (0 > usX2Y->hwdep_pcm_shm->capture_iso_start) { //FIXME
+		int head = usX2Y->hwdep_pcm_shm->captured_iso_head + 1;
+		if (head >= ARRAY_SIZE(usX2Y->hwdep_pcm_shm->captured_iso))
+			head = 0;
+		usX2Y->hwdep_pcm_shm->capture_iso_start = head;
+		snd_printdd("cap start %i\n", head);
+	}
+	for (i = 0; i < nr_of_packs(); i++) {
+		if (urb->iso_frame_desc[i].status) { /* active? hmm, skip this */
+			snd_printk("activ frame status %i. Most propably some hardware problem.\n", urb->iso_frame_desc[i].status);
+			return urb->iso_frame_desc[i].status;
+		}
+		lens += urb->iso_frame_desc[i].actual_length / usX2Y->stride;
+	}
+	if ((hwptr_done += lens) >= runtime->buffer_size)
+		hwptr_done -= runtime->buffer_size;
+	subs->hwptr_done = hwptr_done;
+	subs->transfer_done += lens;
+	/* update the pointer, call callback if necessary */
+	if (subs->transfer_done >= runtime->period_size) {
+		subs->transfer_done -= runtime->period_size;
+		snd_pcm_period_elapsed(subs->pcm_substream);
+	}
+	return 0;
+}
+
+static inline int usX2Y_iso_frames_per_buffer(snd_pcm_runtime_t *runtime, usX2Ydev_t * usX2Y)
+{
+	return (runtime->buffer_size * 1000) / usX2Y->rate + 1;	//FIXME: so far only correct period_size == 2^x ?
+}
+
+/*
+ * prepare urb for playback data pipe
+ *
+ * we copy the data directly from the pcm buffer.
+ * the current position to be copied is held in hwptr field.
+ * since a urb can handle only a single linear buffer, if the total
+ * transferred area overflows the buffer boundary, we cannot send
+ * it directly from the buffer.  thus the data is once copied to
+ * a temporary buffer and urb points to that.
+ */
+static int usX2Y_hwdep_urb_play_prepare(snd_usX2Y_substream_t *subs,
+				  struct urb *urb)
+{
+	int count, counts, pack;
+	usX2Ydev_t *usX2Y = subs->usX2Y;
+	struct snd_usX2Y_hwdep_pcm_shm *shm = usX2Y->hwdep_pcm_shm;
+	snd_pcm_runtime_t *runtime = subs->pcm_substream->runtime;
+
+	if (0 > shm->playback_iso_start) {
+		shm->playback_iso_start = shm->captured_iso_head -
+			usX2Y_iso_frames_per_buffer(runtime, usX2Y);
+		if (0 > shm->playback_iso_start)
+			shm->playback_iso_start += ARRAY_SIZE(shm->captured_iso);
+		shm->playback_iso_head = shm->playback_iso_start;
+	}
+
+	count = 0;
+	for (pack = 0; pack < nr_of_packs(); pack++) {
+		/* calculate the size of a packet */
+		counts = shm->captured_iso[shm->playback_iso_head].length / usX2Y->stride;
+		if (counts < 43 || counts > 50) {
+			snd_printk("should not be here with counts=%i\n", counts);
+			return -EPIPE;
+		}
+		/* set up descriptor */
+		urb->iso_frame_desc[pack].offset = shm->captured_iso[shm->playback_iso_head].offset;
+		urb->iso_frame_desc[pack].length = shm->captured_iso[shm->playback_iso_head].length;
+		if (atomic_read(&subs->state) != state_RUNNING)
+			memset((char *)urb->transfer_buffer + urb->iso_frame_desc[pack].offset, 0,
+			       urb->iso_frame_desc[pack].length);
+		if (++shm->playback_iso_head >= ARRAY_SIZE(shm->captured_iso))
+			shm->playback_iso_head = 0;
+		count += counts;
+	}
+	urb->transfer_buffer_length = count * usX2Y->stride;
+	return 0;
+}
+
+
+static inline void usX2Y_usbpcm_urb_capt_iso_advance(snd_usX2Y_substream_t *subs, struct urb *urb)
+{
+	int pack;
+	for (pack = 0; pack < nr_of_packs(); ++pack) {
+		struct usb_iso_packet_descriptor *desc = urb->iso_frame_desc + pack;
+		if (NULL != subs) {
+			snd_usX2Y_hwdep_pcm_shm_t *shm = subs->usX2Y->hwdep_pcm_shm;
+			int head = shm->captured_iso_head + 1;
+			if (head >= ARRAY_SIZE(shm->captured_iso))
+				head = 0;
+			shm->captured_iso[head].frame = urb->start_frame + pack;
+			shm->captured_iso[head].offset = desc->offset;
+			shm->captured_iso[head].length = desc->actual_length;
+			shm->captured_iso_head = head;
+			shm->captured_iso_frames++;
+		}
+		if ((desc->offset += desc->length * NRURBS*nr_of_packs()) +
+		    desc->length >= SSS)
+			desc->offset -= (SSS - desc->length);
+	}
+}
+
+static inline int usX2Y_usbpcm_usbframe_complete(snd_usX2Y_substream_t *capsubs,
+					   snd_usX2Y_substream_t *capsubs2,
+					   snd_usX2Y_substream_t *playbacksubs, int frame)
+{
+	int err, state;
+	struct urb *urb = playbacksubs->completed_urb;
+
+	state = atomic_read(&playbacksubs->state);
+	if (NULL != urb) {
+		if (state == state_RUNNING)
+			usX2Y_urb_play_retire(playbacksubs, urb);
+		else
+			if (state >= state_PRERUNNING) {
+				atomic_inc(&playbacksubs->state);
+			}
+	} else {
+		switch (state) {
+		case state_STARTING1:
+			urb = playbacksubs->urb[0];
+			atomic_inc(&playbacksubs->state);
+			break;
+		case state_STARTING2:
+			urb = playbacksubs->urb[1];
+			atomic_inc(&playbacksubs->state);
+			break;
+		}
+	}
+	if (urb) {
+		if ((err = usX2Y_hwdep_urb_play_prepare(playbacksubs, urb)) ||
+		    (err = usX2Y_urb_submit(playbacksubs, urb, frame))) {
+			return err;
+		}
+	}
+	
+	playbacksubs->completed_urb = NULL;
+
+	state = atomic_read(&capsubs->state);
+	if (state >= state_PREPARED) {
+		if (state == state_RUNNING) {
+			if ((err = usX2Y_usbpcm_urb_capt_retire(capsubs)))
+				return err;
+		} else {
+			if (state >= state_PRERUNNING)
+				atomic_inc(&capsubs->state);
+		}
+		usX2Y_usbpcm_urb_capt_iso_advance(capsubs, capsubs->completed_urb);
+		if (NULL != capsubs2)
+			usX2Y_usbpcm_urb_capt_iso_advance(NULL, capsubs2->completed_urb);
+		if ((err = usX2Y_urb_submit(capsubs, capsubs->completed_urb, frame)))
+			return err;
+		if (NULL != capsubs2)
+			if ((err = usX2Y_urb_submit(capsubs2, capsubs2->completed_urb, frame)))
+				return err;
+	}
+	capsubs->completed_urb = NULL;
+	if (NULL != capsubs2)
+		capsubs2->completed_urb = NULL;
+	return 0;
+}
+
+
+static void i_usX2Y_usbpcm_urb_complete(struct urb *urb, struct pt_regs *regs)
+{
+	snd_usX2Y_substream_t *subs = (snd_usX2Y_substream_t*)urb->context;
+	usX2Ydev_t *usX2Y = subs->usX2Y;
+	snd_usX2Y_substream_t *capsubs, *capsubs2, *playbacksubs;
+
+	if (unlikely(atomic_read(&subs->state) < state_PREPARED)) {
+		snd_printdd("hcd_frame=%i ep=%i%s status=%i start_frame=%i\n", usb_get_current_frame_number(usX2Y->chip.dev), subs->endpoint, usb_pipein(urb->pipe) ? "in" : "out", urb->status, urb->start_frame);
+		return;
+	}
+	if (unlikely(urb->status)) {
+		usX2Y_error_urb_status(usX2Y, subs, urb);
+		return;
+	}
+	if (likely((0xFFFF & urb->start_frame) == usX2Y->wait_iso_frame))
+		subs->completed_urb = urb;
+	else {
+		usX2Y_error_sequence(usX2Y, subs, urb);
+		return;
+	}
+
+	capsubs = usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE];
+	capsubs2 = usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE + 2];
+	playbacksubs = usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK];
+	if (capsubs->completed_urb && atomic_read(&capsubs->state) >= state_PREPARED &&
+	    (NULL == capsubs2 || capsubs2->completed_urb) &&
+	    (playbacksubs->completed_urb || atomic_read(&playbacksubs->state) < state_PREPARED)) {
+		if (!usX2Y_usbpcm_usbframe_complete(capsubs, capsubs2, playbacksubs, urb->start_frame)) {
+			if (nr_of_packs() <= urb->start_frame &&
+			    urb->start_frame <= (2 * nr_of_packs() - 1))	// uhci and ohci
+				usX2Y->wait_iso_frame = urb->start_frame - nr_of_packs();
+			else
+				usX2Y->wait_iso_frame +=  nr_of_packs();
+		} else {
+			snd_printdd("\n");
+			usX2Y_clients_stop(usX2Y);
+		}
+	}
+}
+
+
+static void usX2Y_hwdep_urb_release(struct urb** urb)
+{
+	usb_kill_urb(*urb);
+	usb_free_urb(*urb);
+	*urb = NULL;
+}
+
+/*
+ * release a substream
+ */
+static void usX2Y_usbpcm_urbs_release(snd_usX2Y_substream_t *subs)
+{
+	int i;
+	snd_printdd("snd_usX2Y_urbs_release() %i\n", subs->endpoint);
+	for (i = 0; i < NRURBS; i++)
+		usX2Y_hwdep_urb_release(subs->urb + i);
+}
+
+static void usX2Y_usbpcm_subs_startup_finish(usX2Ydev_t * usX2Y)
+{
+	usX2Y_urbs_set_complete(usX2Y, i_usX2Y_usbpcm_urb_complete);
+	usX2Y->prepare_subs = NULL;
+}
+
+static void i_usX2Y_usbpcm_subs_startup(struct urb *urb, struct pt_regs *regs)
+{
+	snd_usX2Y_substream_t *subs = (snd_usX2Y_substream_t*)urb->context;
+	usX2Ydev_t *usX2Y = subs->usX2Y;
+	snd_usX2Y_substream_t *prepare_subs = usX2Y->prepare_subs;
+	if (NULL != prepare_subs &&
+	    urb->start_frame == prepare_subs->urb[0]->start_frame) {
+		atomic_inc(&prepare_subs->state);
+		if (prepare_subs == usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE]) {
+			snd_usX2Y_substream_t *cap_subs2 = usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE + 2];
+			if (cap_subs2 != NULL)
+				atomic_inc(&cap_subs2->state);
+		}
+		usX2Y_usbpcm_subs_startup_finish(usX2Y);
+		wake_up(&usX2Y->prepare_wait_queue);
+	}
+
+	i_usX2Y_usbpcm_urb_complete(urb, regs);
+}
+
+/*
+ * initialize a substream's urbs
+ */
+static int usX2Y_usbpcm_urbs_allocate(snd_usX2Y_substream_t *subs)
+{
+	int i;
+	unsigned int pipe;
+	int is_playback = subs == subs->usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK];
+	struct usb_device *dev = subs->usX2Y->chip.dev;
+
+	pipe = is_playback ? usb_sndisocpipe(dev, subs->endpoint) :
+			usb_rcvisocpipe(dev, subs->endpoint);
+	subs->maxpacksize = usb_maxpacket(dev, pipe, is_playback);
+	if (!subs->maxpacksize)
+		return -EINVAL;
+
+	/* allocate and initialize data urbs */
+	for (i = 0; i < NRURBS; i++) {
+		struct urb** purb = subs->urb + i;
+		if (*purb) {
+			usb_kill_urb(*purb);
+			continue;
+		}
+		*purb = usb_alloc_urb(nr_of_packs(), GFP_KERNEL);
+		if (NULL == *purb) {
+			usX2Y_usbpcm_urbs_release(subs);
+			return -ENOMEM;
+		}
+		(*purb)->transfer_buffer = is_playback ?
+			subs->usX2Y->hwdep_pcm_shm->playback : (
+				subs->endpoint == 0x8 ?
+				subs->usX2Y->hwdep_pcm_shm->capture0x8 :
+				subs->usX2Y->hwdep_pcm_shm->capture0xA);
+
+		(*purb)->dev = dev;
+		(*purb)->pipe = pipe;
+		(*purb)->number_of_packets = nr_of_packs();
+		(*purb)->context = subs;
+		(*purb)->interval = 1;
+		(*purb)->complete = i_usX2Y_usbpcm_subs_startup;
+	}
+	return 0;
+}
+
+/*
+ * free the buffer
+ */
+static int snd_usX2Y_usbpcm_hw_free(snd_pcm_substream_t *substream)
+{
+	snd_pcm_runtime_t *runtime = substream->runtime;
+	snd_usX2Y_substream_t *subs = (snd_usX2Y_substream_t *)runtime->private_data,
+		*cap_subs2 = subs->usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE + 2];
+	down(&subs->usX2Y->prepare_mutex);
+	snd_printdd("snd_usX2Y_usbpcm_hw_free(%p)\n", substream);
+
+	if (SNDRV_PCM_STREAM_PLAYBACK == substream->stream) {
+		snd_usX2Y_substream_t *cap_subs = subs->usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE];
+		atomic_set(&subs->state, state_STOPPED);
+		usX2Y_usbpcm_urbs_release(subs);
+		if (!cap_subs->pcm_substream ||
+		    !cap_subs->pcm_substream->runtime ||
+		    !cap_subs->pcm_substream->runtime->status ||
+		    cap_subs->pcm_substream->runtime->status->state < SNDRV_PCM_STATE_PREPARED) {
+			atomic_set(&cap_subs->state, state_STOPPED);
+			if (NULL != cap_subs2)
+				atomic_set(&cap_subs2->state, state_STOPPED);
+			usX2Y_usbpcm_urbs_release(cap_subs);
+			if (NULL != cap_subs2)
+				usX2Y_usbpcm_urbs_release(cap_subs2);
+		}
+	} else {
+		snd_usX2Y_substream_t *playback_subs = subs->usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK];
+		if (atomic_read(&playback_subs->state) < state_PREPARED) {
+			atomic_set(&subs->state, state_STOPPED);
+			if (NULL != cap_subs2)
+				atomic_set(&cap_subs2->state, state_STOPPED);
+			usX2Y_usbpcm_urbs_release(subs);
+			if (NULL != cap_subs2)
+				usX2Y_usbpcm_urbs_release(cap_subs2);
+		}
+	}
+	up(&subs->usX2Y->prepare_mutex);
+	return snd_pcm_lib_free_pages(substream);
+}
+
+static void usX2Y_usbpcm_subs_startup(snd_usX2Y_substream_t *subs)
+{
+	usX2Ydev_t * usX2Y = subs->usX2Y;
+	usX2Y->prepare_subs = subs;
+	subs->urb[0]->start_frame = -1;
+	smp_wmb();	// Make shure above modifications are seen by i_usX2Y_subs_startup()
+	usX2Y_urbs_set_complete(usX2Y, i_usX2Y_usbpcm_subs_startup);
+}
+
+static int usX2Y_usbpcm_urbs_start(snd_usX2Y_substream_t *subs)
+{
+	int	p, u, err,
+		stream = subs->pcm_substream->stream;
+	usX2Ydev_t *usX2Y = subs->usX2Y;
+
+	if (SNDRV_PCM_STREAM_CAPTURE == stream) {
+		usX2Y->hwdep_pcm_shm->captured_iso_head = -1;
+		usX2Y->hwdep_pcm_shm->captured_iso_frames = 0;
+	}
+
+	for (p = 0; 3 >= (stream + p); p += 2) {
+		snd_usX2Y_substream_t *subs = usX2Y->subs[stream + p];
+		if (subs != NULL) {
+			if ((err = usX2Y_usbpcm_urbs_allocate(subs)) < 0)
+				return err;
+			subs->completed_urb = NULL;
+		}
+	}
+
+	for (p = 0; p < 4; p++) {
+		snd_usX2Y_substream_t *subs = usX2Y->subs[p];
+		if (subs != NULL && atomic_read(&subs->state) >= state_PREPARED)
+			goto start;
+	}
+	usX2Y->wait_iso_frame = -1;
+
+ start:
+	usX2Y_usbpcm_subs_startup(subs);
+	for (u = 0; u < NRURBS; u++) {
+		for (p = 0; 3 >= (stream + p); p += 2) {
+			snd_usX2Y_substream_t *subs = usX2Y->subs[stream + p];
+			if (subs != NULL) {
+				struct urb *urb = subs->urb[u];
+				if (usb_pipein(urb->pipe)) {
+					unsigned long pack;
+					if (0 == u)
+						atomic_set(&subs->state, state_STARTING3);
+					urb->dev = usX2Y->chip.dev;
+					urb->transfer_flags = URB_ISO_ASAP;
+					for (pack = 0; pack < nr_of_packs(); pack++) {
+						urb->iso_frame_desc[pack].offset = subs->maxpacksize * (pack + u * nr_of_packs());
+						urb->iso_frame_desc[pack].length = subs->maxpacksize;
+					}
+					urb->transfer_buffer_length = subs->maxpacksize * nr_of_packs(); 
+					if ((err = usb_submit_urb(urb, GFP_KERNEL)) < 0) {
+						snd_printk (KERN_ERR "cannot usb_submit_urb() for urb %d, err = %d\n", u, err);
+						err = -EPIPE;
+						goto cleanup;
+					}  else {
+						snd_printdd("%i\n", urb->start_frame);
+						if (0 > usX2Y->wait_iso_frame)
+							usX2Y->wait_iso_frame = urb->start_frame;
+					}
+					urb->transfer_flags = 0;
+				} else {
+					atomic_set(&subs->state, state_STARTING1);
+					break;
+				}			
+			}
+		}
+	}
+	err = 0;
+	wait_event(usX2Y->prepare_wait_queue, NULL == usX2Y->prepare_subs);
+	if (atomic_read(&subs->state) != state_PREPARED)
+		err = -EPIPE;
+		
+ cleanup:
+	if (err) {
+		usX2Y_subs_startup_finish(usX2Y);	// Call it now
+		usX2Y_clients_stop(usX2Y);		// something is completely wroong > stop evrything			
+	}
+	return err;
+}
+
+/*
+ * prepare callback
+ *
+ * set format and initialize urbs
+ */
+static int snd_usX2Y_usbpcm_prepare(snd_pcm_substream_t *substream)
+{
+	snd_pcm_runtime_t *runtime = substream->runtime;
+	snd_usX2Y_substream_t *subs = (snd_usX2Y_substream_t *)runtime->private_data;
+	usX2Ydev_t *usX2Y = subs->usX2Y;
+	snd_usX2Y_substream_t *capsubs = subs->usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE];
+	int err = 0;
+	snd_printdd("snd_usX2Y_pcm_prepare(%p)\n", substream);
+
+	if (NULL == usX2Y->hwdep_pcm_shm) {
+		if (NULL == (usX2Y->hwdep_pcm_shm = snd_malloc_pages(sizeof(snd_usX2Y_hwdep_pcm_shm_t), GFP_KERNEL)))
+			return -ENOMEM;
+		memset(usX2Y->hwdep_pcm_shm, 0, sizeof(snd_usX2Y_hwdep_pcm_shm_t));
+	}
+
+	down(&usX2Y->prepare_mutex);
+	usX2Y_subs_prepare(subs);
+// Start hardware streams
+// SyncStream first....
+	if (atomic_read(&capsubs->state) < state_PREPARED) {
+		if (usX2Y->format != runtime->format)
+			if ((err = usX2Y_format_set(usX2Y, runtime->format)) < 0)
+				goto up_prepare_mutex;
+		if (usX2Y->rate != runtime->rate)
+			if ((err = usX2Y_rate_set(usX2Y, runtime->rate)) < 0)
+				goto up_prepare_mutex;
+		snd_printdd("starting capture pipe for %s\n", subs == capsubs ? "self" : "playpipe");
+		if (0 > (err = usX2Y_usbpcm_urbs_start(capsubs)))
+			goto up_prepare_mutex;
+	}
+
+	if (subs != capsubs) {
+		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)) {
+					err = -ERESTARTSYS;
+					goto up_prepare_mutex;
+				}
+			} 
+			if (0 > (err = usX2Y_usbpcm_urbs_start(subs)))
+				goto up_prepare_mutex;
+		}
+		snd_printd("Ready: iso_frames_per_buffer=%i,captured_iso_frames=%i\n", usX2Y_iso_frames_per_buffer(runtime, usX2Y), usX2Y->hwdep_pcm_shm->captured_iso_frames);
+	} else
+		usX2Y->hwdep_pcm_shm->capture_iso_start = -1;
+
+ up_prepare_mutex:
+	up(&usX2Y->prepare_mutex);
+	return err;
+}
+
+static snd_pcm_hardware_t snd_usX2Y_4c =
+{
+	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
+				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
+				 SNDRV_PCM_INFO_MMAP_VALID),
+	.formats =                 SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_3LE,
+	.rates =                   SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
+	.rate_min =                44100,
+	.rate_max =                48000,
+	.channels_min =            2,
+	.channels_max =            4,
+	.buffer_bytes_max =	(2*128*1024),
+	.period_bytes_min =	64,
+	.period_bytes_max =	(128*1024),
+	.periods_min =		2,
+	.periods_max =		1024,
+	.fifo_size =              0
+};
+
+
+
+static int snd_usX2Y_usbpcm_open(snd_pcm_substream_t *substream)
+{
+	snd_usX2Y_substream_t	*subs = ((snd_usX2Y_substream_t **)
+					 snd_pcm_substream_chip(substream))[substream->stream];
+	snd_pcm_runtime_t	*runtime = substream->runtime;
+
+	if (!(subs->usX2Y->chip_status & USX2Y_STAT_CHIP_MMAP_PCM_URBS))
+		return -EBUSY;
+
+	runtime->hw = SNDRV_PCM_STREAM_PLAYBACK == substream->stream ? snd_usX2Y_2c :
+		(subs->usX2Y->subs[3] ? snd_usX2Y_4c : snd_usX2Y_2c);
+	runtime->private_data = subs;
+	subs->pcm_substream = substream;
+	snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME, 1000, 200000);
+	return 0;
+}
+
+
+static int snd_usX2Y_usbpcm_close(snd_pcm_substream_t *substream)
+{
+	snd_pcm_runtime_t *runtime = substream->runtime;
+	snd_usX2Y_substream_t *subs = (snd_usX2Y_substream_t *)runtime->private_data;
+	int err = 0;
+	snd_printd("\n");
+	subs->pcm_substream = NULL;
+	return err;
+}
+
+
+static snd_pcm_ops_t snd_usX2Y_usbpcm_ops = 
+{
+	.open =		snd_usX2Y_usbpcm_open,
+	.close =	snd_usX2Y_usbpcm_close,
+	.ioctl =	snd_pcm_lib_ioctl,
+	.hw_params =	snd_usX2Y_pcm_hw_params,
+	.hw_free =	snd_usX2Y_usbpcm_hw_free,
+	.prepare =	snd_usX2Y_usbpcm_prepare,
+	.trigger =	snd_usX2Y_pcm_trigger,
+	.pointer =	snd_usX2Y_pcm_pointer,
+};
+
+
+static int usX2Y_pcms_lock_check(snd_card_t *card)
+{
+	struct list_head *list;
+	snd_device_t *dev;
+	snd_pcm_t *pcm;
+	int err = 0;
+	list_for_each(list, &card->devices) {
+		dev = snd_device(list);
+		if (dev->type != SNDRV_DEV_PCM)
+			continue;
+		pcm = dev->device_data;
+		down(&pcm->open_mutex);
+	}
+	list_for_each(list, &card->devices) {
+		int s;
+		dev = snd_device(list);
+		if (dev->type != SNDRV_DEV_PCM)
+			continue;
+		pcm = dev->device_data;
+		for (s = 0; s < 2; ++s) {
+			snd_pcm_substream_t *substream;
+			substream = pcm->streams[s].substream;
+			if (substream && substream->open_flag)
+				err = -EBUSY;
+		}
+	}
+	return err;
+}
+
+
+static void usX2Y_pcms_unlock(snd_card_t *card)
+{
+	struct list_head *list;
+	snd_device_t *dev;
+	snd_pcm_t *pcm;
+	list_for_each(list, &card->devices) {
+		dev = snd_device(list);
+		if (dev->type != SNDRV_DEV_PCM)
+			continue;
+		pcm = dev->device_data;
+		up(&pcm->open_mutex);
+	}
+}
+
+
+static int snd_usX2Y_hwdep_pcm_open(snd_hwdep_t *hw, struct file *file)
+{
+	// we need to be the first 
+	snd_card_t *card = hw->card;
+	int err = usX2Y_pcms_lock_check(card);
+	if (0 == err)
+		usX2Y(card)->chip_status |= USX2Y_STAT_CHIP_MMAP_PCM_URBS;
+	usX2Y_pcms_unlock(card);
+	return err;
+}
+
+
+static int snd_usX2Y_hwdep_pcm_release(snd_hwdep_t *hw, struct file *file)
+{
+	snd_card_t *card = hw->card;
+	int err = usX2Y_pcms_lock_check(card);
+	if (0 == err)
+		usX2Y(hw->card)->chip_status &= ~USX2Y_STAT_CHIP_MMAP_PCM_URBS;
+	usX2Y_pcms_unlock(card);
+	return err;
+}
+
+
+static void snd_usX2Y_hwdep_pcm_vm_open(struct vm_area_struct *area)
+{
+}
+
+
+static void snd_usX2Y_hwdep_pcm_vm_close(struct vm_area_struct *area)
+{
+}
+
+
+static struct page * snd_usX2Y_hwdep_pcm_vm_nopage(struct vm_area_struct *area, unsigned long address, int *type)
+{
+	unsigned long offset;
+	struct page *page;
+	void *vaddr;
+
+	offset = area->vm_pgoff << PAGE_SHIFT;
+	offset += address - area->vm_start;
+	snd_assert((offset % PAGE_SIZE) == 0, return NOPAGE_OOM);
+	vaddr = (char*)((usX2Ydev_t*)area->vm_private_data)->hwdep_pcm_shm + offset;
+	page = virt_to_page(vaddr);
+
+	if (type)
+		*type = VM_FAULT_MINOR;
+
+	return page;
+}
+
+
+static struct vm_operations_struct snd_usX2Y_hwdep_pcm_vm_ops = {
+	.open = snd_usX2Y_hwdep_pcm_vm_open,
+	.close = snd_usX2Y_hwdep_pcm_vm_close,
+	.nopage = snd_usX2Y_hwdep_pcm_vm_nopage,
+};
+
+
+static int snd_usX2Y_hwdep_pcm_mmap(snd_hwdep_t * hw, struct file *filp, struct vm_area_struct *area)
+{
+	unsigned long	size = (unsigned long)(area->vm_end - area->vm_start);
+	usX2Ydev_t	*usX2Y = (usX2Ydev_t*)hw->private_data;
+
+	if (!(((usX2Ydev_t*)hw->private_data)->chip_status & USX2Y_STAT_CHIP_INIT))
+		return -EBUSY;
+
+	/* if userspace tries to mmap beyond end of our buffer, fail */ 
+	if (size > PAGE_ALIGN(sizeof(snd_usX2Y_hwdep_pcm_shm_t))) {
+		snd_printd("%lu > %lu\n", size, (unsigned long)sizeof(snd_usX2Y_hwdep_pcm_shm_t)); 
+		return -EINVAL;
+	}
+
+	if (!usX2Y->hwdep_pcm_shm) {
+		return -ENODEV;
+	}
+	area->vm_ops = &snd_usX2Y_hwdep_pcm_vm_ops;
+	area->vm_flags |= VM_RESERVED;
+	snd_printd("vm_flags=0x%lX\n", area->vm_flags);
+	area->vm_private_data = hw->private_data;
+	return 0;
+}
+
+
+static void snd_usX2Y_hwdep_pcm_private_free(snd_hwdep_t *hwdep)
+{
+	usX2Ydev_t *usX2Y = (usX2Ydev_t *)hwdep->private_data;
+	if (NULL != usX2Y->hwdep_pcm_shm)
+		snd_free_pages(usX2Y->hwdep_pcm_shm, sizeof(snd_usX2Y_hwdep_pcm_shm_t));
+}
+
+
+static void snd_usX2Y_usbpcm_private_free(snd_pcm_t *pcm)
+{
+	snd_pcm_lib_preallocate_free_for_all(pcm);
+}
+
+
+int usX2Y_hwdep_pcm_new(snd_card_t* card)
+{
+	int err;
+	snd_hwdep_t *hw;
+	snd_pcm_t *pcm;
+	struct usb_device *dev = usX2Y(card)->chip.dev;
+	if (1 != nr_of_packs())
+		return 0;
+
+	if ((err = snd_hwdep_new(card, SND_USX2Y_USBPCM_ID, 1, &hw)) < 0) {
+		snd_printd("\n");
+		return err;
+	}
+	hw->iface = SNDRV_HWDEP_IFACE_USX2Y_PCM;
+	hw->private_data = usX2Y(card);
+	hw->private_free = snd_usX2Y_hwdep_pcm_private_free;
+	hw->ops.open = snd_usX2Y_hwdep_pcm_open;
+	hw->ops.release = snd_usX2Y_hwdep_pcm_release;
+	hw->ops.mmap = snd_usX2Y_hwdep_pcm_mmap;
+	hw->exclusive = 1;
+	sprintf(hw->name, "/proc/bus/usb/%03d/%03d/hwdeppcm", dev->bus->busnum, dev->devnum);
+
+	err = snd_pcm_new(card, NAME_ALLCAPS" hwdep Audio", 2, 1, 1, &pcm);
+	if (err < 0) {
+		return err;
+	}
+	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_usX2Y_usbpcm_ops);
+	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_usX2Y_usbpcm_ops);
+
+	pcm->private_data = usX2Y(card)->subs;
+	pcm->private_free = snd_usX2Y_usbpcm_private_free;
+	pcm->info_flags = 0;
+
+	sprintf(pcm->name, NAME_ALLCAPS" hwdep Audio");
+	if (0 > (err = snd_pcm_lib_preallocate_pages(pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream,
+						     SNDRV_DMA_TYPE_CONTINUOUS,
+						     snd_dma_continuous_data(GFP_KERNEL),
+						     64*1024, 128*1024)) ||
+	    0 > (err = snd_pcm_lib_preallocate_pages(pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream,
+	    					     SNDRV_DMA_TYPE_CONTINUOUS,
+	    					     snd_dma_continuous_data(GFP_KERNEL),
+						     64*1024, 128*1024))) {
+		snd_usX2Y_usbpcm_private_free(pcm);
+		return err;
+	}
+
+
+	return 0;
+}
+
+#else
+
+int usX2Y_hwdep_pcm_new(snd_card_t* card)
+{
+	return 0;
+}
+
+#endif
diff -Nru a/sound/usb/usx2y/usx2yhwdeppcm.h b/sound/usb/usx2y/usx2yhwdeppcm.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/sound/usb/usx2y/usx2yhwdeppcm.h	2005-03-01 23:39:19 -08:00
@@ -0,0 +1,21 @@
+#define MAXPACK 50
+#define MAXBUFFERMS 100
+#define MAXSTRIDE 3
+
+#define SSS (((MAXPACK*MAXBUFFERMS*MAXSTRIDE + 4096) / 4096) * 4096)
+struct snd_usX2Y_hwdep_pcm_shm {
+	char playback[SSS];
+	char capture0x8[SSS];
+	char capture0xA[SSS];
+	volatile int playback_iso_head;
+	int playback_iso_start;
+	struct {
+		int	frame,
+			offset,
+			length;
+	} captured_iso[128];
+	volatile int captured_iso_head;
+	volatile unsigned captured_iso_frames;
+	int capture_iso_start;
+};
+typedef struct snd_usX2Y_hwdep_pcm_shm snd_usX2Y_hwdep_pcm_shm_t;
diff -Nru a/usr/Makefile b/usr/Makefile
--- a/usr/Makefile	2005-03-01 23:38:58 -08:00
+++ b/usr/Makefile	2005-03-01 23:38:58 -08:00
@@ -5,40 +5,60 @@
 
 clean-files := initramfs_data.cpio.gz initramfs_list
 
-# If you want a different list of files in the initramfs_data.cpio
-# then you can either overwrite the cpio_list in this directory
-# or set INITRAMFS_LIST to another filename.
-INITRAMFS_LIST := $(obj)/initramfs_list
-
 # initramfs_data.o contains the initramfs_data.cpio.gz image.
 # The image is included using .incbin, a dependency which is not
 # tracked automatically.
 $(obj)/initramfs_data.o: $(obj)/initramfs_data.cpio.gz FORCE
 
-# initramfs-y are the programs which will be copied into the CPIO
-# archive. Currently, the filenames are hardcoded in gen_init_cpio,
-# but we need the information for the build as well, so it's duplicated
-# here.
-
-# Commented out for now
-# initramfs-y := $(obj)/root/hello
+ifdef CONFIG_INITRAMFS_ROOT_UID
+gen_initramfs_args += -u $(CONFIG_INITRAMFS_ROOT_UID)
+endif
+
+ifdef CONFIG_INITRAMFS_ROOT_GID
+gen_initramfs_args += -g $(CONFIG_INITRAMFS_ROOT_GID)
+endif
+
+# The $(shell echo $(CONFIG_INITRAMFS_SOURCE)) is to remove the
+# gratuitous begin and end quotes from the Kconfig string type.
+# Internal, escaped quotes in the Kconfig string will loose the
+# escape and become active quotes.
+quotefixed_initramfs_source := $(shell echo $(CONFIG_INITRAMFS_SOURCE))
 
 filechk_initramfs_list = $(CONFIG_SHELL) \
- $(srctree)/scripts/gen_initramfs_list.sh $(CONFIG_INITRAMFS_SOURCE)
-			   
+ $(srctree)/scripts/gen_initramfs_list.sh $(gen_initramfs_args) $(quotefixed_initramfs_source)
+
 $(obj)/initramfs_list: FORCE
 	$(call filechk,initramfs_list)
 
 quiet_cmd_cpio = CPIO    $@
       cmd_cpio = ./$< $(obj)/initramfs_list > $@
 
+
+# Check if the INITRAMFS_SOURCE is a cpio archive
+ifneq (,$(findstring .cpio,$(quotefixed_initramfs_source)))
+
+# INITRAMFS_SOURCE has a cpio archive - verify that it's a single file
+ifneq (1,$(words $(quotefixed_initramfs_source)))
+$(error Only a single file may be specified in CONFIG_INITRAMFS_SOURCE (="$(quotefixed_initramfs_source)") when a cpio archive is directly specified.)
+endif
+# Now use the cpio archive directly
+initramfs_data_cpio = $(quotefixed_initramfs_source)
+targets += $(quotefixed_initramfs_source)
+
+else
+
+# INITRAMFS_SOURCE is not a cpio archive - create one
 $(obj)/initramfs_data.cpio: $(obj)/gen_init_cpio \
                             $(initramfs-y) $(obj)/initramfs_list FORCE
 	$(call if_changed,cpio)
 
 targets += initramfs_data.cpio
+initramfs_data_cpio = $(obj)/initramfs_data.cpio
+
+endif
+
 
-$(obj)/initramfs_data.cpio.gz: $(obj)/initramfs_data.cpio FORCE
+$(obj)/initramfs_data.cpio.gz: $(initramfs_data_cpio) FORCE
 	$(call if_changed,gzip)
 
 targets += initramfs_data.cpio.gz
diff -Nru a/usr/gen_init_cpio.c b/usr/gen_init_cpio.c
--- a/usr/gen_init_cpio.c	2005-03-01 23:38:59 -08:00
+++ b/usr/gen_init_cpio.c	2005-03-01 23:38:59 -08:00
@@ -10,13 +10,19 @@
 #include <ctype.h>
 #include <limits.h>
 
+/*
+ * Original work by Jeff Garzik
+ *
+ * External file lists, symlink, pipe and fifo support by Thayne Harbaugh
+ */
+
 #define xstr(s) #s
 #define str(s) xstr(s)
 
 static unsigned int offset;
 static unsigned int ino = 721;
 
-struct file_type {
+struct file_handler {
 	const char *type;
 	int (*handler)(const char *line);
 };
@@ -80,7 +86,7 @@
 		0,			/* minor */
 		0,			/* rmajor */
 		0,			/* rminor */
-		(unsigned)strlen(name) + 1, /* namesize */
+		(unsigned)strlen(name)+1, /* namesize */
 		0);			/* chksum */
 	push_hdr(s);
 	push_rest(name);
@@ -91,7 +97,55 @@
 	}
 }
 
-static int cpio_mkdir(const char *name, unsigned int mode,
+static int cpio_mkslink(const char *name, const char *target,
+			 unsigned int mode, uid_t uid, gid_t gid)
+{
+	char s[256];
+	time_t mtime = time(NULL);
+
+	sprintf(s,"%s%08X%08X%08lX%08lX%08X%08lX"
+	       "%08X%08X%08X%08X%08X%08X%08X",
+		"070701",		/* magic */
+		ino++,			/* ino */
+		S_IFLNK | mode,		/* mode */
+		(long) uid,		/* uid */
+		(long) gid,		/* gid */
+		1,			/* nlink */
+		(long) mtime,		/* mtime */
+		(unsigned)strlen(target)+1, /* filesize */
+		3,			/* major */
+		1,			/* minor */
+		0,			/* rmajor */
+		0,			/* rminor */
+		(unsigned)strlen(name) + 1,/* namesize */
+		0);			/* chksum */
+	push_hdr(s);
+	push_string(name);
+	push_pad();
+	push_string(target);
+	push_pad();
+	return 0;
+}
+
+static int cpio_mkslink_line(const char *line)
+{
+	char name[PATH_MAX + 1];
+	char target[PATH_MAX + 1];
+	unsigned int mode;
+	int uid;
+	int gid;
+	int rc = -1;
+
+	if (5 != sscanf(line, "%" str(PATH_MAX) "s %" str(PATH_MAX) "s %o %d %d", name, target, &mode, &uid, &gid)) {
+		fprintf(stderr, "Unrecognized dir format '%s'", line);
+		goto fail;
+	}
+	rc = cpio_mkslink(name, target, mode, uid, gid);
+ fail:
+	return rc;
+}
+
+static int cpio_mkgeneric(const char *name, unsigned int mode,
 		       uid_t uid, gid_t gid)
 {
 	char s[256];
@@ -101,7 +155,7 @@
 	       "%08X%08X%08X%08X%08X%08X%08X",
 		"070701",		/* magic */
 		ino++,			/* ino */
-		S_IFDIR | mode,		/* mode */
+		mode,			/* mode */
 		(long) uid,		/* uid */
 		(long) gid,		/* gid */
 		2,			/* nlink */
@@ -118,7 +172,33 @@
 	return 0;
 }
 
-static int cpio_mkdir_line(const char *line)
+enum generic_types {
+	GT_DIR,
+	GT_PIPE,
+	GT_SOCK
+};
+
+struct generic_type {
+	const char *type;
+	mode_t mode;
+};
+
+static struct generic_type generic_type_table[] = {
+	[GT_DIR] = {
+		.type = "dir",
+		.mode = S_IFDIR
+	},
+	[GT_PIPE] = {
+		.type = "pipe",
+		.mode = S_IFIFO
+	},
+	[GT_SOCK] = {
+		.type = "sock",
+		.mode = S_IFSOCK
+	}
+};
+
+static int cpio_mkgeneric_line(const char *line, enum generic_types gt)
 {
 	char name[PATH_MAX + 1];
 	unsigned int mode;
@@ -127,14 +207,31 @@
 	int rc = -1;
 
 	if (4 != sscanf(line, "%" str(PATH_MAX) "s %o %d %d", name, &mode, &uid, &gid)) {
-		fprintf(stderr, "Unrecognized dir format '%s'", line);
+		fprintf(stderr, "Unrecognized %s format '%s'",
+			line, generic_type_table[gt].type);
 		goto fail;
 	}
-	rc = cpio_mkdir(name, mode, uid, gid);
+	mode |= generic_type_table[gt].mode;
+	rc = cpio_mkgeneric(name, mode, uid, gid);
  fail:
 	return rc;
 }
 
+static int cpio_mkdir_line(const char *line)
+{
+	return cpio_mkgeneric_line(line, GT_DIR);
+}
+
+static int cpio_mkpipe_line(const char *line)
+{
+	return cpio_mkgeneric_line(line, GT_PIPE);
+}
+
+static int cpio_mksock_line(const char *line)
+{
+	return cpio_mkgeneric_line(line, GT_SOCK);
+}
+
 static int cpio_mknod(const char *name, unsigned int mode,
 		       uid_t uid, gid_t gid, char dev_type,
 		       unsigned int maj, unsigned int min)
@@ -198,7 +295,6 @@
 	struct stat buf;
 	int file = -1;
 	int retval;
-	int i;
 	int rc = -1;
 
 	mode |= S_IFREG;
@@ -247,8 +343,7 @@
 	push_string(name);
 	push_pad();
 
-	for (i = 0; i < buf.st_size; ++i)
-		fputc(filebuf[i], stdout);
+	fwrite(filebuf, buf.st_size, 1, stdout);
 	offset += buf.st_size;
 	push_pad();
 	rc = 0;
@@ -286,12 +381,16 @@
 		"describe the files to be included in the initramfs archive:\n"
 		"\n"
 		"# a comment\n"
-		"file <name> <location> <mode> <uid> <gid> \n"
+		"file <name> <location> <mode> <uid> <gid>\n"
 		"dir <name> <mode> <uid> <gid>\n"
 		"nod <name> <mode> <uid> <gid> <dev_type> <maj> <min>\n"
+		"slink <name> <target> <mode> <uid> <gid>\n"
+		"pipe <name> <mode> <uid> <gid>\n"
+		"sock <name> <mode> <uid> <gid>\n"
 		"\n"
-		"<name>      name of the file/dir/nod in the archive\n"
+		"<name>      name of the file/dir/nod/etc in the archive\n"
 		"<location>  location of the file in the current filesystem\n"
+		"<target>    link target\n"
 		"<mode>      mode/permissions of the file\n"
 		"<uid>       user id (0=root)\n"
 		"<gid>       group id (0=root)\n"
@@ -309,7 +408,7 @@
 		prog);
 }
 
-struct file_type file_type_table[] = {
+struct file_handler file_handler_table[] = {
 	{
 		.type    = "file",
 		.handler = cpio_mkfile_line,
@@ -320,6 +419,15 @@
 		.type    = "dir",
 		.handler = cpio_mkdir_line,
 	}, {
+		.type    = "slink",
+		.handler = cpio_mkslink_line,
+	}, {
+		.type    = "pipe",
+		.handler = cpio_mkpipe_line,
+	}, {
+		.type    = "sock",
+		.handler = cpio_mksock_line,
+	}, {
 		.type    = NULL,
 		.handler = NULL,
 	}
@@ -382,10 +490,10 @@
 			ec = -1;
 		}
 
-		for (type_idx = 0; file_type_table[type_idx].type; type_idx++) {
+		for (type_idx = 0; file_handler_table[type_idx].type; type_idx++) {
 			int rc;
-			if (! strcmp(line, file_type_table[type_idx].type)) {
-				if ((rc = file_type_table[type_idx].handler(args))) {
+			if (! strcmp(line, file_handler_table[type_idx].type)) {
+				if ((rc = file_handler_table[type_idx].handler(args))) {
 					ec = rc;
 					fprintf(stderr, " line %d\n", line_nr);
 				}
@@ -393,7 +501,7 @@
 			}
 		}
 
-		if (NULL == file_type_table[type_idx].type) {
+		if (NULL == file_handler_table[type_idx].type) {
 			fprintf(stderr, "unknown file type line %d: '%s'\n",
 				line_nr, line);
 		}
